diff options
Diffstat (limited to 'target')
-rw-r--r-- | target/linux/s3c24xx/Makefile | 2 | ||||
-rw-r--r-- | target/linux/s3c24xx/config-2.6.29 | 587 | ||||
-rw-r--r-- | target/linux/s3c24xx/patches-2.6.29/000-downgrade-to-rc3.patch | 170300 | ||||
-rw-r--r-- | target/linux/s3c24xx/patches-2.6.29/001-merge-openmoko.patch | 96426 | ||||
-rw-r--r-- | target/linux/s3c24xx/patches-2.6.29/002-call-preinit-instead-of-init.patch | 10 |
5 files changed, 267324 insertions, 1 deletions
diff --git a/target/linux/s3c24xx/Makefile b/target/linux/s3c24xx/Makefile index c5a4a94509..33050cbbc6 100644 --- a/target/linux/s3c24xx/Makefile +++ b/target/linux/s3c24xx/Makefile @@ -12,7 +12,7 @@ BOARDNAME:=Samsung S3C24xx FEATURES:=jffs2 CFLAGS:=-O2 -pipe -march=armv4t -mtune=arm920t -funit-at-a-time -LINUX_VERSION:=2.6.28.10 +LINUX_VERSION:=2.6.29 DEVICE_TYPE=phone diff --git a/target/linux/s3c24xx/config-2.6.29 b/target/linux/s3c24xx/config-2.6.29 new file mode 100644 index 0000000000..c4dddb3259 --- /dev/null +++ b/target/linux/s3c24xx/config-2.6.29 @@ -0,0 +1,587 @@ +# CONFIG_AEABI is not set +CONFIG_ALIGNMENT_TRAP=y +CONFIG_APM_EMULATION=y +CONFIG_APM_POWER=y +CONFIG_AR6000_WLAN=y +# CONFIG_AR6000_WLAN_DEBUG is not set +# CONFIG_AR6000_WLAN_RESET is not set +# CONFIG_ARCH_AAEC2000 is not set +# CONFIG_ARCH_AT91 is not set +# CONFIG_ARCH_BAST is not set +# CONFIG_ARCH_CLPS711X is not set +# CONFIG_ARCH_DAVINCI is not set +# CONFIG_ARCH_EBSA110 is not set +# CONFIG_ARCH_EP93XX is not set +CONFIG_ARCH_FLATMEM_HAS_HOLES=y +# CONFIG_ARCH_FOOTBRIDGE is not set +# CONFIG_ARCH_H1940 is not set +# CONFIG_ARCH_H720X is not set +# CONFIG_ARCH_HAS_ILOG2_U32 is not set +# CONFIG_ARCH_HAS_ILOG2_U64 is not set +# CONFIG_ARCH_IMX is not set +# CONFIG_ARCH_INTEGRATOR is not set +# CONFIG_ARCH_IOP13XX is not set +# CONFIG_ARCH_IOP32X is not set +# CONFIG_ARCH_IOP33X is not set +# CONFIG_ARCH_IXP2000 is not set +# CONFIG_ARCH_IXP23XX is not set +# CONFIG_ARCH_IXP4XX is not set +# CONFIG_ARCH_KIRKWOOD is not set +# CONFIG_ARCH_KS8695 is not set +# CONFIG_ARCH_L7200 is not set +# CONFIG_ARCH_LH7A40X is not set +# CONFIG_ARCH_LOKI is not set +# CONFIG_ARCH_MSM is not set +# CONFIG_ARCH_MV78XX0 is not set +# CONFIG_ARCH_MXC is not set +# CONFIG_ARCH_NETX is not set +# CONFIG_ARCH_NS9XXX is not set +# CONFIG_ARCH_OMAP is not set +# CONFIG_ARCH_ORION5X is not set +# CONFIG_ARCH_PNX4008 is not set +# CONFIG_ARCH_PXA is not set +# CONFIG_ARCH_REALVIEW is not set +CONFIG_ARCH_REQUIRE_GPIOLIB=y +# CONFIG_ARCH_RPC is not set +CONFIG_ARCH_S3C2410=y +CONFIG_ARCH_S3C2440=y +# CONFIG_ARCH_S3C64XX is not set +# CONFIG_ARCH_SA1100 is not set +# CONFIG_ARCH_SELECT_MEMORY_MODEL is not set +# CONFIG_ARCH_SHARK is not set +# CONFIG_ARCH_SMDK2410 is not set +# CONFIG_ARCH_SPARSEMEM_DEFAULT is not set +# CONFIG_ARCH_SUPPORTS_MSI is not set +CONFIG_ARCH_SUSPEND_POSSIBLE=y +# CONFIG_ARCH_VERSATILE is not set +# CONFIG_ARCH_W90X900 is not set +CONFIG_ARM=y +CONFIG_ARM_THUMB=y +# CONFIG_ARPD is not set +CONFIG_ASHMEM=y +CONFIG_ATAGS_PROC=y +CONFIG_BACKLIGHT_CLASS_DEVICE=y +CONFIG_BACKLIGHT_GENERIC=y +CONFIG_BACKLIGHT_GTA01=y +CONFIG_BACKLIGHT_LCD_SUPPORT=y +# CONFIG_BACKLIGHT_PWM is not set +CONFIG_BASE_SMALL=0 +CONFIG_BATTERY_BQ27000_HDQ=y +# CONFIG_BATTERY_BQ27x00 is not set +# CONFIG_BATTERY_DS2760 is not set +CONFIG_BATTERY_GTA01=y +CONFIG_BITREVERSE=y +CONFIG_BLK_DEV_RAM=y +CONFIG_BLK_DEV_RAM_COUNT=16 +CONFIG_BLK_DEV_RAM_SIZE=4096 +CONFIG_BRIDGE_NETFILTER=y +# CONFIG_BSD_PROCESS_ACCT is not set +CONFIG_CHARGER_PCF50606=y +CONFIG_CHARGER_PCF50633=y +CONFIG_CMDLINE="unused -- bootloader passes ATAG list" +CONFIG_COMPAT_BRK=y +CONFIG_COMPAT_NET_DEV_OPS=y +# CONFIG_CONFIGFS_FS is not set +CONFIG_CONSOLE_TRANSLATIONS=y +CONFIG_CPU_32=y +CONFIG_CPU_32v4T=y +CONFIG_CPU_ABRT_EV4T=y +CONFIG_CPU_ARM920T=y +CONFIG_CPU_CACHE_V4WT=y +CONFIG_CPU_CACHE_VIVT=y +CONFIG_CPU_COPY_V4WB=y +CONFIG_CPU_CP15=y +CONFIG_CPU_CP15_MMU=y +# CONFIG_CPU_DCACHE_WRITETHROUGH is not set +# CONFIG_CPU_ICACHE_DISABLE is not set +CONFIG_CPU_IDLE=y +CONFIG_CPU_IDLE_GOV_LADDER=y +CONFIG_CPU_LLSERIAL_S3C2410=y +CONFIG_CPU_LLSERIAL_S3C2440=y +CONFIG_CPU_PABRT_NOIFAR=y +CONFIG_CPU_S3C2410=y +CONFIG_CPU_S3C2410_DMA=y +CONFIG_CPU_S3C2440=y +CONFIG_CPU_S3C2442=y +CONFIG_CPU_S3C244X=y +CONFIG_CPU_TLB_V4WBI=y +CONFIG_CRC16=y +CONFIG_CRC_CCITT=y +CONFIG_CRC_T10DIF=y +# CONFIG_CRYPTO_AEAD is not set +CONFIG_CRYPTO_AEAD2=y +CONFIG_CRYPTO_AES=y +CONFIG_CRYPTO_ALGAPI=y +CONFIG_CRYPTO_ALGAPI2=y +CONFIG_CRYPTO_ANSI_CPRNG=y +CONFIG_CRYPTO_ARC4=y +CONFIG_CRYPTO_BLKCIPHER=y +CONFIG_CRYPTO_BLKCIPHER2=y +CONFIG_CRYPTO_CBC=y +CONFIG_CRYPTO_DES=y +CONFIG_CRYPTO_ECB=y +CONFIG_CRYPTO_FIPS=y +CONFIG_CRYPTO_HASH=y +CONFIG_CRYPTO_HASH2=y +CONFIG_CRYPTO_HMAC=y +CONFIG_CRYPTO_HW=y +CONFIG_CRYPTO_MANAGER=y +CONFIG_CRYPTO_MANAGER2=y +CONFIG_CRYPTO_MD5=y +CONFIG_CRYPTO_RNG=y +CONFIG_CRYPTO_RNG2=y +CONFIG_CRYPTO_SHA1=y +# CONFIG_DCB is not set +CONFIG_DEBUG_BUGVERBOSE=y +# CONFIG_DEBUG_FS is not set +CONFIG_DEBUG_MEMORY_INIT=y +CONFIG_DEBUG_S3C_UART=2 +# CONFIG_DEBUG_USER is not set +CONFIG_DEFAULT_TCP_CONG="cubic" +# CONFIG_DEVPTS_MULTIPLE_INSTANCES is not set +CONFIG_DISPLAY_JBT6K74=y +# CONFIG_DISPLAY_L1K002 is not set +CONFIG_DISPLAY_SUPPORT=y +CONFIG_DMADEVICES=y +CONFIG_DUMMY_CONSOLE=y +CONFIG_ELF_CORE=y +# CONFIG_EMBEDDED is not set +# CONFIG_ENABLE_WARN_DEPRECATED is not set +CONFIG_FB=y +# CONFIG_FB_BACKLIGHT is not set +# CONFIG_FB_BOOT_VESA_SUPPORT is not set +CONFIG_FB_CFB_COPYAREA=y +CONFIG_FB_CFB_FILLRECT=y +CONFIG_FB_CFB_IMAGEBLIT=y +# CONFIG_FB_CFB_REV_PIXELS_IN_BYTE is not set +# CONFIG_FB_DDC is not set +# CONFIG_FB_FOREIGN_ENDIAN is not set +# CONFIG_FB_MACMODES is not set +# CONFIG_FB_MB862XX is not set +# CONFIG_FB_METRONOME is not set +# CONFIG_FB_MODE_HELPERS is not set +# CONFIG_FB_S1D13XXX is not set +CONFIG_FB_S3C2410=y +# CONFIG_FB_S3C2410_DEBUG is not set +# CONFIG_FB_SVGALIB is not set +# CONFIG_FB_SYS_COPYAREA is not set +# CONFIG_FB_SYS_FILLRECT is not set +# CONFIG_FB_SYS_FOPS is not set +# CONFIG_FB_SYS_IMAGEBLIT is not set +# CONFIG_FB_TILEBLITTING is not set +# CONFIG_FB_VIRTUAL is not set +# CONFIG_FIND_IRQ_BLOCKERS is not set +CONFIG_FIQ=y +# CONFIG_FIRMWARE_EDID is not set +CONFIG_FONTS=y +# CONFIG_FONT_10x18 is not set +CONFIG_FONT_6x11=y +# CONFIG_FONT_7x14 is not set +# CONFIG_FONT_8x16 is not set +# CONFIG_FONT_8x8 is not set +# CONFIG_FONT_ACORN_8x8 is not set +# CONFIG_FONT_MINI_4x6 is not set +# CONFIG_FONT_PEARL_8x8 is not set +# CONFIG_FONT_SUN12x22 is not set +# CONFIG_FONT_SUN8x16 is not set +# CONFIG_FPE_FASTFPE is not set +CONFIG_FPE_NWFPE=y +# CONFIG_FPE_NWFPE_XP is not set +CONFIG_FRAMEBUFFER_CONSOLE=y +# CONFIG_FRAMEBUFFER_CONSOLE_DETECT_PRIMARY is not set +# CONFIG_FRAMEBUFFER_CONSOLE_ROTATION is not set +CONFIG_FRAME_POINTER=y +CONFIG_FREEZER=y +# CONFIG_GENERIC_CLOCKEVENTS is not set +CONFIG_GENERIC_FIND_LAST_BIT=y +CONFIG_GENERIC_GPIO=y +CONFIG_GENERIC_HARDIRQS_NO__DO_IRQ=y +# CONFIG_GENERIC_TIME is not set +CONFIG_GPIOLIB=y +CONFIG_GPIO_DEVICE=y +CONFIG_GPIO_SYSFS=y +# CONFIG_GREENASIA_FF is not set +# CONFIG_HAMRADIO is not set +CONFIG_HARDIRQS_SW_RESEND=y +CONFIG_HAS_DMA=y +CONFIG_HAS_IOMEM=y +CONFIG_HAVE_AOUT=y +CONFIG_HAVE_ARCH_KGDB=y +CONFIG_HAVE_CLK=y +CONFIG_HAVE_FUNCTION_TRACER=y +CONFIG_HAVE_GENERIC_DMA_COHERENT=y +CONFIG_HAVE_IDE=y +CONFIG_HAVE_KPROBES=y +CONFIG_HAVE_KRETPROBES=y +CONFIG_HAVE_LATENCYTOP_SUPPORT=y +CONFIG_HAVE_OPROFILE=y +CONFIG_HAVE_PWM=y +# CONFIG_HDQ_GPIO_BITBANG is not set +CONFIG_HID=y +CONFIG_HID_A4TECH=y +CONFIG_HID_APPLE=y +CONFIG_HID_BELKIN=y +CONFIG_HID_CHERRY=y +CONFIG_HID_CHICONY=y +CONFIG_HID_COMPAT=y +CONFIG_HID_CYPRESS=y +CONFIG_HID_EZKEY=y +CONFIG_HID_GYRATION=y +CONFIG_HID_LOGITECH=y +CONFIG_HID_MICROSOFT=y +CONFIG_HID_MONTEREY=y +CONFIG_HID_NTRIG=y +CONFIG_HID_PANTHERLORD=y +CONFIG_HID_PETALYNX=y +CONFIG_HID_PID=y +CONFIG_HID_SAMSUNG=y +CONFIG_HID_SONY=y +CONFIG_HID_SUNPLUS=y +CONFIG_HID_SUPPORT=y +CONFIG_HID_TOPSEED=y +CONFIG_HW_CONSOLE=y +# CONFIG_HW_RANDOM is not set +CONFIG_HZ=200 +CONFIG_I2C=y +CONFIG_I2C_BOARDINFO=y +CONFIG_I2C_CHARDEV=y +CONFIG_I2C_HELPER_AUTO=y +CONFIG_I2C_S3C2410=y +CONFIG_IKCONFIG=y +CONFIG_IKCONFIG_PROC=y +CONFIG_INET_DIAG=y +CONFIG_INET_TCP_DIAG=y +CONFIG_INITRAMFS_SOURCE="" +CONFIG_INOTIFY=y +CONFIG_INOTIFY_USER=y +CONFIG_INPUT=y +CONFIG_INPUT_EVDEV=y +# CONFIG_INPUT_GPIO_BUTTONS is not set +CONFIG_INPUT_KEYBOARD=y +CONFIG_INPUT_LIS302DL=y +CONFIG_INPUT_MOUSE=y +CONFIG_INPUT_MOUSEDEV=y +# CONFIG_INPUT_MOUSEDEV_PSAUX is not set +CONFIG_INPUT_MOUSEDEV_SCREEN_X=480 +CONFIG_INPUT_MOUSEDEV_SCREEN_Y=640 +CONFIG_INPUT_PCF50606_PMU=y +CONFIG_INPUT_PCF50633_PMU=y +CONFIG_INPUT_TOUCHSCREEN=y +# CONFIG_INPUT_YEALINK is not set +CONFIG_IP_PNP=y +# CONFIG_IP_PNP_BOOTP is not set +# CONFIG_IP_PNP_DHCP is not set +# CONFIG_IP_PNP_RARP is not set +# CONFIG_IP_ROUTE_MULTIPATH is not set +# CONFIG_IP_ROUTE_VERBOSE is not set +# CONFIG_ISDN is not set +# CONFIG_JFFS2_COMPRESSION_OPTIONS is not set +CONFIG_KALLSYMS=y +CONFIG_KEXEC=y +# CONFIG_KEYBOARD_ATKBD is not set +# CONFIG_KEYBOARD_GPIO is not set +# CONFIG_KEYBOARD_LKKBD is not set +CONFIG_KEYBOARD_NEO1973=y +# CONFIG_KEYBOARD_NEWTON is not set +# CONFIG_KEYBOARD_STOWAWAY is not set +# CONFIG_KEYBOARD_SUNKBD is not set +# CONFIG_KEYBOARD_XTKBD is not set +CONFIG_LCD_CLASS_DEVICE=y +# CONFIG_LCD_ILI9320 is not set +CONFIG_LCD_LTV350QV=y +# CONFIG_LCD_PLATFORM is not set +# CONFIG_LCD_TDO24M is not set +# CONFIG_LCD_VGG2432A4 is not set +CONFIG_LEDS_GPIO=y +# CONFIG_LEDS_LP5521 is not set +CONFIG_LEDS_NEO1973_GTA02=y +CONFIG_LEDS_NEO1973_VIBRATOR=y +CONFIG_LEDS_TRIGGER_BACKLIGHT=y +# CONFIG_LEDS_TRIGGER_DEFAULT_ON is not set +# CONFIG_LEDS_TRIGGER_HEARTBEAT is not set +CONFIG_LOCK_KERNEL=y +# CONFIG_LOGO is not set +CONFIG_LOG_BUF_SHIFT=18 +# CONFIG_MACH_AML_M5900 is not set +# CONFIG_MACH_ANUBIS is not set +# CONFIG_MACH_AT2440EVB is not set +# CONFIG_MACH_JIVE is not set +# CONFIG_MACH_N30 is not set +CONFIG_MACH_NEO1973=y +CONFIG_MACH_NEO1973_GTA01=y +CONFIG_MACH_NEO1973_GTA02=y +# CONFIG_MACH_NEXCODER_2440 is not set +# CONFIG_MACH_OSIRIS is not set +# CONFIG_MACH_OTOM is not set +# CONFIG_MACH_QT2410 is not set +# CONFIG_MACH_RX3715 is not set +CONFIG_MACH_SMDK=y +# CONFIG_MACH_SMDK2412 is not set +# CONFIG_MACH_SMDK2413 is not set +# CONFIG_MACH_SMDK2443 is not set +# CONFIG_MACH_TCT_HAMMER is not set +# CONFIG_MACH_VR1000 is not set +# CONFIG_MACH_VSTMS is not set +# CONFIG_MAC_PARTITION is not set +CONFIG_MFD_GLAMO=y +CONFIG_MFD_GLAMO_FB=y +# CONFIG_MFD_GLAMO_FB_XGLAMO_WORKAROUND is not set +CONFIG_MFD_GLAMO_MCI=y +CONFIG_MFD_GLAMO_SPI_FB=y +CONFIG_MFD_GLAMO_SPI_GPIO=y +CONFIG_MFD_PCF50606=y +CONFIG_MFD_PCF50633=y +# CONFIG_MFD_T7L66XB is not set +# CONFIG_MISC_DEVICES is not set +CONFIG_MISC_FILESYSTEMS=y +CONFIG_MMC=y +CONFIG_MMC_BLOCK=y +CONFIG_MMC_BLOCK_BOUNCE=y +# CONFIG_MMC_DEBUG is not set +CONFIG_MMC_S3C=y +CONFIG_MMC_SDHCI=y +CONFIG_MMC_SDHCI_S3C=y +# CONFIG_MMC_SPI is not set +CONFIG_MMC_UNSAFE_RESUME=y +CONFIG_MODULE_FORCE_UNLOAD=y +# CONFIG_MOUSE_BCM5974 is not set +# CONFIG_MOUSE_GPIO is not set +# CONFIG_MOUSE_PS2 is not set +# CONFIG_MOUSE_SERIAL is not set +# CONFIG_MOUSE_VSXXXAA is not set +CONFIG_MTD_ABSENT=y +# CONFIG_MTD_CFI_AMDSTD is not set +CONFIG_MTD_CMDLINE_PARTS=y +# CONFIG_MTD_COMPLEX_MAPPINGS is not set +CONFIG_MTD_CONCAT=y +CONFIG_MTD_NAND=y +# CONFIG_MTD_NAND_GPIO is not set +CONFIG_MTD_NAND_S3C2410=y +# CONFIG_MTD_NAND_S3C2410_CLKSTOP is not set +# CONFIG_MTD_NAND_S3C2410_DEBUG is not set +CONFIG_MTD_NAND_S3C2410_HWECC=y +CONFIG_MTD_NAND_VERIFY_WRITE=y +CONFIG_MTD_PHYSMAP=y +# CONFIG_MTD_PHYSMAP_COMPAT is not set +# CONFIG_MTD_QINFO_PROBE is not set +CONFIG_MTD_ROM=y +CONFIG_NAMESPACES=y +CONFIG_NEO1973_GTA02_2440=y +# CONFIG_NETDEV_1000 is not set +# CONFIG_NETWORK_FILESYSTEMS is not set +# CONFIG_NET_CLS_ACT is not set +# CONFIG_NET_ETHERNET is not set +# CONFIG_NET_NS is not set +# CONFIG_NET_SCH_DRR is not set +CONFIG_NF_CONNTRACK=y +CONFIG_NF_CONNTRACK_IPV4=y +# CONFIG_NF_CONNTRACK_MARK is not set +# CONFIG_NF_CONNTRACK_PROC_COMPAT is not set +CONFIG_NF_DEFRAG_IPV4=y +CONFIG_NO_IOPORT=y +CONFIG_NR_TTY_DEVICES=6 +# CONFIG_NVRAM is not set +# CONFIG_OUTER_CACHE is not set +CONFIG_PAGEFLAGS_EXTENDED=y +CONFIG_PAGE_OFFSET=0xC0000000 +CONFIG_PCA9632=y +CONFIG_PCF50606_ADC=y +CONFIG_PCF50606_GPO=y +CONFIG_PCF50606_WATCHDOG=y +CONFIG_PCF50633_ADC=y +CONFIG_PCF50633_GPIO=y +# CONFIG_PCI_SYSCALL is not set +CONFIG_PDA_POWER=y +# CONFIG_PHYS_ADDR_T_64BIT is not set +CONFIG_PLAT_S3C=y +CONFIG_PLAT_S3C24XX=y +CONFIG_PM=y +# CONFIG_PM_DEBUG is not set +CONFIG_PM_SLEEP=y +CONFIG_POWER_SUPPLY=y +# CONFIG_POWER_SUPPLY_DEBUG is not set +CONFIG_PREEMPT=y +CONFIG_PROC_PAGE_MONITOR=y +CONFIG_REGULATOR=y +CONFIG_REGULATOR_DEBUG=y +CONFIG_REGULATOR_PCF50606=y +CONFIG_REGULATOR_PCF50633=y +CONFIG_RFKILL=y +CONFIG_RFKILL_INPUT=y +CONFIG_RFKILL_LEDS=y +CONFIG_RTC_CLASS=y +# CONFIG_RTC_DRV_CMOS is not set +CONFIG_RTC_DRV_PCF50606=y +CONFIG_RTC_DRV_PCF50633=y +CONFIG_RTC_DRV_S3C=y +CONFIG_S3C2410_CLOCK=y +CONFIG_S3C2410_DMA=y +# CONFIG_S3C2410_DMA_DEBUG is not set +CONFIG_S3C2410_GPIO=y +CONFIG_S3C2410_PM=y +# CONFIG_S3C2410_PM_CHECK is not set +# CONFIG_S3C2410_PM_DEBUG is not set +CONFIG_S3C2410_WATCHDOG=y +CONFIG_S3C2440_DMA=y +# CONFIG_S3C24XX_ADC is not set +CONFIG_S3C24XX_GPIO_EXTRA=0 +CONFIG_S3C24XX_PWM=y +# CONFIG_S3C_BOOT_ERROR_RESET is not set +CONFIG_S3C_BOOT_UART_FORCE_FIFO=y +# CONFIG_S3C_BOOT_WATCHDOG is not set +CONFIG_S3C_DEV_USB_HOST=y +CONFIG_S3C_DMA=y +CONFIG_S3C_GPIO_SPACE=0 +CONFIG_S3C_GPIO_TRACK=y +CONFIG_S3C_LOWLEVEL_UART_PORT=2 +CONFIG_S3C_PWM=y +CONFIG_SCSI=y +# CONFIG_SCSI_LOWLEVEL is not set +# CONFIG_SCSI_MULTI_LUN is not set +# CONFIG_SCSI_PROC_FS is not set +# CONFIG_SDIO_UART is not set +# CONFIG_SENSORS_PCF50606 is not set +# CONFIG_SERIAL_8250 is not set +CONFIG_SERIAL_S3C2410=y +CONFIG_SERIAL_S3C2440=y +CONFIG_SERIAL_SAMSUNG=y +CONFIG_SERIAL_SAMSUNG_CONSOLE=y +CONFIG_SERIAL_SAMSUNG_UARTS=3 +CONFIG_SERIO=y +# CONFIG_SERIO_RAW is not set +# CONFIG_SERIO_SERPORT is not set +CONFIG_SMDK2440_CPU2440=y +CONFIG_SMDK2440_CPU2442=y +CONFIG_SND=m +# CONFIG_SND_ARM is not set +# CONFIG_SND_DRIVERS is not set +CONFIG_SND_PCM=m +CONFIG_SND_S3C24XX_SOC=m +CONFIG_SND_S3C24XX_SOC_I2S=m +# CONFIG_SND_S3C24XX_SOC_LN2440SBC_ALC650 is not set +CONFIG_SND_S3C24XX_SOC_NEO1973_GTA02_WM8753=m +# CONFIG_SND_S3C24XX_SOC_NEO1973_WM8753 is not set +# CONFIG_SND_S3C24XX_SOC_S3C24XX_UDA134X is not set +# CONFIG_SND_S3C64XX_SOC_SMDK6410_WM8731 is not set +CONFIG_SND_SOC=m +# CONFIG_SND_SOC_ALL_CODECS is not set +CONFIG_SND_SOC_I2C_AND_SPI=m +CONFIG_SND_SOC_WM8753=m +CONFIG_SND_TIMER=m +# CONFIG_SND_USB is not set +# CONFIG_SND_VERBOSE_PROCFS is not set +CONFIG_SOUND=m +# CONFIG_SOUND_OSS_CORE is not set +CONFIG_SPI=y +CONFIG_SPI_BITBANG=y +# CONFIG_SPI_GPIO is not set +# CONFIG_SPI_GPIO_OLD is not set +CONFIG_SPI_MASTER=y +CONFIG_SPI_S3C24XX=y +CONFIG_SPI_S3C24XX_GPIO=y +# CONFIG_SPI_SPIDEV is not set +CONFIG_SPLIT_PTLOCK_CPUS=4096 +# CONFIG_SQUASHFS is not set +CONFIG_SUSPEND=y +CONFIG_SUSPEND_FREEZER=y +# CONFIG_SYSCTL_SYSCALL_CHECK is not set +CONFIG_SYSFS_DEPRECATED=y +CONFIG_SYSFS_DEPRECATED_V2=y +CONFIG_SYS_SUPPORTS_APM_EMULATION=y +# CONFIG_TCP_CONG_ADVANCED is not set +CONFIG_TCP_CONG_CUBIC=y +CONFIG_TCP_MD5SIG=y +# CONFIG_TOUCHSCREEN_ADS7846 is not set +# CONFIG_TOUCHSCREEN_ELO is not set +CONFIG_TOUCHSCREEN_FILTER=y +CONFIG_TOUCHSCREEN_FILTER_GROUP=y +CONFIG_TOUCHSCREEN_FILTER_LINEAR=y +CONFIG_TOUCHSCREEN_FILTER_MEAN=y +CONFIG_TOUCHSCREEN_FILTER_MEDIAN=y +# CONFIG_TOUCHSCREEN_FUJITSU is not set +# CONFIG_TOUCHSCREEN_GUNZE is not set +# CONFIG_TOUCHSCREEN_INEXIO is not set +# CONFIG_TOUCHSCREEN_MK712 is not set +# CONFIG_TOUCHSCREEN_MTOUCH is not set +# CONFIG_TOUCHSCREEN_PCAP7200 is not set +# CONFIG_TOUCHSCREEN_PENMOUNT is not set +CONFIG_TOUCHSCREEN_S3C2410=y +# CONFIG_TOUCHSCREEN_S3C2410_DEBUG is not set +# CONFIG_TOUCHSCREEN_TOUCHIT213 is not set +# CONFIG_TOUCHSCREEN_TOUCHRIGHT is not set +# CONFIG_TOUCHSCREEN_TOUCHWIN is not set +# CONFIG_TOUCHSCREEN_TSC2007 is not set +# CONFIG_TOUCHSCREEN_USB_COMPOSITE is not set +# CONFIG_TOUCHSCREEN_WACOM_W8001 is not set +CONFIG_UID16=y +CONFIG_UIO=y +CONFIG_UIO_PDRV=y +# CONFIG_UIO_PDRV_GENIRQ is not set +# CONFIG_UIO_SERCOS3 is not set +# CONFIG_UIO_SMX is not set +CONFIG_UNEVICTABLE_LRU=y +CONFIG_USB=y +CONFIG_USB_ACM=y +CONFIG_USB_ANNOUNCE_NEW_DEVICES=y +# CONFIG_USB_ARCH_HAS_EHCI is not set +# CONFIG_USB_CDC_COMPOSITE is not set +# CONFIG_USB_DEVICEFS is not set +CONFIG_USB_ETH=y +CONFIG_USB_ETH_RNDIS=y +# CONFIG_USB_FILE_STORAGE is not set +CONFIG_USB_GADGET=y +# CONFIG_USB_GADGETFS is not set +# CONFIG_USB_GADGET_AMD5536UDC is not set +# CONFIG_USB_GADGET_AT91 is not set +# CONFIG_USB_GADGET_ATMEL_USBA is not set +# CONFIG_USB_GADGET_CI13XXX is not set +# CONFIG_USB_GADGET_DEBUG_FILES is not set +# CONFIG_USB_GADGET_DUALSPEED is not set +# CONFIG_USB_GADGET_DUMMY_HCD is not set +# CONFIG_USB_GADGET_FSL_QE is not set +# CONFIG_USB_GADGET_FSL_USB2 is not set +# CONFIG_USB_GADGET_GOKU is not set +# CONFIG_USB_GADGET_IMX is not set +# CONFIG_USB_GADGET_LH7A40X is not set +# CONFIG_USB_GADGET_M66592 is not set +# CONFIG_USB_GADGET_MUSB_HDRC is not set +# CONFIG_USB_GADGET_NET2280 is not set +# CONFIG_USB_GADGET_OMAP is not set +# CONFIG_USB_GADGET_PXA25X is not set +# CONFIG_USB_GADGET_PXA27X is not set +CONFIG_USB_GADGET_S3C2410=y +# CONFIG_USB_GADGET_S3C_OTGD_HS is not set +CONFIG_USB_GADGET_SELECTED=y +CONFIG_USB_GADGET_VBUS_DRAW=500 +# CONFIG_USB_G_PRINTER is not set +# CONFIG_USB_G_SERIAL is not set +CONFIG_USB_HID=y +# CONFIG_USB_MIDI_GADGET is not set +# CONFIG_USB_MUSB_HDRC is not set +# CONFIG_USB_OHCI_BIG_ENDIAN_DESC is not set +# CONFIG_USB_OHCI_BIG_ENDIAN_MMIO is not set +CONFIG_USB_OHCI_HCD=y +CONFIG_USB_S3C2410=y +# CONFIG_USB_S3C2410_DEBUG is not set +CONFIG_USB_SERIAL=y +CONFIG_USB_SERIAL_CONSOLE=y +# CONFIG_USB_SERIAL_OPTICON is not set +CONFIG_USB_SERIAL_OPTION=y +# CONFIG_USB_SERIAL_SIEMENS_MPI is not set +CONFIG_USB_SUPPORT=y +CONFIG_USB_SUSPEND=y +# CONFIG_USB_ZERO is not set +# CONFIG_USER_NS is not set +CONFIG_VECTORS_BASE=0xffff0000 +# CONFIG_VGA_CONSOLE is not set +CONFIG_VIDEO_OUTPUT_CONTROL=y +# CONFIG_VLAN_8021Q is not set +CONFIG_VM_EVENT_COUNTERS=y +CONFIG_VT=y +CONFIG_VT_CONSOLE=y +CONFIG_VT_HW_CONSOLE_BINDING=y +# CONFIG_WIRELESS is not set +# CONFIG_WLAN_80211 is not set +CONFIG_ZBOOT_ROM_BSS=0x0 +CONFIG_ZBOOT_ROM_TEXT=0x0 +CONFIG_ZONE_DMA_FLAG=0 diff --git a/target/linux/s3c24xx/patches-2.6.29/000-downgrade-to-rc3.patch b/target/linux/s3c24xx/patches-2.6.29/000-downgrade-to-rc3.patch new file mode 100644 index 0000000000..c9c8453827 --- /dev/null +++ b/target/linux/s3c24xx/patches-2.6.29/000-downgrade-to-rc3.patch @@ -0,0 +1,170300 @@ +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/arch/alpha/include/asm/bug.h linux-2.6.29-rc3.owrt/arch/alpha/include/asm/bug.h +--- linux-2.6.29.owrt/arch/alpha/include/asm/bug.h 2009-05-10 22:04:41.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/arch/alpha/include/asm/bug.h 2009-05-10 23:48:27.000000000 +0200 +@@ -8,12 +8,17 @@ + + /* ??? Would be nice to use .gprel32 here, but we can't be sure that the + function loaded the GP, so this could fail in modules. */ +-#define BUG() do { \ +- __asm__ __volatile__( \ +- "call_pal %0 # bugchk\n\t" \ +- ".long %1\n\t.8byte %2" \ +- : : "i"(PAL_bugchk), "i"(__LINE__), "i"(__FILE__)); \ +- for ( ; ; ); } while (0) ++static inline void ATTRIB_NORET __BUG(const char *file, int line) ++{ ++ __asm__ __volatile__( ++ "call_pal %0 # bugchk\n\t" ++ ".long %1\n\t.8byte %2" ++ : : "i" (PAL_bugchk), "i"(line), "i"(file)); ++ for ( ; ; ) ++ ; ++} ++ ++#define BUG() __BUG(__FILE__, __LINE__) + + #define HAVE_ARCH_BUG + #endif +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/arch/alpha/include/asm/dma-mapping.h linux-2.6.29-rc3.owrt/arch/alpha/include/asm/dma-mapping.h +--- linux-2.6.29.owrt/arch/alpha/include/asm/dma-mapping.h 2009-05-10 22:04:41.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/arch/alpha/include/asm/dma-mapping.h 2009-05-10 23:48:27.000000000 +0200 +@@ -29,8 +29,6 @@ + + #else /* no PCI - no IOMMU. */ + +-#include <asm/io.h> /* for virt_to_phys() */ +- + struct scatterlist; + void *dma_alloc_coherent(struct device *dev, size_t size, + dma_addr_t *dma_handle, gfp_t gfp); +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/arch/alpha/Kconfig linux-2.6.29-rc3.owrt/arch/alpha/Kconfig +--- linux-2.6.29.owrt/arch/alpha/Kconfig 2009-05-10 22:04:41.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/arch/alpha/Kconfig 2009-05-10 23:48:27.000000000 +0200 +@@ -8,7 +8,6 @@ + select HAVE_AOUT + select HAVE_IDE + select HAVE_OPROFILE +- select HAVE_SYSCALL_WRAPPERS + help + The Alpha is a 64-bit general-purpose processor designed and + marketed by the Digital Equipment Corporation of blessed memory, +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/arch/alpha/kernel/entry.S linux-2.6.29-rc3.owrt/arch/alpha/kernel/entry.S +--- linux-2.6.29.owrt/arch/alpha/kernel/entry.S 2009-05-10 22:04:41.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/arch/alpha/kernel/entry.S 2009-05-10 23:48:27.000000000 +0200 +@@ -933,7 +933,7 @@ + osf_sigprocmask: + .prologue 0 + mov $sp, $18 +- jmp $31, sys_osf_sigprocmask ++ jmp $31, do_osf_sigprocmask + .end osf_sigprocmask + + .align 4 +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/arch/alpha/kernel/osf_sys.c linux-2.6.29-rc3.owrt/arch/alpha/kernel/osf_sys.c +--- linux-2.6.29.owrt/arch/alpha/kernel/osf_sys.c 2009-05-10 22:04:41.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/arch/alpha/kernel/osf_sys.c 2009-05-10 23:48:27.000000000 +0200 +@@ -54,7 +54,8 @@ + * identical to OSF as we don't return 0 on success, but doing otherwise + * would require changes to libc. Hopefully this is good enough. + */ +-SYSCALL_DEFINE1(osf_brk, unsigned long, brk) ++asmlinkage unsigned long ++osf_brk(unsigned long brk) + { + unsigned long retval = sys_brk(brk); + if (brk && brk != retval) +@@ -65,9 +66,9 @@ + /* + * This is pure guess-work.. + */ +-SYSCALL_DEFINE4(osf_set_program_attributes, unsigned long, text_start, +- unsigned long, text_len, unsigned long, bss_start, +- unsigned long, bss_len) ++asmlinkage int ++osf_set_program_attributes(unsigned long text_start, unsigned long text_len, ++ unsigned long bss_start, unsigned long bss_len) + { + struct mm_struct *mm; + +@@ -145,9 +146,9 @@ + return -EFAULT; + } + +-SYSCALL_DEFINE4(osf_getdirentries, unsigned int, fd, +- struct osf_dirent __user *, dirent, unsigned int, count, +- long __user *, basep) ++asmlinkage int ++osf_getdirentries(unsigned int fd, struct osf_dirent __user *dirent, ++ unsigned int count, long __user *basep) + { + int error; + struct file *file; +@@ -176,9 +177,9 @@ + + #undef NAME_OFFSET + +-SYSCALL_DEFINE6(osf_mmap, unsigned long, addr, unsigned long, len, +- unsigned long, prot, unsigned long, flags, unsigned long, fd, +- unsigned long, off) ++asmlinkage unsigned long ++osf_mmap(unsigned long addr, unsigned long len, unsigned long prot, ++ unsigned long flags, unsigned long fd, unsigned long off) + { + struct file *file = NULL; + unsigned long ret = -EBADF; +@@ -253,8 +254,8 @@ + return error; + } + +-SYSCALL_DEFINE3(osf_statfs, char __user *, pathname, +- struct osf_statfs __user *, buffer, unsigned long, bufsiz) ++asmlinkage int ++osf_statfs(char __user *pathname, struct osf_statfs __user *buffer, unsigned long bufsiz) + { + struct path path; + int retval; +@@ -267,8 +268,8 @@ + return retval; + } + +-SYSCALL_DEFINE3(osf_fstatfs, unsigned long, fd, +- struct osf_statfs __user *, buffer, unsigned long, bufsiz) ++asmlinkage int ++osf_fstatfs(unsigned long fd, struct osf_statfs __user *buffer, unsigned long bufsiz) + { + struct file *file; + int retval; +@@ -367,8 +368,8 @@ + return do_mount("", dirname, "proc", flags, NULL); + } + +-SYSCALL_DEFINE4(osf_mount, unsigned long, typenr, char __user *, path, +- int, flag, void __user *, data) ++asmlinkage int ++osf_mount(unsigned long typenr, char __user *path, int flag, void __user *data) + { + int retval = -EINVAL; + char *name; +@@ -398,7 +399,8 @@ + return retval; + } + +-SYSCALL_DEFINE1(osf_utsname, char __user *, name) ++asmlinkage int ++osf_utsname(char __user *name) + { + int error; + +@@ -421,12 +423,14 @@ + return error; + } + +-SYSCALL_DEFINE0(getpagesize) ++asmlinkage unsigned long ++sys_getpagesize(void) + { + return PAGE_SIZE; + } + +-SYSCALL_DEFINE0(getdtablesize) ++asmlinkage unsigned long ++sys_getdtablesize(void) + { + return sysctl_nr_open; + } +@@ -434,7 +438,8 @@ + /* + * For compatibility with OSF/1 only. Use utsname(2) instead. + */ +-SYSCALL_DEFINE2(osf_getdomainname, char __user *, name, int, namelen) ++asmlinkage int ++osf_getdomainname(char __user *name, int namelen) + { + unsigned len; + int i; +@@ -522,8 +527,8 @@ + PL_DEL = 5, PL_FDEL = 6 + }; + +-SYSCALL_DEFINE2(osf_proplist_syscall, enum pl_code, code, +- union pl_args __user *, args) ++asmlinkage long ++osf_proplist_syscall(enum pl_code code, union pl_args __user *args) + { + long error; + int __user *min_buf_size_ptr; +@@ -562,8 +567,8 @@ + return error; + } + +-SYSCALL_DEFINE2(osf_sigstack, struct sigstack __user *, uss, +- struct sigstack __user *, uoss) ++asmlinkage int ++osf_sigstack(struct sigstack __user *uss, struct sigstack __user *uoss) + { + unsigned long usp = rdusp(); + unsigned long oss_sp = current->sas_ss_sp + current->sas_ss_size; +@@ -603,7 +608,8 @@ + return error; + } + +-SYSCALL_DEFINE3(osf_sysinfo, int, command, char __user *, buf, long, count) ++asmlinkage long ++osf_sysinfo(int command, char __user *buf, long count) + { + char *sysinfo_table[] = { + utsname()->sysname, +@@ -641,8 +647,9 @@ + return err; + } + +-SYSCALL_DEFINE5(osf_getsysinfo, unsigned long, op, void __user *, buffer, +- unsigned long, nbytes, int __user *, start, void __user *, arg) ++asmlinkage unsigned long ++osf_getsysinfo(unsigned long op, void __user *buffer, unsigned long nbytes, ++ int __user *start, void __user *arg) + { + unsigned long w; + struct percpu_struct *cpu; +@@ -698,8 +705,9 @@ + return -EOPNOTSUPP; + } + +-SYSCALL_DEFINE5(osf_setsysinfo, unsigned long, op, void __user *, buffer, +- unsigned long, nbytes, int __user *, start, void __user *, arg) ++asmlinkage unsigned long ++osf_setsysinfo(unsigned long op, void __user *buffer, unsigned long nbytes, ++ int __user *start, void __user *arg) + { + switch (op) { + case SSI_IEEE_FP_CONTROL: { +@@ -872,8 +880,8 @@ + value->tv_sec = jiffies / HZ; + } + +-SYSCALL_DEFINE2(osf_gettimeofday, struct timeval32 __user *, tv, +- struct timezone __user *, tz) ++asmlinkage int ++osf_gettimeofday(struct timeval32 __user *tv, struct timezone __user *tz) + { + if (tv) { + struct timeval ktv; +@@ -888,8 +896,8 @@ + return 0; + } + +-SYSCALL_DEFINE2(osf_settimeofday, struct timeval32 __user *, tv, +- struct timezone __user *, tz) ++asmlinkage int ++osf_settimeofday(struct timeval32 __user *tv, struct timezone __user *tz) + { + struct timespec kts; + struct timezone ktz; +@@ -908,7 +916,8 @@ + return do_sys_settimeofday(tv ? &kts : NULL, tz ? &ktz : NULL); + } + +-SYSCALL_DEFINE2(osf_getitimer, int, which, struct itimerval32 __user *, it) ++asmlinkage int ++osf_getitimer(int which, struct itimerval32 __user *it) + { + struct itimerval kit; + int error; +@@ -920,8 +929,8 @@ + return error; + } + +-SYSCALL_DEFINE3(osf_setitimer, int, which, struct itimerval32 __user *, in, +- struct itimerval32 __user *, out) ++asmlinkage int ++osf_setitimer(int which, struct itimerval32 __user *in, struct itimerval32 __user *out) + { + struct itimerval kin, kout; + int error; +@@ -943,8 +952,8 @@ + + } + +-SYSCALL_DEFINE2(osf_utimes, char __user *, filename, +- struct timeval32 __user *, tvs) ++asmlinkage int ++osf_utimes(char __user *filename, struct timeval32 __user *tvs) + { + struct timespec tv[2]; + +@@ -970,8 +979,9 @@ + #define MAX_SELECT_SECONDS \ + ((unsigned long) (MAX_SCHEDULE_TIMEOUT / HZ)-1) + +-SYSCALL_DEFINE5(osf_select, int, n, fd_set __user *, inp, fd_set __user *, outp, +- fd_set __user *, exp, struct timeval32 __user *, tvp) ++asmlinkage int ++osf_select(int n, fd_set __user *inp, fd_set __user *outp, fd_set __user *exp, ++ struct timeval32 __user *tvp) + { + struct timespec end_time, *to = NULL; + if (tvp) { +@@ -1016,7 +1026,8 @@ + long ru_nivcsw; /* involuntary " */ + }; + +-SYSCALL_DEFINE2(osf_getrusage, int, who, struct rusage32 __user *, ru) ++asmlinkage int ++osf_getrusage(int who, struct rusage32 __user *ru) + { + struct rusage32 r; + +@@ -1042,8 +1053,9 @@ + return copy_to_user(ru, &r, sizeof(r)) ? -EFAULT : 0; + } + +-SYSCALL_DEFINE4(osf_wait4, pid_t, pid, int __user *, ustatus, int, options, +- struct rusage32 __user *, ur) ++asmlinkage long ++osf_wait4(pid_t pid, int __user *ustatus, int options, ++ struct rusage32 __user *ur) + { + struct rusage r; + long ret, err; +@@ -1089,8 +1101,8 @@ + * seems to be a timeval pointer, and I suspect the second + * one is the time remaining.. Ho humm.. No documentation. + */ +-SYSCALL_DEFINE2(osf_usleep_thread, struct timeval32 __user *, sleep, +- struct timeval32 __user *, remain) ++asmlinkage int ++osf_usleep_thread(struct timeval32 __user *sleep, struct timeval32 __user *remain) + { + struct timeval tmp; + unsigned long ticks; +@@ -1143,7 +1155,8 @@ + int :32; int :32; int :32; int :32; + }; + +-SYSCALL_DEFINE1(old_adjtimex, struct timex32 __user *, txc_p) ++asmlinkage int ++sys_old_adjtimex(struct timex32 __user *txc_p) + { + struct timex txc; + int ret; +@@ -1254,8 +1267,8 @@ + return 0; + } + +-SYSCALL_DEFINE3(osf_readv, unsigned long, fd, +- const struct iovec __user *, vector, unsigned long, count) ++asmlinkage ssize_t ++osf_readv(unsigned long fd, const struct iovec __user * vector, unsigned long count) + { + if (unlikely(personality(current->personality) == PER_OSF4)) + if (osf_fix_iov_len(vector, count)) +@@ -1263,8 +1276,8 @@ + return sys_readv(fd, vector, count); + } + +-SYSCALL_DEFINE3(osf_writev, unsigned long, fd, +- const struct iovec __user *, vector, unsigned long, count) ++asmlinkage ssize_t ++osf_writev(unsigned long fd, const struct iovec __user * vector, unsigned long count) + { + if (unlikely(personality(current->personality) == PER_OSF4)) + if (osf_fix_iov_len(vector, count)) +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/arch/alpha/kernel/pci-noop.c linux-2.6.29-rc3.owrt/arch/alpha/kernel/pci-noop.c +--- linux-2.6.29.owrt/arch/alpha/kernel/pci-noop.c 2009-05-10 22:04:41.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/arch/alpha/kernel/pci-noop.c 2009-05-10 23:48:27.000000000 +0200 +@@ -109,8 +109,7 @@ + /* Stubs for the routines in pci_iommu.c: */ + + void * +-__pci_alloc_consistent(struct pci_dev *pdev, size_t size, +- dma_addr_t *dma_addrp, gfp_t gfp) ++pci_alloc_consistent(struct pci_dev *pdev, size_t size, dma_addr_t *dma_addrp) + { + return NULL; + } +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/arch/alpha/kernel/process.c linux-2.6.29-rc3.owrt/arch/alpha/kernel/process.c +--- linux-2.6.29.owrt/arch/alpha/kernel/process.c 2009-05-10 22:04:41.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/arch/alpha/kernel/process.c 2009-05-10 23:48:27.000000000 +0200 +@@ -93,8 +93,8 @@ + if (cpuid != boot_cpuid) { + flags |= 0x00040000UL; /* "remain halted" */ + *pflags = flags; +- set_cpu_present(cpuid, false); +- set_cpu_possible(cpuid, false); ++ cpu_clear(cpuid, cpu_present_map); ++ cpu_clear(cpuid, cpu_possible_map); + halt(); + } + #endif +@@ -120,8 +120,8 @@ + + #ifdef CONFIG_SMP + /* Wait for the secondaries to halt. */ +- set_cpu_present(boot_cpuid, false); +- set_cpu_possible(boot_cpuid, false); ++ cpu_clear(boot_cpuid, cpu_present_map); ++ cpu_clear(boot_cpuid, cpu_possible_map); + while (cpus_weight(cpu_present_map)) + barrier(); + #endif +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/arch/alpha/kernel/signal.c linux-2.6.29-rc3.owrt/arch/alpha/kernel/signal.c +--- linux-2.6.29.owrt/arch/alpha/kernel/signal.c 2009-05-10 22:04:41.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/arch/alpha/kernel/signal.c 2009-05-10 23:48:27.000000000 +0200 +@@ -19,7 +19,6 @@ + #include <linux/tty.h> + #include <linux/binfmts.h> + #include <linux/bitops.h> +-#include <linux/syscalls.h> + + #include <asm/uaccess.h> + #include <asm/sigcontext.h> +@@ -52,8 +51,8 @@ + * Note that we don't need to acquire the kernel lock for SMP + * operation, as all of this is local to this thread. + */ +-SYSCALL_DEFINE3(osf_sigprocmask, int, how, unsigned long, newmask, +- struct pt_regs *, regs) ++asmlinkage unsigned long ++do_osf_sigprocmask(int how, unsigned long newmask, struct pt_regs *regs) + { + unsigned long oldmask = -EINVAL; + +@@ -82,9 +81,9 @@ + return oldmask; + } + +-SYSCALL_DEFINE3(osf_sigaction, int, sig, +- const struct osf_sigaction __user *, act, +- struct osf_sigaction __user *, oact) ++asmlinkage int ++osf_sigaction(int sig, const struct osf_sigaction __user *act, ++ struct osf_sigaction __user *oact) + { + struct k_sigaction new_ka, old_ka; + int ret; +@@ -113,9 +112,10 @@ + return ret; + } + +-SYSCALL_DEFINE5(rt_sigaction, int, sig, const struct sigaction __user *, act, +- struct sigaction __user *, oact, +- size_t, sigsetsize, void __user *, restorer) ++asmlinkage long ++sys_rt_sigaction(int sig, const struct sigaction __user *act, ++ struct sigaction __user *oact, ++ size_t sigsetsize, void __user *restorer) + { + struct k_sigaction new_ka, old_ka; + int ret; +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/arch/alpha/kernel/smp.c linux-2.6.29-rc3.owrt/arch/alpha/kernel/smp.c +--- linux-2.6.29.owrt/arch/alpha/kernel/smp.c 2009-05-10 22:04:41.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/arch/alpha/kernel/smp.c 2009-05-10 23:48:27.000000000 +0200 +@@ -121,11 +121,10 @@ + { + int cpuid = hard_smp_processor_id(); + +- if (cpu_online(cpuid)) { ++ if (cpu_test_and_set(cpuid, cpu_online_map)) { + printk("??, cpu 0x%x already present??\n", cpuid); + BUG(); + } +- set_cpu_online(cpuid, true); + + /* Turn on machine checks. */ + wrmces(7); +@@ -436,8 +435,8 @@ + ((char *)cpubase + i*hwrpb->processor_size); + if ((cpu->flags & 0x1cc) == 0x1cc) { + smp_num_probed++; +- set_cpu_possible(i, true); +- set_cpu_present(i, true); ++ cpu_set(i, cpu_possible_map); ++ cpu_set(i, cpu_present_map); + cpu->pal_revision = boot_cpu_palrev; + } + +@@ -470,8 +469,8 @@ + + /* Nothing to do on a UP box, or when told not to. */ + if (smp_num_probed == 1 || max_cpus == 0) { +- init_cpu_possible(cpumask_of(boot_cpuid)); +- init_cpu_present(cpumask_of(boot_cpuid)); ++ cpu_possible_map = cpumask_of_cpu(boot_cpuid); ++ cpu_present_map = cpumask_of_cpu(boot_cpuid); + printk(KERN_INFO "SMP mode deactivated.\n"); + return; + } +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/arch/alpha/kernel/systbls.S linux-2.6.29-rc3.owrt/arch/alpha/kernel/systbls.S +--- linux-2.6.29.owrt/arch/alpha/kernel/systbls.S 2009-05-10 22:04:41.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/arch/alpha/kernel/systbls.S 2009-05-10 23:48:27.000000000 +0200 +@@ -17,7 +17,7 @@ + .quad sys_write + .quad alpha_ni_syscall /* 5 */ + .quad sys_close +- .quad sys_osf_wait4 ++ .quad osf_wait4 + .quad alpha_ni_syscall + .quad sys_link + .quad sys_unlink /* 10 */ +@@ -27,11 +27,11 @@ + .quad sys_mknod + .quad sys_chmod /* 15 */ + .quad sys_chown +- .quad sys_osf_brk ++ .quad osf_brk + .quad alpha_ni_syscall + .quad sys_lseek + .quad sys_getxpid /* 20 */ +- .quad sys_osf_mount ++ .quad osf_mount + .quad sys_umount + .quad sys_setuid + .quad sys_getxuid +@@ -53,7 +53,7 @@ + .quad alpha_ni_syscall /* 40 */ + .quad sys_dup + .quad sys_alpha_pipe +- .quad sys_osf_set_program_attributes ++ .quad osf_set_program_attributes + .quad alpha_ni_syscall + .quad sys_open /* 45 */ + .quad alpha_ni_syscall +@@ -81,7 +81,7 @@ + .quad sys_newlstat + .quad alpha_ni_syscall + .quad alpha_ni_syscall /* 70 */ +- .quad sys_osf_mmap ++ .quad osf_mmap + .quad alpha_ni_syscall + .quad sys_munmap + .quad sys_mprotect +@@ -94,17 +94,17 @@ + .quad sys_setgroups /* 80 */ + .quad alpha_ni_syscall + .quad sys_setpgid +- .quad sys_osf_setitimer ++ .quad osf_setitimer + .quad alpha_ni_syscall + .quad alpha_ni_syscall /* 85 */ +- .quad sys_osf_getitimer ++ .quad osf_getitimer + .quad sys_gethostname + .quad sys_sethostname + .quad sys_getdtablesize + .quad sys_dup2 /* 90 */ + .quad sys_newfstat + .quad sys_fcntl +- .quad sys_osf_select ++ .quad osf_select + .quad sys_poll + .quad sys_fsync /* 95 */ + .quad sys_setpriority +@@ -123,22 +123,22 @@ + .quad alpha_ni_syscall + .quad alpha_ni_syscall /* 110 */ + .quad sys_sigsuspend +- .quad sys_osf_sigstack ++ .quad osf_sigstack + .quad sys_recvmsg + .quad sys_sendmsg + .quad alpha_ni_syscall /* 115 */ +- .quad sys_osf_gettimeofday +- .quad sys_osf_getrusage ++ .quad osf_gettimeofday ++ .quad osf_getrusage + .quad sys_getsockopt + .quad alpha_ni_syscall + #ifdef CONFIG_OSF4_COMPAT +- .quad sys_osf_readv /* 120 */ +- .quad sys_osf_writev ++ .quad osf_readv /* 120 */ ++ .quad osf_writev + #else + .quad sys_readv /* 120 */ + .quad sys_writev + #endif +- .quad sys_osf_settimeofday ++ .quad osf_settimeofday + .quad sys_fchown + .quad sys_fchmod + .quad sys_recvfrom /* 125 */ +@@ -154,7 +154,7 @@ + .quad sys_socketpair /* 135 */ + .quad sys_mkdir + .quad sys_rmdir +- .quad sys_osf_utimes ++ .quad osf_utimes + .quad alpha_ni_syscall + .quad alpha_ni_syscall /* 140 */ + .quad sys_getpeername +@@ -172,16 +172,16 @@ + .quad alpha_ni_syscall + .quad alpha_ni_syscall + .quad alpha_ni_syscall /* 155 */ +- .quad sys_osf_sigaction ++ .quad osf_sigaction + .quad alpha_ni_syscall + .quad alpha_ni_syscall +- .quad sys_osf_getdirentries +- .quad sys_osf_statfs /* 160 */ +- .quad sys_osf_fstatfs ++ .quad osf_getdirentries ++ .quad osf_statfs /* 160 */ ++ .quad osf_fstatfs + .quad alpha_ni_syscall + .quad alpha_ni_syscall + .quad alpha_ni_syscall +- .quad sys_osf_getdomainname /* 165 */ ++ .quad osf_getdomainname /* 165 */ + .quad sys_setdomainname + .quad alpha_ni_syscall + .quad alpha_ni_syscall +@@ -224,7 +224,7 @@ + .quad sys_semctl + .quad sys_semget /* 205 */ + .quad sys_semop +- .quad sys_osf_utsname ++ .quad osf_utsname + .quad sys_lchown + .quad sys_shmat + .quad sys_shmctl /* 210 */ +@@ -258,23 +258,23 @@ + .quad alpha_ni_syscall + .quad alpha_ni_syscall + .quad alpha_ni_syscall /* 240 */ +- .quad sys_osf_sysinfo ++ .quad osf_sysinfo + .quad alpha_ni_syscall + .quad alpha_ni_syscall +- .quad sys_osf_proplist_syscall ++ .quad osf_proplist_syscall + .quad alpha_ni_syscall /* 245 */ + .quad alpha_ni_syscall + .quad alpha_ni_syscall + .quad alpha_ni_syscall + .quad alpha_ni_syscall + .quad alpha_ni_syscall /* 250 */ +- .quad sys_osf_usleep_thread ++ .quad osf_usleep_thread + .quad alpha_ni_syscall + .quad alpha_ni_syscall + .quad sys_sysfs + .quad alpha_ni_syscall /* 255 */ +- .quad sys_osf_getsysinfo +- .quad sys_osf_setsysinfo ++ .quad osf_getsysinfo ++ .quad osf_setsysinfo + .quad alpha_ni_syscall + .quad alpha_ni_syscall + .quad alpha_ni_syscall /* 260 */ +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/arch/arm/configs/at91sam9260ek_defconfig linux-2.6.29-rc3.owrt/arch/arm/configs/at91sam9260ek_defconfig +--- linux-2.6.29.owrt/arch/arm/configs/at91sam9260ek_defconfig 2009-05-10 22:04:41.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/arch/arm/configs/at91sam9260ek_defconfig 2009-05-10 23:48:27.000000000 +0200 +@@ -608,7 +608,7 @@ + # Watchdog Device Drivers + # + # CONFIG_SOFT_WATCHDOG is not set +-CONFIG_AT91SAM9X_WATCHDOG=y ++CONFIG_AT91SAM9_WATCHDOG=y + + # + # USB-based Watchdog Cards +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/arch/arm/configs/at91sam9261ek_defconfig linux-2.6.29-rc3.owrt/arch/arm/configs/at91sam9261ek_defconfig +--- linux-2.6.29.owrt/arch/arm/configs/at91sam9261ek_defconfig 2009-05-10 22:04:41.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/arch/arm/configs/at91sam9261ek_defconfig 2009-05-10 23:48:27.000000000 +0200 +@@ -700,7 +700,7 @@ + # Watchdog Device Drivers + # + # CONFIG_SOFT_WATCHDOG is not set +-CONFIG_AT91SAM9X_WATCHDOG=y ++CONFIG_AT91SAM9_WATCHDOG=y + + # + # USB-based Watchdog Cards +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/arch/arm/configs/at91sam9263ek_defconfig linux-2.6.29-rc3.owrt/arch/arm/configs/at91sam9263ek_defconfig +--- linux-2.6.29.owrt/arch/arm/configs/at91sam9263ek_defconfig 2009-05-10 22:04:41.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/arch/arm/configs/at91sam9263ek_defconfig 2009-05-10 23:48:27.000000000 +0200 +@@ -710,7 +710,7 @@ + # Watchdog Device Drivers + # + # CONFIG_SOFT_WATCHDOG is not set +-CONFIG_AT91SAM9X_WATCHDOG=y ++CONFIG_AT91SAM9_WATCHDOG=y + + # + # USB-based Watchdog Cards +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/arch/arm/configs/at91sam9rlek_defconfig linux-2.6.29-rc3.owrt/arch/arm/configs/at91sam9rlek_defconfig +--- linux-2.6.29.owrt/arch/arm/configs/at91sam9rlek_defconfig 2009-05-10 22:04:41.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/arch/arm/configs/at91sam9rlek_defconfig 2009-05-10 23:48:27.000000000 +0200 +@@ -606,7 +606,7 @@ + # Watchdog Device Drivers + # + # CONFIG_SOFT_WATCHDOG is not set +-CONFIG_AT91SAM9X_WATCHDOG=y ++CONFIG_AT91SAM9_WATCHDOG=y + + # + # Sonics Silicon Backplane +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/arch/arm/configs/qil-a9260_defconfig linux-2.6.29-rc3.owrt/arch/arm/configs/qil-a9260_defconfig +--- linux-2.6.29.owrt/arch/arm/configs/qil-a9260_defconfig 2009-05-10 22:04:41.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/arch/arm/configs/qil-a9260_defconfig 2009-05-10 23:48:27.000000000 +0200 +@@ -727,7 +727,7 @@ + # Watchdog Device Drivers + # + # CONFIG_SOFT_WATCHDOG is not set +-# CONFIG_AT91SAM9X_WATCHDOG is not set ++# CONFIG_AT91SAM9_WATCHDOG is not set + + # + # USB-based Watchdog Cards +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/arch/arm/kernel/elf.c linux-2.6.29-rc3.owrt/arch/arm/kernel/elf.c +--- linux-2.6.29.owrt/arch/arm/kernel/elf.c 2009-05-10 22:04:41.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/arch/arm/kernel/elf.c 2009-05-10 23:48:27.000000000 +0200 +@@ -74,9 +74,9 @@ + */ + int arm_elf_read_implies_exec(const struct elf32_hdr *x, int executable_stack) + { +- if (executable_stack != EXSTACK_DISABLE_X) ++ if (executable_stack != EXSTACK_ENABLE_X) + return 1; +- if (cpu_architecture() < CPU_ARCH_ARMv6) ++ if (cpu_architecture() <= CPU_ARCH_ARMv6) + return 1; + return 0; + } +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/arch/arm/kernel/entry-armv.S linux-2.6.29-rc3.owrt/arch/arm/kernel/entry-armv.S +--- linux-2.6.29.owrt/arch/arm/kernel/entry-armv.S 2009-05-10 22:04:41.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/arch/arm/kernel/entry-armv.S 2009-05-10 23:48:27.000000000 +0200 +@@ -650,7 +650,6 @@ + no_fp: mov pc, lr + + __und_usr_unknown: +- enable_irq + mov r0, sp + adr lr, ret_from_exception + b do_undefinstr +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/arch/arm/kernel/entry-common.S linux-2.6.29-rc3.owrt/arch/arm/kernel/entry-common.S +--- linux-2.6.29.owrt/arch/arm/kernel/entry-common.S 2009-05-10 22:04:41.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/arch/arm/kernel/entry-common.S 2009-05-10 23:48:27.000000000 +0200 +@@ -111,7 +111,6 @@ + .globl mcount_call + mcount_call: + bl ftrace_stub +- ldr lr, [fp, #-4] @ restore lr + ldmia sp!, {r0-r3, pc} + + ENTRY(ftrace_caller) +@@ -123,7 +122,6 @@ + .globl ftrace_call + ftrace_call: + bl ftrace_stub +- ldr lr, [fp, #-4] @ restore lr + ldmia sp!, {r0-r3, pc} + + #else +@@ -135,16 +133,14 @@ + adr r0, ftrace_stub + cmp r0, r2 + bne trace +- ldr lr, [fp, #-4] @ restore lr + ldmia sp!, {r0-r3, pc} + + trace: +- ldr r1, [fp, #-4] @ lr of instrumented routine ++ ldr r1, [fp, #-4] + mov r0, lr + sub r0, r0, #MCOUNT_INSN_SIZE + mov lr, pc + mov pc, r2 +- mov lr, r1 @ restore lr + ldmia sp!, {r0-r3, pc} + + #endif /* CONFIG_DYNAMIC_FTRACE */ +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/arch/arm/kernel/fiq.c linux-2.6.29-rc3.owrt/arch/arm/kernel/fiq.c +--- linux-2.6.29.owrt/arch/arm/kernel/fiq.c 2009-05-10 22:04:41.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/arch/arm/kernel/fiq.c 2009-05-10 23:48:27.000000000 +0200 +@@ -88,7 +88,7 @@ + * disable irqs for the duration. Note - these functions are almost + * entirely coded in assembly. + */ +-void __naked set_fiq_regs(struct pt_regs *regs) ++void __attribute__((naked)) set_fiq_regs(struct pt_regs *regs) + { + register unsigned long tmp; + asm volatile ( +@@ -106,7 +106,7 @@ + : "r" (®s->ARM_r8), "I" (PSR_I_BIT | PSR_F_BIT | FIQ_MODE)); + } + +-void __naked get_fiq_regs(struct pt_regs *regs) ++void __attribute__((naked)) get_fiq_regs(struct pt_regs *regs) + { + register unsigned long tmp; + asm volatile ( +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/arch/arm/kernel/irq.c linux-2.6.29-rc3.owrt/arch/arm/kernel/irq.c +--- linux-2.6.29.owrt/arch/arm/kernel/irq.c 2009-05-10 22:04:41.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/arch/arm/kernel/irq.c 2009-05-10 23:48:27.000000000 +0200 +@@ -101,7 +101,7 @@ + /* Handle bad interrupts */ + static struct irq_desc bad_irq_desc = { + .handle_irq = handle_bad_irq, +- .lock = __SPIN_LOCK_UNLOCKED(bad_irq_desc.lock), ++ .lock = SPIN_LOCK_UNLOCKED + }; + + /* +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/arch/arm/kernel/machine_kexec.c linux-2.6.29-rc3.owrt/arch/arm/kernel/machine_kexec.c +--- linux-2.6.29.owrt/arch/arm/kernel/machine_kexec.c 2009-05-10 22:04:41.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/arch/arm/kernel/machine_kexec.c 2009-05-10 23:48:27.000000000 +0200 +@@ -13,8 +13,8 @@ + #include <asm/cacheflush.h> + #include <asm/mach-types.h> + +-extern const unsigned char relocate_new_kernel[]; +-extern const unsigned int relocate_new_kernel_size; ++const extern unsigned char relocate_new_kernel[]; ++const extern unsigned int relocate_new_kernel_size; + + extern void setup_mm_for_reboot(char mode); + +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/arch/arm/kernel/setup.c linux-2.6.29-rc3.owrt/arch/arm/kernel/setup.c +--- linux-2.6.29.owrt/arch/arm/kernel/setup.c 2009-05-10 22:04:41.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/arch/arm/kernel/setup.c 2009-05-10 23:48:27.000000000 +0200 +@@ -233,13 +233,12 @@ + unsigned int cachetype = read_cpuid_cachetype(); + unsigned int arch = cpu_architecture(); + +- if (arch >= CPU_ARCH_ARMv6) { +- if ((cachetype & (7 << 29)) == 4 << 29) { +- /* ARMv7 register format */ +- cacheid = CACHEID_VIPT_NONALIASING; +- if ((cachetype & (3 << 14)) == 1 << 14) +- cacheid |= CACHEID_ASID_TAGGED; +- } else if (cachetype & (1 << 23)) ++ if (arch >= CPU_ARCH_ARMv7) { ++ cacheid = CACHEID_VIPT_NONALIASING; ++ if ((cachetype & (3 << 14)) == 1 << 14) ++ cacheid |= CACHEID_ASID_TAGGED; ++ } else if (arch >= CPU_ARCH_ARMv6) { ++ if (cachetype & (1 << 23)) + cacheid = CACHEID_VIPT_ALIASING; + else + cacheid = CACHEID_VIPT_NONALIASING; +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/arch/arm/mach-at91/at91cap9_devices.c linux-2.6.29-rc3.owrt/arch/arm/mach-at91/at91cap9_devices.c +--- linux-2.6.29.owrt/arch/arm/mach-at91/at91cap9_devices.c 2009-05-10 22:04:41.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/arch/arm/mach-at91/at91cap9_devices.c 2009-05-10 23:48:27.000000000 +0200 +@@ -697,7 +697,7 @@ + * Watchdog + * -------------------------------------------------------------------- */ + +-#if defined(CONFIG_AT91SAM9X_WATCHDOG) || defined(CONFIG_AT91SAM9X_WATCHDOG_MODULE) ++#if defined(CONFIG_AT91SAM9_WATCHDOG) || defined(CONFIG_AT91SAM9_WATCHDOG_MODULE) + static struct platform_device at91cap9_wdt_device = { + .name = "at91_wdt", + .id = -1, +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/arch/arm/mach-at91/at91sam9260_devices.c linux-2.6.29-rc3.owrt/arch/arm/mach-at91/at91sam9260_devices.c +--- linux-2.6.29.owrt/arch/arm/mach-at91/at91sam9260_devices.c 2009-05-10 22:04:41.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/arch/arm/mach-at91/at91sam9260_devices.c 2009-05-10 23:48:27.000000000 +0200 +@@ -643,7 +643,7 @@ + * Watchdog + * -------------------------------------------------------------------- */ + +-#if defined(CONFIG_AT91SAM9X_WATCHDOG) || defined(CONFIG_AT91SAM9X_WATCHDOG_MODULE) ++#if defined(CONFIG_AT91SAM9_WATCHDOG) || defined(CONFIG_AT91SAM9_WATCHDOG_MODULE) + static struct platform_device at91sam9260_wdt_device = { + .name = "at91_wdt", + .id = -1, +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/arch/arm/mach-at91/at91sam9261_devices.c linux-2.6.29-rc3.owrt/arch/arm/mach-at91/at91sam9261_devices.c +--- linux-2.6.29.owrt/arch/arm/mach-at91/at91sam9261_devices.c 2009-05-10 22:04:41.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/arch/arm/mach-at91/at91sam9261_devices.c 2009-05-10 23:48:27.000000000 +0200 +@@ -621,7 +621,7 @@ + * Watchdog + * -------------------------------------------------------------------- */ + +-#if defined(CONFIG_AT91SAM9X_WATCHDOG) || defined(CONFIG_AT91SAM9X_WATCHDOG_MODULE) ++#if defined(CONFIG_AT91SAM9_WATCHDOG) || defined(CONFIG_AT91SAM9_WATCHDOG_MODULE) + static struct platform_device at91sam9261_wdt_device = { + .name = "at91_wdt", + .id = -1, +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/arch/arm/mach-at91/at91sam9263_devices.c linux-2.6.29-rc3.owrt/arch/arm/mach-at91/at91sam9263_devices.c +--- linux-2.6.29.owrt/arch/arm/mach-at91/at91sam9263_devices.c 2009-05-10 22:04:41.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/arch/arm/mach-at91/at91sam9263_devices.c 2009-05-10 23:48:27.000000000 +0200 +@@ -347,111 +347,6 @@ + void __init at91_add_device_mmc(short mmc_id, struct at91_mmc_data *data) {} + #endif + +-/* -------------------------------------------------------------------- +- * Compact Flash (PCMCIA or IDE) +- * -------------------------------------------------------------------- */ +- +-#if defined(CONFIG_AT91_CF) || defined(CONFIG_AT91_CF_MODULE) || \ +- defined(CONFIG_BLK_DEV_IDE_AT91) || defined(CONFIG_BLK_DEV_IDE_AT91_MODULE) +- +-static struct at91_cf_data cf0_data; +- +-static struct resource cf0_resources[] = { +- [0] = { +- .start = AT91_CHIPSELECT_4, +- .end = AT91_CHIPSELECT_4 + SZ_256M - 1, +- .flags = IORESOURCE_MEM | IORESOURCE_MEM_8AND16BIT, +- } +-}; +- +-static struct platform_device cf0_device = { +- .id = 0, +- .dev = { +- .platform_data = &cf0_data, +- }, +- .resource = cf0_resources, +- .num_resources = ARRAY_SIZE(cf0_resources), +-}; +- +-static struct at91_cf_data cf1_data; +- +-static struct resource cf1_resources[] = { +- [0] = { +- .start = AT91_CHIPSELECT_5, +- .end = AT91_CHIPSELECT_5 + SZ_256M - 1, +- .flags = IORESOURCE_MEM | IORESOURCE_MEM_8AND16BIT, +- } +-}; +- +-static struct platform_device cf1_device = { +- .id = 1, +- .dev = { +- .platform_data = &cf1_data, +- }, +- .resource = cf1_resources, +- .num_resources = ARRAY_SIZE(cf1_resources), +-}; +- +-void __init at91_add_device_cf(struct at91_cf_data *data) +-{ +- unsigned long ebi0_csa; +- struct platform_device *pdev; +- +- if (!data) +- return; +- +- /* +- * assign CS4 or CS5 to SMC with Compact Flash logic support, +- * we assume SMC timings are configured by board code, +- * except True IDE where timings are controlled by driver +- */ +- ebi0_csa = at91_sys_read(AT91_MATRIX_EBI0CSA); +- switch (data->chipselect) { +- case 4: +- at91_set_A_periph(AT91_PIN_PD6, 0); /* EBI0_NCS4/CFCS0 */ +- ebi0_csa |= AT91_MATRIX_EBI0_CS4A_SMC_CF1; +- cf0_data = *data; +- pdev = &cf0_device; +- break; +- case 5: +- at91_set_A_periph(AT91_PIN_PD7, 0); /* EBI0_NCS5/CFCS1 */ +- ebi0_csa |= AT91_MATRIX_EBI0_CS5A_SMC_CF2; +- cf1_data = *data; +- pdev = &cf1_device; +- break; +- default: +- printk(KERN_ERR "AT91 CF: bad chip-select requested (%u)\n", +- data->chipselect); +- return; +- } +- at91_sys_write(AT91_MATRIX_EBI0CSA, ebi0_csa); +- +- if (data->det_pin) { +- at91_set_gpio_input(data->det_pin, 1); +- at91_set_deglitch(data->det_pin, 1); +- } +- +- if (data->irq_pin) { +- at91_set_gpio_input(data->irq_pin, 1); +- at91_set_deglitch(data->irq_pin, 1); +- } +- +- if (data->vcc_pin) +- /* initially off */ +- at91_set_gpio_output(data->vcc_pin, 0); +- +- /* enable EBI controlled pins */ +- at91_set_A_periph(AT91_PIN_PD5, 1); /* NWAIT */ +- at91_set_A_periph(AT91_PIN_PD8, 0); /* CFCE1 */ +- at91_set_A_periph(AT91_PIN_PD9, 0); /* CFCE2 */ +- at91_set_A_periph(AT91_PIN_PD14, 0); /* CFNRW */ +- +- pdev->name = (data->flags & AT91_CF_TRUE_IDE) ? "at91_ide" : "at91_cf"; +- platform_device_register(pdev); +-} +-#else +-void __init at91_add_device_cf(struct at91_cf_data *data) {} +-#endif + + /* -------------------------------------------------------------------- + * NAND / SmartMedia +@@ -959,7 +854,7 @@ + * Watchdog + * -------------------------------------------------------------------- */ + +-#if defined(CONFIG_AT91SAM9X_WATCHDOG) || defined(CONFIG_AT91SAM9X_WATCHDOG_MODULE) ++#if defined(CONFIG_AT91SAM9_WATCHDOG) || defined(CONFIG_AT91SAM9_WATCHDOG_MODULE) + static struct platform_device at91sam9263_wdt_device = { + .name = "at91_wdt", + .id = -1, +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/arch/arm/mach-at91/at91sam9rl_devices.c linux-2.6.29-rc3.owrt/arch/arm/mach-at91/at91sam9rl_devices.c +--- linux-2.6.29.owrt/arch/arm/mach-at91/at91sam9rl_devices.c 2009-05-10 22:04:41.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/arch/arm/mach-at91/at91sam9rl_devices.c 2009-05-10 23:48:27.000000000 +0200 +@@ -609,7 +609,7 @@ + * Watchdog + * -------------------------------------------------------------------- */ + +-#if defined(CONFIG_AT91SAM9X_WATCHDOG) || defined(CONFIG_AT91SAM9X_WATCHDOG_MODULE) ++#if defined(CONFIG_AT91SAM9_WATCHDOG) || defined(CONFIG_AT91SAM9_WATCHDOG_MODULE) + static struct platform_device at91sam9rl_wdt_device = { + .name = "at91_wdt", + .id = -1, +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/arch/arm/mach-at91/gpio.c linux-2.6.29-rc3.owrt/arch/arm/mach-at91/gpio.c +--- linux-2.6.29.owrt/arch/arm/mach-at91/gpio.c 2009-05-10 22:04:41.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/arch/arm/mach-at91/gpio.c 2009-05-10 23:48:27.000000000 +0200 +@@ -490,8 +490,7 @@ + + /*--------------------------------------------------------------------------*/ + +-/* +- * This lock class tells lockdep that GPIO irqs are in a different ++/* This lock class tells lockdep that GPIO irqs are in a different + * category than their parents, so it won't report false recursion. + */ + static struct lock_class_key gpio_lock_class; +@@ -510,6 +509,9 @@ + unsigned id = this->id; + unsigned i; + ++ /* enable PIO controller's clock */ ++ clk_enable(this->clock); ++ + __raw_writel(~0, this->regbase + PIO_IDR); + + for (i = 0, pin = this->chipbase; i < 32; i++, pin++) { +@@ -554,14 +556,7 @@ + data->chipbase = PIN_BASE + i * 32; + data->regbase = data->offset + (void __iomem *)AT91_VA_BASE_SYS; + +- /* enable PIO controller's clock */ +- clk_enable(data->clock); +- +- /* +- * Some processors share peripheral ID between multiple GPIO banks. +- * SAM9263 (PIOC, PIOD, PIOE) +- * CAP9 (PIOA, PIOB, PIOC, PIOD) +- */ ++ /* AT91SAM9263_ID_PIOCDE groups PIOC, PIOD, PIOE */ + if (last && last->id == data->id) + last->next = data; + } +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/arch/arm/mach-at91/include/mach/board.h linux-2.6.29-rc3.owrt/arch/arm/mach-at91/include/mach/board.h +--- linux-2.6.29.owrt/arch/arm/mach-at91/include/mach/board.h 2009-05-10 22:04:41.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/arch/arm/mach-at91/include/mach/board.h 2009-05-10 23:48:27.000000000 +0200 +@@ -56,9 +56,6 @@ + u8 vcc_pin; /* power switching */ + u8 rst_pin; /* card reset */ + u8 chipselect; /* EBI Chip Select number */ +- u8 flags; +-#define AT91_CF_TRUE_IDE 0x01 +-#define AT91_IDE_SWAP_A0_A2 0x02 + }; + extern void __init at91_add_device_cf(struct at91_cf_data *data); + +@@ -96,7 +93,6 @@ + u8 enable_pin; /* chip enable */ + u8 det_pin; /* card detect */ + u8 rdy_pin; /* ready/busy */ +- u8 rdy_pin_active_low; /* rdy_pin value is inverted */ + u8 ale; /* address line number connected to ALE */ + u8 cle; /* address line number connected to CLE */ + u8 bus_width_16; /* buswidth is 16 bit */ +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/arch/arm/mach-at91/pm.c linux-2.6.29-rc3.owrt/arch/arm/mach-at91/pm.c +--- linux-2.6.29.owrt/arch/arm/mach-at91/pm.c 2009-05-10 22:04:41.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/arch/arm/mach-at91/pm.c 2009-05-10 23:48:27.000000000 +0200 +@@ -332,6 +332,7 @@ + at91_sys_read(AT91_AIC_IPR) & at91_sys_read(AT91_AIC_IMR)); + + error: ++ sdram_selfrefresh_disable(); + target_state = PM_SUSPEND_ON; + at91_irq_resume(); + at91_gpio_resume(); +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/arch/arm/mach-davinci/board-evm.c linux-2.6.29-rc3.owrt/arch/arm/mach-davinci/board-evm.c +--- linux-2.6.29.owrt/arch/arm/mach-davinci/board-evm.c 2009-05-10 22:04:41.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/arch/arm/mach-davinci/board-evm.c 2009-05-10 23:48:27.000000000 +0200 +@@ -311,9 +311,6 @@ + gpio_request(gpio + 7, "nCF_SEL"); + gpio_direction_output(gpio + 7, 1); + +- /* irlml6401 sustains over 3A, switches 5V in under 8 msec */ +- setup_usb(500, 8); +- + return 0; + } + +@@ -420,6 +417,9 @@ + platform_add_devices(davinci_evm_devices, + ARRAY_SIZE(davinci_evm_devices)); + evm_init_i2c(); ++ ++ /* irlml6401 sustains over 3A, switches 5V in under 8 msec */ ++ setup_usb(500, 8); + } + + static __init void davinci_evm_irq_init(void) +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/arch/arm/mach-davinci/clock.c linux-2.6.29-rc3.owrt/arch/arm/mach-davinci/clock.c +--- linux-2.6.29.owrt/arch/arm/mach-davinci/clock.c 2009-05-10 22:04:41.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/arch/arm/mach-davinci/clock.c 2009-05-10 23:48:27.000000000 +0200 +@@ -231,11 +231,6 @@ + .lpsc = DAVINCI_LPSC_GPIO, + }, + { +- .name = "usb", +- .rate = &commonrate, +- .lpsc = DAVINCI_LPSC_USB, +- }, +- { + .name = "AEMIFCLK", + .rate = &commonrate, + .lpsc = DAVINCI_LPSC_AEMIF, +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/arch/arm/mach-davinci/usb.c linux-2.6.29-rc3.owrt/arch/arm/mach-davinci/usb.c +--- linux-2.6.29.owrt/arch/arm/mach-davinci/usb.c 2009-05-10 22:04:41.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/arch/arm/mach-davinci/usb.c 2009-05-10 23:48:27.000000000 +0200 +@@ -47,7 +47,6 @@ + #elif defined(CONFIG_USB_MUSB_HOST) + .mode = MUSB_HOST, + #endif +- .clock = "usb", + .config = &musb_config, + }; + +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/arch/arm/mach-ep93xx/include/mach/gesbc9312.h linux-2.6.29-rc3.owrt/arch/arm/mach-ep93xx/include/mach/gesbc9312.h +--- linux-2.6.29.owrt/arch/arm/mach-ep93xx/include/mach/gesbc9312.h 1970-01-01 01:00:00.000000000 +0100 ++++ linux-2.6.29-rc3.owrt/arch/arm/mach-ep93xx/include/mach/gesbc9312.h 2009-05-10 23:48:27.000000000 +0200 +@@ -0,0 +1,3 @@ ++/* ++ * arch/arm/mach-ep93xx/include/mach/gesbc9312.h ++ */ +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/arch/arm/mach-ep93xx/include/mach/hardware.h linux-2.6.29-rc3.owrt/arch/arm/mach-ep93xx/include/mach/hardware.h +--- linux-2.6.29.owrt/arch/arm/mach-ep93xx/include/mach/hardware.h 2009-05-10 22:04:41.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/arch/arm/mach-ep93xx/include/mach/hardware.h 2009-05-10 23:48:27.000000000 +0200 +@@ -10,6 +10,7 @@ + + #include "platform.h" + ++#include "gesbc9312.h" + #include "ts72xx.h" + + #endif +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/arch/arm/mach-ep93xx/include/mach/platform.h linux-2.6.29-rc3.owrt/arch/arm/mach-ep93xx/include/mach/platform.h +--- linux-2.6.29.owrt/arch/arm/mach-ep93xx/include/mach/platform.h 2009-05-10 22:04:41.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/arch/arm/mach-ep93xx/include/mach/platform.h 2009-05-10 23:48:27.000000000 +0200 +@@ -4,8 +4,6 @@ + + #ifndef __ASSEMBLY__ + +-struct i2c_board_info; +- + struct ep93xx_eth_data + { + unsigned char dev_addr[6]; +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/arch/arm/mach-kirkwood/irq.c linux-2.6.29-rc3.owrt/arch/arm/mach-kirkwood/irq.c +--- linux-2.6.29.owrt/arch/arm/mach-kirkwood/irq.c 2009-05-10 22:04:41.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/arch/arm/mach-kirkwood/irq.c 2009-05-10 23:48:27.000000000 +0200 +@@ -42,7 +42,7 @@ + writel(0, GPIO_EDGE_CAUSE(32)); + + for (i = IRQ_KIRKWOOD_GPIO_START; i < NR_IRQS; i++) { +- set_irq_chip(i, &orion_gpio_irq_chip); ++ set_irq_chip(i, &orion_gpio_irq_level_chip); + set_irq_handler(i, handle_level_irq); + irq_desc[i].status |= IRQ_LEVEL; + set_irq_flags(i, IRQF_VALID); +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/arch/arm/mach-msm/board-halibut.c linux-2.6.29-rc3.owrt/arch/arm/mach-msm/board-halibut.c +--- linux-2.6.29.owrt/arch/arm/mach-msm/board-halibut.c 2009-05-10 22:04:41.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/arch/arm/mach-msm/board-halibut.c 2009-05-10 23:48:27.000000000 +0200 +@@ -27,7 +27,6 @@ + #include <asm/mach/map.h> + #include <asm/mach/flash.h> + +-#include <mach/irqs.h> + #include <mach/board.h> + #include <mach/msm_iomap.h> + +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/arch/arm/mach-mv78xx0/irq.c linux-2.6.29-rc3.owrt/arch/arm/mach-mv78xx0/irq.c +--- linux-2.6.29.owrt/arch/arm/mach-mv78xx0/irq.c 2009-05-10 22:04:41.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/arch/arm/mach-mv78xx0/irq.c 2009-05-10 23:48:27.000000000 +0200 +@@ -40,7 +40,7 @@ + writel(0, GPIO_EDGE_CAUSE(0)); + + for (i = IRQ_MV78XX0_GPIO_START; i < NR_IRQS; i++) { +- set_irq_chip(i, &orion_gpio_irq_chip); ++ set_irq_chip(i, &orion_gpio_irq_level_chip); + set_irq_handler(i, handle_level_irq); + irq_desc[i].status |= IRQ_LEVEL; + set_irq_flags(i, IRQF_VALID); +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/arch/arm/mach-mx1/devices.c linux-2.6.29-rc3.owrt/arch/arm/mach-mx1/devices.c +--- linux-2.6.29.owrt/arch/arm/mach-mx1/devices.c 2009-05-10 22:04:41.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/arch/arm/mach-mx1/devices.c 2009-05-10 23:48:27.000000000 +0200 +@@ -23,8 +23,6 @@ + #include <linux/init.h> + #include <linux/platform_device.h> + #include <linux/gpio.h> +- +-#include <mach/irqs.h> + #include <mach/hardware.h> + + static struct resource imx_csi_resources[] = { +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/arch/arm/mach-mx1/mx1ads.c linux-2.6.29-rc3.owrt/arch/arm/mach-mx1/mx1ads.c +--- linux-2.6.29.owrt/arch/arm/mach-mx1/mx1ads.c 2009-05-10 22:04:41.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/arch/arm/mach-mx1/mx1ads.c 2009-05-10 23:48:27.000000000 +0200 +@@ -21,7 +21,6 @@ + #include <asm/mach/arch.h> + #include <asm/mach/time.h> + +-#include <mach/irqs.h> + #include <mach/hardware.h> + #include <mach/common.h> + #include <mach/imx-uart.h> +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/arch/arm/mach-omap1/devices.c linux-2.6.29-rc3.owrt/arch/arm/mach-omap1/devices.c +--- linux-2.6.29.owrt/arch/arm/mach-omap1/devices.c 2009-05-10 22:04:41.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/arch/arm/mach-omap1/devices.c 2009-05-10 23:48:27.000000000 +0200 +@@ -181,7 +181,7 @@ + } + size = OMAP1_MMC_SIZE; + +- omap_mmc_add("mmci-omap", i, base, size, irq, mmc_data[i]); ++ omap_mmc_add(i, base, size, irq, mmc_data[i]); + }; + } + +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/arch/arm/mach-omap1/mcbsp.c linux-2.6.29-rc3.owrt/arch/arm/mach-omap1/mcbsp.c +--- linux-2.6.29.owrt/arch/arm/mach-omap1/mcbsp.c 2009-05-10 22:04:41.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/arch/arm/mach-omap1/mcbsp.c 2009-05-10 23:48:27.000000000 +0200 +@@ -28,8 +28,81 @@ + #define DPS_RSTCT2_PER_EN (1 << 0) + #define DSP_RSTCT2_WD_PER_EN (1 << 1) + ++struct mcbsp_internal_clk { ++ struct clk clk; ++ struct clk **childs; ++ int n_childs; ++}; ++ + #if defined(CONFIG_ARCH_OMAP15XX) || defined(CONFIG_ARCH_OMAP16XX) +-const char *clk_names[] = { "dsp_ck", "api_ck", "dspxor_ck" }; ++static void omap_mcbsp_clk_init(struct mcbsp_internal_clk *mclk) ++{ ++ const char *clk_names[] = { "dsp_ck", "api_ck", "dspxor_ck" }; ++ int i; ++ ++ mclk->n_childs = ARRAY_SIZE(clk_names); ++ mclk->childs = kzalloc(mclk->n_childs * sizeof(struct clk *), ++ GFP_KERNEL); ++ ++ for (i = 0; i < mclk->n_childs; i++) { ++ /* We fake a platform device to get correct device id */ ++ struct platform_device pdev; ++ ++ pdev.dev.bus = &platform_bus_type; ++ pdev.id = mclk->clk.id; ++ mclk->childs[i] = clk_get(&pdev.dev, clk_names[i]); ++ if (IS_ERR(mclk->childs[i])) ++ printk(KERN_ERR "Could not get clock %s (%d).\n", ++ clk_names[i], mclk->clk.id); ++ } ++} ++ ++static int omap_mcbsp_clk_enable(struct clk *clk) ++{ ++ struct mcbsp_internal_clk *mclk = container_of(clk, ++ struct mcbsp_internal_clk, clk); ++ int i; ++ ++ for (i = 0; i < mclk->n_childs; i++) ++ clk_enable(mclk->childs[i]); ++ return 0; ++} ++ ++static void omap_mcbsp_clk_disable(struct clk *clk) ++{ ++ struct mcbsp_internal_clk *mclk = container_of(clk, ++ struct mcbsp_internal_clk, clk); ++ int i; ++ ++ for (i = 0; i < mclk->n_childs; i++) ++ clk_disable(mclk->childs[i]); ++} ++ ++static struct mcbsp_internal_clk omap_mcbsp_clks[] = { ++ { ++ .clk = { ++ .name = "mcbsp_clk", ++ .id = 1, ++ .enable = omap_mcbsp_clk_enable, ++ .disable = omap_mcbsp_clk_disable, ++ }, ++ }, ++ { ++ .clk = { ++ .name = "mcbsp_clk", ++ .id = 3, ++ .enable = omap_mcbsp_clk_enable, ++ .disable = omap_mcbsp_clk_disable, ++ }, ++ }, ++}; ++ ++#define omap_mcbsp_clks_size ARRAY_SIZE(omap_mcbsp_clks) ++#else ++#define omap_mcbsp_clks_size 0 ++static struct mcbsp_internal_clk __initdata *omap_mcbsp_clks; ++static inline void omap_mcbsp_clk_init(struct mcbsp_internal_clk *mclk) ++{ } + #endif + + static void omap1_mcbsp_request(unsigned int id) +@@ -94,9 +167,8 @@ + .rx_irq = INT_McBSP1RX, + .tx_irq = INT_McBSP1TX, + .ops = &omap1_mcbsp_ops, +- .clk_names = clk_names, +- .num_clks = 3, +- }, ++ .clk_name = "mcbsp_clk", ++ }, + { + .phys_base = OMAP1510_MCBSP2_BASE, + .dma_rx_sync = OMAP_DMA_MCBSP2_RX, +@@ -112,8 +184,7 @@ + .rx_irq = INT_McBSP3RX, + .tx_irq = INT_McBSP3TX, + .ops = &omap1_mcbsp_ops, +- .clk_names = clk_names, +- .num_clks = 3, ++ .clk_name = "mcbsp_clk", + }, + }; + #define OMAP15XX_MCBSP_PDATA_SZ ARRAY_SIZE(omap15xx_mcbsp_pdata) +@@ -131,8 +202,7 @@ + .rx_irq = INT_McBSP1RX, + .tx_irq = INT_McBSP1TX, + .ops = &omap1_mcbsp_ops, +- .clk_names = clk_names, +- .num_clks = 3, ++ .clk_name = "mcbsp_clk", + }, + { + .phys_base = OMAP1610_MCBSP2_BASE, +@@ -149,8 +219,7 @@ + .rx_irq = INT_McBSP3RX, + .tx_irq = INT_McBSP3TX, + .ops = &omap1_mcbsp_ops, +- .clk_names = clk_names, +- .num_clks = 3, ++ .clk_name = "mcbsp_clk", + }, + }; + #define OMAP16XX_MCBSP_PDATA_SZ ARRAY_SIZE(omap16xx_mcbsp_pdata) +@@ -161,6 +230,15 @@ + + int __init omap1_mcbsp_init(void) + { ++ int i; ++ ++ for (i = 0; i < omap_mcbsp_clks_size; i++) { ++ if (cpu_is_omap15xx() || cpu_is_omap16xx()) { ++ omap_mcbsp_clk_init(&omap_mcbsp_clks[i]); ++ clk_register(&omap_mcbsp_clks[i].clk); ++ } ++ } ++ + if (cpu_is_omap730()) + omap_mcbsp_count = OMAP730_MCBSP_PDATA_SZ; + if (cpu_is_omap15xx()) +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/arch/arm/mach-omap2/board-ldp.c linux-2.6.29-rc3.owrt/arch/arm/mach-omap2/board-ldp.c +--- linux-2.6.29.owrt/arch/arm/mach-omap2/board-ldp.c 2009-05-10 22:04:41.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/arch/arm/mach-omap2/board-ldp.c 2009-05-10 23:48:27.000000000 +0200 +@@ -81,7 +81,7 @@ + } + + ldp_smc911x_resources[0].start = cs_mem_base + 0x0; +- ldp_smc911x_resources[0].end = cs_mem_base + 0xff; ++ ldp_smc911x_resources[0].end = cs_mem_base + 0xf; + udelay(100); + + eth_gpio = LDP_SMC911X_GPIO; +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/arch/arm/mach-omap2/board-omap3beagle.c linux-2.6.29-rc3.owrt/arch/arm/mach-omap2/board-omap3beagle.c +--- linux-2.6.29.owrt/arch/arm/mach-omap2/board-omap3beagle.c 2009-05-10 22:04:41.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/arch/arm/mach-omap2/board-omap3beagle.c 2009-05-10 23:48:27.000000000 +0200 +@@ -178,9 +178,7 @@ + #ifdef CONFIG_I2C2_OMAP_BEAGLE + omap_register_i2c_bus(2, 400, NULL, 0); + #endif +- /* Bus 3 is attached to the DVI port where devices like the pico DLP +- * projector don't work reliably with 400kHz */ +- omap_register_i2c_bus(3, 100, NULL, 0); ++ omap_register_i2c_bus(3, 400, NULL, 0); + return 0; + } + +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/arch/arm/mach-omap2/clock.c linux-2.6.29-rc3.owrt/arch/arm/mach-omap2/clock.c +--- linux-2.6.29.owrt/arch/arm/mach-omap2/clock.c 2009-05-10 22:04:41.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/arch/arm/mach-omap2/clock.c 2009-05-10 23:48:27.000000000 +0200 +@@ -565,7 +565,7 @@ + * + * Given a struct clk of a rate-selectable clksel clock, and a clock divisor, + * find the corresponding register field value. The return register value is +- * the value before left-shifting. Returns ~0 on error ++ * the value before left-shifting. Returns 0xffffffff on error + */ + u32 omap2_divisor_to_clksel(struct clk *clk, u32 div) + { +@@ -577,7 +577,7 @@ + + clks = omap2_get_clksel_by_parent(clk, clk->parent); + if (clks == NULL) +- return ~0; ++ return 0; + + for (clkr = clks->rates; clkr->div; clkr++) { + if ((clkr->flags & cpu_mask) && (clkr->div == div)) +@@ -588,7 +588,7 @@ + printk(KERN_ERR "clock: Could not find divisor %d for " + "clock %s parent %s\n", div, clk->name, + clk->parent->name); +- return ~0; ++ return 0; + } + + return clkr->val; +@@ -708,7 +708,7 @@ + return 0; + + for (clkr = clks->rates; clkr->div; clkr++) { +- if (clkr->flags & cpu_mask && clkr->flags & DEFAULT_RATE) ++ if (clkr->flags & (cpu_mask | DEFAULT_RATE)) + break; /* Found the default rate for this platform */ + } + +@@ -746,7 +746,7 @@ + return -EINVAL; + + if (clk->usecount > 0) +- omap2_clk_disable(clk); ++ _omap2_clk_disable(clk); + + /* Set new source value (previous dividers if any in effect) */ + reg_val = __raw_readl(src_addr) & ~field_mask; +@@ -759,10 +759,10 @@ + wmb(); + } + +- clk->parent = new_parent; +- + if (clk->usecount > 0) +- omap2_clk_enable(clk); ++ _omap2_clk_enable(clk); ++ ++ clk->parent = new_parent; + + /* CLKSEL clocks follow their parents' rates, divided by a divisor */ + clk->rate = new_parent->rate; +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/arch/arm/mach-omap2/devices.c linux-2.6.29-rc3.owrt/arch/arm/mach-omap2/devices.c +--- linux-2.6.29.owrt/arch/arm/mach-omap2/devices.c 2009-05-10 22:04:41.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/arch/arm/mach-omap2/devices.c 2009-05-10 23:48:27.000000000 +0200 +@@ -421,7 +421,6 @@ + int nr_controllers) + { + int i; +- char *name; + + for (i = 0; i < nr_controllers; i++) { + unsigned long base, size; +@@ -451,14 +450,12 @@ + continue; + } + +- if (cpu_is_omap2420()) { ++ if (cpu_is_omap2420()) + size = OMAP2420_MMC_SIZE; +- name = "mmci-omap"; +- } else { ++ else + size = HSMMC_SIZE; +- name = "mmci-omap-hs"; +- } +- omap_mmc_add(name, i, base, size, irq, mmc_data[i]); ++ ++ omap_mmc_add(i, base, size, irq, mmc_data[i]); + }; + } + +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/arch/arm/mach-omap2/id.c linux-2.6.29-rc3.owrt/arch/arm/mach-omap2/id.c +--- linux-2.6.29.owrt/arch/arm/mach-omap2/id.c 2009-05-10 22:04:41.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/arch/arm/mach-omap2/id.c 2009-05-10 23:48:27.000000000 +0200 +@@ -172,13 +172,9 @@ + omap_revision = OMAP3430_REV_ES3_0; + rev_name = "ES3.0"; + break; +- case 4: +- omap_revision = OMAP3430_REV_ES3_1; +- rev_name = "ES3.1"; +- break; + default: + /* Use the latest known revision as default */ +- omap_revision = OMAP3430_REV_ES3_1; ++ omap_revision = OMAP3430_REV_ES3_0; + rev_name = "Unknown revision\n"; + } + } +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/arch/arm/mach-omap2/irq.c linux-2.6.29-rc3.owrt/arch/arm/mach-omap2/irq.c +--- linux-2.6.29.owrt/arch/arm/mach-omap2/irq.c 2009-05-10 22:04:41.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/arch/arm/mach-omap2/irq.c 2009-05-10 23:48:27.000000000 +0200 +@@ -134,7 +134,6 @@ + .ack = omap_mask_ack_irq, + .mask = omap_mask_irq, + .unmask = omap_unmask_irq, +- .disable = omap_mask_irq, + }; + + static void __init omap_irq_bank_init_one(struct omap_irq_bank *bank) +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/arch/arm/mach-omap2/mcbsp.c linux-2.6.29-rc3.owrt/arch/arm/mach-omap2/mcbsp.c +--- linux-2.6.29.owrt/arch/arm/mach-omap2/mcbsp.c 2009-05-10 22:04:41.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/arch/arm/mach-omap2/mcbsp.c 2009-05-10 23:48:27.000000000 +0200 +@@ -24,7 +24,106 @@ + #include <mach/cpu.h> + #include <mach/mcbsp.h> + +-const char *clk_names[] = { "mcbsp_ick", "mcbsp_fck" }; ++struct mcbsp_internal_clk { ++ struct clk clk; ++ struct clk **childs; ++ int n_childs; ++}; ++ ++#if defined(CONFIG_ARCH_OMAP24XX) || defined(CONFIG_ARCH_OMAP34XX) ++static void omap_mcbsp_clk_init(struct mcbsp_internal_clk *mclk) ++{ ++ const char *clk_names[] = { "mcbsp_ick", "mcbsp_fck" }; ++ int i; ++ ++ mclk->n_childs = ARRAY_SIZE(clk_names); ++ mclk->childs = kzalloc(mclk->n_childs * sizeof(struct clk *), ++ GFP_KERNEL); ++ ++ for (i = 0; i < mclk->n_childs; i++) { ++ /* We fake a platform device to get correct device id */ ++ struct platform_device pdev; ++ ++ pdev.dev.bus = &platform_bus_type; ++ pdev.id = mclk->clk.id; ++ mclk->childs[i] = clk_get(&pdev.dev, clk_names[i]); ++ if (IS_ERR(mclk->childs[i])) ++ printk(KERN_ERR "Could not get clock %s (%d).\n", ++ clk_names[i], mclk->clk.id); ++ } ++} ++ ++static int omap_mcbsp_clk_enable(struct clk *clk) ++{ ++ struct mcbsp_internal_clk *mclk = container_of(clk, ++ struct mcbsp_internal_clk, clk); ++ int i; ++ ++ for (i = 0; i < mclk->n_childs; i++) ++ clk_enable(mclk->childs[i]); ++ return 0; ++} ++ ++static void omap_mcbsp_clk_disable(struct clk *clk) ++{ ++ struct mcbsp_internal_clk *mclk = container_of(clk, ++ struct mcbsp_internal_clk, clk); ++ int i; ++ ++ for (i = 0; i < mclk->n_childs; i++) ++ clk_disable(mclk->childs[i]); ++} ++ ++static struct mcbsp_internal_clk omap_mcbsp_clks[] = { ++ { ++ .clk = { ++ .name = "mcbsp_clk", ++ .id = 1, ++ .enable = omap_mcbsp_clk_enable, ++ .disable = omap_mcbsp_clk_disable, ++ }, ++ }, ++ { ++ .clk = { ++ .name = "mcbsp_clk", ++ .id = 2, ++ .enable = omap_mcbsp_clk_enable, ++ .disable = omap_mcbsp_clk_disable, ++ }, ++ }, ++ { ++ .clk = { ++ .name = "mcbsp_clk", ++ .id = 3, ++ .enable = omap_mcbsp_clk_enable, ++ .disable = omap_mcbsp_clk_disable, ++ }, ++ }, ++ { ++ .clk = { ++ .name = "mcbsp_clk", ++ .id = 4, ++ .enable = omap_mcbsp_clk_enable, ++ .disable = omap_mcbsp_clk_disable, ++ }, ++ }, ++ { ++ .clk = { ++ .name = "mcbsp_clk", ++ .id = 5, ++ .enable = omap_mcbsp_clk_enable, ++ .disable = omap_mcbsp_clk_disable, ++ }, ++ }, ++}; ++ ++#define omap_mcbsp_clks_size ARRAY_SIZE(omap_mcbsp_clks) ++#else ++#define omap_mcbsp_clks_size 0 ++static struct mcbsp_internal_clk __initdata *omap_mcbsp_clks; ++static inline void omap_mcbsp_clk_init(struct clk *clk) ++{ } ++#endif + + static void omap2_mcbsp2_mux_setup(void) + { +@@ -57,8 +156,7 @@ + .rx_irq = INT_24XX_MCBSP1_IRQ_RX, + .tx_irq = INT_24XX_MCBSP1_IRQ_TX, + .ops = &omap2_mcbsp_ops, +- .clk_names = clk_names, +- .num_clks = 2, ++ .clk_name = "mcbsp_clk", + }, + { + .phys_base = OMAP24XX_MCBSP2_BASE, +@@ -67,8 +165,7 @@ + .rx_irq = INT_24XX_MCBSP2_IRQ_RX, + .tx_irq = INT_24XX_MCBSP2_IRQ_TX, + .ops = &omap2_mcbsp_ops, +- .clk_names = clk_names, +- .num_clks = 2, ++ .clk_name = "mcbsp_clk", + }, + }; + #define OMAP2420_MCBSP_PDATA_SZ ARRAY_SIZE(omap2420_mcbsp_pdata) +@@ -86,8 +183,7 @@ + .rx_irq = INT_24XX_MCBSP1_IRQ_RX, + .tx_irq = INT_24XX_MCBSP1_IRQ_TX, + .ops = &omap2_mcbsp_ops, +- .clk_names = clk_names, +- .num_clks = 2, ++ .clk_name = "mcbsp_clk", + }, + { + .phys_base = OMAP24XX_MCBSP2_BASE, +@@ -96,8 +192,7 @@ + .rx_irq = INT_24XX_MCBSP2_IRQ_RX, + .tx_irq = INT_24XX_MCBSP2_IRQ_TX, + .ops = &omap2_mcbsp_ops, +- .clk_names = clk_names, +- .num_clks = 2, ++ .clk_name = "mcbsp_clk", + }, + { + .phys_base = OMAP2430_MCBSP3_BASE, +@@ -106,8 +201,7 @@ + .rx_irq = INT_24XX_MCBSP3_IRQ_RX, + .tx_irq = INT_24XX_MCBSP3_IRQ_TX, + .ops = &omap2_mcbsp_ops, +- .clk_names = clk_names, +- .num_clks = 2, ++ .clk_name = "mcbsp_clk", + }, + { + .phys_base = OMAP2430_MCBSP4_BASE, +@@ -116,8 +210,7 @@ + .rx_irq = INT_24XX_MCBSP4_IRQ_RX, + .tx_irq = INT_24XX_MCBSP4_IRQ_TX, + .ops = &omap2_mcbsp_ops, +- .clk_names = clk_names, +- .num_clks = 2, ++ .clk_name = "mcbsp_clk", + }, + { + .phys_base = OMAP2430_MCBSP5_BASE, +@@ -126,8 +219,7 @@ + .rx_irq = INT_24XX_MCBSP5_IRQ_RX, + .tx_irq = INT_24XX_MCBSP5_IRQ_TX, + .ops = &omap2_mcbsp_ops, +- .clk_names = clk_names, +- .num_clks = 2, ++ .clk_name = "mcbsp_clk", + }, + }; + #define OMAP2430_MCBSP_PDATA_SZ ARRAY_SIZE(omap2430_mcbsp_pdata) +@@ -145,8 +237,7 @@ + .rx_irq = INT_24XX_MCBSP1_IRQ_RX, + .tx_irq = INT_24XX_MCBSP1_IRQ_TX, + .ops = &omap2_mcbsp_ops, +- .clk_names = clk_names, +- .num_clks = 2, ++ .clk_name = "mcbsp_clk", + }, + { + .phys_base = OMAP34XX_MCBSP2_BASE, +@@ -155,8 +246,7 @@ + .rx_irq = INT_24XX_MCBSP2_IRQ_RX, + .tx_irq = INT_24XX_MCBSP2_IRQ_TX, + .ops = &omap2_mcbsp_ops, +- .clk_names = clk_names, +- .num_clks = 2, ++ .clk_name = "mcbsp_clk", + }, + { + .phys_base = OMAP34XX_MCBSP3_BASE, +@@ -165,8 +255,7 @@ + .rx_irq = INT_24XX_MCBSP3_IRQ_RX, + .tx_irq = INT_24XX_MCBSP3_IRQ_TX, + .ops = &omap2_mcbsp_ops, +- .clk_names = clk_names, +- .num_clks = 2, ++ .clk_name = "mcbsp_clk", + }, + { + .phys_base = OMAP34XX_MCBSP4_BASE, +@@ -175,8 +264,7 @@ + .rx_irq = INT_24XX_MCBSP4_IRQ_RX, + .tx_irq = INT_24XX_MCBSP4_IRQ_TX, + .ops = &omap2_mcbsp_ops, +- .clk_names = clk_names, +- .num_clks = 2, ++ .clk_name = "mcbsp_clk", + }, + { + .phys_base = OMAP34XX_MCBSP5_BASE, +@@ -185,8 +273,7 @@ + .rx_irq = INT_24XX_MCBSP5_IRQ_RX, + .tx_irq = INT_24XX_MCBSP5_IRQ_TX, + .ops = &omap2_mcbsp_ops, +- .clk_names = clk_names, +- .num_clks = 2, ++ .clk_name = "mcbsp_clk", + }, + }; + #define OMAP34XX_MCBSP_PDATA_SZ ARRAY_SIZE(omap34xx_mcbsp_pdata) +@@ -197,6 +284,14 @@ + + static int __init omap2_mcbsp_init(void) + { ++ int i; ++ ++ for (i = 0; i < omap_mcbsp_clks_size; i++) { ++ /* Once we call clk_get inside init, we do not register it */ ++ omap_mcbsp_clk_init(&omap_mcbsp_clks[i]); ++ clk_register(&omap_mcbsp_clks[i].clk); ++ } ++ + if (cpu_is_omap2420()) + omap_mcbsp_count = OMAP2420_MCBSP_PDATA_SZ; + if (cpu_is_omap2430()) +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/arch/arm/mach-omap2/sleep24xx.S linux-2.6.29-rc3.owrt/arch/arm/mach-omap2/sleep24xx.S +--- linux-2.6.29.owrt/arch/arm/mach-omap2/sleep24xx.S 2009-05-10 22:04:41.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/arch/arm/mach-omap2/sleep24xx.S 2009-05-10 23:48:28.000000000 +0200 +@@ -93,8 +93,9 @@ + orr r4, r4, #0x40 @ enable self refresh on idle req + mov r5, #0x2000 @ set delay (DPLL relock + DLL relock) + str r4, [r2] @ make it so ++ mov r2, #0 + nop +- mcr p15, 0, r3, c7, c0, 4 @ wait for interrupt ++ mcr p15, 0, r2, c7, c0, 4 @ wait for interrupt + nop + loop: + subs r5, r5, #0x1 @ awake, wait just a bit +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/arch/arm/mach-omap2/timer-gp.c linux-2.6.29-rc3.owrt/arch/arm/mach-omap2/timer-gp.c +--- linux-2.6.29.owrt/arch/arm/mach-omap2/timer-gp.c 2009-05-10 22:04:41.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/arch/arm/mach-omap2/timer-gp.c 2009-05-10 23:48:28.000000000 +0200 +@@ -118,8 +118,7 @@ + clockevent_gpt.max_delta_ns = + clockevent_delta2ns(0xffffffff, &clockevent_gpt); + clockevent_gpt.min_delta_ns = +- clockevent_delta2ns(3, &clockevent_gpt); +- /* Timer internal resynch latency. */ ++ clockevent_delta2ns(1, &clockevent_gpt); + + clockevent_gpt.cpumask = cpumask_of(0); + clockevents_register_device(&clockevent_gpt); +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/arch/arm/mach-orion5x/common.c linux-2.6.29-rc3.owrt/arch/arm/mach-orion5x/common.c +--- linux-2.6.29.owrt/arch/arm/mach-orion5x/common.c 2009-05-10 22:04:41.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/arch/arm/mach-orion5x/common.c 2009-05-10 23:48:28.000000000 +0200 +@@ -431,10 +431,6 @@ + /***************************************************************************** + * XOR engine + ****************************************************************************/ +-struct mv_xor_platform_shared_data orion5x_xor_shared_data = { +- .dram = &orion5x_mbus_dram_info, +-}; +- + static struct resource orion5x_xor_shared_resources[] = { + { + .name = "xor low", +@@ -452,9 +448,6 @@ + static struct platform_device orion5x_xor_shared = { + .name = MV_XOR_SHARED_NAME, + .id = 0, +- .dev = { +- .platform_data = &orion5x_xor_shared_data, +- }, + .num_resources = ARRAY_SIZE(orion5x_xor_shared_resources), + .resource = orion5x_xor_shared_resources, + }; +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/arch/arm/mach-orion5x/irq.c linux-2.6.29-rc3.owrt/arch/arm/mach-orion5x/irq.c +--- linux-2.6.29.owrt/arch/arm/mach-orion5x/irq.c 2009-05-10 22:04:41.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/arch/arm/mach-orion5x/irq.c 2009-05-10 23:48:28.000000000 +0200 +@@ -44,7 +44,7 @@ + * User can use set_type() if he wants to use edge types handlers. + */ + for (i = IRQ_ORION5X_GPIO_START; i < NR_IRQS; i++) { +- set_irq_chip(i, &orion_gpio_irq_chip); ++ set_irq_chip(i, &orion_gpio_irq_level_chip); + set_irq_handler(i, handle_level_irq); + irq_desc[i].status |= IRQ_LEVEL; + set_irq_flags(i, IRQF_VALID); +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/arch/arm/mach-pxa/dma.c linux-2.6.29-rc3.owrt/arch/arm/mach-pxa/dma.c +--- linux-2.6.29.owrt/arch/arm/mach-pxa/dma.c 2009-05-10 22:04:41.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/arch/arm/mach-pxa/dma.c 2009-05-10 23:48:28.000000000 +0200 +@@ -121,16 +121,6 @@ + if (dma_channels == NULL) + return -ENOMEM; + +- /* dma channel priorities on pxa2xx processors: +- * ch 0 - 3, 16 - 19 <--> (0) DMA_PRIO_HIGH +- * ch 4 - 7, 20 - 23 <--> (1) DMA_PRIO_MEDIUM +- * ch 8 - 15, 24 - 31 <--> (2) DMA_PRIO_LOW +- */ +- for (i = 0; i < num_ch; i++) { +- DCSR(i) = 0; +- dma_channels[i].prio = min((i & 0xf) >> 2, DMA_PRIO_LOW); +- } +- + ret = request_irq(IRQ_DMA, dma_irq_handler, IRQF_DISABLED, "DMA", NULL); + if (ret) { + printk (KERN_CRIT "Wow! Can't register IRQ for DMA\n"); +@@ -138,6 +128,14 @@ + return ret; + } + ++ /* dma channel priorities on pxa2xx processors: ++ * ch 0 - 3, 16 - 19 <--> (0) DMA_PRIO_HIGH ++ * ch 4 - 7, 20 - 23 <--> (1) DMA_PRIO_MEDIUM ++ * ch 8 - 15, 24 - 31 <--> (2) DMA_PRIO_LOW ++ */ ++ for (i = 0; i < num_ch; i++) ++ dma_channels[i].prio = min((i & 0xf) >> 2, DMA_PRIO_LOW); ++ + num_dma_channels = num_ch; + return 0; + } +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/arch/arm/mach-pxa/include/mach/regs-ac97.h linux-2.6.29-rc3.owrt/arch/arm/mach-pxa/include/mach/regs-ac97.h +--- linux-2.6.29.owrt/arch/arm/mach-pxa/include/mach/regs-ac97.h 2009-05-10 22:04:41.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/arch/arm/mach-pxa/include/mach/regs-ac97.h 2009-05-10 23:48:28.000000000 +0200 +@@ -1,8 +1,6 @@ + #ifndef __ASM_ARCH_REGS_AC97_H + #define __ASM_ARCH_REGS_AC97_H + +-#include <mach/hardware.h> +- + /* + * AC97 Controller registers + */ +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/arch/arm/mach-pxa/include/mach/regs-ssp.h linux-2.6.29-rc3.owrt/arch/arm/mach-pxa/include/mach/regs-ssp.h +--- linux-2.6.29.owrt/arch/arm/mach-pxa/include/mach/regs-ssp.h 2009-05-10 22:04:41.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/arch/arm/mach-pxa/include/mach/regs-ssp.h 2009-05-10 23:48:28.000000000 +0200 +@@ -41,9 +41,6 @@ + #elif defined(CONFIG_PXA27x) || defined(CONFIG_PXA3xx) + #define SSCR0_SCR (0x000fff00) /* Serial Clock Rate (mask) */ + #define SSCR0_SerClkDiv(x) (((x) - 1) << 8) /* Divisor [1..4096] */ +-#endif +- +-#if defined(CONFIG_PXA27x) || defined(CONFIG_PXA3xx) + #define SSCR0_EDSS (1 << 20) /* Extended data size select */ + #define SSCR0_NCS (1 << 21) /* Network clock select */ + #define SSCR0_RIM (1 << 22) /* Receive FIFO overrrun interrupt mask */ +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/arch/arm/mach-pxa/pxa300.c linux-2.6.29-rc3.owrt/arch/arm/mach-pxa/pxa300.c +--- linux-2.6.29.owrt/arch/arm/mach-pxa/pxa300.c 2009-05-10 22:04:41.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/arch/arm/mach-pxa/pxa300.c 2009-05-10 23:48:28.000000000 +0200 +@@ -88,13 +88,13 @@ + static DEFINE_PXA3_CKEN(common_nand, NAND, 156000000, 0); + + static struct clk_lookup common_clkregs[] = { +- INIT_CLKREG(&clk_common_nand, "pxa3xx-nand", NULL), ++ INIT_CLKREG(&clk_common_nand, "pxa3xx-nand", "NANDCLK"), + }; + + static DEFINE_PXA3_CKEN(pxa310_mmc3, MMC3, 19500000, 0); + + static struct clk_lookup pxa310_clkregs[] = { +- INIT_CLKREG(&clk_pxa310_mmc3, "pxa2xx-mci.2", NULL), ++ INIT_CLKREG(&clk_pxa310_mmc3, "pxa2xx-mci.2", "MMCCLK"), + }; + + static int __init pxa300_init(void) +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/arch/arm/mach-pxa/pxa320.c linux-2.6.29-rc3.owrt/arch/arm/mach-pxa/pxa320.c +--- linux-2.6.29.owrt/arch/arm/mach-pxa/pxa320.c 2009-05-10 22:04:41.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/arch/arm/mach-pxa/pxa320.c 2009-05-10 23:48:28.000000000 +0200 +@@ -83,7 +83,7 @@ + static DEFINE_PXA3_CKEN(pxa320_nand, NAND, 104000000, 0); + + static struct clk_lookup pxa320_clkregs[] = { +- INIT_CLKREG(&clk_pxa320_nand, "pxa3xx-nand", NULL), ++ INIT_CLKREG(&clk_pxa320_nand, "pxa3xx-nand", "NANDCLK"), + }; + + static int __init pxa320_init(void) +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/arch/arm/mach-rpc/riscpc.c linux-2.6.29-rc3.owrt/arch/arm/mach-rpc/riscpc.c +--- linux-2.6.29.owrt/arch/arm/mach-rpc/riscpc.c 2009-05-10 22:04:41.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/arch/arm/mach-rpc/riscpc.c 2009-05-10 23:48:28.000000000 +0200 +@@ -19,7 +19,6 @@ + #include <linux/serial_8250.h> + #include <linux/ata_platform.h> + #include <linux/io.h> +-#include <linux/i2c.h> + + #include <asm/elf.h> + #include <asm/mach-types.h> +@@ -202,13 +201,8 @@ + &pata_device, + }; + +-static struct i2c_board_info i2c_rtc = { +- I2C_BOARD_INFO("pcf8583", 0x50) +-}; +- + static int __init rpc_init(void) + { +- i2c_register_board_info(0, &i2c_rtc, 1); + return platform_add_devices(devs, ARRAY_SIZE(devs)); + } + +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/arch/arm/mach-s3c6410/mach-smdk6410.c linux-2.6.29-rc3.owrt/arch/arm/mach-s3c6410/mach-smdk6410.c +--- linux-2.6.29.owrt/arch/arm/mach-s3c6410/mach-smdk6410.c 2009-05-10 22:04:41.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/arch/arm/mach-s3c6410/mach-smdk6410.c 2009-05-10 23:48:28.000000000 +0200 +@@ -129,7 +129,7 @@ + .vidcon1 = VIDCON1_INV_HSYNC | VIDCON1_INV_VSYNC, + }; + +-static struct map_desc smdk6410_iodesc[] = {}; ++struct map_desc smdk6410_iodesc[] = {}; + + static struct platform_device *smdk6410_devices[] __initdata = { + #ifdef CONFIG_SMDK6410_SD_CH0 +@@ -146,7 +146,7 @@ + + static struct i2c_board_info i2c_devs0[] __initdata = { + { I2C_BOARD_INFO("24c08", 0x50), }, +- { I2C_BOARD_INFO("wm8580", 0x1b), }, ++ { I2C_BOARD_INFO("WM8580", 0X1b), }, + }; + + static struct i2c_board_info i2c_devs1[] __initdata = { +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/arch/arm/mach-sa1100/generic.c linux-2.6.29-rc3.owrt/arch/arm/mach-sa1100/generic.c +--- linux-2.6.29.owrt/arch/arm/mach-sa1100/generic.c 2009-05-10 22:04:41.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/arch/arm/mach-sa1100/generic.c 2009-05-10 23:48:28.000000000 +0200 +@@ -289,7 +289,7 @@ + }; + + static struct platform_device sa11x0mtd_device = { +- .name = "sa1100-mtd", ++ .name = "flash", + .id = -1, + }; + +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/arch/arm/mm/abort-ev6.S linux-2.6.29-rc3.owrt/arch/arm/mm/abort-ev6.S +--- linux-2.6.29.owrt/arch/arm/mm/abort-ev6.S 2009-05-10 22:04:41.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/arch/arm/mm/abort-ev6.S 2009-05-10 23:48:28.000000000 +0200 +@@ -23,8 +23,7 @@ + #ifdef CONFIG_CPU_32v6K + clrex + #else +- sub r1, sp, #4 @ Get unused stack location +- strex r0, r1, [r1] @ Clear the exclusive monitor ++ strex r0, r1, [sp] @ Clear the exclusive monitor + #endif + mrc p15, 0, r1, c5, c0, 0 @ get FSR + mrc p15, 0, r0, c6, c0, 0 @ get FAR +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/arch/arm/mm/copypage-feroceon.c linux-2.6.29-rc3.owrt/arch/arm/mm/copypage-feroceon.c +--- linux-2.6.29.owrt/arch/arm/mm/copypage-feroceon.c 2009-05-10 22:04:41.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/arch/arm/mm/copypage-feroceon.c 2009-05-10 23:48:28.000000000 +0200 +@@ -13,7 +13,7 @@ + #include <linux/init.h> + #include <linux/highmem.h> + +-static void __naked ++static void __attribute__((naked)) + feroceon_copy_user_page(void *kto, const void *kfrom) + { + asm("\ +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/arch/arm/mm/copypage-v3.c linux-2.6.29-rc3.owrt/arch/arm/mm/copypage-v3.c +--- linux-2.6.29.owrt/arch/arm/mm/copypage-v3.c 2009-05-10 22:04:41.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/arch/arm/mm/copypage-v3.c 2009-05-10 23:48:28.000000000 +0200 +@@ -15,7 +15,7 @@ + * + * FIXME: do we need to handle cache stuff... + */ +-static void __naked ++static void __attribute__((naked)) + v3_copy_user_page(void *kto, const void *kfrom) + { + asm("\n\ +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/arch/arm/mm/copypage-v4mc.c linux-2.6.29-rc3.owrt/arch/arm/mm/copypage-v4mc.c +--- linux-2.6.29.owrt/arch/arm/mm/copypage-v4mc.c 2009-05-10 22:04:41.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/arch/arm/mm/copypage-v4mc.c 2009-05-10 23:48:28.000000000 +0200 +@@ -44,7 +44,7 @@ + * instruction. If your processor does not supply this, you have to write your + * own copy_user_highpage that does the right thing. + */ +-static void __naked ++static void __attribute__((naked)) + mc_copy_user_page(void *from, void *to) + { + asm volatile( +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/arch/arm/mm/copypage-v4wb.c linux-2.6.29-rc3.owrt/arch/arm/mm/copypage-v4wb.c +--- linux-2.6.29.owrt/arch/arm/mm/copypage-v4wb.c 2009-05-10 22:04:41.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/arch/arm/mm/copypage-v4wb.c 2009-05-10 23:48:28.000000000 +0200 +@@ -22,7 +22,7 @@ + * instruction. If your processor does not supply this, you have to write your + * own copy_user_highpage that does the right thing. + */ +-static void __naked ++static void __attribute__((naked)) + v4wb_copy_user_page(void *kto, const void *kfrom) + { + asm("\ +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/arch/arm/mm/copypage-v4wt.c linux-2.6.29-rc3.owrt/arch/arm/mm/copypage-v4wt.c +--- linux-2.6.29.owrt/arch/arm/mm/copypage-v4wt.c 2009-05-10 22:04:41.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/arch/arm/mm/copypage-v4wt.c 2009-05-10 23:48:28.000000000 +0200 +@@ -20,7 +20,7 @@ + * dirty data in the cache. However, we do have to ensure that + * subsequent reads are up to date. + */ +-static void __naked ++static void __attribute__((naked)) + v4wt_copy_user_page(void *kto, const void *kfrom) + { + asm("\ +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/arch/arm/mm/copypage-xsc3.c linux-2.6.29-rc3.owrt/arch/arm/mm/copypage-xsc3.c +--- linux-2.6.29.owrt/arch/arm/mm/copypage-xsc3.c 2009-05-10 22:04:41.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/arch/arm/mm/copypage-xsc3.c 2009-05-10 23:48:28.000000000 +0200 +@@ -29,7 +29,7 @@ + * if we eventually end up using our copied page. + * + */ +-static void __naked ++static void __attribute__((naked)) + xsc3_mc_copy_user_page(void *kto, const void *kfrom) + { + asm("\ +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/arch/arm/mm/copypage-xscale.c linux-2.6.29-rc3.owrt/arch/arm/mm/copypage-xscale.c +--- linux-2.6.29.owrt/arch/arm/mm/copypage-xscale.c 2009-05-10 22:04:41.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/arch/arm/mm/copypage-xscale.c 2009-05-10 23:48:28.000000000 +0200 +@@ -42,7 +42,7 @@ + * Dcache aliasing issue. The writes will be forwarded to the write buffer, + * and merged as appropriate. + */ +-static void __naked ++static void __attribute__((naked)) + mc_copy_user_page(void *from, void *to) + { + /* +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/arch/arm/mm/dma-mapping.c linux-2.6.29-rc3.owrt/arch/arm/mm/dma-mapping.c +--- linux-2.6.29.owrt/arch/arm/mm/dma-mapping.c 2009-05-10 22:04:41.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/arch/arm/mm/dma-mapping.c 2009-05-10 23:48:28.000000000 +0200 +@@ -490,30 +490,26 @@ + */ + void dma_cache_maint(const void *start, size_t size, int direction) + { +- void (*inner_op)(const void *, const void *); +- void (*outer_op)(unsigned long, unsigned long); ++ const void *end = start + size; + +- BUG_ON(!virt_addr_valid(start) || !virt_addr_valid(start + size - 1)); ++ BUG_ON(!virt_addr_valid(start) || !virt_addr_valid(end - 1)); + + switch (direction) { + case DMA_FROM_DEVICE: /* invalidate only */ +- inner_op = dmac_inv_range; +- outer_op = outer_inv_range; ++ dmac_inv_range(start, end); ++ outer_inv_range(__pa(start), __pa(end)); + break; + case DMA_TO_DEVICE: /* writeback only */ +- inner_op = dmac_clean_range; +- outer_op = outer_clean_range; ++ dmac_clean_range(start, end); ++ outer_clean_range(__pa(start), __pa(end)); + break; + case DMA_BIDIRECTIONAL: /* writeback and invalidate */ +- inner_op = dmac_flush_range; +- outer_op = outer_flush_range; ++ dmac_flush_range(start, end); ++ outer_flush_range(__pa(start), __pa(end)); + break; + default: + BUG(); + } +- +- inner_op(start, start + size); +- outer_op(__pa(start), __pa(start) + size); + } + EXPORT_SYMBOL(dma_cache_maint); + +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/arch/arm/mm/fault-armv.c linux-2.6.29-rc3.owrt/arch/arm/mm/fault-armv.c +--- linux-2.6.29.owrt/arch/arm/mm/fault-armv.c 2009-05-10 22:04:41.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/arch/arm/mm/fault-armv.c 2009-05-10 23:48:28.000000000 +0200 +@@ -66,10 +66,7 @@ + * fault (ie, is old), we can safely ignore any issues. + */ + if (ret && (pte_val(entry) & L_PTE_MT_MASK) != shared_pte_mask) { +- unsigned long pfn = pte_pfn(entry); +- flush_cache_page(vma, address, pfn); +- outer_flush_range((pfn << PAGE_SHIFT), +- (pfn << PAGE_SHIFT) + PAGE_SIZE); ++ flush_cache_page(vma, address, pte_pfn(entry)); + pte_val(entry) &= ~L_PTE_MT_MASK; + pte_val(entry) |= shared_pte_mask; + set_pte_at(vma->vm_mm, address, pte, entry); +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/arch/arm/mm/init.c linux-2.6.29-rc3.owrt/arch/arm/mm/init.c +--- linux-2.6.29.owrt/arch/arm/mm/init.c 2009-05-10 22:04:41.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/arch/arm/mm/init.c 2009-05-10 23:48:28.000000000 +0200 +@@ -382,7 +382,7 @@ + for_each_node(node) + bootmem_free_node(node, mi); + +- high_memory = __va((memend_pfn << PAGE_SHIFT) - 1) + 1; ++ high_memory = __va(memend_pfn << PAGE_SHIFT); + + /* + * This doesn't seem to be used by the Linux memory manager any +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/arch/arm/mm/mmap.c linux-2.6.29-rc3.owrt/arch/arm/mm/mmap.c +--- linux-2.6.29.owrt/arch/arm/mm/mmap.c 2009-05-10 22:04:41.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/arch/arm/mm/mmap.c 2009-05-10 23:48:28.000000000 +0200 +@@ -124,7 +124,7 @@ + { + if (addr < PHYS_OFFSET) + return 0; +- if (addr + size >= __pa(high_memory - 1)) ++ if (addr + size > __pa(high_memory)) + return 0; + + return 1; +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/arch/arm/mm/mmu.c linux-2.6.29-rc3.owrt/arch/arm/mm/mmu.c +--- linux-2.6.29.owrt/arch/arm/mm/mmu.c 2009-05-10 22:04:41.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/arch/arm/mm/mmu.c 2009-05-10 23:48:28.000000000 +0200 +@@ -693,8 +693,7 @@ + * Check whether this memory bank would entirely overlap + * the vmalloc area. + */ +- if (__va(bank->start) >= VMALLOC_MIN || +- __va(bank->start) < PAGE_OFFSET) { ++ if (__va(bank->start) >= VMALLOC_MIN) { + printk(KERN_NOTICE "Ignoring RAM at %.8lx-%.8lx " + "(vmalloc region overlap).\n", + bank->start, bank->start + bank->size - 1); +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/arch/arm/plat-mxc/include/mach/mmc.h linux-2.6.29-rc3.owrt/arch/arm/plat-mxc/include/mach/mmc.h +--- linux-2.6.29.owrt/arch/arm/plat-mxc/include/mach/mmc.h 2009-05-10 22:04:41.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/arch/arm/plat-mxc/include/mach/mmc.h 1970-01-01 01:00:00.000000000 +0100 +@@ -1,36 +0,0 @@ +-#ifndef ASMARM_ARCH_MMC_H +-#define ASMARM_ARCH_MMC_H +- +-#include <linux/mmc/host.h> +- +-struct device; +- +-/* board specific SDHC data, optional. +- * If not present, a writable card with 3,3V is assumed. +- */ +-struct imxmmc_platform_data { +- /* Return values for the get_ro callback should be: +- * 0 for a read/write card +- * 1 for a read-only card +- * -ENOSYS when not supported (equal to NULL callback) +- * or a negative errno value when something bad happened +- */ +- int (*get_ro)(struct device *); +- +- /* board specific hook to (de)initialize the SD slot. +- * The board code can call 'handler' on a card detection +- * change giving data as argument. +- */ +- int (*init)(struct device *dev, irq_handler_t handler, void *data); +- void (*exit)(struct device *dev, void *data); +- +- /* available voltages. If not given, assume +- * MMC_VDD_32_33 | MMC_VDD_33_34 +- */ +- unsigned int ocr_avail; +- +- /* adjust slot voltage */ +- void (*setpower)(struct device *, unsigned int vdd); +-}; +- +-#endif +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/arch/arm/plat-omap/common.c linux-2.6.29-rc3.owrt/arch/arm/plat-omap/common.c +--- linux-2.6.29.owrt/arch/arm/plat-omap/common.c 2009-05-10 22:04:41.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/arch/arm/plat-omap/common.c 2009-05-10 23:48:28.000000000 +0200 +@@ -200,16 +200,20 @@ + }; + + /* ++ * Rounds down to nearest nsec. ++ */ ++unsigned long long omap_32k_ticks_to_nsecs(unsigned long ticks_32k) ++{ ++ return cyc2ns(&clocksource_32k, ticks_32k); ++} ++ ++/* + * Returns current time from boot in nsecs. It's OK for this to wrap + * around for now, as it's just a relative time stamp. + */ + unsigned long long sched_clock(void) + { +- unsigned long long ret; +- +- ret = (unsigned long long)omap_32k_read(); +- ret = (ret * clocksource_32k.mult_orig) >> clocksource_32k.shift; +- return ret; ++ return omap_32k_ticks_to_nsecs(omap_32k_read()); + } + + static int __init omap_init_clocksource_32k(void) +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/arch/arm/plat-omap/devices.c linux-2.6.29-rc3.owrt/arch/arm/plat-omap/devices.c +--- linux-2.6.29.owrt/arch/arm/plat-omap/devices.c 2009-05-10 22:04:41.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/arch/arm/plat-omap/devices.c 2009-05-10 23:48:28.000000000 +0200 +@@ -200,15 +200,14 @@ + /* + * Register MMC devices. Called from mach-omap1 and mach-omap2 device init. + */ +-int __init omap_mmc_add(const char *name, int id, unsigned long base, +- unsigned long size, unsigned int irq, +- struct omap_mmc_platform_data *data) ++int __init omap_mmc_add(int id, unsigned long base, unsigned long size, ++ unsigned int irq, struct omap_mmc_platform_data *data) + { + struct platform_device *pdev; + struct resource res[OMAP_MMC_NR_RES]; + int ret; + +- pdev = platform_device_alloc(name, id); ++ pdev = platform_device_alloc("mmci-omap", id); + if (!pdev) + return -ENOMEM; + +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/arch/arm/plat-omap/dma.c linux-2.6.29-rc3.owrt/arch/arm/plat-omap/dma.c +--- linux-2.6.29.owrt/arch/arm/plat-omap/dma.c 2009-05-10 22:04:41.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/arch/arm/plat-omap/dma.c 2009-05-10 23:48:28.000000000 +0200 +@@ -709,7 +709,6 @@ + chan->dev_name = dev_name; + chan->callback = callback; + chan->data = data; +- chan->flags = 0; + + #ifndef CONFIG_ARCH_OMAP1 + if (cpu_class_is_omap2()) { +@@ -1889,11 +1888,11 @@ + status = dma_read(CSR(ch)); + } + +- dma_write(status, CSR(ch)); +- + if (likely(dma_chan[ch].callback != NULL)) + dma_chan[ch].callback(ch, status, dma_chan[ch].data); + ++ dma_write(status, CSR(ch)); ++ + return 0; + } + +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/arch/arm/plat-omap/include/mach/common.h linux-2.6.29-rc3.owrt/arch/arm/plat-omap/include/mach/common.h +--- linux-2.6.29.owrt/arch/arm/plat-omap/include/mach/common.h 2009-05-10 22:04:41.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/arch/arm/plat-omap/include/mach/common.h 2009-05-10 23:48:28.000000000 +0200 +@@ -35,7 +35,7 @@ + extern struct sys_timer omap_timer; + extern void omap_serial_init(void); + extern void omap_serial_enable_clocks(int enable); +-#if defined(CONFIG_I2C_OMAP) || defined(CONFIG_I2C_OMAP_MODULE) ++#ifdef CONFIG_I2C_OMAP + extern int omap_register_i2c_bus(int bus_id, u32 clkrate, + struct i2c_board_info const *info, + unsigned len); +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/arch/arm/plat-omap/include/mach/cpu.h linux-2.6.29-rc3.owrt/arch/arm/plat-omap/include/mach/cpu.h +--- linux-2.6.29.owrt/arch/arm/plat-omap/include/mach/cpu.h 2009-05-10 22:04:41.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/arch/arm/plat-omap/include/mach/cpu.h 2009-05-10 23:48:28.000000000 +0200 +@@ -339,7 +339,6 @@ + #define OMAP3430_REV_ES2_0 0x34301034 + #define OMAP3430_REV_ES2_1 0x34302034 + #define OMAP3430_REV_ES3_0 0x34303034 +-#define OMAP3430_REV_ES3_1 0x34304034 + + /* + * omap_chip bits +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/arch/arm/plat-omap/include/mach/mcbsp.h linux-2.6.29-rc3.owrt/arch/arm/plat-omap/include/mach/mcbsp.h +--- linux-2.6.29.owrt/arch/arm/plat-omap/include/mach/mcbsp.h 2009-05-10 22:04:41.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/arch/arm/plat-omap/include/mach/mcbsp.h 2009-05-10 23:48:28.000000000 +0200 +@@ -344,8 +344,7 @@ + u8 dma_rx_sync, dma_tx_sync; + u16 rx_irq, tx_irq; + struct omap_mcbsp_ops *ops; +- char const **clk_names; +- int num_clks; ++ char const *clk_name; + }; + + struct omap_mcbsp { +@@ -377,8 +376,7 @@ + /* Protect the field .free, while checking if the mcbsp is in use */ + spinlock_t lock; + struct omap_mcbsp_platform_data *pdata; +- struct clk **clks; +- int num_clks; ++ struct clk *clk; + }; + extern struct omap_mcbsp **mcbsp_ptr; + extern int omap_mcbsp_count; +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/arch/arm/plat-omap/include/mach/mmc.h linux-2.6.29-rc3.owrt/arch/arm/plat-omap/include/mach/mmc.h +--- linux-2.6.29.owrt/arch/arm/plat-omap/include/mach/mmc.h 2009-05-10 22:04:41.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/arch/arm/plat-omap/include/mach/mmc.h 2009-05-10 23:48:28.000000000 +0200 +@@ -115,9 +115,8 @@ + int nr_controllers); + void omap2_init_mmc(struct omap_mmc_platform_data **mmc_data, + int nr_controllers); +-int omap_mmc_add(const char *name, int id, unsigned long base, +- unsigned long size, unsigned int irq, +- struct omap_mmc_platform_data *data); ++int omap_mmc_add(int id, unsigned long base, unsigned long size, ++ unsigned int irq, struct omap_mmc_platform_data *data); + #else + static inline void omap1_init_mmc(struct omap_mmc_platform_data **mmc_data, + int nr_controllers) +@@ -127,9 +126,8 @@ + int nr_controllers) + { + } +-static inline int omap_mmc_add(const char *name, int id, unsigned long base, +- unsigned long size, unsigned int irq, +- struct omap_mmc_platform_data *data) ++static inline int omap_mmc_add(int id, unsigned long base, unsigned long size, ++ unsigned int irq, struct omap_mmc_platform_data *data) + { + return 0; + } +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/arch/arm/plat-omap/include/mach/pm.h linux-2.6.29-rc3.owrt/arch/arm/plat-omap/include/mach/pm.h +--- linux-2.6.29.owrt/arch/arm/plat-omap/include/mach/pm.h 2009-05-10 22:04:41.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/arch/arm/plat-omap/include/mach/pm.h 2009-05-10 23:48:28.000000000 +0200 +@@ -108,7 +108,7 @@ + !defined(CONFIG_ARCH_OMAP15XX) && \ + !defined(CONFIG_ARCH_OMAP16XX) && \ + !defined(CONFIG_ARCH_OMAP24XX) +-#warning "Power management for this processor not implemented yet" ++#error "Power management for this processor not implemented yet" + #endif + + #ifndef __ASSEMBLER__ +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/arch/arm/plat-omap/Makefile linux-2.6.29-rc3.owrt/arch/arm/plat-omap/Makefile +--- linux-2.6.29.owrt/arch/arm/plat-omap/Makefile 2009-05-10 22:04:41.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/arch/arm/plat-omap/Makefile 2009-05-10 23:48:28.000000000 +0200 +@@ -18,8 +18,7 @@ + obj-$(CONFIG_OMAP_DM_TIMER) += dmtimer.o + obj-$(CONFIG_OMAP_DEBUG_DEVICES) += debug-devices.o + obj-$(CONFIG_OMAP_DEBUG_LEDS) += debug-leds.o +-i2c-omap-$(CONFIG_I2C_OMAP) := i2c.o +-obj-y += $(i2c-omap-m) $(i2c-omap-y) ++obj-$(CONFIG_I2C_OMAP) += i2c.o + + # OMAP mailbox framework + obj-$(CONFIG_OMAP_MBOX_FWK) += mailbox.o +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/arch/arm/plat-omap/mcbsp.c linux-2.6.29-rc3.owrt/arch/arm/plat-omap/mcbsp.c +--- linux-2.6.29.owrt/arch/arm/plat-omap/mcbsp.c 2009-05-10 22:04:41.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/arch/arm/plat-omap/mcbsp.c 2009-05-10 23:48:28.000000000 +0200 +@@ -214,7 +214,6 @@ + int omap_mcbsp_request(unsigned int id) + { + struct omap_mcbsp *mcbsp; +- int i; + int err; + + if (!omap_mcbsp_check_valid_id(id)) { +@@ -226,8 +225,7 @@ + if (mcbsp->pdata && mcbsp->pdata->ops && mcbsp->pdata->ops->request) + mcbsp->pdata->ops->request(id); + +- for (i = 0; i < mcbsp->num_clks; i++) +- clk_enable(mcbsp->clks[i]); ++ clk_enable(mcbsp->clk); + + spin_lock(&mcbsp->lock); + if (!mcbsp->free) { +@@ -278,7 +276,6 @@ + void omap_mcbsp_free(unsigned int id) + { + struct omap_mcbsp *mcbsp; +- int i; + + if (!omap_mcbsp_check_valid_id(id)) { + printk(KERN_ERR "%s: Invalid id (%d)\n", __func__, id + 1); +@@ -289,8 +286,7 @@ + if (mcbsp->pdata && mcbsp->pdata->ops && mcbsp->pdata->ops->free) + mcbsp->pdata->ops->free(id); + +- for (i = mcbsp->num_clks - 1; i >= 0; i--) +- clk_disable(mcbsp->clks[i]); ++ clk_disable(mcbsp->clk); + + spin_lock(&mcbsp->lock); + if (mcbsp->free) { +@@ -876,7 +872,6 @@ + struct omap_mcbsp_platform_data *pdata = pdev->dev.platform_data; + struct omap_mcbsp *mcbsp; + int id = pdev->id - 1; +- int i; + int ret = 0; + + if (!pdata) { +@@ -921,25 +916,14 @@ + mcbsp->dma_rx_sync = pdata->dma_rx_sync; + mcbsp->dma_tx_sync = pdata->dma_tx_sync; + +- if (pdata->num_clks) { +- mcbsp->num_clks = pdata->num_clks; +- mcbsp->clks = kzalloc(mcbsp->num_clks * sizeof(struct clk *), +- GFP_KERNEL); +- if (!mcbsp->clks) { +- ret = -ENOMEM; +- goto exit; +- } +- for (i = 0; i < mcbsp->num_clks; i++) { +- mcbsp->clks[i] = clk_get(&pdev->dev, pdata->clk_names[i]); +- if (IS_ERR(mcbsp->clks[i])) { +- dev_err(&pdev->dev, +- "Invalid %s configuration for McBSP%d.\n", +- pdata->clk_names[i], mcbsp->id); +- ret = PTR_ERR(mcbsp->clks[i]); +- goto err_clk; +- } +- } +- ++ if (pdata->clk_name) ++ mcbsp->clk = clk_get(&pdev->dev, pdata->clk_name); ++ if (IS_ERR(mcbsp->clk)) { ++ dev_err(&pdev->dev, ++ "Invalid clock configuration for McBSP%d.\n", ++ mcbsp->id); ++ ret = PTR_ERR(mcbsp->clk); ++ goto err_clk; + } + + mcbsp->pdata = pdata; +@@ -948,9 +932,6 @@ + return 0; + + err_clk: +- while (i--) +- clk_put(mcbsp->clks[i]); +- kfree(mcbsp->clks); + iounmap(mcbsp->io_base); + err_ioremap: + mcbsp->free = 0; +@@ -961,7 +942,6 @@ + static int __devexit omap_mcbsp_remove(struct platform_device *pdev) + { + struct omap_mcbsp *mcbsp = platform_get_drvdata(pdev); +- int i; + + platform_set_drvdata(pdev, NULL); + if (mcbsp) { +@@ -970,18 +950,12 @@ + mcbsp->pdata->ops->free) + mcbsp->pdata->ops->free(mcbsp->id); + +- for (i = mcbsp->num_clks - 1; i >= 0; i--) { +- clk_disable(mcbsp->clks[i]); +- clk_put(mcbsp->clks[i]); +- } ++ clk_disable(mcbsp->clk); ++ clk_put(mcbsp->clk); + + iounmap(mcbsp->io_base); + +- if (mcbsp->num_clks) { +- kfree(mcbsp->clks); +- mcbsp->clks = NULL; +- mcbsp->num_clks = 0; +- } ++ mcbsp->clk = NULL; + mcbsp->free = 0; + mcbsp->dev = NULL; + } +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/arch/arm/plat-orion/gpio.c linux-2.6.29-rc3.owrt/arch/arm/plat-orion/gpio.c +--- linux-2.6.29.owrt/arch/arm/plat-orion/gpio.c 2009-05-10 22:04:41.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/arch/arm/plat-orion/gpio.c 2009-05-10 23:48:28.000000000 +0200 +@@ -265,36 +265,51 @@ + * polarity LEVEL mask + * + ****************************************************************************/ ++static void gpio_irq_edge_ack(u32 irq) ++{ ++ int pin = irq_to_gpio(irq); ++ ++ writel(~(1 << (pin & 31)), GPIO_EDGE_CAUSE(pin)); ++} + +-static void gpio_irq_ack(u32 irq) ++static void gpio_irq_edge_mask(u32 irq) + { +- int type = irq_desc[irq].status & IRQ_TYPE_SENSE_MASK; +- if (type & (IRQ_TYPE_EDGE_RISING | IRQ_TYPE_EDGE_FALLING)) { +- int pin = irq_to_gpio(irq); +- writel(~(1 << (pin & 31)), GPIO_EDGE_CAUSE(pin)); +- } ++ int pin = irq_to_gpio(irq); ++ u32 u; ++ ++ u = readl(GPIO_EDGE_MASK(pin)); ++ u &= ~(1 << (pin & 31)); ++ writel(u, GPIO_EDGE_MASK(pin)); ++} ++ ++static void gpio_irq_edge_unmask(u32 irq) ++{ ++ int pin = irq_to_gpio(irq); ++ u32 u; ++ ++ u = readl(GPIO_EDGE_MASK(pin)); ++ u |= 1 << (pin & 31); ++ writel(u, GPIO_EDGE_MASK(pin)); + } + +-static void gpio_irq_mask(u32 irq) ++static void gpio_irq_level_mask(u32 irq) + { + int pin = irq_to_gpio(irq); +- int type = irq_desc[irq].status & IRQ_TYPE_SENSE_MASK; +- u32 reg = (type & (IRQ_TYPE_EDGE_RISING | IRQ_TYPE_EDGE_FALLING)) ? +- GPIO_EDGE_MASK(pin) : GPIO_LEVEL_MASK(pin); +- u32 u = readl(reg); ++ u32 u; ++ ++ u = readl(GPIO_LEVEL_MASK(pin)); + u &= ~(1 << (pin & 31)); +- writel(u, reg); ++ writel(u, GPIO_LEVEL_MASK(pin)); + } + +-static void gpio_irq_unmask(u32 irq) ++static void gpio_irq_level_unmask(u32 irq) + { + int pin = irq_to_gpio(irq); +- int type = irq_desc[irq].status & IRQ_TYPE_SENSE_MASK; +- u32 reg = (type & (IRQ_TYPE_EDGE_RISING | IRQ_TYPE_EDGE_FALLING)) ? +- GPIO_EDGE_MASK(pin) : GPIO_LEVEL_MASK(pin); +- u32 u = readl(reg); ++ u32 u; ++ ++ u = readl(GPIO_LEVEL_MASK(pin)); + u |= 1 << (pin & 31); +- writel(u, reg); ++ writel(u, GPIO_LEVEL_MASK(pin)); + } + + static int gpio_irq_set_type(u32 irq, u32 type) +@@ -316,9 +331,9 @@ + * Set edge/level type. + */ + if (type & (IRQ_TYPE_EDGE_RISING | IRQ_TYPE_EDGE_FALLING)) { +- desc->handle_irq = handle_edge_irq; ++ desc->chip = &orion_gpio_irq_edge_chip; + } else if (type & (IRQ_TYPE_LEVEL_HIGH | IRQ_TYPE_LEVEL_LOW)) { +- desc->handle_irq = handle_level_irq; ++ desc->chip = &orion_gpio_irq_level_chip; + } else { + printk(KERN_ERR "failed to set irq=%d (type=%d)\n", irq, type); + return -EINVAL; +@@ -356,11 +371,19 @@ + return 0; + } + +-struct irq_chip orion_gpio_irq_chip = { +- .name = "orion_gpio", +- .ack = gpio_irq_ack, +- .mask = gpio_irq_mask, +- .unmask = gpio_irq_unmask, ++struct irq_chip orion_gpio_irq_edge_chip = { ++ .name = "orion_gpio_irq_edge", ++ .ack = gpio_irq_edge_ack, ++ .mask = gpio_irq_edge_mask, ++ .unmask = gpio_irq_edge_unmask, ++ .set_type = gpio_irq_set_type, ++}; ++ ++struct irq_chip orion_gpio_irq_level_chip = { ++ .name = "orion_gpio_irq_level", ++ .mask = gpio_irq_level_mask, ++ .mask_ack = gpio_irq_level_mask, ++ .unmask = gpio_irq_level_unmask, + .set_type = gpio_irq_set_type, + }; + +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/arch/arm/plat-orion/include/plat/gpio.h linux-2.6.29-rc3.owrt/arch/arm/plat-orion/include/plat/gpio.h +--- linux-2.6.29.owrt/arch/arm/plat-orion/include/plat/gpio.h 2009-05-10 22:04:41.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/arch/arm/plat-orion/include/plat/gpio.h 2009-05-10 23:48:28.000000000 +0200 +@@ -31,7 +31,8 @@ + /* + * GPIO interrupt handling. + */ +-extern struct irq_chip orion_gpio_irq_chip; ++extern struct irq_chip orion_gpio_irq_edge_chip; ++extern struct irq_chip orion_gpio_irq_level_chip; + void orion_gpio_irq_handler(int irqoff); + + +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/arch/arm/plat-s3c64xx/clock.c linux-2.6.29-rc3.owrt/arch/arm/plat-s3c64xx/clock.c +--- linux-2.6.29.owrt/arch/arm/plat-s3c64xx/clock.c 2009-05-10 22:04:41.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/arch/arm/plat-s3c64xx/clock.c 2009-05-10 23:48:28.000000000 +0200 +@@ -248,7 +248,7 @@ + &clk_48m, + }; + +-void __init s3c64xx_register_clocks(void) ++void s3c64xx_register_clocks(void) + { + struct clk *clkp; + int ret; +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/arch/arm/plat-s3c64xx/gpiolib.c linux-2.6.29-rc3.owrt/arch/arm/plat-s3c64xx/gpiolib.c +--- linux-2.6.29.owrt/arch/arm/plat-s3c64xx/gpiolib.c 2009-05-10 22:04:41.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/arch/arm/plat-s3c64xx/gpiolib.c 2009-05-10 23:48:28.000000000 +0200 +@@ -417,4 +417,4 @@ + return 0; + } + +-core_initcall(s3c64xx_gpiolib_init); ++arch_initcall(s3c64xx_gpiolib_init); +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/arch/arm/plat-s3c64xx/include/plat/irqs.h linux-2.6.29-rc3.owrt/arch/arm/plat-s3c64xx/include/plat/irqs.h +--- linux-2.6.29.owrt/arch/arm/plat-s3c64xx/include/plat/irqs.h 2009-05-10 22:04:41.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/arch/arm/plat-s3c64xx/include/plat/irqs.h 2009-05-10 23:48:28.000000000 +0200 +@@ -117,7 +117,7 @@ + #define IRQ_ONENAND1 S3C64XX_IRQ_VIC1(12) + #define IRQ_NFC S3C64XX_IRQ_VIC1(13) + #define IRQ_CFCON S3C64XX_IRQ_VIC1(14) +-#define IRQ_USBH S3C64XX_IRQ_VIC1(15) ++#define IRQ_UHOST S3C64XX_IRQ_VIC1(15) + #define IRQ_SPI0 S3C64XX_IRQ_VIC1(16) + #define IRQ_SPI1 S3C64XX_IRQ_VIC1(17) + #define IRQ_IIC S3C64XX_IRQ_VIC1(18) +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/arch/arm/plat-s3c64xx/irq.c linux-2.6.29-rc3.owrt/arch/arm/plat-s3c64xx/irq.c +--- linux-2.6.29.owrt/arch/arm/plat-s3c64xx/irq.c 2009-05-10 22:04:41.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/arch/arm/plat-s3c64xx/irq.c 2009-05-10 23:48:28.000000000 +0200 +@@ -207,7 +207,7 @@ + + static void __init s3c64xx_uart_irq(struct uart_irq *uirq) + { +- void __iomem *reg_base = uirq->regs; ++ void *reg_base = uirq->regs; + unsigned int irq; + int offs; + +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/arch/arm/plat-s3c64xx/irq-eint.c linux-2.6.29-rc3.owrt/arch/arm/plat-s3c64xx/irq-eint.c +--- linux-2.6.29.owrt/arch/arm/plat-s3c64xx/irq-eint.c 2009-05-10 22:04:41.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/arch/arm/plat-s3c64xx/irq-eint.c 2009-05-10 23:48:28.000000000 +0200 +@@ -14,15 +14,12 @@ + + #include <linux/kernel.h> + #include <linux/interrupt.h> +-#include <linux/gpio.h> + #include <linux/irq.h> + #include <linux/io.h> + + #include <asm/hardware/vic.h> + + #include <plat/regs-irqtype.h> +-#include <plat/regs-gpio.h> +-#include <plat/gpio-cfg.h> + + #include <mach/map.h> + #include <plat/cpu.h> +@@ -58,7 +55,7 @@ + u32 mask; + + mask = __raw_readl(S3C64XX_EINT0MASK); +- mask &= ~eint_irq_to_bit(irq); ++ mask |= eint_irq_to_bit(irq); + __raw_writel(mask, S3C64XX_EINT0MASK); + } + +@@ -77,7 +74,6 @@ + static int s3c_irq_eint_set_type(unsigned int irq, unsigned int type) + { + int offs = eint_offset(irq); +- int pin; + int shift; + u32 ctrl, mask; + u32 newvalue = 0; +@@ -129,15 +125,6 @@ + ctrl |= newvalue << shift; + __raw_writel(ctrl, reg); + +- /* set the GPIO pin appropriately */ +- +- if (offs < 23) +- pin = S3C64XX_GPN(offs); +- else +- pin = S3C64XX_GPM(offs - 23); +- +- s3c_gpio_cfgpin(pin, S3C_GPIO_SFN(2)); +- + return 0; + } + +@@ -194,7 +181,7 @@ + s3c_irq_demux_eint(20, 27); + } + +-static int __init s3c64xx_init_irq_eint(void) ++int __init s3c64xx_init_irq_eint(void) + { + int irq; + +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/arch/arm/plat-s3c64xx/s3c6400-clock.c linux-2.6.29-rc3.owrt/arch/arm/plat-s3c64xx/s3c6400-clock.c +--- linux-2.6.29.owrt/arch/arm/plat-s3c64xx/s3c6400-clock.c 2009-05-10 22:04:41.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/arch/arm/plat-s3c64xx/s3c6400-clock.c 2009-05-10 23:48:28.000000000 +0200 +@@ -36,7 +36,7 @@ + * ext_xtal_mux for want of an actual name from the manual. + */ + +-static struct clk clk_ext_xtal_mux = { ++struct clk clk_ext_xtal_mux = { + .name = "ext_xtal", + .id = -1, + }; +@@ -63,7 +63,7 @@ + void __iomem *reg_divider; + }; + +-static struct clk clk_fout_apll = { ++struct clk clk_fout_apll = { + .name = "fout_apll", + .id = -1, + }; +@@ -78,7 +78,7 @@ + .nr_sources = ARRAY_SIZE(clk_src_apll_list), + }; + +-static struct clksrc_clk clk_mout_apll = { ++struct clksrc_clk clk_mout_apll = { + .clk = { + .name = "mout_apll", + .id = -1, +@@ -88,7 +88,7 @@ + .sources = &clk_src_apll, + }; + +-static struct clk clk_fout_epll = { ++struct clk clk_fout_epll = { + .name = "fout_epll", + .id = -1, + }; +@@ -103,7 +103,7 @@ + .nr_sources = ARRAY_SIZE(clk_src_epll_list), + }; + +-static struct clksrc_clk clk_mout_epll = { ++struct clksrc_clk clk_mout_epll = { + .clk = { + .name = "mout_epll", + .id = -1, +@@ -123,7 +123,7 @@ + .nr_sources = ARRAY_SIZE(clk_src_mpll_list), + }; + +-static struct clksrc_clk clk_mout_mpll = { ++struct clksrc_clk clk_mout_mpll = { + .clk = { + .name = "mout_mpll", + .id = -1, +@@ -145,7 +145,7 @@ + return rate; + } + +-static struct clk clk_dout_mpll = { ++struct clk clk_dout_mpll = { + .name = "dout_mpll", + .id = -1, + .parent = &clk_mout_mpll.clk, +@@ -189,10 +189,10 @@ + }; + + static struct clk *clkset_uhost_list[] = { +- &clk_48m, + &clk_mout_epll.clk, + &clk_dout_mpll, + &clk_fin_epll, ++ &clk_48m, + }; + + static struct clk_sources clkset_uhost = { +@@ -239,12 +239,10 @@ + + rate = clk_round_rate(clk, rate); + div = clk_get_rate(clk->parent) / rate; +- if (div > 16) +- return -EINVAL; + + val = __raw_readl(reg); +- val &= ~(0xf << sclk->shift); +- val |= (div - 1) << sclk->shift; ++ val &= ~sclk->mask; ++ val |= (rate - 1) << sclk->shift; + __raw_writel(val, reg); + + return 0; +@@ -353,7 +351,7 @@ + + static struct clksrc_clk clk_usbhost = { + .clk = { +- .name = "usb-bus-host", ++ .name = "usb-host-bus", + .id = -1, + .ctrlbit = S3C_CLKCON_SCLK_UHOST, + .enable = s3c64xx_sclk_ctrl, +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/arch/arm/tools/mach-types linux-2.6.29-rc3.owrt/arch/arm/tools/mach-types +--- linux-2.6.29.owrt/arch/arm/tools/mach-types 2009-05-10 22:04:41.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/arch/arm/tools/mach-types 2009-05-10 23:48:28.000000000 +0200 +@@ -12,7 +12,7 @@ + # + # http://www.arm.linux.org.uk/developer/machines/?action=new + # +-# Last update: Thu Mar 12 18:01:45 2009 ++# Last update: Sun Nov 30 16:39:36 2008 + # + # machine_is_xxx CONFIG_xxxx MACH_TYPE_xxx number + # +@@ -1811,7 +1811,7 @@ + jade MACH_JADE JADE 1821 + ks8695_softplc MACH_KS8695_SOFTPLC KS8695_SOFTPLC 1822 + gprisc3 MACH_GPRISC3 GPRISC3 1823 +-stamp9g20 MACH_STAMP9G20 STAMP9G20 1824 ++stamp9260 MACH_STAMP9260 STAMP9260 1824 + smdk6430 MACH_SMDK6430 SMDK6430 1825 + smdkc100 MACH_SMDKC100 SMDKC100 1826 + tavorevb MACH_TAVOREVB TAVOREVB 1827 +@@ -1993,134 +1993,4 @@ + benzina MACH_BENZINA BENZINA 2003 + blaze MACH_BLAZE BLAZE 2004 + linkstation_ls_hgl MACH_LINKSTATION_LS_HGL LINKSTATION_LS_HGL 2005 +-htckovsky MACH_HTCVENUS HTCVENUS 2006 +-sony_prs505 MACH_SONY_PRS505 SONY_PRS505 2007 +-hanlin_v3 MACH_HANLIN_V3 HANLIN_V3 2008 +-sapphira MACH_SAPPHIRA SAPPHIRA 2009 +-dack_sda_01 MACH_DACK_SDA_01 DACK_SDA_01 2010 +-armbox MACH_ARMBOX ARMBOX 2011 +-harris_rvp MACH_HARRIS_RVP HARRIS_RVP 2012 +-ribaldo MACH_RIBALDO RIBALDO 2013 +-agora MACH_AGORA AGORA 2014 +-omap3_mini MACH_OMAP3_MINI OMAP3_MINI 2015 +-a9sam6432_b MACH_A9SAM6432_B A9SAM6432_B 2016 +-usg2410 MACH_USG2410 USG2410 2017 +-pc72052_i10_revb MACH_PC72052_I10_REVB PC72052_I10_REVB 2018 +-mx35_exm32 MACH_MX35_EXM32 MX35_EXM32 2019 +-topas910 MACH_TOPAS910 TOPAS910 2020 +-hyena MACH_HYENA HYENA 2021 +-pospax MACH_POSPAX POSPAX 2022 +-hdl_gx MACH_HDL_GX HDL_GX 2023 +-ctera_4bay MACH_CTERA_4BAY CTERA_4BAY 2024 +-ctera_plug_c MACH_CTERA_PLUG_C CTERA_PLUG_C 2025 +-crwea_plug_i MACH_CRWEA_PLUG_I CRWEA_PLUG_I 2026 +-egauge2 MACH_EGAUGE2 EGAUGE2 2027 +-didj MACH_DIDJ DIDJ 2028 +-m_s3c2443 MACH_MEISTER MEISTER 2029 +-htcblackstone MACH_HTCBLACKSTONE HTCBLACKSTONE 2030 +-cpuat9g20 MACH_CPUAT9G20 CPUAT9G20 2031 +-smdk6440 MACH_SMDK6440 SMDK6440 2032 +-omap_35xx_mvp MACH_OMAP_35XX_MVP OMAP_35XX_MVP 2033 +-ctera_plug_i MACH_CTERA_PLUG_I CTERA_PLUG_I 2034 +-pvg610_100 MACH_PVG610 PVG610 2035 +-hprw6815 MACH_HPRW6815 HPRW6815 2036 +-omap3_oswald MACH_OMAP3_OSWALD OMAP3_OSWALD 2037 +-nas4220b MACH_NAS4220B NAS4220B 2038 +-htcraphael_cdma MACH_HTCRAPHAEL_CDMA HTCRAPHAEL_CDMA 2039 +-htcdiamond_cdma MACH_HTCDIAMOND_CDMA HTCDIAMOND_CDMA 2040 +-scaler MACH_SCALER SCALER 2041 +-zylonite2 MACH_ZYLONITE2 ZYLONITE2 2042 +-aspenite MACH_ASPENITE ASPENITE 2043 +-teton MACH_TETON TETON 2044 +-ttc_dkb MACH_TTC_DKB TTC_DKB 2045 +-bishop2 MACH_BISHOP2 BISHOP2 2046 +-ippv5 MACH_IPPV5 IPPV5 2047 +-farm926 MACH_FARM926 FARM926 2048 +-mmccpu MACH_MMCCPU MMCCPU 2049 +-sgmsfl MACH_SGMSFL SGMSFL 2050 +-tt8000 MACH_TT8000 TT8000 2051 +-zrn4300lp MACH_ZRN4300LP ZRN4300LP 2052 +-mptc MACH_MPTC MPTC 2053 +-h6051 MACH_H6051 H6051 2054 +-pvg610_101 MACH_PVG610_101 PVG610_101 2055 +-stamp9261_pc_evb MACH_STAMP9261_PC_EVB STAMP9261_PC_EVB 2056 +-pelco_odysseus MACH_PELCO_ODYSSEUS PELCO_ODYSSEUS 2057 +-tny_a9260 MACH_TNY_A9260 TNY_A9260 2058 +-tny_a9g20 MACH_TNY_A9G20 TNY_A9G20 2059 +-aesop_mp2530f MACH_AESOP_MP2530F AESOP_MP2530F 2060 +-dx900 MACH_DX900 DX900 2061 +-cpodc2 MACH_CPODC2 CPODC2 2062 +-tilt_8925 MACH_TILT_8925 TILT_8925 2063 +-davinci_dm357_evm MACH_DAVINCI_DM357_EVM DAVINCI_DM357_EVM 2064 +-swordfish MACH_SWORDFISH SWORDFISH 2065 +-corvus MACH_CORVUS CORVUS 2066 +-taurus MACH_TAURUS TAURUS 2067 +-axm MACH_AXM AXM 2068 +-axc MACH_AXC AXC 2069 +-baby MACH_BABY BABY 2070 +-mp200 MACH_MP200 MP200 2071 +-pcm043 MACH_PCM043 PCM043 2072 +-hanlin_v3c MACH_HANLIN_V3C HANLIN_V3C 2073 +-kbk9g20 MACH_KBK9G20 KBK9G20 2074 +-adsturbog5 MACH_ADSTURBOG5 ADSTURBOG5 2075 +-avenger_lite1 MACH_AVENGER_LITE1 AVENGER_LITE1 2076 +-suc82x MACH_SUC SUC 2077 +-at91sam7s256 MACH_AT91SAM7S256 AT91SAM7S256 2078 +-mendoza MACH_MENDOZA MENDOZA 2079 +-kira MACH_KIRA KIRA 2080 +-mx1hbm MACH_MX1HBM MX1HBM 2081 +-quatro43xx MACH_QUATRO43XX QUATRO43XX 2082 +-quatro4230 MACH_QUATRO4230 QUATRO4230 2083 +-nsb400 MACH_NSB400 NSB400 2084 +-drp255 MACH_DRP255 DRP255 2085 +-thoth MACH_THOTH THOTH 2086 +-firestone MACH_FIRESTONE FIRESTONE 2087 +-asusp750 MACH_ASUSP750 ASUSP750 2088 +-ctera_dl MACH_CTERA_DL CTERA_DL 2089 +-socr MACH_SOCR SOCR 2090 +-htcoxygen MACH_HTCOXYGEN HTCOXYGEN 2091 +-heroc MACH_HEROC HEROC 2092 +-zeno6800 MACH_ZENO6800 ZENO6800 2093 +-sc2mcs MACH_SC2MCS SC2MCS 2094 +-gene100 MACH_GENE100 GENE100 2095 +-as353x MACH_AS353X AS353X 2096 +-sheevaplug MACH_SHEEVAPLUG SHEEVAPLUG 2097 +-at91sam9g20 MACH_AT91SAM9G20 AT91SAM9G20 2098 +-mv88f6192gtw_fe MACH_MV88F6192GTW_FE MV88F6192GTW_FE 2099 +-cc9200 MACH_CC9200 CC9200 2100 +-sm9200 MACH_SM9200 SM9200 2101 +-tp9200 MACH_TP9200 TP9200 2102 +-snapperdv MACH_SNAPPERDV SNAPPERDV 2103 +-avengers_lite MACH_AVENGERS_LITE AVENGERS_LITE 2104 +-avengers_lite1 MACH_AVENGERS_LITE1 AVENGERS_LITE1 2105 +-omap3axon MACH_OMAP3AXON OMAP3AXON 2106 +-ma8xx MACH_MA8XX MA8XX 2107 +-mp201ek MACH_MP201EK MP201EK 2108 +-davinci_tux MACH_DAVINCI_TUX DAVINCI_TUX 2109 +-mpa1600 MACH_MPA1600 MPA1600 2110 +-pelco_troy MACH_PELCO_TROY PELCO_TROY 2111 +-nsb667 MACH_NSB667 NSB667 2112 +-rovers5_4mpix MACH_ROVERS5_4MPIX ROVERS5_4MPIX 2113 +-twocom MACH_TWOCOM TWOCOM 2114 +-ubisys_p9_rcu3r2 MACH_UBISYS_P9_RCU3R2 UBISYS_P9_RCU3R2 2115 +-hero_espresso MACH_HERO_ESPRESSO HERO_ESPRESSO 2116 +-afeusb MACH_AFEUSB AFEUSB 2117 +-t830 MACH_T830 T830 2118 +-spd8020_cc MACH_SPD8020_CC SPD8020_CC 2119 +-om_3d7k MACH_OM_3D7K OM_3D7K 2120 +-picocom2 MACH_PICOCOM2 PICOCOM2 2121 +-uwg4mx27 MACH_UWG4MX27 UWG4MX27 2122 +-uwg4mx31 MACH_UWG4MX31 UWG4MX31 2123 +-cherry MACH_CHERRY CHERRY 2124 +-mx51_babbage MACH_MX51_BABBAGE MX51_BABBAGE 2125 +-s3c2440turkiye MACH_S3C2440TURKIYE S3C2440TURKIYE 2126 +-tx37 MACH_TX37 TX37 2127 +-sbc2800_9g20 MACH_SBC2800_9G20 SBC2800_9G20 2128 +-benzglb MACH_BENZGLB BENZGLB 2129 +-benztd MACH_BENZTD BENZTD 2130 +-cartesio_plus MACH_CARTESIO_PLUS CARTESIO_PLUS 2131 +-solrad_g20 MACH_SOLRAD_G20 SOLRAD_G20 2132 +-mx27wallace MACH_MX27WALLACE MX27WALLACE 2133 +-fmzwebmodul MACH_FMZWEBMODUL FMZWEBMODUL 2134 +-rd78x00_masa MACH_RD78X00_MASA RD78X00_MASA 2135 +-smallogger MACH_SMALLOGGER SMALLOGGER 2136 ++htcvenus MACH_HTCVENUS HTCVENUS 2006 +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/arch/avr32/mach-at32ap/include/mach/board.h linux-2.6.29-rc3.owrt/arch/avr32/mach-at32ap/include/mach/board.h +--- linux-2.6.29.owrt/arch/avr32/mach-at32ap/include/mach/board.h 2009-05-10 22:04:40.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/arch/avr32/mach-at32ap/include/mach/board.h 2009-05-10 23:48:28.000000000 +0200 +@@ -116,7 +116,6 @@ + int enable_pin; /* chip enable */ + int det_pin; /* card detect */ + int rdy_pin; /* ready/busy */ +- u8 rdy_pin_active_low; /* rdy_pin value is inverted */ + u8 ale; /* address line number connected to ALE */ + u8 cle; /* address line number connected to CLE */ + u8 bus_width_16; /* buswidth is 16 bit */ +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/arch/blackfin/configs/BF518F-EZBRD_defconfig linux-2.6.29-rc3.owrt/arch/blackfin/configs/BF518F-EZBRD_defconfig +--- linux-2.6.29.owrt/arch/blackfin/configs/BF518F-EZBRD_defconfig 2009-05-10 22:04:41.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/arch/blackfin/configs/BF518F-EZBRD_defconfig 2009-05-10 23:48:28.000000000 +0200 +@@ -1,7 +1,6 @@ + # + # Automatically generated make config: don't edit +-# Linux kernel version: 2.6.28 +-# Fri Feb 20 10:01:44 2009 ++# Linux kernel version: 2.6.28-rc2 + # + # CONFIG_MMU is not set + # CONFIG_FPU is not set +@@ -133,15 +132,10 @@ + # CONFIG_BF538 is not set + # CONFIG_BF539 is not set + # CONFIG_BF542 is not set +-# CONFIG_BF542M is not set + # CONFIG_BF544 is not set +-# CONFIG_BF544M is not set + # CONFIG_BF547 is not set +-# CONFIG_BF547M is not set + # CONFIG_BF548 is not set +-# CONFIG_BF548M is not set + # CONFIG_BF549 is not set +-# CONFIG_BF549M is not set + # CONFIG_BF561 is not set + CONFIG_BF_REV_MIN=0 + CONFIG_BF_REV_MAX=2 +@@ -155,7 +149,6 @@ + # CONFIG_BF_REV_ANY is not set + # CONFIG_BF_REV_NONE is not set + CONFIG_BF51x=y +-CONFIG_MEM_MT48LC32M8A2_75=y + CONFIG_BFIN518F_EZBRD=y + + # +@@ -431,17 +424,7 @@ + # CONFIG_TIPC is not set + # CONFIG_ATM is not set + # CONFIG_BRIDGE is not set +-CONFIG_NET_DSA=y +-# CONFIG_NET_DSA_TAG_DSA is not set +-# CONFIG_NET_DSA_TAG_EDSA is not set +-# CONFIG_NET_DSA_TAG_TRAILER is not set +-CONFIG_NET_DSA_TAG_STPID=y +-# CONFIG_NET_DSA_MV88E6XXX is not set +-# CONFIG_NET_DSA_MV88E6060 is not set +-# CONFIG_NET_DSA_MV88E6XXX_NEED_PPU is not set +-# CONFIG_NET_DSA_MV88E6131 is not set +-# CONFIG_NET_DSA_MV88E6123_61_65 is not set +-CONFIG_NET_DSA_KSZ8893M=y ++# CONFIG_NET_DSA is not set + # CONFIG_VLAN_8021Q is not set + # CONFIG_DECNET is not set + # CONFIG_LLC2 is not set +@@ -544,8 +527,6 @@ + # + # Self-contained MTD device drivers + # +-# CONFIG_MTD_DATAFLASH is not set +-# CONFIG_MTD_M25P80 is not set + # CONFIG_MTD_SLRAM is not set + # CONFIG_MTD_PHRAM is not set + # CONFIG_MTD_MTDRAM is not set +@@ -578,9 +559,7 @@ + # CONFIG_BLK_DEV_HD is not set + CONFIG_MISC_DEVICES=y + # CONFIG_EEPROM_93CX6 is not set +-# CONFIG_ICS932S401 is not set + # CONFIG_ENCLOSURE_SERVICES is not set +-# CONFIG_C2PORT is not set + CONFIG_HAVE_IDE=y + # CONFIG_IDE is not set + +@@ -619,14 +598,10 @@ + # CONFIG_MDIO_BITBANG is not set + CONFIG_NET_ETHERNET=y + CONFIG_MII=y +-CONFIG_BFIN_MAC=y +-CONFIG_BFIN_TX_DESC_NUM=10 +-CONFIG_BFIN_RX_DESC_NUM=20 +-# CONFIG_BFIN_MAC_RMII is not set ++# CONFIG_BFIN_MAC is not set + # CONFIG_SMC91X is not set + # CONFIG_SMSC911X is not set + # CONFIG_DM9000 is not set +-# CONFIG_ENC28J60 is not set + # CONFIG_IBM_NEW_EMAC_ZMII is not set + # CONFIG_IBM_NEW_EMAC_RGMII is not set + # CONFIG_IBM_NEW_EMAC_TAH is not set +@@ -704,7 +679,7 @@ + CONFIG_HW_CONSOLE=y + # CONFIG_VT_HW_CONSOLE_BINDING is not set + # CONFIG_DEVKMEM is not set +-CONFIG_BFIN_JTAG_COMM=m ++# CONFIG_BFIN_JTAG_COMM is not set + # CONFIG_SERIAL_NONSTANDARD is not set + + # +@@ -784,23 +759,7 @@ + # CONFIG_I2C_DEBUG_ALGO is not set + # CONFIG_I2C_DEBUG_BUS is not set + # CONFIG_I2C_DEBUG_CHIP is not set +-CONFIG_SPI=y +-# CONFIG_SPI_DEBUG is not set +-CONFIG_SPI_MASTER=y +- +-# +-# SPI Master Controller Drivers +-# +-CONFIG_SPI_BFIN=y +-# CONFIG_SPI_BFIN_LOCK is not set +-# CONFIG_SPI_BITBANG is not set +- +-# +-# SPI Protocol Masters +-# +-# CONFIG_SPI_AT25 is not set +-# CONFIG_SPI_SPIDEV is not set +-# CONFIG_SPI_TLE62X0 is not set ++# CONFIG_SPI is not set + CONFIG_ARCH_WANT_OPTIONAL_GPIOLIB=y + # CONFIG_GPIOLIB is not set + # CONFIG_W1 is not set +@@ -824,10 +783,8 @@ + # CONFIG_MFD_SM501 is not set + # CONFIG_HTC_PASIC3 is not set + # CONFIG_MFD_TMIO is not set +-# CONFIG_PMIC_DA903X is not set + # CONFIG_MFD_WM8400 is not set + # CONFIG_MFD_WM8350_I2C is not set +-# CONFIG_REGULATOR is not set + + # + # Multimedia devices +@@ -899,18 +856,10 @@ + # CONFIG_RTC_DRV_M41T80 is not set + # CONFIG_RTC_DRV_S35390A is not set + # CONFIG_RTC_DRV_FM3130 is not set +-# CONFIG_RTC_DRV_RX8581 is not set + + # + # SPI RTC drivers + # +-# CONFIG_RTC_DRV_M41T94 is not set +-# CONFIG_RTC_DRV_DS1305 is not set +-# CONFIG_RTC_DRV_DS1390 is not set +-# CONFIG_RTC_DRV_MAX6902 is not set +-# CONFIG_RTC_DRV_R9701 is not set +-# CONFIG_RTC_DRV_RS5C348 is not set +-# CONFIG_RTC_DRV_DS3234 is not set + + # + # Platform RTC drivers +@@ -1108,20 +1057,12 @@ + # CONFIG_DEBUG_BLOCK_EXT_DEVT is not set + # CONFIG_FAULT_INJECTION is not set + CONFIG_SYSCTL_SYSCALL_CHECK=y +- +-# +-# Tracers +-# +-# CONFIG_SCHED_TRACER is not set +-# CONFIG_CONTEXT_SWITCH_TRACER is not set +-# CONFIG_BOOT_TRACER is not set + # CONFIG_DYNAMIC_PRINTK_DEBUG is not set + # CONFIG_SAMPLES is not set + CONFIG_HAVE_ARCH_KGDB=y + # CONFIG_KGDB is not set + # CONFIG_DEBUG_STACKOVERFLOW is not set + # CONFIG_DEBUG_STACK_USAGE is not set +-# CONFIG_KGDB_TESTCASE is not set + CONFIG_DEBUG_VERBOSE=y + CONFIG_DEBUG_MMRS=y + # CONFIG_DEBUG_HWERR is not set +@@ -1154,7 +1095,6 @@ + # + # CONFIG_CRYPTO_FIPS is not set + # CONFIG_CRYPTO_MANAGER is not set +-# CONFIG_CRYPTO_MANAGER2 is not set + # CONFIG_CRYPTO_GF128MUL is not set + # CONFIG_CRYPTO_NULL is not set + # CONFIG_CRYPTO_CRYPTD is not set +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/arch/blackfin/configs/BF526-EZBRD_defconfig linux-2.6.29-rc3.owrt/arch/blackfin/configs/BF526-EZBRD_defconfig +--- linux-2.6.29.owrt/arch/blackfin/configs/BF526-EZBRD_defconfig 2009-05-10 22:04:41.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/arch/blackfin/configs/BF526-EZBRD_defconfig 2009-05-10 23:48:28.000000000 +0200 +@@ -723,7 +723,7 @@ + CONFIG_HW_CONSOLE=y + # CONFIG_VT_HW_CONSOLE_BINDING is not set + # CONFIG_DEVKMEM is not set +-CONFIG_BFIN_JTAG_COMM=m ++# CONFIG_BFIN_JTAG_COMM is not set + # CONFIG_SERIAL_NONSTANDARD is not set + + # +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/arch/blackfin/configs/BF527-EZKIT_defconfig linux-2.6.29-rc3.owrt/arch/blackfin/configs/BF527-EZKIT_defconfig +--- linux-2.6.29.owrt/arch/blackfin/configs/BF527-EZKIT_defconfig 2009-05-10 22:04:41.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/arch/blackfin/configs/BF527-EZKIT_defconfig 2009-05-10 23:48:28.000000000 +0200 +@@ -327,8 +327,8 @@ + CONFIG_BFIN_DCACHE=y + # CONFIG_BFIN_DCACHE_BANKA is not set + # CONFIG_BFIN_ICACHE_LOCK is not set +-CONFIG_BFIN_WB=y +-# CONFIG_BFIN_WT is not set ++# CONFIG_BFIN_WB is not set ++CONFIG_BFIN_WT=y + # CONFIG_MPU is not set + + # +@@ -767,7 +767,7 @@ + CONFIG_HW_CONSOLE=y + # CONFIG_VT_HW_CONSOLE_BINDING is not set + # CONFIG_DEVKMEM is not set +-CONFIG_BFIN_JTAG_COMM=m ++# CONFIG_BFIN_JTAG_COMM is not set + # CONFIG_SERIAL_NONSTANDARD is not set + + # +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/arch/blackfin/configs/BF533-EZKIT_defconfig linux-2.6.29-rc3.owrt/arch/blackfin/configs/BF533-EZKIT_defconfig +--- linux-2.6.29.owrt/arch/blackfin/configs/BF533-EZKIT_defconfig 2009-05-10 22:04:41.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/arch/blackfin/configs/BF533-EZKIT_defconfig 2009-05-10 23:48:28.000000000 +0200 +@@ -290,8 +290,8 @@ + CONFIG_BFIN_DCACHE=y + # CONFIG_BFIN_DCACHE_BANKA is not set + # CONFIG_BFIN_ICACHE_LOCK is not set +-CONFIG_BFIN_WB=y +-# CONFIG_BFIN_WT is not set ++# CONFIG_BFIN_WB is not set ++CONFIG_BFIN_WT=y + # CONFIG_MPU is not set + + # +@@ -672,7 +672,7 @@ + CONFIG_SIMPLE_GPIO=m + # CONFIG_VT is not set + # CONFIG_DEVKMEM is not set +-CONFIG_BFIN_JTAG_COMM=m ++# CONFIG_BFIN_JTAG_COMM is not set + # CONFIG_SERIAL_NONSTANDARD is not set + + # +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/arch/blackfin/configs/BF533-STAMP_defconfig linux-2.6.29-rc3.owrt/arch/blackfin/configs/BF533-STAMP_defconfig +--- linux-2.6.29.owrt/arch/blackfin/configs/BF533-STAMP_defconfig 2009-05-10 22:04:41.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/arch/blackfin/configs/BF533-STAMP_defconfig 2009-05-10 23:48:28.000000000 +0200 +@@ -290,8 +290,8 @@ + CONFIG_BFIN_DCACHE=y + # CONFIG_BFIN_DCACHE_BANKA is not set + # CONFIG_BFIN_ICACHE_LOCK is not set +-CONFIG_BFIN_WB=y +-# CONFIG_BFIN_WT is not set ++# CONFIG_BFIN_WB is not set ++CONFIG_BFIN_WT=y + # CONFIG_MPU is not set + + # +@@ -679,7 +679,7 @@ + CONFIG_SIMPLE_GPIO=m + # CONFIG_VT is not set + # CONFIG_DEVKMEM is not set +-CONFIG_BFIN_JTAG_COMM=m ++# CONFIG_BFIN_JTAG_COMM is not set + # CONFIG_SERIAL_NONSTANDARD is not set + + # +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/arch/blackfin/configs/BF537-STAMP_defconfig linux-2.6.29-rc3.owrt/arch/blackfin/configs/BF537-STAMP_defconfig +--- linux-2.6.29.owrt/arch/blackfin/configs/BF537-STAMP_defconfig 2009-05-10 22:04:41.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/arch/blackfin/configs/BF537-STAMP_defconfig 2009-05-10 23:48:28.000000000 +0200 +@@ -298,8 +298,8 @@ + CONFIG_BFIN_DCACHE=y + # CONFIG_BFIN_DCACHE_BANKA is not set + # CONFIG_BFIN_ICACHE_LOCK is not set +-CONFIG_BFIN_WB=y +-# CONFIG_BFIN_WT is not set ++# CONFIG_BFIN_WB is not set ++CONFIG_BFIN_WT=y + # CONFIG_MPU is not set + + # +@@ -568,7 +568,15 @@ + # CONFIG_MTD_DOC2000 is not set + # CONFIG_MTD_DOC2001 is not set + # CONFIG_MTD_DOC2001PLUS is not set +-# CONFIG_MTD_NAND is not set ++CONFIG_MTD_NAND=m ++# CONFIG_MTD_NAND_VERIFY_WRITE is not set ++# CONFIG_MTD_NAND_ECC_SMC is not set ++# CONFIG_MTD_NAND_MUSEUM_IDS is not set ++# CONFIG_MTD_NAND_BFIN is not set ++CONFIG_MTD_NAND_IDS=m ++# CONFIG_MTD_NAND_DISKONCHIP is not set ++# CONFIG_MTD_NAND_NANDSIM is not set ++CONFIG_MTD_NAND_PLATFORM=m + # CONFIG_MTD_ONENAND is not set + + # +@@ -714,7 +722,7 @@ + CONFIG_SIMPLE_GPIO=m + # CONFIG_VT is not set + # CONFIG_DEVKMEM is not set +-CONFIG_BFIN_JTAG_COMM=m ++# CONFIG_BFIN_JTAG_COMM is not set + # CONFIG_SERIAL_NONSTANDARD is not set + + # +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/arch/blackfin/configs/BF538-EZKIT_defconfig linux-2.6.29-rc3.owrt/arch/blackfin/configs/BF538-EZKIT_defconfig +--- linux-2.6.29.owrt/arch/blackfin/configs/BF538-EZKIT_defconfig 2009-05-10 22:04:41.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/arch/blackfin/configs/BF538-EZKIT_defconfig 2009-05-10 23:48:28.000000000 +0200 +@@ -306,8 +306,8 @@ + CONFIG_BFIN_DCACHE=y + # CONFIG_BFIN_DCACHE_BANKA is not set + # CONFIG_BFIN_ICACHE_LOCK is not set +-CONFIG_BFIN_WB=y +-# CONFIG_BFIN_WT is not set ++# CONFIG_BFIN_WB is not set ++CONFIG_BFIN_WT=y + # CONFIG_MPU is not set + + # +@@ -726,7 +726,7 @@ + CONFIG_SIMPLE_GPIO=m + # CONFIG_VT is not set + # CONFIG_DEVKMEM is not set +-CONFIG_BFIN_JTAG_COMM=m ++# CONFIG_BFIN_JTAG_COMM is not set + # CONFIG_SERIAL_NONSTANDARD is not set + + # +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/arch/blackfin/configs/BF548-EZKIT_defconfig linux-2.6.29-rc3.owrt/arch/blackfin/configs/BF548-EZKIT_defconfig +--- linux-2.6.29.owrt/arch/blackfin/configs/BF548-EZKIT_defconfig 2009-05-10 22:04:41.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/arch/blackfin/configs/BF548-EZKIT_defconfig 2009-05-10 23:48:28.000000000 +0200 +@@ -361,8 +361,8 @@ + CONFIG_BFIN_DCACHE=y + # CONFIG_BFIN_DCACHE_BANKA is not set + # CONFIG_BFIN_ICACHE_LOCK is not set +-CONFIG_BFIN_WB=y +-# CONFIG_BFIN_WT is not set ++# CONFIG_BFIN_WB is not set ++CONFIG_BFIN_WT=y + # CONFIG_BFIN_L2_CACHEABLE is not set + # CONFIG_MPU is not set + +@@ -680,7 +680,7 @@ + CONFIG_SCSI_DMA=y + # CONFIG_SCSI_TGT is not set + # CONFIG_SCSI_NETLINK is not set +-# CONFIG_SCSI_PROC_FS is not set ++CONFIG_SCSI_PROC_FS=y + + # + # SCSI support type (disk, tape, CD-ROM) +@@ -856,7 +856,7 @@ + CONFIG_HW_CONSOLE=y + # CONFIG_VT_HW_CONSOLE_BINDING is not set + # CONFIG_DEVKMEM is not set +-CONFIG_BFIN_JTAG_COMM=m ++# CONFIG_BFIN_JTAG_COMM is not set + # CONFIG_SERIAL_NONSTANDARD is not set + + # +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/arch/blackfin/configs/BF561-EZKIT_defconfig linux-2.6.29-rc3.owrt/arch/blackfin/configs/BF561-EZKIT_defconfig +--- linux-2.6.29.owrt/arch/blackfin/configs/BF561-EZKIT_defconfig 2009-05-10 22:04:41.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/arch/blackfin/configs/BF561-EZKIT_defconfig 2009-05-10 23:48:28.000000000 +0200 +@@ -329,8 +329,8 @@ + CONFIG_BFIN_DCACHE=y + # CONFIG_BFIN_DCACHE_BANKA is not set + # CONFIG_BFIN_ICACHE_LOCK is not set +-CONFIG_BFIN_WB=y +-# CONFIG_BFIN_WT is not set ++# CONFIG_BFIN_WB is not set ++CONFIG_BFIN_WT=y + # CONFIG_BFIN_L2_CACHEABLE is not set + # CONFIG_MPU is not set + +@@ -709,7 +709,7 @@ + CONFIG_SIMPLE_GPIO=m + # CONFIG_VT is not set + # CONFIG_DEVKMEM is not set +-CONFIG_BFIN_JTAG_COMM=m ++# CONFIG_BFIN_JTAG_COMM is not set + # CONFIG_SERIAL_NONSTANDARD is not set + + # +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/arch/blackfin/configs/BlackStamp_defconfig linux-2.6.29-rc3.owrt/arch/blackfin/configs/BlackStamp_defconfig +--- linux-2.6.29.owrt/arch/blackfin/configs/BlackStamp_defconfig 2009-05-10 22:04:41.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/arch/blackfin/configs/BlackStamp_defconfig 2009-05-10 23:48:28.000000000 +0200 +@@ -288,8 +288,8 @@ + CONFIG_BFIN_DCACHE=y + # CONFIG_BFIN_DCACHE_BANKA is not set + # CONFIG_BFIN_ICACHE_LOCK is not set +-CONFIG_BFIN_WB=y +-# CONFIG_BFIN_WT is not set ++# CONFIG_BFIN_WB is not set ++CONFIG_BFIN_WT=y + # CONFIG_MPU is not set + + # +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/arch/blackfin/configs/CM-BF527_defconfig linux-2.6.29-rc3.owrt/arch/blackfin/configs/CM-BF527_defconfig +--- linux-2.6.29.owrt/arch/blackfin/configs/CM-BF527_defconfig 2009-05-10 22:04:41.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/arch/blackfin/configs/CM-BF527_defconfig 2009-05-10 23:48:28.000000000 +0200 +@@ -1,6 +1,7 @@ + # + # Automatically generated make config: don't edit +-# Linux kernel version: 2.6.28 ++# Linux kernel version: 2.6.24.7 ++# Fri Jul 18 18:00:41 2008 + # + # CONFIG_MMU is not set + # CONFIG_FPU is not set +@@ -8,6 +9,7 @@ + # CONFIG_RWSEM_XCHGADD_ALGORITHM is not set + CONFIG_BLACKFIN=y + CONFIG_ZONE_DMA=y ++CONFIG_SEMAPHORE_SLEEPERS=y + CONFIG_GENERIC_FIND_NEXT_BIT=y + CONFIG_GENERIC_HWEIGHT=y + CONFIG_GENERIC_HARDIRQS=y +@@ -30,16 +32,18 @@ + # CONFIG_POSIX_MQUEUE is not set + # CONFIG_BSD_PROCESS_ACCT is not set + # CONFIG_TASKSTATS is not set ++# CONFIG_USER_NS is not set ++# CONFIG_PID_NS is not set + # CONFIG_AUDIT is not set + CONFIG_IKCONFIG=y + CONFIG_IKCONFIG_PROC=y + CONFIG_LOG_BUF_SHIFT=14 + # CONFIG_CGROUPS is not set +-# CONFIG_GROUP_SCHED is not set +-CONFIG_SYSFS_DEPRECATED=y +-CONFIG_SYSFS_DEPRECATED_V2=y ++CONFIG_FAIR_GROUP_SCHED=y ++CONFIG_FAIR_USER_SCHED=y ++# CONFIG_FAIR_CGROUP_SCHED is not set ++# CONFIG_SYSFS_DEPRECATED is not set + # CONFIG_RELAY is not set +-# CONFIG_NAMESPACES is not set + CONFIG_BLK_DEV_INITRD=y + CONFIG_INITRAMFS_SOURCE="" + # CONFIG_CC_OPTIMIZE_FOR_SIZE is not set +@@ -48,35 +52,26 @@ + CONFIG_UID16=y + CONFIG_SYSCTL_SYSCALL=y + CONFIG_KALLSYMS=y +-# CONFIG_KALLSYMS_ALL is not set + # CONFIG_KALLSYMS_EXTRA_PASS is not set + CONFIG_HOTPLUG=y + CONFIG_PRINTK=y + CONFIG_BUG=y + # CONFIG_ELF_CORE is not set +-CONFIG_COMPAT_BRK=y + CONFIG_BASE_FULL=y + CONFIG_FUTEX=y + CONFIG_ANON_INODES=y + CONFIG_EPOLL=y + CONFIG_SIGNALFD=y +-CONFIG_TIMERFD=y + CONFIG_EVENTFD=y +-CONFIG_AIO=y + CONFIG_VM_EVENT_COUNTERS=y + CONFIG_SLAB=y + # CONFIG_SLUB is not set + # CONFIG_SLOB is not set +-# CONFIG_PROFILING is not set +-# CONFIG_MARKERS is not set +-CONFIG_HAVE_OPROFILE=y +-# CONFIG_HAVE_GENERIC_DMA_COHERENT is not set + CONFIG_SLABINFO=y + CONFIG_RT_MUTEXES=y + CONFIG_TINY_SHMEM=y + CONFIG_BASE_SMALL=0 + CONFIG_MODULES=y +-# CONFIG_MODULE_FORCE_LOAD is not set + CONFIG_MODULE_UNLOAD=y + # CONFIG_MODULE_FORCE_UNLOAD is not set + # CONFIG_MODVERSIONS is not set +@@ -87,7 +82,6 @@ + # CONFIG_BLK_DEV_IO_TRACE is not set + # CONFIG_LSF is not set + # CONFIG_BLK_DEV_BSG is not set +-# CONFIG_BLK_DEV_INTEGRITY is not set + + # + # IO Schedulers +@@ -101,11 +95,9 @@ + CONFIG_DEFAULT_CFQ=y + # CONFIG_DEFAULT_NOOP is not set + CONFIG_DEFAULT_IOSCHED="cfq" +-CONFIG_CLASSIC_RCU=y + # CONFIG_PREEMPT_NONE is not set + CONFIG_PREEMPT_VOLUNTARY=y + # CONFIG_PREEMPT is not set +-# CONFIG_FREEZER is not set + + # + # Blackfin Processor Options +@@ -114,10 +106,6 @@ + # + # Processor and Board Settings + # +-# CONFIG_BF512 is not set +-# CONFIG_BF514 is not set +-# CONFIG_BF516 is not set +-# CONFIG_BF518 is not set + # CONFIG_BF522 is not set + # CONFIG_BF523 is not set + # CONFIG_BF524 is not set +@@ -130,32 +118,48 @@ + # CONFIG_BF534 is not set + # CONFIG_BF536 is not set + # CONFIG_BF537 is not set +-# CONFIG_BF538 is not set +-# CONFIG_BF539 is not set + # CONFIG_BF542 is not set +-# CONFIG_BF542M is not set + # CONFIG_BF544 is not set +-# CONFIG_BF544M is not set + # CONFIG_BF547 is not set +-# CONFIG_BF547M is not set + # CONFIG_BF548 is not set +-# CONFIG_BF548M is not set + # CONFIG_BF549 is not set +-# CONFIG_BF549M is not set + # CONFIG_BF561 is not set +-CONFIG_BF_REV_MIN=0 +-CONFIG_BF_REV_MAX=2 + # CONFIG_BF_REV_0_0 is not set + CONFIG_BF_REV_0_1=y + # CONFIG_BF_REV_0_2 is not set + # CONFIG_BF_REV_0_3 is not set + # CONFIG_BF_REV_0_4 is not set + # CONFIG_BF_REV_0_5 is not set +-# CONFIG_BF_REV_0_6 is not set + # CONFIG_BF_REV_ANY is not set + # CONFIG_BF_REV_NONE is not set + CONFIG_BF52x=y + CONFIG_MEM_MT48LC16M16A2TG_75=y ++# CONFIG_BFIN527_EZKIT is not set ++CONFIG_BFIN527_BLUETECHNIX_CM=y ++ ++# ++# BF527 Specific Configuration ++# ++ ++# ++# Alternative Multiplexing Scheme ++# ++# CONFIG_BF527_SPORT0_PORTF is not set ++CONFIG_BF527_SPORT0_PORTG=y ++CONFIG_BF527_SPORT0_TSCLK_PG10=y ++# CONFIG_BF527_SPORT0_TSCLK_PG14 is not set ++CONFIG_BF527_UART1_PORTF=y ++# CONFIG_BF527_UART1_PORTG is not set ++# CONFIG_BF527_NAND_D_PORTF is not set ++CONFIG_BF527_NAND_D_PORTH=y ++ ++# ++# Interrupt Priority Assignment ++# ++ ++# ++# Priority ++# + CONFIG_IRQ_PLL_WAKEUP=7 + CONFIG_IRQ_DMA0_ERROR=7 + CONFIG_IRQ_DMAR0_BLK=7 +@@ -175,6 +179,7 @@ + CONFIG_IRQ_SPORT1_RX=9 + CONFIG_IRQ_SPORT1_TX=9 + CONFIG_IRQ_TWI=10 ++CONFIG_IRQ_SPI=10 + CONFIG_IRQ_UART0_RX=10 + CONFIG_IRQ_UART0_TX=10 + CONFIG_IRQ_UART1_RX=10 +@@ -200,34 +205,6 @@ + CONFIG_IRQ_WATCH=13 + CONFIG_IRQ_PORTF_INTA=13 + CONFIG_IRQ_PORTF_INTB=13 +-# CONFIG_BFIN527_EZKIT is not set +-CONFIG_BFIN527_BLUETECHNIX_CM=y +-# CONFIG_BFIN526_EZBRD is not set +- +-# +-# BF527 Specific Configuration +-# +- +-# +-# Alternative Multiplexing Scheme +-# +-# CONFIG_BF527_SPORT0_PORTF is not set +-CONFIG_BF527_SPORT0_PORTG=y +-CONFIG_BF527_SPORT0_TSCLK_PG10=y +-# CONFIG_BF527_SPORT0_TSCLK_PG14 is not set +-CONFIG_BF527_UART1_PORTF=y +-# CONFIG_BF527_UART1_PORTG is not set +-# CONFIG_BF527_NAND_D_PORTF is not set +-CONFIG_BF527_NAND_D_PORTH=y +- +-# +-# Interrupt Priority Assignment +-# +- +-# +-# Priority +-# +-CONFIG_IRQ_SPI=10 + CONFIG_IRQ_SPI_ERROR=7 + CONFIG_IRQ_NFC_ERROR=7 + CONFIG_IRQ_HDMA_ERROR=7 +@@ -249,6 +226,7 @@ + # + CONFIG_CLKIN_HZ=25000000 + # CONFIG_BFIN_KERNEL_CLOCK is not set ++CONFIG_MAX_MEM_SIZE=512 + CONFIG_MAX_VCO_HZ=600000000 + CONFIG_MIN_VCO_HZ=50000000 + CONFIG_MAX_SCLK_HZ=133333333 +@@ -262,10 +240,10 @@ + # CONFIG_HZ_300 is not set + # CONFIG_HZ_1000 is not set + CONFIG_HZ=250 +-# CONFIG_SCHED_HRTICK is not set + CONFIG_GENERIC_TIME=y + CONFIG_GENERIC_CLOCKEVENTS=y + # CONFIG_CYCLES_CLOCKSOURCE is not set ++# CONFIG_TICK_ONESHOT is not set + # CONFIG_NO_HZ is not set + # CONFIG_HIGH_RES_TIMERS is not set + CONFIG_GENERIC_CLOCKEVENTS_BUILD=y +@@ -299,12 +277,6 @@ + CONFIG_CACHELINE_ALIGNED_L1=y + # CONFIG_SYSCALL_TAB_L1 is not set + # CONFIG_CPLB_SWITCH_TAB_L1 is not set +-CONFIG_APP_STACK_L1=y +- +-# +-# Speed Optimizations +-# +-CONFIG_BFIN_INS_LOWOVERHEAD=y + CONFIG_RAMKERNEL=y + # CONFIG_ROMKERNEL is not set + CONFIG_SELECT_MEMORY_MODEL=y +@@ -313,10 +285,10 @@ + # CONFIG_SPARSEMEM_MANUAL is not set + CONFIG_FLATMEM=y + CONFIG_FLAT_NODE_MEM_MAP=y +-CONFIG_PAGEFLAGS_EXTENDED=y ++# CONFIG_SPARSEMEM_STATIC is not set ++# CONFIG_SPARSEMEM_VMEMMAP_ENABLE is not set + CONFIG_SPLIT_PTLOCK_CPUS=4 + # CONFIG_RESOURCES_64BIT is not set +-# CONFIG_PHYS_ADDR_T_64BIT is not set + CONFIG_ZONE_DMA_FLAG=1 + CONFIG_VIRT_TO_BUS=y + CONFIG_BFIN_GPTIMERS=y +@@ -332,8 +304,8 @@ + CONFIG_BFIN_DCACHE=y + # CONFIG_BFIN_DCACHE_BANKA is not set + # CONFIG_BFIN_ICACHE_LOCK is not set +-CONFIG_BFIN_WB=y +-# CONFIG_BFIN_WT is not set ++# CONFIG_BFIN_WB is not set ++CONFIG_BFIN_WT=y + # CONFIG_MPU is not set + + # +@@ -362,6 +334,7 @@ + # + # Bus options (PCI, PCMCIA, EISA, MCA, ISA) + # ++# CONFIG_PCI is not set + # CONFIG_ARCH_SUPPORTS_MSI is not set + # CONFIG_PCCARD is not set + +@@ -372,20 +345,25 @@ + CONFIG_BINFMT_FLAT=y + CONFIG_BINFMT_ZFLAT=y + # CONFIG_BINFMT_SHARED_FLAT is not set +-# CONFIG_HAVE_AOUT is not set + # CONFIG_BINFMT_MISC is not set + + # + # Power management options + # + # CONFIG_PM is not set +-CONFIG_ARCH_SUSPEND_POSSIBLE=y ++CONFIG_SUSPEND_UP_POSSIBLE=y ++# CONFIG_PM_BFIN_SLEEP_DEEPER is not set ++# CONFIG_PM_BFIN_SLEEP is not set + # CONFIG_PM_WAKEUP_BY_GPIO is not set + + # + # CPU Frequency scaling + # + # CONFIG_CPU_FREQ is not set ++ ++# ++# Networking ++# + CONFIG_NET=y + + # +@@ -398,7 +376,6 @@ + # CONFIG_XFRM_USER is not set + # CONFIG_XFRM_SUB_POLICY is not set + # CONFIG_XFRM_MIGRATE is not set +-# CONFIG_XFRM_STATISTICS is not set + # CONFIG_NET_KEY is not set + CONFIG_INET=y + # CONFIG_IP_MULTICAST is not set +@@ -428,6 +405,8 @@ + CONFIG_DEFAULT_TCP_CONG="cubic" + # CONFIG_TCP_MD5SIG is not set + # CONFIG_IPV6 is not set ++# CONFIG_INET6_XFRM_TUNNEL is not set ++# CONFIG_INET6_TUNNEL is not set + # CONFIG_NETLABEL is not set + # CONFIG_NETWORK_SECMARK is not set + # CONFIG_NETFILTER is not set +@@ -436,7 +415,6 @@ + # CONFIG_TIPC is not set + # CONFIG_ATM is not set + # CONFIG_BRIDGE is not set +-# CONFIG_NET_DSA is not set + # CONFIG_VLAN_8021Q is not set + # CONFIG_DECNET is not set + # CONFIG_LLC2 is not set +@@ -453,14 +431,14 @@ + # + # CONFIG_NET_PKTGEN is not set + # CONFIG_HAMRADIO is not set +-# CONFIG_CAN is not set + # CONFIG_IRDA is not set + # CONFIG_BT is not set + # CONFIG_AF_RXRPC is not set +-# CONFIG_PHONET is not set +-CONFIG_WIRELESS=y ++ ++# ++# Wireless ++# + # CONFIG_CFG80211 is not set +-CONFIG_WIRELESS_OLD_REGULATORY=y + # CONFIG_WIRELESS_EXT is not set + # CONFIG_MAC80211 is not set + # CONFIG_IEEE80211 is not set +@@ -478,8 +456,6 @@ + CONFIG_STANDALONE=y + CONFIG_PREVENT_FIRMWARE_BUILD=y + # CONFIG_FW_LOADER is not set +-# CONFIG_DEBUG_DRIVER is not set +-# CONFIG_DEBUG_DEVRES is not set + # CONFIG_SYS_HYPERVISOR is not set + # CONFIG_CONNECTOR is not set + CONFIG_MTD=y +@@ -488,7 +464,6 @@ + CONFIG_MTD_PARTITIONS=y + # CONFIG_MTD_REDBOOT_PARTS is not set + # CONFIG_MTD_CMDLINE_PARTS is not set +-# CONFIG_MTD_AR7_PARTS is not set + + # + # User Modules And Translation Layers +@@ -532,7 +507,6 @@ + # + CONFIG_MTD_COMPLEX_MAPPINGS=y + # CONFIG_MTD_PHYSMAP is not set +-# CONFIG_MTD_GPIO_ADDR is not set + # CONFIG_MTD_UCLINUX is not set + # CONFIG_MTD_PLATRAM is not set + +@@ -568,12 +542,10 @@ + CONFIG_BLK_DEV_RAM=y + CONFIG_BLK_DEV_RAM_COUNT=16 + CONFIG_BLK_DEV_RAM_SIZE=4096 +-# CONFIG_BLK_DEV_XIP is not set ++CONFIG_BLK_DEV_RAM_BLOCKSIZE=1024 + # CONFIG_CDROM_PKTCDVD is not set + # CONFIG_ATA_OVER_ETH is not set +-# CONFIG_BLK_DEV_HD is not set + # CONFIG_MISC_DEVICES is not set +-CONFIG_HAVE_IDE=y + # CONFIG_IDE is not set + + # +@@ -586,6 +558,7 @@ + # CONFIG_ATA is not set + # CONFIG_MD is not set + CONFIG_NETDEVICES=y ++# CONFIG_NETDEVICES_MULTIQUEUE is not set + # CONFIG_DUMMY is not set + # CONFIG_BONDING is not set + # CONFIG_MACVLAN is not set +@@ -606,7 +579,6 @@ + # CONFIG_SMSC_PHY is not set + # CONFIG_BROADCOM_PHY is not set + # CONFIG_ICPLUS_PHY is not set +-# CONFIG_REALTEK_PHY is not set + # CONFIG_FIXED_PHY is not set + # CONFIG_MDIO_BITBANG is not set + CONFIG_NET_ETHERNET=y +@@ -619,14 +591,11 @@ + # CONFIG_SMC91X is not set + # CONFIG_SMSC911X is not set + # CONFIG_DM9000 is not set +-# CONFIG_ENC28J60 is not set + # CONFIG_IBM_NEW_EMAC_ZMII is not set + # CONFIG_IBM_NEW_EMAC_RGMII is not set + # CONFIG_IBM_NEW_EMAC_TAH is not set + # CONFIG_IBM_NEW_EMAC_EMAC4 is not set +-# CONFIG_IBM_NEW_EMAC_NO_FLOW_CTRL is not set +-# CONFIG_IBM_NEW_EMAC_MAL_CLR_ICINTSTAT is not set +-# CONFIG_IBM_NEW_EMAC_MAL_COMMON_ERR is not set ++# CONFIG_B44 is not set + # CONFIG_NETDEV_1000 is not set + # CONFIG_NETDEV_10000 is not set + +@@ -635,7 +604,6 @@ + # + # CONFIG_WLAN_PRE80211 is not set + # CONFIG_WLAN_80211 is not set +-# CONFIG_IWLWIFI_LEDS is not set + + # + # USB Network Adapters +@@ -648,6 +616,7 @@ + # CONFIG_WAN is not set + # CONFIG_PPP is not set + # CONFIG_SLIP is not set ++# CONFIG_SHAPER is not set + # CONFIG_NETCONSOLE is not set + # CONFIG_NETPOLL is not set + # CONFIG_NET_POLL_CONTROLLER is not set +@@ -673,15 +642,14 @@ + # CONFIG_BF5xx_PPIFCD is not set + # CONFIG_BFIN_SIMPLE_TIMER is not set + # CONFIG_BF5xx_PPI is not set +-# CONFIG_BF5xx_EPPI is not set ++CONFIG_BFIN_OTP=y ++# CONFIG_BFIN_OTP_WRITE_ENABLE is not set + # CONFIG_BFIN_SPORT is not set + # CONFIG_BFIN_TIMER_LATENCY is not set + # CONFIG_TWI_LCD is not set +-CONFIG_BFIN_DMA_INTERFACE=m + CONFIG_SIMPLE_GPIO=m + # CONFIG_VT is not set + # CONFIG_DEVKMEM is not set +-# CONFIG_BFIN_JTAG_COMM is not set + # CONFIG_SERIAL_NONSTANDARD is not set + + # +@@ -705,8 +673,6 @@ + # CONFIG_SERIAL_BFIN_SPORT is not set + CONFIG_UNIX98_PTYS=y + # CONFIG_LEGACY_PTYS is not set +-CONFIG_BFIN_OTP=y +-# CONFIG_BFIN_OTP_WRITE_ENABLE is not set + + # + # CAN, the car bus and industrial fieldbus +@@ -714,49 +680,44 @@ + # CONFIG_CAN4LINUX is not set + # CONFIG_IPMI_HANDLER is not set + # CONFIG_HW_RANDOM is not set ++# CONFIG_GEN_RTC is not set + # CONFIG_R3964 is not set + # CONFIG_RAW_DRIVER is not set + # CONFIG_TCG_TPM is not set + CONFIG_I2C=y + CONFIG_I2C_BOARDINFO=y + CONFIG_I2C_CHARDEV=m +-CONFIG_I2C_HELPER_AUTO=y + + # +-# I2C Hardware Bus support ++# I2C Algorithms + # ++# CONFIG_I2C_ALGOBIT is not set ++# CONFIG_I2C_ALGOPCF is not set ++# CONFIG_I2C_ALGOPCA is not set + + # +-# I2C system bus drivers (mostly embedded / system-on-chip) ++# I2C Hardware Bus support + # + CONFIG_I2C_BLACKFIN_TWI=m + CONFIG_I2C_BLACKFIN_TWI_CLK_KHZ=100 + # CONFIG_I2C_GPIO is not set + # CONFIG_I2C_OCORES is not set +-# CONFIG_I2C_SIMTEC is not set +- +-# +-# External I2C/SMBus adapter drivers +-# + # CONFIG_I2C_PARPORT_LIGHT is not set ++# CONFIG_I2C_SIMTEC is not set + # CONFIG_I2C_TAOS_EVM is not set +-# CONFIG_I2C_TINY_USB is not set +- +-# +-# Other I2C/SMBus bus drivers +-# +-# CONFIG_I2C_PCA_PLATFORM is not set + # CONFIG_I2C_STUB is not set ++# CONFIG_I2C_TINY_USB is not set + + # + # Miscellaneous I2C Chip support + # ++# CONFIG_SENSORS_DS1337 is not set ++# CONFIG_SENSORS_DS1374 is not set + # CONFIG_DS1682 is not set +-# CONFIG_AT24 is not set + # CONFIG_SENSORS_AD5252 is not set +-# CONFIG_SENSORS_EEPROM is not set ++# CONFIG_EEPROM_LEGACY is not set + # CONFIG_SENSORS_PCF8574 is not set +-# CONFIG_PCF8575 is not set ++# CONFIG_SENSORS_PCF8575 is not set + # CONFIG_SENSORS_PCA9539 is not set + # CONFIG_SENSORS_PCF8591 is not set + # CONFIG_SENSORS_MAX6875 is not set +@@ -765,41 +726,37 @@ + # CONFIG_I2C_DEBUG_ALGO is not set + # CONFIG_I2C_DEBUG_BUS is not set + # CONFIG_I2C_DEBUG_CHIP is not set ++ ++# ++# SPI support ++# + CONFIG_SPI=y +-# CONFIG_SPI_DEBUG is not set + CONFIG_SPI_MASTER=y + + # + # SPI Master Controller Drivers + # + CONFIG_SPI_BFIN=y +-# CONFIG_SPI_BFIN_LOCK is not set + # CONFIG_SPI_BITBANG is not set + + # + # SPI Protocol Masters + # +-# CONFIG_SPI_AT25 is not set ++# CONFIG_EEPROM_AT25 is not set + # CONFIG_SPI_SPIDEV is not set + # CONFIG_SPI_TLE62X0 is not set +-CONFIG_ARCH_WANT_OPTIONAL_GPIOLIB=y +-# CONFIG_GPIOLIB is not set + # CONFIG_W1 is not set + # CONFIG_POWER_SUPPLY is not set + CONFIG_HWMON=y + # CONFIG_HWMON_VID is not set +-# CONFIG_SENSORS_AD7414 is not set + # CONFIG_SENSORS_AD7418 is not set +-# CONFIG_SENSORS_ADCXX is not set + # CONFIG_SENSORS_ADM1021 is not set + # CONFIG_SENSORS_ADM1025 is not set + # CONFIG_SENSORS_ADM1026 is not set + # CONFIG_SENSORS_ADM1029 is not set + # CONFIG_SENSORS_ADM1031 is not set + # CONFIG_SENSORS_ADM9240 is not set +-# CONFIG_SENSORS_ADT7462 is not set + # CONFIG_SENSORS_ADT7470 is not set +-# CONFIG_SENSORS_ADT7473 is not set + # CONFIG_SENSORS_ATXP1 is not set + # CONFIG_SENSORS_DS1621 is not set + # CONFIG_SENSORS_F71805F is not set +@@ -820,7 +777,6 @@ + # CONFIG_SENSORS_LM90 is not set + # CONFIG_SENSORS_LM92 is not set + # CONFIG_SENSORS_LM93 is not set +-# CONFIG_SENSORS_MAX1111 is not set + # CONFIG_SENSORS_MAX1619 is not set + # CONFIG_SENSORS_MAX6650 is not set + # CONFIG_SENSORS_PC87360 is not set +@@ -829,7 +785,6 @@ + # CONFIG_SENSORS_SMSC47M1 is not set + # CONFIG_SENSORS_SMSC47M192 is not set + # CONFIG_SENSORS_SMSC47B397 is not set +-# CONFIG_SENSORS_ADS7828 is not set + # CONFIG_SENSORS_THMC50 is not set + # CONFIG_SENSORS_VT1211 is not set + # CONFIG_SENSORS_W83781D is not set +@@ -837,12 +792,9 @@ + # CONFIG_SENSORS_W83792D is not set + # CONFIG_SENSORS_W83793 is not set + # CONFIG_SENSORS_W83L785TS is not set +-# CONFIG_SENSORS_W83L786NG is not set + # CONFIG_SENSORS_W83627HF is not set + # CONFIG_SENSORS_W83627EHF is not set + # CONFIG_HWMON_DEBUG_CHIP is not set +-# CONFIG_THERMAL is not set +-# CONFIG_THERMAL_HWMON is not set + CONFIG_WATCHDOG=y + # CONFIG_WATCHDOG_NOWAYOUT is not set + +@@ -858,31 +810,21 @@ + # CONFIG_USBPCWATCHDOG is not set + + # +-# Multifunction device drivers ++# Sonics Silicon Backplane + # +-# CONFIG_MFD_CORE is not set +-# CONFIG_MFD_SM501 is not set +-# CONFIG_HTC_PASIC3 is not set +-# CONFIG_MFD_TMIO is not set +-# CONFIG_PMIC_DA903X is not set +-# CONFIG_MFD_WM8400 is not set +-# CONFIG_MFD_WM8350_I2C is not set +-# CONFIG_REGULATOR is not set ++CONFIG_SSB_POSSIBLE=y ++# CONFIG_SSB is not set + + # +-# Multimedia devices ++# Multifunction device drivers + # ++# CONFIG_MFD_SM501 is not set + + # +-# Multimedia core support ++# Multimedia devices + # + # CONFIG_VIDEO_DEV is not set + # CONFIG_DVB_CORE is not set +-# CONFIG_VIDEO_MEDIA is not set +- +-# +-# Multimedia drivers +-# + # CONFIG_DAB is not set + + # +@@ -897,6 +839,10 @@ + # Display device support + # + # CONFIG_DISPLAY_SUPPORT is not set ++ ++# ++# Sound ++# + # CONFIG_SOUND is not set + CONFIG_USB_SUPPORT=y + CONFIG_USB_ARCH_HAS_HCD=y +@@ -904,7 +850,6 @@ + # CONFIG_USB_ARCH_HAS_EHCI is not set + CONFIG_USB=y + # CONFIG_USB_DEBUG is not set +-# CONFIG_USB_ANNOUNCE_NEW_DEVICES is not set + + # + # Miscellaneous USB options +@@ -915,48 +860,40 @@ + # CONFIG_USB_OTG is not set + # CONFIG_USB_OTG_WHITELIST is not set + CONFIG_USB_OTG_BLACKLIST_HUB=y +-CONFIG_USB_MON=y +-# CONFIG_USB_WUSB is not set +-# CONFIG_USB_WUSB_CBAF is not set + + # + # USB Host Controller Drivers + # +-# CONFIG_USB_C67X00_HCD is not set + # CONFIG_USB_ISP116X_HCD is not set +-# CONFIG_USB_ISP1760_HCD is not set + # CONFIG_USB_ISP1362_HCD is not set ++# CONFIG_USB_ISP1760_HCD is not set + # CONFIG_USB_SL811_HCD is not set + # CONFIG_USB_R8A66597_HCD is not set +-# CONFIG_USB_HWA_HCD is not set + CONFIG_USB_MUSB_HDRC=y + CONFIG_USB_MUSB_SOC=y + + # +-# Blackfin high speed USB Support ++# Blackfin high speed USB support + # + CONFIG_USB_MUSB_HOST=y + # CONFIG_USB_MUSB_PERIPHERAL is not set + # CONFIG_USB_MUSB_OTG is not set + CONFIG_USB_MUSB_HDRC_HCD=y + CONFIG_MUSB_PIO_ONLY=y +-CONFIG_MUSB_DMA_POLL=y +-# CONFIG_USB_MUSB_DEBUG is not set ++CONFIG_USB_MUSB_LOGLEVEL=0 + + # + # USB Device Class drivers + # + # CONFIG_USB_ACM is not set + # CONFIG_USB_PRINTER is not set +-# CONFIG_USB_WDM is not set +-# CONFIG_USB_TMC is not set + + # +-# NOTE: USB_STORAGE depends on SCSI but BLK_DEV_SD may also be needed; ++# NOTE: USB_STORAGE enables SCSI, and 'SCSI disk support' + # + + # +-# see USB_STORAGE Help for more information ++# may also be needed; see USB_STORAGE Help for more information + # + # CONFIG_USB_LIBUSUAL is not set + +@@ -964,10 +901,15 @@ + # USB Imaging devices + # + # CONFIG_USB_MDC800 is not set ++CONFIG_USB_MON=y + + # + # USB port drivers + # ++ ++# ++# USB Serial Converter support ++# + # CONFIG_USB_SERIAL is not set + + # +@@ -976,7 +918,7 @@ + # CONFIG_USB_EMI62 is not set + # CONFIG_USB_EMI26 is not set + # CONFIG_USB_ADUTUX is not set +-# CONFIG_USB_SEVSEG is not set ++# CONFIG_USB_AUERSWALD is not set + # CONFIG_USB_RIO500 is not set + # CONFIG_USB_LEGOTOWER is not set + # CONFIG_USB_LCD is not set +@@ -992,13 +934,17 @@ + # CONFIG_USB_LD is not set + # CONFIG_USB_TRANCEVIBRATOR is not set + # CONFIG_USB_IOWARRIOR is not set +-# CONFIG_USB_ISIGHTFW is not set +-# CONFIG_USB_VST is not set ++ ++# ++# USB DSL modem support ++# ++ ++# ++# USB Gadget Support ++# + # CONFIG_USB_GADGET is not set + # CONFIG_MMC is not set +-# CONFIG_MEMSTICK is not set + # CONFIG_NEW_LEDS is not set +-# CONFIG_ACCESSIBILITY is not set + CONFIG_RTC_LIB=y + CONFIG_RTC_CLASS=y + CONFIG_RTC_HCTOSYS=y +@@ -1027,59 +973,51 @@ + # CONFIG_RTC_DRV_PCF8563 is not set + # CONFIG_RTC_DRV_PCF8583 is not set + # CONFIG_RTC_DRV_M41T80 is not set +-# CONFIG_RTC_DRV_S35390A is not set +-# CONFIG_RTC_DRV_FM3130 is not set +-# CONFIG_RTC_DRV_RX8581 is not set + + # + # SPI RTC drivers + # +-# CONFIG_RTC_DRV_M41T94 is not set +-# CONFIG_RTC_DRV_DS1305 is not set +-# CONFIG_RTC_DRV_DS1390 is not set +-# CONFIG_RTC_DRV_MAX6902 is not set +-# CONFIG_RTC_DRV_R9701 is not set + # CONFIG_RTC_DRV_RS5C348 is not set +-# CONFIG_RTC_DRV_DS3234 is not set ++# CONFIG_RTC_DRV_MAX6902 is not set + + # + # Platform RTC drivers + # +-# CONFIG_RTC_DRV_DS1286 is not set +-# CONFIG_RTC_DRV_DS1511 is not set + # CONFIG_RTC_DRV_DS1553 is not set +-# CONFIG_RTC_DRV_DS1742 is not set + # CONFIG_RTC_DRV_STK17TA8 is not set ++# CONFIG_RTC_DRV_DS1742 is not set + # CONFIG_RTC_DRV_M48T86 is not set +-# CONFIG_RTC_DRV_M48T35 is not set + # CONFIG_RTC_DRV_M48T59 is not set +-# CONFIG_RTC_DRV_BQ4802 is not set + # CONFIG_RTC_DRV_V3020 is not set + + # + # on-CPU RTC drivers + # + CONFIG_RTC_DRV_BFIN=y +-# CONFIG_DMADEVICES is not set ++ ++# ++# Userspace I/O ++# + # CONFIG_UIO is not set +-# CONFIG_STAGING is not set + + # + # File systems + # + # CONFIG_EXT2_FS is not set + # CONFIG_EXT3_FS is not set +-# CONFIG_EXT4_FS is not set ++# CONFIG_EXT4DEV_FS is not set + # CONFIG_REISERFS_FS is not set + # CONFIG_JFS_FS is not set + # CONFIG_FS_POSIX_ACL is not set +-CONFIG_FILE_LOCKING=y + # CONFIG_XFS_FS is not set ++# CONFIG_GFS2_FS is not set + # CONFIG_OCFS2_FS is not set +-# CONFIG_DNOTIFY is not set ++# CONFIG_MINIX_FS is not set ++# CONFIG_ROMFS_FS is not set + CONFIG_INOTIFY=y + CONFIG_INOTIFY_USER=y + # CONFIG_QUOTA is not set ++# CONFIG_DNOTIFY is not set + # CONFIG_AUTOFS_FS is not set + # CONFIG_AUTOFS4_FS is not set + # CONFIG_FUSE_FS is not set +@@ -1121,11 +1059,8 @@ + # CONFIG_JFFS2_FS is not set + # CONFIG_CRAMFS is not set + # CONFIG_VXFS_FS is not set +-# CONFIG_MINIX_FS is not set +-# CONFIG_OMFS_FS is not set + # CONFIG_HPFS_FS is not set + # CONFIG_QNX4FS_FS is not set +-# CONFIG_ROMFS_FS is not set + # CONFIG_SYSV_FS is not set + # CONFIG_UFS_FS is not set + CONFIG_NETWORK_FILESYSTEMS=y +@@ -1133,12 +1068,13 @@ + CONFIG_NFS_V3=y + # CONFIG_NFS_V3_ACL is not set + # CONFIG_NFS_V4 is not set ++# CONFIG_NFS_DIRECTIO is not set + # CONFIG_NFSD is not set + CONFIG_LOCKD=m + CONFIG_LOCKD_V4=y + CONFIG_NFS_COMMON=y + CONFIG_SUNRPC=m +-# CONFIG_SUNRPC_REGISTER_V4 is not set ++# CONFIG_SUNRPC_BIND34 is not set + # CONFIG_RPCSEC_GSS_KRB5 is not set + # CONFIG_RPCSEC_GSS_SPKM3 is not set + CONFIG_SMB_FS=m +@@ -1194,6 +1130,7 @@ + # CONFIG_NLS_KOI8_U is not set + # CONFIG_NLS_UTF8 is not set + # CONFIG_DLM is not set ++# CONFIG_INSTRUMENTATION is not set + + # + # Kernel hacking +@@ -1201,61 +1138,14 @@ + # CONFIG_PRINTK_TIME is not set + CONFIG_ENABLE_WARN_DEPRECATED=y + CONFIG_ENABLE_MUST_CHECK=y +-CONFIG_FRAME_WARN=1024 + # CONFIG_MAGIC_SYSRQ is not set + # CONFIG_UNUSED_SYMBOLS is not set + CONFIG_DEBUG_FS=y + # CONFIG_HEADERS_CHECK is not set +-CONFIG_DEBUG_KERNEL=y +-# CONFIG_DEBUG_SHIRQ is not set +-CONFIG_DETECT_SOFTLOCKUP=y +-# CONFIG_BOOTPARAM_SOFTLOCKUP_PANIC is not set +-CONFIG_BOOTPARAM_SOFTLOCKUP_PANIC_VALUE=0 +-# CONFIG_SCHED_DEBUG is not set +-# CONFIG_SCHEDSTATS is not set +-# CONFIG_TIMER_STATS is not set +-# CONFIG_DEBUG_OBJECTS is not set +-# CONFIG_DEBUG_SLAB is not set +-# CONFIG_DEBUG_RT_MUTEXES is not set +-# CONFIG_RT_MUTEX_TESTER is not set +-# CONFIG_DEBUG_SPINLOCK is not set +-# CONFIG_DEBUG_MUTEXES is not set +-# CONFIG_DEBUG_SPINLOCK_SLEEP is not set +-# CONFIG_DEBUG_LOCKING_API_SELFTESTS is not set +-# CONFIG_DEBUG_KOBJECT is not set ++# CONFIG_DEBUG_KERNEL is not set + # CONFIG_DEBUG_BUGVERBOSE is not set +-# CONFIG_DEBUG_INFO is not set +-# CONFIG_DEBUG_VM is not set +-# CONFIG_DEBUG_WRITECOUNT is not set +-# CONFIG_DEBUG_MEMORY_INIT is not set +-# CONFIG_DEBUG_LIST is not set +-# CONFIG_DEBUG_SG is not set +-# CONFIG_FRAME_POINTER is not set +-# CONFIG_BOOT_PRINTK_DELAY is not set +-# CONFIG_RCU_TORTURE_TEST is not set +-# CONFIG_RCU_CPU_STALL_DETECTOR is not set +-# CONFIG_BACKTRACE_SELF_TEST is not set +-# CONFIG_DEBUG_BLOCK_EXT_DEVT is not set +-# CONFIG_FAULT_INJECTION is not set +-# CONFIG_SYSCTL_SYSCALL_CHECK is not set +- +-# +-# Tracers +-# +-# CONFIG_SCHED_TRACER is not set +-# CONFIG_CONTEXT_SWITCH_TRACER is not set +-# CONFIG_BOOT_TRACER is not set +-# CONFIG_DYNAMIC_PRINTK_DEBUG is not set + # CONFIG_SAMPLES is not set +-CONFIG_HAVE_ARCH_KGDB=y +-# CONFIG_KGDB is not set +-# CONFIG_DEBUG_STACKOVERFLOW is not set +-# CONFIG_DEBUG_STACK_USAGE is not set +-# CONFIG_KGDB_TESTCASE is not set +-CONFIG_DEBUG_VERBOSE=y + CONFIG_DEBUG_MMRS=y +-# CONFIG_DEBUG_HWERR is not set +-# CONFIG_DEBUG_DOUBLEFAULT is not set + CONFIG_DEBUG_HUNT_FOR_ZERO=y + CONFIG_DEBUG_BFIN_HWTRACE_ON=y + CONFIG_DEBUG_BFIN_HWTRACE_COMPRESSION_OFF=y +@@ -1264,7 +1154,7 @@ + CONFIG_DEBUG_BFIN_HWTRACE_COMPRESSION=0 + # CONFIG_DEBUG_BFIN_HWTRACE_EXPAND is not set + # CONFIG_DEBUG_BFIN_NO_KERN_HWTRACE is not set +-# CONFIG_EARLY_PRINTK is not set ++CONFIG_EARLY_PRINTK=y + # CONFIG_CPLB_INFO is not set + CONFIG_ACCESS_CHECK=y + +@@ -1273,96 +1163,10 @@ + # + # CONFIG_KEYS is not set + CONFIG_SECURITY=y +-# CONFIG_SECURITYFS is not set + # CONFIG_SECURITY_NETWORK is not set +-# CONFIG_SECURITY_FILE_CAPABILITIES is not set ++# CONFIG_SECURITY_CAPABILITIES is not set + # CONFIG_SECURITY_ROOTPLUG is not set +-CONFIG_SECURITY_DEFAULT_MMAP_MIN_ADDR=0 +-CONFIG_CRYPTO=y +- +-# +-# Crypto core or helper +-# +-# CONFIG_CRYPTO_FIPS is not set +-# CONFIG_CRYPTO_MANAGER is not set +-# CONFIG_CRYPTO_MANAGER2 is not set +-# CONFIG_CRYPTO_GF128MUL is not set +-# CONFIG_CRYPTO_NULL is not set +-# CONFIG_CRYPTO_CRYPTD is not set +-# CONFIG_CRYPTO_AUTHENC is not set +-# CONFIG_CRYPTO_TEST is not set +- +-# +-# Authenticated Encryption with Associated Data +-# +-# CONFIG_CRYPTO_CCM is not set +-# CONFIG_CRYPTO_GCM is not set +-# CONFIG_CRYPTO_SEQIV is not set +- +-# +-# Block modes +-# +-# CONFIG_CRYPTO_CBC is not set +-# CONFIG_CRYPTO_CTR is not set +-# CONFIG_CRYPTO_CTS is not set +-# CONFIG_CRYPTO_ECB is not set +-# CONFIG_CRYPTO_LRW is not set +-# CONFIG_CRYPTO_PCBC is not set +-# CONFIG_CRYPTO_XTS is not set +- +-# +-# Hash modes +-# +-# CONFIG_CRYPTO_HMAC is not set +-# CONFIG_CRYPTO_XCBC is not set +- +-# +-# Digest +-# +-# CONFIG_CRYPTO_CRC32C is not set +-# CONFIG_CRYPTO_MD4 is not set +-# CONFIG_CRYPTO_MD5 is not set +-# CONFIG_CRYPTO_MICHAEL_MIC is not set +-# CONFIG_CRYPTO_RMD128 is not set +-# CONFIG_CRYPTO_RMD160 is not set +-# CONFIG_CRYPTO_RMD256 is not set +-# CONFIG_CRYPTO_RMD320 is not set +-# CONFIG_CRYPTO_SHA1 is not set +-# CONFIG_CRYPTO_SHA256 is not set +-# CONFIG_CRYPTO_SHA512 is not set +-# CONFIG_CRYPTO_TGR192 is not set +-# CONFIG_CRYPTO_WP512 is not set +- +-# +-# Ciphers +-# +-# CONFIG_CRYPTO_AES is not set +-# CONFIG_CRYPTO_ANUBIS is not set +-# CONFIG_CRYPTO_ARC4 is not set +-# CONFIG_CRYPTO_BLOWFISH is not set +-# CONFIG_CRYPTO_CAMELLIA is not set +-# CONFIG_CRYPTO_CAST5 is not set +-# CONFIG_CRYPTO_CAST6 is not set +-# CONFIG_CRYPTO_DES is not set +-# CONFIG_CRYPTO_FCRYPT is not set +-# CONFIG_CRYPTO_KHAZAD is not set +-# CONFIG_CRYPTO_SALSA20 is not set +-# CONFIG_CRYPTO_SEED is not set +-# CONFIG_CRYPTO_SERPENT is not set +-# CONFIG_CRYPTO_TEA is not set +-# CONFIG_CRYPTO_TWOFISH is not set +- +-# +-# Compression +-# +-# CONFIG_CRYPTO_DEFLATE is not set +-# CONFIG_CRYPTO_LZO is not set +- +-# +-# Random Number Generation +-# +-# CONFIG_CRYPTO_ANSI_CPRNG is not set +-CONFIG_CRYPTO_HW=y ++# CONFIG_CRYPTO is not set + + # + # Library routines +@@ -1370,7 +1174,6 @@ + CONFIG_BITREVERSE=y + CONFIG_CRC_CCITT=m + # CONFIG_CRC16 is not set +-# CONFIG_CRC_T10DIF is not set + # CONFIG_CRC_ITU_T is not set + CONFIG_CRC32=y + # CONFIG_CRC7 is not set +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/arch/blackfin/configs/CM-BF548_defconfig linux-2.6.29-rc3.owrt/arch/blackfin/configs/CM-BF548_defconfig +--- linux-2.6.29.owrt/arch/blackfin/configs/CM-BF548_defconfig 2009-05-10 22:04:41.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/arch/blackfin/configs/CM-BF548_defconfig 2009-05-10 23:48:28.000000000 +0200 +@@ -336,8 +336,8 @@ + CONFIG_BFIN_DCACHE=y + # CONFIG_BFIN_DCACHE_BANKA is not set + # CONFIG_BFIN_ICACHE_LOCK is not set +-CONFIG_BFIN_WB=y +-# CONFIG_BFIN_WT is not set ++# CONFIG_BFIN_WB is not set ++CONFIG_BFIN_WT=y + CONFIG_L1_MAX_PIECE=16 + # CONFIG_MPU is not set + +@@ -595,7 +595,7 @@ + CONFIG_SCSI_DMA=y + # CONFIG_SCSI_TGT is not set + # CONFIG_SCSI_NETLINK is not set +-# CONFIG_SCSI_PROC_FS is not set ++CONFIG_SCSI_PROC_FS=y + + # + # SCSI support type (disk, tape, CD-ROM) +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/arch/blackfin/configs/IP0X_defconfig linux-2.6.29-rc3.owrt/arch/blackfin/configs/IP0X_defconfig +--- linux-2.6.29.owrt/arch/blackfin/configs/IP0X_defconfig 2009-05-10 22:04:41.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/arch/blackfin/configs/IP0X_defconfig 2009-05-10 23:48:28.000000000 +0200 +@@ -612,7 +612,7 @@ + CONFIG_SCSI=y + # CONFIG_SCSI_TGT is not set + # CONFIG_SCSI_NETLINK is not set +-# CONFIG_SCSI_PROC_FS is not set ++CONFIG_SCSI_PROC_FS=y + + # + # SCSI support type (disk, tape, CD-ROM) +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/arch/blackfin/configs/SRV1_defconfig linux-2.6.29-rc3.owrt/arch/blackfin/configs/SRV1_defconfig +--- linux-2.6.29.owrt/arch/blackfin/configs/SRV1_defconfig 2009-05-10 22:04:41.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/arch/blackfin/configs/SRV1_defconfig 2009-05-10 23:48:28.000000000 +0200 +@@ -282,8 +282,8 @@ + CONFIG_BFIN_DCACHE=y + # CONFIG_BFIN_DCACHE_BANKA is not set + # CONFIG_BFIN_ICACHE_LOCK is not set +-CONFIG_BFIN_WB=y +-# CONFIG_BFIN_WT is not set ++# CONFIG_BFIN_WB is not set ++CONFIG_BFIN_WT=y + CONFIG_L1_MAX_PIECE=16 + + # +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/arch/blackfin/include/asm/bfin_sport.h linux-2.6.29-rc3.owrt/arch/blackfin/include/asm/bfin_sport.h +--- linux-2.6.29.owrt/arch/blackfin/include/asm/bfin_sport.h 2009-05-10 22:04:40.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/arch/blackfin/include/asm/bfin_sport.h 2009-05-10 23:48:28.000000000 +0200 +@@ -1,9 +1,30 @@ + /* +- * bfin_sport.h - userspace header for bfin sport driver ++ * File: include/asm-blackfin/bfin_sport.h ++ * Based on: ++ * Author: Roy Huang (roy.huang@analog.com) + * +- * Copyright 2004-2008 Analog Devices Inc. ++ * Created: Thu Aug. 24 2006 ++ * Description: + * +- * Licensed under the GPL-2 or later. ++ * Modified: ++ * Copyright 2004-2006 Analog Devices Inc. ++ * ++ * Bugs: Enter bugs at http://blackfin.uclinux.org/ ++ * ++ * 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, see the file COPYING, or write ++ * to the Free Software Foundation, Inc., ++ * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + */ + + #ifndef __BFIN_SPORT_H__ +@@ -21,10 +42,11 @@ + #define NORM_FORMAT 0x0 + #define ALAW_FORMAT 0x2 + #define ULAW_FORMAT 0x3 ++struct sport_register; + + /* Function driver which use sport must initialize the structure */ + struct sport_config { +- /* TDM (multichannels), I2S or other mode */ ++ /*TDM (multichannels), I2S or other mode */ + unsigned int mode:3; + + /* if TDM mode is selected, channels must be set */ +@@ -50,18 +72,12 @@ + int serial_clk; + int fsync_clk; + +- unsigned int data_format:2; /* Normal, u-law or a-law */ ++ unsigned int data_format:2; /*Normal, u-law or a-law */ + + int word_len; /* How length of the word in bits, 3-32 bits */ + int dma_enabled; + }; + +-/* Userspace interface */ +-#define SPORT_IOC_MAGIC 'P' +-#define SPORT_IOC_CONFIG _IOWR('P', 0x01, struct sport_config) +- +-#ifdef __KERNEL__ +- + struct sport_register { + unsigned short tcr1; + unsigned short reserved0; +@@ -101,6 +117,9 @@ + unsigned long mrcs3; + }; + ++#define SPORT_IOC_MAGIC 'P' ++#define SPORT_IOC_CONFIG _IOWR('P', 0x01, struct sport_config) ++ + struct sport_dev { + struct cdev cdev; /* Char device structure */ + +@@ -130,8 +149,6 @@ + struct sport_config config; + }; + +-#endif +- + #define SPORT_TCR1 0 + #define SPORT_TCR2 1 + #define SPORT_TCLKDIV 2 +@@ -152,4 +169,4 @@ + #define SPORT_MRCS2 22 + #define SPORT_MRCS3 23 + +-#endif ++#endif /*__BFIN_SPORT_H__*/ +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/arch/blackfin/include/asm/checksum.h linux-2.6.29-rc3.owrt/arch/blackfin/include/asm/checksum.h +--- linux-2.6.29.owrt/arch/blackfin/include/asm/checksum.h 2009-05-10 22:04:40.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/arch/blackfin/include/asm/checksum.h 2009-05-10 23:48:28.000000000 +0200 +@@ -63,23 +63,23 @@ + csum_tcpudp_nofold(__be32 saddr, __be32 daddr, unsigned short len, + unsigned short proto, __wsum sum) + { +- unsigned int carry; + +- __asm__ ("%0 = %0 + %2;\n\t" +- "CC = AC0;\n\t" +- "%1 = CC;\n\t" +- "%0 = %0 + %1;\n\t" +- "%0 = %0 + %3;\n\t" +- "CC = AC0;\n\t" +- "%1 = CC;\n\t" +- "%0 = %0 + %1;\n\t" +- "%0 = %0 + %4;\n\t" +- "CC = AC0;\n\t" +- "%1 = CC;\n\t" +- "%0 = %0 + %1;\n\t" +- : "=d" (sum), "=&d" (carry) +- : "d" (daddr), "d" (saddr), "d" ((len + proto) << 8), "0"(sum) +- : "CC"); ++ __asm__ ("%0 = %0 + %1;\n\t" ++ "CC = AC0;\n\t" ++ "if !CC jump 4;\n\t" ++ "%0 = %0 + %4;\n\t" ++ "%0 = %0 + %2;\n\t" ++ "CC = AC0;\n\t" ++ "if !CC jump 4;\n\t" ++ "%0 = %0 + %4;\n\t" ++ "%0 = %0 + %3;\n\t" ++ "CC = AC0;\n\t" ++ "if !CC jump 4;\n\t" ++ "%0 = %0 + %4;\n\t" ++ "NOP;\n\t" ++ : "=d" (sum) ++ : "d" (daddr), "d" (saddr), "d" ((ntohs(len)<<16)+proto*256), "d" (1), "0"(sum) ++ : "CC"); + + return (sum); + } +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/arch/blackfin/include/asm/delay.h linux-2.6.29-rc3.owrt/arch/blackfin/include/asm/delay.h +--- linux-2.6.29.owrt/arch/blackfin/include/asm/delay.h 2009-05-10 22:04:40.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/arch/blackfin/include/asm/delay.h 2009-05-10 23:48:28.000000000 +0200 +@@ -13,7 +13,29 @@ + + static inline void __delay(unsigned long loops) + { +-__asm__ __volatile__ ( ++ if (ANOMALY_05000312) { ++ /* Interrupted loads to loop registers -> bad */ ++ unsigned long tmp; ++ __asm__ __volatile__( ++ "[--SP] = LC0;" ++ "[--SP] = LT0;" ++ "[--SP] = LB0;" ++ "LSETUP (1f,1f) LC0 = %1;" ++ "1: NOP;" ++ /* We take advantage of the fact that LC0 is 0 at ++ * the end of the loop. Otherwise we'd need some ++ * NOPs after the CLI here. ++ */ ++ "CLI %0;" ++ "LB0 = [SP++];" ++ "LT0 = [SP++];" ++ "LC0 = [SP++];" ++ "STI %0;" ++ : "=d" (tmp) ++ : "a" (loops) ++ ); ++ } else ++ __asm__ __volatile__ ( + "LSETUP(1f, 1f) LC0 = %0;" + "1: NOP;" + : +@@ -25,15 +47,16 @@ + #include <linux/param.h> /* needed for HZ */ + + /* +- * close approximation borrowed from m68knommu to avoid 64-bit math ++ * Use only for very small delays ( < 1 msec). Should probably use a ++ * lookup table, really, as the multiplications take much too long with ++ * short delays. This is a "reasonable" implementation, though (and the ++ * first constant multiplications gets optimized away if the delay is ++ * a constant) + */ +- +-#define HZSCALE (268435456 / (1000000/HZ)) +- + static inline void udelay(unsigned long usecs) + { + extern unsigned long loops_per_jiffy; +- __delay((((usecs * HZSCALE) >> 11) * (loops_per_jiffy >> 11)) >> 6); ++ __delay(usecs * loops_per_jiffy / (1000000 / HZ)); + } + + #endif +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/arch/blackfin/include/asm/gpio.h linux-2.6.29-rc3.owrt/arch/blackfin/include/asm/gpio.h +--- linux-2.6.29.owrt/arch/blackfin/include/asm/gpio.h 2009-05-10 22:04:40.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/arch/blackfin/include/asm/gpio.h 2009-05-10 23:48:28.000000000 +0200 +@@ -27,6 +27,60 @@ + * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + */ + ++/* ++* Number BF537/6/4 BF561 BF533/2/1 ++* BF527/5/2 ++* ++* GPIO_0 PF0 PF0 PF0 ++* GPIO_1 PF1 PF1 PF1 ++* GPIO_2 PF2 PF2 PF2 ++* GPIO_3 PF3 PF3 PF3 ++* GPIO_4 PF4 PF4 PF4 ++* GPIO_5 PF5 PF5 PF5 ++* GPIO_6 PF6 PF6 PF6 ++* GPIO_7 PF7 PF7 PF7 ++* GPIO_8 PF8 PF8 PF8 ++* GPIO_9 PF9 PF9 PF9 ++* GPIO_10 PF10 PF10 PF10 ++* GPIO_11 PF11 PF11 PF11 ++* GPIO_12 PF12 PF12 PF12 ++* GPIO_13 PF13 PF13 PF13 ++* GPIO_14 PF14 PF14 PF14 ++* GPIO_15 PF15 PF15 PF15 ++* GPIO_16 PG0 PF16 ++* GPIO_17 PG1 PF17 ++* GPIO_18 PG2 PF18 ++* GPIO_19 PG3 PF19 ++* GPIO_20 PG4 PF20 ++* GPIO_21 PG5 PF21 ++* GPIO_22 PG6 PF22 ++* GPIO_23 PG7 PF23 ++* GPIO_24 PG8 PF24 ++* GPIO_25 PG9 PF25 ++* GPIO_26 PG10 PF26 ++* GPIO_27 PG11 PF27 ++* GPIO_28 PG12 PF28 ++* GPIO_29 PG13 PF29 ++* GPIO_30 PG14 PF30 ++* GPIO_31 PG15 PF31 ++* GPIO_32 PH0 PF32 ++* GPIO_33 PH1 PF33 ++* GPIO_34 PH2 PF34 ++* GPIO_35 PH3 PF35 ++* GPIO_36 PH4 PF36 ++* GPIO_37 PH5 PF37 ++* GPIO_38 PH6 PF38 ++* GPIO_39 PH7 PF39 ++* GPIO_40 PH8 PF40 ++* GPIO_41 PH9 PF41 ++* GPIO_42 PH10 PF42 ++* GPIO_43 PH11 PF43 ++* GPIO_44 PH12 PF44 ++* GPIO_45 PH13 PF45 ++* GPIO_46 PH14 PF46 ++* GPIO_47 PH15 PF47 ++*/ ++ + #ifndef __ARCH_BLACKFIN_GPIO_H__ + #define __ARCH_BLACKFIN_GPIO_H__ + +@@ -241,6 +295,10 @@ + int bfin_gpio_get_value(unsigned gpio); + void bfin_gpio_set_value(unsigned gpio, int value); + ++#ifndef BF548_FAMILY ++#define bfin_gpio_set_value(gpio, value) set_gpio_data(gpio, value) ++#endif ++ + #ifdef CONFIG_GPIOLIB + #include <asm-generic/gpio.h> /* cansleep wrappers */ + +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/arch/blackfin/include/asm/ipipe_base.h linux-2.6.29-rc3.owrt/arch/blackfin/include/asm/ipipe_base.h +--- linux-2.6.29.owrt/arch/blackfin/include/asm/ipipe_base.h 2009-05-10 22:04:40.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/arch/blackfin/include/asm/ipipe_base.h 2009-05-10 23:48:28.000000000 +0200 +@@ -1,5 +1,5 @@ + /* -*- linux-c -*- +- * include/asm-blackfin/ipipe_base.h ++ * include/asm-blackfin/_baseipipe.h + * + * Copyright (C) 2007 Philippe Gerum. + * +@@ -27,9 +27,8 @@ + #define IPIPE_NR_XIRQS NR_IRQS + #define IPIPE_IRQ_ISHIFT 5 /* 2^5 for 32bits arch. */ + +-/* Blackfin-specific, per-cpu pipeline status */ +-#define IPIPE_SYNCDEFER_FLAG 15 +-#define IPIPE_SYNCDEFER_MASK (1L << IPIPE_SYNCDEFER_MASK) ++/* Blackfin-specific, global domain flags */ ++#define IPIPE_ROOTLOCK_FLAG 1 /* Lock pipeline for root */ + + /* Blackfin traps -- i.e. exception vector numbers */ + #define IPIPE_NR_FAULTS 52 /* We leave a gap after VEC_ILL_RES. */ +@@ -49,6 +48,11 @@ + + #ifndef __ASSEMBLY__ + ++#include <linux/bitops.h> ++ ++extern int test_bit(int nr, const void *addr); ++ ++ + extern unsigned long __ipipe_root_status; /* Alias to ipipe_root_cpudom_var(status) */ + + static inline void __ipipe_stall_root(void) +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/arch/blackfin/include/asm/ipipe.h linux-2.6.29-rc3.owrt/arch/blackfin/include/asm/ipipe.h +--- linux-2.6.29.owrt/arch/blackfin/include/asm/ipipe.h 2009-05-10 22:04:40.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/arch/blackfin/include/asm/ipipe.h 2009-05-10 23:48:28.000000000 +0200 +@@ -35,9 +35,9 @@ + #include <asm/atomic.h> + #include <asm/traps.h> + +-#define IPIPE_ARCH_STRING "1.9-00" ++#define IPIPE_ARCH_STRING "1.8-00" + #define IPIPE_MAJOR_NUMBER 1 +-#define IPIPE_MINOR_NUMBER 9 ++#define IPIPE_MINOR_NUMBER 8 + #define IPIPE_PATCH_NUMBER 0 + + #ifdef CONFIG_SMP +@@ -83,9 +83,9 @@ + "%2 = CYCLES2\n" \ + "CC = %2 == %0\n" \ + "if ! CC jump 1b\n" \ +- : "=d,a" (((unsigned long *)&t)[1]), \ +- "=d,a" (((unsigned long *)&t)[0]), \ +- "=d,a" (__cy2) \ ++ : "=r" (((unsigned long *)&t)[1]), \ ++ "=r" (((unsigned long *)&t)[0]), \ ++ "=r" (__cy2) \ + : /*no input*/ : "CC"); \ + t; \ + }) +@@ -118,40 +118,35 @@ + + #define __ipipe_disable_irq(irq) (irq_desc[irq].chip->mask(irq)) + +-static inline int __ipipe_check_tickdev(const char *devname) +-{ +- return 1; +-} ++#define __ipipe_lock_root() \ ++ set_bit(IPIPE_ROOTLOCK_FLAG, &ipipe_root_domain->flags) + +-static inline void __ipipe_lock_root(void) +-{ +- set_bit(IPIPE_SYNCDEFER_FLAG, &ipipe_root_cpudom_var(status)); +-} +- +-static inline void __ipipe_unlock_root(void) +-{ +- clear_bit(IPIPE_SYNCDEFER_FLAG, &ipipe_root_cpudom_var(status)); +-} ++#define __ipipe_unlock_root() \ ++ clear_bit(IPIPE_ROOTLOCK_FLAG, &ipipe_root_domain->flags) + + void __ipipe_enable_pipeline(void); + + #define __ipipe_hook_critical_ipi(ipd) do { } while (0) + +-#define __ipipe_sync_pipeline ___ipipe_sync_pipeline +-void ___ipipe_sync_pipeline(unsigned long syncmask); ++#define __ipipe_sync_pipeline(syncmask) \ ++ do { \ ++ struct ipipe_domain *ipd = ipipe_current_domain; \ ++ if (likely(ipd != ipipe_root_domain || !test_bit(IPIPE_ROOTLOCK_FLAG, &ipd->flags))) \ ++ __ipipe_sync_stage(syncmask); \ ++ } while (0) + + void __ipipe_handle_irq(unsigned irq, struct pt_regs *regs); + + int __ipipe_get_irq_priority(unsigned irq); + ++int __ipipe_get_irqthread_priority(unsigned irq); ++ + void __ipipe_stall_root_raw(void); + + void __ipipe_unstall_root_raw(void); + + void __ipipe_serial_debug(const char *fmt, ...); + +-asmlinkage void __ipipe_call_irqtail(unsigned long addr); +- + DECLARE_PER_CPU(struct pt_regs, __ipipe_tick_regs); + + extern unsigned long __ipipe_core_clock; +@@ -167,25 +162,42 @@ + + #define __ipipe_run_irqtail() /* Must be a macro */ \ + do { \ ++ asmlinkage void __ipipe_call_irqtail(void); \ + unsigned long __pending; \ +- CSYNC(); \ ++ CSYNC(); \ + __pending = bfin_read_IPEND(); \ + if (__pending & 0x8000) { \ + __pending &= ~0x8010; \ + if (__pending && (__pending & (__pending - 1)) == 0) \ +- __ipipe_call_irqtail(__ipipe_irq_tail_hook); \ ++ __ipipe_call_irqtail(); \ + } \ + } while (0) + + #define __ipipe_run_isr(ipd, irq) \ + do { \ + if (ipd == ipipe_root_domain) { \ +- local_irq_enable_hw(); \ +- if (ipipe_virtual_irq_p(irq)) \ ++ /* \ ++ * Note: the I-pipe implements a threaded interrupt model on \ ++ * this arch for Linux external IRQs. The interrupt handler we \ ++ * call here only wakes up the associated IRQ thread. \ ++ */ \ ++ if (ipipe_virtual_irq_p(irq)) { \ ++ /* No irqtail here; virtual interrupts have no effect \ ++ on IPEND so there is no need for processing \ ++ deferral. */ \ ++ local_irq_enable_nohead(ipd); \ + ipd->irqs[irq].handler(irq, ipd->irqs[irq].cookie); \ +- else \ ++ local_irq_disable_nohead(ipd); \ ++ } else \ ++ /* \ ++ * No need to run the irqtail here either; \ ++ * we can't be preempted by hw IRQs, so \ ++ * non-Linux IRQs cannot stack over the short \ ++ * thread wakeup code. Which in turn means \ ++ * that no irqtail condition could be pending \ ++ * for domains above Linux in the pipeline. \ ++ */ \ + ipd->irqs[irq].handler(irq, &__raw_get_cpu_var(__ipipe_tick_regs)); \ +- local_irq_disable_hw(); \ + } else { \ + __clear_bit(IPIPE_SYNC_FLAG, &ipipe_cpudom_var(ipd, status)); \ + local_irq_enable_nohead(ipd); \ +@@ -205,24 +217,42 @@ + + int ipipe_start_irq_thread(unsigned irq, struct irq_desc *desc); + +-#ifdef CONFIG_GENERIC_CLOCKEVENTS +-#define IRQ_SYSTMR IRQ_CORETMR +-#define IRQ_PRIOTMR IRQ_CORETMR +-#else ++#define IS_SYSIRQ(irq) ((irq) > IRQ_CORETMR && (irq) <= SYS_IRQS) ++#define IS_GPIOIRQ(irq) ((irq) >= GPIO_IRQ_BASE && (irq) < NR_IRQS) ++ + #define IRQ_SYSTMR IRQ_TIMER0 + #define IRQ_PRIOTMR CONFIG_IRQ_TIMER0 +-#endif + +-#ifdef CONFIG_BF561 ++#if defined(CONFIG_BF531) || defined(CONFIG_BF532) || defined(CONFIG_BF533) ++#define PRIO_GPIODEMUX(irq) CONFIG_PFA ++#elif defined(CONFIG_BF534) || defined(CONFIG_BF536) || defined(CONFIG_BF537) ++#define PRIO_GPIODEMUX(irq) CONFIG_IRQ_PROG_INTA ++#elif defined(CONFIG_BF52x) ++#define PRIO_GPIODEMUX(irq) ((irq) == IRQ_PORTF_INTA ? CONFIG_IRQ_PORTF_INTA : \ ++ (irq) == IRQ_PORTG_INTA ? CONFIG_IRQ_PORTG_INTA : \ ++ (irq) == IRQ_PORTH_INTA ? CONFIG_IRQ_PORTH_INTA : \ ++ -1) ++#elif defined(CONFIG_BF561) ++#define PRIO_GPIODEMUX(irq) ((irq) == IRQ_PROG0_INTA ? CONFIG_IRQ_PROG0_INTA : \ ++ (irq) == IRQ_PROG1_INTA ? CONFIG_IRQ_PROG1_INTA : \ ++ (irq) == IRQ_PROG2_INTA ? CONFIG_IRQ_PROG2_INTA : \ ++ -1) + #define bfin_write_TIMER_DISABLE(val) bfin_write_TMRS8_DISABLE(val) + #define bfin_write_TIMER_ENABLE(val) bfin_write_TMRS8_ENABLE(val) + #define bfin_write_TIMER_STATUS(val) bfin_write_TMRS8_STATUS(val) + #define bfin_read_TIMER_STATUS() bfin_read_TMRS8_STATUS() + #elif defined(CONFIG_BF54x) ++#define PRIO_GPIODEMUX(irq) ((irq) == IRQ_PINT0 ? CONFIG_IRQ_PINT0 : \ ++ (irq) == IRQ_PINT1 ? CONFIG_IRQ_PINT1 : \ ++ (irq) == IRQ_PINT2 ? CONFIG_IRQ_PINT2 : \ ++ (irq) == IRQ_PINT3 ? CONFIG_IRQ_PINT3 : \ ++ -1) + #define bfin_write_TIMER_DISABLE(val) bfin_write_TIMER_DISABLE0(val) + #define bfin_write_TIMER_ENABLE(val) bfin_write_TIMER_ENABLE0(val) + #define bfin_write_TIMER_STATUS(val) bfin_write_TIMER_STATUS0(val) + #define bfin_read_TIMER_STATUS(val) bfin_read_TIMER_STATUS0(val) ++#else ++# error "no PRIO_GPIODEMUX() for this part" + #endif + + #define __ipipe_root_tick_p(regs) ((regs->ipend & 0x10) != 0) +@@ -245,6 +275,4 @@ + + #endif /* !CONFIG_IPIPE */ + +-#define ipipe_update_tick_evtdev(evtdev) do { } while (0) +- + #endif /* !__ASM_BLACKFIN_IPIPE_H */ +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/arch/blackfin/include/asm/irq.h linux-2.6.29-rc3.owrt/arch/blackfin/include/asm/irq.h +--- linux-2.6.29.owrt/arch/blackfin/include/asm/irq.h 2009-05-10 22:04:40.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/arch/blackfin/include/asm/irq.h 2009-05-10 23:48:28.000000000 +0200 +@@ -61,38 +61,20 @@ + #define raw_irqs_disabled_flags(flags) (!irqs_enabled_from_flags_hw(flags)) + #define local_test_iflag_hw(x) irqs_enabled_from_flags_hw(x) + +-#define local_save_flags(x) \ +- do { \ +- (x) = __ipipe_test_root() ? \ +- __all_masked_irq_flags : bfin_irq_flags; \ +- barrier(); \ +- } while (0) +- +-#define local_irq_save(x) \ +- do { \ +- (x) = __ipipe_test_and_stall_root() ? \ ++#define local_save_flags(x) \ ++ do { \ ++ (x) = __ipipe_test_root() ? \ + __all_masked_irq_flags : bfin_irq_flags; \ +- barrier(); \ + } while (0) + +-static inline void local_irq_restore(unsigned long x) +-{ +- barrier(); +- __ipipe_restore_root(x == __all_masked_irq_flags); +-} +- +-#define local_irq_disable() \ +- do { \ +- __ipipe_stall_root(); \ +- barrier(); \ ++#define local_irq_save(x) \ ++ do { \ ++ (x) = __ipipe_test_and_stall_root(); \ + } while (0) + +-static inline void local_irq_enable(void) +-{ +- barrier(); +- __ipipe_unstall_root(); +-} +- ++#define local_irq_restore(x) __ipipe_restore_root(x) ++#define local_irq_disable() __ipipe_stall_root() ++#define local_irq_enable() __ipipe_unstall_root() + #define irqs_disabled() __ipipe_test_root() + + #define local_save_flags_hw(x) \ +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/arch/blackfin/include/asm/Kbuild linux-2.6.29-rc3.owrt/arch/blackfin/include/asm/Kbuild +--- linux-2.6.29.owrt/arch/blackfin/include/asm/Kbuild 2009-05-10 22:04:40.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/arch/blackfin/include/asm/Kbuild 2009-05-10 23:48:28.000000000 +0200 +@@ -1,4 +1,3 @@ + include include/asm-generic/Kbuild.asm + +-unifdef-y += bfin_sport.h + unifdef-y += fixed_code.h +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/arch/blackfin/include/asm/kgdb.h linux-2.6.29-rc3.owrt/arch/blackfin/include/asm/kgdb.h +--- linux-2.6.29.owrt/arch/blackfin/include/asm/kgdb.h 2009-05-10 22:04:40.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/arch/blackfin/include/asm/kgdb.h 2009-05-10 23:48:28.000000000 +0200 +@@ -1,8 +1,32 @@ +-/* Blackfin KGDB header ++/* ++ * File: include/asm-blackfin/kgdb.h ++ * Based on: ++ * Author: Sonic Zhang ++ * ++ * Created: ++ * Description: ++ * ++ * Rev: $Id: kgdb_bfin_linux-2.6.x.patch 4934 2007-02-13 09:32:11Z sonicz $ ++ * ++ * Modified: ++ * Copyright 2005-2006 Analog Devices Inc. ++ * ++ * Bugs: Enter bugs at http://blackfin.uclinux.org/ + * +- * Copyright 2005-2009 Analog Devices Inc. ++ * 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. + * +- * Licensed under the GPL-2 or later. ++ * 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, see the file COPYING, or write ++ * to the Free Software Foundation, Inc., ++ * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + */ + + #ifndef __ASM_BLACKFIN_KGDB_H__ +@@ -13,18 +37,17 @@ + /* gdb locks */ + #define KGDB_MAX_NO_CPUS 8 + +-/* +- * BUFMAX defines the maximum number of characters in inbound/outbound buffers. +- * At least NUMREGBYTES*2 are needed for register packets. +- * Longer buffer is needed to list all threads. +- */ ++/************************************************************************/ ++/* BUFMAX defines the maximum number of characters in inbound/outbound buffers*/ ++/* at least NUMREGBYTES*2 are needed for register packets */ ++/* Longer buffer is needed to list all threads */ + #define BUFMAX 2048 + + /* +- * Note that this register image is different from +- * the register image that Linux produces at interrupt time. +- * +- * Linux's register image is defined by struct pt_regs in ptrace.h. ++ * Note that this register image is different from ++ * the register image that Linux produces at interrupt time. ++ * ++ * Linux's register image is defined by struct pt_regs in ptrace.h. + */ + enum regnames { + /* Core Registers */ +@@ -81,14 +104,14 @@ + BFIN_RETX, + BFIN_RETN, + BFIN_RETE, +- ++ + /* Pseudo Registers */ + BFIN_PC, + BFIN_CC, + BFIN_EXTRA1, /* Address of .text section. */ + BFIN_EXTRA2, /* Address of .data section. */ + BFIN_EXTRA3, /* Address of .bss section. */ +- BFIN_FDPIC_EXEC, ++ BFIN_FDPIC_EXEC, + BFIN_FDPIC_INTERP, + + /* MMRs */ +@@ -103,7 +126,7 @@ + + static inline void arch_kgdb_breakpoint(void) + { +- asm("EXCPT 2;"); ++ asm(" EXCPT 2;"); + } + #define BREAK_INSTR_SIZE 2 + #define CACHE_FLUSH_IS_SAFE 1 +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/arch/blackfin/include/asm/mem_init.h linux-2.6.29-rc3.owrt/arch/blackfin/include/asm/mem_init.h +--- linux-2.6.29.owrt/arch/blackfin/include/asm/mem_init.h 2009-05-10 22:04:40.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/arch/blackfin/include/asm/mem_init.h 2009-05-10 23:48:28.000000000 +0200 +@@ -115,7 +115,7 @@ + #define mem_SDRRC (((CONFIG_SCLK_HZ / 1000) * SDRAM_Tref) / SDRAM_NRA) - (SDRAM_tRAS_num + SDRAM_tRP_num) + + /* Enable SCLK Out */ +-#define mem_SDGCTL (SCTLE | SDRAM_CL | SDRAM_tRAS | SDRAM_tRP | SDRAM_tRCD | SDRAM_tWR | PSS) ++#define mem_SDGCTL (0x80000000 | SCTLE | SDRAM_CL | SDRAM_tRAS | SDRAM_tRP | SDRAM_tRCD | SDRAM_tWR | PSS) + #else + #define mem_SDRRC CONFIG_MEM_SDRRC + #define mem_SDGCTL CONFIG_MEM_SDGCTL +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/arch/blackfin/include/asm/pda.h linux-2.6.29-rc3.owrt/arch/blackfin/include/asm/pda.h +--- linux-2.6.29.owrt/arch/blackfin/include/asm/pda.h 2009-05-10 22:04:40.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/arch/blackfin/include/asm/pda.h 2009-05-10 23:48:28.000000000 +0200 +@@ -59,7 +59,6 @@ + unsigned long icplb_fault_addr; + unsigned long retx; + unsigned long seqstat; +- unsigned int __nmi_count; /* number of times NMI asserted on this CPU */ + }; + + extern struct blackfin_pda cpu_pda[]; +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/arch/blackfin/include/asm/reboot.h linux-2.6.29-rc3.owrt/arch/blackfin/include/asm/reboot.h +--- linux-2.6.29.owrt/arch/blackfin/include/asm/reboot.h 2009-05-10 22:04:40.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/arch/blackfin/include/asm/reboot.h 2009-05-10 23:48:28.000000000 +0200 +@@ -15,6 +15,6 @@ + extern void native_machine_power_off(void); + + /* common reboot workarounds */ +-extern void bfin_reset_boot_spi_cs(unsigned short pin); ++extern void bfin_gpio_reset_spi0_ssel1(void); + + #endif +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/arch/blackfin/include/asm/thread_info.h linux-2.6.29-rc3.owrt/arch/blackfin/include/asm/thread_info.h +--- linux-2.6.29.owrt/arch/blackfin/include/asm/thread_info.h 2009-05-10 22:04:40.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/arch/blackfin/include/asm/thread_info.h 2009-05-10 23:48:28.000000000 +0200 +@@ -122,7 +122,6 @@ + #define TIF_MEMDIE 4 + #define TIF_RESTORE_SIGMASK 5 /* restore signal mask in do_signal() */ + #define TIF_FREEZE 6 /* is freezing for suspend */ +-#define TIF_IRQ_SYNC 7 /* sync pipeline stage */ + + /* as above, but as bit values */ + #define _TIF_SYSCALL_TRACE (1<<TIF_SYSCALL_TRACE) +@@ -131,7 +130,6 @@ + #define _TIF_POLLING_NRFLAG (1<<TIF_POLLING_NRFLAG) + #define _TIF_RESTORE_SIGMASK (1<<TIF_RESTORE_SIGMASK) + #define _TIF_FREEZE (1<<TIF_FREEZE) +-#define _TIF_IRQ_SYNC (1<<TIF_IRQ_SYNC) + + #define _TIF_WORK_MASK 0x0000FFFE /* work to do on interrupt/exception return */ + +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/arch/blackfin/Kconfig linux-2.6.29-rc3.owrt/arch/blackfin/Kconfig +--- linux-2.6.29.owrt/arch/blackfin/Kconfig 2009-05-10 22:04:40.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/arch/blackfin/Kconfig 2009-05-10 23:48:28.000000000 +0200 +@@ -169,51 +169,26 @@ + help + BF542 Processor Support. + +-config BF542M +- bool "BF542m" +- help +- BF542 Processor Support. +- + config BF544 + bool "BF544" + help + BF544 Processor Support. + +-config BF544M +- bool "BF544m" +- help +- BF544 Processor Support. +- + config BF547 + bool "BF547" + help + BF547 Processor Support. + +-config BF547M +- bool "BF547m" +- help +- BF547 Processor Support. +- + config BF548 + bool "BF548" + help + BF548 Processor Support. + +-config BF548M +- bool "BF548m" +- help +- BF548 Processor Support. +- + config BF549 + bool "BF549" + help + BF549 Processor Support. + +-config BF549M +- bool "BF549m" +- help +- BF549 Processor Support. +- + config BF561 + bool "BF561" + help +@@ -249,39 +224,39 @@ + + config BF_REV_MIN + int +- default 0 if (BF51x || BF52x || (BF54x && !BF54xM)) ++ default 0 if (BF51x || BF52x || BF54x) + default 2 if (BF537 || BF536 || BF534) +- default 3 if (BF561 || BF533 || BF532 || BF531 || BF54xM) ++ default 3 if (BF561 ||BF533 || BF532 || BF531) + default 4 if (BF538 || BF539) + + config BF_REV_MAX + int +- default 2 if (BF51x || BF52x || (BF54x && !BF54xM)) +- default 3 if (BF537 || BF536 || BF534 || BF54xM) ++ default 2 if (BF51x || BF52x || BF54x) ++ default 3 if (BF537 || BF536 || BF534) + default 5 if (BF561 || BF538 || BF539) + default 6 if (BF533 || BF532 || BF531) + + choice + prompt "Silicon Rev" +- default BF_REV_0_1 if (BF51x || BF52x || (BF54x && !BF54xM)) ++ default BF_REV_0_1 if (BF51x || BF52x || BF54x) + default BF_REV_0_2 if (BF534 || BF536 || BF537) +- default BF_REV_0_3 if (BF531 || BF532 || BF533 || BF54xM || BF561) ++ default BF_REV_0_3 if (BF531 || BF532 || BF533 || BF561) + + config BF_REV_0_0 + bool "0.0" +- depends on (BF51x || BF52x || (BF54x && !BF54xM)) ++ depends on (BF51x || BF52x || BF54x) + + config BF_REV_0_1 + bool "0.1" +- depends on (BF52x || (BF54x && !BF54xM)) ++ depends on (BF52x || BF54x) + + config BF_REV_0_2 + bool "0.2" +- depends on (BF52x || BF537 || BF536 || BF534 || (BF54x && !BF54xM)) ++ depends on (BF52x || BF537 || BF536 || BF534 || BF54x) + + config BF_REV_0_3 + bool "0.3" +- depends on (BF54xM || BF561 || BF537 || BF536 || BF534 || BF533 || BF532 || BF531) ++ depends on (BF561 || BF537 || BF536 || BF534 || BF533 || BF532 || BF531) + + config BF_REV_0_4 + bool "0.4" +@@ -318,14 +293,9 @@ + depends on (BF531 || BF532 || BF533 || BF534 || BF536 || BF537) + default y + +-config BF54xM +- bool +- depends on (BF542M || BF544M || BF547M || BF548M || BF549M) +- default y +- + config BF54x + bool +- depends on (BF542 || BF544 || BF547 || BF548 || BF549 || BF54xM) ++ depends on (BF542 || BF544 || BF547 || BF548 || BF549) + default y + + config MEM_GENERIC_BOARD +@@ -1129,7 +1099,6 @@ + + config PM_WAKEUP_BY_GPIO + bool "Allow Wakeup from Standby by GPIO" +- depends on PM && !BF54x + + config PM_WAKEUP_GPIO_NUMBER + int "GPIO number" +@@ -1169,12 +1138,6 @@ + default n + help + Enable General-Purpose Wake-Up (Voltage Regulator Power-Up) +- (all processors, except ADSP-BF549). This option sets +- the general-purpose wake-up enable (GPWE) control bit to enable +- wake-up upon detection of an active low signal on the /GPW (PH7) pin. +- On ADSP-BF549 this option enables the the same functionality on the +- /MRXON pin also PH7. +- + endmenu + + menu "CPU Frequency scaling" +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/arch/blackfin/Kconfig.debug linux-2.6.29-rc3.owrt/arch/blackfin/Kconfig.debug +--- linux-2.6.29.owrt/arch/blackfin/Kconfig.debug 2009-05-10 22:04:41.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/arch/blackfin/Kconfig.debug 2009-05-10 23:48:28.000000000 +0200 +@@ -21,6 +21,12 @@ + config HAVE_ARCH_KGDB + def_bool y + ++config KGDB_TESTCASE ++ tristate "KGDB: for test case in expect" ++ default n ++ help ++ This is a kgdb test case for automated testing. ++ + config DEBUG_VERBOSE + bool "Verbose fault messages" + default y +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/arch/blackfin/kernel/bfin_dma_5xx.c linux-2.6.29-rc3.owrt/arch/blackfin/kernel/bfin_dma_5xx.c +--- linux-2.6.29.owrt/arch/blackfin/kernel/bfin_dma_5xx.c 2009-05-10 22:04:41.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/arch/blackfin/kernel/bfin_dma_5xx.c 2009-05-10 23:48:28.000000000 +0200 +@@ -249,13 +249,6 @@ + + spin_lock_irqsave(&mdma_lock, flags); + +- /* Force a sync in case a previous config reset on this channel +- * occurred. This is needed so subsequent writes to DMA registers +- * are not spuriously lost/corrupted. Do it under irq lock and +- * without the anomaly version (because we are atomic already). +- */ +- __builtin_bfin_ssync(); +- + if (bfin_read_MDMA_S0_CONFIG()) + while (!(bfin_read_MDMA_D0_IRQ_STATUS() & DMA_DONE)) + continue; +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/arch/blackfin/kernel/bfin_gpio.c linux-2.6.29-rc3.owrt/arch/blackfin/kernel/bfin_gpio.c +--- linux-2.6.29.owrt/arch/blackfin/kernel/bfin_gpio.c 2009-05-10 22:04:41.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/arch/blackfin/kernel/bfin_gpio.c 2009-05-10 23:48:28.000000000 +0200 +@@ -27,6 +27,59 @@ + * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + */ + ++/* ++* Number BF537/6/4 BF561 BF533/2/1 BF549/8/4/2 ++* ++* GPIO_0 PF0 PF0 PF0 PA0...PJ13 ++* GPIO_1 PF1 PF1 PF1 ++* GPIO_2 PF2 PF2 PF2 ++* GPIO_3 PF3 PF3 PF3 ++* GPIO_4 PF4 PF4 PF4 ++* GPIO_5 PF5 PF5 PF5 ++* GPIO_6 PF6 PF6 PF6 ++* GPIO_7 PF7 PF7 PF7 ++* GPIO_8 PF8 PF8 PF8 ++* GPIO_9 PF9 PF9 PF9 ++* GPIO_10 PF10 PF10 PF10 ++* GPIO_11 PF11 PF11 PF11 ++* GPIO_12 PF12 PF12 PF12 ++* GPIO_13 PF13 PF13 PF13 ++* GPIO_14 PF14 PF14 PF14 ++* GPIO_15 PF15 PF15 PF15 ++* GPIO_16 PG0 PF16 ++* GPIO_17 PG1 PF17 ++* GPIO_18 PG2 PF18 ++* GPIO_19 PG3 PF19 ++* GPIO_20 PG4 PF20 ++* GPIO_21 PG5 PF21 ++* GPIO_22 PG6 PF22 ++* GPIO_23 PG7 PF23 ++* GPIO_24 PG8 PF24 ++* GPIO_25 PG9 PF25 ++* GPIO_26 PG10 PF26 ++* GPIO_27 PG11 PF27 ++* GPIO_28 PG12 PF28 ++* GPIO_29 PG13 PF29 ++* GPIO_30 PG14 PF30 ++* GPIO_31 PG15 PF31 ++* GPIO_32 PH0 PF32 ++* GPIO_33 PH1 PF33 ++* GPIO_34 PH2 PF34 ++* GPIO_35 PH3 PF35 ++* GPIO_36 PH4 PF36 ++* GPIO_37 PH5 PF37 ++* GPIO_38 PH6 PF38 ++* GPIO_39 PH7 PF39 ++* GPIO_40 PH8 PF40 ++* GPIO_41 PH9 PF41 ++* GPIO_42 PH10 PF42 ++* GPIO_43 PH11 PF43 ++* GPIO_44 PH12 PF44 ++* GPIO_45 PH13 PF45 ++* GPIO_46 PH14 PF46 ++* GPIO_47 PH15 PF47 ++*/ ++ + #include <linux/delay.h> + #include <linux/module.h> + #include <linux/err.h> +@@ -66,61 +119,62 @@ + #define AWA_DUMMY_READ(...) do { } while (0) + #endif + +-static struct gpio_port_t * const gpio_array[] = { + #if defined(BF533_FAMILY) || defined(BF538_FAMILY) ++static struct gpio_port_t *gpio_bankb[] = { + (struct gpio_port_t *) FIO_FLAG_D, +-#elif defined(BF527_FAMILY) || defined(BF537_FAMILY) || defined(BF518_FAMILY) ++}; ++#endif ++ ++#if defined(BF527_FAMILY) || defined(BF537_FAMILY) || defined(BF518_FAMILY) ++static struct gpio_port_t *gpio_bankb[] = { + (struct gpio_port_t *) PORTFIO, + (struct gpio_port_t *) PORTGIO, + (struct gpio_port_t *) PORTHIO, +-#elif defined(BF561_FAMILY) +- (struct gpio_port_t *) FIO0_FLAG_D, +- (struct gpio_port_t *) FIO1_FLAG_D, +- (struct gpio_port_t *) FIO2_FLAG_D, +-#elif defined(BF548_FAMILY) +- (struct gpio_port_t *)PORTA_FER, +- (struct gpio_port_t *)PORTB_FER, +- (struct gpio_port_t *)PORTC_FER, +- (struct gpio_port_t *)PORTD_FER, +- (struct gpio_port_t *)PORTE_FER, +- (struct gpio_port_t *)PORTF_FER, +- (struct gpio_port_t *)PORTG_FER, +- (struct gpio_port_t *)PORTH_FER, +- (struct gpio_port_t *)PORTI_FER, +- (struct gpio_port_t *)PORTJ_FER, +-#else +-# error no gpio arrays defined +-#endif + }; + +-#if defined(BF527_FAMILY) || defined(BF537_FAMILY) || defined(BF518_FAMILY) +-static unsigned short * const port_fer[] = { ++static unsigned short *port_fer[] = { + (unsigned short *) PORTF_FER, + (unsigned short *) PORTG_FER, + (unsigned short *) PORTH_FER, + }; ++#endif + +-# if !defined(BF537_FAMILY) +-static unsigned short * const port_mux[] = { ++#if defined(BF527_FAMILY) || defined(BF518_FAMILY) ++static unsigned short *port_mux[] = { + (unsigned short *) PORTF_MUX, + (unsigned short *) PORTG_MUX, + (unsigned short *) PORTH_MUX, + }; + + static const +-u8 pmux_offset[][16] = { +-# if defined(BF527_FAMILY) +- { 0, 0, 0, 0, 0, 0, 0, 0, 2, 2, 4, 6, 8, 8, 10, 10 }, /* PORTF */ +- { 0, 0, 0, 0, 0, 2, 2, 4, 4, 6, 8, 10, 10, 10, 12, 12 }, /* PORTG */ +- { 0, 0, 0, 0, 0, 0, 0, 0, 2, 4, 4, 4, 4, 4, 4, 4 }, /* PORTH */ +-# elif defined(BF518_FAMILY) +- { 0, 2, 2, 2, 2, 2, 2, 4, 6, 6, 6, 8, 8, 8, 8, 10 }, /* PORTF */ +- { 0, 0, 0, 2, 4, 6, 6, 6, 8, 10, 10, 12, 14, 14, 14, 14 }, /* PORTG */ +- { 0, 0, 0, 0, 2, 2, 4, 6, 10, 10, 10, 10, 10, 10, 10, 10 }, /* PORTH */ +-# endif ++u8 pmux_offset[][16] = ++ {{ 0, 0, 0, 0, 0, 0, 0, 0, 2, 2, 4, 6, 8, 8, 10, 10 }, /* PORTF */ ++ { 0, 0, 0, 0, 0, 2, 2, 4, 4, 6, 8, 10, 10, 10, 12, 12 }, /* PORTG */ ++ { 0, 0, 0, 0, 0, 0, 0, 0, 2, 4, 4, 4, 4, 4, 4, 4 }, /* PORTH */ ++ }; ++#endif ++ ++#ifdef BF561_FAMILY ++static struct gpio_port_t *gpio_bankb[] = { ++ (struct gpio_port_t *) FIO0_FLAG_D, ++ (struct gpio_port_t *) FIO1_FLAG_D, ++ (struct gpio_port_t *) FIO2_FLAG_D, + }; +-# endif ++#endif + ++#ifdef BF548_FAMILY ++static struct gpio_port_t *gpio_array[] = { ++ (struct gpio_port_t *)PORTA_FER, ++ (struct gpio_port_t *)PORTB_FER, ++ (struct gpio_port_t *)PORTC_FER, ++ (struct gpio_port_t *)PORTD_FER, ++ (struct gpio_port_t *)PORTE_FER, ++ (struct gpio_port_t *)PORTF_FER, ++ (struct gpio_port_t *)PORTG_FER, ++ (struct gpio_port_t *)PORTH_FER, ++ (struct gpio_port_t *)PORTI_FER, ++ (struct gpio_port_t *)PORTJ_FER, ++}; + #endif + + static unsigned short reserved_gpio_map[GPIO_BANK_NUM]; +@@ -134,9 +188,35 @@ + } str_ident[MAX_RESOURCES]; + + #if defined(CONFIG_PM) ++#if defined(CONFIG_BF54x) ++static struct gpio_port_s gpio_bank_saved[GPIO_BANK_NUM]; ++#else ++static unsigned short wakeup_map[GPIO_BANK_NUM]; ++static unsigned char wakeup_flags_map[MAX_BLACKFIN_GPIOS]; + static struct gpio_port_s gpio_bank_saved[GPIO_BANK_NUM]; ++ ++#ifdef BF533_FAMILY ++static unsigned int sic_iwr_irqs[] = {IRQ_PROG_INTB}; ++#endif ++ ++#ifdef BF537_FAMILY ++static unsigned int sic_iwr_irqs[] = {IRQ_PROG_INTB, IRQ_PORTG_INTB, IRQ_MAC_TX}; ++#endif ++ ++#ifdef BF538_FAMILY ++static unsigned int sic_iwr_irqs[] = {IRQ_PORTF_INTB}; + #endif + ++#if defined(BF527_FAMILY) || defined(BF518_FAMILY) ++static unsigned int sic_iwr_irqs[] = {IRQ_PORTF_INTB, IRQ_PORTG_INTB, IRQ_PORTH_INTB}; ++#endif ++ ++#ifdef BF561_FAMILY ++static unsigned int sic_iwr_irqs[] = {IRQ_PROG0_INTB, IRQ_PROG1_INTB, IRQ_PROG2_INTB}; ++#endif ++#endif ++#endif /* CONFIG_PM */ ++ + inline int check_gpio(unsigned gpio) + { + #if defined(BF548_FAMILY) +@@ -250,10 +330,9 @@ + {.res = P_SPI0_SSEL3, .offset = 0}, + }; + +-static void portmux_setup(unsigned short per) ++static void portmux_setup(unsigned short per, unsigned short function) + { + u16 y, offset, muxreg; +- u16 function = P_FUNCT2MUX(per); + + for (y = 0; y < ARRAY_SIZE(port_mux_lut); y++) { + if (port_mux_lut[y].res == per) { +@@ -274,33 +353,30 @@ + } + } + #elif defined(BF548_FAMILY) +-inline void portmux_setup(unsigned short per) ++inline void portmux_setup(unsigned short portno, unsigned short function) + { + u32 pmux; +- u16 ident = P_IDENT(per); +- u16 function = P_FUNCT2MUX(per); + +- pmux = gpio_array[gpio_bank(ident)]->port_mux; ++ pmux = gpio_array[gpio_bank(portno)]->port_mux; + +- pmux &= ~(0x3 << (2 * gpio_sub_n(ident))); +- pmux |= (function & 0x3) << (2 * gpio_sub_n(ident)); ++ pmux &= ~(0x3 << (2 * gpio_sub_n(portno))); ++ pmux |= (function & 0x3) << (2 * gpio_sub_n(portno)); + +- gpio_array[gpio_bank(ident)]->port_mux = pmux; ++ gpio_array[gpio_bank(portno)]->port_mux = pmux; + } + +-inline u16 get_portmux(unsigned short per) ++inline u16 get_portmux(unsigned short portno) + { + u32 pmux; +- u16 ident = P_IDENT(per); + +- pmux = gpio_array[gpio_bank(ident)]->port_mux; ++ pmux = gpio_array[gpio_bank(portno)]->port_mux; + +- return (pmux >> (2 * gpio_sub_n(ident)) & 0x3); ++ return (pmux >> (2 * gpio_sub_n(portno)) & 0x3); + } + #elif defined(BF527_FAMILY) || defined(BF518_FAMILY) +-inline void portmux_setup(unsigned short per) ++inline void portmux_setup(unsigned short portno, unsigned short function) + { +- u16 pmux, ident = P_IDENT(per), function = P_FUNCT2MUX(per); ++ u16 pmux, ident = P_IDENT(portno); + u8 offset = pmux_offset[gpio_bank(ident)][gpio_sub_n(ident)]; + + pmux = *port_mux[gpio_bank(ident)]; +@@ -348,71 +424,90 @@ + unsigned long flags; \ + local_irq_save_hw(flags); \ + if (arg) \ +- gpio_array[gpio_bank(gpio)]->name |= gpio_bit(gpio); \ ++ gpio_bankb[gpio_bank(gpio)]->name |= gpio_bit(gpio); \ + else \ +- gpio_array[gpio_bank(gpio)]->name &= ~gpio_bit(gpio); \ ++ gpio_bankb[gpio_bank(gpio)]->name &= ~gpio_bit(gpio); \ + AWA_DUMMY_READ(name); \ + local_irq_restore_hw(flags); \ + } \ + EXPORT_SYMBOL(set_gpio_ ## name); + +-SET_GPIO(dir) /* set_gpio_dir() */ +-SET_GPIO(inen) /* set_gpio_inen() */ +-SET_GPIO(polar) /* set_gpio_polar() */ +-SET_GPIO(edge) /* set_gpio_edge() */ +-SET_GPIO(both) /* set_gpio_both() */ ++SET_GPIO(dir) ++SET_GPIO(inen) ++SET_GPIO(polar) ++SET_GPIO(edge) ++SET_GPIO(both) + + ++#if ANOMALY_05000311 || ANOMALY_05000323 + #define SET_GPIO_SC(name) \ + void set_gpio_ ## name(unsigned gpio, unsigned short arg) \ + { \ + unsigned long flags; \ +- if (ANOMALY_05000311 || ANOMALY_05000323) \ +- local_irq_save_hw(flags); \ ++ local_irq_save_hw(flags); \ + if (arg) \ +- gpio_array[gpio_bank(gpio)]->name ## _set = gpio_bit(gpio); \ ++ gpio_bankb[gpio_bank(gpio)]->name ## _set = gpio_bit(gpio); \ + else \ +- gpio_array[gpio_bank(gpio)]->name ## _clear = gpio_bit(gpio); \ +- if (ANOMALY_05000311 || ANOMALY_05000323) { \ +- AWA_DUMMY_READ(name); \ +- local_irq_restore_hw(flags); \ +- } \ ++ gpio_bankb[gpio_bank(gpio)]->name ## _clear = gpio_bit(gpio); \ ++ AWA_DUMMY_READ(name); \ ++ local_irq_restore_hw(flags); \ + } \ + EXPORT_SYMBOL(set_gpio_ ## name); ++#else ++#define SET_GPIO_SC(name) \ ++void set_gpio_ ## name(unsigned gpio, unsigned short arg) \ ++{ \ ++ if (arg) \ ++ gpio_bankb[gpio_bank(gpio)]->name ## _set = gpio_bit(gpio); \ ++ else \ ++ gpio_bankb[gpio_bank(gpio)]->name ## _clear = gpio_bit(gpio); \ ++} \ ++EXPORT_SYMBOL(set_gpio_ ## name); ++#endif + + SET_GPIO_SC(maska) + SET_GPIO_SC(maskb) + SET_GPIO_SC(data) + ++#if ANOMALY_05000311 || ANOMALY_05000323 + void set_gpio_toggle(unsigned gpio) + { + unsigned long flags; +- if (ANOMALY_05000311 || ANOMALY_05000323) +- local_irq_save_hw(flags); +- gpio_array[gpio_bank(gpio)]->toggle = gpio_bit(gpio); +- if (ANOMALY_05000311 || ANOMALY_05000323) { +- AWA_DUMMY_READ(toggle); +- local_irq_restore_hw(flags); +- } ++ local_irq_save_hw(flags); ++ gpio_bankb[gpio_bank(gpio)]->toggle = gpio_bit(gpio); ++ AWA_DUMMY_READ(toggle); ++ local_irq_restore_hw(flags); ++} ++#else ++void set_gpio_toggle(unsigned gpio) ++{ ++ gpio_bankb[gpio_bank(gpio)]->toggle = gpio_bit(gpio); + } ++#endif + EXPORT_SYMBOL(set_gpio_toggle); + + + /*Set current PORT date (16-bit word)*/ + ++#if ANOMALY_05000311 || ANOMALY_05000323 + #define SET_GPIO_P(name) \ + void set_gpiop_ ## name(unsigned gpio, unsigned short arg) \ + { \ + unsigned long flags; \ +- if (ANOMALY_05000311 || ANOMALY_05000323) \ +- local_irq_save_hw(flags); \ +- gpio_array[gpio_bank(gpio)]->name = arg; \ +- if (ANOMALY_05000311 || ANOMALY_05000323) { \ +- AWA_DUMMY_READ(name); \ +- local_irq_restore_hw(flags); \ +- } \ ++ local_irq_save_hw(flags); \ ++ gpio_bankb[gpio_bank(gpio)]->name = arg; \ ++ AWA_DUMMY_READ(name); \ ++ local_irq_restore_hw(flags); \ ++} \ ++EXPORT_SYMBOL(set_gpiop_ ## name); ++#else ++#define SET_GPIO_P(name) \ ++void set_gpiop_ ## name(unsigned gpio, unsigned short arg) \ ++{ \ ++ gpio_bankb[gpio_bank(gpio)]->name = arg; \ + } \ + EXPORT_SYMBOL(set_gpiop_ ## name); ++#endif + + SET_GPIO_P(data) + SET_GPIO_P(dir) +@@ -424,21 +519,27 @@ + SET_GPIO_P(maskb) + + /* Get a specific bit */ ++#if ANOMALY_05000311 || ANOMALY_05000323 + #define GET_GPIO(name) \ + unsigned short get_gpio_ ## name(unsigned gpio) \ + { \ + unsigned long flags; \ + unsigned short ret; \ +- if (ANOMALY_05000311 || ANOMALY_05000323) \ +- local_irq_save_hw(flags); \ +- ret = 0x01 & (gpio_array[gpio_bank(gpio)]->name >> gpio_sub_n(gpio)); \ +- if (ANOMALY_05000311 || ANOMALY_05000323) { \ +- AWA_DUMMY_READ(name); \ +- local_irq_restore_hw(flags); \ +- } \ ++ local_irq_save_hw(flags); \ ++ ret = 0x01 & (gpio_bankb[gpio_bank(gpio)]->name >> gpio_sub_n(gpio)); \ ++ AWA_DUMMY_READ(name); \ ++ local_irq_restore_hw(flags); \ + return ret; \ + } \ + EXPORT_SYMBOL(get_gpio_ ## name); ++#else ++#define GET_GPIO(name) \ ++unsigned short get_gpio_ ## name(unsigned gpio) \ ++{ \ ++ return (0x01 & (gpio_bankb[gpio_bank(gpio)]->name >> gpio_sub_n(gpio))); \ ++} \ ++EXPORT_SYMBOL(get_gpio_ ## name); ++#endif + + GET_GPIO(data) + GET_GPIO(dir) +@@ -451,21 +552,27 @@ + + /*Get current PORT date (16-bit word)*/ + ++#if ANOMALY_05000311 || ANOMALY_05000323 + #define GET_GPIO_P(name) \ + unsigned short get_gpiop_ ## name(unsigned gpio) \ + { \ + unsigned long flags; \ + unsigned short ret; \ +- if (ANOMALY_05000311 || ANOMALY_05000323) \ +- local_irq_save_hw(flags); \ +- ret = (gpio_array[gpio_bank(gpio)]->name); \ +- if (ANOMALY_05000311 || ANOMALY_05000323) { \ +- AWA_DUMMY_READ(name); \ +- local_irq_restore_hw(flags); \ +- } \ ++ local_irq_save_hw(flags); \ ++ ret = (gpio_bankb[gpio_bank(gpio)]->name); \ ++ AWA_DUMMY_READ(name); \ ++ local_irq_restore_hw(flags); \ + return ret; \ + } \ + EXPORT_SYMBOL(get_gpiop_ ## name); ++#else ++#define GET_GPIO_P(name) \ ++unsigned short get_gpiop_ ## name(unsigned gpio) \ ++{ \ ++ return (gpio_bankb[gpio_bank(gpio)]->name);\ ++} \ ++EXPORT_SYMBOL(get_gpiop_ ## name); ++#endif + + GET_GPIO_P(data) + GET_GPIO_P(dir) +@@ -478,26 +585,6 @@ + + + #ifdef CONFIG_PM +- +-static unsigned short wakeup_map[GPIO_BANK_NUM]; +-static unsigned char wakeup_flags_map[MAX_BLACKFIN_GPIOS]; +- +-static const unsigned int sic_iwr_irqs[] = { +-#if defined(BF533_FAMILY) +- IRQ_PROG_INTB +-#elif defined(BF537_FAMILY) +- IRQ_PROG_INTB, IRQ_PORTG_INTB, IRQ_MAC_TX +-#elif defined(BF538_FAMILY) +- IRQ_PORTF_INTB +-#elif defined(BF527_FAMILY) || defined(BF518_FAMILY) +- IRQ_PORTF_INTB, IRQ_PORTG_INTB, IRQ_PORTH_INTB +-#elif defined(BF561_FAMILY) +- IRQ_PROG0_INTB, IRQ_PROG1_INTB, IRQ_PROG2_INTB +-#else +-# error no SIC_IWR defined +-#endif +-}; +- + /*********************************************************** + * + * FUNCTIONS: Blackfin PM Setup API +@@ -582,18 +669,18 @@ + mask = wakeup_map[gpio_bank(i)]; + bank = gpio_bank(i); + +- gpio_bank_saved[bank].maskb = gpio_array[bank]->maskb; +- gpio_array[bank]->maskb = 0; ++ gpio_bank_saved[bank].maskb = gpio_bankb[bank]->maskb; ++ gpio_bankb[bank]->maskb = 0; + + if (mask) { + #if defined(BF527_FAMILY) || defined(BF537_FAMILY) || defined(BF518_FAMILY) + gpio_bank_saved[bank].fer = *port_fer[bank]; + #endif +- gpio_bank_saved[bank].inen = gpio_array[bank]->inen; +- gpio_bank_saved[bank].polar = gpio_array[bank]->polar; +- gpio_bank_saved[bank].dir = gpio_array[bank]->dir; +- gpio_bank_saved[bank].edge = gpio_array[bank]->edge; +- gpio_bank_saved[bank].both = gpio_array[bank]->both; ++ gpio_bank_saved[bank].inen = gpio_bankb[bank]->inen; ++ gpio_bank_saved[bank].polar = gpio_bankb[bank]->polar; ++ gpio_bank_saved[bank].dir = gpio_bankb[bank]->dir; ++ gpio_bank_saved[bank].edge = gpio_bankb[bank]->edge; ++ gpio_bank_saved[bank].both = gpio_bankb[bank]->both; + gpio_bank_saved[bank].reserved = + reserved_gpio_map[bank]; + +@@ -613,7 +700,7 @@ + } + + bfin_internal_set_wake(sic_iwr_irqs[bank], 1); +- gpio_array[bank]->maskb_set = wakeup_map[gpio_bank(i)]; ++ gpio_bankb[bank]->maskb_set = wakeup_map[gpio_bank(i)]; + } + } + +@@ -634,18 +721,18 @@ + #if defined(BF527_FAMILY) || defined(BF537_FAMILY) || defined(BF518_FAMILY) + *port_fer[bank] = gpio_bank_saved[bank].fer; + #endif +- gpio_array[bank]->inen = gpio_bank_saved[bank].inen; +- gpio_array[bank]->dir = gpio_bank_saved[bank].dir; +- gpio_array[bank]->polar = gpio_bank_saved[bank].polar; +- gpio_array[bank]->edge = gpio_bank_saved[bank].edge; +- gpio_array[bank]->both = gpio_bank_saved[bank].both; ++ gpio_bankb[bank]->inen = gpio_bank_saved[bank].inen; ++ gpio_bankb[bank]->dir = gpio_bank_saved[bank].dir; ++ gpio_bankb[bank]->polar = gpio_bank_saved[bank].polar; ++ gpio_bankb[bank]->edge = gpio_bank_saved[bank].edge; ++ gpio_bankb[bank]->both = gpio_bank_saved[bank].both; + + reserved_gpio_map[bank] = + gpio_bank_saved[bank].reserved; + bfin_internal_set_wake(sic_iwr_irqs[bank], 0); + } + +- gpio_array[bank]->maskb = gpio_bank_saved[bank].maskb; ++ gpio_bankb[bank]->maskb = gpio_bank_saved[bank].maskb; + } + AWA_DUMMY_READ(maskb); + } +@@ -658,21 +745,21 @@ + bank = gpio_bank(i); + + #if defined(BF527_FAMILY) || defined(BF537_FAMILY) || defined(BF518_FAMILY) +- gpio_bank_saved[bank].fer = *port_fer[bank]; ++ gpio_bank_saved[bank].fer = *port_fer[bank]; + #if defined(BF527_FAMILY) || defined(BF518_FAMILY) +- gpio_bank_saved[bank].mux = *port_mux[bank]; ++ gpio_bank_saved[bank].mux = *port_mux[bank]; + #else +- if (bank == 0) +- gpio_bank_saved[bank].mux = bfin_read_PORT_MUX(); ++ if (bank == 0) ++ gpio_bank_saved[bank].mux = bfin_read_PORT_MUX(); + #endif + #endif +- gpio_bank_saved[bank].data = gpio_array[bank]->data; +- gpio_bank_saved[bank].inen = gpio_array[bank]->inen; +- gpio_bank_saved[bank].polar = gpio_array[bank]->polar; +- gpio_bank_saved[bank].dir = gpio_array[bank]->dir; +- gpio_bank_saved[bank].edge = gpio_array[bank]->edge; +- gpio_bank_saved[bank].both = gpio_array[bank]->both; +- gpio_bank_saved[bank].maska = gpio_array[bank]->maska; ++ gpio_bank_saved[bank].data = gpio_bankb[bank]->data; ++ gpio_bank_saved[bank].inen = gpio_bankb[bank]->inen; ++ gpio_bank_saved[bank].polar = gpio_bankb[bank]->polar; ++ gpio_bank_saved[bank].dir = gpio_bankb[bank]->dir; ++ gpio_bank_saved[bank].edge = gpio_bankb[bank]->edge; ++ gpio_bank_saved[bank].both = gpio_bankb[bank]->both; ++ gpio_bank_saved[bank].maska = gpio_bankb[bank]->maska; + } + + AWA_DUMMY_READ(maska); +@@ -683,27 +770,27 @@ + int i, bank; + + for (i = 0; i < MAX_BLACKFIN_GPIOS; i += GPIO_BANKSIZE) { +- bank = gpio_bank(i); ++ bank = gpio_bank(i); + + #if defined(BF527_FAMILY) || defined(BF537_FAMILY) || defined(BF518_FAMILY) + #if defined(BF527_FAMILY) || defined(BF518_FAMILY) +- *port_mux[bank] = gpio_bank_saved[bank].mux; ++ *port_mux[bank] = gpio_bank_saved[bank].mux; + #else +- if (bank == 0) +- bfin_write_PORT_MUX(gpio_bank_saved[bank].mux); ++ if (bank == 0) ++ bfin_write_PORT_MUX(gpio_bank_saved[bank].mux); + #endif +- *port_fer[bank] = gpio_bank_saved[bank].fer; ++ *port_fer[bank] = gpio_bank_saved[bank].fer; + #endif +- gpio_array[bank]->inen = gpio_bank_saved[bank].inen; +- gpio_array[bank]->dir = gpio_bank_saved[bank].dir; +- gpio_array[bank]->polar = gpio_bank_saved[bank].polar; +- gpio_array[bank]->edge = gpio_bank_saved[bank].edge; +- gpio_array[bank]->both = gpio_bank_saved[bank].both; ++ gpio_bankb[bank]->inen = gpio_bank_saved[bank].inen; ++ gpio_bankb[bank]->dir = gpio_bank_saved[bank].dir; ++ gpio_bankb[bank]->polar = gpio_bank_saved[bank].polar; ++ gpio_bankb[bank]->edge = gpio_bank_saved[bank].edge; ++ gpio_bankb[bank]->both = gpio_bank_saved[bank].both; + +- gpio_array[bank]->data_set = gpio_bank_saved[bank].data +- | gpio_bank_saved[bank].dir; ++ gpio_bankb[bank]->data_set = gpio_bank_saved[bank].data ++ | gpio_bank_saved[bank].dir; + +- gpio_array[bank]->maska = gpio_bank_saved[bank].maska; ++ gpio_bankb[bank]->maska = gpio_bank_saved[bank].maska; + } + AWA_DUMMY_READ(maska); + } +@@ -730,12 +817,12 @@ + for (i = 0; i < MAX_BLACKFIN_GPIOS; i += GPIO_BANKSIZE) { + bank = gpio_bank(i); + +- gpio_bank_saved[bank].fer = gpio_array[bank]->port_fer; +- gpio_bank_saved[bank].mux = gpio_array[bank]->port_mux; +- gpio_bank_saved[bank].data = gpio_array[bank]->data; +- gpio_bank_saved[bank].data = gpio_array[bank]->data; +- gpio_bank_saved[bank].inen = gpio_array[bank]->inen; +- gpio_bank_saved[bank].dir = gpio_array[bank]->dir_set; ++ gpio_bank_saved[bank].fer = gpio_array[bank]->port_fer; ++ gpio_bank_saved[bank].mux = gpio_array[bank]->port_mux; ++ gpio_bank_saved[bank].data = gpio_array[bank]->port_data; ++ gpio_bank_saved[bank].data = gpio_array[bank]->port_data; ++ gpio_bank_saved[bank].inen = gpio_array[bank]->port_inen; ++ gpio_bank_saved[bank].dir = gpio_array[bank]->port_dir_set; + } + } + +@@ -744,21 +831,21 @@ + int i, bank; + + for (i = 0; i < MAX_BLACKFIN_GPIOS; i += GPIO_BANKSIZE) { +- bank = gpio_bank(i); ++ bank = gpio_bank(i); + +- gpio_array[bank]->port_mux = gpio_bank_saved[bank].mux; +- gpio_array[bank]->port_fer = gpio_bank_saved[bank].fer; +- gpio_array[bank]->inen = gpio_bank_saved[bank].inen; +- gpio_array[bank]->dir_set = gpio_bank_saved[bank].dir; +- gpio_array[bank]->data_set = gpio_bank_saved[bank].data +- | gpio_bank_saved[bank].dir; ++ gpio_array[bank]->port_mux = gpio_bank_saved[bank].mux; ++ gpio_array[bank]->port_fer = gpio_bank_saved[bank].fer; ++ gpio_array[bank]->port_inen = gpio_bank_saved[bank].inen; ++ gpio_array[bank]->port_dir_set = gpio_bank_saved[bank].dir; ++ gpio_array[bank]->port_set = gpio_bank_saved[bank].data ++ | gpio_bank_saved[bank].dir; + } + } + #endif + + unsigned short get_gpio_dir(unsigned gpio) + { +- return (0x01 & (gpio_array[gpio_bank(gpio)]->dir_clear >> gpio_sub_n(gpio))); ++ return (0x01 & (gpio_array[gpio_bank(gpio)]->port_dir_clear >> gpio_sub_n(gpio))); + } + EXPORT_SYMBOL(get_gpio_dir); + +@@ -818,7 +905,9 @@ + */ + + #ifdef BF548_FAMILY +- if (!((per & P_MAYSHARE) && get_portmux(per) == P_FUNCT2MUX(per))) { ++ u16 funct = get_portmux(ident); ++ ++ if (!((per & P_MAYSHARE) && (funct == P_FUNCT2MUX(per)))) { + #else + if (!(per & P_MAYSHARE)) { + #endif +@@ -842,7 +931,11 @@ + anyway: + reserved_peri_map[gpio_bank(ident)] |= gpio_bit(ident); + +- portmux_setup(per); ++#ifdef BF548_FAMILY ++ portmux_setup(ident, P_FUNCT2MUX(per)); ++#else ++ portmux_setup(per, P_FUNCT2MUX(per)); ++#endif + port_setup(ident, PERIPHERAL_USAGE); + + local_irq_restore_hw(flags); +@@ -884,6 +977,9 @@ + if (!(per & P_DEFINED)) + return; + ++ if (check_gpio(ident) < 0) ++ return; ++ + local_irq_save_hw(flags); + + if (unlikely(!(reserved_peri_map[gpio_bank(ident)] & gpio_bit(ident)))) { +@@ -960,15 +1056,9 @@ + local_irq_restore_hw(flags); + return -EBUSY; + } +- if (unlikely(reserved_gpio_irq_map[gpio_bank(gpio)] & gpio_bit(gpio))) { ++ if (unlikely(reserved_gpio_irq_map[gpio_bank(gpio)] & gpio_bit(gpio))) + printk(KERN_NOTICE "bfin-gpio: GPIO %d is already reserved as gpio-irq!" + " (Documentation/blackfin/bfin-gpio-notes.txt)\n", gpio); +- } +-#ifndef BF548_FAMILY +- else { /* Reset POLAR setting when acquiring a gpio for the first time */ +- set_gpio_polar(gpio, 0); +- } +-#endif + + reserved_gpio_map[gpio_bank(gpio)] |= gpio_bit(gpio); + set_label(gpio, label); +@@ -988,8 +1078,6 @@ + if (check_gpio(gpio) < 0) + return; + +- might_sleep(); +- + local_irq_save_hw(flags); + + if (unlikely(!(reserved_gpio_map[gpio_bank(gpio)] & gpio_bit(gpio)))) { +@@ -1070,16 +1158,8 @@ + local_irq_restore_hw(flags); + } + +-static inline void __bfin_gpio_direction_input(unsigned gpio) +-{ +-#ifdef BF548_FAMILY +- gpio_array[gpio_bank(gpio)]->dir_clear = gpio_bit(gpio); +-#else +- gpio_array[gpio_bank(gpio)]->dir &= ~gpio_bit(gpio); +-#endif +- gpio_array[gpio_bank(gpio)]->inen |= gpio_bit(gpio); +-} + ++#ifdef BF548_FAMILY + int bfin_gpio_direction_input(unsigned gpio) + { + unsigned long flags; +@@ -1090,85 +1170,125 @@ + } + + local_irq_save_hw(flags); +- __bfin_gpio_direction_input(gpio); +- AWA_DUMMY_READ(inen); ++ gpio_array[gpio_bank(gpio)]->port_dir_clear = gpio_bit(gpio); ++ gpio_array[gpio_bank(gpio)]->port_inen |= gpio_bit(gpio); + local_irq_restore_hw(flags); + + return 0; + } + EXPORT_SYMBOL(bfin_gpio_direction_input); + +-void bfin_gpio_irq_prepare(unsigned gpio) ++int bfin_gpio_direction_output(unsigned gpio, int value) + { +-#ifdef BF548_FAMILY + unsigned long flags; +-#endif + +- port_setup(gpio, GPIO_USAGE); ++ if (!(reserved_gpio_map[gpio_bank(gpio)] & gpio_bit(gpio))) { ++ gpio_error(gpio); ++ return -EINVAL; ++ } + +-#ifdef BF548_FAMILY + local_irq_save_hw(flags); +- __bfin_gpio_direction_input(gpio); ++ gpio_array[gpio_bank(gpio)]->port_inen &= ~gpio_bit(gpio); ++ gpio_set_value(gpio, value); ++ gpio_array[gpio_bank(gpio)]->port_dir_set = gpio_bit(gpio); + local_irq_restore_hw(flags); +-#endif ++ ++ return 0; + } ++EXPORT_SYMBOL(bfin_gpio_direction_output); + + void bfin_gpio_set_value(unsigned gpio, int arg) + { + if (arg) +- gpio_array[gpio_bank(gpio)]->data_set = gpio_bit(gpio); ++ gpio_array[gpio_bank(gpio)]->port_set = gpio_bit(gpio); + else +- gpio_array[gpio_bank(gpio)]->data_clear = gpio_bit(gpio); ++ gpio_array[gpio_bank(gpio)]->port_clear = gpio_bit(gpio); + } + EXPORT_SYMBOL(bfin_gpio_set_value); + +-int bfin_gpio_direction_output(unsigned gpio, int value) ++int bfin_gpio_get_value(unsigned gpio) ++{ ++ return (1 & (gpio_array[gpio_bank(gpio)]->port_data >> gpio_sub_n(gpio))); ++} ++EXPORT_SYMBOL(bfin_gpio_get_value); ++ ++void bfin_gpio_irq_prepare(unsigned gpio) + { + unsigned long flags; + +- if (!(reserved_gpio_map[gpio_bank(gpio)] & gpio_bit(gpio))) { +- gpio_error(gpio); +- return -EINVAL; +- } ++ port_setup(gpio, GPIO_USAGE); + + local_irq_save_hw(flags); +- +- gpio_array[gpio_bank(gpio)]->inen &= ~gpio_bit(gpio); +- gpio_set_value(gpio, value); +-#ifdef BF548_FAMILY +- gpio_array[gpio_bank(gpio)]->dir_set = gpio_bit(gpio); +-#else +- gpio_array[gpio_bank(gpio)]->dir |= gpio_bit(gpio); +-#endif +- +- AWA_DUMMY_READ(dir); ++ gpio_array[gpio_bank(gpio)]->port_dir_clear = gpio_bit(gpio); ++ gpio_array[gpio_bank(gpio)]->port_inen |= gpio_bit(gpio); + local_irq_restore_hw(flags); +- +- return 0; + } +-EXPORT_SYMBOL(bfin_gpio_direction_output); ++ ++#else + + int bfin_gpio_get_value(unsigned gpio) + { +-#ifdef BF548_FAMILY +- return (1 & (gpio_array[gpio_bank(gpio)]->data >> gpio_sub_n(gpio))); +-#else + unsigned long flags; ++ int ret; + + if (unlikely(get_gpio_edge(gpio))) { +- int ret; + local_irq_save_hw(flags); + set_gpio_edge(gpio, 0); + ret = get_gpio_data(gpio); + set_gpio_edge(gpio, 1); + local_irq_restore_hw(flags); ++ + return ret; + } else + return get_gpio_data(gpio); +-#endif + } + EXPORT_SYMBOL(bfin_gpio_get_value); + ++ ++int bfin_gpio_direction_input(unsigned gpio) ++{ ++ unsigned long flags; ++ ++ if (!(reserved_gpio_map[gpio_bank(gpio)] & gpio_bit(gpio))) { ++ gpio_error(gpio); ++ return -EINVAL; ++ } ++ ++ local_irq_save_hw(flags); ++ gpio_bankb[gpio_bank(gpio)]->dir &= ~gpio_bit(gpio); ++ gpio_bankb[gpio_bank(gpio)]->inen |= gpio_bit(gpio); ++ AWA_DUMMY_READ(inen); ++ local_irq_restore_hw(flags); ++ ++ return 0; ++} ++EXPORT_SYMBOL(bfin_gpio_direction_input); ++ ++int bfin_gpio_direction_output(unsigned gpio, int value) ++{ ++ unsigned long flags; ++ ++ if (!(reserved_gpio_map[gpio_bank(gpio)] & gpio_bit(gpio))) { ++ gpio_error(gpio); ++ return -EINVAL; ++ } ++ ++ local_irq_save_hw(flags); ++ gpio_bankb[gpio_bank(gpio)]->inen &= ~gpio_bit(gpio); ++ ++ if (value) ++ gpio_bankb[gpio_bank(gpio)]->data_set = gpio_bit(gpio); ++ else ++ gpio_bankb[gpio_bank(gpio)]->data_clear = gpio_bit(gpio); ++ ++ gpio_bankb[gpio_bank(gpio)]->dir |= gpio_bit(gpio); ++ AWA_DUMMY_READ(dir); ++ local_irq_restore_hw(flags); ++ ++ return 0; ++} ++EXPORT_SYMBOL(bfin_gpio_direction_output); ++ + /* If we are booting from SPI and our board lacks a strong enough pull up, + * the core can reset and execute the bootrom faster than the resistor can + * pull the signal logically high. To work around this (common) error in +@@ -1179,15 +1299,23 @@ + * lives here as we need to force all the GPIO states w/out going through + * BUG() checks and such. + */ +-void bfin_reset_boot_spi_cs(unsigned short pin) ++void bfin_gpio_reset_spi0_ssel1(void) + { +- unsigned short gpio = P_IDENT(pin); ++ u16 gpio = P_IDENT(P_SPI0_SSEL1); ++ + port_setup(gpio, GPIO_USAGE); +- gpio_array[gpio_bank(gpio)]->data_set = gpio_bit(gpio); ++ gpio_bankb[gpio_bank(gpio)]->data_set = gpio_bit(gpio); + AWA_DUMMY_READ(data_set); + udelay(1); + } + ++void bfin_gpio_irq_prepare(unsigned gpio) ++{ ++ port_setup(gpio, GPIO_USAGE); ++} ++ ++#endif /*BF548_FAMILY */ ++ + #if defined(CONFIG_PROC_FS) + static int gpio_proc_read(char *buf, char **start, off_t offset, + int len, int *unused_i, void *unused_v) +@@ -1241,7 +1369,11 @@ + + void bfin_gpiolib_set_value(struct gpio_chip *chip, unsigned gpio, int value) + { ++#ifdef BF548_FAMILY + return bfin_gpio_set_value(gpio, value); ++#else ++ return set_gpio_data(gpio, value); ++#endif + } + + int bfin_gpiolib_gpio_request(struct gpio_chip *chip, unsigned gpio) +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/arch/blackfin/kernel/cplb-mpu/cplbinit.c linux-2.6.29-rc3.owrt/arch/blackfin/kernel/cplb-mpu/cplbinit.c +--- linux-2.6.29.owrt/arch/blackfin/kernel/cplb-mpu/cplbinit.c 2009-05-10 22:04:41.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/arch/blackfin/kernel/cplb-mpu/cplbinit.c 2009-05-10 23:48:28.000000000 +0200 +@@ -63,8 +63,10 @@ + dcplb_tbl[cpu][i_d].addr = 0; + dcplb_tbl[cpu][i_d++].data = SDRAM_OOPS | PAGE_SIZE_1KB; + ++#if 0 + icplb_tbl[cpu][i_i].addr = 0; +- icplb_tbl[cpu][i_i++].data = i_cache | CPLB_USER_RD | PAGE_SIZE_1KB; ++ icplb_tbl[cpu][i_i++].data = i_cache | CPLB_USER_RD | PAGE_SIZE_4KB; ++#endif + + /* Cover kernel memory with 4M pages. */ + addr = 0; +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/arch/blackfin/kernel/cplb-nompu/cplbinit.c linux-2.6.29-rc3.owrt/arch/blackfin/kernel/cplb-nompu/cplbinit.c +--- linux-2.6.29.owrt/arch/blackfin/kernel/cplb-nompu/cplbinit.c 2009-05-10 22:04:41.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/arch/blackfin/kernel/cplb-nompu/cplbinit.c 2009-05-10 23:48:28.000000000 +0200 +@@ -53,13 +53,9 @@ + + i_d = i_i = 0; + +-#ifdef CONFIG_DEBUG_HUNT_FOR_ZERO + /* Set up the zero page. */ + d_tbl[i_d].addr = 0; + d_tbl[i_d++].data = SDRAM_OOPS | PAGE_SIZE_1KB; +- i_tbl[i_i].addr = 0; +- i_tbl[i_i++].data = SDRAM_OOPS | PAGE_SIZE_1KB; +-#endif + + /* Cover kernel memory with 4M pages. */ + addr = 0; +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/arch/blackfin/kernel/cplb-nompu/cplbmgr.c linux-2.6.29-rc3.owrt/arch/blackfin/kernel/cplb-nompu/cplbmgr.c +--- linux-2.6.29.owrt/arch/blackfin/kernel/cplb-nompu/cplbmgr.c 2009-05-10 22:04:41.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/arch/blackfin/kernel/cplb-nompu/cplbmgr.c 2009-05-10 23:48:28.000000000 +0200 +@@ -163,14 +163,12 @@ + nr_icplb_supv_miss[cpu]++; + + base = 0; +- idx = 0; +- do { ++ for (idx = 0; idx < icplb_nr_bounds; idx++) { + eaddr = icplb_bounds[idx].eaddr; + if (addr < eaddr) + break; + base = eaddr; +- } while (++idx < icplb_nr_bounds); +- ++ } + if (unlikely(idx == icplb_nr_bounds)) + return CPLB_NO_ADDR_MATCH; + +@@ -210,14 +208,12 @@ + nr_dcplb_supv_miss[cpu]++; + + base = 0; +- idx = 0; +- do { ++ for (idx = 0; idx < dcplb_nr_bounds; idx++) { + eaddr = dcplb_bounds[idx].eaddr; + if (addr < eaddr) + break; + base = eaddr; +- } while (++idx < dcplb_nr_bounds); +- ++ } + if (unlikely(idx == dcplb_nr_bounds)) + return CPLB_NO_ADDR_MATCH; + +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/arch/blackfin/kernel/ipipe.c linux-2.6.29-rc3.owrt/arch/blackfin/kernel/ipipe.c +--- linux-2.6.29.owrt/arch/blackfin/kernel/ipipe.c 2009-05-10 22:04:41.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/arch/blackfin/kernel/ipipe.c 2009-05-10 23:48:28.000000000 +0200 +@@ -35,8 +35,14 @@ + #include <asm/atomic.h> + #include <asm/io.h> + ++static int create_irq_threads; ++ + DEFINE_PER_CPU(struct pt_regs, __ipipe_tick_regs); + ++static DEFINE_PER_CPU(unsigned long, pending_irqthread_mask); ++ ++static DEFINE_PER_CPU(int [IVG13 + 1], pending_irq_count); ++ + asmlinkage void asm_do_IRQ(unsigned int irq, struct pt_regs *regs); + + static void __ipipe_no_irqtail(void); +@@ -87,7 +93,6 @@ + */ + void __ipipe_handle_irq(unsigned irq, struct pt_regs *regs) + { +- struct ipipe_percpu_domain_data *p = ipipe_root_cpudom_ptr(); + struct ipipe_domain *this_domain, *next_domain; + struct list_head *head, *pos; + int m_ack, s = -1; +@@ -99,6 +104,7 @@ + * interrupt. + */ + m_ack = (regs == NULL || irq == IRQ_SYSTMR || irq == IRQ_CORETMR); ++ + this_domain = ipipe_current_domain; + + if (unlikely(test_bit(IPIPE_STICKY_FLAG, &this_domain->irqs[irq].control))) +@@ -108,28 +114,49 @@ + next_domain = list_entry(head, struct ipipe_domain, p_link); + if (likely(test_bit(IPIPE_WIRED_FLAG, &next_domain->irqs[irq].control))) { + if (!m_ack && next_domain->irqs[irq].acknowledge != NULL) +- next_domain->irqs[irq].acknowledge(irq, irq_to_desc(irq)); +- if (test_bit(IPIPE_SYNCDEFER_FLAG, &p->status)) +- s = __test_and_set_bit(IPIPE_STALL_FLAG, &p->status); ++ next_domain->irqs[irq].acknowledge(irq, irq_desc + irq); ++ if (test_bit(IPIPE_ROOTLOCK_FLAG, &ipipe_root_domain->flags)) ++ s = __test_and_set_bit(IPIPE_STALL_FLAG, ++ &ipipe_root_cpudom_var(status)); + __ipipe_dispatch_wired(next_domain, irq); +- goto out; ++ goto finalize; ++ return; + } + } + + /* Ack the interrupt. */ + + pos = head; ++ + while (pos != &__ipipe_pipeline) { + next_domain = list_entry(pos, struct ipipe_domain, p_link); ++ /* ++ * For each domain handling the incoming IRQ, mark it ++ * as pending in its log. ++ */ + if (test_bit(IPIPE_HANDLE_FLAG, &next_domain->irqs[irq].control)) { ++ /* ++ * Domains that handle this IRQ are polled for ++ * acknowledging it by decreasing priority ++ * order. The interrupt must be made pending ++ * _first_ in the domain's status flags before ++ * the PIC is unlocked. ++ */ + __ipipe_set_irq_pending(next_domain, irq); ++ + if (!m_ack && next_domain->irqs[irq].acknowledge != NULL) { +- next_domain->irqs[irq].acknowledge(irq, irq_to_desc(irq)); ++ next_domain->irqs[irq].acknowledge(irq, irq_desc + irq); + m_ack = 1; + } + } ++ ++ /* ++ * If the domain does not want the IRQ to be passed ++ * down the interrupt pipe, exit the loop now. ++ */ + if (!test_bit(IPIPE_PASS_FLAG, &next_domain->irqs[irq].control)) + break; ++ + pos = next_domain->p_link.next; + } + +@@ -139,24 +166,18 @@ + * immediately to the current domain if the interrupt has been + * marked as 'sticky'. This search does not go beyond the + * current domain in the pipeline. We also enforce the +- * additional root stage lock (blackfin-specific). +- */ +- if (test_bit(IPIPE_SYNCDEFER_FLAG, &p->status)) +- s = __test_and_set_bit(IPIPE_STALL_FLAG, &p->status); ++ * additional root stage lock (blackfin-specific). */ + +- /* +- * If the interrupt preempted the head domain, then do not +- * even try to walk the pipeline, unless an interrupt is +- * pending for it. +- */ +- if (test_bit(IPIPE_AHEAD_FLAG, &this_domain->flags) && +- ipipe_head_cpudom_var(irqpend_himask) == 0) +- goto out; ++ if (test_bit(IPIPE_ROOTLOCK_FLAG, &ipipe_root_domain->flags)) ++ s = __test_and_set_bit(IPIPE_STALL_FLAG, ++ &ipipe_root_cpudom_var(status)); ++finalize: + + __ipipe_walk_pipeline(head); +-out: ++ + if (!s) +- __clear_bit(IPIPE_STALL_FLAG, &p->status); ++ __clear_bit(IPIPE_STALL_FLAG, ++ &ipipe_root_cpudom_var(status)); + } + + int __ipipe_check_root(void) +@@ -166,7 +187,7 @@ + + void __ipipe_enable_irqdesc(struct ipipe_domain *ipd, unsigned irq) + { +- struct irq_desc *desc = irq_to_desc(irq); ++ struct irq_desc *desc = irq_desc + irq; + int prio = desc->ic_prio; + + desc->depth = 0; +@@ -178,7 +199,7 @@ + + void __ipipe_disable_irqdesc(struct ipipe_domain *ipd, unsigned irq) + { +- struct irq_desc *desc = irq_to_desc(irq); ++ struct irq_desc *desc = irq_desc + irq; + int prio = desc->ic_prio; + + if (ipd != &ipipe_root && +@@ -215,18 +236,15 @@ + { + unsigned long flags; + +- /* +- * We need to run the IRQ tail hook whenever we don't ++ /* We need to run the IRQ tail hook whenever we don't + * propagate a syscall to higher domains, because we know that + * important operations might be pending there (e.g. Xenomai +- * deferred rescheduling). +- */ ++ * deferred rescheduling). */ + +- if (regs->orig_p0 < NR_syscalls) { ++ if (!__ipipe_syscall_watched_p(current, regs->orig_p0)) { + void (*hook)(void) = (void (*)(void))__ipipe_irq_tail_hook; + hook(); +- if ((current->flags & PF_EVNOTIFY) == 0) +- return 0; ++ return 0; + } + + /* +@@ -294,46 +312,112 @@ + { + unsigned long flags; + +-#ifdef CONFIG_IPIPE_DEBUG + if (irq >= IPIPE_NR_IRQS || + (ipipe_virtual_irq_p(irq) + && !test_bit(irq - IPIPE_VIRQ_BASE, &__ipipe_virtual_irq_map))) + return -EINVAL; +-#endif + + local_irq_save_hw(flags); ++ + __ipipe_handle_irq(irq, NULL); ++ + local_irq_restore_hw(flags); + + return 1; + } + +-asmlinkage void __ipipe_sync_root(void) ++/* Move Linux IRQ to threads. */ ++ ++static int do_irqd(void *__desc) + { +- unsigned long flags; ++ struct irq_desc *desc = __desc; ++ unsigned irq = desc - irq_desc; ++ int thrprio = desc->thr_prio; ++ int thrmask = 1 << thrprio; ++ int cpu = smp_processor_id(); ++ cpumask_t cpumask; ++ ++ sigfillset(¤t->blocked); ++ current->flags |= PF_NOFREEZE; ++ cpumask = cpumask_of_cpu(cpu); ++ set_cpus_allowed(current, cpumask); ++ ipipe_setscheduler_root(current, SCHED_FIFO, 50 + thrprio); ++ ++ while (!kthread_should_stop()) { ++ local_irq_disable(); ++ if (!(desc->status & IRQ_SCHEDULED)) { ++ set_current_state(TASK_INTERRUPTIBLE); ++resched: ++ local_irq_enable(); ++ schedule(); ++ local_irq_disable(); ++ } ++ __set_current_state(TASK_RUNNING); ++ /* ++ * If higher priority interrupt servers are ready to ++ * run, reschedule immediately. We need this for the ++ * GPIO demux IRQ handler to unmask the interrupt line ++ * _last_, after all GPIO IRQs have run. ++ */ ++ if (per_cpu(pending_irqthread_mask, cpu) & ~(thrmask|(thrmask-1))) ++ goto resched; ++ if (--per_cpu(pending_irq_count[thrprio], cpu) == 0) ++ per_cpu(pending_irqthread_mask, cpu) &= ~thrmask; ++ desc->status &= ~IRQ_SCHEDULED; ++ desc->thr_handler(irq, &__raw_get_cpu_var(__ipipe_tick_regs)); ++ local_irq_enable(); ++ } ++ __set_current_state(TASK_RUNNING); ++ return 0; ++} + +- BUG_ON(irqs_disabled()); ++static void kick_irqd(unsigned irq, void *cookie) ++{ ++ struct irq_desc *desc = irq_desc + irq; ++ int thrprio = desc->thr_prio; ++ int thrmask = 1 << thrprio; ++ int cpu = smp_processor_id(); ++ ++ if (!(desc->status & IRQ_SCHEDULED)) { ++ desc->status |= IRQ_SCHEDULED; ++ per_cpu(pending_irqthread_mask, cpu) |= thrmask; ++ ++per_cpu(pending_irq_count[thrprio], cpu); ++ wake_up_process(desc->thread); ++ } ++} + +- local_irq_save_hw(flags); ++int ipipe_start_irq_thread(unsigned irq, struct irq_desc *desc) ++{ ++ if (desc->thread || !create_irq_threads) ++ return 0; + +- clear_thread_flag(TIF_IRQ_SYNC); ++ desc->thread = kthread_create(do_irqd, desc, "IRQ %d", irq); ++ if (desc->thread == NULL) { ++ printk(KERN_ERR "irqd: could not create IRQ thread %d!\n", irq); ++ return -ENOMEM; ++ } + +- if (ipipe_root_cpudom_var(irqpend_himask) != 0) +- __ipipe_sync_pipeline(IPIPE_IRQMASK_ANY); ++ wake_up_process(desc->thread); + +- local_irq_restore_hw(flags); ++ desc->thr_handler = ipipe_root_domain->irqs[irq].handler; ++ ipipe_root_domain->irqs[irq].handler = &kick_irqd; ++ ++ return 0; + } + +-void ___ipipe_sync_pipeline(unsigned long syncmask) ++void __init ipipe_init_irq_threads(void) + { +- struct ipipe_domain *ipd = ipipe_current_domain; ++ unsigned irq; ++ struct irq_desc *desc; + +- if (ipd == ipipe_root_domain) { +- if (test_bit(IPIPE_SYNCDEFER_FLAG, &ipipe_root_cpudom_var(status))) +- return; +- } ++ create_irq_threads = 1; + +- __ipipe_sync_stage(syncmask); ++ for (irq = 0; irq < NR_IRQS; irq++) { ++ desc = irq_desc + irq; ++ if (desc->action != NULL || ++ (desc->status & IRQ_NOREQUEST) != 0) ++ ipipe_start_irq_thread(irq, desc); ++ } + } + + EXPORT_SYMBOL(show_stack); +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/arch/blackfin/kernel/irqchip.c linux-2.6.29-rc3.owrt/arch/blackfin/kernel/irqchip.c +--- linux-2.6.29.owrt/arch/blackfin/kernel/irqchip.c 2009-05-10 22:04:41.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/arch/blackfin/kernel/irqchip.c 2009-05-10 23:48:28.000000000 +0200 +@@ -35,7 +35,6 @@ + #include <linux/interrupt.h> + #include <linux/irq.h> + #include <asm/trace.h> +-#include <asm/pda.h> + + static atomic_t irq_err_count; + static spinlock_t irq_controller_lock; +@@ -92,13 +91,8 @@ + seq_putc(p, '\n'); + skip: + spin_unlock_irqrestore(&irq_desc[i].lock, flags); +- } else if (i == NR_IRQS) { +- seq_printf(p, "NMI: "); +- for_each_online_cpu(j) +- seq_printf(p, "%10u ", cpu_pda[j].__nmi_count); +- seq_printf(p, " CORE Non Maskable Interrupt\n"); ++ } else if (i == NR_IRQS) + seq_printf(p, "Err: %10u\n", atomic_read(&irq_err_count)); +- } + return 0; + } + +@@ -144,15 +138,11 @@ + #endif + generic_handle_irq(irq); + +-#ifndef CONFIG_IPIPE +- /* +- * If we're the only interrupt running (ignoring IRQ15 which +- * is for syscalls), lower our priority to IRQ14 so that +- * softirqs run at that level. If there's another, +- * lower-level interrupt, irq_exit will defer softirqs to +- * that. If the interrupt pipeline is enabled, we are already +- * running at IRQ14 priority, so we don't need this code. +- */ ++#ifndef CONFIG_IPIPE /* Useless and bugous over the I-pipe: IRQs are threaded. */ ++ /* If we're the only interrupt running (ignoring IRQ15 which is for ++ syscalls), lower our priority to IRQ14 so that softirqs run at ++ that level. If there's another, lower-level interrupt, irq_exit ++ will defer softirqs to that. */ + CSYNC(); + pending = bfin_read_IPEND() & ~0x8000; + other_ints = pending & (pending - 1); +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/arch/blackfin/kernel/kgdb_test.c linux-2.6.29-rc3.owrt/arch/blackfin/kernel/kgdb_test.c +--- linux-2.6.29.owrt/arch/blackfin/kernel/kgdb_test.c 2009-05-10 22:04:41.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/arch/blackfin/kernel/kgdb_test.c 2009-05-10 23:48:28.000000000 +0200 +@@ -20,7 +20,6 @@ + static char cmdline[256]; + static unsigned long len; + +-#ifndef CONFIG_SMP + static int num1 __attribute__((l1_data)); + + void kgdb_l1_test(void) __attribute__((l1_text)); +@@ -33,8 +32,6 @@ + printk(KERN_ALERT "L1(after change) : data variable addr = 0x%p, data value is %d\n", &num1, num1); + return ; + } +-#endif +- + #if L2_LENGTH + + static int num2 __attribute__((l2)); +@@ -62,12 +59,10 @@ + static int test_proc_output(char *buf) + { + kgdb_test("hello world!", 12, 0x55, 0x10); +-#ifndef CONFIG_SMP + kgdb_l1_test(); +-#endif +-#if L2_LENGTH ++ #if L2_LENGTH + kgdb_l2_test(); +-#endif ++ #endif + + return 0; + } +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/arch/blackfin/kernel/Makefile linux-2.6.29-rc3.owrt/arch/blackfin/kernel/Makefile +--- linux-2.6.29.owrt/arch/blackfin/kernel/Makefile 2009-05-10 22:04:41.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/arch/blackfin/kernel/Makefile 2009-05-10 23:48:28.000000000 +0200 +@@ -21,9 +21,5 @@ + obj-$(CONFIG_CPLB_INFO) += cplbinfo.o + obj-$(CONFIG_MODULES) += module.o + obj-$(CONFIG_KGDB) += kgdb.o +-obj-$(CONFIG_KGDB_TESTS) += kgdb_test.o ++obj-$(CONFIG_KGDB_TESTCASE) += kgdb_test.o + obj-$(CONFIG_EARLY_PRINTK) += early_printk.o +- +-# the kgdb test puts code into L2 and without linker +-# relaxation, we need to force long calls to/from it +-CFLAGS_kgdb_test.o := -mlong-calls -O0 +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/arch/blackfin/kernel/ptrace.c linux-2.6.29-rc3.owrt/arch/blackfin/kernel/ptrace.c +--- linux-2.6.29.owrt/arch/blackfin/kernel/ptrace.c 2009-05-10 22:04:41.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/arch/blackfin/kernel/ptrace.c 2009-05-10 23:48:28.000000000 +0200 +@@ -45,7 +45,6 @@ + #include <asm/asm-offsets.h> + #include <asm/dma.h> + #include <asm/fixed_code.h> +-#include <asm/cacheflush.h> + #include <asm/mem_map.h> + + #define TEXT_OFFSET 0 +@@ -241,7 +240,7 @@ + + } else if (addr >= FIXED_CODE_START + && addr + sizeof(tmp) <= FIXED_CODE_END) { +- copy_from_user_page(0, 0, 0, &tmp, (const void *)(addr), sizeof(tmp)); ++ memcpy(&tmp, (const void *)(addr), sizeof(tmp)); + copied = sizeof(tmp); + + } else +@@ -321,7 +320,7 @@ + + } else if (addr >= FIXED_CODE_START + && addr + sizeof(data) <= FIXED_CODE_END) { +- copy_to_user_page(0, 0, 0, (void *)(addr), &data, sizeof(data)); ++ memcpy((void *)(addr), &data, sizeof(data)); + copied = sizeof(data); + + } else +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/arch/blackfin/kernel/reboot.c linux-2.6.29-rc3.owrt/arch/blackfin/kernel/reboot.c +--- linux-2.6.29.owrt/arch/blackfin/kernel/reboot.c 2009-05-10 22:04:41.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/arch/blackfin/kernel/reboot.c 2009-05-10 23:48:28.000000000 +0200 +@@ -20,8 +20,8 @@ + * reset while the Core B bit (on dual core parts) is cleared by + * the core reset. + */ +-__attribute__ ((__l1_text__, __noreturn__)) +-static void bfin_reset(void) ++__attribute__((l1_text)) ++static void _bfin_reset(void) + { + /* Wait for completion of "system" events such as cache line + * line fills so that we avoid infinite stalls later on as +@@ -30,11 +30,7 @@ + */ + __builtin_bfin_ssync(); + +- /* The bootrom checks to see how it was reset and will +- * automatically perform a software reset for us when +- * it starts executing after the core reset. +- */ +- if (ANOMALY_05000353 || ANOMALY_05000386) { ++ while (1) { + /* Initiate System software reset. */ + bfin_write_SWRST(0x7); + +@@ -54,11 +50,6 @@ + /* Clear System software reset */ + bfin_write_SWRST(0); + +- /* The BF526 ROM will crash during reset */ +-#if defined(__ADSPBF522__) || defined(__ADSPBF524__) || defined(__ADSPBF526__) +- bfin_read_SWRST(); +-#endif +- + /* Wait for the SWRST write to complete. Cannot rely on SSYNC + * though as the System state is all reset now. + */ +@@ -69,11 +60,22 @@ + : "a" (15 * 1) + : "LC1", "LB1", "LT1" + ); +- } + +- while (1) + /* Issue core reset */ + asm("raise 1"); ++ } ++} ++ ++static void bfin_reset(void) ++{ ++ if (ANOMALY_05000353 || ANOMALY_05000386) ++ _bfin_reset(); ++ else ++ /* the bootrom checks to see how it was reset and will ++ * automatically perform a software reset for us when ++ * it starts executing boot ++ */ ++ asm("raise 1;"); + } + + __attribute__((weak)) +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/arch/blackfin/kernel/setup.c linux-2.6.29-rc3.owrt/arch/blackfin/kernel/setup.c +--- linux-2.6.29.owrt/arch/blackfin/kernel/setup.c 2009-05-10 22:04:41.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/arch/blackfin/kernel/setup.c 2009-05-10 23:48:28.000000000 +0200 +@@ -60,7 +60,7 @@ + #define BFIN_MEMMAP_MAX 128 /* number of entries in bfin_memmap */ + #define BFIN_MEMMAP_RAM 1 + #define BFIN_MEMMAP_RESERVED 2 +-static struct bfin_memmap { ++struct bfin_memmap { + int nr_map; + struct bfin_memmap_entry { + unsigned long long addr; /* start of memory segment */ +@@ -824,15 +824,7 @@ + flash_probe(); + #endif + +- printk(KERN_INFO "Boot Mode: %i\n", bfin_read_SYSCR() & 0xF); +- +- /* Newer parts mirror SWRST bits in SYSCR */ +-#if defined(CONFIG_BF53x) || defined(CONFIG_BF561) || \ +- defined(CONFIG_BF538) || defined(CONFIG_BF539) + _bfin_swrst = bfin_read_SWRST(); +-#else +- _bfin_swrst = bfin_read_SYSCR(); +-#endif + + #ifdef CONFIG_DEBUG_DOUBLEFAULT_PRINT + bfin_write_SWRST(_bfin_swrst & ~DOUBLE_FAULT); +@@ -861,7 +853,7 @@ + else if (_bfin_swrst & RESET_SOFTWARE) + printk(KERN_NOTICE "Reset caused by Software reset\n"); + +- printk(KERN_INFO "Blackfin support (C) 2004-2009 Analog Devices, Inc.\n"); ++ printk(KERN_INFO "Blackfin support (C) 2004-2008 Analog Devices, Inc.\n"); + if (bfin_compiled_revid() == 0xffff) + printk(KERN_INFO "Compiled for ADSP-%s Rev any\n", CPU); + else if (bfin_compiled_revid() == -1) +@@ -889,10 +881,6 @@ + CPU, bfin_revid()); + } + +- /* We can't run on BF548-0.1 due to ANOMALY 05000448 */ +- if (bfin_cpuid() == 0x27de && bfin_revid() == 1) +- panic("You can't run on this processor due to 05000448\n"); +- + printk(KERN_INFO "Blackfin Linux support by http://blackfin.uclinux.org/\n"); + + printk(KERN_INFO "Processor Speed: %lu MHz core clock and %lu MHz System Clock\n", +@@ -1145,12 +1133,12 @@ + icache_size = 0; + + seq_printf(m, "cache size\t: %d KB(L1 icache) " +- "%d KB(L1 dcache%s) %d KB(L2 cache)\n", ++ "%d KB(L1 dcache-%s) %d KB(L2 cache)\n", + icache_size, dcache_size, + #if defined CONFIG_BFIN_WB +- "-wb" ++ "wb" + #elif defined CONFIG_BFIN_WT +- "-wt" ++ "wt" + #endif + "", 0); + +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/arch/blackfin/kernel/time.c linux-2.6.29-rc3.owrt/arch/blackfin/kernel/time.c +--- linux-2.6.29.owrt/arch/blackfin/kernel/time.c 2009-05-10 22:04:41.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/arch/blackfin/kernel/time.c 2009-05-10 23:48:28.000000000 +0200 +@@ -134,10 +134,7 @@ + + write_seqlock(&xtime_lock); + #if defined(CONFIG_TICK_SOURCE_SYSTMR0) && !defined(CONFIG_IPIPE) +- /* +- * TIMIL0 is latched in __ipipe_grab_irq() when the I-Pipe is +- * enabled. +- */ ++/* FIXME: Here TIMIL0 is not set when IPIPE enabled, why? */ + if (get_gptimer_status(0) & TIMER_STATUS_TIMIL0) { + #endif + do_timer(1); +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/arch/blackfin/kernel/traps.c linux-2.6.29-rc3.owrt/arch/blackfin/kernel/traps.c +--- linux-2.6.29.owrt/arch/blackfin/kernel/traps.c 2009-05-10 22:04:41.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/arch/blackfin/kernel/traps.c 2009-05-10 23:48:28.000000000 +0200 +@@ -673,14 +673,6 @@ + verbose_printk("RTI"); + else if (opcode == 0x0012) + verbose_printk("RTX"); +- else if (opcode == 0x0013) +- verbose_printk("RTN"); +- else if (opcode == 0x0014) +- verbose_printk("RTE"); +- else if (opcode == 0x0025) +- verbose_printk("EMUEXCPT"); +- else if (opcode == 0x0040 && opcode <= 0x0047) +- verbose_printk("STI R%i", opcode & 7); + else if (opcode >= 0x0050 && opcode <= 0x0057) + verbose_printk("JUMP (P%i)", opcode & 7); + else if (opcode >= 0x0060 && opcode <= 0x0067) +@@ -689,10 +681,6 @@ + verbose_printk("CALL (PC+P%i)", opcode & 7); + else if (opcode >= 0x0080 && opcode <= 0x0087) + verbose_printk("JUMP (PC+P%i)", opcode & 7); +- else if (opcode >= 0x0090 && opcode <= 0x009F) +- verbose_printk("RAISE 0x%x", opcode & 0xF); +- else if (opcode >= 0x00A0 && opcode <= 0x00AF) +- verbose_printk("EXCPT 0x%x", opcode & 0xF); + else if ((opcode >= 0x1000 && opcode <= 0x13FF) || (opcode >= 0x1800 && opcode <= 0x1BFF)) + verbose_printk("IF !CC JUMP"); + else if ((opcode >= 0x1400 && opcode <= 0x17ff) || (opcode >= 0x1c00 && opcode <= 0x1fff)) +@@ -832,8 +820,11 @@ + decode_address(buf, (unsigned int)stack); + printk(KERN_NOTICE " SP: [0x%p] %s\n", stack, buf); + ++ addr = (unsigned int *)((unsigned int)stack & ~0x3F); ++ + /* First thing is to look for a frame pointer */ +- for (addr = (unsigned int *)((unsigned int)stack & ~0xF); addr < endstack; addr++) { ++ for (addr = (unsigned int *)((unsigned int)stack & ~0xF), i = 0; ++ addr < endstack; addr++, i++) { + if (*addr & 0x1) + continue; + ins_addr = (unsigned short *)*addr; +@@ -843,8 +834,7 @@ + + if (fp) { + /* Let's check to see if it is a frame pointer */ +- while (fp >= (addr - 1) && fp < endstack +- && fp && ((unsigned int) fp & 0x3) == 0) ++ while (fp >= (addr - 1) && fp < endstack && fp) + fp = (unsigned int *)*fp; + if (fp == 0 || fp == endstack) { + fp = addr - 1; +@@ -1062,9 +1052,8 @@ + char buf [150]; + struct irqaction *action; + unsigned int i; +- unsigned long flags = 0; ++ unsigned long flags; + unsigned int cpu = smp_processor_id(); +- unsigned char in_atomic = (bfin_read_IPEND() & 0x10) || in_atomic(); + + verbose_printk(KERN_NOTICE "\n" KERN_NOTICE "SEQUENCER STATUS:\t\t%s\n", print_tainted()); + verbose_printk(KERN_NOTICE " SEQSTAT: %08lx IPEND: %04lx SYSCFG: %04lx\n", +@@ -1084,22 +1073,17 @@ + } + verbose_printk(KERN_NOTICE " EXCAUSE : 0x%lx\n", + fp->seqstat & SEQSTAT_EXCAUSE); +- for (i = 2; i <= 15 ; i++) { ++ for (i = 6; i <= 15 ; i++) { + if (fp->ipend & (1 << i)) { +- if (i != 4) { +- decode_address(buf, bfin_read32(EVT0 + 4*i)); +- verbose_printk(KERN_NOTICE " physical IVG%i asserted : %s\n", i, buf); +- } else +- verbose_printk(KERN_NOTICE " interrupts disabled\n"); ++ decode_address(buf, bfin_read32(EVT0 + 4*i)); ++ verbose_printk(KERN_NOTICE " physical IVG%i asserted : %s\n", i, buf); + } + } + + /* if no interrupts are going off, don't print this out */ + if (fp->ipend & ~0x3F) { + for (i = 0; i < (NR_IRQS - 1); i++) { +- if (!in_atomic) +- spin_lock_irqsave(&irq_desc[i].lock, flags); +- ++ spin_lock_irqsave(&irq_desc[i].lock, flags); + action = irq_desc[i].action; + if (!action) + goto unlock; +@@ -1112,8 +1096,7 @@ + } + verbose_printk("\n"); + unlock: +- if (!in_atomic) +- spin_unlock_irqrestore(&irq_desc[i].lock, flags); ++ spin_unlock_irqrestore(&irq_desc[i].lock, flags); + } + } + +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/arch/blackfin/mach-bf518/boards/ezbrd.c linux-2.6.29-rc3.owrt/arch/blackfin/mach-bf518/boards/ezbrd.c +--- linux-2.6.29.owrt/arch/blackfin/mach-bf518/boards/ezbrd.c 2009-05-10 22:04:41.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/arch/blackfin/mach-bf518/boards/ezbrd.c 2009-05-10 23:48:28.000000000 +0200 +@@ -46,7 +46,6 @@ + #include <asm/dpmc.h> + #include <asm/bfin_sdh.h> + #include <linux/spi/ad7877.h> +-#include <net/dsa.h> + + /* + * Name the Board for the /proc/cpuinfo +@@ -105,33 +104,10 @@ + #endif + + #if defined(CONFIG_BFIN_MAC) || defined(CONFIG_BFIN_MAC_MODULE) +-static struct platform_device bfin_mii_bus = { +- .name = "bfin_mii_bus", +-}; +- + static struct platform_device bfin_mac_device = { + .name = "bfin_mac", +- .dev.platform_data = &bfin_mii_bus, +-}; +- +-#if defined(CONFIG_NET_DSA_KSZ8893M) || defined(CONFIG_NET_DSA_KSZ8893M_MODULE) +-static struct dsa_platform_data ksz8893m_switch_data = { +- .mii_bus = &bfin_mii_bus.dev, +- .netdev = &bfin_mac_device.dev, +- .port_names[0] = NULL, +- .port_names[1] = "eth%d", +- .port_names[2] = "eth%d", +- .port_names[3] = "cpu", +-}; +- +-static struct platform_device ksz8893m_switch_device = { +- .name = "dsa", +- .id = 0, +- .num_resources = 0, +- .dev.platform_data = &ksz8893m_switch_data, + }; + #endif +-#endif + + #if defined(CONFIG_MTD_M25P80) \ + || defined(CONFIG_MTD_M25P80_MODULE) +@@ -171,20 +147,9 @@ + }; + #endif + +-#if defined(CONFIG_BFIN_MAC) || defined(CONFIG_BFIN_MAC_MODULE) +-#if defined(CONFIG_NET_DSA_KSZ8893M) \ +- || defined(CONFIG_NET_DSA_KSZ8893M_MODULE) +-/* SPI SWITCH CHIP */ +-static struct bfin5xx_spi_chip spi_switch_info = { +- .enable_dma = 0, +- .bits_per_word = 8, +-}; +-#endif +-#endif +- +-#if defined(CONFIG_MMC_SPI) || defined(CONFIG_MMC_SPI_MODULE) +-static struct bfin5xx_spi_chip mmc_spi_chip_info = { +- .enable_dma = 0, ++#if defined(CONFIG_SPI_MMC) || defined(CONFIG_SPI_MMC_MODULE) ++static struct bfin5xx_spi_chip spi_mmc_chip_info = { ++ .enable_dma = 1, + .bits_per_word = 8, + }; + #endif +@@ -261,28 +226,23 @@ + }, + #endif + +-#if defined(CONFIG_BFIN_MAC) || defined(CONFIG_BFIN_MAC_MODULE) +-#if defined(CONFIG_NET_DSA_KSZ8893M) \ +- || defined(CONFIG_NET_DSA_KSZ8893M_MODULE) ++#if defined(CONFIG_SPI_MMC) || defined(CONFIG_SPI_MMC_MODULE) + { +- .modalias = "ksz8893m", +- .max_speed_hz = 5000000, ++ .modalias = "spi_mmc_dummy", ++ .max_speed_hz = 25000000, /* max spi clock (SCK) speed in HZ */ + .bus_num = 0, +- .chip_select = 1, ++ .chip_select = 0, + .platform_data = NULL, +- .controller_data = &spi_switch_info, ++ .controller_data = &spi_mmc_chip_info, + .mode = SPI_MODE_3, + }, +-#endif +-#endif +- +-#if defined(CONFIG_MMC_SPI) || defined(CONFIG_MMC_SPI_MODULE) + { +- .modalias = "mmc_spi", ++ .modalias = "spi_mmc", + .max_speed_hz = 25000000, /* max spi clock (SCK) speed in HZ */ + .bus_num = 0, +- .chip_select = 5, +- .controller_data = &mmc_spi_chip_info, ++ .chip_select = CONFIG_SPI_MMC_CS_CHAN, ++ .platform_data = NULL, ++ .controller_data = &spi_mmc_chip_info, + .mode = SPI_MODE_3, + }, + #endif +@@ -513,6 +473,7 @@ + }; + #endif + ++#ifdef CONFIG_I2C_BOARDINFO + static struct i2c_board_info __initdata bfin_i2c_board_info[] = { + #if defined(CONFIG_TWI_LCD) || defined(CONFIG_TWI_LCD_MODULE) + { +@@ -526,6 +487,7 @@ + }, + #endif + }; ++#endif + + #if defined(CONFIG_SERIAL_BFIN_SPORT) || defined(CONFIG_SERIAL_BFIN_SPORT_MODULE) + static struct platform_device bfin_sport0_uart_device = { +@@ -622,11 +584,7 @@ + #endif + + #if defined(CONFIG_BFIN_MAC) || defined(CONFIG_BFIN_MAC_MODULE) +- &bfin_mii_bus, + &bfin_mac_device, +-#if defined(CONFIG_NET_DSA_KSZ8893M) || defined(CONFIG_NET_DSA_KSZ8893M_MODULE) +- &ksz8893m_switch_device, +-#endif + #endif + + #if defined(CONFIG_SPI_BFIN) || defined(CONFIG_SPI_BFIN_MODULE) +@@ -674,8 +632,12 @@ + static int __init ezbrd_init(void) + { + printk(KERN_INFO "%s(): registering device resources\n", __func__); ++ ++#ifdef CONFIG_I2C_BOARDINFO + i2c_register_board_info(0, bfin_i2c_board_info, + ARRAY_SIZE(bfin_i2c_board_info)); ++#endif ++ + platform_add_devices(stamp_devices, ARRAY_SIZE(stamp_devices)); + spi_register_board_info(bfin_spi_board_info, ARRAY_SIZE(bfin_spi_board_info)); + return 0; +@@ -687,7 +649,7 @@ + { + /* workaround reboot hang when booting from SPI */ + if ((bfin_read_SYSCR() & 0x7) == 0x3) +- bfin_reset_boot_spi_cs(P_DEFAULT_BOOT_SPI_CS); ++ bfin_gpio_reset_spi0_ssel1(); + } + + void bfin_get_ether_addr(char *addr) +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/arch/blackfin/mach-bf518/include/mach/anomaly.h linux-2.6.29-rc3.owrt/arch/blackfin/mach-bf518/include/mach/anomaly.h +--- linux-2.6.29.owrt/arch/blackfin/mach-bf518/include/mach/anomaly.h 2009-05-10 22:04:41.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/arch/blackfin/mach-bf518/include/mach/anomaly.h 2009-05-10 23:48:28.000000000 +0200 +@@ -2,12 +2,12 @@ + * File: include/asm-blackfin/mach-bf518/anomaly.h + * Bugs: Enter bugs at http://blackfin.uclinux.org/ + * +- * Copyright (C) 2004-2009 Analog Devices Inc. ++ * Copyright (C) 2004-2008 Analog Devices Inc. + * Licensed under the GPL-2 or later. + */ + + /* This file shoule be up to date with: +- * - Revision B, 02/03/2009; ADSP-BF512/BF514/BF516/BF518 Blackfin Processor Anomaly List ++ * - ???? + */ + + #ifndef _MACH_ANOMALY_H_ +@@ -19,8 +19,6 @@ + #define ANOMALY_05000122 (1) + /* False Hardware Error from an Access in the Shadow of a Conditional Branch */ + #define ANOMALY_05000245 (1) +-/* Incorrect Timer Pulse Width in Single-Shot PWM_OUT Mode with External Clock */ +-#define ANOMALY_05000254 (1) + /* Sensitivity To Noise with Slow Input Edge Rates on External SPORT TX and RX Clocks */ + #define ANOMALY_05000265 (1) + /* False Hardware Errors Caused by Fetches at the Boundary of Reserved Memory */ +@@ -55,12 +53,6 @@ + #define ANOMALY_05000443 (1) + /* Incorrect L1 Instruction Bank B Memory Map Location */ + #define ANOMALY_05000444 (1) +-/* Incorrect Default Hysteresis Setting for RESET, NMI, and BMODE Signals */ +-#define ANOMALY_05000452 (1) +-/* PWM_TRIPB Signal Not Available on PG10 */ +-#define ANOMALY_05000453 (1) +-/* PPI_FS3 is Driven One Half Cycle Later Than PPI Data */ +-#define ANOMALY_05000455 (1) + + /* Anomalies that don't exist on this proc */ + #define ANOMALY_05000125 (0) +@@ -73,20 +65,15 @@ + #define ANOMALY_05000263 (0) + #define ANOMALY_05000266 (0) + #define ANOMALY_05000273 (0) +-#define ANOMALY_05000278 (0) + #define ANOMALY_05000285 (0) +-#define ANOMALY_05000305 (0) + #define ANOMALY_05000307 (0) + #define ANOMALY_05000311 (0) + #define ANOMALY_05000312 (0) + #define ANOMALY_05000323 (0) + #define ANOMALY_05000353 (0) + #define ANOMALY_05000363 (0) +-#define ANOMALY_05000380 (0) + #define ANOMALY_05000386 (0) + #define ANOMALY_05000412 (0) + #define ANOMALY_05000432 (0) +-#define ANOMALY_05000447 (0) +-#define ANOMALY_05000448 (0) + + #endif +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/arch/blackfin/mach-bf518/include/mach/bfin_serial_5xx.h linux-2.6.29-rc3.owrt/arch/blackfin/mach-bf518/include/mach/bfin_serial_5xx.h +--- linux-2.6.29.owrt/arch/blackfin/mach-bf518/include/mach/bfin_serial_5xx.h 2009-05-10 22:04:41.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/arch/blackfin/mach-bf518/include/mach/bfin_serial_5xx.h 2009-05-10 23:48:28.000000000 +0200 +@@ -144,7 +144,7 @@ + CH_UART0_TX, + CH_UART0_RX, + #endif +-#ifdef CONFIG_SERIAL_BFIN_CTSRTS ++#ifdef CONFIG_BFIN_UART0_CTSRTS + CONFIG_UART0_CTS_PIN, + CONFIG_UART0_RTS_PIN, + #endif +@@ -158,7 +158,7 @@ + CH_UART1_TX, + CH_UART1_RX, + #endif +-#ifdef CONFIG_SERIAL_BFIN_CTSRTS ++#ifdef CONFIG_BFIN_UART1_CTSRTS + CONFIG_UART1_CTS_PIN, + CONFIG_UART1_RTS_PIN, + #endif +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/arch/blackfin/mach-bf518/include/mach/portmux.h linux-2.6.29-rc3.owrt/arch/blackfin/mach-bf518/include/mach/portmux.h +--- linux-2.6.29.owrt/arch/blackfin/mach-bf518/include/mach/portmux.h 2009-05-10 22:04:41.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/arch/blackfin/mach-bf518/include/mach/portmux.h 2009-05-10 23:48:28.000000000 +0200 +@@ -103,8 +103,6 @@ + #define P_SPI1_SSEL4 (P_DEFINED | P_IDENT(GPIO_PF8) | P_FUNCT(2)) + #define P_SPI1_SSEL5 (P_DEFINED | P_IDENT(GPIO_PG11) | P_FUNCT(2)) + +-#define P_DEFAULT_BOOT_SPI_CS P_SPI0_SSEL2 +- + /* SPORT Port Mux */ + #define P_SPORT0_DRPRI (P_DEFINED | P_IDENT(GPIO_PG3) | P_FUNCT(0)) + #define P_SPORT0_RSCLK (P_DEFINED | P_IDENT(GPIO_PG4) | P_FUNCT(0)) +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/arch/blackfin/mach-bf527/boards/cm_bf527.c linux-2.6.29-rc3.owrt/arch/blackfin/mach-bf527/boards/cm_bf527.c +--- linux-2.6.29.owrt/arch/blackfin/mach-bf527/boards/cm_bf527.c 2009-05-10 22:04:41.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/arch/blackfin/mach-bf527/boards/cm_bf527.c 2009-05-10 23:48:28.000000000 +0200 +@@ -403,13 +403,8 @@ + #endif + + #if defined(CONFIG_BFIN_MAC) || defined(CONFIG_BFIN_MAC_MODULE) +-static struct platform_device bfin_mii_bus = { +- .name = "bfin_mii_bus", +-}; +- + static struct platform_device bfin_mac_device = { + .name = "bfin_mac", +- .dev.platform_data = &bfin_mii_bus, + }; + #endif + +@@ -487,9 +482,9 @@ + }; + #endif + +-#if defined(CONFIG_MMC_SPI) || defined(CONFIG_MMC_SPI_MODULE) +-static struct bfin5xx_spi_chip mmc_spi_chip_info = { +- .enable_dma = 0, ++#if defined(CONFIG_SPI_MMC) || defined(CONFIG_SPI_MMC_MODULE) ++static struct bfin5xx_spi_chip spi_mmc_chip_info = { ++ .enable_dma = 1, + .bits_per_word = 8, + }; + #endif +@@ -585,13 +580,23 @@ + .controller_data = &ad9960_spi_chip_info, + }, + #endif +-#if defined(CONFIG_MMC_SPI) || defined(CONFIG_MMC_SPI_MODULE) ++#if defined(CONFIG_SPI_MMC) || defined(CONFIG_SPI_MMC_MODULE) + { +- .modalias = "mmc_spi", +- .max_speed_hz = 20000000, /* max spi clock (SCK) speed in HZ */ ++ .modalias = "spi_mmc_dummy", ++ .max_speed_hz = 25000000, /* max spi clock (SCK) speed in HZ */ + .bus_num = 0, +- .chip_select = 5, +- .controller_data = &mmc_spi_chip_info, ++ .chip_select = 0, ++ .platform_data = NULL, ++ .controller_data = &spi_mmc_chip_info, ++ .mode = SPI_MODE_3, ++ }, ++ { ++ .modalias = "spi_mmc", ++ .max_speed_hz = 25000000, /* max spi clock (SCK) speed in HZ */ ++ .bus_num = 0, ++ .chip_select = CONFIG_SPI_MMC_CS_CHAN, ++ .platform_data = NULL, ++ .controller_data = &spi_mmc_chip_info, + .mode = SPI_MODE_3, + }, + #endif +@@ -788,6 +793,7 @@ + }; + #endif + ++#ifdef CONFIG_I2C_BOARDINFO + static struct i2c_board_info __initdata bfin_i2c_board_info[] = { + #if defined(CONFIG_TWI_LCD) || defined(CONFIG_TWI_LCD_MODULE) + { +@@ -803,6 +809,7 @@ + }, + #endif + }; ++#endif + + #if defined(CONFIG_SERIAL_BFIN_SPORT) || defined(CONFIG_SERIAL_BFIN_SPORT_MODULE) + static struct platform_device bfin_sport0_uart_device = { +@@ -913,7 +920,6 @@ + #endif + + #if defined(CONFIG_BFIN_MAC) || defined(CONFIG_BFIN_MAC_MODULE) +- &bfin_mii_bus, + &bfin_mac_device, + #endif + +@@ -962,23 +968,27 @@ + &bfin_gpios_device, + }; + +-static int __init cm_init(void) ++static int __init stamp_init(void) + { + printk(KERN_INFO "%s(): registering device resources\n", __func__); ++ ++#ifdef CONFIG_I2C_BOARDINFO + i2c_register_board_info(0, bfin_i2c_board_info, + ARRAY_SIZE(bfin_i2c_board_info)); ++#endif ++ + platform_add_devices(stamp_devices, ARRAY_SIZE(stamp_devices)); + spi_register_board_info(bfin_spi_board_info, ARRAY_SIZE(bfin_spi_board_info)); + return 0; + } + +-arch_initcall(cm_init); ++arch_initcall(stamp_init); + + void native_machine_restart(char *cmd) + { + /* workaround reboot hang when booting from SPI */ + if ((bfin_read_SYSCR() & 0x7) == 0x3) +- bfin_reset_boot_spi_cs(P_DEFAULT_BOOT_SPI_CS); ++ bfin_gpio_reset_spi0_ssel1(); + } + + void bfin_get_ether_addr(char *addr) +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/arch/blackfin/mach-bf527/boards/ezbrd.c linux-2.6.29-rc3.owrt/arch/blackfin/mach-bf527/boards/ezbrd.c +--- linux-2.6.29.owrt/arch/blackfin/mach-bf527/boards/ezbrd.c 2009-05-10 22:04:41.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/arch/blackfin/mach-bf527/boards/ezbrd.c 2009-05-10 23:48:28.000000000 +0200 +@@ -208,13 +208,8 @@ + + + #if defined(CONFIG_BFIN_MAC) || defined(CONFIG_BFIN_MAC_MODULE) +-static struct platform_device bfin_mii_bus = { +- .name = "bfin_mii_bus", +-}; +- + static struct platform_device bfin_mac_device = { + .name = "bfin_mac", +- .dev.platform_data = &bfin_mii_bus, + }; + #endif + +@@ -256,9 +251,9 @@ + }; + #endif + +-#if defined(CONFIG_MMC_SPI) || defined(CONFIG_MMC_SPI_MODULE) +-static struct bfin5xx_spi_chip mmc_spi_chip_info = { +- .enable_dma = 0, ++#if defined(CONFIG_SPI_MMC) || defined(CONFIG_SPI_MMC_MODULE) ++static struct bfin5xx_spi_chip spi_mmc_chip_info = { ++ .enable_dma = 1, + .bits_per_word = 8, + }; + #endif +@@ -366,13 +361,23 @@ + }, + #endif + +-#if defined(CONFIG_MMC_SPI) || defined(CONFIG_MMC_SPI_MODULE) ++#if defined(CONFIG_SPI_MMC) || defined(CONFIG_SPI_MMC_MODULE) + { +- .modalias = "mmc_spi", ++ .modalias = "spi_mmc_dummy", + .max_speed_hz = 25000000, /* max spi clock (SCK) speed in HZ */ + .bus_num = 0, +- .chip_select = 5, +- .controller_data = &mmc_spi_chip_info, ++ .chip_select = 0, ++ .platform_data = NULL, ++ .controller_data = &spi_mmc_chip_info, ++ .mode = SPI_MODE_3, ++ }, ++ { ++ .modalias = "spi_mmc", ++ .max_speed_hz = 25000000, /* max spi clock (SCK) speed in HZ */ ++ .bus_num = 0, ++ .chip_select = CONFIG_SPI_MMC_CS_CHAN, ++ .platform_data = NULL, ++ .controller_data = &spi_mmc_chip_info, + .mode = SPI_MODE_3, + }, + #endif +@@ -585,6 +590,7 @@ + }; + #endif + ++#ifdef CONFIG_I2C_BOARDINFO + static struct i2c_board_info __initdata bfin_i2c_board_info[] = { + #if defined(CONFIG_TWI_LCD) || defined(CONFIG_TWI_LCD_MODULE) + { +@@ -598,6 +604,7 @@ + }, + #endif + }; ++#endif + + #if defined(CONFIG_SERIAL_BFIN_SPORT) || defined(CONFIG_SERIAL_BFIN_SPORT_MODULE) + static struct platform_device bfin_sport0_uart_device = { +@@ -713,7 +720,6 @@ + #endif + + #if defined(CONFIG_BFIN_MAC) || defined(CONFIG_BFIN_MAC_MODULE) +- &bfin_mii_bus, + &bfin_mac_device, + #endif + +@@ -758,23 +764,27 @@ + &bfin_gpios_device, + }; + +-static int __init ezbrd_init(void) ++static int __init stamp_init(void) + { + printk(KERN_INFO "%s(): registering device resources\n", __func__); ++ ++#ifdef CONFIG_I2C_BOARDINFO + i2c_register_board_info(0, bfin_i2c_board_info, + ARRAY_SIZE(bfin_i2c_board_info)); ++#endif ++ + platform_add_devices(stamp_devices, ARRAY_SIZE(stamp_devices)); + spi_register_board_info(bfin_spi_board_info, ARRAY_SIZE(bfin_spi_board_info)); + return 0; + } + +-arch_initcall(ezbrd_init); ++arch_initcall(stamp_init); + + void native_machine_restart(char *cmd) + { + /* workaround reboot hang when booting from SPI */ + if ((bfin_read_SYSCR() & 0x7) == 0x3) +- bfin_reset_boot_spi_cs(P_DEFAULT_BOOT_SPI_CS); ++ bfin_gpio_reset_spi0_ssel1(); + } + + void bfin_get_ether_addr(char *addr) +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/arch/blackfin/mach-bf527/boards/ezkit.c linux-2.6.29-rc3.owrt/arch/blackfin/mach-bf527/boards/ezkit.c +--- linux-2.6.29.owrt/arch/blackfin/mach-bf527/boards/ezkit.c 2009-05-10 22:04:41.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/arch/blackfin/mach-bf527/boards/ezkit.c 2009-05-10 23:48:28.000000000 +0200 +@@ -425,13 +425,8 @@ + #endif + + #if defined(CONFIG_BFIN_MAC) || defined(CONFIG_BFIN_MAC_MODULE) +-static struct platform_device bfin_mii_bus = { +- .name = "bfin_mii_bus", +-}; +- + static struct platform_device bfin_mac_device = { + .name = "bfin_mac", +- .dev.platform_data = &bfin_mii_bus, + }; + #endif + +@@ -835,6 +830,7 @@ + }; + #endif + ++#ifdef CONFIG_I2C_BOARDINFO + static struct i2c_board_info __initdata bfin_i2c_board_info[] = { + #if defined(CONFIG_TWI_LCD) || defined(CONFIG_TWI_LCD_MODULE) + { +@@ -848,6 +844,7 @@ + }, + #endif + }; ++#endif + + #if defined(CONFIG_SERIAL_BFIN_SPORT) || defined(CONFIG_SERIAL_BFIN_SPORT_MODULE) + static struct platform_device bfin_sport0_uart_device = { +@@ -991,7 +988,6 @@ + #endif + + #if defined(CONFIG_BFIN_MAC) || defined(CONFIG_BFIN_MAC_MODULE) +- &bfin_mii_bus, + &bfin_mac_device, + #endif + +@@ -1052,23 +1048,27 @@ + &bfin_gpios_device, + }; + +-static int __init ezkit_init(void) ++static int __init stamp_init(void) + { + printk(KERN_INFO "%s(): registering device resources\n", __func__); ++ ++#ifdef CONFIG_I2C_BOARDINFO + i2c_register_board_info(0, bfin_i2c_board_info, + ARRAY_SIZE(bfin_i2c_board_info)); ++#endif ++ + platform_add_devices(stamp_devices, ARRAY_SIZE(stamp_devices)); + spi_register_board_info(bfin_spi_board_info, ARRAY_SIZE(bfin_spi_board_info)); + return 0; + } + +-arch_initcall(ezkit_init); ++arch_initcall(stamp_init); + + void native_machine_restart(char *cmd) + { + /* workaround reboot hang when booting from SPI */ + if ((bfin_read_SYSCR() & 0x7) == 0x3) +- bfin_reset_boot_spi_cs(P_DEFAULT_BOOT_SPI_CS); ++ bfin_gpio_reset_spi0_ssel1(); + } + + void bfin_get_ether_addr(char *addr) +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/arch/blackfin/mach-bf527/include/mach/anomaly.h linux-2.6.29-rc3.owrt/arch/blackfin/mach-bf527/include/mach/anomaly.h +--- linux-2.6.29.owrt/arch/blackfin/mach-bf527/include/mach/anomaly.h 2009-05-10 22:04:41.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/arch/blackfin/mach-bf527/include/mach/anomaly.h 2009-05-10 23:48:28.000000000 +0200 +@@ -2,7 +2,7 @@ + * File: include/asm-blackfin/mach-bf527/anomaly.h + * Bugs: Enter bugs at http://blackfin.uclinux.org/ + * +- * Copyright (C) 2004-2009 Analog Devices Inc. ++ * Copyright (C) 2004-2008 Analog Devices Inc. + * Licensed under the GPL-2 or later. + */ + +@@ -167,16 +167,12 @@ + #define ANOMALY_05000263 (0) + #define ANOMALY_05000266 (0) + #define ANOMALY_05000273 (0) +-#define ANOMALY_05000278 (0) + #define ANOMALY_05000285 (0) +-#define ANOMALY_05000305 (0) + #define ANOMALY_05000307 (0) + #define ANOMALY_05000311 (0) + #define ANOMALY_05000312 (0) + #define ANOMALY_05000323 (0) + #define ANOMALY_05000363 (0) + #define ANOMALY_05000412 (0) +-#define ANOMALY_05000447 (0) +-#define ANOMALY_05000448 (0) + + #endif +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/arch/blackfin/mach-bf527/include/mach/bfin_serial_5xx.h linux-2.6.29-rc3.owrt/arch/blackfin/mach-bf527/include/mach/bfin_serial_5xx.h +--- linux-2.6.29.owrt/arch/blackfin/mach-bf527/include/mach/bfin_serial_5xx.h 2009-05-10 22:04:41.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/arch/blackfin/mach-bf527/include/mach/bfin_serial_5xx.h 2009-05-10 23:48:28.000000000 +0200 +@@ -144,7 +144,7 @@ + CH_UART0_TX, + CH_UART0_RX, + #endif +-#ifdef CONFIG_SERIAL_BFIN_CTSRTS ++#ifdef CONFIG_BFIN_UART0_CTSRTS + CONFIG_UART0_CTS_PIN, + CONFIG_UART0_RTS_PIN, + #endif +@@ -158,7 +158,7 @@ + CH_UART1_TX, + CH_UART1_RX, + #endif +-#ifdef CONFIG_SERIAL_BFIN_CTSRTS ++#ifdef CONFIG_BFIN_UART1_CTSRTS + CONFIG_UART1_CTS_PIN, + CONFIG_UART1_RTS_PIN, + #endif +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/arch/blackfin/mach-bf527/include/mach/portmux.h linux-2.6.29-rc3.owrt/arch/blackfin/mach-bf527/include/mach/portmux.h +--- linux-2.6.29.owrt/arch/blackfin/mach-bf527/include/mach/portmux.h 2009-05-10 22:04:41.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/arch/blackfin/mach-bf527/include/mach/portmux.h 2009-05-10 23:48:28.000000000 +0200 +@@ -73,8 +73,6 @@ + + #define P_HWAIT (P_DONTCARE) + +-#define P_DEFAULT_BOOT_SPI_CS P_SPI0_SSEL1 +- + #define P_SPI0_SS (P_DEFINED | P_IDENT(GPIO_PG1) | P_FUNCT(0)) + #define P_SPI0_SSEL1 (P_DEFINED | P_IDENT(GPIO_PG1) | P_FUNCT(2)) + #define P_SPI0_SCK (P_DEFINED | P_IDENT(GPIO_PG2) | P_FUNCT(2)) +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/arch/blackfin/mach-bf533/boards/blackstamp.c linux-2.6.29-rc3.owrt/arch/blackfin/mach-bf533/boards/blackstamp.c +--- linux-2.6.29.owrt/arch/blackfin/mach-bf533/boards/blackstamp.c 2009-05-10 22:04:41.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/arch/blackfin/mach-bf533/boards/blackstamp.c 2009-05-10 23:48:28.000000000 +0200 +@@ -101,9 +101,9 @@ + }; + #endif + +-#if defined(CONFIG_MMC_SPI) || defined(CONFIG_MMC_SPI_MODULE) +-static struct bfin5xx_spi_chip mmc_spi_chip_info = { +- .enable_dma = 0, ++#if defined(CONFIG_SPI_MMC) || defined(CONFIG_SPI_MMC_MODULE) ++static struct bfin5xx_spi_chip spi_mmc_chip_info = { ++ .enable_dma = 1, + .bits_per_word = 8, + }; + #endif +@@ -129,13 +129,23 @@ + }, + #endif + +-#if defined(CONFIG_MMC_SPI) || defined(CONFIG_MMC_SPI_MODULE) ++#if defined(CONFIG_SPI_MMC) || defined(CONFIG_SPI_MMC_MODULE) ++ { ++ .modalias = "spi_mmc_dummy", ++ .max_speed_hz = 20000000, /* max spi clock (SCK) speed in HZ */ ++ .bus_num = 0, ++ .chip_select = 0, ++ .platform_data = NULL, ++ .controller_data = &spi_mmc_chip_info, ++ .mode = SPI_MODE_3, ++ }, + { +- .modalias = "mmc_spi", ++ .modalias = "spi_mmc", + .max_speed_hz = 20000000, /* max spi clock (SCK) speed in HZ */ + .bus_num = 0, +- .chip_select = 5, +- .controller_data = &mmc_spi_chip_info, ++ .chip_select = CONFIG_SPI_MMC_CS_CHAN, ++ .platform_data = NULL, ++ .controller_data = &spi_mmc_chip_info, + .mode = SPI_MODE_3, + }, + #endif +@@ -299,8 +309,10 @@ + }; + #endif + ++#ifdef CONFIG_I2C_BOARDINFO + static struct i2c_board_info __initdata bfin_i2c_board_info[] = { + }; ++#endif + + static const unsigned int cclk_vlev_datasheet[] = + { +@@ -378,8 +390,10 @@ + + printk(KERN_INFO "%s(): registering device resources\n", __func__); + ++#ifdef CONFIG_I2C_BOARDINFO + i2c_register_board_info(0, bfin_i2c_board_info, + ARRAY_SIZE(bfin_i2c_board_info)); ++#endif + + ret = platform_add_devices(stamp_devices, ARRAY_SIZE(stamp_devices)); + if (ret < 0) +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/arch/blackfin/mach-bf533/boards/cm_bf533.c linux-2.6.29-rc3.owrt/arch/blackfin/mach-bf533/boards/cm_bf533.c +--- linux-2.6.29.owrt/arch/blackfin/mach-bf533/boards/cm_bf533.c 2009-05-10 22:04:41.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/arch/blackfin/mach-bf533/boards/cm_bf533.c 2009-05-10 23:48:28.000000000 +0200 +@@ -96,9 +96,9 @@ + }; + #endif + +-#if defined(CONFIG_MMC_SPI) || defined(CONFIG_MMC_SPI_MODULE) +-static struct bfin5xx_spi_chip mmc_spi_chip_info = { +- .enable_dma = 0, ++#if defined(CONFIG_SPI_MMC) || defined(CONFIG_SPI_MMC_MODULE) ++static struct bfin5xx_spi_chip spi_mmc_chip_info = { ++ .enable_dma = 1, + .bits_per_word = 8, + }; + #endif +@@ -138,13 +138,23 @@ + }, + #endif + +-#if defined(CONFIG_MMC_SPI) || defined(CONFIG_MMC_SPI_MODULE) ++#if defined(CONFIG_SPI_MMC) || defined(CONFIG_SPI_MMC_MODULE) + { +- .modalias = "mmc_spi", ++ .modalias = "spi_mmc_dummy", + .max_speed_hz = 25000000, /* max spi clock (SCK) speed in HZ */ + .bus_num = 0, +- .chip_select = 5, +- .controller_data = &mmc_spi_chip_info, ++ .chip_select = 0, ++ .platform_data = NULL, ++ .controller_data = &spi_mmc_chip_info, ++ .mode = SPI_MODE_3, ++ }, ++ { ++ .modalias = "spi_mmc", ++ .max_speed_hz = 25000000, /* max spi clock (SCK) speed in HZ */ ++ .bus_num = 0, ++ .chip_select = CONFIG_SPI_MMC_CS_CHAN, ++ .platform_data = NULL, ++ .controller_data = &spi_mmc_chip_info, + .mode = SPI_MODE_3, + }, + #endif +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/arch/blackfin/mach-bf533/boards/generic_board.c linux-2.6.29-rc3.owrt/arch/blackfin/mach-bf533/boards/generic_board.c +--- linux-2.6.29.owrt/arch/blackfin/mach-bf533/boards/generic_board.c 1970-01-01 01:00:00.000000000 +0100 ++++ linux-2.6.29-rc3.owrt/arch/blackfin/mach-bf533/boards/generic_board.c 2009-05-10 23:48:28.000000000 +0200 +@@ -0,0 +1,126 @@ ++/* ++ * File: arch/blackfin/mach-bf533/generic_board.c ++ * Based on: arch/blackfin/mach-bf533/ezkit.c ++ * Author: Aidan Williams <aidan@nicta.com.au> ++ * ++ * Created: 2005 ++ * Description: ++ * ++ * Modified: ++ * Copyright 2005 National ICT Australia (NICTA) ++ * Copyright 2004-2006 Analog Devices Inc. ++ * ++ * Bugs: Enter bugs at http://blackfin.uclinux.org/ ++ * ++ * 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, see the file COPYING, or write ++ * to the Free Software Foundation, Inc., ++ * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA ++ */ ++ ++#include <linux/device.h> ++#include <linux/platform_device.h> ++#include <linux/irq.h> ++ ++/* ++ * Name the Board for the /proc/cpuinfo ++ */ ++const char bfin_board_name[] = "UNKNOWN BOARD"; ++ ++#if defined(CONFIG_RTC_DRV_BFIN) || defined(CONFIG_RTC_DRV_BFIN_MODULE) ++static struct platform_device rtc_device = { ++ .name = "rtc-bfin", ++ .id = -1, ++}; ++#endif ++ ++/* ++ * Driver needs to know address, irq and flag pin. ++ */ ++#if defined(CONFIG_SMC91X) || defined(CONFIG_SMC91X_MODULE) ++static struct resource smc91x_resources[] = { ++ { ++ .start = 0x20300300, ++ .end = 0x20300300 + 16, ++ .flags = IORESOURCE_MEM, ++ }, { ++ .start = IRQ_PROG_INTB, ++ .end = IRQ_PROG_INTB, ++ .flags = IORESOURCE_IRQ | IORESOURCE_IRQ_HIGHLEVEL, ++ }, { ++ .start = IRQ_PF7, ++ .end = IRQ_PF7, ++ .flags = IORESOURCE_IRQ | IORESOURCE_IRQ_HIGHLEVEL, ++ }, ++}; ++ ++static struct platform_device smc91x_device = { ++ .name = "smc91x", ++ .id = 0, ++ .num_resources = ARRAY_SIZE(smc91x_resources), ++ .resource = smc91x_resources, ++}; ++#endif ++ ++#if defined(CONFIG_BFIN_SIR) || defined(CONFIG_BFIN_SIR_MODULE) ++#ifdef CONFIG_BFIN_SIR0 ++static struct resource bfin_sir0_resources[] = { ++ { ++ .start = 0xFFC00400, ++ .end = 0xFFC004FF, ++ .flags = IORESOURCE_MEM, ++ }, ++ { ++ .start = IRQ_UART0_RX, ++ .end = IRQ_UART0_RX+1, ++ .flags = IORESOURCE_IRQ, ++ }, ++ { ++ .start = CH_UART0_RX, ++ .end = CH_UART0_RX+1, ++ .flags = IORESOURCE_DMA, ++ }, ++}; ++ ++static struct platform_device bfin_sir0_device = { ++ .name = "bfin_sir", ++ .id = 0, ++ .num_resources = ARRAY_SIZE(bfin_sir0_resources), ++ .resource = bfin_sir0_resources, ++}; ++#endif ++#endif ++ ++static struct platform_device *generic_board_devices[] __initdata = { ++#if defined(CONFIG_RTC_DRV_BFIN) || defined(CONFIG_RTC_DRV_BFIN_MODULE) ++ &rtc_device, ++#endif ++ ++#if defined(CONFIG_SMC91X) || defined(CONFIG_SMC91X_MODULE) ++ &smc91x_device, ++#endif ++ ++#if defined(CONFIG_BFIN_SIR) || defined(CONFIG_BFIN_SIR_MODULE) ++#ifdef CONFIG_BFIN_SIR0 ++ &bfin_sir0_device, ++#endif ++#endif ++}; ++ ++static int __init generic_board_init(void) ++{ ++ printk(KERN_INFO "%s(): registering device resources\n", __func__); ++ return platform_add_devices(generic_board_devices, ARRAY_SIZE(generic_board_devices)); ++} ++ ++arch_initcall(generic_board_init); +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/arch/blackfin/mach-bf533/boards/ip0x.c linux-2.6.29-rc3.owrt/arch/blackfin/mach-bf533/boards/ip0x.c +--- linux-2.6.29.owrt/arch/blackfin/mach-bf533/boards/ip0x.c 2009-05-10 22:04:41.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/arch/blackfin/mach-bf533/boards/ip0x.c 2009-05-10 23:48:28.000000000 +0200 +@@ -127,8 +127,8 @@ + #if defined(CONFIG_SPI_BFIN) || defined(CONFIG_SPI_BFIN_MODULE) + /* all SPI peripherals info goes here */ + +-#if defined(CONFIG_MMC_SPI) || defined(CONFIG_MMC_SPI_MODULE) +-static struct bfin5xx_spi_chip mmc_spi_chip_info = { ++#if defined(CONFIG_SPI_MMC) || defined(CONFIG_SPI_MMC_MODULE) ++static struct bfin5xx_spi_chip spi_mmc_chip_info = { + /* + * CPOL (Clock Polarity) + * 0 - Active high SCK +@@ -152,13 +152,14 @@ + /* Notice: for blackfin, the speed_hz is the value of register + * SPI_BAUD, not the real baudrate */ + static struct spi_board_info bfin_spi_board_info[] __initdata = { +-#if defined(CONFIG_MMC_SPI) || defined(CONFIG_MMC_SPI_MODULE) ++#if defined(CONFIG_SPI_MMC) || defined(CONFIG_SPI_MMC_MODULE) + { +- .modalias = "mmc_spi", ++ .modalias = "spi_mmc", + .max_speed_hz = 2, + .bus_num = 1, +- .chip_select = 5, +- .controller_data = &mmc_spi_chip_info, ++ .chip_select = CONFIG_SPI_MMC_CS_CHAN, ++ .platform_data = NULL, ++ .controller_data = &spi_mmc_chip_info, + }, + #endif + }; +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/arch/blackfin/mach-bf533/boards/Kconfig linux-2.6.29-rc3.owrt/arch/blackfin/mach-bf533/boards/Kconfig +--- linux-2.6.29.owrt/arch/blackfin/mach-bf533/boards/Kconfig 2009-05-10 22:04:41.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/arch/blackfin/mach-bf533/boards/Kconfig 2009-05-10 23:48:28.000000000 +0200 +@@ -38,4 +38,9 @@ + help + Core support for IP04/IP04 open hardware IP-PBX. + ++config GENERIC_BF533_BOARD ++ bool "Generic" ++ help ++ Generic or Custom board support. ++ + endchoice +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/arch/blackfin/mach-bf533/boards/Makefile linux-2.6.29-rc3.owrt/arch/blackfin/mach-bf533/boards/Makefile +--- linux-2.6.29.owrt/arch/blackfin/mach-bf533/boards/Makefile 2009-05-10 22:04:41.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/arch/blackfin/mach-bf533/boards/Makefile 2009-05-10 23:48:28.000000000 +0200 +@@ -2,6 +2,7 @@ + # arch/blackfin/mach-bf533/boards/Makefile + # + ++obj-$(CONFIG_GENERIC_BF533_BOARD) += generic_board.o + obj-$(CONFIG_BFIN533_STAMP) += stamp.o + obj-$(CONFIG_BFIN532_IP0X) += ip0x.o + obj-$(CONFIG_BFIN533_EZKIT) += ezkit.o +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/arch/blackfin/mach-bf533/boards/stamp.c linux-2.6.29-rc3.owrt/arch/blackfin/mach-bf533/boards/stamp.c +--- linux-2.6.29.owrt/arch/blackfin/mach-bf533/boards/stamp.c 2009-05-10 22:04:41.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/arch/blackfin/mach-bf533/boards/stamp.c 2009-05-10 23:48:28.000000000 +0200 +@@ -441,6 +441,7 @@ + }; + #endif + ++#ifdef CONFIG_I2C_BOARDINFO + static struct i2c_board_info __initdata bfin_i2c_board_info[] = { + #if defined(CONFIG_JOYSTICK_AD7142) || defined(CONFIG_JOYSTICK_AD7142_MODULE) + { +@@ -460,6 +461,7 @@ + }, + #endif + }; ++#endif + + static const unsigned int cclk_vlev_datasheet[] = + { +@@ -548,8 +550,10 @@ + + printk(KERN_INFO "%s(): registering device resources\n", __func__); + ++#ifdef CONFIG_I2C_BOARDINFO + i2c_register_board_info(0, bfin_i2c_board_info, + ARRAY_SIZE(bfin_i2c_board_info)); ++#endif + + ret = platform_add_devices(stamp_devices, ARRAY_SIZE(stamp_devices)); + if (ret < 0) +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/arch/blackfin/mach-bf533/include/mach/anomaly.h linux-2.6.29-rc3.owrt/arch/blackfin/mach-bf533/include/mach/anomaly.h +--- linux-2.6.29.owrt/arch/blackfin/mach-bf533/include/mach/anomaly.h 2009-05-10 22:04:41.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/arch/blackfin/mach-bf533/include/mach/anomaly.h 2009-05-10 23:48:28.000000000 +0200 +@@ -2,7 +2,7 @@ + * File: include/asm-blackfin/mach-bf533/anomaly.h + * Bugs: Enter bugs at http://blackfin.uclinux.org/ + * +- * Copyright (C) 2004-2009 Analog Devices Inc. ++ * Copyright (C) 2004-2008 Analog Devices Inc. + * Licensed under the GPL-2 or later. + */ + +@@ -160,7 +160,7 @@ + #define ANOMALY_05000301 (__SILICON_REVISION__ < 6) + /* SSYNCs After Writes To DMA MMR Registers May Not Be Handled Correctly */ + #define ANOMALY_05000302 (__SILICON_REVISION__ < 5) +-/* SPORT_HYS Bit in PLL_CTL Register Is Not Functional */ ++/* New Feature: Additional Hysteresis on SPORT Input Pins (Not Available On Older Silicon) */ + #define ANOMALY_05000305 (__SILICON_REVISION__ < 5) + /* New Feature: Additional PPI Frame Sync Sampling Options (Not Available On Older Silicon) */ + #define ANOMALY_05000306 (__SILICON_REVISION__ < 5) +@@ -278,12 +278,9 @@ + #define ANOMALY_05000266 (0) + #define ANOMALY_05000323 (0) + #define ANOMALY_05000353 (1) +-#define ANOMALY_05000380 (0) + #define ANOMALY_05000386 (1) + #define ANOMALY_05000412 (0) + #define ANOMALY_05000432 (0) + #define ANOMALY_05000435 (0) +-#define ANOMALY_05000447 (0) +-#define ANOMALY_05000448 (0) + + #endif +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/arch/blackfin/mach-bf533/include/mach/bfin_serial_5xx.h linux-2.6.29-rc3.owrt/arch/blackfin/mach-bf533/include/mach/bfin_serial_5xx.h +--- linux-2.6.29.owrt/arch/blackfin/mach-bf533/include/mach/bfin_serial_5xx.h 2009-05-10 22:04:41.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/arch/blackfin/mach-bf533/include/mach/bfin_serial_5xx.h 2009-05-10 23:48:28.000000000 +0200 +@@ -134,7 +134,7 @@ + CH_UART_TX, + CH_UART_RX, + #endif +-#ifdef CONFIG_SERIAL_BFIN_CTSRTS ++#ifdef CONFIG_BFIN_UART0_CTSRTS + CONFIG_UART0_CTS_PIN, + CONFIG_UART0_RTS_PIN, + #endif +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/arch/blackfin/mach-bf533/include/mach/portmux.h linux-2.6.29-rc3.owrt/arch/blackfin/mach-bf533/include/mach/portmux.h +--- linux-2.6.29.owrt/arch/blackfin/mach-bf533/include/mach/portmux.h 2009-05-10 22:04:41.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/arch/blackfin/mach-bf533/include/mach/portmux.h 2009-05-10 23:48:28.000000000 +0200 +@@ -54,11 +54,14 @@ + #define P_SPI0_SSEL2 (P_DEFINED | P_IDENT(GPIO_PF2)) + #define P_SPI0_SSEL1 (P_DEFINED | P_IDENT(GPIO_PF1)) + #define P_SPI0_SS (P_DEFINED | P_IDENT(GPIO_PF0)) +-#define P_DEFAULT_BOOT_SPI_CS P_SPI0_SSEL2 + + #define P_TMR2 (P_DONTCARE) + #define P_TMR1 (P_DONTCARE) + #define P_TMR0 (P_DONTCARE) + #define P_TMRCLK (P_DEFINED | P_IDENT(GPIO_PF1)) + ++ ++ ++ ++ + #endif /* _MACH_PORTMUX_H_ */ +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/arch/blackfin/mach-bf537/boards/cm_bf537.c linux-2.6.29-rc3.owrt/arch/blackfin/mach-bf537/boards/cm_bf537.c +--- linux-2.6.29.owrt/arch/blackfin/mach-bf537/boards/cm_bf537.c 2009-05-10 22:04:40.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/arch/blackfin/mach-bf537/boards/cm_bf537.c 2009-05-10 23:48:28.000000000 +0200 +@@ -108,9 +108,9 @@ + }; + #endif + +-#if defined(CONFIG_MMC_SPI) || defined(CONFIG_MMC_SPI_MODULE) +-static struct bfin5xx_spi_chip mmc_spi_chip_info = { +- .enable_dma = 0, ++#if defined(CONFIG_SPI_MMC) || defined(CONFIG_SPI_MMC_MODULE) ++static struct bfin5xx_spi_chip spi_mmc_chip_info = { ++ .enable_dma = 1, + .bits_per_word = 8, + }; + #endif +@@ -160,13 +160,23 @@ + }, + #endif + +-#if defined(CONFIG_MMC_SPI) || defined(CONFIG_MMC_SPI_MODULE) ++#if defined(CONFIG_SPI_MMC) || defined(CONFIG_SPI_MMC_MODULE) + { +- .modalias = "mmc_spi", +- .max_speed_hz = 20000000, /* max spi clock (SCK) speed in HZ */ ++ .modalias = "spi_mmc_dummy", ++ .max_speed_hz = 25000000, /* max spi clock (SCK) speed in HZ */ + .bus_num = 0, +- .chip_select = 1, +- .controller_data = &mmc_spi_chip_info, ++ .chip_select = 7, ++ .platform_data = NULL, ++ .controller_data = &spi_mmc_chip_info, ++ .mode = SPI_MODE_3, ++ }, ++ { ++ .modalias = "spi_mmc", ++ .max_speed_hz = 25000000, /* max spi clock (SCK) speed in HZ */ ++ .bus_num = 0, ++ .chip_select = CONFIG_SPI_MMC_CS_CHAN, ++ .platform_data = NULL, ++ .controller_data = &spi_mmc_chip_info, + .mode = SPI_MODE_3, + }, + #endif +@@ -469,13 +479,8 @@ + #endif + + #if defined(CONFIG_BFIN_MAC) || defined(CONFIG_BFIN_MAC_MODULE) +-static struct platform_device bfin_mii_bus = { +- .name = "bfin_mii_bus", +-}; +- + static struct platform_device bfin_mac_device = { + .name = "bfin_mac", +- .dev.platform_data = &bfin_mii_bus, + }; + #endif + +@@ -586,7 +591,6 @@ + #endif + + #if defined(CONFIG_BFIN_MAC) || defined(CONFIG_BFIN_MAC_MODULE) +- &bfin_mii_bus, + &bfin_mac_device, + #endif + +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/arch/blackfin/mach-bf537/boards/generic_board.c linux-2.6.29-rc3.owrt/arch/blackfin/mach-bf537/boards/generic_board.c +--- linux-2.6.29.owrt/arch/blackfin/mach-bf537/boards/generic_board.c 1970-01-01 01:00:00.000000000 +0100 ++++ linux-2.6.29-rc3.owrt/arch/blackfin/mach-bf537/boards/generic_board.c 2009-05-10 23:48:28.000000000 +0200 +@@ -0,0 +1,739 @@ ++/* ++ * File: arch/blackfin/mach-bf537/boards/generic_board.c ++ * Based on: arch/blackfin/mach-bf533/boards/ezkit.c ++ * Author: Aidan Williams <aidan@nicta.com.au> ++ * ++ * Created: ++ * Description: ++ * ++ * Modified: ++ * Copyright 2005 National ICT Australia (NICTA) ++ * Copyright 2004-2008 Analog Devices Inc. ++ * ++ * Bugs: Enter bugs at http://blackfin.uclinux.org/ ++ * ++ * 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, see the file COPYING, or write ++ * to the Free Software Foundation, Inc., ++ * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA ++ */ ++ ++#include <linux/device.h> ++#include <linux/etherdevice.h> ++#include <linux/platform_device.h> ++#include <linux/mtd/mtd.h> ++#include <linux/mtd/partitions.h> ++#include <linux/spi/spi.h> ++#include <linux/spi/flash.h> ++#if defined(CONFIG_USB_ISP1362_HCD) || defined(CONFIG_USB_ISP1362_HCD_MODULE) ++#include <linux/usb/isp1362.h> ++#endif ++#include <linux/irq.h> ++#include <linux/interrupt.h> ++#include <linux/usb/sl811.h> ++#include <asm/dma.h> ++#include <asm/bfin5xx_spi.h> ++#include <asm/reboot.h> ++#include <asm/portmux.h> ++#include <linux/spi/ad7877.h> ++ ++/* ++ * Name the Board for the /proc/cpuinfo ++ */ ++const char bfin_board_name[] = "UNKNOWN BOARD"; ++ ++/* ++ * Driver needs to know address, irq and flag pin. ++ */ ++ ++#if defined(CONFIG_USB_ISP1760_HCD) || defined(CONFIG_USB_ISP1760_HCD_MODULE) ++#include <linux/usb/isp1760.h> ++static struct resource bfin_isp1760_resources[] = { ++ [0] = { ++ .start = 0x203C0000, ++ .end = 0x203C0000 + 0x000fffff, ++ .flags = IORESOURCE_MEM, ++ }, ++ [1] = { ++ .start = IRQ_PF7, ++ .end = IRQ_PF7, ++ .flags = IORESOURCE_IRQ, ++ }, ++}; ++ ++static struct isp1760_platform_data isp1760_priv = { ++ .is_isp1761 = 0, ++ .port1_disable = 0, ++ .bus_width_16 = 1, ++ .port1_otg = 0, ++ .analog_oc = 0, ++ .dack_polarity_high = 0, ++ .dreq_polarity_high = 0, ++}; ++ ++static struct platform_device bfin_isp1760_device = { ++ .name = "isp1760-hcd", ++ .id = 0, ++ .dev = { ++ .platform_data = &isp1760_priv, ++ }, ++ .num_resources = ARRAY_SIZE(bfin_isp1760_resources), ++ .resource = bfin_isp1760_resources, ++}; ++#endif ++ ++#if defined(CONFIG_BFIN_CFPCMCIA) || defined(CONFIG_BFIN_CFPCMCIA_MODULE) ++static struct resource bfin_pcmcia_cf_resources[] = { ++ { ++ .start = 0x20310000, /* IO PORT */ ++ .end = 0x20312000, ++ .flags = IORESOURCE_MEM, ++ }, { ++ .start = 0x20311000, /* Attribute Memory */ ++ .end = 0x20311FFF, ++ .flags = IORESOURCE_MEM, ++ }, { ++ .start = IRQ_PF4, ++ .end = IRQ_PF4, ++ .flags = IORESOURCE_IRQ | IORESOURCE_IRQ_LOWLEVEL, ++ }, { ++ .start = 6, /* Card Detect PF6 */ ++ .end = 6, ++ .flags = IORESOURCE_IRQ, ++ }, ++}; ++ ++static struct platform_device bfin_pcmcia_cf_device = { ++ .name = "bfin_cf_pcmcia", ++ .id = -1, ++ .num_resources = ARRAY_SIZE(bfin_pcmcia_cf_resources), ++ .resource = bfin_pcmcia_cf_resources, ++}; ++#endif ++ ++#if defined(CONFIG_RTC_DRV_BFIN) || defined(CONFIG_RTC_DRV_BFIN_MODULE) ++static struct platform_device rtc_device = { ++ .name = "rtc-bfin", ++ .id = -1, ++}; ++#endif ++ ++#if defined(CONFIG_SMC91X) || defined(CONFIG_SMC91X_MODULE) ++static struct resource smc91x_resources[] = { ++ { ++ .name = "smc91x-regs", ++ .start = 0x20300300, ++ .end = 0x20300300 + 16, ++ .flags = IORESOURCE_MEM, ++ }, { ++ ++ .start = IRQ_PF7, ++ .end = IRQ_PF7, ++ .flags = IORESOURCE_IRQ | IORESOURCE_IRQ_HIGHLEVEL, ++ }, ++}; ++static struct platform_device smc91x_device = { ++ .name = "smc91x", ++ .id = 0, ++ .num_resources = ARRAY_SIZE(smc91x_resources), ++ .resource = smc91x_resources, ++}; ++#endif ++ ++#if defined(CONFIG_DM9000) || defined(CONFIG_DM9000_MODULE) ++static struct resource dm9000_resources[] = { ++ [0] = { ++ .start = 0x203FB800, ++ .end = 0x203FB800 + 1, ++ .flags = IORESOURCE_MEM, ++ }, ++ [1] = { ++ .start = 0x203FB800 + 4, ++ .end = 0x203FB800 + 5, ++ .flags = IORESOURCE_MEM, ++ }, ++ [2] = { ++ .start = IRQ_PF9, ++ .end = IRQ_PF9, ++ .flags = (IORESOURCE_IRQ | IORESOURCE_IRQ_HIGHEDGE), ++ }, ++}; ++ ++static struct platform_device dm9000_device = { ++ .name = "dm9000", ++ .id = -1, ++ .num_resources = ARRAY_SIZE(dm9000_resources), ++ .resource = dm9000_resources, ++}; ++#endif ++ ++#if defined(CONFIG_USB_SL811_HCD) || defined(CONFIG_USB_SL811_HCD_MODULE) ++static struct resource sl811_hcd_resources[] = { ++ { ++ .start = 0x20340000, ++ .end = 0x20340000, ++ .flags = IORESOURCE_MEM, ++ }, { ++ .start = 0x20340004, ++ .end = 0x20340004, ++ .flags = IORESOURCE_MEM, ++ }, { ++ .start = CONFIG_USB_SL811_BFIN_IRQ, ++ .end = CONFIG_USB_SL811_BFIN_IRQ, ++ .flags = IORESOURCE_IRQ | IORESOURCE_IRQ_HIGHLEVEL, ++ }, ++}; ++ ++#if defined(CONFIG_USB_SL811_BFIN_USE_VBUS) ++void sl811_port_power(struct device *dev, int is_on) ++{ ++ gpio_request(CONFIG_USB_SL811_BFIN_GPIO_VBUS, "usb:SL811_VBUS"); ++ gpio_direction_output(CONFIG_USB_SL811_BFIN_GPIO_VBUS, is_on); ++ ++} ++#endif ++ ++static struct sl811_platform_data sl811_priv = { ++ .potpg = 10, ++ .power = 250, /* == 500mA */ ++#if defined(CONFIG_USB_SL811_BFIN_USE_VBUS) ++ .port_power = &sl811_port_power, ++#endif ++}; ++ ++static struct platform_device sl811_hcd_device = { ++ .name = "sl811-hcd", ++ .id = 0, ++ .dev = { ++ .platform_data = &sl811_priv, ++ }, ++ .num_resources = ARRAY_SIZE(sl811_hcd_resources), ++ .resource = sl811_hcd_resources, ++}; ++#endif ++ ++#if defined(CONFIG_USB_ISP1362_HCD) || defined(CONFIG_USB_ISP1362_HCD_MODULE) ++static struct resource isp1362_hcd_resources[] = { ++ { ++ .start = 0x20360000, ++ .end = 0x20360000, ++ .flags = IORESOURCE_MEM, ++ }, { ++ .start = 0x20360004, ++ .end = 0x20360004, ++ .flags = IORESOURCE_MEM, ++ }, { ++ .start = CONFIG_USB_ISP1362_BFIN_GPIO_IRQ, ++ .end = CONFIG_USB_ISP1362_BFIN_GPIO_IRQ, ++ .flags = IORESOURCE_IRQ | IORESOURCE_IRQ_HIGHLEVEL, ++ }, ++}; ++ ++static struct isp1362_platform_data isp1362_priv = { ++ .sel15Kres = 1, ++ .clknotstop = 0, ++ .oc_enable = 0, ++ .int_act_high = 0, ++ .int_edge_triggered = 0, ++ .remote_wakeup_connected = 0, ++ .no_power_switching = 1, ++ .power_switching_mode = 0, ++}; ++ ++static struct platform_device isp1362_hcd_device = { ++ .name = "isp1362-hcd", ++ .id = 0, ++ .dev = { ++ .platform_data = &isp1362_priv, ++ }, ++ .num_resources = ARRAY_SIZE(isp1362_hcd_resources), ++ .resource = isp1362_hcd_resources, ++}; ++#endif ++ ++#if defined(CONFIG_BFIN_MAC) || defined(CONFIG_BFIN_MAC_MODULE) ++static struct platform_device bfin_mac_device = { ++ .name = "bfin_mac", ++}; ++#endif ++ ++#if defined(CONFIG_USB_NET2272) || defined(CONFIG_USB_NET2272_MODULE) ++static struct resource net2272_bfin_resources[] = { ++ { ++ .start = 0x20300000, ++ .end = 0x20300000 + 0x100, ++ .flags = IORESOURCE_MEM, ++ }, { ++ .start = IRQ_PF7, ++ .end = IRQ_PF7, ++ .flags = IORESOURCE_IRQ | IORESOURCE_IRQ_HIGHLEVEL, ++ }, ++}; ++ ++static struct platform_device net2272_bfin_device = { ++ .name = "net2272", ++ .id = -1, ++ .num_resources = ARRAY_SIZE(net2272_bfin_resources), ++ .resource = net2272_bfin_resources, ++}; ++#endif ++ ++#if defined(CONFIG_SPI_BFIN) || defined(CONFIG_SPI_BFIN_MODULE) ++/* all SPI peripherals info goes here */ ++ ++#if defined(CONFIG_MTD_M25P80) \ ++ || defined(CONFIG_MTD_M25P80_MODULE) ++static struct mtd_partition bfin_spi_flash_partitions[] = { ++ { ++ .name = "bootloader(spi)", ++ .size = 0x00020000, ++ .offset = 0, ++ .mask_flags = MTD_CAP_ROM ++ }, { ++ .name = "linux kernel(spi)", ++ .size = 0xe0000, ++ .offset = 0x20000 ++ }, { ++ .name = "file system(spi)", ++ .size = 0x700000, ++ .offset = 0x00100000, ++ } ++}; ++ ++static struct flash_platform_data bfin_spi_flash_data = { ++ .name = "m25p80", ++ .parts = bfin_spi_flash_partitions, ++ .nr_parts = ARRAY_SIZE(bfin_spi_flash_partitions), ++ .type = "m25p64", ++}; ++ ++/* SPI flash chip (m25p64) */ ++static struct bfin5xx_spi_chip spi_flash_chip_info = { ++ .enable_dma = 0, /* use dma transfer with this chip*/ ++ .bits_per_word = 8, ++}; ++#endif ++ ++#if defined(CONFIG_SPI_ADC_BF533) \ ++ || defined(CONFIG_SPI_ADC_BF533_MODULE) ++/* SPI ADC chip */ ++static struct bfin5xx_spi_chip spi_adc_chip_info = { ++ .enable_dma = 1, /* use dma transfer with this chip*/ ++ .bits_per_word = 16, ++}; ++#endif ++ ++#if defined(CONFIG_SND_BLACKFIN_AD1836) \ ++ || defined(CONFIG_SND_BLACKFIN_AD1836_MODULE) ++static struct bfin5xx_spi_chip ad1836_spi_chip_info = { ++ .enable_dma = 0, ++ .bits_per_word = 16, ++}; ++#endif ++ ++#if defined(CONFIG_AD9960) || defined(CONFIG_AD9960_MODULE) ++static struct bfin5xx_spi_chip ad9960_spi_chip_info = { ++ .enable_dma = 0, ++ .bits_per_word = 16, ++}; ++#endif ++ ++#if defined(CONFIG_SPI_MMC) || defined(CONFIG_SPI_MMC_MODULE) ++static struct bfin5xx_spi_chip spi_mmc_chip_info = { ++ .enable_dma = 1, ++ .bits_per_word = 8, ++}; ++#endif ++ ++#if defined(CONFIG_PBX) ++static struct bfin5xx_spi_chip spi_si3xxx_chip_info = { ++ .ctl_reg = 0x4, /* send zero */ ++ .enable_dma = 0, ++ .bits_per_word = 8, ++ .cs_change_per_word = 1, ++}; ++#endif ++ ++#if defined(CONFIG_TOUCHSCREEN_AD7877) || defined(CONFIG_TOUCHSCREEN_AD7877_MODULE) ++static struct bfin5xx_spi_chip spi_ad7877_chip_info = { ++ .enable_dma = 0, ++ .bits_per_word = 16, ++}; ++ ++static const struct ad7877_platform_data bfin_ad7877_ts_info = { ++ .model = 7877, ++ .vref_delay_usecs = 50, /* internal, no capacitor */ ++ .x_plate_ohms = 419, ++ .y_plate_ohms = 486, ++ .pressure_max = 1000, ++ .pressure_min = 0, ++ .stopacq_polarity = 1, ++ .first_conversion_delay = 3, ++ .acquisition_time = 1, ++ .averaging = 1, ++ .pen_down_acc_interval = 1, ++}; ++#endif ++ ++static struct spi_board_info bfin_spi_board_info[] __initdata = { ++#if defined(CONFIG_MTD_M25P80) \ ++ || defined(CONFIG_MTD_M25P80_MODULE) ++ { ++ /* the modalias must be the same as spi device driver name */ ++ .modalias = "m25p80", /* Name of spi_driver for this device */ ++ .max_speed_hz = 25000000, /* max spi clock (SCK) speed in HZ */ ++ .bus_num = 0, /* Framework bus number */ ++ .chip_select = 1, /* Framework chip select. On STAMP537 it is SPISSEL1*/ ++ .platform_data = &bfin_spi_flash_data, ++ .controller_data = &spi_flash_chip_info, ++ .mode = SPI_MODE_3, ++ }, ++#endif ++ ++#if defined(CONFIG_SPI_ADC_BF533) \ ++ || defined(CONFIG_SPI_ADC_BF533_MODULE) ++ { ++ .modalias = "bfin_spi_adc", /* Name of spi_driver for this device */ ++ .max_speed_hz = 6250000, /* max spi clock (SCK) speed in HZ */ ++ .bus_num = 0, /* Framework bus number */ ++ .chip_select = 1, /* Framework chip select. */ ++ .platform_data = NULL, /* No spi_driver specific config */ ++ .controller_data = &spi_adc_chip_info, ++ }, ++#endif ++ ++#if defined(CONFIG_SND_BLACKFIN_AD1836) \ ++ || defined(CONFIG_SND_BLACKFIN_AD1836_MODULE) ++ { ++ .modalias = "ad1836-spi", ++ .max_speed_hz = 3125000, /* max spi clock (SCK) speed in HZ */ ++ .bus_num = 0, ++ .chip_select = CONFIG_SND_BLACKFIN_SPI_PFBIT, ++ .controller_data = &ad1836_spi_chip_info, ++ }, ++#endif ++#if defined(CONFIG_AD9960) || defined(CONFIG_AD9960_MODULE) ++ { ++ .modalias = "ad9960-spi", ++ .max_speed_hz = 10000000, /* max spi clock (SCK) speed in HZ */ ++ .bus_num = 0, ++ .chip_select = 1, ++ .controller_data = &ad9960_spi_chip_info, ++ }, ++#endif ++#if defined(CONFIG_SPI_MMC) || defined(CONFIG_SPI_MMC_MODULE) ++ { ++ .modalias = "spi_mmc_dummy", ++ .max_speed_hz = 25000000, /* max spi clock (SCK) speed in HZ */ ++ .bus_num = 0, ++ .chip_select = 0, ++ .platform_data = NULL, ++ .controller_data = &spi_mmc_chip_info, ++ .mode = SPI_MODE_3, ++ }, ++ { ++ .modalias = "spi_mmc", ++ .max_speed_hz = 25000000, /* max spi clock (SCK) speed in HZ */ ++ .bus_num = 0, ++ .chip_select = CONFIG_SPI_MMC_CS_CHAN, ++ .platform_data = NULL, ++ .controller_data = &spi_mmc_chip_info, ++ .mode = SPI_MODE_3, ++ }, ++#endif ++#if defined(CONFIG_PBX) ++ { ++ .modalias = "fxs-spi", ++ .max_speed_hz = 12500000, /* max spi clock (SCK) speed in HZ */ ++ .bus_num = 0, ++ .chip_select = 8 - CONFIG_J11_JUMPER, ++ .controller_data = &spi_si3xxx_chip_info, ++ .mode = SPI_MODE_3, ++ }, ++ { ++ .modalias = "fxo-spi", ++ .max_speed_hz = 12500000, /* max spi clock (SCK) speed in HZ */ ++ .bus_num = 0, ++ .chip_select = 8 - CONFIG_J19_JUMPER, ++ .controller_data = &spi_si3xxx_chip_info, ++ .mode = SPI_MODE_3, ++ }, ++#endif ++#if defined(CONFIG_TOUCHSCREEN_AD7877) || defined(CONFIG_TOUCHSCREEN_AD7877_MODULE) ++ { ++ .modalias = "ad7877", ++ .platform_data = &bfin_ad7877_ts_info, ++ .irq = IRQ_PF6, ++ .max_speed_hz = 12500000, /* max spi clock (SCK) speed in HZ */ ++ .bus_num = 0, ++ .chip_select = 1, ++ .controller_data = &spi_ad7877_chip_info, ++ }, ++#endif ++}; ++ ++/* SPI controller data */ ++static struct bfin5xx_spi_master bfin_spi0_info = { ++ .num_chipselect = 8, ++ .enable_dma = 1, /* master has the ability to do dma transfer */ ++ .pin_req = {P_SPI0_SCK, P_SPI0_MISO, P_SPI0_MOSI, 0}, ++}; ++ ++/* SPI (0) */ ++static struct resource bfin_spi0_resource[] = { ++ [0] = { ++ .start = SPI0_REGBASE, ++ .end = SPI0_REGBASE + 0xFF, ++ .flags = IORESOURCE_MEM, ++ }, ++ [1] = { ++ .start = CH_SPI, ++ .end = CH_SPI, ++ .flags = IORESOURCE_IRQ, ++ }, ++}; ++ ++static struct platform_device bfin_spi0_device = { ++ .name = "bfin-spi", ++ .id = 0, /* Bus number */ ++ .num_resources = ARRAY_SIZE(bfin_spi0_resource), ++ .resource = bfin_spi0_resource, ++ .dev = { ++ .platform_data = &bfin_spi0_info, /* Passed to driver */ ++ }, ++}; ++#endif /* spi master and devices */ ++ ++#if defined(CONFIG_FB_BF537_LQ035) || defined(CONFIG_FB_BF537_LQ035_MODULE) ++static struct platform_device bfin_fb_device = { ++ .name = "bf537-lq035", ++}; ++#endif ++ ++#if defined(CONFIG_FB_BFIN_7393) || defined(CONFIG_FB_BFIN_7393_MODULE) ++static struct platform_device bfin_fb_adv7393_device = { ++ .name = "bfin-adv7393", ++}; ++#endif ++ ++#if defined(CONFIG_SERIAL_BFIN) || defined(CONFIG_SERIAL_BFIN_MODULE) ++static struct resource bfin_uart_resources[] = { ++ { ++ .start = 0xFFC00400, ++ .end = 0xFFC004FF, ++ .flags = IORESOURCE_MEM, ++ }, { ++ .start = 0xFFC02000, ++ .end = 0xFFC020FF, ++ .flags = IORESOURCE_MEM, ++ }, ++}; ++ ++static struct platform_device bfin_uart_device = { ++ .name = "bfin-uart", ++ .id = 1, ++ .num_resources = ARRAY_SIZE(bfin_uart_resources), ++ .resource = bfin_uart_resources, ++}; ++#endif ++ ++#if defined(CONFIG_BFIN_SIR) || defined(CONFIG_BFIN_SIR_MODULE) ++#ifdef CONFIG_BFIN_SIR0 ++static struct resource bfin_sir0_resources[] = { ++ { ++ .start = 0xFFC00400, ++ .end = 0xFFC004FF, ++ .flags = IORESOURCE_MEM, ++ }, ++ { ++ .start = IRQ_UART0_RX, ++ .end = IRQ_UART0_RX+1, ++ .flags = IORESOURCE_IRQ, ++ }, ++ { ++ .start = CH_UART0_RX, ++ .end = CH_UART0_RX+1, ++ .flags = IORESOURCE_DMA, ++ }, ++}; ++ ++static struct platform_device bfin_sir0_device = { ++ .name = "bfin_sir", ++ .id = 0, ++ .num_resources = ARRAY_SIZE(bfin_sir0_resources), ++ .resource = bfin_sir0_resources, ++}; ++#endif ++#ifdef CONFIG_BFIN_SIR1 ++static struct resource bfin_sir1_resources[] = { ++ { ++ .start = 0xFFC02000, ++ .end = 0xFFC020FF, ++ .flags = IORESOURCE_MEM, ++ }, ++ { ++ .start = IRQ_UART1_RX, ++ .end = IRQ_UART1_RX+1, ++ .flags = IORESOURCE_IRQ, ++ }, ++ { ++ .start = CH_UART1_RX, ++ .end = CH_UART1_RX+1, ++ .flags = IORESOURCE_DMA, ++ }, ++}; ++ ++static struct platform_device bfin_sir1_device = { ++ .name = "bfin_sir", ++ .id = 1, ++ .num_resources = ARRAY_SIZE(bfin_sir1_resources), ++ .resource = bfin_sir1_resources, ++}; ++#endif ++#endif ++ ++#if defined(CONFIG_I2C_BLACKFIN_TWI) || defined(CONFIG_I2C_BLACKFIN_TWI_MODULE) ++static struct resource bfin_twi0_resource[] = { ++ [0] = { ++ .start = TWI0_REGBASE, ++ .end = TWI0_REGBASE + 0xFF, ++ .flags = IORESOURCE_MEM, ++ }, ++ [1] = { ++ .start = IRQ_TWI, ++ .end = IRQ_TWI, ++ .flags = IORESOURCE_IRQ, ++ }, ++}; ++ ++static struct platform_device i2c_bfin_twi_device = { ++ .name = "i2c-bfin-twi", ++ .id = 0, ++ .num_resources = ARRAY_SIZE(bfin_twi0_resource), ++ .resource = bfin_twi0_resource, ++}; ++#endif ++ ++#if defined(CONFIG_SERIAL_BFIN_SPORT) || defined(CONFIG_SERIAL_BFIN_SPORT_MODULE) ++static struct platform_device bfin_sport0_uart_device = { ++ .name = "bfin-sport-uart", ++ .id = 0, ++}; ++ ++static struct platform_device bfin_sport1_uart_device = { ++ .name = "bfin-sport-uart", ++ .id = 1, ++}; ++#endif ++ ++static struct platform_device *stamp_devices[] __initdata = { ++#if defined(CONFIG_BFIN_CFPCMCIA) || defined(CONFIG_BFIN_CFPCMCIA_MODULE) ++ &bfin_pcmcia_cf_device, ++#endif ++ ++#if defined(CONFIG_RTC_DRV_BFIN) || defined(CONFIG_RTC_DRV_BFIN_MODULE) ++ &rtc_device, ++#endif ++ ++#if defined(CONFIG_USB_SL811_HCD) || defined(CONFIG_USB_SL811_HCD_MODULE) ++ &sl811_hcd_device, ++#endif ++ ++#if defined(CONFIG_USB_ISP1362_HCD) || defined(CONFIG_USB_ISP1362_HCD_MODULE) ++ &isp1362_hcd_device, ++#endif ++ ++#if defined(CONFIG_SMC91X) || defined(CONFIG_SMC91X_MODULE) ++ &smc91x_device, ++#endif ++ ++#if defined(CONFIG_DM9000) || defined(CONFIG_DM9000_MODULE) ++ &dm9000_device, ++#endif ++ ++#if defined(CONFIG_BFIN_MAC) || defined(CONFIG_BFIN_MAC_MODULE) ++ &bfin_mac_device, ++#endif ++ ++#if defined(CONFIG_USB_NET2272) || defined(CONFIG_USB_NET2272_MODULE) ++ &net2272_bfin_device, ++#endif ++ ++#if defined(CONFIG_USB_ISP1760_HCD) || defined(CONFIG_USB_ISP1760_HCD_MODULE) ++ &bfin_isp1760_device, ++#endif ++ ++#if defined(CONFIG_SPI_BFIN) || defined(CONFIG_SPI_BFIN_MODULE) ++ &bfin_spi0_device, ++#endif ++ ++#if defined(CONFIG_FB_BF537_LQ035) || defined(CONFIG_FB_BF537_LQ035_MODULE) ++ &bfin_fb_device, ++#endif ++ ++#if defined(CONFIG_FB_BFIN_7393) || defined(CONFIG_FB_BFIN_7393_MODULE) ++ &bfin_fb_adv7393_device, ++#endif ++ ++#if defined(CONFIG_SERIAL_BFIN) || defined(CONFIG_SERIAL_BFIN_MODULE) ++ &bfin_uart_device, ++#endif ++ ++#if defined(CONFIG_BFIN_SIR) || defined(CONFIG_BFIN_SIR_MODULE) ++#ifdef CONFIG_BFIN_SIR0 ++ &bfin_sir0_device, ++#endif ++#ifdef CONFIG_BFIN_SIR1 ++ &bfin_sir1_device, ++#endif ++#endif ++ ++#if defined(CONFIG_I2C_BLACKFIN_TWI) || defined(CONFIG_I2C_BLACKFIN_TWI_MODULE) ++ &i2c_bfin_twi_device, ++#endif ++ ++#if defined(CONFIG_SERIAL_BFIN_SPORT) || defined(CONFIG_SERIAL_BFIN_SPORT_MODULE) ++ &bfin_sport0_uart_device, ++ &bfin_sport1_uart_device, ++#endif ++}; ++ ++static int __init stamp_init(void) ++{ ++ printk(KERN_INFO "%s(): registering device resources\n", __func__); ++ platform_add_devices(stamp_devices, ARRAY_SIZE(stamp_devices)); ++#if defined(CONFIG_SPI_BFIN) || defined(CONFIG_SPI_BFIN_MODULE) ++ spi_register_board_info(bfin_spi_board_info, ++ ARRAY_SIZE(bfin_spi_board_info)); ++#endif ++ ++ return 0; ++} ++ ++arch_initcall(stamp_init); ++ ++void native_machine_restart(char *cmd) ++{ ++ /* workaround reboot hang when booting from SPI */ ++ if ((bfin_read_SYSCR() & 0x7) == 0x3) ++ bfin_gpio_reset_spi0_ssel1(); ++} ++ ++#if defined(CONFIG_BFIN_MAC) || defined(CONFIG_BFIN_MAC_MODULE) ++void bfin_get_ether_addr(char *addr) ++{ ++ random_ether_addr(addr); ++ printk(KERN_WARNING "%s:%s: Setting Ethernet MAC to a random one\n", __FILE__, __func__); ++} ++EXPORT_SYMBOL(bfin_get_ether_addr); ++#endif +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/arch/blackfin/mach-bf537/boards/Kconfig linux-2.6.29-rc3.owrt/arch/blackfin/mach-bf537/boards/Kconfig +--- linux-2.6.29.owrt/arch/blackfin/mach-bf537/boards/Kconfig 2009-05-10 22:04:40.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/arch/blackfin/mach-bf537/boards/Kconfig 2009-05-10 23:48:28.000000000 +0200 +@@ -33,4 +33,9 @@ + help + Board supply package for CSP Minotaur + ++config GENERIC_BF537_BOARD ++ bool "Generic" ++ help ++ Generic or Custom board support. ++ + endchoice +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/arch/blackfin/mach-bf537/boards/Makefile linux-2.6.29-rc3.owrt/arch/blackfin/mach-bf537/boards/Makefile +--- linux-2.6.29.owrt/arch/blackfin/mach-bf537/boards/Makefile 2009-05-10 22:04:40.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/arch/blackfin/mach-bf537/boards/Makefile 2009-05-10 23:48:28.000000000 +0200 +@@ -2,6 +2,7 @@ + # arch/blackfin/mach-bf537/boards/Makefile + # + ++obj-$(CONFIG_GENERIC_BF537_BOARD) += generic_board.o + obj-$(CONFIG_BFIN537_STAMP) += stamp.o + obj-$(CONFIG_BFIN537_BLUETECHNIX_CM) += cm_bf537.o + obj-$(CONFIG_BFIN537_BLUETECHNIX_TCM) += tcm_bf537.o +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/arch/blackfin/mach-bf537/boards/minotaur.c linux-2.6.29-rc3.owrt/arch/blackfin/mach-bf537/boards/minotaur.c +--- linux-2.6.29.owrt/arch/blackfin/mach-bf537/boards/minotaur.c 2009-05-10 22:04:40.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/arch/blackfin/mach-bf537/boards/minotaur.c 2009-05-10 23:48:28.000000000 +0200 +@@ -61,13 +61,8 @@ + #endif + + #if defined(CONFIG_BFIN_MAC) || defined(CONFIG_BFIN_MAC_MODULE) +-static struct platform_device bfin_mii_bus = { +- .name = "bfin_mii_bus", +-}; +- + static struct platform_device bfin_mac_device = { + .name = "bfin_mac", +- .dev.platform_data = &bfin_mii_bus, + }; + #endif + +@@ -134,9 +129,9 @@ + }; + #endif + +-#if defined(CONFIG_MMC_SPI) || defined(CONFIG_MMC_SPI_MODULE) +-static struct bfin5xx_spi_chip mmc_spi_chip_info = { +- .enable_dma = 0, ++#if defined(CONFIG_SPI_MMC) || defined(CONFIG_SPI_MMC_MODULE) ++static struct bfin5xx_spi_chip spi_mmc_chip_info = { ++ .enable_dma = 1, + .bits_per_word = 8, + }; + #endif +@@ -156,13 +151,23 @@ + }, + #endif + +-#if defined(CONFIG_MMC_SPI) || defined(CONFIG_MMC_SPI_MODULE) ++#if defined(CONFIG_SPI_MMC) || defined(CONFIG_SPI_MMC_MODULE) ++ { ++ .modalias = "spi_mmc_dummy", ++ .max_speed_hz = 5000000, /* max spi clock (SCK) speed in HZ */ ++ .bus_num = 0, ++ .chip_select = 0, ++ .platform_data = NULL, ++ .controller_data = &spi_mmc_chip_info, ++ .mode = SPI_MODE_3, ++ }, + { +- .modalias = "mmc_spi", ++ .modalias = "spi_mmc", + .max_speed_hz = 5000000, /* max spi clock (SCK) speed in HZ */ + .bus_num = 0, +- .chip_select = 5, +- .controller_data = &mmc_spi_chip_info, ++ .chip_select = CONFIG_SPI_MMC_CS_CHAN, ++ .platform_data = NULL, ++ .controller_data = &spi_mmc_chip_info, + .mode = SPI_MODE_3, + }, + #endif +@@ -319,7 +324,6 @@ + #endif + + #if defined(CONFIG_BFIN_MAC) || defined(CONFIG_BFIN_MAC_MODULE) +- &bfin_mii_bus, + &bfin_mac_device, + #endif + +@@ -373,5 +377,5 @@ + { + /* workaround reboot hang when booting from SPI */ + if ((bfin_read_SYSCR() & 0x7) == 0x3) +- bfin_reset_boot_spi_cs(P_DEFAULT_BOOT_SPI_CS); ++ bfin_gpio_reset_spi0_ssel1(); + } +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/arch/blackfin/mach-bf537/boards/pnav10.c linux-2.6.29-rc3.owrt/arch/blackfin/mach-bf537/boards/pnav10.c +--- linux-2.6.29.owrt/arch/blackfin/mach-bf537/boards/pnav10.c 2009-05-10 22:04:40.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/arch/blackfin/mach-bf537/boards/pnav10.c 2009-05-10 23:48:28.000000000 +0200 +@@ -198,13 +198,8 @@ + #endif + + #if defined(CONFIG_BFIN_MAC) || defined(CONFIG_BFIN_MAC_MODULE) +-static struct platform_device bfin_mii_bus = { +- .name = "bfin_mii_bus", +-}; +- + static struct platform_device bfin_mac_device = { + .name = "bfin_mac", +- .dev.platform_data = &bfin_mii_bus, + }; + #endif + +@@ -289,9 +284,9 @@ + }; + #endif + +-#if defined(CONFIG_MMC_SPI) || defined(CONFIG_MMC_SPI_MODULE) +-static struct bfin5xx_spi_chip mmc_spi_chip_info = { +- .enable_dma = 0, ++#if defined(CONFIG_SPI_MMC) || defined(CONFIG_SPI_MMC_MODULE) ++static struct bfin5xx_spi_chip spi_mmc_chip_info = { ++ .enable_dma = 1, + .bits_per_word = 8, + }; + #endif +@@ -364,13 +359,23 @@ + .controller_data = &ad9960_spi_chip_info, + }, + #endif +-#if defined(CONFIG_MMC_SPI) || defined(CONFIG_MMC_SPI_MODULE) ++#if defined(CONFIG_SPI_MMC) || defined(CONFIG_SPI_MMC_MODULE) ++ { ++ .modalias = "spi_mmc_dummy", ++ .max_speed_hz = 25000000, /* max spi clock (SCK) speed in HZ */ ++ .bus_num = 0, ++ .chip_select = 7, ++ .platform_data = NULL, ++ .controller_data = &spi_mmc_chip_info, ++ .mode = SPI_MODE_3, ++ }, + { +- .modalias = "mmc_spi", ++ .modalias = "spi_mmc", + .max_speed_hz = 25000000, /* max spi clock (SCK) speed in HZ */ + .bus_num = 0, +- .chip_select = 5, +- .controller_data = &mmc_spi_chip_info, ++ .chip_select = CONFIG_SPI_MMC_CS_CHAN, ++ .platform_data = NULL, ++ .controller_data = &spi_mmc_chip_info, + .mode = SPI_MODE_3, + }, + #endif +@@ -524,7 +529,6 @@ + #endif + + #if defined(CONFIG_BFIN_MAC) || defined(CONFIG_BFIN_MAC_MODULE) +- &bfin_mii_bus, + &bfin_mac_device, + #endif + +@@ -554,7 +558,7 @@ + #endif + }; + +-static int __init pnav_init(void) ++static int __init stamp_init(void) + { + printk(KERN_INFO "%s(): registering device resources\n", __func__); + platform_add_devices(stamp_devices, ARRAY_SIZE(stamp_devices)); +@@ -565,7 +569,7 @@ + return 0; + } + +-arch_initcall(pnav_init); ++arch_initcall(stamp_init); + + void bfin_get_ether_addr(char *addr) + { +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/arch/blackfin/mach-bf537/boards/stamp.c linux-2.6.29-rc3.owrt/arch/blackfin/mach-bf537/boards/stamp.c +--- linux-2.6.29.owrt/arch/blackfin/mach-bf537/boards/stamp.c 2009-05-10 22:04:40.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/arch/blackfin/mach-bf537/boards/stamp.c 2009-05-10 23:48:28.000000000 +0200 +@@ -321,13 +321,8 @@ + #endif + + #if defined(CONFIG_BFIN_MAC) || defined(CONFIG_BFIN_MAC_MODULE) +-static struct platform_device bfin_mii_bus = { +- .name = "bfin_mii_bus", +-}; +- + static struct platform_device bfin_mac_device = { + .name = "bfin_mac", +- .dev.platform_data = &bfin_mii_bus, + }; + #endif + +@@ -1073,6 +1068,7 @@ + }; + #endif + ++#ifdef CONFIG_I2C_BOARDINFO + static struct i2c_board_info __initdata bfin_i2c_board_info[] = { + #if defined(CONFIG_JOYSTICK_AD7142) || defined(CONFIG_JOYSTICK_AD7142_MODULE) + { +@@ -1106,6 +1102,7 @@ + }, + #endif + }; ++#endif + + #if defined(CONFIG_SERIAL_BFIN_SPORT) || defined(CONFIG_SERIAL_BFIN_SPORT_MODULE) + static struct platform_device bfin_sport0_uart_device = { +@@ -1220,7 +1217,6 @@ + #endif + + #if defined(CONFIG_BFIN_MAC) || defined(CONFIG_BFIN_MAC_MODULE) +- &bfin_mii_bus, + &bfin_mac_device, + #endif + +@@ -1288,8 +1284,12 @@ + static int __init stamp_init(void) + { + printk(KERN_INFO "%s(): registering device resources\n", __func__); ++ ++#ifdef CONFIG_I2C_BOARDINFO + i2c_register_board_info(0, bfin_i2c_board_info, + ARRAY_SIZE(bfin_i2c_board_info)); ++#endif ++ + bfin_plat_nand_init(); + platform_add_devices(stamp_devices, ARRAY_SIZE(stamp_devices)); + spi_register_board_info(bfin_spi_board_info, ARRAY_SIZE(bfin_spi_board_info)); +@@ -1307,7 +1307,7 @@ + { + /* workaround reboot hang when booting from SPI */ + if ((bfin_read_SYSCR() & 0x7) == 0x3) +- bfin_reset_boot_spi_cs(P_DEFAULT_BOOT_SPI_CS); ++ bfin_gpio_reset_spi0_ssel1(); + } + + /* +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/arch/blackfin/mach-bf537/boards/tcm_bf537.c linux-2.6.29-rc3.owrt/arch/blackfin/mach-bf537/boards/tcm_bf537.c +--- linux-2.6.29.owrt/arch/blackfin/mach-bf537/boards/tcm_bf537.c 2009-05-10 22:04:40.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/arch/blackfin/mach-bf537/boards/tcm_bf537.c 2009-05-10 23:48:28.000000000 +0200 +@@ -108,9 +108,9 @@ + }; + #endif + +-#if defined(CONFIG_MMC_SPI) || defined(CONFIG_MMC_SPI_MODULE) +-static struct bfin5xx_spi_chip mmc_spi_chip_info = { +- .enable_dma = 0, ++#if defined(CONFIG_SPI_MMC) || defined(CONFIG_SPI_MMC_MODULE) ++static struct bfin5xx_spi_chip spi_mmc_chip_info = { ++ .enable_dma = 1, + .bits_per_word = 8, + }; + #endif +@@ -160,13 +160,23 @@ + }, + #endif + +-#if defined(CONFIG_MMC_SPI) || defined(CONFIG_MMC_SPI_MODULE) ++#if defined(CONFIG_SPI_MMC) || defined(CONFIG_SPI_MMC_MODULE) + { +- .modalias = "mmc_spi", ++ .modalias = "spi_mmc_dummy", + .max_speed_hz = 25000000, /* max spi clock (SCK) speed in HZ */ + .bus_num = 0, +- .chip_select = 5, +- .controller_data = &mmc_spi_chip_info, ++ .chip_select = 7, ++ .platform_data = NULL, ++ .controller_data = &spi_mmc_chip_info, ++ .mode = SPI_MODE_3, ++ }, ++ { ++ .modalias = "spi_mmc", ++ .max_speed_hz = 25000000, /* max spi clock (SCK) speed in HZ */ ++ .bus_num = 0, ++ .chip_select = CONFIG_SPI_MMC_CS_CHAN, ++ .platform_data = NULL, ++ .controller_data = &spi_mmc_chip_info, + .mode = SPI_MODE_3, + }, + #endif +@@ -471,13 +481,8 @@ + #endif + + #if defined(CONFIG_BFIN_MAC) || defined(CONFIG_BFIN_MAC_MODULE) +-static struct platform_device bfin_mii_bus = { +- .name = "bfin_mii_bus", +-}; +- + static struct platform_device bfin_mac_device = { + .name = "bfin_mac", +- .dev.platform_data = &bfin_mii_bus, + }; + #endif + +@@ -588,7 +593,6 @@ + #endif + + #if defined(CONFIG_BFIN_MAC) || defined(CONFIG_BFIN_MAC_MODULE) +- &bfin_mii_bus, + &bfin_mac_device, + #endif + +@@ -611,7 +615,7 @@ + &bfin_gpios_device, + }; + +-static int __init tcm_bf537_init(void) ++static int __init cm_bf537_init(void) + { + printk(KERN_INFO "%s(): registering device resources\n", __func__); + platform_add_devices(cm_bf537_devices, ARRAY_SIZE(cm_bf537_devices)); +@@ -625,7 +629,7 @@ + return 0; + } + +-arch_initcall(tcm_bf537_init); ++arch_initcall(cm_bf537_init); + + void bfin_get_ether_addr(char *addr) + { +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/arch/blackfin/mach-bf537/include/mach/anomaly.h linux-2.6.29-rc3.owrt/arch/blackfin/mach-bf537/include/mach/anomaly.h +--- linux-2.6.29.owrt/arch/blackfin/mach-bf537/include/mach/anomaly.h 2009-05-10 22:04:40.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/arch/blackfin/mach-bf537/include/mach/anomaly.h 2009-05-10 23:48:28.000000000 +0200 +@@ -2,7 +2,7 @@ + * File: include/asm-blackfin/mach-bf537/anomaly.h + * Bugs: Enter bugs at http://blackfin.uclinux.org/ + * +- * Copyright (C) 2004-2009 Analog Devices Inc. ++ * Copyright (C) 2004-2008 Analog Devices Inc. + * Licensed under the GPL-2 or later. + */ + +@@ -110,7 +110,7 @@ + #define ANOMALY_05000301 (1) + /* SSYNCs After Writes To CAN/DMA MMR Registers Are Not Always Handled Correctly */ + #define ANOMALY_05000304 (__SILICON_REVISION__ < 3) +-/* SPORT_HYS Bit in PLL_CTL Register Is Not Functional */ ++/* New Feature: Additional Hysteresis on SPORT Input Pins (Not Available On Older Silicon) */ + #define ANOMALY_05000305 (__SILICON_REVISION__ < 3) + /* SCKELOW Bit Does Not Maintain State Through Hibernate */ + #define ANOMALY_05000307 (__SILICON_REVISION__ < 3) +@@ -168,12 +168,9 @@ + #define ANOMALY_05000323 (0) + #define ANOMALY_05000353 (1) + #define ANOMALY_05000363 (0) +-#define ANOMALY_05000380 (0) + #define ANOMALY_05000386 (1) + #define ANOMALY_05000412 (0) + #define ANOMALY_05000432 (0) + #define ANOMALY_05000435 (0) +-#define ANOMALY_05000447 (0) +-#define ANOMALY_05000448 (0) + + #endif +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/arch/blackfin/mach-bf537/include/mach/bfin_serial_5xx.h linux-2.6.29-rc3.owrt/arch/blackfin/mach-bf537/include/mach/bfin_serial_5xx.h +--- linux-2.6.29.owrt/arch/blackfin/mach-bf537/include/mach/bfin_serial_5xx.h 2009-05-10 22:04:40.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/arch/blackfin/mach-bf537/include/mach/bfin_serial_5xx.h 2009-05-10 23:48:28.000000000 +0200 +@@ -144,7 +144,7 @@ + CH_UART0_TX, + CH_UART0_RX, + #endif +-#ifdef CONFIG_SERIAL_BFIN_CTSRTS ++#ifdef CONFIG_BFIN_UART0_CTSRTS + CONFIG_UART0_CTS_PIN, + CONFIG_UART0_RTS_PIN, + #endif +@@ -158,7 +158,7 @@ + CH_UART1_TX, + CH_UART1_RX, + #endif +-#ifdef CONFIG_SERIAL_BFIN_CTSRTS ++#ifdef CONFIG_BFIN_UART1_CTSRTS + CONFIG_UART1_CTS_PIN, + CONFIG_UART1_RTS_PIN, + #endif +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/arch/blackfin/mach-bf537/include/mach/portmux.h linux-2.6.29-rc3.owrt/arch/blackfin/mach-bf537/include/mach/portmux.h +--- linux-2.6.29.owrt/arch/blackfin/mach-bf537/include/mach/portmux.h 2009-05-10 22:04:40.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/arch/blackfin/mach-bf537/include/mach/portmux.h 2009-05-10 23:48:28.000000000 +0200 +@@ -31,7 +31,6 @@ + #define P_PPI0_FS1 (P_DEFINED | P_IDENT(GPIO_PF9) | P_FUNCT(1)) + #define P_TACLK0 (P_DEFINED | P_IDENT(GPIO_PF14) | P_FUNCT(1)) + #define P_TMRCLK (P_DEFINED | P_IDENT(GPIO_PF15) | P_FUNCT(1)) +-#define P_DEFAULT_BOOT_SPI_CS P_SPI0_SSEL1 + + #define P_PPI0_D0 (P_DEFINED | P_IDENT(GPIO_PG0) | P_FUNCT(0)) + #define P_PPI0_D1 (P_DEFINED | P_IDENT(GPIO_PG1) | P_FUNCT(0)) +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/arch/blackfin/mach-bf538/include/mach/anomaly.h linux-2.6.29-rc3.owrt/arch/blackfin/mach-bf538/include/mach/anomaly.h +--- linux-2.6.29.owrt/arch/blackfin/mach-bf538/include/mach/anomaly.h 2009-05-10 22:04:40.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/arch/blackfin/mach-bf538/include/mach/anomaly.h 2009-05-10 23:48:28.000000000 +0200 +@@ -2,7 +2,7 @@ + * File: include/asm-blackfin/mach-bf538/anomaly.h + * Bugs: Enter bugs at http://blackfin.uclinux.org/ + * +- * Copyright (C) 2004-2009 Analog Devices Inc. ++ * Copyright (C) 2004-2008 Analog Devices Inc. + * Licensed under the GPL-2 or later. + */ + +@@ -120,17 +120,13 @@ + #define ANOMALY_05000198 (0) + #define ANOMALY_05000230 (0) + #define ANOMALY_05000263 (0) +-#define ANOMALY_05000305 (0) + #define ANOMALY_05000311 (0) + #define ANOMALY_05000323 (0) + #define ANOMALY_05000353 (1) + #define ANOMALY_05000363 (0) +-#define ANOMALY_05000380 (0) + #define ANOMALY_05000386 (1) + #define ANOMALY_05000412 (0) + #define ANOMALY_05000432 (0) + #define ANOMALY_05000435 (0) +-#define ANOMALY_05000447 (0) +-#define ANOMALY_05000448 (0) + + #endif +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/arch/blackfin/mach-bf538/include/mach/bfin_serial_5xx.h linux-2.6.29-rc3.owrt/arch/blackfin/mach-bf538/include/mach/bfin_serial_5xx.h +--- linux-2.6.29.owrt/arch/blackfin/mach-bf538/include/mach/bfin_serial_5xx.h 2009-05-10 22:04:40.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/arch/blackfin/mach-bf538/include/mach/bfin_serial_5xx.h 2009-05-10 23:48:28.000000000 +0200 +@@ -144,7 +144,7 @@ + CH_UART0_TX, + CH_UART0_RX, + #endif +-#ifdef CONFIG_SERIAL_BFIN_CTSRTS ++#ifdef CONFIG_BFIN_UART0_CTSRTS + CONFIG_UART0_CTS_PIN, + CONFIG_UART0_RTS_PIN, + #endif +@@ -158,7 +158,7 @@ + CH_UART1_TX, + CH_UART1_RX, + #endif +-#ifdef CONFIG_SERIAL_BFIN_CTSRTS ++#ifdef CONFIG_BFIN_UART1_CTSRTS + CONFIG_UART1_CTS_PIN, + CONFIG_UART1_RTS_PIN, + #endif +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/arch/blackfin/mach-bf538/include/mach/portmux.h linux-2.6.29-rc3.owrt/arch/blackfin/mach-bf538/include/mach/portmux.h +--- linux-2.6.29.owrt/arch/blackfin/mach-bf538/include/mach/portmux.h 2009-05-10 22:04:40.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/arch/blackfin/mach-bf538/include/mach/portmux.h 2009-05-10 23:48:28.000000000 +0200 +@@ -102,6 +102,5 @@ + #define P_SPI0_SSEL2 (P_DEFINED | P_IDENT(GPIO_PF2)) + #define P_SPI0_SSEL1 (P_DEFINED | P_IDENT(GPIO_PF1)) + #define P_SPI0_SS (P_DEFINED | P_IDENT(GPIO_PF0)) +-#define P_DEFAULT_BOOT_SPI_CS P_SPI0_SSEL2 + + #endif /* _MACH_PORTMUX_H_ */ +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/arch/blackfin/mach-bf548/boards/ezkit.c linux-2.6.29-rc3.owrt/arch/blackfin/mach-bf548/boards/ezkit.c +--- linux-2.6.29.owrt/arch/blackfin/mach-bf548/boards/ezkit.c 2009-05-10 22:04:41.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/arch/blackfin/mach-bf548/boards/ezkit.c 2009-05-10 23:48:28.000000000 +0200 +@@ -781,6 +781,7 @@ + #endif + #endif + ++#ifdef CONFIG_I2C_BOARDINFO + static struct i2c_board_info __initdata bfin_i2c_board_info0[] = { + }; + +@@ -799,6 +800,7 @@ + #endif + }; + #endif ++#endif + + #if defined(CONFIG_KEYBOARD_GPIO) || defined(CONFIG_KEYBOARD_GPIO_MODULE) + #include <linux/gpio_keys.h> +@@ -954,12 +956,14 @@ + { + printk(KERN_INFO "%s(): registering device resources\n", __func__); + ++#ifdef CONFIG_I2C_BOARDINFO + i2c_register_board_info(0, bfin_i2c_board_info0, + ARRAY_SIZE(bfin_i2c_board_info0)); + #if !defined(CONFIG_BF542) /* The BF542 only has 1 TWI */ + i2c_register_board_info(1, bfin_i2c_board_info1, + ARRAY_SIZE(bfin_i2c_board_info1)); + #endif ++#endif + + platform_add_devices(ezkit_devices, ARRAY_SIZE(ezkit_devices)); + +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/arch/blackfin/mach-bf548/include/mach/anomaly.h linux-2.6.29-rc3.owrt/arch/blackfin/mach-bf548/include/mach/anomaly.h +--- linux-2.6.29.owrt/arch/blackfin/mach-bf548/include/mach/anomaly.h 2009-05-10 22:04:40.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/arch/blackfin/mach-bf548/include/mach/anomaly.h 2009-05-10 23:48:28.000000000 +0200 +@@ -2,12 +2,12 @@ + * File: include/asm-blackfin/mach-bf548/anomaly.h + * Bugs: Enter bugs at http://blackfin.uclinux.org/ + * +- * Copyright (C) 2004-2009 Analog Devices Inc. ++ * Copyright (C) 2004-2008 Analog Devices Inc. + * Licensed under the GPL-2 or later. + */ + + /* This file shoule be up to date with: +- * - Revision H, 01/16/2009; ADSP-BF542/BF544/BF547/BF548/BF549 Blackfin Processor Anomaly List ++ * - Revision G, 08/07/2008; ADSP-BF542/BF544/BF547/BF548/BF549 Blackfin Processor Anomaly List + */ + + #ifndef _MACH_ANOMALY_H_ +@@ -91,6 +91,8 @@ + #define ANOMALY_05000371 (__SILICON_REVISION__ < 2) + /* USB DP/DM Data Pins May Lose State When Entering Hibernate */ + #define ANOMALY_05000372 (__SILICON_REVISION__ < 1) ++/* Mobile DDR Operation Not Functional */ ++#define ANOMALY_05000377 (1) + /* Security/Authentication Speedpath Causes Authentication To Fail To Initiate */ + #define ANOMALY_05000378 (__SILICON_REVISION__ < 2) + /* 16-Bit NAND FLASH Boot Mode Is Not Functional */ +@@ -155,22 +157,8 @@ + #define ANOMALY_05000429 (__SILICON_REVISION__ < 2) + /* Software System Reset Corrupts PLL_LOCKCNT Register */ + #define ANOMALY_05000430 (__SILICON_REVISION__ >= 2) +-/* Incorrect Use of Stack in Lockbox Firmware During Authentication */ +-#define ANOMALY_05000431 (__SILICON_REVISION__ < 3) +-/* OTP Write Accesses Not Supported */ +-#define ANOMALY_05000442 (__SILICON_REVISION__ < 1) + /* IFLUSH Instruction at End of Hardware Loop Causes Infinite Stall */ + #define ANOMALY_05000443 (1) +-/* CDMAPRIO and L2DMAPRIO Bits in the SYSCR Register Are Not Functional */ +-#define ANOMALY_05000446 (1) +-/* UART IrDA Receiver Fails on Extended Bit Pulses */ +-#define ANOMALY_05000447 (1) +-/* DDR Clock Duty Cycle Spec Violation (tCH, tCL) */ +-#define ANOMALY_05000448 (__SILICON_REVISION__ == 1) +-/* Reduced Timing Margins on DDR Output Setup and Hold (tDS and tDH) */ +-#define ANOMALY_05000449 (__SILICON_REVISION__ == 1) +-/* USB DMA Mode 1 Short Packet Data Corruption */ +-#define ANOMALY_05000450 (1 + + /* Anomalies that don't exist on this proc */ + #define ANOMALY_05000125 (0) +@@ -183,13 +171,10 @@ + #define ANOMALY_05000263 (0) + #define ANOMALY_05000266 (0) + #define ANOMALY_05000273 (0) +-#define ANOMALY_05000278 (0) +-#define ANOMALY_05000305 (0) + #define ANOMALY_05000307 (0) + #define ANOMALY_05000311 (0) + #define ANOMALY_05000323 (0) + #define ANOMALY_05000363 (0) +-#define ANOMALY_05000380 (0) + #define ANOMALY_05000412 (0) + #define ANOMALY_05000432 (0) + #define ANOMALY_05000435 (0) +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/arch/blackfin/mach-bf548/include/mach/bf548.h linux-2.6.29-rc3.owrt/arch/blackfin/mach-bf548/include/mach/bf548.h +--- linux-2.6.29.owrt/arch/blackfin/mach-bf548/include/mach/bf548.h 2009-05-10 22:04:41.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/arch/blackfin/mach-bf548/include/mach/bf548.h 2009-05-10 23:48:28.000000000 +0200 +@@ -104,18 +104,6 @@ + + #define AMGCTLVAL (V_AMBEN | V_AMCKEN) + +-#if defined(CONFIG_BF542M) +-# define CONFIG_BF542 +-#elif defined(CONFIG_BF544M) +-# define CONFIG_BF544 +-#elif defined(CONFIG_BF547M) +-# define CONFIG_BF547 +-#elif defined(CONFIG_BF548M) +-# define CONFIG_BF548 +-#elif defined(CONFIG_BF549M) +-# define CONFIG_BF549 +-#endif +- + #if defined(CONFIG_BF542) + # define CPU "BF542" + # define CPUID 0x27de +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/arch/blackfin/mach-bf548/include/mach/bfin_serial_5xx.h linux-2.6.29-rc3.owrt/arch/blackfin/mach-bf548/include/mach/bfin_serial_5xx.h +--- linux-2.6.29.owrt/arch/blackfin/mach-bf548/include/mach/bfin_serial_5xx.h 2009-05-10 22:04:40.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/arch/blackfin/mach-bf548/include/mach/bfin_serial_5xx.h 2009-05-10 23:48:28.000000000 +0200 +@@ -63,7 +63,7 @@ + #define UART_ENABLE_INTS(x, v) UART_SET_IER(x, v) + #define UART_DISABLE_INTS(x) UART_CLEAR_IER(x, 0xF) + +-#if defined(CONFIG_BFIN_UART0_CTSRTS) || defined(CONFIG_BFIN_UART2_CTSRTS) ++#if defined(CONFIG_BFIN_UART0_CTSRTS) || defined(CONFIG_BFIN_UART1_CTSRTS) + # define CONFIG_SERIAL_BFIN_CTSRTS + + # ifndef CONFIG_UART0_CTS_PIN +@@ -74,12 +74,12 @@ + # define CONFIG_UART0_RTS_PIN -1 + # endif + +-# ifndef CONFIG_UART2_CTS_PIN +-# define CONFIG_UART2_CTS_PIN -1 ++# ifndef CONFIG_UART1_CTS_PIN ++# define CONFIG_UART1_CTS_PIN -1 + # endif + +-# ifndef CONFIG_UART2_RTS_PIN +-# define CONFIG_UART2_RTS_PIN -1 ++# ifndef CONFIG_UART1_RTS_PIN ++# define CONFIG_UART1_RTS_PIN -1 + # endif + #endif + +@@ -130,7 +130,7 @@ + CH_UART0_TX, + CH_UART0_RX, + #endif +-#ifdef CONFIG_SERIAL_BFIN_CTSRTS ++#ifdef CONFIG_BFIN_UART0_CTSRTS + CONFIG_UART0_CTS_PIN, + CONFIG_UART0_RTS_PIN, + #endif +@@ -144,10 +144,6 @@ + CH_UART1_TX, + CH_UART1_RX, + #endif +-#ifdef CONFIG_SERIAL_BFIN_CTSRTS +- 0, +- 0, +-#endif + }, + #endif + #ifdef CONFIG_SERIAL_BFIN_UART2 +@@ -158,7 +154,7 @@ + CH_UART2_TX, + CH_UART2_RX, + #endif +-#ifdef CONFIG_SERIAL_BFIN_CTSRTS ++#ifdef CONFIG_BFIN_UART2_CTSRTS + CONFIG_UART2_CTS_PIN, + CONFIG_UART2_RTS_PIN, + #endif +@@ -172,10 +168,6 @@ + CH_UART3_TX, + CH_UART3_RX, + #endif +-#ifdef CONFIG_SERIAL_BFIN_CTSRTS +- 0, +- 0, +-#endif + }, + #endif + }; +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/arch/blackfin/mach-bf548/include/mach/gpio.h linux-2.6.29-rc3.owrt/arch/blackfin/mach-bf548/include/mach/gpio.h +--- linux-2.6.29.owrt/arch/blackfin/mach-bf548/include/mach/gpio.h 2009-05-10 22:04:41.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/arch/blackfin/mach-bf548/include/mach/gpio.h 2009-05-10 23:48:28.000000000 +0200 +@@ -195,17 +195,17 @@ + struct gpio_port_t { + unsigned short port_fer; + unsigned short dummy1; +- unsigned short data; ++ unsigned short port_data; + unsigned short dummy2; +- unsigned short data_set; ++ unsigned short port_set; + unsigned short dummy3; +- unsigned short data_clear; ++ unsigned short port_clear; + unsigned short dummy4; +- unsigned short dir_set; ++ unsigned short port_dir_set; + unsigned short dummy5; +- unsigned short dir_clear; ++ unsigned short port_dir_clear; + unsigned short dummy6; +- unsigned short inen; ++ unsigned short port_inen; + unsigned short dummy7; + unsigned int port_mux; + }; +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/arch/blackfin/mach-bf548/include/mach/irq.h linux-2.6.29-rc3.owrt/arch/blackfin/mach-bf548/include/mach/irq.h +--- linux-2.6.29.owrt/arch/blackfin/mach-bf548/include/mach/irq.h 2009-05-10 22:04:41.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/arch/blackfin/mach-bf548/include/mach/irq.h 2009-05-10 23:48:28.000000000 +0200 +@@ -123,8 +123,8 @@ + #define IRQ_MXVR_ERROR BFIN_IRQ(51) /* MXVR Status (Error) Interrupt */ + #define IRQ_MXVR_MSG BFIN_IRQ(52) /* MXVR Message Interrupt */ + #define IRQ_MXVR_PKT BFIN_IRQ(53) /* MXVR Packet Interrupt */ +-#define IRQ_EPPI1_ERROR BFIN_IRQ(54) /* EPPI1 Error Interrupt */ +-#define IRQ_EPPI2_ERROR BFIN_IRQ(55) /* EPPI2 Error Interrupt */ ++#define IRQ_EPP1_ERROR BFIN_IRQ(54) /* EPPI1 Error Interrupt */ ++#define IRQ_EPP2_ERROR BFIN_IRQ(55) /* EPPI2 Error Interrupt */ + #define IRQ_UART3_ERROR BFIN_IRQ(56) /* UART3 Status (Error) Interrupt */ + #define IRQ_HOST_ERROR BFIN_IRQ(57) /* HOST Status (Error) Interrupt */ + #define IRQ_PIXC_ERROR BFIN_IRQ(59) /* PIXC Status (Error) Interrupt */ +@@ -361,8 +361,8 @@ + #define IRQ_UART2_ERR IRQ_UART2_ERROR + #define IRQ_CAN0_ERR IRQ_CAN0_ERROR + #define IRQ_MXVR_ERR IRQ_MXVR_ERROR +-#define IRQ_EPPI1_ERR IRQ_EPPI1_ERROR +-#define IRQ_EPPI2_ERR IRQ_EPPI2_ERROR ++#define IRQ_EPP1_ERR IRQ_EPP1_ERROR ++#define IRQ_EPP2_ERR IRQ_EPP2_ERROR + #define IRQ_UART3_ERR IRQ_UART3_ERROR + #define IRQ_HOST_ERR IRQ_HOST_ERROR + #define IRQ_PIXC_ERR IRQ_PIXC_ERROR +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/arch/blackfin/mach-bf548/include/mach/portmux.h linux-2.6.29-rc3.owrt/arch/blackfin/mach-bf548/include/mach/portmux.h +--- linux-2.6.29.owrt/arch/blackfin/mach-bf548/include/mach/portmux.h 2009-05-10 22:04:41.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/arch/blackfin/mach-bf548/include/mach/portmux.h 2009-05-10 23:48:28.000000000 +0200 +@@ -125,7 +125,6 @@ + #define P_KEY_COL2 (P_DEFINED | P_IDENT(GPIO_PD14) | P_FUNCT(3)) + #define P_KEY_COL3 (P_DEFINED | P_IDENT(GPIO_PD15) | P_FUNCT(3)) + +-#define P_DEFAULT_BOOT_SPI_CS P_SPI0_SSEL1 + #define P_SPI0_SCK (P_DEFINED | P_IDENT(GPIO_PE0) | P_FUNCT(0)) + #define P_SPI0_MISO (P_DEFINED | P_IDENT(GPIO_PE1) | P_FUNCT(0)) + #define P_SPI0_MOSI (P_DEFINED | P_IDENT(GPIO_PE2) | P_FUNCT(0)) +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/arch/blackfin/mach-bf561/boards/cm_bf561.c linux-2.6.29-rc3.owrt/arch/blackfin/mach-bf561/boards/cm_bf561.c +--- linux-2.6.29.owrt/arch/blackfin/mach-bf561/boards/cm_bf561.c 2009-05-10 22:04:40.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/arch/blackfin/mach-bf561/boards/cm_bf561.c 2009-05-10 23:48:28.000000000 +0200 +@@ -105,9 +105,9 @@ + }; + #endif + +-#if defined(CONFIG_MMC_SPI) || defined(CONFIG_MMC_SPI_MODULE) +-static struct bfin5xx_spi_chip mmc_spi_chip_info = { +- .enable_dma = 0, ++#if defined(CONFIG_SPI_MMC) || defined(CONFIG_SPI_MMC_MODULE) ++static struct bfin5xx_spi_chip spi_mmc_chip_info = { ++ .enable_dma = 1, + .bits_per_word = 8, + }; + #endif +@@ -155,13 +155,14 @@ + .controller_data = &ad9960_spi_chip_info, + }, + #endif +-#if defined(CONFIG_MMC_SPI) || defined(CONFIG_MMC_SPI_MODULE) ++#if defined(CONFIG_SPI_MMC) || defined(CONFIG_SPI_MMC_MODULE) + { +- .modalias = "mmc_spi", ++ .modalias = "spi_mmc", + .max_speed_hz = 25000000, /* max spi clock (SCK) speed in HZ */ + .bus_num = 0, +- .chip_select = 5, +- .controller_data = &mmc_spi_chip_info, ++ .chip_select = CONFIG_SPI_MMC_CS_CHAN, ++ .platform_data = NULL, ++ .controller_data = &spi_mmc_chip_info, + .mode = SPI_MODE_3, + }, + #endif +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/arch/blackfin/mach-bf561/boards/generic_board.c linux-2.6.29-rc3.owrt/arch/blackfin/mach-bf561/boards/generic_board.c +--- linux-2.6.29.owrt/arch/blackfin/mach-bf561/boards/generic_board.c 1970-01-01 01:00:00.000000000 +0100 ++++ linux-2.6.29-rc3.owrt/arch/blackfin/mach-bf561/boards/generic_board.c 2009-05-10 23:48:28.000000000 +0200 +@@ -0,0 +1,113 @@ ++/* ++ * File: arch/blackfin/mach-bf561/generic_board.c ++ * Based on: arch/blackfin/mach-bf533/ezkit.c ++ * Author: Aidan Williams <aidan@nicta.com.au> ++ * ++ * Created: ++ * Description: ++ * ++ * Modified: ++ * Copyright 2005 National ICT Australia (NICTA) ++ * Copyright 2004-2006 Analog Devices Inc. ++ * ++ * Bugs: Enter bugs at http://blackfin.uclinux.org/ ++ * ++ * 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, see the file COPYING, or write ++ * to the Free Software Foundation, Inc., ++ * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA ++ */ ++ ++#include <linux/device.h> ++#include <linux/platform_device.h> ++#include <linux/irq.h> ++ ++const char bfin_board_name[] = "UNKNOWN BOARD"; ++ ++/* ++ * Driver needs to know address, irq and flag pin. ++ */ ++#if defined(CONFIG_SMC91X) || defined(CONFIG_SMC91X_MODULE) ++static struct resource smc91x_resources[] = { ++ { ++ .start = 0x2C010300, ++ .end = 0x2C010300 + 16, ++ .flags = IORESOURCE_MEM, ++ }, { ++ .start = IRQ_PROG_INTB, ++ .end = IRQ_PROG_INTB, ++ .flags = IORESOURCE_IRQ | IORESOURCE_IRQ_HIGHLEVEL, ++ }, { ++ .start = IRQ_PF9, ++ .end = IRQ_PF9, ++ .flags = IORESOURCE_IRQ | IORESOURCE_IRQ_HIGHLEVEL, ++ }, ++}; ++ ++static struct platform_device smc91x_device = { ++ .name = "smc91x", ++ .id = 0, ++ .num_resources = ARRAY_SIZE(smc91x_resources), ++ .resource = smc91x_resources, ++}; ++#endif ++ ++#if defined(CONFIG_BFIN_SIR) || defined(CONFIG_BFIN_SIR_MODULE) ++#ifdef CONFIG_BFIN_SIR0 ++static struct resource bfin_sir0_resources[] = { ++ { ++ .start = 0xFFC00400, ++ .end = 0xFFC004FF, ++ .flags = IORESOURCE_MEM, ++ }, ++ { ++ .start = IRQ_UART0_RX, ++ .end = IRQ_UART0_RX+1, ++ .flags = IORESOURCE_IRQ, ++ }, ++ { ++ .start = CH_UART0_RX, ++ .end = CH_UART0_RX+1, ++ .flags = IORESOURCE_DMA, ++ }, ++}; ++ ++static struct platform_device bfin_sir0_device = { ++ .name = "bfin_sir", ++ .id = 0, ++ .num_resources = ARRAY_SIZE(bfin_sir0_resources), ++ .resource = bfin_sir0_resources, ++}; ++#endif ++#endif ++ ++static struct platform_device *generic_board_devices[] __initdata = { ++#if defined(CONFIG_SMC91X) || defined(CONFIG_SMC91X_MODULE) ++ &smc91x_device, ++#endif ++ ++#if defined(CONFIG_BFIN_SIR) || defined(CONFIG_BFIN_SIR_MODULE) ++#ifdef CONFIG_BFIN_SIR0 ++ &bfin_sir0_device, ++#endif ++#endif ++}; ++ ++static int __init generic_board_init(void) ++{ ++ printk(KERN_INFO "%s(): registering device resources\n", __func__); ++ return platform_add_devices(generic_board_devices, ++ ARRAY_SIZE(generic_board_devices)); ++} ++ ++arch_initcall(generic_board_init); +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/arch/blackfin/mach-bf561/boards/Kconfig linux-2.6.29-rc3.owrt/arch/blackfin/mach-bf561/boards/Kconfig +--- linux-2.6.29.owrt/arch/blackfin/mach-bf561/boards/Kconfig 2009-05-10 22:04:40.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/arch/blackfin/mach-bf561/boards/Kconfig 2009-05-10 23:48:28.000000000 +0200 +@@ -19,4 +19,9 @@ + help + CM-BF561 support for EVAL- and DEV-Board. + ++config GENERIC_BF561_BOARD ++ bool "Generic" ++ help ++ Generic or Custom board support. ++ + endchoice +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/arch/blackfin/mach-bf561/boards/Makefile linux-2.6.29-rc3.owrt/arch/blackfin/mach-bf561/boards/Makefile +--- linux-2.6.29.owrt/arch/blackfin/mach-bf561/boards/Makefile 2009-05-10 22:04:40.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/arch/blackfin/mach-bf561/boards/Makefile 2009-05-10 23:48:28.000000000 +0200 +@@ -2,6 +2,7 @@ + # arch/blackfin/mach-bf561/boards/Makefile + # + ++obj-$(CONFIG_GENERIC_BF561_BOARD) += generic_board.o + obj-$(CONFIG_BFIN561_BLUETECHNIX_CM) += cm_bf561.o + obj-$(CONFIG_BFIN561_EZKIT) += ezkit.o + obj-$(CONFIG_BFIN561_TEPLA) += tepla.o +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/arch/blackfin/mach-bf561/include/mach/anomaly.h linux-2.6.29-rc3.owrt/arch/blackfin/mach-bf561/include/mach/anomaly.h +--- linux-2.6.29.owrt/arch/blackfin/mach-bf561/include/mach/anomaly.h 2009-05-10 22:04:40.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/arch/blackfin/mach-bf561/include/mach/anomaly.h 2009-05-10 23:48:28.000000000 +0200 +@@ -2,7 +2,7 @@ + * File: include/asm-blackfin/mach-bf561/anomaly.h + * Bugs: Enter bugs at http://blackfin.uclinux.org/ + * +- * Copyright (C) 2004-2009 Analog Devices Inc. ++ * Copyright (C) 2004-2008 Analog Devices Inc. + * Licensed under the GPL-2 or later. + */ + +@@ -224,7 +224,7 @@ + #define ANOMALY_05000301 (1) + /* SSYNCs After Writes To DMA MMR Registers May Not Be Handled Correctly */ + #define ANOMALY_05000302 (1) +-/* SPORT_HYS Bit in PLL_CTL Register Is Not Functional */ ++/* New Feature: Additional Hysteresis on SPORT Input Pins (Not Available On Older Silicon) */ + #define ANOMALY_05000305 (__SILICON_REVISION__ < 5) + /* SCKELOW Bit Does Not Maintain State Through Hibernate */ + #define ANOMALY_05000307 (__SILICON_REVISION__ < 5) +@@ -283,11 +283,8 @@ + #define ANOMALY_05000273 (0) + #define ANOMALY_05000311 (0) + #define ANOMALY_05000353 (1) +-#define ANOMALY_05000380 (0) + #define ANOMALY_05000386 (1) + #define ANOMALY_05000432 (0) + #define ANOMALY_05000435 (0) +-#define ANOMALY_05000447 (0) +-#define ANOMALY_05000448 (0) + + #endif +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/arch/blackfin/mach-bf561/include/mach/bfin_serial_5xx.h linux-2.6.29-rc3.owrt/arch/blackfin/mach-bf561/include/mach/bfin_serial_5xx.h +--- linux-2.6.29.owrt/arch/blackfin/mach-bf561/include/mach/bfin_serial_5xx.h 2009-05-10 22:04:40.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/arch/blackfin/mach-bf561/include/mach/bfin_serial_5xx.h 2009-05-10 23:48:28.000000000 +0200 +@@ -134,7 +134,7 @@ + CH_UART_TX, + CH_UART_RX, + #endif +-#ifdef CONFIG_SERIAL_BFIN_CTSRTS ++#ifdef CONFIG_BFIN_UART0_CTSRTS + CONFIG_UART0_CTS_PIN, + CONFIG_UART0_RTS_PIN, + #endif +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/arch/blackfin/mach-bf561/include/mach/defBF561.h linux-2.6.29-rc3.owrt/arch/blackfin/mach-bf561/include/mach/defBF561.h +--- linux-2.6.29.owrt/arch/blackfin/mach-bf561/include/mach/defBF561.h 2009-05-10 22:04:40.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/arch/blackfin/mach-bf561/include/mach/defBF561.h 2009-05-10 23:48:28.000000000 +0200 +@@ -1106,8 +1106,6 @@ + #define DLEN_8 0x0 /* PPI Data Length mask for DLEN=8 */ + #define DLEN(x) (((x-9) & 0x07) << 11) /* PPI Data Length (only works for x=10-->x=16) */ + #define POL 0x0000C000 /* PPI Signal Polarities */ +-#define POLC 0x4000 /* PPI Clock Polarity */ +-#define POLS 0x8000 /* PPI Frame Sync Polarity */ + + /* PPI_STATUS Masks */ + #define FLD 0x00000400 /* Field Indicator */ +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/arch/blackfin/mach-bf561/include/mach/portmux.h linux-2.6.29-rc3.owrt/arch/blackfin/mach-bf561/include/mach/portmux.h +--- linux-2.6.29.owrt/arch/blackfin/mach-bf561/include/mach/portmux.h 2009-05-10 22:04:40.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/arch/blackfin/mach-bf561/include/mach/portmux.h 2009-05-10 23:48:28.000000000 +0200 +@@ -85,6 +85,5 @@ + #define P_SPI0_MOSI (P_DONTCARE) + #define P_SPI0_MISO (P_DONTCARE) + #define P_SPI0_SCK (P_DONTCARE) +-#define P_DEFAULT_BOOT_SPI_CS P_SPI0_SSEL2 + + #endif /* _MACH_PORTMUX_H_ */ +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/arch/blackfin/mach-common/arch_checks.c linux-2.6.29-rc3.owrt/arch/blackfin/mach-common/arch_checks.c +--- linux-2.6.29.owrt/arch/blackfin/mach-common/arch_checks.c 2009-05-10 22:04:40.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/arch/blackfin/mach-common/arch_checks.c 2009-05-10 23:48:28.000000000 +0200 +@@ -62,12 +62,3 @@ + #if (CONFIG_BOOT_LOAD & 0x3) + # error "The kernel load address must be 4 byte aligned" + #endif +- +-/* The entire kernel must be able to make a 24bit pcrel call to start of L1 */ +-#if ((0xffffffff - L1_CODE_START + 1) + CONFIG_BOOT_LOAD) > 0x1000000 +-# error "The kernel load address is too high; keep it below 10meg for safety" +-#endif +- +-#if ANOMALY_05000448 +-# error You are using a part with anomaly 05000448, this issue causes random memory read/write failures - that means random crashes. +-#endif +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/arch/blackfin/mach-common/cache.S linux-2.6.29-rc3.owrt/arch/blackfin/mach-common/cache.S +--- linux-2.6.29.owrt/arch/blackfin/mach-common/cache.S 2009-05-10 22:04:40.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/arch/blackfin/mach-common/cache.S 2009-05-10 23:48:28.000000000 +0200 +@@ -66,33 +66,11 @@ + + /* Invalidate all instruction cache lines assocoiated with this memory area */ + ENTRY(_blackfin_icache_flush_range) +-/* +- * Walkaround to avoid loading wrong instruction after invalidating icache +- * and following sequence is met. +- * +- * 1) One instruction address is cached in the instruction cache. +- * 2) This instruction in SDRAM is changed. +- * 3) IFLASH[P0] is executed only once in blackfin_icache_flush_range(). +- * 4) This instruction is executed again, but the old one is loaded. +- */ +- P0 = R0; +- IFLUSH[P0]; + do_flush IFLUSH, , nop + ENDPROC(_blackfin_icache_flush_range) + + /* Flush all cache lines assocoiated with this area of memory. */ + ENTRY(_blackfin_icache_dcache_flush_range) +-/* +- * Walkaround to avoid loading wrong instruction after invalidating icache +- * and following sequence is met. +- * +- * 1) One instruction address is cached in the instruction cache. +- * 2) This instruction in SDRAM is changed. +- * 3) IFLASH[P0] is executed only once in blackfin_icache_flush_range(). +- * 4) This instruction is executed again, but the old one is loaded. +- */ +- P0 = R0; +- IFLUSH[P0]; + do_flush FLUSH, IFLUSH + ENDPROC(_blackfin_icache_dcache_flush_range) + +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/arch/blackfin/mach-common/clocks-init.c linux-2.6.29-rc3.owrt/arch/blackfin/mach-common/clocks-init.c +--- linux-2.6.29.owrt/arch/blackfin/mach-common/clocks-init.c 2009-05-10 22:04:40.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/arch/blackfin/mach-common/clocks-init.c 2009-05-10 23:48:28.000000000 +0200 +@@ -14,10 +14,9 @@ + #include <asm/clocks.h> + #include <asm/mem_init.h> + +-#define SDGCTL_WIDTH (1 << 31) /* SDRAM external data path width */ + #define PLL_CTL_VAL \ + (((CONFIG_VCO_MULT & 63) << 9) | CLKIN_HALF | \ +- (PLL_BYPASS << 8) | (ANOMALY_05000305 ? 0 : 0x8000)) ++ (PLL_BYPASS << 8) | (ANOMALY_05000265 ? 0x8000 : 0)) + + __attribute__((l1_text)) + static void do_sync(void) +@@ -77,7 +76,7 @@ + bfin_write_PLL_DIV(CONFIG_CCLK_ACT_DIV | CONFIG_SCLK_DIV); + #ifdef EBIU_SDGCTL + bfin_write_EBIU_SDRRC(mem_SDRRC); +- bfin_write_EBIU_SDGCTL((bfin_read_EBIU_SDGCTL() & SDGCTL_WIDTH) | mem_SDGCTL); ++ bfin_write_EBIU_SDGCTL(mem_SDGCTL); + #else + bfin_write_EBIU_RSTCTL(bfin_read_EBIU_RSTCTL() & ~(SRREQ)); + do_sync(); +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/arch/blackfin/mach-common/dpmc_modes.S linux-2.6.29-rc3.owrt/arch/blackfin/mach-common/dpmc_modes.S +--- linux-2.6.29.owrt/arch/blackfin/mach-common/dpmc_modes.S 2009-05-10 22:04:40.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/arch/blackfin/mach-common/dpmc_modes.S 2009-05-10 23:48:28.000000000 +0200 +@@ -376,22 +376,10 @@ + #endif + + #ifdef PINT0_ASSIGN +- PM_SYS_PUSH(PINT0_MASK_SET) +- PM_SYS_PUSH(PINT1_MASK_SET) +- PM_SYS_PUSH(PINT2_MASK_SET) +- PM_SYS_PUSH(PINT3_MASK_SET) + PM_SYS_PUSH(PINT0_ASSIGN) + PM_SYS_PUSH(PINT1_ASSIGN) + PM_SYS_PUSH(PINT2_ASSIGN) + PM_SYS_PUSH(PINT3_ASSIGN) +- PM_SYS_PUSH(PINT0_INVERT_SET) +- PM_SYS_PUSH(PINT1_INVERT_SET) +- PM_SYS_PUSH(PINT2_INVERT_SET) +- PM_SYS_PUSH(PINT3_INVERT_SET) +- PM_SYS_PUSH(PINT0_EDGE_SET) +- PM_SYS_PUSH(PINT1_EDGE_SET) +- PM_SYS_PUSH(PINT2_EDGE_SET) +- PM_SYS_PUSH(PINT3_EDGE_SET) + #endif + + PM_SYS_PUSH(EBIU_AMBCTL0) +@@ -726,22 +714,10 @@ + PM_SYS_POP(EBIU_AMBCTL0) + + #ifdef PINT0_ASSIGN +- PM_SYS_POP(PINT3_EDGE_SET) +- PM_SYS_POP(PINT2_EDGE_SET) +- PM_SYS_POP(PINT1_EDGE_SET) +- PM_SYS_POP(PINT0_EDGE_SET) +- PM_SYS_POP(PINT3_INVERT_SET) +- PM_SYS_POP(PINT2_INVERT_SET) +- PM_SYS_POP(PINT1_INVERT_SET) +- PM_SYS_POP(PINT0_INVERT_SET) + PM_SYS_POP(PINT3_ASSIGN) + PM_SYS_POP(PINT2_ASSIGN) + PM_SYS_POP(PINT1_ASSIGN) + PM_SYS_POP(PINT0_ASSIGN) +- PM_SYS_POP(PINT3_MASK_SET) +- PM_SYS_POP(PINT2_MASK_SET) +- PM_SYS_POP(PINT1_MASK_SET) +- PM_SYS_POP(PINT0_MASK_SET) + #endif + + #ifdef SICA_IWR1 +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/arch/blackfin/mach-common/entry.S linux-2.6.29-rc3.owrt/arch/blackfin/mach-common/entry.S +--- linux-2.6.29.owrt/arch/blackfin/mach-common/entry.S 2009-05-10 22:04:40.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/arch/blackfin/mach-common/entry.S 2009-05-10 23:48:28.000000000 +0200 +@@ -151,6 +151,13 @@ + jump.s _bfin_return_from_exception; + ENDPROC(_ex_syscall) + ++ENTRY(_ex_soft_bp) ++ r7 = retx; ++ r7 += -2; ++ retx = r7; ++ jump.s _ex_trap_c; ++ENDPROC(_ex_soft_bp) ++ + ENTRY(_ex_single_step) + /* If we just returned from an interrupt, the single step event is + for the RTI instruction. */ +@@ -600,19 +607,6 @@ + p2 = [p2]; + + [p2+(TASK_THREAD+THREAD_KSP)] = sp; +-#ifdef CONFIG_IPIPE +- r0 = sp; +- SP += -12; +- call ___ipipe_syscall_root; +- SP += 12; +- cc = r0 == 1; +- if cc jump .Lsyscall_really_exit; +- cc = r0 == -1; +- if cc jump .Lresume_userspace; +- r3 = [sp + PT_R3]; +- r4 = [sp + PT_R4]; +- p0 = [sp + PT_ORIG_P0]; +-#endif /* CONFIG_IPIPE */ + + /* Check the System Call */ + r7 = __NR_syscall; +@@ -667,17 +661,6 @@ + r7 = r7 & r4; + + .Lsyscall_resched: +-#ifdef CONFIG_IPIPE +- cc = BITTST(r7, TIF_IRQ_SYNC); +- if !cc jump .Lsyscall_no_irqsync; +- [--sp] = reti; +- r0 = [sp++]; +- SP += -12; +- call ___ipipe_sync_root; +- SP += 12; +- jump .Lresume_userspace_1; +-.Lsyscall_no_irqsync: +-#endif + cc = BITTST(r7, TIF_NEED_RESCHED); + if !cc jump .Lsyscall_sigpending; + +@@ -709,10 +692,6 @@ + .Lsyscall_really_exit: + r5 = [sp + PT_RESERVED]; + rets = r5; +-#ifdef CONFIG_IPIPE +- [--sp] = reti; +- r5 = [sp++]; +-#endif /* CONFIG_IPIPE */ + rts; + ENDPROC(_system_call) + +@@ -799,15 +778,6 @@ + ENDPROC(_resume) + + ENTRY(_ret_from_exception) +-#ifdef CONFIG_IPIPE +- [--sp] = rets; +- SP += -12; +- call ___ipipe_check_root +- SP += 12 +- rets = [sp++]; +- cc = r0 == 0; +- if cc jump 4f; /* not on behalf of Linux, get out */ +-#endif /* CONFIG_IPIPE */ + p2.l = lo(IPEND); + p2.h = hi(IPEND); + +@@ -864,28 +834,6 @@ + rts; + ENDPROC(_ret_from_exception) + +-#ifdef CONFIG_IPIPE +- +-_sync_root_irqs: +- [--sp] = reti; /* Reenable interrupts */ +- r0 = [sp++]; +- jump.l ___ipipe_sync_root +- +-_resume_kernel_from_int: +- r0.l = _sync_root_irqs +- r0.h = _sync_root_irqs +- [--sp] = rets; +- [--sp] = ( r7:4, p5:3 ); +- SP += -12; +- call ___ipipe_call_irqtail +- SP += 12; +- ( r7:4, p5:3 ) = [sp++]; +- rets = [sp++]; +- rts +-#else +-#define _resume_kernel_from_int 2f +-#endif +- + ENTRY(_return_from_int) + /* If someone else already raised IRQ 15, do nothing. */ + csync; +@@ -907,7 +855,7 @@ + r1 = r0 - r1; + r2 = r0 & r1; + cc = r2 == 0; +- if !cc jump _resume_kernel_from_int; ++ if !cc jump 2f; + + /* Lower the interrupt level to 15. */ + p0.l = lo(EVT15); +@@ -1139,7 +1087,7 @@ + * EXCPT instruction can provide 4 bits of EXCAUSE, allowing 16 to be user defined + */ + .long _ex_syscall /* 0x00 - User Defined - Linux Syscall */ +- .long _ex_trap_c /* 0x01 - User Defined - Software breakpoint */ ++ .long _ex_soft_bp /* 0x01 - User Defined - Software breakpoint */ + #ifdef CONFIG_KGDB + .long _ex_trap_c /* 0x02 - User Defined - KGDB initial connection + and break signal trap */ +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/arch/blackfin/mach-common/head.S linux-2.6.29-rc3.owrt/arch/blackfin/mach-common/head.S +--- linux-2.6.29.owrt/arch/blackfin/mach-common/head.S 2009-05-10 22:04:40.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/arch/blackfin/mach-common/head.S 2009-05-10 23:48:28.000000000 +0200 +@@ -17,19 +17,6 @@ + + __INIT + +-ENTRY(__init_clear_bss) +- r2 = r2 - r1; +- cc = r2 == 0; +- if cc jump .L_bss_done; +- r2 >>= 2; +- p1 = r1; +- p2 = r2; +- lsetup (1f, 1f) lc0 = p2; +-1: [p1++] = r0; +-.L_bss_done: +- rts; +-ENDPROC(__init_clear_bss) +- + #define INITIAL_STACK (L1_SCRATCH_START + L1_SCRATCH_LENGTH - 12) + + ENTRY(__start) +@@ -157,35 +144,6 @@ + call _init_early_exception_vectors; + #endif + +- r0 = 0 (x); +- /* Zero out all of the fun bss regions */ +-#if L1_DATA_A_LENGTH > 0 +- r1.l = __sbss_l1; +- r1.h = __sbss_l1; +- r2.l = __ebss_l1; +- r2.h = __ebss_l1; +- call __init_clear_bss +-#endif +-#if L1_DATA_B_LENGTH > 0 +- r1.l = __sbss_b_l1; +- r1.h = __sbss_b_l1; +- r2.l = __ebss_b_l1; +- r2.h = __ebss_b_l1; +- call __init_clear_bss +-#endif +-#if L2_LENGTH > 0 +- r1.l = __sbss_l2; +- r1.h = __sbss_l2; +- r2.l = __ebss_l2; +- r2.h = __ebss_l2; +- call __init_clear_bss +-#endif +- r1.l = ___bss_start; +- r1.h = ___bss_start; +- r2.l = ___bss_stop; +- r2.h = ___bss_stop; +- call __init_clear_bss +- + /* Put The Code for PLL Programming and SDRAM Programming in L1 ISRAM */ + call _bfin_relocate_l1_mem; + #ifdef CONFIG_BFIN_KERNEL_CLOCK +@@ -227,6 +185,19 @@ + # define WDOG_CTL WDOGA_CTL + #endif + ++ENTRY(__init_clear_bss) ++ r2 = r2 - r1; ++ cc = r2 == 0; ++ if cc jump .L_bss_done; ++ r2 >>= 2; ++ p1 = r1; ++ p2 = r2; ++ lsetup (1f, 1f) lc0 = p2; ++1: [p1++] = r0; ++.L_bss_done: ++ rts; ++ENDPROC(__init_clear_bss) ++ + ENTRY(_real_start) + /* Enable nested interrupts */ + [--sp] = reti; +@@ -238,6 +209,35 @@ + w[p0] = r0; + ssync; + ++ r0 = 0 (x); ++ /* Zero out all of the fun bss regions */ ++#if L1_DATA_A_LENGTH > 0 ++ r1.l = __sbss_l1; ++ r1.h = __sbss_l1; ++ r2.l = __ebss_l1; ++ r2.h = __ebss_l1; ++ call __init_clear_bss ++#endif ++#if L1_DATA_B_LENGTH > 0 ++ r1.l = __sbss_b_l1; ++ r1.h = __sbss_b_l1; ++ r2.l = __ebss_b_l1; ++ r2.h = __ebss_b_l1; ++ call __init_clear_bss ++#endif ++#if L2_LENGTH > 0 ++ r1.l = __sbss_l2; ++ r1.h = __sbss_l2; ++ r2.l = __ebss_l2; ++ r2.h = __ebss_l2; ++ call __init_clear_bss ++#endif ++ r1.l = ___bss_start; ++ r1.h = ___bss_start; ++ r2.l = ___bss_stop; ++ r2.h = ___bss_stop; ++ call __init_clear_bss ++ + /* Pass the u-boot arguments to the global value command line */ + R0 = R7; + call _cmdline_init; +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/arch/blackfin/mach-common/interrupt.S linux-2.6.29-rc3.owrt/arch/blackfin/mach-common/interrupt.S +--- linux-2.6.29.owrt/arch/blackfin/mach-common/interrupt.S 2009-05-10 22:04:40.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/arch/blackfin/mach-common/interrupt.S 2009-05-10 23:48:28.000000000 +0200 +@@ -195,7 +195,7 @@ + /* Interrupt routine for evt2 (NMI). + * We don't actually use this, so just return. + * For inner circle type details, please see: +- * http://docs.blackfin.uclinux.org/doku.php?id=linux-kernel:nmi ++ * http://docs.blackfin.uclinux.org/doku.php?id=linux:nmi + */ + ENTRY(_evt_nmi) + .weak _evt_nmi +@@ -235,7 +235,6 @@ + + #ifdef CONFIG_IPIPE + ENTRY(___ipipe_call_irqtail) +- p0 = r0; + r0.l = 1f; + r0.h = 1f; + reti = r0; +@@ -243,6 +242,9 @@ + 1: + [--sp] = rets; + [--sp] = ( r7:4, p5:3 ); ++ p0.l = ___ipipe_irq_tail_hook; ++ p0.h = ___ipipe_irq_tail_hook; ++ p0 = [p0]; + sp += -12; + call (p0); + sp += 12; +@@ -257,7 +259,7 @@ + p0.h = hi(EVT14); + [p0] = r0; + csync; +- r0 = 0x401f (z); ++ r0 = 0x401f; + sti r0; + raise 14; + [--sp] = reti; /* IRQs on. */ +@@ -275,7 +277,11 @@ + p0.h = _bfin_irq_flags; + r0 = [p0]; + sti r0; ++#if 0 /* FIXME: this actually raises scheduling latencies */ ++ /* Reenable interrupts */ ++ [--sp] = reti; ++ r0 = [sp++]; ++#endif + rts; + ENDPROC(___ipipe_call_irqtail) +- + #endif /* CONFIG_IPIPE */ +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/arch/blackfin/mach-common/ints-priority.c linux-2.6.29-rc3.owrt/arch/blackfin/mach-common/ints-priority.c +--- linux-2.6.29.owrt/arch/blackfin/mach-common/ints-priority.c 2009-05-10 22:04:40.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/arch/blackfin/mach-common/ints-priority.c 2009-05-10 23:48:28.000000000 +0200 +@@ -161,15 +161,11 @@ + + static void bfin_internal_mask_irq(unsigned int irq) + { +- unsigned long flags; +- + #ifdef CONFIG_BF53x +- local_irq_save_hw(flags); + bfin_write_SIC_IMASK(bfin_read_SIC_IMASK() & + ~(1 << SIC_SYSIRQ(irq))); + #else + unsigned mask_bank, mask_bit; +- local_irq_save_hw(flags); + mask_bank = SIC_SYSIRQ(irq) / 32; + mask_bit = SIC_SYSIRQ(irq) % 32; + bfin_write_SIC_IMASK(mask_bank, bfin_read_SIC_IMASK(mask_bank) & +@@ -179,20 +175,15 @@ + ~(1 << mask_bit)); + #endif + #endif +- local_irq_restore_hw(flags); + } + + static void bfin_internal_unmask_irq(unsigned int irq) + { +- unsigned long flags; +- + #ifdef CONFIG_BF53x +- local_irq_save_hw(flags); + bfin_write_SIC_IMASK(bfin_read_SIC_IMASK() | + (1 << SIC_SYSIRQ(irq))); + #else + unsigned mask_bank, mask_bit; +- local_irq_save_hw(flags); + mask_bank = SIC_SYSIRQ(irq) / 32; + mask_bit = SIC_SYSIRQ(irq) % 32; + bfin_write_SIC_IMASK(mask_bank, bfin_read_SIC_IMASK(mask_bank) | +@@ -202,7 +193,6 @@ + (1 << mask_bit)); + #endif + #endif +- local_irq_restore_hw(flags); + } + + #ifdef CONFIG_PM +@@ -400,7 +390,7 @@ + static inline void bfin_set_irq_handler(unsigned irq, irq_flow_handler_t handle) + { + #ifdef CONFIG_IPIPE +- _set_irq_handler(irq, handle_level_irq); ++ _set_irq_handler(irq, handle_edge_irq); + #else + struct irq_desc *desc = irq_desc + irq; + /* May not call generic set_irq_handler() due to spinlock +@@ -1065,18 +1055,13 @@ + #endif + default: + #ifdef CONFIG_IPIPE +- /* +- * We want internal interrupt sources to be +- * masked, because ISRs may trigger interrupts +- * recursively (e.g. DMA), but interrupts are +- * _not_ masked at CPU level. So let's handle +- * most of them as level interrupts, except +- * the timer interrupt which is special. +- */ +- if (irq == IRQ_SYSTMR || irq == IRQ_CORETMR) +- set_irq_handler(irq, handle_simple_irq); +- else +- set_irq_handler(irq, handle_level_irq); ++ /* ++ * We want internal interrupt sources to be masked, because ++ * ISRs may trigger interrupts recursively (e.g. DMA), but ++ * interrupts are _not_ masked at CPU level. So let's handle ++ * them as level interrupts. ++ */ ++ set_irq_handler(irq, handle_level_irq); + #else /* !CONFIG_IPIPE */ + set_irq_handler(irq, handle_simple_irq); + #endif /* !CONFIG_IPIPE */ +@@ -1116,9 +1101,10 @@ + IMASK_IVG14 | IMASK_IVG13 | IMASK_IVG12 | IMASK_IVG11 | + IMASK_IVG10 | IMASK_IVG9 | IMASK_IVG8 | IMASK_IVG7 | IMASK_IVGHW; + +-#ifdef SIC_IWR0 ++#if defined(CONFIG_BF54x) || defined(CONFIG_BF52x) || defined(CONFIG_BF561) \ ++ || defined(BF538_FAMILY) || defined(CONFIG_BF51x) + bfin_write_SIC_IWR0(IWR_DISABLE_ALL); +-# ifdef SIC_IWR1 ++#if defined(CONFIG_BF52x) || defined(CONFIG_BF51x) + /* BF52x/BF51x system reset does not properly reset SIC_IWR1 which + * will screw up the bootrom as it relies on MDMA0/1 waking it + * up from IDLE instructions. See this report for more info: +@@ -1128,8 +1114,10 @@ + bfin_write_SIC_IWR1(IWR_ENABLE(10) | IWR_ENABLE(11)); + else + bfin_write_SIC_IWR1(IWR_DISABLE_ALL); +-# endif +-# ifdef SIC_IWR2 ++#else ++ bfin_write_SIC_IWR1(IWR_DISABLE_ALL); ++#endif ++# ifdef CONFIG_BF54x + bfin_write_SIC_IWR2(IWR_DISABLE_ALL); + # endif + #else +@@ -1138,8 +1126,9 @@ + + #ifdef CONFIG_IPIPE + for (irq = 0; irq < NR_IRQS; irq++) { +- struct irq_desc *desc = irq_to_desc(irq); ++ struct irq_desc *desc = irq_desc + irq; + desc->ic_prio = __ipipe_get_irq_priority(irq); ++ desc->thr_prio = __ipipe_get_irqthread_priority(irq); + } + #endif /* CONFIG_IPIPE */ + +@@ -1222,21 +1211,76 @@ + return IVG15; + } + ++int __ipipe_get_irqthread_priority(unsigned irq) ++{ ++ int ient, prio; ++ int demux_irq; ++ ++ /* The returned priority value is rescaled to [0..IVG13+1] ++ * with 0 being the lowest effective priority level. */ ++ ++ if (irq <= IRQ_CORETMR) ++ return IVG13 - irq + 1; ++ ++ /* GPIO IRQs are given the priority of the demux ++ * interrupt. */ ++ if (IS_GPIOIRQ(irq)) { ++#if defined(CONFIG_BF54x) ++ u32 bank = PINT_2_BANK(irq2pint_lut[irq - SYS_IRQS]); ++ demux_irq = (bank == 0 ? IRQ_PINT0 : ++ bank == 1 ? IRQ_PINT1 : ++ bank == 2 ? IRQ_PINT2 : ++ IRQ_PINT3); ++#elif defined(CONFIG_BF561) ++ demux_irq = (irq >= IRQ_PF32 ? IRQ_PROG2_INTA : ++ irq >= IRQ_PF16 ? IRQ_PROG1_INTA : ++ IRQ_PROG0_INTA); ++#elif defined(CONFIG_BF52x) ++ demux_irq = (irq >= IRQ_PH0 ? IRQ_PORTH_INTA : ++ irq >= IRQ_PG0 ? IRQ_PORTG_INTA : ++ IRQ_PORTF_INTA); ++#else ++ demux_irq = irq; ++#endif ++ return IVG13 - PRIO_GPIODEMUX(demux_irq) + 1; ++ } ++ ++ /* The GPIO demux interrupt is given a lower priority ++ * than the GPIO IRQs, so that its threaded handler ++ * unmasks the interrupt line after the decoded IRQs ++ * have been processed. */ ++ prio = PRIO_GPIODEMUX(irq); ++ /* demux irq? */ ++ if (prio != -1) ++ return IVG13 - prio; ++ ++ for (ient = 0; ient < NR_PERI_INTS; ient++) { ++ struct ivgx *ivg = ivg_table + ient; ++ if (ivg->irqno == irq) { ++ for (prio = 0; prio <= IVG13-IVG7; prio++) { ++ if (ivg7_13[prio].ifirst <= ivg && ++ ivg7_13[prio].istop > ivg) ++ return IVG7 - prio; ++ } ++ } ++ } ++ ++ return 0; ++} ++ + /* Hw interrupts are disabled on entry (check SAVE_CONTEXT). */ + #ifdef CONFIG_DO_IRQ_L1 + __attribute__((l1_text)) + #endif + asmlinkage int __ipipe_grab_irq(int vec, struct pt_regs *regs) + { +- struct ipipe_percpu_domain_data *p = ipipe_root_cpudom_ptr(); +- struct ipipe_domain *this_domain = ipipe_current_domain; + struct ivgx *ivg_stop = ivg7_13[vec-IVG7].istop; + struct ivgx *ivg = ivg7_13[vec-IVG7].ifirst; +- int irq, s; ++ int irq; + + if (likely(vec == EVT_IVTMR_P)) { + irq = IRQ_CORETMR; +- goto core_tick; ++ goto handle_irq; + } + + SSYNC(); +@@ -1278,39 +1322,24 @@ + irq = ivg->irqno; + + if (irq == IRQ_SYSTMR) { +-#ifdef CONFIG_GENERIC_CLOCKEVENTS +-core_tick: +-#else + bfin_write_TIMER_STATUS(1); /* Latch TIMIL0 */ +-#endif + /* This is basically what we need from the register frame. */ + __raw_get_cpu_var(__ipipe_tick_regs).ipend = regs->ipend; + __raw_get_cpu_var(__ipipe_tick_regs).pc = regs->pc; +- if (this_domain != ipipe_root_domain) +- __raw_get_cpu_var(__ipipe_tick_regs).ipend &= ~0x10; +- else ++ if (!ipipe_root_domain_p) + __raw_get_cpu_var(__ipipe_tick_regs).ipend |= 0x10; ++ else ++ __raw_get_cpu_var(__ipipe_tick_regs).ipend &= ~0x10; + } + +-#ifndef CONFIG_GENERIC_CLOCKEVENTS +-core_tick: +-#endif +- if (this_domain == ipipe_root_domain) { +- s = __test_and_set_bit(IPIPE_SYNCDEFER_FLAG, &p->status); +- barrier(); +- } ++handle_irq: + + ipipe_trace_irq_entry(irq); + __ipipe_handle_irq(irq, regs); +- ipipe_trace_irq_exit(irq); ++ ipipe_trace_irq_exit(irq); + +- if (this_domain == ipipe_root_domain) { +- set_thread_flag(TIF_IRQ_SYNC); +- if (!s) { +- __clear_bit(IPIPE_SYNCDEFER_FLAG, &p->status); +- return !test_bit(IPIPE_STALL_FLAG, &p->status); +- } +- } ++ if (ipipe_root_domain_p) ++ return !test_bit(IPIPE_STALL_FLAG, &ipipe_root_cpudom_var(status)); + + return 0; + } +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/arch/blackfin/mach-common/pm.c linux-2.6.29-rc3.owrt/arch/blackfin/mach-common/pm.c +--- linux-2.6.29.owrt/arch/blackfin/mach-common/pm.c 2009-05-10 22:04:40.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/arch/blackfin/mach-common/pm.c 2009-05-10 23:48:28.000000000 +0200 +@@ -82,9 +82,10 @@ + + bfin_pm_standby_restore(); + +-#ifdef SIC_IWR0 ++#if defined(CONFIG_BF54x) || defined(CONFIG_BF52x) || defined(CONFIG_BF561) || \ ++ defined(CONFIG_BF538) || defined(CONFIG_BF539) || defined(CONFIG_BF51x) + bfin_write_SIC_IWR0(IWR_DISABLE_ALL); +-# ifdef SIC_IWR1 ++#if defined(CONFIG_BF52x) || defined(CONFIG_BF51x) + /* BF52x system reset does not properly reset SIC_IWR1 which + * will screw up the bootrom as it relies on MDMA0/1 waking it + * up from IDLE instructions. See this report for more info: +@@ -94,8 +95,10 @@ + bfin_write_SIC_IWR1(IWR_ENABLE(10) | IWR_ENABLE(11)); + else + bfin_write_SIC_IWR1(IWR_DISABLE_ALL); +-# endif +-# ifdef SIC_IWR2 ++#else ++ bfin_write_SIC_IWR1(IWR_DISABLE_ALL); ++#endif ++# ifdef CONFIG_BF54x + bfin_write_SIC_IWR2(IWR_DISABLE_ALL); + # endif + #else +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/arch/blackfin/mach-common/smp.c linux-2.6.29-rc3.owrt/arch/blackfin/mach-common/smp.c +--- linux-2.6.29.owrt/arch/blackfin/mach-common/smp.c 2009-05-10 22:04:40.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/arch/blackfin/mach-common/smp.c 2009-05-10 23:48:28.000000000 +0200 +@@ -158,14 +158,10 @@ + kfree(msg); + break; + case BFIN_IPI_CALL_FUNC: +- spin_unlock(&msg_queue->lock); + ipi_call_function(cpu, msg); +- spin_lock(&msg_queue->lock); + break; + case BFIN_IPI_CPU_STOP: +- spin_unlock(&msg_queue->lock); + ipi_cpu_stop(cpu); +- spin_lock(&msg_queue->lock); + kfree(msg); + break; + default: +@@ -461,7 +457,7 @@ + smp_flush_data.start = start; + smp_flush_data.end = end; + +- if (smp_call_function(&ipi_flush_icache, &smp_flush_data, 0)) ++ if (smp_call_function(&ipi_flush_icache, &smp_flush_data, 1)) + printk(KERN_WARNING "SMP: failed to run I-cache flush request on other CPUs\n"); + } + EXPORT_SYMBOL_GPL(smp_icache_flush_range_others); +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/arch/blackfin/Makefile linux-2.6.29-rc3.owrt/arch/blackfin/Makefile +--- linux-2.6.29.owrt/arch/blackfin/Makefile 2009-05-10 22:04:41.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/arch/blackfin/Makefile 2009-05-10 23:48:28.000000000 +0200 +@@ -21,67 +21,57 @@ + KBUILD_DEFCONFIG := BF537-STAMP_defconfig + + # setup the machine name and the machine dependent settings +-machine-$(CONFIG_BF512) := bf518 +-machine-$(CONFIG_BF514) := bf518 +-machine-$(CONFIG_BF516) := bf518 +-machine-$(CONFIG_BF518) := bf518 +-machine-$(CONFIG_BF522) := bf527 +-machine-$(CONFIG_BF523) := bf527 +-machine-$(CONFIG_BF524) := bf527 +-machine-$(CONFIG_BF525) := bf527 +-machine-$(CONFIG_BF526) := bf527 +-machine-$(CONFIG_BF527) := bf527 +-machine-$(CONFIG_BF531) := bf533 +-machine-$(CONFIG_BF532) := bf533 +-machine-$(CONFIG_BF533) := bf533 +-machine-$(CONFIG_BF534) := bf537 +-machine-$(CONFIG_BF536) := bf537 +-machine-$(CONFIG_BF537) := bf537 +-machine-$(CONFIG_BF538) := bf538 +-machine-$(CONFIG_BF539) := bf538 +-machine-$(CONFIG_BF542) := bf548 +-machine-$(CONFIG_BF542M) := bf548 +-machine-$(CONFIG_BF544) := bf548 +-machine-$(CONFIG_BF544M) := bf548 +-machine-$(CONFIG_BF547) := bf548 +-machine-$(CONFIG_BF547M) := bf548 +-machine-$(CONFIG_BF548) := bf548 +-machine-$(CONFIG_BF548M) := bf548 +-machine-$(CONFIG_BF549) := bf548 +-machine-$(CONFIG_BF549M) := bf548 +-machine-$(CONFIG_BF561) := bf561 ++machine-$(CONFIG_BF512) := bf518 ++machine-$(CONFIG_BF514) := bf518 ++machine-$(CONFIG_BF516) := bf518 ++machine-$(CONFIG_BF518) := bf518 ++machine-$(CONFIG_BF522) := bf527 ++machine-$(CONFIG_BF523) := bf527 ++machine-$(CONFIG_BF524) := bf527 ++machine-$(CONFIG_BF525) := bf527 ++machine-$(CONFIG_BF526) := bf527 ++machine-$(CONFIG_BF527) := bf527 ++machine-$(CONFIG_BF531) := bf533 ++machine-$(CONFIG_BF532) := bf533 ++machine-$(CONFIG_BF533) := bf533 ++machine-$(CONFIG_BF534) := bf537 ++machine-$(CONFIG_BF536) := bf537 ++machine-$(CONFIG_BF537) := bf537 ++machine-$(CONFIG_BF538) := bf538 ++machine-$(CONFIG_BF539) := bf538 ++machine-$(CONFIG_BF542) := bf548 ++machine-$(CONFIG_BF544) := bf548 ++machine-$(CONFIG_BF547) := bf548 ++machine-$(CONFIG_BF548) := bf548 ++machine-$(CONFIG_BF549) := bf548 ++machine-$(CONFIG_BF561) := bf561 + MACHINE := $(machine-y) + export MACHINE + +-cpu-$(CONFIG_BF512) := bf512 +-cpu-$(CONFIG_BF514) := bf514 +-cpu-$(CONFIG_BF516) := bf516 +-cpu-$(CONFIG_BF518) := bf518 +-cpu-$(CONFIG_BF522) := bf522 +-cpu-$(CONFIG_BF523) := bf523 +-cpu-$(CONFIG_BF524) := bf524 +-cpu-$(CONFIG_BF525) := bf525 +-cpu-$(CONFIG_BF526) := bf526 +-cpu-$(CONFIG_BF527) := bf527 +-cpu-$(CONFIG_BF531) := bf531 +-cpu-$(CONFIG_BF532) := bf532 +-cpu-$(CONFIG_BF533) := bf533 +-cpu-$(CONFIG_BF534) := bf534 +-cpu-$(CONFIG_BF536) := bf536 +-cpu-$(CONFIG_BF537) := bf537 +-cpu-$(CONFIG_BF538) := bf538 +-cpu-$(CONFIG_BF539) := bf539 +-cpu-$(CONFIG_BF542) := bf542 +-cpu-$(CONFIG_BF542M) := bf542m +-cpu-$(CONFIG_BF544) := bf544 +-cpu-$(CONFIG_BF544M) := bf544m +-cpu-$(CONFIG_BF547) := bf547 +-cpu-$(CONFIG_BF547M) := bf547m +-cpu-$(CONFIG_BF548) := bf548 +-cpu-$(CONFIG_BF548M) := bf548m +-cpu-$(CONFIG_BF549) := bf549 +-cpu-$(CONFIG_BF549M) := bf549m +-cpu-$(CONFIG_BF561) := bf561 ++cpu-$(CONFIG_BF512) := bf512 ++cpu-$(CONFIG_BF514) := bf514 ++cpu-$(CONFIG_BF516) := bf516 ++cpu-$(CONFIG_BF518) := bf518 ++cpu-$(CONFIG_BF522) := bf522 ++cpu-$(CONFIG_BF523) := bf523 ++cpu-$(CONFIG_BF524) := bf524 ++cpu-$(CONFIG_BF525) := bf525 ++cpu-$(CONFIG_BF526) := bf526 ++cpu-$(CONFIG_BF527) := bf527 ++cpu-$(CONFIG_BF531) := bf531 ++cpu-$(CONFIG_BF532) := bf532 ++cpu-$(CONFIG_BF533) := bf533 ++cpu-$(CONFIG_BF534) := bf534 ++cpu-$(CONFIG_BF536) := bf536 ++cpu-$(CONFIG_BF537) := bf537 ++cpu-$(CONFIG_BF538) := bf538 ++cpu-$(CONFIG_BF539) := bf539 ++cpu-$(CONFIG_BF542) := bf542 ++cpu-$(CONFIG_BF544) := bf544 ++cpu-$(CONFIG_BF547) := bf547 ++cpu-$(CONFIG_BF548) := bf548 ++cpu-$(CONFIG_BF549) := bf549 ++cpu-$(CONFIG_BF561) := bf561 + + rev-$(CONFIG_BF_REV_0_0) := 0.0 + rev-$(CONFIG_BF_REV_0_1) := 0.1 +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/arch/blackfin/mm/init.c linux-2.6.29-rc3.owrt/arch/blackfin/mm/init.c +--- linux-2.6.29.owrt/arch/blackfin/mm/init.c 2009-05-10 22:04:40.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/arch/blackfin/mm/init.c 2009-05-10 23:48:28.000000000 +0200 +@@ -104,7 +104,7 @@ + } + } + +-asmlinkage void __init init_pda(void) ++asmlinkage void init_pda(void) + { + unsigned int cpu = raw_smp_processor_id(); + +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/arch/frv/mm/dma-alloc.c linux-2.6.29-rc3.owrt/arch/frv/mm/dma-alloc.c +--- linux-2.6.29.owrt/arch/frv/mm/dma-alloc.c 2009-05-10 22:04:39.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/arch/frv/mm/dma-alloc.c 2009-05-10 23:48:28.000000000 +0200 +@@ -36,10 +36,10 @@ + #include <linux/vmalloc.h> + #include <linux/init.h> + #include <linux/pci.h> +-#include <linux/hardirq.h> + + #include <asm/pgalloc.h> + #include <asm/io.h> ++#include <asm/hardirq.h> + #include <asm/mmu_context.h> + #include <asm/pgtable.h> + #include <asm/mmu.h> +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/arch/ia64/configs/xen_domu_defconfig linux-2.6.29-rc3.owrt/arch/ia64/configs/xen_domu_defconfig +--- linux-2.6.29.owrt/arch/ia64/configs/xen_domu_defconfig 2009-05-10 22:04:40.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/arch/ia64/configs/xen_domu_defconfig 1970-01-01 01:00:00.000000000 +0100 +@@ -1,1601 +0,0 @@ +-# +-# Automatically generated make config: don't edit +-# Linux kernel version: 2.6.29-rc1 +-# Fri Jan 16 11:49:59 2009 +-# +-CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config" +- +-# +-# General setup +-# +-CONFIG_EXPERIMENTAL=y +-CONFIG_LOCK_KERNEL=y +-CONFIG_INIT_ENV_ARG_LIMIT=32 +-CONFIG_LOCALVERSION="" +-CONFIG_LOCALVERSION_AUTO=y +-CONFIG_SWAP=y +-CONFIG_SYSVIPC=y +-CONFIG_SYSVIPC_SYSCTL=y +-CONFIG_POSIX_MQUEUE=y +-# CONFIG_BSD_PROCESS_ACCT is not set +-# CONFIG_TASKSTATS is not set +-# CONFIG_AUDIT is not set +-CONFIG_IKCONFIG=y +-CONFIG_IKCONFIG_PROC=y +-CONFIG_LOG_BUF_SHIFT=20 +-CONFIG_HAVE_UNSTABLE_SCHED_CLOCK=y +-# CONFIG_GROUP_SCHED is not set +- +-# +-# Control Group support +-# +-# CONFIG_CGROUPS is not set +-CONFIG_SYSFS_DEPRECATED=y +-CONFIG_SYSFS_DEPRECATED_V2=y +-# CONFIG_RELAY is not set +-CONFIG_NAMESPACES=y +-# CONFIG_UTS_NS is not set +-# CONFIG_IPC_NS is not set +-# CONFIG_USER_NS is not set +-# CONFIG_PID_NS is not set +-CONFIG_BLK_DEV_INITRD=y +-CONFIG_INITRAMFS_SOURCE="" +-CONFIG_CC_OPTIMIZE_FOR_SIZE=y +-CONFIG_SYSCTL=y +-# CONFIG_EMBEDDED is not set +-CONFIG_SYSCTL_SYSCALL=y +-CONFIG_KALLSYMS=y +-CONFIG_KALLSYMS_ALL=y +-CONFIG_KALLSYMS_STRIP_GENERATED=y +-# CONFIG_KALLSYMS_EXTRA_PASS is not set +-CONFIG_HOTPLUG=y +-CONFIG_PRINTK=y +-CONFIG_BUG=y +-CONFIG_ELF_CORE=y +-CONFIG_COMPAT_BRK=y +-CONFIG_BASE_FULL=y +-CONFIG_FUTEX=y +-CONFIG_ANON_INODES=y +-CONFIG_EPOLL=y +-CONFIG_SIGNALFD=y +-CONFIG_TIMERFD=y +-CONFIG_EVENTFD=y +-CONFIG_SHMEM=y +-CONFIG_AIO=y +-CONFIG_VM_EVENT_COUNTERS=y +-CONFIG_PCI_QUIRKS=y +-CONFIG_SLUB_DEBUG=y +-# CONFIG_SLAB is not set +-CONFIG_SLUB=y +-# CONFIG_SLOB is not set +-# CONFIG_PROFILING is not set +-CONFIG_HAVE_OPROFILE=y +-# CONFIG_KPROBES is not set +-CONFIG_HAVE_KPROBES=y +-CONFIG_HAVE_KRETPROBES=y +-CONFIG_HAVE_ARCH_TRACEHOOK=y +-CONFIG_HAVE_DMA_ATTRS=y +-CONFIG_USE_GENERIC_SMP_HELPERS=y +-# CONFIG_HAVE_GENERIC_DMA_COHERENT is not set +-CONFIG_SLABINFO=y +-CONFIG_RT_MUTEXES=y +-CONFIG_BASE_SMALL=0 +-CONFIG_MODULES=y +-# CONFIG_MODULE_FORCE_LOAD is not set +-CONFIG_MODULE_UNLOAD=y +-# CONFIG_MODULE_FORCE_UNLOAD is not set +-CONFIG_MODVERSIONS=y +-CONFIG_MODULE_SRCVERSION_ALL=y +-CONFIG_STOP_MACHINE=y +-CONFIG_BLOCK=y +-# CONFIG_BLK_DEV_IO_TRACE is not set +-# CONFIG_BLK_DEV_BSG is not set +-# CONFIG_BLK_DEV_INTEGRITY is not set +- +-# +-# IO Schedulers +-# +-CONFIG_IOSCHED_NOOP=y +-CONFIG_IOSCHED_AS=y +-CONFIG_IOSCHED_DEADLINE=y +-CONFIG_IOSCHED_CFQ=y +-CONFIG_DEFAULT_AS=y +-# CONFIG_DEFAULT_DEADLINE is not set +-# CONFIG_DEFAULT_CFQ is not set +-# CONFIG_DEFAULT_NOOP is not set +-CONFIG_DEFAULT_IOSCHED="anticipatory" +-CONFIG_CLASSIC_RCU=y +-# CONFIG_TREE_RCU is not set +-# CONFIG_PREEMPT_RCU is not set +-# CONFIG_TREE_RCU_TRACE is not set +-# CONFIG_PREEMPT_RCU_TRACE is not set +-CONFIG_FREEZER=y +- +-# +-# Processor type and features +-# +-CONFIG_IA64=y +-CONFIG_64BIT=y +-CONFIG_ZONE_DMA=y +-CONFIG_QUICKLIST=y +-CONFIG_MMU=y +-CONFIG_SWIOTLB=y +-CONFIG_IOMMU_HELPER=y +-CONFIG_RWSEM_XCHGADD_ALGORITHM=y +-CONFIG_HUGETLB_PAGE_SIZE_VARIABLE=y +-CONFIG_GENERIC_FIND_NEXT_BIT=y +-CONFIG_GENERIC_CALIBRATE_DELAY=y +-CONFIG_GENERIC_TIME=y +-CONFIG_GENERIC_TIME_VSYSCALL=y +-CONFIG_HAVE_SETUP_PER_CPU_AREA=y +-CONFIG_DMI=y +-CONFIG_EFI=y +-CONFIG_GENERIC_IOMAP=y +-CONFIG_SCHED_OMIT_FRAME_POINTER=y +-CONFIG_AUDIT_ARCH=y +-CONFIG_PARAVIRT_GUEST=y +-CONFIG_PARAVIRT=y +-CONFIG_XEN=y +-CONFIG_XEN_XENCOMM=y +-CONFIG_NO_IDLE_HZ=y +-# CONFIG_IA64_GENERIC is not set +-# CONFIG_IA64_DIG is not set +-# CONFIG_IA64_DIG_VTD is not set +-# CONFIG_IA64_HP_ZX1 is not set +-# CONFIG_IA64_HP_ZX1_SWIOTLB is not set +-# CONFIG_IA64_SGI_SN2 is not set +-# CONFIG_IA64_SGI_UV is not set +-# CONFIG_IA64_HP_SIM is not set +-CONFIG_IA64_XEN_GUEST=y +-# CONFIG_ITANIUM is not set +-CONFIG_MCKINLEY=y +-# CONFIG_IA64_PAGE_SIZE_4KB is not set +-# CONFIG_IA64_PAGE_SIZE_8KB is not set +-CONFIG_IA64_PAGE_SIZE_16KB=y +-# CONFIG_IA64_PAGE_SIZE_64KB is not set +-CONFIG_PGTABLE_3=y +-# CONFIG_PGTABLE_4 is not set +-CONFIG_HZ=250 +-# CONFIG_HZ_100 is not set +-CONFIG_HZ_250=y +-# CONFIG_HZ_300 is not set +-# CONFIG_HZ_1000 is not set +-# CONFIG_SCHED_HRTICK is not set +-CONFIG_IA64_L1_CACHE_SHIFT=7 +-CONFIG_IA64_CYCLONE=y +-CONFIG_IOSAPIC=y +-CONFIG_FORCE_MAX_ZONEORDER=17 +-# CONFIG_VIRT_CPU_ACCOUNTING is not set +-CONFIG_SMP=y +-CONFIG_NR_CPUS=16 +-CONFIG_HOTPLUG_CPU=y +-CONFIG_ARCH_ENABLE_MEMORY_HOTPLUG=y +-CONFIG_ARCH_ENABLE_MEMORY_HOTREMOVE=y +-# CONFIG_SCHED_SMT is not set +-CONFIG_PERMIT_BSP_REMOVE=y +-CONFIG_FORCE_CPEI_RETARGET=y +-CONFIG_PREEMPT_NONE=y +-# CONFIG_PREEMPT_VOLUNTARY is not set +-# CONFIG_PREEMPT is not set +-CONFIG_SELECT_MEMORY_MODEL=y +-CONFIG_FLATMEM_MANUAL=y +-# CONFIG_DISCONTIGMEM_MANUAL is not set +-# CONFIG_SPARSEMEM_MANUAL is not set +-CONFIG_FLATMEM=y +-CONFIG_FLAT_NODE_MEM_MAP=y +-CONFIG_SPARSEMEM_VMEMMAP_ENABLE=y +-CONFIG_PAGEFLAGS_EXTENDED=y +-CONFIG_SPLIT_PTLOCK_CPUS=4 +-CONFIG_MIGRATION=y +-CONFIG_PHYS_ADDR_T_64BIT=y +-CONFIG_ZONE_DMA_FLAG=1 +-CONFIG_BOUNCE=y +-CONFIG_NR_QUICK=1 +-CONFIG_VIRT_TO_BUS=y +-CONFIG_UNEVICTABLE_LRU=y +-CONFIG_ARCH_SELECT_MEMORY_MODEL=y +-CONFIG_ARCH_DISCONTIGMEM_ENABLE=y +-CONFIG_ARCH_FLATMEM_ENABLE=y +-CONFIG_ARCH_SPARSEMEM_ENABLE=y +-CONFIG_ARCH_POPULATES_NODE_MAP=y +-CONFIG_VIRTUAL_MEM_MAP=y +-CONFIG_HOLES_IN_ZONE=y +-# CONFIG_IA32_SUPPORT is not set +-# CONFIG_COMPAT_FOR_U64_ALIGNMENT is not set +-CONFIG_IA64_MCA_RECOVERY=y +-CONFIG_PERFMON=y +-CONFIG_IA64_PALINFO=y +-# CONFIG_IA64_MC_ERR_INJECT is not set +-# CONFIG_IA64_ESI is not set +-# CONFIG_IA64_HP_AML_NFW is not set +-CONFIG_KEXEC=y +-# CONFIG_CRASH_DUMP is not set +- +-# +-# Firmware Drivers +-# +-# CONFIG_FIRMWARE_MEMMAP is not set +-CONFIG_EFI_VARS=y +-CONFIG_EFI_PCDP=y +-CONFIG_DMIID=y +-CONFIG_BINFMT_ELF=y +-# CONFIG_CORE_DUMP_DEFAULT_ELF_HEADERS is not set +-# CONFIG_HAVE_AOUT is not set +-CONFIG_BINFMT_MISC=m +- +-# +-# Power management and ACPI options +-# +-CONFIG_PM=y +-# CONFIG_PM_DEBUG is not set +-CONFIG_PM_SLEEP=y +-CONFIG_SUSPEND=y +-CONFIG_SUSPEND_FREEZER=y +-CONFIG_ACPI=y +-CONFIG_ACPI_SLEEP=y +-CONFIG_ACPI_PROCFS=y +-CONFIG_ACPI_PROCFS_POWER=y +-CONFIG_ACPI_SYSFS_POWER=y +-CONFIG_ACPI_PROC_EVENT=y +-CONFIG_ACPI_BUTTON=m +-CONFIG_ACPI_FAN=m +-# CONFIG_ACPI_DOCK is not set +-CONFIG_ACPI_PROCESSOR=m +-CONFIG_ACPI_HOTPLUG_CPU=y +-CONFIG_ACPI_THERMAL=m +-# CONFIG_ACPI_CUSTOM_DSDT is not set +-CONFIG_ACPI_BLACKLIST_YEAR=0 +-# CONFIG_ACPI_DEBUG is not set +-# CONFIG_ACPI_PCI_SLOT is not set +-CONFIG_ACPI_SYSTEM=y +-CONFIG_ACPI_CONTAINER=m +- +-# +-# CPU Frequency scaling +-# +-# CONFIG_CPU_FREQ is not set +- +-# +-# Bus options (PCI, PCMCIA) +-# +-CONFIG_PCI=y +-CONFIG_PCI_DOMAINS=y +-CONFIG_PCI_SYSCALL=y +-# CONFIG_PCIEPORTBUS is not set +-CONFIG_ARCH_SUPPORTS_MSI=y +-# CONFIG_PCI_MSI is not set +-CONFIG_PCI_LEGACY=y +-# CONFIG_PCI_DEBUG is not set +-# CONFIG_PCI_STUB is not set +-CONFIG_HOTPLUG_PCI=m +-# CONFIG_HOTPLUG_PCI_FAKE is not set +-CONFIG_HOTPLUG_PCI_ACPI=m +-# CONFIG_HOTPLUG_PCI_ACPI_IBM is not set +-# CONFIG_HOTPLUG_PCI_CPCI is not set +-# CONFIG_HOTPLUG_PCI_SHPC is not set +-# CONFIG_PCCARD is not set +-CONFIG_NET=y +- +-# +-# Networking options +-# +-# CONFIG_NET_NS is not set +-CONFIG_COMPAT_NET_DEV_OPS=y +-CONFIG_PACKET=y +-# CONFIG_PACKET_MMAP is not set +-CONFIG_UNIX=y +-CONFIG_XFRM=y +-# CONFIG_XFRM_USER is not set +-# CONFIG_XFRM_SUB_POLICY is not set +-# CONFIG_XFRM_MIGRATE is not set +-# CONFIG_XFRM_STATISTICS is not set +-# CONFIG_NET_KEY is not set +-CONFIG_INET=y +-CONFIG_IP_MULTICAST=y +-# CONFIG_IP_ADVANCED_ROUTER is not set +-CONFIG_IP_FIB_HASH=y +-# CONFIG_IP_PNP is not set +-# CONFIG_NET_IPIP is not set +-# CONFIG_NET_IPGRE is not set +-# CONFIG_IP_MROUTE is not set +-CONFIG_ARPD=y +-CONFIG_SYN_COOKIES=y +-# CONFIG_INET_AH is not set +-# CONFIG_INET_ESP is not set +-# CONFIG_INET_IPCOMP is not set +-# CONFIG_INET_XFRM_TUNNEL is not set +-# CONFIG_INET_TUNNEL is not set +-CONFIG_INET_XFRM_MODE_TRANSPORT=y +-CONFIG_INET_XFRM_MODE_TUNNEL=y +-CONFIG_INET_XFRM_MODE_BEET=y +-# CONFIG_INET_LRO is not set +-CONFIG_INET_DIAG=y +-CONFIG_INET_TCP_DIAG=y +-# CONFIG_TCP_CONG_ADVANCED is not set +-CONFIG_TCP_CONG_CUBIC=y +-CONFIG_DEFAULT_TCP_CONG="cubic" +-# CONFIG_TCP_MD5SIG is not set +-# CONFIG_IPV6 is not set +-# CONFIG_NETWORK_SECMARK is not set +-# CONFIG_NETFILTER is not set +-# CONFIG_IP_DCCP is not set +-# CONFIG_IP_SCTP is not set +-# CONFIG_TIPC is not set +-# CONFIG_ATM is not set +-# CONFIG_BRIDGE is not set +-# CONFIG_NET_DSA is not set +-# CONFIG_VLAN_8021Q is not set +-# CONFIG_DECNET is not set +-# CONFIG_LLC2 is not set +-# CONFIG_IPX is not set +-# CONFIG_ATALK is not set +-# CONFIG_X25 is not set +-# CONFIG_LAPB is not set +-# CONFIG_ECONET is not set +-# CONFIG_WAN_ROUTER is not set +-# CONFIG_NET_SCHED is not set +-# CONFIG_DCB is not set +- +-# +-# Network testing +-# +-# CONFIG_NET_PKTGEN is not set +-# CONFIG_HAMRADIO is not set +-# CONFIG_CAN is not set +-# CONFIG_IRDA is not set +-# CONFIG_BT is not set +-# CONFIG_AF_RXRPC is not set +-# CONFIG_PHONET is not set +-# CONFIG_WIRELESS is not set +-# CONFIG_WIMAX is not set +-# CONFIG_RFKILL is not set +-# CONFIG_NET_9P is not set +- +-# +-# Device Drivers +-# +- +-# +-# Generic Driver Options +-# +-CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug" +-CONFIG_STANDALONE=y +-CONFIG_PREVENT_FIRMWARE_BUILD=y +-CONFIG_FW_LOADER=y +-CONFIG_FIRMWARE_IN_KERNEL=y +-CONFIG_EXTRA_FIRMWARE="" +-# CONFIG_DEBUG_DRIVER is not set +-# CONFIG_DEBUG_DEVRES is not set +-# CONFIG_SYS_HYPERVISOR is not set +-# CONFIG_CONNECTOR is not set +-# CONFIG_MTD is not set +-# CONFIG_PARPORT is not set +-CONFIG_PNP=y +-CONFIG_PNP_DEBUG_MESSAGES=y +- +-# +-# Protocols +-# +-CONFIG_PNPACPI=y +-CONFIG_BLK_DEV=y +-# CONFIG_BLK_CPQ_DA is not set +-# CONFIG_BLK_CPQ_CISS_DA is not set +-# CONFIG_BLK_DEV_DAC960 is not set +-# CONFIG_BLK_DEV_UMEM is not set +-# CONFIG_BLK_DEV_COW_COMMON is not set +-CONFIG_BLK_DEV_LOOP=m +-CONFIG_BLK_DEV_CRYPTOLOOP=m +-CONFIG_BLK_DEV_NBD=m +-# CONFIG_BLK_DEV_SX8 is not set +-# CONFIG_BLK_DEV_UB is not set +-CONFIG_BLK_DEV_RAM=y +-CONFIG_BLK_DEV_RAM_COUNT=16 +-CONFIG_BLK_DEV_RAM_SIZE=4096 +-# CONFIG_BLK_DEV_XIP is not set +-# CONFIG_CDROM_PKTCDVD is not set +-# CONFIG_ATA_OVER_ETH is not set +-CONFIG_XEN_BLKDEV_FRONTEND=y +-# CONFIG_BLK_DEV_HD is not set +-CONFIG_MISC_DEVICES=y +-# CONFIG_PHANTOM is not set +-# CONFIG_EEPROM_93CX6 is not set +-# CONFIG_SGI_IOC4 is not set +-# CONFIG_TIFM_CORE is not set +-# CONFIG_ICS932S401 is not set +-# CONFIG_ENCLOSURE_SERVICES is not set +-# CONFIG_HP_ILO is not set +-# CONFIG_C2PORT is not set +-CONFIG_HAVE_IDE=y +-CONFIG_IDE=y +- +-# +-# Please see Documentation/ide/ide.txt for help/info on IDE drives +-# +-CONFIG_IDE_TIMINGS=y +-CONFIG_IDE_ATAPI=y +-# CONFIG_BLK_DEV_IDE_SATA is not set +-CONFIG_IDE_GD=y +-CONFIG_IDE_GD_ATA=y +-# CONFIG_IDE_GD_ATAPI is not set +-CONFIG_BLK_DEV_IDECD=y +-CONFIG_BLK_DEV_IDECD_VERBOSE_ERRORS=y +-# CONFIG_BLK_DEV_IDETAPE is not set +-# CONFIG_BLK_DEV_IDEACPI is not set +-# CONFIG_IDE_TASK_IOCTL is not set +-CONFIG_IDE_PROC_FS=y +- +-# +-# IDE chipset support/bugfixes +-# +-# CONFIG_IDE_GENERIC is not set +-# CONFIG_BLK_DEV_PLATFORM is not set +-# CONFIG_BLK_DEV_IDEPNP is not set +-CONFIG_BLK_DEV_IDEDMA_SFF=y +- +-# +-# PCI IDE chipsets support +-# +-CONFIG_BLK_DEV_IDEPCI=y +-CONFIG_IDEPCI_PCIBUS_ORDER=y +-# CONFIG_BLK_DEV_OFFBOARD is not set +-CONFIG_BLK_DEV_GENERIC=y +-# CONFIG_BLK_DEV_OPTI621 is not set +-CONFIG_BLK_DEV_IDEDMA_PCI=y +-# CONFIG_BLK_DEV_AEC62XX is not set +-# CONFIG_BLK_DEV_ALI15X3 is not set +-# CONFIG_BLK_DEV_AMD74XX is not set +-CONFIG_BLK_DEV_CMD64X=y +-# CONFIG_BLK_DEV_TRIFLEX is not set +-# CONFIG_BLK_DEV_CS5520 is not set +-# CONFIG_BLK_DEV_CS5530 is not set +-# CONFIG_BLK_DEV_HPT366 is not set +-# CONFIG_BLK_DEV_JMICRON is not set +-# CONFIG_BLK_DEV_SC1200 is not set +-CONFIG_BLK_DEV_PIIX=y +-# CONFIG_BLK_DEV_IT8172 is not set +-# CONFIG_BLK_DEV_IT8213 is not set +-# CONFIG_BLK_DEV_IT821X is not set +-# CONFIG_BLK_DEV_NS87415 is not set +-# CONFIG_BLK_DEV_PDC202XX_OLD is not set +-# CONFIG_BLK_DEV_PDC202XX_NEW is not set +-# CONFIG_BLK_DEV_SVWKS is not set +-# CONFIG_BLK_DEV_SIIMAGE is not set +-# CONFIG_BLK_DEV_SLC90E66 is not set +-# CONFIG_BLK_DEV_TRM290 is not set +-# CONFIG_BLK_DEV_VIA82CXXX is not set +-# CONFIG_BLK_DEV_TC86C001 is not set +-CONFIG_BLK_DEV_IDEDMA=y +- +-# +-# SCSI device support +-# +-# CONFIG_RAID_ATTRS is not set +-CONFIG_SCSI=y +-CONFIG_SCSI_DMA=y +-# CONFIG_SCSI_TGT is not set +-CONFIG_SCSI_NETLINK=y +-CONFIG_SCSI_PROC_FS=y +- +-# +-# SCSI support type (disk, tape, CD-ROM) +-# +-CONFIG_BLK_DEV_SD=y +-CONFIG_CHR_DEV_ST=m +-# CONFIG_CHR_DEV_OSST is not set +-CONFIG_BLK_DEV_SR=m +-# CONFIG_BLK_DEV_SR_VENDOR is not set +-CONFIG_CHR_DEV_SG=m +-# CONFIG_CHR_DEV_SCH is not set +- +-# +-# Some SCSI devices (e.g. CD jukebox) support multiple LUNs +-# +-# CONFIG_SCSI_MULTI_LUN is not set +-# CONFIG_SCSI_CONSTANTS is not set +-# CONFIG_SCSI_LOGGING is not set +-# CONFIG_SCSI_SCAN_ASYNC is not set +-CONFIG_SCSI_WAIT_SCAN=m +- +-# +-# SCSI Transports +-# +-CONFIG_SCSI_SPI_ATTRS=y +-CONFIG_SCSI_FC_ATTRS=y +-# CONFIG_SCSI_ISCSI_ATTRS is not set +-# CONFIG_SCSI_SAS_LIBSAS is not set +-# CONFIG_SCSI_SRP_ATTRS is not set +-CONFIG_SCSI_LOWLEVEL=y +-# CONFIG_ISCSI_TCP is not set +-# CONFIG_SCSI_CXGB3_ISCSI is not set +-# CONFIG_BLK_DEV_3W_XXXX_RAID is not set +-# CONFIG_SCSI_3W_9XXX is not set +-# CONFIG_SCSI_ACARD is not set +-# CONFIG_SCSI_AACRAID is not set +-# CONFIG_SCSI_AIC7XXX is not set +-# CONFIG_SCSI_AIC7XXX_OLD is not set +-# CONFIG_SCSI_AIC79XX is not set +-# CONFIG_SCSI_AIC94XX is not set +-# CONFIG_SCSI_DPT_I2O is not set +-# CONFIG_SCSI_ADVANSYS is not set +-# CONFIG_SCSI_ARCMSR is not set +-# CONFIG_MEGARAID_NEWGEN is not set +-# CONFIG_MEGARAID_LEGACY is not set +-# CONFIG_MEGARAID_SAS is not set +-# CONFIG_SCSI_HPTIOP is not set +-# CONFIG_LIBFC is not set +-# CONFIG_FCOE is not set +-# CONFIG_SCSI_DMX3191D is not set +-# CONFIG_SCSI_FUTURE_DOMAIN is not set +-# CONFIG_SCSI_IPS is not set +-# CONFIG_SCSI_INITIO is not set +-# CONFIG_SCSI_INIA100 is not set +-# CONFIG_SCSI_MVSAS is not set +-# CONFIG_SCSI_STEX is not set +-CONFIG_SCSI_SYM53C8XX_2=y +-CONFIG_SCSI_SYM53C8XX_DMA_ADDRESSING_MODE=1 +-CONFIG_SCSI_SYM53C8XX_DEFAULT_TAGS=16 +-CONFIG_SCSI_SYM53C8XX_MAX_TAGS=64 +-CONFIG_SCSI_SYM53C8XX_MMIO=y +-CONFIG_SCSI_QLOGIC_1280=y +-# CONFIG_SCSI_QLA_FC is not set +-# CONFIG_SCSI_QLA_ISCSI is not set +-# CONFIG_SCSI_LPFC is not set +-# CONFIG_SCSI_DC395x is not set +-# CONFIG_SCSI_DC390T is not set +-# CONFIG_SCSI_DEBUG is not set +-# CONFIG_SCSI_SRP is not set +-# CONFIG_SCSI_DH is not set +-# CONFIG_ATA is not set +-CONFIG_MD=y +-CONFIG_BLK_DEV_MD=m +-CONFIG_MD_LINEAR=m +-CONFIG_MD_RAID0=m +-CONFIG_MD_RAID1=m +-# CONFIG_MD_RAID10 is not set +-# CONFIG_MD_RAID456 is not set +-CONFIG_MD_MULTIPATH=m +-# CONFIG_MD_FAULTY is not set +-CONFIG_BLK_DEV_DM=m +-# CONFIG_DM_DEBUG is not set +-CONFIG_DM_CRYPT=m +-CONFIG_DM_SNAPSHOT=m +-CONFIG_DM_MIRROR=m +-CONFIG_DM_ZERO=m +-# CONFIG_DM_MULTIPATH is not set +-# CONFIG_DM_DELAY is not set +-# CONFIG_DM_UEVENT is not set +-CONFIG_FUSION=y +-CONFIG_FUSION_SPI=y +-CONFIG_FUSION_FC=y +-# CONFIG_FUSION_SAS is not set +-CONFIG_FUSION_MAX_SGE=128 +-CONFIG_FUSION_CTL=y +-# CONFIG_FUSION_LOGGING is not set +- +-# +-# IEEE 1394 (FireWire) support +-# +- +-# +-# Enable only one of the two stacks, unless you know what you are doing +-# +-# CONFIG_FIREWIRE is not set +-# CONFIG_IEEE1394 is not set +-# CONFIG_I2O is not set +-CONFIG_NETDEVICES=y +-CONFIG_DUMMY=m +-# CONFIG_BONDING is not set +-# CONFIG_MACVLAN is not set +-# CONFIG_EQUALIZER is not set +-# CONFIG_TUN is not set +-# CONFIG_VETH is not set +-# CONFIG_NET_SB1000 is not set +-# CONFIG_ARCNET is not set +-CONFIG_PHYLIB=y +- +-# +-# MII PHY device drivers +-# +-# CONFIG_MARVELL_PHY is not set +-# CONFIG_DAVICOM_PHY is not set +-# CONFIG_QSEMI_PHY is not set +-# CONFIG_LXT_PHY is not set +-# CONFIG_CICADA_PHY is not set +-# CONFIG_VITESSE_PHY is not set +-# CONFIG_SMSC_PHY is not set +-# CONFIG_BROADCOM_PHY is not set +-# CONFIG_ICPLUS_PHY is not set +-# CONFIG_REALTEK_PHY is not set +-# CONFIG_NATIONAL_PHY is not set +-# CONFIG_STE10XP is not set +-# CONFIG_LSI_ET1011C_PHY is not set +-# CONFIG_FIXED_PHY is not set +-# CONFIG_MDIO_BITBANG is not set +-CONFIG_NET_ETHERNET=y +-CONFIG_MII=m +-# CONFIG_HAPPYMEAL is not set +-# CONFIG_SUNGEM is not set +-# CONFIG_CASSINI is not set +-# CONFIG_NET_VENDOR_3COM is not set +-CONFIG_NET_TULIP=y +-# CONFIG_DE2104X is not set +-CONFIG_TULIP=m +-# CONFIG_TULIP_MWI is not set +-# CONFIG_TULIP_MMIO is not set +-# CONFIG_TULIP_NAPI is not set +-# CONFIG_DE4X5 is not set +-# CONFIG_WINBOND_840 is not set +-# CONFIG_DM9102 is not set +-# CONFIG_ULI526X is not set +-# CONFIG_HP100 is not set +-# CONFIG_IBM_NEW_EMAC_ZMII is not set +-# CONFIG_IBM_NEW_EMAC_RGMII is not set +-# CONFIG_IBM_NEW_EMAC_TAH is not set +-# CONFIG_IBM_NEW_EMAC_EMAC4 is not set +-# CONFIG_IBM_NEW_EMAC_NO_FLOW_CTRL is not set +-# CONFIG_IBM_NEW_EMAC_MAL_CLR_ICINTSTAT is not set +-# CONFIG_IBM_NEW_EMAC_MAL_COMMON_ERR is not set +-CONFIG_NET_PCI=y +-# CONFIG_PCNET32 is not set +-# CONFIG_AMD8111_ETH is not set +-# CONFIG_ADAPTEC_STARFIRE is not set +-# CONFIG_B44 is not set +-# CONFIG_FORCEDETH is not set +-CONFIG_E100=m +-# CONFIG_FEALNX is not set +-# CONFIG_NATSEMI is not set +-# CONFIG_NE2K_PCI is not set +-# CONFIG_8139CP is not set +-# CONFIG_8139TOO is not set +-# CONFIG_R6040 is not set +-# CONFIG_SIS900 is not set +-# CONFIG_EPIC100 is not set +-# CONFIG_SMSC9420 is not set +-# CONFIG_SUNDANCE is not set +-# CONFIG_TLAN is not set +-# CONFIG_VIA_RHINE is not set +-# CONFIG_SC92031 is not set +-# CONFIG_ATL2 is not set +-CONFIG_NETDEV_1000=y +-# CONFIG_ACENIC is not set +-# CONFIG_DL2K is not set +-CONFIG_E1000=y +-# CONFIG_E1000E is not set +-# CONFIG_IP1000 is not set +-# CONFIG_IGB is not set +-# CONFIG_NS83820 is not set +-# CONFIG_HAMACHI is not set +-# CONFIG_YELLOWFIN is not set +-# CONFIG_R8169 is not set +-# CONFIG_SIS190 is not set +-# CONFIG_SKGE is not set +-# CONFIG_SKY2 is not set +-# CONFIG_VIA_VELOCITY is not set +-CONFIG_TIGON3=y +-# CONFIG_BNX2 is not set +-# CONFIG_QLA3XXX is not set +-# CONFIG_ATL1 is not set +-# CONFIG_ATL1E is not set +-# CONFIG_JME is not set +-CONFIG_NETDEV_10000=y +-# CONFIG_CHELSIO_T1 is not set +-CONFIG_CHELSIO_T3_DEPENDS=y +-# CONFIG_CHELSIO_T3 is not set +-# CONFIG_ENIC is not set +-# CONFIG_IXGBE is not set +-# CONFIG_IXGB is not set +-# CONFIG_S2IO is not set +-# CONFIG_MYRI10GE is not set +-# CONFIG_NETXEN_NIC is not set +-# CONFIG_NIU is not set +-# CONFIG_MLX4_EN is not set +-# CONFIG_MLX4_CORE is not set +-# CONFIG_TEHUTI is not set +-# CONFIG_BNX2X is not set +-# CONFIG_QLGE is not set +-# CONFIG_SFC is not set +-# CONFIG_TR is not set +- +-# +-# Wireless LAN +-# +-# CONFIG_WLAN_PRE80211 is not set +-# CONFIG_WLAN_80211 is not set +-# CONFIG_IWLWIFI_LEDS is not set +- +-# +-# Enable WiMAX (Networking options) to see the WiMAX drivers +-# +- +-# +-# USB Network Adapters +-# +-# CONFIG_USB_CATC is not set +-# CONFIG_USB_KAWETH is not set +-# CONFIG_USB_PEGASUS is not set +-# CONFIG_USB_RTL8150 is not set +-# CONFIG_USB_USBNET is not set +-# CONFIG_WAN is not set +-CONFIG_XEN_NETDEV_FRONTEND=y +-# CONFIG_FDDI is not set +-# CONFIG_HIPPI is not set +-# CONFIG_PPP is not set +-# CONFIG_SLIP is not set +-# CONFIG_NET_FC is not set +-CONFIG_NETCONSOLE=y +-# CONFIG_NETCONSOLE_DYNAMIC is not set +-CONFIG_NETPOLL=y +-# CONFIG_NETPOLL_TRAP is not set +-CONFIG_NET_POLL_CONTROLLER=y +-# CONFIG_ISDN is not set +-# CONFIG_PHONE is not set +- +-# +-# Input device support +-# +-CONFIG_INPUT=y +-# CONFIG_INPUT_FF_MEMLESS is not set +-# CONFIG_INPUT_POLLDEV is not set +- +-# +-# Userland interfaces +-# +-CONFIG_INPUT_MOUSEDEV=y +-CONFIG_INPUT_MOUSEDEV_PSAUX=y +-CONFIG_INPUT_MOUSEDEV_SCREEN_X=1024 +-CONFIG_INPUT_MOUSEDEV_SCREEN_Y=768 +-# CONFIG_INPUT_JOYDEV is not set +-# CONFIG_INPUT_EVDEV is not set +-# CONFIG_INPUT_EVBUG is not set +- +-# +-# Input Device Drivers +-# +-CONFIG_INPUT_KEYBOARD=y +-CONFIG_KEYBOARD_ATKBD=y +-# CONFIG_KEYBOARD_SUNKBD is not set +-# CONFIG_KEYBOARD_LKKBD is not set +-# CONFIG_KEYBOARD_XTKBD is not set +-# CONFIG_KEYBOARD_NEWTON is not set +-# CONFIG_KEYBOARD_STOWAWAY is not set +-CONFIG_INPUT_MOUSE=y +-CONFIG_MOUSE_PS2=y +-CONFIG_MOUSE_PS2_ALPS=y +-CONFIG_MOUSE_PS2_LOGIPS2PP=y +-CONFIG_MOUSE_PS2_SYNAPTICS=y +-CONFIG_MOUSE_PS2_LIFEBOOK=y +-CONFIG_MOUSE_PS2_TRACKPOINT=y +-# CONFIG_MOUSE_PS2_ELANTECH is not set +-# CONFIG_MOUSE_PS2_TOUCHKIT is not set +-# CONFIG_MOUSE_SERIAL is not set +-# CONFIG_MOUSE_APPLETOUCH is not set +-# CONFIG_MOUSE_BCM5974 is not set +-# CONFIG_MOUSE_VSXXXAA is not set +-# CONFIG_INPUT_JOYSTICK is not set +-# CONFIG_INPUT_TABLET is not set +-# CONFIG_INPUT_TOUCHSCREEN is not set +-# CONFIG_INPUT_MISC is not set +- +-# +-# Hardware I/O ports +-# +-CONFIG_SERIO=y +-CONFIG_SERIO_I8042=y +-# CONFIG_SERIO_SERPORT is not set +-# CONFIG_SERIO_PCIPS2 is not set +-CONFIG_SERIO_LIBPS2=y +-# CONFIG_SERIO_RAW is not set +-CONFIG_GAMEPORT=m +-# CONFIG_GAMEPORT_NS558 is not set +-# CONFIG_GAMEPORT_L4 is not set +-# CONFIG_GAMEPORT_EMU10K1 is not set +-# CONFIG_GAMEPORT_FM801 is not set +- +-# +-# Character devices +-# +-CONFIG_VT=y +-CONFIG_CONSOLE_TRANSLATIONS=y +-CONFIG_VT_CONSOLE=y +-CONFIG_HW_CONSOLE=y +-# CONFIG_VT_HW_CONSOLE_BINDING is not set +-CONFIG_DEVKMEM=y +-CONFIG_SERIAL_NONSTANDARD=y +-# CONFIG_COMPUTONE is not set +-# CONFIG_ROCKETPORT is not set +-# CONFIG_CYCLADES is not set +-# CONFIG_DIGIEPCA is not set +-# CONFIG_MOXA_INTELLIO is not set +-# CONFIG_MOXA_SMARTIO is not set +-# CONFIG_ISI is not set +-# CONFIG_SYNCLINKMP is not set +-# CONFIG_SYNCLINK_GT is not set +-# CONFIG_N_HDLC is not set +-# CONFIG_RISCOM8 is not set +-# CONFIG_SPECIALIX is not set +-# CONFIG_SX is not set +-# CONFIG_RIO is not set +-# CONFIG_STALDRV is not set +-# CONFIG_NOZOMI is not set +- +-# +-# Serial drivers +-# +-CONFIG_SERIAL_8250=y +-CONFIG_SERIAL_8250_CONSOLE=y +-CONFIG_SERIAL_8250_PCI=y +-CONFIG_SERIAL_8250_PNP=y +-CONFIG_SERIAL_8250_NR_UARTS=6 +-CONFIG_SERIAL_8250_RUNTIME_UARTS=4 +-CONFIG_SERIAL_8250_EXTENDED=y +-CONFIG_SERIAL_8250_SHARE_IRQ=y +-# CONFIG_SERIAL_8250_DETECT_IRQ is not set +-# CONFIG_SERIAL_8250_RSA is not set +- +-# +-# Non-8250 serial port support +-# +-CONFIG_SERIAL_CORE=y +-CONFIG_SERIAL_CORE_CONSOLE=y +-# CONFIG_SERIAL_JSM is not set +-CONFIG_UNIX98_PTYS=y +-# CONFIG_DEVPTS_MULTIPLE_INSTANCES is not set +-CONFIG_LEGACY_PTYS=y +-CONFIG_LEGACY_PTY_COUNT=256 +-CONFIG_HVC_DRIVER=y +-CONFIG_HVC_IRQ=y +-CONFIG_HVC_XEN=y +-# CONFIG_IPMI_HANDLER is not set +-# CONFIG_HW_RANDOM is not set +-CONFIG_EFI_RTC=y +-# CONFIG_R3964 is not set +-# CONFIG_APPLICOM is not set +-CONFIG_RAW_DRIVER=m +-CONFIG_MAX_RAW_DEVS=256 +-CONFIG_HPET=y +-CONFIG_HPET_MMAP=y +-# CONFIG_HANGCHECK_TIMER is not set +-# CONFIG_TCG_TPM is not set +-CONFIG_DEVPORT=y +-CONFIG_I2C=m +-CONFIG_I2C_BOARDINFO=y +-# CONFIG_I2C_CHARDEV is not set +-CONFIG_I2C_HELPER_AUTO=y +-CONFIG_I2C_ALGOBIT=m +- +-# +-# I2C Hardware Bus support +-# +- +-# +-# PC SMBus host controller drivers +-# +-# CONFIG_I2C_ALI1535 is not set +-# CONFIG_I2C_ALI1563 is not set +-# CONFIG_I2C_ALI15X3 is not set +-# CONFIG_I2C_AMD756 is not set +-# CONFIG_I2C_AMD8111 is not set +-# CONFIG_I2C_I801 is not set +-# CONFIG_I2C_ISCH is not set +-# CONFIG_I2C_PIIX4 is not set +-# CONFIG_I2C_NFORCE2 is not set +-# CONFIG_I2C_SIS5595 is not set +-# CONFIG_I2C_SIS630 is not set +-# CONFIG_I2C_SIS96X is not set +-# CONFIG_I2C_VIA is not set +-# CONFIG_I2C_VIAPRO is not set +- +-# +-# I2C system bus drivers (mostly embedded / system-on-chip) +-# +-# CONFIG_I2C_OCORES is not set +-# CONFIG_I2C_SIMTEC is not set +- +-# +-# External I2C/SMBus adapter drivers +-# +-# CONFIG_I2C_PARPORT_LIGHT is not set +-# CONFIG_I2C_TAOS_EVM is not set +-# CONFIG_I2C_TINY_USB is not set +- +-# +-# Graphics adapter I2C/DDC channel drivers +-# +-# CONFIG_I2C_VOODOO3 is not set +- +-# +-# Other I2C/SMBus bus drivers +-# +-# CONFIG_I2C_PCA_PLATFORM is not set +-# CONFIG_I2C_STUB is not set +- +-# +-# Miscellaneous I2C Chip support +-# +-# CONFIG_DS1682 is not set +-# CONFIG_AT24 is not set +-# CONFIG_SENSORS_EEPROM is not set +-# CONFIG_SENSORS_PCF8574 is not set +-# CONFIG_PCF8575 is not set +-# CONFIG_SENSORS_PCA9539 is not set +-# CONFIG_SENSORS_PCF8591 is not set +-# CONFIG_SENSORS_MAX6875 is not set +-# CONFIG_SENSORS_TSL2550 is not set +-# CONFIG_I2C_DEBUG_CORE is not set +-# CONFIG_I2C_DEBUG_ALGO is not set +-# CONFIG_I2C_DEBUG_BUS is not set +-# CONFIG_I2C_DEBUG_CHIP is not set +-# CONFIG_SPI is not set +-# CONFIG_W1 is not set +-CONFIG_POWER_SUPPLY=y +-# CONFIG_POWER_SUPPLY_DEBUG is not set +-# CONFIG_PDA_POWER is not set +-# CONFIG_BATTERY_DS2760 is not set +-# CONFIG_BATTERY_BQ27x00 is not set +-CONFIG_HWMON=y +-# CONFIG_HWMON_VID is not set +-# CONFIG_SENSORS_AD7414 is not set +-# CONFIG_SENSORS_AD7418 is not set +-# CONFIG_SENSORS_ADM1021 is not set +-# CONFIG_SENSORS_ADM1025 is not set +-# CONFIG_SENSORS_ADM1026 is not set +-# CONFIG_SENSORS_ADM1029 is not set +-# CONFIG_SENSORS_ADM1031 is not set +-# CONFIG_SENSORS_ADM9240 is not set +-# CONFIG_SENSORS_ADT7462 is not set +-# CONFIG_SENSORS_ADT7470 is not set +-# CONFIG_SENSORS_ADT7473 is not set +-# CONFIG_SENSORS_ATXP1 is not set +-# CONFIG_SENSORS_DS1621 is not set +-# CONFIG_SENSORS_I5K_AMB is not set +-# CONFIG_SENSORS_F71805F is not set +-# CONFIG_SENSORS_F71882FG is not set +-# CONFIG_SENSORS_F75375S is not set +-# CONFIG_SENSORS_GL518SM is not set +-# CONFIG_SENSORS_GL520SM is not set +-# CONFIG_SENSORS_IT87 is not set +-# CONFIG_SENSORS_LM63 is not set +-# CONFIG_SENSORS_LM75 is not set +-# CONFIG_SENSORS_LM77 is not set +-# CONFIG_SENSORS_LM78 is not set +-# CONFIG_SENSORS_LM80 is not set +-# CONFIG_SENSORS_LM83 is not set +-# CONFIG_SENSORS_LM85 is not set +-# CONFIG_SENSORS_LM87 is not set +-# CONFIG_SENSORS_LM90 is not set +-# CONFIG_SENSORS_LM92 is not set +-# CONFIG_SENSORS_LM93 is not set +-# CONFIG_SENSORS_LTC4245 is not set +-# CONFIG_SENSORS_MAX1619 is not set +-# CONFIG_SENSORS_MAX6650 is not set +-# CONFIG_SENSORS_PC87360 is not set +-# CONFIG_SENSORS_PC87427 is not set +-# CONFIG_SENSORS_SIS5595 is not set +-# CONFIG_SENSORS_DME1737 is not set +-# CONFIG_SENSORS_SMSC47M1 is not set +-# CONFIG_SENSORS_SMSC47M192 is not set +-# CONFIG_SENSORS_SMSC47B397 is not set +-# CONFIG_SENSORS_ADS7828 is not set +-# CONFIG_SENSORS_THMC50 is not set +-# CONFIG_SENSORS_VIA686A is not set +-# CONFIG_SENSORS_VT1211 is not set +-# CONFIG_SENSORS_VT8231 is not set +-# CONFIG_SENSORS_W83781D is not set +-# CONFIG_SENSORS_W83791D is not set +-# CONFIG_SENSORS_W83792D is not set +-# CONFIG_SENSORS_W83793 is not set +-# CONFIG_SENSORS_W83L785TS is not set +-# CONFIG_SENSORS_W83L786NG is not set +-# CONFIG_SENSORS_W83627HF is not set +-# CONFIG_SENSORS_W83627EHF is not set +-# CONFIG_SENSORS_LIS3LV02D is not set +-# CONFIG_HWMON_DEBUG_CHIP is not set +-CONFIG_THERMAL=m +-# CONFIG_THERMAL_HWMON is not set +-# CONFIG_WATCHDOG is not set +-CONFIG_SSB_POSSIBLE=y +- +-# +-# Sonics Silicon Backplane +-# +-# CONFIG_SSB is not set +- +-# +-# Multifunction device drivers +-# +-# CONFIG_MFD_CORE is not set +-# CONFIG_MFD_SM501 is not set +-# CONFIG_HTC_PASIC3 is not set +-# CONFIG_MFD_TMIO is not set +-# CONFIG_MFD_WM8400 is not set +-# CONFIG_MFD_WM8350_I2C is not set +-# CONFIG_MFD_PCF50633 is not set +-# CONFIG_REGULATOR is not set +- +-# +-# Multimedia devices +-# +- +-# +-# Multimedia core support +-# +-# CONFIG_VIDEO_DEV is not set +-# CONFIG_DVB_CORE is not set +-# CONFIG_VIDEO_MEDIA is not set +- +-# +-# Multimedia drivers +-# +-CONFIG_DAB=y +-# CONFIG_USB_DABUSB is not set +- +-# +-# Graphics support +-# +-CONFIG_AGP=m +-CONFIG_DRM=m +-CONFIG_DRM_TDFX=m +-CONFIG_DRM_R128=m +-CONFIG_DRM_RADEON=m +-CONFIG_DRM_MGA=m +-CONFIG_DRM_SIS=m +-# CONFIG_DRM_VIA is not set +-# CONFIG_DRM_SAVAGE is not set +-# CONFIG_VGASTATE is not set +-# CONFIG_VIDEO_OUTPUT_CONTROL is not set +-# CONFIG_FB is not set +-# CONFIG_BACKLIGHT_LCD_SUPPORT is not set +- +-# +-# Display device support +-# +-# CONFIG_DISPLAY_SUPPORT is not set +- +-# +-# Console display driver support +-# +-CONFIG_VGA_CONSOLE=y +-# CONFIG_VGACON_SOFT_SCROLLBACK is not set +-CONFIG_DUMMY_CONSOLE=y +-# CONFIG_SOUND is not set +-CONFIG_HID_SUPPORT=y +-CONFIG_HID=y +-# CONFIG_HID_DEBUG is not set +-# CONFIG_HIDRAW is not set +- +-# +-# USB Input Devices +-# +-CONFIG_USB_HID=y +-# CONFIG_HID_PID is not set +-# CONFIG_USB_HIDDEV is not set +- +-# +-# Special HID drivers +-# +-CONFIG_HID_COMPAT=y +-CONFIG_HID_A4TECH=y +-CONFIG_HID_APPLE=y +-CONFIG_HID_BELKIN=y +-CONFIG_HID_CHERRY=y +-CONFIG_HID_CHICONY=y +-CONFIG_HID_CYPRESS=y +-CONFIG_HID_EZKEY=y +-CONFIG_HID_GYRATION=y +-CONFIG_HID_LOGITECH=y +-# CONFIG_LOGITECH_FF is not set +-# CONFIG_LOGIRUMBLEPAD2_FF is not set +-CONFIG_HID_MICROSOFT=y +-CONFIG_HID_MONTEREY=y +-CONFIG_HID_NTRIG=y +-CONFIG_HID_PANTHERLORD=y +-# CONFIG_PANTHERLORD_FF is not set +-CONFIG_HID_PETALYNX=y +-CONFIG_HID_SAMSUNG=y +-CONFIG_HID_SONY=y +-CONFIG_HID_SUNPLUS=y +-# CONFIG_GREENASIA_FF is not set +-CONFIG_HID_TOPSEED=y +-# CONFIG_THRUSTMASTER_FF is not set +-# CONFIG_ZEROPLUS_FF is not set +-CONFIG_USB_SUPPORT=y +-CONFIG_USB_ARCH_HAS_HCD=y +-CONFIG_USB_ARCH_HAS_OHCI=y +-CONFIG_USB_ARCH_HAS_EHCI=y +-CONFIG_USB=y +-# CONFIG_USB_DEBUG is not set +-# CONFIG_USB_ANNOUNCE_NEW_DEVICES is not set +- +-# +-# Miscellaneous USB options +-# +-CONFIG_USB_DEVICEFS=y +-CONFIG_USB_DEVICE_CLASS=y +-# CONFIG_USB_DYNAMIC_MINORS is not set +-# CONFIG_USB_SUSPEND is not set +-# CONFIG_USB_OTG is not set +-# CONFIG_USB_MON is not set +-# CONFIG_USB_WUSB is not set +-# CONFIG_USB_WUSB_CBAF is not set +- +-# +-# USB Host Controller Drivers +-# +-# CONFIG_USB_C67X00_HCD is not set +-CONFIG_USB_EHCI_HCD=m +-# CONFIG_USB_EHCI_ROOT_HUB_TT is not set +-# CONFIG_USB_EHCI_TT_NEWSCHED is not set +-# CONFIG_USB_OXU210HP_HCD is not set +-# CONFIG_USB_ISP116X_HCD is not set +-# CONFIG_USB_ISP1760_HCD is not set +-CONFIG_USB_OHCI_HCD=m +-# CONFIG_USB_OHCI_BIG_ENDIAN_DESC is not set +-# CONFIG_USB_OHCI_BIG_ENDIAN_MMIO is not set +-CONFIG_USB_OHCI_LITTLE_ENDIAN=y +-CONFIG_USB_UHCI_HCD=y +-# CONFIG_USB_SL811_HCD is not set +-# CONFIG_USB_R8A66597_HCD is not set +-# CONFIG_USB_WHCI_HCD is not set +-# CONFIG_USB_HWA_HCD is not set +- +-# +-# USB Device Class drivers +-# +-# CONFIG_USB_ACM is not set +-# CONFIG_USB_PRINTER is not set +-# CONFIG_USB_WDM is not set +-# CONFIG_USB_TMC is not set +- +-# +-# NOTE: USB_STORAGE depends on SCSI but BLK_DEV_SD may also be needed; +-# +- +-# +-# see USB_STORAGE Help for more information +-# +-CONFIG_USB_STORAGE=m +-# CONFIG_USB_STORAGE_DEBUG is not set +-# CONFIG_USB_STORAGE_DATAFAB is not set +-# CONFIG_USB_STORAGE_FREECOM is not set +-# CONFIG_USB_STORAGE_ISD200 is not set +-# CONFIG_USB_STORAGE_USBAT is not set +-# CONFIG_USB_STORAGE_SDDR09 is not set +-# CONFIG_USB_STORAGE_SDDR55 is not set +-# CONFIG_USB_STORAGE_JUMPSHOT is not set +-# CONFIG_USB_STORAGE_ALAUDA is not set +-# CONFIG_USB_STORAGE_ONETOUCH is not set +-# CONFIG_USB_STORAGE_KARMA is not set +-# CONFIG_USB_STORAGE_CYPRESS_ATACB is not set +-# CONFIG_USB_LIBUSUAL is not set +- +-# +-# USB Imaging devices +-# +-# CONFIG_USB_MDC800 is not set +-# CONFIG_USB_MICROTEK is not set +- +-# +-# USB port drivers +-# +-# CONFIG_USB_SERIAL is not set +- +-# +-# USB Miscellaneous drivers +-# +-# CONFIG_USB_EMI62 is not set +-# CONFIG_USB_EMI26 is not set +-# CONFIG_USB_ADUTUX is not set +-# CONFIG_USB_SEVSEG is not set +-# CONFIG_USB_RIO500 is not set +-# CONFIG_USB_LEGOTOWER is not set +-# CONFIG_USB_LCD is not set +-# CONFIG_USB_BERRY_CHARGE is not set +-# CONFIG_USB_LED is not set +-# CONFIG_USB_CYPRESS_CY7C63 is not set +-# CONFIG_USB_CYTHERM is not set +-# CONFIG_USB_PHIDGET is not set +-# CONFIG_USB_IDMOUSE is not set +-# CONFIG_USB_FTDI_ELAN is not set +-# CONFIG_USB_APPLEDISPLAY is not set +-# CONFIG_USB_SISUSBVGA is not set +-# CONFIG_USB_LD is not set +-# CONFIG_USB_TRANCEVIBRATOR is not set +-# CONFIG_USB_IOWARRIOR is not set +-# CONFIG_USB_TEST is not set +-# CONFIG_USB_ISIGHTFW is not set +-# CONFIG_USB_VST is not set +-# CONFIG_USB_GADGET is not set +- +-# +-# OTG and related infrastructure +-# +-# CONFIG_UWB is not set +-# CONFIG_MMC is not set +-# CONFIG_MEMSTICK is not set +-# CONFIG_NEW_LEDS is not set +-# CONFIG_ACCESSIBILITY is not set +-# CONFIG_INFINIBAND is not set +-# CONFIG_RTC_CLASS is not set +-# CONFIG_DMADEVICES is not set +-# CONFIG_UIO is not set +-CONFIG_XEN_BALLOON=y +-CONFIG_XEN_SCRUB_PAGES=y +-CONFIG_XENFS=y +-CONFIG_XEN_COMPAT_XENFS=y +-# CONFIG_STAGING is not set +-# CONFIG_MSPEC is not set +- +-# +-# File systems +-# +-CONFIG_EXT2_FS=y +-CONFIG_EXT2_FS_XATTR=y +-CONFIG_EXT2_FS_POSIX_ACL=y +-CONFIG_EXT2_FS_SECURITY=y +-# CONFIG_EXT2_FS_XIP is not set +-CONFIG_EXT3_FS=y +-CONFIG_EXT3_FS_XATTR=y +-CONFIG_EXT3_FS_POSIX_ACL=y +-CONFIG_EXT3_FS_SECURITY=y +-# CONFIG_EXT4_FS is not set +-CONFIG_JBD=y +-CONFIG_FS_MBCACHE=y +-CONFIG_REISERFS_FS=y +-# CONFIG_REISERFS_CHECK is not set +-# CONFIG_REISERFS_PROC_INFO is not set +-CONFIG_REISERFS_FS_XATTR=y +-CONFIG_REISERFS_FS_POSIX_ACL=y +-CONFIG_REISERFS_FS_SECURITY=y +-# CONFIG_JFS_FS is not set +-CONFIG_FS_POSIX_ACL=y +-CONFIG_FILE_LOCKING=y +-CONFIG_XFS_FS=y +-# CONFIG_XFS_QUOTA is not set +-# CONFIG_XFS_POSIX_ACL is not set +-# CONFIG_XFS_RT is not set +-# CONFIG_XFS_DEBUG is not set +-# CONFIG_GFS2_FS is not set +-# CONFIG_OCFS2_FS is not set +-# CONFIG_BTRFS_FS is not set +-CONFIG_DNOTIFY=y +-CONFIG_INOTIFY=y +-CONFIG_INOTIFY_USER=y +-# CONFIG_QUOTA is not set +-CONFIG_AUTOFS_FS=y +-CONFIG_AUTOFS4_FS=y +-# CONFIG_FUSE_FS is not set +- +-# +-# CD-ROM/DVD Filesystems +-# +-CONFIG_ISO9660_FS=m +-CONFIG_JOLIET=y +-# CONFIG_ZISOFS is not set +-CONFIG_UDF_FS=m +-CONFIG_UDF_NLS=y +- +-# +-# DOS/FAT/NT Filesystems +-# +-CONFIG_FAT_FS=y +-# CONFIG_MSDOS_FS is not set +-CONFIG_VFAT_FS=y +-CONFIG_FAT_DEFAULT_CODEPAGE=437 +-CONFIG_FAT_DEFAULT_IOCHARSET="iso8859-1" +-CONFIG_NTFS_FS=m +-# CONFIG_NTFS_DEBUG is not set +-# CONFIG_NTFS_RW is not set +- +-# +-# Pseudo filesystems +-# +-CONFIG_PROC_FS=y +-CONFIG_PROC_KCORE=y +-CONFIG_PROC_SYSCTL=y +-CONFIG_PROC_PAGE_MONITOR=y +-CONFIG_SYSFS=y +-CONFIG_TMPFS=y +-# CONFIG_TMPFS_POSIX_ACL is not set +-CONFIG_HUGETLBFS=y +-CONFIG_HUGETLB_PAGE=y +-# CONFIG_CONFIGFS_FS is not set +-CONFIG_MISC_FILESYSTEMS=y +-# CONFIG_ADFS_FS is not set +-# CONFIG_AFFS_FS is not set +-# CONFIG_HFS_FS is not set +-# CONFIG_HFSPLUS_FS is not set +-# CONFIG_BEFS_FS is not set +-# CONFIG_BFS_FS is not set +-# CONFIG_EFS_FS is not set +-# CONFIG_CRAMFS is not set +-# CONFIG_SQUASHFS is not set +-# CONFIG_VXFS_FS is not set +-# CONFIG_MINIX_FS is not set +-# CONFIG_OMFS_FS is not set +-# CONFIG_HPFS_FS is not set +-# CONFIG_QNX4FS_FS is not set +-# CONFIG_ROMFS_FS is not set +-# CONFIG_SYSV_FS is not set +-# CONFIG_UFS_FS is not set +-CONFIG_NETWORK_FILESYSTEMS=y +-CONFIG_NFS_FS=m +-CONFIG_NFS_V3=y +-# CONFIG_NFS_V3_ACL is not set +-CONFIG_NFS_V4=y +-CONFIG_NFSD=m +-CONFIG_NFSD_V3=y +-# CONFIG_NFSD_V3_ACL is not set +-CONFIG_NFSD_V4=y +-CONFIG_LOCKD=m +-CONFIG_LOCKD_V4=y +-CONFIG_EXPORTFS=m +-CONFIG_NFS_COMMON=y +-CONFIG_SUNRPC=m +-CONFIG_SUNRPC_GSS=m +-# CONFIG_SUNRPC_REGISTER_V4 is not set +-CONFIG_RPCSEC_GSS_KRB5=m +-# CONFIG_RPCSEC_GSS_SPKM3 is not set +-CONFIG_SMB_FS=m +-CONFIG_SMB_NLS_DEFAULT=y +-CONFIG_SMB_NLS_REMOTE="cp437" +-CONFIG_CIFS=m +-# CONFIG_CIFS_STATS is not set +-# CONFIG_CIFS_WEAK_PW_HASH is not set +-# CONFIG_CIFS_XATTR is not set +-# CONFIG_CIFS_DEBUG2 is not set +-# CONFIG_CIFS_EXPERIMENTAL is not set +-# CONFIG_NCP_FS is not set +-# CONFIG_CODA_FS is not set +-# CONFIG_AFS_FS is not set +- +-# +-# Partition Types +-# +-CONFIG_PARTITION_ADVANCED=y +-# CONFIG_ACORN_PARTITION is not set +-# CONFIG_OSF_PARTITION is not set +-# CONFIG_AMIGA_PARTITION is not set +-# CONFIG_ATARI_PARTITION is not set +-# CONFIG_MAC_PARTITION is not set +-CONFIG_MSDOS_PARTITION=y +-# CONFIG_BSD_DISKLABEL is not set +-# CONFIG_MINIX_SUBPARTITION is not set +-# CONFIG_SOLARIS_X86_PARTITION is not set +-# CONFIG_UNIXWARE_DISKLABEL is not set +-# CONFIG_LDM_PARTITION is not set +-CONFIG_SGI_PARTITION=y +-# CONFIG_ULTRIX_PARTITION is not set +-# CONFIG_SUN_PARTITION is not set +-# CONFIG_KARMA_PARTITION is not set +-CONFIG_EFI_PARTITION=y +-# CONFIG_SYSV68_PARTITION is not set +-CONFIG_NLS=y +-CONFIG_NLS_DEFAULT="iso8859-1" +-CONFIG_NLS_CODEPAGE_437=y +-CONFIG_NLS_CODEPAGE_737=m +-CONFIG_NLS_CODEPAGE_775=m +-CONFIG_NLS_CODEPAGE_850=m +-CONFIG_NLS_CODEPAGE_852=m +-CONFIG_NLS_CODEPAGE_855=m +-CONFIG_NLS_CODEPAGE_857=m +-CONFIG_NLS_CODEPAGE_860=m +-CONFIG_NLS_CODEPAGE_861=m +-CONFIG_NLS_CODEPAGE_862=m +-CONFIG_NLS_CODEPAGE_863=m +-CONFIG_NLS_CODEPAGE_864=m +-CONFIG_NLS_CODEPAGE_865=m +-CONFIG_NLS_CODEPAGE_866=m +-CONFIG_NLS_CODEPAGE_869=m +-CONFIG_NLS_CODEPAGE_936=m +-CONFIG_NLS_CODEPAGE_950=m +-CONFIG_NLS_CODEPAGE_932=m +-CONFIG_NLS_CODEPAGE_949=m +-CONFIG_NLS_CODEPAGE_874=m +-CONFIG_NLS_ISO8859_8=m +-CONFIG_NLS_CODEPAGE_1250=m +-CONFIG_NLS_CODEPAGE_1251=m +-# CONFIG_NLS_ASCII is not set +-CONFIG_NLS_ISO8859_1=y +-CONFIG_NLS_ISO8859_2=m +-CONFIG_NLS_ISO8859_3=m +-CONFIG_NLS_ISO8859_4=m +-CONFIG_NLS_ISO8859_5=m +-CONFIG_NLS_ISO8859_6=m +-CONFIG_NLS_ISO8859_7=m +-CONFIG_NLS_ISO8859_9=m +-CONFIG_NLS_ISO8859_13=m +-CONFIG_NLS_ISO8859_14=m +-CONFIG_NLS_ISO8859_15=m +-CONFIG_NLS_KOI8_R=m +-CONFIG_NLS_KOI8_U=m +-CONFIG_NLS_UTF8=m +-# CONFIG_DLM is not set +- +-# +-# Kernel hacking +-# +-# CONFIG_PRINTK_TIME is not set +-CONFIG_ENABLE_WARN_DEPRECATED=y +-CONFIG_ENABLE_MUST_CHECK=y +-CONFIG_FRAME_WARN=2048 +-CONFIG_MAGIC_SYSRQ=y +-# CONFIG_UNUSED_SYMBOLS is not set +-# CONFIG_DEBUG_FS is not set +-# CONFIG_HEADERS_CHECK is not set +-CONFIG_DEBUG_KERNEL=y +-# CONFIG_DEBUG_SHIRQ is not set +-CONFIG_DETECT_SOFTLOCKUP=y +-# CONFIG_BOOTPARAM_SOFTLOCKUP_PANIC is not set +-CONFIG_BOOTPARAM_SOFTLOCKUP_PANIC_VALUE=0 +-CONFIG_SCHED_DEBUG=y +-# CONFIG_SCHEDSTATS is not set +-# CONFIG_TIMER_STATS is not set +-# CONFIG_DEBUG_OBJECTS is not set +-# CONFIG_SLUB_DEBUG_ON is not set +-# CONFIG_SLUB_STATS is not set +-# CONFIG_DEBUG_RT_MUTEXES is not set +-# CONFIG_RT_MUTEX_TESTER is not set +-# CONFIG_DEBUG_SPINLOCK is not set +-CONFIG_DEBUG_MUTEXES=y +-# CONFIG_DEBUG_SPINLOCK_SLEEP is not set +-# CONFIG_DEBUG_LOCKING_API_SELFTESTS is not set +-# CONFIG_DEBUG_KOBJECT is not set +-# CONFIG_DEBUG_INFO is not set +-# CONFIG_DEBUG_VM is not set +-# CONFIG_DEBUG_WRITECOUNT is not set +-CONFIG_DEBUG_MEMORY_INIT=y +-# CONFIG_DEBUG_LIST is not set +-# CONFIG_DEBUG_SG is not set +-# CONFIG_DEBUG_NOTIFIERS is not set +-# CONFIG_BOOT_PRINTK_DELAY is not set +-# CONFIG_RCU_TORTURE_TEST is not set +-# CONFIG_RCU_CPU_STALL_DETECTOR is not set +-# CONFIG_BACKTRACE_SELF_TEST is not set +-# CONFIG_DEBUG_BLOCK_EXT_DEVT is not set +-# CONFIG_FAULT_INJECTION is not set +-# CONFIG_SYSCTL_SYSCALL_CHECK is not set +- +-# +-# Tracers +-# +-# CONFIG_SCHED_TRACER is not set +-# CONFIG_CONTEXT_SWITCH_TRACER is not set +-# CONFIG_BOOT_TRACER is not set +-# CONFIG_TRACE_BRANCH_PROFILING is not set +-# CONFIG_DYNAMIC_PRINTK_DEBUG is not set +-# CONFIG_SAMPLES is not set +-CONFIG_IA64_GRANULE_16MB=y +-# CONFIG_IA64_GRANULE_64MB is not set +-# CONFIG_IA64_PRINT_HAZARDS is not set +-# CONFIG_DISABLE_VHPT is not set +-# CONFIG_IA64_DEBUG_CMPXCHG is not set +-# CONFIG_IA64_DEBUG_IRQ is not set +- +-# +-# Security options +-# +-# CONFIG_KEYS is not set +-# CONFIG_SECURITY is not set +-# CONFIG_SECURITYFS is not set +-# CONFIG_SECURITY_FILE_CAPABILITIES is not set +-CONFIG_CRYPTO=y +- +-# +-# Crypto core or helper +-# +-# CONFIG_CRYPTO_FIPS is not set +-CONFIG_CRYPTO_ALGAPI=y +-CONFIG_CRYPTO_ALGAPI2=y +-CONFIG_CRYPTO_AEAD2=y +-CONFIG_CRYPTO_BLKCIPHER=m +-CONFIG_CRYPTO_BLKCIPHER2=y +-CONFIG_CRYPTO_HASH=y +-CONFIG_CRYPTO_HASH2=y +-CONFIG_CRYPTO_RNG2=y +-CONFIG_CRYPTO_MANAGER=m +-CONFIG_CRYPTO_MANAGER2=y +-# CONFIG_CRYPTO_GF128MUL is not set +-# CONFIG_CRYPTO_NULL is not set +-# CONFIG_CRYPTO_CRYPTD is not set +-# CONFIG_CRYPTO_AUTHENC is not set +-# CONFIG_CRYPTO_TEST is not set +- +-# +-# Authenticated Encryption with Associated Data +-# +-# CONFIG_CRYPTO_CCM is not set +-# CONFIG_CRYPTO_GCM is not set +-# CONFIG_CRYPTO_SEQIV is not set +- +-# +-# Block modes +-# +-CONFIG_CRYPTO_CBC=m +-# CONFIG_CRYPTO_CTR is not set +-# CONFIG_CRYPTO_CTS is not set +-CONFIG_CRYPTO_ECB=m +-# CONFIG_CRYPTO_LRW is not set +-CONFIG_CRYPTO_PCBC=m +-# CONFIG_CRYPTO_XTS is not set +- +-# +-# Hash modes +-# +-# CONFIG_CRYPTO_HMAC is not set +-# CONFIG_CRYPTO_XCBC is not set +- +-# +-# Digest +-# +-# CONFIG_CRYPTO_CRC32C is not set +-# CONFIG_CRYPTO_MD4 is not set +-CONFIG_CRYPTO_MD5=y +-# CONFIG_CRYPTO_MICHAEL_MIC is not set +-# CONFIG_CRYPTO_RMD128 is not set +-# CONFIG_CRYPTO_RMD160 is not set +-# CONFIG_CRYPTO_RMD256 is not set +-# CONFIG_CRYPTO_RMD320 is not set +-# CONFIG_CRYPTO_SHA1 is not set +-# CONFIG_CRYPTO_SHA256 is not set +-# CONFIG_CRYPTO_SHA512 is not set +-# CONFIG_CRYPTO_TGR192 is not set +-# CONFIG_CRYPTO_WP512 is not set +- +-# +-# Ciphers +-# +-# CONFIG_CRYPTO_AES is not set +-# CONFIG_CRYPTO_ANUBIS is not set +-# CONFIG_CRYPTO_ARC4 is not set +-# CONFIG_CRYPTO_BLOWFISH is not set +-# CONFIG_CRYPTO_CAMELLIA is not set +-# CONFIG_CRYPTO_CAST5 is not set +-# CONFIG_CRYPTO_CAST6 is not set +-CONFIG_CRYPTO_DES=m +-# CONFIG_CRYPTO_FCRYPT is not set +-# CONFIG_CRYPTO_KHAZAD is not set +-# CONFIG_CRYPTO_SALSA20 is not set +-# CONFIG_CRYPTO_SEED is not set +-# CONFIG_CRYPTO_SERPENT is not set +-# CONFIG_CRYPTO_TEA is not set +-# CONFIG_CRYPTO_TWOFISH is not set +- +-# +-# Compression +-# +-# CONFIG_CRYPTO_DEFLATE is not set +-# CONFIG_CRYPTO_LZO is not set +- +-# +-# Random Number Generation +-# +-# CONFIG_CRYPTO_ANSI_CPRNG is not set +-CONFIG_CRYPTO_HW=y +-# CONFIG_CRYPTO_DEV_HIFN_795X is not set +-CONFIG_HAVE_KVM=y +-CONFIG_VIRTUALIZATION=y +-# CONFIG_KVM is not set +-# CONFIG_VIRTIO_PCI is not set +-# CONFIG_VIRTIO_BALLOON is not set +- +-# +-# Library routines +-# +-CONFIG_BITREVERSE=y +-CONFIG_GENERIC_FIND_LAST_BIT=y +-# CONFIG_CRC_CCITT is not set +-# CONFIG_CRC16 is not set +-# CONFIG_CRC_T10DIF is not set +-CONFIG_CRC_ITU_T=m +-CONFIG_CRC32=y +-# CONFIG_CRC7 is not set +-# CONFIG_LIBCRC32C is not set +-CONFIG_PLIST=y +-CONFIG_HAS_IOMEM=y +-CONFIG_HAS_IOPORT=y +-CONFIG_HAS_DMA=y +-CONFIG_GENERIC_HARDIRQS=y +-CONFIG_GENERIC_IRQ_PROBE=y +-CONFIG_GENERIC_PENDING_IRQ=y +-CONFIG_IRQ_PER_CPU=y +-# CONFIG_IOMMU_API is not set +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/arch/ia64/hp/common/sba_iommu.c linux-2.6.29-rc3.owrt/arch/ia64/hp/common/sba_iommu.c +--- linux-2.6.29.owrt/arch/ia64/hp/common/sba_iommu.c 2009-05-10 22:04:40.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/arch/ia64/hp/common/sba_iommu.c 2009-05-10 23:48:28.000000000 +0200 +@@ -906,7 +906,7 @@ + * @dir: R/W or both. + * @attrs: optional dma attributes + * +- * See Documentation/PCI/PCI-DMA-mapping.txt ++ * See Documentation/DMA-mapping.txt + */ + dma_addr_t + sba_map_single_attrs(struct device *dev, void *addr, size_t size, int dir, +@@ -1024,7 +1024,7 @@ + * @dir: R/W or both. + * @attrs: optional dma attributes + * +- * See Documentation/PCI/PCI-DMA-mapping.txt ++ * See Documentation/DMA-mapping.txt + */ + void sba_unmap_single_attrs(struct device *dev, dma_addr_t iova, size_t size, + int dir, struct dma_attrs *attrs) +@@ -1102,7 +1102,7 @@ + * @size: number of bytes mapped in driver buffer. + * @dma_handle: IOVA of new buffer. + * +- * See Documentation/PCI/PCI-DMA-mapping.txt ++ * See Documentation/DMA-mapping.txt + */ + void * + sba_alloc_coherent (struct device *dev, size_t size, dma_addr_t *dma_handle, gfp_t flags) +@@ -1165,7 +1165,7 @@ + * @vaddr: virtual address IOVA of "consistent" buffer. + * @dma_handler: IO virtual address of "consistent" buffer. + * +- * See Documentation/PCI/PCI-DMA-mapping.txt ++ * See Documentation/DMA-mapping.txt + */ + void sba_free_coherent (struct device *dev, size_t size, void *vaddr, dma_addr_t dma_handle) + { +@@ -1420,7 +1420,7 @@ + * @dir: R/W or both. + * @attrs: optional dma attributes + * +- * See Documentation/PCI/PCI-DMA-mapping.txt ++ * See Documentation/DMA-mapping.txt + */ + int sba_map_sg_attrs(struct device *dev, struct scatterlist *sglist, int nents, + int dir, struct dma_attrs *attrs) +@@ -1512,7 +1512,7 @@ + * @dir: R/W or both. + * @attrs: optional dma attributes + * +- * See Documentation/PCI/PCI-DMA-mapping.txt ++ * See Documentation/DMA-mapping.txt + */ + void sba_unmap_sg_attrs(struct device *dev, struct scatterlist *sglist, + int nents, int dir, struct dma_attrs *attrs) +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/arch/ia64/include/asm/kvm.h linux-2.6.29-rc3.owrt/arch/ia64/include/asm/kvm.h +--- linux-2.6.29.owrt/arch/ia64/include/asm/kvm.h 2009-05-10 22:04:40.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/arch/ia64/include/asm/kvm.h 2009-05-10 23:48:28.000000000 +0200 +@@ -25,10 +25,6 @@ + + #include <linux/ioctl.h> + +-/* Select x86 specific features in <linux/kvm.h> */ +-#define __KVM_HAVE_IOAPIC +-#define __KVM_HAVE_DEVICE_ASSIGNMENT +- + /* Architectural interrupt line count. */ + #define KVM_NR_INTERRUPTS 256 + +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/arch/ia64/include/asm/mmzone.h linux-2.6.29-rc3.owrt/arch/ia64/include/asm/mmzone.h +--- linux-2.6.29.owrt/arch/ia64/include/asm/mmzone.h 2009-05-10 22:04:40.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/arch/ia64/include/asm/mmzone.h 2009-05-10 23:48:28.000000000 +0200 +@@ -31,6 +31,10 @@ + #endif + } + ++#ifdef CONFIG_HAVE_ARCH_EARLY_PFN_TO_NID ++extern int early_pfn_to_nid(unsigned long pfn); ++#endif ++ + #ifdef CONFIG_IA64_DIG /* DIG systems are small */ + # define MAX_PHYSNODE_ID 8 + # define NR_NODE_MEMBLKS (MAX_NUMNODES * 8) +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/arch/ia64/include/asm/sn/bte.h linux-2.6.29-rc3.owrt/arch/ia64/include/asm/sn/bte.h +--- linux-2.6.29.owrt/arch/ia64/include/asm/sn/bte.h 2009-05-10 22:04:40.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/arch/ia64/include/asm/sn/bte.h 2009-05-10 23:48:28.000000000 +0200 +@@ -39,7 +39,7 @@ + /* BTE status register only supports 16 bits for length field */ + #define BTE_LEN_BITS (16) + #define BTE_LEN_MASK ((1 << BTE_LEN_BITS) - 1) +-#define BTE_MAX_XFER (BTE_LEN_MASK << L1_CACHE_SHIFT) ++#define BTE_MAX_XFER ((1 << BTE_LEN_BITS) * L1_CACHE_BYTES) + + + /* Define hardware */ +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/arch/ia64/Kconfig linux-2.6.29-rc3.owrt/arch/ia64/Kconfig +--- linux-2.6.29.owrt/arch/ia64/Kconfig 2009-05-10 22:04:40.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/arch/ia64/Kconfig 2009-05-10 23:48:28.000000000 +0200 +@@ -221,11 +221,7 @@ + + config IA64_XEN_GUEST + bool "Xen guest" +- select SWIOTLB + depends on XEN +- help +- Build a kernel that runs on Xen guest domain. At this moment only +- 16KB page size in supported. + + endchoice + +@@ -483,7 +479,8 @@ + default y if VIRTUAL_MEM_MAP + + config HAVE_ARCH_EARLY_PFN_TO_NID +- def_bool NUMA && SPARSEMEM ++ def_bool y ++ depends on NEED_MULTIPLE_NODES + + config HAVE_ARCH_NODEDATA_EXTENSION + def_bool y +@@ -638,17 +635,6 @@ + and include PCI device scope covered by these DMA + remapping devices. + +-config DMAR_DEFAULT_ON +- def_bool y +- prompt "Enable DMA Remapping Devices by default" +- depends on DMAR +- help +- Selecting this option will enable a DMAR device at boot time if +- one is found. If this option is not selected, DMAR support can +- be enabled by passing intel_iommu=on to the kernel. It is +- recommended you say N here while the DMAR code remains +- experimental. +- + endmenu + + endif +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/arch/ia64/kernel/iosapic.c linux-2.6.29-rc3.owrt/arch/ia64/kernel/iosapic.c +--- linux-2.6.29.owrt/arch/ia64/kernel/iosapic.c 2009-05-10 22:04:40.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/arch/ia64/kernel/iosapic.c 2009-05-10 23:48:28.000000000 +0200 +@@ -507,7 +507,7 @@ + if (trigger == IOSAPIC_EDGE) + return -EINVAL; + +- for (i = 0; i < NR_IRQS; i++) { ++ for (i = 0; i <= NR_IRQS; i++) { + info = &iosapic_intr_info[i]; + if (info->trigger == trigger && info->polarity == pol && + (info->dmode == IOSAPIC_FIXED || +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/arch/ia64/kernel/smpboot.c linux-2.6.29-rc3.owrt/arch/ia64/kernel/smpboot.c +--- linux-2.6.29.owrt/arch/ia64/kernel/smpboot.c 2009-05-10 22:04:40.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/arch/ia64/kernel/smpboot.c 2009-05-10 23:48:28.000000000 +0200 +@@ -736,15 +736,14 @@ + return -EBUSY; + } + +- cpu_clear(cpu, cpu_online_map); +- + if (migrate_platform_irqs(cpu)) { + cpu_set(cpu, cpu_online_map); +- return -EBUSY; ++ return (-EBUSY); + } + + remove_siblinginfo(cpu); + fixup_irqs(); ++ cpu_clear(cpu, cpu_online_map); + local_flush_tlb_all(); + cpu_clear(cpu, cpu_callin_map); + return 0; +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/arch/ia64/kernel/unwind.c linux-2.6.29-rc3.owrt/arch/ia64/kernel/unwind.c +--- linux-2.6.29.owrt/arch/ia64/kernel/unwind.c 2009-05-10 22:04:40.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/arch/ia64/kernel/unwind.c 2009-05-10 23:48:28.000000000 +0200 +@@ -2149,7 +2149,7 @@ + + /* next, remove hash table entries for this table */ + +- for (index = 0; index < UNW_HASH_SIZE; ++index) { ++ for (index = 0; index <= UNW_HASH_SIZE; ++index) { + tmp = unw.cache + unw.hash[index]; + if (unw.hash[index] >= UNW_CACHE_SIZE + || tmp->ip < table->start || tmp->ip >= table->end) +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/arch/ia64/kvm/kvm-ia64.c linux-2.6.29-rc3.owrt/arch/ia64/kvm/kvm-ia64.c +--- linux-2.6.29.owrt/arch/ia64/kvm/kvm-ia64.c 2009-05-10 22:04:40.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/arch/ia64/kvm/kvm-ia64.c 2009-05-10 23:48:28.000000000 +0200 +@@ -1337,10 +1337,6 @@ + } + } + +-void kvm_arch_sync_events(struct kvm *kvm) +-{ +-} +- + void kvm_arch_destroy_vm(struct kvm *kvm) + { + kvm_iommu_unmap_guest(kvm); +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/arch/ia64/kvm/process.c linux-2.6.29-rc3.owrt/arch/ia64/kvm/process.c +--- linux-2.6.29.owrt/arch/ia64/kvm/process.c 2009-05-10 22:04:40.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/arch/ia64/kvm/process.c 2009-05-10 23:48:28.000000000 +0200 +@@ -455,18 +455,13 @@ + if (!vmm_fpswa_interface) + return (fpswa_ret_t) {-1, 0, 0, 0}; + +- memset(&fp_state, 0, sizeof(fp_state_t)); +- + /* +- * compute fp_state. only FP registers f6 - f11 are used by the +- * vmm, so set those bits in the mask and set the low volatile +- * pointer to point to these registers. ++ * Just let fpswa driver to use hardware fp registers. ++ * No fp register is valid in memory. + */ +- fp_state.bitmask_low64 = 0xfc0; /* bit6..bit11 */ +- +- fp_state.fp_state_low_volatile = (fp_state_low_volatile_t *) ®s->f6; ++ memset(&fp_state, 0, sizeof(fp_state_t)); + +- /* ++ /* + * unsigned long (*EFI_FPSWA) ( + * unsigned long trap_type, + * void *Bundle, +@@ -550,6 +545,10 @@ + status = vmm_handle_fpu_swa(0, regs, isr); + if (!status) + return ; ++ else if (-EAGAIN == status) { ++ vcpu_decrement_iip(vcpu); ++ return ; ++ } + break; + } + +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/arch/ia64/mm/numa.c linux-2.6.29-rc3.owrt/arch/ia64/mm/numa.c +--- linux-2.6.29.owrt/arch/ia64/mm/numa.c 2009-05-10 22:04:40.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/arch/ia64/mm/numa.c 2009-05-10 23:48:28.000000000 +0200 +@@ -58,7 +58,7 @@ + * SPARSEMEM to allocate the SPARSEMEM sectionmap on the NUMA node where + * the section resides. + */ +-int __meminit __early_pfn_to_nid(unsigned long pfn) ++int early_pfn_to_nid(unsigned long pfn) + { + int i, section = pfn >> PFN_SECTION_SHIFT, ssec, esec; + +@@ -70,7 +70,7 @@ + return node_memblk[i].nid; + } + +- return -1; ++ return 0; + } + + #ifdef CONFIG_MEMORY_HOTPLUG +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/arch/ia64/sn/kernel/bte.c linux-2.6.29-rc3.owrt/arch/ia64/sn/kernel/bte.c +--- linux-2.6.29.owrt/arch/ia64/sn/kernel/bte.c 2009-05-10 22:04:40.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/arch/ia64/sn/kernel/bte.c 2009-05-10 23:48:28.000000000 +0200 +@@ -97,10 +97,9 @@ + return BTE_SUCCESS; + } + +- BUG_ON(len & L1_CACHE_MASK); +- BUG_ON(src & L1_CACHE_MASK); +- BUG_ON(dest & L1_CACHE_MASK); +- BUG_ON(len > BTE_MAX_XFER); ++ BUG_ON((len & L1_CACHE_MASK) || ++ (src & L1_CACHE_MASK) || (dest & L1_CACHE_MASK)); ++ BUG_ON(!(len < ((BTE_LEN_MASK + 1) << L1_CACHE_SHIFT))); + + /* + * Start with interface corresponding to cpu number +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/arch/ia64/sn/kernel/io_acpi_init.c linux-2.6.29-rc3.owrt/arch/ia64/sn/kernel/io_acpi_init.c +--- linux-2.6.29.owrt/arch/ia64/sn/kernel/io_acpi_init.c 2009-05-10 22:04:40.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/arch/ia64/sn/kernel/io_acpi_init.c 2009-05-10 23:48:28.000000000 +0200 +@@ -443,7 +443,7 @@ + size = pci_resource_len(dev, PCI_ROM_RESOURCE); + addr = ioremap(pcidev_info->pdi_pio_mapped_addr[PCI_ROM_RESOURCE], + size); +- image_size = pci_get_rom_size(dev, addr, size); ++ image_size = pci_get_rom_size(addr, size); + dev->resource[PCI_ROM_RESOURCE].start = (unsigned long) addr; + dev->resource[PCI_ROM_RESOURCE].end = + (unsigned long) addr + image_size - 1; +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/arch/ia64/sn/kernel/io_init.c linux-2.6.29-rc3.owrt/arch/ia64/sn/kernel/io_init.c +--- linux-2.6.29.owrt/arch/ia64/sn/kernel/io_init.c 2009-05-10 22:04:40.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/arch/ia64/sn/kernel/io_init.c 2009-05-10 23:48:28.000000000 +0200 +@@ -269,7 +269,7 @@ + + rom = ioremap(pci_resource_start(dev, PCI_ROM_RESOURCE), + size + 1); +- image_size = pci_get_rom_size(dev, rom, size + 1); ++ image_size = pci_get_rom_size(rom, size + 1); + dev->resource[PCI_ROM_RESOURCE].end = + dev->resource[PCI_ROM_RESOURCE].start + + image_size - 1; +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/arch/ia64/sn/pci/pcibr/pcibr_dma.c linux-2.6.29-rc3.owrt/arch/ia64/sn/pci/pcibr/pcibr_dma.c +--- linux-2.6.29.owrt/arch/ia64/sn/pci/pcibr/pcibr_dma.c 2009-05-10 22:04:40.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/arch/ia64/sn/pci/pcibr/pcibr_dma.c 2009-05-10 23:48:28.000000000 +0200 +@@ -135,10 +135,11 @@ + if (SN_DMA_ADDRTYPE(dma_flags) == SN_DMA_ADDR_PHYS) + pci_addr = IS_PIC_SOFT(pcibus_info) ? + PHYS_TO_DMA(paddr) : +- PHYS_TO_TIODMA(paddr); ++ PHYS_TO_TIODMA(paddr) | dma_attributes; + else +- pci_addr = paddr; +- pci_addr |= dma_attributes; ++ pci_addr = IS_PIC_SOFT(pcibus_info) ? ++ paddr : ++ paddr | dma_attributes; + + /* Handle Bus mode */ + if (IS_PCIX(pcibus_info)) +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/arch/ia64/xen/Kconfig linux-2.6.29-rc3.owrt/arch/ia64/xen/Kconfig +--- linux-2.6.29.owrt/arch/ia64/xen/Kconfig 2009-05-10 22:04:40.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/arch/ia64/xen/Kconfig 2009-05-10 23:48:28.000000000 +0200 +@@ -8,7 +8,8 @@ + depends on PARAVIRT && MCKINLEY && IA64_PAGE_SIZE_16KB && EXPERIMENTAL + select XEN_XENCOMM + select NO_IDLE_HZ +- # followings are required to save/restore. ++ ++ # those are required to save/restore. + select ARCH_SUSPEND_POSSIBLE + select SUSPEND + select PM_SLEEP +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/arch/ia64/xen/xen_pv_ops.c linux-2.6.29-rc3.owrt/arch/ia64/xen/xen_pv_ops.c +--- linux-2.6.29.owrt/arch/ia64/xen/xen_pv_ops.c 2009-05-10 22:04:40.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/arch/ia64/xen/xen_pv_ops.c 2009-05-10 23:48:28.000000000 +0200 +@@ -153,7 +153,7 @@ + xen_setup_vcpu_info_placement(); + } + +-static const struct pv_init_ops xen_init_ops __initconst = { ++static const struct pv_init_ops xen_init_ops __initdata = { + .banner = xen_banner, + + .reserve_memory = xen_reserve_memory, +@@ -337,7 +337,7 @@ + HYPERVISOR_physdev_op(PHYSDEVOP_apic_write, &apic_op); + } + +-static const struct pv_iosapic_ops xen_iosapic_ops __initconst = { ++static const struct pv_iosapic_ops xen_iosapic_ops __initdata = { + .pcat_compat_init = xen_pcat_compat_init, + .__get_irq_chip = xen_iosapic_get_irq_chip, + +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/arch/m68k/atari/ataints.c linux-2.6.29-rc3.owrt/arch/m68k/atari/ataints.c +--- linux-2.6.29.owrt/arch/m68k/atari/ataints.c 2009-05-10 22:04:40.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/arch/m68k/atari/ataints.c 2009-05-10 23:48:28.000000000 +0200 +@@ -187,8 +187,8 @@ + " jbra ret_from_interrupt\n" \ + : : "i" (&kstat_cpu(0).irqs[n+8]), "i" (&irq_handler[n+8]), \ + "n" (PT_OFF_SR), "n" (n), \ +- "i" (n & 8 ? (n & 16 ? &tt_mfp.int_mk_a : &st_mfp.int_mk_a) \ +- : (n & 16 ? &tt_mfp.int_mk_b : &st_mfp.int_mk_b)), \ ++ "i" (n & 8 ? (n & 16 ? &tt_mfp.int_mk_a : &mfp.int_mk_a) \ ++ : (n & 16 ? &tt_mfp.int_mk_b : &mfp.int_mk_b)), \ + "m" (preempt_count()), "di" (HARDIRQ_OFFSET) \ + ); \ + for (;;); /* fake noreturn */ \ +@@ -366,14 +366,14 @@ + /* Initialize the MFP(s) */ + + #ifdef ATARI_USE_SOFTWARE_EOI +- st_mfp.vec_adr = 0x48; /* Software EOI-Mode */ ++ mfp.vec_adr = 0x48; /* Software EOI-Mode */ + #else +- st_mfp.vec_adr = 0x40; /* Automatic EOI-Mode */ ++ mfp.vec_adr = 0x40; /* Automatic EOI-Mode */ + #endif +- st_mfp.int_en_a = 0x00; /* turn off MFP-Ints */ +- st_mfp.int_en_b = 0x00; +- st_mfp.int_mk_a = 0xff; /* no Masking */ +- st_mfp.int_mk_b = 0xff; ++ mfp.int_en_a = 0x00; /* turn off MFP-Ints */ ++ mfp.int_en_b = 0x00; ++ mfp.int_mk_a = 0xff; /* no Masking */ ++ mfp.int_mk_b = 0xff; + + if (ATARIHW_PRESENT(TT_MFP)) { + #ifdef ATARI_USE_SOFTWARE_EOI +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/arch/m68k/atari/atakeyb.c linux-2.6.29-rc3.owrt/arch/m68k/atari/atakeyb.c +--- linux-2.6.29.owrt/arch/m68k/atari/atakeyb.c 2009-05-10 22:04:40.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/arch/m68k/atari/atakeyb.c 2009-05-10 23:48:28.000000000 +0200 +@@ -609,10 +609,10 @@ + ACIA_RHTID : 0); + + /* make sure the interrupt line is up */ +- } while ((st_mfp.par_dt_reg & 0x10) == 0); ++ } while ((mfp.par_dt_reg & 0x10) == 0); + + /* enable ACIA Interrupts */ +- st_mfp.active_edge &= ~0x10; ++ mfp.active_edge &= ~0x10; + atari_turnon_irq(IRQ_MFP_ACIA); + + ikbd_self_test = 1; +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/arch/m68k/atari/config.c linux-2.6.29-rc3.owrt/arch/m68k/atari/config.c +--- linux-2.6.29.owrt/arch/m68k/atari/config.c 2009-05-10 22:04:40.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/arch/m68k/atari/config.c 2009-05-10 23:48:28.000000000 +0200 +@@ -258,7 +258,7 @@ + printk("STND_SHIFTER "); + } + } +- if (hwreg_present(&st_mfp.par_dt_reg)) { ++ if (hwreg_present(&mfp.par_dt_reg)) { + ATARIHW_SET(ST_MFP); + printk("ST_MFP "); + } +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/arch/m68k/atari/debug.c linux-2.6.29-rc3.owrt/arch/m68k/atari/debug.c +--- linux-2.6.29.owrt/arch/m68k/atari/debug.c 2009-05-10 22:04:40.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/arch/m68k/atari/debug.c 2009-05-10 23:48:28.000000000 +0200 +@@ -34,9 +34,9 @@ + + static inline void ata_mfp_out(char c) + { +- while (!(st_mfp.trn_stat & 0x80)) /* wait for tx buf empty */ ++ while (!(mfp.trn_stat & 0x80)) /* wait for tx buf empty */ + barrier(); +- st_mfp.usart_dta = c; ++ mfp.usart_dta = c; + } + + static void atari_mfp_console_write(struct console *co, const char *str, +@@ -91,7 +91,7 @@ + /* This a some-seconds timeout in case no printer is connected */ + unsigned long i = loops_per_jiffy > 1 ? loops_per_jiffy : 10000000/HZ; + +- while ((st_mfp.par_dt_reg & 1) && --i) /* wait for BUSY == L */ ++ while ((mfp.par_dt_reg & 1) && --i) /* wait for BUSY == L */ + ; + if (!i) + return 0; +@@ -131,9 +131,9 @@ + #if 0 + int atari_mfp_console_wait_key(struct console *co) + { +- while (!(st_mfp.rcv_stat & 0x80)) /* wait for rx buf filled */ ++ while (!(mfp.rcv_stat & 0x80)) /* wait for rx buf filled */ + barrier(); +- return st_mfp.usart_dta; ++ return mfp.usart_dta; + } + + int atari_scc_console_wait_key(struct console *co) +@@ -175,12 +175,12 @@ + baud = B9600; /* use default 9600bps for non-implemented rates */ + baud -= B1200; /* baud_table[] starts at 1200bps */ + +- st_mfp.trn_stat &= ~0x01; /* disable TX */ +- st_mfp.usart_ctr = parity | csize | 0x88; /* 1:16 clk mode, 1 stop bit */ +- st_mfp.tim_ct_cd &= 0x70; /* stop timer D */ +- st_mfp.tim_dt_d = baud_table[baud]; +- st_mfp.tim_ct_cd |= 0x01; /* start timer D, 1:4 */ +- st_mfp.trn_stat |= 0x01; /* enable TX */ ++ mfp.trn_stat &= ~0x01; /* disable TX */ ++ mfp.usart_ctr = parity | csize | 0x88; /* 1:16 clk mode, 1 stop bit */ ++ mfp.tim_ct_cd &= 0x70; /* stop timer D */ ++ mfp.tim_dt_d = baud_table[baud]; ++ mfp.tim_ct_cd |= 0x01; /* start timer D, 1:4 */ ++ mfp.trn_stat |= 0x01; /* enable TX */ + } + + #define SCC_WRITE(reg, val) \ +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/arch/m68k/atari/time.c linux-2.6.29-rc3.owrt/arch/m68k/atari/time.c +--- linux-2.6.29.owrt/arch/m68k/atari/time.c 2009-05-10 22:04:40.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/arch/m68k/atari/time.c 2009-05-10 23:48:28.000000000 +0200 +@@ -27,9 +27,9 @@ + atari_sched_init(irq_handler_t timer_routine) + { + /* set Timer C data Register */ +- st_mfp.tim_dt_c = INT_TICKS; ++ mfp.tim_dt_c = INT_TICKS; + /* start timer C, div = 1:100 */ +- st_mfp.tim_ct_cd = (st_mfp.tim_ct_cd & 15) | 0x60; ++ mfp.tim_ct_cd = (mfp.tim_ct_cd & 15) | 0x60; + /* install interrupt service routine for MFP Timer C */ + if (request_irq(IRQ_MFP_TIMC, timer_routine, IRQ_TYPE_SLOW, + "timer", timer_routine)) +@@ -46,11 +46,11 @@ + unsigned long ticks, offset = 0; + + /* read MFP timer C current value */ +- ticks = st_mfp.tim_dt_c; ++ ticks = mfp.tim_dt_c; + /* The probability of underflow is less than 2% */ + if (ticks > INT_TICKS - INT_TICKS / 50) + /* Check for pending timer interrupt */ +- if (st_mfp.int_pn_b & (1 << 5)) ++ if (mfp.int_pn_b & (1 << 5)) + offset = TICK_SIZE; + + ticks = INT_TICKS - ticks; +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/arch/m68k/include/asm/atarihw.h linux-2.6.29-rc3.owrt/arch/m68k/include/asm/atarihw.h +--- linux-2.6.29.owrt/arch/m68k/include/asm/atarihw.h 2009-05-10 22:04:40.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/arch/m68k/include/asm/atarihw.h 2009-05-10 23:48:28.000000000 +0200 +@@ -113,7 +113,7 @@ + * of nops on various machines. Somebody claimed that the tstb takes 600 ns. + */ + #define MFPDELAY() \ +- __asm__ __volatile__ ( "tstb %0" : : "m" (st_mfp.par_dt_reg) : "cc" ); ++ __asm__ __volatile__ ( "tstb %0" : : "m" (mfp.par_dt_reg) : "cc" ); + + /* Do cache push/invalidate for DMA read/write. This function obeys the + * snooping on some machines (Medusa) and processors: The Medusa itself can +@@ -565,7 +565,7 @@ + u_char char_dummy23; + u_char usart_dta; + }; +-# define st_mfp ((*(volatile struct MFP*)MFP_BAS)) ++# define mfp ((*(volatile struct MFP*)MFP_BAS)) + + /* TT's second MFP */ + +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/arch/m68k/include/asm/atariints.h linux-2.6.29-rc3.owrt/arch/m68k/include/asm/atariints.h +--- linux-2.6.29.owrt/arch/m68k/include/asm/atariints.h 2009-05-10 22:04:40.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/arch/m68k/include/asm/atariints.h 2009-05-10 23:48:28.000000000 +0200 +@@ -113,7 +113,7 @@ + { unsigned char mask, *reg; + + mask = 1 << (irq & 7); +- reg = (unsigned char *)&st_mfp.int_en_a + type*4 + ++ reg = (unsigned char *)&mfp.int_en_a + type*4 + + ((irq & 8) >> 2) + (((irq-8) & 16) << 3); + return( *reg & mask ); + } +@@ -123,7 +123,7 @@ + { unsigned char mask, *reg; + + mask = 1 << (irq & 7); +- reg = (unsigned char *)&st_mfp.int_en_a + type*4 + ++ reg = (unsigned char *)&mfp.int_en_a + type*4 + + ((irq & 8) >> 2) + (((irq-8) & 16) << 3); + __asm__ __volatile__ ( "orb %0,%1" + : : "di" (mask), "m" (*reg) : "memory" ); +@@ -134,7 +134,7 @@ + { unsigned char mask, *reg; + + mask = ~(1 << (irq & 7)); +- reg = (unsigned char *)&st_mfp.int_en_a + type*4 + ++ reg = (unsigned char *)&mfp.int_en_a + type*4 + + ((irq & 8) >> 2) + (((irq-8) & 16) << 3); + if (type == MFP_PENDING || type == MFP_SERVICE) + __asm__ __volatile__ ( "moveb %0,%1" +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/arch/m68k/include/asm/param.h linux-2.6.29-rc3.owrt/arch/m68k/include/asm/param.h +--- linux-2.6.29.owrt/arch/m68k/include/asm/param.h 2009-05-10 22:04:40.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/arch/m68k/include/asm/param.h 2009-05-10 23:48:28.000000000 +0200 +@@ -1,26 +1,5 @@ +-#ifndef _M68K_PARAM_H +-#define _M68K_PARAM_H +- +-#ifdef __KERNEL__ +-# define HZ CONFIG_HZ /* Internal kernel timer frequency */ +-# define USER_HZ 100 /* .. some user interfaces are in "ticks" */ +-# define CLOCKS_PER_SEC (USER_HZ) /* like times() */ +-#endif +- +-#ifndef HZ +-#define HZ 100 +-#endif +- + #ifdef __uClinux__ +-#define EXEC_PAGESIZE 4096 ++#include "param_no.h" + #else +-#define EXEC_PAGESIZE 8192 +-#endif +- +-#ifndef NOGROUP +-#define NOGROUP (-1) ++#include "param_mm.h" + #endif +- +-#define MAXHOSTNAMELEN 64 /* max length of hostname */ +- +-#endif /* _M68K_PARAM_H */ +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/arch/m68k/include/asm/param_mm.h linux-2.6.29-rc3.owrt/arch/m68k/include/asm/param_mm.h +--- linux-2.6.29.owrt/arch/m68k/include/asm/param_mm.h 1970-01-01 01:00:00.000000000 +0100 ++++ linux-2.6.29-rc3.owrt/arch/m68k/include/asm/param_mm.h 2009-05-10 23:48:28.000000000 +0200 +@@ -0,0 +1,22 @@ ++#ifndef _M68K_PARAM_H ++#define _M68K_PARAM_H ++ ++#ifdef __KERNEL__ ++# define HZ CONFIG_HZ /* Internal kernel timer frequency */ ++# define USER_HZ 100 /* .. some user interfaces are in "ticks" */ ++# define CLOCKS_PER_SEC (USER_HZ) /* like times() */ ++#endif ++ ++#ifndef HZ ++#define HZ 100 ++#endif ++ ++#define EXEC_PAGESIZE 8192 ++ ++#ifndef NOGROUP ++#define NOGROUP (-1) ++#endif ++ ++#define MAXHOSTNAMELEN 64 /* max length of hostname */ ++ ++#endif /* _M68K_PARAM_H */ +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/arch/m68k/include/asm/param_no.h linux-2.6.29-rc3.owrt/arch/m68k/include/asm/param_no.h +--- linux-2.6.29.owrt/arch/m68k/include/asm/param_no.h 1970-01-01 01:00:00.000000000 +0100 ++++ linux-2.6.29-rc3.owrt/arch/m68k/include/asm/param_no.h 2009-05-10 23:48:28.000000000 +0200 +@@ -0,0 +1,22 @@ ++#ifndef _M68KNOMMU_PARAM_H ++#define _M68KNOMMU_PARAM_H ++ ++#ifdef __KERNEL__ ++#define HZ CONFIG_HZ ++#define USER_HZ HZ ++#define CLOCKS_PER_SEC (USER_HZ) ++#endif ++ ++#ifndef HZ ++#define HZ 100 ++#endif ++ ++#define EXEC_PAGESIZE 4096 ++ ++#ifndef NOGROUP ++#define NOGROUP (-1) ++#endif ++ ++#define MAXHOSTNAMELEN 64 /* max length of hostname */ ++ ++#endif /* _M68KNOMMU_PARAM_H */ +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/arch/m68k/include/asm/ptrace.h linux-2.6.29-rc3.owrt/arch/m68k/include/asm/ptrace.h +--- linux-2.6.29.owrt/arch/m68k/include/asm/ptrace.h 2009-05-10 22:04:40.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/arch/m68k/include/asm/ptrace.h 2009-05-10 23:48:28.000000000 +0200 +@@ -1,87 +1,5 @@ +-#ifndef _M68K_PTRACE_H +-#define _M68K_PTRACE_H +- +-#define PT_D1 0 +-#define PT_D2 1 +-#define PT_D3 2 +-#define PT_D4 3 +-#define PT_D5 4 +-#define PT_D6 5 +-#define PT_D7 6 +-#define PT_A0 7 +-#define PT_A1 8 +-#define PT_A2 9 +-#define PT_A3 10 +-#define PT_A4 11 +-#define PT_A5 12 +-#define PT_A6 13 +-#define PT_D0 14 +-#define PT_USP 15 +-#define PT_ORIG_D0 16 +-#define PT_SR 17 +-#define PT_PC 18 +- +-#ifndef __ASSEMBLY__ +- +-/* this struct defines the way the registers are stored on the +- stack during a system call. */ +- +-struct pt_regs { +- long d1; +- long d2; +- long d3; +- long d4; +- long d5; +- long a0; +- long a1; +- long a2; +- long d0; +- long orig_d0; +- long stkadj; +-#ifdef CONFIG_COLDFIRE +- unsigned format : 4; /* frame format specifier */ +- unsigned vector : 12; /* vector offset */ +- unsigned short sr; +- unsigned long pc; ++#ifdef __uClinux__ ++#include "ptrace_no.h" + #else +- unsigned short sr; +- unsigned long pc; +- unsigned format : 4; /* frame format specifier */ +- unsigned vector : 12; /* vector offset */ ++#include "ptrace_mm.h" + #endif +-}; +- +-/* +- * This is the extended stack used by signal handlers and the context +- * switcher: it's pushed after the normal "struct pt_regs". +- */ +-struct switch_stack { +- unsigned long d6; +- unsigned long d7; +- unsigned long a3; +- unsigned long a4; +- unsigned long a5; +- unsigned long a6; +- unsigned long retpc; +-}; +- +-/* Arbitrarily choose the same ptrace numbers as used by the Sparc code. */ +-#define PTRACE_GETREGS 12 +-#define PTRACE_SETREGS 13 +-#define PTRACE_GETFPREGS 14 +-#define PTRACE_SETFPREGS 15 +- +-#ifdef __KERNEL__ +- +-#ifndef PS_S +-#define PS_S (0x2000) +-#define PS_M (0x1000) +-#endif +- +-#define user_mode(regs) (!((regs)->sr & PS_S)) +-#define instruction_pointer(regs) ((regs)->pc) +-#define profile_pc(regs) instruction_pointer(regs) +-extern void show_regs(struct pt_regs *); +-#endif /* __KERNEL__ */ +-#endif /* __ASSEMBLY__ */ +-#endif /* _M68K_PTRACE_H */ +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/arch/m68k/include/asm/ptrace_mm.h linux-2.6.29-rc3.owrt/arch/m68k/include/asm/ptrace_mm.h +--- linux-2.6.29.owrt/arch/m68k/include/asm/ptrace_mm.h 1970-01-01 01:00:00.000000000 +0100 ++++ linux-2.6.29-rc3.owrt/arch/m68k/include/asm/ptrace_mm.h 2009-05-10 23:48:28.000000000 +0200 +@@ -0,0 +1,80 @@ ++#ifndef _M68K_PTRACE_H ++#define _M68K_PTRACE_H ++ ++#define PT_D1 0 ++#define PT_D2 1 ++#define PT_D3 2 ++#define PT_D4 3 ++#define PT_D5 4 ++#define PT_D6 5 ++#define PT_D7 6 ++#define PT_A0 7 ++#define PT_A1 8 ++#define PT_A2 9 ++#define PT_A3 10 ++#define PT_A4 11 ++#define PT_A5 12 ++#define PT_A6 13 ++#define PT_D0 14 ++#define PT_USP 15 ++#define PT_ORIG_D0 16 ++#define PT_SR 17 ++#define PT_PC 18 ++ ++#ifndef __ASSEMBLY__ ++ ++/* this struct defines the way the registers are stored on the ++ stack during a system call. */ ++ ++struct pt_regs { ++ long d1; ++ long d2; ++ long d3; ++ long d4; ++ long d5; ++ long a0; ++ long a1; ++ long a2; ++ long d0; ++ long orig_d0; ++ long stkadj; ++ unsigned short sr; ++ unsigned long pc; ++ unsigned format : 4; /* frame format specifier */ ++ unsigned vector : 12; /* vector offset */ ++}; ++ ++/* ++ * This is the extended stack used by signal handlers and the context ++ * switcher: it's pushed after the normal "struct pt_regs". ++ */ ++struct switch_stack { ++ unsigned long d6; ++ unsigned long d7; ++ unsigned long a3; ++ unsigned long a4; ++ unsigned long a5; ++ unsigned long a6; ++ unsigned long retpc; ++}; ++ ++/* Arbitrarily choose the same ptrace numbers as used by the Sparc code. */ ++#define PTRACE_GETREGS 12 ++#define PTRACE_SETREGS 13 ++#define PTRACE_GETFPREGS 14 ++#define PTRACE_SETFPREGS 15 ++ ++#ifdef __KERNEL__ ++ ++#ifndef PS_S ++#define PS_S (0x2000) ++#define PS_M (0x1000) ++#endif ++ ++#define user_mode(regs) (!((regs)->sr & PS_S)) ++#define instruction_pointer(regs) ((regs)->pc) ++#define profile_pc(regs) instruction_pointer(regs) ++extern void show_regs(struct pt_regs *); ++#endif /* __KERNEL__ */ ++#endif /* __ASSEMBLY__ */ ++#endif /* _M68K_PTRACE_H */ +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/arch/m68k/include/asm/ptrace_no.h linux-2.6.29-rc3.owrt/arch/m68k/include/asm/ptrace_no.h +--- linux-2.6.29.owrt/arch/m68k/include/asm/ptrace_no.h 1970-01-01 01:00:00.000000000 +0100 ++++ linux-2.6.29-rc3.owrt/arch/m68k/include/asm/ptrace_no.h 2009-05-10 23:48:28.000000000 +0200 +@@ -0,0 +1,87 @@ ++#ifndef _M68K_PTRACE_H ++#define _M68K_PTRACE_H ++ ++#define PT_D1 0 ++#define PT_D2 1 ++#define PT_D3 2 ++#define PT_D4 3 ++#define PT_D5 4 ++#define PT_D6 5 ++#define PT_D7 6 ++#define PT_A0 7 ++#define PT_A1 8 ++#define PT_A2 9 ++#define PT_A3 10 ++#define PT_A4 11 ++#define PT_A5 12 ++#define PT_A6 13 ++#define PT_D0 14 ++#define PT_USP 15 ++#define PT_ORIG_D0 16 ++#define PT_SR 17 ++#define PT_PC 18 ++ ++#ifndef __ASSEMBLY__ ++ ++/* this struct defines the way the registers are stored on the ++ stack during a system call. */ ++ ++struct pt_regs { ++ long d1; ++ long d2; ++ long d3; ++ long d4; ++ long d5; ++ long a0; ++ long a1; ++ long a2; ++ long d0; ++ long orig_d0; ++ long stkadj; ++#ifdef CONFIG_COLDFIRE ++ unsigned format : 4; /* frame format specifier */ ++ unsigned vector : 12; /* vector offset */ ++ unsigned short sr; ++ unsigned long pc; ++#else ++ unsigned short sr; ++ unsigned long pc; ++ unsigned format : 4; /* frame format specifier */ ++ unsigned vector : 12; /* vector offset */ ++#endif ++}; ++ ++/* ++ * This is the extended stack used by signal handlers and the context ++ * switcher: it's pushed after the normal "struct pt_regs". ++ */ ++struct switch_stack { ++ unsigned long d6; ++ unsigned long d7; ++ unsigned long a3; ++ unsigned long a4; ++ unsigned long a5; ++ unsigned long a6; ++ unsigned long retpc; ++}; ++ ++/* Arbitrarily choose the same ptrace numbers as used by the Sparc code. */ ++#define PTRACE_GETREGS 12 ++#define PTRACE_SETREGS 13 ++#define PTRACE_GETFPREGS 14 ++#define PTRACE_SETFPREGS 15 ++ ++#ifdef __KERNEL__ ++ ++#ifndef PS_S ++#define PS_S (0x2000) ++#define PS_M (0x1000) ++#endif ++ ++#define user_mode(regs) (!((regs)->sr & PS_S)) ++#define instruction_pointer(regs) ((regs)->pc) ++#define profile_pc(regs) instruction_pointer(regs) ++extern void show_regs(struct pt_regs *); ++#endif /* __KERNEL__ */ ++#endif /* __ASSEMBLY__ */ ++#endif /* _M68K_PTRACE_H */ +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/arch/m68k/include/asm/setup.h linux-2.6.29-rc3.owrt/arch/m68k/include/asm/setup.h +--- linux-2.6.29.owrt/arch/m68k/include/asm/setup.h 2009-05-10 22:04:40.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/arch/m68k/include/asm/setup.h 2009-05-10 23:48:28.000000000 +0200 +@@ -1,376 +1,5 @@ +-/* +-** asm/setup.h -- Definition of the Linux/m68k setup information +-** +-** Copyright 1992 by Greg Harp +-** +-** This file is subject to the terms and conditions of the GNU General Public +-** License. See the file COPYING in the main directory of this archive +-** for more details. +-** +-** Created 09/29/92 by Greg Harp +-** +-** 5/2/94 Roman Hodek: +-** Added bi_atari part of the machine dependent union bi_un; for now it +-** contains just a model field to distinguish between TT and Falcon. +-** 26/7/96 Roman Zippel: +-** Renamed to setup.h; added some useful macros to allow gcc some +-** optimizations if possible. +-** 5/10/96 Geert Uytterhoeven: +-** Redesign of the boot information structure; moved boot information +-** structure to bootinfo.h +-*/ +- +-#ifndef _M68K_SETUP_H +-#define _M68K_SETUP_H +- +- +- +- /* +- * Linux/m68k Architectures +- */ +- +-#define MACH_AMIGA 1 +-#define MACH_ATARI 2 +-#define MACH_MAC 3 +-#define MACH_APOLLO 4 +-#define MACH_SUN3 5 +-#define MACH_MVME147 6 +-#define MACH_MVME16x 7 +-#define MACH_BVME6000 8 +-#define MACH_HP300 9 +-#define MACH_Q40 10 +-#define MACH_SUN3X 11 +- +-#define COMMAND_LINE_SIZE 256 +- +-#ifdef __KERNEL__ +- +-#define CL_SIZE COMMAND_LINE_SIZE +- +-#ifndef __ASSEMBLY__ +-extern unsigned long m68k_machtype; +-#endif /* !__ASSEMBLY__ */ +- +-#if !defined(CONFIG_AMIGA) +-# define MACH_IS_AMIGA (0) +-#elif defined(CONFIG_ATARI) || defined(CONFIG_MAC) || defined(CONFIG_APOLLO) \ +- || defined(CONFIG_MVME16x) || defined(CONFIG_BVME6000) \ +- || defined(CONFIG_HP300) || defined(CONFIG_Q40) \ +- || defined(CONFIG_SUN3X) || defined(CONFIG_MVME147) +-# define MACH_IS_AMIGA (m68k_machtype == MACH_AMIGA) ++#ifdef __uClinux__ ++#include "setup_no.h" + #else +-# define MACH_AMIGA_ONLY +-# define MACH_IS_AMIGA (1) +-# define MACH_TYPE (MACH_AMIGA) ++#include "setup_mm.h" + #endif +- +-#if !defined(CONFIG_ATARI) +-# define MACH_IS_ATARI (0) +-#elif defined(CONFIG_AMIGA) || defined(CONFIG_MAC) || defined(CONFIG_APOLLO) \ +- || defined(CONFIG_MVME16x) || defined(CONFIG_BVME6000) \ +- || defined(CONFIG_HP300) || defined(CONFIG_Q40) \ +- || defined(CONFIG_SUN3X) || defined(CONFIG_MVME147) +-# define MACH_IS_ATARI (m68k_machtype == MACH_ATARI) +-#else +-# define MACH_ATARI_ONLY +-# define MACH_IS_ATARI (1) +-# define MACH_TYPE (MACH_ATARI) +-#endif +- +-#if !defined(CONFIG_MAC) +-# define MACH_IS_MAC (0) +-#elif defined(CONFIG_AMIGA) || defined(CONFIG_ATARI) || defined(CONFIG_APOLLO) \ +- || defined(CONFIG_MVME16x) || defined(CONFIG_BVME6000) \ +- || defined(CONFIG_HP300) || defined(CONFIG_Q40) \ +- || defined(CONFIG_SUN3X) || defined(CONFIG_MVME147) +-# define MACH_IS_MAC (m68k_machtype == MACH_MAC) +-#else +-# define MACH_MAC_ONLY +-# define MACH_IS_MAC (1) +-# define MACH_TYPE (MACH_MAC) +-#endif +- +-#if defined(CONFIG_SUN3) +-#define MACH_IS_SUN3 (1) +-#define MACH_SUN3_ONLY (1) +-#define MACH_TYPE (MACH_SUN3) +-#else +-#define MACH_IS_SUN3 (0) +-#endif +- +-#if !defined (CONFIG_APOLLO) +-# define MACH_IS_APOLLO (0) +-#elif defined(CONFIG_AMIGA) || defined(CONFIG_MAC) || defined(CONFIG_ATARI) \ +- || defined(CONFIG_MVME16x) || defined(CONFIG_BVME6000) \ +- || defined(CONFIG_HP300) || defined(CONFIG_Q40) \ +- || defined(CONFIG_SUN3X) || defined(CONFIG_MVME147) +-# define MACH_IS_APOLLO (m68k_machtype == MACH_APOLLO) +-#else +-# define MACH_APOLLO_ONLY +-# define MACH_IS_APOLLO (1) +-# define MACH_TYPE (MACH_APOLLO) +-#endif +- +-#if !defined (CONFIG_MVME147) +-# define MACH_IS_MVME147 (0) +-#elif defined(CONFIG_AMIGA) || defined(CONFIG_MAC) || defined(CONFIG_ATARI) \ +- || defined(CONFIG_APOLLO) || defined(CONFIG_BVME6000) \ +- || defined(CONFIG_HP300) || defined(CONFIG_Q40) \ +- || defined(CONFIG_SUN3X) || defined(CONFIG_MVME16x) +-# define MACH_IS_MVME147 (m68k_machtype == MACH_MVME147) +-#else +-# define MACH_MVME147_ONLY +-# define MACH_IS_MVME147 (1) +-# define MACH_TYPE (MACH_MVME147) +-#endif +- +-#if !defined (CONFIG_MVME16x) +-# define MACH_IS_MVME16x (0) +-#elif defined(CONFIG_AMIGA) || defined(CONFIG_MAC) || defined(CONFIG_ATARI) \ +- || defined(CONFIG_APOLLO) || defined(CONFIG_BVME6000) \ +- || defined(CONFIG_HP300) || defined(CONFIG_Q40) \ +- || defined(CONFIG_SUN3X) || defined(CONFIG_MVME147) +-# define MACH_IS_MVME16x (m68k_machtype == MACH_MVME16x) +-#else +-# define MACH_MVME16x_ONLY +-# define MACH_IS_MVME16x (1) +-# define MACH_TYPE (MACH_MVME16x) +-#endif +- +-#if !defined (CONFIG_BVME6000) +-# define MACH_IS_BVME6000 (0) +-#elif defined(CONFIG_AMIGA) || defined(CONFIG_MAC) || defined(CONFIG_ATARI) \ +- || defined(CONFIG_APOLLO) || defined(CONFIG_MVME16x) \ +- || defined(CONFIG_HP300) || defined(CONFIG_Q40) \ +- || defined(CONFIG_SUN3X) || defined(CONFIG_MVME147) +-# define MACH_IS_BVME6000 (m68k_machtype == MACH_BVME6000) +-#else +-# define MACH_BVME6000_ONLY +-# define MACH_IS_BVME6000 (1) +-# define MACH_TYPE (MACH_BVME6000) +-#endif +- +-#if !defined (CONFIG_HP300) +-# define MACH_IS_HP300 (0) +-#elif defined(CONFIG_AMIGA) || defined(CONFIG_MAC) || defined(CONFIG_ATARI) \ +- || defined(CONFIG_APOLLO) || defined(CONFIG_MVME16x) \ +- || defined(CONFIG_BVME6000) || defined(CONFIG_Q40) \ +- || defined(CONFIG_SUN3X) || defined(CONFIG_MVME147) +-# define MACH_IS_HP300 (m68k_machtype == MACH_HP300) +-#else +-# define MACH_HP300_ONLY +-# define MACH_IS_HP300 (1) +-# define MACH_TYPE (MACH_HP300) +-#endif +- +-#if !defined (CONFIG_Q40) +-# define MACH_IS_Q40 (0) +-#elif defined(CONFIG_AMIGA) || defined(CONFIG_MAC) || defined(CONFIG_ATARI) \ +- || defined(CONFIG_APOLLO) || defined(CONFIG_MVME16x) \ +- || defined(CONFIG_BVME6000) || defined(CONFIG_HP300) \ +- || defined(CONFIG_SUN3X) || defined(CONFIG_MVME147) +-# define MACH_IS_Q40 (m68k_machtype == MACH_Q40) +-#else +-# define MACH_Q40_ONLY +-# define MACH_IS_Q40 (1) +-# define MACH_TYPE (MACH_Q40) +-#endif +- +-#if !defined (CONFIG_SUN3X) +-# define MACH_IS_SUN3X (0) +-#elif defined(CONFIG_AMIGA) || defined(CONFIG_MAC) || defined(CONFIG_ATARI) \ +- || defined(CONFIG_APOLLO) || defined(CONFIG_MVME16x) \ +- || defined(CONFIG_BVME6000) || defined(CONFIG_HP300) \ +- || defined(CONFIG_Q40) || defined(CONFIG_MVME147) +-# define MACH_IS_SUN3X (m68k_machtype == MACH_SUN3X) +-#else +-# define CONFIG_SUN3X_ONLY +-# define MACH_IS_SUN3X (1) +-# define MACH_TYPE (MACH_SUN3X) +-#endif +- +-#ifndef MACH_TYPE +-# define MACH_TYPE (m68k_machtype) +-#endif +- +-#endif /* __KERNEL__ */ +- +- +- /* +- * CPU, FPU and MMU types +- * +- * Note: we may rely on the following equalities: +- * +- * CPU_68020 == MMU_68851 +- * CPU_68030 == MMU_68030 +- * CPU_68040 == FPU_68040 == MMU_68040 +- * CPU_68060 == FPU_68060 == MMU_68060 +- */ +- +-#define CPUB_68020 0 +-#define CPUB_68030 1 +-#define CPUB_68040 2 +-#define CPUB_68060 3 +- +-#define CPU_68020 (1<<CPUB_68020) +-#define CPU_68030 (1<<CPUB_68030) +-#define CPU_68040 (1<<CPUB_68040) +-#define CPU_68060 (1<<CPUB_68060) +- +-#define FPUB_68881 0 +-#define FPUB_68882 1 +-#define FPUB_68040 2 /* Internal FPU */ +-#define FPUB_68060 3 /* Internal FPU */ +-#define FPUB_SUNFPA 4 /* Sun-3 FPA */ +- +-#define FPU_68881 (1<<FPUB_68881) +-#define FPU_68882 (1<<FPUB_68882) +-#define FPU_68040 (1<<FPUB_68040) +-#define FPU_68060 (1<<FPUB_68060) +-#define FPU_SUNFPA (1<<FPUB_SUNFPA) +- +-#define MMUB_68851 0 +-#define MMUB_68030 1 /* Internal MMU */ +-#define MMUB_68040 2 /* Internal MMU */ +-#define MMUB_68060 3 /* Internal MMU */ +-#define MMUB_APOLLO 4 /* Custom Apollo */ +-#define MMUB_SUN3 5 /* Custom Sun-3 */ +- +-#define MMU_68851 (1<<MMUB_68851) +-#define MMU_68030 (1<<MMUB_68030) +-#define MMU_68040 (1<<MMUB_68040) +-#define MMU_68060 (1<<MMUB_68060) +-#define MMU_SUN3 (1<<MMUB_SUN3) +-#define MMU_APOLLO (1<<MMUB_APOLLO) +- +-#ifdef __KERNEL__ +- +-#ifndef __ASSEMBLY__ +-extern unsigned long m68k_cputype; +-extern unsigned long m68k_fputype; +-extern unsigned long m68k_mmutype; +-#ifdef CONFIG_VME +-extern unsigned long vme_brdtype; +-#endif +- +- /* +- * m68k_is040or060 is != 0 for a '040 or higher; +- * used numbers are 4 for 68040 and 6 for 68060. +- */ +- +-extern int m68k_is040or060; +-#endif /* !__ASSEMBLY__ */ +- +-#if !defined(CONFIG_M68020) +-# define CPU_IS_020 (0) +-# define MMU_IS_851 (0) +-# define MMU_IS_SUN3 (0) +-#elif defined(CONFIG_M68030) || defined(CONFIG_M68040) || defined(CONFIG_M68060) +-# define CPU_IS_020 (m68k_cputype & CPU_68020) +-# define MMU_IS_851 (m68k_mmutype & MMU_68851) +-# define MMU_IS_SUN3 (0) /* Sun3 not supported with other CPU enabled */ +-#else +-# define CPU_M68020_ONLY +-# define CPU_IS_020 (1) +-#ifdef MACH_SUN3_ONLY +-# define MMU_IS_SUN3 (1) +-# define MMU_IS_851 (0) +-#else +-# define MMU_IS_SUN3 (0) +-# define MMU_IS_851 (1) +-#endif +-#endif +- +-#if !defined(CONFIG_M68030) +-# define CPU_IS_030 (0) +-# define MMU_IS_030 (0) +-#elif defined(CONFIG_M68020) || defined(CONFIG_M68040) || defined(CONFIG_M68060) +-# define CPU_IS_030 (m68k_cputype & CPU_68030) +-# define MMU_IS_030 (m68k_mmutype & MMU_68030) +-#else +-# define CPU_M68030_ONLY +-# define CPU_IS_030 (1) +-# define MMU_IS_030 (1) +-#endif +- +-#if !defined(CONFIG_M68040) +-# define CPU_IS_040 (0) +-# define MMU_IS_040 (0) +-#elif defined(CONFIG_M68020) || defined(CONFIG_M68030) || defined(CONFIG_M68060) +-# define CPU_IS_040 (m68k_cputype & CPU_68040) +-# define MMU_IS_040 (m68k_mmutype & MMU_68040) +-#else +-# define CPU_M68040_ONLY +-# define CPU_IS_040 (1) +-# define MMU_IS_040 (1) +-#endif +- +-#if !defined(CONFIG_M68060) +-# define CPU_IS_060 (0) +-# define MMU_IS_060 (0) +-#elif defined(CONFIG_M68020) || defined(CONFIG_M68030) || defined(CONFIG_M68040) +-# define CPU_IS_060 (m68k_cputype & CPU_68060) +-# define MMU_IS_060 (m68k_mmutype & MMU_68060) +-#else +-# define CPU_M68060_ONLY +-# define CPU_IS_060 (1) +-# define MMU_IS_060 (1) +-#endif +- +-#if !defined(CONFIG_M68020) && !defined(CONFIG_M68030) +-# define CPU_IS_020_OR_030 (0) +-#else +-# define CPU_M68020_OR_M68030 +-# if defined(CONFIG_M68040) || defined(CONFIG_M68060) +-# define CPU_IS_020_OR_030 (!m68k_is040or060) +-# else +-# define CPU_M68020_OR_M68030_ONLY +-# define CPU_IS_020_OR_030 (1) +-# endif +-#endif +- +-#if !defined(CONFIG_M68040) && !defined(CONFIG_M68060) +-# define CPU_IS_040_OR_060 (0) +-#else +-# define CPU_M68040_OR_M68060 +-# if defined(CONFIG_M68020) || defined(CONFIG_M68030) +-# define CPU_IS_040_OR_060 (m68k_is040or060) +-# else +-# define CPU_M68040_OR_M68060_ONLY +-# define CPU_IS_040_OR_060 (1) +-# endif +-#endif +- +-#define CPU_TYPE (m68k_cputype) +- +-#ifdef CONFIG_M68KFPU_EMU +-# ifdef CONFIG_M68KFPU_EMU_ONLY +-# define FPU_IS_EMU (1) +-# else +-# define FPU_IS_EMU (!m68k_fputype) +-# endif +-#else +-# define FPU_IS_EMU (0) +-#endif +- +- +- /* +- * Miscellaneous +- */ +- +-#define NUM_MEMINFO 4 +- +-#ifndef __ASSEMBLY__ +-struct mem_info { +- unsigned long addr; /* physical address of memory chunk */ +- unsigned long size; /* length of memory chunk (in bytes) */ +-}; +- +-extern int m68k_num_memory; /* # of memory blocks found (and used) */ +-extern int m68k_realnum_memory; /* real # of memory blocks found */ +-extern struct mem_info m68k_memory[NUM_MEMINFO];/* memory description */ +-#endif +- +-#endif /* __KERNEL__ */ +- +-#endif /* _M68K_SETUP_H */ +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/arch/m68k/include/asm/setup_mm.h linux-2.6.29-rc3.owrt/arch/m68k/include/asm/setup_mm.h +--- linux-2.6.29.owrt/arch/m68k/include/asm/setup_mm.h 1970-01-01 01:00:00.000000000 +0100 ++++ linux-2.6.29-rc3.owrt/arch/m68k/include/asm/setup_mm.h 2009-05-10 23:48:28.000000000 +0200 +@@ -0,0 +1,376 @@ ++/* ++** asm/setup.h -- Definition of the Linux/m68k setup information ++** ++** Copyright 1992 by Greg Harp ++** ++** This file is subject to the terms and conditions of the GNU General Public ++** License. See the file COPYING in the main directory of this archive ++** for more details. ++** ++** Created 09/29/92 by Greg Harp ++** ++** 5/2/94 Roman Hodek: ++** Added bi_atari part of the machine dependent union bi_un; for now it ++** contains just a model field to distinguish between TT and Falcon. ++** 26/7/96 Roman Zippel: ++** Renamed to setup.h; added some useful macros to allow gcc some ++** optimizations if possible. ++** 5/10/96 Geert Uytterhoeven: ++** Redesign of the boot information structure; moved boot information ++** structure to bootinfo.h ++*/ ++ ++#ifndef _M68K_SETUP_H ++#define _M68K_SETUP_H ++ ++ ++ ++ /* ++ * Linux/m68k Architectures ++ */ ++ ++#define MACH_AMIGA 1 ++#define MACH_ATARI 2 ++#define MACH_MAC 3 ++#define MACH_APOLLO 4 ++#define MACH_SUN3 5 ++#define MACH_MVME147 6 ++#define MACH_MVME16x 7 ++#define MACH_BVME6000 8 ++#define MACH_HP300 9 ++#define MACH_Q40 10 ++#define MACH_SUN3X 11 ++ ++#define COMMAND_LINE_SIZE 256 ++ ++#ifdef __KERNEL__ ++ ++#define CL_SIZE COMMAND_LINE_SIZE ++ ++#ifndef __ASSEMBLY__ ++extern unsigned long m68k_machtype; ++#endif /* !__ASSEMBLY__ */ ++ ++#if !defined(CONFIG_AMIGA) ++# define MACH_IS_AMIGA (0) ++#elif defined(CONFIG_ATARI) || defined(CONFIG_MAC) || defined(CONFIG_APOLLO) \ ++ || defined(CONFIG_MVME16x) || defined(CONFIG_BVME6000) \ ++ || defined(CONFIG_HP300) || defined(CONFIG_Q40) \ ++ || defined(CONFIG_SUN3X) || defined(CONFIG_MVME147) ++# define MACH_IS_AMIGA (m68k_machtype == MACH_AMIGA) ++#else ++# define MACH_AMIGA_ONLY ++# define MACH_IS_AMIGA (1) ++# define MACH_TYPE (MACH_AMIGA) ++#endif ++ ++#if !defined(CONFIG_ATARI) ++# define MACH_IS_ATARI (0) ++#elif defined(CONFIG_AMIGA) || defined(CONFIG_MAC) || defined(CONFIG_APOLLO) \ ++ || defined(CONFIG_MVME16x) || defined(CONFIG_BVME6000) \ ++ || defined(CONFIG_HP300) || defined(CONFIG_Q40) \ ++ || defined(CONFIG_SUN3X) || defined(CONFIG_MVME147) ++# define MACH_IS_ATARI (m68k_machtype == MACH_ATARI) ++#else ++# define MACH_ATARI_ONLY ++# define MACH_IS_ATARI (1) ++# define MACH_TYPE (MACH_ATARI) ++#endif ++ ++#if !defined(CONFIG_MAC) ++# define MACH_IS_MAC (0) ++#elif defined(CONFIG_AMIGA) || defined(CONFIG_ATARI) || defined(CONFIG_APOLLO) \ ++ || defined(CONFIG_MVME16x) || defined(CONFIG_BVME6000) \ ++ || defined(CONFIG_HP300) || defined(CONFIG_Q40) \ ++ || defined(CONFIG_SUN3X) || defined(CONFIG_MVME147) ++# define MACH_IS_MAC (m68k_machtype == MACH_MAC) ++#else ++# define MACH_MAC_ONLY ++# define MACH_IS_MAC (1) ++# define MACH_TYPE (MACH_MAC) ++#endif ++ ++#if defined(CONFIG_SUN3) ++#define MACH_IS_SUN3 (1) ++#define MACH_SUN3_ONLY (1) ++#define MACH_TYPE (MACH_SUN3) ++#else ++#define MACH_IS_SUN3 (0) ++#endif ++ ++#if !defined (CONFIG_APOLLO) ++# define MACH_IS_APOLLO (0) ++#elif defined(CONFIG_AMIGA) || defined(CONFIG_MAC) || defined(CONFIG_ATARI) \ ++ || defined(CONFIG_MVME16x) || defined(CONFIG_BVME6000) \ ++ || defined(CONFIG_HP300) || defined(CONFIG_Q40) \ ++ || defined(CONFIG_SUN3X) || defined(CONFIG_MVME147) ++# define MACH_IS_APOLLO (m68k_machtype == MACH_APOLLO) ++#else ++# define MACH_APOLLO_ONLY ++# define MACH_IS_APOLLO (1) ++# define MACH_TYPE (MACH_APOLLO) ++#endif ++ ++#if !defined (CONFIG_MVME147) ++# define MACH_IS_MVME147 (0) ++#elif defined(CONFIG_AMIGA) || defined(CONFIG_MAC) || defined(CONFIG_ATARI) \ ++ || defined(CONFIG_APOLLO) || defined(CONFIG_BVME6000) \ ++ || defined(CONFIG_HP300) || defined(CONFIG_Q40) \ ++ || defined(CONFIG_SUN3X) || defined(CONFIG_MVME16x) ++# define MACH_IS_MVME147 (m68k_machtype == MACH_MVME147) ++#else ++# define MACH_MVME147_ONLY ++# define MACH_IS_MVME147 (1) ++# define MACH_TYPE (MACH_MVME147) ++#endif ++ ++#if !defined (CONFIG_MVME16x) ++# define MACH_IS_MVME16x (0) ++#elif defined(CONFIG_AMIGA) || defined(CONFIG_MAC) || defined(CONFIG_ATARI) \ ++ || defined(CONFIG_APOLLO) || defined(CONFIG_BVME6000) \ ++ || defined(CONFIG_HP300) || defined(CONFIG_Q40) \ ++ || defined(CONFIG_SUN3X) || defined(CONFIG_MVME147) ++# define MACH_IS_MVME16x (m68k_machtype == MACH_MVME16x) ++#else ++# define MACH_MVME16x_ONLY ++# define MACH_IS_MVME16x (1) ++# define MACH_TYPE (MACH_MVME16x) ++#endif ++ ++#if !defined (CONFIG_BVME6000) ++# define MACH_IS_BVME6000 (0) ++#elif defined(CONFIG_AMIGA) || defined(CONFIG_MAC) || defined(CONFIG_ATARI) \ ++ || defined(CONFIG_APOLLO) || defined(CONFIG_MVME16x) \ ++ || defined(CONFIG_HP300) || defined(CONFIG_Q40) \ ++ || defined(CONFIG_SUN3X) || defined(CONFIG_MVME147) ++# define MACH_IS_BVME6000 (m68k_machtype == MACH_BVME6000) ++#else ++# define MACH_BVME6000_ONLY ++# define MACH_IS_BVME6000 (1) ++# define MACH_TYPE (MACH_BVME6000) ++#endif ++ ++#if !defined (CONFIG_HP300) ++# define MACH_IS_HP300 (0) ++#elif defined(CONFIG_AMIGA) || defined(CONFIG_MAC) || defined(CONFIG_ATARI) \ ++ || defined(CONFIG_APOLLO) || defined(CONFIG_MVME16x) \ ++ || defined(CONFIG_BVME6000) || defined(CONFIG_Q40) \ ++ || defined(CONFIG_SUN3X) || defined(CONFIG_MVME147) ++# define MACH_IS_HP300 (m68k_machtype == MACH_HP300) ++#else ++# define MACH_HP300_ONLY ++# define MACH_IS_HP300 (1) ++# define MACH_TYPE (MACH_HP300) ++#endif ++ ++#if !defined (CONFIG_Q40) ++# define MACH_IS_Q40 (0) ++#elif defined(CONFIG_AMIGA) || defined(CONFIG_MAC) || defined(CONFIG_ATARI) \ ++ || defined(CONFIG_APOLLO) || defined(CONFIG_MVME16x) \ ++ || defined(CONFIG_BVME6000) || defined(CONFIG_HP300) \ ++ || defined(CONFIG_SUN3X) || defined(CONFIG_MVME147) ++# define MACH_IS_Q40 (m68k_machtype == MACH_Q40) ++#else ++# define MACH_Q40_ONLY ++# define MACH_IS_Q40 (1) ++# define MACH_TYPE (MACH_Q40) ++#endif ++ ++#if !defined (CONFIG_SUN3X) ++# define MACH_IS_SUN3X (0) ++#elif defined(CONFIG_AMIGA) || defined(CONFIG_MAC) || defined(CONFIG_ATARI) \ ++ || defined(CONFIG_APOLLO) || defined(CONFIG_MVME16x) \ ++ || defined(CONFIG_BVME6000) || defined(CONFIG_HP300) \ ++ || defined(CONFIG_Q40) || defined(CONFIG_MVME147) ++# define MACH_IS_SUN3X (m68k_machtype == MACH_SUN3X) ++#else ++# define CONFIG_SUN3X_ONLY ++# define MACH_IS_SUN3X (1) ++# define MACH_TYPE (MACH_SUN3X) ++#endif ++ ++#ifndef MACH_TYPE ++# define MACH_TYPE (m68k_machtype) ++#endif ++ ++#endif /* __KERNEL__ */ ++ ++ ++ /* ++ * CPU, FPU and MMU types ++ * ++ * Note: we may rely on the following equalities: ++ * ++ * CPU_68020 == MMU_68851 ++ * CPU_68030 == MMU_68030 ++ * CPU_68040 == FPU_68040 == MMU_68040 ++ * CPU_68060 == FPU_68060 == MMU_68060 ++ */ ++ ++#define CPUB_68020 0 ++#define CPUB_68030 1 ++#define CPUB_68040 2 ++#define CPUB_68060 3 ++ ++#define CPU_68020 (1<<CPUB_68020) ++#define CPU_68030 (1<<CPUB_68030) ++#define CPU_68040 (1<<CPUB_68040) ++#define CPU_68060 (1<<CPUB_68060) ++ ++#define FPUB_68881 0 ++#define FPUB_68882 1 ++#define FPUB_68040 2 /* Internal FPU */ ++#define FPUB_68060 3 /* Internal FPU */ ++#define FPUB_SUNFPA 4 /* Sun-3 FPA */ ++ ++#define FPU_68881 (1<<FPUB_68881) ++#define FPU_68882 (1<<FPUB_68882) ++#define FPU_68040 (1<<FPUB_68040) ++#define FPU_68060 (1<<FPUB_68060) ++#define FPU_SUNFPA (1<<FPUB_SUNFPA) ++ ++#define MMUB_68851 0 ++#define MMUB_68030 1 /* Internal MMU */ ++#define MMUB_68040 2 /* Internal MMU */ ++#define MMUB_68060 3 /* Internal MMU */ ++#define MMUB_APOLLO 4 /* Custom Apollo */ ++#define MMUB_SUN3 5 /* Custom Sun-3 */ ++ ++#define MMU_68851 (1<<MMUB_68851) ++#define MMU_68030 (1<<MMUB_68030) ++#define MMU_68040 (1<<MMUB_68040) ++#define MMU_68060 (1<<MMUB_68060) ++#define MMU_SUN3 (1<<MMUB_SUN3) ++#define MMU_APOLLO (1<<MMUB_APOLLO) ++ ++#ifdef __KERNEL__ ++ ++#ifndef __ASSEMBLY__ ++extern unsigned long m68k_cputype; ++extern unsigned long m68k_fputype; ++extern unsigned long m68k_mmutype; ++#ifdef CONFIG_VME ++extern unsigned long vme_brdtype; ++#endif ++ ++ /* ++ * m68k_is040or060 is != 0 for a '040 or higher; ++ * used numbers are 4 for 68040 and 6 for 68060. ++ */ ++ ++extern int m68k_is040or060; ++#endif /* !__ASSEMBLY__ */ ++ ++#if !defined(CONFIG_M68020) ++# define CPU_IS_020 (0) ++# define MMU_IS_851 (0) ++# define MMU_IS_SUN3 (0) ++#elif defined(CONFIG_M68030) || defined(CONFIG_M68040) || defined(CONFIG_M68060) ++# define CPU_IS_020 (m68k_cputype & CPU_68020) ++# define MMU_IS_851 (m68k_mmutype & MMU_68851) ++# define MMU_IS_SUN3 (0) /* Sun3 not supported with other CPU enabled */ ++#else ++# define CPU_M68020_ONLY ++# define CPU_IS_020 (1) ++#ifdef MACH_SUN3_ONLY ++# define MMU_IS_SUN3 (1) ++# define MMU_IS_851 (0) ++#else ++# define MMU_IS_SUN3 (0) ++# define MMU_IS_851 (1) ++#endif ++#endif ++ ++#if !defined(CONFIG_M68030) ++# define CPU_IS_030 (0) ++# define MMU_IS_030 (0) ++#elif defined(CONFIG_M68020) || defined(CONFIG_M68040) || defined(CONFIG_M68060) ++# define CPU_IS_030 (m68k_cputype & CPU_68030) ++# define MMU_IS_030 (m68k_mmutype & MMU_68030) ++#else ++# define CPU_M68030_ONLY ++# define CPU_IS_030 (1) ++# define MMU_IS_030 (1) ++#endif ++ ++#if !defined(CONFIG_M68040) ++# define CPU_IS_040 (0) ++# define MMU_IS_040 (0) ++#elif defined(CONFIG_M68020) || defined(CONFIG_M68030) || defined(CONFIG_M68060) ++# define CPU_IS_040 (m68k_cputype & CPU_68040) ++# define MMU_IS_040 (m68k_mmutype & MMU_68040) ++#else ++# define CPU_M68040_ONLY ++# define CPU_IS_040 (1) ++# define MMU_IS_040 (1) ++#endif ++ ++#if !defined(CONFIG_M68060) ++# define CPU_IS_060 (0) ++# define MMU_IS_060 (0) ++#elif defined(CONFIG_M68020) || defined(CONFIG_M68030) || defined(CONFIG_M68040) ++# define CPU_IS_060 (m68k_cputype & CPU_68060) ++# define MMU_IS_060 (m68k_mmutype & MMU_68060) ++#else ++# define CPU_M68060_ONLY ++# define CPU_IS_060 (1) ++# define MMU_IS_060 (1) ++#endif ++ ++#if !defined(CONFIG_M68020) && !defined(CONFIG_M68030) ++# define CPU_IS_020_OR_030 (0) ++#else ++# define CPU_M68020_OR_M68030 ++# if defined(CONFIG_M68040) || defined(CONFIG_M68060) ++# define CPU_IS_020_OR_030 (!m68k_is040or060) ++# else ++# define CPU_M68020_OR_M68030_ONLY ++# define CPU_IS_020_OR_030 (1) ++# endif ++#endif ++ ++#if !defined(CONFIG_M68040) && !defined(CONFIG_M68060) ++# define CPU_IS_040_OR_060 (0) ++#else ++# define CPU_M68040_OR_M68060 ++# if defined(CONFIG_M68020) || defined(CONFIG_M68030) ++# define CPU_IS_040_OR_060 (m68k_is040or060) ++# else ++# define CPU_M68040_OR_M68060_ONLY ++# define CPU_IS_040_OR_060 (1) ++# endif ++#endif ++ ++#define CPU_TYPE (m68k_cputype) ++ ++#ifdef CONFIG_M68KFPU_EMU ++# ifdef CONFIG_M68KFPU_EMU_ONLY ++# define FPU_IS_EMU (1) ++# else ++# define FPU_IS_EMU (!m68k_fputype) ++# endif ++#else ++# define FPU_IS_EMU (0) ++#endif ++ ++ ++ /* ++ * Miscellaneous ++ */ ++ ++#define NUM_MEMINFO 4 ++ ++#ifndef __ASSEMBLY__ ++struct mem_info { ++ unsigned long addr; /* physical address of memory chunk */ ++ unsigned long size; /* length of memory chunk (in bytes) */ ++}; ++ ++extern int m68k_num_memory; /* # of memory blocks found (and used) */ ++extern int m68k_realnum_memory; /* real # of memory blocks found */ ++extern struct mem_info m68k_memory[NUM_MEMINFO];/* memory description */ ++#endif ++ ++#endif /* __KERNEL__ */ ++ ++#endif /* _M68K_SETUP_H */ +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/arch/m68k/include/asm/setup_no.h linux-2.6.29-rc3.owrt/arch/m68k/include/asm/setup_no.h +--- linux-2.6.29.owrt/arch/m68k/include/asm/setup_no.h 1970-01-01 01:00:00.000000000 +0100 ++++ linux-2.6.29-rc3.owrt/arch/m68k/include/asm/setup_no.h 2009-05-10 23:48:28.000000000 +0200 +@@ -0,0 +1,10 @@ ++#ifdef __KERNEL__ ++ ++#include <asm/setup_mm.h> ++ ++/* We have a bigger command line buffer. */ ++#undef COMMAND_LINE_SIZE ++ ++#endif /* __KERNEL__ */ ++ ++#define COMMAND_LINE_SIZE 512 +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/arch/m68k/include/asm/sigcontext.h linux-2.6.29-rc3.owrt/arch/m68k/include/asm/sigcontext.h +--- linux-2.6.29.owrt/arch/m68k/include/asm/sigcontext.h 2009-05-10 22:04:40.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/arch/m68k/include/asm/sigcontext.h 2009-05-10 23:48:28.000000000 +0200 +@@ -1,24 +1,5 @@ +-#ifndef _ASM_M68k_SIGCONTEXT_H +-#define _ASM_M68k_SIGCONTEXT_H +- +-struct sigcontext { +- unsigned long sc_mask; /* old sigmask */ +- unsigned long sc_usp; /* old user stack pointer */ +- unsigned long sc_d0; +- unsigned long sc_d1; +- unsigned long sc_a0; +- unsigned long sc_a1; + #ifdef __uClinux__ +- unsigned long sc_a5; +-#endif +- unsigned short sc_sr; +- unsigned long sc_pc; +- unsigned short sc_formatvec; +-#ifndef __uClinux__ +- unsigned long sc_fpregs[2*3]; /* room for two fp registers */ +- unsigned long sc_fpcntl[3]; +- unsigned char sc_fpstate[216]; +-#endif +-}; +- ++#include "sigcontext_no.h" ++#else ++#include "sigcontext_mm.h" + #endif +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/arch/m68k/include/asm/sigcontext_mm.h linux-2.6.29-rc3.owrt/arch/m68k/include/asm/sigcontext_mm.h +--- linux-2.6.29.owrt/arch/m68k/include/asm/sigcontext_mm.h 1970-01-01 01:00:00.000000000 +0100 ++++ linux-2.6.29-rc3.owrt/arch/m68k/include/asm/sigcontext_mm.h 2009-05-10 23:48:28.000000000 +0200 +@@ -0,0 +1,19 @@ ++#ifndef _ASM_M68k_SIGCONTEXT_H ++#define _ASM_M68k_SIGCONTEXT_H ++ ++struct sigcontext { ++ unsigned long sc_mask; /* old sigmask */ ++ unsigned long sc_usp; /* old user stack pointer */ ++ unsigned long sc_d0; ++ unsigned long sc_d1; ++ unsigned long sc_a0; ++ unsigned long sc_a1; ++ unsigned short sc_sr; ++ unsigned long sc_pc; ++ unsigned short sc_formatvec; ++ unsigned long sc_fpregs[2*3]; /* room for two fp registers */ ++ unsigned long sc_fpcntl[3]; ++ unsigned char sc_fpstate[216]; ++}; ++ ++#endif +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/arch/m68k/include/asm/sigcontext_no.h linux-2.6.29-rc3.owrt/arch/m68k/include/asm/sigcontext_no.h +--- linux-2.6.29.owrt/arch/m68k/include/asm/sigcontext_no.h 1970-01-01 01:00:00.000000000 +0100 ++++ linux-2.6.29-rc3.owrt/arch/m68k/include/asm/sigcontext_no.h 2009-05-10 23:48:28.000000000 +0200 +@@ -0,0 +1,17 @@ ++#ifndef _ASM_M68KNOMMU_SIGCONTEXT_H ++#define _ASM_M68KNOMMU_SIGCONTEXT_H ++ ++struct sigcontext { ++ unsigned long sc_mask; /* old sigmask */ ++ unsigned long sc_usp; /* old user stack pointer */ ++ unsigned long sc_d0; ++ unsigned long sc_d1; ++ unsigned long sc_a0; ++ unsigned long sc_a1; ++ unsigned long sc_a5; ++ unsigned short sc_sr; ++ unsigned long sc_pc; ++ unsigned short sc_formatvec; ++}; ++ ++#endif +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/arch/m68k/include/asm/siginfo.h linux-2.6.29-rc3.owrt/arch/m68k/include/asm/siginfo.h +--- linux-2.6.29.owrt/arch/m68k/include/asm/siginfo.h 2009-05-10 22:04:40.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/arch/m68k/include/asm/siginfo.h 2009-05-10 23:48:28.000000000 +0200 +@@ -1,97 +1,5 @@ +-#ifndef _M68K_SIGINFO_H +-#define _M68K_SIGINFO_H +- +-#ifndef __uClinux__ +-#define HAVE_ARCH_SIGINFO_T +-#define HAVE_ARCH_COPY_SIGINFO +-#endif +- +-#include <asm-generic/siginfo.h> +- +-#ifndef __uClinux__ +- +-typedef struct siginfo { +- int si_signo; +- int si_errno; +- int si_code; +- +- union { +- int _pad[SI_PAD_SIZE]; +- +- /* kill() */ +- struct { +- __kernel_pid_t _pid; /* sender's pid */ +- __kernel_uid_t _uid; /* backwards compatibility */ +- __kernel_uid32_t _uid32; /* sender's uid */ +- } _kill; +- +- /* POSIX.1b timers */ +- struct { +- timer_t _tid; /* timer id */ +- int _overrun; /* overrun count */ +- char _pad[sizeof( __ARCH_SI_UID_T) - sizeof(int)]; +- sigval_t _sigval; /* same as below */ +- int _sys_private; /* not to be passed to user */ +- } _timer; +- +- /* POSIX.1b signals */ +- struct { +- __kernel_pid_t _pid; /* sender's pid */ +- __kernel_uid_t _uid; /* backwards compatibility */ +- sigval_t _sigval; +- __kernel_uid32_t _uid32; /* sender's uid */ +- } _rt; +- +- /* SIGCHLD */ +- struct { +- __kernel_pid_t _pid; /* which child */ +- __kernel_uid_t _uid; /* backwards compatibility */ +- int _status; /* exit code */ +- clock_t _utime; +- clock_t _stime; +- __kernel_uid32_t _uid32; /* sender's uid */ +- } _sigchld; +- +- /* SIGILL, SIGFPE, SIGSEGV, SIGBUS */ +- struct { +- void *_addr; /* faulting insn/memory ref. */ +- } _sigfault; +- +- /* SIGPOLL */ +- struct { +- int _band; /* POLL_IN, POLL_OUT, POLL_MSG */ +- int _fd; +- } _sigpoll; +- } _sifields; +-} siginfo_t; +- +-#define UID16_SIGINFO_COMPAT_NEEDED +- +-/* +- * How these fields are to be accessed. +- */ +-#undef si_uid +-#ifdef __KERNEL__ +-#define si_uid _sifields._kill._uid32 +-#define si_uid16 _sifields._kill._uid ++#ifdef __uClinux__ ++#include "siginfo_no.h" + #else +-#define si_uid _sifields._kill._uid +-#endif +- +-#ifdef __KERNEL__ +- +-#include <linux/string.h> +- +-static inline void copy_siginfo(struct siginfo *to, struct siginfo *from) +-{ +- if (from->si_code < 0) +- memcpy(to, from, sizeof(*to)); +- else +- /* _sigchld is currently the largest know union member */ +- memcpy(to, from, 3*sizeof(int) + sizeof(from->_sifields._sigchld)); +-} +- +-#endif /* __KERNEL__ */ +-#endif /* !__uClinux__ */ +- ++#include "siginfo_mm.h" + #endif +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/arch/m68k/include/asm/siginfo_mm.h linux-2.6.29-rc3.owrt/arch/m68k/include/asm/siginfo_mm.h +--- linux-2.6.29.owrt/arch/m68k/include/asm/siginfo_mm.h 1970-01-01 01:00:00.000000000 +0100 ++++ linux-2.6.29-rc3.owrt/arch/m68k/include/asm/siginfo_mm.h 2009-05-10 23:48:28.000000000 +0200 +@@ -0,0 +1,92 @@ ++#ifndef _M68K_SIGINFO_H ++#define _M68K_SIGINFO_H ++ ++#define HAVE_ARCH_SIGINFO_T ++#define HAVE_ARCH_COPY_SIGINFO ++ ++#include <asm-generic/siginfo.h> ++ ++typedef struct siginfo { ++ int si_signo; ++ int si_errno; ++ int si_code; ++ ++ union { ++ int _pad[SI_PAD_SIZE]; ++ ++ /* kill() */ ++ struct { ++ __kernel_pid_t _pid; /* sender's pid */ ++ __kernel_uid_t _uid; /* backwards compatibility */ ++ __kernel_uid32_t _uid32; /* sender's uid */ ++ } _kill; ++ ++ /* POSIX.1b timers */ ++ struct { ++ timer_t _tid; /* timer id */ ++ int _overrun; /* overrun count */ ++ char _pad[sizeof( __ARCH_SI_UID_T) - sizeof(int)]; ++ sigval_t _sigval; /* same as below */ ++ int _sys_private; /* not to be passed to user */ ++ } _timer; ++ ++ /* POSIX.1b signals */ ++ struct { ++ __kernel_pid_t _pid; /* sender's pid */ ++ __kernel_uid_t _uid; /* backwards compatibility */ ++ sigval_t _sigval; ++ __kernel_uid32_t _uid32; /* sender's uid */ ++ } _rt; ++ ++ /* SIGCHLD */ ++ struct { ++ __kernel_pid_t _pid; /* which child */ ++ __kernel_uid_t _uid; /* backwards compatibility */ ++ int _status; /* exit code */ ++ clock_t _utime; ++ clock_t _stime; ++ __kernel_uid32_t _uid32; /* sender's uid */ ++ } _sigchld; ++ ++ /* SIGILL, SIGFPE, SIGSEGV, SIGBUS */ ++ struct { ++ void *_addr; /* faulting insn/memory ref. */ ++ } _sigfault; ++ ++ /* SIGPOLL */ ++ struct { ++ int _band; /* POLL_IN, POLL_OUT, POLL_MSG */ ++ int _fd; ++ } _sigpoll; ++ } _sifields; ++} siginfo_t; ++ ++#define UID16_SIGINFO_COMPAT_NEEDED ++ ++/* ++ * How these fields are to be accessed. ++ */ ++#undef si_uid ++#ifdef __KERNEL__ ++#define si_uid _sifields._kill._uid32 ++#define si_uid16 _sifields._kill._uid ++#else ++#define si_uid _sifields._kill._uid ++#endif ++ ++#ifdef __KERNEL__ ++ ++#include <linux/string.h> ++ ++static inline void copy_siginfo(struct siginfo *to, struct siginfo *from) ++{ ++ if (from->si_code < 0) ++ memcpy(to, from, sizeof(*to)); ++ else ++ /* _sigchld is currently the largest know union member */ ++ memcpy(to, from, 3*sizeof(int) + sizeof(from->_sifields._sigchld)); ++} ++ ++#endif /* __KERNEL__ */ ++ ++#endif +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/arch/m68k/include/asm/siginfo_no.h linux-2.6.29-rc3.owrt/arch/m68k/include/asm/siginfo_no.h +--- linux-2.6.29.owrt/arch/m68k/include/asm/siginfo_no.h 1970-01-01 01:00:00.000000000 +0100 ++++ linux-2.6.29-rc3.owrt/arch/m68k/include/asm/siginfo_no.h 2009-05-10 23:48:28.000000000 +0200 +@@ -0,0 +1,6 @@ ++#ifndef _M68KNOMMU_SIGINFO_H ++#define _M68KNOMMU_SIGINFO_H ++ ++#include <asm-generic/siginfo.h> ++ ++#endif +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/arch/m68k/include/asm/signal.h linux-2.6.29-rc3.owrt/arch/m68k/include/asm/signal.h +--- linux-2.6.29.owrt/arch/m68k/include/asm/signal.h 2009-05-10 22:04:40.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/arch/m68k/include/asm/signal.h 2009-05-10 23:48:28.000000000 +0200 +@@ -1,213 +1,5 @@ +-#ifndef _M68K_SIGNAL_H +-#define _M68K_SIGNAL_H +- +-#include <linux/types.h> +- +-/* Avoid too many header ordering problems. */ +-struct siginfo; +- +-#ifdef __KERNEL__ +-/* Most things should be clean enough to redefine this at will, if care +- is taken to make libc match. */ +- +-#define _NSIG 64 +-#define _NSIG_BPW 32 +-#define _NSIG_WORDS (_NSIG / _NSIG_BPW) +- +-typedef unsigned long old_sigset_t; /* at least 32 bits */ +- +-typedef struct { +- unsigned long sig[_NSIG_WORDS]; +-} sigset_t; +- ++#ifdef __uClinux__ ++#include "signal_no.h" + #else +-/* Here we must cater to libcs that poke about in kernel headers. */ +- +-#define NSIG 32 +-typedef unsigned long sigset_t; +- +-#endif /* __KERNEL__ */ +- +-#define SIGHUP 1 +-#define SIGINT 2 +-#define SIGQUIT 3 +-#define SIGILL 4 +-#define SIGTRAP 5 +-#define SIGABRT 6 +-#define SIGIOT 6 +-#define SIGBUS 7 +-#define SIGFPE 8 +-#define SIGKILL 9 +-#define SIGUSR1 10 +-#define SIGSEGV 11 +-#define SIGUSR2 12 +-#define SIGPIPE 13 +-#define SIGALRM 14 +-#define SIGTERM 15 +-#define SIGSTKFLT 16 +-#define SIGCHLD 17 +-#define SIGCONT 18 +-#define SIGSTOP 19 +-#define SIGTSTP 20 +-#define SIGTTIN 21 +-#define SIGTTOU 22 +-#define SIGURG 23 +-#define SIGXCPU 24 +-#define SIGXFSZ 25 +-#define SIGVTALRM 26 +-#define SIGPROF 27 +-#define SIGWINCH 28 +-#define SIGIO 29 +-#define SIGPOLL SIGIO +-/* +-#define SIGLOST 29 +-*/ +-#define SIGPWR 30 +-#define SIGSYS 31 +-#define SIGUNUSED 31 +- +-/* These should not be considered constants from userland. */ +-#define SIGRTMIN 32 +-#define SIGRTMAX _NSIG +- +-/* +- * SA_FLAGS values: +- * +- * SA_ONSTACK indicates that a registered stack_t will be used. +- * SA_RESTART flag to get restarting signals (which were the default long ago) +- * SA_NOCLDSTOP flag to turn off SIGCHLD when children stop. +- * SA_RESETHAND clears the handler when the signal is delivered. +- * SA_NOCLDWAIT flag on SIGCHLD to inhibit zombies. +- * SA_NODEFER prevents the current signal from being masked in the handler. +- * +- * SA_ONESHOT and SA_NOMASK are the historical Linux names for the Single +- * Unix names RESETHAND and NODEFER respectively. +- */ +-#define SA_NOCLDSTOP 0x00000001 +-#define SA_NOCLDWAIT 0x00000002 +-#define SA_SIGINFO 0x00000004 +-#define SA_ONSTACK 0x08000000 +-#define SA_RESTART 0x10000000 +-#define SA_NODEFER 0x40000000 +-#define SA_RESETHAND 0x80000000 +- +-#define SA_NOMASK SA_NODEFER +-#define SA_ONESHOT SA_RESETHAND +- +-/* +- * sigaltstack controls +- */ +-#define SS_ONSTACK 1 +-#define SS_DISABLE 2 +- +-#define MINSIGSTKSZ 2048 +-#define SIGSTKSZ 8192 +- +-#include <asm-generic/signal.h> +- +-#ifdef __KERNEL__ +-struct old_sigaction { +- __sighandler_t sa_handler; +- old_sigset_t sa_mask; +- unsigned long sa_flags; +- __sigrestore_t sa_restorer; +-}; +- +-struct sigaction { +- __sighandler_t sa_handler; +- unsigned long sa_flags; +- __sigrestore_t sa_restorer; +- sigset_t sa_mask; /* mask last for extensibility */ +-}; +- +-struct k_sigaction { +- struct sigaction sa; +-}; +-#else +-/* Here we must cater to libcs that poke about in kernel headers. */ +- +-struct sigaction { +- union { +- __sighandler_t _sa_handler; +- void (*_sa_sigaction)(int, struct siginfo *, void *); +- } _u; +- sigset_t sa_mask; +- unsigned long sa_flags; +- void (*sa_restorer)(void); +-}; +- +-#define sa_handler _u._sa_handler +-#define sa_sigaction _u._sa_sigaction +- +-#endif /* __KERNEL__ */ +- +-typedef struct sigaltstack { +- void __user *ss_sp; +- int ss_flags; +- size_t ss_size; +-} stack_t; +- +-#ifdef __KERNEL__ +-#include <asm/sigcontext.h> +- +-#ifndef __uClinux__ +-#define __HAVE_ARCH_SIG_BITOPS +- +-static inline void sigaddset(sigset_t *set, int _sig) +-{ +- asm ("bfset %0{%1,#1}" +- : "+od" (*set) +- : "id" ((_sig - 1) ^ 31) +- : "cc"); +-} +- +-static inline void sigdelset(sigset_t *set, int _sig) +-{ +- asm ("bfclr %0{%1,#1}" +- : "+od" (*set) +- : "id" ((_sig - 1) ^ 31) +- : "cc"); +-} +- +-static inline int __const_sigismember(sigset_t *set, int _sig) +-{ +- unsigned long sig = _sig - 1; +- return 1 & (set->sig[sig / _NSIG_BPW] >> (sig % _NSIG_BPW)); +-} +- +-static inline int __gen_sigismember(sigset_t *set, int _sig) +-{ +- int ret; +- asm ("bfextu %1{%2,#1},%0" +- : "=d" (ret) +- : "od" (*set), "id" ((_sig-1) ^ 31) +- : "cc"); +- return ret; +-} +- +-#define sigismember(set,sig) \ +- (__builtin_constant_p(sig) ? \ +- __const_sigismember(set,sig) : \ +- __gen_sigismember(set,sig)) +- +-static inline int sigfindinword(unsigned long word) +-{ +- asm ("bfffo %1{#0,#0},%0" +- : "=d" (word) +- : "d" (word & -word) +- : "cc"); +- return word ^ 31; +-} +- +-struct pt_regs; +-extern void ptrace_signal_deliver(struct pt_regs *regs, void *cookie); +- +-#else +- +-#undef __HAVE_ARCH_SIG_BITOPS +-#define ptrace_signal_deliver(regs, cookie) do { } while (0) +- +-#endif /* __uClinux__ */ +-#endif /* __KERNEL__ */ +- +-#endif /* _M68K_SIGNAL_H */ ++#include "signal_mm.h" ++#endif +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/arch/m68k/include/asm/signal_mm.h linux-2.6.29-rc3.owrt/arch/m68k/include/asm/signal_mm.h +--- linux-2.6.29.owrt/arch/m68k/include/asm/signal_mm.h 1970-01-01 01:00:00.000000000 +0100 ++++ linux-2.6.29-rc3.owrt/arch/m68k/include/asm/signal_mm.h 2009-05-10 23:48:28.000000000 +0200 +@@ -0,0 +1,206 @@ ++#ifndef _M68K_SIGNAL_H ++#define _M68K_SIGNAL_H ++ ++#include <linux/types.h> ++ ++/* Avoid too many header ordering problems. */ ++struct siginfo; ++ ++#ifdef __KERNEL__ ++/* Most things should be clean enough to redefine this at will, if care ++ is taken to make libc match. */ ++ ++#define _NSIG 64 ++#define _NSIG_BPW 32 ++#define _NSIG_WORDS (_NSIG / _NSIG_BPW) ++ ++typedef unsigned long old_sigset_t; /* at least 32 bits */ ++ ++typedef struct { ++ unsigned long sig[_NSIG_WORDS]; ++} sigset_t; ++ ++#else ++/* Here we must cater to libcs that poke about in kernel headers. */ ++ ++#define NSIG 32 ++typedef unsigned long sigset_t; ++ ++#endif /* __KERNEL__ */ ++ ++#define SIGHUP 1 ++#define SIGINT 2 ++#define SIGQUIT 3 ++#define SIGILL 4 ++#define SIGTRAP 5 ++#define SIGABRT 6 ++#define SIGIOT 6 ++#define SIGBUS 7 ++#define SIGFPE 8 ++#define SIGKILL 9 ++#define SIGUSR1 10 ++#define SIGSEGV 11 ++#define SIGUSR2 12 ++#define SIGPIPE 13 ++#define SIGALRM 14 ++#define SIGTERM 15 ++#define SIGSTKFLT 16 ++#define SIGCHLD 17 ++#define SIGCONT 18 ++#define SIGSTOP 19 ++#define SIGTSTP 20 ++#define SIGTTIN 21 ++#define SIGTTOU 22 ++#define SIGURG 23 ++#define SIGXCPU 24 ++#define SIGXFSZ 25 ++#define SIGVTALRM 26 ++#define SIGPROF 27 ++#define SIGWINCH 28 ++#define SIGIO 29 ++#define SIGPOLL SIGIO ++/* ++#define SIGLOST 29 ++*/ ++#define SIGPWR 30 ++#define SIGSYS 31 ++#define SIGUNUSED 31 ++ ++/* These should not be considered constants from userland. */ ++#define SIGRTMIN 32 ++#define SIGRTMAX _NSIG ++ ++/* ++ * SA_FLAGS values: ++ * ++ * SA_ONSTACK indicates that a registered stack_t will be used. ++ * SA_RESTART flag to get restarting signals (which were the default long ago) ++ * SA_NOCLDSTOP flag to turn off SIGCHLD when children stop. ++ * SA_RESETHAND clears the handler when the signal is delivered. ++ * SA_NOCLDWAIT flag on SIGCHLD to inhibit zombies. ++ * SA_NODEFER prevents the current signal from being masked in the handler. ++ * ++ * SA_ONESHOT and SA_NOMASK are the historical Linux names for the Single ++ * Unix names RESETHAND and NODEFER respectively. ++ */ ++#define SA_NOCLDSTOP 0x00000001 ++#define SA_NOCLDWAIT 0x00000002 ++#define SA_SIGINFO 0x00000004 ++#define SA_ONSTACK 0x08000000 ++#define SA_RESTART 0x10000000 ++#define SA_NODEFER 0x40000000 ++#define SA_RESETHAND 0x80000000 ++ ++#define SA_NOMASK SA_NODEFER ++#define SA_ONESHOT SA_RESETHAND ++ ++/* ++ * sigaltstack controls ++ */ ++#define SS_ONSTACK 1 ++#define SS_DISABLE 2 ++ ++#define MINSIGSTKSZ 2048 ++#define SIGSTKSZ 8192 ++ ++#include <asm-generic/signal.h> ++ ++#ifdef __KERNEL__ ++struct old_sigaction { ++ __sighandler_t sa_handler; ++ old_sigset_t sa_mask; ++ unsigned long sa_flags; ++ __sigrestore_t sa_restorer; ++}; ++ ++struct sigaction { ++ __sighandler_t sa_handler; ++ unsigned long sa_flags; ++ __sigrestore_t sa_restorer; ++ sigset_t sa_mask; /* mask last for extensibility */ ++}; ++ ++struct k_sigaction { ++ struct sigaction sa; ++}; ++#else ++/* Here we must cater to libcs that poke about in kernel headers. */ ++ ++struct sigaction { ++ union { ++ __sighandler_t _sa_handler; ++ void (*_sa_sigaction)(int, struct siginfo *, void *); ++ } _u; ++ sigset_t sa_mask; ++ unsigned long sa_flags; ++ void (*sa_restorer)(void); ++}; ++ ++#define sa_handler _u._sa_handler ++#define sa_sigaction _u._sa_sigaction ++ ++#endif /* __KERNEL__ */ ++ ++typedef struct sigaltstack { ++ void __user *ss_sp; ++ int ss_flags; ++ size_t ss_size; ++} stack_t; ++ ++#ifdef __KERNEL__ ++#include <asm/sigcontext.h> ++ ++#define __HAVE_ARCH_SIG_BITOPS ++ ++static inline void sigaddset(sigset_t *set, int _sig) ++{ ++ asm ("bfset %0{%1,#1}" ++ : "+od" (*set) ++ : "id" ((_sig - 1) ^ 31) ++ : "cc"); ++} ++ ++static inline void sigdelset(sigset_t *set, int _sig) ++{ ++ asm ("bfclr %0{%1,#1}" ++ : "+od" (*set) ++ : "id" ((_sig - 1) ^ 31) ++ : "cc"); ++} ++ ++static inline int __const_sigismember(sigset_t *set, int _sig) ++{ ++ unsigned long sig = _sig - 1; ++ return 1 & (set->sig[sig / _NSIG_BPW] >> (sig % _NSIG_BPW)); ++} ++ ++static inline int __gen_sigismember(sigset_t *set, int _sig) ++{ ++ int ret; ++ asm ("bfextu %1{%2,#1},%0" ++ : "=d" (ret) ++ : "od" (*set), "id" ((_sig-1) ^ 31) ++ : "cc"); ++ return ret; ++} ++ ++#define sigismember(set,sig) \ ++ (__builtin_constant_p(sig) ? \ ++ __const_sigismember(set,sig) : \ ++ __gen_sigismember(set,sig)) ++ ++static inline int sigfindinword(unsigned long word) ++{ ++ asm ("bfffo %1{#0,#0},%0" ++ : "=d" (word) ++ : "d" (word & -word) ++ : "cc"); ++ return word ^ 31; ++} ++ ++struct pt_regs; ++extern void ptrace_signal_deliver(struct pt_regs *regs, void *cookie); ++ ++#endif /* __KERNEL__ */ ++ ++#endif /* _M68K_SIGNAL_H */ +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/arch/m68k/include/asm/signal_no.h linux-2.6.29-rc3.owrt/arch/m68k/include/asm/signal_no.h +--- linux-2.6.29.owrt/arch/m68k/include/asm/signal_no.h 1970-01-01 01:00:00.000000000 +0100 ++++ linux-2.6.29-rc3.owrt/arch/m68k/include/asm/signal_no.h 2009-05-10 23:48:28.000000000 +0200 +@@ -0,0 +1,159 @@ ++#ifndef _M68KNOMMU_SIGNAL_H ++#define _M68KNOMMU_SIGNAL_H ++ ++#include <linux/types.h> ++ ++/* Avoid too many header ordering problems. */ ++struct siginfo; ++ ++#ifdef __KERNEL__ ++/* Most things should be clean enough to redefine this at will, if care ++ is taken to make libc match. */ ++ ++#define _NSIG 64 ++#define _NSIG_BPW 32 ++#define _NSIG_WORDS (_NSIG / _NSIG_BPW) ++ ++typedef unsigned long old_sigset_t; /* at least 32 bits */ ++ ++typedef struct { ++ unsigned long sig[_NSIG_WORDS]; ++} sigset_t; ++ ++#else ++/* Here we must cater to libcs that poke about in kernel headers. */ ++ ++#define NSIG 32 ++typedef unsigned long sigset_t; ++ ++#endif /* __KERNEL__ */ ++ ++#define SIGHUP 1 ++#define SIGINT 2 ++#define SIGQUIT 3 ++#define SIGILL 4 ++#define SIGTRAP 5 ++#define SIGABRT 6 ++#define SIGIOT 6 ++#define SIGBUS 7 ++#define SIGFPE 8 ++#define SIGKILL 9 ++#define SIGUSR1 10 ++#define SIGSEGV 11 ++#define SIGUSR2 12 ++#define SIGPIPE 13 ++#define SIGALRM 14 ++#define SIGTERM 15 ++#define SIGSTKFLT 16 ++#define SIGCHLD 17 ++#define SIGCONT 18 ++#define SIGSTOP 19 ++#define SIGTSTP 20 ++#define SIGTTIN 21 ++#define SIGTTOU 22 ++#define SIGURG 23 ++#define SIGXCPU 24 ++#define SIGXFSZ 25 ++#define SIGVTALRM 26 ++#define SIGPROF 27 ++#define SIGWINCH 28 ++#define SIGIO 29 ++#define SIGPOLL SIGIO ++/* ++#define SIGLOST 29 ++*/ ++#define SIGPWR 30 ++#define SIGSYS 31 ++#define SIGUNUSED 31 ++ ++/* These should not be considered constants from userland. */ ++#define SIGRTMIN 32 ++#define SIGRTMAX _NSIG ++ ++/* ++ * SA_FLAGS values: ++ * ++ * SA_ONSTACK indicates that a registered stack_t will be used. ++ * SA_RESTART flag to get restarting signals (which were the default long ago) ++ * SA_NOCLDSTOP flag to turn off SIGCHLD when children stop. ++ * SA_RESETHAND clears the handler when the signal is delivered. ++ * SA_NOCLDWAIT flag on SIGCHLD to inhibit zombies. ++ * SA_NODEFER prevents the current signal from being masked in the handler. ++ * ++ * SA_ONESHOT and SA_NOMASK are the historical Linux names for the Single ++ * Unix names RESETHAND and NODEFER respectively. ++ */ ++#define SA_NOCLDSTOP 0x00000001 ++#define SA_NOCLDWAIT 0x00000002 ++#define SA_SIGINFO 0x00000004 ++#define SA_ONSTACK 0x08000000 ++#define SA_RESTART 0x10000000 ++#define SA_NODEFER 0x40000000 ++#define SA_RESETHAND 0x80000000 ++ ++#define SA_NOMASK SA_NODEFER ++#define SA_ONESHOT SA_RESETHAND ++ ++/* ++ * sigaltstack controls ++ */ ++#define SS_ONSTACK 1 ++#define SS_DISABLE 2 ++ ++#define MINSIGSTKSZ 2048 ++#define SIGSTKSZ 8192 ++ ++#include <asm-generic/signal.h> ++ ++#ifdef __KERNEL__ ++struct old_sigaction { ++ __sighandler_t sa_handler; ++ old_sigset_t sa_mask; ++ unsigned long sa_flags; ++ void (*sa_restorer)(void); ++}; ++ ++struct sigaction { ++ __sighandler_t sa_handler; ++ unsigned long sa_flags; ++ void (*sa_restorer)(void); ++ sigset_t sa_mask; /* mask last for extensibility */ ++}; ++ ++struct k_sigaction { ++ struct sigaction sa; ++}; ++#else ++/* Here we must cater to libcs that poke about in kernel headers. */ ++ ++struct sigaction { ++ union { ++ __sighandler_t _sa_handler; ++ void (*_sa_sigaction)(int, struct siginfo *, void *); ++ } _u; ++ sigset_t sa_mask; ++ unsigned long sa_flags; ++ void (*sa_restorer)(void); ++}; ++ ++#define sa_handler _u._sa_handler ++#define sa_sigaction _u._sa_sigaction ++ ++#endif /* __KERNEL__ */ ++ ++typedef struct sigaltstack { ++ void *ss_sp; ++ int ss_flags; ++ size_t ss_size; ++} stack_t; ++ ++#ifdef __KERNEL__ ++ ++#include <asm/sigcontext.h> ++#undef __HAVE_ARCH_SIG_BITOPS ++ ++#define ptrace_signal_deliver(regs, cookie) do { } while (0) ++ ++#endif /* __KERNEL__ */ ++ ++#endif /* _M68KNOMMU_SIGNAL_H */ +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/arch/m68k/include/asm/swab.h linux-2.6.29-rc3.owrt/arch/m68k/include/asm/swab.h +--- linux-2.6.29.owrt/arch/m68k/include/asm/swab.h 2009-05-10 22:04:40.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/arch/m68k/include/asm/swab.h 2009-05-10 23:48:28.000000000 +0200 +@@ -1,27 +1,5 @@ +-#ifndef _M68K_SWAB_H +-#define _M68K_SWAB_H +- +-#include <asm/types.h> +-#include <linux/compiler.h> +- +-#define __SWAB_64_THRU_32__ +- +-#if defined (__mcfisaaplus__) || defined (__mcfisac__) +-static inline __attribute_const__ __u32 __arch_swab32(__u32 val) +-{ +- __asm__("byterev %0" : "=d" (val) : "0" (val)); +- return val; +-} +- +-#define __arch_swab32 __arch_swab32 +-#elif !defined(__uClinux__) +- +-static inline __attribute_const__ __u32 __arch_swab32(__u32 val) +-{ +- __asm__("rolw #8,%0; swap %0; rolw #8,%0" : "=d" (val) : "0" (val)); +- return val; +-} +-#define __arch_swab32 __arch_swab32 ++#ifdef __uClinux__ ++#include "swab_no.h" ++#else ++#include "swab_mm.h" + #endif +- +-#endif /* _M68K_SWAB_H */ +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/arch/m68k/include/asm/swab_mm.h linux-2.6.29-rc3.owrt/arch/m68k/include/asm/swab_mm.h +--- linux-2.6.29.owrt/arch/m68k/include/asm/swab_mm.h 1970-01-01 01:00:00.000000000 +0100 ++++ linux-2.6.29-rc3.owrt/arch/m68k/include/asm/swab_mm.h 2009-05-10 23:48:28.000000000 +0200 +@@ -0,0 +1,16 @@ ++#ifndef _M68K_SWAB_H ++#define _M68K_SWAB_H ++ ++#include <asm/types.h> ++#include <linux/compiler.h> ++ ++#define __SWAB_64_THRU_32__ ++ ++static inline __attribute_const__ __u32 __arch_swab32(__u32 val) ++{ ++ __asm__("rolw #8,%0; swap %0; rolw #8,%0" : "=d" (val) : "0" (val)); ++ return val; ++} ++#define __arch_swab32 __arch_swab32 ++ ++#endif /* _M68K_SWAB_H */ +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/arch/m68k/include/asm/swab_no.h linux-2.6.29-rc3.owrt/arch/m68k/include/asm/swab_no.h +--- linux-2.6.29.owrt/arch/m68k/include/asm/swab_no.h 1970-01-01 01:00:00.000000000 +0100 ++++ linux-2.6.29-rc3.owrt/arch/m68k/include/asm/swab_no.h 2009-05-10 23:48:28.000000000 +0200 +@@ -0,0 +1,24 @@ ++#ifndef _M68KNOMMU_SWAB_H ++#define _M68KNOMMU_SWAB_H ++ ++#include <linux/types.h> ++ ++#if defined(__GNUC__) && !defined(__STRICT_ANSI__) || defined(__KERNEL__) ++# define __SWAB_64_THRU_32__ ++#endif ++ ++#if defined (__mcfisaaplus__) || defined (__mcfisac__) ++static inline __attribute_const__ __u32 __arch_swab32(__u32 val) ++{ ++ asm( ++ "byterev %0" ++ : "=d" (val) ++ : "0" (val) ++ ); ++ return val; ++} ++ ++#define __arch_swab32 __arch_swab32 ++#endif ++ ++#endif /* _M68KNOMMU_SWAB_H */ +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/arch/m68k/include/asm/unistd.h linux-2.6.29-rc3.owrt/arch/m68k/include/asm/unistd.h +--- linux-2.6.29.owrt/arch/m68k/include/asm/unistd.h 2009-05-10 22:04:40.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/arch/m68k/include/asm/unistd.h 2009-05-10 23:48:28.000000000 +0200 +@@ -1,372 +1,5 @@ +-#ifndef _ASM_M68K_UNISTD_H_ +-#define _ASM_M68K_UNISTD_H_ +- +-/* +- * This file contains the system call numbers. +- */ +- +-#define __NR_restart_syscall 0 +-#define __NR_exit 1 +-#define __NR_fork 2 +-#define __NR_read 3 +-#define __NR_write 4 +-#define __NR_open 5 +-#define __NR_close 6 +-#define __NR_waitpid 7 +-#define __NR_creat 8 +-#define __NR_link 9 +-#define __NR_unlink 10 +-#define __NR_execve 11 +-#define __NR_chdir 12 +-#define __NR_time 13 +-#define __NR_mknod 14 +-#define __NR_chmod 15 +-#define __NR_chown 16 +-#define __NR_break 17 +-#define __NR_oldstat 18 +-#define __NR_lseek 19 +-#define __NR_getpid 20 +-#define __NR_mount 21 +-#define __NR_umount 22 +-#define __NR_setuid 23 +-#define __NR_getuid 24 +-#define __NR_stime 25 +-#define __NR_ptrace 26 +-#define __NR_alarm 27 +-#define __NR_oldfstat 28 +-#define __NR_pause 29 +-#define __NR_utime 30 +-#define __NR_stty 31 +-#define __NR_gtty 32 +-#define __NR_access 33 +-#define __NR_nice 34 +-#define __NR_ftime 35 +-#define __NR_sync 36 +-#define __NR_kill 37 +-#define __NR_rename 38 +-#define __NR_mkdir 39 +-#define __NR_rmdir 40 +-#define __NR_dup 41 +-#define __NR_pipe 42 +-#define __NR_times 43 +-#define __NR_prof 44 +-#define __NR_brk 45 +-#define __NR_setgid 46 +-#define __NR_getgid 47 +-#define __NR_signal 48 +-#define __NR_geteuid 49 +-#define __NR_getegid 50 +-#define __NR_acct 51 +-#define __NR_umount2 52 +-#define __NR_lock 53 +-#define __NR_ioctl 54 +-#define __NR_fcntl 55 +-#define __NR_mpx 56 +-#define __NR_setpgid 57 +-#define __NR_ulimit 58 +-#define __NR_oldolduname 59 +-#define __NR_umask 60 +-#define __NR_chroot 61 +-#define __NR_ustat 62 +-#define __NR_dup2 63 +-#define __NR_getppid 64 +-#define __NR_getpgrp 65 +-#define __NR_setsid 66 +-#define __NR_sigaction 67 +-#define __NR_sgetmask 68 +-#define __NR_ssetmask 69 +-#define __NR_setreuid 70 +-#define __NR_setregid 71 +-#define __NR_sigsuspend 72 +-#define __NR_sigpending 73 +-#define __NR_sethostname 74 +-#define __NR_setrlimit 75 +-#define __NR_getrlimit 76 +-#define __NR_getrusage 77 +-#define __NR_gettimeofday 78 +-#define __NR_settimeofday 79 +-#define __NR_getgroups 80 +-#define __NR_setgroups 81 +-#define __NR_select 82 +-#define __NR_symlink 83 +-#define __NR_oldlstat 84 +-#define __NR_readlink 85 +-#define __NR_uselib 86 +-#define __NR_swapon 87 +-#define __NR_reboot 88 +-#define __NR_readdir 89 +-#define __NR_mmap 90 +-#define __NR_munmap 91 +-#define __NR_truncate 92 +-#define __NR_ftruncate 93 +-#define __NR_fchmod 94 +-#define __NR_fchown 95 +-#define __NR_getpriority 96 +-#define __NR_setpriority 97 +-#define __NR_profil 98 +-#define __NR_statfs 99 +-#define __NR_fstatfs 100 +-#define __NR_ioperm 101 +-#define __NR_socketcall 102 +-#define __NR_syslog 103 +-#define __NR_setitimer 104 +-#define __NR_getitimer 105 +-#define __NR_stat 106 +-#define __NR_lstat 107 +-#define __NR_fstat 108 +-#define __NR_olduname 109 +-#define __NR_iopl /* 110 */ not supported +-#define __NR_vhangup 111 +-#define __NR_idle /* 112 */ Obsolete +-#define __NR_vm86 /* 113 */ not supported +-#define __NR_wait4 114 +-#define __NR_swapoff 115 +-#define __NR_sysinfo 116 +-#define __NR_ipc 117 +-#define __NR_fsync 118 +-#define __NR_sigreturn 119 +-#define __NR_clone 120 +-#define __NR_setdomainname 121 +-#define __NR_uname 122 +-#define __NR_cacheflush 123 +-#define __NR_adjtimex 124 +-#define __NR_mprotect 125 +-#define __NR_sigprocmask 126 +-#define __NR_create_module 127 +-#define __NR_init_module 128 +-#define __NR_delete_module 129 +-#define __NR_get_kernel_syms 130 +-#define __NR_quotactl 131 +-#define __NR_getpgid 132 +-#define __NR_fchdir 133 +-#define __NR_bdflush 134 +-#define __NR_sysfs 135 +-#define __NR_personality 136 +-#define __NR_afs_syscall 137 /* Syscall for Andrew File System */ +-#define __NR_setfsuid 138 +-#define __NR_setfsgid 139 +-#define __NR__llseek 140 +-#define __NR_getdents 141 +-#define __NR__newselect 142 +-#define __NR_flock 143 +-#define __NR_msync 144 +-#define __NR_readv 145 +-#define __NR_writev 146 +-#define __NR_getsid 147 +-#define __NR_fdatasync 148 +-#define __NR__sysctl 149 +-#define __NR_mlock 150 +-#define __NR_munlock 151 +-#define __NR_mlockall 152 +-#define __NR_munlockall 153 +-#define __NR_sched_setparam 154 +-#define __NR_sched_getparam 155 +-#define __NR_sched_setscheduler 156 +-#define __NR_sched_getscheduler 157 +-#define __NR_sched_yield 158 +-#define __NR_sched_get_priority_max 159 +-#define __NR_sched_get_priority_min 160 +-#define __NR_sched_rr_get_interval 161 +-#define __NR_nanosleep 162 +-#define __NR_mremap 163 +-#define __NR_setresuid 164 +-#define __NR_getresuid 165 +-#define __NR_getpagesize 166 +-#define __NR_query_module 167 +-#define __NR_poll 168 +-#define __NR_nfsservctl 169 +-#define __NR_setresgid 170 +-#define __NR_getresgid 171 +-#define __NR_prctl 172 +-#define __NR_rt_sigreturn 173 +-#define __NR_rt_sigaction 174 +-#define __NR_rt_sigprocmask 175 +-#define __NR_rt_sigpending 176 +-#define __NR_rt_sigtimedwait 177 +-#define __NR_rt_sigqueueinfo 178 +-#define __NR_rt_sigsuspend 179 +-#define __NR_pread64 180 +-#define __NR_pwrite64 181 +-#define __NR_lchown 182 +-#define __NR_getcwd 183 +-#define __NR_capget 184 +-#define __NR_capset 185 +-#define __NR_sigaltstack 186 +-#define __NR_sendfile 187 +-#define __NR_getpmsg 188 /* some people actually want streams */ +-#define __NR_putpmsg 189 /* some people actually want streams */ +-#define __NR_vfork 190 +-#define __NR_ugetrlimit 191 +-#define __NR_mmap2 192 +-#define __NR_truncate64 193 +-#define __NR_ftruncate64 194 +-#define __NR_stat64 195 +-#define __NR_lstat64 196 +-#define __NR_fstat64 197 +-#define __NR_chown32 198 +-#define __NR_getuid32 199 +-#define __NR_getgid32 200 +-#define __NR_geteuid32 201 +-#define __NR_getegid32 202 +-#define __NR_setreuid32 203 +-#define __NR_setregid32 204 +-#define __NR_getgroups32 205 +-#define __NR_setgroups32 206 +-#define __NR_fchown32 207 +-#define __NR_setresuid32 208 +-#define __NR_getresuid32 209 +-#define __NR_setresgid32 210 +-#define __NR_getresgid32 211 +-#define __NR_lchown32 212 +-#define __NR_setuid32 213 +-#define __NR_setgid32 214 +-#define __NR_setfsuid32 215 +-#define __NR_setfsgid32 216 +-#define __NR_pivot_root 217 +-#define __NR_getdents64 220 +-#define __NR_gettid 221 +-#define __NR_tkill 222 +-#define __NR_setxattr 223 +-#define __NR_lsetxattr 224 +-#define __NR_fsetxattr 225 +-#define __NR_getxattr 226 +-#define __NR_lgetxattr 227 +-#define __NR_fgetxattr 228 +-#define __NR_listxattr 229 +-#define __NR_llistxattr 230 +-#define __NR_flistxattr 231 +-#define __NR_removexattr 232 +-#define __NR_lremovexattr 233 +-#define __NR_fremovexattr 234 +-#define __NR_futex 235 +-#define __NR_sendfile64 236 +-#define __NR_mincore 237 +-#define __NR_madvise 238 +-#define __NR_fcntl64 239 +-#define __NR_readahead 240 +-#define __NR_io_setup 241 +-#define __NR_io_destroy 242 +-#define __NR_io_getevents 243 +-#define __NR_io_submit 244 +-#define __NR_io_cancel 245 +-#define __NR_fadvise64 246 +-#define __NR_exit_group 247 +-#define __NR_lookup_dcookie 248 +-#define __NR_epoll_create 249 +-#define __NR_epoll_ctl 250 +-#define __NR_epoll_wait 251 +-#define __NR_remap_file_pages 252 +-#define __NR_set_tid_address 253 +-#define __NR_timer_create 254 +-#define __NR_timer_settime 255 +-#define __NR_timer_gettime 256 +-#define __NR_timer_getoverrun 257 +-#define __NR_timer_delete 258 +-#define __NR_clock_settime 259 +-#define __NR_clock_gettime 260 +-#define __NR_clock_getres 261 +-#define __NR_clock_nanosleep 262 +-#define __NR_statfs64 263 +-#define __NR_fstatfs64 264 +-#define __NR_tgkill 265 +-#define __NR_utimes 266 +-#define __NR_fadvise64_64 267 +-#define __NR_mbind 268 +-#define __NR_get_mempolicy 269 +-#define __NR_set_mempolicy 270 +-#define __NR_mq_open 271 +-#define __NR_mq_unlink 272 +-#define __NR_mq_timedsend 273 +-#define __NR_mq_timedreceive 274 +-#define __NR_mq_notify 275 +-#define __NR_mq_getsetattr 276 +-#define __NR_waitid 277 +-#define __NR_vserver 278 +-#define __NR_add_key 279 +-#define __NR_request_key 280 +-#define __NR_keyctl 281 +-#define __NR_ioprio_set 282 +-#define __NR_ioprio_get 283 +-#define __NR_inotify_init 284 +-#define __NR_inotify_add_watch 285 +-#define __NR_inotify_rm_watch 286 +-#define __NR_migrate_pages 287 +-#define __NR_openat 288 +-#define __NR_mkdirat 289 +-#define __NR_mknodat 290 +-#define __NR_fchownat 291 +-#define __NR_futimesat 292 +-#define __NR_fstatat64 293 +-#define __NR_unlinkat 294 +-#define __NR_renameat 295 +-#define __NR_linkat 296 +-#define __NR_symlinkat 297 +-#define __NR_readlinkat 298 +-#define __NR_fchmodat 299 +-#define __NR_faccessat 300 +-#define __NR_pselect6 301 +-#define __NR_ppoll 302 +-#define __NR_unshare 303 +-#define __NR_set_robust_list 304 +-#define __NR_get_robust_list 305 +-#define __NR_splice 306 +-#define __NR_sync_file_range 307 +-#define __NR_tee 308 +-#define __NR_vmsplice 309 +-#define __NR_move_pages 310 +-#define __NR_sched_setaffinity 311 +-#define __NR_sched_getaffinity 312 +-#define __NR_kexec_load 313 +-#define __NR_getcpu 314 +-#define __NR_epoll_pwait 315 +-#define __NR_utimensat 316 +-#define __NR_signalfd 317 +-#define __NR_timerfd_create 318 +-#define __NR_eventfd 319 +-#define __NR_fallocate 320 +-#define __NR_timerfd_settime 321 +-#define __NR_timerfd_gettime 322 +-#define __NR_signalfd4 323 +-#define __NR_eventfd2 324 +-#define __NR_epoll_create1 325 +-#define __NR_dup3 326 +-#define __NR_pipe2 327 +-#define __NR_inotify_init1 328 +- +-#ifdef __KERNEL__ +- +-#define NR_syscalls 329 +- +-#define __ARCH_WANT_IPC_PARSE_VERSION +-#define __ARCH_WANT_OLD_READDIR +-#define __ARCH_WANT_OLD_STAT +-#define __ARCH_WANT_STAT64 +-#define __ARCH_WANT_SYS_ALARM +-#define __ARCH_WANT_SYS_GETHOSTNAME +-#define __ARCH_WANT_SYS_PAUSE +-#define __ARCH_WANT_SYS_SGETMASK +-#define __ARCH_WANT_SYS_SIGNAL +-#define __ARCH_WANT_SYS_TIME +-#define __ARCH_WANT_SYS_UTIME +-#define __ARCH_WANT_SYS_WAITPID +-#define __ARCH_WANT_SYS_SOCKETCALL +-#define __ARCH_WANT_SYS_FADVISE64 +-#define __ARCH_WANT_SYS_GETPGRP +-#define __ARCH_WANT_SYS_LLSEEK +-#define __ARCH_WANT_SYS_NICE +-#define __ARCH_WANT_SYS_OLD_GETRLIMIT +-#define __ARCH_WANT_SYS_OLDUMOUNT +-#define __ARCH_WANT_SYS_SIGPENDING +-#define __ARCH_WANT_SYS_SIGPROCMASK +-#define __ARCH_WANT_SYS_RT_SIGACTION +- +-/* +- * "Conditional" syscalls +- * +- * What we want is __attribute__((weak,alias("sys_ni_syscall"))), +- * but it doesn't work on all toolchains, so we just do it by hand +- */ +-#define cond_syscall(x) asm(".weak\t" #x "\n\t.set\t" #x ",sys_ni_syscall") +- +-#endif /* __KERNEL__ */ +-#endif /* _ASM_M68K_UNISTD_H_ */ ++#ifdef __uClinux__ ++#include "unistd_no.h" ++#else ++#include "unistd_mm.h" ++#endif +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/arch/m68k/include/asm/unistd_mm.h linux-2.6.29-rc3.owrt/arch/m68k/include/asm/unistd_mm.h +--- linux-2.6.29.owrt/arch/m68k/include/asm/unistd_mm.h 1970-01-01 01:00:00.000000000 +0100 ++++ linux-2.6.29-rc3.owrt/arch/m68k/include/asm/unistd_mm.h 2009-05-10 23:48:28.000000000 +0200 +@@ -0,0 +1,372 @@ ++#ifndef _ASM_M68K_UNISTD_H_ ++#define _ASM_M68K_UNISTD_H_ ++ ++/* ++ * This file contains the system call numbers. ++ */ ++ ++#define __NR_restart_syscall 0 ++#define __NR_exit 1 ++#define __NR_fork 2 ++#define __NR_read 3 ++#define __NR_write 4 ++#define __NR_open 5 ++#define __NR_close 6 ++#define __NR_waitpid 7 ++#define __NR_creat 8 ++#define __NR_link 9 ++#define __NR_unlink 10 ++#define __NR_execve 11 ++#define __NR_chdir 12 ++#define __NR_time 13 ++#define __NR_mknod 14 ++#define __NR_chmod 15 ++#define __NR_chown 16 ++#define __NR_break 17 ++#define __NR_oldstat 18 ++#define __NR_lseek 19 ++#define __NR_getpid 20 ++#define __NR_mount 21 ++#define __NR_umount 22 ++#define __NR_setuid 23 ++#define __NR_getuid 24 ++#define __NR_stime 25 ++#define __NR_ptrace 26 ++#define __NR_alarm 27 ++#define __NR_oldfstat 28 ++#define __NR_pause 29 ++#define __NR_utime 30 ++#define __NR_stty 31 ++#define __NR_gtty 32 ++#define __NR_access 33 ++#define __NR_nice 34 ++#define __NR_ftime 35 ++#define __NR_sync 36 ++#define __NR_kill 37 ++#define __NR_rename 38 ++#define __NR_mkdir 39 ++#define __NR_rmdir 40 ++#define __NR_dup 41 ++#define __NR_pipe 42 ++#define __NR_times 43 ++#define __NR_prof 44 ++#define __NR_brk 45 ++#define __NR_setgid 46 ++#define __NR_getgid 47 ++#define __NR_signal 48 ++#define __NR_geteuid 49 ++#define __NR_getegid 50 ++#define __NR_acct 51 ++#define __NR_umount2 52 ++#define __NR_lock 53 ++#define __NR_ioctl 54 ++#define __NR_fcntl 55 ++#define __NR_mpx 56 ++#define __NR_setpgid 57 ++#define __NR_ulimit 58 ++#define __NR_oldolduname 59 ++#define __NR_umask 60 ++#define __NR_chroot 61 ++#define __NR_ustat 62 ++#define __NR_dup2 63 ++#define __NR_getppid 64 ++#define __NR_getpgrp 65 ++#define __NR_setsid 66 ++#define __NR_sigaction 67 ++#define __NR_sgetmask 68 ++#define __NR_ssetmask 69 ++#define __NR_setreuid 70 ++#define __NR_setregid 71 ++#define __NR_sigsuspend 72 ++#define __NR_sigpending 73 ++#define __NR_sethostname 74 ++#define __NR_setrlimit 75 ++#define __NR_getrlimit 76 ++#define __NR_getrusage 77 ++#define __NR_gettimeofday 78 ++#define __NR_settimeofday 79 ++#define __NR_getgroups 80 ++#define __NR_setgroups 81 ++#define __NR_select 82 ++#define __NR_symlink 83 ++#define __NR_oldlstat 84 ++#define __NR_readlink 85 ++#define __NR_uselib 86 ++#define __NR_swapon 87 ++#define __NR_reboot 88 ++#define __NR_readdir 89 ++#define __NR_mmap 90 ++#define __NR_munmap 91 ++#define __NR_truncate 92 ++#define __NR_ftruncate 93 ++#define __NR_fchmod 94 ++#define __NR_fchown 95 ++#define __NR_getpriority 96 ++#define __NR_setpriority 97 ++#define __NR_profil 98 ++#define __NR_statfs 99 ++#define __NR_fstatfs 100 ++#define __NR_ioperm 101 ++#define __NR_socketcall 102 ++#define __NR_syslog 103 ++#define __NR_setitimer 104 ++#define __NR_getitimer 105 ++#define __NR_stat 106 ++#define __NR_lstat 107 ++#define __NR_fstat 108 ++#define __NR_olduname 109 ++#define __NR_iopl /* 110 */ not supported ++#define __NR_vhangup 111 ++#define __NR_idle /* 112 */ Obsolete ++#define __NR_vm86 /* 113 */ not supported ++#define __NR_wait4 114 ++#define __NR_swapoff 115 ++#define __NR_sysinfo 116 ++#define __NR_ipc 117 ++#define __NR_fsync 118 ++#define __NR_sigreturn 119 ++#define __NR_clone 120 ++#define __NR_setdomainname 121 ++#define __NR_uname 122 ++#define __NR_cacheflush 123 ++#define __NR_adjtimex 124 ++#define __NR_mprotect 125 ++#define __NR_sigprocmask 126 ++#define __NR_create_module 127 ++#define __NR_init_module 128 ++#define __NR_delete_module 129 ++#define __NR_get_kernel_syms 130 ++#define __NR_quotactl 131 ++#define __NR_getpgid 132 ++#define __NR_fchdir 133 ++#define __NR_bdflush 134 ++#define __NR_sysfs 135 ++#define __NR_personality 136 ++#define __NR_afs_syscall 137 /* Syscall for Andrew File System */ ++#define __NR_setfsuid 138 ++#define __NR_setfsgid 139 ++#define __NR__llseek 140 ++#define __NR_getdents 141 ++#define __NR__newselect 142 ++#define __NR_flock 143 ++#define __NR_msync 144 ++#define __NR_readv 145 ++#define __NR_writev 146 ++#define __NR_getsid 147 ++#define __NR_fdatasync 148 ++#define __NR__sysctl 149 ++#define __NR_mlock 150 ++#define __NR_munlock 151 ++#define __NR_mlockall 152 ++#define __NR_munlockall 153 ++#define __NR_sched_setparam 154 ++#define __NR_sched_getparam 155 ++#define __NR_sched_setscheduler 156 ++#define __NR_sched_getscheduler 157 ++#define __NR_sched_yield 158 ++#define __NR_sched_get_priority_max 159 ++#define __NR_sched_get_priority_min 160 ++#define __NR_sched_rr_get_interval 161 ++#define __NR_nanosleep 162 ++#define __NR_mremap 163 ++#define __NR_setresuid 164 ++#define __NR_getresuid 165 ++#define __NR_getpagesize 166 ++#define __NR_query_module 167 ++#define __NR_poll 168 ++#define __NR_nfsservctl 169 ++#define __NR_setresgid 170 ++#define __NR_getresgid 171 ++#define __NR_prctl 172 ++#define __NR_rt_sigreturn 173 ++#define __NR_rt_sigaction 174 ++#define __NR_rt_sigprocmask 175 ++#define __NR_rt_sigpending 176 ++#define __NR_rt_sigtimedwait 177 ++#define __NR_rt_sigqueueinfo 178 ++#define __NR_rt_sigsuspend 179 ++#define __NR_pread64 180 ++#define __NR_pwrite64 181 ++#define __NR_lchown 182 ++#define __NR_getcwd 183 ++#define __NR_capget 184 ++#define __NR_capset 185 ++#define __NR_sigaltstack 186 ++#define __NR_sendfile 187 ++#define __NR_getpmsg 188 /* some people actually want streams */ ++#define __NR_putpmsg 189 /* some people actually want streams */ ++#define __NR_vfork 190 ++#define __NR_ugetrlimit 191 ++#define __NR_mmap2 192 ++#define __NR_truncate64 193 ++#define __NR_ftruncate64 194 ++#define __NR_stat64 195 ++#define __NR_lstat64 196 ++#define __NR_fstat64 197 ++#define __NR_chown32 198 ++#define __NR_getuid32 199 ++#define __NR_getgid32 200 ++#define __NR_geteuid32 201 ++#define __NR_getegid32 202 ++#define __NR_setreuid32 203 ++#define __NR_setregid32 204 ++#define __NR_getgroups32 205 ++#define __NR_setgroups32 206 ++#define __NR_fchown32 207 ++#define __NR_setresuid32 208 ++#define __NR_getresuid32 209 ++#define __NR_setresgid32 210 ++#define __NR_getresgid32 211 ++#define __NR_lchown32 212 ++#define __NR_setuid32 213 ++#define __NR_setgid32 214 ++#define __NR_setfsuid32 215 ++#define __NR_setfsgid32 216 ++#define __NR_pivot_root 217 ++#define __NR_getdents64 220 ++#define __NR_gettid 221 ++#define __NR_tkill 222 ++#define __NR_setxattr 223 ++#define __NR_lsetxattr 224 ++#define __NR_fsetxattr 225 ++#define __NR_getxattr 226 ++#define __NR_lgetxattr 227 ++#define __NR_fgetxattr 228 ++#define __NR_listxattr 229 ++#define __NR_llistxattr 230 ++#define __NR_flistxattr 231 ++#define __NR_removexattr 232 ++#define __NR_lremovexattr 233 ++#define __NR_fremovexattr 234 ++#define __NR_futex 235 ++#define __NR_sendfile64 236 ++#define __NR_mincore 237 ++#define __NR_madvise 238 ++#define __NR_fcntl64 239 ++#define __NR_readahead 240 ++#define __NR_io_setup 241 ++#define __NR_io_destroy 242 ++#define __NR_io_getevents 243 ++#define __NR_io_submit 244 ++#define __NR_io_cancel 245 ++#define __NR_fadvise64 246 ++#define __NR_exit_group 247 ++#define __NR_lookup_dcookie 248 ++#define __NR_epoll_create 249 ++#define __NR_epoll_ctl 250 ++#define __NR_epoll_wait 251 ++#define __NR_remap_file_pages 252 ++#define __NR_set_tid_address 253 ++#define __NR_timer_create 254 ++#define __NR_timer_settime 255 ++#define __NR_timer_gettime 256 ++#define __NR_timer_getoverrun 257 ++#define __NR_timer_delete 258 ++#define __NR_clock_settime 259 ++#define __NR_clock_gettime 260 ++#define __NR_clock_getres 261 ++#define __NR_clock_nanosleep 262 ++#define __NR_statfs64 263 ++#define __NR_fstatfs64 264 ++#define __NR_tgkill 265 ++#define __NR_utimes 266 ++#define __NR_fadvise64_64 267 ++#define __NR_mbind 268 ++#define __NR_get_mempolicy 269 ++#define __NR_set_mempolicy 270 ++#define __NR_mq_open 271 ++#define __NR_mq_unlink 272 ++#define __NR_mq_timedsend 273 ++#define __NR_mq_timedreceive 274 ++#define __NR_mq_notify 275 ++#define __NR_mq_getsetattr 276 ++#define __NR_waitid 277 ++#define __NR_vserver 278 ++#define __NR_add_key 279 ++#define __NR_request_key 280 ++#define __NR_keyctl 281 ++#define __NR_ioprio_set 282 ++#define __NR_ioprio_get 283 ++#define __NR_inotify_init 284 ++#define __NR_inotify_add_watch 285 ++#define __NR_inotify_rm_watch 286 ++#define __NR_migrate_pages 287 ++#define __NR_openat 288 ++#define __NR_mkdirat 289 ++#define __NR_mknodat 290 ++#define __NR_fchownat 291 ++#define __NR_futimesat 292 ++#define __NR_fstatat64 293 ++#define __NR_unlinkat 294 ++#define __NR_renameat 295 ++#define __NR_linkat 296 ++#define __NR_symlinkat 297 ++#define __NR_readlinkat 298 ++#define __NR_fchmodat 299 ++#define __NR_faccessat 300 ++#define __NR_pselect6 301 ++#define __NR_ppoll 302 ++#define __NR_unshare 303 ++#define __NR_set_robust_list 304 ++#define __NR_get_robust_list 305 ++#define __NR_splice 306 ++#define __NR_sync_file_range 307 ++#define __NR_tee 308 ++#define __NR_vmsplice 309 ++#define __NR_move_pages 310 ++#define __NR_sched_setaffinity 311 ++#define __NR_sched_getaffinity 312 ++#define __NR_kexec_load 313 ++#define __NR_getcpu 314 ++#define __NR_epoll_pwait 315 ++#define __NR_utimensat 316 ++#define __NR_signalfd 317 ++#define __NR_timerfd_create 318 ++#define __NR_eventfd 319 ++#define __NR_fallocate 320 ++#define __NR_timerfd_settime 321 ++#define __NR_timerfd_gettime 322 ++#define __NR_signalfd4 323 ++#define __NR_eventfd2 324 ++#define __NR_epoll_create1 325 ++#define __NR_dup3 326 ++#define __NR_pipe2 327 ++#define __NR_inotify_init1 328 ++ ++#ifdef __KERNEL__ ++ ++#define NR_syscalls 329 ++ ++#define __ARCH_WANT_IPC_PARSE_VERSION ++#define __ARCH_WANT_OLD_READDIR ++#define __ARCH_WANT_OLD_STAT ++#define __ARCH_WANT_STAT64 ++#define __ARCH_WANT_SYS_ALARM ++#define __ARCH_WANT_SYS_GETHOSTNAME ++#define __ARCH_WANT_SYS_PAUSE ++#define __ARCH_WANT_SYS_SGETMASK ++#define __ARCH_WANT_SYS_SIGNAL ++#define __ARCH_WANT_SYS_TIME ++#define __ARCH_WANT_SYS_UTIME ++#define __ARCH_WANT_SYS_WAITPID ++#define __ARCH_WANT_SYS_SOCKETCALL ++#define __ARCH_WANT_SYS_FADVISE64 ++#define __ARCH_WANT_SYS_GETPGRP ++#define __ARCH_WANT_SYS_LLSEEK ++#define __ARCH_WANT_SYS_NICE ++#define __ARCH_WANT_SYS_OLD_GETRLIMIT ++#define __ARCH_WANT_SYS_OLDUMOUNT ++#define __ARCH_WANT_SYS_SIGPENDING ++#define __ARCH_WANT_SYS_SIGPROCMASK ++#define __ARCH_WANT_SYS_RT_SIGACTION ++ ++/* ++ * "Conditional" syscalls ++ * ++ * What we want is __attribute__((weak,alias("sys_ni_syscall"))), ++ * but it doesn't work on all toolchains, so we just do it by hand ++ */ ++#define cond_syscall(x) asm(".weak\t" #x "\n\t.set\t" #x ",sys_ni_syscall") ++ ++#endif /* __KERNEL__ */ ++#endif /* _ASM_M68K_UNISTD_H_ */ +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/arch/m68k/include/asm/unistd_no.h linux-2.6.29-rc3.owrt/arch/m68k/include/asm/unistd_no.h +--- linux-2.6.29.owrt/arch/m68k/include/asm/unistd_no.h 1970-01-01 01:00:00.000000000 +0100 ++++ linux-2.6.29-rc3.owrt/arch/m68k/include/asm/unistd_no.h 2009-05-10 23:48:28.000000000 +0200 +@@ -0,0 +1,372 @@ ++#ifndef _ASM_M68K_UNISTD_H_ ++#define _ASM_M68K_UNISTD_H_ ++ ++/* ++ * This file contains the system call numbers. ++ */ ++ ++#define __NR_restart_syscall 0 ++#define __NR_exit 1 ++#define __NR_fork 2 ++#define __NR_read 3 ++#define __NR_write 4 ++#define __NR_open 5 ++#define __NR_close 6 ++#define __NR_waitpid 7 ++#define __NR_creat 8 ++#define __NR_link 9 ++#define __NR_unlink 10 ++#define __NR_execve 11 ++#define __NR_chdir 12 ++#define __NR_time 13 ++#define __NR_mknod 14 ++#define __NR_chmod 15 ++#define __NR_chown 16 ++#define __NR_break 17 ++#define __NR_oldstat 18 ++#define __NR_lseek 19 ++#define __NR_getpid 20 ++#define __NR_mount 21 ++#define __NR_umount 22 ++#define __NR_setuid 23 ++#define __NR_getuid 24 ++#define __NR_stime 25 ++#define __NR_ptrace 26 ++#define __NR_alarm 27 ++#define __NR_oldfstat 28 ++#define __NR_pause 29 ++#define __NR_utime 30 ++#define __NR_stty 31 ++#define __NR_gtty 32 ++#define __NR_access 33 ++#define __NR_nice 34 ++#define __NR_ftime 35 ++#define __NR_sync 36 ++#define __NR_kill 37 ++#define __NR_rename 38 ++#define __NR_mkdir 39 ++#define __NR_rmdir 40 ++#define __NR_dup 41 ++#define __NR_pipe 42 ++#define __NR_times 43 ++#define __NR_prof 44 ++#define __NR_brk 45 ++#define __NR_setgid 46 ++#define __NR_getgid 47 ++#define __NR_signal 48 ++#define __NR_geteuid 49 ++#define __NR_getegid 50 ++#define __NR_acct 51 ++#define __NR_umount2 52 ++#define __NR_lock 53 ++#define __NR_ioctl 54 ++#define __NR_fcntl 55 ++#define __NR_mpx 56 ++#define __NR_setpgid 57 ++#define __NR_ulimit 58 ++#define __NR_oldolduname 59 ++#define __NR_umask 60 ++#define __NR_chroot 61 ++#define __NR_ustat 62 ++#define __NR_dup2 63 ++#define __NR_getppid 64 ++#define __NR_getpgrp 65 ++#define __NR_setsid 66 ++#define __NR_sigaction 67 ++#define __NR_sgetmask 68 ++#define __NR_ssetmask 69 ++#define __NR_setreuid 70 ++#define __NR_setregid 71 ++#define __NR_sigsuspend 72 ++#define __NR_sigpending 73 ++#define __NR_sethostname 74 ++#define __NR_setrlimit 75 ++#define __NR_getrlimit 76 ++#define __NR_getrusage 77 ++#define __NR_gettimeofday 78 ++#define __NR_settimeofday 79 ++#define __NR_getgroups 80 ++#define __NR_setgroups 81 ++#define __NR_select 82 ++#define __NR_symlink 83 ++#define __NR_oldlstat 84 ++#define __NR_readlink 85 ++#define __NR_uselib 86 ++#define __NR_swapon 87 ++#define __NR_reboot 88 ++#define __NR_readdir 89 ++#define __NR_mmap 90 ++#define __NR_munmap 91 ++#define __NR_truncate 92 ++#define __NR_ftruncate 93 ++#define __NR_fchmod 94 ++#define __NR_fchown 95 ++#define __NR_getpriority 96 ++#define __NR_setpriority 97 ++#define __NR_profil 98 ++#define __NR_statfs 99 ++#define __NR_fstatfs 100 ++#define __NR_ioperm 101 ++#define __NR_socketcall 102 ++#define __NR_syslog 103 ++#define __NR_setitimer 104 ++#define __NR_getitimer 105 ++#define __NR_stat 106 ++#define __NR_lstat 107 ++#define __NR_fstat 108 ++#define __NR_olduname 109 ++#define __NR_iopl /* 110 */ not supported ++#define __NR_vhangup 111 ++#define __NR_idle /* 112 */ Obsolete ++#define __NR_vm86 /* 113 */ not supported ++#define __NR_wait4 114 ++#define __NR_swapoff 115 ++#define __NR_sysinfo 116 ++#define __NR_ipc 117 ++#define __NR_fsync 118 ++#define __NR_sigreturn 119 ++#define __NR_clone 120 ++#define __NR_setdomainname 121 ++#define __NR_uname 122 ++#define __NR_cacheflush 123 ++#define __NR_adjtimex 124 ++#define __NR_mprotect 125 ++#define __NR_sigprocmask 126 ++#define __NR_create_module 127 ++#define __NR_init_module 128 ++#define __NR_delete_module 129 ++#define __NR_get_kernel_syms 130 ++#define __NR_quotactl 131 ++#define __NR_getpgid 132 ++#define __NR_fchdir 133 ++#define __NR_bdflush 134 ++#define __NR_sysfs 135 ++#define __NR_personality 136 ++#define __NR_afs_syscall 137 /* Syscall for Andrew File System */ ++#define __NR_setfsuid 138 ++#define __NR_setfsgid 139 ++#define __NR__llseek 140 ++#define __NR_getdents 141 ++#define __NR__newselect 142 ++#define __NR_flock 143 ++#define __NR_msync 144 ++#define __NR_readv 145 ++#define __NR_writev 146 ++#define __NR_getsid 147 ++#define __NR_fdatasync 148 ++#define __NR__sysctl 149 ++#define __NR_mlock 150 ++#define __NR_munlock 151 ++#define __NR_mlockall 152 ++#define __NR_munlockall 153 ++#define __NR_sched_setparam 154 ++#define __NR_sched_getparam 155 ++#define __NR_sched_setscheduler 156 ++#define __NR_sched_getscheduler 157 ++#define __NR_sched_yield 158 ++#define __NR_sched_get_priority_max 159 ++#define __NR_sched_get_priority_min 160 ++#define __NR_sched_rr_get_interval 161 ++#define __NR_nanosleep 162 ++#define __NR_mremap 163 ++#define __NR_setresuid 164 ++#define __NR_getresuid 165 ++#define __NR_getpagesize 166 ++#define __NR_query_module 167 ++#define __NR_poll 168 ++#define __NR_nfsservctl 169 ++#define __NR_setresgid 170 ++#define __NR_getresgid 171 ++#define __NR_prctl 172 ++#define __NR_rt_sigreturn 173 ++#define __NR_rt_sigaction 174 ++#define __NR_rt_sigprocmask 175 ++#define __NR_rt_sigpending 176 ++#define __NR_rt_sigtimedwait 177 ++#define __NR_rt_sigqueueinfo 178 ++#define __NR_rt_sigsuspend 179 ++#define __NR_pread64 180 ++#define __NR_pwrite64 181 ++#define __NR_lchown 182 ++#define __NR_getcwd 183 ++#define __NR_capget 184 ++#define __NR_capset 185 ++#define __NR_sigaltstack 186 ++#define __NR_sendfile 187 ++#define __NR_getpmsg 188 /* some people actually want streams */ ++#define __NR_putpmsg 189 /* some people actually want streams */ ++#define __NR_vfork 190 ++#define __NR_ugetrlimit 191 ++#define __NR_mmap2 192 ++#define __NR_truncate64 193 ++#define __NR_ftruncate64 194 ++#define __NR_stat64 195 ++#define __NR_lstat64 196 ++#define __NR_fstat64 197 ++#define __NR_chown32 198 ++#define __NR_getuid32 199 ++#define __NR_getgid32 200 ++#define __NR_geteuid32 201 ++#define __NR_getegid32 202 ++#define __NR_setreuid32 203 ++#define __NR_setregid32 204 ++#define __NR_getgroups32 205 ++#define __NR_setgroups32 206 ++#define __NR_fchown32 207 ++#define __NR_setresuid32 208 ++#define __NR_getresuid32 209 ++#define __NR_setresgid32 210 ++#define __NR_getresgid32 211 ++#define __NR_lchown32 212 ++#define __NR_setuid32 213 ++#define __NR_setgid32 214 ++#define __NR_setfsuid32 215 ++#define __NR_setfsgid32 216 ++#define __NR_pivot_root 217 ++#define __NR_getdents64 220 ++#define __NR_gettid 221 ++#define __NR_tkill 222 ++#define __NR_setxattr 223 ++#define __NR_lsetxattr 224 ++#define __NR_fsetxattr 225 ++#define __NR_getxattr 226 ++#define __NR_lgetxattr 227 ++#define __NR_fgetxattr 228 ++#define __NR_listxattr 229 ++#define __NR_llistxattr 230 ++#define __NR_flistxattr 231 ++#define __NR_removexattr 232 ++#define __NR_lremovexattr 233 ++#define __NR_fremovexattr 234 ++#define __NR_futex 235 ++#define __NR_sendfile64 236 ++#define __NR_mincore 237 ++#define __NR_madvise 238 ++#define __NR_fcntl64 239 ++#define __NR_readahead 240 ++#define __NR_io_setup 241 ++#define __NR_io_destroy 242 ++#define __NR_io_getevents 243 ++#define __NR_io_submit 244 ++#define __NR_io_cancel 245 ++#define __NR_fadvise64 246 ++#define __NR_exit_group 247 ++#define __NR_lookup_dcookie 248 ++#define __NR_epoll_create 249 ++#define __NR_epoll_ctl 250 ++#define __NR_epoll_wait 251 ++#define __NR_remap_file_pages 252 ++#define __NR_set_tid_address 253 ++#define __NR_timer_create 254 ++#define __NR_timer_settime 255 ++#define __NR_timer_gettime 256 ++#define __NR_timer_getoverrun 257 ++#define __NR_timer_delete 258 ++#define __NR_clock_settime 259 ++#define __NR_clock_gettime 260 ++#define __NR_clock_getres 261 ++#define __NR_clock_nanosleep 262 ++#define __NR_statfs64 263 ++#define __NR_fstatfs64 264 ++#define __NR_tgkill 265 ++#define __NR_utimes 266 ++#define __NR_fadvise64_64 267 ++#define __NR_mbind 268 ++#define __NR_get_mempolicy 269 ++#define __NR_set_mempolicy 270 ++#define __NR_mq_open 271 ++#define __NR_mq_unlink 272 ++#define __NR_mq_timedsend 273 ++#define __NR_mq_timedreceive 274 ++#define __NR_mq_notify 275 ++#define __NR_mq_getsetattr 276 ++#define __NR_waitid 277 ++#define __NR_vserver 278 ++#define __NR_add_key 279 ++#define __NR_request_key 280 ++#define __NR_keyctl 281 ++#define __NR_ioprio_set 282 ++#define __NR_ioprio_get 283 ++#define __NR_inotify_init 284 ++#define __NR_inotify_add_watch 285 ++#define __NR_inotify_rm_watch 286 ++#define __NR_migrate_pages 287 ++#define __NR_openat 288 ++#define __NR_mkdirat 289 ++#define __NR_mknodat 290 ++#define __NR_fchownat 291 ++#define __NR_futimesat 292 ++#define __NR_fstatat64 293 ++#define __NR_unlinkat 294 ++#define __NR_renameat 295 ++#define __NR_linkat 296 ++#define __NR_symlinkat 297 ++#define __NR_readlinkat 298 ++#define __NR_fchmodat 299 ++#define __NR_faccessat 300 ++#define __NR_pselect6 301 ++#define __NR_ppoll 302 ++#define __NR_unshare 303 ++#define __NR_set_robust_list 304 ++#define __NR_get_robust_list 305 ++#define __NR_splice 306 ++#define __NR_sync_file_range 307 ++#define __NR_tee 308 ++#define __NR_vmsplice 309 ++#define __NR_move_pages 310 ++#define __NR_sched_setaffinity 311 ++#define __NR_sched_getaffinity 312 ++#define __NR_kexec_load 313 ++#define __NR_getcpu 314 ++#define __NR_epoll_pwait 315 ++#define __NR_utimensat 316 ++#define __NR_signalfd 317 ++#define __NR_timerfd_create 318 ++#define __NR_eventfd 319 ++#define __NR_fallocate 320 ++#define __NR_timerfd_settime 321 ++#define __NR_timerfd_gettime 322 ++#define __NR_signalfd4 323 ++#define __NR_eventfd2 324 ++#define __NR_epoll_create1 325 ++#define __NR_dup3 326 ++#define __NR_pipe2 327 ++#define __NR_inotify_init1 328 ++ ++#ifdef __KERNEL__ ++ ++#define NR_syscalls 329 ++ ++#define __ARCH_WANT_IPC_PARSE_VERSION ++#define __ARCH_WANT_OLD_READDIR ++#define __ARCH_WANT_OLD_STAT ++#define __ARCH_WANT_STAT64 ++#define __ARCH_WANT_SYS_ALARM ++#define __ARCH_WANT_SYS_GETHOSTNAME ++#define __ARCH_WANT_SYS_PAUSE ++#define __ARCH_WANT_SYS_SGETMASK ++#define __ARCH_WANT_SYS_SIGNAL ++#define __ARCH_WANT_SYS_TIME ++#define __ARCH_WANT_SYS_UTIME ++#define __ARCH_WANT_SYS_WAITPID ++#define __ARCH_WANT_SYS_SOCKETCALL ++#define __ARCH_WANT_SYS_FADVISE64 ++#define __ARCH_WANT_SYS_GETPGRP ++#define __ARCH_WANT_SYS_LLSEEK ++#define __ARCH_WANT_SYS_NICE ++#define __ARCH_WANT_SYS_OLD_GETRLIMIT ++#define __ARCH_WANT_SYS_OLDUMOUNT ++#define __ARCH_WANT_SYS_SIGPENDING ++#define __ARCH_WANT_SYS_SIGPROCMASK ++#define __ARCH_WANT_SYS_RT_SIGACTION ++ ++/* ++ * "Conditional" syscalls ++ * ++ * What we want is __attribute__((weak,alias("sys_ni_syscall"))), ++ * but it doesn't work on all toolchains, so we just do it by hand ++ */ ++#define cond_syscall(x) asm(".weak\t" #x "\n\t.set\t" #x ",sys_ni_syscall") ++ ++#endif /* __KERNEL__ */ ++#endif /* _ASM_M68K_UNISTD_H_ */ +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/arch/m68knommu/platform/5206e/config.c linux-2.6.29-rc3.owrt/arch/m68knommu/platform/5206e/config.c +--- linux-2.6.29.owrt/arch/m68knommu/platform/5206e/config.c 2009-05-10 22:04:41.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/arch/m68knommu/platform/5206e/config.c 2009-05-10 23:48:28.000000000 +0200 +@@ -17,7 +17,6 @@ + #include <asm/coldfire.h> + #include <asm/mcfsim.h> + #include <asm/mcfdma.h> +-#include <asm/mcfuart.h> + + /***************************************************************************/ + +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/arch/m68knommu/platform/528x/config.c linux-2.6.29-rc3.owrt/arch/m68knommu/platform/528x/config.c +--- linux-2.6.29.owrt/arch/m68knommu/platform/528x/config.c 2009-05-10 22:04:41.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/arch/m68knommu/platform/528x/config.c 2009-05-10 23:48:28.000000000 +0200 +@@ -24,6 +24,7 @@ + #include <asm/coldfire.h> + #include <asm/mcfsim.h> + #include <asm/mcfuart.h> ++#include <asm/mcfqspi.h> + + #ifdef CONFIG_MTD_PARTITIONS + #include <linux/mtd/partitions.h> +@@ -32,6 +33,233 @@ + /***************************************************************************/ + + void coldfire_reset(void); ++static void coldfire_qspi_cs_control(u8 cs, u8 command); ++ ++/***************************************************************************/ ++ ++#if defined(CONFIG_SPI) ++ ++#if defined(CONFIG_WILDFIRE) ++#define SPI_NUM_CHIPSELECTS 0x02 ++#define SPI_PAR_VAL 0x07 /* Enable DIN, DOUT, CLK */ ++#define SPI_CS_MASK 0x18 ++ ++#define FLASH_BLOCKSIZE (1024*64) ++#define FLASH_NUMBLOCKS 16 ++#define FLASH_TYPE "m25p80" ++ ++#define M25P80_CS 0 ++#define MMC_CS 1 ++ ++#ifdef CONFIG_MTD_PARTITIONS ++static struct mtd_partition stm25p_partitions[] = { ++ /* sflash */ ++ [0] = { ++ .name = "stm25p80", ++ .offset = 0x00000000, ++ .size = FLASH_BLOCKSIZE * FLASH_NUMBLOCKS, ++ .mask_flags = 0 ++ } ++}; ++ ++#endif ++ ++#elif defined(CONFIG_WILDFIREMOD) ++ ++#define SPI_NUM_CHIPSELECTS 0x08 ++#define SPI_PAR_VAL 0x07 /* Enable DIN, DOUT, CLK */ ++#define SPI_CS_MASK 0x78 ++ ++#define FLASH_BLOCKSIZE (1024*64) ++#define FLASH_NUMBLOCKS 64 ++#define FLASH_TYPE "m25p32" ++/* Reserve 1M for the kernel parition */ ++#define FLASH_KERNEL_SIZE (1024 * 1024) ++ ++#define M25P80_CS 5 ++#define MMC_CS 6 ++ ++#ifdef CONFIG_MTD_PARTITIONS ++static struct mtd_partition stm25p_partitions[] = { ++ /* sflash */ ++ [0] = { ++ .name = "kernel", ++ .offset = FLASH_BLOCKSIZE * FLASH_NUMBLOCKS - FLASH_KERNEL_SIZE, ++ .size = FLASH_KERNEL_SIZE, ++ .mask_flags = 0 ++ }, ++ [1] = { ++ .name = "image", ++ .offset = 0x00000000, ++ .size = FLASH_BLOCKSIZE * FLASH_NUMBLOCKS - FLASH_KERNEL_SIZE, ++ .mask_flags = 0 ++ }, ++ [2] = { ++ .name = "all", ++ .offset = 0x00000000, ++ .size = FLASH_BLOCKSIZE * FLASH_NUMBLOCKS, ++ .mask_flags = 0 ++ } ++}; ++#endif ++ ++#else ++#define SPI_NUM_CHIPSELECTS 0x04 ++#define SPI_PAR_VAL 0x7F /* Enable DIN, DOUT, CLK, CS0 - CS4 */ ++#endif ++ ++#ifdef MMC_CS ++static struct coldfire_spi_chip flash_chip_info = { ++ .mode = SPI_MODE_0, ++ .bits_per_word = 16, ++ .del_cs_to_clk = 17, ++ .del_after_trans = 1, ++ .void_write_data = 0 ++}; ++ ++static struct coldfire_spi_chip mmc_chip_info = { ++ .mode = SPI_MODE_0, ++ .bits_per_word = 16, ++ .del_cs_to_clk = 17, ++ .del_after_trans = 1, ++ .void_write_data = 0xFFFF ++}; ++#endif ++ ++#ifdef M25P80_CS ++static struct flash_platform_data stm25p80_platform_data = { ++ .name = "ST M25P80 SPI Flash chip", ++#ifdef CONFIG_MTD_PARTITIONS ++ .parts = stm25p_partitions, ++ .nr_parts = sizeof(stm25p_partitions) / sizeof(*stm25p_partitions), ++#endif ++ .type = FLASH_TYPE ++}; ++#endif ++ ++static struct spi_board_info spi_board_info[] __initdata = { ++#ifdef M25P80_CS ++ { ++ .modalias = "m25p80", ++ .max_speed_hz = 16000000, ++ .bus_num = 1, ++ .chip_select = M25P80_CS, ++ .platform_data = &stm25p80_platform_data, ++ .controller_data = &flash_chip_info ++ }, ++#endif ++#ifdef MMC_CS ++ { ++ .modalias = "mmc_spi", ++ .max_speed_hz = 16000000, ++ .bus_num = 1, ++ .chip_select = MMC_CS, ++ .controller_data = &mmc_chip_info ++ } ++#endif ++}; ++ ++static struct coldfire_spi_master coldfire_master_info = { ++ .bus_num = 1, ++ .num_chipselect = SPI_NUM_CHIPSELECTS, ++ .irq_source = MCF5282_QSPI_IRQ_SOURCE, ++ .irq_vector = MCF5282_QSPI_IRQ_VECTOR, ++ .irq_mask = ((0x01 << MCF5282_QSPI_IRQ_SOURCE) | 0x01), ++ .irq_lp = 0x2B, /* Level 5 and Priority 3 */ ++ .par_val = SPI_PAR_VAL, ++ .cs_control = coldfire_qspi_cs_control, ++}; ++ ++static struct resource coldfire_spi_resources[] = { ++ [0] = { ++ .name = "qspi-par", ++ .start = MCF5282_QSPI_PAR, ++ .end = MCF5282_QSPI_PAR, ++ .flags = IORESOURCE_MEM ++ }, ++ ++ [1] = { ++ .name = "qspi-module", ++ .start = MCF5282_QSPI_QMR, ++ .end = MCF5282_QSPI_QMR + 0x18, ++ .flags = IORESOURCE_MEM ++ }, ++ ++ [2] = { ++ .name = "qspi-int-level", ++ .start = MCF5282_INTC0 + MCFINTC_ICR0 + MCF5282_QSPI_IRQ_SOURCE, ++ .end = MCF5282_INTC0 + MCFINTC_ICR0 + MCF5282_QSPI_IRQ_SOURCE, ++ .flags = IORESOURCE_MEM ++ }, ++ ++ [3] = { ++ .name = "qspi-int-mask", ++ .start = MCF5282_INTC0 + MCFINTC_IMRL, ++ .end = MCF5282_INTC0 + MCFINTC_IMRL, ++ .flags = IORESOURCE_MEM ++ } ++}; ++ ++static struct platform_device coldfire_spi = { ++ .name = "spi_coldfire", ++ .id = -1, ++ .resource = coldfire_spi_resources, ++ .num_resources = ARRAY_SIZE(coldfire_spi_resources), ++ .dev = { ++ .platform_data = &coldfire_master_info, ++ } ++}; ++ ++static void coldfire_qspi_cs_control(u8 cs, u8 command) ++{ ++ u8 cs_bit = ((0x01 << cs) << 3) & SPI_CS_MASK; ++ ++#if defined(CONFIG_WILDFIRE) ++ u8 cs_mask = ~(((0x01 << cs) << 3) & SPI_CS_MASK); ++#endif ++#if defined(CONFIG_WILDFIREMOD) ++ u8 cs_mask = (cs << 3) & SPI_CS_MASK; ++#endif ++ ++ /* ++ * Don't do anything if the chip select is not ++ * one of the port qs pins. ++ */ ++ if (command & QSPI_CS_INIT) { ++#if defined(CONFIG_WILDFIRE) ++ MCF5282_GPIO_DDRQS |= cs_bit; ++ MCF5282_GPIO_PQSPAR &= ~cs_bit; ++#endif ++ ++#if defined(CONFIG_WILDFIREMOD) ++ MCF5282_GPIO_DDRQS |= SPI_CS_MASK; ++ MCF5282_GPIO_PQSPAR &= ~SPI_CS_MASK; ++#endif ++ } ++ ++ if (command & QSPI_CS_ASSERT) { ++ MCF5282_GPIO_PORTQS &= ~SPI_CS_MASK; ++ MCF5282_GPIO_PORTQS |= cs_mask; ++ } else if (command & QSPI_CS_DROP) { ++ MCF5282_GPIO_PORTQS |= SPI_CS_MASK; ++ } ++} ++ ++static int __init spi_dev_init(void) ++{ ++ int retval; ++ ++ retval = platform_device_register(&coldfire_spi); ++ if (retval < 0) ++ return retval; ++ ++ if (ARRAY_SIZE(spi_board_info)) ++ retval = spi_register_board_info(spi_board_info, ARRAY_SIZE(spi_board_info)); ++ ++ return retval; ++} ++ ++#endif /* CONFIG_SPI */ + + /***************************************************************************/ + +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/arch/mips/alchemy/common/time.c linux-2.6.29-rc3.owrt/arch/mips/alchemy/common/time.c +--- linux-2.6.29.owrt/arch/mips/alchemy/common/time.c 2009-05-10 22:04:40.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/arch/mips/alchemy/common/time.c 2009-05-10 23:48:28.000000000 +0200 +@@ -89,7 +89,7 @@ + .irq = AU1000_RTC_MATCH2_INT, + .set_next_event = au1x_rtcmatch2_set_next_event, + .set_mode = au1x_rtcmatch2_set_mode, +- .cpumask = CPU_MASK_ALL_PTR, ++ .cpumask = CPU_MASK_ALL, + }; + + static struct irqaction au1x_rtcmatch2_irqaction = { +@@ -118,7 +118,7 @@ + * setup counter 1 (RTC) to tick at full speed + */ + t = 0xffffff; +- while ((au_readl(SYS_COUNTER_CNTRL) & SYS_CNTRL_T1S) && --t) ++ while ((au_readl(SYS_COUNTER_CNTRL) & SYS_CNTRL_T1S) && t--) + asm volatile ("nop"); + if (!t) + goto cntr_err; +@@ -127,7 +127,7 @@ + au_sync(); + + t = 0xffffff; +- while ((au_readl(SYS_COUNTER_CNTRL) & SYS_CNTRL_C1S) && --t) ++ while ((au_readl(SYS_COUNTER_CNTRL) & SYS_CNTRL_C1S) && t--) + asm volatile ("nop"); + if (!t) + goto cntr_err; +@@ -135,7 +135,7 @@ + au_sync(); + + t = 0xffffff; +- while ((au_readl(SYS_COUNTER_CNTRL) & SYS_CNTRL_C1S) && --t) ++ while ((au_readl(SYS_COUNTER_CNTRL) & SYS_CNTRL_C1S) && t--) + asm volatile ("nop"); + if (!t) + goto cntr_err; +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/arch/mips/cavium-octeon/setup.c linux-2.6.29-rc3.owrt/arch/mips/cavium-octeon/setup.c +--- linux-2.6.29.owrt/arch/mips/cavium-octeon/setup.c 2009-05-10 22:04:40.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/arch/mips/cavium-octeon/setup.c 2009-05-10 23:48:28.000000000 +0200 +@@ -15,11 +15,13 @@ + #include <linux/serial.h> + #include <linux/types.h> + #include <linux/string.h> /* for memset */ ++#include <linux/serial.h> + #include <linux/tty.h> + #include <linux/time.h> + #include <linux/platform_device.h> + #include <linux/serial_core.h> + #include <linux/serial_8250.h> ++#include <linux/string.h> + + #include <asm/processor.h> + #include <asm/reboot.h> +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/arch/mips/configs/emma2rh_defconfig linux-2.6.29-rc3.owrt/arch/mips/configs/emma2rh_defconfig +--- linux-2.6.29.owrt/arch/mips/configs/emma2rh_defconfig 1970-01-01 01:00:00.000000000 +0100 ++++ linux-2.6.29-rc3.owrt/arch/mips/configs/emma2rh_defconfig 2009-05-10 23:48:28.000000000 +0200 +@@ -0,0 +1,1439 @@ ++# ++# Automatically generated make config: don't edit ++# Linux kernel version: 2.6.20 ++# Tue Feb 20 21:47:29 2007 ++# ++CONFIG_MIPS=y ++ ++# ++# Machine selection ++# ++CONFIG_ZONE_DMA=y ++# CONFIG_MIPS_MTX1 is not set ++# CONFIG_MIPS_BOSPORUS is not set ++# CONFIG_MIPS_PB1000 is not set ++# CONFIG_MIPS_PB1100 is not set ++# CONFIG_MIPS_PB1500 is not set ++# CONFIG_MIPS_PB1550 is not set ++# CONFIG_MIPS_PB1200 is not set ++# CONFIG_MIPS_DB1000 is not set ++# CONFIG_MIPS_DB1100 is not set ++# CONFIG_MIPS_DB1500 is not set ++# CONFIG_MIPS_DB1550 is not set ++# CONFIG_MIPS_DB1200 is not set ++# CONFIG_MIPS_MIRAGE is not set ++# CONFIG_BASLER_EXCITE is not set ++# CONFIG_MIPS_COBALT is not set ++# CONFIG_MACH_DECSTATION is not set ++# CONFIG_MACH_JAZZ is not set ++# CONFIG_MIPS_MALTA is not set ++# CONFIG_WR_PPMC is not set ++# CONFIG_MIPS_SIM is not set ++# CONFIG_MOMENCO_JAGUAR_ATX is not set ++# CONFIG_MIPS_XXS1500 is not set ++# CONFIG_PNX8550_JBS is not set ++# CONFIG_PNX8550_STB810 is not set ++# CONFIG_MACH_VR41XX is not set ++# CONFIG_PMC_YOSEMITE is not set ++CONFIG_MARKEINS=y ++# CONFIG_SGI_IP22 is not set ++# CONFIG_SGI_IP27 is not set ++# CONFIG_SGI_IP32 is not set ++# CONFIG_SIBYTE_BIGSUR is not set ++# CONFIG_SIBYTE_SWARM is not set ++# CONFIG_SIBYTE_SENTOSA is not set ++# CONFIG_SIBYTE_RHONE is not set ++# CONFIG_SIBYTE_CARMEL is not set ++# CONFIG_SIBYTE_LITTLESUR is not set ++# CONFIG_SIBYTE_CRHINE is not set ++# CONFIG_SIBYTE_CRHONE is not set ++# CONFIG_SNI_RM is not set ++# CONFIG_TOSHIBA_JMR3927 is not set ++# CONFIG_TOSHIBA_RBTX4927 is not set ++# CONFIG_TOSHIBA_RBTX4938 is not set ++CONFIG_RWSEM_GENERIC_SPINLOCK=y ++# CONFIG_ARCH_HAS_ILOG2_U32 is not set ++# CONFIG_ARCH_HAS_ILOG2_U64 is not set ++CONFIG_GENERIC_FIND_NEXT_BIT=y ++CONFIG_GENERIC_HWEIGHT=y ++CONFIG_GENERIC_CALIBRATE_DELAY=y ++CONFIG_GENERIC_TIME=y ++CONFIG_SCHED_NO_NO_OMIT_FRAME_POINTER=y ++# CONFIG_GENERIC_HARDIRQS_NO__DO_IRQ is not set ++CONFIG_DMA_NONCOHERENT=y ++CONFIG_DMA_NEED_PCI_MAP_STATE=y ++CONFIG_CPU_BIG_ENDIAN=y ++# CONFIG_CPU_LITTLE_ENDIAN is not set ++CONFIG_SYS_SUPPORTS_BIG_ENDIAN=y ++CONFIG_SYS_SUPPORTS_LITTLE_ENDIAN=y ++CONFIG_IRQ_CPU=y ++CONFIG_SWAP_IO_SPACE=y ++CONFIG_EMMA2RH=y ++CONFIG_MIPS_L1_CACHE_SHIFT=5 ++ ++# ++# CPU selection ++# ++# CONFIG_CPU_MIPS32_R1 is not set ++# CONFIG_CPU_MIPS32_R2 is not set ++# CONFIG_CPU_MIPS64_R1 is not set ++# CONFIG_CPU_MIPS64_R2 is not set ++# CONFIG_CPU_R3000 is not set ++# CONFIG_CPU_TX39XX is not set ++# CONFIG_CPU_VR41XX is not set ++# CONFIG_CPU_R4300 is not set ++# CONFIG_CPU_R4X00 is not set ++# CONFIG_CPU_TX49XX is not set ++CONFIG_CPU_R5000=y ++# CONFIG_CPU_R5432 is not set ++# CONFIG_CPU_R6000 is not set ++# CONFIG_CPU_NEVADA is not set ++# CONFIG_CPU_R8000 is not set ++# CONFIG_CPU_R10000 is not set ++# CONFIG_CPU_RM7000 is not set ++# CONFIG_CPU_RM9000 is not set ++# CONFIG_CPU_SB1 is not set ++CONFIG_SYS_HAS_CPU_R5000=y ++CONFIG_SYS_SUPPORTS_32BIT_KERNEL=y ++CONFIG_CPU_SUPPORTS_32BIT_KERNEL=y ++CONFIG_CPU_SUPPORTS_64BIT_KERNEL=y ++ ++# ++# Kernel type ++# ++CONFIG_32BIT=y ++# CONFIG_64BIT is not set ++CONFIG_PAGE_SIZE_4KB=y ++# CONFIG_PAGE_SIZE_8KB is not set ++# CONFIG_PAGE_SIZE_16KB is not set ++# CONFIG_PAGE_SIZE_64KB is not set ++CONFIG_MIPS_MT_DISABLED=y ++# CONFIG_MIPS_MT_SMP is not set ++# CONFIG_MIPS_MT_SMTC is not set ++# CONFIG_MIPS_VPE_LOADER is not set ++# CONFIG_64BIT_PHYS_ADDR is not set ++CONFIG_CPU_HAS_LLSC=y ++CONFIG_CPU_HAS_SYNC=y ++CONFIG_GENERIC_HARDIRQS=y ++CONFIG_GENERIC_IRQ_PROBE=y ++CONFIG_ARCH_FLATMEM_ENABLE=y ++CONFIG_SELECT_MEMORY_MODEL=y ++CONFIG_FLATMEM_MANUAL=y ++# CONFIG_DISCONTIGMEM_MANUAL is not set ++# CONFIG_SPARSEMEM_MANUAL is not set ++CONFIG_FLATMEM=y ++CONFIG_FLAT_NODE_MEM_MAP=y ++# CONFIG_SPARSEMEM_STATIC is not set ++CONFIG_SPLIT_PTLOCK_CPUS=4 ++# CONFIG_RESOURCES_64BIT is not set ++CONFIG_ZONE_DMA_FLAG=1 ++# CONFIG_HZ_48 is not set ++# CONFIG_HZ_100 is not set ++# CONFIG_HZ_128 is not set ++# CONFIG_HZ_250 is not set ++# CONFIG_HZ_256 is not set ++CONFIG_HZ_1000=y ++# CONFIG_HZ_1024 is not set ++CONFIG_SYS_SUPPORTS_ARBIT_HZ=y ++CONFIG_HZ=1000 ++# CONFIG_PREEMPT_NONE is not set ++# CONFIG_PREEMPT_VOLUNTARY is not set ++CONFIG_PREEMPT=y ++CONFIG_PREEMPT_BKL=y ++# CONFIG_KEXEC is not set ++CONFIG_LOCKDEP_SUPPORT=y ++CONFIG_STACKTRACE_SUPPORT=y ++CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config" ++ ++# ++# Code maturity level options ++# ++CONFIG_EXPERIMENTAL=y ++CONFIG_BROKEN_ON_SMP=y ++CONFIG_LOCK_KERNEL=y ++CONFIG_INIT_ENV_ARG_LIMIT=32 ++ ++# ++# General setup ++# ++CONFIG_LOCALVERSION="" ++CONFIG_LOCALVERSION_AUTO=y ++CONFIG_SWAP=y ++CONFIG_SYSVIPC=y ++# CONFIG_IPC_NS is not set ++CONFIG_SYSVIPC_SYSCTL=y ++CONFIG_POSIX_MQUEUE=y ++CONFIG_BSD_PROCESS_ACCT=y ++# CONFIG_BSD_PROCESS_ACCT_V3 is not set ++# CONFIG_TASKSTATS is not set ++# CONFIG_UTS_NS is not set ++# CONFIG_AUDIT is not set ++CONFIG_IKCONFIG=y ++CONFIG_IKCONFIG_PROC=y ++CONFIG_SYSFS_DEPRECATED=y ++# CONFIG_RELAY is not set ++# CONFIG_CC_OPTIMIZE_FOR_SIZE is not set ++CONFIG_SYSCTL=y ++CONFIG_EMBEDDED=y ++CONFIG_SYSCTL_SYSCALL=y ++CONFIG_KALLSYMS=y ++# CONFIG_KALLSYMS_EXTRA_PASS is not set ++CONFIG_HOTPLUG=y ++CONFIG_PRINTK=y ++CONFIG_BUG=y ++CONFIG_ELF_CORE=y ++CONFIG_BASE_FULL=y ++CONFIG_FUTEX=y ++CONFIG_EPOLL=y ++CONFIG_SHMEM=y ++CONFIG_SLAB=y ++CONFIG_VM_EVENT_COUNTERS=y ++CONFIG_RT_MUTEXES=y ++# CONFIG_TINY_SHMEM is not set ++CONFIG_BASE_SMALL=0 ++# CONFIG_SLOB is not set ++ ++# ++# Loadable module support ++# ++CONFIG_MODULES=y ++CONFIG_MODULE_UNLOAD=y ++CONFIG_MODULE_FORCE_UNLOAD=y ++CONFIG_MODVERSIONS=y ++# CONFIG_MODULE_SRCVERSION_ALL is not set ++CONFIG_KMOD=y ++ ++# ++# Block layer ++# ++CONFIG_BLOCK=y ++CONFIG_LBD=y ++# CONFIG_BLK_DEV_IO_TRACE is not set ++# CONFIG_LSF is not set ++ ++# ++# IO Schedulers ++# ++CONFIG_IOSCHED_NOOP=y ++CONFIG_IOSCHED_AS=y ++CONFIG_IOSCHED_DEADLINE=y ++CONFIG_IOSCHED_CFQ=y ++CONFIG_DEFAULT_AS=y ++# CONFIG_DEFAULT_DEADLINE is not set ++# CONFIG_DEFAULT_CFQ is not set ++# CONFIG_DEFAULT_NOOP is not set ++CONFIG_DEFAULT_IOSCHED="anticipatory" ++ ++# ++# Bus options (PCI, PCMCIA, EISA, ISA, TC) ++# ++CONFIG_HW_HAS_PCI=y ++CONFIG_PCI=y ++CONFIG_MMU=y ++ ++# ++# PCCARD (PCMCIA/CardBus) support ++# ++# CONFIG_PCCARD is not set ++ ++# ++# PCI Hotplug Support ++# ++# CONFIG_HOTPLUG_PCI is not set ++ ++# ++# Executable file formats ++# ++CONFIG_BINFMT_ELF=y ++# CONFIG_BINFMT_MISC is not set ++CONFIG_TRAD_SIGNALS=y ++ ++# ++# Power management options ++# ++CONFIG_PM=y ++# CONFIG_PM_LEGACY is not set ++# CONFIG_PM_DEBUG is not set ++# CONFIG_PM_SYSFS_DEPRECATED is not set ++ ++# ++# Networking ++# ++CONFIG_NET=y ++ ++# ++# Networking options ++# ++# CONFIG_NETDEBUG is not set ++CONFIG_PACKET=y ++CONFIG_PACKET_MMAP=y ++CONFIG_UNIX=y ++CONFIG_XFRM=y ++# CONFIG_XFRM_USER is not set ++# CONFIG_XFRM_SUB_POLICY is not set ++CONFIG_XFRM_MIGRATE=y ++CONFIG_NET_KEY=y ++CONFIG_NET_KEY_MIGRATE=y ++CONFIG_INET=y ++CONFIG_IP_MULTICAST=y ++CONFIG_IP_ADVANCED_ROUTER=y ++CONFIG_ASK_IP_FIB_HASH=y ++# CONFIG_IP_FIB_TRIE is not set ++CONFIG_IP_FIB_HASH=y ++CONFIG_IP_MULTIPLE_TABLES=y ++CONFIG_IP_ROUTE_MULTIPATH=y ++# CONFIG_IP_ROUTE_MULTIPATH_CACHED is not set ++CONFIG_IP_ROUTE_VERBOSE=y ++CONFIG_IP_PNP=y ++# CONFIG_IP_PNP_DHCP is not set ++CONFIG_IP_PNP_BOOTP=y ++# CONFIG_IP_PNP_RARP is not set ++# CONFIG_NET_IPIP is not set ++# CONFIG_NET_IPGRE is not set ++# CONFIG_IP_MROUTE is not set ++# CONFIG_ARPD is not set ++CONFIG_SYN_COOKIES=y ++# CONFIG_INET_AH is not set ++# CONFIG_INET_ESP is not set ++# CONFIG_INET_IPCOMP is not set ++# CONFIG_INET_XFRM_TUNNEL is not set ++CONFIG_INET_TUNNEL=m ++CONFIG_INET_XFRM_MODE_TRANSPORT=m ++CONFIG_INET_XFRM_MODE_TUNNEL=m ++CONFIG_INET_XFRM_MODE_BEET=m ++CONFIG_INET_DIAG=y ++CONFIG_INET_TCP_DIAG=y ++# CONFIG_TCP_CONG_ADVANCED is not set ++CONFIG_TCP_CONG_CUBIC=y ++CONFIG_DEFAULT_TCP_CONG="cubic" ++CONFIG_TCP_MD5SIG=y ++ ++# ++# IP: Virtual Server Configuration ++# ++# CONFIG_IP_VS is not set ++CONFIG_IPV6=m ++# CONFIG_IPV6_PRIVACY is not set ++# CONFIG_IPV6_ROUTER_PREF is not set ++# CONFIG_INET6_AH is not set ++# CONFIG_INET6_ESP is not set ++# CONFIG_INET6_IPCOMP is not set ++CONFIG_IPV6_MIP6=y ++# CONFIG_INET6_XFRM_TUNNEL is not set ++# CONFIG_INET6_TUNNEL is not set ++CONFIG_INET6_XFRM_MODE_TRANSPORT=m ++CONFIG_INET6_XFRM_MODE_TUNNEL=m ++CONFIG_INET6_XFRM_MODE_BEET=m ++CONFIG_INET6_XFRM_MODE_ROUTEOPTIMIZATION=m ++CONFIG_IPV6_SIT=m ++# CONFIG_IPV6_TUNNEL is not set ++CONFIG_IPV6_MULTIPLE_TABLES=y ++CONFIG_IPV6_SUBTREES=y ++CONFIG_NETWORK_SECMARK=y ++CONFIG_NETFILTER=y ++# CONFIG_NETFILTER_DEBUG is not set ++ ++# ++# Core Netfilter Configuration ++# ++# CONFIG_NETFILTER_NETLINK is not set ++CONFIG_NF_CONNTRACK_ENABLED=m ++CONFIG_NF_CONNTRACK_SUPPORT=y ++# CONFIG_IP_NF_CONNTRACK_SUPPORT is not set ++CONFIG_NF_CONNTRACK=m ++CONFIG_NF_CT_ACCT=y ++CONFIG_NF_CONNTRACK_MARK=y ++CONFIG_NF_CONNTRACK_SECMARK=y ++CONFIG_NF_CONNTRACK_EVENTS=y ++CONFIG_NF_CT_PROTO_GRE=m ++CONFIG_NF_CT_PROTO_SCTP=m ++CONFIG_NF_CONNTRACK_AMANDA=m ++CONFIG_NF_CONNTRACK_FTP=m ++CONFIG_NF_CONNTRACK_H323=m ++CONFIG_NF_CONNTRACK_IRC=m ++# CONFIG_NF_CONNTRACK_NETBIOS_NS is not set ++CONFIG_NF_CONNTRACK_PPTP=m ++CONFIG_NF_CONNTRACK_SANE=m ++CONFIG_NF_CONNTRACK_SIP=m ++CONFIG_NF_CONNTRACK_TFTP=m ++CONFIG_NETFILTER_XTABLES=m ++CONFIG_NETFILTER_XT_TARGET_CLASSIFY=m ++CONFIG_NETFILTER_XT_TARGET_CONNMARK=m ++CONFIG_NETFILTER_XT_TARGET_DSCP=m ++CONFIG_NETFILTER_XT_TARGET_MARK=m ++CONFIG_NETFILTER_XT_TARGET_NFQUEUE=m ++CONFIG_NETFILTER_XT_TARGET_NFLOG=m ++CONFIG_NETFILTER_XT_TARGET_NOTRACK=m ++CONFIG_NETFILTER_XT_TARGET_SECMARK=m ++CONFIG_NETFILTER_XT_TARGET_CONNSECMARK=m ++CONFIG_NETFILTER_XT_TARGET_TCPMSS=m ++CONFIG_NETFILTER_XT_MATCH_COMMENT=m ++CONFIG_NETFILTER_XT_MATCH_CONNBYTES=m ++CONFIG_NETFILTER_XT_MATCH_CONNMARK=m ++CONFIG_NETFILTER_XT_MATCH_CONNTRACK=m ++CONFIG_NETFILTER_XT_MATCH_DCCP=m ++CONFIG_NETFILTER_XT_MATCH_DSCP=m ++CONFIG_NETFILTER_XT_MATCH_ESP=m ++CONFIG_NETFILTER_XT_MATCH_HELPER=m ++CONFIG_NETFILTER_XT_MATCH_LENGTH=m ++CONFIG_NETFILTER_XT_MATCH_LIMIT=m ++CONFIG_NETFILTER_XT_MATCH_MAC=m ++CONFIG_NETFILTER_XT_MATCH_MARK=m ++CONFIG_NETFILTER_XT_MATCH_POLICY=m ++CONFIG_NETFILTER_XT_MATCH_MULTIPORT=m ++CONFIG_NETFILTER_XT_MATCH_PKTTYPE=m ++CONFIG_NETFILTER_XT_MATCH_QUOTA=m ++CONFIG_NETFILTER_XT_MATCH_REALM=m ++CONFIG_NETFILTER_XT_MATCH_SCTP=m ++CONFIG_NETFILTER_XT_MATCH_STATE=m ++CONFIG_NETFILTER_XT_MATCH_STATISTIC=m ++CONFIG_NETFILTER_XT_MATCH_STRING=m ++CONFIG_NETFILTER_XT_MATCH_TCPMSS=m ++CONFIG_NETFILTER_XT_MATCH_HASHLIMIT=m ++ ++# ++# IP: Netfilter Configuration ++# ++CONFIG_NF_CONNTRACK_IPV4=m ++CONFIG_NF_CONNTRACK_PROC_COMPAT=y ++# CONFIG_IP_NF_QUEUE is not set ++CONFIG_IP_NF_IPTABLES=m ++CONFIG_IP_NF_MATCH_IPRANGE=m ++CONFIG_IP_NF_MATCH_TOS=m ++CONFIG_IP_NF_MATCH_RECENT=m ++CONFIG_IP_NF_MATCH_ECN=m ++CONFIG_IP_NF_MATCH_AH=m ++CONFIG_IP_NF_MATCH_TTL=m ++CONFIG_IP_NF_MATCH_OWNER=m ++CONFIG_IP_NF_MATCH_ADDRTYPE=m ++CONFIG_IP_NF_FILTER=m ++CONFIG_IP_NF_TARGET_REJECT=m ++CONFIG_IP_NF_TARGET_LOG=m ++CONFIG_IP_NF_TARGET_ULOG=m ++CONFIG_NF_NAT=m ++CONFIG_NF_NAT_NEEDED=y ++CONFIG_IP_NF_TARGET_MASQUERADE=m ++CONFIG_IP_NF_TARGET_REDIRECT=m ++CONFIG_IP_NF_TARGET_NETMAP=m ++CONFIG_IP_NF_TARGET_SAME=m ++CONFIG_NF_NAT_SNMP_BASIC=m ++CONFIG_NF_NAT_PROTO_GRE=m ++CONFIG_NF_NAT_FTP=m ++CONFIG_NF_NAT_IRC=m ++CONFIG_NF_NAT_TFTP=m ++CONFIG_NF_NAT_AMANDA=m ++CONFIG_NF_NAT_PPTP=m ++CONFIG_NF_NAT_H323=m ++CONFIG_NF_NAT_SIP=m ++CONFIG_IP_NF_MANGLE=m ++CONFIG_IP_NF_TARGET_TOS=m ++CONFIG_IP_NF_TARGET_ECN=m ++CONFIG_IP_NF_TARGET_TTL=m ++CONFIG_IP_NF_TARGET_CLUSTERIP=m ++CONFIG_IP_NF_RAW=m ++CONFIG_IP_NF_ARPTABLES=m ++CONFIG_IP_NF_ARPFILTER=m ++CONFIG_IP_NF_ARP_MANGLE=m ++ ++# ++# IPv6: Netfilter Configuration (EXPERIMENTAL) ++# ++CONFIG_NF_CONNTRACK_IPV6=m ++# CONFIG_IP6_NF_QUEUE is not set ++CONFIG_IP6_NF_IPTABLES=m ++CONFIG_IP6_NF_MATCH_RT=m ++CONFIG_IP6_NF_MATCH_OPTS=m ++CONFIG_IP6_NF_MATCH_FRAG=m ++CONFIG_IP6_NF_MATCH_HL=m ++CONFIG_IP6_NF_MATCH_OWNER=m ++CONFIG_IP6_NF_MATCH_IPV6HEADER=m ++CONFIG_IP6_NF_MATCH_AH=m ++CONFIG_IP6_NF_MATCH_MH=m ++CONFIG_IP6_NF_MATCH_EUI64=m ++CONFIG_IP6_NF_FILTER=m ++CONFIG_IP6_NF_TARGET_LOG=m ++CONFIG_IP6_NF_TARGET_REJECT=m ++CONFIG_IP6_NF_MANGLE=m ++CONFIG_IP6_NF_TARGET_HL=m ++CONFIG_IP6_NF_RAW=m ++ ++# ++# DCCP Configuration (EXPERIMENTAL) ++# ++# CONFIG_IP_DCCP is not set ++ ++# ++# SCTP Configuration (EXPERIMENTAL) ++# ++CONFIG_IP_SCTP=m ++# CONFIG_SCTP_DBG_MSG is not set ++# CONFIG_SCTP_DBG_OBJCNT is not set ++# CONFIG_SCTP_HMAC_NONE is not set ++# CONFIG_SCTP_HMAC_SHA1 is not set ++CONFIG_SCTP_HMAC_MD5=y ++ ++# ++# TIPC Configuration (EXPERIMENTAL) ++# ++# CONFIG_TIPC is not set ++# CONFIG_ATM is not set ++# CONFIG_BRIDGE is not set ++# CONFIG_VLAN_8021Q is not set ++# CONFIG_DECNET is not set ++# CONFIG_LLC2 is not set ++# CONFIG_IPX is not set ++# CONFIG_ATALK is not set ++# CONFIG_X25 is not set ++# CONFIG_LAPB is not set ++# CONFIG_ECONET is not set ++# CONFIG_WAN_ROUTER is not set ++ ++# ++# QoS and/or fair queueing ++# ++# CONFIG_NET_SCHED is not set ++CONFIG_NET_CLS_ROUTE=y ++ ++# ++# Network testing ++# ++# CONFIG_NET_PKTGEN is not set ++# CONFIG_HAMRADIO is not set ++# CONFIG_IRDA is not set ++# CONFIG_BT is not set ++# CONFIG_IEEE80211 is not set ++CONFIG_FIB_RULES=y ++ ++# ++# Device Drivers ++# ++ ++# ++# Generic Driver Options ++# ++CONFIG_STANDALONE=y ++CONFIG_PREVENT_FIRMWARE_BUILD=y ++CONFIG_FW_LOADER=m ++# CONFIG_SYS_HYPERVISOR is not set ++ ++# ++# Connector - unified userspace <-> kernelspace linker ++# ++# CONFIG_CONNECTOR is not set ++ ++# ++# Memory Technology Devices (MTD) ++# ++CONFIG_MTD=y ++# CONFIG_MTD_DEBUG is not set ++# CONFIG_MTD_CONCAT is not set ++CONFIG_MTD_PARTITIONS=y ++# CONFIG_MTD_REDBOOT_PARTS is not set ++CONFIG_MTD_CMDLINE_PARTS=y ++ ++# ++# User Modules And Translation Layers ++# ++CONFIG_MTD_CHAR=y ++CONFIG_MTD_BLKDEVS=y ++CONFIG_MTD_BLOCK=y ++# CONFIG_FTL is not set ++# CONFIG_NFTL is not set ++# CONFIG_INFTL is not set ++# CONFIG_RFD_FTL is not set ++# CONFIG_SSFDC is not set ++ ++# ++# RAM/ROM/Flash chip drivers ++# ++CONFIG_MTD_CFI=y ++# CONFIG_MTD_JEDECPROBE is not set ++CONFIG_MTD_GEN_PROBE=y ++# CONFIG_MTD_CFI_ADV_OPTIONS is not set ++CONFIG_MTD_MAP_BANK_WIDTH_1=y ++CONFIG_MTD_MAP_BANK_WIDTH_2=y ++CONFIG_MTD_MAP_BANK_WIDTH_4=y ++# CONFIG_MTD_MAP_BANK_WIDTH_8 is not set ++# CONFIG_MTD_MAP_BANK_WIDTH_16 is not set ++# CONFIG_MTD_MAP_BANK_WIDTH_32 is not set ++CONFIG_MTD_CFI_I1=y ++CONFIG_MTD_CFI_I2=y ++# CONFIG_MTD_CFI_I4 is not set ++# CONFIG_MTD_CFI_I8 is not set ++# CONFIG_MTD_CFI_INTELEXT is not set ++CONFIG_MTD_CFI_AMDSTD=y ++# CONFIG_MTD_CFI_STAA is not set ++CONFIG_MTD_CFI_UTIL=y ++# CONFIG_MTD_RAM is not set ++# CONFIG_MTD_ROM is not set ++# CONFIG_MTD_ABSENT is not set ++# CONFIG_MTD_OBSOLETE_CHIPS is not set ++ ++# ++# Mapping drivers for chip access ++# ++# CONFIG_MTD_COMPLEX_MAPPINGS is not set ++CONFIG_MTD_PHYSMAP=y ++CONFIG_MTD_PHYSMAP_START=0x1e000000 ++CONFIG_MTD_PHYSMAP_LEN=0x02000000 ++CONFIG_MTD_PHYSMAP_BANKWIDTH=2 ++# CONFIG_MTD_PLATRAM is not set ++ ++# ++# Self-contained MTD device drivers ++# ++# CONFIG_MTD_PMC551 is not set ++# CONFIG_MTD_SLRAM is not set ++# CONFIG_MTD_PHRAM is not set ++# CONFIG_MTD_MTDRAM is not set ++# CONFIG_MTD_BLOCK2MTD is not set ++ ++# ++# Disk-On-Chip Device Drivers ++# ++# CONFIG_MTD_DOC2000 is not set ++# CONFIG_MTD_DOC2001 is not set ++# CONFIG_MTD_DOC2001PLUS is not set ++ ++# ++# NAND Flash Device Drivers ++# ++# CONFIG_MTD_NAND is not set ++ ++# ++# OneNAND Flash Device Drivers ++# ++# CONFIG_MTD_ONENAND is not set ++ ++# ++# Parallel port support ++# ++# CONFIG_PARPORT is not set ++ ++# ++# Plug and Play support ++# ++# CONFIG_PNPACPI is not set ++ ++# ++# Block devices ++# ++# CONFIG_BLK_CPQ_DA is not set ++# CONFIG_BLK_CPQ_CISS_DA is not set ++# CONFIG_BLK_DEV_DAC960 is not set ++# CONFIG_BLK_DEV_UMEM is not set ++# CONFIG_BLK_DEV_COW_COMMON is not set ++CONFIG_BLK_DEV_LOOP=m ++CONFIG_BLK_DEV_CRYPTOLOOP=m ++# CONFIG_BLK_DEV_NBD is not set ++# CONFIG_BLK_DEV_SX8 is not set ++# CONFIG_BLK_DEV_RAM is not set ++# CONFIG_BLK_DEV_INITRD is not set ++# CONFIG_CDROM_PKTCDVD is not set ++# CONFIG_ATA_OVER_ETH is not set ++ ++# ++# Misc devices ++# ++CONFIG_SGI_IOC4=m ++# CONFIG_TIFM_CORE is not set ++ ++# ++# ATA/ATAPI/MFM/RLL support ++# ++# CONFIG_IDE is not set ++ ++# ++# SCSI device support ++# ++# CONFIG_RAID_ATTRS is not set ++CONFIG_SCSI=m ++CONFIG_SCSI_TGT=m ++# CONFIG_SCSI_NETLINK is not set ++# CONFIG_SCSI_PROC_FS is not set ++ ++# ++# SCSI support type (disk, tape, CD-ROM) ++# ++CONFIG_BLK_DEV_SD=m ++# CONFIG_CHR_DEV_ST is not set ++# CONFIG_CHR_DEV_OSST is not set ++# CONFIG_BLK_DEV_SR is not set ++CONFIG_CHR_DEV_SG=m ++# CONFIG_CHR_DEV_SCH is not set ++ ++# ++# Some SCSI devices (e.g. CD jukebox) support multiple LUNs ++# ++# CONFIG_SCSI_MULTI_LUN is not set ++# CONFIG_SCSI_CONSTANTS is not set ++# CONFIG_SCSI_LOGGING is not set ++CONFIG_SCSI_SCAN_ASYNC=y ++ ++# ++# SCSI Transports ++# ++# CONFIG_SCSI_SPI_ATTRS is not set ++# CONFIG_SCSI_FC_ATTRS is not set ++# CONFIG_SCSI_ISCSI_ATTRS is not set ++CONFIG_SCSI_SAS_ATTRS=m ++CONFIG_SCSI_SAS_LIBSAS=m ++# CONFIG_SCSI_SAS_LIBSAS_DEBUG is not set ++ ++# ++# SCSI low-level drivers ++# ++# CONFIG_ISCSI_TCP is not set ++# CONFIG_BLK_DEV_3W_XXXX_RAID is not set ++# CONFIG_SCSI_3W_9XXX is not set ++# CONFIG_SCSI_ACARD is not set ++# CONFIG_SCSI_AACRAID is not set ++# CONFIG_SCSI_AIC7XXX is not set ++# CONFIG_SCSI_AIC7XXX_OLD is not set ++# CONFIG_SCSI_AIC79XX is not set ++CONFIG_SCSI_AIC94XX=m ++# CONFIG_AIC94XX_DEBUG is not set ++# CONFIG_SCSI_DPT_I2O is not set ++# CONFIG_SCSI_ARCMSR is not set ++# CONFIG_MEGARAID_NEWGEN is not set ++# CONFIG_MEGARAID_LEGACY is not set ++# CONFIG_MEGARAID_SAS is not set ++# CONFIG_SCSI_HPTIOP is not set ++# CONFIG_SCSI_DMX3191D is not set ++# CONFIG_SCSI_FUTURE_DOMAIN is not set ++# CONFIG_SCSI_IPS is not set ++# CONFIG_SCSI_INITIO is not set ++# CONFIG_SCSI_INIA100 is not set ++# CONFIG_SCSI_STEX is not set ++# CONFIG_SCSI_SYM53C8XX_2 is not set ++# CONFIG_SCSI_QLOGIC_1280 is not set ++# CONFIG_SCSI_QLA_FC is not set ++# CONFIG_SCSI_QLA_ISCSI is not set ++# CONFIG_SCSI_LPFC is not set ++# CONFIG_SCSI_DC395x is not set ++# CONFIG_SCSI_DC390T is not set ++# CONFIG_SCSI_NSP32 is not set ++# CONFIG_SCSI_DEBUG is not set ++# CONFIG_SCSI_SRP is not set ++ ++# ++# Serial ATA (prod) and Parallel ATA (experimental) drivers ++# ++# CONFIG_ATA is not set ++ ++# ++# Multi-device support (RAID and LVM) ++# ++# CONFIG_MD is not set ++ ++# ++# Fusion MPT device support ++# ++# CONFIG_FUSION is not set ++# CONFIG_FUSION_SPI is not set ++# CONFIG_FUSION_FC is not set ++# CONFIG_FUSION_SAS is not set ++ ++# ++# IEEE 1394 (FireWire) support ++# ++# CONFIG_IEEE1394 is not set ++ ++# ++# I2O device support ++# ++# CONFIG_I2O is not set ++ ++# ++# Network device support ++# ++CONFIG_NETDEVICES=y ++# CONFIG_DUMMY is not set ++# CONFIG_BONDING is not set ++# CONFIG_EQUALIZER is not set ++CONFIG_TUN=m ++ ++# ++# ARCnet devices ++# ++# CONFIG_ARCNET is not set ++ ++# ++# PHY device support ++# ++# CONFIG_PHYLIB is not set ++ ++# ++# Ethernet (10 or 100Mbit) ++# ++CONFIG_NET_ETHERNET=y ++CONFIG_MII=y ++# CONFIG_HAPPYMEAL is not set ++# CONFIG_SUNGEM is not set ++# CONFIG_CASSINI is not set ++# CONFIG_NET_VENDOR_3COM is not set ++# CONFIG_DM9000 is not set ++ ++# ++# Tulip family network device support ++# ++# CONFIG_NET_TULIP is not set ++# CONFIG_HP100 is not set ++CONFIG_NET_PCI=y ++# CONFIG_PCNET32 is not set ++# CONFIG_AMD8111_ETH is not set ++# CONFIG_ADAPTEC_STARFIRE is not set ++# CONFIG_B44 is not set ++# CONFIG_FORCEDETH is not set ++# CONFIG_DGRS is not set ++# CONFIG_EEPRO100 is not set ++# CONFIG_E100 is not set ++# CONFIG_FEALNX is not set ++CONFIG_NATSEMI=y ++# CONFIG_NE2K_PCI is not set ++# CONFIG_8139CP is not set ++# CONFIG_8139TOO is not set ++# CONFIG_SIS900 is not set ++# CONFIG_EPIC100 is not set ++# CONFIG_SUNDANCE is not set ++# CONFIG_TLAN is not set ++# CONFIG_VIA_RHINE is not set ++# CONFIG_SC92031 is not set ++ ++# ++# Ethernet (1000 Mbit) ++# ++# CONFIG_ACENIC is not set ++# CONFIG_DL2K is not set ++# CONFIG_E1000 is not set ++# CONFIG_NS83820 is not set ++# CONFIG_HAMACHI is not set ++# CONFIG_YELLOWFIN is not set ++# CONFIG_R8169 is not set ++# CONFIG_SIS190 is not set ++# CONFIG_SKGE is not set ++# CONFIG_SKY2 is not set ++# CONFIG_SK98LIN is not set ++# CONFIG_VIA_VELOCITY is not set ++# CONFIG_TIGON3 is not set ++# CONFIG_BNX2 is not set ++CONFIG_QLA3XXX=m ++# CONFIG_ATL1 is not set ++ ++# ++# Ethernet (10000 Mbit) ++# ++# CONFIG_CHELSIO_T1 is not set ++CONFIG_CHELSIO_T3=m ++# CONFIG_IXGB is not set ++# CONFIG_S2IO is not set ++# CONFIG_MYRI10GE is not set ++CONFIG_NETXEN_NIC=m ++ ++# ++# Token Ring devices ++# ++# CONFIG_TR is not set ++ ++# ++# Wireless LAN (non-hamradio) ++# ++# CONFIG_NET_RADIO is not set ++ ++# ++# Wan interfaces ++# ++# CONFIG_WAN is not set ++# CONFIG_FDDI is not set ++# CONFIG_HIPPI is not set ++CONFIG_PPP=m ++# CONFIG_PPP_MULTILINK is not set ++# CONFIG_PPP_FILTER is not set ++CONFIG_PPP_ASYNC=m ++CONFIG_PPP_SYNC_TTY=m ++CONFIG_PPP_DEFLATE=m ++# CONFIG_PPP_BSDCOMP is not set ++# CONFIG_PPP_MPPE is not set ++# CONFIG_PPPOE is not set ++# CONFIG_SLIP is not set ++CONFIG_SLHC=m ++# CONFIG_NET_FC is not set ++# CONFIG_SHAPER is not set ++# CONFIG_NETCONSOLE is not set ++# CONFIG_NETPOLL is not set ++# CONFIG_NET_POLL_CONTROLLER is not set ++ ++# ++# ISDN subsystem ++# ++# CONFIG_ISDN is not set ++ ++# ++# Telephony Support ++# ++# CONFIG_PHONE is not set ++ ++# ++# Input device support ++# ++CONFIG_INPUT=y ++# CONFIG_INPUT_FF_MEMLESS is not set ++ ++# ++# Userland interfaces ++# ++# CONFIG_INPUT_MOUSEDEV is not set ++# CONFIG_INPUT_JOYDEV is not set ++# CONFIG_INPUT_TSDEV is not set ++CONFIG_INPUT_EVDEV=m ++# CONFIG_INPUT_EVBUG is not set ++ ++# ++# Input Device Drivers ++# ++# CONFIG_INPUT_KEYBOARD is not set ++# CONFIG_INPUT_MOUSE is not set ++# CONFIG_INPUT_JOYSTICK is not set ++# CONFIG_INPUT_TOUCHSCREEN is not set ++# CONFIG_INPUT_MISC is not set ++ ++# ++# Hardware I/O ports ++# ++# CONFIG_SERIO is not set ++# CONFIG_GAMEPORT is not set ++ ++# ++# Character devices ++# ++# CONFIG_VT is not set ++# CONFIG_SERIAL_NONSTANDARD is not set ++ ++# ++# Serial drivers ++# ++CONFIG_SERIAL_8250=y ++CONFIG_SERIAL_8250_CONSOLE=y ++CONFIG_SERIAL_8250_PCI=y ++CONFIG_SERIAL_8250_NR_UARTS=4 ++CONFIG_SERIAL_8250_RUNTIME_UARTS=4 ++# CONFIG_SERIAL_8250_EXTENDED is not set ++ ++# ++# Non-8250 serial port support ++# ++CONFIG_SERIAL_CORE=y ++CONFIG_SERIAL_CORE_CONSOLE=y ++# CONFIG_SERIAL_JSM is not set ++CONFIG_UNIX98_PTYS=y ++CONFIG_LEGACY_PTYS=y ++CONFIG_LEGACY_PTY_COUNT=256 ++ ++# ++# IPMI ++# ++# CONFIG_IPMI_HANDLER is not set ++ ++# ++# Watchdog Cards ++# ++# CONFIG_WATCHDOG is not set ++# CONFIG_HW_RANDOM is not set ++CONFIG_RTC=m ++# CONFIG_GEN_RTC is not set ++# CONFIG_DTLK is not set ++# CONFIG_R3964 is not set ++# CONFIG_APPLICOM is not set ++# CONFIG_DRM is not set ++# CONFIG_RAW_DRIVER is not set ++ ++# ++# TPM devices ++# ++# CONFIG_TCG_TPM is not set ++ ++# ++# I2C support ++# ++CONFIG_I2C=y ++CONFIG_I2C_CHARDEV=y ++ ++# ++# I2C Algorithms ++# ++# CONFIG_I2C_ALGOBIT is not set ++# CONFIG_I2C_ALGOPCF is not set ++# CONFIG_I2C_ALGOPCA is not set ++ ++# ++# I2C Hardware Bus support ++# ++# CONFIG_I2C_ALI1535 is not set ++# CONFIG_I2C_ALI1563 is not set ++# CONFIG_I2C_ALI15X3 is not set ++# CONFIG_I2C_AMD756 is not set ++# CONFIG_I2C_AMD8111 is not set ++# CONFIG_I2C_I801 is not set ++# CONFIG_I2C_I810 is not set ++# CONFIG_I2C_PIIX4 is not set ++# CONFIG_I2C_NFORCE2 is not set ++# CONFIG_I2C_OCORES is not set ++# CONFIG_I2C_PARPORT_LIGHT is not set ++# CONFIG_I2C_PASEMI is not set ++# CONFIG_I2C_PROSAVAGE is not set ++# CONFIG_I2C_SAVAGE4 is not set ++# CONFIG_I2C_SIS5595 is not set ++# CONFIG_I2C_SIS630 is not set ++# CONFIG_I2C_SIS96X is not set ++# CONFIG_I2C_STUB is not set ++# CONFIG_I2C_VIA is not set ++# CONFIG_I2C_VIAPRO is not set ++# CONFIG_I2C_VOODOO3 is not set ++# CONFIG_I2C_PCA_ISA is not set ++ ++# ++# Miscellaneous I2C Chip support ++# ++# CONFIG_SENSORS_DS1337 is not set ++# CONFIG_SENSORS_DS1374 is not set ++# CONFIG_EEPROM_LEGACY is not set ++# CONFIG_SENSORS_PCF8574 is not set ++# CONFIG_SENSORS_PCA9539 is not set ++# CONFIG_SENSORS_PCF8591 is not set ++# CONFIG_SENSORS_MAX6875 is not set ++CONFIG_I2C_DEBUG_CORE=y ++# CONFIG_I2C_DEBUG_ALGO is not set ++CONFIG_I2C_DEBUG_BUS=y ++# CONFIG_I2C_DEBUG_CHIP is not set ++ ++# ++# SPI support ++# ++# CONFIG_SPI is not set ++# CONFIG_SPI_MASTER is not set ++ ++# ++# Dallas's 1-wire bus ++# ++# CONFIG_W1 is not set ++ ++# ++# Hardware Monitoring support ++# ++CONFIG_HWMON=y ++# CONFIG_HWMON_VID is not set ++# CONFIG_SENSORS_ABITUGURU is not set ++# CONFIG_SENSORS_ADM1021 is not set ++# CONFIG_SENSORS_ADM1025 is not set ++# CONFIG_SENSORS_ADM1026 is not set ++# CONFIG_SENSORS_ADM1029 is not set ++# CONFIG_SENSORS_ADM1031 is not set ++# CONFIG_SENSORS_ADM9240 is not set ++# CONFIG_SENSORS_ASB100 is not set ++# CONFIG_SENSORS_ATXP1 is not set ++# CONFIG_SENSORS_DS1621 is not set ++# CONFIG_SENSORS_F71805F is not set ++# CONFIG_SENSORS_FSCHER is not set ++# CONFIG_SENSORS_FSCPOS is not set ++# CONFIG_SENSORS_GL518SM is not set ++# CONFIG_SENSORS_GL520SM is not set ++# CONFIG_SENSORS_IT87 is not set ++# CONFIG_SENSORS_LM63 is not set ++# CONFIG_SENSORS_LM75 is not set ++# CONFIG_SENSORS_LM77 is not set ++# CONFIG_SENSORS_LM78 is not set ++# CONFIG_SENSORS_LM80 is not set ++# CONFIG_SENSORS_LM83 is not set ++# CONFIG_SENSORS_LM85 is not set ++# CONFIG_SENSORS_LM87 is not set ++# CONFIG_SENSORS_LM90 is not set ++# CONFIG_SENSORS_LM92 is not set ++# CONFIG_SENSORS_MAX1619 is not set ++# CONFIG_SENSORS_PC87360 is not set ++# CONFIG_SENSORS_PC87427 is not set ++# CONFIG_SENSORS_SIS5595 is not set ++# CONFIG_SENSORS_SMSC47M1 is not set ++# CONFIG_SENSORS_SMSC47M192 is not set ++# CONFIG_SENSORS_SMSC47B397 is not set ++# CONFIG_SENSORS_VIA686A is not set ++# CONFIG_SENSORS_VT1211 is not set ++# CONFIG_SENSORS_VT8231 is not set ++# CONFIG_SENSORS_W83781D is not set ++# CONFIG_SENSORS_W83791D is not set ++# CONFIG_SENSORS_W83792D is not set ++# CONFIG_SENSORS_W83793 is not set ++# CONFIG_SENSORS_W83L785TS is not set ++# CONFIG_SENSORS_W83627HF is not set ++# CONFIG_SENSORS_W83627EHF is not set ++# CONFIG_HWMON_DEBUG_CHIP is not set ++ ++# ++# Multimedia devices ++# ++# CONFIG_VIDEO_DEV is not set ++ ++# ++# Digital Video Broadcasting Devices ++# ++# CONFIG_DVB is not set ++ ++# ++# Graphics support ++# ++# CONFIG_FIRMWARE_EDID is not set ++# CONFIG_FB is not set ++# CONFIG_BACKLIGHT_LCD_SUPPORT is not set ++ ++# ++# Sound ++# ++# CONFIG_SOUND is not set ++ ++# ++# HID Devices ++# ++# CONFIG_HID is not set ++ ++# ++# USB support ++# ++CONFIG_USB_ARCH_HAS_HCD=y ++CONFIG_USB_ARCH_HAS_OHCI=y ++CONFIG_USB_ARCH_HAS_EHCI=y ++# CONFIG_USB is not set ++ ++# ++# NOTE: USB_STORAGE enables SCSI, and 'SCSI disk support' ++# ++ ++# ++# USB Gadget Support ++# ++# CONFIG_USB_GADGET is not set ++ ++# ++# MMC/SD Card support ++# ++# CONFIG_MMC is not set ++ ++# ++# LED devices ++# ++# CONFIG_NEW_LEDS is not set ++ ++# ++# LED drivers ++# ++ ++# ++# LED Triggers ++# ++ ++# ++# InfiniBand support ++# ++# CONFIG_INFINIBAND is not set ++ ++# ++# EDAC - error detection and reporting (RAS) (EXPERIMENTAL) ++# ++ ++# ++# Real Time Clock ++# ++# CONFIG_RTC_CLASS is not set ++ ++# ++# DMA Engine support ++# ++# CONFIG_DMA_ENGINE is not set ++ ++# ++# DMA Clients ++# ++ ++# ++# DMA Devices ++# ++ ++# ++# Auxiliary Display support ++# ++ ++# ++# Virtualization ++# ++ ++# ++# File systems ++# ++CONFIG_EXT2_FS=y ++CONFIG_EXT2_FS_XATTR=y ++CONFIG_EXT2_FS_POSIX_ACL=y ++CONFIG_EXT2_FS_SECURITY=y ++# CONFIG_EXT2_FS_XIP is not set ++CONFIG_EXT3_FS=m ++CONFIG_EXT3_FS_XATTR=y ++# CONFIG_EXT3_FS_POSIX_ACL is not set ++# CONFIG_EXT3_FS_SECURITY is not set ++# CONFIG_EXT4DEV_FS is not set ++CONFIG_JBD=m ++# CONFIG_JBD_DEBUG is not set ++CONFIG_FS_MBCACHE=y ++# CONFIG_REISERFS_FS is not set ++# CONFIG_JFS_FS is not set ++CONFIG_FS_POSIX_ACL=y ++CONFIG_XFS_FS=m ++# CONFIG_XFS_QUOTA is not set ++# CONFIG_XFS_SECURITY is not set ++# CONFIG_XFS_POSIX_ACL is not set ++# CONFIG_XFS_RT is not set ++# CONFIG_GFS2_FS is not set ++# CONFIG_OCFS2_FS is not set ++# CONFIG_MINIX_FS is not set ++# CONFIG_ROMFS_FS is not set ++CONFIG_INOTIFY=y ++CONFIG_INOTIFY_USER=y ++# CONFIG_QUOTA is not set ++# CONFIG_DNOTIFY is not set ++# CONFIG_AUTOFS_FS is not set ++CONFIG_AUTOFS4_FS=m ++# CONFIG_FUSE_FS is not set ++CONFIG_GENERIC_ACL=y ++ ++# ++# CD-ROM/DVD Filesystems ++# ++# CONFIG_ISO9660_FS is not set ++# CONFIG_UDF_FS is not set ++ ++# ++# DOS/FAT/NT Filesystems ++# ++CONFIG_FAT_FS=y ++CONFIG_MSDOS_FS=y ++CONFIG_VFAT_FS=y ++CONFIG_FAT_DEFAULT_CODEPAGE=437 ++CONFIG_FAT_DEFAULT_IOCHARSET="iso8859-1" ++CONFIG_NTFS_FS=m ++# CONFIG_NTFS_DEBUG is not set ++# CONFIG_NTFS_RW is not set ++ ++# ++# Pseudo filesystems ++# ++CONFIG_PROC_FS=y ++CONFIG_PROC_KCORE=y ++CONFIG_PROC_SYSCTL=y ++CONFIG_SYSFS=y ++CONFIG_TMPFS=y ++CONFIG_TMPFS_POSIX_ACL=y ++# CONFIG_HUGETLB_PAGE is not set ++CONFIG_RAMFS=y ++CONFIG_CONFIGFS_FS=m ++ ++# ++# Miscellaneous filesystems ++# ++# CONFIG_ADFS_FS is not set ++# CONFIG_AFFS_FS is not set ++# CONFIG_HFS_FS is not set ++# CONFIG_HFSPLUS_FS is not set ++# CONFIG_BEFS_FS is not set ++# CONFIG_BFS_FS is not set ++# CONFIG_EFS_FS is not set ++CONFIG_JFFS2_FS=y ++CONFIG_JFFS2_FS_DEBUG=0 ++CONFIG_JFFS2_FS_WRITEBUFFER=y ++# CONFIG_JFFS2_SUMMARY is not set ++# CONFIG_JFFS2_FS_XATTR is not set ++CONFIG_JFFS2_COMPRESSION_OPTIONS=y ++CONFIG_JFFS2_ZLIB=y ++CONFIG_JFFS2_RTIME=y ++# CONFIG_JFFS2_RUBIN is not set ++# CONFIG_JFFS2_CMODE_NONE is not set ++CONFIG_JFFS2_CMODE_PRIORITY=y ++# CONFIG_JFFS2_CMODE_SIZE is not set ++CONFIG_CRAMFS=y ++# CONFIG_VXFS_FS is not set ++# CONFIG_HPFS_FS is not set ++# CONFIG_QNX4FS_FS is not set ++# CONFIG_SYSV_FS is not set ++# CONFIG_UFS_FS is not set ++ ++# ++# Network File Systems ++# ++CONFIG_NFS_FS=y ++CONFIG_NFS_V3=y ++# CONFIG_NFS_V3_ACL is not set ++CONFIG_NFS_V4=y ++CONFIG_NFS_DIRECTIO=y ++CONFIG_NFSD=m ++CONFIG_NFSD_V3=y ++# CONFIG_NFSD_V3_ACL is not set ++# CONFIG_NFSD_V4 is not set ++CONFIG_NFSD_TCP=y ++CONFIG_ROOT_NFS=y ++CONFIG_LOCKD=y ++CONFIG_LOCKD_V4=y ++CONFIG_EXPORTFS=m ++CONFIG_NFS_COMMON=y ++CONFIG_SUNRPC=y ++CONFIG_SUNRPC_GSS=y ++CONFIG_RPCSEC_GSS_KRB5=y ++# CONFIG_RPCSEC_GSS_SPKM3 is not set ++CONFIG_SMB_FS=m ++# CONFIG_SMB_NLS_DEFAULT is not set ++# CONFIG_CIFS is not set ++# CONFIG_NCP_FS is not set ++# CONFIG_CODA_FS is not set ++# CONFIG_AFS_FS is not set ++# CONFIG_9P_FS is not set ++ ++# ++# Partition Types ++# ++# CONFIG_PARTITION_ADVANCED is not set ++CONFIG_MSDOS_PARTITION=y ++ ++# ++# Native Language Support ++# ++CONFIG_NLS=y ++CONFIG_NLS_DEFAULT="" ++CONFIG_NLS_CODEPAGE_437=m ++# CONFIG_NLS_CODEPAGE_737 is not set ++# CONFIG_NLS_CODEPAGE_775 is not set ++# CONFIG_NLS_CODEPAGE_850 is not set ++# CONFIG_NLS_CODEPAGE_852 is not set ++# CONFIG_NLS_CODEPAGE_855 is not set ++# CONFIG_NLS_CODEPAGE_857 is not set ++# CONFIG_NLS_CODEPAGE_860 is not set ++# CONFIG_NLS_CODEPAGE_861 is not set ++# CONFIG_NLS_CODEPAGE_862 is not set ++# CONFIG_NLS_CODEPAGE_863 is not set ++# CONFIG_NLS_CODEPAGE_864 is not set ++# CONFIG_NLS_CODEPAGE_865 is not set ++# CONFIG_NLS_CODEPAGE_866 is not set ++# CONFIG_NLS_CODEPAGE_869 is not set ++# CONFIG_NLS_CODEPAGE_936 is not set ++# CONFIG_NLS_CODEPAGE_950 is not set ++# CONFIG_NLS_CODEPAGE_932 is not set ++# CONFIG_NLS_CODEPAGE_949 is not set ++# CONFIG_NLS_CODEPAGE_874 is not set ++# CONFIG_NLS_ISO8859_8 is not set ++# CONFIG_NLS_CODEPAGE_1250 is not set ++# CONFIG_NLS_CODEPAGE_1251 is not set ++CONFIG_NLS_ASCII=m ++CONFIG_NLS_ISO8859_1=m ++# CONFIG_NLS_ISO8859_2 is not set ++# CONFIG_NLS_ISO8859_3 is not set ++# CONFIG_NLS_ISO8859_4 is not set ++# CONFIG_NLS_ISO8859_5 is not set ++# CONFIG_NLS_ISO8859_6 is not set ++# CONFIG_NLS_ISO8859_7 is not set ++# CONFIG_NLS_ISO8859_9 is not set ++# CONFIG_NLS_ISO8859_13 is not set ++# CONFIG_NLS_ISO8859_14 is not set ++# CONFIG_NLS_ISO8859_15 is not set ++# CONFIG_NLS_KOI8_R is not set ++# CONFIG_NLS_KOI8_U is not set ++CONFIG_NLS_UTF8=m ++ ++# ++# Distributed Lock Manager ++# ++CONFIG_DLM=m ++CONFIG_DLM_TCP=y ++# CONFIG_DLM_SCTP is not set ++# CONFIG_DLM_DEBUG is not set ++ ++# ++# Profiling support ++# ++# CONFIG_PROFILING is not set ++ ++# ++# Kernel hacking ++# ++CONFIG_TRACE_IRQFLAGS_SUPPORT=y ++# CONFIG_PRINTK_TIME is not set ++CONFIG_ENABLE_MUST_CHECK=y ++# CONFIG_MAGIC_SYSRQ is not set ++# CONFIG_UNUSED_SYMBOLS is not set ++# CONFIG_DEBUG_FS is not set ++# CONFIG_HEADERS_CHECK is not set ++# CONFIG_DEBUG_KERNEL is not set ++CONFIG_LOG_BUF_SHIFT=14 ++CONFIG_CROSSCOMPILE=y ++CONFIG_CMDLINE="console=ttyS0,115200 mem=192m ip=bootp root=/dev/nfs rw" ++ ++# ++# Security options ++# ++# CONFIG_KEYS is not set ++# CONFIG_SECURITY is not set ++ ++# ++# Cryptographic options ++# ++CONFIG_CRYPTO=y ++CONFIG_CRYPTO_ALGAPI=y ++CONFIG_CRYPTO_BLKCIPHER=y ++CONFIG_CRYPTO_HASH=y ++CONFIG_CRYPTO_MANAGER=y ++CONFIG_CRYPTO_HMAC=y ++CONFIG_CRYPTO_XCBC=m ++# CONFIG_CRYPTO_NULL is not set ++# CONFIG_CRYPTO_MD4 is not set ++CONFIG_CRYPTO_MD5=y ++# CONFIG_CRYPTO_SHA1 is not set ++# CONFIG_CRYPTO_SHA256 is not set ++# CONFIG_CRYPTO_SHA512 is not set ++# CONFIG_CRYPTO_WP512 is not set ++# CONFIG_CRYPTO_TGR192 is not set ++CONFIG_CRYPTO_GF128MUL=m ++CONFIG_CRYPTO_ECB=m ++CONFIG_CRYPTO_CBC=y ++CONFIG_CRYPTO_PCBC=m ++CONFIG_CRYPTO_LRW=m ++CONFIG_CRYPTO_DES=y ++CONFIG_CRYPTO_FCRYPT=m ++# CONFIG_CRYPTO_BLOWFISH is not set ++# CONFIG_CRYPTO_TWOFISH is not set ++# CONFIG_CRYPTO_SERPENT is not set ++# CONFIG_CRYPTO_AES is not set ++# CONFIG_CRYPTO_CAST5 is not set ++# CONFIG_CRYPTO_CAST6 is not set ++# CONFIG_CRYPTO_TEA is not set ++# CONFIG_CRYPTO_ARC4 is not set ++# CONFIG_CRYPTO_KHAZAD is not set ++# CONFIG_CRYPTO_ANUBIS is not set ++# CONFIG_CRYPTO_DEFLATE is not set ++# CONFIG_CRYPTO_MICHAEL_MIC is not set ++# CONFIG_CRYPTO_CRC32C is not set ++CONFIG_CRYPTO_CAMELLIA=m ++# CONFIG_CRYPTO_TEST is not set ++ ++# ++# Hardware crypto devices ++# ++ ++# ++# Library routines ++# ++CONFIG_BITREVERSE=y ++CONFIG_CRC_CCITT=m ++# CONFIG_CRC16 is not set ++CONFIG_CRC32=y ++# CONFIG_LIBCRC32C is not set ++CONFIG_ZLIB_INFLATE=y ++CONFIG_ZLIB_DEFLATE=y ++CONFIG_TEXTSEARCH=y ++CONFIG_TEXTSEARCH_KMP=m ++CONFIG_TEXTSEARCH_BM=m ++CONFIG_TEXTSEARCH_FSM=m ++CONFIG_PLIST=y ++CONFIG_HAS_IOMEM=y ++CONFIG_HAS_IOPORT=y +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/arch/mips/configs/ip27_defconfig linux-2.6.29-rc3.owrt/arch/mips/configs/ip27_defconfig +--- linux-2.6.29.owrt/arch/mips/configs/ip27_defconfig 2009-05-10 22:04:40.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/arch/mips/configs/ip27_defconfig 2009-05-10 23:48:28.000000000 +0200 +@@ -53,7 +53,7 @@ + CONFIG_SCHED_NO_NO_OMIT_FRAME_POINTER=y + CONFIG_GENERIC_HARDIRQS_NO__DO_IRQ=y + CONFIG_ARC=y +-CONFIG_DMA_COHERENT=y ++CONFIG_DMA_IP27=y + CONFIG_EARLY_PRINTK=y + CONFIG_SYS_HAS_EARLY_PRINTK=y + # CONFIG_NO_IOPORT is not set +@@ -512,7 +512,7 @@ + CONFIG_MD_RAID0=y + CONFIG_MD_RAID1=y + CONFIG_MD_RAID10=m +-CONFIG_MD_RAID456=y ++CONFIG_MD_RAID456=m + CONFIG_MD_RAID5_RESHAPE=y + CONFIG_MD_MULTIPATH=m + CONFIG_MD_FAULTY=m +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/arch/mips/configs/jmr3927_defconfig linux-2.6.29-rc3.owrt/arch/mips/configs/jmr3927_defconfig +--- linux-2.6.29.owrt/arch/mips/configs/jmr3927_defconfig 2009-05-10 22:04:40.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/arch/mips/configs/jmr3927_defconfig 2009-05-10 23:48:28.000000000 +0200 +@@ -1,7 +1,7 @@ + # + # Automatically generated make config: don't edit +-# Linux kernel version: 2.6.29-rc7 +-# Wed Mar 4 23:07:16 2009 ++# Linux kernel version: 2.6.26-rc9 ++# Fri Jul 11 23:01:36 2008 + # + CONFIG_MIPS=y + +@@ -18,10 +18,8 @@ + # CONFIG_LEMOTE_FULONG is not set + # CONFIG_MIPS_MALTA is not set + # CONFIG_MIPS_SIM is not set +-# CONFIG_MACH_EMMA is not set ++# CONFIG_MARKEINS is not set + # CONFIG_MACH_VR41XX is not set +-# CONFIG_NXP_STB220 is not set +-# CONFIG_NXP_STB225 is not set + # CONFIG_PNX8550_JBS is not set + # CONFIG_PNX8550_STB810 is not set + # CONFIG_PMC_MSP is not set +@@ -41,11 +39,7 @@ + # CONFIG_SNI_RM is not set + CONFIG_MACH_TX39XX=y + # CONFIG_MACH_TX49XX is not set +-# CONFIG_MIKROTIK_RB532 is not set + # CONFIG_WR_PPMC is not set +-# CONFIG_CAVIUM_OCTEON_SIMULATOR is not set +-# CONFIG_CAVIUM_OCTEON_REFERENCE_BOARD is not set +-CONFIG_MACH_TXX9=y + CONFIG_TOSHIBA_JMR3927=y + CONFIG_SOC_TX3927=y + # CONFIG_TOSHIBA_FPCIB0 is not set +@@ -60,14 +54,12 @@ + CONFIG_GENERIC_CLOCKEVENTS=y + CONFIG_GENERIC_TIME=y + CONFIG_GENERIC_CMOS_UPDATE=y +-CONFIG_SCHED_OMIT_FRAME_POINTER=y ++CONFIG_SCHED_NO_NO_OMIT_FRAME_POINTER=y + CONFIG_GENERIC_HARDIRQS_NO__DO_IRQ=y + CONFIG_CEVT_TXX9=y + CONFIG_GPIO_TXX9=y + CONFIG_DMA_NONCOHERENT=y + CONFIG_DMA_NEED_PCI_MAP_STATE=y +-CONFIG_EARLY_PRINTK=y +-CONFIG_SYS_HAS_EARLY_PRINTK=y + # CONFIG_HOTPLUG_CPU is not set + # CONFIG_NO_IOPORT is not set + CONFIG_GENERIC_GPIO=y +@@ -95,7 +87,6 @@ + # CONFIG_CPU_TX49XX 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_NEVADA is not set + # CONFIG_CPU_R8000 is not set +@@ -103,7 +94,6 @@ + # CONFIG_CPU_RM7000 is not set + # CONFIG_CPU_RM9000 is not set + # CONFIG_CPU_SB1 is not set +-# CONFIG_CPU_CAVIUM_OCTEON is not set + CONFIG_SYS_HAS_CPU_TX39XX=y + CONFIG_SYS_SUPPORTS_32BIT_KERNEL=y + CONFIG_CPU_SUPPORTS_32BIT_KERNEL=y +@@ -127,12 +117,14 @@ + CONFIG_ARCH_POPULATES_NODE_MAP=y + CONFIG_FLATMEM=y + CONFIG_FLAT_NODE_MEM_MAP=y ++# CONFIG_SPARSEMEM_STATIC is not set ++# CONFIG_SPARSEMEM_VMEMMAP_ENABLE is not set + CONFIG_PAGEFLAGS_EXTENDED=y + CONFIG_SPLIT_PTLOCK_CPUS=4 +-# CONFIG_PHYS_ADDR_T_64BIT is not set ++# CONFIG_RESOURCES_64BIT is not set + CONFIG_ZONE_DMA_FLAG=0 + CONFIG_VIRT_TO_BUS=y +-CONFIG_UNEVICTABLE_LRU=y ++# CONFIG_TICK_ONESHOT is not set + # CONFIG_NO_HZ is not set + # CONFIG_HIGH_RES_TIMERS is not set + CONFIG_GENERIC_CLOCKEVENTS_BUILD=y +@@ -167,15 +159,6 @@ + # CONFIG_BSD_PROCESS_ACCT is not set + # CONFIG_TASKSTATS is not set + # CONFIG_AUDIT is not set +- +-# +-# RCU Subsystem +-# +-CONFIG_CLASSIC_RCU=y +-# CONFIG_TREE_RCU is not set +-# CONFIG_PREEMPT_RCU is not set +-# CONFIG_TREE_RCU_TRACE is not set +-# CONFIG_PREEMPT_RCU_TRACE is not set + # CONFIG_IKCONFIG is not set + CONFIG_LOG_BUF_SHIFT=14 + # CONFIG_CGROUPS is not set +@@ -188,6 +171,7 @@ + CONFIG_SYSCTL=y + CONFIG_EMBEDDED=y + CONFIG_SYSCTL_SYSCALL=y ++CONFIG_SYSCTL_SYSCALL_CHECK=y + CONFIG_KALLSYMS=y + # CONFIG_KALLSYMS_EXTRA_PASS is not set + # CONFIG_HOTPLUG is not set +@@ -204,23 +188,26 @@ + CONFIG_TIMERFD=y + CONFIG_EVENTFD=y + CONFIG_SHMEM=y +-CONFIG_AIO=y + CONFIG_VM_EVENT_COUNTERS=y +-CONFIG_PCI_QUIRKS=y + CONFIG_SLAB=y + # CONFIG_SLUB is not set + # CONFIG_SLOB is not set + # CONFIG_PROFILING is not set ++# CONFIG_MARKERS is not set + CONFIG_HAVE_OPROFILE=y +-# CONFIG_HAVE_GENERIC_DMA_COHERENT is not set ++# CONFIG_HAVE_KPROBES is not set ++# CONFIG_HAVE_KRETPROBES is not set ++# CONFIG_HAVE_DMA_ATTRS is not set ++CONFIG_PROC_PAGE_MONITOR=y + CONFIG_SLABINFO=y + CONFIG_RT_MUTEXES=y ++# CONFIG_TINY_SHMEM is not set + CONFIG_BASE_SMALL=0 + # CONFIG_MODULES is not set + CONFIG_BLOCK=y + # CONFIG_LBD is not set + # CONFIG_BLK_DEV_IO_TRACE is not set +-# CONFIG_BLK_DEV_INTEGRITY is not set ++# CONFIG_LSF is not set + + # + # IO Schedulers +@@ -234,7 +221,7 @@ + CONFIG_DEFAULT_CFQ=y + # CONFIG_DEFAULT_NOOP is not set + CONFIG_DEFAULT_IOSCHED="cfq" +-# CONFIG_FREEZER is not set ++CONFIG_CLASSIC_RCU=y + + # + # Bus options (PCI, PCMCIA, EISA, ISA, TC) +@@ -244,15 +231,12 @@ + CONFIG_PCI_DOMAINS=y + # CONFIG_ARCH_SUPPORTS_MSI is not set + CONFIG_PCI_LEGACY=y +-# CONFIG_PCI_STUB is not set + CONFIG_MMU=y + + # + # Executable file formats + # + CONFIG_BINFMT_ELF=y +-# CONFIG_CORE_DUMP_DEFAULT_ELF_HEADERS is not set +-# CONFIG_HAVE_AOUT is not set + # CONFIG_BINFMT_MISC is not set + CONFIG_TRAD_SIGNALS=y + +@@ -261,12 +245,15 @@ + # + CONFIG_ARCH_SUSPEND_POSSIBLE=y + # CONFIG_PM is not set ++ ++# ++# Networking ++# + CONFIG_NET=y + + # + # Networking options + # +-CONFIG_COMPAT_NET_DEV_OPS=y + CONFIG_PACKET=y + # CONFIG_PACKET_MMAP is not set + CONFIG_UNIX=y +@@ -306,7 +293,6 @@ + # CONFIG_IPX is not set + # CONFIG_ATALK is not set + # CONFIG_NET_SCHED is not set +-# CONFIG_DCB is not set + + # + # Network testing +@@ -316,9 +302,14 @@ + # CONFIG_CAN is not set + # CONFIG_IRDA is not set + # CONFIG_BT is not set +-# CONFIG_PHONET is not set +-# CONFIG_WIRELESS is not set +-# CONFIG_WIMAX is not set ++ ++# ++# Wireless ++# ++# CONFIG_CFG80211 is not set ++# CONFIG_WIRELESS_EXT is not set ++# CONFIG_MAC80211 is not set ++# CONFIG_IEEE80211 is not set + # CONFIG_RFKILL is not set + + # +@@ -332,89 +323,7 @@ + CONFIG_PREVENT_FIRMWARE_BUILD=y + # CONFIG_SYS_HYPERVISOR is not set + # CONFIG_CONNECTOR is not set +-CONFIG_MTD=y +-# CONFIG_MTD_DEBUG is not set +-# CONFIG_MTD_CONCAT is not set +-CONFIG_MTD_PARTITIONS=y +-# CONFIG_MTD_REDBOOT_PARTS is not set +-CONFIG_MTD_CMDLINE_PARTS=y +-# CONFIG_MTD_AR7_PARTS is not set +- +-# +-# User Modules And Translation Layers +-# +-CONFIG_MTD_CHAR=y +-# CONFIG_MTD_BLKDEVS is not set +-# CONFIG_MTD_BLOCK is not set +-# CONFIG_MTD_BLOCK_RO is not set +-# CONFIG_FTL is not set +-# CONFIG_NFTL is not set +-# CONFIG_INFTL is not set +-# CONFIG_RFD_FTL is not set +-# CONFIG_SSFDC is not set +-# CONFIG_MTD_OOPS is not set +- +-# +-# RAM/ROM/Flash chip drivers +-# +-CONFIG_MTD_CFI=y +-CONFIG_MTD_JEDECPROBE=y +-CONFIG_MTD_GEN_PROBE=y +-# CONFIG_MTD_CFI_ADV_OPTIONS is not set +-CONFIG_MTD_MAP_BANK_WIDTH_1=y +-CONFIG_MTD_MAP_BANK_WIDTH_2=y +-CONFIG_MTD_MAP_BANK_WIDTH_4=y +-# CONFIG_MTD_MAP_BANK_WIDTH_8 is not set +-# CONFIG_MTD_MAP_BANK_WIDTH_16 is not set +-# CONFIG_MTD_MAP_BANK_WIDTH_32 is not set +-CONFIG_MTD_CFI_I1=y +-CONFIG_MTD_CFI_I2=y +-# CONFIG_MTD_CFI_I4 is not set +-# CONFIG_MTD_CFI_I8 is not set +-# CONFIG_MTD_CFI_INTELEXT is not set +-CONFIG_MTD_CFI_AMDSTD=y +-# CONFIG_MTD_CFI_STAA is not set +-CONFIG_MTD_CFI_UTIL=y +-# CONFIG_MTD_RAM is not set +-# CONFIG_MTD_ROM is not set +-# CONFIG_MTD_ABSENT is not set +- +-# +-# Mapping drivers for chip access +-# +-# CONFIG_MTD_COMPLEX_MAPPINGS is not set +-CONFIG_MTD_PHYSMAP=y +-# CONFIG_MTD_PHYSMAP_COMPAT is not set +-# CONFIG_MTD_INTEL_VR_NOR is not set +-# CONFIG_MTD_PLATRAM is not set +- +-# +-# Self-contained MTD device drivers +-# +-# CONFIG_MTD_PMC551 is not set +-# CONFIG_MTD_SLRAM is not set +-# CONFIG_MTD_PHRAM is not set +-# CONFIG_MTD_MTDRAM is not set +-# CONFIG_MTD_BLOCK2MTD is not set +- +-# +-# Disk-On-Chip Device Drivers +-# +-# CONFIG_MTD_DOC2000 is not set +-# CONFIG_MTD_DOC2001 is not set +-# CONFIG_MTD_DOC2001PLUS is not set +-# CONFIG_MTD_NAND is not set +-# CONFIG_MTD_ONENAND is not set +- +-# +-# LPDDR flash memory drivers +-# +-# CONFIG_MTD_LPDDR is not set +- +-# +-# UBI - Unsorted block images +-# +-# CONFIG_MTD_UBI is not set ++# CONFIG_MTD is not set + # CONFIG_PARPORT is not set + CONFIG_BLK_DEV=y + # CONFIG_BLK_CPQ_DA is not set +@@ -427,7 +336,6 @@ + # CONFIG_BLK_DEV_RAM is not set + # CONFIG_CDROM_PKTCDVD is not set + # CONFIG_ATA_OVER_ETH is not set +-# CONFIG_BLK_DEV_HD is not set + # CONFIG_MISC_DEVICES is not set + CONFIG_HAVE_IDE=y + # CONFIG_IDE is not set +@@ -453,6 +361,7 @@ + # CONFIG_IEEE1394 is not set + # CONFIG_I2O is not set + CONFIG_NETDEVICES=y ++# CONFIG_NETDEVICES_MULTIQUEUE is not set + # CONFIG_DUMMY is not set + # CONFIG_BONDING is not set + # CONFIG_EQUALIZER is not set +@@ -474,9 +383,6 @@ + # CONFIG_BROADCOM_PHY is not set + # CONFIG_ICPLUS_PHY is not set + # CONFIG_REALTEK_PHY is not set +-# CONFIG_NATIONAL_PHY is not set +-# CONFIG_STE10XP is not set +-# CONFIG_LSI_ET1011C_PHY is not set + # CONFIG_FIXED_PHY is not set + # CONFIG_MDIO_BITBANG is not set + CONFIG_NET_ETHERNET=y +@@ -486,7 +392,6 @@ + # CONFIG_SUNGEM is not set + # CONFIG_CASSINI is not set + # CONFIG_NET_VENDOR_3COM is not set +-# CONFIG_SMC91X is not set + # CONFIG_DM9000 is not set + # CONFIG_NET_TULIP is not set + # CONFIG_HP100 is not set +@@ -494,9 +399,6 @@ + # CONFIG_IBM_NEW_EMAC_RGMII is not set + # CONFIG_IBM_NEW_EMAC_TAH is not set + # CONFIG_IBM_NEW_EMAC_EMAC4 is not set +-# CONFIG_IBM_NEW_EMAC_NO_FLOW_CTRL is not set +-# CONFIG_IBM_NEW_EMAC_MAL_CLR_ICINTSTAT is not set +-# CONFIG_IBM_NEW_EMAC_MAL_COMMON_ERR is not set + CONFIG_NET_PCI=y + # CONFIG_PCNET32 is not set + # CONFIG_AMD8111_ETH is not set +@@ -504,6 +406,7 @@ + # CONFIG_B44 is not set + # CONFIG_FORCEDETH is not set + CONFIG_TC35815=y ++# CONFIG_EEPRO100 is not set + # CONFIG_E100 is not set + # CONFIG_FEALNX is not set + # CONFIG_NATSEMI is not set +@@ -512,11 +415,9 @@ + # CONFIG_R6040 is not set + # CONFIG_SIS900 is not set + # CONFIG_EPIC100 is not set +-# CONFIG_SMSC9420 is not set + # CONFIG_SUNDANCE is not set + # CONFIG_TLAN is not set + # CONFIG_VIA_RHINE is not set +-# CONFIG_ATL2 is not set + # CONFIG_NETDEV_1000 is not set + # CONFIG_NETDEV_10000 is not set + # CONFIG_TR is not set +@@ -527,10 +428,6 @@ + # CONFIG_WLAN_PRE80211 is not set + # CONFIG_WLAN_80211 is not set + # CONFIG_IWLWIFI_LEDS is not set +- +-# +-# Enable WiMAX (Networking options) to see the WiMAX drivers +-# + # CONFIG_WAN is not set + # CONFIG_FDDI is not set + # CONFIG_PPP is not set +@@ -543,7 +440,27 @@ + # + # Input device support + # +-# CONFIG_INPUT is not set ++CONFIG_INPUT=y ++# CONFIG_INPUT_FF_MEMLESS is not set ++# CONFIG_INPUT_POLLDEV is not set ++ ++# ++# Userland interfaces ++# ++# CONFIG_INPUT_MOUSEDEV is not set ++# CONFIG_INPUT_JOYDEV is not set ++# CONFIG_INPUT_EVDEV is not set ++# CONFIG_INPUT_EVBUG is not set ++ ++# ++# Input Device Drivers ++# ++# CONFIG_INPUT_KEYBOARD is not set ++# CONFIG_INPUT_MOUSE is not set ++# CONFIG_INPUT_JOYSTICK is not set ++# CONFIG_INPUT_TABLET is not set ++# CONFIG_INPUT_TOUCHSCREEN is not set ++# CONFIG_INPUT_MISC is not set + + # + # Hardware I/O ports +@@ -600,11 +517,10 @@ + CONFIG_DEVPORT=y + # CONFIG_I2C is not set + # CONFIG_SPI is not set +-CONFIG_ARCH_REQUIRE_GPIOLIB=y +-CONFIG_GPIOLIB=y ++CONFIG_HAVE_GPIO_LIB=y + + # +-# Memory mapped GPIO expanders: ++# GPIO Support + # + + # +@@ -612,11 +528,6 @@ + # + + # +-# PCI GPIO expanders: +-# +-# CONFIG_GPIO_BT8XX is not set +- +-# + # SPI GPIO expanders: + # + # CONFIG_W1 is not set +@@ -631,7 +542,6 @@ + # Watchdog Device Drivers + # + # CONFIG_SOFT_WATCHDOG is not set +-# CONFIG_ALIM7101_WDT is not set + CONFIG_TXX9_WDT=y + + # +@@ -639,21 +549,18 @@ + # + # CONFIG_PCIPCWATCHDOG is not set + # CONFIG_WDTPCI is not set +-CONFIG_SSB_POSSIBLE=y + + # + # Sonics Silicon Backplane + # ++CONFIG_SSB_POSSIBLE=y + # CONFIG_SSB is not set + + # + # Multifunction device drivers + # +-# CONFIG_MFD_CORE is not set + # CONFIG_MFD_SM501 is not set + # CONFIG_HTC_PASIC3 is not set +-# CONFIG_MFD_TMIO is not set +-# CONFIG_REGULATOR is not set + + # + # Multimedia devices +@@ -684,26 +591,16 @@ + # Display device support + # + # CONFIG_DISPLAY_SUPPORT is not set ++ ++# ++# Sound ++# + # CONFIG_SOUND is not set ++# CONFIG_HID_SUPPORT is not set + # CONFIG_USB_SUPPORT is not set + # CONFIG_MMC is not set + # CONFIG_MEMSTICK is not set +-CONFIG_NEW_LEDS=y +-CONFIG_LEDS_CLASS=y +- +-# +-# LED drivers +-# +-CONFIG_LEDS_GPIO=y +- +-# +-# LED Triggers +-# +-CONFIG_LEDS_TRIGGERS=y +-# CONFIG_LEDS_TRIGGER_TIMER is not set +-CONFIG_LEDS_TRIGGER_HEARTBEAT=y +-# CONFIG_LEDS_TRIGGER_BACKLIGHT is not set +-# CONFIG_LEDS_TRIGGER_DEFAULT_ON is not set ++# CONFIG_NEW_LEDS is not set + # CONFIG_ACCESSIBILITY is not set + # CONFIG_INFINIBAND is not set + CONFIG_RTC_LIB=y +@@ -729,34 +626,27 @@ + # Platform RTC drivers + # + # CONFIG_RTC_DRV_CMOS is not set +-# CONFIG_RTC_DRV_DS1286 is not set + # CONFIG_RTC_DRV_DS1511 is not set + # CONFIG_RTC_DRV_DS1553 is not set + CONFIG_RTC_DRV_DS1742=y + # CONFIG_RTC_DRV_STK17TA8 is not set + # CONFIG_RTC_DRV_M48T86 is not set +-# CONFIG_RTC_DRV_M48T35 is not set + # CONFIG_RTC_DRV_M48T59 is not set +-# CONFIG_RTC_DRV_BQ4802 is not set + # CONFIG_RTC_DRV_V3020 is not set + + # + # on-CPU RTC drivers + # +-# CONFIG_DMADEVICES is not set + # CONFIG_UIO is not set +-# CONFIG_STAGING is not set + + # + # File systems + # + # CONFIG_EXT2_FS is not set + # CONFIG_EXT3_FS is not set +-# CONFIG_EXT4_FS is not set + # CONFIG_REISERFS_FS is not set + # CONFIG_JFS_FS is not set + # CONFIG_FS_POSIX_ACL is not set +-CONFIG_FILE_LOCKING=y + # CONFIG_XFS_FS is not set + # CONFIG_OCFS2_FS is not set + CONFIG_DNOTIFY=y +@@ -786,17 +676,28 @@ + CONFIG_PROC_FS=y + CONFIG_PROC_KCORE=y + CONFIG_PROC_SYSCTL=y +-CONFIG_PROC_PAGE_MONITOR=y + CONFIG_SYSFS=y + # CONFIG_TMPFS is not set + # CONFIG_HUGETLB_PAGE is not set + # CONFIG_CONFIGFS_FS is not set +-# CONFIG_MISC_FILESYSTEMS is not set ++ ++# ++# Miscellaneous filesystems ++# ++# CONFIG_HFSPLUS_FS is not set ++# CONFIG_CRAMFS is not set ++# CONFIG_VXFS_FS is not set ++# CONFIG_MINIX_FS is not set ++# CONFIG_HPFS_FS is not set ++# CONFIG_QNX4FS_FS is not set ++# CONFIG_ROMFS_FS is not set ++# CONFIG_SYSV_FS is not set ++# CONFIG_UFS_FS is not set + CONFIG_NETWORK_FILESYSTEMS=y + CONFIG_NFS_FS=y + # CONFIG_NFS_V3 is not set +-CONFIG_ROOT_NFS=y + # CONFIG_NFSD is not set ++CONFIG_ROOT_NFS=y + CONFIG_LOCKD=y + CONFIG_NFS_COMMON=y + CONFIG_SUNRPC=y +@@ -825,16 +726,7 @@ + # CONFIG_DEBUG_FS is not set + # CONFIG_HEADERS_CHECK is not set + # CONFIG_DEBUG_KERNEL is not set +-# CONFIG_DEBUG_MEMORY_INIT is not set +-# CONFIG_RCU_CPU_STALL_DETECTOR is not set +-CONFIG_SYSCTL_SYSCALL_CHECK=y +- +-# +-# Tracers +-# +-# CONFIG_DYNAMIC_PRINTK_DEBUG is not set + # CONFIG_SAMPLES is not set +-CONFIG_HAVE_ARCH_KGDB=y + CONFIG_CMDLINE="" + + # +@@ -842,18 +734,15 @@ + # + # CONFIG_KEYS is not set + # CONFIG_SECURITY is not set +-# CONFIG_SECURITYFS is not set +-# CONFIG_SECURITY_FILE_CAPABILITIES is not set + # CONFIG_CRYPTO is not set + + # + # Library routines + # + CONFIG_BITREVERSE=y +-CONFIG_GENERIC_FIND_LAST_BIT=y ++# CONFIG_GENERIC_FIND_FIRST_BIT is not set + # CONFIG_CRC_CCITT is not set + # CONFIG_CRC16 is not set +-# CONFIG_CRC_T10DIF is not set + # CONFIG_CRC_ITU_T is not set + CONFIG_CRC32=y + # CONFIG_CRC7 is not set +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/arch/mips/configs/markeins_defconfig linux-2.6.29-rc3.owrt/arch/mips/configs/markeins_defconfig +--- linux-2.6.29.owrt/arch/mips/configs/markeins_defconfig 2009-05-10 22:04:40.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/arch/mips/configs/markeins_defconfig 1970-01-01 01:00:00.000000000 +0100 +@@ -1,1439 +0,0 @@ +-# +-# Automatically generated make config: don't edit +-# Linux kernel version: 2.6.20 +-# Tue Feb 20 21:47:29 2007 +-# +-CONFIG_MIPS=y +- +-# +-# Machine selection +-# +-CONFIG_ZONE_DMA=y +-# CONFIG_MIPS_MTX1 is not set +-# CONFIG_MIPS_BOSPORUS is not set +-# CONFIG_MIPS_PB1000 is not set +-# CONFIG_MIPS_PB1100 is not set +-# CONFIG_MIPS_PB1500 is not set +-# CONFIG_MIPS_PB1550 is not set +-# CONFIG_MIPS_PB1200 is not set +-# CONFIG_MIPS_DB1000 is not set +-# CONFIG_MIPS_DB1100 is not set +-# CONFIG_MIPS_DB1500 is not set +-# CONFIG_MIPS_DB1550 is not set +-# CONFIG_MIPS_DB1200 is not set +-# CONFIG_MIPS_MIRAGE is not set +-# CONFIG_BASLER_EXCITE is not set +-# CONFIG_MIPS_COBALT is not set +-# CONFIG_MACH_DECSTATION is not set +-# CONFIG_MACH_JAZZ is not set +-# CONFIG_MIPS_MALTA is not set +-# CONFIG_WR_PPMC is not set +-# CONFIG_MIPS_SIM is not set +-# CONFIG_MOMENCO_JAGUAR_ATX is not set +-# CONFIG_MIPS_XXS1500 is not set +-# CONFIG_PNX8550_JBS is not set +-# CONFIG_PNX8550_STB810 is not set +-# CONFIG_MACH_VR41XX is not set +-# CONFIG_PMC_YOSEMITE is not set +-CONFIG_NEC_MARKEINS=y +-# CONFIG_SGI_IP22 is not set +-# CONFIG_SGI_IP27 is not set +-# CONFIG_SGI_IP32 is not set +-# CONFIG_SIBYTE_BIGSUR is not set +-# CONFIG_SIBYTE_SWARM is not set +-# CONFIG_SIBYTE_SENTOSA is not set +-# CONFIG_SIBYTE_RHONE is not set +-# CONFIG_SIBYTE_CARMEL is not set +-# CONFIG_SIBYTE_LITTLESUR is not set +-# CONFIG_SIBYTE_CRHINE is not set +-# CONFIG_SIBYTE_CRHONE is not set +-# CONFIG_SNI_RM is not set +-# CONFIG_TOSHIBA_JMR3927 is not set +-# CONFIG_TOSHIBA_RBTX4927 is not set +-# CONFIG_TOSHIBA_RBTX4938 is not set +-CONFIG_RWSEM_GENERIC_SPINLOCK=y +-# CONFIG_ARCH_HAS_ILOG2_U32 is not set +-# CONFIG_ARCH_HAS_ILOG2_U64 is not set +-CONFIG_GENERIC_FIND_NEXT_BIT=y +-CONFIG_GENERIC_HWEIGHT=y +-CONFIG_GENERIC_CALIBRATE_DELAY=y +-CONFIG_GENERIC_TIME=y +-CONFIG_SCHED_NO_NO_OMIT_FRAME_POINTER=y +-# CONFIG_GENERIC_HARDIRQS_NO__DO_IRQ is not set +-CONFIG_DMA_NONCOHERENT=y +-CONFIG_DMA_NEED_PCI_MAP_STATE=y +-CONFIG_CPU_BIG_ENDIAN=y +-# CONFIG_CPU_LITTLE_ENDIAN is not set +-CONFIG_SYS_SUPPORTS_BIG_ENDIAN=y +-CONFIG_SYS_SUPPORTS_LITTLE_ENDIAN=y +-CONFIG_IRQ_CPU=y +-CONFIG_SWAP_IO_SPACE=y +-CONFIG_SOC_EMMA2RH=y +-CONFIG_MIPS_L1_CACHE_SHIFT=5 +- +-# +-# CPU selection +-# +-# CONFIG_CPU_MIPS32_R1 is not set +-# CONFIG_CPU_MIPS32_R2 is not set +-# CONFIG_CPU_MIPS64_R1 is not set +-# CONFIG_CPU_MIPS64_R2 is not set +-# CONFIG_CPU_R3000 is not set +-# CONFIG_CPU_TX39XX is not set +-# CONFIG_CPU_VR41XX is not set +-# CONFIG_CPU_R4300 is not set +-# CONFIG_CPU_R4X00 is not set +-# CONFIG_CPU_TX49XX is not set +-CONFIG_CPU_R5000=y +-# CONFIG_CPU_R5432 is not set +-# CONFIG_CPU_R6000 is not set +-# CONFIG_CPU_NEVADA is not set +-# CONFIG_CPU_R8000 is not set +-# CONFIG_CPU_R10000 is not set +-# CONFIG_CPU_RM7000 is not set +-# CONFIG_CPU_RM9000 is not set +-# CONFIG_CPU_SB1 is not set +-CONFIG_SYS_HAS_CPU_R5000=y +-CONFIG_SYS_SUPPORTS_32BIT_KERNEL=y +-CONFIG_CPU_SUPPORTS_32BIT_KERNEL=y +-CONFIG_CPU_SUPPORTS_64BIT_KERNEL=y +- +-# +-# Kernel type +-# +-CONFIG_32BIT=y +-# CONFIG_64BIT is not set +-CONFIG_PAGE_SIZE_4KB=y +-# CONFIG_PAGE_SIZE_8KB is not set +-# CONFIG_PAGE_SIZE_16KB is not set +-# CONFIG_PAGE_SIZE_64KB is not set +-CONFIG_MIPS_MT_DISABLED=y +-# CONFIG_MIPS_MT_SMP is not set +-# CONFIG_MIPS_MT_SMTC is not set +-# CONFIG_MIPS_VPE_LOADER is not set +-# CONFIG_64BIT_PHYS_ADDR is not set +-CONFIG_CPU_HAS_LLSC=y +-CONFIG_CPU_HAS_SYNC=y +-CONFIG_GENERIC_HARDIRQS=y +-CONFIG_GENERIC_IRQ_PROBE=y +-CONFIG_ARCH_FLATMEM_ENABLE=y +-CONFIG_SELECT_MEMORY_MODEL=y +-CONFIG_FLATMEM_MANUAL=y +-# CONFIG_DISCONTIGMEM_MANUAL is not set +-# CONFIG_SPARSEMEM_MANUAL is not set +-CONFIG_FLATMEM=y +-CONFIG_FLAT_NODE_MEM_MAP=y +-# CONFIG_SPARSEMEM_STATIC is not set +-CONFIG_SPLIT_PTLOCK_CPUS=4 +-# CONFIG_RESOURCES_64BIT is not set +-CONFIG_ZONE_DMA_FLAG=1 +-# CONFIG_HZ_48 is not set +-# CONFIG_HZ_100 is not set +-# CONFIG_HZ_128 is not set +-# CONFIG_HZ_250 is not set +-# CONFIG_HZ_256 is not set +-CONFIG_HZ_1000=y +-# CONFIG_HZ_1024 is not set +-CONFIG_SYS_SUPPORTS_ARBIT_HZ=y +-CONFIG_HZ=1000 +-# CONFIG_PREEMPT_NONE is not set +-# CONFIG_PREEMPT_VOLUNTARY is not set +-CONFIG_PREEMPT=y +-CONFIG_PREEMPT_BKL=y +-# CONFIG_KEXEC is not set +-CONFIG_LOCKDEP_SUPPORT=y +-CONFIG_STACKTRACE_SUPPORT=y +-CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config" +- +-# +-# Code maturity level options +-# +-CONFIG_EXPERIMENTAL=y +-CONFIG_BROKEN_ON_SMP=y +-CONFIG_LOCK_KERNEL=y +-CONFIG_INIT_ENV_ARG_LIMIT=32 +- +-# +-# General setup +-# +-CONFIG_LOCALVERSION="" +-CONFIG_LOCALVERSION_AUTO=y +-CONFIG_SWAP=y +-CONFIG_SYSVIPC=y +-# CONFIG_IPC_NS is not set +-CONFIG_SYSVIPC_SYSCTL=y +-CONFIG_POSIX_MQUEUE=y +-CONFIG_BSD_PROCESS_ACCT=y +-# CONFIG_BSD_PROCESS_ACCT_V3 is not set +-# CONFIG_TASKSTATS is not set +-# CONFIG_UTS_NS is not set +-# CONFIG_AUDIT is not set +-CONFIG_IKCONFIG=y +-CONFIG_IKCONFIG_PROC=y +-CONFIG_SYSFS_DEPRECATED=y +-# CONFIG_RELAY is not set +-# CONFIG_CC_OPTIMIZE_FOR_SIZE is not set +-CONFIG_SYSCTL=y +-CONFIG_EMBEDDED=y +-CONFIG_SYSCTL_SYSCALL=y +-CONFIG_KALLSYMS=y +-# CONFIG_KALLSYMS_EXTRA_PASS is not set +-CONFIG_HOTPLUG=y +-CONFIG_PRINTK=y +-CONFIG_BUG=y +-CONFIG_ELF_CORE=y +-CONFIG_BASE_FULL=y +-CONFIG_FUTEX=y +-CONFIG_EPOLL=y +-CONFIG_SHMEM=y +-CONFIG_SLAB=y +-CONFIG_VM_EVENT_COUNTERS=y +-CONFIG_RT_MUTEXES=y +-# CONFIG_TINY_SHMEM is not set +-CONFIG_BASE_SMALL=0 +-# CONFIG_SLOB is not set +- +-# +-# Loadable module support +-# +-CONFIG_MODULES=y +-CONFIG_MODULE_UNLOAD=y +-CONFIG_MODULE_FORCE_UNLOAD=y +-CONFIG_MODVERSIONS=y +-# CONFIG_MODULE_SRCVERSION_ALL is not set +-CONFIG_KMOD=y +- +-# +-# Block layer +-# +-CONFIG_BLOCK=y +-CONFIG_LBD=y +-# CONFIG_BLK_DEV_IO_TRACE is not set +-# CONFIG_LSF is not set +- +-# +-# IO Schedulers +-# +-CONFIG_IOSCHED_NOOP=y +-CONFIG_IOSCHED_AS=y +-CONFIG_IOSCHED_DEADLINE=y +-CONFIG_IOSCHED_CFQ=y +-CONFIG_DEFAULT_AS=y +-# CONFIG_DEFAULT_DEADLINE is not set +-# CONFIG_DEFAULT_CFQ is not set +-# CONFIG_DEFAULT_NOOP is not set +-CONFIG_DEFAULT_IOSCHED="anticipatory" +- +-# +-# Bus options (PCI, PCMCIA, EISA, ISA, TC) +-# +-CONFIG_HW_HAS_PCI=y +-CONFIG_PCI=y +-CONFIG_MMU=y +- +-# +-# PCCARD (PCMCIA/CardBus) support +-# +-# CONFIG_PCCARD is not set +- +-# +-# PCI Hotplug Support +-# +-# CONFIG_HOTPLUG_PCI is not set +- +-# +-# Executable file formats +-# +-CONFIG_BINFMT_ELF=y +-# CONFIG_BINFMT_MISC is not set +-CONFIG_TRAD_SIGNALS=y +- +-# +-# Power management options +-# +-CONFIG_PM=y +-# CONFIG_PM_LEGACY is not set +-# CONFIG_PM_DEBUG is not set +-# CONFIG_PM_SYSFS_DEPRECATED is not set +- +-# +-# Networking +-# +-CONFIG_NET=y +- +-# +-# Networking options +-# +-# CONFIG_NETDEBUG is not set +-CONFIG_PACKET=y +-CONFIG_PACKET_MMAP=y +-CONFIG_UNIX=y +-CONFIG_XFRM=y +-# CONFIG_XFRM_USER is not set +-# CONFIG_XFRM_SUB_POLICY is not set +-CONFIG_XFRM_MIGRATE=y +-CONFIG_NET_KEY=y +-CONFIG_NET_KEY_MIGRATE=y +-CONFIG_INET=y +-CONFIG_IP_MULTICAST=y +-CONFIG_IP_ADVANCED_ROUTER=y +-CONFIG_ASK_IP_FIB_HASH=y +-# CONFIG_IP_FIB_TRIE is not set +-CONFIG_IP_FIB_HASH=y +-CONFIG_IP_MULTIPLE_TABLES=y +-CONFIG_IP_ROUTE_MULTIPATH=y +-# CONFIG_IP_ROUTE_MULTIPATH_CACHED is not set +-CONFIG_IP_ROUTE_VERBOSE=y +-CONFIG_IP_PNP=y +-# CONFIG_IP_PNP_DHCP is not set +-CONFIG_IP_PNP_BOOTP=y +-# CONFIG_IP_PNP_RARP is not set +-# CONFIG_NET_IPIP is not set +-# CONFIG_NET_IPGRE is not set +-# CONFIG_IP_MROUTE is not set +-# CONFIG_ARPD is not set +-CONFIG_SYN_COOKIES=y +-# CONFIG_INET_AH is not set +-# CONFIG_INET_ESP is not set +-# CONFIG_INET_IPCOMP is not set +-# CONFIG_INET_XFRM_TUNNEL is not set +-CONFIG_INET_TUNNEL=m +-CONFIG_INET_XFRM_MODE_TRANSPORT=m +-CONFIG_INET_XFRM_MODE_TUNNEL=m +-CONFIG_INET_XFRM_MODE_BEET=m +-CONFIG_INET_DIAG=y +-CONFIG_INET_TCP_DIAG=y +-# CONFIG_TCP_CONG_ADVANCED is not set +-CONFIG_TCP_CONG_CUBIC=y +-CONFIG_DEFAULT_TCP_CONG="cubic" +-CONFIG_TCP_MD5SIG=y +- +-# +-# IP: Virtual Server Configuration +-# +-# CONFIG_IP_VS is not set +-CONFIG_IPV6=m +-# CONFIG_IPV6_PRIVACY is not set +-# CONFIG_IPV6_ROUTER_PREF is not set +-# CONFIG_INET6_AH is not set +-# CONFIG_INET6_ESP is not set +-# CONFIG_INET6_IPCOMP is not set +-CONFIG_IPV6_MIP6=y +-# CONFIG_INET6_XFRM_TUNNEL is not set +-# CONFIG_INET6_TUNNEL is not set +-CONFIG_INET6_XFRM_MODE_TRANSPORT=m +-CONFIG_INET6_XFRM_MODE_TUNNEL=m +-CONFIG_INET6_XFRM_MODE_BEET=m +-CONFIG_INET6_XFRM_MODE_ROUTEOPTIMIZATION=m +-CONFIG_IPV6_SIT=m +-# CONFIG_IPV6_TUNNEL is not set +-CONFIG_IPV6_MULTIPLE_TABLES=y +-CONFIG_IPV6_SUBTREES=y +-CONFIG_NETWORK_SECMARK=y +-CONFIG_NETFILTER=y +-# CONFIG_NETFILTER_DEBUG is not set +- +-# +-# Core Netfilter Configuration +-# +-# CONFIG_NETFILTER_NETLINK is not set +-CONFIG_NF_CONNTRACK_ENABLED=m +-CONFIG_NF_CONNTRACK_SUPPORT=y +-# CONFIG_IP_NF_CONNTRACK_SUPPORT is not set +-CONFIG_NF_CONNTRACK=m +-CONFIG_NF_CT_ACCT=y +-CONFIG_NF_CONNTRACK_MARK=y +-CONFIG_NF_CONNTRACK_SECMARK=y +-CONFIG_NF_CONNTRACK_EVENTS=y +-CONFIG_NF_CT_PROTO_GRE=m +-CONFIG_NF_CT_PROTO_SCTP=m +-CONFIG_NF_CONNTRACK_AMANDA=m +-CONFIG_NF_CONNTRACK_FTP=m +-CONFIG_NF_CONNTRACK_H323=m +-CONFIG_NF_CONNTRACK_IRC=m +-# CONFIG_NF_CONNTRACK_NETBIOS_NS is not set +-CONFIG_NF_CONNTRACK_PPTP=m +-CONFIG_NF_CONNTRACK_SANE=m +-CONFIG_NF_CONNTRACK_SIP=m +-CONFIG_NF_CONNTRACK_TFTP=m +-CONFIG_NETFILTER_XTABLES=m +-CONFIG_NETFILTER_XT_TARGET_CLASSIFY=m +-CONFIG_NETFILTER_XT_TARGET_CONNMARK=m +-CONFIG_NETFILTER_XT_TARGET_DSCP=m +-CONFIG_NETFILTER_XT_TARGET_MARK=m +-CONFIG_NETFILTER_XT_TARGET_NFQUEUE=m +-CONFIG_NETFILTER_XT_TARGET_NFLOG=m +-CONFIG_NETFILTER_XT_TARGET_NOTRACK=m +-CONFIG_NETFILTER_XT_TARGET_SECMARK=m +-CONFIG_NETFILTER_XT_TARGET_CONNSECMARK=m +-CONFIG_NETFILTER_XT_TARGET_TCPMSS=m +-CONFIG_NETFILTER_XT_MATCH_COMMENT=m +-CONFIG_NETFILTER_XT_MATCH_CONNBYTES=m +-CONFIG_NETFILTER_XT_MATCH_CONNMARK=m +-CONFIG_NETFILTER_XT_MATCH_CONNTRACK=m +-CONFIG_NETFILTER_XT_MATCH_DCCP=m +-CONFIG_NETFILTER_XT_MATCH_DSCP=m +-CONFIG_NETFILTER_XT_MATCH_ESP=m +-CONFIG_NETFILTER_XT_MATCH_HELPER=m +-CONFIG_NETFILTER_XT_MATCH_LENGTH=m +-CONFIG_NETFILTER_XT_MATCH_LIMIT=m +-CONFIG_NETFILTER_XT_MATCH_MAC=m +-CONFIG_NETFILTER_XT_MATCH_MARK=m +-CONFIG_NETFILTER_XT_MATCH_POLICY=m +-CONFIG_NETFILTER_XT_MATCH_MULTIPORT=m +-CONFIG_NETFILTER_XT_MATCH_PKTTYPE=m +-CONFIG_NETFILTER_XT_MATCH_QUOTA=m +-CONFIG_NETFILTER_XT_MATCH_REALM=m +-CONFIG_NETFILTER_XT_MATCH_SCTP=m +-CONFIG_NETFILTER_XT_MATCH_STATE=m +-CONFIG_NETFILTER_XT_MATCH_STATISTIC=m +-CONFIG_NETFILTER_XT_MATCH_STRING=m +-CONFIG_NETFILTER_XT_MATCH_TCPMSS=m +-CONFIG_NETFILTER_XT_MATCH_HASHLIMIT=m +- +-# +-# IP: Netfilter Configuration +-# +-CONFIG_NF_CONNTRACK_IPV4=m +-CONFIG_NF_CONNTRACK_PROC_COMPAT=y +-# CONFIG_IP_NF_QUEUE is not set +-CONFIG_IP_NF_IPTABLES=m +-CONFIG_IP_NF_MATCH_IPRANGE=m +-CONFIG_IP_NF_MATCH_TOS=m +-CONFIG_IP_NF_MATCH_RECENT=m +-CONFIG_IP_NF_MATCH_ECN=m +-CONFIG_IP_NF_MATCH_AH=m +-CONFIG_IP_NF_MATCH_TTL=m +-CONFIG_IP_NF_MATCH_OWNER=m +-CONFIG_IP_NF_MATCH_ADDRTYPE=m +-CONFIG_IP_NF_FILTER=m +-CONFIG_IP_NF_TARGET_REJECT=m +-CONFIG_IP_NF_TARGET_LOG=m +-CONFIG_IP_NF_TARGET_ULOG=m +-CONFIG_NF_NAT=m +-CONFIG_NF_NAT_NEEDED=y +-CONFIG_IP_NF_TARGET_MASQUERADE=m +-CONFIG_IP_NF_TARGET_REDIRECT=m +-CONFIG_IP_NF_TARGET_NETMAP=m +-CONFIG_IP_NF_TARGET_SAME=m +-CONFIG_NF_NAT_SNMP_BASIC=m +-CONFIG_NF_NAT_PROTO_GRE=m +-CONFIG_NF_NAT_FTP=m +-CONFIG_NF_NAT_IRC=m +-CONFIG_NF_NAT_TFTP=m +-CONFIG_NF_NAT_AMANDA=m +-CONFIG_NF_NAT_PPTP=m +-CONFIG_NF_NAT_H323=m +-CONFIG_NF_NAT_SIP=m +-CONFIG_IP_NF_MANGLE=m +-CONFIG_IP_NF_TARGET_TOS=m +-CONFIG_IP_NF_TARGET_ECN=m +-CONFIG_IP_NF_TARGET_TTL=m +-CONFIG_IP_NF_TARGET_CLUSTERIP=m +-CONFIG_IP_NF_RAW=m +-CONFIG_IP_NF_ARPTABLES=m +-CONFIG_IP_NF_ARPFILTER=m +-CONFIG_IP_NF_ARP_MANGLE=m +- +-# +-# IPv6: Netfilter Configuration (EXPERIMENTAL) +-# +-CONFIG_NF_CONNTRACK_IPV6=m +-# CONFIG_IP6_NF_QUEUE is not set +-CONFIG_IP6_NF_IPTABLES=m +-CONFIG_IP6_NF_MATCH_RT=m +-CONFIG_IP6_NF_MATCH_OPTS=m +-CONFIG_IP6_NF_MATCH_FRAG=m +-CONFIG_IP6_NF_MATCH_HL=m +-CONFIG_IP6_NF_MATCH_OWNER=m +-CONFIG_IP6_NF_MATCH_IPV6HEADER=m +-CONFIG_IP6_NF_MATCH_AH=m +-CONFIG_IP6_NF_MATCH_MH=m +-CONFIG_IP6_NF_MATCH_EUI64=m +-CONFIG_IP6_NF_FILTER=m +-CONFIG_IP6_NF_TARGET_LOG=m +-CONFIG_IP6_NF_TARGET_REJECT=m +-CONFIG_IP6_NF_MANGLE=m +-CONFIG_IP6_NF_TARGET_HL=m +-CONFIG_IP6_NF_RAW=m +- +-# +-# DCCP Configuration (EXPERIMENTAL) +-# +-# CONFIG_IP_DCCP is not set +- +-# +-# SCTP Configuration (EXPERIMENTAL) +-# +-CONFIG_IP_SCTP=m +-# CONFIG_SCTP_DBG_MSG is not set +-# CONFIG_SCTP_DBG_OBJCNT is not set +-# CONFIG_SCTP_HMAC_NONE is not set +-# CONFIG_SCTP_HMAC_SHA1 is not set +-CONFIG_SCTP_HMAC_MD5=y +- +-# +-# TIPC Configuration (EXPERIMENTAL) +-# +-# CONFIG_TIPC is not set +-# CONFIG_ATM is not set +-# CONFIG_BRIDGE is not set +-# CONFIG_VLAN_8021Q is not set +-# CONFIG_DECNET is not set +-# CONFIG_LLC2 is not set +-# CONFIG_IPX is not set +-# CONFIG_ATALK is not set +-# CONFIG_X25 is not set +-# CONFIG_LAPB is not set +-# CONFIG_ECONET is not set +-# CONFIG_WAN_ROUTER is not set +- +-# +-# QoS and/or fair queueing +-# +-# CONFIG_NET_SCHED is not set +-CONFIG_NET_CLS_ROUTE=y +- +-# +-# Network testing +-# +-# CONFIG_NET_PKTGEN is not set +-# CONFIG_HAMRADIO is not set +-# CONFIG_IRDA is not set +-# CONFIG_BT is not set +-# CONFIG_IEEE80211 is not set +-CONFIG_FIB_RULES=y +- +-# +-# Device Drivers +-# +- +-# +-# Generic Driver Options +-# +-CONFIG_STANDALONE=y +-CONFIG_PREVENT_FIRMWARE_BUILD=y +-CONFIG_FW_LOADER=m +-# CONFIG_SYS_HYPERVISOR is not set +- +-# +-# Connector - unified userspace <-> kernelspace linker +-# +-# CONFIG_CONNECTOR is not set +- +-# +-# Memory Technology Devices (MTD) +-# +-CONFIG_MTD=y +-# CONFIG_MTD_DEBUG is not set +-# CONFIG_MTD_CONCAT is not set +-CONFIG_MTD_PARTITIONS=y +-# CONFIG_MTD_REDBOOT_PARTS is not set +-CONFIG_MTD_CMDLINE_PARTS=y +- +-# +-# User Modules And Translation Layers +-# +-CONFIG_MTD_CHAR=y +-CONFIG_MTD_BLKDEVS=y +-CONFIG_MTD_BLOCK=y +-# CONFIG_FTL is not set +-# CONFIG_NFTL is not set +-# CONFIG_INFTL is not set +-# CONFIG_RFD_FTL is not set +-# CONFIG_SSFDC is not set +- +-# +-# RAM/ROM/Flash chip drivers +-# +-CONFIG_MTD_CFI=y +-# CONFIG_MTD_JEDECPROBE is not set +-CONFIG_MTD_GEN_PROBE=y +-# CONFIG_MTD_CFI_ADV_OPTIONS is not set +-CONFIG_MTD_MAP_BANK_WIDTH_1=y +-CONFIG_MTD_MAP_BANK_WIDTH_2=y +-CONFIG_MTD_MAP_BANK_WIDTH_4=y +-# CONFIG_MTD_MAP_BANK_WIDTH_8 is not set +-# CONFIG_MTD_MAP_BANK_WIDTH_16 is not set +-# CONFIG_MTD_MAP_BANK_WIDTH_32 is not set +-CONFIG_MTD_CFI_I1=y +-CONFIG_MTD_CFI_I2=y +-# CONFIG_MTD_CFI_I4 is not set +-# CONFIG_MTD_CFI_I8 is not set +-# CONFIG_MTD_CFI_INTELEXT is not set +-CONFIG_MTD_CFI_AMDSTD=y +-# CONFIG_MTD_CFI_STAA is not set +-CONFIG_MTD_CFI_UTIL=y +-# CONFIG_MTD_RAM is not set +-# CONFIG_MTD_ROM is not set +-# CONFIG_MTD_ABSENT is not set +-# CONFIG_MTD_OBSOLETE_CHIPS is not set +- +-# +-# Mapping drivers for chip access +-# +-# CONFIG_MTD_COMPLEX_MAPPINGS is not set +-CONFIG_MTD_PHYSMAP=y +-CONFIG_MTD_PHYSMAP_START=0x0 +-CONFIG_MTD_PHYSMAP_LEN=0x0 +-CONFIG_MTD_PHYSMAP_BANKWIDTH=0 +-# CONFIG_MTD_PLATRAM is not set +- +-# +-# Self-contained MTD device drivers +-# +-# CONFIG_MTD_PMC551 is not set +-# CONFIG_MTD_SLRAM is not set +-# CONFIG_MTD_PHRAM is not set +-# CONFIG_MTD_MTDRAM is not set +-# CONFIG_MTD_BLOCK2MTD is not set +- +-# +-# Disk-On-Chip Device Drivers +-# +-# CONFIG_MTD_DOC2000 is not set +-# CONFIG_MTD_DOC2001 is not set +-# CONFIG_MTD_DOC2001PLUS is not set +- +-# +-# NAND Flash Device Drivers +-# +-# CONFIG_MTD_NAND is not set +- +-# +-# OneNAND Flash Device Drivers +-# +-# CONFIG_MTD_ONENAND is not set +- +-# +-# Parallel port support +-# +-# CONFIG_PARPORT is not set +- +-# +-# Plug and Play support +-# +-# CONFIG_PNPACPI is not set +- +-# +-# Block devices +-# +-# CONFIG_BLK_CPQ_DA is not set +-# CONFIG_BLK_CPQ_CISS_DA is not set +-# CONFIG_BLK_DEV_DAC960 is not set +-# CONFIG_BLK_DEV_UMEM is not set +-# CONFIG_BLK_DEV_COW_COMMON is not set +-CONFIG_BLK_DEV_LOOP=m +-CONFIG_BLK_DEV_CRYPTOLOOP=m +-# CONFIG_BLK_DEV_NBD is not set +-# CONFIG_BLK_DEV_SX8 is not set +-# CONFIG_BLK_DEV_RAM is not set +-# CONFIG_BLK_DEV_INITRD is not set +-# CONFIG_CDROM_PKTCDVD is not set +-# CONFIG_ATA_OVER_ETH is not set +- +-# +-# Misc devices +-# +-CONFIG_SGI_IOC4=m +-# CONFIG_TIFM_CORE is not set +- +-# +-# ATA/ATAPI/MFM/RLL support +-# +-# CONFIG_IDE is not set +- +-# +-# SCSI device support +-# +-# CONFIG_RAID_ATTRS is not set +-CONFIG_SCSI=m +-CONFIG_SCSI_TGT=m +-# CONFIG_SCSI_NETLINK is not set +-# CONFIG_SCSI_PROC_FS is not set +- +-# +-# SCSI support type (disk, tape, CD-ROM) +-# +-CONFIG_BLK_DEV_SD=m +-# CONFIG_CHR_DEV_ST is not set +-# CONFIG_CHR_DEV_OSST is not set +-# CONFIG_BLK_DEV_SR is not set +-CONFIG_CHR_DEV_SG=m +-# CONFIG_CHR_DEV_SCH is not set +- +-# +-# Some SCSI devices (e.g. CD jukebox) support multiple LUNs +-# +-# CONFIG_SCSI_MULTI_LUN is not set +-# CONFIG_SCSI_CONSTANTS is not set +-# CONFIG_SCSI_LOGGING is not set +-CONFIG_SCSI_SCAN_ASYNC=y +- +-# +-# SCSI Transports +-# +-# CONFIG_SCSI_SPI_ATTRS is not set +-# CONFIG_SCSI_FC_ATTRS is not set +-# CONFIG_SCSI_ISCSI_ATTRS is not set +-CONFIG_SCSI_SAS_ATTRS=m +-CONFIG_SCSI_SAS_LIBSAS=m +-# CONFIG_SCSI_SAS_LIBSAS_DEBUG is not set +- +-# +-# SCSI low-level drivers +-# +-# CONFIG_ISCSI_TCP is not set +-# CONFIG_BLK_DEV_3W_XXXX_RAID is not set +-# CONFIG_SCSI_3W_9XXX is not set +-# CONFIG_SCSI_ACARD is not set +-# CONFIG_SCSI_AACRAID is not set +-# CONFIG_SCSI_AIC7XXX is not set +-# CONFIG_SCSI_AIC7XXX_OLD is not set +-# CONFIG_SCSI_AIC79XX is not set +-CONFIG_SCSI_AIC94XX=m +-# CONFIG_AIC94XX_DEBUG is not set +-# CONFIG_SCSI_DPT_I2O is not set +-# CONFIG_SCSI_ARCMSR is not set +-# CONFIG_MEGARAID_NEWGEN is not set +-# CONFIG_MEGARAID_LEGACY is not set +-# CONFIG_MEGARAID_SAS is not set +-# CONFIG_SCSI_HPTIOP is not set +-# CONFIG_SCSI_DMX3191D is not set +-# CONFIG_SCSI_FUTURE_DOMAIN is not set +-# CONFIG_SCSI_IPS is not set +-# CONFIG_SCSI_INITIO is not set +-# CONFIG_SCSI_INIA100 is not set +-# CONFIG_SCSI_STEX is not set +-# CONFIG_SCSI_SYM53C8XX_2 is not set +-# CONFIG_SCSI_QLOGIC_1280 is not set +-# CONFIG_SCSI_QLA_FC is not set +-# CONFIG_SCSI_QLA_ISCSI is not set +-# CONFIG_SCSI_LPFC is not set +-# CONFIG_SCSI_DC395x is not set +-# CONFIG_SCSI_DC390T is not set +-# CONFIG_SCSI_NSP32 is not set +-# CONFIG_SCSI_DEBUG is not set +-# CONFIG_SCSI_SRP is not set +- +-# +-# Serial ATA (prod) and Parallel ATA (experimental) drivers +-# +-# CONFIG_ATA is not set +- +-# +-# Multi-device support (RAID and LVM) +-# +-# CONFIG_MD is not set +- +-# +-# Fusion MPT device support +-# +-# CONFIG_FUSION is not set +-# CONFIG_FUSION_SPI is not set +-# CONFIG_FUSION_FC is not set +-# CONFIG_FUSION_SAS is not set +- +-# +-# IEEE 1394 (FireWire) support +-# +-# CONFIG_IEEE1394 is not set +- +-# +-# I2O device support +-# +-# CONFIG_I2O is not set +- +-# +-# Network device support +-# +-CONFIG_NETDEVICES=y +-# CONFIG_DUMMY is not set +-# CONFIG_BONDING is not set +-# CONFIG_EQUALIZER is not set +-CONFIG_TUN=m +- +-# +-# ARCnet devices +-# +-# CONFIG_ARCNET is not set +- +-# +-# PHY device support +-# +-# CONFIG_PHYLIB is not set +- +-# +-# Ethernet (10 or 100Mbit) +-# +-CONFIG_NET_ETHERNET=y +-CONFIG_MII=y +-# CONFIG_HAPPYMEAL is not set +-# CONFIG_SUNGEM is not set +-# CONFIG_CASSINI is not set +-# CONFIG_NET_VENDOR_3COM is not set +-# CONFIG_DM9000 is not set +- +-# +-# Tulip family network device support +-# +-# CONFIG_NET_TULIP is not set +-# CONFIG_HP100 is not set +-CONFIG_NET_PCI=y +-# CONFIG_PCNET32 is not set +-# CONFIG_AMD8111_ETH is not set +-# CONFIG_ADAPTEC_STARFIRE is not set +-# CONFIG_B44 is not set +-# CONFIG_FORCEDETH is not set +-# CONFIG_DGRS is not set +-# CONFIG_EEPRO100 is not set +-# CONFIG_E100 is not set +-# CONFIG_FEALNX is not set +-CONFIG_NATSEMI=y +-# CONFIG_NE2K_PCI is not set +-# CONFIG_8139CP is not set +-# CONFIG_8139TOO is not set +-# CONFIG_SIS900 is not set +-# CONFIG_EPIC100 is not set +-# CONFIG_SUNDANCE is not set +-# CONFIG_TLAN is not set +-# CONFIG_VIA_RHINE is not set +-# CONFIG_SC92031 is not set +- +-# +-# Ethernet (1000 Mbit) +-# +-# CONFIG_ACENIC is not set +-# CONFIG_DL2K is not set +-# CONFIG_E1000 is not set +-# CONFIG_NS83820 is not set +-# CONFIG_HAMACHI is not set +-# CONFIG_YELLOWFIN is not set +-# CONFIG_R8169 is not set +-# CONFIG_SIS190 is not set +-# CONFIG_SKGE is not set +-# CONFIG_SKY2 is not set +-# CONFIG_SK98LIN is not set +-# CONFIG_VIA_VELOCITY is not set +-# CONFIG_TIGON3 is not set +-# CONFIG_BNX2 is not set +-CONFIG_QLA3XXX=m +-# CONFIG_ATL1 is not set +- +-# +-# Ethernet (10000 Mbit) +-# +-# CONFIG_CHELSIO_T1 is not set +-CONFIG_CHELSIO_T3=m +-# CONFIG_IXGB is not set +-# CONFIG_S2IO is not set +-# CONFIG_MYRI10GE is not set +-CONFIG_NETXEN_NIC=m +- +-# +-# Token Ring devices +-# +-# CONFIG_TR is not set +- +-# +-# Wireless LAN (non-hamradio) +-# +-# CONFIG_NET_RADIO is not set +- +-# +-# Wan interfaces +-# +-# CONFIG_WAN is not set +-# CONFIG_FDDI is not set +-# CONFIG_HIPPI is not set +-CONFIG_PPP=m +-# CONFIG_PPP_MULTILINK is not set +-# CONFIG_PPP_FILTER is not set +-CONFIG_PPP_ASYNC=m +-CONFIG_PPP_SYNC_TTY=m +-CONFIG_PPP_DEFLATE=m +-# CONFIG_PPP_BSDCOMP is not set +-# CONFIG_PPP_MPPE is not set +-# CONFIG_PPPOE is not set +-# CONFIG_SLIP is not set +-CONFIG_SLHC=m +-# CONFIG_NET_FC is not set +-# CONFIG_SHAPER is not set +-# CONFIG_NETCONSOLE is not set +-# CONFIG_NETPOLL is not set +-# CONFIG_NET_POLL_CONTROLLER is not set +- +-# +-# ISDN subsystem +-# +-# CONFIG_ISDN is not set +- +-# +-# Telephony Support +-# +-# CONFIG_PHONE is not set +- +-# +-# Input device support +-# +-CONFIG_INPUT=y +-# CONFIG_INPUT_FF_MEMLESS is not set +- +-# +-# Userland interfaces +-# +-# CONFIG_INPUT_MOUSEDEV is not set +-# CONFIG_INPUT_JOYDEV is not set +-# CONFIG_INPUT_TSDEV is not set +-CONFIG_INPUT_EVDEV=m +-# CONFIG_INPUT_EVBUG is not set +- +-# +-# Input Device Drivers +-# +-# CONFIG_INPUT_KEYBOARD is not set +-# CONFIG_INPUT_MOUSE is not set +-# CONFIG_INPUT_JOYSTICK is not set +-# CONFIG_INPUT_TOUCHSCREEN is not set +-# CONFIG_INPUT_MISC is not set +- +-# +-# Hardware I/O ports +-# +-# CONFIG_SERIO is not set +-# CONFIG_GAMEPORT is not set +- +-# +-# Character devices +-# +-# CONFIG_VT is not set +-# CONFIG_SERIAL_NONSTANDARD is not set +- +-# +-# Serial drivers +-# +-CONFIG_SERIAL_8250=y +-CONFIG_SERIAL_8250_CONSOLE=y +-CONFIG_SERIAL_8250_PCI=y +-CONFIG_SERIAL_8250_NR_UARTS=4 +-CONFIG_SERIAL_8250_RUNTIME_UARTS=4 +-# CONFIG_SERIAL_8250_EXTENDED is not set +- +-# +-# Non-8250 serial port support +-# +-CONFIG_SERIAL_CORE=y +-CONFIG_SERIAL_CORE_CONSOLE=y +-# CONFIG_SERIAL_JSM is not set +-CONFIG_UNIX98_PTYS=y +-CONFIG_LEGACY_PTYS=y +-CONFIG_LEGACY_PTY_COUNT=256 +- +-# +-# IPMI +-# +-# CONFIG_IPMI_HANDLER is not set +- +-# +-# Watchdog Cards +-# +-# CONFIG_WATCHDOG is not set +-# CONFIG_HW_RANDOM is not set +-CONFIG_RTC=m +-# CONFIG_GEN_RTC is not set +-# CONFIG_DTLK is not set +-# CONFIG_R3964 is not set +-# CONFIG_APPLICOM is not set +-# CONFIG_DRM is not set +-# CONFIG_RAW_DRIVER is not set +- +-# +-# TPM devices +-# +-# CONFIG_TCG_TPM is not set +- +-# +-# I2C support +-# +-CONFIG_I2C=y +-CONFIG_I2C_CHARDEV=y +- +-# +-# I2C Algorithms +-# +-# CONFIG_I2C_ALGOBIT is not set +-# CONFIG_I2C_ALGOPCF is not set +-# CONFIG_I2C_ALGOPCA is not set +- +-# +-# I2C Hardware Bus support +-# +-# CONFIG_I2C_ALI1535 is not set +-# CONFIG_I2C_ALI1563 is not set +-# CONFIG_I2C_ALI15X3 is not set +-# CONFIG_I2C_AMD756 is not set +-# CONFIG_I2C_AMD8111 is not set +-# CONFIG_I2C_I801 is not set +-# CONFIG_I2C_I810 is not set +-# CONFIG_I2C_PIIX4 is not set +-# CONFIG_I2C_NFORCE2 is not set +-# CONFIG_I2C_OCORES is not set +-# CONFIG_I2C_PARPORT_LIGHT is not set +-# CONFIG_I2C_PASEMI is not set +-# CONFIG_I2C_PROSAVAGE is not set +-# CONFIG_I2C_SAVAGE4 is not set +-# CONFIG_I2C_SIS5595 is not set +-# CONFIG_I2C_SIS630 is not set +-# CONFIG_I2C_SIS96X is not set +-# CONFIG_I2C_STUB is not set +-# CONFIG_I2C_VIA is not set +-# CONFIG_I2C_VIAPRO is not set +-# CONFIG_I2C_VOODOO3 is not set +-# CONFIG_I2C_PCA_ISA is not set +- +-# +-# Miscellaneous I2C Chip support +-# +-# CONFIG_SENSORS_DS1337 is not set +-# CONFIG_SENSORS_DS1374 is not set +-# CONFIG_EEPROM_LEGACY is not set +-# CONFIG_SENSORS_PCF8574 is not set +-# CONFIG_SENSORS_PCA9539 is not set +-# CONFIG_SENSORS_PCF8591 is not set +-# CONFIG_SENSORS_MAX6875 is not set +-CONFIG_I2C_DEBUG_CORE=y +-# CONFIG_I2C_DEBUG_ALGO is not set +-CONFIG_I2C_DEBUG_BUS=y +-# CONFIG_I2C_DEBUG_CHIP is not set +- +-# +-# SPI support +-# +-# CONFIG_SPI is not set +-# CONFIG_SPI_MASTER is not set +- +-# +-# Dallas's 1-wire bus +-# +-# CONFIG_W1 is not set +- +-# +-# Hardware Monitoring support +-# +-CONFIG_HWMON=y +-# CONFIG_HWMON_VID is not set +-# CONFIG_SENSORS_ABITUGURU is not set +-# CONFIG_SENSORS_ADM1021 is not set +-# CONFIG_SENSORS_ADM1025 is not set +-# CONFIG_SENSORS_ADM1026 is not set +-# CONFIG_SENSORS_ADM1029 is not set +-# CONFIG_SENSORS_ADM1031 is not set +-# CONFIG_SENSORS_ADM9240 is not set +-# CONFIG_SENSORS_ASB100 is not set +-# CONFIG_SENSORS_ATXP1 is not set +-# CONFIG_SENSORS_DS1621 is not set +-# CONFIG_SENSORS_F71805F is not set +-# CONFIG_SENSORS_FSCHER is not set +-# CONFIG_SENSORS_FSCPOS is not set +-# CONFIG_SENSORS_GL518SM is not set +-# CONFIG_SENSORS_GL520SM is not set +-# CONFIG_SENSORS_IT87 is not set +-# CONFIG_SENSORS_LM63 is not set +-# CONFIG_SENSORS_LM75 is not set +-# CONFIG_SENSORS_LM77 is not set +-# CONFIG_SENSORS_LM78 is not set +-# CONFIG_SENSORS_LM80 is not set +-# CONFIG_SENSORS_LM83 is not set +-# CONFIG_SENSORS_LM85 is not set +-# CONFIG_SENSORS_LM87 is not set +-# CONFIG_SENSORS_LM90 is not set +-# CONFIG_SENSORS_LM92 is not set +-# CONFIG_SENSORS_MAX1619 is not set +-# CONFIG_SENSORS_PC87360 is not set +-# CONFIG_SENSORS_PC87427 is not set +-# CONFIG_SENSORS_SIS5595 is not set +-# CONFIG_SENSORS_SMSC47M1 is not set +-# CONFIG_SENSORS_SMSC47M192 is not set +-# CONFIG_SENSORS_SMSC47B397 is not set +-# CONFIG_SENSORS_VIA686A is not set +-# CONFIG_SENSORS_VT1211 is not set +-# CONFIG_SENSORS_VT8231 is not set +-# CONFIG_SENSORS_W83781D is not set +-# CONFIG_SENSORS_W83791D is not set +-# CONFIG_SENSORS_W83792D is not set +-# CONFIG_SENSORS_W83793 is not set +-# CONFIG_SENSORS_W83L785TS is not set +-# CONFIG_SENSORS_W83627HF is not set +-# CONFIG_SENSORS_W83627EHF is not set +-# CONFIG_HWMON_DEBUG_CHIP is not set +- +-# +-# Multimedia devices +-# +-# CONFIG_VIDEO_DEV is not set +- +-# +-# Digital Video Broadcasting Devices +-# +-# CONFIG_DVB is not set +- +-# +-# Graphics support +-# +-# CONFIG_FIRMWARE_EDID is not set +-# CONFIG_FB is not set +-# CONFIG_BACKLIGHT_LCD_SUPPORT is not set +- +-# +-# Sound +-# +-# CONFIG_SOUND is not set +- +-# +-# HID Devices +-# +-# CONFIG_HID is not set +- +-# +-# USB support +-# +-CONFIG_USB_ARCH_HAS_HCD=y +-CONFIG_USB_ARCH_HAS_OHCI=y +-CONFIG_USB_ARCH_HAS_EHCI=y +-# CONFIG_USB is not set +- +-# +-# NOTE: USB_STORAGE enables SCSI, and 'SCSI disk support' +-# +- +-# +-# USB Gadget Support +-# +-# CONFIG_USB_GADGET is not set +- +-# +-# MMC/SD Card support +-# +-# CONFIG_MMC is not set +- +-# +-# LED devices +-# +-# CONFIG_NEW_LEDS is not set +- +-# +-# LED drivers +-# +- +-# +-# LED Triggers +-# +- +-# +-# InfiniBand support +-# +-# CONFIG_INFINIBAND is not set +- +-# +-# EDAC - error detection and reporting (RAS) (EXPERIMENTAL) +-# +- +-# +-# Real Time Clock +-# +-# CONFIG_RTC_CLASS is not set +- +-# +-# DMA Engine support +-# +-# CONFIG_DMA_ENGINE is not set +- +-# +-# DMA Clients +-# +- +-# +-# DMA Devices +-# +- +-# +-# Auxiliary Display support +-# +- +-# +-# Virtualization +-# +- +-# +-# File systems +-# +-CONFIG_EXT2_FS=y +-CONFIG_EXT2_FS_XATTR=y +-CONFIG_EXT2_FS_POSIX_ACL=y +-CONFIG_EXT2_FS_SECURITY=y +-# CONFIG_EXT2_FS_XIP is not set +-CONFIG_EXT3_FS=m +-CONFIG_EXT3_FS_XATTR=y +-# CONFIG_EXT3_FS_POSIX_ACL is not set +-# CONFIG_EXT3_FS_SECURITY is not set +-# CONFIG_EXT4DEV_FS is not set +-CONFIG_JBD=m +-# CONFIG_JBD_DEBUG is not set +-CONFIG_FS_MBCACHE=y +-# CONFIG_REISERFS_FS is not set +-# CONFIG_JFS_FS is not set +-CONFIG_FS_POSIX_ACL=y +-CONFIG_XFS_FS=m +-# CONFIG_XFS_QUOTA is not set +-# CONFIG_XFS_SECURITY is not set +-# CONFIG_XFS_POSIX_ACL is not set +-# CONFIG_XFS_RT is not set +-# CONFIG_GFS2_FS is not set +-# CONFIG_OCFS2_FS is not set +-# CONFIG_MINIX_FS is not set +-# CONFIG_ROMFS_FS is not set +-CONFIG_INOTIFY=y +-CONFIG_INOTIFY_USER=y +-# CONFIG_QUOTA is not set +-# CONFIG_DNOTIFY is not set +-# CONFIG_AUTOFS_FS is not set +-CONFIG_AUTOFS4_FS=m +-# CONFIG_FUSE_FS is not set +-CONFIG_GENERIC_ACL=y +- +-# +-# CD-ROM/DVD Filesystems +-# +-# CONFIG_ISO9660_FS is not set +-# CONFIG_UDF_FS is not set +- +-# +-# DOS/FAT/NT Filesystems +-# +-CONFIG_FAT_FS=y +-CONFIG_MSDOS_FS=y +-CONFIG_VFAT_FS=y +-CONFIG_FAT_DEFAULT_CODEPAGE=437 +-CONFIG_FAT_DEFAULT_IOCHARSET="iso8859-1" +-CONFIG_NTFS_FS=m +-# CONFIG_NTFS_DEBUG is not set +-# CONFIG_NTFS_RW is not set +- +-# +-# Pseudo filesystems +-# +-CONFIG_PROC_FS=y +-CONFIG_PROC_KCORE=y +-CONFIG_PROC_SYSCTL=y +-CONFIG_SYSFS=y +-CONFIG_TMPFS=y +-CONFIG_TMPFS_POSIX_ACL=y +-# CONFIG_HUGETLB_PAGE is not set +-CONFIG_RAMFS=y +-CONFIG_CONFIGFS_FS=m +- +-# +-# Miscellaneous filesystems +-# +-# CONFIG_ADFS_FS is not set +-# CONFIG_AFFS_FS is not set +-# CONFIG_HFS_FS is not set +-# CONFIG_HFSPLUS_FS is not set +-# CONFIG_BEFS_FS is not set +-# CONFIG_BFS_FS is not set +-# CONFIG_EFS_FS is not set +-CONFIG_JFFS2_FS=y +-CONFIG_JFFS2_FS_DEBUG=0 +-CONFIG_JFFS2_FS_WRITEBUFFER=y +-# CONFIG_JFFS2_SUMMARY is not set +-# CONFIG_JFFS2_FS_XATTR is not set +-CONFIG_JFFS2_COMPRESSION_OPTIONS=y +-CONFIG_JFFS2_ZLIB=y +-CONFIG_JFFS2_RTIME=y +-# CONFIG_JFFS2_RUBIN is not set +-# CONFIG_JFFS2_CMODE_NONE is not set +-CONFIG_JFFS2_CMODE_PRIORITY=y +-# CONFIG_JFFS2_CMODE_SIZE is not set +-CONFIG_CRAMFS=y +-# CONFIG_VXFS_FS is not set +-# CONFIG_HPFS_FS is not set +-# CONFIG_QNX4FS_FS is not set +-# CONFIG_SYSV_FS is not set +-# CONFIG_UFS_FS is not set +- +-# +-# Network File Systems +-# +-CONFIG_NFS_FS=y +-CONFIG_NFS_V3=y +-# CONFIG_NFS_V3_ACL is not set +-CONFIG_NFS_V4=y +-CONFIG_NFS_DIRECTIO=y +-CONFIG_NFSD=m +-CONFIG_NFSD_V3=y +-# CONFIG_NFSD_V3_ACL is not set +-# CONFIG_NFSD_V4 is not set +-CONFIG_NFSD_TCP=y +-CONFIG_ROOT_NFS=y +-CONFIG_LOCKD=y +-CONFIG_LOCKD_V4=y +-CONFIG_EXPORTFS=m +-CONFIG_NFS_COMMON=y +-CONFIG_SUNRPC=y +-CONFIG_SUNRPC_GSS=y +-CONFIG_RPCSEC_GSS_KRB5=y +-# CONFIG_RPCSEC_GSS_SPKM3 is not set +-CONFIG_SMB_FS=m +-# CONFIG_SMB_NLS_DEFAULT is not set +-# CONFIG_CIFS is not set +-# CONFIG_NCP_FS is not set +-# CONFIG_CODA_FS is not set +-# CONFIG_AFS_FS is not set +-# CONFIG_9P_FS is not set +- +-# +-# Partition Types +-# +-# CONFIG_PARTITION_ADVANCED is not set +-CONFIG_MSDOS_PARTITION=y +- +-# +-# Native Language Support +-# +-CONFIG_NLS=y +-CONFIG_NLS_DEFAULT="" +-CONFIG_NLS_CODEPAGE_437=m +-# CONFIG_NLS_CODEPAGE_737 is not set +-# CONFIG_NLS_CODEPAGE_775 is not set +-# CONFIG_NLS_CODEPAGE_850 is not set +-# CONFIG_NLS_CODEPAGE_852 is not set +-# CONFIG_NLS_CODEPAGE_855 is not set +-# CONFIG_NLS_CODEPAGE_857 is not set +-# CONFIG_NLS_CODEPAGE_860 is not set +-# CONFIG_NLS_CODEPAGE_861 is not set +-# CONFIG_NLS_CODEPAGE_862 is not set +-# CONFIG_NLS_CODEPAGE_863 is not set +-# CONFIG_NLS_CODEPAGE_864 is not set +-# CONFIG_NLS_CODEPAGE_865 is not set +-# CONFIG_NLS_CODEPAGE_866 is not set +-# CONFIG_NLS_CODEPAGE_869 is not set +-# CONFIG_NLS_CODEPAGE_936 is not set +-# CONFIG_NLS_CODEPAGE_950 is not set +-# CONFIG_NLS_CODEPAGE_932 is not set +-# CONFIG_NLS_CODEPAGE_949 is not set +-# CONFIG_NLS_CODEPAGE_874 is not set +-# CONFIG_NLS_ISO8859_8 is not set +-# CONFIG_NLS_CODEPAGE_1250 is not set +-# CONFIG_NLS_CODEPAGE_1251 is not set +-CONFIG_NLS_ASCII=m +-CONFIG_NLS_ISO8859_1=m +-# CONFIG_NLS_ISO8859_2 is not set +-# CONFIG_NLS_ISO8859_3 is not set +-# CONFIG_NLS_ISO8859_4 is not set +-# CONFIG_NLS_ISO8859_5 is not set +-# CONFIG_NLS_ISO8859_6 is not set +-# CONFIG_NLS_ISO8859_7 is not set +-# CONFIG_NLS_ISO8859_9 is not set +-# CONFIG_NLS_ISO8859_13 is not set +-# CONFIG_NLS_ISO8859_14 is not set +-# CONFIG_NLS_ISO8859_15 is not set +-# CONFIG_NLS_KOI8_R is not set +-# CONFIG_NLS_KOI8_U is not set +-CONFIG_NLS_UTF8=m +- +-# +-# Distributed Lock Manager +-# +-CONFIG_DLM=m +-CONFIG_DLM_TCP=y +-# CONFIG_DLM_SCTP is not set +-# CONFIG_DLM_DEBUG is not set +- +-# +-# Profiling support +-# +-# CONFIG_PROFILING is not set +- +-# +-# Kernel hacking +-# +-CONFIG_TRACE_IRQFLAGS_SUPPORT=y +-# CONFIG_PRINTK_TIME is not set +-CONFIG_ENABLE_MUST_CHECK=y +-# CONFIG_MAGIC_SYSRQ is not set +-# CONFIG_UNUSED_SYMBOLS is not set +-# CONFIG_DEBUG_FS is not set +-# CONFIG_HEADERS_CHECK is not set +-# CONFIG_DEBUG_KERNEL is not set +-CONFIG_LOG_BUF_SHIFT=14 +-CONFIG_CROSSCOMPILE=y +-CONFIG_CMDLINE="console=ttyS0,115200 mem=192m ip=bootp root=/dev/nfs rw" +- +-# +-# Security options +-# +-# CONFIG_KEYS is not set +-# CONFIG_SECURITY is not set +- +-# +-# Cryptographic options +-# +-CONFIG_CRYPTO=y +-CONFIG_CRYPTO_ALGAPI=y +-CONFIG_CRYPTO_BLKCIPHER=y +-CONFIG_CRYPTO_HASH=y +-CONFIG_CRYPTO_MANAGER=y +-CONFIG_CRYPTO_HMAC=y +-CONFIG_CRYPTO_XCBC=m +-# CONFIG_CRYPTO_NULL is not set +-# CONFIG_CRYPTO_MD4 is not set +-CONFIG_CRYPTO_MD5=y +-# CONFIG_CRYPTO_SHA1 is not set +-# CONFIG_CRYPTO_SHA256 is not set +-# CONFIG_CRYPTO_SHA512 is not set +-# CONFIG_CRYPTO_WP512 is not set +-# CONFIG_CRYPTO_TGR192 is not set +-CONFIG_CRYPTO_GF128MUL=m +-CONFIG_CRYPTO_ECB=m +-CONFIG_CRYPTO_CBC=y +-CONFIG_CRYPTO_PCBC=m +-CONFIG_CRYPTO_LRW=m +-CONFIG_CRYPTO_DES=y +-CONFIG_CRYPTO_FCRYPT=m +-# CONFIG_CRYPTO_BLOWFISH is not set +-# CONFIG_CRYPTO_TWOFISH is not set +-# CONFIG_CRYPTO_SERPENT is not set +-# CONFIG_CRYPTO_AES is not set +-# CONFIG_CRYPTO_CAST5 is not set +-# CONFIG_CRYPTO_CAST6 is not set +-# CONFIG_CRYPTO_TEA is not set +-# CONFIG_CRYPTO_ARC4 is not set +-# CONFIG_CRYPTO_KHAZAD is not set +-# CONFIG_CRYPTO_ANUBIS is not set +-# CONFIG_CRYPTO_DEFLATE is not set +-# CONFIG_CRYPTO_MICHAEL_MIC is not set +-# CONFIG_CRYPTO_CRC32C is not set +-CONFIG_CRYPTO_CAMELLIA=m +-# CONFIG_CRYPTO_TEST is not set +- +-# +-# Hardware crypto devices +-# +- +-# +-# Library routines +-# +-CONFIG_BITREVERSE=y +-CONFIG_CRC_CCITT=m +-# CONFIG_CRC16 is not set +-CONFIG_CRC32=y +-# CONFIG_LIBCRC32C is not set +-CONFIG_ZLIB_INFLATE=y +-CONFIG_ZLIB_DEFLATE=y +-CONFIG_TEXTSEARCH=y +-CONFIG_TEXTSEARCH_KMP=m +-CONFIG_TEXTSEARCH_BM=m +-CONFIG_TEXTSEARCH_FSM=m +-CONFIG_PLIST=y +-CONFIG_HAS_IOMEM=y +-CONFIG_HAS_IOPORT=y +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/arch/mips/configs/rbtx49xx_defconfig linux-2.6.29-rc3.owrt/arch/mips/configs/rbtx49xx_defconfig +--- linux-2.6.29.owrt/arch/mips/configs/rbtx49xx_defconfig 2009-05-10 22:04:40.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/arch/mips/configs/rbtx49xx_defconfig 2009-05-10 23:48:28.000000000 +0200 +@@ -1,7 +1,7 @@ + # + # Automatically generated make config: don't edit +-# Linux kernel version: 2.6.29-rc7 +-# Wed Mar 4 23:08:06 2009 ++# Linux kernel version: 2.6.26-rc9 ++# Fri Jul 11 23:03:21 2008 + # + CONFIG_MIPS=y + +@@ -18,10 +18,8 @@ + # CONFIG_LEMOTE_FULONG is not set + # CONFIG_MIPS_MALTA is not set + # CONFIG_MIPS_SIM is not set +-# CONFIG_MACH_EMMA is not set ++# CONFIG_MARKEINS is not set + # CONFIG_MACH_VR41XX is not set +-# CONFIG_NXP_STB220 is not set +-# CONFIG_NXP_STB225 is not set + # CONFIG_PNX8550_JBS is not set + # CONFIG_PNX8550_STB810 is not set + # CONFIG_PMC_MSP is not set +@@ -41,28 +39,20 @@ + # CONFIG_SNI_RM is not set + # CONFIG_MACH_TX39XX is not set + CONFIG_MACH_TX49XX=y +-# CONFIG_MIKROTIK_RB532 is not set + # CONFIG_WR_PPMC is not set +-# CONFIG_CAVIUM_OCTEON_SIMULATOR is not set +-# CONFIG_CAVIUM_OCTEON_REFERENCE_BOARD is not set +-CONFIG_MACH_TXX9=y + CONFIG_TOSHIBA_RBTX4927=y + CONFIG_TOSHIBA_RBTX4938=y +-CONFIG_TOSHIBA_RBTX4939=y + CONFIG_SOC_TX4927=y + CONFIG_SOC_TX4938=y +-CONFIG_SOC_TX4939=y +-CONFIG_TXX9_7SEGLED=y + # CONFIG_TOSHIBA_FPCIB0 is not set + CONFIG_PICMG_PCI_BACKPLANE_DEFAULT=y + + # + # Multiplex Pin Select + # +-# CONFIG_TOSHIBA_RBTX4938_MPLEX_PIO58_61 is not set ++CONFIG_TOSHIBA_RBTX4938_MPLEX_PIO58_61=y + # CONFIG_TOSHIBA_RBTX4938_MPLEX_NAND is not set + # CONFIG_TOSHIBA_RBTX4938_MPLEX_ATA is not set +-CONFIG_TOSHIBA_RBTX4938_MPLEX_KEEP=y + CONFIG_PCI_TX4927=y + CONFIG_RWSEM_GENERIC_SPINLOCK=y + # CONFIG_ARCH_HAS_ILOG2_U32 is not set +@@ -74,18 +64,14 @@ + CONFIG_GENERIC_CLOCKEVENTS=y + CONFIG_GENERIC_TIME=y + CONFIG_GENERIC_CMOS_UPDATE=y +-CONFIG_SCHED_OMIT_FRAME_POINTER=y ++CONFIG_SCHED_NO_NO_OMIT_FRAME_POINTER=y + CONFIG_GENERIC_HARDIRQS_NO__DO_IRQ=y +-CONFIG_CEVT_R4K_LIB=y + CONFIG_CEVT_R4K=y + CONFIG_CEVT_TXX9=y +-CONFIG_CSRC_R4K_LIB=y + CONFIG_CSRC_R4K=y + CONFIG_GPIO_TXX9=y + CONFIG_DMA_NONCOHERENT=y + CONFIG_DMA_NEED_PCI_MAP_STATE=y +-CONFIG_EARLY_PRINTK=y +-CONFIG_SYS_HAS_EARLY_PRINTK=y + # CONFIG_HOTPLUG_CPU is not set + # CONFIG_NO_IOPORT is not set + CONFIG_GENERIC_GPIO=y +@@ -114,7 +100,6 @@ + CONFIG_CPU_TX49XX=y + # 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_NEVADA is not set + # CONFIG_CPU_R8000 is not set +@@ -122,7 +107,6 @@ + # CONFIG_CPU_RM7000 is not set + # CONFIG_CPU_RM9000 is not set + # CONFIG_CPU_SB1 is not set +-# CONFIG_CPU_CAVIUM_OCTEON is not set + CONFIG_SYS_HAS_CPU_TX49XX=y + CONFIG_SYS_SUPPORTS_32BIT_KERNEL=y + CONFIG_SYS_SUPPORTS_64BIT_KERNEL=y +@@ -150,12 +134,13 @@ + CONFIG_ARCH_POPULATES_NODE_MAP=y + CONFIG_FLATMEM=y + CONFIG_FLAT_NODE_MEM_MAP=y ++# CONFIG_SPARSEMEM_STATIC is not set ++# CONFIG_SPARSEMEM_VMEMMAP_ENABLE is not set + CONFIG_PAGEFLAGS_EXTENDED=y + CONFIG_SPLIT_PTLOCK_CPUS=4 +-# CONFIG_PHYS_ADDR_T_64BIT is not set ++# CONFIG_RESOURCES_64BIT is not set + CONFIG_ZONE_DMA_FLAG=0 + CONFIG_VIRT_TO_BUS=y +-CONFIG_UNEVICTABLE_LRU=y + CONFIG_TICK_ONESHOT=y + CONFIG_NO_HZ=y + CONFIG_HIGH_RES_TIMERS=y +@@ -191,15 +176,6 @@ + # CONFIG_BSD_PROCESS_ACCT is not set + # CONFIG_TASKSTATS is not set + # CONFIG_AUDIT is not set +- +-# +-# RCU Subsystem +-# +-CONFIG_CLASSIC_RCU=y +-# CONFIG_TREE_RCU is not set +-# CONFIG_PREEMPT_RCU is not set +-# CONFIG_TREE_RCU_TRACE is not set +-# CONFIG_PREEMPT_RCU_TRACE is not set + CONFIG_IKCONFIG=y + CONFIG_IKCONFIG_PROC=y + CONFIG_LOG_BUF_SHIFT=14 +@@ -214,6 +190,7 @@ + CONFIG_SYSCTL=y + CONFIG_EMBEDDED=y + CONFIG_SYSCTL_SYSCALL=y ++CONFIG_SYSCTL_SYSCALL_CHECK=y + CONFIG_KALLSYMS=y + # CONFIG_KALLSYMS_EXTRA_PASS is not set + # CONFIG_HOTPLUG is not set +@@ -230,26 +207,30 @@ + CONFIG_TIMERFD=y + CONFIG_EVENTFD=y + CONFIG_SHMEM=y +-CONFIG_AIO=y + CONFIG_VM_EVENT_COUNTERS=y +-CONFIG_PCI_QUIRKS=y + CONFIG_SLAB=y + # CONFIG_SLUB is not set + # CONFIG_SLOB is not set + # CONFIG_PROFILING is not set ++# CONFIG_MARKERS is not set + CONFIG_HAVE_OPROFILE=y +-# CONFIG_HAVE_GENERIC_DMA_COHERENT is not set ++# CONFIG_HAVE_KPROBES is not set ++# CONFIG_HAVE_KRETPROBES is not set ++# CONFIG_HAVE_DMA_ATTRS is not set ++CONFIG_PROC_PAGE_MONITOR=y + CONFIG_SLABINFO=y ++# CONFIG_TINY_SHMEM is not set + CONFIG_BASE_SMALL=0 + CONFIG_MODULES=y + # CONFIG_MODULE_FORCE_LOAD is not set +-CONFIG_MODULE_UNLOAD=y ++# CONFIG_MODULE_UNLOAD is not set + # CONFIG_MODVERSIONS is not set + # CONFIG_MODULE_SRCVERSION_ALL is not set ++CONFIG_KMOD=y + CONFIG_BLOCK=y + # CONFIG_LBD is not set + # CONFIG_BLK_DEV_IO_TRACE is not set +-# CONFIG_BLK_DEV_INTEGRITY is not set ++# CONFIG_LSF is not set + + # + # IO Schedulers +@@ -263,8 +244,7 @@ + # CONFIG_DEFAULT_CFQ is not set + # CONFIG_DEFAULT_NOOP is not set + CONFIG_DEFAULT_IOSCHED="anticipatory" +-# CONFIG_PROBE_INITRD_HEADER is not set +-# CONFIG_FREEZER is not set ++CONFIG_CLASSIC_RCU=y + + # + # Bus options (PCI, PCMCIA, EISA, ISA, TC) +@@ -274,15 +254,12 @@ + CONFIG_PCI_DOMAINS=y + # CONFIG_ARCH_SUPPORTS_MSI is not set + # CONFIG_PCI_LEGACY is not set +-# CONFIG_PCI_STUB is not set + CONFIG_MMU=y + + # + # Executable file formats + # + CONFIG_BINFMT_ELF=y +-# CONFIG_CORE_DUMP_DEFAULT_ELF_HEADERS is not set +-# CONFIG_HAVE_AOUT is not set + # CONFIG_BINFMT_MISC is not set + CONFIG_TRAD_SIGNALS=y + +@@ -291,12 +268,15 @@ + # + CONFIG_ARCH_SUSPEND_POSSIBLE=y + # CONFIG_PM is not set ++ ++# ++# Networking ++# + CONFIG_NET=y + + # + # Networking options + # +-CONFIG_COMPAT_NET_DEV_OPS=y + CONFIG_PACKET=y + # CONFIG_PACKET_MMAP is not set + CONFIG_UNIX=y +@@ -338,7 +318,6 @@ + # CONFIG_IPX is not set + # CONFIG_ATALK is not set + # CONFIG_NET_SCHED is not set +-# CONFIG_DCB is not set + + # + # Network testing +@@ -348,9 +327,14 @@ + # CONFIG_CAN is not set + # CONFIG_IRDA is not set + # CONFIG_BT is not set +-# CONFIG_PHONET is not set +-# CONFIG_WIRELESS is not set +-# CONFIG_WIMAX is not set ++ ++# ++# Wireless ++# ++# CONFIG_CFG80211 is not set ++# CONFIG_WIRELESS_EXT is not set ++# CONFIG_MAC80211 is not set ++# CONFIG_IEEE80211 is not set + # CONFIG_RFKILL is not set + + # +@@ -364,90 +348,7 @@ + CONFIG_PREVENT_FIRMWARE_BUILD=y + # CONFIG_SYS_HYPERVISOR is not set + # CONFIG_CONNECTOR is not set +-CONFIG_MTD=y +-# CONFIG_MTD_DEBUG is not set +-# CONFIG_MTD_CONCAT is not set +-CONFIG_MTD_PARTITIONS=y +-# CONFIG_MTD_TESTS is not set +-# CONFIG_MTD_REDBOOT_PARTS is not set +-CONFIG_MTD_CMDLINE_PARTS=y +-# CONFIG_MTD_AR7_PARTS is not set +- +-# +-# User Modules And Translation Layers +-# +-CONFIG_MTD_CHAR=y +-# CONFIG_MTD_BLKDEVS is not set +-# CONFIG_MTD_BLOCK is not set +-# CONFIG_MTD_BLOCK_RO is not set +-# CONFIG_FTL is not set +-# CONFIG_NFTL is not set +-# CONFIG_INFTL is not set +-# CONFIG_RFD_FTL is not set +-# CONFIG_SSFDC is not set +-# CONFIG_MTD_OOPS is not set +- +-# +-# RAM/ROM/Flash chip drivers +-# +-CONFIG_MTD_CFI=y +-CONFIG_MTD_JEDECPROBE=y +-CONFIG_MTD_GEN_PROBE=y +-# CONFIG_MTD_CFI_ADV_OPTIONS is not set +-CONFIG_MTD_MAP_BANK_WIDTH_1=y +-CONFIG_MTD_MAP_BANK_WIDTH_2=y +-CONFIG_MTD_MAP_BANK_WIDTH_4=y +-# CONFIG_MTD_MAP_BANK_WIDTH_8 is not set +-# CONFIG_MTD_MAP_BANK_WIDTH_16 is not set +-# CONFIG_MTD_MAP_BANK_WIDTH_32 is not set +-CONFIG_MTD_CFI_I1=y +-CONFIG_MTD_CFI_I2=y +-# CONFIG_MTD_CFI_I4 is not set +-# CONFIG_MTD_CFI_I8 is not set +-# CONFIG_MTD_CFI_INTELEXT is not set +-CONFIG_MTD_CFI_AMDSTD=y +-# CONFIG_MTD_CFI_STAA is not set +-CONFIG_MTD_CFI_UTIL=y +-# CONFIG_MTD_RAM is not set +-# CONFIG_MTD_ROM is not set +-# CONFIG_MTD_ABSENT is not set +- +-# +-# Mapping drivers for chip access +-# +-# CONFIG_MTD_COMPLEX_MAPPINGS is not set +-CONFIG_MTD_PHYSMAP=y +-# CONFIG_MTD_PHYSMAP_COMPAT is not set +-# CONFIG_MTD_INTEL_VR_NOR is not set +-# CONFIG_MTD_PLATRAM is not set +- +-# +-# Self-contained MTD device drivers +-# +-# CONFIG_MTD_PMC551 is not set +-# CONFIG_MTD_SLRAM is not set +-# CONFIG_MTD_PHRAM is not set +-# CONFIG_MTD_MTDRAM is not set +-# CONFIG_MTD_BLOCK2MTD is not set +- +-# +-# Disk-On-Chip Device Drivers +-# +-# CONFIG_MTD_DOC2000 is not set +-# CONFIG_MTD_DOC2001 is not set +-# CONFIG_MTD_DOC2001PLUS is not set +-# CONFIG_MTD_NAND is not set +-# CONFIG_MTD_ONENAND is not set +- +-# +-# LPDDR flash memory drivers +-# +-# CONFIG_MTD_LPDDR is not set +- +-# +-# UBI - Unsorted block images +-# +-# CONFIG_MTD_UBI is not set ++# CONFIG_MTD is not set + # CONFIG_PARPORT is not set + CONFIG_BLK_DEV=y + # CONFIG_BLK_CPQ_DA is not set +@@ -464,60 +365,9 @@ + # CONFIG_BLK_DEV_XIP is not set + # CONFIG_CDROM_PKTCDVD is not set + # CONFIG_ATA_OVER_ETH is not set +-# CONFIG_BLK_DEV_HD is not set + # CONFIG_MISC_DEVICES is not set + CONFIG_HAVE_IDE=y +-CONFIG_IDE=y +- +-# +-# Please see Documentation/ide/ide.txt for help/info on IDE drives +-# +-CONFIG_IDE_TIMINGS=y +-# CONFIG_BLK_DEV_IDE_SATA is not set +-CONFIG_IDE_GD=y +-CONFIG_IDE_GD_ATA=y +-# CONFIG_IDE_GD_ATAPI is not set +-# CONFIG_BLK_DEV_IDECD is not set +-# CONFIG_BLK_DEV_IDETAPE is not set +-# CONFIG_IDE_TASK_IOCTL is not set +-CONFIG_IDE_PROC_FS=y +- +-# +-# IDE chipset support/bugfixes +-# +-# CONFIG_IDE_GENERIC is not set +-# CONFIG_BLK_DEV_PLATFORM is not set +-CONFIG_BLK_DEV_IDEDMA_SFF=y +- +-# +-# PCI IDE chipsets support +-# +-# CONFIG_BLK_DEV_GENERIC is not set +-# CONFIG_BLK_DEV_AEC62XX is not set +-# CONFIG_BLK_DEV_ALI15X3 is not set +-# CONFIG_BLK_DEV_AMD74XX is not set +-# CONFIG_BLK_DEV_CMD64X is not set +-# CONFIG_BLK_DEV_TRIFLEX is not set +-# CONFIG_BLK_DEV_CS5530 is not set +-# CONFIG_BLK_DEV_HPT366 is not set +-# CONFIG_BLK_DEV_JMICRON is not set +-# CONFIG_BLK_DEV_SC1200 is not set +-# CONFIG_BLK_DEV_PIIX is not set +-# CONFIG_BLK_DEV_IT8172 is not set +-# CONFIG_BLK_DEV_IT8213 is not set +-# CONFIG_BLK_DEV_IT821X is not set +-# CONFIG_BLK_DEV_NS87415 is not set +-# CONFIG_BLK_DEV_PDC202XX_OLD is not set +-# CONFIG_BLK_DEV_PDC202XX_NEW is not set +-# CONFIG_BLK_DEV_SVWKS is not set +-# CONFIG_BLK_DEV_SIIMAGE is not set +-# CONFIG_BLK_DEV_SLC90E66 is not set +-# CONFIG_BLK_DEV_TRM290 is not set +-# CONFIG_BLK_DEV_VIA82CXXX is not set +-# CONFIG_BLK_DEV_TC86C001 is not set +-CONFIG_BLK_DEV_IDE_TX4938=y +-CONFIG_BLK_DEV_IDE_TX4939=y +-CONFIG_BLK_DEV_IDEDMA=y ++# CONFIG_IDE is not set + + # + # SCSI device support +@@ -540,6 +390,7 @@ + # CONFIG_IEEE1394 is not set + # CONFIG_I2O is not set + CONFIG_NETDEVICES=y ++# CONFIG_NETDEVICES_MULTIQUEUE is not set + # CONFIG_DUMMY is not set + # CONFIG_BONDING is not set + # CONFIG_EQUALIZER is not set +@@ -561,19 +412,15 @@ + # CONFIG_BROADCOM_PHY is not set + # CONFIG_ICPLUS_PHY is not set + # CONFIG_REALTEK_PHY is not set +-# CONFIG_NATIONAL_PHY is not set +-# CONFIG_STE10XP is not set +-# CONFIG_LSI_ET1011C_PHY is not set + # CONFIG_FIXED_PHY is not set + # CONFIG_MDIO_BITBANG is not set + CONFIG_NET_ETHERNET=y +-CONFIG_MII=y ++# CONFIG_MII is not set + # CONFIG_AX88796 is not set + # CONFIG_HAPPYMEAL is not set + # CONFIG_SUNGEM is not set + # CONFIG_CASSINI is not set + # CONFIG_NET_VENDOR_3COM is not set +-CONFIG_SMC91X=y + # CONFIG_DM9000 is not set + # CONFIG_NET_TULIP is not set + # CONFIG_HP100 is not set +@@ -582,9 +429,6 @@ + # CONFIG_IBM_NEW_EMAC_RGMII is not set + # CONFIG_IBM_NEW_EMAC_TAH is not set + # CONFIG_IBM_NEW_EMAC_EMAC4 is not set +-# CONFIG_IBM_NEW_EMAC_NO_FLOW_CTRL is not set +-# CONFIG_IBM_NEW_EMAC_MAL_CLR_ICINTSTAT is not set +-# CONFIG_IBM_NEW_EMAC_MAL_COMMON_ERR is not set + CONFIG_NET_PCI=y + # CONFIG_PCNET32 is not set + # CONFIG_AMD8111_ETH is not set +@@ -592,6 +436,7 @@ + # CONFIG_B44 is not set + # CONFIG_FORCEDETH is not set + CONFIG_TC35815=y ++# CONFIG_EEPRO100 is not set + # CONFIG_E100 is not set + # CONFIG_FEALNX is not set + # CONFIG_NATSEMI is not set +@@ -600,11 +445,9 @@ + # CONFIG_R6040 is not set + # CONFIG_SIS900 is not set + # CONFIG_EPIC100 is not set +-# CONFIG_SMSC9420 is not set + # CONFIG_SUNDANCE is not set + # CONFIG_TLAN is not set + # CONFIG_VIA_RHINE is not set +-# CONFIG_ATL2 is not set + # CONFIG_NETDEV_1000 is not set + # CONFIG_NETDEV_10000 is not set + # CONFIG_TR is not set +@@ -615,10 +458,6 @@ + # CONFIG_WLAN_PRE80211 is not set + # CONFIG_WLAN_80211 is not set + # CONFIG_IWLWIFI_LEDS is not set +- +-# +-# Enable WiMAX (Networking options) to see the WiMAX drivers +-# + # CONFIG_WAN is not set + # CONFIG_FDDI is not set + # CONFIG_PPP is not set +@@ -663,7 +502,6 @@ + CONFIG_SERIAL_TXX9_STDSERIAL=y + # CONFIG_SERIAL_JSM is not set + CONFIG_UNIX98_PTYS=y +-# CONFIG_DEVPTS_MULTIPLE_INSTANCES is not set + CONFIG_LEGACY_PTYS=y + CONFIG_LEGACY_PTY_COUNT=256 + # CONFIG_IPMI_HANDLER is not set +@@ -679,19 +517,17 @@ + # + # SPI Master Controller Drivers + # +-# CONFIG_SPI_BITBANG is not set +-# CONFIG_SPI_GPIO is not set + CONFIG_SPI_TXX9=y + + # + # SPI Protocol Masters + # ++CONFIG_EEPROM_AT25=y + # CONFIG_SPI_TLE62X0 is not set +-CONFIG_ARCH_REQUIRE_GPIOLIB=y +-CONFIG_GPIOLIB=y ++CONFIG_HAVE_GPIO_LIB=y + + # +-# Memory mapped GPIO expanders: ++# GPIO Support + # + + # +@@ -699,14 +535,8 @@ + # + + # +-# PCI GPIO expanders: +-# +-# CONFIG_GPIO_BT8XX is not set +- +-# + # SPI GPIO expanders: + # +-# CONFIG_GPIO_MAX7301 is not set + # CONFIG_GPIO_MCP23S08 is not set + # CONFIG_W1 is not set + # CONFIG_POWER_SUPPLY is not set +@@ -720,7 +550,6 @@ + # Watchdog Device Drivers + # + # CONFIG_SOFT_WATCHDOG is not set +-# CONFIG_ALIM7101_WDT is not set + CONFIG_TXX9_WDT=m + + # +@@ -728,21 +557,18 @@ + # + # CONFIG_PCIPCWATCHDOG is not set + # CONFIG_WDTPCI is not set +-CONFIG_SSB_POSSIBLE=y + + # + # Sonics Silicon Backplane + # ++CONFIG_SSB_POSSIBLE=y + # CONFIG_SSB is not set + + # + # Multifunction device drivers + # +-# CONFIG_MFD_CORE is not set + # CONFIG_MFD_SM501 is not set + # CONFIG_HTC_PASIC3 is not set +-# CONFIG_MFD_TMIO is not set +-# CONFIG_REGULATOR is not set + + # + # Multimedia devices +@@ -773,27 +599,15 @@ + # Display device support + # + # CONFIG_DISPLAY_SUPPORT is not set ++ ++# ++# Sound ++# + # CONFIG_SOUND is not set + # CONFIG_USB_SUPPORT is not set + # CONFIG_MMC is not set + # CONFIG_MEMSTICK is not set +-CONFIG_NEW_LEDS=y +-CONFIG_LEDS_CLASS=y +- +-# +-# LED drivers +-# +-CONFIG_LEDS_GPIO=y +- +-# +-# LED Triggers +-# +-CONFIG_LEDS_TRIGGERS=y +-# CONFIG_LEDS_TRIGGER_TIMER is not set +-CONFIG_LEDS_TRIGGER_IDE_DISK=y +-CONFIG_LEDS_TRIGGER_HEARTBEAT=y +-# CONFIG_LEDS_TRIGGER_BACKLIGHT is not set +-# CONFIG_LEDS_TRIGGER_DEFAULT_ON is not set ++# CONFIG_NEW_LEDS is not set + # CONFIG_ACCESSIBILITY is not set + # CONFIG_INFINIBAND is not set + CONFIG_RTC_LIB=y +@@ -814,47 +628,35 @@ + # + # SPI RTC drivers + # +-# CONFIG_RTC_DRV_M41T94 is not set +-# CONFIG_RTC_DRV_DS1305 is not set +-# CONFIG_RTC_DRV_DS1390 is not set + # CONFIG_RTC_DRV_MAX6902 is not set + # CONFIG_RTC_DRV_R9701 is not set + CONFIG_RTC_DRV_RS5C348=y +-# CONFIG_RTC_DRV_DS3234 is not set + + # + # Platform RTC drivers + # + # CONFIG_RTC_DRV_CMOS is not set +-# CONFIG_RTC_DRV_DS1286 is not set + # CONFIG_RTC_DRV_DS1511 is not set + # CONFIG_RTC_DRV_DS1553 is not set + CONFIG_RTC_DRV_DS1742=y + # CONFIG_RTC_DRV_STK17TA8 is not set + # CONFIG_RTC_DRV_M48T86 is not set +-# CONFIG_RTC_DRV_M48T35 is not set + # CONFIG_RTC_DRV_M48T59 is not set +-# CONFIG_RTC_DRV_BQ4802 is not set + # CONFIG_RTC_DRV_V3020 is not set + + # + # on-CPU RTC drivers + # +-CONFIG_RTC_DRV_TX4939=y +-# CONFIG_DMADEVICES is not set + # CONFIG_UIO is not set +-# CONFIG_STAGING is not set + + # + # File systems + # + # CONFIG_EXT2_FS is not set + # CONFIG_EXT3_FS is not set +-# CONFIG_EXT4_FS is not set + # CONFIG_REISERFS_FS is not set + # CONFIG_JFS_FS is not set + CONFIG_FS_POSIX_ACL=y +-CONFIG_FILE_LOCKING=y + # CONFIG_XFS_FS is not set + # CONFIG_OCFS2_FS is not set + # CONFIG_DNOTIFY is not set +@@ -885,19 +687,30 @@ + CONFIG_PROC_FS=y + # CONFIG_PROC_KCORE is not set + CONFIG_PROC_SYSCTL=y +-CONFIG_PROC_PAGE_MONITOR=y + CONFIG_SYSFS=y + CONFIG_TMPFS=y + CONFIG_TMPFS_POSIX_ACL=y + # CONFIG_HUGETLB_PAGE is not set + # CONFIG_CONFIGFS_FS is not set +-# CONFIG_MISC_FILESYSTEMS is not set ++ ++# ++# Miscellaneous filesystems ++# ++# CONFIG_HFSPLUS_FS is not set ++# CONFIG_CRAMFS is not set ++# CONFIG_VXFS_FS is not set ++# CONFIG_MINIX_FS is not set ++# CONFIG_HPFS_FS is not set ++# CONFIG_QNX4FS_FS is not set ++# CONFIG_ROMFS_FS is not set ++# CONFIG_SYSV_FS is not set ++# CONFIG_UFS_FS is not set + CONFIG_NETWORK_FILESYSTEMS=y + CONFIG_NFS_FS=y + CONFIG_NFS_V3=y + # CONFIG_NFS_V3_ACL is not set +-CONFIG_ROOT_NFS=y + # CONFIG_NFSD is not set ++CONFIG_ROOT_NFS=y + CONFIG_LOCKD=y + CONFIG_LOCKD_V4=y + CONFIG_NFS_COMMON=y +@@ -927,16 +740,7 @@ + CONFIG_DEBUG_FS=y + # CONFIG_HEADERS_CHECK is not set + # CONFIG_DEBUG_KERNEL is not set +-# CONFIG_DEBUG_MEMORY_INIT is not set +-# CONFIG_RCU_CPU_STALL_DETECTOR is not set +-CONFIG_SYSCTL_SYSCALL_CHECK=y +- +-# +-# Tracers +-# +-# CONFIG_DYNAMIC_PRINTK_DEBUG is not set + # CONFIG_SAMPLES is not set +-CONFIG_HAVE_ARCH_KGDB=y + CONFIG_CMDLINE="" + + # +@@ -944,18 +748,15 @@ + # + # CONFIG_KEYS is not set + # CONFIG_SECURITY is not set +-# CONFIG_SECURITYFS is not set +-# CONFIG_SECURITY_FILE_CAPABILITIES is not set + # CONFIG_CRYPTO is not set + + # + # Library routines + # + CONFIG_BITREVERSE=y +-CONFIG_GENERIC_FIND_LAST_BIT=y ++# CONFIG_GENERIC_FIND_FIRST_BIT is not set + # CONFIG_CRC_CCITT is not set + # CONFIG_CRC16 is not set +-# CONFIG_CRC_T10DIF is not set + # CONFIG_CRC_ITU_T is not set + CONFIG_CRC32=y + # CONFIG_CRC7 is not set +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/arch/mips/emma/Kconfig linux-2.6.29-rc3.owrt/arch/mips/emma/Kconfig +--- linux-2.6.29.owrt/arch/mips/emma/Kconfig 1970-01-01 01:00:00.000000000 +0100 ++++ linux-2.6.29-rc3.owrt/arch/mips/emma/Kconfig 2009-05-10 23:48:28.000000000 +0200 +@@ -0,0 +1,29 @@ ++choice ++ prompt "Machine type" ++ depends on MACH_EMMA ++ default NEC_MARKEINS ++ ++config NEC_MARKEINS ++ bool "NEC EMMA2RH Mark-eins board" ++ select SOC_EMMA2RH ++ select HW_HAS_PCI ++ help ++ This enables support for the NEC Electronics Mark-eins boards. ++ ++endchoice ++ ++config SOC_EMMA2RH ++ bool ++ select SOC_EMMA ++ select SYS_HAS_CPU_R5500 ++ select SYS_SUPPORTS_32BIT_KERNEL ++ select SYS_SUPPORTS_64BIT_KERNEL ++ ++config SOC_EMMA ++ bool ++ select CEVT_R4K ++ select CSRC_R4K ++ select DMA_NONCOHERENT ++ select IRQ_CPU ++ select SWAP_IO_SPACE ++ select SYS_SUPPORTS_BIG_ENDIAN +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/arch/mips/emma/markeins/platform.c linux-2.6.29-rc3.owrt/arch/mips/emma/markeins/platform.c +--- linux-2.6.29.owrt/arch/mips/emma/markeins/platform.c 2009-05-10 22:04:40.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/arch/mips/emma/markeins/platform.c 2009-05-10 23:48:28.000000000 +0200 +@@ -141,6 +141,13 @@ + }, + }; + ++static struct platform_device *devices[] = { ++ &i2c_emma_devices[0], ++ &i2c_emma_devices[1], ++ &i2c_emma_devices[2], ++ &serial_emma, ++}; ++ + static struct mtd_partition markeins_parts[] = { + [0] = { + .name = "RootFS", +@@ -174,39 +181,11 @@ + }, + }; + +-static struct physmap_flash_data markeins_flash_data = { +- .width = 2, +- .nr_parts = ARRAY_SIZE(markeins_parts), +- .parts = markeins_parts +-}; +- +-static struct resource markeins_flash_resource = { +- .start = 0x1e000000, +- .end = 0x02000000, +- .flags = IORESOURCE_MEM +-}; +- +-static struct platform_device markeins_flash_device = { +- .name = "physmap-flash", +- .id = 0, +- .dev = { +- .platform_data = &markeins_flash_data, +- }, +- .num_resources = 1, +- .resource = &markeins_flash_resource, +-}; +- +-static struct platform_device *devices[] = { +- i2c_emma_devices, +- i2c_emma_devices + 1, +- i2c_emma_devices + 2, +- &serial_emma, +- &markeins_flash_device, +-}; +- + static int __init platform_devices_setup(void) + { ++ physmap_set_partitions(markeins_parts, ARRAY_SIZE(markeins_parts)); + return platform_add_devices(devices, ARRAY_SIZE(devices)); + } + + arch_initcall(platform_devices_setup); ++ +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/arch/mips/include/asm/atomic.h linux-2.6.29-rc3.owrt/arch/mips/include/asm/atomic.h +--- linux-2.6.29.owrt/arch/mips/include/asm/atomic.h 2009-05-10 22:04:40.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/arch/mips/include/asm/atomic.h 2009-05-10 23:48:28.000000000 +0200 +@@ -50,7 +50,7 @@ + static __inline__ void atomic_add(int i, atomic_t * v) + { + if (cpu_has_llsc && R10000_LLSC_WAR) { +- int temp; ++ unsigned long temp; + + __asm__ __volatile__( + " .set mips3 \n" +@@ -62,7 +62,7 @@ + : "=&r" (temp), "=m" (v->counter) + : "Ir" (i), "m" (v->counter)); + } else if (cpu_has_llsc) { +- int temp; ++ unsigned long temp; + + __asm__ __volatile__( + " .set mips3 \n" +@@ -95,7 +95,7 @@ + static __inline__ void atomic_sub(int i, atomic_t * v) + { + if (cpu_has_llsc && R10000_LLSC_WAR) { +- int temp; ++ unsigned long temp; + + __asm__ __volatile__( + " .set mips3 \n" +@@ -107,7 +107,7 @@ + : "=&r" (temp), "=m" (v->counter) + : "Ir" (i), "m" (v->counter)); + } else if (cpu_has_llsc) { +- int temp; ++ unsigned long temp; + + __asm__ __volatile__( + " .set mips3 \n" +@@ -135,12 +135,12 @@ + */ + static __inline__ int atomic_add_return(int i, atomic_t * v) + { +- int result; ++ unsigned long result; + + smp_llsc_mb(); + + if (cpu_has_llsc && R10000_LLSC_WAR) { +- int temp; ++ unsigned long temp; + + __asm__ __volatile__( + " .set mips3 \n" +@@ -154,7 +154,7 @@ + : "Ir" (i), "m" (v->counter) + : "memory"); + } else if (cpu_has_llsc) { +- int temp; ++ unsigned long temp; + + __asm__ __volatile__( + " .set mips3 \n" +@@ -187,12 +187,12 @@ + + static __inline__ int atomic_sub_return(int i, atomic_t * v) + { +- int result; ++ unsigned long result; + + smp_llsc_mb(); + + if (cpu_has_llsc && R10000_LLSC_WAR) { +- int temp; ++ unsigned long temp; + + __asm__ __volatile__( + " .set mips3 \n" +@@ -206,7 +206,7 @@ + : "Ir" (i), "m" (v->counter) + : "memory"); + } else if (cpu_has_llsc) { +- int temp; ++ unsigned long temp; + + __asm__ __volatile__( + " .set mips3 \n" +@@ -247,12 +247,12 @@ + */ + static __inline__ int atomic_sub_if_positive(int i, atomic_t * v) + { +- int result; ++ unsigned long result; + + smp_llsc_mb(); + + if (cpu_has_llsc && R10000_LLSC_WAR) { +- int temp; ++ unsigned long temp; + + __asm__ __volatile__( + " .set mips3 \n" +@@ -270,7 +270,7 @@ + : "Ir" (i), "m" (v->counter) + : "memory"); + } else if (cpu_has_llsc) { +- int temp; ++ unsigned long temp; + + __asm__ __volatile__( + " .set mips3 \n" +@@ -429,7 +429,7 @@ + static __inline__ void atomic64_add(long i, atomic64_t * v) + { + if (cpu_has_llsc && R10000_LLSC_WAR) { +- long temp; ++ unsigned long temp; + + __asm__ __volatile__( + " .set mips3 \n" +@@ -441,7 +441,7 @@ + : "=&r" (temp), "=m" (v->counter) + : "Ir" (i), "m" (v->counter)); + } else if (cpu_has_llsc) { +- long temp; ++ unsigned long temp; + + __asm__ __volatile__( + " .set mips3 \n" +@@ -474,7 +474,7 @@ + static __inline__ void atomic64_sub(long i, atomic64_t * v) + { + if (cpu_has_llsc && R10000_LLSC_WAR) { +- long temp; ++ unsigned long temp; + + __asm__ __volatile__( + " .set mips3 \n" +@@ -486,7 +486,7 @@ + : "=&r" (temp), "=m" (v->counter) + : "Ir" (i), "m" (v->counter)); + } else if (cpu_has_llsc) { +- long temp; ++ unsigned long temp; + + __asm__ __volatile__( + " .set mips3 \n" +@@ -514,12 +514,12 @@ + */ + static __inline__ long atomic64_add_return(long i, atomic64_t * v) + { +- long result; ++ unsigned long result; + + smp_llsc_mb(); + + if (cpu_has_llsc && R10000_LLSC_WAR) { +- long temp; ++ unsigned long temp; + + __asm__ __volatile__( + " .set mips3 \n" +@@ -533,7 +533,7 @@ + : "Ir" (i), "m" (v->counter) + : "memory"); + } else if (cpu_has_llsc) { +- long temp; ++ unsigned long temp; + + __asm__ __volatile__( + " .set mips3 \n" +@@ -566,12 +566,12 @@ + + static __inline__ long atomic64_sub_return(long i, atomic64_t * v) + { +- long result; ++ unsigned long result; + + smp_llsc_mb(); + + if (cpu_has_llsc && R10000_LLSC_WAR) { +- long temp; ++ unsigned long temp; + + __asm__ __volatile__( + " .set mips3 \n" +@@ -585,7 +585,7 @@ + : "Ir" (i), "m" (v->counter) + : "memory"); + } else if (cpu_has_llsc) { +- long temp; ++ unsigned long temp; + + __asm__ __volatile__( + " .set mips3 \n" +@@ -626,12 +626,12 @@ + */ + static __inline__ long atomic64_sub_if_positive(long i, atomic64_t * v) + { +- long result; ++ unsigned long result; + + smp_llsc_mb(); + + if (cpu_has_llsc && R10000_LLSC_WAR) { +- long temp; ++ unsigned long temp; + + __asm__ __volatile__( + " .set mips3 \n" +@@ -649,7 +649,7 @@ + : "Ir" (i), "m" (v->counter) + : "memory"); + } else if (cpu_has_llsc) { +- long temp; ++ unsigned long temp; + + __asm__ __volatile__( + " .set mips3 \n" +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/arch/mips/include/asm/compat.h linux-2.6.29-rc3.owrt/arch/mips/include/asm/compat.h +--- linux-2.6.29.owrt/arch/mips/include/asm/compat.h 2009-05-10 22:04:40.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/arch/mips/include/asm/compat.h 2009-05-10 23:48:28.000000000 +0200 +@@ -3,8 +3,6 @@ + /* + * Architecture specific compatibility types + */ +-#include <linux/seccomp.h> +-#include <linux/thread_info.h> + #include <linux/types.h> + #include <asm/page.h> + #include <asm/ptrace.h> +@@ -220,9 +218,4 @@ + compat_ulong_t __unused2; + }; + +-static inline int is_compat_task(void) +-{ +- return test_thread_flag(TIF_32BIT); +-} +- + #endif /* _ASM_COMPAT_H */ +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/arch/mips/include/asm/hazards.h linux-2.6.29-rc3.owrt/arch/mips/include/asm/hazards.h +--- linux-2.6.29.owrt/arch/mips/include/asm/hazards.h 2009-05-10 22:04:40.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/arch/mips/include/asm/hazards.h 2009-05-10 23:48:28.000000000 +0200 +@@ -138,8 +138,7 @@ + __instruction_hazard(); \ + } while (0) + +-#elif defined(CONFIG_CPU_R10000) || defined(CONFIG_CPU_CAVIUM_OCTEON) || \ +- defined(CONFIG_CPU_R5500) ++#elif defined(CONFIG_CPU_R10000) || defined(CONFIG_CPU_CAVIUM_OCTEON) + + /* + * R10000 rocks - all hazards handled in hardware, so this becomes a nobrainer. +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/arch/mips/include/asm/mach-rc32434/gpio.h linux-2.6.29-rc3.owrt/arch/mips/include/asm/mach-rc32434/gpio.h +--- linux-2.6.29.owrt/arch/mips/include/asm/mach-rc32434/gpio.h 2009-05-10 22:04:40.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/arch/mips/include/asm/mach-rc32434/gpio.h 2009-05-10 23:48:28.000000000 +0200 +@@ -80,8 +80,11 @@ + /* Compact Flash GPIO pin */ + #define CF_GPIO_NUM 13 + ++extern void set_434_reg(unsigned reg_offs, unsigned bit, unsigned len, unsigned val); ++extern unsigned get_434_reg(unsigned reg_offs); ++extern void set_latch_u5(unsigned char or_mask, unsigned char nand_mask); ++extern unsigned char get_latch_u5(void); + extern void rb532_gpio_set_ilevel(int bit, unsigned gpio); + extern void rb532_gpio_set_istat(int bit, unsigned gpio); +-extern void rb532_gpio_set_func(unsigned gpio); + + #endif /* _RC32434_GPIO_H_ */ +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/arch/mips/include/asm/mach-rc32434/irq.h linux-2.6.29-rc3.owrt/arch/mips/include/asm/mach-rc32434/irq.h +--- linux-2.6.29.owrt/arch/mips/include/asm/mach-rc32434/irq.h 2009-05-10 22:04:40.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/arch/mips/include/asm/mach-rc32434/irq.h 2009-05-10 23:48:28.000000000 +0200 +@@ -30,7 +30,4 @@ + #define ETH0_RX_OVR_IRQ (GROUP3_IRQ_BASE + 9) + #define ETH0_TX_UND_IRQ (GROUP3_IRQ_BASE + 10) + +-#define GPIO_MAPPED_IRQ_BASE GROUP4_IRQ_BASE +-#define GPIO_MAPPED_IRQ_GROUP 4 +- + #endif /* __ASM_RC32434_IRQ_H */ +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/arch/mips/include/asm/mach-rc32434/rb.h linux-2.6.29-rc3.owrt/arch/mips/include/asm/mach-rc32434/rb.h +--- linux-2.6.29.owrt/arch/mips/include/asm/mach-rc32434/rb.h 2009-05-10 22:04:40.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/arch/mips/include/asm/mach-rc32434/rb.h 2009-05-10 23:48:28.000000000 +0200 +@@ -83,7 +83,4 @@ + void __iomem *base; + }; + +-extern void set_latch_u5(unsigned char or_mask, unsigned char nand_mask); +-extern unsigned char get_latch_u5(void); +- + #endif /* __ASM_RC32434_RB_H */ +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/arch/mips/include/asm/prefetch.h linux-2.6.29-rc3.owrt/arch/mips/include/asm/prefetch.h +--- linux-2.6.29.owrt/arch/mips/include/asm/prefetch.h 2009-05-10 22:04:40.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/arch/mips/include/asm/prefetch.h 2009-05-10 23:48:28.000000000 +0200 +@@ -26,7 +26,7 @@ + * Pref_WriteBackInvalidate is a nop and Pref_PrepareForStore is broken in + * current versions due to erratum G105. + * +- * VR5500 (including VR5701 and VR7701) only implement load prefetch. ++ * VR7701 only implements the Load prefetch. + * + * Finally MIPS32 and MIPS64 implement all of the following hints. + */ +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/arch/mips/include/asm/ptrace.h linux-2.6.29-rc3.owrt/arch/mips/include/asm/ptrace.h +--- linux-2.6.29.owrt/arch/mips/include/asm/ptrace.h 2009-05-10 22:04:40.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/arch/mips/include/asm/ptrace.h 2009-05-10 23:48:28.000000000 +0200 +@@ -105,7 +105,7 @@ + enum pt_watch_style style; + union { + struct mips32_watch_regs mips32; +- struct mips64_watch_regs mips64; ++ struct mips32_watch_regs mips64; + }; + }; + +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/arch/mips/include/asm/seccomp.h linux-2.6.29-rc3.owrt/arch/mips/include/asm/seccomp.h +--- linux-2.6.29.owrt/arch/mips/include/asm/seccomp.h 2009-05-10 22:04:40.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/arch/mips/include/asm/seccomp.h 2009-05-10 23:48:28.000000000 +0200 +@@ -1,5 +1,6 @@ + #ifndef __ASM_SECCOMP_H + ++#include <linux/thread_info.h> + #include <linux/unistd.h> + + #define __NR_seccomp_read __NR_read +@@ -15,6 +16,8 @@ + */ + #ifdef CONFIG_MIPS32_O32 + ++#define TIF_32BIT TIF_32BIT_REGS ++ + #define __NR_seccomp_read_32 4003 + #define __NR_seccomp_write_32 4004 + #define __NR_seccomp_exit_32 4001 +@@ -22,6 +25,8 @@ + + #elif defined(CONFIG_MIPS32_N32) + ++#define TIF_32BIT _TIF_32BIT_ADDR ++ + #define __NR_seccomp_read_32 6000 + #define __NR_seccomp_write_32 6001 + #define __NR_seccomp_exit_32 6058 +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/arch/mips/include/asm/spinlock.h linux-2.6.29-rc3.owrt/arch/mips/include/asm/spinlock.h +--- linux-2.6.29.owrt/arch/mips/include/asm/spinlock.h 2009-05-10 22:04:40.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/arch/mips/include/asm/spinlock.h 2009-05-10 23:48:28.000000000 +0200 +@@ -51,7 +51,6 @@ + + return (((counters >> 14) - counters) & 0x1fff) > 1; + } +-#define __raw_spin_is_contended __raw_spin_is_contended + + static inline void __raw_spin_lock(raw_spinlock_t *lock) + { +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/arch/mips/include/asm/termios.h linux-2.6.29-rc3.owrt/arch/mips/include/asm/termios.h +--- linux-2.6.29.owrt/arch/mips/include/asm/termios.h 2009-05-10 22:04:40.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/arch/mips/include/asm/termios.h 2009-05-10 23:48:28.000000000 +0200 +@@ -9,7 +9,6 @@ + #ifndef _ASM_TERMIOS_H + #define _ASM_TERMIOS_H + +-#include <linux/errno.h> + #include <asm/termbits.h> + #include <asm/ioctls.h> + +@@ -95,81 +94,38 @@ + /* + * Translate a "termio" structure into a "termios". Ugh. + */ +-static inline int user_termio_to_kernel_termios(struct ktermios *termios, +- struct termio __user *termio) +-{ +- unsigned short iflag, oflag, cflag, lflag; +- unsigned int err; +- +- if (!access_ok(VERIFY_READ, termio, sizeof(struct termio))) +- return -EFAULT; +- +- err = __get_user(iflag, &termio->c_iflag); +- termios->c_iflag = (termios->c_iflag & 0xffff0000) | iflag; +- err |=__get_user(oflag, &termio->c_oflag); +- termios->c_oflag = (termios->c_oflag & 0xffff0000) | oflag; +- err |=__get_user(cflag, &termio->c_cflag); +- termios->c_cflag = (termios->c_cflag & 0xffff0000) | cflag; +- err |=__get_user(lflag, &termio->c_lflag); +- termios->c_lflag = (termios->c_lflag & 0xffff0000) | lflag; +- err |=__get_user(termios->c_line, &termio->c_line); +- if (err) +- return -EFAULT; +- +- if (__copy_from_user(termios->c_cc, termio->c_cc, NCC)) +- return -EFAULT; +- +- return 0; +-} ++#define user_termio_to_kernel_termios(termios, termio) \ ++({ \ ++ unsigned short tmp; \ ++ get_user(tmp, &(termio)->c_iflag); \ ++ (termios)->c_iflag = (0xffff0000 & ((termios)->c_iflag)) | tmp; \ ++ get_user(tmp, &(termio)->c_oflag); \ ++ (termios)->c_oflag = (0xffff0000 & ((termios)->c_oflag)) | tmp; \ ++ get_user(tmp, &(termio)->c_cflag); \ ++ (termios)->c_cflag = (0xffff0000 & ((termios)->c_cflag)) | tmp; \ ++ get_user(tmp, &(termio)->c_lflag); \ ++ (termios)->c_lflag = (0xffff0000 & ((termios)->c_lflag)) | tmp; \ ++ get_user((termios)->c_line, &(termio)->c_line); \ ++ copy_from_user((termios)->c_cc, (termio)->c_cc, NCC); \ ++}) + + /* + * Translate a "termios" structure into a "termio". Ugh. + */ +-static inline int kernel_termios_to_user_termio(struct termio __user *termio, +- struct ktermios *termios) +-{ +- int err; +- +- if (!access_ok(VERIFY_WRITE, termio, sizeof(struct termio))) +- return -EFAULT; +- +- err = __put_user(termios->c_iflag, &termio->c_iflag); +- err |= __put_user(termios->c_oflag, &termio->c_oflag); +- err |= __put_user(termios->c_cflag, &termio->c_cflag); +- err |= __put_user(termios->c_lflag, &termio->c_lflag); +- err |= __put_user(termios->c_line, &termio->c_line); +- if (err) +- return -EFAULT; +- +- if (__copy_to_user(termio->c_cc, termios->c_cc, NCC)) +- return -EFAULT; +- +- return 0; +-} +- +-static inline int user_termios_to_kernel_termios(struct ktermios __user *k, +- struct termios2 *u) +-{ +- return copy_from_user(k, u, sizeof(struct termios2)) ? -EFAULT : 0; +-} +- +-static inline int kernel_termios_to_user_termios(struct termios2 __user *u, +- struct ktermios *k) +-{ +- return copy_to_user(u, k, sizeof(struct termios2)) ? -EFAULT : 0; +-} +- +-static inline int user_termios_to_kernel_termios_1(struct ktermios *k, +- struct termios __user *u) +-{ +- return copy_from_user(k, u, sizeof(struct termios)) ? -EFAULT : 0; +-} +- +-static inline int kernel_termios_to_user_termios_1(struct termios __user *u, +- struct ktermios *k) +-{ +- return copy_to_user(u, k, sizeof(struct termios)) ? -EFAULT : 0; +-} ++#define kernel_termios_to_user_termio(termio, termios) \ ++({ \ ++ put_user((termios)->c_iflag, &(termio)->c_iflag); \ ++ put_user((termios)->c_oflag, &(termio)->c_oflag); \ ++ put_user((termios)->c_cflag, &(termio)->c_cflag); \ ++ put_user((termios)->c_lflag, &(termio)->c_lflag); \ ++ put_user((termios)->c_line, &(termio)->c_line); \ ++ copy_to_user((termio)->c_cc, (termios)->c_cc, NCC); \ ++}) ++ ++#define user_termios_to_kernel_termios(k, u) copy_from_user(k, u, sizeof(struct termios2)) ++#define kernel_termios_to_user_termios(u, k) copy_to_user(u, k, sizeof(struct termios2)) ++#define user_termios_to_kernel_termios_1(k, u) copy_from_user(k, u, sizeof(struct termios)) ++#define kernel_termios_to_user_termios_1(u, k) copy_to_user(u, k, sizeof(struct termios)) + + #endif /* defined(__KERNEL__) */ + +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/arch/mips/include/asm/thread_info.h linux-2.6.29-rc3.owrt/arch/mips/include/asm/thread_info.h +--- linux-2.6.29.owrt/arch/mips/include/asm/thread_info.h 2009-05-10 22:04:40.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/arch/mips/include/asm/thread_info.h 2009-05-10 23:48:28.000000000 +0200 +@@ -127,12 +127,6 @@ + #define TIF_LOAD_WATCH 25 /* If set, load watch registers */ + #define TIF_SYSCALL_TRACE 31 /* syscall trace active */ + +-#ifdef CONFIG_MIPS32_O32 +-#define TIF_32BIT TIF_32BIT_REGS +-#elif defined(CONFIG_MIPS32_N32) +-#define TIF_32BIT _TIF_32BIT_ADDR +-#endif /* CONFIG_MIPS32_O32 */ +- + #define _TIF_SYSCALL_TRACE (1<<TIF_SYSCALL_TRACE) + #define _TIF_SIGPENDING (1<<TIF_SIGPENDING) + #define _TIF_NEED_RESCHED (1<<TIF_NEED_RESCHED) +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/arch/mips/include/asm/txx9/tx4939.h linux-2.6.29-rc3.owrt/arch/mips/include/asm/txx9/tx4939.h +--- linux-2.6.29.owrt/arch/mips/include/asm/txx9/tx4939.h 2009-05-10 22:04:40.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/arch/mips/include/asm/txx9/tx4939.h 2009-05-10 23:48:28.000000000 +0200 +@@ -541,6 +541,5 @@ + int tx4939_irq(void); + void tx4939_mtd_init(int ch); + void tx4939_ata_init(void); +-void tx4939_rtc_init(void); + + #endif /* __ASM_TXX9_TX4939_H */ +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/arch/mips/Kconfig linux-2.6.29-rc3.owrt/arch/mips/Kconfig +--- linux-2.6.29.owrt/arch/mips/Kconfig 2009-05-10 22:04:40.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/arch/mips/Kconfig 2009-05-10 23:48:28.000000000 +0200 +@@ -238,12 +238,8 @@ + This option enables support for MIPS Technologies MIPSsim software + emulator. + +-config NEC_MARKEINS +- bool "NEC EMMA2RH Mark-eins board" +- select SOC_EMMA2RH +- select HW_HAS_PCI +- help +- This enables support for the NEC Electronics Mark-eins boards. ++config MACH_EMMA ++ bool "NEC EMMA series based machines" + + config MACH_VR41XX + bool "NEC VR4100 series based machines" +@@ -355,7 +351,7 @@ + select ARC64 + select BOOT_ELF64 + select DEFAULT_SGI_PARTITION +- select DMA_COHERENT ++ select DMA_IP27 + select SYS_HAS_EARLY_PRINTK + select HW_HAS_PCI + select NR_CPUS_DEFAULT_64 +@@ -607,7 +603,7 @@ + select SYS_SUPPORTS_64BIT_KERNEL + select SYS_SUPPORTS_BIG_ENDIAN + select SYS_SUPPORTS_HIGHMEM +- select SYS_HAS_CPU_CAVIUM_OCTEON ++ select CPU_CAVIUM_OCTEON + help + The Octeon simulator is software performance model of the Cavium + Octeon Processor. It supports simulating Octeon processors on x86 +@@ -622,7 +618,7 @@ + select SYS_SUPPORTS_BIG_ENDIAN + select SYS_SUPPORTS_HIGHMEM + select SYS_HAS_EARLY_PRINTK +- select SYS_HAS_CPU_CAVIUM_OCTEON ++ select CPU_CAVIUM_OCTEON + select SWAP_IO_SPACE + help + This option supports all of the Octeon reference boards from Cavium +@@ -641,6 +637,7 @@ + + source "arch/mips/alchemy/Kconfig" + source "arch/mips/basler/excite/Kconfig" ++source "arch/mips/emma/Kconfig" + source "arch/mips/jazz/Kconfig" + source "arch/mips/lasat/Kconfig" + source "arch/mips/pmc-sierra/Kconfig" +@@ -764,6 +761,9 @@ + config DMA_COHERENT + bool + ++config DMA_IP27 ++ bool ++ + config DMA_NONCOHERENT + bool + select DMA_NEED_PCI_MAP_STATE +@@ -904,18 +904,6 @@ + bool + select SERIAL_RM9000 + +-config SOC_EMMA2RH +- bool +- select CEVT_R4K +- select CSRC_R4K +- select DMA_NONCOHERENT +- select IRQ_CPU +- select SWAP_IO_SPACE +- select SYS_HAS_CPU_R5500 +- select SYS_SUPPORTS_32BIT_KERNEL +- select SYS_SUPPORTS_64BIT_KERNEL +- select SYS_SUPPORTS_BIG_ENDIAN +- + config SOC_PNX833X + bool + select CEVT_R4K +@@ -951,6 +939,11 @@ + config SWAP_IO_SPACE + bool + ++config EMMA2RH ++ bool ++ depends on MARKEINS ++ default y ++ + config SERIAL_RM9000 + bool + +@@ -1250,7 +1243,6 @@ + + config CPU_CAVIUM_OCTEON + bool "Cavium Octeon processor" +- depends on SYS_HAS_CPU_CAVIUM_OCTEON + select IRQ_CPU + select IRQ_CPU_OCTEON + select CPU_HAS_PREFETCH +@@ -1331,9 +1323,6 @@ + config SYS_HAS_CPU_SB1 + bool + +-config SYS_HAS_CPU_CAVIUM_OCTEON +- bool +- + # + # CPU may reorder R->R, R->W, W->R, W->W + # Reordering beyond LL and SC is handled in WEAK_REORDERING_BEYOND_LLSC +@@ -1385,7 +1374,7 @@ + # + config HARDWARE_WATCHPOINTS + bool +- default y if CPU_MIPSR1 || CPU_MIPSR2 ++ default y if CPU_MIPS32 || CPU_MIPS64 + + menu "Kernel type" + +@@ -1407,7 +1396,6 @@ + config 64BIT + bool "64-bit kernel" + depends on CPU_SUPPORTS_64BIT_KERNEL && SYS_SUPPORTS_64BIT_KERNEL +- select HAVE_SYSCALL_WRAPPERS + help + Select this option if you want to build a 64-bit kernel. + +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/arch/mips/kernel/cpu-probe.c linux-2.6.29-rc3.owrt/arch/mips/kernel/cpu-probe.c +--- linux-2.6.29.owrt/arch/mips/kernel/cpu-probe.c 2009-05-10 22:04:40.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/arch/mips/kernel/cpu-probe.c 2009-05-10 23:48:28.000000000 +0200 +@@ -149,7 +149,6 @@ + case CPU_R4650: + case CPU_R4700: + case CPU_R5000: +- case CPU_R5500: + case CPU_NEVADA: + case CPU_4KC: + case CPU_4KEC: +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/arch/mips/kernel/genex.S linux-2.6.29-rc3.owrt/arch/mips/kernel/genex.S +--- linux-2.6.29.owrt/arch/mips/kernel/genex.S 2009-05-10 22:04:40.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/arch/mips/kernel/genex.S 2009-05-10 23:48:28.000000000 +0200 +@@ -458,11 +458,7 @@ + BUILD_HANDLER fpe fpe fpe silent /* #15 */ + BUILD_HANDLER mdmx mdmx sti silent /* #22 */ + #ifdef CONFIG_HARDWARE_WATCHPOINTS +- /* +- * For watch, interrupts will be enabled after the watch +- * registers are read. +- */ +- BUILD_HANDLER watch watch cli silent /* #23 */ ++ BUILD_HANDLER watch watch sti silent /* #23 */ + #else + BUILD_HANDLER watch watch sti verbose /* #23 */ + #endif +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/arch/mips/kernel/irq.c linux-2.6.29-rc3.owrt/arch/mips/kernel/irq.c +--- linux-2.6.29.owrt/arch/mips/kernel/irq.c 2009-05-10 22:04:40.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/arch/mips/kernel/irq.c 2009-05-10 23:48:28.000000000 +0200 +@@ -111,6 +111,7 @@ + seq_printf(p, "%10u ", kstat_cpu(j).irqs[i]); + #endif + seq_printf(p, " %14s", irq_desc[i].chip->name); ++ seq_printf(p, "-%-8s", irq_desc[i].name); + seq_printf(p, " %s", action->name); + + for (action=action->next; action; action = action->next) +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/arch/mips/kernel/linux32.c linux-2.6.29-rc3.owrt/arch/mips/kernel/linux32.c +--- linux-2.6.29.owrt/arch/mips/kernel/linux32.c 2009-05-10 22:04:40.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/arch/mips/kernel/linux32.c 2009-05-10 23:48:28.000000000 +0200 +@@ -32,7 +32,6 @@ + #include <linux/module.h> + #include <linux/binfmts.h> + #include <linux/security.h> +-#include <linux/syscalls.h> + #include <linux/compat.h> + #include <linux/vfs.h> + #include <linux/ipc.h> +@@ -64,9 +63,9 @@ + #define merge_64(r1, r2) ((((r2) & 0xffffffffUL) << 32) + ((r1) & 0xffffffffUL)) + #endif + +-SYSCALL_DEFINE6(32_mmap2, unsigned long, addr, unsigned long, len, +- unsigned long, prot, unsigned long, flags, unsigned long, fd, +- unsigned long, pgoff) ++asmlinkage unsigned long ++sys32_mmap2(unsigned long addr, unsigned long len, unsigned long prot, ++ unsigned long flags, unsigned long fd, unsigned long pgoff) + { + struct file * file = NULL; + unsigned long error; +@@ -122,21 +121,21 @@ + int rlim_max; + }; + +-SYSCALL_DEFINE4(32_truncate64, const char __user *, path, +- unsigned long, __dummy, unsigned long, a2, unsigned long, a3) ++asmlinkage long sys32_truncate64(const char __user * path, ++ unsigned long __dummy, int a2, int a3) + { + return sys_truncate(path, merge_64(a2, a3)); + } + +-SYSCALL_DEFINE4(32_ftruncate64, unsigned long, fd, unsigned long, __dummy, +- unsigned long, a2, unsigned long, a3) ++asmlinkage long sys32_ftruncate64(unsigned int fd, unsigned long __dummy, ++ int a2, int a3) + { + return sys_ftruncate(fd, merge_64(a2, a3)); + } + +-SYSCALL_DEFINE5(32_llseek, unsigned long, fd, unsigned long, offset_high, +- unsigned long, offset_low, loff_t __user *, result, +- unsigned long, origin) ++asmlinkage int sys32_llseek(unsigned int fd, unsigned int offset_high, ++ unsigned int offset_low, loff_t __user * result, ++ unsigned int origin) + { + return sys_llseek(fd, offset_high, offset_low, result, origin); + } +@@ -145,20 +144,20 @@ + lseek back to original location. They fail just like lseek does on + non-seekable files. */ + +-SYSCALL_DEFINE6(32_pread, unsigned long, fd, char __user *, buf, size_t, count, +- unsigned long, unused, unsigned long, a4, unsigned long, a5) ++asmlinkage ssize_t sys32_pread(unsigned int fd, char __user * buf, ++ size_t count, u32 unused, u64 a4, u64 a5) + { + return sys_pread64(fd, buf, count, merge_64(a4, a5)); + } + +-SYSCALL_DEFINE6(32_pwrite, unsigned int, fd, const char __user *, buf, +- size_t, count, u32, unused, u64, a4, u64, a5) ++asmlinkage ssize_t sys32_pwrite(unsigned int fd, const char __user * buf, ++ size_t count, u32 unused, u64 a4, u64 a5) + { + return sys_pwrite64(fd, buf, count, merge_64(a4, a5)); + } + +-SYSCALL_DEFINE2(32_sched_rr_get_interval, compat_pid_t, pid, +- struct compat_timespec __user *, interval) ++asmlinkage int sys32_sched_rr_get_interval(compat_pid_t pid, ++ struct compat_timespec __user *interval) + { + struct timespec t; + int ret; +@@ -175,8 +174,8 @@ + + #ifdef CONFIG_SYSVIPC + +-SYSCALL_DEFINE6(32_ipc, u32, call, long, first, long, second, long, third, +- unsigned long, ptr, unsigned long, fifth) ++asmlinkage long ++sys32_ipc(u32 call, int first, int second, int third, u32 ptr, u32 fifth) + { + int version, err; + +@@ -234,8 +233,8 @@ + + #else + +-SYSCALL_DEFINE6(32_ipc, u32, call, int, first, int, second, int, third, +- u32, ptr, u32, fifth) ++asmlinkage long ++sys32_ipc(u32 call, int first, int second, int third, u32 ptr, u32 fifth) + { + return -ENOSYS; + } +@@ -243,7 +242,7 @@ + #endif /* CONFIG_SYSVIPC */ + + #ifdef CONFIG_MIPS32_N32 +-SYSCALL_DEFINE4(n32_semctl, int, semid, int, semnum, int, cmd, u32, arg) ++asmlinkage long sysn32_semctl(int semid, int semnum, int cmd, u32 arg) + { + /* compat_sys_semctl expects a pointer to union semun */ + u32 __user *uptr = compat_alloc_user_space(sizeof(u32)); +@@ -252,14 +251,13 @@ + return compat_sys_semctl(semid, semnum, cmd, uptr); + } + +-SYSCALL_DEFINE4(n32_msgsnd, int, msqid, u32, msgp, unsigned int, msgsz, +- int, msgflg) ++asmlinkage long sysn32_msgsnd(int msqid, u32 msgp, unsigned msgsz, int msgflg) + { + return compat_sys_msgsnd(msqid, msgsz, msgflg, compat_ptr(msgp)); + } + +-SYSCALL_DEFINE5(n32_msgrcv, int, msqid, u32, msgp, size_t, msgsz, +- int, msgtyp, int, msgflg) ++asmlinkage long sysn32_msgrcv(int msqid, u32 msgp, size_t msgsz, int msgtyp, ++ int msgflg) + { + return compat_sys_msgrcv(msqid, msgsz, msgtyp, msgflg, IPC_64, + compat_ptr(msgp)); +@@ -279,7 +277,7 @@ + + #ifdef CONFIG_SYSCTL_SYSCALL + +-SYSCALL_DEFINE1(32_sysctl, struct sysctl_args32 __user *, args) ++asmlinkage long sys32_sysctl(struct sysctl_args32 __user *args) + { + struct sysctl_args32 tmp; + int error; +@@ -318,16 +316,9 @@ + return error; + } + +-#else +- +-SYSCALL_DEFINE1(32_sysctl, struct sysctl_args32 __user *, args) +-{ +- return -ENOSYS; +-} +- + #endif /* CONFIG_SYSCTL_SYSCALL */ + +-SYSCALL_DEFINE1(32_newuname, struct new_utsname __user *, name) ++asmlinkage long sys32_newuname(struct new_utsname __user * name) + { + int ret = 0; + +@@ -343,7 +334,7 @@ + return ret; + } + +-SYSCALL_DEFINE1(32_personality, unsigned long, personality) ++asmlinkage int sys32_personality(unsigned long personality) + { + int ret; + personality &= 0xffffffff; +@@ -366,7 +357,7 @@ + + extern asmlinkage long sys_ustat(dev_t dev, struct ustat __user * ubuf); + +-SYSCALL_DEFINE2(32_ustat, dev_t, dev, struct ustat32 __user *, ubuf32) ++asmlinkage int sys32_ustat(dev_t dev, struct ustat32 __user * ubuf32) + { + int err; + struct ustat tmp; +@@ -390,8 +381,8 @@ + return err; + } + +-SYSCALL_DEFINE4(32_sendfile, long, out_fd, long, in_fd, +- compat_off_t __user *, offset, s32, count) ++asmlinkage int sys32_sendfile(int out_fd, int in_fd, compat_off_t __user *offset, ++ s32 count) + { + mm_segment_t old_fs = get_fs(); + int ret; +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/arch/mips/kernel/mips-mt-fpaff.c linux-2.6.29-rc3.owrt/arch/mips/kernel/mips-mt-fpaff.c +--- linux-2.6.29.owrt/arch/mips/kernel/mips-mt-fpaff.c 2009-05-10 22:04:40.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/arch/mips/kernel/mips-mt-fpaff.c 2009-05-10 23:48:28.000000000 +0200 +@@ -79,8 +79,7 @@ + + euid = current_euid(); + retval = -EPERM; +- if (euid != p->cred->euid && euid != p->cred->uid && +- !capable(CAP_SYS_NICE)) { ++ if (euid != p->euid && euid != p->uid && !capable(CAP_SYS_NICE)) { + read_unlock(&tasklist_lock); + goto out_unlock; + } +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/arch/mips/kernel/scall32-o32.S linux-2.6.29-rc3.owrt/arch/mips/kernel/scall32-o32.S +--- linux-2.6.29.owrt/arch/mips/kernel/scall32-o32.S 2009-05-10 22:04:40.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/arch/mips/kernel/scall32-o32.S 2009-05-10 23:48:28.000000000 +0200 +@@ -399,7 +399,7 @@ + sys sys_swapon 2 + sys sys_reboot 3 + sys sys_old_readdir 3 +- sys sys_mips_mmap 6 /* 4090 */ ++ sys old_mmap 6 /* 4090 */ + sys sys_munmap 2 + sys sys_truncate 2 + sys sys_ftruncate 2 +@@ -519,7 +519,7 @@ + sys sys_sendfile 4 + sys sys_ni_syscall 0 + sys sys_ni_syscall 0 +- sys sys_mips_mmap2 6 /* 4210 */ ++ sys sys_mmap2 6 /* 4210 */ + sys sys_truncate64 4 + sys sys_ftruncate64 4 + sys sys_stat64 2 +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/arch/mips/kernel/scall64-64.S linux-2.6.29-rc3.owrt/arch/mips/kernel/scall64-64.S +--- linux-2.6.29.owrt/arch/mips/kernel/scall64-64.S 2009-05-10 22:04:40.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/arch/mips/kernel/scall64-64.S 2009-05-10 23:48:28.000000000 +0200 +@@ -207,7 +207,7 @@ + PTR sys_newlstat + PTR sys_poll + PTR sys_lseek +- PTR sys_mips_mmap ++ PTR old_mmap + PTR sys_mprotect /* 5010 */ + PTR sys_munmap + PTR sys_brk +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/arch/mips/kernel/scall64-n32.S linux-2.6.29-rc3.owrt/arch/mips/kernel/scall64-n32.S +--- linux-2.6.29.owrt/arch/mips/kernel/scall64-n32.S 2009-05-10 22:04:40.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/arch/mips/kernel/scall64-n32.S 2009-05-10 23:48:28.000000000 +0200 +@@ -129,12 +129,12 @@ + PTR sys_newlstat + PTR sys_poll + PTR sys_lseek +- PTR sys_mips_mmap ++ PTR old_mmap + PTR sys_mprotect /* 6010 */ + PTR sys_munmap + PTR sys_brk +- PTR sys_32_rt_sigaction +- PTR sys_32_rt_sigprocmask ++ PTR sys32_rt_sigaction ++ PTR sys32_rt_sigprocmask + PTR compat_sys_ioctl /* 6015 */ + PTR sys_pread64 + PTR sys_pwrite64 +@@ -159,7 +159,7 @@ + PTR compat_sys_setitimer + PTR sys_alarm + PTR sys_getpid +- PTR sys_32_sendfile ++ PTR sys32_sendfile + PTR sys_socket /* 6040 */ + PTR sys_connect + PTR sys_accept +@@ -181,14 +181,14 @@ + PTR sys_exit + PTR compat_sys_wait4 + PTR sys_kill /* 6060 */ +- PTR sys_32_newuname ++ PTR sys32_newuname + PTR sys_semget + PTR sys_semop +- PTR sys_n32_semctl ++ PTR sysn32_semctl + PTR sys_shmdt /* 6065 */ + PTR sys_msgget +- PTR sys_n32_msgsnd +- PTR sys_n32_msgrcv ++ PTR sysn32_msgsnd ++ PTR sysn32_msgrcv + PTR compat_sys_msgctl + PTR compat_sys_fcntl /* 6070 */ + PTR sys_flock +@@ -245,15 +245,15 @@ + PTR sys_getsid + PTR sys_capget + PTR sys_capset +- PTR sys_32_rt_sigpending /* 6125 */ ++ PTR sys32_rt_sigpending /* 6125 */ + PTR compat_sys_rt_sigtimedwait +- PTR sys_32_rt_sigqueueinfo ++ PTR sys32_rt_sigqueueinfo + PTR sysn32_rt_sigsuspend + PTR sys32_sigaltstack + PTR compat_sys_utime /* 6130 */ + PTR sys_mknod +- PTR sys_32_personality +- PTR sys_32_ustat ++ PTR sys32_personality ++ PTR sys32_ustat + PTR compat_sys_statfs + PTR compat_sys_fstatfs /* 6135 */ + PTR sys_sysfs +@@ -265,14 +265,14 @@ + PTR sys_sched_getscheduler + PTR sys_sched_get_priority_max + PTR sys_sched_get_priority_min +- PTR sys_32_sched_rr_get_interval /* 6145 */ ++ PTR sys32_sched_rr_get_interval /* 6145 */ + PTR sys_mlock + PTR sys_munlock + PTR sys_mlockall + PTR sys_munlockall + PTR sys_vhangup /* 6150 */ + PTR sys_pivot_root +- PTR sys_32_sysctl ++ PTR sys32_sysctl + PTR sys_prctl + PTR compat_sys_adjtimex + PTR compat_sys_setrlimit /* 6155 */ +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/arch/mips/kernel/scall64-o32.S linux-2.6.29-rc3.owrt/arch/mips/kernel/scall64-o32.S +--- linux-2.6.29.owrt/arch/mips/kernel/scall64-o32.S 2009-05-10 22:04:40.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/arch/mips/kernel/scall64-o32.S 2009-05-10 23:48:28.000000000 +0200 +@@ -265,12 +265,12 @@ + PTR sys_olduname + PTR sys_umask /* 4060 */ + PTR sys_chroot +- PTR sys_32_ustat ++ PTR sys32_ustat + PTR sys_dup2 + PTR sys_getppid + PTR sys_getpgrp /* 4065 */ + PTR sys_setsid +- PTR sys_32_sigaction ++ PTR sys32_sigaction + PTR sys_sgetmask + PTR sys_ssetmask + PTR sys_setreuid /* 4070 */ +@@ -293,7 +293,7 @@ + PTR sys_swapon + PTR sys_reboot + PTR compat_sys_old_readdir +- PTR sys_mips_mmap /* 4090 */ ++ PTR old_mmap /* 4090 */ + PTR sys_munmap + PTR sys_truncate + PTR sys_ftruncate +@@ -320,12 +320,12 @@ + PTR compat_sys_wait4 + PTR sys_swapoff /* 4115 */ + PTR compat_sys_sysinfo +- PTR sys_32_ipc ++ PTR sys32_ipc + PTR sys_fsync + PTR sys32_sigreturn + PTR sys32_clone /* 4120 */ + PTR sys_setdomainname +- PTR sys_32_newuname ++ PTR sys32_newuname + PTR sys_ni_syscall /* sys_modify_ldt */ + PTR compat_sys_adjtimex + PTR sys_mprotect /* 4125 */ +@@ -339,11 +339,11 @@ + PTR sys_fchdir + PTR sys_bdflush + PTR sys_sysfs /* 4135 */ +- PTR sys_32_personality ++ PTR sys32_personality + PTR sys_ni_syscall /* for afs_syscall */ + PTR sys_setfsuid + PTR sys_setfsgid +- PTR sys_32_llseek /* 4140 */ ++ PTR sys32_llseek /* 4140 */ + PTR compat_sys_getdents + PTR compat_sys_select + PTR sys_flock +@@ -356,7 +356,7 @@ + PTR sys_ni_syscall /* 4150 */ + PTR sys_getsid + PTR sys_fdatasync +- PTR sys_32_sysctl ++ PTR sys32_sysctl + PTR sys_mlock + PTR sys_munlock /* 4155 */ + PTR sys_mlockall +@@ -368,7 +368,7 @@ + PTR sys_sched_yield + PTR sys_sched_get_priority_max + PTR sys_sched_get_priority_min +- PTR sys_32_sched_rr_get_interval /* 4165 */ ++ PTR sys32_sched_rr_get_interval /* 4165 */ + PTR compat_sys_nanosleep + PTR sys_mremap + PTR sys_accept +@@ -397,25 +397,25 @@ + PTR sys_getresgid + PTR sys_prctl + PTR sys32_rt_sigreturn +- PTR sys_32_rt_sigaction +- PTR sys_32_rt_sigprocmask /* 4195 */ +- PTR sys_32_rt_sigpending ++ PTR sys32_rt_sigaction ++ PTR sys32_rt_sigprocmask /* 4195 */ ++ PTR sys32_rt_sigpending + PTR compat_sys_rt_sigtimedwait +- PTR sys_32_rt_sigqueueinfo ++ PTR sys32_rt_sigqueueinfo + PTR sys32_rt_sigsuspend +- PTR sys_32_pread /* 4200 */ +- PTR sys_32_pwrite ++ PTR sys32_pread /* 4200 */ ++ PTR sys32_pwrite + PTR sys_chown + PTR sys_getcwd + PTR sys_capget + PTR sys_capset /* 4205 */ + PTR sys32_sigaltstack +- PTR sys_32_sendfile ++ PTR sys32_sendfile + PTR sys_ni_syscall + PTR sys_ni_syscall +- PTR sys_mips_mmap2 /* 4210 */ +- PTR sys_32_truncate64 +- PTR sys_32_ftruncate64 ++ PTR sys32_mmap2 /* 4210 */ ++ PTR sys32_truncate64 ++ PTR sys32_ftruncate64 + PTR sys_newstat + PTR sys_newlstat + PTR sys_newfstat /* 4215 */ +@@ -481,7 +481,7 @@ + PTR compat_sys_mq_notify /* 4275 */ + PTR compat_sys_mq_getsetattr + PTR sys_ni_syscall /* sys_vserver */ +- PTR sys_32_waitid ++ PTR sys32_waitid + PTR sys_ni_syscall /* available, was setaltroot */ + PTR sys_add_key /* 4280 */ + PTR sys_request_key +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/arch/mips/kernel/signal32.c linux-2.6.29-rc3.owrt/arch/mips/kernel/signal32.c +--- linux-2.6.29.owrt/arch/mips/kernel/signal32.c 2009-05-10 22:04:40.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/arch/mips/kernel/signal32.c 2009-05-10 23:48:28.000000000 +0200 +@@ -349,8 +349,8 @@ + return -ERESTARTNOHAND; + } + +-SYSCALL_DEFINE3(32_sigaction, long, sig, const struct sigaction32 __user *, act, +- struct sigaction32 __user *, oact) ++asmlinkage int sys32_sigaction(int sig, const struct sigaction32 __user *act, ++ struct sigaction32 __user *oact) + { + struct k_sigaction new_ka, old_ka; + int ret; +@@ -704,9 +704,9 @@ + .restart = __NR_O32_restart_syscall + }; + +-SYSCALL_DEFINE4(32_rt_sigaction, int, sig, +- const struct sigaction32 __user *, act, +- struct sigaction32 __user *, oact, unsigned int, sigsetsize) ++asmlinkage int sys32_rt_sigaction(int sig, const struct sigaction32 __user *act, ++ struct sigaction32 __user *oact, ++ unsigned int sigsetsize) + { + struct k_sigaction new_sa, old_sa; + int ret = -EINVAL; +@@ -748,8 +748,8 @@ + return ret; + } + +-SYSCALL_DEFINE4(32_rt_sigprocmask, int, how, compat_sigset_t __user *, set, +- compat_sigset_t __user *, oset, unsigned int, sigsetsize) ++asmlinkage int sys32_rt_sigprocmask(int how, compat_sigset_t __user *set, ++ compat_sigset_t __user *oset, unsigned int sigsetsize) + { + sigset_t old_set, new_set; + int ret; +@@ -770,8 +770,8 @@ + return ret; + } + +-SYSCALL_DEFINE2(32_rt_sigpending, compat_sigset_t __user *, uset, +- unsigned int, sigsetsize) ++asmlinkage int sys32_rt_sigpending(compat_sigset_t __user *uset, ++ unsigned int sigsetsize) + { + int ret; + sigset_t set; +@@ -787,8 +787,7 @@ + return ret; + } + +-SYSCALL_DEFINE3(32_rt_sigqueueinfo, int, pid, int, sig, +- compat_siginfo_t __user *, uinfo) ++asmlinkage int sys32_rt_sigqueueinfo(int pid, int sig, compat_siginfo_t __user *uinfo) + { + siginfo_t info; + int ret; +@@ -803,9 +802,10 @@ + return ret; + } + +-SYSCALL_DEFINE5(32_waitid, int, which, compat_pid_t, pid, +- compat_siginfo_t __user *, uinfo, int, options, +- struct compat_rusage __user *, uru) ++asmlinkage long ++sys32_waitid(int which, compat_pid_t pid, ++ compat_siginfo_t __user *uinfo, int options, ++ struct compat_rusage __user *uru) + { + siginfo_t info; + struct rusage ru; +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/arch/mips/kernel/signal.c linux-2.6.29-rc3.owrt/arch/mips/kernel/signal.c +--- linux-2.6.29.owrt/arch/mips/kernel/signal.c 2009-05-10 22:04:40.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/arch/mips/kernel/signal.c 2009-05-10 23:48:28.000000000 +0200 +@@ -19,7 +19,6 @@ + #include <linux/ptrace.h> + #include <linux/unistd.h> + #include <linux/compiler.h> +-#include <linux/syscalls.h> + #include <linux/uaccess.h> + + #include <asm/abi.h> +@@ -339,8 +338,8 @@ + } + + #ifdef CONFIG_TRAD_SIGNALS +-SYSCALL_DEFINE3(sigaction, int, sig, const struct sigaction __user *, act, +- struct sigaction __user *, oact) ++asmlinkage int sys_sigaction(int sig, const struct sigaction __user *act, ++ struct sigaction __user *oact) + { + struct k_sigaction new_ka, old_ka; + int ret; +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/arch/mips/kernel/syscall.c linux-2.6.29-rc3.owrt/arch/mips/kernel/syscall.c +--- linux-2.6.29.owrt/arch/mips/kernel/syscall.c 2009-05-10 22:04:40.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/arch/mips/kernel/syscall.c 2009-05-10 23:48:28.000000000 +0200 +@@ -152,9 +152,9 @@ + return error; + } + +-SYSCALL_DEFINE6(mips_mmap, unsigned long, addr, unsigned long, len, +- unsigned long, prot, unsigned long, flags, unsigned long, +- fd, off_t, offset) ++asmlinkage unsigned long ++old_mmap(unsigned long addr, unsigned long len, int prot, ++ int flags, int fd, off_t offset) + { + unsigned long result; + +@@ -168,9 +168,9 @@ + return result; + } + +-SYSCALL_DEFINE6(mips_mmap2, unsigned long, addr, unsigned long, len, +- unsigned long, prot, unsigned long, flags, unsigned long, fd, +- unsigned long, pgoff) ++asmlinkage unsigned long ++sys_mmap2(unsigned long addr, unsigned long len, unsigned long prot, ++ unsigned long flags, unsigned long fd, unsigned long pgoff) + { + if (pgoff & (~PAGE_MASK >> 12)) + return -EINVAL; +@@ -240,7 +240,7 @@ + /* + * Compacrapability ... + */ +-SYSCALL_DEFINE1(uname, struct old_utsname __user *, name) ++asmlinkage int sys_uname(struct old_utsname __user * name) + { + if (name && !copy_to_user(name, utsname(), sizeof (*name))) + return 0; +@@ -250,7 +250,7 @@ + /* + * Compacrapability ... + */ +-SYSCALL_DEFINE1(olduname, struct oldold_utsname __user *, name) ++asmlinkage int sys_olduname(struct oldold_utsname __user * name) + { + int error; + +@@ -279,7 +279,7 @@ + return error; + } + +-SYSCALL_DEFINE1(set_thread_area, unsigned long, addr) ++asmlinkage int sys_set_thread_area(unsigned long addr) + { + struct thread_info *ti = task_thread_info(current); + +@@ -290,7 +290,7 @@ + return 0; + } + +-asmlinkage int _sys_sysmips(long cmd, long arg1, long arg2, long arg3) ++asmlinkage int _sys_sysmips(int cmd, long arg1, int arg2, int arg3) + { + switch (cmd) { + case MIPS_ATOMIC_SET: +@@ -325,8 +325,8 @@ + * + * This is really horribly ugly. + */ +-SYSCALL_DEFINE6(ipc, unsigned int, call, int, first, int, second, +- unsigned long, third, void __user *, ptr, long, fifth) ++asmlinkage int sys_ipc(unsigned int call, int first, int second, ++ unsigned long third, void __user *ptr, long fifth) + { + int version, ret; + +@@ -411,7 +411,7 @@ + /* + * No implemented yet ... + */ +-SYSCALL_DEFINE3(cachectl, char *, addr, int, nbytes, int, op) ++asmlinkage int sys_cachectl(char *addr, int nbytes, int op) + { + return -ENOSYS; + } +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/arch/mips/kernel/traps.c linux-2.6.29-rc3.owrt/arch/mips/kernel/traps.c +--- linux-2.6.29.owrt/arch/mips/kernel/traps.c 2009-05-10 22:04:40.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/arch/mips/kernel/traps.c 2009-05-10 23:48:28.000000000 +0200 +@@ -944,9 +944,6 @@ + force_sig(SIGILL, current); + } + +-/* +- * Called with interrupts disabled. +- */ + asmlinkage void do_watch(struct pt_regs *regs) + { + u32 cause; +@@ -966,12 +963,9 @@ + */ + if (test_tsk_thread_flag(current, TIF_LOAD_WATCH)) { + mips_read_watch_registers(); +- local_irq_enable(); + force_sig(SIGTRAP, current); +- } else { ++ } else + mips_clear_watch_registers(); +- local_irq_enable(); +- } + } + + asmlinkage void do_mcheck(struct pt_regs *regs) +@@ -1588,11 +1582,7 @@ + static char panic_null_cerr[] __cpuinitdata = + "Trying to set NULL cache error exception handler"; + +-/* +- * Install uncached CPU exception handler. +- * This is suitable only for the cache error exception which is the only +- * exception handler that is being run uncached. +- */ ++/* Install uncached CPU exception handler */ + void __cpuinit set_uncached_handler(unsigned long offset, void *addr, + unsigned long size) + { +@@ -1603,7 +1593,7 @@ + unsigned long uncached_ebase = TO_UNCAC(ebase); + #endif + if (cpu_has_mips_r2) +- uncached_ebase += (read_c0_ebase() & 0x3ffff000); ++ ebase += (read_c0_ebase() & 0x3ffff000); + + if (!addr) + panic(panic_null_cerr); +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/arch/mips/lib/memcpy-inatomic.S linux-2.6.29-rc3.owrt/arch/mips/lib/memcpy-inatomic.S +--- linux-2.6.29.owrt/arch/mips/lib/memcpy-inatomic.S 2009-05-10 22:04:40.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/arch/mips/lib/memcpy-inatomic.S 2009-05-10 23:48:28.000000000 +0200 +@@ -21,7 +21,7 @@ + * end of memory on some systems. It's also a seriously bad idea on non + * dma-coherent systems. + */ +-#ifdef CONFIG_DMA_NONCOHERENT ++#if !defined(CONFIG_DMA_COHERENT) || !defined(CONFIG_DMA_IP27) + #undef CONFIG_CPU_HAS_PREFETCH + #endif + #ifdef CONFIG_MIPS_MALTA +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/arch/mips/lib/memcpy.S linux-2.6.29-rc3.owrt/arch/mips/lib/memcpy.S +--- linux-2.6.29.owrt/arch/mips/lib/memcpy.S 2009-05-10 22:04:40.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/arch/mips/lib/memcpy.S 2009-05-10 23:48:28.000000000 +0200 +@@ -21,7 +21,7 @@ + * end of memory on some systems. It's also a seriously bad idea on non + * dma-coherent systems. + */ +-#ifdef CONFIG_DMA_NONCOHERENT ++#if !defined(CONFIG_DMA_COHERENT) || !defined(CONFIG_DMA_IP27) + #undef CONFIG_CPU_HAS_PREFETCH + #endif + #ifdef CONFIG_MIPS_MALTA +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/arch/mips/Makefile linux-2.6.29-rc3.owrt/arch/mips/Makefile +--- linux-2.6.29.owrt/arch/mips/Makefile 2009-05-10 22:04:40.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/arch/mips/Makefile 2009-05-10 23:48:28.000000000 +0200 +@@ -416,7 +416,7 @@ + # + # Common NEC EMMAXXX + # +-core-$(CONFIG_SOC_EMMA2RH) += arch/mips/emma/common/ ++core-$(CONFIG_SOC_EMMA) += arch/mips/emma/common/ + cflags-$(CONFIG_SOC_EMMA2RH) += -I$(srctree)/arch/mips/include/asm/mach-emma2rh + + # +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/arch/mips/mm/cache.c linux-2.6.29-rc3.owrt/arch/mips/mm/cache.c +--- linux-2.6.29.owrt/arch/mips/mm/cache.c 2009-05-10 22:04:40.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/arch/mips/mm/cache.c 2009-05-10 23:48:28.000000000 +0200 +@@ -13,7 +13,6 @@ + #include <linux/linkage.h> + #include <linux/module.h> + #include <linux/sched.h> +-#include <linux/syscalls.h> + #include <linux/mm.h> + + #include <asm/cacheflush.h> +@@ -59,8 +58,8 @@ + * We could optimize the case where the cache argument is not BCACHE but + * that seems very atypical use ... + */ +-SYSCALL_DEFINE3(cacheflush, unsigned long, addr, unsigned long, bytes, +- unsigned int, cache) ++asmlinkage int sys_cacheflush(unsigned long addr, ++ unsigned long bytes, unsigned int cache) + { + if (bytes == 0) + return 0; +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/arch/mips/mm/c-r4k.c linux-2.6.29-rc3.owrt/arch/mips/mm/c-r4k.c +--- linux-2.6.29.owrt/arch/mips/mm/c-r4k.c 2009-05-10 22:04:40.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/arch/mips/mm/c-r4k.c 2009-05-10 23:48:28.000000000 +0200 +@@ -618,35 +618,15 @@ + if (cpu_has_inclusive_pcaches) { + if (size >= scache_size) + r4k_blast_scache(); +- else { +- unsigned long lsize = cpu_scache_line_size(); +- unsigned long almask = ~(lsize - 1); +- +- /* +- * There is no clearly documented alignment requirement +- * for the cache instruction on MIPS processors and +- * some processors, among them the RM5200 and RM7000 +- * QED processors will throw an address error for cache +- * hit ops with insufficient alignment. Solved by +- * aligning the address to cache line size. +- */ +- cache_op(Hit_Writeback_Inv_SD, addr & almask); +- cache_op(Hit_Writeback_Inv_SD, +- (addr + size - 1) & almask); ++ else + blast_inv_scache_range(addr, addr + size); +- } + return; + } + + if (cpu_has_safe_index_cacheops && size >= dcache_size) { + r4k_blast_dcache(); + } else { +- unsigned long lsize = cpu_dcache_line_size(); +- unsigned long almask = ~(lsize - 1); +- + R4600_HIT_CACHEOP_WAR_IMPL; +- cache_op(Hit_Writeback_Inv_D, addr & almask); +- cache_op(Hit_Writeback_Inv_D, (addr + size - 1) & almask); + blast_inv_dcache_range(addr, addr + size); + } + +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/arch/mips/mm/fault.c linux-2.6.29-rc3.owrt/arch/mips/mm/fault.c +--- linux-2.6.29.owrt/arch/mips/mm/fault.c 2009-05-10 22:04:40.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/arch/mips/mm/fault.c 2009-05-10 23:48:28.000000000 +0200 +@@ -97,6 +97,7 @@ + goto bad_area; + } + ++survive: + /* + * If for any reason at all we couldn't handle the fault, + * make sure we exit gracefully rather than endlessly redo +@@ -166,13 +167,21 @@ + field, regs->regs[31]); + die("Oops", regs); + ++/* ++ * We ran out of memory, or some other thing happened to us that made ++ * us unable to handle the page fault gracefully. ++ */ + out_of_memory: +- /* +- * We ran out of memory, call the OOM killer, and return the userspace +- * (which will retry the fault, or kill us if we got oom-killed). +- */ +- pagefault_out_of_memory(); +- return; ++ up_read(&mm->mmap_sem); ++ if (is_global_init(tsk)) { ++ yield(); ++ down_read(&mm->mmap_sem); ++ goto survive; ++ } ++ printk("VM: killing process %s\n", tsk->comm); ++ if (user_mode(regs)) ++ do_group_exit(SIGKILL); ++ goto no_context; + + do_sigbus: + up_read(&mm->mmap_sem); +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/arch/mips/mm/page.c linux-2.6.29-rc3.owrt/arch/mips/mm/page.c +--- linux-2.6.29.owrt/arch/mips/mm/page.c 2009-05-10 22:04:40.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/arch/mips/mm/page.c 2009-05-10 23:48:28.000000000 +0200 +@@ -172,9 +172,8 @@ + */ + cache_line_size = cpu_dcache_line_size(); + switch (current_cpu_type()) { +- case CPU_R5500: + case CPU_TX49XX: +- /* These processors only support the Pref_Load. */ ++ /* TX49 supports only Pref_Load */ + pref_bias_copy_load = 256; + break; + +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/arch/mips/mm/tlbex.c linux-2.6.29-rc3.owrt/arch/mips/mm/tlbex.c +--- linux-2.6.29.owrt/arch/mips/mm/tlbex.c 2009-05-10 22:04:40.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/arch/mips/mm/tlbex.c 2009-05-10 23:48:28.000000000 +0200 +@@ -318,7 +318,6 @@ + case CPU_BCM4710: + case CPU_LOONGSON2: + case CPU_CAVIUM_OCTEON: +- case CPU_R5500: + if (m4kc_tlbp_war()) + uasm_i_nop(p); + tlbw(p); +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/arch/mips/pci/pci-rc32434.c linux-2.6.29-rc3.owrt/arch/mips/pci/pci-rc32434.c +--- linux-2.6.29.owrt/arch/mips/pci/pci-rc32434.c 2009-05-10 22:04:40.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/arch/mips/pci/pci-rc32434.c 2009-05-10 23:48:28.000000000 +0200 +@@ -205,8 +205,6 @@ + + static int __init rc32434_pci_init(void) + { +- void __iomem *io_map_base; +- + pr_info("PCI: Initializing PCI\n"); + + ioport_resource.start = rc32434_res_pci_io1.start; +@@ -214,15 +212,6 @@ + + rc32434_pcibridge_init(); + +- io_map_base = ioremap(rc32434_res_pci_io1.start, +- rc32434_res_pci_io1.end - rc32434_res_pci_io1.start + 1); +- +- if (!io_map_base) +- return -ENOMEM; +- +- rc32434_controller.io_map_base = +- (unsigned long)io_map_base - rc32434_res_pci_io1.start; +- + register_pci_controller(&rc32434_controller); + rc32434_sync(); + +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/arch/mips/rb532/devices.c linux-2.6.29-rc3.owrt/arch/mips/rb532/devices.c +--- linux-2.6.29.owrt/arch/mips/rb532/devices.c 2009-05-10 22:04:40.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/arch/mips/rb532/devices.c 2009-05-10 23:48:28.000000000 +0200 +@@ -24,7 +24,6 @@ + #include <linux/mtd/partitions.h> + #include <linux/gpio_keys.h> + #include <linux/input.h> +-#include <linux/serial_8250.h> + + #include <asm/bootinfo.h> + +@@ -40,29 +39,6 @@ + #define ETH0_RX_DMA_ADDR (DMA0_BASE_ADDR + 0 * DMA_CHAN_OFFSET) + #define ETH0_TX_DMA_ADDR (DMA0_BASE_ADDR + 1 * DMA_CHAN_OFFSET) + +-extern unsigned int idt_cpu_freq; +- +-static struct mpmc_device dev3; +- +-void set_latch_u5(unsigned char or_mask, unsigned char nand_mask) +-{ +- unsigned long flags; +- +- spin_lock_irqsave(&dev3.lock, flags); +- +- dev3.state = (dev3.state | or_mask) & ~nand_mask; +- writeb(dev3.state, dev3.base); +- +- spin_unlock_irqrestore(&dev3.lock, flags); +-} +-EXPORT_SYMBOL(set_latch_u5); +- +-unsigned char get_latch_u5(void) +-{ +- return dev3.state; +-} +-EXPORT_SYMBOL(get_latch_u5); +- + static struct resource korina_dev0_res[] = { + { + .name = "korina_regs", +@@ -110,7 +86,7 @@ + static struct platform_device korina_dev0 = { + .id = -1, + .name = "korina", +- .dev.driver_data = &korina_dev0_data, ++ .dev.platform_data = &korina_dev0_data, + .resource = korina_dev0_res, + .num_resources = ARRAY_SIZE(korina_dev0_res), + }; +@@ -238,32 +214,12 @@ + .num_resources = ARRAY_SIZE(rb532_wdt_res), + }; + +-static struct plat_serial8250_port rb532_uart_res[] = { +- { +- .membase = (char *)KSEG1ADDR(REGBASE + UART0BASE), +- .irq = UART0_IRQ, +- .regshift = 2, +- .iotype = UPIO_MEM, +- .flags = UPF_BOOT_AUTOCONF, +- }, +- { +- .flags = 0, +- } +-}; +- +-static struct platform_device rb532_uart = { +- .name = "serial8250", +- .id = PLAT8250_DEV_PLATFORM, +- .dev.platform_data = &rb532_uart_res, +-}; +- + static struct platform_device *rb532_devs[] = { + &korina_dev0, + &nand_slot0, + &cf_slot0, + &rb532_led, + &rb532_button, +- &rb532_uart, + &rb532_wdt + }; + +@@ -335,20 +291,9 @@ + nand_slot0_res[0].start = readl(IDT434_REG_BASE + DEV2BASE); + nand_slot0_res[0].end = nand_slot0_res[0].start + 0x1000; + +- /* Read and map device controller 3 */ +- dev3.base = ioremap_nocache(readl(IDT434_REG_BASE + DEV3BASE), 1); +- +- if (!dev3.base) { +- printk(KERN_ERR "rb532: cannot remap device controller 3\n"); +- return -ENXIO; +- } +- + /* Initialise the NAND device */ + rb532_nand_setup(); + +- /* set the uart clock to the current cpu frequency */ +- rb532_uart_res[0].uartclk = idt_cpu_freq; +- + return platform_add_devices(rb532_devs, ARRAY_SIZE(rb532_devs)); + } + +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/arch/mips/rb532/gpio.c linux-2.6.29-rc3.owrt/arch/mips/rb532/gpio.c +--- linux-2.6.29.owrt/arch/mips/rb532/gpio.c 2009-05-10 22:04:40.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/arch/mips/rb532/gpio.c 2009-05-10 23:48:28.000000000 +0200 +@@ -41,6 +41,8 @@ + void __iomem *regbase; + }; + ++struct mpmc_device dev3; ++ + static struct resource rb532_gpio_reg0_res[] = { + { + .name = "gpio_reg0", +@@ -50,6 +52,61 @@ + } + }; + ++static struct resource rb532_dev3_ctl_res[] = { ++ { ++ .name = "dev3_ctl", ++ .start = REGBASE + DEV3BASE, ++ .end = REGBASE + DEV3BASE + sizeof(struct dev_reg) - 1, ++ .flags = IORESOURCE_MEM, ++ } ++}; ++ ++void set_434_reg(unsigned reg_offs, unsigned bit, unsigned len, unsigned val) ++{ ++ unsigned long flags; ++ unsigned data; ++ unsigned i = 0; ++ ++ spin_lock_irqsave(&dev3.lock, flags); ++ ++ data = readl(IDT434_REG_BASE + reg_offs); ++ for (i = 0; i != len; ++i) { ++ if (val & (1 << i)) ++ data |= (1 << (i + bit)); ++ else ++ data &= ~(1 << (i + bit)); ++ } ++ writel(data, (IDT434_REG_BASE + reg_offs)); ++ ++ spin_unlock_irqrestore(&dev3.lock, flags); ++} ++EXPORT_SYMBOL(set_434_reg); ++ ++unsigned get_434_reg(unsigned reg_offs) ++{ ++ return readl(IDT434_REG_BASE + reg_offs); ++} ++EXPORT_SYMBOL(get_434_reg); ++ ++void set_latch_u5(unsigned char or_mask, unsigned char nand_mask) ++{ ++ unsigned long flags; ++ ++ spin_lock_irqsave(&dev3.lock, flags); ++ ++ dev3.state = (dev3.state | or_mask) & ~nand_mask; ++ writel(dev3.state, &dev3.base); ++ ++ spin_unlock_irqrestore(&dev3.lock, flags); ++} ++EXPORT_SYMBOL(set_latch_u5); ++ ++unsigned char get_latch_u5(void) ++{ ++ return dev3.state; ++} ++EXPORT_SYMBOL(get_latch_u5); ++ + /* rb532_set_bit - sanely set a bit + * + * bitval: new value for the bit +@@ -62,11 +119,13 @@ + unsigned long flags; + u32 val; + ++ bitval = !!bitval; /* map parameter to {0,1} */ ++ + local_irq_save(flags); + + val = readl(ioaddr); +- val &= ~(!bitval << offset); /* unset bit if bitval == 0 */ +- val |= (!!bitval << offset); /* set bit if bitval == 1 */ ++ val &= ~( ~bitval << offset ); /* unset bit if bitval == 0 */ ++ val |= ( bitval << offset ); /* set bit if bitval == 1 */ + writel(val, ioaddr); + + local_irq_restore(flags); +@@ -112,8 +171,8 @@ + + gpch = container_of(chip, struct rb532_gpio_chip, chip); + +- /* disable alternate function in case it's set */ +- rb532_set_bit(0, offset, gpch->regbase + GPIOFUNC); ++ if (rb532_get_bit(offset, gpch->regbase + GPIOFUNC)) ++ return 1; /* alternate function, GPIOCFG is ignored */ + + rb532_set_bit(0, offset, gpch->regbase + GPIOCFG); + return 0; +@@ -129,8 +188,8 @@ + + gpch = container_of(chip, struct rb532_gpio_chip, chip); + +- /* disable alternate function in case it's set */ +- rb532_set_bit(0, offset, gpch->regbase + GPIOFUNC); ++ if (rb532_get_bit(offset, gpch->regbase + GPIOFUNC)) ++ return 1; /* alternate function, GPIOCFG is ignored */ + + /* set the initial output value */ + rb532_set_bit(value, offset, gpch->regbase + GPIOD); +@@ -174,11 +233,10 @@ + /* + * Configure GPIO alternate function + */ +-void rb532_gpio_set_func(unsigned gpio) ++static void rb532_gpio_set_func(int bit, unsigned gpio) + { +- rb532_set_bit(1, gpio, rb532_gpio_chip->regbase + GPIOFUNC); ++ rb532_set_bit(bit, gpio, rb532_gpio_chip->regbase + GPIOFUNC); + } +-EXPORT_SYMBOL(rb532_gpio_set_func); + + int __init rb532_gpio_init(void) + { +@@ -195,6 +253,20 @@ + /* Register our GPIO chip */ + gpiochip_add(&rb532_gpio_chip->chip); + ++ r = rb532_dev3_ctl_res; ++ dev3.base = ioremap_nocache(r->start, r->end - r->start); ++ ++ if (!dev3.base) { ++ printk(KERN_ERR "rb532: cannot remap device controller 3\n"); ++ return -ENXIO; ++ } ++ ++ /* configure CF_GPIO_NUM as CFRDY IRQ source */ ++ rb532_gpio_set_func(0, CF_GPIO_NUM); ++ rb532_gpio_direction_input(&rb532_gpio_chip->chip, CF_GPIO_NUM); ++ rb532_gpio_set_ilevel(1, CF_GPIO_NUM); ++ rb532_gpio_set_istat(0, CF_GPIO_NUM); ++ + return 0; + } + arch_initcall(rb532_gpio_init); +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/arch/mips/rb532/irq.c linux-2.6.29-rc3.owrt/arch/mips/rb532/irq.c +--- linux-2.6.29.owrt/arch/mips/rb532/irq.c 2009-05-10 22:04:40.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/arch/mips/rb532/irq.c 2009-05-10 23:48:28.000000000 +0200 +@@ -46,7 +46,6 @@ + #include <asm/system.h> + + #include <asm/mach-rc32434/irq.h> +-#include <asm/mach-rc32434/gpio.h> + + struct intr_group { + u32 mask; /* mask of valid bits in pending/mask registers */ +@@ -151,9 +150,6 @@ + mask |= intr_bit; + WRITE_MASK(addr, mask); + +- if (group == GPIO_MAPPED_IRQ_GROUP) +- rb532_gpio_set_istat(0, irq_nr - GPIO_MAPPED_IRQ_BASE); +- + /* + * if there are no more interrupts enabled in this + * group, disable corresponding IP +@@ -169,35 +165,12 @@ + ack_local_irq(group_to_ip(irq_to_group(irq_nr))); + } + +-static int rb532_set_type(unsigned int irq_nr, unsigned type) +-{ +- int gpio = irq_nr - GPIO_MAPPED_IRQ_BASE; +- int group = irq_to_group(irq_nr); +- +- if (group != GPIO_MAPPED_IRQ_GROUP) +- return (type == IRQ_TYPE_LEVEL_HIGH) ? 0 : -EINVAL; +- +- switch (type) { +- case IRQ_TYPE_LEVEL_HIGH: +- rb532_gpio_set_ilevel(1, gpio); +- break; +- case IRQ_TYPE_LEVEL_LOW: +- rb532_gpio_set_ilevel(0, gpio); +- break; +- default: +- return -EINVAL; +- } +- +- return 0; +-} +- + static struct irq_chip rc32434_irq_type = { + .name = "RB532", + .ack = rb532_disable_irq, + .mask = rb532_disable_irq, + .mask_ack = rb532_mask_and_ack_irq, + .unmask = rb532_enable_irq, +- .set_type = rb532_set_type, + }; + + void __init arch_init_irq(void) +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/arch/mips/rb532/serial.c linux-2.6.29-rc3.owrt/arch/mips/rb532/serial.c +--- linux-2.6.29.owrt/arch/mips/rb532/serial.c 2009-05-10 22:04:40.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/arch/mips/rb532/serial.c 2009-05-10 23:48:28.000000000 +0200 +@@ -36,7 +36,7 @@ + extern unsigned int idt_cpu_freq; + + static struct uart_port rb532_uart = { +- .flags = UPF_BOOT_AUTOCONF, ++ .type = PORT_16550A, + .line = 0, + .irq = UART0_IRQ, + .iotype = UPIO_MEM, +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/arch/mips/txx9/generic/setup_tx4939.c linux-2.6.29-rc3.owrt/arch/mips/txx9/generic/setup_tx4939.c +--- linux-2.6.29.owrt/arch/mips/txx9/generic/setup_tx4939.c 2009-05-10 22:04:40.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/arch/mips/txx9/generic/setup_tx4939.c 2009-05-10 23:48:28.000000000 +0200 +@@ -435,28 +435,6 @@ + platform_device_register(&ata1_dev); + } + +-void __init tx4939_rtc_init(void) +-{ +- static struct resource res[] = { +- { +- .start = TX4939_RTC_REG & 0xfffffffffULL, +- .end = (TX4939_RTC_REG & 0xfffffffffULL) + 0x100 - 1, +- .flags = IORESOURCE_MEM, +- }, { +- .start = TXX9_IRQ_BASE + TX4939_IR_RTC, +- .flags = IORESOURCE_IRQ, +- }, +- }; +- static struct platform_device rtc_dev = { +- .name = "tx4939rtc", +- .id = -1, +- .num_resources = ARRAY_SIZE(res), +- .resource = res, +- }; +- +- platform_device_register(&rtc_dev); +-} +- + static void __init tx4939_stop_unused_modules(void) + { + __u64 pcfg, rst = 0, ckd = 0; +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/arch/mips/txx9/rbtx4939/setup.c linux-2.6.29-rc3.owrt/arch/mips/txx9/rbtx4939/setup.c +--- linux-2.6.29.owrt/arch/mips/txx9/rbtx4939/setup.c 2009-05-10 22:04:40.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/arch/mips/txx9/rbtx4939/setup.c 2009-05-10 23:48:28.000000000 +0200 +@@ -336,7 +336,6 @@ + rbtx4939_led_setup(); + tx4939_wdt_init(); + tx4939_ata_init(); +- tx4939_rtc_init(); + } + + static void __init rbtx4939_setup(void) +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/arch/mn10300/Kconfig linux-2.6.29-rc3.owrt/arch/mn10300/Kconfig +--- linux-2.6.29.owrt/arch/mn10300/Kconfig 2009-05-10 22:04:41.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/arch/mn10300/Kconfig 2009-05-10 23:48:28.000000000 +0200 +@@ -7,7 +7,6 @@ + + config MN10300 + def_bool y +- select HAVE_OPROFILE + + config AM33 + def_bool y +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/arch/mn10300/unit-asb2305/pci.c linux-2.6.29-rc3.owrt/arch/mn10300/unit-asb2305/pci.c +--- linux-2.6.29.owrt/arch/mn10300/unit-asb2305/pci.c 2009-05-10 22:04:41.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/arch/mn10300/unit-asb2305/pci.c 2009-05-10 23:48:28.000000000 +0200 +@@ -173,7 +173,7 @@ + BRIDGEREGB(where) = value; + } else { + if (bus->number == 0 && +- (devfn == PCI_DEVFN(2, 0) || devfn == PCI_DEVFN(3, 0)) ++ (devfn == PCI_DEVFN(2, 0) && devfn == PCI_DEVFN(3, 0)) + ) + __pcidebug("<= %02x", bus, devfn, where, value); + CONFIG_ADDRESS = CONFIG_CMD(bus, devfn, where); +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/arch/parisc/configs/712_defconfig linux-2.6.29-rc3.owrt/arch/parisc/configs/712_defconfig +--- linux-2.6.29.owrt/arch/parisc/configs/712_defconfig 2009-05-10 22:04:39.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/arch/parisc/configs/712_defconfig 2009-05-10 23:48:28.000000000 +0200 +@@ -1,7 +1,7 @@ + # + # Automatically generated make config: don't edit +-# Linux kernel version: 2.6.29-rc8 +-# Fri Mar 13 01:32:55 2009 ++# Linux kernel version: 2.6.23 ++# Fri Oct 12 21:00:07 2007 + # + CONFIG_PARISC=y + CONFIG_MMU=y +@@ -33,35 +33,17 @@ + CONFIG_POSIX_MQUEUE=y + # CONFIG_BSD_PROCESS_ACCT is not set + # CONFIG_TASKSTATS is not set ++# CONFIG_USER_NS is not set + # CONFIG_AUDIT is not set +- +-# +-# RCU Subsystem +-# +-CONFIG_CLASSIC_RCU=y +-# CONFIG_TREE_RCU is not set +-# CONFIG_PREEMPT_RCU is not set +-# CONFIG_TREE_RCU_TRACE is not set +-# CONFIG_PREEMPT_RCU_TRACE is not set + CONFIG_IKCONFIG=y + CONFIG_IKCONFIG_PROC=y + CONFIG_LOG_BUF_SHIFT=16 +-# CONFIG_GROUP_SCHED is not set +-# CONFIG_CGROUPS is not set + CONFIG_SYSFS_DEPRECATED=y +-CONFIG_SYSFS_DEPRECATED_V2=y + # CONFIG_RELAY is not set +-CONFIG_NAMESPACES=y +-# CONFIG_UTS_NS is not set +-# CONFIG_IPC_NS is not set +-# CONFIG_USER_NS is not set +-# CONFIG_PID_NS is not set +-# CONFIG_NET_NS is not set + CONFIG_BLK_DEV_INITRD=y + CONFIG_INITRAMFS_SOURCE="" + CONFIG_CC_OPTIMIZE_FOR_SIZE=y + CONFIG_SYSCTL=y +-CONFIG_ANON_INODES=y + # CONFIG_EMBEDDED is not set + CONFIG_SYSCTL_SYSCALL=y + CONFIG_KALLSYMS=y +@@ -73,38 +55,29 @@ + CONFIG_ELF_CORE=y + CONFIG_BASE_FULL=y + CONFIG_FUTEX=y ++CONFIG_ANON_INODES=y + CONFIG_EPOLL=y + CONFIG_SIGNALFD=y +-CONFIG_TIMERFD=y + CONFIG_EVENTFD=y + CONFIG_SHMEM=y +-CONFIG_AIO=y + CONFIG_VM_EVENT_COUNTERS=y +-CONFIG_COMPAT_BRK=y + CONFIG_SLAB=y + # CONFIG_SLUB is not set + # CONFIG_SLOB is not set +-CONFIG_PROFILING=y +-CONFIG_TRACEPOINTS=y +-# CONFIG_MARKERS is not set +-CONFIG_OPROFILE=m +-CONFIG_HAVE_OPROFILE=y +-# CONFIG_HAVE_GENERIC_DMA_COHERENT is not set +-CONFIG_SLABINFO=y + CONFIG_RT_MUTEXES=y ++# CONFIG_TINY_SHMEM is not set + CONFIG_BASE_SMALL=0 + CONFIG_MODULES=y +-# CONFIG_MODULE_FORCE_LOAD is not set + CONFIG_MODULE_UNLOAD=y + CONFIG_MODULE_FORCE_UNLOAD=y + # CONFIG_MODVERSIONS is not set + # CONFIG_MODULE_SRCVERSION_ALL is not set +-CONFIG_INIT_ALL_POSSIBLE=y ++CONFIG_KMOD=y + CONFIG_BLOCK=y + # CONFIG_LBD is not set + # CONFIG_BLK_DEV_IO_TRACE is not set ++# CONFIG_LSF is not set + # CONFIG_BLK_DEV_BSG is not set +-# CONFIG_BLK_DEV_INTEGRITY is not set + + # + # IO Schedulers +@@ -118,7 +91,6 @@ + # CONFIG_DEFAULT_CFQ is not set + # CONFIG_DEFAULT_NOOP is not set + CONFIG_DEFAULT_IOSCHED="anticipatory" +-# CONFIG_FREEZER is not set + + # + # Processor type and features +@@ -142,19 +114,17 @@ + # CONFIG_HZ_300 is not set + # CONFIG_HZ_1000 is not set + CONFIG_HZ=250 +-# CONFIG_SCHED_HRTICK is not set + CONFIG_SELECT_MEMORY_MODEL=y + CONFIG_FLATMEM_MANUAL=y + # CONFIG_DISCONTIGMEM_MANUAL is not set + # CONFIG_SPARSEMEM_MANUAL is not set + CONFIG_FLATMEM=y + CONFIG_FLAT_NODE_MEM_MAP=y +-CONFIG_PAGEFLAGS_EXTENDED=y ++# CONFIG_SPARSEMEM_STATIC is not set + CONFIG_SPLIT_PTLOCK_CPUS=4096 +-# CONFIG_PHYS_ADDR_T_64BIT is not set ++# CONFIG_RESOURCES_64BIT is not set + CONFIG_ZONE_DMA_FLAG=0 + CONFIG_VIRT_TO_BUS=y +-CONFIG_UNEVICTABLE_LRU=y + # CONFIG_HPUX is not set + + # +@@ -168,6 +138,10 @@ + # CONFIG_EISA is not set + # CONFIG_PCI is not set + # CONFIG_ARCH_SUPPORTS_MSI is not set ++ ++# ++# PCCARD (PCMCIA/CardBus) support ++# + # CONFIG_PCCARD is not set + + # +@@ -182,15 +156,16 @@ + # Executable file formats + # + CONFIG_BINFMT_ELF=y +-# CONFIG_CORE_DUMP_DEFAULT_ELF_HEADERS is not set +-# CONFIG_HAVE_AOUT is not set + CONFIG_BINFMT_MISC=m ++ ++# ++# Networking ++# + CONFIG_NET=y + + # + # Networking options + # +-CONFIG_COMPAT_NET_DEV_OPS=y + CONFIG_PACKET=y + CONFIG_PACKET_MMAP=y + CONFIG_UNIX=y +@@ -198,7 +173,6 @@ + CONFIG_XFRM_USER=m + # CONFIG_XFRM_SUB_POLICY is not set + # CONFIG_XFRM_MIGRATE is not set +-# CONFIG_XFRM_STATISTICS is not set + CONFIG_NET_KEY=m + # CONFIG_NET_KEY_MIGRATE is not set + CONFIG_INET=y +@@ -229,25 +203,25 @@ + CONFIG_TCP_CONG_CUBIC=y + CONFIG_DEFAULT_TCP_CONG="cubic" + # CONFIG_TCP_MD5SIG is not set ++# CONFIG_IP_VS is not set + # CONFIG_IPV6 is not set ++# CONFIG_INET6_XFRM_TUNNEL is not set ++# CONFIG_INET6_TUNNEL is not set + # CONFIG_NETWORK_SECMARK is not set + CONFIG_NETFILTER=y + # CONFIG_NETFILTER_DEBUG is not set +-CONFIG_NETFILTER_ADVANCED=y + + # + # Core Netfilter Configuration + # +-# CONFIG_NETFILTER_NETLINK_QUEUE is not set +-# CONFIG_NETFILTER_NETLINK_LOG is not set ++# CONFIG_NETFILTER_NETLINK is not set ++# CONFIG_NF_CONNTRACK_ENABLED is not set + # CONFIG_NF_CONNTRACK is not set + # CONFIG_NETFILTER_XTABLES is not set +-# CONFIG_IP_VS is not set + + # + # IP: Netfilter Configuration + # +-# CONFIG_NF_DEFRAG_IPV4 is not set + CONFIG_IP_NF_QUEUE=m + # CONFIG_IP_NF_IPTABLES is not set + # CONFIG_IP_NF_ARPTABLES is not set +@@ -256,7 +230,6 @@ + # CONFIG_TIPC is not set + # CONFIG_ATM is not set + # CONFIG_BRIDGE is not set +-# CONFIG_NET_DSA is not set + # CONFIG_VLAN_8021Q is not set + # CONFIG_DECNET is not set + CONFIG_LLC=m +@@ -267,26 +240,28 @@ + # CONFIG_LAPB is not set + # CONFIG_ECONET is not set + # CONFIG_WAN_ROUTER is not set ++ ++# ++# QoS and/or fair queueing ++# + # CONFIG_NET_SCHED is not set +-# CONFIG_DCB is not set + + # + # Network testing + # + CONFIG_NET_PKTGEN=m + # CONFIG_HAMRADIO is not set +-# CONFIG_CAN is not set + # CONFIG_IRDA is not set + # CONFIG_BT is not set + # CONFIG_AF_RXRPC is not set +-# CONFIG_PHONET is not set +-CONFIG_WIRELESS=y ++ ++# ++# Wireless ++# + # CONFIG_CFG80211 is not set +-CONFIG_WIRELESS_OLD_REGULATORY=y + # CONFIG_WIRELESS_EXT is not set +-# CONFIG_LIB80211 is not set + # CONFIG_MAC80211 is not set +-# CONFIG_WIMAX is not set ++# CONFIG_IEEE80211 is not set + # CONFIG_RFKILL is not set + # CONFIG_NET_9P is not set + +@@ -301,8 +276,6 @@ + # CONFIG_STANDALONE is not set + # CONFIG_PREVENT_FIRMWARE_BUILD is not set + CONFIG_FW_LOADER=y +-CONFIG_FIRMWARE_IN_KERNEL=y +-CONFIG_EXTRA_FIRMWARE="" + # CONFIG_DEBUG_DRIVER is not set + # CONFIG_DEBUG_DEVRES is not set + # CONFIG_SYS_HYPERVISOR is not set +@@ -325,19 +298,11 @@ + CONFIG_BLK_DEV_RAM=y + CONFIG_BLK_DEV_RAM_COUNT=16 + CONFIG_BLK_DEV_RAM_SIZE=6144 +-# CONFIG_BLK_DEV_XIP is not set ++CONFIG_BLK_DEV_RAM_BLOCKSIZE=1024 + # CONFIG_CDROM_PKTCDVD is not set + CONFIG_ATA_OVER_ETH=m +-# CONFIG_BLK_DEV_HD is not set + CONFIG_MISC_DEVICES=y +-# CONFIG_ENCLOSURE_SERVICES is not set +-# CONFIG_C2PORT is not set +- +-# +-# EEPROM support +-# + # CONFIG_EEPROM_93CX6 is not set +-CONFIG_HAVE_IDE=y + # CONFIG_IDE is not set + + # +@@ -377,17 +342,14 @@ + # CONFIG_SCSI_FC_ATTRS is not set + CONFIG_SCSI_ISCSI_ATTRS=m + # CONFIG_SCSI_SAS_LIBSAS is not set +-# CONFIG_SCSI_SRP_ATTRS is not set + CONFIG_SCSI_LOWLEVEL=y + # CONFIG_ISCSI_TCP is not set +-# CONFIG_LIBFC is not set + # CONFIG_SCSI_PPA is not set + # CONFIG_SCSI_IMM is not set + CONFIG_SCSI_LASI700=y + CONFIG_53C700_LE_ON_BE=y + # CONFIG_SCSI_ZALON is not set + CONFIG_SCSI_DEBUG=m +-# CONFIG_SCSI_DH is not set + # CONFIG_ATA is not set + CONFIG_MD=y + CONFIG_BLK_DEV_MD=m +@@ -400,6 +362,7 @@ + # CONFIG_MD_FAULTY is not set + # CONFIG_BLK_DEV_DM is not set + CONFIG_NETDEVICES=y ++# CONFIG_NETDEVICES_MULTIQUEUE is not set + CONFIG_DUMMY=m + CONFIG_BONDING=m + # CONFIG_MACVLAN is not set +@@ -414,9 +377,6 @@ + # CONFIG_IBM_NEW_EMAC_RGMII is not set + # CONFIG_IBM_NEW_EMAC_TAH is not set + # CONFIG_IBM_NEW_EMAC_EMAC4 is not set +-# CONFIG_IBM_NEW_EMAC_NO_FLOW_CTRL is not set +-# CONFIG_IBM_NEW_EMAC_MAL_CLR_ICINTSTAT is not set +-# CONFIG_IBM_NEW_EMAC_MAL_COMMON_ERR is not set + # CONFIG_B44 is not set + # CONFIG_NET_POCKET is not set + CONFIG_NETDEV_1000=y +@@ -427,11 +387,6 @@ + # + # CONFIG_WLAN_PRE80211 is not set + # CONFIG_WLAN_80211 is not set +-# CONFIG_IWLWIFI_LEDS is not set +- +-# +-# Enable WiMAX (Networking options) to see the WiMAX drivers +-# + # CONFIG_WAN is not set + # CONFIG_PLIP is not set + CONFIG_PPP=m +@@ -446,6 +401,7 @@ + # CONFIG_PPPOL2TP is not set + # CONFIG_SLIP is not set + CONFIG_SLHC=m ++# CONFIG_SHAPER is not set + # CONFIG_NETCONSOLE is not set + # CONFIG_NETPOLL is not set + # CONFIG_NET_POLL_CONTROLLER is not set +@@ -467,6 +423,7 @@ + CONFIG_INPUT_MOUSEDEV_SCREEN_X=1024 + CONFIG_INPUT_MOUSEDEV_SCREEN_Y=768 + # CONFIG_INPUT_JOYDEV is not set ++# CONFIG_INPUT_TSDEV is not set + # CONFIG_INPUT_EVDEV is not set + # CONFIG_INPUT_EVBUG is not set + +@@ -489,8 +446,8 @@ + CONFIG_MOUSE_PS2_ALPS=y + CONFIG_MOUSE_PS2_LOGIPS2PP=y + CONFIG_MOUSE_PS2_SYNAPTICS=y ++CONFIG_MOUSE_PS2_LIFEBOOK=y + CONFIG_MOUSE_PS2_TRACKPOINT=y +-# CONFIG_MOUSE_PS2_ELANTECH is not set + # CONFIG_MOUSE_PS2_TOUCHKIT is not set + CONFIG_MOUSE_SERIAL=m + # CONFIG_MOUSE_VSXXXAA is not set +@@ -517,11 +474,9 @@ + # Character devices + # + CONFIG_VT=y +-CONFIG_CONSOLE_TRANSLATIONS=y + CONFIG_VT_CONSOLE=y + CONFIG_HW_CONSOLE=y + # CONFIG_VT_HW_CONSOLE_BINDING is not set +-CONFIG_DEVKMEM=y + # CONFIG_SERIAL_NONSTANDARD is not set + + # +@@ -546,76 +501,72 @@ + CONFIG_SERIAL_CORE=y + CONFIG_SERIAL_CORE_CONSOLE=y + CONFIG_UNIX98_PTYS=y +-# CONFIG_DEVPTS_MULTIPLE_INSTANCES is not set + CONFIG_LEGACY_PTYS=y + CONFIG_LEGACY_PTY_COUNT=64 + CONFIG_PRINTER=m + # CONFIG_LP_CONSOLE is not set + CONFIG_PPDEV=m ++# CONFIG_TIPAR is not set + # CONFIG_IPMI_HANDLER is not set ++# CONFIG_WATCHDOG is not set + # CONFIG_HW_RANDOM is not set ++CONFIG_GEN_RTC=y ++CONFIG_GEN_RTC_X=y + # CONFIG_R3964 is not set + CONFIG_RAW_DRIVER=y + CONFIG_MAX_RAW_DEVS=256 + # CONFIG_TCG_TPM is not set + # CONFIG_I2C is not set ++ ++# ++# SPI support ++# + # CONFIG_SPI is not set ++# CONFIG_SPI_MASTER is not set + # CONFIG_W1 is not set + # CONFIG_POWER_SUPPLY is not set + # CONFIG_HWMON is not set +-# CONFIG_THERMAL is not set +-# CONFIG_THERMAL_HWMON is not set +-# CONFIG_WATCHDOG is not set +-CONFIG_SSB_POSSIBLE=y + + # + # Sonics Silicon Backplane + # ++CONFIG_SSB_POSSIBLE=y + # CONFIG_SSB is not set + + # + # Multifunction device drivers + # +-# CONFIG_MFD_CORE is not set + # CONFIG_MFD_SM501 is not set +-# CONFIG_HTC_PASIC3 is not set +-# CONFIG_MFD_TMIO is not set +-# CONFIG_REGULATOR is not set + + # + # Multimedia devices + # +- +-# +-# Multimedia core support +-# + # CONFIG_VIDEO_DEV is not set + # CONFIG_DVB_CORE is not set +-# CONFIG_VIDEO_MEDIA is not set ++# CONFIG_DAB is not set + + # +-# Multimedia drivers ++# Graphics support + # +-# CONFIG_DAB is not set ++# CONFIG_BACKLIGHT_LCD_SUPPORT is not set + + # +-# Graphics support ++# Display device support + # ++# CONFIG_DISPLAY_SUPPORT is not set + # CONFIG_VGASTATE is not set + CONFIG_VIDEO_OUTPUT_CONTROL=m + CONFIG_FB=y + # CONFIG_FIRMWARE_EDID is not set + # CONFIG_FB_DDC is not set +-# CONFIG_FB_BOOT_VESA_SUPPORT is not set + CONFIG_FB_CFB_FILLRECT=y + CONFIG_FB_CFB_COPYAREA=y + CONFIG_FB_CFB_IMAGEBLIT=y +-# CONFIG_FB_CFB_REV_PIXELS_IN_BYTE is not set + # CONFIG_FB_SYS_FILLRECT is not set + # CONFIG_FB_SYS_COPYAREA is not set + # CONFIG_FB_SYS_IMAGEBLIT is not set +-# CONFIG_FB_FOREIGN_ENDIAN is not set + # CONFIG_FB_SYS_FOPS is not set ++CONFIG_FB_DEFERRED_IO=y + # CONFIG_FB_SVGALIB is not set + # CONFIG_FB_MACMODES is not set + # CONFIG_FB_BACKLIGHT is not set +@@ -628,14 +579,6 @@ + CONFIG_FB_STI=y + # CONFIG_FB_S1D13XXX is not set + # CONFIG_FB_VIRTUAL is not set +-# CONFIG_FB_METRONOME is not set +-# CONFIG_FB_MB862XX is not set +-# CONFIG_BACKLIGHT_LCD_SUPPORT is not set +- +-# +-# Display device support +-# +-# CONFIG_DISPLAY_SUPPORT is not set + + # + # Console display driver support +@@ -663,8 +606,15 @@ + # CONFIG_LOGO_LINUX_VGA16 is not set + # CONFIG_LOGO_LINUX_CLUT224 is not set + CONFIG_LOGO_PARISC_CLUT224=y ++ ++# ++# Sound ++# + CONFIG_SOUND=y +-CONFIG_SOUND_OSS_CORE=y ++ ++# ++# Advanced Linux Sound Architecture ++# + CONFIG_SND=y + CONFIG_SND_TIMER=y + CONFIG_SND_PCM=y +@@ -680,7 +630,10 @@ + CONFIG_SND_VERBOSE_PROCFS=y + # CONFIG_SND_VERBOSE_PRINTK is not set + # CONFIG_SND_DEBUG is not set +-CONFIG_SND_DRIVERS=y ++ ++# ++# Generic devices ++# + # CONFIG_SND_DUMMY is not set + # CONFIG_SND_VIRMIDI is not set + # CONFIG_SND_MTPAV is not set +@@ -688,82 +641,63 @@ + # CONFIG_SND_SERIAL_U16550 is not set + # CONFIG_SND_MPU401 is not set + # CONFIG_SND_PORTMAN2X4 is not set +-CONFIG_SND_GSC=y ++ ++# ++# GSC devices ++# + CONFIG_SND_HARMONY=y ++ ++# ++# System on Chip audio support ++# + # CONFIG_SND_SOC is not set ++ ++# ++# SoC Audio support for SuperH ++# ++ ++# ++# Open Sound System ++# + # CONFIG_SOUND_PRIME is not set + CONFIG_HID_SUPPORT=y + CONFIG_HID=y + CONFIG_HID_DEBUG=y +-# CONFIG_HIDRAW is not set +-# CONFIG_HID_PID is not set +- +-# +-# Special HID drivers +-# +-CONFIG_HID_COMPAT=y + CONFIG_USB_SUPPORT=y + # CONFIG_USB_ARCH_HAS_HCD is not set + # CONFIG_USB_ARCH_HAS_OHCI is not set + # CONFIG_USB_ARCH_HAS_EHCI is not set + + # +-# Enable Host or Gadget support to see Inventra options ++# NOTE: USB_STORAGE enables SCSI, and 'SCSI disk support' + # + + # +-# NOTE: USB_STORAGE depends on SCSI but BLK_DEV_SD may also be needed; ++# USB Gadget Support + # + # CONFIG_USB_GADGET is not set +- +-# +-# OTG and related infrastructure +-# + # CONFIG_MMC is not set +-# CONFIG_MEMSTICK is not set + # CONFIG_NEW_LEDS is not set +-# CONFIG_ACCESSIBILITY is not set +-CONFIG_RTC_LIB=y +-CONFIG_RTC_CLASS=y +-CONFIG_RTC_HCTOSYS=y +-CONFIG_RTC_HCTOSYS_DEVICE="rtc0" +-# CONFIG_RTC_DEBUG is not set ++# CONFIG_RTC_CLASS is not set + + # +-# RTC interfaces ++# DMA Engine support + # +-CONFIG_RTC_INTF_SYSFS=y +-CONFIG_RTC_INTF_PROC=y +-CONFIG_RTC_INTF_DEV=y +-# CONFIG_RTC_INTF_DEV_UIE_EMUL is not set +-# CONFIG_RTC_DRV_TEST is not set ++# CONFIG_DMA_ENGINE is not set + + # +-# SPI RTC drivers ++# DMA Clients + # + + # +-# Platform RTC drivers ++# DMA Devices + # +-# CONFIG_RTC_DRV_DS1286 is not set +-# CONFIG_RTC_DRV_DS1511 is not set +-# CONFIG_RTC_DRV_DS1553 is not set +-# CONFIG_RTC_DRV_DS1742 is not set +-# CONFIG_RTC_DRV_STK17TA8 is not set +-# CONFIG_RTC_DRV_M48T86 is not set +-# CONFIG_RTC_DRV_M48T35 is not set +-# CONFIG_RTC_DRV_M48T59 is not set +-# CONFIG_RTC_DRV_BQ4802 is not set +-# CONFIG_RTC_DRV_V3020 is not set ++# CONFIG_AUXDISPLAY is not set + + # +-# on-CPU RTC drivers ++# Userspace I/O + # +-CONFIG_RTC_DRV_PARISC=y +-# CONFIG_DMADEVICES is not set +-# CONFIG_AUXDISPLAY is not set + # CONFIG_UIO is not set +-# CONFIG_STAGING is not set + + # + # File systems +@@ -773,7 +707,7 @@ + # CONFIG_EXT2_FS_XIP is not set + CONFIG_EXT3_FS=y + # CONFIG_EXT3_FS_XATTR is not set +-# CONFIG_EXT4_FS is not set ++# CONFIG_EXT4DEV_FS is not set + CONFIG_JBD=y + # CONFIG_JBD_DEBUG is not set + # CONFIG_REISERFS_FS is not set +@@ -783,18 +717,19 @@ + # CONFIG_JFS_DEBUG is not set + # CONFIG_JFS_STATISTICS is not set + CONFIG_FS_POSIX_ACL=y +-CONFIG_FILE_LOCKING=y + CONFIG_XFS_FS=m + # CONFIG_XFS_QUOTA is not set ++# CONFIG_XFS_SECURITY is not set + # CONFIG_XFS_POSIX_ACL is not set + # CONFIG_XFS_RT is not set +-# CONFIG_XFS_DEBUG is not set ++# CONFIG_GFS2_FS is not set + # CONFIG_OCFS2_FS is not set +-# CONFIG_BTRFS_FS is not set +-CONFIG_DNOTIFY=y ++# CONFIG_MINIX_FS is not set ++# CONFIG_ROMFS_FS is not set + CONFIG_INOTIFY=y + CONFIG_INOTIFY_USER=y + # CONFIG_QUOTA is not set ++CONFIG_DNOTIFY=y + # CONFIG_AUTOFS_FS is not set + CONFIG_AUTOFS4_FS=y + # CONFIG_FUSE_FS is not set +@@ -824,13 +759,16 @@ + CONFIG_PROC_FS=y + CONFIG_PROC_KCORE=y + CONFIG_PROC_SYSCTL=y +-CONFIG_PROC_PAGE_MONITOR=y + CONFIG_SYSFS=y + CONFIG_TMPFS=y + # CONFIG_TMPFS_POSIX_ACL is not set + # CONFIG_HUGETLB_PAGE is not set ++CONFIG_RAMFS=y + # CONFIG_CONFIGFS_FS is not set +-CONFIG_MISC_FILESYSTEMS=y ++ ++# ++# Miscellaneous filesystems ++# + # CONFIG_ADFS_FS is not set + # CONFIG_AFFS_FS is not set + # CONFIG_ECRYPT_FS is not set +@@ -840,34 +778,35 @@ + # CONFIG_BFS_FS is not set + # CONFIG_EFS_FS is not set + # CONFIG_CRAMFS is not set +-# CONFIG_SQUASHFS is not set + # CONFIG_VXFS_FS is not set +-# CONFIG_MINIX_FS is not set +-# CONFIG_OMFS_FS is not set + # CONFIG_HPFS_FS is not set + # CONFIG_QNX4FS_FS is not set +-# CONFIG_ROMFS_FS is not set + # CONFIG_SYSV_FS is not set + CONFIG_UFS_FS=m + # CONFIG_UFS_FS_WRITE is not set + # CONFIG_UFS_DEBUG is not set +-CONFIG_NETWORK_FILESYSTEMS=y ++ ++# ++# Network File Systems ++# + CONFIG_NFS_FS=y + CONFIG_NFS_V3=y + # CONFIG_NFS_V3_ACL is not set + CONFIG_NFS_V4=y +-CONFIG_ROOT_NFS=y ++CONFIG_NFS_DIRECTIO=y + CONFIG_NFSD=m + CONFIG_NFSD_V3=y + # CONFIG_NFSD_V3_ACL is not set + CONFIG_NFSD_V4=y ++CONFIG_NFSD_TCP=y ++CONFIG_ROOT_NFS=y + CONFIG_LOCKD=y + CONFIG_LOCKD_V4=y + CONFIG_EXPORTFS=m + CONFIG_NFS_COMMON=y + CONFIG_SUNRPC=y + CONFIG_SUNRPC_GSS=y +-# CONFIG_SUNRPC_REGISTER_V4 is not set ++# CONFIG_SUNRPC_BIND34 is not set + CONFIG_RPCSEC_GSS_KRB5=y + CONFIG_RPCSEC_GSS_SPKM3=m + CONFIG_SMB_FS=m +@@ -876,7 +815,6 @@ + CONFIG_CIFS=m + # CONFIG_CIFS_STATS is not set + # CONFIG_CIFS_WEAK_PW_HASH is not set +-# CONFIG_CIFS_UPCALL is not set + # CONFIG_CIFS_XATTR is not set + # CONFIG_CIFS_DEBUG2 is not set + # CONFIG_CIFS_EXPERIMENTAL is not set +@@ -889,6 +827,10 @@ + # + # CONFIG_PARTITION_ADVANCED is not set + CONFIG_MSDOS_PARTITION=y ++ ++# ++# Native Language Support ++# + CONFIG_NLS=y + CONFIG_NLS_DEFAULT="iso8859-1" + CONFIG_NLS_CODEPAGE_437=m +@@ -929,28 +871,33 @@ + CONFIG_NLS_KOI8_R=m + CONFIG_NLS_KOI8_U=m + CONFIG_NLS_UTF8=m ++ ++# ++# Distributed Lock Manager ++# + # CONFIG_DLM is not set + + # ++# Profiling support ++# ++CONFIG_PROFILING=y ++CONFIG_OPROFILE=m ++ ++# + # Kernel hacking + # + # CONFIG_PRINTK_TIME is not set +-CONFIG_ENABLE_WARN_DEPRECATED=y + CONFIG_ENABLE_MUST_CHECK=y +-CONFIG_FRAME_WARN=1024 + CONFIG_MAGIC_SYSRQ=y + # CONFIG_UNUSED_SYMBOLS is not set +-CONFIG_DEBUG_FS=y ++# CONFIG_DEBUG_FS is not set + # CONFIG_HEADERS_CHECK is not set + CONFIG_DEBUG_KERNEL=y + # CONFIG_DEBUG_SHIRQ is not set + CONFIG_DETECT_SOFTLOCKUP=y +-# CONFIG_BOOTPARAM_SOFTLOCKUP_PANIC is not set +-CONFIG_BOOTPARAM_SOFTLOCKUP_PANIC_VALUE=0 + CONFIG_SCHED_DEBUG=y + # CONFIG_SCHEDSTATS is not set + # CONFIG_TIMER_STATS is not set +-# CONFIG_DEBUG_OBJECTS is not set + # CONFIG_DEBUG_SLAB is not set + # CONFIG_DEBUG_RT_MUTEXES is not set + # CONFIG_RT_MUTEX_TESTER is not set +@@ -962,32 +909,10 @@ + CONFIG_DEBUG_BUGVERBOSE=y + # CONFIG_DEBUG_INFO is not set + # CONFIG_DEBUG_VM is not set +-# CONFIG_DEBUG_WRITECOUNT is not set +-CONFIG_DEBUG_MEMORY_INIT=y + # CONFIG_DEBUG_LIST is not set +-# CONFIG_DEBUG_SG is not set +-# CONFIG_DEBUG_NOTIFIERS is not set +-# CONFIG_BOOT_PRINTK_DELAY is not set ++CONFIG_FORCED_INLINING=y + # CONFIG_RCU_TORTURE_TEST is not set +-# CONFIG_RCU_CPU_STALL_DETECTOR is not set +-# CONFIG_BACKTRACE_SELF_TEST is not set +-# CONFIG_DEBUG_BLOCK_EXT_DEVT is not set + # CONFIG_FAULT_INJECTION is not set +-# CONFIG_SYSCTL_SYSCALL_CHECK is not set +-CONFIG_NOP_TRACER=y +-CONFIG_RING_BUFFER=y +-CONFIG_TRACING=y +- +-# +-# Tracers +-# +-# CONFIG_SCHED_TRACER is not set +-# CONFIG_CONTEXT_SWITCH_TRACER is not set +-# CONFIG_BOOT_TRACER is not set +-# CONFIG_TRACE_BRANCH_PROFILING is not set +-# CONFIG_FTRACE_STARTUP_TEST is not set +-# CONFIG_DYNAMIC_PRINTK_DEBUG is not set +-# CONFIG_SAMPLES is not set + CONFIG_DEBUG_RODATA=y + + # +@@ -996,113 +921,57 @@ + CONFIG_KEYS=y + CONFIG_KEYS_DEBUG_PROC_KEYS=y + # CONFIG_SECURITY is not set +-# CONFIG_SECURITYFS is not set +-# CONFIG_SECURITY_FILE_CAPABILITIES is not set + CONFIG_CRYPTO=y +- +-# +-# Crypto core or helper +-# +-# CONFIG_CRYPTO_FIPS is not set + CONFIG_CRYPTO_ALGAPI=y +-CONFIG_CRYPTO_ALGAPI2=y +-CONFIG_CRYPTO_AEAD=m +-CONFIG_CRYPTO_AEAD2=y + CONFIG_CRYPTO_BLKCIPHER=y +-CONFIG_CRYPTO_BLKCIPHER2=y + CONFIG_CRYPTO_HASH=y +-CONFIG_CRYPTO_HASH2=y +-CONFIG_CRYPTO_RNG2=y + CONFIG_CRYPTO_MANAGER=y +-CONFIG_CRYPTO_MANAGER2=y +-# CONFIG_CRYPTO_GF128MUL is not set +-CONFIG_CRYPTO_NULL=m +-# CONFIG_CRYPTO_CRYPTD is not set +-CONFIG_CRYPTO_AUTHENC=m +-CONFIG_CRYPTO_TEST=m +- +-# +-# Authenticated Encryption with Associated Data +-# +-# CONFIG_CRYPTO_CCM is not set +-# CONFIG_CRYPTO_GCM is not set +-# CONFIG_CRYPTO_SEQIV is not set +- +-# +-# Block modes +-# +-CONFIG_CRYPTO_CBC=y +-# CONFIG_CRYPTO_CTR is not set +-# CONFIG_CRYPTO_CTS is not set +-CONFIG_CRYPTO_ECB=m +-# CONFIG_CRYPTO_LRW is not set +-# CONFIG_CRYPTO_PCBC is not set +-# CONFIG_CRYPTO_XTS is not set +- +-# +-# Hash modes +-# + CONFIG_CRYPTO_HMAC=y + # CONFIG_CRYPTO_XCBC is not set +- +-# +-# Digest +-# +-CONFIG_CRYPTO_CRC32C=m ++CONFIG_CRYPTO_NULL=m + CONFIG_CRYPTO_MD4=m + CONFIG_CRYPTO_MD5=y +-CONFIG_CRYPTO_MICHAEL_MIC=m +-# CONFIG_CRYPTO_RMD128 is not set +-# CONFIG_CRYPTO_RMD160 is not set +-# CONFIG_CRYPTO_RMD256 is not set +-# CONFIG_CRYPTO_RMD320 is not set + CONFIG_CRYPTO_SHA1=m + CONFIG_CRYPTO_SHA256=m + CONFIG_CRYPTO_SHA512=m +-CONFIG_CRYPTO_TGR192=m + CONFIG_CRYPTO_WP512=m +- +-# +-# Ciphers +-# +-CONFIG_CRYPTO_AES=m +-CONFIG_CRYPTO_ANUBIS=m +-CONFIG_CRYPTO_ARC4=m ++CONFIG_CRYPTO_TGR192=m ++# CONFIG_CRYPTO_GF128MUL is not set ++CONFIG_CRYPTO_ECB=m ++CONFIG_CRYPTO_CBC=y ++# CONFIG_CRYPTO_PCBC is not set ++# CONFIG_CRYPTO_LRW is not set ++# CONFIG_CRYPTO_XTS is not set ++# CONFIG_CRYPTO_CRYPTD is not set ++CONFIG_CRYPTO_DES=y ++# CONFIG_CRYPTO_FCRYPT is not set + CONFIG_CRYPTO_BLOWFISH=m +-# CONFIG_CRYPTO_CAMELLIA is not set ++CONFIG_CRYPTO_TWOFISH=m ++CONFIG_CRYPTO_TWOFISH_COMMON=m ++CONFIG_CRYPTO_SERPENT=m ++CONFIG_CRYPTO_AES=m + CONFIG_CRYPTO_CAST5=m + CONFIG_CRYPTO_CAST6=m +-CONFIG_CRYPTO_DES=y +-# CONFIG_CRYPTO_FCRYPT is not set ++CONFIG_CRYPTO_TEA=m ++CONFIG_CRYPTO_ARC4=m + CONFIG_CRYPTO_KHAZAD=m +-# CONFIG_CRYPTO_SALSA20 is not set ++CONFIG_CRYPTO_ANUBIS=m + # CONFIG_CRYPTO_SEED is not set +-CONFIG_CRYPTO_SERPENT=m +-CONFIG_CRYPTO_TEA=m +-CONFIG_CRYPTO_TWOFISH=m +-CONFIG_CRYPTO_TWOFISH_COMMON=m +- +-# +-# Compression +-# + CONFIG_CRYPTO_DEFLATE=m +-# CONFIG_CRYPTO_LZO is not set +- +-# +-# Random Number Generation +-# +-# CONFIG_CRYPTO_ANSI_CPRNG is not set ++CONFIG_CRYPTO_MICHAEL_MIC=m ++CONFIG_CRYPTO_CRC32C=m ++# CONFIG_CRYPTO_CAMELLIA is not set ++CONFIG_CRYPTO_TEST=m ++# CONFIG_CRYPTO_AUTHENC is not set + # CONFIG_CRYPTO_HW is not set + + # + # Library routines + # + CONFIG_BITREVERSE=y +-CONFIG_GENERIC_FIND_LAST_BIT=y + CONFIG_CRC_CCITT=m + # CONFIG_CRC16 is not set +-# CONFIG_CRC_T10DIF is not set +-CONFIG_CRC_ITU_T=m ++# CONFIG_CRC_ITU_T is not set + CONFIG_CRC32=y + # CONFIG_CRC7 is not set + CONFIG_LIBCRC32C=m +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/arch/parisc/configs/a500_defconfig linux-2.6.29-rc3.owrt/arch/parisc/configs/a500_defconfig +--- linux-2.6.29.owrt/arch/parisc/configs/a500_defconfig 2009-05-10 22:04:39.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/arch/parisc/configs/a500_defconfig 2009-05-10 23:48:28.000000000 +0200 +@@ -1,7 +1,7 @@ + # + # Automatically generated make config: don't edit +-# Linux kernel version: 2.6.29-rc8 +-# Fri Mar 13 01:32:56 2009 ++# Linux kernel version: 2.6.23 ++# Fri Oct 12 21:12:44 2007 + # + CONFIG_PARISC=y + CONFIG_MMU=y +@@ -34,30 +34,18 @@ + CONFIG_POSIX_MQUEUE=y + # CONFIG_BSD_PROCESS_ACCT is not set + # CONFIG_TASKSTATS is not set ++# CONFIG_USER_NS is not set + # CONFIG_AUDIT is not set +- +-# +-# RCU Subsystem +-# +-CONFIG_CLASSIC_RCU=y +-# CONFIG_TREE_RCU is not set +-# CONFIG_PREEMPT_RCU is not set +-# CONFIG_TREE_RCU_TRACE is not set +-# CONFIG_PREEMPT_RCU_TRACE is not set + CONFIG_IKCONFIG=y + CONFIG_IKCONFIG_PROC=y + CONFIG_LOG_BUF_SHIFT=16 +-# CONFIG_GROUP_SCHED is not set +-# CONFIG_CGROUPS is not set ++# CONFIG_CPUSETS is not set + CONFIG_SYSFS_DEPRECATED=y +-CONFIG_SYSFS_DEPRECATED_V2=y + # CONFIG_RELAY is not set +-# CONFIG_NAMESPACES is not set + CONFIG_BLK_DEV_INITRD=y + CONFIG_INITRAMFS_SOURCE="" + # CONFIG_CC_OPTIMIZE_FOR_SIZE is not set + CONFIG_SYSCTL=y +-CONFIG_ANON_INODES=y + CONFIG_EMBEDDED=y + CONFIG_SYSCTL_SYSCALL=y + CONFIG_KALLSYMS=y +@@ -69,40 +57,28 @@ + CONFIG_ELF_CORE=y + CONFIG_BASE_FULL=y + CONFIG_FUTEX=y ++CONFIG_ANON_INODES=y + CONFIG_EPOLL=y + CONFIG_SIGNALFD=y +-CONFIG_TIMERFD=y + CONFIG_EVENTFD=y + CONFIG_SHMEM=y +-CONFIG_AIO=y + CONFIG_VM_EVENT_COUNTERS=y +-CONFIG_PCI_QUIRKS=y +-CONFIG_COMPAT_BRK=y + CONFIG_SLAB=y + # CONFIG_SLUB is not set + # CONFIG_SLOB is not set +-CONFIG_PROFILING=y +-CONFIG_TRACEPOINTS=y +-# CONFIG_MARKERS is not set +-CONFIG_OPROFILE=m +-CONFIG_HAVE_OPROFILE=y +-CONFIG_USE_GENERIC_SMP_HELPERS=y +-# CONFIG_HAVE_GENERIC_DMA_COHERENT is not set +-CONFIG_SLABINFO=y + CONFIG_RT_MUTEXES=y ++# CONFIG_TINY_SHMEM is not set + CONFIG_BASE_SMALL=0 + CONFIG_MODULES=y +-# CONFIG_MODULE_FORCE_LOAD is not set + CONFIG_MODULE_UNLOAD=y + CONFIG_MODULE_FORCE_UNLOAD=y + # CONFIG_MODVERSIONS is not set + # CONFIG_MODULE_SRCVERSION_ALL is not set +-CONFIG_INIT_ALL_POSSIBLE=y ++CONFIG_KMOD=y + CONFIG_STOP_MACHINE=y + CONFIG_BLOCK=y + # CONFIG_BLK_DEV_IO_TRACE is not set + # CONFIG_BLK_DEV_BSG is not set +-# CONFIG_BLK_DEV_INTEGRITY is not set + CONFIG_BLOCK_COMPAT=y + + # +@@ -117,7 +93,6 @@ + CONFIG_DEFAULT_CFQ=y + # CONFIG_DEFAULT_NOOP is not set + CONFIG_DEFAULT_IOSCHED="cfq" +-# CONFIG_FREEZER is not set + + # + # Processor type and features +@@ -143,12 +118,12 @@ + CONFIG_PREEMPT_NONE=y + # CONFIG_PREEMPT_VOLUNTARY is not set + # CONFIG_PREEMPT is not set ++CONFIG_PREEMPT_BKL=y + # CONFIG_HZ_100 is not set + CONFIG_HZ_250=y + # CONFIG_HZ_300 is not set + # CONFIG_HZ_1000 is not set + CONFIG_HZ=250 +-# CONFIG_SCHED_HRTICK is not set + CONFIG_SELECT_MEMORY_MODEL=y + # CONFIG_FLATMEM_MANUAL is not set + CONFIG_DISCONTIGMEM_MANUAL=y +@@ -156,12 +131,11 @@ + CONFIG_DISCONTIGMEM=y + CONFIG_FLAT_NODE_MEM_MAP=y + CONFIG_NEED_MULTIPLE_NODES=y +-CONFIG_PAGEFLAGS_EXTENDED=y ++# CONFIG_SPARSEMEM_STATIC is not set + CONFIG_SPLIT_PTLOCK_CPUS=4 +-CONFIG_PHYS_ADDR_T_64BIT=y ++CONFIG_RESOURCES_64BIT=y + CONFIG_ZONE_DMA_FLAG=0 + CONFIG_VIRT_TO_BUS=y +-CONFIG_UNEVICTABLE_LRU=y + CONFIG_COMPAT=y + CONFIG_NR_CPUS=8 + +@@ -171,13 +145,14 @@ + # CONFIG_GSC is not set + CONFIG_PCI=y + # CONFIG_ARCH_SUPPORTS_MSI is not set +-CONFIG_PCI_LEGACY=y + # CONFIG_PCI_DEBUG is not set +-# CONFIG_PCI_STUB is not set + CONFIG_PCI_LBA=y + CONFIG_IOSAPIC=y + CONFIG_IOMMU_SBA=y +-CONFIG_IOMMU_HELPER=y ++ ++# ++# PCCARD (PCMCIA/CardBus) support ++# + CONFIG_PCCARD=m + # CONFIG_PCMCIA_DEBUG is not set + CONFIG_PCMCIA=m +@@ -212,15 +187,16 @@ + # Executable file formats + # + CONFIG_BINFMT_ELF=y +-# CONFIG_CORE_DUMP_DEFAULT_ELF_HEADERS is not set +-# CONFIG_HAVE_AOUT is not set + # CONFIG_BINFMT_MISC is not set ++ ++# ++# Networking ++# + CONFIG_NET=y + + # + # Networking options + # +-CONFIG_COMPAT_NET_DEV_OPS=y + CONFIG_PACKET=y + CONFIG_PACKET_MMAP=y + CONFIG_UNIX=y +@@ -228,8 +204,6 @@ + CONFIG_XFRM_USER=m + # CONFIG_XFRM_SUB_POLICY is not set + # CONFIG_XFRM_MIGRATE is not set +-# CONFIG_XFRM_STATISTICS is not set +-CONFIG_XFRM_IPCOMP=m + CONFIG_NET_KEY=m + # CONFIG_NET_KEY_MIGRATE is not set + CONFIG_INET=y +@@ -260,6 +234,7 @@ + CONFIG_TCP_CONG_CUBIC=y + CONFIG_DEFAULT_TCP_CONG="cubic" + # CONFIG_TCP_MD5SIG is not set ++# CONFIG_IP_VS is not set + CONFIG_IPV6=m + # CONFIG_IPV6_PRIVACY is not set + # CONFIG_IPV6_ROUTER_PREF is not set +@@ -275,72 +250,66 @@ + CONFIG_INET6_XFRM_MODE_BEET=m + # CONFIG_INET6_XFRM_MODE_ROUTEOPTIMIZATION is not set + CONFIG_IPV6_SIT=m +-CONFIG_IPV6_NDISC_NODETYPE=y + CONFIG_IPV6_TUNNEL=m + # CONFIG_IPV6_MULTIPLE_TABLES is not set +-# CONFIG_IPV6_MROUTE is not set + # CONFIG_NETWORK_SECMARK is not set + CONFIG_NETFILTER=y + # CONFIG_NETFILTER_DEBUG is not set +-CONFIG_NETFILTER_ADVANCED=y + + # + # Core Netfilter Configuration + # +-# CONFIG_NETFILTER_NETLINK_QUEUE is not set +-# CONFIG_NETFILTER_NETLINK_LOG is not set ++# CONFIG_NETFILTER_NETLINK is not set ++# CONFIG_NF_CONNTRACK_ENABLED is not set + # CONFIG_NF_CONNTRACK is not set + CONFIG_NETFILTER_XTABLES=m + # CONFIG_NETFILTER_XT_TARGET_CLASSIFY is not set + # CONFIG_NETFILTER_XT_TARGET_DSCP is not set + # CONFIG_NETFILTER_XT_TARGET_MARK is not set +-# CONFIG_NETFILTER_XT_TARGET_NFLOG is not set + # CONFIG_NETFILTER_XT_TARGET_NFQUEUE is not set +-# CONFIG_NETFILTER_XT_TARGET_RATEEST is not set ++# CONFIG_NETFILTER_XT_TARGET_NFLOG is not set + # CONFIG_NETFILTER_XT_TARGET_TRACE is not set + # CONFIG_NETFILTER_XT_TARGET_TCPMSS is not set +-# CONFIG_NETFILTER_XT_TARGET_TCPOPTSTRIP is not set + # CONFIG_NETFILTER_XT_MATCH_COMMENT is not set + # CONFIG_NETFILTER_XT_MATCH_DCCP is not set + # CONFIG_NETFILTER_XT_MATCH_DSCP is not set + # CONFIG_NETFILTER_XT_MATCH_ESP is not set +-# CONFIG_NETFILTER_XT_MATCH_HASHLIMIT is not set +-# CONFIG_NETFILTER_XT_MATCH_IPRANGE is not set + # CONFIG_NETFILTER_XT_MATCH_LENGTH is not set + # CONFIG_NETFILTER_XT_MATCH_LIMIT is not set + # CONFIG_NETFILTER_XT_MATCH_MAC is not set + # CONFIG_NETFILTER_XT_MATCH_MARK is not set +-# CONFIG_NETFILTER_XT_MATCH_MULTIPORT is not set +-# CONFIG_NETFILTER_XT_MATCH_OWNER is not set + # CONFIG_NETFILTER_XT_MATCH_POLICY is not set ++# CONFIG_NETFILTER_XT_MATCH_MULTIPORT is not set + # CONFIG_NETFILTER_XT_MATCH_PKTTYPE is not set + # CONFIG_NETFILTER_XT_MATCH_QUOTA is not set +-# CONFIG_NETFILTER_XT_MATCH_RATEEST is not set + # CONFIG_NETFILTER_XT_MATCH_REALM is not set +-# CONFIG_NETFILTER_XT_MATCH_RECENT is not set + # CONFIG_NETFILTER_XT_MATCH_SCTP is not set + # CONFIG_NETFILTER_XT_MATCH_STATISTIC is not set + # CONFIG_NETFILTER_XT_MATCH_STRING is not set + # CONFIG_NETFILTER_XT_MATCH_TCPMSS is not set + # CONFIG_NETFILTER_XT_MATCH_TIME is not set + # CONFIG_NETFILTER_XT_MATCH_U32 is not set +-# CONFIG_IP_VS is not set ++# CONFIG_NETFILTER_XT_MATCH_HASHLIMIT is not set + + # + # IP: Netfilter Configuration + # +-# CONFIG_NF_DEFRAG_IPV4 is not set + CONFIG_IP_NF_QUEUE=m + CONFIG_IP_NF_IPTABLES=m +-# CONFIG_IP_NF_MATCH_ADDRTYPE is not set +-# CONFIG_IP_NF_MATCH_AH is not set ++CONFIG_IP_NF_MATCH_IPRANGE=m ++CONFIG_IP_NF_MATCH_TOS=m ++CONFIG_IP_NF_MATCH_RECENT=m + CONFIG_IP_NF_MATCH_ECN=m ++# CONFIG_IP_NF_MATCH_AH is not set + CONFIG_IP_NF_MATCH_TTL=m ++CONFIG_IP_NF_MATCH_OWNER=m ++# CONFIG_IP_NF_MATCH_ADDRTYPE is not set + CONFIG_IP_NF_FILTER=m + CONFIG_IP_NF_TARGET_REJECT=m + CONFIG_IP_NF_TARGET_LOG=m + CONFIG_IP_NF_TARGET_ULOG=m + CONFIG_IP_NF_MANGLE=m ++CONFIG_IP_NF_TARGET_TOS=m + CONFIG_IP_NF_TARGET_ECN=m + # CONFIG_IP_NF_TARGET_TTL is not set + CONFIG_IP_NF_RAW=m +@@ -349,30 +318,33 @@ + CONFIG_IP_NF_ARP_MANGLE=m + + # +-# IPv6: Netfilter Configuration ++# IPv6: Netfilter Configuration (EXPERIMENTAL) + # + # CONFIG_IP6_NF_QUEUE is not set + CONFIG_IP6_NF_IPTABLES=m +-# CONFIG_IP6_NF_MATCH_AH is not set +-# CONFIG_IP6_NF_MATCH_EUI64 is not set +-CONFIG_IP6_NF_MATCH_FRAG=m ++CONFIG_IP6_NF_MATCH_RT=m + CONFIG_IP6_NF_MATCH_OPTS=m ++CONFIG_IP6_NF_MATCH_FRAG=m + CONFIG_IP6_NF_MATCH_HL=m ++# CONFIG_IP6_NF_MATCH_OWNER is not set + CONFIG_IP6_NF_MATCH_IPV6HEADER=m ++# CONFIG_IP6_NF_MATCH_AH is not set + # CONFIG_IP6_NF_MATCH_MH is not set +-CONFIG_IP6_NF_MATCH_RT=m +-CONFIG_IP6_NF_TARGET_LOG=m ++# CONFIG_IP6_NF_MATCH_EUI64 is not set + CONFIG_IP6_NF_FILTER=m ++CONFIG_IP6_NF_TARGET_LOG=m + CONFIG_IP6_NF_TARGET_REJECT=m + CONFIG_IP6_NF_MANGLE=m + # CONFIG_IP6_NF_TARGET_HL is not set + CONFIG_IP6_NF_RAW=m + CONFIG_IP_DCCP=m + CONFIG_INET_DCCP_DIAG=m ++CONFIG_IP_DCCP_ACKVEC=y + + # + # DCCP CCIDs Configuration (EXPERIMENTAL) + # ++CONFIG_IP_DCCP_CCID2=m + # CONFIG_IP_DCCP_CCID2_DEBUG is not set + # CONFIG_IP_DCCP_CCID3 is not set + +@@ -384,7 +356,6 @@ + # CONFIG_TIPC is not set + # CONFIG_ATM is not set + # CONFIG_BRIDGE is not set +-# CONFIG_NET_DSA is not set + # CONFIG_VLAN_8021Q is not set + # CONFIG_DECNET is not set + CONFIG_LLC=m +@@ -395,26 +366,28 @@ + # CONFIG_LAPB is not set + # CONFIG_ECONET is not set + # CONFIG_WAN_ROUTER is not set ++ ++# ++# QoS and/or fair queueing ++# + # CONFIG_NET_SCHED is not set +-# CONFIG_DCB is not set + + # + # Network testing + # + CONFIG_NET_PKTGEN=m + # CONFIG_HAMRADIO is not set +-# CONFIG_CAN is not set + # CONFIG_IRDA is not set + # CONFIG_BT is not set + # CONFIG_AF_RXRPC is not set +-# CONFIG_PHONET is not set +-CONFIG_WIRELESS=y ++ ++# ++# Wireless ++# + # CONFIG_CFG80211 is not set +-CONFIG_WIRELESS_OLD_REGULATORY=y + # CONFIG_WIRELESS_EXT is not set +-# CONFIG_LIB80211 is not set + # CONFIG_MAC80211 is not set +-# CONFIG_WIMAX is not set ++# CONFIG_IEEE80211 is not set + # CONFIG_RFKILL is not set + # CONFIG_NET_9P is not set + +@@ -429,8 +402,6 @@ + # CONFIG_STANDALONE is not set + # CONFIG_PREVENT_FIRMWARE_BUILD is not set + CONFIG_FW_LOADER=y +-CONFIG_FIRMWARE_IN_KERNEL=y +-CONFIG_EXTRA_FIRMWARE="" + # CONFIG_DEBUG_DRIVER is not set + # CONFIG_DEBUG_DEVRES is not set + # CONFIG_SYS_HYPERVISOR is not set +@@ -450,23 +421,14 @@ + CONFIG_BLK_DEV_RAM=y + CONFIG_BLK_DEV_RAM_COUNT=16 + CONFIG_BLK_DEV_RAM_SIZE=6144 +-# CONFIG_BLK_DEV_XIP is not set ++CONFIG_BLK_DEV_RAM_BLOCKSIZE=1024 + # CONFIG_CDROM_PKTCDVD is not set + # CONFIG_ATA_OVER_ETH is not set +-# CONFIG_BLK_DEV_HD is not set + CONFIG_MISC_DEVICES=y + # CONFIG_PHANTOM is not set ++# CONFIG_EEPROM_93CX6 is not set + # CONFIG_SGI_IOC4 is not set + # CONFIG_TIFM_CORE is not set +-# CONFIG_ENCLOSURE_SERVICES is not set +-# CONFIG_HP_ILO is not set +-# CONFIG_C2PORT is not set +- +-# +-# EEPROM support +-# +-# CONFIG_EEPROM_93CX6 is not set +-CONFIG_HAVE_IDE=y + # CONFIG_IDE is not set + + # +@@ -506,10 +468,8 @@ + CONFIG_SCSI_FC_ATTRS=m + CONFIG_SCSI_ISCSI_ATTRS=m + # CONFIG_SCSI_SAS_LIBSAS is not set +-# CONFIG_SCSI_SRP_ATTRS is not set + CONFIG_SCSI_LOWLEVEL=y + # CONFIG_ISCSI_TCP is not set +-# CONFIG_SCSI_CXGB3_ISCSI is not set + # CONFIG_BLK_DEV_3W_XXXX_RAID is not set + # CONFIG_SCSI_3W_9XXX is not set + # CONFIG_SCSI_ACARD is not set +@@ -518,21 +478,16 @@ + # CONFIG_SCSI_AIC7XXX_OLD is not set + # CONFIG_SCSI_AIC79XX is not set + # CONFIG_SCSI_AIC94XX is not set +-# CONFIG_SCSI_DPT_I2O is not set +-# CONFIG_SCSI_ADVANSYS is not set + # CONFIG_SCSI_ARCMSR is not set + # CONFIG_MEGARAID_NEWGEN is not set + # CONFIG_MEGARAID_LEGACY is not set + # CONFIG_MEGARAID_SAS is not set + # CONFIG_SCSI_HPTIOP is not set +-# CONFIG_LIBFC is not set +-# CONFIG_FCOE is not set + # CONFIG_SCSI_DMX3191D is not set + # CONFIG_SCSI_FUTURE_DOMAIN is not set + # CONFIG_SCSI_IPS is not set + # CONFIG_SCSI_INITIO is not set + # CONFIG_SCSI_INIA100 is not set +-# CONFIG_SCSI_MVSAS is not set + # CONFIG_SCSI_STEX is not set + CONFIG_SCSI_SYM53C8XX_2=y + CONFIG_SCSI_SYM53C8XX_DMA_ADDRESSING_MODE=1 +@@ -548,11 +503,9 @@ + CONFIG_SCSI_DEBUG=m + # CONFIG_SCSI_SRP is not set + # CONFIG_SCSI_LOWLEVEL_PCMCIA is not set +-# CONFIG_SCSI_DH is not set + # CONFIG_ATA is not set + CONFIG_MD=y + CONFIG_BLK_DEV_MD=y +-CONFIG_MD_AUTODETECT=y + CONFIG_MD_LINEAR=y + CONFIG_MD_RAID0=y + CONFIG_MD_RAID1=y +@@ -561,6 +514,10 @@ + # CONFIG_MD_MULTIPATH is not set + # CONFIG_MD_FAULTY is not set + # CONFIG_BLK_DEV_DM is not set ++ ++# ++# Fusion MPT device support ++# + CONFIG_FUSION=y + CONFIG_FUSION_SPI=m + CONFIG_FUSION_FC=m +@@ -572,40 +529,20 @@ + # + # IEEE 1394 (FireWire) support + # +- +-# +-# Enable only one of the two stacks, unless you know what you are doing +-# + # CONFIG_FIREWIRE is not set + # CONFIG_IEEE1394 is not set + # CONFIG_I2O is not set + CONFIG_NETDEVICES=y ++# CONFIG_NETDEVICES_MULTIQUEUE is not set + CONFIG_DUMMY=m + CONFIG_BONDING=m + # CONFIG_MACVLAN is not set + # CONFIG_EQUALIZER is not set + CONFIG_TUN=m + # CONFIG_VETH is not set ++# CONFIG_IP1000 is not set + # CONFIG_ARCNET is not set +-CONFIG_PHYLIB=m +- +-# +-# MII PHY device drivers +-# +-# CONFIG_MARVELL_PHY is not set +-# CONFIG_DAVICOM_PHY is not set +-# CONFIG_QSEMI_PHY is not set +-# CONFIG_LXT_PHY is not set +-# CONFIG_CICADA_PHY is not set +-# CONFIG_VITESSE_PHY is not set +-# CONFIG_SMSC_PHY is not set +-# CONFIG_BROADCOM_PHY is not set +-# CONFIG_ICPLUS_PHY is not set +-# CONFIG_REALTEK_PHY is not set +-# CONFIG_NATIONAL_PHY is not set +-# CONFIG_STE10XP is not set +-# CONFIG_LSI_ET1011C_PHY is not set +-# CONFIG_MDIO_BITBANG is not set ++# CONFIG_PHYLIB is not set + CONFIG_NET_ETHERNET=y + CONFIG_MII=m + # CONFIG_HAPPYMEAL is not set +@@ -630,38 +567,33 @@ + # CONFIG_IBM_NEW_EMAC_RGMII is not set + # CONFIG_IBM_NEW_EMAC_TAH is not set + # CONFIG_IBM_NEW_EMAC_EMAC4 is not set +-# CONFIG_IBM_NEW_EMAC_NO_FLOW_CTRL is not set +-# CONFIG_IBM_NEW_EMAC_MAL_CLR_ICINTSTAT is not set +-# CONFIG_IBM_NEW_EMAC_MAL_COMMON_ERR is not set + CONFIG_NET_PCI=y + CONFIG_PCNET32=m ++# CONFIG_PCNET32_NAPI is not set + # CONFIG_AMD8111_ETH is not set + # CONFIG_ADAPTEC_STARFIRE is not set + # CONFIG_B44 is not set + # CONFIG_FORCEDETH is not set ++# CONFIG_EEPRO100 is not set + CONFIG_E100=m + # CONFIG_FEALNX is not set + # CONFIG_NATSEMI is not set + # CONFIG_NE2K_PCI is not set + # CONFIG_8139CP is not set + # CONFIG_8139TOO is not set +-# CONFIG_R6040 is not set + # CONFIG_SIS900 is not set + # CONFIG_EPIC100 is not set +-# CONFIG_SMSC9420 is not set + # CONFIG_SUNDANCE is not set +-# CONFIG_TLAN is not set + # CONFIG_VIA_RHINE is not set + # CONFIG_SC92031 is not set +-# CONFIG_ATL2 is not set + CONFIG_NETDEV_1000=y + CONFIG_ACENIC=m + CONFIG_ACENIC_OMIT_TIGON_I=y + # CONFIG_DL2K is not set + CONFIG_E1000=m ++CONFIG_E1000_NAPI=y ++# CONFIG_E1000_DISABLE_PACKET_SPLIT is not set + # CONFIG_E1000E is not set +-# CONFIG_IP1000 is not set +-# CONFIG_IGB is not set + # CONFIG_NS83820 is not set + # CONFIG_HAMACHI is not set + # CONFIG_YELLOWFIN is not set +@@ -669,31 +601,23 @@ + # CONFIG_SIS190 is not set + # CONFIG_SKGE is not set + # CONFIG_SKY2 is not set ++# CONFIG_SK98LIN is not set + # CONFIG_VIA_VELOCITY is not set + CONFIG_TIGON3=m + # CONFIG_BNX2 is not set + # CONFIG_QLA3XXX is not set + # CONFIG_ATL1 is not set +-# CONFIG_ATL1E is not set +-# CONFIG_ATL1C is not set +-# CONFIG_JME is not set + CONFIG_NETDEV_10000=y + # CONFIG_CHELSIO_T1 is not set +-CONFIG_CHELSIO_T3_DEPENDS=y + # CONFIG_CHELSIO_T3 is not set +-# CONFIG_ENIC is not set + # CONFIG_IXGBE is not set + # CONFIG_IXGB is not set + # CONFIG_S2IO is not set + # CONFIG_MYRI10GE is not set + # CONFIG_NETXEN_NIC is not set + # CONFIG_NIU is not set +-# CONFIG_MLX4_EN is not set + # CONFIG_MLX4_CORE is not set + # CONFIG_TEHUTI is not set +-# CONFIG_BNX2X is not set +-# CONFIG_QLGE is not set +-# CONFIG_SFC is not set + # CONFIG_TR is not set + + # +@@ -701,11 +625,6 @@ + # + # CONFIG_WLAN_PRE80211 is not set + # CONFIG_WLAN_80211 is not set +-# CONFIG_IWLWIFI_LEDS is not set +- +-# +-# Enable WiMAX (Networking options) to see the WiMAX drivers +-# + CONFIG_NET_PCMCIA=y + CONFIG_PCMCIA_3C589=m + CONFIG_PCMCIA_3C574=m +@@ -731,6 +650,7 @@ + # CONFIG_SLIP is not set + CONFIG_SLHC=m + # CONFIG_NET_FC is not set ++# CONFIG_SHAPER is not set + # CONFIG_NETCONSOLE is not set + # CONFIG_NETPOLL is not set + # CONFIG_NET_POLL_CONTROLLER is not set +@@ -749,6 +669,7 @@ + # + # CONFIG_INPUT_MOUSEDEV is not set + # CONFIG_INPUT_JOYDEV is not set ++# CONFIG_INPUT_TSDEV is not set + # CONFIG_INPUT_EVDEV is not set + # CONFIG_INPUT_EVBUG is not set + +@@ -772,13 +693,10 @@ + # Character devices + # + CONFIG_VT=y +-CONFIG_CONSOLE_TRANSLATIONS=y + CONFIG_VT_CONSOLE=y + CONFIG_HW_CONSOLE=y + # CONFIG_VT_HW_CONSOLE_BINDING is not set +-CONFIG_DEVKMEM=y + # CONFIG_SERIAL_NONSTANDARD is not set +-# CONFIG_NOZOMI is not set + + # + # Serial drivers +@@ -803,12 +721,17 @@ + CONFIG_SERIAL_CORE_CONSOLE=y + # CONFIG_SERIAL_JSM is not set + CONFIG_UNIX98_PTYS=y +-# CONFIG_DEVPTS_MULTIPLE_INSTANCES is not set + # CONFIG_LEGACY_PTYS is not set + # CONFIG_IPMI_HANDLER is not set ++# CONFIG_WATCHDOG is not set + # CONFIG_HW_RANDOM is not set ++CONFIG_GEN_RTC=y ++CONFIG_GEN_RTC_X=y + # CONFIG_R3964 is not set + # CONFIG_APPLICOM is not set ++CONFIG_AGP=y ++CONFIG_AGP_PARISC=y ++# CONFIG_DRM is not set + + # + # PCMCIA character devices +@@ -816,66 +739,51 @@ + # CONFIG_SYNCLINK_CS is not set + # CONFIG_CARDMAN_4000 is not set + # CONFIG_CARDMAN_4040 is not set +-# CONFIG_IPWIRELESS is not set + CONFIG_RAW_DRIVER=y + CONFIG_MAX_RAW_DEVS=256 + # CONFIG_TCG_TPM is not set + CONFIG_DEVPORT=y + # CONFIG_I2C is not set ++ ++# ++# SPI support ++# + # CONFIG_SPI is not set ++# CONFIG_SPI_MASTER is not set + # CONFIG_W1 is not set + # CONFIG_POWER_SUPPLY is not set + # CONFIG_HWMON is not set +-# CONFIG_THERMAL is not set +-# CONFIG_THERMAL_HWMON is not set +-# CONFIG_WATCHDOG is not set +-CONFIG_SSB_POSSIBLE=y + + # + # Sonics Silicon Backplane + # ++CONFIG_SSB_POSSIBLE=y + # CONFIG_SSB is not set + + # + # Multifunction device drivers + # +-# CONFIG_MFD_CORE is not set + # CONFIG_MFD_SM501 is not set +-# CONFIG_HTC_PASIC3 is not set +-# CONFIG_MFD_TMIO is not set +-# CONFIG_REGULATOR is not set + + # + # Multimedia devices + # +- +-# +-# Multimedia core support +-# + # CONFIG_VIDEO_DEV is not set + # CONFIG_DVB_CORE is not set +-# CONFIG_VIDEO_MEDIA is not set +- +-# +-# Multimedia drivers +-# + # CONFIG_DAB is not set + + # + # Graphics support + # +-CONFIG_AGP=y +-CONFIG_AGP_PARISC=y +-# CONFIG_DRM is not set +-# CONFIG_VGASTATE is not set +-# CONFIG_VIDEO_OUTPUT_CONTROL is not set +-# CONFIG_FB is not set + # CONFIG_BACKLIGHT_LCD_SUPPORT is not set + + # + # Display device support + # + # CONFIG_DISPLAY_SUPPORT is not set ++# CONFIG_VGASTATE is not set ++# CONFIG_VIDEO_OUTPUT_CONTROL is not set ++# CONFIG_FB is not set + + # + # Console display driver support +@@ -884,83 +792,50 @@ + CONFIG_DUMMY_CONSOLE_COLUMNS=160 + CONFIG_DUMMY_CONSOLE_ROWS=64 + # CONFIG_STI_CONSOLE is not set ++ ++# ++# Sound ++# + # CONFIG_SOUND is not set + CONFIG_HID_SUPPORT=y + CONFIG_HID=y + # CONFIG_HID_DEBUG is not set +-# CONFIG_HIDRAW is not set +-# CONFIG_HID_PID is not set +- +-# +-# Special HID drivers +-# +-CONFIG_HID_COMPAT=y + CONFIG_USB_SUPPORT=y + CONFIG_USB_ARCH_HAS_HCD=y + CONFIG_USB_ARCH_HAS_OHCI=y + CONFIG_USB_ARCH_HAS_EHCI=y + # CONFIG_USB is not set +-# CONFIG_USB_OTG_WHITELIST is not set +-# CONFIG_USB_OTG_BLACKLIST_HUB is not set + + # +-# Enable Host or Gadget support to see Inventra options ++# NOTE: USB_STORAGE enables SCSI, and 'SCSI disk support' + # + + # +-# NOTE: USB_STORAGE depends on SCSI but BLK_DEV_SD may also be needed; ++# USB Gadget Support + # + # CONFIG_USB_GADGET is not set +- +-# +-# OTG and related infrastructure +-# +-# CONFIG_UWB is not set + # CONFIG_MMC is not set +-# CONFIG_MEMSTICK is not set + # CONFIG_NEW_LEDS is not set +-# CONFIG_ACCESSIBILITY is not set + # CONFIG_INFINIBAND is not set +-CONFIG_RTC_LIB=y +-CONFIG_RTC_CLASS=y +-CONFIG_RTC_HCTOSYS=y +-CONFIG_RTC_HCTOSYS_DEVICE="rtc0" +-# CONFIG_RTC_DEBUG is not set ++# CONFIG_RTC_CLASS is not set + + # +-# RTC interfaces ++# DMA Engine support + # +-CONFIG_RTC_INTF_SYSFS=y +-CONFIG_RTC_INTF_PROC=y +-CONFIG_RTC_INTF_DEV=y +-# CONFIG_RTC_INTF_DEV_UIE_EMUL is not set +-# CONFIG_RTC_DRV_TEST is not set ++# CONFIG_DMA_ENGINE is not set + + # +-# SPI RTC drivers ++# DMA Clients + # + + # +-# Platform RTC drivers ++# DMA Devices + # +-# CONFIG_RTC_DRV_DS1286 is not set +-# CONFIG_RTC_DRV_DS1511 is not set +-# CONFIG_RTC_DRV_DS1553 is not set +-# CONFIG_RTC_DRV_DS1742 is not set +-# CONFIG_RTC_DRV_STK17TA8 is not set +-# CONFIG_RTC_DRV_M48T86 is not set +-# CONFIG_RTC_DRV_M48T35 is not set +-# CONFIG_RTC_DRV_M48T59 is not set +-# CONFIG_RTC_DRV_BQ4802 is not set +-# CONFIG_RTC_DRV_V3020 is not set + + # +-# on-CPU RTC drivers ++# Userspace I/O + # +-CONFIG_RTC_DRV_PARISC=y +-# CONFIG_DMADEVICES is not set + # CONFIG_UIO is not set +-# CONFIG_STAGING is not set + + # + # File systems +@@ -970,7 +845,7 @@ + # CONFIG_EXT2_FS_XIP is not set + CONFIG_EXT3_FS=y + # CONFIG_EXT3_FS_XATTR is not set +-# CONFIG_EXT4_FS is not set ++# CONFIG_EXT4DEV_FS is not set + CONFIG_JBD=y + # CONFIG_JBD_DEBUG is not set + # CONFIG_REISERFS_FS is not set +@@ -980,19 +855,19 @@ + # CONFIG_JFS_DEBUG is not set + # CONFIG_JFS_STATISTICS is not set + CONFIG_FS_POSIX_ACL=y +-CONFIG_FILE_LOCKING=y + CONFIG_XFS_FS=m + # CONFIG_XFS_QUOTA is not set ++# CONFIG_XFS_SECURITY is not set + # CONFIG_XFS_POSIX_ACL is not set + # CONFIG_XFS_RT is not set +-# CONFIG_XFS_DEBUG is not set + # CONFIG_GFS2_FS is not set + # CONFIG_OCFS2_FS is not set +-# CONFIG_BTRFS_FS is not set +-CONFIG_DNOTIFY=y ++# CONFIG_MINIX_FS is not set ++# CONFIG_ROMFS_FS is not set + CONFIG_INOTIFY=y + CONFIG_INOTIFY_USER=y + # CONFIG_QUOTA is not set ++CONFIG_DNOTIFY=y + # CONFIG_AUTOFS_FS is not set + CONFIG_AUTOFS4_FS=y + # CONFIG_FUSE_FS is not set +@@ -1022,13 +897,16 @@ + CONFIG_PROC_FS=y + CONFIG_PROC_KCORE=y + CONFIG_PROC_SYSCTL=y +-CONFIG_PROC_PAGE_MONITOR=y + CONFIG_SYSFS=y + CONFIG_TMPFS=y + # CONFIG_TMPFS_POSIX_ACL is not set + # CONFIG_HUGETLB_PAGE is not set ++CONFIG_RAMFS=y + # CONFIG_CONFIGFS_FS is not set +-CONFIG_MISC_FILESYSTEMS=y ++ ++# ++# Miscellaneous filesystems ++# + # CONFIG_ADFS_FS is not set + # CONFIG_AFFS_FS is not set + # CONFIG_ECRYPT_FS is not set +@@ -1038,33 +916,34 @@ + # CONFIG_BFS_FS is not set + # CONFIG_EFS_FS is not set + # CONFIG_CRAMFS is not set +-# CONFIG_SQUASHFS is not set + # CONFIG_VXFS_FS is not set +-# CONFIG_MINIX_FS is not set +-# CONFIG_OMFS_FS is not set + # CONFIG_HPFS_FS is not set + # CONFIG_QNX4FS_FS is not set +-# CONFIG_ROMFS_FS is not set + # CONFIG_SYSV_FS is not set + CONFIG_UFS_FS=m + # CONFIG_UFS_FS_WRITE is not set + # CONFIG_UFS_DEBUG is not set +-CONFIG_NETWORK_FILESYSTEMS=y ++ ++# ++# Network File Systems ++# + CONFIG_NFS_FS=m + CONFIG_NFS_V3=y + # CONFIG_NFS_V3_ACL is not set + CONFIG_NFS_V4=y ++CONFIG_NFS_DIRECTIO=y + CONFIG_NFSD=m + CONFIG_NFSD_V3=y + # CONFIG_NFSD_V3_ACL is not set + CONFIG_NFSD_V4=y ++CONFIG_NFSD_TCP=y + CONFIG_LOCKD=m + CONFIG_LOCKD_V4=y + CONFIG_EXPORTFS=m + CONFIG_NFS_COMMON=y + CONFIG_SUNRPC=m + CONFIG_SUNRPC_GSS=m +-# CONFIG_SUNRPC_REGISTER_V4 is not set ++# CONFIG_SUNRPC_BIND34 is not set + CONFIG_RPCSEC_GSS_KRB5=m + CONFIG_RPCSEC_GSS_SPKM3=m + CONFIG_SMB_FS=m +@@ -1073,7 +952,6 @@ + CONFIG_CIFS=m + # CONFIG_CIFS_STATS is not set + # CONFIG_CIFS_WEAK_PW_HASH is not set +-# CONFIG_CIFS_UPCALL is not set + # CONFIG_CIFS_XATTR is not set + # CONFIG_CIFS_DEBUG2 is not set + # CONFIG_CIFS_EXPERIMENTAL is not set +@@ -1086,6 +964,10 @@ + # + # CONFIG_PARTITION_ADVANCED is not set + CONFIG_MSDOS_PARTITION=y ++ ++# ++# Native Language Support ++# + CONFIG_NLS=y + CONFIG_NLS_DEFAULT="iso8859-1" + CONFIG_NLS_CODEPAGE_437=m +@@ -1126,28 +1008,33 @@ + # CONFIG_NLS_KOI8_R is not set + # CONFIG_NLS_KOI8_U is not set + CONFIG_NLS_UTF8=m ++ ++# ++# Distributed Lock Manager ++# + # CONFIG_DLM is not set + + # ++# Profiling support ++# ++CONFIG_PROFILING=y ++CONFIG_OPROFILE=m ++ ++# + # Kernel hacking + # + # CONFIG_PRINTK_TIME is not set +-CONFIG_ENABLE_WARN_DEPRECATED=y + CONFIG_ENABLE_MUST_CHECK=y +-CONFIG_FRAME_WARN=2048 + CONFIG_MAGIC_SYSRQ=y + # CONFIG_UNUSED_SYMBOLS is not set +-CONFIG_DEBUG_FS=y ++# CONFIG_DEBUG_FS is not set + CONFIG_HEADERS_CHECK=y + CONFIG_DEBUG_KERNEL=y + # CONFIG_DEBUG_SHIRQ is not set + CONFIG_DETECT_SOFTLOCKUP=y +-# CONFIG_BOOTPARAM_SOFTLOCKUP_PANIC is not set +-CONFIG_BOOTPARAM_SOFTLOCKUP_PANIC_VALUE=0 + CONFIG_SCHED_DEBUG=y + # CONFIG_SCHEDSTATS is not set + # CONFIG_TIMER_STATS is not set +-# CONFIG_DEBUG_OBJECTS is not set + # CONFIG_DEBUG_SLAB is not set + # CONFIG_DEBUG_RT_MUTEXES is not set + # CONFIG_RT_MUTEX_TESTER is not set +@@ -1159,33 +1046,10 @@ + # CONFIG_DEBUG_BUGVERBOSE is not set + # CONFIG_DEBUG_INFO is not set + # CONFIG_DEBUG_VM is not set +-# CONFIG_DEBUG_WRITECOUNT is not set +-# CONFIG_DEBUG_MEMORY_INIT is not set + # CONFIG_DEBUG_LIST is not set +-# CONFIG_DEBUG_SG is not set +-# CONFIG_DEBUG_NOTIFIERS is not set +-# CONFIG_BOOT_PRINTK_DELAY is not set ++CONFIG_FORCED_INLINING=y + # CONFIG_RCU_TORTURE_TEST is not set +-# CONFIG_RCU_CPU_STALL_DETECTOR is not set +-# CONFIG_BACKTRACE_SELF_TEST is not set +-# CONFIG_DEBUG_BLOCK_EXT_DEVT is not set + # CONFIG_FAULT_INJECTION is not set +-# CONFIG_SYSCTL_SYSCALL_CHECK is not set +-CONFIG_NOP_TRACER=y +-CONFIG_RING_BUFFER=y +-CONFIG_TRACING=y +- +-# +-# Tracers +-# +-# CONFIG_SCHED_TRACER is not set +-# CONFIG_CONTEXT_SWITCH_TRACER is not set +-# CONFIG_BOOT_TRACER is not set +-# CONFIG_TRACE_BRANCH_PROFILING is not set +-# CONFIG_FTRACE_STARTUP_TEST is not set +-# CONFIG_BUILD_DOCSRC is not set +-# CONFIG_DYNAMIC_PRINTK_DEBUG is not set +-# CONFIG_SAMPLES is not set + # CONFIG_DEBUG_RODATA is not set + + # +@@ -1194,112 +1058,56 @@ + CONFIG_KEYS=y + CONFIG_KEYS_DEBUG_PROC_KEYS=y + # CONFIG_SECURITY is not set +-# CONFIG_SECURITYFS is not set +-# CONFIG_SECURITY_FILE_CAPABILITIES is not set + CONFIG_CRYPTO=y +- +-# +-# Crypto core or helper +-# +-# CONFIG_CRYPTO_FIPS is not set + CONFIG_CRYPTO_ALGAPI=y +-CONFIG_CRYPTO_ALGAPI2=y +-CONFIG_CRYPTO_AEAD=m +-CONFIG_CRYPTO_AEAD2=y + CONFIG_CRYPTO_BLKCIPHER=m +-CONFIG_CRYPTO_BLKCIPHER2=y + CONFIG_CRYPTO_HASH=y +-CONFIG_CRYPTO_HASH2=y +-CONFIG_CRYPTO_RNG2=y + CONFIG_CRYPTO_MANAGER=y +-CONFIG_CRYPTO_MANAGER2=y +-# CONFIG_CRYPTO_GF128MUL is not set +-CONFIG_CRYPTO_NULL=m +-# CONFIG_CRYPTO_CRYPTD is not set +-CONFIG_CRYPTO_AUTHENC=m +-CONFIG_CRYPTO_TEST=m +- +-# +-# Authenticated Encryption with Associated Data +-# +-# CONFIG_CRYPTO_CCM is not set +-# CONFIG_CRYPTO_GCM is not set +-# CONFIG_CRYPTO_SEQIV is not set +- +-# +-# Block modes +-# +-CONFIG_CRYPTO_CBC=m +-# CONFIG_CRYPTO_CTR is not set +-# CONFIG_CRYPTO_CTS is not set +-# CONFIG_CRYPTO_ECB is not set +-# CONFIG_CRYPTO_LRW is not set +-# CONFIG_CRYPTO_PCBC is not set +-# CONFIG_CRYPTO_XTS is not set +- +-# +-# Hash modes +-# + CONFIG_CRYPTO_HMAC=y + # CONFIG_CRYPTO_XCBC is not set +- +-# +-# Digest +-# +-CONFIG_CRYPTO_CRC32C=m ++CONFIG_CRYPTO_NULL=m + # CONFIG_CRYPTO_MD4 is not set + CONFIG_CRYPTO_MD5=y +-# CONFIG_CRYPTO_MICHAEL_MIC is not set +-# CONFIG_CRYPTO_RMD128 is not set +-# CONFIG_CRYPTO_RMD160 is not set +-# CONFIG_CRYPTO_RMD256 is not set +-# CONFIG_CRYPTO_RMD320 is not set + CONFIG_CRYPTO_SHA1=m + # CONFIG_CRYPTO_SHA256 is not set + # CONFIG_CRYPTO_SHA512 is not set +-# CONFIG_CRYPTO_TGR192 is not set + # CONFIG_CRYPTO_WP512 is not set +- +-# +-# Ciphers +-# +-# CONFIG_CRYPTO_AES is not set +-# CONFIG_CRYPTO_ANUBIS is not set +-# CONFIG_CRYPTO_ARC4 is not set ++# CONFIG_CRYPTO_TGR192 is not set ++# CONFIG_CRYPTO_GF128MUL is not set ++# CONFIG_CRYPTO_ECB is not set ++CONFIG_CRYPTO_CBC=m ++# CONFIG_CRYPTO_PCBC is not set ++# CONFIG_CRYPTO_LRW is not set ++# CONFIG_CRYPTO_XTS is not set ++# CONFIG_CRYPTO_CRYPTD is not set ++CONFIG_CRYPTO_DES=m ++# CONFIG_CRYPTO_FCRYPT is not set + CONFIG_CRYPTO_BLOWFISH=m +-# CONFIG_CRYPTO_CAMELLIA is not set ++# CONFIG_CRYPTO_TWOFISH is not set ++# CONFIG_CRYPTO_SERPENT is not set ++# CONFIG_CRYPTO_AES is not set + CONFIG_CRYPTO_CAST5=m + # CONFIG_CRYPTO_CAST6 is not set +-CONFIG_CRYPTO_DES=m +-# CONFIG_CRYPTO_FCRYPT is not set ++# CONFIG_CRYPTO_TEA is not set ++# CONFIG_CRYPTO_ARC4 is not set + # CONFIG_CRYPTO_KHAZAD is not set +-# CONFIG_CRYPTO_SALSA20 is not set ++# CONFIG_CRYPTO_ANUBIS is not set + # CONFIG_CRYPTO_SEED is not set +-# CONFIG_CRYPTO_SERPENT is not set +-# CONFIG_CRYPTO_TEA is not set +-# CONFIG_CRYPTO_TWOFISH is not set +- +-# +-# Compression +-# + CONFIG_CRYPTO_DEFLATE=m +-# CONFIG_CRYPTO_LZO is not set +- +-# +-# Random Number Generation +-# +-# CONFIG_CRYPTO_ANSI_CPRNG is not set ++# CONFIG_CRYPTO_MICHAEL_MIC is not set ++CONFIG_CRYPTO_CRC32C=m ++# CONFIG_CRYPTO_CAMELLIA is not set ++CONFIG_CRYPTO_TEST=m ++# CONFIG_CRYPTO_AUTHENC is not set + # CONFIG_CRYPTO_HW is not set + + # + # Library routines + # + CONFIG_BITREVERSE=y +-CONFIG_GENERIC_FIND_LAST_BIT=y + CONFIG_CRC_CCITT=m + # CONFIG_CRC16 is not set +-# CONFIG_CRC_T10DIF is not set +-CONFIG_CRC_ITU_T=m ++# CONFIG_CRC_ITU_T is not set + CONFIG_CRC32=y + # CONFIG_CRC7 is not set + CONFIG_LIBCRC32C=m +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/arch/parisc/configs/b180_defconfig linux-2.6.29-rc3.owrt/arch/parisc/configs/b180_defconfig +--- linux-2.6.29.owrt/arch/parisc/configs/b180_defconfig 2009-05-10 22:04:39.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/arch/parisc/configs/b180_defconfig 2009-05-10 23:48:28.000000000 +0200 +@@ -1,7 +1,7 @@ + # + # Automatically generated make config: don't edit +-# Linux kernel version: 2.6.29-rc8 +-# Fri Mar 13 01:32:57 2009 ++# Linux kernel version: 2.6.23 ++# Fri Oct 12 21:16:46 2007 + # + CONFIG_PARISC=y + CONFIG_MMU=y +@@ -33,29 +33,13 @@ + # CONFIG_BSD_PROCESS_ACCT is not set + # CONFIG_TASKSTATS is not set + # CONFIG_AUDIT is not set +- +-# +-# RCU Subsystem +-# +-CONFIG_CLASSIC_RCU=y +-# CONFIG_TREE_RCU is not set +-# CONFIG_PREEMPT_RCU is not set +-# CONFIG_TREE_RCU_TRACE is not set +-# CONFIG_PREEMPT_RCU_TRACE is not set + CONFIG_IKCONFIG=y + CONFIG_IKCONFIG_PROC=y + CONFIG_LOG_BUF_SHIFT=16 +-# CONFIG_CGROUPS is not set + CONFIG_SYSFS_DEPRECATED=y +-CONFIG_SYSFS_DEPRECATED_V2=y + # CONFIG_RELAY is not set +-CONFIG_NAMESPACES=y +-# CONFIG_UTS_NS is not set +-# CONFIG_IPC_NS is not set + # CONFIG_BLK_DEV_INITRD is not set +-CONFIG_CC_OPTIMIZE_FOR_SIZE=y + CONFIG_SYSCTL=y +-CONFIG_ANON_INODES=y + # CONFIG_EMBEDDED is not set + CONFIG_SYSCTL_SYSCALL=y + CONFIG_KALLSYMS=y +@@ -67,34 +51,27 @@ + CONFIG_ELF_CORE=y + CONFIG_BASE_FULL=y + CONFIG_FUTEX=y ++CONFIG_ANON_INODES=y + CONFIG_EPOLL=y + CONFIG_SIGNALFD=y +-CONFIG_TIMERFD=y + CONFIG_EVENTFD=y + CONFIG_SHMEM=y +-CONFIG_AIO=y + CONFIG_VM_EVENT_COUNTERS=y +-CONFIG_PCI_QUIRKS=y +-CONFIG_COMPAT_BRK=y + CONFIG_SLAB=y + # CONFIG_SLUB is not set + # CONFIG_SLOB is not set +-# CONFIG_PROFILING is not set +-CONFIG_HAVE_OPROFILE=y +-# CONFIG_HAVE_GENERIC_DMA_COHERENT is not set +-CONFIG_SLABINFO=y + CONFIG_RT_MUTEXES=y ++# CONFIG_TINY_SHMEM is not set + CONFIG_BASE_SMALL=0 + CONFIG_MODULES=y +-# CONFIG_MODULE_FORCE_LOAD is not set + # CONFIG_MODULE_UNLOAD is not set + CONFIG_MODVERSIONS=y + # CONFIG_MODULE_SRCVERSION_ALL is not set +-CONFIG_INIT_ALL_POSSIBLE=y ++# CONFIG_KMOD is not set + CONFIG_BLOCK=y + # CONFIG_LBD is not set + # CONFIG_BLK_DEV_IO_TRACE is not set +-# CONFIG_BLK_DEV_INTEGRITY is not set ++# CONFIG_LSF is not set + + # + # IO Schedulers +@@ -108,7 +85,6 @@ + CONFIG_DEFAULT_CFQ=y + # CONFIG_DEFAULT_NOOP is not set + CONFIG_DEFAULT_IOSCHED="cfq" +-# CONFIG_FREEZER is not set + + # + # Processor type and features +@@ -132,15 +108,13 @@ + # CONFIG_HZ_300 is not set + # CONFIG_HZ_1000 is not set + CONFIG_HZ=250 +-# CONFIG_SCHED_HRTICK is not set + CONFIG_FLATMEM=y + CONFIG_FLAT_NODE_MEM_MAP=y +-CONFIG_PAGEFLAGS_EXTENDED=y ++# CONFIG_SPARSEMEM_STATIC is not set + CONFIG_SPLIT_PTLOCK_CPUS=4096 +-# CONFIG_PHYS_ADDR_T_64BIT is not set ++# CONFIG_RESOURCES_64BIT is not set + CONFIG_ZONE_DMA_FLAG=0 + CONFIG_VIRT_TO_BUS=y +-CONFIG_UNEVICTABLE_LRU=y + # CONFIG_HPUX is not set + + # +@@ -156,14 +130,14 @@ + CONFIG_ISA=y + CONFIG_PCI=y + # CONFIG_ARCH_SUPPORTS_MSI is not set +-CONFIG_PCI_LEGACY=y + # CONFIG_PCI_DEBUG is not set +-# CONFIG_PCI_STUB is not set + CONFIG_GSC_DINO=y + # CONFIG_PCI_LBA is not set +-CONFIG_IOMMU_HELPER=y ++ ++# ++# PCCARD (PCMCIA/CardBus) support ++# + # CONFIG_PCCARD is not set +-# CONFIG_HOTPLUG_PCI is not set + + # + # PA-RISC specific drivers +@@ -177,15 +151,16 @@ + # Executable file formats + # + CONFIG_BINFMT_ELF=y +-# CONFIG_CORE_DUMP_DEFAULT_ELF_HEADERS is not set +-# CONFIG_HAVE_AOUT is not set + # CONFIG_BINFMT_MISC is not set ++ ++# ++# Networking ++# + CONFIG_NET=y + + # + # Networking options + # +-CONFIG_COMPAT_NET_DEV_OPS=y + CONFIG_PACKET=y + CONFIG_PACKET_MMAP=y + CONFIG_UNIX=y +@@ -230,37 +205,36 @@ + CONFIG_INET6_XFRM_MODE_TUNNEL=y + CONFIG_INET6_XFRM_MODE_BEET=y + CONFIG_IPV6_SIT=y +-CONFIG_IPV6_NDISC_NODETYPE=y + # CONFIG_IPV6_TUNNEL is not set + # CONFIG_NETLABEL is not set + # CONFIG_NETWORK_SECMARK is not set + # CONFIG_NETFILTER is not set +-# CONFIG_ATM is not set + # CONFIG_BRIDGE is not set + # CONFIG_VLAN_8021Q is not set + # CONFIG_DECNET is not set + # CONFIG_LLC2 is not set + # CONFIG_IPX is not set + # CONFIG_ATALK is not set ++ ++# ++# QoS and/or fair queueing ++# + # CONFIG_NET_SCHED is not set +-# CONFIG_DCB is not set + + # + # Network testing + # + # CONFIG_NET_PKTGEN is not set + # CONFIG_HAMRADIO is not set +-# CONFIG_CAN is not set + # CONFIG_IRDA is not set + # CONFIG_BT is not set +-# CONFIG_PHONET is not set +-CONFIG_WIRELESS=y ++ ++# ++# Wireless ++# + # CONFIG_CFG80211 is not set +-CONFIG_WIRELESS_OLD_REGULATORY=y + # CONFIG_WIRELESS_EXT is not set +-# CONFIG_LIB80211 is not set +-# CONFIG_MAC80211 is not set +-# CONFIG_WIMAX is not set ++# CONFIG_IEEE80211 is not set + # CONFIG_RFKILL is not set + + # +@@ -273,9 +247,7 @@ + CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug" + CONFIG_STANDALONE=y + # CONFIG_PREVENT_FIRMWARE_BUILD is not set +-CONFIG_FW_LOADER=y +-CONFIG_FIRMWARE_IN_KERNEL=y +-CONFIG_EXTRA_FIRMWARE="" ++# CONFIG_FW_LOADER is not set + # CONFIG_DEBUG_DRIVER is not set + # CONFIG_DEBUG_DEVRES is not set + # CONFIG_SYS_HYPERVISOR is not set +@@ -303,18 +275,10 @@ + CONFIG_CDROM_PKTCDVD=m + CONFIG_CDROM_PKTCDVD_BUFFERS=8 + CONFIG_ATA_OVER_ETH=y +-# CONFIG_BLK_DEV_HD is not set + CONFIG_MISC_DEVICES=y + # CONFIG_PHANTOM is not set +-# CONFIG_SGI_IOC4 is not set +-# CONFIG_ENCLOSURE_SERVICES is not set +-# CONFIG_HP_ILO is not set +- +-# +-# EEPROM support +-# + # CONFIG_EEPROM_93CX6 is not set +-CONFIG_HAVE_IDE=y ++# CONFIG_SGI_IOC4 is not set + # CONFIG_IDE is not set + + # +@@ -353,10 +317,8 @@ + # CONFIG_SCSI_FC_ATTRS is not set + # CONFIG_SCSI_ISCSI_ATTRS is not set + # CONFIG_SCSI_SAS_LIBSAS is not set +-# CONFIG_SCSI_SRP_ATTRS is not set + CONFIG_SCSI_LOWLEVEL=y + # CONFIG_ISCSI_TCP is not set +-# CONFIG_SCSI_CXGB3_ISCSI is not set + # CONFIG_BLK_DEV_3W_XXXX_RAID is not set + # CONFIG_SCSI_3W_9XXX is not set + # CONFIG_SCSI_ACARD is not set +@@ -368,15 +330,12 @@ + # CONFIG_SCSI_AIC79XX is not set + # CONFIG_SCSI_AIC94XX is not set + # CONFIG_SCSI_DPT_I2O is not set +-# CONFIG_SCSI_ADVANSYS is not set + # CONFIG_SCSI_IN2000 is not set + # CONFIG_SCSI_ARCMSR is not set + # CONFIG_MEGARAID_NEWGEN is not set + # CONFIG_MEGARAID_LEGACY is not set + # CONFIG_MEGARAID_SAS is not set + # CONFIG_SCSI_HPTIOP is not set +-# CONFIG_LIBFC is not set +-# CONFIG_FCOE is not set + # CONFIG_SCSI_DMX3191D is not set + # CONFIG_SCSI_DTC3280 is not set + # CONFIG_SCSI_FUTURE_DOMAIN is not set +@@ -387,7 +346,6 @@ + # CONFIG_SCSI_INIA100 is not set + # CONFIG_SCSI_PPA is not set + # CONFIG_SCSI_IMM is not set +-# CONFIG_SCSI_MVSAS is not set + # CONFIG_SCSI_NCR53C406A is not set + CONFIG_SCSI_LASI700=y + CONFIG_53C700_LE_ON_BE=y +@@ -402,6 +360,7 @@ + CONFIG_SCSI_NCR53C8XX_MAX_TAGS=32 + CONFIG_SCSI_NCR53C8XX_SYNC=40 + # CONFIG_SCSI_PAS16 is not set ++# CONFIG_SCSI_PSI240I is not set + # CONFIG_SCSI_QLOGIC_FAS is not set + # CONFIG_SCSI_QLOGIC_1280 is not set + # CONFIG_SCSI_QLA_FC is not set +@@ -414,11 +373,9 @@ + # CONFIG_SCSI_NSP32 is not set + # CONFIG_SCSI_DEBUG is not set + # CONFIG_SCSI_SRP is not set +-# CONFIG_SCSI_DH is not set + # CONFIG_ATA is not set + CONFIG_MD=y + CONFIG_BLK_DEV_MD=y +-CONFIG_MD_AUTODETECT=y + CONFIG_MD_LINEAR=y + CONFIG_MD_RAID0=y + CONFIG_MD_RAID1=y +@@ -426,18 +383,26 @@ + # CONFIG_MD_MULTIPATH is not set + # CONFIG_MD_FAULTY is not set + # CONFIG_BLK_DEV_DM is not set ++ ++# ++# Fusion MPT device support ++# + # CONFIG_FUSION is not set ++# CONFIG_FUSION_SPI is not set ++# CONFIG_FUSION_FC is not set ++# CONFIG_FUSION_SAS is not set + + # + # IEEE 1394 (FireWire) support + # + + # +-# A new alternative FireWire stack is available with EXPERIMENTAL=y ++# An alternative FireWire stack is available with EXPERIMENTAL=y + # + # CONFIG_IEEE1394 is not set + # CONFIG_I2O is not set + CONFIG_NETDEVICES=y ++# CONFIG_NETDEVICES_MULTIQUEUE is not set + # CONFIG_DUMMY is not set + # CONFIG_BONDING is not set + # CONFIG_EQUALIZER is not set +@@ -469,49 +434,36 @@ + # CONFIG_IBM_NEW_EMAC_RGMII is not set + # CONFIG_IBM_NEW_EMAC_TAH is not set + # CONFIG_IBM_NEW_EMAC_EMAC4 is not set +-# CONFIG_IBM_NEW_EMAC_NO_FLOW_CTRL is not set +-# CONFIG_IBM_NEW_EMAC_MAL_CLR_ICINTSTAT is not set +-# CONFIG_IBM_NEW_EMAC_MAL_COMMON_ERR is not set + # CONFIG_NET_PCI is not set + # CONFIG_B44 is not set +-# CONFIG_CS89x0 is not set + # CONFIG_NET_POCKET is not set +-# CONFIG_ATL2 is not set + CONFIG_NETDEV_1000=y + # CONFIG_ACENIC is not set + # CONFIG_DL2K is not set + # CONFIG_E1000 is not set + # CONFIG_E1000E is not set +-# CONFIG_IGB is not set + # CONFIG_NS83820 is not set + # CONFIG_HAMACHI is not set + # CONFIG_R8169 is not set + # CONFIG_SIS190 is not set + # CONFIG_SKGE is not set + # CONFIG_SKY2 is not set ++# CONFIG_SK98LIN is not set + # CONFIG_VIA_VELOCITY is not set + # CONFIG_TIGON3 is not set + # CONFIG_BNX2 is not set + # CONFIG_QLA3XXX is not set +-# CONFIG_ATL1 is not set +-# CONFIG_JME is not set + CONFIG_NETDEV_10000=y + # CONFIG_CHELSIO_T1 is not set +-CONFIG_CHELSIO_T3_DEPENDS=y + # CONFIG_CHELSIO_T3 is not set +-# CONFIG_ENIC is not set + # CONFIG_IXGBE is not set + # CONFIG_IXGB is not set + # CONFIG_S2IO is not set + # CONFIG_MYRI10GE is not set + # CONFIG_NETXEN_NIC is not set + # CONFIG_NIU is not set +-# CONFIG_MLX4_EN is not set + # CONFIG_MLX4_CORE is not set + # CONFIG_TEHUTI is not set +-# CONFIG_BNX2X is not set +-# CONFIG_QLGE is not set +-# CONFIG_SFC is not set + # CONFIG_TR is not set + + # +@@ -519,11 +471,6 @@ + # + # CONFIG_WLAN_PRE80211 is not set + # CONFIG_WLAN_80211 is not set +-# CONFIG_IWLWIFI_LEDS is not set +- +-# +-# Enable WiMAX (Networking options) to see the WiMAX drivers +-# + # CONFIG_WAN is not set + # CONFIG_FDDI is not set + # CONFIG_PLIP is not set +@@ -556,6 +503,7 @@ + CONFIG_INPUT_MOUSEDEV_SCREEN_X=1024 + CONFIG_INPUT_MOUSEDEV_SCREEN_Y=768 + # CONFIG_INPUT_JOYDEV is not set ++# CONFIG_INPUT_TSDEV is not set + CONFIG_INPUT_EVDEV=y + # CONFIG_INPUT_EVBUG is not set + +@@ -578,12 +526,11 @@ + CONFIG_MOUSE_PS2_ALPS=y + CONFIG_MOUSE_PS2_LOGIPS2PP=y + CONFIG_MOUSE_PS2_SYNAPTICS=y ++CONFIG_MOUSE_PS2_LIFEBOOK=y + CONFIG_MOUSE_PS2_TRACKPOINT=y +-# CONFIG_MOUSE_PS2_ELANTECH is not set + # CONFIG_MOUSE_PS2_TOUCHKIT is not set + # CONFIG_MOUSE_SERIAL is not set + # CONFIG_MOUSE_APPLETOUCH is not set +-# CONFIG_MOUSE_BCM5974 is not set + # CONFIG_MOUSE_INPORT is not set + # CONFIG_MOUSE_LOGIBM is not set + # CONFIG_MOUSE_PC110PAD is not set +@@ -617,11 +564,9 @@ + # Character devices + # + CONFIG_VT=y +-CONFIG_CONSOLE_TRANSLATIONS=y + CONFIG_VT_CONSOLE=y + CONFIG_HW_CONSOLE=y + # CONFIG_VT_HW_CONSOLE_BINDING is not set +-CONFIG_DEVKMEM=y + # CONFIG_SERIAL_NONSTANDARD is not set + + # +@@ -653,79 +598,75 @@ + CONFIG_SERIAL_CORE_CONSOLE=y + # CONFIG_SERIAL_JSM is not set + CONFIG_UNIX98_PTYS=y +-# CONFIG_DEVPTS_MULTIPLE_INSTANCES is not set + CONFIG_LEGACY_PTYS=y + CONFIG_LEGACY_PTY_COUNT=256 + CONFIG_PRINTER=y + # CONFIG_LP_CONSOLE is not set + # CONFIG_PPDEV is not set ++# CONFIG_TIPAR is not set + # CONFIG_IPMI_HANDLER is not set ++# CONFIG_WATCHDOG is not set + # CONFIG_HW_RANDOM is not set ++CONFIG_GEN_RTC=y ++# CONFIG_GEN_RTC_X is not set + # CONFIG_DTLK is not set + # CONFIG_R3964 is not set + # CONFIG_APPLICOM is not set ++# CONFIG_AGP is not set ++# CONFIG_DRM is not set + # CONFIG_RAW_DRIVER is not set + CONFIG_DEVPORT=y + # CONFIG_I2C is not set ++ ++# ++# SPI support ++# + # CONFIG_SPI is not set ++# CONFIG_SPI_MASTER is not set + # CONFIG_W1 is not set + # CONFIG_POWER_SUPPLY is not set + # CONFIG_HWMON is not set +-# CONFIG_THERMAL is not set +-# CONFIG_THERMAL_HWMON is not set +-# CONFIG_WATCHDOG is not set +-CONFIG_SSB_POSSIBLE=y + + # + # Sonics Silicon Backplane + # ++CONFIG_SSB_POSSIBLE=y + # CONFIG_SSB is not set + + # + # Multifunction device drivers + # +-# CONFIG_MFD_CORE is not set + # CONFIG_MFD_SM501 is not set +-# CONFIG_HTC_PASIC3 is not set +-# CONFIG_MFD_TMIO is not set +-# CONFIG_REGULATOR is not set + + # + # Multimedia devices + # +- +-# +-# Multimedia core support +-# + # CONFIG_VIDEO_DEV is not set + # CONFIG_DVB_CORE is not set +-# CONFIG_VIDEO_MEDIA is not set ++# CONFIG_DAB is not set + + # +-# Multimedia drivers ++# Graphics support + # +-# CONFIG_DAB is not set ++# CONFIG_BACKLIGHT_LCD_SUPPORT is not set + + # +-# Graphics support ++# Display device support + # +-# CONFIG_AGP is not set +-# CONFIG_DRM is not set ++# CONFIG_DISPLAY_SUPPORT is not set + # CONFIG_VGASTATE is not set + CONFIG_VIDEO_OUTPUT_CONTROL=m + CONFIG_FB=y + # CONFIG_FIRMWARE_EDID is not set + # CONFIG_FB_DDC is not set +-# CONFIG_FB_BOOT_VESA_SUPPORT is not set + CONFIG_FB_CFB_FILLRECT=y + CONFIG_FB_CFB_COPYAREA=y + CONFIG_FB_CFB_IMAGEBLIT=y +-# CONFIG_FB_CFB_REV_PIXELS_IN_BYTE is not set + # CONFIG_FB_SYS_FILLRECT is not set + # CONFIG_FB_SYS_COPYAREA is not set + # CONFIG_FB_SYS_IMAGEBLIT is not set +-# CONFIG_FB_FOREIGN_ENDIAN is not set + # CONFIG_FB_SYS_FOPS is not set ++CONFIG_FB_DEFERRED_IO=y + # CONFIG_FB_SVGALIB is not set + # CONFIG_FB_MACMODES is not set + # CONFIG_FB_BACKLIGHT is not set +@@ -750,7 +691,6 @@ + # CONFIG_FB_ATY is not set + # CONFIG_FB_S3 is not set + # CONFIG_FB_SIS is not set +-# CONFIG_FB_VIA is not set + # CONFIG_FB_NEOMAGIC is not set + # CONFIG_FB_KYRO is not set + # CONFIG_FB_3DFX is not set +@@ -758,16 +698,7 @@ + # CONFIG_FB_VT8623 is not set + # CONFIG_FB_TRIDENT is not set + # CONFIG_FB_ARK is not set +-# CONFIG_FB_CARMINE is not set + # CONFIG_FB_VIRTUAL is not set +-# CONFIG_FB_METRONOME is not set +-# CONFIG_FB_MB862XX is not set +-# CONFIG_BACKLIGHT_LCD_SUPPORT is not set +- +-# +-# Display device support +-# +-# CONFIG_DISPLAY_SUPPORT is not set + + # + # Console display driver support +@@ -787,8 +718,15 @@ + CONFIG_LOGO_LINUX_VGA16=y + CONFIG_LOGO_LINUX_CLUT224=y + CONFIG_LOGO_PARISC_CLUT224=y ++ ++# ++# Sound ++# + CONFIG_SOUND=y +-CONFIG_SOUND_OSS_CORE=y ++ ++# ++# Advanced Linux Sound Architecture ++# + CONFIG_SND=y + CONFIG_SND_TIMER=y + CONFIG_SND_PCM=y +@@ -804,7 +742,10 @@ + CONFIG_SND_VERBOSE_PROCFS=y + # CONFIG_SND_VERBOSE_PRINTK is not set + # CONFIG_SND_DEBUG is not set +-CONFIG_SND_DRIVERS=y ++ ++# ++# Generic devices ++# + # CONFIG_SND_DUMMY is not set + # CONFIG_SND_VIRMIDI is not set + # CONFIG_SND_MTPAV is not set +@@ -812,7 +753,10 @@ + # CONFIG_SND_SERIAL_U16550 is not set + # CONFIG_SND_MPU401 is not set + # CONFIG_SND_PORTMAN2X4 is not set +-CONFIG_SND_PCI=y ++ ++# ++# PCI devices ++# + # CONFIG_SND_AD1889 is not set + # CONFIG_SND_ALS300 is not set + # CONFIG_SND_ALI5451 is not set +@@ -821,11 +765,9 @@ + # CONFIG_SND_AU8810 is not set + # CONFIG_SND_AU8820 is not set + # CONFIG_SND_AU8830 is not set +-# CONFIG_SND_AW2 is not set + # CONFIG_SND_BT87X is not set + # CONFIG_SND_CA0106 is not set + # CONFIG_SND_CMIPCI is not set +-# CONFIG_SND_OXYGEN is not set + # CONFIG_SND_CS4281 is not set + # CONFIG_SND_CS46XX is not set + # CONFIG_SND_DARLA20 is not set +@@ -850,7 +792,6 @@ + # CONFIG_SND_HDA_INTEL is not set + # CONFIG_SND_HDSP is not set + # CONFIG_SND_HDSPM is not set +-# CONFIG_SND_HIFIER is not set + # CONFIG_SND_ICE1712 is not set + # CONFIG_SND_ICE1724 is not set + # CONFIG_SND_INTEL8X0 is not set +@@ -868,23 +809,30 @@ + # CONFIG_SND_TRIDENT is not set + # CONFIG_SND_VIA82XX is not set + # CONFIG_SND_VIA82XX_MODEM is not set +-# CONFIG_SND_VIRTUOSO is not set + # CONFIG_SND_VX222 is not set + # CONFIG_SND_YMFPCI is not set +-CONFIG_SND_GSC=y ++ ++# ++# GSC devices ++# + CONFIG_SND_HARMONY=y ++ ++# ++# System on Chip audio support ++# + # CONFIG_SND_SOC is not set ++ ++# ++# SoC Audio support for SuperH ++# ++ ++# ++# Open Sound System ++# + # CONFIG_SOUND_PRIME is not set + CONFIG_HID_SUPPORT=y + CONFIG_HID=y + CONFIG_HID_DEBUG=y +-# CONFIG_HIDRAW is not set +-# CONFIG_HID_PID is not set +- +-# +-# Special HID drivers +-# +-CONFIG_HID_COMPAT=y + CONFIG_USB_SUPPORT=y + CONFIG_USB_ARCH_HAS_HCD=y + CONFIG_USB_ARCH_HAS_OHCI=y +@@ -892,63 +840,36 @@ + # CONFIG_USB is not set + + # +-# Enable Host or Gadget support to see Inventra options ++# NOTE: USB_STORAGE enables SCSI, and 'SCSI disk support' + # + + # +-# NOTE: USB_STORAGE depends on SCSI but BLK_DEV_SD may also be needed; ++# USB Gadget Support + # + # CONFIG_USB_GADGET is not set +- +-# +-# OTG and related infrastructure +-# + # CONFIG_MMC is not set +-# CONFIG_MEMSTICK is not set + # CONFIG_NEW_LEDS is not set +-# CONFIG_ACCESSIBILITY is not set + # CONFIG_INFINIBAND is not set +-CONFIG_RTC_LIB=y +-CONFIG_RTC_CLASS=y +-CONFIG_RTC_HCTOSYS=y +-CONFIG_RTC_HCTOSYS_DEVICE="rtc0" +-# CONFIG_RTC_DEBUG is not set ++# CONFIG_RTC_CLASS is not set + + # +-# RTC interfaces ++# DMA Engine support + # +-CONFIG_RTC_INTF_SYSFS=y +-CONFIG_RTC_INTF_PROC=y +-CONFIG_RTC_INTF_DEV=y +-# CONFIG_RTC_INTF_DEV_UIE_EMUL is not set +-# CONFIG_RTC_DRV_TEST is not set ++# CONFIG_DMA_ENGINE is not set + + # +-# SPI RTC drivers ++# DMA Clients + # + + # +-# Platform RTC drivers ++# DMA Devices + # +-# CONFIG_RTC_DRV_DS1286 is not set +-# CONFIG_RTC_DRV_DS1511 is not set +-# CONFIG_RTC_DRV_DS1553 is not set +-# CONFIG_RTC_DRV_DS1742 is not set +-# CONFIG_RTC_DRV_STK17TA8 is not set +-# CONFIG_RTC_DRV_M48T86 is not set +-# CONFIG_RTC_DRV_M48T35 is not set +-# CONFIG_RTC_DRV_M48T59 is not set +-# CONFIG_RTC_DRV_BQ4802 is not set +-# CONFIG_RTC_DRV_V3020 is not set ++# CONFIG_AUXDISPLAY is not set + + # +-# on-CPU RTC drivers ++# Userspace I/O + # +-CONFIG_RTC_DRV_PARISC=y +-# CONFIG_DMADEVICES is not set +-# CONFIG_AUXDISPLAY is not set + # CONFIG_UIO is not set +-# CONFIG_STAGING is not set + + # + # File systems +@@ -958,18 +879,19 @@ + # CONFIG_EXT2_FS_XIP is not set + CONFIG_EXT3_FS=y + # CONFIG_EXT3_FS_XATTR is not set +-# CONFIG_EXT4_FS is not set + CONFIG_JBD=y ++# CONFIG_JBD_DEBUG is not set + # CONFIG_REISERFS_FS is not set + # CONFIG_JFS_FS is not set + # CONFIG_FS_POSIX_ACL is not set +-CONFIG_FILE_LOCKING=y + # CONFIG_XFS_FS is not set + # CONFIG_OCFS2_FS is not set +-CONFIG_DNOTIFY=y ++# CONFIG_MINIX_FS is not set ++# CONFIG_ROMFS_FS is not set + CONFIG_INOTIFY=y + CONFIG_INOTIFY_USER=y + # CONFIG_QUOTA is not set ++CONFIG_DNOTIFY=y + # CONFIG_AUTOFS_FS is not set + CONFIG_AUTOFS4_FS=y + # CONFIG_FUSE_FS is not set +@@ -995,32 +917,35 @@ + CONFIG_PROC_FS=y + CONFIG_PROC_KCORE=y + CONFIG_PROC_SYSCTL=y +-CONFIG_PROC_PAGE_MONITOR=y + CONFIG_SYSFS=y + CONFIG_TMPFS=y + # CONFIG_TMPFS_POSIX_ACL is not set + # CONFIG_HUGETLB_PAGE is not set +-# CONFIG_CONFIGFS_FS is not set +-CONFIG_MISC_FILESYSTEMS=y ++CONFIG_RAMFS=y ++ ++# ++# Miscellaneous filesystems ++# + # CONFIG_HFSPLUS_FS is not set + # CONFIG_CRAMFS is not set +-# CONFIG_SQUASHFS is not set + # CONFIG_VXFS_FS is not set +-# CONFIG_MINIX_FS is not set +-# CONFIG_OMFS_FS is not set + # CONFIG_HPFS_FS is not set + # CONFIG_QNX4FS_FS is not set +-# CONFIG_ROMFS_FS is not set + # CONFIG_SYSV_FS is not set + # CONFIG_UFS_FS is not set +-CONFIG_NETWORK_FILESYSTEMS=y ++ ++# ++# Network File Systems ++# + CONFIG_NFS_FS=y + CONFIG_NFS_V3=y + # CONFIG_NFS_V3_ACL is not set +-CONFIG_ROOT_NFS=y ++# CONFIG_NFS_DIRECTIO is not set + CONFIG_NFSD=y + CONFIG_NFSD_V3=y + # CONFIG_NFSD_V3_ACL is not set ++CONFIG_NFSD_TCP=y ++CONFIG_ROOT_NFS=y + CONFIG_LOCKD=y + CONFIG_LOCKD_V4=y + CONFIG_EXPORTFS=y +@@ -1037,6 +962,10 @@ + # + # CONFIG_PARTITION_ADVANCED is not set + CONFIG_MSDOS_PARTITION=y ++ ++# ++# Native Language Support ++# + CONFIG_NLS=y + CONFIG_NLS_DEFAULT="iso8859-1" + CONFIG_NLS_CODEPAGE_437=m +@@ -1082,9 +1011,7 @@ + # Kernel hacking + # + # CONFIG_PRINTK_TIME is not set +-CONFIG_ENABLE_WARN_DEPRECATED=y + CONFIG_ENABLE_MUST_CHECK=y +-CONFIG_FRAME_WARN=1024 + CONFIG_MAGIC_SYSRQ=y + # CONFIG_UNUSED_SYMBOLS is not set + # CONFIG_DEBUG_FS is not set +@@ -1092,12 +1019,9 @@ + CONFIG_DEBUG_KERNEL=y + # CONFIG_DEBUG_SHIRQ is not set + CONFIG_DETECT_SOFTLOCKUP=y +-# CONFIG_BOOTPARAM_SOFTLOCKUP_PANIC is not set +-CONFIG_BOOTPARAM_SOFTLOCKUP_PANIC_VALUE=0 + CONFIG_SCHED_DEBUG=y + # CONFIG_SCHEDSTATS is not set + # CONFIG_TIMER_STATS is not set +-# CONFIG_DEBUG_OBJECTS is not set + # CONFIG_DEBUG_SLAB is not set + # CONFIG_DEBUG_RT_MUTEXES is not set + # CONFIG_RT_MUTEX_TESTER is not set +@@ -1109,29 +1033,10 @@ + CONFIG_DEBUG_BUGVERBOSE=y + # CONFIG_DEBUG_INFO is not set + # CONFIG_DEBUG_VM is not set +-# CONFIG_DEBUG_WRITECOUNT is not set +-CONFIG_DEBUG_MEMORY_INIT=y + # CONFIG_DEBUG_LIST is not set +-# CONFIG_DEBUG_SG is not set +-# CONFIG_DEBUG_NOTIFIERS is not set +-# CONFIG_BOOT_PRINTK_DELAY is not set ++CONFIG_FORCED_INLINING=y + # CONFIG_RCU_TORTURE_TEST is not set +-# CONFIG_RCU_CPU_STALL_DETECTOR is not set +-# CONFIG_BACKTRACE_SELF_TEST is not set +-# CONFIG_DEBUG_BLOCK_EXT_DEVT is not set + # CONFIG_FAULT_INJECTION is not set +-# CONFIG_SYSCTL_SYSCALL_CHECK is not set +- +-# +-# Tracers +-# +-# CONFIG_SCHED_TRACER is not set +-# CONFIG_CONTEXT_SWITCH_TRACER is not set +-# CONFIG_BOOT_TRACER is not set +-# CONFIG_TRACE_BRANCH_PROFILING is not set +-# CONFIG_BUILD_DOCSRC is not set +-# CONFIG_DYNAMIC_PRINTK_DEBUG is not set +-# CONFIG_SAMPLES is not set + # CONFIG_DEBUG_RODATA is not set + + # +@@ -1139,108 +1044,52 @@ + # + # CONFIG_KEYS is not set + CONFIG_SECURITY=y +-# CONFIG_SECURITYFS is not set + # CONFIG_SECURITY_NETWORK is not set +-# CONFIG_SECURITY_PATH is not set +-# CONFIG_SECURITY_FILE_CAPABILITIES is not set +-CONFIG_SECURITY_DEFAULT_MMAP_MIN_ADDR=0 ++CONFIG_SECURITY_CAPABILITIES=y + CONFIG_CRYPTO=y +- +-# +-# Crypto core or helper +-# +-# CONFIG_CRYPTO_FIPS is not set + CONFIG_CRYPTO_ALGAPI=y +-CONFIG_CRYPTO_ALGAPI2=y +-CONFIG_CRYPTO_AEAD2=y + CONFIG_CRYPTO_BLKCIPHER=y +-CONFIG_CRYPTO_BLKCIPHER2=y +-CONFIG_CRYPTO_HASH2=y +-CONFIG_CRYPTO_RNG2=y + CONFIG_CRYPTO_MANAGER=y +-CONFIG_CRYPTO_MANAGER2=y +-# CONFIG_CRYPTO_NULL is not set +-# CONFIG_CRYPTO_CRYPTD is not set +-# CONFIG_CRYPTO_AUTHENC is not set +-# CONFIG_CRYPTO_TEST is not set +- +-# +-# Authenticated Encryption with Associated Data +-# +-# CONFIG_CRYPTO_CCM is not set +-# CONFIG_CRYPTO_GCM is not set +-# CONFIG_CRYPTO_SEQIV is not set +- +-# +-# Block modes +-# +-CONFIG_CRYPTO_CBC=y +-# CONFIG_CRYPTO_CTR is not set +-# CONFIG_CRYPTO_CTS is not set +-# CONFIG_CRYPTO_ECB is not set +-# CONFIG_CRYPTO_PCBC is not set +- +-# +-# Hash modes +-# + # CONFIG_CRYPTO_HMAC is not set +- +-# +-# Digest +-# +-# CONFIG_CRYPTO_CRC32C is not set ++# CONFIG_CRYPTO_NULL is not set + # CONFIG_CRYPTO_MD4 is not set + # CONFIG_CRYPTO_MD5 is not set +-# CONFIG_CRYPTO_MICHAEL_MIC is not set +-# CONFIG_CRYPTO_RMD128 is not set +-# CONFIG_CRYPTO_RMD160 is not set +-# CONFIG_CRYPTO_RMD256 is not set +-# CONFIG_CRYPTO_RMD320 is not set + # CONFIG_CRYPTO_SHA1 is not set + # CONFIG_CRYPTO_SHA256 is not set + # CONFIG_CRYPTO_SHA512 is not set +-# CONFIG_CRYPTO_TGR192 is not set + # CONFIG_CRYPTO_WP512 is not set +- +-# +-# Ciphers +-# +-# CONFIG_CRYPTO_AES is not set +-# CONFIG_CRYPTO_ANUBIS is not set +-# CONFIG_CRYPTO_ARC4 is not set ++# CONFIG_CRYPTO_TGR192 is not set ++# CONFIG_CRYPTO_ECB is not set ++CONFIG_CRYPTO_CBC=y ++# CONFIG_CRYPTO_PCBC is not set ++# CONFIG_CRYPTO_CRYPTD is not set ++# CONFIG_CRYPTO_DES is not set ++# CONFIG_CRYPTO_FCRYPT is not set + # CONFIG_CRYPTO_BLOWFISH is not set +-# CONFIG_CRYPTO_CAMELLIA is not set ++# CONFIG_CRYPTO_TWOFISH is not set ++# CONFIG_CRYPTO_SERPENT is not set ++# CONFIG_CRYPTO_AES is not set + # CONFIG_CRYPTO_CAST5 is not set + # CONFIG_CRYPTO_CAST6 is not set +-# CONFIG_CRYPTO_DES is not set +-# CONFIG_CRYPTO_FCRYPT is not set ++# CONFIG_CRYPTO_TEA is not set ++# CONFIG_CRYPTO_ARC4 is not set + # CONFIG_CRYPTO_KHAZAD is not set ++# CONFIG_CRYPTO_ANUBIS is not set + # CONFIG_CRYPTO_SEED is not set +-# CONFIG_CRYPTO_SERPENT is not set +-# CONFIG_CRYPTO_TEA is not set +-# CONFIG_CRYPTO_TWOFISH is not set +- +-# +-# Compression +-# + # CONFIG_CRYPTO_DEFLATE is not set +-# CONFIG_CRYPTO_LZO is not set +- +-# +-# Random Number Generation +-# +-# CONFIG_CRYPTO_ANSI_CPRNG is not set ++# CONFIG_CRYPTO_MICHAEL_MIC is not set ++# CONFIG_CRYPTO_CRC32C is not set ++# CONFIG_CRYPTO_CAMELLIA is not set ++# CONFIG_CRYPTO_TEST is not set ++# CONFIG_CRYPTO_AUTHENC is not set + CONFIG_CRYPTO_HW=y +-# CONFIG_CRYPTO_DEV_HIFN_795X is not set + + # + # Library routines + # + CONFIG_BITREVERSE=y +-CONFIG_GENERIC_FIND_LAST_BIT=y + # CONFIG_CRC_CCITT is not set + # CONFIG_CRC16 is not set +-# CONFIG_CRC_T10DIF is not set + # CONFIG_CRC_ITU_T is not set + CONFIG_CRC32=y + # CONFIG_CRC7 is not set +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/arch/parisc/configs/c3000_defconfig linux-2.6.29-rc3.owrt/arch/parisc/configs/c3000_defconfig +--- linux-2.6.29.owrt/arch/parisc/configs/c3000_defconfig 2009-05-10 22:04:39.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/arch/parisc/configs/c3000_defconfig 2009-05-10 23:48:28.000000000 +0200 +@@ -1,7 +1,7 @@ + # + # Automatically generated make config: don't edit +-# Linux kernel version: 2.6.29-rc8 +-# Fri Mar 13 01:32:58 2009 ++# Linux kernel version: 2.6.23 ++# Fri Oct 12 21:24:00 2007 + # + CONFIG_PARISC=y + CONFIG_MMU=y +@@ -33,29 +33,16 @@ + # CONFIG_POSIX_MQUEUE is not set + # CONFIG_BSD_PROCESS_ACCT is not set + # CONFIG_TASKSTATS is not set ++# CONFIG_USER_NS is not set + # CONFIG_AUDIT is not set +- +-# +-# RCU Subsystem +-# +-CONFIG_CLASSIC_RCU=y +-# CONFIG_TREE_RCU is not set +-# CONFIG_PREEMPT_RCU is not set +-# CONFIG_TREE_RCU_TRACE is not set +-# CONFIG_PREEMPT_RCU_TRACE is not set + CONFIG_IKCONFIG=y + CONFIG_IKCONFIG_PROC=y + CONFIG_LOG_BUF_SHIFT=16 +-# CONFIG_GROUP_SCHED is not set +-# CONFIG_CGROUPS is not set + CONFIG_SYSFS_DEPRECATED=y +-CONFIG_SYSFS_DEPRECATED_V2=y + # CONFIG_RELAY is not set +-# CONFIG_NAMESPACES is not set + # CONFIG_BLK_DEV_INITRD is not set + # CONFIG_CC_OPTIMIZE_FOR_SIZE is not set + CONFIG_SYSCTL=y +-CONFIG_ANON_INODES=y + CONFIG_EMBEDDED=y + CONFIG_SYSCTL_SYSCALL=y + CONFIG_KALLSYMS=y +@@ -67,39 +54,29 @@ + CONFIG_ELF_CORE=y + CONFIG_BASE_FULL=y + CONFIG_FUTEX=y ++CONFIG_ANON_INODES=y + CONFIG_EPOLL=y + CONFIG_SIGNALFD=y +-CONFIG_TIMERFD=y + CONFIG_EVENTFD=y + CONFIG_SHMEM=y +-CONFIG_AIO=y + CONFIG_VM_EVENT_COUNTERS=y +-CONFIG_PCI_QUIRKS=y +-CONFIG_COMPAT_BRK=y + CONFIG_SLAB=y + # CONFIG_SLUB is not set + # CONFIG_SLOB is not set +-CONFIG_PROFILING=y +-CONFIG_TRACEPOINTS=y +-# CONFIG_MARKERS is not set +-CONFIG_OPROFILE=m +-CONFIG_HAVE_OPROFILE=y +-# CONFIG_HAVE_GENERIC_DMA_COHERENT is not set +-CONFIG_SLABINFO=y + CONFIG_RT_MUTEXES=y ++# CONFIG_TINY_SHMEM is not set + CONFIG_BASE_SMALL=0 + CONFIG_MODULES=y +-# CONFIG_MODULE_FORCE_LOAD is not set + CONFIG_MODULE_UNLOAD=y + CONFIG_MODULE_FORCE_UNLOAD=y + # CONFIG_MODVERSIONS is not set + # CONFIG_MODULE_SRCVERSION_ALL is not set +-CONFIG_INIT_ALL_POSSIBLE=y ++CONFIG_KMOD=y + CONFIG_BLOCK=y + # CONFIG_LBD is not set + # CONFIG_BLK_DEV_IO_TRACE is not set ++# CONFIG_LSF is not set + # CONFIG_BLK_DEV_BSG is not set +-# CONFIG_BLK_DEV_INTEGRITY is not set + + # + # IO Schedulers +@@ -113,7 +90,6 @@ + # CONFIG_DEFAULT_CFQ is not set + # CONFIG_DEFAULT_NOOP is not set + CONFIG_DEFAULT_IOSCHED="anticipatory" +-# CONFIG_FREEZER is not set + + # + # Processor type and features +@@ -139,19 +115,17 @@ + # CONFIG_HZ_300 is not set + # CONFIG_HZ_1000 is not set + CONFIG_HZ=250 +-# CONFIG_SCHED_HRTICK is not set + CONFIG_SELECT_MEMORY_MODEL=y + CONFIG_FLATMEM_MANUAL=y + # CONFIG_DISCONTIGMEM_MANUAL is not set + # CONFIG_SPARSEMEM_MANUAL is not set + CONFIG_FLATMEM=y + CONFIG_FLAT_NODE_MEM_MAP=y +-CONFIG_PAGEFLAGS_EXTENDED=y ++# CONFIG_SPARSEMEM_STATIC is not set + CONFIG_SPLIT_PTLOCK_CPUS=4 +-# CONFIG_PHYS_ADDR_T_64BIT is not set ++# CONFIG_RESOURCES_64BIT is not set + CONFIG_ZONE_DMA_FLAG=0 + CONFIG_VIRT_TO_BUS=y +-CONFIG_UNEVICTABLE_LRU=y + # CONFIG_HPUX is not set + + # +@@ -160,13 +134,14 @@ + # CONFIG_GSC is not set + CONFIG_PCI=y + # CONFIG_ARCH_SUPPORTS_MSI is not set +-CONFIG_PCI_LEGACY=y + # CONFIG_PCI_DEBUG is not set +-# CONFIG_PCI_STUB is not set + CONFIG_PCI_LBA=y + CONFIG_IOSAPIC=y + CONFIG_IOMMU_SBA=y +-CONFIG_IOMMU_HELPER=y ++ ++# ++# PCCARD (PCMCIA/CardBus) support ++# + # CONFIG_PCCARD is not set + # CONFIG_HOTPLUG_PCI is not set + +@@ -183,15 +158,16 @@ + # Executable file formats + # + CONFIG_BINFMT_ELF=y +-# CONFIG_CORE_DUMP_DEFAULT_ELF_HEADERS is not set +-# CONFIG_HAVE_AOUT is not set + # CONFIG_BINFMT_MISC is not set ++ ++# ++# Networking ++# + CONFIG_NET=y + + # + # Networking options + # +-CONFIG_COMPAT_NET_DEV_OPS=y + CONFIG_PACKET=y + CONFIG_PACKET_MMAP=y + CONFIG_UNIX=y +@@ -199,8 +175,6 @@ + CONFIG_XFRM_USER=m + # CONFIG_XFRM_SUB_POLICY is not set + # CONFIG_XFRM_MIGRATE is not set +-# CONFIG_XFRM_STATISTICS is not set +-CONFIG_XFRM_IPCOMP=m + CONFIG_NET_KEY=m + # CONFIG_NET_KEY_MIGRATE is not set + CONFIG_INET=y +@@ -230,6 +204,7 @@ + CONFIG_TCP_CONG_CUBIC=y + CONFIG_DEFAULT_TCP_CONG="cubic" + # CONFIG_TCP_MD5SIG is not set ++# CONFIG_IP_VS is not set + CONFIG_IPV6=m + # CONFIG_IPV6_PRIVACY is not set + # CONFIG_IPV6_ROUTER_PREF is not set +@@ -245,34 +220,29 @@ + CONFIG_INET6_XFRM_MODE_BEET=m + # CONFIG_INET6_XFRM_MODE_ROUTEOPTIMIZATION is not set + CONFIG_IPV6_SIT=m +-CONFIG_IPV6_NDISC_NODETYPE=y + CONFIG_IPV6_TUNNEL=m + # CONFIG_IPV6_MULTIPLE_TABLES is not set +-# CONFIG_IPV6_MROUTE is not set + # CONFIG_NETWORK_SECMARK is not set + CONFIG_NETFILTER=y + CONFIG_NETFILTER_DEBUG=y +-CONFIG_NETFILTER_ADVANCED=y + + # + # Core Netfilter Configuration + # +-# CONFIG_NETFILTER_NETLINK_QUEUE is not set +-# CONFIG_NETFILTER_NETLINK_LOG is not set ++# CONFIG_NETFILTER_NETLINK is not set ++# CONFIG_NF_CONNTRACK_ENABLED is not set + # CONFIG_NF_CONNTRACK is not set + # CONFIG_NETFILTER_XTABLES is not set +-# CONFIG_IP_VS is not set + + # + # IP: Netfilter Configuration + # +-# CONFIG_NF_DEFRAG_IPV4 is not set + CONFIG_IP_NF_QUEUE=m + # CONFIG_IP_NF_IPTABLES is not set + # CONFIG_IP_NF_ARPTABLES is not set + + # +-# IPv6: Netfilter Configuration ++# IPv6: Netfilter Configuration (EXPERIMENTAL) + # + # CONFIG_IP6_NF_QUEUE is not set + # CONFIG_IP6_NF_IPTABLES is not set +@@ -281,7 +251,6 @@ + # CONFIG_TIPC is not set + # CONFIG_ATM is not set + # CONFIG_BRIDGE is not set +-# CONFIG_NET_DSA is not set + # CONFIG_VLAN_8021Q is not set + # CONFIG_DECNET is not set + # CONFIG_LLC2 is not set +@@ -291,26 +260,28 @@ + # CONFIG_LAPB is not set + # CONFIG_ECONET is not set + # CONFIG_WAN_ROUTER is not set ++ ++# ++# QoS and/or fair queueing ++# + # CONFIG_NET_SCHED is not set +-# CONFIG_DCB is not set + + # + # Network testing + # + CONFIG_NET_PKTGEN=m + # CONFIG_HAMRADIO is not set +-# CONFIG_CAN is not set + # CONFIG_IRDA is not set + # CONFIG_BT is not set + # CONFIG_AF_RXRPC is not set +-# CONFIG_PHONET is not set +-CONFIG_WIRELESS=y ++ ++# ++# Wireless ++# + # CONFIG_CFG80211 is not set +-CONFIG_WIRELESS_OLD_REGULATORY=y + # CONFIG_WIRELESS_EXT is not set +-# CONFIG_LIB80211 is not set + # CONFIG_MAC80211 is not set +-# CONFIG_WIMAX is not set ++# CONFIG_IEEE80211 is not set + # CONFIG_RFKILL is not set + # CONFIG_NET_9P is not set + +@@ -325,8 +296,6 @@ + # CONFIG_STANDALONE is not set + # CONFIG_PREVENT_FIRMWARE_BUILD is not set + CONFIG_FW_LOADER=y +-CONFIG_FIRMWARE_IN_KERNEL=y +-CONFIG_EXTRA_FIRMWARE="" + # CONFIG_DEBUG_DRIVER is not set + # CONFIG_DEBUG_DEVRES is not set + # CONFIG_SYS_HYPERVISOR is not set +@@ -347,62 +316,59 @@ + # CONFIG_BLK_DEV_RAM is not set + # CONFIG_CDROM_PKTCDVD is not set + # CONFIG_ATA_OVER_ETH is not set +-# CONFIG_BLK_DEV_HD is not set + CONFIG_MISC_DEVICES=y + # CONFIG_PHANTOM is not set ++# CONFIG_EEPROM_93CX6 is not set + # CONFIG_SGI_IOC4 is not set + # CONFIG_TIFM_CORE is not set +-# CONFIG_ENCLOSURE_SERVICES is not set +-# CONFIG_HP_ILO is not set +-# CONFIG_C2PORT is not set +- +-# +-# EEPROM support +-# +-# CONFIG_EEPROM_93CX6 is not set +-CONFIG_HAVE_IDE=y + CONFIG_IDE=y ++CONFIG_IDE_MAX_HWIFS=4 ++CONFIG_BLK_DEV_IDE=y + + # +-# Please see Documentation/ide/ide.txt for help/info on IDE drives ++# Please see Documentation/ide.txt for help/info on IDE drives + # +-CONFIG_IDE_ATAPI=y + # CONFIG_BLK_DEV_IDE_SATA is not set +-CONFIG_IDE_GD=y +-CONFIG_IDE_GD_ATA=y +-# CONFIG_IDE_GD_ATAPI is not set ++CONFIG_BLK_DEV_IDEDISK=m ++# CONFIG_IDEDISK_MULTI_MODE is not set + CONFIG_BLK_DEV_IDECD=y +-CONFIG_BLK_DEV_IDECD_VERBOSE_ERRORS=y + # CONFIG_BLK_DEV_IDETAPE is not set ++# CONFIG_BLK_DEV_IDEFLOPPY is not set ++CONFIG_BLK_DEV_IDESCSI=y + # CONFIG_IDE_TASK_IOCTL is not set + CONFIG_IDE_PROC_FS=y + + # + # IDE chipset support/bugfixes + # ++CONFIG_IDE_GENERIC=y + # CONFIG_BLK_DEV_PLATFORM is not set +-CONFIG_BLK_DEV_IDEDMA_SFF=y + + # + # PCI IDE chipsets support + # + CONFIG_BLK_DEV_IDEPCI=y ++CONFIG_IDEPCI_SHARE_IRQ=y + CONFIG_IDEPCI_PCIBUS_ORDER=y ++# CONFIG_BLK_DEV_OFFBOARD is not set + # CONFIG_BLK_DEV_GENERIC is not set + # CONFIG_BLK_DEV_OPTI621 is not set + CONFIG_BLK_DEV_IDEDMA_PCI=y ++# CONFIG_BLK_DEV_IDEDMA_FORCED is not set ++CONFIG_IDEDMA_ONLYDISK=y + # CONFIG_BLK_DEV_AEC62XX is not set + # CONFIG_BLK_DEV_ALI15X3 is not set + # CONFIG_BLK_DEV_AMD74XX is not set + # CONFIG_BLK_DEV_CMD64X is not set + # CONFIG_BLK_DEV_TRIFLEX is not set ++# CONFIG_BLK_DEV_CY82C693 is not set + # CONFIG_BLK_DEV_CS5520 is not set + # CONFIG_BLK_DEV_CS5530 is not set ++# CONFIG_BLK_DEV_HPT34X is not set + # CONFIG_BLK_DEV_HPT366 is not set + # CONFIG_BLK_DEV_JMICRON is not set + # CONFIG_BLK_DEV_SC1200 is not set + # CONFIG_BLK_DEV_PIIX is not set +-# CONFIG_BLK_DEV_IT8172 is not set + # CONFIG_BLK_DEV_IT8213 is not set + # CONFIG_BLK_DEV_IT821X is not set + CONFIG_BLK_DEV_NS87415=y +@@ -414,7 +380,10 @@ + # CONFIG_BLK_DEV_TRM290 is not set + # CONFIG_BLK_DEV_VIA82CXXX is not set + # CONFIG_BLK_DEV_TC86C001 is not set ++# CONFIG_IDE_ARM is not set + CONFIG_BLK_DEV_IDEDMA=y ++# CONFIG_IDEDMA_IVB is not set ++# CONFIG_BLK_DEV_HD is not set + + # + # SCSI device support +@@ -453,10 +422,8 @@ + # CONFIG_SCSI_FC_ATTRS is not set + CONFIG_SCSI_ISCSI_ATTRS=m + # CONFIG_SCSI_SAS_LIBSAS is not set +-# CONFIG_SCSI_SRP_ATTRS is not set + CONFIG_SCSI_LOWLEVEL=y + # CONFIG_ISCSI_TCP is not set +-# CONFIG_SCSI_CXGB3_ISCSI is not set + # CONFIG_BLK_DEV_3W_XXXX_RAID is not set + # CONFIG_SCSI_3W_9XXX is not set + # CONFIG_SCSI_ACARD is not set +@@ -466,20 +433,16 @@ + # CONFIG_SCSI_AIC79XX is not set + # CONFIG_SCSI_AIC94XX is not set + # CONFIG_SCSI_DPT_I2O is not set +-# CONFIG_SCSI_ADVANSYS is not set + # CONFIG_SCSI_ARCMSR is not set + # CONFIG_MEGARAID_NEWGEN is not set + # CONFIG_MEGARAID_LEGACY is not set + # CONFIG_MEGARAID_SAS is not set + # CONFIG_SCSI_HPTIOP is not set +-# CONFIG_LIBFC is not set +-# CONFIG_FCOE is not set + # CONFIG_SCSI_DMX3191D is not set + # CONFIG_SCSI_FUTURE_DOMAIN is not set + # CONFIG_SCSI_IPS is not set + # CONFIG_SCSI_INITIO is not set + # CONFIG_SCSI_INIA100 is not set +-# CONFIG_SCSI_MVSAS is not set + # CONFIG_SCSI_STEX is not set + CONFIG_SCSI_SYM53C8XX_2=y + CONFIG_SCSI_SYM53C8XX_DMA_ADDRESSING_MODE=0 +@@ -495,11 +458,9 @@ + # CONFIG_SCSI_NSP32 is not set + CONFIG_SCSI_DEBUG=m + # CONFIG_SCSI_SRP is not set +-# CONFIG_SCSI_DH is not set + # CONFIG_ATA is not set + CONFIG_MD=y + CONFIG_BLK_DEV_MD=y +-CONFIG_MD_AUTODETECT=y + CONFIG_MD_LINEAR=y + CONFIG_MD_RAID0=y + CONFIG_MD_RAID1=y +@@ -514,8 +475,13 @@ + CONFIG_DM_MIRROR=m + CONFIG_DM_ZERO=m + CONFIG_DM_MULTIPATH=m ++# CONFIG_DM_MULTIPATH_EMC is not set ++# CONFIG_DM_MULTIPATH_RDAC is not set + # CONFIG_DM_DELAY is not set +-# CONFIG_DM_UEVENT is not set ++ ++# ++# Fusion MPT device support ++# + CONFIG_FUSION=y + CONFIG_FUSION_SPI=m + # CONFIG_FUSION_FC is not set +@@ -527,40 +493,20 @@ + # + # IEEE 1394 (FireWire) support + # +- +-# +-# Enable only one of the two stacks, unless you know what you are doing +-# + # CONFIG_FIREWIRE is not set + # CONFIG_IEEE1394 is not set + # CONFIG_I2O is not set + CONFIG_NETDEVICES=y ++# CONFIG_NETDEVICES_MULTIQUEUE is not set + CONFIG_DUMMY=m + CONFIG_BONDING=m + # CONFIG_MACVLAN is not set + # CONFIG_EQUALIZER is not set + CONFIG_TUN=m + # CONFIG_VETH is not set ++# CONFIG_IP1000 is not set + # CONFIG_ARCNET is not set +-CONFIG_PHYLIB=m +- +-# +-# MII PHY device drivers +-# +-# CONFIG_MARVELL_PHY is not set +-# CONFIG_DAVICOM_PHY is not set +-# CONFIG_QSEMI_PHY is not set +-# CONFIG_LXT_PHY is not set +-# CONFIG_CICADA_PHY is not set +-# CONFIG_VITESSE_PHY is not set +-# CONFIG_SMSC_PHY is not set +-# CONFIG_BROADCOM_PHY is not set +-# CONFIG_ICPLUS_PHY is not set +-# CONFIG_REALTEK_PHY is not set +-# CONFIG_NATIONAL_PHY is not set +-# CONFIG_STE10XP is not set +-# CONFIG_LSI_ET1011C_PHY is not set +-# CONFIG_MDIO_BITBANG is not set ++# CONFIG_PHYLIB is not set + CONFIG_NET_ETHERNET=y + CONFIG_MII=m + # CONFIG_HAPPYMEAL is not set +@@ -582,38 +528,33 @@ + # CONFIG_IBM_NEW_EMAC_RGMII is not set + # CONFIG_IBM_NEW_EMAC_TAH is not set + # CONFIG_IBM_NEW_EMAC_EMAC4 is not set +-# CONFIG_IBM_NEW_EMAC_NO_FLOW_CTRL is not set +-# CONFIG_IBM_NEW_EMAC_MAL_CLR_ICINTSTAT is not set +-# CONFIG_IBM_NEW_EMAC_MAL_COMMON_ERR is not set + CONFIG_NET_PCI=y + # CONFIG_PCNET32 is not set + # CONFIG_AMD8111_ETH is not set + # CONFIG_ADAPTEC_STARFIRE is not set + # CONFIG_B44 is not set + # CONFIG_FORCEDETH is not set ++# CONFIG_EEPRO100 is not set + CONFIG_E100=m + # CONFIG_FEALNX is not set + # CONFIG_NATSEMI is not set + # CONFIG_NE2K_PCI is not set + # CONFIG_8139CP is not set + # CONFIG_8139TOO is not set +-# CONFIG_R6040 is not set + # CONFIG_SIS900 is not set + # CONFIG_EPIC100 is not set +-# CONFIG_SMSC9420 is not set + # CONFIG_SUNDANCE is not set + # CONFIG_TLAN is not set + # CONFIG_VIA_RHINE is not set + # CONFIG_SC92031 is not set +-# CONFIG_ATL2 is not set + CONFIG_NETDEV_1000=y + CONFIG_ACENIC=m + # CONFIG_ACENIC_OMIT_TIGON_I is not set + # CONFIG_DL2K is not set + CONFIG_E1000=m ++# CONFIG_E1000_NAPI is not set ++# CONFIG_E1000_DISABLE_PACKET_SPLIT is not set + # CONFIG_E1000E is not set +-# CONFIG_IP1000 is not set +-# CONFIG_IGB is not set + # CONFIG_NS83820 is not set + # CONFIG_HAMACHI is not set + # CONFIG_YELLOWFIN is not set +@@ -621,31 +562,23 @@ + # CONFIG_SIS190 is not set + # CONFIG_SKGE is not set + # CONFIG_SKY2 is not set ++# CONFIG_SK98LIN is not set + # CONFIG_VIA_VELOCITY is not set + CONFIG_TIGON3=m + # CONFIG_BNX2 is not set + # CONFIG_QLA3XXX is not set + # CONFIG_ATL1 is not set +-# CONFIG_ATL1E is not set +-# CONFIG_ATL1C is not set +-# CONFIG_JME is not set + CONFIG_NETDEV_10000=y + # CONFIG_CHELSIO_T1 is not set +-CONFIG_CHELSIO_T3_DEPENDS=y + # CONFIG_CHELSIO_T3 is not set +-# CONFIG_ENIC is not set + # CONFIG_IXGBE is not set + # CONFIG_IXGB is not set + # CONFIG_S2IO is not set + # CONFIG_MYRI10GE is not set + # CONFIG_NETXEN_NIC is not set + # CONFIG_NIU is not set +-# CONFIG_MLX4_EN is not set + # CONFIG_MLX4_CORE is not set + # CONFIG_TEHUTI is not set +-# CONFIG_BNX2X is not set +-# CONFIG_QLGE is not set +-# CONFIG_SFC is not set + # CONFIG_TR is not set + + # +@@ -653,11 +586,6 @@ + # + # CONFIG_WLAN_PRE80211 is not set + # CONFIG_WLAN_80211 is not set +-# CONFIG_IWLWIFI_LEDS is not set +- +-# +-# Enable WiMAX (Networking options) to see the WiMAX drivers +-# + + # + # USB Network Adapters +@@ -666,6 +594,7 @@ + # CONFIG_USB_KAWETH is not set + # CONFIG_USB_PEGASUS is not set + # CONFIG_USB_RTL8150 is not set ++# CONFIG_USB_USBNET_MII is not set + # CONFIG_USB_USBNET is not set + # CONFIG_WAN is not set + # CONFIG_FDDI is not set +@@ -683,6 +612,7 @@ + # CONFIG_SLIP is not set + CONFIG_SLHC=m + # CONFIG_NET_FC is not set ++# CONFIG_SHAPER is not set + # CONFIG_NETCONSOLE is not set + # CONFIG_NETPOLL is not set + # CONFIG_NET_POLL_CONTROLLER is not set +@@ -704,6 +634,7 @@ + CONFIG_INPUT_MOUSEDEV_SCREEN_X=1600 + CONFIG_INPUT_MOUSEDEV_SCREEN_Y=1200 + # CONFIG_INPUT_JOYDEV is not set ++# CONFIG_INPUT_TSDEV is not set + # CONFIG_INPUT_EVDEV is not set + # CONFIG_INPUT_EVBUG is not set + +@@ -721,7 +652,6 @@ + # CONFIG_MOUSE_PS2 is not set + # CONFIG_MOUSE_SERIAL is not set + # CONFIG_MOUSE_APPLETOUCH is not set +-# CONFIG_MOUSE_BCM5974 is not set + # CONFIG_MOUSE_VSXXXAA is not set + # CONFIG_INPUT_JOYSTICK is not set + # CONFIG_INPUT_TABLET is not set +@@ -742,13 +672,10 @@ + # Character devices + # + CONFIG_VT=y +-CONFIG_CONSOLE_TRANSLATIONS=y + CONFIG_VT_CONSOLE=y + CONFIG_HW_CONSOLE=y + # CONFIG_VT_HW_CONSOLE_BINDING is not set +-CONFIG_DEVKMEM=y + # CONFIG_SERIAL_NONSTANDARD is not set +-# CONFIG_NOZOMI is not set + + # + # Serial drivers +@@ -772,77 +699,72 @@ + CONFIG_SERIAL_CORE_CONSOLE=y + # CONFIG_SERIAL_JSM is not set + CONFIG_UNIX98_PTYS=y +-# CONFIG_DEVPTS_MULTIPLE_INSTANCES is not set + CONFIG_LEGACY_PTYS=y + CONFIG_LEGACY_PTY_COUNT=256 + # CONFIG_IPMI_HANDLER is not set ++# CONFIG_WATCHDOG is not set + # CONFIG_HW_RANDOM is not set ++CONFIG_GEN_RTC=y ++CONFIG_GEN_RTC_X=y + # CONFIG_R3964 is not set + # CONFIG_APPLICOM is not set ++# CONFIG_AGP is not set ++# CONFIG_DRM is not set + CONFIG_RAW_DRIVER=y + CONFIG_MAX_RAW_DEVS=256 + # CONFIG_TCG_TPM is not set + CONFIG_DEVPORT=y + # CONFIG_I2C is not set ++ ++# ++# SPI support ++# + # CONFIG_SPI is not set ++# CONFIG_SPI_MASTER is not set + # CONFIG_W1 is not set + # CONFIG_POWER_SUPPLY is not set + # CONFIG_HWMON is not set +-# CONFIG_THERMAL is not set +-# CONFIG_THERMAL_HWMON is not set +-# CONFIG_WATCHDOG is not set +-CONFIG_SSB_POSSIBLE=y + + # + # Sonics Silicon Backplane + # ++CONFIG_SSB_POSSIBLE=y + # CONFIG_SSB is not set + + # + # Multifunction device drivers + # +-# CONFIG_MFD_CORE is not set + # CONFIG_MFD_SM501 is not set +-# CONFIG_HTC_PASIC3 is not set +-# CONFIG_MFD_TMIO is not set +-# CONFIG_REGULATOR is not set + + # + # Multimedia devices + # +- +-# +-# Multimedia core support +-# + # CONFIG_VIDEO_DEV is not set + # CONFIG_DVB_CORE is not set +-# CONFIG_VIDEO_MEDIA is not set ++# CONFIG_DAB is not set + + # +-# Multimedia drivers ++# Graphics support + # +-# CONFIG_DAB is not set ++# CONFIG_BACKLIGHT_LCD_SUPPORT is not set + + # +-# Graphics support ++# Display device support + # +-# CONFIG_AGP is not set +-# CONFIG_DRM is not set ++# CONFIG_DISPLAY_SUPPORT is not set + # CONFIG_VGASTATE is not set + CONFIG_VIDEO_OUTPUT_CONTROL=m + CONFIG_FB=y + # CONFIG_FIRMWARE_EDID is not set + # CONFIG_FB_DDC is not set +-# CONFIG_FB_BOOT_VESA_SUPPORT is not set + CONFIG_FB_CFB_FILLRECT=y + CONFIG_FB_CFB_COPYAREA=y + CONFIG_FB_CFB_IMAGEBLIT=y +-# CONFIG_FB_CFB_REV_PIXELS_IN_BYTE is not set + # CONFIG_FB_SYS_FILLRECT is not set + # CONFIG_FB_SYS_COPYAREA is not set + # CONFIG_FB_SYS_IMAGEBLIT is not set +-# CONFIG_FB_FOREIGN_ENDIAN is not set + # CONFIG_FB_SYS_FOPS is not set ++CONFIG_FB_DEFERRED_IO=y + # CONFIG_FB_SVGALIB is not set + # CONFIG_FB_MACMODES is not set + # CONFIG_FB_BACKLIGHT is not set +@@ -868,7 +790,6 @@ + # CONFIG_FB_S3 is not set + # CONFIG_FB_SAVAGE is not set + # CONFIG_FB_SIS is not set +-# CONFIG_FB_VIA is not set + # CONFIG_FB_NEOMAGIC is not set + # CONFIG_FB_KYRO is not set + # CONFIG_FB_3DFX is not set +@@ -877,16 +798,7 @@ + # CONFIG_FB_TRIDENT is not set + # CONFIG_FB_ARK is not set + # CONFIG_FB_PM3 is not set +-# CONFIG_FB_CARMINE is not set + # CONFIG_FB_VIRTUAL is not set +-# CONFIG_FB_METRONOME is not set +-# CONFIG_FB_MB862XX is not set +-# CONFIG_BACKLIGHT_LCD_SUPPORT is not set +- +-# +-# Display device support +-# +-# CONFIG_DISPLAY_SUPPORT is not set + + # + # Console display driver support +@@ -906,8 +818,15 @@ + # CONFIG_LOGO_LINUX_VGA16 is not set + # CONFIG_LOGO_LINUX_CLUT224 is not set + CONFIG_LOGO_PARISC_CLUT224=y ++ ++# ++# Sound ++# + CONFIG_SOUND=y +-CONFIG_SOUND_OSS_CORE=y ++ ++# ++# Advanced Linux Sound Architecture ++# + CONFIG_SND=y + CONFIG_SND_TIMER=y + CONFIG_SND_PCM=y +@@ -923,16 +842,20 @@ + CONFIG_SND_VERBOSE_PROCFS=y + # CONFIG_SND_VERBOSE_PRINTK is not set + # CONFIG_SND_DEBUG is not set +-CONFIG_SND_VMASTER=y ++ ++# ++# Generic devices ++# + CONFIG_SND_AC97_CODEC=y +-CONFIG_SND_DRIVERS=y + # CONFIG_SND_DUMMY is not set + # CONFIG_SND_VIRMIDI is not set + # CONFIG_SND_MTPAV is not set + # CONFIG_SND_SERIAL_U16550 is not set + # CONFIG_SND_MPU401 is not set +-# CONFIG_SND_AC97_POWER_SAVE is not set +-CONFIG_SND_PCI=y ++ ++# ++# PCI devices ++# + CONFIG_SND_AD1889=y + # CONFIG_SND_ALS300 is not set + # CONFIG_SND_ALI5451 is not set +@@ -941,12 +864,10 @@ + # CONFIG_SND_AU8810 is not set + # CONFIG_SND_AU8820 is not set + # CONFIG_SND_AU8830 is not set +-# CONFIG_SND_AW2 is not set + # CONFIG_SND_AZT3328 is not set + # CONFIG_SND_BT87X is not set + # CONFIG_SND_CA0106 is not set + # CONFIG_SND_CMIPCI is not set +-# CONFIG_SND_OXYGEN is not set + # CONFIG_SND_CS4281 is not set + # CONFIG_SND_CS46XX is not set + # CONFIG_SND_DARLA20 is not set +@@ -971,7 +892,6 @@ + # CONFIG_SND_HDA_INTEL is not set + # CONFIG_SND_HDSP is not set + # CONFIG_SND_HDSPM is not set +-# CONFIG_SND_HIFIER is not set + # CONFIG_SND_ICE1712 is not set + # CONFIG_SND_ICE1724 is not set + # CONFIG_SND_INTEL8X0 is not set +@@ -989,59 +909,47 @@ + # CONFIG_SND_TRIDENT is not set + # CONFIG_SND_VIA82XX is not set + # CONFIG_SND_VIA82XX_MODEM is not set +-# CONFIG_SND_VIRTUOSO is not set + # CONFIG_SND_VX222 is not set + # CONFIG_SND_YMFPCI is not set +-CONFIG_SND_USB=y ++# CONFIG_SND_AC97_POWER_SAVE is not set ++ ++# ++# USB devices ++# + # CONFIG_SND_USB_AUDIO is not set + # CONFIG_SND_USB_CAIAQ is not set ++ ++# ++# System on Chip audio support ++# + # CONFIG_SND_SOC is not set ++ ++# ++# SoC Audio support for SuperH ++# ++ ++# ++# Open Sound System ++# + # CONFIG_SOUND_PRIME is not set + CONFIG_AC97_BUS=y + CONFIG_HID_SUPPORT=y + CONFIG_HID=y + # CONFIG_HID_DEBUG is not set +-# CONFIG_HIDRAW is not set + + # + # USB Input Devices + # + CONFIG_USB_HID=y +-# CONFIG_HID_PID is not set ++# CONFIG_USB_HIDINPUT_POWERBOOK is not set ++# CONFIG_HID_FF is not set + CONFIG_USB_HIDDEV=y +- +-# +-# Special HID drivers +-# +-CONFIG_HID_COMPAT=y +-# CONFIG_HID_A4TECH is not set +-# CONFIG_HID_APPLE is not set +-# CONFIG_HID_BELKIN is not set +-# CONFIG_HID_CHERRY is not set +-# CONFIG_HID_CHICONY is not set +-# CONFIG_HID_CYPRESS is not set +-# CONFIG_HID_EZKEY is not set +-# CONFIG_HID_GYRATION is not set +-# CONFIG_HID_LOGITECH is not set +-# CONFIG_HID_MICROSOFT is not set +-# CONFIG_HID_MONTEREY is not set +-# CONFIG_HID_NTRIG is not set +-# CONFIG_HID_PANTHERLORD is not set +-# CONFIG_HID_PETALYNX is not set +-# CONFIG_HID_SAMSUNG is not set +-# CONFIG_HID_SONY is not set +-# CONFIG_HID_SUNPLUS is not set +-# CONFIG_GREENASIA_FF is not set +-# CONFIG_HID_TOPSEED is not set +-# CONFIG_THRUSTMASTER_FF is not set +-# CONFIG_ZEROPLUS_FF is not set + CONFIG_USB_SUPPORT=y + CONFIG_USB_ARCH_HAS_HCD=y + CONFIG_USB_ARCH_HAS_OHCI=y + CONFIG_USB_ARCH_HAS_EHCI=y + CONFIG_USB=y + CONFIG_USB_DEBUG=y +-# CONFIG_USB_ANNOUNCE_NEW_DEVICES is not set + + # + # Miscellaneous USB options +@@ -1050,20 +958,12 @@ + CONFIG_USB_DEVICE_CLASS=y + # CONFIG_USB_DYNAMIC_MINORS is not set + # CONFIG_USB_OTG is not set +-# CONFIG_USB_OTG_WHITELIST is not set +-# CONFIG_USB_OTG_BLACKLIST_HUB is not set +-# CONFIG_USB_MON is not set +-# CONFIG_USB_WUSB is not set +-# CONFIG_USB_WUSB_CBAF is not set + + # + # USB Host Controller Drivers + # +-# CONFIG_USB_C67X00_HCD is not set + # CONFIG_USB_EHCI_HCD is not set +-# CONFIG_USB_OXU210HP_HCD is not set + # CONFIG_USB_ISP116X_HCD is not set +-# CONFIG_USB_ISP1760_HCD is not set + CONFIG_USB_OHCI_HCD=y + # CONFIG_USB_OHCI_BIG_ENDIAN_DESC is not set + # CONFIG_USB_OHCI_BIG_ENDIAN_MMIO is not set +@@ -1071,37 +971,32 @@ + # CONFIG_USB_UHCI_HCD is not set + # CONFIG_USB_SL811_HCD is not set + # CONFIG_USB_R8A66597_HCD is not set +-# CONFIG_USB_WHCI_HCD is not set +-# CONFIG_USB_HWA_HCD is not set + + # + # USB Device Class drivers + # + # CONFIG_USB_ACM is not set + CONFIG_USB_PRINTER=m +-# CONFIG_USB_WDM is not set +-# CONFIG_USB_TMC is not set + + # +-# NOTE: USB_STORAGE depends on SCSI but BLK_DEV_SD may also be needed; ++# NOTE: USB_STORAGE enables SCSI, and 'SCSI disk support' + # + + # +-# see USB_STORAGE Help for more information ++# may also be needed; see USB_STORAGE Help for more information + # + CONFIG_USB_STORAGE=m + # CONFIG_USB_STORAGE_DEBUG is not set + # CONFIG_USB_STORAGE_DATAFAB is not set + # CONFIG_USB_STORAGE_FREECOM is not set + # CONFIG_USB_STORAGE_ISD200 is not set ++CONFIG_USB_STORAGE_DPCM=y + CONFIG_USB_STORAGE_USBAT=y + CONFIG_USB_STORAGE_SDDR09=y + CONFIG_USB_STORAGE_SDDR55=y + CONFIG_USB_STORAGE_JUMPSHOT=y + # CONFIG_USB_STORAGE_ALAUDA is not set +-# CONFIG_USB_STORAGE_ONETOUCH is not set + # CONFIG_USB_STORAGE_KARMA is not set +-# CONFIG_USB_STORAGE_CYPRESS_ATACB is not set + # CONFIG_USB_LIBUSUAL is not set + + # +@@ -1109,10 +1004,15 @@ + # + CONFIG_USB_MDC800=m + CONFIG_USB_MICROTEK=m ++# CONFIG_USB_MON is not set + + # + # USB port drivers + # ++ ++# ++# USB Serial Converter support ++# + # CONFIG_USB_SERIAL is not set + + # +@@ -1121,7 +1021,7 @@ + # CONFIG_USB_EMI62 is not set + # CONFIG_USB_EMI26 is not set + # CONFIG_USB_ADUTUX is not set +-# CONFIG_USB_SEVSEG is not set ++# CONFIG_USB_AUERSWALD is not set + # CONFIG_USB_RIO500 is not set + CONFIG_USB_LEGOTOWER=m + # CONFIG_USB_LCD is not set +@@ -1137,59 +1037,37 @@ + # CONFIG_USB_TRANCEVIBRATOR is not set + # CONFIG_USB_IOWARRIOR is not set + # CONFIG_USB_TEST is not set +-# CONFIG_USB_ISIGHTFW is not set +-# CONFIG_USB_VST is not set +-# CONFIG_USB_GADGET is not set + + # +-# OTG and related infrastructure ++# USB DSL modem support + # +-# CONFIG_UWB is not set ++ ++# ++# USB Gadget Support ++# ++# CONFIG_USB_GADGET is not set + # CONFIG_MMC is not set +-# CONFIG_MEMSTICK is not set + # CONFIG_NEW_LEDS is not set +-# CONFIG_ACCESSIBILITY is not set + # CONFIG_INFINIBAND is not set +-CONFIG_RTC_LIB=y +-CONFIG_RTC_CLASS=y +-CONFIG_RTC_HCTOSYS=y +-CONFIG_RTC_HCTOSYS_DEVICE="rtc0" +-# CONFIG_RTC_DEBUG is not set ++# CONFIG_RTC_CLASS is not set + + # +-# RTC interfaces ++# DMA Engine support + # +-CONFIG_RTC_INTF_SYSFS=y +-CONFIG_RTC_INTF_PROC=y +-CONFIG_RTC_INTF_DEV=y +-# CONFIG_RTC_INTF_DEV_UIE_EMUL is not set +-# CONFIG_RTC_DRV_TEST is not set ++# CONFIG_DMA_ENGINE is not set + + # +-# SPI RTC drivers ++# DMA Clients + # + + # +-# Platform RTC drivers ++# DMA Devices + # +-# CONFIG_RTC_DRV_DS1286 is not set +-# CONFIG_RTC_DRV_DS1511 is not set +-# CONFIG_RTC_DRV_DS1553 is not set +-# CONFIG_RTC_DRV_DS1742 is not set +-# CONFIG_RTC_DRV_STK17TA8 is not set +-# CONFIG_RTC_DRV_M48T86 is not set +-# CONFIG_RTC_DRV_M48T35 is not set +-# CONFIG_RTC_DRV_M48T59 is not set +-# CONFIG_RTC_DRV_BQ4802 is not set +-# CONFIG_RTC_DRV_V3020 is not set + + # +-# on-CPU RTC drivers ++# Userspace I/O + # +-CONFIG_RTC_DRV_PARISC=y +-# CONFIG_DMADEVICES is not set + # CONFIG_UIO is not set +-# CONFIG_STAGING is not set + + # + # File systems +@@ -1199,24 +1077,25 @@ + # CONFIG_EXT2_FS_XIP is not set + CONFIG_EXT3_FS=y + # CONFIG_EXT3_FS_XATTR is not set +-# CONFIG_EXT4_FS is not set ++# CONFIG_EXT4DEV_FS is not set + CONFIG_JBD=y + # CONFIG_JBD_DEBUG is not set + # CONFIG_REISERFS_FS is not set + # CONFIG_JFS_FS is not set + # CONFIG_FS_POSIX_ACL is not set +-CONFIG_FILE_LOCKING=y + CONFIG_XFS_FS=m + # CONFIG_XFS_QUOTA is not set ++# CONFIG_XFS_SECURITY is not set + # CONFIG_XFS_POSIX_ACL is not set + # CONFIG_XFS_RT is not set +-# CONFIG_XFS_DEBUG is not set ++# CONFIG_GFS2_FS is not set + # CONFIG_OCFS2_FS is not set +-# CONFIG_BTRFS_FS is not set +-CONFIG_DNOTIFY=y ++# CONFIG_MINIX_FS is not set ++# CONFIG_ROMFS_FS is not set + CONFIG_INOTIFY=y + CONFIG_INOTIFY_USER=y + # CONFIG_QUOTA is not set ++CONFIG_DNOTIFY=y + # CONFIG_AUTOFS_FS is not set + CONFIG_AUTOFS4_FS=y + # CONFIG_FUSE_FS is not set +@@ -1245,13 +1124,16 @@ + CONFIG_PROC_FS=y + CONFIG_PROC_KCORE=y + CONFIG_PROC_SYSCTL=y +-CONFIG_PROC_PAGE_MONITOR=y + CONFIG_SYSFS=y + CONFIG_TMPFS=y + # CONFIG_TMPFS_POSIX_ACL is not set + # CONFIG_HUGETLB_PAGE is not set ++CONFIG_RAMFS=y + # CONFIG_CONFIGFS_FS is not set +-CONFIG_MISC_FILESYSTEMS=y ++ ++# ++# Miscellaneous filesystems ++# + # CONFIG_ADFS_FS is not set + # CONFIG_AFFS_FS is not set + # CONFIG_HFS_FS is not set +@@ -1260,31 +1142,32 @@ + # CONFIG_BFS_FS is not set + # CONFIG_EFS_FS is not set + # CONFIG_CRAMFS is not set +-# CONFIG_SQUASHFS is not set + # CONFIG_VXFS_FS is not set +-# CONFIG_MINIX_FS is not set +-# CONFIG_OMFS_FS is not set + # CONFIG_HPFS_FS is not set + # CONFIG_QNX4FS_FS is not set +-# CONFIG_ROMFS_FS is not set + # CONFIG_SYSV_FS is not set + # CONFIG_UFS_FS is not set +-CONFIG_NETWORK_FILESYSTEMS=y ++ ++# ++# Network File Systems ++# + CONFIG_NFS_FS=y + CONFIG_NFS_V3=y + # CONFIG_NFS_V3_ACL is not set + # CONFIG_NFS_V4 is not set +-CONFIG_ROOT_NFS=y ++# CONFIG_NFS_DIRECTIO is not set + CONFIG_NFSD=y + CONFIG_NFSD_V3=y + # CONFIG_NFSD_V3_ACL is not set + # CONFIG_NFSD_V4 is not set ++# CONFIG_NFSD_TCP is not set ++CONFIG_ROOT_NFS=y + CONFIG_LOCKD=y + CONFIG_LOCKD_V4=y + CONFIG_EXPORTFS=y + CONFIG_NFS_COMMON=y + CONFIG_SUNRPC=y +-# CONFIG_SUNRPC_REGISTER_V4 is not set ++# CONFIG_SUNRPC_BIND34 is not set + # CONFIG_RPCSEC_GSS_KRB5 is not set + # CONFIG_RPCSEC_GSS_SPKM3 is not set + # CONFIG_SMB_FS is not set +@@ -1298,6 +1181,10 @@ + # + # CONFIG_PARTITION_ADVANCED is not set + CONFIG_MSDOS_PARTITION=y ++ ++# ++# Native Language Support ++# + CONFIG_NLS=y + CONFIG_NLS_DEFAULT="iso8859-1" + CONFIG_NLS_CODEPAGE_437=m +@@ -1338,28 +1225,33 @@ + # CONFIG_NLS_KOI8_R is not set + # CONFIG_NLS_KOI8_U is not set + CONFIG_NLS_UTF8=m ++ ++# ++# Distributed Lock Manager ++# + # CONFIG_DLM is not set + + # ++# Profiling support ++# ++CONFIG_PROFILING=y ++CONFIG_OPROFILE=m ++ ++# + # Kernel hacking + # + # CONFIG_PRINTK_TIME is not set +-CONFIG_ENABLE_WARN_DEPRECATED=y + CONFIG_ENABLE_MUST_CHECK=y +-CONFIG_FRAME_WARN=1024 + CONFIG_MAGIC_SYSRQ=y + # CONFIG_UNUSED_SYMBOLS is not set +-CONFIG_DEBUG_FS=y ++# CONFIG_DEBUG_FS is not set + CONFIG_HEADERS_CHECK=y + CONFIG_DEBUG_KERNEL=y + # CONFIG_DEBUG_SHIRQ is not set + CONFIG_DETECT_SOFTLOCKUP=y +-# CONFIG_BOOTPARAM_SOFTLOCKUP_PANIC is not set +-CONFIG_BOOTPARAM_SOFTLOCKUP_PANIC_VALUE=0 + CONFIG_SCHED_DEBUG=y + # CONFIG_SCHEDSTATS is not set + # CONFIG_TIMER_STATS is not set +-# CONFIG_DEBUG_OBJECTS is not set + # CONFIG_DEBUG_SLAB is not set + # CONFIG_DEBUG_RT_MUTEXES is not set + # CONFIG_RT_MUTEX_TESTER is not set +@@ -1371,33 +1263,10 @@ + # CONFIG_DEBUG_BUGVERBOSE is not set + # CONFIG_DEBUG_INFO is not set + # CONFIG_DEBUG_VM is not set +-# CONFIG_DEBUG_WRITECOUNT is not set +-# CONFIG_DEBUG_MEMORY_INIT is not set + # CONFIG_DEBUG_LIST is not set +-# CONFIG_DEBUG_SG is not set +-# CONFIG_DEBUG_NOTIFIERS is not set +-# CONFIG_BOOT_PRINTK_DELAY is not set ++CONFIG_FORCED_INLINING=y + # CONFIG_RCU_TORTURE_TEST is not set +-# CONFIG_RCU_CPU_STALL_DETECTOR is not set +-# CONFIG_BACKTRACE_SELF_TEST is not set +-# CONFIG_DEBUG_BLOCK_EXT_DEVT is not set + # CONFIG_FAULT_INJECTION is not set +-# CONFIG_SYSCTL_SYSCALL_CHECK is not set +-CONFIG_NOP_TRACER=y +-CONFIG_RING_BUFFER=y +-CONFIG_TRACING=y +- +-# +-# Tracers +-# +-# CONFIG_SCHED_TRACER is not set +-# CONFIG_CONTEXT_SWITCH_TRACER is not set +-# CONFIG_BOOT_TRACER is not set +-# CONFIG_TRACE_BRANCH_PROFILING is not set +-# CONFIG_FTRACE_STARTUP_TEST is not set +-# CONFIG_BUILD_DOCSRC is not set +-# CONFIG_DYNAMIC_PRINTK_DEBUG is not set +-# CONFIG_SAMPLES is not set + CONFIG_DEBUG_RODATA=y + + # +@@ -1405,110 +1274,54 @@ + # + # CONFIG_KEYS is not set + # CONFIG_SECURITY is not set +-# CONFIG_SECURITYFS is not set +-# CONFIG_SECURITY_FILE_CAPABILITIES is not set + CONFIG_CRYPTO=y +- +-# +-# Crypto core or helper +-# +-# CONFIG_CRYPTO_FIPS is not set + CONFIG_CRYPTO_ALGAPI=m +-CONFIG_CRYPTO_ALGAPI2=m +-CONFIG_CRYPTO_AEAD2=m + CONFIG_CRYPTO_BLKCIPHER=m +-CONFIG_CRYPTO_BLKCIPHER2=m +-CONFIG_CRYPTO_HASH=m +-CONFIG_CRYPTO_HASH2=m +-CONFIG_CRYPTO_RNG2=m + CONFIG_CRYPTO_MANAGER=m +-CONFIG_CRYPTO_MANAGER2=m +-# CONFIG_CRYPTO_GF128MUL is not set +-CONFIG_CRYPTO_NULL=m +-# CONFIG_CRYPTO_CRYPTD is not set +-# CONFIG_CRYPTO_AUTHENC is not set +-CONFIG_CRYPTO_TEST=m +- +-# +-# Authenticated Encryption with Associated Data +-# +-# CONFIG_CRYPTO_CCM is not set +-# CONFIG_CRYPTO_GCM is not set +-# CONFIG_CRYPTO_SEQIV is not set +- +-# +-# Block modes +-# +-CONFIG_CRYPTO_CBC=m +-# CONFIG_CRYPTO_CTR is not set +-# CONFIG_CRYPTO_CTS is not set +-# CONFIG_CRYPTO_ECB is not set +-# CONFIG_CRYPTO_LRW is not set +-# CONFIG_CRYPTO_PCBC is not set +-# CONFIG_CRYPTO_XTS is not set +- +-# +-# Hash modes +-# + # CONFIG_CRYPTO_HMAC is not set + # CONFIG_CRYPTO_XCBC is not set +- +-# +-# Digest +-# +-CONFIG_CRYPTO_CRC32C=m ++CONFIG_CRYPTO_NULL=m + # CONFIG_CRYPTO_MD4 is not set + CONFIG_CRYPTO_MD5=m +-# CONFIG_CRYPTO_MICHAEL_MIC is not set +-# CONFIG_CRYPTO_RMD128 is not set +-# CONFIG_CRYPTO_RMD160 is not set +-# CONFIG_CRYPTO_RMD256 is not set +-# CONFIG_CRYPTO_RMD320 is not set + # CONFIG_CRYPTO_SHA1 is not set + # CONFIG_CRYPTO_SHA256 is not set + # CONFIG_CRYPTO_SHA512 is not set +-# CONFIG_CRYPTO_TGR192 is not set + # CONFIG_CRYPTO_WP512 is not set +- +-# +-# Ciphers +-# +-# CONFIG_CRYPTO_AES is not set +-# CONFIG_CRYPTO_ANUBIS is not set +-# CONFIG_CRYPTO_ARC4 is not set ++# CONFIG_CRYPTO_TGR192 is not set ++# CONFIG_CRYPTO_GF128MUL is not set ++# CONFIG_CRYPTO_ECB is not set ++CONFIG_CRYPTO_CBC=m ++# CONFIG_CRYPTO_PCBC is not set ++# CONFIG_CRYPTO_LRW is not set ++# CONFIG_CRYPTO_XTS is not set ++# CONFIG_CRYPTO_CRYPTD is not set ++CONFIG_CRYPTO_DES=m ++# CONFIG_CRYPTO_FCRYPT is not set + CONFIG_CRYPTO_BLOWFISH=m +-# CONFIG_CRYPTO_CAMELLIA is not set ++# CONFIG_CRYPTO_TWOFISH is not set ++# CONFIG_CRYPTO_SERPENT is not set ++# CONFIG_CRYPTO_AES is not set + # CONFIG_CRYPTO_CAST5 is not set + # CONFIG_CRYPTO_CAST6 is not set +-CONFIG_CRYPTO_DES=m +-# CONFIG_CRYPTO_FCRYPT is not set ++# CONFIG_CRYPTO_TEA is not set ++# CONFIG_CRYPTO_ARC4 is not set + # CONFIG_CRYPTO_KHAZAD is not set +-# CONFIG_CRYPTO_SALSA20 is not set ++# CONFIG_CRYPTO_ANUBIS is not set + # CONFIG_CRYPTO_SEED is not set +-# CONFIG_CRYPTO_SERPENT is not set +-# CONFIG_CRYPTO_TEA is not set +-# CONFIG_CRYPTO_TWOFISH is not set +- +-# +-# Compression +-# + CONFIG_CRYPTO_DEFLATE=m +-# CONFIG_CRYPTO_LZO is not set +- +-# +-# Random Number Generation +-# +-# CONFIG_CRYPTO_ANSI_CPRNG is not set ++# CONFIG_CRYPTO_MICHAEL_MIC is not set ++CONFIG_CRYPTO_CRC32C=m ++# CONFIG_CRYPTO_CAMELLIA is not set ++CONFIG_CRYPTO_TEST=m ++# CONFIG_CRYPTO_AUTHENC is not set + # CONFIG_CRYPTO_HW is not set + + # + # Library routines + # + CONFIG_BITREVERSE=y +-CONFIG_GENERIC_FIND_LAST_BIT=y + CONFIG_CRC_CCITT=m + # CONFIG_CRC16 is not set +-# CONFIG_CRC_T10DIF is not set + # CONFIG_CRC_ITU_T is not set + CONFIG_CRC32=y + # CONFIG_CRC7 is not set +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/arch/parisc/configs/default_defconfig linux-2.6.29-rc3.owrt/arch/parisc/configs/default_defconfig +--- linux-2.6.29.owrt/arch/parisc/configs/default_defconfig 2009-05-10 22:04:39.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/arch/parisc/configs/default_defconfig 2009-05-10 23:48:28.000000000 +0200 +@@ -1,7 +1,7 @@ + # + # Automatically generated make config: don't edit +-# Linux kernel version: 2.6.29-rc8 +-# Fri Mar 13 01:32:59 2009 ++# Linux kernel version: 2.6.23 ++# Fri Oct 12 20:54:57 2007 + # + CONFIG_PARISC=y + CONFIG_MMU=y +@@ -33,35 +33,17 @@ + CONFIG_POSIX_MQUEUE=y + # CONFIG_BSD_PROCESS_ACCT is not set + # CONFIG_TASKSTATS is not set ++# CONFIG_USER_NS is not set + # CONFIG_AUDIT is not set +- +-# +-# RCU Subsystem +-# +-CONFIG_CLASSIC_RCU=y +-# CONFIG_TREE_RCU is not set +-# CONFIG_PREEMPT_RCU is not set +-# CONFIG_TREE_RCU_TRACE is not set +-# CONFIG_PREEMPT_RCU_TRACE is not set + CONFIG_IKCONFIG=y + CONFIG_IKCONFIG_PROC=y + CONFIG_LOG_BUF_SHIFT=16 +-# CONFIG_GROUP_SCHED is not set +-# CONFIG_CGROUPS is not set + CONFIG_SYSFS_DEPRECATED=y +-CONFIG_SYSFS_DEPRECATED_V2=y + # CONFIG_RELAY is not set +-CONFIG_NAMESPACES=y +-# CONFIG_UTS_NS is not set +-# CONFIG_IPC_NS is not set +-# CONFIG_USER_NS is not set +-# CONFIG_PID_NS is not set +-# CONFIG_NET_NS is not set + CONFIG_BLK_DEV_INITRD=y + CONFIG_INITRAMFS_SOURCE="" + CONFIG_CC_OPTIMIZE_FOR_SIZE=y + CONFIG_SYSCTL=y +-CONFIG_ANON_INODES=y + # CONFIG_EMBEDDED is not set + CONFIG_SYSCTL_SYSCALL=y + CONFIG_KALLSYMS=y +@@ -73,39 +55,29 @@ + CONFIG_ELF_CORE=y + CONFIG_BASE_FULL=y + CONFIG_FUTEX=y ++CONFIG_ANON_INODES=y + CONFIG_EPOLL=y + CONFIG_SIGNALFD=y +-CONFIG_TIMERFD=y + CONFIG_EVENTFD=y + CONFIG_SHMEM=y +-CONFIG_AIO=y + CONFIG_VM_EVENT_COUNTERS=y +-CONFIG_PCI_QUIRKS=y +-CONFIG_COMPAT_BRK=y + CONFIG_SLAB=y + # CONFIG_SLUB is not set + # CONFIG_SLOB is not set +-CONFIG_PROFILING=y +-CONFIG_TRACEPOINTS=y +-# CONFIG_MARKERS is not set +-CONFIG_OPROFILE=m +-CONFIG_HAVE_OPROFILE=y +-# CONFIG_HAVE_GENERIC_DMA_COHERENT is not set +-CONFIG_SLABINFO=y + CONFIG_RT_MUTEXES=y ++# CONFIG_TINY_SHMEM is not set + CONFIG_BASE_SMALL=0 + CONFIG_MODULES=y +-# CONFIG_MODULE_FORCE_LOAD is not set + CONFIG_MODULE_UNLOAD=y + CONFIG_MODULE_FORCE_UNLOAD=y + # CONFIG_MODVERSIONS is not set + # CONFIG_MODULE_SRCVERSION_ALL is not set +-CONFIG_INIT_ALL_POSSIBLE=y ++CONFIG_KMOD=y + CONFIG_BLOCK=y + # CONFIG_LBD is not set + # CONFIG_BLK_DEV_IO_TRACE is not set ++# CONFIG_LSF is not set + # CONFIG_BLK_DEV_BSG is not set +-# CONFIG_BLK_DEV_INTEGRITY is not set + + # + # IO Schedulers +@@ -119,7 +91,6 @@ + # CONFIG_DEFAULT_CFQ is not set + # CONFIG_DEFAULT_NOOP is not set + CONFIG_DEFAULT_IOSCHED="anticipatory" +-# CONFIG_FREEZER is not set + + # + # Processor type and features +@@ -143,19 +114,17 @@ + # CONFIG_HZ_300 is not set + # CONFIG_HZ_1000 is not set + CONFIG_HZ=250 +-# CONFIG_SCHED_HRTICK is not set + CONFIG_SELECT_MEMORY_MODEL=y + CONFIG_FLATMEM_MANUAL=y + # CONFIG_DISCONTIGMEM_MANUAL is not set + # CONFIG_SPARSEMEM_MANUAL is not set + CONFIG_FLATMEM=y + CONFIG_FLAT_NODE_MEM_MAP=y +-CONFIG_PAGEFLAGS_EXTENDED=y ++# CONFIG_SPARSEMEM_STATIC is not set + CONFIG_SPLIT_PTLOCK_CPUS=4096 +-# CONFIG_PHYS_ADDR_T_64BIT is not set ++# CONFIG_RESOURCES_64BIT is not set + CONFIG_ZONE_DMA_FLAG=0 + CONFIG_VIRT_TO_BUS=y +-CONFIG_UNEVICTABLE_LRU=y + # CONFIG_HPUX is not set + + # +@@ -171,14 +140,15 @@ + # CONFIG_ISA is not set + CONFIG_PCI=y + # CONFIG_ARCH_SUPPORTS_MSI is not set +-CONFIG_PCI_LEGACY=y + # CONFIG_PCI_DEBUG is not set +-# CONFIG_PCI_STUB is not set + CONFIG_GSC_DINO=y + CONFIG_PCI_LBA=y + CONFIG_IOSAPIC=y + CONFIG_IOMMU_SBA=y +-CONFIG_IOMMU_HELPER=y ++ ++# ++# PCCARD (PCMCIA/CardBus) support ++# + CONFIG_PCCARD=y + # CONFIG_PCMCIA_DEBUG is not set + CONFIG_PCMCIA=y +@@ -213,15 +183,16 @@ + # Executable file formats + # + CONFIG_BINFMT_ELF=y +-# CONFIG_CORE_DUMP_DEFAULT_ELF_HEADERS is not set +-# CONFIG_HAVE_AOUT is not set + CONFIG_BINFMT_MISC=m ++ ++# ++# Networking ++# + CONFIG_NET=y + + # + # Networking options + # +-CONFIG_COMPAT_NET_DEV_OPS=y + CONFIG_PACKET=y + CONFIG_PACKET_MMAP=y + CONFIG_UNIX=y +@@ -229,8 +200,6 @@ + CONFIG_XFRM_USER=m + # CONFIG_XFRM_SUB_POLICY is not set + # CONFIG_XFRM_MIGRATE is not set +-# CONFIG_XFRM_STATISTICS is not set +-CONFIG_XFRM_IPCOMP=y + CONFIG_NET_KEY=m + # CONFIG_NET_KEY_MIGRATE is not set + CONFIG_INET=y +@@ -276,10 +245,8 @@ + CONFIG_INET6_XFRM_MODE_BEET=y + # CONFIG_INET6_XFRM_MODE_ROUTEOPTIMIZATION is not set + CONFIG_IPV6_SIT=y +-CONFIG_IPV6_NDISC_NODETYPE=y + # CONFIG_IPV6_TUNNEL is not set + # CONFIG_IPV6_MULTIPLE_TABLES is not set +-# CONFIG_IPV6_MROUTE is not set + # CONFIG_NETWORK_SECMARK is not set + # CONFIG_NETFILTER is not set + # CONFIG_IP_DCCP is not set +@@ -287,7 +254,6 @@ + # CONFIG_TIPC is not set + # CONFIG_ATM is not set + # CONFIG_BRIDGE is not set +-# CONFIG_NET_DSA is not set + # CONFIG_VLAN_8021Q is not set + # CONFIG_DECNET is not set + CONFIG_LLC=m +@@ -298,26 +264,28 @@ + # CONFIG_LAPB is not set + # CONFIG_ECONET is not set + # CONFIG_WAN_ROUTER is not set ++ ++# ++# QoS and/or fair queueing ++# + # CONFIG_NET_SCHED is not set +-# CONFIG_DCB is not set + + # + # Network testing + # + # CONFIG_NET_PKTGEN is not set + # CONFIG_HAMRADIO is not set +-# CONFIG_CAN is not set + # CONFIG_IRDA is not set + # CONFIG_BT is not set + # CONFIG_AF_RXRPC is not set +-# CONFIG_PHONET is not set +-CONFIG_WIRELESS=y ++ ++# ++# Wireless ++# + # CONFIG_CFG80211 is not set +-CONFIG_WIRELESS_OLD_REGULATORY=y + # CONFIG_WIRELESS_EXT is not set +-# CONFIG_LIB80211 is not set + # CONFIG_MAC80211 is not set +-# CONFIG_WIMAX is not set ++# CONFIG_IEEE80211 is not set + # CONFIG_RFKILL is not set + # CONFIG_NET_9P is not set + +@@ -332,8 +300,6 @@ + # CONFIG_STANDALONE is not set + # CONFIG_PREVENT_FIRMWARE_BUILD is not set + CONFIG_FW_LOADER=y +-CONFIG_FIRMWARE_IN_KERNEL=y +-CONFIG_EXTRA_FIRMWARE="" + # CONFIG_DEBUG_DRIVER is not set + # CONFIG_DEBUG_DEVRES is not set + # CONFIG_SYS_HYPERVISOR is not set +@@ -364,68 +330,63 @@ + CONFIG_BLK_DEV_RAM=y + CONFIG_BLK_DEV_RAM_COUNT=16 + CONFIG_BLK_DEV_RAM_SIZE=6144 +-# CONFIG_BLK_DEV_XIP is not set ++CONFIG_BLK_DEV_RAM_BLOCKSIZE=1024 + # CONFIG_CDROM_PKTCDVD is not set + # CONFIG_ATA_OVER_ETH is not set +-# CONFIG_BLK_DEV_HD is not set + CONFIG_MISC_DEVICES=y + # CONFIG_PHANTOM is not set ++# CONFIG_EEPROM_93CX6 is not set + # CONFIG_SGI_IOC4 is not set + # CONFIG_TIFM_CORE is not set +-# CONFIG_ENCLOSURE_SERVICES is not set +-# CONFIG_HP_ILO is not set +-# CONFIG_C2PORT is not set +- +-# +-# EEPROM support +-# +-# CONFIG_EEPROM_93CX6 is not set +-CONFIG_HAVE_IDE=y + CONFIG_IDE=y ++CONFIG_BLK_DEV_IDE=y + + # +-# Please see Documentation/ide/ide.txt for help/info on IDE drives ++# Please see Documentation/ide.txt for help/info on IDE drives + # +-CONFIG_IDE_ATAPI=y + # CONFIG_BLK_DEV_IDE_SATA is not set +-CONFIG_IDE_GD=y +-CONFIG_IDE_GD_ATA=y +-# CONFIG_IDE_GD_ATAPI is not set ++CONFIG_BLK_DEV_IDEDISK=y ++CONFIG_IDEDISK_MULTI_MODE=y + CONFIG_BLK_DEV_IDECS=y + # CONFIG_BLK_DEV_DELKIN is not set + CONFIG_BLK_DEV_IDECD=y +-CONFIG_BLK_DEV_IDECD_VERBOSE_ERRORS=y + # CONFIG_BLK_DEV_IDETAPE is not set ++# CONFIG_BLK_DEV_IDEFLOPPY is not set ++CONFIG_BLK_DEV_IDESCSI=y + # CONFIG_IDE_TASK_IOCTL is not set + CONFIG_IDE_PROC_FS=y + + # + # IDE chipset support/bugfixes + # ++CONFIG_IDE_GENERIC=y + # CONFIG_BLK_DEV_PLATFORM is not set +-CONFIG_BLK_DEV_IDEDMA_SFF=y + + # + # PCI IDE chipsets support + # + CONFIG_BLK_DEV_IDEPCI=y ++CONFIG_IDEPCI_SHARE_IRQ=y + CONFIG_IDEPCI_PCIBUS_ORDER=y + # CONFIG_BLK_DEV_OFFBOARD is not set + CONFIG_BLK_DEV_GENERIC=y + # CONFIG_BLK_DEV_OPTI621 is not set + CONFIG_BLK_DEV_IDEDMA_PCI=y ++# CONFIG_BLK_DEV_IDEDMA_FORCED is not set ++CONFIG_IDEDMA_ONLYDISK=y + # CONFIG_BLK_DEV_AEC62XX is not set + # CONFIG_BLK_DEV_ALI15X3 is not set + # CONFIG_BLK_DEV_AMD74XX is not set + # CONFIG_BLK_DEV_CMD64X is not set + # CONFIG_BLK_DEV_TRIFLEX is not set ++# CONFIG_BLK_DEV_CY82C693 is not set + # CONFIG_BLK_DEV_CS5520 is not set + # CONFIG_BLK_DEV_CS5530 is not set ++# CONFIG_BLK_DEV_HPT34X is not set + # CONFIG_BLK_DEV_HPT366 is not set + # CONFIG_BLK_DEV_JMICRON is not set + # CONFIG_BLK_DEV_SC1200 is not set + # CONFIG_BLK_DEV_PIIX is not set +-# CONFIG_BLK_DEV_IT8172 is not set + # CONFIG_BLK_DEV_IT8213 is not set + # CONFIG_BLK_DEV_IT821X is not set + CONFIG_BLK_DEV_NS87415=y +@@ -437,7 +398,10 @@ + # CONFIG_BLK_DEV_TRM290 is not set + # CONFIG_BLK_DEV_VIA82CXXX is not set + # CONFIG_BLK_DEV_TC86C001 is not set ++# CONFIG_IDE_ARM is not set + CONFIG_BLK_DEV_IDEDMA=y ++# CONFIG_IDEDMA_IVB is not set ++# CONFIG_BLK_DEV_HD is not set + + # + # SCSI device support +@@ -476,10 +440,8 @@ + # CONFIG_SCSI_FC_ATTRS is not set + # CONFIG_SCSI_ISCSI_ATTRS is not set + # CONFIG_SCSI_SAS_LIBSAS is not set +-# CONFIG_SCSI_SRP_ATTRS is not set + CONFIG_SCSI_LOWLEVEL=y + # CONFIG_ISCSI_TCP is not set +-# CONFIG_SCSI_CXGB3_ISCSI is not set + # CONFIG_BLK_DEV_3W_XXXX_RAID is not set + # CONFIG_SCSI_3W_9XXX is not set + # CONFIG_SCSI_ACARD is not set +@@ -490,14 +452,11 @@ + # CONFIG_SCSI_AIC79XX is not set + # CONFIG_SCSI_AIC94XX is not set + # CONFIG_SCSI_DPT_I2O is not set +-# CONFIG_SCSI_ADVANSYS is not set + # CONFIG_SCSI_ARCMSR is not set + # CONFIG_MEGARAID_NEWGEN is not set + # CONFIG_MEGARAID_LEGACY is not set + # CONFIG_MEGARAID_SAS is not set + # CONFIG_SCSI_HPTIOP is not set +-# CONFIG_LIBFC is not set +-# CONFIG_FCOE is not set + # CONFIG_SCSI_DMX3191D is not set + # CONFIG_SCSI_FUTURE_DOMAIN is not set + # CONFIG_SCSI_IPS is not set +@@ -505,7 +464,6 @@ + # CONFIG_SCSI_INIA100 is not set + # CONFIG_SCSI_PPA is not set + # CONFIG_SCSI_IMM is not set +-# CONFIG_SCSI_MVSAS is not set + CONFIG_SCSI_LASI700=y + CONFIG_53C700_LE_ON_BE=y + # CONFIG_SCSI_STEX is not set +@@ -529,11 +487,9 @@ + # CONFIG_SCSI_DEBUG is not set + # CONFIG_SCSI_SRP is not set + # CONFIG_SCSI_LOWLEVEL_PCMCIA is not set +-# CONFIG_SCSI_DH is not set + # CONFIG_ATA is not set + CONFIG_MD=y + CONFIG_BLK_DEV_MD=y +-CONFIG_MD_AUTODETECT=y + CONFIG_MD_LINEAR=y + CONFIG_MD_RAID0=y + CONFIG_MD_RAID1=y +@@ -549,47 +505,32 @@ + # CONFIG_DM_ZERO is not set + # CONFIG_DM_MULTIPATH is not set + # CONFIG_DM_DELAY is not set +-# CONFIG_DM_UEVENT is not set +-# CONFIG_FUSION is not set + + # +-# IEEE 1394 (FireWire) support ++# Fusion MPT device support + # ++# CONFIG_FUSION is not set ++# CONFIG_FUSION_SPI is not set ++# CONFIG_FUSION_FC is not set ++# CONFIG_FUSION_SAS is not set + + # +-# Enable only one of the two stacks, unless you know what you are doing ++# IEEE 1394 (FireWire) support + # + # CONFIG_FIREWIRE is not set + # CONFIG_IEEE1394 is not set + # CONFIG_I2O is not set + CONFIG_NETDEVICES=y ++# CONFIG_NETDEVICES_MULTIQUEUE is not set + CONFIG_DUMMY=m + CONFIG_BONDING=m + # CONFIG_MACVLAN is not set + # CONFIG_EQUALIZER is not set + CONFIG_TUN=m + # CONFIG_VETH is not set ++# CONFIG_IP1000 is not set + # CONFIG_ARCNET is not set +-CONFIG_PHYLIB=y +- +-# +-# MII PHY device drivers +-# +-# CONFIG_MARVELL_PHY is not set +-# CONFIG_DAVICOM_PHY is not set +-# CONFIG_QSEMI_PHY is not set +-# CONFIG_LXT_PHY is not set +-# CONFIG_CICADA_PHY is not set +-# CONFIG_VITESSE_PHY is not set +-# CONFIG_SMSC_PHY is not set +-# CONFIG_BROADCOM_PHY is not set +-# CONFIG_ICPLUS_PHY is not set +-# CONFIG_REALTEK_PHY is not set +-# CONFIG_NATIONAL_PHY is not set +-# CONFIG_STE10XP is not set +-# CONFIG_LSI_ET1011C_PHY is not set +-# CONFIG_FIXED_PHY is not set +-# CONFIG_MDIO_BITBANG is not set ++# CONFIG_PHYLIB is not set + CONFIG_NET_ETHERNET=y + CONFIG_MII=m + CONFIG_LASI_82596=y +@@ -609,15 +550,13 @@ + # CONFIG_DM9102 is not set + # CONFIG_ULI526X is not set + # CONFIG_PCMCIA_XIRCOM is not set ++# CONFIG_PCMCIA_XIRTULIP is not set + # CONFIG_DEPCA is not set + # CONFIG_HP100 is not set + # CONFIG_IBM_NEW_EMAC_ZMII is not set + # CONFIG_IBM_NEW_EMAC_RGMII is not set + # CONFIG_IBM_NEW_EMAC_TAH is not set + # CONFIG_IBM_NEW_EMAC_EMAC4 is not set +-# CONFIG_IBM_NEW_EMAC_NO_FLOW_CTRL is not set +-# CONFIG_IBM_NEW_EMAC_MAL_CLR_ICINTSTAT is not set +-# CONFIG_IBM_NEW_EMAC_MAL_COMMON_ERR is not set + CONFIG_NET_PCI=y + # CONFIG_PCNET32 is not set + # CONFIG_AMD8111_ETH is not set +@@ -625,7 +564,7 @@ + # CONFIG_AC3200 is not set + # CONFIG_B44 is not set + # CONFIG_FORCEDETH is not set +-# CONFIG_CS89x0 is not set ++# CONFIG_EEPRO100 is not set + # CONFIG_E100 is not set + # CONFIG_LNE390 is not set + # CONFIG_FEALNX is not set +@@ -635,24 +574,19 @@ + # CONFIG_ES3210 is not set + # CONFIG_8139CP is not set + # CONFIG_8139TOO is not set +-# CONFIG_R6040 is not set + # CONFIG_SIS900 is not set + # CONFIG_EPIC100 is not set +-# CONFIG_SMSC9420 is not set + # CONFIG_SUNDANCE is not set + # CONFIG_TLAN is not set + # CONFIG_VIA_RHINE is not set + # CONFIG_SC92031 is not set + # CONFIG_NET_POCKET is not set +-# CONFIG_ATL2 is not set + CONFIG_NETDEV_1000=y + CONFIG_ACENIC=y + # CONFIG_ACENIC_OMIT_TIGON_I is not set + # CONFIG_DL2K is not set + # CONFIG_E1000 is not set + # CONFIG_E1000E is not set +-# CONFIG_IP1000 is not set +-# CONFIG_IGB is not set + # CONFIG_NS83820 is not set + # CONFIG_HAMACHI is not set + # CONFIG_YELLOWFIN is not set +@@ -660,31 +594,23 @@ + # CONFIG_SIS190 is not set + # CONFIG_SKGE is not set + # CONFIG_SKY2 is not set ++# CONFIG_SK98LIN is not set + # CONFIG_VIA_VELOCITY is not set + CONFIG_TIGON3=y + # CONFIG_BNX2 is not set + # CONFIG_QLA3XXX is not set + # CONFIG_ATL1 is not set +-# CONFIG_ATL1E is not set +-# CONFIG_ATL1C is not set +-# CONFIG_JME is not set + CONFIG_NETDEV_10000=y + # CONFIG_CHELSIO_T1 is not set +-CONFIG_CHELSIO_T3_DEPENDS=y + # CONFIG_CHELSIO_T3 is not set +-# CONFIG_ENIC is not set + # CONFIG_IXGBE is not set + # CONFIG_IXGB is not set + # CONFIG_S2IO is not set + # CONFIG_MYRI10GE is not set + # CONFIG_NETXEN_NIC is not set + # CONFIG_NIU is not set +-# CONFIG_MLX4_EN is not set + # CONFIG_MLX4_CORE is not set + # CONFIG_TEHUTI is not set +-# CONFIG_BNX2X is not set +-# CONFIG_QLGE is not set +-# CONFIG_SFC is not set + # CONFIG_TR is not set + + # +@@ -692,11 +618,6 @@ + # + # CONFIG_WLAN_PRE80211 is not set + # CONFIG_WLAN_80211 is not set +-# CONFIG_IWLWIFI_LEDS is not set +- +-# +-# Enable WiMAX (Networking options) to see the WiMAX drivers +-# + + # + # USB Network Adapters +@@ -705,6 +626,7 @@ + # CONFIG_USB_KAWETH is not set + # CONFIG_USB_PEGASUS is not set + # CONFIG_USB_RTL8150 is not set ++# CONFIG_USB_USBNET_MII is not set + # CONFIG_USB_USBNET is not set + CONFIG_NET_PCMCIA=y + # CONFIG_PCMCIA_3C589 is not set +@@ -732,6 +654,7 @@ + # CONFIG_SLIP is not set + CONFIG_SLHC=m + # CONFIG_NET_FC is not set ++# CONFIG_SHAPER is not set + # CONFIG_NETCONSOLE is not set + # CONFIG_NETPOLL is not set + # CONFIG_NET_POLL_CONTROLLER is not set +@@ -753,6 +676,7 @@ + CONFIG_INPUT_MOUSEDEV_SCREEN_X=1024 + CONFIG_INPUT_MOUSEDEV_SCREEN_Y=768 + # CONFIG_INPUT_JOYDEV is not set ++# CONFIG_INPUT_TSDEV is not set + # CONFIG_INPUT_EVDEV is not set + # CONFIG_INPUT_EVBUG is not set + +@@ -775,12 +699,11 @@ + CONFIG_MOUSE_PS2_ALPS=y + CONFIG_MOUSE_PS2_LOGIPS2PP=y + CONFIG_MOUSE_PS2_SYNAPTICS=y ++CONFIG_MOUSE_PS2_LIFEBOOK=y + CONFIG_MOUSE_PS2_TRACKPOINT=y +-# CONFIG_MOUSE_PS2_ELANTECH is not set + # CONFIG_MOUSE_PS2_TOUCHKIT is not set + CONFIG_MOUSE_SERIAL=y + # CONFIG_MOUSE_APPLETOUCH is not set +-# CONFIG_MOUSE_BCM5974 is not set + # CONFIG_MOUSE_VSXXXAA is not set + CONFIG_MOUSE_HIL=y + # CONFIG_INPUT_JOYSTICK is not set +@@ -806,13 +729,10 @@ + # Character devices + # + CONFIG_VT=y +-CONFIG_CONSOLE_TRANSLATIONS=y + CONFIG_VT_CONSOLE=y + CONFIG_HW_CONSOLE=y + # CONFIG_VT_HW_CONSOLE_BINDING is not set +-CONFIG_DEVKMEM=y + # CONFIG_SERIAL_NONSTANDARD is not set +-# CONFIG_NOZOMI is not set + + # + # Serial drivers +@@ -839,16 +759,21 @@ + CONFIG_SERIAL_CORE_CONSOLE=y + # CONFIG_SERIAL_JSM is not set + CONFIG_UNIX98_PTYS=y +-# CONFIG_DEVPTS_MULTIPLE_INSTANCES is not set + CONFIG_LEGACY_PTYS=y + CONFIG_LEGACY_PTY_COUNT=64 + CONFIG_PRINTER=m + # CONFIG_LP_CONSOLE is not set + CONFIG_PPDEV=m ++# CONFIG_TIPAR is not set + # CONFIG_IPMI_HANDLER is not set ++# CONFIG_WATCHDOG is not set + # CONFIG_HW_RANDOM is not set ++CONFIG_GEN_RTC=y ++CONFIG_GEN_RTC_X=y + # CONFIG_R3964 is not set + # CONFIG_APPLICOM is not set ++# CONFIG_AGP is not set ++# CONFIG_DRM is not set + + # + # PCMCIA character devices +@@ -856,70 +781,60 @@ + # CONFIG_SYNCLINK_CS is not set + # CONFIG_CARDMAN_4000 is not set + # CONFIG_CARDMAN_4040 is not set +-# CONFIG_IPWIRELESS is not set + # CONFIG_RAW_DRIVER is not set + # CONFIG_TCG_TPM is not set + CONFIG_DEVPORT=y + # CONFIG_I2C is not set ++ ++# ++# SPI support ++# + # CONFIG_SPI is not set ++# CONFIG_SPI_MASTER is not set + # CONFIG_W1 is not set + # CONFIG_POWER_SUPPLY is not set + # CONFIG_HWMON is not set +-# CONFIG_THERMAL is not set +-# CONFIG_THERMAL_HWMON is not set +-# CONFIG_WATCHDOG is not set +-CONFIG_SSB_POSSIBLE=y + + # + # Sonics Silicon Backplane + # ++CONFIG_SSB_POSSIBLE=y + # CONFIG_SSB is not set + + # + # Multifunction device drivers + # +-# CONFIG_MFD_CORE is not set + # CONFIG_MFD_SM501 is not set +-# CONFIG_HTC_PASIC3 is not set +-# CONFIG_MFD_TMIO is not set +-# CONFIG_REGULATOR is not set + + # + # Multimedia devices + # +- +-# +-# Multimedia core support +-# + # CONFIG_VIDEO_DEV is not set + # CONFIG_DVB_CORE is not set +-# CONFIG_VIDEO_MEDIA is not set ++# CONFIG_DAB is not set + + # +-# Multimedia drivers ++# Graphics support + # +-# CONFIG_DAB is not set ++# CONFIG_BACKLIGHT_LCD_SUPPORT is not set + + # +-# Graphics support ++# Display device support + # +-# CONFIG_AGP is not set +-# CONFIG_DRM is not set ++# CONFIG_DISPLAY_SUPPORT is not set + # CONFIG_VGASTATE is not set + CONFIG_VIDEO_OUTPUT_CONTROL=m + CONFIG_FB=y + # CONFIG_FIRMWARE_EDID is not set + # CONFIG_FB_DDC is not set +-# CONFIG_FB_BOOT_VESA_SUPPORT is not set + CONFIG_FB_CFB_FILLRECT=y + CONFIG_FB_CFB_COPYAREA=y + CONFIG_FB_CFB_IMAGEBLIT=y +-# CONFIG_FB_CFB_REV_PIXELS_IN_BYTE is not set + # CONFIG_FB_SYS_FILLRECT is not set + # CONFIG_FB_SYS_COPYAREA is not set + # CONFIG_FB_SYS_IMAGEBLIT is not set +-# CONFIG_FB_FOREIGN_ENDIAN is not set + # CONFIG_FB_SYS_FOPS is not set ++CONFIG_FB_DEFERRED_IO=y + # CONFIG_FB_SVGALIB is not set + # CONFIG_FB_MACMODES is not set + # CONFIG_FB_BACKLIGHT is not set +@@ -945,7 +860,6 @@ + # CONFIG_FB_S3 is not set + # CONFIG_FB_SAVAGE is not set + # CONFIG_FB_SIS is not set +-# CONFIG_FB_VIA is not set + # CONFIG_FB_NEOMAGIC is not set + # CONFIG_FB_KYRO is not set + # CONFIG_FB_3DFX is not set +@@ -954,16 +868,7 @@ + # CONFIG_FB_TRIDENT is not set + # CONFIG_FB_ARK is not set + # CONFIG_FB_PM3 is not set +-# CONFIG_FB_CARMINE is not set + # CONFIG_FB_VIRTUAL is not set +-# CONFIG_FB_METRONOME is not set +-# CONFIG_FB_MB862XX is not set +-# CONFIG_BACKLIGHT_LCD_SUPPORT is not set +- +-# +-# Display device support +-# +-# CONFIG_DISPLAY_SUPPORT is not set + + # + # Console display driver support +@@ -991,8 +896,15 @@ + # CONFIG_LOGO_LINUX_VGA16 is not set + # CONFIG_LOGO_LINUX_CLUT224 is not set + CONFIG_LOGO_PARISC_CLUT224=y ++ ++# ++# Sound ++# + CONFIG_SOUND=y +-CONFIG_SOUND_OSS_CORE=y ++ ++# ++# Advanced Linux Sound Architecture ++# + CONFIG_SND=y + CONFIG_SND_TIMER=y + CONFIG_SND_PCM=y +@@ -1008,9 +920,11 @@ + CONFIG_SND_VERBOSE_PROCFS=y + # CONFIG_SND_VERBOSE_PRINTK is not set + # CONFIG_SND_DEBUG is not set +-CONFIG_SND_VMASTER=y ++ ++# ++# Generic devices ++# + CONFIG_SND_AC97_CODEC=y +-CONFIG_SND_DRIVERS=y + # CONFIG_SND_DUMMY is not set + # CONFIG_SND_VIRMIDI is not set + # CONFIG_SND_MTPAV is not set +@@ -1018,8 +932,10 @@ + # CONFIG_SND_SERIAL_U16550 is not set + # CONFIG_SND_MPU401 is not set + # CONFIG_SND_PORTMAN2X4 is not set +-# CONFIG_SND_AC97_POWER_SAVE is not set +-CONFIG_SND_PCI=y ++ ++# ++# PCI devices ++# + CONFIG_SND_AD1889=y + # CONFIG_SND_ALS300 is not set + # CONFIG_SND_ALI5451 is not set +@@ -1028,12 +944,10 @@ + # CONFIG_SND_AU8810 is not set + # CONFIG_SND_AU8820 is not set + # CONFIG_SND_AU8830 is not set +-# CONFIG_SND_AW2 is not set + # CONFIG_SND_AZT3328 is not set + # CONFIG_SND_BT87X is not set + # CONFIG_SND_CA0106 is not set + # CONFIG_SND_CMIPCI is not set +-# CONFIG_SND_OXYGEN is not set + # CONFIG_SND_CS4281 is not set + # CONFIG_SND_CS46XX is not set + # CONFIG_SND_DARLA20 is not set +@@ -1058,7 +972,6 @@ + # CONFIG_SND_HDA_INTEL is not set + # CONFIG_SND_HDSP is not set + # CONFIG_SND_HDSPM is not set +-# CONFIG_SND_HIFIER is not set + # CONFIG_SND_ICE1712 is not set + # CONFIG_SND_ICE1724 is not set + # CONFIG_SND_INTEL8X0 is not set +@@ -1076,67 +989,58 @@ + # CONFIG_SND_TRIDENT is not set + # CONFIG_SND_VIA82XX is not set + # CONFIG_SND_VIA82XX_MODEM is not set +-# CONFIG_SND_VIRTUOSO is not set + # CONFIG_SND_VX222 is not set + # CONFIG_SND_YMFPCI is not set +-CONFIG_SND_USB=y ++# CONFIG_SND_AC97_POWER_SAVE is not set ++ ++# ++# USB devices ++# + # CONFIG_SND_USB_AUDIO is not set + # CONFIG_SND_USB_CAIAQ is not set +-CONFIG_SND_PCMCIA=y ++ ++# ++# PCMCIA devices ++# + # CONFIG_SND_VXPOCKET is not set + # CONFIG_SND_PDAUDIOCF is not set +-CONFIG_SND_GSC=y ++ ++# ++# GSC devices ++# + CONFIG_SND_HARMONY=y ++ ++# ++# System on Chip audio support ++# + # CONFIG_SND_SOC is not set ++ ++# ++# SoC Audio support for SuperH ++# ++ ++# ++# Open Sound System ++# + # CONFIG_SOUND_PRIME is not set + CONFIG_AC97_BUS=y + CONFIG_HID_SUPPORT=y + CONFIG_HID=y + CONFIG_HID_DEBUG=y +-# CONFIG_HIDRAW is not set + + # + # USB Input Devices + # + CONFIG_USB_HID=y +-# CONFIG_HID_PID is not set ++# CONFIG_USB_HIDINPUT_POWERBOOK is not set ++# CONFIG_HID_FF is not set + # CONFIG_USB_HIDDEV is not set +- +-# +-# Special HID drivers +-# +-CONFIG_HID_COMPAT=y +-CONFIG_HID_A4TECH=y +-CONFIG_HID_APPLE=y +-CONFIG_HID_BELKIN=y +-CONFIG_HID_CHERRY=y +-CONFIG_HID_CHICONY=y +-CONFIG_HID_CYPRESS=y +-CONFIG_HID_EZKEY=y +-CONFIG_HID_GYRATION=y +-CONFIG_HID_LOGITECH=y +-# CONFIG_LOGITECH_FF is not set +-# CONFIG_LOGIRUMBLEPAD2_FF is not set +-CONFIG_HID_MICROSOFT=y +-CONFIG_HID_MONTEREY=y +-CONFIG_HID_NTRIG=y +-CONFIG_HID_PANTHERLORD=y +-# CONFIG_PANTHERLORD_FF is not set +-CONFIG_HID_PETALYNX=y +-CONFIG_HID_SAMSUNG=y +-CONFIG_HID_SONY=y +-CONFIG_HID_SUNPLUS=y +-# CONFIG_GREENASIA_FF is not set +-CONFIG_HID_TOPSEED=y +-# CONFIG_THRUSTMASTER_FF is not set +-# CONFIG_ZEROPLUS_FF is not set + CONFIG_USB_SUPPORT=y + CONFIG_USB_ARCH_HAS_HCD=y + CONFIG_USB_ARCH_HAS_OHCI=y + CONFIG_USB_ARCH_HAS_EHCI=y + CONFIG_USB=y + # CONFIG_USB_DEBUG is not set +-# CONFIG_USB_ANNOUNCE_NEW_DEVICES is not set + + # + # Miscellaneous USB options +@@ -1145,18 +1049,12 @@ + CONFIG_USB_DEVICE_CLASS=y + # CONFIG_USB_DYNAMIC_MINORS is not set + # CONFIG_USB_OTG is not set +-CONFIG_USB_MON=y +-# CONFIG_USB_WUSB is not set +-# CONFIG_USB_WUSB_CBAF is not set + + # + # USB Host Controller Drivers + # +-# CONFIG_USB_C67X00_HCD is not set + # CONFIG_USB_EHCI_HCD is not set +-# CONFIG_USB_OXU210HP_HCD is not set + # CONFIG_USB_ISP116X_HCD is not set +-# CONFIG_USB_ISP1760_HCD is not set + CONFIG_USB_OHCI_HCD=y + # CONFIG_USB_OHCI_BIG_ENDIAN_DESC is not set + # CONFIG_USB_OHCI_BIG_ENDIAN_MMIO is not set +@@ -1164,23 +1062,19 @@ + CONFIG_USB_UHCI_HCD=y + # CONFIG_USB_SL811_HCD is not set + # CONFIG_USB_R8A66597_HCD is not set +-# CONFIG_USB_WHCI_HCD is not set +-# CONFIG_USB_HWA_HCD is not set + + # + # USB Device Class drivers + # + # CONFIG_USB_ACM is not set + # CONFIG_USB_PRINTER is not set +-# CONFIG_USB_WDM is not set +-# CONFIG_USB_TMC is not set + + # +-# NOTE: USB_STORAGE depends on SCSI but BLK_DEV_SD may also be needed; ++# NOTE: USB_STORAGE enables SCSI, and 'SCSI disk support' + # + + # +-# see USB_STORAGE Help for more information ++# may also be needed; see USB_STORAGE Help for more information + # + # CONFIG_USB_STORAGE is not set + # CONFIG_USB_LIBUSUAL is not set +@@ -1190,11 +1084,16 @@ + # + # CONFIG_USB_MDC800 is not set + # CONFIG_USB_MICROTEK is not set ++CONFIG_USB_MON=y + + # + # USB port drivers + # + # CONFIG_USB_USS720 is not set ++ ++# ++# USB Serial Converter support ++# + # CONFIG_USB_SERIAL is not set + + # +@@ -1203,7 +1102,7 @@ + # CONFIG_USB_EMI62 is not set + # CONFIG_USB_EMI26 is not set + # CONFIG_USB_ADUTUX is not set +-# CONFIG_USB_SEVSEG is not set ++# CONFIG_USB_AUERSWALD is not set + # CONFIG_USB_RIO500 is not set + # CONFIG_USB_LEGOTOWER is not set + # CONFIG_USB_LCD is not set +@@ -1219,60 +1118,38 @@ + # CONFIG_USB_TRANCEVIBRATOR is not set + # CONFIG_USB_IOWARRIOR is not set + # CONFIG_USB_TEST is not set +-# CONFIG_USB_ISIGHTFW is not set +-# CONFIG_USB_VST is not set +-# CONFIG_USB_GADGET is not set + + # +-# OTG and related infrastructure ++# USB DSL modem support ++# ++ ++# ++# USB Gadget Support + # +-# CONFIG_UWB is not set ++# CONFIG_USB_GADGET is not set + # CONFIG_MMC is not set +-# CONFIG_MEMSTICK is not set + # CONFIG_NEW_LEDS is not set +-# CONFIG_ACCESSIBILITY is not set + # CONFIG_INFINIBAND is not set +-CONFIG_RTC_LIB=y +-CONFIG_RTC_CLASS=y +-CONFIG_RTC_HCTOSYS=y +-CONFIG_RTC_HCTOSYS_DEVICE="rtc0" +-# CONFIG_RTC_DEBUG is not set ++# CONFIG_RTC_CLASS is not set + + # +-# RTC interfaces ++# DMA Engine support + # +-CONFIG_RTC_INTF_SYSFS=y +-CONFIG_RTC_INTF_PROC=y +-CONFIG_RTC_INTF_DEV=y +-# CONFIG_RTC_INTF_DEV_UIE_EMUL is not set +-# CONFIG_RTC_DRV_TEST is not set ++# CONFIG_DMA_ENGINE is not set + + # +-# SPI RTC drivers ++# DMA Clients + # + + # +-# Platform RTC drivers ++# DMA Devices + # +-# CONFIG_RTC_DRV_DS1286 is not set +-# CONFIG_RTC_DRV_DS1511 is not set +-# CONFIG_RTC_DRV_DS1553 is not set +-# CONFIG_RTC_DRV_DS1742 is not set +-# CONFIG_RTC_DRV_STK17TA8 is not set +-# CONFIG_RTC_DRV_M48T86 is not set +-# CONFIG_RTC_DRV_M48T35 is not set +-# CONFIG_RTC_DRV_M48T59 is not set +-# CONFIG_RTC_DRV_BQ4802 is not set +-# CONFIG_RTC_DRV_V3020 is not set ++# CONFIG_AUXDISPLAY is not set + + # +-# on-CPU RTC drivers ++# Userspace I/O + # +-CONFIG_RTC_DRV_PARISC=y +-# CONFIG_DMADEVICES is not set +-# CONFIG_AUXDISPLAY is not set + # CONFIG_UIO is not set +-# CONFIG_STAGING is not set + + # + # File systems +@@ -1282,20 +1159,21 @@ + # CONFIG_EXT2_FS_XIP is not set + CONFIG_EXT3_FS=y + # CONFIG_EXT3_FS_XATTR is not set +-# CONFIG_EXT4_FS is not set ++# CONFIG_EXT4DEV_FS is not set + CONFIG_JBD=y + # CONFIG_JBD_DEBUG is not set + # CONFIG_REISERFS_FS is not set + # CONFIG_JFS_FS is not set + CONFIG_FS_POSIX_ACL=y +-CONFIG_FILE_LOCKING=y + # CONFIG_XFS_FS is not set ++# CONFIG_GFS2_FS is not set + # CONFIG_OCFS2_FS is not set +-# CONFIG_BTRFS_FS is not set +-CONFIG_DNOTIFY=y ++# CONFIG_MINIX_FS is not set ++# CONFIG_ROMFS_FS is not set + CONFIG_INOTIFY=y + CONFIG_INOTIFY_USER=y + # CONFIG_QUOTA is not set ++CONFIG_DNOTIFY=y + CONFIG_AUTOFS_FS=y + # CONFIG_AUTOFS4_FS is not set + # CONFIG_FUSE_FS is not set +@@ -1324,13 +1202,16 @@ + CONFIG_PROC_FS=y + CONFIG_PROC_KCORE=y + CONFIG_PROC_SYSCTL=y +-CONFIG_PROC_PAGE_MONITOR=y + CONFIG_SYSFS=y + CONFIG_TMPFS=y + # CONFIG_TMPFS_POSIX_ACL is not set + # CONFIG_HUGETLB_PAGE is not set ++CONFIG_RAMFS=y + # CONFIG_CONFIGFS_FS is not set +-CONFIG_MISC_FILESYSTEMS=y ++ ++# ++# Miscellaneous filesystems ++# + # CONFIG_ADFS_FS is not set + # CONFIG_AFFS_FS is not set + # CONFIG_ECRYPT_FS is not set +@@ -1340,32 +1221,33 @@ + # CONFIG_BFS_FS is not set + # CONFIG_EFS_FS is not set + # CONFIG_CRAMFS is not set +-# CONFIG_SQUASHFS is not set + # CONFIG_VXFS_FS is not set +-# CONFIG_MINIX_FS is not set +-# CONFIG_OMFS_FS is not set + # CONFIG_HPFS_FS is not set + # CONFIG_QNX4FS_FS is not set +-# CONFIG_ROMFS_FS is not set + # CONFIG_SYSV_FS is not set + # CONFIG_UFS_FS is not set +-CONFIG_NETWORK_FILESYSTEMS=y ++ ++# ++# Network File Systems ++# + CONFIG_NFS_FS=y + CONFIG_NFS_V3=y + # CONFIG_NFS_V3_ACL is not set + # CONFIG_NFS_V4 is not set +-CONFIG_ROOT_NFS=y ++# CONFIG_NFS_DIRECTIO is not set + CONFIG_NFSD=y + CONFIG_NFSD_V3=y + # CONFIG_NFSD_V3_ACL is not set + CONFIG_NFSD_V4=y ++CONFIG_NFSD_TCP=y ++CONFIG_ROOT_NFS=y + CONFIG_LOCKD=y + CONFIG_LOCKD_V4=y + CONFIG_EXPORTFS=y + CONFIG_NFS_COMMON=y + CONFIG_SUNRPC=y + CONFIG_SUNRPC_GSS=y +-# CONFIG_SUNRPC_REGISTER_V4 is not set ++# CONFIG_SUNRPC_BIND34 is not set + CONFIG_RPCSEC_GSS_KRB5=y + CONFIG_RPCSEC_GSS_SPKM3=m + CONFIG_SMB_FS=m +@@ -1374,7 +1256,6 @@ + CONFIG_CIFS=m + # CONFIG_CIFS_STATS is not set + # CONFIG_CIFS_WEAK_PW_HASH is not set +-# CONFIG_CIFS_UPCALL is not set + # CONFIG_CIFS_XATTR is not set + # CONFIG_CIFS_DEBUG2 is not set + # CONFIG_CIFS_EXPERIMENTAL is not set +@@ -1387,6 +1268,10 @@ + # + # CONFIG_PARTITION_ADVANCED is not set + CONFIG_MSDOS_PARTITION=y ++ ++# ++# Native Language Support ++# + CONFIG_NLS=y + CONFIG_NLS_DEFAULT="iso8859-1" + CONFIG_NLS_CODEPAGE_437=y +@@ -1427,28 +1312,33 @@ + CONFIG_NLS_KOI8_R=m + CONFIG_NLS_KOI8_U=m + CONFIG_NLS_UTF8=y ++ ++# ++# Distributed Lock Manager ++# + # CONFIG_DLM is not set + + # ++# Profiling support ++# ++CONFIG_PROFILING=y ++CONFIG_OPROFILE=m ++ ++# + # Kernel hacking + # + # CONFIG_PRINTK_TIME is not set +-CONFIG_ENABLE_WARN_DEPRECATED=y + CONFIG_ENABLE_MUST_CHECK=y +-CONFIG_FRAME_WARN=1024 + CONFIG_MAGIC_SYSRQ=y + # CONFIG_UNUSED_SYMBOLS is not set +-CONFIG_DEBUG_FS=y ++# CONFIG_DEBUG_FS is not set + CONFIG_HEADERS_CHECK=y + CONFIG_DEBUG_KERNEL=y + # CONFIG_DEBUG_SHIRQ is not set + CONFIG_DETECT_SOFTLOCKUP=y +-# CONFIG_BOOTPARAM_SOFTLOCKUP_PANIC is not set +-CONFIG_BOOTPARAM_SOFTLOCKUP_PANIC_VALUE=0 + CONFIG_SCHED_DEBUG=y + # CONFIG_SCHEDSTATS is not set + # CONFIG_TIMER_STATS is not set +-# CONFIG_DEBUG_OBJECTS is not set + # CONFIG_DEBUG_SLAB is not set + # CONFIG_DEBUG_RT_MUTEXES is not set + # CONFIG_RT_MUTEX_TESTER is not set +@@ -1460,33 +1350,10 @@ + CONFIG_DEBUG_BUGVERBOSE=y + # CONFIG_DEBUG_INFO is not set + # CONFIG_DEBUG_VM is not set +-# CONFIG_DEBUG_WRITECOUNT is not set +-CONFIG_DEBUG_MEMORY_INIT=y + # CONFIG_DEBUG_LIST is not set +-# CONFIG_DEBUG_SG is not set +-# CONFIG_DEBUG_NOTIFIERS is not set +-# CONFIG_BOOT_PRINTK_DELAY is not set ++CONFIG_FORCED_INLINING=y + # CONFIG_RCU_TORTURE_TEST is not set +-# CONFIG_RCU_CPU_STALL_DETECTOR is not set +-# CONFIG_BACKTRACE_SELF_TEST is not set +-# CONFIG_DEBUG_BLOCK_EXT_DEVT is not set + # CONFIG_FAULT_INJECTION is not set +-# CONFIG_SYSCTL_SYSCALL_CHECK is not set +-CONFIG_NOP_TRACER=y +-CONFIG_RING_BUFFER=y +-CONFIG_TRACING=y +- +-# +-# Tracers +-# +-# CONFIG_SCHED_TRACER is not set +-# CONFIG_CONTEXT_SWITCH_TRACER is not set +-# CONFIG_BOOT_TRACER is not set +-# CONFIG_TRACE_BRANCH_PROFILING is not set +-# CONFIG_FTRACE_STARTUP_TEST is not set +-# CONFIG_BUILD_DOCSRC is not set +-# CONFIG_DYNAMIC_PRINTK_DEBUG is not set +-# CONFIG_SAMPLES is not set + # CONFIG_DEBUG_RODATA is not set + + # +@@ -1495,112 +1362,56 @@ + CONFIG_KEYS=y + CONFIG_KEYS_DEBUG_PROC_KEYS=y + # CONFIG_SECURITY is not set +-# CONFIG_SECURITYFS is not set +-# CONFIG_SECURITY_FILE_CAPABILITIES is not set + CONFIG_CRYPTO=y +- +-# +-# Crypto core or helper +-# +-# CONFIG_CRYPTO_FIPS is not set + CONFIG_CRYPTO_ALGAPI=y +-CONFIG_CRYPTO_ALGAPI2=y +-CONFIG_CRYPTO_AEAD=y +-CONFIG_CRYPTO_AEAD2=y + CONFIG_CRYPTO_BLKCIPHER=y +-CONFIG_CRYPTO_BLKCIPHER2=y + CONFIG_CRYPTO_HASH=y +-CONFIG_CRYPTO_HASH2=y +-CONFIG_CRYPTO_RNG2=y + CONFIG_CRYPTO_MANAGER=y +-CONFIG_CRYPTO_MANAGER2=y +-# CONFIG_CRYPTO_GF128MUL is not set +-CONFIG_CRYPTO_NULL=m +-# CONFIG_CRYPTO_CRYPTD is not set +-CONFIG_CRYPTO_AUTHENC=y +-CONFIG_CRYPTO_TEST=m +- +-# +-# Authenticated Encryption with Associated Data +-# +-# CONFIG_CRYPTO_CCM is not set +-# CONFIG_CRYPTO_GCM is not set +-# CONFIG_CRYPTO_SEQIV is not set +- +-# +-# Block modes +-# +-CONFIG_CRYPTO_CBC=y +-# CONFIG_CRYPTO_CTR is not set +-# CONFIG_CRYPTO_CTS is not set +-# CONFIG_CRYPTO_ECB is not set +-# CONFIG_CRYPTO_LRW is not set +-# CONFIG_CRYPTO_PCBC is not set +-# CONFIG_CRYPTO_XTS is not set +- +-# +-# Hash modes +-# + CONFIG_CRYPTO_HMAC=y + # CONFIG_CRYPTO_XCBC is not set +- +-# +-# Digest +-# +-CONFIG_CRYPTO_CRC32C=m ++CONFIG_CRYPTO_NULL=m + CONFIG_CRYPTO_MD4=m + CONFIG_CRYPTO_MD5=y +-CONFIG_CRYPTO_MICHAEL_MIC=m +-# CONFIG_CRYPTO_RMD128 is not set +-# CONFIG_CRYPTO_RMD160 is not set +-# CONFIG_CRYPTO_RMD256 is not set +-# CONFIG_CRYPTO_RMD320 is not set + CONFIG_CRYPTO_SHA1=y + CONFIG_CRYPTO_SHA256=m + CONFIG_CRYPTO_SHA512=m +-CONFIG_CRYPTO_TGR192=m + CONFIG_CRYPTO_WP512=m +- +-# +-# Ciphers +-# +-CONFIG_CRYPTO_AES=m +-CONFIG_CRYPTO_ANUBIS=m +-CONFIG_CRYPTO_ARC4=m ++CONFIG_CRYPTO_TGR192=m ++# CONFIG_CRYPTO_GF128MUL is not set ++# CONFIG_CRYPTO_ECB is not set ++CONFIG_CRYPTO_CBC=y ++# CONFIG_CRYPTO_PCBC is not set ++# CONFIG_CRYPTO_LRW is not set ++# CONFIG_CRYPTO_XTS is not set ++# CONFIG_CRYPTO_CRYPTD is not set ++CONFIG_CRYPTO_DES=y ++# CONFIG_CRYPTO_FCRYPT is not set + CONFIG_CRYPTO_BLOWFISH=m +-# CONFIG_CRYPTO_CAMELLIA is not set ++CONFIG_CRYPTO_TWOFISH=m ++CONFIG_CRYPTO_TWOFISH_COMMON=m ++CONFIG_CRYPTO_SERPENT=m ++CONFIG_CRYPTO_AES=m + CONFIG_CRYPTO_CAST5=m + CONFIG_CRYPTO_CAST6=m +-CONFIG_CRYPTO_DES=y +-# CONFIG_CRYPTO_FCRYPT is not set ++CONFIG_CRYPTO_TEA=m ++CONFIG_CRYPTO_ARC4=m + CONFIG_CRYPTO_KHAZAD=m +-# CONFIG_CRYPTO_SALSA20 is not set ++CONFIG_CRYPTO_ANUBIS=m + # CONFIG_CRYPTO_SEED is not set +-CONFIG_CRYPTO_SERPENT=m +-CONFIG_CRYPTO_TEA=m +-CONFIG_CRYPTO_TWOFISH=m +-CONFIG_CRYPTO_TWOFISH_COMMON=m +- +-# +-# Compression +-# + CONFIG_CRYPTO_DEFLATE=y +-# CONFIG_CRYPTO_LZO is not set +- +-# +-# Random Number Generation +-# +-# CONFIG_CRYPTO_ANSI_CPRNG is not set ++CONFIG_CRYPTO_MICHAEL_MIC=m ++CONFIG_CRYPTO_CRC32C=m ++# CONFIG_CRYPTO_CAMELLIA is not set ++CONFIG_CRYPTO_TEST=m ++# CONFIG_CRYPTO_AUTHENC is not set + # CONFIG_CRYPTO_HW is not set + + # + # Library routines + # + CONFIG_BITREVERSE=y +-CONFIG_GENERIC_FIND_LAST_BIT=y + CONFIG_CRC_CCITT=m + # CONFIG_CRC16 is not set +-# CONFIG_CRC_T10DIF is not set + # CONFIG_CRC_ITU_T is not set + CONFIG_CRC32=y + # CONFIG_CRC7 is not set +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/arch/parisc/hpux/fs.c linux-2.6.29-rc3.owrt/arch/parisc/hpux/fs.c +--- linux-2.6.29.owrt/arch/parisc/hpux/fs.c 2009-05-10 22:04:39.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/arch/parisc/hpux/fs.c 2009-05-10 23:48:28.000000000 +0200 +@@ -137,6 +137,7 @@ + error = count - buf.count; + } + ++out_putf: + fput(file); + out: + return error; +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/arch/parisc/include/asm/assembly.h linux-2.6.29-rc3.owrt/arch/parisc/include/asm/assembly.h +--- linux-2.6.29.owrt/arch/parisc/include/asm/assembly.h 2009-05-10 22:04:39.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/arch/parisc/include/asm/assembly.h 2009-05-10 23:48:28.000000000 +0200 +@@ -79,7 +79,6 @@ + + #include <asm/asm-offsets.h> + #include <asm/page.h> +-#include <asm/types.h> + + #include <asm/asmregs.h> + +@@ -130,27 +129,27 @@ + + /* Shift Left - note the r and t can NOT be the same! */ + .macro shl r, sa, t +- dep,z \r, 31-(\sa), 32-(\sa), \t ++ dep,z \r, 31-\sa, 32-\sa, \t + .endm + + /* The PA 2.0 shift left */ + .macro shlw r, sa, t +- depw,z \r, 31-(\sa), 32-(\sa), \t ++ depw,z \r, 31-\sa, 32-\sa, \t + .endm + + /* And the PA 2.0W shift left */ + .macro shld r, sa, t +- depd,z \r, 63-(\sa), 64-(\sa), \t ++ depd,z \r, 63-\sa, 64-\sa, \t + .endm + + /* Shift Right - note the r and t can NOT be the same! */ + .macro shr r, sa, t +- extru \r, 31-(\sa), 32-(\sa), \t ++ extru \r, 31-\sa, 32-\sa, \t + .endm + + /* pa20w version of shift right */ + .macro shrd r, sa, t +- extrd,u \r, 63-(\sa), 64-(\sa), \t ++ extrd,u \r, 63-\sa, 64-\sa, \t + .endm + + /* load 32-bit 'value' into 'reg' compensating for the ldil +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/arch/parisc/include/asm/dma-mapping.h linux-2.6.29-rc3.owrt/arch/parisc/include/asm/dma-mapping.h +--- linux-2.6.29.owrt/arch/parisc/include/asm/dma-mapping.h 2009-05-10 22:04:39.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/arch/parisc/include/asm/dma-mapping.h 2009-05-10 23:48:28.000000000 +0200 +@@ -5,7 +5,7 @@ + #include <asm/cacheflush.h> + #include <asm/scatterlist.h> + +-/* See Documentation/PCI/PCI-DMA-mapping.txt */ ++/* See Documentation/DMA-mapping.txt */ + struct hppa_dma_ops { + int (*dma_supported)(struct device *dev, u64 mask); + void *(*alloc_consistent)(struct device *dev, size_t size, dma_addr_t *iova, gfp_t flag); +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/arch/parisc/include/asm/io.h linux-2.6.29-rc3.owrt/arch/parisc/include/asm/io.h +--- linux-2.6.29.owrt/arch/parisc/include/asm/io.h 2009-05-10 22:04:39.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/arch/parisc/include/asm/io.h 2009-05-10 23:48:28.000000000 +0200 +@@ -174,48 +174,15 @@ + *(volatile unsigned long long __force *) addr = b; + } + +-static inline unsigned char readb(const volatile void __iomem *addr) +-{ +- return __raw_readb(addr); +-} +-static inline unsigned short readw(const volatile void __iomem *addr) +-{ +- return le16_to_cpu(__raw_readw(addr)); +-} +-static inline unsigned int readl(const volatile void __iomem *addr) +-{ +- return le32_to_cpu(__raw_readl(addr)); +-} +-static inline unsigned long long readq(const volatile void __iomem *addr) +-{ +- return le64_to_cpu(__raw_readq(addr)); +-} +- +-static inline void writeb(unsigned char b, volatile void __iomem *addr) +-{ +- __raw_writeb(b, addr); +-} +-static inline void writew(unsigned short w, volatile void __iomem *addr) +-{ +- __raw_writew(cpu_to_le16(w), addr); +-} +-static inline void writel(unsigned int l, volatile void __iomem *addr) +-{ +- __raw_writel(cpu_to_le32(l), addr); +-} +-static inline void writeq(unsigned long long q, volatile void __iomem *addr) +-{ +- __raw_writeq(cpu_to_le64(q), addr); +-} +- +-#define readb readb +-#define readw readw +-#define readl readl +-#define readq readq +-#define writeb writeb +-#define writew writew +-#define writel writel +-#define writeq writeq ++/* readb can never be const, so use __fswab instead of le*_to_cpu */ ++#define readb(addr) __raw_readb(addr) ++#define readw(addr) le16_to_cpu(__raw_readw(addr)) ++#define readl(addr) le32_to_cpu(__raw_readl(addr)) ++#define readq(addr) le64_to_cpu(__raw_readq(addr)) ++#define writeb(b, addr) __raw_writeb(b, addr) ++#define writew(b, addr) __raw_writew(cpu_to_le16(b), addr) ++#define writel(b, addr) __raw_writel(cpu_to_le32(b), addr) ++#define writeq(b, addr) __raw_writeq(cpu_to_le64(b), addr) + + #define readb_relaxed(addr) readb(addr) + #define readw_relaxed(addr) readw(addr) +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/arch/parisc/include/asm/irq.h linux-2.6.29-rc3.owrt/arch/parisc/include/asm/irq.h +--- linux-2.6.29.owrt/arch/parisc/include/asm/irq.h 2009-05-10 22:04:39.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/arch/parisc/include/asm/irq.h 2009-05-10 23:48:28.000000000 +0200 +@@ -49,7 +49,7 @@ + extern unsigned long txn_affinity_addr(unsigned int irq, int cpu); + + extern int cpu_claim_irq(unsigned int irq, struct irq_chip *, void *); +-extern int cpu_check_affinity(unsigned int irq, const struct cpumask *dest); ++extern int cpu_check_affinity(unsigned int irq, cpumask_t *dest); + + /* soft power switch support (power.c) */ + extern struct tasklet_struct power_tasklet; +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/arch/parisc/include/asm/uaccess.h linux-2.6.29-rc3.owrt/arch/parisc/include/asm/uaccess.h +--- linux-2.6.29.owrt/arch/parisc/include/asm/uaccess.h 2009-05-10 22:04:39.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/arch/parisc/include/asm/uaccess.h 2009-05-10 23:48:28.000000000 +0200 +@@ -241,7 +241,6 @@ + #define __copy_to_user_inatomic __copy_to_user + #define __copy_from_user_inatomic __copy_from_user + +-struct pt_regs; + int fixup_exception(struct pt_regs *regs); + + #endif /* __PARISC_UACCESS_H */ +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/arch/parisc/kernel/cache.c linux-2.6.29-rc3.owrt/arch/parisc/kernel/cache.c +--- linux-2.6.29.owrt/arch/parisc/kernel/cache.c 2009-05-10 22:04:39.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/arch/parisc/kernel/cache.c 2009-05-10 23:48:28.000000000 +0200 +@@ -551,7 +551,10 @@ + { + int sr3; + +- BUG_ON(!vma->vm_mm->context); ++ if (!vma->vm_mm->context) { ++ BUG(); ++ return; ++ } + + sr3 = mfsp(3); + if (vma->vm_mm->context == sr3) { +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/arch/parisc/kernel/entry.S linux-2.6.29-rc3.owrt/arch/parisc/kernel/entry.S +--- linux-2.6.29.owrt/arch/parisc/kernel/entry.S 2009-05-10 22:04:39.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/arch/parisc/kernel/entry.S 2009-05-10 23:48:28.000000000 +0200 +@@ -368,7 +368,7 @@ + * abstractions for the macros */ + .macro EXTR reg1,start,length,reg2 + #ifdef CONFIG_64BIT +- extrd,u \reg1,32+(\start),\length,\reg2 ++ extrd,u \reg1,32+\start,\length,\reg2 + #else + extrw,u \reg1,\start,\length,\reg2 + #endif +@@ -376,7 +376,7 @@ + + .macro DEP reg1,start,length,reg2 + #ifdef CONFIG_64BIT +- depd \reg1,32+(\start),\length,\reg2 ++ depd \reg1,32+\start,\length,\reg2 + #else + depw \reg1,\start,\length,\reg2 + #endif +@@ -384,7 +384,7 @@ + + .macro DEPI val,start,length,reg + #ifdef CONFIG_64BIT +- depdi \val,32+(\start),\length,\reg ++ depdi \val,32+\start,\length,\reg + #else + depwi \val,\start,\length,\reg + #endif +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/arch/parisc/kernel/firmware.c linux-2.6.29-rc3.owrt/arch/parisc/kernel/firmware.c +--- linux-2.6.29.owrt/arch/parisc/kernel/firmware.c 2009-05-10 22:04:39.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/arch/parisc/kernel/firmware.c 2009-05-10 23:48:28.000000000 +0200 +@@ -151,7 +151,7 @@ + } + + #ifdef CONFIG_64BIT +-void __cpuinit set_firmware_width_unlocked(void) ++void __init set_firmware_width_unlocked(void) + { + int ret; + +@@ -168,7 +168,7 @@ + * This function must be called before any pdc_* function that uses the + * convert_to_wide function. + */ +-void __cpuinit set_firmware_width(void) ++void __init set_firmware_width(void) + { + unsigned long flags; + spin_lock_irqsave(&pdc_lock, flags); +@@ -176,11 +176,11 @@ + spin_unlock_irqrestore(&pdc_lock, flags); + } + #else +-void __cpuinit set_firmware_width_unlocked(void) { ++void __init set_firmware_width_unlocked(void) { + return; + } + +-void __cpuinit set_firmware_width(void) { ++void __init set_firmware_width(void) { + return; + } + #endif /*CONFIG_64BIT*/ +@@ -302,7 +302,7 @@ + return retval; + } + +-int __cpuinit pdc_coproc_cfg_unlocked(struct pdc_coproc_cfg *pdc_coproc_info) ++int __init pdc_coproc_cfg_unlocked(struct pdc_coproc_cfg *pdc_coproc_info) + { + int ret; + +@@ -323,7 +323,7 @@ + * This PDC call returns the presence and status of all the coprocessors + * attached to the processor. + */ +-int __cpuinit pdc_coproc_cfg(struct pdc_coproc_cfg *pdc_coproc_info) ++int __init pdc_coproc_cfg(struct pdc_coproc_cfg *pdc_coproc_info) + { + int ret; + unsigned long flags; +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/arch/parisc/kernel/irq.c linux-2.6.29-rc3.owrt/arch/parisc/kernel/irq.c +--- linux-2.6.29.owrt/arch/parisc/kernel/irq.c 2009-05-10 22:04:39.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/arch/parisc/kernel/irq.c 2009-05-10 23:48:28.000000000 +0200 +@@ -112,7 +112,7 @@ + } + + #ifdef CONFIG_SMP +-int cpu_check_affinity(unsigned int irq, const struct cpumask *dest) ++int cpu_check_affinity(unsigned int irq, cpumask_t *dest) + { + int cpu_dest; + +@@ -120,25 +120,23 @@ + if (CHECK_IRQ_PER_CPU(irq)) { + /* Bad linux design decision. The mask has already + * been set; we must reset it */ +- cpumask_setall(&irq_desc[irq].affinity); ++ irq_desc[irq].affinity = CPU_MASK_ALL; + return -EINVAL; + } + + /* whatever mask they set, we just allow one CPU */ + cpu_dest = first_cpu(*dest); ++ *dest = cpumask_of_cpu(cpu_dest); + +- return cpu_dest; ++ return 0; + } + + static void cpu_set_affinity_irq(unsigned int irq, const struct cpumask *dest) + { +- int cpu_dest; +- +- cpu_dest = cpu_check_affinity(irq, dest); +- if (cpu_dest < 0) ++ if (cpu_check_affinity(irq, dest)) + return; + +- cpumask_copy(&irq_desc[irq].affinity, &cpumask_of_cpu(cpu_dest)); ++ irq_desc[irq].affinity = *dest; + } + #endif + +@@ -297,7 +295,7 @@ + unsigned long txn_affinity_addr(unsigned int irq, int cpu) + { + #ifdef CONFIG_SMP +- cpumask_copy(&irq_desc[irq].affinity, cpumask_of(cpu)); ++ irq_desc[irq].affinity = cpumask_of_cpu(cpu); + #endif + + return per_cpu(cpu_data, cpu).txn_addr; +@@ -354,7 +352,7 @@ + irq = eirr_to_irq(eirr_val); + + #ifdef CONFIG_SMP +- cpumask_copy(&dest, &irq_desc[irq].affinity); ++ dest = irq_desc[irq].affinity; + if (CHECK_IRQ_PER_CPU(irq_desc[irq].status) && + !cpu_isset(smp_processor_id(), dest)) { + int cpu = first_cpu(dest); +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/arch/parisc/kernel/pci-dma.c linux-2.6.29-rc3.owrt/arch/parisc/kernel/pci-dma.c +--- linux-2.6.29.owrt/arch/parisc/kernel/pci-dma.c 2009-05-10 22:04:39.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/arch/parisc/kernel/pci-dma.c 2009-05-10 23:48:28.000000000 +0200 +@@ -2,7 +2,7 @@ + ** PARISC 1.1 Dynamic DMA mapping support. + ** This implementation is for PA-RISC platforms that do not support + ** I/O TLBs (aka DMA address translation hardware). +-** See Documentation/PCI/PCI-DMA-mapping.txt for interface definitions. ++** See Documentation/DMA-mapping.txt for interface definitions. + ** + ** (c) Copyright 1999,2000 Hewlett-Packard Company + ** (c) Copyright 2000 Grant Grundler +@@ -447,7 +447,10 @@ + + static dma_addr_t pa11_dma_map_single(struct device *dev, void *addr, size_t size, enum dma_data_direction direction) + { +- BUG_ON(direction == DMA_NONE); ++ if (direction == DMA_NONE) { ++ printk(KERN_ERR "pa11_dma_map_single(PCI_DMA_NONE) called by %p\n", __builtin_return_address(0)); ++ BUG(); ++ } + + flush_kernel_dcache_range((unsigned long) addr, size); + return virt_to_phys(addr); +@@ -455,7 +458,10 @@ + + static void pa11_dma_unmap_single(struct device *dev, dma_addr_t dma_handle, size_t size, enum dma_data_direction direction) + { +- BUG_ON(direction == DMA_NONE); ++ if (direction == DMA_NONE) { ++ printk(KERN_ERR "pa11_dma_unmap_single(PCI_DMA_NONE) called by %p\n", __builtin_return_address(0)); ++ BUG(); ++ } + + if (direction == DMA_TO_DEVICE) + return; +@@ -474,7 +480,8 @@ + { + int i; + +- BUG_ON(direction == DMA_NONE); ++ if (direction == DMA_NONE) ++ BUG(); + + for (i = 0; i < nents; i++, sglist++ ) { + unsigned long vaddr = sg_virt_addr(sglist); +@@ -489,7 +496,8 @@ + { + int i; + +- BUG_ON(direction == DMA_NONE); ++ if (direction == DMA_NONE) ++ BUG(); + + if (direction == DMA_TO_DEVICE) + return; +@@ -503,14 +511,16 @@ + + static void pa11_dma_sync_single_for_cpu(struct device *dev, dma_addr_t dma_handle, unsigned long offset, size_t size, enum dma_data_direction direction) + { +- BUG_ON(direction == DMA_NONE); ++ if (direction == DMA_NONE) ++ BUG(); + + flush_kernel_dcache_range((unsigned long) phys_to_virt(dma_handle) + offset, size); + } + + static void pa11_dma_sync_single_for_device(struct device *dev, dma_addr_t dma_handle, unsigned long offset, size_t size, enum dma_data_direction direction) + { +- BUG_ON(direction == DMA_NONE); ++ if (direction == DMA_NONE) ++ BUG(); + + flush_kernel_dcache_range((unsigned long) phys_to_virt(dma_handle) + offset, size); + } +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/arch/parisc/mm/init.c linux-2.6.29-rc3.owrt/arch/parisc/mm/init.c +--- linux-2.6.29.owrt/arch/parisc/mm/init.c 2009-05-10 22:04:39.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/arch/parisc/mm/init.c 2009-05-10 23:48:28.000000000 +0200 +@@ -304,8 +304,10 @@ + */ + max_low_pfn = max_pfn; + +- /* bootmap sizing messed up? */ +- BUG_ON((bootmap_pfn - bootmap_start_pfn) != bootmap_pages); ++ if ((bootmap_pfn - bootmap_start_pfn) != bootmap_pages) { ++ printk(KERN_WARNING "WARNING! bootmap sizing is messed up!\n"); ++ BUG(); ++ } + + /* reserve PAGE0 pdc memory, kernel text/data/bss & bootmap */ + +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/arch/powerpc/boot/dts/mpc8313erdb.dts linux-2.6.29-rc3.owrt/arch/powerpc/boot/dts/mpc8313erdb.dts +--- linux-2.6.29.owrt/arch/powerpc/boot/dts/mpc8313erdb.dts 2009-05-10 22:04:40.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/arch/powerpc/boot/dts/mpc8313erdb.dts 2009-05-10 23:48:28.000000000 +0200 +@@ -191,8 +191,7 @@ + interrupts = <37 0x8 36 0x8 35 0x8>; + interrupt-parent = <&ipic>; + tbi-handle = < &tbi0 >; +- /* Vitesse 7385 isn't on the MDIO bus */ +- fixed-link = <1 1 1000 0 0>; ++ phy-handle = < &phy1 >; + fsl,magic-packet; + + mdio@24520 { +@@ -200,6 +199,12 @@ + #size-cells = <0>; + compatible = "fsl,gianfar-mdio"; + reg = <0x24520 0x20>; ++ phy1: ethernet-phy@1 { ++ interrupt-parent = <&ipic>; ++ interrupts = <19 0x8>; ++ reg = <0x1>; ++ device_type = "ethernet-phy"; ++ }; + phy4: ethernet-phy@4 { + interrupt-parent = <&ipic>; + interrupts = <20 0x8>; +@@ -214,8 +219,6 @@ + }; + + enet1: ethernet@25000 { +- #address-cells = <1>; +- #size-cells = <1>; + cell-index = <1>; + device_type = "network"; + model = "eTSEC"; +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/arch/powerpc/configs/40x/virtex_defconfig linux-2.6.29-rc3.owrt/arch/powerpc/configs/40x/virtex_defconfig +--- linux-2.6.29.owrt/arch/powerpc/configs/40x/virtex_defconfig 2009-05-10 22:04:40.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/arch/powerpc/configs/40x/virtex_defconfig 2009-05-10 23:48:28.000000000 +0200 +@@ -686,7 +686,7 @@ + CONFIG_SERIAL_CORE=y + CONFIG_SERIAL_CORE_CONSOLE=y + # CONFIG_SERIAL_JSM is not set +-CONFIG_SERIAL_OF_PLATFORM=y ++# CONFIG_SERIAL_OF_PLATFORM is not set + # CONFIG_SERIAL_OF_PLATFORM_NWPSERIAL is not set + CONFIG_UNIX98_PTYS=y + # CONFIG_DEVPTS_MULTIPLE_INSTANCES is not set +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/arch/powerpc/configs/44x/virtex5_defconfig linux-2.6.29-rc3.owrt/arch/powerpc/configs/44x/virtex5_defconfig +--- linux-2.6.29.owrt/arch/powerpc/configs/44x/virtex5_defconfig 2009-05-10 22:04:40.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/arch/powerpc/configs/44x/virtex5_defconfig 2009-05-10 23:48:28.000000000 +0200 +@@ -691,7 +691,7 @@ + CONFIG_SERIAL_CORE=y + CONFIG_SERIAL_CORE_CONSOLE=y + # CONFIG_SERIAL_JSM is not set +-CONFIG_SERIAL_OF_PLATFORM=y ++# CONFIG_SERIAL_OF_PLATFORM is not set + # CONFIG_SERIAL_OF_PLATFORM_NWPSERIAL is not set + CONFIG_UNIX98_PTYS=y + # CONFIG_DEVPTS_MULTIPLE_INSTANCES is not set +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/arch/powerpc/configs/52xx/cm5200_defconfig linux-2.6.29-rc3.owrt/arch/powerpc/configs/52xx/cm5200_defconfig +--- linux-2.6.29.owrt/arch/powerpc/configs/52xx/cm5200_defconfig 2009-05-10 22:04:40.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/arch/powerpc/configs/52xx/cm5200_defconfig 2009-05-10 23:48:28.000000000 +0200 +@@ -1,7 +1,7 @@ + # + # Automatically generated make config: don't edit +-# Linux kernel version: 2.6.29-rc2 +-# Mon Jan 26 21:41:58 2009 ++# Linux kernel version: 2.6.28-rc4 ++# Thu Nov 13 02:12:40 2008 + # + # CONFIG_PPC64 is not set + +@@ -43,7 +43,7 @@ + CONFIG_PPC=y + CONFIG_EARLY_PRINTK=y + CONFIG_GENERIC_NVRAM=y +-CONFIG_SCHED_OMIT_FRAME_POINTER=y ++CONFIG_SCHED_NO_NO_OMIT_FRAME_POINTER=y + CONFIG_ARCH_MAY_HAVE_PC_FDC=y + CONFIG_PPC_OF=y + CONFIG_OF=y +@@ -71,23 +71,14 @@ + # CONFIG_BSD_PROCESS_ACCT is not set + # CONFIG_TASKSTATS is not set + # CONFIG_AUDIT is not set +- +-# +-# RCU Subsystem +-# +-CONFIG_CLASSIC_RCU=y +-# CONFIG_TREE_RCU is not set +-# CONFIG_PREEMPT_RCU is not set +-# CONFIG_TREE_RCU_TRACE is not set +-# CONFIG_PREEMPT_RCU_TRACE is not set + # CONFIG_IKCONFIG is not set + CONFIG_LOG_BUF_SHIFT=14 ++# CONFIG_CGROUPS is not set + CONFIG_GROUP_SCHED=y + CONFIG_FAIR_GROUP_SCHED=y + # CONFIG_RT_GROUP_SCHED is not set + CONFIG_USER_SCHED=y + # CONFIG_CGROUP_SCHED is not set +-# CONFIG_CGROUPS is not set + CONFIG_SYSFS_DEPRECATED=y + CONFIG_SYSFS_DEPRECATED_V2=y + # CONFIG_RELAY is not set +@@ -119,6 +110,7 @@ + CONFIG_SLUB=y + # CONFIG_SLOB is not set + # CONFIG_PROFILING is not set ++# CONFIG_MARKERS is not set + CONFIG_HAVE_OPROFILE=y + CONFIG_HAVE_EFFICIENT_UNALIGNED_ACCESS=y + CONFIG_HAVE_IOREMAP_PROT=y +@@ -129,11 +121,13 @@ + # CONFIG_HAVE_GENERIC_DMA_COHERENT is not set + CONFIG_SLABINFO=y + CONFIG_RT_MUTEXES=y ++# CONFIG_TINY_SHMEM is not set + CONFIG_BASE_SMALL=0 + # CONFIG_MODULES is not set + CONFIG_BLOCK=y + # CONFIG_LBD is not set + # CONFIG_BLK_DEV_IO_TRACE is not set ++# CONFIG_LSF is not set + # CONFIG_BLK_DEV_BSG is not set + # CONFIG_BLK_DEV_INTEGRITY is not set + +@@ -149,6 +143,7 @@ + # CONFIG_DEFAULT_CFQ is not set + # CONFIG_DEFAULT_NOOP is not set + CONFIG_DEFAULT_IOSCHED="anticipatory" ++CONFIG_CLASSIC_RCU=y + # CONFIG_FREEZER is not set + + # +@@ -187,8 +182,9 @@ + # CONFIG_TAU is not set + # CONFIG_FSL_ULI1575 is not set + CONFIG_PPC_BESTCOMM=y ++# CONFIG_PPC_BESTCOMM_ATA is not set + CONFIG_PPC_BESTCOMM_FEC=y +-# CONFIG_SIMPLE_GPIO is not set ++# CONFIG_PPC_BESTCOMM_GEN_BD is not set + + # + # Kernel options +@@ -215,7 +211,6 @@ + CONFIG_ARCH_HAS_WALK_MEMORY=y + CONFIG_ARCH_ENABLE_MEMORY_HOTREMOVE=y + # CONFIG_KEXEC is not set +-# CONFIG_CRASH_DUMP is not set + CONFIG_ARCH_FLATMEM_ENABLE=y + CONFIG_ARCH_POPULATES_NODE_MAP=y + CONFIG_SELECT_MEMORY_MODEL=y +@@ -227,14 +222,12 @@ + CONFIG_PAGEFLAGS_EXTENDED=y + CONFIG_SPLIT_PTLOCK_CPUS=4 + CONFIG_MIGRATION=y ++# CONFIG_RESOURCES_64BIT is not set + # CONFIG_PHYS_ADDR_T_64BIT is not set + CONFIG_ZONE_DMA_FLAG=1 + CONFIG_BOUNCE=y + CONFIG_VIRT_TO_BUS=y + CONFIG_UNEVICTABLE_LRU=y +-CONFIG_PPC_4K_PAGES=y +-# CONFIG_PPC_16K_PAGES is not set +-# CONFIG_PPC_64K_PAGES is not set + CONFIG_FORCE_MAX_ZONEORDER=11 + CONFIG_PROC_DEVICETREE=y + # CONFIG_CMDLINE_BOOL is not set +@@ -275,7 +268,6 @@ + # + # Networking options + # +-CONFIG_COMPAT_NET_DEV_OPS=y + CONFIG_PACKET=y + # CONFIG_PACKET_MMAP is not set + CONFIG_UNIX=y +@@ -332,7 +324,6 @@ + # CONFIG_ECONET is not set + # CONFIG_WAN_ROUTER is not set + # CONFIG_NET_SCHED is not set +-# CONFIG_DCB is not set + + # + # Network testing +@@ -345,7 +336,6 @@ + # CONFIG_AF_RXRPC is not set + # CONFIG_PHONET is not set + # CONFIG_WIRELESS is not set +-# CONFIG_WIMAX is not set + # CONFIG_RFKILL is not set + # CONFIG_NET_9P is not set + +@@ -437,12 +427,6 @@ + # CONFIG_MTD_ONENAND is not set + + # +-# LPDDR flash memory drivers +-# +-# CONFIG_MTD_LPDDR is not set +-# CONFIG_MTD_QINFO_PROBE is not set +- +-# + # UBI - Unsorted block images + # + # CONFIG_MTD_UBI is not set +@@ -530,9 +514,6 @@ + # CONFIG_BROADCOM_PHY is not set + # CONFIG_ICPLUS_PHY is not set + # CONFIG_REALTEK_PHY is not set +-# CONFIG_NATIONAL_PHY is not set +-# CONFIG_STE10XP is not set +-# CONFIG_LSI_ET1011C_PHY is not set + # CONFIG_FIXED_PHY is not set + # CONFIG_MDIO_BITBANG is not set + CONFIG_NET_ETHERNET=y +@@ -558,10 +539,6 @@ + # CONFIG_IWLWIFI_LEDS is not set + + # +-# Enable WiMAX (Networking options) to see the WiMAX drivers +-# +- +-# + # USB Network Adapters + # + # CONFIG_USB_CATC is not set +@@ -611,10 +588,8 @@ + CONFIG_SERIAL_MPC52xx_CONSOLE=y + CONFIG_SERIAL_MPC52xx_CONSOLE_BAUD=57600 + CONFIG_UNIX98_PTYS=y +-# CONFIG_DEVPTS_MULTIPLE_INSTANCES is not set + CONFIG_LEGACY_PTYS=y + CONFIG_LEGACY_PTY_COUNT=256 +-# CONFIG_HVC_UDBG is not set + # CONFIG_IPMI_HANDLER is not set + # CONFIG_HW_RANDOM is not set + # CONFIG_NVRAM is not set +@@ -654,6 +629,8 @@ + # Miscellaneous I2C Chip support + # + # CONFIG_DS1682 is not set ++# CONFIG_EEPROM_AT24 is not set ++# CONFIG_EEPROM_LEGACY is not set + # CONFIG_SENSORS_PCF8574 is not set + # CONFIG_PCF8575 is not set + # CONFIG_SENSORS_PCA9539 is not set +@@ -698,12 +675,10 @@ + # CONFIG_MFD_CORE is not set + # CONFIG_MFD_SM501 is not set + # CONFIG_HTC_PASIC3 is not set +-# CONFIG_TWL4030_CORE is not set + # CONFIG_MFD_TMIO is not set + # CONFIG_PMIC_DA903X is not set + # CONFIG_MFD_WM8400 is not set + # CONFIG_MFD_WM8350_I2C is not set +-# CONFIG_MFD_PCF50633 is not set + # CONFIG_REGULATOR is not set + + # +@@ -761,7 +736,6 @@ + # USB Host Controller Drivers + # + # CONFIG_USB_C67X00_HCD is not set +-# CONFIG_USB_OXU210HP_HCD is not set + # CONFIG_USB_ISP116X_HCD is not set + # CONFIG_USB_ISP1760_HCD is not set + CONFIG_USB_OHCI_HCD=y +@@ -786,17 +760,18 @@ + # CONFIG_USB_TMC is not set + + # +-# NOTE: USB_STORAGE depends on SCSI but BLK_DEV_SD may also be needed; ++# NOTE: USB_STORAGE enables SCSI, and 'SCSI disk support' + # + + # +-# see USB_STORAGE Help for more information ++# may also be needed; see USB_STORAGE Help for more information + # + CONFIG_USB_STORAGE=y + # CONFIG_USB_STORAGE_DEBUG is not set + # CONFIG_USB_STORAGE_DATAFAB is not set + # CONFIG_USB_STORAGE_FREECOM is not set + # CONFIG_USB_STORAGE_ISD200 is not set ++# CONFIG_USB_STORAGE_DPCM is not set + # CONFIG_USB_STORAGE_USBAT is not set + # CONFIG_USB_STORAGE_SDDR09 is not set + # CONFIG_USB_STORAGE_SDDR55 is not set +@@ -842,10 +817,6 @@ + # CONFIG_USB_ISIGHTFW is not set + # CONFIG_USB_VST is not set + # CONFIG_USB_GADGET is not set +- +-# +-# OTG and related infrastructure +-# + # CONFIG_MMC is not set + # CONFIG_MEMSTICK is not set + # CONFIG_NEW_LEDS is not set +@@ -855,6 +826,7 @@ + # CONFIG_DMADEVICES is not set + # CONFIG_UIO is not set + # CONFIG_STAGING is not set ++CONFIG_STAGING_EXCLUDE_BUILD=y + + # + # File systems +@@ -875,7 +847,6 @@ + CONFIG_FILE_LOCKING=y + # CONFIG_XFS_FS is not set + # CONFIG_OCFS2_FS is not set +-# CONFIG_BTRFS_FS is not set + CONFIG_DNOTIFY=y + CONFIG_INOTIFY=y + CONFIG_INOTIFY_USER=y +@@ -912,7 +883,10 @@ + # CONFIG_TMPFS_POSIX_ACL is not set + # CONFIG_HUGETLB_PAGE is not set + # CONFIG_CONFIGFS_FS is not set +-CONFIG_MISC_FILESYSTEMS=y ++ ++# ++# Miscellaneous filesystems ++# + # CONFIG_ADFS_FS is not set + # CONFIG_AFFS_FS is not set + # CONFIG_HFS_FS is not set +@@ -932,7 +906,6 @@ + CONFIG_JFFS2_RTIME=y + # CONFIG_JFFS2_RUBIN is not set + CONFIG_CRAMFS=y +-# CONFIG_SQUASHFS is not set + # CONFIG_VXFS_FS is not set + # CONFIG_MINIX_FS is not set + # CONFIG_OMFS_FS is not set +@@ -1029,7 +1002,6 @@ + # Library routines + # + CONFIG_BITREVERSE=y +-CONFIG_GENERIC_FIND_LAST_BIT=y + # CONFIG_CRC_CCITT is not set + # CONFIG_CRC16 is not set + # CONFIG_CRC_T10DIF is not set +@@ -1081,7 +1053,6 @@ + # CONFIG_DEBUG_MEMORY_INIT is not set + # CONFIG_DEBUG_LIST is not set + # CONFIG_DEBUG_SG is not set +-# CONFIG_DEBUG_NOTIFIERS is not set + # CONFIG_BOOT_PRINTK_DELAY is not set + # CONFIG_RCU_TORTURE_TEST is not set + # CONFIG_RCU_CPU_STALL_DETECTOR is not set +@@ -1090,8 +1061,6 @@ + # CONFIG_FAULT_INJECTION is not set + # CONFIG_LATENCYTOP is not set + CONFIG_HAVE_FUNCTION_TRACER=y +-CONFIG_HAVE_DYNAMIC_FTRACE=y +-CONFIG_HAVE_FTRACE_MCOUNT_RECORD=y + + # + # Tracers +@@ -1100,13 +1069,11 @@ + # CONFIG_SCHED_TRACER is not set + # CONFIG_CONTEXT_SWITCH_TRACER is not set + # CONFIG_BOOT_TRACER is not set +-# CONFIG_TRACE_BRANCH_PROFILING is not set + # CONFIG_STACK_TRACER is not set + # CONFIG_DYNAMIC_PRINTK_DEBUG is not set + # CONFIG_SAMPLES is not set + CONFIG_HAVE_ARCH_KGDB=y + # CONFIG_KGDB is not set +-CONFIG_PRINT_STACK_DEPTH=64 + # CONFIG_DEBUG_STACKOVERFLOW is not set + # CONFIG_DEBUG_STACK_USAGE is not set + # CONFIG_DEBUG_PAGEALLOC is not set +@@ -1133,15 +1100,11 @@ + # + # CONFIG_CRYPTO_FIPS is not set + CONFIG_CRYPTO_ALGAPI=y +-CONFIG_CRYPTO_ALGAPI2=y +-CONFIG_CRYPTO_AEAD2=y ++CONFIG_CRYPTO_AEAD=y + CONFIG_CRYPTO_BLKCIPHER=y +-CONFIG_CRYPTO_BLKCIPHER2=y + CONFIG_CRYPTO_HASH=y +-CONFIG_CRYPTO_HASH2=y +-CONFIG_CRYPTO_RNG2=y ++CONFIG_CRYPTO_RNG=y + CONFIG_CRYPTO_MANAGER=y +-CONFIG_CRYPTO_MANAGER2=y + # CONFIG_CRYPTO_GF128MUL is not set + # CONFIG_CRYPTO_NULL is not set + # CONFIG_CRYPTO_CRYPTD is not set +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/arch/powerpc/configs/52xx/lite5200b_defconfig linux-2.6.29-rc3.owrt/arch/powerpc/configs/52xx/lite5200b_defconfig +--- linux-2.6.29.owrt/arch/powerpc/configs/52xx/lite5200b_defconfig 2009-05-10 22:04:40.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/arch/powerpc/configs/52xx/lite5200b_defconfig 2009-05-10 23:48:28.000000000 +0200 +@@ -1,7 +1,7 @@ + # + # Automatically generated make config: don't edit +-# Linux kernel version: 2.6.29-rc2 +-# Mon Jan 26 21:41:14 2009 ++# Linux kernel version: 2.6.28-rc4 ++# Thu Nov 13 02:10:16 2008 + # + # CONFIG_PPC64 is not set + +@@ -43,7 +43,7 @@ + CONFIG_PPC=y + CONFIG_EARLY_PRINTK=y + CONFIG_GENERIC_NVRAM=y +-CONFIG_SCHED_OMIT_FRAME_POINTER=y ++CONFIG_SCHED_NO_NO_OMIT_FRAME_POINTER=y + CONFIG_ARCH_MAY_HAVE_PC_FDC=y + CONFIG_PPC_OF=y + CONFIG_OF=y +@@ -72,23 +72,14 @@ + # CONFIG_BSD_PROCESS_ACCT is not set + # CONFIG_TASKSTATS is not set + # CONFIG_AUDIT is not set +- +-# +-# RCU Subsystem +-# +-CONFIG_CLASSIC_RCU=y +-# CONFIG_TREE_RCU is not set +-# CONFIG_PREEMPT_RCU is not set +-# CONFIG_TREE_RCU_TRACE is not set +-# CONFIG_PREEMPT_RCU_TRACE is not set + # CONFIG_IKCONFIG is not set + CONFIG_LOG_BUF_SHIFT=14 ++# CONFIG_CGROUPS is not set + CONFIG_GROUP_SCHED=y + # CONFIG_FAIR_GROUP_SCHED is not set + # CONFIG_RT_GROUP_SCHED is not set + CONFIG_USER_SCHED=y + # CONFIG_CGROUP_SCHED is not set +-# CONFIG_CGROUPS is not set + CONFIG_SYSFS_DEPRECATED=y + CONFIG_SYSFS_DEPRECATED_V2=y + # CONFIG_RELAY is not set +@@ -121,6 +112,7 @@ + CONFIG_SLUB=y + # CONFIG_SLOB is not set + # CONFIG_PROFILING is not set ++# CONFIG_MARKERS is not set + CONFIG_HAVE_OPROFILE=y + CONFIG_HAVE_EFFICIENT_UNALIGNED_ACCESS=y + CONFIG_HAVE_IOREMAP_PROT=y +@@ -131,6 +123,7 @@ + # CONFIG_HAVE_GENERIC_DMA_COHERENT is not set + CONFIG_SLABINFO=y + CONFIG_RT_MUTEXES=y ++# CONFIG_TINY_SHMEM is not set + CONFIG_BASE_SMALL=0 + CONFIG_MODULES=y + # CONFIG_MODULE_FORCE_LOAD is not set +@@ -138,9 +131,11 @@ + # CONFIG_MODULE_FORCE_UNLOAD is not set + # CONFIG_MODVERSIONS is not set + # CONFIG_MODULE_SRCVERSION_ALL is not set ++CONFIG_KMOD=y + CONFIG_BLOCK=y + # CONFIG_LBD is not set + # CONFIG_BLK_DEV_IO_TRACE is not set ++# CONFIG_LSF is not set + # CONFIG_BLK_DEV_BSG is not set + # CONFIG_BLK_DEV_INTEGRITY is not set + +@@ -156,6 +151,7 @@ + # CONFIG_DEFAULT_CFQ is not set + # CONFIG_DEFAULT_NOOP is not set + CONFIG_DEFAULT_IOSCHED="anticipatory" ++CONFIG_CLASSIC_RCU=y + CONFIG_FREEZER=y + + # +@@ -196,7 +192,7 @@ + CONFIG_PPC_BESTCOMM=y + CONFIG_PPC_BESTCOMM_ATA=y + CONFIG_PPC_BESTCOMM_FEC=y +-# CONFIG_SIMPLE_GPIO is not set ++CONFIG_PPC_BESTCOMM_GEN_BD=y + + # + # Kernel options +@@ -224,7 +220,6 @@ + CONFIG_ARCH_HAS_WALK_MEMORY=y + CONFIG_ARCH_ENABLE_MEMORY_HOTREMOVE=y + # CONFIG_KEXEC is not set +-# CONFIG_CRASH_DUMP is not set + CONFIG_ARCH_FLATMEM_ENABLE=y + CONFIG_ARCH_POPULATES_NODE_MAP=y + CONFIG_SELECT_MEMORY_MODEL=y +@@ -236,14 +231,12 @@ + CONFIG_PAGEFLAGS_EXTENDED=y + CONFIG_SPLIT_PTLOCK_CPUS=4 + CONFIG_MIGRATION=y ++# CONFIG_RESOURCES_64BIT is not set + # CONFIG_PHYS_ADDR_T_64BIT is not set + CONFIG_ZONE_DMA_FLAG=1 + CONFIG_BOUNCE=y + CONFIG_VIRT_TO_BUS=y + CONFIG_UNEVICTABLE_LRU=y +-CONFIG_PPC_4K_PAGES=y +-# CONFIG_PPC_16K_PAGES is not set +-# CONFIG_PPC_64K_PAGES is not set + CONFIG_FORCE_MAX_ZONEORDER=11 + CONFIG_PROC_DEVICETREE=y + # CONFIG_CMDLINE_BOOL is not set +@@ -271,7 +264,6 @@ + # CONFIG_PCI_MSI is not set + CONFIG_PCI_LEGACY=y + # CONFIG_PCI_DEBUG is not set +-# CONFIG_PCI_STUB is not set + # CONFIG_PCCARD is not set + # CONFIG_HOTPLUG_PCI is not set + # CONFIG_HAS_RAPIDIO is not set +@@ -294,7 +286,6 @@ + # + # Networking options + # +-CONFIG_COMPAT_NET_DEV_OPS=y + CONFIG_PACKET=y + # CONFIG_PACKET_MMAP is not set + CONFIG_UNIX=y +@@ -351,7 +342,6 @@ + # CONFIG_ECONET is not set + # CONFIG_WAN_ROUTER is not set + # CONFIG_NET_SCHED is not set +-# CONFIG_DCB is not set + + # + # Network testing +@@ -364,7 +354,6 @@ + # CONFIG_AF_RXRPC is not set + # CONFIG_PHONET is not set + # CONFIG_WIRELESS is not set +-# CONFIG_WIMAX is not set + # CONFIG_RFKILL is not set + # CONFIG_NET_9P is not set + +@@ -407,19 +396,13 @@ + # CONFIG_BLK_DEV_HD is not set + CONFIG_MISC_DEVICES=y + # CONFIG_PHANTOM is not set ++# CONFIG_EEPROM_93CX6 is not set + # CONFIG_SGI_IOC4 is not set + # CONFIG_TIFM_CORE is not set + # CONFIG_ICS932S401 is not set + # CONFIG_ENCLOSURE_SERVICES is not set + # CONFIG_HP_ILO is not set + # CONFIG_C2PORT is not set +- +-# +-# EEPROM support +-# +-# CONFIG_EEPROM_AT24 is not set +-# CONFIG_EEPROM_LEGACY is not set +-# CONFIG_EEPROM_93CX6 is not set + CONFIG_HAVE_IDE=y + # CONFIG_IDE is not set + +@@ -462,7 +445,6 @@ + # CONFIG_SCSI_SRP_ATTRS is not set + CONFIG_SCSI_LOWLEVEL=y + # CONFIG_ISCSI_TCP is not set +-# CONFIG_SCSI_CXGB3_ISCSI is not set + # CONFIG_BLK_DEV_3W_XXXX_RAID is not set + # CONFIG_SCSI_3W_9XXX is not set + # CONFIG_SCSI_ACARD is not set +@@ -479,8 +461,6 @@ + # CONFIG_MEGARAID_SAS is not set + # CONFIG_SCSI_HPTIOP is not set + # CONFIG_SCSI_BUSLOGIC is not set +-# CONFIG_LIBFC is not set +-# CONFIG_FCOE is not set + # CONFIG_SCSI_DMX3191D is not set + # CONFIG_SCSI_EATA is not set + # CONFIG_SCSI_FUTURE_DOMAIN is not set +@@ -600,9 +580,6 @@ + # CONFIG_BROADCOM_PHY is not set + # CONFIG_ICPLUS_PHY is not set + # CONFIG_REALTEK_PHY is not set +-# CONFIG_NATIONAL_PHY is not set +-# CONFIG_STE10XP is not set +-# CONFIG_LSI_ET1011C_PHY is not set + # CONFIG_FIXED_PHY is not set + # CONFIG_MDIO_BITBANG is not set + CONFIG_NET_ETHERNET=y +@@ -649,7 +626,6 @@ + # CONFIG_JME is not set + CONFIG_NETDEV_10000=y + # CONFIG_CHELSIO_T1 is not set +-CONFIG_CHELSIO_T3_DEPENDS=y + # CONFIG_CHELSIO_T3 is not set + # CONFIG_ENIC is not set + # CONFIG_IXGBE is not set +@@ -672,10 +648,6 @@ + # CONFIG_WLAN_PRE80211 is not set + # CONFIG_WLAN_80211 is not set + # CONFIG_IWLWIFI_LEDS is not set +- +-# +-# Enable WiMAX (Networking options) to see the WiMAX drivers +-# + # CONFIG_WAN is not set + # CONFIG_FDDI is not set + # CONFIG_HIPPI is not set +@@ -723,10 +695,8 @@ + CONFIG_SERIAL_MPC52xx_CONSOLE_BAUD=115200 + # CONFIG_SERIAL_JSM is not set + CONFIG_UNIX98_PTYS=y +-# CONFIG_DEVPTS_MULTIPLE_INSTANCES is not set + CONFIG_LEGACY_PTYS=y + CONFIG_LEGACY_PTY_COUNT=256 +-# CONFIG_HVC_UDBG is not set + # CONFIG_IPMI_HANDLER is not set + # CONFIG_HW_RANDOM is not set + # CONFIG_NVRAM is not set +@@ -792,6 +762,8 @@ + # Miscellaneous I2C Chip support + # + # CONFIG_DS1682 is not set ++# CONFIG_EEPROM_AT24 is not set ++# CONFIG_EEPROM_LEGACY is not set + # CONFIG_SENSORS_PCF8574 is not set + # CONFIG_PCF8575 is not set + # CONFIG_SENSORS_PCA9539 is not set +@@ -824,12 +796,10 @@ + # CONFIG_MFD_CORE is not set + # CONFIG_MFD_SM501 is not set + # CONFIG_HTC_PASIC3 is not set +-# CONFIG_TWL4030_CORE is not set + # CONFIG_MFD_TMIO is not set + # CONFIG_PMIC_DA903X is not set + # CONFIG_MFD_WM8400 is not set + # CONFIG_MFD_WM8350_I2C is not set +-# CONFIG_MFD_PCF50633 is not set + # CONFIG_REGULATOR is not set + + # +@@ -876,13 +846,9 @@ + # + + # +-# NOTE: USB_STORAGE depends on SCSI but BLK_DEV_SD may also be needed; ++# NOTE: USB_STORAGE enables SCSI, and 'SCSI disk support' + # + # CONFIG_USB_GADGET is not set +- +-# +-# OTG and related infrastructure +-# + # CONFIG_UWB is not set + # CONFIG_MMC is not set + # CONFIG_MEMSTICK is not set +@@ -894,6 +860,7 @@ + # CONFIG_DMADEVICES is not set + # CONFIG_UIO is not set + # CONFIG_STAGING is not set ++CONFIG_STAGING_EXCLUDE_BUILD=y + + # + # File systems +@@ -914,7 +881,6 @@ + CONFIG_FILE_LOCKING=y + # CONFIG_XFS_FS is not set + # CONFIG_OCFS2_FS is not set +-# CONFIG_BTRFS_FS is not set + CONFIG_DNOTIFY=y + CONFIG_INOTIFY=y + CONFIG_INOTIFY_USER=y +@@ -948,7 +914,10 @@ + # CONFIG_TMPFS_POSIX_ACL is not set + # CONFIG_HUGETLB_PAGE is not set + # CONFIG_CONFIGFS_FS is not set +-CONFIG_MISC_FILESYSTEMS=y ++ ++# ++# Miscellaneous filesystems ++# + # CONFIG_ADFS_FS is not set + # CONFIG_AFFS_FS is not set + # CONFIG_HFS_FS is not set +@@ -957,7 +926,6 @@ + # CONFIG_BFS_FS is not set + # CONFIG_EFS_FS is not set + # CONFIG_CRAMFS is not set +-# CONFIG_SQUASHFS is not set + # CONFIG_VXFS_FS is not set + # CONFIG_MINIX_FS is not set + # CONFIG_OMFS_FS is not set +@@ -999,7 +967,6 @@ + # Library routines + # + CONFIG_BITREVERSE=y +-CONFIG_GENERIC_FIND_LAST_BIT=y + # CONFIG_CRC_CCITT is not set + # CONFIG_CRC16 is not set + # CONFIG_CRC_T10DIF is not set +@@ -1049,7 +1016,6 @@ + # CONFIG_DEBUG_MEMORY_INIT is not set + # CONFIG_DEBUG_LIST is not set + # CONFIG_DEBUG_SG is not set +-# CONFIG_DEBUG_NOTIFIERS is not set + # CONFIG_BOOT_PRINTK_DELAY is not set + # CONFIG_RCU_TORTURE_TEST is not set + # CONFIG_RCU_CPU_STALL_DETECTOR is not set +@@ -1058,8 +1024,6 @@ + # CONFIG_FAULT_INJECTION is not set + # CONFIG_LATENCYTOP is not set + CONFIG_HAVE_FUNCTION_TRACER=y +-CONFIG_HAVE_DYNAMIC_FTRACE=y +-CONFIG_HAVE_FTRACE_MCOUNT_RECORD=y + + # + # Tracers +@@ -1068,13 +1032,11 @@ + # CONFIG_SCHED_TRACER is not set + # CONFIG_CONTEXT_SWITCH_TRACER is not set + # CONFIG_BOOT_TRACER is not set +-# CONFIG_TRACE_BRANCH_PROFILING is not set + # CONFIG_STACK_TRACER is not set + # CONFIG_DYNAMIC_PRINTK_DEBUG is not set + # CONFIG_SAMPLES is not set + CONFIG_HAVE_ARCH_KGDB=y + # CONFIG_KGDB is not set +-CONFIG_PRINT_STACK_DEPTH=64 + # CONFIG_DEBUG_STACKOVERFLOW is not set + # CONFIG_DEBUG_STACK_USAGE is not set + # CONFIG_DEBUG_PAGEALLOC is not set +@@ -1101,15 +1063,11 @@ + # + # CONFIG_CRYPTO_FIPS is not set + CONFIG_CRYPTO_ALGAPI=y +-CONFIG_CRYPTO_ALGAPI2=y +-CONFIG_CRYPTO_AEAD2=y ++CONFIG_CRYPTO_AEAD=y + CONFIG_CRYPTO_BLKCIPHER=y +-CONFIG_CRYPTO_BLKCIPHER2=y + CONFIG_CRYPTO_HASH=y +-CONFIG_CRYPTO_HASH2=y +-CONFIG_CRYPTO_RNG2=y ++CONFIG_CRYPTO_RNG=y + CONFIG_CRYPTO_MANAGER=y +-CONFIG_CRYPTO_MANAGER2=y + # CONFIG_CRYPTO_GF128MUL is not set + # CONFIG_CRYPTO_NULL is not set + # CONFIG_CRYPTO_CRYPTD is not set +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/arch/powerpc/configs/52xx/motionpro_defconfig linux-2.6.29-rc3.owrt/arch/powerpc/configs/52xx/motionpro_defconfig +--- linux-2.6.29.owrt/arch/powerpc/configs/52xx/motionpro_defconfig 2009-05-10 22:04:40.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/arch/powerpc/configs/52xx/motionpro_defconfig 2009-05-10 23:48:28.000000000 +0200 +@@ -1,7 +1,7 @@ + # + # Automatically generated make config: don't edit +-# Linux kernel version: 2.6.29-rc2 +-# Mon Jan 26 21:42:29 2009 ++# Linux kernel version: 2.6.28-rc4 ++# Thu Nov 13 02:11:02 2008 + # + # CONFIG_PPC64 is not set + +@@ -43,7 +43,7 @@ + CONFIG_PPC=y + CONFIG_EARLY_PRINTK=y + CONFIG_GENERIC_NVRAM=y +-CONFIG_SCHED_OMIT_FRAME_POINTER=y ++CONFIG_SCHED_NO_NO_OMIT_FRAME_POINTER=y + CONFIG_ARCH_MAY_HAVE_PC_FDC=y + CONFIG_PPC_OF=y + CONFIG_OF=y +@@ -71,23 +71,14 @@ + # CONFIG_BSD_PROCESS_ACCT is not set + # CONFIG_TASKSTATS is not set + # CONFIG_AUDIT is not set +- +-# +-# RCU Subsystem +-# +-CONFIG_CLASSIC_RCU=y +-# CONFIG_TREE_RCU is not set +-# CONFIG_PREEMPT_RCU is not set +-# CONFIG_TREE_RCU_TRACE is not set +-# CONFIG_PREEMPT_RCU_TRACE is not set + # CONFIG_IKCONFIG is not set + CONFIG_LOG_BUF_SHIFT=14 ++# CONFIG_CGROUPS is not set + CONFIG_GROUP_SCHED=y + CONFIG_FAIR_GROUP_SCHED=y + # CONFIG_RT_GROUP_SCHED is not set + CONFIG_USER_SCHED=y + # CONFIG_CGROUP_SCHED is not set +-# CONFIG_CGROUPS is not set + CONFIG_SYSFS_DEPRECATED=y + CONFIG_SYSFS_DEPRECATED_V2=y + # CONFIG_RELAY is not set +@@ -119,6 +110,7 @@ + CONFIG_SLUB=y + # CONFIG_SLOB is not set + # CONFIG_PROFILING is not set ++# CONFIG_MARKERS is not set + CONFIG_HAVE_OPROFILE=y + CONFIG_HAVE_EFFICIENT_UNALIGNED_ACCESS=y + CONFIG_HAVE_IOREMAP_PROT=y +@@ -129,11 +121,13 @@ + # CONFIG_HAVE_GENERIC_DMA_COHERENT is not set + CONFIG_SLABINFO=y + CONFIG_RT_MUTEXES=y ++# CONFIG_TINY_SHMEM is not set + CONFIG_BASE_SMALL=0 + # CONFIG_MODULES is not set + CONFIG_BLOCK=y + # CONFIG_LBD is not set + # CONFIG_BLK_DEV_IO_TRACE is not set ++# CONFIG_LSF is not set + # CONFIG_BLK_DEV_BSG is not set + # CONFIG_BLK_DEV_INTEGRITY is not set + +@@ -149,6 +143,7 @@ + # CONFIG_DEFAULT_CFQ is not set + # CONFIG_DEFAULT_NOOP is not set + CONFIG_DEFAULT_IOSCHED="anticipatory" ++CONFIG_CLASSIC_RCU=y + # CONFIG_FREEZER is not set + + # +@@ -187,9 +182,9 @@ + # CONFIG_TAU is not set + # CONFIG_FSL_ULI1575 is not set + CONFIG_PPC_BESTCOMM=y +-CONFIG_PPC_BESTCOMM_ATA=y ++# CONFIG_PPC_BESTCOMM_ATA is not set + CONFIG_PPC_BESTCOMM_FEC=y +-# CONFIG_SIMPLE_GPIO is not set ++# CONFIG_PPC_BESTCOMM_GEN_BD is not set + + # + # Kernel options +@@ -216,7 +211,6 @@ + CONFIG_ARCH_HAS_WALK_MEMORY=y + CONFIG_ARCH_ENABLE_MEMORY_HOTREMOVE=y + # CONFIG_KEXEC is not set +-# CONFIG_CRASH_DUMP is not set + CONFIG_ARCH_FLATMEM_ENABLE=y + CONFIG_ARCH_POPULATES_NODE_MAP=y + CONFIG_SELECT_MEMORY_MODEL=y +@@ -228,14 +222,12 @@ + CONFIG_PAGEFLAGS_EXTENDED=y + CONFIG_SPLIT_PTLOCK_CPUS=4 + CONFIG_MIGRATION=y ++# CONFIG_RESOURCES_64BIT is not set + # CONFIG_PHYS_ADDR_T_64BIT is not set + CONFIG_ZONE_DMA_FLAG=1 + CONFIG_BOUNCE=y + CONFIG_VIRT_TO_BUS=y + CONFIG_UNEVICTABLE_LRU=y +-CONFIG_PPC_4K_PAGES=y +-# CONFIG_PPC_16K_PAGES is not set +-# CONFIG_PPC_64K_PAGES is not set + CONFIG_FORCE_MAX_ZONEORDER=11 + CONFIG_PROC_DEVICETREE=y + # CONFIG_CMDLINE_BOOL is not set +@@ -276,7 +268,6 @@ + # + # Networking options + # +-CONFIG_COMPAT_NET_DEV_OPS=y + CONFIG_PACKET=y + # CONFIG_PACKET_MMAP is not set + CONFIG_UNIX=y +@@ -333,7 +324,6 @@ + # CONFIG_ECONET is not set + # CONFIG_WAN_ROUTER is not set + # CONFIG_NET_SCHED is not set +-# CONFIG_DCB is not set + + # + # Network testing +@@ -346,7 +336,6 @@ + # CONFIG_AF_RXRPC is not set + # CONFIG_PHONET is not set + # CONFIG_WIRELESS is not set +-# CONFIG_WIMAX is not set + # CONFIG_RFKILL is not set + # CONFIG_NET_9P is not set + +@@ -438,12 +427,6 @@ + # CONFIG_MTD_ONENAND is not set + + # +-# LPDDR flash memory drivers +-# +-# CONFIG_MTD_LPDDR is not set +-# CONFIG_MTD_QINFO_PROBE is not set +- +-# + # UBI - Unsorted block images + # + # CONFIG_MTD_UBI is not set +@@ -464,16 +447,10 @@ + # CONFIG_ATA_OVER_ETH is not set + # CONFIG_BLK_DEV_HD is not set + CONFIG_MISC_DEVICES=y ++# CONFIG_EEPROM_93CX6 is not set + # CONFIG_ICS932S401 is not set + # CONFIG_ENCLOSURE_SERVICES is not set + # CONFIG_C2PORT is not set +- +-# +-# EEPROM support +-# +-# CONFIG_EEPROM_AT24 is not set +-CONFIG_EEPROM_LEGACY=y +-# CONFIG_EEPROM_93CX6 is not set + CONFIG_HAVE_IDE=y + # CONFIG_IDE is not set + +@@ -515,7 +492,6 @@ + # CONFIG_SCSI_SRP_ATTRS is not set + CONFIG_SCSI_LOWLEVEL=y + # CONFIG_ISCSI_TCP is not set +-# CONFIG_LIBFC is not set + # CONFIG_SCSI_DEBUG is not set + # CONFIG_SCSI_DH is not set + CONFIG_ATA=y +@@ -549,9 +525,6 @@ + CONFIG_BROADCOM_PHY=y + CONFIG_ICPLUS_PHY=y + # CONFIG_REALTEK_PHY is not set +-# CONFIG_NATIONAL_PHY is not set +-# CONFIG_STE10XP is not set +-# CONFIG_LSI_ET1011C_PHY is not set + # CONFIG_FIXED_PHY is not set + CONFIG_MDIO_BITBANG=y + CONFIG_NET_ETHERNET=y +@@ -575,10 +548,6 @@ + # CONFIG_WLAN_PRE80211 is not set + # CONFIG_WLAN_80211 is not set + # CONFIG_IWLWIFI_LEDS is not set +- +-# +-# Enable WiMAX (Networking options) to see the WiMAX drivers +-# + # CONFIG_WAN is not set + # CONFIG_PPP is not set + # CONFIG_SLIP is not set +@@ -621,10 +590,8 @@ + CONFIG_SERIAL_MPC52xx_CONSOLE=y + CONFIG_SERIAL_MPC52xx_CONSOLE_BAUD=115200 + CONFIG_UNIX98_PTYS=y +-# CONFIG_DEVPTS_MULTIPLE_INSTANCES is not set + CONFIG_LEGACY_PTYS=y + CONFIG_LEGACY_PTY_COUNT=256 +-# CONFIG_HVC_UDBG is not set + # CONFIG_IPMI_HANDLER is not set + # CONFIG_HW_RANDOM is not set + # CONFIG_NVRAM is not set +@@ -662,6 +629,8 @@ + # Miscellaneous I2C Chip support + # + # CONFIG_DS1682 is not set ++# CONFIG_EEPROM_AT24 is not set ++CONFIG_EEPROM_LEGACY=y + # CONFIG_SENSORS_PCF8574 is not set + # CONFIG_PCF8575 is not set + # CONFIG_SENSORS_PCA9539 is not set +@@ -690,7 +659,6 @@ + # CONFIG_SENSORS_ADT7462 is not set + # CONFIG_SENSORS_ADT7470 is not set + # CONFIG_SENSORS_ADT7473 is not set +-# CONFIG_SENSORS_ADT7475 is not set + # CONFIG_SENSORS_ATXP1 is not set + # CONFIG_SENSORS_DS1621 is not set + # CONFIG_SENSORS_F71805F is not set +@@ -710,7 +678,6 @@ + # CONFIG_SENSORS_LM90 is not set + # CONFIG_SENSORS_LM92 is not set + # CONFIG_SENSORS_LM93 is not set +-# CONFIG_SENSORS_LTC4245 is not set + # CONFIG_SENSORS_MAX1619 is not set + # CONFIG_SENSORS_MAX6650 is not set + # CONFIG_SENSORS_PC87360 is not set +@@ -754,12 +721,10 @@ + # CONFIG_MFD_CORE is not set + # CONFIG_MFD_SM501 is not set + # CONFIG_HTC_PASIC3 is not set +-# CONFIG_TWL4030_CORE is not set + # CONFIG_MFD_TMIO is not set + # CONFIG_PMIC_DA903X is not set + # CONFIG_MFD_WM8400 is not set + # CONFIG_MFD_WM8350_I2C is not set +-# CONFIG_MFD_PCF50633 is not set + # CONFIG_REGULATOR is not set + + # +@@ -870,6 +835,7 @@ + # CONFIG_DMADEVICES is not set + # CONFIG_UIO is not set + # CONFIG_STAGING is not set ++CONFIG_STAGING_EXCLUDE_BUILD=y + + # + # File systems +@@ -890,7 +856,6 @@ + CONFIG_FILE_LOCKING=y + # CONFIG_XFS_FS is not set + # CONFIG_OCFS2_FS is not set +-# CONFIG_BTRFS_FS is not set + CONFIG_DNOTIFY=y + CONFIG_INOTIFY=y + CONFIG_INOTIFY_USER=y +@@ -927,7 +892,10 @@ + # CONFIG_TMPFS_POSIX_ACL is not set + # CONFIG_HUGETLB_PAGE is not set + # CONFIG_CONFIGFS_FS is not set +-CONFIG_MISC_FILESYSTEMS=y ++ ++# ++# Miscellaneous filesystems ++# + # CONFIG_ADFS_FS is not set + # CONFIG_AFFS_FS is not set + # CONFIG_HFS_FS is not set +@@ -947,7 +915,6 @@ + CONFIG_JFFS2_RTIME=y + # CONFIG_JFFS2_RUBIN is not set + CONFIG_CRAMFS=y +-# CONFIG_SQUASHFS is not set + # CONFIG_VXFS_FS is not set + # CONFIG_MINIX_FS is not set + # CONFIG_OMFS_FS is not set +@@ -1044,7 +1011,6 @@ + # Library routines + # + CONFIG_BITREVERSE=y +-CONFIG_GENERIC_FIND_LAST_BIT=y + # CONFIG_CRC_CCITT is not set + # CONFIG_CRC16 is not set + # CONFIG_CRC_T10DIF is not set +@@ -1096,7 +1062,6 @@ + # CONFIG_DEBUG_MEMORY_INIT is not set + # CONFIG_DEBUG_LIST is not set + # CONFIG_DEBUG_SG is not set +-# CONFIG_DEBUG_NOTIFIERS is not set + # CONFIG_BOOT_PRINTK_DELAY is not set + # CONFIG_RCU_TORTURE_TEST is not set + # CONFIG_RCU_CPU_STALL_DETECTOR is not set +@@ -1105,8 +1070,6 @@ + # CONFIG_FAULT_INJECTION is not set + # CONFIG_LATENCYTOP is not set + CONFIG_HAVE_FUNCTION_TRACER=y +-CONFIG_HAVE_DYNAMIC_FTRACE=y +-CONFIG_HAVE_FTRACE_MCOUNT_RECORD=y + + # + # Tracers +@@ -1115,13 +1078,11 @@ + # CONFIG_SCHED_TRACER is not set + # CONFIG_CONTEXT_SWITCH_TRACER is not set + # CONFIG_BOOT_TRACER is not set +-# CONFIG_TRACE_BRANCH_PROFILING is not set + # CONFIG_STACK_TRACER is not set + # CONFIG_DYNAMIC_PRINTK_DEBUG is not set + # CONFIG_SAMPLES is not set + CONFIG_HAVE_ARCH_KGDB=y + # CONFIG_KGDB is not set +-CONFIG_PRINT_STACK_DEPTH=64 + # CONFIG_DEBUG_STACKOVERFLOW is not set + # CONFIG_DEBUG_STACK_USAGE is not set + # CONFIG_DEBUG_PAGEALLOC is not set +@@ -1148,15 +1109,11 @@ + # + # CONFIG_CRYPTO_FIPS is not set + CONFIG_CRYPTO_ALGAPI=y +-CONFIG_CRYPTO_ALGAPI2=y +-CONFIG_CRYPTO_AEAD2=y ++CONFIG_CRYPTO_AEAD=y + CONFIG_CRYPTO_BLKCIPHER=y +-CONFIG_CRYPTO_BLKCIPHER2=y + CONFIG_CRYPTO_HASH=y +-CONFIG_CRYPTO_HASH2=y +-CONFIG_CRYPTO_RNG2=y ++CONFIG_CRYPTO_RNG=y + CONFIG_CRYPTO_MANAGER=y +-CONFIG_CRYPTO_MANAGER2=y + # CONFIG_CRYPTO_GF128MUL is not set + # CONFIG_CRYPTO_NULL is not set + # CONFIG_CRYPTO_CRYPTD is not set +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/arch/powerpc/configs/52xx/pcm030_defconfig linux-2.6.29-rc3.owrt/arch/powerpc/configs/52xx/pcm030_defconfig +--- linux-2.6.29.owrt/arch/powerpc/configs/52xx/pcm030_defconfig 2009-05-10 22:04:40.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/arch/powerpc/configs/52xx/pcm030_defconfig 2009-05-10 23:48:28.000000000 +0200 +@@ -1,7 +1,7 @@ + # + # Automatically generated make config: don't edit +-# Linux kernel version: 2.6.29-rc2 +-# Mon Jan 26 21:41:33 2009 ++# Linux kernel version: 2.6.28-rc4 ++# Thu Nov 13 02:13:16 2008 + # + # CONFIG_PPC64 is not set + +@@ -43,7 +43,7 @@ + CONFIG_PPC=y + CONFIG_EARLY_PRINTK=y + CONFIG_GENERIC_NVRAM=y +-CONFIG_SCHED_OMIT_FRAME_POINTER=y ++CONFIG_SCHED_NO_NO_OMIT_FRAME_POINTER=y + CONFIG_ARCH_MAY_HAVE_PC_FDC=y + CONFIG_PPC_OF=y + CONFIG_OF=y +@@ -72,24 +72,15 @@ + # CONFIG_BSD_PROCESS_ACCT is not set + # CONFIG_TASKSTATS is not set + # CONFIG_AUDIT is not set +- +-# +-# RCU Subsystem +-# +-CONFIG_CLASSIC_RCU=y +-# CONFIG_TREE_RCU is not set +-# CONFIG_PREEMPT_RCU is not set +-# CONFIG_TREE_RCU_TRACE is not set +-# CONFIG_PREEMPT_RCU_TRACE is not set + CONFIG_IKCONFIG=y + CONFIG_IKCONFIG_PROC=y + CONFIG_LOG_BUF_SHIFT=14 ++# CONFIG_CGROUPS is not set + CONFIG_GROUP_SCHED=y + CONFIG_FAIR_GROUP_SCHED=y + # CONFIG_RT_GROUP_SCHED is not set + CONFIG_USER_SCHED=y + # CONFIG_CGROUP_SCHED is not set +-# CONFIG_CGROUPS is not set + CONFIG_SYSFS_DEPRECATED=y + CONFIG_SYSFS_DEPRECATED_V2=y + # CONFIG_RELAY is not set +@@ -121,6 +112,7 @@ + # CONFIG_SLUB is not set + # CONFIG_SLOB is not set + # CONFIG_PROFILING is not set ++# CONFIG_MARKERS is not set + CONFIG_HAVE_OPROFILE=y + # CONFIG_KPROBES is not set + CONFIG_HAVE_EFFICIENT_UNALIGNED_ACCESS=y +@@ -132,6 +124,7 @@ + # CONFIG_HAVE_GENERIC_DMA_COHERENT is not set + CONFIG_SLABINFO=y + CONFIG_RT_MUTEXES=y ++# CONFIG_TINY_SHMEM is not set + CONFIG_BASE_SMALL=0 + CONFIG_MODULES=y + # CONFIG_MODULE_FORCE_LOAD is not set +@@ -139,9 +132,11 @@ + # CONFIG_MODULE_FORCE_UNLOAD is not set + # CONFIG_MODVERSIONS is not set + # CONFIG_MODULE_SRCVERSION_ALL is not set ++CONFIG_KMOD=y + CONFIG_BLOCK=y + # CONFIG_LBD is not set + # CONFIG_BLK_DEV_IO_TRACE is not set ++# CONFIG_LSF is not set + # CONFIG_BLK_DEV_BSG is not set + # CONFIG_BLK_DEV_INTEGRITY is not set + +@@ -157,6 +152,7 @@ + # CONFIG_DEFAULT_CFQ is not set + CONFIG_DEFAULT_NOOP=y + CONFIG_DEFAULT_IOSCHED="noop" ++CONFIG_CLASSIC_RCU=y + # CONFIG_FREEZER is not set + + # +@@ -195,9 +191,9 @@ + # CONFIG_TAU is not set + # CONFIG_FSL_ULI1575 is not set + CONFIG_PPC_BESTCOMM=y +-CONFIG_PPC_BESTCOMM_ATA=m ++CONFIG_PPC_BESTCOMM_ATA=y + CONFIG_PPC_BESTCOMM_FEC=y +-# CONFIG_SIMPLE_GPIO is not set ++CONFIG_PPC_BESTCOMM_GEN_BD=y + + # + # Kernel options +@@ -216,6 +212,7 @@ + # CONFIG_PREEMPT_NONE is not set + # CONFIG_PREEMPT_VOLUNTARY is not set + CONFIG_PREEMPT=y ++# CONFIG_PREEMPT_RCU is not set + CONFIG_BINFMT_ELF=y + # CONFIG_CORE_DUMP_DEFAULT_ELF_HEADERS is not set + # CONFIG_HAVE_AOUT is not set +@@ -225,7 +222,6 @@ + CONFIG_ARCH_HAS_WALK_MEMORY=y + CONFIG_ARCH_ENABLE_MEMORY_HOTREMOVE=y + # CONFIG_KEXEC is not set +-# CONFIG_CRASH_DUMP is not set + CONFIG_ARCH_FLATMEM_ENABLE=y + CONFIG_ARCH_POPULATES_NODE_MAP=y + CONFIG_SELECT_MEMORY_MODEL=y +@@ -237,14 +233,12 @@ + CONFIG_PAGEFLAGS_EXTENDED=y + CONFIG_SPLIT_PTLOCK_CPUS=4 + CONFIG_MIGRATION=y ++# CONFIG_RESOURCES_64BIT is not set + # CONFIG_PHYS_ADDR_T_64BIT is not set + CONFIG_ZONE_DMA_FLAG=1 + CONFIG_BOUNCE=y + CONFIG_VIRT_TO_BUS=y + CONFIG_UNEVICTABLE_LRU=y +-CONFIG_PPC_4K_PAGES=y +-# CONFIG_PPC_16K_PAGES is not set +-# CONFIG_PPC_64K_PAGES is not set + CONFIG_FORCE_MAX_ZONEORDER=11 + CONFIG_PROC_DEVICETREE=y + # CONFIG_CMDLINE_BOOL is not set +@@ -267,7 +261,6 @@ + CONFIG_ARCH_SUPPORTS_MSI=y + # CONFIG_PCI_MSI is not set + CONFIG_PCI_LEGACY=y +-# CONFIG_PCI_STUB is not set + # CONFIG_PCCARD is not set + # CONFIG_HOTPLUG_PCI is not set + # CONFIG_HAS_RAPIDIO is not set +@@ -290,7 +283,6 @@ + # + # Networking options + # +-CONFIG_COMPAT_NET_DEV_OPS=y + CONFIG_PACKET=y + # CONFIG_PACKET_MMAP is not set + CONFIG_UNIX=y +@@ -341,7 +333,6 @@ + # CONFIG_ECONET is not set + # CONFIG_WAN_ROUTER is not set + # CONFIG_NET_SCHED is not set +-# CONFIG_DCB is not set + + # + # Network testing +@@ -354,7 +345,6 @@ + # CONFIG_AF_RXRPC is not set + # CONFIG_PHONET is not set + # CONFIG_WIRELESS is not set +-# CONFIG_WIMAX is not set + # CONFIG_RFKILL is not set + # CONFIG_NET_9P is not set + +@@ -375,7 +365,6 @@ + # CONFIG_MTD_DEBUG is not set + # CONFIG_MTD_CONCAT is not set + CONFIG_MTD_PARTITIONS=y +-# CONFIG_MTD_TESTS is not set + # CONFIG_MTD_REDBOOT_PARTS is not set + CONFIG_MTD_CMDLINE_PARTS=y + # CONFIG_MTD_OF_PARTS is not set +@@ -424,7 +413,9 @@ + # + # CONFIG_MTD_COMPLEX_MAPPINGS is not set + CONFIG_MTD_PHYSMAP=y +-# CONFIG_MTD_PHYSMAP_COMPAT is not set ++CONFIG_MTD_PHYSMAP_START=0x0 ++CONFIG_MTD_PHYSMAP_LEN=0x0 ++CONFIG_MTD_PHYSMAP_BANKWIDTH=1 + # CONFIG_MTD_PHYSMAP_OF is not set + # CONFIG_MTD_INTEL_VR_NOR is not set + # CONFIG_MTD_PLATRAM is not set +@@ -448,12 +439,6 @@ + # CONFIG_MTD_ONENAND is not set + + # +-# LPDDR flash memory drivers +-# +-# CONFIG_MTD_LPDDR is not set +-# CONFIG_MTD_QINFO_PROBE is not set +- +-# + # UBI - Unsorted block images + # + # CONFIG_MTD_UBI is not set +@@ -602,9 +587,6 @@ + # CONFIG_BROADCOM_PHY is not set + # CONFIG_ICPLUS_PHY is not set + # CONFIG_REALTEK_PHY is not set +-# CONFIG_NATIONAL_PHY is not set +-# CONFIG_STE10XP is not set +-# CONFIG_LSI_ET1011C_PHY is not set + # CONFIG_FIXED_PHY is not set + # CONFIG_MDIO_BITBANG is not set + CONFIG_NET_ETHERNET=y +@@ -639,10 +621,6 @@ + # CONFIG_IWLWIFI_LEDS is not set + + # +-# Enable WiMAX (Networking options) to see the WiMAX drivers +-# +- +-# + # USB Network Adapters + # + # CONFIG_USB_CATC is not set +@@ -697,9 +675,7 @@ + CONFIG_SERIAL_MPC52xx_CONSOLE_BAUD=9600 + # CONFIG_SERIAL_JSM is not set + CONFIG_UNIX98_PTYS=y +-# CONFIG_DEVPTS_MULTIPLE_INSTANCES is not set + # CONFIG_LEGACY_PTYS is not set +-# CONFIG_HVC_UDBG is not set + # CONFIG_IPMI_HANDLER is not set + CONFIG_HW_RANDOM=y + # CONFIG_NVRAM is not set +@@ -764,6 +740,8 @@ + # Miscellaneous I2C Chip support + # + # CONFIG_DS1682 is not set ++# CONFIG_EEPROM_AT24 is not set ++CONFIG_EEPROM_LEGACY=m + # CONFIG_SENSORS_PCF8574 is not set + # CONFIG_PCF8575 is not set + # CONFIG_SENSORS_PCA9539 is not set +@@ -796,12 +774,10 @@ + # CONFIG_MFD_CORE is not set + # CONFIG_MFD_SM501 is not set + # CONFIG_HTC_PASIC3 is not set +-# CONFIG_TWL4030_CORE is not set + # CONFIG_MFD_TMIO is not set + # CONFIG_PMIC_DA903X is not set + # CONFIG_MFD_WM8400 is not set + # CONFIG_MFD_WM8350_I2C is not set +-# CONFIG_MFD_PCF50633 is not set + # CONFIG_REGULATOR is not set + + # +@@ -861,7 +837,6 @@ + # + # CONFIG_USB_C67X00_HCD is not set + # CONFIG_USB_EHCI_HCD is not set +-# CONFIG_USB_OXU210HP_HCD is not set + # CONFIG_USB_ISP116X_HCD is not set + # CONFIG_USB_ISP1760_HCD is not set + CONFIG_USB_OHCI_HCD=m +@@ -889,17 +864,18 @@ + # CONFIG_USB_TMC is not set + + # +-# NOTE: USB_STORAGE depends on SCSI but BLK_DEV_SD may also be needed; ++# NOTE: USB_STORAGE enables SCSI, and 'SCSI disk support' + # + + # +-# see USB_STORAGE Help for more information ++# may also be needed; see USB_STORAGE Help for more information + # + CONFIG_USB_STORAGE=m + # CONFIG_USB_STORAGE_DEBUG is not set + # CONFIG_USB_STORAGE_DATAFAB is not set + # CONFIG_USB_STORAGE_FREECOM is not set + # CONFIG_USB_STORAGE_ISD200 is not set ++# CONFIG_USB_STORAGE_DPCM is not set + # CONFIG_USB_STORAGE_USBAT is not set + # CONFIG_USB_STORAGE_SDDR09 is not set + # CONFIG_USB_STORAGE_SDDR55 is not set +@@ -945,10 +921,6 @@ + # CONFIG_USB_ISIGHTFW is not set + # CONFIG_USB_VST is not set + # CONFIG_USB_GADGET is not set +- +-# +-# OTG and related infrastructure +-# + # CONFIG_UWB is not set + # CONFIG_MMC is not set + # CONFIG_MEMSTICK is not set +@@ -1011,6 +983,7 @@ + # CONFIG_DMADEVICES is not set + # CONFIG_UIO is not set + # CONFIG_STAGING is not set ++CONFIG_STAGING_EXCLUDE_BUILD=y + + # + # File systems +@@ -1031,7 +1004,6 @@ + CONFIG_FILE_LOCKING=y + # CONFIG_XFS_FS is not set + # CONFIG_OCFS2_FS is not set +-# CONFIG_BTRFS_FS is not set + # CONFIG_DNOTIFY is not set + # CONFIG_INOTIFY is not set + # CONFIG_QUOTA is not set +@@ -1067,7 +1039,10 @@ + # CONFIG_TMPFS_POSIX_ACL is not set + # CONFIG_HUGETLB_PAGE is not set + # CONFIG_CONFIGFS_FS is not set +-CONFIG_MISC_FILESYSTEMS=y ++ ++# ++# Miscellaneous filesystems ++# + # CONFIG_ADFS_FS is not set + # CONFIG_AFFS_FS is not set + # CONFIG_HFS_FS is not set +@@ -1087,7 +1062,6 @@ + CONFIG_JFFS2_RTIME=y + # CONFIG_JFFS2_RUBIN is not set + # CONFIG_CRAMFS is not set +-# CONFIG_SQUASHFS is not set + # CONFIG_VXFS_FS is not set + # CONFIG_MINIX_FS is not set + # CONFIG_OMFS_FS is not set +@@ -1167,7 +1141,6 @@ + # Library routines + # + CONFIG_BITREVERSE=y +-CONFIG_GENERIC_FIND_LAST_BIT=y + # CONFIG_CRC_CCITT is not set + # CONFIG_CRC16 is not set + # CONFIG_CRC_T10DIF is not set +@@ -1200,8 +1173,6 @@ + # CONFIG_RCU_CPU_STALL_DETECTOR is not set + # CONFIG_LATENCYTOP is not set + CONFIG_HAVE_FUNCTION_TRACER=y +-CONFIG_HAVE_DYNAMIC_FTRACE=y +-CONFIG_HAVE_FTRACE_MCOUNT_RECORD=y + + # + # Tracers +@@ -1209,7 +1180,6 @@ + # CONFIG_DYNAMIC_PRINTK_DEBUG is not set + # CONFIG_SAMPLES is not set + CONFIG_HAVE_ARCH_KGDB=y +-CONFIG_PRINT_STACK_DEPTH=64 + # CONFIG_IRQSTACKS is not set + # CONFIG_BOOTX_TEXT is not set + # CONFIG_PPC_EARLY_DEBUG is not set +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/arch/powerpc/configs/52xx/tqm5200_defconfig linux-2.6.29-rc3.owrt/arch/powerpc/configs/52xx/tqm5200_defconfig +--- linux-2.6.29.owrt/arch/powerpc/configs/52xx/tqm5200_defconfig 2009-05-10 22:04:40.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/arch/powerpc/configs/52xx/tqm5200_defconfig 2009-05-10 23:48:28.000000000 +0200 +@@ -1,7 +1,7 @@ + # + # Automatically generated make config: don't edit +-# Linux kernel version: 2.6.29-rc2 +-# Mon Jan 26 21:42:58 2009 ++# Linux kernel version: 2.6.28-rc4 ++# Thu Nov 13 02:09:30 2008 + # + # CONFIG_PPC64 is not set + +@@ -43,7 +43,7 @@ + CONFIG_PPC=y + CONFIG_EARLY_PRINTK=y + CONFIG_GENERIC_NVRAM=y +-CONFIG_SCHED_OMIT_FRAME_POINTER=y ++CONFIG_SCHED_NO_NO_OMIT_FRAME_POINTER=y + CONFIG_ARCH_MAY_HAVE_PC_FDC=y + CONFIG_PPC_OF=y + CONFIG_OF=y +@@ -71,23 +71,14 @@ + # CONFIG_BSD_PROCESS_ACCT is not set + # CONFIG_TASKSTATS is not set + # CONFIG_AUDIT is not set +- +-# +-# RCU Subsystem +-# +-CONFIG_CLASSIC_RCU=y +-# CONFIG_TREE_RCU is not set +-# CONFIG_PREEMPT_RCU is not set +-# CONFIG_TREE_RCU_TRACE is not set +-# CONFIG_PREEMPT_RCU_TRACE is not set + # CONFIG_IKCONFIG is not set + CONFIG_LOG_BUF_SHIFT=14 ++# CONFIG_CGROUPS is not set + CONFIG_GROUP_SCHED=y + CONFIG_FAIR_GROUP_SCHED=y + # CONFIG_RT_GROUP_SCHED is not set + CONFIG_USER_SCHED=y + # CONFIG_CGROUP_SCHED is not set +-# CONFIG_CGROUPS is not set + CONFIG_SYSFS_DEPRECATED=y + CONFIG_SYSFS_DEPRECATED_V2=y + # CONFIG_RELAY is not set +@@ -119,6 +110,7 @@ + CONFIG_SLUB=y + # CONFIG_SLOB is not set + # CONFIG_PROFILING is not set ++# CONFIG_MARKERS is not set + CONFIG_HAVE_OPROFILE=y + CONFIG_HAVE_EFFICIENT_UNALIGNED_ACCESS=y + CONFIG_HAVE_IOREMAP_PROT=y +@@ -129,6 +121,7 @@ + # CONFIG_HAVE_GENERIC_DMA_COHERENT is not set + CONFIG_SLABINFO=y + CONFIG_RT_MUTEXES=y ++# CONFIG_TINY_SHMEM is not set + CONFIG_BASE_SMALL=0 + CONFIG_MODULES=y + # CONFIG_MODULE_FORCE_LOAD is not set +@@ -136,9 +129,11 @@ + # CONFIG_MODULE_FORCE_UNLOAD is not set + CONFIG_MODVERSIONS=y + # CONFIG_MODULE_SRCVERSION_ALL is not set ++CONFIG_KMOD=y + CONFIG_BLOCK=y + # CONFIG_LBD is not set + # CONFIG_BLK_DEV_IO_TRACE is not set ++# CONFIG_LSF is not set + # CONFIG_BLK_DEV_BSG is not set + # CONFIG_BLK_DEV_INTEGRITY is not set + +@@ -154,6 +149,7 @@ + # CONFIG_DEFAULT_CFQ is not set + # CONFIG_DEFAULT_NOOP is not set + CONFIG_DEFAULT_IOSCHED="anticipatory" ++CONFIG_CLASSIC_RCU=y + # CONFIG_FREEZER is not set + + # +@@ -192,9 +188,9 @@ + # CONFIG_TAU is not set + # CONFIG_FSL_ULI1575 is not set + CONFIG_PPC_BESTCOMM=y +-CONFIG_PPC_BESTCOMM_ATA=y ++# CONFIG_PPC_BESTCOMM_ATA is not set + CONFIG_PPC_BESTCOMM_FEC=y +-# CONFIG_SIMPLE_GPIO is not set ++# CONFIG_PPC_BESTCOMM_GEN_BD is not set + + # + # Kernel options +@@ -221,7 +217,6 @@ + CONFIG_ARCH_HAS_WALK_MEMORY=y + CONFIG_ARCH_ENABLE_MEMORY_HOTREMOVE=y + # CONFIG_KEXEC is not set +-# CONFIG_CRASH_DUMP is not set + CONFIG_ARCH_FLATMEM_ENABLE=y + CONFIG_ARCH_POPULATES_NODE_MAP=y + CONFIG_SELECT_MEMORY_MODEL=y +@@ -233,14 +228,12 @@ + CONFIG_PAGEFLAGS_EXTENDED=y + CONFIG_SPLIT_PTLOCK_CPUS=4 + CONFIG_MIGRATION=y ++# CONFIG_RESOURCES_64BIT is not set + # CONFIG_PHYS_ADDR_T_64BIT is not set + CONFIG_ZONE_DMA_FLAG=1 + CONFIG_BOUNCE=y + CONFIG_VIRT_TO_BUS=y + CONFIG_UNEVICTABLE_LRU=y +-CONFIG_PPC_4K_PAGES=y +-# CONFIG_PPC_16K_PAGES is not set +-# CONFIG_PPC_64K_PAGES is not set + CONFIG_FORCE_MAX_ZONEORDER=11 + CONFIG_PROC_DEVICETREE=y + # CONFIG_CMDLINE_BOOL is not set +@@ -281,7 +274,6 @@ + # + # Networking options + # +-CONFIG_COMPAT_NET_DEV_OPS=y + CONFIG_PACKET=y + # CONFIG_PACKET_MMAP is not set + CONFIG_UNIX=y +@@ -338,7 +330,6 @@ + # CONFIG_ECONET is not set + # CONFIG_WAN_ROUTER is not set + # CONFIG_NET_SCHED is not set +-# CONFIG_DCB is not set + + # + # Network testing +@@ -351,7 +342,6 @@ + # CONFIG_AF_RXRPC is not set + # CONFIG_PHONET is not set + # CONFIG_WIRELESS is not set +-# CONFIG_WIMAX is not set + # CONFIG_RFKILL is not set + # CONFIG_NET_9P is not set + +@@ -374,7 +364,6 @@ + # CONFIG_MTD_DEBUG is not set + CONFIG_MTD_CONCAT=y + CONFIG_MTD_PARTITIONS=y +-# CONFIG_MTD_TESTS is not set + # CONFIG_MTD_REDBOOT_PARTS is not set + CONFIG_MTD_CMDLINE_PARTS=y + # CONFIG_MTD_OF_PARTS is not set +@@ -444,12 +433,6 @@ + # CONFIG_MTD_ONENAND is not set + + # +-# LPDDR flash memory drivers +-# +-# CONFIG_MTD_LPDDR is not set +-# CONFIG_MTD_QINFO_PROBE is not set +- +-# + # UBI - Unsorted block images + # + # CONFIG_MTD_UBI is not set +@@ -513,7 +496,6 @@ + # CONFIG_SCSI_SRP_ATTRS is not set + CONFIG_SCSI_LOWLEVEL=y + # CONFIG_ISCSI_TCP is not set +-# CONFIG_LIBFC is not set + # CONFIG_SCSI_DEBUG is not set + # CONFIG_SCSI_DH is not set + CONFIG_ATA=y +@@ -548,9 +530,6 @@ + # CONFIG_BROADCOM_PHY is not set + # CONFIG_ICPLUS_PHY is not set + # CONFIG_REALTEK_PHY is not set +-# CONFIG_NATIONAL_PHY is not set +-# CONFIG_STE10XP is not set +-# CONFIG_LSI_ET1011C_PHY is not set + # CONFIG_FIXED_PHY is not set + # CONFIG_MDIO_BITBANG is not set + CONFIG_NET_ETHERNET=y +@@ -576,10 +555,6 @@ + # CONFIG_IWLWIFI_LEDS is not set + + # +-# Enable WiMAX (Networking options) to see the WiMAX drivers +-# +- +-# + # USB Network Adapters + # + # CONFIG_USB_CATC is not set +@@ -629,10 +604,8 @@ + CONFIG_SERIAL_MPC52xx_CONSOLE=y + CONFIG_SERIAL_MPC52xx_CONSOLE_BAUD=115200 + CONFIG_UNIX98_PTYS=y +-# CONFIG_DEVPTS_MULTIPLE_INSTANCES is not set + CONFIG_LEGACY_PTYS=y + CONFIG_LEGACY_PTY_COUNT=256 +-# CONFIG_HVC_UDBG is not set + # CONFIG_IPMI_HANDLER is not set + # CONFIG_HW_RANDOM is not set + # CONFIG_NVRAM is not set +@@ -672,6 +645,8 @@ + # Miscellaneous I2C Chip support + # + # CONFIG_DS1682 is not set ++# CONFIG_EEPROM_AT24 is not set ++# CONFIG_EEPROM_LEGACY is not set + # CONFIG_SENSORS_PCF8574 is not set + # CONFIG_PCF8575 is not set + # CONFIG_SENSORS_PCA9539 is not set +@@ -700,7 +675,6 @@ + # CONFIG_SENSORS_ADT7462 is not set + # CONFIG_SENSORS_ADT7470 is not set + # CONFIG_SENSORS_ADT7473 is not set +-# CONFIG_SENSORS_ADT7475 is not set + # CONFIG_SENSORS_ATXP1 is not set + # CONFIG_SENSORS_DS1621 is not set + # CONFIG_SENSORS_F71805F is not set +@@ -720,7 +694,6 @@ + # CONFIG_SENSORS_LM90 is not set + # CONFIG_SENSORS_LM92 is not set + # CONFIG_SENSORS_LM93 is not set +-# CONFIG_SENSORS_LTC4245 is not set + # CONFIG_SENSORS_MAX1619 is not set + # CONFIG_SENSORS_MAX6650 is not set + # CONFIG_SENSORS_PC87360 is not set +@@ -769,12 +742,10 @@ + # CONFIG_MFD_CORE is not set + # CONFIG_MFD_SM501 is not set + # CONFIG_HTC_PASIC3 is not set +-# CONFIG_TWL4030_CORE is not set + # CONFIG_MFD_TMIO is not set + # CONFIG_PMIC_DA903X is not set + # CONFIG_MFD_WM8400 is not set + # CONFIG_MFD_WM8350_I2C is not set +-# CONFIG_MFD_PCF50633 is not set + # CONFIG_REGULATOR is not set + + # +@@ -832,7 +803,6 @@ + # USB Host Controller Drivers + # + # CONFIG_USB_C67X00_HCD is not set +-# CONFIG_USB_OXU210HP_HCD is not set + # CONFIG_USB_ISP116X_HCD is not set + # CONFIG_USB_ISP1760_HCD is not set + CONFIG_USB_OHCI_HCD=y +@@ -857,17 +827,18 @@ + # CONFIG_USB_TMC is not set + + # +-# NOTE: USB_STORAGE depends on SCSI but BLK_DEV_SD may also be needed; ++# NOTE: USB_STORAGE enables SCSI, and 'SCSI disk support' + # + + # +-# see USB_STORAGE Help for more information ++# may also be needed; see USB_STORAGE Help for more information + # + CONFIG_USB_STORAGE=y + # CONFIG_USB_STORAGE_DEBUG is not set + # CONFIG_USB_STORAGE_DATAFAB is not set + # CONFIG_USB_STORAGE_FREECOM is not set + # CONFIG_USB_STORAGE_ISD200 is not set ++# CONFIG_USB_STORAGE_DPCM is not set + # CONFIG_USB_STORAGE_USBAT is not set + # CONFIG_USB_STORAGE_SDDR09 is not set + # CONFIG_USB_STORAGE_SDDR55 is not set +@@ -913,10 +884,6 @@ + # CONFIG_USB_ISIGHTFW is not set + # CONFIG_USB_VST is not set + # CONFIG_USB_GADGET is not set +- +-# +-# OTG and related infrastructure +-# + # CONFIG_MMC is not set + # CONFIG_MEMSTICK is not set + # CONFIG_NEW_LEDS is not set +@@ -980,6 +947,7 @@ + # CONFIG_DMADEVICES is not set + # CONFIG_UIO is not set + # CONFIG_STAGING is not set ++CONFIG_STAGING_EXCLUDE_BUILD=y + + # + # File systems +@@ -1000,7 +968,6 @@ + CONFIG_FILE_LOCKING=y + # CONFIG_XFS_FS is not set + # CONFIG_OCFS2_FS is not set +-# CONFIG_BTRFS_FS is not set + CONFIG_DNOTIFY=y + CONFIG_INOTIFY=y + CONFIG_INOTIFY_USER=y +@@ -1037,7 +1004,10 @@ + # CONFIG_TMPFS_POSIX_ACL is not set + # CONFIG_HUGETLB_PAGE is not set + # CONFIG_CONFIGFS_FS is not set +-CONFIG_MISC_FILESYSTEMS=y ++ ++# ++# Miscellaneous filesystems ++# + # CONFIG_ADFS_FS is not set + # CONFIG_AFFS_FS is not set + # CONFIG_HFS_FS is not set +@@ -1057,7 +1027,6 @@ + CONFIG_JFFS2_RTIME=y + # CONFIG_JFFS2_RUBIN is not set + CONFIG_CRAMFS=y +-# CONFIG_SQUASHFS is not set + # CONFIG_VXFS_FS is not set + # CONFIG_MINIX_FS is not set + # CONFIG_OMFS_FS is not set +@@ -1154,7 +1123,6 @@ + # Library routines + # + CONFIG_BITREVERSE=y +-CONFIG_GENERIC_FIND_LAST_BIT=y + # CONFIG_CRC_CCITT is not set + # CONFIG_CRC16 is not set + # CONFIG_CRC_T10DIF is not set +@@ -1206,7 +1174,6 @@ + # CONFIG_DEBUG_MEMORY_INIT is not set + # CONFIG_DEBUG_LIST is not set + # CONFIG_DEBUG_SG is not set +-# CONFIG_DEBUG_NOTIFIERS is not set + # CONFIG_BOOT_PRINTK_DELAY is not set + # CONFIG_RCU_TORTURE_TEST is not set + # CONFIG_RCU_CPU_STALL_DETECTOR is not set +@@ -1215,8 +1182,6 @@ + # CONFIG_FAULT_INJECTION is not set + # CONFIG_LATENCYTOP is not set + CONFIG_HAVE_FUNCTION_TRACER=y +-CONFIG_HAVE_DYNAMIC_FTRACE=y +-CONFIG_HAVE_FTRACE_MCOUNT_RECORD=y + + # + # Tracers +@@ -1225,13 +1190,11 @@ + # CONFIG_SCHED_TRACER is not set + # CONFIG_CONTEXT_SWITCH_TRACER is not set + # CONFIG_BOOT_TRACER is not set +-# CONFIG_TRACE_BRANCH_PROFILING is not set + # CONFIG_STACK_TRACER is not set + # CONFIG_DYNAMIC_PRINTK_DEBUG is not set + # CONFIG_SAMPLES is not set + CONFIG_HAVE_ARCH_KGDB=y + # CONFIG_KGDB is not set +-CONFIG_PRINT_STACK_DEPTH=64 + # CONFIG_DEBUG_STACKOVERFLOW is not set + # CONFIG_DEBUG_STACK_USAGE is not set + # CONFIG_DEBUG_PAGEALLOC is not set +@@ -1258,15 +1221,11 @@ + # + # CONFIG_CRYPTO_FIPS is not set + CONFIG_CRYPTO_ALGAPI=y +-CONFIG_CRYPTO_ALGAPI2=y +-CONFIG_CRYPTO_AEAD2=y ++CONFIG_CRYPTO_AEAD=y + CONFIG_CRYPTO_BLKCIPHER=y +-CONFIG_CRYPTO_BLKCIPHER2=y + CONFIG_CRYPTO_HASH=y +-CONFIG_CRYPTO_HASH2=y +-CONFIG_CRYPTO_RNG2=y ++CONFIG_CRYPTO_RNG=y + CONFIG_CRYPTO_MANAGER=y +-CONFIG_CRYPTO_MANAGER2=y + # CONFIG_CRYPTO_GF128MUL is not set + # CONFIG_CRYPTO_NULL is not set + # CONFIG_CRYPTO_CRYPTD is not set +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/arch/powerpc/configs/83xx/mpc8313_rdb_defconfig linux-2.6.29-rc3.owrt/arch/powerpc/configs/83xx/mpc8313_rdb_defconfig +--- linux-2.6.29.owrt/arch/powerpc/configs/83xx/mpc8313_rdb_defconfig 2009-05-10 22:04:40.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/arch/powerpc/configs/83xx/mpc8313_rdb_defconfig 2009-05-10 23:48:28.000000000 +0200 +@@ -651,7 +651,7 @@ + # CONFIG_NATIONAL_PHY is not set + # CONFIG_STE10XP is not set + # CONFIG_LSI_ET1011C_PHY is not set +-CONFIG_FIXED_PHY=y ++# CONFIG_FIXED_PHY is not set + # CONFIG_MDIO_BITBANG is not set + CONFIG_NET_ETHERNET=y + CONFIG_MII=y +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/arch/powerpc/configs/linkstation_defconfig linux-2.6.29-rc3.owrt/arch/powerpc/configs/linkstation_defconfig +--- linux-2.6.29.owrt/arch/powerpc/configs/linkstation_defconfig 2009-05-10 22:04:40.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/arch/powerpc/configs/linkstation_defconfig 2009-05-10 23:48:28.000000000 +0200 +@@ -1,7 +1,7 @@ + # + # Automatically generated make config: don't edit +-# Linux kernel version: 2.6.29-rc6 +-# Fri Mar 6 00:07:38 2009 ++# Linux kernel version: 2.6.29-rc2 ++# Mon Jan 26 15:35:29 2009 + # + # CONFIG_PPC64 is not set + +@@ -71,15 +71,6 @@ + # CONFIG_BSD_PROCESS_ACCT is not set + # CONFIG_TASKSTATS is not set + # CONFIG_AUDIT is not set +- +-# +-# RCU Subsystem +-# +-CONFIG_CLASSIC_RCU=y +-# CONFIG_TREE_RCU is not set +-# CONFIG_PREEMPT_RCU is not set +-# CONFIG_TREE_RCU_TRACE is not set +-# CONFIG_PREEMPT_RCU_TRACE is not set + CONFIG_IKCONFIG=y + CONFIG_IKCONFIG_PROC=y + CONFIG_LOG_BUF_SHIFT=14 +@@ -97,7 +88,6 @@ + # CONFIG_IPC_NS is not set + # CONFIG_USER_NS is not set + # CONFIG_PID_NS is not set +-# CONFIG_NET_NS is not set + CONFIG_BLK_DEV_INITRD=y + CONFIG_INITRAMFS_SOURCE="" + CONFIG_CC_OPTIMIZE_FOR_SIZE=y +@@ -163,6 +153,11 @@ + # CONFIG_DEFAULT_CFQ is not set + # CONFIG_DEFAULT_NOOP is not set + CONFIG_DEFAULT_IOSCHED="anticipatory" ++CONFIG_CLASSIC_RCU=y ++# CONFIG_TREE_RCU is not set ++# CONFIG_PREEMPT_RCU is not set ++# CONFIG_TREE_RCU_TRACE is not set ++# CONFIG_PREEMPT_RCU_TRACE is not set + # CONFIG_FREEZER is not set + + # +@@ -299,6 +294,7 @@ + # + # Networking options + # ++# CONFIG_NET_NS is not set + CONFIG_COMPAT_NET_DEV_OPS=y + CONFIG_PACKET=y + CONFIG_PACKET_MMAP=y +@@ -512,8 +508,8 @@ + CONFIG_MTD_PARTITIONS=y + # CONFIG_MTD_TESTS is not set + # CONFIG_MTD_REDBOOT_PARTS is not set +-CONFIG_MTD_CMDLINE_PARTS=y +-CONFIG_MTD_OF_PARTS=y ++# CONFIG_MTD_CMDLINE_PARTS is not set ++# CONFIG_MTD_OF_PARTS is not set + # CONFIG_MTD_AR7_PARTS is not set + + # +@@ -591,6 +587,7 @@ + # LPDDR flash memory drivers + # + # CONFIG_MTD_LPDDR is not set ++# CONFIG_MTD_QINFO_PROBE is not set + + # + # UBI - Unsorted block images +@@ -620,19 +617,13 @@ + # CONFIG_BLK_DEV_HD is not set + CONFIG_MISC_DEVICES=y + # CONFIG_PHANTOM is not set ++# CONFIG_EEPROM_93CX6 is not set + # CONFIG_SGI_IOC4 is not set + # CONFIG_TIFM_CORE is not set + # CONFIG_ICS932S401 is not set + # CONFIG_ENCLOSURE_SERVICES is not set + # CONFIG_HP_ILO is not set + # CONFIG_C2PORT is not set +- +-# +-# EEPROM support +-# +-# CONFIG_EEPROM_AT24 is not set +-CONFIG_EEPROM_LEGACY=m +-# CONFIG_EEPROM_93CX6 is not set + CONFIG_HAVE_IDE=y + # CONFIG_IDE is not set + +@@ -848,7 +839,6 @@ + # CONFIG_QLA3XXX is not set + # CONFIG_ATL1 is not set + # CONFIG_ATL1E is not set +-# CONFIG_ATL1C is not set + # CONFIG_JME is not set + CONFIG_NETDEV_10000=y + # CONFIG_CHELSIO_T1 is not set +@@ -1047,6 +1037,8 @@ + # Miscellaneous I2C Chip support + # + # CONFIG_DS1682 is not set ++# CONFIG_EEPROM_AT24 is not set ++CONFIG_EEPROM_LEGACY=m + # CONFIG_SENSORS_PCF8574 is not set + # CONFIG_PCF8575 is not set + # CONFIG_SENSORS_PCA9539 is not set +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/arch/powerpc/configs/mpc5200_defconfig linux-2.6.29-rc3.owrt/arch/powerpc/configs/mpc5200_defconfig +--- linux-2.6.29.owrt/arch/powerpc/configs/mpc5200_defconfig 2009-05-10 22:04:40.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/arch/powerpc/configs/mpc5200_defconfig 2009-05-10 23:48:28.000000000 +0200 +@@ -1,7 +1,7 @@ + # + # Automatically generated make config: don't edit +-# Linux kernel version: 2.6.29-rc2 +-# Mon Jan 26 21:40:44 2009 ++# Linux kernel version: 2.6.28-rc4 ++# Thu Nov 13 02:09:07 2008 + # + # CONFIG_PPC64 is not set + +@@ -43,7 +43,7 @@ + CONFIG_PPC=y + CONFIG_EARLY_PRINTK=y + CONFIG_GENERIC_NVRAM=y +-CONFIG_SCHED_OMIT_FRAME_POINTER=y ++CONFIG_SCHED_NO_NO_OMIT_FRAME_POINTER=y + CONFIG_ARCH_MAY_HAVE_PC_FDC=y + CONFIG_PPC_OF=y + CONFIG_OF=y +@@ -72,19 +72,10 @@ + # CONFIG_BSD_PROCESS_ACCT is not set + # CONFIG_TASKSTATS is not set + # CONFIG_AUDIT is not set +- +-# +-# RCU Subsystem +-# +-CONFIG_CLASSIC_RCU=y +-# CONFIG_TREE_RCU is not set +-# CONFIG_PREEMPT_RCU is not set +-# CONFIG_TREE_RCU_TRACE is not set +-# CONFIG_PREEMPT_RCU_TRACE is not set + # CONFIG_IKCONFIG is not set + CONFIG_LOG_BUF_SHIFT=14 +-# CONFIG_GROUP_SCHED is not set + # CONFIG_CGROUPS is not set ++# CONFIG_GROUP_SCHED is not set + CONFIG_SYSFS_DEPRECATED=y + CONFIG_SYSFS_DEPRECATED_V2=y + # CONFIG_RELAY is not set +@@ -117,6 +108,7 @@ + CONFIG_SLUB=y + # CONFIG_SLOB is not set + # CONFIG_PROFILING is not set ++# CONFIG_MARKERS is not set + CONFIG_HAVE_OPROFILE=y + CONFIG_HAVE_EFFICIENT_UNALIGNED_ACCESS=y + CONFIG_HAVE_IOREMAP_PROT=y +@@ -127,6 +119,7 @@ + # CONFIG_HAVE_GENERIC_DMA_COHERENT is not set + CONFIG_SLABINFO=y + CONFIG_RT_MUTEXES=y ++# CONFIG_TINY_SHMEM is not set + CONFIG_BASE_SMALL=0 + CONFIG_MODULES=y + # CONFIG_MODULE_FORCE_LOAD is not set +@@ -134,9 +127,11 @@ + # CONFIG_MODULE_FORCE_UNLOAD is not set + # CONFIG_MODVERSIONS is not set + # CONFIG_MODULE_SRCVERSION_ALL is not set ++CONFIG_KMOD=y + CONFIG_BLOCK=y + # CONFIG_LBD is not set + # CONFIG_BLK_DEV_IO_TRACE is not set ++# CONFIG_LSF is not set + # CONFIG_BLK_DEV_BSG is not set + # CONFIG_BLK_DEV_INTEGRITY is not set + +@@ -152,6 +147,7 @@ + # CONFIG_DEFAULT_CFQ is not set + # CONFIG_DEFAULT_NOOP is not set + CONFIG_DEFAULT_IOSCHED="anticipatory" ++CONFIG_CLASSIC_RCU=y + CONFIG_FREEZER=y + + # +@@ -196,7 +192,7 @@ + CONFIG_PPC_BESTCOMM=y + CONFIG_PPC_BESTCOMM_ATA=y + CONFIG_PPC_BESTCOMM_FEC=y +-# CONFIG_SIMPLE_GPIO is not set ++CONFIG_PPC_BESTCOMM_GEN_BD=y + + # + # Kernel options +@@ -224,7 +220,6 @@ + CONFIG_ARCH_HAS_WALK_MEMORY=y + CONFIG_ARCH_ENABLE_MEMORY_HOTREMOVE=y + # CONFIG_KEXEC is not set +-# CONFIG_CRASH_DUMP is not set + CONFIG_ARCH_FLATMEM_ENABLE=y + CONFIG_ARCH_POPULATES_NODE_MAP=y + CONFIG_SELECT_MEMORY_MODEL=y +@@ -236,14 +231,12 @@ + CONFIG_PAGEFLAGS_EXTENDED=y + CONFIG_SPLIT_PTLOCK_CPUS=4 + CONFIG_MIGRATION=y ++# CONFIG_RESOURCES_64BIT is not set + # CONFIG_PHYS_ADDR_T_64BIT is not set + CONFIG_ZONE_DMA_FLAG=1 + CONFIG_BOUNCE=y + CONFIG_VIRT_TO_BUS=y + CONFIG_UNEVICTABLE_LRU=y +-CONFIG_PPC_4K_PAGES=y +-# CONFIG_PPC_16K_PAGES is not set +-# CONFIG_PPC_64K_PAGES is not set + CONFIG_FORCE_MAX_ZONEORDER=11 + CONFIG_PROC_DEVICETREE=y + # CONFIG_CMDLINE_BOOL is not set +@@ -271,7 +264,6 @@ + # CONFIG_PCI_MSI is not set + CONFIG_PCI_LEGACY=y + # CONFIG_PCI_DEBUG is not set +-# CONFIG_PCI_STUB is not set + # CONFIG_PCCARD is not set + # CONFIG_HOTPLUG_PCI is not set + # CONFIG_HAS_RAPIDIO is not set +@@ -294,7 +286,6 @@ + # + # Networking options + # +-CONFIG_COMPAT_NET_DEV_OPS=y + CONFIG_PACKET=y + # CONFIG_PACKET_MMAP is not set + CONFIG_UNIX=y +@@ -351,7 +342,6 @@ + # CONFIG_ECONET is not set + # CONFIG_WAN_ROUTER is not set + # CONFIG_NET_SCHED is not set +-# CONFIG_DCB is not set + + # + # Network testing +@@ -364,7 +354,6 @@ + # CONFIG_AF_RXRPC is not set + # CONFIG_PHONET is not set + # CONFIG_WIRELESS is not set +-# CONFIG_WIMAX is not set + # CONFIG_RFKILL is not set + # CONFIG_NET_9P is not set + +@@ -387,7 +376,6 @@ + # CONFIG_MTD_DEBUG is not set + CONFIG_MTD_CONCAT=y + CONFIG_MTD_PARTITIONS=y +-# CONFIG_MTD_TESTS is not set + # CONFIG_MTD_REDBOOT_PARTS is not set + CONFIG_MTD_CMDLINE_PARTS=y + # CONFIG_MTD_OF_PARTS is not set +@@ -459,12 +447,6 @@ + # CONFIG_MTD_ONENAND is not set + + # +-# LPDDR flash memory drivers +-# +-# CONFIG_MTD_LPDDR is not set +-# CONFIG_MTD_QINFO_PROBE is not set +- +-# + # UBI - Unsorted block images + # + # CONFIG_MTD_UBI is not set +@@ -492,19 +474,13 @@ + # CONFIG_BLK_DEV_HD is not set + CONFIG_MISC_DEVICES=y + # CONFIG_PHANTOM is not set ++# CONFIG_EEPROM_93CX6 is not set + # CONFIG_SGI_IOC4 is not set + # CONFIG_TIFM_CORE is not set + # CONFIG_ICS932S401 is not set + # CONFIG_ENCLOSURE_SERVICES is not set + # CONFIG_HP_ILO is not set + # CONFIG_C2PORT is not set +- +-# +-# EEPROM support +-# +-# CONFIG_EEPROM_AT24 is not set +-# CONFIG_EEPROM_LEGACY is not set +-# CONFIG_EEPROM_93CX6 is not set + CONFIG_HAVE_IDE=y + # CONFIG_IDE is not set + +@@ -563,8 +539,6 @@ + # CONFIG_MEGARAID_SAS is not set + # CONFIG_SCSI_HPTIOP is not set + # CONFIG_SCSI_BUSLOGIC is not set +-# CONFIG_LIBFC is not set +-# CONFIG_FCOE is not set + # CONFIG_SCSI_DMX3191D is not set + # CONFIG_SCSI_EATA is not set + # CONFIG_SCSI_FUTURE_DOMAIN is not set +@@ -685,9 +659,6 @@ + # CONFIG_BROADCOM_PHY is not set + # CONFIG_ICPLUS_PHY is not set + # CONFIG_REALTEK_PHY is not set +-# CONFIG_NATIONAL_PHY is not set +-# CONFIG_STE10XP is not set +-# CONFIG_LSI_ET1011C_PHY is not set + # CONFIG_FIXED_PHY is not set + # CONFIG_MDIO_BITBANG is not set + CONFIG_NET_ETHERNET=y +@@ -722,10 +693,6 @@ + # CONFIG_IWLWIFI_LEDS is not set + + # +-# Enable WiMAX (Networking options) to see the WiMAX drivers +-# +- +-# + # USB Network Adapters + # + # CONFIG_USB_CATC is not set +@@ -807,11 +774,9 @@ + CONFIG_SERIAL_MPC52xx_CONSOLE_BAUD=115200 + # CONFIG_SERIAL_JSM is not set + CONFIG_UNIX98_PTYS=y +-# CONFIG_DEVPTS_MULTIPLE_INSTANCES is not set + CONFIG_LEGACY_PTYS=y + CONFIG_LEGACY_PTY_COUNT=256 + # CONFIG_HVC_RTAS is not set +-# CONFIG_HVC_UDBG is not set + # CONFIG_IPMI_HANDLER is not set + # CONFIG_HW_RANDOM is not set + # CONFIG_NVRAM is not set +@@ -879,6 +844,8 @@ + # Miscellaneous I2C Chip support + # + # CONFIG_DS1682 is not set ++# CONFIG_EEPROM_AT24 is not set ++# CONFIG_EEPROM_LEGACY is not set + # CONFIG_SENSORS_PCF8574 is not set + # CONFIG_PCF8575 is not set + # CONFIG_SENSORS_PCA9539 is not set +@@ -907,7 +874,6 @@ + # CONFIG_SENSORS_ADT7462 is not set + # CONFIG_SENSORS_ADT7470 is not set + # CONFIG_SENSORS_ADT7473 is not set +-# CONFIG_SENSORS_ADT7475 is not set + # CONFIG_SENSORS_ATXP1 is not set + # CONFIG_SENSORS_DS1621 is not set + # CONFIG_SENSORS_I5K_AMB is not set +@@ -928,7 +894,6 @@ + # CONFIG_SENSORS_LM90 is not set + # CONFIG_SENSORS_LM92 is not set + # CONFIG_SENSORS_LM93 is not set +-# CONFIG_SENSORS_LTC4245 is not set + # CONFIG_SENSORS_MAX1619 is not set + # CONFIG_SENSORS_MAX6650 is not set + # CONFIG_SENSORS_PC87360 is not set +@@ -988,12 +953,10 @@ + # CONFIG_MFD_CORE is not set + # CONFIG_MFD_SM501 is not set + # CONFIG_HTC_PASIC3 is not set +-# CONFIG_TWL4030_CORE is not set + # CONFIG_MFD_TMIO is not set + # CONFIG_PMIC_DA903X is not set + # CONFIG_MFD_WM8400 is not set + # CONFIG_MFD_WM8350_I2C is not set +-# CONFIG_MFD_PCF50633 is not set + # CONFIG_REGULATOR is not set + + # +@@ -1088,7 +1051,7 @@ + # CONFIG_LCD_ILI9320 is not set + # CONFIG_LCD_PLATFORM is not set + CONFIG_BACKLIGHT_CLASS_DEVICE=y +-CONFIG_BACKLIGHT_GENERIC=y ++# CONFIG_BACKLIGHT_CORGI is not set + + # + # Display device support +@@ -1130,22 +1093,21 @@ + CONFIG_HID_A4TECH=y + # CONFIG_HID_APPLE is not set + CONFIG_HID_BELKIN=y ++CONFIG_HID_BRIGHT=y + CONFIG_HID_CHERRY=y + # CONFIG_HID_CHICONY is not set + CONFIG_HID_CYPRESS=y ++CONFIG_HID_DELL=y + CONFIG_HID_EZKEY=y + # CONFIG_HID_GYRATION is not set + # CONFIG_HID_LOGITECH is not set + # CONFIG_HID_MICROSOFT is not set + # CONFIG_HID_MONTEREY is not set +-# CONFIG_HID_NTRIG is not set + # CONFIG_HID_PANTHERLORD is not set + # CONFIG_HID_PETALYNX is not set + # CONFIG_HID_SAMSUNG is not set + # CONFIG_HID_SONY is not set + # CONFIG_HID_SUNPLUS is not set +-# CONFIG_GREENASIA_FF is not set +-# CONFIG_HID_TOPSEED is not set + # CONFIG_THRUSTMASTER_FF is not set + # CONFIG_ZEROPLUS_FF is not set + CONFIG_USB_SUPPORT=y +@@ -1175,7 +1137,6 @@ + # + # CONFIG_USB_C67X00_HCD is not set + # CONFIG_USB_EHCI_HCD is not set +-# CONFIG_USB_OXU210HP_HCD is not set + # CONFIG_USB_ISP116X_HCD is not set + # CONFIG_USB_ISP1760_HCD is not set + CONFIG_USB_OHCI_HCD=y +@@ -1203,17 +1164,18 @@ + # CONFIG_USB_TMC is not set + + # +-# NOTE: USB_STORAGE depends on SCSI but BLK_DEV_SD may also be needed; ++# NOTE: USB_STORAGE enables SCSI, and 'SCSI disk support' + # + + # +-# see USB_STORAGE Help for more information ++# may also be needed; see USB_STORAGE Help for more information + # + CONFIG_USB_STORAGE=y + # CONFIG_USB_STORAGE_DEBUG is not set + # CONFIG_USB_STORAGE_DATAFAB is not set + # CONFIG_USB_STORAGE_FREECOM is not set + # CONFIG_USB_STORAGE_ISD200 is not set ++# CONFIG_USB_STORAGE_DPCM is not set + # CONFIG_USB_STORAGE_USBAT is not set + # CONFIG_USB_STORAGE_SDDR09 is not set + # CONFIG_USB_STORAGE_SDDR55 is not set +@@ -1260,10 +1222,6 @@ + # CONFIG_USB_ISIGHTFW is not set + # CONFIG_USB_VST is not set + # CONFIG_USB_GADGET is not set +- +-# +-# OTG and related infrastructure +-# + # CONFIG_UWB is not set + # CONFIG_MMC is not set + # CONFIG_MEMSTICK is not set +@@ -1285,6 +1243,7 @@ + # CONFIG_DMADEVICES is not set + # CONFIG_UIO is not set + # CONFIG_STAGING is not set ++CONFIG_STAGING_EXCLUDE_BUILD=y + + # + # File systems +@@ -1305,7 +1264,6 @@ + CONFIG_FILE_LOCKING=y + # CONFIG_XFS_FS is not set + # CONFIG_OCFS2_FS is not set +-# CONFIG_BTRFS_FS is not set + CONFIG_DNOTIFY=y + CONFIG_INOTIFY=y + CONFIG_INOTIFY_USER=y +@@ -1342,7 +1300,10 @@ + # CONFIG_TMPFS_POSIX_ACL is not set + # CONFIG_HUGETLB_PAGE is not set + # CONFIG_CONFIGFS_FS is not set +-CONFIG_MISC_FILESYSTEMS=y ++ ++# ++# Miscellaneous filesystems ++# + # CONFIG_ADFS_FS is not set + # CONFIG_AFFS_FS is not set + # CONFIG_HFS_FS is not set +@@ -1362,7 +1323,6 @@ + CONFIG_JFFS2_RTIME=y + # CONFIG_JFFS2_RUBIN is not set + CONFIG_CRAMFS=y +-# CONFIG_SQUASHFS is not set + # CONFIG_VXFS_FS is not set + # CONFIG_MINIX_FS is not set + # CONFIG_OMFS_FS is not set +@@ -1443,7 +1403,6 @@ + # Library routines + # + CONFIG_BITREVERSE=y +-CONFIG_GENERIC_FIND_LAST_BIT=y + # CONFIG_CRC_CCITT is not set + # CONFIG_CRC16 is not set + # CONFIG_CRC_T10DIF is not set +@@ -1495,7 +1454,6 @@ + # CONFIG_DEBUG_MEMORY_INIT is not set + # CONFIG_DEBUG_LIST is not set + # CONFIG_DEBUG_SG is not set +-# CONFIG_DEBUG_NOTIFIERS is not set + # CONFIG_BOOT_PRINTK_DELAY is not set + # CONFIG_RCU_TORTURE_TEST is not set + # CONFIG_RCU_CPU_STALL_DETECTOR is not set +@@ -1504,8 +1462,6 @@ + # CONFIG_FAULT_INJECTION is not set + # CONFIG_LATENCYTOP is not set + CONFIG_HAVE_FUNCTION_TRACER=y +-CONFIG_HAVE_DYNAMIC_FTRACE=y +-CONFIG_HAVE_FTRACE_MCOUNT_RECORD=y + + # + # Tracers +@@ -1514,13 +1470,11 @@ + # CONFIG_SCHED_TRACER is not set + # CONFIG_CONTEXT_SWITCH_TRACER is not set + # CONFIG_BOOT_TRACER is not set +-# CONFIG_TRACE_BRANCH_PROFILING is not set + # CONFIG_STACK_TRACER is not set + # CONFIG_DYNAMIC_PRINTK_DEBUG is not set + # CONFIG_SAMPLES is not set + CONFIG_HAVE_ARCH_KGDB=y + # CONFIG_KGDB is not set +-CONFIG_PRINT_STACK_DEPTH=64 + # CONFIG_DEBUG_STACKOVERFLOW is not set + # CONFIG_DEBUG_STACK_USAGE is not set + # CONFIG_DEBUG_PAGEALLOC is not set +@@ -1547,15 +1501,11 @@ + # + # CONFIG_CRYPTO_FIPS is not set + CONFIG_CRYPTO_ALGAPI=y +-CONFIG_CRYPTO_ALGAPI2=y +-CONFIG_CRYPTO_AEAD2=y ++CONFIG_CRYPTO_AEAD=y + CONFIG_CRYPTO_BLKCIPHER=y +-CONFIG_CRYPTO_BLKCIPHER2=y + CONFIG_CRYPTO_HASH=y +-CONFIG_CRYPTO_HASH2=y +-CONFIG_CRYPTO_RNG2=y ++CONFIG_CRYPTO_RNG=y + CONFIG_CRYPTO_MANAGER=y +-CONFIG_CRYPTO_MANAGER2=y + # CONFIG_CRYPTO_GF128MUL is not set + # CONFIG_CRYPTO_NULL is not set + # CONFIG_CRYPTO_CRYPTD is not set +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/arch/powerpc/configs/ps3_defconfig linux-2.6.29-rc3.owrt/arch/powerpc/configs/ps3_defconfig +--- linux-2.6.29.owrt/arch/powerpc/configs/ps3_defconfig 2009-05-10 22:04:40.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/arch/powerpc/configs/ps3_defconfig 2009-05-10 23:48:28.000000000 +0200 +@@ -1,7 +1,7 @@ + # + # Automatically generated make config: don't edit +-# Linux kernel version: 2.6.29-rc8 +-# Fri Mar 13 09:28:45 2009 ++# Linux kernel version: 2.6.27-rc3 ++# Wed Aug 20 08:16:53 2008 + # + CONFIG_PPC64=y + +@@ -16,14 +16,13 @@ + CONFIG_ALTIVEC=y + # CONFIG_VSX is not set + CONFIG_PPC_STD_MMU=y +-CONFIG_PPC_STD_MMU_64=y + CONFIG_PPC_MM_SLICES=y + CONFIG_VIRT_CPU_ACCOUNTING=y + CONFIG_SMP=y + CONFIG_NR_CPUS=2 + CONFIG_64BIT=y + CONFIG_WORD_SIZE=64 +-CONFIG_ARCH_PHYS_ADDR_T_64BIT=y ++CONFIG_PPC_MERGE=y + CONFIG_MMU=y + CONFIG_GENERIC_CMOS_UPDATE=y + CONFIG_GENERIC_TIME=y +@@ -47,7 +46,7 @@ + CONFIG_EARLY_PRINTK=y + CONFIG_COMPAT=y + CONFIG_SYSVIPC_COMPAT=y +-CONFIG_SCHED_OMIT_FRAME_POINTER=y ++CONFIG_SCHED_NO_NO_OMIT_FRAME_POINTER=y + CONFIG_ARCH_MAY_HAVE_PC_FDC=y + CONFIG_PPC_OF=y + CONFIG_OF=y +@@ -75,19 +74,10 @@ + # CONFIG_BSD_PROCESS_ACCT is not set + # CONFIG_TASKSTATS is not set + # CONFIG_AUDIT is not set +- +-# +-# RCU Subsystem +-# +-CONFIG_CLASSIC_RCU=y +-# CONFIG_TREE_RCU is not set +-# CONFIG_PREEMPT_RCU is not set +-# CONFIG_TREE_RCU_TRACE is not set +-# CONFIG_PREEMPT_RCU_TRACE is not set + # CONFIG_IKCONFIG is not set + CONFIG_LOG_BUF_SHIFT=17 +-# CONFIG_GROUP_SCHED is not set + # CONFIG_CGROUPS is not set ++# CONFIG_GROUP_SCHED is not set + CONFIG_SYSFS_DEPRECATED=y + CONFIG_SYSFS_DEPRECATED_V2=y + # CONFIG_RELAY is not set +@@ -96,13 +86,11 @@ + # CONFIG_IPC_NS is not set + # CONFIG_USER_NS is not set + # CONFIG_PID_NS is not set +-# CONFIG_NET_NS is not set + CONFIG_BLK_DEV_INITRD=y + CONFIG_INITRAMFS_SOURCE="" + CONFIG_CC_OPTIMIZE_FOR_SIZE=y + CONFIG_SYSCTL=y +-CONFIG_ANON_INODES=y +-CONFIG_EMBEDDED=y ++# CONFIG_EMBEDDED is not set + CONFIG_SYSCTL_SYSCALL=y + CONFIG_KALLSYMS=y + CONFIG_KALLSYMS_ALL=y +@@ -111,36 +99,37 @@ + CONFIG_PRINTK=y + CONFIG_BUG=y + CONFIG_ELF_CORE=y ++# CONFIG_COMPAT_BRK is not set + CONFIG_BASE_FULL=y + CONFIG_FUTEX=y ++CONFIG_ANON_INODES=y + CONFIG_EPOLL=y + CONFIG_SIGNALFD=y + CONFIG_TIMERFD=y + CONFIG_EVENTFD=y + CONFIG_SHMEM=y +-CONFIG_AIO=y + CONFIG_VM_EVENT_COUNTERS=y +-# CONFIG_COMPAT_BRK is not set + CONFIG_SLAB=y + # CONFIG_SLUB is not set + # CONFIG_SLOB is not set + CONFIG_PROFILING=y +-CONFIG_TRACEPOINTS=y +-CONFIG_MARKERS=y ++# CONFIG_MARKERS is not set + CONFIG_OPROFILE=m + CONFIG_HAVE_OPROFILE=y + # CONFIG_KPROBES is not set + CONFIG_HAVE_EFFICIENT_UNALIGNED_ACCESS=y +-CONFIG_HAVE_SYSCALL_WRAPPERS=y + CONFIG_HAVE_IOREMAP_PROT=y + CONFIG_HAVE_KPROBES=y + CONFIG_HAVE_KRETPROBES=y + CONFIG_HAVE_ARCH_TRACEHOOK=y + CONFIG_HAVE_DMA_ATTRS=y + CONFIG_USE_GENERIC_SMP_HELPERS=y ++# CONFIG_HAVE_CLK is not set ++CONFIG_PROC_PAGE_MONITOR=y + # CONFIG_HAVE_GENERIC_DMA_COHERENT is not set + CONFIG_SLABINFO=y + CONFIG_RT_MUTEXES=y ++# CONFIG_TINY_SHMEM is not set + CONFIG_BASE_SMALL=0 + CONFIG_MODULES=y + # CONFIG_MODULE_FORCE_LOAD is not set +@@ -148,6 +137,7 @@ + # CONFIG_MODULE_FORCE_UNLOAD is not set + # CONFIG_MODVERSIONS is not set + # CONFIG_MODULE_SRCVERSION_ALL is not set ++CONFIG_KMOD=y + CONFIG_STOP_MACHINE=y + CONFIG_BLOCK=y + # CONFIG_BLK_DEV_IO_TRACE is not set +@@ -167,7 +157,7 @@ + # CONFIG_DEFAULT_CFQ is not set + # CONFIG_DEFAULT_NOOP is not set + CONFIG_DEFAULT_IOSCHED="anticipatory" +-# CONFIG_FREEZER is not set ++CONFIG_CLASSIC_RCU=y + + # + # Platform support +@@ -193,20 +183,18 @@ + CONFIG_PS3_DISK=y + CONFIG_PS3_ROM=y + CONFIG_PS3_FLASH=y +-CONFIG_PS3_VRAM=m ++CONFIG_OPROFILE_PS3=y + CONFIG_PS3_LPM=m + CONFIG_PPC_CELL=y + # CONFIG_PPC_CELL_NATIVE is not set + # CONFIG_PPC_IBM_CELL_BLADE is not set + # CONFIG_PPC_CELLEB is not set +-# CONFIG_PPC_CELL_QPACE is not set + + # + # Cell Broadband Engine options + # + CONFIG_SPU_FS=y + CONFIG_SPU_FS_64K_LS=y +-# CONFIG_SPU_TRACE is not set + CONFIG_SPU_BASE=y + # CONFIG_PQ2ADS is not set + # CONFIG_IPIC is not set +@@ -222,7 +210,6 @@ + # CONFIG_GENERIC_IOMAP is not set + # CONFIG_CPU_FREQ is not set + # CONFIG_FSL_ULI1575 is not set +-# CONFIG_SIMPLE_GPIO is not set + + # + # Kernel options +@@ -242,8 +229,6 @@ + # CONFIG_PREEMPT is not set + CONFIG_BINFMT_ELF=y + CONFIG_COMPAT_BINFMT_ELF=y +-# CONFIG_CORE_DUMP_DEFAULT_ELF_HEADERS is not set +-# CONFIG_HAVE_AOUT is not set + CONFIG_BINFMT_MISC=y + CONFIG_HUGETLB_PAGE_SIZE_VARIABLE=y + # CONFIG_IOMMU_VMERGE is not set +@@ -266,6 +251,7 @@ + CONFIG_SPARSEMEM_MANUAL=y + CONFIG_SPARSEMEM=y + CONFIG_HAVE_MEMORY_PRESENT=y ++# CONFIG_SPARSEMEM_STATIC is not set + CONFIG_SPARSEMEM_EXTREME=y + CONFIG_SPARSEMEM_VMEMMAP_ENABLE=y + # CONFIG_SPARSEMEM_VMEMMAP is not set +@@ -275,14 +261,11 @@ + CONFIG_PAGEFLAGS_EXTENDED=y + CONFIG_SPLIT_PTLOCK_CPUS=4 + CONFIG_MIGRATION=y +-CONFIG_PHYS_ADDR_T_64BIT=y ++CONFIG_RESOURCES_64BIT=y + CONFIG_ZONE_DMA_FLAG=1 + CONFIG_BOUNCE=y +-CONFIG_UNEVICTABLE_LRU=y + CONFIG_ARCH_MEMORY_PROBE=y + CONFIG_PPC_HAS_HASH_64K=y +-CONFIG_PPC_4K_PAGES=y +-# CONFIG_PPC_16K_PAGES is not set + # CONFIG_PPC_64K_PAGES is not set + CONFIG_FORCE_MAX_ZONEORDER=13 + CONFIG_SCHED_SMT=y +@@ -316,7 +299,6 @@ + # + # Networking options + # +-CONFIG_COMPAT_NET_DEV_OPS=y + CONFIG_PACKET=y + CONFIG_PACKET_MMAP=y + CONFIG_UNIX=y +@@ -379,7 +361,6 @@ + # CONFIG_TIPC is not set + # CONFIG_ATM is not set + # CONFIG_BRIDGE is not set +-# CONFIG_NET_DSA is not set + # CONFIG_VLAN_8021Q is not set + # CONFIG_DECNET is not set + # CONFIG_LLC2 is not set +@@ -390,7 +371,6 @@ + # CONFIG_ECONET is not set + # CONFIG_WAN_ROUTER is not set + # CONFIG_NET_SCHED is not set +-# CONFIG_DCB is not set + + # + # Network testing +@@ -412,37 +392,39 @@ + # + # Bluetooth device drivers + # +-CONFIG_BT_HCIBTUSB=m ++CONFIG_BT_HCIUSB=m ++CONFIG_BT_HCIUSB_SCO=y + # CONFIG_BT_HCIUART is not set + # CONFIG_BT_HCIBCM203X is not set + # CONFIG_BT_HCIBPA10X is not set + # CONFIG_BT_HCIBFUSB is not set + # CONFIG_BT_HCIVHCI is not set + # CONFIG_AF_RXRPC is not set +-# CONFIG_PHONET is not set +-CONFIG_WIRELESS=y ++ ++# ++# Wireless ++# + CONFIG_CFG80211=m +-# CONFIG_CFG80211_REG_DEBUG is not set + CONFIG_NL80211=y +-# CONFIG_WIRELESS_OLD_REGULATORY is not set + CONFIG_WIRELESS_EXT=y + # CONFIG_WIRELESS_EXT_SYSFS is not set +-# CONFIG_LIB80211 is not set + CONFIG_MAC80211=m + + # + # Rate control algorithm selection + # + CONFIG_MAC80211_RC_PID=y +-# CONFIG_MAC80211_RC_MINSTREL is not set + CONFIG_MAC80211_RC_DEFAULT_PID=y +-# CONFIG_MAC80211_RC_DEFAULT_MINSTREL is not set + CONFIG_MAC80211_RC_DEFAULT="pid" + # CONFIG_MAC80211_MESH is not set + # CONFIG_MAC80211_LEDS is not set + # CONFIG_MAC80211_DEBUGFS is not set + # CONFIG_MAC80211_DEBUG_MENU is not set +-# CONFIG_WIMAX is not set ++CONFIG_IEEE80211=m ++# CONFIG_IEEE80211_DEBUG is not set ++CONFIG_IEEE80211_CRYPT_WEP=m ++CONFIG_IEEE80211_CRYPT_CCMP=m ++CONFIG_IEEE80211_CRYPT_TKIP=m + # CONFIG_RFKILL is not set + # CONFIG_NET_9P is not set + +@@ -468,7 +450,6 @@ + CONFIG_MTD_DEBUG_VERBOSE=0 + # CONFIG_MTD_CONCAT is not set + # CONFIG_MTD_PARTITIONS is not set +-# CONFIG_MTD_TESTS is not set + + # + # User Modules And Translation Layers +@@ -513,6 +494,7 @@ + # + # CONFIG_MTD_SLRAM is not set + # CONFIG_MTD_PHRAM is not set ++CONFIG_MTD_PS3VRAM=y + # CONFIG_MTD_MTDRAM is not set + # CONFIG_MTD_BLOCK2MTD is not set + +@@ -526,11 +508,6 @@ + # CONFIG_MTD_ONENAND is not set + + # +-# LPDDR flash memory drivers +-# +-# CONFIG_MTD_LPDDR is not set +- +-# + # UBI - Unsorted block images + # + # CONFIG_MTD_UBI is not set +@@ -551,13 +528,8 @@ + # CONFIG_ATA_OVER_ETH is not set + # CONFIG_BLK_DEV_HD is not set + CONFIG_MISC_DEVICES=y +-# CONFIG_ENCLOSURE_SERVICES is not set +-# CONFIG_C2PORT is not set +- +-# +-# EEPROM support +-# + # CONFIG_EEPROM_93CX6 is not set ++# CONFIG_ENCLOSURE_SERVICES is not set + CONFIG_HAVE_IDE=y + # CONFIG_IDE is not set + +@@ -603,17 +575,7 @@ + # CONFIG_SCSI_LOWLEVEL is not set + # CONFIG_SCSI_DH is not set + # CONFIG_ATA is not set +-CONFIG_MD=y +-# CONFIG_BLK_DEV_MD is not set +-CONFIG_BLK_DEV_DM=m +-# CONFIG_DM_DEBUG is not set +-# CONFIG_DM_CRYPT is not set +-# CONFIG_DM_SNAPSHOT is not set +-# CONFIG_DM_MIRROR is not set +-# CONFIG_DM_ZERO is not set +-# CONFIG_DM_MULTIPATH is not set +-# CONFIG_DM_DELAY is not set +-# CONFIG_DM_UEVENT is not set ++# CONFIG_MD is not set + # CONFIG_MACINTOSH_DRIVERS is not set + CONFIG_NETDEVICES=y + # CONFIG_DUMMY is not set +@@ -629,9 +591,6 @@ + # CONFIG_IBM_NEW_EMAC_RGMII is not set + # CONFIG_IBM_NEW_EMAC_TAH is not set + # CONFIG_IBM_NEW_EMAC_EMAC4 is not set +-# CONFIG_IBM_NEW_EMAC_NO_FLOW_CTRL is not set +-# CONFIG_IBM_NEW_EMAC_MAL_CLR_ICINTSTAT is not set +-# CONFIG_IBM_NEW_EMAC_MAL_COMMON_ERR is not set + # CONFIG_B44 is not set + CONFIG_NETDEV_1000=y + CONFIG_GELIC_NET=y +@@ -645,7 +604,6 @@ + # CONFIG_WLAN_PRE80211 is not set + CONFIG_WLAN_80211=y + # CONFIG_LIBERTAS is not set +-# CONFIG_LIBERTAS_THINFIRM is not set + # CONFIG_USB_ZD1201 is not set + # CONFIG_USB_NET_RNDIS_WLAN is not set + # CONFIG_RTL8187 is not set +@@ -657,11 +615,13 @@ + # CONFIG_B43LEGACY is not set + CONFIG_ZD1211RW=m + # CONFIG_ZD1211RW_DEBUG is not set +-# CONFIG_RT2X00 is not set +- +-# +-# Enable WiMAX (Networking options) to see the WiMAX drivers +-# ++CONFIG_RT2X00=m ++CONFIG_RT2X00_LIB=m ++CONFIG_RT2X00_LIB_USB=m ++CONFIG_RT2X00_LIB_FIRMWARE=y ++# CONFIG_RT2500USB is not set ++CONFIG_RT73USB=m ++# CONFIG_RT2X00_DEBUG is not set + + # + # USB Network Adapters +@@ -674,7 +634,6 @@ + CONFIG_USB_NET_AX8817X=m + # CONFIG_USB_NET_CDCETHER is not set + # CONFIG_USB_NET_DM9601 is not set +-# CONFIG_USB_NET_SMSC95XX is not set + # CONFIG_USB_NET_GL620A is not set + # CONFIG_USB_NET_NET1080 is not set + # CONFIG_USB_NET_PLUSB is not set +@@ -705,7 +664,7 @@ + # Input device support + # + CONFIG_INPUT=y +-CONFIG_INPUT_FF_MEMLESS=m ++# CONFIG_INPUT_FF_MEMLESS is not set + # CONFIG_INPUT_POLLDEV is not set + + # +@@ -776,10 +735,8 @@ + # Non-8250 serial port support + # + CONFIG_UNIX98_PTYS=y +-# CONFIG_DEVPTS_MULTIPLE_INSTANCES is not set + CONFIG_LEGACY_PTYS=y + CONFIG_LEGACY_PTY_COUNT=16 +-# CONFIG_HVC_UDBG is not set + # CONFIG_IPMI_HANDLER is not set + # CONFIG_HW_RANDOM is not set + # CONFIG_R3964 is not set +@@ -796,11 +753,11 @@ + # CONFIG_THERMAL is not set + # CONFIG_THERMAL_HWMON is not set + # CONFIG_WATCHDOG is not set +-CONFIG_SSB_POSSIBLE=y + + # + # Sonics Silicon Backplane + # ++CONFIG_SSB_POSSIBLE=y + # CONFIG_SSB is not set + + # +@@ -810,7 +767,6 @@ + # CONFIG_MFD_SM501 is not set + # CONFIG_HTC_PASIC3 is not set + # CONFIG_MFD_TMIO is not set +-# CONFIG_REGULATOR is not set + + # + # Multimedia devices +@@ -836,7 +792,6 @@ + CONFIG_FB=y + # CONFIG_FIRMWARE_EDID is not set + # CONFIG_FB_DDC is not set +-# CONFIG_FB_BOOT_VESA_SUPPORT is not set + # CONFIG_FB_CFB_FILLRECT is not set + # CONFIG_FB_CFB_COPYAREA is not set + # CONFIG_FB_CFB_IMAGEBLIT is not set +@@ -862,8 +817,6 @@ + CONFIG_FB_PS3=y + CONFIG_FB_PS3_DEFAULT_SIZE_M=9 + # CONFIG_FB_VIRTUAL is not set +-# CONFIG_FB_METRONOME is not set +-# CONFIG_FB_MB862XX is not set + # CONFIG_BACKLIGHT_LCD_SUPPORT is not set + + # +@@ -888,7 +841,6 @@ + # CONFIG_LOGO_LINUX_VGA16 is not set + CONFIG_LOGO_LINUX_CLUT224=y + CONFIG_SOUND=m +-# CONFIG_SOUND_OSS_CORE is not set + CONFIG_SND=m + CONFIG_SND_TIMER=m + CONFIG_SND_PCM=m +@@ -897,7 +849,6 @@ + # CONFIG_SND_SEQUENCER is not set + # CONFIG_SND_MIXER_OSS is not set + # CONFIG_SND_PCM_OSS is not set +-# CONFIG_SND_HRTIMER is not set + # CONFIG_SND_DYNAMIC_MINORS is not set + CONFIG_SND_SUPPORT_OLD_API=y + CONFIG_SND_VERBOSE_PROCFS=y +@@ -922,40 +873,15 @@ + # USB Input Devices + # + CONFIG_USB_HID=m +-# CONFIG_HID_PID is not set +-CONFIG_USB_HIDDEV=y ++# CONFIG_USB_HIDINPUT_POWERBOOK is not set ++# CONFIG_HID_FF is not set ++# CONFIG_USB_HIDDEV is not set + + # + # USB HID Boot Protocol drivers + # + # CONFIG_USB_KBD is not set + # CONFIG_USB_MOUSE is not set +- +-# +-# Special HID drivers +-# +-# CONFIG_HID_COMPAT is not set +-# CONFIG_HID_A4TECH is not set +-# CONFIG_HID_APPLE is not set +-# CONFIG_HID_BELKIN is not set +-# CONFIG_HID_CHERRY is not set +-# CONFIG_HID_CHICONY is not set +-# CONFIG_HID_CYPRESS is not set +-# CONFIG_HID_EZKEY is not set +-# CONFIG_HID_GYRATION is not set +-# CONFIG_HID_LOGITECH is not set +-# CONFIG_HID_MICROSOFT is not set +-# CONFIG_HID_MONTEREY is not set +-# CONFIG_HID_NTRIG is not set +-# CONFIG_HID_PANTHERLORD is not set +-# CONFIG_HID_PETALYNX is not set +-# CONFIG_HID_SAMSUNG is not set +-# CONFIG_HID_SONY is not set +-# CONFIG_HID_SUNPLUS is not set +-# CONFIG_GREENASIA_FF is not set +-# CONFIG_HID_TOPSEED is not set +-# CONFIG_THRUSTMASTER_FF is not set +-# CONFIG_ZEROPLUS_FF is not set + CONFIG_USB_SUPPORT=y + CONFIG_USB_ARCH_HAS_HCD=y + CONFIG_USB_ARCH_HAS_OHCI=y +@@ -972,11 +898,7 @@ + # CONFIG_USB_DYNAMIC_MINORS is not set + CONFIG_USB_SUSPEND=y + # CONFIG_USB_OTG is not set +-# CONFIG_USB_OTG_WHITELIST is not set +-# CONFIG_USB_OTG_BLACKLIST_HUB is not set +-CONFIG_USB_MON=m +-# CONFIG_USB_WUSB is not set +-# CONFIG_USB_WUSB_CBAF is not set ++CONFIG_USB_MON=y + + # + # USB Host Controller Drivers +@@ -987,7 +909,6 @@ + # CONFIG_USB_EHCI_TT_NEWSCHED is not set + CONFIG_USB_EHCI_BIG_ENDIAN_MMIO=y + # CONFIG_USB_EHCI_HCD_PPC_OF is not set +-# CONFIG_USB_OXU210HP_HCD is not set + # CONFIG_USB_ISP116X_HCD is not set + # CONFIG_USB_ISP1760_HCD is not set + CONFIG_USB_OHCI_HCD=m +@@ -997,7 +918,6 @@ + CONFIG_USB_OHCI_LITTLE_ENDIAN=y + # CONFIG_USB_SL811_HCD is not set + # CONFIG_USB_R8A66597_HCD is not set +-# CONFIG_USB_HWA_HCD is not set + + # + # Enable Host or Gadget support to see Inventra options +@@ -1009,20 +929,20 @@ + # CONFIG_USB_ACM is not set + # CONFIG_USB_PRINTER is not set + # CONFIG_USB_WDM is not set +-# CONFIG_USB_TMC is not set + + # +-# NOTE: USB_STORAGE depends on SCSI but BLK_DEV_SD may also be needed; ++# NOTE: USB_STORAGE enables SCSI, and 'SCSI disk support' + # + + # +-# see USB_STORAGE Help for more information ++# may also be needed; see USB_STORAGE Help for more information + # + CONFIG_USB_STORAGE=m + # CONFIG_USB_STORAGE_DEBUG is not set + # CONFIG_USB_STORAGE_DATAFAB is not set + # CONFIG_USB_STORAGE_FREECOM is not set + # CONFIG_USB_STORAGE_ISD200 is not set ++# CONFIG_USB_STORAGE_DPCM is not set + # CONFIG_USB_STORAGE_USBAT is not set + # CONFIG_USB_STORAGE_SDDR09 is not set + # CONFIG_USB_STORAGE_SDDR55 is not set +@@ -1030,6 +950,7 @@ + # CONFIG_USB_STORAGE_ALAUDA is not set + # CONFIG_USB_STORAGE_ONETOUCH is not set + # CONFIG_USB_STORAGE_KARMA is not set ++# CONFIG_USB_STORAGE_SIERRA is not set + # CONFIG_USB_STORAGE_CYPRESS_ATACB is not set + # CONFIG_USB_LIBUSUAL is not set + +@@ -1050,7 +971,6 @@ + # CONFIG_USB_EMI62 is not set + # CONFIG_USB_EMI26 is not set + # CONFIG_USB_ADUTUX is not set +-# CONFIG_USB_SEVSEG is not set + # CONFIG_USB_RIO500 is not set + # CONFIG_USB_LEGOTOWER is not set + # CONFIG_USB_LCD is not set +@@ -1068,12 +988,7 @@ + # CONFIG_USB_IOWARRIOR is not set + # CONFIG_USB_TEST is not set + # CONFIG_USB_ISIGHTFW is not set +-# CONFIG_USB_VST is not set + # CONFIG_USB_GADGET is not set +- +-# +-# OTG and related infrastructure +-# + # CONFIG_MMC is not set + # CONFIG_MEMSTICK is not set + # CONFIG_NEW_LEDS is not set +@@ -1099,15 +1014,12 @@ + # Platform RTC drivers + # + # CONFIG_RTC_DRV_CMOS is not set +-# CONFIG_RTC_DRV_DS1286 is not set + # CONFIG_RTC_DRV_DS1511 is not set + # CONFIG_RTC_DRV_DS1553 is not set + # CONFIG_RTC_DRV_DS1742 is not set + # CONFIG_RTC_DRV_STK17TA8 is not set + # CONFIG_RTC_DRV_M48T86 is not set +-# CONFIG_RTC_DRV_M48T35 is not set + # CONFIG_RTC_DRV_M48T59 is not set +-# CONFIG_RTC_DRV_BQ4802 is not set + # CONFIG_RTC_DRV_V3020 is not set + + # +@@ -1116,7 +1028,6 @@ + CONFIG_RTC_DRV_PPC=m + # CONFIG_DMADEVICES is not set + # CONFIG_UIO is not set +-# CONFIG_STAGING is not set + + # + # File systems +@@ -1124,35 +1035,26 @@ + CONFIG_EXT2_FS=m + # CONFIG_EXT2_FS_XATTR is not set + # CONFIG_EXT2_FS_XIP is not set +-CONFIG_EXT3_FS=m ++CONFIG_EXT3_FS=y + CONFIG_EXT3_FS_XATTR=y + # CONFIG_EXT3_FS_POSIX_ACL is not set + # CONFIG_EXT3_FS_SECURITY is not set +-CONFIG_EXT4_FS=y +-# CONFIG_EXT4DEV_COMPAT is not set +-CONFIG_EXT4_FS_XATTR=y +-# CONFIG_EXT4_FS_POSIX_ACL is not set +-# CONFIG_EXT4_FS_SECURITY is not set +-CONFIG_JBD=m ++# CONFIG_EXT4DEV_FS is not set ++CONFIG_JBD=y + # CONFIG_JBD_DEBUG is not set +-CONFIG_JBD2=y +-# CONFIG_JBD2_DEBUG is not set + CONFIG_FS_MBCACHE=y + # CONFIG_REISERFS_FS is not set + # CONFIG_JFS_FS is not set + # CONFIG_FS_POSIX_ACL is not set +-CONFIG_FILE_LOCKING=y + # CONFIG_XFS_FS is not set + # CONFIG_GFS2_FS is not set + # CONFIG_OCFS2_FS is not set +-# CONFIG_BTRFS_FS is not set + CONFIG_DNOTIFY=y + CONFIG_INOTIFY=y + CONFIG_INOTIFY_USER=y + CONFIG_QUOTA=y + # CONFIG_QUOTA_NETLINK_INTERFACE is not set + CONFIG_PRINT_QUOTA_WARNING=y +-CONFIG_QUOTA_TREE=y + # CONFIG_QFMT_V1 is not set + CONFIG_QFMT_V2=y + CONFIG_QUOTACTL=y +@@ -1185,14 +1087,16 @@ + CONFIG_PROC_FS=y + CONFIG_PROC_KCORE=y + CONFIG_PROC_SYSCTL=y +-CONFIG_PROC_PAGE_MONITOR=y + CONFIG_SYSFS=y + CONFIG_TMPFS=y + # CONFIG_TMPFS_POSIX_ACL is not set + CONFIG_HUGETLBFS=y + CONFIG_HUGETLB_PAGE=y + # CONFIG_CONFIGFS_FS is not set +-CONFIG_MISC_FILESYSTEMS=y ++ ++# ++# Miscellaneous filesystems ++# + # CONFIG_ADFS_FS is not set + # CONFIG_AFFS_FS is not set + # CONFIG_HFS_FS is not set +@@ -1202,7 +1106,6 @@ + # CONFIG_EFS_FS is not set + # CONFIG_JFFS2_FS is not set + # CONFIG_CRAMFS is not set +-# CONFIG_SQUASHFS is not set + # CONFIG_VXFS_FS is not set + # CONFIG_MINIX_FS is not set + # CONFIG_OMFS_FS is not set +@@ -1223,7 +1126,6 @@ + CONFIG_NFS_COMMON=y + CONFIG_SUNRPC=y + CONFIG_SUNRPC_GSS=y +-# CONFIG_SUNRPC_REGISTER_V4 is not set + CONFIG_RPCSEC_GSS_KRB5=y + # CONFIG_RPCSEC_GSS_SPKM3 is not set + # CONFIG_SMB_FS is not set +@@ -1288,9 +1190,9 @@ + # Library routines + # + CONFIG_BITREVERSE=y +-CONFIG_GENERIC_FIND_LAST_BIT=y ++# CONFIG_GENERIC_FIND_FIRST_BIT is not set + CONFIG_CRC_CCITT=m +-CONFIG_CRC16=y ++# CONFIG_CRC16 is not set + CONFIG_CRC_T10DIF=y + CONFIG_CRC_ITU_T=m + CONFIG_CRC32=y +@@ -1348,44 +1250,27 @@ + CONFIG_DEBUG_MEMORY_INIT=y + CONFIG_DEBUG_LIST=y + # CONFIG_DEBUG_SG is not set +-# CONFIG_DEBUG_NOTIFIERS is not set ++CONFIG_FRAME_POINTER=y + # CONFIG_BOOT_PRINTK_DELAY is not set + # CONFIG_RCU_TORTURE_TEST is not set +-# CONFIG_RCU_CPU_STALL_DETECTOR is not set + # CONFIG_BACKTRACE_SELF_TEST is not set +-# CONFIG_DEBUG_BLOCK_EXT_DEVT is not set + # CONFIG_FAULT_INJECTION is not set + # CONFIG_LATENCYTOP is not set + CONFIG_SYSCTL_SYSCALL_CHECK=y +-CONFIG_NOP_TRACER=y +-CONFIG_HAVE_FUNCTION_TRACER=y ++CONFIG_HAVE_FTRACE=y + CONFIG_HAVE_DYNAMIC_FTRACE=y +-CONFIG_HAVE_FTRACE_MCOUNT_RECORD=y +-CONFIG_RING_BUFFER=y +-CONFIG_TRACING=y +- +-# +-# Tracers +-# +-# CONFIG_FUNCTION_TRACER is not set ++# CONFIG_FTRACE is not set + # CONFIG_IRQSOFF_TRACER is not set + # CONFIG_SCHED_TRACER is not set + # CONFIG_CONTEXT_SWITCH_TRACER is not set +-# CONFIG_BOOT_TRACER is not set +-# CONFIG_TRACE_BRANCH_PROFILING is not set +-# CONFIG_STACK_TRACER is not set +-# CONFIG_FTRACE_STARTUP_TEST is not set +-# CONFIG_DYNAMIC_PRINTK_DEBUG is not set + # CONFIG_SAMPLES is not set + CONFIG_HAVE_ARCH_KGDB=y + # CONFIG_KGDB is not set +-CONFIG_PRINT_STACK_DEPTH=64 + CONFIG_DEBUG_STACKOVERFLOW=y + # CONFIG_DEBUG_STACK_USAGE is not set + # CONFIG_DEBUG_PAGEALLOC is not set + # CONFIG_CODE_PATCHING_SELFTEST is not set + # CONFIG_FTR_FIXUP_SELFTEST is not set +-# CONFIG_MSI_BITMAP_SELFTEST is not set + # CONFIG_XMON is not set + CONFIG_IRQSTACKS=y + # CONFIG_VIRQ_DEBUG is not set +@@ -1397,26 +1282,16 @@ + # + # CONFIG_KEYS is not set + # CONFIG_SECURITY is not set +-# CONFIG_SECURITYFS is not set + # CONFIG_SECURITY_FILE_CAPABILITIES is not set + CONFIG_CRYPTO=y + + # + # Crypto core or helper + # +-# CONFIG_CRYPTO_FIPS is not set + CONFIG_CRYPTO_ALGAPI=y +-CONFIG_CRYPTO_ALGAPI2=y + CONFIG_CRYPTO_AEAD=m +-CONFIG_CRYPTO_AEAD2=y + CONFIG_CRYPTO_BLKCIPHER=y +-CONFIG_CRYPTO_BLKCIPHER2=y +-CONFIG_CRYPTO_HASH=y +-CONFIG_CRYPTO_HASH2=y +-CONFIG_CRYPTO_RNG=m +-CONFIG_CRYPTO_RNG2=y + CONFIG_CRYPTO_MANAGER=y +-CONFIG_CRYPTO_MANAGER2=y + CONFIG_CRYPTO_GF128MUL=m + # CONFIG_CRYPTO_NULL is not set + # CONFIG_CRYPTO_CRYPTD is not set +@@ -1488,11 +1363,6 @@ + # + # CONFIG_CRYPTO_DEFLATE is not set + CONFIG_CRYPTO_LZO=m +- +-# +-# Random Number Generation +-# +-# CONFIG_CRYPTO_ANSI_CPRNG is not set + CONFIG_CRYPTO_HW=y + # CONFIG_PPC_CLOCK is not set + # CONFIG_VIRTUALIZATION is not set +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/arch/powerpc/configs/storcenter_defconfig linux-2.6.29-rc3.owrt/arch/powerpc/configs/storcenter_defconfig +--- linux-2.6.29.owrt/arch/powerpc/configs/storcenter_defconfig 2009-05-10 22:04:40.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/arch/powerpc/configs/storcenter_defconfig 2009-05-10 23:48:28.000000000 +0200 +@@ -1,7 +1,7 @@ + # + # Automatically generated make config: don't edit +-# Linux kernel version: 2.6.29-rc6 +-# Fri Mar 6 00:09:08 2009 ++# Linux kernel version: 2.6.29-rc2 ++# Mon Jan 26 15:35:46 2009 + # + # CONFIG_PPC64 is not set + +@@ -71,15 +71,6 @@ + # CONFIG_BSD_PROCESS_ACCT is not set + # CONFIG_TASKSTATS is not set + # CONFIG_AUDIT is not set +- +-# +-# RCU Subsystem +-# +-CONFIG_CLASSIC_RCU=y +-# CONFIG_TREE_RCU is not set +-# CONFIG_PREEMPT_RCU is not set +-# CONFIG_TREE_RCU_TRACE is not set +-# CONFIG_PREEMPT_RCU_TRACE is not set + # CONFIG_IKCONFIG is not set + CONFIG_LOG_BUF_SHIFT=14 + CONFIG_GROUP_SCHED=y +@@ -153,6 +144,11 @@ + CONFIG_DEFAULT_CFQ=y + # CONFIG_DEFAULT_NOOP is not set + CONFIG_DEFAULT_IOSCHED="cfq" ++CONFIG_CLASSIC_RCU=y ++# CONFIG_TREE_RCU is not set ++# CONFIG_PREEMPT_RCU is not set ++# CONFIG_TREE_RCU_TRACE is not set ++# CONFIG_PREEMPT_RCU_TRACE is not set + # CONFIG_FREEZER is not set + + # +@@ -381,8 +377,8 @@ + CONFIG_MTD_PARTITIONS=y + # CONFIG_MTD_TESTS is not set + # CONFIG_MTD_REDBOOT_PARTS is not set +-CONFIG_MTD_CMDLINE_PARTS=y +-CONFIG_MTD_OF_PARTS=y ++# CONFIG_MTD_CMDLINE_PARTS is not set ++# CONFIG_MTD_OF_PARTS is not set + # CONFIG_MTD_AR7_PARTS is not set + + # +@@ -456,6 +452,7 @@ + # LPDDR flash memory drivers + # + # CONFIG_MTD_LPDDR is not set ++# CONFIG_MTD_QINFO_PROBE is not set + + # + # UBI - Unsorted block images +@@ -481,19 +478,13 @@ + # CONFIG_BLK_DEV_HD is not set + CONFIG_MISC_DEVICES=y + # CONFIG_PHANTOM is not set ++# CONFIG_EEPROM_93CX6 is not set + # CONFIG_SGI_IOC4 is not set + # CONFIG_TIFM_CORE is not set + # CONFIG_ICS932S401 is not set + # CONFIG_ENCLOSURE_SERVICES is not set + # CONFIG_HP_ILO is not set + # CONFIG_C2PORT is not set +- +-# +-# EEPROM support +-# +-# CONFIG_EEPROM_AT24 is not set +-# CONFIG_EEPROM_LEGACY is not set +-# CONFIG_EEPROM_93CX6 is not set + CONFIG_HAVE_IDE=y + CONFIG_IDE=y + +@@ -686,7 +677,6 @@ + # CONFIG_QLA3XXX is not set + # CONFIG_ATL1 is not set + # CONFIG_ATL1E is not set +-# CONFIG_ATL1C is not set + # CONFIG_JME is not set + # CONFIG_NETDEV_10000 is not set + # CONFIG_TR is not set +@@ -828,6 +818,8 @@ + # Miscellaneous I2C Chip support + # + # CONFIG_DS1682 is not set ++# CONFIG_EEPROM_AT24 is not set ++# CONFIG_EEPROM_LEGACY is not set + # CONFIG_SENSORS_PCF8574 is not set + # CONFIG_PCF8575 is not set + # CONFIG_SENSORS_PCA9539 is not set +@@ -1167,7 +1159,6 @@ + # CONFIG_SYSV_FS is not set + # CONFIG_UFS_FS is not set + # CONFIG_NETWORK_FILESYSTEMS is not set +-CONFIG_EXPORTFS=m + + # + # Partition Types +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/arch/powerpc/include/asm/compat.h linux-2.6.29-rc3.owrt/arch/powerpc/include/asm/compat.h +--- linux-2.6.29.owrt/arch/powerpc/include/asm/compat.h 2009-05-10 22:04:39.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/arch/powerpc/include/asm/compat.h 2009-05-10 23:48:28.000000000 +0200 +@@ -210,10 +210,5 @@ + compat_ulong_t __unused6; + }; + +-static inline int is_compat_task(void) +-{ +- return test_thread_flag(TIF_32BIT); +-} +- + #endif /* __KERNEL__ */ + #endif /* _ASM_POWERPC_COMPAT_H */ +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/arch/powerpc/include/asm/cputable.h linux-2.6.29-rc3.owrt/arch/powerpc/include/asm/cputable.h +--- linux-2.6.29.owrt/arch/powerpc/include/asm/cputable.h 2009-05-10 22:04:40.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/arch/powerpc/include/asm/cputable.h 2009-05-10 23:48:28.000000000 +0200 +@@ -241,11 +241,9 @@ + /* We need to mark all pages as being coherent if we're SMP or we have a + * 74[45]x and an MPC107 host bridge. Also 83xx and PowerQUICC II + * require it for PCI "streaming/prefetch" to work properly. +- * This is also required by 52xx family. + */ + #if defined(CONFIG_SMP) || defined(CONFIG_MPC10X_BRIDGE) \ +- || defined(CONFIG_PPC_83xx) || defined(CONFIG_8260) \ +- || defined(CONFIG_PPC_MPC52xx) ++ || defined(CONFIG_PPC_83xx) || defined(CONFIG_8260) + #define CPU_FTR_COMMON CPU_FTR_NEED_COHERENT + #else + #define CPU_FTR_COMMON 0 +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/arch/powerpc/include/asm/pgtable-4k.h linux-2.6.29-rc3.owrt/arch/powerpc/include/asm/pgtable-4k.h +--- linux-2.6.29.owrt/arch/powerpc/include/asm/pgtable-4k.h 2009-05-10 22:04:39.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/arch/powerpc/include/asm/pgtable-4k.h 2009-05-10 23:48:28.000000000 +0200 +@@ -60,7 +60,7 @@ + /* It should be preserving the high 48 bits and then specifically */ + /* preserving _PAGE_SECONDARY | _PAGE_GROUP_IX */ + #define _PAGE_CHG_MASK (PAGE_MASK | _PAGE_ACCESSED | _PAGE_DIRTY | \ +- _PAGE_HPTEFLAGS | _PAGE_SPECIAL) ++ _PAGE_HPTEFLAGS) + + /* Bits to mask out from a PMD to get to the PTE page */ + #define PMD_MASKED_BITS 0 +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/arch/powerpc/include/asm/pgtable-64k.h linux-2.6.29-rc3.owrt/arch/powerpc/include/asm/pgtable-64k.h +--- linux-2.6.29.owrt/arch/powerpc/include/asm/pgtable-64k.h 2009-05-10 22:04:40.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/arch/powerpc/include/asm/pgtable-64k.h 2009-05-10 23:48:28.000000000 +0200 +@@ -114,7 +114,7 @@ + * pgprot changes + */ + #define _PAGE_CHG_MASK (PTE_RPN_MASK | _PAGE_HPTEFLAGS | _PAGE_DIRTY | \ +- _PAGE_ACCESSED | _PAGE_SPECIAL) ++ _PAGE_ACCESSED) + + /* Bits to mask out from a PMD to get to the PTE page */ + #define PMD_MASKED_BITS 0x1ff +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/arch/powerpc/include/asm/pgtable-ppc32.h linux-2.6.29-rc3.owrt/arch/powerpc/include/asm/pgtable-ppc32.h +--- linux-2.6.29.owrt/arch/powerpc/include/asm/pgtable-ppc32.h 2009-05-10 22:04:39.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/arch/powerpc/include/asm/pgtable-ppc32.h 2009-05-10 23:48:28.000000000 +0200 +@@ -429,8 +429,7 @@ + #define PMD_PAGE_SIZE(pmd) bad_call_to_PMD_PAGE_SIZE() + #endif + +-#define _PAGE_CHG_MASK (PAGE_MASK | _PAGE_ACCESSED | _PAGE_DIRTY | \ +- _PAGE_SPECIAL) ++#define _PAGE_CHG_MASK (PAGE_MASK | _PAGE_ACCESSED | _PAGE_DIRTY) + + + #define PAGE_PROT_BITS (_PAGE_GUARDED | _PAGE_COHERENT | _PAGE_NO_CACHE | \ +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/arch/powerpc/include/asm/seccomp.h linux-2.6.29-rc3.owrt/arch/powerpc/include/asm/seccomp.h +--- linux-2.6.29.owrt/arch/powerpc/include/asm/seccomp.h 2009-05-10 22:04:40.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/arch/powerpc/include/asm/seccomp.h 2009-05-10 23:48:28.000000000 +0200 +@@ -1,6 +1,10 @@ + #ifndef _ASM_POWERPC_SECCOMP_H + #define _ASM_POWERPC_SECCOMP_H + ++#ifdef __KERNEL__ ++#include <linux/thread_info.h> ++#endif ++ + #include <linux/unistd.h> + + #define __NR_seccomp_read __NR_read +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/arch/powerpc/kernel/align.c linux-2.6.29-rc3.owrt/arch/powerpc/kernel/align.c +--- linux-2.6.29.owrt/arch/powerpc/kernel/align.c 2009-05-10 22:04:40.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/arch/powerpc/kernel/align.c 2009-05-10 23:48:28.000000000 +0200 +@@ -367,24 +367,27 @@ + static int emulate_fp_pair(unsigned char __user *addr, unsigned int reg, + unsigned int flags) + { +- char *ptr0 = (char *) ¤t->thread.TS_FPR(reg); +- char *ptr1 = (char *) ¤t->thread.TS_FPR(reg+1); +- int i, ret, sw = 0; ++ char *ptr = (char *) ¤t->thread.TS_FPR(reg); ++ int i, ret; + + if (!(flags & F)) + return 0; + if (reg & 1) + return 0; /* invalid form: FRS/FRT must be even */ +- if (flags & SW) +- sw = 7; +- ret = 0; +- for (i = 0; i < 8; ++i) { +- if (!(flags & ST)) { +- ret |= __get_user(ptr0[i^sw], addr + i); +- ret |= __get_user(ptr1[i^sw], addr + i + 8); +- } else { +- ret |= __put_user(ptr0[i^sw], addr + i); +- ret |= __put_user(ptr1[i^sw], addr + i + 8); ++ if (!(flags & SW)) { ++ /* not byte-swapped - easy */ ++ if (!(flags & ST)) ++ ret = __copy_from_user(ptr, addr, 16); ++ else ++ ret = __copy_to_user(addr, ptr, 16); ++ } else { ++ /* each FPR value is byte-swapped separately */ ++ ret = 0; ++ for (i = 0; i < 16; ++i) { ++ if (!(flags & ST)) ++ ret |= __get_user(ptr[i^7], addr + i); ++ else ++ ret |= __put_user(ptr[i^7], addr + i); + } + } + if (ret) +@@ -643,16 +646,11 @@ + unsigned int areg, struct pt_regs *regs, + unsigned int flags, unsigned int length) + { +- char *ptr; ++ char *ptr = (char *) ¤t->thread.TS_FPR(reg); + int ret = 0; + + flush_vsx_to_thread(current); + +- if (reg < 32) +- ptr = (char *) ¤t->thread.TS_FPR(reg); +- else +- ptr = (char *) ¤t->thread.vr[reg - 32]; +- + if (flags & ST) + ret = __copy_to_user(addr, ptr, length); + else { +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/arch/powerpc/kernel/ftrace.c linux-2.6.29-rc3.owrt/arch/powerpc/kernel/ftrace.c +--- linux-2.6.29.owrt/arch/powerpc/kernel/ftrace.c 2009-05-10 22:04:40.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/arch/powerpc/kernel/ftrace.c 2009-05-10 23:48:28.000000000 +0200 +@@ -195,9 +195,8 @@ + return -EINVAL; + } + +- /* The bottom half is signed extended */ +- offset = ((unsigned)((unsigned short)jmp[0]) << 16) + +- (int)((short)jmp[1]); ++ offset = (unsigned)((unsigned short)jmp[0]) << 16 | ++ (unsigned)((unsigned short)jmp[1]); + + DEBUGP(" %x ", offset); + +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/arch/powerpc/kernel/head_32.S linux-2.6.29-rc3.owrt/arch/powerpc/kernel/head_32.S +--- linux-2.6.29.owrt/arch/powerpc/kernel/head_32.S 2009-05-10 22:04:40.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/arch/powerpc/kernel/head_32.S 2009-05-10 23:48:28.000000000 +0200 +@@ -511,11 +511,8 @@ + and r1,r1,r2 /* writable if _RW and _DIRTY */ + rlwimi r3,r3,32-1,30,30 /* _PAGE_USER -> PP msb */ + rlwimi r3,r3,32-1,31,31 /* _PAGE_USER -> PP lsb */ +- ori r1,r1,0xe04 /* clear out reserved bits */ ++ ori r1,r1,0xe14 /* clear out reserved bits and M */ + andc r1,r3,r1 /* PP = user? (rw&dirty? 2: 3): 0 */ +-BEGIN_FTR_SECTION +- rlwinm r1,r1,0,~_PAGE_COHERENT /* clear M (coherence not required) */ +-END_FTR_SECTION_IFCLR(CPU_FTR_NEED_COHERENT) + mtspr SPRN_RPA,r1 + mfspr r3,SPRN_IMISS + tlbli r3 +@@ -588,11 +585,8 @@ + and r1,r1,r2 /* writable if _RW and _DIRTY */ + rlwimi r3,r3,32-1,30,30 /* _PAGE_USER -> PP msb */ + rlwimi r3,r3,32-1,31,31 /* _PAGE_USER -> PP lsb */ +- ori r1,r1,0xe04 /* clear out reserved bits */ ++ ori r1,r1,0xe14 /* clear out reserved bits and M */ + andc r1,r3,r1 /* PP = user? (rw&dirty? 2: 3): 0 */ +-BEGIN_FTR_SECTION +- rlwinm r1,r1,0,~_PAGE_COHERENT /* clear M (coherence not required) */ +-END_FTR_SECTION_IFCLR(CPU_FTR_NEED_COHERENT) + mtspr SPRN_RPA,r1 + mfspr r3,SPRN_DMISS + tlbld r3 +@@ -659,11 +653,8 @@ + stw r3,0(r2) /* update PTE (accessed/dirty bits) */ + /* Convert linux-style PTE to low word of PPC-style PTE */ + rlwimi r3,r3,32-1,30,30 /* _PAGE_USER -> PP msb */ +- li r1,0xe05 /* clear out reserved bits & PP lsb */ ++ li r1,0xe15 /* clear out reserved bits and M */ + andc r1,r3,r1 /* PP = user? 2: 0 */ +-BEGIN_FTR_SECTION +- rlwinm r1,r1,0,~_PAGE_COHERENT /* clear M (coherence not required) */ +-END_FTR_SECTION_IFCLR(CPU_FTR_NEED_COHERENT) + mtspr SPRN_RPA,r1 + mfspr r3,SPRN_DMISS + tlbld r3 +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/arch/powerpc/kernel/pci-common.c linux-2.6.29-rc3.owrt/arch/powerpc/kernel/pci-common.c +--- linux-2.6.29.owrt/arch/powerpc/kernel/pci-common.c 2009-05-10 22:04:40.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/arch/powerpc/kernel/pci-common.c 2009-05-10 23:48:28.000000000 +0200 +@@ -16,6 +16,8 @@ + * 2 of the License, or (at your option) any later version. + */ + ++#define DEBUG ++ + #include <linux/kernel.h> + #include <linux/pci.h> + #include <linux/string.h> +@@ -256,8 +258,7 @@ + } else { + pr_debug(" Got one, spec %d cells (0x%08x 0x%08x...) on %s\n", + oirq.size, oirq.specifier[0], oirq.specifier[1], +- oirq.controller ? oirq.controller->full_name : +- "<default>"); ++ oirq.controller->full_name); + + virq = irq_create_of_mapping(oirq.controller, oirq.specifier, + oirq.size); +@@ -561,21 +562,8 @@ + (unsigned long long)(offset + size - 1)); + + if (mmap_state == pci_mmap_mem) { +- /* Hack alert ! +- * +- * Because X is lame and can fail starting if it gets an error trying +- * to mmap legacy_mem (instead of just moving on without legacy memory +- * access) we fake it here by giving it anonymous memory, effectively +- * behaving just like /dev/zero +- */ +- if ((offset + size) > hose->isa_mem_size) { +- printk(KERN_DEBUG +- "Process %s (pid:%d) mapped non-existing PCI legacy memory for 0%04x:%02x\n", +- current->comm, current->pid, pci_domain_nr(bus), bus->number); +- if (vma->vm_flags & VM_SHARED) +- return shmem_zero_setup(vma); +- return 0; +- } ++ if ((offset + size) > hose->isa_mem_size) ++ return -ENXIO; + offset += hose->isa_mem_phys; + } else { + unsigned long io_offset = (unsigned long)hose->io_base_virt - _IO_BASE; +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/arch/powerpc/kvm/powerpc.c linux-2.6.29-rc3.owrt/arch/powerpc/kvm/powerpc.c +--- linux-2.6.29.owrt/arch/powerpc/kvm/powerpc.c 2009-05-10 22:04:40.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/arch/powerpc/kvm/powerpc.c 2009-05-10 23:48:28.000000000 +0200 +@@ -125,10 +125,6 @@ + } + } + +-void kvm_arch_sync_events(struct kvm *kvm) +-{ +-} +- + void kvm_arch_destroy_vm(struct kvm *kvm) + { + kvmppc_free_vcpus(kvm); +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/arch/powerpc/lib/copyuser_64.S linux-2.6.29-rc3.owrt/arch/powerpc/lib/copyuser_64.S +--- linux-2.6.29.owrt/arch/powerpc/lib/copyuser_64.S 2009-05-10 22:04:40.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/arch/powerpc/lib/copyuser_64.S 2009-05-10 23:48:28.000000000 +0200 +@@ -62,19 +62,18 @@ + 72: std r8,8(r3) + beq+ 3f + addi r3,r3,16 ++23: ld r9,8(r4) + .Ldo_tail: + bf cr7*4+1,1f +-23: lwz r9,8(r4) +- addi r4,r4,4 ++ rotldi r9,r9,32 + 73: stw r9,0(r3) + addi r3,r3,4 + 1: bf cr7*4+2,2f +-44: lhz r9,8(r4) +- addi r4,r4,2 ++ rotldi r9,r9,16 + 74: sth r9,0(r3) + addi r3,r3,2 + 2: bf cr7*4+3,3f +-45: lbz r9,8(r4) ++ rotldi r9,r9,8 + 75: stb r9,0(r3) + 3: li r3,0 + blr +@@ -142,24 +141,11 @@ + 6: cmpwi cr1,r5,8 + addi r3,r3,32 + sld r9,r9,r10 +- ble cr1,7f ++ ble cr1,.Ldo_tail + 34: ld r0,8(r4) + srd r7,r0,r11 + or r9,r7,r9 +-7: +- bf cr7*4+1,1f +- rotldi r9,r9,32 +-94: stw r9,0(r3) +- addi r3,r3,4 +-1: bf cr7*4+2,2f +- rotldi r9,r9,16 +-95: sth r9,0(r3) +- addi r3,r3,2 +-2: bf cr7*4+3,3f +- rotldi r9,r9,8 +-96: stb r9,0(r3) +-3: li r3,0 +- blr ++ b .Ldo_tail + + .Ldst_unaligned: + PPC_MTOCRF 0x01,r6 /* put #bytes to 8B bdry into cr7 */ +@@ -232,6 +218,7 @@ + 121: + 132: + addi r3,r3,8 ++123: + 134: + 135: + 138: +@@ -239,9 +226,6 @@ + 140: + 141: + 142: +-123: +-144: +-145: + + /* + * here we have had a fault on a load and r3 points to the first +@@ -325,9 +309,6 @@ + 187: + 188: + 189: +-194: +-195: +-196: + 1: + ld r6,-24(r1) + ld r5,-8(r1) +@@ -348,9 +329,7 @@ + .llong 72b,172b + .llong 23b,123b + .llong 73b,173b +- .llong 44b,144b + .llong 74b,174b +- .llong 45b,145b + .llong 75b,175b + .llong 24b,124b + .llong 25b,125b +@@ -368,9 +347,6 @@ + .llong 79b,179b + .llong 80b,180b + .llong 34b,134b +- .llong 94b,194b +- .llong 95b,195b +- .llong 96b,196b + .llong 35b,135b + .llong 81b,181b + .llong 36b,136b +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/arch/powerpc/lib/memcpy_64.S linux-2.6.29-rc3.owrt/arch/powerpc/lib/memcpy_64.S +--- linux-2.6.29.owrt/arch/powerpc/lib/memcpy_64.S 2009-05-10 22:04:40.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/arch/powerpc/lib/memcpy_64.S 2009-05-10 23:48:28.000000000 +0200 +@@ -53,19 +53,18 @@ + 3: std r8,8(r3) + beq 3f + addi r3,r3,16 ++ ld r9,8(r4) + .Ldo_tail: + bf cr7*4+1,1f +- lwz r9,8(r4) +- addi r4,r4,4 ++ rotldi r9,r9,32 + stw r9,0(r3) + addi r3,r3,4 + 1: bf cr7*4+2,2f +- lhz r9,8(r4) +- addi r4,r4,2 ++ rotldi r9,r9,16 + sth r9,0(r3) + addi r3,r3,2 + 2: bf cr7*4+3,3f +- lbz r9,8(r4) ++ rotldi r9,r9,8 + stb r9,0(r3) + 3: ld r3,48(r1) /* return dest pointer */ + blr +@@ -134,24 +133,11 @@ + cmpwi cr1,r5,8 + addi r3,r3,32 + sld r9,r9,r10 +- ble cr1,6f ++ ble cr1,.Ldo_tail + ld r0,8(r4) + srd r7,r0,r11 + or r9,r7,r9 +-6: +- bf cr7*4+1,1f +- rotldi r9,r9,32 +- stw r9,0(r3) +- addi r3,r3,4 +-1: bf cr7*4+2,2f +- rotldi r9,r9,16 +- sth r9,0(r3) +- addi r3,r3,2 +-2: bf cr7*4+3,3f +- rotldi r9,r9,8 +- stb r9,0(r3) +-3: ld r3,48(r1) /* return dest pointer */ +- blr ++ b .Ldo_tail + + .Ldst_unaligned: + PPC_MTOCRF 0x01,r6 # put #bytes to 8B bdry into cr7 +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/arch/powerpc/lib/sstep.c linux-2.6.29-rc3.owrt/arch/powerpc/lib/sstep.c +--- linux-2.6.29.owrt/arch/powerpc/lib/sstep.c 2009-05-10 22:04:40.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/arch/powerpc/lib/sstep.c 2009-05-10 23:48:28.000000000 +0200 +@@ -172,8 +172,6 @@ + } + break; + case 0x378: /* orx */ +- if (instr & 1) +- break; + rs = (instr >> 21) & 0x1f; + rb = (instr >> 11) & 0x1f; + if (rs == rb) { /* mr */ +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/arch/powerpc/mm/fsl_booke_mmu.c linux-2.6.29-rc3.owrt/arch/powerpc/mm/fsl_booke_mmu.c +--- linux-2.6.29.owrt/arch/powerpc/mm/fsl_booke_mmu.c 2009-05-10 22:04:40.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/arch/powerpc/mm/fsl_booke_mmu.c 2009-05-10 23:48:28.000000000 +0200 +@@ -73,7 +73,7 @@ + /* + * Return PA for this VA if it is mapped by a CAM, or 0 + */ +-phys_addr_t v_mapped_by_tlbcam(unsigned long va) ++unsigned long v_mapped_by_tlbcam(unsigned long va) + { + int b; + for (b = 0; b < tlbcam_index; ++b) +@@ -85,7 +85,7 @@ + /* + * Return VA for a given PA or 0 if not mapped + */ +-unsigned long p_mapped_by_tlbcam(phys_addr_t pa) ++unsigned long p_mapped_by_tlbcam(unsigned long pa) + { + int b; + for (b = 0; b < tlbcam_index; ++b) +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/arch/powerpc/mm/hash_low_32.S linux-2.6.29-rc3.owrt/arch/powerpc/mm/hash_low_32.S +--- linux-2.6.29.owrt/arch/powerpc/mm/hash_low_32.S 2009-05-10 22:04:40.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/arch/powerpc/mm/hash_low_32.S 2009-05-10 23:48:28.000000000 +0200 +@@ -320,7 +320,7 @@ + and r8,r8,r0 /* writable if _RW & _DIRTY */ + rlwimi r5,r5,32-1,30,30 /* _PAGE_USER -> PP msb */ + rlwimi r5,r5,32-2,31,31 /* _PAGE_USER -> PP lsb */ +- ori r8,r8,0xe04 /* clear out reserved bits */ ++ ori r8,r8,0xe14 /* clear out reserved bits and M */ + andc r8,r5,r8 /* PP = user? (rw&dirty? 2: 3): 0 */ + BEGIN_FTR_SECTION + rlwinm r8,r8,0,~_PAGE_COHERENT /* clear M (coherence not required) */ +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/arch/powerpc/mm/numa.c linux-2.6.29-rc3.owrt/arch/powerpc/mm/numa.c +--- linux-2.6.29.owrt/arch/powerpc/mm/numa.c 2009-05-10 22:04:40.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/arch/powerpc/mm/numa.c 2009-05-10 23:48:28.000000000 +0200 +@@ -19,7 +19,6 @@ + #include <linux/notifier.h> + #include <linux/lmb.h> + #include <linux/of.h> +-#include <linux/pfn.h> + #include <asm/sparsemem.h> + #include <asm/prom.h> + #include <asm/system.h> +@@ -883,7 +882,7 @@ + unsigned long physbase = lmb.reserved.region[i].base; + unsigned long size = lmb.reserved.region[i].size; + unsigned long start_pfn = physbase >> PAGE_SHIFT; +- unsigned long end_pfn = PFN_UP(physbase + size); ++ unsigned long end_pfn = ((physbase + size) >> PAGE_SHIFT); + struct node_active_region node_ar; + unsigned long node_end_pfn = node->node_start_pfn + + node->node_spanned_pages; +@@ -909,7 +908,7 @@ + */ + if (end_pfn > node_ar.end_pfn) + reserve_size = (node_ar.end_pfn << PAGE_SHIFT) +- - physbase; ++ - (start_pfn << PAGE_SHIFT); + /* + * Only worry about *this* node, others may not + * yet have valid NODE_DATA(). +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/arch/powerpc/mm/pgtable_32.c linux-2.6.29-rc3.owrt/arch/powerpc/mm/pgtable_32.c +--- linux-2.6.29.owrt/arch/powerpc/mm/pgtable_32.c 2009-05-10 22:04:40.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/arch/powerpc/mm/pgtable_32.c 2009-05-10 23:48:28.000000000 +0200 +@@ -61,8 +61,8 @@ + + #ifdef HAVE_TLBCAM + extern unsigned int tlbcam_index; +-extern phys_addr_t v_mapped_by_tlbcam(unsigned long va); +-extern unsigned long p_mapped_by_tlbcam(phys_addr_t pa); ++extern unsigned long v_mapped_by_tlbcam(unsigned long va); ++extern unsigned long p_mapped_by_tlbcam(unsigned long pa); + #else /* !HAVE_TLBCAM */ + #define v_mapped_by_tlbcam(x) (0UL) + #define p_mapped_by_tlbcam(x) (0UL) +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/arch/powerpc/oprofile/cell/spu_profiler.c linux-2.6.29-rc3.owrt/arch/powerpc/oprofile/cell/spu_profiler.c +--- linux-2.6.29.owrt/arch/powerpc/oprofile/cell/spu_profiler.c 2009-05-10 22:04:39.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/arch/powerpc/oprofile/cell/spu_profiler.c 2009-05-10 23:48:28.000000000 +0200 +@@ -16,7 +16,6 @@ + #include <linux/smp.h> + #include <linux/slab.h> + #include <asm/cell-pmu.h> +-#include <asm/time.h> + #include "pr_util.h" + + #define SCALE_SHIFT 14 +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/arch/powerpc/platforms/52xx/mpc52xx_pci.c linux-2.6.29-rc3.owrt/arch/powerpc/platforms/52xx/mpc52xx_pci.c +--- linux-2.6.29.owrt/arch/powerpc/platforms/52xx/mpc52xx_pci.c 2009-05-10 22:04:40.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/arch/powerpc/platforms/52xx/mpc52xx_pci.c 2009-05-10 23:48:28.000000000 +0200 +@@ -20,6 +20,14 @@ + + + /* ======================================================================== */ ++/* PCI windows config */ ++/* ======================================================================== */ ++ ++#define MPC52xx_PCI_TARGET_IO 0xf0000000 ++#define MPC52xx_PCI_TARGET_MEM 0x00000000 ++ ++ ++/* ======================================================================== */ + /* Structures mapping & Defines for PCI Unit */ + /* ======================================================================== */ + +@@ -236,7 +244,7 @@ + + static void __init + mpc52xx_pci_setup(struct pci_controller *hose, +- struct mpc52xx_pci __iomem *pci_regs, phys_addr_t pci_phys) ++ struct mpc52xx_pci __iomem *pci_regs) + { + struct resource *res; + u32 tmp; +@@ -306,14 +314,10 @@ + /* Set all the IWCR fields at once; they're in the same reg */ + out_be32(&pci_regs->iwcr, MPC52xx_PCI_IWCR_PACK(iwcr0, iwcr1, iwcr2)); + +- /* Map IMMR onto PCI bus */ +- pci_phys &= 0xfffc0000; /* bar0 has only 14 significant bits */ +- out_be32(&pci_regs->tbatr0, MPC52xx_PCI_TBATR_ENABLE | pci_phys); +- out_be32(&pci_regs->bar0, PCI_BASE_ADDRESS_MEM_PREFETCH | pci_phys); +- +- /* Map memory onto PCI bus */ +- out_be32(&pci_regs->tbatr1, MPC52xx_PCI_TBATR_ENABLE); +- out_be32(&pci_regs->bar1, PCI_BASE_ADDRESS_MEM_PREFETCH); ++ out_be32(&pci_regs->tbatr0, ++ MPC52xx_PCI_TBATR_ENABLE | MPC52xx_PCI_TARGET_IO ); ++ out_be32(&pci_regs->tbatr1, ++ MPC52xx_PCI_TBATR_ENABLE | MPC52xx_PCI_TARGET_MEM ); + + out_be32(&pci_regs->tcr, MPC52xx_PCI_TCR_LD | MPC52xx_PCI_TCR_WCT8); + +@@ -410,7 +414,7 @@ + + /* Finish setting up PCI using values obtained by + * pci_proces_bridge_OF_ranges */ +- mpc52xx_pci_setup(hose, pci_regs, rsrc.start); ++ mpc52xx_pci_setup(hose, pci_regs); + + return 0; + } +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/arch/powerpc/platforms/82xx/pq2ads-pci-pic.c linux-2.6.29-rc3.owrt/arch/powerpc/platforms/82xx/pq2ads-pci-pic.c +--- linux-2.6.29.owrt/arch/powerpc/platforms/82xx/pq2ads-pci-pic.c 2009-05-10 22:04:40.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/arch/powerpc/platforms/82xx/pq2ads-pci-pic.c 2009-05-10 23:48:28.000000000 +0200 +@@ -186,7 +186,7 @@ + iounmap(priv->regs); + out_free_bootmem: + free_bootmem((unsigned long)priv, +- sizeof(struct pq2ads_pci_pic)); ++ sizeof(sizeof(struct pq2ads_pci_pic))); + of_node_put(np); + out_unmap_irq: + irq_dispose_mapping(irq); +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/arch/powerpc/platforms/86xx/gef_sbc610.c linux-2.6.29-rc3.owrt/arch/powerpc/platforms/86xx/gef_sbc610.c +--- linux-2.6.29.owrt/arch/powerpc/platforms/86xx/gef_sbc610.c 2009-05-10 22:04:40.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/arch/powerpc/platforms/86xx/gef_sbc610.c 2009-05-10 23:48:28.000000000 +0200 +@@ -142,10 +142,6 @@ + { + unsigned int val; + +- /* Do not do the fixup on other platforms! */ +- if (!machine_is(gef_sbc610)) +- return; +- + printk(KERN_INFO "Running NEC uPD720101 Fixup\n"); + + /* Ensure ports 1, 2, 3, 4 & 5 are enabled */ +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/arch/powerpc/platforms/embedded6xx/linkstation.c linux-2.6.29-rc3.owrt/arch/powerpc/platforms/embedded6xx/linkstation.c +--- linux-2.6.29.owrt/arch/powerpc/platforms/embedded6xx/linkstation.c 2009-05-10 22:04:40.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/arch/powerpc/platforms/embedded6xx/linkstation.c 2009-05-10 23:48:28.000000000 +0200 +@@ -12,6 +12,7 @@ + + #include <linux/kernel.h> + #include <linux/initrd.h> ++#include <linux/mtd/physmap.h> + #include <linux/of_platform.h> + + #include <asm/time.h> +@@ -21,6 +22,39 @@ + + #include "mpc10x.h" + ++static struct mtd_partition linkstation_physmap_partitions[] = { ++ { ++ .name = "mtd_firmimg", ++ .offset = 0x000000, ++ .size = 0x300000, ++ }, ++ { ++ .name = "mtd_bootcode", ++ .offset = 0x300000, ++ .size = 0x070000, ++ }, ++ { ++ .name = "mtd_status", ++ .offset = 0x370000, ++ .size = 0x010000, ++ }, ++ { ++ .name = "mtd_conf", ++ .offset = 0x380000, ++ .size = 0x080000, ++ }, ++ { ++ .name = "mtd_allflash", ++ .offset = 0x000000, ++ .size = 0x400000, ++ }, ++ { ++ .name = "mtd_data", ++ .offset = 0x310000, ++ .size = 0x0f0000, ++ }, ++}; ++ + static __initdata struct of_device_id of_bus_ids[] = { + { .type = "soc", }, + { .compatible = "simple-bus", }, +@@ -65,6 +99,10 @@ + static void __init linkstation_setup_arch(void) + { + struct device_node *np; ++#ifdef CONFIG_MTD_PHYSMAP ++ physmap_set_partitions(linkstation_physmap_partitions, ++ ARRAY_SIZE(linkstation_physmap_partitions)); ++#endif + + /* Lookup PCI host bridges */ + for_each_compatible_node(np, "pci", "mpc10x-pci") +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/arch/powerpc/platforms/embedded6xx/storcenter.c linux-2.6.29-rc3.owrt/arch/powerpc/platforms/embedded6xx/storcenter.c +--- linux-2.6.29.owrt/arch/powerpc/platforms/embedded6xx/storcenter.c 2009-05-10 22:04:40.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/arch/powerpc/platforms/embedded6xx/storcenter.c 2009-05-10 23:48:28.000000000 +0200 +@@ -14,6 +14,7 @@ + #include <linux/kernel.h> + #include <linux/pci.h> + #include <linux/initrd.h> ++#include <linux/mtd/physmap.h> + #include <linux/of_platform.h> + + #include <asm/system.h> +@@ -25,6 +26,32 @@ + #include "mpc10x.h" + + ++#ifdef CONFIG_MTD_PHYSMAP ++static struct mtd_partition storcenter_physmap_partitions[] = { ++ { ++ .name = "kernel", ++ .offset = 0x000000, ++ .size = 0x170000, ++ }, ++ { ++ .name = "rootfs", ++ .offset = 0x170000, ++ .size = 0x590000, ++ }, ++ { ++ .name = "uboot", ++ .offset = 0x700000, ++ .size = 0x040000, ++ }, ++ { ++ .name = "config", ++ .offset = 0x740000, ++ .size = 0x0c0000, ++ }, ++}; ++#endif ++ ++ + static __initdata struct of_device_id storcenter_of_bus[] = { + { .name = "soc", }, + {}, +@@ -69,6 +96,11 @@ + { + struct device_node *np; + ++#ifdef CONFIG_MTD_PHYSMAP ++ physmap_set_partitions(storcenter_physmap_partitions, ++ ARRAY_SIZE(storcenter_physmap_partitions)); ++#endif ++ + /* Lookup PCI host bridges */ + for_each_compatible_node(np, "pci", "mpc10x-pci") + storcenter_add_bridge(np); +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/arch/powerpc/platforms/ps3/Kconfig linux-2.6.29-rc3.owrt/arch/powerpc/platforms/ps3/Kconfig +--- linux-2.6.29.owrt/arch/powerpc/platforms/ps3/Kconfig 2009-05-10 22:04:40.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/arch/powerpc/platforms/ps3/Kconfig 2009-05-10 23:48:28.000000000 +0200 +@@ -128,13 +128,6 @@ + be disabled on the kernel command line using "ps3flash=off", to + not allocate this fixed buffer. + +-config PS3_VRAM +- tristate "PS3 Video RAM Storage Driver" +- depends on FB_PS3=y && BLOCK && m +- help +- This driver allows you to use excess PS3 video RAM as volatile +- storage or system swap. +- + config PS3_LPM + tristate "PS3 Logical Performance Monitor support" + depends on PPC_PS3 +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/arch/powerpc/platforms/ps3/mm.c linux-2.6.29-rc3.owrt/arch/powerpc/platforms/ps3/mm.c +--- linux-2.6.29.owrt/arch/powerpc/platforms/ps3/mm.c 2009-05-10 22:04:40.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/arch/powerpc/platforms/ps3/mm.c 2009-05-10 23:48:28.000000000 +0200 +@@ -328,7 +328,7 @@ + return result; + } + +-device_initcall(ps3_mm_add_memory); ++core_initcall(ps3_mm_add_memory); + + /*============================================================================*/ + /* dma routines */ +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/arch/powerpc/platforms/pseries/hotplug-memory.c linux-2.6.29-rc3.owrt/arch/powerpc/platforms/pseries/hotplug-memory.c +--- linux-2.6.29.owrt/arch/powerpc/platforms/pseries/hotplug-memory.c 2009-05-10 22:04:40.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/arch/powerpc/platforms/pseries/hotplug-memory.c 2009-05-10 23:48:28.000000000 +0200 +@@ -14,7 +14,6 @@ + #include <asm/firmware.h> + #include <asm/machdep.h> + #include <asm/pSeries_reconfig.h> +-#include <asm/sparsemem.h> + + static int pseries_remove_lmb(unsigned long base, unsigned int lmb_size) + { +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/arch/powerpc/sysdev/cpm2_pic.c linux-2.6.29-rc3.owrt/arch/powerpc/sysdev/cpm2_pic.c +--- linux-2.6.29.owrt/arch/powerpc/sysdev/cpm2_pic.c 2009-05-10 22:04:39.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/arch/powerpc/sysdev/cpm2_pic.c 2009-05-10 23:48:28.000000000 +0200 +@@ -165,7 +165,7 @@ + edibit = (14 - (src - CPM2_IRQ_EXT1)); + else + if (src >= CPM2_IRQ_PORTC15 && src <= CPM2_IRQ_PORTC0) +- edibit = (31 - (CPM2_IRQ_PORTC0 - src)); ++ edibit = (31 - (src - CPM2_IRQ_PORTC15)); + else + return (flow_type & IRQ_TYPE_LEVEL_LOW) ? 0 : -EINVAL; + +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/arch/powerpc/sysdev/ipic.c linux-2.6.29-rc3.owrt/arch/powerpc/sysdev/ipic.c +--- linux-2.6.29.owrt/arch/powerpc/sysdev/ipic.c 2009-05-10 22:04:39.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/arch/powerpc/sysdev/ipic.c 2009-05-10 23:48:28.000000000 +0200 +@@ -890,7 +890,7 @@ + return irq_linear_revmap(primary_ipic->irqhost, irq); + } + +-#ifdef CONFIG_SUSPEND ++#ifdef CONFIG_PM + static struct { + u32 sicfr; + u32 siprr[2]; +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/arch/powerpc/sysdev/ppc4xx_pci.c linux-2.6.29-rc3.owrt/arch/powerpc/sysdev/ppc4xx_pci.c +--- linux-2.6.29.owrt/arch/powerpc/sysdev/ppc4xx_pci.c 2009-05-10 22:04:39.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/arch/powerpc/sysdev/ppc4xx_pci.c 2009-05-10 23:48:28.000000000 +0200 +@@ -204,23 +204,6 @@ + { + u32 ma, pcila, pciha; + +- /* Hack warning ! The "old" PCI 2.x cell only let us configure the low +- * 32-bit of incoming PLB addresses. The top 4 bits of the 36-bit +- * address are actually hard wired to a value that appears to depend +- * on the specific SoC. For example, it's 0 on 440EP and 1 on 440EPx. +- * +- * The trick here is we just crop those top bits and ignore them when +- * programming the chip. That means the device-tree has to be right +- * for the specific part used (we don't print a warning if it's wrong +- * but on the other hand, you'll crash quickly enough), but at least +- * this code should work whatever the hard coded value is +- */ +- plb_addr &= 0xffffffffull; +- +- /* Note: Due to the above hack, the test below doesn't actually test +- * if you address is above 4G, but it tests that address and +- * (address + size) are both contained in the same 4G +- */ + if ((plb_addr + size) > 0xffffffffull || !is_power_of_2(size) || + size < 0x1000 || (plb_addr & (size - 1)) != 0) { + printk(KERN_WARNING "%s: Resource out of range\n", +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/arch/s390/crypto/aes_s390.c linux-2.6.29-rc3.owrt/arch/s390/crypto/aes_s390.c +--- linux-2.6.29.owrt/arch/s390/crypto/aes_s390.c 2009-05-10 22:04:39.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/arch/s390/crypto/aes_s390.c 2009-05-10 23:48:28.000000000 +0200 +@@ -556,7 +556,7 @@ + module_init(aes_s390_init); + module_exit(aes_s390_fini); + +-MODULE_ALIAS("aes-all"); ++MODULE_ALIAS("aes"); + + MODULE_DESCRIPTION("Rijndael (AES) Cipher Algorithm"); + MODULE_LICENSE("GPL"); +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/arch/s390/defconfig linux-2.6.29-rc3.owrt/arch/s390/defconfig +--- linux-2.6.29.owrt/arch/s390/defconfig 2009-05-10 22:04:39.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/arch/s390/defconfig 2009-05-10 23:48:28.000000000 +0200 +@@ -1,7 +1,7 @@ + # + # Automatically generated make config: don't edit +-# Linux kernel version: 2.6.29-rc4 +-# Wed Feb 11 10:07:16 2009 ++# Linux kernel version: 2.6.28-rc6 ++# Thu Nov 27 11:00:49 2008 + # + CONFIG_SCHED_MC=y + CONFIG_MMU=y +@@ -14,14 +14,12 @@ + # CONFIG_ARCH_HAS_ILOG2_U64 is not set + CONFIG_GENERIC_HWEIGHT=y + CONFIG_GENERIC_TIME=y +-CONFIG_GENERIC_TIME_VSYSCALL=y + CONFIG_GENERIC_CLOCKEVENTS=y + CONFIG_GENERIC_BUG=y + CONFIG_NO_IOMEM=y + CONFIG_NO_DMA=y + CONFIG_GENERIC_LOCKBREAK=y + CONFIG_PGSTE=y +-CONFIG_VIRT_CPU_ACCOUNTING=y + CONFIG_S390=y + CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config" + +@@ -41,29 +39,20 @@ + # CONFIG_TASKSTATS is not set + CONFIG_AUDIT=y + # CONFIG_AUDITSYSCALL is not set +- +-# +-# RCU Subsystem +-# +-CONFIG_CLASSIC_RCU=y +-# CONFIG_TREE_RCU is not set +-# CONFIG_PREEMPT_RCU is not set +-# CONFIG_TREE_RCU_TRACE is not set +-# CONFIG_PREEMPT_RCU_TRACE is not set + CONFIG_IKCONFIG=y + CONFIG_IKCONFIG_PROC=y + CONFIG_LOG_BUF_SHIFT=17 +-CONFIG_GROUP_SCHED=y +-CONFIG_FAIR_GROUP_SCHED=y +-# CONFIG_RT_GROUP_SCHED is not set +-CONFIG_USER_SCHED=y +-# CONFIG_CGROUP_SCHED is not set + CONFIG_CGROUPS=y + # CONFIG_CGROUP_DEBUG is not set + CONFIG_CGROUP_NS=y + # CONFIG_CGROUP_FREEZER is not set + # CONFIG_CGROUP_DEVICE is not set + # CONFIG_CPUSETS is not set ++CONFIG_GROUP_SCHED=y ++CONFIG_FAIR_GROUP_SCHED=y ++# CONFIG_RT_GROUP_SCHED is not set ++CONFIG_USER_SCHED=y ++# CONFIG_CGROUP_SCHED is not set + # CONFIG_CGROUP_CPUACCT is not set + # CONFIG_RESOURCE_COUNTERS is not set + CONFIG_SYSFS_DEPRECATED=y +@@ -74,7 +63,6 @@ + CONFIG_IPC_NS=y + # CONFIG_USER_NS is not set + # CONFIG_PID_NS is not set +-# CONFIG_NET_NS is not set + CONFIG_BLK_DEV_INITRD=y + CONFIG_INITRAMFS_SOURCE="" + # CONFIG_CC_OPTIMIZE_FOR_SIZE is not set +@@ -103,17 +91,17 @@ + # CONFIG_SLUB is not set + # CONFIG_SLOB is not set + # CONFIG_PROFILING is not set ++# CONFIG_MARKERS is not set + CONFIG_HAVE_OPROFILE=y + CONFIG_KPROBES=y +-CONFIG_HAVE_SYSCALL_WRAPPERS=y + CONFIG_KRETPROBES=y + CONFIG_HAVE_KPROBES=y + CONFIG_HAVE_KRETPROBES=y + CONFIG_HAVE_ARCH_TRACEHOOK=y +-CONFIG_USE_GENERIC_SMP_HELPERS=y + # CONFIG_HAVE_GENERIC_DMA_COHERENT is not set + CONFIG_SLABINFO=y + CONFIG_RT_MUTEXES=y ++# CONFIG_TINY_SHMEM is not set + CONFIG_BASE_SMALL=0 + CONFIG_MODULES=y + # CONFIG_MODULE_FORCE_LOAD is not set +@@ -121,7 +109,7 @@ + # CONFIG_MODULE_FORCE_UNLOAD is not set + CONFIG_MODVERSIONS=y + # CONFIG_MODULE_SRCVERSION_ALL is not set +-CONFIG_INIT_ALL_POSSIBLE=y ++CONFIG_KMOD=y + CONFIG_STOP_MACHINE=y + CONFIG_BLOCK=y + # CONFIG_BLK_DEV_IO_TRACE is not set +@@ -142,6 +130,7 @@ + # CONFIG_DEFAULT_NOOP is not set + CONFIG_DEFAULT_IOSCHED="deadline" + CONFIG_PREEMPT_NOTIFIERS=y ++CONFIG_CLASSIC_RCU=y + # CONFIG_FREEZER is not set + + # +@@ -172,7 +161,6 @@ + CONFIG_MARCH_Z900=y + # CONFIG_MARCH_Z990 is not set + # CONFIG_MARCH_Z9_109 is not set +-# CONFIG_MARCH_Z10 is not set + CONFIG_PACK_STACK=y + # CONFIG_SMALL_STACK is not set + CONFIG_CHECK_STACK=y +@@ -186,6 +174,7 @@ + # CONFIG_PREEMPT_NONE is not set + # CONFIG_PREEMPT_VOLUNTARY is not set + CONFIG_PREEMPT=y ++# CONFIG_PREEMPT_RCU is not set + CONFIG_ARCH_SPARSEMEM_ENABLE=y + CONFIG_ARCH_SPARSEMEM_DEFAULT=y + CONFIG_ARCH_SELECT_MEMORY_MODEL=y +@@ -206,6 +195,7 @@ + CONFIG_PAGEFLAGS_EXTENDED=y + CONFIG_SPLIT_PTLOCK_CPUS=4 + CONFIG_MIGRATION=y ++CONFIG_RESOURCES_64BIT=y + CONFIG_PHYS_ADDR_T_64BIT=y + CONFIG_ZONE_DMA_FLAG=1 + CONFIG_BOUNCE=y +@@ -217,6 +207,7 @@ + # + CONFIG_MACHCHK_WARNING=y + CONFIG_QDIO=y ++# CONFIG_QDIO_DEBUG is not set + CONFIG_CHSC_SCH=m + + # +@@ -236,13 +227,15 @@ + # CONFIG_SHARED_KERNEL is not set + # CONFIG_CMM is not set + # CONFIG_PAGE_STATES is not set ++CONFIG_VIRT_TIMER=y ++CONFIG_VIRT_CPU_ACCOUNTING=y + # CONFIG_APPLDATA_BASE is not set + CONFIG_HZ_100=y + # CONFIG_HZ_250 is not set + # CONFIG_HZ_300 is not set + # CONFIG_HZ_1000 is not set + CONFIG_HZ=100 +-CONFIG_SCHED_HRTICK=y ++# CONFIG_SCHED_HRTICK is not set + CONFIG_S390_HYPFS_FS=y + CONFIG_KEXEC=y + # CONFIG_ZFCPDUMP is not set +@@ -252,7 +245,6 @@ + # + # Networking options + # +-CONFIG_COMPAT_NET_DEV_OPS=y + CONFIG_PACKET=y + # CONFIG_PACKET_MMAP is not set + CONFIG_UNIX=y +@@ -391,7 +383,6 @@ + CONFIG_NET_SCH_GRED=m + CONFIG_NET_SCH_DSMARK=m + # CONFIG_NET_SCH_NETEM is not set +-# CONFIG_NET_SCH_DRR is not set + # CONFIG_NET_SCH_INGRESS is not set + + # +@@ -409,7 +400,6 @@ + CONFIG_NET_CLS_RSVP=m + CONFIG_NET_CLS_RSVP6=m + CONFIG_NET_CLS_FLOW=m +-# CONFIG_NET_CLS_CGROUP is not set + # CONFIG_NET_EMATCH is not set + CONFIG_NET_CLS_ACT=y + CONFIG_NET_ACT_POLICE=y +@@ -421,7 +411,6 @@ + # CONFIG_NET_ACT_SKBEDIT is not set + # CONFIG_NET_CLS_IND is not set + CONFIG_NET_SCH_FIFO=y +-# CONFIG_DCB is not set + + # + # Network testing +@@ -439,7 +428,6 @@ + # CONFIG_CAN_DEBUG_DEVICES is not set + # CONFIG_AF_RXRPC is not set + # CONFIG_PHONET is not set +-# CONFIG_WIMAX is not set + # CONFIG_RFKILL is not set + # CONFIG_NET_9P is not set + # CONFIG_PCMCIA is not set +@@ -487,15 +475,11 @@ + CONFIG_DASD_EER=y + CONFIG_VIRTIO_BLK=m + CONFIG_MISC_DEVICES=y ++# CONFIG_EEPROM_93CX6 is not set + # CONFIG_ENCLOSURE_SERVICES is not set + # CONFIG_C2PORT is not set + + # +-# EEPROM support +-# +-# CONFIG_EEPROM_93CX6 is not set +- +-# + # SCSI device support + # + # CONFIG_RAID_ATTRS is not set +@@ -536,7 +520,6 @@ + # CONFIG_SCSI_SRP_ATTRS is not set + CONFIG_SCSI_LOWLEVEL=y + # CONFIG_ISCSI_TCP is not set +-# CONFIG_LIBFC is not set + # CONFIG_SCSI_DEBUG is not set + CONFIG_ZFCP=y + CONFIG_SCSI_DH=m +@@ -583,10 +566,6 @@ + CONFIG_NETDEV_1000=y + CONFIG_NETDEV_10000=y + # CONFIG_TR is not set +- +-# +-# Enable WiMAX (Networking options) to see the WiMAX drivers +-# + # CONFIG_WAN is not set + + # +@@ -614,11 +593,9 @@ + # + CONFIG_DEVKMEM=y + CONFIG_UNIX98_PTYS=y +-# CONFIG_DEVPTS_MULTIPLE_INSTANCES is not set + CONFIG_LEGACY_PTYS=y + CONFIG_LEGACY_PTY_COUNT=256 + CONFIG_HVC_DRIVER=y +-CONFIG_HVC_IUCV=y + CONFIG_VIRTIO_CONSOLE=y + CONFIG_HW_RANDOM=m + CONFIG_HW_RANDOM_VIRTIO=m +@@ -668,6 +645,7 @@ + # CONFIG_NEW_LEDS is not set + CONFIG_ACCESSIBILITY=y + # CONFIG_STAGING is not set ++CONFIG_STAGING_EXCLUDE_BUILD=y + + # + # File systems +@@ -690,7 +668,6 @@ + # CONFIG_XFS_FS is not set + # CONFIG_GFS2_FS is not set + # CONFIG_OCFS2_FS is not set +-# CONFIG_BTRFS_FS is not set + CONFIG_DNOTIFY=y + CONFIG_INOTIFY=y + CONFIG_INOTIFY_USER=y +@@ -726,7 +703,10 @@ + # CONFIG_HUGETLBFS is not set + # CONFIG_HUGETLB_PAGE is not set + CONFIG_CONFIGFS_FS=m +-CONFIG_MISC_FILESYSTEMS=y ++ ++# ++# Miscellaneous filesystems ++# + # CONFIG_ADFS_FS is not set + # CONFIG_AFFS_FS is not set + # CONFIG_HFS_FS is not set +@@ -735,7 +715,6 @@ + # CONFIG_BFS_FS is not set + # CONFIG_EFS_FS is not set + # CONFIG_CRAMFS is not set +-# CONFIG_SQUASHFS is not set + # CONFIG_VXFS_FS is not set + # CONFIG_MINIX_FS is not set + # CONFIG_OMFS_FS is not set +@@ -829,7 +808,6 @@ + CONFIG_DEBUG_MEMORY_INIT=y + # CONFIG_DEBUG_LIST is not set + # CONFIG_DEBUG_SG is not set +-# CONFIG_DEBUG_NOTIFIERS is not set + # CONFIG_FRAME_POINTER is not set + # CONFIG_RCU_TORTURE_TEST is not set + # CONFIG_RCU_CPU_STALL_DETECTOR is not set +@@ -840,19 +818,15 @@ + # CONFIG_FAULT_INJECTION is not set + # CONFIG_LATENCYTOP is not set + CONFIG_SYSCTL_SYSCALL_CHECK=y +-CONFIG_HAVE_FUNCTION_TRACER=y + + # + # Tracers + # +-# CONFIG_FUNCTION_TRACER is not set + # CONFIG_IRQSOFF_TRACER is not set + # CONFIG_PREEMPT_TRACER is not set + # CONFIG_SCHED_TRACER is not set + # CONFIG_CONTEXT_SWITCH_TRACER is not set + # CONFIG_BOOT_TRACER is not set +-# CONFIG_TRACE_BRANCH_PROFILING is not set +-# CONFIG_STACK_TRACER is not set + # CONFIG_DYNAMIC_PRINTK_DEBUG is not set + CONFIG_SAMPLES=y + # CONFIG_SAMPLE_KOBJECT is not set +@@ -873,17 +847,11 @@ + # + CONFIG_CRYPTO_FIPS=y + CONFIG_CRYPTO_ALGAPI=y +-CONFIG_CRYPTO_ALGAPI2=y +-CONFIG_CRYPTO_AEAD=m +-CONFIG_CRYPTO_AEAD2=y ++CONFIG_CRYPTO_AEAD=y + CONFIG_CRYPTO_BLKCIPHER=y +-CONFIG_CRYPTO_BLKCIPHER2=y +-CONFIG_CRYPTO_HASH=m +-CONFIG_CRYPTO_HASH2=y +-CONFIG_CRYPTO_RNG=m +-CONFIG_CRYPTO_RNG2=y ++CONFIG_CRYPTO_HASH=y ++CONFIG_CRYPTO_RNG=y + CONFIG_CRYPTO_MANAGER=y +-CONFIG_CRYPTO_MANAGER2=y + CONFIG_CRYPTO_GF128MUL=m + # CONFIG_CRYPTO_NULL is not set + # CONFIG_CRYPTO_CRYPTD is not set +@@ -917,7 +885,7 @@ + # + # Digest + # +-CONFIG_CRYPTO_CRC32C=m ++# CONFIG_CRYPTO_CRC32C is not set + # CONFIG_CRYPTO_MD4 is not set + CONFIG_CRYPTO_MD5=m + # CONFIG_CRYPTO_MICHAEL_MIC is not set +@@ -974,7 +942,6 @@ + # Library routines + # + CONFIG_BITREVERSE=m +-CONFIG_GENERIC_FIND_LAST_BIT=y + # CONFIG_CRC_CCITT is not set + # CONFIG_CRC16 is not set + CONFIG_CRC_T10DIF=y +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/arch/s390/include/asm/cputime.h linux-2.6.29-rc3.owrt/arch/s390/include/asm/cputime.h +--- linux-2.6.29.owrt/arch/s390/include/asm/cputime.h 2009-05-10 22:04:39.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/arch/s390/include/asm/cputime.h 2009-05-10 23:48:28.000000000 +0200 +@@ -145,7 +145,7 @@ + value->tv_usec = rp.subreg.even / 4096; + value->tv_sec = rp.subreg.odd; + #else +- value->tv_usec = (cputime % 4096000000ULL) / 4096; ++ value->tv_usec = cputime % 4096000000ULL; + value->tv_sec = cputime / 4096000000ULL; + #endif + } +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/arch/s390/include/asm/lowcore.h linux-2.6.29-rc3.owrt/arch/s390/include/asm/lowcore.h +--- linux-2.6.29.owrt/arch/s390/include/asm/lowcore.h 2009-05-10 22:04:39.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/arch/s390/include/asm/lowcore.h 2009-05-10 23:48:28.000000000 +0200 +@@ -384,8 +384,8 @@ + __u32 panic_magic; /* 0xe00 */ + + /* Per cpu primary space access list */ +- __u8 pad_0xe04[0xe38-0xe04]; /* 0xe04 */ +- __u64 vdso_per_cpu_data; /* 0xe38 */ ++ __u8 pad_0xe04[0xe3c-0xe04]; /* 0xe04 */ ++ __u32 vdso_per_cpu_data; /* 0xe3c */ + __u32 paste[16]; /* 0xe40 */ + + __u8 pad13[0x11b8-0xe80]; /* 0xe80 */ +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/arch/s390/include/asm/mman.h linux-2.6.29-rc3.owrt/arch/s390/include/asm/mman.h +--- linux-2.6.29.owrt/arch/s390/include/asm/mman.h 2009-05-10 22:04:39.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/arch/s390/include/asm/mman.h 2009-05-10 23:48:28.000000000 +0200 +@@ -22,9 +22,4 @@ + #define MCL_CURRENT 1 /* lock all current mappings */ + #define MCL_FUTURE 2 /* lock all future mappings */ + +-#if defined(__KERNEL__) && !defined(__ASSEMBLY__) && defined(CONFIG_64BIT) +-int s390_mmap_check(unsigned long addr, unsigned long len); +-#define arch_mmap_check(addr,len,flags) s390_mmap_check(addr,len) +-#endif +- + #endif /* __S390_MMAN_H__ */ +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/arch/s390/include/asm/processor.h linux-2.6.29-rc3.owrt/arch/s390/include/asm/processor.h +--- linux-2.6.29.owrt/arch/s390/include/asm/processor.h 2009-05-10 22:04:39.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/arch/s390/include/asm/processor.h 2009-05-10 23:48:28.000000000 +0200 +@@ -61,7 +61,7 @@ + extern int get_cpu_capability(unsigned int *); + + /* +- * User space process size: 2GB for 31 bit, 4TB or 8PT for 64 bit. ++ * User space process size: 2GB for 31 bit, 4TB for 64 bit. + */ + #ifndef __s390x__ + +@@ -70,7 +70,8 @@ + + #else /* __s390x__ */ + +-#define TASK_SIZE_OF(tsk) ((tsk)->mm->context.asce_limit) ++#define TASK_SIZE_OF(tsk) (test_tsk_thread_flag(tsk,TIF_31BIT) ? \ ++ (1UL << 31) : (1UL << 53)) + #define TASK_UNMAPPED_BASE (test_thread_flag(TIF_31BIT) ? \ + (1UL << 30) : (1UL << 41)) + #define TASK_SIZE TASK_SIZE_OF(current) +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/arch/s390/include/asm/setup.h linux-2.6.29-rc3.owrt/arch/s390/include/asm/setup.h +--- linux-2.6.29.owrt/arch/s390/include/asm/setup.h 2009-05-10 22:04:39.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/arch/s390/include/asm/setup.h 2009-05-10 23:48:28.000000000 +0200 +@@ -43,8 +43,6 @@ + + extern struct mem_chunk memory_chunk[]; + extern unsigned long real_memory_size; +-extern int memory_end_set; +-extern unsigned long memory_end; + + void detect_memory_layout(struct mem_chunk chunk[]); + +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/arch/s390/include/asm/topology.h linux-2.6.29-rc3.owrt/arch/s390/include/asm/topology.h +--- linux-2.6.29.owrt/arch/s390/include/asm/topology.h 2009-05-10 22:04:39.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/arch/s390/include/asm/topology.h 2009-05-10 23:48:28.000000000 +0200 +@@ -30,8 +30,6 @@ + }; + #endif + +-#define SD_MC_INIT SD_CPU_INIT +- + #include <asm-generic/topology.h> + + #endif /* _ASM_S390_TOPOLOGY_H */ +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/arch/s390/kernel/irq.c linux-2.6.29-rc3.owrt/arch/s390/kernel/irq.c +--- linux-2.6.29.owrt/arch/s390/kernel/irq.c 2009-05-10 22:04:39.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/arch/s390/kernel/irq.c 2009-05-10 23:48:28.000000000 +0200 +@@ -95,7 +95,6 @@ + local_irq_restore(flags); + } + +-#ifdef CONFIG_PROC_FS + void init_irq_proc(void) + { + struct proc_dir_entry *root_irq_dir; +@@ -103,4 +102,3 @@ + root_irq_dir = proc_mkdir("irq", NULL); + create_prof_cpu_mask(root_irq_dir); + } +-#endif +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/arch/s390/kernel/mcount.S linux-2.6.29-rc3.owrt/arch/s390/kernel/mcount.S +--- linux-2.6.29.owrt/arch/s390/kernel/mcount.S 2009-05-10 22:04:39.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/arch/s390/kernel/mcount.S 2009-05-10 23:48:28.000000000 +0200 +@@ -5,8 +5,6 @@ + * + */ + +-#include <asm/asm-offsets.h> +- + #ifndef CONFIG_64BIT + .globl _mcount + _mcount: +@@ -16,7 +14,7 @@ + ahi %r15,-96 + l %r3,100(%r15) + la %r2,0(%r14) +- st %r1,__SF_BACKCHAIN(%r15) ++ st %r1,0(%r15) + la %r3,0(%r3) + bras %r14,0f + .long ftrace_trace_function +@@ -40,7 +38,7 @@ + stg %r14,112(%r15) + lgr %r1,%r15 + aghi %r15,-160 +- stg %r1,__SF_BACKCHAIN(%r15) ++ stg %r1,0(%r15) + lgr %r2,%r14 + lg %r3,168(%r15) + larl %r14,ftrace_trace_function +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/arch/s390/kernel/setup.c linux-2.6.29-rc3.owrt/arch/s390/kernel/setup.c +--- linux-2.6.29.owrt/arch/s390/kernel/setup.c 2009-05-10 22:04:39.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/arch/s390/kernel/setup.c 2009-05-10 23:48:28.000000000 +0200 +@@ -82,9 +82,7 @@ + + struct mem_chunk __initdata memory_chunk[MEMORY_CHUNKS]; + volatile int __cpu_logical_map[NR_CPUS]; /* logical cpu to cpu address */ +- +-int __initdata memory_end_set; +-unsigned long __initdata memory_end; ++static unsigned long __initdata memory_end; + + /* + * This is set up by the setup-routine at boot-time +@@ -283,7 +281,6 @@ + static int __init early_parse_mem(char *p) + { + memory_end = memparse(p, &p); +- memory_end_set = 1; + return 0; + } + early_param("mem", early_parse_mem); +@@ -511,10 +508,8 @@ + int i; + + #if defined(CONFIG_ZFCPDUMP) || defined(CONFIG_ZFCPDUMP_MODULE) +- if (ipl_info.type == IPL_TYPE_FCP_DUMP) { ++ if (ipl_info.type == IPL_TYPE_FCP_DUMP) + memory_end = ZFCPDUMP_HSA_SIZE; +- memory_end_set = 1; +- } + #endif + memory_size = 0; + memory_end &= PAGE_MASK; +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/arch/s390/kvm/kvm-s390.c linux-2.6.29-rc3.owrt/arch/s390/kvm/kvm-s390.c +--- linux-2.6.29.owrt/arch/s390/kvm/kvm-s390.c 2009-05-10 22:04:39.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/arch/s390/kvm/kvm-s390.c 2009-05-10 23:48:28.000000000 +0200 +@@ -212,10 +212,6 @@ + } + } + +-void kvm_arch_sync_events(struct kvm *kvm) +-{ +-} +- + void kvm_arch_destroy_vm(struct kvm *kvm) + { + kvm_free_vcpus(kvm); +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/arch/s390/lib/div64.c linux-2.6.29-rc3.owrt/arch/s390/lib/div64.c +--- linux-2.6.29.owrt/arch/s390/lib/div64.c 2009-05-10 22:04:39.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/arch/s390/lib/div64.c 2009-05-10 23:48:28.000000000 +0200 +@@ -61,7 +61,7 @@ + " clr %0,%3\n" + " jl 0f\n" + " slr %0,%3\n" +- " ahi %1,1\n" ++ " alr %1,%2\n" + "0:\n" + : "+d" (reg2), "+d" (reg3), "=d" (tmp) + : "d" (base), "2" (1UL) : "cc" ); +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/arch/s390/lib/uaccess_pt.c linux-2.6.29-rc3.owrt/arch/s390/lib/uaccess_pt.c +--- linux-2.6.29.owrt/arch/s390/lib/uaccess_pt.c 2009-05-10 22:04:39.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/arch/s390/lib/uaccess_pt.c 2009-05-10 23:48:28.000000000 +0200 +@@ -119,6 +119,8 @@ + goto fault; + + pfn = pte_pfn(*pte); ++ if (!pfn_valid(pfn)) ++ goto out; + + offset = uaddr & (PAGE_SIZE - 1); + size = min(n - done, PAGE_SIZE - offset); +@@ -133,6 +135,7 @@ + done += size; + uaddr += size; + } while (done < n); ++out: + spin_unlock(&mm->page_table_lock); + return n - done; + fault: +@@ -160,6 +163,9 @@ + goto fault; + + pfn = pte_pfn(*pte); ++ if (!pfn_valid(pfn)) ++ goto out; ++ + ret = (pfn << PAGE_SHIFT) + (uaddr & (PAGE_SIZE - 1)); + out: + return ret; +@@ -238,6 +244,11 @@ + goto fault; + + pfn = pte_pfn(*pte); ++ if (!pfn_valid(pfn)) { ++ done = -1; ++ goto out; ++ } ++ + offset = uaddr & (PAGE_SIZE-1); + addr = (char *)(pfn << PAGE_SHIFT) + offset; + len = min(count - done, PAGE_SIZE - offset); +@@ -245,6 +256,7 @@ + done += len_str; + uaddr += len_str; + } while ((len_str == len) && (done < count)); ++out: + spin_unlock(&mm->page_table_lock); + return done + 1; + fault: +@@ -313,7 +325,12 @@ + } + + pfn_from = pte_pfn(*pte_from); ++ if (!pfn_valid(pfn_from)) ++ goto out; + pfn_to = pte_pfn(*pte_to); ++ if (!pfn_valid(pfn_to)) ++ goto out; ++ + offset_from = uaddr_from & (PAGE_SIZE-1); + offset_to = uaddr_from & (PAGE_SIZE-1); + offset_max = max(offset_from, offset_to); +@@ -325,6 +342,7 @@ + uaddr_from += size; + uaddr_to += size; + } while (done < n); ++out: + spin_unlock(&mm->page_table_lock); + return n - done; + fault: +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/arch/s390/mm/mmap.c linux-2.6.29-rc3.owrt/arch/s390/mm/mmap.c +--- linux-2.6.29.owrt/arch/s390/mm/mmap.c 2009-05-10 22:04:39.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/arch/s390/mm/mmap.c 2009-05-10 23:48:28.000000000 +0200 +@@ -35,7 +35,7 @@ + * Leave an at least ~128 MB hole. + */ + #define MIN_GAP (128*1024*1024) +-#define MAX_GAP (STACK_TOP/6*5) ++#define MAX_GAP (TASK_SIZE/6*5) + + static inline unsigned long mmap_base(void) + { +@@ -46,7 +46,7 @@ + else if (gap > MAX_GAP) + gap = MAX_GAP; + +- return STACK_TOP - (gap & PAGE_MASK); ++ return TASK_SIZE - (gap & PAGE_MASK); + } + + static inline int mmap_is_legacy(void) +@@ -89,58 +89,42 @@ + + #else + +-int s390_mmap_check(unsigned long addr, unsigned long len) +-{ +- if (!test_thread_flag(TIF_31BIT) && +- len >= TASK_SIZE && TASK_SIZE < (1UL << 53)) +- return crst_table_upgrade(current->mm, 1UL << 53); +- return 0; +-} +- + static unsigned long + s390_get_unmapped_area(struct file *filp, unsigned long addr, + unsigned long len, unsigned long pgoff, unsigned long flags) + { + struct mm_struct *mm = current->mm; +- unsigned long area; + int rc; + +- area = arch_get_unmapped_area(filp, addr, len, pgoff, flags); +- if (!(area & ~PAGE_MASK)) +- return area; +- if (area == -ENOMEM && +- !test_thread_flag(TIF_31BIT) && TASK_SIZE < (1UL << 53)) { +- /* Upgrade the page table to 4 levels and retry. */ +- rc = crst_table_upgrade(mm, 1UL << 53); ++ addr = arch_get_unmapped_area(filp, addr, len, pgoff, flags); ++ if (addr & ~PAGE_MASK) ++ return addr; ++ if (unlikely(mm->context.asce_limit < addr + len)) { ++ rc = crst_table_upgrade(mm, addr + len); + if (rc) + return (unsigned long) rc; +- area = arch_get_unmapped_area(filp, addr, len, pgoff, flags); + } +- return area; ++ return addr; + } + + static unsigned long +-s390_get_unmapped_area_topdown(struct file *filp, const unsigned long addr, ++s390_get_unmapped_area_topdown(struct file *filp, const unsigned long addr0, + const unsigned long len, const unsigned long pgoff, + const unsigned long flags) + { + struct mm_struct *mm = current->mm; +- unsigned long area; ++ unsigned long addr = addr0; + int rc; + +- area = arch_get_unmapped_area_topdown(filp, addr, len, pgoff, flags); +- if (!(area & ~PAGE_MASK)) +- return area; +- if (area == -ENOMEM && +- !test_thread_flag(TIF_31BIT) && TASK_SIZE < (1UL << 53)) { +- /* Upgrade the page table to 4 levels and retry. */ +- rc = crst_table_upgrade(mm, 1UL << 53); ++ addr = arch_get_unmapped_area_topdown(filp, addr, len, pgoff, flags); ++ if (addr & ~PAGE_MASK) ++ return addr; ++ if (unlikely(mm->context.asce_limit < addr + len)) { ++ rc = crst_table_upgrade(mm, addr + len); + if (rc) + return (unsigned long) rc; +- area = arch_get_unmapped_area_topdown(filp, addr, len, +- pgoff, flags); + } +- return area; ++ return addr; + } + /* + * This function, called very early during the creation of a new +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/arch/s390/mm/pgtable.c linux-2.6.29-rc3.owrt/arch/s390/mm/pgtable.c +--- linux-2.6.29.owrt/arch/s390/mm/pgtable.c 2009-05-10 22:04:39.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/arch/s390/mm/pgtable.c 2009-05-10 23:48:28.000000000 +0200 +@@ -117,7 +117,6 @@ + crst_table_init(table, entry); + pgd_populate(mm, (pgd_t *) table, (pud_t *) pgd); + mm->pgd = (pgd_t *) table; +- mm->task_size = mm->context.asce_limit; + table = NULL; + } + spin_unlock(&mm->page_table_lock); +@@ -155,7 +154,6 @@ + BUG(); + } + mm->pgd = (pgd_t *) (pgd_val(*pgd) & _REGION_ENTRY_ORIGIN); +- mm->task_size = mm->context.asce_limit; + crst_table_free(mm, (unsigned long *) pgd); + } + update_mm(mm, current); +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/arch/sh/boards/board-ap325rxa.c linux-2.6.29-rc3.owrt/arch/sh/boards/board-ap325rxa.c +--- linux-2.6.29.owrt/arch/sh/boards/board-ap325rxa.c 2009-05-10 22:04:41.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/arch/sh/boards/board-ap325rxa.c 2009-05-10 23:48:28.000000000 +0200 +@@ -22,7 +22,6 @@ + #include <linux/gpio.h> + #include <linux/spi/spi.h> + #include <linux/spi/spi_gpio.h> +-#include <media/soc_camera.h> + #include <media/soc_camera_platform.h> + #include <media/sh_mobile_ceu.h> + #include <video/sh_mobile_lcdc.h> +@@ -217,12 +216,6 @@ + }, + }; + +-static void camera_power(int val) +-{ +- gpio_set_value(GPIO_PTZ5, val); /* RST_CAM/RSTB */ +- mdelay(10); +-} +- + #ifdef CONFIG_I2C + static unsigned char camera_ncm03j_magic[] = + { +@@ -252,11 +245,9 @@ + int ret = 0; + int i; + +- camera_power(0); + if (!enable) + return 0; /* no disable for now */ + +- camera_power(1); + for (i = 0; i < ARRAY_SIZE(camera_ncm03j_magic); i += 2) { + u_int8_t buf[8]; + +@@ -435,7 +426,7 @@ + gpio_request(GPIO_PTZ6, NULL); + gpio_direction_output(GPIO_PTZ6, 0); /* STBY_CAM */ + gpio_request(GPIO_PTZ5, NULL); +- gpio_direction_output(GPIO_PTZ5, 0); /* RST_CAM */ ++ gpio_direction_output(GPIO_PTZ5, 1); /* RST_CAM */ + gpio_request(GPIO_PTZ4, NULL); + gpio_direction_output(GPIO_PTZ4, 0); /* SADDR */ + +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/arch/sh/configs/ap325rxa_defconfig linux-2.6.29-rc3.owrt/arch/sh/configs/ap325rxa_defconfig +--- linux-2.6.29.owrt/arch/sh/configs/ap325rxa_defconfig 2009-05-10 22:04:41.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/arch/sh/configs/ap325rxa_defconfig 2009-05-10 23:48:28.000000000 +0200 +@@ -1,7 +1,7 @@ + # + # Automatically generated make config: don't edit +-# Linux kernel version: 2.6.29-rc2 +-# Tue Jan 27 11:45:08 2009 ++# Linux kernel version: 2.6.28 ++# Fri Jan 9 16:54:19 2009 + # + CONFIG_SUPERH=y + CONFIG_SUPERH32=y +@@ -45,12 +45,12 @@ + # CONFIG_AUDIT is not set + # CONFIG_IKCONFIG is not set + CONFIG_LOG_BUF_SHIFT=14 ++# CONFIG_CGROUPS is not set + CONFIG_GROUP_SCHED=y + CONFIG_FAIR_GROUP_SCHED=y + # CONFIG_RT_GROUP_SCHED is not set + CONFIG_USER_SCHED=y + # CONFIG_CGROUP_SCHED is not set +-# CONFIG_CGROUPS is not set + CONFIG_SYSFS_DEPRECATED=y + CONFIG_SYSFS_DEPRECATED_V2=y + # CONFIG_RELAY is not set +@@ -378,7 +378,6 @@ + # CONFIG_WIRELESS_EXT is not set + # CONFIG_LIB80211 is not set + # CONFIG_MAC80211 is not set +-# CONFIG_WIMAX is not set + # CONFIG_RFKILL is not set + # CONFIG_NET_9P is not set + +@@ -401,7 +400,6 @@ + # CONFIG_MTD_DEBUG is not set + CONFIG_MTD_CONCAT=y + CONFIG_MTD_PARTITIONS=y +-# CONFIG_MTD_TESTS is not set + # CONFIG_MTD_REDBOOT_PARTS is not set + CONFIG_MTD_CMDLINE_PARTS=y + # CONFIG_MTD_AR7_PARTS is not set +@@ -449,7 +447,9 @@ + # + # CONFIG_MTD_COMPLEX_MAPPINGS is not set + CONFIG_MTD_PHYSMAP=y +-# CONFIG_MTD_PHYSMAP_COMPAT is not set ++CONFIG_MTD_PHYSMAP_START=0xffffffff ++CONFIG_MTD_PHYSMAP_LEN=0 ++CONFIG_MTD_PHYSMAP_BANKWIDTH=0 + # CONFIG_MTD_PLATRAM is not set + + # +@@ -480,12 +480,6 @@ + # CONFIG_MTD_ONENAND is not set + + # +-# LPDDR flash memory drivers +-# +-# CONFIG_MTD_LPDDR is not set +-# CONFIG_MTD_QINFO_PROBE is not set +- +-# + # UBI - Unsorted block images + # + CONFIG_MTD_UBI=y +@@ -613,10 +607,6 @@ + # CONFIG_WLAN_PRE80211 is not set + # CONFIG_WLAN_80211 is not set + # CONFIG_IWLWIFI_LEDS is not set +- +-# +-# Enable WiMAX (Networking options) to see the WiMAX drivers +-# + # CONFIG_WAN is not set + # CONFIG_PPP is not set + # CONFIG_SLIP is not set +@@ -800,7 +790,6 @@ + # CONFIG_PMIC_DA903X is not set + # CONFIG_MFD_WM8400 is not set + # CONFIG_MFD_WM8350_I2C is not set +-# CONFIG_MFD_PCF50633 is not set + # CONFIG_REGULATOR is not set + + # +@@ -848,7 +837,7 @@ + # CONFIG_SOC_CAMERA_MT9V022 is not set + # CONFIG_SOC_CAMERA_TW9910 is not set + CONFIG_SOC_CAMERA_PLATFORM=y +-CONFIG_SOC_CAMERA_OV772X=y ++# CONFIG_SOC_CAMERA_OV772X is not set + CONFIG_VIDEO_SH_MOBILE_CEU=y + # CONFIG_RADIO_ADAPTERS is not set + # CONFIG_DAB is not set +@@ -1023,7 +1012,6 @@ + CONFIG_FILE_LOCKING=y + # CONFIG_XFS_FS is not set + # CONFIG_OCFS2_FS is not set +-# CONFIG_BTRFS_FS is not set + CONFIG_DNOTIFY=y + CONFIG_INOTIFY=y + CONFIG_INOTIFY_USER=y +@@ -1072,7 +1060,6 @@ + # CONFIG_JFFS2_FS is not set + # CONFIG_UBIFS_FS is not set + # CONFIG_CRAMFS is not set +-# CONFIG_SQUASHFS is not set + # CONFIG_VXFS_FS is not set + # CONFIG_MINIX_FS is not set + # CONFIG_OMFS_FS is not set +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/arch/sh/configs/migor_defconfig linux-2.6.29-rc3.owrt/arch/sh/configs/migor_defconfig +--- linux-2.6.29.owrt/arch/sh/configs/migor_defconfig 2009-05-10 22:04:41.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/arch/sh/configs/migor_defconfig 2009-05-10 23:48:28.000000000 +0200 +@@ -1,7 +1,7 @@ + # + # Automatically generated make config: don't edit +-# Linux kernel version: 2.6.29-rc1 +-# Thu Jan 22 09:16:16 2009 ++# Linux kernel version: 2.6.28 ++# Fri Jan 9 17:09:35 2009 + # + CONFIG_SUPERH=y + CONFIG_SUPERH32=y +@@ -45,12 +45,8 @@ + CONFIG_IKCONFIG=y + CONFIG_IKCONFIG_PROC=y + CONFIG_LOG_BUF_SHIFT=14 +-# CONFIG_GROUP_SCHED is not set +- +-# +-# Control Group support +-# + # CONFIG_CGROUPS is not set ++# CONFIG_GROUP_SCHED is not set + CONFIG_SYSFS_DEPRECATED=y + CONFIG_SYSFS_DEPRECATED_V2=y + # CONFIG_RELAY is not set +@@ -393,7 +389,6 @@ + CONFIG_WIRELESS_EXT_SYSFS=y + # CONFIG_LIB80211 is not set + # CONFIG_MAC80211 is not set +-# CONFIG_WIMAX is not set + # CONFIG_RFKILL is not set + # CONFIG_NET_9P is not set + +@@ -416,7 +411,6 @@ + # CONFIG_MTD_DEBUG is not set + CONFIG_MTD_CONCAT=y + CONFIG_MTD_PARTITIONS=y +-# CONFIG_MTD_TESTS is not set + # CONFIG_MTD_REDBOOT_PARTS is not set + CONFIG_MTD_CMDLINE_PARTS=y + # CONFIG_MTD_AR7_PARTS is not set +@@ -464,7 +458,9 @@ + # + # CONFIG_MTD_COMPLEX_MAPPINGS is not set + CONFIG_MTD_PHYSMAP=y +-# CONFIG_MTD_PHYSMAP_COMPAT is not set ++CONFIG_MTD_PHYSMAP_START=0xffffffff ++CONFIG_MTD_PHYSMAP_LEN=0 ++CONFIG_MTD_PHYSMAP_BANKWIDTH=0 + # CONFIG_MTD_PLATRAM is not set + + # +@@ -492,12 +488,6 @@ + # CONFIG_MTD_ONENAND is not set + + # +-# LPDDR flash memory drivers +-# +-# CONFIG_MTD_LPDDR is not set +-# CONFIG_MTD_QINFO_PROBE is not set +- +-# + # UBI - Unsorted block images + # + # CONFIG_MTD_UBI is not set +@@ -597,10 +587,6 @@ + # CONFIG_WLAN_PRE80211 is not set + # CONFIG_WLAN_80211 is not set + # CONFIG_IWLWIFI_LEDS is not set +- +-# +-# Enable WiMAX (Networking options) to see the WiMAX drivers +-# + # CONFIG_WAN is not set + # CONFIG_PPP is not set + # CONFIG_SLIP is not set +@@ -775,7 +761,6 @@ + # CONFIG_PMIC_DA903X is not set + # CONFIG_MFD_WM8400 is not set + # CONFIG_MFD_WM8350_I2C is not set +-# CONFIG_MFD_PCF50633 is not set + # CONFIG_REGULATOR is not set + + # +@@ -821,9 +806,9 @@ + # CONFIG_SOC_CAMERA_MT9M111 is not set + # CONFIG_SOC_CAMERA_MT9T031 is not set + # CONFIG_SOC_CAMERA_MT9V022 is not set +-CONFIG_SOC_CAMERA_TW9910=y +-# CONFIG_SOC_CAMERA_PLATFORM is not set +-CONFIG_SOC_CAMERA_OV772X=y ++# CONFIG_SOC_CAMERA_TW9910 is not set ++CONFIG_SOC_CAMERA_PLATFORM=y ++# CONFIG_SOC_CAMERA_OV772X is not set + CONFIG_VIDEO_SH_MOBILE_CEU=y + # CONFIG_RADIO_ADAPTERS is not set + # CONFIG_DAB is not set +@@ -881,13 +866,11 @@ + # CONFIG_USB_GADGET_PXA25X is not set + # CONFIG_USB_GADGET_PXA27X is not set + # CONFIG_USB_GADGET_S3C2410 is not set +-# CONFIG_USB_GADGET_IMX is not set + CONFIG_USB_GADGET_M66592=y + CONFIG_USB_M66592=y + CONFIG_SUPERH_BUILT_IN_M66592=y + # CONFIG_USB_GADGET_AMD5536UDC is not set + # CONFIG_USB_GADGET_FSL_QE is not set +-# CONFIG_USB_GADGET_CI13XXX is not set + # CONFIG_USB_GADGET_NET2280 is not set + # CONFIG_USB_GADGET_GOKU is not set + # CONFIG_USB_GADGET_DUMMY_HCD is not set +@@ -900,11 +883,6 @@ + # CONFIG_USB_MIDI_GADGET is not set + # CONFIG_USB_G_PRINTER is not set + # CONFIG_USB_CDC_COMPOSITE is not set +- +-# +-# OTG and related infrastructure +-# +-# CONFIG_USB_GPIO_VBUS is not set + # CONFIG_MMC is not set + # CONFIG_MEMSTICK is not set + # CONFIG_NEW_LEDS is not set +@@ -983,7 +961,6 @@ + CONFIG_FILE_LOCKING=y + # CONFIG_XFS_FS is not set + # CONFIG_OCFS2_FS is not set +-# CONFIG_BTRFS_FS is not set + # CONFIG_DNOTIFY is not set + # CONFIG_INOTIFY is not set + # CONFIG_QUOTA is not set +@@ -1027,7 +1004,6 @@ + # CONFIG_EFS_FS is not set + # CONFIG_JFFS2_FS is not set + # CONFIG_CRAMFS is not set +-# CONFIG_SQUASHFS is not set + # CONFIG_VXFS_FS is not set + # CONFIG_MINIX_FS is not set + # CONFIG_OMFS_FS is not set +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/arch/sh/include/asm/mutex-llsc.h linux-2.6.29-rc3.owrt/arch/sh/include/asm/mutex-llsc.h +--- linux-2.6.29.owrt/arch/sh/include/asm/mutex-llsc.h 2009-05-10 22:04:41.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/arch/sh/include/asm/mutex-llsc.h 2009-05-10 23:48:28.000000000 +0200 +@@ -21,36 +21,38 @@ + static inline void + __mutex_fastpath_lock(atomic_t *count, void (*fail_fn)(atomic_t *)) + { +- int __done, __res; ++ int __ex_flag, __res; + + __asm__ __volatile__ ( + "movli.l @%2, %0 \n" + "add #-1, %0 \n" + "movco.l %0, @%2 \n" + "movt %1 \n" +- : "=&z" (__res), "=&r" (__done) ++ : "=&z" (__res), "=&r" (__ex_flag) + : "r" (&(count)->counter) + : "t"); + +- if (unlikely(!__done || __res != 0)) ++ __res |= !__ex_flag; ++ if (unlikely(__res != 0)) + fail_fn(count); + } + + static inline int + __mutex_fastpath_lock_retval(atomic_t *count, int (*fail_fn)(atomic_t *)) + { +- int __done, __res; ++ int __ex_flag, __res; + + __asm__ __volatile__ ( + "movli.l @%2, %0 \n" + "add #-1, %0 \n" + "movco.l %0, @%2 \n" + "movt %1 \n" +- : "=&z" (__res), "=&r" (__done) ++ : "=&z" (__res), "=&r" (__ex_flag) + : "r" (&(count)->counter) + : "t"); + +- if (unlikely(!__done || __res != 0)) ++ __res |= !__ex_flag; ++ if (unlikely(__res != 0)) + __res = fail_fn(count); + + return __res; +@@ -59,18 +61,19 @@ + static inline void + __mutex_fastpath_unlock(atomic_t *count, void (*fail_fn)(atomic_t *)) + { +- int __done, __res; ++ int __ex_flag, __res; + + __asm__ __volatile__ ( + "movli.l @%2, %0 \n\t" + "add #1, %0 \n\t" + "movco.l %0, @%2 \n\t" + "movt %1 \n\t" +- : "=&z" (__res), "=&r" (__done) ++ : "=&z" (__res), "=&r" (__ex_flag) + : "r" (&(count)->counter) + : "t"); + +- if (unlikely(!__done || __res <= 0)) ++ __res |= !__ex_flag; ++ if (unlikely(__res <= 0)) + fail_fn(count); + } + +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/arch/sh/include/asm/syscall_32.h linux-2.6.29-rc3.owrt/arch/sh/include/asm/syscall_32.h +--- linux-2.6.29.owrt/arch/sh/include/asm/syscall_32.h 2009-05-10 22:04:41.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/arch/sh/include/asm/syscall_32.h 2009-05-10 23:48:28.000000000 +0200 +@@ -21,10 +21,23 @@ + */ + } + ++static inline bool syscall_has_error(struct pt_regs *regs) ++{ ++ return (regs->sr & 0x1) ? true : false; ++} ++static inline void syscall_set_error(struct pt_regs *regs) ++{ ++ regs->sr |= 0x1; ++} ++static inline void syscall_clear_error(struct pt_regs *regs) ++{ ++ regs->sr &= ~0x1; ++} ++ + static inline long syscall_get_error(struct task_struct *task, + struct pt_regs *regs) + { +- return IS_ERR_VALUE(regs->regs[0]) ? regs->regs[0] : 0; ++ return syscall_has_error(regs) ? regs->regs[0] : 0; + } + + static inline long syscall_get_return_value(struct task_struct *task, +@@ -37,10 +50,13 @@ + struct pt_regs *regs, + int error, long val) + { +- if (error) ++ if (error) { ++ syscall_set_error(regs); + regs->regs[0] = -error; +- else ++ } else { ++ syscall_clear_error(regs); + regs->regs[0] = val; ++ } + } + + static inline void syscall_get_arguments(struct task_struct *task, +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/arch/sh/include/asm/syscall_64.h linux-2.6.29-rc3.owrt/arch/sh/include/asm/syscall_64.h +--- linux-2.6.29.owrt/arch/sh/include/asm/syscall_64.h 2009-05-10 22:04:41.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/arch/sh/include/asm/syscall_64.h 2009-05-10 23:48:28.000000000 +0200 +@@ -21,10 +21,23 @@ + */ + } + ++static inline bool syscall_has_error(struct pt_regs *regs) ++{ ++ return (regs->sr & 0x1) ? true : false; ++} ++static inline void syscall_set_error(struct pt_regs *regs) ++{ ++ regs->sr |= 0x1; ++} ++static inline void syscall_clear_error(struct pt_regs *regs) ++{ ++ regs->sr &= ~0x1; ++} ++ + static inline long syscall_get_error(struct task_struct *task, + struct pt_regs *regs) + { +- return IS_ERR_VALUE(regs->regs[9]) ? regs->regs[9] : 0; ++ return syscall_has_error(regs) ? regs->regs[9] : 0; + } + + static inline long syscall_get_return_value(struct task_struct *task, +@@ -37,10 +50,13 @@ + struct pt_regs *regs, + int error, long val) + { +- if (error) ++ if (error) { ++ syscall_set_error(regs); + regs->regs[9] = -error; +- else ++ } else { ++ syscall_clear_error(regs); + regs->regs[9] = val; ++ } + } + + static inline void syscall_get_arguments(struct task_struct *task, +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/arch/sh/kernel/cpu/sh2a/clock-sh7201.c linux-2.6.29-rc3.owrt/arch/sh/kernel/cpu/sh2a/clock-sh7201.c +--- linux-2.6.29.owrt/arch/sh/kernel/cpu/sh2a/clock-sh7201.c 2009-05-10 22:04:41.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/arch/sh/kernel/cpu/sh2a/clock-sh7201.c 2009-05-10 23:48:28.000000000 +0200 +@@ -18,8 +18,8 @@ + #include <asm/freq.h> + #include <asm/io.h> + +-static const int pll1rate[]={1,2,3,4,6,8}; +-static const int pfc_divisors[]={1,2,3,4,6,8,12}; ++const static int pll1rate[]={1,2,3,4,6,8}; ++const static int pfc_divisors[]={1,2,3,4,6,8,12}; + #define ifc_divisors pfc_divisors + + #if (CONFIG_SH_CLK_MD == 0) +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/arch/sh/kernel/cpu/sh4/fpu.c linux-2.6.29-rc3.owrt/arch/sh/kernel/cpu/sh4/fpu.c +--- linux-2.6.29.owrt/arch/sh/kernel/cpu/sh4/fpu.c 2009-05-10 22:04:41.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/arch/sh/kernel/cpu/sh4/fpu.c 2009-05-10 23:48:28.000000000 +0200 +@@ -423,7 +423,7 @@ + int m; + unsigned int hx; + +- m = (finsn >> 8) & 0x7; ++ m = (finsn >> 9) & 0x7; + hx = tsk->thread.fpu.hard.fp_regs[m]; + + if ((tsk->thread.fpu.hard.fpscr & FPSCR_CAUSE_ERROR) +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/arch/sh/kernel/setup.c linux-2.6.29-rc3.owrt/arch/sh/kernel/setup.c +--- linux-2.6.29.owrt/arch/sh/kernel/setup.c 2009-05-10 22:04:41.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/arch/sh/kernel/setup.c 2009-05-10 23:48:28.000000000 +0200 +@@ -262,11 +262,11 @@ + BOOTMEM_DEFAULT); + + /* +- * Reserve physical pages below CONFIG_ZERO_PAGE_OFFSET. ++ * reserve physical page 0 - it's a special BIOS page on many boxes, ++ * enabling clean reboots, SMP operation, laptop functions. + */ +- if (CONFIG_ZERO_PAGE_OFFSET != 0) +- reserve_bootmem(__MEMORY_START, CONFIG_ZERO_PAGE_OFFSET, +- BOOTMEM_DEFAULT); ++ reserve_bootmem(__MEMORY_START, CONFIG_ZERO_PAGE_OFFSET, ++ BOOTMEM_DEFAULT); + + sparse_memory_present_with_active_regions(0); + +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/arch/sh/kernel/signal_32.c linux-2.6.29-rc3.owrt/arch/sh/kernel/signal_32.c +--- linux-2.6.29.owrt/arch/sh/kernel/signal_32.c 2009-05-10 22:04:41.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/arch/sh/kernel/signal_32.c 2009-05-10 23:48:28.000000000 +0200 +@@ -510,6 +510,7 @@ + case -ERESTARTNOHAND: + no_system_call_restart: + regs->regs[0] = -EINTR; ++ regs->sr |= 1; + break; + + case -ERESTARTSYS: +@@ -588,7 +589,8 @@ + + signr = get_signal_to_deliver(&info, &ka, regs, NULL); + if (signr > 0) { +- handle_syscall_restart(save_r0, regs, &ka.sa); ++ if (regs->sr & 1) ++ handle_syscall_restart(save_r0, regs, &ka.sa); + + /* Whee! Actually deliver the signal. */ + if (handle_signal(signr, &ka, &info, oldset, +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/arch/sh/kernel/signal_64.c linux-2.6.29-rc3.owrt/arch/sh/kernel/signal_64.c +--- linux-2.6.29.owrt/arch/sh/kernel/signal_64.c 2009-05-10 22:04:41.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/arch/sh/kernel/signal_64.c 2009-05-10 23:48:28.000000000 +0200 +@@ -60,6 +60,7 @@ + case -ERESTARTNOHAND: + no_system_call_restart: + regs->regs[REG_RET] = -EINTR; ++ regs->sr |= 1; + break; + + case -ERESTARTSYS: +@@ -108,7 +109,8 @@ + + signr = get_signal_to_deliver(&info, &ka, regs, 0); + if (signr > 0) { +- handle_syscall_restart(regs, &ka.sa); ++ if (regs->sr & 1) ++ handle_syscall_restart(regs, &ka.sa); + + /* Whee! Actually deliver the signal. */ + if (handle_signal(signr, &info, &ka, oldset, regs) == 0) { +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/arch/sh/lib/checksum.S linux-2.6.29-rc3.owrt/arch/sh/lib/checksum.S +--- linux-2.6.29.owrt/arch/sh/lib/checksum.S 2009-05-10 22:04:41.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/arch/sh/lib/checksum.S 2009-05-10 23:48:28.000000000 +0200 +@@ -36,7 +36,8 @@ + */ + + /* +- * asmlinkage __wsum csum_partial(const void *buf, int len, __wsum sum); ++ * unsigned int csum_partial(const unsigned char *buf, int len, ++ * unsigned int sum); + */ + + .text +@@ -48,31 +49,11 @@ + * Fortunately, it is easy to convert 2-byte alignment to 4-byte + * alignment for the unrolled loop. + */ ++ mov r5, r1 + mov r4, r0 +- tst #3, r0 ! Check alignment. +- bt/s 2f ! Jump if alignment is ok. +- mov r4, r7 ! Keep a copy to check for alignment ++ tst #2, r0 ! Check alignment. ++ bt 2f ! Jump if alignment is ok. + ! +- tst #1, r0 ! Check alignment. +- bt 21f ! Jump if alignment is boundary of 2bytes. +- +- ! buf is odd +- tst r5, r5 +- add #-1, r5 +- bt 9f +- mov.b @r4+, r0 +- extu.b r0, r0 +- addc r0, r6 ! t=0 from previous tst +- mov r6, r0 +- shll8 r6 +- shlr16 r0 +- shlr8 r0 +- or r0, r6 +- mov r4, r0 +- tst #2, r0 +- bt 2f +-21: +- ! buf is 2 byte aligned (len could be 0) + add #-2, r5 ! Alignment uses up two bytes. + cmp/pz r5 ! + bt/s 1f ! Jump if we had at least two bytes. +@@ -80,17 +61,16 @@ + bra 6f + add #2, r5 ! r5 was < 2. Deal with it. + 1: ++ mov r5, r1 ! Save new len for later use. + mov.w @r4+, r0 + extu.w r0, r0 + addc r0, r6 + bf 2f + add #1, r6 + 2: +- ! buf is 4 byte aligned (len could be 0) +- mov r5, r1 + mov #-5, r0 +- shld r0, r1 +- tst r1, r1 ++ shld r0, r5 ++ tst r5, r5 + bt/s 4f ! if it's =0, go to 4f + clrt + .align 2 +@@ -112,31 +92,30 @@ + addc r0, r6 + addc r2, r6 + movt r0 +- dt r1 ++ dt r5 + bf/s 3b + cmp/eq #1, r0 +- ! here, we know r1==0 +- addc r1, r6 ! add carry to r6 ++ ! here, we know r5==0 ++ addc r5, r6 ! add carry to r6 + 4: +- mov r5, r0 ++ mov r1, r0 + and #0x1c, r0 + tst r0, r0 +- bt 6f +- ! 4 bytes or more remaining +- mov r0, r1 +- shlr2 r1 ++ bt/s 6f ++ mov r0, r5 ++ shlr2 r5 + mov #0, r2 + 5: + addc r2, r6 + mov.l @r4+, r2 + movt r0 +- dt r1 ++ dt r5 + bf/s 5b + cmp/eq #1, r0 + addc r2, r6 +- addc r1, r6 ! r1==0 here, so it means add carry-bit ++ addc r5, r6 ! r5==0 here, so it means add carry-bit + 6: +- ! 3 bytes or less remaining ++ mov r1, r5 + mov #3, r0 + and r0, r5 + tst r5, r5 +@@ -160,18 +139,8 @@ + 8: + addc r0, r6 + mov #0, r0 +- addc r0, r6 ++ addc r0, r6 + 9: +- ! Check if the buffer was misaligned, if so realign sum +- mov r7, r0 +- tst #1, r0 +- bt 10f +- mov r6, r0 +- shll8 r6 +- shlr16 r0 +- shlr8 r0 +- or r0, r6 +-10: + rts + mov r6, r0 + +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/arch/sparc/include/asm/compat.h linux-2.6.29-rc3.owrt/arch/sparc/include/asm/compat.h +--- linux-2.6.29.owrt/arch/sparc/include/asm/compat.h 2009-05-10 22:04:40.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/arch/sparc/include/asm/compat.h 2009-05-10 23:48:28.000000000 +0200 +@@ -240,9 +240,4 @@ + unsigned int __unused2; + }; + +-static inline int is_compat_task(void) +-{ +- return test_thread_flag(TIF_32BIT); +-} +- + #endif /* _ASM_SPARC64_COMPAT_H */ +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/arch/sparc/include/asm/cpudata_64.h linux-2.6.29-rc3.owrt/arch/sparc/include/asm/cpudata_64.h +--- linux-2.6.29.owrt/arch/sparc/include/asm/cpudata_64.h 2009-05-10 22:04:40.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/arch/sparc/include/asm/cpudata_64.h 2009-05-10 23:48:28.000000000 +0200 +@@ -17,7 +17,7 @@ + typedef struct { + /* Dcache line 1 */ + unsigned int __softirq_pending; /* must be 1st, see rtrap.S */ +- unsigned int __nmi_count; ++ unsigned int __pad0; + unsigned long clock_tick; /* %tick's per second */ + unsigned long __pad; + unsigned int __pad1; +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/arch/sparc/include/asm/irq_64.h linux-2.6.29-rc3.owrt/arch/sparc/include/asm/irq_64.h +--- linux-2.6.29.owrt/arch/sparc/include/asm/irq_64.h 2009-05-10 22:04:40.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/arch/sparc/include/asm/irq_64.h 2009-05-10 23:48:28.000000000 +0200 +@@ -66,6 +66,9 @@ + extern void __init init_IRQ(void); + extern void fixup_irqs(void); + ++extern int register_perfctr_intr(void (*handler)(struct pt_regs *)); ++extern void release_perfctr_intr(void (*handler)(struct pt_regs *)); ++ + static inline void set_softint(unsigned long bits) + { + __asm__ __volatile__("wr %0, 0x0, %%set_softint" +@@ -95,6 +98,5 @@ + extern void *hardirq_stack[NR_CPUS]; + extern void *softirq_stack[NR_CPUS]; + #define __ARCH_HAS_DO_SOFTIRQ +-#define ARCH_HAS_NMI_WATCHDOG + + #endif +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/arch/sparc/include/asm/kdebug_64.h linux-2.6.29-rc3.owrt/arch/sparc/include/asm/kdebug_64.h +--- linux-2.6.29.owrt/arch/sparc/include/asm/kdebug_64.h 2009-05-10 22:04:40.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/arch/sparc/include/asm/kdebug_64.h 2009-05-10 23:48:28.000000000 +0200 +@@ -14,8 +14,6 @@ + DIE_TRAP, + DIE_TRAP_TL1, + DIE_CALL, +- DIE_NMI, +- DIE_NMIWATCHDOG, + }; + + #endif +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/arch/sparc/include/asm/nmi.h linux-2.6.29-rc3.owrt/arch/sparc/include/asm/nmi.h +--- linux-2.6.29.owrt/arch/sparc/include/asm/nmi.h 2009-05-10 22:04:40.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/arch/sparc/include/asm/nmi.h 1970-01-01 01:00:00.000000000 +0100 +@@ -1,10 +0,0 @@ +-#ifndef __NMI_H +-#define __NMI_H +- +-extern int __init nmi_init(void); +-extern void perfctr_irq(int irq, struct pt_regs *regs); +-extern void nmi_adjust_hz(unsigned int new_hz); +- +-extern int nmi_usable; +- +-#endif /* __NMI_H */ +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/arch/sparc/include/asm/pcr.h linux-2.6.29-rc3.owrt/arch/sparc/include/asm/pcr.h +--- linux-2.6.29.owrt/arch/sparc/include/asm/pcr.h 2009-05-10 22:04:40.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/arch/sparc/include/asm/pcr.h 1970-01-01 01:00:00.000000000 +0100 +@@ -1,46 +0,0 @@ +-#ifndef __PCR_H +-#define __PCR_H +- +-struct pcr_ops { +- u64 (*read)(void); +- void (*write)(u64); +-}; +-extern const struct pcr_ops *pcr_ops; +- +-extern void deferred_pcr_work_irq(int irq, struct pt_regs *regs); +-extern void schedule_deferred_pcr_work(void); +- +-#define PCR_PIC_PRIV 0x00000001 /* PIC access is privileged */ +-#define PCR_STRACE 0x00000002 /* Trace supervisor events */ +-#define PCR_UTRACE 0x00000004 /* Trace user events */ +-#define PCR_N2_HTRACE 0x00000008 /* Trace hypervisor events */ +-#define PCR_N2_TOE_OV0 0x00000010 /* Trap if PIC 0 overflows */ +-#define PCR_N2_TOE_OV1 0x00000020 /* Trap if PIC 1 overflows */ +-#define PCR_N2_MASK0 0x00003fc0 +-#define PCR_N2_MASK0_SHIFT 6 +-#define PCR_N2_SL0 0x0003c000 +-#define PCR_N2_SL0_SHIFT 14 +-#define PCR_N2_OV0 0x00040000 +-#define PCR_N2_MASK1 0x07f80000 +-#define PCR_N2_MASK1_SHIFT 19 +-#define PCR_N2_SL1 0x78000000 +-#define PCR_N2_SL1_SHIFT 27 +-#define PCR_N2_OV1 0x80000000 +- +-extern unsigned int picl_shift; +- +-/* In order to commonize as much of the implementation as +- * possible, we use PICH as our counter. Mostly this is +- * to accomodate Niagara-1 which can only count insn cycles +- * in PICH. +- */ +-static inline u64 picl_value(unsigned int nmi_hz) +-{ +- u32 delta = local_cpu_data().clock_tick / (nmi_hz << picl_shift); +- +- return ((u64)((0 - delta) & 0xffffffff)) << 32; +-} +- +-extern u64 pcr_enable; +- +-#endif /* __PCR_H */ +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/arch/sparc/include/asm/pil.h linux-2.6.29-rc3.owrt/arch/sparc/include/asm/pil.h +--- linux-2.6.29.owrt/arch/sparc/include/asm/pil.h 2009-05-10 22:04:40.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/arch/sparc/include/asm/pil.h 2009-05-10 23:48:28.000000000 +0200 +@@ -23,8 +23,6 @@ + #define PIL_SMP_CTX_NEW_VERSION 4 + #define PIL_DEVICE_IRQ 5 + #define PIL_SMP_CALL_FUNC_SNGL 6 +-#define PIL_DEFERRED_PCR_WORK 7 +-#define PIL_KGDB_CAPTURE 8 + #define PIL_NORMAL_MAX 14 + #define PIL_NMI 15 + +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/arch/sparc/include/asm/seccomp.h linux-2.6.29-rc3.owrt/arch/sparc/include/asm/seccomp.h +--- linux-2.6.29.owrt/arch/sparc/include/asm/seccomp.h 2009-05-10 22:04:40.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/arch/sparc/include/asm/seccomp.h 2009-05-10 23:48:28.000000000 +0200 +@@ -1,5 +1,11 @@ + #ifndef _ASM_SECCOMP_H + ++#include <linux/thread_info.h> /* already defines TIF_32BIT */ ++ ++#ifndef TIF_32BIT ++#error "unexpected TIF_32BIT on sparc64" ++#endif ++ + #include <linux/unistd.h> + + #define __NR_seccomp_read __NR_read +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/arch/sparc/kernel/chmc.c linux-2.6.29-rc3.owrt/arch/sparc/kernel/chmc.c +--- linux-2.6.29.owrt/arch/sparc/kernel/chmc.c 2009-05-10 22:04:40.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/arch/sparc/kernel/chmc.c 2009-05-10 23:48:28.000000000 +0200 +@@ -306,7 +306,6 @@ + buf[1] = '?'; + buf[2] = '?'; + buf[3] = '\0'; +- return 0; + } + p = dp->controller; + prop = &p->layout; +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/arch/sparc/kernel/cpu.c linux-2.6.29-rc3.owrt/arch/sparc/kernel/cpu.c +--- linux-2.6.29.owrt/arch/sparc/kernel/cpu.c 2009-05-10 22:04:40.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/arch/sparc/kernel/cpu.c 2009-05-10 23:48:28.000000000 +0200 +@@ -26,7 +26,6 @@ + struct cpu_info { + int psr_vers; + const char *name; +- const char *pmu_name; + }; + + struct fpu_info { +@@ -46,9 +45,6 @@ + #define CPU(ver, _name) \ + { .psr_vers = ver, .name = _name } + +-#define CPU_PMU(ver, _name, _pmu_name) \ +-{ .psr_vers = ver, .name = _name, .pmu_name = _pmu_name } +- + #define FPU(ver, _name) \ + { .fp_vers = ver, .name = _name } + +@@ -187,10 +183,10 @@ + },{ + 0x17, + .cpu_info = { +- CPU_PMU(0x10, "TI UltraSparc I (SpitFire)", "ultra12"), +- CPU_PMU(0x11, "TI UltraSparc II (BlackBird)", "ultra12"), +- CPU_PMU(0x12, "TI UltraSparc IIi (Sabre)", "ultra12"), +- CPU_PMU(0x13, "TI UltraSparc IIe (Hummingbird)", "ultra12"), ++ CPU(0x10, "TI UltraSparc I (SpitFire)"), ++ CPU(0x11, "TI UltraSparc II (BlackBird)"), ++ CPU(0x12, "TI UltraSparc IIi (Sabre)"), ++ CPU(0x13, "TI UltraSparc IIe (Hummingbird)"), + CPU(-1, NULL) + }, + .fpu_info = { +@@ -203,7 +199,7 @@ + },{ + 0x22, + .cpu_info = { +- CPU_PMU(0x10, "TI UltraSparc I (SpitFire)", "ultra12"), ++ CPU(0x10, "TI UltraSparc I (SpitFire)"), + CPU(-1, NULL) + }, + .fpu_info = { +@@ -213,12 +209,12 @@ + },{ + 0x3e, + .cpu_info = { +- CPU_PMU(0x14, "TI UltraSparc III (Cheetah)", "ultra3"), +- CPU_PMU(0x15, "TI UltraSparc III+ (Cheetah+)", "ultra3+"), +- CPU_PMU(0x16, "TI UltraSparc IIIi (Jalapeno)", "ultra3i"), +- CPU_PMU(0x18, "TI UltraSparc IV (Jaguar)", "ultra3+"), +- CPU_PMU(0x19, "TI UltraSparc IV+ (Panther)", "ultra4+"), +- CPU_PMU(0x22, "TI UltraSparc IIIi+ (Serrano)", "ultra3i"), ++ CPU(0x14, "TI UltraSparc III (Cheetah)"), ++ CPU(0x15, "TI UltraSparc III+ (Cheetah+)"), ++ CPU(0x16, "TI UltraSparc IIIi (Jalapeno)"), ++ CPU(0x18, "TI UltraSparc IV (Jaguar)"), ++ CPU(0x19, "TI UltraSparc IV+ (Panther)"), ++ CPU(0x22, "TI UltraSparc IIIi+ (Serrano)"), + CPU(-1, NULL) + }, + .fpu_info = { +@@ -238,7 +234,6 @@ + + const char *sparc_cpu_type; + const char *sparc_fpu_type; +-const char *sparc_pmu_type; + + unsigned int fsr_storage; + +@@ -249,7 +244,6 @@ + + sparc_cpu_type = NULL; + sparc_fpu_type = NULL; +- sparc_pmu_type = NULL; + manuf = NULL; + + for (i = 0; i < ARRAY_SIZE(manufacturer_info); i++) +@@ -269,7 +263,6 @@ + { + if (cpu->psr_vers == psr_vers) { + sparc_cpu_type = cpu->name; +- sparc_pmu_type = cpu->pmu_name; + sparc_fpu_type = "No FPU"; + break; + } +@@ -297,8 +290,6 @@ + psr_impl, fpu_vers); + sparc_fpu_type = "Unknown FPU"; + } +- if (sparc_pmu_type == NULL) +- sparc_pmu_type = "Unknown PMU"; + } + + #ifdef CONFIG_SPARC32 +@@ -324,13 +315,11 @@ + case SUN4V_CHIP_NIAGARA1: + sparc_cpu_type = "UltraSparc T1 (Niagara)"; + sparc_fpu_type = "UltraSparc T1 integrated FPU"; +- sparc_pmu_type = "niagara"; + break; + + case SUN4V_CHIP_NIAGARA2: + sparc_cpu_type = "UltraSparc T2 (Niagara2)"; + sparc_fpu_type = "UltraSparc T2 integrated FPU"; +- sparc_pmu_type = "niagara2"; + break; + + default: +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/arch/sparc/kernel/head_64.S linux-2.6.29-rc3.owrt/arch/sparc/kernel/head_64.S +--- linux-2.6.29.owrt/arch/sparc/kernel/head_64.S 2009-05-10 22:04:40.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/arch/sparc/kernel/head_64.S 2009-05-10 23:48:28.000000000 +0200 +@@ -891,35 +891,10 @@ + tlb_type: .word 0 /* Must NOT end up in BSS */ + .section ".fixup",#alloc,#execinstr + +- .globl __ret_efault, __retl_efault, __ret_one, __retl_one +-ENTRY(__ret_efault) ++ .globl __ret_efault, __retl_efault ++__ret_efault: + ret + restore %g0, -EFAULT, %o0 +-ENDPROC(__ret_efault) +- +-ENTRY(__retl_efault) ++__retl_efault: + retl + mov -EFAULT, %o0 +-ENDPROC(__retl_efault) +- +-ENTRY(__retl_one) +- retl +- mov 1, %o0 +-ENDPROC(__retl_one) +- +-ENTRY(__ret_one_asi) +- wr %g0, ASI_AIUS, %asi +- ret +- restore %g0, 1, %o0 +-ENDPROC(__ret_one_asi) +- +-ENTRY(__retl_one_asi) +- wr %g0, ASI_AIUS, %asi +- retl +- mov 1, %o0 +-ENDPROC(__retl_one_asi) +- +-ENTRY(__retl_o1) +- retl +- mov %o1, %o0 +-ENDPROC(__retl_o1) +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/arch/sparc/kernel/irq_64.c linux-2.6.29-rc3.owrt/arch/sparc/kernel/irq_64.c +--- linux-2.6.29.owrt/arch/sparc/kernel/irq_64.c 2009-05-10 22:04:40.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/arch/sparc/kernel/irq_64.c 2009-05-10 23:48:28.000000000 +0200 +@@ -196,11 +196,6 @@ + seq_putc(p, '\n'); + skip: + spin_unlock_irqrestore(&irq_desc[i].lock, flags); +- } else if (i == NR_IRQS) { +- seq_printf(p, "NMI: "); +- for_each_online_cpu(j) +- seq_printf(p, "%10u ", cpu_data(j).__nmi_count); +- seq_printf(p, " Non-maskable interrupts\n"); + } + return 0; + } +@@ -323,25 +318,17 @@ + sun4u_irq_enable(virt_irq); + } + +-/* Don't do anything. The desc->status check for IRQ_DISABLED in +- * handler_irq() will skip the handler call and that will leave the +- * interrupt in the sent state. The next ->enable() call will hit the +- * ICLR register to reset the state machine. +- * +- * This scheme is necessary, instead of clearing the Valid bit in the +- * IMAP register, to handle the case of IMAP registers being shared by +- * multiple INOs (and thus ICLR registers). Since we use a different +- * virtual IRQ for each shared IMAP instance, the generic code thinks +- * there is only one user so it prematurely calls ->disable() on +- * free_irq(). +- * +- * We have to provide an explicit ->disable() method instead of using +- * NULL to get the default. The reason is that if the generic code +- * sees that, it also hooks up a default ->shutdown method which +- * invokes ->mask() which we do not want. See irq_chip_set_defaults(). +- */ + static void sun4u_irq_disable(unsigned int virt_irq) + { ++ struct irq_handler_data *data = get_irq_chip_data(virt_irq); ++ ++ if (likely(data)) { ++ unsigned long imap = data->imap; ++ unsigned long tmp = upa_readq(imap); ++ ++ tmp &= ~IMAP_VALID; ++ upa_writeq(tmp, imap); ++ } + } + + static void sun4u_irq_eoi(unsigned int virt_irq) +@@ -754,8 +741,7 @@ + + desc = irq_desc + virt_irq; + +- if (!(desc->status & IRQ_DISABLED)) +- desc->handle_irq(virt_irq, desc); ++ desc->handle_irq(virt_irq, desc); + + bucket_pa = next_pa; + } +@@ -792,6 +778,69 @@ + local_irq_restore(flags); + } + ++static void unhandled_perf_irq(struct pt_regs *regs) ++{ ++ unsigned long pcr, pic; ++ ++ read_pcr(pcr); ++ read_pic(pic); ++ ++ write_pcr(0); ++ ++ printk(KERN_EMERG "CPU %d: Got unexpected perf counter IRQ.\n", ++ smp_processor_id()); ++ printk(KERN_EMERG "CPU %d: PCR[%016lx] PIC[%016lx]\n", ++ smp_processor_id(), pcr, pic); ++} ++ ++/* Almost a direct copy of the powerpc PMC code. */ ++static DEFINE_SPINLOCK(perf_irq_lock); ++static void *perf_irq_owner_caller; /* mostly for debugging */ ++static void (*perf_irq)(struct pt_regs *regs) = unhandled_perf_irq; ++ ++/* Invoked from level 15 PIL handler in trap table. */ ++void perfctr_irq(int irq, struct pt_regs *regs) ++{ ++ clear_softint(1 << irq); ++ perf_irq(regs); ++} ++ ++int register_perfctr_intr(void (*handler)(struct pt_regs *)) ++{ ++ int ret; ++ ++ if (!handler) ++ return -EINVAL; ++ ++ spin_lock(&perf_irq_lock); ++ if (perf_irq != unhandled_perf_irq) { ++ printk(KERN_WARNING "register_perfctr_intr: " ++ "perf IRQ busy (reserved by caller %p)\n", ++ perf_irq_owner_caller); ++ ret = -EBUSY; ++ goto out; ++ } ++ ++ perf_irq_owner_caller = __builtin_return_address(0); ++ perf_irq = handler; ++ ++ ret = 0; ++out: ++ spin_unlock(&perf_irq_lock); ++ ++ return ret; ++} ++EXPORT_SYMBOL_GPL(register_perfctr_intr); ++ ++void release_perfctr_intr(void (*handler)(struct pt_regs *)) ++{ ++ spin_lock(&perf_irq_lock); ++ perf_irq_owner_caller = NULL; ++ perf_irq = unhandled_perf_irq; ++ spin_unlock(&perf_irq_lock); ++} ++EXPORT_SYMBOL_GPL(release_perfctr_intr); ++ + #ifdef CONFIG_HOTPLUG_CPU + void fixup_irqs(void) + { +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/arch/sparc/kernel/kernel.h linux-2.6.29-rc3.owrt/arch/sparc/kernel/kernel.h +--- linux-2.6.29.owrt/arch/sparc/kernel/kernel.h 2009-05-10 22:04:40.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/arch/sparc/kernel/kernel.h 2009-05-10 23:48:28.000000000 +0200 +@@ -5,7 +5,6 @@ + + /* cpu.c */ + extern const char *sparc_cpu_type; +-extern const char *sparc_pmu_type; + extern const char *sparc_fpu_type; + + extern unsigned int fsr_storage; +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/arch/sparc/kernel/kgdb_64.c linux-2.6.29-rc3.owrt/arch/sparc/kernel/kgdb_64.c +--- linux-2.6.29.owrt/arch/sparc/kernel/kgdb_64.c 2009-05-10 22:04:40.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/arch/sparc/kernel/kgdb_64.c 2009-05-10 23:48:28.000000000 +0200 +@@ -108,7 +108,7 @@ + } + + #ifdef CONFIG_SMP +-void smp_kgdb_capture_client(int irq, struct pt_regs *regs) ++void smp_kgdb_capture_client(struct pt_regs *regs) + { + unsigned long flags; + +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/arch/sparc/kernel/Makefile linux-2.6.29-rc3.owrt/arch/sparc/kernel/Makefile +--- linux-2.6.29.owrt/arch/sparc/kernel/Makefile 2009-05-10 22:04:40.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/arch/sparc/kernel/Makefile 2009-05-10 23:48:28.000000000 +0200 +@@ -52,8 +52,6 @@ + obj-$(CONFIG_SPARC64) += hvapi.o + obj-$(CONFIG_SPARC64) += sstate.o + obj-$(CONFIG_SPARC64) += mdesc.o +-obj-$(CONFIG_SPARC64) += pcr.o +-obj-$(CONFIG_SPARC64) += nmi.o + + # sparc32 do not use GENERIC_HARDIRQS but uses the generic devres implementation + obj-$(CONFIG_SPARC32) += devres.o +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/arch/sparc/kernel/nmi.c linux-2.6.29-rc3.owrt/arch/sparc/kernel/nmi.c +--- linux-2.6.29.owrt/arch/sparc/kernel/nmi.c 2009-05-10 22:04:40.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/arch/sparc/kernel/nmi.c 1970-01-01 01:00:00.000000000 +0100 +@@ -1,225 +0,0 @@ +-/* Pseudo NMI support on sparc64 systems. +- * +- * Copyright (C) 2009 David S. Miller <davem@davemloft.net> +- * +- * The NMI watchdog support and infrastructure is based almost +- * entirely upon the x86 NMI support code. +- */ +-#include <linux/kernel.h> +-#include <linux/param.h> +-#include <linux/init.h> +-#include <linux/percpu.h> +-#include <linux/nmi.h> +-#include <linux/module.h> +-#include <linux/kprobes.h> +-#include <linux/kernel_stat.h> +-#include <linux/slab.h> +-#include <linux/kdebug.h> +-#include <linux/delay.h> +-#include <linux/smp.h> +- +-#include <asm/ptrace.h> +-#include <asm/local.h> +-#include <asm/pcr.h> +- +-/* We don't have a real NMI on sparc64, but we can fake one +- * up using profiling counter overflow interrupts and interrupt +- * levels. +- * +- * The profile overflow interrupts at level 15, so we use +- * level 14 as our IRQ off level. +- */ +- +-static int nmi_watchdog_active; +-static int panic_on_timeout; +- +-int nmi_usable; +-EXPORT_SYMBOL_GPL(nmi_usable); +- +-static unsigned int nmi_hz = HZ; +- +-static DEFINE_PER_CPU(unsigned int, last_irq_sum); +-static DEFINE_PER_CPU(local_t, alert_counter); +-static DEFINE_PER_CPU(int, nmi_touch); +- +-void touch_nmi_watchdog(void) +-{ +- if (nmi_watchdog_active) { +- int cpu; +- +- for_each_present_cpu(cpu) { +- if (per_cpu(nmi_touch, cpu) != 1) +- per_cpu(nmi_touch, cpu) = 1; +- } +- } +- +- touch_softlockup_watchdog(); +-} +-EXPORT_SYMBOL(touch_nmi_watchdog); +- +-static void die_nmi(const char *str, struct pt_regs *regs, int do_panic) +-{ +- if (notify_die(DIE_NMIWATCHDOG, str, regs, 0, +- pt_regs_trap_type(regs), SIGINT) == NOTIFY_STOP) +- return; +- +- console_verbose(); +- bust_spinlocks(1); +- +- printk(KERN_EMERG "%s", str); +- printk(" on CPU%d, ip %08lx, registers:\n", +- smp_processor_id(), regs->tpc); +- show_regs(regs); +- dump_stack(); +- +- bust_spinlocks(0); +- +- if (do_panic || panic_on_oops) +- panic("Non maskable interrupt"); +- +- local_irq_enable(); +- do_exit(SIGBUS); +-} +- +-notrace __kprobes void perfctr_irq(int irq, struct pt_regs *regs) +-{ +- unsigned int sum, touched = 0; +- int cpu = smp_processor_id(); +- +- clear_softint(1 << irq); +- pcr_ops->write(PCR_PIC_PRIV); +- +- local_cpu_data().__nmi_count++; +- +- if (notify_die(DIE_NMI, "nmi", regs, 0, +- pt_regs_trap_type(regs), SIGINT) == NOTIFY_STOP) +- touched = 1; +- +- sum = kstat_irqs_cpu(0, cpu); +- if (__get_cpu_var(nmi_touch)) { +- __get_cpu_var(nmi_touch) = 0; +- touched = 1; +- } +- if (!touched && __get_cpu_var(last_irq_sum) == sum) { +- local_inc(&__get_cpu_var(alert_counter)); +- if (local_read(&__get_cpu_var(alert_counter)) == 5 * nmi_hz) +- die_nmi("BUG: NMI Watchdog detected LOCKUP", +- regs, panic_on_timeout); +- } else { +- __get_cpu_var(last_irq_sum) = sum; +- local_set(&__get_cpu_var(alert_counter), 0); +- } +- if (nmi_usable) { +- write_pic(picl_value(nmi_hz)); +- pcr_ops->write(pcr_enable); +- } +-} +- +-static inline unsigned int get_nmi_count(int cpu) +-{ +- return cpu_data(cpu).__nmi_count; +-} +- +-static int endflag __initdata; +- +-static __init void nmi_cpu_busy(void *data) +-{ +- local_irq_enable_in_hardirq(); +- while (endflag == 0) +- mb(); +-} +- +-static void report_broken_nmi(int cpu, int *prev_nmi_count) +-{ +- printk(KERN_CONT "\n"); +- +- printk(KERN_WARNING +- "WARNING: CPU#%d: NMI appears to be stuck (%d->%d)!\n", +- cpu, prev_nmi_count[cpu], get_nmi_count(cpu)); +- +- printk(KERN_WARNING +- "Please report this to bugzilla.kernel.org,\n"); +- printk(KERN_WARNING +- "and attach the output of the 'dmesg' command.\n"); +- +- nmi_usable = 0; +-} +- +-static void stop_watchdog(void *unused) +-{ +- pcr_ops->write(PCR_PIC_PRIV); +-} +- +-static int __init check_nmi_watchdog(void) +-{ +- unsigned int *prev_nmi_count; +- int cpu, err; +- +- prev_nmi_count = kmalloc(nr_cpu_ids * sizeof(unsigned int), GFP_KERNEL); +- if (!prev_nmi_count) { +- err = -ENOMEM; +- goto error; +- } +- +- printk(KERN_INFO "Testing NMI watchdog ... "); +- +- smp_call_function(nmi_cpu_busy, (void *)&endflag, 0); +- +- for_each_possible_cpu(cpu) +- prev_nmi_count[cpu] = get_nmi_count(cpu); +- local_irq_enable(); +- mdelay((20 * 1000) / nmi_hz); /* wait 20 ticks */ +- +- for_each_online_cpu(cpu) { +- if (get_nmi_count(cpu) - prev_nmi_count[cpu] <= 5) +- report_broken_nmi(cpu, prev_nmi_count); +- } +- endflag = 1; +- if (!nmi_usable) { +- kfree(prev_nmi_count); +- err = -ENODEV; +- goto error; +- } +- printk("OK.\n"); +- +- nmi_hz = 1; +- +- kfree(prev_nmi_count); +- return 0; +-error: +- on_each_cpu(stop_watchdog, NULL, 1); +- return err; +-} +- +-static void start_watchdog(void *unused) +-{ +- pcr_ops->write(PCR_PIC_PRIV); +- write_pic(picl_value(nmi_hz)); +- +- pcr_ops->write(pcr_enable); +-} +- +-void nmi_adjust_hz(unsigned int new_hz) +-{ +- nmi_hz = new_hz; +- on_each_cpu(start_watchdog, NULL, 1); +-} +-EXPORT_SYMBOL_GPL(nmi_adjust_hz); +- +-int __init nmi_init(void) +-{ +- nmi_usable = 1; +- +- on_each_cpu(start_watchdog, NULL, 1); +- +- return check_nmi_watchdog(); +-} +- +-static int __init setup_nmi_watchdog(char *str) +-{ +- if (!strncmp(str, "panic", 5)) +- panic_on_timeout = 1; +- +- return 0; +-} +-__setup("nmi_watchdog=", setup_nmi_watchdog); +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/arch/sparc/kernel/pci_common.c linux-2.6.29-rc3.owrt/arch/sparc/kernel/pci_common.c +--- linux-2.6.29.owrt/arch/sparc/kernel/pci_common.c 2009-05-10 22:04:40.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/arch/sparc/kernel/pci_common.c 2009-05-10 23:48:28.000000000 +0200 +@@ -368,7 +368,7 @@ + const u32 *vdma = of_get_property(pbm->op->node, "virtual-dma", NULL); + + if (vdma) { +- struct resource *rp = kzalloc(sizeof(*rp), GFP_KERNEL); ++ struct resource *rp = kmalloc(sizeof(*rp), GFP_KERNEL); + + if (!rp) { + prom_printf("Cannot allocate IOMMU resource.\n"); +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/arch/sparc/kernel/pcr.c linux-2.6.29-rc3.owrt/arch/sparc/kernel/pcr.c +--- linux-2.6.29.owrt/arch/sparc/kernel/pcr.c 2009-05-10 22:04:40.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/arch/sparc/kernel/pcr.c 1970-01-01 01:00:00.000000000 +0100 +@@ -1,158 +0,0 @@ +-/* pcr.c: Generic sparc64 performance counter infrastructure. +- * +- * Copyright (C) 2009 David S. Miller (davem@davemloft.net) +- */ +-#include <linux/kernel.h> +-#include <linux/module.h> +-#include <linux/init.h> +-#include <linux/irq.h> +- +-#include <asm/pil.h> +-#include <asm/pcr.h> +-#include <asm/nmi.h> +- +-/* This code is shared between various users of the performance +- * counters. Users will be oprofile, pseudo-NMI watchdog, and the +- * perf_counter support layer. +- */ +- +-#define PCR_SUN4U_ENABLE (PCR_PIC_PRIV | PCR_STRACE | PCR_UTRACE) +-#define PCR_N2_ENABLE (PCR_PIC_PRIV | PCR_STRACE | PCR_UTRACE | \ +- PCR_N2_TOE_OV1 | \ +- (2 << PCR_N2_SL1_SHIFT) | \ +- (0xff << PCR_N2_MASK1_SHIFT)) +- +-u64 pcr_enable; +-unsigned int picl_shift; +- +-/* Performance counter interrupts run unmasked at PIL level 15. +- * Therefore we can't do things like wakeups and other work +- * that expects IRQ disabling to be adhered to in locking etc. +- * +- * Therefore in such situations we defer the work by signalling +- * a lower level cpu IRQ. +- */ +-void deferred_pcr_work_irq(int irq, struct pt_regs *regs) +-{ +- clear_softint(1 << PIL_DEFERRED_PCR_WORK); +-} +- +-void schedule_deferred_pcr_work(void) +-{ +- set_softint(1 << PIL_DEFERRED_PCR_WORK); +-} +- +-const struct pcr_ops *pcr_ops; +-EXPORT_SYMBOL_GPL(pcr_ops); +- +-static u64 direct_pcr_read(void) +-{ +- u64 val; +- +- read_pcr(val); +- return val; +-} +- +-static void direct_pcr_write(u64 val) +-{ +- write_pcr(val); +-} +- +-static const struct pcr_ops direct_pcr_ops = { +- .read = direct_pcr_read, +- .write = direct_pcr_write, +-}; +- +-static void n2_pcr_write(u64 val) +-{ +- unsigned long ret; +- +- ret = sun4v_niagara2_setperf(HV_N2_PERF_SPARC_CTL, val); +- if (val != HV_EOK) +- write_pcr(val); +-} +- +-static const struct pcr_ops n2_pcr_ops = { +- .read = direct_pcr_read, +- .write = n2_pcr_write, +-}; +- +-static unsigned long perf_hsvc_group; +-static unsigned long perf_hsvc_major; +-static unsigned long perf_hsvc_minor; +- +-static int __init register_perf_hsvc(void) +-{ +- if (tlb_type == hypervisor) { +- switch (sun4v_chip_type) { +- case SUN4V_CHIP_NIAGARA1: +- perf_hsvc_group = HV_GRP_NIAG_PERF; +- break; +- +- case SUN4V_CHIP_NIAGARA2: +- perf_hsvc_group = HV_GRP_N2_CPU; +- break; +- +- default: +- return -ENODEV; +- } +- +- +- perf_hsvc_major = 1; +- perf_hsvc_minor = 0; +- if (sun4v_hvapi_register(perf_hsvc_group, +- perf_hsvc_major, +- &perf_hsvc_minor)) { +- printk("perfmon: Could not register hvapi.\n"); +- return -ENODEV; +- } +- } +- return 0; +-} +- +-static void __init unregister_perf_hsvc(void) +-{ +- if (tlb_type != hypervisor) +- return; +- sun4v_hvapi_unregister(perf_hsvc_group); +-} +- +-int __init pcr_arch_init(void) +-{ +- int err = register_perf_hsvc(); +- +- if (err) +- return err; +- +- switch (tlb_type) { +- case hypervisor: +- pcr_ops = &n2_pcr_ops; +- pcr_enable = PCR_N2_ENABLE; +- picl_shift = 2; +- break; +- +- case cheetah: +- case cheetah_plus: +- pcr_ops = &direct_pcr_ops; +- pcr_enable = PCR_SUN4U_ENABLE; +- break; +- +- case spitfire: +- /* UltraSPARC-I/II and derivatives lack a profile +- * counter overflow interrupt so we can't make use of +- * their hardware currently. +- */ +- /* fallthrough */ +- default: +- err = -ENODEV; +- goto out_unregister; +- } +- +- return nmi_init(); +- +-out_unregister: +- unregister_perf_hsvc(); +- return err; +-} +- +-arch_initcall(pcr_arch_init); +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/arch/sparc/kernel/process_64.c linux-2.6.29-rc3.owrt/arch/sparc/kernel/process_64.c +--- linux-2.6.29.owrt/arch/sparc/kernel/process_64.c 2009-05-10 22:04:40.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/arch/sparc/kernel/process_64.c 2009-05-10 23:48:28.000000000 +0200 +@@ -29,7 +29,6 @@ + #include <linux/cpu.h> + #include <linux/elfcore.h> + #include <linux/sysrq.h> +-#include <linux/nmi.h> + + #include <asm/uaccess.h> + #include <asm/system.h> +@@ -53,10 +52,8 @@ + + static void sparc64_yield(int cpu) + { +- if (tlb_type != hypervisor) { +- touch_nmi_watchdog(); ++ if (tlb_type != hypervisor) + return; +- } + + clear_thread_flag(TIF_POLLING_NRFLAG); + smp_mb__after_clear_bit(); +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/arch/sparc/kernel/setup_64.c linux-2.6.29-rc3.owrt/arch/sparc/kernel/setup_64.c +--- linux-2.6.29.owrt/arch/sparc/kernel/setup_64.c 2009-05-10 22:04:40.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/arch/sparc/kernel/setup_64.c 2009-05-10 23:48:28.000000000 +0200 +@@ -354,7 +354,6 @@ + seq_printf(m, + "cpu\t\t: %s\n" + "fpu\t\t: %s\n" +- "pmu\t\t: %s\n" + "prom\t\t: %s\n" + "type\t\t: %s\n" + "ncpus probed\t: %d\n" +@@ -367,7 +366,6 @@ + , + sparc_cpu_type, + sparc_fpu_type, +- sparc_pmu_type, + prom_version, + ((tlb_type == hypervisor) ? + "sun4v" : +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/arch/sparc/kernel/ttable.S linux-2.6.29-rc3.owrt/arch/sparc/kernel/ttable.S +--- linux-2.6.29.owrt/arch/sparc/kernel/ttable.S 2009-05-10 22:04:40.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/arch/sparc/kernel/ttable.S 2009-05-10 23:48:28.000000000 +0200 +@@ -63,13 +63,7 @@ + #else + tl0_irq6: BTRAP(0x46) + #endif +-tl0_irq7: TRAP_IRQ(deferred_pcr_work_irq, 7) +-#ifdef CONFIG_KGDB +-tl0_irq8: TRAP_IRQ(smp_kgdb_capture_client, 8) +-#else +-tl0_irq8: BTRAP(0x48) +-#endif +-tl0_irq9: BTRAP(0x49) ++tl0_irq7: BTRAP(0x47) BTRAP(0x48) BTRAP(0x49) + tl0_irq10: BTRAP(0x4a) BTRAP(0x4b) BTRAP(0x4c) BTRAP(0x4d) + tl0_irq14: TRAP_IRQ(timer_interrupt, 14) + tl0_irq15: TRAP_NMI_IRQ(perfctr_irq, 15) +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/arch/sparc/lib/bzero.S linux-2.6.29-rc3.owrt/arch/sparc/lib/bzero.S +--- linux-2.6.29.owrt/arch/sparc/lib/bzero.S 2009-05-10 22:04:40.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/arch/sparc/lib/bzero.S 2009-05-10 23:48:28.000000000 +0200 +@@ -88,9 +88,13 @@ + + #define EX_ST(x,y) \ + 98: x,y; \ ++ .section .fixup; \ ++ .align 4; \ ++99: retl; \ ++ mov %o1, %o0; \ + .section __ex_table,"a";\ + .align 4; \ +- .word 98b, __retl_o1; \ ++ .word 98b, 99b; \ + .text; \ + .align 4; + +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/arch/sparc/lib/copy_in_user.S linux-2.6.29-rc3.owrt/arch/sparc/lib/copy_in_user.S +--- linux-2.6.29.owrt/arch/sparc/lib/copy_in_user.S 2009-05-10 22:04:40.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/arch/sparc/lib/copy_in_user.S 2009-05-10 23:48:28.000000000 +0200 +@@ -3,16 +3,19 @@ + * Copyright (C) 1999, 2000, 2004 David S. Miller (davem@redhat.com) + */ + +-#include <linux/linkage.h> + #include <asm/asi.h> + + #define XCC xcc + + #define EX(x,y) \ + 98: x,y; \ ++ .section .fixup; \ ++ .align 4; \ ++99: retl; \ ++ mov 1, %o0; \ + .section __ex_table,"a";\ + .align 4; \ +- .word 98b, __retl_one; \ ++ .word 98b, 99b; \ + .text; \ + .align 4; + +@@ -28,7 +31,18 @@ + * to copy register windows around during thread cloning. + */ + +-ENTRY(___copy_in_user) /* %o0=dst, %o1=src, %o2=len */ ++ .globl ___copy_in_user ++ .type ___copy_in_user,#function ++___copy_in_user: /* %o0=dst, %o1=src, %o2=len */ ++ /* Writing to %asi is _expensive_ so we hardcode it. ++ * Reading %asi to check for KERNEL_DS is comparatively ++ * cheap. ++ */ ++ rd %asi, %g1 ++ cmp %g1, ASI_AIUS ++ bne,pn %icc, memcpy_user_stub ++ nop ++ + cmp %o2, 0 + be,pn %XCC, 85f + or %o0, %o1, %o3 +@@ -39,24 +53,22 @@ + /* 16 < len <= 64 */ + andcc %o3, 0x7, %g0 + bne,pn %XCC, 90f +- nop ++ sub %o0, %o1, %o3 + + andn %o2, 0x7, %o4 + and %o2, 0x7, %o2 + 1: subcc %o4, 0x8, %o4 + EX(ldxa [%o1] %asi, %o5) +- EX(stxa %o5, [%o0] %asi) +- add %o1, 0x8, %o1 ++ EX(stxa %o5, [%o1 + %o3] ASI_AIUS) + bgu,pt %XCC, 1b +- add %o0, 0x8, %o0 ++ add %o1, 0x8, %o1 + andcc %o2, 0x4, %g0 + be,pt %XCC, 1f + nop + sub %o2, 0x4, %o2 + EX(lduwa [%o1] %asi, %o5) +- EX(stwa %o5, [%o0] %asi) ++ EX(stwa %o5, [%o1 + %o3] ASI_AIUS) + add %o1, 0x4, %o1 +- add %o0, 0x4, %o0 + 1: cmp %o2, 0 + be,pt %XCC, 85f + nop +@@ -66,15 +78,14 @@ + 80: /* 0 < len <= 16 */ + andcc %o3, 0x3, %g0 + bne,pn %XCC, 90f +- nop ++ sub %o0, %o1, %o3 + + 82: + subcc %o2, 4, %o2 + EX(lduwa [%o1] %asi, %g1) +- EX(stwa %g1, [%o0] %asi) +- add %o1, 4, %o1 ++ EX(stwa %g1, [%o1 + %o3] ASI_AIUS) + bgu,pt %XCC, 82b +- add %o0, 4, %o0 ++ add %o1, 4, %o1 + + 85: retl + clr %o0 +@@ -83,10 +94,26 @@ + 90: + subcc %o2, 1, %o2 + EX(lduba [%o1] %asi, %g1) +- EX(stba %g1, [%o0] %asi) +- add %o1, 1, %o1 ++ EX(stba %g1, [%o1 + %o3] ASI_AIUS) + bgu,pt %XCC, 90b +- add %o0, 1, %o0 ++ add %o1, 1, %o1 + retl + clr %o0 +-ENDPROC(___copy_in_user) ++ ++ .size ___copy_in_user, .-___copy_in_user ++ ++ /* Act like copy_{to,in}_user(), ie. return zero instead ++ * of original destination pointer. This is invoked when ++ * copy_{to,in}_user() finds that %asi is kernel space. ++ */ ++ .globl memcpy_user_stub ++ .type memcpy_user_stub,#function ++memcpy_user_stub: ++ save %sp, -192, %sp ++ mov %i0, %o0 ++ mov %i1, %o1 ++ call memcpy ++ mov %i2, %o2 ++ ret ++ restore %g0, %g0, %o0 ++ .size memcpy_user_stub, .-memcpy_user_stub +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/arch/sparc/lib/GENbzero.S linux-2.6.29-rc3.owrt/arch/sparc/lib/GENbzero.S +--- linux-2.6.29.owrt/arch/sparc/lib/GENbzero.S 2009-05-10 22:04:40.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/arch/sparc/lib/GENbzero.S 2009-05-10 23:48:28.000000000 +0200 +@@ -6,9 +6,13 @@ + + #define EX_ST(x,y) \ + 98: x,y; \ ++ .section .fixup; \ ++ .align 4; \ ++99: retl; \ ++ mov %o1, %o0; \ + .section __ex_table,"a";\ + .align 4; \ +- .word 98b, __retl_o1; \ ++ .word 98b, 99b; \ + .text; \ + .align 4; + +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/arch/sparc/lib/GENcopy_from_user.S linux-2.6.29-rc3.owrt/arch/sparc/lib/GENcopy_from_user.S +--- linux-2.6.29.owrt/arch/sparc/lib/GENcopy_from_user.S 2009-05-10 22:04:40.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/arch/sparc/lib/GENcopy_from_user.S 2009-05-10 23:48:28.000000000 +0200 +@@ -5,9 +5,13 @@ + + #define EX_LD(x) \ + 98: x; \ ++ .section .fixup; \ ++ .align 4; \ ++99: retl; \ ++ mov 1, %o0; \ + .section __ex_table,"a";\ + .align 4; \ +- .word 98b, __retl_one; \ ++ .word 98b, 99b; \ + .text; \ + .align 4; + +@@ -23,7 +27,7 @@ + #define PREAMBLE \ + rd %asi, %g1; \ + cmp %g1, ASI_AIUS; \ +- bne,pn %icc, ___copy_in_user; \ ++ bne,pn %icc, memcpy_user_stub; \ + nop + #endif + +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/arch/sparc/lib/GENcopy_to_user.S linux-2.6.29-rc3.owrt/arch/sparc/lib/GENcopy_to_user.S +--- linux-2.6.29.owrt/arch/sparc/lib/GENcopy_to_user.S 2009-05-10 22:04:40.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/arch/sparc/lib/GENcopy_to_user.S 2009-05-10 23:48:28.000000000 +0200 +@@ -5,9 +5,13 @@ + + #define EX_ST(x) \ + 98: x; \ ++ .section .fixup; \ ++ .align 4; \ ++99: retl; \ ++ mov 1, %o0; \ + .section __ex_table,"a";\ + .align 4; \ +- .word 98b, __retl_one; \ ++ .word 98b, 99b; \ + .text; \ + .align 4; + +@@ -27,7 +31,7 @@ + #define PREAMBLE \ + rd %asi, %g1; \ + cmp %g1, ASI_AIUS; \ +- bne,pn %icc, ___copy_in_user; \ ++ bne,pn %icc, memcpy_user_stub; \ + nop + #endif + +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/arch/sparc/lib/NG2copy_from_user.S linux-2.6.29-rc3.owrt/arch/sparc/lib/NG2copy_from_user.S +--- linux-2.6.29.owrt/arch/sparc/lib/NG2copy_from_user.S 2009-05-10 22:04:40.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/arch/sparc/lib/NG2copy_from_user.S 2009-05-10 23:48:28.000000000 +0200 +@@ -5,9 +5,14 @@ + + #define EX_LD(x) \ + 98: x; \ ++ .section .fixup; \ ++ .align 4; \ ++99: wr %g0, ASI_AIUS, %asi;\ ++ retl; \ ++ mov 1, %o0; \ + .section __ex_table,"a";\ + .align 4; \ +- .word 98b, __retl_one_asi;\ ++ .word 98b, 99b; \ + .text; \ + .align 4; + +@@ -28,7 +33,7 @@ + #define PREAMBLE \ + rd %asi, %g1; \ + cmp %g1, ASI_AIUS; \ +- bne,pn %icc, ___copy_in_user; \ ++ bne,pn %icc, memcpy_user_stub; \ + nop + #endif + +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/arch/sparc/lib/NG2copy_to_user.S linux-2.6.29-rc3.owrt/arch/sparc/lib/NG2copy_to_user.S +--- linux-2.6.29.owrt/arch/sparc/lib/NG2copy_to_user.S 2009-05-10 22:04:40.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/arch/sparc/lib/NG2copy_to_user.S 2009-05-10 23:48:28.000000000 +0200 +@@ -5,9 +5,14 @@ + + #define EX_ST(x) \ + 98: x; \ ++ .section .fixup; \ ++ .align 4; \ ++99: wr %g0, ASI_AIUS, %asi;\ ++ retl; \ ++ mov 1, %o0; \ + .section __ex_table,"a";\ + .align 4; \ +- .word 98b, __retl_one_asi;\ ++ .word 98b, 99b; \ + .text; \ + .align 4; + +@@ -37,7 +42,7 @@ + #define PREAMBLE \ + rd %asi, %g1; \ + cmp %g1, ASI_AIUS; \ +- bne,pn %icc, ___copy_in_user; \ ++ bne,pn %icc, memcpy_user_stub; \ + nop + #endif + +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/arch/sparc/lib/NGbzero.S linux-2.6.29-rc3.owrt/arch/sparc/lib/NGbzero.S +--- linux-2.6.29.owrt/arch/sparc/lib/NGbzero.S 2009-05-10 22:04:40.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/arch/sparc/lib/NGbzero.S 2009-05-10 23:48:28.000000000 +0200 +@@ -6,9 +6,13 @@ + + #define EX_ST(x,y) \ + 98: x,y; \ ++ .section .fixup; \ ++ .align 4; \ ++99: retl; \ ++ mov %o1, %o0; \ + .section __ex_table,"a";\ + .align 4; \ +- .word 98b, __retl_o1; \ ++ .word 98b, 99b; \ + .text; \ + .align 4; + +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/arch/sparc/lib/NGcopy_from_user.S linux-2.6.29-rc3.owrt/arch/sparc/lib/NGcopy_from_user.S +--- linux-2.6.29.owrt/arch/sparc/lib/NGcopy_from_user.S 2009-05-10 22:04:40.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/arch/sparc/lib/NGcopy_from_user.S 2009-05-10 23:48:28.000000000 +0200 +@@ -5,9 +5,14 @@ + + #define EX_LD(x) \ + 98: x; \ ++ .section .fixup; \ ++ .align 4; \ ++99: wr %g0, ASI_AIUS, %asi;\ ++ ret; \ ++ restore %g0, 1, %o0; \ + .section __ex_table,"a";\ + .align 4; \ +- .word 98b, __ret_one_asi;\ ++ .word 98b, 99b; \ + .text; \ + .align 4; + +@@ -25,7 +30,7 @@ + #define PREAMBLE \ + rd %asi, %g1; \ + cmp %g1, ASI_AIUS; \ +- bne,pn %icc, ___copy_in_user; \ ++ bne,pn %icc, memcpy_user_stub; \ + nop + #endif + +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/arch/sparc/lib/NGcopy_to_user.S linux-2.6.29-rc3.owrt/arch/sparc/lib/NGcopy_to_user.S +--- linux-2.6.29.owrt/arch/sparc/lib/NGcopy_to_user.S 2009-05-10 22:04:40.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/arch/sparc/lib/NGcopy_to_user.S 2009-05-10 23:48:28.000000000 +0200 +@@ -5,9 +5,14 @@ + + #define EX_ST(x) \ + 98: x; \ ++ .section .fixup; \ ++ .align 4; \ ++99: wr %g0, ASI_AIUS, %asi;\ ++ ret; \ ++ restore %g0, 1, %o0; \ + .section __ex_table,"a";\ + .align 4; \ +- .word 98b, __ret_one_asi;\ ++ .word 98b, 99b; \ + .text; \ + .align 4; + +@@ -28,7 +33,7 @@ + #define PREAMBLE \ + rd %asi, %g1; \ + cmp %g1, ASI_AIUS; \ +- bne,pn %icc, ___copy_in_user; \ ++ bne,pn %icc, memcpy_user_stub; \ + nop + #endif + +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/arch/sparc/lib/U1copy_from_user.S linux-2.6.29-rc3.owrt/arch/sparc/lib/U1copy_from_user.S +--- linux-2.6.29.owrt/arch/sparc/lib/U1copy_from_user.S 2009-05-10 22:04:40.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/arch/sparc/lib/U1copy_from_user.S 2009-05-10 23:48:28.000000000 +0200 +@@ -5,9 +5,13 @@ + + #define EX_LD(x) \ + 98: x; \ ++ .section .fixup; \ ++ .align 4; \ ++99: retl; \ ++ mov 1, %o0; \ + .section __ex_table,"a";\ + .align 4; \ +- .word 98b, __retl_one; \ ++ .word 98b, 99b; \ + .text; \ + .align 4; + +@@ -23,7 +27,7 @@ + #define PREAMBLE \ + rd %asi, %g1; \ + cmp %g1, ASI_AIUS; \ +- bne,pn %icc, ___copy_in_user; \ ++ bne,pn %icc, memcpy_user_stub; \ + nop; \ + + #include "U1memcpy.S" +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/arch/sparc/lib/U1copy_to_user.S linux-2.6.29-rc3.owrt/arch/sparc/lib/U1copy_to_user.S +--- linux-2.6.29.owrt/arch/sparc/lib/U1copy_to_user.S 2009-05-10 22:04:40.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/arch/sparc/lib/U1copy_to_user.S 2009-05-10 23:48:28.000000000 +0200 +@@ -5,9 +5,13 @@ + + #define EX_ST(x) \ + 98: x; \ ++ .section .fixup; \ ++ .align 4; \ ++99: retl; \ ++ mov 1, %o0; \ + .section __ex_table,"a";\ + .align 4; \ +- .word 98b, __retl_one; \ ++ .word 98b, 99b; \ + .text; \ + .align 4; + +@@ -23,7 +27,7 @@ + #define PREAMBLE \ + rd %asi, %g1; \ + cmp %g1, ASI_AIUS; \ +- bne,pn %icc, ___copy_in_user; \ ++ bne,pn %icc, memcpy_user_stub; \ + nop; \ + + #include "U1memcpy.S" +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/arch/sparc/lib/U3copy_from_user.S linux-2.6.29-rc3.owrt/arch/sparc/lib/U3copy_from_user.S +--- linux-2.6.29.owrt/arch/sparc/lib/U3copy_from_user.S 2009-05-10 22:04:40.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/arch/sparc/lib/U3copy_from_user.S 2009-05-10 23:48:28.000000000 +0200 +@@ -5,9 +5,13 @@ + + #define EX_LD(x) \ + 98: x; \ ++ .section .fixup; \ ++ .align 4; \ ++99: retl; \ ++ mov 1, %o0; \ + .section __ex_table,"a";\ + .align 4; \ +- .word 98b, __retl_one; \ ++ .word 98b, 99b; \ + .text; \ + .align 4; + +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/arch/sparc/lib/U3copy_to_user.S linux-2.6.29-rc3.owrt/arch/sparc/lib/U3copy_to_user.S +--- linux-2.6.29.owrt/arch/sparc/lib/U3copy_to_user.S 2009-05-10 22:04:40.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/arch/sparc/lib/U3copy_to_user.S 2009-05-10 23:48:28.000000000 +0200 +@@ -5,9 +5,13 @@ + + #define EX_ST(x) \ + 98: x; \ ++ .section .fixup; \ ++ .align 4; \ ++99: retl; \ ++ mov 1, %o0; \ + .section __ex_table,"a";\ + .align 4; \ +- .word 98b, __retl_one; \ ++ .word 98b, 99b; \ + .text; \ + .align 4; + +@@ -23,7 +27,7 @@ + #define PREAMBLE \ + rd %asi, %g1; \ + cmp %g1, ASI_AIUS; \ +- bne,pn %icc, ___copy_in_user; \ ++ bne,pn %icc, memcpy_user_stub; \ + nop; \ + + #include "U3memcpy.S" +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/arch/sparc/mm/fault_64.c linux-2.6.29-rc3.owrt/arch/sparc/mm/fault_64.c +--- linux-2.6.29.owrt/arch/sparc/mm/fault_64.c 2009-05-10 22:04:40.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/arch/sparc/mm/fault_64.c 2009-05-10 23:48:28.000000000 +0200 +@@ -19,7 +19,6 @@ + #include <linux/interrupt.h> + #include <linux/kprobes.h> + #include <linux/kdebug.h> +-#include <linux/percpu.h> + + #include <asm/page.h> + #include <asm/pgtable.h> +@@ -225,30 +224,6 @@ + unhandled_fault (address, current, regs); + } + +-static void noinline bogus_32bit_fault_tpc(struct pt_regs *regs) +-{ +- static int times; +- +- if (times++ < 10) +- printk(KERN_ERR "FAULT[%s:%d]: 32-bit process reports " +- "64-bit TPC [%lx]\n", +- current->comm, current->pid, +- regs->tpc); +- show_regs(regs); +-} +- +-static void noinline bogus_32bit_fault_address(struct pt_regs *regs, +- unsigned long addr) +-{ +- static int times; +- +- if (times++ < 10) +- printk(KERN_ERR "FAULT[%s:%d]: 32-bit process " +- "reports 64-bit fault address [%lx]\n", +- current->comm, current->pid, addr); +- show_regs(regs); +-} +- + asmlinkage void __kprobes do_sparc64_fault(struct pt_regs *regs) + { + struct mm_struct *mm = current->mm; +@@ -269,19 +244,6 @@ + (fault_code & FAULT_CODE_DTLB)) + BUG(); + +- if (test_thread_flag(TIF_32BIT)) { +- if (!(regs->tstate & TSTATE_PRIV)) { +- if (unlikely((regs->tpc >> 32) != 0)) { +- bogus_32bit_fault_tpc(regs); +- goto intr_or_no_mm; +- } +- } +- if (unlikely((address >> 32) != 0)) { +- bogus_32bit_fault_address(regs, address); +- goto intr_or_no_mm; +- } +- } +- + if (regs->tstate & TSTATE_PRIV) { + unsigned long tpc = regs->tpc; + +@@ -302,6 +264,12 @@ + if (in_atomic() || !mm) + goto intr_or_no_mm; + ++ if (test_thread_flag(TIF_32BIT)) { ++ if (!(regs->tstate & TSTATE_PRIV)) ++ regs->tpc &= 0xffffffff; ++ address &= 0xffffffff; ++ } ++ + if (!down_read_trylock(&mm->mmap_sem)) { + if ((regs->tstate & TSTATE_PRIV) && + !search_exception_tables(regs->tpc)) { +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/arch/sparc/mm/ultra.S linux-2.6.29-rc3.owrt/arch/sparc/mm/ultra.S +--- linux-2.6.29.owrt/arch/sparc/mm/ultra.S 2009-05-10 22:04:40.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/arch/sparc/mm/ultra.S 2009-05-10 23:48:28.000000000 +0200 +@@ -679,8 +679,28 @@ + #ifdef CONFIG_KGDB + .globl xcall_kgdb_capture + xcall_kgdb_capture: +- wr %g0, (1 << PIL_KGDB_CAPTURE), %set_softint +- retry ++661: rdpr %pstate, %g2 ++ wrpr %g2, PSTATE_IG | PSTATE_AG, %pstate ++ .section .sun4v_2insn_patch, "ax" ++ .word 661b ++ nop ++ nop ++ .previous ++ ++ rdpr %pil, %g2 ++ wrpr %g0, PIL_NORMAL_MAX, %pil ++ sethi %hi(109f), %g7 ++ ba,pt %xcc, etrap_irq ++109: or %g7, %lo(109b), %g7 ++#ifdef CONFIG_TRACE_IRQFLAGS ++ call trace_hardirqs_off ++ nop ++#endif ++ call smp_kgdb_capture_client ++ add %sp, PTREGS_OFF, %o0 ++ /* Has to be a non-v9 branch due to the large distance. */ ++ ba rtrap_xcall ++ ldx [%sp + PTREGS_OFF + PT_V9_TSTATE], %l1 + #endif + + #endif /* CONFIG_SMP */ +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/arch/sparc/oprofile/init.c linux-2.6.29-rc3.owrt/arch/sparc/oprofile/init.c +--- linux-2.6.29.owrt/arch/sparc/oprofile/init.c 2009-05-10 22:04:40.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/arch/sparc/oprofile/init.c 2009-05-10 23:48:28.000000000 +0200 +@@ -13,57 +13,217 @@ + #include <linux/init.h> + + #ifdef CONFIG_SPARC64 +-#include <linux/notifier.h> +-#include <linux/rcupdate.h> +-#include <linux/kdebug.h> +-#include <asm/nmi.h> +- +-static int profile_timer_exceptions_notify(struct notifier_block *self, +- unsigned long val, void *data) +-{ +- struct die_args *args = (struct die_args *)data; +- int ret = NOTIFY_DONE; +- +- switch (val) { +- case DIE_NMI: +- oprofile_add_sample(args->regs, 0); +- ret = NOTIFY_STOP; +- break; +- default: +- break; +- } +- return ret; ++#include <asm/hypervisor.h> ++#include <asm/spitfire.h> ++#include <asm/cpudata.h> ++#include <asm/irq.h> ++ ++static int nmi_enabled; ++ ++struct pcr_ops { ++ u64 (*read)(void); ++ void (*write)(u64); ++}; ++static const struct pcr_ops *pcr_ops; ++ ++static u64 direct_pcr_read(void) ++{ ++ u64 val; ++ ++ read_pcr(val); ++ return val; ++} ++ ++static void direct_pcr_write(u64 val) ++{ ++ write_pcr(val); + } + +-static struct notifier_block profile_timer_exceptions_nb = { +- .notifier_call = profile_timer_exceptions_notify, ++static const struct pcr_ops direct_pcr_ops = { ++ .read = direct_pcr_read, ++ .write = direct_pcr_write, + }; + +-static int timer_start(void) ++static void n2_pcr_write(u64 val) + { +- if (register_die_notifier(&profile_timer_exceptions_nb)) +- return 1; +- nmi_adjust_hz(HZ); +- return 0; ++ unsigned long ret; ++ ++ ret = sun4v_niagara2_setperf(HV_N2_PERF_SPARC_CTL, val); ++ if (val != HV_EOK) ++ write_pcr(val); + } + ++static const struct pcr_ops n2_pcr_ops = { ++ .read = direct_pcr_read, ++ .write = n2_pcr_write, ++}; + +-static void timer_stop(void) ++/* In order to commonize as much of the implementation as ++ * possible, we use PICH as our counter. Mostly this is ++ * to accomodate Niagara-1 which can only count insn cycles ++ * in PICH. ++ */ ++static u64 picl_value(void) ++{ ++ u32 delta = local_cpu_data().clock_tick / HZ; ++ ++ return ((u64)((0 - delta) & 0xffffffff)) << 32; ++} ++ ++#define PCR_PIC_PRIV 0x00000001 /* PIC access is privileged */ ++#define PCR_STRACE 0x00000002 /* Trace supervisor events */ ++#define PCR_UTRACE 0x00000004 /* Trace user events */ ++#define PCR_N2_HTRACE 0x00000008 /* Trace hypervisor events */ ++#define PCR_N2_TOE_OV0 0x00000010 /* Trap if PIC 0 overflows */ ++#define PCR_N2_TOE_OV1 0x00000020 /* Trap if PIC 1 overflows */ ++#define PCR_N2_MASK0 0x00003fc0 ++#define PCR_N2_MASK0_SHIFT 6 ++#define PCR_N2_SL0 0x0003c000 ++#define PCR_N2_SL0_SHIFT 14 ++#define PCR_N2_OV0 0x00040000 ++#define PCR_N2_MASK1 0x07f80000 ++#define PCR_N2_MASK1_SHIFT 19 ++#define PCR_N2_SL1 0x78000000 ++#define PCR_N2_SL1_SHIFT 27 ++#define PCR_N2_OV1 0x80000000 ++ ++#define PCR_SUN4U_ENABLE (PCR_PIC_PRIV | PCR_STRACE | PCR_UTRACE) ++#define PCR_N2_ENABLE (PCR_PIC_PRIV | PCR_STRACE | PCR_UTRACE | \ ++ PCR_N2_TOE_OV1 | \ ++ (2 << PCR_N2_SL1_SHIFT) | \ ++ (0xff << PCR_N2_MASK1_SHIFT)) ++ ++static u64 pcr_enable = PCR_SUN4U_ENABLE; ++ ++static void nmi_handler(struct pt_regs *regs) + { +- nmi_adjust_hz(1); +- unregister_die_notifier(&profile_timer_exceptions_nb); +- synchronize_sched(); /* Allow already-started NMIs to complete. */ ++ pcr_ops->write(PCR_PIC_PRIV); ++ ++ if (nmi_enabled) { ++ oprofile_add_sample(regs, 0); ++ ++ write_pic(picl_value()); ++ pcr_ops->write(pcr_enable); ++ } ++} ++ ++/* We count "clock cycle" events in the lower 32-bit PIC. ++ * Then configure it such that it overflows every HZ, and thus ++ * generates a level 15 interrupt at that frequency. ++ */ ++static void cpu_nmi_start(void *_unused) ++{ ++ pcr_ops->write(PCR_PIC_PRIV); ++ write_pic(picl_value()); ++ ++ pcr_ops->write(pcr_enable); ++} ++ ++static void cpu_nmi_stop(void *_unused) ++{ ++ pcr_ops->write(PCR_PIC_PRIV); ++} ++ ++static int nmi_start(void) ++{ ++ int err = register_perfctr_intr(nmi_handler); ++ ++ if (!err) { ++ nmi_enabled = 1; ++ wmb(); ++ err = on_each_cpu(cpu_nmi_start, NULL, 1); ++ if (err) { ++ nmi_enabled = 0; ++ wmb(); ++ on_each_cpu(cpu_nmi_stop, NULL, 1); ++ release_perfctr_intr(nmi_handler); ++ } ++ } ++ ++ return err; + } + +-static int op_nmi_timer_init(struct oprofile_operations *ops) ++static void nmi_stop(void) + { +- if (!nmi_usable) ++ nmi_enabled = 0; ++ wmb(); ++ ++ on_each_cpu(cpu_nmi_stop, NULL, 1); ++ release_perfctr_intr(nmi_handler); ++ synchronize_sched(); ++} ++ ++static unsigned long perf_hsvc_group; ++static unsigned long perf_hsvc_major; ++static unsigned long perf_hsvc_minor; ++ ++static int __init register_perf_hsvc(void) ++{ ++ if (tlb_type == hypervisor) { ++ switch (sun4v_chip_type) { ++ case SUN4V_CHIP_NIAGARA1: ++ perf_hsvc_group = HV_GRP_NIAG_PERF; ++ break; ++ ++ case SUN4V_CHIP_NIAGARA2: ++ perf_hsvc_group = HV_GRP_N2_CPU; ++ break; ++ ++ default: ++ return -ENODEV; ++ } ++ ++ ++ perf_hsvc_major = 1; ++ perf_hsvc_minor = 0; ++ if (sun4v_hvapi_register(perf_hsvc_group, ++ perf_hsvc_major, ++ &perf_hsvc_minor)) { ++ printk("perfmon: Could not register N2 hvapi.\n"); ++ return -ENODEV; ++ } ++ } ++ return 0; ++} ++ ++static void unregister_perf_hsvc(void) ++{ ++ if (tlb_type != hypervisor) ++ return; ++ sun4v_hvapi_unregister(perf_hsvc_group); ++} ++ ++static int oprofile_nmi_init(struct oprofile_operations *ops) ++{ ++ int err = register_perf_hsvc(); ++ ++ if (err) ++ return err; ++ ++ switch (tlb_type) { ++ case hypervisor: ++ pcr_ops = &n2_pcr_ops; ++ pcr_enable = PCR_N2_ENABLE; ++ break; ++ ++ case cheetah: ++ case cheetah_plus: ++ pcr_ops = &direct_pcr_ops; ++ break; ++ ++ default: + return -ENODEV; ++ } + +- ops->start = timer_start; +- ops->stop = timer_stop; ++ ops->create_files = NULL; ++ ops->setup = NULL; ++ ops->shutdown = NULL; ++ ops->start = nmi_start; ++ ops->stop = nmi_stop; + ops->cpu_type = "timer"; +- printk(KERN_INFO "oprofile: Using perfctr NMI timer interrupt.\n"); ++ ++ printk(KERN_INFO "oprofile: Using perfctr based NMI timer interrupt.\n"); ++ + return 0; + } + #endif +@@ -73,7 +233,7 @@ + int ret = -ENODEV; + + #ifdef CONFIG_SPARC64 +- ret = op_nmi_timer_init(ops); ++ ret = oprofile_nmi_init(ops); + if (!ret) + return ret; + #endif +@@ -81,6 +241,10 @@ + return ret; + } + ++ + void oprofile_arch_exit(void) + { ++#ifdef CONFIG_SPARC64 ++ unregister_perf_hsvc(); ++#endif + } +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/arch/um/drivers/vde_user.c linux-2.6.29-rc3.owrt/arch/um/drivers/vde_user.c +--- linux-2.6.29.owrt/arch/um/drivers/vde_user.c 2009-05-10 22:04:41.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/arch/um/drivers/vde_user.c 2009-05-10 23:48:28.000000000 +0200 +@@ -78,7 +78,7 @@ + { + struct vde_open_args *args; + +- vpri->args = uml_kmalloc(sizeof(struct vde_open_args), UM_GFP_KERNEL); ++ vpri->args = kmalloc(sizeof(struct vde_open_args), UM_GFP_KERNEL); + if (vpri->args == NULL) { + printk(UM_KERN_ERR "vde_init_libstuff - vde_open_args " + "allocation failed"); +@@ -91,8 +91,8 @@ + args->group = init->group; + args->mode = init->mode ? init->mode : 0700; + +- args->port ? printk("port %d", args->port) : +- printk("undefined port"); ++ args->port ? printk(UM_KERN_INFO "port %d", args->port) : ++ printk(UM_KERN_INFO "undefined port"); + } + + int vde_user_read(void *conn, void *buf, int len) +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/arch/um/kernel/ptrace.c linux-2.6.29-rc3.owrt/arch/um/kernel/ptrace.c +--- linux-2.6.29.owrt/arch/um/kernel/ptrace.c 2009-05-10 22:04:41.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/arch/um/kernel/ptrace.c 2009-05-10 23:48:28.000000000 +0200 +@@ -64,11 +64,6 @@ + ret = poke_user(child, addr, data); + break; + +- case PTRACE_SYSEMU: +- case PTRACE_SYSEMU_SINGLESTEP: +- ret = -EIO; +- break; +- + /* continue and stop at next (return from) syscall */ + case PTRACE_SYSCALL: + /* restart after signal. */ +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/arch/um/os-Linux/user_syms.c linux-2.6.29-rc3.owrt/arch/um/os-Linux/user_syms.c +--- linux-2.6.29.owrt/arch/um/os-Linux/user_syms.c 2009-05-10 22:04:41.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/arch/um/os-Linux/user_syms.c 2009-05-10 23:48:28.000000000 +0200 +@@ -14,6 +14,7 @@ + #undef memset + + extern size_t strlen(const char *); ++extern void *memcpy(void *, const void *, size_t); + extern void *memmove(void *, const void *, size_t); + extern void *memset(void *, int, size_t); + extern int printf(const char *, ...); +@@ -23,11 +24,7 @@ + EXPORT_SYMBOL(strstr); + #endif + +-#ifndef __x86_64__ +-extern void *memcpy(void *, const void *, size_t); + EXPORT_SYMBOL(memcpy); +-#endif +- + EXPORT_SYMBOL(memmove); + EXPORT_SYMBOL(memset); + EXPORT_SYMBOL(printf); +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/arch/x86/boot/video-vesa.c linux-2.6.29-rc3.owrt/arch/x86/boot/video-vesa.c +--- linux-2.6.29.owrt/arch/x86/boot/video-vesa.c 2009-05-10 22:04:41.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/arch/x86/boot/video-vesa.c 2009-05-10 23:48:28.000000000 +0200 +@@ -269,8 +269,9 @@ + we genuinely have to assume all registers are destroyed here. */ + + asm("pushw %%es; movw %2,%%es; "INT10"; popw %%es" +- : "+a" (ax), "+b" (bx), "+c" (cx), "+D" (di) +- : : "esi", "edx"); ++ : "+a" (ax), "+b" (bx) ++ : "c" (cx), "D" (di) ++ : "esi"); + + if (ax != 0x004f) + return; /* No EDID */ +@@ -284,9 +285,9 @@ + dx = 0; /* EDID block number */ + di =(size_t) &boot_params.edid_info; /* (ES:)Pointer to block */ + asm(INT10 +- : "+a" (ax), "+b" (bx), "+d" (dx), "=m" (boot_params.edid_info), +- "+c" (cx), "+D" (di) +- : : "esi"); ++ : "+a" (ax), "+b" (bx), "+d" (dx), "=m" (boot_params.edid_info) ++ : "c" (cx), "D" (di) ++ : "esi"); + #endif /* CONFIG_FIRMWARE_EDID */ + } + +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/arch/x86/ia32/ia32entry.S linux-2.6.29-rc3.owrt/arch/x86/ia32/ia32entry.S +--- linux-2.6.29.owrt/arch/x86/ia32/ia32entry.S 2009-05-10 22:04:41.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/arch/x86/ia32/ia32entry.S 2009-05-10 23:48:28.000000000 +0200 +@@ -418,9 +418,9 @@ + orl $TS_COMPAT,TI_status(%r10) + testl $_TIF_WORK_SYSCALL_ENTRY,TI_flags(%r10) + jnz ia32_tracesys ++ia32_do_syscall: + cmpl $(IA32_NR_syscalls-1),%eax +- ja ia32_badsys +-ia32_do_call: ++ ja int_ret_from_sys_call /* ia32_tracesys has set RAX(%rsp) */ + IA32_ARG_FIXUP + call *ia32_sys_call_table(,%rax,8) # xxx: rip relative + ia32_sysret: +@@ -435,9 +435,7 @@ + call syscall_trace_enter + LOAD_ARGS32 ARGOFFSET /* reload args from stack in case ptrace changed it */ + RESTORE_REST +- cmpl $(IA32_NR_syscalls-1),%eax +- ja int_ret_from_sys_call /* ia32_tracesys has set RAX(%rsp) */ +- jmp ia32_do_call ++ jmp ia32_do_syscall + END(ia32_syscall) + + ia32_badsys: +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/arch/x86/include/asm/a.out-core.h linux-2.6.29-rc3.owrt/arch/x86/include/asm/a.out-core.h +--- linux-2.6.29.owrt/arch/x86/include/asm/a.out-core.h 2009-05-10 22:04:41.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/arch/x86/include/asm/a.out-core.h 2009-05-10 23:48:28.000000000 +0200 +@@ -23,6 +23,8 @@ + */ + static inline void aout_dump_thread(struct pt_regs *regs, struct user *dump) + { ++ u16 gs; ++ + /* changed the size calculations - should hopefully work better. lbt */ + dump->magic = CMAGIC; + dump->start_code = 0; +@@ -55,7 +57,7 @@ + dump->regs.ds = (u16)regs->ds; + dump->regs.es = (u16)regs->es; + dump->regs.fs = (u16)regs->fs; +- savesegment(gs, dump->regs.gs); ++ savesegment(gs, gs); + dump->regs.orig_ax = regs->orig_ax; + dump->regs.ip = regs->ip; + dump->regs.cs = (u16)regs->cs; +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/arch/x86/include/asm/cpufeature.h linux-2.6.29-rc3.owrt/arch/x86/include/asm/cpufeature.h +--- linux-2.6.29.owrt/arch/x86/include/asm/cpufeature.h 2009-05-10 22:04:41.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/arch/x86/include/asm/cpufeature.h 2009-05-10 23:48:28.000000000 +0200 +@@ -93,7 +93,6 @@ + #define X86_FEATURE_XTOPOLOGY (3*32+22) /* cpu topology enum extensions */ + #define X86_FEATURE_TSC_RELIABLE (3*32+23) /* TSC is known to be reliable */ + #define X86_FEATURE_NONSTOP_TSC (3*32+24) /* TSC does not stop in C states */ +-#define X86_FEATURE_CLFLUSH_MONITOR (3*32+25) /* "" clflush reqd with monitor */ + + /* Intel-defined CPU features, CPUID level 0x00000001 (ecx), word 4 */ + #define X86_FEATURE_XMM3 (4*32+ 0) /* "pni" SSE-3 */ +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/arch/x86/include/asm/dma-mapping.h linux-2.6.29-rc3.owrt/arch/x86/include/asm/dma-mapping.h +--- linux-2.6.29.owrt/arch/x86/include/asm/dma-mapping.h 2009-05-10 22:04:41.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/arch/x86/include/asm/dma-mapping.h 2009-05-10 23:48:28.000000000 +0200 +@@ -2,8 +2,8 @@ + #define _ASM_X86_DMA_MAPPING_H + + /* +- * IOMMU interface. See Documentation/PCI/PCI-DMA-mapping.txt and +- * Documentation/DMA-API.txt for documentation. ++ * IOMMU interface. See Documentation/DMA-mapping.txt and DMA-API.txt for ++ * documentation. + */ + + #include <linux/scatterlist.h> +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/arch/x86/include/asm/e820.h linux-2.6.29-rc3.owrt/arch/x86/include/asm/e820.h +--- linux-2.6.29.owrt/arch/x86/include/asm/e820.h 2009-05-10 22:04:41.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/arch/x86/include/asm/e820.h 2009-05-10 23:48:28.000000000 +0200 +@@ -49,7 +49,6 @@ + #define E820_RESERVED_KERN 128 + + #ifndef __ASSEMBLY__ +-#include <linux/types.h> + struct e820entry { + __u64 addr; /* start of memory segment */ + __u64 size; /* size of memory segment */ +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/arch/x86/include/asm/efi.h linux-2.6.29-rc3.owrt/arch/x86/include/asm/efi.h +--- linux-2.6.29.owrt/arch/x86/include/asm/efi.h 2009-05-10 22:04:41.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/arch/x86/include/asm/efi.h 2009-05-10 23:48:28.000000000 +0200 +@@ -37,6 +37,8 @@ + + #else /* !CONFIG_X86_32 */ + ++#define MAX_EFI_IO_PAGES 100 ++ + extern u64 efi_call0(void *fp); + extern u64 efi_call1(void *fp, u64 arg1); + extern u64 efi_call2(void *fp, u64 arg1, u64 arg2); +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/arch/x86/include/asm/fixmap_64.h linux-2.6.29-rc3.owrt/arch/x86/include/asm/fixmap_64.h +--- linux-2.6.29.owrt/arch/x86/include/asm/fixmap_64.h 2009-05-10 22:04:41.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/arch/x86/include/asm/fixmap_64.h 2009-05-10 23:48:28.000000000 +0200 +@@ -16,6 +16,7 @@ + #include <asm/apicdef.h> + #include <asm/page.h> + #include <asm/vsyscall.h> ++#include <asm/efi.h> + + /* + * Here we define all the compile-time 'special' virtual +@@ -42,6 +43,9 @@ + FIX_APIC_BASE, /* local (CPU) APIC) -- required for SMP or not */ + FIX_IO_APIC_BASE_0, + FIX_IO_APIC_BASE_END = FIX_IO_APIC_BASE_0 + MAX_IO_APICS - 1, ++ FIX_EFI_IO_MAP_LAST_PAGE, ++ FIX_EFI_IO_MAP_FIRST_PAGE = FIX_EFI_IO_MAP_LAST_PAGE ++ + MAX_EFI_IO_PAGES - 1, + #ifdef CONFIG_PARAVIRT + FIX_PARAVIRT_BOOTMAP, + #endif +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/arch/x86/include/asm/i387.h linux-2.6.29-rc3.owrt/arch/x86/include/asm/i387.h +--- linux-2.6.29.owrt/arch/x86/include/asm/i387.h 2009-05-10 22:04:41.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/arch/x86/include/asm/i387.h 2009-05-10 23:48:28.000000000 +0200 +@@ -172,13 +172,7 @@ + + #else /* CONFIG_X86_32 */ + +-#ifdef CONFIG_MATH_EMULATION +-extern void finit_task(struct task_struct *tsk); +-#else +-static inline void finit_task(struct task_struct *tsk) +-{ +-} +-#endif ++extern void finit(void); + + static inline void tolerant_fwait(void) + { +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/arch/x86/include/asm/iomap.h linux-2.6.29-rc3.owrt/arch/x86/include/asm/iomap.h +--- linux-2.6.29.owrt/arch/x86/include/asm/iomap.h 2009-05-10 22:04:41.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/arch/x86/include/asm/iomap.h 2009-05-10 23:48:28.000000000 +0200 +@@ -23,9 +23,6 @@ + #include <asm/pgtable.h> + #include <asm/tlbflush.h> + +-int +-is_io_mapping_possible(resource_size_t base, unsigned long size); +- + void * + iomap_atomic_prot_pfn(unsigned long pfn, enum km_type type, pgprot_t prot); + +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/arch/x86/include/asm/kvm.h linux-2.6.29-rc3.owrt/arch/x86/include/asm/kvm.h +--- linux-2.6.29.owrt/arch/x86/include/asm/kvm.h 2009-05-10 22:04:41.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/arch/x86/include/asm/kvm.h 2009-05-10 23:48:28.000000000 +0200 +@@ -6,16 +6,9 @@ + * + */ + +-#include <linux/types.h> ++#include <asm/types.h> + #include <linux/ioctl.h> + +-/* Select x86 specific features in <linux/kvm.h> */ +-#define __KVM_HAVE_PIT +-#define __KVM_HAVE_IOAPIC +-#define __KVM_HAVE_DEVICE_ASSIGNMENT +-#define __KVM_HAVE_MSI +-#define __KVM_HAVE_USER_NMI +- + /* Architectural interrupt line count. */ + #define KVM_NR_INTERRUPTS 256 + +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/arch/x86/include/asm/math_emu.h linux-2.6.29-rc3.owrt/arch/x86/include/asm/math_emu.h +--- linux-2.6.29.owrt/arch/x86/include/asm/math_emu.h 2009-05-10 22:04:41.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/arch/x86/include/asm/math_emu.h 2009-05-10 23:48:28.000000000 +0200 +@@ -1,18 +1,31 @@ + #ifndef _ASM_X86_MATH_EMU_H + #define _ASM_X86_MATH_EMU_H + +-#include <asm/ptrace.h> +-#include <asm/vm86.h> +- + /* This structure matches the layout of the data saved to the stack + following a device-not-present interrupt, part of it saved + automatically by the 80386/80486. + */ +-struct math_emu_info { ++struct info { + long ___orig_eip; +- union { +- struct pt_regs *regs; +- struct kernel_vm86_regs *vm86; +- }; ++ long ___ebx; ++ long ___ecx; ++ long ___edx; ++ long ___esi; ++ long ___edi; ++ long ___ebp; ++ long ___eax; ++ long ___ds; ++ long ___es; ++ long ___fs; ++ long ___orig_eax; ++ long ___eip; ++ long ___cs; ++ long ___eflags; ++ long ___esp; ++ long ___ss; ++ long ___vm86_es; /* This and the following only in vm86 mode */ ++ long ___vm86_ds; ++ long ___vm86_fs; ++ long ___vm86_gs; + }; + #endif /* _ASM_X86_MATH_EMU_H */ +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/arch/x86/include/asm/mce.h linux-2.6.29-rc3.owrt/arch/x86/include/asm/mce.h +--- linux-2.6.29.owrt/arch/x86/include/asm/mce.h 2009-05-10 22:04:41.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/arch/x86/include/asm/mce.h 2009-05-10 23:48:28.000000000 +0200 +@@ -3,8 +3,8 @@ + + #ifdef __x86_64__ + +-#include <linux/types.h> + #include <asm/ioctls.h> ++#include <asm/types.h> + + /* + * Machine Check support for x86 +@@ -115,6 +115,8 @@ + + #endif /* !CONFIG_X86_32 */ + ++ ++ + #ifdef CONFIG_X86_MCE + extern void mcheck_init(struct cpuinfo_x86 *c); + #else +@@ -124,4 +126,5 @@ + extern void restart_mce(void); + + #endif /* __KERNEL__ */ ++ + #endif /* _ASM_X86_MCE_H */ +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/arch/x86/include/asm/mmzone_32.h linux-2.6.29-rc3.owrt/arch/x86/include/asm/mmzone_32.h +--- linux-2.6.29.owrt/arch/x86/include/asm/mmzone_32.h 2009-05-10 22:04:41.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/arch/x86/include/asm/mmzone_32.h 2009-05-10 23:48:28.000000000 +0200 +@@ -32,6 +32,8 @@ + get_memcfg_numa_flat(); + } + ++extern int early_pfn_to_nid(unsigned long pfn); ++ + extern void resume_map_numa_kva(pgd_t *pgd); + + #else /* !CONFIG_NUMA */ +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/arch/x86/include/asm/mmzone_64.h linux-2.6.29-rc3.owrt/arch/x86/include/asm/mmzone_64.h +--- linux-2.6.29.owrt/arch/x86/include/asm/mmzone_64.h 2009-05-10 22:04:41.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/arch/x86/include/asm/mmzone_64.h 2009-05-10 23:48:28.000000000 +0200 +@@ -40,6 +40,8 @@ + #define node_end_pfn(nid) (NODE_DATA(nid)->node_start_pfn + \ + NODE_DATA(nid)->node_spanned_pages) + ++extern int early_pfn_to_nid(unsigned long pfn); ++ + #ifdef CONFIG_NUMA_EMU + #define FAKE_NODE_MIN_SIZE (64 * 1024 * 1024) + #define FAKE_NODE_MIN_HASH_MASK (~(FAKE_NODE_MIN_SIZE - 1UL)) +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/arch/x86/include/asm/mpspec.h linux-2.6.29-rc3.owrt/arch/x86/include/asm/mpspec.h +--- linux-2.6.29.owrt/arch/x86/include/asm/mpspec.h 2009-05-10 22:04:41.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/arch/x86/include/asm/mpspec.h 2009-05-10 23:48:28.000000000 +0200 +@@ -60,7 +60,6 @@ + u32 gsi); + extern void mp_config_acpi_legacy_irqs(void); + extern int mp_register_gsi(u32 gsi, int edge_level, int active_high_low); +-extern int acpi_probe_gsi(void); + #ifdef CONFIG_X86_IO_APIC + extern int mp_config_acpi_gsi(unsigned char number, unsigned int devfn, u8 pin, + u32 gsi, int triggering, int polarity); +@@ -72,11 +71,6 @@ + return 0; + } + #endif +-#else /* !CONFIG_ACPI: */ +-static inline int acpi_probe_gsi(void) +-{ +- return 0; +-} + #endif /* CONFIG_ACPI */ + + #define PHYSID_ARRAY_SIZE BITS_TO_LONGS(MAX_APICS) +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/arch/x86/include/asm/mtrr.h linux-2.6.29-rc3.owrt/arch/x86/include/asm/mtrr.h +--- linux-2.6.29.owrt/arch/x86/include/asm/mtrr.h 2009-05-10 22:04:41.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/arch/x86/include/asm/mtrr.h 2009-05-10 23:48:28.000000000 +0200 +@@ -23,7 +23,6 @@ + #ifndef _ASM_X86_MTRR_H + #define _ASM_X86_MTRR_H + +-#include <linux/types.h> + #include <linux/ioctl.h> + #include <linux/errno.h> + +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/arch/x86/include/asm/page.h linux-2.6.29-rc3.owrt/arch/x86/include/asm/page.h +--- linux-2.6.29.owrt/arch/x86/include/asm/page.h 2009-05-10 22:04:41.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/arch/x86/include/asm/page.h 2009-05-10 23:48:28.000000000 +0200 +@@ -57,6 +57,7 @@ + typedef struct { pgprotval_t pgprot; } pgprot_t; + + extern int page_is_ram(unsigned long pagenr); ++extern int pagerange_is_ram(unsigned long start, unsigned long end); + extern int devmem_is_allowed(unsigned long pagenr); + extern void map_devmem(unsigned long pfn, unsigned long size, + pgprot_t vma_prot); +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/arch/x86/include/asm/paravirt.h linux-2.6.29-rc3.owrt/arch/x86/include/asm/paravirt.h +--- linux-2.6.29.owrt/arch/x86/include/asm/paravirt.h 2009-05-10 22:04:41.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/arch/x86/include/asm/paravirt.h 2009-05-10 23:48:28.000000000 +0200 +@@ -1352,7 +1352,14 @@ + PVOP_VCALL0(pv_cpu_ops.lazy_mode.leave); + } + +-void arch_flush_lazy_cpu_mode(void); ++static inline void arch_flush_lazy_cpu_mode(void) ++{ ++ if (unlikely(paravirt_get_lazy_mode() == PARAVIRT_LAZY_CPU)) { ++ arch_leave_lazy_cpu_mode(); ++ arch_enter_lazy_cpu_mode(); ++ } ++} ++ + + #define __HAVE_ARCH_ENTER_LAZY_MMU_MODE + static inline void arch_enter_lazy_mmu_mode(void) +@@ -1365,7 +1372,13 @@ + PVOP_VCALL0(pv_mmu_ops.lazy_mode.leave); + } + +-void arch_flush_lazy_mmu_mode(void); ++static inline void arch_flush_lazy_mmu_mode(void) ++{ ++ if (unlikely(paravirt_get_lazy_mode() == PARAVIRT_LAZY_MMU)) { ++ arch_leave_lazy_mmu_mode(); ++ arch_enter_lazy_mmu_mode(); ++ } ++} + + static inline void __set_fixmap(unsigned /* enum fixed_addresses */ idx, + unsigned long phys, pgprot_t flags) +@@ -1389,7 +1402,6 @@ + { + return PVOP_CALL1(int, pv_lock_ops.spin_is_contended, lock); + } +-#define __raw_spin_is_contended __raw_spin_is_contended + + static __always_inline void __raw_spin_lock(struct raw_spinlock *lock) + { +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/arch/x86/include/asm/pgtable.h linux-2.6.29-rc3.owrt/arch/x86/include/asm/pgtable.h +--- linux-2.6.29.owrt/arch/x86/include/asm/pgtable.h 2009-05-10 22:04:41.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/arch/x86/include/asm/pgtable.h 2009-05-10 23:48:28.000000000 +0200 +@@ -302,30 +302,16 @@ + + extern pteval_t __supported_pte_mask; + +-/* +- * Mask out unsupported bits in a present pgprot. Non-present pgprots +- * can use those bits for other purposes, so leave them be. +- */ +-static inline pgprotval_t massage_pgprot(pgprot_t pgprot) +-{ +- pgprotval_t protval = pgprot_val(pgprot); +- +- if (protval & _PAGE_PRESENT) +- protval &= __supported_pte_mask; +- +- return protval; +-} +- + static inline pte_t pfn_pte(unsigned long page_nr, pgprot_t pgprot) + { +- return __pte(((phys_addr_t)page_nr << PAGE_SHIFT) | +- massage_pgprot(pgprot)); ++ return __pte((((phys_addr_t)page_nr << PAGE_SHIFT) | ++ pgprot_val(pgprot)) & __supported_pte_mask); + } + + static inline pmd_t pfn_pmd(unsigned long page_nr, pgprot_t pgprot) + { +- return __pmd(((phys_addr_t)page_nr << PAGE_SHIFT) | +- massage_pgprot(pgprot)); ++ return __pmd((((phys_addr_t)page_nr << PAGE_SHIFT) | ++ pgprot_val(pgprot)) & __supported_pte_mask); + } + + static inline pte_t pte_modify(pte_t pte, pgprot_t newprot) +@@ -337,7 +323,7 @@ + * the newprot (if present): + */ + val &= _PAGE_CHG_MASK; +- val |= massage_pgprot(newprot) & ~_PAGE_CHG_MASK; ++ val |= pgprot_val(newprot) & (~_PAGE_CHG_MASK) & __supported_pte_mask; + + return __pte(val); + } +@@ -353,7 +339,7 @@ + + #define pte_pgprot(x) __pgprot(pte_flags(x) & PTE_FLAGS_MASK) + +-#define canon_pgprot(p) __pgprot(massage_pgprot(p)) ++#define canon_pgprot(p) __pgprot(pgprot_val(p) & __supported_pte_mask) + + static inline int is_new_memtype_allowed(unsigned long flags, + unsigned long new_flags) +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/arch/x86/include/asm/processor.h linux-2.6.29-rc3.owrt/arch/x86/include/asm/processor.h +--- linux-2.6.29.owrt/arch/x86/include/asm/processor.h 2009-05-10 22:04:41.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/arch/x86/include/asm/processor.h 2009-05-10 23:48:28.000000000 +0200 +@@ -353,7 +353,7 @@ + u8 no_update; + u8 rm; + u8 alimit; +- struct math_emu_info *info; ++ struct info *info; + u32 entry_eip; + }; + +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/arch/x86/include/asm/ptrace-abi.h linux-2.6.29-rc3.owrt/arch/x86/include/asm/ptrace-abi.h +--- linux-2.6.29.owrt/arch/x86/include/asm/ptrace-abi.h 2009-05-10 22:04:41.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/arch/x86/include/asm/ptrace-abi.h 2009-05-10 23:48:28.000000000 +0200 +@@ -83,7 +83,7 @@ + #ifdef CONFIG_X86_PTRACE_BTS + + #ifndef __ASSEMBLY__ +-#include <linux/types.h> ++#include <asm/types.h> + + /* configuration/status structure used in PTRACE_BTS_CONFIG and + PTRACE_BTS_STATUS commands. +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/arch/x86/include/asm/seccomp_32.h linux-2.6.29-rc3.owrt/arch/x86/include/asm/seccomp_32.h +--- linux-2.6.29.owrt/arch/x86/include/asm/seccomp_32.h 2009-05-10 22:04:41.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/arch/x86/include/asm/seccomp_32.h 2009-05-10 23:48:28.000000000 +0200 +@@ -1,6 +1,12 @@ + #ifndef _ASM_X86_SECCOMP_32_H + #define _ASM_X86_SECCOMP_32_H + ++#include <linux/thread_info.h> ++ ++#ifdef TIF_32BIT ++#error "unexpected TIF_32BIT on i386" ++#endif ++ + #include <linux/unistd.h> + + #define __NR_seccomp_read __NR_read +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/arch/x86/include/asm/seccomp_64.h linux-2.6.29-rc3.owrt/arch/x86/include/asm/seccomp_64.h +--- linux-2.6.29.owrt/arch/x86/include/asm/seccomp_64.h 2009-05-10 22:04:41.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/arch/x86/include/asm/seccomp_64.h 2009-05-10 23:48:28.000000000 +0200 +@@ -1,6 +1,14 @@ + #ifndef _ASM_X86_SECCOMP_64_H + #define _ASM_X86_SECCOMP_64_H + ++#include <linux/thread_info.h> ++ ++#ifdef TIF_32BIT ++#error "unexpected TIF_32BIT on x86_64" ++#else ++#define TIF_32BIT TIF_IA32 ++#endif ++ + #include <linux/unistd.h> + #include <asm/ia32_unistd.h> + +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/arch/x86/include/asm/sigcontext32.h linux-2.6.29-rc3.owrt/arch/x86/include/asm/sigcontext32.h +--- linux-2.6.29.owrt/arch/x86/include/asm/sigcontext32.h 2009-05-10 22:04:41.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/arch/x86/include/asm/sigcontext32.h 2009-05-10 23:48:28.000000000 +0200 +@@ -1,8 +1,6 @@ + #ifndef _ASM_X86_SIGCONTEXT32_H + #define _ASM_X86_SIGCONTEXT32_H + +-#include <linux/types.h> +- + /* signal context for 32bit programs. */ + + #define X86_FXSR_MAGIC 0x0000 +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/arch/x86/include/asm/sigcontext.h linux-2.6.29-rc3.owrt/arch/x86/include/asm/sigcontext.h +--- linux-2.6.29.owrt/arch/x86/include/asm/sigcontext.h 2009-05-10 22:04:41.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/arch/x86/include/asm/sigcontext.h 2009-05-10 23:48:28.000000000 +0200 +@@ -2,7 +2,7 @@ + #define _ASM_X86_SIGCONTEXT_H + + #include <linux/compiler.h> +-#include <linux/types.h> ++#include <asm/types.h> + + #define FP_XSTATE_MAGIC1 0x46505853U + #define FP_XSTATE_MAGIC2 0x46505845U +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/arch/x86/include/asm/spinlock.h linux-2.6.29-rc3.owrt/arch/x86/include/asm/spinlock.h +--- linux-2.6.29.owrt/arch/x86/include/asm/spinlock.h 2009-05-10 22:04:41.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/arch/x86/include/asm/spinlock.h 2009-05-10 23:48:28.000000000 +0200 +@@ -245,7 +245,6 @@ + { + return __ticket_spin_is_contended(lock); + } +-#define __raw_spin_is_contended __raw_spin_is_contended + + static __always_inline void __raw_spin_lock(raw_spinlock_t *lock) + { +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/arch/x86/include/asm/swab.h linux-2.6.29-rc3.owrt/arch/x86/include/asm/swab.h +--- linux-2.6.29.owrt/arch/x86/include/asm/swab.h 2009-05-10 22:04:41.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/arch/x86/include/asm/swab.h 2009-05-10 23:48:28.000000000 +0200 +@@ -1,7 +1,7 @@ + #ifndef _ASM_X86_SWAB_H + #define _ASM_X86_SWAB_H + +-#include <linux/types.h> ++#include <asm/types.h> + #include <linux/compiler.h> + + static inline __attribute_const__ __u32 __arch_swab32(__u32 val) +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/arch/x86/include/asm/traps.h linux-2.6.29-rc3.owrt/arch/x86/include/asm/traps.h +--- linux-2.6.29.owrt/arch/x86/include/asm/traps.h 2009-05-10 22:04:41.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/arch/x86/include/asm/traps.h 2009-05-10 23:48:28.000000000 +0200 +@@ -41,7 +41,7 @@ + dotraplinkage void do_overflow(struct pt_regs *, long); + dotraplinkage void do_bounds(struct pt_regs *, long); + dotraplinkage void do_invalid_op(struct pt_regs *, long); +-dotraplinkage void do_device_not_available(struct pt_regs); ++dotraplinkage void do_device_not_available(struct pt_regs *, long); + dotraplinkage void do_coprocessor_segment_overrun(struct pt_regs *, long); + dotraplinkage void do_invalid_TSS(struct pt_regs *, long); + dotraplinkage void do_segment_not_present(struct pt_regs *, long); +@@ -77,7 +77,7 @@ + extern int kstack_depth_to_print; + + void math_error(void __user *); +-void math_emulate(struct math_emu_info *); ++asmlinkage void math_emulate(long); + #ifdef CONFIG_X86_32 + unsigned long patch_espfix_desc(unsigned long, unsigned long); + #else +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/arch/x86/include/asm/xen/page.h linux-2.6.29-rc3.owrt/arch/x86/include/asm/xen/page.h +--- linux-2.6.29.owrt/arch/x86/include/asm/xen/page.h 2009-05-10 22:04:41.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/arch/x86/include/asm/xen/page.h 2009-05-10 23:48:28.000000000 +0200 +@@ -137,7 +137,7 @@ + pte_t pte; + + pte.pte = ((phys_addr_t)page_nr << PAGE_SHIFT) | +- massage_pgprot(pgprot); ++ (pgprot_val(pgprot) & __supported_pte_mask); + + return pte; + } +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/arch/x86/Kconfig linux-2.6.29-rc3.owrt/arch/x86/Kconfig +--- linux-2.6.29.owrt/arch/x86/Kconfig 2009-05-10 22:04:41.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/arch/x86/Kconfig 2009-05-10 23:48:28.000000000 +0200 +@@ -1802,17 +1802,6 @@ + and include PCI device scope covered by these DMA + remapping devices. + +-config DMAR_DEFAULT_ON +- def_bool y +- prompt "Enable DMA Remapping Devices by default" +- depends on DMAR +- help +- Selecting this option will enable a DMAR device at boot time if +- one is found. If this option is not selected, DMAR support can +- be enabled by passing intel_iommu=on to the kernel. It is +- recommended you say N here while the DMAR code remains +- experimental. +- + config DMAR_GFX_WA + def_bool y + prompt "Support for Graphics workaround" +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/arch/x86/Kconfig.cpu linux-2.6.29-rc3.owrt/arch/x86/Kconfig.cpu +--- linux-2.6.29.owrt/arch/x86/Kconfig.cpu 2009-05-10 22:04:41.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/arch/x86/Kconfig.cpu 2009-05-10 23:48:28.000000000 +0200 +@@ -167,9 +167,9 @@ + config MK8 + bool "Opteron/Athlon64/Hammer/K8" + help +- Select this for an AMD Opteron or Athlon64 Hammer-family processor. +- Enables use of some extended instructions, and passes appropriate +- optimization flags to GCC. ++ Select this for an AMD Opteron or Athlon64 Hammer-family processor. Enables ++ use of some extended instructions, and passes appropriate optimization ++ flags to GCC. + + config MCRUSOE + bool "Crusoe" +@@ -256,11 +256,9 @@ + config MCORE2 + bool "Core 2/newer Xeon" + help +- +- Select this for Intel Core 2 and newer Core 2 Xeons (Xeon 51xx and +- 53xx) CPUs. You can distinguish newer from older Xeons by the CPU +- family in /proc/cpuinfo. Newer ones have 6 and older ones 15 +- (not a typo) ++ Select this for Intel Core 2 and newer Core 2 Xeons (Xeon 51xx and 53xx) ++ CPUs. You can distinguish newer from older Xeons by the CPU family ++ in /proc/cpuinfo. Newer ones have 6 and older ones 15 (not a typo) + + config GENERIC_CPU + bool "Generic-x86-64" +@@ -322,14 +320,14 @@ + bool "PentiumPro memory ordering errata workaround" + depends on M686 || M586MMX || M586TSC || M586 || M486 || M386 || MGEODEGX1 + help +- Old PentiumPro multiprocessor systems had errata that could cause +- memory operations to violate the x86 ordering standard in rare cases. +- Enabling this option will attempt to work around some (but not all) +- occurances of this problem, at the cost of much heavier spinlock and +- memory barrier operations. ++ Old PentiumPro multiprocessor systems had errata that could cause memory ++ operations to violate the x86 ordering standard in rare cases. Enabling this ++ option will attempt to work around some (but not all) occurances of ++ this problem, at the cost of much heavier spinlock and memory barrier ++ operations. + +- If unsure, say n here. Even distro kernels should think twice before +- enabling this: there are few systems, and an unlikely bug. ++ If unsure, say n here. Even distro kernels should think twice before enabling ++ this: there are few systems, and an unlikely bug. + + config X86_F00F_BUG + def_bool y +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/arch/x86/Kconfig.debug linux-2.6.29-rc3.owrt/arch/x86/Kconfig.debug +--- linux-2.6.29.owrt/arch/x86/Kconfig.debug 2009-05-10 22:04:41.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/arch/x86/Kconfig.debug 2009-05-10 23:48:28.000000000 +0200 +@@ -174,8 +174,28 @@ + Add a simple leak tracer to the IOMMU code. This is useful when you + are debugging a buggy device driver that leaks IOMMU mappings. + +-config HAVE_MMIOTRACE_SUPPORT +- def_bool y ++config MMIOTRACE ++ bool "Memory mapped IO tracing" ++ depends on DEBUG_KERNEL && PCI ++ select TRACING ++ help ++ Mmiotrace traces Memory Mapped I/O access and is meant for ++ debugging and reverse engineering. It is called from the ioremap ++ implementation and works via page faults. Tracing is disabled by ++ default and can be enabled at run-time. ++ ++ See Documentation/tracers/mmiotrace.txt. ++ If you are not helping to develop drivers, say N. ++ ++config MMIOTRACE_TEST ++ tristate "Test module for mmiotrace" ++ depends on MMIOTRACE && m ++ help ++ This is a dumb module for testing mmiotrace. It is very dangerous ++ as it will write garbage to IO memory starting at a given address. ++ However, it should be safe to use on e.g. unused portion of VRAM. ++ ++ Say N, unless you absolutely know what you are doing. + + # + # IO delay types: +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/arch/x86/kernel/acpi/boot.c linux-2.6.29-rc3.owrt/arch/x86/kernel/acpi/boot.c +--- linux-2.6.29.owrt/arch/x86/kernel/acpi/boot.c 2009-05-10 22:04:41.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/arch/x86/kernel/acpi/boot.c 2009-05-10 23:48:28.000000000 +0200 +@@ -973,29 +973,6 @@ + nr_ioapics++; + } + +-int __init acpi_probe_gsi(void) +-{ +- int idx; +- int gsi; +- int max_gsi = 0; +- +- if (acpi_disabled) +- return 0; +- +- if (!acpi_ioapic) +- return 0; +- +- max_gsi = 0; +- for (idx = 0; idx < nr_ioapics; idx++) { +- gsi = mp_ioapic_routing[idx].gsi_end; +- +- if (gsi > max_gsi) +- max_gsi = gsi; +- } +- +- return max_gsi + 1; +-} +- + static void assign_to_mp_irq(struct mp_config_intsrc *m, + struct mp_config_intsrc *mp_irq) + { +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/arch/x86/kernel/acpi/sleep.c linux-2.6.29-rc3.owrt/arch/x86/kernel/acpi/sleep.c +--- linux-2.6.29.owrt/arch/x86/kernel/acpi/sleep.c 2009-05-10 22:04:41.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/arch/x86/kernel/acpi/sleep.c 2009-05-10 23:48:28.000000000 +0200 +@@ -156,11 +156,11 @@ + #ifdef CONFIG_HIBERNATION + if (strncmp(str, "s4_nohwsig", 10) == 0) + acpi_no_s4_hw_signature(); +- if (strncmp(str, "s4_nonvs", 8) == 0) +- acpi_s4_no_nvs(); + #endif + if (strncmp(str, "old_ordering", 12) == 0) + acpi_old_suspend_ordering(); ++ if (strncmp(str, "s4_nonvs", 8) == 0) ++ acpi_s4_no_nvs(); + str = strchr(str, ','); + if (str != NULL) + str += strspn(str, ", \t"); +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/arch/x86/kernel/acpi/wakeup_64.S linux-2.6.29-rc3.owrt/arch/x86/kernel/acpi/wakeup_64.S +--- linux-2.6.29.owrt/arch/x86/kernel/acpi/wakeup_64.S 2009-05-10 22:04:41.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/arch/x86/kernel/acpi/wakeup_64.S 2009-05-10 23:48:28.000000000 +0200 +@@ -13,6 +13,7 @@ + * Hooray, we are in Long 64-bit mode (but still running in low memory) + */ + ENTRY(wakeup_long64) ++wakeup_long64: + movq saved_magic, %rax + movq $0x123456789abcdef0, %rdx + cmpq %rdx, %rax +@@ -33,12 +34,16 @@ + + movq saved_rip, %rax + jmp *%rax +-ENDPROC(wakeup_long64) + + bogus_64_magic: + jmp bogus_64_magic + +-ENTRY(do_suspend_lowlevel) ++ .align 2 ++ .p2align 4,,15 ++.globl do_suspend_lowlevel ++ .type do_suspend_lowlevel,@function ++do_suspend_lowlevel: ++.LFB5: + subq $8, %rsp + xorl %eax, %eax + call save_processor_state +@@ -62,7 +67,7 @@ + pushfq + popq pt_regs_flags(%rax) + +- movq $resume_point, saved_rip(%rip) ++ movq $.L97, saved_rip(%rip) + + movq %rsp, saved_rsp + movq %rbp, saved_rbp +@@ -73,12 +78,14 @@ + addq $8, %rsp + movl $3, %edi + xorl %eax, %eax +- call acpi_enter_sleep_state +- /* in case something went wrong, restore the machine status and go on */ +- jmp resume_point +- ++ jmp acpi_enter_sleep_state ++.L97: ++ .p2align 4,,7 ++.L99: + .align 4 +-resume_point: ++ movl $24, %eax ++ movw %ax, %ds ++ + /* We don't restore %rax, it must be 0 anyway */ + movq $saved_context, %rax + movq saved_context_cr4(%rax), %rbx +@@ -110,9 +117,12 @@ + xorl %eax, %eax + addq $8, %rsp + jmp restore_processor_state +-ENDPROC(do_suspend_lowlevel) +- ++.LFE5: ++.Lfe5: ++ .size do_suspend_lowlevel, .Lfe5-do_suspend_lowlevel ++ + .data ++ALIGN + ENTRY(saved_rbp) .quad 0 + ENTRY(saved_rsi) .quad 0 + ENTRY(saved_rdi) .quad 0 +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/arch/x86/kernel/apic.c linux-2.6.29-rc3.owrt/arch/x86/kernel/apic.c +--- linux-2.6.29.owrt/arch/x86/kernel/apic.c 2009-05-10 22:04:41.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/arch/x86/kernel/apic.c 2009-05-10 23:48:28.000000000 +0200 +@@ -862,7 +862,7 @@ + } + + /* lets not touch this if we didn't frob it */ +-#if defined(CONFIG_X86_MCE_P4THERMAL) || defined(CONFIG_X86_MCE_INTEL) ++#if defined(CONFIG_X86_MCE_P4THERMAL) || defined(X86_MCE_INTEL) + if (maxlvt >= 5) { + v = apic_read(APIC_LVTTHMR); + apic_write(APIC_LVTTHMR, v | APIC_LVT_MASKED); +@@ -1436,7 +1436,7 @@ + switch (boot_cpu_data.x86_vendor) { + case X86_VENDOR_AMD: + if ((boot_cpu_data.x86 == 6 && boot_cpu_data.x86_model > 1) || +- (boot_cpu_data.x86 >= 15)) ++ (boot_cpu_data.x86 == 15)) + break; + goto no_apic; + case X86_VENDOR_INTEL: +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/arch/x86/kernel/apm_32.c linux-2.6.29-rc3.owrt/arch/x86/kernel/apm_32.c +--- linux-2.6.29.owrt/arch/x86/kernel/apm_32.c 2009-05-10 22:04:41.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/arch/x86/kernel/apm_32.c 2009-05-10 23:48:28.000000000 +0200 +@@ -1192,7 +1192,6 @@ + device_suspend(PMSG_SUSPEND); + local_irq_disable(); + device_power_down(PMSG_SUSPEND); +- sysdev_suspend(PMSG_SUSPEND); + + local_irq_enable(); + +@@ -1209,7 +1208,6 @@ + if (err != APM_SUCCESS) + apm_error("suspend", err); + err = (err == APM_SUCCESS) ? 0 : -EIO; +- sysdev_resume(); + device_power_up(PMSG_RESUME); + local_irq_enable(); + device_resume(PMSG_RESUME); +@@ -1230,7 +1228,6 @@ + + local_irq_disable(); + device_power_down(PMSG_SUSPEND); +- sysdev_suspend(PMSG_SUSPEND); + local_irq_enable(); + + err = set_system_power_state(APM_STATE_STANDBY); +@@ -1238,7 +1235,6 @@ + apm_error("standby", err); + + local_irq_disable(); +- sysdev_resume(); + device_power_up(PMSG_RESUME); + local_irq_enable(); + } +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/arch/x86/kernel/cpu/cpufreq/Kconfig linux-2.6.29-rc3.owrt/arch/x86/kernel/cpu/cpufreq/Kconfig +--- linux-2.6.29.owrt/arch/x86/kernel/cpu/cpufreq/Kconfig 2009-05-10 22:04:41.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/arch/x86/kernel/cpu/cpufreq/Kconfig 2009-05-10 23:48:28.000000000 +0200 +@@ -245,6 +245,17 @@ + + comment "shared options" + ++config X86_ACPI_CPUFREQ_PROC_INTF ++ bool "/proc/acpi/processor/../performance interface (deprecated)" ++ depends on PROC_FS ++ depends on X86_ACPI_CPUFREQ || X86_POWERNOW_K7_ACPI || X86_POWERNOW_K8_ACPI ++ help ++ This enables the deprecated /proc/acpi/processor/../performance ++ interface. While it is helpful for debugging, the generic, ++ cross-architecture cpufreq interfaces should be used. ++ ++ If in doubt, say N. ++ + config X86_SPEEDSTEP_LIB + tristate + default (X86_SPEEDSTEP_ICH || X86_SPEEDSTEP_SMI || X86_P4_CLOCKMOD) +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/arch/x86/kernel/cpu/cpufreq/p4-clockmod.c linux-2.6.29-rc3.owrt/arch/x86/kernel/cpu/cpufreq/p4-clockmod.c +--- linux-2.6.29.owrt/arch/x86/kernel/cpu/cpufreq/p4-clockmod.c 2009-05-10 22:04:41.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/arch/x86/kernel/cpu/cpufreq/p4-clockmod.c 2009-05-10 23:48:28.000000000 +0200 +@@ -277,6 +277,7 @@ + .name = "p4-clockmod", + .owner = THIS_MODULE, + .attr = p4clockmod_attr, ++ .hide_interface = 1, + }; + + +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/arch/x86/kernel/cpu/cpufreq/powernow-k8.c linux-2.6.29-rc3.owrt/arch/x86/kernel/cpu/cpufreq/powernow-k8.c +--- linux-2.6.29.owrt/arch/x86/kernel/cpu/cpufreq/powernow-k8.c 2009-05-10 22:04:41.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/arch/x86/kernel/cpu/cpufreq/powernow-k8.c 2009-05-10 23:48:28.000000000 +0200 +@@ -939,25 +939,10 @@ + free_cpumask_var(data->acpi_data.shared_cpu_map); + } + +-static int get_transition_latency(struct powernow_k8_data *data) +-{ +- int max_latency = 0; +- int i; +- for (i = 0; i < data->acpi_data.state_count; i++) { +- int cur_latency = data->acpi_data.states[i].transition_latency +- + data->acpi_data.states[i].bus_master_latency; +- if (cur_latency > max_latency) +- max_latency = cur_latency; +- } +- /* value in usecs, needs to be in nanoseconds */ +- return 1000 * max_latency; +-} +- + #else + static int powernow_k8_cpu_init_acpi(struct powernow_k8_data *data) { return -ENODEV; } + static void powernow_k8_cpu_exit_acpi(struct powernow_k8_data *data) { return; } + static void powernow_k8_acpi_pst_values(struct powernow_k8_data *data, unsigned int index) { return; } +-static int get_transition_latency(struct powernow_k8_data *data) { return 0; } + #endif /* CONFIG_X86_POWERNOW_K8_ACPI */ + + /* Take a frequency, and issue the fid/vid transition command */ +@@ -1157,7 +1142,8 @@ + data->cpu = pol->cpu; + data->currpstate = HW_PSTATE_INVALID; + +- if (powernow_k8_cpu_init_acpi(data)) { ++ rc = powernow_k8_cpu_init_acpi(data); ++ if (rc) { + /* + * Use the PSB BIOS structure. This is only availabe on + * an UP version, and is deprecated by AMD. +@@ -1175,28 +1161,19 @@ + "ACPI maintainers and complain to your BIOS " + "vendor.\n"); + #endif +- kfree(data); +- return -ENODEV; ++ goto err_out; + } + if (pol->cpu != 0) { + printk(KERN_ERR FW_BUG PFX "No ACPI _PSS objects for " + "CPU other than CPU0. Complain to your BIOS " + "vendor.\n"); +- kfree(data); +- return -ENODEV; ++ goto err_out; + } + rc = find_psb_table(data); + if (rc) { +- kfree(data); +- return -ENODEV; ++ goto err_out; + } +- /* Take a crude guess here. +- * That guess was in microseconds, so multiply with 1000 */ +- pol->cpuinfo.transition_latency = ( +- ((data->rvo + 8) * data->vstable * VST_UNITS_20US) + +- ((1 << data->irt) * 30)) * 1000; +- } else /* ACPI _PSS objects available */ +- pol->cpuinfo.transition_latency = get_transition_latency(data); ++ } + + /* only run on specific CPU from here on */ + oldmask = current->cpus_allowed; +@@ -1227,6 +1204,11 @@ + cpumask_copy(pol->cpus, &per_cpu(cpu_core_map, pol->cpu)); + data->available_cores = pol->cpus; + ++ /* Take a crude guess here. ++ * That guess was in microseconds, so multiply with 1000 */ ++ pol->cpuinfo.transition_latency = (((data->rvo + 8) * data->vstable * VST_UNITS_20US) ++ + (3 * (1 << data->irt) * 10)) * 1000; ++ + if (cpu_family == CPU_HW_PSTATE) + pol->cur = find_khz_freq_from_pstate(data->powernow_table, data->currpstate); + else +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/arch/x86/kernel/cpu/intel.c linux-2.6.29-rc3.owrt/arch/x86/kernel/cpu/intel.c +--- linux-2.6.29.owrt/arch/x86/kernel/cpu/intel.c 2009-05-10 22:04:41.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/arch/x86/kernel/cpu/intel.c 2009-05-10 23:48:28.000000000 +0200 +@@ -30,7 +30,7 @@ + static void __cpuinit early_init_intel(struct cpuinfo_x86 *c) + { + /* Unmask CPUID levels if masked: */ +- if (c->x86 > 6 || (c->x86 == 6 && c->x86_model >= 0xd)) { ++ if (c->x86 == 6 && c->x86_model >= 15) { + u64 misc_enable; + + rdmsrl(MSR_IA32_MISC_ENABLE, misc_enable); +@@ -291,9 +291,6 @@ + ds_init_intel(c); + } + +- if (c->x86 == 6 && c->x86_model == 29 && cpu_has_clflush) +- set_cpu_cap(c, X86_FEATURE_CLFLUSH_MONITOR); +- + #ifdef CONFIG_X86_64 + if (c->x86 == 15) + c->x86_cache_alignment = c->x86_clflush_size * 2; +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/arch/x86/kernel/cpu/intel_cacheinfo.c linux-2.6.29-rc3.owrt/arch/x86/kernel/cpu/intel_cacheinfo.c +--- linux-2.6.29.owrt/arch/x86/kernel/cpu/intel_cacheinfo.c 2009-05-10 22:04:41.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/arch/x86/kernel/cpu/intel_cacheinfo.c 2009-05-10 23:48:28.000000000 +0200 +@@ -36,11 +36,8 @@ + { + { 0x06, LVL_1_INST, 8 }, /* 4-way set assoc, 32 byte line size */ + { 0x08, LVL_1_INST, 16 }, /* 4-way set assoc, 32 byte line size */ +- { 0x09, LVL_1_INST, 32 }, /* 4-way set assoc, 64 byte line size */ + { 0x0a, LVL_1_DATA, 8 }, /* 2 way set assoc, 32 byte line size */ + { 0x0c, LVL_1_DATA, 16 }, /* 4-way set assoc, 32 byte line size */ +- { 0x0d, LVL_1_DATA, 16 }, /* 4-way set assoc, 64 byte line size */ +- { 0x21, LVL_2, 256 }, /* 8-way set assoc, 64 byte line size */ + { 0x22, LVL_3, 512 }, /* 4-way set assoc, sectored cache, 64 byte line size */ + { 0x23, LVL_3, 1024 }, /* 8-way set assoc, sectored cache, 64 byte line size */ + { 0x25, LVL_3, 2048 }, /* 8-way set assoc, sectored cache, 64 byte line size */ +@@ -88,18 +85,6 @@ + { 0x85, LVL_2, 2048 }, /* 8-way set assoc, 32 byte line size */ + { 0x86, LVL_2, 512 }, /* 4-way set assoc, 64 byte line size */ + { 0x87, LVL_2, 1024 }, /* 8-way set assoc, 64 byte line size */ +- { 0xd0, LVL_3, 512 }, /* 4-way set assoc, 64 byte line size */ +- { 0xd1, LVL_3, 1024 }, /* 4-way set assoc, 64 byte line size */ +- { 0xd2, LVL_3, 2048 }, /* 4-way set assoc, 64 byte line size */ +- { 0xd6, LVL_3, 1024 }, /* 8-way set assoc, 64 byte line size */ +- { 0xd7, LVL_3, 2038 }, /* 8-way set assoc, 64 byte line size */ +- { 0xd8, LVL_3, 4096 }, /* 12-way set assoc, 64 byte line size */ +- { 0xdc, LVL_3, 2048 }, /* 12-way set assoc, 64 byte line size */ +- { 0xdd, LVL_3, 4096 }, /* 12-way set assoc, 64 byte line size */ +- { 0xde, LVL_3, 8192 }, /* 12-way set assoc, 64 byte line size */ +- { 0xe2, LVL_3, 2048 }, /* 16-way set assoc, 64 byte line size */ +- { 0xe3, LVL_3, 4096 }, /* 16-way set assoc, 64 byte line size */ +- { 0xe4, LVL_3, 8192 }, /* 16-way set assoc, 64 byte line size */ + { 0x00, 0, 0} + }; + +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/arch/x86/kernel/cpu/mcheck/mce_64.c linux-2.6.29-rc3.owrt/arch/x86/kernel/cpu/mcheck/mce_64.c +--- linux-2.6.29.owrt/arch/x86/kernel/cpu/mcheck/mce_64.c 2009-05-10 22:04:41.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/arch/x86/kernel/cpu/mcheck/mce_64.c 2009-05-10 23:48:28.000000000 +0200 +@@ -295,11 +295,11 @@ + * If we know that the error was in user space, send a + * SIGBUS. Otherwise, panic if tolerance is low. + * +- * force_sig() takes an awful lot of locks and has a slight ++ * do_exit() takes an awful lot of locks and has a slight + * risk of deadlocking. + */ + if (user_space) { +- force_sig(SIGBUS, current); ++ do_exit(SIGBUS); + } else if (panic_on_oops || tolerant < 2) { + mce_panic("Uncorrected machine check", + &panicm, mcestart); +@@ -490,7 +490,7 @@ + + } + +-static void mce_cpu_features(struct cpuinfo_x86 *c) ++static void __cpuinit mce_cpu_features(struct cpuinfo_x86 *c) + { + switch (c->x86_vendor) { + case X86_VENDOR_INTEL: +@@ -734,7 +734,6 @@ + static int mce_resume(struct sys_device *dev) + { + mce_init(NULL); +- mce_cpu_features(¤t_cpu_data); + return 0; + } + +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/arch/x86/kernel/cpu/mcheck/mce_amd_64.c linux-2.6.29-rc3.owrt/arch/x86/kernel/cpu/mcheck/mce_amd_64.c +--- linux-2.6.29.owrt/arch/x86/kernel/cpu/mcheck/mce_amd_64.c 2009-05-10 22:04:41.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/arch/x86/kernel/cpu/mcheck/mce_amd_64.c 2009-05-10 23:48:28.000000000 +0200 +@@ -121,7 +121,7 @@ + } + + /* cpu init entry point, called from mce.c with preempt off */ +-void mce_amd_feature_init(struct cpuinfo_x86 *c) ++void __cpuinit mce_amd_feature_init(struct cpuinfo_x86 *c) + { + unsigned int bank, block; + unsigned int cpu = smp_processor_id(); +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/arch/x86/kernel/cpu/mcheck/mce_intel_64.c linux-2.6.29-rc3.owrt/arch/x86/kernel/cpu/mcheck/mce_intel_64.c +--- linux-2.6.29.owrt/arch/x86/kernel/cpu/mcheck/mce_intel_64.c 2009-05-10 22:04:41.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/arch/x86/kernel/cpu/mcheck/mce_intel_64.c 2009-05-10 23:48:28.000000000 +0200 +@@ -30,7 +30,7 @@ + irq_exit(); + } + +-static void intel_init_thermal(struct cpuinfo_x86 *c) ++static void __cpuinit intel_init_thermal(struct cpuinfo_x86 *c) + { + u32 l, h; + int tm2 = 0; +@@ -84,7 +84,7 @@ + return; + } + +-void mce_intel_feature_init(struct cpuinfo_x86 *c) ++void __cpuinit mce_intel_feature_init(struct cpuinfo_x86 *c) + { + intel_init_thermal(c); + } +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/arch/x86/kernel/cpu/mtrr/main.c linux-2.6.29-rc3.owrt/arch/x86/kernel/cpu/mtrr/main.c +--- linux-2.6.29.owrt/arch/x86/kernel/cpu/mtrr/main.c 2009-05-10 22:04:41.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/arch/x86/kernel/cpu/mtrr/main.c 2009-05-10 23:48:28.000000000 +0200 +@@ -1594,7 +1594,8 @@ + + /* kvm/qemu doesn't have mtrr set right, don't trim them all */ + if (!highest_pfn) { +- printk(KERN_INFO "CPU MTRRs all blank - virtualized system.\n"); ++ WARN(!kvm_para_available(), KERN_WARNING ++ "WARNING: strange, CPU MTRRs all blank?\n"); + return 0; + } + +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/arch/x86/kernel/ds.c linux-2.6.29-rc3.owrt/arch/x86/kernel/ds.c +--- linux-2.6.29.owrt/arch/x86/kernel/ds.c 2009-05-10 22:04:41.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/arch/x86/kernel/ds.c 2009-05-10 23:48:28.000000000 +0200 +@@ -15,8 +15,8 @@ + * - buffer allocation (memory accounting) + * + * +- * Copyright (C) 2007-2009 Intel Corporation. +- * Markus Metzger <markus.t.metzger@intel.com>, 2007-2009 ++ * Copyright (C) 2007-2008 Intel Corporation. ++ * Markus Metzger <markus.t.metzger@intel.com>, 2007-2008 + */ + + +@@ -729,7 +729,7 @@ + + spin_unlock_irqrestore(&ds_lock, irq); + +- ds_write_config(tracer->ds.context, &tracer->trace.ds, ds_pebs); ++ ds_write_config(tracer->ds.context, &tracer->trace.ds, ds_bts); + ds_resume_pebs(tracer); + + return tracer; +@@ -890,7 +890,7 @@ + } + + static const struct ds_configuration ds_cfg_netburst = { +- .name = "Netburst", ++ .name = "netburst", + .ctl[dsf_bts] = (1 << 2) | (1 << 3), + .ctl[dsf_bts_kernel] = (1 << 5), + .ctl[dsf_bts_user] = (1 << 6), +@@ -904,7 +904,7 @@ + #endif + }; + static const struct ds_configuration ds_cfg_pentium_m = { +- .name = "Pentium M", ++ .name = "pentium m", + .ctl[dsf_bts] = (1 << 6) | (1 << 7), + + .sizeof_field = sizeof(long), +@@ -915,8 +915,8 @@ + .sizeof_rec[ds_pebs] = sizeof(long) * 18, + #endif + }; +-static const struct ds_configuration ds_cfg_core2_atom = { +- .name = "Core 2/Atom", ++static const struct ds_configuration ds_cfg_core2 = { ++ .name = "core 2", + .ctl[dsf_bts] = (1 << 6) | (1 << 7), + .ctl[dsf_bts_kernel] = (1 << 9), + .ctl[dsf_bts_user] = (1 << 10), +@@ -949,22 +949,19 @@ + switch (c->x86) { + case 0x6: + switch (c->x86_model) { +- case 0x9: +- case 0xd: /* Pentium M */ +- ds_configure(&ds_cfg_pentium_m); ++ case 0 ... 0xC: ++ /* sorry, don't know about them */ + break; +- case 0xf: +- case 0x17: /* Core2 */ +- case 0x1c: /* Atom */ +- ds_configure(&ds_cfg_core2_atom); ++ case 0xD: ++ case 0xE: /* Pentium M */ ++ ds_configure(&ds_cfg_pentium_m); + break; +- case 0x1a: /* i7 */ +- default: +- /* sorry, don't know about them */ ++ default: /* Core2, Atom, ... */ ++ ds_configure(&ds_cfg_core2); + break; + } + break; +- case 0xf: ++ case 0xF: + switch (c->x86_model) { + case 0x0: + case 0x1: +@@ -1029,4 +1026,5 @@ + + void ds_exit_thread(struct task_struct *tsk) + { ++ WARN_ON(tsk->thread.ds_ctx); + } +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/arch/x86/kernel/efi_64.c linux-2.6.29-rc3.owrt/arch/x86/kernel/efi_64.c +--- linux-2.6.29.owrt/arch/x86/kernel/efi_64.c 2009-05-10 22:04:41.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/arch/x86/kernel/efi_64.c 2009-05-10 23:48:28.000000000 +0200 +@@ -99,11 +99,24 @@ + + void __iomem *__init efi_ioremap(unsigned long phys_addr, unsigned long size) + { +- unsigned long last_map_pfn; ++ static unsigned pages_mapped __initdata; ++ unsigned i, pages; ++ unsigned long offset; + +- last_map_pfn = init_memory_mapping(phys_addr, phys_addr + size); +- if ((last_map_pfn << PAGE_SHIFT) < phys_addr + size) ++ pages = PFN_UP(phys_addr + size) - PFN_DOWN(phys_addr); ++ offset = phys_addr & ~PAGE_MASK; ++ phys_addr &= PAGE_MASK; ++ ++ if (pages_mapped + pages > MAX_EFI_IO_PAGES) + return NULL; + +- return (void __iomem *)__va(phys_addr); ++ for (i = 0; i < pages; i++) { ++ __set_fixmap(FIX_EFI_IO_MAP_FIRST_PAGE - pages_mapped, ++ phys_addr, PAGE_KERNEL); ++ phys_addr += PAGE_SIZE; ++ pages_mapped++; ++ } ++ ++ return (void __iomem *)__fix_to_virt(FIX_EFI_IO_MAP_FIRST_PAGE - \ ++ (pages_mapped - pages)) + offset; + } +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/arch/x86/kernel/efi.c linux-2.6.29-rc3.owrt/arch/x86/kernel/efi.c +--- linux-2.6.29.owrt/arch/x86/kernel/efi.c 2009-05-10 22:04:41.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/arch/x86/kernel/efi.c 2009-05-10 23:48:28.000000000 +0200 +@@ -467,7 +467,7 @@ + efi_memory_desc_t *md; + efi_status_t status; + unsigned long size; +- u64 end, systab, addr, npages, end_pfn; ++ u64 end, systab, addr, npages; + void *p, *va; + + efi.systab = NULL; +@@ -479,10 +479,7 @@ + size = md->num_pages << EFI_PAGE_SHIFT; + end = md->phys_addr + size; + +- end_pfn = PFN_UP(end); +- if (end_pfn <= max_low_pfn_mapped +- || (end_pfn > (1UL << (32 - PAGE_SHIFT)) +- && end_pfn <= max_pfn_mapped)) ++ if (PFN_UP(end) <= max_low_pfn_mapped) + va = __va(md->phys_addr); + else + va = efi_ioremap(md->phys_addr, size); +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/arch/x86/kernel/entry_64.S linux-2.6.29-rc3.owrt/arch/x86/kernel/entry_64.S +--- linux-2.6.29.owrt/arch/x86/kernel/entry_64.S 2009-05-10 22:04:41.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/arch/x86/kernel/entry_64.S 2009-05-10 23:48:28.000000000 +0200 +@@ -346,7 +346,6 @@ + popq_cfi %rax /* move return address... */ + mov %gs:pda_irqstackptr,%rsp + EMPTY_FRAME 0 +- pushq_cfi %rbp /* backlink for unwinder */ + pushq_cfi %rax /* ... to the new stack */ + /* + * We entered an interrupt context - irqs are off: +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/arch/x86/kernel/ftrace.c linux-2.6.29-rc3.owrt/arch/x86/kernel/ftrace.c +--- linux-2.6.29.owrt/arch/x86/kernel/ftrace.c 2009-05-10 22:04:41.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/arch/x86/kernel/ftrace.c 2009-05-10 23:48:28.000000000 +0200 +@@ -488,21 +488,20 @@ + * ignore such a protection. + */ + asm volatile( +- "1: " _ASM_MOV " (%[parent]), %[old]\n" +- "2: " _ASM_MOV " %[return_hooker], (%[parent])\n" ++ "1: " _ASM_MOV " (%[parent_old]), %[old]\n" ++ "2: " _ASM_MOV " %[return_hooker], (%[parent_replaced])\n" + " movl $0, %[faulted]\n" +- "3:\n" + + ".section .fixup, \"ax\"\n" +- "4: movl $1, %[faulted]\n" +- " jmp 3b\n" ++ "3: movl $1, %[faulted]\n" + ".previous\n" + +- _ASM_EXTABLE(1b, 4b) +- _ASM_EXTABLE(2b, 4b) ++ _ASM_EXTABLE(1b, 3b) ++ _ASM_EXTABLE(2b, 3b) + +- : [old] "=r" (old), [faulted] "=r" (faulted) +- : [parent] "r" (parent), [return_hooker] "r" (return_hooker) ++ : [parent_replaced] "=r" (parent), [old] "=r" (old), ++ [faulted] "=r" (faulted) ++ : [parent_old] "0" (parent), [return_hooker] "r" (return_hooker) + : "memory" + ); + +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/arch/x86/kernel/hpet.c linux-2.6.29-rc3.owrt/arch/x86/kernel/hpet.c +--- linux-2.6.29.owrt/arch/x86/kernel/hpet.c 2009-05-10 22:04:41.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/arch/x86/kernel/hpet.c 2009-05-10 23:48:28.000000000 +0200 +@@ -269,8 +269,6 @@ + now = hpet_readl(HPET_COUNTER); + cmp = now + (unsigned long) delta; + cfg = hpet_readl(HPET_Tn_CFG(timer)); +- /* Make sure we use edge triggered interrupts */ +- cfg &= ~HPET_TN_LEVEL; + cfg |= HPET_TN_ENABLE | HPET_TN_PERIODIC | + HPET_TN_SETVAL | HPET_TN_32BIT; + hpet_writel(cfg, HPET_Tn_CFG(timer)); +@@ -899,7 +897,7 @@ + static int hpet_prev_update_sec; + static struct rtc_time hpet_alarm_time; + static unsigned long hpet_pie_count; +-static u32 hpet_t1_cmp; ++static unsigned long hpet_t1_cmp; + static unsigned long hpet_default_delta; + static unsigned long hpet_pie_delta; + static unsigned long hpet_pie_limit; +@@ -907,14 +905,6 @@ + static rtc_irq_handler irq_handler; + + /* +- * Check that the hpet counter c1 is ahead of the c2 +- */ +-static inline int hpet_cnt_ahead(u32 c1, u32 c2) +-{ +- return (s32)(c2 - c1) < 0; +-} +- +-/* + * Registers a IRQ handler. + */ + int hpet_register_irq_handler(rtc_irq_handler handler) +@@ -1085,7 +1075,7 @@ + hpet_t1_cmp += delta; + hpet_writel(hpet_t1_cmp, HPET_T1_CMP); + lost_ints++; +- } while (!hpet_cnt_ahead(hpet_t1_cmp, hpet_readl(HPET_COUNTER))); ++ } while ((long)(hpet_readl(HPET_COUNTER) - hpet_t1_cmp) > 0); + + if (lost_ints) { + if (hpet_rtc_flags & RTC_PIE) +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/arch/x86/kernel/i387.c linux-2.6.29-rc3.owrt/arch/x86/kernel/i387.c +--- linux-2.6.29.owrt/arch/x86/kernel/i387.c 2009-05-10 22:04:41.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/arch/x86/kernel/i387.c 2009-05-10 23:48:28.000000000 +0200 +@@ -136,7 +136,7 @@ + #ifdef CONFIG_X86_32 + if (!HAVE_HWFP) { + memset(tsk->thread.xstate, 0, xstate_size); +- finit_task(tsk); ++ finit(); + set_stopped_child_used_math(tsk); + return 0; + } +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/arch/x86/kernel/i8237.c linux-2.6.29-rc3.owrt/arch/x86/kernel/i8237.c +--- linux-2.6.29.owrt/arch/x86/kernel/i8237.c 2009-05-10 22:04:41.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/arch/x86/kernel/i8237.c 2009-05-10 23:48:28.000000000 +0200 +@@ -28,10 +28,10 @@ + + flags = claim_dma_lock(); + +- dma_outb(0, DMA1_RESET_REG); +- dma_outb(0, DMA2_RESET_REG); ++ dma_outb(DMA1_RESET_REG, 0); ++ dma_outb(DMA2_RESET_REG, 0); + +- for (i = 0; i < 8; i++) { ++ for (i = 0;i < 8;i++) { + set_dma_addr(i, 0x000000); + /* DMA count is a bit weird so this is not 0 */ + set_dma_count(i, 1); +@@ -51,14 +51,14 @@ + } + + static struct sysdev_class i8237_sysdev_class = { +- .name = "i8237", +- .suspend = i8237A_suspend, +- .resume = i8237A_resume, ++ .name = "i8237", ++ .suspend = i8237A_suspend, ++ .resume = i8237A_resume, + }; + + static struct sys_device device_i8237A = { +- .id = 0, +- .cls = &i8237_sysdev_class, ++ .id = 0, ++ .cls = &i8237_sysdev_class, + }; + + static int __init i8237A_init_sysfs(void) +@@ -68,4 +68,5 @@ + error = sysdev_register(&device_i8237A); + return error; + } ++ + device_initcall(i8237A_init_sysfs); +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/arch/x86/kernel/io_apic.c linux-2.6.29-rc3.owrt/arch/x86/kernel/io_apic.c +--- linux-2.6.29.owrt/arch/x86/kernel/io_apic.c 2009-05-10 22:04:41.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/arch/x86/kernel/io_apic.c 2009-05-10 23:48:28.000000000 +0200 +@@ -2528,15 +2528,14 @@ + + vector = ~get_irq_regs()->orig_ax; + me = smp_processor_id(); +- +- if (vector == cfg->vector && cpumask_test_cpu(me, cfg->domain)) { + #ifdef CONFIG_NUMA_MIGRATE_IRQ_DESC + *descp = desc = move_irq_desc(desc, me); + /* get the new one */ + cfg = desc->chip_data; + #endif ++ ++ if (vector == cfg->vector && cpumask_test_cpu(me, cfg->domain)) + send_cleanup_vector(cfg); +- } + } + #else + static inline void irq_complete_move(struct irq_desc **descp) {} +@@ -3841,24 +3840,14 @@ + + void __init probe_nr_irqs_gsi(void) + { ++ int idx; + int nr = 0; + +- nr = acpi_probe_gsi(); +- if (nr > nr_irqs_gsi) { +- nr_irqs_gsi = nr; +- } else { +- /* for acpi=off or acpi is not compiled in */ +- int idx; +- +- nr = 0; +- for (idx = 0; idx < nr_ioapics; idx++) +- nr += io_apic_get_redir_entries(idx) + 1; +- +- if (nr > nr_irqs_gsi) +- nr_irqs_gsi = nr; +- } ++ for (idx = 0; idx < nr_ioapics; idx++) ++ nr += io_apic_get_redir_entries(idx) + 1; + +- printk(KERN_DEBUG "nr_irqs_gsi: %d\n", nr_irqs_gsi); ++ if (nr > nr_irqs_gsi) ++ nr_irqs_gsi = nr; + } + + /* -------------------------------------------------------------------------- +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/arch/x86/kernel/irqinit_32.c linux-2.6.29-rc3.owrt/arch/x86/kernel/irqinit_32.c +--- linux-2.6.29.owrt/arch/x86/kernel/irqinit_32.c 2009-05-10 22:04:41.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/arch/x86/kernel/irqinit_32.c 2009-05-10 23:48:28.000000000 +0200 +@@ -78,6 +78,15 @@ + } + } + ++/* ++ * IRQ2 is cascade interrupt to second interrupt controller ++ */ ++static struct irqaction irq2 = { ++ .handler = no_action, ++ .mask = CPU_MASK_NONE, ++ .name = "cascade", ++}; ++ + DEFINE_PER_CPU(vector_irq_t, vector_irq) = { + [0 ... IRQ0_VECTOR - 1] = -1, + [IRQ0_VECTOR] = 0, +@@ -169,6 +178,9 @@ + alloc_intr_gate(THERMAL_APIC_VECTOR, thermal_interrupt); + #endif + ++ if (!acpi_ioapic) ++ setup_irq(2, &irq2); ++ + /* setup after call gates are initialised (usually add in + * the architecture specific gates) + */ +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/arch/x86/kernel/kprobes.c linux-2.6.29-rc3.owrt/arch/x86/kernel/kprobes.c +--- linux-2.6.29.owrt/arch/x86/kernel/kprobes.c 2009-05-10 22:04:41.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/arch/x86/kernel/kprobes.c 2009-05-10 23:48:28.000000000 +0200 +@@ -193,9 +193,6 @@ + kprobe_opcode_t opcode; + kprobe_opcode_t *orig_opcodes = opcodes; + +- if (search_exception_tables(opcodes)) +- return 0; /* Page fault may occur on this address. */ +- + retry: + if (opcodes - orig_opcodes > MAX_INSN_SIZE - 1) + return 0; +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/arch/x86/kernel/olpc.c linux-2.6.29-rc3.owrt/arch/x86/kernel/olpc.c +--- linux-2.6.29.owrt/arch/x86/kernel/olpc.c 2009-05-10 22:04:41.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/arch/x86/kernel/olpc.c 2009-05-10 23:48:28.000000000 +0200 +@@ -203,7 +203,7 @@ + static void __init platform_detect(void) + { + /* stopgap until OFW support is added to the kernel */ +- olpc_platform_info.boardrev = olpc_board(0xc2); ++ olpc_platform_info.boardrev = 0xc2; + } + #endif + +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/arch/x86/kernel/paravirt.c linux-2.6.29-rc3.owrt/arch/x86/kernel/paravirt.c +--- linux-2.6.29.owrt/arch/x86/kernel/paravirt.c 2009-05-10 22:04:41.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/arch/x86/kernel/paravirt.c 2009-05-10 23:48:28.000000000 +0200 +@@ -268,32 +268,6 @@ + return __get_cpu_var(paravirt_lazy_mode); + } + +-void arch_flush_lazy_mmu_mode(void) +-{ +- preempt_disable(); +- +- if (paravirt_get_lazy_mode() == PARAVIRT_LAZY_MMU) { +- WARN_ON(preempt_count() == 1); +- arch_leave_lazy_mmu_mode(); +- arch_enter_lazy_mmu_mode(); +- } +- +- preempt_enable(); +-} +- +-void arch_flush_lazy_cpu_mode(void) +-{ +- preempt_disable(); +- +- if (paravirt_get_lazy_mode() == PARAVIRT_LAZY_CPU) { +- WARN_ON(preempt_count() == 1); +- arch_leave_lazy_cpu_mode(); +- arch_enter_lazy_cpu_mode(); +- } +- +- preempt_enable(); +-} +- + struct pv_info pv_info = { + .name = "bare hardware", + .paravirt_enabled = 0, +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/arch/x86/kernel/pci-gart_64.c linux-2.6.29-rc3.owrt/arch/x86/kernel/pci-gart_64.c +--- linux-2.6.29.owrt/arch/x86/kernel/pci-gart_64.c 2009-05-10 22:04:41.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/arch/x86/kernel/pci-gart_64.c 2009-05-10 23:48:28.000000000 +0200 +@@ -5,7 +5,7 @@ + * This allows to use PCI devices that only support 32bit addresses on systems + * with more than 4GB. + * +- * See Documentation/PCI/PCI-DMA-mapping.txt for the interface specification. ++ * See Documentation/DMA-mapping.txt for the interface specification. + * + * Copyright 2002 Andi Kleen, SuSE Labs. + * Subject to the GNU General Public License v2 only. +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/arch/x86/kernel/process_32.c linux-2.6.29-rc3.owrt/arch/x86/kernel/process_32.c +--- linux-2.6.29.owrt/arch/x86/kernel/process_32.c 2009-05-10 22:04:41.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/arch/x86/kernel/process_32.c 2009-05-10 23:48:28.000000000 +0200 +@@ -104,6 +104,9 @@ + check_pgt_cache(); + rmb(); + ++ if (rcu_pending(cpu)) ++ rcu_check_callbacks(cpu, 0); ++ + if (cpu_is_offline(cpu)) + play_dead(); + +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/arch/x86/kernel/process_64.c linux-2.6.29-rc3.owrt/arch/x86/kernel/process_64.c +--- linux-2.6.29.owrt/arch/x86/kernel/process_64.c 2009-05-10 22:04:41.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/arch/x86/kernel/process_64.c 2009-05-10 23:48:28.000000000 +0200 +@@ -40,7 +40,6 @@ + #include <linux/uaccess.h> + #include <linux/io.h> + #include <linux/ftrace.h> +-#include <linux/dmi.h> + + #include <asm/pgtable.h> + #include <asm/system.h> +@@ -152,18 +151,14 @@ + unsigned long d0, d1, d2, d3, d6, d7; + unsigned int fsindex, gsindex; + unsigned int ds, cs, es; +- const char *board; + + printk("\n"); + print_modules(); +- board = dmi_get_system_info(DMI_PRODUCT_NAME); +- if (!board) +- board = ""; +- printk(KERN_INFO "Pid: %d, comm: %.20s %s %s %.*s %s\n", ++ printk(KERN_INFO "Pid: %d, comm: %.20s %s %s %.*s\n", + current->pid, current->comm, print_tainted(), + init_utsname()->release, + (int)strcspn(init_utsname()->version, " "), +- init_utsname()->version, board); ++ init_utsname()->version); + printk(KERN_INFO "RIP: %04lx:[<%016lx>] ", regs->cs & 0xffff, regs->ip); + printk_address(regs->ip, 1); + printk(KERN_INFO "RSP: %04lx:%016lx EFLAGS: %08lx\n", regs->ss, +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/arch/x86/kernel/process.c linux-2.6.29-rc3.owrt/arch/x86/kernel/process.c +--- linux-2.6.29.owrt/arch/x86/kernel/process.c 2009-05-10 22:04:41.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/arch/x86/kernel/process.c 2009-05-10 23:48:28.000000000 +0200 +@@ -180,9 +180,6 @@ + + trace_power_start(&it, POWER_CSTATE, (ax>>4)+1); + if (!need_resched()) { +- if (cpu_has(¤t_cpu_data, X86_FEATURE_CLFLUSH_MONITOR)) +- clflush((void *)¤t_thread_info()->flags); +- + __monitor((void *)¤t_thread_info()->flags, 0, 0); + smp_mb(); + if (!need_resched()) +@@ -197,9 +194,6 @@ + struct power_trace it; + if (!need_resched()) { + trace_power_start(&it, POWER_CSTATE, 1); +- if (cpu_has(¤t_cpu_data, X86_FEATURE_CLFLUSH_MONITOR)) +- clflush((void *)¤t_thread_info()->flags); +- + __monitor((void *)¤t_thread_info()->flags, 0, 0); + smp_mb(); + if (!need_resched()) +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/arch/x86/kernel/ptrace.c linux-2.6.29-rc3.owrt/arch/x86/kernel/ptrace.c +--- linux-2.6.29.owrt/arch/x86/kernel/ptrace.c 2009-05-10 22:04:41.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/arch/x86/kernel/ptrace.c 2009-05-10 23:48:28.000000000 +0200 +@@ -810,16 +810,12 @@ + + static void ptrace_bts_detach(struct task_struct *child) + { +- /* +- * Ptrace_detach() races with ptrace_untrace() in case +- * the child dies and is reaped by another thread. +- * +- * We only do the memory accounting at this point and +- * leave the buffer deallocation and the bts tracer +- * release to ptrace_bts_untrace() which will be called +- * later on with tasklist_lock held. +- */ +- release_locked_buffer(child->bts_buffer, child->bts_size); ++ if (unlikely(child->bts)) { ++ ds_release_bts(child->bts); ++ child->bts = NULL; ++ ++ ptrace_bts_free_buffer(child); ++ } + } + #else + static inline void ptrace_bts_fork(struct task_struct *tsk) {} +@@ -1388,7 +1384,7 @@ + #ifdef CONFIG_X86_32 + # define IS_IA32 1 + #elif defined CONFIG_IA32_EMULATION +-# define IS_IA32 is_compat_task() ++# define IS_IA32 test_thread_flag(TIF_IA32) + #else + # define IS_IA32 0 + #endif +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/arch/x86/kernel/reboot.c linux-2.6.29-rc3.owrt/arch/x86/kernel/reboot.c +--- linux-2.6.29.owrt/arch/x86/kernel/reboot.c 2009-05-10 22:04:41.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/arch/x86/kernel/reboot.c 2009-05-10 23:48:28.000000000 +0200 +@@ -217,14 +217,6 @@ + DMI_MATCH(DMI_PRODUCT_NAME, "HP Compaq"), + }, + }, +- { /* Handle problems with rebooting on Dell XPS710 */ +- .callback = set_bios_reboot, +- .ident = "Dell XPS710", +- .matches = { +- DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc."), +- DMI_MATCH(DMI_PRODUCT_NAME, "Dell XPS710"), +- }, +- }, + { } + }; + +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/arch/x86/kernel/setup.c linux-2.6.29-rc3.owrt/arch/x86/kernel/setup.c +--- linux-2.6.29.owrt/arch/x86/kernel/setup.c 2009-05-10 22:04:41.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/arch/x86/kernel/setup.c 2009-05-10 23:48:28.000000000 +0200 +@@ -607,7 +607,7 @@ + static int __init dmi_low_memory_corruption(const struct dmi_system_id *d) + { + printk(KERN_NOTICE +- "%s detected: BIOS may corrupt low RAM, working around it.\n", ++ "%s detected: BIOS may corrupt low RAM, working it around.\n", + d->ident); + + e820_update_range(0, 0x10000, E820_RAM, E820_RESERVED); +@@ -770,9 +770,6 @@ + + finish_e820_parsing(); + +- if (efi_enabled) +- efi_init(); +- + dmi_scan_machine(); + + dmi_check_system(bad_bios_dmi_table); +@@ -792,6 +789,8 @@ + insert_resource(&iomem_resource, &data_resource); + insert_resource(&iomem_resource, &bss_resource); + ++ if (efi_enabled) ++ efi_init(); + + #ifdef CONFIG_X86_32 + if (ppro_with_ram_bug()) { +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/arch/x86/kernel/time_64.c linux-2.6.29-rc3.owrt/arch/x86/kernel/time_64.c +--- linux-2.6.29.owrt/arch/x86/kernel/time_64.c 2009-05-10 22:04:41.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/arch/x86/kernel/time_64.c 2009-05-10 23:48:28.000000000 +0200 +@@ -115,7 +115,7 @@ + + static struct irqaction irq0 = { + .handler = timer_interrupt, +- .flags = IRQF_DISABLED | IRQF_IRQPOLL | IRQF_NOBALANCING | IRQF_TIMER, ++ .flags = IRQF_DISABLED | IRQF_IRQPOLL | IRQF_NOBALANCING, + .mask = CPU_MASK_NONE, + .name = "timer" + }; +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/arch/x86/kernel/traps.c linux-2.6.29-rc3.owrt/arch/x86/kernel/traps.c +--- linux-2.6.29.owrt/arch/x86/kernel/traps.c 2009-05-10 22:04:41.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/arch/x86/kernel/traps.c 2009-05-10 23:48:28.000000000 +0200 +@@ -99,12 +99,6 @@ + local_irq_enable(); + } + +-static inline void conditional_cli(struct pt_regs *regs) +-{ +- if (regs->flags & X86_EFLAGS_IF) +- local_irq_disable(); +-} +- + static inline void preempt_conditional_cli(struct pt_regs *regs) + { + if (regs->flags & X86_EFLAGS_IF) +@@ -632,10 +626,8 @@ + + #ifdef CONFIG_X86_32 + debug_vm86: +- /* reenable preemption: handle_vm86_trap() might sleep */ +- dec_preempt_count(); + handle_vm86_trap((struct kernel_vm86_regs *) regs, error_code, 1); +- conditional_cli(regs); ++ preempt_conditional_cli(regs); + return; + #endif + +@@ -904,7 +896,7 @@ + EXPORT_SYMBOL_GPL(math_state_restore); + + #ifndef CONFIG_MATH_EMULATION +-void math_emulate(struct math_emu_info *info) ++asmlinkage void math_emulate(long arg) + { + printk(KERN_EMERG + "math-emulation not enabled and no coprocessor found.\n"); +@@ -914,19 +906,16 @@ + } + #endif /* CONFIG_MATH_EMULATION */ + +-dotraplinkage void __kprobes do_device_not_available(struct pt_regs regs) ++dotraplinkage void __kprobes ++do_device_not_available(struct pt_regs *regs, long error) + { + #ifdef CONFIG_X86_32 + if (read_cr0() & X86_CR0_EM) { +- struct math_emu_info info = { }; +- +- conditional_sti(®s); +- +- info.regs = ®s; +- math_emulate(&info); ++ conditional_sti(regs); ++ math_emulate(0); + } else { + math_state_restore(); /* interrupts still off */ +- conditional_sti(®s); ++ conditional_sti(regs); + } + #else + math_state_restore(); +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/arch/x86/kernel/tsc.c linux-2.6.29-rc3.owrt/arch/x86/kernel/tsc.c +--- linux-2.6.29.owrt/arch/x86/kernel/tsc.c 2009-05-10 22:04:41.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/arch/x86/kernel/tsc.c 2009-05-10 23:48:28.000000000 +0200 +@@ -273,43 +273,30 @@ + * use the TSC value at the transitions to calculate a pretty + * good value for the TSC frequencty. + */ +-static inline int pit_expect_msb(unsigned char val, u64 *tscp, unsigned long *deltap) ++static inline int pit_expect_msb(unsigned char val) + { +- int count; +- u64 tsc = 0; ++ int count = 0; + + for (count = 0; count < 50000; count++) { + /* Ignore LSB */ + inb(0x42); + if (inb(0x42) != val) + break; +- tsc = get_cycles(); + } +- *deltap = get_cycles() - tsc; +- *tscp = tsc; +- +- /* +- * We require _some_ success, but the quality control +- * will be based on the error terms on the TSC values. +- */ +- return count > 5; ++ return count > 50; + } + + /* +- * How many MSB values do we want to see? We aim for +- * a maximum error rate of 500ppm (in practice the +- * real error is much smaller), but refuse to spend +- * more than 25ms on it. ++ * How many MSB values do we want to see? We aim for a ++ * 15ms calibration, which assuming a 2us counter read ++ * error should give us roughly 150 ppm precision for ++ * the calibration. + */ +-#define MAX_QUICK_PIT_MS 25 +-#define MAX_QUICK_PIT_ITERATIONS (MAX_QUICK_PIT_MS * PIT_TICK_RATE / 1000 / 256) ++#define QUICK_PIT_MS 15 ++#define QUICK_PIT_ITERATIONS (QUICK_PIT_MS * PIT_TICK_RATE / 1000 / 256) + + static unsigned long quick_pit_calibrate(void) + { +- int i; +- u64 tsc, delta; +- unsigned long d1, d2; +- + /* Set the Gate high, disable speaker */ + outb((inb(0x61) & ~0x02) | 0x01, 0x61); + +@@ -328,52 +315,45 @@ + outb(0xff, 0x42); + outb(0xff, 0x42); + +- /* +- * The PIT starts counting at the next edge, so we +- * need to delay for a microsecond. The easiest way +- * to do that is to just read back the 16-bit counter +- * once from the PIT. +- */ +- inb(0x42); +- inb(0x42); +- +- if (pit_expect_msb(0xff, &tsc, &d1)) { +- for (i = 1; i <= MAX_QUICK_PIT_ITERATIONS; i++) { +- if (!pit_expect_msb(0xff-i, &delta, &d2)) +- break; +- +- /* +- * Iterate until the error is less than 500 ppm +- */ +- delta -= tsc; +- if (d1+d2 < delta >> 11) +- goto success; ++ if (pit_expect_msb(0xff)) { ++ int i; ++ u64 t1, t2, delta; ++ unsigned char expect = 0xfe; ++ ++ t1 = get_cycles(); ++ for (i = 0; i < QUICK_PIT_ITERATIONS; i++, expect--) { ++ if (!pit_expect_msb(expect)) ++ goto failed; + } ++ t2 = get_cycles(); ++ ++ /* ++ * Make sure we can rely on the second TSC timestamp: ++ */ ++ if (!pit_expect_msb(expect)) ++ goto failed; ++ ++ /* ++ * Ok, if we get here, then we've seen the ++ * MSB of the PIT decrement QUICK_PIT_ITERATIONS ++ * times, and each MSB had many hits, so we never ++ * had any sudden jumps. ++ * ++ * As a result, we can depend on there not being ++ * any odd delays anywhere, and the TSC reads are ++ * reliable. ++ * ++ * kHz = ticks / time-in-seconds / 1000; ++ * kHz = (t2 - t1) / (QPI * 256 / PIT_TICK_RATE) / 1000 ++ * kHz = ((t2 - t1) * PIT_TICK_RATE) / (QPI * 256 * 1000) ++ */ ++ delta = (t2 - t1)*PIT_TICK_RATE; ++ do_div(delta, QUICK_PIT_ITERATIONS*256*1000); ++ printk("Fast TSC calibration using PIT\n"); ++ return delta; + } +- printk("Fast TSC calibration failed\n"); ++failed: + return 0; +- +-success: +- /* +- * Ok, if we get here, then we've seen the +- * MSB of the PIT decrement 'i' times, and the +- * error has shrunk to less than 500 ppm. +- * +- * As a result, we can depend on there not being +- * any odd delays anywhere, and the TSC reads are +- * reliable (within the error). We also adjust the +- * delta to the middle of the error bars, just +- * because it looks nicer. +- * +- * kHz = ticks / time-in-seconds / 1000; +- * kHz = (t2 - t1) / (I * 256 / PIT_TICK_RATE) / 1000 +- * kHz = ((t2 - t1) * PIT_TICK_RATE) / (I * 256 * 1000) +- */ +- delta += (long)(d2 - d1)/2; +- delta *= PIT_TICK_RATE; +- do_div(delta, i*256*1000); +- printk("Fast TSC calibration using PIT\n"); +- return delta; + } + + /** +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/arch/x86/kernel/vmi_32.c linux-2.6.29-rc3.owrt/arch/x86/kernel/vmi_32.c +--- linux-2.6.29.owrt/arch/x86/kernel/vmi_32.c 2009-05-10 22:04:41.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/arch/x86/kernel/vmi_32.c 2009-05-10 23:48:28.000000000 +0200 +@@ -321,16 +321,6 @@ + } + + /* +- * We use the pgd_free hook for releasing the pgd page: +- */ +-static void vmi_pgd_free(struct mm_struct *mm, pgd_t *pgd) +-{ +- unsigned long pfn = __pa(pgd) >> PAGE_SHIFT; +- +- vmi_ops.release_page(pfn, VMI_PAGE_L2); +-} +- +-/* + * Helper macros for MMU update flags. We can defer updates until a flush + * or page invalidation only if the update is to the current address space + * (otherwise, there is no flush). We must check against init_mm, since +@@ -772,7 +762,6 @@ + if (vmi_ops.release_page) { + pv_mmu_ops.release_pte = vmi_release_pte; + pv_mmu_ops.release_pmd = vmi_release_pmd; +- pv_mmu_ops.pgd_free = vmi_pgd_free; + } + + /* Set linear is needed in all cases */ +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/arch/x86/kernel/vmiclock_32.c linux-2.6.29-rc3.owrt/arch/x86/kernel/vmiclock_32.c +--- linux-2.6.29.owrt/arch/x86/kernel/vmiclock_32.c 2009-05-10 22:04:41.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/arch/x86/kernel/vmiclock_32.c 2009-05-10 23:48:28.000000000 +0200 +@@ -202,7 +202,7 @@ + static struct irqaction vmi_clock_action = { + .name = "vmi-timer", + .handler = vmi_timer_interrupt, +- .flags = IRQF_DISABLED | IRQF_NOBALANCING | IRQF_TIMER, ++ .flags = IRQF_DISABLED | IRQF_NOBALANCING, + .mask = CPU_MASK_ALL, + }; + +@@ -283,13 +283,10 @@ + #endif + + /** vmi clocksource */ +-static struct clocksource clocksource_vmi; + + static cycle_t read_real_cycles(void) + { +- cycle_t ret = (cycle_t)vmi_timer_ops.get_cycle_counter(VMI_CYCLES_REAL); +- return ret >= clocksource_vmi.cycle_last ? +- ret : clocksource_vmi.cycle_last; ++ return vmi_timer_ops.get_cycle_counter(VMI_CYCLES_REAL); + } + + static struct clocksource clocksource_vmi = { +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/arch/x86/kvm/i8254.c linux-2.6.29-rc3.owrt/arch/x86/kvm/i8254.c +--- linux-2.6.29.owrt/arch/x86/kvm/i8254.c 2009-05-10 22:04:41.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/arch/x86/kvm/i8254.c 2009-05-10 23:48:28.000000000 +0200 +@@ -207,7 +207,7 @@ + hrtimer_add_expires_ns(&pt->timer, pt->period); + pt->scheduled = hrtimer_get_expires_ns(&pt->timer); + if (pt->period) +- ps->channels[0].count_load_time = ktime_get(); ++ ps->channels[0].count_load_time = hrtimer_get_expires(&pt->timer); + + return (pt->period == 0 ? 0 : 1); + } +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/arch/x86/kvm/irq.c linux-2.6.29-rc3.owrt/arch/x86/kvm/irq.c +--- linux-2.6.29.owrt/arch/x86/kvm/irq.c 2009-05-10 22:04:41.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/arch/x86/kvm/irq.c 2009-05-10 23:48:28.000000000 +0200 +@@ -87,6 +87,13 @@ + } + EXPORT_SYMBOL_GPL(kvm_inject_pending_timer_irqs); + ++void kvm_timer_intr_post(struct kvm_vcpu *vcpu, int vec) ++{ ++ kvm_apic_timer_intr_post(vcpu, vec); ++ /* TODO: PIT, RTC etc. */ ++} ++EXPORT_SYMBOL_GPL(kvm_timer_intr_post); ++ + void __kvm_migrate_timers(struct kvm_vcpu *vcpu) + { + __kvm_migrate_apic_timer(vcpu); +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/arch/x86/kvm/irq.h linux-2.6.29-rc3.owrt/arch/x86/kvm/irq.h +--- linux-2.6.29.owrt/arch/x86/kvm/irq.h 2009-05-10 22:04:41.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/arch/x86/kvm/irq.h 2009-05-10 23:48:28.000000000 +0200 +@@ -89,6 +89,7 @@ + + void kvm_pic_reset(struct kvm_kpic_state *s); + ++void kvm_timer_intr_post(struct kvm_vcpu *vcpu, int vec); + void kvm_inject_pending_timer_irqs(struct kvm_vcpu *vcpu); + void kvm_inject_apic_timer_irqs(struct kvm_vcpu *vcpu); + void kvm_apic_nmi_wd_deliver(struct kvm_vcpu *vcpu); +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/arch/x86/kvm/lapic.c linux-2.6.29-rc3.owrt/arch/x86/kvm/lapic.c +--- linux-2.6.29.owrt/arch/x86/kvm/lapic.c 2009-05-10 22:04:41.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/arch/x86/kvm/lapic.c 2009-05-10 23:48:28.000000000 +0200 +@@ -35,12 +35,6 @@ + #include "kvm_cache_regs.h" + #include "irq.h" + +-#ifndef CONFIG_X86_64 +-#define mod_64(x, y) ((x) - (y) * div64_u64(x, y)) +-#else +-#define mod_64(x, y) ((x) % (y)) +-#endif +- + #define PRId64 "d" + #define PRIx64 "llx" + #define PRIu64 "u" +@@ -517,22 +511,52 @@ + + static u32 apic_get_tmcct(struct kvm_lapic *apic) + { +- ktime_t remaining; +- s64 ns; ++ u64 counter_passed; ++ ktime_t passed, now; + u32 tmcct; + + ASSERT(apic != NULL); + ++ now = apic->timer.dev.base->get_time(); ++ tmcct = apic_get_reg(apic, APIC_TMICT); ++ + /* if initial count is 0, current count should also be 0 */ +- if (apic_get_reg(apic, APIC_TMICT) == 0) ++ if (tmcct == 0) + return 0; + +- remaining = hrtimer_expires_remaining(&apic->timer.dev); +- if (ktime_to_ns(remaining) < 0) +- remaining = ktime_set(0, 0); +- +- ns = mod_64(ktime_to_ns(remaining), apic->timer.period); +- tmcct = div64_u64(ns, (APIC_BUS_CYCLE_NS * apic->timer.divide_count)); ++ if (unlikely(ktime_to_ns(now) <= ++ ktime_to_ns(apic->timer.last_update))) { ++ /* Wrap around */ ++ passed = ktime_add(( { ++ (ktime_t) { ++ .tv64 = KTIME_MAX - ++ (apic->timer.last_update).tv64}; } ++ ), now); ++ apic_debug("time elapsed\n"); ++ } else ++ passed = ktime_sub(now, apic->timer.last_update); ++ ++ counter_passed = div64_u64(ktime_to_ns(passed), ++ (APIC_BUS_CYCLE_NS * apic->timer.divide_count)); ++ ++ if (counter_passed > tmcct) { ++ if (unlikely(!apic_lvtt_period(apic))) { ++ /* one-shot timers stick at 0 until reset */ ++ tmcct = 0; ++ } else { ++ /* ++ * periodic timers reset to APIC_TMICT when they ++ * hit 0. The while loop simulates this happening N ++ * times. (counter_passed %= tmcct) would also work, ++ * but might be slower or not work on 32-bit?? ++ */ ++ while (counter_passed > tmcct) ++ counter_passed -= tmcct; ++ tmcct -= counter_passed; ++ } ++ } else { ++ tmcct -= counter_passed; ++ } + + return tmcct; + } +@@ -629,6 +653,8 @@ + { + ktime_t now = apic->timer.dev.base->get_time(); + ++ apic->timer.last_update = now; ++ + apic->timer.period = apic_get_reg(apic, APIC_TMICT) * + APIC_BUS_CYCLE_NS * apic->timer.divide_count; + atomic_set(&apic->timer.pending, 0); +@@ -1084,6 +1110,16 @@ + } + } + ++void kvm_apic_timer_intr_post(struct kvm_vcpu *vcpu, int vec) ++{ ++ struct kvm_lapic *apic = vcpu->arch.apic; ++ ++ if (apic && apic_lvt_vector(apic, APIC_LVTT) == vec) ++ apic->timer.last_update = ktime_add_ns( ++ apic->timer.last_update, ++ apic->timer.period); ++} ++ + int kvm_get_apic_interrupt(struct kvm_vcpu *vcpu) + { + int vector = kvm_apic_has_interrupt(vcpu); +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/arch/x86/kvm/lapic.h linux-2.6.29-rc3.owrt/arch/x86/kvm/lapic.h +--- linux-2.6.29.owrt/arch/x86/kvm/lapic.h 2009-05-10 22:04:41.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/arch/x86/kvm/lapic.h 2009-05-10 23:48:28.000000000 +0200 +@@ -12,6 +12,7 @@ + atomic_t pending; + s64 period; /* unit: ns */ + u32 divide_count; ++ ktime_t last_update; + struct hrtimer dev; + } timer; + struct kvm_vcpu *vcpu; +@@ -41,6 +42,7 @@ + void kvm_apic_post_state_restore(struct kvm_vcpu *vcpu); + int kvm_lapic_enabled(struct kvm_vcpu *vcpu); + int kvm_lapic_find_highest_irr(struct kvm_vcpu *vcpu); ++void kvm_apic_timer_intr_post(struct kvm_vcpu *vcpu, int vec); + + void kvm_lapic_set_vapic_addr(struct kvm_vcpu *vcpu, gpa_t vapic_addr); + void kvm_lapic_sync_from_vapic(struct kvm_vcpu *vcpu); +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/arch/x86/kvm/mmu.c linux-2.6.29-rc3.owrt/arch/x86/kvm/mmu.c +--- linux-2.6.29.owrt/arch/x86/kvm/mmu.c 2009-05-10 22:04:41.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/arch/x86/kvm/mmu.c 2009-05-10 23:48:28.000000000 +0200 +@@ -1698,13 +1698,8 @@ + if (largepage) + spte |= PT_PAGE_SIZE_MASK; + if (mt_mask) { +- if (!kvm_is_mmio_pfn(pfn)) { +- mt_mask = get_memory_type(vcpu, gfn) << +- kvm_x86_ops->get_mt_mask_shift(); +- mt_mask |= VMX_EPT_IGMT_BIT; +- } else +- mt_mask = MTRR_TYPE_UNCACHABLE << +- kvm_x86_ops->get_mt_mask_shift(); ++ mt_mask = get_memory_type(vcpu, gfn) << ++ kvm_x86_ops->get_mt_mask_shift(); + spte |= mt_mask; + } + +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/arch/x86/kvm/svm.c linux-2.6.29-rc3.owrt/arch/x86/kvm/svm.c +--- linux-2.6.29.owrt/arch/x86/kvm/svm.c 2009-05-10 22:04:41.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/arch/x86/kvm/svm.c 2009-05-10 23:48:28.000000000 +0200 +@@ -1600,6 +1600,7 @@ + /* Okay, we can deliver the interrupt: grab it and update PIC state. */ + intr_vector = kvm_cpu_get_interrupt(vcpu); + svm_inject_irq(svm, intr_vector); ++ kvm_timer_intr_post(vcpu, intr_vector); + out: + update_cr8_intercept(vcpu); + } +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/arch/x86/kvm/vmx.c linux-2.6.29-rc3.owrt/arch/x86/kvm/vmx.c +--- linux-2.6.29.owrt/arch/x86/kvm/vmx.c 2009-05-10 22:04:41.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/arch/x86/kvm/vmx.c 2009-05-10 23:48:28.000000000 +0200 +@@ -903,7 +903,6 @@ + data = vmcs_readl(GUEST_SYSENTER_ESP); + break; + default: +- vmx_load_host_state(to_vmx(vcpu)); + msr = find_msr_entry(to_vmx(vcpu), msr_index); + if (msr) { + data = msr->data; +@@ -3286,6 +3285,7 @@ + } + if (vcpu->arch.interrupt.pending) { + vmx_inject_irq(vcpu, vcpu->arch.interrupt.nr); ++ kvm_timer_intr_post(vcpu, vcpu->arch.interrupt.nr); + if (kvm_cpu_has_interrupt(vcpu)) + enable_irq_window(vcpu); + } +@@ -3687,7 +3687,8 @@ + if (vm_need_ept()) { + bypass_guest_pf = 0; + kvm_mmu_set_base_ptes(VMX_EPT_READABLE_MASK | +- VMX_EPT_WRITABLE_MASK); ++ VMX_EPT_WRITABLE_MASK | ++ VMX_EPT_IGMT_BIT); + kvm_mmu_set_mask_ptes(0ull, 0ull, 0ull, 0ull, + VMX_EPT_EXECUTABLE_MASK, + VMX_EPT_DEFAULT_MT << VMX_EPT_MT_EPTE_SHIFT); +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/arch/x86/kvm/x86.c linux-2.6.29-rc3.owrt/arch/x86/kvm/x86.c +--- linux-2.6.29.owrt/arch/x86/kvm/x86.c 2009-05-10 22:04:41.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/arch/x86/kvm/x86.c 2009-05-10 23:48:28.000000000 +0200 +@@ -967,6 +967,7 @@ + case KVM_CAP_MMU_SHADOW_CACHE_CONTROL: + case KVM_CAP_SET_TSS_ADDR: + case KVM_CAP_EXT_CPUID: ++ case KVM_CAP_CLOCKSOURCE: + case KVM_CAP_PIT: + case KVM_CAP_NOP_IO_DELAY: + case KVM_CAP_MP_STATE: +@@ -991,9 +992,6 @@ + case KVM_CAP_IOMMU: + r = iommu_found(); + break; +- case KVM_CAP_CLOCKSOURCE: +- r = boot_cpu_has(X86_FEATURE_CONSTANT_TSC); +- break; + default: + r = 0; + break; +@@ -4129,13 +4127,9 @@ + + } + +-void kvm_arch_sync_events(struct kvm *kvm) +-{ +- kvm_free_all_assigned_devices(kvm); +-} +- + void kvm_arch_destroy_vm(struct kvm *kvm) + { ++ kvm_free_all_assigned_devices(kvm); + kvm_iommu_unmap_guest(kvm); + kvm_free_pit(kvm); + kfree(kvm->arch.vpic); +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/arch/x86/lguest/boot.c linux-2.6.29-rc3.owrt/arch/x86/lguest/boot.c +--- linux-2.6.29.owrt/arch/x86/lguest/boot.c 2009-05-10 22:04:41.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/arch/x86/lguest/boot.c 2009-05-10 23:48:28.000000000 +0200 +@@ -343,11 +343,6 @@ + * flush_tlb_user() for both user and kernel mappings unless + * the Page Global Enable (PGE) feature bit is set. */ + *dx |= 0x00002000; +- /* We also lie, and say we're family id 5. 6 or greater +- * leads to a rdmsr in early_init_intel which we can't handle. +- * Family ID is returned as bits 8-12 in ax. */ +- *ax &= 0xFFFFF0FF; +- *ax |= 0x00000500; + break; + case 0x80000000: + /* Futureproof this a little: if they ask how much extended +@@ -594,21 +589,19 @@ + /* Some systems map "vectors" to interrupts weirdly. Lguest has + * a straightforward 1 to 1 mapping, so force that here. */ + __get_cpu_var(vector_irq)[vector] = i; +- if (vector != SYSCALL_VECTOR) +- set_intr_gate(vector, interrupt[i]); ++ if (vector != SYSCALL_VECTOR) { ++ set_intr_gate(vector, ++ interrupt[vector-FIRST_EXTERNAL_VECTOR]); ++ set_irq_chip_and_handler_name(i, &lguest_irq_controller, ++ handle_level_irq, ++ "level"); ++ } + } + /* This call is required to set up for 4k stacks, where we have + * separate stacks for hard and soft interrupts. */ + irq_ctx_init(smp_processor_id()); + } + +-void lguest_setup_irq(unsigned int irq) +-{ +- irq_to_desc_alloc_cpu(irq, 0); +- set_irq_chip_and_handler_name(irq, &lguest_irq_controller, +- handle_level_irq, "level"); +-} +- + /* + * Time. + * +@@ -938,7 +931,7 @@ + * that we can fit comfortably. + * + * First we need assembly templates of each of the patchable Guest operations, +- * and these are in i386_head.S. */ ++ * and these are in lguest_asm.S. */ + + /*G:060 We construct a table from the assembler templates: */ + static const struct lguest_insns +@@ -1100,7 +1093,7 @@ + acpi_ht = 0; + #endif + +- /* We set the preferred console to "hvc". This is the "hypervisor ++ /* We set the perferred console to "hvc". This is the "hypervisor + * virtual console" driver written by the PowerPC people, which we also + * adapted for lguest's use. */ + add_preferred_console("hvc", 0, NULL); +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/arch/x86/mach-default/setup.c linux-2.6.29-rc3.owrt/arch/x86/mach-default/setup.c +--- linux-2.6.29.owrt/arch/x86/mach-default/setup.c 2009-05-10 22:04:41.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/arch/x86/mach-default/setup.c 2009-05-10 23:48:28.000000000 +0200 +@@ -38,15 +38,6 @@ + init_ISA_irqs(); + } + +-/* +- * IRQ2 is cascade interrupt to second interrupt controller +- */ +-static struct irqaction irq2 = { +- .handler = no_action, +- .mask = CPU_MASK_NONE, +- .name = "cascade", +-}; +- + /** + * intr_init_hook - post gate setup interrupt initialisation + * +@@ -62,9 +53,6 @@ + if (x86_quirks->arch_intr_init()) + return; + } +- if (!acpi_ioapic) +- setup_irq(2, &irq2); +- + } + + /** +@@ -96,7 +84,7 @@ + + static struct irqaction irq0 = { + .handler = timer_interrupt, +- .flags = IRQF_DISABLED | IRQF_NOBALANCING | IRQF_IRQPOLL | IRQF_TIMER, ++ .flags = IRQF_DISABLED | IRQF_NOBALANCING | IRQF_IRQPOLL, + .mask = CPU_MASK_NONE, + .name = "timer" + }; +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/arch/x86/mach-voyager/setup.c linux-2.6.29-rc3.owrt/arch/x86/mach-voyager/setup.c +--- linux-2.6.29.owrt/arch/x86/mach-voyager/setup.c 2009-05-10 22:04:41.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/arch/x86/mach-voyager/setup.c 2009-05-10 23:48:28.000000000 +0200 +@@ -33,30 +33,20 @@ + setup_irq(2, &irq2); + } + +-static void voyager_disable_tsc(void) ++void __init pre_setup_arch_hook(void) + { + /* Voyagers run their CPUs from independent clocks, so disable + * the TSC code because we can't sync them */ + setup_clear_cpu_cap(X86_FEATURE_TSC); + } + +-void __init pre_setup_arch_hook(void) +-{ +- voyager_disable_tsc(); +-} +- +-void __init pre_time_init_hook(void) +-{ +- voyager_disable_tsc(); +-} +- + void __init trap_init_hook(void) + { + } + + static struct irqaction irq0 = { + .handler = timer_interrupt, +- .flags = IRQF_DISABLED | IRQF_NOBALANCING | IRQF_IRQPOLL | IRQF_TIMER, ++ .flags = IRQF_DISABLED | IRQF_NOBALANCING | IRQF_IRQPOLL, + .mask = CPU_MASK_NONE, + .name = "timer" + }; +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/arch/x86/mach-voyager/voyager_smp.c linux-2.6.29-rc3.owrt/arch/x86/mach-voyager/voyager_smp.c +--- linux-2.6.29.owrt/arch/x86/mach-voyager/voyager_smp.c 2009-05-10 22:04:41.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/arch/x86/mach-voyager/voyager_smp.c 2009-05-10 23:48:28.000000000 +0200 +@@ -65,7 +65,7 @@ + + /* Bitmask of CPUs present in the system - exported by i386_syms.c, used + * by scheduler but indexed physically */ +-static cpumask_t voyager_phys_cpu_present_map = CPU_MASK_NONE; ++cpumask_t phys_cpu_present_map = CPU_MASK_NONE; + + /* The internal functions */ + static void send_CPI(__u32 cpuset, __u8 cpi); +@@ -81,7 +81,7 @@ + static void disable_local_vic_irq(unsigned int irq); + static void before_handle_vic_irq(unsigned int irq); + static void after_handle_vic_irq(unsigned int irq); +-static void set_vic_irq_affinity(unsigned int irq, const struct cpumask *mask); ++static void set_vic_irq_affinity(unsigned int irq, cpumask_t mask); + static void ack_vic_irq(unsigned int irq); + static void vic_enable_cpi(void); + static void do_boot_cpu(__u8 cpuid); +@@ -211,6 +211,8 @@ + static cpumask_t smp_commenced_mask = CPU_MASK_NONE; + + /* This is for the new dynamic CPU boot code */ ++cpumask_t cpu_callin_map = CPU_MASK_NONE; ++cpumask_t cpu_callout_map = CPU_MASK_NONE; + + /* The per processor IRQ masks (these are usually kept in sync) */ + static __u16 vic_irq_mask[NR_CPUS] __cacheline_aligned; +@@ -366,19 +368,19 @@ + /* set up everything for just this CPU, we can alter + * this as we start the other CPUs later */ + /* now get the CPU disposition from the extended CMOS */ +- cpus_addr(voyager_phys_cpu_present_map)[0] = ++ cpus_addr(phys_cpu_present_map)[0] = + voyager_extended_cmos_read(VOYAGER_PROCESSOR_PRESENT_MASK); +- cpus_addr(voyager_phys_cpu_present_map)[0] |= ++ cpus_addr(phys_cpu_present_map)[0] |= + voyager_extended_cmos_read(VOYAGER_PROCESSOR_PRESENT_MASK + 1) << 8; +- cpus_addr(voyager_phys_cpu_present_map)[0] |= ++ cpus_addr(phys_cpu_present_map)[0] |= + voyager_extended_cmos_read(VOYAGER_PROCESSOR_PRESENT_MASK + + 2) << 16; +- cpus_addr(voyager_phys_cpu_present_map)[0] |= ++ cpus_addr(phys_cpu_present_map)[0] |= + voyager_extended_cmos_read(VOYAGER_PROCESSOR_PRESENT_MASK + + 3) << 24; +- init_cpu_possible(&voyager_phys_cpu_present_map); +- printk("VOYAGER SMP: voyager_phys_cpu_present_map = 0x%lx\n", +- cpus_addr(voyager_phys_cpu_present_map)[0]); ++ cpu_possible_map = phys_cpu_present_map; ++ printk("VOYAGER SMP: phys_cpu_present_map = 0x%lx\n", ++ cpus_addr(phys_cpu_present_map)[0]); + /* Here we set up the VIC to enable SMP */ + /* enable the CPIs by writing the base vector to their register */ + outb(VIC_DEFAULT_CPI_BASE, VIC_CPI_BASE_REGISTER); +@@ -628,15 +630,15 @@ + /* now that the cat has probed the Voyager System Bus, sanity + * check the cpu map */ + if (((voyager_quad_processors | voyager_extended_vic_processors) +- & cpus_addr(voyager_phys_cpu_present_map)[0]) != +- cpus_addr(voyager_phys_cpu_present_map)[0]) { ++ & cpus_addr(phys_cpu_present_map)[0]) != ++ cpus_addr(phys_cpu_present_map)[0]) { + /* should panic */ + printk("\n\n***WARNING*** " + "Sanity check of CPU present map FAILED\n"); + } + } else if (voyager_level == 4) + voyager_extended_vic_processors = +- cpus_addr(voyager_phys_cpu_present_map)[0]; ++ cpus_addr(phys_cpu_present_map)[0]; + + /* this sets up the idle task to run on the current cpu */ + voyager_extended_cpus = 1; +@@ -670,7 +672,7 @@ + /* loop over all the extended VIC CPUs and boot them. The + * Quad CPUs must be bootstrapped by their extended VIC cpu */ + for (i = 0; i < nr_cpu_ids; i++) { +- if (i == boot_cpu_id || !cpu_isset(i, voyager_phys_cpu_present_map)) ++ if (i == boot_cpu_id || !cpu_isset(i, phys_cpu_present_map)) + continue; + do_boot_cpu(i); + /* This udelay seems to be needed for the Quad boots +@@ -1597,16 +1599,16 @@ + * change the mask and then do an interrupt enable CPI to re-enable on + * the selected processors */ + +-void set_vic_irq_affinity(unsigned int irq, const struct cpumask *mask) ++void set_vic_irq_affinity(unsigned int irq, cpumask_t mask) + { + /* Only extended processors handle interrupts */ + unsigned long real_mask; + unsigned long irq_mask = 1 << irq; + int cpu; + +- real_mask = cpus_addr(*mask)[0] & voyager_extended_vic_processors; ++ real_mask = cpus_addr(mask)[0] & voyager_extended_vic_processors; + +- if (cpus_addr(*mask)[0] == 0) ++ if (cpus_addr(mask)[0] == 0) + /* can't have no CPUs to accept the interrupt -- extremely + * bad things will happen */ + return; +@@ -1748,11 +1750,10 @@ + init_gdt(smp_processor_id()); + switch_to_new_gdt(); + +- cpu_online_map = cpumask_of_cpu(smp_processor_id()); +- cpu_callout_map = cpumask_of_cpu(smp_processor_id()); +- cpu_callin_map = CPU_MASK_NONE; +- cpu_present_map = cpumask_of_cpu(smp_processor_id()); +- ++ cpu_set(smp_processor_id(), cpu_online_map); ++ cpu_set(smp_processor_id(), cpu_callout_map); ++ cpu_set(smp_processor_id(), cpu_possible_map); ++ cpu_set(smp_processor_id(), cpu_present_map); + } + + static int __cpuinit voyager_cpu_up(unsigned int cpu) +@@ -1782,9 +1783,9 @@ + x86_write_percpu(cpu_number, hard_smp_processor_id()); + } + +-static void voyager_send_call_func(const struct cpumask *callmask) ++static void voyager_send_call_func(cpumask_t callmask) + { +- __u32 mask = cpus_addr(*callmask)[0] & ~(1 << smp_processor_id()); ++ __u32 mask = cpus_addr(callmask)[0] & ~(1 << smp_processor_id()); + send_CPI(mask, VIC_CALL_FUNCTION_CPI); + } + +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/arch/x86/math-emu/fpu_aux.c linux-2.6.29-rc3.owrt/arch/x86/math-emu/fpu_aux.c +--- linux-2.6.29.owrt/arch/x86/math-emu/fpu_aux.c 2009-05-10 22:04:41.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/arch/x86/math-emu/fpu_aux.c 2009-05-10 23:48:28.000000000 +0200 +@@ -30,29 +30,20 @@ + } + + /* Needs to be externally visible */ +-void finit_task(struct task_struct *tsk) ++void finit(void) + { +- struct i387_soft_struct *soft = &tsk->thread.xstate->soft; +- struct address *oaddr, *iaddr; +- soft->cwd = 0x037f; +- soft->swd = 0; +- soft->ftop = 0; /* We don't keep top in the status word internally. */ +- soft->twd = 0xffff; ++ control_word = 0x037f; ++ partial_status = 0; ++ top = 0; /* We don't keep top in the status word internally. */ ++ fpu_tag_word = 0xffff; + /* The behaviour is different from that detailed in + Section 15.1.6 of the Intel manual */ +- oaddr = (struct address *)&soft->foo; +- oaddr->offset = 0; +- oaddr->selector = 0; +- iaddr = (struct address *)&soft->fip; +- iaddr->offset = 0; +- iaddr->selector = 0; +- iaddr->opcode = 0; +- soft->no_update = 1; +-} +- +-void finit(void) +-{ +- finit_task(current); ++ operand_address.offset = 0; ++ operand_address.selector = 0; ++ instruction_address.offset = 0; ++ instruction_address.selector = 0; ++ instruction_address.opcode = 0; ++ no_ip_update = 1; + } + + /* +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/arch/x86/math-emu/fpu_entry.c linux-2.6.29-rc3.owrt/arch/x86/math-emu/fpu_entry.c +--- linux-2.6.29.owrt/arch/x86/math-emu/fpu_entry.c 2009-05-10 22:04:41.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/arch/x86/math-emu/fpu_entry.c 2009-05-10 23:48:28.000000000 +0200 +@@ -131,7 +131,7 @@ + static int valid_prefix(u_char *Byte, u_char __user ** fpu_eip, + overrides * override); + +-void math_emulate(struct math_emu_info *info) ++asmlinkage void math_emulate(long arg) + { + u_char FPU_modrm, byte1; + unsigned short code; +@@ -161,7 +161,7 @@ + RE_ENTRANT_CHECK_ON; + #endif /* RE_ENTRANT_CHECKING */ + +- FPU_info = info; ++ SETUP_DATA_AREA(arg); + + FPU_ORIG_EIP = FPU_EIP; + +@@ -659,7 +659,7 @@ + } + } + +-void math_abort(struct math_emu_info *info, unsigned int signal) ++void math_abort(struct info *info, unsigned int signal) + { + FPU_EIP = FPU_ORIG_EIP; + current->thread.trap_no = 16; +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/arch/x86/math-emu/fpu_proto.h linux-2.6.29-rc3.owrt/arch/x86/math-emu/fpu_proto.h +--- linux-2.6.29.owrt/arch/x86/math-emu/fpu_proto.h 2009-05-10 22:04:41.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/arch/x86/math-emu/fpu_proto.h 2009-05-10 23:48:28.000000000 +0200 +@@ -51,8 +51,8 @@ + extern void fst_i_(void); + extern void fstp_i(void); + /* fpu_entry.c */ +-extern void math_emulate(struct math_emu_info *info); +-extern void math_abort(struct math_emu_info *info, unsigned int signal); ++asmlinkage extern void math_emulate(long arg); ++extern void math_abort(struct info *info, unsigned int signal); + /* fpu_etc.c */ + extern void FPU_etc(void); + /* fpu_tags.c */ +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/arch/x86/math-emu/fpu_system.h linux-2.6.29-rc3.owrt/arch/x86/math-emu/fpu_system.h +--- linux-2.6.29.owrt/arch/x86/math-emu/fpu_system.h 2009-05-10 22:04:41.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/arch/x86/math-emu/fpu_system.h 2009-05-10 23:48:28.000000000 +0200 +@@ -16,6 +16,10 @@ + #include <linux/kernel.h> + #include <linux/mm.h> + ++/* This sets the pointer FPU_info to point to the argument part ++ of the stack frame of math_emulate() */ ++#define SETUP_DATA_AREA(arg) FPU_info = (struct info *) &arg ++ + /* s is always from a cpu register, and the cpu does bounds checking + * during register load --> no further bounds checks needed */ + #define LDT_DESCRIPTOR(s) (((struct desc_struct *)current->mm->context.ldt)[(s) >> 3]) +@@ -34,12 +38,12 @@ + #define I387 (current->thread.xstate) + #define FPU_info (I387->soft.info) + +-#define FPU_CS (*(unsigned short *) &(FPU_info->regs->cs)) +-#define FPU_SS (*(unsigned short *) &(FPU_info->regs->ss)) +-#define FPU_DS (*(unsigned short *) &(FPU_info->regs->ds)) +-#define FPU_EAX (FPU_info->regs->ax) +-#define FPU_EFLAGS (FPU_info->regs->flags) +-#define FPU_EIP (FPU_info->regs->ip) ++#define FPU_CS (*(unsigned short *) &(FPU_info->___cs)) ++#define FPU_SS (*(unsigned short *) &(FPU_info->___ss)) ++#define FPU_DS (*(unsigned short *) &(FPU_info->___ds)) ++#define FPU_EAX (FPU_info->___eax) ++#define FPU_EFLAGS (FPU_info->___eflags) ++#define FPU_EIP (FPU_info->___eip) + #define FPU_ORIG_EIP (FPU_info->___orig_eip) + + #define FPU_lookahead (I387->soft.lookahead) +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/arch/x86/math-emu/get_address.c linux-2.6.29-rc3.owrt/arch/x86/math-emu/get_address.c +--- linux-2.6.29.owrt/arch/x86/math-emu/get_address.c 2009-05-10 22:04:41.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/arch/x86/math-emu/get_address.c 2009-05-10 23:48:28.000000000 +0200 +@@ -29,43 +29,46 @@ + #define FPU_WRITE_BIT 0x10 + + static int reg_offset[] = { +- offsetof(struct pt_regs, ax), +- offsetof(struct pt_regs, cx), +- offsetof(struct pt_regs, dx), +- offsetof(struct pt_regs, bx), +- offsetof(struct pt_regs, sp), +- offsetof(struct pt_regs, bp), +- offsetof(struct pt_regs, si), +- offsetof(struct pt_regs, di) ++ offsetof(struct info, ___eax), ++ offsetof(struct info, ___ecx), ++ offsetof(struct info, ___edx), ++ offsetof(struct info, ___ebx), ++ offsetof(struct info, ___esp), ++ offsetof(struct info, ___ebp), ++ offsetof(struct info, ___esi), ++ offsetof(struct info, ___edi) + }; + +-#define REG_(x) (*(long *)(reg_offset[(x)] + (u_char *)FPU_info->regs)) ++#define REG_(x) (*(long *)(reg_offset[(x)]+(u_char *) FPU_info)) + + static int reg_offset_vm86[] = { +- offsetof(struct pt_regs, cs), +- offsetof(struct kernel_vm86_regs, ds), +- offsetof(struct kernel_vm86_regs, es), +- offsetof(struct kernel_vm86_regs, fs), +- offsetof(struct kernel_vm86_regs, gs), +- offsetof(struct pt_regs, ss), +- offsetof(struct kernel_vm86_regs, ds) ++ offsetof(struct info, ___cs), ++ offsetof(struct info, ___vm86_ds), ++ offsetof(struct info, ___vm86_es), ++ offsetof(struct info, ___vm86_fs), ++ offsetof(struct info, ___vm86_gs), ++ offsetof(struct info, ___ss), ++ offsetof(struct info, ___vm86_ds) + }; + + #define VM86_REG_(x) (*(unsigned short *) \ +- (reg_offset_vm86[((unsigned)x)] + (u_char *)FPU_info->regs)) ++ (reg_offset_vm86[((unsigned)x)]+(u_char *) FPU_info)) ++ ++/* This dummy, gs is not saved on the stack. */ ++#define ___GS ___ds + + static int reg_offset_pm[] = { +- offsetof(struct pt_regs, cs), +- offsetof(struct pt_regs, ds), +- offsetof(struct pt_regs, es), +- offsetof(struct pt_regs, fs), +- offsetof(struct pt_regs, ds), /* dummy, not saved on stack */ +- offsetof(struct pt_regs, ss), +- offsetof(struct pt_regs, ds) ++ offsetof(struct info, ___cs), ++ offsetof(struct info, ___ds), ++ offsetof(struct info, ___es), ++ offsetof(struct info, ___fs), ++ offsetof(struct info, ___GS), ++ offsetof(struct info, ___ss), ++ offsetof(struct info, ___ds) + }; + + #define PM_REG_(x) (*(unsigned short *) \ +- (reg_offset_pm[((unsigned)x)] + (u_char *)FPU_info->regs)) ++ (reg_offset_pm[((unsigned)x)]+(u_char *) FPU_info)) + + /* Decode the SIB byte. This function assumes mod != 0 */ + static int sib(int mod, unsigned long *fpu_eip) +@@ -346,34 +349,34 @@ + } + switch (rm) { + case 0: +- address += FPU_info->regs->bx + FPU_info->regs->si; ++ address += FPU_info->___ebx + FPU_info->___esi; + break; + case 1: +- address += FPU_info->regs->bx + FPU_info->regs->di; ++ address += FPU_info->___ebx + FPU_info->___edi; + break; + case 2: +- address += FPU_info->regs->bp + FPU_info->regs->si; ++ address += FPU_info->___ebp + FPU_info->___esi; + if (addr_modes.override.segment == PREFIX_DEFAULT) + addr_modes.override.segment = PREFIX_SS_; + break; + case 3: +- address += FPU_info->regs->bp + FPU_info->regs->di; ++ address += FPU_info->___ebp + FPU_info->___edi; + if (addr_modes.override.segment == PREFIX_DEFAULT) + addr_modes.override.segment = PREFIX_SS_; + break; + case 4: +- address += FPU_info->regs->si; ++ address += FPU_info->___esi; + break; + case 5: +- address += FPU_info->regs->di; ++ address += FPU_info->___edi; + break; + case 6: +- address += FPU_info->regs->bp; ++ address += FPU_info->___ebp; + if (addr_modes.override.segment == PREFIX_DEFAULT) + addr_modes.override.segment = PREFIX_SS_; + break; + case 7: +- address += FPU_info->regs->bx; ++ address += FPU_info->___ebx; + break; + } + +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/arch/x86/mm/fault.c linux-2.6.29-rc3.owrt/arch/x86/mm/fault.c +--- linux-2.6.29.owrt/arch/x86/mm/fault.c 2009-05-10 22:04:41.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/arch/x86/mm/fault.c 2009-05-10 23:48:28.000000000 +0200 +@@ -603,6 +603,8 @@ + + si_code = SEGV_MAPERR; + ++ if (notify_page_fault(regs)) ++ return; + if (unlikely(kmmio_fault(regs, address))) + return; + +@@ -632,9 +634,6 @@ + if (spurious_fault(address, error_code)) + return; + +- /* kprobes don't want to hook the spurious faults. */ +- if (notify_page_fault(regs)) +- return; + /* + * Don't take the mm semaphore here. If we fixup a prefetch + * fault we could otherwise deadlock. +@@ -642,9 +641,6 @@ + goto bad_area_nosemaphore; + } + +- /* kprobes don't want to hook the spurious faults. */ +- if (notify_page_fault(regs)) +- return; + + /* + * It's safe to allow irq's after cr2 has been saved and the +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/arch/x86/mm/init_64.c linux-2.6.29-rc3.owrt/arch/x86/mm/init_64.c +--- linux-2.6.29.owrt/arch/x86/mm/init_64.c 2009-05-10 22:04:41.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/arch/x86/mm/init_64.c 2009-05-10 23:48:28.000000000 +0200 +@@ -714,8 +714,6 @@ + pos = start_pfn << PAGE_SHIFT; + end_pfn = ((pos + (PMD_SIZE - 1)) >> PMD_SHIFT) + << (PMD_SHIFT - PAGE_SHIFT); +- if (end_pfn > (end >> PAGE_SHIFT)) +- end_pfn = end >> PAGE_SHIFT; + if (start_pfn < end_pfn) { + nr_range = save_mr(mr, nr_range, start_pfn, end_pfn, 0); + pos = end_pfn << PAGE_SHIFT; +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/arch/x86/mm/iomap_32.c linux-2.6.29-rc3.owrt/arch/x86/mm/iomap_32.c +--- linux-2.6.29.owrt/arch/x86/mm/iomap_32.c 2009-05-10 22:04:41.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/arch/x86/mm/iomap_32.c 2009-05-10 23:48:28.000000000 +0200 +@@ -20,17 +20,6 @@ + #include <asm/pat.h> + #include <linux/module.h> + +-int is_io_mapping_possible(resource_size_t base, unsigned long size) +-{ +-#ifndef CONFIG_X86_PAE +- /* There is no way to map greater than 1 << 32 address without PAE */ +- if (base + size > 0x100000000ULL) +- return 0; +-#endif +- return 1; +-} +-EXPORT_SYMBOL_GPL(is_io_mapping_possible); +- + /* Map 'pfn' using fixed map 'type' and protections 'prot' + */ + void * +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/arch/x86/mm/ioremap.c linux-2.6.29-rc3.owrt/arch/x86/mm/ioremap.c +--- linux-2.6.29.owrt/arch/x86/mm/ioremap.c 2009-05-10 22:04:41.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/arch/x86/mm/ioremap.c 2009-05-10 23:48:28.000000000 +0200 +@@ -134,6 +134,25 @@ + return 0; + } + ++int pagerange_is_ram(unsigned long start, unsigned long end) ++{ ++ int ram_page = 0, not_rampage = 0; ++ unsigned long page_nr; ++ ++ for (page_nr = (start >> PAGE_SHIFT); page_nr < (end >> PAGE_SHIFT); ++ ++page_nr) { ++ if (page_is_ram(page_nr)) ++ ram_page = 1; ++ else ++ not_rampage = 1; ++ ++ if (ram_page == not_rampage) ++ return -1; ++ } ++ ++ return ram_page; ++} ++ + /* + * Fix up the linear direct mapping of the kernel to avoid cache attribute + * conflicts. +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/arch/x86/mm/kmmio.c linux-2.6.29-rc3.owrt/arch/x86/mm/kmmio.c +--- linux-2.6.29.owrt/arch/x86/mm/kmmio.c 2009-05-10 22:04:41.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/arch/x86/mm/kmmio.c 2009-05-10 23:48:28.000000000 +0200 +@@ -32,14 +32,11 @@ + struct list_head list; + struct kmmio_fault_page *release_next; + unsigned long page; /* location of the fault page */ +- bool old_presence; /* page presence prior to arming */ +- bool armed; + + /* + * Number of times this page has been registered as a part + * of a probe. If zero, page is disarmed and this may be freed. +- * Used only by writers (RCU) and post_kmmio_handler(). +- * Protected by kmmio_lock, when linked into kmmio_page_table. ++ * Used only by writers (RCU). + */ + int count; + }; +@@ -108,85 +105,57 @@ + return NULL; + } + +-static void set_pmd_presence(pmd_t *pmd, bool present, bool *old) +-{ +- pmdval_t v = pmd_val(*pmd); +- *old = !!(v & _PAGE_PRESENT); +- v &= ~_PAGE_PRESENT; +- if (present) +- v |= _PAGE_PRESENT; +- set_pmd(pmd, __pmd(v)); +-} +- +-static void set_pte_presence(pte_t *pte, bool present, bool *old) +-{ +- pteval_t v = pte_val(*pte); +- *old = !!(v & _PAGE_PRESENT); +- v &= ~_PAGE_PRESENT; +- if (present) +- v |= _PAGE_PRESENT; +- set_pte_atomic(pte, __pte(v)); +-} +- +-static int set_page_presence(unsigned long addr, bool present, bool *old) ++static void set_page_present(unsigned long addr, bool present, ++ unsigned int *pglevel) + { ++ pteval_t pteval; ++ pmdval_t pmdval; + unsigned int level; ++ pmd_t *pmd; + pte_t *pte = lookup_address(addr, &level); + + if (!pte) { + pr_err("kmmio: no pte for page 0x%08lx\n", addr); +- return -1; ++ return; + } + ++ if (pglevel) ++ *pglevel = level; ++ + switch (level) { + case PG_LEVEL_2M: +- set_pmd_presence((pmd_t *)pte, present, old); ++ pmd = (pmd_t *)pte; ++ pmdval = pmd_val(*pmd) & ~_PAGE_PRESENT; ++ if (present) ++ pmdval |= _PAGE_PRESENT; ++ set_pmd(pmd, __pmd(pmdval)); + break; ++ + case PG_LEVEL_4K: +- set_pte_presence(pte, present, old); ++ pteval = pte_val(*pte) & ~_PAGE_PRESENT; ++ if (present) ++ pteval |= _PAGE_PRESENT; ++ set_pte_atomic(pte, __pte(pteval)); + break; ++ + default: + pr_err("kmmio: unexpected page level 0x%x.\n", level); +- return -1; ++ return; + } + + __flush_tlb_one(addr); +- return 0; + } + +-/* +- * Mark the given page as not present. Access to it will trigger a fault. +- * +- * Struct kmmio_fault_page is protected by RCU and kmmio_lock, but the +- * protection is ignored here. RCU read lock is assumed held, so the struct +- * will not disappear unexpectedly. Furthermore, the caller must guarantee, +- * that double arming the same virtual address (page) cannot occur. +- * +- * Double disarming on the other hand is allowed, and may occur when a fault +- * and mmiotrace shutdown happen simultaneously. +- */ +-static int arm_kmmio_fault_page(struct kmmio_fault_page *f) ++/** Mark the given page as not present. Access to it will trigger a fault. */ ++static void arm_kmmio_fault_page(unsigned long page, unsigned int *pglevel) + { +- int ret; +- WARN_ONCE(f->armed, KERN_ERR "kmmio page already armed.\n"); +- if (f->armed) { +- pr_warning("kmmio double-arm: page 0x%08lx, ref %d, old %d\n", +- f->page, f->count, f->old_presence); +- } +- ret = set_page_presence(f->page, false, &f->old_presence); +- WARN_ONCE(ret < 0, KERN_ERR "kmmio arming 0x%08lx failed.\n", f->page); +- f->armed = true; +- return ret; ++ set_page_present(page & PAGE_MASK, false, pglevel); + } + +-/** Restore the given page to saved presence state. */ +-static void disarm_kmmio_fault_page(struct kmmio_fault_page *f) ++/** Mark the given page as present. */ ++static void disarm_kmmio_fault_page(unsigned long page, unsigned int *pglevel) + { +- bool tmp; +- int ret = set_page_presence(f->page, f->old_presence, &tmp); +- WARN_ONCE(ret < 0, +- KERN_ERR "kmmio disarming 0x%08lx failed.\n", f->page); +- f->armed = false; ++ set_page_present(page & PAGE_MASK, true, pglevel); + } + + /* +@@ -233,32 +202,28 @@ + + ctx = &get_cpu_var(kmmio_ctx); + if (ctx->active) { ++ disarm_kmmio_fault_page(faultpage->page, NULL); + if (addr == ctx->addr) { + /* +- * A second fault on the same page means some other +- * condition needs handling by do_page_fault(), the +- * page really not being present is the most common. ++ * On SMP we sometimes get recursive probe hits on the ++ * same address. Context is already saved, fall out. + */ +- pr_debug("kmmio: secondary hit for 0x%08lx CPU %d.\n", +- addr, smp_processor_id()); +- +- if (!faultpage->old_presence) +- pr_info("kmmio: unexpected secondary hit for " +- "address 0x%08lx on CPU %d.\n", addr, +- smp_processor_id()); +- } else { +- /* +- * Prevent overwriting already in-flight context. +- * This should not happen, let's hope disarming at +- * least prevents a panic. +- */ +- pr_emerg("kmmio: recursive probe hit on CPU %d, " ++ pr_debug("kmmio: duplicate probe hit on CPU %d, for " ++ "address 0x%08lx.\n", ++ smp_processor_id(), addr); ++ ret = 1; ++ goto no_kmmio_ctx; ++ } ++ /* ++ * Prevent overwriting already in-flight context. ++ * This should not happen, let's hope disarming at least ++ * prevents a panic. ++ */ ++ pr_emerg("kmmio: recursive probe hit on CPU %d, " + "for address 0x%08lx. Ignoring.\n", + smp_processor_id(), addr); +- pr_emerg("kmmio: previous hit was at 0x%08lx.\n", +- ctx->addr); +- disarm_kmmio_fault_page(faultpage); +- } ++ pr_emerg("kmmio: previous hit was at 0x%08lx.\n", ++ ctx->addr); + goto no_kmmio_ctx; + } + ctx->active++; +@@ -279,7 +244,7 @@ + regs->flags &= ~X86_EFLAGS_IF; + + /* Now we set present bit in PTE and single step. */ +- disarm_kmmio_fault_page(ctx->fpage); ++ disarm_kmmio_fault_page(ctx->fpage->page, NULL); + + /* + * If another cpu accesses the same page while we are stepping, +@@ -310,7 +275,7 @@ + struct kmmio_context *ctx = &get_cpu_var(kmmio_ctx); + + if (!ctx->active) { +- pr_warning("kmmio: spurious debug trap on CPU %d.\n", ++ pr_debug("kmmio: spurious debug trap on CPU %d.\n", + smp_processor_id()); + goto out; + } +@@ -318,11 +283,7 @@ + if (ctx->probe && ctx->probe->post_handler) + ctx->probe->post_handler(ctx->probe, condition, regs); + +- /* Prevent racing against release_kmmio_fault_page(). */ +- spin_lock(&kmmio_lock); +- if (ctx->fpage->count) +- arm_kmmio_fault_page(ctx->fpage); +- spin_unlock(&kmmio_lock); ++ arm_kmmio_fault_page(ctx->fpage->page, NULL); + + regs->flags &= ~X86_EFLAGS_TF; + regs->flags |= ctx->saved_flags; +@@ -354,25 +315,21 @@ + f = get_kmmio_fault_page(page); + if (f) { + if (!f->count) +- arm_kmmio_fault_page(f); ++ arm_kmmio_fault_page(f->page, NULL); + f->count++; + return 0; + } + +- f = kzalloc(sizeof(*f), GFP_ATOMIC); ++ f = kmalloc(sizeof(*f), GFP_ATOMIC); + if (!f) + return -1; + + f->count = 1; + f->page = page; +- +- if (arm_kmmio_fault_page(f)) { +- kfree(f); +- return -1; +- } +- + list_add_rcu(&f->list, kmmio_page_list(f->page)); + ++ arm_kmmio_fault_page(f->page, NULL); ++ + return 0; + } + +@@ -390,7 +347,7 @@ + f->count--; + BUG_ON(f->count < 0); + if (!f->count) { +- disarm_kmmio_fault_page(f); ++ disarm_kmmio_fault_page(f->page, NULL); + f->release_next = *release_list; + *release_list = f; + } +@@ -451,24 +408,23 @@ + + static void remove_kmmio_fault_pages(struct rcu_head *head) + { +- struct kmmio_delayed_release *dr = +- container_of(head, struct kmmio_delayed_release, rcu); ++ struct kmmio_delayed_release *dr = container_of( ++ head, ++ struct kmmio_delayed_release, ++ rcu); + struct kmmio_fault_page *p = dr->release_list; + struct kmmio_fault_page **prevp = &dr->release_list; + unsigned long flags; +- + spin_lock_irqsave(&kmmio_lock, flags); + while (p) { +- if (!p->count) { ++ if (!p->count) + list_del_rcu(&p->list); +- prevp = &p->release_next; +- } else { ++ else + *prevp = p->release_next; +- } ++ prevp = &p->release_next; + p = p->release_next; + } + spin_unlock_irqrestore(&kmmio_lock, flags); +- + /* This is the real RCU destroy call. */ + call_rcu(&dr->rcu, rcu_free_kmmio_fault_pages); + } +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/arch/x86/mm/numa_64.c linux-2.6.29-rc3.owrt/arch/x86/mm/numa_64.c +--- linux-2.6.29.owrt/arch/x86/mm/numa_64.c 2009-05-10 22:04:41.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/arch/x86/mm/numa_64.c 2009-05-10 23:48:28.000000000 +0200 +@@ -145,7 +145,7 @@ + return shift; + } + +-int __meminit __early_pfn_to_nid(unsigned long pfn) ++int early_pfn_to_nid(unsigned long pfn) + { + return phys_to_nid(pfn << PAGE_SHIFT); + } +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/arch/x86/mm/pageattr.c linux-2.6.29-rc3.owrt/arch/x86/mm/pageattr.c +--- linux-2.6.29.owrt/arch/x86/mm/pageattr.c 2009-05-10 22:04:41.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/arch/x86/mm/pageattr.c 2009-05-10 23:48:28.000000000 +0200 +@@ -508,24 +508,18 @@ + #endif + + /* +- * Install the new, split up pagetable. ++ * Install the new, split up pagetable. Important details here: + * +- * We use the standard kernel pagetable protections for the new +- * pagetable protections, the actual ptes set above control the +- * primary protection behavior: +- */ +- __set_pmd_pte(kpte, address, mk_pte(base, __pgprot(_KERNPG_TABLE))); +- +- /* +- * Intel Atom errata AAH41 workaround. ++ * On Intel the NX bit of all levels must be cleared to make a ++ * page executable. See section 4.13.2 of Intel 64 and IA-32 ++ * Architectures Software Developer's Manual). + * +- * The real fix should be in hw or in a microcode update, but +- * we also probabilistically try to reduce the window of having +- * a large TLB mixed with 4K TLBs while instruction fetches are +- * going on. ++ * Mark the entry present. The current mapping might be ++ * set to not present, which we preserved above. + */ +- __flush_tlb_all(); +- ++ ref_prot = pte_pgprot(pte_mkexec(pte_clrhuge(*kpte))); ++ pgprot_val(ref_prot) |= _PAGE_PRESENT; ++ __set_pmd_pte(kpte, address, mk_pte(base, ref_prot)); + base = NULL; + + out_unlock: +@@ -581,6 +575,7 @@ + address = cpa->vaddr[cpa->curpage]; + else + address = *cpa->vaddr; ++ + repeat: + kpte = lookup_address(address, &level); + if (!kpte) +@@ -817,13 +812,6 @@ + + vm_unmap_aliases(); + +- /* +- * If we're called with lazy mmu updates enabled, the +- * in-memory pte state may be stale. Flush pending updates to +- * bring them up to date. +- */ +- arch_flush_lazy_mmu_mode(); +- + cpa.vaddr = addr; + cpa.numpages = numpages; + cpa.mask_set = mask_set; +@@ -866,13 +854,6 @@ + } else + cpa_flush_all(cache); + +- /* +- * If we've been called with lazy mmu updates enabled, then +- * make sure that everything gets flushed out before we +- * return. +- */ +- arch_flush_lazy_mmu_mode(); +- + out: + return ret; + } +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/arch/x86/mm/pat.c linux-2.6.29-rc3.owrt/arch/x86/mm/pat.c +--- linux-2.6.29.owrt/arch/x86/mm/pat.c 2009-05-10 22:04:41.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/arch/x86/mm/pat.c 2009-05-10 23:48:28.000000000 +0200 +@@ -11,7 +11,6 @@ + #include <linux/bootmem.h> + #include <linux/debugfs.h> + #include <linux/kernel.h> +-#include <linux/module.h> + #include <linux/gfp.h> + #include <linux/mm.h> + #include <linux/fs.h> +@@ -212,33 +211,6 @@ + static struct memtype *cached_entry; + static u64 cached_start; + +-static int pat_pagerange_is_ram(unsigned long start, unsigned long end) +-{ +- int ram_page = 0, not_rampage = 0; +- unsigned long page_nr; +- +- for (page_nr = (start >> PAGE_SHIFT); page_nr < (end >> PAGE_SHIFT); +- ++page_nr) { +- /* +- * For legacy reasons, physical address range in the legacy ISA +- * region is tracked as non-RAM. This will allow users of +- * /dev/mem to map portions of legacy ISA region, even when +- * some of those portions are listed(or not even listed) with +- * different e820 types(RAM/reserved/..) +- */ +- if (page_nr >= (ISA_END_ADDRESS >> PAGE_SHIFT) && +- page_is_ram(page_nr)) +- ram_page = 1; +- else +- not_rampage = 1; +- +- if (ram_page == not_rampage) +- return -1; +- } +- +- return ram_page; +-} +- + /* + * For RAM pages, mark the pages as non WB memory type using + * PageNonWB (PG_arch_1). We allow only one set_memory_uc() or +@@ -364,12 +336,20 @@ + if (new_type) + *new_type = actual_type; + +- is_range_ram = pat_pagerange_is_ram(start, end); +- if (is_range_ram == 1) +- return reserve_ram_pages_type(start, end, req_type, +- new_type); +- else if (is_range_ram < 0) +- return -EINVAL; ++ /* ++ * For legacy reasons, some parts of the physical address range in the ++ * legacy 1MB region is treated as non-RAM (even when listed as RAM in ++ * the e820 tables). So we will track the memory attributes of this ++ * legacy 1MB region using the linear memtype_list always. ++ */ ++ if (end >= ISA_END_ADDRESS) { ++ is_range_ram = pagerange_is_ram(start, end); ++ if (is_range_ram == 1) ++ return reserve_ram_pages_type(start, end, req_type, ++ new_type); ++ else if (is_range_ram < 0) ++ return -EINVAL; ++ } + + new = kmalloc(sizeof(struct memtype), GFP_KERNEL); + if (!new) +@@ -466,11 +446,19 @@ + if (is_ISA_range(start, end - 1)) + return 0; + +- is_range_ram = pat_pagerange_is_ram(start, end); +- if (is_range_ram == 1) +- return free_ram_pages_type(start, end); +- else if (is_range_ram < 0) +- return -EINVAL; ++ /* ++ * For legacy reasons, some parts of the physical address range in the ++ * legacy 1MB region is treated as non-RAM (even when listed as RAM in ++ * the e820 tables). So we will track the memory attributes of this ++ * legacy 1MB region using the linear memtype_list always. ++ */ ++ if (end >= ISA_END_ADDRESS) { ++ is_range_ram = pagerange_is_ram(start, end); ++ if (is_range_ram == 1) ++ return free_ram_pages_type(start, end); ++ else if (is_range_ram < 0) ++ return -EINVAL; ++ } + + spin_lock(&memtype_lock); + list_for_each_entry(entry, &memtype_list, nd) { +@@ -638,13 +626,17 @@ + unsigned long flags; + unsigned long want_flags = (pgprot_val(*vma_prot) & _PAGE_CACHE_MASK); + +- is_ram = pat_pagerange_is_ram(paddr, paddr + size); ++ is_ram = pagerange_is_ram(paddr, paddr + size); + +- /* +- * reserve_pfn_range() doesn't support RAM pages. +- */ +- if (is_ram != 0) +- return -EINVAL; ++ if (is_ram != 0) { ++ /* ++ * For mapping RAM pages, drivers need to call ++ * set_memory_[uc|wc|wb] directly, for reserve and free, before ++ * setting up the PTE. ++ */ ++ WARN_ON_ONCE(1); ++ return 0; ++ } + + ret = reserve_memtype(paddr, paddr + size, want_flags, &flags); + if (ret) +@@ -701,7 +693,7 @@ + { + int is_ram; + +- is_ram = pat_pagerange_is_ram(paddr, paddr + size); ++ is_ram = pagerange_is_ram(paddr, paddr + size); + if (is_ram == 0) + free_memtype(paddr, paddr + size); + } +@@ -869,7 +861,6 @@ + else + return pgprot_noncached(prot); + } +-EXPORT_SYMBOL_GPL(pgprot_writecombine); + + #if defined(CONFIG_DEBUG_FS) && defined(CONFIG_X86_PAT) + +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/arch/x86/mm/testmmiotrace.c linux-2.6.29-rc3.owrt/arch/x86/mm/testmmiotrace.c +--- linux-2.6.29.owrt/arch/x86/mm/testmmiotrace.c 2009-05-10 22:04:41.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/arch/x86/mm/testmmiotrace.c 2009-05-10 23:48:28.000000000 +0200 +@@ -1,5 +1,5 @@ + /* +- * Written by Pekka Paalanen, 2008-2009 <pq@iki.fi> ++ * Written by Pekka Paalanen, 2008 <pq@iki.fi> + */ + #include <linux/module.h> + #include <linux/io.h> +@@ -9,74 +9,35 @@ + + static unsigned long mmio_address; + module_param(mmio_address, ulong, 0); +-MODULE_PARM_DESC(mmio_address, " Start address of the mapping of 16 kB " +- "(or 8 MB if read_far is non-zero)."); +- +-static unsigned long read_far = 0x400100; +-module_param(read_far, ulong, 0); +-MODULE_PARM_DESC(read_far, " Offset of a 32-bit read within 8 MB " +- "(default: 0x400100)."); +- +-static unsigned v16(unsigned i) +-{ +- return i * 12 + 7; +-} +- +-static unsigned v32(unsigned i) +-{ +- return i * 212371 + 13; +-} ++MODULE_PARM_DESC(mmio_address, "Start address of the mapping of 16 kB."); + + static void do_write_test(void __iomem *p) + { + unsigned int i; +- pr_info(MODULE_NAME ": write test.\n"); + mmiotrace_printk("Write test.\n"); +- + for (i = 0; i < 256; i++) + iowrite8(i, p + i); +- + for (i = 1024; i < (5 * 1024); i += 2) +- iowrite16(v16(i), p + i); +- ++ iowrite16(i * 12 + 7, p + i); + for (i = (5 * 1024); i < (16 * 1024); i += 4) +- iowrite32(v32(i), p + i); ++ iowrite32(i * 212371 + 13, p + i); + } + + static void do_read_test(void __iomem *p) + { + unsigned int i; +- unsigned errs[3] = { 0 }; +- pr_info(MODULE_NAME ": read test.\n"); + mmiotrace_printk("Read test.\n"); +- + for (i = 0; i < 256; i++) +- if (ioread8(p + i) != i) +- ++errs[0]; +- ++ ioread8(p + i); + for (i = 1024; i < (5 * 1024); i += 2) +- if (ioread16(p + i) != v16(i)) +- ++errs[1]; +- ++ ioread16(p + i); + for (i = (5 * 1024); i < (16 * 1024); i += 4) +- if (ioread32(p + i) != v32(i)) +- ++errs[2]; +- +- mmiotrace_printk("Read errors: 8-bit %d, 16-bit %d, 32-bit %d.\n", +- errs[0], errs[1], errs[2]); ++ ioread32(p + i); + } + +-static void do_read_far_test(void __iomem *p) ++static void do_test(void) + { +- pr_info(MODULE_NAME ": read far test.\n"); +- mmiotrace_printk("Read far test.\n"); +- +- ioread32(p + read_far); +-} +- +-static void do_test(unsigned long size) +-{ +- void __iomem *p = ioremap_nocache(mmio_address, size); ++ void __iomem *p = ioremap_nocache(mmio_address, 0x4000); + if (!p) { + pr_err(MODULE_NAME ": could not ioremap, aborting.\n"); + return; +@@ -84,15 +45,11 @@ + mmiotrace_printk("ioremap returned %p.\n", p); + do_write_test(p); + do_read_test(p); +- if (read_far && read_far < size - 4) +- do_read_far_test(p); + iounmap(p); + } + + static int __init init(void) + { +- unsigned long size = (read_far) ? (8 << 20) : (16 << 10); +- + if (mmio_address == 0) { + pr_err(MODULE_NAME ": you have to use the module argument " + "mmio_address.\n"); +@@ -101,11 +58,10 @@ + return -ENXIO; + } + +- pr_warning(MODULE_NAME ": WARNING: mapping %lu kB @ 0x%08lx in PCI " +- "address space, and writing 16 kB of rubbish in there.\n", +- size >> 10, mmio_address); +- do_test(size); +- pr_info(MODULE_NAME ": All done.\n"); ++ pr_warning(MODULE_NAME ": WARNING: mapping 16 kB @ 0x%08lx " ++ "in PCI address space, and writing " ++ "rubbish in there.\n", mmio_address); ++ do_test(); + return 0; + } + +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/arch/x86/oprofile/op_model_ppro.c linux-2.6.29-rc3.owrt/arch/x86/oprofile/op_model_ppro.c +--- linux-2.6.29.owrt/arch/x86/oprofile/op_model_ppro.c 2009-05-10 22:04:41.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/arch/x86/oprofile/op_model_ppro.c 2009-05-10 23:48:28.000000000 +0200 +@@ -78,18 +78,8 @@ + if (cpu_has_arch_perfmon) { + union cpuid10_eax eax; + eax.full = cpuid_eax(0xa); +- +- /* +- * For Core2 (family 6, model 15), don't reset the +- * counter width: +- */ +- if (!(eax.split.version_id == 0 && +- current_cpu_data.x86 == 6 && +- current_cpu_data.x86_model == 15)) { +- +- if (counter_width < eax.split.bit_width) +- counter_width = eax.split.bit_width; +- } ++ if (counter_width < eax.split.bit_width) ++ counter_width = eax.split.bit_width; + } + + /* clear all counters */ +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/arch/x86/pci/irq.c linux-2.6.29-rc3.owrt/arch/x86/pci/irq.c +--- linux-2.6.29.owrt/arch/x86/pci/irq.c 2009-05-10 22:04:41.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/arch/x86/pci/irq.c 2009-05-10 23:48:28.000000000 +0200 +@@ -572,7 +572,6 @@ + case PCI_DEVICE_ID_INTEL_ICH7_1: + case PCI_DEVICE_ID_INTEL_ICH7_30: + case PCI_DEVICE_ID_INTEL_ICH7_31: +- case PCI_DEVICE_ID_INTEL_TGP_LPC: + case PCI_DEVICE_ID_INTEL_ESB2_0: + case PCI_DEVICE_ID_INTEL_ICH8_0: + case PCI_DEVICE_ID_INTEL_ICH8_1: +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/arch/x86/xen/enlighten.c linux-2.6.29-rc3.owrt/arch/x86/xen/enlighten.c +--- linux-2.6.29.owrt/arch/x86/xen/enlighten.c 2009-05-10 22:04:41.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/arch/x86/xen/enlighten.c 2009-05-10 23:48:28.000000000 +0200 +@@ -1672,9 +1672,6 @@ + possible map and a non-dummy shared_info. */ + per_cpu(xen_vcpu, 0) = &HYPERVISOR_shared_info->vcpu_info[0]; + +- local_irq_disable(); +- early_boot_irqs_off(); +- + xen_raw_console_write("mapping kernel into physical memory\n"); + pgd = xen_setup_kernel_pagetable(pgd, xen_start_info->nr_pages); + +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/arch/x86/xen/multicalls.h linux-2.6.29-rc3.owrt/arch/x86/xen/multicalls.h +--- linux-2.6.29.owrt/arch/x86/xen/multicalls.h 2009-05-10 22:04:41.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/arch/x86/xen/multicalls.h 2009-05-10 23:48:28.000000000 +0200 +@@ -19,10 +19,8 @@ + paired with xen_mc_issue() */ + static inline void xen_mc_batch(void) + { +- unsigned long flags; + /* need to disable interrupts until this entry is complete */ +- local_irq_save(flags); +- __get_cpu_var(xen_mc_irq_flags) = flags; ++ local_irq_save(__get_cpu_var(xen_mc_irq_flags)); + } + + static inline struct multicall_space xen_mc_entry(size_t args) +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/arch/xtensa/Kconfig linux-2.6.29-rc3.owrt/arch/xtensa/Kconfig +--- linux-2.6.29.owrt/arch/xtensa/Kconfig 2009-05-10 22:04:41.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/arch/xtensa/Kconfig 2009-05-10 23:48:28.000000000 +0200 +@@ -103,6 +103,9 @@ + help + Can we use information of configuration file? + ++config HIGHMEM ++ bool "High memory support" ++ + endmenu + + menu "Platform options" +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/arch/xtensa/kernel/setup.c linux-2.6.29-rc3.owrt/arch/xtensa/kernel/setup.c +--- linux-2.6.29.owrt/arch/xtensa/kernel/setup.c 2009-05-10 22:04:41.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/arch/xtensa/kernel/setup.c 2009-05-10 23:48:28.000000000 +0200 +@@ -44,8 +44,6 @@ + #include <asm/setup.h> + #include <asm/param.h> + +-#include <platform/hardware.h> +- + #if defined(CONFIG_VGA_CONSOLE) || defined(CONFIG_DUMMY_CONSOLE) + struct screen_info screen_info = { 0, 24, 0, 0, 0, 80, 0, 0, 0, 24, 1, 16}; + #endif +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/arch/xtensa/kernel/traps.c linux-2.6.29-rc3.owrt/arch/xtensa/kernel/traps.c +--- linux-2.6.29.owrt/arch/xtensa/kernel/traps.c 2009-05-10 22:04:41.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/arch/xtensa/kernel/traps.c 2009-05-10 23:48:28.000000000 +0200 +@@ -30,7 +30,6 @@ + #include <linux/stringify.h> + #include <linux/kallsyms.h> + #include <linux/delay.h> +-#include <linux/hardirq.h> + + #include <asm/ptrace.h> + #include <asm/timex.h> +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/arch/xtensa/mm/fault.c linux-2.6.29-rc3.owrt/arch/xtensa/mm/fault.c +--- linux-2.6.29.owrt/arch/xtensa/mm/fault.c 2009-05-10 22:04:41.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/arch/xtensa/mm/fault.c 2009-05-10 23:48:28.000000000 +0200 +@@ -14,7 +14,6 @@ + + #include <linux/mm.h> + #include <linux/module.h> +-#include <linux/hardirq.h> + #include <asm/mmu_context.h> + #include <asm/cacheflush.h> + #include <asm/hardirq.h> +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/arch/xtensa/platforms/iss/console.c linux-2.6.29-rc3.owrt/arch/xtensa/platforms/iss/console.c +--- linux-2.6.29.owrt/arch/xtensa/platforms/iss/console.c 2009-05-10 22:04:41.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/arch/xtensa/platforms/iss/console.c 2009-05-10 23:48:28.000000000 +0200 +@@ -140,14 +140,16 @@ + } + + +-static int rs_put_char(struct tty_struct *tty, unsigned char ch) ++static void rs_put_char(struct tty_struct *tty, unsigned char ch) + { + char buf[2]; + ++ if (!tty) ++ return; ++ + buf[0] = ch; + buf[1] = '\0'; /* Is this NULL necessary? */ + __simc (SYS_write, 1, (unsigned long) buf, 1, 0, 0); +- return 1; + } + + static void rs_flush_chars(struct tty_struct *tty) +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/block/blk-barrier.c linux-2.6.29-rc3.owrt/block/blk-barrier.c +--- linux-2.6.29.owrt/block/blk-barrier.c 2009-05-10 22:04:39.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/block/blk-barrier.c 2009-05-10 23:48:28.000000000 +0200 +@@ -302,7 +302,7 @@ + * Description: + * Issue a flush for the block device in question. Caller can supply + * room for storing the error offset in case of a flush error, if they +- * wish to. ++ * wish to. Caller must run wait_for_completion() on its own. + */ + int blkdev_issue_flush(struct block_device *bdev, sector_t *error_sector) + { +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/block/blk-core.c linux-2.6.29-rc3.owrt/block/blk-core.c +--- linux-2.6.29.owrt/block/blk-core.c 2009-05-10 22:04:39.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/block/blk-core.c 2009-05-10 23:48:28.000000000 +0200 +@@ -64,12 +64,11 @@ + + static void drive_stat_acct(struct request *rq, int new_io) + { +- struct gendisk *disk = rq->rq_disk; + struct hd_struct *part; + int rw = rq_data_dir(rq); + int cpu; + +- if (!blk_fs_request(rq) || !disk || !blk_do_io_stat(disk->queue)) ++ if (!blk_fs_request(rq) || !rq->rq_disk) + return; + + cpu = part_stat_lock(); +@@ -600,7 +599,8 @@ + q->request_fn = rfn; + q->prep_rq_fn = NULL; + q->unplug_fn = generic_unplug_device; +- q->queue_flags = QUEUE_FLAG_DEFAULT; ++ q->queue_flags = (1 << QUEUE_FLAG_CLUSTER | ++ 1 << QUEUE_FLAG_STACKABLE); + q->queue_lock = lock; + + blk_queue_segment_boundary(q, BLK_SEG_BOUNDARY_MASK); +@@ -1125,8 +1125,6 @@ + + if (bio_sync(bio)) + req->cmd_flags |= REQ_RW_SYNC; +- if (bio_unplug(bio)) +- req->cmd_flags |= REQ_UNPLUG; + if (bio_rw_meta(bio)) + req->cmd_flags |= REQ_RW_META; + +@@ -1143,7 +1141,6 @@ + int el_ret, nr_sectors; + const unsigned short prio = bio_prio(bio); + const int sync = bio_sync(bio); +- const int unplug = bio_unplug(bio); + int rw_flags; + + nr_sectors = bio_sectors(bio); +@@ -1247,7 +1244,7 @@ + blk_plug_device(q); + add_request(q, req); + out: +- if (unplug || blk_queue_nonrot(q)) ++ if (sync || blk_queue_nonrot(q)) + __generic_unplug_device(q); + spin_unlock_irq(q->queue_lock); + return 0; +@@ -1451,11 +1448,6 @@ + err = -EOPNOTSUPP; + goto end_io; + } +- if (bio_barrier(bio) && bio_has_data(bio) && +- (q->next_ordered == QUEUE_ORDERED_NONE)) { +- err = -EOPNOTSUPP; +- goto end_io; +- } + + ret = q->make_request_fn(q, bio); + } while (ret); +@@ -1663,55 +1655,6 @@ + } + EXPORT_SYMBOL(blkdev_dequeue_request); + +-static void blk_account_io_completion(struct request *req, unsigned int bytes) +-{ +- struct gendisk *disk = req->rq_disk; +- +- if (!disk || !blk_do_io_stat(disk->queue)) +- return; +- +- if (blk_fs_request(req)) { +- const int rw = rq_data_dir(req); +- struct hd_struct *part; +- int cpu; +- +- cpu = part_stat_lock(); +- part = disk_map_sector_rcu(req->rq_disk, req->sector); +- part_stat_add(cpu, part, sectors[rw], bytes >> 9); +- part_stat_unlock(); +- } +-} +- +-static void blk_account_io_done(struct request *req) +-{ +- struct gendisk *disk = req->rq_disk; +- +- if (!disk || !blk_do_io_stat(disk->queue)) +- return; +- +- /* +- * Account IO completion. bar_rq isn't accounted as a normal +- * IO on queueing nor completion. Accounting the containing +- * request is enough. +- */ +- if (blk_fs_request(req) && req != &req->q->bar_rq) { +- unsigned long duration = jiffies - req->start_time; +- const int rw = rq_data_dir(req); +- struct hd_struct *part; +- int cpu; +- +- cpu = part_stat_lock(); +- part = disk_map_sector_rcu(disk, req->sector); +- +- part_stat_inc(cpu, part, ios[rw]); +- part_stat_add(cpu, part, ticks[rw], duration); +- part_round_stats(cpu, part); +- part_dec_in_flight(part); +- +- part_stat_unlock(); +- } +-} +- + /** + * __end_that_request_first - end I/O on a request + * @req: the request being processed +@@ -1747,7 +1690,16 @@ + (unsigned long long)req->sector); + } + +- blk_account_io_completion(req, nr_bytes); ++ if (blk_fs_request(req) && req->rq_disk) { ++ const int rw = rq_data_dir(req); ++ struct hd_struct *part; ++ int cpu; ++ ++ cpu = part_stat_lock(); ++ part = disk_map_sector_rcu(req->rq_disk, req->sector); ++ part_stat_add(cpu, part, sectors[rw], nr_bytes >> 9); ++ part_stat_unlock(); ++ } + + total_bytes = bio_nbytes = 0; + while ((bio = req->bio) != NULL) { +@@ -1827,6 +1779,8 @@ + */ + static void end_that_request_last(struct request *req, int error) + { ++ struct gendisk *disk = req->rq_disk; ++ + if (blk_rq_tagged(req)) + blk_queue_end_tag(req->q, req); + +@@ -1838,7 +1792,27 @@ + + blk_delete_timer(req); + +- blk_account_io_done(req); ++ /* ++ * Account IO completion. bar_rq isn't accounted as a normal ++ * IO on queueing nor completion. Accounting the containing ++ * request is enough. ++ */ ++ if (disk && blk_fs_request(req) && req != &req->q->bar_rq) { ++ unsigned long duration = jiffies - req->start_time; ++ const int rw = rq_data_dir(req); ++ struct hd_struct *part; ++ int cpu; ++ ++ cpu = part_stat_lock(); ++ part = disk_map_sector_rcu(disk, req->sector); ++ ++ part_stat_inc(cpu, part, ios[rw]); ++ part_stat_add(cpu, part, ticks[rw], duration); ++ part_round_stats(cpu, part); ++ part_dec_in_flight(part); ++ ++ part_stat_unlock(); ++ } + + if (req->end_io) + req->end_io(req, error); +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/block/blk.h linux-2.6.29-rc3.owrt/block/blk.h +--- linux-2.6.29.owrt/block/blk.h 2009-05-10 22:04:39.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/block/blk.h 2009-05-10 23:48:28.000000000 +0200 +@@ -108,12 +108,4 @@ + #endif + } + +-static inline int blk_do_io_stat(struct request_queue *q) +-{ +- if (q) +- return blk_queue_io_stat(q); +- +- return 0; +-} +- + #endif +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/block/blk-integrity.c linux-2.6.29-rc3.owrt/block/blk-integrity.c +--- linux-2.6.29.owrt/block/blk-integrity.c 2009-05-10 22:04:39.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/block/blk-integrity.c 2009-05-10 23:48:28.000000000 +0200 +@@ -309,24 +309,24 @@ + /** + * blk_integrity_register - Register a gendisk as being integrity-capable + * @disk: struct gendisk pointer to make integrity-aware +- * @template: optional integrity profile to register ++ * @template: integrity profile + * + * Description: When a device needs to advertise itself as being able + * to send/receive integrity metadata it must use this function to + * register the capability with the block layer. The template is a + * blk_integrity struct with values appropriate for the underlying +- * hardware. If template is NULL the new profile is allocated but +- * not filled out. See Documentation/block/data-integrity.txt. ++ * hardware. See Documentation/block/data-integrity.txt. + */ + int blk_integrity_register(struct gendisk *disk, struct blk_integrity *template) + { + struct blk_integrity *bi; + + BUG_ON(disk == NULL); ++ BUG_ON(template == NULL); + + if (disk->integrity == NULL) { + bi = kmem_cache_alloc(integrity_cachep, +- GFP_KERNEL | __GFP_ZERO); ++ GFP_KERNEL | __GFP_ZERO); + if (!bi) + return -1; + +@@ -346,16 +346,13 @@ + bi = disk->integrity; + + /* Use the provided profile as template */ +- if (template != NULL) { +- bi->name = template->name; +- bi->generate_fn = template->generate_fn; +- bi->verify_fn = template->verify_fn; +- bi->tuple_size = template->tuple_size; +- bi->set_tag_fn = template->set_tag_fn; +- bi->get_tag_fn = template->get_tag_fn; +- bi->tag_size = template->tag_size; +- } else +- bi->name = "unsupported"; ++ bi->name = template->name; ++ bi->generate_fn = template->generate_fn; ++ bi->verify_fn = template->verify_fn; ++ bi->tuple_size = template->tuple_size; ++ bi->set_tag_fn = template->set_tag_fn; ++ bi->get_tag_fn = template->get_tag_fn; ++ bi->tag_size = template->tag_size; + + return 0; + } +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/block/blk-merge.c linux-2.6.29-rc3.owrt/block/blk-merge.c +--- linux-2.6.29.owrt/block/blk-merge.c 2009-05-10 22:04:39.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/block/blk-merge.c 2009-05-10 23:48:28.000000000 +0200 +@@ -38,77 +38,72 @@ + } + } + +-static unsigned int __blk_recalc_rq_segments(struct request_queue *q, +- struct bio *bio) ++void blk_recalc_rq_segments(struct request *rq) + { ++ int nr_phys_segs; + unsigned int phys_size; + struct bio_vec *bv, *bvprv = NULL; +- int cluster, i, high, highprv = 1; +- unsigned int seg_size, nr_phys_segs; +- struct bio *fbio, *bbio; ++ int seg_size; ++ int cluster; ++ struct req_iterator iter; ++ int high, highprv = 1; ++ struct request_queue *q = rq->q; + +- if (!bio) +- return 0; ++ if (!rq->bio) ++ return; + +- fbio = bio; + cluster = test_bit(QUEUE_FLAG_CLUSTER, &q->queue_flags); + seg_size = 0; + phys_size = nr_phys_segs = 0; +- for_each_bio(bio) { +- bio_for_each_segment(bv, bio, i) { +- /* +- * the trick here is making sure that a high page is +- * never considered part of another segment, since that +- * might change with the bounce page. +- */ +- high = page_to_pfn(bv->bv_page) > q->bounce_pfn; +- if (high || highprv) ++ rq_for_each_segment(bv, rq, iter) { ++ /* ++ * the trick here is making sure that a high page is never ++ * considered part of another segment, since that might ++ * change with the bounce page. ++ */ ++ high = page_to_pfn(bv->bv_page) > q->bounce_pfn; ++ if (high || highprv) ++ goto new_segment; ++ if (cluster) { ++ if (seg_size + bv->bv_len > q->max_segment_size) ++ goto new_segment; ++ if (!BIOVEC_PHYS_MERGEABLE(bvprv, bv)) ++ goto new_segment; ++ if (!BIOVEC_SEG_BOUNDARY(q, bvprv, bv)) + goto new_segment; +- if (cluster) { +- if (seg_size + bv->bv_len > q->max_segment_size) +- goto new_segment; +- if (!BIOVEC_PHYS_MERGEABLE(bvprv, bv)) +- goto new_segment; +- if (!BIOVEC_SEG_BOUNDARY(q, bvprv, bv)) +- goto new_segment; +- +- seg_size += bv->bv_len; +- bvprv = bv; +- continue; +- } +-new_segment: +- if (nr_phys_segs == 1 && seg_size > +- fbio->bi_seg_front_size) +- fbio->bi_seg_front_size = seg_size; + +- nr_phys_segs++; ++ seg_size += bv->bv_len; + bvprv = bv; +- seg_size = bv->bv_len; +- highprv = high; ++ continue; + } +- bbio = bio; ++new_segment: ++ if (nr_phys_segs == 1 && seg_size > rq->bio->bi_seg_front_size) ++ rq->bio->bi_seg_front_size = seg_size; ++ ++ nr_phys_segs++; ++ bvprv = bv; ++ seg_size = bv->bv_len; ++ highprv = high; + } + +- if (nr_phys_segs == 1 && seg_size > fbio->bi_seg_front_size) +- fbio->bi_seg_front_size = seg_size; +- if (seg_size > bbio->bi_seg_back_size) +- bbio->bi_seg_back_size = seg_size; ++ if (nr_phys_segs == 1 && seg_size > rq->bio->bi_seg_front_size) ++ rq->bio->bi_seg_front_size = seg_size; ++ if (seg_size > rq->biotail->bi_seg_back_size) ++ rq->biotail->bi_seg_back_size = seg_size; + +- return nr_phys_segs; +-} +- +-void blk_recalc_rq_segments(struct request *rq) +-{ +- rq->nr_phys_segments = __blk_recalc_rq_segments(rq->q, rq->bio); ++ rq->nr_phys_segments = nr_phys_segs; + } + + void blk_recount_segments(struct request_queue *q, struct bio *bio) + { ++ struct request rq; + struct bio *nxt = bio->bi_next; +- ++ rq.q = q; ++ rq.bio = rq.biotail = bio; + bio->bi_next = NULL; +- bio->bi_phys_segments = __blk_recalc_rq_segments(q, bio); ++ blk_recalc_rq_segments(&rq); + bio->bi_next = nxt; ++ bio->bi_phys_segments = rq.nr_phys_segments; + bio->bi_flags |= (1 << BIO_SEG_VALID); + } + EXPORT_SYMBOL(blk_recount_segments); +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/block/blk-sysfs.c linux-2.6.29-rc3.owrt/block/blk-sysfs.c +--- linux-2.6.29.owrt/block/blk-sysfs.c 2009-05-10 22:04:39.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/block/blk-sysfs.c 2009-05-10 23:48:28.000000000 +0200 +@@ -130,27 +130,6 @@ + return queue_var_show(max_hw_sectors_kb, (page)); + } + +-static ssize_t queue_nonrot_show(struct request_queue *q, char *page) +-{ +- return queue_var_show(!blk_queue_nonrot(q), page); +-} +- +-static ssize_t queue_nonrot_store(struct request_queue *q, const char *page, +- size_t count) +-{ +- unsigned long nm; +- ssize_t ret = queue_var_store(&nm, page, count); +- +- spin_lock_irq(q->queue_lock); +- if (nm) +- queue_flag_clear(QUEUE_FLAG_NONROT, q); +- else +- queue_flag_set(QUEUE_FLAG_NONROT, q); +- spin_unlock_irq(q->queue_lock); +- +- return ret; +-} +- + static ssize_t queue_nomerges_show(struct request_queue *q, char *page) + { + return queue_var_show(blk_queue_nomerges(q), page); +@@ -167,8 +146,8 @@ + queue_flag_set(QUEUE_FLAG_NOMERGES, q); + else + queue_flag_clear(QUEUE_FLAG_NOMERGES, q); +- spin_unlock_irq(q->queue_lock); + ++ spin_unlock_irq(q->queue_lock); + return ret; + } + +@@ -197,27 +176,6 @@ + return ret; + } + +-static ssize_t queue_iostats_show(struct request_queue *q, char *page) +-{ +- return queue_var_show(blk_queue_io_stat(q), page); +-} +- +-static ssize_t queue_iostats_store(struct request_queue *q, const char *page, +- size_t count) +-{ +- unsigned long stats; +- ssize_t ret = queue_var_store(&stats, page, count); +- +- spin_lock_irq(q->queue_lock); +- if (stats) +- queue_flag_set(QUEUE_FLAG_IO_STAT, q); +- else +- queue_flag_clear(QUEUE_FLAG_IO_STAT, q); +- spin_unlock_irq(q->queue_lock); +- +- return ret; +-} +- + static struct queue_sysfs_entry queue_requests_entry = { + .attr = {.name = "nr_requests", .mode = S_IRUGO | S_IWUSR }, + .show = queue_requests_show, +@@ -252,12 +210,6 @@ + .show = queue_hw_sector_size_show, + }; + +-static struct queue_sysfs_entry queue_nonrot_entry = { +- .attr = {.name = "rotational", .mode = S_IRUGO | S_IWUSR }, +- .show = queue_nonrot_show, +- .store = queue_nonrot_store, +-}; +- + static struct queue_sysfs_entry queue_nomerges_entry = { + .attr = {.name = "nomerges", .mode = S_IRUGO | S_IWUSR }, + .show = queue_nomerges_show, +@@ -270,12 +222,6 @@ + .store = queue_rq_affinity_store, + }; + +-static struct queue_sysfs_entry queue_iostats_entry = { +- .attr = {.name = "iostats", .mode = S_IRUGO | S_IWUSR }, +- .show = queue_iostats_show, +- .store = queue_iostats_store, +-}; +- + static struct attribute *default_attrs[] = { + &queue_requests_entry.attr, + &queue_ra_entry.attr, +@@ -283,10 +229,8 @@ + &queue_max_sectors_entry.attr, + &queue_iosched_entry.attr, + &queue_hw_sector_size_entry.attr, +- &queue_nonrot_entry.attr, + &queue_nomerges_entry.attr, + &queue_rq_affinity_entry.attr, +- &queue_iostats_entry.attr, + NULL, + }; + +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/block/blk-timeout.c linux-2.6.29-rc3.owrt/block/blk-timeout.c +--- linux-2.6.29.owrt/block/blk-timeout.c 2009-05-10 22:04:39.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/block/blk-timeout.c 2009-05-10 23:48:28.000000000 +0200 +@@ -209,19 +209,12 @@ + { + unsigned long flags; + struct request *rq, *tmp; +- LIST_HEAD(list); + + spin_lock_irqsave(q->queue_lock, flags); + + elv_abort_queue(q); + +- /* +- * Splice entries to local list, to avoid deadlocking if entries +- * get readded to the timeout list by error handling +- */ +- list_splice_init(&q->timeout_list, &list); +- +- list_for_each_entry_safe(rq, tmp, &list, timeout_list) ++ list_for_each_entry_safe(rq, tmp, &q->timeout_list, timeout_list) + blk_abort_request(rq); + + spin_unlock_irqrestore(q->queue_lock, flags); +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/block/blktrace.c linux-2.6.29-rc3.owrt/block/blktrace.c +--- linux-2.6.29.owrt/block/blktrace.c 2009-05-10 22:04:39.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/block/blktrace.c 2009-05-10 23:48:28.000000000 +0200 +@@ -142,7 +142,7 @@ + + what |= ddir_act[rw & WRITE]; + what |= MASK_TC_BIT(rw, BARRIER); +- what |= MASK_TC_BIT(rw, SYNCIO); ++ what |= MASK_TC_BIT(rw, SYNC); + what |= MASK_TC_BIT(rw, AHEAD); + what |= MASK_TC_BIT(rw, META); + what |= MASK_TC_BIT(rw, DISCARD); +@@ -187,12 +187,59 @@ + + static struct dentry *blk_tree_root; + static DEFINE_MUTEX(blk_tree_mutex); ++static unsigned int root_users; ++ ++static inline void blk_remove_root(void) ++{ ++ if (blk_tree_root) { ++ debugfs_remove(blk_tree_root); ++ blk_tree_root = NULL; ++ } ++} ++ ++static void blk_remove_tree(struct dentry *dir) ++{ ++ mutex_lock(&blk_tree_mutex); ++ debugfs_remove(dir); ++ if (--root_users == 0) ++ blk_remove_root(); ++ mutex_unlock(&blk_tree_mutex); ++} ++ ++static struct dentry *blk_create_tree(const char *blk_name) ++{ ++ struct dentry *dir = NULL; ++ int created = 0; ++ ++ mutex_lock(&blk_tree_mutex); ++ ++ if (!blk_tree_root) { ++ blk_tree_root = debugfs_create_dir("block", NULL); ++ if (!blk_tree_root) ++ goto err; ++ created = 1; ++ } ++ ++ dir = debugfs_create_dir(blk_name, blk_tree_root); ++ if (dir) ++ root_users++; ++ else { ++ /* Delete root only if we created it */ ++ if (created) ++ blk_remove_root(); ++ } ++ ++err: ++ mutex_unlock(&blk_tree_mutex); ++ return dir; ++} + + static void blk_trace_cleanup(struct blk_trace *bt) + { ++ relay_close(bt->rchan); + debugfs_remove(bt->msg_file); + debugfs_remove(bt->dropped_file); +- relay_close(bt->rchan); ++ blk_remove_tree(bt->dir); + free_percpu(bt->sequence); + free_percpu(bt->msg_data); + kfree(bt); +@@ -299,18 +346,7 @@ + + static int blk_remove_buf_file_callback(struct dentry *dentry) + { +- struct dentry *parent = dentry->d_parent; + debugfs_remove(dentry); +- +- /* +- * this will fail for all but the last file, but that is ok. what we +- * care about is the top level buts->name directory going away, when +- * the last trace file is gone. Then we don't have to rmdir() that +- * manually on trace stop, so it nicely solves the issue with +- * force killing of running traces. +- */ +- +- debugfs_remove(parent); + return 0; + } + +@@ -368,15 +404,7 @@ + goto err; + + ret = -ENOENT; +- +- if (!blk_tree_root) { +- blk_tree_root = debugfs_create_dir("block", NULL); +- if (!blk_tree_root) +- return -ENOMEM; +- } +- +- dir = debugfs_create_dir(buts->name, blk_tree_root); +- ++ dir = blk_create_tree(buts->name); + if (!dir) + goto err; + +@@ -430,6 +458,8 @@ + atomic_dec(&blk_probes_ref); + mutex_unlock(&blk_probe_mutex); + err: ++ if (dir) ++ blk_remove_tree(dir); + if (bt) { + if (bt->msg_file) + debugfs_remove(bt->msg_file); +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/block/bsg.c linux-2.6.29-rc3.owrt/block/bsg.c +--- linux-2.6.29.owrt/block/bsg.c 2009-05-10 22:04:39.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/block/bsg.c 2009-05-10 23:48:28.000000000 +0200 +@@ -244,8 +244,7 @@ + * map sg_io_v4 to a request. + */ + static struct request * +-bsg_map_hdr(struct bsg_device *bd, struct sg_io_v4 *hdr, fmode_t has_write_perm, +- u8 *sense) ++bsg_map_hdr(struct bsg_device *bd, struct sg_io_v4 *hdr, fmode_t has_write_perm) + { + struct request_queue *q = bd->queue; + struct request *rq, *next_rq = NULL; +@@ -307,10 +306,6 @@ + if (ret) + goto out; + } +- +- rq->sense = sense; +- rq->sense_len = 0; +- + return rq; + out: + if (rq->cmd != rq->__cmd) +@@ -353,6 +348,9 @@ + static void bsg_add_command(struct bsg_device *bd, struct request_queue *q, + struct bsg_command *bc, struct request *rq) + { ++ rq->sense = bc->sense; ++ rq->sense_len = 0; ++ + /* + * add bc command to busy queue and submit rq for io + */ +@@ -421,7 +419,7 @@ + { + int ret = 0; + +- dprintk("rq %p bio %p 0x%x\n", rq, bio, rq->errors); ++ dprintk("rq %p bio %p %u\n", rq, bio, rq->errors); + /* + * fill in all the output members + */ +@@ -637,7 +635,7 @@ + /* + * get a request, fill in the blanks, and add to request queue + */ +- rq = bsg_map_hdr(bd, &bc->hdr, has_write_perm, bc->sense); ++ rq = bsg_map_hdr(bd, &bc->hdr, has_write_perm); + if (IS_ERR(rq)) { + ret = PTR_ERR(rq); + rq = NULL; +@@ -924,12 +922,11 @@ + struct request *rq; + struct bio *bio, *bidi_bio = NULL; + struct sg_io_v4 hdr; +- u8 sense[SCSI_SENSE_BUFFERSIZE]; + + if (copy_from_user(&hdr, uarg, sizeof(hdr))) + return -EFAULT; + +- rq = bsg_map_hdr(bd, &hdr, file->f_mode & FMODE_WRITE, sense); ++ rq = bsg_map_hdr(bd, &hdr, file->f_mode & FMODE_WRITE); + if (IS_ERR(rq)) + return PTR_ERR(rq); + +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/block/cfq-iosched.c linux-2.6.29-rc3.owrt/block/cfq-iosched.c +--- linux-2.6.29.owrt/block/cfq-iosched.c 2009-05-10 22:04:39.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/block/cfq-iosched.c 2009-05-10 23:48:28.000000000 +0200 +@@ -84,11 +84,6 @@ + */ + struct cfq_rb_root service_tree; + unsigned int busy_queues; +- /* +- * Used to track any pending rt requests so we can pre-empt current +- * non-RT cfqq in service when this value is non-zero. +- */ +- unsigned int busy_rt_queues; + + int rq_in_driver; + int sync_flight; +@@ -567,8 +562,6 @@ + BUG_ON(cfq_cfqq_on_rr(cfqq)); + cfq_mark_cfqq_on_rr(cfqq); + cfqd->busy_queues++; +- if (cfq_class_rt(cfqq)) +- cfqd->busy_rt_queues++; + + cfq_resort_rr_list(cfqd, cfqq); + } +@@ -588,8 +581,6 @@ + + BUG_ON(!cfqd->busy_queues); + cfqd->busy_queues--; +- if (cfq_class_rt(cfqq)) +- cfqd->busy_rt_queues--; + } + + /* +@@ -1014,20 +1005,6 @@ + goto expire; + + /* +- * If we have a RT cfqq waiting, then we pre-empt the current non-rt +- * cfqq. +- */ +- if (!cfq_class_rt(cfqq) && cfqd->busy_rt_queues) { +- /* +- * We simulate this as cfqq timed out so that it gets to bank +- * the remaining of its time slice. +- */ +- cfq_log_cfqq(cfqd, cfqq, "preempt"); +- cfq_slice_expired(cfqd, 1); +- goto new_queue; +- } +- +- /* + * The active queue has requests and isn't expired, allow it to + * dispatch. + */ +@@ -1090,13 +1067,6 @@ + if (RB_EMPTY_ROOT(&cfqq->sort_list)) + break; + +- /* +- * If there is a non-empty RT cfqq waiting for current +- * cfqq's timeslice to complete, pre-empt this cfqq +- */ +- if (!cfq_class_rt(cfqq) && cfqd->busy_rt_queues) +- break; +- + } while (dispatched < max_dispatch); + + /* +@@ -1831,12 +1801,6 @@ + if (rq_is_meta(rq) && !cfqq->meta_pending) + return 1; + +- /* +- * Allow an RT request to pre-empt an ongoing non-RT cfqq timeslice. +- */ +- if (cfq_class_rt(new_cfqq) && !cfq_class_rt(cfqq)) +- return 1; +- + if (!cfqd->active_cic || !cfq_cfqq_wait_request(cfqq)) + return 0; + +@@ -1906,8 +1870,7 @@ + /* + * not the active queue - expire current slice if it is + * idle and has expired it's mean thinktime or this new queue +- * has some old slice time left and is of higher priority or +- * this new queue is RT and the current one is BE ++ * has some old slice time left and is of higher priority + */ + cfq_preempt_queue(cfqd, cfqq); + cfq_mark_cfqq_must_dispatch(cfqq); +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/block/genhd.c linux-2.6.29-rc3.owrt/block/genhd.c +--- linux-2.6.29.owrt/block/genhd.c 2009-05-10 22:04:39.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/block/genhd.c 2009-05-10 23:48:28.000000000 +0200 +@@ -256,22 +256,6 @@ + } + #endif /* CONFIG_PROC_FS */ + +-/** +- * register_blkdev - register a new block device +- * +- * @major: the requested major device number [1..255]. If @major=0, try to +- * allocate any unused major number. +- * @name: the name of the new block device as a zero terminated string +- * +- * The @name must be unique within the system. +- * +- * The return value depends on the @major input parameter. +- * - if a major device number was requested in range [1..255] then the +- * function returns zero on success, or a negative error code +- * - if any unused major number was requested with @major=0 parameter +- * then the return value is the allocated major number in range +- * [1..255] or a negative error code otherwise +- */ + int register_blkdev(unsigned int major, const char *name) + { + struct blk_major_name **n, *p; +@@ -1103,14 +1087,6 @@ + if (strcmp(dev_name(dev), name)) + continue; + +- if (partno < disk->minors) { +- /* We need to return the right devno, even +- * if the partition doesn't exist yet. +- */ +- devt = MKDEV(MAJOR(dev->devt), +- MINOR(dev->devt) + partno); +- break; +- } + part = disk_get_part(disk, partno); + if (part) { + devt = part_devt(part); +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/CREDITS linux-2.6.29-rc3.owrt/CREDITS +--- linux-2.6.29.owrt/CREDITS 2009-05-10 22:04:39.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/CREDITS 2009-05-10 23:48:28.000000000 +0200 +@@ -2166,6 +2166,7 @@ + + N: Pavel Machek + E: pavel@ucw.cz ++E: pavel@suse.cz + D: Softcursor for vga, hypertech cdrom support, vcsa bugfix, nbd + D: sun4/330 port, capabilities for elf, speedup for rm on ext2, USB, + D: work on suspend-to-ram/disk, killing duplicates from ioctl32 +@@ -3738,7 +3739,7 @@ + S: Germany + + N: Gertjan van Wingerde +-E: gwingerde@gmail.com ++E: gwingerde@home.nl + D: Ralink rt2x00 WLAN driver + D: Minix V2 file-system + D: Misc fixes +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/crypto/ahash.c linux-2.6.29-rc3.owrt/crypto/ahash.c +--- linux-2.6.29.owrt/crypto/ahash.c 2009-05-10 22:04:39.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/crypto/ahash.c 2009-05-10 23:48:28.000000000 +0200 +@@ -214,7 +214,7 @@ + seq_printf(m, "async : %s\n", alg->cra_flags & CRYPTO_ALG_ASYNC ? + "yes" : "no"); + seq_printf(m, "blocksize : %u\n", alg->cra_blocksize); +- seq_printf(m, "digestsize : %u\n", alg->cra_ahash.digestsize); ++ seq_printf(m, "digestsize : %u\n", alg->cra_hash.digestsize); + } + + const struct crypto_type crypto_ahash_type = { +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/crypto/algapi.c linux-2.6.29-rc3.owrt/crypto/algapi.c +--- linux-2.6.29.owrt/crypto/algapi.c 2009-05-10 22:04:39.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/crypto/algapi.c 2009-05-10 23:48:28.000000000 +0200 +@@ -149,9 +149,6 @@ + if (q == alg) + goto err; + +- if (crypto_is_moribund(q)) +- continue; +- + if (crypto_is_larval(q)) { + if (!strcmp(alg->cra_driver_name, q->cra_driver_name)) + goto err; +@@ -200,7 +197,7 @@ + + down_write(&crypto_alg_sem); + list_for_each_entry(q, &crypto_alg_list, cra_list) { +- if (crypto_is_moribund(q) || !crypto_is_larval(q)) ++ if (!crypto_is_larval(q)) + continue; + + test = (struct crypto_larval *)q; +@@ -213,7 +210,6 @@ + goto unlock; + + found: +- q->cra_flags |= CRYPTO_ALG_DEAD; + alg = test->adult; + if (err || list_empty(&alg->cra_list)) + goto complete; +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/crypto/api.c linux-2.6.29-rc3.owrt/crypto/api.c +--- linux-2.6.29.owrt/crypto/api.c 2009-05-10 22:04:39.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/crypto/api.c 2009-05-10 23:48:28.000000000 +0200 +@@ -215,19 +215,8 @@ + mask &= ~(CRYPTO_ALG_LARVAL | CRYPTO_ALG_DEAD); + type &= mask; + +- alg = crypto_alg_lookup(name, type, mask); +- if (!alg) { +- char tmp[CRYPTO_MAX_ALG_NAME]; +- +- request_module(name); +- +- if (!((type ^ CRYPTO_ALG_NEED_FALLBACK) & mask) && +- snprintf(tmp, sizeof(tmp), "%s-all", name) < sizeof(tmp)) +- request_module(tmp); +- +- alg = crypto_alg_lookup(name, type, mask); +- } +- ++ alg = try_then_request_module(crypto_alg_lookup(name, type, mask), ++ name); + if (alg) + return crypto_is_larval(alg) ? crypto_larval_wait(alg) : alg; + +@@ -568,34 +557,34 @@ + return ERR_PTR(err); + } + EXPORT_SYMBOL_GPL(crypto_alloc_tfm); +- ++ + /* +- * crypto_destroy_tfm - Free crypto transform +- * @mem: Start of tfm slab ++ * crypto_free_tfm - Free crypto transform + * @tfm: Transform to free + * +- * This function frees up the transform and any associated resources, ++ * crypto_free_tfm() frees up the transform and any associated resources, + * then drops the refcount on the associated algorithm. + */ +-void crypto_destroy_tfm(void *mem, struct crypto_tfm *tfm) ++void crypto_free_tfm(struct crypto_tfm *tfm) + { + struct crypto_alg *alg; + int size; + +- if (unlikely(!mem)) ++ if (unlikely(!tfm)) + return; + + alg = tfm->__crt_alg; +- size = ksize(mem); ++ size = sizeof(*tfm) + alg->cra_ctxsize; + + if (!tfm->exit && alg->cra_exit) + alg->cra_exit(tfm); + crypto_exit_ops(tfm); + crypto_mod_put(alg); +- memset(mem, 0, size); +- kfree(mem); ++ memset(tfm, 0, size); ++ kfree(tfm); + } +-EXPORT_SYMBOL_GPL(crypto_destroy_tfm); ++ ++EXPORT_SYMBOL_GPL(crypto_free_tfm); + + int crypto_has_alg(const char *name, u32 type, u32 mask) + { +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/crypto/lrw.c linux-2.6.29-rc3.owrt/crypto/lrw.c +--- linux-2.6.29.owrt/crypto/lrw.c 2009-05-10 22:04:39.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/crypto/lrw.c 2009-05-10 23:48:28.000000000 +0200 +@@ -45,13 +45,7 @@ + + static inline void setbit128_bbe(void *b, int bit) + { +- __set_bit(bit ^ (0x80 - +-#ifdef __BIG_ENDIAN +- BITS_PER_LONG +-#else +- BITS_PER_BYTE +-#endif +- ), b); ++ __set_bit(bit ^ 0x78, b); + } + + static int setkey(struct crypto_tfm *parent, const u8 *key, +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/crypto/scatterwalk.c linux-2.6.29-rc3.owrt/crypto/scatterwalk.c +--- linux-2.6.29.owrt/crypto/scatterwalk.c 2009-05-10 22:04:39.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/crypto/scatterwalk.c 2009-05-10 23:48:28.000000000 +0200 +@@ -54,8 +54,7 @@ + struct page *page; + + page = sg_page(walk->sg) + ((walk->offset - 1) >> PAGE_SHIFT); +- if (!PageSlab(page)) +- flush_dcache_page(page); ++ flush_dcache_page(page); + } + + if (more) { +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/crypto/shash.c linux-2.6.29-rc3.owrt/crypto/shash.c +--- linux-2.6.29.owrt/crypto/shash.c 2009-05-10 22:04:39.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/crypto/shash.c 2009-05-10 23:48:28.000000000 +0200 +@@ -388,15 +388,10 @@ + struct shash_desc *desc = crypto_tfm_ctx(tfm); + struct crypto_shash *shash; + +- if (!crypto_mod_get(calg)) +- return -EAGAIN; +- + shash = __crypto_shash_cast(crypto_create_tfm( + calg, &crypto_shash_type)); +- if (IS_ERR(shash)) { +- crypto_mod_put(calg); ++ if (IS_ERR(shash)) + return PTR_ERR(shash); +- } + + desc->tfm = shash; + tfm->exit = crypto_exit_shash_ops_compat; +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/Documentation/ABI/testing/sysfs-bus-pci linux-2.6.29-rc3.owrt/Documentation/ABI/testing/sysfs-bus-pci +--- linux-2.6.29.owrt/Documentation/ABI/testing/sysfs-bus-pci 2009-05-10 22:04:39.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/Documentation/ABI/testing/sysfs-bus-pci 2009-05-10 23:48:28.000000000 +0200 +@@ -1,46 +1,3 @@ +-What: /sys/bus/pci/drivers/.../bind +-Date: December 2003 +-Contact: linux-pci@vger.kernel.org +-Description: +- Writing a device location to this file will cause +- the driver to attempt to bind to the device found at +- this location. This is useful for overriding default +- bindings. The format for the location is: DDDD:BB:DD.F. +- That is Domain:Bus:Device.Function and is the same as +- found in /sys/bus/pci/devices/. For example: +- # echo 0000:00:19.0 > /sys/bus/pci/drivers/foo/bind +- (Note: kernels before 2.6.28 may require echo -n). +- +-What: /sys/bus/pci/drivers/.../unbind +-Date: December 2003 +-Contact: linux-pci@vger.kernel.org +-Description: +- Writing a device location to this file will cause the +- driver to attempt to unbind from the device found at +- this location. This may be useful when overriding default +- bindings. The format for the location is: DDDD:BB:DD.F. +- That is Domain:Bus:Device.Function and is the same as +- found in /sys/bus/pci/devices/. For example: +- # echo 0000:00:19.0 > /sys/bus/pci/drivers/foo/unbind +- (Note: kernels before 2.6.28 may require echo -n). +- +-What: /sys/bus/pci/drivers/.../new_id +-Date: December 2003 +-Contact: linux-pci@vger.kernel.org +-Description: +- Writing a device ID to this file will attempt to +- dynamically add a new device ID to a PCI device driver. +- This may allow the driver to support more hardware than +- was included in the driver's static device ID support +- table at compile time. The format for the device ID is: +- VVVV DDDD SVVV SDDD CCCC MMMM PPPP. That is Vendor ID, +- Device ID, Subsystem Vendor ID, Subsystem Device ID, +- Class, Class Mask, and Private Driver Data. The Vendor ID +- and Device ID fields are required, the rest are optional. +- Upon successfully adding an ID, the driver will probe +- for the device and attempt to bind to it. For example: +- # echo "8086 10f5" > /sys/bus/pci/drivers/foo/new_id +- + What: /sys/bus/pci/devices/.../vpd + Date: February 2008 + Contact: Ben Hutchings <bhutchings@solarflare.com> +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/Documentation/ABI/testing/sysfs-firmware-memmap linux-2.6.29-rc3.owrt/Documentation/ABI/testing/sysfs-firmware-memmap +--- linux-2.6.29.owrt/Documentation/ABI/testing/sysfs-firmware-memmap 2009-05-10 22:04:39.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/Documentation/ABI/testing/sysfs-firmware-memmap 2009-05-10 23:48:28.000000000 +0200 +@@ -1,6 +1,6 @@ + What: /sys/firmware/memmap/ + Date: June 2008 +-Contact: Bernhard Walle <bernhard.walle@gmx.de> ++Contact: Bernhard Walle <bwalle@suse.de> + Description: + On all platforms, the firmware provides a memory map which the + kernel reads. The resources from that memory map are registered +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/Documentation/block/biodoc.txt linux-2.6.29-rc3.owrt/Documentation/block/biodoc.txt +--- linux-2.6.29.owrt/Documentation/block/biodoc.txt 2009-05-10 22:04:39.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/Documentation/block/biodoc.txt 2009-05-10 23:48:28.000000000 +0200 +@@ -186,9 +186,8 @@ + do not have a corresponding kernel virtual address space mapping) and + low-memory pages. + +-Note: Please refer to Documentation/PCI/PCI-DMA-mapping.txt for a discussion +-on PCI high mem DMA aspects and mapping of scatter gather lists, and support +-for 64 bit PCI. ++Note: Please refer to DMA-mapping.txt for a discussion on PCI high mem DMA ++aspects and mapping of scatter gather lists, and support for 64 bit PCI. + + Special handling is required only for cases where i/o needs to happen on + pages at physical memory addresses beyond what the device can support. In these +@@ -954,14 +953,14 @@ + results in some sort of conflict internally, + this hook allows it to do that. + +-elevator_dispatch_fn* fills the dispatch queue with ready requests. ++elevator_dispatch_fn fills the dispatch queue with ready requests. + I/O schedulers are free to postpone requests by + not filling the dispatch queue unless @force + is non-zero. Once dispatched, I/O schedulers + are not allowed to manipulate the requests - + they belong to generic dispatch queue. + +-elevator_add_req_fn* called to add a new request into the scheduler ++elevator_add_req_fn called to add a new request into the scheduler + + elevator_queue_empty_fn returns true if the merge queue is empty. + Drivers shouldn't use this, but rather check +@@ -991,7 +990,7 @@ + elevator_deactivate_req_fn Called when device driver decides to delay + a request by requeueing it. + +-elevator_init_fn* ++elevator_init_fn + elevator_exit_fn Allocate and free any elevator specific storage + for a queue. + +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/Documentation/block/queue-sysfs.txt linux-2.6.29-rc3.owrt/Documentation/block/queue-sysfs.txt +--- linux-2.6.29.owrt/Documentation/block/queue-sysfs.txt 2009-05-10 22:04:39.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/Documentation/block/queue-sysfs.txt 1970-01-01 01:00:00.000000000 +0100 +@@ -1,63 +0,0 @@ +-Queue sysfs files +-================= +- +-This text file will detail the queue files that are located in the sysfs tree +-for each block device. Note that stacked devices typically do not export +-any settings, since their queue merely functions are a remapping target. +-These files are the ones found in the /sys/block/xxx/queue/ directory. +- +-Files denoted with a RO postfix are readonly and the RW postfix means +-read-write. +- +-hw_sector_size (RO) +-------------------- +-This is the hardware sector size of the device, in bytes. +- +-max_hw_sectors_kb (RO) +----------------------- +-This is the maximum number of kilobytes supported in a single data transfer. +- +-max_sectors_kb (RW) +-------------------- +-This is the maximum number of kilobytes that the block layer will allow +-for a filesystem request. Must be smaller than or equal to the maximum +-size allowed by the hardware. +- +-nomerges (RW) +-------------- +-This enables the user to disable the lookup logic involved with IO merging +-requests in the block layer. Merging may still occur through a direct +-1-hit cache, since that comes for (almost) free. The IO scheduler will not +-waste cycles doing tree/hash lookups for merges if nomerges is 1. Defaults +-to 0, enabling all merges. +- +-nr_requests (RW) +----------------- +-This controls how many requests may be allocated in the block layer for +-read or write requests. Note that the total allocated number may be twice +-this amount, since it applies only to reads or writes (not the accumulated +-sum). +- +-read_ahead_kb (RW) +------------------- +-Maximum number of kilobytes to read-ahead for filesystems on this block +-device. +- +-rq_affinity (RW) +----------------- +-If this option is enabled, the block layer will migrate request completions +-to the CPU that originally submitted the request. For some workloads +-this provides a significant reduction in CPU cycles due to caching effects. +- +-scheduler (RW) +--------------- +-When read, this file will display the current and available IO schedulers +-for this block device. The currently active IO scheduler will be enclosed +-in [] brackets. Writing an IO scheduler name to this file will switch +-control of this block device to that new IO scheduler. Note that writing +-an IO scheduler name to this file will attempt to load that IO scheduler +-module, if it isn't already present in the system. +- +- +- +-Jens Axboe <jens.axboe@oracle.com>, February 2009 +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/Documentation/cgroups/cgroups.txt linux-2.6.29-rc3.owrt/Documentation/cgroups/cgroups.txt +--- linux-2.6.29.owrt/Documentation/cgroups/cgroups.txt 2009-05-10 22:04:39.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/Documentation/cgroups/cgroups.txt 2009-05-10 23:48:28.000000000 +0200 +@@ -252,8 +252,10 @@ + When a task is moved from one cgroup to another, it gets a new + css_set pointer - if there's an already existing css_set with the + desired collection of cgroups then that group is reused, else a new +-css_set is allocated. The appropriate existing css_set is located by +-looking into a hash table. ++css_set is allocated. Note that the current implementation uses a ++linear search to locate an appropriate existing css_set, so isn't ++very efficient. A future version will use a hash table for better ++performance. + + To allow access from a cgroup to the css_sets (and hence tasks) + that comprise it, a set of cg_cgroup_link objects form a lattice; +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/Documentation/cgroups/cpusets.txt linux-2.6.29-rc3.owrt/Documentation/cgroups/cpusets.txt +--- linux-2.6.29.owrt/Documentation/cgroups/cpusets.txt 2009-05-10 22:04:39.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/Documentation/cgroups/cpusets.txt 2009-05-10 23:48:28.000000000 +0200 +@@ -142,7 +142,7 @@ + - in fork and exit, to attach and detach a task from its cpuset. + - in sched_setaffinity, to mask the requested CPUs by what's + allowed in that tasks cpuset. +- - in sched.c migrate_live_tasks(), to keep migrating tasks within ++ - in sched.c migrate_all_tasks(), to keep migrating tasks within + the CPUs allowed by their cpuset, if possible. + - in the mbind and set_mempolicy system calls, to mask the requested + Memory Nodes by what's allowed in that tasks cpuset. +@@ -175,10 +175,6 @@ + - mem_exclusive flag: is memory placement exclusive? + - mem_hardwall flag: is memory allocation hardwalled + - memory_pressure: measure of how much paging pressure in cpuset +- - memory_spread_page flag: if set, spread page cache evenly on allowed nodes +- - memory_spread_slab flag: if set, spread slab cache evenly on allowed nodes +- - sched_load_balance flag: if set, load balance within CPUs on that cpuset +- - sched_relax_domain_level: the searching range when migrating tasks + + In addition, the root cpuset only has the following file: + - memory_pressure_enabled flag: compute memory_pressure? +@@ -256,7 +252,7 @@ + + This is useful both on tightly managed systems running a wide mix of + submitted jobs, which may choose to terminate or re-prioritize jobs that +-are trying to use more memory than allowed on the nodes assigned to them, ++are trying to use more memory than allowed on the nodes assigned them, + and with tightly coupled, long running, massively parallel scientific + computing jobs that will dramatically fail to meet required performance + goals if they start to use more memory than allowed to them. +@@ -382,7 +378,7 @@ + The algorithmic cost of load balancing and its impact on key shared + kernel data structures such as the task list increases more than + linearly with the number of CPUs being balanced. So the scheduler +-has support to partition the systems CPUs into a number of sched ++has support to partition the systems CPUs into a number of sched + domains such that it only load balances within each sched domain. + Each sched domain covers some subset of the CPUs in the system; + no two sched domains overlap; some CPUs might not be in any sched +@@ -489,22 +485,17 @@ + The internal kernel cpuset to scheduler interface passes from the + cpuset code to the scheduler code a partition of the load balanced + CPUs in the system. This partition is a set of subsets (represented +-as an array of struct cpumask) of CPUs, pairwise disjoint, that cover +-all the CPUs that must be load balanced. ++as an array of cpumask_t) of CPUs, pairwise disjoint, that cover all ++the CPUs that must be load balanced. + +-The cpuset code builds a new such partition and passes it to the +-scheduler sched domain setup code, to have the sched domains rebuilt +-as necessary, whenever: +- - the 'sched_load_balance' flag of a cpuset with non-empty CPUs changes, +- - or CPUs come or go from a cpuset with this flag enabled, +- - or 'sched_relax_domain_level' value of a cpuset with non-empty CPUs +- and with this flag enabled changes, +- - or a cpuset with non-empty CPUs and with this flag enabled is removed, +- - or a cpu is offlined/onlined. ++Whenever the 'sched_load_balance' flag changes, or CPUs come or go ++from a cpuset with this flag enabled, or a cpuset with this flag ++enabled is removed, the cpuset code builds a new such partition and ++passes it to the scheduler sched domain setup code, to have the sched ++domains rebuilt as necessary. + + This partition exactly defines what sched domains the scheduler should +-setup - one sched domain for each element (struct cpumask) in the +-partition. ++setup - one sched domain for each element (cpumask_t) in the partition. + + The scheduler remembers the currently active sched domain partitions. + When the scheduler routine partition_sched_domains() is invoked from +@@ -568,7 +559,7 @@ + requests 0 and others are -1 then 0 is used. + + Note that modifying this file will have both good and bad effects, +-and whether it is acceptable or not depends on your situation. ++and whether it is acceptable or not will be depend on your situation. + Don't modify this file if you are not sure. + + If your situation is: +@@ -609,15 +600,19 @@ + + If a cpuset has its 'cpus' modified, then each task in that cpuset + will have its allowed CPU placement changed immediately. Similarly, +-if a tasks pid is written to another cpusets 'tasks' file, then its +-allowed CPU placement is changed immediately. If such a task had been +-bound to some subset of its cpuset using the sched_setaffinity() call, +-the task will be allowed to run on any CPU allowed in its new cpuset, +-negating the effect of the prior sched_setaffinity() call. ++if a tasks pid is written to a cpusets 'tasks' file, in either its ++current cpuset or another cpuset, then its allowed CPU placement is ++changed immediately. If such a task had been bound to some subset ++of its cpuset using the sched_setaffinity() call, the task will be ++allowed to run on any CPU allowed in its new cpuset, negating the ++affect of the prior sched_setaffinity() call. + + In summary, the memory placement of a task whose cpuset is changed is + updated by the kernel, on the next allocation of a page for that task, +-and the processor placement is updated immediately. ++but the processor placement is not updated, until that tasks pid is ++rewritten to the 'tasks' file of its cpuset. This is done to avoid ++impacting the scheduler code in the kernel with a check for changes ++in a tasks processor placement. + + Normally, once a page is allocated (given a physical page + of main memory) then that page stays on whatever node it +@@ -686,14 +681,10 @@ + # The next line should display '/Charlie' + cat /proc/self/cpuset + +-There are ways to query or modify cpusets: +- - via the cpuset file system directly, using the various cd, mkdir, echo, +- cat, rmdir commands from the shell, or their equivalent from C. +- - via the C library libcpuset. +- - via the C library libcgroup. +- (http://sourceforge.net/proects/libcg/) +- - via the python application cset. +- (http://developer.novell.com/wiki/index.php/Cpuset) ++In the future, a C library interface to cpusets will likely be ++available. For now, the only way to query or modify cpusets is ++via the cpuset file system, using the various cd, mkdir, echo, cat, ++rmdir commands from the shell, or their equivalent from C. + + The sched_setaffinity calls can also be done at the shell prompt using + SGI's runon or Robert Love's taskset. The mbind and set_mempolicy +@@ -765,7 +756,7 @@ + + is equivalent to + +-mount -t cgroup -ocpuset,noprefix X /dev/cpuset ++mount -t cgroup -ocpuset X /dev/cpuset + echo "/sbin/cpuset_release_agent" > /dev/cpuset/release_agent + + 2.2 Adding/removing cpus +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/Documentation/cgroups/memcg_test.txt linux-2.6.29-rc3.owrt/Documentation/cgroups/memcg_test.txt +--- linux-2.6.29.owrt/Documentation/cgroups/memcg_test.txt 2009-05-10 22:04:39.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/Documentation/cgroups/memcg_test.txt 2009-05-10 23:48:28.000000000 +0200 +@@ -1,6 +1,6 @@ + Memory Resource Controller(Memcg) Implementation Memo. +-Last Updated: 2009/1/19 +-Base Kernel Version: based on 2.6.29-rc2. ++Last Updated: 2008/12/15 ++Base Kernel Version: based on 2.6.28-rc8-mm. + + Because VM is getting complex (one of reasons is memcg...), memcg's behavior + is complex. This is a document for memcg's internal behavior. +@@ -340,23 +340,3 @@ + # mount -t cgroup none /cgroup -t cpuset,memory,cpu,devices + + and do task move, mkdir, rmdir etc...under this. +- +- 9.7 swapoff. +- Besides management of swap is one of complicated parts of memcg, +- call path of swap-in at swapoff is not same as usual swap-in path.. +- It's worth to be tested explicitly. +- +- For example, test like following is good. +- (Shell-A) +- # mount -t cgroup none /cgroup -t memory +- # mkdir /cgroup/test +- # echo 40M > /cgroup/test/memory.limit_in_bytes +- # echo 0 > /cgroup/test/tasks +- Run malloc(100M) program under this. You'll see 60M of swaps. +- (Shell-B) +- # move all tasks in /cgroup/test to /cgroup +- # /sbin/swapoff -a +- # rmdir /test/cgroup +- # kill malloc task. +- +- Of course, tmpfs v.s. swapoff test should be tested, too. +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/Documentation/Changes linux-2.6.29-rc3.owrt/Documentation/Changes +--- linux-2.6.29.owrt/Documentation/Changes 2009-05-10 22:04:39.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/Documentation/Changes 2009-05-10 23:48:28.000000000 +0200 +@@ -33,12 +33,10 @@ + o binutils 2.12 # ld -v + o util-linux 2.10o # fdformat --version + o module-init-tools 0.9.10 # depmod -V +-o e2fsprogs 1.41.4 # e2fsck -V ++o e2fsprogs 1.29 # tune2fs + o jfsutils 1.1.3 # fsck.jfs -V + o reiserfsprogs 3.6.3 # reiserfsck -V 2>&1|grep reiserfsprogs + o xfsprogs 2.6.0 # xfs_db -V +-o squashfs-tools 4.0 # mksquashfs -version +-o btrfs-progs 0.18 # btrfsck + o pcmciautils 004 # pccardctl -V + o quota-tools 3.09 # quota -V + o PPP 2.4.0 # pppd --version +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/Documentation/CodingStyle linux-2.6.29-rc3.owrt/Documentation/CodingStyle +--- linux-2.6.29.owrt/Documentation/CodingStyle 2009-05-10 22:04:39.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/Documentation/CodingStyle 2009-05-10 23:48:28.000000000 +0200 +@@ -483,25 +483,17 @@ + (* (max steps 1) + c-basic-offset))) + +-(add-hook 'c-mode-common-hook +- (lambda () +- ;; Add kernel style +- (c-add-style +- "linux-tabs-only" +- '("linux" (c-offsets-alist +- (arglist-cont-nonempty +- c-lineup-gcc-asm-reg +- c-lineup-arglist-tabs-only)))))) +- + (add-hook 'c-mode-hook + (lambda () + (let ((filename (buffer-file-name))) + ;; Enable kernel mode for the appropriate files + (when (and filename +- (string-match (expand-file-name "~/src/linux-trees") +- filename)) ++ (string-match "~/src/linux-trees" filename)) + (setq indent-tabs-mode t) +- (c-set-style "linux-tabs-only"))))) ++ (c-set-style "linux") ++ (c-set-offset 'arglist-cont-nonempty ++ '(c-lineup-gcc-asm-reg ++ c-lineup-arglist-tabs-only)))))) + + This will make emacs go better with the kernel coding style for C + files below ~/src/linux-trees. +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/Documentation/connector/cn_test.c linux-2.6.29-rc3.owrt/Documentation/connector/cn_test.c +--- linux-2.6.29.owrt/Documentation/connector/cn_test.c 2009-05-10 22:04:39.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/Documentation/connector/cn_test.c 2009-05-10 23:48:28.000000000 +0200 +@@ -137,7 +137,7 @@ + + memcpy(m + 1, data, m->len); + +- cn_netlink_send(m, 0, GFP_ATOMIC); ++ cn_netlink_send(m, 0, gfp_any()); + kfree(m); + } + +@@ -160,8 +160,10 @@ + goto err_out; + } + +- setup_timer(&cn_test_timer, cn_test_timer_func, 0); ++ init_timer(&cn_test_timer); ++ cn_test_timer.function = cn_test_timer_func; + cn_test_timer.expires = jiffies + HZ; ++ cn_test_timer.data = 0; + add_timer(&cn_test_timer); + + return 0; +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/Documentation/cpu-freq/user-guide.txt linux-2.6.29-rc3.owrt/Documentation/cpu-freq/user-guide.txt +--- linux-2.6.29.owrt/Documentation/cpu-freq/user-guide.txt 2009-05-10 22:04:39.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/Documentation/cpu-freq/user-guide.txt 2009-05-10 23:48:28.000000000 +0200 +@@ -195,3 +195,19 @@ + you can change the speed of the CPU, + but only within the limits of + scaling_min_freq and scaling_max_freq. ++ ++ ++3.2 Deprecated Interfaces ++------------------------- ++ ++Depending on your kernel configuration, you might find the following ++cpufreq-related files: ++/proc/cpufreq ++/proc/sys/cpu/*/speed ++/proc/sys/cpu/*/speed-min ++/proc/sys/cpu/*/speed-max ++ ++These are files for deprecated interfaces to cpufreq, which offer far ++less functionality. Because of this, these interfaces aren't described ++here. ++ +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/Documentation/DMA-API.txt linux-2.6.29-rc3.owrt/Documentation/DMA-API.txt +--- linux-2.6.29.owrt/Documentation/DMA-API.txt 2009-05-10 22:04:39.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/Documentation/DMA-API.txt 2009-05-10 23:48:28.000000000 +0200 +@@ -5,7 +5,7 @@ + + This document describes the DMA API. For a more gentle introduction + phrased in terms of the pci_ equivalents (and actual examples) see +-Documentation/PCI/PCI-DMA-mapping.txt. ++DMA-mapping.txt + + This API is split into two pieces. Part I describes the API and the + corresponding pci_ API. Part II describes the extensions to the API +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/Documentation/DocBook/device-drivers.tmpl linux-2.6.29-rc3.owrt/Documentation/DocBook/device-drivers.tmpl +--- linux-2.6.29.owrt/Documentation/DocBook/device-drivers.tmpl 2009-05-10 22:04:39.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/Documentation/DocBook/device-drivers.tmpl 1970-01-01 01:00:00.000000000 +0100 +@@ -1,418 +0,0 @@ +-<?xml version="1.0" encoding="UTF-8"?> +-<!DOCTYPE book PUBLIC "-//OASIS//DTD DocBook XML V4.1.2//EN" +- "http://www.oasis-open.org/docbook/xml/4.1.2/docbookx.dtd" []> +- +-<book id="LinuxDriversAPI"> +- <bookinfo> +- <title>Linux Device Drivers</title> +- +- <legalnotice> +- <para> +- This documentation 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. +- </para> +- +- <para> +- 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. +- </para> +- +- <para> +- 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, +- MA 02111-1307 USA +- </para> +- +- <para> +- For more details see the file COPYING in the source +- distribution of Linux. +- </para> +- </legalnotice> +- </bookinfo> +- +-<toc></toc> +- +- <chapter id="Basics"> +- <title>Driver Basics</title> +- <sect1><title>Driver Entry and Exit points</title> +-!Iinclude/linux/init.h +- </sect1> +- +- <sect1><title>Atomic and pointer manipulation</title> +-!Iarch/x86/include/asm/atomic_32.h +-!Iarch/x86/include/asm/unaligned.h +- </sect1> +- +- <sect1><title>Delaying, scheduling, and timer routines</title> +-!Iinclude/linux/sched.h +-!Ekernel/sched.c +-!Ekernel/timer.c +- </sect1> +- <sect1><title>High-resolution timers</title> +-!Iinclude/linux/ktime.h +-!Iinclude/linux/hrtimer.h +-!Ekernel/hrtimer.c +- </sect1> +- <sect1><title>Workqueues and Kevents</title> +-!Ekernel/workqueue.c +- </sect1> +- <sect1><title>Internal Functions</title> +-!Ikernel/exit.c +-!Ikernel/signal.c +-!Iinclude/linux/kthread.h +-!Ekernel/kthread.c +- </sect1> +- +- <sect1><title>Kernel objects manipulation</title> +-<!-- +-X!Iinclude/linux/kobject.h +---> +-!Elib/kobject.c +- </sect1> +- +- <sect1><title>Kernel utility functions</title> +-!Iinclude/linux/kernel.h +-!Ekernel/printk.c +-!Ekernel/panic.c +-!Ekernel/sys.c +-!Ekernel/rcupdate.c +- </sect1> +- +- <sect1><title>Device Resource Management</title> +-!Edrivers/base/devres.c +- </sect1> +- +- </chapter> +- +- <chapter id="devdrivers"> +- <title>Device drivers infrastructure</title> +- <sect1><title>Device Drivers Base</title> +-<!-- +-X!Iinclude/linux/device.h +---> +-!Edrivers/base/driver.c +-!Edrivers/base/core.c +-!Edrivers/base/class.c +-!Edrivers/base/firmware_class.c +-!Edrivers/base/transport_class.c +-<!-- Cannot be included, because +- attribute_container_add_class_device_adapter +- and attribute_container_classdev_to_container +- exceed allowed 44 characters maximum +-X!Edrivers/base/attribute_container.c +---> +-!Edrivers/base/sys.c +-<!-- +-X!Edrivers/base/interface.c +---> +-!Edrivers/base/platform.c +-!Edrivers/base/bus.c +- </sect1> +- <sect1><title>Device Drivers Power Management</title> +-!Edrivers/base/power/main.c +- </sect1> +- <sect1><title>Device Drivers ACPI Support</title> +-<!-- Internal functions only +-X!Edrivers/acpi/sleep/main.c +-X!Edrivers/acpi/sleep/wakeup.c +-X!Edrivers/acpi/motherboard.c +-X!Edrivers/acpi/bus.c +---> +-!Edrivers/acpi/scan.c +-!Idrivers/acpi/scan.c +-<!-- No correct structured comments +-X!Edrivers/acpi/pci_bind.c +---> +- </sect1> +- <sect1><title>Device drivers PnP support</title> +-!Idrivers/pnp/core.c +-<!-- No correct structured comments +-X!Edrivers/pnp/system.c +- --> +-!Edrivers/pnp/card.c +-!Idrivers/pnp/driver.c +-!Edrivers/pnp/manager.c +-!Edrivers/pnp/support.c +- </sect1> +- <sect1><title>Userspace IO devices</title> +-!Edrivers/uio/uio.c +-!Iinclude/linux/uio_driver.h +- </sect1> +- </chapter> +- +- <chapter id="parportdev"> +- <title>Parallel Port Devices</title> +-!Iinclude/linux/parport.h +-!Edrivers/parport/ieee1284.c +-!Edrivers/parport/share.c +-!Idrivers/parport/daisy.c +- </chapter> +- +- <chapter id="message_devices"> +- <title>Message-based devices</title> +- <sect1><title>Fusion message devices</title> +-!Edrivers/message/fusion/mptbase.c +-!Idrivers/message/fusion/mptbase.c +-!Edrivers/message/fusion/mptscsih.c +-!Idrivers/message/fusion/mptscsih.c +-!Idrivers/message/fusion/mptctl.c +-!Idrivers/message/fusion/mptspi.c +-!Idrivers/message/fusion/mptfc.c +-!Idrivers/message/fusion/mptlan.c +- </sect1> +- <sect1><title>I2O message devices</title> +-!Iinclude/linux/i2o.h +-!Idrivers/message/i2o/core.h +-!Edrivers/message/i2o/iop.c +-!Idrivers/message/i2o/iop.c +-!Idrivers/message/i2o/config-osm.c +-!Edrivers/message/i2o/exec-osm.c +-!Idrivers/message/i2o/exec-osm.c +-!Idrivers/message/i2o/bus-osm.c +-!Edrivers/message/i2o/device.c +-!Idrivers/message/i2o/device.c +-!Idrivers/message/i2o/driver.c +-!Idrivers/message/i2o/pci.c +-!Idrivers/message/i2o/i2o_block.c +-!Idrivers/message/i2o/i2o_scsi.c +-!Idrivers/message/i2o/i2o_proc.c +- </sect1> +- </chapter> +- +- <chapter id="snddev"> +- <title>Sound Devices</title> +-!Iinclude/sound/core.h +-!Esound/sound_core.c +-!Iinclude/sound/pcm.h +-!Esound/core/pcm.c +-!Esound/core/device.c +-!Esound/core/info.c +-!Esound/core/rawmidi.c +-!Esound/core/sound.c +-!Esound/core/memory.c +-!Esound/core/pcm_memory.c +-!Esound/core/init.c +-!Esound/core/isadma.c +-!Esound/core/control.c +-!Esound/core/pcm_lib.c +-!Esound/core/hwdep.c +-!Esound/core/pcm_native.c +-!Esound/core/memalloc.c +-<!-- FIXME: Removed for now since no structured comments in source +-X!Isound/sound_firmware.c +---> +- </chapter> +- +- <chapter id="uart16x50"> +- <title>16x50 UART Driver</title> +-!Iinclude/linux/serial_core.h +-!Edrivers/serial/serial_core.c +-!Edrivers/serial/8250.c +- </chapter> +- +- <chapter id="fbdev"> +- <title>Frame Buffer Library</title> +- +- <para> +- The frame buffer drivers depend heavily on four data structures. +- These structures are declared in include/linux/fb.h. They are +- fb_info, fb_var_screeninfo, fb_fix_screeninfo and fb_monospecs. +- The last three can be made available to and from userland. +- </para> +- +- <para> +- fb_info defines the current state of a particular video card. +- Inside fb_info, there exists a fb_ops structure which is a +- collection of needed functions to make fbdev and fbcon work. +- fb_info is only visible to the kernel. +- </para> +- +- <para> +- fb_var_screeninfo is used to describe the features of a video card +- that are user defined. With fb_var_screeninfo, things such as +- depth and the resolution may be defined. +- </para> +- +- <para> +- The next structure is fb_fix_screeninfo. This defines the +- properties of a card that are created when a mode is set and can't +- be changed otherwise. A good example of this is the start of the +- frame buffer memory. This "locks" the address of the frame buffer +- memory, so that it cannot be changed or moved. +- </para> +- +- <para> +- The last structure is fb_monospecs. In the old API, there was +- little importance for fb_monospecs. This allowed for forbidden things +- such as setting a mode of 800x600 on a fix frequency monitor. With +- the new API, fb_monospecs prevents such things, and if used +- correctly, can prevent a monitor from being cooked. fb_monospecs +- will not be useful until kernels 2.5.x. +- </para> +- +- <sect1><title>Frame Buffer Memory</title> +-!Edrivers/video/fbmem.c +- </sect1> +-<!-- +- <sect1><title>Frame Buffer Console</title> +-X!Edrivers/video/console/fbcon.c +- </sect1> +---> +- <sect1><title>Frame Buffer Colormap</title> +-!Edrivers/video/fbcmap.c +- </sect1> +-<!-- FIXME: +- drivers/video/fbgen.c has no docs, which stuffs up the sgml. Comment +- out until somebody adds docs. KAO +- <sect1><title>Frame Buffer Generic Functions</title> +-X!Idrivers/video/fbgen.c +- </sect1> +-KAO --> +- <sect1><title>Frame Buffer Video Mode Database</title> +-!Idrivers/video/modedb.c +-!Edrivers/video/modedb.c +- </sect1> +- <sect1><title>Frame Buffer Macintosh Video Mode Database</title> +-!Edrivers/video/macmodes.c +- </sect1> +- <sect1><title>Frame Buffer Fonts</title> +- <para> +- Refer to the file drivers/video/console/fonts.c for more information. +- </para> +-<!-- FIXME: Removed for now since no structured comments in source +-X!Idrivers/video/console/fonts.c +---> +- </sect1> +- </chapter> +- +- <chapter id="input_subsystem"> +- <title>Input Subsystem</title> +-!Iinclude/linux/input.h +-!Edrivers/input/input.c +-!Edrivers/input/ff-core.c +-!Edrivers/input/ff-memless.c +- </chapter> +- +- <chapter id="spi"> +- <title>Serial Peripheral Interface (SPI)</title> +- <para> +- SPI is the "Serial Peripheral Interface", widely used with +- embedded systems because it is a simple and efficient +- interface: basically a multiplexed shift register. +- Its three signal wires hold a clock (SCK, often in the range +- of 1-20 MHz), a "Master Out, Slave In" (MOSI) data line, and +- a "Master In, Slave Out" (MISO) data line. +- SPI is a full duplex protocol; for each bit shifted out the +- MOSI line (one per clock) another is shifted in on the MISO line. +- Those bits are assembled into words of various sizes on the +- way to and from system memory. +- An additional chipselect line is usually active-low (nCS); +- four signals are normally used for each peripheral, plus +- sometimes an interrupt. +- </para> +- <para> +- The SPI bus facilities listed here provide a generalized +- interface to declare SPI busses and devices, manage them +- according to the standard Linux driver model, and perform +- input/output operations. +- At this time, only "master" side interfaces are supported, +- where Linux talks to SPI peripherals and does not implement +- such a peripheral itself. +- (Interfaces to support implementing SPI slaves would +- necessarily look different.) +- </para> +- <para> +- The programming interface is structured around two kinds of driver, +- and two kinds of device. +- A "Controller Driver" abstracts the controller hardware, which may +- be as simple as a set of GPIO pins or as complex as a pair of FIFOs +- connected to dual DMA engines on the other side of the SPI shift +- register (maximizing throughput). Such drivers bridge between +- whatever bus they sit on (often the platform bus) and SPI, and +- expose the SPI side of their device as a +- <structname>struct spi_master</structname>. +- SPI devices are children of that master, represented as a +- <structname>struct spi_device</structname> and manufactured from +- <structname>struct spi_board_info</structname> descriptors which +- are usually provided by board-specific initialization code. +- A <structname>struct spi_driver</structname> is called a +- "Protocol Driver", and is bound to a spi_device using normal +- driver model calls. +- </para> +- <para> +- The I/O model is a set of queued messages. Protocol drivers +- submit one or more <structname>struct spi_message</structname> +- objects, which are processed and completed asynchronously. +- (There are synchronous wrappers, however.) Messages are +- built from one or more <structname>struct spi_transfer</structname> +- objects, each of which wraps a full duplex SPI transfer. +- A variety of protocol tweaking options are needed, because +- different chips adopt very different policies for how they +- use the bits transferred with SPI. +- </para> +-!Iinclude/linux/spi/spi.h +-!Fdrivers/spi/spi.c spi_register_board_info +-!Edrivers/spi/spi.c +- </chapter> +- +- <chapter id="i2c"> +- <title>I<superscript>2</superscript>C and SMBus Subsystem</title> +- +- <para> +- I<superscript>2</superscript>C (or without fancy typography, "I2C") +- is an acronym for the "Inter-IC" bus, a simple bus protocol which is +- widely used where low data rate communications suffice. +- Since it's also a licensed trademark, some vendors use another +- name (such as "Two-Wire Interface", TWI) for the same bus. +- I2C only needs two signals (SCL for clock, SDA for data), conserving +- board real estate and minimizing signal quality issues. +- Most I2C devices use seven bit addresses, and bus speeds of up +- to 400 kHz; there's a high speed extension (3.4 MHz) that's not yet +- found wide use. +- I2C is a multi-master bus; open drain signaling is used to +- arbitrate between masters, as well as to handshake and to +- synchronize clocks from slower clients. +- </para> +- +- <para> +- The Linux I2C programming interfaces support only the master +- side of bus interactions, not the slave side. +- The programming interface is structured around two kinds of driver, +- and two kinds of device. +- An I2C "Adapter Driver" abstracts the controller hardware; it binds +- to a physical device (perhaps a PCI device or platform_device) and +- exposes a <structname>struct i2c_adapter</structname> representing +- each I2C bus segment it manages. +- On each I2C bus segment will be I2C devices represented by a +- <structname>struct i2c_client</structname>. Those devices will +- be bound to a <structname>struct i2c_driver</structname>, +- which should follow the standard Linux driver model. +- (At this writing, a legacy model is more widely used.) +- There are functions to perform various I2C protocol operations; at +- this writing all such functions are usable only from task context. +- </para> +- +- <para> +- The System Management Bus (SMBus) is a sibling protocol. Most SMBus +- systems are also I2C conformant. The electrical constraints are +- tighter for SMBus, and it standardizes particular protocol messages +- and idioms. Controllers that support I2C can also support most +- SMBus operations, but SMBus controllers don't support all the protocol +- options that an I2C controller will. +- There are functions to perform various SMBus protocol operations, +- either using I2C primitives or by issuing SMBus commands to +- i2c_adapter devices which don't support those I2C operations. +- </para> +- +-!Iinclude/linux/i2c.h +-!Fdrivers/i2c/i2c-boardinfo.c i2c_register_board_info +-!Edrivers/i2c/i2c-core.c +- </chapter> +- +-</book> +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/Documentation/DocBook/kernel-api.tmpl linux-2.6.29-rc3.owrt/Documentation/DocBook/kernel-api.tmpl +--- linux-2.6.29.owrt/Documentation/DocBook/kernel-api.tmpl 2009-05-10 22:04:39.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/Documentation/DocBook/kernel-api.tmpl 2009-05-10 23:48:28.000000000 +0200 +@@ -38,6 +38,58 @@ + + <toc></toc> + ++ <chapter id="Basics"> ++ <title>Driver Basics</title> ++ <sect1><title>Driver Entry and Exit points</title> ++!Iinclude/linux/init.h ++ </sect1> ++ ++ <sect1><title>Atomic and pointer manipulation</title> ++!Iarch/x86/include/asm/atomic_32.h ++!Iarch/x86/include/asm/unaligned.h ++ </sect1> ++ ++ <sect1><title>Delaying, scheduling, and timer routines</title> ++!Iinclude/linux/sched.h ++!Ekernel/sched.c ++!Ekernel/timer.c ++ </sect1> ++ <sect1><title>High-resolution timers</title> ++!Iinclude/linux/ktime.h ++!Iinclude/linux/hrtimer.h ++!Ekernel/hrtimer.c ++ </sect1> ++ <sect1><title>Workqueues and Kevents</title> ++!Ekernel/workqueue.c ++ </sect1> ++ <sect1><title>Internal Functions</title> ++!Ikernel/exit.c ++!Ikernel/signal.c ++!Iinclude/linux/kthread.h ++!Ekernel/kthread.c ++ </sect1> ++ ++ <sect1><title>Kernel objects manipulation</title> ++<!-- ++X!Iinclude/linux/kobject.h ++--> ++!Elib/kobject.c ++ </sect1> ++ ++ <sect1><title>Kernel utility functions</title> ++!Iinclude/linux/kernel.h ++!Ekernel/printk.c ++!Ekernel/panic.c ++!Ekernel/sys.c ++!Ekernel/rcupdate.c ++ </sect1> ++ ++ <sect1><title>Device Resource Management</title> ++!Edrivers/base/devres.c ++ </sect1> ++ ++ </chapter> ++ + <chapter id="adt"> + <title>Data Types</title> + <sect1><title>Doubly Linked Lists</title> +@@ -246,6 +298,62 @@ + !Ikernel/acct.c + </chapter> + ++ <chapter id="devdrivers"> ++ <title>Device drivers infrastructure</title> ++ <sect1><title>Device Drivers Base</title> ++<!-- ++X!Iinclude/linux/device.h ++--> ++!Edrivers/base/driver.c ++!Edrivers/base/core.c ++!Edrivers/base/class.c ++!Edrivers/base/firmware_class.c ++!Edrivers/base/transport_class.c ++<!-- Cannot be included, because ++ attribute_container_add_class_device_adapter ++ and attribute_container_classdev_to_container ++ exceed allowed 44 characters maximum ++X!Edrivers/base/attribute_container.c ++--> ++!Edrivers/base/sys.c ++<!-- ++X!Edrivers/base/interface.c ++--> ++!Edrivers/base/platform.c ++!Edrivers/base/bus.c ++ </sect1> ++ <sect1><title>Device Drivers Power Management</title> ++!Edrivers/base/power/main.c ++ </sect1> ++ <sect1><title>Device Drivers ACPI Support</title> ++<!-- Internal functions only ++X!Edrivers/acpi/sleep/main.c ++X!Edrivers/acpi/sleep/wakeup.c ++X!Edrivers/acpi/motherboard.c ++X!Edrivers/acpi/bus.c ++--> ++!Edrivers/acpi/scan.c ++!Idrivers/acpi/scan.c ++<!-- No correct structured comments ++X!Edrivers/acpi/pci_bind.c ++--> ++ </sect1> ++ <sect1><title>Device drivers PnP support</title> ++!Idrivers/pnp/core.c ++<!-- No correct structured comments ++X!Edrivers/pnp/system.c ++ --> ++!Edrivers/pnp/card.c ++!Idrivers/pnp/driver.c ++!Edrivers/pnp/manager.c ++!Edrivers/pnp/support.c ++ </sect1> ++ <sect1><title>Userspace IO devices</title> ++!Edrivers/uio/uio.c ++!Iinclude/linux/uio_driver.h ++ </sect1> ++ </chapter> ++ + <chapter id="blkdev"> + <title>Block Devices</title> + !Eblock/blk-core.c +@@ -273,6 +381,275 @@ + !Edrivers/char/misc.c + </chapter> + ++ <chapter id="parportdev"> ++ <title>Parallel Port Devices</title> ++!Iinclude/linux/parport.h ++!Edrivers/parport/ieee1284.c ++!Edrivers/parport/share.c ++!Idrivers/parport/daisy.c ++ </chapter> ++ ++ <chapter id="message_devices"> ++ <title>Message-based devices</title> ++ <sect1><title>Fusion message devices</title> ++!Edrivers/message/fusion/mptbase.c ++!Idrivers/message/fusion/mptbase.c ++!Edrivers/message/fusion/mptscsih.c ++!Idrivers/message/fusion/mptscsih.c ++!Idrivers/message/fusion/mptctl.c ++!Idrivers/message/fusion/mptspi.c ++!Idrivers/message/fusion/mptfc.c ++!Idrivers/message/fusion/mptlan.c ++ </sect1> ++ <sect1><title>I2O message devices</title> ++!Iinclude/linux/i2o.h ++!Idrivers/message/i2o/core.h ++!Edrivers/message/i2o/iop.c ++!Idrivers/message/i2o/iop.c ++!Idrivers/message/i2o/config-osm.c ++!Edrivers/message/i2o/exec-osm.c ++!Idrivers/message/i2o/exec-osm.c ++!Idrivers/message/i2o/bus-osm.c ++!Edrivers/message/i2o/device.c ++!Idrivers/message/i2o/device.c ++!Idrivers/message/i2o/driver.c ++!Idrivers/message/i2o/pci.c ++!Idrivers/message/i2o/i2o_block.c ++!Idrivers/message/i2o/i2o_scsi.c ++!Idrivers/message/i2o/i2o_proc.c ++ </sect1> ++ </chapter> ++ ++ <chapter id="snddev"> ++ <title>Sound Devices</title> ++!Iinclude/sound/core.h ++!Esound/sound_core.c ++!Iinclude/sound/pcm.h ++!Esound/core/pcm.c ++!Esound/core/device.c ++!Esound/core/info.c ++!Esound/core/rawmidi.c ++!Esound/core/sound.c ++!Esound/core/memory.c ++!Esound/core/pcm_memory.c ++!Esound/core/init.c ++!Esound/core/isadma.c ++!Esound/core/control.c ++!Esound/core/pcm_lib.c ++!Esound/core/hwdep.c ++!Esound/core/pcm_native.c ++!Esound/core/memalloc.c ++<!-- FIXME: Removed for now since no structured comments in source ++X!Isound/sound_firmware.c ++--> ++ </chapter> ++ ++ <chapter id="uart16x50"> ++ <title>16x50 UART Driver</title> ++!Iinclude/linux/serial_core.h ++!Edrivers/serial/serial_core.c ++!Edrivers/serial/8250.c ++ </chapter> ++ ++ <chapter id="fbdev"> ++ <title>Frame Buffer Library</title> ++ ++ <para> ++ The frame buffer drivers depend heavily on four data structures. ++ These structures are declared in include/linux/fb.h. They are ++ fb_info, fb_var_screeninfo, fb_fix_screeninfo and fb_monospecs. ++ The last three can be made available to and from userland. ++ </para> ++ ++ <para> ++ fb_info defines the current state of a particular video card. ++ Inside fb_info, there exists a fb_ops structure which is a ++ collection of needed functions to make fbdev and fbcon work. ++ fb_info is only visible to the kernel. ++ </para> ++ ++ <para> ++ fb_var_screeninfo is used to describe the features of a video card ++ that are user defined. With fb_var_screeninfo, things such as ++ depth and the resolution may be defined. ++ </para> ++ ++ <para> ++ The next structure is fb_fix_screeninfo. This defines the ++ properties of a card that are created when a mode is set and can't ++ be changed otherwise. A good example of this is the start of the ++ frame buffer memory. This "locks" the address of the frame buffer ++ memory, so that it cannot be changed or moved. ++ </para> ++ ++ <para> ++ The last structure is fb_monospecs. In the old API, there was ++ little importance for fb_monospecs. This allowed for forbidden things ++ such as setting a mode of 800x600 on a fix frequency monitor. With ++ the new API, fb_monospecs prevents such things, and if used ++ correctly, can prevent a monitor from being cooked. fb_monospecs ++ will not be useful until kernels 2.5.x. ++ </para> ++ ++ <sect1><title>Frame Buffer Memory</title> ++!Edrivers/video/fbmem.c ++ </sect1> ++<!-- ++ <sect1><title>Frame Buffer Console</title> ++X!Edrivers/video/console/fbcon.c ++ </sect1> ++--> ++ <sect1><title>Frame Buffer Colormap</title> ++!Edrivers/video/fbcmap.c ++ </sect1> ++<!-- FIXME: ++ drivers/video/fbgen.c has no docs, which stuffs up the sgml. Comment ++ out until somebody adds docs. KAO ++ <sect1><title>Frame Buffer Generic Functions</title> ++X!Idrivers/video/fbgen.c ++ </sect1> ++KAO --> ++ <sect1><title>Frame Buffer Video Mode Database</title> ++!Idrivers/video/modedb.c ++!Edrivers/video/modedb.c ++ </sect1> ++ <sect1><title>Frame Buffer Macintosh Video Mode Database</title> ++!Edrivers/video/macmodes.c ++ </sect1> ++ <sect1><title>Frame Buffer Fonts</title> ++ <para> ++ Refer to the file drivers/video/console/fonts.c for more information. ++ </para> ++<!-- FIXME: Removed for now since no structured comments in source ++X!Idrivers/video/console/fonts.c ++--> ++ </sect1> ++ </chapter> ++ ++ <chapter id="input_subsystem"> ++ <title>Input Subsystem</title> ++!Iinclude/linux/input.h ++!Edrivers/input/input.c ++!Edrivers/input/ff-core.c ++!Edrivers/input/ff-memless.c ++ </chapter> ++ ++ <chapter id="spi"> ++ <title>Serial Peripheral Interface (SPI)</title> ++ <para> ++ SPI is the "Serial Peripheral Interface", widely used with ++ embedded systems because it is a simple and efficient ++ interface: basically a multiplexed shift register. ++ Its three signal wires hold a clock (SCK, often in the range ++ of 1-20 MHz), a "Master Out, Slave In" (MOSI) data line, and ++ a "Master In, Slave Out" (MISO) data line. ++ SPI is a full duplex protocol; for each bit shifted out the ++ MOSI line (one per clock) another is shifted in on the MISO line. ++ Those bits are assembled into words of various sizes on the ++ way to and from system memory. ++ An additional chipselect line is usually active-low (nCS); ++ four signals are normally used for each peripheral, plus ++ sometimes an interrupt. ++ </para> ++ <para> ++ The SPI bus facilities listed here provide a generalized ++ interface to declare SPI busses and devices, manage them ++ according to the standard Linux driver model, and perform ++ input/output operations. ++ At this time, only "master" side interfaces are supported, ++ where Linux talks to SPI peripherals and does not implement ++ such a peripheral itself. ++ (Interfaces to support implementing SPI slaves would ++ necessarily look different.) ++ </para> ++ <para> ++ The programming interface is structured around two kinds of driver, ++ and two kinds of device. ++ A "Controller Driver" abstracts the controller hardware, which may ++ be as simple as a set of GPIO pins or as complex as a pair of FIFOs ++ connected to dual DMA engines on the other side of the SPI shift ++ register (maximizing throughput). Such drivers bridge between ++ whatever bus they sit on (often the platform bus) and SPI, and ++ expose the SPI side of their device as a ++ <structname>struct spi_master</structname>. ++ SPI devices are children of that master, represented as a ++ <structname>struct spi_device</structname> and manufactured from ++ <structname>struct spi_board_info</structname> descriptors which ++ are usually provided by board-specific initialization code. ++ A <structname>struct spi_driver</structname> is called a ++ "Protocol Driver", and is bound to a spi_device using normal ++ driver model calls. ++ </para> ++ <para> ++ The I/O model is a set of queued messages. Protocol drivers ++ submit one or more <structname>struct spi_message</structname> ++ objects, which are processed and completed asynchronously. ++ (There are synchronous wrappers, however.) Messages are ++ built from one or more <structname>struct spi_transfer</structname> ++ objects, each of which wraps a full duplex SPI transfer. ++ A variety of protocol tweaking options are needed, because ++ different chips adopt very different policies for how they ++ use the bits transferred with SPI. ++ </para> ++!Iinclude/linux/spi/spi.h ++!Fdrivers/spi/spi.c spi_register_board_info ++!Edrivers/spi/spi.c ++ </chapter> ++ ++ <chapter id="i2c"> ++ <title>I<superscript>2</superscript>C and SMBus Subsystem</title> ++ ++ <para> ++ I<superscript>2</superscript>C (or without fancy typography, "I2C") ++ is an acronym for the "Inter-IC" bus, a simple bus protocol which is ++ widely used where low data rate communications suffice. ++ Since it's also a licensed trademark, some vendors use another ++ name (such as "Two-Wire Interface", TWI) for the same bus. ++ I2C only needs two signals (SCL for clock, SDA for data), conserving ++ board real estate and minimizing signal quality issues. ++ Most I2C devices use seven bit addresses, and bus speeds of up ++ to 400 kHz; there's a high speed extension (3.4 MHz) that's not yet ++ found wide use. ++ I2C is a multi-master bus; open drain signaling is used to ++ arbitrate between masters, as well as to handshake and to ++ synchronize clocks from slower clients. ++ </para> ++ ++ <para> ++ The Linux I2C programming interfaces support only the master ++ side of bus interactions, not the slave side. ++ The programming interface is structured around two kinds of driver, ++ and two kinds of device. ++ An I2C "Adapter Driver" abstracts the controller hardware; it binds ++ to a physical device (perhaps a PCI device or platform_device) and ++ exposes a <structname>struct i2c_adapter</structname> representing ++ each I2C bus segment it manages. ++ On each I2C bus segment will be I2C devices represented by a ++ <structname>struct i2c_client</structname>. Those devices will ++ be bound to a <structname>struct i2c_driver</structname>, ++ which should follow the standard Linux driver model. ++ (At this writing, a legacy model is more widely used.) ++ There are functions to perform various I2C protocol operations; at ++ this writing all such functions are usable only from task context. ++ </para> ++ ++ <para> ++ The System Management Bus (SMBus) is a sibling protocol. Most SMBus ++ systems are also I2C conformant. The electrical constraints are ++ tighter for SMBus, and it standardizes particular protocol messages ++ and idioms. Controllers that support I2C can also support most ++ SMBus operations, but SMBus controllers don't support all the protocol ++ options that an I2C controller will. ++ There are functions to perform various SMBus protocol operations, ++ either using I2C primitives or by issuing SMBus commands to ++ i2c_adapter devices which don't support those I2C operations. ++ </para> ++ ++!Iinclude/linux/i2c.h ++!Fdrivers/i2c/i2c-boardinfo.c i2c_register_board_info ++!Edrivers/i2c/i2c-core.c ++ </chapter> ++ + <chapter id="clk"> + <title>Clock Framework</title> + +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/Documentation/DocBook/Makefile linux-2.6.29-rc3.owrt/Documentation/DocBook/Makefile +--- linux-2.6.29.owrt/Documentation/DocBook/Makefile 2009-05-10 22:04:39.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/Documentation/DocBook/Makefile 2009-05-10 23:48:28.000000000 +0200 +@@ -6,7 +6,7 @@ + # To add a new book the only step required is to add the book to the + # list of DOCBOOKS. + +-DOCBOOKS := z8530book.xml mcabook.xml device-drivers.xml \ ++DOCBOOKS := z8530book.xml mcabook.xml \ + kernel-hacking.xml kernel-locking.xml deviceiobook.xml \ + procfs-guide.xml writing_usb_driver.xml networking.xml \ + kernel-api.xml filesystems.xml lsm.xml usb.xml kgdb.xml \ +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/Documentation/DocBook/uio-howto.tmpl linux-2.6.29-rc3.owrt/Documentation/DocBook/uio-howto.tmpl +--- linux-2.6.29.owrt/Documentation/DocBook/uio-howto.tmpl 2009-05-10 22:04:39.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/Documentation/DocBook/uio-howto.tmpl 2009-05-10 23:48:28.000000000 +0200 +@@ -42,12 +42,6 @@ + + <revhistory> + <revision> +- <revnumber>0.7</revnumber> +- <date>2008-12-23</date> +- <authorinitials>hjk</authorinitials> +- <revremark>Added generic platform drivers and offset attribute.</revremark> +- </revision> +- <revision> + <revnumber>0.6</revnumber> + <date>2008-12-05</date> + <authorinitials>hjk</authorinitials> +@@ -318,16 +312,6 @@ + pointed to by addr. + </para> + </listitem> +-<listitem> +- <para> +- <filename>offset</filename>: The offset, in bytes, that has to be +- added to the pointer returned by <function>mmap()</function> to get +- to the actual device memory. This is important if the device's memory +- is not page aligned. Remember that pointers returned by +- <function>mmap()</function> are always page aligned, so it is good +- style to always add this offset. +- </para> +-</listitem> + </itemizedlist> + + <para> +@@ -610,78 +594,6 @@ + </para> + </sect1> + +-<sect1 id="using_uio_pdrv"> +-<title>Using uio_pdrv for platform devices</title> +- <para> +- In many cases, UIO drivers for platform devices can be handled in a +- generic way. In the same place where you define your +- <varname>struct platform_device</varname>, you simply also implement +- your interrupt handler and fill your +- <varname>struct uio_info</varname>. A pointer to this +- <varname>struct uio_info</varname> is then used as +- <varname>platform_data</varname> for your platform device. +- </para> +- <para> +- You also need to set up an array of <varname>struct resource</varname> +- containing addresses and sizes of your memory mappings. This +- information is passed to the driver using the +- <varname>.resource</varname> and <varname>.num_resources</varname> +- elements of <varname>struct platform_device</varname>. +- </para> +- <para> +- You now have to set the <varname>.name</varname> element of +- <varname>struct platform_device</varname> to +- <varname>"uio_pdrv"</varname> to use the generic UIO platform device +- driver. This driver will fill the <varname>mem[]</varname> array +- according to the resources given, and register the device. +- </para> +- <para> +- The advantage of this approach is that you only have to edit a file +- you need to edit anyway. You do not have to create an extra driver. +- </para> +-</sect1> +- +-<sect1 id="using_uio_pdrv_genirq"> +-<title>Using uio_pdrv_genirq for platform devices</title> +- <para> +- Especially in embedded devices, you frequently find chips where the +- irq pin is tied to its own dedicated interrupt line. In such cases, +- where you can be really sure the interrupt is not shared, we can take +- the concept of <varname>uio_pdrv</varname> one step further and use a +- generic interrupt handler. That's what +- <varname>uio_pdrv_genirq</varname> does. +- </para> +- <para> +- The setup for this driver is the same as described above for +- <varname>uio_pdrv</varname>, except that you do not implement an +- interrupt handler. The <varname>.handler</varname> element of +- <varname>struct uio_info</varname> must remain +- <varname>NULL</varname>. The <varname>.irq_flags</varname> element +- must not contain <varname>IRQF_SHARED</varname>. +- </para> +- <para> +- You will set the <varname>.name</varname> element of +- <varname>struct platform_device</varname> to +- <varname>"uio_pdrv_genirq"</varname> to use this driver. +- </para> +- <para> +- The generic interrupt handler of <varname>uio_pdrv_genirq</varname> +- will simply disable the interrupt line using +- <function>disable_irq_nosync()</function>. After doing its work, +- userspace can reenable the interrupt by writing 0x00000001 to the UIO +- device file. The driver already implements an +- <function>irq_control()</function> to make this possible, you must not +- implement your own. +- </para> +- <para> +- Using <varname>uio_pdrv_genirq</varname> not only saves a few lines of +- interrupt handler code. You also do not need to know anything about +- the chip's internal registers to create the kernel part of the driver. +- All you need to know is the irq number of the pin the chip is +- connected to. +- </para> +-</sect1> +- + </chapter> + + <chapter id="userspace_driver" xreflabel="Writing a driver in user space"> +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/Documentation/driver-model/device.txt linux-2.6.29-rc3.owrt/Documentation/driver-model/device.txt +--- linux-2.6.29.owrt/Documentation/driver-model/device.txt 2009-05-10 22:04:39.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/Documentation/driver-model/device.txt 2009-05-10 23:48:28.000000000 +0200 +@@ -127,11 +127,9 @@ + Attributes + ~~~~~~~~~~ + struct device_attribute { +- struct attribute attr; +- ssize_t (*show)(struct device *dev, struct device_attribute *attr, +- char *buf); +- ssize_t (*store)(struct device *dev, struct device_attribute *attr, +- const char *buf, size_t count); ++ struct attribute attr; ++ ssize_t (*show)(struct device * dev, char * buf, size_t count, loff_t off); ++ ssize_t (*store)(struct device * dev, const char * buf, size_t count, loff_t off); + }; + + Attributes of devices can be exported via drivers using a simple +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/Documentation/dvb/README.flexcop linux-2.6.29-rc3.owrt/Documentation/dvb/README.flexcop +--- linux-2.6.29.owrt/Documentation/dvb/README.flexcop 1970-01-01 01:00:00.000000000 +0100 ++++ linux-2.6.29-rc3.owrt/Documentation/dvb/README.flexcop 2009-05-10 23:48:28.000000000 +0200 +@@ -0,0 +1,205 @@ ++This README escorted the skystar2-driver rewriting procedure. It describes the ++state of the new flexcop-driver set and some internals are written down here ++too. ++ ++This document hopefully describes things about the flexcop and its ++device-offsprings. Goal was to write an easy-to-write and easy-to-read set of ++drivers based on the skystar2.c and other information. ++ ++Remark: flexcop-pci.c was a copy of skystar2.c, but every line has been ++touched and rewritten. ++ ++History & News ++============== ++ 2005-04-01 - correct USB ISOC transfers (thanks to Vadim Catana) ++ ++ ++ ++ ++General coding processing ++========================= ++ ++We should proceed as follows (as long as no one complains): ++ ++0) Think before start writing code! ++ ++1) rewriting the skystar2.c with the help of the flexcop register descriptions ++and splitting up the files to a pci-bus-part and a flexcop-part. ++The new driver will be called b2c2-flexcop-pci.ko/b2c2-flexcop-usb.ko for the ++device-specific part and b2c2-flexcop.ko for the common flexcop-functions. ++ ++2) Search for errors in the leftover of flexcop-pci.c (compare with pluto2.c ++and other pci drivers) ++ ++3) make some beautification (see 'Improvements when rewriting (refactoring) is ++done') ++ ++4) Testing the new driver and maybe substitute the skystar2.c with it, to reach ++a wider tester audience. ++ ++5) creating an usb-bus-part using the already written flexcop code for the pci ++card. ++ ++Idea: create a kernel-object for the flexcop and export all important ++functions. This option saves kernel-memory, but maybe a lot of functions have ++to be exported to kernel namespace. ++ ++ ++Current situation ++================= ++ ++0) Done :) ++1) Done (some minor issues left) ++2) Done ++3) Not ready yet, more information is necessary ++4) next to be done (see the table below) ++5) USB driver is working (yes, there are some minor issues) ++ ++What seems to be ready? ++----------------------- ++ ++1) Rewriting ++1a) i2c is cut off from the flexcop-pci.c and seems to work ++1b) moved tuner and demod stuff from flexcop-pci.c to flexcop-tuner-fe.c ++1c) moved lnb and diseqc stuff from flexcop-pci.c to flexcop-tuner-fe.c ++1e) eeprom (reading MAC address) ++1d) sram (no dynamic sll size detection (commented out) (using default as JJ told me)) ++1f) misc. register accesses for reading parameters (e.g. resetting, revision) ++1g) pid/mac filter (flexcop-hw-filter.c) ++1i) dvb-stuff initialization in flexcop.c (done) ++1h) dma stuff (now just using the size-irq, instead of all-together, to be done) ++1j) remove flexcop initialization from flexcop-pci.c completely (done) ++1l) use a well working dma IRQ method (done, see 'Known bugs and problems and TODO') ++1k) cleanup flexcop-files (remove unused EXPORT_SYMBOLs, make static from ++non-static where possible, moved code to proper places) ++ ++2) Search for errors in the leftover of flexcop-pci.c (partially done) ++5a) add MAC address reading ++5c) feeding of ISOC data to the software demux (format of the isochronous data ++and speed optimization, no real error) (thanks to Vadim Catana) ++ ++What to do in the near future? ++-------------------------------------- ++(no special order here) ++ ++5) USB driver ++5b) optimize isoc-transfer (submitting/killing isoc URBs when transfer is starting) ++ ++Testing changes ++--------------- ++ ++O = item is working ++P = item is partially working ++X = item is not working ++N = item does not apply here ++<empty field> = item need to be examined ++ ++ | PCI | USB ++item | mt352 | nxt2002 | stv0299 | mt312 | mt352 | nxt2002 | stv0299 | mt312 ++-------+-------+---------+---------+-------+-------+---------+---------+------- ++1a) | O | | | | N | N | N | N ++1b) | O | | | | | | O | ++1c) | N | N | | | N | N | O | ++1d) | O | O ++1e) | O | O ++1f) | P ++1g) | O ++1h) | P | ++1i) | O | N ++1j) | O | N ++1l) | O | N ++2) | O | N ++5a) | N | O ++5b)* | N | ++5c) | N | O ++ ++* - not done yet ++ ++Known bugs and problems and TODO ++-------------------------------- ++ ++1g/h/l) when pid filtering is enabled on the pci card ++ ++DMA usage currently: ++ The DMA is splitted in 2 equal-sized subbuffers. The Flexcop writes to first ++ address and triggers an IRQ when it's full and starts writing to the second ++ address. When the second address is full, the IRQ is triggered again, and ++ the flexcop writes to first address again, and so on. ++ The buffersize of each address is currently 640*188 bytes. ++ ++ Problem is, when using hw-pid-filtering and doing some low-bandwidth ++ operation (like scanning) the buffers won't be filled enough to trigger ++ the IRQ. That's why: ++ ++ When PID filtering is activated, the timer IRQ is used. Every 1.97 ms the IRQ ++ is triggered. Is the current write address of DMA1 different to the one ++ during the last IRQ, then the data is passed to the demuxer. ++ ++ There is an additional DMA-IRQ-method: packet count IRQ. This isn't ++ implemented correctly yet. ++ ++ The solution is to disable HW PID filtering, but I don't know how the DVB ++ API software demux behaves on slow systems with 45MBit/s TS. ++ ++Solved bugs :) ++-------------- ++1g) pid-filtering (somehow pid index 4 and 5 (EMM_PID and ECM_PID) aren't ++working) ++SOLUTION: also index 0 was affected, because net_translation is done for ++these indexes by default ++ ++5b) isochronous transfer does only work in the first attempt (for the Sky2PC ++USB, Air2PC is working) SOLUTION: the flexcop was going asleep and never really ++woke up again (don't know if this need fixes, see ++flexcop-fe-tuner.c:flexcop_sleep) ++ ++NEWS: when the driver is loaded and unloaded and loaded again (w/o doing ++anything in the while the driver is loaded the first time), no transfers take ++place anymore. ++ ++Improvements when rewriting (refactoring) is done ++================================================= ++ ++- split sleeping of the flexcop (misc_204.ACPI3_sig = 1;) from lnb_control ++ (enable sleeping for other demods than dvb-s) ++- add support for CableStar (stv0297 Microtune 203x/ALPS) (almost done, incompatibilities with the Nexus-CA) ++ ++Debugging ++--------- ++- add verbose debugging to skystar2.c (dump the reg_dw_data) and compare it ++ with this flexcop, this is important, because i2c is now using the ++ flexcop_ibi_value union from flexcop-reg.h (do you have a better idea for ++ that, please tell us so). ++ ++Everything which is identical in the following table, can be put into a common ++flexcop-module. ++ ++ PCI USB ++------------------------------------------------------------------------------- ++Different: ++Register access: accessing IO memory USB control message ++I2C bus: I2C bus of the FC USB control message ++Data transfer: DMA isochronous transfer ++EEPROM transfer: through i2c bus not clear yet ++ ++Identical: ++Streaming: accessing registers ++PID Filtering: accessing registers ++Sram destinations: accessing registers ++Tuner/Demod: I2C bus ++DVB-stuff: can be written for common use ++ ++Acknowledgements (just for the rewriting part) ++================ ++ ++Bjarne Steinsbo thought a lot in the first place of the pci part for this code ++sharing idea. ++ ++Andreas Oberritter for providing a recent PCI initialization template ++(pluto2.c). ++ ++Boleslaw Ciesielski for pointing out a problem with firmware loader. ++ ++Vadim Catana for correcting the USB transfer. ++ ++comments, critics and ideas to linux-dvb@linuxtv.org. +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/Documentation/dvb/technisat.txt linux-2.6.29-rc3.owrt/Documentation/dvb/technisat.txt +--- linux-2.6.29.owrt/Documentation/dvb/technisat.txt 2009-05-10 22:04:39.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/Documentation/dvb/technisat.txt 2009-05-10 23:48:28.000000000 +0200 +@@ -1,5 +1,5 @@ +-How to set up the Technisat/B2C2 Flexcop devices +-================================================ ++How to set up the Technisat devices ++=================================== + + 1) Find out what device you have + ================================ +@@ -16,60 +16,54 @@ + + If the Technisat is the only TV device in your box get rid of unnecessary modules and check this one: + "Multimedia devices" => "Customise analog and hybrid tuner modules to build" +-In this directory uncheck every driver which is activated there (except "Simple tuner support" for case 9 only). ++In this directory uncheck every driver which is activated there. + + Then please activate: + 2a) Main module part: + + a.)"Multimedia devices" => "DVB/ATSC adapters" => "Technisat/B2C2 FlexcopII(b) and FlexCopIII adapters" +-b.)"Multimedia devices" => "DVB/ATSC adapters" => "Technisat/B2C2 FlexcopII(b) and FlexCopIII adapters" => "Technisat/B2C2 Air/Sky/Cable2PC PCI" in case of a PCI card +-OR ++b.)"Multimedia devices" => "DVB/ATSC adapters" => "Technisat/B2C2 FlexcopII(b) and FlexCopIII adapters" => "Technisat/B2C2 Air/Sky/Cable2PC PCI" in case of a PCI card OR + c.)"Multimedia devices" => "DVB/ATSC adapters" => "Technisat/B2C2 FlexcopII(b) and FlexCopIII adapters" => "Technisat/B2C2 Air/Sky/Cable2PC USB" in case of an USB 1.1 adapter + d.)"Multimedia devices" => "DVB/ATSC adapters" => "Technisat/B2C2 FlexcopII(b) and FlexCopIII adapters" => "Enable debug for the B2C2 FlexCop drivers" + Notice: d.) is helpful for troubleshooting + + 2b) Frontend module part: + +-1.) SkyStar DVB-S Revision 2.3: ++1.) Revision 2.3: + a.)"Multimedia devices" => "Customise DVB frontends" => "Customise the frontend modules to build" + b.)"Multimedia devices" => "Customise DVB frontends" => "Zarlink VP310/MT312/ZL10313 based" + +-2.) SkyStar DVB-S Revision 2.6: ++2.) Revision 2.6: + a.)"Multimedia devices" => "Customise DVB frontends" => "Customise the frontend modules to build" + b.)"Multimedia devices" => "Customise DVB frontends" => "ST STV0299 based" + +-3.) SkyStar DVB-S Revision 2.7: ++3.) Revision 2.7: + a.)"Multimedia devices" => "Customise DVB frontends" => "Customise the frontend modules to build" + b.)"Multimedia devices" => "Customise DVB frontends" => "Samsung S5H1420 based" + c.)"Multimedia devices" => "Customise DVB frontends" => "Integrant ITD1000 Zero IF tuner for DVB-S/DSS" + d.)"Multimedia devices" => "Customise DVB frontends" => "ISL6421 SEC controller" + +-4.) SkyStar DVB-S Revision 2.8: ++4.) Revision 2.8: + a.)"Multimedia devices" => "Customise DVB frontends" => "Customise the frontend modules to build" + b.)"Multimedia devices" => "Customise DVB frontends" => "Conexant CX24113/CX24128 tuner for DVB-S/DSS" + c.)"Multimedia devices" => "Customise DVB frontends" => "Conexant CX24123 based" + d.)"Multimedia devices" => "Customise DVB frontends" => "ISL6421 SEC controller" + +-5.) AirStar DVB-T card: ++5.) DVB-T card: + a.)"Multimedia devices" => "Customise DVB frontends" => "Customise the frontend modules to build" + b.)"Multimedia devices" => "Customise DVB frontends" => "Zarlink MT352 based" + +-6.) CableStar DVB-C card: ++6.) DVB-C card: + a.)"Multimedia devices" => "Customise DVB frontends" => "Customise the frontend modules to build" + b.)"Multimedia devices" => "Customise DVB frontends" => "ST STV0297 based" + +-7.) AirStar ATSC card 1st generation: ++7.) ATSC card 1st generation: + a.)"Multimedia devices" => "Customise DVB frontends" => "Customise the frontend modules to build" + b.)"Multimedia devices" => "Customise DVB frontends" => "Broadcom BCM3510" + +-8.) AirStar ATSC card 2nd generation: ++8.) ATSC card 2nd generation: + a.)"Multimedia devices" => "Customise DVB frontends" => "Customise the frontend modules to build" + b.)"Multimedia devices" => "Customise DVB frontends" => "NxtWave Communications NXT2002/NXT2004 based" +-c.)"Multimedia devices" => "Customise DVB frontends" => "Generic I2C PLL based tuners" ++c.)"Multimedia devices" => "Customise DVB frontends" => "LG Electronics LGDT3302/LGDT3303 based" + +-9.) AirStar ATSC card 3rd generation: +-a.)"Multimedia devices" => "Customise DVB frontends" => "Customise the frontend modules to build" +-b.)"Multimedia devices" => "Customise DVB frontends" => "LG Electronics LGDT3302/LGDT3303 based" +-c.)"Multimedia devices" => "Customise analog and hybrid tuner modules to build" => "Simple tuner support" +- +-Author: Uwe Bugla <uwe.bugla@gmx.de> February 2009 ++Author: Uwe Bugla <uwe.bugla@gmx.de> December 2008 +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/Documentation/feature-removal-schedule.txt linux-2.6.29-rc3.owrt/Documentation/feature-removal-schedule.txt +--- linux-2.6.29.owrt/Documentation/feature-removal-schedule.txt 2009-05-10 22:04:39.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/Documentation/feature-removal-schedule.txt 2009-05-10 23:48:28.000000000 +0200 +@@ -335,12 +335,3 @@ + Secmark, it is time to deprecate the older mechanism and start the + process of removing the old code. + Who: Paul Moore <paul.moore@hp.com> +---------------------------- +- +-What: sysfs ui for changing p4-clockmod parameters +-When: September 2009 +-Why: See commits 129f8ae9b1b5be94517da76009ea956e89104ce8 and +- e088e4c9cdb618675874becb91b2fd581ee707e6. +- Removal is subject to fixing any remaining bugs in ACPI which may +- cause the thermal throttling not to happen at the right time. +-Who: Dave Jones <davej@redhat.com>, Matthew Garrett <mjg@redhat.com> +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/Documentation/filesystems/ext2.txt linux-2.6.29-rc3.owrt/Documentation/filesystems/ext2.txt +--- linux-2.6.29.owrt/Documentation/filesystems/ext2.txt 2009-05-10 22:04:39.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/Documentation/filesystems/ext2.txt 2009-05-10 23:48:28.000000000 +0200 +@@ -373,11 +373,10 @@ + Compression (*) http://e2compr.sourceforge.net/ + + Implementations for: +-Windows 95/98/NT/2000 http://www.chrysocome.net/explore2fs +-Windows 95 (*) http://www.yipton.net/content.html#FSDEXT2 ++Windows 95/98/NT/2000 http://uranus.it.swin.edu.au/~jn/linux/Explore2fs.htm ++Windows 95 (*) http://www.yipton.demon.co.uk/content.html#FSDEXT2 + DOS client (*) ftp://metalab.unc.edu/pub/Linux/system/filesystems/ext2/ +-OS/2 (+) ftp://metalab.unc.edu/pub/Linux/system/filesystems/ext2/ +-RISC OS client http://www.esw-heim.tu-clausthal.de/~marco/smorbrod/IscaFS/ ++OS/2 http://perso.wanadoo.fr/matthieu.willm/ext2-os2/ ++RISC OS client ftp://ftp.barnet.ac.uk/pub/acorn/armlinux/iscafs/ + + (*) no longer actively developed/supported (as of Apr 2001) +-(+) no longer actively developed/supported (as of Mar 2009) +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/Documentation/filesystems/ext3.txt linux-2.6.29-rc3.owrt/Documentation/filesystems/ext3.txt +--- linux-2.6.29.owrt/Documentation/filesystems/ext3.txt 2009-05-10 22:04:39.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/Documentation/filesystems/ext3.txt 2009-05-10 23:48:28.000000000 +0200 +@@ -198,5 +198,5 @@ + programs: http://e2fsprogs.sourceforge.net/ + http://ext2resize.sourceforge.net + +-useful links: http://www.ibm.com/developerworks/library/l-fs7.html +- http://www.ibm.com/developerworks/library/l-fs8.html ++useful links: http://www-106.ibm.com/developerworks/linux/library/l-fs7/ ++ http://www-106.ibm.com/developerworks/linux/library/l-fs8/ +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/Documentation/filesystems/proc.txt linux-2.6.29-rc3.owrt/Documentation/filesystems/proc.txt +--- linux-2.6.29.owrt/Documentation/filesystems/proc.txt 2009-05-10 22:04:39.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/Documentation/filesystems/proc.txt 2009-05-10 23:48:28.000000000 +0200 +@@ -1478,13 +1478,6 @@ + this should be enabled, but if the problem persists the messages can be + disabled. + +-netdev_budget +-------------- +- +-Maximum number of packets taken from all interfaces in one polling cycle (NAPI +-poll). In one polling cycle interfaces which are registered to polling are +-probed in a round-robin manner. The limit of packets in one such probe can be +-set per-device via sysfs class/net/<device>/weight . + + netdev_max_backlog + ------------------ +@@ -2034,34 +2027,6 @@ + values are in the range -16 to +15, plus the special value -17, which disables + oom-killing altogether for this process. + +-The process to be killed in an out-of-memory situation is selected among all others +-based on its badness score. This value equals the original memory size of the process +-and is then updated according to its CPU time (utime + stime) and the +-run time (uptime - start time). The longer it runs the smaller is the score. +-Badness score is divided by the square root of the CPU time and then by +-the double square root of the run time. +- +-Swapped out tasks are killed first. Half of each child's memory size is added to +-the parent's score if they do not share the same memory. Thus forking servers +-are the prime candidates to be killed. Having only one 'hungry' child will make +-parent less preferable than the child. +- +-/proc/<pid>/oom_score shows process' current badness score. +- +-The following heuristics are then applied: +- * if the task was reniced, its score doubles +- * superuser or direct hardware access tasks (CAP_SYS_ADMIN, CAP_SYS_RESOURCE +- or CAP_SYS_RAWIO) have their score divided by 4 +- * if oom condition happened in one cpuset and checked task does not belong +- to it, its score is divided by 8 +- * the resulting score is multiplied by two to the power of oom_adj, i.e. +- points <<= oom_adj when it is positive and +- points >>= -(oom_adj) otherwise +- +-The task with the highest badness score is then selected and its children +-are killed, process itself will be killed in an OOM situation when it does +-not have children or some of them disabled oom like described above. +- + 2.13 /proc/<pid>/oom_score - Display current oom-killer score + ------------------------------------------------------------- + +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/Documentation/filesystems/squashfs.txt linux-2.6.29-rc3.owrt/Documentation/filesystems/squashfs.txt +--- linux-2.6.29.owrt/Documentation/filesystems/squashfs.txt 2009-05-10 22:04:39.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/Documentation/filesystems/squashfs.txt 2009-05-10 23:48:28.000000000 +0200 +@@ -22,7 +22,7 @@ + + Squashfs Cramfs + +-Max filesystem size: 2^64 256 MiB ++Max filesystem size: 2^64 16 MiB + Max file size: ~ 2 TiB 16 MiB + Max files: unlimited unlimited + Max directories: unlimited unlimited +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/Documentation/filesystems/sysfs-pci.txt linux-2.6.29-rc3.owrt/Documentation/filesystems/sysfs-pci.txt +--- linux-2.6.29.owrt/Documentation/filesystems/sysfs-pci.txt 2009-05-10 22:04:39.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/Documentation/filesystems/sysfs-pci.txt 2009-05-10 23:48:28.000000000 +0200 +@@ -9,7 +9,6 @@ + | |-- class + | |-- config + | |-- device +- | |-- enable + | |-- irq + | |-- local_cpus + | |-- resource +@@ -33,7 +32,6 @@ + class PCI class (ascii, ro) + config PCI config space (binary, rw) + device PCI device (ascii, ro) +- enable Whether the device is enabled (ascii, rw) + irq IRQ number (ascii, ro) + local_cpus nearby CPU mask (cpumask, ro) + resource PCI resource host addresses (ascii, ro) +@@ -59,19 +57,10 @@ + don't support mmapping of certain resources, so be sure to check the return + value from any attempted mmap. + +-The 'enable' file provides a counter that indicates how many times the device +-has been enabled. If the 'enable' file currently returns '4', and a '1' is +-echoed into it, it will then return '5'. Echoing a '0' into it will decrease +-the count. Even when it returns to 0, though, some of the initialisation +-may not be reversed. +- + The 'rom' file is special in that it provides read-only access to the device's + ROM file, if available. It's disabled by default, however, so applications + should write the string "1" to the file to enable it before attempting a read +-call, and disable it following the access by writing "0" to the file. Note +-that the device must be enabled for a rom read to return data succesfully. +-In the event a driver is not bound to the device, it can be enabled using the +-'enable' file, documented above. ++call, and disable it following the access by writing "0" to the file. + + Accessing legacy resources through sysfs + ---------------------------------------- +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/Documentation/filesystems/sysfs.txt linux-2.6.29-rc3.owrt/Documentation/filesystems/sysfs.txt +--- linux-2.6.29.owrt/Documentation/filesystems/sysfs.txt 2009-05-10 22:04:39.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/Documentation/filesystems/sysfs.txt 2009-05-10 23:48:28.000000000 +0200 +@@ -2,10 +2,8 @@ + sysfs - _The_ filesystem for exporting kernel objects. + + Patrick Mochel <mochel@osdl.org> +-Mike Murphy <mamurph@cs.clemson.edu> + +-Revised: 22 February 2009 +-Original: 10 January 2003 ++10 January 2003 + + + What it is: +@@ -66,13 +64,12 @@ + + struct attribute { + char * name; +- struct module *owner; + mode_t mode; + }; + + +-int sysfs_create_file(struct kobject * kobj, const struct attribute * attr); +-void sysfs_remove_file(struct kobject * kobj, const struct attribute * attr); ++int sysfs_create_file(struct kobject * kobj, struct attribute * attr); ++void sysfs_remove_file(struct kobject * kobj, struct attribute * attr); + + + A bare attribute contains no means to read or write the value of the +@@ -83,11 +80,9 @@ + For example, the driver model defines struct device_attribute like: + + struct device_attribute { +- struct attribute attr; +- ssize_t (*show)(struct device *dev, struct device_attribute *attr, +- char *buf); +- ssize_t (*store)(struct device *dev, struct device_attribute *attr, +- const char *buf, size_t count); ++ struct attribute attr; ++ ssize_t (*show)(struct device * dev, char * buf); ++ ssize_t (*store)(struct device * dev, const char * buf); + }; + + int device_create_file(struct device *, struct device_attribute *); +@@ -95,8 +90,12 @@ + + It also defines this helper for defining device attributes: + +-#define DEVICE_ATTR(_name, _mode, _show, _store) \ +-struct device_attribute dev_attr_##_name = __ATTR(_name, _mode, _show, _store) ++#define DEVICE_ATTR(_name, _mode, _show, _store) \ ++struct device_attribute dev_attr_##_name = { \ ++ .attr = {.name = __stringify(_name) , .mode = _mode }, \ ++ .show = _show, \ ++ .store = _store, \ ++}; + + For example, declaring + +@@ -108,9 +107,9 @@ + .attr = { + .name = "foo", + .mode = S_IWUSR | S_IRUGO, +- .show = show_foo, +- .store = store_foo, + }, ++ .show = show_foo, ++ .store = store_foo, + }; + + +@@ -162,12 +161,10 @@ + specified when declaring the attribute. The method types should be as + simple as those defined for device attributes: + +-ssize_t (*show)(struct device * dev, struct device_attribute * attr, +- char * buf); +-ssize_t (*store)(struct device * dev, struct device_attribute * attr, +- const char * buf); ++ ssize_t (*show)(struct device * dev, char * buf); ++ ssize_t (*store)(struct device * dev, const char * buf); + +-IOW, they should take only an object, an attribute, and a buffer as parameters. ++IOW, they should take only an object and a buffer as parameters. + + + sysfs allocates a buffer of size (PAGE_SIZE) and passes it to the +@@ -302,16 +299,14 @@ + Structure: + + struct device_attribute { +- struct attribute attr; +- ssize_t (*show)(struct device *dev, struct device_attribute *attr, +- char *buf); +- ssize_t (*store)(struct device *dev, struct device_attribute *attr, +- const char *buf, size_t count); ++ struct attribute attr; ++ ssize_t (*show)(struct device * dev, char * buf); ++ ssize_t (*store)(struct device * dev, const char * buf); + }; + + Declaring: + +-DEVICE_ATTR(_name, _mode, _show, _store); ++DEVICE_ATTR(_name, _str, _mode, _show, _store); + + Creation/Removal: + +@@ -347,8 +342,7 @@ + struct driver_attribute { + struct attribute attr; + ssize_t (*show)(struct device_driver *, char * buf); +- ssize_t (*store)(struct device_driver *, const char * buf, +- size_t count); ++ ssize_t (*store)(struct device_driver *, const char * buf); + }; + + Declaring: +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/Documentation/filesystems/ubifs.txt linux-2.6.29-rc3.owrt/Documentation/filesystems/ubifs.txt +--- linux-2.6.29.owrt/Documentation/filesystems/ubifs.txt 2009-05-10 22:04:39.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/Documentation/filesystems/ubifs.txt 2009-05-10 23:48:28.000000000 +0200 +@@ -79,6 +79,13 @@ + + (*) == default. + ++norm_unmount (*) commit on unmount; the journal is committed ++ when the file-system is unmounted so that the ++ next mount does not have to replay the journal ++ and it becomes very fast; ++fast_unmount do not commit on unmount; this option makes ++ unmount faster, but the next mount slower ++ because of the need to replay the journal. + bulk_read read more in one go to take advantage of flash + media that read faster sequentially + no_bulk_read (*) do not bulk-read +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/Documentation/hwmon/hpfall.c linux-2.6.29-rc3.owrt/Documentation/hwmon/hpfall.c +--- linux-2.6.29.owrt/Documentation/hwmon/hpfall.c 2009-05-10 22:04:39.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/Documentation/hwmon/hpfall.c 1970-01-01 01:00:00.000000000 +0100 +@@ -1,101 +0,0 @@ +-/* Disk protection for HP machines. +- * +- * Copyright 2008 Eric Piel +- * Copyright 2009 Pavel Machek <pavel@suse.cz> +- * +- * GPLv2. +- */ +- +-#include <stdio.h> +-#include <stdlib.h> +-#include <unistd.h> +-#include <fcntl.h> +-#include <sys/stat.h> +-#include <sys/types.h> +-#include <string.h> +-#include <stdint.h> +-#include <errno.h> +-#include <signal.h> +- +-void write_int(char *path, int i) +-{ +- char buf[1024]; +- int fd = open(path, O_RDWR); +- if (fd < 0) { +- perror("open"); +- exit(1); +- } +- sprintf(buf, "%d", i); +- if (write(fd, buf, strlen(buf)) != strlen(buf)) { +- perror("write"); +- exit(1); +- } +- close(fd); +-} +- +-void set_led(int on) +-{ +- write_int("/sys/class/leds/hp::hddprotect/brightness", on); +-} +- +-void protect(int seconds) +-{ +- write_int("/sys/block/sda/device/unload_heads", seconds*1000); +-} +- +-int on_ac(void) +-{ +-// /sys/class/power_supply/AC0/online +-} +- +-int lid_open(void) +-{ +-// /proc/acpi/button/lid/LID/state +-} +- +-void ignore_me(void) +-{ +- protect(0); +- set_led(0); +- +-} +- +-int main(int argc, char* argv[]) +-{ +- int fd, ret; +- +- fd = open("/dev/freefall", O_RDONLY); +- if (fd < 0) { +- perror("open"); +- return EXIT_FAILURE; +- } +- +- signal(SIGALRM, ignore_me); +- +- for (;;) { +- unsigned char count; +- +- ret = read(fd, &count, sizeof(count)); +- alarm(0); +- if ((ret == -1) && (errno == EINTR)) { +- /* Alarm expired, time to unpark the heads */ +- continue; +- } +- +- if (ret != sizeof(count)) { +- perror("read"); +- break; +- } +- +- protect(21); +- set_led(1); +- if (1 || on_ac() || lid_open()) { +- alarm(2); +- } else { +- alarm(20); +- } +- } +- +- close(fd); +- return EXIT_SUCCESS; +-} +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/Documentation/hwmon/lis3lv02d linux-2.6.29-rc3.owrt/Documentation/hwmon/lis3lv02d +--- linux-2.6.29.owrt/Documentation/hwmon/lis3lv02d 2009-05-10 22:04:39.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/Documentation/hwmon/lis3lv02d 2009-05-10 23:48:28.000000000 +0200 +@@ -33,14 +33,6 @@ + This driver also provides an absolute input class device, allowing + the laptop to act as a pinball machine-esque joystick. + +-Another feature of the driver is misc device called "freefall" that +-acts similar to /dev/rtc and reacts on free-fall interrupts received +-from the device. It supports blocking operations, poll/select and +-fasync operation modes. You must read 1 bytes from the device. The +-result is number of free-fall interrupts since the last successful +-read (or 255 if number of interrupts would not fit). +- +- + Axes orientation + ---------------- + +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/Documentation/hwmon/lm90 linux-2.6.29-rc3.owrt/Documentation/hwmon/lm90 +--- linux-2.6.29.owrt/Documentation/hwmon/lm90 2009-05-10 22:04:39.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/Documentation/hwmon/lm90 2009-05-10 23:48:28.000000000 +0200 +@@ -42,11 +42,6 @@ + Addresses scanned: I2C 0x4e + Datasheet: Publicly available at the Maxim website + http://www.maxim-ic.com/quick_view2.cfm/qv_pk/3497 +- * Maxim MAX6648 +- Prefix: 'max6646' +- Addresses scanned: I2C 0x4c +- Datasheet: Publicly available at the Maxim website +- http://www.maxim-ic.com/quick_view2.cfm/qv_pk/3500 + * Maxim MAX6649 + Prefix: 'max6646' + Addresses scanned: I2C 0x4c +@@ -79,11 +74,6 @@ + 0x4c, 0x4d and 0x4e + Datasheet: Publicly available at the Maxim website + http://www.maxim-ic.com/quick_view2.cfm/qv_pk/3370 +- * Maxim MAX6692 +- Prefix: 'max6646' +- Addresses scanned: I2C 0x4c +- Datasheet: Publicly available at the Maxim website +- http://www.maxim-ic.com/quick_view2.cfm/qv_pk/3500 + + + Author: Jean Delvare <khali@linux-fr.org> +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/Documentation/IO-mapping.txt linux-2.6.29-rc3.owrt/Documentation/IO-mapping.txt +--- linux-2.6.29.owrt/Documentation/IO-mapping.txt 2009-05-10 22:04:39.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/Documentation/IO-mapping.txt 2009-05-10 23:48:28.000000000 +0200 +@@ -1,6 +1,6 @@ + [ NOTE: The virt_to_bus() and bus_to_virt() functions have been +- superseded by the functionality provided by the PCI DMA interface +- (see Documentation/PCI/PCI-DMA-mapping.txt). They continue ++ superseded by the functionality provided by the PCI DMA ++ interface (see Documentation/DMA-mapping.txt). They continue + to be documented below for historical purposes, but new code + must not use them. --davidm 00/12/12 ] + +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/Documentation/ja_JP/stable_kernel_rules.txt linux-2.6.29-rc3.owrt/Documentation/ja_JP/stable_kernel_rules.txt +--- linux-2.6.29.owrt/Documentation/ja_JP/stable_kernel_rules.txt 2009-05-10 22:04:39.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/Documentation/ja_JP/stable_kernel_rules.txt 2009-05-10 23:48:28.000000000 +0200 +@@ -12,11 +12,11 @@ + + ================================== + ã“ã‚Œã¯ã€ +-linux-2.6.29/Documentation/stable_kernel_rules.txt ++linux-2.6.24/Documentation/stable_kernel_rules.txt + ã®å’Œè¨³ã§ã™ã€‚ + + 翻訳団体: JF プãƒã‚¸ã‚§ã‚¯ãƒˆ < http://www.linux.or.jp/JF/ > +-翻訳日: 2009/1/14 ++翻訳日: 2007/12/30 + 翻訳者: Tsugikazu Shibata <tshibata at ab dot jp dot nec dot com> + æ ¡æ£è€…: æ¦äº•ä¼¸å…‰ã•ã‚“ã€<takei at webmasters dot gr dot jp> + ã‹ãã“ã•ã‚“ (Seiji Kaneko) <skaneko at a2 dot mbn dot or dot jp> +@@ -38,15 +38,12 @@ + - ビルドエラー(CONFIG_BROKENã«ãªã£ã¦ã„ã‚‹ã‚‚ã®ã‚’除ã), oops, ãƒãƒ³ã‚°ã€ãƒ‡ãƒ¼ + ã‚¿ç ´å£Šã€ç¾å®Ÿã®ã‚»ã‚ュリティå•é¡Œã€ãã®ä»– "ã‚ã‚ã€ã“ã‚Œã¯ãƒ€ãƒ¡ã ã"ã¨ã„ㆠ+ よã†ãªã‚‚ã®ã‚’ä¿®æ£ã—ãªã‘ã‚Œã°ãªã‚‰ãªã„。çŸã言ãˆã°ã€é‡å¤§ãªå•é¡Œã€‚ +- - æ–°ã—ã„ device ID ã¨ã‚¯ã‚ªãƒ¼ã‚¯ã‚‚å—ã‘入れられる。 + - ã©ã®ã‚ˆã†ã«ç«¶åˆçŠ¶æ…‹ãŒç™ºç”Ÿã™ã‚‹ã‹ã®èª¬æ˜Žã‚‚一緒ã«æ›¸ã‹ã‚Œã¦ã„ãªã„é™ã‚Šã€ + "ç†è«–çš„ã«ã¯ç«¶åˆçŠ¶æ…‹ã«ãªã‚‹"よã†ãªã‚‚ã®ã¯ä¸å¯ã€‚ + - ã„ã‹ãªã‚‹äº›ç´°ãªä¿®æ£ã‚‚å«ã‚ã‚‹ã“ã¨ã¯ã§ããªã„。(スペルã®ä¿®æ£ã€ç©ºç™½ã®ã‚¯ãƒªãƒ¼ + ンアップãªã©) ++ - 対応ã™ã‚‹ã‚µãƒ–システムメンテナãŒå—ã‘入れãŸã‚‚ã®ã§ãªã‘ã‚Œã°ãªã‚‰ãªã„。 + - Documentation/SubmittingPatches ã®è¦å‰‡ã«å¾“ã£ãŸã‚‚ã®ã§ãªã‘ã‚Œã°ãªã‚‰ãªã„。 +- - パッãƒè‡ªä½“ã‹åŒç‰ã®ä¿®æ£ãŒ Linus ã®ãƒ„リーã«æ—¢ã«å˜åœ¨ã—ãªã‘ã‚Œã°ãªã‚‰ãªã„。 +-  Linus ã®ãƒ„リーã§ã®ã‚³ãƒŸãƒƒãƒˆID ã‚’ -stable ã¸ã®ãƒ‘ッãƒæŠ•ç¨¿ã®éš›ã«å¼•ç”¨ã™ +- ã‚‹ã“ã¨ã€‚ + + -stable ツリーã«ãƒ‘ッãƒã‚’é€ä»˜ã™ã‚‹æ‰‹ç¶šã- + +@@ -55,10 +52,8 @@ + - é€ä¿¡è€…ã¯ãƒ‘ッãƒãŒã‚ューã«å—ã‘付ã‘られãŸéš›ã«ã¯ ACK ã‚’ã€å´ä¸‹ã•ã‚ŒãŸå ´åˆ + ã«ã¯ NAK ã‚’å—ã‘å–る。ã“ã®åå¿œã¯é–‹ç™ºè€…ãŸã¡ã®ã‚¹ã‚±ã‚¸ãƒ¥ãƒ¼ãƒ«ã«ã‚ˆã£ã¦ã€æ•° + æ—¥ã‹ã‹ã‚‹å ´åˆãŒã‚る。 +- - ã‚‚ã—å—ã‘å–られãŸã‚‰ã€ãƒ‘ッãƒã¯ä»–ã®é–‹ç™ºè€…ãŸã¡ã¨é–¢é€£ã™ã‚‹ã‚µãƒ–システム㮠+- メンテナーã«ã‚ˆã‚‹ãƒ¬ãƒ“ューã®ãŸã‚ã« -stable ã‚ューã«è¿½åŠ ã•ã‚Œã‚‹ã€‚ +- - パッãƒã« stable@kernel.org ã®ã‚¢ãƒ‰ãƒ¬ã‚¹ãŒä»˜åŠ ã•ã‚Œã¦ã„ã‚‹ã¨ãã«ã¯ã€ãã‚Œ +- ㌠Linus ã®ãƒ„リーã«å…¥ã‚‹æ™‚ã«è‡ªå‹•çš„ã« stable ãƒãƒ¼ãƒ ã« email ã•ã‚Œã‚‹ã€‚ ++ - ã‚‚ã—å—ã‘å–られãŸã‚‰ã€ãƒ‘ッãƒã¯ä»–ã®é–‹ç™ºè€…ãŸã¡ã®ãƒ¬ãƒ“ューã®ãŸã‚ã« ++ -stable ã‚ューã«è¿½åŠ ã•ã‚Œã‚‹ã€‚ + - ã‚»ã‚ュリティパッãƒã¯ã“ã®ã‚¨ã‚¤ãƒªã‚¢ã‚¹ (stable@kernel.org) ã«é€ã‚‰ã‚Œã‚‹ã¹ + ãã§ã¯ãªãã€ä»£ã‚ã‚Šã« security@kernel.org ã®ã‚¢ãƒ‰ãƒ¬ã‚¹ã«é€ã‚‰ã‚Œã‚‹ã€‚ + +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/Documentation/kernel-doc-nano-HOWTO.txt linux-2.6.29-rc3.owrt/Documentation/kernel-doc-nano-HOWTO.txt +--- linux-2.6.29.owrt/Documentation/kernel-doc-nano-HOWTO.txt 2009-05-10 22:04:39.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/Documentation/kernel-doc-nano-HOWTO.txt 2009-05-10 23:48:28.000000000 +0200 +@@ -43,8 +43,7 @@ + and any comment so marked must be in kernel-doc format. Do not use + "/**" to be begin a comment block unless the comment block contains + kernel-doc formatted comments. The closing comment marker for +-kernel-doc comments can be either "*/" or "**/", but "*/" is +-preferred in the Linux kernel tree. ++kernel-doc comments can be either "*/" or "**/". + + Kernel-doc comments should be placed just before the function + or data structure being described. +@@ -64,7 +63,7 @@ + * comment lines. + * + * The longer description can have multiple paragraphs. +- */ ++ **/ + + The first line, with the short description, must be on a single line. + +@@ -86,7 +85,7 @@ + * perhaps with more lines and words. + * + * Longer description of this structure. +- */ ++ **/ + + The kernel-doc function comments describe each parameter to the + function, in order, with the @name lines. +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/Documentation/kernel-parameters.txt linux-2.6.29-rc3.owrt/Documentation/kernel-parameters.txt +--- linux-2.6.29.owrt/Documentation/kernel-parameters.txt 2009-05-10 22:04:39.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/Documentation/kernel-parameters.txt 2009-05-10 23:48:28.000000000 +0200 +@@ -114,7 +114,7 @@ + Parameters denoted with BOOT are actually interpreted by the boot + loader, and have no meaning to the kernel directly. + Do not modify the syntax of boot loader parameters without extreme +-need or coordination with <Documentation/x86/boot.txt>. ++need or coordination with <Documentation/x86/i386/boot.txt>. + + There are also arch-specific kernel-parameters not documented here. + See for example <Documentation/x86/x86_64/boot-options.txt>. +@@ -134,7 +134,7 @@ + + acpi= [HW,ACPI,X86-64,i386] + Advanced Configuration and Power Interface +- Format: { force | off | ht | strict | noirq | rsdt } ++ Format: { force | off | ht | strict | noirq } + force -- enable ACPI if default was off + off -- disable ACPI if default was on + noirq -- do not use ACPI for IRQ routing +@@ -868,10 +868,8 @@ + icn= [HW,ISDN] + Format: <io>[,<membase>[,<icn_id>[,<icn_id2>]]] + +- ide-core.nodma= [HW] (E)IDE subsystem +- Format: =0.0 to prevent dma on hda, =0.1 hdb =1.0 hdc +- .vlb_clock .pci_clock .noflush .noprobe .nowerr .cdrom +- .chs .ignore_cable are additional options ++ ide= [HW] (E)IDE subsystem ++ Format: ide=nodma or ide=doubler + See Documentation/ide/ide.txt. + + idebus= [HW] (E)IDE subsystem - VLB/PCI bus speed +@@ -939,8 +937,6 @@ + + + intel_iommu= [DMAR] Intel IOMMU driver (DMAR) option +- on +- Enable intel iommu driver. + off + Disable intel iommu driver. + igfx_off [Default Off] +@@ -2451,7 +2447,7 @@ + See Documentation/fb/modedb.txt. + + vga= [BOOT,X86-32] Select a particular video mode +- See Documentation/x86/boot.txt and ++ See Documentation/x86/i386/boot.txt and + Documentation/svga.txt. + Use vga=ask for menu. + This is actually a boot loader parameter; the value is +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/Documentation/lguest/Makefile linux-2.6.29-rc3.owrt/Documentation/lguest/Makefile +--- linux-2.6.29.owrt/Documentation/lguest/Makefile 2009-05-10 22:04:39.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/Documentation/lguest/Makefile 2009-05-10 23:48:28.000000000 +0200 +@@ -1,5 +1,5 @@ + # This creates the demonstration utility "lguest" which runs a Linux guest. +-CFLAGS:=-Wall -Wmissing-declarations -Wmissing-prototypes -O3 -I../../include -I../../arch/x86/include -U_FORTIFY_SOURCE ++CFLAGS:=-Wall -Wmissing-declarations -Wmissing-prototypes -O3 -I../../include -I../../arch/x86/include + LDLIBS:=-lz + + all: lguest +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/Documentation/logo.svg linux-2.6.29-rc3.owrt/Documentation/logo.svg +--- linux-2.6.29.owrt/Documentation/logo.svg 2009-05-10 22:04:39.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/Documentation/logo.svg 1970-01-01 01:00:00.000000000 +0100 +@@ -1,2911 +0,0 @@ +-<?xml version="1.0" encoding="UTF-8" standalone="no"?> +-<!-- Created with Inkscape (http://www.inkscape.org/) --> +-<svg +- xmlns:dc="http://purl.org/dc/elements/1.1/" +- xmlns:cc="http://creativecommons.org/ns#" +- xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" +- xmlns:svg="http://www.w3.org/2000/svg" +- xmlns="http://www.w3.org/2000/svg" +- xmlns:xlink="http://www.w3.org/1999/xlink" +- xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd" +- xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape" +- width="1771.6534" +- height="1417.3228" +- id="svg2" +- sodipodi:version="0.32" +- inkscape:version="0.46" +- sodipodi:docname="tuz.svg" +- inkscape:output_extension="org.inkscape.output.svg.inkscape" +- version="1.0" +- style="display:inline;enable-background:new" +- inkscape:export-filename="/home/cheeseness/Documents/LCA09/mascot/tuz_final.png" +- inkscape:export-xdpi="100.03588" +- inkscape:export-ydpi="100.03588"> +- <sodipodi:namedview +- id="base" +- pagecolor="#ffffff" +- bordercolor="#666666" +- borderopacity="1.0" +- gridtolerance="10000" +- guidetolerance="10" +- objecttolerance="10" +- inkscape:pageopacity="0.0" +- inkscape:pageshadow="2" +- inkscape:zoom="0.25" +- inkscape:cx="-174.7931" +- inkscape:cy="784.26325" +- inkscape:document-units="px" +- inkscape:current-layer="svg2" +- showgrid="false" +- inkscape:window-width="1280" +- inkscape:window-height="823" +- inkscape:window-x="-4" +- inkscape:window-y="25" +- showguides="true" +- inkscape:guide-bbox="true" +- units="mm" /> +- <defs +- id="defs4"> +- <filter +- inkscape:collect="always" +- x="-0.084654994" +- width="1.16931" +- y="-0.36592469" +- height="1.7318494" +- id="filter11361"> +- <feGaussianBlur +- inkscape:collect="always" +- stdDeviation="4.5740586" +- id="feGaussianBlur11363" /> +- </filter> +- <inkscape:perspective +- sodipodi:type="inkscape:persp3d" +- inkscape:vp_x="0 : 564.0976 : 1" +- inkscape:vp_y="0 : 1000 : 0" +- inkscape:vp_z="1445.8591 : 564.0976 : 1" +- inkscape:persp3d-origin="722.92957 : 376.06506 : 1" +- id="perspective8145" /> +- <linearGradient +- id="linearGradient7622"> +- <stop +- style="stop-color:#ffffff;stop-opacity:1;" +- offset="0" +- id="stop7624" /> +- <stop +- style="stop-color:#ffffff;stop-opacity:0;" +- offset="1" +- id="stop7626" /> +- </linearGradient> +- <linearGradient +- id="linearGradient4113"> +- <stop +- style="stop-color:#000000;stop-opacity:0;" +- offset="0" +- id="stop4115" /> +- <stop +- style="stop-color:#000000;stop-opacity:1;" +- offset="1" +- id="stop4117" /> +- </linearGradient> +- <linearGradient +- inkscape:collect="always" +- id="linearGradient3660"> +- <stop +- style="stop-color:#ffffff;stop-opacity:1;" +- offset="0" +- id="stop3662" /> +- <stop +- style="stop-color:#ffffff;stop-opacity:0;" +- offset="1" +- id="stop3664" /> +- </linearGradient> +- <linearGradient +- id="linearGradient3627"> +- <stop +- style="stop-color:#ffffff;stop-opacity:1;" +- offset="0" +- id="stop3629" /> +- <stop +- style="stop-color:#000000;stop-opacity:1;" +- offset="1" +- id="stop3631" /> +- </linearGradient> +- <linearGradient +- id="linearGradient2843"> +- <stop +- id="stop2845" +- offset="0" +- style="stop-color:#000000;stop-opacity:1;" /> +- <stop +- style="stop-color:#000000;stop-opacity:1;" +- offset="0.02188784" +- id="stop2847" /> +- <stop +- style="stop-color:#000000;stop-opacity:1;" +- offset="0.75866222" +- id="stop2849" /> +- <stop +- id="stop2851" +- offset="0.88508981" +- style="stop-color:#232323;stop-opacity:1;" /> +- <stop +- id="stop2853" +- offset="1" +- style="stop-color:#595959;stop-opacity:1;" /> +- </linearGradient> +- <linearGradient +- inkscape:collect="always" +- id="linearGradient8964"> +- <stop +- style="stop-color:#1a1a1a;stop-opacity:1;" +- offset="0" +- id="stop8966" /> +- <stop +- style="stop-color:#1a1a1a;stop-opacity:0;" +- offset="1" +- id="stop8968" /> +- </linearGradient> +- <linearGradient +- id="linearGradient8952"> +- <stop +- style="stop-color:#0a0c0c;stop-opacity:1;" +- offset="0" +- id="stop8954" /> +- <stop +- style="stop-color:#1f2727;stop-opacity:0;" +- offset="1" +- id="stop8956" /> +- </linearGradient> +- <linearGradient +- id="linearGradient8430"> +- <stop +- style="stop-color:#1e2323;stop-opacity:1;" +- offset="0" +- id="stop8432" /> +- <stop +- id="stop8438" +- offset="0.55992389" +- style="stop-color:#181d1d;stop-opacity:1;" /> +- <stop +- style="stop-color:#000000;stop-opacity:1;" +- offset="1" +- id="stop8434" /> +- </linearGradient> +- <linearGradient +- id="linearGradient8398"> +- <stop +- style="stop-color:#283131;stop-opacity:0;" +- offset="0" +- id="stop8400" /> +- <stop +- id="stop8402" +- offset="0.5125587" +- style="stop-color:#1e2424;stop-opacity:0;" /> +- <stop +- style="stop-color:#000000;stop-opacity:1;" +- offset="1" +- id="stop8404" /> +- </linearGradient> +- <linearGradient +- inkscape:collect="always" +- id="linearGradient4870"> +- <stop +- style="stop-color:#c7bd80;stop-opacity:1;" +- offset="0" +- id="stop4872" /> +- <stop +- style="stop-color:#c7bd80;stop-opacity:0;" +- offset="1" +- id="stop4874" /> +- </linearGradient> +- <linearGradient +- inkscape:collect="always" +- id="linearGradient4862"> +- <stop +- style="stop-color:#e2e2e2;stop-opacity:1;" +- offset="0" +- id="stop4864" /> +- <stop +- style="stop-color:#e2e2e2;stop-opacity:0;" +- offset="1" +- id="stop4866" /> +- </linearGradient> +- <linearGradient +- id="linearGradient4478"> +- <stop +- style="stop-color:#f9eed3;stop-opacity:1;" +- offset="0" +- id="stop4480" /> +- <stop +- style="stop-color:#000000;stop-opacity:0;" +- offset="1" +- id="stop4482" /> +- </linearGradient> +- <linearGradient +- id="linearGradient4106"> +- <stop +- style="stop-color:#d9e002;stop-opacity:1;" +- offset="0" +- id="stop4108" /> +- <stop +- id="stop4114" +- offset="0.5" +- style="stop-color:#a9ae01;stop-opacity:1;" /> +- <stop +- style="stop-color:#717501;stop-opacity:1;" +- offset="1" +- id="stop4110" /> +- </linearGradient> +- <linearGradient +- id="linearGradient4084"> +- <stop +- style="stop-color:#7d7d00;stop-opacity:1;" +- offset="0" +- id="stop4086" /> +- <stop +- id="stop4088" +- offset="0.3636601" +- style="stop-color:#c6c700;stop-opacity:1;" /> +- <stop +- style="stop-color:#f6f800;stop-opacity:1;" +- offset="1" +- id="stop4090" /> +- </linearGradient> +- <linearGradient +- id="linearGradient4041"> +- <stop +- id="stop4043" +- offset="0" +- style="stop-color:#ffff00;stop-opacity:1;" /> +- <stop +- id="stop4045" +- offset="1" +- style="stop-color:#ffff00;stop-opacity:0;" /> +- </linearGradient> +- <linearGradient +- id="linearGradient4025"> +- <stop +- style="stop-color:#ffffff;stop-opacity:1;" +- offset="0" +- id="stop4027" /> +- <stop +- style="stop-color:#ffffff;stop-opacity:0;" +- offset="1" +- id="stop4031" /> +- </linearGradient> +- <linearGradient +- id="linearGradient4013"> +- <stop +- style="stop-color:#ffff00;stop-opacity:1;" +- offset="0" +- id="stop4015" /> +- <stop +- style="stop-color:#b2b200;stop-opacity:1;" +- offset="1" +- id="stop4017" /> +- </linearGradient> +- <linearGradient +- id="linearGradient3985"> +- <stop +- style="stop-color:#000000;stop-opacity:1;" +- offset="0" +- id="stop3987" /> +- <stop +- style="stop-color:#1d1d1d;stop-opacity:1;" +- offset="1" +- id="stop3989" /> +- </linearGradient> +- <linearGradient +- id="linearGradient3961"> +- <stop +- style="stop-color:#283131;stop-opacity:0;" +- offset="0" +- id="stop3963" /> +- <stop +- id="stop3965" +- offset="0.5" +- style="stop-color:#1e2424;stop-opacity:1;" /> +- <stop +- style="stop-color:#000000;stop-opacity:1;" +- offset="1" +- id="stop3967" /> +- </linearGradient> +- <linearGradient +- id="linearGradient3951"> +- <stop +- id="stop3953" +- offset="0" +- style="stop-color:#344040;stop-opacity:1;" /> +- <stop +- style="stop-color:#222929;stop-opacity:1;" +- offset="0.5" +- id="stop3955" /> +- <stop +- id="stop3957" +- offset="1" +- style="stop-color:#000000;stop-opacity:1;" /> +- </linearGradient> +- <linearGradient +- id="linearGradient3909"> +- <stop +- style="stop-color:#283131;stop-opacity:1;" +- offset="0" +- id="stop3911" /> +- <stop +- id="stop3917" +- offset="0.5" +- style="stop-color:#1e2424;stop-opacity:1;" /> +- <stop +- style="stop-color:#000000;stop-opacity:1;" +- offset="1" +- id="stop3913" /> +- </linearGradient> +- <linearGradient +- id="linearGradient3537"> +- <stop +- style="stop-color:#ada469;stop-opacity:1;" +- offset="0" +- id="stop3539" /> +- <stop +- id="stop3545" +- offset="0.81132078" +- style="stop-color:#ada469;stop-opacity:1;" /> +- <stop +- style="stop-color:#ffffff;stop-opacity:1;" +- offset="1" +- id="stop3541" /> +- </linearGradient> +- <linearGradient +- id="linearGradient3317"> +- <stop +- style="stop-color:#cfc690;stop-opacity:1" +- offset="0" +- id="stop3319" /> +- <stop +- id="stop3321" +- offset="0.21161865" +- style="stop-color:#afa775;stop-opacity:1;" /> +- <stop +- id="stop3323" +- offset="0.53408515" +- style="stop-color:#615c3a;stop-opacity:1;" /> +- <stop +- style="stop-color:#000000;stop-opacity:1;" +- offset="0.76504093" +- id="stop3325" /> +- <stop +- id="stop3327" +- offset="1" +- style="stop-color:#403518;stop-opacity:1;" /> +- </linearGradient> +- <linearGradient +- id="linearGradient3239"> +- <stop +- id="stop3251" +- offset="0" +- style="stop-color:#cfc690;stop-opacity:1;" /> +- <stop +- style="stop-color:#afa775;stop-opacity:1;" +- offset="0.21161865" +- id="stop3267" /> +- <stop +- style="stop-color:#615c3a;stop-opacity:1;" +- offset="0.53408515" +- id="stop3261" /> +- <stop +- id="stop3265" +- offset="0.76504093" +- style="stop-color:#000000;stop-opacity:1;" /> +- <stop +- style="stop-color:#403518;stop-opacity:1;" +- offset="1" +- id="stop3243" /> +- </linearGradient> +- <radialGradient +- inkscape:collect="always" +- xlink:href="#linearGradient3239" +- id="radialGradient3281" +- gradientUnits="userSpaceOnUse" +- gradientTransform="matrix(1.5480423,1.7414304,-1.9683515,1.7497638,-1130.5586,-1872.5121)" +- spreadMethod="pad" +- cx="806.52582" +- cy="212.68117" +- fx="806.52582" +- fy="212.68117" +- r="48.363216" /> +- <radialGradient +- inkscape:collect="always" +- xlink:href="#linearGradient3317" +- id="radialGradient3315" +- cx="543.6698" +- cy="147.3131" +- fx="543.6698" +- fy="147.3131" +- r="47.863216" +- gradientTransform="matrix(2.1382256,0,0,2.3382884,-77.03847,-101.68704)" +- gradientUnits="userSpaceOnUse" /> +- <radialGradient +- inkscape:collect="always" +- xlink:href="#linearGradient3537" +- id="radialGradient3543" +- cx="385" +- cy="237.00504" +- fx="385" +- fy="237.00504" +- r="86.928574" +- gradientTransform="matrix(1,0,0,0.8562038,0,34.080427)" +- gradientUnits="userSpaceOnUse" /> +- <radialGradient +- inkscape:collect="always" +- xlink:href="#linearGradient3909" +- id="radialGradient3915" +- cx="418.30365" +- cy="342.47794" +- fx="418.30365" +- fy="342.47794" +- r="131.4509" +- gradientTransform="matrix(1.3957347,0.6211056,-0.4244067,0.9537174,-15.061913,-227.96711)" +- gradientUnits="userSpaceOnUse" /> +- <radialGradient +- inkscape:collect="always" +- xlink:href="#linearGradient3951" +- id="radialGradient3933" +- cx="397.16388" +- cy="336.95245" +- fx="397.16388" +- fy="336.95245" +- r="36.75" +- gradientUnits="userSpaceOnUse" +- gradientTransform="matrix(1.9449972,2.4894837e-7,-2.4894833e-7,1.9449969,-375.31868,-318.41912)" /> +- <linearGradient +- inkscape:collect="always" +- xlink:href="#linearGradient3961" +- id="linearGradient3959" +- x1="398.21429" +- y1="343.52289" +- x2="379.28571" +- y2="265.30862" +- gradientUnits="userSpaceOnUse" +- gradientTransform="translate(450.03125,73.843964)" /> +- <filter +- inkscape:collect="always" +- id="filter3981" +- x="-0.30000001" +- width="1.6" +- y="-0.30000001" +- height="1.6"> +- <feGaussianBlur +- inkscape:collect="always" +- stdDeviation="2" +- id="feGaussianBlur3983" /> +- </filter> +- <radialGradient +- inkscape:collect="always" +- xlink:href="#linearGradient3985" +- id="radialGradient3991" +- cx="402.48898" +- cy="317.23578" +- fx="402.48898" +- fy="317.23578" +- r="23.714285" +- gradientUnits="userSpaceOnUse" +- gradientTransform="matrix(4.3776616,0,0,4.3776616,-1358.3025,-1070.7357)" /> +- <clipPath +- clipPathUnits="userSpaceOnUse" +- id="clipPath3999"> +- <path +- style="opacity:1;fill:#f5ff04;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:20.79999924;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1;display:inline" +- d="M 179.64286,267.36218 C 157.23242,307.0651 119.02676,383.14247 110.35715,417.00504 C 101.70994,450.78014 101.58516,483.42158 110,503.43362 C 118.3602,523.31575 136.16398,539.06642 150.71428,544.86218 C 150.1179,530.48631 165.08723,501.57635 223.57143,472.36218 C 282.1977,443.07704 301.95306,445.23132 327.14285,425.21932 C 352.77291,404.85756 339.75316,358.17469 330.35714,331.29075 C 320.9229,304.29747 295.38973,272.16627 263.92857,261.6479 C 232.8953,251.27258 198.91081,256.79953 179.64286,267.36218 z" +- id="path4001" +- sodipodi:nodetypes="czzczzzzc" /> +- </clipPath> +- <radialGradient +- inkscape:collect="always" +- xlink:href="#linearGradient4013" +- id="radialGradient4056" +- gradientUnits="userSpaceOnUse" +- gradientTransform="matrix(1.1323239,0.7659488,-1.4550286,2.1510098,588.75376,-711.79716)" +- cx="228.81355" +- cy="440.26971" +- fx="228.81355" +- fy="440.26971" +- r="119.17509" /> +- <radialGradient +- inkscape:collect="always" +- xlink:href="#linearGradient4041" +- id="radialGradient4060" +- gradientUnits="userSpaceOnUse" +- gradientTransform="matrix(5.911206e-2,2.6869855,-0.7234268,1.5914947e-2,408.72779,-424.56452)" +- cx="275.4422" +- cy="335.34866" +- fx="275.4422" +- fy="335.34866" +- r="36.75" /> +- <radialGradient +- inkscape:collect="always" +- xlink:href="#linearGradient4025" +- id="radialGradient4062" +- gradientUnits="userSpaceOnUse" +- gradientTransform="matrix(5.911206e-2,2.6869855,-0.7234268,1.5914947e-2,408.72779,-424.56452)" +- cx="275.4422" +- cy="335.34866" +- fx="275.4422" +- fy="335.34866" +- r="36.75" /> +- <linearGradient +- inkscape:collect="always" +- xlink:href="#linearGradient4084" +- id="linearGradient4082" +- gradientUnits="userSpaceOnUse" +- x1="182.35046" +- y1="256.11136" +- x2="145.53348" +- y2="542.20502" /> +- <clipPath +- clipPathUnits="userSpaceOnUse" +- id="clipPath4100"> +- <path +- style="fill:#000000;fill-opacity:1;fill-rule:evenodd;stroke:#000000;stroke-width:0.9000755px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1" +- d="M 265.93541,126.68393 L 247.1682,295.54701 L 421.27363,222.42633 L 483.22803,311.08516 L 541.11243,279.09486 L 503.57801,99.035183 L 265.93541,126.68393 z" +- id="path4102" +- sodipodi:nodetypes="ccccccc" /> +- </clipPath> +- <radialGradient +- inkscape:collect="always" +- xlink:href="#linearGradient4106" +- id="radialGradient4112" +- cx="250.22678" +- cy="475.09763" +- fx="250.22678" +- fy="475.09763" +- r="95.98877" +- gradientTransform="matrix(1.2259004,-0.7077739,0.1413989,0.2449102,322.22326,608.91815)" +- gradientUnits="userSpaceOnUse" /> +- <linearGradient +- inkscape:collect="always" +- xlink:href="#linearGradient4478" +- id="linearGradient4484" +- x1="412.08926" +- y1="404.91574" +- x2="417.375" +- y2="401.82648" +- gradientUnits="userSpaceOnUse" /> +- <linearGradient +- inkscape:collect="always" +- xlink:href="#linearGradient4478" +- id="linearGradient4486" +- x1="411.91071" +- y1="404.91577" +- x2="417.375" +- y2="401.82648" +- gradientUnits="userSpaceOnUse" /> +- <linearGradient +- inkscape:collect="always" +- xlink:href="#linearGradient4478" +- id="linearGradient4488" +- x1="411.91071" +- y1="405.54077" +- x2="417.375" +- y2="401.82648" +- gradientUnits="userSpaceOnUse" /> +- <linearGradient +- inkscape:collect="always" +- xlink:href="#linearGradient4478" +- id="linearGradient4490" +- x1="412.08926" +- y1="405.54077" +- x2="417.375" +- y2="401.82648" +- gradientUnits="userSpaceOnUse" /> +- <linearGradient +- inkscape:collect="always" +- xlink:href="#linearGradient4478" +- id="linearGradient4492" +- x1="411.73212" +- y1="405.54077" +- x2="417.375" +- y2="401.82648" +- gradientUnits="userSpaceOnUse" /> +- <radialGradient +- inkscape:collect="always" +- xlink:href="#linearGradient4862" +- id="radialGradient4868" +- cx="429.56738" +- cy="377.42877" +- fx="429.56738" +- fy="377.42877" +- r="72.079735" +- gradientTransform="matrix(1,0,0,0.618034,0,144.16496)" +- gradientUnits="userSpaceOnUse" /> +- <radialGradient +- inkscape:collect="always" +- xlink:href="#linearGradient4870" +- id="radialGradient4876" +- cx="437.6991" +- cy="391.21735" +- fx="437.6991" +- fy="391.21735" +- r="36.611931" +- gradientTransform="matrix(1,0,0,0.618034,0,149.43174)" +- gradientUnits="userSpaceOnUse" /> +- <radialGradient +- inkscape:collect="always" +- xlink:href="#linearGradient4013" +- id="radialGradient3585" +- gradientUnits="userSpaceOnUse" +- gradientTransform="matrix(1.1323239,0.7659488,-1.4550286,2.1510098,588.75376,-711.79716)" +- cx="228.81355" +- cy="440.26971" +- fx="228.81355" +- fy="440.26971" +- r="119.17509" /> +- <linearGradient +- inkscape:collect="always" +- xlink:href="#linearGradient4084" +- id="linearGradient3587" +- gradientUnits="userSpaceOnUse" +- x1="182.35046" +- y1="256.11136" +- x2="145.53348" +- y2="542.20502" /> +- <radialGradient +- inkscape:collect="always" +- xlink:href="#linearGradient3317" +- id="radialGradient8410" +- gradientUnits="userSpaceOnUse" +- gradientTransform="matrix(1.0036478,-1.0345492e-7,1.7124628e-7,1.6613125,-753.99632,-302.76972)" +- cx="317.78754" +- cy="129.65378" +- fx="317.78754" +- fy="129.65378" +- r="47.863216" /> +- <radialGradient +- inkscape:collect="always" +- xlink:href="#linearGradient8398" +- id="radialGradient8412" +- gradientUnits="userSpaceOnUse" +- gradientTransform="matrix(2.0747661,-0.1577957,0.2382425,3.1325183,-1144.2358,-272.29325)" +- cx="325.30847" +- cy="80.909554" +- fx="325.30847" +- fy="80.909554" +- r="26.937988" /> +- <clipPath +- clipPathUnits="userSpaceOnUse" +- id="clipPath8514"> +- <path +- style="opacity:1;fill:#262f2f;fill-opacity:1;fill-rule:evenodd;stroke:#000000;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;marker:none;marker-start:none;marker-mid:none;marker-end:none;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" +- d="M 352.24553,211.99185 C 348.4411,186.72762 335.43581,161.35383 335.08873,136.46662 C 334.90247,123.1111 338.36158,109.89571 348.84426,96.912574 C 385.19128,31.616739 465.78517,12.217889 534.77892,5.447147 C 621.70131,-5.569654 719.69159,23.387219 768.15026,100.84843 C 822.27428,176.58173 824.82502,273.38755 848.7623,360.37638 C 878.20009,487.50398 903.54144,616.59052 909.15454,747.22673 C 906.09106,825.40858 900.7282,912.41088 848.65133,975.36086 C 800.62479,1025.7183 725.86486,1025.4139 661.58145,1034.3632 C 571.02606,1039.0182 477.22992,1018.2174 399.79755,970.16496 C 335.02191,932.22495 304.06736,856.68633 302.51815,784.14538 C 294.12898,704.27022 328.90967,630.33687 354.13855,556.98577 C 361.60916,474.2247 363.55141,390.73802 363.79189,307.60093 C 362.95507,275.40549 356.70236,243.7836 352.24553,211.99185 z" +- id="path8516" +- sodipodi:nodetypes="cscccccccccccc" /> +- </clipPath> +- <clipPath +- clipPathUnits="userSpaceOnUse" +- id="clipPath8604"> +- <path +- style="opacity:1;fill:#262f2f;fill-opacity:1;fill-rule:evenodd;stroke:#000000;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;marker:none;marker-start:none;marker-mid:none;marker-end:none;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" +- d="M 352.24553,211.99185 C 348.4411,186.72762 335.43581,161.35383 335.08873,136.46662 C 334.90247,123.1111 338.36158,109.89571 348.84426,96.912574 C 385.19128,31.616739 465.78517,12.217889 534.77892,5.447147 C 621.70131,-5.569654 719.69159,23.387219 768.15026,100.84843 C 822.27428,176.58173 824.82502,273.38755 848.7623,360.37638 C 878.20009,487.50398 903.54144,616.59052 909.15454,747.22673 C 906.09106,825.40858 900.7282,912.41088 848.65133,975.36086 C 800.62479,1025.7183 725.86486,1025.4139 661.58145,1034.3632 C 571.02606,1039.0182 477.22992,1018.2174 399.79755,970.16496 C 335.02191,932.22495 304.06736,856.68633 302.51815,784.14538 C 294.12898,704.27022 328.90967,630.33687 354.13855,556.98577 C 361.60916,474.2247 363.55141,390.73802 363.79189,307.60093 C 362.95507,275.40549 356.70236,243.7836 352.24553,211.99185 z" +- id="path8606" +- sodipodi:nodetypes="cscccccccccccc" /> +- </clipPath> +- <clipPath +- clipPathUnits="userSpaceOnUse" +- id="clipPath8610"> +- <path +- style="opacity:1;fill:#262f2f;fill-opacity:1;fill-rule:evenodd;stroke:#000000;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;marker:none;marker-start:none;marker-mid:none;marker-end:none;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" +- d="M 352.24553,211.99185 C 348.4411,186.72762 335.43581,161.35383 335.08873,136.46662 C 334.90247,123.1111 338.36158,109.89571 348.84426,96.912574 C 385.19128,31.616739 465.78517,12.217889 534.77892,5.447147 C 621.70131,-5.569654 719.69159,23.387219 768.15026,100.84843 C 822.27428,176.58173 824.82502,273.38755 848.7623,360.37638 C 878.20009,487.50398 903.54144,616.59052 909.15454,747.22673 C 906.09106,825.40858 900.7282,912.41088 848.65133,975.36086 C 800.62479,1025.7183 725.86486,1025.4139 661.58145,1034.3632 C 571.02606,1039.0182 477.22992,1018.2174 399.79755,970.16496 C 335.02191,932.22495 304.06736,856.68633 302.51815,784.14538 C 294.12898,704.27022 328.90967,630.33687 354.13855,556.98577 C 361.60916,474.2247 363.55141,390.73802 363.79189,307.60093 C 362.95507,275.40549 356.70236,243.7836 352.24553,211.99185 z" +- id="path8612" +- sodipodi:nodetypes="cscccccccccccc" /> +- </clipPath> +- <clipPath +- clipPathUnits="userSpaceOnUse" +- id="clipPath8616"> +- <path +- style="opacity:1;fill:#262f2f;fill-opacity:1;fill-rule:evenodd;stroke:#000000;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;marker:none;marker-start:none;marker-mid:none;marker-end:none;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" +- d="M 352.24553,211.99185 C 348.4411,186.72762 335.43581,161.35383 335.08873,136.46662 C 334.90247,123.1111 338.36158,109.89571 348.84426,96.912574 C 385.19128,31.616739 465.78517,12.217889 534.77892,5.447147 C 621.70131,-5.569654 719.69159,23.387219 768.15026,100.84843 C 822.27428,176.58173 824.82502,273.38755 848.7623,360.37638 C 878.20009,487.50398 903.54144,616.59052 909.15454,747.22673 C 906.09106,825.40858 900.7282,912.41088 848.65133,975.36086 C 800.62479,1025.7183 725.86486,1025.4139 661.58145,1034.3632 C 571.02606,1039.0182 477.22992,1018.2174 399.79755,970.16496 C 335.02191,932.22495 304.06736,856.68633 302.51815,784.14538 C 294.12898,704.27022 328.90967,630.33687 354.13855,556.98577 C 361.60916,474.2247 363.55141,390.73802 363.79189,307.60093 C 362.95507,275.40549 356.70236,243.7836 352.24553,211.99185 z" +- id="path8618" +- sodipodi:nodetypes="cscccccccccccc" /> +- </clipPath> +- <clipPath +- clipPathUnits="userSpaceOnUse" +- id="clipPath8622"> +- <path +- style="opacity:1;fill:#202020;fill-opacity:1;fill-rule:evenodd;stroke:#000000;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;display:inline;enable-background:new" +- d="M 821.64329,477.88997 C 821.64329,477.88997 844.26276,471.38316 857.38604,472.01724 C 870.50932,472.65133 888.02762,473.95586 901.09489,484.20343 C 914.16216,494.45099 926.16263,511.3435 935.20728,542.57308 C 944.25193,573.80266 936.9056,641.82509 929.03125,685.92043 C 921.1569,730.01577 900.76615,792.03341 884.03125,825.92043 C 867.29635,859.80745 834.23354,903.41563 823.46182,915.79659 C 812.0976,928.85856 767.25593,952.22276 744.03125,958.06326 C 749.33455,947.45666 792.93101,907.47442 779.03125,897.349 C 765.01228,887.13674 733.27116,943.33136 694.7381,926.38217 C 716.12041,913.25005 736.5175,875.19611 728.77871,859.78772 C 720.93846,844.17733 698.07378,908.54529 635.24317,896.8006 C 665.29521,869.27394 690.65023,825.89659 676.50587,813.8209 C 662.09071,801.51403 616.04412,868.11405 616.04412,868.11405 C 616.04412,868.11405 613.22222,826.41287 629.81732,799.50673 C 646.45667,772.52886 709.47029,717.89146 729.37045,687.80331 C 749.2706,657.71517 762.98301,621.79429 771.50587,595.28537 C 780.02873,568.77645 787.30681,518.18583 787.30681,518.18583" +- id="path8624" +- sodipodi:nodetypes="czzzzzzczczczczzzc" /> +- </clipPath> +- <clipPath +- clipPathUnits="userSpaceOnUse" +- id="clipPath8642"> +- <path +- style="opacity:1;fill:#0f0f0f;fill-opacity:1;fill-rule:evenodd;stroke:#000000;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;marker:none;marker-start:none;marker-mid:none;marker-end:none;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" +- d="M 366.88839,504.13471 C 366.88839,504.13471 337.33433,544.70776 319.03125,578.42042 C 300.72816,612.13309 260.41016,704.77736 248.67411,749.49185 C 236.91471,794.29529 186.17411,873.06329 186.17411,873.06329 L 262.24554,891.27757 C 262.24554,891.27757 274.05266,878.45422 293.31696,845.20614 C 312.58126,811.95806 353.67411,706.63471 353.67411,706.63471 L 366.88839,504.13471 z" +- id="path8644" +- sodipodi:nodetypes="czzcczcc" /> +- </clipPath> +- <clipPath +- clipPathUnits="userSpaceOnUse" +- id="clipPath8658"> +- <path +- style="opacity:1;fill:#0b0b0b;fill-opacity:1;fill-rule:evenodd;stroke:#000000;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;marker:none;marker-start:none;marker-mid:none;marker-end:none;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" +- d="M 569.03125,1018.7776 C 564.74554,1019.4919 541.4031,1022.3957 511.17411,1028.7776 C 480.94512,1035.1595 411.39918,1054.7395 368.31696,1064.4919 C 325.23474,1074.2443 251.05253,1099.3079 211.40434,1091.7573 C 171.75616,1084.2067 121.88839,1027.349 121.88839,1027.349 L 126.17411,933.06329 C 126.17411,933.06329 212.05962,916.86235 238.31696,899.49186 C 264.57431,882.12137 283.89934,849.82588 297.60268,828.06329 C 311.30602,806.3007 330.45982,756.63471 330.45982,756.63471 L 569.03125,1018.7776 z" +- id="path8660" +- sodipodi:nodetypes="czzzcczzcc" /> +- </clipPath> +- <filter +- inkscape:collect="always" +- id="filter8802" +- x="-0.35311759" +- width="1.7062352" +- y="-0.1817714" +- height="1.3635428"> +- <feGaussianBlur +- inkscape:collect="always" +- stdDeviation="48.038491" +- id="feGaussianBlur8804" /> +- </filter> +- <filter +- inkscape:collect="always" +- id="filter8806" +- x="-0.61142862" +- width="2.2228572" +- y="-0.14930232" +- height="1.2986046"> +- <feGaussianBlur +- inkscape:collect="always" +- stdDeviation="37.830213" +- id="feGaussianBlur8808" /> +- </filter> +- <filter +- inkscape:collect="always" +- id="filter8810" +- x="-0.23519406" +- width="1.4703881" +- y="-0.24500646" +- height="1.4900129"> +- <feGaussianBlur +- inkscape:collect="always" +- stdDeviation="58.328041" +- id="feGaussianBlur8812" /> +- </filter> +- <filter +- inkscape:collect="always" +- id="filter8814" +- x="-0.20466694" +- width="1.4093339" +- y="-0.29007819" +- height="1.5801564"> +- <feGaussianBlur +- inkscape:collect="always" +- stdDeviation="22.300169" +- id="feGaussianBlur8816" /> +- </filter> +- <filter +- inkscape:collect="always" +- id="filter8818" +- x="-0.34381232" +- width="1.6876246" +- y="-0.18433961" +- height="1.3686792"> +- <feGaussianBlur +- inkscape:collect="always" +- stdDeviation="34.542167" +- id="feGaussianBlur8820" /> +- </filter> +- <filter +- inkscape:collect="always" +- id="filter8822" +- x="-0.2742857" +- width="1.5485713" +- y="-0.21333334" +- height="1.4266667"> +- <feGaussianBlur +- inkscape:collect="always" +- stdDeviation="11.313708" +- id="feGaussianBlur8824" /> +- </filter> +- <filter +- inkscape:collect="always" +- id="filter8826" +- x="-0.25894088" +- width="1.5178818" +- y="-0.2236412" +- height="1.4472824"> +- <feGaussianBlur +- inkscape:collect="always" +- stdDeviation="19.631544" +- id="feGaussianBlur8828" /> +- </filter> +- <filter +- inkscape:collect="always" +- id="filter8856" +- x="-0.3253231" +- width="1.6506462" +- y="-0.19013336" +- height="1.3802667"> +- <feGaussianBlur +- inkscape:collect="always" +- stdDeviation="28.712591" +- id="feGaussianBlur8858" /> +- </filter> +- <filter +- inkscape:collect="always" +- id="filter8860" +- x="-0.38093024" +- width="1.7618605" +- y="-0.17518716" +- height="1.3503743"> +- <feGaussianBlur +- inkscape:collect="always" +- stdDeviation="19.304015" +- id="feGaussianBlur8862" /> +- </filter> +- <filter +- inkscape:collect="always" +- id="filter8888" +- x="-0.2112188" +- width="1.4224375" +- y="-0.16808605" +- height="1.3361721"> +- <feGaussianBlur +- inkscape:collect="always" +- stdDeviation="8.3693583" +- id="feGaussianBlur8890" /> +- </filter> +- <filter +- inkscape:collect="always" +- id="filter8892" +- x="-0.18692794" +- width="1.3738559" +- y="-0.23646873" +- height="1.4729375"> +- <feGaussianBlur +- inkscape:collect="always" +- stdDeviation="31.21228" +- id="feGaussianBlur8894" /> +- </filter> +- <clipPath +- clipPathUnits="userSpaceOnUse" +- id="clipPath8906"> +- <path +- style="opacity:1;fill:#262f2f;fill-opacity:1;fill-rule:evenodd;stroke:#000000;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;marker:none;marker-start:none;marker-mid:none;marker-end:none;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" +- d="M 352.24553,211.99185 C 348.4411,186.72762 335.43581,161.35383 335.08873,136.46662 C 334.90247,123.1111 338.36158,109.89571 348.84426,96.912574 C 385.19128,31.616739 465.78517,12.217889 534.77892,5.447147 C 621.70131,-5.569654 719.69159,23.387219 768.15026,100.84843 C 822.27428,176.58173 824.82502,273.38755 848.7623,360.37638 C 878.20009,487.50398 903.54144,616.59052 909.15454,747.22673 C 906.09106,825.40858 900.7282,912.41088 848.65133,975.36086 C 800.62479,1025.7183 725.86486,1025.4139 661.58145,1034.3632 C 571.02606,1039.0182 477.22992,1018.2174 399.79755,970.16496 C 335.02191,932.22495 304.06736,856.68633 302.51815,784.14538 C 294.12898,704.27022 328.90967,630.33687 354.13855,556.98577 C 361.60916,474.2247 363.55141,390.73802 363.79189,307.60093 C 362.95507,275.40549 356.70236,243.7836 352.24553,211.99185 z" +- id="path8908" +- sodipodi:nodetypes="cscccccccccccc" /> +- </clipPath> +- <filter +- inkscape:collect="always" +- id="filter8940" +- x="-0.25152978" +- width="1.5030596" +- y="-0.053035267" +- height="1.1060705"> +- <feGaussianBlur +- inkscape:collect="always" +- stdDeviation="13.024603" +- id="feGaussianBlur8942" /> +- </filter> +- <linearGradient +- inkscape:collect="always" +- xlink:href="#linearGradient8952" +- id="linearGradient8958" +- x1="609.31244" +- y1="239.46866" +- x2="560.83142" +- y2="262.86206" +- gradientUnits="userSpaceOnUse" +- gradientTransform="translate(450.03125,73.843964)" /> +- <linearGradient +- inkscape:collect="always" +- xlink:href="#linearGradient8964" +- id="linearGradient8970" +- x1="603.84064" +- y1="627.85303" +- x2="616.24396" +- y2="585.42664" +- gradientUnits="userSpaceOnUse" +- gradientTransform="translate(450.03125,73.843964)" /> +- <filter +- inkscape:collect="always" +- id="filter9020" +- x="-0.32861114" +- width="1.6572223" +- y="-0.182" +- height="1.364"> +- <feGaussianBlur +- inkscape:collect="always" +- stdDeviation="20.912684" +- id="feGaussianBlur9022" /> +- </filter> +- <filter +- inkscape:collect="always" +- id="filter9024" +- x="-0.55453134" +- width="2.1090627" +- y="-0.51434779" +- height="2.0286956"> +- <feGaussianBlur +- inkscape:collect="always" +- stdDeviation="20.912684" +- id="feGaussianBlur9026" /> +- </filter> +- <filter +- inkscape:collect="always" +- id="filter9044" +- x="-0.32631579" +- width="1.6526316" +- y="-0.84545463" +- height="2.6909094"> +- <feGaussianBlur +- inkscape:collect="always" +- stdDeviation="21.92031" +- id="feGaussianBlur9046" /> +- </filter> +- <filter +- inkscape:collect="always" +- id="filter9048" +- x="-0.40879121" +- width="1.8175824" +- y="-0.71538466" +- height="2.4307692"> +- <feGaussianBlur +- inkscape:collect="always" +- stdDeviation="21.92031" +- id="feGaussianBlur9050" /> +- </filter> +- <filter +- inkscape:collect="always" +- id="filter3587" +- x="-0.1"> +- <feGaussianBlur +- inkscape:collect="always" +- stdDeviation="8.881432" +- id="feGaussianBlur3589" /> +- </filter> +- <clipPath +- clipPathUnits="userSpaceOnUse" +- id="clipPath3602"> +- <path +- sodipodi:nodetypes="czzzzzzczczczczzzc" +- id="path3604" +- d="M 647.61204,540.04601 C 647.61204,540.04601 670.23151,533.5392 683.35479,534.17328 C 696.47807,534.80737 713.99637,536.1119 727.06364,546.35947 C 740.13091,556.60703 752.13138,573.49954 761.17603,604.72912 C 770.22068,635.9587 762.87435,703.98113 755,748.07647 C 747.12565,792.17181 726.7349,854.18945 710,888.07647 C 693.2651,921.96349 660.20229,965.57167 649.43057,977.95263 C 638.06635,991.0146 593.22468,1014.3788 570,1020.2193 C 575.3033,1009.6127 618.89976,969.63046 605,959.50504 C 590.98103,949.29278 559.23991,1005.4874 520.70685,988.53821 C 542.08916,975.40609 562.48625,937.35215 554.74746,921.94376 C 546.90721,906.33337 524.04253,970.70133 461.21192,958.95664 C 491.26396,931.42998 516.61898,888.05263 502.47462,875.97694 C 488.05946,863.67007 442.01287,930.27009 442.01287,930.27009 C 442.01287,930.27009 439.19097,888.56891 455.78607,861.66277 C 472.42542,834.6849 535.43904,780.0475 555.3392,749.95935 C 575.23935,719.87121 588.95176,683.95033 597.47462,657.44141 C 605.99748,630.93249 613.27556,580.34187 613.27556,580.34187" +- style="opacity:1;fill:#202020;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;display:inline;enable-background:new" /> +- </clipPath> +- <filter +- inkscape:collect="always" +- id="filter4120" +- x="-0.2770822" +- width="1.5541644" +- y="-0.32482043" +- height="1.6496409"> +- <feGaussianBlur +- inkscape:collect="always" +- stdDeviation="19.956289" +- id="feGaussianBlur4122" /> +- </filter> +- <clipPath +- clipPathUnits="userSpaceOnUse" +- id="clipPath3631"> +- <path +- style="opacity:1;fill:#ada469;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;display:inline;enable-background:new" +- d="M 760.16396,935.83377 C 766.95806,954.73656 770.65765,969.13346 772.05426,987.04566 C 773.45088,1004.958 768.27158,1038.8465 769.1538,1057.7018 C 770.03555,1076.547 777.28749,1097.8008 796.49843,1106.6707 C 815.9173,1115.6365 845.81767,1116.882 870.61827,1103.5251 C 895.41887,1090.1681 928.01929,1033.1996 941.59253,1006.2164 C 955.21638,979.13246 980.3536,891.71903 986.25333,856.44781 C 992.15306,821.1766 988.80387,815.14704 981.63585,807.39232 C 984.27615,779.55217 980.13613,752.45689 994.74554,720.20614 C 964.49653,732.03184 957.36325,760.36684 946.42665,785.71122 C 938.42574,734.77829 946.63581,714.43803 949.74554,684.49186 C 920.68078,699.26977 906.88403,731.60588 904.74554,777.349 C 893.82159,776.0448 883.3541,772.91477 871.17411,776.63471 C 870.91007,730.61137 869.71055,699.7453 880.08474,662.42822 C 826.82927,683.45508 817.13746,769.02232 824.03125,775.20614 C 813.14843,775.74114 802.66017,773.90884 791.17411,778.06329 C 791.81303,735.49194 790.91365,693.15468 761.17411,655.20614 C 761.17411,655.20614 730.21605,736.12848 729.74554,758.77757 C 729.27503,781.42666 739.19713,798.94345 739.19713,798.94345 C 739.19713,798.94345 730.62906,835.68396 732.89854,857.17568 C 735.19439,878.91714 753.34144,916.85185 760.16396,935.83377 z" +- id="path3633" +- sodipodi:nodetypes="czzzzzzcccccccccczczz" /> +- </clipPath> +- <clipPath +- clipPathUnits="userSpaceOnUse" +- id="clipPath3665"> +- <path +- sodipodi:nodetypes="czzcczcc" +- id="path3667" +- d="M 366.88839,504.13471 C 366.88839,504.13471 337.33433,544.70776 319.03125,578.42042 C 300.72816,612.13309 260.41016,704.77736 248.67411,749.49185 C 236.91471,794.29529 186.17411,873.06329 186.17411,873.06329 L 262.24554,891.27757 C 262.24554,891.27757 274.05266,878.45422 293.31696,845.20614 C 312.58126,811.95806 353.67411,706.63471 353.67411,706.63471 L 366.88839,504.13471 z" +- style="opacity:1;fill:#0f0f0f;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;marker:none;marker-start:none;marker-mid:none;marker-end:none;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" /> +- </clipPath> +- <clipPath +- clipPathUnits="userSpaceOnUse" +- id="clipPath3677"> +- <path +- style="opacity:1;fill:#ada469;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;display:inline;enable-background:new" +- d="M 586.13271,997.98981 C 592.92681,1016.8926 596.6264,1031.2895 598.02301,1049.2017 C 599.41963,1067.114 594.24033,1101.0025 595.12255,1119.8578 C 596.0043,1138.703 603.25624,1159.9568 622.46718,1168.8267 C 641.88605,1177.7925 671.78642,1179.038 696.58702,1165.6811 C 721.38762,1152.3241 753.98804,1095.3556 767.56128,1068.3724 C 781.18513,1041.2885 806.32235,953.87507 812.22208,918.60385 C 818.12181,883.33264 814.77262,877.30308 807.6046,869.54836 C 810.2449,841.70821 806.10488,814.61293 820.71429,782.36218 C 790.46528,794.18788 783.332,822.52288 772.3954,847.86726 C 764.39449,796.93433 772.60456,776.59407 775.71429,746.6479 C 746.64953,761.42581 732.85278,793.76192 730.71429,839.50504 C 719.79034,838.20084 709.32285,835.07081 697.14286,838.79075 C 696.87882,792.76741 695.6793,761.90134 706.05349,724.58426 C 652.79802,745.61112 643.10621,831.17836 650,837.36218 C 639.11718,837.89718 628.62892,836.06488 617.14286,840.21933 C 617.78178,797.64798 616.8824,755.31072 587.14286,717.36218 C 587.14286,717.36218 556.1848,798.28452 555.71429,820.93361 C 555.24378,843.5827 565.16588,861.09949 565.16588,861.09949 C 565.16588,861.09949 556.59781,897.84 558.86729,919.33172 C 561.16314,941.07318 579.31019,979.00789 586.13271,997.98981 z" +- id="path3679" +- sodipodi:nodetypes="czzzzzzcccccccccczczz" /> +- </clipPath> +- <filter +- inkscape:collect="always" +- id="filter3898"> +- <feGaussianBlur +- inkscape:collect="always" +- stdDeviation="10.892985" +- id="feGaussianBlur3900" /> +- </filter> +- <filter +- inkscape:collect="always" +- id="filter4130" +- x="-0.49509686" +- width="1.9901937" +- y="-0.26708817" +- height="1.5341763"> +- <feGaussianBlur +- inkscape:collect="always" +- stdDeviation="10.730622" +- id="feGaussianBlur4132" /> +- </filter> +- <filter +- inkscape:collect="always" +- id="filter4141" +- x="-0.40611032" +- width="1.8122206" +- y="-0.30260596" +- height="1.6052119"> +- <feGaussianBlur +- inkscape:collect="always" +- stdDeviation="9.8586086" +- id="feGaussianBlur4143" /> +- </filter> +- <clipPath +- clipPathUnits="userSpaceOnUse" +- id="clipPath4177"> +- <path +- sodipodi:nodetypes="czzzzzzcccccccccczczz" +- id="path4179" +- d="M 586.13271,997.98981 C 592.92681,1016.8926 596.6264,1031.2895 598.02301,1049.2017 C 599.41963,1067.114 594.24033,1101.0025 595.12255,1119.8578 C 596.0043,1138.703 603.25624,1159.9568 622.46718,1168.8267 C 641.88605,1177.7925 671.78642,1179.038 696.58702,1165.6811 C 721.38762,1152.3241 753.98804,1095.3556 767.56128,1068.3724 C 781.18513,1041.2885 806.32235,953.87507 812.22208,918.60385 C 818.12181,883.33264 814.77262,877.30308 807.6046,869.54836 C 810.2449,841.70821 806.10488,814.61293 820.71429,782.36218 C 790.46528,794.18788 783.332,822.52288 772.3954,847.86726 C 764.39449,796.93433 772.60456,776.59407 775.71429,746.6479 C 746.64953,761.42581 732.85278,793.76192 730.71429,839.50504 C 719.79034,838.20084 709.32285,835.07081 697.14286,838.79075 C 696.87882,792.76741 695.6793,761.90134 706.05349,724.58426 C 652.79802,745.61112 643.10621,831.17836 650,837.36218 C 639.11718,837.89718 628.62892,836.06488 617.14286,840.21933 C 617.78178,797.64798 616.8824,755.31072 587.14286,717.36218 C 587.14286,717.36218 556.1848,798.28452 555.71429,820.93361 C 555.24378,843.5827 565.16588,861.09949 565.16588,861.09949 C 565.16588,861.09949 556.59781,897.84 558.86729,919.33172 C 561.16314,941.07318 579.31019,979.00789 586.13271,997.98981 z" +- style="opacity:1;fill:#ada469;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;display:inline;enable-background:new" /> +- </clipPath> +- <filter +- inkscape:collect="always" +- id="filter4185"> +- <feGaussianBlur +- inkscape:collect="always" +- stdDeviation="3.6164709" +- id="feGaussianBlur4187" /> +- </filter> +- <filter +- inkscape:collect="always" +- id="filter4105"> +- <feGaussianBlur +- inkscape:collect="always" +- stdDeviation="3.8640966" +- id="feGaussianBlur4107" /> +- </filter> +- <clipPath +- clipPathUnits="userSpaceOnUse" +- id="clipPath2833"> +- <path +- style="opacity:1;fill:#292929;fill-opacity:1;fill-rule:evenodd;stroke:#000000;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;marker:none;marker-start:none;marker-mid:none;marker-end:none;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" +- d="M 569.03125,1018.7776 C 564.74554,1019.4919 541.4031,1022.3957 511.17411,1028.7776 C 480.94512,1035.1595 453.86016,1033.7437 375.38803,1046.1072 C 295.53625,1058.688 281.32367,1088.6495 267.26578,1093.1715 C 252.56564,1097.9001 121.88839,1027.349 121.88839,1027.349 L 126.17411,933.06329 C 126.17411,933.06329 212.05962,916.86235 238.31696,899.49186 C 264.57431,882.12137 283.89934,849.82588 297.60268,828.06329 C 311.30602,806.3007 330.45982,756.63471 330.45982,756.63471 L 569.03125,1018.7776 z" +- id="path2835" +- sodipodi:nodetypes="czzzcczzcc" /> +- </clipPath> +- <linearGradient +- inkscape:collect="always" +- xlink:href="#linearGradient2843" +- id="linearGradient2841" +- gradientUnits="userSpaceOnUse" +- x1="347.89655" +- y1="1070.2124" +- x2="275.58191" +- y2="867.97992" /> +- <linearGradient +- inkscape:collect="always" +- xlink:href="#linearGradient3627" +- id="linearGradient3688" +- gradientUnits="userSpaceOnUse" +- x1="699.32867" +- y1="269.76755" +- x2="698.97504" +- y2="346.1351" /> +- <mask +- maskUnits="userSpaceOnUse" +- id="mask3684"> +- <path +- sodipodi:type="arc" +- style="opacity:1;fill:url(#linearGradient3688);fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:0.43724918px;stroke-linecap:butt;stroke-linejoin:miter;marker:none;marker-start:none;marker-mid:none;marker-end:none;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" +- id="path3686" +- sodipodi:cx="579.474" +- sodipodi:cy="260.57516" +- sodipodi:rx="192.6866" +- sodipodi:ry="164.04877" +- d="M 772.1606,260.57516 A 192.6866,164.04877 0 1 1 386.7874,260.57516 A 192.6866,164.04877 0 1 1 772.1606,260.57516 z" +- transform="translate(-174.03125,62.156036)" /> +- </mask> +- <clipPath +- clipPathUnits="userSpaceOnUse" +- id="clipPath3622"> +- <path +- style="opacity:1;fill:#ada469;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;display:inline;enable-background:new" +- d="M 266.27183,924.57186 C 264.86456,943.37307 265.12693,957.32289 268.35357,973.87514 C 271.58022,990.42748 284.75965,1019.7825 288.68797,1037.0589 C 292.61419,1054.326 291.3821,1075.3685 276.22853,1088.2071 C 260.91092,1101.1845 234.17726,1109.806 208.39623,1103.9409 C 182.61517,1098.0756 138.84716,1054.7175 119.80604,1033.7126 C 100.6939,1012.6293 56.045183,939.86194 41.867508,909.43681 C 27.689836,879.01169 29.207903,872.71824 33.747793,863.90708 C 24.381071,839.38658 21.334081,813.84027 0.035335518,788.33044 C 30.360815,791.44488 43.915625,815.28677 60.161025,835.47019 C 54.631129,787.39416 42.10631,771.05369 31.787073,744.74589 C 61.781368,750.82755 82.366433,776.61829 95.766856,817.45839 C 105.32101,813.54048 114.00462,808.08545 125.95427,808.39719 C 114.65677,766.70139 108.00481,738.48135 89.267015,707.32725 C 142.70898,712.99758 172.92404,787.96657 168.23844,795.28805 C 178.21641,793.04406 187.24409,788.75767 198.67497,789.63638 C 187.42601,751.28936 177.62716,712.76848 195.01526,670.9882 C 195.01526,670.9882 243.30204,736.42507 249.40492,756.79397 C 255.50779,777.16288 250.92373,795.49449 250.92373,795.49449 C 250.92373,795.49449 267.8833,826.57978 271.21765,846.58862 C 274.59075,866.82997 267.68496,905.69194 266.27183,924.57186 z" +- id="path3624" +- sodipodi:nodetypes="czzzzzzcccccccccczczz" /> +- </clipPath> +- <clipPath +- clipPathUnits="userSpaceOnUse" +- id="clipPath3636"> +- <path +- style="opacity:1;fill:#ada469;fill-opacity:1;fill-rule:evenodd;stroke:#000000;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;display:inline;enable-background:new" +- d="M 760.16396,935.83377 C 766.95806,954.73656 770.65765,969.13346 772.05426,987.04566 C 773.45088,1004.958 768.27158,1038.8465 769.1538,1057.7018 C 770.03555,1076.547 777.28749,1097.8008 796.49843,1106.6707 C 815.9173,1115.6365 845.81767,1116.882 870.61827,1103.5251 C 895.41887,1090.1681 928.01929,1033.1996 941.59253,1006.2164 C 955.21638,979.13246 980.3536,891.71903 986.25333,856.44781 C 992.15306,821.1766 988.80387,815.14704 981.63585,807.39232 C 984.27615,779.55217 980.13613,752.45689 994.74554,720.20614 C 964.49653,732.03184 957.36325,760.36684 946.42665,785.71122 C 938.42574,734.77829 946.63581,714.43803 949.74554,684.49186 C 920.68078,699.26977 906.88403,731.60588 904.74554,777.349 C 893.82159,776.0448 883.3541,772.91477 871.17411,776.63471 C 870.91007,730.61137 869.71055,699.7453 880.08474,662.42822 C 826.82927,683.45508 817.13746,769.02232 824.03125,775.20614 C 813.14843,775.74114 802.66017,773.90884 791.17411,778.06329 C 791.81303,735.49194 790.91365,693.15468 761.17411,655.20614 C 761.17411,655.20614 730.21605,736.12848 729.74554,758.77757 C 729.27503,781.42666 739.19713,798.94345 739.19713,798.94345 C 739.19713,798.94345 730.62906,835.68396 732.89854,857.17568 C 735.19439,878.91714 753.34144,916.85185 760.16396,935.83377 z" +- id="path3638" +- sodipodi:nodetypes="czzzzzzcccccccccczczz" /> +- </clipPath> +- <linearGradient +- inkscape:collect="always" +- xlink:href="#linearGradient3660" +- id="linearGradient3666" +- x1="1255.7386" +- y1="667.09216" +- x2="893.69995" +- y2="858.01099" +- gradientUnits="userSpaceOnUse" /> +- <filter +- inkscape:collect="always" +- id="filter3779" +- x="-0.087980822" +- width="1.1759616" +- y="-0.17728332" +- height="1.3545666"> +- <feGaussianBlur +- inkscape:collect="always" +- stdDeviation="16.340344" +- id="feGaussianBlur3781" /> +- </filter> +- <filter +- id="filter3785" +- inkscape:label="White Fur"> +- <feTurbulence +- id="feTurbulence3787" +- in="SourceAlpha" +- type="fractalNoise" +- baseFrequency="0.24044943820224721" +- numOctaves="10" +- seed="655" +- result="result0" /> +- <feDisplacementMap +- id="feDisplacementMap3789" +- in="SourceGraphic" +- in2="result0" +- scale="62" +- xChannelSelector="B" +- yChannelSelector="G" /> +- </filter> +- <filter +- inkscape:collect="always" +- id="filter3677"> +- <feGaussianBlur +- inkscape:collect="always" +- stdDeviation="2.0397518" +- id="feGaussianBlur3679" /> +- </filter> +- <clipPath +- clipPathUnits="userSpaceOnUse" +- id="clipPath3722"> +- <path +- style="opacity:1;fill:#121212;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;marker:none;marker-start:none;marker-mid:none;marker-end:none;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" +- d="M 709.28572,844.50504 C 763.57143,843.07647 835.32072,829.45305 879.28572,817.71932 C 923.33843,805.96218 1005.172,781.37208 1054.6428,759.86218 C 1103.9821,738.40946 1168.2465,700.58058 1208.9286,667.71933 C 1249.4367,634.99864 1261.3185,611.89952 1269.6429,634.1479 C 1278.012,656.51569 1253.2359,690.47352 1231.7857,715.21933 C 1210.1816,740.14273 1179.0544,767.92466 1132.8571,804.50504 C 1086.6598,841.08542 976.77458,906.08967 920,933.07647 C 862.93394,960.20183 791.79666,991.31489 747.85714,1005.5765 C 703.91762,1019.8381 616.42857,1036.6479 616.42857,1036.6479 L 709.28572,844.50504 z" +- id="path3724" +- sodipodi:nodetypes="czzzzzzzzcc" /> +- </clipPath> +- <clipPath +- clipPathUnits="userSpaceOnUse" +- id="clipPath3986"> +- <path +- style="opacity:1;fill:#121212;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;marker:none;marker-start:none;marker-mid:none;marker-end:none;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" +- d="M 709.28572,844.50504 C 763.57143,843.07647 835.32072,829.45305 879.28572,817.71932 C 923.33843,805.96218 1005.172,781.37208 1054.6428,759.86218 C 1103.9821,738.40946 1168.2465,700.58058 1208.9286,667.71933 C 1249.4367,634.99864 1261.3185,611.89952 1269.6429,634.1479 C 1278.012,656.51569 1253.2359,690.47352 1231.7857,715.21933 C 1210.1816,740.14273 1179.0544,767.92466 1132.8571,804.50504 C 1086.6598,841.08542 976.77458,906.08967 920,933.07647 C 862.93394,960.20183 791.79666,991.31489 747.85714,1005.5765 C 703.91762,1019.8381 616.42857,1036.6479 616.42857,1036.6479 L 709.28572,844.50504 z" +- id="path3988" +- sodipodi:nodetypes="czzzzzzzzcc" /> +- </clipPath> +- <clipPath +- clipPathUnits="userSpaceOnUse" +- id="clipPath3992"> +- <path +- style="opacity:1;fill:#121212;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;marker:none;marker-start:none;marker-mid:none;marker-end:none;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" +- d="M 709.28572,844.50504 C 763.57143,843.07647 835.32072,829.45305 879.28572,817.71932 C 923.33843,805.96218 1005.172,781.37208 1054.6428,759.86218 C 1103.9821,738.40946 1168.2465,700.58058 1208.9286,667.71933 C 1249.4367,634.99864 1261.3185,611.89952 1269.6429,634.1479 C 1278.012,656.51569 1253.2359,690.47352 1231.7857,715.21933 C 1210.1816,740.14273 1179.0544,767.92466 1132.8571,804.50504 C 1086.6598,841.08542 976.77458,906.08967 920,933.07647 C 862.93394,960.20183 791.79666,991.31489 747.85714,1005.5765 C 703.91762,1019.8381 616.42857,1036.6479 616.42857,1036.6479 L 709.28572,844.50504 z" +- id="path3994" +- sodipodi:nodetypes="czzzzzzzzcc" /> +- </clipPath> +- <clipPath +- clipPathUnits="userSpaceOnUse" +- id="clipPath3998"> +- <path +- style="opacity:1;fill:#262f2f;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;marker:none;marker-start:none;marker-mid:none;marker-end:none;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" +- d="M 178.21428,274.14789 C 174.40985,248.88366 161.40456,223.50987 161.05748,198.62266 C 160.87122,185.26714 164.33033,172.05175 174.81301,159.06861 C 211.16003,93.772775 291.75392,74.373925 360.74767,67.603183 C 447.67006,56.586382 545.66034,85.543255 594.11901,163.00447 C 648.24303,238.73777 650.79377,335.54359 674.73105,422.53242 C 704.16884,549.66002 729.51019,678.74656 735.12329,809.38277 C 732.05981,887.56462 726.69695,974.56692 674.62008,1037.5169 C 626.59354,1087.8743 551.83361,1087.5699 487.5502,1096.5192 C 396.99481,1101.1742 303.19867,1080.3734 225.7663,1032.321 C 160.99066,994.38099 130.03611,918.84237 128.4869,846.30142 C 120.09773,766.42626 154.87842,692.49291 180.1073,619.14181 C 187.57791,536.38074 189.52016,452.89406 189.76064,369.75697 C 188.92382,337.56153 182.67111,305.93964 178.21428,274.14789 z" +- id="path4000" +- sodipodi:nodetypes="cscccccccccccc" /> +- </clipPath> +- <filter +- inkscape:collect="always" +- id="filter4002" +- x="-0.24334238" +- width="1.4866848" +- y="-0.39104807" +- height="1.7820961"> +- <feGaussianBlur +- inkscape:collect="always" +- stdDeviation="14.589518" +- id="feGaussianBlur4004" /> +- </filter> +- <filter +- inkscape:collect="always" +- id="filter4010" +- x="-0.14577261" +- width="1.2915452" +- y="-0.23523259" +- height="1.4704652"> +- <feGaussianBlur +- inkscape:collect="always" +- stdDeviation="4.4442907" +- id="feGaussianBlur4012" /> +- </filter> +- <filter +- inkscape:collect="always" +- id="filter4053"> +- <feGaussianBlur +- inkscape:collect="always" +- stdDeviation="0.6062947" +- id="feGaussianBlur4055" /> +- </filter> +- <filter +- inkscape:collect="always" +- id="filter4079"> +- <feGaussianBlur +- inkscape:collect="always" +- stdDeviation="6.5887624" +- id="feGaussianBlur4081" /> +- </filter> +- <filter +- inkscape:collect="always" +- id="filter4083"> +- <feGaussianBlur +- inkscape:collect="always" +- stdDeviation="1.5052066" +- id="feGaussianBlur4085" /> +- </filter> +- <radialGradient +- inkscape:collect="always" +- xlink:href="#linearGradient4113" +- id="radialGradient4119" +- cx="296.33783" +- cy="427.17749" +- fx="296.33783" +- fy="427.17749" +- r="19.704132" +- gradientUnits="userSpaceOnUse" +- gradientTransform="matrix(2.9797125,0,0,2.9797125,-599.28727,-827.0855)" /> +- <filter +- inkscape:collect="always" +- id="filter6949" +- x="-0.10294895" +- width="1.2058979" +- y="-0.34224695" +- height="1.6844939"> +- <feGaussianBlur +- inkscape:collect="always" +- stdDeviation="1.1675612" +- id="feGaussianBlur6951" /> +- </filter> +- <filter +- inkscape:collect="always" +- id="filter6953" +- x="-0.098320946" +- width="1.1966419" +- y="-0.19750816" +- height="1.3950163"> +- <feGaussianBlur +- inkscape:collect="always" +- stdDeviation="1.1675612" +- id="feGaussianBlur6955" /> +- </filter> +- <filter +- inkscape:collect="always" +- id="filter6957" +- x="-0.098213427" +- width="1.1964267" +- y="-0.19838208" +- height="1.3967642"> +- <feGaussianBlur +- inkscape:collect="always" +- stdDeviation="1.1675612" +- id="feGaussianBlur6959" /> +- </filter> +- <filter +- inkscape:collect="always" +- id="filter6961" +- x="-0.09919104" +- width="1.1983821" +- y="-0.22643611" +- height="1.4528722"> +- <feGaussianBlur +- inkscape:collect="always" +- stdDeviation="1.1675612" +- id="feGaussianBlur6963" /> +- </filter> +- <filter +- inkscape:collect="always" +- id="filter6965" +- x="-0.099081434" +- width="1.1981629" +- y="-0.22529824" +- height="1.4505965"> +- <feGaussianBlur +- inkscape:collect="always" +- stdDeviation="1.1675612" +- id="feGaussianBlur6967" /> +- </filter> +- <filter +- inkscape:collect="always" +- id="filter6969" +- x="-0.10450897" +- width="1.2090179" +- y="-0.40468886" +- height="1.8093777"> +- <feGaussianBlur +- inkscape:collect="always" +- stdDeviation="1.1675612" +- id="feGaussianBlur6971" /> +- </filter> +- <filter +- inkscape:collect="always" +- id="filter6973" +- x="-0.10330495" +- width="1.2066098" +- y="-0.36439717" +- height="1.7287945"> +- <feGaussianBlur +- inkscape:collect="always" +- stdDeviation="1.1675612" +- id="feGaussianBlur6975" /> +- </filter> +- <filter +- inkscape:collect="always" +- id="filter6977" +- x="-0.10224481" +- width="1.2044896" +- y="-0.32371372" +- height="1.6474274"> +- <feGaussianBlur +- inkscape:collect="always" +- stdDeviation="1.1675612" +- id="feGaussianBlur6979" /> +- </filter> +- <filter +- inkscape:collect="always" +- id="filter6981" +- x="-0.10052545" +- width="1.2010509" +- y="-0.2742162" +- height="1.5484324"> +- <feGaussianBlur +- inkscape:collect="always" +- stdDeviation="1.1675612" +- id="feGaussianBlur6983" /> +- </filter> +- <filter +- inkscape:collect="always" +- id="filter6985" +- x="-0.098428868" +- width="1.1968577" +- y="-0.20853186" +- height="1.4170637"> +- <feGaussianBlur +- inkscape:collect="always" +- stdDeviation="1.1675612" +- id="feGaussianBlur6987" /> +- </filter> +- <filter +- inkscape:collect="always" +- id="filter6989" +- x="-0.098428868" +- width="1.1968577" +- y="-0.20287035" +- height="1.4057407"> +- <feGaussianBlur +- inkscape:collect="always" +- stdDeviation="1.1675612" +- id="feGaussianBlur6991" /> +- </filter> +- <filter +- inkscape:collect="always" +- id="filter6993" +- x="-0.098213255" +- width="1.1964265" +- y="-0.19838208" +- height="1.3967642"> +- <feGaussianBlur +- inkscape:collect="always" +- stdDeviation="1.1675612" +- id="feGaussianBlur6995" /> +- </filter> +- <filter +- inkscape:collect="always" +- id="filter6997"> +- <feGaussianBlur +- inkscape:collect="always" +- stdDeviation="1.1675612" +- id="feGaussianBlur6999" /> +- </filter> +- <filter +- inkscape:collect="always" +- id="filter7001"> +- <feGaussianBlur +- inkscape:collect="always" +- stdDeviation="1.1675612" +- id="feGaussianBlur7003" /> +- </filter> +- <filter +- inkscape:collect="always" +- id="filter7285" +- x="-0.030884685" +- width="1.0617694" +- y="-0.10267408" +- height="1.2053483"> +- <feGaussianBlur +- inkscape:collect="always" +- stdDeviation="0.35026836" +- id="feGaussianBlur7287" /> +- </filter> +- <filter +- inkscape:collect="always" +- id="filter7289"> +- <feGaussianBlur +- inkscape:collect="always" +- stdDeviation="0.35026836" +- id="feGaussianBlur7291" /> +- </filter> +- <filter +- inkscape:collect="always" +- id="filter7293"> +- <feGaussianBlur +- inkscape:collect="always" +- stdDeviation="0.35026836" +- id="feGaussianBlur7295" /> +- </filter> +- <filter +- inkscape:collect="always" +- id="filter7297"> +- <feGaussianBlur +- inkscape:collect="always" +- stdDeviation="0.35026836" +- id="feGaussianBlur7299" /> +- </filter> +- <filter +- inkscape:collect="always" +- id="filter7301"> +- <feGaussianBlur +- inkscape:collect="always" +- stdDeviation="0.35026836" +- id="feGaussianBlur7303" /> +- </filter> +- <filter +- inkscape:collect="always" +- id="filter7305"> +- <feGaussianBlur +- inkscape:collect="always" +- stdDeviation="0.35026836" +- id="feGaussianBlur7307" /> +- </filter> +- <filter +- inkscape:collect="always" +- id="filter7309"> +- <feGaussianBlur +- inkscape:collect="always" +- stdDeviation="0.35026836" +- id="feGaussianBlur7311" /> +- </filter> +- <filter +- inkscape:collect="always" +- id="filter7313"> +- <feGaussianBlur +- inkscape:collect="always" +- stdDeviation="0.35026836" +- id="feGaussianBlur7315" /> +- </filter> +- <filter +- inkscape:collect="always" +- id="filter7317"> +- <feGaussianBlur +- inkscape:collect="always" +- stdDeviation="0.35026836" +- id="feGaussianBlur7319" /> +- </filter> +- <filter +- inkscape:collect="always" +- id="filter7321"> +- <feGaussianBlur +- inkscape:collect="always" +- stdDeviation="0.35026836" +- id="feGaussianBlur7323" /> +- </filter> +- <filter +- inkscape:collect="always" +- id="filter7325" +- x="-0.031352691" +- width="1.0627054" +- y="-0.12140666" +- height="1.2428133"> +- <feGaussianBlur +- inkscape:collect="always" +- stdDeviation="0.35026836" +- id="feGaussianBlur7327" /> +- </filter> +- <filter +- inkscape:collect="always" +- id="filter7329" +- x="-0.030991485" +- width="1.061983" +- y="-0.10931916" +- height="1.2186383"> +- <feGaussianBlur +- inkscape:collect="always" +- stdDeviation="0.35026836" +- id="feGaussianBlur7331" /> +- </filter> +- <filter +- inkscape:collect="always" +- id="filter7333"> +- <feGaussianBlur +- inkscape:collect="always" +- stdDeviation="0.35026836" +- id="feGaussianBlur7335" /> +- </filter> +- <filter +- inkscape:collect="always" +- id="filter7337"> +- <feGaussianBlur +- inkscape:collect="always" +- stdDeviation="0.35026836" +- id="feGaussianBlur7339" /> +- </filter> +- <filter +- inkscape:collect="always" +- id="filter7345"> +- <feGaussianBlur +- inkscape:collect="always" +- stdDeviation="1.7233839" +- id="feGaussianBlur7347" /> +- </filter> +- <clipPath +- clipPathUnits="userSpaceOnUse" +- id="clipPath7421"> +- <path +- sodipodi:type="inkscape:offset" +- inkscape:radius="0" +- inkscape:original="M 1111.4062 -285.9375 L 1107.4688 -284.0625 C 1107.4283 -284.05228 1107.3692 -284.04201 1107.3438 -284.03125 C 1106.925 -283.8184 1107.1791 -283.93067 1106.6875 -283.71875 C 1106.2014 -283.50919 1104.9499 -283.13456 1102.5938 -282.25 C 1099.2626 -280.99942 1096.7895 -280.10016 1095.5938 -279.1875 C 1094.0576 -279.16623 1091.8733 -278.95419 1089.9375 -278.46875 C 1086.956 -277.72108 1085.0823 -277.29474 1083.1875 -276.875 C 1081.2927 -276.45527 1081.512 -276.23281 1080.3125 -276 C 1079.0159 -275.74833 1078.5911 -276.00899 1074.875 -275.21875 C 1071.3851 -274.4766 1065.9802 -273.28768 1064.7188 -272.53125 C 1063.1348 -272.71203 1060.8513 -272.85303 1058.875 -272.5625 C 1055.8346 -272.11554 1053.9588 -271.88974 1052.0312 -271.65625 C 1051.3758 -271.57687 1050.9902 -271.45547 1050.6875 -271.375 C 1050.2613 -271.24334 1050.0017 -271.11498 1049.3125 -271.03125 C 1048.0009 -270.87188 1047.5503 -271.18808 1043.7812 -270.75 C 1040.2273 -270.33691 1034.7758 -269.47718 1033.5312 -268.8125 C 1031.9322 -269.10979 1029.6735 -269.34669 1027.6875 -269.15625 C 1024.6287 -268.86293 1022.7155 -268.67226 1020.7812 -268.5 C 1018.847 -268.32773 1019.0926 -268.07763 1017.875 -267.96875 C 1016.5588 -267.85105 1016.1152 -268.13238 1012.3438 -267.71875 C 1008.8017 -267.3303 1003.3359 -266.50948 1002.0625 -265.84375 C 1000.4636 -266.13844 998.1753 -266.35076 996.1875 -266.15625 C 993.12921 -265.857 991.2463 -265.67601 989.3125 -265.5 C 988.65501 -265.44015 988.27245 -265.32144 987.96875 -265.25 C 987.54105 -265.13104 987.28525 -265.03193 986.59375 -264.96875 C 985.27775 -264.84849 984.834 -265.16363 981.0625 -264.75 C 977.50631 -264.35998 972.0569 -263.51084 970.8125 -262.84375 C 969.21381 -263.13793 966.95265 -263.36747 964.96875 -263.15625 C 961.91305 -262.83092 959.9947 -262.63001 958.0625 -262.4375 C 956.13031 -262.24499 956.37275 -261.99662 955.15625 -261.875 C 953.84137 -261.74353 953.3932 -262.03954 949.625 -261.59375 C 946.08611 -261.17509 940.6473 -260.30158 939.375 -259.625 C 937.77741 -259.90604 935.51505 -260.04543 933.53125 -259.8125 C 930.47927 -259.45413 928.58625 -259.24464 926.65625 -259.03125 C 926.00007 -258.95869 925.6156 -258.85856 925.3125 -258.78125 C 924.88571 -258.65402 924.6276 -258.51405 923.9375 -258.4375 C 922.62411 -258.29181 922.17015 -258.61152 918.40625 -258.125 C 914.85737 -257.66624 909.4276 -256.70598 908.1875 -256 C 906.59441 -256.24424 904.3537 -256.38135 902.375 -256.125 C 899.32741 -255.73018 897.4243 -255.47655 895.5 -255.21875 C 893.57571 -254.96096 893.7739 -254.72522 892.5625 -254.5625 C 891.25301 -254.3866 890.8153 -254.66688 887.0625 -254.09375 C 883.53821 -253.55551 878.1393 -252.39458 876.875 -251.65625 C 875.28751 -251.85979 873.0295 -251.91098 871.0625 -251.5625 C 868.03631 -251.02638 866.1636 -250.70081 864.25 -250.375 C 863.59941 -250.26423 863.2363 -250.10406 862.9375 -250 C 862.51681 -249.83512 862.27405 -249.6687 861.59375 -249.53125 C 860.29905 -249.26966 859.86665 -249.53745 856.15625 -248.71875 C 852.65777 -247.9468 847.31035 -246.33582 846.09375 -245.5 C 844.53085 -245.57745 842.33625 -245.41472 840.40625 -244.90625 C 837.43387 -244.12312 835.58855 -243.67416 833.71875 -243.15625 C 831.84875 -242.63835 832.0521 -242.38897 830.875 -242.0625 C 829.60251 -241.7096 829.17795 -241.95541 825.53125 -240.875 C 822.10657 -239.86037 816.88185 -237.94183 815.65625 -237.03125 C 814.11747 -237.01851 811.93645 -236.75903 810.03125 -236.15625 C 807.10027 -235.22891 805.2809 -234.69783 803.4375 -234.09375 C 802.81071 -233.88837 802.44585 -233.70117 802.15625 -233.5625 C 801.74867 -233.34889 801.50295 -233.15375 800.84375 -232.9375 C 799.58925 -232.52596 799.1576 -232.74846 795.5625 -231.5 C 792.17261 -230.32283 786.96755 -228.2863 785.78125 -227.34375 C 784.25737 -227.28408 782.1312 -226.94888 780.25 -226.28125 C 777.35261 -225.25296 775.55095 -224.60577 773.71875 -223.96875 C 771.88655 -223.33174 772.0909 -223.12021 770.9375 -222.71875 C 769.69071 -222.28479 769.27395 -222.51903 765.71875 -221.15625 C 762.38005 -219.87645 757.23165 -217.6737 756.03125 -216.6875 C 754.52407 -216.57981 752.39555 -216.1887 750.53125 -215.46875 C 747.66307 -214.36115 745.90735 -213.68719 744.09375 -213 C 743.47705 -212.76637 743.0973 -212.55797 742.8125 -212.40625 C 742.81251 -212.40625 742.8125 -212.37673 742.8125 -212.375 L 734.8125 -209.1875 L 736.625 -194.46875 C 736.36701 -194.52956 742.8125 -191.15625 742.8125 -191.15625 C 743.03891 -191.30093 743.26145 -191.42886 743.53125 -191.53125 C 744.61177 -191.94123 745.70285 -191.74702 749.53125 -193.21875 C 753.35977 -194.69049 754.7553 -195.22373 755.4375 -195.625 C 756.11711 -196.02478 757.04925 -196.50437 757.65625 -197.15625 C 759.48317 -197.294 761.22705 -197.64948 762.59375 -198.15625 C 765.56175 -199.25677 767.4691 -199.96244 769.375 -200.625 C 771.28081 -201.28754 771.72915 -202.03987 772.78125 -202.40625 C 773.87287 -202.78636 774.97635 -202.57163 778.84375 -203.9375 C 782.71115 -205.30336 784.1269 -205.76458 784.8125 -206.15625 C 785.51361 -206.55677 786.5133 -207.08923 787.125 -207.75 C 789.09581 -207.80466 790.94195 -208.13463 792.40625 -208.625 C 795.40777 -209.63008 797.3324 -210.24671 799.25 -210.875 C 800.78861 -211.3791 801.42415 -211.92177 802.15625 -212.3125 C 802.38647 -212.44681 802.63215 -212.56623 802.90625 -212.65625 C 804.00457 -213.01673 805.0877 -212.73762 809 -213.96875 C 812.91231 -215.19988 814.366 -215.6417 815.0625 -216 C 815.75641 -216.35697 816.6926 -216.79261 817.3125 -217.40625 C 819.17771 -217.42891 820.94835 -217.67308 822.34375 -218.09375 C 825.37415 -219.00729 827.33615 -219.52385 829.28125 -220.0625 C 831.22637 -220.60114 831.70745 -221.32702 832.78125 -221.625 C 833.89527 -221.93415 835.00125 -221.61761 838.96875 -222.65625 C 842.93625 -223.69488 844.38625 -224.08898 845.09375 -224.40625 C 845.82855 -224.73584 846.90765 -225.15997 847.53125 -225.78125 C 849.52907 -225.66525 851.3887 -225.80134 852.875 -226.15625 C 855.95311 -226.89125 857.9584 -227.25719 859.9375 -227.65625 C 861.52541 -227.97643 862.1818 -228.4468 862.9375 -228.75 C 863.17501 -228.8568 863.4044 -228.94276 863.6875 -229 C 864.82091 -229.22919 865.99215 -228.79107 870.03125 -229.5 C 874.07067 -230.20893 875.5315 -230.42709 876.25 -230.6875 C 876.96581 -230.94694 877.95435 -231.25474 878.59375 -231.78125 C 880.51795 -231.54176 882.34165 -231.55672 883.78125 -231.78125 C 886.90767 -232.26887 888.9358 -232.48192 890.9375 -232.75 C 892.93921 -233.01807 893.42625 -233.69514 894.53125 -233.84375 C 895.67767 -233.99793 896.8071 -233.54218 900.875 -234.0625 C 904.94281 -234.58282 906.43525 -234.75823 907.15625 -235 C 907.89337 -235.24714 908.95435 -235.58623 909.59375 -236.125 C 911.64375 -235.78947 913.56745 -235.72704 915.09375 -235.90625 C 918.23595 -236.27521 920.27375 -236.46561 922.28125 -236.6875 C 923.89207 -236.86552 924.5459 -237.2957 925.3125 -237.53125 C 925.55341 -237.61677 925.80655 -237.68685 926.09375 -237.71875 C 927.24345 -237.84647 928.39505 -237.3721 932.46875 -237.84375 C 936.54245 -238.3154 938.0278 -238.45435 938.75 -238.6875 C 939.46941 -238.91977 940.45025 -239.16096 941.09375 -239.65625 C 943.03005 -239.32279 944.8638 -239.25201 946.3125 -239.40625 C 949.45851 -239.7412 951.49 -239.92484 953.5 -240.125 C 955.50991 -240.32514 955.98415 -240.95139 957.09375 -241.0625 C 958.24485 -241.17778 959.39025 -240.69744 963.46875 -241.125 C 967.54725 -241.55256 969.05765 -241.68709 969.78125 -241.90625 C 970.52047 -242.13011 971.57685 -242.4195 972.21875 -242.9375 C 974.27575 -242.53883 976.2206 -242.4441 977.75 -242.59375 C 980.89871 -242.90185 982.9258 -243.067 984.9375 -243.25 C 986.55151 -243.39682 987.20055 -243.81055 987.96875 -244.03125 C 988.21005 -244.11211 988.4623 -244.16116 988.75 -244.1875 C 989.90211 -244.29295 991.0429 -243.79475 995.125 -244.1875 C 999.20711 -244.58025 1000.7139 -244.71834 1001.4375 -244.9375 C 1002.1584 -245.15583 1003.1371 -245.3852 1003.7812 -245.875 C 1005.7193 -245.52501 1007.5501 -245.42062 1009 -245.5625 C 1012.1487 -245.8706 1014.1758 -246.03575 1016.1875 -246.21875 C 1018.1991 -246.40174 1018.7017 -247.05677 1019.8125 -247.15625 C 1020.9648 -247.25948 1022.1047 -246.77142 1026.1875 -247.15625 C 1030.2704 -247.54107 1031.7762 -247.65725 1032.5 -247.875 C 1033.2393 -248.09743 1034.2956 -248.38949 1034.9375 -248.90625 C 1036.9949 -248.50448 1038.9404 -248.40292 1040.4688 -248.5625 C 1043.6153 -248.89102 1045.6458 -249.0852 1047.6562 -249.28125 C 1049.2692 -249.43854 1049.9219 -249.91273 1050.6875 -250.15625 C 1050.9282 -250.24429 1051.1507 -250.27762 1051.4375 -250.3125 C 1052.5858 -250.4522 1053.7542 -249.97259 1057.8125 -250.5625 C 1061.8708 -251.15242 1063.3743 -251.33964 1064.0938 -251.59375 C 1064.8104 -251.84691 1065.7684 -252.15182 1066.4062 -252.6875 C 1068.3259 -252.47556 1070.1262 -252.53609 1071.5625 -252.78125 C 1074.6816 -253.31365 1076.6741 -253.70986 1078.6562 -254.09375 C 1080.6383 -254.47762 1081.1305 -255.1334 1082.2188 -255.375 C 1083.3475 -255.62566 1084.489 -255.25871 1088.4688 -256.25 C 1092.4483 -257.24127 1093.8983 -257.6693 1094.5938 -258.03125 C 1095.316 -258.40725 1096.3555 -258.90183 1096.9688 -259.5625 C 1098.9317 -259.57454 1100.7625 -259.85355 1102.1875 -260.40625 C 1105.1387 -261.55085 1107.0607 -262.27567 1108.875 -263.15625 C 1110.3307 -263.86277 1111.1941 -264.85828 1111.4062 -265.15625 C 1111.6185 -265.4542 1111.5051 -265.8848 1111.5312 -265.90625 C 1111.5742 -265.94148 1111.8716 -266.00028 1112.0312 -266.34375 C 1112.8902 -268.19082 1114.3544 -271.97139 1114.4688 -272.65625 C 1114.5825 -273.33839 1114.6368 -274.00902 1114.6875 -274.40625 C 1114.7169 -274.63575 1114.5404 -275.28515 1114.5625 -275.34375 C 1114.5934 -275.42579 1114.8508 -275.59432 1114.9062 -275.84375 C 1115.1725 -277.04206 1114.9953 -278.05111 1114.7812 -279.46875 C 1114.5673 -280.88638 1113.8096 -284.08338 1113.1562 -284.9375 C 1112.4973 -285.79922 1111.9314 -285.94801 1111.4062 -285.9375 z " +- style="fill:#bcb786;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;display:inline;enable-background:new" +- id="path7423" +- d="M 1111.4062,-285.9375 L 1107.4688,-284.0625 C 1107.4283,-284.05228 1107.3692,-284.04201 1107.3438,-284.03125 C 1106.925,-283.8184 1107.1791,-283.93067 1106.6875,-283.71875 C 1106.2014,-283.50919 1104.9499,-283.13456 1102.5938,-282.25 C 1099.2626,-280.99942 1096.7895,-280.10016 1095.5938,-279.1875 C 1094.0576,-279.16623 1091.8733,-278.95419 1089.9375,-278.46875 C 1086.956,-277.72108 1085.0823,-277.29474 1083.1875,-276.875 C 1081.2927,-276.45527 1081.512,-276.23281 1080.3125,-276 C 1079.0159,-275.74833 1078.5911,-276.00899 1074.875,-275.21875 C 1071.3851,-274.4766 1065.9802,-273.28768 1064.7188,-272.53125 C 1063.1348,-272.71203 1060.8513,-272.85303 1058.875,-272.5625 C 1055.8346,-272.11554 1053.9588,-271.88974 1052.0312,-271.65625 C 1051.3758,-271.57687 1050.9902,-271.45547 1050.6875,-271.375 C 1050.2613,-271.24334 1050.0017,-271.11498 1049.3125,-271.03125 C 1048.0009,-270.87188 1047.5503,-271.18808 1043.7812,-270.75 C 1040.2273,-270.33691 1034.7758,-269.47718 1033.5312,-268.8125 C 1031.9322,-269.10979 1029.6735,-269.34669 1027.6875,-269.15625 C 1024.6287,-268.86293 1022.7155,-268.67226 1020.7812,-268.5 C 1018.847,-268.32773 1019.0926,-268.07763 1017.875,-267.96875 C 1016.5588,-267.85105 1016.1152,-268.13238 1012.3438,-267.71875 C 1008.8017,-267.3303 1003.3359,-266.50948 1002.0625,-265.84375 C 1000.4636,-266.13844 998.1753,-266.35076 996.1875,-266.15625 C 993.12921,-265.857 991.2463,-265.67601 989.3125,-265.5 C 988.65501,-265.44015 988.27245,-265.32144 987.96875,-265.25 C 987.54105,-265.13104 987.28525,-265.03193 986.59375,-264.96875 C 985.27775,-264.84849 984.834,-265.16363 981.0625,-264.75 C 977.50631,-264.35998 972.0569,-263.51084 970.8125,-262.84375 C 969.21381,-263.13793 966.95265,-263.36747 964.96875,-263.15625 C 961.91305,-262.83092 959.9947,-262.63001 958.0625,-262.4375 C 956.13031,-262.24499 956.37275,-261.99662 955.15625,-261.875 C 953.84137,-261.74353 953.3932,-262.03954 949.625,-261.59375 C 946.08611,-261.17509 940.6473,-260.30158 939.375,-259.625 C 937.77741,-259.90604 935.51505,-260.04543 933.53125,-259.8125 C 930.47927,-259.45413 928.58625,-259.24464 926.65625,-259.03125 C 926.00007,-258.95869 925.6156,-258.85856 925.3125,-258.78125 C 924.88571,-258.65402 924.6276,-258.51405 923.9375,-258.4375 C 922.62411,-258.29181 922.17015,-258.61152 918.40625,-258.125 C 914.85737,-257.66624 909.4276,-256.70598 908.1875,-256 C 906.59441,-256.24424 904.3537,-256.38135 902.375,-256.125 C 899.32741,-255.73018 897.4243,-255.47655 895.5,-255.21875 C 893.57571,-254.96096 893.7739,-254.72522 892.5625,-254.5625 C 891.25301,-254.3866 890.8153,-254.66688 887.0625,-254.09375 C 883.53821,-253.55551 878.1393,-252.39458 876.875,-251.65625 C 875.28751,-251.85979 873.0295,-251.91098 871.0625,-251.5625 C 868.03631,-251.02638 866.1636,-250.70081 864.25,-250.375 C 863.59941,-250.26423 863.2363,-250.10406 862.9375,-250 C 862.51681,-249.83512 862.27405,-249.6687 861.59375,-249.53125 C 860.29905,-249.26966 859.86665,-249.53745 856.15625,-248.71875 C 852.65777,-247.9468 847.31035,-246.33582 846.09375,-245.5 C 844.53085,-245.57745 842.33625,-245.41472 840.40625,-244.90625 C 837.43387,-244.12312 835.58855,-243.67416 833.71875,-243.15625 C 831.84875,-242.63835 832.0521,-242.38897 830.875,-242.0625 C 829.60251,-241.7096 829.17795,-241.95541 825.53125,-240.875 C 822.10657,-239.86037 816.88185,-237.94183 815.65625,-237.03125 C 814.11747,-237.01851 811.93645,-236.75903 810.03125,-236.15625 C 807.10027,-235.22891 805.2809,-234.69783 803.4375,-234.09375 C 802.81071,-233.88837 802.44585,-233.70117 802.15625,-233.5625 C 801.74867,-233.34889 801.50295,-233.15375 800.84375,-232.9375 C 799.58925,-232.52596 799.1576,-232.74846 795.5625,-231.5 C 792.17261,-230.32283 786.96755,-228.2863 785.78125,-227.34375 C 784.25737,-227.28408 782.1312,-226.94888 780.25,-226.28125 C 777.35261,-225.25296 775.55095,-224.60577 773.71875,-223.96875 C 771.88655,-223.33174 772.0909,-223.12021 770.9375,-222.71875 C 769.69071,-222.28479 769.27395,-222.51903 765.71875,-221.15625 C 762.38005,-219.87645 757.23165,-217.6737 756.03125,-216.6875 C 754.52407,-216.57981 752.39555,-216.1887 750.53125,-215.46875 C 747.66307,-214.36115 745.90735,-213.68719 744.09375,-213 C 743.47705,-212.76637 743.0973,-212.55797 742.8125,-212.40625 C 742.81251,-212.40625 742.8125,-212.37673 742.8125,-212.375 L 734.8125,-209.1875 L 736.625,-194.46875 C 736.36701,-194.52956 742.8125,-191.15625 742.8125,-191.15625 C 743.03891,-191.30093 743.26145,-191.42886 743.53125,-191.53125 C 744.61177,-191.94123 745.70285,-191.74702 749.53125,-193.21875 C 753.35977,-194.69049 754.7553,-195.22373 755.4375,-195.625 C 756.11711,-196.02478 757.04925,-196.50437 757.65625,-197.15625 C 759.48317,-197.294 761.22705,-197.64948 762.59375,-198.15625 C 765.56175,-199.25677 767.4691,-199.96244 769.375,-200.625 C 771.28081,-201.28754 771.72915,-202.03987 772.78125,-202.40625 C 773.87287,-202.78636 774.97635,-202.57163 778.84375,-203.9375 C 782.71115,-205.30336 784.1269,-205.76458 784.8125,-206.15625 C 785.51361,-206.55677 786.5133,-207.08923 787.125,-207.75 C 789.09581,-207.80466 790.94195,-208.13463 792.40625,-208.625 C 795.40777,-209.63008 797.3324,-210.24671 799.25,-210.875 C 800.78861,-211.3791 801.42415,-211.92177 802.15625,-212.3125 C 802.38647,-212.44681 802.63215,-212.56623 802.90625,-212.65625 C 804.00457,-213.01673 805.0877,-212.73762 809,-213.96875 C 812.91231,-215.19988 814.366,-215.6417 815.0625,-216 C 815.75641,-216.35697 816.6926,-216.79261 817.3125,-217.40625 C 819.17771,-217.42891 820.94835,-217.67308 822.34375,-218.09375 C 825.37415,-219.00729 827.33615,-219.52385 829.28125,-220.0625 C 831.22637,-220.60114 831.70745,-221.32702 832.78125,-221.625 C 833.89527,-221.93415 835.00125,-221.61761 838.96875,-222.65625 C 842.93625,-223.69488 844.38625,-224.08898 845.09375,-224.40625 C 845.82855,-224.73584 846.90765,-225.15997 847.53125,-225.78125 C 849.52907,-225.66525 851.3887,-225.80134 852.875,-226.15625 C 855.95311,-226.89125 857.9584,-227.25719 859.9375,-227.65625 C 861.52541,-227.97643 862.1818,-228.4468 862.9375,-228.75 C 863.17501,-228.8568 863.4044,-228.94276 863.6875,-229 C 864.82091,-229.22919 865.99215,-228.79107 870.03125,-229.5 C 874.07067,-230.20893 875.5315,-230.42709 876.25,-230.6875 C 876.96581,-230.94694 877.95435,-231.25474 878.59375,-231.78125 C 880.51795,-231.54176 882.34165,-231.55672 883.78125,-231.78125 C 886.90767,-232.26887 888.9358,-232.48192 890.9375,-232.75 C 892.93921,-233.01807 893.42625,-233.69514 894.53125,-233.84375 C 895.67767,-233.99793 896.8071,-233.54218 900.875,-234.0625 C 904.94281,-234.58282 906.43525,-234.75823 907.15625,-235 C 907.89337,-235.24714 908.95435,-235.58623 909.59375,-236.125 C 911.64375,-235.78947 913.56745,-235.72704 915.09375,-235.90625 C 918.23595,-236.27521 920.27375,-236.46561 922.28125,-236.6875 C 923.89207,-236.86552 924.5459,-237.2957 925.3125,-237.53125 C 925.55341,-237.61677 925.80655,-237.68685 926.09375,-237.71875 C 927.24345,-237.84647 928.39505,-237.3721 932.46875,-237.84375 C 936.54245,-238.3154 938.0278,-238.45435 938.75,-238.6875 C 939.46941,-238.91977 940.45025,-239.16096 941.09375,-239.65625 C 943.03005,-239.32279 944.8638,-239.25201 946.3125,-239.40625 C 949.45851,-239.7412 951.49,-239.92484 953.5,-240.125 C 955.50991,-240.32514 955.98415,-240.95139 957.09375,-241.0625 C 958.24485,-241.17778 959.39025,-240.69744 963.46875,-241.125 C 967.54725,-241.55256 969.05765,-241.68709 969.78125,-241.90625 C 970.52047,-242.13011 971.57685,-242.4195 972.21875,-242.9375 C 974.27575,-242.53883 976.2206,-242.4441 977.75,-242.59375 C 980.89871,-242.90185 982.9258,-243.067 984.9375,-243.25 C 986.55151,-243.39682 987.20055,-243.81055 987.96875,-244.03125 C 988.21005,-244.11211 988.4623,-244.16116 988.75,-244.1875 C 989.90211,-244.29295 991.0429,-243.79475 995.125,-244.1875 C 999.20711,-244.58025 1000.7139,-244.71834 1001.4375,-244.9375 C 1002.1584,-245.15583 1003.1371,-245.3852 1003.7812,-245.875 C 1005.7193,-245.52501 1007.5501,-245.42062 1009,-245.5625 C 1012.1487,-245.8706 1014.1758,-246.03575 1016.1875,-246.21875 C 1018.1991,-246.40174 1018.7017,-247.05677 1019.8125,-247.15625 C 1020.9648,-247.25948 1022.1047,-246.77142 1026.1875,-247.15625 C 1030.2704,-247.54107 1031.7762,-247.65725 1032.5,-247.875 C 1033.2393,-248.09743 1034.2956,-248.38949 1034.9375,-248.90625 C 1036.9949,-248.50448 1038.9404,-248.40292 1040.4688,-248.5625 C 1043.6153,-248.89102 1045.6458,-249.0852 1047.6562,-249.28125 C 1049.2692,-249.43854 1049.9219,-249.91273 1050.6875,-250.15625 C 1050.9282,-250.24429 1051.1507,-250.27762 1051.4375,-250.3125 C 1052.5858,-250.4522 1053.7542,-249.97259 1057.8125,-250.5625 C 1061.8708,-251.15242 1063.3743,-251.33964 1064.0938,-251.59375 C 1064.8104,-251.84691 1065.7684,-252.15182 1066.4062,-252.6875 C 1068.3259,-252.47556 1070.1262,-252.53609 1071.5625,-252.78125 C 1074.6816,-253.31365 1076.6741,-253.70986 1078.6562,-254.09375 C 1080.6383,-254.47762 1081.1305,-255.1334 1082.2188,-255.375 C 1083.3475,-255.62566 1084.489,-255.25871 1088.4688,-256.25 C 1092.4483,-257.24127 1093.8983,-257.6693 1094.5938,-258.03125 C 1095.316,-258.40725 1096.3555,-258.90183 1096.9688,-259.5625 C 1098.9317,-259.57454 1100.7625,-259.85355 1102.1875,-260.40625 C 1105.1387,-261.55085 1107.0607,-262.27567 1108.875,-263.15625 C 1110.3307,-263.86277 1111.1941,-264.85828 1111.4062,-265.15625 C 1111.6185,-265.4542 1111.5051,-265.8848 1111.5312,-265.90625 C 1111.5742,-265.94148 1111.8716,-266.00028 1112.0312,-266.34375 C 1112.8902,-268.19082 1114.3544,-271.97139 1114.4688,-272.65625 C 1114.5825,-273.33839 1114.6368,-274.00902 1114.6875,-274.40625 C 1114.7169,-274.63575 1114.5404,-275.28515 1114.5625,-275.34375 C 1114.5934,-275.42579 1114.8508,-275.59432 1114.9062,-275.84375 C 1115.1725,-277.04206 1114.9953,-278.05111 1114.7812,-279.46875 C 1114.5673,-280.88638 1113.8096,-284.08338 1113.1562,-284.9375 C 1112.4973,-285.79922 1111.9314,-285.94801 1111.4062,-285.9375 z" +- transform="translate(8.0045714e-2,-3.125e-2)" /> +- </clipPath> +- <filter +- inkscape:collect="always" +- id="filter7578" +- x="-0.08160872" +- width="1.1632174" +- y="-0.22659944" +- height="1.4531989"> +- <feGaussianBlur +- inkscape:collect="always" +- stdDeviation="2.437399" +- id="feGaussianBlur7580" /> +- </filter> +- <filter +- inkscape:collect="always" +- id="filter7594" +- x="-0.040804356" +- width="1.0816087" +- y="-0.11329972" +- height="1.2265995"> +- <feGaussianBlur +- inkscape:collect="always" +- stdDeviation="1.2186995" +- id="feGaussianBlur7596" /> +- </filter> +- <clipPath +- clipPathUnits="userSpaceOnUse" +- id="clipPath7606"> +- <path +- id="path7608" +- d="M 1049.205,-282.26672 L 1049.1152,-282.25891 C 1047.7278,-281.37446 1042.5119,-280.65171 1042.4862,-272.73547 C 1042.462,-265.31022 1057.4991,-255.64401 1059.6425,-254.64172 C 1061.3727,-253.83263 1063.2341,-253.23296 1065.0488,-252.92297 L 1066.4862,-252.70422 C 1068.4059,-252.49228 1070.2062,-252.55281 1071.6425,-252.79797 C 1074.7616,-253.33037 1076.7541,-253.72658 1078.7362,-254.11047 C 1080.7183,-254.49434 1081.2105,-255.15012 1082.2988,-255.39172 C 1083.4275,-255.64238 1084.569,-255.27543 1088.5488,-256.26672 C 1092.5283,-257.258 1093.9782,-257.68602 1094.6738,-258.04797 C 1095.396,-258.42398 1096.4355,-258.91855 1097.0488,-259.57922 C 1099.0117,-259.59127 1100.8425,-259.87027 1102.2675,-260.42297 C 1105.2187,-261.56758 1107.1407,-262.29239 1108.955,-263.17297 C 1110.4107,-263.8795 1111.2741,-264.875 1111.4862,-265.17297 C 1111.6985,-265.47093 1111.5852,-265.90152 1111.6112,-265.92297 C 1111.6542,-265.95821 1111.9517,-266.017 1112.1112,-266.36047 C 1112.9702,-268.20755 1114.4344,-271.98811 1114.5488,-272.67297 C 1114.6625,-273.35512 1114.7168,-274.02574 1114.7675,-274.42297 C 1114.7969,-274.65248 1114.6204,-275.30187 1114.6425,-275.36047 C 1114.6734,-275.44252 1114.9308,-275.61104 1114.9862,-275.86047 C 1115.2525,-277.05879 1115.0754,-278.06783 1114.8612,-279.48547 C 1114.6473,-280.90311 1113.8896,-284.1001 1113.2362,-284.95422 C 1112.8168,-285.50279 1112.4369,-285.74672 1112.08,-285.86047 C 1112.0129,-285.87776 1111.9561,-285.90721 1111.8925,-285.92297 C 1111.8715,-285.92695 1111.8508,-285.91983 1111.83,-285.92297 C 1111.5184,-285.99847 1111.2215,-286.08164 1110.6738,-286.14172 C 1109.6883,-286.24984 1108.2491,-286.40112 1106.705,-286.39172 C 1106.1903,-286.38859 1105.6679,-286.34408 1105.1425,-286.29797 C 1101.5836,-285.98569 1096.1327,-285.30689 1094.9238,-284.67297 C 1093.2907,-285.00699 1090.9756,-285.2852 1088.9862,-285.14172 C 1085.9222,-284.92075 1084.0185,-284.79953 1082.08,-284.67297 C 1080.1416,-284.54642 1080.3939,-284.28433 1079.1738,-284.20422 C 1077.8547,-284.11762 1077.3869,-284.42747 1073.6112,-284.11047 C 1070.0655,-283.81275 1064.6306,-283.1173 1063.3925,-282.48547 C 1061.7591,-282.81998 1059.4466,-283.09786 1057.455,-282.95422 C 1054.3908,-282.73324 1052.4872,-282.58078 1050.5488,-282.45422 C 1049.8896,-282.41119 1049.5064,-282.33029 1049.205,-282.26672 z" +- style="opacity:0.82448976;fill:#bcb786;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;display:inline;enable-background:new" /> +- </clipPath> +- <filter +- inkscape:collect="always" +- id="filter7610" +- x="-0.021942979" +- width="1.0438859" +- y="-0.10017137" +- height="1.2003427"> +- <feGaussianBlur +- inkscape:collect="always" +- stdDeviation="0.57530213" +- id="feGaussianBlur7612" /> +- </filter> +- <clipPath +- clipPathUnits="userSpaceOnUse" +- id="clipPath7616"> +- <path +- id="path7618" +- d="M 205.47016,-408.97318 L 205.38003,-408.97164 C 203.9344,-408.18598 198.68082,-407.82829 198.10378,-399.93307 C 197.56244,-392.52754 211.88973,-381.83741 213.95811,-380.68826 C 215.62775,-379.76062 217.44286,-379.03275 219.23156,-378.59711 L 220.65023,-378.27877 C 222.5505,-377.93363 224.35065,-377.86862 225.80054,-378.01314 C 228.94914,-378.32698 230.9644,-378.58345 232.96843,-378.82834 C 234.97245,-379.07322 235.50913,-379.69312 236.61162,-379.85833 C 237.75504,-380.02976 238.86821,-379.58419 242.90739,-380.29586 C 246.94627,-381.00755 248.42246,-381.33354 249.14158,-381.64616 C 249.88822,-381.97095 250.95964,-382.39191 251.61747,-383.00826 C 253.57644,-382.88355 255.42223,-383.03435 256.88227,-383.48645 C 259.90603,-384.42272 261.87384,-385.01189 263.74507,-385.76396 C 265.24645,-386.36738 266.17709,-387.30032 266.40943,-387.58279 C 266.64197,-387.86524 266.55894,-388.30268 266.58637,-388.32227 C 266.63172,-388.35443 266.93259,-388.39235 267.11563,-388.72388 C 268.1012,-390.50664 269.82518,-394.17603 269.987,-394.85126 C 270.14794,-395.52383 270.24882,-396.18904 270.32707,-396.58177 C 270.37238,-396.80868 270.24154,-397.46878 270.26767,-397.5257 C 270.30421,-397.6054 270.57272,-397.75558 270.64536,-398.00055 C 270.99449,-399.17741 270.8881,-400.19633 270.77316,-401.62545 C 270.65853,-403.05454 270.12535,-406.29655 269.53303,-407.1941 C 269.15286,-407.77056 268.79088,-408.04035 268.44277,-408.17869 C 268.37703,-408.20061 268.32242,-408.23394 268.26007,-408.2541 C 268.2394,-408.25953 268.21826,-408.25387 268.19773,-408.25845 C 267.89214,-408.35547 267.60176,-408.45912 267.05957,-408.5572 C 266.084,-408.7337 264.65883,-408.98486 263.11782,-409.08304 C 262.60416,-409.11577 262.07992,-409.10775 261.55259,-409.09835 C 257.98058,-409.03472 252.49564,-408.73725 251.24552,-408.18907 C 249.63965,-408.63604 247.34955,-409.07483 245.35499,-409.07027 C 242.28304,-409.06325 240.37552,-409.07493 238.43292,-409.0837 C 236.49041,-409.09248 236.72384,-408.81345 235.50112,-408.81852 C 234.1792,-408.82401 233.73411,-409.16569 229.9455,-409.11245 C 226.38768,-409.06243 220.91754,-408.74723 219.63844,-408.20318 C 218.0323,-408.65065 215.74477,-409.08893 213.74801,-409.08436 C 210.67586,-409.07735 208.76626,-409.05786 206.82375,-409.06662 C 206.16316,-409.06961 205.77525,-409.0156 205.47016,-408.97318 z" +- style="opacity:0.82448976;fill:#bcb786;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;display:inline;enable-background:new" /> +- </clipPath> +- <linearGradient +- inkscape:collect="always" +- xlink:href="#linearGradient7622" +- id="linearGradient7708" +- gradientUnits="userSpaceOnUse" +- gradientTransform="translate(-19.091883,4.2426407)" +- x1="774.97668" +- y1="-211.87105" +- x2="755.11584" +- y2="-202.67865" /> +- <mask +- maskUnits="userSpaceOnUse" +- id="mask7704"> +- <path +- style="fill:url(#linearGradient7708);fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1" +- d="M 718.40812,-224.31217 L 751.65812,-168.31217 L 1027.6581,-192.31217 L 1187.1581,-240.56217 L 1120.6581,-323.31217 L 718.40812,-224.31217 z" +- id="path7706" /> +- </mask> +- <radialGradient +- inkscape:collect="always" +- xlink:href="#linearGradient8430" +- id="radialGradient7904" +- gradientUnits="userSpaceOnUse" +- gradientTransform="matrix(-0.3324832,0.9022288,-0.9582407,-0.3531242,305.29227,19.909497)" +- cx="142.95833" +- cy="107.09234" +- fx="142.95833" +- fy="107.09234" +- r="66.981766" /> +- <radialGradient +- inkscape:collect="always" +- xlink:href="#linearGradient3317" +- id="radialGradient7906" +- gradientUnits="userSpaceOnUse" +- gradientTransform="matrix(1.0036478,-1.0345492e-7,1.7124628e-7,1.6613125,-160.53487,-96.205369)" +- cx="317.78754" +- cy="129.65378" +- fx="317.78754" +- fy="129.65378" +- r="47.863216" /> +- <radialGradient +- inkscape:collect="always" +- xlink:href="#linearGradient8398" +- id="radialGradient7908" +- gradientUnits="userSpaceOnUse" +- gradientTransform="matrix(2.0747661,-0.1577957,0.2382425,3.1325183,-550.77432,-65.728909)" +- cx="325.30847" +- cy="80.909554" +- fx="325.30847" +- fy="80.909554" +- r="26.937988" /> +- <clipPath +- clipPathUnits="userSpaceOnUse" +- id="clipPath8209"> +- <path +- sodipodi:nodetypes="czcc" +- id="path8211" +- d="M 734.03125,519.49186 C 734.03125,519.49186 750.78638,556.50992 762.73266,573.44581 C 774.67895,590.3817 815.45982,629.49186 815.45982,629.49186 L 816.05699,490.90211" +- style="opacity:1;fill:#1a1a1a;fill-opacity:1;fill-rule:evenodd;stroke:#000000;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;marker:none;marker-start:none;marker-mid:none;marker-end:none;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" /> +- </clipPath> +- <filter +- inkscape:collect="always" +- id="filter8225"> +- <feGaussianBlur +- inkscape:collect="always" +- stdDeviation="10.661912" +- id="feGaussianBlur8227" /> +- </filter> +- <filter +- inkscape:collect="always" +- id="filter8333"> +- <feGaussianBlur +- inkscape:collect="always" +- stdDeviation="7.18" +- id="feGaussianBlur8335" /> +- </filter> +- <clipPath +- clipPathUnits="userSpaceOnUse" +- id="clipPath8338"> +- <path +- sodipodi:nodetypes="czzzzzzcccccccccczczz" +- id="path8340" +- d="M 266.27183,924.57185 C 264.86456,943.37307 265.12693,957.32289 268.35357,973.87513 C 271.58023,990.42751 284.75966,1019.7825 288.68798,1037.0589 C 292.61419,1054.326 291.38211,1075.3686 276.22854,1088.2071 C 260.91093,1101.1846 234.17727,1109.8061 208.39624,1103.9409 C 182.61518,1098.0756 138.84716,1054.7175 119.80605,1033.7126 C 100.6939,1012.6293 56.045182,939.86193 41.867507,909.4368 C 27.689835,879.01168 29.207902,872.71823 33.747792,863.90708 C 24.38107,839.38658 21.33408,813.84026 0.035334479,788.33044 C 30.360814,791.44487 43.915624,815.28676 60.161024,835.47019 C 54.631128,787.39416 42.106309,771.05368 31.787072,744.74589 C 61.781367,750.82754 82.366432,776.61828 95.766855,817.45839 C 105.32101,813.54047 114.00462,808.08545 125.95427,808.39719 C 114.65677,766.70139 108.0048,738.48134 89.267014,707.32725 C 142.70898,712.99757 172.92404,787.96657 168.23844,795.28805 C 178.21641,793.04406 187.24409,788.75767 198.67497,789.63638 C 187.426,751.28935 177.62715,712.76848 195.01526,670.98819 C 195.01526,670.98819 243.30204,736.42507 249.40491,756.79397 C 255.50779,777.16287 250.92373,795.49448 250.92373,795.49448 C 250.92373,795.49448 267.8833,826.57978 271.21765,846.58862 C 274.59075,866.82996 267.68496,905.69193 266.27183,924.57185 z" +- style="opacity:1;fill:#ada469;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;display:inline;enable-background:new" /> +- </clipPath> +- <filter +- inkscape:collect="always" +- id="filter8354"> +- <feGaussianBlur +- inkscape:collect="always" +- stdDeviation="6.82" +- id="feGaussianBlur8356" /> +- </filter> +- <clipPath +- clipPathUnits="userSpaceOnUse" +- id="clipPath8359"> +- <path +- sodipodi:nodetypes="czzzzzzcccccccccczczz" +- id="path8361" +- d="M 266.27183,924.57185 C 264.86456,943.37307 265.12693,957.32289 268.35357,973.87513 C 271.58023,990.42751 284.75966,1019.7825 288.68798,1037.0589 C 292.61419,1054.326 291.38211,1075.3686 276.22854,1088.2071 C 260.91093,1101.1846 234.17727,1109.8061 208.39624,1103.9409 C 182.61518,1098.0756 138.84716,1054.7175 119.80605,1033.7126 C 100.6939,1012.6293 56.045182,939.86193 41.867507,909.4368 C 27.689835,879.01168 29.207902,872.71823 33.747792,863.90708 C 24.38107,839.38658 21.33408,813.84026 0.035334479,788.33044 C 30.360814,791.44487 43.915624,815.28676 60.161024,835.47019 C 54.631128,787.39416 42.106309,771.05368 31.787072,744.74589 C 61.781367,750.82754 82.366432,776.61828 95.766855,817.45839 C 105.32101,813.54047 114.00462,808.08545 125.95427,808.39719 C 114.65677,766.70139 108.0048,738.48134 89.267014,707.32725 C 142.70898,712.99757 172.92404,787.96657 168.23844,795.28805 C 178.21641,793.04406 187.24409,788.75767 198.67497,789.63638 C 187.426,751.28935 177.62715,712.76848 195.01526,670.98819 C 195.01526,670.98819 243.30204,736.42507 249.40491,756.79397 C 255.50779,777.16287 250.92373,795.49448 250.92373,795.49448 C 250.92373,795.49448 267.8833,826.57978 271.21765,846.58862 C 274.59075,866.82996 267.68496,905.69193 266.27183,924.57185 z" +- style="opacity:1;fill:#ada469;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;display:inline;enable-background:new" /> +- </clipPath> +- <filter +- inkscape:collect="always" +- id="filter8379" +- x="-0.14413793" +- width="1.288276" +- y="-0.10278689" +- height="1.2055738"> +- <feGaussianBlur +- inkscape:collect="always" +- stdDeviation="7.389266" +- id="feGaussianBlur8381" /> +- </filter> +- <clipPath +- clipPathUnits="userSpaceOnUse" +- id="clipPath8392"> +- <path +- sodipodi:nodetypes="czzzzzzcccccccccczczz" +- id="path8394" +- d="M 760.16396,935.83377 C 766.95806,954.73656 770.65765,969.13346 772.05426,987.04566 C 773.45088,1004.958 768.27158,1038.8465 769.1538,1057.7018 C 770.03555,1076.547 777.28749,1097.8008 796.49843,1106.6707 C 815.9173,1115.6365 845.81767,1116.882 870.61827,1103.5251 C 895.41887,1090.1681 928.01929,1033.1996 941.59253,1006.2164 C 955.21638,979.13246 980.3536,891.71903 986.25333,856.44781 C 992.15306,821.1766 988.80387,815.14704 981.63585,807.39232 C 984.27615,779.55217 980.13613,752.45689 994.74554,720.20614 C 964.49653,732.03184 957.36325,760.36684 946.42665,785.71122 C 938.42574,734.77829 946.63581,714.43803 949.74554,684.49186 C 920.68078,699.26977 906.88403,731.60588 904.74554,777.349 C 893.82159,776.0448 883.3541,772.91477 871.17411,776.63471 C 870.91007,730.61137 869.71055,699.7453 880.08474,662.42822 C 826.82927,683.45508 817.13746,769.02232 824.03125,775.20614 C 813.14843,775.74114 802.66017,773.90884 791.17411,778.06329 C 791.81303,735.49194 790.91365,693.15468 761.17411,655.20614 C 761.17411,655.20614 730.21605,736.12848 729.74554,758.77757 C 729.27503,781.42666 739.19713,798.94345 739.19713,798.94345 C 739.19713,798.94345 730.62906,835.68396 732.89854,857.17568 C 735.19439,878.91714 753.34144,916.85185 760.16396,935.83377 z" +- style="opacity:1;fill:#ada469;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;display:inline;enable-background:new" /> +- </clipPath> +- <filter +- inkscape:collect="always" +- id="filter8404" +- x="-0.090268657" +- width="1.1805373" +- y="-0.10250848" +- height="1.205017"> +- <feGaussianBlur +- inkscape:collect="always" +- stdDeviation="5.3457272" +- id="feGaussianBlur8406" /> +- </filter> +- <clipPath +- clipPathUnits="userSpaceOnUse" +- id="clipPath8417"> +- <path +- sodipodi:nodetypes="czzzzzzcccccccccczczz" +- id="path8419" +- d="M 760.16396,935.83377 C 766.95806,954.73656 770.65765,969.13346 772.05426,987.04566 C 773.45088,1004.958 768.27158,1038.8465 769.1538,1057.7018 C 770.03555,1076.547 777.28749,1097.8008 796.49843,1106.6707 C 815.9173,1115.6365 845.81767,1116.882 870.61827,1103.5251 C 895.41887,1090.1681 928.01929,1033.1996 941.59253,1006.2164 C 955.21638,979.13246 980.3536,891.71903 986.25333,856.44781 C 992.15306,821.1766 988.80387,815.14704 981.63585,807.39232 C 984.27615,779.55217 980.13613,752.45689 994.74554,720.20614 C 964.49653,732.03184 957.36325,760.36684 946.42665,785.71122 C 938.42574,734.77829 946.63581,714.43803 949.74554,684.49186 C 920.68078,699.26977 906.88403,731.60588 904.74554,777.349 C 893.82159,776.0448 883.3541,772.91477 871.17411,776.63471 C 870.91007,730.61137 869.71055,699.7453 880.08474,662.42822 C 826.82927,683.45508 817.13746,769.02232 824.03125,775.20614 C 813.14843,775.74114 802.66017,773.90884 791.17411,778.06329 C 791.81303,735.49194 790.91365,693.15468 761.17411,655.20614 C 761.17411,655.20614 730.21605,736.12848 729.74554,758.77757 C 729.27503,781.42666 739.19713,798.94345 739.19713,798.94345 C 739.19713,798.94345 730.62906,835.68396 732.89854,857.17568 C 735.19439,878.91714 753.34144,916.85185 760.16396,935.83377 z" +- style="opacity:1;fill:#ada469;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;display:inline;enable-background:new" /> +- </clipPath> +- </defs> +- <metadata +- id="metadata7"> +- <rdf:RDF> +- <cc:Work +- rdf:about=""> +- <dc:format>image/svg+xml</dc:format> +- <dc:type +- rdf:resource="http://purl.org/dc/dcmitype/StillImage" /> +- </cc:Work> +- </rdf:RDF> +- </metadata> +- <g +- inkscape:groupmode="layer" +- id="layer1" +- inkscape:label="Shadow"> +- <path +- style="opacity:0.5;fill:#000000;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;display:inline;filter:url(#filter11361);enable-background:new" +- d="M 304.64285,526.6479 C 294.64285,527.00505 286.42857,529.50504 286.42857,529.50504 L 293.92857,535.57647 L 304.28571,539.1479 L 320.35714,539.50504 L 342.85714,534.1479 L 350.71428,535.21933 L 371.07143,533.07647 L 360.71428,539.86219 C 366.17351,538.83858 378.10757,543.4313 370.35714,545.21933 C 368.61714,545.62075 384.28571,540.57648 384.28571,540.57648 L 386.78571,535.93361 L 390.35714,526.6479 L 401.78571,526.6479 L 419.99999,522.00504 L 423.57143,517.00505 L 407.49999,518.07647 L 395.35714,520.21933 L 380.71428,515.21933 L 310.02218,531.92707 L 304.64285,526.6479 z" +- id="path10326" +- sodipodi:nodetypes="cccccccccsccccccccccc" +- transform="matrix(10.726753,0,0,10.726753,-2882.1235,-4565.4583)" +- inkscape:export-filename="/home/cheeseness/Documents/LCA09/mascot/tuz_new.png" +- inkscape:export-xdpi="142.10527" +- inkscape:export-ydpi="142.10527" /> +- </g> +- <g +- inkscape:groupmode="layer" +- id="layer20" +- inkscape:label="New Ear"> +- <g +- style="opacity:1;display:inline;enable-background:new" +- id="g7882" +- transform="matrix(0.71084,-0.1937433,0.262963,0.9648058,503.68027,136.48399)"> +- <path +- sodipodi:nodetypes="czzzzcc" +- id="path7876" +- d="M 245.12255,100.05344 C 245.12255,100.05344 197.99444,68.406519 177.9079,64.252501 C 157.86998,60.108538 139.435,60.934923 125.97426,77.859824 C 112.51352,94.784725 113.89687,139.12502 112.43872,164.82937 C 110.98057,190.53372 114.98817,235.00638 130.04332,253.49489 C 145.09848,271.98339 175.92966,267.07991 179.97027,274.90859 C 182.1831,279.19595 245.12255,100.05344 245.12255,100.05344 z" +- style="opacity:1;fill:url(#radialGradient7904);fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;marker:none;marker-start:none;marker-mid:none;marker-end:none;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" /> +- <path +- sodipodi:nodetypes="czzzzzc" +- id="path7878" +- d="M 135.37935,82.017807 C 135.37935,82.017807 161.7229,83.95659 173.01242,95.920995 C 184.42736,108.01833 186.74699,117.25251 188.30828,133.65558 C 189.87165,150.08057 187.45871,162.0737 180.49446,169.69292 C 173.53021,177.31214 179.49017,189.27624 154.57841,181.76399 C 129.66665,174.25174 127.54617,153.98101 128.06318,135.45924 C 128.58039,116.93026 135.37935,82.017807 135.37935,82.017807 z" +- style="opacity:1;fill:url(#radialGradient7906);fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;marker:none;marker-start:none;marker-mid:none;marker-end:none;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" /> +- <path +- sodipodi:nodetypes="czccssc" +- id="path7880" +- d="M 135.648,81.927211 C 135.648,81.927211 131.00335,98.292286 136.23625,110.49031 C 141.72419,123.28285 163.4605,154.75038 163.4605,165.14596 L 186.11675,160.14596 C 188.65893,153.17952 189.32727,144.3939 188.30425,133.64596 C 186.74296,117.24289 184.43795,108.02455 173.023,95.927211 C 163.36812,85.695164 141.42989,82.552354 135.648,81.927211 z" +- style="opacity:1;fill:url(#radialGradient7908);fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;display:inline;enable-background:new" /> +- </g> +- </g> +- <g +- inkscape:groupmode="layer" +- id="layer21" +- inkscape:label="Rendered2" +- style="display:inline"> +- <path +- style="opacity:1;fill:#000000;fill-opacity:1;fill-rule:evenodd;stroke:#000000;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;marker:none;marker-start:none;marker-mid:none;marker-end:none;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" +- d="M 845.03125,1154.7776 C 840.74554,1155.4919 817.4031,1158.3957 787.17411,1164.7776 C 756.94512,1171.1595 729.86016,1169.7437 651.38803,1182.1072 C 571.53625,1194.688 557.32367,1224.6495 543.26578,1229.1715 C 528.56564,1233.9001 397.88839,1163.349 397.88839,1163.349 L 402.17411,1069.0633 C 402.17411,1069.0633 488.05962,1052.8624 514.31696,1035.4919 C 540.57431,1018.1214 559.89934,985.82588 573.60268,964.06329 C 587.30602,942.3007 606.45982,892.63471 606.45982,892.63471 L 845.03125,1154.7776 z" +- id="path7917" +- sodipodi:nodetypes="czzzcczzcc" /> +- <path +- style="opacity:0.5;fill:#ffffff;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;marker:none;marker-start:none;marker-mid:none;marker-end:none;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;visibility:visible;display:inline;overflow:visible;filter:url(#filter8888);enable-background:accumulate" +- d="M 332.34019,898.38549 L 299.60838,837.08593 L 261.99104,882.19239 C 264.16779,883.5095 267.76529,861.33636 307.59144,817.77531 L 332.34019,898.38549 z" +- id="path7919" +- clip-path="url(#clipPath8658)" +- sodipodi:nodetypes="ccccc" +- transform="translate(276,136)" /> +- <path +- style="opacity:1;fill:url(#linearGradient2841);fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;marker:none;marker-start:none;marker-mid:none;marker-end:none;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;visibility:visible;display:inline;overflow:visible;filter:url(#filter8892);enable-background:accumulate" +- d="M 200.81833,863.03015 L 347.18943,811.41136 L 591.14127,1037.6855 L 349.31075,1177.6927 L 168.29141,1090.0114 L 200.81833,863.03015 z" +- id="path7923" +- clip-path="url(#clipPath2833)" +- sodipodi:nodetypes="cccccc" +- transform="translate(276,136)" /> +- <path +- style="opacity:1;fill:#0f0f0f;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;marker:none;marker-start:none;marker-mid:none;marker-end:none;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" +- d="M 642.88839,640.13471 C 642.88839,640.13471 613.33433,680.70776 595.03125,714.42042 C 576.72816,748.13309 536.41016,840.77736 524.67411,885.49185 C 512.91471,930.29529 462.17411,1009.0633 462.17411,1009.0633 L 538.24554,1027.2776 C 538.24554,1027.2776 550.05266,1014.4542 569.31696,981.20614 C 588.58126,947.95806 629.67411,842.63471 629.67411,842.63471 L 642.88839,640.13471 z" +- id="path7921" +- sodipodi:nodetypes="czzcczcc" /> +- <path +- style="opacity:0.4;fill:#ffffff;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;marker:none;marker-start:none;marker-mid:none;marker-end:none;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;visibility:visible;display:inline;overflow:visible;filter:url(#filter8856);enable-background:accumulate" +- d="M 430.28131,381.94122 C 423.21025,384.76965 194.10007,414.09303 194.10007,414.09303 L 154.46046,773.92607 L 244.65895,866.56568 L 296.98485,752.01438 L 397.45289,565.62246 L 430.28131,381.94122 z" +- id="path7925" +- sodipodi:nodetypes="ccccccc" +- clip-path="url(#clipPath3665)" +- transform="translate(276,136)" /> +- <path +- style="opacity:1;fill:#000000;fill-opacity:1;fill-rule:evenodd;stroke:#000000;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;marker:none;marker-start:none;marker-mid:none;marker-end:none;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" +- d="M 969.67051,1164.0346 C 969.67051,1164.0346 992.92679,1175.4283 1005.7383,1184.5107 C 1018.4357,1193.5122 1035.2107,1209.1598 1047.4307,1221.8712 C 1059.7362,1234.6714 1067.5434,1244.4699 1088.9634,1246.032 C 1110.3956,1247.5949 1142.2458,1237.2444 1162.2594,1221.3678 C 1182.2729,1205.4912 1207.9063,1152.135 1207.9063,1152.135 L 1080.7455,1009.0633" +- id="path7927" +- sodipodi:nodetypes="czzzzcc" /> +- <path +- style="opacity:0.75;fill:#000000;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;marker:none;marker-start:none;marker-mid:none;marker-end:none;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;visibility:visible;display:inline;overflow:visible;filter:url(#filter8860);enable-background:accumulate" +- d="M 331.34019,641.50471 L 216.17367,835.36467 L 260.2153,925.96265 L 357.79603,732.21539 L 331.34019,641.50471 z" +- id="path7929" +- clip-path="url(#clipPath8642)" +- sodipodi:nodetypes="ccccc" +- transform="translate(276,136)" /> +- <g +- style="opacity:1;display:inline;enable-background:new" +- id="g7931" +- transform="matrix(0.9934486,0.1142802,-0.1142802,0.9934486,-9.24324,588.09054)" +- inkscape:transform-center-x="-347.89063" +- inkscape:transform-center-y="-28.255779"> +- <path +- style="opacity:1;fill:#bcb786;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;display:inline;enable-background:new" +- d="M 1049.205,-282.26672 L 1049.1152,-282.25891 C 1047.7278,-281.37446 1042.5119,-280.65171 1042.4862,-272.73547 C 1042.462,-265.31022 1057.4991,-255.64401 1059.6425,-254.64172 C 1061.3727,-253.83263 1063.2341,-253.23296 1065.0488,-252.92297 L 1066.4862,-252.70422 C 1068.4059,-252.49228 1070.2062,-252.55281 1071.6425,-252.79797 C 1074.7616,-253.33037 1076.7541,-253.72658 1078.7362,-254.11047 C 1080.7183,-254.49434 1081.2105,-255.15012 1082.2988,-255.39172 C 1083.4275,-255.64238 1084.569,-255.27543 1088.5488,-256.26672 C 1092.5283,-257.258 1093.9782,-257.68602 1094.6738,-258.04797 C 1095.396,-258.42398 1096.4355,-258.91855 1097.0488,-259.57922 C 1099.0117,-259.59127 1100.8425,-259.87027 1102.2675,-260.42297 C 1105.2187,-261.56758 1107.1407,-262.29239 1108.955,-263.17297 C 1110.4107,-263.8795 1111.2741,-264.875 1111.4862,-265.17297 C 1111.6985,-265.47093 1111.5852,-265.90152 1111.6112,-265.92297 C 1111.6542,-265.95821 1111.9517,-266.017 1112.1112,-266.36047 C 1112.9702,-268.20755 1114.4344,-271.98811 1114.5488,-272.67297 C 1114.6625,-273.35512 1114.7168,-274.02574 1114.7675,-274.42297 C 1114.7969,-274.65248 1114.6204,-275.30187 1114.6425,-275.36047 C 1114.6734,-275.44252 1114.9308,-275.61104 1114.9862,-275.86047 C 1115.2525,-277.05879 1115.0754,-278.06783 1114.8612,-279.48547 C 1114.6473,-280.90311 1113.8896,-284.1001 1113.2362,-284.95422 C 1112.8168,-285.50279 1112.4369,-285.74672 1112.08,-285.86047 C 1112.0129,-285.87776 1111.9561,-285.90721 1111.8925,-285.92297 C 1111.8715,-285.92695 1111.8508,-285.91983 1111.83,-285.92297 C 1111.5184,-285.99847 1111.2215,-286.08164 1110.6738,-286.14172 C 1109.6883,-286.24984 1108.2491,-286.40112 1106.705,-286.39172 C 1106.1903,-286.38859 1105.6679,-286.34408 1105.1425,-286.29797 C 1101.5836,-285.98569 1096.1327,-285.30689 1094.9238,-284.67297 C 1093.2907,-285.00699 1090.9756,-285.2852 1088.9862,-285.14172 C 1085.9222,-284.92075 1084.0185,-284.79953 1082.08,-284.67297 C 1080.1416,-284.54642 1080.3939,-284.28433 1079.1738,-284.20422 C 1077.8547,-284.11762 1077.3869,-284.42747 1073.6112,-284.11047 C 1070.0655,-283.81275 1064.6306,-283.1173 1063.3925,-282.48547 C 1061.7591,-282.81998 1059.4466,-283.09786 1057.455,-282.95422 C 1054.3908,-282.73324 1052.4872,-282.58078 1050.5488,-282.45422 C 1049.8896,-282.41119 1049.5064,-282.33029 1049.205,-282.26672 z" +- id="path7933" /> +- <g +- clip-path="url(#clipPath7616)" +- style="display:inline;filter:url(#filter7610);enable-background:new" +- id="g7935" +- transform="matrix(0.9975712,-6.9654277e-2,6.9654277e-2,0.9975712,872.72062,140.02502)"> +- <path +- sodipodi:nodetypes="ccssscsssscscsscsssccscssccsscssscc" +- id="path7937" +- d="M 229.94262,-409.12268 C 226.38481,-409.07267 220.91842,-408.76259 219.63928,-408.21854 C 218.03319,-408.66601 215.73612,-409.09985 213.73933,-409.09528 C 210.66734,-409.08826 208.77464,-409.08651 206.83206,-409.09528 C 206.17159,-409.09827 205.78447,-409.02811 205.47939,-408.98569 C 205.47939,-408.98569 205.47939,-407.88976 205.47939,-407.88976 C 205.59911,-408.06923 205.87191,-408.58022 206.42914,-408.65691 C 207.17672,-408.7598 211.59842,-408.80814 213.73933,-408.76651 C 215.51393,-408.73198 218.19456,-408.49224 220.12854,-407.80756 C 220.44994,-407.69378 220.74779,-407.53378 221.02073,-407.39659 C 222.98415,-406.40966 228.96409,-403.09505 228.96409,-403.09505 C 228.96409,-403.09505 222.33134,-407.04273 221.48122,-407.53358 C 221.27791,-407.65097 220.90658,-407.79127 220.44513,-407.94456 C 221.66576,-408.39235 225.5211,-408.56427 228.27336,-408.65691 C 231.29786,-408.75873 231.62112,-408.7465 233.68405,-408.46512 C 235.81336,-408.17469 237.02256,-407.86236 237.02256,-407.86236 C 237.02255,-407.86236 236.9442,-408.50354 238.05865,-408.65691 C 238.80622,-408.7598 243.22794,-408.80814 245.36884,-408.76651 C 247.43834,-408.72625 250.73489,-408.35935 252.65024,-407.39659 C 253.65356,-406.89226 255.68588,-405.82796 257.44559,-404.86088 L 257.5412,-404.88031 C 257.5412,-404.88031 253.96086,-407.04273 253.11073,-407.53358 C 252.90742,-407.65097 252.5361,-407.79127 252.07464,-407.94456 C 253.29526,-408.39235 257.12183,-408.56427 259.87409,-408.65691 C 262.89859,-408.75873 263.22184,-408.7465 265.28478,-408.46512 C 267.23794,-408.19872 268.2977,-407.93506 268.47939,-407.88976 C 268.47939,-407.88976 268.4523,-408.20122 268.4523,-408.20122 C 268.04327,-408.33767 267.73806,-408.43457 267.05192,-408.5587 C 265.75111,-408.79403 263.6528,-409.16026 261.54335,-409.12268 C 257.9714,-409.05904 252.49007,-408.76672 251.24001,-408.21854 C 249.63418,-408.66549 247.36339,-409.09984 245.36884,-409.09528 C 242.29685,-409.08826 240.37536,-409.08651 238.43279,-409.09528 C 236.49023,-409.10406 236.72011,-408.81621 235.49721,-408.8213 C 234.1753,-408.8268 233.73109,-409.17593 229.94262,-409.12268 C 229.94262,-409.12268 229.94262,-409.12268 229.94262,-409.12268" +- style="fill:#000000;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;display:inline;enable-background:new" /> +- <path +- id="path7939" +- d="M 206.1989,-407.47878 C 208.11911,-406.66172 210.77605,-405.28595 212.35787,-404.08139 C 213.93971,-402.87683 215.26544,-402.30771 217.91246,-400.16344 C 218.79803,-399.44606 219.66111,-398.81359 220.50439,-398.2417 L 221.04496,-398.43181 C 220.33173,-398.9152 219.5772,-399.45212 218.77587,-400.05384 C 215.95364,-402.17305 215.14932,-402.86357 212.7608,-404.32798 C 210.37226,-405.79238 208.66132,-406.69374 206.1989,-407.47878 C 206.1989,-407.47878 206.1989,-407.47878 206.1989,-407.47878" +- style="fill:#000000;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;display:inline;enable-background:new" +- sodipodi:nodetypes="cssccsscc" /> +- <path +- id="path7941" +- d="M 237.79963,-407.47878 C 239.71984,-406.66172 242.40557,-405.28595 243.98738,-404.08139 C 244.80045,-403.46223 245.54587,-403.01097 246.43784,-402.42738 L 247.08684,-402.54404 C 246.28853,-403.12041 245.51507,-403.63839 244.39031,-404.32798 C 242.00177,-405.79238 240.26205,-406.69374 237.79963,-407.47878 C 237.79963,-407.47878 237.79963,-407.47878 237.79963,-407.47878" +- style="fill:#000000;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;display:inline;enable-background:new" +- sodipodi:nodetypes="csccscc" /> +- </g> +- <g +- clip-path="url(#clipPath7606)" +- id="g7943"> +- <path +- style="opacity:0.75;fill:#000000;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;display:inline;filter:url(#filter7578);enable-background:new" +- d="M 1056.25,-278.80481 C 1060.3946,-280.28358 1066.25,-275.67981 1066.25,-275.67981 C 1067.149,-275.39889 1068.9751,-276.57428 1068.8743,-277.36595 C 1068.8743,-277.36595 1067.324,-279.22657 1068.5,-280.30481 C 1069.676,-281.38305 1073.796,-278.79743 1076,-278.67981 C 1078.204,-278.56219 1081.5621,-278.90922 1083,-279.42981 C 1084.4379,-279.9504 1084.1129,-280.8544 1085.625,-281.17981 C 1087.1371,-281.50522 1090.7439,-280.14227 1092.6855,-280.01098 C 1094.6271,-279.87969 1097.3336,-279.67671 1098.5,-280.17981 C 1099.6664,-280.68291 1098.6782,-281.33902 1100.375,-282.05481 C 1102.0718,-282.7706 1108.1352,-283.01143 1110,-282.17981 C 1111.8648,-281.34819 1111.8099,-281.66061 1112.625,-279.17981 C 1113.4401,-276.69901 1120.0648,-274.01696 1111.5,-265.80481 C 1102.9352,-257.59266 1052.1221,-252.01887 1045.875,-263.05481 C 1039.6279,-274.09075 1052.1054,-277.32604 1056.25,-278.80481 z" +- id="path7945" +- sodipodi:nodetypes="czzzzzzzzzzzzzz" /> +- <path +- style="opacity:0.75;fill:#000000;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;display:inline;filter:url(#filter7594);enable-background:new" +- d="M 1058.5,-275.42981 C 1062.6446,-276.90858 1068.5,-272.30481 1068.5,-272.30481 C 1069.399,-272.02389 1071.2251,-273.19928 1071.1243,-273.99095 C 1071.1243,-273.99095 1069.574,-275.85157 1070.75,-276.92981 C 1071.926,-278.00805 1076.046,-275.42243 1078.25,-275.30481 C 1080.454,-275.18719 1083.8121,-275.53422 1085.25,-276.05481 C 1086.6879,-276.5754 1086.3629,-277.4794 1087.875,-277.80481 C 1089.3871,-278.13022 1092.9939,-276.76727 1094.9355,-276.63598 C 1096.8771,-276.50469 1099.5836,-276.30171 1100.75,-276.80481 C 1101.9164,-277.30791 1100.9282,-277.96402 1102.625,-278.67981 C 1104.3218,-279.3956 1110.3852,-279.63643 1112.25,-278.80481 C 1114.1148,-277.97319 1114.0599,-278.28561 1114.875,-275.80481 C 1115.6901,-273.32401 1122.3148,-270.64196 1113.75,-262.42981 C 1105.1852,-254.21766 1054.3721,-248.64387 1048.125,-259.67981 C 1041.8779,-270.71575 1054.3554,-273.95104 1058.5,-275.42981 z" +- id="path7947" +- sodipodi:nodetypes="czzzzzzzzzzzzzz" /> +- </g> +- </g> +- <path +- style="opacity:1;fill:#101414;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;marker:none;marker-start:none;marker-mid:none;marker-end:none;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" +- d="M 628.24553,347.99185 C 624.4411,322.72762 611.43581,297.35383 611.08873,272.46662 C 610.90247,259.1111 614.36158,245.89571 624.84426,232.91257 C 661.19128,167.61674 741.78517,148.21789 810.77892,141.44715 C 897.70131,130.43035 995.69159,159.38722 1044.1503,236.84843 C 1098.2743,312.58173 1100.825,409.38755 1124.7623,496.37638 C 1154.2001,623.50398 1179.5414,752.59052 1185.1545,883.22673 C 1182.0911,961.40858 1176.7282,1048.4109 1124.6513,1111.3609 C 1076.6248,1161.7183 1001.8649,1161.4139 937.58145,1170.3632 C 847.02606,1175.0182 753.22992,1154.2174 675.79755,1106.165 C 611.02191,1068.225 580.06736,992.68633 578.51815,920.14538 C 570.12898,840.27022 604.90967,766.33687 630.13855,692.98577 C 637.60916,610.2247 639.55141,526.73802 639.79189,443.60093 C 638.95507,411.40549 632.70236,379.7836 628.24553,347.99185 z" +- id="path7949" +- sodipodi:nodetypes="cscccccccccccc" /> +- <path +- style="opacity:0.25;fill:#ffffff;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;marker:none;marker-start:none;marker-mid:none;marker-end:none;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;visibility:visible;display:inline;overflow:visible;filter:url(#filter8940);enable-background:accumulate" +- d="M 311.83409,415.43155 L 321.73359,537.05392 L 261.62951,673.52553 L 277.18586,848.1809 C 292.79912,910.0601 309.37131,946.84995 351.56201,965.23473 C 355.88112,928.99475 312.95049,822.27485 312.31937,776.11489 C 311.68792,729.93044 323.14971,667.50703 342.99704,617.81842 C 363.04539,567.62654 379.89378,572.972 385.12193,525.22549 C 390.35008,477.47898 367.69553,375.83357 367.69553,375.83357 L 311.83409,415.43155 z" +- id="path7951" +- sodipodi:nodetypes="ccccczzzcc" +- clip-path="url(#clipPath8616)" +- transform="translate(276,136)" /> +- <path +- style="opacity:1;fill:url(#linearGradient8970);fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;marker:none;marker-start:none;marker-mid:none;marker-end:none;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" +- d="M 1010.0312,655.49186 C 1010.0312,655.49186 1026.7864,692.50992 1038.7327,709.44581 C 1050.6789,726.3817 1091.4598,765.49186 1091.4598,765.49186 L 1144.057,637.90211" +- id="path7953" +- sodipodi:nodetypes="czcc" /> +- <path +- style="opacity:0.07999998;fill:#ffffff;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;marker:none;marker-start:none;marker-mid:none;marker-end:none;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;visibility:visible;display:inline;overflow:visible;filter:url(#filter8822);enable-background:accumulate" +- d="M 730.31998,536.56864 C 730.31998,545.05392 772.86772,595.03667 772.86772,595.03667 L 785.47431,566.26713 L 730.31998,536.56864 z" +- id="path7955" +- sodipodi:nodetypes="cccc" +- clip-path="url(#clipPath8209)" +- transform="translate(276,136)" /> +- <g +- transform="translate(450.03125,73.843964)" +- style="opacity:1;display:inline;enable-background:new" +- id="g7957" +- clip-path="url(#clipPath3998)"> +- <g +- transform="translate(-174.03125,62.156036)" +- style="filter:url(#filter3677)" +- id="g7959"> +- <g +- id="g7961" +- style="filter:url(#filter3785)"> +- <path +- sodipodi:nodetypes="czzzzzzzzzz" +- id="path7963" +- d="M 425.88244,476.99186 C 436.68787,475.5132 450.62645,480.34637 470.5253,480.20614 C 490.42415,480.06591 527.97852,463.29492 552.66815,463.06328 C 577.35778,462.83164 615.41985,475.34734 631.95387,478.06328 C 648.48789,480.77922 654.80219,477.90476 659.45386,485.92043 C 664.10553,493.9361 661.38057,496.66767 649.09672,506.63472 C 636.81287,516.60177 608.30704,519.27104 583.02529,519.49186 C 557.74295,519.71268 512.644,526.57038 487.66815,523.42042 C 462.6923,520.27046 430.73059,515.59775 418.73958,505.56328 C 406.74857,495.52881 398.88874,488.83146 401.23958,481.63471 C 403.59042,474.43796 415.07701,478.47052 425.88244,476.99186 z" +- style="opacity:1;fill:#ffffff;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;display:inline;enable-background:new" /> +- <rect +- y="412.60312" +- x="343.6539" +- height="181.01935" +- width="381.83765" +- id="rect7965" +- style="opacity:1;fill:none;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;marker:none;marker-start:none;marker-mid:none;marker-end:none;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" /> +- </g> +- <g +- id="g7967" +- style="filter:url(#filter3785)"> +- <path +- sodipodi:nodetypes="czzzcc" +- id="path7969" +- d="M 687.14286,452.36218 C 676.68117,462.07661 600.16326,471.36732 586.42857,481.6479 C 572.69388,491.92848 571.67605,494.53616 574.28571,501.6479 C 576.89537,508.75964 580.83098,511.05362 600,510.21932 C 619.16902,509.38502 698.57143,482.5976 698.57143,488.79075 L 687.14286,452.36218 z" +- style="opacity:1;fill:#ffffff;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;display:inline;enable-background:new" +- transform="translate(174.03125,-62.156036)" /> +- <rect +- y="344.82138" +- x="702.86414" +- height="162.63455" +- width="207.8894" +- id="rect7971" +- style="opacity:1;fill:none;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;marker:none;marker-start:none;marker-mid:none;marker-end:none;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" /> +- </g> +- </g> +- <g +- transform="translate(-174.03125,62.156036)" +- style="opacity:0.18000004;display:inline;enable-background:new" +- id="g7973"> +- <g +- id="g7975" +- style="filter:url(#filter3785)"> +- <path +- sodipodi:nodetypes="czzzzzzzzzz" +- id="path7977" +- d="M 425.88244,476.99186 C 436.68787,475.5132 450.62645,480.34637 470.5253,480.20614 C 490.42415,480.06591 527.97852,463.29492 552.66815,463.06328 C 577.35778,462.83164 615.41985,475.34734 631.95387,478.06328 C 648.48789,480.77922 654.80219,477.90476 659.45386,485.92043 C 664.10553,493.9361 661.38057,496.66767 649.09672,506.63472 C 636.81287,516.60177 608.30704,519.27104 583.02529,519.49186 C 557.74295,519.71268 512.644,526.57038 487.66815,523.42042 C 462.6923,520.27046 430.73059,515.59775 418.73958,505.56328 C 406.74857,495.52881 398.88874,488.83146 401.23958,481.63471 C 403.59042,474.43796 415.07701,478.47052 425.88244,476.99186 z" +- style="opacity:1;fill:#ffffff;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;display:inline;enable-background:new" /> +- <rect +- y="412.60312" +- x="343.6539" +- height="181.01935" +- width="381.83765" +- id="rect7979" +- style="opacity:1;fill:none;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;marker:none;marker-start:none;marker-mid:none;marker-end:none;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" /> +- </g> +- <g +- id="g7981" +- style="filter:url(#filter3785)"> +- <path +- sodipodi:nodetypes="czzzcc" +- id="path7983" +- d="M 687.14286,452.36218 C 676.68117,462.07661 600.16326,471.36732 586.42857,481.6479 C 572.69388,491.92848 571.67605,494.53616 574.28571,501.6479 C 576.89537,508.75964 580.83098,511.05362 600,510.21932 C 619.16902,509.38502 698.57143,482.5976 698.57143,488.79075 L 687.14286,452.36218 z" +- style="opacity:1;fill:#ffffff;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;display:inline;enable-background:new" +- transform="translate(174.03125,-62.156036)" /> +- <rect +- y="344.82138" +- x="702.86414" +- height="162.63455" +- width="207.8894" +- id="rect7985" +- style="opacity:1;fill:none;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;marker:none;marker-start:none;marker-mid:none;marker-end:none;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" /> +- </g> +- </g> +- </g> +- <path +- style="opacity:0.75;fill:#000000;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;marker:none;marker-start:none;marker-mid:none;marker-end:none;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;visibility:visible;display:inline;overflow:visible;filter:url(#filter8802);enable-background:accumulate" +- d="M 582.65599,-7.4183011 L 695.79307,78.848726 L 804.68752,337.64981 L 842.87128,545.5392 L 963.07944,637.46308 C 963.07944,637.46308 950.35151,350.37773 943.28044,323.50767 C 936.20938,296.63761 793.37381,-69.643698 793.37381,-69.643698 L 582.65599,-7.4183011 z" +- id="path7987" +- clip-path="url(#clipPath8604)" +- sodipodi:nodetypes="cccccscc" +- transform="translate(276,136)" /> +- <path +- style="opacity:1;fill:url(#linearGradient8958);fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;marker:none;marker-start:none;marker-mid:none;marker-end:none;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" +- d="M 964.13839,239.599 C 964.13839,239.599 972.81571,250.49562 988.24554,251.56328 C 1003.6754,252.63094 1037.9672,211.61061 1058.4241,199.42043 C 1078.9034,187.2169 1105.4705,172.81818 1122.3527,179.06329 C 1139.2348,185.30839 1144.5105,205.49938 1150.2098,227.099 C 1155.9092,248.69861 1156.9284,288.91289 1147.5313,319.95615 C 1138.1341,350.9994 1097.028,393.0599 1082.1741,423.349 C 1067.3202,453.6381 1070.567,463.17043 1070.567,463.17043" +- id="path7989" +- sodipodi:nodetypes="czzzzzzc" /> +- <path +- style="opacity:1;fill:url(#radialGradient3315);fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;display:inline;enable-background:new" +- d="M 1124.4955,207.63471 C 1108.6027,206.74185 1074.7767,219.74054 1058.4241,231.92043 C 1041.9855,244.16433 1029.2032,256.03483 1029.1384,284.06328 C 1029.0732,312.26932 1042.2575,323.13969 1058.2455,331.02757 C 1074.2335,338.91546 1091.9317,338.14685 1110.2098,319.24186 C 1128.488,300.33686 1124.4955,207.63471 1124.4955,207.63471 z" +- id="path7991" +- sodipodi:nodetypes="czzzzc" /> +- <path +- sodipodi:type="arc" +- style="opacity:0.75;fill:url(#radialGradient3543);fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:bevel;marker:none;marker-start:none;marker-mid:none;marker-end:none;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;visibility:visible;display:inline;overflow:visible;filter:url(#filter4120);enable-background:accumulate" +- id="path7993" +- sodipodi:cx="385" +- sodipodi:cy="237.00504" +- sodipodi:rx="86.428574" +- sodipodi:ry="73.928574" +- d="M 471.42857,237.00504 A 86.428574,73.928574 0 1 1 298.57143,237.00504 A 86.428574,73.928574 0 1 1 471.42857,237.00504 z" +- transform="matrix(0.9434749,-0.1239943,0.1440089,1.0957669,451.94827,134.5988)" +- clip-path="url(#clipPath4100)" /> +- <path +- transform="translate(450.03125,73.843964)" +- style="opacity:1;fill:url(#radialGradient3915);fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;marker:none;marker-start:none;marker-mid:none;marker-end:none;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" +- d="M 527.60588,407.44884 C 527.60588,407.44884 405.56444,445.85232 340.09154,417.08065 C 274.61865,388.30899 265.71429,292.36218 265.71429,292.36218 C 265.71429,292.36218 339.09587,211.85825 395.63507,208.74742 C 451.46212,205.67578 486.20893,228.89074 510.50508,274.59913 C 534.85708,320.41261 527.60588,407.44884 527.60588,407.44884 z" +- id="path7995" +- sodipodi:nodetypes="csczzc" +- mask="url(#mask3684)" /> +- <path +- style="opacity:1;fill:url(#linearGradient3959);fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:bevel;marker:none;marker-start:none;marker-mid:none;marker-end:none;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" +- d="M 772.17411,393.349 C 772.17411,393.349 808.39165,365.96653 823.78125,357.45614 C 838.95859,349.06313 849.49553,345.849 859.6741,345.849 L 844.13839,412.81328" +- id="path7997" +- sodipodi:nodetypes="czcc" /> +- <path +- sodipodi:type="arc" +- style="opacity:1;fill:url(#radialGradient3933);fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:bevel;marker:none;marker-start:none;marker-mid:none;marker-end:none;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" +- id="path7999" +- sodipodi:cx="409.28571" +- sodipodi:cy="306.64789" +- sodipodi:rx="36.25" +- sodipodi:ry="36.25" +- d="M 445.53571,306.64789 A 36.25,36.25 0 1 1 373.03571,306.64789 A 36.25,36.25 0 1 1 445.53571,306.64789 z" +- transform="translate(449.49554,74.915393)" /> +- <path +- style="opacity:0.3;fill:#ffffff;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;marker:none;marker-start:none;marker-mid:none;marker-end:none;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;visibility:visible;display:inline;overflow:visible;filter:url(#filter8806);enable-background:accumulate" +- d="M 311.83409,415.43155 L 321.73359,537.05392 L 261.62951,673.52553 L 277.18586,848.1809 C 292.79912,910.0601 309.37131,946.84995 351.56201,965.23473 C 355.88112,928.99475 360.24362,892.86709 320.31937,742.11489 L 337.99704,672.81842 L 410.12193,534.22549 L 367.69553,375.83357 L 311.83409,415.43155 z" +- id="path8001" +- sodipodi:nodetypes="cccccccccc" +- clip-path="url(#clipPath8616)" +- transform="translate(276,136)" /> +- <path +- style="opacity:0.5;fill:#000000;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;marker:none;marker-start:none;marker-mid:none;marker-end:none;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;visibility:visible;display:inline;overflow:visible;filter:url(#filter8826);enable-background:accumulate" +- d="M 635.21025,581.13004 C 621.06811,593.85796 674.44372,615.71019 711.57778,605.17167 C 748.71184,594.63315 816.22265,569.6073 814.81537,525.97571 C 813.40809,482.34413 738.44784,397.28228 738.44784,397.28228 L 635.21025,581.13004 z" +- id="path8003" +- sodipodi:nodetypes="czzcc" /> +- <path +- sodipodi:type="arc" +- style="opacity:1;fill:url(#radialGradient3991);fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:bevel;marker:none;marker-start:none;marker-mid:none;marker-end:none;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" +- id="path8005" +- sodipodi:cx="410" +- sodipodi:cy="306.64789" +- sodipodi:rx="23.214285" +- sodipodi:ry="23.214285" +- d="M 433.21428,306.64789 A 23.214285,23.214285 0 1 1 386.78572,306.64789 A 23.214285,23.214285 0 1 1 433.21428,306.64789 z" +- transform="translate(449.67411,74.915393)" /> +- <path +- sodipodi:type="arc" +- style="opacity:1;fill:#ffffff;fill-opacity:1;fill-rule:evenodd;stroke:#000000;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:bevel;marker:none;marker-start:none;marker-mid:none;marker-end:none;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;visibility:visible;display:inline;overflow:visible;filter:url(#filter3981);enable-background:accumulate" +- id="path8007" +- sodipodi:cx="414.28571" +- sodipodi:cy="303.07648" +- sodipodi:rx="7.5" +- sodipodi:ry="7.5" +- d="M 421.78571,303.07648 A 7.5,7.5 0 1 1 406.78571,303.07648 A 7.5,7.5 0 1 1 421.78571,303.07648 z" +- transform="translate(451.99554,73.486821)" /> +- <path +- style="opacity:1;fill:url(#radialGradient4112);fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;marker:none;marker-start:none;marker-mid:none;marker-end:none;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" +- d="M 789.31696,478.349 C 789.31696,478.349 796.33977,497.91759 788.24553,513.349 C 780.15129,528.78041 745.92236,552.33722 720.74554,563.349 C 695.43582,574.41891 635.27254,596.31293 618.95982,605.31328 C 602.49834,614.39571 600.74554,617.99185 600.74554,617.99185 C 600.74554,617.99185 593.59861,598.92744 629.49553,566.20615 C 665.66764,533.23401 771.52265,518.15665 789.31696,478.349 z" +- id="path8009" +- sodipodi:nodetypes="czzzczc" /> +- <g +- style="opacity:1;display:inline;enable-background:new" +- id="g8011" +- transform="translate(780.74553,74.55825)"> +- <path +- transform="translate(-329.81481,0)" +- clip-path="url(#clipPath3999)" +- sodipodi:nodetypes="czzczzzszc" +- id="path8013" +- d="M 179.64286,267.36218 C 157.23242,307.0651 119.02676,383.14247 110.35715,417.00504 C 101.70994,450.78014 101.58516,483.42158 110,503.43362 C 118.3602,523.31575 136.16398,539.06642 150.71428,544.86218 C 150.1179,530.48631 165.08723,501.57635 223.57143,472.36218 C 282.1977,443.07704 301.95306,445.23132 327.14285,425.21932 C 352.77291,404.85756 335.34872,345.57268 330.35714,331.29075 C 325.36556,317.00882 329.12051,327.91101 328.41112,326.19774 C 317.72184,300.38182 294.1968,271.76744 263.92857,261.6479 C 233.66034,251.52836 198.91081,256.79953 179.64286,267.36218 z" +- style="opacity:1;fill:url(#radialGradient3585);fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:20.79999924;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1;display:inline" /> +- <path +- transform="matrix(0.8823874,0.4705236,-0.4705236,0.8823874,-166.62245,2.387362)" +- d="M 248.28731,338.07648 A 64.715881,134.00607 0 1 1 118.85555,338.07648 A 64.715881,134.00607 0 1 1 248.28731,338.07648 z" +- sodipodi:ry="134.00607" +- sodipodi:rx="64.715881" +- sodipodi:cy="338.07648" +- sodipodi:cx="183.57143" +- id="path8015" +- style="opacity:1;fill:url(#radialGradient4060);fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:20.79999924;stroke-linecap:butt;stroke-linejoin:bevel;marker:none;marker-start:none;marker-mid:none;marker-end:none;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" +- sodipodi:type="arc" /> +- <path +- transform="matrix(0.8823874,0.4705236,-0.4705236,0.8823874,-162.19388,-18.755495)" +- d="M 248.28731,338.07648 A 64.715881,134.00607 0 1 1 118.85555,338.07648 A 64.715881,134.00607 0 1 1 248.28731,338.07648 z" +- sodipodi:ry="134.00607" +- sodipodi:rx="64.715881" +- sodipodi:cy="338.07648" +- sodipodi:cx="183.57143" +- id="path8017" +- style="opacity:1;fill:url(#radialGradient4062);fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:20.79999924;stroke-linecap:butt;stroke-linejoin:bevel;marker:none;marker-start:none;marker-mid:none;marker-end:none;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" +- sodipodi:type="arc" /> +- <path +- transform="translate(-329.81481,3e-7)" +- clip-path="url(#clipPath3999)" +- sodipodi:nodetypes="czzczzzszc" +- id="path8019" +- d="M 179.64286,267.36218 C 157.23242,307.0651 119.02676,383.14247 110.35715,417.00504 C 101.70994,450.78014 101.58516,483.42158 110,503.43362 C 118.3602,523.31575 136.16398,539.06642 150.71428,544.86218 C 150.1179,530.48631 165.08723,501.57635 223.57143,472.36218 C 282.1977,443.07704 301.95306,445.23132 327.14285,425.21932 C 352.77291,404.85756 335.34872,345.57268 330.35714,331.29075 C 325.36556,317.00882 329.12051,327.91101 328.41112,326.19774 C 317.72184,300.38182 294.1968,271.76744 263.92857,261.6479 C 233.66034,251.52836 198.91081,256.79953 179.64286,267.36218 z" +- style="opacity:1;fill:none;fill-opacity:1;fill-rule:evenodd;stroke:url(#linearGradient3587);stroke-width:20.79999924;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1;display:inline;filter:url(#filter4079);enable-background:new" /> +- </g> +- <path +- sodipodi:type="arc" +- style="opacity:1;fill:#000000;fill-opacity:1;fill-rule:evenodd;stroke:#000000;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:bevel;marker:none;marker-start:none;marker-mid:none;marker-end:none;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" +- id="path8021" +- sodipodi:cx="310.71429" +- sodipodi:cy="398.07648" +- sodipodi:rx="19.704132" +- sodipodi:ry="19.704132" +- d="M 330.41843,398.07648 A 19.704132,19.704132 0 1 1 291.01016,398.07648 A 19.704132,19.704132 0 1 1 330.41843,398.07648 z" +- transform="translate(452.55663,72.581273)" /> +- <path +- sodipodi:type="arc" +- style="opacity:1;fill:url(#radialGradient4056);fill-opacity:1;fill-rule:evenodd;stroke:url(#linearGradient4082);stroke-width:20.79999924;stroke-linecap:butt;stroke-linejoin:miter;marker:none;marker-start:none;marker-mid:none;marker-end:none;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;visibility:visible;display:inline;overflow:visible;filter:url(#filter4083);enable-background:accumulate" +- id="path8023" +- sodipodi:cx="310.71429" +- sodipodi:cy="398.07648" +- sodipodi:rx="19.704132" +- sodipodi:ry="19.704132" +- d="M 330.41843,398.07648 A 19.704132,19.704132 0 1 1 291.01016,398.07648 A 19.704132,19.704132 0 1 1 330.41843,398.07648 z" +- transform="translate(450.55663,72.581273)" /> +- <path +- sodipodi:type="arc" +- style="opacity:1;fill:url(#radialGradient4119);fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:bevel;marker:none;marker-start:none;marker-mid:none;marker-end:none;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" +- id="path8025" +- sodipodi:cx="310.71429" +- sodipodi:cy="398.07648" +- sodipodi:rx="19.704132" +- sodipodi:ry="19.704132" +- d="M 330.41843,398.07648 A 19.704132,19.704132 0 1 1 291.01016,398.07648 A 19.704132,19.704132 0 1 1 330.41843,398.07648 z" +- transform="translate(450.55663,72.581273)" /> +- <path +- sodipodi:type="arc" +- style="opacity:1;fill:url(#radialGradient4868);fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:0.99999994px;stroke-linecap:butt;stroke-linejoin:bevel;marker:none;marker-start:none;marker-mid:none;marker-end:none;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;visibility:visible;display:inline;overflow:visible;filter:url(#filter4002);enable-background:accumulate" +- id="path8027" +- sodipodi:cx="429.56738" +- sodipodi:cy="377.42877" +- sodipodi:rx="72.079735" +- sodipodi:ry="44.547726" +- d="M 501.64712,377.42877 A 72.079735,44.547726 0 1 1 357.48765,377.42877 A 72.079735,44.547726 0 1 1 501.64712,377.42877 z" +- transform="matrix(0.9969564,-7.7961675e-2,7.7961675e-2,0.9969564,436.61877,125.29509)" +- inkscape:transform-center-x="-47.231976" +- inkscape:transform-center-y="-3.6935079" /> +- <path +- sodipodi:type="arc" +- style="opacity:1;fill:url(#radialGradient4876);fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:0.99999994px;stroke-linecap:butt;stroke-linejoin:bevel;marker:none;marker-start:none;marker-mid:none;marker-end:none;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;visibility:visible;display:inline;overflow:visible;filter:url(#filter4010);enable-background:accumulate" +- id="path8029" +- sodipodi:cx="437.6991" +- sodipodi:cy="391.21735" +- sodipodi:rx="36.611931" +- sodipodi:ry="22.627417" +- d="M 474.31103,391.21735 A 36.611931,22.627417 0 1 1 401.08717,391.21735 A 36.611931,22.627417 0 1 1 474.31103,391.21735 z" +- transform="matrix(1.4357951,-6.9991037e-2,6.9991037e-2,1.4357951,235.18065,-63.86546)" +- inkscape:transform-center-x="-20.955902" +- inkscape:transform-center-y="-13.056625" /> +- <g +- transform="translate(450.03125,73.843964)" +- id="g8031" +- style="opacity:1;display:inline;filter:url(#filter4053);enable-background:new"> +- <path +- d="M 416.87499,401.82648 A 3.2142856,3.2142856 0 1 1 410.44642,401.82648 A 3.2142856,3.2142856 0 1 1 416.87499,401.82648 z" +- sodipodi:ry="3.2142856" +- sodipodi:rx="3.2142856" +- sodipodi:cy="401.82648" +- sodipodi:cx="413.66071" +- id="path8033" +- style="opacity:1;fill:#000000;fill-opacity:1;fill-rule:evenodd;stroke:url(#linearGradient4484);stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;marker:none;marker-start:none;marker-mid:none;marker-end:none;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" +- sodipodi:type="arc" /> +- <path +- transform="translate(13.125009,8.1249913)" +- d="M 416.87499,401.82648 A 3.2142856,3.2142856 0 1 1 410.44642,401.82648 A 3.2142856,3.2142856 0 1 1 416.87499,401.82648 z" +- sodipodi:ry="3.2142856" +- sodipodi:rx="3.2142856" +- sodipodi:cy="401.82648" +- sodipodi:cx="413.66071" +- id="path8035" +- style="opacity:1;fill:#000000;fill-opacity:1;fill-rule:evenodd;stroke:url(#linearGradient4486);stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;marker:none;marker-start:none;marker-mid:none;marker-end:none;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" +- sodipodi:type="arc" /> +- <path +- transform="translate(32.946437,7.4999913)" +- d="M 416.87499,401.82648 A 3.2142856,3.2142856 0 1 1 410.44642,401.82648 A 3.2142856,3.2142856 0 1 1 416.87499,401.82648 z" +- sodipodi:ry="3.2142856" +- sodipodi:rx="3.2142856" +- sodipodi:cy="401.82648" +- sodipodi:cx="413.66071" +- id="path8037" +- style="opacity:1;fill:#000000;fill-opacity:1;fill-rule:evenodd;stroke:url(#linearGradient4488);stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;marker:none;marker-start:none;marker-mid:none;marker-end:none;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" +- sodipodi:type="arc" /> +- <path +- transform="translate(24.910723,-10.267866)" +- d="M 416.87499,401.82648 A 3.2142856,3.2142856 0 1 1 410.44642,401.82648 A 3.2142856,3.2142856 0 1 1 416.87499,401.82648 z" +- sodipodi:ry="3.2142856" +- sodipodi:rx="3.2142856" +- sodipodi:cy="401.82648" +- sodipodi:cx="413.66071" +- id="path8039" +- style="opacity:1;fill:#000000;fill-opacity:1;fill-rule:evenodd;stroke:url(#linearGradient4490);stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;marker:none;marker-start:none;marker-mid:none;marker-end:none;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" +- sodipodi:type="arc" /> +- <path +- transform="translate(47.589294,-0.6250087)" +- d="M 416.87499,401.82648 A 3.2142856,3.2142856 0 1 1 410.44642,401.82648 A 3.2142856,3.2142856 0 1 1 416.87499,401.82648 z" +- sodipodi:ry="3.2142856" +- sodipodi:rx="3.2142856" +- sodipodi:cy="401.82648" +- sodipodi:cx="413.66071" +- id="path8041" +- style="opacity:1;fill:#000000;fill-opacity:1;fill-rule:evenodd;stroke:url(#linearGradient4492);stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;marker:none;marker-start:none;marker-mid:none;marker-end:none;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" +- sodipodi:type="arc" /> +- </g> +- <path +- style="opacity:1;fill:none;fill-rule:evenodd;stroke:#000000;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;display:inline;enable-background:new" +- d="M 896.20301,482.92837 C 897.1881,487.27845 900.74008,489.10785 903.58974,490.82019 C 908.05042,493.33311 910.1099,492.3423 912.74425,490.06258 C 914.3462,488.14141 923.42736,485.36393 928.33848,482.99151 C 932.66809,481.5326 937.24178,477.63278 941.723,474.65775 C 945.11814,473.03051 947.06964,475.01239 949.55168,475.6679 C 952.4958,476.38451 953.96285,477.83965 955.6126,479.20344 C 958.00876,480.37863 954.6847,482.34657 958.8956,483.49658 C 960.08651,483.71452 961.31255,484.07303 962.17859,482.99151" +- id="path8043" +- sodipodi:nodetypes="ccccccccc" /> +- <path +- style="opacity:1;fill:none;fill-rule:evenodd;stroke:#000000;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;display:inline;enable-background:new" +- d="M 910.85021,475.35223 C 913.16515,475.32025 914.02799,475.99476 916.34292,474.53148 C 919.79856,471.45035 921.74546,471.38671 924.29787,470.11206 C 927.32444,468.79683 930.83357,478.26375 934.3994,479.96105 C 936.79449,479.13963 935.68854,481.75484 935.85149,482.6127 C 935.90862,485.25954 938.65843,486.29076 940.20777,488.04227 C 943.52381,490.29776 947.583,494.33773 951.31945,493.34557 C 957.7647,490.4145 961.59867,492.06411 967.60816,485.95883 C 968.31221,484.77749 967.02391,479.06423 970.70175,478.76149 C 973.22574,479.01487 974.86842,478.81164 976.76267,479.32971 C 982.20367,481.4469 984.50045,485.77971 991.47301,487.28466 C 997.65591,488.25105 999.08565,491.07892 1005.3626,492.33542" +- id="path8045" +- sodipodi:nodetypes="cccccccccccc" /> +- <path +- style="opacity:1;fill:none;fill-rule:evenodd;stroke:#000000;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;display:inline;enable-background:new" +- d="M 876.98133,483.52197 C 879.37991,482.72817 883.08746,487.71407 885.15446,490.56765 C 885.74727,493.24717 886.30823,496.0541 885.91207,502.68948 C 886.6972,505.10702 888.59256,505.72043 890.7103,505.97248 C 893.82775,505.4357 896.58699,504.64818 898.0339,502.94202 C 899.9055,501.00035 903.34643,505.33596 906.11512,506.98263 C 909.72521,508.89472 913.8889,508.96149 917.98442,509.25547 C 919.688,509.02483 920.35482,513.77062 921.26741,517.3367 C 921.65155,521.71476 920.38197,524.23239 919.49965,527.18568 C 919.20535,529.68223 922.48815,530.71542 925.8131,531.73137 C 928.99554,532.47261 932.35734,533.39321 934.90447,533.49914 C 940.04633,534.37405 942.99321,536.18966 947.0263,537.53975 C 949.26544,538.3563 950.28649,539.78191 951.57199,541.07528" +- id="path8047" +- sodipodi:nodetypes="ccccccccccccc" /> +- <path +- style="opacity:0.25;fill:#ffffff;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;display:inline;filter:url(#filter8814);enable-background:new" +- d="M 332,187.69519 C 332,187.69519 389.5,162.19519 389.5,159.69519 C 389.5,157.19519 395,107.69519 395,107.69519 C 395,107.69519 486,59.195189 486.5,57.195189 C 487,55.195189 572.5,-4.8048114 572.5,-4.8048114 L 386.5,17.195189 L 311,123.19519 L 332,187.69519 z" +- id="path8049" +- clip-path="url(#clipPath8514)" +- transform="translate(276,136)" /> +- <path +- style="opacity:0.25;fill:#ffffff;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;marker:none;marker-start:none;marker-mid:none;marker-end:none;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" +- d="M 1697.2846,722.5514 C 1697.2846,722.5514 1581.3191,796.0905 1574.2481,800.33314 C 1567.177,804.57578 1343.7312,937.51186 1343.7312,937.51186 L 1347.9739,977.10984 L 1564.3486,876.70067 L 1681.7283,774.8773 L 1697.2846,722.5514 z" +- id="path8051" /> +- <path +- style="opacity:0.5;fill:#000000;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;marker:none;marker-start:none;marker-mid:none;marker-end:none;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;visibility:visible;display:inline;overflow:visible;filter:url(#filter8810);enable-background:accumulate" +- d="M 528.91587,556.85291 C 523.25902,555.4387 347.89654,631.80623 347.89654,631.80623 L 313.95541,812.82557 L 365.05087,1006.7738 L 622.25397,1074.4551 C 622.25397,1074.4551 828.72915,1227.1901 834.386,1222.9475 C 840.04286,1218.7049 1002.6774,1029.2002 1002.6774,1029.2002 L 842.87128,845.35248 L 796.20224,667.16157 L 528.91587,556.85291 z" +- id="path8053" +- clip-path="url(#clipPath8610)" +- sodipodi:nodetypes="cccccscccc" +- transform="translate(276,136)" /> +- <path +- style="opacity:1;fill:#0c0c0c;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;display:inline;enable-background:new" +- d="M 1097.6433,613.88997 C 1097.6433,613.88997 1120.2628,607.38316 1133.386,608.01724 C 1146.5093,608.65133 1164.0276,609.95586 1177.0949,620.20343 C 1190.1622,630.45099 1202.1626,647.3435 1211.2073,678.57308 C 1220.2519,709.80266 1212.9056,777.82509 1205.0312,821.92043 C 1197.1569,866.01577 1176.7661,928.03341 1160.0312,961.92043 C 1143.2964,995.80745 1110.2335,1039.4156 1099.4618,1051.7966 C 1088.0976,1064.8586 1043.2559,1088.2228 1020.0312,1094.0633 C 1025.3346,1083.4567 1068.931,1043.4744 1055.0312,1033.349 C 1041.0123,1023.1367 1009.2712,1079.3314 970.7381,1062.3822 C 992.12041,1049.2501 1012.5175,1011.1961 1004.7787,995.78772 C 996.93846,980.17733 974.07378,1044.5453 911.24317,1032.8006 C 941.29521,1005.2739 966.65023,961.89659 952.50587,949.8209 C 938.09071,937.51403 892.04412,1004.1141 892.04412,1004.1141 C 892.04412,1004.1141 889.22222,962.41287 905.81732,935.50673 C 922.45667,908.52886 985.47029,853.89146 1005.3704,823.80331 C 1025.2706,793.71517 1038.983,757.79429 1047.5059,731.28537 C 1056.0287,704.77645 1063.3068,654.18583 1063.3068,654.18583" +- id="path8055" +- sodipodi:nodetypes="czzzzzzczczczczzzc" /> +- <path +- style="opacity:0.25;fill:#ffffff;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;marker:none;marker-start:none;marker-mid:none;marker-end:none;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;visibility:visible;display:inline;overflow:visible;filter:url(#filter8818);enable-background:accumulate" +- d="M 770.74639,609.17881 L 719.8347,706.75955 L 639.93163,817.77531 L 674.57987,889.19309 L 717.00628,968.38906 L 789.13117,923.13422 L 803.27331,730.80117 L 824.48651,592.20825 L 810.34437,502.05213 L 770.74639,609.17881 z" +- id="path8057" +- clip-path="url(#clipPath8622)" +- sodipodi:nodetypes="cccccccccc" +- transform="translate(276,136)" /> +- <path +- style="opacity:1;fill:#000000;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;marker:none;marker-start:none;marker-mid:none;marker-end:none;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;visibility:visible;display:inline;overflow:visible;filter:url(#filter8810);enable-background:accumulate" +- d="M 295,846.19519 L 301.64488,777.27234 C 301.64488,777.27234 391.96439,866.27691 464,900.19519 C 536.03561,934.11347 772,962.19519 772,962.19519 L 926,936.19519 L 890,1098.1952 L 604,1124.1952 L 306,1035.1952 L 295,846.19519 z" +- id="path8059" +- clip-path="url(#clipPath8906)" +- sodipodi:nodetypes="cczcccccc" +- transform="translate(276,136)" /> +- <path +- transform="translate(450.03125,73.843964)" +- style="opacity:1;fill:#ffffff;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;display:inline;filter:url(#filter3587);enable-background:new" +- d="M 405.79629,845.99023 L 480.74961,911.04406 L 483.24924,927.92446 L 502.6526,938.08337 L 509.14464,961.13446 L 540.85369,952.76336 L 555.70293,1000.8466 C 567.95945,1013.5745 645.49637,887.7369 611.56436,1039.0304 L 550.75318,1055.2939 L 461.55026,960.60104 L 398.72523,906.80141 L 405.79629,845.99023 z" +- id="path8061" +- sodipodi:nodetypes="cccccccccccc" +- clip-path="url(#clipPath3602)" /> +- <path +- style="opacity:1;fill:#121212;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;marker:none;marker-start:none;marker-mid:none;marker-end:none;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" +- d="M 1159.317,918.349 C 1213.6027,916.92043 1285.352,903.29701 1329.317,891.56328 C 1373.3697,879.80614 1455.2033,855.21604 1504.674,833.70614 C 1554.0133,812.25342 1618.2778,774.42454 1658.9599,741.56329 C 1699.468,708.8426 1711.3498,685.74348 1719.6741,707.99186 C 1728.0432,730.35965 1703.2672,764.31748 1681.817,789.06329 C 1660.2128,813.98669 1629.0856,841.76862 1582.8883,878.349 C 1536.691,914.92938 1426.8058,979.93363 1370.0312,1006.9204 C 1312.9652,1034.0458 1241.8279,1065.1589 1197.8884,1079.4205 C 1153.9489,1093.6821 1066.4598,1110.4919 1066.4598,1110.4919 L 1159.317,918.349 z" +- id="path8063" +- sodipodi:nodetypes="czzzzzzzzcc" /> +- <path +- transform="translate(450.03125,73.843964)" +- style="opacity:0.5;fill:url(#linearGradient3666);fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;marker:none;marker-start:none;marker-mid:none;marker-end:none;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;visibility:visible;display:inline;overflow:visible;filter:url(#filter3779);enable-background:accumulate" +- d="M 1241.5965,652.95007 C 1241.5965,652.95007 1176.875,707.28713 1095.9326,751.94501 C 1013.9082,797.19985 811.67556,845.28311 811.67556,845.28311 C 811.67556,845.28311 796.57419,866.33507 856.93045,873.56739 C 917.28671,880.79971 1081.0124,820.2667 1135.5306,777.40085 C 1190.0488,734.535 1255.7387,665.67799 1255.7387,665.67799 L 1241.5965,652.95007 z" +- id="path8065" +- sodipodi:nodetypes="czczzcc" +- clip-path="url(#clipPath3992)" /> +- <g +- transform="translate(450.03125,73.843964)" +- style="opacity:1;display:inline;enable-background:new" +- id="g8067" +- clip-path="url(#clipPath3986)"> +- <g +- transform="translate(-174.03125,62.156036)" +- style="filter:url(#filter3677)" +- id="g8069"> +- <g +- style="filter:url(#filter3785)" +- id="g8071"> +- <path +- sodipodi:nodetypes="czzccccc" +- id="path8073" +- d="M 1094.2857,725.93361 C 1094.2857,725.93361 1093.9896,752.09452 1098.9285,763.79076 C 1103.8674,775.487 1118.9666,790.27741 1127.5,795.21933 C 1136.0334,800.16125 1146.4286,803.79075 1146.4286,803.79075 L 1264.2857,688.79075 L 1282.1429,613.07647 L 1185.7143,651.6479 L 1094.2857,725.93361 z" +- style="opacity:1;fill:#ffffff;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;display:inline;enable-background:new" +- transform="translate(174.03125,-62.156036)" /> +- <rect +- y="486.14224" +- x="1197.8389" +- height="309.71277" +- width="333.75412" +- id="rect8075" +- style="opacity:1;fill:none;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;marker:none;marker-start:none;marker-mid:none;marker-end:none;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" /> +- </g> +- </g> +- <g +- transform="translate(-174.03125,62.156036)" +- style="opacity:0.18000004;display:inline;enable-background:new" +- id="g8077"> +- <g +- style="filter:url(#filter3785)" +- id="g8079"> +- <path +- sodipodi:nodetypes="czzccccc" +- id="path8081" +- d="M 1094.2857,725.93361 C 1094.2857,725.93361 1093.9896,752.09452 1098.9285,763.79076 C 1103.8674,775.487 1118.9666,790.27741 1127.5,795.21933 C 1136.0334,800.16125 1146.4286,803.79075 1146.4286,803.79075 L 1264.2857,688.79075 L 1282.1429,613.07647 L 1185.7143,651.6479 L 1094.2857,725.93361 z" +- style="opacity:1;fill:#ffffff;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;display:inline;enable-background:new" +- transform="translate(174.03125,-62.156036)" /> +- <rect +- y="486.14224" +- x="1197.8389" +- height="309.71277" +- width="333.75412" +- id="rect8083" +- style="opacity:1;fill:none;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;marker:none;marker-start:none;marker-mid:none;marker-end:none;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" /> +- </g> +- </g> +- </g> +- <path +- transform="translate(450.03125,73.843964)" +- style="opacity:0.83300003;fill:#050505;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:15;stroke-linecap:butt;stroke-linejoin:miter;marker:none;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;visibility:visible;display:inline;overflow:visible;filter:url(#filter8225);enable-background:accumulate" +- d="M 1264.1875,605 C 1259.6964,605.73268 1256.0305,608.45509 1252.25,611.40625 C 1242.1687,619.27601 1224.0805,645.83149 1204.2188,661.875 C 1164.3514,694.07816 1100.2228,731.85201 1051.6562,752.96875 C 1003.0422,774.10613 921.11498,798.78676 877.34375,810.46875 C 833.94554,822.05121 762.29972,835.59982 709.09375,837 L 704.53125,837.125 L 702.53125,841.25 L 609.6875,1033.375 L 603.1875,1046.8438 L 617.84375,1044 C 617.84375,1044 705.11343,1027.3486 750.1875,1012.7188 C 794.9127,998.20213 865.97836,967.05197 923.21875,939.84375 C 980.82199,912.46306 1090.1551,847.86412 1137.5,810.375 C 1183.8608,773.66518 1215.3049,745.65818 1237.4375,720.125 C 1248.3386,707.549 1260.1823,692.59356 1268.4688,677.375 C 1276.7552,662.15644 1287.6285,633.15692 1282.1562,618.53125 C 1280.9385,615.27651 1279.6048,612.46995 1277.5625,610.03125 C 1275.5202,607.59255 1269.0878,608.45926 1269,605 C 1268.7902,596.73518 1265.6845,604.75577 1264.1875,605 z M 1266.3438,620.21875 C 1266.7586,620.80449 1267.3749,621.77641 1268.125,623.78125 C 1271.0218,631.52338 1266.6843,655.68 1259.3125,669.21875 C 1251.9407,682.7575 1236.6741,698.14269 1226.125,710.3125 C 1205.0496,734.62606 1174.2213,762.17406 1128.1875,798.625 C 1083.1379,834.29659 972.72717,899.71959 916.78125,926.3125 C 859.88952,953.35499 788.68509,984.4309 745.53125,998.4375 C 709.16634,1010.2406 649.68654,1022.2713 629.8125,1026.2188 L 714.09375,851.75 C 768.80066,849.7007 837.88634,836.53365 881.21875,824.96875 C 925.55297,813.1365 1007.2974,788.63242 1057.625,766.75 C 1107.737,744.96129 1170.1594,705.58184 1211.6562,672.0625 C 1232.3026,655.38529 1253.4011,629.51662 1261.4688,623.21875 C 1263.9058,621.31633 1265.5494,620.58295 1266.3438,620.21875 z" +- id="path8085" +- clip-path="url(#clipPath3722)" +- sodipodi:nodetypes="cssssccccccssssssssccssssssccssssc" /> +- <g +- style="opacity:1;display:inline;enable-background:new" +- id="g8087" +- mask="url(#mask7704)" +- transform="matrix(0.9934486,0.1142802,-0.1142802,0.9934486,-9.24324,588.09054)" +- inkscape:transform-center-x="-185.09603" +- inkscape:transform-center-y="-12.859654"> +- <path +- transform="translate(8.0045714e-2,-3.125e-2)" +- style="fill:#bcb786;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;display:inline;enable-background:new" +- d="M 1111.4062,-285.9375 L 1107.4688,-284.0625 C 1107.4283,-284.05228 1107.3692,-284.04201 1107.3438,-284.03125 C 1106.925,-283.8184 1107.1791,-283.93067 1106.6875,-283.71875 C 1106.2014,-283.50919 1104.9499,-283.13456 1102.5938,-282.25 C 1099.2626,-280.99942 1096.7895,-280.10016 1095.5938,-279.1875 C 1094.0576,-279.16623 1091.8733,-278.95419 1089.9375,-278.46875 C 1086.956,-277.72108 1085.0823,-277.29474 1083.1875,-276.875 C 1081.2927,-276.45527 1081.512,-276.23281 1080.3125,-276 C 1079.0159,-275.74833 1078.5911,-276.00899 1074.875,-275.21875 C 1071.3851,-274.4766 1065.9802,-273.28768 1064.7188,-272.53125 C 1063.1348,-272.71203 1060.8513,-272.85303 1058.875,-272.5625 C 1055.8346,-272.11554 1053.9588,-271.88974 1052.0312,-271.65625 C 1051.3758,-271.57687 1050.9902,-271.45547 1050.6875,-271.375 C 1050.2613,-271.24334 1050.0017,-271.11498 1049.3125,-271.03125 C 1048.0009,-270.87188 1047.5503,-271.18808 1043.7812,-270.75 C 1040.2273,-270.33691 1034.7758,-269.47718 1033.5312,-268.8125 C 1031.9322,-269.10979 1029.6735,-269.34669 1027.6875,-269.15625 C 1024.6287,-268.86293 1022.7155,-268.67226 1020.7812,-268.5 C 1018.847,-268.32773 1019.0926,-268.07763 1017.875,-267.96875 C 1016.5588,-267.85105 1016.1152,-268.13238 1012.3438,-267.71875 C 1008.8017,-267.3303 1003.3359,-266.50948 1002.0625,-265.84375 C 1000.4636,-266.13844 998.1753,-266.35076 996.1875,-266.15625 C 993.12921,-265.857 991.2463,-265.67601 989.3125,-265.5 C 988.65501,-265.44015 988.27245,-265.32144 987.96875,-265.25 C 987.54105,-265.13104 987.28525,-265.03193 986.59375,-264.96875 C 985.27775,-264.84849 984.834,-265.16363 981.0625,-264.75 C 977.50631,-264.35998 972.0569,-263.51084 970.8125,-262.84375 C 969.21381,-263.13793 966.95265,-263.36747 964.96875,-263.15625 C 961.91305,-262.83092 959.9947,-262.63001 958.0625,-262.4375 C 956.13031,-262.24499 956.37275,-261.99662 955.15625,-261.875 C 953.84137,-261.74353 953.3932,-262.03954 949.625,-261.59375 C 946.08611,-261.17509 940.6473,-260.30158 939.375,-259.625 C 937.77741,-259.90604 935.51505,-260.04543 933.53125,-259.8125 C 930.47927,-259.45413 928.58625,-259.24464 926.65625,-259.03125 C 926.00007,-258.95869 925.6156,-258.85856 925.3125,-258.78125 C 924.88571,-258.65402 924.6276,-258.51405 923.9375,-258.4375 C 922.62411,-258.29181 922.17015,-258.61152 918.40625,-258.125 C 914.85737,-257.66624 909.4276,-256.70598 908.1875,-256 C 906.59441,-256.24424 904.3537,-256.38135 902.375,-256.125 C 899.32741,-255.73018 897.4243,-255.47655 895.5,-255.21875 C 893.57571,-254.96096 893.7739,-254.72522 892.5625,-254.5625 C 891.25301,-254.3866 890.8153,-254.66688 887.0625,-254.09375 C 883.53821,-253.55551 878.1393,-252.39458 876.875,-251.65625 C 875.28751,-251.85979 873.0295,-251.91098 871.0625,-251.5625 C 868.03631,-251.02638 866.1636,-250.70081 864.25,-250.375 C 863.59941,-250.26423 863.2363,-250.10406 862.9375,-250 C 862.51681,-249.83512 862.27405,-249.6687 861.59375,-249.53125 C 860.29905,-249.26966 859.86665,-249.53745 856.15625,-248.71875 C 852.65777,-247.9468 847.31035,-246.33582 846.09375,-245.5 C 844.53085,-245.57745 842.33625,-245.41472 840.40625,-244.90625 C 837.43387,-244.12312 835.58855,-243.67416 833.71875,-243.15625 C 831.84875,-242.63835 832.0521,-242.38897 830.875,-242.0625 C 829.60251,-241.7096 829.17795,-241.95541 825.53125,-240.875 C 822.10657,-239.86037 816.88185,-237.94183 815.65625,-237.03125 C 814.11747,-237.01851 811.93645,-236.75903 810.03125,-236.15625 C 807.10027,-235.22891 805.2809,-234.69783 803.4375,-234.09375 C 802.81071,-233.88837 802.44585,-233.70117 802.15625,-233.5625 C 801.74867,-233.34889 801.50295,-233.15375 800.84375,-232.9375 C 799.58925,-232.52596 799.1576,-232.74846 795.5625,-231.5 C 792.17261,-230.32283 786.96755,-228.2863 785.78125,-227.34375 C 784.25737,-227.28408 782.1312,-226.94888 780.25,-226.28125 C 777.35261,-225.25296 775.55095,-224.60577 773.71875,-223.96875 C 771.88655,-223.33174 772.0909,-223.12021 770.9375,-222.71875 C 769.69071,-222.28479 769.27395,-222.51903 765.71875,-221.15625 C 762.38005,-219.87645 757.23165,-217.6737 756.03125,-216.6875 C 754.52407,-216.57981 752.39555,-216.1887 750.53125,-215.46875 C 747.66307,-214.36115 745.90735,-213.68719 744.09375,-213 C 743.47705,-212.76637 743.0973,-212.55797 742.8125,-212.40625 C 742.81251,-212.40625 742.8125,-212.37673 742.8125,-212.375 L 734.8125,-209.1875 L 722.3366,-205.69561 L 730.26626,-186.41789 C 729.67463,-184.44432 742.8125,-191.15625 742.8125,-191.15625 C 743.03891,-191.30093 743.26145,-191.42886 743.53125,-191.53125 C 744.61177,-191.94123 745.70285,-191.74702 749.53125,-193.21875 C 753.35977,-194.69049 754.7553,-195.22373 755.4375,-195.625 C 756.11711,-196.02478 757.04925,-196.50437 757.65625,-197.15625 C 759.48317,-197.294 761.22705,-197.64948 762.59375,-198.15625 C 765.56175,-199.25677 767.4691,-199.96244 769.375,-200.625 C 771.28081,-201.28754 771.72915,-202.03987 772.78125,-202.40625 C 773.87287,-202.78636 774.97635,-202.57163 778.84375,-203.9375 C 782.71115,-205.30336 784.1269,-205.76458 784.8125,-206.15625 C 785.51361,-206.55677 786.5133,-207.08923 787.125,-207.75 C 789.09581,-207.80466 790.94195,-208.13463 792.40625,-208.625 C 795.40777,-209.63008 797.3324,-210.24671 799.25,-210.875 C 800.78861,-211.3791 801.42415,-211.92177 802.15625,-212.3125 C 802.38647,-212.44681 802.63215,-212.56623 802.90625,-212.65625 C 804.00457,-213.01673 805.0877,-212.73762 809,-213.96875 C 812.91231,-215.19988 814.366,-215.6417 815.0625,-216 C 815.75641,-216.35697 816.6926,-216.79261 817.3125,-217.40625 C 819.17771,-217.42891 820.94835,-217.67308 822.34375,-218.09375 C 825.37415,-219.00729 827.33615,-219.52385 829.28125,-220.0625 C 831.22637,-220.60114 831.70745,-221.32702 832.78125,-221.625 C 833.89527,-221.93415 835.00125,-221.61761 838.96875,-222.65625 C 842.93625,-223.69488 844.38625,-224.08898 845.09375,-224.40625 C 845.82855,-224.73584 846.90765,-225.15997 847.53125,-225.78125 C 849.52907,-225.66525 851.3887,-225.80134 852.875,-226.15625 C 855.95311,-226.89125 857.9584,-227.25719 859.9375,-227.65625 C 861.52541,-227.97643 862.1818,-228.4468 862.9375,-228.75 C 863.17501,-228.8568 863.4044,-228.94276 863.6875,-229 C 864.82091,-229.22919 865.99215,-228.79107 870.03125,-229.5 C 874.07067,-230.20893 875.5315,-230.42709 876.25,-230.6875 C 876.96581,-230.94694 877.95435,-231.25474 878.59375,-231.78125 C 880.51795,-231.54176 882.34165,-231.55672 883.78125,-231.78125 C 886.90767,-232.26887 888.9358,-232.48192 890.9375,-232.75 C 892.93921,-233.01807 893.42625,-233.69514 894.53125,-233.84375 C 895.67767,-233.99793 896.8071,-233.54218 900.875,-234.0625 C 904.94281,-234.58282 906.43525,-234.75823 907.15625,-235 C 907.89337,-235.24714 908.95435,-235.58623 909.59375,-236.125 C 911.64375,-235.78947 913.56745,-235.72704 915.09375,-235.90625 C 918.23595,-236.27521 920.27375,-236.46561 922.28125,-236.6875 C 923.89207,-236.86552 924.5459,-237.2957 925.3125,-237.53125 C 925.55341,-237.61677 925.80655,-237.68685 926.09375,-237.71875 C 927.24345,-237.84647 928.39505,-237.3721 932.46875,-237.84375 C 936.54245,-238.3154 938.0278,-238.45435 938.75,-238.6875 C 939.46941,-238.91977 940.45025,-239.16096 941.09375,-239.65625 C 943.03005,-239.32279 944.8638,-239.25201 946.3125,-239.40625 C 949.45851,-239.7412 951.49,-239.92484 953.5,-240.125 C 955.50991,-240.32514 955.98415,-240.95139 957.09375,-241.0625 C 958.24485,-241.17778 959.39025,-240.69744 963.46875,-241.125 C 967.54725,-241.55256 969.05765,-241.68709 969.78125,-241.90625 C 970.52047,-242.13011 971.57685,-242.4195 972.21875,-242.9375 C 974.27575,-242.53883 976.2206,-242.4441 977.75,-242.59375 C 980.89871,-242.90185 982.9258,-243.067 984.9375,-243.25 C 986.55151,-243.39682 987.20055,-243.81055 987.96875,-244.03125 C 988.21005,-244.11211 988.4623,-244.16116 988.75,-244.1875 C 989.90211,-244.29295 991.0429,-243.79475 995.125,-244.1875 C 999.20711,-244.58025 1000.7139,-244.71834 1001.4375,-244.9375 C 1002.1584,-245.15583 1003.1371,-245.3852 1003.7812,-245.875 C 1005.7193,-245.52501 1007.5501,-245.42062 1009,-245.5625 C 1012.1487,-245.8706 1014.1758,-246.03575 1016.1875,-246.21875 C 1018.1991,-246.40174 1018.7017,-247.05677 1019.8125,-247.15625 C 1020.9648,-247.25948 1022.1047,-246.77142 1026.1875,-247.15625 C 1030.2704,-247.54107 1031.7762,-247.65725 1032.5,-247.875 C 1033.2393,-248.09743 1034.2956,-248.38949 1034.9375,-248.90625 C 1036.9949,-248.50448 1038.9404,-248.40292 1040.4688,-248.5625 C 1043.6153,-248.89102 1045.6458,-249.0852 1047.6562,-249.28125 C 1049.2692,-249.43854 1049.9219,-249.91273 1050.6875,-250.15625 C 1050.9282,-250.24429 1051.1507,-250.27762 1051.4375,-250.3125 C 1052.5858,-250.4522 1053.7542,-249.97259 1057.8125,-250.5625 C 1061.8708,-251.15242 1063.3743,-251.33964 1064.0938,-251.59375 C 1064.8104,-251.84691 1065.7684,-252.15182 1066.4062,-252.6875 C 1068.3259,-252.47556 1070.1262,-252.53609 1071.5625,-252.78125 C 1074.6816,-253.31365 1076.6741,-253.70986 1078.6562,-254.09375 C 1080.6383,-254.47762 1081.1305,-255.1334 1082.2188,-255.375 C 1083.3475,-255.62566 1084.489,-255.25871 1088.4688,-256.25 C 1092.4483,-257.24127 1093.8983,-257.6693 1094.5938,-258.03125 C 1095.316,-258.40725 1096.3555,-258.90183 1096.9688,-259.5625 C 1098.9317,-259.57454 1100.7625,-259.85355 1102.1875,-260.40625 C 1105.1387,-261.55085 1107.0607,-262.27567 1108.875,-263.15625 C 1110.3307,-263.86277 1111.1941,-264.85828 1111.4062,-265.15625 C 1111.6185,-265.4542 1111.5051,-265.8848 1111.5312,-265.90625 C 1111.5742,-265.94148 1111.8716,-266.00028 1112.0312,-266.34375 C 1112.8902,-268.19082 1114.3544,-271.97139 1114.4688,-272.65625 C 1114.5825,-273.33839 1114.6368,-274.00902 1114.6875,-274.40625 C 1114.7169,-274.63575 1114.5404,-275.28515 1114.5625,-275.34375 C 1114.5934,-275.42579 1114.8508,-275.59432 1114.9062,-275.84375 C 1115.1725,-277.04206 1114.9953,-278.05111 1114.7812,-279.46875 C 1114.5673,-280.88638 1113.8096,-284.08338 1113.1562,-284.9375 C 1112.4973,-285.79922 1111.9314,-285.94801 1111.4062,-285.9375 z" +- id="path8089" +- sodipodi:nodetypes="ccssscsssscssssscsssscssssscsssscssssscsssscssssscsssscssssscsssscssscccccssscssssscsssssscssssscsssssscssssscsssssscssssscsssssscssssscsssssscssssscsssssssssssc" /> +- <g +- clip-path="url(#clipPath7421)" +- id="g8091"> +- <path +- id="path8093" +- d="M 1107.409,-284.04961 C 1106.9903,-283.83678 1107.2534,-283.95572 1106.7618,-283.7438 C 1106.2757,-283.53426 1105.0384,-283.16941 1102.6822,-282.28485 C 1099.3511,-281.03428 1096.852,-280.13141 1095.6563,-279.21875 C 1094.1202,-279.19749 1091.9358,-278.98544 1090,-278.5 C 1087.0185,-277.75234 1085.1448,-277.32599 1083.25,-276.90625 C 1081.3552,-276.48653 1081.5745,-276.26406 1080.375,-276.03125 C 1079.0784,-275.77959 1078.6536,-276.04024 1074.9375,-275.25 C 1071.4476,-274.50786 1066.0427,-273.31893 1064.7813,-272.5625 C 1063.1974,-272.74329 1060.9138,-272.88428 1058.9375,-272.59375 C 1055.8971,-272.1468 1054.0213,-271.92099 1052.0938,-271.6875 C 1051.4384,-271.60813 1051.0527,-271.48672 1050.75,-271.40625 C 1050.3238,-271.2746 1050.0642,-271.14623 1049.375,-271.0625 C 1048.0634,-270.90314 1047.6128,-271.21933 1043.8438,-270.78125 C 1040.2899,-270.36817 1034.8384,-269.50843 1033.5938,-268.84375 C 1031.9948,-269.14105 1029.736,-269.37794 1027.75,-269.1875 C 1024.6912,-268.89419 1022.778,-268.70351 1020.8438,-268.53125 C 1018.9095,-268.35899 1019.1551,-268.10888 1017.9375,-268 C 1016.6213,-267.88231 1016.1777,-268.16363 1012.4063,-267.75 C 1008.8644,-267.36156 1003.3984,-266.54073 1002.125,-265.875 C 1000.5261,-266.1697 998.23783,-266.38201 996.25,-266.1875 C 993.19176,-265.88826 991.30887,-265.70726 989.375,-265.53125 C 988.71751,-265.47141 988.33496,-265.35269 988.03125,-265.28125 C 987.6036,-265.1623 987.34774,-265.06318 986.65625,-265 C 985.34029,-264.87975 984.89649,-265.19488 981.125,-264.78125 C 977.56886,-264.39124 972.11946,-263.54209 970.875,-262.875 C 969.27637,-263.16919 967.01516,-263.39872 965.03125,-263.1875 C 961.97565,-262.86218 960.05721,-262.66126 958.125,-262.46875 C 956.19279,-262.27625 956.43513,-262.02787 955.21875,-261.90625 C 953.90387,-261.77479 953.45577,-262.07079 949.6875,-261.625 C 946.14863,-261.20635 940.70982,-260.33283 939.4375,-259.65625 C 937.83995,-259.9373 935.57754,-260.07668 933.59375,-259.84375 C 930.54177,-259.48539 928.64867,-259.27589 926.71875,-259.0625 C 926.06255,-258.98995 925.67809,-258.88981 925.375,-258.8125 C 924.94823,-258.68528 924.69009,-258.5453 924,-258.46875 C 922.68667,-258.32307 922.23254,-258.64277 918.46875,-258.15625 C 914.91986,-257.6975 909.49012,-256.73723 908.25,-256.03125 C 906.65695,-256.27549 904.41619,-256.4126 902.4375,-256.15625 C 899.38991,-255.76144 897.48679,-255.5078 895.5625,-255.25 C 893.63822,-254.99221 893.83639,-254.75647 892.625,-254.59375 C 891.31554,-254.41785 890.87781,-254.69813 887.125,-254.125 C 883.60071,-253.58676 878.20185,-252.42583 876.9375,-251.6875 C 875.35,-251.89104 873.092,-251.94223 871.125,-251.59375 C 868.09883,-251.05763 866.22611,-250.73206 864.3125,-250.40625 C 863.66189,-250.29548 863.29879,-250.13531 863,-250.03125 C 862.57933,-249.86637 862.33655,-249.69995 861.65625,-249.5625 C 860.3616,-249.30091 859.92913,-249.5687 856.21875,-248.75 C 852.72022,-247.97805 847.3728,-246.36707 846.15625,-245.53125 C 844.59347,-245.6087 842.39867,-245.44597 840.46875,-244.9375 C 837.49631,-244.15437 835.65114,-243.70541 833.78125,-243.1875 C 831.91137,-242.6696 832.11465,-242.42022 830.9375,-242.09375 C 829.66504,-241.74085 829.24047,-241.98666 825.59375,-240.90625 C 822.16905,-239.89162 816.94431,-237.97308 815.71875,-237.0625 C 814.17992,-237.04976 811.99892,-236.79028 810.09375,-236.1875 C 807.16269,-235.26016 805.34344,-234.72908 803.5,-234.125 C 802.87324,-233.91962 802.50827,-233.73242 802.21875,-233.59375 C 801.81112,-233.38014 801.56541,-233.185 800.90625,-232.96875 C 799.65179,-232.55721 799.22014,-232.77971 795.625,-231.53125 C 792.23515,-230.35408 787.03002,-228.31755 785.84375,-227.375 C 784.31986,-227.31533 782.1937,-226.98013 780.3125,-226.3125 C 777.41511,-225.28421 775.61342,-224.63702 773.78125,-224 C 771.94908,-223.36299 772.1534,-223.15146 771,-222.75 C 769.75322,-222.31604 769.33639,-222.55028 765.78125,-221.1875 C 762.44258,-219.9077 757.2941,-217.70495 756.09375,-216.71875 C 754.58657,-216.61106 752.45806,-216.21995 750.59375,-215.5 C 747.72557,-214.3924 745.96995,-213.71844 744.15625,-213.03125 C 743.53959,-212.79762 743.15984,-212.58922 742.875,-212.4375 C 742.875,-212.4375 742.875,-211.34375 742.875,-211.34375 C 742.98678,-211.56611 743.26099,-212.16118 743.78125,-212.4375 C 744.47922,-212.80822 748.59488,-214.43087 750.59375,-215.15625 C 752.25061,-215.7575 754.74764,-216.48493 756.5625,-216.46875 C 756.86412,-216.46606 757.15012,-216.41785 757.40625,-216.375 C 759.24874,-216.06675 764.875,-214.8125 764.875,-214.8125 C 764.87499,-214.8125 758.64151,-216.45925 757.84375,-216.65625 C 757.65296,-216.70336 757.30803,-216.72497 756.875,-216.71875 C 758.02046,-217.58846 761.636,-219.11226 764.21875,-220.15625 C 767.05697,-221.30352 767.33556,-221.40807 769.28125,-221.8125 C 771.28955,-222.22994 772.4375,-222.3125 772.4375,-222.3125 C 772.4375,-222.31249 772.35514,-222.91364 773.40625,-223.4375 C 774.11135,-223.78891 778.29327,-225.3299 780.3125,-226 C 782.2644,-226.64773 785.3699,-227.3585 787.1875,-227 C 789.05073,-226.6325 794.71875,-225.1875 794.71875,-225.1875 C 794.71876,-225.1875 788.43175,-227.05861 787.625,-227.28125 C 787.43208,-227.3345 787.09416,-227.36729 786.65625,-227.375 C 787.81459,-228.20788 791.45069,-229.57032 794.0625,-230.53125 C 796.93266,-231.58726 797.22984,-231.69305 799.1875,-232.0625 C 801.04099,-232.41229 802.04634,-232.48798 802.21875,-232.5 C 802.33235,-232.71724 802.5962,-233.31002 803.125,-233.5625 C 803.83444,-233.90124 808.05107,-235.27525 810.09375,-235.875 C 811.78692,-236.37211 814.33452,-236.91177 816.1875,-236.78125 C 816.49545,-236.75957 816.80099,-236.68399 817.0625,-236.625 C 818.94368,-236.20068 824.65625,-234.59375 824.65625,-234.59375 C 824.65626,-234.59375 818.31451,-236.659 817.5,-236.90625 C 817.30521,-236.96539 816.94212,-237.01019 816.5,-237.03125 C 817.66949,-237.8288 821.36302,-239.08747 824,-239.96875 C 826.89781,-240.93722 827.23301,-240.97207 829.21875,-241.25 C 831.2684,-241.53689 832.40625,-241.5625 832.40625,-241.5625 C 832.40623,-241.5625 832.3335,-242.16947 833.40625,-242.625 C 834.12585,-242.93057 838.39723,-244.12575 840.46875,-244.625 C 842.47119,-245.10758 845.66724,-245.55329 847.53125,-245.03125 C 849.44203,-244.4961 855.25,-242.53125 855.25,-242.53125 C 855.25,-242.53125 848.82734,-244.95476 848,-245.25 C 847.80216,-245.32061 847.41784,-245.39039 846.96875,-245.4375 C 848.15665,-246.16615 851.88402,-247.21158 854.5625,-247.9375 C 857.50592,-248.73525 857.85458,-248.70833 859.875,-248.84375 C 861.78789,-248.97198 862.82205,-248.91484 863,-248.90625 C 863.11728,-249.10991 863.39176,-249.68573 863.9375,-249.875 C 864.66969,-250.12894 869.01602,-250.92289 871.125,-251.25 C 872.87313,-251.52111 875.52588,-251.7347 877.4375,-251.34375 C 877.75516,-251.27879 878.04272,-251.15824 878.3125,-251.0625 C 880.25324,-250.37377 886.15625,-247.96875 886.15625,-247.96875 C 886.15626,-247.96875 879.62154,-250.91952 878.78125,-251.28125 C 878.58028,-251.36776 878.20612,-251.44804 877.75,-251.53125 C 878.9565,-252.16443 882.77956,-252.92685 885.5,-253.4375 C 888.48953,-253.99869 888.80023,-253.96704 890.84375,-253.96875 C 892.95301,-253.97052 894.15625,-253.84375 894.15625,-253.84375 C 894.15625,-253.84374 894.08354,-254.47494 895.1875,-254.78125 C 895.92802,-254.98672 900.31362,-255.61512 902.4375,-255.84375 C 904.49052,-256.06474 907.75613,-256.09597 909.65625,-255.375 C 911.60404,-254.63593 917.5,-252 917.5,-252 C 917.50002,-252 910.93712,-255.17897 910.09375,-255.5625 C 909.89207,-255.65423 909.55154,-255.74871 909.09375,-255.84375 C 910.30467,-256.44563 914.07817,-257.09259 916.8125,-257.5 C 919.8173,-257.94772 920.13801,-257.9517 922.1875,-257.90625 C 924.12795,-257.86323 925.19449,-257.71202 925.375,-257.6875 C 925.49392,-257.88066 925.7589,-258.45333 926.3125,-258.59375 C 927.05521,-258.78213 931.46679,-259.32803 933.59375,-259.53125 C 935.35678,-259.69967 938.01384,-259.76554 939.9375,-259.28125 C 940.25718,-259.20077 940.54101,-259.07766 940.8125,-258.96875 C 942.76543,-258.18526 948.71875,-255.5 948.71875,-255.5 C 948.71873,-255.5 942.12684,-258.75348 941.28125,-259.15625 C 941.07903,-259.25257 940.70899,-259.36328 940.25,-259.46875 C 941.46414,-260.04302 945.29366,-260.59094 948.03125,-260.96875 C 951.03963,-261.38395 951.35432,-261.41138 953.40625,-261.34375 C 955.52423,-261.27394 956.71875,-261.09375 956.71875,-261.09375 C 956.71873,-261.09375 956.6415,-261.73116 957.75,-262 C 958.49362,-262.18035 962.90176,-262.66355 965.03125,-262.84375 C 967.08972,-263.01792 970.37449,-262.96807 972.28125,-262.1875 C 974.23584,-261.38734 980.15625,-258.65625 980.15625,-258.65625 C 980.15623,-258.65625 973.59632,-261.96501 972.75,-262.375 C 972.54763,-262.47305 972.17814,-262.5781 971.71875,-262.6875 C 972.93392,-263.2514 976.72883,-263.8018 979.46875,-264.15625 C 982.47966,-264.54577 982.79006,-264.5539 984.84375,-264.46875 C 986.78814,-264.38815 987.85038,-264.21551 988.03125,-264.1875 C 988.15041,-264.37836 988.41402,-264.93281 988.96875,-265.0625 C 989.71301,-265.2365 994.11868,-265.71297 996.25,-265.875 C 998.01662,-266.00927 1000.6997,-266.00071 1002.625,-265.5 C 1002.945,-265.41679 1003.2283,-265.29873 1003.5,-265.1875 C 1005.4546,-264.38734 1011.4063,-261.625 1011.4063,-261.625 C 1011.4062,-261.625 1004.8151,-264.96501 1003.9688,-265.375 C 1003.7664,-265.47305 1003.3969,-265.57811 1002.9375,-265.6875 C 1004.1526,-266.2514 1007.9788,-266.77056 1010.7188,-267.125 C 1013.7297,-267.51453 1014.0713,-267.5539 1016.125,-267.46875 C 1018.2447,-267.38087 1019.4375,-267.15625 1019.4375,-267.15625 C 1019.4375,-267.15625 1019.3591,-267.80527 1020.4688,-268.0625 C 1021.2131,-268.23506 1025.6183,-268.68586 1027.75,-268.84375 C 1029.8106,-268.99635 1033.0929,-268.94052 1035,-268.15625 C 1036.955,-267.3523 1042.875,-264.65625 1042.875,-264.65625 C 1042.875,-264.65625 1036.3152,-267.93212 1035.4688,-268.34375 C 1035.2663,-268.44219 1034.897,-268.54597 1034.4375,-268.65625 C 1035.6529,-269.21779 1039.4494,-269.78403 1042.1875,-270.15625 C 1045.1965,-270.5653 1045.5102,-270.57183 1047.5625,-270.5 C 1049.5056,-270.43201 1050.5697,-270.33515 1050.75,-270.3125 C 1050.8688,-270.5069 1051.1346,-271.04131 1051.6875,-271.1875 C 1052.4293,-271.38362 1056.8186,-272.01628 1058.9375,-272.28125 C 1060.6939,-272.50086 1063.3428,-272.61356 1065.25,-272.25 C 1065.5669,-272.18959 1065.8558,-272.06062 1066.125,-271.96875 C 1068.0612,-271.30783 1073.9688,-269.03125 1073.9688,-269.03125 C 1073.9687,-269.03125 1067.4321,-271.8378 1066.5938,-272.1875 C 1066.3933,-272.27113 1066.0176,-272.36083 1065.5625,-272.4375 C 1066.7662,-273.08796 1070.5816,-273.80945 1073.2813,-274.4375 C 1076.248,-275.1277 1076.5702,-275.19257 1078.5938,-275.3125 C 1080.6824,-275.4363 1081.875,-275.34375 1081.875,-275.34375 C 1081.875,-275.34374 1081.788,-275.9758 1082.875,-276.375 C 1083.6042,-276.6428 1087.9222,-277.71297 1090,-278.1875 C 1092.0085,-278.64619 1095.1679,-279.2168 1097,-278.8125 C 1098.8781,-278.39804 1110.5782,-275.79687 1110.5782,-275.79687 C 1110.5782,-275.79687 1098.2507,-278.81953 1097.4375,-279.0625 C 1097.243,-279.12062 1096.8789,-279.16876 1096.4375,-279.1875 C 1097.6051,-279.99119 1099.9517,-280.8748 1102.5469,-281.89062 C 1104.2283,-282.5488 1103.4706,-282.26721 1105.3228,-282.89422 C 1107.0764,-283.48788 1107.8082,-283.90493 1107.9532,-284.00721 C 1108.2993,-284.21372 1107.5972,-284.12909 1107.409,-284.04961 z" +- style="fill:#000000;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;display:inline;filter:url(#filter7001);enable-background:new" +- sodipodi:nodetypes="czscsssscssssscsssscssssscsssscssssscsssscssssscsssscssssscsssscssccsssscscsscssscscsscsssscscsscssscscsscsssscscsscssscscsscsssscscsscssscscsscsssscscsscssscscsscsssscscsscssscscsscc" /> +- <path +- id="path8095" +- d="M 1082.625,-275.125 C 1084.498,-274.73152 1087.1211,-273.97945 1088.6563,-273.15625 C 1090.1915,-272.33306 1091.4785,-272.10025 1094.0313,-270.65625 C 1096.5579,-269.22699 1098.8271,-268.64929 1101,-268.125 C 1103.3476,-267.55858 1106.4354,-267.40977 1109.8438,-266.9375 C 1108.7549,-267.77725 1103.2364,-268.10995 1101.4375,-268.5 C 1099.6386,-268.89006 1097.5434,-269.51616 1094.8438,-270.8125 C 1092.1441,-272.10884 1091.3494,-272.61146 1089.0313,-273.5 C 1086.7131,-274.38854 1085.0269,-274.88314 1082.625,-275.125 z" +- style="fill:#000000;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;display:inline;filter:url(#filter6949);enable-background:new" /> +- <path +- id="path8097" +- d="M 1051.4688,-270 C 1053.3741,-269.42241 1055.9969,-268.38428 1057.5625,-267.40625 C 1059.1281,-266.42823 1060.4427,-266.04644 1063.0625,-264.28125 C 1065.6555,-262.53409 1068.0484,-261.57198 1070.3125,-260.6875 C 1072.7586,-259.73193 1075.9951,-259.03037 1079.7188,-257.625 C 1078.5292,-258.76284 1072.6557,-260.31175 1070.7813,-261 C 1068.9068,-261.68825 1066.6995,-262.5662 1063.9063,-264.28125 C 1061.113,-265.99629 1060.3327,-266.56515 1057.9688,-267.6875 C 1055.6047,-268.80984 1053.9121,-269.52205 1051.4688,-270 z" +- style="fill:#000000;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;display:inline;filter:url(#filter6961);enable-background:new" /> +- <path +- id="path8099" +- d="M 1020.2188,-266.84375 C 1022.1307,-266.20564 1024.8,-265.08839 1026.375,-264.03125 C 1027.9501,-262.9741 1029.2706,-262.52258 1031.9063,-260.625 C 1034.5149,-258.74679 1036.9347,-257.59497 1039.2188,-256.5625 C 1041.6865,-255.44705 1044.9833,-254.3892 1048.75,-252.71875 C 1047.5467,-253.94128 1041.5472,-256.03298 1039.6563,-256.84375 C 1037.7653,-257.65452 1035.5914,-258.73754 1032.7813,-260.59375 C 1029.9711,-262.44995 1029.1595,-263.07068 1026.7813,-264.3125 C 1024.403,-265.5543 1022.6706,-266.28819 1020.2188,-266.84375 z" +- style="fill:#000000;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;display:inline;filter:url(#filter6957);enable-background:new" /> +- <path +- id="path8101" +- d="M 1110.1719,-266.89063 C 1110.3227,-266.84207 1110.8599,-266.25963 1110.2813,-265.40625 C 1109.4712,-264.21166 1104.5764,-262.08196 1101.7188,-261.28125 C 1098.8739,-260.48413 1095.4287,-260.30351 1091.1563,-261.65625 C 1086.8547,-263.0182 1085.6866,-264.12497 1080.5,-265.96875 C 1085.164,-263.85358 1086.6953,-262.01642 1090.625,-260.625 C 1092.2457,-260.05113 1093.9921,-259.6854 1095.6875,-259.59375 C 1095.2424,-259.26812 1094.1572,-258.61045 1092.125,-258 C 1089.3295,-257.16031 1085.4759,-256.46622 1083.875,-256.375 C 1082.3604,-256.28868 1080.733,-256.88749 1080.4375,-257 C 1080.6042,-256.89692 1080.8107,-256.62266 1080.1875,-255.96875 C 1079.2882,-255.02512 1074.0401,-254.04575 1071.0625,-253.71875 C 1068.0982,-253.3932 1064.5409,-253.73471 1060.1563,-255.625 C 1056.1783,-257.33997 1054.8173,-258.54036 1050.75,-260.375 C 1050.75,-260.375 1050.75,-260.21875 1050.75,-260.21875 C 1054.3931,-258.12346 1056.034,-256.33548 1059.625,-254.65625 C 1061.3552,-253.84716 1063.2167,-253.24749 1065.0313,-252.9375 C 1064.4964,-252.65074 1063.4735,-252.22599 1061.5938,-251.90625 C 1058.7248,-251.41829 1054.7848,-251.09011 1053.1563,-251.15625 C 1052.3056,-251.19079 1051.4277,-251.34062 1050.75,-251.5625 C 1050.0652,-251.77738 1049.5603,-252.00717 1049.4375,-252.0625 C 1049.6069,-251.95529 1049.8686,-251.65962 1049.2188,-251.03125 C 1048.3091,-250.15163 1042.9727,-249.69487 1039.9688,-249.5625 C 1036.9783,-249.43071 1033.3799,-250.01313 1028.9688,-252.125 C 1024.5276,-254.25126 1023.3273,-255.5266 1018.0625,-257.90625 C 1022.7968,-255.30921 1024.349,-253.27715 1028.4063,-251.1875 C 1030.0796,-250.32565 1031.8915,-249.69325 1033.6563,-249.25 C 1033.193,-249.01668 1032.0669,-248.56186 1029.9688,-248.3125 C 1027.0825,-247.96952 1023.1342,-247.81962 1021.5,-247.9375 C 1019.9538,-248.049 1018.2688,-248.79446 1017.9688,-248.9375 C 1018.1379,-248.81721 1018.3826,-248.52702 1017.75,-247.9375 C 1016.8372,-247.08677 1011.5059,-246.67538 1008.5,-246.5625 C 1005.5075,-246.45013 1001.9103,-247.05293 997.5,-249.15625 C 993.49875,-251.06448 992.11197,-252.29408 988.03125,-254.25 C 988.03122,-254.25 988.03125,-254.09375 988.03125,-254.09375 C 991.68631,-251.88983 993.32546,-250.0412 996.9375,-248.1875 C 998.67779,-247.29435 1000.5745,-246.65923 1002.4063,-246.21875 C 1001.8663,-245.97045 1000.8282,-245.60342 998.9375,-245.375 C 996.05182,-245.02642 992.07145,-244.85405 990.4375,-244.96875 C 989.58405,-245.02865 988.71119,-245.22666 988.03125,-245.46875 C 987.34415,-245.70405 986.8419,-245.94101 986.71875,-246 C 986.88873,-245.88773 987.18323,-245.57775 986.53125,-244.96875 C 985.6186,-244.11625 980.25592,-243.67538 977.25,-243.5625 C 974.25754,-243.45013 970.65654,-244.09055 966.25,-246.15625 C 961.81347,-248.23603 960.60312,-249.48796 955.34375,-251.8125 C 960.07313,-249.26501 961.63449,-247.2347 965.6875,-245.1875 C 967.35905,-244.34317 969.17304,-243.72107 970.9375,-243.28125 C 970.47427,-243.04703 969.3478,-242.59718 967.25,-242.34375 C 964.36431,-241.99517 960.4138,-241.77423 958.78125,-241.875 C 957.23669,-241.97032 955.58094,-242.70385 955.28125,-242.84375 C 955.45024,-242.72522 955.66317,-242.4399 955.03125,-241.84375 C 954.11939,-240.98347 948.7846,-240.5135 945.78125,-240.375 C 942.7913,-240.2371 939.2138,-240.82568 934.8125,-242.84375 C 930.81942,-244.67464 929.44739,-245.87295 925.375,-247.75 C 925.37498,-247.75 925.375,-247.59375 925.375,-247.59375 C 929.02261,-245.46048 930.64533,-243.65888 934.25,-241.875 C 935.98675,-241.01549 937.85727,-240.42486 939.6875,-240 C 939.14803,-239.7471 938.13687,-239.35871 936.25,-239.09375 C 933.37022,-238.68939 929.41187,-238.44813 927.78125,-238.53125 C 926.92953,-238.57466 926.05355,-238.7398 925.375,-238.96875 C 924.68931,-239.19076 924.1854,-239.41214 924.0625,-239.46875 C 924.23209,-239.35976 924.4944,-239.0591 923.84375,-238.4375 C 922.93296,-237.56736 917.59354,-237.04598 914.59375,-236.875 C 911.60742,-236.70479 908.01994,-237.19077 903.625,-239.15625 C 899.20011,-241.13513 898.01904,-242.38444 892.78125,-244.53125 C 897.49122,-242.14358 899.05142,-240.14252 903.09375,-238.1875 C 904.7609,-237.38119 906.55418,-236.79092 908.3125,-236.40625 C 907.85087,-236.15755 906.7155,-235.694 904.625,-235.375 C 901.7494,-234.93624 897.8446,-234.6419 896.21875,-234.6875 C 894.68052,-234.73062 892.98595,-235.43272 892.6875,-235.5625 C 892.85583,-235.44968 893.09807,-235.14875 892.46875,-234.53125 C 891.56063,-233.64015 886.2658,-233.003 883.28125,-232.71875 C 880.31007,-232.43577 876.70783,-232.89455 872.34375,-234.65625 C 868.38441,-236.25456 867.0146,-237.45112 863,-238.96875 C 863.00003,-238.96875 863,-238.8125 863,-238.8125 C 866.5959,-237.00115 868.23831,-235.23017 871.8125,-233.65625 C 873.53457,-232.8979 875.39998,-232.3673 877.21875,-232.03125 C 876.68266,-231.75217 875.65217,-231.34362 873.78125,-230.96875 C 870.92586,-230.39665 866.99183,-229.94936 865.375,-229.9375 C 864.53049,-229.93129 863.66892,-230.01844 863,-230.1875 C 862.32409,-230.34901 861.83991,-230.51673 861.71875,-230.5625 C 861.88597,-230.46848 862.14142,-230.17902 861.5,-229.5 C 860.60213,-228.54948 855.31352,-227.58292 852.375,-227.0625 C 849.44966,-226.54441 845.94285,-226.68826 841.65625,-228.09375 C 837.34045,-229.50882 836.18348,-230.62369 831.09375,-232.0625 C 835.6706,-230.31149 837.1823,-228.50244 841.125,-227.0625 C 842.75108,-226.46861 844.49385,-226.10685 846.21875,-225.90625 C 845.7659,-225.60923 844.66397,-225.02286 842.625,-224.4375 C 839.82028,-223.63233 835.98614,-222.86167 834.40625,-222.6875 C 832.9115,-222.5227 831.29002,-223.00431 831,-223.09375 C 831.16356,-223.00368 831.39278,-222.73382 830.78125,-222.03125 C 829.89878,-221.0174 824.73673,-219.6596 821.84375,-218.96875 C 818.96373,-218.28097 815.50815,-218.20873 811.28125,-219.40625 C 807.4464,-220.4927 806.10867,-221.47862 802.21875,-222.53125 C 802.21874,-222.53125 802.21875,-222.375 802.21875,-222.375 C 805.70293,-220.98015 807.28816,-219.4556 810.75,-218.34375 C 812.41793,-217.80803 814.20578,-217.55701 815.96875,-217.46875 C 815.44911,-217.11663 814.46836,-216.55423 812.65625,-215.9375 C 809.89059,-214.99625 806.06601,-214.00213 804.5,-213.78125 C 803.68206,-213.66586 802.8669,-213.65842 802.21875,-213.75 C 801.56379,-213.83321 801.08615,-213.96827 800.96875,-214 C 801.13079,-213.92536 801.40274,-213.65956 800.78125,-212.90625 C 799.91125,-211.85172 794.77162,-210.247 791.90625,-209.46875 C 789.05372,-208.69399 785.64713,-208.51055 781.46875,-209.5625 C 777.26192,-210.62163 776.11206,-211.60416 771.125,-212.71875 C 775.60954,-211.25929 777.09435,-209.58352 780.9375,-208.46875 C 782.52254,-208.00898 784.22429,-207.8305 785.90625,-207.78125 C 785.46468,-207.44449 784.39374,-206.75352 782.40625,-206 C 779.67232,-204.96351 775.95427,-203.83731 774.40625,-203.5625 C 772.94163,-203.30248 771.34667,-203.67904 771.0625,-203.75 C 771.22275,-203.67035 771.44294,-203.42902 770.84375,-202.6875 C 769.97909,-201.61744 764.92723,-199.86935 762.09375,-199 C 759.27295,-198.13453 755.88625,-197.84369 751.75,-198.78125 C 747.99741,-199.63186 746.70215,-200.49772 742.875,-201.375 C 742.875,-201.375 742.875,-201.21875 742.875,-201.21875 C 746.30296,-199.98096 747.86241,-198.58645 751.25,-197.6875 C 752.88216,-197.25436 754.61704,-197.10449 756.34375,-197.125 C 755.83482,-196.74083 754.867,-196.10318 753.09375,-195.375 C 750.38741,-194.26366 746.65742,-193.06719 745.125,-192.75 C 744.3246,-192.58431 743.51269,-192.53138 742.875,-192.59375 C 742.875,-192.59375 742.875,-192.07823 742.875,-191.67146 C 742.875,-191.40639 742.875,-191.1875 742.875,-191.1875 C 743.10145,-191.33218 743.32391,-191.46011 743.59375,-191.5625 C 744.67427,-191.97248 745.76536,-191.77827 749.59375,-193.25 C 753.42218,-194.72174 754.81787,-195.25498 755.5,-195.65625 C 756.1796,-196.05603 757.11165,-196.53562 757.71875,-197.1875 C 759.5456,-197.32525 761.2895,-197.68073 762.65625,-198.1875 C 765.62437,-199.28802 767.53162,-199.99369 769.4375,-200.65625 C 771.34336,-201.31879 771.79159,-202.07112 772.84375,-202.4375 C 773.9353,-202.81761 775.03886,-202.60288 778.90625,-203.96875 C 782.7737,-205.33461 784.18941,-205.79583 784.875,-206.1875 C 785.57609,-206.58802 786.57581,-207.12048 787.1875,-207.78125 C 789.1583,-207.83591 791.00435,-208.16588 792.46875,-208.65625 C 795.47023,-209.66133 797.3949,-210.27796 799.3125,-210.90625 C 800.8511,-211.41035 801.48652,-211.95302 802.21875,-212.34375 C 802.44891,-212.47806 802.69449,-212.59748 802.96875,-212.6875 C 804.06698,-213.04798 805.1502,-212.76887 809.0625,-214 C 812.97483,-215.23113 814.42855,-215.67295 815.125,-216.03125 C 815.81888,-216.38822 816.75515,-216.82386 817.375,-217.4375 C 819.24021,-217.46016 821.01081,-217.70433 822.40625,-218.125 C 825.43668,-219.03854 827.39863,-219.5551 829.34375,-220.09375 C 831.28886,-220.63239 831.76993,-221.35827 832.84375,-221.65625 C 833.95776,-221.9654 835.06369,-221.64886 839.03125,-222.6875 C 842.99886,-223.72613 844.44883,-224.12023 845.15625,-224.4375 C 845.89112,-224.76709 846.97008,-225.19122 847.59375,-225.8125 C 849.59149,-225.6965 851.45118,-225.83259 852.9375,-226.1875 C 856.01561,-226.9225 858.02094,-227.28844 860,-227.6875 C 861.58792,-228.00768 862.24429,-228.47805 863,-228.78125 C 863.23757,-228.88805 863.46695,-228.97401 863.75,-229.03125 C 864.88347,-229.26044 866.05448,-228.82232 870.09375,-229.53125 C 874.13308,-230.24018 875.594,-230.45834 876.3125,-230.71875 C 877.02836,-230.97819 878.01678,-231.28599 878.65625,-231.8125 C 880.58052,-231.57301 882.40413,-231.58797 883.84375,-231.8125 C 886.97008,-232.30012 888.9983,-232.51317 891,-232.78125 C 893.00171,-233.04932 893.48869,-233.72639 894.59375,-233.875 C 895.74014,-234.02918 896.86967,-233.57343 900.9375,-234.09375 C 905.00534,-234.61407 906.49763,-234.78948 907.21875,-235.03125 C 907.95585,-235.27839 909.01684,-235.61748 909.65625,-236.15625 C 911.70632,-235.82072 913.63003,-235.75829 915.15625,-235.9375 C 918.29856,-236.30646 920.33619,-236.49686 922.34375,-236.71875 C 923.95451,-236.89677 924.60842,-237.32695 925.375,-237.5625 C 925.61594,-237.64802 925.86912,-237.7181 926.15625,-237.75 C 927.30603,-237.87772 928.45754,-237.40335 932.53125,-237.875 C 936.60499,-238.34665 938.09034,-238.4856 938.8125,-238.71875 C 939.53196,-238.95102 940.51274,-239.19221 941.15625,-239.6875 C 943.09262,-239.35404 944.92631,-239.28326 946.375,-239.4375 C 949.52102,-239.77245 951.55256,-239.95609 953.5625,-240.15625 C 955.57246,-240.35639 956.04664,-240.98264 957.15625,-241.09375 C 958.30739,-241.20903 959.45268,-240.72869 963.53125,-241.15625 C 967.60986,-241.58381 969.12011,-241.71834 969.84375,-241.9375 C 970.5829,-242.16136 971.63947,-242.45075 972.28125,-242.96875 C 974.33835,-242.57008 976.28312,-242.47535 977.8125,-242.625 C 980.96123,-242.9331 982.98834,-243.09825 985,-243.28125 C 986.61407,-243.42807 987.2631,-243.8418 988.03125,-244.0625 C 988.27267,-244.14336 988.52478,-244.19241 988.8125,-244.21875 C 989.96461,-244.3242 991.10546,-243.826 995.1875,-244.21875 C 999.26958,-244.6115 1000.7764,-244.74959 1001.5,-244.96875 C 1002.2209,-245.18708 1003.1997,-245.41645 1003.8438,-245.90625 C 1005.7818,-245.55626 1007.6126,-245.45187 1009.0625,-245.59375 C 1012.2112,-245.90185 1014.2383,-246.067 1016.25,-246.25 C 1018.2616,-246.43299 1018.7642,-247.08802 1019.875,-247.1875 C 1021.0273,-247.29073 1022.1672,-246.80267 1026.25,-247.1875 C 1030.3329,-247.57232 1031.8387,-247.6885 1032.5625,-247.90625 C 1033.3018,-248.12868 1034.3581,-248.42074 1035,-248.9375 C 1037.0574,-248.53573 1039.0029,-248.43417 1040.5313,-248.59375 C 1043.6779,-248.92227 1045.7084,-249.11645 1047.7188,-249.3125 C 1049.3318,-249.46979 1049.9844,-249.94398 1050.75,-250.1875 C 1050.9907,-250.27554 1051.2132,-250.30887 1051.5,-250.34375 C 1052.6483,-250.48345 1053.8167,-250.00384 1057.875,-250.59375 C 1061.9333,-251.18367 1063.4368,-251.37089 1064.1563,-251.625 C 1064.873,-251.87816 1065.8308,-252.18307 1066.4688,-252.71875 C 1068.3885,-252.50681 1070.1887,-252.56734 1071.625,-252.8125 C 1074.7441,-253.3449 1076.7366,-253.74111 1078.7188,-254.125 C 1080.7009,-254.50887 1081.1931,-255.16465 1082.2813,-255.40625 C 1083.4101,-255.65691 1084.5516,-255.28996 1088.5313,-256.28125 C 1092.5109,-257.27253 1093.9609,-257.70055 1094.6563,-258.0625 C 1095.3786,-258.43851 1096.4182,-258.93308 1097.0313,-259.59375 C 1098.9943,-259.6058 1100.825,-259.8848 1102.25,-260.4375 C 1105.2012,-261.58211 1107.1232,-262.30692 1108.9375,-263.1875 C 1110.3932,-263.89403 1111.2723,-264.87391 1111.4844,-265.17188 C 1111.6966,-265.46984 1111.5962,-265.91718 1111.6223,-265.93863 C 1111.6652,-265.97387 1111.9416,-266.0236 1112.1013,-266.36707 C 1112.9602,-268.21415 1114.4223,-272.01166 1114.5365,-272.69652 C 1114.6502,-273.37868 1114.7003,-274.04426 1114.751,-274.44149 C 1114.7804,-274.67101 1114.6043,-275.30693 1114.6264,-275.36553 C 1114.6573,-275.44759 1114.9309,-275.63081 1114.9863,-275.88024 C 1115.2526,-277.07857 1115.0752,-278.07153 1114.8612,-279.48917 C 1114.6472,-280.90681 1113.8775,-284.11131 1113.2243,-284.96543 C 1112.5654,-285.82715 1112.0014,-285.9766 1111.4764,-285.96609 C 1111.2678,-285.69633 1111.6132,-285.703 1111.639,-285.65348 C 1112.3196,-285.60269 1112.573,-285.28484 1113.0582,-284.75686 C 1113.5434,-284.22888 1114.501,-280.8173 1114.6376,-279.36691 C 1114.7742,-277.91652 1114.8276,-276.50671 1114.5496,-275.89827 C 1114.2715,-275.28982 1113.6054,-275.46963 1113.313,-275.40375 C 1113.844,-275.21786 1114.2038,-275.19053 1114.2654,-274.34607 C 1114.3247,-273.53269 1114.1322,-272.70638 1113.7456,-271.54045 C 1113.3544,-270.36044 1111.9004,-267.19047 1111.4599,-266.94168 C 1111.0076,-266.68617 1110.5075,-266.75969 1110.1719,-266.89063 z" +- style="fill:#000000;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;display:inline;filter:url(#filter6997);enable-background:new" +- sodipodi:nodetypes="cssscscsscsssccscssssssscscsscsssscscssssssscscsscsssscscssssssscscsscsssscscssssssscscsscsssscscssssssscscsscsssccscsscscssscssssscsssssscssssscsssssscssssscsssssscssssscsssssscssssscsssssscssssscsszsszssszzcczzzczzzc" /> +- <path +- id="path8103" +- d="M 988.75,-263.84375 C 990.66161,-263.20935 993.30027,-262.08534 994.875,-261.03125 C 996.44977,-259.97716 997.7711,-259.54873 1000.4063,-257.65625 C 1003.0145,-255.78311 1005.4332,-254.64103 1007.7188,-253.59375 C 1010.1881,-252.46228 1013.4709,-251.43901 1017.25,-249.65625 C 1016.0428,-250.91465 1010.111,-253.0207 1008.2188,-253.84375 C 1006.3266,-254.66679 1004.0908,-255.77424 1001.2813,-257.625 C 998.47169,-259.47575 997.65906,-260.10654 995.28125,-261.34375 C 992.90343,-262.58094 991.20137,-263.29295 988.75,-263.84375 z" +- style="fill:#000000;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;display:inline;filter:url(#filter6953);enable-background:new" /> +- <path +- id="path8105" +- d="M 957.5,-260.78125 C 959.41,-260.16315 962.08288,-259.07191 963.65625,-258.03125 C 965.22964,-256.99059 966.55233,-256.54873 969.1875,-254.65625 C 971.79573,-252.7831 974.21442,-251.64104 976.5,-250.59375 C 978.96931,-249.46228 982.25213,-248.439 986.03125,-246.65625 C 984.82397,-247.91465 978.82971,-250.05195 976.9375,-250.875 C 975.04533,-251.69804 972.84084,-252.8055 970.03125,-254.65625 C 967.22167,-256.507 966.4383,-257.09557 964.0625,-258.3125 C 961.68672,-259.52941 959.94929,-260.25135 957.5,-260.78125 z" +- style="fill:#000000;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;display:inline;filter:url(#filter6993);enable-background:new" /> +- <path +- id="path8107" +- d="M 926.09375,-257.375 C 928.00147,-256.77755 930.64723,-255.71116 932.21875,-254.6875 C 933.79025,-253.66385 935.08897,-253.24779 937.71875,-251.40625 C 940.32166,-249.58352 942.74762,-248.43405 945.03125,-247.40625 C 947.49845,-246.29584 950.7866,-245.31302 954.5625,-243.5625 C 953.35627,-244.8106 947.3906,-246.88059 945.5,-247.6875 C 943.60942,-248.4944 941.39758,-249.57854 938.59375,-251.375 C 935.7899,-253.17144 934.96671,-253.77751 932.59375,-254.96875 C 930.22078,-256.15999 928.54013,-256.87158 926.09375,-257.375 z" +- style="fill:#000000;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;display:inline;filter:url(#filter6989);enable-background:new" /> +- <path +- id="path8109" +- d="M 894.90625,-253.5625 C 896.80838,-253.00895 899.49326,-251.97363 901.0625,-250.96875 C 902.63173,-249.96388 903.93651,-249.56011 906.5625,-247.75 C 909.16162,-245.95836 911.56284,-244.87811 913.84375,-243.875 C 916.30803,-242.79126 919.60359,-241.83471 923.375,-240.125 C 922.1702,-241.36007 916.20084,-243.36978 914.3125,-244.15625 C 912.42418,-244.94272 910.2373,-245.98705 907.4375,-247.75 C 904.63773,-249.51294 903.83831,-250.11836 901.46875,-251.28125 C 899.09918,-252.44413 897.3455,-253.11537 894.90625,-253.5625 z" +- style="fill:#000000;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;display:inline;filter:url(#filter6985);enable-background:new" /> +- <path +- id="path8111" +- d="M 863.71875,-248.65625 C 865.59937,-248.22716 868.22302,-247.27587 869.78125,-246.34375 C 871.33948,-245.41164 872.63358,-245.08599 875.25,-243.34375 C 877.83971,-241.61931 880.23067,-240.63573 882.5,-239.71875 C 884.95176,-238.72806 888.23959,-237.84168 892,-236.21875 C 890.79869,-237.42609 884.84751,-239.28484 882.96875,-240 C 881.09,-240.71517 878.88335,-241.68442 876.09375,-243.375 C 873.30412,-245.06557 872.50914,-245.60322 870.15625,-246.65625 C 867.80333,-247.70926 866.13041,-248.36873 863.71875,-248.65625 z" +- style="fill:#000000;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;display:inline;filter:url(#filter6965);enable-background:new" /> +- <path +- id="path8113" +- d="M 833.15625,-241.375 C 835.00461,-241.07856 837.6257,-240.39868 839.15625,-239.59375 C 840.68683,-238.78882 841.96999,-238.53802 844.53125,-237.0625 C 847.06629,-235.60204 849.42193,-234.73741 851.65625,-234 C 854.07024,-233.20332 857.31336,-232.53311 861.03125,-231.15625 C 859.84354,-232.28498 853.94353,-233.746 852.09375,-234.3125 C 850.24398,-234.879 848.09033,-235.68642 845.34375,-237.15625 C 842.59718,-238.62608 841.84239,-239.07653 839.53125,-239.9375 C 837.2201,-240.79845 835.52654,-241.25759 833.15625,-241.375 z" +- style="fill:#000000;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;display:inline;filter:url(#filter6981);enable-background:new" /> +- <path +- id="path8115" +- d="M 802.90625,-232.3125 C 804.72845,-232.10123 807.27201,-231.51193 808.78125,-230.78125 C 810.2905,-230.05059 811.53693,-229.85127 814.0625,-228.5 C 816.56226,-227.16254 818.89404,-226.45157 821.09375,-225.84375 C 823.47028,-225.18708 826.65839,-224.77087 830.3125,-223.65625 C 829.14515,-224.70121 823.38362,-225.75954 821.5625,-226.21875 C 819.74139,-226.67796 817.61025,-227.34571 814.90625,-228.65625 C 812.20222,-229.96677 811.43519,-230.37615 809.15625,-231.125 C 806.8773,-231.87383 805.243,-232.30431 802.90625,-232.3125 z" +- style="fill:#000000;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;display:inline;filter:url(#filter6977);enable-background:new" /> +- <path +- id="path8117" +- d="M 773.1875,-222.1875 C 774.99859,-222.0088 777.50809,-221.52244 779,-220.84375 C 780.49194,-220.16506 781.7534,-220.04553 784.25,-218.78125 C 786.72107,-217.52987 789.04005,-216.88511 791.21875,-216.34375 C 793.57262,-215.75887 796.71009,-215.44623 800.3125,-214.5 C 799.16166,-215.49116 793.45999,-216.2833 791.65625,-216.6875 C 789.85253,-217.0917 787.74072,-217.70866 785.0625,-218.9375 C 782.38432,-220.16634 781.65905,-220.54839 779.40625,-221.21875 C 777.15346,-221.88909 775.50998,-222.22107 773.1875,-222.1875 z" +- style="fill:#000000;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;display:inline;filter:url(#filter6973);enable-background:new" /> +- <path +- id="path8119" +- d="M 743.5625,-211.1875 C 745.35531,-211.05839 747.83563,-210.63785 749.3125,-210 C 750.7894,-209.36215 752.0286,-209.25844 754.5,-208.0625 C 756.94618,-206.87878 759.22054,-206.31584 761.375,-205.84375 C 763.70267,-205.33372 766.7946,-205.16311 770.375,-204.28125 C 769.23121,-205.25185 763.62741,-205.8719 761.84375,-206.21875 C 760.06008,-206.56559 757.9609,-207.10631 755.3125,-208.25 C 752.66409,-209.39368 751.91755,-209.76631 749.6875,-210.375 C 747.45742,-210.98368 745.86156,-211.28466 743.5625,-211.1875 z" +- style="fill:#000000;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;display:inline;filter:url(#filter6969);enable-background:new" /> +- <g +- id="g8121" +- style="fill:#ffffff;fill-opacity:1;filter:url(#filter7345)"> +- <path +- sodipodi:nodetypes="czzzczzc" +- id="path8123" +- d="M 744.9375,-212.11731 C 744.9375,-212.11731 752.15979,-215.34049 754,-215.61731 C 755.84021,-215.89413 757.35225,-215.62054 760,-215.05481 C 762.64775,-214.48908 768.7357,-212.83963 771.1875,-211.67981 C 773.6393,-210.51999 776.5,-208.11731 776.5,-208.11731 C 776.5,-208.11731 769.35356,-210.8975 766.3125,-211.67981 C 763.27144,-212.46212 758.66789,-213.76355 755.9375,-213.99231 C 753.20711,-214.22107 744.9375,-212.11731 744.9375,-212.11731 z" +- style="fill:#ffffff;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1" /> +- <path +- sodipodi:nodetypes="czzzczzc" +- id="path8125" +- d="M 735.46875,-206.95416 C 735.46875,-206.95416 739.12854,-209.17734 740.96875,-209.45416 C 742.80896,-209.73098 744.6335,-209.20739 747.28125,-208.64166 C 749.929,-208.07593 756.01695,-206.42648 758.46875,-205.26666 C 760.92055,-204.10684 765.03125,-203.14166 765.03125,-203.14166 C 765.03125,-203.14166 756.63481,-204.48435 753.59375,-205.26666 C 750.55269,-206.04897 745.63664,-207.6004 742.90625,-207.82916 C 740.17586,-208.05792 735.46875,-206.95416 735.46875,-206.95416 z" +- style="fill:#ffffff;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;display:inline;enable-background:new" /> +- <path +- sodipodi:nodetypes="czzzczzc" +- id="path8127" +- d="M 759.85042,-217.61116 C 759.85042,-217.61116 768.39412,-220.90973 770.2482,-221.06902 C 772.10229,-221.22832 773.88986,-220.58982 776.4963,-219.85694 C 779.10274,-219.12406 785.07354,-217.091 787.44666,-215.77769 C 789.81978,-214.46438 793.86083,-213.23987 793.86083,-213.23987 C 793.86083,-213.23987 785.5667,-215.11352 782.58152,-216.08754 C 779.59633,-217.06156 774.78883,-218.92232 772.0785,-219.32416 C 769.36817,-219.726 759.85042,-217.61116 759.85042,-217.61116 z" +- style="fill:#ffffff;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;display:inline;enable-background:new" /> +- <path +- sodipodi:nodetypes="czzzczzc" +- id="path8129" +- d="M 775.19813,-223.2266 C 775.19813,-223.2266 782.96946,-226.00904 784.82644,-226.13009 C 786.68341,-226.25113 788.45744,-225.57592 791.04822,-224.78947 C 793.63899,-224.00302 799.56662,-221.8473 801.91216,-220.48535 C 804.25771,-219.1234 808.27265,-217.81585 808.27265,-217.81585 C 808.27265,-217.81585 800.01892,-219.86008 797.05444,-220.89543 C 794.08997,-221.93078 789.32185,-223.89024 786.62038,-224.34786 C 783.91891,-224.80549 775.19813,-223.2266 775.19813,-223.2266 z" +- style="fill:#ffffff;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;display:inline;enable-background:new" /> +- <path +- inkscape:transform-center-y="-4.3190906" +- inkscape:transform-center-x="13.852145" +- sodipodi:nodetypes="czzzczzc" +- id="path8131" +- d="M 789.64298,-227.95417 C 789.64298,-227.95417 798.32554,-231.47448 800.18452,-231.55952 C 802.04349,-231.64455 803.8041,-230.9351 806.37915,-230.09859 C 808.9542,-229.2621 814.83894,-226.99193 817.15766,-225.58479 C 819.47638,-224.17764 823.46523,-222.79255 823.46523,-222.79255 C 823.46523,-222.79255 815.25266,-224.99632 812.3088,-226.08891 C 809.36494,-227.1815 804.63568,-229.23299 801.94358,-229.74288 C 799.25149,-230.25276 789.64298,-227.95417 789.64298,-227.95417 z" +- style="fill:#ffffff;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;display:inline;enable-background:new" /> +- <path +- inkscape:transform-center-y="-4.3190906" +- inkscape:transform-center-x="13.852145" +- sodipodi:nodetypes="czzzczzc" +- id="path8133" +- d="M 804.49513,-233.32948 C 804.49513,-233.32948 812.30269,-235.91229 814.16167,-235.99733 C 816.02064,-236.08236 817.78125,-235.37291 820.3563,-234.5364 C 822.93135,-233.69991 828.81609,-231.42974 831.13481,-230.0226 C 833.45353,-228.61545 837.44238,-227.23036 837.44238,-227.23036 C 837.44238,-227.23036 829.22981,-229.43413 826.28595,-230.52672 C 823.34209,-231.61931 818.61283,-233.6708 815.92073,-234.18069 C 813.22864,-234.69057 804.49513,-233.32948 804.49513,-233.32948 z" +- style="fill:#ffffff;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;display:inline;enable-background:new" /> +- <path +- inkscape:transform-center-y="-4.3190906" +- inkscape:transform-center-x="13.852145" +- sodipodi:nodetypes="czzzczzc" +- id="path8135" +- d="M 819.55763,-237.57948 C 819.55763,-237.57948 828.11519,-240.16229 829.97417,-240.24733 C 831.83314,-240.33236 833.59375,-239.62291 836.1688,-238.7864 C 838.74385,-237.94991 844.62859,-235.67974 846.94731,-234.2726 C 849.26603,-232.86545 853.25488,-231.48036 853.25488,-231.48036 C 853.25488,-231.48036 845.04231,-233.68413 842.09845,-234.77672 C 839.15459,-235.86931 834.42533,-237.9208 831.73323,-238.43069 C 829.04114,-238.94057 819.55763,-237.57948 819.55763,-237.57948 z" +- style="fill:#ffffff;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;display:inline;enable-background:new" /> +- <path +- inkscape:transform-center-y="-4.9269042" +- inkscape:transform-center-x="13.64141" +- sodipodi:nodetypes="czzzczzc" +- id="path8137" +- d="M 836.23395,-242.60125 C 836.23395,-242.60125 843.20097,-244.58848 845.06179,-244.56882 C 846.9226,-244.54915 848.64052,-243.7418 851.16444,-242.76177 C 853.68837,-241.78177 859.4361,-239.18419 861.672,-237.64886 C 863.9079,-236.11351 867.81253,-234.50625 867.81253,-234.50625 C 867.81253,-234.50625 859.73692,-237.16847 856.85917,-238.42491 C 853.98143,-239.68136 849.37505,-241.99561 846.71589,-242.65612 C 844.05674,-243.31661 836.23395,-242.60125 836.23395,-242.60125 z" +- style="fill:#ffffff;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;display:inline;enable-background:new" /> +- <path +- inkscape:transform-center-y="-5.1542119" +- inkscape:transform-center-x="13.55068" +- sodipodi:nodetypes="czzzczzc" +- id="path8139" +- d="M 850.73028,-246.00461 C 850.73028,-246.00461 858.41812,-248.03229 860.2781,-247.97315 C 862.13807,-247.914 863.83848,-247.07036 866.34103,-246.03699 C 868.84358,-245.00365 874.5349,-242.28467 876.73771,-240.70224 C 878.94053,-239.11979 882.81016,-237.43004 882.81016,-237.43004 C 882.81016,-237.43004 874.79287,-240.26302 871.94244,-241.58026 C 869.09201,-242.89749 864.53578,-245.30898 861.89124,-246.02576 C 859.2467,-246.74254 850.73028,-246.00461 850.73028,-246.00461 z" +- style="fill:#ffffff;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;display:inline;enable-background:new" /> +- <path +- inkscape:transform-center-y="-5.4740887" +- inkscape:transform-center-x="13.41151" +- sodipodi:nodetypes="czzzczzc" +- id="path8141" +- d="M 864.82496,-249.21081 C 864.82496,-249.21081 872.99448,-251.17987 874.85184,-251.06477 C 876.70919,-250.94965 878.38342,-250.05521 880.85374,-248.94698 C 883.32405,-247.83877 888.93094,-244.94971 891.08512,-243.30167 C 893.2393,-241.65363 897.05632,-239.84815 897.05632,-239.84815 C 897.05632,-239.84815 889.12793,-242.92121 886.31845,-244.32365 C 883.50896,-245.72609 879.02739,-248.27364 876.40562,-249.06971 C 873.78386,-249.86577 864.82496,-249.21081 864.82496,-249.21081 z" +- style="fill:#ffffff;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;display:inline;enable-background:new" /> +- <path +- inkscape:transform-center-y="-5.79376" +- inkscape:transform-center-x="13.258805" +- sodipodi:nodetypes="czzzczzc" +- id="path8143" +- d="M 881.38485,-251.60282 C 881.38485,-251.60282 889.47021,-253.51091 891.32322,-253.33946 C 893.17622,-253.16799 894.82252,-252.22313 897.25804,-251.04038 C 899.69357,-249.85767 905.21013,-246.79968 907.31327,-245.08699 C 909.41641,-243.37429 913.17684,-241.45373 913.17684,-241.45373 C 913.17684,-241.45373 905.34544,-244.76613 902.57984,-246.25323 C 899.81423,-247.74035 895.41209,-250.42282 892.8157,-251.29814 C 890.21933,-252.17345 881.38485,-251.60282 881.38485,-251.60282 z" +- style="fill:#ffffff;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;display:inline;enable-background:new" /> +- <path +- inkscape:transform-center-y="-5.7433893" +- inkscape:transform-center-x="13.28378" +- sodipodi:nodetypes="czzzczzc" +- id="path8145" +- d="M 896.58415,-254.34724 C 896.58415,-254.34724 904.22581,-255.77494 906.07962,-255.61239 C 907.93342,-255.44983 909.58424,-254.51289 912.02541,-253.34186 C 914.46659,-252.17086 919.99779,-249.1394 922.10913,-247.43684 C 924.22047,-245.73426 927.99009,-243.83179 927.99009,-243.83179 C 927.99009,-243.83179 920.14286,-247.10653 917.37014,-248.58034 C 914.59743,-250.05414 910.18245,-252.71543 907.58189,-253.57827 C 904.98134,-254.44109 896.58415,-254.34724 896.58415,-254.34724 z" +- style="fill:#ffffff;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;display:inline;enable-background:new" /> +- <path +- inkscape:transform-center-y="-5.7433893" +- inkscape:transform-center-x="13.28378" +- sodipodi:nodetypes="czzzczzc" +- id="path8147" +- d="M 911.45328,-255.98544 C 911.45328,-255.98544 920.09494,-257.53814 921.94875,-257.37559 C 923.80255,-257.21303 925.45337,-256.27609 927.89454,-255.10506 C 930.33572,-253.93406 935.86692,-250.9026 937.97826,-249.20004 C 940.0896,-247.49746 943.85922,-245.59499 943.85922,-245.59499 C 943.85922,-245.59499 936.01199,-248.86973 933.23927,-250.34354 C 930.46656,-251.81734 926.05158,-254.47863 923.45102,-255.34147 C 920.85047,-256.20429 911.45328,-255.98544 911.45328,-255.98544 z" +- style="fill:#ffffff;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;display:inline;enable-background:new" /> +- <path +- inkscape:transform-center-y="-5.7433893" +- inkscape:transform-center-x="13.28378" +- sodipodi:nodetypes="czzzczzc" +- id="path8149" +- d="M 927.70328,-258.29794 C 927.70328,-258.29794 935.34494,-259.16314 937.19875,-259.00059 C 939.05255,-258.83803 940.70337,-257.90109 943.14454,-256.73006 C 945.58572,-255.55906 951.11692,-252.5276 953.22826,-250.82504 C 955.3396,-249.12246 959.10922,-247.21999 959.10922,-247.21999 C 959.10922,-247.21999 951.26199,-250.49473 948.48927,-251.96854 C 945.71656,-253.44234 941.30158,-256.10363 938.70102,-256.96647 C 936.10047,-257.82929 927.70328,-258.29794 927.70328,-258.29794 z" +- style="fill:#ffffff;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;display:inline;enable-background:new" /> +- <path +- inkscape:transform-center-y="-5.7433893" +- inkscape:transform-center-x="13.28378" +- sodipodi:nodetypes="czzzczzc" +- id="path8151" +- d="M 942.82828,-259.48544 C 942.82828,-259.48544 951.40744,-260.97564 953.26125,-260.81309 C 955.11505,-260.65053 956.76587,-259.71359 959.20704,-258.54256 C 961.64822,-257.37156 967.17942,-254.3401 969.29076,-252.63754 C 971.4021,-250.93496 975.17172,-249.03249 975.17172,-249.03249 C 975.17172,-249.03249 967.32449,-252.30723 964.55177,-253.78104 C 961.77906,-255.25484 957.36408,-257.91613 954.76352,-258.77897 C 952.16297,-259.64179 942.82828,-259.48544 942.82828,-259.48544 z" +- style="fill:#ffffff;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;display:inline;enable-background:new" /> +- <path +- inkscape:transform-center-y="-5.7433893" +- inkscape:transform-center-x="13.28378" +- sodipodi:nodetypes="czzzczzc" +- id="path8153" +- d="M 959.07828,-261.54794 C 959.07828,-261.54794 966.90744,-262.35064 968.76125,-262.18809 C 970.61505,-262.02553 972.26587,-261.08859 974.70704,-259.91756 C 977.14822,-258.74656 982.67942,-255.7151 984.79076,-254.01254 C 986.9021,-252.30996 990.67172,-250.40749 990.67172,-250.40749 C 990.67172,-250.40749 982.82449,-253.68223 980.05177,-255.15604 C 977.27906,-256.62984 972.86408,-259.29113 970.26352,-260.15397 C 967.66297,-261.01679 959.07828,-261.54794 959.07828,-261.54794 z" +- style="fill:#ffffff;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;display:inline;enable-background:new" /> +- <path +- inkscape:transform-center-y="-5.7433893" +- inkscape:transform-center-x="13.28378" +- sodipodi:nodetypes="czzzczzc" +- id="path8155" +- d="M 974.45328,-262.79794 C 974.45328,-262.79794 982.84494,-263.97564 984.69875,-263.81309 C 986.55255,-263.65053 988.20337,-262.71359 990.64454,-261.54256 C 993.08572,-260.37156 998.61692,-257.3401 1000.7283,-255.63754 C 1002.8396,-253.93496 1006.6092,-252.03249 1006.6092,-252.03249 C 1006.6092,-252.03249 998.76199,-255.30723 995.98927,-256.78104 C 993.21656,-258.25484 988.80158,-260.91613 986.20102,-261.77897 C 983.60047,-262.64179 974.45328,-262.79794 974.45328,-262.79794 z" +- style="fill:#ffffff;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;display:inline;enable-background:new" /> +- <path +- inkscape:transform-center-y="-5.7433893" +- inkscape:transform-center-x="13.28378" +- sodipodi:nodetypes="czzzczzc" +- id="path8157" +- d="M 990.64078,-264.86044 C 990.64078,-264.86044 997.53244,-265.85064 999.38625,-265.68809 C 1001.2401,-265.52553 1002.8909,-264.58859 1005.332,-263.41756 C 1007.7732,-262.24656 1013.3044,-259.2151 1015.4158,-257.51254 C 1017.5271,-255.80996 1021.2967,-253.90749 1021.2967,-253.90749 C 1021.2967,-253.90749 1013.4495,-257.18223 1010.6768,-258.65604 C 1007.9041,-260.12984 1003.4891,-262.79113 1000.8885,-263.65397 C 998.28797,-264.51679 990.64078,-264.86044 990.64078,-264.86044 z" +- style="fill:#ffffff;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;display:inline;enable-background:new" /> +- <path +- inkscape:transform-center-y="-5.7433893" +- inkscape:transform-center-x="13.28378" +- sodipodi:nodetypes="czzzczzc" +- id="path8159" +- d="M 1007.7658,-265.79794 C 1007.7658,-265.79794 1014.5949,-266.97564 1016.4488,-266.81309 C 1018.3026,-266.65053 1019.9534,-265.71359 1022.3945,-264.54256 C 1024.8357,-263.37156 1030.3669,-260.3401 1032.4783,-258.63754 C 1034.5896,-256.93496 1038.3592,-255.03249 1038.3592,-255.03249 C 1038.3592,-255.03249 1030.512,-258.30723 1027.7393,-259.78104 C 1024.9666,-261.25484 1020.5516,-263.91613 1017.951,-264.77897 C 1015.3505,-265.64179 1007.7658,-265.79794 1007.7658,-265.79794 z" +- style="fill:#ffffff;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;display:inline;enable-background:new" /> +- <path +- inkscape:transform-center-y="-5.7433893" +- inkscape:transform-center-x="13.28378" +- sodipodi:nodetypes="czzzczzc" +- id="path8161" +- d="M 1023.8908,-267.79794 C 1023.8908,-267.79794 1029.9699,-268.22564 1031.8238,-268.06309 C 1033.6776,-267.90053 1035.3284,-266.96359 1037.7695,-265.79256 C 1040.2107,-264.62156 1045.7419,-261.5901 1047.8533,-259.88754 C 1049.9646,-258.18496 1053.7342,-256.28249 1053.7342,-256.28249 C 1053.7342,-256.28249 1045.887,-259.55723 1043.1143,-261.03104 C 1040.3416,-262.50484 1035.9266,-265.16613 1033.326,-266.02897 C 1030.7255,-266.89179 1023.8908,-267.79794 1023.8908,-267.79794 z" +- style="fill:#ffffff;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;display:inline;enable-background:new" /> +- <path +- inkscape:transform-center-y="-5.7433893" +- inkscape:transform-center-x="13.28378" +- sodipodi:nodetypes="czzzczzc" +- id="path8163" +- d="M 1039.7033,-269.17294 C 1039.7033,-269.17294 1046.1574,-269.85064 1048.0113,-269.68809 C 1049.8651,-269.52553 1051.5159,-268.58859 1053.957,-267.41756 C 1056.3982,-266.24656 1061.9294,-263.2151 1064.0408,-261.51254 C 1066.1521,-259.80996 1069.9217,-257.90749 1069.9217,-257.90749 C 1069.9217,-257.90749 1062.0745,-261.18223 1059.3018,-262.65604 C 1056.5291,-264.12984 1052.1141,-266.79113 1049.5135,-267.65397 C 1046.913,-268.51679 1039.7033,-269.17294 1039.7033,-269.17294 z" +- style="fill:#ffffff;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;display:inline;enable-background:new" /> +- <path +- inkscape:transform-center-y="-5.1360724" +- inkscape:transform-center-x="13.55813" +- sodipodi:nodetypes="czzzczzc" +- id="path8165" +- d="M 1055.2718,-271.03319 C 1055.2718,-271.03319 1060.7694,-271.94264 1062.6296,-271.88667 C 1064.4897,-271.83067 1066.1915,-270.98993 1068.6957,-269.96081 C 1071.2001,-268.93171 1076.896,-266.22241 1079.1015,-264.64372 C 1081.307,-263.06501 1085.1795,-261.38182 1085.1795,-261.38182 C 1085.1795,-261.38182 1077.1575,-264.20121 1074.3047,-265.5136 C 1071.4521,-266.82598 1066.8918,-269.22973 1064.246,-269.94203 C 1061.6003,-270.65431 1055.2718,-271.03319 1055.2718,-271.03319 z" +- style="fill:#ffffff;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;display:inline;enable-background:new" /> +- <path +- inkscape:transform-center-y="-4.6370147" +- inkscape:transform-center-x="13.74758" +- sodipodi:nodetypes="czzzczzc" +- id="path8167" +- d="M 1072.7007,-273.48537 C 1072.7007,-273.48537 1077.2479,-274.64118 1079.1087,-274.67158 C 1080.9694,-274.70196 1082.7083,-273.94109 1085.2576,-273.02927 C 1087.807,-272.1175 1093.6225,-269.67541 1095.899,-268.20077 C 1098.1753,-266.72609 1102.1217,-265.22441 1102.1217,-265.22441 C 1102.1217,-265.22441 1093.9775,-267.66852 1091.067,-268.84713 C 1088.1565,-270.02573 1083.4896,-272.21528 1080.8136,-272.80404 C 1078.1377,-273.39279 1072.7007,-273.48537 1072.7007,-273.48537 z" +- style="fill:#ffffff;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;display:inline;enable-background:new" /> +- <path +- inkscape:transform-center-y="-4.4842392" +- inkscape:transform-center-x="13.79933" +- sodipodi:nodetypes="czzzczzc" +- id="path8169" +- d="M 1087.1585,-276.5244 C 1087.1585,-276.5244 1093.1185,-278.29795 1094.9787,-278.35464 C 1096.8387,-278.41131 1098.5883,-277.67509 1101.1502,-276.79939 C 1103.7122,-275.92373 1103.6728,-275.94226 1106.4837,-275.30924 C 1109.2806,-274.67938 1113.5604,-273.79611 1113.5604,-273.79611 C 1113.5604,-273.79611 1109.9449,-273.81239 1106.7681,-274.26225 C 1103.6526,-274.70344 1099.3938,-275.9605 1096.7097,-276.51138 C 1094.0258,-277.06226 1087.1585,-276.5244 1087.1585,-276.5244 z" +- style="fill:#ffffff;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;display:inline;enable-background:new" /> +- <path +- sodipodi:nodetypes="czczc" +- id="path8171" +- d="M 1099.25,-279.92981 C 1099.4112,-279.66119 1110.4581,-284.53027 1111.4375,-284.61731 C 1112.4169,-284.70435 1113.4375,-281.49231 1113.4375,-281.49231 C 1113.4375,-281.49231 1112.6624,-282.99665 1110.5625,-282.55481 C 1108.4626,-282.11297 1099.2616,-279.8834 1099.25,-279.92981 z" +- style="fill:#ffffff;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1" /> +- </g> +- <path +- id="path8173" +- d="M 1107.4532,-284.0938 C 1107.0345,-283.88097 1107.2976,-283.99991 1106.806,-283.78799 C 1106.3199,-283.57845 1105.0826,-283.2136 1102.7264,-282.32904 C 1099.3953,-281.07847 1096.8962,-280.1756 1095.7005,-279.26294 C 1094.1644,-279.24168 1091.98,-279.02963 1090.0442,-278.54419 C 1087.0627,-277.79653 1085.189,-277.37018 1083.2942,-276.95044 C 1081.3994,-276.53072 1081.6187,-276.30825 1080.4192,-276.07544 C 1079.1226,-275.82378 1078.6978,-276.08443 1074.9817,-275.29419 C 1071.4918,-274.55205 1066.0869,-273.36312 1064.8255,-272.60669 C 1063.2416,-272.78748 1060.958,-272.92847 1058.9817,-272.63794 C 1055.9413,-272.19099 1054.0655,-271.96518 1052.138,-271.73169 C 1051.4826,-271.65232 1051.0969,-271.53091 1050.7942,-271.45044 C 1050.368,-271.31879 1050.1084,-271.19042 1049.4192,-271.10669 C 1048.1076,-270.94733 1047.657,-271.26352 1043.888,-270.82544 C 1040.3341,-270.41236 1034.8826,-269.55262 1033.638,-268.88794 C 1032.039,-269.18524 1029.7802,-269.42213 1027.7942,-269.23169 C 1024.7354,-268.93838 1022.8222,-268.7477 1020.888,-268.57544 C 1018.9537,-268.40318 1019.1993,-268.15307 1017.9817,-268.04419 C 1016.6655,-267.9265 1016.2219,-268.20782 1012.4505,-267.79419 C 1008.9086,-267.40575 1003.4426,-266.58492 1002.1692,-265.91919 C 1000.5703,-266.21389 998.28202,-266.4262 996.29419,-266.23169 C 993.23595,-265.93245 991.35306,-265.75145 989.41919,-265.57544 C 988.7617,-265.5156 988.37915,-265.39688 988.07544,-265.32544 C 987.64779,-265.20649 987.39193,-265.10737 986.70044,-265.04419 C 985.38448,-264.92394 984.94068,-265.23907 981.16919,-264.82544 C 977.61305,-264.43543 972.16365,-263.58628 970.91919,-262.91919 C 969.32056,-263.21338 967.05935,-263.44291 965.07544,-263.23169 C 962.01984,-262.90637 960.1014,-262.70545 958.16919,-262.51294 C 956.23698,-262.32044 956.47932,-262.07206 955.26294,-261.95044 C 953.94806,-261.81898 953.49996,-262.11498 949.73169,-261.66919 C 946.19282,-261.25054 940.75401,-260.37702 939.48169,-259.70044 C 937.88414,-259.98149 935.62173,-260.12087 933.63794,-259.88794 C 930.58596,-259.52958 928.69286,-259.32008 926.76294,-259.10669 C 926.10674,-259.03414 925.72228,-258.934 925.41919,-258.85669 C 924.99242,-258.72947 924.73428,-258.58949 924.04419,-258.51294 C 922.73086,-258.36726 922.27673,-258.68696 918.51294,-258.20044 C 914.96405,-257.74169 909.53431,-256.78142 908.29419,-256.07544 C 906.70114,-256.31968 904.46038,-256.45679 902.48169,-256.20044 C 899.4341,-255.80563 897.53098,-255.55199 895.60669,-255.29419 C 893.68241,-255.0364 893.88058,-254.80066 892.66919,-254.63794 C 891.35973,-254.46204 890.922,-254.74232 887.16919,-254.16919 C 883.6449,-253.63095 878.24604,-252.47002 876.98169,-251.73169 C 875.39419,-251.93523 873.13619,-251.98642 871.16919,-251.63794 C 868.14302,-251.10182 866.2703,-250.77625 864.35669,-250.45044 C 863.70608,-250.33967 863.34298,-250.1795 863.04419,-250.07544 C 862.62352,-249.91056 862.38074,-249.74414 861.70044,-249.60669 C 860.40579,-249.3451 859.97332,-249.61289 856.26294,-248.79419 C 852.76441,-248.02224 847.41699,-246.41126 846.20044,-245.57544 C 844.63766,-245.65289 842.44286,-245.49016 840.51294,-244.98169 C 837.5405,-244.19856 835.69533,-243.7496 833.82544,-243.23169 C 831.95556,-242.71379 832.15884,-242.46441 830.98169,-242.13794 C 829.70923,-241.78504 829.28466,-242.03085 825.63794,-240.95044 C 822.21324,-239.93581 816.9885,-238.01727 815.76294,-237.10669 C 814.22411,-237.09395 812.04311,-236.83447 810.13794,-236.23169 C 807.20688,-235.30435 805.38763,-234.77327 803.54419,-234.16919 C 802.91743,-233.96381 802.55246,-233.77661 802.26294,-233.63794 C 801.85531,-233.42433 801.6096,-233.22919 800.95044,-233.01294 C 799.69598,-232.6014 799.26433,-232.8239 795.66919,-231.57544 C 792.27934,-230.39827 787.07421,-228.36174 785.88794,-227.41919 C 784.36405,-227.35952 782.23789,-227.02432 780.35669,-226.35669 C 777.4593,-225.3284 775.65761,-224.68121 773.82544,-224.04419 C 771.99327,-223.40718 772.19759,-223.19565 771.04419,-222.79419 C 769.79741,-222.36023 769.38058,-222.59447 765.82544,-221.23169 C 762.48677,-219.95189 757.33829,-217.74914 756.13794,-216.76294 C 754.63076,-216.65525 752.50225,-216.26414 750.63794,-215.54419 C 747.76976,-214.43659 746.01414,-213.76263 744.20044,-213.07544 C 743.58378,-212.84181 743.20403,-212.63341 742.91919,-212.48169 C 742.91919,-212.48169 742.91919,-211.38794 742.91919,-211.38794 C 743.03097,-211.6103 743.30518,-212.20537 743.82544,-212.48169 C 744.52341,-212.85241 748.63907,-214.47506 750.63794,-215.20044 C 752.2948,-215.80169 754.79183,-216.52912 756.60669,-216.51294 C 756.90831,-216.51025 757.19431,-216.46204 757.45044,-216.41919 C 759.29293,-216.11094 764.91919,-214.85669 764.91919,-214.85669 C 764.91918,-214.85669 758.6857,-216.50344 757.88794,-216.70044 C 757.69715,-216.74755 757.35222,-216.76916 756.91919,-216.76294 C 758.06465,-217.63265 761.68019,-219.15645 764.26294,-220.20044 C 767.10116,-221.34771 767.37975,-221.45226 769.32544,-221.85669 C 771.33374,-222.27413 772.48169,-222.35669 772.48169,-222.35669 C 772.48169,-222.35668 772.39933,-222.95783 773.45044,-223.48169 C 774.15554,-223.8331 778.33746,-225.37409 780.35669,-226.04419 C 782.30859,-226.69192 785.41409,-227.40269 787.23169,-227.04419 C 789.09492,-226.67669 794.76294,-225.23169 794.76294,-225.23169 C 794.76295,-225.23169 788.47594,-227.1028 787.66919,-227.32544 C 787.47627,-227.37869 787.13835,-227.41148 786.70044,-227.41919 C 787.85878,-228.25207 791.49488,-229.61451 794.10669,-230.57544 C 796.97685,-231.63145 797.27403,-231.73724 799.23169,-232.10669 C 801.08518,-232.45648 802.09053,-232.53217 802.26294,-232.54419 C 802.37654,-232.76143 802.64039,-233.35421 803.16919,-233.60669 C 803.87863,-233.94543 808.09526,-235.31944 810.13794,-235.91919 C 811.83111,-236.4163 814.37871,-236.95596 816.23169,-236.82544 C 816.53964,-236.80376 816.84518,-236.72818 817.10669,-236.66919 C 818.98787,-236.24487 824.70044,-234.63794 824.70044,-234.63794 C 824.70045,-234.63794 818.3587,-236.70319 817.54419,-236.95044 C 817.3494,-237.00958 816.98631,-237.05438 816.54419,-237.07544 C 817.71368,-237.87299 821.40721,-239.13166 824.04419,-240.01294 C 826.942,-240.98141 827.2772,-241.01626 829.26294,-241.29419 C 831.31259,-241.58108 832.45044,-241.60669 832.45044,-241.60669 C 832.45042,-241.60669 832.37769,-242.21366 833.45044,-242.66919 C 834.17004,-242.97476 838.44142,-244.16994 840.51294,-244.66919 C 842.51538,-245.15177 845.71143,-245.59748 847.57544,-245.07544 C 849.48622,-244.54029 855.29419,-242.57544 855.29419,-242.57544 C 855.29419,-242.57544 848.87153,-244.99895 848.04419,-245.29419 C 847.84635,-245.3648 847.46203,-245.43458 847.01294,-245.48169 C 848.20084,-246.21034 851.92821,-247.25577 854.60669,-247.98169 C 857.55011,-248.77944 857.89877,-248.75252 859.91919,-248.88794 C 861.83208,-249.01617 862.86624,-248.95903 863.04419,-248.95044 C 863.16147,-249.1541 863.43595,-249.72992 863.98169,-249.91919 C 864.71388,-250.17313 869.06021,-250.96708 871.16919,-251.29419 C 872.91732,-251.5653 875.57007,-251.77889 877.48169,-251.38794 C 877.79935,-251.32298 878.08691,-251.20243 878.35669,-251.10669 C 880.29743,-250.41796 886.20044,-248.01294 886.20044,-248.01294 C 886.20045,-248.01294 879.66573,-250.96371 878.82544,-251.32544 C 878.62447,-251.41195 878.25031,-251.49223 877.79419,-251.57544 C 879.00069,-252.20862 882.82375,-252.97104 885.54419,-253.48169 C 888.53372,-254.04288 888.84442,-254.01123 890.88794,-254.01294 C 892.9972,-254.01471 894.20044,-253.88794 894.20044,-253.88794 C 894.20044,-253.88793 894.12773,-254.51913 895.23169,-254.82544 C 895.97221,-255.03091 900.35781,-255.65931 902.48169,-255.88794 C 904.53471,-256.10893 907.80032,-256.14016 909.70044,-255.41919 C 911.64823,-254.68012 917.54419,-252.04419 917.54419,-252.04419 C 917.54421,-252.04419 910.98131,-255.22316 910.13794,-255.60669 C 909.93626,-255.69842 909.59573,-255.7929 909.13794,-255.88794 C 910.34886,-256.48982 914.12236,-257.13678 916.85669,-257.54419 C 919.86149,-257.99191 920.1822,-257.99589 922.23169,-257.95044 C 924.17214,-257.90742 925.23868,-257.75621 925.41919,-257.73169 C 925.53811,-257.92485 925.80309,-258.49752 926.35669,-258.63794 C 927.0994,-258.82632 931.51098,-259.37222 933.63794,-259.57544 C 935.40097,-259.74386 938.05803,-259.80973 939.98169,-259.32544 C 940.30137,-259.24496 940.5852,-259.12185 940.85669,-259.01294 C 942.80962,-258.22945 948.76294,-255.54419 948.76294,-255.54419 C 948.76292,-255.54419 942.17103,-258.79767 941.32544,-259.20044 C 941.12322,-259.29676 940.75318,-259.40747 940.29419,-259.51294 C 941.50833,-260.08721 945.33785,-260.63513 948.07544,-261.01294 C 951.08382,-261.42814 951.39851,-261.45557 953.45044,-261.38794 C 955.56842,-261.31813 956.76294,-261.13794 956.76294,-261.13794 C 956.76292,-261.13794 956.68569,-261.77535 957.79419,-262.04419 C 958.53781,-262.22454 962.94595,-262.70774 965.07544,-262.88794 C 967.13391,-263.06211 970.41868,-263.01226 972.32544,-262.23169 C 974.28003,-261.43153 980.20044,-258.70044 980.20044,-258.70044 C 980.20042,-258.70044 973.64051,-262.0092 972.79419,-262.41919 C 972.59182,-262.51724 972.22233,-262.62229 971.76294,-262.73169 C 972.97811,-263.29559 976.77302,-263.84599 979.51294,-264.20044 C 982.52385,-264.58996 982.83425,-264.59809 984.88794,-264.51294 C 986.83233,-264.43234 987.89457,-264.2597 988.07544,-264.23169 C 988.1946,-264.42255 988.45821,-264.977 989.01294,-265.10669 C 989.7572,-265.28069 994.16287,-265.75716 996.29419,-265.91919 C 998.06081,-266.05346 1000.7439,-266.0449 1002.6692,-265.54419 C 1002.9892,-265.46098 1003.2725,-265.34292 1003.5442,-265.23169 C 1005.4988,-264.43153 1011.4505,-261.66919 1011.4505,-261.66919 C 1011.4504,-261.66919 1004.8593,-265.0092 1004.013,-265.41919 C 1003.8106,-265.51724 1003.4411,-265.6223 1002.9817,-265.73169 C 1004.1968,-266.29559 1008.023,-266.81475 1010.763,-267.16919 C 1013.7739,-267.55872 1014.1155,-267.59809 1016.1692,-267.51294 C 1018.2889,-267.42506 1019.4817,-267.20044 1019.4817,-267.20044 C 1019.4817,-267.20044 1019.4033,-267.84946 1020.513,-268.10669 C 1021.2573,-268.27925 1025.6625,-268.73005 1027.7942,-268.88794 C 1029.8548,-269.04054 1033.1371,-268.98471 1035.0442,-268.20044 C 1036.9992,-267.39649 1042.9192,-264.70044 1042.9192,-264.70044 C 1042.9192,-264.70044 1036.3594,-267.97631 1035.513,-268.38794 C 1035.3105,-268.48638 1034.9412,-268.59016 1034.4817,-268.70044 C 1035.6971,-269.26198 1039.4936,-269.82822 1042.2317,-270.20044 C 1045.2407,-270.60949 1045.5544,-270.61602 1047.6067,-270.54419 C 1049.5498,-270.4762 1050.6139,-270.37934 1050.7942,-270.35669 C 1050.913,-270.55109 1051.1788,-271.0855 1051.7317,-271.23169 C 1052.4735,-271.42781 1056.8628,-272.06047 1058.9817,-272.32544 C 1060.7381,-272.54505 1063.387,-272.65775 1065.2942,-272.29419 C 1065.6111,-272.23378 1065.9,-272.10481 1066.1692,-272.01294 C 1068.1054,-271.35202 1074.013,-269.07544 1074.013,-269.07544 C 1074.0129,-269.07544 1067.4763,-271.88199 1066.638,-272.23169 C 1066.4375,-272.31532 1066.0618,-272.40502 1065.6067,-272.48169 C 1066.8104,-273.13215 1070.6258,-273.85364 1073.3255,-274.48169 C 1076.2922,-275.17189 1076.6144,-275.23676 1078.638,-275.35669 C 1080.7266,-275.48049 1081.9192,-275.38794 1081.9192,-275.38794 C 1081.9192,-275.38793 1081.8322,-276.01999 1082.9192,-276.41919 C 1083.6484,-276.68699 1087.9664,-277.75716 1090.0442,-278.23169 C 1092.0527,-278.69038 1095.2121,-279.26099 1097.0442,-278.85669 C 1098.9223,-278.44223 1110.6224,-275.84106 1110.6224,-275.84106 C 1110.6224,-275.84106 1098.2949,-278.86372 1097.4817,-279.10669 C 1097.2872,-279.16481 1096.9231,-279.21295 1096.4817,-279.23169 C 1097.6493,-280.03538 1099.9959,-280.91899 1102.5911,-281.93481 C 1104.2725,-282.59299 1103.5148,-282.3114 1105.367,-282.93841 C 1107.1206,-283.53207 1107.8524,-283.94912 1107.9974,-284.0514 C 1108.3435,-284.25791 1107.6414,-284.17328 1107.4532,-284.0938 z" +- style="opacity:0.25;fill:#000000;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;display:inline;filter:url(#filter7333);enable-background:new" +- sodipodi:nodetypes="czscsssscssssscsssscssssscsssscssssscsssscssssscsssscssssscsssscssccsssscscsscssscscsscsssscscsscssscscsscsssscscsscssscscsscsssscscsscssscscsscsssscscsscssscscsscsssscscsscssscscsscc" /> +- <path +- id="path8175" +- d="M 1082.625,-275.125 C 1084.498,-274.73152 1087.1211,-273.97945 1088.6563,-273.15625 C 1090.1915,-272.33306 1091.4785,-272.10025 1094.0313,-270.65625 C 1096.5579,-269.22699 1098.8271,-268.64929 1101,-268.125 C 1103.3476,-267.55858 1106.4354,-267.40977 1109.8438,-266.9375 C 1108.7549,-267.77725 1103.2364,-268.10995 1101.4375,-268.5 C 1099.6386,-268.89006 1097.5434,-269.51616 1094.8438,-270.8125 C 1092.1441,-272.10884 1091.3494,-272.61146 1089.0313,-273.5 C 1086.7131,-274.38854 1085.0269,-274.88314 1082.625,-275.125 z" +- style="opacity:0.25;fill:#000000;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;display:inline;filter:url(#filter7285);enable-background:new" /> +- <path +- id="path8177" +- d="M 1051.4688,-270 C 1053.3741,-269.42241 1055.9969,-268.38428 1057.5625,-267.40625 C 1059.1281,-266.42823 1060.4427,-266.04644 1063.0625,-264.28125 C 1065.6555,-262.53409 1068.0484,-261.57198 1070.3125,-260.6875 C 1072.7586,-259.73193 1075.9951,-259.03037 1079.7188,-257.625 C 1078.5292,-258.76284 1072.6557,-260.31175 1070.7813,-261 C 1068.9068,-261.68825 1066.6995,-262.5662 1063.9063,-264.28125 C 1061.113,-265.99629 1060.3327,-266.56515 1057.9688,-267.6875 C 1055.6047,-268.80984 1053.9121,-269.52205 1051.4688,-270 z" +- style="opacity:0.25;fill:#000000;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;display:inline;filter:url(#filter7289);enable-background:new" /> +- <path +- id="path8179" +- d="M 1020.2188,-266.84375 C 1022.1307,-266.20564 1024.8,-265.08839 1026.375,-264.03125 C 1027.9501,-262.9741 1029.2706,-262.52258 1031.9063,-260.625 C 1034.5149,-258.74679 1036.9347,-257.59497 1039.2188,-256.5625 C 1041.6865,-255.44705 1044.9833,-254.3892 1048.75,-252.71875 C 1047.5467,-253.94128 1041.5472,-256.03298 1039.6563,-256.84375 C 1037.7653,-257.65452 1035.5914,-258.73754 1032.7813,-260.59375 C 1029.9711,-262.44995 1029.1595,-263.07068 1026.7813,-264.3125 C 1024.403,-265.5543 1022.6706,-266.28819 1020.2188,-266.84375 z" +- style="opacity:0.25;fill:#000000;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;display:inline;filter:url(#filter7293);enable-background:new" /> +- <path +- id="path8181" +- d="M 1110.1719,-266.89063 C 1110.3227,-266.84207 1110.8599,-266.25963 1110.2813,-265.40625 C 1109.4712,-264.21166 1104.5764,-262.08196 1101.7188,-261.28125 C 1098.8739,-260.48413 1095.4287,-260.30351 1091.1563,-261.65625 C 1086.8547,-263.0182 1085.6866,-264.12497 1080.5,-265.96875 C 1085.164,-263.85358 1086.6953,-262.01642 1090.625,-260.625 C 1092.2457,-260.05113 1093.9921,-259.6854 1095.6875,-259.59375 C 1095.2424,-259.26812 1094.1572,-258.61045 1092.125,-258 C 1089.3295,-257.16031 1085.4759,-256.46622 1083.875,-256.375 C 1082.3604,-256.28868 1080.733,-256.88749 1080.4375,-257 C 1080.6042,-256.89692 1080.8107,-256.62266 1080.1875,-255.96875 C 1079.2882,-255.02512 1074.0401,-254.04575 1071.0625,-253.71875 C 1068.0982,-253.3932 1064.5409,-253.73471 1060.1563,-255.625 C 1056.1783,-257.33997 1054.8173,-258.54036 1050.75,-260.375 C 1050.75,-260.375 1050.75,-260.21875 1050.75,-260.21875 C 1054.3931,-258.12346 1056.034,-256.33548 1059.625,-254.65625 C 1061.3552,-253.84716 1063.2167,-253.24749 1065.0313,-252.9375 C 1064.4964,-252.65074 1063.4735,-252.22599 1061.5938,-251.90625 C 1058.7248,-251.41829 1054.7848,-251.09011 1053.1563,-251.15625 C 1052.3056,-251.19079 1051.4277,-251.34062 1050.75,-251.5625 C 1050.0652,-251.77738 1049.5603,-252.00717 1049.4375,-252.0625 C 1049.6069,-251.95529 1049.8686,-251.65962 1049.2188,-251.03125 C 1048.3091,-250.15163 1042.9727,-249.69487 1039.9688,-249.5625 C 1036.9783,-249.43071 1033.3799,-250.01313 1028.9688,-252.125 C 1024.5276,-254.25126 1023.3273,-255.5266 1018.0625,-257.90625 C 1022.7968,-255.30921 1024.349,-253.27715 1028.4063,-251.1875 C 1030.0796,-250.32565 1031.8915,-249.69325 1033.6563,-249.25 C 1033.193,-249.01668 1032.0669,-248.56186 1029.9688,-248.3125 C 1027.0825,-247.96952 1023.1342,-247.81962 1021.5,-247.9375 C 1019.9538,-248.049 1018.2688,-248.79446 1017.9688,-248.9375 C 1018.1379,-248.81721 1018.3826,-248.52702 1017.75,-247.9375 C 1016.8372,-247.08677 1011.5059,-246.67538 1008.5,-246.5625 C 1005.5075,-246.45013 1001.9103,-247.05293 997.5,-249.15625 C 993.49875,-251.06448 992.11197,-252.29408 988.03125,-254.25 C 988.03122,-254.25 988.03125,-254.09375 988.03125,-254.09375 C 991.68631,-251.88983 993.32546,-250.0412 996.9375,-248.1875 C 998.67779,-247.29435 1000.5745,-246.65923 1002.4063,-246.21875 C 1001.8663,-245.97045 1000.8282,-245.60342 998.9375,-245.375 C 996.05182,-245.02642 992.07145,-244.85405 990.4375,-244.96875 C 989.58405,-245.02865 988.71119,-245.22666 988.03125,-245.46875 C 987.34415,-245.70405 986.8419,-245.94101 986.71875,-246 C 986.88873,-245.88773 987.18323,-245.57775 986.53125,-244.96875 C 985.6186,-244.11625 980.25592,-243.67538 977.25,-243.5625 C 974.25754,-243.45013 970.65654,-244.09055 966.25,-246.15625 C 961.81347,-248.23603 960.60312,-249.48796 955.34375,-251.8125 C 960.07313,-249.26501 961.63449,-247.2347 965.6875,-245.1875 C 967.35905,-244.34317 969.17304,-243.72107 970.9375,-243.28125 C 970.47427,-243.04703 969.3478,-242.59718 967.25,-242.34375 C 964.36431,-241.99517 960.4138,-241.77423 958.78125,-241.875 C 957.23669,-241.97032 955.58094,-242.70385 955.28125,-242.84375 C 955.45024,-242.72522 955.66317,-242.4399 955.03125,-241.84375 C 954.11939,-240.98347 948.7846,-240.5135 945.78125,-240.375 C 942.7913,-240.2371 939.2138,-240.82568 934.8125,-242.84375 C 930.81942,-244.67464 929.44739,-245.87295 925.375,-247.75 C 925.37498,-247.75 925.375,-247.59375 925.375,-247.59375 C 929.02261,-245.46048 930.64533,-243.65888 934.25,-241.875 C 935.98675,-241.01549 937.85727,-240.42486 939.6875,-240 C 939.14803,-239.7471 938.13687,-239.35871 936.25,-239.09375 C 933.37022,-238.68939 929.41187,-238.44813 927.78125,-238.53125 C 926.92953,-238.57466 926.05355,-238.7398 925.375,-238.96875 C 924.68931,-239.19076 924.1854,-239.41214 924.0625,-239.46875 C 924.23209,-239.35976 924.4944,-239.0591 923.84375,-238.4375 C 922.93296,-237.56736 917.59354,-237.04598 914.59375,-236.875 C 911.60742,-236.70479 908.01994,-237.19077 903.625,-239.15625 C 899.20011,-241.13513 898.01904,-242.38444 892.78125,-244.53125 C 897.49122,-242.14358 899.05142,-240.14252 903.09375,-238.1875 C 904.7609,-237.38119 906.55418,-236.79092 908.3125,-236.40625 C 907.85087,-236.15755 906.7155,-235.694 904.625,-235.375 C 901.7494,-234.93624 897.8446,-234.6419 896.21875,-234.6875 C 894.68052,-234.73062 892.98595,-235.43272 892.6875,-235.5625 C 892.85583,-235.44968 893.09807,-235.14875 892.46875,-234.53125 C 891.56063,-233.64015 886.2658,-233.003 883.28125,-232.71875 C 880.31007,-232.43577 876.70783,-232.89455 872.34375,-234.65625 C 868.38441,-236.25456 867.0146,-237.45112 863,-238.96875 C 863.00003,-238.96875 863,-238.8125 863,-238.8125 C 866.5959,-237.00115 868.23831,-235.23017 871.8125,-233.65625 C 873.53457,-232.8979 875.39998,-232.3673 877.21875,-232.03125 C 876.68266,-231.75217 875.65217,-231.34362 873.78125,-230.96875 C 870.92586,-230.39665 866.99183,-229.94936 865.375,-229.9375 C 864.53049,-229.93129 863.66892,-230.01844 863,-230.1875 C 862.32409,-230.34901 861.83991,-230.51673 861.71875,-230.5625 C 861.88597,-230.46848 862.14142,-230.17902 861.5,-229.5 C 860.60213,-228.54948 855.31352,-227.58292 852.375,-227.0625 C 849.44966,-226.54441 845.94285,-226.68826 841.65625,-228.09375 C 837.34045,-229.50882 836.18348,-230.62369 831.09375,-232.0625 C 835.6706,-230.31149 837.1823,-228.50244 841.125,-227.0625 C 842.75108,-226.46861 844.49385,-226.10685 846.21875,-225.90625 C 845.7659,-225.60923 844.66397,-225.02286 842.625,-224.4375 C 839.82028,-223.63233 835.98614,-222.86167 834.40625,-222.6875 C 832.9115,-222.5227 831.29002,-223.00431 831,-223.09375 C 831.16356,-223.00368 831.39278,-222.73382 830.78125,-222.03125 C 829.89878,-221.0174 824.73673,-219.6596 821.84375,-218.96875 C 818.96373,-218.28097 815.50815,-218.20873 811.28125,-219.40625 C 807.4464,-220.4927 806.10867,-221.47862 802.21875,-222.53125 C 802.21874,-222.53125 802.21875,-222.375 802.21875,-222.375 C 805.70293,-220.98015 807.28816,-219.4556 810.75,-218.34375 C 812.41793,-217.80803 814.20578,-217.55701 815.96875,-217.46875 C 815.44911,-217.11663 814.46836,-216.55423 812.65625,-215.9375 C 809.89059,-214.99625 806.06601,-214.00213 804.5,-213.78125 C 803.68206,-213.66586 802.8669,-213.65842 802.21875,-213.75 C 801.56379,-213.83321 801.08615,-213.96827 800.96875,-214 C 801.13079,-213.92536 801.40274,-213.65956 800.78125,-212.90625 C 799.91125,-211.85172 794.77162,-210.247 791.90625,-209.46875 C 789.05372,-208.69399 785.64713,-208.51055 781.46875,-209.5625 C 777.26192,-210.62163 776.11206,-211.60416 771.125,-212.71875 C 775.60954,-211.25929 777.09435,-209.58352 780.9375,-208.46875 C 782.52254,-208.00898 784.22429,-207.8305 785.90625,-207.78125 C 785.46468,-207.44449 784.39374,-206.75352 782.40625,-206 C 779.67232,-204.96351 775.95427,-203.83731 774.40625,-203.5625 C 772.94163,-203.30248 771.34667,-203.67904 771.0625,-203.75 C 771.22275,-203.67035 771.44294,-203.42902 770.84375,-202.6875 C 769.97909,-201.61744 764.92723,-199.86935 762.09375,-199 C 759.27295,-198.13453 755.88625,-197.84369 751.75,-198.78125 C 747.99741,-199.63186 746.70215,-200.49772 742.875,-201.375 C 742.875,-201.375 742.875,-201.21875 742.875,-201.21875 C 746.30296,-199.98096 747.86241,-198.58645 751.25,-197.6875 C 752.88216,-197.25436 754.61704,-197.10449 756.34375,-197.125 C 755.83482,-196.74083 754.867,-196.10318 753.09375,-195.375 C 750.38741,-194.26366 746.65742,-193.06719 745.125,-192.75 C 744.3246,-192.58431 743.51269,-192.53138 742.875,-192.59375 C 742.875,-192.59375 742.875,-192.07823 742.875,-191.67146 C 742.875,-191.40639 742.875,-191.1875 742.875,-191.1875 C 743.10145,-191.33218 743.32391,-191.46011 743.59375,-191.5625 C 744.67427,-191.97248 745.76536,-191.77827 749.59375,-193.25 C 753.42218,-194.72174 754.81787,-195.25498 755.5,-195.65625 C 756.1796,-196.05603 757.11165,-196.53562 757.71875,-197.1875 C 759.5456,-197.32525 761.2895,-197.68073 762.65625,-198.1875 C 765.62437,-199.28802 767.53162,-199.99369 769.4375,-200.65625 C 771.34336,-201.31879 771.79159,-202.07112 772.84375,-202.4375 C 773.9353,-202.81761 775.03886,-202.60288 778.90625,-203.96875 C 782.7737,-205.33461 784.18941,-205.79583 784.875,-206.1875 C 785.57609,-206.58802 786.57581,-207.12048 787.1875,-207.78125 C 789.1583,-207.83591 791.00435,-208.16588 792.46875,-208.65625 C 795.47023,-209.66133 797.3949,-210.27796 799.3125,-210.90625 C 800.8511,-211.41035 801.48652,-211.95302 802.21875,-212.34375 C 802.44891,-212.47806 802.69449,-212.59748 802.96875,-212.6875 C 804.06698,-213.04798 805.1502,-212.76887 809.0625,-214 C 812.97483,-215.23113 814.42855,-215.67295 815.125,-216.03125 C 815.81888,-216.38822 816.75515,-216.82386 817.375,-217.4375 C 819.24021,-217.46016 821.01081,-217.70433 822.40625,-218.125 C 825.43668,-219.03854 827.39863,-219.5551 829.34375,-220.09375 C 831.28886,-220.63239 831.76993,-221.35827 832.84375,-221.65625 C 833.95776,-221.9654 835.06369,-221.64886 839.03125,-222.6875 C 842.99886,-223.72613 844.44883,-224.12023 845.15625,-224.4375 C 845.89112,-224.76709 846.97008,-225.19122 847.59375,-225.8125 C 849.59149,-225.6965 851.45118,-225.83259 852.9375,-226.1875 C 856.01561,-226.9225 858.02094,-227.28844 860,-227.6875 C 861.58792,-228.00768 862.24429,-228.47805 863,-228.78125 C 863.23757,-228.88805 863.46695,-228.97401 863.75,-229.03125 C 864.88347,-229.26044 866.05448,-228.82232 870.09375,-229.53125 C 874.13308,-230.24018 875.594,-230.45834 876.3125,-230.71875 C 877.02836,-230.97819 878.01678,-231.28599 878.65625,-231.8125 C 880.58052,-231.57301 882.40413,-231.58797 883.84375,-231.8125 C 886.97008,-232.30012 888.9983,-232.51317 891,-232.78125 C 893.00171,-233.04932 893.48869,-233.72639 894.59375,-233.875 C 895.74014,-234.02918 896.86967,-233.57343 900.9375,-234.09375 C 905.00534,-234.61407 906.49763,-234.78948 907.21875,-235.03125 C 907.95585,-235.27839 909.01684,-235.61748 909.65625,-236.15625 C 911.70632,-235.82072 913.63003,-235.75829 915.15625,-235.9375 C 918.29856,-236.30646 920.33619,-236.49686 922.34375,-236.71875 C 923.95451,-236.89677 924.60842,-237.32695 925.375,-237.5625 C 925.61594,-237.64802 925.86912,-237.7181 926.15625,-237.75 C 927.30603,-237.87772 928.45754,-237.40335 932.53125,-237.875 C 936.60499,-238.34665 938.09034,-238.4856 938.8125,-238.71875 C 939.53196,-238.95102 940.51274,-239.19221 941.15625,-239.6875 C 943.09262,-239.35404 944.92631,-239.28326 946.375,-239.4375 C 949.52102,-239.77245 951.55256,-239.95609 953.5625,-240.15625 C 955.57246,-240.35639 956.04664,-240.98264 957.15625,-241.09375 C 958.30739,-241.20903 959.45268,-240.72869 963.53125,-241.15625 C 967.60986,-241.58381 969.12011,-241.71834 969.84375,-241.9375 C 970.5829,-242.16136 971.63947,-242.45075 972.28125,-242.96875 C 974.33835,-242.57008 976.28312,-242.47535 977.8125,-242.625 C 980.96123,-242.9331 982.98834,-243.09825 985,-243.28125 C 986.61407,-243.42807 987.2631,-243.8418 988.03125,-244.0625 C 988.27267,-244.14336 988.52478,-244.19241 988.8125,-244.21875 C 989.96461,-244.3242 991.10546,-243.826 995.1875,-244.21875 C 999.26958,-244.6115 1000.7764,-244.74959 1001.5,-244.96875 C 1002.2209,-245.18708 1003.1997,-245.41645 1003.8438,-245.90625 C 1005.7818,-245.55626 1007.6126,-245.45187 1009.0625,-245.59375 C 1012.2112,-245.90185 1014.2383,-246.067 1016.25,-246.25 C 1018.2616,-246.43299 1018.7642,-247.08802 1019.875,-247.1875 C 1021.0273,-247.29073 1022.1672,-246.80267 1026.25,-247.1875 C 1030.3329,-247.57232 1031.8387,-247.6885 1032.5625,-247.90625 C 1033.3018,-248.12868 1034.3581,-248.42074 1035,-248.9375 C 1037.0574,-248.53573 1039.0029,-248.43417 1040.5313,-248.59375 C 1043.6779,-248.92227 1045.7084,-249.11645 1047.7188,-249.3125 C 1049.3318,-249.46979 1049.9844,-249.94398 1050.75,-250.1875 C 1050.9907,-250.27554 1051.2132,-250.30887 1051.5,-250.34375 C 1052.6483,-250.48345 1053.8167,-250.00384 1057.875,-250.59375 C 1061.9333,-251.18367 1063.4368,-251.37089 1064.1563,-251.625 C 1064.873,-251.87816 1065.8308,-252.18307 1066.4688,-252.71875 C 1068.3885,-252.50681 1070.1887,-252.56734 1071.625,-252.8125 C 1074.7441,-253.3449 1076.7366,-253.74111 1078.7188,-254.125 C 1080.7009,-254.50887 1081.1931,-255.16465 1082.2813,-255.40625 C 1083.4101,-255.65691 1084.5516,-255.28996 1088.5313,-256.28125 C 1092.5109,-257.27253 1093.9609,-257.70055 1094.6563,-258.0625 C 1095.3786,-258.43851 1096.4182,-258.93308 1097.0313,-259.59375 C 1098.9943,-259.6058 1100.825,-259.8848 1102.25,-260.4375 C 1105.2012,-261.58211 1107.1232,-262.30692 1108.9375,-263.1875 C 1110.3932,-263.89403 1111.2723,-264.87391 1111.4844,-265.17188 C 1111.6966,-265.46984 1111.5962,-265.91718 1111.6223,-265.93863 C 1111.6652,-265.97387 1111.9416,-266.0236 1112.1013,-266.36707 C 1112.9602,-268.21415 1114.4223,-272.01166 1114.5365,-272.69652 C 1114.6502,-273.37868 1114.7003,-274.04426 1114.751,-274.44149 C 1114.7804,-274.67101 1114.6043,-275.30693 1114.6264,-275.36553 C 1114.6573,-275.44759 1114.9309,-275.63081 1114.9863,-275.88024 C 1115.2526,-277.07857 1115.0752,-278.07153 1114.8612,-279.48917 C 1114.6472,-280.90681 1113.8775,-284.11131 1113.2243,-284.96543 C 1112.5654,-285.82715 1112.0014,-285.9766 1111.4764,-285.96609 C 1111.2678,-285.69633 1111.6132,-285.703 1111.639,-285.65348 C 1112.3196,-285.60269 1112.573,-285.28484 1113.0582,-284.75686 C 1113.5434,-284.22888 1114.28,-280.90569 1114.4166,-279.4553 C 1114.5532,-278.00491 1114.6066,-276.5951 1114.3286,-275.98666 C 1114.0505,-275.37821 1113.6054,-275.46963 1113.313,-275.40375 C 1113.844,-275.21786 1113.9828,-275.27892 1114.0444,-274.43446 C 1114.1037,-273.62108 1113.9112,-272.79477 1113.5246,-271.62884 C 1113.1334,-270.44883 1111.6794,-267.27886 1111.2389,-267.03007 C 1110.7866,-266.77456 1110.5075,-266.75969 1110.1719,-266.89063 z" +- style="opacity:0.25;fill:#000000;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;display:inline;filter:url(#filter7337);enable-background:new" +- sodipodi:nodetypes="cssscscsscsssccscssssssscscsscsssscscssssssscscsscsssscscssssssscscsscsssscscssssssscscsscsssscscssssssscscsscsssccscsscscssscssssscsssssscssssscsssssscssssscsssssscssssscsssssscssssscsssssscssssscsszsszssszzcczzzczzzc" /> +- <path +- id="path8183" +- d="M 988.75,-263.84375 C 990.66161,-263.20935 993.30027,-262.08534 994.875,-261.03125 C 996.44977,-259.97716 997.7711,-259.54873 1000.4063,-257.65625 C 1003.0145,-255.78311 1005.4332,-254.64103 1007.7188,-253.59375 C 1010.1881,-252.46228 1013.4709,-251.43901 1017.25,-249.65625 C 1016.0428,-250.91465 1010.111,-253.0207 1008.2188,-253.84375 C 1006.3266,-254.66679 1004.0908,-255.77424 1001.2813,-257.625 C 998.47169,-259.47575 997.65906,-260.10654 995.28125,-261.34375 C 992.90343,-262.58094 991.20137,-263.29295 988.75,-263.84375 z" +- style="opacity:0.25;fill:#000000;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;display:inline;filter:url(#filter7297);enable-background:new" /> +- <path +- id="path8185" +- d="M 957.5,-260.78125 C 959.41,-260.16315 962.08288,-259.07191 963.65625,-258.03125 C 965.22964,-256.99059 966.55233,-256.54873 969.1875,-254.65625 C 971.79573,-252.7831 974.21442,-251.64104 976.5,-250.59375 C 978.96931,-249.46228 982.25213,-248.439 986.03125,-246.65625 C 984.82397,-247.91465 978.82971,-250.05195 976.9375,-250.875 C 975.04533,-251.69804 972.84084,-252.8055 970.03125,-254.65625 C 967.22167,-256.507 966.4383,-257.09557 964.0625,-258.3125 C 961.68672,-259.52941 959.94929,-260.25135 957.5,-260.78125 z" +- style="opacity:0.25;fill:#000000;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;display:inline;filter:url(#filter7301);enable-background:new" /> +- <path +- id="path8187" +- d="M 926.09375,-257.375 C 928.00147,-256.77755 930.64723,-255.71116 932.21875,-254.6875 C 933.79025,-253.66385 935.08897,-253.24779 937.71875,-251.40625 C 940.32166,-249.58352 942.74762,-248.43405 945.03125,-247.40625 C 947.49845,-246.29584 950.7866,-245.31302 954.5625,-243.5625 C 953.35627,-244.8106 947.3906,-246.88059 945.5,-247.6875 C 943.60942,-248.4944 941.39758,-249.57854 938.59375,-251.375 C 935.7899,-253.17144 934.96671,-253.77751 932.59375,-254.96875 C 930.22078,-256.15999 928.54013,-256.87158 926.09375,-257.375 z" +- style="opacity:0.25;fill:#000000;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;display:inline;filter:url(#filter7305);enable-background:new" /> +- <path +- id="path8189" +- d="M 894.90625,-253.5625 C 896.80838,-253.00895 899.49326,-251.97363 901.0625,-250.96875 C 902.63173,-249.96388 903.93651,-249.56011 906.5625,-247.75 C 909.16162,-245.95836 911.56284,-244.87811 913.84375,-243.875 C 916.30803,-242.79126 919.60359,-241.83471 923.375,-240.125 C 922.1702,-241.36007 916.20084,-243.36978 914.3125,-244.15625 C 912.42418,-244.94272 910.2373,-245.98705 907.4375,-247.75 C 904.63773,-249.51294 903.83831,-250.11836 901.46875,-251.28125 C 899.09918,-252.44413 897.3455,-253.11537 894.90625,-253.5625 z" +- style="opacity:0.25;fill:#000000;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;display:inline;filter:url(#filter7309);enable-background:new" /> +- <path +- id="path8191" +- d="M 863.71875,-248.65625 C 865.59937,-248.22716 868.22302,-247.27587 869.78125,-246.34375 C 871.33948,-245.41164 872.63358,-245.08599 875.25,-243.34375 C 877.83971,-241.61931 880.23067,-240.63573 882.5,-239.71875 C 884.95176,-238.72806 888.23959,-237.84168 892,-236.21875 C 890.79869,-237.42609 884.84751,-239.28484 882.96875,-240 C 881.09,-240.71517 878.88335,-241.68442 876.09375,-243.375 C 873.30412,-245.06557 872.50914,-245.60322 870.15625,-246.65625 C 867.80333,-247.70926 866.13041,-248.36873 863.71875,-248.65625 z" +- style="opacity:0.25;fill:#000000;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;display:inline;filter:url(#filter7313);enable-background:new" /> +- <path +- id="path8193" +- d="M 833.15625,-241.375 C 835.00461,-241.07856 837.6257,-240.39868 839.15625,-239.59375 C 840.68683,-238.78882 841.96999,-238.53802 844.53125,-237.0625 C 847.06629,-235.60204 849.42193,-234.73741 851.65625,-234 C 854.07024,-233.20332 857.31336,-232.53311 861.03125,-231.15625 C 859.84354,-232.28498 853.94353,-233.746 852.09375,-234.3125 C 850.24398,-234.879 848.09033,-235.68642 845.34375,-237.15625 C 842.59718,-238.62608 841.84239,-239.07653 839.53125,-239.9375 C 837.2201,-240.79845 835.52654,-241.25759 833.15625,-241.375 z" +- style="opacity:0.25;fill:#000000;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;display:inline;filter:url(#filter7317);enable-background:new" /> +- <path +- id="path8195" +- d="M 802.90625,-232.3125 C 804.72845,-232.10123 807.27201,-231.51193 808.78125,-230.78125 C 810.2905,-230.05059 811.53693,-229.85127 814.0625,-228.5 C 816.56226,-227.16254 818.89404,-226.45157 821.09375,-225.84375 C 823.47028,-225.18708 826.65839,-224.77087 830.3125,-223.65625 C 829.14515,-224.70121 823.38362,-225.75954 821.5625,-226.21875 C 819.74139,-226.67796 817.61025,-227.34571 814.90625,-228.65625 C 812.20222,-229.96677 811.43519,-230.37615 809.15625,-231.125 C 806.8773,-231.87383 805.243,-232.30431 802.90625,-232.3125 z" +- style="opacity:0.25;fill:#000000;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;display:inline;filter:url(#filter7321);enable-background:new" /> +- <path +- id="path8197" +- d="M 773.1875,-222.1875 C 774.99859,-222.0088 777.50809,-221.52244 779,-220.84375 C 780.49194,-220.16506 781.7534,-220.04553 784.25,-218.78125 C 786.72107,-217.52987 789.04005,-216.88511 791.21875,-216.34375 C 793.57262,-215.75887 796.71009,-215.44623 800.3125,-214.5 C 799.16166,-215.49116 793.45999,-216.2833 791.65625,-216.6875 C 789.85253,-217.0917 787.74072,-217.70866 785.0625,-218.9375 C 782.38432,-220.16634 781.65905,-220.54839 779.40625,-221.21875 C 777.15346,-221.88909 775.50998,-222.22107 773.1875,-222.1875 z" +- style="opacity:0.25;fill:#000000;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;display:inline;filter:url(#filter7329);enable-background:new" /> +- <path +- id="path8199" +- d="M 743.5625,-211.1875 C 745.35531,-211.05839 747.83563,-210.63785 749.3125,-210 C 750.7894,-209.36215 752.0286,-209.25844 754.5,-208.0625 C 756.94618,-206.87878 759.22054,-206.31584 761.375,-205.84375 C 763.70267,-205.33372 766.7946,-205.16311 770.375,-204.28125 C 769.23121,-205.25185 763.62741,-205.8719 761.84375,-206.21875 C 760.06008,-206.56559 757.9609,-207.10631 755.3125,-208.25 C 752.66409,-209.39368 751.91755,-209.76631 749.6875,-210.375 C 747.45742,-210.98368 745.86156,-211.28466 743.5625,-211.1875 z" +- style="opacity:0.25;fill:#000000;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;display:inline;filter:url(#filter7325);enable-background:new" /> +- </g> +- </g> +- <path +- style="opacity:1;fill:none;fill-rule:evenodd;stroke:#000000;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;display:inline;enable-background:new" +- d="M 863.87812,475.6679 C 865.52024,472.4499 867.39593,469.93261 868.73948,465.81892 C 869.5382,462.16103 872.05152,463.78819 875.99995,457.42202 C 877.40188,455.18252 881.47648,457.81338 884.96505,455.02291 C 886.23577,454.21972 887.84993,454.6186 889.44761,454.95978 C 893.213,456.27874 895.27337,458.66333 897.78137,460.76815 C 903.92043,466.73838 918.31551,468.71142 921.26741,467.08161 C 922.70146,464.17687 929.14869,461.67273 933.64178,455.96993 C 934.38989,454.84726 945.37114,447.22547 948.28899,449.40394" +- id="path8201" +- sodipodi:nodetypes="ccccccccc" /> +- <path +- style="opacity:1;fill:none;fill-rule:evenodd;stroke:#000000;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;display:inline;enable-background:new" +- d="M 888.50059,465.25071 C 895.864,462.01774 902.31149,456.34231 909.20872,451.86619 C 912.51929,449.89665 916.07855,455.0822 920.00472,455.46485 C 922.30245,455.24672 923.71762,456.66744 925.68683,457.10635 C 930.84319,458.42414 928.08476,460.97123 935.66209,463.54607 C 941.8177,465.26647 944.56949,456.7476 950.56184,456.22247 C 955.43923,455.71948 958.66076,455.90644 962.17859,455.96993 C 966.10555,456.10882 966.25714,452.47233 968.23951,450.66663 C 971.22007,447.86141 975.39512,448.81691 978.38436,445.92573 C 979.4019,444.54105 980.33894,442.91488 981.11895,440.81764 C 982.00096,438.8173 984.15901,441.12362 985.91718,442.08033" +- id="path8203" +- sodipodi:nodetypes="ccccccccccc" /> +- </g> +- <g +- inkscape:groupmode="layer" +- id="layer15" +- inkscape:label="Feet" +- style="display:inline"> +- <path +- style="opacity:0.25;fill:#000000;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;marker:none;marker-start:none;marker-mid:none;marker-end:none;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;visibility:visible;display:inline;overflow:visible;filter:url(#filter9048);enable-background:accumulate" +- d="M 403.27922,1056.3058 L 459.84776,1013.8794 L 531.97265,1028.0215 L 485.30361,1080.3474 L 431.56349,1087.4185 L 403.27922,1056.3058 z" +- id="path8994" /> +- <path +- style="opacity:1;fill:#ada469;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;display:inline;enable-background:new" +- d="M 542.27183,1060.5719 C 540.86456,1079.3731 541.12693,1093.3229 544.35357,1109.8752 C 547.58023,1126.4275 560.75966,1155.7825 564.68798,1173.0589 C 568.61419,1190.326 567.38211,1211.3686 552.22854,1224.2072 C 536.91093,1237.1846 510.17726,1245.8061 484.39623,1239.9409 C 458.61518,1234.0757 414.84716,1190.7175 395.80604,1169.7126 C 376.6939,1148.6293 332.04518,1075.862 317.86751,1045.4368 C 303.68984,1015.0117 305.2079,1008.7182 309.74779,999.90708 C 300.38107,975.38658 297.33408,949.84027 276.03534,924.33044 C 306.36081,927.44488 319.91562,951.28677 336.16102,971.47019 C 330.63113,923.39416 318.10631,907.05369 307.78707,880.74589 C 337.78137,886.82754 358.36643,912.61828 371.76686,953.45839 C 381.32101,949.54048 390.00462,944.08545 401.95427,944.39719 C 390.65677,902.70139 384.00481,874.48135 365.26702,843.32725 C 418.70898,848.99758 448.92404,923.96657 444.23844,931.28805 C 454.21641,929.04406 463.24409,924.75767 474.67497,925.63638 C 463.426,887.28936 453.62716,848.76848 471.01526,806.98819 C 471.01526,806.98819 519.30204,872.42507 525.40492,892.79397 C 531.50779,913.16287 526.92373,931.49448 526.92373,931.49448 C 526.92373,931.49448 543.8833,962.57978 547.21765,982.58862 C 550.59075,1002.83 543.68496,1041.6919 542.27183,1060.5719 z" +- id="path4189" +- sodipodi:nodetypes="czzzzzzcccccccccczczz" /> +- <path +- style="opacity:1;fill:#ffffff;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;marker:none;marker-start:none;marker-mid:none;marker-end:none;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;visibility:visible;display:inline;overflow:visible;filter:url(#filter3587);enable-background:accumulate" +- d="M 719.5,738.69519 L 737.81177,754.12715 L 782.2228,738.73894 L 805.5,713.19519 L 816.96397,732.41584 L 847.63558,745.19938 L 872.73295,750.92775 L 892,723.19519 L 908.02309,747.02126 L 947,752.19519 L 957.24541,745.99667 L 964.00012,754.69487 L 989.5,765.69519 L 991.5,725.19519 L 955.94866,710.6576 L 923.45591,689.1305 L 883.0038,677.66492 L 861.69668,662.13148 L 840,685.19519 L 755.02878,638.61208 L 722,676.69519 L 719.5,738.69519 z" +- id="path4191" +- sodipodi:nodetypes="cccccccccccccccccccccc" +- clip-path="url(#clipPath3631)" +- transform="matrix(-0.9045327,0.2506626,0.2506626,0.9045327,995.28646,23.53493)" /> +- <path +- style="opacity:0.58775509;fill:#000000;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:20.79999924;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1;display:inline;filter:url(#filter3898);enable-background:new" +- d="M 584,696.5 L 577.4375,713.65625 C 577.4375,713.65625 569.62598,734.02113 561.75,757.3125 C 557.81201,768.95818 553.86698,781.35395 550.8125,792.4375 C 547.75802,803.52105 545.47664,812.81736 545.3125,820.71875 C 544.91443,839.88071 551.05903,855.60705 554.25,862.46875 C 553.47847,866.02398 552.25863,871.92307 550.90625,880.5625 C 548.98583,892.83071 547.18798,907.71691 548.53125,920.4375 C 549.91334,933.52585 555.34347,948.62515 561.125,963.46875 C 566.90653,978.31235 573.17935,992.69586 576.34375,1001.5 C 582.97581,1019.9519 586.33671,1033.0763 587.65625,1050 C 588.2376,1057.4561 587.41398,1070.336 586.40625,1083.375 C 585.39852,1096.414 584.21964,1109.6764 584.71875,1120.3438 C 585.70786,1141.4836 594.04673,1167.1785 618.09375,1178.2812 C 640.86858,1188.7966 673.42057,1189.9834 701.53125,1174.8438 C 717.69117,1166.1404 731.60759,1147.7462 744.90625,1127.9375 C 758.20491,1108.1288 769.87542,1086.8841 776.84375,1073.0312 C 792.19667,1042.51 816.23728,957.56702 822.46875,920.3125 C 825.48734,902.26597 826.39041,891.24695 825.09375,882.28125 C 824.11522,875.51521 821.26556,870.13385 818.21875,866.0625 C 820.26149,838.55459 817.48668,814.69372 830.1875,786.65625 L 840.75,763.375 L 816.9375,772.6875 C 799.44775,779.52503 788.03586,791.73286 780.34375,804.75 C 780.02124,805.29577 779.78061,805.85776 779.46875,806.40625 C 779.69078,783.89104 783.87659,768.76866 786.0625,747.71875 L 788.03125,728.71875 L 771,737.375 C 740.40551,752.93071 725.30511,785.56821 721.28125,827.59375 C 717.03593,826.96828 712.44985,826.5741 707.46875,826.75 C 707.17726,787.56964 707.07246,759.71315 716.0625,727.375 L 721.65625,707.25 L 702.21875,714.90625 C 671.30938,727.11019 654.35921,756.83698 645.59375,783.28125 C 641.21102,796.50339 638.84793,809.08246 638,819.21875 C 637.76797,821.99248 637.68894,824.53007 637.6875,826.9375 C 634.44563,826.90109 631.26698,827.07339 627.625,827.4375 C 627.66662,788.43277 624.14076,747.68335 595.34375,710.9375 L 584,696.5 z M 589.8125,740.3125 C 606.61941,770.95633 607.28701,804.27978 606.75,840.0625 L 606.53125,855.125 L 618.56618,848.58579 C 627.22823,845.45277 638.12676,848.35827 650.5,847.75 L 665.17465,857.1066 L 658.84375,831.3125 C 658.7541,831.08253 658.62329,830.89581 658.59375,830.59375 C 658.39424,828.55389 658.37143,825.12068 658.71875,820.96875 C 659.41339,812.66489 661.50832,801.38351 665.34375,789.8125 C 670.49907,774.25956 678.83176,758.62002 690.46875,747.28125 C 685.78494,775.91923 687.25316,807.54059 687.45711,843.08639 L 684.69118,856.34803 L 700.1875,848.75 C 709.2169,845.99229 717.37647,848.40004 729.46875,849.84375 L 742.71507,859.28798 L 741.09375,840 C 742.54168,809.02823 749.31524,786.32192 761.8125,771.125 C 758.82562,790.90384 756.38207,812.9098 762.125,849.46875 L 763.19052,855.84193 L 760.25237,867.35878 L 770.86948,859.1906 L 780.05921,869.41258 L 778.51093,858.94898 L 781.9375,852 C 787.63852,838.78851 792.11032,825.78663 798.28125,815.34375 C 799.24111,813.71941 800.31278,812.27939 801.34375,810.78125 C 797.66309,831.9366 798.91659,850.9894 797.25,868.5625 L 792.56986,876.36948 L 799.96875,876.59375 C 803.1888,880.07736 803.83625,880.44443 804.53125,885.25 C 805.22625,890.05557 804.84987,899.65035 801.96875,916.875 C 796.40076,950.16292 770.12313,994.71481 758.22835,1018.3614 C 751.62344,1031.4918 739.70002,1075.8473 727.105,1094.6079 C 714.50998,1113.3684 698.57363,1134.3752 689.93296,1139.0288 C 668.44244,1150.603 645.37702,1164.5347 629.31407,1157.1183 C 614.93921,1150.4813 606.27438,1135.9256 605.5,1119.375 C 605.11689,1111.187 606.11279,1098.0658 607.125,1084.9688 C 608.13721,1071.8717 618.41391,1062.398 622.54839,1048.4062 C 627.92068,1030.2254 621.10152,1011.8118 610.04839,994.46875 C 603.56184,984.29097 586.07159,970.21085 580.5,955.90625 C 574.92841,941.60165 570.13249,926.9031 569.21875,918.25 C 568.29254,909.47887 569.64125,895.22498 571.4375,883.75 C 573.23375,872.27503 575.28125,863.46875 575.28125,863.46875 L 584.70403,859.85355 L 574.21875,855.96875 C 574.21875,855.96875 565.71986,840.65865 566.125,821.15625 C 566.19611,817.73309 567.96126,808.4282 570.84375,797.96875 C 573.72624,787.5093 577.60841,775.41604 581.46875,764 C 584.51314,754.99692 587.24938,747.39655 589.8125,740.3125 z" +- id="path4193" +- clip-path="url(#clipPath3677)" +- sodipodi:nodetypes="ccssscsssssssssssssccccscccccccccsscccccccccccssscccccccccccccccsccccssssssssssssscccsssc" +- transform="matrix(-0.9045327,0.2506626,0.2506626,0.9045327,822.28931,10.93589)" /> +- <g +- id="g3617" +- clip-path="url(#clipPath3622)" +- transform="translate(276,136)"> +- <path +- transform="matrix(-0.9045327,0.2506626,0.2506626,0.9045327,-52.200498,74.09707)" +- id="path4195" +- d="M -15.66751,843.48852 L -65.16499,827.93217 L -92.03504,880.25807 L -51.02285,925.51291 L -1.52538,887.32914 L -15.66751,843.48852 z" +- style="opacity:1;fill:#ffffff;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;marker:none;marker-start:none;marker-mid:none;marker-end:none;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;visibility:visible;display:inline;overflow:visible;filter:url(#filter9024);enable-background:accumulate" /> +- <path +- sodipodi:nodetypes="ccccccccccccc" +- transform="matrix(-0.9045327,0.2506626,0.2506626,0.9045327,-46.92842,75.511284)" +- id="path4197" +- d="M 118.70648,859.93048 L 63.552152,813.26144 L 19.711532,850.03099 L 53.652662,903.7711 L 40.055848,989.23313 L 0.61048221,1017.5253 L -40.401718,1028.839 L -43.230138,1075.508 L 13.338402,1100.9639 L 32.282389,1031.3139 L 55.738939,972.45727 L 102.08648,899.84236 L 118.70648,859.93048 z" +- style="opacity:1;fill:#ffffff;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;marker:none;marker-start:none;marker-mid:none;marker-end:none;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;visibility:visible;display:inline;overflow:visible;filter:url(#filter9020);enable-background:accumulate" /> +- </g> +- <path +- style="opacity:0.25;fill:#000000;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;marker:none;marker-start:none;marker-mid:none;marker-end:none;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;visibility:visible;display:inline;overflow:visible;filter:url(#filter9044);enable-background:accumulate" +- d="M -70.82184,932.58397 L -10.01066,905.71392 L 90.3985,936.82662 L 26.75889,967.93931 L -55.26549,950.96875 L -70.82184,932.58397 z" +- id="path4199" +- transform="matrix(-0.9045327,0.2506626,0.2506626,0.9045327,229.07158,211.51128)" /> +- <path +- style="opacity:0.58775509;fill:#000000;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:20.79999924;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1;display:inline;filter:url(#filter4105);enable-background:new" +- d="M 583.0625,715.75 C 570.95641,750.19974 556.348,784.28333 551.3125,820.59375 C 550.48042,835.52242 555.90165,849.75318 560.15625,863.65625 C 554.24001,890.85751 550.01944,920.5562 561.3125,946.78125 C 574.82967,984.9421 596.31397,1022.4634 593.73529,1064.2495 C 592.78699,1093.5437 584.72085,1125.2436 599.125,1152.5312 C 609.32364,1171.866 632.26456,1179.8429 653.09285,1180.1988 C 680.95504,1181.3729 709.55546,1168.5772 725.09375,1144.9375 C 747.68924,1115.5658 766.89426,1083.4402 780.3324,1048.8777 C 797.22293,1003.3717 810.0042,956.31698 818.26642,908.4788 C 820.09082,895.53774 821.3675,881.00895 813.6875,869.65625 C 810.25635,862.31993 813.72957,854.09611 813.00293,846.34648 C 813.67693,821.35182 817.01525,795.68272 829.65625,773.75 C 811.92312,780.1946 794.58357,790.30971 785.65318,807.61425 C 781.7181,814.3238 778.04836,821.18838 774.28125,828 C 770.73126,797.98592 778.00088,768.35172 781.0625,738.71875 C 760.89646,747.77338 744.18578,764.37397 736.88755,785.40075 C 730.58292,800.98078 728.08533,817.71793 726.625,834.4375 C 718.37166,832.91825 709.94053,832.33595 701.5625,832.9375 C 700.59942,794.23963 701.09554,753.53035 712.53125,717.03125 C 693.85012,723.24901 677.36504,735.76676 666.90322,752.41848 C 653.05068,773.29827 645.64182,798.17243 643.84375,823.03125 C 644.42909,827.35579 643.78249,834.87134 637.5,832.90625 C 632.16882,832.9238 626.87092,833.58508 621.5625,834 C 622.71034,794.61852 618.22106,752.3718 594.5,719.78125 C 591.43929,716.14408 588.86315,712.09687 585.875,708.4375 C 584.9375,710.875 584,713.3125 583.0625,715.75 z M 590.8125,729.59375 C 609.37777,758.89004 613.295,794.41387 612.9375,828.46875 C 613.14159,833.64401 612.42094,840.29795 613.0625,844.53125 C 625.38106,838.4285 639.80162,842.09135 652.84375,842.34375 C 655.16087,843.567 656.03585,843.99618 654.75,840.9375 C 650.58545,826.98465 652.90172,812.3245 656.55504,798.52986 C 662.92191,772.23922 677.18332,747.44188 699.375,731.5 C 690.75791,768.73706 693.65842,808.06161 693.28125,845.46875 C 705.53469,838.55885 720.56004,842.02262 733.3125,845.21875 C 736.70472,848.75355 735.60185,844.48927 735.5,841.40625 C 735.01691,820.03567 739.63133,798.33662 749.1875,779.25 C 755.15016,768.56273 763.43088,759.44621 771.625,750.375 C 763.75344,784.2131 762.4221,819.71093 768.90625,853.875 C 770.6311,852.46382 773.51306,853.42086 774.5625,853.5 C 784.24619,832.26318 790.91362,808.11938 809.45266,792.75815 C 811.32595,792.38693 808.00448,801.2831 807.96875,804.65625 C 804.43387,826.50206 800.79359,848.79859 799.18454,870.87536 C 790.40075,873.21707 802.03289,873.1989 802.65329,874.93786 C 810.5764,885.50366 807.31628,899.34258 806.28494,911.2912 C 799.22089,956.32475 784.14263,998.65314 770.33139,1041.971 C 758.25663,1074.9203 742.95719,1100.8235 722.44331,1129.1725 C 711.49074,1142.7239 699.19859,1157.0238 681.59956,1161.6725 C 661.44355,1167.9138 637.3928,1172.5494 619,1161.7188 C 601.71034,1149.3774 597.97607,1126.0099 599.73774,1106.0324 C 599.78653,1090.2062 604.6766,1077.5203 604.14834,1062.5406 C 603.6101,1047.2777 601.85699,1031.9759 597.60573,1015.6743 C 593.35447,999.37268 588.56248,990.75636 581.48667,974.10092 C 574.24556,957.05636 566.41652,937.35229 563.28125,917.8125 C 561.53177,899.18536 566.17296,880.68988 569.0625,862.5625 C 572.35873,859.72554 567.46451,857.36591 566.75,854.375 C 559.14887,837.35992 558.34253,817.6001 564.00766,799.81502 C 571.13786,774.74272 579.76853,750.18261 588.6875,725.6875 C 589.39583,726.98958 590.10417,728.29167 590.8125,729.59375 z" +- id="path4201" +- sodipodi:nodetypes="ccccccccccccccccccccccccccccccccccccccccccccccccccczzzcccccc" +- clip-path="url(#clipPath4177)" +- transform="matrix(-0.9045327,0.2506626,0.2506626,0.9045327,822.28931,10.93589)" /> +- <path +- style="opacity:1;fill:#ffffff;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;marker:none;marker-start:none;marker-mid:none;marker-end:none;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;visibility:visible;display:inline;overflow:visible;filter:url(#filter4130);enable-background:accumulate" +- d="M 735.05635,733.03834 L 737.81177,754.12715 L 782.2228,738.73894 L 787.07343,716.34919 L 783.13726,694.29697 L 760.68563,657.70396 L 752.40559,688.0089 L 735.05635,733.03834 z" +- id="path4203" +- sodipodi:nodetypes="cccccccc" +- clip-path="url(#clipPath3631)" +- transform="matrix(-0.9045327,0.2506626,0.2506626,0.9045327,995.28646,23.53493)" /> +- <path +- style="opacity:1;fill:#ffffff;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;marker:none;marker-start:none;marker-mid:none;marker-end:none;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;visibility:visible;display:inline;overflow:visible;filter:url(#filter4141);enable-background:accumulate" +- d="M 831.81321,730.29452 L 847.63558,745.19938 L 868.49031,748.09932 L 866.90002,708.17334 L 875.22563,677.66492 L 868.06064,671.32386 L 846.36395,692.26626 L 831.81321,730.29452 z" +- id="path4205" +- sodipodi:nodetypes="cccccccc" +- clip-path="url(#clipPath3631)" +- transform="matrix(-0.9045327,0.2506626,0.2506626,0.9045327,995.28646,23.53493)" /> +- <g +- id="g8317" +- style="filter:url(#filter8333)" +- clip-path="url(#clipPath8338)" +- transform="translate(276,136)"> +- <path +- transform="matrix(-0.9045327,0.2506626,0.2506626,0.9045327,719.28646,-112.46507)" +- clip-path="none" +- sodipodi:nodetypes="ccccc" +- id="path4209" +- d="M 964.00012,754.69487 L 982.42893,762.15966 L 991.5,725.19519 L 976.62969,730.03405 L 964.00012,754.69487 z" +- style="opacity:1;fill:#ffffff;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;marker:none;marker-start:none;marker-mid:none;marker-end:none;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" /> +- <rect +- y="757.19519" +- x="-55" +- height="177" +- width="182" +- id="rect8315" +- style="opacity:1;fill:none;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:25;stroke-linecap:butt;stroke-linejoin:miter;marker:none;marker-start:none;marker-mid:none;marker-end:none;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" /> +- </g> +- <g +- id="g8346" +- style="filter:url(#filter8354)" +- clip-path="url(#clipPath8359)" +- transform="translate(276,136)"> +- <path +- transform="matrix(-0.9045327,0.2506626,0.2506626,0.9045327,719.28646,-112.46507)" +- clip-path="none" +- sodipodi:nodetypes="ccccccc" +- id="path4207" +- d="M 910.14441,746.31415 L 942.75736,751.48808 L 942.39617,727.61189 L 949.5847,697.92968 L 941.13358,692.66603 L 919.31164,719.1768 L 910.14441,746.31415 z" +- style="opacity:1;fill:#ffffff;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;marker:none;marker-start:none;marker-mid:none;marker-end:none;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" /> +- <rect +- y="696.19519" +- x="-22" +- height="176" +- width="165" +- id="rect8344" +- style="opacity:1;fill:none;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:25;stroke-linecap:butt;stroke-linejoin:miter;marker:none;marker-start:none;marker-mid:none;marker-end:none;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" /> +- </g> +- </g> +- <g +- inkscape:groupmode="layer" +- id="layer16" +- inkscape:label="Left Foot" +- style="display:inline"> +- <path +- style="opacity:1;fill:#ada469;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;display:inline;enable-background:new" +- d="M 1036.164,1071.8338 C 1042.9581,1090.7366 1046.6577,1105.1335 1048.0543,1123.0457 C 1049.4509,1140.958 1044.2716,1174.8465 1045.1538,1193.7018 C 1046.0356,1212.547 1053.2875,1233.8008 1072.4984,1242.6707 C 1091.9173,1251.6365 1121.8177,1252.882 1146.6183,1239.5251 C 1171.4189,1226.1681 1204.0193,1169.1996 1217.5925,1142.2164 C 1231.2164,1115.1325 1256.3536,1027.719 1262.2533,992.44781 C 1268.1531,957.1766 1264.8039,951.14704 1257.6359,943.39232 C 1260.2762,915.55217 1256.1361,888.45689 1270.7455,856.20614 C 1240.4965,868.03184 1233.3632,896.36684 1222.4266,921.71122 C 1214.4257,870.77829 1222.6358,850.43803 1225.7455,820.49186 C 1196.6808,835.26977 1182.884,867.60588 1180.7455,913.349 C 1169.8216,912.0448 1159.3541,908.91477 1147.1741,912.63471 C 1146.9101,866.61137 1145.7106,835.7453 1156.0847,798.42822 C 1102.8293,819.45508 1093.1375,905.02232 1100.0312,911.20614 C 1089.1484,911.74114 1078.6602,909.90884 1067.1741,914.06329 C 1067.813,871.49194 1066.9136,829.15468 1037.1741,791.20614 C 1037.1741,791.20614 1006.2161,872.12848 1005.7455,894.77757 C 1005.275,917.42666 1015.1971,934.94345 1015.1971,934.94345 C 1015.1971,934.94345 1006.6291,971.68396 1008.8985,993.17568 C 1011.1944,1014.9171 1029.3414,1052.8519 1036.164,1071.8338 z" +- id="path8848" +- sodipodi:nodetypes="czzzzzzcccccccccczczz" /> +- <path +- style="opacity:1;fill:#ffffff;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;marker:none;marker-start:none;marker-mid:none;marker-end:none;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;visibility:visible;display:inline;overflow:visible;filter:url(#filter3587);enable-background:accumulate" +- d="M 719.5,738.69519 L 737.81177,754.12715 L 782.2228,738.73894 L 805.5,713.19519 L 816.96397,732.41584 L 847.63558,745.19938 L 872.73295,750.92775 L 892,723.19519 L 908.02309,747.02126 L 947,752.19519 L 957.24541,745.99667 L 964.00012,754.69487 L 989.5,765.69519 L 991.5,725.19519 L 955.94866,710.6576 L 923.45591,689.1305 L 883.0038,677.66492 L 861.69668,662.13148 L 840,685.19519 L 755.02878,638.61208 L 722,676.69519 L 719.5,738.69519 z" +- id="path3635" +- sodipodi:nodetypes="cccccccccccccccccccccc" +- clip-path="url(#clipPath3631)" +- transform="translate(276,136)" /> +- <path +- transform="translate(450.03125,73.843964)" +- style="opacity:0.58775509;fill:#000000;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:20.79999924;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1;display:inline;filter:url(#filter3898);enable-background:new" +- d="M 584,696.5 L 577.4375,713.65625 C 577.4375,713.65625 569.62598,734.02113 561.75,757.3125 C 557.81201,768.95818 553.86698,781.35395 550.8125,792.4375 C 547.75802,803.52105 545.47664,812.81736 545.3125,820.71875 C 544.91443,839.88071 551.05903,855.60705 554.25,862.46875 C 553.47847,866.02398 552.25863,871.92307 550.90625,880.5625 C 548.98583,892.83071 547.18798,907.71691 548.53125,920.4375 C 549.91334,933.52585 555.34347,948.62515 561.125,963.46875 C 566.90653,978.31235 573.17935,992.69586 576.34375,1001.5 C 582.97581,1019.9519 586.33671,1033.0763 587.65625,1050 C 588.2376,1057.4561 587.41398,1070.336 586.40625,1083.375 C 585.39852,1096.414 584.21964,1109.6764 584.71875,1120.3438 C 585.70786,1141.4836 594.04673,1167.1785 618.09375,1178.2812 C 640.86858,1188.7966 673.42057,1189.9834 701.53125,1174.8438 C 717.69117,1166.1404 731.60759,1147.7462 744.90625,1127.9375 C 758.20491,1108.1288 769.87542,1086.8841 776.84375,1073.0312 C 792.19667,1042.51 816.23728,957.56702 822.46875,920.3125 C 825.48734,902.26597 826.39041,891.24695 825.09375,882.28125 C 824.11522,875.51521 821.26556,870.13385 818.21875,866.0625 C 820.26149,838.55459 817.48668,814.69372 830.1875,786.65625 L 840.75,763.375 L 816.9375,772.6875 C 799.44775,779.52503 788.03586,791.73286 780.34375,804.75 C 780.02124,805.29577 779.78061,805.85776 779.46875,806.40625 C 779.69078,783.89104 783.87659,768.76866 786.0625,747.71875 L 788.03125,728.71875 L 771,737.375 C 740.40551,752.93071 725.30511,785.56821 721.28125,827.59375 C 717.03593,826.96828 712.44985,826.5741 707.46875,826.75 C 707.17726,787.56964 707.07246,759.71315 716.0625,727.375 L 721.65625,707.25 L 702.21875,714.90625 C 671.30938,727.11019 654.35921,756.83698 645.59375,783.28125 C 641.21102,796.50339 638.84793,809.08246 638,819.21875 C 637.76797,821.99248 637.68894,824.53007 637.6875,826.9375 C 634.44563,826.90109 631.26698,827.07339 627.625,827.4375 C 627.66662,788.43277 624.14076,747.68335 595.34375,710.9375 L 584,696.5 z M 589.8125,740.3125 C 606.61941,770.95633 607.28701,804.27978 606.75,840.0625 L 606.53125,855.125 L 618.56618,848.58579 C 627.22823,845.45277 638.12676,848.35827 650.5,847.75 L 665.17465,857.1066 L 658.84375,831.3125 C 658.7541,831.08253 658.62329,830.89581 658.59375,830.59375 C 658.39424,828.55389 658.37143,825.12068 658.71875,820.96875 C 659.41339,812.66489 661.50832,801.38351 665.34375,789.8125 C 670.49907,774.25956 678.83176,758.62002 690.46875,747.28125 C 685.78494,775.91923 687.25316,807.54059 687.45711,843.08639 L 684.69118,856.34803 L 700.1875,848.75 C 709.2169,845.99229 717.37647,848.40004 729.46875,849.84375 L 742.71507,859.28798 L 741.09375,840 C 742.54168,809.02823 749.31524,786.32192 761.8125,771.125 C 758.82562,790.90384 756.38207,812.9098 762.125,849.46875 L 763.19052,855.84193 L 760.25237,867.35878 L 770.86948,859.1906 L 780.05921,869.41258 L 778.51093,858.94898 L 781.9375,852 C 787.63852,838.78851 792.11032,825.78663 798.28125,815.34375 C 799.24111,813.71941 800.31278,812.27939 801.34375,810.78125 C 797.66309,831.9366 798.91659,850.9894 797.25,868.5625 L 792.56986,876.36948 L 799.96875,876.59375 C 803.1888,880.07736 803.83625,880.44443 804.53125,885.25 C 805.22625,890.05557 804.84987,899.65035 801.96875,916.875 C 796.40076,950.16292 770.17603,1040.0409 758.28125,1063.6875 C 751.67634,1076.8179 740.25127,1097.5832 727.65625,1116.3438 C 715.06123,1135.1043 700.29692,1151.8776 691.65625,1156.5312 C 670.16573,1168.1054 642.87545,1166.7914 626.8125,1159.375 C 612.43764,1152.738 606.27438,1135.9256 605.5,1119.375 C 605.11689,1111.187 606.11279,1098.0658 607.125,1084.9688 C 608.13721,1071.8717 618.41391,1062.398 622.54839,1048.4062 C 627.92068,1030.2254 621.10152,1011.8118 610.04839,994.46875 C 603.56184,984.29097 586.07159,970.21085 580.5,955.90625 C 574.92841,941.60165 570.13249,926.9031 569.21875,918.25 C 568.29254,909.47887 569.64125,895.22498 571.4375,883.75 C 573.23375,872.27503 575.28125,863.46875 575.28125,863.46875 L 584.70403,859.85355 L 574.21875,855.96875 C 574.21875,855.96875 565.71986,840.65865 566.125,821.15625 C 566.19611,817.73309 567.96126,808.4282 570.84375,797.96875 C 573.72624,787.5093 577.60841,775.41604 581.46875,764 C 584.51314,754.99692 587.24938,747.39655 589.8125,740.3125 z" +- id="path3669" +- clip-path="url(#clipPath3677)" +- sodipodi:nodetypes="ccssscsssssssssssssccccscccccccccsscccccccccccssscccccccccccccccsccccssssssssssssscccsssc" /> +- <g +- id="g3628" +- clip-path="url(#clipPath3636)" +- transform="translate(276,136)"> +- <path +- id="path8988" +- d="M 824.48651,818.48242 L 774.98903,802.92607 L 748.11898,855.25197 L 789.13117,900.50681 L 838.62864,862.32304 L 824.48651,818.48242 z" +- style="opacity:1;fill:#ffffff;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;marker:none;marker-start:none;marker-mid:none;marker-end:none;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;visibility:visible;display:inline;overflow:visible;filter:url(#filter9024);enable-background:accumulate" /> +- <path +- id="path8990" +- d="M 964.49365,855.25197 L 909.33932,808.58293 L 865.4987,845.35248 L 899.43983,899.09259 L 906.51089,965.56063 L 855.59921,1000.916 L 814.58701,1012.2297 L 811.75859,1058.8987 L 868.32713,1084.3546 L 931.96674,1007.987 L 956.00837,913.23473 L 964.49365,855.25197 z" +- style="opacity:1;fill:#ffffff;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;marker:none;marker-start:none;marker-mid:none;marker-end:none;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;visibility:visible;display:inline;overflow:visible;filter:url(#filter9020);enable-background:accumulate" /> +- </g> +- <path +- style="opacity:0.25;fill:#000000;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;marker:none;marker-start:none;marker-mid:none;marker-end:none;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;visibility:visible;display:inline;overflow:visible;filter:url(#filter9044);enable-background:accumulate" +- d="M 1045.3322,1043.5779 L 1106.1434,1016.7078 L 1206.5525,1047.8205 L 1142.9129,1078.9332 L 1060.8885,1061.9626 L 1045.3322,1043.5779 z" +- id="path8992" /> +- <path +- transform="translate(450.03125,73.843964)" +- style="opacity:0.58775509;fill:#000000;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:20.79999924;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1;display:inline;filter:url(#filter4185);enable-background:new" +- d="M 583.0625,715.75 C 570.95641,750.19974 556.348,784.28333 551.3125,820.59375 C 550.48042,835.52242 555.90165,849.75318 560.15625,863.65625 C 554.24001,890.85751 550.01944,920.5562 561.3125,946.78125 C 574.82967,984.9421 596.31397,1022.4634 593.73529,1064.2495 C 592.78699,1093.5437 584.72085,1125.2436 599.125,1152.5312 C 609.32364,1171.866 632.26456,1179.8429 653.09285,1180.1988 C 680.95504,1181.3729 709.55546,1168.5772 725.09375,1144.9375 C 747.68924,1115.5658 766.89426,1083.4402 780.3324,1048.8777 C 797.22293,1003.3717 810.0042,956.31698 818.26642,908.4788 C 820.09082,895.53774 821.3675,881.00895 813.6875,869.65625 C 810.25635,862.31993 813.72957,854.09611 813.00293,846.34648 C 813.67693,821.35182 817.01525,795.68272 829.65625,773.75 C 811.92312,780.1946 794.58357,790.30971 785.65318,807.61425 C 781.7181,814.3238 778.04836,821.18838 774.28125,828 C 770.73126,797.98592 778.00088,768.35172 781.0625,738.71875 C 760.89646,747.77338 744.18578,764.37397 736.88755,785.40075 C 730.58292,800.98078 728.08533,817.71793 726.625,834.4375 C 718.37166,832.91825 709.94053,832.33595 701.5625,832.9375 C 700.59942,794.23963 701.09554,753.53035 712.53125,717.03125 C 693.85012,723.24901 677.36504,735.76676 666.90322,752.41848 C 653.05068,773.29827 645.64182,798.17243 643.84375,823.03125 C 644.42909,827.35579 643.78249,834.87134 637.5,832.90625 C 632.16882,832.9238 626.87092,833.58508 621.5625,834 C 622.71034,794.61852 618.22106,752.3718 594.5,719.78125 C 591.43929,716.14408 588.86315,712.09687 585.875,708.4375 C 584.9375,710.875 584,713.3125 583.0625,715.75 z M 590.8125,729.59375 C 609.37777,758.89004 613.295,794.41387 612.9375,828.46875 C 613.14159,833.64401 612.42094,840.29795 613.0625,844.53125 C 625.38106,838.4285 639.80162,842.09135 652.84375,842.34375 C 655.16087,843.567 656.03585,843.99618 654.75,840.9375 C 650.58545,826.98465 652.90172,812.3245 656.55504,798.52986 C 662.92191,772.23922 677.18332,747.44188 699.375,731.5 C 690.75791,768.73706 693.65842,808.06161 693.28125,845.46875 C 705.53469,838.55885 720.56004,842.02262 733.3125,845.21875 C 736.70472,848.75355 735.60185,844.48927 735.5,841.40625 C 735.01691,820.03567 739.63133,798.33662 749.1875,779.25 C 755.15016,768.56273 763.43088,759.44621 771.625,750.375 C 763.75344,784.2131 762.4221,819.71093 768.90625,853.875 C 770.6311,852.46382 773.51306,853.42086 774.5625,853.5 C 784.24619,832.26318 790.91362,808.11938 809.45266,792.75815 C 811.32595,792.38693 808.00448,801.2831 807.96875,804.65625 C 804.43387,826.50206 804.67155,848.82948 803.0625,870.90625 C 801.75012,872.28304 805.91085,873.22979 806.53125,874.96875 C 814.45436,885.53455 809.65419,899.80024 808.62285,911.74886 C 801.5588,956.78241 786.85732,1000.1282 773.04608,1043.446 C 760.97132,1076.3953 742.32638,1106.526 721.8125,1134.875 C 710.85993,1148.4264 698.56778,1162.7263 680.96875,1167.375 C 660.81274,1173.6163 637.3928,1172.5494 619,1161.7188 C 601.71034,1149.3774 597.97607,1126.0099 599.73774,1106.0324 C 599.78653,1090.2062 602.10985,1078.2316 607.65521,1063.2271 C 613.20056,1048.2226 610.12626,1031.8954 605.875,1015.5938 C 601.62374,999.2922 593.69597,989.33378 584.05342,973.38963 C 574.41087,957.44548 566.41652,937.35229 563.28125,917.8125 C 561.53177,899.18536 566.17296,880.68988 569.0625,862.5625 C 572.35873,859.72554 567.46451,857.36591 566.75,854.375 C 559.14887,837.35992 558.34253,817.6001 564.00766,799.81502 C 571.13786,774.74272 579.76853,750.18261 588.6875,725.6875 C 589.39583,726.98958 590.10417,728.29167 590.8125,729.59375 z" +- id="path4149" +- sodipodi:nodetypes="ccccccccccccccccccccccccccccccccccccccccccccccccccczzzcccccc" +- clip-path="url(#clipPath4177)" /> +- <path +- style="opacity:1;fill:#ffffff;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;marker:none;marker-start:none;marker-mid:none;marker-end:none;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;visibility:visible;display:inline;overflow:visible;filter:url(#filter4130);enable-background:accumulate" +- d="M 735.05635,733.03834 L 737.81177,754.12715 L 782.2228,738.73894 L 787.07343,716.34919 L 783.13726,694.29697 L 760.68563,657.70396 L 752.40559,688.0089 L 735.05635,733.03834 z" +- id="path3902" +- sodipodi:nodetypes="cccccccc" +- clip-path="url(#clipPath3631)" +- transform="translate(276,136)" /> +- <path +- style="opacity:1;fill:#ffffff;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;marker:none;marker-start:none;marker-mid:none;marker-end:none;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;visibility:visible;display:inline;overflow:visible;filter:url(#filter4141);enable-background:accumulate" +- d="M 831.81321,730.29452 L 847.63558,745.19938 L 868.49031,748.09932 L 866.90002,708.17334 L 875.22563,677.66492 L 868.06064,671.32386 L 846.36395,692.26626 L 831.81321,730.29452 z" +- id="path4135" +- sodipodi:nodetypes="cccccccc" +- clip-path="url(#clipPath3631)" +- transform="translate(276,136)" /> +- <g +- id="g8367" +- style="filter:url(#filter8379)" +- clip-path="url(#clipPath8392)" +- transform="translate(276,136)"> +- <path +- clip-path="none" +- sodipodi:nodetypes="ccccccc" +- id="path4145" +- d="M 910.14441,746.31415 L 942.75736,751.48808 L 942.39617,727.61189 L 949.5847,697.92968 L 941.13358,692.66603 L 919.31164,719.1768 L 910.14441,746.31415 z" +- style="opacity:1;fill:#ffffff;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;marker:none;marker-start:none;marker-mid:none;marker-end:none;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" /> +- <rect +- y="650.19098" +- x="877.51953" +- height="172.53406" +- width="123.03658" +- id="rect8365" +- style="opacity:1;fill:none;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:25;stroke-linecap:butt;stroke-linejoin:miter;marker:none;marker-start:none;marker-mid:none;marker-end:none;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" /> +- </g> +- <g +- id="g8400" +- style="filter:url(#filter8404)" +- clip-path="url(#clipPath8417)" +- transform="translate(276,136)"> +- <path +- clip-path="none" +- sodipodi:nodetypes="ccccc" +- id="path4147" +- d="M 964.00012,754.69487 L 982.42893,762.15966 L 991.5,725.19519 L 976.62969,730.03405 L 964.00012,754.69487 z" +- style="opacity:1;fill:#ffffff;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;marker:none;marker-start:none;marker-mid:none;marker-end:none;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" /> +- <rect +- y="677.06104" +- x="924.89569" +- height="125.1579" +- width="142.12846" +- id="rect8398" +- style="opacity:1;fill:none;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:25;stroke-linecap:butt;stroke-linejoin:miter;marker:none;marker-start:none;marker-mid:none;marker-end:none;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" /> +- </g> +- </g> +-</svg> +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/Documentation/logo.txt linux-2.6.29-rc3.owrt/Documentation/logo.txt +--- linux-2.6.29.owrt/Documentation/logo.txt 2009-05-10 22:04:39.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/Documentation/logo.txt 2009-05-10 23:48:28.000000000 +0200 +@@ -1,4 +1,13 @@ +-Tux is taking a three month sabbatical to work as a barber, so Tuz is +-standing in. He's taken pains to ensure you'll hardly notice. ++This is the full-colour version of the currently unofficial Linux logo ++("currently unofficial" just means that there has been no paperwork and ++that I have not really announced it yet). It was created by Larry Ewing, ++and is freely usable as long as you acknowledge Larry as the original ++artist. ++ ++Note that there are black-and-white versions of this available that ++scale down to smaller sizes and are better for letterheads or whatever ++you want to use it for: for the full range of logos take a look at ++Larry's web-page: ++ ++ http://www.isc.tamu.edu/~lewing/linux/ + +-Image by Andrew McGown and Josh Bush. Image is licensed CC BY-SA. +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/Documentation/networking/alias.txt linux-2.6.29-rc3.owrt/Documentation/networking/alias.txt +--- linux-2.6.29.owrt/Documentation/networking/alias.txt 2009-05-10 22:04:39.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/Documentation/networking/alias.txt 2009-05-10 23:48:28.000000000 +0200 +@@ -2,14 +2,14 @@ + IP-Aliasing: + ============ + +-IP-aliases are an obsolete way to manage multiple IP-addresses/masks +-per interface. Newer tools such as iproute2 support multiple +-address/prefixes per interface, but aliases are still supported +-for backwards compatibility. +- +-An alias is formed by adding a colon and a string when running ifconfig. ++IP-aliases are additional IP-addresses/masks hooked up to a base ++interface by adding a colon and a string when running ifconfig. + This string is usually numeric, but this is not a must. + ++IP-Aliases are avail if CONFIG_INET (`standard' IPv4 networking) ++is configured in the kernel. ++ ++ + o Alias creation. + Alias creation is done by 'magic' interface naming: eg. to create a + 200.1.1.1 alias for eth0 ... +@@ -38,3 +38,16 @@ + + If the base device is shut down the added aliases will be deleted + too. ++ ++ ++Contact ++------- ++Please finger or e-mail me: ++ Juan Jose Ciarlante <jjciarla@raiz.uncu.edu.ar> ++ ++Updated by Erik Schoenfelder <schoenfr@gaertner.DE> ++ ++; local variables: ++; mode: indented-text ++; mode: auto-fill ++; end: +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/Documentation/networking/ipv6.txt linux-2.6.29-rc3.owrt/Documentation/networking/ipv6.txt +--- linux-2.6.29.owrt/Documentation/networking/ipv6.txt 2009-05-10 22:04:39.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/Documentation/networking/ipv6.txt 1970-01-01 01:00:00.000000000 +0100 +@@ -1,35 +0,0 @@ +- +-Options for the ipv6 module are supplied as parameters at load time. +- +-Module options may be given as command line arguments to the insmod +-or modprobe command, but are usually specified in either the +-/etc/modules.conf or /etc/modprobe.conf configuration file, or in a +-distro-specific configuration file. +- +-The available ipv6 module parameters are listed below. If a parameter +-is not specified the default value is used. +- +-The parameters are as follows: +- +-disable +- +- Specifies whether to load the IPv6 module, but disable all +- its functionality. This might be used when another module +- has a dependency on the IPv6 module being loaded, but no +- IPv6 addresses or operations are desired. +- +- The possible values and their effects are: +- +- 0 +- IPv6 is enabled. +- +- This is the default value. +- +- 1 +- IPv6 is disabled. +- +- No IPv6 addresses will be added to interfaces, and +- it will not be possible to open an IPv6 socket. +- +- A reboot is required to enable IPv6. +- +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/Documentation/PCI/PCIEBUS-HOWTO.txt linux-2.6.29-rc3.owrt/Documentation/PCI/PCIEBUS-HOWTO.txt +--- linux-2.6.29.owrt/Documentation/PCI/PCIEBUS-HOWTO.txt 2009-05-10 22:04:39.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/Documentation/PCI/PCIEBUS-HOWTO.txt 2009-05-10 23:48:28.000000000 +0200 +@@ -93,7 +93,7 @@ + + int pcie_port_service_register(struct pcie_port_service_driver *new) + +-This API replaces the Linux Driver Model's pci_register_driver API. A ++This API replaces the Linux Driver Model's pci_module_init API. A + service driver should always calls pcie_port_service_register at + module init. Note that after service driver being loaded, calls + such as pci_enable_device(dev) and pci_set_master(dev) are no longer +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/Documentation/powerpc/dts-bindings/fsl/mpc5200.txt linux-2.6.29-rc3.owrt/Documentation/powerpc/dts-bindings/fsl/mpc5200.txt +--- linux-2.6.29.owrt/Documentation/powerpc/dts-bindings/fsl/mpc5200.txt 2009-05-10 22:04:39.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/Documentation/powerpc/dts-bindings/fsl/mpc5200.txt 1970-01-01 01:00:00.000000000 +0100 +@@ -1,180 +0,0 @@ +-MPC5200 Device Tree Bindings +----------------------------- +- +-(c) 2006-2009 Secret Lab Technologies Ltd +-Grant Likely <grant.likely@secretlab.ca> +- +-Naming conventions +------------------- +-For mpc5200 on-chip devices, the format for each compatible value is +-<chip>-<device>[-<mode>]. The OS should be able to match a device driver +-to the device based solely on the compatible value. If two drivers +-match on the compatible list; the 'most compatible' driver should be +-selected. +- +-The split between the MPC5200 and the MPC5200B leaves a bit of a +-conundrum. How should the compatible property be set up to provide +-maximum compatibility information; but still accurately describe the +-chip? For the MPC5200; the answer is easy. Most of the SoC devices +-originally appeared on the MPC5200. Since they didn't exist anywhere +-else; the 5200 compatible properties will contain only one item; +-"fsl,mpc5200-<device>". +- +-The 5200B is almost the same as the 5200, but not quite. It fixes +-silicon bugs and it adds a small number of enhancements. Most of the +-devices either provide exactly the same interface as on the 5200. A few +-devices have extra functions but still have a backwards compatible mode. +-To express this information as completely as possible, 5200B device trees +-should have two items in the compatible list: +- compatible = "fsl,mpc5200b-<device>","fsl,mpc5200-<device>"; +- +-It is *strongly* recommended that 5200B device trees follow this convention +-(instead of only listing the base mpc5200 item). +- +-ie. ethernet on mpc5200: compatible = "fsl,mpc5200-fec"; +- ethernet on mpc5200b: compatible = "fsl,mpc5200b-fec", "fsl,mpc5200-fec"; +- +-Modal devices, like PSCs, also append the configured function to the +-end of the compatible field. ie. A PSC in i2s mode would specify +-"fsl,mpc5200-psc-i2s", not "fsl,mpc5200-i2s". This convention is chosen to +-avoid naming conflicts with non-psc devices providing the same +-function. For example, "fsl,mpc5200-spi" and "fsl,mpc5200-psc-spi" describe +-the mpc5200 simple spi device and a PSC spi mode respectively. +- +-At the time of writing, exact chip may be either 'fsl,mpc5200' or +-'fsl,mpc5200b'. +- +-The soc node +------------- +-This node describes the on chip SOC peripherals. Every mpc5200 based +-board will have this node, and as such there is a common naming +-convention for SOC devices. +- +-Required properties: +-name description +----- ----------- +-ranges Memory range of the internal memory mapped registers. +- Should be <0 [baseaddr] 0xc000> +-reg Should be <[baseaddr] 0x100> +-compatible mpc5200: "fsl,mpc5200-immr" +- mpc5200b: "fsl,mpc5200b-immr" +-system-frequency 'fsystem' frequency in Hz; XLB, IPB, USB and PCI +- clocks are derived from the fsystem clock. +-bus-frequency IPB bus frequency in Hz. Clock rate +- used by most of the soc devices. +- +-soc child nodes +---------------- +-Any on chip SOC devices available to Linux must appear as soc5200 child nodes. +- +-Note: The tables below show the value for the mpc5200. A mpc5200b device +-tree should use the "fsl,mpc5200b-<device>","fsl,mpc5200-<device>" form. +- +-Required soc5200 child nodes: +-name compatible Description +----- ---------- ----------- +-cdm@<addr> fsl,mpc5200-cdm Clock Distribution +-interrupt-controller@<addr> fsl,mpc5200-pic need an interrupt +- controller to boot +-bestcomm@<addr> fsl,mpc5200-bestcomm Bestcomm DMA controller +- +-Recommended soc5200 child nodes; populate as needed for your board +-name compatible Description +----- ---------- ----------- +-timer@<addr> fsl,mpc5200-gpt General purpose timers +-gpio@<addr> fsl,mpc5200-gpio MPC5200 simple gpio controller +-gpio@<addr> fsl,mpc5200-gpio-wkup MPC5200 wakeup gpio controller +-rtc@<addr> fsl,mpc5200-rtc Real time clock +-mscan@<addr> fsl,mpc5200-mscan CAN bus controller +-pci@<addr> fsl,mpc5200-pci PCI bridge +-serial@<addr> fsl,mpc5200-psc-uart PSC in serial mode +-i2s@<addr> fsl,mpc5200-psc-i2s PSC in i2s mode +-ac97@<addr> fsl,mpc5200-psc-ac97 PSC in ac97 mode +-spi@<addr> fsl,mpc5200-psc-spi PSC in spi mode +-irda@<addr> fsl,mpc5200-psc-irda PSC in IrDA mode +-spi@<addr> fsl,mpc5200-spi MPC5200 spi device +-ethernet@<addr> fsl,mpc5200-fec MPC5200 ethernet device +-ata@<addr> fsl,mpc5200-ata IDE ATA interface +-i2c@<addr> fsl,mpc5200-i2c I2C controller +-usb@<addr> fsl,mpc5200-ohci,ohci-be USB controller +-xlb@<addr> fsl,mpc5200-xlb XLB arbitrator +- +-fsl,mpc5200-gpt nodes +---------------------- +-On the mpc5200 and 5200b, GPT0 has a watchdog timer function. If the board +-design supports the internal wdt, then the device node for GPT0 should +-include the empty property 'fsl,has-wdt'. +- +-An mpc5200-gpt can be used as a single line GPIO controller. To do so, +-add the following properties to the gpt node: +- gpio-controller; +- #gpio-cells = <2>; +-When referencing the GPIO line from another node, the first cell must always +-be zero and the second cell represents the gpio flags and described in the +-gpio device tree binding. +- +-An mpc5200-gpt can be used as a single line edge sensitive interrupt +-controller. To do so, add the following properties to the gpt node: +- interrupt-controller; +- #interrupt-cells = <1>; +-When referencing the IRQ line from another node, the cell represents the +-sense mode; 1 for edge rising, 2 for edge falling. +- +-fsl,mpc5200-psc nodes +---------------------- +-The PSCs should include a cell-index which is the index of the PSC in +-hardware. cell-index is used to determine which shared SoC registers to +-use when setting up PSC clocking. cell-index number starts at '0'. ie: +- PSC1 has 'cell-index = <0>' +- PSC4 has 'cell-index = <3>' +- +-PSC in i2s mode: The mpc5200 and mpc5200b PSCs are not compatible when in +-i2s mode. An 'mpc5200b-psc-i2s' node cannot include 'mpc5200-psc-i2s' in the +-compatible field. +- +- +-fsl,mpc5200-gpio and fsl,mpc5200-gpio-wkup nodes +------------------------------------------------- +-Each GPIO controller node should have the empty property gpio-controller and +-#gpio-cells set to 2. First cell is the GPIO number which is interpreted +-according to the bit numbers in the GPIO control registers. The second cell +-is for flags which is currently unused. +- +-fsl,mpc5200-fec nodes +---------------------- +-The FEC node can specify one of the following properties to configure +-the MII link: +-- fsl,7-wire-mode - An empty property that specifies the link uses 7-wire +- mode instead of MII +-- current-speed - Specifies that the MII should be configured for a fixed +- speed. This property should contain two cells. The +- first cell specifies the speed in Mbps and the second +- should be '0' for half duplex and '1' for full duplex +-- phy-handle - Contains a phandle to an Ethernet PHY. +- +-Interrupt controller (fsl,mpc5200-pic) node +-------------------------------------------- +-The mpc5200 pic binding splits hardware IRQ numbers into two levels. The +-split reflects the layout of the PIC hardware itself, which groups +-interrupts into one of three groups; CRIT, MAIN or PERP. Also, the +-Bestcomm dma engine has it's own set of interrupt sources which are +-cascaded off of peripheral interrupt 0, which the driver interprets as a +-fourth group, SDMA. +- +-The interrupts property for device nodes using the mpc5200 pic consists +-of three cells; <L1 L2 level> +- +- L1 := [CRIT=0, MAIN=1, PERP=2, SDMA=3] +- L2 := interrupt number; directly mapped from the value in the +- "ICTL PerStat, MainStat, CritStat Encoded Register" +- level := [LEVEL_HIGH=0, EDGE_RISING=1, EDGE_FALLING=2, LEVEL_LOW=3] +- +-For external IRQs, use the following interrupt property values (how to +-specify external interrupts is a frequently asked question): +-External interrupts: +- external irq0: interrupts = <0 0 n>; +- external irq1: interrupts = <1 1 n>; +- external irq2: interrupts = <1 2 n>; +- external irq3: interrupts = <1 3 n>; +-'n' is sense (0: level high, 1: edge rising, 2: edge falling 3: level low) +- +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/Documentation/powerpc/mpc52xx-device-tree-bindings.txt linux-2.6.29-rc3.owrt/Documentation/powerpc/mpc52xx-device-tree-bindings.txt +--- linux-2.6.29.owrt/Documentation/powerpc/mpc52xx-device-tree-bindings.txt 1970-01-01 01:00:00.000000000 +0100 ++++ linux-2.6.29-rc3.owrt/Documentation/powerpc/mpc52xx-device-tree-bindings.txt 2009-05-10 23:48:28.000000000 +0200 +@@ -0,0 +1,277 @@ ++MPC5200 Device Tree Bindings ++---------------------------- ++ ++(c) 2006-2007 Secret Lab Technologies Ltd ++Grant Likely <grant.likely at secretlab.ca> ++ ++********** DRAFT *********** ++* WARNING: Do not depend on the stability of these bindings just yet. ++* The MPC5200 device tree conventions are still in flux ++* Keep an eye on the linuxppc-dev mailing list for more details ++********** DRAFT *********** ++ ++I - Introduction ++================ ++Boards supported by the arch/powerpc architecture require device tree be ++passed by the boot loader to the kernel at boot time. The device tree ++describes what devices are present on the board and how they are ++connected. The device tree can either be passed as a binary blob (as ++described in Documentation/powerpc/booting-without-of.txt), or passed ++by Open Firmware (IEEE 1275) compatible firmware using an OF compatible ++client interface API. ++ ++This document specifies the requirements on the device-tree for mpc5200 ++based boards. These requirements are above and beyond the details ++specified in either the Open Firmware spec or booting-without-of.txt ++ ++All new mpc5200-based boards are expected to match this document. In ++cases where this document is not sufficient to support a new board port, ++this document should be updated as part of adding the new board support. ++ ++II - Philosophy ++=============== ++The core of this document is naming convention. The whole point of ++defining this convention is to reduce or eliminate the number of ++special cases required to support a 5200 board. If all 5200 boards ++follow the same convention, then generic 5200 support code will work ++rather than coding special cases for each new board. ++ ++This section tries to capture the thought process behind why the naming ++convention is what it is. ++ ++1. names ++--------- ++There is strong convention/requirements already established for children ++of the root node. 'cpus' describes the processor cores, 'memory' ++describes memory, and 'chosen' provides boot configuration. Other nodes ++are added to describe devices attached to the processor local bus. ++ ++Following convention already established with other system-on-chip ++processors, 5200 device trees should use the name 'soc5200' for the ++parent node of on chip devices, and the root node should be its parent. ++ ++Child nodes are typically named after the configured function. ie. ++the FEC node is named 'ethernet', and a PSC in uart mode is named 'serial'. ++ ++2. device_type property ++----------------------- ++similar to the node name convention above; the device_type reflects the ++configured function of a device. ie. 'serial' for a uart and 'spi' for ++an spi controller. However, while node names *should* reflect the ++configured function, device_type *must* match the configured function ++exactly. ++ ++3. compatible property ++---------------------- ++Since device_type isn't enough to match devices to drivers, there also ++needs to be a naming convention for the compatible property. Compatible ++is an list of device descriptions sorted from specific to generic. For ++the mpc5200, the required format for each compatible value is ++<chip>-<device>[-<mode>]. The OS should be able to match a device driver ++to the device based solely on the compatible value. If two drivers ++match on the compatible list; the 'most compatible' driver should be ++selected. ++ ++The split between the MPC5200 and the MPC5200B leaves a bit of a ++conundrum. How should the compatible property be set up to provide ++maximum compatibility information; but still accurately describe the ++chip? For the MPC5200; the answer is easy. Most of the SoC devices ++originally appeared on the MPC5200. Since they didn't exist anywhere ++else; the 5200 compatible properties will contain only one item; ++"mpc5200-<device>". ++ ++The 5200B is almost the same as the 5200, but not quite. It fixes ++silicon bugs and it adds a small number of enhancements. Most of the ++devices either provide exactly the same interface as on the 5200. A few ++devices have extra functions but still have a backwards compatible mode. ++To express this information as completely as possible, 5200B device trees ++should have two items in the compatible list; ++"mpc5200b-<device>\0mpc5200-<device>". It is *strongly* recommended ++that 5200B device trees follow this convention (instead of only listing ++the base mpc5200 item). ++ ++If another chip appear on the market with one of the mpc5200 SoC ++devices, then the compatible list should include mpc5200-<device>. ++ ++ie. ethernet on mpc5200: compatible = "mpc5200-ethernet" ++ ethernet on mpc5200b: compatible = "mpc5200b-ethernet\0mpc5200-ethernet" ++ ++Modal devices, like PSCs, also append the configured function to the ++end of the compatible field. ie. A PSC in i2s mode would specify ++"mpc5200-psc-i2s", not "mpc5200-i2s". This convention is chosen to ++avoid naming conflicts with non-psc devices providing the same ++function. For example, "mpc5200-spi" and "mpc5200-psc-spi" describe ++the mpc5200 simple spi device and a PSC spi mode respectively. ++ ++If the soc device is more generic and present on other SOCs, the ++compatible property can specify the more generic device type also. ++ ++ie. mscan: compatible = "mpc5200-mscan\0fsl,mscan"; ++ ++At the time of writing, exact chip may be either 'mpc5200' or ++'mpc5200b'. ++ ++Device drivers should always try to match as generically as possible. ++ ++III - Structure ++=============== ++The device tree for an mpc5200 board follows the structure defined in ++booting-without-of.txt with the following additional notes: ++ ++0) the root node ++---------------- ++Typical root description node; see booting-without-of ++ ++1) The cpus node ++---------------- ++The cpus node follows the basic layout described in booting-without-of. ++The bus-frequency property holds the XLB bus frequency ++The clock-frequency property holds the core frequency ++ ++2) The memory node ++------------------ ++Typical memory description node; see booting-without-of. ++ ++3) The soc5200 node ++------------------- ++This node describes the on chip SOC peripherals. Every mpc5200 based ++board will have this node, and as such there is a common naming ++convention for SOC devices. ++ ++Required properties: ++name type description ++---- ---- ----------- ++device_type string must be "soc" ++ranges int should be <0 baseaddr baseaddr+10000> ++reg int must be <baseaddr 10000> ++compatible string mpc5200: "mpc5200-soc" ++ mpc5200b: "mpc5200b-soc\0mpc5200-soc" ++system-frequency int Fsystem frequency; source of all ++ other clocks. ++bus-frequency int IPB bus frequency in HZ. Clock rate ++ used by most of the soc devices. ++#interrupt-cells int must be <3>. ++ ++Recommended properties: ++name type description ++---- ---- ----------- ++model string Exact model of the chip; ++ ie: model="fsl,mpc5200" ++revision string Silicon revision of chip ++ ie: revision="M08A" ++ ++The 'model' and 'revision' properties are *strongly* recommended. Having ++them presence acts as a bit of a safety net for working around as yet ++undiscovered bugs on one version of silicon. For example, device drivers ++can use the model and revision properties to decide if a bug fix should ++be turned on. ++ ++4) soc5200 child nodes ++---------------------- ++Any on chip SOC devices available to Linux must appear as soc5200 child nodes. ++ ++Note: The tables below show the value for the mpc5200. A mpc5200b device ++tree should use the "mpc5200b-<device>\0mpc5200-<device> form. ++ ++Required soc5200 child nodes: ++name device_type compatible Description ++---- ----------- ---------- ----------- ++cdm@<addr> cdm mpc5200-cmd Clock Distribution ++pic@<addr> interrupt-controller mpc5200-pic need an interrupt ++ controller to boot ++bestcomm@<addr> dma-controller mpc5200-bestcomm 5200 pic also requires ++ the bestcomm device ++ ++Recommended soc5200 child nodes; populate as needed for your board ++name device_type compatible Description ++---- ----------- ---------- ----------- ++gpt@<addr> gpt fsl,mpc5200-gpt General purpose timers ++gpt@<addr> gpt fsl,mpc5200-gpt-gpio General purpose ++ timers in GPIO mode ++gpio@<addr> fsl,mpc5200-gpio MPC5200 simple gpio ++ controller ++gpio@<addr> fsl,mpc5200-gpio-wkup MPC5200 wakeup gpio ++ controller ++rtc@<addr> rtc mpc5200-rtc Real time clock ++mscan@<addr> mscan mpc5200-mscan CAN bus controller ++pci@<addr> pci mpc5200-pci PCI bridge ++serial@<addr> serial mpc5200-psc-uart PSC in serial mode ++i2s@<addr> sound mpc5200-psc-i2s PSC in i2s mode ++ac97@<addr> sound mpc5200-psc-ac97 PSC in ac97 mode ++spi@<addr> spi mpc5200-psc-spi PSC in spi mode ++irda@<addr> irda mpc5200-psc-irda PSC in IrDA mode ++spi@<addr> spi mpc5200-spi MPC5200 spi device ++ethernet@<addr> network mpc5200-fec MPC5200 ethernet device ++ata@<addr> ata mpc5200-ata IDE ATA interface ++i2c@<addr> i2c mpc5200-i2c I2C controller ++usb@<addr> usb-ohci-be mpc5200-ohci,ohci-be USB controller ++xlb@<addr> xlb mpc5200-xlb XLB arbitrator ++ ++Important child node properties ++name type description ++---- ---- ----------- ++cell-index int When multiple devices are present, is the ++ index of the device in the hardware (ie. There ++ are 6 PSC on the 5200 numbered PSC1 to PSC6) ++ PSC1 has 'cell-index = <0>' ++ PSC4 has 'cell-index = <3>' ++ ++5) General Purpose Timer nodes (child of soc5200 node) ++On the mpc5200 and 5200b, GPT0 has a watchdog timer function. If the board ++design supports the internal wdt, then the device node for GPT0 should ++include the empty property 'fsl,has-wdt'. ++ ++6) PSC nodes (child of soc5200 node) ++PSC nodes can define the optional 'port-number' property to force assignment ++order of serial ports. For example, PSC5 might be physically connected to ++the port labeled 'COM1' and PSC1 wired to 'COM1'. In this case, PSC5 would ++have a "port-number = <0>" property, and PSC1 would have "port-number = <1>". ++ ++PSC in i2s mode: The mpc5200 and mpc5200b PSCs are not compatible when in ++i2s mode. An 'mpc5200b-psc-i2s' node cannot include 'mpc5200-psc-i2s' in the ++compatible field. ++ ++7) GPIO controller nodes ++Each GPIO controller node should have the empty property gpio-controller and ++#gpio-cells set to 2. First cell is the GPIO number which is interpreted ++according to the bit numbers in the GPIO control registers. The second cell ++is for flags which is currently unsused. ++ ++8) FEC nodes ++The FEC node can specify one of the following properties to configure ++the MII link: ++"fsl,7-wire-mode" - An empty property that specifies the link uses 7-wire ++ mode instead of MII ++"current-speed" - Specifies that the MII should be configured for a fixed ++ speed. This property should contain two cells. The ++ first cell specifies the speed in Mbps and the second ++ should be '0' for half duplex and '1' for full duplex ++"phy-handle" - Contains a phandle to an Ethernet PHY. ++ ++IV - Extra Notes ++================ ++ ++1. Interrupt mapping ++-------------------- ++The mpc5200 pic driver splits hardware IRQ numbers into two levels. The ++split reflects the layout of the PIC hardware itself, which groups ++interrupts into one of three groups; CRIT, MAIN or PERP. Also, the ++Bestcomm dma engine has it's own set of interrupt sources which are ++cascaded off of peripheral interrupt 0, which the driver interprets as a ++fourth group, SDMA. ++ ++The interrupts property for device nodes using the mpc5200 pic consists ++of three cells; <L1 L2 level> ++ ++ L1 := [CRIT=0, MAIN=1, PERP=2, SDMA=3] ++ L2 := interrupt number; directly mapped from the value in the ++ "ICTL PerStat, MainStat, CritStat Encoded Register" ++ level := [LEVEL_HIGH=0, EDGE_RISING=1, EDGE_FALLING=2, LEVEL_LOW=3] ++ ++2. Shared registers ++------------------- ++Some SoC devices share registers between them. ie. the i2c devices use ++a single clock control register, and almost all device are affected by ++the port_config register. Devices which need to manipulate shared regs ++should look to the parent SoC node. The soc node is responsible ++for arbitrating all shared register access. +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/Documentation/RCU/checklist.txt linux-2.6.29-rc3.owrt/Documentation/RCU/checklist.txt +--- linux-2.6.29.owrt/Documentation/RCU/checklist.txt 2009-05-10 22:04:39.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/Documentation/RCU/checklist.txt 2009-05-10 23:48:28.000000000 +0200 +@@ -298,15 +298,3 @@ + + Note that, rcu_assign_pointer() and rcu_dereference() relate to + SRCU just as they do to other forms of RCU. +- +-15. The whole point of call_rcu(), synchronize_rcu(), and friends +- is to wait until all pre-existing readers have finished before +- carrying out some otherwise-destructive operation. It is +- therefore critically important to -first- remove any path +- that readers can follow that could be affected by the +- destructive operation, and -only- -then- invoke call_rcu(), +- synchronize_rcu(), or friends. +- +- Because these primitives only wait for pre-existing readers, +- it is the caller's responsibility to guarantee safety to +- any subsequent readers. +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/Documentation/scsi/cxgb3i.txt linux-2.6.29-rc3.owrt/Documentation/scsi/cxgb3i.txt +--- linux-2.6.29.owrt/Documentation/scsi/cxgb3i.txt 2009-05-10 22:04:39.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/Documentation/scsi/cxgb3i.txt 2009-05-10 23:48:28.000000000 +0200 +@@ -4,7 +4,7 @@ + ============ + + The Chelsio T3 ASIC based Adapters (S310, S320, S302, S304, Mezz cards, etc. +-series of products) support iSCSI acceleration and iSCSI Direct Data Placement ++series of products) supports iSCSI acceleration and iSCSI Direct Data Placement + (DDP) where the hardware handles the expensive byte touching operations, such + as CRC computation and verification, and direct DMA to the final host memory + destination: +@@ -31,9 +31,9 @@ + the TCP segments onto the wire. It handles TCP retransmission if + needed. + +- On receiving, S3 h/w recovers the iSCSI PDU by reassembling TCP ++ On receving, S3 h/w recovers the iSCSI PDU by reassembling TCP + segments, separating the header and data, calculating and verifying +- the digests, then forwarding the header to the host. The payload data, ++ the digests, then forwards the header to the host. The payload data, + if possible, will be directly placed into the pre-posted host DDP + buffer. Otherwise, the payload data will be sent to the host too. + +@@ -68,8 +68,9 @@ + sure the ip address is unique in the network. + + 3. edit /etc/iscsi/iscsid.conf +- The default setting for MaxRecvDataSegmentLength (131072) is too big; +- replace with a value no bigger than 15360 (for example 8192): ++ The default setting for MaxRecvDataSegmentLength (131072) is too big, ++ replace "node.conn[0].iscsi.MaxRecvDataSegmentLength" to be a value no ++ bigger than 15360 (for example 8192): + + node.conn[0].iscsi.MaxRecvDataSegmentLength = 8192 + +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/Documentation/tracers/mmiotrace.txt linux-2.6.29-rc3.owrt/Documentation/tracers/mmiotrace.txt +--- linux-2.6.29.owrt/Documentation/tracers/mmiotrace.txt 2009-05-10 22:04:39.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/Documentation/tracers/mmiotrace.txt 2009-05-10 23:48:28.000000000 +0200 +@@ -78,10 +78,12 @@ + events were lost, the trace is incomplete. You should enlarge the buffers and + try again. Buffers are enlarged by first seeing how large the current buffers + are: +-$ cat /debug/tracing/buffer_size_kb ++$ cat /debug/tracing/trace_entries + gives you a number. Approximately double this number and write it back, for + instance: +-$ echo 128000 > /debug/tracing/buffer_size_kb ++$ echo 0 > /debug/tracing/tracing_enabled ++$ echo 128000 > /debug/tracing/trace_entries ++$ echo 1 > /debug/tracing/tracing_enabled + Then start again from the top. + + If you are doing a trace for a driver project, e.g. Nouveau, you should also +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/Documentation/usb/dma.txt linux-2.6.29-rc3.owrt/Documentation/usb/dma.txt +--- linux-2.6.29.owrt/Documentation/usb/dma.txt 2009-05-10 22:04:39.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/Documentation/usb/dma.txt 2009-05-10 23:48:28.000000000 +0200 +@@ -6,9 +6,8 @@ + API OVERVIEW + + The big picture is that USB drivers can continue to ignore most DMA issues, +-though they still must provide DMA-ready buffers (see +-Documentation/PCI/PCI-DMA-mapping.txt). That's how they've worked through +-the 2.4 (and earlier) kernels. ++though they still must provide DMA-ready buffers (see DMA-mapping.txt). ++That's how they've worked through the 2.4 (and earlier) kernels. + + OR: they can now be DMA-aware. + +@@ -63,8 +62,8 @@ + force a consistent memory access ordering by using memory barriers. It's + not using a streaming DMA mapping, so it's good for small transfers on + systems where the I/O would otherwise thrash an IOMMU mapping. (See +- Documentation/PCI/PCI-DMA-mapping.txt for definitions of "coherent" and +- "streaming" DMA mappings.) ++ Documentation/DMA-mapping.txt for definitions of "coherent" and "streaming" ++ DMA mappings.) + + Asking for 1/Nth of a page (as well as asking for N pages) is reasonably + space-efficient. +@@ -94,7 +93,7 @@ + Existing buffers aren't usable for DMA without first being mapped into the + DMA address space of the device. However, most buffers passed to your + driver can safely be used with such DMA mapping. (See the first section +-of Documentation/PCI/PCI-DMA-mapping.txt, titled "What memory is DMA-able?") ++of DMA-mapping.txt, titled "What memory is DMA-able?") + + - When you're using scatterlists, you can map everything at once. On some + systems, this kicks in an IOMMU and turns the scatterlists into single +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/Documentation/video4linux/v4lgrab.c linux-2.6.29-rc3.owrt/Documentation/video4linux/v4lgrab.c +--- linux-2.6.29.owrt/Documentation/video4linux/v4lgrab.c 2009-05-10 22:04:39.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/Documentation/video4linux/v4lgrab.c 2009-05-10 23:48:28.000000000 +0200 +@@ -4,21 +4,12 @@ + * + * Compile with: + * gcc -s -Wall -Wstrict-prototypes v4lgrab.c -o v4lgrab +- * Use as: +- * v4lgrab >image.ppm ++ * Use as: ++ * v4lgrab >image.ppm + * + * Copyright (C) 1998-05-03, Phil Blundell <philb@gnu.org> +- * Copied from http://www.tazenda.demon.co.uk/phil/vgrabber.c +- * with minor modifications (Dave Forrest, drf5n@virginia.edu). +- * +- * +- * For some cameras you may need to pre-load libv4l to perform +- * the necessary decompression, e.g.: +- * +- * export LD_PRELOAD=/usr/lib/libv4l/v4l1compat.so +- * ./v4lgrab >image.ppm +- * +- * see http://hansdegoede.livejournal.com/3636.html for details. ++ * Copied from http://www.tazenda.demon.co.uk/phil/vgrabber.c ++ * with minor modifications (Dave Forrest, drf5n@virginia.edu). + * + */ + +@@ -33,7 +24,7 @@ + #include <linux/types.h> + #include <linux/videodev.h> + +-#define VIDEO_DEV "/dev/video0" ++#define FILE "/dev/video0" + + /* Stole this from tvset.c */ + +@@ -99,7 +90,7 @@ + + int main(int argc, char ** argv) + { +- int fd = open(VIDEO_DEV, O_RDONLY), f; ++ int fd = open(FILE, O_RDONLY), f; + struct video_capability cap; + struct video_window win; + struct video_picture vpic; +@@ -109,13 +100,13 @@ + unsigned int i, src_depth; + + if (fd < 0) { +- perror(VIDEO_DEV); ++ perror(FILE); + exit(1); + } + + if (ioctl(fd, VIDIOCGCAP, &cap) < 0) { + perror("VIDIOGCAP"); +- fprintf(stderr, "(" VIDEO_DEV " not a video4linux device?)\n"); ++ fprintf(stderr, "(" FILE " not a video4linux device?)\n"); + close(fd); + exit(1); + } +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/drivers/acpi/acpica/tbutils.c linux-2.6.29-rc3.owrt/drivers/acpi/acpica/tbutils.c +--- linux-2.6.29.owrt/drivers/acpi/acpica/tbutils.c 2009-05-10 22:04:38.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/drivers/acpi/acpica/tbutils.c 2009-05-10 23:48:28.000000000 +0200 +@@ -538,9 +538,10 @@ + if (ACPI_FAILURE(status)) { + ACPI_WARNING((AE_INFO, + "Truncating %u table entries!", +- (unsigned) (table_count - +- (acpi_gbl_root_table_list. +- count - 2)))); ++ (unsigned) ++ (acpi_gbl_root_table_list.size - ++ acpi_gbl_root_table_list. ++ count))); + break; + } + } +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/drivers/acpi/acpica/uteval.c linux-2.6.29-rc3.owrt/drivers/acpi/acpica/uteval.c +--- linux-2.6.29.owrt/drivers/acpi/acpica/uteval.c 2009-05-10 22:04:38.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/drivers/acpi/acpica/uteval.c 2009-05-10 23:48:28.000000000 +0200 +@@ -116,9 +116,9 @@ + return_ACPI_STATUS(AE_NO_MEMORY); + } + +- /* Default return value is 0, NOT-SUPPORTED */ ++ /* Default return value is SUPPORTED */ + +- return_desc->integer.value = 0; ++ return_desc->integer.value = ACPI_UINT32_MAX; + walk_state->return_desc = return_desc; + + /* Compare input string to static table of supported interfaces */ +@@ -127,8 +127,10 @@ + if (!ACPI_STRCMP + (string_desc->string.pointer, + acpi_interfaces_supported[i])) { +- return_desc->integer.value = ACPI_UINT32_MAX; +- goto done; ++ ++ /* The interface is supported */ ++ ++ return_ACPI_STATUS(AE_OK); + } + } + +@@ -139,14 +141,15 @@ + */ + status = acpi_os_validate_interface(string_desc->string.pointer); + if (ACPI_SUCCESS(status)) { +- return_desc->integer.value = ACPI_UINT32_MAX; ++ ++ /* The interface is supported */ ++ ++ return_ACPI_STATUS(AE_OK); + } + +-done: +- ACPI_DEBUG_PRINT_RAW((ACPI_DB_INFO, "ACPI: BIOS _OSI(%s) %ssupported\n", +- string_desc->string.pointer, +- return_desc->integer.value == 0 ? "not-" : "")); ++ /* The interface is not supported */ + ++ return_desc->integer.value = 0; + return_ACPI_STATUS(AE_OK); + } + +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/drivers/acpi/battery.c linux-2.6.29-rc3.owrt/drivers/acpi/battery.c +--- linux-2.6.29.owrt/drivers/acpi/battery.c 2009-05-10 22:04:38.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/drivers/acpi/battery.c 2009-05-10 23:48:28.000000000 +0200 +@@ -138,29 +138,6 @@ + + static int acpi_battery_get_state(struct acpi_battery *battery); + +-static int acpi_battery_is_charged(struct acpi_battery *battery) +-{ +- /* either charging or discharging */ +- if (battery->state != 0) +- return 0; +- +- /* battery not reporting charge */ +- if (battery->capacity_now == ACPI_BATTERY_VALUE_UNKNOWN || +- battery->capacity_now == 0) +- return 0; +- +- /* good batteries update full_charge as the batteries degrade */ +- if (battery->full_charge_capacity == battery->capacity_now) +- return 1; +- +- /* fallback to using design values for broken batteries */ +- if (battery->design_capacity == battery->capacity_now) +- return 1; +- +- /* we don't do any sort of metric based on percentages */ +- return 0; +-} +- + static int acpi_battery_get_property(struct power_supply *psy, + enum power_supply_property psp, + union power_supply_propval *val) +@@ -178,7 +155,7 @@ + val->intval = POWER_SUPPLY_STATUS_DISCHARGING; + else if (battery->state & 0x02) + val->intval = POWER_SUPPLY_STATUS_CHARGING; +- else if (acpi_battery_is_charged(battery)) ++ else if (battery->state == 0) + val->intval = POWER_SUPPLY_STATUS_FULL; + else + val->intval = POWER_SUPPLY_STATUS_UNKNOWN; +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/drivers/acpi/bus.c linux-2.6.29-rc3.owrt/drivers/acpi/bus.c +--- linux-2.6.29.owrt/drivers/acpi/bus.c 2009-05-10 22:04:38.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/drivers/acpi/bus.c 2009-05-10 23:48:28.000000000 +0200 +@@ -758,7 +758,8 @@ + acpi_status status = AE_OK; + extern acpi_status acpi_os_initialize1(void); + +- acpi_os_initialize1(); ++ ++ status = acpi_os_initialize1(); + + status = + acpi_enable_subsystem(ACPI_NO_HARDWARE_INIT | ACPI_NO_ACPI_ENABLE); +@@ -768,6 +769,12 @@ + goto error1; + } + ++ if (ACPI_FAILURE(status)) { ++ printk(KERN_ERR PREFIX ++ "Unable to initialize ACPI OS objects\n"); ++ goto error1; ++ } ++ + /* + * ACPI 2.0 requires the EC driver to be loaded and work before + * the EC device is found in the namespace (i.e. before acpi_initialize_objects() +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/drivers/acpi/container.c linux-2.6.29-rc3.owrt/drivers/acpi/container.c +--- linux-2.6.29.owrt/drivers/acpi/container.c 2009-05-10 22:04:38.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/drivers/acpi/container.c 2009-05-10 23:48:28.000000000 +0200 +@@ -163,7 +163,7 @@ + case ACPI_NOTIFY_BUS_CHECK: + /* Fall through */ + case ACPI_NOTIFY_DEVICE_CHECK: +- printk(KERN_WARNING "Container driver received %s event\n", ++ printk("Container driver received %s event\n", + (type == ACPI_NOTIFY_BUS_CHECK) ? + "ACPI_NOTIFY_BUS_CHECK" : "ACPI_NOTIFY_DEVICE_CHECK"); + status = acpi_bus_get_device(handle, &device); +@@ -174,8 +174,7 @@ + kobject_uevent(&device->dev.kobj, + KOBJ_ONLINE); + else +- printk(KERN_WARNING +- "Failed to add container\n"); ++ printk("Failed to add container\n"); + } + } else { + if (ACPI_SUCCESS(status)) { +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/drivers/acpi/dock.c linux-2.6.29-rc3.owrt/drivers/acpi/dock.c +--- linux-2.6.29.owrt/drivers/acpi/dock.c 2009-05-10 22:04:38.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/drivers/acpi/dock.c 2009-05-10 23:48:28.000000000 +0200 +@@ -855,14 +855,10 @@ + static ssize_t show_docked(struct device *dev, + struct device_attribute *attr, char *buf) + { +- struct acpi_device *tmp; +- + struct dock_station *dock_station = *((struct dock_station **) + dev->platform_data); ++ return snprintf(buf, PAGE_SIZE, "%d\n", dock_present(dock_station)); + +- if (ACPI_SUCCESS(acpi_bus_get_device(dock_station->handle, &tmp))) +- return snprintf(buf, PAGE_SIZE, "1\n"); +- return snprintf(buf, PAGE_SIZE, "0\n"); + } + static DEVICE_ATTR(docked, S_IRUGO, show_docked, NULL); + +@@ -988,7 +984,7 @@ + + ret = device_create_file(&dock_device->dev, &dev_attr_docked); + if (ret) { +- printk(KERN_ERR "Error %d adding sysfs file\n", ret); ++ printk("Error %d adding sysfs file\n", ret); + platform_device_unregister(dock_device); + kfree(dock_station); + dock_station = NULL; +@@ -996,7 +992,7 @@ + } + ret = device_create_file(&dock_device->dev, &dev_attr_undock); + if (ret) { +- printk(KERN_ERR "Error %d adding sysfs file\n", ret); ++ printk("Error %d adding sysfs file\n", ret); + device_remove_file(&dock_device->dev, &dev_attr_docked); + platform_device_unregister(dock_device); + kfree(dock_station); +@@ -1005,7 +1001,7 @@ + } + ret = device_create_file(&dock_device->dev, &dev_attr_uid); + if (ret) { +- printk(KERN_ERR "Error %d adding sysfs file\n", ret); ++ printk("Error %d adding sysfs file\n", ret); + device_remove_file(&dock_device->dev, &dev_attr_docked); + device_remove_file(&dock_device->dev, &dev_attr_undock); + platform_device_unregister(dock_device); +@@ -1015,7 +1011,7 @@ + } + ret = device_create_file(&dock_device->dev, &dev_attr_flags); + if (ret) { +- printk(KERN_ERR "Error %d adding sysfs file\n", ret); ++ printk("Error %d adding sysfs file\n", ret); + device_remove_file(&dock_device->dev, &dev_attr_docked); + device_remove_file(&dock_device->dev, &dev_attr_undock); + device_remove_file(&dock_device->dev, &dev_attr_uid); +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/drivers/acpi/ec.c linux-2.6.29-rc3.owrt/drivers/acpi/ec.c +--- linux-2.6.29.owrt/drivers/acpi/ec.c 2009-05-10 22:04:38.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/drivers/acpi/ec.c 2009-05-10 23:48:28.000000000 +0200 +@@ -120,8 +120,6 @@ + spinlock_t curr_lock; + } *boot_ec, *first_ec; + +-static int EC_FLAGS_MSI; /* Out-of-spec MSI controller */ +- + /* -------------------------------------------------------------------------- + Transaction Management + -------------------------------------------------------------------------- */ +@@ -261,8 +259,6 @@ + clear_bit(EC_FLAGS_GPE_MODE, &ec->flags); + acpi_disable_gpe(NULL, ec->gpe); + } +- if (EC_FLAGS_MSI) +- udelay(ACPI_EC_DELAY); + /* start transaction */ + spin_lock_irqsave(&ec->curr_lock, tmp); + /* following two actions should be kept atomic */ +@@ -971,11 +967,6 @@ + /* + * Generate a boot ec context + */ +- if (dmi_name_in_vendors("Micro-Star") || +- dmi_name_in_vendors("Notebook")) { +- pr_info(PREFIX "Enabling special treatment for EC from MSI.\n"); +- EC_FLAGS_MSI = 1; +- } + status = acpi_get_table(ACPI_SIG_ECDT, 1, + (struct acpi_table_header **)&ecdt_ptr); + if (ACPI_SUCCESS(status)) { +@@ -991,7 +982,7 @@ + saved_ec = kmalloc(sizeof(struct acpi_ec), GFP_KERNEL); + if (!saved_ec) + return -ENOMEM; +- memcpy(saved_ec, boot_ec, sizeof(*saved_ec)); ++ memcpy(&saved_ec, boot_ec, sizeof(saved_ec)); + /* fall through */ + } + /* This workaround is needed only on some broken machines, +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/drivers/acpi/glue.c linux-2.6.29-rc3.owrt/drivers/acpi/glue.c +--- linux-2.6.29.owrt/drivers/acpi/glue.c 2009-05-10 22:04:38.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/drivers/acpi/glue.c 2009-05-10 23:48:28.000000000 +0200 +@@ -255,12 +255,12 @@ + } + type = acpi_get_bus_type(dev->bus); + if (!type) { +- DBG("No ACPI bus support for %s\n", dev_name(dev)); ++ DBG("No ACPI bus support for %s\n", dev->bus_id); + ret = -EINVAL; + goto end; + } + if ((ret = type->find_device(dev, &handle)) != 0) +- DBG("Can't get handler for %s\n", dev_name(dev)); ++ DBG("Can't get handler for %s\n", dev->bus_id); + end: + if (!ret) + acpi_bind_one(dev, handle); +@@ -271,10 +271,10 @@ + + acpi_get_name(dev->archdata.acpi_handle, + ACPI_FULL_PATHNAME, &buffer); +- DBG("Device %s -> %s\n", dev_name(dev), (char *)buffer.pointer); ++ DBG("Device %s -> %s\n", dev->bus_id, (char *)buffer.pointer); + kfree(buffer.pointer); + } else +- DBG("Device %s -> No ACPI support\n", dev_name(dev)); ++ DBG("Device %s -> No ACPI support\n", dev->bus_id); + #endif + + return ret; +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/drivers/acpi/Kconfig linux-2.6.29-rc3.owrt/drivers/acpi/Kconfig +--- linux-2.6.29.owrt/drivers/acpi/Kconfig 2009-05-10 22:04:38.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/drivers/acpi/Kconfig 2009-05-10 23:48:28.000000000 +0200 +@@ -9,7 +9,6 @@ + depends on PCI + depends on PM + select PNP +- select CPU_IDLE + default y + ---help--- + Advanced Configuration and Power Interface (ACPI) support for +@@ -254,6 +253,13 @@ + help you correlate PCI bus addresses with the physical geography + of your slots. If you are unsure, say N. + ++config ACPI_SYSTEM ++ bool ++ default y ++ help ++ This driver will enable your system to shut down using ACPI, and ++ dump your ACPI DSDT table using /proc/acpi/dsdt. ++ + config X86_PM_TIMER + bool "Power Management Timer Support" if EMBEDDED + depends on X86 +@@ -281,7 +287,7 @@ + support physical cpu/memory hot-plug. + + If one selects "m", this driver can be loaded with +- "modprobe container". ++ "modprobe acpi_container". + + config ACPI_HOTPLUG_MEMORY + tristate "Memory Hotplug" +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/drivers/acpi/Makefile linux-2.6.29-rc3.owrt/drivers/acpi/Makefile +--- linux-2.6.29.owrt/drivers/acpi/Makefile 2009-05-10 22:04:38.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/drivers/acpi/Makefile 2009-05-10 23:48:28.000000000 +0200 +@@ -52,7 +52,7 @@ + obj-$(CONFIG_ACPI_CONTAINER) += container.o + obj-$(CONFIG_ACPI_THERMAL) += thermal.o + obj-y += power.o +-obj-y += system.o event.o ++obj-$(CONFIG_ACPI_SYSTEM) += system.o event.o + obj-$(CONFIG_ACPI_DEBUG) += debug.o + obj-$(CONFIG_ACPI_NUMA) += numa.o + obj-$(CONFIG_ACPI_HOTPLUG_MEMORY) += acpi_memhotplug.o +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/drivers/acpi/numa.c linux-2.6.29-rc3.owrt/drivers/acpi/numa.c +--- linux-2.6.29.owrt/drivers/acpi/numa.c 2009-05-10 22:04:38.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/drivers/acpi/numa.c 2009-05-10 23:48:28.000000000 +0200 +@@ -277,7 +277,7 @@ + int pxm, node = -1; + + pxm = acpi_get_pxm(handle); +- if (pxm >= 0 && pxm < MAX_PXM_DOMAINS) ++ if (pxm >= 0) + node = acpi_map_pxm_to_node(pxm); + + return node; +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/drivers/acpi/osl.c linux-2.6.29-rc3.owrt/drivers/acpi/osl.c +--- linux-2.6.29.owrt/drivers/acpi/osl.c 2009-05-10 22:04:38.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/drivers/acpi/osl.c 2009-05-10 23:48:28.000000000 +0200 +@@ -228,10 +228,10 @@ + if (acpi_in_debugger) { + kdb_printf("%s", buffer); + } else { +- printk(KERN_CONT "%s", buffer); ++ printk("%s", buffer); + } + #else +- printk(KERN_CONT "%s", buffer); ++ printk("%s", buffer); + #endif + } + +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/drivers/acpi/pci_link.c linux-2.6.29-rc3.owrt/drivers/acpi/pci_link.c +--- linux-2.6.29.owrt/drivers/acpi/pci_link.c 2009-05-10 22:04:38.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/drivers/acpi/pci_link.c 2009-05-10 23:48:28.000000000 +0200 +@@ -593,7 +593,7 @@ + return -ENODEV; + } else { + acpi_irq_penalty[link->irq.active] += PIRQ_PENALTY_PCI_USING; +- printk(KERN_WARNING PREFIX "%s [%s] enabled at IRQ %d\n", ++ printk(PREFIX "%s [%s] enabled at IRQ %d\n", + acpi_device_name(link->device), + acpi_device_bid(link->device), link->irq.active); + } +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/drivers/acpi/processor_idle.c linux-2.6.29-rc3.owrt/drivers/acpi/processor_idle.c +--- linux-2.6.29.owrt/drivers/acpi/processor_idle.c 2009-05-10 22:04:38.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/drivers/acpi/processor_idle.c 2009-05-10 23:48:28.000000000 +0200 +@@ -66,17 +66,43 @@ + #define ACPI_PROCESSOR_FILE_POWER "power" + #define US_TO_PM_TIMER_TICKS(t) ((t * (PM_TIMER_FREQUENCY/1000)) / 1000) + #define PM_TIMER_TICK_NS (1000000000ULL/PM_TIMER_FREQUENCY) ++#ifndef CONFIG_CPU_IDLE ++#define C2_OVERHEAD 4 /* 1us (3.579 ticks per us) */ ++#define C3_OVERHEAD 4 /* 1us (3.579 ticks per us) */ ++static void (*pm_idle_save) (void) __read_mostly; ++#else + #define C2_OVERHEAD 1 /* 1us */ + #define C3_OVERHEAD 1 /* 1us */ ++#endif + #define PM_TIMER_TICKS_TO_US(p) (((p) * 1000)/(PM_TIMER_FREQUENCY/1000)) + + static unsigned int max_cstate __read_mostly = ACPI_PROCESSOR_MAX_POWER; ++#ifdef CONFIG_CPU_IDLE + module_param(max_cstate, uint, 0000); ++#else ++module_param(max_cstate, uint, 0644); ++#endif + static unsigned int nocst __read_mostly; + module_param(nocst, uint, 0000); + ++#ifndef CONFIG_CPU_IDLE ++/* ++ * bm_history -- bit-mask with a bit per jiffy of bus-master activity ++ * 1000 HZ: 0xFFFFFFFF: 32 jiffies = 32ms ++ * 800 HZ: 0xFFFFFFFF: 32 jiffies = 40ms ++ * 100 HZ: 0x0000000F: 4 jiffies = 40ms ++ * reduce history for more aggressive entry into C3 ++ */ ++static unsigned int bm_history __read_mostly = ++ (HZ >= 800 ? 0xFFFFFFFF : ((1U << (HZ / 25)) - 1)); ++module_param(bm_history, uint, 0644); ++ ++static int acpi_processor_set_power_policy(struct acpi_processor *pr); ++ ++#else /* CONFIG_CPU_IDLE */ + static unsigned int latency_factor __read_mostly = 2; + module_param(latency_factor, uint, 0644); ++#endif + + /* + * IBM ThinkPad R40e crashes mysteriously when going into C2 or C3. +@@ -198,6 +224,71 @@ + current_thread_info()->status |= TS_POLLING; + } + ++#ifndef CONFIG_CPU_IDLE ++ ++static void ++acpi_processor_power_activate(struct acpi_processor *pr, ++ struct acpi_processor_cx *new) ++{ ++ struct acpi_processor_cx *old; ++ ++ if (!pr || !new) ++ return; ++ ++ old = pr->power.state; ++ ++ if (old) ++ old->promotion.count = 0; ++ new->demotion.count = 0; ++ ++ /* Cleanup from old state. */ ++ if (old) { ++ switch (old->type) { ++ case ACPI_STATE_C3: ++ /* Disable bus master reload */ ++ if (new->type != ACPI_STATE_C3 && pr->flags.bm_check) ++ acpi_set_register(ACPI_BITREG_BUS_MASTER_RLD, 0); ++ break; ++ } ++ } ++ ++ /* Prepare to use new state. */ ++ switch (new->type) { ++ case ACPI_STATE_C3: ++ /* Enable bus master reload */ ++ if (old->type != ACPI_STATE_C3 && pr->flags.bm_check) ++ acpi_set_register(ACPI_BITREG_BUS_MASTER_RLD, 1); ++ break; ++ } ++ ++ pr->power.state = new; ++ ++ return; ++} ++ ++static atomic_t c3_cpu_count; ++ ++/* Common C-state entry for C2, C3, .. */ ++static void acpi_cstate_enter(struct acpi_processor_cx *cstate) ++{ ++ /* Don't trace irqs off for idle */ ++ stop_critical_timings(); ++ if (cstate->entry_method == ACPI_CSTATE_FFH) { ++ /* Call into architectural FFH based C-state */ ++ acpi_processor_ffh_cstate_enter(cstate); ++ } else { ++ int unused; ++ /* IO port based C-state */ ++ inb(cstate->address); ++ /* Dummy wait op - must do something useless after P_LVL2 read ++ because chipsets cannot guarantee that STPCLK# signal ++ gets asserted in time to freeze execution properly. */ ++ unused = inl(acpi_gbl_FADT.xpm_timer_block.address); ++ } ++ start_critical_timings(); ++} ++#endif /* !CONFIG_CPU_IDLE */ ++ + #ifdef ARCH_APICTIMER_STOPS_ON_C3 + + /* +@@ -299,6 +390,421 @@ + } + #endif + ++#ifndef CONFIG_CPU_IDLE ++static void acpi_processor_idle(void) ++{ ++ struct acpi_processor *pr = NULL; ++ struct acpi_processor_cx *cx = NULL; ++ struct acpi_processor_cx *next_state = NULL; ++ int sleep_ticks = 0; ++ u32 t1, t2 = 0; ++ ++ /* ++ * Interrupts must be disabled during bus mastering calculations and ++ * for C2/C3 transitions. ++ */ ++ local_irq_disable(); ++ ++ pr = __get_cpu_var(processors); ++ if (!pr) { ++ local_irq_enable(); ++ return; ++ } ++ ++ /* ++ * Check whether we truly need to go idle, or should ++ * reschedule: ++ */ ++ if (unlikely(need_resched())) { ++ local_irq_enable(); ++ return; ++ } ++ ++ cx = pr->power.state; ++ if (!cx || acpi_idle_suspend) { ++ if (pm_idle_save) { ++ pm_idle_save(); /* enables IRQs */ ++ } else { ++ acpi_safe_halt(); ++ local_irq_enable(); ++ } ++ ++ return; ++ } ++ ++ /* ++ * Check BM Activity ++ * ----------------- ++ * Check for bus mastering activity (if required), record, and check ++ * for demotion. ++ */ ++ if (pr->flags.bm_check) { ++ u32 bm_status = 0; ++ unsigned long diff = jiffies - pr->power.bm_check_timestamp; ++ ++ if (diff > 31) ++ diff = 31; ++ ++ pr->power.bm_activity <<= diff; ++ ++ acpi_get_register(ACPI_BITREG_BUS_MASTER_STATUS, &bm_status); ++ if (bm_status) { ++ pr->power.bm_activity |= 0x1; ++ acpi_set_register(ACPI_BITREG_BUS_MASTER_STATUS, 1); ++ } ++ /* ++ * PIIX4 Erratum #18: Note that BM_STS doesn't always reflect ++ * the true state of bus mastering activity; forcing us to ++ * manually check the BMIDEA bit of each IDE channel. ++ */ ++ else if (errata.piix4.bmisx) { ++ if ((inb_p(errata.piix4.bmisx + 0x02) & 0x01) ++ || (inb_p(errata.piix4.bmisx + 0x0A) & 0x01)) ++ pr->power.bm_activity |= 0x1; ++ } ++ ++ pr->power.bm_check_timestamp = jiffies; ++ ++ /* ++ * If bus mastering is or was active this jiffy, demote ++ * to avoid a faulty transition. Note that the processor ++ * won't enter a low-power state during this call (to this ++ * function) but should upon the next. ++ * ++ * TBD: A better policy might be to fallback to the demotion ++ * state (use it for this quantum only) istead of ++ * demoting -- and rely on duration as our sole demotion ++ * qualification. This may, however, introduce DMA ++ * issues (e.g. floppy DMA transfer overrun/underrun). ++ */ ++ if ((pr->power.bm_activity & 0x1) && ++ cx->demotion.threshold.bm) { ++ local_irq_enable(); ++ next_state = cx->demotion.state; ++ goto end; ++ } ++ } ++ ++#ifdef CONFIG_HOTPLUG_CPU ++ /* ++ * Check for P_LVL2_UP flag before entering C2 and above on ++ * an SMP system. We do it here instead of doing it at _CST/P_LVL ++ * detection phase, to work cleanly with logical CPU hotplug. ++ */ ++ if ((cx->type != ACPI_STATE_C1) && (num_online_cpus() > 1) && ++ !pr->flags.has_cst && !(acpi_gbl_FADT.flags & ACPI_FADT_C2_MP_SUPPORTED)) ++ cx = &pr->power.states[ACPI_STATE_C1]; ++#endif ++ ++ /* ++ * Sleep: ++ * ------ ++ * Invoke the current Cx state to put the processor to sleep. ++ */ ++ if (cx->type == ACPI_STATE_C2 || cx->type == ACPI_STATE_C3) { ++ current_thread_info()->status &= ~TS_POLLING; ++ /* ++ * TS_POLLING-cleared state must be visible before we ++ * test NEED_RESCHED: ++ */ ++ smp_mb(); ++ if (need_resched()) { ++ current_thread_info()->status |= TS_POLLING; ++ local_irq_enable(); ++ return; ++ } ++ } ++ ++ switch (cx->type) { ++ ++ case ACPI_STATE_C1: ++ /* ++ * Invoke C1. ++ * Use the appropriate idle routine, the one that would ++ * be used without acpi C-states. ++ */ ++ if (pm_idle_save) { ++ pm_idle_save(); /* enables IRQs */ ++ } else { ++ acpi_safe_halt(); ++ local_irq_enable(); ++ } ++ ++ /* ++ * TBD: Can't get time duration while in C1, as resumes ++ * go to an ISR rather than here. Need to instrument ++ * base interrupt handler. ++ * ++ * Note: the TSC better not stop in C1, sched_clock() will ++ * skew otherwise. ++ */ ++ sleep_ticks = 0xFFFFFFFF; ++ ++ break; ++ ++ case ACPI_STATE_C2: ++ /* Get start time (ticks) */ ++ t1 = inl(acpi_gbl_FADT.xpm_timer_block.address); ++ /* Tell the scheduler that we are going deep-idle: */ ++ sched_clock_idle_sleep_event(); ++ /* Invoke C2 */ ++ acpi_state_timer_broadcast(pr, cx, 1); ++ acpi_cstate_enter(cx); ++ /* Get end time (ticks) */ ++ t2 = inl(acpi_gbl_FADT.xpm_timer_block.address); ++ ++#if defined (CONFIG_GENERIC_TIME) && defined (CONFIG_X86) ++ /* TSC halts in C2, so notify users */ ++ if (tsc_halts_in_c(ACPI_STATE_C2)) ++ mark_tsc_unstable("possible TSC halt in C2"); ++#endif ++ /* Compute time (ticks) that we were actually asleep */ ++ sleep_ticks = ticks_elapsed(t1, t2); ++ ++ /* Tell the scheduler how much we idled: */ ++ sched_clock_idle_wakeup_event(sleep_ticks*PM_TIMER_TICK_NS); ++ ++ /* Re-enable interrupts */ ++ local_irq_enable(); ++ /* Do not account our idle-switching overhead: */ ++ sleep_ticks -= cx->latency_ticks + C2_OVERHEAD; ++ ++ current_thread_info()->status |= TS_POLLING; ++ acpi_state_timer_broadcast(pr, cx, 0); ++ break; ++ ++ case ACPI_STATE_C3: ++ acpi_unlazy_tlb(smp_processor_id()); ++ /* ++ * Must be done before busmaster disable as we might ++ * need to access HPET ! ++ */ ++ acpi_state_timer_broadcast(pr, cx, 1); ++ /* ++ * disable bus master ++ * bm_check implies we need ARB_DIS ++ * !bm_check implies we need cache flush ++ * bm_control implies whether we can do ARB_DIS ++ * ++ * That leaves a case where bm_check is set and bm_control is ++ * not set. In that case we cannot do much, we enter C3 ++ * without doing anything. ++ */ ++ if (pr->flags.bm_check && pr->flags.bm_control) { ++ if (atomic_inc_return(&c3_cpu_count) == ++ num_online_cpus()) { ++ /* ++ * All CPUs are trying to go to C3 ++ * Disable bus master arbitration ++ */ ++ acpi_set_register(ACPI_BITREG_ARB_DISABLE, 1); ++ } ++ } else if (!pr->flags.bm_check) { ++ /* SMP with no shared cache... Invalidate cache */ ++ ACPI_FLUSH_CPU_CACHE(); ++ } ++ ++ /* Get start time (ticks) */ ++ t1 = inl(acpi_gbl_FADT.xpm_timer_block.address); ++ /* Invoke C3 */ ++ /* Tell the scheduler that we are going deep-idle: */ ++ sched_clock_idle_sleep_event(); ++ acpi_cstate_enter(cx); ++ /* Get end time (ticks) */ ++ t2 = inl(acpi_gbl_FADT.xpm_timer_block.address); ++ if (pr->flags.bm_check && pr->flags.bm_control) { ++ /* Enable bus master arbitration */ ++ atomic_dec(&c3_cpu_count); ++ acpi_set_register(ACPI_BITREG_ARB_DISABLE, 0); ++ } ++ ++#if defined (CONFIG_GENERIC_TIME) && defined (CONFIG_X86) ++ /* TSC halts in C3, so notify users */ ++ if (tsc_halts_in_c(ACPI_STATE_C3)) ++ mark_tsc_unstable("TSC halts in C3"); ++#endif ++ /* Compute time (ticks) that we were actually asleep */ ++ sleep_ticks = ticks_elapsed(t1, t2); ++ /* Tell the scheduler how much we idled: */ ++ sched_clock_idle_wakeup_event(sleep_ticks*PM_TIMER_TICK_NS); ++ ++ /* Re-enable interrupts */ ++ local_irq_enable(); ++ /* Do not account our idle-switching overhead: */ ++ sleep_ticks -= cx->latency_ticks + C3_OVERHEAD; ++ ++ current_thread_info()->status |= TS_POLLING; ++ acpi_state_timer_broadcast(pr, cx, 0); ++ break; ++ ++ default: ++ local_irq_enable(); ++ return; ++ } ++ cx->usage++; ++ if ((cx->type != ACPI_STATE_C1) && (sleep_ticks > 0)) ++ cx->time += sleep_ticks; ++ ++ next_state = pr->power.state; ++ ++#ifdef CONFIG_HOTPLUG_CPU ++ /* Don't do promotion/demotion */ ++ if ((cx->type == ACPI_STATE_C1) && (num_online_cpus() > 1) && ++ !pr->flags.has_cst && !(acpi_gbl_FADT.flags & ACPI_FADT_C2_MP_SUPPORTED)) { ++ next_state = cx; ++ goto end; ++ } ++#endif ++ ++ /* ++ * Promotion? ++ * ---------- ++ * Track the number of longs (time asleep is greater than threshold) ++ * and promote when the count threshold is reached. Note that bus ++ * mastering activity may prevent promotions. ++ * Do not promote above max_cstate. ++ */ ++ if (cx->promotion.state && ++ ((cx->promotion.state - pr->power.states) <= max_cstate)) { ++ if (sleep_ticks > cx->promotion.threshold.ticks && ++ cx->promotion.state->latency <= ++ pm_qos_requirement(PM_QOS_CPU_DMA_LATENCY)) { ++ cx->promotion.count++; ++ cx->demotion.count = 0; ++ if (cx->promotion.count >= ++ cx->promotion.threshold.count) { ++ if (pr->flags.bm_check) { ++ if (! ++ (pr->power.bm_activity & cx-> ++ promotion.threshold.bm)) { ++ next_state = ++ cx->promotion.state; ++ goto end; ++ } ++ } else { ++ next_state = cx->promotion.state; ++ goto end; ++ } ++ } ++ } ++ } ++ ++ /* ++ * Demotion? ++ * --------- ++ * Track the number of shorts (time asleep is less than time threshold) ++ * and demote when the usage threshold is reached. ++ */ ++ if (cx->demotion.state) { ++ if (sleep_ticks < cx->demotion.threshold.ticks) { ++ cx->demotion.count++; ++ cx->promotion.count = 0; ++ if (cx->demotion.count >= cx->demotion.threshold.count) { ++ next_state = cx->demotion.state; ++ goto end; ++ } ++ } ++ } ++ ++ end: ++ /* ++ * Demote if current state exceeds max_cstate ++ * or if the latency of the current state is unacceptable ++ */ ++ if ((pr->power.state - pr->power.states) > max_cstate || ++ pr->power.state->latency > ++ pm_qos_requirement(PM_QOS_CPU_DMA_LATENCY)) { ++ if (cx->demotion.state) ++ next_state = cx->demotion.state; ++ } ++ ++ /* ++ * New Cx State? ++ * ------------- ++ * If we're going to start using a new Cx state we must clean up ++ * from the previous and prepare to use the new. ++ */ ++ if (next_state != pr->power.state) ++ acpi_processor_power_activate(pr, next_state); ++} ++ ++static int acpi_processor_set_power_policy(struct acpi_processor *pr) ++{ ++ unsigned int i; ++ unsigned int state_is_set = 0; ++ struct acpi_processor_cx *lower = NULL; ++ struct acpi_processor_cx *higher = NULL; ++ struct acpi_processor_cx *cx; ++ ++ ++ if (!pr) ++ return -EINVAL; ++ ++ /* ++ * This function sets the default Cx state policy (OS idle handler). ++ * Our scheme is to promote quickly to C2 but more conservatively ++ * to C3. We're favoring C2 for its characteristics of low latency ++ * (quick response), good power savings, and ability to allow bus ++ * mastering activity. Note that the Cx state policy is completely ++ * customizable and can be altered dynamically. ++ */ ++ ++ /* startup state */ ++ for (i = 1; i < ACPI_PROCESSOR_MAX_POWER; i++) { ++ cx = &pr->power.states[i]; ++ if (!cx->valid) ++ continue; ++ ++ if (!state_is_set) ++ pr->power.state = cx; ++ state_is_set++; ++ break; ++ } ++ ++ if (!state_is_set) ++ return -ENODEV; ++ ++ /* demotion */ ++ for (i = 1; i < ACPI_PROCESSOR_MAX_POWER; i++) { ++ cx = &pr->power.states[i]; ++ if (!cx->valid) ++ continue; ++ ++ if (lower) { ++ cx->demotion.state = lower; ++ cx->demotion.threshold.ticks = cx->latency_ticks; ++ cx->demotion.threshold.count = 1; ++ if (cx->type == ACPI_STATE_C3) ++ cx->demotion.threshold.bm = bm_history; ++ } ++ ++ lower = cx; ++ } ++ ++ /* promotion */ ++ for (i = (ACPI_PROCESSOR_MAX_POWER - 1); i > 0; i--) { ++ cx = &pr->power.states[i]; ++ if (!cx->valid) ++ continue; ++ ++ if (higher) { ++ cx->promotion.state = higher; ++ cx->promotion.threshold.ticks = cx->latency_ticks; ++ if (cx->type >= ACPI_STATE_C2) ++ cx->promotion.threshold.count = 4; ++ else ++ cx->promotion.threshold.count = 10; ++ if (higher->type == ACPI_STATE_C3) ++ cx->promotion.threshold.bm = bm_history; ++ } ++ ++ higher = cx; ++ } ++ ++ return 0; ++} ++#endif /* !CONFIG_CPU_IDLE */ ++ + static int acpi_processor_get_power_info_fadt(struct acpi_processor *pr) + { + +@@ -541,7 +1047,11 @@ + */ + cx->valid = 1; + ++#ifndef CONFIG_CPU_IDLE ++ cx->latency_ticks = US_TO_PM_TIMER_TICKS(cx->latency); ++#else + cx->latency_ticks = cx->latency; ++#endif + + return; + } +@@ -611,6 +1121,7 @@ + " for C3 to be enabled on SMP systems\n")); + return; + } ++ acpi_set_register(ACPI_BITREG_BUS_MASTER_RLD, 0); + } + + /* +@@ -621,16 +1132,11 @@ + */ + cx->valid = 1; + ++#ifndef CONFIG_CPU_IDLE ++ cx->latency_ticks = US_TO_PM_TIMER_TICKS(cx->latency); ++#else + cx->latency_ticks = cx->latency; +- /* +- * On older chipsets, BM_RLD needs to be set +- * in order for Bus Master activity to wake the +- * system from C3. Newer chipsets handle DMA +- * during C3 automatically and BM_RLD is a NOP. +- * In either case, the proper way to +- * handle BM_RLD is to set it and leave it set. +- */ +- acpi_set_register(ACPI_BITREG_BUS_MASTER_RLD, 1); ++#endif + + return; + } +@@ -695,6 +1201,20 @@ + + pr->power.count = acpi_processor_power_verify(pr); + ++#ifndef CONFIG_CPU_IDLE ++ /* ++ * Set Default Policy ++ * ------------------ ++ * Now that we know which states are supported, set the default ++ * policy. Note that this policy can be changed dynamically ++ * (e.g. encourage deeper sleeps to conserve battery life when ++ * not on AC). ++ */ ++ result = acpi_processor_set_power_policy(pr); ++ if (result) ++ return result; ++#endif ++ + /* + * if one state of type C2 or C3 is available, mark this + * CPU as being "idle manageable" +@@ -792,6 +1312,69 @@ + .release = single_release, + }; + ++#ifndef CONFIG_CPU_IDLE ++ ++int acpi_processor_cst_has_changed(struct acpi_processor *pr) ++{ ++ int result = 0; ++ ++ if (boot_option_idle_override) ++ return 0; ++ ++ if (!pr) ++ return -EINVAL; ++ ++ if (nocst) { ++ return -ENODEV; ++ } ++ ++ if (!pr->flags.power_setup_done) ++ return -ENODEV; ++ ++ /* ++ * Fall back to the default idle loop, when pm_idle_save had ++ * been initialized. ++ */ ++ if (pm_idle_save) { ++ pm_idle = pm_idle_save; ++ /* Relies on interrupts forcing exit from idle. */ ++ synchronize_sched(); ++ } ++ ++ pr->flags.power = 0; ++ result = acpi_processor_get_power_info(pr); ++ if ((pr->flags.power == 1) && (pr->flags.power_setup_done)) ++ pm_idle = acpi_processor_idle; ++ ++ return result; ++} ++ ++#ifdef CONFIG_SMP ++static void smp_callback(void *v) ++{ ++ /* we already woke the CPU up, nothing more to do */ ++} ++ ++/* ++ * This function gets called when a part of the kernel has a new latency ++ * requirement. This means we need to get all processors out of their C-state, ++ * and then recalculate a new suitable C-state. Just do a cross-cpu IPI; that ++ * wakes them all right up. ++ */ ++static int acpi_processor_latency_notify(struct notifier_block *b, ++ unsigned long l, void *v) ++{ ++ smp_call_function(smp_callback, NULL, 1); ++ return NOTIFY_OK; ++} ++ ++static struct notifier_block acpi_processor_latency_notifier = { ++ .notifier_call = acpi_processor_latency_notify, ++}; ++ ++#endif ++ ++#else /* CONFIG_CPU_IDLE */ + + /** + * acpi_idle_bm_check - checks if bus master activity was detected +@@ -800,7 +1383,7 @@ + { + u32 bm_status = 0; + +- acpi_get_register_unlocked(ACPI_BITREG_BUS_MASTER_STATUS, &bm_status); ++ acpi_get_register(ACPI_BITREG_BUS_MASTER_STATUS, &bm_status); + if (bm_status) + acpi_set_register(ACPI_BITREG_BUS_MASTER_STATUS, 1); + /* +@@ -817,6 +1400,25 @@ + } + + /** ++ * acpi_idle_update_bm_rld - updates the BM_RLD bit depending on target state ++ * @pr: the processor ++ * @target: the new target state ++ */ ++static inline void acpi_idle_update_bm_rld(struct acpi_processor *pr, ++ struct acpi_processor_cx *target) ++{ ++ if (pr->flags.bm_rld_set && target->type != ACPI_STATE_C3) { ++ acpi_set_register(ACPI_BITREG_BUS_MASTER_RLD, 0); ++ pr->flags.bm_rld_set = 0; ++ } ++ ++ if (!pr->flags.bm_rld_set && target->type == ACPI_STATE_C3) { ++ acpi_set_register(ACPI_BITREG_BUS_MASTER_RLD, 1); ++ pr->flags.bm_rld_set = 1; ++ } ++} ++ ++/** + * acpi_idle_do_entry - a helper function that does C2 and C3 type entry + * @cx: cstate data + * +@@ -871,6 +1473,9 @@ + return 0; + } + ++ if (pr->flags.bm_check) ++ acpi_idle_update_bm_rld(pr, cx); ++ + t1 = inl(acpi_gbl_FADT.xpm_timer_block.address); + acpi_idle_do_entry(cx); + t2 = inl(acpi_gbl_FADT.xpm_timer_block.address); +@@ -922,6 +1527,9 @@ + */ + acpi_state_timer_broadcast(pr, cx, 1); + ++ if (pr->flags.bm_check) ++ acpi_idle_update_bm_rld(pr, cx); ++ + if (cx->type == ACPI_STATE_C3) + ACPI_FLUSH_CPU_CACHE(); + +@@ -1013,6 +1621,8 @@ + */ + acpi_state_timer_broadcast(pr, cx, 1); + ++ acpi_idle_update_bm_rld(pr, cx); ++ + /* + * disable bus master + * bm_check implies we need ARB_DIS +@@ -1185,6 +1795,8 @@ + return ret; + } + ++#endif /* CONFIG_CPU_IDLE */ ++ + int __cpuinit acpi_processor_power_init(struct acpi_processor *pr, + struct acpi_device *device) + { +@@ -1213,6 +1825,10 @@ + "ACPI: processor limited to max C-state %d\n", + max_cstate); + first_run++; ++#if !defined(CONFIG_CPU_IDLE) && defined(CONFIG_SMP) ++ pm_qos_add_notifier(PM_QOS_CPU_DMA_LATENCY, ++ &acpi_processor_latency_notifier); ++#endif + } + + if (!pr) +@@ -1236,9 +1852,11 @@ + * platforms that only support C1. + */ + if (pr->flags.power) { ++#ifdef CONFIG_CPU_IDLE + acpi_processor_setup_cpuidle(pr); + if (cpuidle_register_device(&pr->power.dev)) + return -EIO; ++#endif + + printk(KERN_INFO PREFIX "CPU%d (power states:", pr->id); + for (i = 1; i <= pr->power.count; i++) +@@ -1246,6 +1864,13 @@ + printk(" C%d[C%d]", i, + pr->power.states[i].type); + printk(")\n"); ++ ++#ifndef CONFIG_CPU_IDLE ++ if (pr->id == 0) { ++ pm_idle_save = pm_idle; ++ pm_idle = acpi_processor_idle; ++ } ++#endif + } + + /* 'power' [R] */ +@@ -1264,12 +1889,34 @@ + if (boot_option_idle_override) + return 0; + ++#ifdef CONFIG_CPU_IDLE + cpuidle_unregister_device(&pr->power.dev); ++#endif + pr->flags.power_setup_done = 0; + + if (acpi_device_dir(device)) + remove_proc_entry(ACPI_PROCESSOR_FILE_POWER, + acpi_device_dir(device)); + ++#ifndef CONFIG_CPU_IDLE ++ ++ /* Unregister the idle handler when processor #0 is removed. */ ++ if (pr->id == 0) { ++ if (pm_idle_save) ++ pm_idle = pm_idle_save; ++ ++ /* ++ * We are about to unload the current idle thread pm callback ++ * (pm_idle), Wait for all processors to update cached/local ++ * copies of pm_idle before proceeding. ++ */ ++ cpu_idle_wait(); ++#ifdef CONFIG_SMP ++ pm_qos_remove_notifier(PM_QOS_CPU_DMA_LATENCY, ++ &acpi_processor_latency_notifier); ++#endif ++ } ++#endif ++ + return 0; + } +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/drivers/acpi/processor_perflib.c linux-2.6.29-rc3.owrt/drivers/acpi/processor_perflib.c +--- linux-2.6.29.owrt/drivers/acpi/processor_perflib.c 2009-05-10 22:04:38.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/drivers/acpi/processor_perflib.c 2009-05-10 23:48:28.000000000 +0200 +@@ -31,6 +31,14 @@ + #include <linux/init.h> + #include <linux/cpufreq.h> + ++#ifdef CONFIG_X86_ACPI_CPUFREQ_PROC_INTF ++#include <linux/proc_fs.h> ++#include <linux/seq_file.h> ++#include <linux/mutex.h> ++ ++#include <asm/uaccess.h> ++#endif ++ + #ifdef CONFIG_X86 + #include <asm/cpufeature.h> + #endif +@@ -426,6 +434,96 @@ + + EXPORT_SYMBOL(acpi_processor_notify_smm); + ++#ifdef CONFIG_X86_ACPI_CPUFREQ_PROC_INTF ++/* /proc/acpi/processor/../performance interface (DEPRECATED) */ ++ ++static int acpi_processor_perf_open_fs(struct inode *inode, struct file *file); ++static struct file_operations acpi_processor_perf_fops = { ++ .owner = THIS_MODULE, ++ .open = acpi_processor_perf_open_fs, ++ .read = seq_read, ++ .llseek = seq_lseek, ++ .release = single_release, ++}; ++ ++static int acpi_processor_perf_seq_show(struct seq_file *seq, void *offset) ++{ ++ struct acpi_processor *pr = seq->private; ++ int i; ++ ++ ++ if (!pr) ++ goto end; ++ ++ if (!pr->performance) { ++ seq_puts(seq, "<not supported>\n"); ++ goto end; ++ } ++ ++ seq_printf(seq, "state count: %d\n" ++ "active state: P%d\n", ++ pr->performance->state_count, pr->performance->state); ++ ++ seq_puts(seq, "states:\n"); ++ for (i = 0; i < pr->performance->state_count; i++) ++ seq_printf(seq, ++ " %cP%d: %d MHz, %d mW, %d uS\n", ++ (i == pr->performance->state ? '*' : ' '), i, ++ (u32) pr->performance->states[i].core_frequency, ++ (u32) pr->performance->states[i].power, ++ (u32) pr->performance->states[i].transition_latency); ++ ++ end: ++ return 0; ++} ++ ++static int acpi_processor_perf_open_fs(struct inode *inode, struct file *file) ++{ ++ return single_open(file, acpi_processor_perf_seq_show, ++ PDE(inode)->data); ++} ++ ++static void acpi_cpufreq_add_file(struct acpi_processor *pr) ++{ ++ struct acpi_device *device = NULL; ++ ++ ++ if (acpi_bus_get_device(pr->handle, &device)) ++ return; ++ ++ /* add file 'performance' [R/W] */ ++ proc_create_data(ACPI_PROCESSOR_FILE_PERFORMANCE, S_IFREG | S_IRUGO, ++ acpi_device_dir(device), ++ &acpi_processor_perf_fops, acpi_driver_data(device)); ++ return; ++} ++ ++static void acpi_cpufreq_remove_file(struct acpi_processor *pr) ++{ ++ struct acpi_device *device = NULL; ++ ++ ++ if (acpi_bus_get_device(pr->handle, &device)) ++ return; ++ ++ /* remove file 'performance' */ ++ remove_proc_entry(ACPI_PROCESSOR_FILE_PERFORMANCE, ++ acpi_device_dir(device)); ++ ++ return; ++} ++ ++#else ++static void acpi_cpufreq_add_file(struct acpi_processor *pr) ++{ ++ return; ++} ++static void acpi_cpufreq_remove_file(struct acpi_processor *pr) ++{ ++ return; ++} ++#endif /* CONFIG_X86_ACPI_CPUFREQ_PROC_INTF */ ++ + static int acpi_processor_get_psd(struct acpi_processor *pr) + { + int result = 0; +@@ -649,12 +747,14 @@ + } + EXPORT_SYMBOL(acpi_processor_preregister_performance); + ++ + int + acpi_processor_register_performance(struct acpi_processor_performance + *performance, unsigned int cpu) + { + struct acpi_processor *pr; + ++ + if (!(acpi_processor_ppc_status & PPC_REGISTERED)) + return -EINVAL; + +@@ -681,6 +781,8 @@ + return -EIO; + } + ++ acpi_cpufreq_add_file(pr); ++ + mutex_unlock(&performance_mutex); + return 0; + } +@@ -693,6 +795,7 @@ + { + struct acpi_processor *pr; + ++ + mutex_lock(&performance_mutex); + + pr = per_cpu(processors, cpu); +@@ -705,6 +808,8 @@ + kfree(pr->performance->states); + pr->performance = NULL; + ++ acpi_cpufreq_remove_file(pr); ++ + mutex_unlock(&performance_mutex); + + return; +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/drivers/acpi/sleep.c linux-2.6.29-rc3.owrt/drivers/acpi/sleep.c +--- linux-2.6.29.owrt/drivers/acpi/sleep.c 2009-05-10 22:04:38.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/drivers/acpi/sleep.c 2009-05-10 23:48:28.000000000 +0200 +@@ -90,6 +90,31 @@ + old_suspend_ordering = true; + } + ++/* ++ * According to the ACPI specification the BIOS should make sure that ACPI is ++ * enabled and SCI_EN bit is set on wake-up from S1 - S3 sleep states. Still, ++ * some BIOSes don't do that and therefore we use acpi_enable() to enable ACPI ++ * on such systems during resume. Unfortunately that doesn't help in ++ * particularly pathological cases in which SCI_EN has to be set directly on ++ * resume, although the specification states very clearly that this flag is ++ * owned by the hardware. The set_sci_en_on_resume variable will be set in such ++ * cases. ++ */ ++static bool set_sci_en_on_resume; ++/* ++ * The ACPI specification wants us to save NVS memory regions during hibernation ++ * and to restore them during the subsequent resume. However, it is not certain ++ * if this mechanism is going to work on all machines, so we allow the user to ++ * disable this mechanism using the 'acpi_sleep=s4_nonvs' kernel command line ++ * option. ++ */ ++static bool s4_no_nvs; ++ ++void __init acpi_s4_no_nvs(void) ++{ ++ s4_no_nvs = true; ++} ++ + /** + * acpi_pm_disable_gpes - Disable the GPEs. + */ +@@ -168,18 +193,6 @@ + #endif /* CONFIG_ACPI_SLEEP */ + + #ifdef CONFIG_SUSPEND +-/* +- * According to the ACPI specification the BIOS should make sure that ACPI is +- * enabled and SCI_EN bit is set on wake-up from S1 - S3 sleep states. Still, +- * some BIOSes don't do that and therefore we use acpi_enable() to enable ACPI +- * on such systems during resume. Unfortunately that doesn't help in +- * particularly pathological cases in which SCI_EN has to be set directly on +- * resume, although the specification states very clearly that this flag is +- * owned by the hardware. The set_sci_en_on_resume variable will be set in such +- * cases. +- */ +-static bool set_sci_en_on_resume; +- + extern void do_suspend_lowlevel(void); + + static u32 acpi_suspend_states[] = { +@@ -378,41 +391,11 @@ + DMI_MATCH(DMI_PRODUCT_NAME, "Macmini1,1"), + }, + }, +- { +- .callback = init_old_suspend_ordering, +- .ident = "Asus Pundit P1-AH2 (M2N8L motherboard)", +- .matches = { +- DMI_MATCH(DMI_BOARD_VENDOR, "ASUSTek Computer INC."), +- DMI_MATCH(DMI_BOARD_NAME, "M2N8L"), +- }, +- }, +- { +- .callback = init_set_sci_en_on_resume, +- .ident = "Toshiba Satellite L300", +- .matches = { +- DMI_MATCH(DMI_SYS_VENDOR, "TOSHIBA"), +- DMI_MATCH(DMI_PRODUCT_NAME, "Satellite L300"), +- }, +- }, + {}, + }; + #endif /* CONFIG_SUSPEND */ + + #ifdef CONFIG_HIBERNATION +-/* +- * The ACPI specification wants us to save NVS memory regions during hibernation +- * and to restore them during the subsequent resume. However, it is not certain +- * if this mechanism is going to work on all machines, so we allow the user to +- * disable this mechanism using the 'acpi_sleep=s4_nonvs' kernel command line +- * option. +- */ +-static bool s4_no_nvs; +- +-void __init acpi_s4_no_nvs(void) +-{ +- s4_no_nvs = true; +-} +- + static unsigned long s4_hardware_signature; + static struct acpi_table_facs *facs; + static bool nosigcheck; +@@ -696,7 +679,7 @@ + static void acpi_power_off(void) + { + /* acpi_sleep_prepare(ACPI_STATE_S5) should have already been called */ +- printk(KERN_DEBUG "%s called\n", __func__); ++ printk("%s called\n", __func__); + local_irq_disable(); + acpi_enable_wakeup_device(ACPI_STATE_S5); + acpi_enter_sleep_state(ACPI_STATE_S5); +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/drivers/acpi/tables.c linux-2.6.29-rc3.owrt/drivers/acpi/tables.c +--- linux-2.6.29.owrt/drivers/acpi/tables.c 2009-05-10 22:04:38.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/drivers/acpi/tables.c 2009-05-10 23:48:28.000000000 +0200 +@@ -293,12 +293,7 @@ + + int __init acpi_table_init(void) + { +- acpi_status status; +- +- status = acpi_initialize_tables(initial_tables, ACPI_MAX_TABLES, 0); +- if (ACPI_FAILURE(status)) +- return 1; +- ++ acpi_initialize_tables(initial_tables, ACPI_MAX_TABLES, 0); + check_multiple_madt(); + return 0; + } +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/drivers/acpi/video.c linux-2.6.29-rc3.owrt/drivers/acpi/video.c +--- linux-2.6.29.owrt/drivers/acpi/video.c 2009-05-10 22:04:38.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/drivers/acpi/video.c 2009-05-10 23:48:28.000000000 +0200 +@@ -1020,7 +1020,7 @@ + } + + seq_printf(seq, "levels: "); +- for (i = 2; i < dev->brightness->count; i++) ++ for (i = 0; i < dev->brightness->count; i++) + seq_printf(seq, " %d", dev->brightness->levels[i]); + seq_printf(seq, "\ncurrent: %d\n", dev->brightness->curr); + +@@ -1059,7 +1059,7 @@ + return -EFAULT; + + /* validate through the list of available levels */ +- for (i = 2; i < dev->brightness->count; i++) ++ for (i = 0; i < dev->brightness->count; i++) + if (level == dev->brightness->levels[i]) { + if (ACPI_SUCCESS + (acpi_video_device_lcd_set_level(dev, level))) +@@ -1260,7 +1260,7 @@ + printk(KERN_WARNING PREFIX + "This indicates a BIOS bug. Please contact the manufacturer.\n"); + } +- printk(KERN_WARNING "%llx\n", options); ++ printk("%llx\n", options); + seq_printf(seq, "can POST: <integrated video>"); + if (options & 2) + seq_printf(seq, " <PCI video>"); +@@ -1712,7 +1712,7 @@ + max = max_below = 0; + min = min_above = 255; + /* Find closest level to level_current */ +- for (i = 2; i < device->brightness->count; i++) { ++ for (i = 0; i < device->brightness->count; i++) { + l = device->brightness->levels[i]; + if (abs(l - level_current) < abs(delta)) { + delta = l - level_current; +@@ -1722,7 +1722,7 @@ + } + /* Ajust level_current to closest available level */ + level_current += delta; +- for (i = 2; i < device->brightness->count; i++) { ++ for (i = 0; i < device->brightness->count; i++) { + l = device->brightness->levels[i]; + if (l < min) + min = l; +@@ -2006,12 +2006,6 @@ + device->pnp.bus_id[3] = '0' + instance; + instance ++; + } +- /* a hack to fix the duplicate name "VGA" problem on Pa 3553 */ +- if (!strcmp(device->pnp.bus_id, "VGA")) { +- if (instance) +- device->pnp.bus_id[3] = '0' + instance; +- instance++; +- } + + video->device = device; + strcpy(acpi_device_name(device), ACPI_VIDEO_BUS_NAME); +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/drivers/ata/ahci.c linux-2.6.29-rc3.owrt/drivers/ata/ahci.c +--- linux-2.6.29.owrt/drivers/ata/ahci.c 2009-05-10 22:04:38.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/drivers/ata/ahci.c 2009-05-10 23:48:28.000000000 +0200 +@@ -61,14 +61,9 @@ + #define EM_MSG_LED_VALUE_ON 0x00010000 + + static int ahci_skip_host_reset; +-static int ahci_ignore_sss; +- + module_param_named(skip_host_reset, ahci_skip_host_reset, int, 0444); + MODULE_PARM_DESC(skip_host_reset, "skip global host reset (0=don't skip, 1=skip)"); + +-module_param_named(ignore_sss, ahci_ignore_sss, int, 0444); +-MODULE_PARM_DESC(ignore_sss, "Ignore staggered spinup flag (0=don't ignore, 1=ignore)"); +- + static int ahci_enable_alpm(struct ata_port *ap, + enum link_pm policy); + static void ahci_disable_alpm(struct ata_port *ap); +@@ -582,18 +577,18 @@ + { PCI_VDEVICE(NVIDIA, 0x0abd), board_ahci }, /* MCP79 */ + { PCI_VDEVICE(NVIDIA, 0x0abe), board_ahci }, /* MCP79 */ + { PCI_VDEVICE(NVIDIA, 0x0abf), board_ahci }, /* MCP79 */ +- { PCI_VDEVICE(NVIDIA, 0x0d84), board_ahci }, /* MCP89 */ +- { PCI_VDEVICE(NVIDIA, 0x0d85), board_ahci }, /* MCP89 */ +- { PCI_VDEVICE(NVIDIA, 0x0d86), board_ahci }, /* MCP89 */ +- { PCI_VDEVICE(NVIDIA, 0x0d87), board_ahci }, /* MCP89 */ +- { PCI_VDEVICE(NVIDIA, 0x0d88), board_ahci }, /* MCP89 */ +- { PCI_VDEVICE(NVIDIA, 0x0d89), board_ahci }, /* MCP89 */ +- { PCI_VDEVICE(NVIDIA, 0x0d8a), board_ahci }, /* MCP89 */ +- { PCI_VDEVICE(NVIDIA, 0x0d8b), board_ahci }, /* MCP89 */ +- { PCI_VDEVICE(NVIDIA, 0x0d8c), board_ahci }, /* MCP89 */ +- { PCI_VDEVICE(NVIDIA, 0x0d8d), board_ahci }, /* MCP89 */ +- { PCI_VDEVICE(NVIDIA, 0x0d8e), board_ahci }, /* MCP89 */ +- { PCI_VDEVICE(NVIDIA, 0x0d8f), board_ahci }, /* MCP89 */ ++ { PCI_VDEVICE(NVIDIA, 0x0bc8), board_ahci }, /* MCP7B */ ++ { PCI_VDEVICE(NVIDIA, 0x0bc9), board_ahci }, /* MCP7B */ ++ { PCI_VDEVICE(NVIDIA, 0x0bca), board_ahci }, /* MCP7B */ ++ { PCI_VDEVICE(NVIDIA, 0x0bcb), board_ahci }, /* MCP7B */ ++ { PCI_VDEVICE(NVIDIA, 0x0bcc), board_ahci }, /* MCP7B */ ++ { PCI_VDEVICE(NVIDIA, 0x0bcd), board_ahci }, /* MCP7B */ ++ { PCI_VDEVICE(NVIDIA, 0x0bce), board_ahci }, /* MCP7B */ ++ { PCI_VDEVICE(NVIDIA, 0x0bcf), board_ahci }, /* MCP7B */ ++ { PCI_VDEVICE(NVIDIA, 0x0bc4), board_ahci }, /* MCP7B */ ++ { PCI_VDEVICE(NVIDIA, 0x0bc5), board_ahci }, /* MCP7B */ ++ { PCI_VDEVICE(NVIDIA, 0x0bc6), board_ahci }, /* MCP7B */ ++ { PCI_VDEVICE(NVIDIA, 0x0bc7), board_ahci }, /* MCP7B */ + + /* SiS */ + { PCI_VDEVICE(SI, 0x1184), board_ahci }, /* SiS 966 */ +@@ -2697,10 +2692,8 @@ + host->iomap = pcim_iomap_table(pdev); + host->private_data = hpriv; + +- if (!(hpriv->cap & HOST_CAP_SSS) || ahci_ignore_sss) ++ if (!(hpriv->cap & HOST_CAP_SSS)) + host->flags |= ATA_HOST_PARALLEL_SCAN; +- else +- printk(KERN_INFO "ahci: SSS flag set, parallel bus scan disabled\n"); + + if (pi.flags & ATA_FLAG_EM) + ahci_reset_em(host); +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/drivers/ata/ata_piix.c linux-2.6.29-rc3.owrt/drivers/ata/ata_piix.c +--- linux-2.6.29.owrt/drivers/ata/ata_piix.c 2009-05-10 22:04:38.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/drivers/ata/ata_piix.c 2009-05-10 23:48:28.000000000 +0200 +@@ -1289,39 +1289,6 @@ + return map; + } + +-static bool piix_no_sidpr(struct ata_host *host) +-{ +- struct pci_dev *pdev = to_pci_dev(host->dev); +- +- /* +- * Samsung DB-P70 only has three ATA ports exposed and +- * curiously the unconnected first port reports link online +- * while not responding to SRST protocol causing excessive +- * detection delay. +- * +- * Unfortunately, the system doesn't carry enough DMI +- * information to identify the machine but does have subsystem +- * vendor and device set. As it's unclear whether the +- * subsystem vendor/device is used only for this specific +- * board, the port can't be disabled solely with the +- * information; however, turning off SIDPR access works around +- * the problem. Turn it off. +- * +- * This problem is reported in bnc#441240. +- * +- * https://bugzilla.novell.com/show_bug.cgi?id=441420 +- */ +- if (pdev->vendor == PCI_VENDOR_ID_INTEL && pdev->device == 0x2920 && +- pdev->subsystem_vendor == PCI_VENDOR_ID_SAMSUNG && +- pdev->subsystem_device == 0xb049) { +- dev_printk(KERN_WARNING, host->dev, +- "Samsung DB-P70 detected, disabling SIDPR\n"); +- return true; +- } +- +- return false; +-} +- + static int __devinit piix_init_sidpr(struct ata_host *host) + { + struct pci_dev *pdev = to_pci_dev(host->dev); +@@ -1335,10 +1302,6 @@ + if (hpriv->map[i] == IDE) + return 0; + +- /* is it blacklisted? */ +- if (piix_no_sidpr(host)) +- return 0; +- + if (!(host->ports[0]->flags & PIIX_FLAG_SIDPR)) + return 0; + +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/drivers/ata/libata-core.c linux-2.6.29-rc3.owrt/drivers/ata/libata-core.c +--- linux-2.6.29.owrt/drivers/ata/libata-core.c 2009-05-10 22:04:38.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/drivers/ata/libata-core.c 2009-05-10 23:48:28.000000000 +0200 +@@ -164,11 +164,6 @@ + MODULE_VERSION(DRV_VERSION); + + +-static bool ata_sstatus_online(u32 sstatus) +-{ +- return (sstatus & 0xf) == 0x3; +-} +- + /** + * ata_link_next - link iteration helper + * @link: the previous link, NULL to start +@@ -1020,6 +1015,18 @@ + return spd_str[spd - 1]; + } + ++void ata_dev_disable(struct ata_device *dev) ++{ ++ if (ata_dev_enabled(dev)) { ++ if (ata_msg_drv(dev->link->ap)) ++ ata_dev_printk(dev, KERN_WARNING, "disabled\n"); ++ ata_acpi_on_disable(dev); ++ ata_down_xfermask_limit(dev, ATA_DNXFER_FORCE_PIO0 | ++ ATA_DNXFER_QUIET); ++ dev->class++; ++ } ++} ++ + static int ata_dev_set_dipm(struct ata_device *dev, enum link_pm policy) + { + struct ata_link *link = dev->link; +@@ -1322,16 +1329,14 @@ + { + if (ata_id_has_lba(id)) { + if (ata_id_has_lba48(id)) +- return ata_id_u64(id, ATA_ID_LBA_CAPACITY_2); ++ return ata_id_u64(id, 100); + else +- return ata_id_u32(id, ATA_ID_LBA_CAPACITY); ++ return ata_id_u32(id, 60); + } else { + if (ata_id_current_chs_valid(id)) +- return id[ATA_ID_CUR_CYLS] * id[ATA_ID_CUR_HEADS] * +- id[ATA_ID_CUR_SECTORS]; ++ return ata_id_u32(id, 57); + else +- return id[ATA_ID_CYLS] * id[ATA_ID_HEADS] * +- id[ATA_ID_SECTORS]; ++ return id[1] * id[3] * id[6]; + } + } + +@@ -2234,40 +2239,6 @@ + return rc; + } + +-static int ata_do_link_spd_horkage(struct ata_device *dev) +-{ +- struct ata_link *plink = ata_dev_phys_link(dev); +- u32 target, target_limit; +- +- if (!sata_scr_valid(plink)) +- return 0; +- +- if (dev->horkage & ATA_HORKAGE_1_5_GBPS) +- target = 1; +- else +- return 0; +- +- target_limit = (1 << target) - 1; +- +- /* if already on stricter limit, no need to push further */ +- if (plink->sata_spd_limit <= target_limit) +- return 0; +- +- plink->sata_spd_limit = target_limit; +- +- /* Request another EH round by returning -EAGAIN if link is +- * going faster than the target speed. Forward progress is +- * guaranteed by setting sata_spd_limit to target_limit above. +- */ +- if (plink->sata_spd > target) { +- ata_dev_printk(dev, KERN_INFO, +- "applying link speed limit horkage to %s\n", +- sata_spd_string(target)); +- return -EAGAIN; +- } +- return 0; +-} +- + static inline u8 ata_dev_knobble(struct ata_device *dev) + { + struct ata_port *ap = dev->link->ap; +@@ -2358,10 +2329,6 @@ + return 0; + } + +- rc = ata_do_link_spd_horkage(dev); +- if (rc) +- return rc; +- + /* let ACPI work its magic */ + rc = ata_acpi_on_devcfg(dev); + if (rc) +@@ -2817,7 +2784,7 @@ + /* This is the last chance, better to slow + * down than lose it. + */ +- sata_down_spd_limit(&ap->link, 0); ++ sata_down_spd_limit(&ap->link); + ata_down_xfermask_limit(dev, ATA_DNXFER_PIO); + } + } +@@ -2913,27 +2880,21 @@ + /** + * sata_down_spd_limit - adjust SATA spd limit downward + * @link: Link to adjust SATA spd limit for +- * @spd_limit: Additional limit + * + * Adjust SATA spd limit of @link downward. Note that this + * function only adjusts the limit. The change must be applied + * using sata_set_spd(). + * +- * If @spd_limit is non-zero, the speed is limited to equal to or +- * lower than @spd_limit if such speed is supported. If +- * @spd_limit is slower than any supported speed, only the lowest +- * supported speed is allowed. +- * + * LOCKING: + * Inherited from caller. + * + * RETURNS: + * 0 on success, negative errno on failure + */ +-int sata_down_spd_limit(struct ata_link *link, u32 spd_limit) ++int sata_down_spd_limit(struct ata_link *link) + { + u32 sstatus, spd, mask; +- int rc, bit; ++ int rc, highbit; + + if (!sata_scr_valid(link)) + return -EOPNOTSUPP; +@@ -2942,7 +2903,7 @@ + * If not, use cached value in link->sata_spd. + */ + rc = sata_scr_read(link, SCR_STATUS, &sstatus); +- if (rc == 0 && ata_sstatus_online(sstatus)) ++ if (rc == 0) + spd = (sstatus >> 4) & 0xf; + else + spd = link->sata_spd; +@@ -2952,8 +2913,8 @@ + return -EINVAL; + + /* unconditionally mask off the highest bit */ +- bit = fls(mask) - 1; +- mask &= ~(1 << bit); ++ highbit = fls(mask) - 1; ++ mask &= ~(1 << highbit); + + /* Mask off all speeds higher than or equal to the current + * one. Force 1.5Gbps if current SPD is not available. +@@ -2967,15 +2928,6 @@ + if (!mask) + return -EINVAL; + +- if (spd_limit) { +- if (mask & ((1 << spd_limit) - 1)) +- mask &= (1 << spd_limit) - 1; +- else { +- bit = ffs(mask) - 1; +- mask = 1 << bit; +- } +- } +- + link->sata_spd_limit = mask; + + ata_link_printk(link, KERN_WARNING, "limiting SATA link speed to %s\n", +@@ -4263,9 +4215,6 @@ + /* Devices that do not need bridging limits applied */ + { "MTRON MSP-SATA*", NULL, ATA_HORKAGE_BRIDGE_OK, }, + +- /* Devices which aren't very happy with higher link speeds */ +- { "WD My Book", NULL, ATA_HORKAGE_1_5_GBPS, }, +- + /* End Marker */ + { } + }; +@@ -4614,7 +4563,7 @@ + VPRINTK("unmapping %u sg elements\n", qc->n_elem); + + if (qc->n_elem) +- dma_unmap_sg(ap->dev, sg, qc->orig_n_elem, dir); ++ dma_unmap_sg(ap->dev, sg, qc->n_elem, dir); + + qc->flags &= ~ATA_QCFLAG_DMAMAP; + qc->sg = NULL; +@@ -4729,7 +4678,7 @@ + return -1; + + DPRINTK("%d sg elements mapped\n", n_elem); +- qc->orig_n_elem = qc->n_elem; ++ + qc->n_elem = n_elem; + qc->flags |= ATA_QCFLAG_DMAMAP; + +@@ -4760,7 +4709,8 @@ + + /** + * ata_qc_new - Request an available ATA command, for queueing +- * @ap: target port ++ * @ap: Port associated with device @dev ++ * @dev: Device from whom we request an available command structure + * + * LOCKING: + * None. +@@ -5225,7 +5175,7 @@ + u32 sstatus; + + if (sata_scr_read(link, SCR_STATUS, &sstatus) == 0 && +- ata_sstatus_online(sstatus)) ++ (sstatus & 0xf) == 0x3) + return true; + return false; + } +@@ -5249,7 +5199,7 @@ + u32 sstatus; + + if (sata_scr_read(link, SCR_STATUS, &sstatus) == 0 && +- !ata_sstatus_online(sstatus)) ++ (sstatus & 0xf) != 0x3) + return true; + return false; + } +@@ -5462,8 +5412,8 @@ + dev->horkage = 0; + spin_unlock_irqrestore(ap->lock, flags); + +- memset((void *)dev + ATA_DEVICE_CLEAR_BEGIN, 0, +- ATA_DEVICE_CLEAR_END - ATA_DEVICE_CLEAR_BEGIN); ++ memset((void *)dev + ATA_DEVICE_CLEAR_OFFSET, 0, ++ sizeof(*dev) - ATA_DEVICE_CLEAR_OFFSET); + dev->pio_mask = UINT_MAX; + dev->mwdma_mask = UINT_MAX; + dev->udma_mask = UINT_MAX; +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/drivers/ata/libata-eh.c linux-2.6.29-rc3.owrt/drivers/ata/libata-eh.c +--- linux-2.6.29.owrt/drivers/ata/libata-eh.c 2009-05-10 22:04:38.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/drivers/ata/libata-eh.c 2009-05-10 23:48:28.000000000 +0200 +@@ -82,10 +82,6 @@ + ATA_EH_FASTDRAIN_INTERVAL = 3000, + + ATA_EH_UA_TRIES = 5, +- +- /* probe speed down parameters, see ata_eh_schedule_probe() */ +- ATA_EH_PROBE_TRIAL_INTERVAL = 60000, /* 1 min */ +- ATA_EH_PROBE_TRIALS = 2, + }; + + /* The following table determines how we sequence resets. Each entry +@@ -1180,32 +1176,6 @@ + } + + /** +- * ata_dev_disable - disable ATA device +- * @dev: ATA device to disable +- * +- * Disable @dev. +- * +- * Locking: +- * EH context. +- */ +-void ata_dev_disable(struct ata_device *dev) +-{ +- if (!ata_dev_enabled(dev)) +- return; +- +- if (ata_msg_drv(dev->link->ap)) +- ata_dev_printk(dev, KERN_WARNING, "disabled\n"); +- ata_acpi_on_disable(dev); +- ata_down_xfermask_limit(dev, ATA_DNXFER_FORCE_PIO0 | ATA_DNXFER_QUIET); +- dev->class++; +- +- /* From now till the next successful probe, ering is used to +- * track probe failures. Clear accumulated device error info. +- */ +- ata_ering_clear(&dev->ering); +-} +- +-/** + * ata_eh_detach_dev - detach ATA device + * @dev: ATA device to detach + * +@@ -1879,7 +1849,7 @@ + /* speed down? */ + if (verdict & ATA_EH_SPDN_SPEED_DOWN) { + /* speed down SATA link speed if possible */ +- if (sata_down_spd_limit(link, 0) == 0) { ++ if (sata_down_spd_limit(link) == 0) { + action |= ATA_EH_RESET; + goto done; + } +@@ -2423,14 +2393,11 @@ + } + + /* prereset() might have cleared ATA_EH_RESET. If so, +- * bang classes, thaw and return. ++ * bang classes and return. + */ + if (reset && !(ehc->i.action & ATA_EH_RESET)) { + ata_for_each_dev(dev, link, ALL) + classes[dev->devno] = ATA_DEV_NONE; +- if ((ap->pflags & ATA_PFLAG_FROZEN) && +- ata_is_host_link(link)) +- ata_eh_thaw_port(ap); + rc = 0; + goto out; + } +@@ -2634,11 +2601,11 @@ + } + + if (try == max_tries - 1) { +- sata_down_spd_limit(link, 0); ++ sata_down_spd_limit(link); + if (slave) +- sata_down_spd_limit(slave, 0); ++ sata_down_spd_limit(slave); + } else if (rc == -EPIPE) +- sata_down_spd_limit(failed_link, 0); ++ sata_down_spd_limit(failed_link); + + if (hardreset) + reset = hardreset; +@@ -2777,8 +2744,6 @@ + readid_flags, dev->id); + switch (rc) { + case 0: +- /* clear error info accumulated during probe */ +- ata_ering_clear(&dev->ering); + new_mask |= 1 << dev->devno; + break; + case -ENOENT: +@@ -2904,7 +2869,7 @@ + int i; + + for (i = 0; i < ATA_EH_UA_TRIES; i++) { +- u8 *sense_buffer = dev->link->ap->sector_buf; ++ u8 sense_buffer[SCSI_SENSE_BUFFERSIZE]; + u8 sense_key = 0; + unsigned int err_mask; + +@@ -2982,24 +2947,9 @@ + return 1; + } + +-static int ata_count_probe_trials_cb(struct ata_ering_entry *ent, void *void_arg) +-{ +- u64 interval = msecs_to_jiffies(ATA_EH_PROBE_TRIAL_INTERVAL); +- u64 now = get_jiffies_64(); +- int *trials = void_arg; +- +- if (ent->timestamp < now - min(now, interval)) +- return -1; +- +- (*trials)++; +- return 0; +-} +- + static int ata_eh_schedule_probe(struct ata_device *dev) + { + struct ata_eh_context *ehc = &dev->link->eh_context; +- struct ata_link *link = ata_dev_phys_link(dev); +- int trials = 0; + + if (!(ehc->i.probe_mask & (1 << dev->devno)) || + (ehc->did_probe_mask & (1 << dev->devno))) +@@ -3012,25 +2962,6 @@ + ehc->saved_xfer_mode[dev->devno] = 0; + ehc->saved_ncq_enabled &= ~(1 << dev->devno); + +- /* Record and count probe trials on the ering. The specific +- * error mask used is irrelevant. Because a successful device +- * detection clears the ering, this count accumulates only if +- * there are consecutive failed probes. +- * +- * If the count is equal to or higher than ATA_EH_PROBE_TRIALS +- * in the last ATA_EH_PROBE_TRIAL_INTERVAL, link speed is +- * forced to 1.5Gbps. +- * +- * This is to work around cases where failed link speed +- * negotiation results in device misdetection leading to +- * infinite DEVXCHG or PHRDY CHG events. +- */ +- ata_ering_record(&dev->ering, 0, AC_ERR_OTHER); +- ata_ering_map(&dev->ering, ata_count_probe_trials_cb, &trials); +- +- if (trials > ATA_EH_PROBE_TRIALS) +- sata_down_spd_limit(link, 1); +- + return 1; + } + +@@ -3038,11 +2969,7 @@ + { + struct ata_eh_context *ehc = &dev->link->eh_context; + +- /* -EAGAIN from EH routine indicates retry without prejudice. +- * The requester is responsible for ensuring forward progress. +- */ +- if (err != -EAGAIN) +- ehc->tries[dev->devno]--; ++ ehc->tries[dev->devno]--; + + switch (err) { + case -ENODEV: +@@ -3052,13 +2979,12 @@ + /* give it just one more chance */ + ehc->tries[dev->devno] = min(ehc->tries[dev->devno], 1); + case -EIO: +- if (ehc->tries[dev->devno] == 1) { ++ if (ehc->tries[dev->devno] == 1 && dev->pio_mode > XFER_PIO_0) { + /* This is the last chance, better to slow + * down than lose it. + */ +- sata_down_spd_limit(ata_dev_phys_link(dev), 0); +- if (dev->pio_mode > XFER_PIO_0) +- ata_down_xfermask_limit(dev, ATA_DNXFER_PIO); ++ sata_down_spd_limit(ata_dev_phys_link(dev)); ++ ata_down_xfermask_limit(dev, ATA_DNXFER_PIO); + } + } + +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/drivers/ata/libata.h linux-2.6.29-rc3.owrt/drivers/ata/libata.h +--- linux-2.6.29.owrt/drivers/ata/libata.h 2009-05-10 22:04:38.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/drivers/ata/libata.h 2009-05-10 23:48:28.000000000 +0200 +@@ -79,6 +79,7 @@ + u64 block, u32 n_block, unsigned int tf_flags, + unsigned int tag); + extern u64 ata_tf_read_block(struct ata_taskfile *tf, struct ata_device *dev); ++extern void ata_dev_disable(struct ata_device *dev); + extern void ata_pio_queue_task(struct ata_port *ap, void *data, + unsigned long delay); + extern void ata_port_flush_task(struct ata_port *ap); +@@ -99,7 +100,7 @@ + extern int ata_dev_revalidate(struct ata_device *dev, unsigned int new_class, + unsigned int readid_flags); + extern int ata_dev_configure(struct ata_device *dev); +-extern int sata_down_spd_limit(struct ata_link *link, u32 spd_limit); ++extern int sata_down_spd_limit(struct ata_link *link); + extern int ata_down_xfermask_limit(struct ata_device *dev, unsigned int sel); + extern void ata_sg_clean(struct ata_queued_cmd *qc); + extern void ata_qc_free(struct ata_queued_cmd *qc); +@@ -159,7 +160,6 @@ + extern void ata_port_wait_eh(struct ata_port *ap); + extern void ata_eh_fastdrain_timerfn(unsigned long arg); + extern void ata_qc_schedule_eh(struct ata_queued_cmd *qc); +-extern void ata_dev_disable(struct ata_device *dev); + extern void ata_eh_detach_dev(struct ata_device *dev); + extern void ata_eh_about_to_do(struct ata_link *link, struct ata_device *dev, + unsigned int action); +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/drivers/ata/libata-pmp.c linux-2.6.29-rc3.owrt/drivers/ata/libata-pmp.c +--- linux-2.6.29.owrt/drivers/ata/libata-pmp.c 2009-05-10 22:04:38.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/drivers/ata/libata-pmp.c 2009-05-10 23:48:28.000000000 +0200 +@@ -729,7 +729,7 @@ + if (tries) { + /* consecutive revalidation failures? speed down */ + if (reval_failed) +- sata_down_spd_limit(link, 0); ++ sata_down_spd_limit(link); + else + reval_failed = 1; + +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/drivers/ata/libata-scsi.c linux-2.6.29-rc3.owrt/drivers/ata/libata-scsi.c +--- linux-2.6.29.owrt/drivers/ata/libata-scsi.c 2009-05-10 22:04:38.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/drivers/ata/libata-scsi.c 2009-05-10 23:48:28.000000000 +0200 +@@ -415,7 +415,6 @@ + + /** + * ata_get_identity - Handler for HDIO_GET_IDENTITY ioctl +- * @ap: target port + * @sdev: SCSI device to get identify data for + * @arg: User buffer area for identify data + * +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/drivers/ata/libata-sff.c linux-2.6.29-rc3.owrt/drivers/ata/libata-sff.c +--- linux-2.6.29.owrt/drivers/ata/libata-sff.c 2009-05-10 22:04:38.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/drivers/ata/libata-sff.c 2009-05-10 23:48:28.000000000 +0200 +@@ -773,32 +773,18 @@ + else + iowrite32_rep(data_addr, buf, words); + +- /* Transfer trailing bytes, if any */ + if (unlikely(slop)) { +- unsigned char pad[4]; +- +- /* Point buf to the tail of buffer */ +- buf += buflen - slop; +- +- /* +- * Use io*_rep() accessors here as well to avoid pointlessly +- * swapping bytes to and fro on the big endian machines... +- */ ++ __le32 pad; + if (rw == READ) { +- if (slop < 3) +- ioread16_rep(data_addr, pad, 1); +- else +- ioread32_rep(data_addr, pad, 1); +- memcpy(buf, pad, slop); ++ pad = cpu_to_le32(ioread32(ap->ioaddr.data_addr)); ++ memcpy(buf + buflen - slop, &pad, slop); + } else { +- memcpy(pad, buf, slop); +- if (slop < 3) +- iowrite16_rep(data_addr, pad, 1); +- else +- iowrite32_rep(data_addr, pad, 1); ++ memcpy(&pad, buf + buflen - slop, slop); ++ iowrite32(le32_to_cpu(pad), ap->ioaddr.data_addr); + } ++ words++; + } +- return (buflen + 1) & ~1; ++ return words << 2; + } + EXPORT_SYMBOL_GPL(ata_sff_data_xfer32); + +@@ -2066,7 +2052,6 @@ + iowrite8(ap->ctl | ATA_SRST, ioaddr->ctl_addr); + udelay(20); /* FIXME: flush */ + iowrite8(ap->ctl, ioaddr->ctl_addr); +- ap->last_ctl = ap->ctl; + + /* wait the port to become ready */ + return ata_sff_wait_after_reset(&ap->link, devmask, deadline); +@@ -2191,10 +2176,8 @@ + } + + /* set up device control */ +- if (ap->ioaddr.ctl_addr) { ++ if (ap->ioaddr.ctl_addr) + iowrite8(ap->ctl, ap->ioaddr.ctl_addr); +- ap->last_ctl = ap->ctl; +- } + } + EXPORT_SYMBOL_GPL(ata_sff_postreset); + +@@ -2537,7 +2520,6 @@ + if (ap->flags & (ATA_FLAG_SATA_RESET | ATA_FLAG_SRST)) { + /* set up device control for ATA_FLAG_SATA_RESET */ + iowrite8(ap->ctl, ioaddr->ctl_addr); +- ap->last_ctl = ap->ctl; + } + + DPRINTK("EXIT\n"); +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/drivers/ata/pata_amd.c linux-2.6.29-rc3.owrt/drivers/ata/pata_amd.c +--- linux-2.6.29.owrt/drivers/ata/pata_amd.c 2009-05-10 22:04:38.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/drivers/ata/pata_amd.c 2009-05-10 23:48:28.000000000 +0200 +@@ -24,7 +24,7 @@ + #include <linux/libata.h> + + #define DRV_NAME "pata_amd" +-#define DRV_VERSION "0.4.1" ++#define DRV_VERSION "0.3.11" + + /** + * timing_setup - shared timing computation and load +@@ -145,13 +145,6 @@ + return ata_sff_prereset(link, deadline); + } + +-/** +- * amd_cable_detect - report cable type +- * @ap: port +- * +- * AMD controller/BIOS setups record the cable type in word 0x42 +- */ +- + static int amd_cable_detect(struct ata_port *ap) + { + static const u32 bitmask[2] = {0x03, 0x0C}; +@@ -165,40 +158,6 @@ + } + + /** +- * amd_fifo_setup - set the PIO FIFO for ATA/ATAPI +- * @ap: ATA interface +- * @adev: ATA device +- * +- * Set the PCI fifo for this device according to the devices present +- * on the bus at this point in time. We need to turn the post write buffer +- * off for ATAPI devices as we may need to issue a word sized write to the +- * device as the final I/O +- */ +- +-static void amd_fifo_setup(struct ata_port *ap) +-{ +- struct ata_device *adev; +- struct pci_dev *pdev = to_pci_dev(ap->host->dev); +- static const u8 fifobit[2] = { 0xC0, 0x30}; +- u8 fifo = fifobit[ap->port_no]; +- u8 r; +- +- +- ata_for_each_dev(adev, &ap->link, ENABLED) { +- if (adev->class == ATA_DEV_ATAPI) +- fifo = 0; +- } +- if (pdev->device == PCI_DEVICE_ID_AMD_VIPER_7411) /* FIFO is broken */ +- fifo = 0; +- +- /* On the later chips the read prefetch bits become no-op bits */ +- pci_read_config_byte(pdev, 0x41, &r); +- r &= ~fifobit[ap->port_no]; +- r |= fifo; +- pci_write_config_byte(pdev, 0x41, r); +-} +- +-/** + * amd33_set_piomode - set initial PIO mode data + * @ap: ATA interface + * @adev: ATA device +@@ -208,25 +167,21 @@ + + static void amd33_set_piomode(struct ata_port *ap, struct ata_device *adev) + { +- amd_fifo_setup(ap); + timing_setup(ap, adev, 0x40, adev->pio_mode, 1); + } + + static void amd66_set_piomode(struct ata_port *ap, struct ata_device *adev) + { +- amd_fifo_setup(ap); + timing_setup(ap, adev, 0x40, adev->pio_mode, 2); + } + + static void amd100_set_piomode(struct ata_port *ap, struct ata_device *adev) + { +- amd_fifo_setup(ap); + timing_setup(ap, adev, 0x40, adev->pio_mode, 3); + } + + static void amd133_set_piomode(struct ata_port *ap, struct ata_device *adev) + { +- amd_fifo_setup(ap); + timing_setup(ap, adev, 0x40, adev->pio_mode, 4); + } + +@@ -442,16 +397,6 @@ + .set_dmamode = nv133_set_dmamode, + }; + +-static void amd_clear_fifo(struct pci_dev *pdev) +-{ +- u8 fifo; +- /* Disable the FIFO, the FIFO logic will re-enable it as +- appropriate */ +- pci_read_config_byte(pdev, 0x41, &fifo); +- fifo &= 0x0F; +- pci_write_config_byte(pdev, 0x41, fifo); +-} +- + static int amd_init_one(struct pci_dev *pdev, const struct pci_device_id *id) + { + static const struct ata_port_info info[10] = { +@@ -558,8 +503,14 @@ + + if (type < 3) + ata_pci_bmdma_clear_simplex(pdev); +- if (pdev->vendor == PCI_VENDOR_ID_AMD) +- amd_clear_fifo(pdev); ++ ++ /* Check for AMD7411 */ ++ if (type == 3) ++ /* FIFO is broken */ ++ pci_write_config_byte(pdev, 0x41, fifo & 0x0F); ++ else ++ pci_write_config_byte(pdev, 0x41, fifo | 0xF0); ++ + /* Cable detection on Nvidia chips doesn't work too well, + * cache BIOS programmed UDMA mode. + */ +@@ -585,11 +536,18 @@ + return rc; + + if (pdev->vendor == PCI_VENDOR_ID_AMD) { +- amd_clear_fifo(pdev); ++ u8 fifo; ++ pci_read_config_byte(pdev, 0x41, &fifo); ++ if (pdev->device == PCI_DEVICE_ID_AMD_VIPER_7411) ++ /* FIFO is broken */ ++ pci_write_config_byte(pdev, 0x41, fifo & 0x0F); ++ else ++ pci_write_config_byte(pdev, 0x41, fifo | 0xF0); + if (pdev->device == PCI_DEVICE_ID_AMD_VIPER_7409 || + pdev->device == PCI_DEVICE_ID_AMD_COBRA_7401) + ata_pci_bmdma_clear_simplex(pdev); + } ++ + ata_host_resume(host); + return 0; + } +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/drivers/ata/pata_it821x.c linux-2.6.29-rc3.owrt/drivers/ata/pata_it821x.c +--- linux-2.6.29.owrt/drivers/ata/pata_it821x.c 2009-05-10 22:04:38.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/drivers/ata/pata_it821x.c 2009-05-10 23:48:28.000000000 +0200 +@@ -557,9 +557,6 @@ + id[83] |= 0x4400; /* Word 83 is valid and LBA48 */ + id[86] |= 0x0400; /* LBA48 on */ + id[ATA_ID_MAJOR_VER] |= 0x1F; +- /* Clear the serial number because it's different each boot +- which breaks validation on resume */ +- memset(&id[ATA_ID_SERNO], 0x20, ATA_ID_SERNO_LEN); + } + return err_mask; + } +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/drivers/ata/pata_legacy.c linux-2.6.29-rc3.owrt/drivers/ata/pata_legacy.c +--- linux-2.6.29.owrt/drivers/ata/pata_legacy.c 2009-05-10 22:04:38.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/drivers/ata/pata_legacy.c 2009-05-10 23:48:28.000000000 +0200 +@@ -283,10 +283,9 @@ + static unsigned int pdc_data_xfer_vlb(struct ata_device *dev, + unsigned char *buf, unsigned int buflen, int rw) + { +- int slop = buflen & 3; +- /* 32bit I/O capable *and* we need to write a whole number of dwords */ +- if (ata_id_has_dword_io(dev->id) && (slop == 0 || slop == 3)) { ++ if (ata_id_has_dword_io(dev->id)) { + struct ata_port *ap = dev->link->ap; ++ int slop = buflen & 3; + unsigned long flags; + + local_irq_save(flags); +@@ -736,7 +735,7 @@ + struct ata_port *ap = adev->link->ap; + int slop = buflen & 3; + +- if (ata_id_has_dword_io(adev->id) && (slop == 0 || slop == 3)) { ++ if (ata_id_has_dword_io(adev->id)) { + if (rw == WRITE) + iowrite32_rep(ap->ioaddr.data_addr, buf, buflen >> 2); + else +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/drivers/ata/pata_qdi.c linux-2.6.29-rc3.owrt/drivers/ata/pata_qdi.c +--- linux-2.6.29.owrt/drivers/ata/pata_qdi.c 2009-05-10 22:04:38.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/drivers/ata/pata_qdi.c 2009-05-10 23:48:28.000000000 +0200 +@@ -12,7 +12,7 @@ + * + * Probe code based on drivers/ide/legacy/qd65xx.c + * Rewritten from the work of Colten Edwards <pje120@cs.usask.ca> by +- * Samuel Thibault <samuel.thibault@ens-lyon.org> ++ * Samuel Thibault <samuel.thibault@fnac.net> + */ + + #include <linux/kernel.h> +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/drivers/ata/pata_via.c linux-2.6.29-rc3.owrt/drivers/ata/pata_via.c +--- linux-2.6.29.owrt/drivers/ata/pata_via.c 2009-05-10 22:04:38.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/drivers/ata/pata_via.c 2009-05-10 23:48:28.000000000 +0200 +@@ -110,8 +110,7 @@ + { "vt8237s", PCI_DEVICE_ID_VIA_8237S, 0x00, 0x2f, VIA_UDMA_133 | VIA_BAD_AST }, + { "vt8251", PCI_DEVICE_ID_VIA_8251, 0x00, 0x2f, VIA_UDMA_133 | VIA_BAD_AST }, + { "cx700", PCI_DEVICE_ID_VIA_CX700, 0x00, 0x2f, VIA_UDMA_133 | VIA_BAD_AST | VIA_SATA_PATA }, +- { "vt6410", PCI_DEVICE_ID_VIA_6410, 0x00, 0x2f, VIA_UDMA_133 | VIA_BAD_AST | VIA_NO_ENABLES }, +- { "vt6415", PCI_DEVICE_ID_VIA_6415, 0x00, 0x2f, VIA_UDMA_133 | VIA_BAD_AST | VIA_NO_ENABLES }, ++ { "vt6410", PCI_DEVICE_ID_VIA_6410, 0x00, 0x2f, VIA_UDMA_133 | VIA_BAD_AST | VIA_NO_ENABLES}, + { "vt8237a", PCI_DEVICE_ID_VIA_8237A, 0x00, 0x2f, VIA_UDMA_133 | VIA_BAD_AST }, + { "vt8237", PCI_DEVICE_ID_VIA_8237, 0x00, 0x2f, VIA_UDMA_133 | VIA_BAD_AST }, + { "vt8235", PCI_DEVICE_ID_VIA_8235, 0x00, 0x2f, VIA_UDMA_133 | VIA_BAD_AST }, +@@ -594,7 +593,6 @@ + #endif + + static const struct pci_device_id via[] = { +- { PCI_VDEVICE(VIA, 0x0415), }, + { PCI_VDEVICE(VIA, 0x0571), }, + { PCI_VDEVICE(VIA, 0x0581), }, + { PCI_VDEVICE(VIA, 0x1571), }, +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/drivers/ata/sata_mv.c linux-2.6.29-rc3.owrt/drivers/ata/sata_mv.c +--- linux-2.6.29.owrt/drivers/ata/sata_mv.c 2009-05-10 22:04:38.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/drivers/ata/sata_mv.c 2009-05-10 23:48:28.000000000 +0200 +@@ -663,8 +663,8 @@ + { PCI_VDEVICE(MARVELL, 0x5081), chip_508x }, + /* RocketRAID 1720/174x have different identifiers */ + { PCI_VDEVICE(TTI, 0x1720), chip_6042 }, +- { PCI_VDEVICE(TTI, 0x1740), chip_6042 }, +- { PCI_VDEVICE(TTI, 0x1742), chip_6042 }, ++ { PCI_VDEVICE(TTI, 0x1740), chip_508x }, ++ { PCI_VDEVICE(TTI, 0x1742), chip_508x }, + + { PCI_VDEVICE(MARVELL, 0x6040), chip_604x }, + { PCI_VDEVICE(MARVELL, 0x6041), chip_604x }, +@@ -2218,13 +2218,12 @@ + else + handled = mv_host_intr(host, pending_irqs); + } ++ spin_unlock(&host->lock); + + /* for MSI: unmask; interrupt cause bits will retrigger now */ + if (using_msi) + writel(hpriv->main_irq_mask, hpriv->main_irq_mask_addr); + +- spin_unlock(&host->lock); +- + return IRQ_RETVAL(handled); + } + +@@ -3115,17 +3114,19 @@ + writelfl(0, hc_mmio + HC_IRQ_CAUSE_OFS); + } + +- /* Clear any currently outstanding host interrupt conditions */ +- writelfl(0, mmio + hpriv->irq_cause_ofs); ++ if (!IS_SOC(hpriv)) { ++ /* Clear any currently outstanding host interrupt conditions */ ++ writelfl(0, mmio + hpriv->irq_cause_ofs); + +- /* and unmask interrupt generation for host regs */ +- writelfl(hpriv->unmask_all_irqs, mmio + hpriv->irq_mask_ofs); ++ /* and unmask interrupt generation for host regs */ ++ writelfl(hpriv->unmask_all_irqs, mmio + hpriv->irq_mask_ofs); + +- /* +- * enable only global host interrupts for now. +- * The per-port interrupts get done later as ports are set up. +- */ +- mv_set_main_irq_mask(host, 0, PCI_ERR); ++ /* ++ * enable only global host interrupts for now. ++ * The per-port interrupts get done later as ports are set up. ++ */ ++ mv_set_main_irq_mask(host, 0, PCI_ERR); ++ } + done: + return rc; + } +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/drivers/ata/sata_nv.c linux-2.6.29-rc3.owrt/drivers/ata/sata_nv.c +--- linux-2.6.29.owrt/drivers/ata/sata_nv.c 2009-05-10 22:04:38.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/drivers/ata/sata_nv.c 2009-05-10 23:48:28.000000000 +0200 +@@ -421,33 +421,26 @@ + .hardreset = ATA_OP_NULL, + }; + +-/* nf2 is ripe with hardreset related problems. +- * +- * kernel bz#3352 reports nf2/3 controllers can't determine device +- * signature reliably. The following thread reports detection failure +- * on cold boot with the standard debouncing timing. ++/* OSDL bz3352 reports that nf2/3 controllers can't determine device ++ * signature reliably. Also, the following thread reports detection ++ * failure on cold boot with the standard debouncing timing. + * + * http://thread.gmane.org/gmane.linux.ide/34098 + * +- * And bz#12176 reports that hardreset simply doesn't work on nf2. +- * Give up on it and just don't do hardreset. ++ * Debounce with hotplug timing and request follow-up SRST. + */ + static struct ata_port_operations nv_nf2_ops = { +- .inherits = &nv_generic_ops, ++ .inherits = &nv_common_ops, + .freeze = nv_nf2_freeze, + .thaw = nv_nf2_thaw, ++ .hardreset = nv_noclassify_hardreset, + }; + +-/* For initial probing after boot and hot plugging, hardreset mostly +- * works fine on CK804 but curiously, reprobing on the initial port by +- * rescanning or rmmod/insmod fails to acquire the initial D2H Reg FIS +- * in somewhat undeterministic way. Use noclassify hardreset. +- */ ++/* CK804 finally gets hardreset right */ + static struct ata_port_operations nv_ck804_ops = { + .inherits = &nv_common_ops, + .freeze = nv_ck804_freeze, + .thaw = nv_ck804_thaw, +- .hardreset = nv_noclassify_hardreset, + .host_stop = nv_ck804_host_stop, + }; + +@@ -2523,7 +2516,7 @@ + module_init(nv_init); + module_exit(nv_exit); + module_param_named(adma, adma_enabled, bool, 0444); +-MODULE_PARM_DESC(adma, "Enable use of ADMA (Default: false)"); ++MODULE_PARM_DESC(adma, "Enable use of ADMA (Default: true)"); + module_param_named(swncq, swncq_enabled, bool, 0444); + MODULE_PARM_DESC(swncq, "Enable use of SWNCQ (Default: true)"); + +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/drivers/ata/sata_sil.c linux-2.6.29-rc3.owrt/drivers/ata/sata_sil.c +--- linux-2.6.29.owrt/drivers/ata/sata_sil.c 2009-05-10 22:04:38.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/drivers/ata/sata_sil.c 2009-05-10 23:48:28.000000000 +0200 +@@ -44,7 +44,6 @@ + #include <linux/device.h> + #include <scsi/scsi_host.h> + #include <linux/libata.h> +-#include <linux/dmi.h> + + #define DRV_NAME "sata_sil" + #define DRV_VERSION "2.4" +@@ -324,7 +323,7 @@ + + prd->addr = cpu_to_le32(addr); + prd->flags_len = cpu_to_le32(sg_len); +- VPRINTK("PRD[%u] = (0x%X, 0x%X)\n", si, addr, sg_len); ++ VPRINTK("PRD[%u] = (0x%X, 0x%X)\n", pi, addr, sg_len); + + last_prd = prd; + prd++; +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/drivers/atm/fore200e.c linux-2.6.29-rc3.owrt/drivers/atm/fore200e.c +--- linux-2.6.29.owrt/drivers/atm/fore200e.c 2009-05-10 22:04:38.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/drivers/atm/fore200e.c 2009-05-10 23:48:28.000000000 +0200 +@@ -2519,8 +2519,8 @@ + return err; + + sprintf(buf, "%s%s", fore200e->bus->proc_name, FW_EXT); +- if ((err = request_firmware(&firmware, buf, device)) < 0) { +- printk(FORE200E "problem loading firmware image %s\n", fore200e->bus->model_name); ++ if (request_firmware(&firmware, buf, device) == 1) { ++ printk(FORE200E "missing %s firmware image\n", fore200e->bus->model_name); + return err; + } + +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/drivers/atm/lanai.c linux-2.6.29-rc3.owrt/drivers/atm/lanai.c +--- linux-2.6.29.owrt/drivers/atm/lanai.c 2009-05-10 22:04:38.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/drivers/atm/lanai.c 2009-05-10 23:48:28.000000000 +0200 +@@ -901,7 +901,7 @@ + clock_l(); udelay(5); + for (i = 128; i != 0; i >>= 1) { /* write command out */ + tmp = (lanai->conf1 & ~CONFIG1_PROMDATA) | +- ((data & i) ? CONFIG1_PROMDATA : 0); ++ (data & i) ? CONFIG1_PROMDATA : 0; + if (lanai->conf1 != tmp) { + set_config1(tmp); + udelay(5); /* Let new data settle */ +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/drivers/atm/solos-pci.c linux-2.6.29-rc3.owrt/drivers/atm/solos-pci.c +--- linux-2.6.29.owrt/drivers/atm/solos-pci.c 2009-05-10 22:04:38.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/drivers/atm/solos-pci.c 2009-05-10 23:48:28.000000000 +0200 +@@ -685,7 +685,6 @@ + out_release_regions: + pci_release_regions(dev); + out: +- kfree(card); + return err; + } + +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/drivers/base/base.h linux-2.6.29-rc3.owrt/drivers/base/base.h +--- linux-2.6.29.owrt/drivers/base/base.h 2009-05-10 22:04:39.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/drivers/base/base.h 2009-05-10 23:48:28.000000000 +0200 +@@ -88,6 +88,8 @@ + extern int driver_probe_device(struct device_driver *drv, struct device *dev); + + extern void sysdev_shutdown(void); ++extern int sysdev_suspend(pm_message_t state); ++extern int sysdev_resume(void); + + extern char *make_class_name(const char *name, struct kobject *kobj); + +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/drivers/base/core.c linux-2.6.29-rc3.owrt/drivers/base/core.c +--- linux-2.6.29.owrt/drivers/base/core.c 2009-05-10 22:04:39.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/drivers/base/core.c 2009-05-10 23:48:28.000000000 +0200 +@@ -1280,7 +1280,7 @@ + + /** + * root_device_unregister - unregister and free a root device +- * @dev: device going away ++ * @root: device going away. + * + * This function unregisters and cleans up a device that was created by + * root_device_register(). +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/drivers/base/dd.c linux-2.6.29-rc3.owrt/drivers/base/dd.c +--- linux-2.6.29.owrt/drivers/base/dd.c 2009-05-10 22:04:39.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/drivers/base/dd.c 2009-05-10 23:48:28.000000000 +0200 +@@ -18,11 +18,9 @@ + */ + + #include <linux/device.h> +-#include <linux/delay.h> + #include <linux/module.h> + #include <linux/kthread.h> + #include <linux/wait.h> +-#include <linux/async.h> + + #include "base.h" + #include "power/power.h" +@@ -170,21 +168,6 @@ + } + + /** +- * wait_for_device_probe +- * Wait for device probing to be completed. +- * +- * Note: this function polls at 100 msec intervals. +- */ +-int wait_for_device_probe(void) +-{ +- /* wait for the known devices to complete their probing */ +- while (driver_probe_done() != 0) +- msleep(100); +- async_synchronize_full(); +- return 0; +-} +- +-/** + * driver_probe_device - attempt to bind device & driver together + * @drv: driver to bind a device to + * @dev: device to try to bind to the driver +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/drivers/base/node.c linux-2.6.29-rc3.owrt/drivers/base/node.c +--- linux-2.6.29.owrt/drivers/base/node.c 2009-05-10 22:04:39.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/drivers/base/node.c 2009-05-10 23:48:28.000000000 +0200 +@@ -303,7 +303,7 @@ + sect_start_pfn = section_nr_to_pfn(mem_blk->phys_index); + sect_end_pfn = sect_start_pfn + PAGES_PER_SECTION - 1; + for (pfn = sect_start_pfn; pfn <= sect_end_pfn; pfn++) { +- int nid; ++ unsigned int nid; + + nid = get_nid_for_pfn(pfn); + if (nid < 0) +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/drivers/base/power/main.c linux-2.6.29-rc3.owrt/drivers/base/power/main.c +--- linux-2.6.29.owrt/drivers/base/power/main.c 2009-05-10 22:04:39.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/drivers/base/power/main.c 2009-05-10 23:48:28.000000000 +0200 +@@ -333,6 +333,7 @@ + */ + void device_power_up(pm_message_t state) + { ++ sysdev_resume(); + dpm_power_up(state); + } + EXPORT_SYMBOL_GPL(device_power_up); +@@ -576,6 +577,8 @@ + } + dev->power.status = DPM_OFF_IRQ; + } ++ if (!error) ++ error = sysdev_suspend(state); + if (error) + dpm_power_up(resume_event(state)); + return error; +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/drivers/base/sys.c linux-2.6.29-rc3.owrt/drivers/base/sys.c +--- linux-2.6.29.owrt/drivers/base/sys.c 2009-05-10 22:04:39.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/drivers/base/sys.c 2009-05-10 23:48:28.000000000 +0200 +@@ -303,6 +303,7 @@ + * is guaranteed by virtue of the fact that child devices are registered + * after their parents. + */ ++ + void sysdev_shutdown(void) + { + struct sysdev_class * cls; +@@ -362,6 +363,7 @@ + * This is only called by the device PM core, so we let them handle + * all synchronization. + */ ++ + int sysdev_suspend(pm_message_t state) + { + struct sysdev_class * cls; +@@ -430,7 +432,7 @@ + } + return ret; + } +-EXPORT_SYMBOL_GPL(sysdev_suspend); ++ + + /** + * sysdev_resume - Bring system devices back to life. +@@ -440,6 +442,7 @@ + * + * Note: Interrupts are disabled when called. + */ ++ + int sysdev_resume(void) + { + struct sysdev_class * cls; +@@ -460,7 +463,7 @@ + } + return 0; + } +-EXPORT_SYMBOL_GPL(sysdev_resume); ++ + + int __init system_bus_init(void) + { +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/drivers/block/aoe/aoedev.c linux-2.6.29-rc3.owrt/drivers/block/aoe/aoedev.c +--- linux-2.6.29.owrt/drivers/block/aoe/aoedev.c 2009-05-10 22:04:38.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/drivers/block/aoe/aoedev.c 2009-05-10 23:48:28.000000000 +0200 +@@ -173,7 +173,7 @@ + return; + while (atomic_read(&skb_shinfo(skb)->dataref) != 1 && i-- > 0) + msleep(Sms); +- if (i < 0) { ++ if (i <= 0) { + printk(KERN_ERR + "aoe: %s holds ref: %s\n", + skb->dev ? skb->dev->name : "netif", +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/drivers/block/aoe/aoe.h linux-2.6.29-rc3.owrt/drivers/block/aoe/aoe.h +--- linux-2.6.29.owrt/drivers/block/aoe/aoe.h 2009-05-10 22:04:38.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/drivers/block/aoe/aoe.h 2009-05-10 23:48:28.000000000 +0200 +@@ -18,7 +18,6 @@ + enum { + AOECMD_ATA, + AOECMD_CFG, +- AOECMD_VEND_MIN = 0xf0, + + AOEFL_RSP = (1<<3), + AOEFL_ERR = (1<<2), +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/drivers/block/aoe/aoenet.c linux-2.6.29-rc3.owrt/drivers/block/aoe/aoenet.c +--- linux-2.6.29.owrt/drivers/block/aoe/aoenet.c 2009-05-10 22:04:38.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/drivers/block/aoe/aoenet.c 2009-05-10 23:48:28.000000000 +0200 +@@ -142,8 +142,6 @@ + aoecmd_cfg_rsp(skb); + break; + default: +- if (h->cmd >= AOECMD_VEND_MIN) +- break; /* don't complain about vendor commands */ + printk(KERN_INFO "aoe: unknown cmd %d\n", h->cmd); + } + exit: +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/drivers/block/ataflop.c linux-2.6.29-rc3.owrt/drivers/block/ataflop.c +--- linux-2.6.29.owrt/drivers/block/ataflop.c 2009-05-10 22:04:38.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/drivers/block/ataflop.c 2009-05-10 23:48:28.000000000 +0200 +@@ -1730,7 +1730,7 @@ + + timeout = jiffies + 2*HZ+HZ/2; + while (time_before(jiffies, timeout)) +- if (!(st_mfp.par_dt_reg & 0x20)) ++ if (!(mfp.par_dt_reg & 0x20)) + break; + + status = FDC_READ( FDCREG_STATUS ); +@@ -1747,7 +1747,7 @@ + /* dummy seek command to make WP bit accessible */ + FDC_WRITE( FDCREG_DATA, 0 ); + FDC_WRITE( FDCREG_CMD, FDCCMD_SEEK ); +- while( st_mfp.par_dt_reg & 0x20 ) ++ while( mfp.par_dt_reg & 0x20 ) + ; + status = FDC_READ( FDCREG_STATUS ); + } +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/drivers/block/cciss.c linux-2.6.29-rc3.owrt/drivers/block/cciss.c +--- linux-2.6.29.owrt/drivers/block/cciss.c 2009-05-10 22:04:38.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/drivers/block/cciss.c 2009-05-10 23:48:28.000000000 +0200 +@@ -3390,203 +3390,6 @@ + kfree(p); + } + +-/* Send a message CDB to the firmware. */ +-static __devinit int cciss_message(struct pci_dev *pdev, unsigned char opcode, unsigned char type) +-{ +- typedef struct { +- CommandListHeader_struct CommandHeader; +- RequestBlock_struct Request; +- ErrDescriptor_struct ErrorDescriptor; +- } Command; +- static const size_t cmd_sz = sizeof(Command) + sizeof(ErrorInfo_struct); +- Command *cmd; +- dma_addr_t paddr64; +- uint32_t paddr32, tag; +- void __iomem *vaddr; +- int i, err; +- +- vaddr = ioremap_nocache(pci_resource_start(pdev, 0), pci_resource_len(pdev, 0)); +- if (vaddr == NULL) +- return -ENOMEM; +- +- /* The Inbound Post Queue only accepts 32-bit physical addresses for the +- CCISS commands, so they must be allocated from the lower 4GiB of +- memory. */ +- err = pci_set_consistent_dma_mask(pdev, DMA_32BIT_MASK); +- if (err) { +- iounmap(vaddr); +- return -ENOMEM; +- } +- +- cmd = pci_alloc_consistent(pdev, cmd_sz, &paddr64); +- if (cmd == NULL) { +- iounmap(vaddr); +- return -ENOMEM; +- } +- +- /* This must fit, because of the 32-bit consistent DMA mask. Also, +- although there's no guarantee, we assume that the address is at +- least 4-byte aligned (most likely, it's page-aligned). */ +- paddr32 = paddr64; +- +- cmd->CommandHeader.ReplyQueue = 0; +- cmd->CommandHeader.SGList = 0; +- cmd->CommandHeader.SGTotal = 0; +- cmd->CommandHeader.Tag.lower = paddr32; +- cmd->CommandHeader.Tag.upper = 0; +- memset(&cmd->CommandHeader.LUN.LunAddrBytes, 0, 8); +- +- cmd->Request.CDBLen = 16; +- cmd->Request.Type.Type = TYPE_MSG; +- cmd->Request.Type.Attribute = ATTR_HEADOFQUEUE; +- cmd->Request.Type.Direction = XFER_NONE; +- cmd->Request.Timeout = 0; /* Don't time out */ +- cmd->Request.CDB[0] = opcode; +- cmd->Request.CDB[1] = type; +- memset(&cmd->Request.CDB[2], 0, 14); /* the rest of the CDB is reserved */ +- +- cmd->ErrorDescriptor.Addr.lower = paddr32 + sizeof(Command); +- cmd->ErrorDescriptor.Addr.upper = 0; +- cmd->ErrorDescriptor.Len = sizeof(ErrorInfo_struct); +- +- writel(paddr32, vaddr + SA5_REQUEST_PORT_OFFSET); +- +- for (i = 0; i < 10; i++) { +- tag = readl(vaddr + SA5_REPLY_PORT_OFFSET); +- if ((tag & ~3) == paddr32) +- break; +- schedule_timeout_uninterruptible(HZ); +- } +- +- iounmap(vaddr); +- +- /* we leak the DMA buffer here ... no choice since the controller could +- still complete the command. */ +- if (i == 10) { +- printk(KERN_ERR "cciss: controller message %02x:%02x timed out\n", +- opcode, type); +- return -ETIMEDOUT; +- } +- +- pci_free_consistent(pdev, cmd_sz, cmd, paddr64); +- +- if (tag & 2) { +- printk(KERN_ERR "cciss: controller message %02x:%02x failed\n", +- opcode, type); +- return -EIO; +- } +- +- printk(KERN_INFO "cciss: controller message %02x:%02x succeeded\n", +- opcode, type); +- return 0; +-} +- +-#define cciss_soft_reset_controller(p) cciss_message(p, 1, 0) +-#define cciss_noop(p) cciss_message(p, 3, 0) +- +-static __devinit int cciss_reset_msi(struct pci_dev *pdev) +-{ +-/* the #defines are stolen from drivers/pci/msi.h. */ +-#define msi_control_reg(base) (base + PCI_MSI_FLAGS) +-#define PCI_MSIX_FLAGS_ENABLE (1 << 15) +- +- int pos; +- u16 control = 0; +- +- pos = pci_find_capability(pdev, PCI_CAP_ID_MSI); +- if (pos) { +- pci_read_config_word(pdev, msi_control_reg(pos), &control); +- if (control & PCI_MSI_FLAGS_ENABLE) { +- printk(KERN_INFO "cciss: resetting MSI\n"); +- pci_write_config_word(pdev, msi_control_reg(pos), control & ~PCI_MSI_FLAGS_ENABLE); +- } +- } +- +- pos = pci_find_capability(pdev, PCI_CAP_ID_MSIX); +- if (pos) { +- pci_read_config_word(pdev, msi_control_reg(pos), &control); +- if (control & PCI_MSIX_FLAGS_ENABLE) { +- printk(KERN_INFO "cciss: resetting MSI-X\n"); +- pci_write_config_word(pdev, msi_control_reg(pos), control & ~PCI_MSIX_FLAGS_ENABLE); +- } +- } +- +- return 0; +-} +- +-/* This does a hard reset of the controller using PCI power management +- * states. */ +-static __devinit int cciss_hard_reset_controller(struct pci_dev *pdev) +-{ +- u16 pmcsr, saved_config_space[32]; +- int i, pos; +- +- printk(KERN_INFO "cciss: using PCI PM to reset controller\n"); +- +- /* This is very nearly the same thing as +- +- pci_save_state(pci_dev); +- pci_set_power_state(pci_dev, PCI_D3hot); +- pci_set_power_state(pci_dev, PCI_D0); +- pci_restore_state(pci_dev); +- +- but we can't use these nice canned kernel routines on +- kexec, because they also check the MSI/MSI-X state in PCI +- configuration space and do the wrong thing when it is +- set/cleared. Also, the pci_save/restore_state functions +- violate the ordering requirements for restoring the +- configuration space from the CCISS document (see the +- comment below). So we roll our own .... */ +- +- for (i = 0; i < 32; i++) +- pci_read_config_word(pdev, 2*i, &saved_config_space[i]); +- +- pos = pci_find_capability(pdev, PCI_CAP_ID_PM); +- if (pos == 0) { +- printk(KERN_ERR "cciss_reset_controller: PCI PM not supported\n"); +- return -ENODEV; +- } +- +- /* Quoting from the Open CISS Specification: "The Power +- * Management Control/Status Register (CSR) controls the power +- * state of the device. The normal operating state is D0, +- * CSR=00h. The software off state is D3, CSR=03h. To reset +- * the controller, place the interface device in D3 then to +- * D0, this causes a secondary PCI reset which will reset the +- * controller." */ +- +- /* enter the D3hot power management state */ +- pci_read_config_word(pdev, pos + PCI_PM_CTRL, &pmcsr); +- pmcsr &= ~PCI_PM_CTRL_STATE_MASK; +- pmcsr |= PCI_D3hot; +- pci_write_config_word(pdev, pos + PCI_PM_CTRL, pmcsr); +- +- schedule_timeout_uninterruptible(HZ >> 1); +- +- /* enter the D0 power management state */ +- pmcsr &= ~PCI_PM_CTRL_STATE_MASK; +- pmcsr |= PCI_D0; +- pci_write_config_word(pdev, pos + PCI_PM_CTRL, pmcsr); +- +- schedule_timeout_uninterruptible(HZ >> 1); +- +- /* Restore the PCI configuration space. The Open CISS +- * Specification says, "Restore the PCI Configuration +- * Registers, offsets 00h through 60h. It is important to +- * restore the command register, 16-bits at offset 04h, +- * last. Do not restore the configuration status register, +- * 16-bits at offset 06h." Note that the offset is 2*i. */ +- for (i = 0; i < 32; i++) { +- if (i == 2 || i == 3) +- continue; +- pci_write_config_word(pdev, 2*i, saved_config_space[i]); +- } +- wmb(); +- pci_write_config_word(pdev, 4, saved_config_space[2]); +- +- return 0; +-} +- + /* + * This is it. Find all the controllers and register them. I really hate + * stealing all these major device numbers. +@@ -3601,26 +3404,6 @@ + int dac, return_code; + InquiryData_struct *inq_buff = NULL; + +- if (reset_devices) { +- /* Reset the controller with a PCI power-cycle */ +- if (cciss_hard_reset_controller(pdev) || cciss_reset_msi(pdev)) +- return -ENODEV; +- +- /* Now try to get the controller to respond to a no-op. Some +- devices (notably the HP Smart Array 5i Controller) need +- up to 30 seconds to respond. */ +- for (i=0; i<30; i++) { +- if (cciss_noop(pdev) == 0) +- break; +- +- schedule_timeout_uninterruptible(HZ); +- } +- if (i == 30) { +- printk(KERN_ERR "cciss: controller seems dead\n"); +- return -EBUSY; +- } +- } +- + i = alloc_cciss_hba(); + if (i < 0) + return -1; +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/drivers/block/floppy.c linux-2.6.29-rc3.owrt/drivers/block/floppy.c +--- linux-2.6.29.owrt/drivers/block/floppy.c 2009-05-10 22:04:38.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/drivers/block/floppy.c 2009-05-10 23:48:28.000000000 +0200 +@@ -558,8 +558,6 @@ + static void recalibrate_floppy(void); + static void floppy_shutdown(unsigned long); + +-static int floppy_request_regions(int); +-static void floppy_release_regions(int); + static int floppy_grab_irq_and_dma(void); + static void floppy_release_irq_and_dma(void); + +@@ -4276,7 +4274,8 @@ + FDCS->rawcmd = 2; + if (user_reset_fdc(-1, FD_RESET_ALWAYS, 0)) { + /* free ioports reserved by floppy_grab_irq_and_dma() */ +- floppy_release_regions(fdc); ++ release_region(FDCS->address + 2, 4); ++ release_region(FDCS->address + 7, 1); + FDCS->address = -1; + FDCS->version = FDC_NONE; + continue; +@@ -4285,7 +4284,8 @@ + FDCS->version = get_fdc_version(); + if (FDCS->version == FDC_NONE) { + /* free ioports reserved by floppy_grab_irq_and_dma() */ +- floppy_release_regions(fdc); ++ release_region(FDCS->address + 2, 4); ++ release_region(FDCS->address + 7, 1); + FDCS->address = -1; + continue; + } +@@ -4358,47 +4358,6 @@ + + static DEFINE_SPINLOCK(floppy_usage_lock); + +-static const struct io_region { +- int offset; +- int size; +-} io_regions[] = { +- { 2, 1 }, +- /* address + 3 is sometimes reserved by pnp bios for motherboard */ +- { 4, 2 }, +- /* address + 6 is reserved, and may be taken by IDE. +- * Unfortunately, Adaptec doesn't know this :-(, */ +- { 7, 1 }, +-}; +- +-static void floppy_release_allocated_regions(int fdc, const struct io_region *p) +-{ +- while (p != io_regions) { +- p--; +- release_region(FDCS->address + p->offset, p->size); +- } +-} +- +-#define ARRAY_END(X) (&((X)[ARRAY_SIZE(X)])) +- +-static int floppy_request_regions(int fdc) +-{ +- const struct io_region *p; +- +- for (p = io_regions; p < ARRAY_END(io_regions); p++) { +- if (!request_region(FDCS->address + p->offset, p->size, "floppy")) { +- DPRINT("Floppy io-port 0x%04lx in use\n", FDCS->address + p->offset); +- floppy_release_allocated_regions(fdc, p); +- return -EBUSY; +- } +- } +- return 0; +-} +- +-static void floppy_release_regions(int fdc) +-{ +- floppy_release_allocated_regions(fdc, ARRAY_END(io_regions)); +-} +- + static int floppy_grab_irq_and_dma(void) + { + unsigned long flags; +@@ -4440,8 +4399,18 @@ + + for (fdc = 0; fdc < N_FDC; fdc++) { + if (FDCS->address != -1) { +- if (floppy_request_regions(fdc)) +- goto cleanup; ++ if (!request_region(FDCS->address + 2, 4, "floppy")) { ++ DPRINT("Floppy io-port 0x%04lx in use\n", ++ FDCS->address + 2); ++ goto cleanup1; ++ } ++ if (!request_region(FDCS->address + 7, 1, "floppy DIR")) { ++ DPRINT("Floppy io-port 0x%04lx in use\n", ++ FDCS->address + 7); ++ goto cleanup2; ++ } ++ /* address + 6 is reserved, and may be taken by IDE. ++ * Unfortunately, Adaptec doesn't know this :-(, */ + } + } + for (fdc = 0; fdc < N_FDC; fdc++) { +@@ -4463,11 +4432,15 @@ + fdc = 0; + irqdma_allocated = 1; + return 0; +-cleanup: ++cleanup2: ++ release_region(FDCS->address + 2, 4); ++cleanup1: + fd_free_irq(); + fd_free_dma(); +- while (--fdc >= 0) +- floppy_release_regions(fdc); ++ while (--fdc >= 0) { ++ release_region(FDCS->address + 2, 4); ++ release_region(FDCS->address + 7, 1); ++ } + spin_lock_irqsave(&floppy_usage_lock, flags); + usage_count--; + spin_unlock_irqrestore(&floppy_usage_lock, flags); +@@ -4528,8 +4501,10 @@ + #endif + old_fdc = fdc; + for (fdc = 0; fdc < N_FDC; fdc++) +- if (FDCS->address != -1) +- floppy_release_regions(fdc); ++ if (FDCS->address != -1) { ++ release_region(FDCS->address + 2, 4); ++ release_region(FDCS->address + 7, 1); ++ } + fdc = old_fdc; + } + +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/drivers/block/loop.c linux-2.6.29-rc3.owrt/drivers/block/loop.c +--- linux-2.6.29.owrt/drivers/block/loop.c 2009-05-10 22:04:38.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/drivers/block/loop.c 2009-05-10 23:48:28.000000000 +0200 +@@ -392,7 +392,8 @@ + struct loop_device *lo = p->lo; + struct page *page = buf->page; + sector_t IV; +- int size, ret; ++ size_t size; ++ int ret; + + ret = buf->ops->confirm(pipe, buf); + if (unlikely(ret)) +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/drivers/block/Makefile linux-2.6.29-rc3.owrt/drivers/block/Makefile +--- linux-2.6.29.owrt/drivers/block/Makefile 2009-05-10 22:04:38.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/drivers/block/Makefile 2009-05-10 23:48:28.000000000 +0200 +@@ -9,7 +9,6 @@ + obj-$(CONFIG_BLK_DEV_FD) += floppy.o + obj-$(CONFIG_AMIGA_FLOPPY) += amiflop.o + obj-$(CONFIG_PS3_DISK) += ps3disk.o +-obj-$(CONFIG_PS3_VRAM) += ps3vram.o + obj-$(CONFIG_ATARI_FLOPPY) += ataflop.o + obj-$(CONFIG_AMIGA_Z2RAM) += z2ram.o + obj-$(CONFIG_BLK_DEV_RAM) += brd.o +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/drivers/block/nbd.c linux-2.6.29-rc3.owrt/drivers/block/nbd.c +--- linux-2.6.29.owrt/drivers/block/nbd.c 2009-05-10 22:04:38.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/drivers/block/nbd.c 2009-05-10 23:48:28.000000000 +0200 +@@ -549,15 +549,6 @@ + + BUG_ON(lo->magic != LO_MAGIC); + +- if (unlikely(!lo->sock)) { +- printk(KERN_ERR "%s: Attempted send on closed socket\n", +- lo->disk->disk_name); +- req->errors++; +- nbd_end_request(req); +- spin_lock_irq(q->queue_lock); +- continue; +- } +- + spin_lock_irq(&lo->queue_lock); + list_add_tail(&req->queuelist, &lo->waiting_queue); + spin_unlock_irq(&lo->queue_lock); +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/drivers/block/paride/pg.c linux-2.6.29-rc3.owrt/drivers/block/paride/pg.c +--- linux-2.6.29.owrt/drivers/block/paride/pg.c 2009-05-10 22:04:38.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/drivers/block/paride/pg.c 2009-05-10 23:48:28.000000000 +0200 +@@ -422,7 +422,7 @@ + + for (k = 0; k < len; k++) { + char c = *buf++; +- if (c != ' ' && c != l) ++ if (c != ' ' || c != l) + l = *targ++ = c; + } + if (l == ' ') +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/drivers/block/ps3vram.c linux-2.6.29-rc3.owrt/drivers/block/ps3vram.c +--- linux-2.6.29.owrt/drivers/block/ps3vram.c 2009-05-10 22:04:38.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/drivers/block/ps3vram.c 1970-01-01 01:00:00.000000000 +0100 +@@ -1,865 +0,0 @@ +-/* +- * ps3vram - Use extra PS3 video ram as MTD block device. +- * +- * Copyright 2009 Sony Corporation +- * +- * Based on the MTD ps3vram driver, which is +- * Copyright (c) 2007-2008 Jim Paris <jim@jtan.com> +- * Added support RSX DMA Vivien Chappelier <vivien.chappelier@free.fr> +- */ +- +-#include <linux/blkdev.h> +-#include <linux/delay.h> +-#include <linux/proc_fs.h> +-#include <linux/seq_file.h> +- +-#include <asm/firmware.h> +-#include <asm/lv1call.h> +-#include <asm/ps3.h> +- +- +-#define DEVICE_NAME "ps3vram" +- +- +-#define XDR_BUF_SIZE (2 * 1024 * 1024) /* XDR buffer (must be 1MiB aligned) */ +-#define XDR_IOIF 0x0c000000 +- +-#define FIFO_BASE XDR_IOIF +-#define FIFO_SIZE (64 * 1024) +- +-#define DMA_PAGE_SIZE (4 * 1024) +- +-#define CACHE_PAGE_SIZE (256 * 1024) +-#define CACHE_PAGE_COUNT ((XDR_BUF_SIZE - FIFO_SIZE) / CACHE_PAGE_SIZE) +- +-#define CACHE_OFFSET CACHE_PAGE_SIZE +-#define FIFO_OFFSET 0 +- +-#define CTRL_PUT 0x10 +-#define CTRL_GET 0x11 +-#define CTRL_TOP 0x15 +- +-#define UPLOAD_SUBCH 1 +-#define DOWNLOAD_SUBCH 2 +- +-#define NV_MEMORY_TO_MEMORY_FORMAT_OFFSET_IN 0x0000030c +-#define NV_MEMORY_TO_MEMORY_FORMAT_NOTIFY 0x00000104 +- +-#define L1GPU_CONTEXT_ATTRIBUTE_FB_BLIT 0x601 +- +-#define CACHE_PAGE_PRESENT 1 +-#define CACHE_PAGE_DIRTY 2 +- +-struct ps3vram_tag { +- unsigned int address; +- unsigned int flags; +-}; +- +-struct ps3vram_cache { +- unsigned int page_count; +- unsigned int page_size; +- struct ps3vram_tag *tags; +- unsigned int hit; +- unsigned int miss; +-}; +- +-struct ps3vram_priv { +- struct request_queue *queue; +- struct gendisk *gendisk; +- +- u64 size; +- +- u64 memory_handle; +- u64 context_handle; +- u32 *ctrl; +- u32 *reports; +- u8 __iomem *ddr_base; +- u8 *xdr_buf; +- +- u32 *fifo_base; +- u32 *fifo_ptr; +- +- struct ps3vram_cache cache; +- +- /* Used to serialize cache/DMA operations */ +- struct mutex lock; +-}; +- +- +-static int ps3vram_major; +- +- +-static struct block_device_operations ps3vram_fops = { +- .owner = THIS_MODULE, +-}; +- +- +-#define DMA_NOTIFIER_HANDLE_BASE 0x66604200 /* first DMA notifier handle */ +-#define DMA_NOTIFIER_OFFSET_BASE 0x1000 /* first DMA notifier offset */ +-#define DMA_NOTIFIER_SIZE 0x40 +-#define NOTIFIER 7 /* notifier used for completion report */ +- +-static char *size = "256M"; +-module_param(size, charp, 0); +-MODULE_PARM_DESC(size, "memory size"); +- +-static u32 *ps3vram_get_notifier(u32 *reports, int notifier) +-{ +- return (void *)reports + DMA_NOTIFIER_OFFSET_BASE + +- DMA_NOTIFIER_SIZE * notifier; +-} +- +-static void ps3vram_notifier_reset(struct ps3_system_bus_device *dev) +-{ +- struct ps3vram_priv *priv = dev->core.driver_data; +- u32 *notify = ps3vram_get_notifier(priv->reports, NOTIFIER); +- int i; +- +- for (i = 0; i < 4; i++) +- notify[i] = 0xffffffff; +-} +- +-static int ps3vram_notifier_wait(struct ps3_system_bus_device *dev, +- unsigned int timeout_ms) +-{ +- struct ps3vram_priv *priv = dev->core.driver_data; +- u32 *notify = ps3vram_get_notifier(priv->reports, NOTIFIER); +- unsigned long timeout = jiffies + msecs_to_jiffies(timeout_ms); +- +- do { +- if (!notify[3]) +- return 0; +- msleep(1); +- } while (time_before(jiffies, timeout)); +- +- return -ETIMEDOUT; +-} +- +-static void ps3vram_init_ring(struct ps3_system_bus_device *dev) +-{ +- struct ps3vram_priv *priv = dev->core.driver_data; +- +- priv->ctrl[CTRL_PUT] = FIFO_BASE + FIFO_OFFSET; +- priv->ctrl[CTRL_GET] = FIFO_BASE + FIFO_OFFSET; +-} +- +-static int ps3vram_wait_ring(struct ps3_system_bus_device *dev, +- unsigned int timeout_ms) +-{ +- struct ps3vram_priv *priv = dev->core.driver_data; +- unsigned long timeout = jiffies + msecs_to_jiffies(timeout_ms); +- +- do { +- if (priv->ctrl[CTRL_PUT] == priv->ctrl[CTRL_GET]) +- return 0; +- msleep(1); +- } while (time_before(jiffies, timeout)); +- +- dev_warn(&dev->core, "FIFO timeout (%08x/%08x/%08x)\n", +- priv->ctrl[CTRL_PUT], priv->ctrl[CTRL_GET], +- priv->ctrl[CTRL_TOP]); +- +- return -ETIMEDOUT; +-} +- +-static void ps3vram_out_ring(struct ps3vram_priv *priv, u32 data) +-{ +- *(priv->fifo_ptr)++ = data; +-} +- +-static void ps3vram_begin_ring(struct ps3vram_priv *priv, u32 chan, u32 tag, +- u32 size) +-{ +- ps3vram_out_ring(priv, (size << 18) | (chan << 13) | tag); +-} +- +-static void ps3vram_rewind_ring(struct ps3_system_bus_device *dev) +-{ +- struct ps3vram_priv *priv = dev->core.driver_data; +- int status; +- +- ps3vram_out_ring(priv, 0x20000000 | (FIFO_BASE + FIFO_OFFSET)); +- +- priv->ctrl[CTRL_PUT] = FIFO_BASE + FIFO_OFFSET; +- +- /* asking the HV for a blit will kick the FIFO */ +- status = lv1_gpu_context_attribute(priv->context_handle, +- L1GPU_CONTEXT_ATTRIBUTE_FB_BLIT, 0, +- 0, 0, 0); +- if (status) +- dev_err(&dev->core, +- "%s: lv1_gpu_context_attribute failed %d\n", __func__, +- status); +- +- priv->fifo_ptr = priv->fifo_base; +-} +- +-static void ps3vram_fire_ring(struct ps3_system_bus_device *dev) +-{ +- struct ps3vram_priv *priv = dev->core.driver_data; +- int status; +- +- mutex_lock(&ps3_gpu_mutex); +- +- priv->ctrl[CTRL_PUT] = FIFO_BASE + FIFO_OFFSET + +- (priv->fifo_ptr - priv->fifo_base) * sizeof(u32); +- +- /* asking the HV for a blit will kick the FIFO */ +- status = lv1_gpu_context_attribute(priv->context_handle, +- L1GPU_CONTEXT_ATTRIBUTE_FB_BLIT, 0, +- 0, 0, 0); +- if (status) +- dev_err(&dev->core, +- "%s: lv1_gpu_context_attribute failed %d\n", __func__, +- status); +- +- if ((priv->fifo_ptr - priv->fifo_base) * sizeof(u32) > +- FIFO_SIZE - 1024) { +- dev_dbg(&dev->core, "FIFO full, rewinding\n"); +- ps3vram_wait_ring(dev, 200); +- ps3vram_rewind_ring(dev); +- } +- +- mutex_unlock(&ps3_gpu_mutex); +-} +- +-static void ps3vram_bind(struct ps3_system_bus_device *dev) +-{ +- struct ps3vram_priv *priv = dev->core.driver_data; +- +- ps3vram_begin_ring(priv, UPLOAD_SUBCH, 0, 1); +- ps3vram_out_ring(priv, 0x31337303); +- ps3vram_begin_ring(priv, UPLOAD_SUBCH, 0x180, 3); +- ps3vram_out_ring(priv, DMA_NOTIFIER_HANDLE_BASE + NOTIFIER); +- ps3vram_out_ring(priv, 0xfeed0001); /* DMA system RAM instance */ +- ps3vram_out_ring(priv, 0xfeed0000); /* DMA video RAM instance */ +- +- ps3vram_begin_ring(priv, DOWNLOAD_SUBCH, 0, 1); +- ps3vram_out_ring(priv, 0x3137c0de); +- ps3vram_begin_ring(priv, DOWNLOAD_SUBCH, 0x180, 3); +- ps3vram_out_ring(priv, DMA_NOTIFIER_HANDLE_BASE + NOTIFIER); +- ps3vram_out_ring(priv, 0xfeed0000); /* DMA video RAM instance */ +- ps3vram_out_ring(priv, 0xfeed0001); /* DMA system RAM instance */ +- +- ps3vram_fire_ring(dev); +-} +- +-static int ps3vram_upload(struct ps3_system_bus_device *dev, +- unsigned int src_offset, unsigned int dst_offset, +- int len, int count) +-{ +- struct ps3vram_priv *priv = dev->core.driver_data; +- +- ps3vram_begin_ring(priv, UPLOAD_SUBCH, +- NV_MEMORY_TO_MEMORY_FORMAT_OFFSET_IN, 8); +- ps3vram_out_ring(priv, XDR_IOIF + src_offset); +- ps3vram_out_ring(priv, dst_offset); +- ps3vram_out_ring(priv, len); +- ps3vram_out_ring(priv, len); +- ps3vram_out_ring(priv, len); +- ps3vram_out_ring(priv, count); +- ps3vram_out_ring(priv, (1 << 8) | 1); +- ps3vram_out_ring(priv, 0); +- +- ps3vram_notifier_reset(dev); +- ps3vram_begin_ring(priv, UPLOAD_SUBCH, +- NV_MEMORY_TO_MEMORY_FORMAT_NOTIFY, 1); +- ps3vram_out_ring(priv, 0); +- ps3vram_begin_ring(priv, UPLOAD_SUBCH, 0x100, 1); +- ps3vram_out_ring(priv, 0); +- ps3vram_fire_ring(dev); +- if (ps3vram_notifier_wait(dev, 200) < 0) { +- dev_warn(&dev->core, "%s: Notifier timeout\n", __func__); +- return -1; +- } +- +- return 0; +-} +- +-static int ps3vram_download(struct ps3_system_bus_device *dev, +- unsigned int src_offset, unsigned int dst_offset, +- int len, int count) +-{ +- struct ps3vram_priv *priv = dev->core.driver_data; +- +- ps3vram_begin_ring(priv, DOWNLOAD_SUBCH, +- NV_MEMORY_TO_MEMORY_FORMAT_OFFSET_IN, 8); +- ps3vram_out_ring(priv, src_offset); +- ps3vram_out_ring(priv, XDR_IOIF + dst_offset); +- ps3vram_out_ring(priv, len); +- ps3vram_out_ring(priv, len); +- ps3vram_out_ring(priv, len); +- ps3vram_out_ring(priv, count); +- ps3vram_out_ring(priv, (1 << 8) | 1); +- ps3vram_out_ring(priv, 0); +- +- ps3vram_notifier_reset(dev); +- ps3vram_begin_ring(priv, DOWNLOAD_SUBCH, +- NV_MEMORY_TO_MEMORY_FORMAT_NOTIFY, 1); +- ps3vram_out_ring(priv, 0); +- ps3vram_begin_ring(priv, DOWNLOAD_SUBCH, 0x100, 1); +- ps3vram_out_ring(priv, 0); +- ps3vram_fire_ring(dev); +- if (ps3vram_notifier_wait(dev, 200) < 0) { +- dev_warn(&dev->core, "%s: Notifier timeout\n", __func__); +- return -1; +- } +- +- return 0; +-} +- +-static void ps3vram_cache_evict(struct ps3_system_bus_device *dev, int entry) +-{ +- struct ps3vram_priv *priv = dev->core.driver_data; +- struct ps3vram_cache *cache = &priv->cache; +- +- if (!(cache->tags[entry].flags & CACHE_PAGE_DIRTY)) +- return; +- +- dev_dbg(&dev->core, "Flushing %d: 0x%08x\n", entry, +- cache->tags[entry].address); +- if (ps3vram_upload(dev, CACHE_OFFSET + entry * cache->page_size, +- cache->tags[entry].address, DMA_PAGE_SIZE, +- cache->page_size / DMA_PAGE_SIZE) < 0) { +- dev_err(&dev->core, +- "Failed to upload from 0x%x to " "0x%x size 0x%x\n", +- entry * cache->page_size, cache->tags[entry].address, +- cache->page_size); +- } +- cache->tags[entry].flags &= ~CACHE_PAGE_DIRTY; +-} +- +-static void ps3vram_cache_load(struct ps3_system_bus_device *dev, int entry, +- unsigned int address) +-{ +- struct ps3vram_priv *priv = dev->core.driver_data; +- struct ps3vram_cache *cache = &priv->cache; +- +- dev_dbg(&dev->core, "Fetching %d: 0x%08x\n", entry, address); +- if (ps3vram_download(dev, address, +- CACHE_OFFSET + entry * cache->page_size, +- DMA_PAGE_SIZE, +- cache->page_size / DMA_PAGE_SIZE) < 0) { +- dev_err(&dev->core, +- "Failed to download from 0x%x to 0x%x size 0x%x\n", +- address, entry * cache->page_size, cache->page_size); +- } +- +- cache->tags[entry].address = address; +- cache->tags[entry].flags |= CACHE_PAGE_PRESENT; +-} +- +- +-static void ps3vram_cache_flush(struct ps3_system_bus_device *dev) +-{ +- struct ps3vram_priv *priv = dev->core.driver_data; +- struct ps3vram_cache *cache = &priv->cache; +- int i; +- +- dev_dbg(&dev->core, "FLUSH\n"); +- for (i = 0; i < cache->page_count; i++) { +- ps3vram_cache_evict(dev, i); +- cache->tags[i].flags = 0; +- } +-} +- +-static unsigned int ps3vram_cache_match(struct ps3_system_bus_device *dev, +- loff_t address) +-{ +- struct ps3vram_priv *priv = dev->core.driver_data; +- struct ps3vram_cache *cache = &priv->cache; +- unsigned int base; +- unsigned int offset; +- int i; +- static int counter; +- +- offset = (unsigned int) (address & (cache->page_size - 1)); +- base = (unsigned int) (address - offset); +- +- /* fully associative check */ +- for (i = 0; i < cache->page_count; i++) { +- if ((cache->tags[i].flags & CACHE_PAGE_PRESENT) && +- cache->tags[i].address == base) { +- cache->hit++; +- dev_dbg(&dev->core, "Found entry %d: 0x%08x\n", i, +- cache->tags[i].address); +- return i; +- } +- } +- +- /* choose a random entry */ +- i = (jiffies + (counter++)) % cache->page_count; +- dev_dbg(&dev->core, "Using entry %d\n", i); +- +- ps3vram_cache_evict(dev, i); +- ps3vram_cache_load(dev, i, base); +- +- cache->miss++; +- return i; +-} +- +-static int ps3vram_cache_init(struct ps3_system_bus_device *dev) +-{ +- struct ps3vram_priv *priv = dev->core.driver_data; +- +- priv->cache.page_count = CACHE_PAGE_COUNT; +- priv->cache.page_size = CACHE_PAGE_SIZE; +- priv->cache.tags = kzalloc(sizeof(struct ps3vram_tag) * +- CACHE_PAGE_COUNT, GFP_KERNEL); +- if (priv->cache.tags == NULL) { +- dev_err(&dev->core, "Could not allocate cache tags\n"); +- return -ENOMEM; +- } +- +- dev_info(&dev->core, "Created ram cache: %d entries, %d KiB each\n", +- CACHE_PAGE_COUNT, CACHE_PAGE_SIZE / 1024); +- +- return 0; +-} +- +-static void ps3vram_cache_cleanup(struct ps3_system_bus_device *dev) +-{ +- struct ps3vram_priv *priv = dev->core.driver_data; +- +- ps3vram_cache_flush(dev); +- kfree(priv->cache.tags); +-} +- +-static int ps3vram_read(struct ps3_system_bus_device *dev, loff_t from, +- size_t len, size_t *retlen, u_char *buf) +-{ +- struct ps3vram_priv *priv = dev->core.driver_data; +- unsigned int cached, count; +- +- dev_dbg(&dev->core, "%s: from=0x%08x len=0x%zx\n", __func__, +- (unsigned int)from, len); +- +- if (from >= priv->size) +- return -EIO; +- +- if (len > priv->size - from) +- len = priv->size - from; +- +- /* Copy from vram to buf */ +- count = len; +- while (count) { +- unsigned int offset, avail; +- unsigned int entry; +- +- offset = (unsigned int) (from & (priv->cache.page_size - 1)); +- avail = priv->cache.page_size - offset; +- +- mutex_lock(&priv->lock); +- +- entry = ps3vram_cache_match(dev, from); +- cached = CACHE_OFFSET + entry * priv->cache.page_size + offset; +- +- dev_dbg(&dev->core, "%s: from=%08x cached=%08x offset=%08x " +- "avail=%08x count=%08x\n", __func__, +- (unsigned int)from, cached, offset, avail, count); +- +- if (avail > count) +- avail = count; +- memcpy(buf, priv->xdr_buf + cached, avail); +- +- mutex_unlock(&priv->lock); +- +- buf += avail; +- count -= avail; +- from += avail; +- } +- +- *retlen = len; +- return 0; +-} +- +-static int ps3vram_write(struct ps3_system_bus_device *dev, loff_t to, +- size_t len, size_t *retlen, const u_char *buf) +-{ +- struct ps3vram_priv *priv = dev->core.driver_data; +- unsigned int cached, count; +- +- if (to >= priv->size) +- return -EIO; +- +- if (len > priv->size - to) +- len = priv->size - to; +- +- /* Copy from buf to vram */ +- count = len; +- while (count) { +- unsigned int offset, avail; +- unsigned int entry; +- +- offset = (unsigned int) (to & (priv->cache.page_size - 1)); +- avail = priv->cache.page_size - offset; +- +- mutex_lock(&priv->lock); +- +- entry = ps3vram_cache_match(dev, to); +- cached = CACHE_OFFSET + entry * priv->cache.page_size + offset; +- +- dev_dbg(&dev->core, "%s: to=%08x cached=%08x offset=%08x " +- "avail=%08x count=%08x\n", __func__, (unsigned int)to, +- cached, offset, avail, count); +- +- if (avail > count) +- avail = count; +- memcpy(priv->xdr_buf + cached, buf, avail); +- +- priv->cache.tags[entry].flags |= CACHE_PAGE_DIRTY; +- +- mutex_unlock(&priv->lock); +- +- buf += avail; +- count -= avail; +- to += avail; +- } +- +- *retlen = len; +- return 0; +-} +- +-static int ps3vram_proc_show(struct seq_file *m, void *v) +-{ +- struct ps3vram_priv *priv = m->private; +- +- seq_printf(m, "hit:%u\nmiss:%u\n", priv->cache.hit, priv->cache.miss); +- return 0; +-} +- +-static int ps3vram_proc_open(struct inode *inode, struct file *file) +-{ +- return single_open(file, ps3vram_proc_show, PDE(inode)->data); +-} +- +-static const struct file_operations ps3vram_proc_fops = { +- .owner = THIS_MODULE, +- .open = ps3vram_proc_open, +- .read = seq_read, +- .llseek = seq_lseek, +- .release = single_release, +-}; +- +-static void __devinit ps3vram_proc_init(struct ps3_system_bus_device *dev) +-{ +- struct ps3vram_priv *priv = dev->core.driver_data; +- struct proc_dir_entry *pde; +- +- pde = proc_create(DEVICE_NAME, 0444, NULL, &ps3vram_proc_fops); +- if (!pde) { +- dev_warn(&dev->core, "failed to create /proc entry\n"); +- return; +- } +- +- pde->owner = THIS_MODULE; +- pde->data = priv; +-} +- +-static int ps3vram_make_request(struct request_queue *q, struct bio *bio) +-{ +- struct ps3_system_bus_device *dev = q->queuedata; +- int write = bio_data_dir(bio) == WRITE; +- const char *op = write ? "write" : "read"; +- loff_t offset = bio->bi_sector << 9; +- int error = 0; +- struct bio_vec *bvec; +- unsigned int i; +- +- dev_dbg(&dev->core, "%s\n", __func__); +- +- bio_for_each_segment(bvec, bio, i) { +- /* PS3 is ppc64, so we don't handle highmem */ +- char *ptr = page_address(bvec->bv_page) + bvec->bv_offset; +- size_t len = bvec->bv_len, retlen; +- +- dev_dbg(&dev->core, " %s %zu bytes at offset %llu\n", op, +- len, offset); +- if (write) +- error = ps3vram_write(dev, offset, len, &retlen, ptr); +- else +- error = ps3vram_read(dev, offset, len, &retlen, ptr); +- +- if (error) { +- dev_err(&dev->core, "%s failed\n", op); +- goto out; +- } +- +- if (retlen != len) { +- dev_err(&dev->core, "Short %s\n", op); +- goto out; +- } +- +- offset += len; +- } +- +- dev_dbg(&dev->core, "%s completed\n", op); +- +-out: +- bio_endio(bio, error); +- return 0; +-} +- +-static int __devinit ps3vram_probe(struct ps3_system_bus_device *dev) +-{ +- struct ps3vram_priv *priv; +- int error, status; +- struct request_queue *queue; +- struct gendisk *gendisk; +- u64 ddr_lpar, ctrl_lpar, info_lpar, reports_lpar, ddr_size, +- reports_size; +- char *rest; +- +- priv = kzalloc(sizeof(*priv), GFP_KERNEL); +- if (!priv) { +- error = -ENOMEM; +- goto fail; +- } +- +- mutex_init(&priv->lock); +- dev->core.driver_data = priv; +- +- priv = dev->core.driver_data; +- +- /* Allocate XDR buffer (1MiB aligned) */ +- priv->xdr_buf = (void *)__get_free_pages(GFP_KERNEL, +- get_order(XDR_BUF_SIZE)); +- if (priv->xdr_buf == NULL) { +- dev_err(&dev->core, "Could not allocate XDR buffer\n"); +- error = -ENOMEM; +- goto fail_free_priv; +- } +- +- /* Put FIFO at begginning of XDR buffer */ +- priv->fifo_base = (u32 *) (priv->xdr_buf + FIFO_OFFSET); +- priv->fifo_ptr = priv->fifo_base; +- +- /* XXX: Need to open GPU, in case ps3fb or snd_ps3 aren't loaded */ +- if (ps3_open_hv_device(dev)) { +- dev_err(&dev->core, "ps3_open_hv_device failed\n"); +- error = -EAGAIN; +- goto out_close_gpu; +- } +- +- /* Request memory */ +- status = -1; +- ddr_size = ALIGN(memparse(size, &rest), 1024*1024); +- if (!ddr_size) { +- dev_err(&dev->core, "Specified size is too small\n"); +- error = -EINVAL; +- goto out_close_gpu; +- } +- +- while (ddr_size > 0) { +- status = lv1_gpu_memory_allocate(ddr_size, 0, 0, 0, 0, +- &priv->memory_handle, +- &ddr_lpar); +- if (!status) +- break; +- ddr_size -= 1024*1024; +- } +- if (status) { +- dev_err(&dev->core, "lv1_gpu_memory_allocate failed %d\n", +- status); +- error = -ENOMEM; +- goto out_free_xdr_buf; +- } +- +- /* Request context */ +- status = lv1_gpu_context_allocate(priv->memory_handle, 0, +- &priv->context_handle, &ctrl_lpar, +- &info_lpar, &reports_lpar, +- &reports_size); +- if (status) { +- dev_err(&dev->core, "lv1_gpu_context_allocate failed %d\n", +- status); +- error = -ENOMEM; +- goto out_free_memory; +- } +- +- /* Map XDR buffer to RSX */ +- status = lv1_gpu_context_iomap(priv->context_handle, XDR_IOIF, +- ps3_mm_phys_to_lpar(__pa(priv->xdr_buf)), +- XDR_BUF_SIZE, 0); +- if (status) { +- dev_err(&dev->core, "lv1_gpu_context_iomap failed %d\n", +- status); +- error = -ENOMEM; +- goto out_free_context; +- } +- +- priv->ddr_base = ioremap_flags(ddr_lpar, ddr_size, _PAGE_NO_CACHE); +- +- if (!priv->ddr_base) { +- dev_err(&dev->core, "ioremap DDR failed\n"); +- error = -ENOMEM; +- goto out_free_context; +- } +- +- priv->ctrl = ioremap(ctrl_lpar, 64 * 1024); +- if (!priv->ctrl) { +- dev_err(&dev->core, "ioremap CTRL failed\n"); +- error = -ENOMEM; +- goto out_unmap_vram; +- } +- +- priv->reports = ioremap(reports_lpar, reports_size); +- if (!priv->reports) { +- dev_err(&dev->core, "ioremap REPORTS failed\n"); +- error = -ENOMEM; +- goto out_unmap_ctrl; +- } +- +- mutex_lock(&ps3_gpu_mutex); +- ps3vram_init_ring(dev); +- mutex_unlock(&ps3_gpu_mutex); +- +- priv->size = ddr_size; +- +- ps3vram_bind(dev); +- +- mutex_lock(&ps3_gpu_mutex); +- error = ps3vram_wait_ring(dev, 100); +- mutex_unlock(&ps3_gpu_mutex); +- if (error < 0) { +- dev_err(&dev->core, "Failed to initialize channels\n"); +- error = -ETIMEDOUT; +- goto out_unmap_reports; +- } +- +- ps3vram_cache_init(dev); +- ps3vram_proc_init(dev); +- +- queue = blk_alloc_queue(GFP_KERNEL); +- if (!queue) { +- dev_err(&dev->core, "blk_alloc_queue failed\n"); +- error = -ENOMEM; +- goto out_cache_cleanup; +- } +- +- priv->queue = queue; +- queue->queuedata = dev; +- blk_queue_make_request(queue, ps3vram_make_request); +- blk_queue_max_phys_segments(queue, MAX_PHYS_SEGMENTS); +- blk_queue_max_hw_segments(queue, MAX_HW_SEGMENTS); +- blk_queue_max_segment_size(queue, MAX_SEGMENT_SIZE); +- blk_queue_max_sectors(queue, SAFE_MAX_SECTORS); +- +- gendisk = alloc_disk(1); +- if (!gendisk) { +- dev_err(&dev->core, "alloc_disk failed\n"); +- error = -ENOMEM; +- goto fail_cleanup_queue; +- } +- +- priv->gendisk = gendisk; +- gendisk->major = ps3vram_major; +- gendisk->first_minor = 0; +- gendisk->fops = &ps3vram_fops; +- gendisk->queue = queue; +- gendisk->private_data = dev; +- gendisk->driverfs_dev = &dev->core; +- strlcpy(gendisk->disk_name, DEVICE_NAME, sizeof(gendisk->disk_name)); +- set_capacity(gendisk, priv->size >> 9); +- +- dev_info(&dev->core, "%s: Using %lu MiB of GPU memory\n", +- gendisk->disk_name, get_capacity(gendisk) >> 11); +- +- add_disk(gendisk); +- return 0; +- +-fail_cleanup_queue: +- blk_cleanup_queue(queue); +-out_cache_cleanup: +- remove_proc_entry(DEVICE_NAME, NULL); +- ps3vram_cache_cleanup(dev); +-out_unmap_reports: +- iounmap(priv->reports); +-out_unmap_ctrl: +- iounmap(priv->ctrl); +-out_unmap_vram: +- iounmap(priv->ddr_base); +-out_free_context: +- lv1_gpu_context_free(priv->context_handle); +-out_free_memory: +- lv1_gpu_memory_free(priv->memory_handle); +-out_close_gpu: +- ps3_close_hv_device(dev); +-out_free_xdr_buf: +- free_pages((unsigned long) priv->xdr_buf, get_order(XDR_BUF_SIZE)); +-fail_free_priv: +- kfree(priv); +- dev->core.driver_data = NULL; +-fail: +- return error; +-} +- +-static int ps3vram_remove(struct ps3_system_bus_device *dev) +-{ +- struct ps3vram_priv *priv = dev->core.driver_data; +- +- del_gendisk(priv->gendisk); +- put_disk(priv->gendisk); +- blk_cleanup_queue(priv->queue); +- remove_proc_entry(DEVICE_NAME, NULL); +- ps3vram_cache_cleanup(dev); +- iounmap(priv->reports); +- iounmap(priv->ctrl); +- iounmap(priv->ddr_base); +- lv1_gpu_context_free(priv->context_handle); +- lv1_gpu_memory_free(priv->memory_handle); +- ps3_close_hv_device(dev); +- free_pages((unsigned long) priv->xdr_buf, get_order(XDR_BUF_SIZE)); +- kfree(priv); +- dev->core.driver_data = NULL; +- return 0; +-} +- +-static struct ps3_system_bus_driver ps3vram = { +- .match_id = PS3_MATCH_ID_GPU, +- .match_sub_id = PS3_MATCH_SUB_ID_GPU_RAMDISK, +- .core.name = DEVICE_NAME, +- .core.owner = THIS_MODULE, +- .probe = ps3vram_probe, +- .remove = ps3vram_remove, +- .shutdown = ps3vram_remove, +-}; +- +- +-static int __init ps3vram_init(void) +-{ +- int error; +- +- if (!firmware_has_feature(FW_FEATURE_PS3_LV1)) +- return -ENODEV; +- +- error = register_blkdev(0, DEVICE_NAME); +- if (error <= 0) { +- pr_err("%s: register_blkdev failed %d\n", DEVICE_NAME, error); +- return error; +- } +- ps3vram_major = error; +- +- pr_info("%s: registered block device major %d\n", DEVICE_NAME, +- ps3vram_major); +- +- error = ps3_system_bus_driver_register(&ps3vram); +- if (error) +- unregister_blkdev(ps3vram_major, DEVICE_NAME); +- +- return error; +-} +- +-static void __exit ps3vram_exit(void) +-{ +- ps3_system_bus_driver_unregister(&ps3vram); +- unregister_blkdev(ps3vram_major, DEVICE_NAME); +-} +- +-module_init(ps3vram_init); +-module_exit(ps3vram_exit); +- +-MODULE_LICENSE("GPL"); +-MODULE_DESCRIPTION("PS3 Video RAM Storage Driver"); +-MODULE_AUTHOR("Sony Corporation"); +-MODULE_ALIAS(PS3_MODULE_ALIAS_GPU_RAMDISK); +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/drivers/block/xen-blkfront.c linux-2.6.29-rc3.owrt/drivers/block/xen-blkfront.c +--- linux-2.6.29.owrt/drivers/block/xen-blkfront.c 2009-05-10 22:04:38.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/drivers/block/xen-blkfront.c 2009-05-10 23:48:28.000000000 +0200 +@@ -40,7 +40,6 @@ + #include <linux/hdreg.h> + #include <linux/cdrom.h> + #include <linux/module.h> +-#include <linux/scatterlist.h> + + #include <xen/xenbus.h> + #include <xen/grant_table.h> +@@ -83,7 +82,6 @@ + enum blkif_state connected; + int ring_ref; + struct blkif_front_ring ring; +- struct scatterlist sg[BLKIF_MAX_SEGMENTS_PER_REQUEST]; + unsigned int evtchn, irq; + struct request_queue *rq; + struct work_struct work; +@@ -206,11 +204,12 @@ + struct blkfront_info *info = req->rq_disk->private_data; + unsigned long buffer_mfn; + struct blkif_request *ring_req; ++ struct req_iterator iter; ++ struct bio_vec *bvec; + unsigned long id; + unsigned int fsect, lsect; +- int i, ref; ++ int ref; + grant_ref_t gref_head; +- struct scatterlist *sg; + + if (unlikely(info->connected != BLKIF_STATE_CONNECTED)) + return 1; +@@ -239,13 +238,12 @@ + if (blk_barrier_rq(req)) + ring_req->operation = BLKIF_OP_WRITE_BARRIER; + +- ring_req->nr_segments = blk_rq_map_sg(req->q, req, info->sg); +- BUG_ON(ring_req->nr_segments > BLKIF_MAX_SEGMENTS_PER_REQUEST); +- +- for_each_sg(info->sg, sg, ring_req->nr_segments, i) { +- buffer_mfn = pfn_to_mfn(page_to_pfn(sg_page(sg))); +- fsect = sg->offset >> 9; +- lsect = fsect + (sg->length >> 9) - 1; ++ ring_req->nr_segments = 0; ++ rq_for_each_segment(bvec, req, iter) { ++ BUG_ON(ring_req->nr_segments == BLKIF_MAX_SEGMENTS_PER_REQUEST); ++ buffer_mfn = pfn_to_mfn(page_to_pfn(bvec->bv_page)); ++ fsect = bvec->bv_offset >> 9; ++ lsect = fsect + (bvec->bv_len >> 9) - 1; + /* install a grant reference. */ + ref = gnttab_claim_grant_reference(&gref_head); + BUG_ON(ref == -ENOSPC); +@@ -256,12 +254,16 @@ + buffer_mfn, + rq_data_dir(req) ); + +- info->shadow[id].frame[i] = mfn_to_pfn(buffer_mfn); +- ring_req->seg[i] = ++ info->shadow[id].frame[ring_req->nr_segments] = ++ mfn_to_pfn(buffer_mfn); ++ ++ ring_req->seg[ring_req->nr_segments] = + (struct blkif_request_segment) { + .gref = ref, + .first_sect = fsect, + .last_sect = lsect }; ++ ++ ring_req->nr_segments++; + } + + info->ring.req_prod_pvt++; +@@ -620,8 +622,6 @@ + SHARED_RING_INIT(sring); + FRONT_RING_INIT(&info->ring, sring, PAGE_SIZE); + +- sg_init_table(info->sg, BLKIF_MAX_SEGMENTS_PER_REQUEST); +- + err = xenbus_grant_ring(dev, virt_to_mfn(info->ring.sring)); + if (err < 0) { + free_page((unsigned long)sring); +@@ -977,8 +977,6 @@ + break; + + case XenbusStateClosing: +- if (info->gd == NULL) +- xenbus_dev_fatal(dev, -ENODEV, "gd is NULL"); + bd = bdget_disk(info->gd, 0); + if (bd == NULL) + xenbus_dev_fatal(dev, -ENODEV, "bdget failed"); +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/drivers/block/xsysace.c linux-2.6.29-rc3.owrt/drivers/block/xsysace.c +--- linux-2.6.29.owrt/drivers/block/xsysace.c 2009-05-10 22:04:38.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/drivers/block/xsysace.c 2009-05-10 23:48:28.000000000 +0200 +@@ -489,28 +489,6 @@ + ace->fsm_state, ace->id_req_count); + #endif + +- /* Verify that there is actually a CF in the slot. If not, then +- * bail out back to the idle state and wake up all the waiters */ +- status = ace_in32(ace, ACE_STATUS); +- if ((status & ACE_STATUS_CFDETECT) == 0) { +- ace->fsm_state = ACE_FSM_STATE_IDLE; +- ace->media_change = 1; +- set_capacity(ace->gd, 0); +- dev_info(ace->dev, "No CF in slot\n"); +- +- /* Drop all pending requests */ +- while ((req = elv_next_request(ace->queue)) != NULL) +- end_request(req, 0); +- +- /* Drop back to IDLE state and notify waiters */ +- ace->fsm_state = ACE_FSM_STATE_IDLE; +- ace->id_result = -EIO; +- while (ace->id_req_count) { +- complete(&ace->id_completion); +- ace->id_req_count--; +- } +- } +- + switch (ace->fsm_state) { + case ACE_FSM_STATE_IDLE: + /* See if there is anything to do */ +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/drivers/char/agp/amd64-agp.c linux-2.6.29-rc3.owrt/drivers/char/agp/amd64-agp.c +--- linux-2.6.29.owrt/drivers/char/agp/amd64-agp.c 2009-05-10 22:04:38.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/drivers/char/agp/amd64-agp.c 2009-05-10 23:48:28.000000000 +0200 +@@ -271,15 +271,15 @@ + nb_order = (nb_order >> 1) & 7; + pci_read_config_dword(nb, AMD64_GARTAPERTUREBASE, &nb_base); + nb_aper = nb_base << 25; ++ if (agp_aperture_valid(nb_aper, (32*1024*1024)<<nb_order)) { ++ return 0; ++ } + + /* Northbridge seems to contain crap. Try the AGP bridge. */ + + pci_read_config_word(agp, cap+0x14, &apsize); +- if (apsize == 0xffff) { +- if (agp_aperture_valid(nb_aper, (32*1024*1024)<<nb_order)) +- return 0; ++ if (apsize == 0xffff) + return -1; +- } + + apsize &= 0xfff; + /* Some BIOS use weird encodings not in the AGPv3 table. */ +@@ -301,11 +301,6 @@ + order = nb_order; + } + +- if (nb_order >= order) { +- if (agp_aperture_valid(nb_aper, (32*1024*1024)<<nb_order)) +- return 0; +- } +- + dev_info(&agp->dev, "aperture from AGP @ %Lx size %u MB\n", + aper, 32 << order); + if (order < 0 || !agp_aperture_valid(aper, (32*1024*1024)<<order)) +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/drivers/char/agp/intel-agp.c linux-2.6.29-rc3.owrt/drivers/char/agp/intel-agp.c +--- linux-2.6.29.owrt/drivers/char/agp/intel-agp.c 2009-05-10 22:04:38.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/drivers/char/agp/intel-agp.c 2009-05-10 23:48:28.000000000 +0200 +@@ -633,15 +633,13 @@ + break; + } + } +- if (gtt_entries > 0) { ++ if (gtt_entries > 0) + dev_info(&agp_bridge->dev->dev, "detected %dK %s memory\n", + gtt_entries / KB(1), local ? "local" : "stolen"); +- gtt_entries /= KB(4); +- } else { ++ else + dev_info(&agp_bridge->dev->dev, + "no pre-allocated video memory detected\n"); +- gtt_entries = 0; +- } ++ gtt_entries /= KB(4); + + intel_private.gtt_entries = gtt_entries; + } +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/drivers/char/agp/parisc-agp.c linux-2.6.29-rc3.owrt/drivers/char/agp/parisc-agp.c +--- linux-2.6.29.owrt/drivers/char/agp/parisc-agp.c 2009-05-10 22:04:38.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/drivers/char/agp/parisc-agp.c 2009-05-10 23:48:28.000000000 +0200 +@@ -359,16 +359,9 @@ + return error; + } + +-static int +-find_quicksilver(struct device *dev, void *data) +-{ +- struct parisc_device **lba = data; +- struct parisc_device *padev = to_parisc_device(dev); +- +- if (IS_QUICKSILVER(padev)) +- *lba = padev; +- +- return 0; ++static struct device *next_device(struct klist_iter *i) { ++ struct klist_node * n = klist_next(i); ++ return n ? container_of(n, struct device, knode_parent) : NULL; + } + + static int +@@ -379,6 +372,8 @@ + int err = -1; + struct parisc_device *sba = NULL, *lba = NULL; + struct lba_device *lbadev = NULL; ++ struct device *dev = NULL; ++ struct klist_iter i; + + if (!sba_list) + goto out; +@@ -391,7 +386,13 @@ + } + + /* Now search our Pluto for our precious AGP device... */ +- device_for_each_child(&sba->dev, &lba, find_quicksilver); ++ klist_iter_init(&sba->dev.klist_children, &i); ++ while ((dev = next_device(&i))) { ++ struct parisc_device *padev = to_parisc_device(dev); ++ if (IS_QUICKSILVER(padev)) ++ lba = padev; ++ } ++ klist_iter_exit(&i); + + if (!lba) { + printk(KERN_INFO DRVPFX "No AGP devices found.\n"); +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/drivers/char/hvcs.c linux-2.6.29-rc3.owrt/drivers/char/hvcs.c +--- linux-2.6.29.owrt/drivers/char/hvcs.c 2009-05-10 22:04:38.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/drivers/char/hvcs.c 2009-05-10 23:48:28.000000000 +0200 +@@ -1139,6 +1139,15 @@ + hvcsd->tty = tty; + tty->driver_data = hvcsd; + ++ /* ++ * Set this driver to low latency so that we actually have a chance at ++ * catching a throttled TTY after we flip_buffer_push. Otherwise the ++ * flush_to_async may not execute until after the kernel_thread has ++ * yielded and resumed the next flip_buffer_push resulting in data ++ * loss. ++ */ ++ tty->low_latency = 1; ++ + memset(&hvcsd->buffer[0], 0x00, HVCS_BUFF_LEN); + + /* +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/drivers/char/hvsi.c linux-2.6.29-rc3.owrt/drivers/char/hvsi.c +--- linux-2.6.29.owrt/drivers/char/hvsi.c 2009-05-10 22:04:38.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/drivers/char/hvsi.c 2009-05-10 23:48:28.000000000 +0200 +@@ -810,6 +810,7 @@ + hp = &hvsi_ports[line]; + + tty->driver_data = hp; ++ tty->low_latency = 1; /* avoid throttle/tty_flip_buffer_push race */ + + mb(); + if (hp->state == HVSI_FSP_DIED) +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/drivers/char/Kconfig linux-2.6.29-rc3.owrt/drivers/char/Kconfig +--- linux-2.6.29.owrt/drivers/char/Kconfig 2009-05-10 22:04:38.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/drivers/char/Kconfig 2009-05-10 23:48:28.000000000 +0200 +@@ -761,7 +761,7 @@ + + config NVRAM + tristate "/dev/nvram support" +- depends on ATARI || X86 || (ARM && RTC_DRV_CMOS) || GENERIC_NVRAM ++ depends on ATARI || X86 || ARM || GENERIC_NVRAM + ---help--- + If you say Y here and create a character special file /dev/nvram + with major number 10 and minor number 144 using mknod ("man mknod"), +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/drivers/char/scc.h linux-2.6.29-rc3.owrt/drivers/char/scc.h +--- linux-2.6.29.owrt/drivers/char/scc.h 2009-05-10 22:04:38.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/drivers/char/scc.h 2009-05-10 23:48:28.000000000 +0200 +@@ -387,7 +387,7 @@ + /* The SCC needs 3.5 PCLK cycles recovery time between to register + * accesses. PCLK runs with 8 MHz on an Atari, so this delay is 3.5 * + * 125 ns = 437.5 ns. This is too short for udelay(). +- * 10/16/95: A tstb st_mfp.par_dt_reg takes 600ns (sure?) and thus should be ++ * 10/16/95: A tstb mfp.par_dt_reg takes 600ns (sure?) and thus should be + * quite right + */ + +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/drivers/char/selection.c linux-2.6.29-rc3.owrt/drivers/char/selection.c +--- linux-2.6.29.owrt/drivers/char/selection.c 2009-05-10 22:04:38.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/drivers/char/selection.c 2009-05-10 23:48:28.000000000 +0200 +@@ -268,7 +268,7 @@ + + /* Allocate a new buffer before freeing the old one ... */ + multiplier = use_unicode ? 3 : 1; /* chars can take up to 3 bytes */ +- bp = kmalloc(((sel_end-sel_start)/2+1)*multiplier, GFP_KERNEL); ++ bp = kmalloc((sel_end-sel_start)/2*multiplier+1, GFP_KERNEL); + if (!bp) { + printk(KERN_WARNING "selection: kmalloc() failed\n"); + clear_selection(); +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/drivers/char/sx.c linux-2.6.29-rc3.owrt/drivers/char/sx.c +--- linux-2.6.29.owrt/drivers/char/sx.c 2009-05-10 22:04:38.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/drivers/char/sx.c 2009-05-10 23:48:28.000000000 +0200 +@@ -1713,8 +1713,8 @@ + for (i = 0; i < SX_NBOARDS; i++) + sx_dprintk(SX_DEBUG_FIRMWARE, "<%x> ", boards[i].flags); + sx_dprintk(SX_DEBUG_FIRMWARE, "\n"); +- rc = -EIO; +- goto out; ++ unlock_kernel(); ++ return -EIO; + } + + switch (cmd) { +@@ -1746,10 +1746,8 @@ + sx_dprintk(SX_DEBUG_FIRMWARE, "returning type= %ld\n", rc); + break; + case SXIO_DO_RAMTEST: +- if (sx_initialized) { /* Already initialized: better not ramtest the board. */ +- rc = -EPERM; +- break; +- } ++ if (sx_initialized) /* Already initialized: better not ramtest the board. */ ++ return -EPERM; + if (IS_SX_BOARD(board)) { + rc = do_memtest(board, 0, 0x7000); + if (!rc) +@@ -1789,7 +1787,7 @@ + nbytes - i : SX_CHUNK_SIZE)) { + kfree(tmp); + rc = -EFAULT; +- goto out; ++ break; + } + memcpy_toio(board->base2 + offset + i, tmp, + (i + SX_CHUNK_SIZE > nbytes) ? +@@ -1846,7 +1844,6 @@ + rc = -ENOTTY; + break; + } +-out: + unlock_kernel(); + func_exit(); + return rc; +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/drivers/char/tpm/tpm_infineon.c linux-2.6.29-rc3.owrt/drivers/char/tpm/tpm_infineon.c +--- linux-2.6.29.owrt/drivers/char/tpm/tpm_infineon.c 2009-05-10 22:04:38.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/drivers/char/tpm/tpm_infineon.c 2009-05-10 23:48:28.000000000 +0200 +@@ -4,7 +4,7 @@ + * SLD 9630 TT 1.1 and SLB 9635 TT 1.2 Trusted Platform Module + * Specifications at www.trustedcomputinggroup.org + * +- * Copyright (C) 2005, Marcel Selhorst <m.selhorst@sirrix.com> ++ * Copyright (C) 2005, Marcel Selhorst <selhorst@crypto.rub.de> + * Sirrix AG - security technologies, http://www.sirrix.com and + * Applied Data Security Group, Ruhr-University Bochum, Germany + * Project-Homepage: http://www.prosec.rub.de/tpm +@@ -636,7 +636,7 @@ + module_init(init_inf); + module_exit(cleanup_inf); + +-MODULE_AUTHOR("Marcel Selhorst <m.selhorst@sirrix.com>"); ++MODULE_AUTHOR("Marcel Selhorst <selhorst@crypto.rub.de>"); + MODULE_DESCRIPTION("Driver for Infineon TPM SLD 9630 TT 1.1 / SLB 9635 TT 1.2"); + MODULE_VERSION("1.9"); + MODULE_LICENSE("GPL"); +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/drivers/cpufreq/cpufreq.c linux-2.6.29-rc3.owrt/drivers/cpufreq/cpufreq.c +--- linux-2.6.29.owrt/drivers/cpufreq/cpufreq.c 2009-05-10 22:04:38.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/drivers/cpufreq/cpufreq.c 2009-05-10 23:48:28.000000000 +0200 +@@ -754,6 +754,11 @@ + .release = cpufreq_sysfs_release, + }; + ++static struct kobj_type ktype_empty_cpufreq = { ++ .sysfs_ops = &sysfs_ops, ++ .release = cpufreq_sysfs_release, ++}; ++ + + /** + * cpufreq_add_dev - add a CPU device +@@ -887,26 +892,36 @@ + memcpy(&new_policy, policy, sizeof(struct cpufreq_policy)); + + /* prepare interface data */ +- ret = kobject_init_and_add(&policy->kobj, &ktype_cpufreq, &sys_dev->kobj, +- "cpufreq"); +- if (ret) +- goto err_out_driver_exit; +- +- /* set up files for this cpu device */ +- drv_attr = cpufreq_driver->attr; +- while ((drv_attr) && (*drv_attr)) { +- ret = sysfs_create_file(&policy->kobj, &((*drv_attr)->attr)); ++ if (!cpufreq_driver->hide_interface) { ++ ret = kobject_init_and_add(&policy->kobj, &ktype_cpufreq, ++ &sys_dev->kobj, "cpufreq"); + if (ret) + goto err_out_driver_exit; +- drv_attr++; +- } +- if (cpufreq_driver->get) { +- ret = sysfs_create_file(&policy->kobj, &cpuinfo_cur_freq.attr); +- if (ret) +- goto err_out_driver_exit; +- } +- if (cpufreq_driver->target) { +- ret = sysfs_create_file(&policy->kobj, &scaling_cur_freq.attr); ++ ++ /* set up files for this cpu device */ ++ drv_attr = cpufreq_driver->attr; ++ while ((drv_attr) && (*drv_attr)) { ++ ret = sysfs_create_file(&policy->kobj, ++ &((*drv_attr)->attr)); ++ if (ret) ++ goto err_out_driver_exit; ++ drv_attr++; ++ } ++ if (cpufreq_driver->get) { ++ ret = sysfs_create_file(&policy->kobj, ++ &cpuinfo_cur_freq.attr); ++ if (ret) ++ goto err_out_driver_exit; ++ } ++ if (cpufreq_driver->target) { ++ ret = sysfs_create_file(&policy->kobj, ++ &scaling_cur_freq.attr); ++ if (ret) ++ goto err_out_driver_exit; ++ } ++ } else { ++ ret = kobject_init_and_add(&policy->kobj, &ktype_empty_cpufreq, ++ &sys_dev->kobj, "cpufreq"); + if (ret) + goto err_out_driver_exit; + } +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/drivers/cpufreq/cpufreq_ondemand.c linux-2.6.29-rc3.owrt/drivers/cpufreq/cpufreq_ondemand.c +--- linux-2.6.29.owrt/drivers/cpufreq/cpufreq_ondemand.c 2009-05-10 22:04:38.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/drivers/cpufreq/cpufreq_ondemand.c 2009-05-10 23:48:28.000000000 +0200 +@@ -117,7 +117,11 @@ + busy_time = cputime64_add(busy_time, kstat_cpu(cpu).cpustat.irq); + busy_time = cputime64_add(busy_time, kstat_cpu(cpu).cpustat.softirq); + busy_time = cputime64_add(busy_time, kstat_cpu(cpu).cpustat.steal); +- busy_time = cputime64_add(busy_time, kstat_cpu(cpu).cpustat.nice); ++ ++ if (!dbs_tuners_ins.ignore_nice) { ++ busy_time = cputime64_add(busy_time, ++ kstat_cpu(cpu).cpustat.nice); ++ } + + idle_time = cputime64_sub(cur_wall_time, busy_time); + if (wall) +@@ -133,6 +137,23 @@ + if (idle_time == -1ULL) + return get_cpu_idle_time_jiffy(cpu, wall); + ++ if (dbs_tuners_ins.ignore_nice) { ++ cputime64_t cur_nice; ++ unsigned long cur_nice_jiffies; ++ struct cpu_dbs_info_s *dbs_info; ++ ++ dbs_info = &per_cpu(cpu_dbs_info, cpu); ++ cur_nice = cputime64_sub(kstat_cpu(cpu).cpustat.nice, ++ dbs_info->prev_cpu_nice); ++ /* ++ * Assumption: nice time between sampling periods will be ++ * less than 2^32 jiffies for 32 bit sys ++ */ ++ cur_nice_jiffies = (unsigned long) ++ cputime64_to_jiffies64(cur_nice); ++ dbs_info->prev_cpu_nice = kstat_cpu(cpu).cpustat.nice; ++ return idle_time + jiffies_to_usecs(cur_nice_jiffies); ++ } + return idle_time; + } + +@@ -298,9 +319,6 @@ + dbs_info = &per_cpu(cpu_dbs_info, j); + dbs_info->prev_cpu_idle = get_cpu_idle_time(j, + &dbs_info->prev_cpu_wall); +- if (dbs_tuners_ins.ignore_nice) +- dbs_info->prev_cpu_nice = kstat_cpu(j).cpustat.nice; +- + } + mutex_unlock(&dbs_mutex); + +@@ -401,23 +419,6 @@ + j_dbs_info->prev_cpu_idle); + j_dbs_info->prev_cpu_idle = cur_idle_time; + +- if (dbs_tuners_ins.ignore_nice) { +- cputime64_t cur_nice; +- unsigned long cur_nice_jiffies; +- +- cur_nice = cputime64_sub(kstat_cpu(j).cpustat.nice, +- j_dbs_info->prev_cpu_nice); +- /* +- * Assumption: nice time between sampling periods will +- * be less than 2^32 jiffies for 32 bit sys +- */ +- cur_nice_jiffies = (unsigned long) +- cputime64_to_jiffies64(cur_nice); +- +- j_dbs_info->prev_cpu_nice = kstat_cpu(j).cpustat.nice; +- idle_time += jiffies_to_usecs(cur_nice_jiffies); +- } +- + if (unlikely(!wall_time || wall_time < idle_time)) + continue; + +@@ -574,10 +575,6 @@ + + j_dbs_info->prev_cpu_idle = get_cpu_idle_time(j, + &j_dbs_info->prev_cpu_wall); +- if (dbs_tuners_ins.ignore_nice) { +- j_dbs_info->prev_cpu_nice = +- kstat_cpu(j).cpustat.nice; +- } + } + this_dbs_info->cpu = cpu; + /* +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/drivers/crypto/ixp4xx_crypto.c linux-2.6.29-rc3.owrt/drivers/crypto/ixp4xx_crypto.c +--- linux-2.6.29.owrt/drivers/crypto/ixp4xx_crypto.c 2009-05-10 22:04:38.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/drivers/crypto/ixp4xx_crypto.c 2009-05-10 23:48:28.000000000 +0200 +@@ -457,12 +457,10 @@ + if (!ctx_pool) { + goto err; + } +- ret = qmgr_request_queue(SEND_QID, NPE_QLEN_TOTAL, 0, 0, +- "ixp_crypto:out", NULL); ++ ret = qmgr_request_queue(SEND_QID, NPE_QLEN_TOTAL, 0, 0); + if (ret) + goto err; +- ret = qmgr_request_queue(RECV_QID, NPE_QLEN, 0, 0, +- "ixp_crypto:in", NULL); ++ ret = qmgr_request_queue(RECV_QID, NPE_QLEN, 0, 0); + if (ret) { + qmgr_release_queue(SEND_QID); + goto err; +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/drivers/crypto/padlock-aes.c linux-2.6.29-rc3.owrt/drivers/crypto/padlock-aes.c +--- linux-2.6.29.owrt/drivers/crypto/padlock-aes.c 2009-05-10 22:04:38.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/drivers/crypto/padlock-aes.c 2009-05-10 23:48:28.000000000 +0200 +@@ -489,4 +489,4 @@ + MODULE_LICENSE("GPL"); + MODULE_AUTHOR("Michal Ludvig"); + +-MODULE_ALIAS("aes-all"); ++MODULE_ALIAS("aes"); +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/drivers/crypto/padlock-sha.c linux-2.6.29-rc3.owrt/drivers/crypto/padlock-sha.c +--- linux-2.6.29.owrt/drivers/crypto/padlock-sha.c 2009-05-10 22:04:38.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/drivers/crypto/padlock-sha.c 2009-05-10 23:48:28.000000000 +0200 +@@ -304,7 +304,7 @@ + MODULE_LICENSE("GPL"); + MODULE_AUTHOR("Michal Ludvig"); + +-MODULE_ALIAS("sha1-all"); +-MODULE_ALIAS("sha256-all"); ++MODULE_ALIAS("sha1"); ++MODULE_ALIAS("sha256"); + MODULE_ALIAS("sha1-padlock"); + MODULE_ALIAS("sha256-padlock"); +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/drivers/dca/dca-core.c linux-2.6.29-rc3.owrt/drivers/dca/dca-core.c +--- linux-2.6.29.owrt/drivers/dca/dca-core.c 2009-05-10 22:04:38.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/drivers/dca/dca-core.c 2009-05-10 23:48:28.000000000 +0200 +@@ -1,5 +1,5 @@ + /* +- * Copyright(c) 2007 - 2009 Intel Corporation. All rights reserved. ++ * Copyright(c) 2007 Intel Corporation. All rights reserved. + * + * 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 +@@ -28,7 +28,7 @@ + #include <linux/device.h> + #include <linux/dca.h> + +-#define DCA_VERSION "1.8" ++#define DCA_VERSION "1.4" + + MODULE_VERSION(DCA_VERSION); + MODULE_LICENSE("GPL"); +@@ -60,17 +60,16 @@ + { + struct dca_provider *dca; + int err, slot = -ENODEV; +- unsigned long flags; + + if (!dev) + return -EFAULT; + +- spin_lock_irqsave(&dca_lock, flags); ++ spin_lock(&dca_lock); + + /* check if the requester has not been added already */ + dca = dca_find_provider_by_dev(dev); + if (dca) { +- spin_unlock_irqrestore(&dca_lock, flags); ++ spin_unlock(&dca_lock); + return -EEXIST; + } + +@@ -79,21 +78,19 @@ + if (slot >= 0) + break; + } +- +- spin_unlock_irqrestore(&dca_lock, flags); +- +- if (slot < 0) ++ if (slot < 0) { ++ spin_unlock(&dca_lock); + return slot; ++ } + + err = dca_sysfs_add_req(dca, dev, slot); + if (err) { +- spin_lock_irqsave(&dca_lock, flags); +- if (dca == dca_find_provider_by_dev(dev)) +- dca->ops->remove_requester(dca, dev); +- spin_unlock_irqrestore(&dca_lock, flags); ++ dca->ops->remove_requester(dca, dev); ++ spin_unlock(&dca_lock); + return err; + } + ++ spin_unlock(&dca_lock); + return 0; + } + EXPORT_SYMBOL_GPL(dca_add_requester); +@@ -106,25 +103,25 @@ + { + struct dca_provider *dca; + int slot; +- unsigned long flags; + + if (!dev) + return -EFAULT; + +- spin_lock_irqsave(&dca_lock, flags); ++ spin_lock(&dca_lock); + dca = dca_find_provider_by_dev(dev); + if (!dca) { +- spin_unlock_irqrestore(&dca_lock, flags); ++ spin_unlock(&dca_lock); + return -ENODEV; + } + slot = dca->ops->remove_requester(dca, dev); +- spin_unlock_irqrestore(&dca_lock, flags); +- +- if (slot < 0) ++ if (slot < 0) { ++ spin_unlock(&dca_lock); + return slot; ++ } + + dca_sysfs_remove_req(dca, slot); + ++ spin_unlock(&dca_lock); + return 0; + } + EXPORT_SYMBOL_GPL(dca_remove_requester); +@@ -138,18 +135,17 @@ + { + struct dca_provider *dca; + u8 tag; +- unsigned long flags; + +- spin_lock_irqsave(&dca_lock, flags); ++ spin_lock(&dca_lock); + + dca = dca_find_provider_by_dev(dev); + if (!dca) { +- spin_unlock_irqrestore(&dca_lock, flags); ++ spin_unlock(&dca_lock); + return -ENODEV; + } + tag = dca->ops->get_tag(dca, dev, cpu); + +- spin_unlock_irqrestore(&dca_lock, flags); ++ spin_unlock(&dca_lock); + return tag; + } + +@@ -221,16 +217,11 @@ + int register_dca_provider(struct dca_provider *dca, struct device *dev) + { + int err; +- unsigned long flags; + + err = dca_sysfs_add_provider(dca, dev); + if (err) + return err; +- +- spin_lock_irqsave(&dca_lock, flags); + list_add(&dca->node, &dca_providers); +- spin_unlock_irqrestore(&dca_lock, flags); +- + blocking_notifier_call_chain(&dca_provider_chain, + DCA_PROVIDER_ADD, NULL); + return 0; +@@ -243,15 +234,9 @@ + */ + void unregister_dca_provider(struct dca_provider *dca) + { +- unsigned long flags; +- + blocking_notifier_call_chain(&dca_provider_chain, + DCA_PROVIDER_REMOVE, NULL); +- +- spin_lock_irqsave(&dca_lock, flags); + list_del(&dca->node); +- spin_unlock_irqrestore(&dca_lock, flags); +- + dca_sysfs_remove_provider(dca); + } + EXPORT_SYMBOL_GPL(unregister_dca_provider); +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/drivers/dca/dca-sysfs.c linux-2.6.29-rc3.owrt/drivers/dca/dca-sysfs.c +--- linux-2.6.29.owrt/drivers/dca/dca-sysfs.c 2009-05-10 22:04:38.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/drivers/dca/dca-sysfs.c 2009-05-10 23:48:28.000000000 +0200 +@@ -1,24 +1,3 @@ +-/* +- * Copyright(c) 2007 - 2009 Intel Corporation. All rights reserved. +- * +- * 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, MA 02111-1307, USA. +- * +- * The full GNU General Public License is included in this distribution in the +- * file called COPYING. +- */ +- + #include <linux/kernel.h> + #include <linux/spinlock.h> + #include <linux/device.h> +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/drivers/dma/dmaengine.c linux-2.6.29-rc3.owrt/drivers/dma/dmaengine.c +--- linux-2.6.29.owrt/drivers/dma/dmaengine.c 2009-05-10 22:04:38.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/drivers/dma/dmaengine.c 2009-05-10 23:48:28.000000000 +0200 +@@ -518,7 +518,6 @@ + dma_chan_name(chan), err); + else + break; +- chan->private = NULL; + chan = NULL; + } + } +@@ -537,7 +536,6 @@ + WARN_ONCE(chan->client_count != 1, + "chan reference count %d != 1\n", chan->client_count); + dma_chan_put(chan); +- chan->private = NULL; + mutex_unlock(&dma_list_mutex); + } + EXPORT_SYMBOL_GPL(dma_release_channel); +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/drivers/dma/dmatest.c linux-2.6.29-rc3.owrt/drivers/dma/dmatest.c +--- linux-2.6.29.owrt/drivers/dma/dmatest.c 2009-05-10 22:04:38.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/drivers/dma/dmatest.c 2009-05-10 23:48:28.000000000 +0200 +@@ -430,15 +430,13 @@ + static void __exit dmatest_exit(void) + { + struct dmatest_chan *dtc, *_dtc; +- struct dma_chan *chan; + + list_for_each_entry_safe(dtc, _dtc, &dmatest_channels, node) { + list_del(&dtc->node); +- chan = dtc->chan; + dmatest_cleanup_channel(dtc); + pr_debug("dmatest: dropped channel %s\n", +- dma_chan_name(chan)); +- dma_release_channel(chan); ++ dma_chan_name(dtc->chan)); ++ dma_release_channel(dtc->chan); + } + } + module_exit(dmatest_exit); +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/drivers/dma/dw_dmac.c linux-2.6.29-rc3.owrt/drivers/dma/dw_dmac.c +--- linux-2.6.29.owrt/drivers/dma/dw_dmac.c 2009-05-10 22:04:38.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/drivers/dma/dw_dmac.c 2009-05-10 23:48:28.000000000 +0200 +@@ -560,7 +560,7 @@ + unsigned long flags) + { + struct dw_dma_chan *dwc = to_dw_dma_chan(chan); +- struct dw_dma_slave *dws = chan->private; ++ struct dw_dma_slave *dws = dwc->dws; + struct dw_desc *prev; + struct dw_desc *first; + u32 ctllo; +@@ -790,7 +790,7 @@ + cfghi = DWC_CFGH_FIFO_MODE; + cfglo = 0; + +- dws = chan->private; ++ dws = dwc->dws; + if (dws) { + /* + * We need controller-specific data to set up slave +@@ -866,6 +866,7 @@ + spin_lock_bh(&dwc->lock); + list_splice_init(&dwc->free_list, &list); + dwc->descs_allocated = 0; ++ dwc->dws = NULL; + + /* Disable interrupts */ + channel_clear_bit(dw, MASK.XFER, dwc->mask); +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/drivers/dma/dw_dmac_regs.h linux-2.6.29-rc3.owrt/drivers/dma/dw_dmac_regs.h +--- linux-2.6.29.owrt/drivers/dma/dw_dmac_regs.h 2009-05-10 22:04:38.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/drivers/dma/dw_dmac_regs.h 2009-05-10 23:48:28.000000000 +0200 +@@ -139,6 +139,8 @@ + struct list_head queue; + struct list_head free_list; + ++ struct dw_dma_slave *dws; ++ + unsigned int descs_allocated; + }; + +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/drivers/dma/fsldma.c linux-2.6.29-rc3.owrt/drivers/dma/fsldma.c +--- linux-2.6.29.owrt/drivers/dma/fsldma.c 2009-05-10 22:04:38.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/drivers/dma/fsldma.c 2009-05-10 23:48:28.000000000 +0200 +@@ -158,8 +158,7 @@ + + static void dma_halt(struct fsl_dma_chan *fsl_chan) + { +- int i; +- ++ int i = 0; + DMA_OUT(fsl_chan, &fsl_chan->reg_base->mr, + DMA_IN(fsl_chan, &fsl_chan->reg_base->mr, 32) | FSL_DMA_MR_CA, + 32); +@@ -167,11 +166,8 @@ + DMA_IN(fsl_chan, &fsl_chan->reg_base->mr, 32) & ~(FSL_DMA_MR_CS + | FSL_DMA_MR_EMS_EN | FSL_DMA_MR_CA), 32); + +- for (i = 0; i < 100; i++) { +- if (dma_is_idle(fsl_chan)) +- break; ++ while (!dma_is_idle(fsl_chan) && (i++ < 100)) + udelay(10); +- } + if (i >= 100 && !dma_is_idle(fsl_chan)) + dev_err(fsl_chan->dev, "DMA halt timeout!\n"); + } +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/drivers/dma/ioat.c linux-2.6.29-rc3.owrt/drivers/dma/ioat.c +--- linux-2.6.29.owrt/drivers/dma/ioat.c 2009-05-10 22:04:38.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/drivers/dma/ioat.c 2009-05-10 23:48:28.000000000 +0200 +@@ -1,6 +1,6 @@ + /* + * Intel I/OAT DMA Linux driver +- * Copyright(c) 2007 - 2009 Intel Corporation. ++ * Copyright(c) 2007 Intel Corporation. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/drivers/dma/ioat_dca.c linux-2.6.29-rc3.owrt/drivers/dma/ioat_dca.c +--- linux-2.6.29.owrt/drivers/dma/ioat_dca.c 2009-05-10 22:04:38.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/drivers/dma/ioat_dca.c 2009-05-10 23:48:28.000000000 +0200 +@@ -1,6 +1,6 @@ + /* + * Intel I/OAT DMA Linux driver +- * Copyright(c) 2007 - 2009 Intel Corporation. ++ * Copyright(c) 2007 Intel Corporation. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, +@@ -49,23 +49,6 @@ + + #define DCA_TAG_MAP_MASK 0xDF + +-/* expected tag map bytes for I/OAT ver.2 */ +-#define DCA2_TAG_MAP_BYTE0 0x80 +-#define DCA2_TAG_MAP_BYTE1 0x0 +-#define DCA2_TAG_MAP_BYTE2 0x81 +-#define DCA2_TAG_MAP_BYTE3 0x82 +-#define DCA2_TAG_MAP_BYTE4 0x82 +- +-/* verify if tag map matches expected values */ +-static inline int dca2_tag_map_valid(u8 *tag_map) +-{ +- return ((tag_map[0] == DCA2_TAG_MAP_BYTE0) && +- (tag_map[1] == DCA2_TAG_MAP_BYTE1) && +- (tag_map[2] == DCA2_TAG_MAP_BYTE2) && +- (tag_map[3] == DCA2_TAG_MAP_BYTE3) && +- (tag_map[4] == DCA2_TAG_MAP_BYTE4)); +-} +- + /* + * "Legacy" DCA systems do not implement the DCA register set in the + * I/OAT device. Software needs direct support for their tag mappings. +@@ -469,13 +452,6 @@ + ioatdca->tag_map[i] = 0; + } + +- if (!dca2_tag_map_valid(ioatdca->tag_map)) { +- dev_err(&pdev->dev, "APICID_TAG_MAP set incorrectly by BIOS, " +- "disabling DCA\n"); +- free_dca_provider(dca); +- return NULL; +- } +- + err = register_dca_provider(dca, &pdev->dev); + if (err) { + free_dca_provider(dca); +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/drivers/dma/ioat_dma.c linux-2.6.29-rc3.owrt/drivers/dma/ioat_dma.c +--- linux-2.6.29.owrt/drivers/dma/ioat_dma.c 2009-05-10 22:04:38.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/drivers/dma/ioat_dma.c 2009-05-10 23:48:28.000000000 +0200 +@@ -1,6 +1,6 @@ + /* + * Intel I/OAT DMA Linux driver +- * Copyright(c) 2004 - 2009 Intel Corporation. ++ * Copyright(c) 2004 - 2007 Intel Corporation. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, +@@ -189,13 +189,11 @@ + ioat_chan->xfercap = xfercap; + ioat_chan->desccount = 0; + INIT_DELAYED_WORK(&ioat_chan->work, ioat_dma_chan_reset_part2); +- if (ioat_chan->device->version == IOAT_VER_2_0) +- writel(IOAT_DCACTRL_CMPL_WRITE_ENABLE | +- IOAT_DMA_DCA_ANY_CPU, +- ioat_chan->reg_base + IOAT_DCACTRL_OFFSET); +- else if (ioat_chan->device->version == IOAT_VER_3_0) +- writel(IOAT_DMA_DCA_ANY_CPU, +- ioat_chan->reg_base + IOAT_DCACTRL_OFFSET); ++ if (ioat_chan->device->version != IOAT_VER_1_2) { ++ writel(IOAT_DCACTRL_CMPL_WRITE_ENABLE ++ | IOAT_DMA_DCA_ANY_CPU, ++ ioat_chan->reg_base + IOAT_DCACTRL_OFFSET); ++ } + spin_lock_init(&ioat_chan->cleanup_lock); + spin_lock_init(&ioat_chan->desc_lock); + INIT_LIST_HEAD(&ioat_chan->free_desc); +@@ -1171,8 +1169,9 @@ + * up if the client is done with the descriptor + */ + if (async_tx_test_ack(&desc->async_tx)) { +- list_move_tail(&desc->node, +- &ioat_chan->free_desc); ++ list_del(&desc->node); ++ list_add_tail(&desc->node, ++ &ioat_chan->free_desc); + } else + desc->async_tx.cookie = 0; + } else { +@@ -1363,7 +1362,6 @@ + dma_cookie_t cookie; + int err = 0; + struct completion cmp; +- unsigned long tmo; + + src = kzalloc(sizeof(u8) * IOAT_TEST_SIZE, GFP_KERNEL); + if (!src) +@@ -1415,10 +1413,9 @@ + } + device->common.device_issue_pending(dma_chan); + +- tmo = wait_for_completion_timeout(&cmp, msecs_to_jiffies(3000)); ++ wait_for_completion_timeout(&cmp, msecs_to_jiffies(3000)); + +- if (tmo == 0 || +- device->common.device_is_tx_complete(dma_chan, cookie, NULL, NULL) ++ if (device->common.device_is_tx_complete(dma_chan, cookie, NULL, NULL) + != DMA_SUCCESS) { + dev_err(&device->pdev->dev, + "Self-test copy timed out, disabling\n"); +@@ -1660,13 +1657,6 @@ + " %d channels, device version 0x%02x, driver version %s\n", + device->common.chancnt, device->version, IOAT_DMA_VERSION); + +- if (!device->common.chancnt) { +- dev_err(&device->pdev->dev, +- "Intel(R) I/OAT DMA Engine problem found: " +- "zero channels detected\n"); +- goto err_setup_interrupts; +- } +- + err = ioat_dma_setup_interrupts(device); + if (err) + goto err_setup_interrupts; +@@ -1706,9 +1696,6 @@ + struct dma_chan *chan, *_chan; + struct ioat_dma_chan *ioat_chan; + +- if (device->version != IOAT_VER_3_0) +- cancel_delayed_work(&device->work); +- + ioat_dma_remove_interrupts(device); + + dma_async_device_unregister(&device->common); +@@ -1720,6 +1707,10 @@ + pci_release_regions(device->pdev); + pci_disable_device(device->pdev); + ++ if (device->version != IOAT_VER_3_0) { ++ cancel_delayed_work(&device->work); ++ } ++ + list_for_each_entry_safe(chan, _chan, + &device->common.channels, device_node) { + ioat_chan = to_ioat_chan(chan); +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/drivers/dma/ioatdma.h linux-2.6.29-rc3.owrt/drivers/dma/ioatdma.h +--- linux-2.6.29.owrt/drivers/dma/ioatdma.h 2009-05-10 22:04:38.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/drivers/dma/ioatdma.h 2009-05-10 23:48:28.000000000 +0200 +@@ -1,5 +1,5 @@ + /* +- * Copyright(c) 2004 - 2009 Intel Corporation. All rights reserved. ++ * Copyright(c) 2004 - 2007 Intel Corporation. All rights reserved. + * + * 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 +@@ -29,7 +29,7 @@ + #include <linux/pci_ids.h> + #include <net/tcp.h> + +-#define IOAT_DMA_VERSION "3.64" ++#define IOAT_DMA_VERSION "3.30" + + enum ioat_interrupt { + none = 0, +@@ -135,14 +135,12 @@ + #ifdef CONFIG_NET_DMA + switch (dev->version) { + case IOAT_VER_1_2: ++ case IOAT_VER_3_0: + sysctl_tcp_dma_copybreak = 4096; + break; + case IOAT_VER_2_0: + sysctl_tcp_dma_copybreak = 2048; + break; +- case IOAT_VER_3_0: +- sysctl_tcp_dma_copybreak = 262144; +- break; + } + #endif + } +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/drivers/dma/ioatdma_hw.h linux-2.6.29-rc3.owrt/drivers/dma/ioatdma_hw.h +--- linux-2.6.29.owrt/drivers/dma/ioatdma_hw.h 2009-05-10 22:04:38.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/drivers/dma/ioatdma_hw.h 2009-05-10 23:48:28.000000000 +0200 +@@ -1,5 +1,5 @@ + /* +- * Copyright(c) 2004 - 2009 Intel Corporation. All rights reserved. ++ * Copyright(c) 2004 - 2007 Intel Corporation. All rights reserved. + * + * 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 +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/drivers/dma/ioatdma_registers.h linux-2.6.29-rc3.owrt/drivers/dma/ioatdma_registers.h +--- linux-2.6.29.owrt/drivers/dma/ioatdma_registers.h 2009-05-10 22:04:38.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/drivers/dma/ioatdma_registers.h 2009-05-10 23:48:28.000000000 +0200 +@@ -1,5 +1,5 @@ + /* +- * Copyright(c) 2004 - 2009 Intel Corporation. All rights reserved. ++ * Copyright(c) 2004 - 2007 Intel Corporation. All rights reserved. + * + * 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 +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/drivers/dma/iop-adma.c linux-2.6.29-rc3.owrt/drivers/dma/iop-adma.c +--- linux-2.6.29.owrt/drivers/dma/iop-adma.c 2009-05-10 22:04:38.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/drivers/dma/iop-adma.c 2009-05-10 23:48:28.000000000 +0200 +@@ -928,19 +928,19 @@ + + for (src_idx = 0; src_idx < IOP_ADMA_NUM_SRC_TEST; src_idx++) { + xor_srcs[src_idx] = alloc_page(GFP_KERNEL); +- if (!xor_srcs[src_idx]) { +- while (src_idx--) ++ if (!xor_srcs[src_idx]) ++ while (src_idx--) { + __free_page(xor_srcs[src_idx]); +- return -ENOMEM; +- } ++ return -ENOMEM; ++ } + } + + dest = alloc_page(GFP_KERNEL); +- if (!dest) { +- while (src_idx--) ++ if (!dest) ++ while (src_idx--) { + __free_page(xor_srcs[src_idx]); +- return -ENOMEM; +- } ++ return -ENOMEM; ++ } + + /* Fill in src buffers */ + for (src_idx = 0; src_idx < IOP_ADMA_NUM_SRC_TEST; src_idx++) { +@@ -1401,7 +1401,7 @@ + + static struct platform_driver iop_adma_driver = { + .probe = iop_adma_probe, +- .remove = __devexit_p(iop_adma_remove), ++ .remove = iop_adma_remove, + .driver = { + .owner = THIS_MODULE, + .name = "iop-adma", +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/drivers/dma/ipu/ipu_idmac.c linux-2.6.29-rc3.owrt/drivers/dma/ipu/ipu_idmac.c +--- linux-2.6.29.owrt/drivers/dma/ipu/ipu_idmac.c 2009-05-10 22:04:38.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/drivers/dma/ipu/ipu_idmac.c 2009-05-10 23:48:28.000000000 +0200 +@@ -729,7 +729,7 @@ + + ichan->status = IPU_CHANNEL_READY; + +- spin_unlock_irqrestore(&ipu->lock, flags); ++ spin_unlock_irqrestore(ipu->lock, flags); + + return 0; + } +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/drivers/dma/mv_xor.c linux-2.6.29-rc3.owrt/drivers/dma/mv_xor.c +--- linux-2.6.29.owrt/drivers/dma/mv_xor.c 2009-05-10 22:04:38.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/drivers/dma/mv_xor.c 2009-05-10 23:48:28.000000000 +0200 +@@ -1019,19 +1019,19 @@ + + for (src_idx = 0; src_idx < MV_XOR_NUM_SRC_TEST; src_idx++) { + xor_srcs[src_idx] = alloc_page(GFP_KERNEL); +- if (!xor_srcs[src_idx]) { +- while (src_idx--) ++ if (!xor_srcs[src_idx]) ++ while (src_idx--) { + __free_page(xor_srcs[src_idx]); +- return -ENOMEM; +- } ++ return -ENOMEM; ++ } + } + + dest = alloc_page(GFP_KERNEL); +- if (!dest) { +- while (src_idx--) ++ if (!dest) ++ while (src_idx--) { + __free_page(xor_srcs[src_idx]); +- return -ENOMEM; +- } ++ return -ENOMEM; ++ } + + /* Fill in src buffers */ + for (src_idx = 0; src_idx < MV_XOR_NUM_SRC_TEST; src_idx++) { +@@ -1287,7 +1287,7 @@ + + static struct platform_driver mv_xor_driver = { + .probe = mv_xor_probe, +- .remove = __devexit_p(mv_xor_remove), ++ .remove = mv_xor_remove, + .driver = { + .owner = THIS_MODULE, + .name = MV_XOR_NAME, +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/drivers/firewire/fw-card.c linux-2.6.29-rc3.owrt/drivers/firewire/fw-card.c +--- linux-2.6.29.owrt/drivers/firewire/fw-card.c 2009-05-10 22:04:39.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/drivers/firewire/fw-card.c 2009-05-10 23:48:28.000000000 +0200 +@@ -232,7 +232,7 @@ + root_id = root_node->node_id; + grace = time_after(jiffies, card->reset_jiffies + DIV_ROUND_UP(HZ, 10)); + +- if (is_next_generation(generation, card->bm_generation) || ++ if (card->bm_generation + 1 == generation || + (card->bm_generation != generation && grace)) { + /* + * This first step is to figure out who is IRM and +@@ -412,7 +412,6 @@ + { + u32 *config_rom; + size_t length; +- int err; + + card->max_receive = max_receive; + card->link_speed = link_speed; +@@ -423,13 +422,7 @@ + list_add_tail(&card->link, &card_list); + mutex_unlock(&card_mutex); + +- err = card->driver->enable(card, config_rom, length); +- if (err < 0) { +- mutex_lock(&card_mutex); +- list_del(&card->link); +- mutex_unlock(&card_mutex); +- } +- return err; ++ return card->driver->enable(card, config_rom, length); + } + EXPORT_SYMBOL(fw_card_add); + +@@ -519,7 +512,7 @@ + fw_core_initiate_bus_reset(card, 1); + + mutex_lock(&card_mutex); +- list_del_init(&card->link); ++ list_del(&card->link); + mutex_unlock(&card_mutex); + + /* Set up the dummy driver. */ +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/drivers/firewire/fw-device.c linux-2.6.29-rc3.owrt/drivers/firewire/fw-device.c +--- linux-2.6.29.owrt/drivers/firewire/fw-device.c 2009-05-10 22:04:39.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/drivers/firewire/fw-device.c 2009-05-10 23:48:28.000000000 +0200 +@@ -25,7 +25,6 @@ + #include <linux/device.h> + #include <linux/delay.h> + #include <linux/idr.h> +-#include <linux/jiffies.h> + #include <linux/string.h> + #include <linux/rwsem.h> + #include <linux/semaphore.h> +@@ -635,39 +634,12 @@ + return device; + } + +-/* +- * These defines control the retry behavior for reading the config +- * rom. It shouldn't be necessary to tweak these; if the device +- * doesn't respond to a config rom read within 10 seconds, it's not +- * going to respond at all. As for the initial delay, a lot of +- * devices will be able to respond within half a second after bus +- * reset. On the other hand, it's not really worth being more +- * aggressive than that, since it scales pretty well; if 10 devices +- * are plugged in, they're all getting read within one second. +- */ +- +-#define MAX_RETRIES 10 +-#define RETRY_DELAY (3 * HZ) +-#define INITIAL_DELAY (HZ / 2) +-#define SHUTDOWN_DELAY (2 * HZ) +- + static void fw_device_shutdown(struct work_struct *work) + { + struct fw_device *device = + container_of(work, struct fw_device, work.work); + int minor = MINOR(device->device.devt); + +- if (time_is_after_jiffies(device->card->reset_jiffies + SHUTDOWN_DELAY) +- && !list_empty(&device->card->link)) { +- schedule_delayed_work(&device->work, SHUTDOWN_DELAY); +- return; +- } +- +- if (atomic_cmpxchg(&device->state, +- FW_DEVICE_GONE, +- FW_DEVICE_SHUTDOWN) != FW_DEVICE_GONE) +- return; +- + fw_device_cdev_remove(device); + device_for_each_child(&device->device, NULL, shutdown_unit); + device_unregister(&device->device); +@@ -675,7 +647,6 @@ + down_write(&fw_device_rwsem); + idr_remove(&fw_device_idr, minor); + up_write(&fw_device_rwsem); +- + fw_device_put(device); + } + +@@ -683,63 +654,25 @@ + .release = fw_device_release, + }; + +-static void fw_device_update(struct work_struct *work); +- + /* +- * If a device was pending for deletion because its node went away but its +- * bus info block and root directory header matches that of a newly discovered +- * device, revive the existing fw_device. +- * The newly allocated fw_device becomes obsolete instead. ++ * These defines control the retry behavior for reading the config ++ * rom. It shouldn't be necessary to tweak these; if the device ++ * doesn't respond to a config rom read within 10 seconds, it's not ++ * going to respond at all. As for the initial delay, a lot of ++ * devices will be able to respond within half a second after bus ++ * reset. On the other hand, it's not really worth being more ++ * aggressive than that, since it scales pretty well; if 10 devices ++ * are plugged in, they're all getting read within one second. + */ +-static int lookup_existing_device(struct device *dev, void *data) +-{ +- struct fw_device *old = fw_device(dev); +- struct fw_device *new = data; +- struct fw_card *card = new->card; +- int match = 0; +- +- down_read(&fw_device_rwsem); /* serialize config_rom access */ +- spin_lock_irq(&card->lock); /* serialize node access */ +- +- if (memcmp(old->config_rom, new->config_rom, 6 * 4) == 0 && +- atomic_cmpxchg(&old->state, +- FW_DEVICE_GONE, +- FW_DEVICE_RUNNING) == FW_DEVICE_GONE) { +- struct fw_node *current_node = new->node; +- struct fw_node *obsolete_node = old->node; +- +- new->node = obsolete_node; +- new->node->data = new; +- old->node = current_node; +- old->node->data = old; +- +- old->max_speed = new->max_speed; +- old->node_id = current_node->node_id; +- smp_wmb(); /* update node_id before generation */ +- old->generation = card->generation; +- old->config_rom_retries = 0; +- fw_notify("rediscovered device %s\n", dev_name(dev)); +- +- PREPARE_DELAYED_WORK(&old->work, fw_device_update); +- schedule_delayed_work(&old->work, 0); +- +- if (current_node == card->root_node) +- fw_schedule_bm_work(card, 0); +- +- match = 1; +- } + +- spin_unlock_irq(&card->lock); +- up_read(&fw_device_rwsem); +- +- return match; +-} ++#define MAX_RETRIES 10 ++#define RETRY_DELAY (3 * HZ) ++#define INITIAL_DELAY (HZ / 2) + + static void fw_device_init(struct work_struct *work) + { + struct fw_device *device = + container_of(work, struct fw_device, work.work); +- struct device *revived_dev; + int minor, err; + + /* +@@ -763,15 +696,6 @@ + return; + } + +- revived_dev = device_find_child(device->card->device, +- device, lookup_existing_device); +- if (revived_dev) { +- put_device(revived_dev); +- fw_device_release(&device->device); +- +- return; +- } +- + device_initialize(&device->device); + + fw_device_get(device); +@@ -810,10 +734,9 @@ + * fw_node_event(). + */ + if (atomic_cmpxchg(&device->state, +- FW_DEVICE_INITIALIZING, +- FW_DEVICE_RUNNING) == FW_DEVICE_GONE) { +- PREPARE_DELAYED_WORK(&device->work, fw_device_shutdown); +- schedule_delayed_work(&device->work, SHUTDOWN_DELAY); ++ FW_DEVICE_INITIALIZING, ++ FW_DEVICE_RUNNING) == FW_DEVICE_SHUTDOWN) { ++ fw_device_shutdown(work); + } else { + if (device->config_rom_retries) + fw_notify("created device %s: GUID %08x%08x, S%d00, " +@@ -924,8 +847,8 @@ + + case REREAD_BIB_UNCHANGED: + if (atomic_cmpxchg(&device->state, +- FW_DEVICE_INITIALIZING, +- FW_DEVICE_RUNNING) == FW_DEVICE_GONE) ++ FW_DEVICE_INITIALIZING, ++ FW_DEVICE_RUNNING) == FW_DEVICE_SHUTDOWN) + goto gone; + + fw_device_update(work); +@@ -956,8 +879,8 @@ + create_units(device); + + if (atomic_cmpxchg(&device->state, +- FW_DEVICE_INITIALIZING, +- FW_DEVICE_RUNNING) == FW_DEVICE_GONE) ++ FW_DEVICE_INITIALIZING, ++ FW_DEVICE_RUNNING) == FW_DEVICE_SHUTDOWN) + goto gone; + + fw_notify("refreshed device %s\n", dev_name(&device->device)); +@@ -967,9 +890,8 @@ + give_up: + fw_notify("giving up on refresh of device %s\n", dev_name(&device->device)); + gone: +- atomic_set(&device->state, FW_DEVICE_GONE); +- PREPARE_DELAYED_WORK(&device->work, fw_device_shutdown); +- schedule_delayed_work(&device->work, SHUTDOWN_DELAY); ++ atomic_set(&device->state, FW_DEVICE_SHUTDOWN); ++ fw_device_shutdown(work); + out: + if (node_id == card->root_node->node_id) + fw_schedule_bm_work(card, 0); +@@ -1073,10 +995,9 @@ + */ + device = node->data; + if (atomic_xchg(&device->state, +- FW_DEVICE_GONE) == FW_DEVICE_RUNNING) { ++ FW_DEVICE_SHUTDOWN) == FW_DEVICE_RUNNING) { + PREPARE_DELAYED_WORK(&device->work, fw_device_shutdown); +- schedule_delayed_work(&device->work, +- list_empty(&card->link) ? 0 : SHUTDOWN_DELAY); ++ schedule_delayed_work(&device->work, 0); + } + break; + } +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/drivers/firewire/fw-device.h linux-2.6.29-rc3.owrt/drivers/firewire/fw-device.h +--- linux-2.6.29.owrt/drivers/firewire/fw-device.h 2009-05-10 22:04:39.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/drivers/firewire/fw-device.h 2009-05-10 23:48:28.000000000 +0200 +@@ -28,7 +28,6 @@ + enum fw_device_state { + FW_DEVICE_INITIALIZING, + FW_DEVICE_RUNNING, +- FW_DEVICE_GONE, + FW_DEVICE_SHUTDOWN, + }; + +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/drivers/firewire/fw-ohci.c linux-2.6.29-rc3.owrt/drivers/firewire/fw-ohci.c +--- linux-2.6.29.owrt/drivers/firewire/fw-ohci.c 2009-05-10 22:04:39.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/drivers/firewire/fw-ohci.c 2009-05-10 23:48:28.000000000 +0200 +@@ -226,7 +226,7 @@ + #define CONTEXT_DEAD 0x0800 + #define CONTEXT_ACTIVE 0x0400 + +-#define OHCI1394_MAX_AT_REQ_RETRIES 0xf ++#define OHCI1394_MAX_AT_REQ_RETRIES 0x2 + #define OHCI1394_MAX_AT_RESP_RETRIES 0x2 + #define OHCI1394_MAX_PHYS_RESP_RETRIES 0x8 + +@@ -896,11 +896,11 @@ + for (i = 0; i < 10; i++) { + reg = reg_read(ctx->ohci, CONTROL_SET(ctx->regs)); + if ((reg & CONTEXT_ACTIVE) == 0) +- return; ++ break; + ++ fw_notify("context_stop: still active (0x%08x)\n", reg); + mdelay(1); + } +- fw_error("Error: DMA context still active (0x%08x)\n", reg); + } + + struct driver_data { +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/drivers/firewire/fw-sbp2.c linux-2.6.29-rc3.owrt/drivers/firewire/fw-sbp2.c +--- linux-2.6.29.owrt/drivers/firewire/fw-sbp2.c 2009-05-10 22:04:39.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/drivers/firewire/fw-sbp2.c 2009-05-10 23:48:28.000000000 +0200 +@@ -168,7 +168,6 @@ + int address_high; + unsigned int workarounds; + unsigned int mgt_orb_timeout; +- unsigned int max_payload; + + int dont_block; /* counter for each logical unit */ + int blocked; /* ditto */ +@@ -311,16 +310,14 @@ + dma_addr_t page_table_bus; + }; + +-#define SBP2_ROM_VALUE_WILDCARD ~0 /* match all */ +-#define SBP2_ROM_VALUE_MISSING 0xff000000 /* not present in the unit dir. */ +- + /* + * List of devices with known bugs. + * + * The firmware_revision field, masked with 0xffff00, is the best + * indicator for the type of bridge chip of a device. It yields a few + * false positives but this did not break correctly behaving devices +- * so far. ++ * so far. We use ~0 as a wildcard, since the 24 bit values we get ++ * from the config rom can never match that. + */ + static const struct { + u32 firmware_revision; +@@ -342,35 +339,33 @@ + }, + /* Initio bridges, actually only needed for some older ones */ { + .firmware_revision = 0x000200, +- .model = SBP2_ROM_VALUE_WILDCARD, ++ .model = ~0, + .workarounds = SBP2_WORKAROUND_INQUIRY_36, + }, + /* PL-3507 bridge with Prolific firmware */ { + .firmware_revision = 0x012800, +- .model = SBP2_ROM_VALUE_WILDCARD, ++ .model = ~0, + .workarounds = SBP2_WORKAROUND_POWER_CONDITION, + }, + /* Symbios bridge */ { + .firmware_revision = 0xa0b800, +- .model = SBP2_ROM_VALUE_WILDCARD, ++ .model = ~0, + .workarounds = SBP2_WORKAROUND_128K_MAX_TRANS, + }, + /* Datafab MD2-FW2 with Symbios/LSILogic SYM13FW500 bridge */ { + .firmware_revision = 0x002600, +- .model = SBP2_ROM_VALUE_WILDCARD, ++ .model = ~0, + .workarounds = SBP2_WORKAROUND_128K_MAX_TRANS, + }, ++ + /* +- * iPod 2nd generation: needs 128k max transfer size workaround +- * iPod 3rd generation: needs fix capacity workaround ++ * There are iPods (2nd gen, 3rd gen) with model_id == 0, but ++ * these iPods do not feature the read_capacity bug according ++ * to one report. Read_capacity behaviour as well as model_id ++ * could change due to Apple-supplied firmware updates though. + */ +- { +- .firmware_revision = 0x0a2700, +- .model = 0x000000, +- .workarounds = SBP2_WORKAROUND_128K_MAX_TRANS | +- SBP2_WORKAROUND_FIX_CAPACITY, +- }, +- /* iPod 4th generation */ { ++ ++ /* iPod 4th generation. */ { + .firmware_revision = 0x0a2700, + .model = 0x000021, + .workarounds = SBP2_WORKAROUND_FIX_CAPACITY, +@@ -1097,7 +1092,7 @@ + continue; + + if (sbp2_workarounds_table[i].model != model && +- sbp2_workarounds_table[i].model != SBP2_ROM_VALUE_WILDCARD) ++ sbp2_workarounds_table[i].model != ~0) + continue; + + w |= sbp2_workarounds_table[i].workarounds; +@@ -1147,28 +1142,20 @@ + fw_device_get(device); + fw_unit_get(unit); + ++ /* Initialize to values that won't match anything in our table. */ ++ firmware_revision = 0xff000000; ++ model = 0xff000000; ++ + /* implicit directory ID */ + tgt->directory_id = ((unit->directory - device->config_rom) * 4 + + CSR_CONFIG_ROM) & 0xffffff; + +- firmware_revision = SBP2_ROM_VALUE_MISSING; +- model = SBP2_ROM_VALUE_MISSING; +- + if (sbp2_scan_unit_dir(tgt, unit->directory, &model, + &firmware_revision) < 0) + goto fail_tgt_put; + + sbp2_init_workarounds(tgt, model, firmware_revision); + +- /* +- * At S100 we can do 512 bytes per packet, at S200 1024 bytes, +- * and so on up to 4096 bytes. The SBP-2 max_payload field +- * specifies the max payload size as 2 ^ (max_payload + 2), so +- * if we set this to max_speed + 7, we get the right value. +- */ +- tgt->max_payload = min(device->max_speed + 7, 10U); +- tgt->max_payload = min(tgt->max_payload, device->card->max_receive - 1); +- + /* Do the login in a workqueue so we can easily reschedule retries. */ + list_for_each_entry(lu, &tgt->lu_list, link) + sbp2_queue_work(lu, DIV_ROUND_UP(HZ, 5)); +@@ -1286,19 +1273,6 @@ + .id_table = sbp2_id_table, + }; + +-static void sbp2_unmap_scatterlist(struct device *card_device, +- struct sbp2_command_orb *orb) +-{ +- if (scsi_sg_count(orb->cmd)) +- dma_unmap_sg(card_device, scsi_sglist(orb->cmd), +- scsi_sg_count(orb->cmd), +- orb->cmd->sc_data_direction); +- +- if (orb->request.misc & cpu_to_be32(COMMAND_ORB_PAGE_TABLE_PRESENT)) +- dma_unmap_single(card_device, orb->page_table_bus, +- sizeof(orb->page_table), DMA_TO_DEVICE); +-} +- + static unsigned int + sbp2_status_to_sense_data(u8 *sbp2_status, u8 *sense_data) + { +@@ -1378,7 +1352,15 @@ + + dma_unmap_single(device->card->device, orb->base.request_bus, + sizeof(orb->request), DMA_TO_DEVICE); +- sbp2_unmap_scatterlist(device->card->device, orb); ++ ++ if (scsi_sg_count(orb->cmd) > 0) ++ dma_unmap_sg(device->card->device, scsi_sglist(orb->cmd), ++ scsi_sg_count(orb->cmd), ++ orb->cmd->sc_data_direction); ++ ++ if (orb->page_table_bus != 0) ++ dma_unmap_single(device->card->device, orb->page_table_bus, ++ sizeof(orb->page_table), DMA_TO_DEVICE); + + orb->cmd->result = result; + orb->done(orb->cmd); +@@ -1452,6 +1434,7 @@ + struct sbp2_logical_unit *lu = cmd->device->hostdata; + struct fw_device *device = fw_device(lu->tgt->unit->device.parent); + struct sbp2_command_orb *orb; ++ unsigned int max_payload; + int generation, retval = SCSI_MLQUEUE_HOST_BUSY; + + /* +@@ -1479,9 +1462,17 @@ + orb->done = done; + orb->cmd = cmd; + +- orb->request.next.high = cpu_to_be32(SBP2_ORB_NULL); ++ orb->request.next.high = cpu_to_be32(SBP2_ORB_NULL); ++ /* ++ * At speed 100 we can do 512 bytes per packet, at speed 200, ++ * 1024 bytes per packet etc. The SBP-2 max_payload field ++ * specifies the max payload size as 2 ^ (max_payload + 2), so ++ * if we set this to max_speed + 7, we get the right value. ++ */ ++ max_payload = min(device->max_speed + 7, ++ device->card->max_receive - 1); + orb->request.misc = cpu_to_be32( +- COMMAND_ORB_MAX_PAYLOAD(lu->tgt->max_payload) | ++ COMMAND_ORB_MAX_PAYLOAD(max_payload) | + COMMAND_ORB_SPEED(device->max_speed) | + COMMAND_ORB_NOTIFY); + +@@ -1500,10 +1491,8 @@ + orb->base.request_bus = + dma_map_single(device->card->device, &orb->request, + sizeof(orb->request), DMA_TO_DEVICE); +- if (dma_mapping_error(device->card->device, orb->base.request_bus)) { +- sbp2_unmap_scatterlist(device->card->device, orb); ++ if (dma_mapping_error(device->card->device, orb->base.request_bus)) + goto out; +- } + + sbp2_send_orb(&orb->base, lu, lu->tgt->node_id, generation, + lu->command_block_agent_address + SBP2_ORB_POINTER); +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/drivers/firewire/fw-topology.c linux-2.6.29-rc3.owrt/drivers/firewire/fw-topology.c +--- linux-2.6.29.owrt/drivers/firewire/fw-topology.c 2009-05-10 22:04:39.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/drivers/firewire/fw-topology.c 2009-05-10 23:48:28.000000000 +0200 +@@ -518,18 +518,6 @@ + struct fw_node *local_node; + unsigned long flags; + +- /* +- * If the selfID buffer is not the immediate successor of the +- * previously processed one, we cannot reliably compare the +- * old and new topologies. +- */ +- if (!is_next_generation(generation, card->generation) && +- card->local_node != NULL) { +- fw_notify("skipped bus generations, destroying all nodes\n"); +- fw_destroy_nodes(card); +- card->bm_retries = 0; +- } +- + spin_lock_irqsave(&card->lock, flags); + + card->node_id = node_id; +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/drivers/firewire/fw-transaction.h linux-2.6.29-rc3.owrt/drivers/firewire/fw-transaction.h +--- linux-2.6.29.owrt/drivers/firewire/fw-transaction.h 2009-05-10 22:04:39.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/drivers/firewire/fw-transaction.h 2009-05-10 23:48:28.000000000 +0200 +@@ -276,15 +276,6 @@ + extern void fw_schedule_bm_work(struct fw_card *card, unsigned long delay); + + /* +- * Check whether new_generation is the immediate successor of old_generation. +- * Take counter roll-over at 255 (as per to OHCI) into account. +- */ +-static inline bool is_next_generation(int new_generation, int old_generation) +-{ +- return (new_generation & 0xff) == ((old_generation + 1) & 0xff); +-} +- +-/* + * The iso packet format allows for an immediate header/payload part + * stored in 'header' immediately after the packet info plus an + * indirect payload part that is pointer to by the 'payload' field. +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/drivers/firmware/memmap.c linux-2.6.29-rc3.owrt/drivers/firmware/memmap.c +--- linux-2.6.29.owrt/drivers/firmware/memmap.c 2009-05-10 22:04:38.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/drivers/firmware/memmap.c 2009-05-10 23:48:28.000000000 +0200 +@@ -1,7 +1,7 @@ + /* + * linux/drivers/firmware/memmap.c + * Copyright (C) 2008 SUSE LINUX Products GmbH +- * by Bernhard Walle <bernhard.walle@gmx.de> ++ * by Bernhard Walle <bwalle@suse.de> + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License v2.0 as published by +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/drivers/gpio/gpiolib.c linux-2.6.29-rc3.owrt/drivers/gpio/gpiolib.c +--- linux-2.6.29.owrt/drivers/gpio/gpiolib.c 2009-05-10 22:04:39.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/drivers/gpio/gpiolib.c 2009-05-10 23:48:28.000000000 +0200 +@@ -789,7 +789,6 @@ + } else { + status = -EBUSY; + module_put(chip->owner); +- goto done; + } + + if (chip->request) { +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/drivers/gpu/drm/drm_bufs.c linux-2.6.29-rc3.owrt/drivers/gpu/drm/drm_bufs.c +--- linux-2.6.29.owrt/drivers/gpu/drm/drm_bufs.c 2009-05-10 22:04:38.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/drivers/gpu/drm/drm_bufs.c 2009-05-10 23:48:28.000000000 +0200 +@@ -420,7 +420,7 @@ + dev->sigdata.lock = NULL; + master->lock.hw_lock = NULL; /* SHM removed */ + master->lock.file_priv = NULL; +- wake_up_interruptible_all(&master->lock.lock_queue); ++ wake_up_interruptible(&master->lock.lock_queue); + } + break; + case _DRM_AGP: +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/drivers/gpu/drm/drm_crtc.c linux-2.6.29-rc3.owrt/drivers/gpu/drm/drm_crtc.c +--- linux-2.6.29.owrt/drivers/gpu/drm/drm_crtc.c 2009-05-10 22:04:38.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/drivers/gpu/drm/drm_crtc.c 2009-05-10 23:48:28.000000000 +0200 +@@ -1741,8 +1741,9 @@ + * RETURNS: + * Zero on success, errno on failure. + */ +-void drm_fb_release(struct drm_file *priv) ++void drm_fb_release(struct file *filp) + { ++ struct drm_file *priv = filp->private_data; + struct drm_device *dev = priv->minor->dev; + struct drm_framebuffer *fb, *tfb; + +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/drivers/gpu/drm/drm_crtc_helper.c linux-2.6.29-rc3.owrt/drivers/gpu/drm/drm_crtc_helper.c +--- linux-2.6.29.owrt/drivers/gpu/drm/drm_crtc_helper.c 2009-05-10 22:04:38.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/drivers/gpu/drm/drm_crtc_helper.c 2009-05-10 23:48:28.000000000 +0200 +@@ -452,59 +452,6 @@ + kfree(modes); + kfree(enabled); + } +- +-/** +- * drm_encoder_crtc_ok - can a given crtc drive a given encoder? +- * @encoder: encoder to test +- * @crtc: crtc to test +- * +- * Return false if @encoder can't be driven by @crtc, true otherwise. +- */ +-static bool drm_encoder_crtc_ok(struct drm_encoder *encoder, +- struct drm_crtc *crtc) +-{ +- struct drm_device *dev; +- struct drm_crtc *tmp; +- int crtc_mask = 1; +- +- WARN(!crtc, "checking null crtc?"); +- +- dev = crtc->dev; +- +- list_for_each_entry(tmp, &dev->mode_config.crtc_list, head) { +- if (tmp == crtc) +- break; +- crtc_mask <<= 1; +- } +- +- if (encoder->possible_crtcs & crtc_mask) +- return true; +- return false; +-} +- +-/* +- * Check the CRTC we're going to map each output to vs. its current +- * CRTC. If they don't match, we have to disable the output and the CRTC +- * since the driver will have to re-route things. +- */ +-static void +-drm_crtc_prepare_encoders(struct drm_device *dev) +-{ +- struct drm_encoder_helper_funcs *encoder_funcs; +- struct drm_encoder *encoder; +- +- list_for_each_entry(encoder, &dev->mode_config.encoder_list, head) { +- encoder_funcs = encoder->helper_private; +- /* Disable unused encoders */ +- if (encoder->crtc == NULL) +- (*encoder_funcs->dpms)(encoder, DRM_MODE_DPMS_OFF); +- /* Disable encoders whose CRTC is about to change */ +- if (encoder_funcs->get_crtc && +- encoder->crtc != (*encoder_funcs->get_crtc)(encoder)) +- (*encoder_funcs->dpms)(encoder, DRM_MODE_DPMS_OFF); +- } +-} +- + /** + * drm_crtc_set_mode - set a mode + * @crtc: CRTC to program +@@ -565,8 +512,8 @@ + if (drm_mode_equal(&saved_mode, &crtc->mode)) { + if (saved_x != crtc->x || saved_y != crtc->y || + depth_changed || bpp_changed) { +- ret = !crtc_funcs->mode_set_base(crtc, crtc->x, crtc->y, +- old_fb); ++ crtc_funcs->mode_set_base(crtc, crtc->x, crtc->y, ++ old_fb); + goto done; + } + } +@@ -600,16 +547,12 @@ + encoder_funcs->prepare(encoder); + } + +- drm_crtc_prepare_encoders(dev); +- + crtc_funcs->prepare(crtc); + + /* Set up the DPLL and any encoders state that needs to adjust or depend + * on the DPLL. + */ +- ret = !crtc_funcs->mode_set(crtc, mode, adjusted_mode, x, y, old_fb); +- if (!ret) +- goto done; ++ crtc_funcs->mode_set(crtc, mode, adjusted_mode, x, y, old_fb); + + list_for_each_entry(encoder, &dev->mode_config.encoder_list, head) { + +@@ -672,7 +615,7 @@ + struct drm_device *dev; + struct drm_crtc **save_crtcs, *new_crtc; + struct drm_encoder **save_encoders, *new_encoder; +- struct drm_framebuffer *old_fb = NULL; ++ struct drm_framebuffer *old_fb; + bool save_enabled; + bool mode_changed = false; + bool fb_changed = false; +@@ -723,10 +666,9 @@ + * and then just flip_or_move it */ + if (set->crtc->fb != set->fb) { + /* If we have no fb then treat it as a full mode set */ +- if (set->crtc->fb == NULL) { +- DRM_DEBUG("crtc has no fb, full mode set\n"); ++ if (set->crtc->fb == NULL) + mode_changed = true; +- } else if ((set->fb->bits_per_pixel != ++ else if ((set->fb->bits_per_pixel != + set->crtc->fb->bits_per_pixel) || + set->fb->depth != set->crtc->fb->depth) + fb_changed = true; +@@ -738,7 +680,7 @@ + fb_changed = true; + + if (set->mode && !drm_mode_equal(set->mode, &set->crtc->mode)) { +- DRM_DEBUG("modes are different, full mode set\n"); ++ DRM_DEBUG("modes are different\n"); + drm_mode_debug_printmodeline(&set->crtc->mode); + drm_mode_debug_printmodeline(set->mode); + mode_changed = true; +@@ -764,7 +706,6 @@ + } + + if (new_encoder != connector->encoder) { +- DRM_DEBUG("encoder changed, full mode switch\n"); + mode_changed = true; + connector->encoder = new_encoder; + } +@@ -791,20 +732,10 @@ + if (set->connectors[ro] == connector) + new_crtc = set->crtc; + } +- +- /* Make sure the new CRTC will work with the encoder */ +- if (new_crtc && +- !drm_encoder_crtc_ok(connector->encoder, new_crtc)) { +- ret = -EINVAL; +- goto fail_set_mode; +- } + if (new_crtc != connector->encoder->crtc) { +- DRM_DEBUG("crtc changed, full mode switch\n"); + mode_changed = true; + connector->encoder->crtc = new_crtc; + } +- DRM_DEBUG("setting connector %d crtc to %p\n", +- connector->base.id, new_crtc); + } + + /* mode_set_base is not a required function */ +@@ -821,8 +752,6 @@ + if (!drm_crtc_helper_set_mode(set->crtc, set->mode, + set->x, set->y, + old_fb)) { +- DRM_ERROR("failed to set mode on crtc %p\n", +- set->crtc); + ret = -EINVAL; + goto fail_set_mode; + } +@@ -836,10 +765,7 @@ + old_fb = set->crtc->fb; + if (set->crtc->fb != set->fb) + set->crtc->fb = set->fb; +- ret = crtc_funcs->mode_set_base(set->crtc, +- set->x, set->y, old_fb); +- if (ret != 0) +- goto fail_set_mode; ++ crtc_funcs->mode_set_base(set->crtc, set->x, set->y, old_fb); + } + + kfree(save_encoders); +@@ -848,14 +774,9 @@ + + fail_set_mode: + set->crtc->enabled = save_enabled; +- set->crtc->fb = old_fb; + count = 0; +- list_for_each_entry(connector, &dev->mode_config.connector_list, head) { +- if (!connector->encoder) +- continue; +- ++ list_for_each_entry(connector, &dev->mode_config.connector_list, head) + connector->encoder->crtc = save_crtcs[count++]; +- } + fail_no_encoder: + kfree(save_crtcs); + count = 0; +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/drivers/gpu/drm/drm_edid.c linux-2.6.29-rc3.owrt/drivers/gpu/drm/drm_edid.c +--- linux-2.6.29.owrt/drivers/gpu/drm/drm_edid.c 2009-05-10 22:04:38.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/drivers/gpu/drm/drm_edid.c 2009-05-10 23:48:28.000000000 +0200 +@@ -125,7 +125,7 @@ + DRM_ERROR("EDID has major version %d, instead of 1\n", edid->version); + goto bad; + } +- if (edid->revision > 3) { ++ if (edid->revision <= 0 || edid->revision > 3) { + DRM_ERROR("EDID has minor version %d, which is not between 0-3\n", edid->revision); + goto bad; + } +@@ -320,10 +320,10 @@ + mode->htotal = mode->hdisplay + ((pt->hblank_hi << 8) | pt->hblank_lo); + + mode->vdisplay = (pt->vactive_hi << 8) | pt->vactive_lo; +- mode->vsync_start = mode->vdisplay + ((pt->vsync_offset_hi << 4) | ++ mode->vsync_start = mode->vdisplay + ((pt->vsync_offset_hi << 8) | + pt->vsync_offset_lo); + mode->vsync_end = mode->vsync_start + +- ((pt->vsync_pulse_width_hi << 4) | ++ ((pt->vsync_pulse_width_hi << 8) | + pt->vsync_pulse_width_lo); + mode->vtotal = mode->vdisplay + ((pt->vblank_hi << 8) | pt->vblank_lo); + +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/drivers/gpu/drm/drm_fops.c linux-2.6.29-rc3.owrt/drivers/gpu/drm/drm_fops.c +--- linux-2.6.29.owrt/drivers/gpu/drm/drm_fops.c 2009-05-10 22:04:38.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/drivers/gpu/drm/drm_fops.c 2009-05-10 23:48:28.000000000 +0200 +@@ -457,9 +457,6 @@ + if (dev->driver->driver_features & DRIVER_GEM) + drm_gem_release(dev, file_priv); + +- if (dev->driver->driver_features & DRIVER_MODESET) +- drm_fb_release(file_priv); +- + mutex_lock(&dev->ctxlist_mutex); + if (!list_empty(&dev->ctxlist)) { + struct drm_ctx_list *pos, *n; +@@ -484,7 +481,6 @@ + mutex_lock(&dev->struct_mutex); + + if (file_priv->is_master) { +- struct drm_master *master = file_priv->master; + struct drm_file *temp; + list_for_each_entry(temp, &dev->filelist, lhead) { + if ((temp->master == file_priv->master) && +@@ -492,19 +488,6 @@ + temp->authenticated = 0; + } + +- /** +- * Since the master is disappearing, so is the +- * possibility to lock. +- */ +- +- if (master->lock.hw_lock) { +- if (dev->sigdata.lock == master->lock.hw_lock) +- dev->sigdata.lock = NULL; +- master->lock.hw_lock = NULL; +- master->lock.file_priv = NULL; +- wake_up_interruptible_all(&master->lock.lock_queue); +- } +- + if (file_priv->minor->master == file_priv->master) { + /* drop the reference held my the minor */ + drm_master_put(&file_priv->minor->master); +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/drivers/gpu/drm/drm_gem.c linux-2.6.29-rc3.owrt/drivers/gpu/drm/drm_gem.c +--- linux-2.6.29.owrt/drivers/gpu/drm/drm_gem.c 2009-05-10 22:04:38.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/drivers/gpu/drm/drm_gem.c 2009-05-10 23:48:28.000000000 +0200 +@@ -104,8 +104,8 @@ + + if (drm_mm_init(&mm->offset_manager, DRM_FILE_PAGE_OFFSET_START, + DRM_FILE_PAGE_OFFSET_SIZE)) { +- drm_ht_remove(&mm->offset_hash); + drm_free(mm, sizeof(struct drm_gem_mm), DRM_MEM_MM); ++ drm_ht_remove(&mm->offset_hash); + return -ENOMEM; + } + +@@ -136,7 +136,7 @@ + obj = kcalloc(1, sizeof(*obj), GFP_KERNEL); + + obj->dev = dev; +- obj->filp = shmem_file_setup("drm mm object", size, VM_NORESERVE); ++ obj->filp = shmem_file_setup("drm mm object", size, 0); + if (IS_ERR(obj->filp)) { + kfree(obj); + return NULL; +@@ -295,37 +295,35 @@ + return -EBADF; + + again: +- if (idr_pre_get(&dev->object_name_idr, GFP_KERNEL) == 0) { +- ret = -ENOMEM; +- goto err; +- } ++ if (idr_pre_get(&dev->object_name_idr, GFP_KERNEL) == 0) ++ return -ENOMEM; + + spin_lock(&dev->object_name_lock); +- if (!obj->name) { +- ret = idr_get_new_above(&dev->object_name_idr, obj, 1, +- &obj->name); +- args->name = (uint64_t) obj->name; ++ if (obj->name) { ++ args->name = obj->name; + spin_unlock(&dev->object_name_lock); ++ return 0; ++ } ++ ret = idr_get_new_above(&dev->object_name_idr, obj, 1, ++ &obj->name); ++ spin_unlock(&dev->object_name_lock); ++ if (ret == -EAGAIN) ++ goto again; + +- if (ret == -EAGAIN) +- goto again; +- +- if (ret != 0) +- goto err; +- +- /* Allocate a reference for the name table. */ +- drm_gem_object_reference(obj); +- } else { +- args->name = (uint64_t) obj->name; +- spin_unlock(&dev->object_name_lock); +- ret = 0; ++ if (ret != 0) { ++ mutex_lock(&dev->struct_mutex); ++ drm_gem_object_unreference(obj); ++ mutex_unlock(&dev->struct_mutex); ++ return ret; + } + +-err: +- mutex_lock(&dev->struct_mutex); +- drm_gem_object_unreference(obj); +- mutex_unlock(&dev->struct_mutex); +- return ret; ++ /* ++ * Leave the reference from the lookup around as the ++ * name table now holds one ++ */ ++ args->name = (uint64_t) obj->name; ++ ++ return 0; + } + + /** +@@ -450,7 +448,6 @@ + spin_lock(&dev->object_name_lock); + if (obj->name) { + idr_remove(&dev->object_name_idr, obj->name); +- obj->name = 0; + spin_unlock(&dev->object_name_lock); + /* + * The object name held a reference to this object, drop +@@ -463,26 +460,6 @@ + } + EXPORT_SYMBOL(drm_gem_object_handle_free); + +-void drm_gem_vm_open(struct vm_area_struct *vma) +-{ +- struct drm_gem_object *obj = vma->vm_private_data; +- +- drm_gem_object_reference(obj); +-} +-EXPORT_SYMBOL(drm_gem_vm_open); +- +-void drm_gem_vm_close(struct vm_area_struct *vma) +-{ +- struct drm_gem_object *obj = vma->vm_private_data; +- struct drm_device *dev = obj->dev; +- +- mutex_lock(&dev->struct_mutex); +- drm_gem_object_unreference(obj); +- mutex_unlock(&dev->struct_mutex); +-} +-EXPORT_SYMBOL(drm_gem_vm_close); +- +- + /** + * drm_gem_mmap - memory map routine for GEM objects + * @filp: DRM file pointer +@@ -544,14 +521,6 @@ + #endif + vma->vm_page_prot = __pgprot(prot); + +- /* Take a ref for this mapping of the object, so that the fault +- * handler can dereference the mmap offset's pointer to the object. +- * This reference is cleaned up by the corresponding vm_close +- * (which should happen whether the vma was created by this call, or +- * by a vm_open due to mremap or partial unmap or whatever). +- */ +- drm_gem_object_reference(obj); +- + vma->vm_file = filp; /* Needed for drm_vm_open() */ + drm_vm_open_locked(vma); + +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/drivers/gpu/drm/drm_irq.c linux-2.6.29-rc3.owrt/drivers/gpu/drm/drm_irq.c +--- linux-2.6.29.owrt/drivers/gpu/drm/drm_irq.c 2009-05-10 22:04:38.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/drivers/gpu/drm/drm_irq.c 2009-05-10 23:48:28.000000000 +0200 +@@ -276,7 +276,6 @@ + for (i = 0; i < dev->num_crtcs; i++) { + DRM_WAKEUP(&dev->vbl_queue[i]); + dev->vblank_enabled[i] = 0; +- dev->last_vblank[i] = dev->driver->get_vblank_counter(dev, i); + } + spin_unlock_irqrestore(&dev->vbl_lock, irqflags); + +@@ -435,8 +434,6 @@ + */ + void drm_vblank_put(struct drm_device *dev, int crtc) + { +- BUG_ON (atomic_read (&dev->vblank_refcount[crtc]) == 0); +- + /* Last user schedules interrupt disable */ + if (atomic_dec_and_test(&dev->vblank_refcount[crtc])) + mod_timer(&dev->vblank_disable_timer, jiffies + 5*DRM_HZ); +@@ -462,9 +459,8 @@ + * so that interrupts remain enabled in the interim. + */ + if (!dev->vblank_inmodeset[crtc]) { +- dev->vblank_inmodeset[crtc] = 0x1; +- if (drm_vblank_get(dev, crtc) == 0) +- dev->vblank_inmodeset[crtc] |= 0x2; ++ dev->vblank_inmodeset[crtc] = 1; ++ drm_vblank_get(dev, crtc); + } + } + EXPORT_SYMBOL(drm_vblank_pre_modeset); +@@ -476,12 +472,9 @@ + if (dev->vblank_inmodeset[crtc]) { + spin_lock_irqsave(&dev->vbl_lock, irqflags); + dev->vblank_disable_allowed = 1; +- spin_unlock_irqrestore(&dev->vbl_lock, irqflags); +- +- if (dev->vblank_inmodeset[crtc] & 0x2) +- drm_vblank_put(dev, crtc); +- + dev->vblank_inmodeset[crtc] = 0; ++ spin_unlock_irqrestore(&dev->vbl_lock, irqflags); ++ drm_vblank_put(dev, crtc); + } + } + EXPORT_SYMBOL(drm_vblank_post_modeset); +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/drivers/gpu/drm/drm_lock.c linux-2.6.29-rc3.owrt/drivers/gpu/drm/drm_lock.c +--- linux-2.6.29.owrt/drivers/gpu/drm/drm_lock.c 2009-05-10 22:04:38.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/drivers/gpu/drm/drm_lock.c 2009-05-10 23:48:28.000000000 +0200 +@@ -80,7 +80,6 @@ + __set_current_state(TASK_INTERRUPTIBLE); + if (!master->lock.hw_lock) { + /* Device has been unregistered */ +- send_sig(SIGTERM, current, 0); + ret = -EINTR; + break; + } +@@ -94,7 +93,7 @@ + /* Contention */ + schedule(); + if (signal_pending(current)) { +- ret = -EINTR; ++ ret = -ERESTARTSYS; + break; + } + } +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/drivers/gpu/drm/drm_memory.c linux-2.6.29-rc3.owrt/drivers/gpu/drm/drm_memory.c +--- linux-2.6.29.owrt/drivers/gpu/drm/drm_memory.c 2009-05-10 22:04:38.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/drivers/gpu/drm/drm_memory.c 2009-05-10 23:48:28.000000000 +0200 +@@ -171,14 +171,9 @@ + + void drm_core_ioremap_wc(struct drm_map *map, struct drm_device *dev) + { +- if (drm_core_has_AGP(dev) && +- dev->agp && dev->agp->cant_use_aperture && map->type == _DRM_AGP) +- map->handle = agp_remap(map->offset, map->size, dev); +- else +- map->handle = ioremap_wc(map->offset, map->size); ++ map->handle = ioremap_wc(map->offset, map->size); + } + EXPORT_SYMBOL(drm_core_ioremap_wc); +- + void drm_core_ioremapfree(struct drm_map *map, struct drm_device *dev) + { + if (!map->handle || !map->size) +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/drivers/gpu/drm/drm_stub.c linux-2.6.29-rc3.owrt/drivers/gpu/drm/drm_stub.c +--- linux-2.6.29.owrt/drivers/gpu/drm/drm_stub.c 2009-05-10 22:04:38.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/drivers/gpu/drm/drm_stub.c 2009-05-10 23:48:28.000000000 +0200 +@@ -146,6 +146,14 @@ + + drm_ht_remove(&master->magiclist); + ++ if (master->lock.hw_lock) { ++ if (dev->sigdata.lock == master->lock.hw_lock) ++ dev->sigdata.lock = NULL; ++ master->lock.hw_lock = NULL; ++ master->lock.file_priv = NULL; ++ wake_up_interruptible(&master->lock.lock_queue); ++ } ++ + drm_free(master, sizeof(*master), DRM_MEM_DRIVER); + } + +@@ -168,7 +176,7 @@ + file_priv->minor->master != file_priv->master) { + mutex_lock(&dev->struct_mutex); + file_priv->minor->master = drm_master_get(file_priv->master); +- mutex_unlock(&dev->struct_mutex); ++ mutex_lock(&dev->struct_mutex); + } + + return 0; +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/drivers/gpu/drm/i915/i915_dma.c linux-2.6.29-rc3.owrt/drivers/gpu/drm/i915/i915_dma.c +--- linux-2.6.29.owrt/drivers/gpu/drm/i915/i915_dma.c 2009-05-10 22:04:38.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/drivers/gpu/drm/i915/i915_dma.c 2009-05-10 23:48:28.000000000 +0200 +@@ -202,7 +202,7 @@ + dev_priv->ring.map.flags = 0; + dev_priv->ring.map.mtrr = 0; + +- drm_core_ioremap_wc(&dev_priv->ring.map, dev); ++ drm_core_ioremap(&dev_priv->ring.map, dev); + + if (dev_priv->ring.map.handle == NULL) { + i915_dma_cleanup(dev); +@@ -731,11 +731,8 @@ + case I915_PARAM_HAS_GEM: + value = dev_priv->has_gem; + break; +- case I915_PARAM_NUM_FENCES_AVAIL: +- value = dev_priv->num_fence_regs - dev_priv->fence_reg_start; +- break; + default: +- DRM_DEBUG("Unknown parameter %d\n", param->param); ++ DRM_ERROR("Unknown parameter %d\n", param->param); + return -EINVAL; + } + +@@ -767,15 +764,8 @@ + case I915_SETPARAM_ALLOW_BATCHBUFFER: + dev_priv->allow_batchbuffer = param->value; + break; +- case I915_SETPARAM_NUM_USED_FENCES: +- if (param->value > dev_priv->num_fence_regs || +- param->value < 0) +- return -EINVAL; +- /* Userspace can use first N regs */ +- dev_priv->fence_reg_start = param->value; +- break; + default: +- DRM_DEBUG("unknown parameter %d\n", param->param); ++ DRM_ERROR("unknown parameter %d\n", param->param); + return -EINVAL; + } + +@@ -811,7 +801,7 @@ + dev_priv->hws_map.flags = 0; + dev_priv->hws_map.mtrr = 0; + +- drm_core_ioremap_wc(&dev_priv->hws_map, dev); ++ drm_core_ioremap(&dev_priv->hws_map, dev); + if (dev_priv->hws_map.handle == NULL) { + i915_dma_cleanup(dev); + dev_priv->status_gfx_addr = 0; +@@ -976,6 +966,10 @@ + if (ret) + goto kfree_devname; + ++ dev_priv->mm.gtt_mapping = ++ io_mapping_create_wc(dev->agp->base, ++ dev->agp->agp_info.aper_size * 1024*1024); ++ + /* Allow hardware batchbuffers unless told otherwise. + */ + dev_priv->allow_batchbuffer = 1; +@@ -1087,28 +1081,6 @@ + goto free_priv; + } + +- dev_priv->mm.gtt_mapping = +- io_mapping_create_wc(dev->agp->base, +- dev->agp->agp_info.aper_size * 1024*1024); +- if (dev_priv->mm.gtt_mapping == NULL) { +- ret = -EIO; +- goto out_rmmap; +- } +- +- /* Set up a WC MTRR for non-PAT systems. This is more common than +- * one would think, because the kernel disables PAT on first +- * generation Core chips because WC PAT gets overridden by a UC +- * MTRR if present. Even if a UC MTRR isn't present. +- */ +- dev_priv->mm.gtt_mtrr = mtrr_add(dev->agp->base, +- dev->agp->agp_info.aper_size * +- 1024 * 1024, +- MTRR_TYPE_WRCOMB, 1); +- if (dev_priv->mm.gtt_mtrr < 0) { +- DRM_INFO("MTRR allocation failed. Graphics " +- "performance may suffer.\n"); +- } +- + #ifdef CONFIG_HIGHMEM64G + /* don't enable GEM on PAE - needs agp + set_memory_* interface fixes */ + dev_priv->has_gem = 0; +@@ -1117,17 +1089,13 @@ + dev_priv->has_gem = 1; + #endif + +- dev->driver->get_vblank_counter = i915_get_vblank_counter; +- if (IS_GM45(dev)) +- dev->driver->get_vblank_counter = gm45_get_vblank_counter; +- + i915_gem_load(dev); + + /* Init HWS */ + if (!I915_NEED_GFX_HWS(dev)) { + ret = i915_init_phys_hws(dev); + if (ret != 0) +- goto out_iomapfree; ++ goto out_rmmap; + } + + /* On the 945G/GM, the chipset reports the MSI capability on the +@@ -1166,8 +1134,6 @@ + + return 0; + +-out_iomapfree: +- io_mapping_free(dev_priv->mm.gtt_mapping); + out_rmmap: + iounmap(dev_priv->regs); + free_priv: +@@ -1179,14 +1145,8 @@ + { + struct drm_i915_private *dev_priv = dev->dev_private; + +- io_mapping_free(dev_priv->mm.gtt_mapping); +- if (dev_priv->mm.gtt_mtrr >= 0) { +- mtrr_del(dev_priv->mm.gtt_mtrr, dev->agp->base, +- dev->agp->agp_info.aper_size * 1024 * 1024); +- dev_priv->mm.gtt_mtrr = -1; +- } +- + if (drm_core_check_feature(dev, DRIVER_MODESET)) { ++ io_mapping_free(dev_priv->mm.gtt_mapping); + drm_irq_uninstall(dev); + } + +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/drivers/gpu/drm/i915/i915_drv.c linux-2.6.29-rc3.owrt/drivers/gpu/drm/i915/i915_drv.c +--- linux-2.6.29.owrt/drivers/gpu/drm/i915/i915_drv.c 2009-05-10 22:04:38.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/drivers/gpu/drm/i915/i915_drv.c 2009-05-10 23:48:28.000000000 +0200 +@@ -27,7 +27,6 @@ + * + */ + +-#include <linux/device.h> + #include "drmP.h" + #include "drm.h" + #include "i915_drm.h" +@@ -67,14 +66,6 @@ + + i915_save_state(dev); + +- /* If KMS is active, we do the leavevt stuff here */ +- if (drm_core_check_feature(dev, DRIVER_MODESET)) { +- if (i915_gem_idle(dev)) +- dev_err(&dev->pdev->dev, +- "GEM idle failed, resume may fail\n"); +- drm_irq_uninstall(dev); +- } +- + intel_opregion_free(dev); + + if (state.event == PM_EVENT_SUSPEND) { +@@ -88,9 +79,6 @@ + + static int i915_resume(struct drm_device *dev) + { +- struct drm_i915_private *dev_priv = dev->dev_private; +- int ret = 0; +- + pci_set_power_state(dev->pdev, PCI_D0); + pci_restore_state(dev->pdev); + if (pci_enable_device(dev->pdev)) +@@ -101,26 +89,11 @@ + + intel_opregion_init(dev); + +- /* KMS EnterVT equivalent */ +- if (drm_core_check_feature(dev, DRIVER_MODESET)) { +- mutex_lock(&dev->struct_mutex); +- dev_priv->mm.suspended = 0; +- +- ret = i915_gem_init_ringbuffer(dev); +- if (ret != 0) +- ret = -1; +- mutex_unlock(&dev->struct_mutex); +- +- drm_irq_install(dev); +- } +- +- return ret; ++ return 0; + } + + static struct vm_operations_struct i915_gem_vm_ops = { + .fault = i915_gem_fault, +- .open = drm_gem_vm_open, +- .close = drm_gem_vm_close, + }; + + static struct drm_driver driver = { +@@ -139,6 +112,7 @@ + .suspend = i915_suspend, + .resume = i915_resume, + .device_is_agp = i915_driver_device_is_agp, ++ .get_vblank_counter = i915_get_vblank_counter, + .enable_vblank = i915_enable_vblank, + .disable_vblank = i915_disable_vblank, + .irq_preinstall = i915_driver_irq_preinstall, +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/drivers/gpu/drm/i915/i915_drv.h linux-2.6.29-rc3.owrt/drivers/gpu/drm/i915/i915_drv.h +--- linux-2.6.29.owrt/drivers/gpu/drm/i915/i915_drv.h 2009-05-10 22:04:38.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/drivers/gpu/drm/i915/i915_drv.h 2009-05-10 23:48:28.000000000 +0200 +@@ -184,8 +184,6 @@ + unsigned int lvds_dither:1; + unsigned int lvds_vbt:1; + unsigned int int_crt_support:1; +- unsigned int lvds_use_ssc:1; +- int lvds_ssc_freq; + + struct drm_i915_fence_reg fence_regs[16]; /* assume 965 */ + int fence_reg_start; /* 4 if userland hasn't ioctl'd us yet */ +@@ -279,13 +277,13 @@ + u8 saveAR_INDEX; + u8 saveAR[21]; + u8 saveDACMASK; ++ u8 saveDACDATA[256*3]; /* 256 3-byte colors */ + u8 saveCR[37]; + + struct { + struct drm_mm gtt_space; + + struct io_mapping *gtt_mapping; +- int gtt_mtrr; + + /** + * List of objects currently involved in rendering from the +@@ -456,12 +454,6 @@ + + /** for phy allocated objects */ + struct drm_i915_gem_phys_object *phys_obj; +- +- /** +- * Used for checking the object doesn't appear more than once +- * in an execbuffer object list. +- */ +- int in_execbuffer; + }; + + /** +@@ -542,7 +534,6 @@ + extern int i915_enable_vblank(struct drm_device *dev, int crtc); + extern void i915_disable_vblank(struct drm_device *dev, int crtc); + extern u32 i915_get_vblank_counter(struct drm_device *dev, int crtc); +-extern u32 gm45_get_vblank_counter(struct drm_device *dev, int crtc); + extern int i915_vblank_swap(struct drm_device *dev, void *data, + struct drm_file *file_priv); + extern void i915_enable_irq(drm_i915_private_t *dev_priv, u32 mask); +@@ -610,7 +601,6 @@ + void i915_gem_free_object(struct drm_gem_object *obj); + int i915_gem_object_pin(struct drm_gem_object *obj, uint32_t alignment); + void i915_gem_object_unpin(struct drm_gem_object *obj); +-int i915_gem_object_unbind(struct drm_gem_object *obj); + void i915_gem_lastclose(struct drm_device *dev); + uint32_t i915_get_gem_seqno(struct drm_device *dev); + void i915_gem_retire_requests(struct drm_device *dev); +@@ -623,7 +613,6 @@ + void i915_gem_cleanup_ringbuffer(struct drm_device *dev); + int i915_gem_do_init(struct drm_device *dev, unsigned long start, + unsigned long end); +-int i915_gem_idle(struct drm_device *dev); + int i915_gem_fault(struct vm_area_struct *vma, struct vm_fault *vmf); + int i915_gem_object_set_to_gtt_domain(struct drm_gem_object *obj, + int write); +@@ -795,11 +784,6 @@ + IS_I945GM(dev) || IS_I965GM(dev) || IS_GM45(dev)) + + #define I915_NEED_GFX_HWS(dev) (IS_G33(dev) || IS_GM45(dev) || IS_G4X(dev)) +-/* With the 945 and later, Y tiling got adjusted so that it was 32 128-byte +- * rows, which changed the alignment requirements and fence programming. +- */ +-#define HAS_128_BYTE_Y_TILING(dev) (IS_I9XX(dev) && !(IS_I915G(dev) || \ +- IS_I915GM(dev))) + #define SUPPORTS_INTEGRATED_HDMI(dev) (IS_G4X(dev)) + + #define PRIMARY_RINGBUFFER_SIZE (128*1024) +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/drivers/gpu/drm/i915/i915_gem.c linux-2.6.29-rc3.owrt/drivers/gpu/drm/i915/i915_gem.c +--- linux-2.6.29.owrt/drivers/gpu/drm/i915/i915_gem.c 2009-05-10 22:04:38.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/drivers/gpu/drm/i915/i915_gem.c 2009-05-10 23:48:28.000000000 +0200 +@@ -34,6 +34,10 @@ + + #define I915_GEM_GPU_DOMAINS (~(I915_GEM_DOMAIN_CPU | I915_GEM_DOMAIN_GTT)) + ++static void ++i915_gem_object_set_to_gpu_domain(struct drm_gem_object *obj, ++ uint32_t read_domains, ++ uint32_t write_domain); + static void i915_gem_object_flush_gpu_write_domain(struct drm_gem_object *obj); + static void i915_gem_object_flush_gtt_write_domain(struct drm_gem_object *obj); + static void i915_gem_object_flush_cpu_write_domain(struct drm_gem_object *obj); +@@ -48,7 +52,7 @@ + static int i915_gem_object_wait_rendering(struct drm_gem_object *obj); + static int i915_gem_object_bind_to_gtt(struct drm_gem_object *obj, + unsigned alignment); +-static int i915_gem_object_get_fence_reg(struct drm_gem_object *obj, bool write); ++static void i915_gem_object_get_fence_reg(struct drm_gem_object *obj); + static void i915_gem_clear_fence_reg(struct drm_gem_object *obj); + static int i915_gem_evict_something(struct drm_device *dev); + static int i915_gem_phys_pwrite(struct drm_device *dev, struct drm_gem_object *obj, +@@ -563,7 +567,6 @@ + pgoff_t page_offset; + unsigned long pfn; + int ret = 0; +- bool write = !!(vmf->flags & FAULT_FLAG_WRITE); + + /* We don't use vmf->pgoff since that has the fake offset */ + page_offset = ((unsigned long)vmf->virtual_address - vma->vm_start) >> +@@ -582,13 +585,8 @@ + + /* Need a new fence register? */ + if (obj_priv->fence_reg == I915_FENCE_REG_NONE && +- obj_priv->tiling_mode != I915_TILING_NONE) { +- ret = i915_gem_object_get_fence_reg(obj, write); +- if (ret) { +- mutex_unlock(&dev->struct_mutex); +- return VM_FAULT_SIGBUS; +- } +- } ++ obj_priv->tiling_mode != I915_TILING_NONE) ++ i915_gem_object_get_fence_reg(obj); + + pfn = ((dev->agp->base + obj_priv->gtt_offset) >> PAGE_SHIFT) + + page_offset; +@@ -603,6 +601,8 @@ + case -EAGAIN: + return VM_FAULT_OOM; + case -EFAULT: ++ case -EBUSY: ++ DRM_ERROR("can't insert pfn?? fault or busy...\n"); + return VM_FAULT_SIGBUS; + default: + return VM_FAULT_NOPAGE; +@@ -678,30 +678,6 @@ + return ret; + } + +-static void +-i915_gem_free_mmap_offset(struct drm_gem_object *obj) +-{ +- struct drm_device *dev = obj->dev; +- struct drm_i915_gem_object *obj_priv = obj->driver_private; +- struct drm_gem_mm *mm = dev->mm_private; +- struct drm_map_list *list; +- +- list = &obj->map_list; +- drm_ht_remove_item(&mm->offset_hash, &list->hash); +- +- if (list->file_offset_node) { +- drm_mm_put_block(list->file_offset_node); +- list->file_offset_node = NULL; +- } +- +- if (list->map) { +- drm_free(list->map, sizeof(struct drm_map), DRM_MEM_DRIVER); +- list->map = NULL; +- } +- +- obj_priv->mmap_offset = 0; +-} +- + /** + * i915_gem_get_gtt_alignment - return required GTT alignment for an object + * @obj: object to check +@@ -776,11 +752,8 @@ + + if (!obj_priv->mmap_offset) { + ret = i915_gem_create_mmap_offset(obj); +- if (ret) { +- drm_gem_object_unreference(obj); +- mutex_unlock(&dev->struct_mutex); ++ if (ret) + return ret; +- } + } + + args->offset = obj_priv->mmap_offset; +@@ -1051,9 +1024,6 @@ + drm_i915_private_t *dev_priv = dev->dev_private; + uint32_t seqno; + +- if (!dev_priv->hw_status_page) +- return; +- + seqno = i915_get_gem_seqno(dev); + + while (!list_empty(&dev_priv->mm.request_list)) { +@@ -1241,7 +1211,7 @@ + /** + * Unbinds an object from the GTT aperture. + */ +-int ++static int + i915_gem_object_unbind(struct drm_gem_object *obj) + { + struct drm_device *dev = obj->dev; +@@ -1475,26 +1445,21 @@ + drm_i915_private_t *dev_priv = dev->dev_private; + struct drm_i915_gem_object *obj_priv = obj->driver_private; + int regnum = obj_priv->fence_reg; +- int tile_width; +- uint32_t fence_reg, val; ++ uint32_t val; + uint32_t pitch_val; + + if ((obj_priv->gtt_offset & ~I915_FENCE_START_MASK) || + (obj_priv->gtt_offset & (obj->size - 1))) { +- WARN(1, "%s: object 0x%08x not 1M or size (0x%zx) aligned\n", +- __func__, obj_priv->gtt_offset, obj->size); ++ WARN(1, "%s: object not 1M or size aligned\n", __func__); + return; + } + +- if (obj_priv->tiling_mode == I915_TILING_Y && +- HAS_128_BYTE_Y_TILING(dev)) +- tile_width = 128; ++ if (obj_priv->tiling_mode == I915_TILING_Y && (IS_I945G(dev) || ++ IS_I945GM(dev) || ++ IS_G33(dev))) ++ pitch_val = (obj_priv->stride / 128) - 1; + else +- tile_width = 512; +- +- /* Note: pitch better be a power of two tile widths */ +- pitch_val = obj_priv->stride / tile_width; +- pitch_val = ffs(pitch_val) - 1; ++ pitch_val = (obj_priv->stride / 512) - 1; + + val = obj_priv->gtt_offset; + if (obj_priv->tiling_mode == I915_TILING_Y) +@@ -1503,11 +1468,7 @@ + val |= pitch_val << I830_FENCE_PITCH_SHIFT; + val |= I830_FENCE_REG_VALID; + +- if (regnum < 8) +- fence_reg = FENCE_REG_830_0 + (regnum * 4); +- else +- fence_reg = FENCE_REG_945_8 + ((regnum - 8) * 4); +- I915_WRITE(fence_reg, val); ++ I915_WRITE(FENCE_REG_830_0 + (regnum * 4), val); + } + + static void i830_write_fence_reg(struct drm_i915_fence_reg *reg) +@@ -1522,8 +1483,7 @@ + + if ((obj_priv->gtt_offset & ~I915_FENCE_START_MASK) || + (obj_priv->gtt_offset & (obj->size - 1))) { +- WARN(1, "%s: object 0x%08x not 1M or size aligned\n", +- __func__, obj_priv->gtt_offset); ++ WARN(1, "%s: object not 1M or size aligned\n", __func__); + return; + } + +@@ -1543,7 +1503,6 @@ + /** + * i915_gem_object_get_fence_reg - set up a fence reg for an object + * @obj: object to map through a fence reg +- * @write: object is about to be written + * + * When mapping objects through the GTT, userspace wants to be able to write + * to them without having to worry about swizzling if the object is tiled. +@@ -1554,77 +1513,49 @@ + * It then sets up the reg based on the object's properties: address, pitch + * and tiling format. + */ +-static int +-i915_gem_object_get_fence_reg(struct drm_gem_object *obj, bool write) ++static void ++i915_gem_object_get_fence_reg(struct drm_gem_object *obj) + { + struct drm_device *dev = obj->dev; + struct drm_i915_private *dev_priv = dev->dev_private; + struct drm_i915_gem_object *obj_priv = obj->driver_private; + struct drm_i915_fence_reg *reg = NULL; +- struct drm_i915_gem_object *old_obj_priv = NULL; +- int i, ret, avail; ++ int i, ret; + + switch (obj_priv->tiling_mode) { + case I915_TILING_NONE: + WARN(1, "allocating a fence for non-tiled object?\n"); + break; + case I915_TILING_X: +- if (!obj_priv->stride) +- return -EINVAL; +- WARN((obj_priv->stride & (512 - 1)), +- "object 0x%08x is X tiled but has non-512B pitch\n", +- obj_priv->gtt_offset); ++ WARN(obj_priv->stride & (512 - 1), ++ "object is X tiled but has non-512B pitch\n"); + break; + case I915_TILING_Y: +- if (!obj_priv->stride) +- return -EINVAL; +- WARN((obj_priv->stride & (128 - 1)), +- "object 0x%08x is Y tiled but has non-128B pitch\n", +- obj_priv->gtt_offset); ++ WARN(obj_priv->stride & (128 - 1), ++ "object is Y tiled but has non-128B pitch\n"); + break; + } + + /* First try to find a free reg */ +-try_again: +- avail = 0; + for (i = dev_priv->fence_reg_start; i < dev_priv->num_fence_regs; i++) { + reg = &dev_priv->fence_regs[i]; + if (!reg->obj) + break; +- +- old_obj_priv = reg->obj->driver_private; +- if (!old_obj_priv->pin_count) +- avail++; + } + + /* None available, try to steal one or wait for a user to finish */ + if (i == dev_priv->num_fence_regs) { +- uint32_t seqno = dev_priv->mm.next_gem_seqno; ++ struct drm_i915_gem_object *old_obj_priv = NULL; + loff_t offset; + +- if (avail == 0) +- return -ENOMEM; +- ++try_again: ++ /* Could try to use LRU here instead... */ + for (i = dev_priv->fence_reg_start; + i < dev_priv->num_fence_regs; i++) { +- uint32_t this_seqno; +- + reg = &dev_priv->fence_regs[i]; + old_obj_priv = reg->obj->driver_private; +- +- if (old_obj_priv->pin_count) +- continue; +- +- /* i915 uses fences for GPU access to tiled buffers */ +- if (IS_I965G(dev) || !old_obj_priv->active) ++ if (!old_obj_priv->pin_count) + break; +- +- /* find the seqno of the first available fence */ +- this_seqno = old_obj_priv->last_rendering_seqno; +- if (this_seqno != 0 && +- reg->obj->write_domain == 0 && +- i915_seqno_passed(seqno, this_seqno)) +- seqno = this_seqno; + } + + /* +@@ -1632,25 +1563,14 @@ + * objects to finish before trying again. + */ + if (i == dev_priv->num_fence_regs) { +- if (seqno == dev_priv->mm.next_gem_seqno) { +- i915_gem_flush(dev, +- I915_GEM_GPU_DOMAINS, +- I915_GEM_GPU_DOMAINS); +- seqno = i915_add_request(dev, +- I915_GEM_GPU_DOMAINS); +- if (seqno == 0) +- return -ENOMEM; ++ ret = i915_gem_object_wait_rendering(reg->obj); ++ if (ret) { ++ WARN(ret, "wait_rendering failed: %d\n", ret); ++ return; + } +- +- ret = i915_wait_request(dev, seqno); +- if (ret) +- return ret; + goto try_again; + } + +- BUG_ON(old_obj_priv->active || +- (reg->obj->write_domain & I915_GEM_GPU_DOMAINS)); +- + /* + * Zap this virtual mapping so we can set up a fence again + * for this object next time we need it. +@@ -1671,8 +1591,6 @@ + i915_write_fence_reg(reg); + else + i830_write_fence_reg(reg); +- +- return 0; + } + + /** +@@ -1691,17 +1609,8 @@ + + if (IS_I965G(dev)) + I915_WRITE64(FENCE_REG_965_0 + (obj_priv->fence_reg * 8), 0); +- else { +- uint32_t fence_reg; +- +- if (obj_priv->fence_reg < 8) +- fence_reg = FENCE_REG_830_0 + obj_priv->fence_reg * 4; +- else +- fence_reg = FENCE_REG_945_8 + (obj_priv->fence_reg - +- 8) * 4; +- +- I915_WRITE(fence_reg, 0); +- } ++ else ++ I915_WRITE(FENCE_REG_830_0 + (obj_priv->fence_reg * 4), 0); + + dev_priv->fence_regs[obj_priv->fence_reg].obj = NULL; + obj_priv->fence_reg = I915_FENCE_REG_NONE; +@@ -1722,7 +1631,7 @@ + if (dev_priv->mm.suspended) + return -EBUSY; + if (alignment == 0) +- alignment = i915_gem_get_gtt_alignment(obj); ++ alignment = PAGE_SIZE; + if (alignment & (PAGE_SIZE - 1)) { + DRM_ERROR("Invalid object alignment requested %u\n", alignment); + return -EINVAL; +@@ -2065,28 +1974,30 @@ + * drm_agp_chipset_flush + */ + static void +-i915_gem_object_set_to_gpu_domain(struct drm_gem_object *obj) ++i915_gem_object_set_to_gpu_domain(struct drm_gem_object *obj, ++ uint32_t read_domains, ++ uint32_t write_domain) + { + struct drm_device *dev = obj->dev; + struct drm_i915_gem_object *obj_priv = obj->driver_private; + uint32_t invalidate_domains = 0; + uint32_t flush_domains = 0; + +- BUG_ON(obj->pending_read_domains & I915_GEM_DOMAIN_CPU); +- BUG_ON(obj->pending_write_domain == I915_GEM_DOMAIN_CPU); ++ BUG_ON(read_domains & I915_GEM_DOMAIN_CPU); ++ BUG_ON(write_domain == I915_GEM_DOMAIN_CPU); + + #if WATCH_BUF + DRM_INFO("%s: object %p read %08x -> %08x write %08x -> %08x\n", + __func__, obj, +- obj->read_domains, obj->pending_read_domains, +- obj->write_domain, obj->pending_write_domain); ++ obj->read_domains, read_domains, ++ obj->write_domain, write_domain); + #endif + /* + * If the object isn't moving to a new write domain, + * let the object stay in multiple read domains + */ +- if (obj->pending_write_domain == 0) +- obj->pending_read_domains |= obj->read_domains; ++ if (write_domain == 0) ++ read_domains |= obj->read_domains; + else + obj_priv->dirty = 1; + +@@ -2096,17 +2007,15 @@ + * any read domains which differ from the old + * write domain + */ +- if (obj->write_domain && +- obj->write_domain != obj->pending_read_domains) { ++ if (obj->write_domain && obj->write_domain != read_domains) { + flush_domains |= obj->write_domain; +- invalidate_domains |= +- obj->pending_read_domains & ~obj->write_domain; ++ invalidate_domains |= read_domains & ~obj->write_domain; + } + /* + * Invalidate any read caches which may have + * stale data. That is, any new read domains. + */ +- invalidate_domains |= obj->pending_read_domains & ~obj->read_domains; ++ invalidate_domains |= read_domains & ~obj->read_domains; + if ((flush_domains | invalidate_domains) & I915_GEM_DOMAIN_CPU) { + #if WATCH_BUF + DRM_INFO("%s: CPU domain flush %08x invalidate %08x\n", +@@ -2115,15 +2024,9 @@ + i915_gem_clflush_object(obj); + } + +- /* The actual obj->write_domain will be updated with +- * pending_write_domain after we emit the accumulated flush for all +- * of our domain changes in execbuffers (which clears objects' +- * write_domains). So if we have a current write domain that we +- * aren't changing, set pending_write_domain to that. +- */ +- if (flush_domains == 0 && obj->pending_write_domain == 0) +- obj->pending_write_domain = obj->write_domain; +- obj->read_domains = obj->pending_read_domains; ++ if ((write_domain | flush_domains) != 0) ++ obj->write_domain = write_domain; ++ obj->read_domains = read_domains; + + dev->invalidate_domains |= invalidate_domains; + dev->flush_domains |= flush_domains; +@@ -2326,8 +2229,6 @@ + (int) reloc.offset, + reloc.read_domains, + reloc.write_domain); +- drm_gem_object_unreference(target_obj); +- i915_gem_object_unpin(obj); + return -EINVAL; + } + +@@ -2514,7 +2415,6 @@ + struct drm_i915_gem_exec_object *exec_list = NULL; + struct drm_gem_object **object_list = NULL; + struct drm_gem_object *batch_obj; +- struct drm_i915_gem_object *obj_priv; + int ret, i, pinned = 0; + uint64_t exec_offset; + uint32_t seqno, flush_domains; +@@ -2558,15 +2458,13 @@ + if (dev_priv->mm.wedged) { + DRM_ERROR("Execbuf while wedged\n"); + mutex_unlock(&dev->struct_mutex); +- ret = -EIO; +- goto pre_mutex_err; ++ return -EIO; + } + + if (dev_priv->mm.suspended) { + DRM_ERROR("Execbuf while VT-switched.\n"); + mutex_unlock(&dev->struct_mutex); +- ret = -EBUSY; +- goto pre_mutex_err; ++ return -EBUSY; + } + + /* Look up object handles */ +@@ -2579,15 +2477,6 @@ + ret = -EBADF; + goto err; + } +- +- obj_priv = object_list[i]->driver_private; +- if (obj_priv->in_execbuffer) { +- DRM_ERROR("Object %p appears more than once in object list\n", +- object_list[i]); +- ret = -EBADF; +- goto err; +- } +- obj_priv->in_execbuffer = true; + } + + /* Pin and relocate */ +@@ -2643,7 +2532,9 @@ + struct drm_gem_object *obj = object_list[i]; + + /* Compute new gpu domains and update invalidate/flush */ +- i915_gem_object_set_to_gpu_domain(obj); ++ i915_gem_object_set_to_gpu_domain(obj, ++ obj->pending_read_domains, ++ obj->pending_write_domain); + } + + i915_verify_inactive(dev, __FILE__, __LINE__); +@@ -2662,12 +2553,6 @@ + (void)i915_add_request(dev, dev->flush_domains); + } + +- for (i = 0; i < args->buffer_count; i++) { +- struct drm_gem_object *obj = object_list[i]; +- +- obj->write_domain = obj->pending_write_domain; +- } +- + i915_verify_inactive(dev, __FILE__, __LINE__); + + #if WATCH_COHERENCY +@@ -2725,32 +2610,24 @@ + + i915_verify_inactive(dev, __FILE__, __LINE__); + ++ /* Copy the new buffer offsets back to the user's exec list. */ ++ ret = copy_to_user((struct drm_i915_relocation_entry __user *) ++ (uintptr_t) args->buffers_ptr, ++ exec_list, ++ sizeof(*exec_list) * args->buffer_count); ++ if (ret) ++ DRM_ERROR("failed to copy %d exec entries " ++ "back to user (%d)\n", ++ args->buffer_count, ret); + err: + for (i = 0; i < pinned; i++) + i915_gem_object_unpin(object_list[i]); + +- for (i = 0; i < args->buffer_count; i++) { +- if (object_list[i]) { +- obj_priv = object_list[i]->driver_private; +- obj_priv->in_execbuffer = false; +- } ++ for (i = 0; i < args->buffer_count; i++) + drm_gem_object_unreference(object_list[i]); +- } + + mutex_unlock(&dev->struct_mutex); + +- if (!ret) { +- /* Copy the new buffer offsets back to the user's exec list. */ +- ret = copy_to_user((struct drm_i915_relocation_entry __user *) +- (uintptr_t) args->buffers_ptr, +- exec_list, +- sizeof(*exec_list) * args->buffer_count); +- if (ret) +- DRM_ERROR("failed to copy %d exec entries " +- "back to user (%d)\n", +- args->buffer_count, ret); +- } +- + pre_mutex_err: + drm_free(object_list, sizeof(*object_list) * args->buffer_count, + DRM_MEM_DRIVER); +@@ -2772,22 +2649,7 @@ + ret = i915_gem_object_bind_to_gtt(obj, alignment); + if (ret != 0) { + if (ret != -EBUSY && ret != -ERESTARTSYS) +- DRM_ERROR("Failure to bind: %d\n", ret); +- return ret; +- } +- } +- /* +- * Pre-965 chips need a fence register set up in order to +- * properly handle tiled surfaces. +- */ +- if (!IS_I965G(dev) && +- obj_priv->fence_reg == I915_FENCE_REG_NONE && +- obj_priv->tiling_mode != I915_TILING_NONE) { +- ret = i915_gem_object_get_fence_reg(obj, true); +- if (ret != 0) { +- if (ret != -EBUSY && ret != -ERESTARTSYS) +- DRM_ERROR("Failure to install fence: %d\n", +- ret); ++ DRM_ERROR("Failure to bind: %d", ret); + return ret; + } + } +@@ -2861,7 +2723,6 @@ + if (obj_priv->pin_filp != NULL && obj_priv->pin_filp != file_priv) { + DRM_ERROR("Already pinned in i915_gem_pin_ioctl(): %d\n", + args->handle); +- drm_gem_object_unreference(obj); + mutex_unlock(&dev->struct_mutex); + return -EINVAL; + } +@@ -2942,13 +2803,6 @@ + return -EBADF; + } + +- /* Update the active list for the hardware's current position. +- * Otherwise this only updates on a delayed timer or when irqs are +- * actually unmasked, and our working set ends up being larger than +- * required. +- */ +- i915_gem_retire_requests(dev); +- + obj_priv = obj->driver_private; + /* Don't count being on the flushing list against the object being + * done. Otherwise, a buffer left on the flushing list but not getting +@@ -3001,6 +2855,9 @@ + void i915_gem_free_object(struct drm_gem_object *obj) + { + struct drm_device *dev = obj->dev; ++ struct drm_gem_mm *mm = dev->mm_private; ++ struct drm_map_list *list; ++ struct drm_map *map; + struct drm_i915_gem_object *obj_priv = obj->driver_private; + + while (obj_priv->pin_count > 0) +@@ -3011,7 +2868,19 @@ + + i915_gem_object_unbind(obj); + +- i915_gem_free_mmap_offset(obj); ++ list = &obj->map_list; ++ drm_ht_remove_item(&mm->offset_hash, &list->hash); ++ ++ if (list->file_offset_node) { ++ drm_mm_put_block(list->file_offset_node); ++ list->file_offset_node = NULL; ++ } ++ ++ map = list->map; ++ if (map) { ++ drm_free(map, sizeof(*map), DRM_MEM_DRIVER); ++ list->map = NULL; ++ } + + drm_free(obj_priv->page_cpu_valid, 1, DRM_MEM_DRIVER); + drm_free(obj->driver_private, 1, DRM_MEM_DRIVER); +@@ -3050,7 +2919,7 @@ + return 0; + } + +-int ++static int + i915_gem_idle(struct drm_device *dev) + { + drm_i915_private_t *dev_priv = dev->dev_private; +@@ -3196,7 +3065,6 @@ + if (dev_priv->hw_status_page == NULL) { + DRM_ERROR("Failed to map status page.\n"); + memset(&dev_priv->hws_map, 0, sizeof(dev_priv->hws_map)); +- i915_gem_object_unpin(obj); + drm_gem_object_unreference(obj); + return -EINVAL; + } +@@ -3209,31 +3077,6 @@ + return 0; + } + +-static void +-i915_gem_cleanup_hws(struct drm_device *dev) +-{ +- drm_i915_private_t *dev_priv = dev->dev_private; +- struct drm_gem_object *obj; +- struct drm_i915_gem_object *obj_priv; +- +- if (dev_priv->hws_obj == NULL) +- return; +- +- obj = dev_priv->hws_obj; +- obj_priv = obj->driver_private; +- +- kunmap(obj_priv->page_list[0]); +- i915_gem_object_unpin(obj); +- drm_gem_object_unreference(obj); +- dev_priv->hws_obj = NULL; +- +- memset(&dev_priv->hws_map, 0, sizeof(dev_priv->hws_map)); +- dev_priv->hw_status_page = NULL; +- +- /* Write high address into HWS_PGA when disabling. */ +- I915_WRITE(HWS_PGA, 0x1ffff000); +-} +- + int + i915_gem_init_ringbuffer(struct drm_device *dev) + { +@@ -3251,7 +3094,6 @@ + obj = drm_gem_object_alloc(dev, 128 * 1024); + if (obj == NULL) { + DRM_ERROR("Failed to allocate ringbuffer\n"); +- i915_gem_cleanup_hws(dev); + return -ENOMEM; + } + obj_priv = obj->driver_private; +@@ -3259,7 +3101,6 @@ + ret = i915_gem_object_pin(obj, 4096); + if (ret != 0) { + drm_gem_object_unreference(obj); +- i915_gem_cleanup_hws(dev); + return ret; + } + +@@ -3277,9 +3118,7 @@ + if (ring->map.handle == NULL) { + DRM_ERROR("Failed to map ringbuffer.\n"); + memset(&dev_priv->ring, 0, sizeof(dev_priv->ring)); +- i915_gem_object_unpin(obj); + drm_gem_object_unreference(obj); +- i915_gem_cleanup_hws(dev); + return -EINVAL; + } + ring->ring_obj = obj; +@@ -3359,7 +3198,20 @@ + dev_priv->ring.ring_obj = NULL; + memset(&dev_priv->ring, 0, sizeof(dev_priv->ring)); + +- i915_gem_cleanup_hws(dev); ++ if (dev_priv->hws_obj != NULL) { ++ struct drm_gem_object *obj = dev_priv->hws_obj; ++ struct drm_i915_gem_object *obj_priv = obj->driver_private; ++ ++ kunmap(obj_priv->page_list[0]); ++ i915_gem_object_unpin(obj); ++ drm_gem_object_unreference(obj); ++ dev_priv->hws_obj = NULL; ++ memset(&dev_priv->hws_map, 0, sizeof(dev_priv->hws_map)); ++ dev_priv->hw_status_page = NULL; ++ ++ /* Write high address into HWS_PGA when disabling. */ ++ I915_WRITE(HWS_PGA, 0x1ffff000); ++ } + } + + int +@@ -3377,6 +3229,10 @@ + dev_priv->mm.wedged = 0; + } + ++ dev_priv->mm.gtt_mapping = io_mapping_create_wc(dev->agp->base, ++ dev->agp->agp_info.aper_size ++ * 1024 * 1024); ++ + mutex_lock(&dev->struct_mutex); + dev_priv->mm.suspended = 0; + +@@ -3399,6 +3255,7 @@ + i915_gem_leavevt_ioctl(struct drm_device *dev, void *data, + struct drm_file *file_priv) + { ++ drm_i915_private_t *dev_priv = dev->dev_private; + int ret; + + if (drm_core_check_feature(dev, DRIVER_MODESET)) +@@ -3407,6 +3264,7 @@ + ret = i915_gem_idle(dev); + drm_irq_uninstall(dev); + ++ io_mapping_free(dev_priv->mm.gtt_mapping); + return ret; + } + +@@ -3415,9 +3273,6 @@ + { + int ret; + +- if (drm_core_check_feature(dev, DRIVER_MODESET)) +- return; +- + ret = i915_gem_idle(dev); + if (ret) + DRM_ERROR("failed to idle hardware: %d\n", ret); +@@ -3439,7 +3294,7 @@ + /* Old X drivers will take 0-2 for front, back, depth buffers */ + dev_priv->fence_reg_start = 3; + +- if (IS_I965G(dev) || IS_I945G(dev) || IS_I945GM(dev) || IS_G33(dev)) ++ if (IS_I965G(dev)) + dev_priv->num_fence_regs = 16; + else + dev_priv->num_fence_regs = 8; +@@ -3615,7 +3470,7 @@ + user_data = (char __user *) (uintptr_t) args->data_ptr; + obj_addr = obj_priv->phys_obj->handle->vaddr + args->offset; + +- DRM_DEBUG("obj_addr %p, %lld\n", obj_addr, args->size); ++ DRM_ERROR("obj_addr %p, %lld\n", obj_addr, args->size); + ret = copy_from_user(obj_addr, user_data, args->size); + if (ret) + return -EFAULT; +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/drivers/gpu/drm/i915/i915_gem_tiling.c linux-2.6.29-rc3.owrt/drivers/gpu/drm/i915/i915_gem_tiling.c +--- linux-2.6.29.owrt/drivers/gpu/drm/i915/i915_gem_tiling.c 2009-05-10 22:04:38.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/drivers/gpu/drm/i915/i915_gem_tiling.c 2009-05-10 23:48:28.000000000 +0200 +@@ -173,73 +173,6 @@ + dev_priv->mm.bit_6_swizzle_y = swizzle_y; + } + +- +-/** +- * Returns the size of the fence for a tiled object of the given size. +- */ +-static int +-i915_get_fence_size(struct drm_device *dev, int size) +-{ +- int i; +- int start; +- +- if (IS_I965G(dev)) { +- /* The 965 can have fences at any page boundary. */ +- return ALIGN(size, 4096); +- } else { +- /* Align the size to a power of two greater than the smallest +- * fence size. +- */ +- if (IS_I9XX(dev)) +- start = 1024 * 1024; +- else +- start = 512 * 1024; +- +- for (i = start; i < size; i <<= 1) +- ; +- +- return i; +- } +-} +- +-/* Check pitch constriants for all chips & tiling formats */ +-static bool +-i915_tiling_ok(struct drm_device *dev, int stride, int size, int tiling_mode) +-{ +- int tile_width; +- +- /* Linear is always fine */ +- if (tiling_mode == I915_TILING_NONE) +- return true; +- +- if (tiling_mode == I915_TILING_Y && HAS_128_BYTE_Y_TILING(dev)) +- tile_width = 128; +- else +- tile_width = 512; +- +- /* 965+ just needs multiples of tile width */ +- if (IS_I965G(dev)) { +- if (stride & (tile_width - 1)) +- return false; +- return true; +- } +- +- /* Pre-965 needs power of two tile widths */ +- if (stride < tile_width) +- return false; +- +- if (stride & (stride - 1)) +- return false; +- +- /* We don't handle the aperture area covered by the fence being bigger +- * than the object size. +- */ +- if (i915_get_fence_size(dev, size) != size) +- return false; +- +- return true; +-} +- + /** + * Sets the tiling mode of an object, returning the required swizzling of + * bit 6 of addresses in the object. +@@ -258,11 +191,6 @@ + return -EINVAL; + obj_priv = obj->driver_private; + +- if (!i915_tiling_ok(dev, args->stride, obj->size, args->tiling_mode)) { +- drm_gem_object_unreference(obj); +- return -EINVAL; +- } +- + mutex_lock(&dev->struct_mutex); + + if (args->tiling_mode == I915_TILING_NONE) { +@@ -279,29 +207,13 @@ + args->swizzle_mode = I915_BIT_6_SWIZZLE_NONE; + } + } +- if (args->tiling_mode != obj_priv->tiling_mode) { +- int ret; +- +- /* Unbind the object, as switching tiling means we're +- * switching the cache organization due to fencing, probably. +- */ +- ret = i915_gem_object_unbind(obj); +- if (ret != 0) { +- WARN(ret != -ERESTARTSYS, +- "failed to unbind object for tiling switch"); +- args->tiling_mode = obj_priv->tiling_mode; +- mutex_unlock(&dev->struct_mutex); +- drm_gem_object_unreference(obj); +- +- return ret; +- } +- obj_priv->tiling_mode = args->tiling_mode; +- } ++ obj_priv->tiling_mode = args->tiling_mode; + obj_priv->stride = args->stride; + +- drm_gem_object_unreference(obj); + mutex_unlock(&dev->struct_mutex); + ++ drm_gem_object_unreference(obj); ++ + return 0; + } + +@@ -339,8 +251,9 @@ + DRM_ERROR("unknown tiling mode\n"); + } + +- drm_gem_object_unreference(obj); + mutex_unlock(&dev->struct_mutex); + ++ drm_gem_object_unreference(obj); ++ + return 0; + } +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/drivers/gpu/drm/i915/i915_irq.c linux-2.6.29-rc3.owrt/drivers/gpu/drm/i915/i915_irq.c +--- linux-2.6.29.owrt/drivers/gpu/drm/i915/i915_irq.c 2009-05-10 22:04:38.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/drivers/gpu/drm/i915/i915_irq.c 2009-05-10 23:48:28.000000000 +0200 +@@ -174,19 +174,6 @@ + return count; + } + +-u32 gm45_get_vblank_counter(struct drm_device *dev, int pipe) +-{ +- drm_i915_private_t *dev_priv = (drm_i915_private_t *) dev->dev_private; +- int reg = pipe ? PIPEB_FRMCOUNT_GM45 : PIPEA_FRMCOUNT_GM45; +- +- if (!i915_pipe_enabled(dev, pipe)) { +- DRM_ERROR("trying to get vblank count for disabled pipe %d\n", pipe); +- return 0; +- } +- +- return I915_READ(reg); +-} +- + irqreturn_t i915_driver_irq_handler(DRM_IRQ_ARGS) + { + struct drm_device *dev = (struct drm_device *) arg; +@@ -383,13 +370,12 @@ + drm_i915_irq_emit_t *emit = data; + int result; + ++ RING_LOCK_TEST_WITH_RETURN(dev, file_priv); ++ + if (!dev_priv) { + DRM_ERROR("called with no initialization\n"); + return -EINVAL; + } +- +- RING_LOCK_TEST_WITH_RETURN(dev, file_priv); +- + mutex_lock(&dev->struct_mutex); + result = i915_emit_irq(dev); + mutex_unlock(&dev->struct_mutex); +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/drivers/gpu/drm/i915/i915_reg.h linux-2.6.29-rc3.owrt/drivers/gpu/drm/i915/i915_reg.h +--- linux-2.6.29.owrt/drivers/gpu/drm/i915/i915_reg.h 2009-05-10 22:04:38.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/drivers/gpu/drm/i915/i915_reg.h 2009-05-10 23:48:28.000000000 +0200 +@@ -184,15 +184,14 @@ + * Fence registers + */ + #define FENCE_REG_830_0 0x2000 +-#define FENCE_REG_945_8 0x3000 + #define I830_FENCE_START_MASK 0x07f80000 + #define I830_FENCE_TILING_Y_SHIFT 12 +-#define I830_FENCE_SIZE_BITS(size) ((ffs((size) >> 19) - 1) << 8) ++#define I830_FENCE_SIZE_BITS(size) ((get_order(size >> 19) - 1) << 8) + #define I830_FENCE_PITCH_SHIFT 4 + #define I830_FENCE_REG_VALID (1<<0) + + #define I915_FENCE_START_MASK 0x0ff00000 +-#define I915_FENCE_SIZE_BITS(size) ((ffs((size) >> 20) - 1) << 8) ++#define I915_FENCE_SIZE_BITS(size) ((get_order(size >> 20) - 1) << 8) + + #define FENCE_REG_965_0 0x03000 + #define I965_FENCE_PITCH_SHIFT 2 +@@ -1372,9 +1371,6 @@ + #define PIPE_FRAME_LOW_SHIFT 24 + #define PIPE_PIXEL_MASK 0x00ffffff + #define PIPE_PIXEL_SHIFT 0 +-/* GM45+ just has to be different */ +-#define PIPEA_FRMCOUNT_GM45 0x70040 +-#define PIPEA_FLIPCOUNT_GM45 0x70044 + + /* Cursor A & B regs */ + #define CURACNTR 0x70080 +@@ -1443,9 +1439,6 @@ + #define PIPEBSTAT 0x71024 + #define PIPEBFRAMEHIGH 0x71040 + #define PIPEBFRAMEPIXEL 0x71044 +-#define PIPEB_FRMCOUNT_GM45 0x71040 +-#define PIPEB_FLIPCOUNT_GM45 0x71044 +- + + /* Display B control */ + #define DSPBCNTR 0x71180 +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/drivers/gpu/drm/i915/i915_suspend.c linux-2.6.29-rc3.owrt/drivers/gpu/drm/i915/i915_suspend.c +--- linux-2.6.29.owrt/drivers/gpu/drm/i915/i915_suspend.c 2009-05-10 22:04:38.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/drivers/gpu/drm/i915/i915_suspend.c 2009-05-10 23:48:28.000000000 +0200 +@@ -119,6 +119,11 @@ + + /* VGA color palette registers */ + dev_priv->saveDACMASK = I915_READ8(VGA_DACMASK); ++ /* DACCRX automatically increments during read */ ++ I915_WRITE8(VGA_DACRX, 0); ++ /* Read 3 bytes of color data from each index */ ++ for (i = 0; i < 256 * 3; i++) ++ dev_priv->saveDACDATA[i] = I915_READ8(VGA_DACDATA); + + /* MSR bits */ + dev_priv->saveMSR = I915_READ8(VGA_MSR_READ); +@@ -220,6 +225,12 @@ + + /* VGA color palette registers */ + I915_WRITE8(VGA_DACMASK, dev_priv->saveDACMASK); ++ /* DACCRX automatically increments during read */ ++ I915_WRITE8(VGA_DACWX, 0); ++ /* Read 3 bytes of color data from each index */ ++ for (i = 0; i < 256 * 3; i++) ++ I915_WRITE8(VGA_DACDATA, dev_priv->saveDACDATA[i]); ++ + } + + int i915_save_state(struct drm_device *dev) +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/drivers/gpu/drm/i915/intel_bios.c linux-2.6.29-rc3.owrt/drivers/gpu/drm/i915/intel_bios.c +--- linux-2.6.29.owrt/drivers/gpu/drm/i915/intel_bios.c 2009-05-10 22:04:38.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/drivers/gpu/drm/i915/intel_bios.c 2009-05-10 23:48:28.000000000 +0200 +@@ -111,12 +111,6 @@ + panel_fixed_mode->clock = dvo_timing->clock * 10; + panel_fixed_mode->type = DRM_MODE_TYPE_PREFERRED; + +- /* Some VBTs have bogus h/vtotal values */ +- if (panel_fixed_mode->hsync_end > panel_fixed_mode->htotal) +- panel_fixed_mode->htotal = panel_fixed_mode->hsync_end + 1; +- if (panel_fixed_mode->vsync_end > panel_fixed_mode->vtotal) +- panel_fixed_mode->vtotal = panel_fixed_mode->vsync_end + 1; +- + drm_mode_set_name(panel_fixed_mode); + + dev_priv->vbt_mode = panel_fixed_mode; +@@ -141,14 +135,6 @@ + if (general) { + dev_priv->int_tv_support = general->int_tv_support; + dev_priv->int_crt_support = general->int_crt_support; +- dev_priv->lvds_use_ssc = general->enable_ssc; +- +- if (dev_priv->lvds_use_ssc) { +- if (IS_I855(dev_priv->dev)) +- dev_priv->lvds_ssc_freq = general->ssc_freq ? 66 : 48; +- else +- dev_priv->lvds_ssc_freq = general->ssc_freq ? 100 : 96; +- } + } + } + +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/drivers/gpu/drm/i915/intel_display.c linux-2.6.29-rc3.owrt/drivers/gpu/drm/i915/intel_display.c +--- linux-2.6.29.owrt/drivers/gpu/drm/i915/intel_display.c 2009-05-10 22:04:38.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/drivers/gpu/drm/i915/intel_display.c 2009-05-10 23:48:28.000000000 +0200 +@@ -90,12 +90,12 @@ + #define I9XX_DOT_MAX 400000 + #define I9XX_VCO_MIN 1400000 + #define I9XX_VCO_MAX 2800000 +-#define I9XX_N_MIN 1 +-#define I9XX_N_MAX 6 ++#define I9XX_N_MIN 3 ++#define I9XX_N_MAX 8 + #define I9XX_M_MIN 70 + #define I9XX_M_MAX 120 + #define I9XX_M1_MIN 10 +-#define I9XX_M1_MAX 22 ++#define I9XX_M1_MAX 20 + #define I9XX_M2_MIN 5 + #define I9XX_M2_MAX 9 + #define I9XX_P_SDVO_DAC_MIN 5 +@@ -189,7 +189,9 @@ + return limit; + } + +-static void intel_clock(int refclk, intel_clock_t *clock) ++/** Derive the pixel clock for the given refclk and divisors for 8xx chips. */ ++ ++static void i8xx_clock(int refclk, intel_clock_t *clock) + { + clock->m = 5 * (clock->m1 + 2) + (clock->m2 + 2); + clock->p = clock->p1 * clock->p2; +@@ -197,6 +199,25 @@ + clock->dot = clock->vco / clock->p; + } + ++/** Derive the pixel clock for the given refclk and divisors for 9xx chips. */ ++ ++static void i9xx_clock(int refclk, intel_clock_t *clock) ++{ ++ clock->m = 5 * (clock->m1 + 2) + (clock->m2 + 2); ++ clock->p = clock->p1 * clock->p2; ++ clock->vco = refclk * clock->m / (clock->n + 2); ++ clock->dot = clock->vco / clock->p; ++} ++ ++static void intel_clock(struct drm_device *dev, int refclk, ++ intel_clock_t *clock) ++{ ++ if (IS_I9XX(dev)) ++ i9xx_clock (refclk, clock); ++ else ++ i8xx_clock (refclk, clock); ++} ++ + /** + * Returns whether any output on the specified pipe is of the specified type + */ +@@ -217,7 +238,7 @@ + return false; + } + +-#define INTELPllInvalid(s) do { /* DRM_DEBUG(s); */ return false; } while (0) ++#define INTELPllInvalid(s) { /* ErrorF (s) */; return false; } + /** + * Returns whether the given set of divisors are valid for a given refclk with + * the given connectors. +@@ -297,7 +318,7 @@ + clock.p1 <= limit->p1.max; clock.p1++) { + int this_err; + +- intel_clock(refclk, &clock); ++ intel_clock(dev, refclk, &clock); + + if (!intel_PLL_is_valid(crtc, &clock)) + continue; +@@ -322,7 +343,7 @@ + udelay(20000); + } + +-static int ++static void + intel_pipe_set_base(struct drm_crtc *crtc, int x, int y, + struct drm_framebuffer *old_fb) + { +@@ -340,21 +361,11 @@ + int dspstride = (pipe == 0) ? DSPASTRIDE : DSPBSTRIDE; + int dspcntr_reg = (pipe == 0) ? DSPACNTR : DSPBCNTR; + u32 dspcntr, alignment; +- int ret; + + /* no fb bound */ + if (!crtc->fb) { + DRM_DEBUG("No FB bound\n"); +- return 0; +- } +- +- switch (pipe) { +- case 0: +- case 1: +- break; +- default: +- DRM_ERROR("Can't update pipe %d in SAREA\n", pipe); +- return -EINVAL; ++ return; + } + + intel_fb = to_intel_framebuffer(crtc->fb); +@@ -366,30 +377,28 @@ + alignment = 64 * 1024; + break; + case I915_TILING_X: +- /* pin() will align the object as required by fence */ +- alignment = 0; ++ if (IS_I9XX(dev)) ++ alignment = 1024 * 1024; ++ else ++ alignment = 512 * 1024; + break; + case I915_TILING_Y: + /* FIXME: Is this true? */ + DRM_ERROR("Y tiled not allowed for scan out buffers\n"); +- return -EINVAL; ++ return; + default: + BUG(); + } + +- mutex_lock(&dev->struct_mutex); +- ret = i915_gem_object_pin(intel_fb->obj, alignment); +- if (ret != 0) { +- mutex_unlock(&dev->struct_mutex); +- return ret; +- } ++ if (i915_gem_object_pin(intel_fb->obj, alignment)) ++ return; + +- ret = i915_gem_object_set_to_gtt_domain(intel_fb->obj, 1); +- if (ret != 0) { +- i915_gem_object_unpin(intel_fb->obj); +- mutex_unlock(&dev->struct_mutex); +- return ret; +- } ++ i915_gem_object_set_to_gtt_domain(intel_fb->obj, 1); ++ ++ Start = obj_priv->gtt_offset; ++ Offset = y * crtc->fb->pitch + x * (crtc->fb->bits_per_pixel / 8); ++ ++ I915_WRITE(dspstride, crtc->fb->pitch); + + dspcntr = I915_READ(dspcntr_reg); + /* Mask out pixel format bits in case we change it */ +@@ -410,17 +419,11 @@ + break; + default: + DRM_ERROR("Unknown color depth\n"); +- i915_gem_object_unpin(intel_fb->obj); +- mutex_unlock(&dev->struct_mutex); +- return -EINVAL; ++ return; + } + I915_WRITE(dspcntr_reg, dspcntr); + +- Start = obj_priv->gtt_offset; +- Offset = y * crtc->fb->pitch + x * (crtc->fb->bits_per_pixel / 8); +- + DRM_DEBUG("Writing base %08lX %08lX %d %d\n", Start, Offset, x, y); +- I915_WRITE(dspstride, crtc->fb->pitch); + if (IS_I965G(dev)) { + I915_WRITE(dspbase, Offset); + I915_READ(dspbase); +@@ -437,24 +440,27 @@ + intel_fb = to_intel_framebuffer(old_fb); + i915_gem_object_unpin(intel_fb->obj); + } +- mutex_unlock(&dev->struct_mutex); + + if (!dev->primary->master) +- return 0; ++ return; + + master_priv = dev->primary->master->driver_priv; + if (!master_priv->sarea_priv) +- return 0; ++ return; + +- if (pipe) { +- master_priv->sarea_priv->pipeB_x = x; +- master_priv->sarea_priv->pipeB_y = y; +- } else { ++ switch (pipe) { ++ case 0: + master_priv->sarea_priv->pipeA_x = x; + master_priv->sarea_priv->pipeA_y = y; ++ break; ++ case 1: ++ master_priv->sarea_priv->pipeB_x = x; ++ master_priv->sarea_priv->pipeB_y = y; ++ break; ++ default: ++ DRM_ERROR("Can't update pipe %d in SAREA\n", pipe); ++ break; + } +- +- return 0; + } + + +@@ -702,11 +708,11 @@ + return 1; + } + +-static int intel_crtc_mode_set(struct drm_crtc *crtc, +- struct drm_display_mode *mode, +- struct drm_display_mode *adjusted_mode, +- int x, int y, +- struct drm_framebuffer *old_fb) ++static void intel_crtc_mode_set(struct drm_crtc *crtc, ++ struct drm_display_mode *mode, ++ struct drm_display_mode *adjusted_mode, ++ int x, int y, ++ struct drm_framebuffer *old_fb) + { + struct drm_device *dev = crtc->dev; + struct drm_i915_private *dev_priv = dev->dev_private; +@@ -726,14 +732,13 @@ + int dspsize_reg = (pipe == 0) ? DSPASIZE : DSPBSIZE; + int dsppos_reg = (pipe == 0) ? DSPAPOS : DSPBPOS; + int pipesrc_reg = (pipe == 0) ? PIPEASRC : PIPEBSRC; +- int refclk, num_outputs = 0; ++ int refclk; + intel_clock_t clock; + u32 dpll = 0, fp = 0, dspcntr, pipeconf; + bool ok, is_sdvo = false, is_dvo = false; + bool is_crt = false, is_lvds = false, is_tv = false; + struct drm_mode_config *mode_config = &dev->mode_config; + struct drm_connector *connector; +- int ret; + + drm_vblank_pre_modeset(dev, pipe); + +@@ -750,8 +755,6 @@ + case INTEL_OUTPUT_SDVO: + case INTEL_OUTPUT_HDMI: + is_sdvo = true; +- if (intel_output->needs_tv_clock) +- is_tv = true; + break; + case INTEL_OUTPUT_DVO: + is_dvo = true; +@@ -763,14 +766,9 @@ + is_crt = true; + break; + } +- +- num_outputs++; + } + +- if (is_lvds && dev_priv->lvds_use_ssc && num_outputs < 2) { +- refclk = dev_priv->lvds_ssc_freq * 1000; +- DRM_DEBUG("using SSC reference clock of %d MHz\n", refclk / 1000); +- } else if (IS_I9XX(dev)) { ++ if (IS_I9XX(dev)) { + refclk = 96000; + } else { + refclk = 48000; +@@ -779,7 +777,7 @@ + ok = intel_find_best_PLL(crtc, adjusted_mode->clock, refclk, &clock); + if (!ok) { + DRM_ERROR("Couldn't find PLL settings for mode!\n"); +- return -EINVAL; ++ return; + } + + fp = clock.n << 16 | clock.m1 << 8 | clock.m2; +@@ -829,14 +827,11 @@ + } + } + +- if (is_sdvo && is_tv) +- dpll |= PLL_REF_INPUT_TVCLKINBC; +- else if (is_tv) ++ if (is_tv) { + /* XXX: just matching BIOS for now */ +- /* dpll |= PLL_REF_INPUT_TVCLKINBC; */ ++/* dpll |= PLL_REF_INPUT_TVCLKINBC; */ + dpll |= 3; +- else if (is_lvds && dev_priv->lvds_use_ssc && num_outputs < 2) +- dpll |= PLLB_REF_INPUT_SPREADSPECTRUMIN; ++ } + else + dpll |= PLL_REF_INPUT_DREFCLK; + +@@ -953,13 +948,9 @@ + I915_WRITE(dspcntr_reg, dspcntr); + + /* Flush the plane changes */ +- ret = intel_pipe_set_base(crtc, x, y, old_fb); +- if (ret != 0) +- return ret; ++ intel_pipe_set_base(crtc, x, y, old_fb); + + drm_vblank_post_modeset(dev, pipe); +- +- return 0; + } + + /** Loads the palette/gamma unit for the CRTC with the prepared values */ +@@ -1008,7 +999,6 @@ + temp = CURSOR_MODE_DISABLE; + addr = 0; + bo = NULL; +- mutex_lock(&dev->struct_mutex); + goto finish; + } + +@@ -1031,19 +1021,18 @@ + } + + /* we only need to pin inside GTT if cursor is non-phy */ +- mutex_lock(&dev->struct_mutex); + if (!dev_priv->cursor_needs_physical) { + ret = i915_gem_object_pin(bo, PAGE_SIZE); + if (ret) { + DRM_ERROR("failed to pin cursor bo\n"); +- goto fail_locked; ++ goto fail; + } + addr = obj_priv->gtt_offset; + } else { + ret = i915_gem_attach_phys_object(dev, bo, (pipe == 0) ? I915_GEM_PHYS_CURSOR_0 : I915_GEM_PHYS_CURSOR_1); + if (ret) { + DRM_ERROR("failed to attach phys object\n"); +- goto fail_locked; ++ goto fail; + } + addr = obj_priv->phys_obj->handle->busaddr; + } +@@ -1063,9 +1052,10 @@ + i915_gem_detach_phys_object(dev, intel_crtc->cursor_bo); + } else + i915_gem_object_unpin(intel_crtc->cursor_bo); ++ mutex_lock(&dev->struct_mutex); + drm_gem_object_unreference(intel_crtc->cursor_bo); ++ mutex_unlock(&dev->struct_mutex); + } +- mutex_unlock(&dev->struct_mutex); + + intel_crtc->cursor_addr = addr; + intel_crtc->cursor_bo = bo; +@@ -1073,7 +1063,6 @@ + return 0; + fail: + mutex_lock(&dev->struct_mutex); +-fail_locked: + drm_gem_object_unreference(bo); + mutex_unlock(&dev->struct_mutex); + return ret; +@@ -1301,7 +1290,7 @@ + } + + /* XXX: Handle the 100Mhz refclk */ +- intel_clock(96000, &clock); ++ i9xx_clock(96000, &clock); + } else { + bool is_lvds = (pipe == 1) && (I915_READ(LVDS) & LVDS_PORT_EN); + +@@ -1313,9 +1302,9 @@ + if ((dpll & PLL_REF_INPUT_MASK) == + PLLB_REF_INPUT_SPREADSPECTRUMIN) { + /* XXX: might not be 66MHz */ +- intel_clock(66000, &clock); ++ i8xx_clock(66000, &clock); + } else +- intel_clock(48000, &clock); ++ i8xx_clock(48000, &clock); + } else { + if (dpll & PLL_P1_DIVIDE_BY_TWO) + clock.p1 = 2; +@@ -1328,7 +1317,7 @@ + else + clock.p2 = 2; + +- intel_clock(48000, &clock); ++ i8xx_clock(48000, &clock); + } + } + +@@ -1463,7 +1452,6 @@ + + static void intel_setup_outputs(struct drm_device *dev) + { +- struct drm_i915_private *dev_priv = dev->dev_private; + struct drm_connector *connector; + + intel_crt_init(dev); +@@ -1475,16 +1463,13 @@ + if (IS_I9XX(dev)) { + int found; + +- if (I915_READ(SDVOB) & SDVO_DETECTED) { +- found = intel_sdvo_init(dev, SDVOB); +- if (!found && SUPPORTS_INTEGRATED_HDMI(dev)) +- intel_hdmi_init(dev, SDVOB); +- } +- if (!IS_G4X(dev) || (I915_READ(SDVOB) & SDVO_DETECTED)) { +- found = intel_sdvo_init(dev, SDVOC); +- if (!found && SUPPORTS_INTEGRATED_HDMI(dev)) +- intel_hdmi_init(dev, SDVOC); +- } ++ found = intel_sdvo_init(dev, SDVOB); ++ if (!found && SUPPORTS_INTEGRATED_HDMI(dev)) ++ intel_hdmi_init(dev, SDVOB); ++ ++ found = intel_sdvo_init(dev, SDVOC); ++ if (!found && SUPPORTS_INTEGRATED_HDMI(dev)) ++ intel_hdmi_init(dev, SDVOC); + } else + intel_dvo_init(dev); + +@@ -1607,9 +1592,7 @@ + + ret = intel_framebuffer_create(dev, mode_cmd, &fb, obj); + if (ret) { +- mutex_lock(&dev->struct_mutex); + drm_gem_object_unreference(obj); +- mutex_unlock(&dev->struct_mutex); + return NULL; + } + +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/drivers/gpu/drm/i915/intel_drv.h linux-2.6.29-rc3.owrt/drivers/gpu/drm/i915/intel_drv.h +--- linux-2.6.29.owrt/drivers/gpu/drm/i915/intel_drv.h 2009-05-10 22:04:38.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/drivers/gpu/drm/i915/intel_drv.h 2009-05-10 23:48:28.000000000 +0200 +@@ -82,7 +82,6 @@ + struct intel_i2c_chan *i2c_bus; /* for control functions */ + struct intel_i2c_chan *ddc_bus; /* for DDC only stuff */ + bool load_detect_temp; +- bool needs_tv_clock; + void *dev_priv; + }; + +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/drivers/gpu/drm/i915/intel_fb.c linux-2.6.29-rc3.owrt/drivers/gpu/drm/i915/intel_fb.c +--- linux-2.6.29.owrt/drivers/gpu/drm/i915/intel_fb.c 2009-05-10 22:04:38.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/drivers/gpu/drm/i915/intel_fb.c 2009-05-10 23:48:28.000000000 +0200 +@@ -473,7 +473,7 @@ + ret = intel_framebuffer_create(dev, &mode_cmd, &fb, fbo); + if (ret) { + DRM_ERROR("failed to allocate fb.\n"); +- goto out_unpin; ++ goto out_unref; + } + + list_add(&fb->filp_head, &dev->mode_config.fb_kernel_list); +@@ -484,7 +484,7 @@ + info = framebuffer_alloc(sizeof(struct intelfb_par), device); + if (!info) { + ret = -ENOMEM; +- goto out_unpin; ++ goto out_unref; + } + + par = info->par; +@@ -513,7 +513,7 @@ + size); + if (!info->screen_base) { + ret = -ENOSPC; +- goto out_unpin; ++ goto out_unref; + } + info->screen_size = size; + +@@ -608,8 +608,6 @@ + mutex_unlock(&dev->struct_mutex); + return 0; + +-out_unpin: +- i915_gem_object_unpin(fbo); + out_unref: + drm_gem_object_unreference(fbo); + mutex_unlock(&dev->struct_mutex); +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/drivers/gpu/drm/i915/intel_lvds.c linux-2.6.29-rc3.owrt/drivers/gpu/drm/i915/intel_lvds.c +--- linux-2.6.29.owrt/drivers/gpu/drm/i915/intel_lvds.c 2009-05-10 22:04:38.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/drivers/gpu/drm/i915/intel_lvds.c 2009-05-10 23:48:28.000000000 +0200 +@@ -27,7 +27,6 @@ + * Jesse Barnes <jesse.barnes@intel.com> + */ + +-#include <linux/dmi.h> + #include <linux/i2c.h> + #include "drmP.h" + #include "drm.h" +@@ -312,8 +311,10 @@ + if (dev_priv->panel_fixed_mode != NULL) { + struct drm_display_mode *mode; + ++ mutex_unlock(&dev->mode_config.mutex); + mode = drm_mode_duplicate(dev, dev_priv->panel_fixed_mode); + drm_mode_probed_add(connector, mode); ++ mutex_unlock(&dev->mode_config.mutex); + + return 1; + } +@@ -404,16 +405,6 @@ + u32 lvds; + int pipe; + +- /* Blacklist machines that we know falsely report LVDS. */ +- /* FIXME: add a check for the Aopen Mini PC */ +- +- /* Apple Mac Mini Core Duo and Mac Mini Core 2 Duo */ +- if(dmi_match(DMI_PRODUCT_NAME, "Macmini1,1") || +- dmi_match(DMI_PRODUCT_NAME, "Macmini2,1")) { +- DRM_DEBUG("Skipping LVDS initialization for Apple Mac Mini\n"); +- return; +- } +- + intel_output = kzalloc(sizeof(struct intel_output), GFP_KERNEL); + if (!intel_output) { + return; +@@ -467,7 +458,7 @@ + dev_priv->panel_fixed_mode = + drm_mode_duplicate(dev, scan); + mutex_unlock(&dev->mode_config.mutex); +- goto out; ++ goto out; /* FIXME: check for quirks */ + } + mutex_unlock(&dev->mode_config.mutex); + } +@@ -481,6 +472,8 @@ + if (dev_priv->panel_fixed_mode) { + dev_priv->panel_fixed_mode->type |= + DRM_MODE_TYPE_PREFERRED; ++ drm_mode_probed_add(connector, ++ dev_priv->panel_fixed_mode); + goto out; + } + } +@@ -499,7 +492,7 @@ + if (dev_priv->panel_fixed_mode) { + dev_priv->panel_fixed_mode->type |= + DRM_MODE_TYPE_PREFERRED; +- goto out; ++ goto out; /* FIXME: check for quirks */ + } + } + +@@ -507,6 +500,38 @@ + if (!dev_priv->panel_fixed_mode) + goto failed; + ++ /* FIXME: detect aopen & mac mini type stuff automatically? */ ++ /* ++ * Blacklist machines with BIOSes that list an LVDS panel without ++ * actually having one. ++ */ ++ if (IS_I945GM(dev)) { ++ /* aopen mini pc */ ++ if (dev->pdev->subsystem_vendor == 0xa0a0) ++ goto failed; ++ ++ if ((dev->pdev->subsystem_vendor == 0x8086) && ++ (dev->pdev->subsystem_device == 0x7270)) { ++ /* It's a Mac Mini or Macbook Pro. ++ * ++ * Apple hardware is out to get us. The macbook pro ++ * has a real LVDS panel, but the mac mini does not, ++ * and they have the same device IDs. We'll ++ * distinguish by panel size, on the assumption ++ * that Apple isn't about to make any machines with an ++ * 800x600 display. ++ */ ++ ++ if (dev_priv->panel_fixed_mode != NULL && ++ dev_priv->panel_fixed_mode->hdisplay == 800 && ++ dev_priv->panel_fixed_mode->vdisplay == 600) { ++ DRM_DEBUG("Suspected Mac Mini, ignoring the LVDS\n"); ++ goto failed; ++ } ++ } ++ } ++ ++ + out: + drm_sysfs_connector_add(connector); + return; +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/drivers/gpu/drm/i915/intel_sdvo.c linux-2.6.29-rc3.owrt/drivers/gpu/drm/i915/intel_sdvo.c +--- linux-2.6.29.owrt/drivers/gpu/drm/i915/intel_sdvo.c 2009-05-10 22:04:38.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/drivers/gpu/drm/i915/intel_sdvo.c 2009-05-10 23:48:28.000000000 +0200 +@@ -40,59 +40,13 @@ + struct intel_sdvo_priv { + struct intel_i2c_chan *i2c_bus; + int slaveaddr; +- +- /* Register for the SDVO device: SDVOB or SDVOC */ + int output_device; + +- /* Active outputs controlled by this SDVO output */ +- uint16_t controlled_output; ++ u16 active_outputs; + +- /* +- * Capabilities of the SDVO device returned by +- * i830_sdvo_get_capabilities() +- */ + struct intel_sdvo_caps caps; +- +- /* Pixel clock limitations reported by the SDVO device, in kHz */ + int pixel_clock_min, pixel_clock_max; + +- /** +- * This is set if we're going to treat the device as TV-out. +- * +- * While we have these nice friendly flags for output types that ought +- * to decide this for us, the S-Video output on our HDMI+S-Video card +- * shows up as RGB1 (VGA). +- */ +- bool is_tv; +- +- /** +- * This is set if we treat the device as HDMI, instead of DVI. +- */ +- bool is_hdmi; +- +- /** +- * Returned SDTV resolutions allowed for the current format, if the +- * device reported it. +- */ +- struct intel_sdvo_sdtv_resolution_reply sdtv_resolutions; +- +- /** +- * Current selected TV format. +- * +- * This is stored in the same structure that's passed to the device, for +- * convenience. +- */ +- struct intel_sdvo_tv_format tv_format; +- +- /* +- * supported encoding mode, used to determine whether HDMI is +- * supported +- */ +- struct intel_sdvo_encode encode; +- +- /* DDC bus used by this SDVO output */ +- uint8_t ddc_bus; +- + int save_sdvo_mult; + u16 save_active_outputs; + struct intel_sdvo_dtd save_input_dtd_1, save_input_dtd_2; +@@ -193,9 +147,9 @@ + + #define SDVO_CMD_NAME_ENTRY(cmd) {cmd, #cmd} + /** Mapping of command numbers to names, for debug output */ +-static const struct _sdvo_cmd_name { +- u8 cmd; +- char *name; ++const static struct _sdvo_cmd_name { ++ u8 cmd; ++ char *name; + } sdvo_cmd_names[] = { + SDVO_CMD_NAME_ENTRY(SDVO_CMD_RESET), + SDVO_CMD_NAME_ENTRY(SDVO_CMD_GET_DEVICE_CAPS), +@@ -232,35 +186,8 @@ + SDVO_CMD_NAME_ENTRY(SDVO_CMD_GET_SUPPORTED_TV_FORMATS), + SDVO_CMD_NAME_ENTRY(SDVO_CMD_GET_TV_FORMAT), + SDVO_CMD_NAME_ENTRY(SDVO_CMD_SET_TV_FORMAT), +- SDVO_CMD_NAME_ENTRY(SDVO_CMD_GET_SUPPORTED_POWER_STATES), +- SDVO_CMD_NAME_ENTRY(SDVO_CMD_GET_POWER_STATE), +- SDVO_CMD_NAME_ENTRY(SDVO_CMD_SET_ENCODER_POWER_STATE), +- SDVO_CMD_NAME_ENTRY(SDVO_CMD_SET_DISPLAY_POWER_STATE), ++ SDVO_CMD_NAME_ENTRY(SDVO_CMD_SET_TV_RESOLUTION_SUPPORT), + SDVO_CMD_NAME_ENTRY(SDVO_CMD_SET_CONTROL_BUS_SWITCH), +- SDVO_CMD_NAME_ENTRY(SDVO_CMD_GET_SDTV_RESOLUTION_SUPPORT), +- SDVO_CMD_NAME_ENTRY(SDVO_CMD_GET_SCALED_HDTV_RESOLUTION_SUPPORT), +- SDVO_CMD_NAME_ENTRY(SDVO_CMD_GET_SUPPORTED_ENHANCEMENTS), +- /* HDMI op code */ +- SDVO_CMD_NAME_ENTRY(SDVO_CMD_GET_SUPP_ENCODE), +- SDVO_CMD_NAME_ENTRY(SDVO_CMD_GET_ENCODE), +- SDVO_CMD_NAME_ENTRY(SDVO_CMD_SET_ENCODE), +- SDVO_CMD_NAME_ENTRY(SDVO_CMD_SET_PIXEL_REPLI), +- SDVO_CMD_NAME_ENTRY(SDVO_CMD_GET_PIXEL_REPLI), +- SDVO_CMD_NAME_ENTRY(SDVO_CMD_GET_COLORIMETRY_CAP), +- SDVO_CMD_NAME_ENTRY(SDVO_CMD_SET_COLORIMETRY), +- SDVO_CMD_NAME_ENTRY(SDVO_CMD_GET_COLORIMETRY), +- SDVO_CMD_NAME_ENTRY(SDVO_CMD_GET_AUDIO_ENCRYPT_PREFER), +- SDVO_CMD_NAME_ENTRY(SDVO_CMD_SET_AUDIO_STAT), +- SDVO_CMD_NAME_ENTRY(SDVO_CMD_GET_AUDIO_STAT), +- SDVO_CMD_NAME_ENTRY(SDVO_CMD_GET_HBUF_INDEX), +- SDVO_CMD_NAME_ENTRY(SDVO_CMD_SET_HBUF_INDEX), +- SDVO_CMD_NAME_ENTRY(SDVO_CMD_GET_HBUF_INFO), +- SDVO_CMD_NAME_ENTRY(SDVO_CMD_GET_HBUF_AV_SPLIT), +- SDVO_CMD_NAME_ENTRY(SDVO_CMD_SET_HBUF_AV_SPLIT), +- SDVO_CMD_NAME_ENTRY(SDVO_CMD_GET_HBUF_TXRATE), +- SDVO_CMD_NAME_ENTRY(SDVO_CMD_SET_HBUF_TXRATE), +- SDVO_CMD_NAME_ENTRY(SDVO_CMD_SET_HBUF_DATA), +- SDVO_CMD_NAME_ENTRY(SDVO_CMD_GET_HBUF_DATA), + }; + + #define SDVO_NAME(dev_priv) ((dev_priv)->output_device == SDVOB ? "SDVOB" : "SDVOC") +@@ -579,50 +506,6 @@ + SDVO_CMD_SET_OUTPUT_TIMINGS_PART1, dtd); + } + +-static bool +-intel_sdvo_create_preferred_input_timing(struct intel_output *output, +- uint16_t clock, +- uint16_t width, +- uint16_t height) +-{ +- struct intel_sdvo_preferred_input_timing_args args; +- uint8_t status; +- +- args.clock = clock; +- args.width = width; +- args.height = height; +- intel_sdvo_write_cmd(output, SDVO_CMD_CREATE_PREFERRED_INPUT_TIMING, +- &args, sizeof(args)); +- status = intel_sdvo_read_response(output, NULL, 0); +- if (status != SDVO_CMD_STATUS_SUCCESS) +- return false; +- +- return true; +-} +- +-static bool intel_sdvo_get_preferred_input_timing(struct intel_output *output, +- struct intel_sdvo_dtd *dtd) +-{ +- bool status; +- +- intel_sdvo_write_cmd(output, SDVO_CMD_GET_PREFERRED_INPUT_TIMING_PART1, +- NULL, 0); +- +- status = intel_sdvo_read_response(output, &dtd->part1, +- sizeof(dtd->part1)); +- if (status != SDVO_CMD_STATUS_SUCCESS) +- return false; +- +- intel_sdvo_write_cmd(output, SDVO_CMD_GET_PREFERRED_INPUT_TIMING_PART2, +- NULL, 0); +- +- status = intel_sdvo_read_response(output, &dtd->part2, +- sizeof(dtd->part2)); +- if (status != SDVO_CMD_STATUS_SUCCESS) +- return false; +- +- return false; +-} + + static int intel_sdvo_get_clock_rate_mult(struct intel_output *intel_output) + { +@@ -653,12 +536,36 @@ + return true; + } + +-static void intel_sdvo_get_dtd_from_mode(struct intel_sdvo_dtd *dtd, +- struct drm_display_mode *mode) ++static bool intel_sdvo_mode_fixup(struct drm_encoder *encoder, ++ struct drm_display_mode *mode, ++ struct drm_display_mode *adjusted_mode) + { +- uint16_t width, height; +- uint16_t h_blank_len, h_sync_len, v_blank_len, v_sync_len; +- uint16_t h_sync_offset, v_sync_offset; ++ /* Make the CRTC code factor in the SDVO pixel multiplier. The SDVO ++ * device will be told of the multiplier during mode_set. ++ */ ++ adjusted_mode->clock *= intel_sdvo_get_pixel_multiplier(mode); ++ return true; ++} ++ ++static void intel_sdvo_mode_set(struct drm_encoder *encoder, ++ struct drm_display_mode *mode, ++ struct drm_display_mode *adjusted_mode) ++{ ++ struct drm_device *dev = encoder->dev; ++ struct drm_i915_private *dev_priv = dev->dev_private; ++ struct drm_crtc *crtc = encoder->crtc; ++ struct intel_crtc *intel_crtc = to_intel_crtc(crtc); ++ struct intel_output *intel_output = enc_to_intel_output(encoder); ++ struct intel_sdvo_priv *sdvo_priv = intel_output->dev_priv; ++ u16 width, height; ++ u16 h_blank_len, h_sync_len, v_blank_len, v_sync_len; ++ u16 h_sync_offset, v_sync_offset; ++ u32 sdvox; ++ struct intel_sdvo_dtd output_dtd; ++ int sdvo_pixel_multiply; ++ ++ if (!mode) ++ return; + + width = mode->crtc_hdisplay; + height = mode->crtc_vdisplay; +@@ -673,423 +580,93 @@ + h_sync_offset = mode->crtc_hsync_start - mode->crtc_hblank_start; + v_sync_offset = mode->crtc_vsync_start - mode->crtc_vblank_start; + +- dtd->part1.clock = mode->clock / 10; +- dtd->part1.h_active = width & 0xff; +- dtd->part1.h_blank = h_blank_len & 0xff; +- dtd->part1.h_high = (((width >> 8) & 0xf) << 4) | ++ output_dtd.part1.clock = mode->clock / 10; ++ output_dtd.part1.h_active = width & 0xff; ++ output_dtd.part1.h_blank = h_blank_len & 0xff; ++ output_dtd.part1.h_high = (((width >> 8) & 0xf) << 4) | + ((h_blank_len >> 8) & 0xf); +- dtd->part1.v_active = height & 0xff; +- dtd->part1.v_blank = v_blank_len & 0xff; +- dtd->part1.v_high = (((height >> 8) & 0xf) << 4) | ++ output_dtd.part1.v_active = height & 0xff; ++ output_dtd.part1.v_blank = v_blank_len & 0xff; ++ output_dtd.part1.v_high = (((height >> 8) & 0xf) << 4) | + ((v_blank_len >> 8) & 0xf); + +- dtd->part2.h_sync_off = h_sync_offset; +- dtd->part2.h_sync_width = h_sync_len & 0xff; +- dtd->part2.v_sync_off_width = (v_sync_offset & 0xf) << 4 | ++ output_dtd.part2.h_sync_off = h_sync_offset; ++ output_dtd.part2.h_sync_width = h_sync_len & 0xff; ++ output_dtd.part2.v_sync_off_width = (v_sync_offset & 0xf) << 4 | + (v_sync_len & 0xf); +- dtd->part2.sync_off_width_high = ((h_sync_offset & 0x300) >> 2) | ++ output_dtd.part2.sync_off_width_high = ((h_sync_offset & 0x300) >> 2) | + ((h_sync_len & 0x300) >> 4) | ((v_sync_offset & 0x30) >> 2) | + ((v_sync_len & 0x30) >> 4); + +- dtd->part2.dtd_flags = 0x18; ++ output_dtd.part2.dtd_flags = 0x18; + if (mode->flags & DRM_MODE_FLAG_PHSYNC) +- dtd->part2.dtd_flags |= 0x2; ++ output_dtd.part2.dtd_flags |= 0x2; + if (mode->flags & DRM_MODE_FLAG_PVSYNC) +- dtd->part2.dtd_flags |= 0x4; +- +- dtd->part2.sdvo_flags = 0; +- dtd->part2.v_sync_off_high = v_sync_offset & 0xc0; +- dtd->part2.reserved = 0; +-} +- +-static void intel_sdvo_get_mode_from_dtd(struct drm_display_mode * mode, +- struct intel_sdvo_dtd *dtd) +-{ +- uint16_t width, height; +- uint16_t h_blank_len, h_sync_len, v_blank_len, v_sync_len; +- uint16_t h_sync_offset, v_sync_offset; +- +- width = mode->crtc_hdisplay; +- height = mode->crtc_vdisplay; +- +- /* do some mode translations */ +- h_blank_len = mode->crtc_hblank_end - mode->crtc_hblank_start; +- h_sync_len = mode->crtc_hsync_end - mode->crtc_hsync_start; +- +- v_blank_len = mode->crtc_vblank_end - mode->crtc_vblank_start; +- v_sync_len = mode->crtc_vsync_end - mode->crtc_vsync_start; +- +- h_sync_offset = mode->crtc_hsync_start - mode->crtc_hblank_start; +- v_sync_offset = mode->crtc_vsync_start - mode->crtc_vblank_start; +- +- mode->hdisplay = dtd->part1.h_active; +- mode->hdisplay += ((dtd->part1.h_high >> 4) & 0x0f) << 8; +- mode->hsync_start = mode->hdisplay + dtd->part2.h_sync_off; +- mode->hsync_start += (dtd->part2.sync_off_width_high & 0xa0) << 2; +- mode->hsync_end = mode->hsync_start + dtd->part2.h_sync_width; +- mode->hsync_end += (dtd->part2.sync_off_width_high & 0x30) << 4; +- mode->htotal = mode->hdisplay + dtd->part1.h_blank; +- mode->htotal += (dtd->part1.h_high & 0xf) << 8; +- +- mode->vdisplay = dtd->part1.v_active; +- mode->vdisplay += ((dtd->part1.v_high >> 4) & 0x0f) << 8; +- mode->vsync_start = mode->vdisplay; +- mode->vsync_start += (dtd->part2.v_sync_off_width >> 4) & 0xf; +- mode->vsync_start += (dtd->part2.sync_off_width_high & 0x0a) << 2; +- mode->vsync_start += dtd->part2.v_sync_off_high & 0xc0; +- mode->vsync_end = mode->vsync_start + +- (dtd->part2.v_sync_off_width & 0xf); +- mode->vsync_end += (dtd->part2.sync_off_width_high & 0x3) << 4; +- mode->vtotal = mode->vdisplay + dtd->part1.v_blank; +- mode->vtotal += (dtd->part1.v_high & 0xf) << 8; +- +- mode->clock = dtd->part1.clock * 10; +- +- mode->flags &= (DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC); +- if (dtd->part2.dtd_flags & 0x2) +- mode->flags |= DRM_MODE_FLAG_PHSYNC; +- if (dtd->part2.dtd_flags & 0x4) +- mode->flags |= DRM_MODE_FLAG_PVSYNC; +-} +- +-static bool intel_sdvo_get_supp_encode(struct intel_output *output, +- struct intel_sdvo_encode *encode) +-{ +- uint8_t status; +- +- intel_sdvo_write_cmd(output, SDVO_CMD_GET_SUPP_ENCODE, NULL, 0); +- status = intel_sdvo_read_response(output, encode, sizeof(*encode)); +- if (status != SDVO_CMD_STATUS_SUCCESS) { /* non-support means DVI */ +- memset(encode, 0, sizeof(*encode)); +- return false; +- } +- +- return true; +-} +- +-static bool intel_sdvo_set_encode(struct intel_output *output, uint8_t mode) +-{ +- uint8_t status; +- +- intel_sdvo_write_cmd(output, SDVO_CMD_SET_ENCODE, &mode, 1); +- status = intel_sdvo_read_response(output, NULL, 0); +- +- return (status == SDVO_CMD_STATUS_SUCCESS); +-} +- +-static bool intel_sdvo_set_colorimetry(struct intel_output *output, +- uint8_t mode) +-{ +- uint8_t status; +- +- intel_sdvo_write_cmd(output, SDVO_CMD_SET_COLORIMETRY, &mode, 1); +- status = intel_sdvo_read_response(output, NULL, 0); +- +- return (status == SDVO_CMD_STATUS_SUCCESS); +-} +- +-#if 0 +-static void intel_sdvo_dump_hdmi_buf(struct intel_output *output) +-{ +- int i, j; +- uint8_t set_buf_index[2]; +- uint8_t av_split; +- uint8_t buf_size; +- uint8_t buf[48]; +- uint8_t *pos; +- +- intel_sdvo_write_cmd(output, SDVO_CMD_GET_HBUF_AV_SPLIT, NULL, 0); +- intel_sdvo_read_response(output, &av_split, 1); +- +- for (i = 0; i <= av_split; i++) { +- set_buf_index[0] = i; set_buf_index[1] = 0; +- intel_sdvo_write_cmd(output, SDVO_CMD_SET_HBUF_INDEX, +- set_buf_index, 2); +- intel_sdvo_write_cmd(output, SDVO_CMD_GET_HBUF_INFO, NULL, 0); +- intel_sdvo_read_response(output, &buf_size, 1); +- +- pos = buf; +- for (j = 0; j <= buf_size; j += 8) { +- intel_sdvo_write_cmd(output, SDVO_CMD_GET_HBUF_DATA, +- NULL, 0); +- intel_sdvo_read_response(output, pos, 8); +- pos += 8; +- } +- } +-} +-#endif +- +-static void intel_sdvo_set_hdmi_buf(struct intel_output *output, int index, +- uint8_t *data, int8_t size, uint8_t tx_rate) +-{ +- uint8_t set_buf_index[2]; +- +- set_buf_index[0] = index; +- set_buf_index[1] = 0; +- +- intel_sdvo_write_cmd(output, SDVO_CMD_SET_HBUF_INDEX, set_buf_index, 2); +- +- for (; size > 0; size -= 8) { +- intel_sdvo_write_cmd(output, SDVO_CMD_SET_HBUF_DATA, data, 8); +- data += 8; +- } +- +- intel_sdvo_write_cmd(output, SDVO_CMD_SET_HBUF_TXRATE, &tx_rate, 1); +-} +- +-static uint8_t intel_sdvo_calc_hbuf_csum(uint8_t *data, uint8_t size) +-{ +- uint8_t csum = 0; +- int i; +- +- for (i = 0; i < size; i++) +- csum += data[i]; +- +- return 0x100 - csum; +-} +- +-#define DIP_TYPE_AVI 0x82 +-#define DIP_VERSION_AVI 0x2 +-#define DIP_LEN_AVI 13 +- +-struct dip_infoframe { +- uint8_t type; +- uint8_t version; +- uint8_t len; +- uint8_t checksum; +- union { +- struct { +- /* Packet Byte #1 */ +- uint8_t S:2; +- uint8_t B:2; +- uint8_t A:1; +- uint8_t Y:2; +- uint8_t rsvd1:1; +- /* Packet Byte #2 */ +- uint8_t R:4; +- uint8_t M:2; +- uint8_t C:2; +- /* Packet Byte #3 */ +- uint8_t SC:2; +- uint8_t Q:2; +- uint8_t EC:3; +- uint8_t ITC:1; +- /* Packet Byte #4 */ +- uint8_t VIC:7; +- uint8_t rsvd2:1; +- /* Packet Byte #5 */ +- uint8_t PR:4; +- uint8_t rsvd3:4; +- /* Packet Byte #6~13 */ +- uint16_t top_bar_end; +- uint16_t bottom_bar_start; +- uint16_t left_bar_end; +- uint16_t right_bar_start; +- } avi; +- struct { +- /* Packet Byte #1 */ +- uint8_t channel_count:3; +- uint8_t rsvd1:1; +- uint8_t coding_type:4; +- /* Packet Byte #2 */ +- uint8_t sample_size:2; /* SS0, SS1 */ +- uint8_t sample_frequency:3; +- uint8_t rsvd2:3; +- /* Packet Byte #3 */ +- uint8_t coding_type_private:5; +- uint8_t rsvd3:3; +- /* Packet Byte #4 */ +- uint8_t channel_allocation; +- /* Packet Byte #5 */ +- uint8_t rsvd4:3; +- uint8_t level_shift:4; +- uint8_t downmix_inhibit:1; +- } audio; +- uint8_t payload[28]; +- } __attribute__ ((packed)) u; +-} __attribute__((packed)); +- +-static void intel_sdvo_set_avi_infoframe(struct intel_output *output, +- struct drm_display_mode * mode) +-{ +- struct dip_infoframe avi_if = { +- .type = DIP_TYPE_AVI, +- .version = DIP_VERSION_AVI, +- .len = DIP_LEN_AVI, +- }; +- +- avi_if.checksum = intel_sdvo_calc_hbuf_csum((uint8_t *)&avi_if, +- 4 + avi_if.len); +- intel_sdvo_set_hdmi_buf(output, 1, (uint8_t *)&avi_if, 4 + avi_if.len, +- SDVO_HBUF_TX_VSYNC); +-} +- +-static bool intel_sdvo_mode_fixup(struct drm_encoder *encoder, +- struct drm_display_mode *mode, +- struct drm_display_mode *adjusted_mode) +-{ +- struct intel_output *output = enc_to_intel_output(encoder); +- struct intel_sdvo_priv *dev_priv = output->dev_priv; +- +- if (!dev_priv->is_tv) { +- /* Make the CRTC code factor in the SDVO pixel multiplier. The +- * SDVO device will be told of the multiplier during mode_set. +- */ +- adjusted_mode->clock *= intel_sdvo_get_pixel_multiplier(mode); +- } else { +- struct intel_sdvo_dtd output_dtd; +- bool success; +- +- /* We need to construct preferred input timings based on our +- * output timings. To do that, we have to set the output +- * timings, even though this isn't really the right place in +- * the sequence to do it. Oh well. +- */ +- +- +- /* Set output timings */ +- intel_sdvo_get_dtd_from_mode(&output_dtd, mode); +- intel_sdvo_set_target_output(output, +- dev_priv->controlled_output); +- intel_sdvo_set_output_timing(output, &output_dtd); +- +- /* Set the input timing to the screen. Assume always input 0. */ +- intel_sdvo_set_target_input(output, true, false); +- +- +- success = intel_sdvo_create_preferred_input_timing(output, +- mode->clock / 10, +- mode->hdisplay, +- mode->vdisplay); +- if (success) { +- struct intel_sdvo_dtd input_dtd; +- +- intel_sdvo_get_preferred_input_timing(output, +- &input_dtd); +- intel_sdvo_get_mode_from_dtd(adjusted_mode, &input_dtd); +- +- } else { +- return false; +- } +- } +- return true; +-} +- +-static void intel_sdvo_mode_set(struct drm_encoder *encoder, +- struct drm_display_mode *mode, +- struct drm_display_mode *adjusted_mode) +-{ +- struct drm_device *dev = encoder->dev; +- struct drm_i915_private *dev_priv = dev->dev_private; +- struct drm_crtc *crtc = encoder->crtc; +- struct intel_crtc *intel_crtc = to_intel_crtc(crtc); +- struct intel_output *output = enc_to_intel_output(encoder); +- struct intel_sdvo_priv *sdvo_priv = output->dev_priv; +- u32 sdvox = 0; +- int sdvo_pixel_multiply; +- struct intel_sdvo_in_out_map in_out; +- struct intel_sdvo_dtd input_dtd; +- u8 status; +- +- if (!mode) +- return; +- +- /* First, set the input mapping for the first input to our controlled +- * output. This is only correct if we're a single-input device, in +- * which case the first input is the output from the appropriate SDVO +- * channel on the motherboard. In a two-input device, the first input +- * will be SDVOB and the second SDVOC. +- */ +- in_out.in0 = sdvo_priv->controlled_output; +- in_out.in1 = 0; +- +- intel_sdvo_write_cmd(output, SDVO_CMD_SET_IN_OUT_MAP, +- &in_out, sizeof(in_out)); +- status = intel_sdvo_read_response(output, NULL, 0); +- +- if (sdvo_priv->is_hdmi) { +- intel_sdvo_set_avi_infoframe(output, mode); +- sdvox |= SDVO_AUDIO_ENABLE; +- } +- +- intel_sdvo_get_dtd_from_mode(&input_dtd, mode); ++ output_dtd.part2.dtd_flags |= 0x4; + +- /* If it's a TV, we already set the output timing in mode_fixup. +- * Otherwise, the output timing is equal to the input timing. +- */ +- if (!sdvo_priv->is_tv) { +- /* Set the output timing to the screen */ +- intel_sdvo_set_target_output(output, +- sdvo_priv->controlled_output); +- intel_sdvo_set_output_timing(output, &input_dtd); +- } ++ output_dtd.part2.sdvo_flags = 0; ++ output_dtd.part2.v_sync_off_high = v_sync_offset & 0xc0; ++ output_dtd.part2.reserved = 0; ++ ++ /* Set the output timing to the screen */ ++ intel_sdvo_set_target_output(intel_output, sdvo_priv->active_outputs); ++ intel_sdvo_set_output_timing(intel_output, &output_dtd); + + /* Set the input timing to the screen. Assume always input 0. */ +- intel_sdvo_set_target_input(output, true, false); ++ intel_sdvo_set_target_input(intel_output, true, false); + +- /* We would like to use intel_sdvo_create_preferred_input_timing() to ++ /* We would like to use i830_sdvo_create_preferred_input_timing() to + * provide the device with a timing it can support, if it supports that + * feature. However, presumably we would need to adjust the CRTC to + * output the preferred timing, and we don't support that currently. + */ +-#if 0 +- success = intel_sdvo_create_preferred_input_timing(output, clock, +- width, height); +- if (success) { +- struct intel_sdvo_dtd *input_dtd; +- +- intel_sdvo_get_preferred_input_timing(output, &input_dtd); +- intel_sdvo_set_input_timing(output, &input_dtd); +- } +-#else +- intel_sdvo_set_input_timing(output, &input_dtd); +-#endif ++ intel_sdvo_set_input_timing(intel_output, &output_dtd); + + switch (intel_sdvo_get_pixel_multiplier(mode)) { + case 1: +- intel_sdvo_set_clock_rate_mult(output, ++ intel_sdvo_set_clock_rate_mult(intel_output, + SDVO_CLOCK_RATE_MULT_1X); + break; + case 2: +- intel_sdvo_set_clock_rate_mult(output, ++ intel_sdvo_set_clock_rate_mult(intel_output, + SDVO_CLOCK_RATE_MULT_2X); + break; + case 4: +- intel_sdvo_set_clock_rate_mult(output, ++ intel_sdvo_set_clock_rate_mult(intel_output, + SDVO_CLOCK_RATE_MULT_4X); + break; + } + + /* Set the SDVO control regs. */ +- if (IS_I965G(dev)) { +- sdvox |= SDVO_BORDER_ENABLE | +- SDVO_VSYNC_ACTIVE_HIGH | +- SDVO_HSYNC_ACTIVE_HIGH; +- } else { +- sdvox |= I915_READ(sdvo_priv->output_device); +- switch (sdvo_priv->output_device) { +- case SDVOB: +- sdvox &= SDVOB_PRESERVE_MASK; +- break; +- case SDVOC: +- sdvox &= SDVOC_PRESERVE_MASK; +- break; +- } +- sdvox |= (9 << 19) | SDVO_BORDER_ENABLE; +- } ++ if (0/*IS_I965GM(dev)*/) { ++ sdvox = SDVO_BORDER_ENABLE; ++ } else { ++ sdvox = I915_READ(sdvo_priv->output_device); ++ switch (sdvo_priv->output_device) { ++ case SDVOB: ++ sdvox &= SDVOB_PRESERVE_MASK; ++ break; ++ case SDVOC: ++ sdvox &= SDVOC_PRESERVE_MASK; ++ break; ++ } ++ sdvox |= (9 << 19) | SDVO_BORDER_ENABLE; ++ } + if (intel_crtc->pipe == 1) + sdvox |= SDVO_PIPE_B_SELECT; + + sdvo_pixel_multiply = intel_sdvo_get_pixel_multiplier(mode); + if (IS_I965G(dev)) { +- /* done in crtc_mode_set as the dpll_md reg must be written early */ +- } else if (IS_I945G(dev) || IS_I945GM(dev) || IS_G33(dev)) { +- /* done in crtc_mode_set as it lives inside the dpll register */ ++ /* done in crtc_mode_set as the dpll_md reg must be written ++ early */ ++ } else if (IS_I945G(dev) || IS_I945GM(dev)) { ++ /* done in crtc_mode_set as it lives inside the ++ dpll register */ + } else { + sdvox |= (sdvo_pixel_multiply - 1) << SDVO_PORT_MULTIPLY_SHIFT; + } + +- intel_sdvo_write_sdvox(output, sdvox); ++ intel_sdvo_write_sdvox(intel_output, sdvox); + } + + static void intel_sdvo_dpms(struct drm_encoder *encoder, int mode) +@@ -1137,7 +714,7 @@ + + if (0) + intel_sdvo_set_encoder_power_state(intel_output, mode); +- intel_sdvo_set_active_outputs(intel_output, sdvo_priv->controlled_output); ++ intel_sdvo_set_active_outputs(intel_output, sdvo_priv->active_outputs); + } + return; + } +@@ -1175,9 +752,6 @@ + &sdvo_priv->save_output_dtd[o]); + } + } +- if (sdvo_priv->is_tv) { +- /* XXX: Save TV format/enhancements. */ +- } + + sdvo_priv->save_SDVOX = I915_READ(sdvo_priv->output_device); + } +@@ -1185,6 +759,7 @@ + static void intel_sdvo_restore(struct drm_connector *connector) + { + struct drm_device *dev = connector->dev; ++ struct drm_i915_private *dev_priv = dev->dev_private; + struct intel_output *intel_output = to_intel_output(connector); + struct intel_sdvo_priv *sdvo_priv = intel_output->dev_priv; + int o; +@@ -1215,11 +790,7 @@ + + intel_sdvo_set_clock_rate_mult(intel_output, sdvo_priv->save_sdvo_mult); + +- if (sdvo_priv->is_tv) { +- /* XXX: Restore TV format/enhancements. */ +- } +- +- intel_sdvo_write_sdvox(intel_output, sdvo_priv->save_SDVOX); ++ I915_WRITE(sdvo_priv->output_device, sdvo_priv->save_SDVOX); + + if (sdvo_priv->save_SDVOX & SDVO_ENABLE) + { +@@ -1345,173 +916,20 @@ + status = intel_sdvo_read_response(intel_output, &response, 2); + + DRM_DEBUG("SDVO response %d %d\n", response[0], response[1]); +- +- if (status != SDVO_CMD_STATUS_SUCCESS) +- return connector_status_unknown; +- + if ((response[0] != 0) || (response[1] != 0)) + return connector_status_connected; + else + return connector_status_disconnected; + } + +-static void intel_sdvo_get_ddc_modes(struct drm_connector *connector) ++static int intel_sdvo_get_modes(struct drm_connector *connector) + { + struct intel_output *intel_output = to_intel_output(connector); +- struct intel_sdvo_priv *sdvo_priv = intel_output->dev_priv; + + /* set the bus switch and get the modes */ +- intel_sdvo_set_control_bus_switch(intel_output, sdvo_priv->ddc_bus); ++ intel_sdvo_set_control_bus_switch(intel_output, SDVO_CONTROL_BUS_DDC2); + intel_ddc_get_modes(intel_output); + +-#if 0 +- struct drm_device *dev = encoder->dev; +- struct drm_i915_private *dev_priv = dev->dev_private; +- /* Mac mini hack. On this device, I get DDC through the analog, which +- * load-detects as disconnected. I fail to DDC through the SDVO DDC, +- * but it does load-detect as connected. So, just steal the DDC bits +- * from analog when we fail at finding it the right way. +- */ +- crt = xf86_config->output[0]; +- intel_output = crt->driver_private; +- if (intel_output->type == I830_OUTPUT_ANALOG && +- crt->funcs->detect(crt) == XF86OutputStatusDisconnected) { +- I830I2CInit(pScrn, &intel_output->pDDCBus, GPIOA, "CRTDDC_A"); +- edid_mon = xf86OutputGetEDID(crt, intel_output->pDDCBus); +- xf86DestroyI2CBusRec(intel_output->pDDCBus, true, true); +- } +- if (edid_mon) { +- xf86OutputSetEDID(output, edid_mon); +- modes = xf86OutputGetEDIDModes(output); +- } +-#endif +-} +- +-/** +- * This function checks the current TV format, and chooses a default if +- * it hasn't been set. +- */ +-static void +-intel_sdvo_check_tv_format(struct intel_output *output) +-{ +- struct intel_sdvo_priv *dev_priv = output->dev_priv; +- struct intel_sdvo_tv_format format, unset; +- uint8_t status; +- +- intel_sdvo_write_cmd(output, SDVO_CMD_GET_TV_FORMAT, NULL, 0); +- status = intel_sdvo_read_response(output, &format, sizeof(format)); +- if (status != SDVO_CMD_STATUS_SUCCESS) +- return; +- +- memset(&unset, 0, sizeof(unset)); +- if (memcmp(&format, &unset, sizeof(format))) { +- DRM_DEBUG("%s: Choosing default TV format of NTSC-M\n", +- SDVO_NAME(dev_priv)); +- +- format.ntsc_m = true; +- intel_sdvo_write_cmd(output, SDVO_CMD_SET_TV_FORMAT, NULL, 0); +- status = intel_sdvo_read_response(output, NULL, 0); +- } +-} +- +-/* +- * Set of SDVO TV modes. +- * Note! This is in reply order (see loop in get_tv_modes). +- * XXX: all 60Hz refresh? +- */ +-struct drm_display_mode sdvo_tv_modes[] = { +- { DRM_MODE("320x200", DRM_MODE_TYPE_DRIVER, 5815680, 321, 384, 416, +- 200, 0, 232, 201, 233, 4196112, 0, +- DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC) }, +- { DRM_MODE("320x240", DRM_MODE_TYPE_DRIVER, 6814080, 321, 384, 416, +- 240, 0, 272, 241, 273, 4196112, 0, +- DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC) }, +- { DRM_MODE("400x300", DRM_MODE_TYPE_DRIVER, 9910080, 401, 464, 496, +- 300, 0, 332, 301, 333, 4196112, 0, +- DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC) }, +- { DRM_MODE("640x350", DRM_MODE_TYPE_DRIVER, 16913280, 641, 704, 736, +- 350, 0, 382, 351, 383, 4196112, 0, +- DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC) }, +- { DRM_MODE("640x400", DRM_MODE_TYPE_DRIVER, 19121280, 641, 704, 736, +- 400, 0, 432, 401, 433, 4196112, 0, +- DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC) }, +- { DRM_MODE("640x400", DRM_MODE_TYPE_DRIVER, 19121280, 641, 704, 736, +- 400, 0, 432, 401, 433, 4196112, 0, +- DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC) }, +- { DRM_MODE("704x480", DRM_MODE_TYPE_DRIVER, 24624000, 705, 768, 800, +- 480, 0, 512, 481, 513, 4196112, 0, +- DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC) }, +- { DRM_MODE("704x576", DRM_MODE_TYPE_DRIVER, 29232000, 705, 768, 800, +- 576, 0, 608, 577, 609, 4196112, 0, +- DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC) }, +- { DRM_MODE("720x350", DRM_MODE_TYPE_DRIVER, 18751680, 721, 784, 816, +- 350, 0, 382, 351, 383, 4196112, 0, +- DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC) }, +- { DRM_MODE("720x400", DRM_MODE_TYPE_DRIVER, 21199680, 721, 784, 816, +- 400, 0, 432, 401, 433, 4196112, 0, +- DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC) }, +- { DRM_MODE("720x480", DRM_MODE_TYPE_DRIVER, 25116480, 721, 784, 816, +- 480, 0, 512, 481, 513, 4196112, 0, +- DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC) }, +- { DRM_MODE("720x540", DRM_MODE_TYPE_DRIVER, 28054080, 721, 784, 816, +- 540, 0, 572, 541, 573, 4196112, 0, +- DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC) }, +- { DRM_MODE("720x576", DRM_MODE_TYPE_DRIVER, 29816640, 721, 784, 816, +- 576, 0, 608, 577, 609, 4196112, 0, +- DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC) }, +- { DRM_MODE("768x576", DRM_MODE_TYPE_DRIVER, 31570560, 769, 832, 864, +- 576, 0, 608, 577, 609, 4196112, 0, +- DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC) }, +- { DRM_MODE("800x600", DRM_MODE_TYPE_DRIVER, 34030080, 801, 864, 896, +- 600, 0, 632, 601, 633, 4196112, 0, +- DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC) }, +- { DRM_MODE("832x624", DRM_MODE_TYPE_DRIVER, 36581760, 833, 896, 928, +- 624, 0, 656, 625, 657, 4196112, 0, +- DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC) }, +- { DRM_MODE("920x766", DRM_MODE_TYPE_DRIVER, 48707040, 921, 984, 1016, +- 766, 0, 798, 767, 799, 4196112, 0, +- DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC) }, +- { DRM_MODE("1024x768", DRM_MODE_TYPE_DRIVER, 53827200, 1025, 1088, 1120, +- 768, 0, 800, 769, 801, 4196112, 0, +- DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC) }, +- { DRM_MODE("1280x1024", DRM_MODE_TYPE_DRIVER, 87265920, 1281, 1344, 1376, +- 1024, 0, 1056, 1025, 1057, 4196112, 0, +- DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC) }, +-}; +- +-static void intel_sdvo_get_tv_modes(struct drm_connector *connector) +-{ +- struct intel_output *output = to_intel_output(connector); +- uint32_t reply = 0; +- uint8_t status; +- int i = 0; +- +- intel_sdvo_check_tv_format(output); +- +- /* Read the list of supported input resolutions for the selected TV +- * format. +- */ +- intel_sdvo_write_cmd(output, SDVO_CMD_GET_SDTV_RESOLUTION_SUPPORT, +- NULL, 0); +- status = intel_sdvo_read_response(output, &reply, 3); +- if (status != SDVO_CMD_STATUS_SUCCESS) +- return; +- +- for (i = 0; i < ARRAY_SIZE(sdvo_tv_modes); i++) +- if (reply & (1 << i)) +- drm_mode_probed_add(connector, &sdvo_tv_modes[i]); +-} +- +-static int intel_sdvo_get_modes(struct drm_connector *connector) +-{ +- struct intel_output *output = to_intel_output(connector); +- struct intel_sdvo_priv *sdvo_priv = output->dev_priv; +- +- if (sdvo_priv->is_tv) +- intel_sdvo_get_tv_modes(connector); +- else +- intel_sdvo_get_ddc_modes(connector); +- + if (list_empty(&connector->probed_modes)) + return 0; + return 1; +@@ -1560,65 +978,6 @@ + }; + + +-/** +- * Choose the appropriate DDC bus for control bus switch command for this +- * SDVO output based on the controlled output. +- * +- * DDC bus number assignment is in a priority order of RGB outputs, then TMDS +- * outputs, then LVDS outputs. +- */ +-static void +-intel_sdvo_select_ddc_bus(struct intel_sdvo_priv *dev_priv) +-{ +- uint16_t mask = 0; +- unsigned int num_bits; +- +- /* Make a mask of outputs less than or equal to our own priority in the +- * list. +- */ +- switch (dev_priv->controlled_output) { +- case SDVO_OUTPUT_LVDS1: +- mask |= SDVO_OUTPUT_LVDS1; +- case SDVO_OUTPUT_LVDS0: +- mask |= SDVO_OUTPUT_LVDS0; +- case SDVO_OUTPUT_TMDS1: +- mask |= SDVO_OUTPUT_TMDS1; +- case SDVO_OUTPUT_TMDS0: +- mask |= SDVO_OUTPUT_TMDS0; +- case SDVO_OUTPUT_RGB1: +- mask |= SDVO_OUTPUT_RGB1; +- case SDVO_OUTPUT_RGB0: +- mask |= SDVO_OUTPUT_RGB0; +- break; +- } +- +- /* Count bits to find what number we are in the priority list. */ +- mask &= dev_priv->caps.output_flags; +- num_bits = hweight16(mask); +- if (num_bits > 3) { +- /* if more than 3 outputs, default to DDC bus 3 for now */ +- num_bits = 3; +- } +- +- /* Corresponds to SDVO_CONTROL_BUS_DDCx */ +- dev_priv->ddc_bus = 1 << num_bits; +-} +- +-static bool +-intel_sdvo_get_digital_encoding_mode(struct intel_output *output) +-{ +- struct intel_sdvo_priv *sdvo_priv = output->dev_priv; +- uint8_t status; +- +- intel_sdvo_set_target_output(output, sdvo_priv->controlled_output); +- +- intel_sdvo_write_cmd(output, SDVO_CMD_GET_ENCODE, NULL, 0); +- status = intel_sdvo_read_response(output, &sdvo_priv->is_hdmi, 1); +- if (status != SDVO_CMD_STATUS_SUCCESS) +- return false; +- return true; +-} +- + bool intel_sdvo_init(struct drm_device *dev, int output_device) + { + struct drm_connector *connector; +@@ -1681,76 +1040,45 @@ + + intel_sdvo_get_capabilities(intel_output, &sdvo_priv->caps); + +- if (sdvo_priv->caps.output_flags & +- (SDVO_OUTPUT_TMDS0 | SDVO_OUTPUT_TMDS1)) { +- if (sdvo_priv->caps.output_flags & SDVO_OUTPUT_TMDS0) +- sdvo_priv->controlled_output = SDVO_OUTPUT_TMDS0; +- else +- sdvo_priv->controlled_output = SDVO_OUTPUT_TMDS1; +- +- connector->display_info.subpixel_order = SubPixelHorizontalRGB; +- encoder_type = DRM_MODE_ENCODER_TMDS; +- connector_type = DRM_MODE_CONNECTOR_DVID; ++ memset(&sdvo_priv->active_outputs, 0, sizeof(sdvo_priv->active_outputs)); + +- if (intel_sdvo_get_supp_encode(intel_output, +- &sdvo_priv->encode) && +- intel_sdvo_get_digital_encoding_mode(intel_output) && +- sdvo_priv->is_hdmi) { +- /* enable hdmi encoding mode if supported */ +- intel_sdvo_set_encode(intel_output, SDVO_ENCODE_HDMI); +- intel_sdvo_set_colorimetry(intel_output, +- SDVO_COLORIMETRY_RGB256); +- connector_type = DRM_MODE_CONNECTOR_HDMIA; +- } +- } +- else if (sdvo_priv->caps.output_flags & SDVO_OUTPUT_SVID0) ++ /* TODO, CVBS, SVID, YPRPB & SCART outputs. */ ++ if (sdvo_priv->caps.output_flags & SDVO_OUTPUT_RGB0) + { +- sdvo_priv->controlled_output = SDVO_OUTPUT_SVID0; +- connector->display_info.subpixel_order = SubPixelHorizontalRGB; +- encoder_type = DRM_MODE_ENCODER_TVDAC; +- connector_type = DRM_MODE_CONNECTOR_SVIDEO; +- sdvo_priv->is_tv = true; +- intel_output->needs_tv_clock = true; +- } +- else if (sdvo_priv->caps.output_flags & SDVO_OUTPUT_RGB0) +- { +- sdvo_priv->controlled_output = SDVO_OUTPUT_RGB0; ++ sdvo_priv->active_outputs = SDVO_OUTPUT_RGB0; + connector->display_info.subpixel_order = SubPixelHorizontalRGB; + encoder_type = DRM_MODE_ENCODER_DAC; + connector_type = DRM_MODE_CONNECTOR_VGA; + } + else if (sdvo_priv->caps.output_flags & SDVO_OUTPUT_RGB1) + { +- sdvo_priv->controlled_output = SDVO_OUTPUT_RGB1; ++ sdvo_priv->active_outputs = SDVO_OUTPUT_RGB1; + connector->display_info.subpixel_order = SubPixelHorizontalRGB; + encoder_type = DRM_MODE_ENCODER_DAC; + connector_type = DRM_MODE_CONNECTOR_VGA; + } +- else if (sdvo_priv->caps.output_flags & SDVO_OUTPUT_LVDS0) ++ else if (sdvo_priv->caps.output_flags & SDVO_OUTPUT_TMDS0) + { +- sdvo_priv->controlled_output = SDVO_OUTPUT_LVDS0; ++ sdvo_priv->active_outputs = SDVO_OUTPUT_TMDS0; + connector->display_info.subpixel_order = SubPixelHorizontalRGB; +- encoder_type = DRM_MODE_ENCODER_LVDS; +- connector_type = DRM_MODE_CONNECTOR_LVDS; ++ encoder_type = DRM_MODE_ENCODER_TMDS; ++ connector_type = DRM_MODE_CONNECTOR_DVID; + } +- else if (sdvo_priv->caps.output_flags & SDVO_OUTPUT_LVDS1) ++ else if (sdvo_priv->caps.output_flags & SDVO_OUTPUT_TMDS1) + { +- sdvo_priv->controlled_output = SDVO_OUTPUT_LVDS1; ++ sdvo_priv->active_outputs = SDVO_OUTPUT_TMDS1; + connector->display_info.subpixel_order = SubPixelHorizontalRGB; +- encoder_type = DRM_MODE_ENCODER_LVDS; +- connector_type = DRM_MODE_CONNECTOR_LVDS; ++ encoder_type = DRM_MODE_ENCODER_TMDS; ++ connector_type = DRM_MODE_CONNECTOR_DVID; + } + else + { + unsigned char bytes[2]; + +- sdvo_priv->controlled_output = 0; + memcpy (bytes, &sdvo_priv->caps.output_flags, 2); +- DRM_DEBUG("%s: Unknown SDVO output type (0x%02x%02x)\n", ++ DRM_DEBUG("%s: No active RGB or TMDS outputs (0x%02x%02x)\n", + SDVO_NAME(sdvo_priv), + bytes[0], bytes[1]); +- encoder_type = DRM_MODE_ENCODER_NONE; +- connector_type = DRM_MODE_CONNECTOR_Unknown; + goto err_i2c; + } + +@@ -1761,8 +1089,6 @@ + drm_mode_connector_attach_encoder(&intel_output->base, &intel_output->enc); + drm_sysfs_connector_add(connector); + +- intel_sdvo_select_ddc_bus(sdvo_priv); +- + /* Set the input timing to the screen. Assume always input 0. */ + intel_sdvo_set_target_input(intel_output, true, false); + +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/drivers/gpu/drm/i915/intel_sdvo_regs.h linux-2.6.29-rc3.owrt/drivers/gpu/drm/i915/intel_sdvo_regs.h +--- linux-2.6.29.owrt/drivers/gpu/drm/i915/intel_sdvo_regs.h 2009-05-10 22:04:38.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/drivers/gpu/drm/i915/intel_sdvo_regs.h 2009-05-10 23:48:28.000000000 +0200 +@@ -173,9 +173,6 @@ + * Returns two struct intel_sdvo_output_flags structures. + */ + #define SDVO_CMD_GET_IN_OUT_MAP 0x06 +-struct intel_sdvo_in_out_map { +- u16 in0, in1; +-}; + + /** + * Sets the current mapping of SDVO inputs to outputs on the device. +@@ -209,8 +206,7 @@ + struct intel_sdvo_get_interrupt_event_source_response { + u16 interrupt_status; + unsigned int ambient_light_interrupt:1; +- unsigned int hdmi_audio_encrypt_change:1; +- unsigned int pad:6; ++ unsigned int pad:7; + } __attribute__((packed)); + + /** +@@ -309,411 +305,23 @@ + # define SDVO_CLOCK_RATE_MULT_4X (1 << 3) + + #define SDVO_CMD_GET_SUPPORTED_TV_FORMATS 0x27 +-/** 5 bytes of bit flags for TV formats shared by all TV format functions */ +-struct intel_sdvo_tv_format { +- unsigned int ntsc_m:1; +- unsigned int ntsc_j:1; +- unsigned int ntsc_443:1; +- unsigned int pal_b:1; +- unsigned int pal_d:1; +- unsigned int pal_g:1; +- unsigned int pal_h:1; +- unsigned int pal_i:1; +- +- unsigned int pal_m:1; +- unsigned int pal_n:1; +- unsigned int pal_nc:1; +- unsigned int pal_60:1; +- unsigned int secam_b:1; +- unsigned int secam_d:1; +- unsigned int secam_g:1; +- unsigned int secam_k:1; +- +- unsigned int secam_k1:1; +- unsigned int secam_l:1; +- unsigned int secam_60:1; +- unsigned int hdtv_std_smpte_240m_1080i_59:1; +- unsigned int hdtv_std_smpte_240m_1080i_60:1; +- unsigned int hdtv_std_smpte_260m_1080i_59:1; +- unsigned int hdtv_std_smpte_260m_1080i_60:1; +- unsigned int hdtv_std_smpte_274m_1080i_50:1; +- +- unsigned int hdtv_std_smpte_274m_1080i_59:1; +- unsigned int hdtv_std_smpte_274m_1080i_60:1; +- unsigned int hdtv_std_smpte_274m_1080p_23:1; +- unsigned int hdtv_std_smpte_274m_1080p_24:1; +- unsigned int hdtv_std_smpte_274m_1080p_25:1; +- unsigned int hdtv_std_smpte_274m_1080p_29:1; +- unsigned int hdtv_std_smpte_274m_1080p_30:1; +- unsigned int hdtv_std_smpte_274m_1080p_50:1; +- +- unsigned int hdtv_std_smpte_274m_1080p_59:1; +- unsigned int hdtv_std_smpte_274m_1080p_60:1; +- unsigned int hdtv_std_smpte_295m_1080i_50:1; +- unsigned int hdtv_std_smpte_295m_1080p_50:1; +- unsigned int hdtv_std_smpte_296m_720p_59:1; +- unsigned int hdtv_std_smpte_296m_720p_60:1; +- unsigned int hdtv_std_smpte_296m_720p_50:1; +- unsigned int hdtv_std_smpte_293m_480p_59:1; +- +- unsigned int hdtv_std_smpte_170m_480i_59:1; +- unsigned int hdtv_std_iturbt601_576i_50:1; +- unsigned int hdtv_std_iturbt601_576p_50:1; +- unsigned int hdtv_std_eia_7702a_480i_60:1; +- unsigned int hdtv_std_eia_7702a_480p_60:1; +- unsigned int pad:3; +-} __attribute__((packed)); + + #define SDVO_CMD_GET_TV_FORMAT 0x28 + + #define SDVO_CMD_SET_TV_FORMAT 0x29 + +-/** Returns the resolutiosn that can be used with the given TV format */ +-#define SDVO_CMD_GET_SDTV_RESOLUTION_SUPPORT 0x83 +-struct intel_sdvo_sdtv_resolution_request { +- unsigned int ntsc_m:1; +- unsigned int ntsc_j:1; +- unsigned int ntsc_443:1; +- unsigned int pal_b:1; +- unsigned int pal_d:1; +- unsigned int pal_g:1; +- unsigned int pal_h:1; +- unsigned int pal_i:1; +- +- unsigned int pal_m:1; +- unsigned int pal_n:1; +- unsigned int pal_nc:1; +- unsigned int pal_60:1; +- unsigned int secam_b:1; +- unsigned int secam_d:1; +- unsigned int secam_g:1; +- unsigned int secam_k:1; +- +- unsigned int secam_k1:1; +- unsigned int secam_l:1; +- unsigned int secam_60:1; +- unsigned int pad:5; +-} __attribute__((packed)); +- +-struct intel_sdvo_sdtv_resolution_reply { +- unsigned int res_320x200:1; +- unsigned int res_320x240:1; +- unsigned int res_400x300:1; +- unsigned int res_640x350:1; +- unsigned int res_640x400:1; +- unsigned int res_640x480:1; +- unsigned int res_704x480:1; +- unsigned int res_704x576:1; +- +- unsigned int res_720x350:1; +- unsigned int res_720x400:1; +- unsigned int res_720x480:1; +- unsigned int res_720x540:1; +- unsigned int res_720x576:1; +- unsigned int res_768x576:1; +- unsigned int res_800x600:1; +- unsigned int res_832x624:1; +- +- unsigned int res_920x766:1; +- unsigned int res_1024x768:1; +- unsigned int res_1280x1024:1; +- unsigned int pad:5; +-} __attribute__((packed)); +- +-/* Get supported resolution with squire pixel aspect ratio that can be +- scaled for the requested HDTV format */ +-#define SDVO_CMD_GET_SCALED_HDTV_RESOLUTION_SUPPORT 0x85 +- +-struct intel_sdvo_hdtv_resolution_request { +- unsigned int hdtv_std_smpte_240m_1080i_59:1; +- unsigned int hdtv_std_smpte_240m_1080i_60:1; +- unsigned int hdtv_std_smpte_260m_1080i_59:1; +- unsigned int hdtv_std_smpte_260m_1080i_60:1; +- unsigned int hdtv_std_smpte_274m_1080i_50:1; +- unsigned int hdtv_std_smpte_274m_1080i_59:1; +- unsigned int hdtv_std_smpte_274m_1080i_60:1; +- unsigned int hdtv_std_smpte_274m_1080p_23:1; +- +- unsigned int hdtv_std_smpte_274m_1080p_24:1; +- unsigned int hdtv_std_smpte_274m_1080p_25:1; +- unsigned int hdtv_std_smpte_274m_1080p_29:1; +- unsigned int hdtv_std_smpte_274m_1080p_30:1; +- unsigned int hdtv_std_smpte_274m_1080p_50:1; +- unsigned int hdtv_std_smpte_274m_1080p_59:1; +- unsigned int hdtv_std_smpte_274m_1080p_60:1; +- unsigned int hdtv_std_smpte_295m_1080i_50:1; +- +- unsigned int hdtv_std_smpte_295m_1080p_50:1; +- unsigned int hdtv_std_smpte_296m_720p_59:1; +- unsigned int hdtv_std_smpte_296m_720p_60:1; +- unsigned int hdtv_std_smpte_296m_720p_50:1; +- unsigned int hdtv_std_smpte_293m_480p_59:1; +- unsigned int hdtv_std_smpte_170m_480i_59:1; +- unsigned int hdtv_std_iturbt601_576i_50:1; +- unsigned int hdtv_std_iturbt601_576p_50:1; +- +- unsigned int hdtv_std_eia_7702a_480i_60:1; +- unsigned int hdtv_std_eia_7702a_480p_60:1; +- unsigned int pad:6; +-} __attribute__((packed)); +- +-struct intel_sdvo_hdtv_resolution_reply { +- unsigned int res_640x480:1; +- unsigned int res_800x600:1; +- unsigned int res_1024x768:1; +- unsigned int res_1280x960:1; +- unsigned int res_1400x1050:1; +- unsigned int res_1600x1200:1; +- unsigned int res_1920x1440:1; +- unsigned int res_2048x1536:1; +- +- unsigned int res_2560x1920:1; +- unsigned int res_3200x2400:1; +- unsigned int res_3840x2880:1; +- unsigned int pad1:5; +- +- unsigned int res_848x480:1; +- unsigned int res_1064x600:1; +- unsigned int res_1280x720:1; +- unsigned int res_1360x768:1; +- unsigned int res_1704x960:1; +- unsigned int res_1864x1050:1; +- unsigned int res_1920x1080:1; +- unsigned int res_2128x1200:1; +- +- unsigned int res_2560x1400:1; +- unsigned int res_2728x1536:1; +- unsigned int res_3408x1920:1; +- unsigned int res_4264x2400:1; +- unsigned int res_5120x2880:1; +- unsigned int pad2:3; +- +- unsigned int res_768x480:1; +- unsigned int res_960x600:1; +- unsigned int res_1152x720:1; +- unsigned int res_1124x768:1; +- unsigned int res_1536x960:1; +- unsigned int res_1680x1050:1; +- unsigned int res_1728x1080:1; +- unsigned int res_1920x1200:1; +- +- unsigned int res_2304x1440:1; +- unsigned int res_2456x1536:1; +- unsigned int res_3072x1920:1; +- unsigned int res_3840x2400:1; +- unsigned int res_4608x2880:1; +- unsigned int pad3:3; +- +- unsigned int res_1280x1024:1; +- unsigned int pad4:7; +- +- unsigned int res_1280x768:1; +- unsigned int pad5:7; +-} __attribute__((packed)); +- +-/* Get supported power state returns info for encoder and monitor, rely on +- last SetTargetInput and SetTargetOutput calls */ + #define SDVO_CMD_GET_SUPPORTED_POWER_STATES 0x2a +-/* Get power state returns info for encoder and monitor, rely on last +- SetTargetInput and SetTargetOutput calls */ +-#define SDVO_CMD_GET_POWER_STATE 0x2b + #define SDVO_CMD_GET_ENCODER_POWER_STATE 0x2b + #define SDVO_CMD_SET_ENCODER_POWER_STATE 0x2c + # define SDVO_ENCODER_STATE_ON (1 << 0) + # define SDVO_ENCODER_STATE_STANDBY (1 << 1) + # define SDVO_ENCODER_STATE_SUSPEND (1 << 2) + # define SDVO_ENCODER_STATE_OFF (1 << 3) +-# define SDVO_MONITOR_STATE_ON (1 << 4) +-# define SDVO_MONITOR_STATE_STANDBY (1 << 5) +-# define SDVO_MONITOR_STATE_SUSPEND (1 << 6) +-# define SDVO_MONITOR_STATE_OFF (1 << 7) +- +-#define SDVO_CMD_GET_MAX_PANEL_POWER_SEQUENCING 0x2d +-#define SDVO_CMD_GET_PANEL_POWER_SEQUENCING 0x2e +-#define SDVO_CMD_SET_PANEL_POWER_SEQUENCING 0x2f +-/** +- * The panel power sequencing parameters are in units of milliseconds. +- * The high fields are bits 8:9 of the 10-bit values. +- */ +-struct sdvo_panel_power_sequencing { +- u8 t0; +- u8 t1; +- u8 t2; +- u8 t3; +- u8 t4; +- +- unsigned int t0_high:2; +- unsigned int t1_high:2; +- unsigned int t2_high:2; +- unsigned int t3_high:2; +- +- unsigned int t4_high:2; +- unsigned int pad:6; +-} __attribute__((packed)); +- +-#define SDVO_CMD_GET_MAX_BACKLIGHT_LEVEL 0x30 +-struct sdvo_max_backlight_reply { +- u8 max_value; +- u8 default_value; +-} __attribute__((packed)); +- +-#define SDVO_CMD_GET_BACKLIGHT_LEVEL 0x31 +-#define SDVO_CMD_SET_BACKLIGHT_LEVEL 0x32 +- +-#define SDVO_CMD_GET_AMBIENT_LIGHT 0x33 +-struct sdvo_get_ambient_light_reply { +- u16 trip_low; +- u16 trip_high; +- u16 value; +-} __attribute__((packed)); +-#define SDVO_CMD_SET_AMBIENT_LIGHT 0x34 +-struct sdvo_set_ambient_light_reply { +- u16 trip_low; +- u16 trip_high; +- unsigned int enable:1; +- unsigned int pad:7; +-} __attribute__((packed)); +- +-/* Set display power state */ +-#define SDVO_CMD_SET_DISPLAY_POWER_STATE 0x7d +-# define SDVO_DISPLAY_STATE_ON (1 << 0) +-# define SDVO_DISPLAY_STATE_STANDBY (1 << 1) +-# define SDVO_DISPLAY_STATE_SUSPEND (1 << 2) +-# define SDVO_DISPLAY_STATE_OFF (1 << 3) +- +-#define SDVO_CMD_GET_SUPPORTED_ENHANCEMENTS 0x84 +-struct intel_sdvo_enhancements_reply { +- unsigned int flicker_filter:1; +- unsigned int flicker_filter_adaptive:1; +- unsigned int flicker_filter_2d:1; +- unsigned int saturation:1; +- unsigned int hue:1; +- unsigned int brightness:1; +- unsigned int contrast:1; +- unsigned int overscan_h:1; +- +- unsigned int overscan_v:1; +- unsigned int position_h:1; +- unsigned int position_v:1; +- unsigned int sharpness:1; +- unsigned int dot_crawl:1; +- unsigned int dither:1; +- unsigned int max_tv_chroma_filter:1; +- unsigned int max_tv_luma_filter:1; +-} __attribute__((packed)); +- +-/* Picture enhancement limits below are dependent on the current TV format, +- * and thus need to be queried and set after it. +- */ +-#define SDVO_CMD_GET_MAX_FLICKER_FITER 0x4d +-#define SDVO_CMD_GET_MAX_ADAPTIVE_FLICKER_FITER 0x7b +-#define SDVO_CMD_GET_MAX_2D_FLICKER_FITER 0x52 +-#define SDVO_CMD_GET_MAX_SATURATION 0x55 +-#define SDVO_CMD_GET_MAX_HUE 0x58 +-#define SDVO_CMD_GET_MAX_BRIGHTNESS 0x5b +-#define SDVO_CMD_GET_MAX_CONTRAST 0x5e +-#define SDVO_CMD_GET_MAX_OVERSCAN_H 0x61 +-#define SDVO_CMD_GET_MAX_OVERSCAN_V 0x64 +-#define SDVO_CMD_GET_MAX_POSITION_H 0x67 +-#define SDVO_CMD_GET_MAX_POSITION_V 0x6a +-#define SDVO_CMD_GET_MAX_SHARPNESS_V 0x6d +-#define SDVO_CMD_GET_MAX_TV_CHROMA 0x74 +-#define SDVO_CMD_GET_MAX_TV_LUMA 0x77 +-struct intel_sdvo_enhancement_limits_reply { +- u16 max_value; +- u16 default_value; +-} __attribute__((packed)); + +-#define SDVO_CMD_GET_LVDS_PANEL_INFORMATION 0x7f +-#define SDVO_CMD_SET_LVDS_PANEL_INFORMATION 0x80 +-# define SDVO_LVDS_COLOR_DEPTH_18 (0 << 0) +-# define SDVO_LVDS_COLOR_DEPTH_24 (1 << 0) +-# define SDVO_LVDS_CONNECTOR_SPWG (0 << 2) +-# define SDVO_LVDS_CONNECTOR_OPENLDI (1 << 2) +-# define SDVO_LVDS_SINGLE_CHANNEL (0 << 4) +-# define SDVO_LVDS_DUAL_CHANNEL (1 << 4) +- +-#define SDVO_CMD_GET_FLICKER_FILTER 0x4e +-#define SDVO_CMD_SET_FLICKER_FILTER 0x4f +-#define SDVO_CMD_GET_ADAPTIVE_FLICKER_FITER 0x50 +-#define SDVO_CMD_SET_ADAPTIVE_FLICKER_FITER 0x51 +-#define SDVO_CMD_GET_2D_FLICKER_FITER 0x53 +-#define SDVO_CMD_SET_2D_FLICKER_FITER 0x54 +-#define SDVO_CMD_GET_SATURATION 0x56 +-#define SDVO_CMD_SET_SATURATION 0x57 +-#define SDVO_CMD_GET_HUE 0x59 +-#define SDVO_CMD_SET_HUE 0x5a +-#define SDVO_CMD_GET_BRIGHTNESS 0x5c +-#define SDVO_CMD_SET_BRIGHTNESS 0x5d +-#define SDVO_CMD_GET_CONTRAST 0x5f +-#define SDVO_CMD_SET_CONTRAST 0x60 +-#define SDVO_CMD_GET_OVERSCAN_H 0x62 +-#define SDVO_CMD_SET_OVERSCAN_H 0x63 +-#define SDVO_CMD_GET_OVERSCAN_V 0x65 +-#define SDVO_CMD_SET_OVERSCAN_V 0x66 +-#define SDVO_CMD_GET_POSITION_H 0x68 +-#define SDVO_CMD_SET_POSITION_H 0x69 +-#define SDVO_CMD_GET_POSITION_V 0x6b +-#define SDVO_CMD_SET_POSITION_V 0x6c +-#define SDVO_CMD_GET_SHARPNESS 0x6e +-#define SDVO_CMD_SET_SHARPNESS 0x6f +-#define SDVO_CMD_GET_TV_CHROMA 0x75 +-#define SDVO_CMD_SET_TV_CHROMA 0x76 +-#define SDVO_CMD_GET_TV_LUMA 0x78 +-#define SDVO_CMD_SET_TV_LUMA 0x79 +-struct intel_sdvo_enhancements_arg { +- u16 value; +-}__attribute__((packed)); +- +-#define SDVO_CMD_GET_DOT_CRAWL 0x70 +-#define SDVO_CMD_SET_DOT_CRAWL 0x71 +-# define SDVO_DOT_CRAWL_ON (1 << 0) +-# define SDVO_DOT_CRAWL_DEFAULT_ON (1 << 1) +- +-#define SDVO_CMD_GET_DITHER 0x72 +-#define SDVO_CMD_SET_DITHER 0x73 +-# define SDVO_DITHER_ON (1 << 0) +-# define SDVO_DITHER_DEFAULT_ON (1 << 1) ++#define SDVO_CMD_SET_TV_RESOLUTION_SUPPORT 0x93 + + #define SDVO_CMD_SET_CONTROL_BUS_SWITCH 0x7a +-# define SDVO_CONTROL_BUS_PROM (1 << 0) +-# define SDVO_CONTROL_BUS_DDC1 (1 << 1) +-# define SDVO_CONTROL_BUS_DDC2 (1 << 2) +-# define SDVO_CONTROL_BUS_DDC3 (1 << 3) +- +-/* HDMI op codes */ +-#define SDVO_CMD_GET_SUPP_ENCODE 0x9d +-#define SDVO_CMD_GET_ENCODE 0x9e +-#define SDVO_CMD_SET_ENCODE 0x9f +- #define SDVO_ENCODE_DVI 0x0 +- #define SDVO_ENCODE_HDMI 0x1 +-#define SDVO_CMD_SET_PIXEL_REPLI 0x8b +-#define SDVO_CMD_GET_PIXEL_REPLI 0x8c +-#define SDVO_CMD_GET_COLORIMETRY_CAP 0x8d +-#define SDVO_CMD_SET_COLORIMETRY 0x8e +- #define SDVO_COLORIMETRY_RGB256 0x0 +- #define SDVO_COLORIMETRY_RGB220 0x1 +- #define SDVO_COLORIMETRY_YCrCb422 0x3 +- #define SDVO_COLORIMETRY_YCrCb444 0x4 +-#define SDVO_CMD_GET_COLORIMETRY 0x8f +-#define SDVO_CMD_GET_AUDIO_ENCRYPT_PREFER 0x90 +-#define SDVO_CMD_SET_AUDIO_STAT 0x91 +-#define SDVO_CMD_GET_AUDIO_STAT 0x92 +-#define SDVO_CMD_SET_HBUF_INDEX 0x93 +-#define SDVO_CMD_GET_HBUF_INDEX 0x94 +-#define SDVO_CMD_GET_HBUF_INFO 0x95 +-#define SDVO_CMD_SET_HBUF_AV_SPLIT 0x96 +-#define SDVO_CMD_GET_HBUF_AV_SPLIT 0x97 +-#define SDVO_CMD_SET_HBUF_DATA 0x98 +-#define SDVO_CMD_GET_HBUF_DATA 0x99 +-#define SDVO_CMD_SET_HBUF_TXRATE 0x9a +-#define SDVO_CMD_GET_HBUF_TXRATE 0x9b +- #define SDVO_HBUF_TX_DISABLED (0 << 6) +- #define SDVO_HBUF_TX_ONCE (2 << 6) +- #define SDVO_HBUF_TX_VSYNC (3 << 6) +-#define SDVO_CMD_GET_AUDIO_TX_INFO 0x9c +- +-struct intel_sdvo_encode{ +- u8 dvi_rev; +- u8 hdmi_rev; +-} __attribute__ ((packed)); ++# define SDVO_CONTROL_BUS_PROM 0x0 ++# define SDVO_CONTROL_BUS_DDC1 0x1 ++# define SDVO_CONTROL_BUS_DDC2 0x2 ++# define SDVO_CONTROL_BUS_DDC3 0x3 +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/drivers/gpu/drm/i915/intel_tv.c linux-2.6.29-rc3.owrt/drivers/gpu/drm/i915/intel_tv.c +--- linux-2.6.29.owrt/drivers/gpu/drm/i915/intel_tv.c 2009-05-10 22:04:38.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/drivers/gpu/drm/i915/intel_tv.c 2009-05-10 23:48:28.000000000 +0200 +@@ -411,7 +411,7 @@ + * These values account for -1s required. + */ + +-static const struct tv_mode tv_modes[] = { ++const static struct tv_mode tv_modes[] = { + { + .name = "NTSC-M", + .clock = 107520, +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/drivers/gpu/drm/Kconfig linux-2.6.29-rc3.owrt/drivers/gpu/drm/Kconfig +--- linux-2.6.29.owrt/drivers/gpu/drm/Kconfig 2009-05-10 22:04:38.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/drivers/gpu/drm/Kconfig 2009-05-10 23:48:28.000000000 +0200 +@@ -70,7 +70,7 @@ + select FB_CFB_FILLRECT + select FB_CFB_COPYAREA + select FB_CFB_IMAGEBLIT +- select FB ++ depends on FB + tristate "i915 driver" + help + Choose this option if you have a system that has Intel 830M, 845G, +@@ -80,17 +80,18 @@ + XFree86 4.4 and above. If unsure, build this and i830 as modules and + the X server will load the correct one. + ++endchoice ++ + config DRM_I915_KMS + bool "Enable modesetting on intel by default" + depends on DRM_I915 + help +- Choose this option if you want kernel modesetting enabled by default, +- and you have a new enough userspace to support this. Running old +- userspaces with this enabled will cause pain. Note that this causes +- the driver to bind to PCI devices, which precludes loading things +- like intelfb. ++ Choose this option if you want kernel modesetting enabled by default, ++ and you have a new enough userspace to support this. Running old ++ userspaces with this enabled will cause pain. Note that this causes ++ the driver to bind to PCI devices, which precludes loading things ++ like intelfb. + +-endchoice + + config DRM_MGA + tristate "Matrox g200/g400" +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/drivers/gpu/drm/radeon/radeon_cp.c linux-2.6.29-rc3.owrt/drivers/gpu/drm/radeon/radeon_cp.c +--- linux-2.6.29.owrt/drivers/gpu/drm/radeon/radeon_cp.c 2009-05-10 22:04:38.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/drivers/gpu/drm/radeon/radeon_cp.c 2009-05-10 23:48:28.000000000 +0200 +@@ -557,10 +557,8 @@ + } + + static void radeon_cp_init_ring_buffer(struct drm_device * dev, +- drm_radeon_private_t *dev_priv, +- struct drm_file *file_priv) ++ drm_radeon_private_t * dev_priv) + { +- struct drm_radeon_master_private *master_priv; + u32 ring_start, cur_read_ptr; + u32 tmp; + +@@ -679,14 +677,6 @@ + dev_priv->scratch[2] = 0; + RADEON_WRITE(RADEON_LAST_CLEAR_REG, 0); + +- /* reset sarea copies of these */ +- master_priv = file_priv->master->driver_priv; +- if (master_priv->sarea_priv) { +- master_priv->sarea_priv->last_frame = 0; +- master_priv->sarea_priv->last_dispatch = 0; +- master_priv->sarea_priv->last_clear = 0; +- } +- + radeon_do_wait_for_idle(dev_priv); + + /* Sync everything up */ +@@ -1049,9 +1039,9 @@ + + #if __OS_HAS_AGP + if (dev_priv->flags & RADEON_IS_AGP) { +- drm_core_ioremap_wc(dev_priv->cp_ring, dev); +- drm_core_ioremap_wc(dev_priv->ring_rptr, dev); +- drm_core_ioremap_wc(dev->agp_buffer_map, dev); ++ drm_core_ioremap(dev_priv->cp_ring, dev); ++ drm_core_ioremap(dev_priv->ring_rptr, dev); ++ drm_core_ioremap(dev->agp_buffer_map, dev); + if (!dev_priv->cp_ring->handle || + !dev_priv->ring_rptr->handle || + !dev->agp_buffer_map->handle) { +@@ -1225,7 +1215,7 @@ + } + + radeon_cp_load_microcode(dev_priv); +- radeon_cp_init_ring_buffer(dev, dev_priv, file_priv); ++ radeon_cp_init_ring_buffer(dev, dev_priv); + + dev_priv->last_buf = 0; + +@@ -1291,7 +1281,7 @@ + * + * Charl P. Botha <http://cpbotha.net> + */ +-static int radeon_do_resume_cp(struct drm_device *dev, struct drm_file *file_priv) ++static int radeon_do_resume_cp(struct drm_device * dev) + { + drm_radeon_private_t *dev_priv = dev->dev_private; + +@@ -1314,7 +1304,7 @@ + } + + radeon_cp_load_microcode(dev_priv); +- radeon_cp_init_ring_buffer(dev, dev_priv, file_priv); ++ radeon_cp_init_ring_buffer(dev, dev_priv); + + radeon_do_engine_reset(dev); + radeon_irq_set_state(dev, RADEON_SW_INT_ENABLE, 1); +@@ -1489,7 +1479,8 @@ + */ + int radeon_cp_resume(struct drm_device *dev, void *data, struct drm_file *file_priv) + { +- return radeon_do_resume_cp(dev, file_priv); ++ ++ return radeon_do_resume_cp(dev); + } + + int radeon_engine_reset(struct drm_device *dev, void *data, struct drm_file *file_priv) +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/drivers/hid/hid-core.c linux-2.6.29-rc3.owrt/drivers/hid/hid-core.c +--- linux-2.6.29.owrt/drivers/hid/hid-core.c 2009-05-10 22:04:38.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/drivers/hid/hid-core.c 2009-05-10 23:48:28.000000000 +0200 +@@ -1218,7 +1218,6 @@ + } + EXPORT_SYMBOL_GPL(hid_connect); + +-/* a list of devices for which there is a specialized driver on HID bus */ + static const struct hid_device_id hid_blacklist[] = { + { HID_USB_DEVICE(USB_VENDOR_ID_A4TECH, USB_DEVICE_ID_A4TECH_WCP32PU) }, + { HID_USB_DEVICE(USB_VENDOR_ID_A4TECH, USB_DEVICE_ID_A4TECH_X5_005D) }, +@@ -1300,13 +1299,7 @@ + { HID_USB_DEVICE(USB_VENDOR_ID_SONY, USB_DEVICE_ID_SONY_PS3_CONTROLLER) }, + { HID_USB_DEVICE(USB_VENDOR_ID_SONY, USB_DEVICE_ID_SONY_VAIO_VGX_MOUSE) }, + { HID_USB_DEVICE(USB_VENDOR_ID_SUNPLUS, USB_DEVICE_ID_SUNPLUS_WDESKTOP) }, +- { HID_USB_DEVICE(USB_VENDOR_ID_THRUSTMASTER, 0xb300) }, +- { HID_USB_DEVICE(USB_VENDOR_ID_THRUSTMASTER, 0xb304) }, +- { HID_USB_DEVICE(USB_VENDOR_ID_THRUSTMASTER, 0xb651) }, +- { HID_USB_DEVICE(USB_VENDOR_ID_THRUSTMASTER, 0xb654) }, + { HID_USB_DEVICE(USB_VENDOR_ID_TOPSEED, USB_DEVICE_ID_TOPSEED_CYBERLINK) }, +- { HID_USB_DEVICE(USB_VENDOR_ID_ZEROPLUS, 0x0005) }, +- { HID_USB_DEVICE(USB_VENDOR_ID_ZEROPLUS, 0x0030) }, + + { HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_APPLE, 0x030c) }, + { HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_MICROSOFT, USB_DEVICE_ID_MS_PRESENTER_8K_BT) }, +@@ -1483,7 +1476,6 @@ + .uevent = hid_uevent, + }; + +-/* a list of devices that shouldn't be handled by HID core at all */ + static const struct hid_device_id hid_ignore_list[] = { + { HID_USB_DEVICE(USB_VENDOR_ID_ACECAD, USB_DEVICE_ID_ACECAD_FLAIR) }, + { HID_USB_DEVICE(USB_VENDOR_ID_ACECAD, USB_DEVICE_ID_ACECAD_302) }, +@@ -1611,14 +1603,15 @@ + { HID_USB_DEVICE(USB_VENDOR_ID_PANJIT, 0x0002) }, + { HID_USB_DEVICE(USB_VENDOR_ID_PANJIT, 0x0003) }, + { HID_USB_DEVICE(USB_VENDOR_ID_PANJIT, 0x0004) }, +- { HID_USB_DEVICE(USB_VENDOR_ID_POWERCOM, USB_DEVICE_ID_POWERCOM_UPS) }, + { HID_USB_DEVICE(USB_VENDOR_ID_SOUNDGRAPH, USB_DEVICE_ID_SOUNDGRAPH_IMON_LCD) }, + { HID_USB_DEVICE(USB_VENDOR_ID_SOUNDGRAPH, USB_DEVICE_ID_SOUNDGRAPH_IMON_LCD2) }, + { HID_USB_DEVICE(USB_VENDOR_ID_SOUNDGRAPH, USB_DEVICE_ID_SOUNDGRAPH_IMON_LCD3) }, +- { HID_USB_DEVICE(USB_VENDOR_ID_SOUNDGRAPH, USB_DEVICE_ID_SOUNDGRAPH_IMON_LCD4) }, +- { HID_USB_DEVICE(USB_VENDOR_ID_SOUNDGRAPH, USB_DEVICE_ID_SOUNDGRAPH_IMON_LCD5) }, + { HID_USB_DEVICE(USB_VENDOR_ID_TENX, USB_DEVICE_ID_TENX_IBUDDY1) }, + { HID_USB_DEVICE(USB_VENDOR_ID_TENX, USB_DEVICE_ID_TENX_IBUDDY2) }, ++ { HID_USB_DEVICE(USB_VENDOR_ID_THRUSTMASTER, 0xb300) }, ++ { HID_USB_DEVICE(USB_VENDOR_ID_THRUSTMASTER, 0xb304) }, ++ { HID_USB_DEVICE(USB_VENDOR_ID_THRUSTMASTER, 0xb651) }, ++ { HID_USB_DEVICE(USB_VENDOR_ID_THRUSTMASTER, 0xb654) }, + { HID_USB_DEVICE(USB_VENDOR_ID_VERNIER, USB_DEVICE_ID_VERNIER_LABPRO) }, + { HID_USB_DEVICE(USB_VENDOR_ID_VERNIER, USB_DEVICE_ID_VERNIER_GOTEMP) }, + { HID_USB_DEVICE(USB_VENDOR_ID_VERNIER, USB_DEVICE_ID_VERNIER_SKIP) }, +@@ -1629,6 +1622,8 @@ + { HID_USB_DEVICE(USB_VENDOR_ID_WISEGROUP, USB_DEVICE_ID_1_PHIDGETSERVO_20) }, + { HID_USB_DEVICE(USB_VENDOR_ID_WISEGROUP, USB_DEVICE_ID_8_8_4_IF_KIT) }, + { HID_USB_DEVICE(USB_VENDOR_ID_YEALINK, USB_DEVICE_ID_YEALINK_P1K_P4K_B2K) }, ++ { HID_USB_DEVICE(USB_VENDOR_ID_ZEROPLUS, 0x0005) }, ++ { HID_USB_DEVICE(USB_VENDOR_ID_ZEROPLUS, 0x0030) }, + { } + }; + +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/drivers/hid/hid-ids.h linux-2.6.29-rc3.owrt/drivers/hid/hid-ids.h +--- linux-2.6.29.owrt/drivers/hid/hid-ids.h 2009-05-10 22:04:38.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/drivers/hid/hid-ids.h 2009-05-10 23:48:28.000000000 +0200 +@@ -348,9 +348,6 @@ + #define USB_VENDOR_ID_PLAYDOTCOM 0x0b43 + #define USB_DEVICE_ID_PLAYDOTCOM_EMS_USBII 0x0003 + +-#define USB_VENDOR_ID_POWERCOM 0x0d9f +-#define USB_DEVICE_ID_POWERCOM_UPS 0x0002 +- + #define USB_VENDOR_ID_SAITEK 0x06a3 + #define USB_DEVICE_ID_SAITEK_RUMBLEPAD 0xff17 + +@@ -365,8 +362,6 @@ + #define USB_DEVICE_ID_SOUNDGRAPH_IMON_LCD 0x0038 + #define USB_DEVICE_ID_SOUNDGRAPH_IMON_LCD2 0x0036 + #define USB_DEVICE_ID_SOUNDGRAPH_IMON_LCD3 0x0034 +-#define USB_DEVICE_ID_SOUNDGRAPH_IMON_LCD4 0x0044 +-#define USB_DEVICE_ID_SOUNDGRAPH_IMON_LCD5 0x0045 + + #define USB_VENDOR_ID_SUN 0x0430 + #define USB_DEVICE_ID_RARITAN_KVM_DONGLE 0xcdab +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/drivers/hid/hid-microsoft.c linux-2.6.29-rc3.owrt/drivers/hid/hid-microsoft.c +--- linux-2.6.29.owrt/drivers/hid/hid-microsoft.c 2009-05-10 22:04:38.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/drivers/hid/hid-microsoft.c 2009-05-10 23:48:28.000000000 +0200 +@@ -30,7 +30,7 @@ + #define MS_NOGET 0x10 + + /* +- * Microsoft Wireless Desktop Receiver (Model 1028) has ++ * Microsoft Wireless Desktop Receiver (Model 1028) has several + * 'Usage Min/Max' where it ought to have 'Physical Min/Max' + */ + static void ms_report_fixup(struct hid_device *hdev, __u8 *rdesc, +@@ -38,12 +38,17 @@ + { + unsigned long quirks = (unsigned long)hid_get_drvdata(hdev); + +- if ((quirks & MS_RDESC) && rsize == 571 && rdesc[557] == 0x19 && ++ if ((quirks & MS_RDESC) && rsize == 571 && rdesc[284] == 0x19 && ++ rdesc[286] == 0x2a && rdesc[304] == 0x19 && ++ rdesc[306] == 0x29 && rdesc[352] == 0x1a && ++ rdesc[355] == 0x2a && rdesc[557] == 0x19 && + rdesc[559] == 0x29) { + dev_info(&hdev->dev, "fixing up Microsoft Wireless Receiver " + "Model 1028 report descriptor\n"); +- rdesc[557] = 0x35; +- rdesc[559] = 0x45; ++ rdesc[284] = rdesc[304] = rdesc[557] = 0x35; ++ rdesc[352] = 0x36; ++ rdesc[286] = rdesc[355] = 0x46; ++ rdesc[306] = rdesc[559] = 0x45; + } + } + +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/drivers/hid/hidraw.c linux-2.6.29-rc3.owrt/drivers/hid/hidraw.c +--- linux-2.6.29.owrt/drivers/hid/hidraw.c 2009-05-10 22:04:38.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/drivers/hid/hidraw.c 2009-05-10 23:48:28.000000000 +0200 +@@ -267,10 +267,8 @@ + default: + { + struct hid_device *hid = dev->hid; +- if (_IOC_TYPE(cmd) != 'H' || _IOC_DIR(cmd) != _IOC_READ) { +- ret = -EINVAL; +- break; +- } ++ if (_IOC_TYPE(cmd) != 'H' || _IOC_DIR(cmd) != _IOC_READ) ++ return -EINVAL; + + if (_IOC_NR(cmd) == _IOC_NR(HIDIOCGRAWNAME(0))) { + int len; +@@ -279,9 +277,8 @@ + len = strlen(hid->name) + 1; + if (len > _IOC_SIZE(cmd)) + len = _IOC_SIZE(cmd); +- ret = copy_to_user(user_arg, hid->name, len) ? ++ return copy_to_user(user_arg, hid->name, len) ? + -EFAULT : len; +- break; + } + + if (_IOC_NR(cmd) == _IOC_NR(HIDIOCGRAWPHYS(0))) { +@@ -291,13 +288,12 @@ + len = strlen(hid->phys) + 1; + if (len > _IOC_SIZE(cmd)) + len = _IOC_SIZE(cmd); +- ret = copy_to_user(user_arg, hid->phys, len) ? ++ return copy_to_user(user_arg, hid->phys, len) ? + -EFAULT : len; +- break; + } + } + +- ret = -ENOTTY; ++ ret = -ENOTTY; + } + unlock_kernel(); + return ret; +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/drivers/hid/usbhid/hiddev.c linux-2.6.29-rc3.owrt/drivers/hid/usbhid/hiddev.c +--- linux-2.6.29.owrt/drivers/hid/usbhid/hiddev.c 2009-05-10 22:04:38.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/drivers/hid/usbhid/hiddev.c 2009-05-10 23:48:28.000000000 +0200 +@@ -306,7 +306,7 @@ + return 0; + bail: + file->private_data = NULL; +- kfree(list); ++ kfree(list->hiddev); + return res; + } + +@@ -323,7 +323,7 @@ + */ + static ssize_t hiddev_read(struct file * file, char __user * buffer, size_t count, loff_t *ppos) + { +- DEFINE_WAIT(wait); ++ DECLARE_WAITQUEUE(wait, current); + struct hiddev_list *list = file->private_data; + int event_size; + int retval; +@@ -656,7 +656,7 @@ + + case HIDIOCGSTRING: + mutex_lock(&hiddev->existancelock); +- if (hiddev->exist) ++ if (!hiddev->exist) + r = hiddev_ioctl_string(hiddev, cmd, user_arg); + else + r = -ENODEV; +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/drivers/hwmon/abituguru3.c linux-2.6.29-rc3.owrt/drivers/hwmon/abituguru3.c +--- linux-2.6.29.owrt/drivers/hwmon/abituguru3.c 2009-05-10 22:04:39.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/drivers/hwmon/abituguru3.c 2009-05-10 23:48:28.000000000 +0200 +@@ -760,11 +760,8 @@ + + for (i = 0; i < offset_count; i++) + if ((x = abituguru3_read(data, bank, offset + i, count, +- buf + i * count)) != count) { +- if (x < 0) +- return x; +- return i * count + x; +- } ++ buf + i * count)) != count) ++ return i * count + (i && (x < 0)) ? 0 : x; + + return i * count; + } +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/drivers/hwmon/applesmc.c linux-2.6.29-rc3.owrt/drivers/hwmon/applesmc.c +--- linux-2.6.29.owrt/drivers/hwmon/applesmc.c 2009-05-10 22:04:39.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/drivers/hwmon/applesmc.c 2009-05-10 23:48:28.000000000 +0200 +@@ -83,7 +83,7 @@ + /* + * Temperature sensors keys (sp78 - 2 bytes). + */ +-static const char *temperature_sensors_sets[][41] = { ++static const char* temperature_sensors_sets[][36] = { + /* Set 0: Macbook Pro */ + { "TA0P", "TB0T", "TC0D", "TC0P", "TG0H", "TG0P", "TG0T", "Th0H", + "Th1H", "Tm0P", "Ts0P", "Ts1P", NULL }, +@@ -135,13 +135,6 @@ + { "TB0T", "TB1S", "TB1T", "TB2S", "TB2T", "TC0D", "TN0D", "TTF0", + "TV0P", "TVFP", "TW0P", "Th0P", "Tp0P", "Tp1P", "TpFP", "Ts0P", + "Ts0S", NULL }, +-/* Set 16: Mac Pro 3,1 (2 x Quad-Core) */ +- { "TA0P", "TCAG", "TCAH", "TCBG", "TCBH", "TC0C", "TC0D", "TC0P", +- "TC1C", "TC1D", "TC2C", "TC2D", "TC3C", "TC3D", "TH0P", "TH1P", +- "TH2P", "TH3P", "TMAP", "TMAS", "TMBS", "TM0P", "TM0S", "TM1P", +- "TM1S", "TM2P", "TM2S", "TM3S", "TM8P", "TM8S", "TM9P", "TM9S", +- "TN0C", "TN0D", "TN0H", "TS0C", "Tp0C", "Tp1C", "Tv0S", "Tv1S", +- NULL }, + }; + + /* List of keys used to read/write fan speeds */ +@@ -1160,16 +1153,6 @@ + applesmc_show_temperature, NULL, 33); + static SENSOR_DEVICE_ATTR(temp35_input, S_IRUGO, + applesmc_show_temperature, NULL, 34); +-static SENSOR_DEVICE_ATTR(temp36_input, S_IRUGO, +- applesmc_show_temperature, NULL, 35); +-static SENSOR_DEVICE_ATTR(temp37_input, S_IRUGO, +- applesmc_show_temperature, NULL, 36); +-static SENSOR_DEVICE_ATTR(temp38_input, S_IRUGO, +- applesmc_show_temperature, NULL, 37); +-static SENSOR_DEVICE_ATTR(temp39_input, S_IRUGO, +- applesmc_show_temperature, NULL, 38); +-static SENSOR_DEVICE_ATTR(temp40_input, S_IRUGO, +- applesmc_show_temperature, NULL, 39); + + static struct attribute *temperature_attributes[] = { + &sensor_dev_attr_temp1_input.dev_attr.attr, +@@ -1207,11 +1190,6 @@ + &sensor_dev_attr_temp33_input.dev_attr.attr, + &sensor_dev_attr_temp34_input.dev_attr.attr, + &sensor_dev_attr_temp35_input.dev_attr.attr, +- &sensor_dev_attr_temp36_input.dev_attr.attr, +- &sensor_dev_attr_temp37_input.dev_attr.attr, +- &sensor_dev_attr_temp38_input.dev_attr.attr, +- &sensor_dev_attr_temp39_input.dev_attr.attr, +- &sensor_dev_attr_temp40_input.dev_attr.attr, + NULL + }; + +@@ -1334,8 +1312,6 @@ + { .accelerometer = 0, .light = 0, .temperature_set = 14 }, + /* MacBook Air 2,1: accelerometer, backlight and temperature set 15 */ + { .accelerometer = 1, .light = 1, .temperature_set = 15 }, +-/* MacPro3,1: temperature set 16 */ +- { .accelerometer = 0, .light = 0, .temperature_set = 16 }, + }; + + /* Note that DMI_MATCH(...,"MacBook") will match "MacBookPro1,1". +@@ -1393,10 +1369,6 @@ + DMI_MATCH(DMI_BOARD_VENDOR,"Apple"), + DMI_MATCH(DMI_PRODUCT_NAME,"MacPro2") }, + &applesmc_dmi_data[4]}, +- { applesmc_dmi_match, "Apple MacPro3", { +- DMI_MATCH(DMI_BOARD_VENDOR, "Apple"), +- DMI_MATCH(DMI_PRODUCT_NAME, "MacPro3") }, +- &applesmc_dmi_data[16]}, + { applesmc_dmi_match, "Apple MacPro", { + DMI_MATCH(DMI_BOARD_VENDOR, "Apple"), + DMI_MATCH(DMI_PRODUCT_NAME, "MacPro") }, +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/drivers/hwmon/f71882fg.c linux-2.6.29-rc3.owrt/drivers/hwmon/f71882fg.c +--- linux-2.6.29.owrt/drivers/hwmon/f71882fg.c 2009-05-10 22:04:39.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/drivers/hwmon/f71882fg.c 2009-05-10 23:48:28.000000000 +0200 +@@ -1872,7 +1872,7 @@ + + devid = superio_inw(sioaddr, SIO_REG_MANID); + if (devid != SIO_FINTEK_ID) { +- pr_debug(DRVNAME ": Not a Fintek device\n"); ++ printk(KERN_INFO DRVNAME ": Not a Fintek device\n"); + goto exit; + } + +@@ -1932,7 +1932,7 @@ + res.name = f71882fg_pdev->name; + err = acpi_check_resource_conflict(&res); + if (err) +- goto exit_device_put; ++ return err; + + err = platform_device_add_resources(f71882fg_pdev, &res, 1); + if (err) { +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/drivers/hwmon/f75375s.c linux-2.6.29-rc3.owrt/drivers/hwmon/f75375s.c +--- linux-2.6.29.owrt/drivers/hwmon/f75375s.c 2009-05-10 22:04:39.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/drivers/hwmon/f75375s.c 2009-05-10 23:48:28.000000000 +0200 +@@ -617,7 +617,7 @@ + static int f75375_probe(struct i2c_client *client, + const struct i2c_device_id *id) + { +- struct f75375_data *data; ++ struct f75375_data *data = i2c_get_clientdata(client); + struct f75375s_platform_data *f75375s_pdata = client->dev.platform_data; + int err; + +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/drivers/hwmon/hp_accel.c linux-2.6.29-rc3.owrt/drivers/hwmon/hp_accel.c +--- linux-2.6.29.owrt/drivers/hwmon/hp_accel.c 2009-05-10 22:04:39.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/drivers/hwmon/hp_accel.c 2009-05-10 23:48:28.000000000 +0200 +@@ -153,10 +153,7 @@ + static struct axis_conversion lis3lv02d_axis_x_inverted = {-1, 2, 3}; + static struct axis_conversion lis3lv02d_axis_z_inverted = {1, 2, -3}; + static struct axis_conversion lis3lv02d_axis_xy_rotated_left = {-2, 1, 3}; +-static struct axis_conversion lis3lv02d_axis_xy_rotated_left_usd = {-2, 1, -3}; + static struct axis_conversion lis3lv02d_axis_xy_swap_inverted = {-2, -1, 3}; +-static struct axis_conversion lis3lv02d_axis_xy_rotated_right = {2, -1, 3}; +-static struct axis_conversion lis3lv02d_axis_xy_swap_yz_inverted = {2, -1, -3}; + + #define AXIS_DMI_MATCH(_ident, _name, _axis) { \ + .ident = _ident, \ +@@ -166,18 +163,6 @@ + }, \ + .driver_data = &lis3lv02d_axis_##_axis \ + } +- +-#define AXIS_DMI_MATCH2(_ident, _class1, _name1, \ +- _class2, _name2, \ +- _axis) { \ +- .ident = _ident, \ +- .callback = lis3lv02d_dmi_matched, \ +- .matches = { \ +- DMI_MATCH(DMI_##_class1, _name1), \ +- DMI_MATCH(DMI_##_class2, _name2), \ +- }, \ +- .driver_data = &lis3lv02d_axis_##_axis \ +-} + static struct dmi_system_id lis3lv02d_dmi_ids[] = { + /* product names are truncated to match all kinds of a same model */ + AXIS_DMI_MATCH("NC64x0", "HP Compaq nc64", x_inverted), +@@ -187,22 +172,10 @@ + AXIS_DMI_MATCH("NC2510", "HP Compaq 2510", y_inverted), + AXIS_DMI_MATCH("NC8510", "HP Compaq 8510", xy_swap_inverted), + AXIS_DMI_MATCH("HP2133", "HP 2133", xy_rotated_left), +- AXIS_DMI_MATCH("NC653x", "HP Compaq 653", xy_rotated_left_usd), +- AXIS_DMI_MATCH("NC673x", "HP Compaq 673", xy_rotated_left_usd), +- AXIS_DMI_MATCH("NC651xx", "HP Compaq 651", xy_rotated_right), +- AXIS_DMI_MATCH("NC671xx", "HP Compaq 671", xy_swap_yz_inverted), +- /* Intel-based HP Pavilion dv5 */ +- AXIS_DMI_MATCH2("HPDV5_I", +- PRODUCT_NAME, "HP Pavilion dv5", +- BOARD_NAME, "3603", +- x_inverted), +- /* AMD-based HP Pavilion dv5 */ +- AXIS_DMI_MATCH2("HPDV5_A", +- PRODUCT_NAME, "HP Pavilion dv5", +- BOARD_NAME, "3600", +- y_inverted), + { NULL, } + /* Laptop models without axis info (yet): ++ * "NC651xx" "HP Compaq 651" ++ * "NC671xx" "HP Compaq 671" + * "NC6910" "HP Compaq 6910" + * HP Compaq 8710x Notebook PC / Mobile Workstation + * "NC2400" "HP Compaq nc2400" +@@ -235,49 +208,9 @@ + .set_brightness = hpled_set, + }; + +-static acpi_status +-lis3lv02d_get_resource(struct acpi_resource *resource, void *context) +-{ +- if (resource->type == ACPI_RESOURCE_TYPE_EXTENDED_IRQ) { +- struct acpi_resource_extended_irq *irq; +- u32 *device_irq = context; +- +- irq = &resource->data.extended_irq; +- *device_irq = irq->interrupts[0]; +- } +- +- return AE_OK; +-} +- +-static void lis3lv02d_enum_resources(struct acpi_device *device) +-{ +- acpi_status status; +- +- status = acpi_walk_resources(device->handle, METHOD_NAME__CRS, +- lis3lv02d_get_resource, &adev.irq); +- if (ACPI_FAILURE(status)) +- printk(KERN_DEBUG DRIVER_NAME ": Error getting resources\n"); +-} +- +-static s16 lis3lv02d_read_16(acpi_handle handle, int reg) +-{ +- u8 lo, hi; +- +- adev.read(handle, reg - 1, &lo); +- adev.read(handle, reg, &hi); +- /* In "12 bit right justified" mode, bit 6, bit 7, bit 8 = bit 5 */ +- return (s16)((hi << 8) | lo); +-} +- +-static s16 lis3lv02d_read_8(acpi_handle handle, int reg) +-{ +- s8 lo; +- adev.read(handle, reg, &lo); +- return lo; +-} +- + static int lis3lv02d_add(struct acpi_device *device) + { ++ u8 val; + int ret; + + if (!device) +@@ -291,22 +224,10 @@ + strcpy(acpi_device_class(device), ACPI_MDPS_CLASS); + device->driver_data = &adev; + +- lis3lv02d_acpi_read(device->handle, WHO_AM_I, &adev.whoami); +- switch (adev.whoami) { +- case LIS_DOUBLE_ID: +- printk(KERN_INFO DRIVER_NAME ": 2-byte sensor found\n"); +- adev.read_data = lis3lv02d_read_16; +- adev.mdps_max_val = 2048; +- break; +- case LIS_SINGLE_ID: +- printk(KERN_INFO DRIVER_NAME ": 1-byte sensor found\n"); +- adev.read_data = lis3lv02d_read_8; +- adev.mdps_max_val = 128; +- break; +- default: ++ lis3lv02d_acpi_read(device->handle, WHO_AM_I, &val); ++ if ((val != LIS3LV02DL_ID) && (val != LIS302DL_ID)) { + printk(KERN_ERR DRIVER_NAME +- ": unknown sensor type 0x%X\n", adev.whoami); +- return -EINVAL; ++ ": Accelerometer chip not LIS3LV02D{L,Q}\n"); + } + + /* If possible use a "standard" axes order */ +@@ -321,9 +242,6 @@ + if (ret) + return ret; + +- /* obtain IRQ number of our device from ACPI */ +- lis3lv02d_enum_resources(adev.device); +- + ret = lis3lv02d_init_device(&adev); + if (ret) { + flush_work(&hpled_led.work); +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/drivers/hwmon/it87.c linux-2.6.29-rc3.owrt/drivers/hwmon/it87.c +--- linux-2.6.29.owrt/drivers/hwmon/it87.c 2009-05-10 22:04:39.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/drivers/hwmon/it87.c 2009-05-10 23:48:28.000000000 +0200 +@@ -213,7 +213,7 @@ + + #define TEMP_TO_REG(val) (SENSORS_LIMIT(((val)<0?(((val)-500)/1000):\ + ((val)+500)/1000),-128,127)) +-#define TEMP_FROM_REG(val) ((val) * 1000) ++#define TEMP_FROM_REG(val) (((val)>0x80?(val)-0x100:(val))*1000) + + #define PWM_TO_REG(val) ((val) >> 1) + #define PWM_FROM_REG(val) (((val)&0x7f) << 1) +@@ -267,9 +267,9 @@ + u8 has_fan; /* Bitfield, fans enabled */ + u16 fan[5]; /* Register values, possibly combined */ + u16 fan_min[5]; /* Register values, possibly combined */ +- s8 temp[3]; /* Register value */ +- s8 temp_high[3]; /* Register value */ +- s8 temp_low[3]; /* Register value */ ++ u8 temp[3]; /* Register value */ ++ u8 temp_high[3]; /* Register value */ ++ u8 temp_low[3]; /* Register value */ + u8 sensor; /* Register value */ + u8 fan_div[3]; /* Register encoding, shifted right */ + u8 vid; /* Register encoding, combined */ +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/drivers/hwmon/Kconfig linux-2.6.29-rc3.owrt/drivers/hwmon/Kconfig +--- linux-2.6.29.owrt/drivers/hwmon/Kconfig 2009-05-10 22:04:39.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/drivers/hwmon/Kconfig 2009-05-10 23:48:28.000000000 +0200 +@@ -543,8 +543,8 @@ + help + If you say yes here you get support for National Semiconductor LM90, + LM86, LM89 and LM99, Analog Devices ADM1032 and ADT7461, and Maxim +- MAX6646, MAX6647, MAX6648, MAX6649, MAX6657, MAX6658, MAX6659, +- MAX6680, MAX6681 and MAX6692 sensor chips. ++ MAX6646, MAX6647, MAX6649, MAX6657, MAX6658, MAX6659, MAX6680 and ++ MAX6681 sensor chips. + + This driver can also be built as a module. If so, the module + will be called lm90. +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/drivers/hwmon/lis3lv02d.c linux-2.6.29-rc3.owrt/drivers/hwmon/lis3lv02d.c +--- linux-2.6.29.owrt/drivers/hwmon/lis3lv02d.c 2009-05-10 22:04:39.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/drivers/hwmon/lis3lv02d.c 2009-05-10 23:48:28.000000000 +0200 +@@ -3,7 +3,7 @@ + * + * Copyright (C) 2007-2008 Yan Burman + * Copyright (C) 2008 Eric Piel +- * Copyright (C) 2008-2009 Pavel Machek ++ * Copyright (C) 2008 Pavel Machek + * + * 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 +@@ -35,7 +35,6 @@ + #include <linux/poll.h> + #include <linux/freezer.h> + #include <linux/uaccess.h> +-#include <linux/miscdevice.h> + #include <acpi/acpi_drivers.h> + #include <asm/atomic.h> + #include "lis3lv02d.h" +@@ -53,14 +52,24 @@ + * joystick. + */ + +-struct acpi_lis3lv02d adev = { +- .misc_wait = __WAIT_QUEUE_HEAD_INITIALIZER(adev.misc_wait), +-}; ++/* Maximum value our axis may get for the input device (signed 12 bits) */ ++#define MDPS_MAX_VAL 2048 + ++struct acpi_lis3lv02d adev; + EXPORT_SYMBOL_GPL(adev); + + static int lis3lv02d_add_fs(struct acpi_device *device); + ++static s16 lis3lv02d_read_16(acpi_handle handle, int reg) ++{ ++ u8 lo, hi; ++ ++ adev.read(handle, reg, &lo); ++ adev.read(handle, reg + 1, &hi); ++ /* In "12 bit right justified" mode, bit 6, bit 7, bit 8 = bit 5 */ ++ return (s16)((hi << 8) | lo); ++} ++ + /** + * lis3lv02d_get_axis - For the given axis, give the value converted + * @axis: 1,2,3 - can also be negative +@@ -89,9 +98,9 @@ + { + int position[3]; + +- position[0] = adev.read_data(handle, OUTX); +- position[1] = adev.read_data(handle, OUTY); +- position[2] = adev.read_data(handle, OUTZ); ++ position[0] = lis3lv02d_read_16(handle, OUTX_L); ++ position[1] = lis3lv02d_read_16(handle, OUTY_L); ++ position[2] = lis3lv02d_read_16(handle, OUTZ_L); + + *x = lis3lv02d_get_axis(adev.ac.x, position); + *y = lis3lv02d_get_axis(adev.ac.y, position); +@@ -101,13 +110,26 @@ + void lis3lv02d_poweroff(acpi_handle handle) + { + adev.is_on = 0; ++ /* disable X,Y,Z axis and power down */ ++ adev.write(handle, CTRL_REG1, 0x00); + } + EXPORT_SYMBOL_GPL(lis3lv02d_poweroff); + + void lis3lv02d_poweron(acpi_handle handle) + { ++ u8 val; ++ + adev.is_on = 1; + adev.init(handle); ++ adev.write(handle, FF_WU_CFG, 0); ++ /* ++ * BDU: LSB and MSB values are not updated until both have been read. ++ * So the value read will always be correct. ++ * IEN: Interrupt for free-fall and DD, not for data-ready. ++ */ ++ adev.read(handle, CTRL_REG2, &val); ++ val |= CTRL2_BDU | CTRL2_IEN; ++ adev.write(handle, CTRL_REG2, val); + } + EXPORT_SYMBOL_GPL(lis3lv02d_poweron); + +@@ -140,140 +162,6 @@ + mutex_unlock(&dev->lock); + } + +-static irqreturn_t lis302dl_interrupt(int irq, void *dummy) +-{ +- /* +- * Be careful: on some HP laptops the bios force DD when on battery and +- * the lid is closed. This leads to interrupts as soon as a little move +- * is done. +- */ +- atomic_inc(&adev.count); +- +- wake_up_interruptible(&adev.misc_wait); +- kill_fasync(&adev.async_queue, SIGIO, POLL_IN); +- return IRQ_HANDLED; +-} +- +-static int lis3lv02d_misc_open(struct inode *inode, struct file *file) +-{ +- int ret; +- +- if (test_and_set_bit(0, &adev.misc_opened)) +- return -EBUSY; /* already open */ +- +- atomic_set(&adev.count, 0); +- +- /* +- * The sensor can generate interrupts for free-fall and direction +- * detection (distinguishable with FF_WU_SRC and DD_SRC) but to keep +- * the things simple and _fast_ we activate it only for free-fall, so +- * no need to read register (very slow with ACPI). For the same reason, +- * we forbid shared interrupts. +- * +- * IRQF_TRIGGER_RISING seems pointless on HP laptops because the +- * io-apic is not configurable (and generates a warning) but I keep it +- * in case of support for other hardware. +- */ +- ret = request_irq(adev.irq, lis302dl_interrupt, IRQF_TRIGGER_RISING, +- DRIVER_NAME, &adev); +- +- if (ret) { +- clear_bit(0, &adev.misc_opened); +- printk(KERN_ERR DRIVER_NAME ": IRQ%d allocation failed\n", adev.irq); +- return -EBUSY; +- } +- lis3lv02d_increase_use(&adev); +- printk("lis3: registered interrupt %d\n", adev.irq); +- return 0; +-} +- +-static int lis3lv02d_misc_release(struct inode *inode, struct file *file) +-{ +- fasync_helper(-1, file, 0, &adev.async_queue); +- lis3lv02d_decrease_use(&adev); +- free_irq(adev.irq, &adev); +- clear_bit(0, &adev.misc_opened); /* release the device */ +- return 0; +-} +- +-static ssize_t lis3lv02d_misc_read(struct file *file, char __user *buf, +- size_t count, loff_t *pos) +-{ +- DECLARE_WAITQUEUE(wait, current); +- u32 data; +- unsigned char byte_data; +- ssize_t retval = 1; +- +- if (count < 1) +- return -EINVAL; +- +- add_wait_queue(&adev.misc_wait, &wait); +- while (true) { +- set_current_state(TASK_INTERRUPTIBLE); +- data = atomic_xchg(&adev.count, 0); +- if (data) +- break; +- +- if (file->f_flags & O_NONBLOCK) { +- retval = -EAGAIN; +- goto out; +- } +- +- if (signal_pending(current)) { +- retval = -ERESTARTSYS; +- goto out; +- } +- +- schedule(); +- } +- +- if (data < 255) +- byte_data = data; +- else +- byte_data = 255; +- +- /* make sure we are not going into copy_to_user() with +- * TASK_INTERRUPTIBLE state */ +- set_current_state(TASK_RUNNING); +- if (copy_to_user(buf, &byte_data, sizeof(byte_data))) +- retval = -EFAULT; +- +-out: +- __set_current_state(TASK_RUNNING); +- remove_wait_queue(&adev.misc_wait, &wait); +- +- return retval; +-} +- +-static unsigned int lis3lv02d_misc_poll(struct file *file, poll_table *wait) +-{ +- poll_wait(file, &adev.misc_wait, wait); +- if (atomic_read(&adev.count)) +- return POLLIN | POLLRDNORM; +- return 0; +-} +- +-static int lis3lv02d_misc_fasync(int fd, struct file *file, int on) +-{ +- return fasync_helper(fd, file, on, &adev.async_queue); +-} +- +-static const struct file_operations lis3lv02d_misc_fops = { +- .owner = THIS_MODULE, +- .llseek = no_llseek, +- .read = lis3lv02d_misc_read, +- .open = lis3lv02d_misc_open, +- .release = lis3lv02d_misc_release, +- .poll = lis3lv02d_misc_poll, +- .fasync = lis3lv02d_misc_fasync, +-}; +- +-static struct miscdevice lis3lv02d_misc_device = { +- .minor = MISC_DYNAMIC_MINOR, +- .name = "freefall", +- .fops = &lis3lv02d_misc_fops, +-}; +- + /** + * lis3lv02d_joystick_kthread - Kthread polling function + * @data: unused - here to conform to threadfn prototype +@@ -315,6 +203,7 @@ + lis3lv02d_decrease_use(&adev); + } + ++ + static inline void lis3lv02d_calibrate_joystick(void) + { + lis3lv02d_get_xyz(adev.device->handle, &adev.xcalib, &adev.ycalib, &adev.zcalib); +@@ -342,9 +231,9 @@ + adev.idev->close = lis3lv02d_joystick_close; + + set_bit(EV_ABS, adev.idev->evbit); +- input_set_abs_params(adev.idev, ABS_X, -adev.mdps_max_val, adev.mdps_max_val, 3, 3); +- input_set_abs_params(adev.idev, ABS_Y, -adev.mdps_max_val, adev.mdps_max_val, 3, 3); +- input_set_abs_params(adev.idev, ABS_Z, -adev.mdps_max_val, adev.mdps_max_val, 3, 3); ++ input_set_abs_params(adev.idev, ABS_X, -MDPS_MAX_VAL, MDPS_MAX_VAL, 3, 3); ++ input_set_abs_params(adev.idev, ABS_Y, -MDPS_MAX_VAL, MDPS_MAX_VAL, 3, 3); ++ input_set_abs_params(adev.idev, ABS_Z, -MDPS_MAX_VAL, MDPS_MAX_VAL, 3, 3); + + err = input_register_device(adev.idev); + if (err) { +@@ -361,7 +250,6 @@ + if (!adev.idev) + return; + +- misc_deregister(&lis3lv02d_misc_device); + input_unregister_device(adev.idev); + adev.idev = NULL; + } +@@ -380,19 +268,6 @@ + if (lis3lv02d_joystick_enable()) + printk(KERN_ERR DRIVER_NAME ": joystick initialization failed\n"); + +- printk("lis3_init_device: irq %d\n", dev->irq); +- +- /* if we did not get an IRQ from ACPI - we have nothing more to do */ +- if (!dev->irq) { +- printk(KERN_ERR DRIVER_NAME +- ": No IRQ in ACPI. Disabling /dev/freefall\n"); +- goto out; +- } +- +- printk("lis3: registering device\n"); +- if (misc_register(&lis3lv02d_misc_device)) +- printk(KERN_ERR DRIVER_NAME ": misc_register failed\n"); +-out: + lis3lv02d_decrease_use(dev); + return 0; + } +@@ -476,6 +351,6 @@ + EXPORT_SYMBOL_GPL(lis3lv02d_remove_fs); + + MODULE_DESCRIPTION("ST LIS3LV02Dx three-axis digital accelerometer driver"); +-MODULE_AUTHOR("Yan Burman, Eric Piel, Pavel Machek"); ++MODULE_AUTHOR("Yan Burman and Eric Piel"); + MODULE_LICENSE("GPL"); + +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/drivers/hwmon/lis3lv02d.h linux-2.6.29-rc3.owrt/drivers/hwmon/lis3lv02d.h +--- linux-2.6.29.owrt/drivers/hwmon/lis3lv02d.h 2009-05-10 22:04:39.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/drivers/hwmon/lis3lv02d.h 2009-05-10 23:48:28.000000000 +0200 +@@ -22,15 +22,12 @@ + /* + * The actual chip is STMicroelectronics LIS3LV02DL or LIS3LV02DQ that seems to + * be connected via SPI. There exists also several similar chips (such as LIS302DL or +- * LIS3L02DQ) and they have slightly different registers, but we can provide a +- * common interface for all of them. ++ * LIS3L02DQ) but not in the HP laptops and they have slightly different registers. + * They can also be connected via I²C. + */ + +-/* 2-byte registers */ +-#define LIS_DOUBLE_ID 0x3A /* LIS3LV02D[LQ] */ +-/* 1-byte registers */ +-#define LIS_SINGLE_ID 0x3B /* LIS[32]02DL and others */ ++#define LIS3LV02DL_ID 0x3A /* Also the LIS3LV02DQ */ ++#define LIS302DL_ID 0x3B /* Also the LIS202DL! */ + + enum lis3lv02d_reg { + WHO_AM_I = 0x0F, +@@ -47,13 +44,10 @@ + STATUS_REG = 0x27, + OUTX_L = 0x28, + OUTX_H = 0x29, +- OUTX = 0x29, + OUTY_L = 0x2A, + OUTY_H = 0x2B, +- OUTY = 0x2B, + OUTZ_L = 0x2C, + OUTZ_H = 0x2D, +- OUTZ = 0x2D, + FF_WU_CFG = 0x30, + FF_WU_SRC = 0x31, + FF_WU_ACK = 0x32, +@@ -165,10 +159,6 @@ + acpi_status (*write) (acpi_handle handle, int reg, u8 val); + acpi_status (*read) (acpi_handle handle, int reg, u8 *ret); + +- u8 whoami; /* 3Ah: 2-byte registries, 3Bh: 1-byte registries */ +- s16 (*read_data) (acpi_handle handle, int reg); +- int mdps_max_val; +- + struct input_dev *idev; /* input device */ + struct task_struct *kthread; /* kthread for input */ + struct mutex lock; +@@ -180,11 +170,6 @@ + unsigned char is_on; /* whether the device is on or off */ + unsigned char usage; /* usage counter */ + struct axis_conversion ac; /* hw -> logical axis */ +- +- u32 irq; /* IRQ number */ +- struct fasync_struct *async_queue; /* queue for the misc device */ +- wait_queue_head_t misc_wait; /* Wait queue for the misc device */ +- unsigned long misc_opened; /* bit0: whether the device is open */ + }; + + int lis3lv02d_init_device(struct acpi_lis3lv02d *dev); +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/drivers/hwmon/lm85.c linux-2.6.29-rc3.owrt/drivers/hwmon/lm85.c +--- linux-2.6.29.owrt/drivers/hwmon/lm85.c 2009-05-10 22:04:39.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/drivers/hwmon/lm85.c 2009-05-10 23:48:28.000000000 +0200 +@@ -72,7 +72,6 @@ + #define LM85_COMPANY_SMSC 0x5c + #define LM85_VERSTEP_VMASK 0xf0 + #define LM85_VERSTEP_GENERIC 0x60 +-#define LM85_VERSTEP_GENERIC2 0x70 + #define LM85_VERSTEP_LM85C 0x60 + #define LM85_VERSTEP_LM85B 0x62 + #define LM85_VERSTEP_ADM1027 0x60 +@@ -335,7 +334,6 @@ + static const struct i2c_device_id lm85_id[] = { + { "adm1027", adm1027 }, + { "adt7463", adt7463 }, +- { "adt7468", adt7468 }, + { "lm85", any_chip }, + { "lm85b", lm85b }, + { "lm85c", lm85c }, +@@ -410,8 +408,7 @@ + struct lm85_data *data = lm85_update_device(dev); + int vid; + +- if ((data->type == adt7463 || data->type == adt7468) && +- (data->vid & 0x80)) { ++ if (data->type == adt7463 && (data->vid & 0x80)) { + /* 6-pin VID (VRM 10) */ + vid = vid_from_reg(data->vid & 0x3f, data->vrm); + } else { +@@ -1156,8 +1153,7 @@ + address, company, verstep); + + /* All supported chips have the version in common */ +- if ((verstep & LM85_VERSTEP_VMASK) != LM85_VERSTEP_GENERIC && +- (verstep & LM85_VERSTEP_VMASK) != LM85_VERSTEP_GENERIC2) { ++ if ((verstep & LM85_VERSTEP_VMASK) != LM85_VERSTEP_GENERIC) { + dev_dbg(&adapter->dev, "Autodetection failed: " + "unsupported version\n"); + return -ENODEV; +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/drivers/hwmon/lm90.c linux-2.6.29-rc3.owrt/drivers/hwmon/lm90.c +--- linux-2.6.29.owrt/drivers/hwmon/lm90.c 2009-05-10 22:04:39.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/drivers/hwmon/lm90.c 2009-05-10 23:48:28.000000000 +0200 +@@ -32,10 +32,10 @@ + * supported by this driver. These chips lack the remote temperature + * offset feature. + * +- * This driver also supports the MAX6646, MAX6647, MAX6648, MAX6649 and +- * MAX6692 chips made by Maxim. These are again similar to the LM86, +- * but they use unsigned temperature values and can report temperatures +- * from 0 to 145 degrees. ++ * This driver also supports the MAX6646, MAX6647 and MAX6649 chips ++ * made by Maxim. These are again similar to the LM86, but they use ++ * unsigned temperature values and can report temperatures from 0 to ++ * 145 degrees. + * + * This driver also supports the MAX6680 and MAX6681, two other sensor + * chips made by Maxim. These are quite similar to the other Maxim +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/drivers/hwmon/vt1211.c linux-2.6.29-rc3.owrt/drivers/hwmon/vt1211.c +--- linux-2.6.29.owrt/drivers/hwmon/vt1211.c 2009-05-10 22:04:39.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/drivers/hwmon/vt1211.c 2009-05-10 23:48:28.000000000 +0200 +@@ -1262,7 +1262,7 @@ + res.name = pdev->name; + err = acpi_check_resource_conflict(&res); + if (err) +- goto EXIT_DEV_PUT; ++ goto EXIT; + + err = platform_device_add_resources(pdev, &res, 1); + if (err) { +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/drivers/hwmon/w83627ehf.c linux-2.6.29-rc3.owrt/drivers/hwmon/w83627ehf.c +--- linux-2.6.29.owrt/drivers/hwmon/w83627ehf.c 2009-05-10 22:04:39.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/drivers/hwmon/w83627ehf.c 2009-05-10 23:48:28.000000000 +0200 +@@ -1548,7 +1548,7 @@ + + err = acpi_check_resource_conflict(&res); + if (err) +- goto exit_device_put; ++ goto exit; + + err = platform_device_add_resources(pdev, &res, 1); + if (err) { +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/drivers/i2c/busses/i2c-acorn.c linux-2.6.29-rc3.owrt/drivers/i2c/busses/i2c-acorn.c +--- linux-2.6.29.owrt/drivers/i2c/busses/i2c-acorn.c 2009-05-10 22:04:39.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/drivers/i2c/busses/i2c-acorn.c 2009-05-10 23:48:28.000000000 +0200 +@@ -79,11 +79,10 @@ + .getsda = ioc_getsda, + .getscl = ioc_getscl, + .udelay = 80, +- .timeout = HZ, ++ .timeout = 100 + }; + + static struct i2c_adapter ioc_ops = { +- .nr = 0, + .algo_data = &ioc_data, + }; + +@@ -91,7 +90,7 @@ + { + force_ones = FORCE_ONES | SCL | SDA; + +- return i2c_bit_add_numbered_bus(&ioc_ops); ++ return i2c_bit_add_bus(&ioc_ops); + } + + module_init(i2c_ioc_init); +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/drivers/i2c/busses/i2c-amd8111.c linux-2.6.29-rc3.owrt/drivers/i2c/busses/i2c-amd8111.c +--- linux-2.6.29.owrt/drivers/i2c/busses/i2c-amd8111.c 2009-05-10 22:04:39.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/drivers/i2c/busses/i2c-amd8111.c 2009-05-10 23:48:28.000000000 +0200 +@@ -72,7 +72,7 @@ + { + int timeout = 500; + +- while ((inb(smbus->base + AMD_EC_SC) & AMD_EC_SC_IBF) && --timeout) ++ while (timeout-- && (inb(smbus->base + AMD_EC_SC) & AMD_EC_SC_IBF)) + udelay(1); + + if (!timeout) { +@@ -88,7 +88,7 @@ + { + int timeout = 500; + +- while ((~inb(smbus->base + AMD_EC_SC) & AMD_EC_SC_OBF) && --timeout) ++ while (timeout-- && (~inb(smbus->base + AMD_EC_SC) & AMD_EC_SC_OBF)) + udelay(1); + + if (!timeout) { +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/drivers/i2c/busses/i2c-ixp2000.c linux-2.6.29-rc3.owrt/drivers/i2c/busses/i2c-ixp2000.c +--- linux-2.6.29.owrt/drivers/i2c/busses/i2c-ixp2000.c 2009-05-10 22:04:39.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/drivers/i2c/busses/i2c-ixp2000.c 2009-05-10 23:48:28.000000000 +0200 +@@ -114,7 +114,7 @@ + drv_data->algo_data.getsda = ixp2000_bit_getsda; + drv_data->algo_data.getscl = ixp2000_bit_getscl; + drv_data->algo_data.udelay = 6; +- drv_data->algo_data.timeout = HZ; ++ drv_data->algo_data.timeout = 100; + + strlcpy(drv_data->adapter.name, plat_dev->dev.driver->name, + sizeof(drv_data->adapter.name)); +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/drivers/i2c/busses/i2c-mv64xxx.c linux-2.6.29-rc3.owrt/drivers/i2c/busses/i2c-mv64xxx.c +--- linux-2.6.29.owrt/drivers/i2c/busses/i2c-mv64xxx.c 2009-05-10 22:04:39.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/drivers/i2c/busses/i2c-mv64xxx.c 2009-05-10 23:48:28.000000000 +0200 +@@ -482,7 +482,7 @@ + return 0; + } + +-static void ++static void __devexit + mv64xxx_i2c_unmap_regs(struct mv64xxx_i2c_data *drv_data) + { + if (drv_data->reg_base) { +@@ -577,7 +577,7 @@ + + static struct platform_driver mv64xxx_i2c_driver = { + .probe = mv64xxx_i2c_probe, +- .remove = __devexit_p(mv64xxx_i2c_remove), ++ .remove = mv64xxx_i2c_remove, + .driver = { + .owner = THIS_MODULE, + .name = MV64XXX_I2C_CTLR_NAME, +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/drivers/i2c/busses/i2c-pxa.c linux-2.6.29-rc3.owrt/drivers/i2c/busses/i2c-pxa.c +--- linux-2.6.29.owrt/drivers/i2c/busses/i2c-pxa.c 2009-05-10 22:04:39.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/drivers/i2c/busses/i2c-pxa.c 2009-05-10 23:48:28.000000000 +0200 +@@ -644,7 +644,7 @@ + + i2c_pxa_start_message(i2c); + +- while (i2c->msg_num > 0 && --timeout) { ++ while (timeout-- && i2c->msg_num > 0) { + i2c_pxa_handler(0, i2c); + udelay(10); + } +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/drivers/i2c/busses/scx200_i2c.c linux-2.6.29-rc3.owrt/drivers/i2c/busses/scx200_i2c.c +--- linux-2.6.29.owrt/drivers/i2c/busses/scx200_i2c.c 2009-05-10 22:04:39.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/drivers/i2c/busses/scx200_i2c.c 2009-05-10 23:48:28.000000000 +0200 +@@ -76,7 +76,7 @@ + .getsda = scx200_i2c_getsda, + .getscl = scx200_i2c_getscl, + .udelay = 10, +- .timeout = HZ, ++ .timeout = 100, + }; + + static struct i2c_adapter scx200_i2c_ops = { +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/drivers/i2c/i2c-core.c linux-2.6.29-rc3.owrt/drivers/i2c/i2c-core.c +--- linux-2.6.29.owrt/drivers/i2c/i2c-core.c 2009-05-10 22:04:39.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/drivers/i2c/i2c-core.c 2009-05-10 23:48:28.000000000 +0200 +@@ -1831,8 +1831,7 @@ + case I2C_SMBUS_QUICK: + msg[0].len = 0; + /* Special case: The read/write field is used as data */ +- msg[0].flags = flags | (read_write == I2C_SMBUS_READ ? +- I2C_M_RD : 0); ++ msg[0].flags = flags | (read_write==I2C_SMBUS_READ)?I2C_M_RD:0; + num = 1; + break; + case I2C_SMBUS_BYTE: +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/drivers/i2c/i2c-dev.c linux-2.6.29-rc3.owrt/drivers/i2c/i2c-dev.c +--- linux-2.6.29.owrt/drivers/i2c/i2c-dev.c 2009-05-10 22:04:39.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/drivers/i2c/i2c-dev.c 2009-05-10 23:48:28.000000000 +0200 +@@ -35,7 +35,6 @@ + #include <linux/i2c.h> + #include <linux/i2c-dev.h> + #include <linux/smp_lock.h> +-#include <linux/jiffies.h> + #include <asm/uaccess.h> + + static struct i2c_driver i2cdev_driver; +@@ -423,10 +422,7 @@ + client->adapter->retries = arg; + break; + case I2C_TIMEOUT: +- /* For historical reasons, user-space sets the timeout +- * value in units of 10 ms. +- */ +- client->adapter->timeout = msecs_to_jiffies(arg * 10); ++ client->adapter->timeout = arg; + break; + default: + /* NOTE: returning a fault code here could cause trouble +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/drivers/ide/amd74xx.c linux-2.6.29-rc3.owrt/drivers/ide/amd74xx.c +--- linux-2.6.29.owrt/drivers/ide/amd74xx.c 2009-05-10 22:04:39.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/drivers/ide/amd74xx.c 2009-05-10 23:48:28.000000000 +0200 +@@ -166,7 +166,7 @@ + * Check for broken FIFO support. + */ + if (dev->vendor == PCI_VENDOR_ID_AMD && +- dev->device == PCI_DEVICE_ID_AMD_VIPER_7411) ++ dev->vendor == PCI_DEVICE_ID_AMD_VIPER_7411) + t &= 0x0f; + else + t |= 0xf0; +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/drivers/ide/at91_ide.c linux-2.6.29-rc3.owrt/drivers/ide/at91_ide.c +--- linux-2.6.29.owrt/drivers/ide/at91_ide.c 2009-05-10 22:04:39.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/drivers/ide/at91_ide.c 1970-01-01 01:00:00.000000000 +0100 +@@ -1,467 +0,0 @@ +-/* +- * IDE host driver for AT91 (SAM9, CAP9, AT572D940HF) Static Memory Controller +- * with Compact Flash True IDE logic +- * +- * Copyright (c) 2008, 2009 Kelvatek Ltd. +- * +- * 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., 675 Mass Ave, Cambridge, MA 02139, USA. +- * +- */ +- +-#include <linux/version.h> +-#include <linux/kernel.h> +-#include <linux/module.h> +-#include <linux/clk.h> +-#include <linux/err.h> +-#include <linux/ide.h> +-#include <linux/platform_device.h> +- +-#include <mach/board.h> +-#include <mach/gpio.h> +-#include <mach/at91sam9263.h> +-#include <mach/at91sam9_smc.h> +-#include <mach/at91sam9263_matrix.h> +- +-#define DRV_NAME "at91_ide" +- +-#define perr(fmt, args...) pr_err(DRV_NAME ": " fmt, ##args) +-#define pdbg(fmt, args...) pr_debug("%s " fmt, __func__, ##args) +- +-/* +- * Access to IDE device is possible through EBI Static Memory Controller +- * with Compact Flash logic. For details see EBI and SMC datasheet sections +- * of any microcontroller from AT91SAM9 family. +- * +- * Within SMC chip select address space, lines A[23:21] distinguish Compact +- * Flash modes (I/O, common memory, attribute memory, True IDE). IDE modes are: +- * 0x00c0000 - True IDE +- * 0x00e0000 - Alternate True IDE (Alt Status Register) +- * +- * On True IDE mode Task File and Data Register are mapped at the same address. +- * To distinguish access between these two different bus data width is used: +- * 8Bit for Task File, 16Bit for Data I/O. +- * +- * After initialization we do 8/16 bit flipping (changes in SMC MODE register) +- * only inside IDE callback routines which are serialized by IDE layer, +- * so no additional locking needed. +- */ +- +-#define TASK_FILE 0x00c00000 +-#define ALT_MODE 0x00e00000 +-#define REGS_SIZE 8 +- +-#define enter_16bit(cs, mode) do { \ +- mode = at91_sys_read(AT91_SMC_MODE(cs)); \ +- at91_sys_write(AT91_SMC_MODE(cs), mode | AT91_SMC_DBW_16); \ +-} while (0) +- +-#define leave_16bit(cs, mode) at91_sys_write(AT91_SMC_MODE(cs), mode); +- +-static void set_smc_timings(const u8 chipselect, const u16 cycle, +- const u16 setup, const u16 pulse, +- const u16 data_float, int use_iordy) +-{ +- unsigned long mode = AT91_SMC_READMODE | AT91_SMC_WRITEMODE | +- AT91_SMC_BAT_SELECT; +- +- /* disable or enable waiting for IORDY signal */ +- if (use_iordy) +- mode |= AT91_SMC_EXNWMODE_READY; +- +- /* add data float cycles if needed */ +- if (data_float) +- mode |= AT91_SMC_TDF_(data_float); +- +- at91_sys_write(AT91_SMC_MODE(chipselect), mode); +- +- /* setup timings in SMC */ +- at91_sys_write(AT91_SMC_SETUP(chipselect), AT91_SMC_NWESETUP_(setup) | +- AT91_SMC_NCS_WRSETUP_(0) | +- AT91_SMC_NRDSETUP_(setup) | +- AT91_SMC_NCS_RDSETUP_(0)); +- at91_sys_write(AT91_SMC_PULSE(chipselect), AT91_SMC_NWEPULSE_(pulse) | +- AT91_SMC_NCS_WRPULSE_(cycle) | +- AT91_SMC_NRDPULSE_(pulse) | +- AT91_SMC_NCS_RDPULSE_(cycle)); +- at91_sys_write(AT91_SMC_CYCLE(chipselect), AT91_SMC_NWECYCLE_(cycle) | +- AT91_SMC_NRDCYCLE_(cycle)); +-} +- +-static unsigned int calc_mck_cycles(unsigned int ns, unsigned int mck_hz) +-{ +- u64 tmp = ns; +- +- tmp *= mck_hz; +- tmp += 1000*1000*1000 - 1; /* round up */ +- do_div(tmp, 1000*1000*1000); +- return (unsigned int) tmp; +-} +- +-static void apply_timings(const u8 chipselect, const u8 pio, +- const struct ide_timing *timing, int use_iordy) +-{ +- unsigned int t0, t1, t2, t6z; +- unsigned int cycle, setup, pulse, data_float; +- unsigned int mck_hz; +- struct clk *mck; +- +- /* see table 22 of Compact Flash standard 4.1 for the meaning, +- * we do not stretch active (t2) time, so setup (t1) + hold time (th) +- * assure at least minimal recovery (t2i) time */ +- t0 = timing->cyc8b; +- t1 = timing->setup; +- t2 = timing->act8b; +- t6z = (pio < 5) ? 30 : 20; +- +- pdbg("t0=%u t1=%u t2=%u t6z=%u\n", t0, t1, t2, t6z); +- +- mck = clk_get(NULL, "mck"); +- BUG_ON(IS_ERR(mck)); +- mck_hz = clk_get_rate(mck); +- pdbg("mck_hz=%u\n", mck_hz); +- +- cycle = calc_mck_cycles(t0, mck_hz); +- setup = calc_mck_cycles(t1, mck_hz); +- pulse = calc_mck_cycles(t2, mck_hz); +- data_float = calc_mck_cycles(t6z, mck_hz); +- +- pdbg("cycle=%u setup=%u pulse=%u data_float=%u\n", +- cycle, setup, pulse, data_float); +- +- set_smc_timings(chipselect, cycle, setup, pulse, data_float, use_iordy); +-} +- +-static void at91_ide_input_data(ide_drive_t *drive, struct request *rq, +- void *buf, unsigned int len) +-{ +- ide_hwif_t *hwif = drive->hwif; +- struct ide_io_ports *io_ports = &hwif->io_ports; +- u8 chipselect = hwif->select_data; +- unsigned long mode; +- +- pdbg("cs %u buf %p len %d\n", chipselect, buf, len); +- +- len++; +- +- enter_16bit(chipselect, mode); +- __ide_mm_insw((void __iomem *) io_ports->data_addr, buf, len / 2); +- leave_16bit(chipselect, mode); +-} +- +-static void at91_ide_output_data(ide_drive_t *drive, struct request *rq, +- void *buf, unsigned int len) +-{ +- ide_hwif_t *hwif = drive->hwif; +- struct ide_io_ports *io_ports = &hwif->io_ports; +- u8 chipselect = hwif->select_data; +- unsigned long mode; +- +- pdbg("cs %u buf %p len %d\n", chipselect, buf, len); +- +- enter_16bit(chipselect, mode); +- __ide_mm_outsw((void __iomem *) io_ports->data_addr, buf, len / 2); +- leave_16bit(chipselect, mode); +-} +- +-static u8 ide_mm_inb(unsigned long port) +-{ +- return readb((void __iomem *) port); +-} +- +-static void ide_mm_outb(u8 value, unsigned long port) +-{ +- writeb(value, (void __iomem *) port); +-} +- +-static void at91_ide_tf_load(ide_drive_t *drive, ide_task_t *task) +-{ +- ide_hwif_t *hwif = drive->hwif; +- struct ide_io_ports *io_ports = &hwif->io_ports; +- struct ide_taskfile *tf = &task->tf; +- u8 HIHI = (task->tf_flags & IDE_TFLAG_LBA48) ? 0xE0 : 0xEF; +- +- if (task->tf_flags & IDE_TFLAG_FLAGGED) +- HIHI = 0xFF; +- +- if (task->tf_flags & IDE_TFLAG_OUT_DATA) { +- u16 data = (tf->hob_data << 8) | tf->data; +- +- at91_ide_output_data(drive, NULL, &data, 2); +- } +- +- if (task->tf_flags & IDE_TFLAG_OUT_HOB_FEATURE) +- ide_mm_outb(tf->hob_feature, io_ports->feature_addr); +- if (task->tf_flags & IDE_TFLAG_OUT_HOB_NSECT) +- ide_mm_outb(tf->hob_nsect, io_ports->nsect_addr); +- if (task->tf_flags & IDE_TFLAG_OUT_HOB_LBAL) +- ide_mm_outb(tf->hob_lbal, io_ports->lbal_addr); +- if (task->tf_flags & IDE_TFLAG_OUT_HOB_LBAM) +- ide_mm_outb(tf->hob_lbam, io_ports->lbam_addr); +- if (task->tf_flags & IDE_TFLAG_OUT_HOB_LBAH) +- ide_mm_outb(tf->hob_lbah, io_ports->lbah_addr); +- +- if (task->tf_flags & IDE_TFLAG_OUT_FEATURE) +- ide_mm_outb(tf->feature, io_ports->feature_addr); +- if (task->tf_flags & IDE_TFLAG_OUT_NSECT) +- ide_mm_outb(tf->nsect, io_ports->nsect_addr); +- if (task->tf_flags & IDE_TFLAG_OUT_LBAL) +- ide_mm_outb(tf->lbal, io_ports->lbal_addr); +- if (task->tf_flags & IDE_TFLAG_OUT_LBAM) +- ide_mm_outb(tf->lbam, io_ports->lbam_addr); +- if (task->tf_flags & IDE_TFLAG_OUT_LBAH) +- ide_mm_outb(tf->lbah, io_ports->lbah_addr); +- +- if (task->tf_flags & IDE_TFLAG_OUT_DEVICE) +- ide_mm_outb((tf->device & HIHI) | drive->select, io_ports->device_addr); +-} +- +-static void at91_ide_tf_read(ide_drive_t *drive, ide_task_t *task) +-{ +- ide_hwif_t *hwif = drive->hwif; +- struct ide_io_ports *io_ports = &hwif->io_ports; +- struct ide_taskfile *tf = &task->tf; +- +- if (task->tf_flags & IDE_TFLAG_IN_DATA) { +- u16 data; +- +- at91_ide_input_data(drive, NULL, &data, 2); +- tf->data = data & 0xff; +- tf->hob_data = (data >> 8) & 0xff; +- } +- +- /* be sure we're looking at the low order bits */ +- ide_mm_outb(ATA_DEVCTL_OBS & ~0x80, io_ports->ctl_addr); +- +- if (task->tf_flags & IDE_TFLAG_IN_FEATURE) +- tf->feature = ide_mm_inb(io_ports->feature_addr); +- if (task->tf_flags & IDE_TFLAG_IN_NSECT) +- tf->nsect = ide_mm_inb(io_ports->nsect_addr); +- if (task->tf_flags & IDE_TFLAG_IN_LBAL) +- tf->lbal = ide_mm_inb(io_ports->lbal_addr); +- if (task->tf_flags & IDE_TFLAG_IN_LBAM) +- tf->lbam = ide_mm_inb(io_ports->lbam_addr); +- if (task->tf_flags & IDE_TFLAG_IN_LBAH) +- tf->lbah = ide_mm_inb(io_ports->lbah_addr); +- if (task->tf_flags & IDE_TFLAG_IN_DEVICE) +- tf->device = ide_mm_inb(io_ports->device_addr); +- +- if (task->tf_flags & IDE_TFLAG_LBA48) { +- ide_mm_outb(ATA_DEVCTL_OBS | 0x80, io_ports->ctl_addr); +- +- if (task->tf_flags & IDE_TFLAG_IN_HOB_FEATURE) +- tf->hob_feature = ide_mm_inb(io_ports->feature_addr); +- if (task->tf_flags & IDE_TFLAG_IN_HOB_NSECT) +- tf->hob_nsect = ide_mm_inb(io_ports->nsect_addr); +- if (task->tf_flags & IDE_TFLAG_IN_HOB_LBAL) +- tf->hob_lbal = ide_mm_inb(io_ports->lbal_addr); +- if (task->tf_flags & IDE_TFLAG_IN_HOB_LBAM) +- tf->hob_lbam = ide_mm_inb(io_ports->lbam_addr); +- if (task->tf_flags & IDE_TFLAG_IN_HOB_LBAH) +- tf->hob_lbah = ide_mm_inb(io_ports->lbah_addr); +- } +-} +- +-static void at91_ide_set_pio_mode(ide_drive_t *drive, const u8 pio) +-{ +- struct ide_timing *timing; +- u8 chipselect = drive->hwif->select_data; +- int use_iordy = 0; +- +- pdbg("chipselect %u pio %u\n", chipselect, pio); +- +- timing = ide_timing_find_mode(XFER_PIO_0 + pio); +- BUG_ON(!timing); +- +- if ((pio > 2 || ata_id_has_iordy(drive->id)) && +- !(ata_id_is_cfa(drive->id) && pio > 4)) +- use_iordy = 1; +- +- apply_timings(chipselect, pio, timing, use_iordy); +-} +- +-static const struct ide_tp_ops at91_ide_tp_ops = { +- .exec_command = ide_exec_command, +- .read_status = ide_read_status, +- .read_altstatus = ide_read_altstatus, +- .set_irq = ide_set_irq, +- +- .tf_load = at91_ide_tf_load, +- .tf_read = at91_ide_tf_read, +- +- .input_data = at91_ide_input_data, +- .output_data = at91_ide_output_data, +-}; +- +-static const struct ide_port_ops at91_ide_port_ops = { +- .set_pio_mode = at91_ide_set_pio_mode, +-}; +- +-static const struct ide_port_info at91_ide_port_info __initdata = { +- .port_ops = &at91_ide_port_ops, +- .tp_ops = &at91_ide_tp_ops, +- .host_flags = IDE_HFLAG_MMIO | IDE_HFLAG_NO_DMA | IDE_HFLAG_SINGLE | +- IDE_HFLAG_NO_IO_32BIT | IDE_HFLAG_UNMASK_IRQS, +- .pio_mask = ATA_PIO5, +-}; +- +-/* +- * If interrupt is delivered through GPIO, IRQ are triggered on falling +- * and rising edge of signal. Whereas IDE device request interrupt on high +- * level (rising edge in our case). This mean we have fake interrupts, so +- * we need to check interrupt pin and exit instantly from ISR when line +- * is on low level. +- */ +- +-irqreturn_t at91_irq_handler(int irq, void *dev_id) +-{ +- int ntries = 8; +- int pin_val1, pin_val2; +- +- /* additional deglitch, line can be noisy in badly designed PCB */ +- do { +- pin_val1 = at91_get_gpio_value(irq); +- pin_val2 = at91_get_gpio_value(irq); +- } while (pin_val1 != pin_val2 && --ntries > 0); +- +- if (pin_val1 == 0 || ntries <= 0) +- return IRQ_HANDLED; +- +- return ide_intr(irq, dev_id); +-} +- +-static int __init at91_ide_probe(struct platform_device *pdev) +-{ +- int ret; +- hw_regs_t hw; +- hw_regs_t *hws[] = { &hw, NULL, NULL, NULL }; +- struct ide_host *host; +- struct resource *res; +- unsigned long tf_base = 0, ctl_base = 0; +- struct at91_cf_data *board = pdev->dev.platform_data; +- +- if (!board) +- return -ENODEV; +- +- if (board->det_pin && at91_get_gpio_value(board->det_pin) != 0) { +- perr("no device detected\n"); +- return -ENODEV; +- } +- +- res = platform_get_resource(pdev, IORESOURCE_MEM, 0); +- if (!res) { +- perr("can't get memory resource\n"); +- return -ENODEV; +- } +- +- if (!devm_request_mem_region(&pdev->dev, res->start + TASK_FILE, +- REGS_SIZE, "ide") || +- !devm_request_mem_region(&pdev->dev, res->start + ALT_MODE, +- REGS_SIZE, "alt")) { +- perr("memory resources in use\n"); +- return -EBUSY; +- } +- +- pdbg("chipselect %u irq %u res %08lx\n", board->chipselect, +- board->irq_pin, (unsigned long) res->start); +- +- tf_base = (unsigned long) devm_ioremap(&pdev->dev, res->start + TASK_FILE, +- REGS_SIZE); +- ctl_base = (unsigned long) devm_ioremap(&pdev->dev, res->start + ALT_MODE, +- REGS_SIZE); +- if (!tf_base || !ctl_base) { +- perr("can't map memory regions\n"); +- return -EBUSY; +- } +- +- memset(&hw, 0, sizeof(hw)); +- +- if (board->flags & AT91_IDE_SWAP_A0_A2) { +- /* workaround for stupid hardware bug */ +- hw.io_ports.data_addr = tf_base + 0; +- hw.io_ports.error_addr = tf_base + 4; +- hw.io_ports.nsect_addr = tf_base + 2; +- hw.io_ports.lbal_addr = tf_base + 6; +- hw.io_ports.lbam_addr = tf_base + 1; +- hw.io_ports.lbah_addr = tf_base + 5; +- hw.io_ports.device_addr = tf_base + 3; +- hw.io_ports.command_addr = tf_base + 7; +- hw.io_ports.ctl_addr = ctl_base + 3; +- } else +- ide_std_init_ports(&hw, tf_base, ctl_base + 6); +- +- hw.irq = board->irq_pin; +- hw.chipset = ide_generic; +- hw.dev = &pdev->dev; +- +- host = ide_host_alloc(&at91_ide_port_info, hws); +- if (!host) { +- perr("failed to allocate ide host\n"); +- return -ENOMEM; +- } +- +- /* setup Static Memory Controller - PIO 0 as default */ +- apply_timings(board->chipselect, 0, ide_timing_find_mode(XFER_PIO_0), 0); +- +- /* with GPIO interrupt we have to do quirks in handler */ +- if (board->irq_pin >= PIN_BASE) +- host->irq_handler = at91_irq_handler; +- +- host->ports[0]->select_data = board->chipselect; +- +- ret = ide_host_register(host, &at91_ide_port_info, hws); +- if (ret) { +- perr("failed to register ide host\n"); +- goto err_free_host; +- } +- platform_set_drvdata(pdev, host); +- return 0; +- +-err_free_host: +- ide_host_free(host); +- return ret; +-} +- +-static int __exit at91_ide_remove(struct platform_device *pdev) +-{ +- struct ide_host *host = platform_get_drvdata(pdev); +- +- ide_host_remove(host); +- return 0; +-} +- +-static struct platform_driver at91_ide_driver = { +- .driver = { +- .name = DRV_NAME, +- .owner = THIS_MODULE, +- }, +- .remove = __exit_p(at91_ide_remove), +-}; +- +-static int __init at91_ide_init(void) +-{ +- return platform_driver_probe(&at91_ide_driver, at91_ide_probe); +-} +- +-static void __exit at91_ide_exit(void) +-{ +- platform_driver_unregister(&at91_ide_driver); +-} +- +-module_init(at91_ide_init); +-module_exit(at91_ide_exit); +- +-MODULE_LICENSE("GPL"); +-MODULE_AUTHOR("Stanislaw Gruszka <stf_xl@wp.pl>"); +- +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/drivers/ide/atiixp.c linux-2.6.29-rc3.owrt/drivers/ide/atiixp.c +--- linux-2.6.29.owrt/drivers/ide/atiixp.c 2009-05-10 22:04:39.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/drivers/ide/atiixp.c 2009-05-10 23:48:28.000000000 +0200 +@@ -52,7 +52,7 @@ + { + struct pci_dev *dev = to_pci_dev(drive->hwif->dev); + unsigned long flags; +- int timing_shift = (drive->dn ^ 1) * 8; ++ int timing_shift = (drive->dn & 2) ? 16 : 0 + (drive->dn & 1) ? 0 : 8; + u32 pio_timing_data; + u16 pio_mode_data; + +@@ -85,7 +85,7 @@ + { + struct pci_dev *dev = to_pci_dev(drive->hwif->dev); + unsigned long flags; +- int timing_shift = (drive->dn ^ 1) * 8; ++ int timing_shift = (drive->dn & 2) ? 16 : 0 + (drive->dn & 1) ? 0 : 8; + u32 tmp32; + u16 tmp16; + u16 udma_ctl = 0; +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/drivers/ide/cs5536.c linux-2.6.29-rc3.owrt/drivers/ide/cs5536.c +--- linux-2.6.29.owrt/drivers/ide/cs5536.c 2009-05-10 22:04:39.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/drivers/ide/cs5536.c 1970-01-01 01:00:00.000000000 +0100 +@@ -1,308 +0,0 @@ +-/* +- * CS5536 PATA support +- * (C) 2007 Martin K. Petersen <mkp@mkp.net> +- * (C) 2009 Bartlomiej Zolnierkiewicz +- * +- * 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. +- * +- * 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, MA 02111-1307 USA +- * +- * Documentation: +- * Available from AMD web site. +- * +- * The IDE timing registers for the CS5536 live in the Geode Machine +- * Specific Register file and not PCI config space. Most BIOSes +- * virtualize the PCI registers so the chip looks like a standard IDE +- * controller. Unfortunately not all implementations get this right. +- * In particular some have problems with unaligned accesses to the +- * virtualized PCI registers. This driver always does full dword +- * writes to work around the issue. Also, in case of a bad BIOS this +- * driver can be loaded with the "msr=1" parameter which forces using +- * the Machine Specific Registers to configure the device. +- */ +- +-#include <linux/kernel.h> +-#include <linux/module.h> +-#include <linux/pci.h> +-#include <linux/init.h> +-#include <linux/ide.h> +-#include <asm/msr.h> +- +-#define DRV_NAME "cs5536" +- +-enum { +- MSR_IDE_CFG = 0x51300010, +- PCI_IDE_CFG = 0x40, +- +- CFG = 0, +- DTC = 2, +- CAST = 3, +- ETC = 4, +- +- IDE_CFG_CHANEN = (1 << 1), +- IDE_CFG_CABLE = (1 << 17) | (1 << 16), +- +- IDE_D0_SHIFT = 24, +- IDE_D1_SHIFT = 16, +- IDE_DRV_MASK = 0xff, +- +- IDE_CAST_D0_SHIFT = 6, +- IDE_CAST_D1_SHIFT = 4, +- IDE_CAST_DRV_MASK = 0x3, +- +- IDE_CAST_CMD_SHIFT = 24, +- IDE_CAST_CMD_MASK = 0xff, +- +- IDE_ETC_UDMA_MASK = 0xc0, +-}; +- +-static int use_msr; +- +-static int cs5536_read(struct pci_dev *pdev, int reg, u32 *val) +-{ +- if (unlikely(use_msr)) { +- u32 dummy; +- +- rdmsr(MSR_IDE_CFG + reg, *val, dummy); +- return 0; +- } +- +- return pci_read_config_dword(pdev, PCI_IDE_CFG + reg * 4, val); +-} +- +-static int cs5536_write(struct pci_dev *pdev, int reg, int val) +-{ +- if (unlikely(use_msr)) { +- wrmsr(MSR_IDE_CFG + reg, val, 0); +- return 0; +- } +- +- return pci_write_config_dword(pdev, PCI_IDE_CFG + reg * 4, val); +-} +- +-static void cs5536_program_dtc(ide_drive_t *drive, u8 tim) +-{ +- struct pci_dev *pdev = to_pci_dev(drive->hwif->dev); +- int dshift = (drive->dn & 1) ? IDE_D1_SHIFT : IDE_D0_SHIFT; +- u32 dtc; +- +- cs5536_read(pdev, DTC, &dtc); +- dtc &= ~(IDE_DRV_MASK << dshift); +- dtc |= tim << dshift; +- cs5536_write(pdev, DTC, dtc); +-} +- +-/** +- * cs5536_cable_detect - detect cable type +- * @hwif: Port to detect on +- * +- * Perform cable detection for ATA66 capable cable. +- * +- * Returns a cable type. +- */ +- +-static u8 cs5536_cable_detect(ide_hwif_t *hwif) +-{ +- struct pci_dev *pdev = to_pci_dev(hwif->dev); +- u32 cfg; +- +- cs5536_read(pdev, CFG, &cfg); +- +- if (cfg & IDE_CFG_CABLE) +- return ATA_CBL_PATA80; +- else +- return ATA_CBL_PATA40; +-} +- +-/** +- * cs5536_set_pio_mode - PIO timing setup +- * @drive: ATA device +- * @pio: PIO mode number +- */ +- +-static void cs5536_set_pio_mode(ide_drive_t *drive, const u8 pio) +-{ +- static const u8 drv_timings[5] = { +- 0x98, 0x55, 0x32, 0x21, 0x20, +- }; +- +- static const u8 addr_timings[5] = { +- 0x2, 0x1, 0x0, 0x0, 0x0, +- }; +- +- static const u8 cmd_timings[5] = { +- 0x99, 0x92, 0x90, 0x22, 0x20, +- }; +- +- struct pci_dev *pdev = to_pci_dev(drive->hwif->dev); +- ide_drive_t *pair = ide_get_pair_dev(drive); +- int cshift = (drive->dn & 1) ? IDE_CAST_D1_SHIFT : IDE_CAST_D0_SHIFT; +- u32 cast; +- u8 cmd_pio = pio; +- +- if (pair) +- cmd_pio = min(pio, ide_get_best_pio_mode(pair, 255, 4)); +- +- drive->drive_data &= (IDE_DRV_MASK << 8); +- drive->drive_data |= drv_timings[pio]; +- +- cs5536_program_dtc(drive, drv_timings[pio]); +- +- cs5536_read(pdev, CAST, &cast); +- +- cast &= ~(IDE_CAST_DRV_MASK << cshift); +- cast |= addr_timings[pio] << cshift; +- +- cast &= ~(IDE_CAST_CMD_MASK << IDE_CAST_CMD_SHIFT); +- cast |= cmd_timings[cmd_pio] << IDE_CAST_CMD_SHIFT; +- +- cs5536_write(pdev, CAST, cast); +-} +- +-/** +- * cs5536_set_dma_mode - DMA timing setup +- * @drive: ATA device +- * @mode: DMA mode +- */ +- +-static void cs5536_set_dma_mode(ide_drive_t *drive, const u8 mode) +-{ +- static const u8 udma_timings[6] = { +- 0xc2, 0xc1, 0xc0, 0xc4, 0xc5, 0xc6, +- }; +- +- static const u8 mwdma_timings[3] = { +- 0x67, 0x21, 0x20, +- }; +- +- struct pci_dev *pdev = to_pci_dev(drive->hwif->dev); +- int dshift = (drive->dn & 1) ? IDE_D1_SHIFT : IDE_D0_SHIFT; +- u32 etc; +- +- cs5536_read(pdev, ETC, &etc); +- +- if (mode >= XFER_UDMA_0) { +- etc &= ~(IDE_DRV_MASK << dshift); +- etc |= udma_timings[mode - XFER_UDMA_0] << dshift; +- } else { /* MWDMA */ +- etc &= ~(IDE_ETC_UDMA_MASK << dshift); +- drive->drive_data &= IDE_DRV_MASK; +- drive->drive_data |= mwdma_timings[mode - XFER_MW_DMA_0] << 8; +- } +- +- cs5536_write(pdev, ETC, etc); +-} +- +-static void cs5536_dma_start(ide_drive_t *drive) +-{ +- if (drive->current_speed < XFER_UDMA_0 && +- (drive->drive_data >> 8) != (drive->drive_data & IDE_DRV_MASK)) +- cs5536_program_dtc(drive, drive->drive_data >> 8); +- +- ide_dma_start(drive); +-} +- +-static int cs5536_dma_end(ide_drive_t *drive) +-{ +- int ret = ide_dma_end(drive); +- +- if (drive->current_speed < XFER_UDMA_0 && +- (drive->drive_data >> 8) != (drive->drive_data & IDE_DRV_MASK)) +- cs5536_program_dtc(drive, drive->drive_data & IDE_DRV_MASK); +- +- return ret; +-} +- +-static const struct ide_port_ops cs5536_port_ops = { +- .set_pio_mode = cs5536_set_pio_mode, +- .set_dma_mode = cs5536_set_dma_mode, +- .cable_detect = cs5536_cable_detect, +-}; +- +-static const struct ide_dma_ops cs5536_dma_ops = { +- .dma_host_set = ide_dma_host_set, +- .dma_setup = ide_dma_setup, +- .dma_exec_cmd = ide_dma_exec_cmd, +- .dma_start = cs5536_dma_start, +- .dma_end = cs5536_dma_end, +- .dma_test_irq = ide_dma_test_irq, +- .dma_lost_irq = ide_dma_lost_irq, +- .dma_timeout = ide_dma_timeout, +-}; +- +-static const struct ide_port_info cs5536_info = { +- .name = DRV_NAME, +- .port_ops = &cs5536_port_ops, +- .dma_ops = &cs5536_dma_ops, +- .host_flags = IDE_HFLAG_SINGLE, +- .pio_mask = ATA_PIO4, +- .mwdma_mask = ATA_MWDMA2, +- .udma_mask = ATA_UDMA5, +-}; +- +-/** +- * cs5536_init_one +- * @dev: PCI device +- * @id: Entry in match table +- */ +- +-static int cs5536_init_one(struct pci_dev *dev, const struct pci_device_id *id) +-{ +- u32 cfg; +- +- if (use_msr) +- printk(KERN_INFO DRV_NAME ": Using MSR regs instead of PCI\n"); +- +- cs5536_read(dev, CFG, &cfg); +- +- if ((cfg & IDE_CFG_CHANEN) == 0) { +- printk(KERN_ERR DRV_NAME ": disabled by BIOS\n"); +- return -ENODEV; +- } +- +- return ide_pci_init_one(dev, &cs5536_info, NULL); +-} +- +-static const struct pci_device_id cs5536_pci_tbl[] = { +- { PCI_VDEVICE(AMD, PCI_DEVICE_ID_AMD_CS5536_IDE), }, +- { }, +-}; +- +-static struct pci_driver cs5536_pci_driver = { +- .name = DRV_NAME, +- .id_table = cs5536_pci_tbl, +- .probe = cs5536_init_one, +- .remove = ide_pci_remove, +- .suspend = ide_pci_suspend, +- .resume = ide_pci_resume, +-}; +- +-static int __init cs5536_init(void) +-{ +- return pci_register_driver(&cs5536_pci_driver); +-} +- +-static void __exit cs5536_exit(void) +-{ +- pci_unregister_driver(&cs5536_pci_driver); +-} +- +-MODULE_AUTHOR("Martin K. Petersen, Bartlomiej Zolnierkiewicz"); +-MODULE_DESCRIPTION("low-level driver for the CS5536 IDE controller"); +-MODULE_LICENSE("GPL"); +-MODULE_DEVICE_TABLE(pci, cs5536_pci_tbl); +- +-module_param_named(msr, use_msr, int, 0644); +-MODULE_PARM_DESC(msr, "Force using MSR to configure IDE function (Default: 0)"); +- +-module_init(cs5536_init); +-module_exit(cs5536_exit); +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/drivers/ide/icside.c linux-2.6.29-rc3.owrt/drivers/ide/icside.c +--- linux-2.6.29.owrt/drivers/ide/icside.c 2009-05-10 22:04:39.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/drivers/ide/icside.c 2009-05-10 23:48:28.000000000 +0200 +@@ -534,7 +534,7 @@ + d.dma_ops = NULL; + } + +- ret = ide_host_register(host, &d, hws); ++ ret = ide_host_register(host, NULL, hws); + if (ret) + goto err_free; + +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/drivers/ide/ide-acpi.c linux-2.6.29-rc3.owrt/drivers/ide/ide-acpi.c +--- linux-2.6.29.owrt/drivers/ide/ide-acpi.c 2009-05-10 22:04:39.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/drivers/ide/ide-acpi.c 2009-05-10 23:48:28.000000000 +0200 +@@ -282,7 +282,7 @@ + port = hwif->channel ? drive->dn - 2: drive->dn; + + DEBPRINT("ENTER: %s at %s, port#: %d, hard_port#: %d\n", +- hwif->name, dev_name(dev), port, hwif->channel); ++ hwif->name, dev->bus_id, port, hwif->channel); + + if ((drive->dev_flags & IDE_DFLAG_PRESENT) == 0) { + DEBPRINT("%s drive %d:%d not present\n", +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/drivers/ide/ide-atapi.c linux-2.6.29-rc3.owrt/drivers/ide/ide-atapi.c +--- linux-2.6.29.owrt/drivers/ide/ide-atapi.c 2009-05-10 22:04:39.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/drivers/ide/ide-atapi.c 2009-05-10 23:48:28.000000000 +0200 +@@ -140,12 +140,6 @@ + rq->cmd_flags |= REQ_PREEMPT; + rq->buffer = (char *)pc; + rq->rq_disk = disk; +- +- if (pc->req_xfer) { +- rq->data = pc->buf; +- rq->data_len = pc->req_xfer; +- } +- + memcpy(rq->cmd, pc->c, 12); + if (drive->media == ide_tape) + rq->cmd[13] = REQ_IDETAPE_PC1; +@@ -165,12 +159,6 @@ + rq = blk_get_request(drive->queue, READ, __GFP_WAIT); + rq->cmd_type = REQ_TYPE_SPECIAL; + rq->buffer = (char *)pc; +- +- if (pc->req_xfer) { +- rq->data = pc->buf; +- rq->data_len = pc->req_xfer; +- } +- + memcpy(rq->cmd, pc->c, 12); + if (drive->media == ide_tape) + rq->cmd[13] = REQ_IDETAPE_PC1; +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/drivers/ide/ide.c linux-2.6.29-rc3.owrt/drivers/ide/ide.c +--- linux-2.6.29.owrt/drivers/ide/ide.c 2009-05-10 22:04:39.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/drivers/ide/ide.c 2009-05-10 23:48:28.000000000 +0200 +@@ -337,7 +337,6 @@ + int a, b, i, j = 1; + unsigned int *dev_param_mask = (unsigned int *)kp->arg; + +- /* controller . device (0 or 1) [ : 1 (set) | 0 (clear) ] */ + if (sscanf(s, "%d.%d:%d", &a, &b, &j) != 3 && + sscanf(s, "%d.%d", &a, &b) != 2) + return -EINVAL; +@@ -350,7 +349,7 @@ + if (j) + *dev_param_mask |= (1 << i); + else +- *dev_param_mask &= ~(1 << i); ++ *dev_param_mask &= (1 << i); + + return 0; + } +@@ -393,8 +392,6 @@ + { + int a, b, c = 0, h = 0, s = 0, i, j = 1; + +- /* controller . device (0 or 1) : Cylinders , Heads , Sectors */ +- /* controller . device (0 or 1) : 1 (use CHS) | 0 (ignore CHS) */ + if (sscanf(str, "%d.%d:%d,%d,%d", &a, &b, &c, &h, &s) != 5 && + sscanf(str, "%d.%d:%d", &a, &b, &j) != 3) + return -EINVAL; +@@ -410,7 +407,7 @@ + if (j) + ide_disks |= (1 << i); + else +- ide_disks &= ~(1 << i); ++ ide_disks &= (1 << i); + + ide_disks_chs[i].cyl = c; + ide_disks_chs[i].head = h; +@@ -472,8 +469,6 @@ + { + int i, j = 1; + +- /* controller (ignore) */ +- /* controller : 1 (ignore) | 0 (use) */ + if (sscanf(s, "%d:%d", &i, &j) != 2 && sscanf(s, "%d", &i) != 1) + return -EINVAL; + +@@ -483,7 +478,7 @@ + if (j) + ide_ignore_cable |= (1 << i); + else +- ide_ignore_cable &= ~(1 << i); ++ ide_ignore_cable &= (1 << i); + + return 0; + } +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/drivers/ide/ide-cd.c linux-2.6.29-rc3.owrt/drivers/ide/ide-cd.c +--- linux-2.6.29.owrt/drivers/ide/ide-cd.c 2009-05-10 22:04:39.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/drivers/ide/ide-cd.c 2009-05-10 23:48:28.000000000 +0200 +@@ -55,7 +55,7 @@ + + static DEFINE_MUTEX(idecd_ref_mutex); + +-static void ide_cd_release(struct device *); ++static void ide_cd_release(struct kref *); + + static struct cdrom_info *ide_cd_get(struct gendisk *disk) + { +@@ -67,7 +67,7 @@ + if (ide_device_get(cd->drive)) + cd = NULL; + else +- get_device(&cd->dev); ++ kref_get(&cd->kref); + + } + mutex_unlock(&idecd_ref_mutex); +@@ -79,7 +79,7 @@ + ide_drive_t *drive = cd->drive; + + mutex_lock(&idecd_ref_mutex); +- put_device(&cd->dev); ++ kref_put(&cd->kref, ide_cd_release); + ide_device_put(drive); + mutex_unlock(&idecd_ref_mutex); + } +@@ -194,14 +194,6 @@ + bio_sectors = max(bio_sectors(failed_command->bio), 4U); + sector &= ~(bio_sectors - 1); + +- /* +- * The SCSI specification allows for the value +- * returned by READ CAPACITY to be up to 75 2K +- * sectors past the last readable block. +- * Therefore, if we hit a medium error within the +- * last 75 2K sectors, we decrease the saved size +- * value. +- */ + if (sector < get_capacity(info->disk) && + drive->probed_capacity - sector < 4 * 75) + set_capacity(info->disk, sector); +@@ -795,9 +787,6 @@ + if (blk_fs_request(rq)) { + ide_end_request(drive, 1, rq->nr_sectors); + return ide_stopped; +- } else if (rq->cmd_type == REQ_TYPE_ATA_PC && !rq->bio) { +- ide_end_request(drive, 1, 1); +- return ide_stopped; + } + goto end_request; + } +@@ -1798,17 +1787,15 @@ + ide_debug_log(IDE_DBG_FUNC, "Call %s\n", __func__); + + ide_proc_unregister_driver(drive, info->driver); +- device_del(&info->dev); ++ + del_gendisk(info->disk); + +- mutex_lock(&idecd_ref_mutex); +- put_device(&info->dev); +- mutex_unlock(&idecd_ref_mutex); ++ ide_cd_put(info); + } + +-static void ide_cd_release(struct device *dev) ++static void ide_cd_release(struct kref *kref) + { +- struct cdrom_info *info = to_ide_drv(dev, cdrom_info); ++ struct cdrom_info *info = to_ide_drv(kref, cdrom_info); + struct cdrom_device_info *devinfo = &info->devinfo; + ide_drive_t *drive = info->drive; + struct gendisk *g = info->disk; +@@ -2007,12 +1994,7 @@ + + ide_init_disk(g, drive); + +- info->dev.parent = &drive->gendev; +- info->dev.release = ide_cd_release; +- dev_set_name(&info->dev, dev_name(&drive->gendev)); +- +- if (device_register(&info->dev)) +- goto out_free_disk; ++ kref_init(&info->kref); + + info->drive = drive; + info->driver = &ide_cdrom_driver; +@@ -2026,7 +2008,7 @@ + g->driverfs_dev = &drive->gendev; + g->flags = GENHD_FL_CD | GENHD_FL_REMOVABLE; + if (ide_cdrom_setup(drive)) { +- put_device(&info->dev); ++ ide_cd_release(&info->kref); + goto failed; + } + +@@ -2036,8 +2018,6 @@ + add_disk(g); + return 0; + +-out_free_disk: +- put_disk(g); + out_free_cd: + kfree(info); + failed: +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/drivers/ide/ide-cd.h linux-2.6.29-rc3.owrt/drivers/ide/ide-cd.h +--- linux-2.6.29.owrt/drivers/ide/ide-cd.h 2009-05-10 22:04:39.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/drivers/ide/ide-cd.h 2009-05-10 23:48:28.000000000 +0200 +@@ -80,7 +80,7 @@ + ide_drive_t *drive; + struct ide_driver *driver; + struct gendisk *disk; +- struct device dev; ++ struct kref kref; + + /* Buffer for table of contents. NULL if we haven't allocated + a TOC buffer for this device yet. */ +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/drivers/ide/ide-disk_proc.c linux-2.6.29-rc3.owrt/drivers/ide/ide-disk_proc.c +--- linux-2.6.29.owrt/drivers/ide/ide-disk_proc.c 2009-05-10 22:04:39.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/drivers/ide/ide-disk_proc.c 2009-05-10 23:48:28.000000000 +0200 +@@ -125,5 +125,5 @@ + IDE_PROC_DEVSET(multcount, 0, 16), + IDE_PROC_DEVSET(nowerr, 0, 1), + IDE_PROC_DEVSET(wcache, 0, 1), +- { NULL }, ++ { 0 }, + }; +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/drivers/ide/ide-dma.c linux-2.6.29-rc3.owrt/drivers/ide/ide-dma.c +--- linux-2.6.29.owrt/drivers/ide/ide-dma.c 2009-05-10 22:04:39.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/drivers/ide/ide-dma.c 2009-05-10 23:48:28.000000000 +0200 +@@ -128,7 +128,6 @@ + { + ide_hwif_t *hwif = drive->hwif; + struct scatterlist *sg = hwif->sg_table; +- int i; + + ide_map_sg(drive, rq); + +@@ -137,13 +136,8 @@ + else + hwif->sg_dma_direction = DMA_TO_DEVICE; + +- i = dma_map_sg(hwif->dev, sg, hwif->sg_nents, hwif->sg_dma_direction); +- if (i) { +- hwif->orig_sg_nents = hwif->sg_nents; +- hwif->sg_nents = i; +- } +- +- return i; ++ return dma_map_sg(hwif->dev, sg, hwif->sg_nents, ++ hwif->sg_dma_direction); + } + EXPORT_SYMBOL_GPL(ide_build_sglist); + +@@ -162,7 +156,7 @@ + { + ide_hwif_t *hwif = drive->hwif; + +- dma_unmap_sg(hwif->dev, hwif->sg_table, hwif->orig_sg_nents, ++ dma_unmap_sg(hwif->dev, hwif->sg_table, hwif->sg_nents, + hwif->sg_dma_direction); + } + EXPORT_SYMBOL_GPL(ide_destroy_dmatable); +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/drivers/ide/ide-floppy.c linux-2.6.29-rc3.owrt/drivers/ide/ide-floppy.c +--- linux-2.6.29.owrt/drivers/ide/ide-floppy.c 2009-05-10 22:04:39.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/drivers/ide/ide-floppy.c 2009-05-10 23:48:28.000000000 +0200 +@@ -327,10 +327,8 @@ + return ide_stopped; + } + +- if (blk_fs_request(rq) || pc->req_xfer) { +- ide_init_sg_cmd(drive, rq); +- ide_map_sg(drive, rq); +- } ++ ide_init_sg_cmd(drive, rq); ++ ide_map_sg(drive, rq); + + pc->sg = hwif->sg_table; + pc->sg_cnt = hwif->sg_nents; +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/drivers/ide/ide-floppy_proc.c linux-2.6.29-rc3.owrt/drivers/ide/ide-floppy_proc.c +--- linux-2.6.29.owrt/drivers/ide/ide-floppy_proc.c 2009-05-10 22:04:39.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/drivers/ide/ide-floppy_proc.c 2009-05-10 23:48:28.000000000 +0200 +@@ -29,5 +29,5 @@ + IDE_PROC_DEVSET(bios_head, 0, 255), + IDE_PROC_DEVSET(bios_sect, 0, 63), + IDE_PROC_DEVSET(ticks, 0, 255), +- { NULL }, ++ { 0 }, + }; +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/drivers/ide/ide-gd.c linux-2.6.29-rc3.owrt/drivers/ide/ide-gd.c +--- linux-2.6.29.owrt/drivers/ide/ide-gd.c 2009-05-10 22:04:39.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/drivers/ide/ide-gd.c 2009-05-10 23:48:28.000000000 +0200 +@@ -25,7 +25,7 @@ + + static DEFINE_MUTEX(ide_disk_ref_mutex); + +-static void ide_disk_release(struct device *); ++static void ide_disk_release(struct kref *); + + static struct ide_disk_obj *ide_disk_get(struct gendisk *disk) + { +@@ -37,7 +37,7 @@ + if (ide_device_get(idkp->drive)) + idkp = NULL; + else +- get_device(&idkp->dev); ++ kref_get(&idkp->kref); + } + mutex_unlock(&ide_disk_ref_mutex); + return idkp; +@@ -48,7 +48,7 @@ + ide_drive_t *drive = idkp->drive; + + mutex_lock(&ide_disk_ref_mutex); +- put_device(&idkp->dev); ++ kref_put(&idkp->kref, ide_disk_release); + ide_device_put(drive); + mutex_unlock(&ide_disk_ref_mutex); + } +@@ -66,18 +66,17 @@ + struct gendisk *g = idkp->disk; + + ide_proc_unregister_driver(drive, idkp->driver); +- device_del(&idkp->dev); ++ + del_gendisk(g); ++ + drive->disk_ops->flush(drive); + +- mutex_lock(&ide_disk_ref_mutex); +- put_device(&idkp->dev); +- mutex_unlock(&ide_disk_ref_mutex); ++ ide_disk_put(idkp); + } + +-static void ide_disk_release(struct device *dev) ++static void ide_disk_release(struct kref *kref) + { +- struct ide_disk_obj *idkp = to_ide_drv(dev, ide_disk_obj); ++ struct ide_disk_obj *idkp = to_ide_drv(kref, ide_disk_obj); + ide_drive_t *drive = idkp->drive; + struct gendisk *g = idkp->disk; + +@@ -349,12 +348,7 @@ + + ide_init_disk(g, drive); + +- idkp->dev.parent = &drive->gendev; +- idkp->dev.release = ide_disk_release; +- dev_set_name(&idkp->dev, dev_name(&drive->gendev)); +- +- if (device_register(&idkp->dev)) +- goto out_free_disk; ++ kref_init(&idkp->kref); + + idkp->drive = drive; + idkp->driver = &ide_gd_driver; +@@ -379,8 +373,6 @@ + add_disk(g); + return 0; + +-out_free_disk: +- put_disk(g); + out_free_idkp: + kfree(idkp); + failed: +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/drivers/ide/ide-gd.h linux-2.6.29-rc3.owrt/drivers/ide/ide-gd.h +--- linux-2.6.29.owrt/drivers/ide/ide-gd.h 2009-05-10 22:04:39.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/drivers/ide/ide-gd.h 2009-05-10 23:48:28.000000000 +0200 +@@ -17,7 +17,7 @@ + ide_drive_t *drive; + struct ide_driver *driver; + struct gendisk *disk; +- struct device dev; ++ struct kref kref; + unsigned int openers; /* protected by BKL for now */ + + /* Last failed packet command */ +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/drivers/ide/ide-io.c linux-2.6.29-rc3.owrt/drivers/ide/ide-io.c +--- linux-2.6.29.owrt/drivers/ide/ide-io.c 2009-05-10 22:04:39.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/drivers/ide/ide-io.c 2009-05-10 23:48:28.000000000 +0200 +@@ -418,14 +418,11 @@ + ide_hwif_t *hwif = drive->hwif; + struct scatterlist *sg = hwif->sg_table; + +- if (rq->cmd_type == REQ_TYPE_ATA_TASKFILE) { ++ if (rq->cmd_type != REQ_TYPE_ATA_TASKFILE) { ++ hwif->sg_nents = blk_rq_map_sg(drive->queue, rq, sg); ++ } else { + sg_init_one(sg, rq->buffer, rq->nr_sectors * SECTOR_SIZE); + hwif->sg_nents = 1; +- } else if (!rq->bio) { +- sg_init_one(sg, rq->data, rq->data_len); +- hwif->sg_nents = 1; +- } else { +- hwif->sg_nents = blk_rq_map_sg(drive->queue, rq, sg); + } + } + +@@ -908,7 +905,7 @@ + ide_drive_t *uninitialized_var(drive); + ide_handler_t *handler; + unsigned long flags; +- int wait = -1; ++ unsigned long wait = -1; + int plug_device = 0; + + spin_lock_irqsave(&hwif->lock, flags); +@@ -1162,7 +1159,6 @@ + + return irq_ret; + } +-EXPORT_SYMBOL_GPL(ide_intr); + + /** + * ide_do_drive_cmd - issue IDE special command +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/drivers/ide/ide-iops.c linux-2.6.29-rc3.owrt/drivers/ide/ide-iops.c +--- linux-2.6.29.owrt/drivers/ide/ide-iops.c 2009-05-10 22:04:39.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/drivers/ide/ide-iops.c 2009-05-10 23:48:28.000000000 +0200 +@@ -315,8 +315,6 @@ + u8 io_32bit = drive->io_32bit; + u8 mmio = (hwif->host_flags & IDE_HFLAG_MMIO) ? 1 : 0; + +- len++; +- + if (io_32bit) { + unsigned long uninitialized_var(flags); + +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/drivers/ide/ide-probe.c linux-2.6.29-rc3.owrt/drivers/ide/ide-probe.c +--- linux-2.6.29.owrt/drivers/ide/ide-probe.c 2009-05-10 22:04:39.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/drivers/ide/ide-probe.c 2009-05-10 23:48:28.000000000 +0200 +@@ -950,7 +950,6 @@ + static int init_irq (ide_hwif_t *hwif) + { + struct ide_io_ports *io_ports = &hwif->io_ports; +- irq_handler_t irq_handler; + int sa = 0; + + mutex_lock(&ide_cfg_mtx); +@@ -960,10 +959,6 @@ + hwif->timer.function = &ide_timer_expiry; + hwif->timer.data = (unsigned long)hwif; + +- irq_handler = hwif->host->irq_handler; +- if (irq_handler == NULL) +- irq_handler = ide_intr; +- + #if defined(__mc68000__) + sa = IRQF_SHARED; + #endif /* __mc68000__ */ +@@ -974,7 +969,7 @@ + if (io_ports->ctl_addr) + hwif->tp_ops->set_irq(hwif, 1); + +- if (request_irq(hwif->irq, irq_handler, sa, hwif->name, hwif)) ++ if (request_irq(hwif->irq, &ide_intr, sa, hwif->name, hwif)) + goto out_up; + + if (!hwif->rqsize) { +@@ -1472,30 +1467,6 @@ + } + EXPORT_SYMBOL_GPL(ide_host_alloc); + +-static void ide_port_free(ide_hwif_t *hwif) +-{ +- ide_port_free_devices(hwif); +- ide_free_port_slot(hwif->index); +- kfree(hwif); +-} +- +-static void ide_disable_port(ide_hwif_t *hwif) +-{ +- struct ide_host *host = hwif->host; +- int i; +- +- printk(KERN_INFO "%s: disabling port\n", hwif->name); +- +- for (i = 0; i < MAX_HOST_PORTS; i++) { +- if (host->ports[i] == hwif) { +- host->ports[i] = NULL; +- host->n_ports--; +- } +- } +- +- ide_port_free(hwif); +-} +- + int ide_host_register(struct ide_host *host, const struct ide_port_info *d, + hw_regs_t **hws) + { +@@ -1536,12 +1507,8 @@ + hwif->present = 1; + + if (hwif->chipset != ide_4drives || !hwif->mate || +- !hwif->mate->present) { +- if (ide_register_port(hwif)) { +- ide_disable_port(hwif); +- continue; +- } +- } ++ !hwif->mate->present) ++ ide_register_port(hwif); + + if (hwif->present) + ide_port_tune_devices(hwif); +@@ -1554,8 +1521,7 @@ + if (hwif_init(hwif) == 0) { + printk(KERN_INFO "%s: failed to initialize IDE " + "interface\n", hwif->name); +- device_unregister(&hwif->gendev); +- ide_disable_port(hwif); ++ hwif->present = 0; + continue; + } + +@@ -1694,8 +1660,12 @@ + int i; + + ide_host_for_each_port(i, hwif, host) { +- if (hwif) +- ide_port_free(hwif); ++ if (hwif == NULL) ++ continue; ++ ++ ide_port_free_devices(hwif); ++ ide_free_port_slot(hwif->index); ++ kfree(hwif); + } + + kfree(host); +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/drivers/ide/ide-proc.c linux-2.6.29-rc3.owrt/drivers/ide/ide-proc.c +--- linux-2.6.29.owrt/drivers/ide/ide-proc.c 2009-05-10 22:04:39.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/drivers/ide/ide-proc.c 2009-05-10 23:48:28.000000000 +0200 +@@ -231,7 +231,7 @@ + IDE_PROC_DEVSET(pio_mode, 0, 255), + IDE_PROC_DEVSET(unmaskirq, 0, 1), + IDE_PROC_DEVSET(using_dma, 0, 1), +- { NULL }, ++ { 0 }, + }; + + static void proc_ide_settings_warn(void) +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/drivers/ide/ide-tape.c linux-2.6.29-rc3.owrt/drivers/ide/ide-tape.c +--- linux-2.6.29.owrt/drivers/ide/ide-tape.c 2009-05-10 22:04:39.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/drivers/ide/ide-tape.c 2009-05-10 23:48:28.000000000 +0200 +@@ -169,7 +169,7 @@ + ide_drive_t *drive; + struct ide_driver *driver; + struct gendisk *disk; +- struct device dev; ++ struct kref kref; + + /* + * failed_pc points to the last failed packet command, or contains +@@ -267,7 +267,7 @@ + + static struct class *idetape_sysfs_class; + +-static void ide_tape_release(struct device *); ++static void ide_tape_release(struct kref *); + + static struct ide_tape_obj *ide_tape_get(struct gendisk *disk) + { +@@ -279,7 +279,7 @@ + if (ide_device_get(tape->drive)) + tape = NULL; + else +- get_device(&tape->dev); ++ kref_get(&tape->kref); + } + mutex_unlock(&idetape_ref_mutex); + return tape; +@@ -290,7 +290,7 @@ + ide_drive_t *drive = tape->drive; + + mutex_lock(&idetape_ref_mutex); +- put_device(&tape->dev); ++ kref_put(&tape->kref, ide_tape_release); + ide_device_put(drive); + mutex_unlock(&idetape_ref_mutex); + } +@@ -308,7 +308,7 @@ + mutex_lock(&idetape_ref_mutex); + tape = idetape_devs[i]; + if (tape) +- get_device(&tape->dev); ++ kref_get(&tape->kref); + mutex_unlock(&idetape_ref_mutex); + return tape; + } +@@ -2166,7 +2166,7 @@ + __IDE_PROC_DEVSET(speed, 0, 0xffff, NULL, NULL), + __IDE_PROC_DEVSET(tdsc, IDETAPE_DSC_RW_MIN, IDETAPE_DSC_RW_MAX, + mulf_tdsc, divf_tdsc), +- { NULL }, ++ { 0 }, + }; + #endif + +@@ -2256,17 +2256,15 @@ + idetape_tape_t *tape = drive->driver_data; + + ide_proc_unregister_driver(drive, tape->driver); +- device_del(&tape->dev); ++ + ide_unregister_region(tape->disk); + +- mutex_lock(&idetape_ref_mutex); +- put_device(&tape->dev); +- mutex_unlock(&idetape_ref_mutex); ++ ide_tape_put(tape); + } + +-static void ide_tape_release(struct device *dev) ++static void ide_tape_release(struct kref *kref) + { +- struct ide_tape_obj *tape = to_ide_drv(dev, ide_tape_obj); ++ struct ide_tape_obj *tape = to_ide_drv(kref, ide_tape_obj); + ide_drive_t *drive = tape->drive; + struct gendisk *g = tape->disk; + +@@ -2409,12 +2407,7 @@ + + ide_init_disk(g, drive); + +- tape->dev.parent = &drive->gendev; +- tape->dev.release = ide_tape_release; +- dev_set_name(&tape->dev, dev_name(&drive->gendev)); +- +- if (device_register(&tape->dev)) +- goto out_free_disk; ++ kref_init(&tape->kref); + + tape->drive = drive; + tape->driver = &idetape_driver; +@@ -2443,8 +2436,6 @@ + + return 0; + +-out_free_disk: +- put_disk(g); + out_free_tape: + kfree(tape); + failed: +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/drivers/ide/it821x.c linux-2.6.29-rc3.owrt/drivers/ide/it821x.c +--- linux-2.6.29.owrt/drivers/ide/it821x.c 2009-05-10 22:04:39.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/drivers/ide/it821x.c 2009-05-10 23:48:28.000000000 +0200 +@@ -5,8 +5,9 @@ + * May be copied or modified under the terms of the GNU General Public License + * Based in part on the ITE vendor provided SCSI driver. + * +- * Documentation: +- * Datasheet is freely available, some other documents under NDA. ++ * Documentation available from ++ * http://www.ite.com.tw/pc/IT8212F_V04.pdf ++ * Some other documents are NDA. + * + * The ITE8212 isn't exactly a standard IDE controller. It has two + * modes. In pass through mode then it is an IDE controller. In its smart +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/drivers/ide/Kconfig linux-2.6.29-rc3.owrt/drivers/ide/Kconfig +--- linux-2.6.29.owrt/drivers/ide/Kconfig 2009-05-10 22:04:39.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/drivers/ide/Kconfig 2009-05-10 23:48:28.000000000 +0200 +@@ -46,7 +46,7 @@ + SMART parameters from disk drives. + + To compile this driver as a module, choose M here: the +- module will be called ide-core.ko. ++ module will be called ide. + + For further information, please read <file:Documentation/ide/ide.txt>. + +@@ -465,16 +465,6 @@ + + It is safe to say Y to this question. + +-config BLK_DEV_CS5536 +- tristate "CS5536 chipset support" +- depends on X86_32 +- select BLK_DEV_IDEDMA_PCI +- help +- This option enables support for the AMD CS5536 +- companion chip used with the Geode LX processor family. +- +- If unsure, say N. +- + config BLK_DEV_HPT366 + tristate "HPT36X/37X chipset support" + select BLK_DEV_IDEDMA_PCI +@@ -721,11 +711,6 @@ + depends on SOC_TX4939 + select BLK_DEV_IDEDMA_SFF + +-config BLK_DEV_IDE_AT91 +- tristate "Atmel AT91 (SAM9, CAP9, AT572D940HF) IDE support" +- depends on ARM && ARCH_AT91 && !ARCH_AT91RM9200 && !ARCH_AT91X40 +- select IDE_TIMINGS +- + config IDE_ARM + tristate "ARM IDE support" + depends on ARM && (ARCH_RPC || ARCH_SHARK) +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/drivers/ide/Makefile linux-2.6.29-rc3.owrt/drivers/ide/Makefile +--- linux-2.6.29.owrt/drivers/ide/Makefile 2009-05-10 22:04:39.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/drivers/ide/Makefile 2009-05-10 23:48:28.000000000 +0200 +@@ -43,7 +43,6 @@ + obj-$(CONFIG_BLK_DEV_CS5520) += cs5520.o + obj-$(CONFIG_BLK_DEV_CS5530) += cs5530.o + obj-$(CONFIG_BLK_DEV_CS5535) += cs5535.o +-obj-$(CONFIG_BLK_DEV_CS5536) += cs5536.o + obj-$(CONFIG_BLK_DEV_SC1200) += sc1200.o + obj-$(CONFIG_BLK_DEV_CY82C693) += cy82c693.o + obj-$(CONFIG_BLK_DEV_DELKIN) += delkin_cb.o +@@ -116,4 +115,3 @@ + + obj-$(CONFIG_BLK_DEV_IDE_TX4938) += tx4938ide.o + obj-$(CONFIG_BLK_DEV_IDE_TX4939) += tx4939ide.o +-obj-$(CONFIG_BLK_DEV_IDE_AT91) += at91_ide.o +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/drivers/ide/qd65xx.c linux-2.6.29-rc3.owrt/drivers/ide/qd65xx.c +--- linux-2.6.29.owrt/drivers/ide/qd65xx.c 2009-05-10 22:04:39.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/drivers/ide/qd65xx.c 2009-05-10 23:48:28.000000000 +0200 +@@ -16,7 +16,7 @@ + + /* + * Rewritten from the work of Colten Edwards <pje120@cs.usask.ca> by +- * Samuel Thibault <samuel.thibault@ens-lyon.org> ++ * Samuel Thibault <samuel.thibault@fnac.net> + */ + + #include <linux/module.h> +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/drivers/ide/qd65xx.h linux-2.6.29-rc3.owrt/drivers/ide/qd65xx.h +--- linux-2.6.29.owrt/drivers/ide/qd65xx.h 2009-05-10 22:04:39.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/drivers/ide/qd65xx.h 2009-05-10 23:48:28.000000000 +0200 +@@ -4,7 +4,7 @@ + + /* + * Authors: Petr Soucek <petr@ryston.cz> +- * Samuel Thibault <samuel.thibault@ens-lyon.org> ++ * Samuel Thibault <samuel.thibault@fnac.net> + */ + + /* truncates a in [b,c] */ +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/drivers/ide/tx4939ide.c linux-2.6.29-rc3.owrt/drivers/ide/tx4939ide.c +--- linux-2.6.29.owrt/drivers/ide/tx4939ide.c 2009-05-10 22:04:39.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/drivers/ide/tx4939ide.c 2009-05-10 23:48:28.000000000 +0200 +@@ -261,9 +261,9 @@ + bcount = cur_len; + /* + * This workaround for zero count seems required. +- * (standard ide_build_dmatable does it too) ++ * (standard ide_build_dmatable do it too) + */ +- if (bcount == 0x10000) ++ if ((bcount & 0xffff) == 0x0000) + bcount = 0x8000; + *table++ = bcount & 0xffff; + *table++ = cur_addr; +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/drivers/ide/via82cxxx.c linux-2.6.29-rc3.owrt/drivers/ide/via82cxxx.c +--- linux-2.6.29.owrt/drivers/ide/via82cxxx.c 2009-05-10 22:04:39.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/drivers/ide/via82cxxx.c 2009-05-10 23:48:28.000000000 +0200 +@@ -448,11 +448,6 @@ + d.host_flags |= IDE_HFLAG_FORCE_LEGACY_IRQS; + #endif + +-#ifdef CONFIG_AMIGAONE +- if (machine_is(amigaone)) +- d.host_flags |= IDE_HFLAG_FORCE_LEGACY_IRQS; +-#endif +- + d.udma_mask = via_config->udma_mask; + + vdev = kzalloc(sizeof(*vdev), GFP_KERNEL); +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/drivers/ieee1394/dma.h linux-2.6.29-rc3.owrt/drivers/ieee1394/dma.h +--- linux-2.6.29.owrt/drivers/ieee1394/dma.h 2009-05-10 22:04:38.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/drivers/ieee1394/dma.h 2009-05-10 23:48:28.000000000 +0200 +@@ -12,7 +12,6 @@ + + #include <asm/types.h> + +-struct file; + struct pci_dev; + struct scatterlist; + struct vm_area_struct; +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/drivers/ieee1394/dv1394.c linux-2.6.29-rc3.owrt/drivers/ieee1394/dv1394.c +--- linux-2.6.29.owrt/drivers/ieee1394/dv1394.c 2009-05-10 22:04:38.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/drivers/ieee1394/dv1394.c 2009-05-10 23:48:28.000000000 +0200 +@@ -1823,10 +1823,6 @@ + + #endif + +- printk(KERN_INFO "%s: NOTE, the dv1394 interface is unsupported " +- "and will not be available in the new firewire driver stack. " +- "Try libraw1394 based programs instead.\n", current->comm); +- + return 0; + } + +@@ -2571,6 +2567,10 @@ + { + int ret; + ++ printk(KERN_WARNING ++ "NOTE: The dv1394 driver is unsupported and may be removed in a " ++ "future Linux release. Use raw1394 instead.\n"); ++ + cdev_init(&dv1394_cdev, &dv1394_fops); + dv1394_cdev.owner = THIS_MODULE; + ret = cdev_add(&dv1394_cdev, IEEE1394_DV1394_DEV, 16); +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/drivers/ieee1394/ieee1394_core.c linux-2.6.29-rc3.owrt/drivers/ieee1394/ieee1394_core.c +--- linux-2.6.29.owrt/drivers/ieee1394/ieee1394_core.c 2009-05-10 22:04:38.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/drivers/ieee1394/ieee1394_core.c 2009-05-10 23:48:28.000000000 +0200 +@@ -338,7 +338,6 @@ + u8 cldcnt[nodecount]; + u8 *map = host->speed_map; + u8 *speedcap = host->speed; +- u8 local_link_speed = host->csr.lnk_spd; + struct selfid *sid; + struct ext_selfid *esid; + int i, j, n; +@@ -374,8 +373,8 @@ + if (sid->port2 == SELFID_PORT_CHILD) cldcnt[n]++; + + speedcap[n] = sid->speed; +- if (speedcap[n] > local_link_speed) +- speedcap[n] = local_link_speed; ++ if (speedcap[n] > host->csr.lnk_spd) ++ speedcap[n] = host->csr.lnk_spd; + n--; + } + } +@@ -408,11 +407,12 @@ + } + } + +- /* assume a maximum speed for 1394b PHYs, nodemgr will correct it */ +- if (local_link_speed > SELFID_SPEED_UNKNOWN) +- for (i = 0; i < nodecount; i++) +- if (speedcap[i] == SELFID_SPEED_UNKNOWN) +- speedcap[i] = local_link_speed; ++#if SELFID_SPEED_UNKNOWN != IEEE1394_SPEED_MAX ++ /* assume maximum speed for 1394b PHYs, nodemgr will correct it */ ++ for (n = 0; n < nodecount; n++) ++ if (speedcap[n] == SELFID_SPEED_UNKNOWN) ++ speedcap[n] = IEEE1394_SPEED_MAX; ++#endif + } + + +@@ -1275,7 +1275,7 @@ + unregister_chrdev_region(IEEE1394_CORE_DEV, 256); + } + +-fs_initcall(ieee1394_init); ++module_init(ieee1394_init); + module_exit(ieee1394_cleanup); + + /* Exported symbols */ +@@ -1314,7 +1314,6 @@ + EXPORT_SYMBOL(hpsb_make_phypacket); + EXPORT_SYMBOL(hpsb_read); + EXPORT_SYMBOL(hpsb_write); +-EXPORT_SYMBOL(hpsb_lock); + EXPORT_SYMBOL(hpsb_packet_success); + + /** highlevel.c **/ +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/drivers/ieee1394/ieee1394.h linux-2.6.29-rc3.owrt/drivers/ieee1394/ieee1394.h +--- linux-2.6.29.owrt/drivers/ieee1394/ieee1394.h 2009-05-10 22:04:38.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/drivers/ieee1394/ieee1394.h 2009-05-10 23:48:28.000000000 +0200 +@@ -54,7 +54,9 @@ + #define IEEE1394_SPEED_800 0x03 + #define IEEE1394_SPEED_1600 0x04 + #define IEEE1394_SPEED_3200 0x05 +-#define IEEE1394_SPEED_MAX IEEE1394_SPEED_3200 ++ ++/* The current highest tested speed supported by the subsystem */ ++#define IEEE1394_SPEED_MAX IEEE1394_SPEED_800 + + /* Maps speed values above to a string representation */ + extern const char *hpsb_speedto_str[]; +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/drivers/ieee1394/ieee1394_transactions.c linux-2.6.29-rc3.owrt/drivers/ieee1394/ieee1394_transactions.c +--- linux-2.6.29.owrt/drivers/ieee1394/ieee1394_transactions.c 2009-05-10 22:04:38.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/drivers/ieee1394/ieee1394_transactions.c 2009-05-10 23:48:28.000000000 +0200 +@@ -501,6 +501,8 @@ + if (length == 0) + return -EINVAL; + ++ BUG_ON(in_interrupt()); // We can't be called in an interrupt, yet ++ + packet = hpsb_make_readpacket(host, node, addr, length); + + if (!packet) { +@@ -548,6 +550,8 @@ + if (length == 0) + return -EINVAL; + ++ BUG_ON(in_interrupt()); // We can't be called in an interrupt, yet ++ + packet = hpsb_make_writepacket(host, node, addr, buffer, length); + + if (!packet) +@@ -566,30 +570,3 @@ + + return retval; + } +- +-int hpsb_lock(struct hpsb_host *host, nodeid_t node, unsigned int generation, +- u64 addr, int extcode, quadlet_t *data, quadlet_t arg) +-{ +- struct hpsb_packet *packet; +- int retval = 0; +- +- packet = hpsb_make_lockpacket(host, node, addr, extcode, data, arg); +- if (!packet) +- return -ENOMEM; +- +- packet->generation = generation; +- retval = hpsb_send_packet_and_wait(packet); +- if (retval < 0) +- goto hpsb_lock_fail; +- +- retval = hpsb_packet_success(packet); +- +- if (retval == 0) +- *data = packet->data[0]; +- +-hpsb_lock_fail: +- hpsb_free_tlabel(packet); +- hpsb_free_packet(packet); +- +- return retval; +-} +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/drivers/ieee1394/ieee1394_transactions.h linux-2.6.29-rc3.owrt/drivers/ieee1394/ieee1394_transactions.h +--- linux-2.6.29.owrt/drivers/ieee1394/ieee1394_transactions.h 2009-05-10 22:04:38.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/drivers/ieee1394/ieee1394_transactions.h 2009-05-10 23:48:28.000000000 +0200 +@@ -30,8 +30,6 @@ + u64 addr, quadlet_t *buffer, size_t length); + int hpsb_write(struct hpsb_host *host, nodeid_t node, unsigned int generation, + u64 addr, quadlet_t *buffer, size_t length); +-int hpsb_lock(struct hpsb_host *host, nodeid_t node, unsigned int generation, +- u64 addr, int extcode, quadlet_t *data, quadlet_t arg); + + #ifdef HPSB_DEBUG_TLABELS + extern spinlock_t hpsb_tlabel_lock; +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/drivers/ieee1394/iso.h linux-2.6.29-rc3.owrt/drivers/ieee1394/iso.h +--- linux-2.6.29.owrt/drivers/ieee1394/iso.h 2009-05-10 22:04:38.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/drivers/ieee1394/iso.h 2009-05-10 23:48:28.000000000 +0200 +@@ -13,7 +13,6 @@ + #define IEEE1394_ISO_H + + #include <linux/spinlock_types.h> +-#include <linux/wait.h> + #include <asm/atomic.h> + #include <asm/types.h> + +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/drivers/ieee1394/nodemgr.c linux-2.6.29-rc3.owrt/drivers/ieee1394/nodemgr.c +--- linux-2.6.29.owrt/drivers/ieee1394/nodemgr.c 2009-05-10 22:04:38.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/drivers/ieee1394/nodemgr.c 2009-05-10 23:48:28.000000000 +0200 +@@ -971,9 +971,6 @@ + ud->ud_kv = ud_kv; + ud->id = (*id)++; + +- /* inherit vendor_id from root directory if none exists in unit dir */ +- ud->vendor_id = ne->vendor_id; +- + csr1212_for_each_dir_entry(ne->csr, kv, ud_kv, dentry) { + switch (kv->key.id) { + case CSR1212_KV_ID_VENDOR: +@@ -1268,8 +1265,7 @@ + csr1212_destroy_csr(csr); + } + +- /* Finally, mark the node current */ +- smp_wmb(); ++ /* Mark the node current */ + ne->generation = generation; + + if (ne->in_limbo) { +@@ -1802,7 +1798,7 @@ + { + packet->host = ne->host; + packet->generation = ne->generation; +- smp_rmb(); ++ barrier(); + packet->node_id = ne->nodeid; + } + +@@ -1811,7 +1807,7 @@ + { + unsigned int generation = ne->generation; + +- smp_rmb(); ++ barrier(); + return hpsb_write(ne->host, ne->nodeid, generation, + addr, buffer, length); + } +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/drivers/ieee1394/nodemgr.h linux-2.6.29-rc3.owrt/drivers/ieee1394/nodemgr.h +--- linux-2.6.29.owrt/drivers/ieee1394/nodemgr.h 2009-05-10 22:04:38.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/drivers/ieee1394/nodemgr.h 2009-05-10 23:48:28.000000000 +0200 +@@ -21,11 +21,9 @@ + #define _IEEE1394_NODEMGR_H + + #include <linux/device.h> +-#include <asm/system.h> + #include <asm/types.h> + + #include "ieee1394_core.h" +-#include "ieee1394_transactions.h" + #include "ieee1394_types.h" + + struct csr1212_csr; +@@ -156,22 +154,6 @@ + void hpsb_node_fill_packet(struct node_entry *ne, struct hpsb_packet *packet); + int hpsb_node_write(struct node_entry *ne, u64 addr, + quadlet_t *buffer, size_t length); +-static inline int hpsb_node_read(struct node_entry *ne, u64 addr, +- quadlet_t *buffer, size_t length) +-{ +- unsigned int g = ne->generation; +- +- smp_rmb(); +- return hpsb_read(ne->host, ne->nodeid, g, addr, buffer, length); +-} +-static inline int hpsb_node_lock(struct node_entry *ne, u64 addr, int extcode, +- quadlet_t *buffer, quadlet_t arg) +-{ +- unsigned int g = ne->generation; +- +- smp_rmb(); +- return hpsb_lock(ne->host, ne->nodeid, g, addr, extcode, buffer, arg); +-} + int nodemgr_for_each_host(void *data, int (*cb)(struct hpsb_host *, void *)); + + int init_ieee1394_nodemgr(void); +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/drivers/ieee1394/ohci1394.h linux-2.6.29-rc3.owrt/drivers/ieee1394/ohci1394.h +--- linux-2.6.29.owrt/drivers/ieee1394/ohci1394.h 2009-05-10 22:04:38.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/drivers/ieee1394/ohci1394.h 2009-05-10 23:48:28.000000000 +0200 +@@ -26,7 +26,7 @@ + + #define OHCI1394_DRIVER_NAME "ohci1394" + +-#define OHCI1394_MAX_AT_REQ_RETRIES 0xf ++#define OHCI1394_MAX_AT_REQ_RETRIES 0x2 + #define OHCI1394_MAX_AT_RESP_RETRIES 0x2 + #define OHCI1394_MAX_PHYS_RESP_RETRIES 0x8 + #define OHCI1394_MAX_SELF_ID_ERRORS 16 +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/drivers/ieee1394/sbp2.c linux-2.6.29-rc3.owrt/drivers/ieee1394/sbp2.c +--- linux-2.6.29.owrt/drivers/ieee1394/sbp2.c 2009-05-10 22:04:38.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/drivers/ieee1394/sbp2.c 2009-05-10 23:48:28.000000000 +0200 +@@ -115,8 +115,8 @@ + */ + static int sbp2_max_speed = IEEE1394_SPEED_MAX; + module_param_named(max_speed, sbp2_max_speed, int, 0644); +-MODULE_PARM_DESC(max_speed, "Limit data transfer speed (5 <= 3200, " +- "4 <= 1600, 3 <= 800, 2 <= 400, 1 <= 200, 0 = 100 Mb/s)"); ++MODULE_PARM_DESC(max_speed, "Force max speed " ++ "(3 = 800Mb/s, 2 = 400Mb/s, 1 = 200Mb/s, 0 = 100Mb/s)"); + + /* + * Set serialize_io to 0 or N to use dynamically appended lists of command ORBs. +@@ -256,7 +256,7 @@ + static int sbp2_max_speed_and_size(struct sbp2_lu *); + + +-static const u8 sbp2_speedto_max_payload[] = { 0x7, 0x8, 0x9, 0xa, 0xa, 0xa }; ++static const u8 sbp2_speedto_max_payload[] = { 0x7, 0x8, 0x9, 0xA, 0xB, 0xC }; + + static DEFINE_RWLOCK(sbp2_hi_logical_units_lock); + +@@ -347,8 +347,8 @@ + .sdev_attrs = sbp2_sysfs_sdev_attrs, + }; + +-#define SBP2_ROM_VALUE_WILDCARD ~0 /* match all */ +-#define SBP2_ROM_VALUE_MISSING 0xff000000 /* not present in the unit dir. */ ++/* for match-all entries in sbp2_workarounds_table */ ++#define SBP2_ROM_VALUE_WILDCARD 0x1000000 + + /* + * List of devices with known bugs. +@@ -359,70 +359,60 @@ + */ + static const struct { + u32 firmware_revision; +- u32 model; ++ u32 model_id; + unsigned workarounds; + } sbp2_workarounds_table[] = { + /* DViCO Momobay CX-1 with TSB42AA9 bridge */ { + .firmware_revision = 0x002800, +- .model = 0x001010, ++ .model_id = 0x001010, + .workarounds = SBP2_WORKAROUND_INQUIRY_36 | + SBP2_WORKAROUND_MODE_SENSE_8 | + SBP2_WORKAROUND_POWER_CONDITION, + }, + /* DViCO Momobay FX-3A with TSB42AA9A bridge */ { + .firmware_revision = 0x002800, +- .model = 0x000000, ++ .model_id = 0x000000, + .workarounds = SBP2_WORKAROUND_DELAY_INQUIRY | + SBP2_WORKAROUND_POWER_CONDITION, + }, + /* Initio bridges, actually only needed for some older ones */ { + .firmware_revision = 0x000200, +- .model = SBP2_ROM_VALUE_WILDCARD, ++ .model_id = SBP2_ROM_VALUE_WILDCARD, + .workarounds = SBP2_WORKAROUND_INQUIRY_36, + }, + /* PL-3507 bridge with Prolific firmware */ { + .firmware_revision = 0x012800, +- .model = SBP2_ROM_VALUE_WILDCARD, ++ .model_id = SBP2_ROM_VALUE_WILDCARD, + .workarounds = SBP2_WORKAROUND_POWER_CONDITION, + }, + /* Symbios bridge */ { + .firmware_revision = 0xa0b800, +- .model = SBP2_ROM_VALUE_WILDCARD, ++ .model_id = SBP2_ROM_VALUE_WILDCARD, + .workarounds = SBP2_WORKAROUND_128K_MAX_TRANS, + }, + /* Datafab MD2-FW2 with Symbios/LSILogic SYM13FW500 bridge */ { + .firmware_revision = 0x002600, +- .model = SBP2_ROM_VALUE_WILDCARD, ++ .model_id = SBP2_ROM_VALUE_WILDCARD, + .workarounds = SBP2_WORKAROUND_128K_MAX_TRANS, + }, +- /* +- * iPod 2nd generation: needs 128k max transfer size workaround +- * iPod 3rd generation: needs fix capacity workaround +- */ +- { +- .firmware_revision = 0x0a2700, +- .model = 0x000000, +- .workarounds = SBP2_WORKAROUND_128K_MAX_TRANS | +- SBP2_WORKAROUND_FIX_CAPACITY, +- }, + /* iPod 4th generation */ { + .firmware_revision = 0x0a2700, +- .model = 0x000021, ++ .model_id = 0x000021, + .workarounds = SBP2_WORKAROUND_FIX_CAPACITY, + }, + /* iPod mini */ { + .firmware_revision = 0x0a2700, +- .model = 0x000022, ++ .model_id = 0x000022, + .workarounds = SBP2_WORKAROUND_FIX_CAPACITY, + }, + /* iPod mini */ { + .firmware_revision = 0x0a2700, +- .model = 0x000023, ++ .model_id = 0x000023, + .workarounds = SBP2_WORKAROUND_FIX_CAPACITY, + }, + /* iPod Photo */ { + .firmware_revision = 0x0a2700, +- .model = 0x00007e, ++ .model_id = 0x00007e, + .workarounds = SBP2_WORKAROUND_FIX_CAPACITY, + } + }; +@@ -1351,15 +1341,13 @@ + struct csr1212_keyval *kv; + struct csr1212_dentry *dentry; + u64 management_agent_addr; +- u32 unit_characteristics, firmware_revision, model; ++ u32 unit_characteristics, firmware_revision; + unsigned workarounds; + int i; + + management_agent_addr = 0; + unit_characteristics = 0; +- firmware_revision = SBP2_ROM_VALUE_MISSING; +- model = ud->flags & UNIT_DIRECTORY_MODEL_ID ? +- ud->model_id : SBP2_ROM_VALUE_MISSING; ++ firmware_revision = 0; + + csr1212_for_each_dir_entry(ud->ne->csr, kv, ud->ud_kv, dentry) { + switch (kv->key.id) { +@@ -1400,9 +1388,9 @@ + sbp2_workarounds_table[i].firmware_revision != + (firmware_revision & 0xffff00)) + continue; +- if (sbp2_workarounds_table[i].model != ++ if (sbp2_workarounds_table[i].model_id != + SBP2_ROM_VALUE_WILDCARD && +- sbp2_workarounds_table[i].model != model) ++ sbp2_workarounds_table[i].model_id != ud->model_id) + continue; + workarounds |= sbp2_workarounds_table[i].workarounds; + break; +@@ -1415,7 +1403,7 @@ + NODE_BUS_ARGS(ud->ne->host, ud->ne->nodeid), + workarounds, firmware_revision, + ud->vendor_id ? ud->vendor_id : ud->ne->vendor_id, +- model); ++ ud->model_id); + + /* We would need one SCSI host template for each target to adjust + * max_sectors on the fly, therefore warn only. */ +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/drivers/infiniband/hw/nes/nes_cm.c linux-2.6.29-rc3.owrt/drivers/infiniband/hw/nes/nes_cm.c +--- linux-2.6.29.owrt/drivers/infiniband/hw/nes/nes_cm.c 2009-05-10 22:04:38.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/drivers/infiniband/hw/nes/nes_cm.c 2009-05-10 23:48:28.000000000 +0200 +@@ -2490,14 +2490,12 @@ + int ret = 0; + struct nes_vnic *nesvnic; + struct nes_device *nesdev; +- struct nes_ib_device *nesibdev; + + nesvnic = to_nesvnic(nesqp->ibqp.device); + if (!nesvnic) + return -EINVAL; + + nesdev = nesvnic->nesdev; +- nesibdev = nesvnic->nesibdev; + + nes_debug(NES_DBG_CM, "netdev refcnt = %u.\n", + atomic_read(&nesvnic->netdev->refcnt)); +@@ -2509,8 +2507,6 @@ + } else { + /* Need to free the Last Streaming Mode Message */ + if (nesqp->ietf_frame) { +- if (nesqp->lsmm_mr) +- nesibdev->ibdev.dereg_mr(nesqp->lsmm_mr); + pci_free_consistent(nesdev->pcidev, + nesqp->private_data_len+sizeof(struct ietf_mpa_frame), + nesqp->ietf_frame, nesqp->ietf_frame_pbase); +@@ -2547,12 +2543,6 @@ + u32 crc_value; + int ret; + int passive_state; +- struct nes_ib_device *nesibdev; +- struct ib_mr *ibmr = NULL; +- struct ib_phys_buf ibphysbuf; +- struct nes_pd *nespd; +- +- + + ibqp = nes_get_qp(cm_id->device, conn_param->qpn); + if (!ibqp) +@@ -2611,26 +2601,6 @@ + if (cm_id->remote_addr.sin_addr.s_addr != + cm_id->local_addr.sin_addr.s_addr) { + u64temp = (unsigned long)nesqp; +- nesibdev = nesvnic->nesibdev; +- nespd = nesqp->nespd; +- ibphysbuf.addr = nesqp->ietf_frame_pbase; +- ibphysbuf.size = conn_param->private_data_len + +- sizeof(struct ietf_mpa_frame); +- ibmr = nesibdev->ibdev.reg_phys_mr((struct ib_pd *)nespd, +- &ibphysbuf, 1, +- IB_ACCESS_LOCAL_WRITE, +- (u64 *)&nesqp->ietf_frame); +- if (!ibmr) { +- nes_debug(NES_DBG_CM, "Unable to register memory region" +- "for lSMM for cm_node = %p \n", +- cm_node); +- return -ENOMEM; +- } +- +- ibmr->pd = &nespd->ibpd; +- ibmr->device = nespd->ibpd.device; +- nesqp->lsmm_mr = ibmr; +- + u64temp |= NES_SW_CONTEXT_ALIGN>>1; + set_wqe_64bit_value(wqe->wqe_words, + NES_IWARP_SQ_WQE_COMP_CTX_LOW_IDX, +@@ -2641,13 +2611,14 @@ + wqe->wqe_words[NES_IWARP_SQ_WQE_TOTAL_PAYLOAD_IDX] = + cpu_to_le32(conn_param->private_data_len + + sizeof(struct ietf_mpa_frame)); +- set_wqe_64bit_value(wqe->wqe_words, +- NES_IWARP_SQ_WQE_FRAG0_LOW_IDX, +- (u64)nesqp->ietf_frame); ++ wqe->wqe_words[NES_IWARP_SQ_WQE_FRAG0_LOW_IDX] = ++ cpu_to_le32((u32)nesqp->ietf_frame_pbase); ++ wqe->wqe_words[NES_IWARP_SQ_WQE_FRAG0_HIGH_IDX] = ++ cpu_to_le32((u32)((u64)nesqp->ietf_frame_pbase >> 32)); + wqe->wqe_words[NES_IWARP_SQ_WQE_LENGTH0_IDX] = + cpu_to_le32(conn_param->private_data_len + + sizeof(struct ietf_mpa_frame)); +- wqe->wqe_words[NES_IWARP_SQ_WQE_STAG0_IDX] = ibmr->lkey; ++ wqe->wqe_words[NES_IWARP_SQ_WQE_STAG0_IDX] = 0; + + nesqp->nesqp_context->ird_ord_sizes |= + cpu_to_le32(NES_QPCONTEXT_ORDIRD_LSMM_PRESENT | +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/drivers/infiniband/hw/nes/nes_verbs.c linux-2.6.29-rc3.owrt/drivers/infiniband/hw/nes/nes_verbs.c +--- linux-2.6.29.owrt/drivers/infiniband/hw/nes/nes_verbs.c 2009-05-10 22:04:38.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/drivers/infiniband/hw/nes/nes_verbs.c 2009-05-10 23:48:28.000000000 +0200 +@@ -1360,10 +1360,8 @@ + NES_QPCONTEXT_MISC_RQ_SIZE_SHIFT); + nesqp->nesqp_context->misc |= cpu_to_le32((u32)nesqp->hwqp.sq_encoded_size << + NES_QPCONTEXT_MISC_SQ_SIZE_SHIFT); +- if (!udata) { + nesqp->nesqp_context->misc |= cpu_to_le32(NES_QPCONTEXT_MISC_PRIV_EN); + nesqp->nesqp_context->misc |= cpu_to_le32(NES_QPCONTEXT_MISC_FAST_REGISTER_EN); +- } + nesqp->nesqp_context->cqs = cpu_to_le32(nesqp->nesscq->hw_cq.cq_number + + ((u32)nesqp->nesrcq->hw_cq.cq_number << 16)); + u64temp = (u64)nesqp->hwqp.sq_pbase; +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/drivers/infiniband/hw/nes/nes_verbs.h linux-2.6.29-rc3.owrt/drivers/infiniband/hw/nes/nes_verbs.h +--- linux-2.6.29.owrt/drivers/infiniband/hw/nes/nes_verbs.h 2009-05-10 22:04:38.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/drivers/infiniband/hw/nes/nes_verbs.h 2009-05-10 23:48:28.000000000 +0200 +@@ -134,7 +134,6 @@ + struct ietf_mpa_frame *ietf_frame; + dma_addr_t ietf_frame_pbase; + wait_queue_head_t state_waitq; +- struct ib_mr *lsmm_mr; + unsigned long socket; + struct nes_hw_qp hwqp; + struct work_struct work; +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/drivers/input/keyboard/atkbd.c linux-2.6.29-rc3.owrt/drivers/input/keyboard/atkbd.c +--- linux-2.6.29.owrt/drivers/input/keyboard/atkbd.c 2009-05-10 22:04:39.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/drivers/input/keyboard/atkbd.c 2009-05-10 23:48:28.000000000 +0200 +@@ -839,7 +839,7 @@ + */ + static void atkbd_dell_laptop_keymap_fixup(struct atkbd *atkbd) + { +- static const unsigned int forced_release_keys[] = { ++ const unsigned int forced_release_keys[] = { + 0x85, 0x86, 0x87, 0x88, 0x89, 0x8a, 0x8b, 0x8f, 0x93, + }; + int i; +@@ -856,7 +856,7 @@ + */ + static void atkbd_hp_keymap_fixup(struct atkbd *atkbd) + { +- static const unsigned int forced_release_keys[] = { ++ const unsigned int forced_release_keys[] = { + 0x94, + }; + int i; +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/drivers/input/keyboard/bf54x-keys.c linux-2.6.29-rc3.owrt/drivers/input/keyboard/bf54x-keys.c +--- linux-2.6.29.owrt/drivers/input/keyboard/bf54x-keys.c 2009-05-10 22:04:39.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/drivers/input/keyboard/bf54x-keys.c 2009-05-10 23:48:28.000000000 +0200 +@@ -209,8 +209,8 @@ + goto out; + } + +- if (!pdata->debounce_time || pdata->debounce_time > MAX_MULT || +- !pdata->coldrive_time || pdata->coldrive_time > MAX_MULT) { ++ if (!pdata->debounce_time || !pdata->debounce_time > MAX_MULT || ++ !pdata->coldrive_time || !pdata->coldrive_time > MAX_MULT) { + printk(KERN_ERR DRV_NAME + ": Invalid Debounce/Columdrive Time from pdata\n"); + bfin_write_KPAD_MSEL(0xFF0); /* Default MSEL */ +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/drivers/input/keyboard/corgikbd.c linux-2.6.29-rc3.owrt/drivers/input/keyboard/corgikbd.c +--- linux-2.6.29.owrt/drivers/input/keyboard/corgikbd.c 2009-05-10 22:04:39.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/drivers/input/keyboard/corgikbd.c 2009-05-10 23:48:28.000000000 +0200 +@@ -288,7 +288,7 @@ + #define corgikbd_resume NULL + #endif + +-static int __devinit corgikbd_probe(struct platform_device *pdev) ++static int __init corgikbd_probe(struct platform_device *pdev) + { + struct corgikbd *corgikbd; + struct input_dev *input_dev; +@@ -368,7 +368,7 @@ + return err; + } + +-static int __devexit corgikbd_remove(struct platform_device *pdev) ++static int corgikbd_remove(struct platform_device *pdev) + { + int i; + struct corgikbd *corgikbd = platform_get_drvdata(pdev); +@@ -388,7 +388,7 @@ + + static struct platform_driver corgikbd_driver = { + .probe = corgikbd_probe, +- .remove = __devexit_p(corgikbd_remove), ++ .remove = corgikbd_remove, + .suspend = corgikbd_suspend, + .resume = corgikbd_resume, + .driver = { +@@ -397,7 +397,7 @@ + }, + }; + +-static int __init corgikbd_init(void) ++static int __devinit corgikbd_init(void) + { + return platform_driver_register(&corgikbd_driver); + } +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/drivers/input/keyboard/omap-keypad.c linux-2.6.29-rc3.owrt/drivers/input/keyboard/omap-keypad.c +--- linux-2.6.29.owrt/drivers/input/keyboard/omap-keypad.c 2009-05-10 22:04:39.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/drivers/input/keyboard/omap-keypad.c 2009-05-10 23:48:28.000000000 +0200 +@@ -279,7 +279,7 @@ + #define omap_kp_resume NULL + #endif + +-static int __devinit omap_kp_probe(struct platform_device *pdev) ++static int __init omap_kp_probe(struct platform_device *pdev) + { + struct omap_kp *omap_kp; + struct input_dev *input_dev; +@@ -422,7 +422,7 @@ + return -EINVAL; + } + +-static int __devexit omap_kp_remove(struct platform_device *pdev) ++static int omap_kp_remove(struct platform_device *pdev) + { + struct omap_kp *omap_kp = platform_get_drvdata(pdev); + +@@ -454,7 +454,7 @@ + + static struct platform_driver omap_kp_driver = { + .probe = omap_kp_probe, +- .remove = __devexit_p(omap_kp_remove), ++ .remove = omap_kp_remove, + .suspend = omap_kp_suspend, + .resume = omap_kp_resume, + .driver = { +@@ -463,7 +463,7 @@ + }, + }; + +-static int __init omap_kp_init(void) ++static int __devinit omap_kp_init(void) + { + printk(KERN_INFO "OMAP Keypad Driver\n"); + return platform_driver_register(&omap_kp_driver); +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/drivers/input/keyboard/spitzkbd.c linux-2.6.29-rc3.owrt/drivers/input/keyboard/spitzkbd.c +--- linux-2.6.29.owrt/drivers/input/keyboard/spitzkbd.c 2009-05-10 22:04:39.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/drivers/input/keyboard/spitzkbd.c 2009-05-10 23:48:28.000000000 +0200 +@@ -343,7 +343,7 @@ + #define spitzkbd_resume NULL + #endif + +-static int __devinit spitzkbd_probe(struct platform_device *dev) ++static int __init spitzkbd_probe(struct platform_device *dev) + { + struct spitzkbd *spitzkbd; + struct input_dev *input_dev; +@@ -444,7 +444,7 @@ + return err; + } + +-static int __devexit spitzkbd_remove(struct platform_device *dev) ++static int spitzkbd_remove(struct platform_device *dev) + { + int i; + struct spitzkbd *spitzkbd = platform_get_drvdata(dev); +@@ -470,7 +470,7 @@ + + static struct platform_driver spitzkbd_driver = { + .probe = spitzkbd_probe, +- .remove = __devexit_p(spitzkbd_remove), ++ .remove = spitzkbd_remove, + .suspend = spitzkbd_suspend, + .resume = spitzkbd_resume, + .driver = { +@@ -479,7 +479,7 @@ + }, + }; + +-static int __init spitzkbd_init(void) ++static int __devinit spitzkbd_init(void) + { + return platform_driver_register(&spitzkbd_driver); + } +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/drivers/input/mouse/elantech.c linux-2.6.29-rc3.owrt/drivers/input/mouse/elantech.c +--- linux-2.6.29.owrt/drivers/input/mouse/elantech.c 2009-05-10 22:04:39.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/drivers/input/mouse/elantech.c 2009-05-10 23:48:28.000000000 +0200 +@@ -542,7 +542,7 @@ + ps2_command(ps2dev, NULL, PSMOUSE_CMD_SETSCALE11) || + ps2_command(ps2dev, NULL, PSMOUSE_CMD_SETSCALE11) || + ps2_command(ps2dev, param, PSMOUSE_CMD_GETINFO)) { +- pr_debug("elantech.c: sending Elantech magic knock failed.\n"); ++ pr_err("elantech.c: sending Elantech magic knock failed.\n"); + return -1; + } + +@@ -551,27 +551,8 @@ + * set of magic numbers + */ + if (param[0] != 0x3c || param[1] != 0x03 || param[2] != 0xc8) { +- pr_debug("elantech.c: " +- "unexpected magic knock result 0x%02x, 0x%02x, 0x%02x.\n", +- param[0], param[1], param[2]); +- return -1; +- } +- +- /* +- * Query touchpad's firmware version and see if it reports known +- * value to avoid mis-detection. Logitech mice are known to respond +- * to Elantech magic knock and there might be more. +- */ +- if (synaptics_send_cmd(psmouse, ETP_FW_VERSION_QUERY, param)) { +- pr_debug("elantech.c: failed to query firmware version.\n"); +- return -1; +- } +- +- pr_debug("elantech.c: Elantech version query result 0x%02x, 0x%02x, 0x%02x.\n", +- param[0], param[1], param[2]); +- +- if (param[0] == 0 || param[1] != 0) { +- pr_debug("elantech.c: Probably not a real Elantech touchpad. Aborting.\n"); ++ pr_info("elantech.c: unexpected magic knock result 0x%02x, 0x%02x, 0x%02x.\n", ++ param[0], param[1], param[2]); + return -1; + } + +@@ -619,7 +600,8 @@ + int i, error; + unsigned char param[3]; + +- psmouse->private = etd = kzalloc(sizeof(struct elantech_data), GFP_KERNEL); ++ etd = kzalloc(sizeof(struct elantech_data), GFP_KERNEL); ++ psmouse->private = etd; + if (!etd) + return -1; + +@@ -628,12 +610,14 @@ + etd->parity[i] = etd->parity[i & (i - 1)] ^ 1; + + /* +- * Do the version query again so we can store the result ++ * Find out what version hardware this is + */ + if (synaptics_send_cmd(psmouse, ETP_FW_VERSION_QUERY, param)) { + pr_err("elantech.c: failed to query firmware version.\n"); + goto init_fail; + } ++ pr_info("elantech.c: Elantech version query result 0x%02x, 0x%02x, 0x%02x.\n", ++ param[0], param[1], param[2]); + etd->fw_version_maj = param[0]; + etd->fw_version_min = param[2]; + +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/drivers/input/mouse/Kconfig linux-2.6.29-rc3.owrt/drivers/input/mouse/Kconfig +--- linux-2.6.29.owrt/drivers/input/mouse/Kconfig 2009-05-10 22:04:39.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/drivers/input/mouse/Kconfig 2009-05-10 23:48:28.000000000 +0200 +@@ -70,7 +70,7 @@ + config MOUSE_PS2_LIFEBOOK + bool "Fujitsu Lifebook PS/2 mouse protocol extension" if EMBEDDED + default y +- depends on MOUSE_PS2 && X86 ++ depends on MOUSE_PS2 + help + Say Y here if you have a Fujitsu B-series Lifebook PS/2 + TouchScreen connected to your system. +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/drivers/input/mouse/pxa930_trkball.c linux-2.6.29-rc3.owrt/drivers/input/mouse/pxa930_trkball.c +--- linux-2.6.29.owrt/drivers/input/mouse/pxa930_trkball.c 2009-05-10 22:04:39.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/drivers/input/mouse/pxa930_trkball.c 2009-05-10 23:48:28.000000000 +0200 +@@ -83,7 +83,7 @@ + + __raw_writel(v, trkball->mmio_base + TBCR); + +- while (--i) { ++ while (i--) { + if (__raw_readl(trkball->mmio_base + TBCR) == v) + break; + msleep(1); +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/drivers/input/mouse/synaptics.c linux-2.6.29-rc3.owrt/drivers/input/mouse/synaptics.c +--- linux-2.6.29.owrt/drivers/input/mouse/synaptics.c 2009-05-10 22:04:39.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/drivers/input/mouse/synaptics.c 2009-05-10 23:48:28.000000000 +0200 +@@ -182,6 +182,11 @@ + + static int synaptics_query_hardware(struct psmouse *psmouse) + { ++ int retries = 0; ++ ++ while ((retries++ < 3) && psmouse_reset(psmouse)) ++ /* empty */; ++ + if (synaptics_identify(psmouse)) + return -1; + if (synaptics_model_id(psmouse)) +@@ -577,8 +582,6 @@ + struct synaptics_data *priv = psmouse->private; + struct synaptics_data old_priv = *priv; + +- psmouse_reset(psmouse); +- + if (synaptics_detect(psmouse, 0)) + return -1; + +@@ -637,8 +640,6 @@ + if (!priv) + return -1; + +- psmouse_reset(psmouse); +- + if (synaptics_query_hardware(psmouse)) { + printk(KERN_ERR "Unable to query Synaptics hardware.\n"); + goto init_fail; +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/drivers/input/serio/ambakmi.c linux-2.6.29-rc3.owrt/drivers/input/serio/ambakmi.c +--- linux-2.6.29.owrt/drivers/input/serio/ambakmi.c 2009-05-10 22:04:39.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/drivers/input/serio/ambakmi.c 2009-05-10 23:48:28.000000000 +0200 +@@ -57,7 +57,7 @@ + struct amba_kmi_port *kmi = io->port_data; + unsigned int timeleft = 10000; /* timeout in 100ms */ + +- while ((readb(KMISTAT) & KMISTAT_TXEMPTY) == 0 && --timeleft) ++ while ((readb(KMISTAT) & KMISTAT_TXEMPTY) == 0 && timeleft--) + udelay(10); + + if (timeleft) +@@ -129,8 +129,8 @@ + io->write = amba_kmi_write; + io->open = amba_kmi_open; + io->close = amba_kmi_close; +- strlcpy(io->name, dev_name(&dev->dev), sizeof(io->name)); +- strlcpy(io->phys, dev_name(&dev->dev), sizeof(io->phys)); ++ strlcpy(io->name, dev->dev.bus_id, sizeof(io->name)); ++ strlcpy(io->phys, dev->dev.bus_id, sizeof(io->phys)); + io->port_data = kmi; + io->dev.parent = &dev->dev; + +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/drivers/input/serio/gscps2.c linux-2.6.29-rc3.owrt/drivers/input/serio/gscps2.c +--- linux-2.6.29.owrt/drivers/input/serio/gscps2.c 2009-05-10 22:04:39.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/drivers/input/serio/gscps2.c 2009-05-10 23:48:28.000000000 +0200 +@@ -359,7 +359,7 @@ + + snprintf(serio->name, sizeof(serio->name), "GSC PS/2 %s", + (ps2port->id == GSC_ID_KEYBOARD) ? "keyboard" : "mouse"); +- strlcpy(serio->phys, dev_name(&dev->dev), sizeof(serio->phys)); ++ strlcpy(serio->phys, dev->dev.bus_id, sizeof(serio->phys)); + serio->id.type = SERIO_8042; + serio->write = gscps2_write; + serio->open = gscps2_open; +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/drivers/input/serio/sa1111ps2.c linux-2.6.29-rc3.owrt/drivers/input/serio/sa1111ps2.c +--- linux-2.6.29.owrt/drivers/input/serio/sa1111ps2.c 2009-05-10 22:04:39.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/drivers/input/serio/sa1111ps2.c 2009-05-10 23:48:28.000000000 +0200 +@@ -246,8 +246,8 @@ + serio->write = ps2_write; + serio->open = ps2_open; + serio->close = ps2_close; +- strlcpy(serio->name, dev_name(&dev->dev), sizeof(serio->name)); +- strlcpy(serio->phys, dev_name(&dev->dev), sizeof(serio->phys)); ++ strlcpy(serio->name, dev->dev.bus_id, sizeof(serio->name)); ++ strlcpy(serio->phys, dev->dev.bus_id, sizeof(serio->phys)); + serio->port_data = ps2if; + serio->dev.parent = &dev->dev; + ps2if->io = serio; +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/drivers/input/touchscreen/atmel_tsadcc.c linux-2.6.29-rc3.owrt/drivers/input/touchscreen/atmel_tsadcc.c +--- linux-2.6.29.owrt/drivers/input/touchscreen/atmel_tsadcc.c 2009-05-10 22:04:39.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/drivers/input/touchscreen/atmel_tsadcc.c 2009-05-10 23:48:28.000000000 +0200 +@@ -236,7 +236,7 @@ + ts_dev->bufferedmeasure = 0; + + snprintf(ts_dev->phys, sizeof(ts_dev->phys), +- "%s/input0", dev_name(&pdev->dev)); ++ "%s/input0", pdev->dev.bus_id); + + input_dev->name = "atmel touch screen controller"; + input_dev->phys = ts_dev->phys; +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/drivers/input/touchscreen/corgi_ts.c linux-2.6.29-rc3.owrt/drivers/input/touchscreen/corgi_ts.c +--- linux-2.6.29.owrt/drivers/input/touchscreen/corgi_ts.c 2009-05-10 22:04:39.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/drivers/input/touchscreen/corgi_ts.c 2009-05-10 23:48:28.000000000 +0200 +@@ -268,7 +268,7 @@ + #define corgits_resume NULL + #endif + +-static int __devinit corgits_probe(struct platform_device *pdev) ++static int __init corgits_probe(struct platform_device *pdev) + { + struct corgi_ts *corgi_ts; + struct input_dev *input_dev; +@@ -343,7 +343,7 @@ + return err; + } + +-static int __devexit corgits_remove(struct platform_device *pdev) ++static int corgits_remove(struct platform_device *pdev) + { + struct corgi_ts *corgi_ts = platform_get_drvdata(pdev); + +@@ -352,13 +352,12 @@ + corgi_ts->machinfo->put_hsync(); + input_unregister_device(corgi_ts->input); + kfree(corgi_ts); +- + return 0; + } + + static struct platform_driver corgits_driver = { + .probe = corgits_probe, +- .remove = __devexit_p(corgits_remove), ++ .remove = corgits_remove, + .suspend = corgits_suspend, + .resume = corgits_resume, + .driver = { +@@ -367,7 +366,7 @@ + }, + }; + +-static int __init corgits_init(void) ++static int __devinit corgits_init(void) + { + return platform_driver_register(&corgits_driver); + } +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/drivers/input/touchscreen/tsc2007.c linux-2.6.29-rc3.owrt/drivers/input/touchscreen/tsc2007.c +--- linux-2.6.29.owrt/drivers/input/touchscreen/tsc2007.c 2009-05-10 22:04:39.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/drivers/input/touchscreen/tsc2007.c 2009-05-10 23:48:28.000000000 +0200 +@@ -289,8 +289,7 @@ + + pdata->init_platform_hw(); + +- snprintf(ts->phys, sizeof(ts->phys), +- "%s/input0", dev_name(&client->dev)); ++ snprintf(ts->phys, sizeof(ts->phys), "%s/input0", client->dev.bus_id); + + input_dev->name = "TSC2007 Touchscreen"; + input_dev->phys = ts->phys; +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/drivers/input/touchscreen/usbtouchscreen.c linux-2.6.29-rc3.owrt/drivers/input/touchscreen/usbtouchscreen.c +--- linux-2.6.29.owrt/drivers/input/touchscreen/usbtouchscreen.c 2009-05-10 22:04:39.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/drivers/input/touchscreen/usbtouchscreen.c 2009-05-10 23:48:28.000000000 +0200 +@@ -60,10 +60,6 @@ + module_param(swap_xy, bool, 0644); + MODULE_PARM_DESC(swap_xy, "If set X and Y axes are swapped."); + +-static int hwcalib_xy; +-module_param(hwcalib_xy, bool, 0644); +-MODULE_PARM_DESC(hwcalib_xy, "If set hw-calibrated X/Y are used if available"); +- + /* device specifc data/functions */ + struct usbtouch_usb; + struct usbtouch_device_info { +@@ -122,7 +118,6 @@ + + #define USB_DEVICE_HID_CLASS(vend, prod) \ + .match_flags = USB_DEVICE_ID_MATCH_INT_CLASS \ +- | USB_DEVICE_ID_MATCH_INT_PROTOCOL \ + | USB_DEVICE_ID_MATCH_DEVICE, \ + .idVendor = (vend), \ + .idProduct = (prod), \ +@@ -265,13 +260,8 @@ + + static int mtouch_read_data(struct usbtouch_usb *dev, unsigned char *pkt) + { +- if (hwcalib_xy) { +- dev->x = (pkt[4] << 8) | pkt[3]; +- dev->y = 0xffff - ((pkt[6] << 8) | pkt[5]); +- } else { +- dev->x = (pkt[8] << 8) | pkt[7]; +- dev->y = (pkt[10] << 8) | pkt[9]; +- } ++ dev->x = (pkt[8] << 8) | pkt[7]; ++ dev->y = (pkt[10] << 8) | pkt[9]; + dev->touch = (pkt[2] & 0x40) ? 1 : 0; + + return 1; +@@ -304,12 +294,6 @@ + return ret; + } + +- /* Default min/max xy are the raw values, override if using hw-calib */ +- if (hwcalib_xy) { +- input_set_abs_params(usbtouch->input, ABS_X, 0, 0xffff, 0, 0); +- input_set_abs_params(usbtouch->input, ABS_Y, 0, 0xffff, 0, 0); +- } +- + return 0; + } + #endif +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/drivers/isdn/gigaset/bas-gigaset.c linux-2.6.29-rc3.owrt/drivers/isdn/gigaset/bas-gigaset.c +--- linux-2.6.29.owrt/drivers/isdn/gigaset/bas-gigaset.c 2009-05-10 22:04:38.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/drivers/isdn/gigaset/bas-gigaset.c 2009-05-10 23:48:28.000000000 +0200 +@@ -46,9 +46,6 @@ + /* length limit according to Siemens 3070usb-protokoll.doc ch. 2.1 */ + #define IF_WRITEBUF 264 + +-/* interrupt pipe message size according to ibid. ch. 2.2 */ +-#define IP_MSGSIZE 3 +- + /* Values for the Gigaset 307x */ + #define USB_GIGA_VENDOR_ID 0x0681 + #define USB_3070_PRODUCT_ID 0x0001 +@@ -113,7 +110,7 @@ + unsigned char *rcvbuf; /* AT reply receive buffer */ + + struct urb *urb_int_in; /* URB for interrupt pipe */ +- unsigned char *int_in_buf; ++ unsigned char int_in_buf[3]; + + spinlock_t lock; /* locks all following */ + int basstate; /* bitmap (BS_*) */ +@@ -660,7 +657,7 @@ + } + + /* drop incomplete packets even if the missing bytes wouldn't matter */ +- if (unlikely(urb->actual_length < IP_MSGSIZE)) { ++ if (unlikely(urb->actual_length < 3)) { + dev_warn(cs->dev, "incomplete interrupt packet (%d bytes)\n", + urb->actual_length); + goto resubmit; +@@ -2130,7 +2127,6 @@ + static void gigaset_freecshw(struct cardstate *cs) + { + /* timers, URBs and rcvbuf are disposed of in disconnect */ +- kfree(cs->hw.bas->int_in_buf); + kfree(cs->hw.bas); + cs->hw.bas = NULL; + } +@@ -2144,12 +2140,6 @@ + pr_err("out of memory\n"); + return 0; + } +- ucs->int_in_buf = kmalloc(IP_MSGSIZE, GFP_KERNEL); +- if (!ucs->int_in_buf) { +- kfree(ucs); +- pr_err("out of memory\n"); +- return 0; +- } + + ucs->urb_cmd_in = NULL; + ucs->urb_cmd_out = NULL; +@@ -2302,7 +2292,7 @@ + usb_fill_int_urb(ucs->urb_int_in, udev, + usb_rcvintpipe(udev, + (endpoint->bEndpointAddress) & 0x0f), +- ucs->int_in_buf, IP_MSGSIZE, read_int_callback, cs, ++ ucs->int_in_buf, 3, read_int_callback, cs, + endpoint->bInterval); + if ((rc = usb_submit_urb(ucs->urb_int_in, GFP_KERNEL)) != 0) { + dev_err(cs->dev, "could not submit interrupt URB: %s\n", +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/drivers/isdn/hardware/mISDN/hfcmulti.c linux-2.6.29-rc3.owrt/drivers/isdn/hardware/mISDN/hfcmulti.c +--- linux-2.6.29.owrt/drivers/isdn/hardware/mISDN/hfcmulti.c 2009-05-10 22:04:38.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/drivers/isdn/hardware/mISDN/hfcmulti.c 2009-05-10 23:48:28.000000000 +0200 +@@ -4599,7 +4599,6 @@ + printk(KERN_ERR "%s: no memory for coeffs\n", + __func__); + ret = -ENOMEM; +- kfree(bch); + goto free_chan; + } + bch->nr = ch; +@@ -4768,7 +4767,6 @@ + printk(KERN_ERR "%s: no memory for coeffs\n", + __func__); + ret = -ENOMEM; +- kfree(bch); + goto free_chan; + } + bch->nr = ch + 1; +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/drivers/isdn/sc/shmem.c linux-2.6.29-rc3.owrt/drivers/isdn/sc/shmem.c +--- linux-2.6.29.owrt/drivers/isdn/sc/shmem.c 2009-05-10 22:04:38.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/drivers/isdn/sc/shmem.c 2009-05-10 23:48:28.000000000 +0200 +@@ -54,7 +54,7 @@ + spin_unlock_irqrestore(&sc_adapter[card]->lock, flags); + pr_debug("%s: set page to %#x\n",sc_adapter[card]->devicename, + ((sc_adapter[card]->shmem_magic + ch * SRAM_PAGESIZE)>>14)|0x80); +- pr_debug("%s: copying %zu bytes from %#lx to %#lx\n", ++ pr_debug("%s: copying %d bytes from %#lx to %#lx\n", + sc_adapter[card]->devicename, n, + (unsigned long) src, + sc_adapter[card]->rambase + ((unsigned long) dest %0x4000)); +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/drivers/lguest/core.c linux-2.6.29-rc3.owrt/drivers/lguest/core.c +--- linux-2.6.29.owrt/drivers/lguest/core.c 2009-05-10 22:04:38.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/drivers/lguest/core.c 2009-05-10 23:48:28.000000000 +0200 +@@ -224,7 +224,7 @@ + break; + + /* If the Guest asked to be stopped, we sleep. The Guest's +- * clock timer or LHREQ_BREAK from the Waker will wake us. */ ++ * clock timer or LHCALL_BREAK from the Waker will wake us. */ + if (cpu->halted) { + set_current_state(TASK_INTERRUPTIBLE); + schedule(); +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/drivers/lguest/lguest_device.c linux-2.6.29-rc3.owrt/drivers/lguest/lguest_device.c +--- linux-2.6.29.owrt/drivers/lguest/lguest_device.c 2009-05-10 22:04:38.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/drivers/lguest/lguest_device.c 2009-05-10 23:48:28.000000000 +0200 +@@ -212,9 +212,6 @@ + hcall(LHCALL_NOTIFY, lvq->config.pfn << PAGE_SHIFT, 0, 0); + } + +-/* An extern declaration inside a C file is bad form. Don't do it. */ +-extern void lguest_setup_irq(unsigned int irq); +- + /* This routine finds the first virtqueue described in the configuration of + * this device and sets it up. + * +@@ -269,9 +266,6 @@ + goto unmap; + } + +- /* Make sure the interrupt is allocated. */ +- lguest_setup_irq(lvq->config.irq); +- + /* Tell the interrupt for this virtqueue to go to the virtio_ring + * interrupt handler. */ + /* FIXME: We used to have a flag for the Host to tell us we could use +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/drivers/lguest/lguest_user.c linux-2.6.29-rc3.owrt/drivers/lguest/lguest_user.c +--- linux-2.6.29.owrt/drivers/lguest/lguest_user.c 2009-05-10 22:04:38.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/drivers/lguest/lguest_user.c 2009-05-10 23:48:28.000000000 +0200 +@@ -307,8 +307,9 @@ + * kmalloc()ed string, either of which is ok to hand to kfree(). */ + if (!IS_ERR(lg->dead)) + kfree(lg->dead); +- /* Free the memory allocated to the lguest_struct */ +- kfree(lg); ++ /* We clear the entire structure, which also marks it as free for the ++ * next user. */ ++ memset(lg, 0, sizeof(*lg)); + /* Release lock and exit. */ + mutex_unlock(&lguest_lock); + +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/drivers/md/dm.c linux-2.6.29-rc3.owrt/drivers/md/dm.c +--- linux-2.6.29.owrt/drivers/md/dm.c 2009-05-10 22:04:38.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/drivers/md/dm.c 2009-05-10 23:48:28.000000000 +0200 +@@ -525,12 +525,9 @@ + static void dec_pending(struct dm_io *io, int error) + { + unsigned long flags; +- int io_error; +- struct bio *bio; +- struct mapped_device *md = io->md; + + /* Push-back supersedes any I/O errors */ +- if (error && !(io->error > 0 && __noflush_suspending(md))) ++ if (error && !(io->error > 0 && __noflush_suspending(io->md))) + io->error = error; + + if (atomic_dec_and_test(&io->io_count)) { +@@ -540,27 +537,24 @@ + * This must be handled before the sleeper on + * suspend queue merges the pushback list. + */ +- spin_lock_irqsave(&md->pushback_lock, flags); +- if (__noflush_suspending(md)) +- bio_list_add(&md->pushback, io->bio); ++ spin_lock_irqsave(&io->md->pushback_lock, flags); ++ if (__noflush_suspending(io->md)) ++ bio_list_add(&io->md->pushback, io->bio); + else + /* noflush suspend was interrupted. */ + io->error = -EIO; +- spin_unlock_irqrestore(&md->pushback_lock, flags); ++ spin_unlock_irqrestore(&io->md->pushback_lock, flags); + } + + end_io_acct(io); + +- io_error = io->error; +- bio = io->bio; +- +- free_io(md, io); ++ if (io->error != DM_ENDIO_REQUEUE) { ++ trace_block_bio_complete(io->md->queue, io->bio); + +- if (io_error != DM_ENDIO_REQUEUE) { +- trace_block_bio_complete(md->queue, bio); +- +- bio_endio(bio, io_error); ++ bio_endio(io->bio, io->error); + } ++ ++ free_io(io->md, io); + } + } + +@@ -568,7 +562,6 @@ + { + int r = 0; + struct dm_target_io *tio = bio->bi_private; +- struct dm_io *io = tio->io; + struct mapped_device *md = tio->io->md; + dm_endio_fn endio = tio->ti->type->end_io; + +@@ -592,14 +585,15 @@ + } + } + ++ dec_pending(tio->io, error); ++ + /* + * Store md for cleanup instead of tio which is about to get freed. + */ + bio->bi_private = md->bs; + +- free_tio(md, tio); + bio_put(bio); +- dec_pending(io, error); ++ free_tio(md, tio); + } + + static sector_t max_io_len(struct mapped_device *md, +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/drivers/md/dm-crypt.c linux-2.6.29-rc3.owrt/drivers/md/dm-crypt.c +--- linux-2.6.29.owrt/drivers/md/dm-crypt.c 2009-05-10 22:04:38.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/drivers/md/dm-crypt.c 2009-05-10 23:48:28.000000000 +0200 +@@ -60,7 +60,6 @@ + }; + + struct dm_crypt_request { +- struct convert_context *ctx; + struct scatterlist sg_in; + struct scatterlist sg_out; + }; +@@ -336,18 +335,6 @@ + init_completion(&ctx->restart); + } + +-static struct dm_crypt_request *dmreq_of_req(struct crypt_config *cc, +- struct ablkcipher_request *req) +-{ +- return (struct dm_crypt_request *)((char *)req + cc->dmreq_start); +-} +- +-static struct ablkcipher_request *req_of_dmreq(struct crypt_config *cc, +- struct dm_crypt_request *dmreq) +-{ +- return (struct ablkcipher_request *)((char *)dmreq - cc->dmreq_start); +-} +- + static int crypt_convert_block(struct crypt_config *cc, + struct convert_context *ctx, + struct ablkcipher_request *req) +@@ -358,11 +345,10 @@ + u8 *iv; + int r = 0; + +- dmreq = dmreq_of_req(cc, req); ++ dmreq = (struct dm_crypt_request *)((char *)req + cc->dmreq_start); + iv = (u8 *)ALIGN((unsigned long)(dmreq + 1), + crypto_ablkcipher_alignmask(cc->tfm) + 1); + +- dmreq->ctx = ctx; + sg_init_table(&dmreq->sg_in, 1); + sg_set_page(&dmreq->sg_in, bv_in->bv_page, 1 << SECTOR_SHIFT, + bv_in->bv_offset + ctx->offset_in); +@@ -409,9 +395,8 @@ + cc->req = mempool_alloc(cc->req_pool, GFP_NOIO); + ablkcipher_request_set_tfm(cc->req, cc->tfm); + ablkcipher_request_set_callback(cc->req, CRYPTO_TFM_REQ_MAY_BACKLOG | +- CRYPTO_TFM_REQ_MAY_SLEEP, +- kcryptd_async_done, +- dmreq_of_req(cc, cc->req)); ++ CRYPTO_TFM_REQ_MAY_SLEEP, ++ kcryptd_async_done, ctx); + } + + /* +@@ -568,22 +553,19 @@ + static void crypt_dec_pending(struct dm_crypt_io *io) + { + struct crypt_config *cc = io->target->private; +- struct bio *base_bio = io->base_bio; +- struct dm_crypt_io *base_io = io->base_io; +- int error = io->error; + + if (!atomic_dec_and_test(&io->pending)) + return; + +- mempool_free(io, cc->io_pool); +- +- if (likely(!base_io)) +- bio_endio(base_bio, error); ++ if (likely(!io->base_io)) ++ bio_endio(io->base_bio, io->error); + else { +- if (error && !base_io->error) +- base_io->error = error; +- crypt_dec_pending(base_io); ++ if (io->error && !io->base_io->error) ++ io->base_io->error = io->error; ++ crypt_dec_pending(io->base_io); + } ++ ++ mempool_free(io, cc->io_pool); + } + + /* +@@ -839,8 +821,7 @@ + static void kcryptd_async_done(struct crypto_async_request *async_req, + int error) + { +- struct dm_crypt_request *dmreq = async_req->data; +- struct convert_context *ctx = dmreq->ctx; ++ struct convert_context *ctx = async_req->data; + struct dm_crypt_io *io = container_of(ctx, struct dm_crypt_io, ctx); + struct crypt_config *cc = io->target->private; + +@@ -849,7 +830,7 @@ + return; + } + +- mempool_free(req_of_dmreq(cc, dmreq), cc->req_pool); ++ mempool_free(ablkcipher_request_cast(async_req), cc->req_pool); + + if (!atomic_dec_and_test(&ctx->pending)) + return; +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/drivers/md/dm-io.c linux-2.6.29-rc3.owrt/drivers/md/dm-io.c +--- linux-2.6.29.owrt/drivers/md/dm-io.c 2009-05-10 22:04:38.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/drivers/md/dm-io.c 2009-05-10 23:48:28.000000000 +0200 +@@ -292,8 +292,6 @@ + (PAGE_SIZE >> SECTOR_SHIFT)); + num_bvecs = 1 + min_t(int, bio_get_nr_vecs(where->bdev), + num_bvecs); +- if (unlikely(num_bvecs > BIO_MAX_PAGES)) +- num_bvecs = BIO_MAX_PAGES; + bio = bio_alloc_bioset(GFP_NOIO, num_bvecs, io->client->bios); + bio->bi_sector = where->sector + (where->count - remaining); + bio->bi_bdev = where->bdev; +@@ -330,7 +328,7 @@ + struct dpages old_pages = *dp; + + if (sync) +- rw |= (1 << BIO_RW_SYNCIO) | (1 << BIO_RW_UNPLUG); ++ rw |= (1 << BIO_RW_SYNC); + + /* + * For multiple regions we need to be careful to rewind +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/drivers/md/dm-ioctl.c linux-2.6.29-rc3.owrt/drivers/md/dm-ioctl.c +--- linux-2.6.29.owrt/drivers/md/dm-ioctl.c 2009-05-10 22:04:38.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/drivers/md/dm-ioctl.c 2009-05-10 23:48:28.000000000 +0200 +@@ -704,8 +704,7 @@ + char *new_name = (char *) param + param->data_start; + + if (new_name < param->data || +- invalid_str(new_name, (void *) param + param_size) || +- strlen(new_name) > DM_NAME_LEN - 1) { ++ invalid_str(new_name, (void *) param + param_size)) { + DMWARN("Invalid new logical volume name supplied."); + return -EINVAL; + } +@@ -1064,7 +1063,7 @@ + + r = populate_table(t, param, param_size); + if (r) { +- dm_table_destroy(t); ++ dm_table_put(t); + goto out; + } + +@@ -1072,7 +1071,7 @@ + hc = dm_get_mdptr(md); + if (!hc || hc->md != md) { + DMWARN("device has been removed from the dev hash table."); +- dm_table_destroy(t); ++ dm_table_put(t); + up_write(&_hash_lock); + r = -ENXIO; + goto out; +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/drivers/md/dm-kcopyd.c linux-2.6.29-rc3.owrt/drivers/md/dm-kcopyd.c +--- linux-2.6.29.owrt/drivers/md/dm-kcopyd.c 2009-05-10 22:04:38.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/drivers/md/dm-kcopyd.c 2009-05-10 23:48:28.000000000 +0200 +@@ -344,7 +344,7 @@ + { + int r; + struct dm_io_request io_req = { +- .bi_rw = job->rw | (1 << BIO_RW_SYNCIO) | (1 << BIO_RW_UNPLUG), ++ .bi_rw = job->rw | (1 << BIO_RW_SYNC), + .mem.type = DM_IO_PAGE_LIST, + .mem.ptr.pl = job->pages, + .mem.offset = job->offset, +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/drivers/md/linear.c linux-2.6.29-rc3.owrt/drivers/md/linear.c +--- linux-2.6.29.owrt/drivers/md/linear.c 2009-05-10 22:04:38.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/drivers/md/linear.c 2009-05-10 23:48:28.000000000 +0200 +@@ -25,13 +25,13 @@ + { + dev_info_t *hash; + linear_conf_t *conf = mddev_to_conf(mddev); +- sector_t idx = sector >> conf->sector_shift; + + /* + * sector_div(a,b) returns the remainer and sets a to a/b + */ +- (void)sector_div(idx, conf->spacing); +- hash = conf->hash_table[idx]; ++ sector >>= conf->sector_shift; ++ (void)sector_div(sector, conf->spacing); ++ hash = conf->hash_table[sector]; + + while (sector >= hash->num_sectors + hash->start_sector) + hash++; +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/drivers/md/md.c linux-2.6.29-rc3.owrt/drivers/md/md.c +--- linux-2.6.29.owrt/drivers/md/md.c 2009-05-10 22:04:38.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/drivers/md/md.c 2009-05-10 23:48:28.000000000 +0200 +@@ -214,7 +214,12 @@ + return mddev; + } + +-static void mddev_delayed_delete(struct work_struct *ws); ++static void mddev_delayed_delete(struct work_struct *ws) ++{ ++ mddev_t *mddev = container_of(ws, mddev_t, del_work); ++ kobject_del(&mddev->kobj); ++ kobject_put(&mddev->kobj); ++} + + static void mddev_put(mddev_t *mddev) + { +@@ -469,7 +474,7 @@ + * causes ENOTSUPP, we allocate a spare bio... + */ + struct bio *bio = bio_alloc(GFP_NOIO, 1); +- int rw = (1<<BIO_RW) | (1<<BIO_RW_SYNCIO) | (1<<BIO_RW_UNPLUG); ++ int rw = (1<<BIO_RW) | (1<<BIO_RW_SYNC); + + bio->bi_bdev = rdev->bdev; + bio->bi_sector = sector; +@@ -526,7 +531,7 @@ + struct completion event; + int ret; + +- rw |= (1 << BIO_RW_SYNCIO) | (1 << BIO_RW_UNPLUG); ++ rw |= (1 << BIO_RW_SYNC); + + bio->bi_bdev = bdev; + bio->bi_sector = sector; +@@ -1476,11 +1481,6 @@ + if (find_rdev_nr(mddev, rdev->desc_nr)) + return -EBUSY; + } +- if (mddev->max_disks && rdev->desc_nr >= mddev->max_disks) { +- printk(KERN_WARNING "md: %s: array is limited to %d devices\n", +- mdname(mddev), mddev->max_disks); +- return -EBUSY; +- } + bdevname(rdev->bdev,b); + while ( (s=strchr(b, '/')) != NULL) + *s = '!'; +@@ -2441,15 +2441,6 @@ + + i = 0; + rdev_for_each(rdev, tmp, mddev) { +- if (rdev->desc_nr >= mddev->max_disks || +- i > mddev->max_disks) { +- printk(KERN_WARNING +- "md: %s: %s: only %d devices permitted\n", +- mdname(mddev), bdevname(rdev->bdev, b), +- mddev->max_disks); +- kick_rdev_from_array(rdev); +- continue; +- } + if (rdev != freshest) + if (super_types[mddev->major_version]. + validate_super(mddev, rdev)) { +@@ -3537,21 +3528,6 @@ + + int mdp_major = 0; + +-static void mddev_delayed_delete(struct work_struct *ws) +-{ +- mddev_t *mddev = container_of(ws, mddev_t, del_work); +- +- if (mddev->private == &md_redundancy_group) { +- sysfs_remove_group(&mddev->kobj, &md_redundancy_group); +- if (mddev->sysfs_action) +- sysfs_put(mddev->sysfs_action); +- mddev->sysfs_action = NULL; +- mddev->private = NULL; +- } +- kobject_del(&mddev->kobj); +- kobject_put(&mddev->kobj); +-} +- + static int md_alloc(dev_t dev, char *name) + { + static DEFINE_MUTEX(disks_mutex); +@@ -4043,9 +4019,13 @@ + mddev->queue->merge_bvec_fn = NULL; + mddev->queue->unplug_fn = NULL; + mddev->queue->backing_dev_info.congested_fn = NULL; ++ if (mddev->pers->sync_request) { ++ sysfs_remove_group(&mddev->kobj, &md_redundancy_group); ++ if (mddev->sysfs_action) ++ sysfs_put(mddev->sysfs_action); ++ mddev->sysfs_action = NULL; ++ } + module_put(mddev->pers->owner); +- if (mddev->pers->sync_request) +- mddev->private = &md_redundancy_group; + mddev->pers = NULL; + /* tell userspace to handle 'inactive' */ + sysfs_notify_dirent(mddev->sysfs_state); +@@ -4634,6 +4614,13 @@ + * noticed in interrupt contexts ... + */ + ++ if (rdev->desc_nr == mddev->max_disks) { ++ printk(KERN_WARNING "%s: can not hot-add to full array!\n", ++ mdname(mddev)); ++ err = -EBUSY; ++ goto abort_unbind_export; ++ } ++ + rdev->raid_disk = -1; + + md_update_sb(mddev, 1); +@@ -4647,6 +4634,9 @@ + md_new_event(mddev); + return 0; + ++abort_unbind_export: ++ unbind_rdev_from_array(rdev); ++ + abort_export: + export_rdev(rdev); + return err; +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/drivers/md/raid10.c linux-2.6.29-rc3.owrt/drivers/md/raid10.c +--- linux-2.6.29.owrt/drivers/md/raid10.c 2009-05-10 22:04:38.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/drivers/md/raid10.c 2009-05-10 23:48:28.000000000 +0200 +@@ -1236,7 +1236,6 @@ + /* for reconstruct, we always reschedule after a read. + * for resync, only after all reads + */ +- rdev_dec_pending(conf->mirrors[d].rdev, conf->mddev); + if (test_bit(R10BIO_IsRecover, &r10_bio->state) || + atomic_dec_and_test(&r10_bio->remaining)) { + /* we have read all the blocks, +@@ -1244,6 +1243,7 @@ + */ + reschedule_retry(r10_bio); + } ++ rdev_dec_pending(conf->mirrors[d].rdev, conf->mddev); + } + + static void end_sync_write(struct bio *bio, int error) +@@ -1264,13 +1264,11 @@ + + update_head_pos(i, r10_bio); + +- rdev_dec_pending(conf->mirrors[d].rdev, mddev); + while (atomic_dec_and_test(&r10_bio->remaining)) { + if (r10_bio->master_bio == NULL) { + /* the primary of several recovery bios */ +- sector_t s = r10_bio->sectors; ++ md_done_sync(mddev, r10_bio->sectors, 1); + put_buf(r10_bio); +- md_done_sync(mddev, s, 1); + break; + } else { + r10bio_t *r10_bio2 = (r10bio_t *)r10_bio->master_bio; +@@ -1278,6 +1276,7 @@ + r10_bio = r10_bio2; + } + } ++ rdev_dec_pending(conf->mirrors[d].rdev, mddev); + } + + /* +@@ -1750,6 +1749,8 @@ + if (!go_faster && conf->nr_waiting) + msleep_interruptible(1000); + ++ bitmap_cond_end_sync(mddev->bitmap, sector_nr); ++ + /* Again, very different code for resync and recovery. + * Both must result in an r10bio with a list of bios that + * have bi_end_io, bi_sector, bi_bdev set, +@@ -1885,8 +1886,6 @@ + /* resync. Schedule a read for every block at this virt offset */ + int count = 0; + +- bitmap_cond_end_sync(mddev->bitmap, sector_nr); +- + if (!bitmap_start_sync(mddev->bitmap, sector_nr, + &sync_blocks, mddev->degraded) && + !conf->fullsync && !test_bit(MD_RECOVERY_REQUESTED, &mddev->recovery)) { +@@ -2011,13 +2010,13 @@ + /* There is nowhere to write, so all non-sync + * drives must be failed, so try the next chunk... + */ +- if (sector_nr + max_sync < max_sector) +- max_sector = sector_nr + max_sync; +- +- sectors_skipped += (max_sector - sector_nr); ++ { ++ sector_t sec = max_sector - sector_nr; ++ sectors_skipped += sec; + chunks_skipped ++; + sector_nr = max_sector; + goto skipped; ++ } + } + + static int run(mddev_t *mddev) +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/drivers/md/raid1.c linux-2.6.29-rc3.owrt/drivers/md/raid1.c +--- linux-2.6.29.owrt/drivers/md/raid1.c 2009-05-10 22:04:38.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/drivers/md/raid1.c 2009-05-10 23:48:28.000000000 +0200 +@@ -1237,9 +1237,8 @@ + update_head_pos(mirror, r1_bio); + + if (atomic_dec_and_test(&r1_bio->remaining)) { +- sector_t s = r1_bio->sectors; ++ md_done_sync(mddev, r1_bio->sectors, uptodate); + put_buf(r1_bio); +- md_done_sync(mddev, s, uptodate); + } + } + +@@ -1641,8 +1640,7 @@ + } + + bio = r1_bio->bios[r1_bio->read_disk]; +- if ((disk=read_balance(conf, r1_bio)) == -1 || +- disk == r1_bio->read_disk) { ++ if ((disk=read_balance(conf, r1_bio)) == -1) { + printk(KERN_ALERT "raid1: %s: unrecoverable I/O" + " read error for block %llu\n", + bdevname(bio->bi_bdev,b), +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/drivers/media/common/saa7146_video.c linux-2.6.29-rc3.owrt/drivers/media/common/saa7146_video.c +--- linux-2.6.29.owrt/drivers/media/common/saa7146_video.c 2009-05-10 22:04:39.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/drivers/media/common/saa7146_video.c 2009-05-10 23:48:28.000000000 +0200 +@@ -576,7 +576,6 @@ + vv->vflip = c->value; + break; + default: { +- mutex_unlock(&dev->lock); + return -EINVAL; + } + } +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/drivers/media/common/tuners/mxl5007t.c linux-2.6.29-rc3.owrt/drivers/media/common/tuners/mxl5007t.c +--- linux-2.6.29.owrt/drivers/media/common/tuners/mxl5007t.c 2009-05-10 22:04:39.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/drivers/media/common/tuners/mxl5007t.c 2009-05-10 23:48:28.000000000 +0200 +@@ -657,7 +657,7 @@ + { + struct mxl5007t_state *state = fe->tuner_priv; + int rf_locked, ref_locked; +- s32 rf_input_level = 0; ++ s32 rf_input_level; + int ret; + + if (fe->ops.i2c_gate_ctrl) +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/drivers/media/common/tuners/tuner-simple.c linux-2.6.29-rc3.owrt/drivers/media/common/tuners/tuner-simple.c +--- linux-2.6.29.owrt/drivers/media/common/tuners/tuner-simple.c 2009-05-10 22:04:39.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/drivers/media/common/tuners/tuner-simple.c 2009-05-10 23:48:28.000000000 +0200 +@@ -318,6 +318,7 @@ + u8 *config, u8 *cb) + { + struct tuner_simple_priv *priv = fe->tuner_priv; ++ u8 tuneraddr; + int rc; + + /* tv norm specific stuff for multi-norm tuners */ +@@ -386,7 +387,6 @@ + + case TUNER_PHILIPS_TUV1236D: + { +- struct tuner_i2c_props i2c = priv->i2c_props; + /* 0x40 -> ATSC antenna input 1 */ + /* 0x48 -> ATSC antenna input 2 */ + /* 0x00 -> NTSC antenna input 1 */ +@@ -398,15 +398,17 @@ + buffer[1] = 0x04; + } + /* set to the correct mode (analog or digital) */ +- i2c.addr = 0x0a; +- rc = tuner_i2c_xfer_send(&i2c, &buffer[0], 2); ++ tuneraddr = priv->i2c_props.addr; ++ priv->i2c_props.addr = 0x0a; ++ rc = tuner_i2c_xfer_send(&priv->i2c_props, &buffer[0], 2); + if (2 != rc) + tuner_warn("i2c i/o error: rc == %d " + "(should be 2)\n", rc); +- rc = tuner_i2c_xfer_send(&i2c, &buffer[2], 2); ++ rc = tuner_i2c_xfer_send(&priv->i2c_props, &buffer[2], 2); + if (2 != rc) + tuner_warn("i2c i/o error: rc == %d " + "(should be 2)\n", rc); ++ priv->i2c_props.addr = tuneraddr; + break; + } + } +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/drivers/media/dvb/b2c2/flexcop.c linux-2.6.29-rc3.owrt/drivers/media/dvb/b2c2/flexcop.c +--- linux-2.6.29.owrt/drivers/media/dvb/b2c2/flexcop.c 2009-05-10 22:04:39.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/drivers/media/dvb/b2c2/flexcop.c 2009-05-10 23:48:28.000000000 +0200 +@@ -212,7 +212,8 @@ + v210.sw_reset_210.Block_reset_enable = 0xb2; + + fc->write_ibi_reg(fc,sw_reset_210,v210); +- udelay(1000); ++ msleep(1); ++ + fc->write_ibi_reg(fc,ctrl_208,v208_save); + } + +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/drivers/media/dvb/b2c2/flexcop-hw-filter.c linux-2.6.29-rc3.owrt/drivers/media/dvb/b2c2/flexcop-hw-filter.c +--- linux-2.6.29.owrt/drivers/media/dvb/b2c2/flexcop-hw-filter.c 2009-05-10 22:04:39.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/drivers/media/dvb/b2c2/flexcop-hw-filter.c 2009-05-10 23:48:28.000000000 +0200 +@@ -192,7 +192,6 @@ + + return 0; + } +-EXPORT_SYMBOL(flexcop_pid_feed_control); + + void flexcop_hw_filter_init(struct flexcop_device *fc) + { +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/drivers/media/dvb/b2c2/flexcop-pci.c linux-2.6.29-rc3.owrt/drivers/media/dvb/b2c2/flexcop-pci.c +--- linux-2.6.29.owrt/drivers/media/dvb/b2c2/flexcop-pci.c 2009-05-10 22:04:39.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/drivers/media/dvb/b2c2/flexcop-pci.c 2009-05-10 23:48:28.000000000 +0200 +@@ -13,9 +13,9 @@ + module_param(enable_pid_filtering, int, 0444); + MODULE_PARM_DESC(enable_pid_filtering, "enable hardware pid filtering: supported values: 0 (fullts), 1"); + +-static int irq_chk_intv = 100; ++static int irq_chk_intv; + module_param(irq_chk_intv, int, 0644); +-MODULE_PARM_DESC(irq_chk_intv, "set the interval for IRQ streaming watchdog."); ++MODULE_PARM_DESC(irq_chk_intv, "set the interval for IRQ watchdog (currently just debugging)."); + + #ifdef CONFIG_DVB_B2C2_FLEXCOP_DEBUG + #define dprintk(level,args...) \ +@@ -34,9 +34,7 @@ + + static int debug; + module_param(debug, int, 0644); +-MODULE_PARM_DESC(debug, +- "set debug level (1=info,2=regs,4=TS,8=irqdma,16=check (|-able))." +- DEBSTATUS); ++MODULE_PARM_DESC(debug, "set debug level (1=info,2=regs,4=TS,8=irqdma (|-able))." DEBSTATUS); + + #define DRIVER_VERSION "0.1" + #define DRIVER_NAME "Technisat/B2C2 FlexCop II/IIb/III Digital TV PCI Driver" +@@ -60,8 +58,6 @@ + int active_dma1_addr; /* 0 = addr0 of dma1; 1 = addr1 of dma1 */ + u32 last_dma1_cur_pos; /* position of the pointer last time the timer/packet irq occured */ + int count; +- int count_prev; +- int stream_problem; + + spinlock_t irq_lock; + +@@ -107,32 +103,18 @@ + container_of(work, struct flexcop_pci, irq_check_work.work); + struct flexcop_device *fc = fc_pci->fc_dev; + +- if (fc->feedcount) { ++ flexcop_ibi_value v = fc->read_ibi_reg(fc,sram_dest_reg_714); + +- if (fc_pci->count == fc_pci->count_prev) { +- deb_chk("no IRQ since the last check\n"); +- if (fc_pci->stream_problem++ == 3) { +- struct dvb_demux_feed *feed; +- +- spin_lock_irq(&fc->demux.lock); +- list_for_each_entry(feed, &fc->demux.feed_list, +- list_head) { +- flexcop_pid_feed_control(fc, feed, 0); +- } +- +- list_for_each_entry(feed, &fc->demux.feed_list, +- list_head) { +- flexcop_pid_feed_control(fc, feed, 1); +- } +- spin_unlock_irq(&fc->demux.lock); +- +- fc_pci->stream_problem = 0; +- } +- } else { +- fc_pci->stream_problem = 0; +- fc_pci->count_prev = fc_pci->count; +- } +- } ++ flexcop_dump_reg(fc_pci->fc_dev,dma1_000,4); ++ ++ if (v.sram_dest_reg_714.net_ovflow_error) ++ deb_chk("sram net_ovflow_error\n"); ++ if (v.sram_dest_reg_714.media_ovflow_error) ++ deb_chk("sram media_ovflow_error\n"); ++ if (v.sram_dest_reg_714.cai_ovflow_error) ++ deb_chk("sram cai_ovflow_error\n"); ++ if (v.sram_dest_reg_714.cai_ovflow_error) ++ deb_chk("sram cai_ovflow_error\n"); + + schedule_delayed_work(&fc_pci->irq_check_work, + msecs_to_jiffies(irq_chk_intv < 100 ? 100 : irq_chk_intv)); +@@ -234,12 +216,16 @@ + flexcop_dma_control_timer_irq(fc,FC_DMA_1,1); + deb_irq("IRQ enabled\n"); + +- fc_pci->count_prev = fc_pci->count; +- + // fc_pci->active_dma1_addr = 0; + // flexcop_dma_control_size_irq(fc,FC_DMA_1,1); + ++ if (irq_chk_intv > 0) ++ schedule_delayed_work(&fc_pci->irq_check_work, ++ msecs_to_jiffies(irq_chk_intv < 100 ? 100 : irq_chk_intv)); + } else { ++ if (irq_chk_intv > 0) ++ cancel_delayed_work(&fc_pci->irq_check_work); ++ + flexcop_dma_control_timer_irq(fc,FC_DMA_1,0); + deb_irq("IRQ disabled\n"); + +@@ -313,6 +299,8 @@ + IRQF_SHARED, DRIVER_NAME, fc_pci)) != 0) + goto err_pci_iounmap; + ++ ++ + fc_pci->init_state |= FC_PCI_INIT; + return ret; + +@@ -387,10 +375,6 @@ + + INIT_DELAYED_WORK(&fc_pci->irq_check_work, flexcop_pci_irq_check_work); + +- if (irq_chk_intv > 0) +- schedule_delayed_work(&fc_pci->irq_check_work, +- msecs_to_jiffies(irq_chk_intv < 100 ? 100 : irq_chk_intv)); +- + return ret; + + err_fc_exit: +@@ -409,9 +393,6 @@ + { + struct flexcop_pci *fc_pci = pci_get_drvdata(pdev); + +- if (irq_chk_intv > 0) +- cancel_delayed_work(&fc_pci->irq_check_work); +- + flexcop_pci_dma_exit(fc_pci); + flexcop_device_exit(fc_pci->fc_dev); + flexcop_pci_exit(fc_pci); +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/drivers/media/dvb/bt8xx/dst.c linux-2.6.29-rc3.owrt/drivers/media/dvb/bt8xx/dst.c +--- linux-2.6.29.owrt/drivers/media/dvb/bt8xx/dst.c 2009-05-10 22:04:39.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/drivers/media/dvb/bt8xx/dst.c 2009-05-10 23:48:28.000000000 +0200 +@@ -1683,7 +1683,7 @@ + + static int dst_get_tuning_algo(struct dvb_frontend *fe) + { +- return dst_algo ? DVBFE_ALGO_HW : DVBFE_ALGO_SW; ++ return dst_algo; + } + + static int dst_get_frontend(struct dvb_frontend *fe, struct dvb_frontend_parameters *p) +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/drivers/media/dvb/dvb-core/dmxdev.c linux-2.6.29-rc3.owrt/drivers/media/dvb/dvb-core/dmxdev.c +--- linux-2.6.29.owrt/drivers/media/dvb/dvb-core/dmxdev.c 2009-05-10 22:04:39.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/drivers/media/dvb/dvb-core/dmxdev.c 2009-05-10 23:48:28.000000000 +0200 +@@ -364,15 +364,16 @@ + enum dmx_success success) + { + struct dmxdev_filter *dmxdevfilter = filter->priv; ++ unsigned long flags; + int ret; + + if (dmxdevfilter->buffer.error) { + wake_up(&dmxdevfilter->buffer.queue); + return 0; + } +- spin_lock(&dmxdevfilter->dev->lock); ++ spin_lock_irqsave(&dmxdevfilter->dev->lock, flags); + if (dmxdevfilter->state != DMXDEV_STATE_GO) { +- spin_unlock(&dmxdevfilter->dev->lock); ++ spin_unlock_irqrestore(&dmxdevfilter->dev->lock, flags); + return 0; + } + del_timer(&dmxdevfilter->timer); +@@ -391,7 +392,7 @@ + } + if (dmxdevfilter->params.sec.flags & DMX_ONESHOT) + dmxdevfilter->state = DMXDEV_STATE_DONE; +- spin_unlock(&dmxdevfilter->dev->lock); ++ spin_unlock_irqrestore(&dmxdevfilter->dev->lock, flags); + wake_up(&dmxdevfilter->buffer.queue); + return 0; + } +@@ -403,11 +404,12 @@ + { + struct dmxdev_filter *dmxdevfilter = feed->priv; + struct dvb_ringbuffer *buffer; ++ unsigned long flags; + int ret; + +- spin_lock(&dmxdevfilter->dev->lock); ++ spin_lock_irqsave(&dmxdevfilter->dev->lock, flags); + if (dmxdevfilter->params.pes.output == DMX_OUT_DECODER) { +- spin_unlock(&dmxdevfilter->dev->lock); ++ spin_unlock_irqrestore(&dmxdevfilter->dev->lock, flags); + return 0; + } + +@@ -417,7 +419,7 @@ + else + buffer = &dmxdevfilter->dev->dvr_buffer; + if (buffer->error) { +- spin_unlock(&dmxdevfilter->dev->lock); ++ spin_unlock_irqrestore(&dmxdevfilter->dev->lock, flags); + wake_up(&buffer->queue); + return 0; + } +@@ -428,7 +430,7 @@ + dvb_ringbuffer_flush(buffer); + buffer->error = ret; + } +- spin_unlock(&dmxdevfilter->dev->lock); ++ spin_unlock_irqrestore(&dmxdevfilter->dev->lock, flags); + wake_up(&buffer->queue); + return 0; + } +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/drivers/media/dvb/dvb-core/dvb_ca_en50221.c linux-2.6.29-rc3.owrt/drivers/media/dvb/dvb-core/dvb_ca_en50221.c +--- linux-2.6.29.owrt/drivers/media/dvb/dvb-core/dvb_ca_en50221.c 2009-05-10 22:04:39.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/drivers/media/dvb/dvb-core/dvb_ca_en50221.c 2009-05-10 23:48:28.000000000 +0200 +@@ -93,9 +93,6 @@ + /* current state of the CAM */ + int slot_state; + +- /* mutex used for serializing access to one CI slot */ +- struct mutex slot_lock; +- + /* Number of CAMCHANGES that have occurred since last processing */ + atomic_t camchange_count; + +@@ -714,20 +711,14 @@ + dprintk("%s\n", __func__); + + +- /* sanity check */ ++ // sanity check + if (bytes_write > ca->slot_info[slot].link_buf_size) + return -EINVAL; + +- /* it is possible we are dealing with a single buffer implementation, +- thus if there is data available for read or if there is even a read +- already in progress, we do nothing but awake the kernel thread to +- process the data if necessary. */ ++ /* check if interface is actually waiting for us to read from it, or if a read is in progress */ + if ((status = ca->pub->read_cam_control(ca->pub, slot, CTRLIF_STATUS)) < 0) + goto exitnowrite; + if (status & (STATUSREG_DA | STATUSREG_RE)) { +- if (status & STATUSREG_DA) +- dvb_ca_en50221_thread_wakeup(ca); +- + status = -EAGAIN; + goto exitnowrite; + } +@@ -996,8 +987,6 @@ + /* go through all the slots processing them */ + for (slot = 0; slot < ca->slot_count; slot++) { + +- mutex_lock(&ca->slot_info[slot].slot_lock); +- + // check the cam status + deal with CAMCHANGEs + while (dvb_ca_en50221_check_camstatus(ca, slot)) { + /* clear down an old CI slot if necessary */ +@@ -1133,7 +1122,7 @@ + + case DVB_CA_SLOTSTATE_RUNNING: + if (!ca->open) +- break; ++ continue; + + // poll slots for data + pktcount = 0; +@@ -1157,8 +1146,6 @@ + } + break; + } +- +- mutex_unlock(&ca->slot_info[slot].slot_lock); + } + } + +@@ -1194,7 +1181,6 @@ + switch (cmd) { + case CA_RESET: + for (slot = 0; slot < ca->slot_count; slot++) { +- mutex_lock(&ca->slot_info[slot].slot_lock); + if (ca->slot_info[slot].slot_state != DVB_CA_SLOTSTATE_NONE) { + dvb_ca_en50221_slot_shutdown(ca, slot); + if (ca->flags & DVB_CA_EN50221_FLAG_IRQ_CAMCHANGE) +@@ -1202,7 +1188,6 @@ + slot, + DVB_CA_EN50221_CAMCHANGE_INSERTED); + } +- mutex_unlock(&ca->slot_info[slot].slot_lock); + } + ca->next_read_slot = 0; + dvb_ca_en50221_thread_wakeup(ca); +@@ -1323,9 +1308,7 @@ + goto exit; + } + +- mutex_lock(&ca->slot_info[slot].slot_lock); + status = dvb_ca_en50221_write_data(ca, slot, fragbuf, fraglen + 2); +- mutex_unlock(&ca->slot_info[slot].slot_lock); + if (status == (fraglen + 2)) { + written = 1; + break; +@@ -1681,7 +1664,6 @@ + ca->slot_info[i].slot_state = DVB_CA_SLOTSTATE_NONE; + atomic_set(&ca->slot_info[i].camchange_count, 0); + ca->slot_info[i].camchange_type = DVB_CA_EN50221_CAMCHANGE_REMOVED; +- mutex_init(&ca->slot_info[i].slot_lock); + } + + if (signal_pending(current)) { +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/drivers/media/dvb/dvb-core/dvb_ca_en50221.h linux-2.6.29-rc3.owrt/drivers/media/dvb/dvb-core/dvb_ca_en50221.h +--- linux-2.6.29.owrt/drivers/media/dvb/dvb-core/dvb_ca_en50221.h 2009-05-10 22:04:39.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/drivers/media/dvb/dvb-core/dvb_ca_en50221.h 2009-05-10 23:48:28.000000000 +0200 +@@ -45,10 +45,8 @@ + /* the module owning this structure */ + struct module* owner; + +- /* NOTE: the read_*, write_* and poll_slot_status functions will be +- * called for different slots concurrently and need to use locks where +- * and if appropriate. There will be no concurrent access to one slot. +- */ ++ /* NOTE: the read_*, write_* and poll_slot_status functions must use locks as ++ * they may be called from several threads at once */ + + /* functions for accessing attribute memory on the CAM */ + int (*read_attribute_mem)(struct dvb_ca_en50221* ca, int slot, int address); +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/drivers/media/dvb/dvb-core/dvb_demux.c linux-2.6.29-rc3.owrt/drivers/media/dvb/dvb-core/dvb_demux.c +--- linux-2.6.29.owrt/drivers/media/dvb/dvb-core/dvb_demux.c 2009-05-10 22:04:39.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/drivers/media/dvb/dvb-core/dvb_demux.c 2009-05-10 23:48:28.000000000 +0200 +@@ -399,7 +399,9 @@ + void dvb_dmx_swfilter_packets(struct dvb_demux *demux, const u8 *buf, + size_t count) + { +- spin_lock(&demux->lock); ++ unsigned long flags; ++ ++ spin_lock_irqsave(&demux->lock, flags); + + while (count--) { + if (buf[0] == 0x47) +@@ -407,16 +409,17 @@ + buf += 188; + } + +- spin_unlock(&demux->lock); ++ spin_unlock_irqrestore(&demux->lock, flags); + } + + EXPORT_SYMBOL(dvb_dmx_swfilter_packets); + + void dvb_dmx_swfilter(struct dvb_demux *demux, const u8 *buf, size_t count) + { ++ unsigned long flags; + int p = 0, i, j; + +- spin_lock(&demux->lock); ++ spin_lock_irqsave(&demux->lock, flags); + + if (demux->tsbufp) { + i = demux->tsbufp; +@@ -449,17 +452,18 @@ + } + + bailout: +- spin_unlock(&demux->lock); ++ spin_unlock_irqrestore(&demux->lock, flags); + } + + EXPORT_SYMBOL(dvb_dmx_swfilter); + + void dvb_dmx_swfilter_204(struct dvb_demux *demux, const u8 *buf, size_t count) + { ++ unsigned long flags; + int p = 0, i, j; + u8 tmppack[188]; + +- spin_lock(&demux->lock); ++ spin_lock_irqsave(&demux->lock, flags); + + if (demux->tsbufp) { + i = demux->tsbufp; +@@ -500,7 +504,7 @@ + } + + bailout: +- spin_unlock(&demux->lock); ++ spin_unlock_irqrestore(&demux->lock, flags); + } + + EXPORT_SYMBOL(dvb_dmx_swfilter_204); +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/drivers/media/dvb/dvb-core/dvb_frontend.c linux-2.6.29-rc3.owrt/drivers/media/dvb/dvb-core/dvb_frontend.c +--- linux-2.6.29.owrt/drivers/media/dvb/dvb-core/dvb_frontend.c 2009-05-10 22:04:39.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/drivers/media/dvb/dvb-core/dvb_frontend.c 2009-05-10 23:48:28.000000000 +0200 +@@ -1290,6 +1290,9 @@ + dprintk("%s() Finalised property cache\n", __func__); + dtv_property_cache_submit(fe); + ++ /* Request the search algorithm to search */ ++ fepriv->algo_status |= DVBFE_ALGO_SEARCH_AGAIN; ++ + r |= dvb_frontend_ioctl_legacy(inode, file, FE_SET_FRONTEND, + &fepriv->parameters); + break; +@@ -1714,10 +1717,6 @@ + fepriv->min_delay = (dvb_override_tune_delay * HZ) / 1000; + + fepriv->state = FESTATE_RETUNE; +- +- /* Request the search algorithm to search */ +- fepriv->algo_status |= DVBFE_ALGO_SEARCH_AGAIN; +- + dvb_frontend_wakeup(fe); + dvb_frontend_add_event(fe, 0); + fepriv->status = 0; +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/drivers/media/dvb/dvb-usb/af9005-fe.c linux-2.6.29-rc3.owrt/drivers/media/dvb/dvb-usb/af9005-fe.c +--- linux-2.6.29.owrt/drivers/media/dvb/dvb-usb/af9005-fe.c 2009-05-10 22:04:39.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/drivers/media/dvb/dvb-usb/af9005-fe.c 2009-05-10 23:48:28.000000000 +0200 +@@ -220,7 +220,7 @@ + u16 * abort_count) + { + u32 loc_cw_count = 0, loc_err_count; +- u16 loc_abort_count = 0; ++ u16 loc_abort_count; + int ret; + + ret = +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/drivers/media/dvb/dvb-usb/af9015.c linux-2.6.29-rc3.owrt/drivers/media/dvb/dvb-usb/af9015.c +--- linux-2.6.29.owrt/drivers/media/dvb/dvb-usb/af9015.c 2009-05-10 22:04:39.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/drivers/media/dvb/dvb-usb/af9015.c 2009-05-10 23:48:28.000000000 +0200 +@@ -694,12 +694,7 @@ + + /* IR remote controller */ + req.addr = AF9015_EEPROM_IR_MODE; +- /* first message will timeout often due to possible hw bug */ +- for (i = 0; i < 4; i++) { +- ret = af9015_rw_udev(udev, &req); +- if (!ret) +- break; +- } ++ ret = af9015_rw_udev(udev, &req); + if (ret) + goto error; + deb_info("%s: IR mode:%d\n", __func__, val); +@@ -840,19 +835,18 @@ + if (!dvb_usb_af9015_dual_mode) + af9015_config.dual_mode = 0; + +- /* Set adapter0 buffer size according to USB port speed, adapter1 buffer +- size can be static because it is enabled only USB2.0 */ ++ /* set buffer size according to USB port speed */ + for (i = 0; i < af9015_properties_count; i++) { + /* USB1.1 set smaller buffersize and disable 2nd adapter */ + if (udev->speed == USB_SPEED_FULL) { +- af9015_properties[i].adapter[0].stream.u.bulk.buffersize +- = TS_USB11_MAX_PACKET_SIZE; ++ af9015_properties[i].adapter->stream.u.bulk.buffersize = ++ TS_USB11_MAX_PACKET_SIZE; + /* disable 2nd adapter because we don't have + PID-filters */ + af9015_config.dual_mode = 0; + } else { +- af9015_properties[i].adapter[0].stream.u.bulk.buffersize +- = TS_USB20_MAX_PACKET_SIZE; ++ af9015_properties[i].adapter->stream.u.bulk.buffersize = ++ TS_USB20_MAX_PACKET_SIZE; + } + } + +@@ -1260,12 +1254,6 @@ + .type = USB_BULK, + .count = 6, + .endpoint = 0x85, +- .u = { +- .bulk = { +- .buffersize = +- TS_USB20_MAX_PACKET_SIZE, +- } +- } + }, + } + }, +@@ -1365,12 +1353,6 @@ + .type = USB_BULK, + .count = 6, + .endpoint = 0x85, +- .u = { +- .bulk = { +- .buffersize = +- TS_USB20_MAX_PACKET_SIZE, +- } +- } + }, + } + }, +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/drivers/media/dvb/dvb-usb/dib0700_devices.c linux-2.6.29-rc3.owrt/drivers/media/dvb/dvb-usb/dib0700_devices.c +--- linux-2.6.29.owrt/drivers/media/dvb/dvb-usb/dib0700_devices.c 2009-05-10 22:04:39.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/drivers/media/dvb/dvb-usb/dib0700_devices.c 2009-05-10 23:48:28.000000000 +0200 +@@ -1393,9 +1393,6 @@ + { USB_DEVICE(USB_VID_ASUS, USB_PID_ASUS_U3000H) }, + /* 40 */{ USB_DEVICE(USB_VID_PINNACLE, USB_PID_PINNACLE_PCTV801E) }, + { USB_DEVICE(USB_VID_PINNACLE, USB_PID_PINNACLE_PCTV801E_SE) }, +- { USB_DEVICE(USB_VID_TERRATEC, USB_PID_TERRATEC_CINERGY_T_EXPRESS) }, +- { USB_DEVICE(USB_VID_TERRATEC, +- USB_PID_TERRATEC_CINERGY_DT_XS_DIVERSITY_2) }, + { 0 } /* Terminating entry */ + }; + MODULE_DEVICE_TABLE(usb, dib0700_usb_id_table); +@@ -1540,8 +1537,7 @@ + { "DiBcom STK7700D reference design", + { &dib0700_usb_id_table[14], NULL }, + { NULL }, +- }, +- ++ } + }, + + .rc_interval = DEFAULT_RC_INTERVAL, +@@ -1561,7 +1557,7 @@ + }, + }, + +- .num_device_descs = 3, ++ .num_device_descs = 2, + .devices = { + { "ASUS My Cinema U3000 Mini DVBT Tuner", + { &dib0700_usb_id_table[23], NULL }, +@@ -1570,10 +1566,6 @@ + { "Yuan EC372S", + { &dib0700_usb_id_table[31], NULL }, + { NULL }, +- }, +- { "Terratec Cinergy T Express", +- { &dib0700_usb_id_table[42], NULL }, +- { NULL }, + } + }, + +@@ -1661,7 +1653,7 @@ + } + }, + +- .num_device_descs = 5, ++ .num_device_descs = 4, + .devices = { + { "DiBcom STK7070PD reference design", + { &dib0700_usb_id_table[17], NULL }, +@@ -1678,10 +1670,6 @@ + { "Hauppauge Nova-TD-500 (84xxx)", + { &dib0700_usb_id_table[36], NULL }, + { NULL }, +- }, +- { "Terratec Cinergy DT USB XS Diversity", +- { &dib0700_usb_id_table[43], NULL }, +- { NULL }, + } + } + }, { DIB0700_DEFAULT_DEVICE_PROPERTIES, +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/drivers/media/dvb/dvb-usb/dvb-usb-ids.h linux-2.6.29-rc3.owrt/drivers/media/dvb/dvb-usb/dvb-usb-ids.h +--- linux-2.6.29.owrt/drivers/media/dvb/dvb-usb/dvb-usb-ids.h 2009-05-10 22:04:39.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/drivers/media/dvb/dvb-usb/dvb-usb-ids.h 2009-05-10 23:48:28.000000000 +0200 +@@ -162,10 +162,8 @@ + #define USB_PID_AVERMEDIA_A309 0xa309 + #define USB_PID_TECHNOTREND_CONNECT_S2400 0x3006 + #define USB_PID_TERRATEC_CINERGY_DT_XS_DIVERSITY 0x005a +-#define USB_PID_TERRATEC_CINERGY_DT_XS_DIVERSITY_2 0x0081 + #define USB_PID_TERRATEC_CINERGY_HT_USB_XE 0x0058 + #define USB_PID_TERRATEC_CINERGY_HT_EXPRESS 0x0060 +-#define USB_PID_TERRATEC_CINERGY_T_EXPRESS 0x0062 + #define USB_PID_TERRATEC_CINERGY_T_XXS 0x0078 + #define USB_PID_PINNACLE_EXPRESSCARD_320CX 0x022e + #define USB_PID_PINNACLE_PCTV2000E 0x022c +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/drivers/media/dvb/firewire/firedtv-1394.c linux-2.6.29-rc3.owrt/drivers/media/dvb/firewire/firedtv-1394.c +--- linux-2.6.29.owrt/drivers/media/dvb/firewire/firedtv-1394.c 2009-05-10 22:04:39.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/drivers/media/dvb/firewire/firedtv-1394.c 1970-01-01 01:00:00.000000000 +0100 +@@ -1,285 +0,0 @@ +-/* +- * FireDTV driver (formerly known as FireSAT) +- * +- * Copyright (C) 2004 Andreas Monitzer <andy@monitzer.com> +- * Copyright (C) 2007-2008 Ben Backx <ben@bbackx.com> +- * Copyright (C) 2008 Henrik Kurelid <henrik@kurelid.se> +- * +- * 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. +- */ +- +-#include <linux/device.h> +-#include <linux/errno.h> +-#include <linux/kernel.h> +-#include <linux/list.h> +-#include <linux/spinlock.h> +-#include <linux/types.h> +- +-#include <dma.h> +-#include <csr1212.h> +-#include <highlevel.h> +-#include <hosts.h> +-#include <ieee1394.h> +-#include <iso.h> +-#include <nodemgr.h> +- +-#include "firedtv.h" +- +-static LIST_HEAD(node_list); +-static DEFINE_SPINLOCK(node_list_lock); +- +-#define FIREWIRE_HEADER_SIZE 4 +-#define CIP_HEADER_SIZE 8 +- +-static void rawiso_activity_cb(struct hpsb_iso *iso) +-{ +- struct firedtv *f, *fdtv = NULL; +- unsigned int i, num, packet; +- unsigned char *buf; +- unsigned long flags; +- int count; +- +- spin_lock_irqsave(&node_list_lock, flags); +- list_for_each_entry(f, &node_list, list) +- if (f->backend_data == iso) { +- fdtv = f; +- break; +- } +- spin_unlock_irqrestore(&node_list_lock, flags); +- +- packet = iso->first_packet; +- num = hpsb_iso_n_ready(iso); +- +- if (!fdtv) { +- dev_err(fdtv->device, "received at unknown iso channel\n"); +- goto out; +- } +- +- for (i = 0; i < num; i++, packet = (packet + 1) % iso->buf_packets) { +- buf = dma_region_i(&iso->data_buf, unsigned char, +- iso->infos[packet].offset + CIP_HEADER_SIZE); +- count = (iso->infos[packet].len - CIP_HEADER_SIZE) / +- (188 + FIREWIRE_HEADER_SIZE); +- +- /* ignore empty packet */ +- if (iso->infos[packet].len <= CIP_HEADER_SIZE) +- continue; +- +- while (count--) { +- if (buf[FIREWIRE_HEADER_SIZE] == 0x47) +- dvb_dmx_swfilter_packets(&fdtv->demux, +- &buf[FIREWIRE_HEADER_SIZE], 1); +- else +- dev_err(fdtv->device, +- "skipping invalid packet\n"); +- buf += 188 + FIREWIRE_HEADER_SIZE; +- } +- } +-out: +- hpsb_iso_recv_release_packets(iso, num); +-} +- +-static inline struct node_entry *node_of(struct firedtv *fdtv) +-{ +- return container_of(fdtv->device, struct unit_directory, device)->ne; +-} +- +-static int node_lock(struct firedtv *fdtv, u64 addr, void *data, __be32 arg) +-{ +- return hpsb_node_lock(node_of(fdtv), addr, EXTCODE_COMPARE_SWAP, data, +- (__force quadlet_t)arg); +-} +- +-static int node_read(struct firedtv *fdtv, u64 addr, void *data, size_t len) +-{ +- return hpsb_node_read(node_of(fdtv), addr, data, len); +-} +- +-static int node_write(struct firedtv *fdtv, u64 addr, void *data, size_t len) +-{ +- return hpsb_node_write(node_of(fdtv), addr, data, len); +-} +- +-#define FDTV_ISO_BUFFER_PACKETS 256 +-#define FDTV_ISO_BUFFER_SIZE (FDTV_ISO_BUFFER_PACKETS * 200) +- +-static int start_iso(struct firedtv *fdtv) +-{ +- struct hpsb_iso *iso_handle; +- int ret; +- +- iso_handle = hpsb_iso_recv_init(node_of(fdtv)->host, +- FDTV_ISO_BUFFER_SIZE, FDTV_ISO_BUFFER_PACKETS, +- fdtv->isochannel, HPSB_ISO_DMA_DEFAULT, +- -1, /* stat.config.irq_interval */ +- rawiso_activity_cb); +- if (iso_handle == NULL) { +- dev_err(fdtv->device, "cannot initialize iso receive\n"); +- return -ENOMEM; +- } +- fdtv->backend_data = iso_handle; +- +- ret = hpsb_iso_recv_start(iso_handle, -1, -1, 0); +- if (ret != 0) { +- dev_err(fdtv->device, "cannot start iso receive\n"); +- hpsb_iso_shutdown(iso_handle); +- fdtv->backend_data = NULL; +- } +- return ret; +-} +- +-static void stop_iso(struct firedtv *fdtv) +-{ +- struct hpsb_iso *iso_handle = fdtv->backend_data; +- +- if (iso_handle != NULL) { +- hpsb_iso_stop(iso_handle); +- hpsb_iso_shutdown(iso_handle); +- } +- fdtv->backend_data = NULL; +-} +- +-static const struct firedtv_backend fdtv_1394_backend = { +- .lock = node_lock, +- .read = node_read, +- .write = node_write, +- .start_iso = start_iso, +- .stop_iso = stop_iso, +-}; +- +-static void fcp_request(struct hpsb_host *host, int nodeid, int direction, +- int cts, u8 *data, size_t length) +-{ +- struct firedtv *f, *fdtv = NULL; +- unsigned long flags; +- int su; +- +- if (length == 0 || (data[0] & 0xf0) != 0) +- return; +- +- su = data[1] & 0x7; +- +- spin_lock_irqsave(&node_list_lock, flags); +- list_for_each_entry(f, &node_list, list) +- if (node_of(f)->host == host && +- node_of(f)->nodeid == nodeid && +- (f->subunit == su || (f->subunit == 0 && su == 0x7))) { +- fdtv = f; +- break; +- } +- spin_unlock_irqrestore(&node_list_lock, flags); +- +- if (fdtv) +- avc_recv(fdtv, data, length); +-} +- +-static int node_probe(struct device *dev) +-{ +- struct unit_directory *ud = +- container_of(dev, struct unit_directory, device); +- struct firedtv *fdtv; +- int kv_len, err; +- void *kv_str; +- +- kv_len = (ud->model_name_kv->value.leaf.len - 2) * sizeof(quadlet_t); +- kv_str = CSR1212_TEXTUAL_DESCRIPTOR_LEAF_DATA(ud->model_name_kv); +- +- fdtv = fdtv_alloc(dev, &fdtv_1394_backend, kv_str, kv_len); +- if (!fdtv) +- return -ENOMEM; +- +- /* +- * Work around a bug in udev's path_id script: Use the fw-host's dev +- * instead of the unit directory's dev as parent of the input device. +- */ +- err = fdtv_register_rc(fdtv, dev->parent->parent); +- if (err) +- goto fail_free; +- +- spin_lock_irq(&node_list_lock); +- list_add_tail(&fdtv->list, &node_list); +- spin_unlock_irq(&node_list_lock); +- +- err = avc_identify_subunit(fdtv); +- if (err) +- goto fail; +- +- err = fdtv_dvb_register(fdtv); +- if (err) +- goto fail; +- +- avc_register_remote_control(fdtv); +- return 0; +-fail: +- spin_lock_irq(&node_list_lock); +- list_del(&fdtv->list); +- spin_unlock_irq(&node_list_lock); +- fdtv_unregister_rc(fdtv); +-fail_free: +- kfree(fdtv); +- return err; +-} +- +-static int node_remove(struct device *dev) +-{ +- struct firedtv *fdtv = dev->driver_data; +- +- fdtv_dvb_unregister(fdtv); +- +- spin_lock_irq(&node_list_lock); +- list_del(&fdtv->list); +- spin_unlock_irq(&node_list_lock); +- +- cancel_work_sync(&fdtv->remote_ctrl_work); +- fdtv_unregister_rc(fdtv); +- +- kfree(fdtv); +- return 0; +-} +- +-static int node_update(struct unit_directory *ud) +-{ +- struct firedtv *fdtv = ud->device.driver_data; +- +- if (fdtv->isochannel >= 0) +- cmp_establish_pp_connection(fdtv, fdtv->subunit, +- fdtv->isochannel); +- return 0; +-} +- +-static struct hpsb_protocol_driver fdtv_driver = { +- .name = "firedtv", +- .update = node_update, +- .driver = { +- .probe = node_probe, +- .remove = node_remove, +- }, +-}; +- +-static struct hpsb_highlevel fdtv_highlevel = { +- .name = "firedtv", +- .fcp_request = fcp_request, +-}; +- +-int __init fdtv_1394_init(struct ieee1394_device_id id_table[]) +-{ +- int ret; +- +- hpsb_register_highlevel(&fdtv_highlevel); +- fdtv_driver.id_table = id_table; +- ret = hpsb_register_protocol(&fdtv_driver); +- if (ret) { +- printk(KERN_ERR "firedtv: failed to register protocol\n"); +- hpsb_unregister_highlevel(&fdtv_highlevel); +- } +- return ret; +-} +- +-void __exit fdtv_1394_exit(void) +-{ +- hpsb_unregister_protocol(&fdtv_driver); +- hpsb_unregister_highlevel(&fdtv_highlevel); +-} +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/drivers/media/dvb/firewire/firedtv-avc.c linux-2.6.29-rc3.owrt/drivers/media/dvb/firewire/firedtv-avc.c +--- linux-2.6.29.owrt/drivers/media/dvb/firewire/firedtv-avc.c 2009-05-10 22:04:39.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/drivers/media/dvb/firewire/firedtv-avc.c 1970-01-01 01:00:00.000000000 +0100 +@@ -1,1315 +0,0 @@ +-/* +- * FireDTV driver (formerly known as FireSAT) +- * +- * Copyright (C) 2004 Andreas Monitzer <andy@monitzer.com> +- * Copyright (C) 2008 Ben Backx <ben@bbackx.com> +- * Copyright (C) 2008 Henrik Kurelid <henrik@kurelid.se> +- * +- * 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. +- */ +- +-#include <linux/bug.h> +-#include <linux/crc32.h> +-#include <linux/delay.h> +-#include <linux/device.h> +-#include <linux/jiffies.h> +-#include <linux/kernel.h> +-#include <linux/moduleparam.h> +-#include <linux/mutex.h> +-#include <linux/string.h> +-#include <linux/stringify.h> +-#include <linux/wait.h> +-#include <linux/workqueue.h> +- +-#include "firedtv.h" +- +-#define FCP_COMMAND_REGISTER 0xfffff0000b00ULL +- +-#define AVC_CTYPE_CONTROL 0x0 +-#define AVC_CTYPE_STATUS 0x1 +-#define AVC_CTYPE_NOTIFY 0x3 +- +-#define AVC_RESPONSE_ACCEPTED 0x9 +-#define AVC_RESPONSE_STABLE 0xc +-#define AVC_RESPONSE_CHANGED 0xd +-#define AVC_RESPONSE_INTERIM 0xf +- +-#define AVC_SUBUNIT_TYPE_TUNER (0x05 << 3) +-#define AVC_SUBUNIT_TYPE_UNIT (0x1f << 3) +- +-#define AVC_OPCODE_VENDOR 0x00 +-#define AVC_OPCODE_READ_DESCRIPTOR 0x09 +-#define AVC_OPCODE_DSIT 0xc8 +-#define AVC_OPCODE_DSD 0xcb +- +-#define DESCRIPTOR_TUNER_STATUS 0x80 +-#define DESCRIPTOR_SUBUNIT_IDENTIFIER 0x00 +- +-#define SFE_VENDOR_DE_COMPANYID_0 0x00 /* OUI of Digital Everywhere */ +-#define SFE_VENDOR_DE_COMPANYID_1 0x12 +-#define SFE_VENDOR_DE_COMPANYID_2 0x87 +- +-#define SFE_VENDOR_OPCODE_REGISTER_REMOTE_CONTROL 0x0a +-#define SFE_VENDOR_OPCODE_LNB_CONTROL 0x52 +-#define SFE_VENDOR_OPCODE_TUNE_QPSK 0x58 /* for DVB-S */ +- +-#define SFE_VENDOR_OPCODE_GET_FIRMWARE_VERSION 0x00 +-#define SFE_VENDOR_OPCODE_HOST2CA 0x56 +-#define SFE_VENDOR_OPCODE_CA2HOST 0x57 +-#define SFE_VENDOR_OPCODE_CISTATUS 0x59 +-#define SFE_VENDOR_OPCODE_TUNE_QPSK2 0x60 /* for DVB-S2 */ +- +-#define SFE_VENDOR_TAG_CA_RESET 0x00 +-#define SFE_VENDOR_TAG_CA_APPLICATION_INFO 0x01 +-#define SFE_VENDOR_TAG_CA_PMT 0x02 +-#define SFE_VENDOR_TAG_CA_DATE_TIME 0x04 +-#define SFE_VENDOR_TAG_CA_MMI 0x05 +-#define SFE_VENDOR_TAG_CA_ENTER_MENU 0x07 +- +-#define EN50221_LIST_MANAGEMENT_ONLY 0x03 +-#define EN50221_TAG_APP_INFO 0x9f8021 +-#define EN50221_TAG_CA_INFO 0x9f8031 +- +-struct avc_command_frame { +- int length; +- u8 ctype; +- u8 subunit; +- u8 opcode; +- u8 operand[509]; +-}; +- +-struct avc_response_frame { +- int length; +- u8 response; +- u8 subunit; +- u8 opcode; +- u8 operand[509]; +-}; +- +-#define AVC_DEBUG_FCP_SUBACTIONS 1 +-#define AVC_DEBUG_FCP_PAYLOADS 2 +- +-static int avc_debug; +-module_param_named(debug, avc_debug, int, 0644); +-MODULE_PARM_DESC(debug, "Verbose logging (default = 0" +- ", FCP subactions = " __stringify(AVC_DEBUG_FCP_SUBACTIONS) +- ", FCP payloads = " __stringify(AVC_DEBUG_FCP_PAYLOADS) +- ", or all = -1)"); +- +-static const char *debug_fcp_ctype(unsigned int ctype) +-{ +- static const char *ctypes[] = { +- [0x0] = "CONTROL", [0x1] = "STATUS", +- [0x2] = "SPECIFIC INQUIRY", [0x3] = "NOTIFY", +- [0x4] = "GENERAL INQUIRY", [0x8] = "NOT IMPLEMENTED", +- [0x9] = "ACCEPTED", [0xa] = "REJECTED", +- [0xb] = "IN TRANSITION", [0xc] = "IMPLEMENTED/STABLE", +- [0xd] = "CHANGED", [0xf] = "INTERIM", +- }; +- const char *ret = ctype < ARRAY_SIZE(ctypes) ? ctypes[ctype] : NULL; +- +- return ret ? ret : "?"; +-} +- +-static const char *debug_fcp_opcode(unsigned int opcode, +- const u8 *data, size_t length) +-{ +- switch (opcode) { +- case AVC_OPCODE_VENDOR: break; +- case AVC_OPCODE_READ_DESCRIPTOR: return "ReadDescriptor"; +- case AVC_OPCODE_DSIT: return "DirectSelectInfo.Type"; +- case AVC_OPCODE_DSD: return "DirectSelectData"; +- default: return "?"; +- } +- +- if (length < 7 || +- data[3] != SFE_VENDOR_DE_COMPANYID_0 || +- data[4] != SFE_VENDOR_DE_COMPANYID_1 || +- data[5] != SFE_VENDOR_DE_COMPANYID_2) +- return "Vendor"; +- +- switch (data[6]) { +- case SFE_VENDOR_OPCODE_REGISTER_REMOTE_CONTROL: return "RegisterRC"; +- case SFE_VENDOR_OPCODE_LNB_CONTROL: return "LNBControl"; +- case SFE_VENDOR_OPCODE_TUNE_QPSK: return "TuneQPSK"; +- case SFE_VENDOR_OPCODE_HOST2CA: return "Host2CA"; +- case SFE_VENDOR_OPCODE_CA2HOST: return "CA2Host"; +- } +- return "Vendor"; +-} +- +-static void debug_fcp(const u8 *data, size_t length) +-{ +- unsigned int subunit_type, subunit_id, op; +- const char *prefix = data[0] > 7 ? "FCP <- " : "FCP -> "; +- +- if (avc_debug & AVC_DEBUG_FCP_SUBACTIONS) { +- subunit_type = data[1] >> 3; +- subunit_id = data[1] & 7; +- op = subunit_type == 0x1e || subunit_id == 5 ? ~0 : data[2]; +- printk(KERN_INFO "%ssu=%x.%x l=%d: %-8s - %s\n", +- prefix, subunit_type, subunit_id, length, +- debug_fcp_ctype(data[0]), +- debug_fcp_opcode(op, data, length)); +- } +- +- if (avc_debug & AVC_DEBUG_FCP_PAYLOADS) +- print_hex_dump(KERN_INFO, prefix, DUMP_PREFIX_NONE, 16, 1, +- data, length, false); +-} +- +-static int __avc_write(struct firedtv *fdtv, +- const struct avc_command_frame *c, struct avc_response_frame *r) +-{ +- int err, retry; +- +- if (r) +- fdtv->avc_reply_received = false; +- +- for (retry = 0; retry < 6; retry++) { +- if (unlikely(avc_debug)) +- debug_fcp(&c->ctype, c->length); +- +- err = fdtv->backend->write(fdtv, FCP_COMMAND_REGISTER, +- (void *)&c->ctype, c->length); +- if (err) { +- fdtv->avc_reply_received = true; +- dev_err(fdtv->device, "FCP command write failed\n"); +- return err; +- } +- +- if (!r) +- return 0; +- +- /* +- * AV/C specs say that answers should be sent within 150 ms. +- * Time out after 200 ms. +- */ +- if (wait_event_timeout(fdtv->avc_wait, +- fdtv->avc_reply_received, +- msecs_to_jiffies(200)) != 0) { +- r->length = fdtv->response_length; +- memcpy(&r->response, fdtv->response, r->length); +- +- return 0; +- } +- } +- dev_err(fdtv->device, "FCP response timed out\n"); +- return -ETIMEDOUT; +-} +- +-static int avc_write(struct firedtv *fdtv, +- const struct avc_command_frame *c, struct avc_response_frame *r) +-{ +- int ret; +- +- if (mutex_lock_interruptible(&fdtv->avc_mutex)) +- return -EINTR; +- +- ret = __avc_write(fdtv, c, r); +- +- mutex_unlock(&fdtv->avc_mutex); +- return ret; +-} +- +-int avc_recv(struct firedtv *fdtv, void *data, size_t length) +-{ +- struct avc_response_frame *r = +- data - offsetof(struct avc_response_frame, response); +- +- if (unlikely(avc_debug)) +- debug_fcp(data, length); +- +- if (length >= 8 && +- r->operand[0] == SFE_VENDOR_DE_COMPANYID_0 && +- r->operand[1] == SFE_VENDOR_DE_COMPANYID_1 && +- r->operand[2] == SFE_VENDOR_DE_COMPANYID_2 && +- r->operand[3] == SFE_VENDOR_OPCODE_REGISTER_REMOTE_CONTROL) { +- if (r->response == AVC_RESPONSE_CHANGED) { +- fdtv_handle_rc(fdtv, +- r->operand[4] << 8 | r->operand[5]); +- schedule_work(&fdtv->remote_ctrl_work); +- } else if (r->response != AVC_RESPONSE_INTERIM) { +- dev_info(fdtv->device, +- "remote control result = %d\n", r->response); +- } +- return 0; +- } +- +- if (fdtv->avc_reply_received) { +- dev_err(fdtv->device, "out-of-order AVC response, ignored\n"); +- return -EIO; +- } +- +- memcpy(fdtv->response, data, length); +- fdtv->response_length = length; +- +- fdtv->avc_reply_received = true; +- wake_up(&fdtv->avc_wait); +- +- return 0; +-} +- +-/* +- * tuning command for setting the relative LNB frequency +- * (not supported by the AVC standard) +- */ +-static void avc_tuner_tuneqpsk(struct firedtv *fdtv, +- struct dvb_frontend_parameters *params, +- struct avc_command_frame *c) +-{ +- c->opcode = AVC_OPCODE_VENDOR; +- +- c->operand[0] = SFE_VENDOR_DE_COMPANYID_0; +- c->operand[1] = SFE_VENDOR_DE_COMPANYID_1; +- c->operand[2] = SFE_VENDOR_DE_COMPANYID_2; +- c->operand[3] = SFE_VENDOR_OPCODE_TUNE_QPSK; +- +- c->operand[4] = (params->frequency >> 24) & 0xff; +- c->operand[5] = (params->frequency >> 16) & 0xff; +- c->operand[6] = (params->frequency >> 8) & 0xff; +- c->operand[7] = params->frequency & 0xff; +- +- c->operand[8] = ((params->u.qpsk.symbol_rate / 1000) >> 8) & 0xff; +- c->operand[9] = (params->u.qpsk.symbol_rate / 1000) & 0xff; +- +- switch (params->u.qpsk.fec_inner) { +- case FEC_1_2: c->operand[10] = 0x1; break; +- case FEC_2_3: c->operand[10] = 0x2; break; +- case FEC_3_4: c->operand[10] = 0x3; break; +- case FEC_5_6: c->operand[10] = 0x4; break; +- case FEC_7_8: c->operand[10] = 0x5; break; +- case FEC_4_5: +- case FEC_8_9: +- case FEC_AUTO: +- default: c->operand[10] = 0x0; +- } +- +- if (fdtv->voltage == 0xff) +- c->operand[11] = 0xff; +- else if (fdtv->voltage == SEC_VOLTAGE_18) /* polarisation */ +- c->operand[11] = 0; +- else +- c->operand[11] = 1; +- +- if (fdtv->tone == 0xff) +- c->operand[12] = 0xff; +- else if (fdtv->tone == SEC_TONE_ON) /* band */ +- c->operand[12] = 1; +- else +- c->operand[12] = 0; +- +- if (fdtv->type == FIREDTV_DVB_S2) { +- c->operand[13] = 0x1; +- c->operand[14] = 0xff; +- c->operand[15] = 0xff; +- c->length = 20; +- } else { +- c->length = 16; +- } +-} +- +-static void avc_tuner_dsd_dvb_c(struct dvb_frontend_parameters *params, +- struct avc_command_frame *c) +-{ +- c->opcode = AVC_OPCODE_DSD; +- +- c->operand[0] = 0; /* source plug */ +- c->operand[1] = 0xd2; /* subfunction replace */ +- c->operand[2] = 0x20; /* system id = DVB */ +- c->operand[3] = 0x00; /* antenna number */ +- c->operand[4] = 0x11; /* system_specific_multiplex selection_length */ +- +- /* multiplex_valid_flags, high byte */ +- c->operand[5] = 0 << 7 /* reserved */ +- | 0 << 6 /* Polarisation */ +- | 0 << 5 /* Orbital_Pos */ +- | 1 << 4 /* Frequency */ +- | 1 << 3 /* Symbol_Rate */ +- | 0 << 2 /* FEC_outer */ +- | (params->u.qam.fec_inner != FEC_AUTO ? 1 << 1 : 0) +- | (params->u.qam.modulation != QAM_AUTO ? 1 << 0 : 0); +- +- /* multiplex_valid_flags, low byte */ +- c->operand[6] = 0 << 7 /* NetworkID */ +- | 0 << 0 /* reserved */ ; +- +- c->operand[7] = 0x00; +- c->operand[8] = 0x00; +- c->operand[9] = 0x00; +- c->operand[10] = 0x00; +- +- c->operand[11] = (((params->frequency / 4000) >> 16) & 0xff) | (2 << 6); +- c->operand[12] = ((params->frequency / 4000) >> 8) & 0xff; +- c->operand[13] = (params->frequency / 4000) & 0xff; +- c->operand[14] = ((params->u.qpsk.symbol_rate / 1000) >> 12) & 0xff; +- c->operand[15] = ((params->u.qpsk.symbol_rate / 1000) >> 4) & 0xff; +- c->operand[16] = ((params->u.qpsk.symbol_rate / 1000) << 4) & 0xf0; +- c->operand[17] = 0x00; +- +- switch (params->u.qpsk.fec_inner) { +- case FEC_1_2: c->operand[18] = 0x1; break; +- case FEC_2_3: c->operand[18] = 0x2; break; +- case FEC_3_4: c->operand[18] = 0x3; break; +- case FEC_5_6: c->operand[18] = 0x4; break; +- case FEC_7_8: c->operand[18] = 0x5; break; +- case FEC_8_9: c->operand[18] = 0x6; break; +- case FEC_4_5: c->operand[18] = 0x8; break; +- case FEC_AUTO: +- default: c->operand[18] = 0x0; +- } +- +- switch (params->u.qam.modulation) { +- case QAM_16: c->operand[19] = 0x08; break; +- case QAM_32: c->operand[19] = 0x10; break; +- case QAM_64: c->operand[19] = 0x18; break; +- case QAM_128: c->operand[19] = 0x20; break; +- case QAM_256: c->operand[19] = 0x28; break; +- case QAM_AUTO: +- default: c->operand[19] = 0x00; +- } +- +- c->operand[20] = 0x00; +- c->operand[21] = 0x00; +- /* Nr_of_dsd_sel_specs = 0 -> no PIDs are transmitted */ +- c->operand[22] = 0x00; +- +- c->length = 28; +-} +- +-static void avc_tuner_dsd_dvb_t(struct dvb_frontend_parameters *params, +- struct avc_command_frame *c) +-{ +- struct dvb_ofdm_parameters *ofdm = ¶ms->u.ofdm; +- +- c->opcode = AVC_OPCODE_DSD; +- +- c->operand[0] = 0; /* source plug */ +- c->operand[1] = 0xd2; /* subfunction replace */ +- c->operand[2] = 0x20; /* system id = DVB */ +- c->operand[3] = 0x00; /* antenna number */ +- c->operand[4] = 0x0c; /* system_specific_multiplex selection_length */ +- +- /* multiplex_valid_flags, high byte */ +- c->operand[5] = +- 0 << 7 /* reserved */ +- | 1 << 6 /* CenterFrequency */ +- | (ofdm->bandwidth != BANDWIDTH_AUTO ? 1 << 5 : 0) +- | (ofdm->constellation != QAM_AUTO ? 1 << 4 : 0) +- | (ofdm->hierarchy_information != HIERARCHY_AUTO ? 1 << 3 : 0) +- | (ofdm->code_rate_HP != FEC_AUTO ? 1 << 2 : 0) +- | (ofdm->code_rate_LP != FEC_AUTO ? 1 << 1 : 0) +- | (ofdm->guard_interval != GUARD_INTERVAL_AUTO ? 1 << 0 : 0); +- +- /* multiplex_valid_flags, low byte */ +- c->operand[6] = +- 0 << 7 /* NetworkID */ +- | (ofdm->transmission_mode != TRANSMISSION_MODE_AUTO ? 1 << 6 : 0) +- | 0 << 5 /* OtherFrequencyFlag */ +- | 0 << 0 /* reserved */ ; +- +- c->operand[7] = 0x0; +- c->operand[8] = (params->frequency / 10) >> 24; +- c->operand[9] = ((params->frequency / 10) >> 16) & 0xff; +- c->operand[10] = ((params->frequency / 10) >> 8) & 0xff; +- c->operand[11] = (params->frequency / 10) & 0xff; +- +- switch (ofdm->bandwidth) { +- case BANDWIDTH_7_MHZ: c->operand[12] = 0x20; break; +- case BANDWIDTH_8_MHZ: +- case BANDWIDTH_6_MHZ: /* not defined by AVC spec */ +- case BANDWIDTH_AUTO: +- default: c->operand[12] = 0x00; +- } +- +- switch (ofdm->constellation) { +- case QAM_16: c->operand[13] = 1 << 6; break; +- case QAM_64: c->operand[13] = 2 << 6; break; +- case QPSK: +- default: c->operand[13] = 0x00; +- } +- +- switch (ofdm->hierarchy_information) { +- case HIERARCHY_1: c->operand[13] |= 1 << 3; break; +- case HIERARCHY_2: c->operand[13] |= 2 << 3; break; +- case HIERARCHY_4: c->operand[13] |= 3 << 3; break; +- case HIERARCHY_AUTO: +- case HIERARCHY_NONE: +- default: break; +- } +- +- switch (ofdm->code_rate_HP) { +- case FEC_2_3: c->operand[13] |= 1; break; +- case FEC_3_4: c->operand[13] |= 2; break; +- case FEC_5_6: c->operand[13] |= 3; break; +- case FEC_7_8: c->operand[13] |= 4; break; +- case FEC_1_2: +- default: break; +- } +- +- switch (ofdm->code_rate_LP) { +- case FEC_2_3: c->operand[14] = 1 << 5; break; +- case FEC_3_4: c->operand[14] = 2 << 5; break; +- case FEC_5_6: c->operand[14] = 3 << 5; break; +- case FEC_7_8: c->operand[14] = 4 << 5; break; +- case FEC_1_2: +- default: c->operand[14] = 0x00; break; +- } +- +- switch (ofdm->guard_interval) { +- case GUARD_INTERVAL_1_16: c->operand[14] |= 1 << 3; break; +- case GUARD_INTERVAL_1_8: c->operand[14] |= 2 << 3; break; +- case GUARD_INTERVAL_1_4: c->operand[14] |= 3 << 3; break; +- case GUARD_INTERVAL_1_32: +- case GUARD_INTERVAL_AUTO: +- default: break; +- } +- +- switch (ofdm->transmission_mode) { +- case TRANSMISSION_MODE_8K: c->operand[14] |= 1 << 1; break; +- case TRANSMISSION_MODE_2K: +- case TRANSMISSION_MODE_AUTO: +- default: break; +- } +- +- c->operand[15] = 0x00; /* network_ID[0] */ +- c->operand[16] = 0x00; /* network_ID[1] */ +- /* Nr_of_dsd_sel_specs = 0 -> no PIDs are transmitted */ +- c->operand[17] = 0x00; +- +- c->length = 24; +-} +- +-int avc_tuner_dsd(struct firedtv *fdtv, +- struct dvb_frontend_parameters *params) +-{ +- char buffer[sizeof(struct avc_command_frame)]; +- struct avc_command_frame *c = (void *)buffer; +- struct avc_response_frame *r = (void *)buffer; /* FIXME: unused */ +- +- memset(c, 0, sizeof(*c)); +- +- c->ctype = AVC_CTYPE_CONTROL; +- c->subunit = AVC_SUBUNIT_TYPE_TUNER | fdtv->subunit; +- +- switch (fdtv->type) { +- case FIREDTV_DVB_S: +- case FIREDTV_DVB_S2: avc_tuner_tuneqpsk(fdtv, params, c); break; +- case FIREDTV_DVB_C: avc_tuner_dsd_dvb_c(params, c); break; +- case FIREDTV_DVB_T: avc_tuner_dsd_dvb_t(params, c); break; +- default: +- BUG(); +- } +- +- if (avc_write(fdtv, c, r) < 0) +- return -EIO; +- +- msleep(500); +-#if 0 +- /* FIXME: */ +- /* u8 *status was an out-parameter of avc_tuner_dsd, unused by caller */ +- if (status) +- *status = r->operand[2]; +-#endif +- return 0; +-} +- +-int avc_tuner_set_pids(struct firedtv *fdtv, unsigned char pidc, u16 pid[]) +-{ +- char buffer[sizeof(struct avc_command_frame)]; +- struct avc_command_frame *c = (void *)buffer; +- struct avc_response_frame *r = (void *)buffer; /* FIXME: unused */ +- int pos, k; +- +- if (pidc > 16 && pidc != 0xff) +- return -EINVAL; +- +- memset(c, 0, sizeof(*c)); +- +- c->ctype = AVC_CTYPE_CONTROL; +- c->subunit = AVC_SUBUNIT_TYPE_TUNER | fdtv->subunit; +- c->opcode = AVC_OPCODE_DSD; +- +- c->operand[0] = 0; /* source plug */ +- c->operand[1] = 0xd2; /* subfunction replace */ +- c->operand[2] = 0x20; /* system id = DVB */ +- c->operand[3] = 0x00; /* antenna number */ +- c->operand[4] = 0x00; /* system_specific_multiplex selection_length */ +- c->operand[5] = pidc; /* Nr_of_dsd_sel_specs */ +- +- pos = 6; +- if (pidc != 0xff) +- for (k = 0; k < pidc; k++) { +- c->operand[pos++] = 0x13; /* flowfunction relay */ +- c->operand[pos++] = 0x80; /* dsd_sel_spec_valid_flags -> PID */ +- c->operand[pos++] = (pid[k] >> 8) & 0x1f; +- c->operand[pos++] = pid[k] & 0xff; +- c->operand[pos++] = 0x00; /* tableID */ +- c->operand[pos++] = 0x00; /* filter_length */ +- } +- +- c->length = ALIGN(3 + pos, 4); +- +- if (avc_write(fdtv, c, r) < 0) +- return -EIO; +- +- msleep(50); +- return 0; +-} +- +-int avc_tuner_get_ts(struct firedtv *fdtv) +-{ +- char buffer[sizeof(struct avc_command_frame)]; +- struct avc_command_frame *c = (void *)buffer; +- struct avc_response_frame *r = (void *)buffer; /* FIXME: unused */ +- int sl; +- +- memset(c, 0, sizeof(*c)); +- +- c->ctype = AVC_CTYPE_CONTROL; +- c->subunit = AVC_SUBUNIT_TYPE_TUNER | fdtv->subunit; +- c->opcode = AVC_OPCODE_DSIT; +- +- sl = fdtv->type == FIREDTV_DVB_T ? 0x0c : 0x11; +- +- c->operand[0] = 0; /* source plug */ +- c->operand[1] = 0xd2; /* subfunction replace */ +- c->operand[2] = 0xff; /* status */ +- c->operand[3] = 0x20; /* system id = DVB */ +- c->operand[4] = 0x00; /* antenna number */ +- c->operand[5] = 0x0; /* system_specific_search_flags */ +- c->operand[6] = sl; /* system_specific_multiplex selection_length */ +- c->operand[7] = 0x00; /* valid_flags [0] */ +- c->operand[8] = 0x00; /* valid_flags [1] */ +- c->operand[7 + sl] = 0x00; /* nr_of_dsit_sel_specs (always 0) */ +- +- c->length = fdtv->type == FIREDTV_DVB_T ? 24 : 28; +- +- if (avc_write(fdtv, c, r) < 0) +- return -EIO; +- +- msleep(250); +- return 0; +-} +- +-int avc_identify_subunit(struct firedtv *fdtv) +-{ +- char buffer[sizeof(struct avc_command_frame)]; +- struct avc_command_frame *c = (void *)buffer; +- struct avc_response_frame *r = (void *)buffer; +- +- memset(c, 0, sizeof(*c)); +- +- c->ctype = AVC_CTYPE_CONTROL; +- c->subunit = AVC_SUBUNIT_TYPE_TUNER | fdtv->subunit; +- c->opcode = AVC_OPCODE_READ_DESCRIPTOR; +- +- c->operand[0] = DESCRIPTOR_SUBUNIT_IDENTIFIER; +- c->operand[1] = 0xff; +- c->operand[2] = 0x00; +- c->operand[3] = 0x00; /* length highbyte */ +- c->operand[4] = 0x08; /* length lowbyte */ +- c->operand[5] = 0x00; /* offset highbyte */ +- c->operand[6] = 0x0d; /* offset lowbyte */ +- +- c->length = 12; +- +- if (avc_write(fdtv, c, r) < 0) +- return -EIO; +- +- if ((r->response != AVC_RESPONSE_STABLE && +- r->response != AVC_RESPONSE_ACCEPTED) || +- (r->operand[3] << 8) + r->operand[4] != 8) { +- dev_err(fdtv->device, "cannot read subunit identifier\n"); +- return -EINVAL; +- } +- return 0; +-} +- +-#define SIZEOF_ANTENNA_INPUT_INFO 22 +- +-int avc_tuner_status(struct firedtv *fdtv, struct firedtv_tuner_status *stat) +-{ +- char buffer[sizeof(struct avc_command_frame)]; +- struct avc_command_frame *c = (void *)buffer; +- struct avc_response_frame *r = (void *)buffer; +- int length; +- +- memset(c, 0, sizeof(*c)); +- +- c->ctype = AVC_CTYPE_CONTROL; +- c->subunit = AVC_SUBUNIT_TYPE_TUNER | fdtv->subunit; +- c->opcode = AVC_OPCODE_READ_DESCRIPTOR; +- +- c->operand[0] = DESCRIPTOR_TUNER_STATUS; +- c->operand[1] = 0xff; /* read_result_status */ +- c->operand[2] = 0x00; /* reserved */ +- c->operand[3] = 0; /* SIZEOF_ANTENNA_INPUT_INFO >> 8; */ +- c->operand[4] = 0; /* SIZEOF_ANTENNA_INPUT_INFO & 0xff; */ +- c->operand[5] = 0x00; +- c->operand[6] = 0x00; +- +- c->length = 12; +- +- if (avc_write(fdtv, c, r) < 0) +- return -EIO; +- +- if (r->response != AVC_RESPONSE_STABLE && +- r->response != AVC_RESPONSE_ACCEPTED) { +- dev_err(fdtv->device, "cannot read tuner status\n"); +- return -EINVAL; +- } +- +- length = r->operand[9]; +- if (r->operand[1] != 0x10 || length != SIZEOF_ANTENNA_INPUT_INFO) { +- dev_err(fdtv->device, "got invalid tuner status\n"); +- return -EINVAL; +- } +- +- stat->active_system = r->operand[10]; +- stat->searching = r->operand[11] >> 7 & 1; +- stat->moving = r->operand[11] >> 6 & 1; +- stat->no_rf = r->operand[11] >> 5 & 1; +- stat->input = r->operand[12] >> 7 & 1; +- stat->selected_antenna = r->operand[12] & 0x7f; +- stat->ber = r->operand[13] << 24 | +- r->operand[14] << 16 | +- r->operand[15] << 8 | +- r->operand[16]; +- stat->signal_strength = r->operand[17]; +- stat->raster_frequency = r->operand[18] >> 6 & 2; +- stat->rf_frequency = (r->operand[18] & 0x3f) << 16 | +- r->operand[19] << 8 | +- r->operand[20]; +- stat->man_dep_info_length = r->operand[21]; +- stat->front_end_error = r->operand[22] >> 4 & 1; +- stat->antenna_error = r->operand[22] >> 3 & 1; +- stat->front_end_power_status = r->operand[22] >> 1 & 1; +- stat->power_supply = r->operand[22] & 1; +- stat->carrier_noise_ratio = r->operand[23] << 8 | +- r->operand[24]; +- stat->power_supply_voltage = r->operand[27]; +- stat->antenna_voltage = r->operand[28]; +- stat->firewire_bus_voltage = r->operand[29]; +- stat->ca_mmi = r->operand[30] & 1; +- stat->ca_pmt_reply = r->operand[31] >> 7 & 1; +- stat->ca_date_time_request = r->operand[31] >> 6 & 1; +- stat->ca_application_info = r->operand[31] >> 5 & 1; +- stat->ca_module_present_status = r->operand[31] >> 4 & 1; +- stat->ca_dvb_flag = r->operand[31] >> 3 & 1; +- stat->ca_error_flag = r->operand[31] >> 2 & 1; +- stat->ca_initialization_status = r->operand[31] >> 1 & 1; +- +- return 0; +-} +- +-int avc_lnb_control(struct firedtv *fdtv, char voltage, char burst, +- char conttone, char nrdiseq, +- struct dvb_diseqc_master_cmd *diseqcmd) +-{ +- char buffer[sizeof(struct avc_command_frame)]; +- struct avc_command_frame *c = (void *)buffer; +- struct avc_response_frame *r = (void *)buffer; +- int i, j, k; +- +- memset(c, 0, sizeof(*c)); +- +- c->ctype = AVC_CTYPE_CONTROL; +- c->subunit = AVC_SUBUNIT_TYPE_TUNER | fdtv->subunit; +- c->opcode = AVC_OPCODE_VENDOR; +- +- c->operand[0] = SFE_VENDOR_DE_COMPANYID_0; +- c->operand[1] = SFE_VENDOR_DE_COMPANYID_1; +- c->operand[2] = SFE_VENDOR_DE_COMPANYID_2; +- c->operand[3] = SFE_VENDOR_OPCODE_LNB_CONTROL; +- +- c->operand[4] = voltage; +- c->operand[5] = nrdiseq; +- +- i = 6; +- +- for (j = 0; j < nrdiseq; j++) { +- c->operand[i++] = diseqcmd[j].msg_len; +- +- for (k = 0; k < diseqcmd[j].msg_len; k++) +- c->operand[i++] = diseqcmd[j].msg[k]; +- } +- +- c->operand[i++] = burst; +- c->operand[i++] = conttone; +- +- c->length = ALIGN(3 + i, 4); +- +- if (avc_write(fdtv, c, r) < 0) +- return -EIO; +- +- if (r->response != AVC_RESPONSE_ACCEPTED) { +- dev_err(fdtv->device, "LNB control failed\n"); +- return -EINVAL; +- } +- +- return 0; +-} +- +-int avc_register_remote_control(struct firedtv *fdtv) +-{ +- char buffer[sizeof(struct avc_command_frame)]; +- struct avc_command_frame *c = (void *)buffer; +- +- memset(c, 0, sizeof(*c)); +- +- c->ctype = AVC_CTYPE_NOTIFY; +- c->subunit = AVC_SUBUNIT_TYPE_UNIT | 7; +- c->opcode = AVC_OPCODE_VENDOR; +- +- c->operand[0] = SFE_VENDOR_DE_COMPANYID_0; +- c->operand[1] = SFE_VENDOR_DE_COMPANYID_1; +- c->operand[2] = SFE_VENDOR_DE_COMPANYID_2; +- c->operand[3] = SFE_VENDOR_OPCODE_REGISTER_REMOTE_CONTROL; +- +- c->length = 8; +- +- return avc_write(fdtv, c, NULL); +-} +- +-void avc_remote_ctrl_work(struct work_struct *work) +-{ +- struct firedtv *fdtv = +- container_of(work, struct firedtv, remote_ctrl_work); +- +- /* Should it be rescheduled in failure cases? */ +- avc_register_remote_control(fdtv); +-} +- +-#if 0 /* FIXME: unused */ +-int avc_tuner_host2ca(struct firedtv *fdtv) +-{ +- char buffer[sizeof(struct avc_command_frame)]; +- struct avc_command_frame *c = (void *)buffer; +- struct avc_response_frame *r = (void *)buffer; /* FIXME: unused */ +- +- memset(c, 0, sizeof(*c)); +- +- c->ctype = AVC_CTYPE_CONTROL; +- c->subunit = AVC_SUBUNIT_TYPE_TUNER | fdtv->subunit; +- c->opcode = AVC_OPCODE_VENDOR; +- +- c->operand[0] = SFE_VENDOR_DE_COMPANYID_0; +- c->operand[1] = SFE_VENDOR_DE_COMPANYID_1; +- c->operand[2] = SFE_VENDOR_DE_COMPANYID_2; +- c->operand[3] = SFE_VENDOR_OPCODE_HOST2CA; +- c->operand[4] = 0; /* slot */ +- c->operand[5] = SFE_VENDOR_TAG_CA_APPLICATION_INFO; /* ca tag */ +- c->operand[6] = 0; /* more/last */ +- c->operand[7] = 0; /* length */ +- +- c->length = 12; +- +- if (avc_write(fdtv, c, r) < 0) +- return -EIO; +- +- return 0; +-} +-#endif +- +-static int get_ca_object_pos(struct avc_response_frame *r) +-{ +- int length = 1; +- +- /* Check length of length field */ +- if (r->operand[7] & 0x80) +- length = (r->operand[7] & 0x7f) + 1; +- return length + 7; +-} +- +-static int get_ca_object_length(struct avc_response_frame *r) +-{ +-#if 0 /* FIXME: unused */ +- int size = 0; +- int i; +- +- if (r->operand[7] & 0x80) +- for (i = 0; i < (r->operand[7] & 0x7f); i++) { +- size <<= 8; +- size += r->operand[8 + i]; +- } +-#endif +- return r->operand[7]; +-} +- +-int avc_ca_app_info(struct firedtv *fdtv, char *app_info, unsigned int *len) +-{ +- char buffer[sizeof(struct avc_command_frame)]; +- struct avc_command_frame *c = (void *)buffer; +- struct avc_response_frame *r = (void *)buffer; +- int pos; +- +- memset(c, 0, sizeof(*c)); +- +- c->ctype = AVC_CTYPE_STATUS; +- c->subunit = AVC_SUBUNIT_TYPE_TUNER | fdtv->subunit; +- c->opcode = AVC_OPCODE_VENDOR; +- +- c->operand[0] = SFE_VENDOR_DE_COMPANYID_0; +- c->operand[1] = SFE_VENDOR_DE_COMPANYID_1; +- c->operand[2] = SFE_VENDOR_DE_COMPANYID_2; +- c->operand[3] = SFE_VENDOR_OPCODE_CA2HOST; +- c->operand[4] = 0; /* slot */ +- c->operand[5] = SFE_VENDOR_TAG_CA_APPLICATION_INFO; /* ca tag */ +- +- c->length = 12; +- +- if (avc_write(fdtv, c, r) < 0) +- return -EIO; +- +- /* FIXME: check response code and validate response data */ +- +- pos = get_ca_object_pos(r); +- app_info[0] = (EN50221_TAG_APP_INFO >> 16) & 0xff; +- app_info[1] = (EN50221_TAG_APP_INFO >> 8) & 0xff; +- app_info[2] = (EN50221_TAG_APP_INFO >> 0) & 0xff; +- app_info[3] = 6 + r->operand[pos + 4]; +- app_info[4] = 0x01; +- memcpy(&app_info[5], &r->operand[pos], 5 + r->operand[pos + 4]); +- *len = app_info[3] + 4; +- +- return 0; +-} +- +-int avc_ca_info(struct firedtv *fdtv, char *app_info, unsigned int *len) +-{ +- char buffer[sizeof(struct avc_command_frame)]; +- struct avc_command_frame *c = (void *)buffer; +- struct avc_response_frame *r = (void *)buffer; +- int pos; +- +- memset(c, 0, sizeof(*c)); +- +- c->ctype = AVC_CTYPE_STATUS; +- c->subunit = AVC_SUBUNIT_TYPE_TUNER | fdtv->subunit; +- c->opcode = AVC_OPCODE_VENDOR; +- +- c->operand[0] = SFE_VENDOR_DE_COMPANYID_0; +- c->operand[1] = SFE_VENDOR_DE_COMPANYID_1; +- c->operand[2] = SFE_VENDOR_DE_COMPANYID_2; +- c->operand[3] = SFE_VENDOR_OPCODE_CA2HOST; +- c->operand[4] = 0; /* slot */ +- c->operand[5] = SFE_VENDOR_TAG_CA_APPLICATION_INFO; /* ca tag */ +- +- c->length = 12; +- +- if (avc_write(fdtv, c, r) < 0) +- return -EIO; +- +- pos = get_ca_object_pos(r); +- app_info[0] = (EN50221_TAG_CA_INFO >> 16) & 0xff; +- app_info[1] = (EN50221_TAG_CA_INFO >> 8) & 0xff; +- app_info[2] = (EN50221_TAG_CA_INFO >> 0) & 0xff; +- app_info[3] = 2; +- app_info[4] = r->operand[pos + 0]; +- app_info[5] = r->operand[pos + 1]; +- *len = app_info[3] + 4; +- +- return 0; +-} +- +-int avc_ca_reset(struct firedtv *fdtv) +-{ +- char buffer[sizeof(struct avc_command_frame)]; +- struct avc_command_frame *c = (void *)buffer; +- struct avc_response_frame *r = (void *)buffer; /* FIXME: unused */ +- +- memset(c, 0, sizeof(*c)); +- +- c->ctype = AVC_CTYPE_CONTROL; +- c->subunit = AVC_SUBUNIT_TYPE_TUNER | fdtv->subunit; +- c->opcode = AVC_OPCODE_VENDOR; +- +- c->operand[0] = SFE_VENDOR_DE_COMPANYID_0; +- c->operand[1] = SFE_VENDOR_DE_COMPANYID_1; +- c->operand[2] = SFE_VENDOR_DE_COMPANYID_2; +- c->operand[3] = SFE_VENDOR_OPCODE_HOST2CA; +- c->operand[4] = 0; /* slot */ +- c->operand[5] = SFE_VENDOR_TAG_CA_RESET; /* ca tag */ +- c->operand[6] = 0; /* more/last */ +- c->operand[7] = 1; /* length */ +- c->operand[8] = 0; /* force hardware reset */ +- +- c->length = 12; +- +- if (avc_write(fdtv, c, r) < 0) +- return -EIO; +- +- return 0; +-} +- +-int avc_ca_pmt(struct firedtv *fdtv, char *msg, int length) +-{ +- char buffer[sizeof(struct avc_command_frame)]; +- struct avc_command_frame *c = (void *)buffer; +- struct avc_response_frame *r = (void *)buffer; +- int list_management; +- int program_info_length; +- int pmt_cmd_id; +- int read_pos; +- int write_pos; +- int es_info_length; +- int crc32_csum; +- +- memset(c, 0, sizeof(*c)); +- +- c->ctype = AVC_CTYPE_CONTROL; +- c->subunit = AVC_SUBUNIT_TYPE_TUNER | fdtv->subunit; +- c->opcode = AVC_OPCODE_VENDOR; +- +- if (msg[0] != EN50221_LIST_MANAGEMENT_ONLY) { +- dev_info(fdtv->device, "forcing list_management to ONLY\n"); +- msg[0] = EN50221_LIST_MANAGEMENT_ONLY; +- } +- /* We take the cmd_id from the programme level only! */ +- list_management = msg[0]; +- program_info_length = ((msg[4] & 0x0f) << 8) + msg[5]; +- if (program_info_length > 0) +- program_info_length--; /* Remove pmt_cmd_id */ +- pmt_cmd_id = msg[6]; +- +- c->operand[0] = SFE_VENDOR_DE_COMPANYID_0; +- c->operand[1] = SFE_VENDOR_DE_COMPANYID_1; +- c->operand[2] = SFE_VENDOR_DE_COMPANYID_2; +- c->operand[3] = SFE_VENDOR_OPCODE_HOST2CA; +- c->operand[4] = 0; /* slot */ +- c->operand[5] = SFE_VENDOR_TAG_CA_PMT; /* ca tag */ +- c->operand[6] = 0; /* more/last */ +- /* c->operand[7] = XXXprogram_info_length + 17; */ /* length */ +- c->operand[8] = list_management; +- c->operand[9] = 0x01; /* pmt_cmd=OK_descramble */ +- +- /* TS program map table */ +- +- c->operand[10] = 0x02; /* Table id=2 */ +- c->operand[11] = 0x80; /* Section syntax + length */ +- /* c->operand[12] = XXXprogram_info_length + 12; */ +- c->operand[13] = msg[1]; /* Program number */ +- c->operand[14] = msg[2]; +- c->operand[15] = 0x01; /* Version number=0 + current/next=1 */ +- c->operand[16] = 0x00; /* Section number=0 */ +- c->operand[17] = 0x00; /* Last section number=0 */ +- c->operand[18] = 0x1f; /* PCR_PID=1FFF */ +- c->operand[19] = 0xff; +- c->operand[20] = (program_info_length >> 8); /* Program info length */ +- c->operand[21] = (program_info_length & 0xff); +- +- /* CA descriptors at programme level */ +- read_pos = 6; +- write_pos = 22; +- if (program_info_length > 0) { +- pmt_cmd_id = msg[read_pos++]; +- if (pmt_cmd_id != 1 && pmt_cmd_id != 4) +- dev_err(fdtv->device, +- "invalid pmt_cmd_id %d\n", pmt_cmd_id); +- +- memcpy(&c->operand[write_pos], &msg[read_pos], +- program_info_length); +- read_pos += program_info_length; +- write_pos += program_info_length; +- } +- while (read_pos < length) { +- c->operand[write_pos++] = msg[read_pos++]; +- c->operand[write_pos++] = msg[read_pos++]; +- c->operand[write_pos++] = msg[read_pos++]; +- es_info_length = +- ((msg[read_pos] & 0x0f) << 8) + msg[read_pos + 1]; +- read_pos += 2; +- if (es_info_length > 0) +- es_info_length--; /* Remove pmt_cmd_id */ +- c->operand[write_pos++] = es_info_length >> 8; +- c->operand[write_pos++] = es_info_length & 0xff; +- if (es_info_length > 0) { +- pmt_cmd_id = msg[read_pos++]; +- if (pmt_cmd_id != 1 && pmt_cmd_id != 4) +- dev_err(fdtv->device, "invalid pmt_cmd_id %d " +- "at stream level\n", pmt_cmd_id); +- +- memcpy(&c->operand[write_pos], &msg[read_pos], +- es_info_length); +- read_pos += es_info_length; +- write_pos += es_info_length; +- } +- } +- +- /* CRC */ +- c->operand[write_pos++] = 0x00; +- c->operand[write_pos++] = 0x00; +- c->operand[write_pos++] = 0x00; +- c->operand[write_pos++] = 0x00; +- +- c->operand[7] = write_pos - 8; +- c->operand[12] = write_pos - 13; +- +- crc32_csum = crc32_be(0, &c->operand[10], c->operand[12] - 1); +- c->operand[write_pos - 4] = (crc32_csum >> 24) & 0xff; +- c->operand[write_pos - 3] = (crc32_csum >> 16) & 0xff; +- c->operand[write_pos - 2] = (crc32_csum >> 8) & 0xff; +- c->operand[write_pos - 1] = (crc32_csum >> 0) & 0xff; +- +- c->length = ALIGN(3 + write_pos, 4); +- +- if (avc_write(fdtv, c, r) < 0) +- return -EIO; +- +- if (r->response != AVC_RESPONSE_ACCEPTED) { +- dev_err(fdtv->device, +- "CA PMT failed with response 0x%x\n", r->response); +- return -EFAULT; +- } +- +- return 0; +-} +- +-int avc_ca_get_time_date(struct firedtv *fdtv, int *interval) +-{ +- char buffer[sizeof(struct avc_command_frame)]; +- struct avc_command_frame *c = (void *)buffer; +- struct avc_response_frame *r = (void *)buffer; +- +- memset(c, 0, sizeof(*c)); +- +- c->ctype = AVC_CTYPE_STATUS; +- c->subunit = AVC_SUBUNIT_TYPE_TUNER | fdtv->subunit; +- c->opcode = AVC_OPCODE_VENDOR; +- +- c->operand[0] = SFE_VENDOR_DE_COMPANYID_0; +- c->operand[1] = SFE_VENDOR_DE_COMPANYID_1; +- c->operand[2] = SFE_VENDOR_DE_COMPANYID_2; +- c->operand[3] = SFE_VENDOR_OPCODE_CA2HOST; +- c->operand[4] = 0; /* slot */ +- c->operand[5] = SFE_VENDOR_TAG_CA_DATE_TIME; /* ca tag */ +- c->operand[6] = 0; /* more/last */ +- c->operand[7] = 0; /* length */ +- +- c->length = 12; +- +- if (avc_write(fdtv, c, r) < 0) +- return -EIO; +- +- /* FIXME: check response code and validate response data */ +- +- *interval = r->operand[get_ca_object_pos(r)]; +- +- return 0; +-} +- +-int avc_ca_enter_menu(struct firedtv *fdtv) +-{ +- char buffer[sizeof(struct avc_command_frame)]; +- struct avc_command_frame *c = (void *)buffer; +- struct avc_response_frame *r = (void *)buffer; /* FIXME: unused */ +- +- memset(c, 0, sizeof(*c)); +- +- c->ctype = AVC_CTYPE_STATUS; +- c->subunit = AVC_SUBUNIT_TYPE_TUNER | fdtv->subunit; +- c->opcode = AVC_OPCODE_VENDOR; +- +- c->operand[0] = SFE_VENDOR_DE_COMPANYID_0; +- c->operand[1] = SFE_VENDOR_DE_COMPANYID_1; +- c->operand[2] = SFE_VENDOR_DE_COMPANYID_2; +- c->operand[3] = SFE_VENDOR_OPCODE_HOST2CA; +- c->operand[4] = 0; /* slot */ +- c->operand[5] = SFE_VENDOR_TAG_CA_ENTER_MENU; +- c->operand[6] = 0; /* more/last */ +- c->operand[7] = 0; /* length */ +- +- c->length = 12; +- +- if (avc_write(fdtv, c, r) < 0) +- return -EIO; +- +- return 0; +-} +- +-int avc_ca_get_mmi(struct firedtv *fdtv, char *mmi_object, unsigned int *len) +-{ +- char buffer[sizeof(struct avc_command_frame)]; +- struct avc_command_frame *c = (void *)buffer; +- struct avc_response_frame *r = (void *)buffer; +- +- memset(c, 0, sizeof(*c)); +- +- c->ctype = AVC_CTYPE_STATUS; +- c->subunit = AVC_SUBUNIT_TYPE_TUNER | fdtv->subunit; +- c->opcode = AVC_OPCODE_VENDOR; +- +- c->operand[0] = SFE_VENDOR_DE_COMPANYID_0; +- c->operand[1] = SFE_VENDOR_DE_COMPANYID_1; +- c->operand[2] = SFE_VENDOR_DE_COMPANYID_2; +- c->operand[3] = SFE_VENDOR_OPCODE_CA2HOST; +- c->operand[4] = 0; /* slot */ +- c->operand[5] = SFE_VENDOR_TAG_CA_MMI; +- c->operand[6] = 0; /* more/last */ +- c->operand[7] = 0; /* length */ +- +- c->length = 12; +- +- if (avc_write(fdtv, c, r) < 0) +- return -EIO; +- +- /* FIXME: check response code and validate response data */ +- +- *len = get_ca_object_length(r); +- memcpy(mmi_object, &r->operand[get_ca_object_pos(r)], *len); +- +- return 0; +-} +- +-#define CMP_OUTPUT_PLUG_CONTROL_REG_0 0xfffff0000904ULL +- +-static int cmp_read(struct firedtv *fdtv, void *buf, u64 addr, size_t len) +-{ +- int ret; +- +- if (mutex_lock_interruptible(&fdtv->avc_mutex)) +- return -EINTR; +- +- ret = fdtv->backend->read(fdtv, addr, buf, len); +- if (ret < 0) +- dev_err(fdtv->device, "CMP: read I/O error\n"); +- +- mutex_unlock(&fdtv->avc_mutex); +- return ret; +-} +- +-static int cmp_lock(struct firedtv *fdtv, void *data, u64 addr, __be32 arg) +-{ +- int ret; +- +- if (mutex_lock_interruptible(&fdtv->avc_mutex)) +- return -EINTR; +- +- ret = fdtv->backend->lock(fdtv, addr, data, arg); +- if (ret < 0) +- dev_err(fdtv->device, "CMP: lock I/O error\n"); +- +- mutex_unlock(&fdtv->avc_mutex); +- return ret; +-} +- +-static inline u32 get_opcr(__be32 opcr, u32 mask, u32 shift) +-{ +- return (be32_to_cpu(opcr) >> shift) & mask; +-} +- +-static inline void set_opcr(__be32 *opcr, u32 value, u32 mask, u32 shift) +-{ +- *opcr &= ~cpu_to_be32(mask << shift); +- *opcr |= cpu_to_be32((value & mask) << shift); +-} +- +-#define get_opcr_online(v) get_opcr((v), 0x1, 31) +-#define get_opcr_p2p_connections(v) get_opcr((v), 0x3f, 24) +-#define get_opcr_channel(v) get_opcr((v), 0x3f, 16) +- +-#define set_opcr_p2p_connections(p, v) set_opcr((p), (v), 0x3f, 24) +-#define set_opcr_channel(p, v) set_opcr((p), (v), 0x3f, 16) +-#define set_opcr_data_rate(p, v) set_opcr((p), (v), 0x3, 14) +-#define set_opcr_overhead_id(p, v) set_opcr((p), (v), 0xf, 10) +- +-int cmp_establish_pp_connection(struct firedtv *fdtv, int plug, int channel) +-{ +- __be32 old_opcr, opcr; +- u64 opcr_address = CMP_OUTPUT_PLUG_CONTROL_REG_0 + (plug << 2); +- int attempts = 0; +- int ret; +- +- ret = cmp_read(fdtv, &opcr, opcr_address, 4); +- if (ret < 0) +- return ret; +- +-repeat: +- if (!get_opcr_online(opcr)) { +- dev_err(fdtv->device, "CMP: output offline\n"); +- return -EBUSY; +- } +- +- old_opcr = opcr; +- +- if (get_opcr_p2p_connections(opcr)) { +- if (get_opcr_channel(opcr) != channel) { +- dev_err(fdtv->device, "CMP: cannot change channel\n"); +- return -EBUSY; +- } +- dev_info(fdtv->device, "CMP: overlaying connection\n"); +- +- /* We don't allocate isochronous resources. */ +- } else { +- set_opcr_channel(&opcr, channel); +- set_opcr_data_rate(&opcr, 2); /* S400 */ +- +- /* FIXME: this is for the worst case - optimize */ +- set_opcr_overhead_id(&opcr, 0); +- +- /* +- * FIXME: allocate isochronous channel and bandwidth at IRM +- * fdtv->backend->alloc_resources(fdtv, channels_mask, bw); +- */ +- } +- +- set_opcr_p2p_connections(&opcr, get_opcr_p2p_connections(opcr) + 1); +- +- ret = cmp_lock(fdtv, &opcr, opcr_address, old_opcr); +- if (ret < 0) +- return ret; +- +- if (old_opcr != opcr) { +- /* +- * FIXME: if old_opcr.P2P_Connections > 0, +- * deallocate isochronous channel and bandwidth at IRM +- * if (...) +- * fdtv->backend->dealloc_resources(fdtv, channel, bw); +- */ +- +- if (++attempts < 6) /* arbitrary limit */ +- goto repeat; +- return -EBUSY; +- } +- +- return 0; +-} +- +-void cmp_break_pp_connection(struct firedtv *fdtv, int plug, int channel) +-{ +- __be32 old_opcr, opcr; +- u64 opcr_address = CMP_OUTPUT_PLUG_CONTROL_REG_0 + (plug << 2); +- int attempts = 0; +- +- if (cmp_read(fdtv, &opcr, opcr_address, 4) < 0) +- return; +- +-repeat: +- if (!get_opcr_online(opcr) || !get_opcr_p2p_connections(opcr) || +- get_opcr_channel(opcr) != channel) { +- dev_err(fdtv->device, "CMP: no connection to break\n"); +- return; +- } +- +- old_opcr = opcr; +- set_opcr_p2p_connections(&opcr, get_opcr_p2p_connections(opcr) - 1); +- +- if (cmp_lock(fdtv, &opcr, opcr_address, old_opcr) < 0) +- return; +- +- if (old_opcr != opcr) { +- /* +- * FIXME: if old_opcr.P2P_Connections == 1, i.e. we were last +- * owner, deallocate isochronous channel and bandwidth at IRM +- * if (...) +- * fdtv->backend->dealloc_resources(fdtv, channel, bw); +- */ +- +- if (++attempts < 6) /* arbitrary limit */ +- goto repeat; +- } +-} +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/drivers/media/dvb/firewire/firedtv-ci.c linux-2.6.29-rc3.owrt/drivers/media/dvb/firewire/firedtv-ci.c +--- linux-2.6.29.owrt/drivers/media/dvb/firewire/firedtv-ci.c 2009-05-10 22:04:39.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/drivers/media/dvb/firewire/firedtv-ci.c 1970-01-01 01:00:00.000000000 +0100 +@@ -1,260 +0,0 @@ +-/* +- * FireDTV driver (formerly known as FireSAT) +- * +- * Copyright (C) 2004 Andreas Monitzer <andy@monitzer.com> +- * Copyright (C) 2008 Henrik Kurelid <henrik@kurelid.se> +- * +- * 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. +- */ +- +-#include <linux/device.h> +-#include <linux/dvb/ca.h> +-#include <linux/fs.h> +-#include <linux/module.h> +- +-#include <dvbdev.h> +- +-#include "firedtv.h" +- +-#define EN50221_TAG_APP_INFO_ENQUIRY 0x9f8020 +-#define EN50221_TAG_CA_INFO_ENQUIRY 0x9f8030 +-#define EN50221_TAG_CA_PMT 0x9f8032 +-#define EN50221_TAG_ENTER_MENU 0x9f8022 +- +-static int fdtv_ca_ready(struct firedtv_tuner_status *stat) +-{ +- return stat->ca_initialization_status == 1 && +- stat->ca_error_flag == 0 && +- stat->ca_dvb_flag == 1 && +- stat->ca_module_present_status == 1; +-} +- +-static int fdtv_get_ca_flags(struct firedtv_tuner_status *stat) +-{ +- int flags = 0; +- +- if (stat->ca_module_present_status == 1) +- flags |= CA_CI_MODULE_PRESENT; +- if (stat->ca_initialization_status == 1 && +- stat->ca_error_flag == 0 && +- stat->ca_dvb_flag == 1) +- flags |= CA_CI_MODULE_READY; +- return flags; +-} +- +-static int fdtv_ca_reset(struct firedtv *fdtv) +-{ +- return avc_ca_reset(fdtv) ? -EFAULT : 0; +-} +- +-static int fdtv_ca_get_caps(void *arg) +-{ +- struct ca_caps *cap = arg; +- +- cap->slot_num = 1; +- cap->slot_type = CA_CI; +- cap->descr_num = 1; +- cap->descr_type = CA_ECD; +- return 0; +-} +- +-static int fdtv_ca_get_slot_info(struct firedtv *fdtv, void *arg) +-{ +- struct firedtv_tuner_status stat; +- struct ca_slot_info *slot = arg; +- +- if (avc_tuner_status(fdtv, &stat)) +- return -EFAULT; +- +- if (slot->num != 0) +- return -EFAULT; +- +- slot->type = CA_CI; +- slot->flags = fdtv_get_ca_flags(&stat); +- return 0; +-} +- +-static int fdtv_ca_app_info(struct firedtv *fdtv, void *arg) +-{ +- struct ca_msg *reply = arg; +- +- return avc_ca_app_info(fdtv, reply->msg, &reply->length) ? -EFAULT : 0; +-} +- +-static int fdtv_ca_info(struct firedtv *fdtv, void *arg) +-{ +- struct ca_msg *reply = arg; +- +- return avc_ca_info(fdtv, reply->msg, &reply->length) ? -EFAULT : 0; +-} +- +-static int fdtv_ca_get_mmi(struct firedtv *fdtv, void *arg) +-{ +- struct ca_msg *reply = arg; +- +- return avc_ca_get_mmi(fdtv, reply->msg, &reply->length) ? -EFAULT : 0; +-} +- +-static int fdtv_ca_get_msg(struct firedtv *fdtv, void *arg) +-{ +- struct firedtv_tuner_status stat; +- int err; +- +- switch (fdtv->ca_last_command) { +- case EN50221_TAG_APP_INFO_ENQUIRY: +- err = fdtv_ca_app_info(fdtv, arg); +- break; +- case EN50221_TAG_CA_INFO_ENQUIRY: +- err = fdtv_ca_info(fdtv, arg); +- break; +- default: +- if (avc_tuner_status(fdtv, &stat)) +- err = -EFAULT; +- else if (stat.ca_mmi == 1) +- err = fdtv_ca_get_mmi(fdtv, arg); +- else { +- dev_info(fdtv->device, "unhandled CA message 0x%08x\n", +- fdtv->ca_last_command); +- err = -EFAULT; +- } +- } +- fdtv->ca_last_command = 0; +- return err; +-} +- +-static int fdtv_ca_pmt(struct firedtv *fdtv, void *arg) +-{ +- struct ca_msg *msg = arg; +- int data_pos; +- int data_length; +- int i; +- +- data_pos = 4; +- if (msg->msg[3] & 0x80) { +- data_length = 0; +- for (i = 0; i < (msg->msg[3] & 0x7f); i++) +- data_length = (data_length << 8) + msg->msg[data_pos++]; +- } else { +- data_length = msg->msg[3]; +- } +- +- return avc_ca_pmt(fdtv, &msg->msg[data_pos], data_length) ? -EFAULT : 0; +-} +- +-static int fdtv_ca_send_msg(struct firedtv *fdtv, void *arg) +-{ +- struct ca_msg *msg = arg; +- int err; +- +- /* Do we need a semaphore for this? */ +- fdtv->ca_last_command = +- (msg->msg[0] << 16) + (msg->msg[1] << 8) + msg->msg[2]; +- switch (fdtv->ca_last_command) { +- case EN50221_TAG_CA_PMT: +- err = fdtv_ca_pmt(fdtv, arg); +- break; +- case EN50221_TAG_APP_INFO_ENQUIRY: +- /* handled in ca_get_msg */ +- err = 0; +- break; +- case EN50221_TAG_CA_INFO_ENQUIRY: +- /* handled in ca_get_msg */ +- err = 0; +- break; +- case EN50221_TAG_ENTER_MENU: +- err = avc_ca_enter_menu(fdtv); +- break; +- default: +- dev_err(fdtv->device, "unhandled CA message 0x%08x\n", +- fdtv->ca_last_command); +- err = -EFAULT; +- } +- return err; +-} +- +-static int fdtv_ca_ioctl(struct inode *inode, struct file *file, +- unsigned int cmd, void *arg) +-{ +- struct dvb_device *dvbdev = file->private_data; +- struct firedtv *fdtv = dvbdev->priv; +- struct firedtv_tuner_status stat; +- int err; +- +- switch (cmd) { +- case CA_RESET: +- err = fdtv_ca_reset(fdtv); +- break; +- case CA_GET_CAP: +- err = fdtv_ca_get_caps(arg); +- break; +- case CA_GET_SLOT_INFO: +- err = fdtv_ca_get_slot_info(fdtv, arg); +- break; +- case CA_GET_MSG: +- err = fdtv_ca_get_msg(fdtv, arg); +- break; +- case CA_SEND_MSG: +- err = fdtv_ca_send_msg(fdtv, arg); +- break; +- default: +- dev_info(fdtv->device, "unhandled CA ioctl %u\n", cmd); +- err = -EOPNOTSUPP; +- } +- +- /* FIXME Is this necessary? */ +- avc_tuner_status(fdtv, &stat); +- +- return err; +-} +- +-static unsigned int fdtv_ca_io_poll(struct file *file, poll_table *wait) +-{ +- return POLLIN; +-} +- +-static struct file_operations fdtv_ca_fops = { +- .owner = THIS_MODULE, +- .ioctl = dvb_generic_ioctl, +- .open = dvb_generic_open, +- .release = dvb_generic_release, +- .poll = fdtv_ca_io_poll, +-}; +- +-static struct dvb_device fdtv_ca = { +- .users = 1, +- .readers = 1, +- .writers = 1, +- .fops = &fdtv_ca_fops, +- .kernel_ioctl = fdtv_ca_ioctl, +-}; +- +-int fdtv_ca_register(struct firedtv *fdtv) +-{ +- struct firedtv_tuner_status stat; +- int err; +- +- if (avc_tuner_status(fdtv, &stat)) +- return -EINVAL; +- +- if (!fdtv_ca_ready(&stat)) +- return -EFAULT; +- +- err = dvb_register_device(&fdtv->adapter, &fdtv->cadev, +- &fdtv_ca, fdtv, DVB_DEVICE_CA); +- +- if (stat.ca_application_info == 0) +- dev_err(fdtv->device, "CaApplicationInfo is not set\n"); +- if (stat.ca_date_time_request == 1) +- avc_ca_get_time_date(fdtv, &fdtv->ca_time_interval); +- +- return err; +-} +- +-void fdtv_ca_release(struct firedtv *fdtv) +-{ +- if (fdtv->cadev) +- dvb_unregister_device(fdtv->cadev); +-} +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/drivers/media/dvb/firewire/firedtv-dvb.c linux-2.6.29-rc3.owrt/drivers/media/dvb/firewire/firedtv-dvb.c +--- linux-2.6.29.owrt/drivers/media/dvb/firewire/firedtv-dvb.c 2009-05-10 22:04:39.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/drivers/media/dvb/firewire/firedtv-dvb.c 1970-01-01 01:00:00.000000000 +0100 +@@ -1,364 +0,0 @@ +-/* +- * FireDTV driver (formerly known as FireSAT) +- * +- * Copyright (C) 2004 Andreas Monitzer <andy@monitzer.com> +- * Copyright (C) 2008 Henrik Kurelid <henrik@kurelid.se> +- * +- * 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. +- */ +- +-#include <linux/bitops.h> +-#include <linux/device.h> +-#include <linux/errno.h> +-#include <linux/kernel.h> +-#include <linux/mod_devicetable.h> +-#include <linux/module.h> +-#include <linux/mutex.h> +-#include <linux/slab.h> +-#include <linux/string.h> +-#include <linux/types.h> +-#include <linux/wait.h> +-#include <linux/workqueue.h> +- +-#include <dmxdev.h> +-#include <dvb_demux.h> +-#include <dvbdev.h> +-#include <dvb_frontend.h> +- +-#include "firedtv.h" +- +-static int alloc_channel(struct firedtv *fdtv) +-{ +- int i; +- +- for (i = 0; i < 16; i++) +- if (!__test_and_set_bit(i, &fdtv->channel_active)) +- break; +- return i; +-} +- +-static void collect_channels(struct firedtv *fdtv, int *pidc, u16 pid[]) +-{ +- int i, n; +- +- for (i = 0, n = 0; i < 16; i++) +- if (test_bit(i, &fdtv->channel_active)) +- pid[n++] = fdtv->channel_pid[i]; +- *pidc = n; +-} +- +-static inline void dealloc_channel(struct firedtv *fdtv, int i) +-{ +- __clear_bit(i, &fdtv->channel_active); +-} +- +-int fdtv_start_feed(struct dvb_demux_feed *dvbdmxfeed) +-{ +- struct firedtv *fdtv = dvbdmxfeed->demux->priv; +- int pidc, c, ret; +- u16 pids[16]; +- +- switch (dvbdmxfeed->type) { +- case DMX_TYPE_TS: +- case DMX_TYPE_SEC: +- break; +- default: +- dev_err(fdtv->device, "can't start dmx feed: invalid type %u\n", +- dvbdmxfeed->type); +- return -EINVAL; +- } +- +- if (mutex_lock_interruptible(&fdtv->demux_mutex)) +- return -EINTR; +- +- if (dvbdmxfeed->type == DMX_TYPE_TS) { +- switch (dvbdmxfeed->pes_type) { +- case DMX_TS_PES_VIDEO: +- case DMX_TS_PES_AUDIO: +- case DMX_TS_PES_TELETEXT: +- case DMX_TS_PES_PCR: +- case DMX_TS_PES_OTHER: +- c = alloc_channel(fdtv); +- break; +- default: +- dev_err(fdtv->device, +- "can't start dmx feed: invalid pes type %u\n", +- dvbdmxfeed->pes_type); +- ret = -EINVAL; +- goto out; +- } +- } else { +- c = alloc_channel(fdtv); +- } +- +- if (c > 15) { +- dev_err(fdtv->device, "can't start dmx feed: busy\n"); +- ret = -EBUSY; +- goto out; +- } +- +- dvbdmxfeed->priv = (typeof(dvbdmxfeed->priv))(unsigned long)c; +- fdtv->channel_pid[c] = dvbdmxfeed->pid; +- collect_channels(fdtv, &pidc, pids); +- +- if (dvbdmxfeed->pid == 8192) { +- ret = avc_tuner_get_ts(fdtv); +- if (ret) { +- dealloc_channel(fdtv, c); +- dev_err(fdtv->device, "can't get TS\n"); +- goto out; +- } +- } else { +- ret = avc_tuner_set_pids(fdtv, pidc, pids); +- if (ret) { +- dealloc_channel(fdtv, c); +- dev_err(fdtv->device, "can't set PIDs\n"); +- goto out; +- } +- } +-out: +- mutex_unlock(&fdtv->demux_mutex); +- +- return ret; +-} +- +-int fdtv_stop_feed(struct dvb_demux_feed *dvbdmxfeed) +-{ +- struct dvb_demux *demux = dvbdmxfeed->demux; +- struct firedtv *fdtv = demux->priv; +- int pidc, c, ret; +- u16 pids[16]; +- +- if (dvbdmxfeed->type == DMX_TYPE_TS && +- !((dvbdmxfeed->ts_type & TS_PACKET) && +- (demux->dmx.frontend->source != DMX_MEMORY_FE))) { +- +- if (dvbdmxfeed->ts_type & TS_DECODER) { +- if (dvbdmxfeed->pes_type >= DMX_TS_PES_OTHER || +- !demux->pesfilter[dvbdmxfeed->pes_type]) +- return -EINVAL; +- +- demux->pids[dvbdmxfeed->pes_type] |= 0x8000; +- demux->pesfilter[dvbdmxfeed->pes_type] = NULL; +- } +- +- if (!(dvbdmxfeed->ts_type & TS_DECODER && +- dvbdmxfeed->pes_type < DMX_TS_PES_OTHER)) +- return 0; +- } +- +- if (mutex_lock_interruptible(&fdtv->demux_mutex)) +- return -EINTR; +- +- c = (unsigned long)dvbdmxfeed->priv; +- dealloc_channel(fdtv, c); +- collect_channels(fdtv, &pidc, pids); +- +- ret = avc_tuner_set_pids(fdtv, pidc, pids); +- +- mutex_unlock(&fdtv->demux_mutex); +- +- return ret; +-} +- +-DVB_DEFINE_MOD_OPT_ADAPTER_NR(adapter_nr); +- +-int fdtv_dvb_register(struct firedtv *fdtv) +-{ +- int err; +- +- err = dvb_register_adapter(&fdtv->adapter, fdtv_model_names[fdtv->type], +- THIS_MODULE, fdtv->device, adapter_nr); +- if (err < 0) +- goto fail_log; +- +- /*DMX_TS_FILTERING | DMX_SECTION_FILTERING*/ +- fdtv->demux.dmx.capabilities = 0; +- +- fdtv->demux.priv = fdtv; +- fdtv->demux.filternum = 16; +- fdtv->demux.feednum = 16; +- fdtv->demux.start_feed = fdtv_start_feed; +- fdtv->demux.stop_feed = fdtv_stop_feed; +- fdtv->demux.write_to_decoder = NULL; +- +- err = dvb_dmx_init(&fdtv->demux); +- if (err) +- goto fail_unreg_adapter; +- +- fdtv->dmxdev.filternum = 16; +- fdtv->dmxdev.demux = &fdtv->demux.dmx; +- fdtv->dmxdev.capabilities = 0; +- +- err = dvb_dmxdev_init(&fdtv->dmxdev, &fdtv->adapter); +- if (err) +- goto fail_dmx_release; +- +- fdtv->frontend.source = DMX_FRONTEND_0; +- +- err = fdtv->demux.dmx.add_frontend(&fdtv->demux.dmx, &fdtv->frontend); +- if (err) +- goto fail_dmxdev_release; +- +- err = fdtv->demux.dmx.connect_frontend(&fdtv->demux.dmx, +- &fdtv->frontend); +- if (err) +- goto fail_rem_frontend; +- +- dvb_net_init(&fdtv->adapter, &fdtv->dvbnet, &fdtv->demux.dmx); +- +- fdtv_frontend_init(fdtv); +- err = dvb_register_frontend(&fdtv->adapter, &fdtv->fe); +- if (err) +- goto fail_net_release; +- +- err = fdtv_ca_register(fdtv); +- if (err) +- dev_info(fdtv->device, +- "Conditional Access Module not enabled\n"); +- return 0; +- +-fail_net_release: +- dvb_net_release(&fdtv->dvbnet); +- fdtv->demux.dmx.close(&fdtv->demux.dmx); +-fail_rem_frontend: +- fdtv->demux.dmx.remove_frontend(&fdtv->demux.dmx, &fdtv->frontend); +-fail_dmxdev_release: +- dvb_dmxdev_release(&fdtv->dmxdev); +-fail_dmx_release: +- dvb_dmx_release(&fdtv->demux); +-fail_unreg_adapter: +- dvb_unregister_adapter(&fdtv->adapter); +-fail_log: +- dev_err(fdtv->device, "DVB initialization failed\n"); +- return err; +-} +- +-void fdtv_dvb_unregister(struct firedtv *fdtv) +-{ +- fdtv_ca_release(fdtv); +- dvb_unregister_frontend(&fdtv->fe); +- dvb_net_release(&fdtv->dvbnet); +- fdtv->demux.dmx.close(&fdtv->demux.dmx); +- fdtv->demux.dmx.remove_frontend(&fdtv->demux.dmx, &fdtv->frontend); +- dvb_dmxdev_release(&fdtv->dmxdev); +- dvb_dmx_release(&fdtv->demux); +- dvb_unregister_adapter(&fdtv->adapter); +-} +- +-const char *fdtv_model_names[] = { +- [FIREDTV_UNKNOWN] = "unknown type", +- [FIREDTV_DVB_S] = "FireDTV S/CI", +- [FIREDTV_DVB_C] = "FireDTV C/CI", +- [FIREDTV_DVB_T] = "FireDTV T/CI", +- [FIREDTV_DVB_S2] = "FireDTV S2 ", +-}; +- +-struct firedtv *fdtv_alloc(struct device *dev, +- const struct firedtv_backend *backend, +- const char *name, size_t name_len) +-{ +- struct firedtv *fdtv; +- int i; +- +- fdtv = kzalloc(sizeof(*fdtv), GFP_KERNEL); +- if (!fdtv) +- return NULL; +- +- dev->driver_data = fdtv; +- fdtv->device = dev; +- fdtv->isochannel = -1; +- fdtv->voltage = 0xff; +- fdtv->tone = 0xff; +- fdtv->backend = backend; +- +- mutex_init(&fdtv->avc_mutex); +- init_waitqueue_head(&fdtv->avc_wait); +- fdtv->avc_reply_received = true; +- mutex_init(&fdtv->demux_mutex); +- INIT_WORK(&fdtv->remote_ctrl_work, avc_remote_ctrl_work); +- +- for (i = ARRAY_SIZE(fdtv_model_names); --i; ) +- if (strlen(fdtv_model_names[i]) <= name_len && +- strncmp(name, fdtv_model_names[i], name_len) == 0) +- break; +- fdtv->type = i; +- +- return fdtv; +-} +- +-#define MATCH_FLAGS (IEEE1394_MATCH_VENDOR_ID | IEEE1394_MATCH_MODEL_ID | \ +- IEEE1394_MATCH_SPECIFIER_ID | IEEE1394_MATCH_VERSION) +- +-#define DIGITAL_EVERYWHERE_OUI 0x001287 +-#define AVC_UNIT_SPEC_ID_ENTRY 0x00a02d +-#define AVC_SW_VERSION_ENTRY 0x010001 +- +-static struct ieee1394_device_id fdtv_id_table[] = { +- { +- /* FloppyDTV S/CI and FloppyDTV S2 */ +- .match_flags = MATCH_FLAGS, +- .vendor_id = DIGITAL_EVERYWHERE_OUI, +- .model_id = 0x000024, +- .specifier_id = AVC_UNIT_SPEC_ID_ENTRY, +- .version = AVC_SW_VERSION_ENTRY, +- }, { +- /* FloppyDTV T/CI */ +- .match_flags = MATCH_FLAGS, +- .vendor_id = DIGITAL_EVERYWHERE_OUI, +- .model_id = 0x000025, +- .specifier_id = AVC_UNIT_SPEC_ID_ENTRY, +- .version = AVC_SW_VERSION_ENTRY, +- }, { +- /* FloppyDTV C/CI */ +- .match_flags = MATCH_FLAGS, +- .vendor_id = DIGITAL_EVERYWHERE_OUI, +- .model_id = 0x000026, +- .specifier_id = AVC_UNIT_SPEC_ID_ENTRY, +- .version = AVC_SW_VERSION_ENTRY, +- }, { +- /* FireDTV S/CI and FloppyDTV S2 */ +- .match_flags = MATCH_FLAGS, +- .vendor_id = DIGITAL_EVERYWHERE_OUI, +- .model_id = 0x000034, +- .specifier_id = AVC_UNIT_SPEC_ID_ENTRY, +- .version = AVC_SW_VERSION_ENTRY, +- }, { +- /* FireDTV T/CI */ +- .match_flags = MATCH_FLAGS, +- .vendor_id = DIGITAL_EVERYWHERE_OUI, +- .model_id = 0x000035, +- .specifier_id = AVC_UNIT_SPEC_ID_ENTRY, +- .version = AVC_SW_VERSION_ENTRY, +- }, { +- /* FireDTV C/CI */ +- .match_flags = MATCH_FLAGS, +- .vendor_id = DIGITAL_EVERYWHERE_OUI, +- .model_id = 0x000036, +- .specifier_id = AVC_UNIT_SPEC_ID_ENTRY, +- .version = AVC_SW_VERSION_ENTRY, +- }, {} +-}; +-MODULE_DEVICE_TABLE(ieee1394, fdtv_id_table); +- +-static int __init fdtv_init(void) +-{ +- return fdtv_1394_init(fdtv_id_table); +-} +- +-static void __exit fdtv_exit(void) +-{ +- fdtv_1394_exit(); +-} +- +-module_init(fdtv_init); +-module_exit(fdtv_exit); +- +-MODULE_AUTHOR("Andreas Monitzer <andy@monitzer.com>"); +-MODULE_AUTHOR("Ben Backx <ben@bbackx.com>"); +-MODULE_DESCRIPTION("FireDTV DVB Driver"); +-MODULE_LICENSE("GPL"); +-MODULE_SUPPORTED_DEVICE("FireDTV DVB"); +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/drivers/media/dvb/firewire/firedtv-fe.c linux-2.6.29-rc3.owrt/drivers/media/dvb/firewire/firedtv-fe.c +--- linux-2.6.29.owrt/drivers/media/dvb/firewire/firedtv-fe.c 2009-05-10 22:04:39.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/drivers/media/dvb/firewire/firedtv-fe.c 1970-01-01 01:00:00.000000000 +0100 +@@ -1,247 +0,0 @@ +-/* +- * FireDTV driver (formerly known as FireSAT) +- * +- * Copyright (C) 2004 Andreas Monitzer <andy@monitzer.com> +- * Copyright (C) 2008 Henrik Kurelid <henrik@kurelid.se> +- * +- * 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. +- */ +- +-#include <linux/device.h> +-#include <linux/errno.h> +-#include <linux/kernel.h> +-#include <linux/string.h> +-#include <linux/types.h> +- +-#include <dvb_frontend.h> +- +-#include "firedtv.h" +- +-static int fdtv_dvb_init(struct dvb_frontend *fe) +-{ +- struct firedtv *fdtv = fe->sec_priv; +- int err; +- +- /* FIXME - allocate free channel at IRM */ +- fdtv->isochannel = fdtv->adapter.num; +- +- err = cmp_establish_pp_connection(fdtv, fdtv->subunit, +- fdtv->isochannel); +- if (err) { +- dev_err(fdtv->device, +- "could not establish point to point connection\n"); +- return err; +- } +- +- return fdtv->backend->start_iso(fdtv); +-} +- +-static int fdtv_sleep(struct dvb_frontend *fe) +-{ +- struct firedtv *fdtv = fe->sec_priv; +- +- fdtv->backend->stop_iso(fdtv); +- cmp_break_pp_connection(fdtv, fdtv->subunit, fdtv->isochannel); +- fdtv->isochannel = -1; +- return 0; +-} +- +-#define LNBCONTROL_DONTCARE 0xff +- +-static int fdtv_diseqc_send_master_cmd(struct dvb_frontend *fe, +- struct dvb_diseqc_master_cmd *cmd) +-{ +- struct firedtv *fdtv = fe->sec_priv; +- +- return avc_lnb_control(fdtv, LNBCONTROL_DONTCARE, LNBCONTROL_DONTCARE, +- LNBCONTROL_DONTCARE, 1, cmd); +-} +- +-static int fdtv_diseqc_send_burst(struct dvb_frontend *fe, +- fe_sec_mini_cmd_t minicmd) +-{ +- return 0; +-} +- +-static int fdtv_set_tone(struct dvb_frontend *fe, fe_sec_tone_mode_t tone) +-{ +- struct firedtv *fdtv = fe->sec_priv; +- +- fdtv->tone = tone; +- return 0; +-} +- +-static int fdtv_set_voltage(struct dvb_frontend *fe, +- fe_sec_voltage_t voltage) +-{ +- struct firedtv *fdtv = fe->sec_priv; +- +- fdtv->voltage = voltage; +- return 0; +-} +- +-static int fdtv_read_status(struct dvb_frontend *fe, fe_status_t *status) +-{ +- struct firedtv *fdtv = fe->sec_priv; +- struct firedtv_tuner_status stat; +- +- if (avc_tuner_status(fdtv, &stat)) +- return -EINVAL; +- +- if (stat.no_rf) +- *status = 0; +- else +- *status = FE_HAS_SIGNAL | FE_HAS_VITERBI | FE_HAS_SYNC | +- FE_HAS_CARRIER | FE_HAS_LOCK; +- return 0; +-} +- +-static int fdtv_read_ber(struct dvb_frontend *fe, u32 *ber) +-{ +- struct firedtv *fdtv = fe->sec_priv; +- struct firedtv_tuner_status stat; +- +- if (avc_tuner_status(fdtv, &stat)) +- return -EINVAL; +- +- *ber = stat.ber; +- return 0; +-} +- +-static int fdtv_read_signal_strength(struct dvb_frontend *fe, u16 *strength) +-{ +- struct firedtv *fdtv = fe->sec_priv; +- struct firedtv_tuner_status stat; +- +- if (avc_tuner_status(fdtv, &stat)) +- return -EINVAL; +- +- *strength = stat.signal_strength << 8; +- return 0; +-} +- +-static int fdtv_read_snr(struct dvb_frontend *fe, u16 *snr) +-{ +- struct firedtv *fdtv = fe->sec_priv; +- struct firedtv_tuner_status stat; +- +- if (avc_tuner_status(fdtv, &stat)) +- return -EINVAL; +- +- /* C/N[dB] = -10 * log10(snr / 65535) */ +- *snr = stat.carrier_noise_ratio * 257; +- return 0; +-} +- +-static int fdtv_read_uncorrected_blocks(struct dvb_frontend *fe, u32 *ucblocks) +-{ +- return -EOPNOTSUPP; +-} +- +-#define ACCEPTED 0x9 +- +-static int fdtv_set_frontend(struct dvb_frontend *fe, +- struct dvb_frontend_parameters *params) +-{ +- struct firedtv *fdtv = fe->sec_priv; +- +- /* FIXME: avc_tuner_dsd never returns ACCEPTED. Check status? */ +- if (avc_tuner_dsd(fdtv, params) != ACCEPTED) +- return -EINVAL; +- else +- return 0; /* not sure of this... */ +-} +- +-static int fdtv_get_frontend(struct dvb_frontend *fe, +- struct dvb_frontend_parameters *params) +-{ +- return -EOPNOTSUPP; +-} +- +-void fdtv_frontend_init(struct firedtv *fdtv) +-{ +- struct dvb_frontend_ops *ops = &fdtv->fe.ops; +- struct dvb_frontend_info *fi = &ops->info; +- +- ops->init = fdtv_dvb_init; +- ops->sleep = fdtv_sleep; +- +- ops->set_frontend = fdtv_set_frontend; +- ops->get_frontend = fdtv_get_frontend; +- +- ops->read_status = fdtv_read_status; +- ops->read_ber = fdtv_read_ber; +- ops->read_signal_strength = fdtv_read_signal_strength; +- ops->read_snr = fdtv_read_snr; +- ops->read_ucblocks = fdtv_read_uncorrected_blocks; +- +- ops->diseqc_send_master_cmd = fdtv_diseqc_send_master_cmd; +- ops->diseqc_send_burst = fdtv_diseqc_send_burst; +- ops->set_tone = fdtv_set_tone; +- ops->set_voltage = fdtv_set_voltage; +- +- switch (fdtv->type) { +- case FIREDTV_DVB_S: +- case FIREDTV_DVB_S2: +- fi->type = FE_QPSK; +- +- fi->frequency_min = 950000; +- fi->frequency_max = 2150000; +- fi->frequency_stepsize = 125; +- fi->symbol_rate_min = 1000000; +- fi->symbol_rate_max = 40000000; +- +- fi->caps = FE_CAN_INVERSION_AUTO | +- FE_CAN_FEC_1_2 | +- FE_CAN_FEC_2_3 | +- FE_CAN_FEC_3_4 | +- FE_CAN_FEC_5_6 | +- FE_CAN_FEC_7_8 | +- FE_CAN_FEC_AUTO | +- FE_CAN_QPSK; +- break; +- +- case FIREDTV_DVB_C: +- fi->type = FE_QAM; +- +- fi->frequency_min = 47000000; +- fi->frequency_max = 866000000; +- fi->frequency_stepsize = 62500; +- fi->symbol_rate_min = 870000; +- fi->symbol_rate_max = 6900000; +- +- fi->caps = FE_CAN_INVERSION_AUTO | +- FE_CAN_QAM_16 | +- FE_CAN_QAM_32 | +- FE_CAN_QAM_64 | +- FE_CAN_QAM_128 | +- FE_CAN_QAM_256 | +- FE_CAN_QAM_AUTO; +- break; +- +- case FIREDTV_DVB_T: +- fi->type = FE_OFDM; +- +- fi->frequency_min = 49000000; +- fi->frequency_max = 861000000; +- fi->frequency_stepsize = 62500; +- +- fi->caps = FE_CAN_INVERSION_AUTO | +- FE_CAN_FEC_2_3 | +- FE_CAN_TRANSMISSION_MODE_AUTO | +- FE_CAN_GUARD_INTERVAL_AUTO | +- FE_CAN_HIERARCHY_AUTO; +- break; +- +- default: +- dev_err(fdtv->device, "no frontend for model type %d\n", +- fdtv->type); +- } +- strcpy(fi->name, fdtv_model_names[fdtv->type]); +- +- fdtv->fe.dvb = &fdtv->adapter; +- fdtv->fe.sec_priv = fdtv; +-} +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/drivers/media/dvb/firewire/firedtv.h linux-2.6.29-rc3.owrt/drivers/media/dvb/firewire/firedtv.h +--- linux-2.6.29.owrt/drivers/media/dvb/firewire/firedtv.h 2009-05-10 22:04:39.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/drivers/media/dvb/firewire/firedtv.h 1970-01-01 01:00:00.000000000 +0100 +@@ -1,182 +0,0 @@ +-/* +- * FireDTV driver (formerly known as FireSAT) +- * +- * Copyright (C) 2004 Andreas Monitzer <andy@monitzer.com> +- * Copyright (C) 2008 Henrik Kurelid <henrik@kurelid.se> +- * +- * 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. +- */ +- +-#ifndef _FIREDTV_H +-#define _FIREDTV_H +- +-#include <linux/dvb/dmx.h> +-#include <linux/dvb/frontend.h> +-#include <linux/list.h> +-#include <linux/mutex.h> +-#include <linux/spinlock_types.h> +-#include <linux/types.h> +-#include <linux/wait.h> +-#include <linux/workqueue.h> +- +-#include <demux.h> +-#include <dmxdev.h> +-#include <dvb_demux.h> +-#include <dvb_frontend.h> +-#include <dvb_net.h> +-#include <dvbdev.h> +- +-struct firedtv_tuner_status { +- unsigned active_system:8; +- unsigned searching:1; +- unsigned moving:1; +- unsigned no_rf:1; +- unsigned input:1; +- unsigned selected_antenna:7; +- unsigned ber:32; +- unsigned signal_strength:8; +- unsigned raster_frequency:2; +- unsigned rf_frequency:22; +- unsigned man_dep_info_length:8; +- unsigned front_end_error:1; +- unsigned antenna_error:1; +- unsigned front_end_power_status:1; +- unsigned power_supply:1; +- unsigned carrier_noise_ratio:16; +- unsigned power_supply_voltage:8; +- unsigned antenna_voltage:8; +- unsigned firewire_bus_voltage:8; +- unsigned ca_mmi:1; +- unsigned ca_pmt_reply:1; +- unsigned ca_date_time_request:1; +- unsigned ca_application_info:1; +- unsigned ca_module_present_status:1; +- unsigned ca_dvb_flag:1; +- unsigned ca_error_flag:1; +- unsigned ca_initialization_status:1; +-}; +- +-enum model_type { +- FIREDTV_UNKNOWN = 0, +- FIREDTV_DVB_S = 1, +- FIREDTV_DVB_C = 2, +- FIREDTV_DVB_T = 3, +- FIREDTV_DVB_S2 = 4, +-}; +- +-struct device; +-struct input_dev; +-struct firedtv; +- +-struct firedtv_backend { +- int (*lock)(struct firedtv *fdtv, u64 addr, void *data, __be32 arg); +- int (*read)(struct firedtv *fdtv, u64 addr, void *data, size_t len); +- int (*write)(struct firedtv *fdtv, u64 addr, void *data, size_t len); +- int (*start_iso)(struct firedtv *fdtv); +- void (*stop_iso)(struct firedtv *fdtv); +-}; +- +-struct firedtv { +- struct device *device; +- struct list_head list; +- +- struct dvb_adapter adapter; +- struct dmxdev dmxdev; +- struct dvb_demux demux; +- struct dmx_frontend frontend; +- struct dvb_net dvbnet; +- struct dvb_frontend fe; +- +- struct dvb_device *cadev; +- int ca_last_command; +- int ca_time_interval; +- +- struct mutex avc_mutex; +- wait_queue_head_t avc_wait; +- bool avc_reply_received; +- struct work_struct remote_ctrl_work; +- struct input_dev *remote_ctrl_dev; +- +- enum model_type type; +- char subunit; +- char isochannel; +- fe_sec_voltage_t voltage; +- fe_sec_tone_mode_t tone; +- +- const struct firedtv_backend *backend; +- void *backend_data; +- +- struct mutex demux_mutex; +- unsigned long channel_active; +- u16 channel_pid[16]; +- +- size_t response_length; +- u8 response[512]; +-}; +- +-/* firedtv-1394.c */ +-#ifdef CONFIG_DVB_FIREDTV_IEEE1394 +-int fdtv_1394_init(struct ieee1394_device_id id_table[]); +-void fdtv_1394_exit(void); +-#else +-static inline int fdtv_1394_init(struct ieee1394_device_id it[]) { return 0; } +-static inline void fdtv_1394_exit(void) {} +-#endif +- +-/* firedtv-avc.c */ +-int avc_recv(struct firedtv *fdtv, void *data, size_t length); +-int avc_tuner_status(struct firedtv *fdtv, struct firedtv_tuner_status *stat); +-struct dvb_frontend_parameters; +-int avc_tuner_dsd(struct firedtv *fdtv, struct dvb_frontend_parameters *params); +-int avc_tuner_set_pids(struct firedtv *fdtv, unsigned char pidc, u16 pid[]); +-int avc_tuner_get_ts(struct firedtv *fdtv); +-int avc_identify_subunit(struct firedtv *fdtv); +-struct dvb_diseqc_master_cmd; +-int avc_lnb_control(struct firedtv *fdtv, char voltage, char burst, +- char conttone, char nrdiseq, +- struct dvb_diseqc_master_cmd *diseqcmd); +-void avc_remote_ctrl_work(struct work_struct *work); +-int avc_register_remote_control(struct firedtv *fdtv); +-int avc_ca_app_info(struct firedtv *fdtv, char *app_info, unsigned int *len); +-int avc_ca_info(struct firedtv *fdtv, char *app_info, unsigned int *len); +-int avc_ca_reset(struct firedtv *fdtv); +-int avc_ca_pmt(struct firedtv *fdtv, char *app_info, int length); +-int avc_ca_get_time_date(struct firedtv *fdtv, int *interval); +-int avc_ca_enter_menu(struct firedtv *fdtv); +-int avc_ca_get_mmi(struct firedtv *fdtv, char *mmi_object, unsigned int *len); +-int cmp_establish_pp_connection(struct firedtv *fdtv, int plug, int channel); +-void cmp_break_pp_connection(struct firedtv *fdtv, int plug, int channel); +- +-/* firedtv-ci.c */ +-int fdtv_ca_register(struct firedtv *fdtv); +-void fdtv_ca_release(struct firedtv *fdtv); +- +-/* firedtv-dvb.c */ +-int fdtv_start_feed(struct dvb_demux_feed *dvbdmxfeed); +-int fdtv_stop_feed(struct dvb_demux_feed *dvbdmxfeed); +-int fdtv_dvb_register(struct firedtv *fdtv); +-void fdtv_dvb_unregister(struct firedtv *fdtv); +-struct firedtv *fdtv_alloc(struct device *dev, +- const struct firedtv_backend *backend, +- const char *name, size_t name_len); +-extern const char *fdtv_model_names[]; +- +-/* firedtv-fe.c */ +-void fdtv_frontend_init(struct firedtv *fdtv); +- +-/* firedtv-rc.c */ +-#ifdef CONFIG_DVB_FIREDTV_INPUT +-int fdtv_register_rc(struct firedtv *fdtv, struct device *dev); +-void fdtv_unregister_rc(struct firedtv *fdtv); +-void fdtv_handle_rc(struct firedtv *fdtv, unsigned int code); +-#else +-static inline int fdtv_register_rc(struct firedtv *fdtv, +- struct device *dev) { return 0; } +-static inline void fdtv_unregister_rc(struct firedtv *fdtv) {} +-static inline void fdtv_handle_rc(struct firedtv *fdtv, unsigned int code) {} +-#endif +- +-#endif /* _FIREDTV_H */ +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/drivers/media/dvb/firewire/firedtv-rc.c linux-2.6.29-rc3.owrt/drivers/media/dvb/firewire/firedtv-rc.c +--- linux-2.6.29.owrt/drivers/media/dvb/firewire/firedtv-rc.c 2009-05-10 22:04:39.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/drivers/media/dvb/firewire/firedtv-rc.c 1970-01-01 01:00:00.000000000 +0100 +@@ -1,190 +0,0 @@ +-/* +- * FireDTV driver (formerly known as FireSAT) +- * +- * Copyright (C) 2004 Andreas Monitzer <andy@monitzer.com> +- * +- * 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. +- */ +- +-#include <linux/bitops.h> +-#include <linux/input.h> +-#include <linux/kernel.h> +-#include <linux/string.h> +-#include <linux/types.h> +- +-#include "firedtv.h" +- +-/* fixed table with older keycodes, geared towards MythTV */ +-const static u16 oldtable[] = { +- +- /* code from device: 0x4501...0x451f */ +- +- KEY_ESC, +- KEY_F9, +- KEY_1, +- KEY_2, +- KEY_3, +- KEY_4, +- KEY_5, +- KEY_6, +- KEY_7, +- KEY_8, +- KEY_9, +- KEY_I, +- KEY_0, +- KEY_ENTER, +- KEY_RED, +- KEY_UP, +- KEY_GREEN, +- KEY_F10, +- KEY_SPACE, +- KEY_F11, +- KEY_YELLOW, +- KEY_DOWN, +- KEY_BLUE, +- KEY_Z, +- KEY_P, +- KEY_PAGEDOWN, +- KEY_LEFT, +- KEY_W, +- KEY_RIGHT, +- KEY_P, +- KEY_M, +- +- /* code from device: 0x4540...0x4542 */ +- +- KEY_R, +- KEY_V, +- KEY_C, +-}; +- +-/* user-modifiable table for a remote as sold in 2008 */ +-const static u16 keytable[] = { +- +- /* code from device: 0x0300...0x031f */ +- +- [0x00] = KEY_POWER, +- [0x01] = KEY_SLEEP, +- [0x02] = KEY_STOP, +- [0x03] = KEY_OK, +- [0x04] = KEY_RIGHT, +- [0x05] = KEY_1, +- [0x06] = KEY_2, +- [0x07] = KEY_3, +- [0x08] = KEY_LEFT, +- [0x09] = KEY_4, +- [0x0a] = KEY_5, +- [0x0b] = KEY_6, +- [0x0c] = KEY_UP, +- [0x0d] = KEY_7, +- [0x0e] = KEY_8, +- [0x0f] = KEY_9, +- [0x10] = KEY_DOWN, +- [0x11] = KEY_TITLE, /* "OSD" - fixme */ +- [0x12] = KEY_0, +- [0x13] = KEY_F20, /* "16:9" - fixme */ +- [0x14] = KEY_SCREEN, /* "FULL" - fixme */ +- [0x15] = KEY_MUTE, +- [0x16] = KEY_SUBTITLE, +- [0x17] = KEY_RECORD, +- [0x18] = KEY_TEXT, +- [0x19] = KEY_AUDIO, +- [0x1a] = KEY_RED, +- [0x1b] = KEY_PREVIOUS, +- [0x1c] = KEY_REWIND, +- [0x1d] = KEY_PLAYPAUSE, +- [0x1e] = KEY_NEXT, +- [0x1f] = KEY_VOLUMEUP, +- +- /* code from device: 0x0340...0x0354 */ +- +- [0x20] = KEY_CHANNELUP, +- [0x21] = KEY_F21, /* "4:3" - fixme */ +- [0x22] = KEY_TV, +- [0x23] = KEY_DVD, +- [0x24] = KEY_VCR, +- [0x25] = KEY_AUX, +- [0x26] = KEY_GREEN, +- [0x27] = KEY_YELLOW, +- [0x28] = KEY_BLUE, +- [0x29] = KEY_CHANNEL, /* "CH.LIST" */ +- [0x2a] = KEY_VENDOR, /* "CI" - fixme */ +- [0x2b] = KEY_VOLUMEDOWN, +- [0x2c] = KEY_CHANNELDOWN, +- [0x2d] = KEY_LAST, +- [0x2e] = KEY_INFO, +- [0x2f] = KEY_FORWARD, +- [0x30] = KEY_LIST, +- [0x31] = KEY_FAVORITES, +- [0x32] = KEY_MENU, +- [0x33] = KEY_EPG, +- [0x34] = KEY_EXIT, +-}; +- +-int fdtv_register_rc(struct firedtv *fdtv, struct device *dev) +-{ +- struct input_dev *idev; +- int i, err; +- +- idev = input_allocate_device(); +- if (!idev) +- return -ENOMEM; +- +- fdtv->remote_ctrl_dev = idev; +- idev->name = "FireDTV remote control"; +- idev->dev.parent = dev; +- idev->evbit[0] = BIT_MASK(EV_KEY); +- idev->keycode = kmemdup(keytable, sizeof(keytable), GFP_KERNEL); +- if (!idev->keycode) { +- err = -ENOMEM; +- goto fail; +- } +- idev->keycodesize = sizeof(keytable[0]); +- idev->keycodemax = ARRAY_SIZE(keytable); +- +- for (i = 0; i < ARRAY_SIZE(keytable); i++) +- set_bit(keytable[i], idev->keybit); +- +- err = input_register_device(idev); +- if (err) +- goto fail_free_keymap; +- +- return 0; +- +-fail_free_keymap: +- kfree(idev->keycode); +-fail: +- input_free_device(idev); +- return err; +-} +- +-void fdtv_unregister_rc(struct firedtv *fdtv) +-{ +- kfree(fdtv->remote_ctrl_dev->keycode); +- input_unregister_device(fdtv->remote_ctrl_dev); +-} +- +-void fdtv_handle_rc(struct firedtv *fdtv, unsigned int code) +-{ +- u16 *keycode = fdtv->remote_ctrl_dev->keycode; +- +- if (code >= 0x0300 && code <= 0x031f) +- code = keycode[code - 0x0300]; +- else if (code >= 0x0340 && code <= 0x0354) +- code = keycode[code - 0x0320]; +- else if (code >= 0x4501 && code <= 0x451f) +- code = oldtable[code - 0x4501]; +- else if (code >= 0x4540 && code <= 0x4542) +- code = oldtable[code - 0x4521]; +- else { +- printk(KERN_DEBUG "firedtv: invalid key code 0x%04x " +- "from remote control\n", code); +- return; +- } +- +- input_report_key(fdtv->remote_ctrl_dev, code, 1); +- input_report_key(fdtv->remote_ctrl_dev, code, 0); +-} +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/drivers/media/dvb/firewire/Kconfig linux-2.6.29-rc3.owrt/drivers/media/dvb/firewire/Kconfig +--- linux-2.6.29.owrt/drivers/media/dvb/firewire/Kconfig 2009-05-10 22:04:39.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/drivers/media/dvb/firewire/Kconfig 1970-01-01 01:00:00.000000000 +0100 +@@ -1,22 +0,0 @@ +-config DVB_FIREDTV +- tristate "FireDTV and FloppyDTV" +- depends on DVB_CORE && IEEE1394 +- help +- Support for DVB receivers from Digital Everywhere +- which are connected via IEEE 1394 (FireWire). +- +- These devices don't have an MPEG decoder built in, +- so you need an external software decoder to watch TV. +- +- To compile this driver as a module, say M here: +- the module will be called firedtv. +- +-if DVB_FIREDTV +- +-config DVB_FIREDTV_IEEE1394 +- def_bool IEEE1394 +- +-config DVB_FIREDTV_INPUT +- def_bool INPUT = y || (INPUT = m && DVB_FIREDTV = m) +- +-endif # DVB_FIREDTV +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/drivers/media/dvb/firewire/Makefile linux-2.6.29-rc3.owrt/drivers/media/dvb/firewire/Makefile +--- linux-2.6.29.owrt/drivers/media/dvb/firewire/Makefile 2009-05-10 22:04:39.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/drivers/media/dvb/firewire/Makefile 1970-01-01 01:00:00.000000000 +0100 +@@ -1,8 +0,0 @@ +-obj-$(CONFIG_DVB_FIREDTV) += firedtv.o +- +-firedtv-y := firedtv-avc.o firedtv-ci.o firedtv-dvb.o firedtv-fe.o +-firedtv-$(CONFIG_DVB_FIREDTV_IEEE1394) += firedtv-1394.o +-firedtv-$(CONFIG_DVB_FIREDTV_INPUT) += firedtv-rc.o +- +-ccflags-y += -Idrivers/media/dvb/dvb-core +-ccflags-$(CONFIG_DVB_FIREDTV_IEEE1394) += -Idrivers/ieee1394 +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/drivers/media/dvb/frontends/drx397xD.c linux-2.6.29-rc3.owrt/drivers/media/dvb/frontends/drx397xD.c +--- linux-2.6.29.owrt/drivers/media/dvb/frontends/drx397xD.c 2009-05-10 22:04:39.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/drivers/media/dvb/frontends/drx397xD.c 2009-05-10 23:48:28.000000000 +0200 +@@ -646,7 +646,7 @@ + u32 edi = 0, ebx = 0, ebp = 0, edx = 0; + u16 v20 = 0, v1E = 0, v16 = 0, v14 = 0, v12 = 0, v10 = 0, v0E = 0; + +- int rc, df_tuner = 0; ++ int rc, df_tuner; + int a, b, c, d; + pr_debug("%s %d\n", __func__, s->config.d60); + +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/drivers/media/dvb/frontends/s5h1409.c linux-2.6.29-rc3.owrt/drivers/media/dvb/frontends/s5h1409.c +--- linux-2.6.29.owrt/drivers/media/dvb/frontends/s5h1409.c 2009-05-10 22:04:39.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/drivers/media/dvb/frontends/s5h1409.c 2009-05-10 23:48:28.000000000 +0200 +@@ -545,6 +545,9 @@ + + s5h1409_enable_modulation(fe, p->u.vsb.modulation); + ++ /* Allow the demod to settle */ ++ msleep(100); ++ + if (fe->ops.tuner_ops.set_params) { + if (fe->ops.i2c_gate_ctrl) + fe->ops.i2c_gate_ctrl(fe, 1); +@@ -559,10 +562,6 @@ + s5h1409_set_qam_interleave_mode(fe); + } + +- /* Issue a reset to the demod so it knows to resync against the +- newly tuned frequency */ +- s5h1409_softreset(fe); +- + return 0; + } + +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/drivers/media/dvb/frontends/stb0899_algo.c linux-2.6.29-rc3.owrt/drivers/media/dvb/frontends/stb0899_algo.c +--- linux-2.6.29.owrt/drivers/media/dvb/frontends/stb0899_algo.c 2009-05-10 22:04:39.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/drivers/media/dvb/frontends/stb0899_algo.c 2009-05-10 23:48:28.000000000 +0200 +@@ -31,8 +31,6 @@ + return n; + } + +-#if 0 +-/* These functions are currently unused */ + /* + * stb0899_calc_srate + * Compute symbol rate +@@ -65,7 +63,6 @@ + + return stb0899_calc_srate(internal->master_clk, sfr); + } +-#endif + + /* + * stb0899_set_srate +@@ -156,7 +153,7 @@ + } + + if (range > 0) +- internal->sub_range = min(internal->srch_range, range); ++ internal->sub_range = MIN(internal->srch_range, range); + else + internal->sub_range = 0; + +@@ -185,7 +182,7 @@ + timing = stb0899_read_reg(state, STB0899_RTF); + + if (lock >= 42) { +- if ((lock > 48) && (abs(timing) >= 110)) { ++ if ((lock > 48) && (ABS(timing) >= 110)) { + internal->status = ANALOGCARRIER; + dprintk(state->verbose, FE_DEBUG, 1, "-->ANALOG Carrier !"); + } else { +@@ -222,7 +219,7 @@ + index++; + derot_freq += index * internal->direction * derot_step; /* next derot zig zag position */ + +- if (abs(derot_freq) > derot_limit) ++ if (ABS(derot_freq) > derot_limit) + next_loop--; + + if (next_loop) { +@@ -298,7 +295,7 @@ + last_derot_freq = derot_freq; + derot_freq += index * internal->direction * internal->derot_step; /* next zig zag derotator position */ + +- if(abs(derot_freq) > derot_limit) ++ if(ABS(derot_freq) > derot_limit) + next_loop--; + + if (next_loop) { +@@ -400,7 +397,7 @@ + if ((internal->status != CARRIEROK) || (stb0899_check_data(state) != DATAOK)) { + + derot_freq += index * internal->direction * derot_step; /* next zig zag derotator position */ +- if (abs(derot_freq) > derot_limit) ++ if (ABS(derot_freq) > derot_limit) + next_loop--; + + if (next_loop) { +@@ -467,7 +464,7 @@ + + if (internal->sub_dir > 0) { + old_sub_range = internal->sub_range; +- internal->sub_range = min((internal->srch_range / 2) - ++ internal->sub_range = MIN((internal->srch_range / 2) - + (internal->tuner_offst + internal->sub_range / 2), + internal->sub_range); + +@@ -771,7 +768,7 @@ + int i; + + i = 0; +- while ((1 << i) <= abs(number)) ++ while ((1 << i) <= ABS(number)) + i++; + + if (number == 0) +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/drivers/media/dvb/frontends/stb0899_drv.c linux-2.6.29-rc3.owrt/drivers/media/dvb/frontends/stb0899_drv.c +--- linux-2.6.29.owrt/drivers/media/dvb/frontends/stb0899_drv.c 2009-05-10 22:04:39.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/drivers/media/dvb/frontends/stb0899_drv.c 2009-05-10 23:48:28.000000000 +0200 +@@ -794,7 +794,7 @@ + reg = stb0899_read_reg(state, STB0899_DISCNTRL1); + old_state = reg; + /* set to burst mode */ +- STB0899_SETFIELD_VAL(DISEQCMODE, reg, 0x03); ++ STB0899_SETFIELD_VAL(DISEQCMODE, reg, 0x02); + STB0899_SETFIELD_VAL(DISPRECHARGE, reg, 0x01); + stb0899_write_reg(state, STB0899_DISCNTRL1, reg); + switch (burst) { +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/drivers/media/dvb/frontends/stb0899_priv.h linux-2.6.29-rc3.owrt/drivers/media/dvb/frontends/stb0899_priv.h +--- linux-2.6.29.owrt/drivers/media/dvb/frontends/stb0899_priv.h 2009-05-10 22:04:39.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/drivers/media/dvb/frontends/stb0899_priv.h 2009-05-10 23:48:28.000000000 +0200 +@@ -59,6 +59,10 @@ + #define MAKEWORD32(a, b, c, d) (((a) << 24) | ((b) << 16) | ((c) << 8) | (d)) + #define MAKEWORD16(a, b) (((a) << 8) | (b)) + ++#define MIN(x, y) ((x) <= (y) ? (x) : (y)) ++#define MAX(x, y) ((x) >= (y) ? (x) : (y)) ++#define ABS(x) ((x) >= 0 ? (x) : -(x)) ++ + #define LSB(x) ((x & 0xff)) + #define MSB(y) ((y >> 8) & 0xff) + +@@ -164,10 +168,10 @@ + u32 freq; /* Demod internal Frequency */ + u32 srate; /* Demod internal Symbol rate */ + enum stb0899_fec fecrate; /* Demod internal FEC rate */ +- s32 srch_range; /* Demod internal Search Range */ +- s32 sub_range; /* Demod current sub range (Hz) */ +- s32 tuner_step; /* Tuner step (Hz) */ +- s32 tuner_offst; /* Relative offset to carrier (Hz) */ ++ u32 srch_range; /* Demod internal Search Range */ ++ u32 sub_range; /* Demod current sub range (Hz) */ ++ u32 tuner_step; /* Tuner step (Hz) */ ++ u32 tuner_offst; /* Relative offset to carrier (Hz) */ + u32 tuner_bw; /* Current bandwidth of the tuner (Hz) */ + + s32 mclk; /* Masterclock Divider factor (binary) */ +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/drivers/media/dvb/frontends/stb6100.c linux-2.6.29-rc3.owrt/drivers/media/dvb/frontends/stb6100.c +--- linux-2.6.29.owrt/drivers/media/dvb/frontends/stb6100.c 2009-05-10 22:04:39.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/drivers/media/dvb/frontends/stb6100.c 2009-05-10 23:48:28.000000000 +0200 +@@ -427,11 +427,11 @@ + status->refclock = 27000000; /* Hz */ + status->iqsense = 1; + status->bandwidth = 36000; /* kHz */ +- state->bandwidth = status->bandwidth * 1000; /* Hz */ ++ state->bandwidth = status->bandwidth * 1000; /* MHz */ + state->reference = status->refclock / 1000; /* kHz */ + + /* Set default bandwidth. */ +- return stb6100_set_bandwidth(fe, state->bandwidth); ++ return stb6100_set_bandwidth(fe, status->bandwidth); + } + + static int stb6100_get_state(struct dvb_frontend *fe, +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/drivers/media/dvb/frontends/zl10353.c linux-2.6.29-rc3.owrt/drivers/media/dvb/frontends/zl10353.c +--- linux-2.6.29.owrt/drivers/media/dvb/frontends/zl10353.c 2009-05-10 22:04:39.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/drivers/media/dvb/frontends/zl10353.c 2009-05-10 23:48:28.000000000 +0200 +@@ -590,7 +590,7 @@ + struct zl10353_state *state = fe->demodulator_priv; + u8 val = 0x0a; + +- if (state->config.disable_i2c_gate_ctrl) { ++ if (state->config.no_tuner) { + /* No tuner attached to the internal I2C bus */ + /* If set enable I2C bridge, the main I2C bus stopped hardly */ + return 0; +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/drivers/media/dvb/frontends/zl10353.h linux-2.6.29-rc3.owrt/drivers/media/dvb/frontends/zl10353.h +--- linux-2.6.29.owrt/drivers/media/dvb/frontends/zl10353.h 2009-05-10 22:04:39.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/drivers/media/dvb/frontends/zl10353.h 2009-05-10 23:48:28.000000000 +0200 +@@ -38,9 +38,6 @@ + + /* set if parallel ts output is required */ + int parallel_ts; +- +- /* set if i2c_gate_ctrl disable is required */ +- u8 disable_i2c_gate_ctrl:1; + }; + + #if defined(CONFIG_DVB_ZL10353) || (defined(CONFIG_DVB_ZL10353_MODULE) && defined(MODULE)) +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/drivers/media/dvb/Kconfig linux-2.6.29-rc3.owrt/drivers/media/dvb/Kconfig +--- linux-2.6.29.owrt/drivers/media/dvb/Kconfig 2009-05-10 22:04:39.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/drivers/media/dvb/Kconfig 2009-05-10 23:48:28.000000000 +0200 +@@ -51,10 +51,6 @@ + depends on DVB_CORE && PCI && I2C + source "drivers/media/dvb/dm1105/Kconfig" + +-comment "Supported FireWire (IEEE 1394) Adapters" +- depends on DVB_CORE && IEEE1394 +-source "drivers/media/dvb/firewire/Kconfig" +- + comment "Supported DVB Frontends" + depends on DVB_CORE + source "drivers/media/dvb/frontends/Kconfig" +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/drivers/media/dvb/Makefile linux-2.6.29-rc3.owrt/drivers/media/dvb/Makefile +--- linux-2.6.29.owrt/drivers/media/dvb/Makefile 2009-05-10 22:04:39.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/drivers/media/dvb/Makefile 2009-05-10 23:48:28.000000000 +0200 +@@ -3,5 +3,3 @@ + # + + obj-y := dvb-core/ frontends/ ttpci/ ttusb-dec/ ttusb-budget/ b2c2/ bt8xx/ dvb-usb/ pluto2/ siano/ dm1105/ +- +-obj-$(CONFIG_DVB_FIREDTV) += firewire/ +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/drivers/media/dvb/ttpci/budget.c linux-2.6.29-rc3.owrt/drivers/media/dvb/ttpci/budget.c +--- linux-2.6.29.owrt/drivers/media/dvb/ttpci/budget.c 2009-05-10 22:04:39.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/drivers/media/dvb/ttpci/budget.c 2009-05-10 23:48:28.000000000 +0200 +@@ -470,7 +470,6 @@ + budget->dvb_frontend = dvb_attach(l64781_attach, &grundig_29504_401_config, &budget->i2c_adap); + if (budget->dvb_frontend) { + budget->dvb_frontend->ops.tuner_ops.set_params = grundig_29504_401_tuner_set_params; +- budget->dvb_frontend->tuner_priv = NULL; + break; + } + break; +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/drivers/media/dvb/ttusb-dec/ttusb_dec.c linux-2.6.29-rc3.owrt/drivers/media/dvb/ttusb-dec/ttusb_dec.c +--- linux-2.6.29.owrt/drivers/media/dvb/ttusb-dec/ttusb_dec.c 2009-05-10 22:04:39.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/drivers/media/dvb/ttusb-dec/ttusb_dec.c 2009-05-10 23:48:28.000000000 +0200 +@@ -1384,7 +1384,7 @@ + static int ttusb_dec_init_stb(struct ttusb_dec *dec) + { + int result; +- unsigned int mode = 0, model = 0, version = 0; ++ unsigned int mode, model, version; + + dprintk("%s\n", __func__); + +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/drivers/media/radio/radio-mr800.c linux-2.6.29-rc3.owrt/drivers/media/radio/radio-mr800.c +--- linux-2.6.29.owrt/drivers/media/radio/radio-mr800.c 2009-05-10 22:04:39.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/drivers/media/radio/radio-mr800.c 2009-05-10 23:48:28.000000000 +0200 +@@ -194,10 +194,10 @@ + return retval; + } + +- radio->muted = 0; +- + mutex_unlock(&radio->lock); + ++ radio->muted = 0; ++ + return retval; + } + +@@ -230,10 +230,10 @@ + return retval; + } + +- radio->muted = 1; +- + mutex_unlock(&radio->lock); + ++ radio->muted = 1; ++ + return retval; + } + +@@ -284,10 +284,10 @@ + return retval; + } + +- radio->stereo = 0; +- + mutex_unlock(&radio->lock); + ++ radio->stereo = 0; ++ + return retval; + } + +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/drivers/media/radio/radio-si470x.c linux-2.6.29-rc3.owrt/drivers/media/radio/radio-si470x.c +--- linux-2.6.29.owrt/drivers/media/radio/radio-si470x.c 2009-05-10 22:04:39.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/drivers/media/radio/radio-si470x.c 2009-05-10 23:48:28.000000000 +0200 +@@ -98,16 +98,11 @@ + * - blacklisted KWorld radio in hid-core.c and hid-ids.h + * 2008-12-03 Mark Lord <mlord@pobox.com> + * - add support for DealExtreme USB Radio +- * 2009-01-31 Bob Ross <pigiron@gmx.com> +- * - correction of stereo detection/setting +- * - correction of signal strength indicator scaling +- * 2009-01-31 Rick Bronson <rick@efn.org> +- * Tobias Lorenz <tobias.lorenz@gmx.net> +- * - add LED status output + * + * ToDo: + * - add firmware download/update support + * - RDS support: interrupt mode, instead of polling ++ * - add LED status output (check if that's not already done in firmware) + */ + + +@@ -887,30 +882,6 @@ + + + /************************************************************************** +- * General Driver Functions - LED_REPORT +- **************************************************************************/ +- +-/* +- * si470x_set_led_state - sets the led state +- */ +-static int si470x_set_led_state(struct si470x_device *radio, +- unsigned char led_state) +-{ +- unsigned char buf[LED_REPORT_SIZE]; +- int retval; +- +- buf[0] = LED_REPORT; +- buf[1] = LED_COMMAND; +- buf[2] = led_state; +- +- retval = si470x_set_report(radio, (void *) &buf, sizeof(buf)); +- +- return (retval < 0) ? -EINVAL : 0; +-} +- +- +- +-/************************************************************************** + * RDS Driver Functions + **************************************************************************/ + +@@ -1414,22 +1385,20 @@ + }; + + /* stereo indicator == stereo (instead of mono) */ +- if ((radio->registers[STATUSRSSI] & STATUSRSSI_ST) == 0) +- tuner->rxsubchans = V4L2_TUNER_SUB_MONO; +- else ++ if ((radio->registers[STATUSRSSI] & STATUSRSSI_ST) == 1) + tuner->rxsubchans = V4L2_TUNER_SUB_MONO | V4L2_TUNER_SUB_STEREO; ++ else ++ tuner->rxsubchans = V4L2_TUNER_SUB_MONO; + + /* mono/stereo selector */ +- if ((radio->registers[POWERCFG] & POWERCFG_MONO) == 0) +- tuner->audmode = V4L2_TUNER_MODE_STEREO; +- else ++ if ((radio->registers[POWERCFG] & POWERCFG_MONO) == 1) + tuner->audmode = V4L2_TUNER_MODE_MONO; ++ else ++ tuner->audmode = V4L2_TUNER_MODE_STEREO; + + /* min is worst, max is best; signal:0..0xffff; rssi: 0..0xff */ +- /* measured in units of dbµV in 1 db increments (max at ~75 dbµV) */ +- tuner->signal = (radio->registers[STATUSRSSI] & STATUSRSSI_RSSI); +- /* the ideal factor is 0xffff/75 = 873,8 */ +- tuner->signal = (tuner->signal * 873) + (8 * tuner->signal / 10); ++ tuner->signal = (radio->registers[STATUSRSSI] & STATUSRSSI_RSSI) ++ * 0x0101; + + /* automatic frequency control: -1: freq to low, 1 freq to high */ + /* AFCRL does only indicate that freq. differs, not if too low/high */ +@@ -1663,9 +1632,6 @@ + /* set initial frequency */ + si470x_set_freq(radio, 87.5 * FREQ_MUL); /* available in all regions */ + +- /* set led to connect state */ +- si470x_set_led_state(radio, BLINK_GREEN_LED); +- + /* rds buffer allocation */ + radio->buf_size = rds_buf * 3; + radio->buffer = kmalloc(radio->buf_size, GFP_KERNEL); +@@ -1749,9 +1715,6 @@ + cancel_delayed_work_sync(&radio->work); + usb_set_intfdata(intf, NULL); + if (radio->users == 0) { +- /* set led to disconnect state */ +- si470x_set_led_state(radio, BLINK_ORANGE_LED); +- + video_unregister_device(radio->videodev); + kfree(radio->buffer); + kfree(radio); +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/drivers/media/video/cs5345.c linux-2.6.29-rc3.owrt/drivers/media/video/cs5345.c +--- linux-2.6.29.owrt/drivers/media/video/cs5345.c 2009-05-10 22:04:38.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/drivers/media/video/cs5345.c 2009-05-10 23:48:28.000000000 +0200 +@@ -18,6 +18,7 @@ + */ + + ++#include <linux/version.h> + #include <linux/module.h> + #include <linux/kernel.h> + #include <linux/i2c.h> +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/drivers/media/video/cx23885/cx23885-417.c linux-2.6.29-rc3.owrt/drivers/media/video/cx23885/cx23885-417.c +--- linux-2.6.29.owrt/drivers/media/video/cx23885/cx23885-417.c 2009-05-10 22:04:38.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/drivers/media/video/cx23885/cx23885-417.c 2009-05-10 23:48:28.000000000 +0200 +@@ -1586,8 +1586,7 @@ + lock_kernel(); + list_for_each(list, &cx23885_devlist) { + h = list_entry(list, struct cx23885_dev, devlist); +- if (h->v4l_device && +- h->v4l_device->minor == minor) { ++ if (h->v4l_device->minor == minor) { + dev = h; + break; + } +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/drivers/media/video/cx23885/cx23885-video.c linux-2.6.29-rc3.owrt/drivers/media/video/cx23885/cx23885-video.c +--- linux-2.6.29.owrt/drivers/media/video/cx23885/cx23885-video.c 2009-05-10 22:04:38.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/drivers/media/video/cx23885/cx23885-video.c 2009-05-10 23:48:28.000000000 +0200 +@@ -730,13 +730,12 @@ + lock_kernel(); + list_for_each(list, &cx23885_devlist) { + h = list_entry(list, struct cx23885_dev, devlist); +- if (h->video_dev && +- h->video_dev->minor == minor) { ++ if (h->video_dev->minor == minor) { + dev = h; + type = V4L2_BUF_TYPE_VIDEO_CAPTURE; + } + if (h->vbi_dev && +- h->vbi_dev->minor == minor) { ++ h->vbi_dev->minor == minor) { + dev = h; + type = V4L2_BUF_TYPE_VBI_CAPTURE; + } +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/drivers/media/video/cx25840/cx25840-core.c linux-2.6.29-rc3.owrt/drivers/media/video/cx25840/cx25840-core.c +--- linux-2.6.29.owrt/drivers/media/video/cx25840/cx25840-core.c 2009-05-10 22:04:38.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/drivers/media/video/cx25840/cx25840-core.c 2009-05-10 23:48:28.000000000 +0200 +@@ -1382,14 +1382,6 @@ + + static int cx25840_command(struct i2c_client *client, unsigned cmd, void *arg) + { +- /* ignore this command */ +- if (cmd == TUNER_SET_TYPE_ADDR || cmd == TUNER_SET_CONFIG) +- return 0; +- +- /* Old-style drivers rely on initialization on first use, so +- call the init whenever a command is issued to this driver. +- New-style drivers using v4l2_subdev should call init explicitly. */ +- cx25840_init(i2c_get_clientdata(client), 0); + return v4l2_subdev_command(i2c_get_clientdata(client), cmd, arg); + } + +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/drivers/media/video/cx88/cx88-dvb.c linux-2.6.29-rc3.owrt/drivers/media/video/cx88/cx88-dvb.c +--- linux-2.6.29.owrt/drivers/media/video/cx88/cx88-dvb.c 2009-05-10 22:04:38.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/drivers/media/video/cx88/cx88-dvb.c 2009-05-10 23:48:28.000000000 +0200 +@@ -614,41 +614,34 @@ + .set_ts_params = cx24116_set_ts_param, + }; + +-static int cx8802_alloc_frontends(struct cx8802_dev *dev) ++static int dvb_register(struct cx8802_dev *dev) + { + struct cx88_core *core = dev->core; +- struct videobuf_dvb_frontend *fe = NULL; ++ struct videobuf_dvb_frontend *fe0, *fe1 = NULL; ++ int mfe_shared = 0; /* bus not shared by default */ + int i; + +- mutex_init(&dev->frontends.lock); +- INIT_LIST_HEAD(&dev->frontends.felist); ++ if (0 != core->i2c_rc) { ++ printk(KERN_ERR "%s/2: no i2c-bus available, cannot attach dvb drivers\n", core->name); ++ goto frontend_detach; ++ } + + if (!core->board.num_frontends) +- return -ENODEV; ++ return -EINVAL; ++ ++ mutex_init(&dev->frontends.lock); ++ INIT_LIST_HEAD(&dev->frontends.felist); + + printk(KERN_INFO "%s() allocating %d frontend(s)\n", __func__, + core->board.num_frontends); + for (i = 1; i <= core->board.num_frontends; i++) { +- fe = videobuf_dvb_alloc_frontend(&dev->frontends, i); +- if (!fe) { ++ fe0 = videobuf_dvb_alloc_frontend(&dev->frontends, i); ++ if (!fe0) { + printk(KERN_ERR "%s() failed to alloc\n", __func__); + videobuf_dvb_dealloc_frontends(&dev->frontends); +- return -ENOMEM; ++ goto frontend_detach; + } + } +- return 0; +-} +- +-static int dvb_register(struct cx8802_dev *dev) +-{ +- struct cx88_core *core = dev->core; +- struct videobuf_dvb_frontend *fe0, *fe1 = NULL; +- int mfe_shared = 0; /* bus not shared by default */ +- +- if (0 != core->i2c_rc) { +- printk(KERN_ERR "%s/2: no i2c-bus available, cannot attach dvb drivers\n", core->name); +- goto frontend_detach; +- } + + /* Get the first frontend */ + fe0 = videobuf_dvb_get_frontend(&dev->frontends, 1); +@@ -1250,8 +1243,6 @@ + struct cx88_core *core = drv->core; + struct cx8802_dev *dev = drv->core->dvbdev; + int err; +- struct videobuf_dvb_frontend *fe; +- int i; + + dprintk( 1, "%s\n", __func__); + dprintk( 1, " ->being probed by Card=%d Name=%s, PCI %02x:%02x\n", +@@ -1267,34 +1258,39 @@ + /* If vp3054 isn't enabled, a stub will just return 0 */ + err = vp3054_i2c_probe(dev); + if (0 != err) +- goto fail_core; ++ goto fail_probe; + + /* dvb stuff */ + printk(KERN_INFO "%s/2: cx2388x based DVB/ATSC card\n", core->name); + dev->ts_gen_cntrl = 0x0c; + +- err = cx8802_alloc_frontends(dev); +- if (err) +- goto fail_core; +- + err = -ENODEV; +- for (i = 1; i <= core->board.num_frontends; i++) { +- fe = videobuf_dvb_get_frontend(&core->dvbdev->frontends, i); +- if (fe == NULL) { +- printk(KERN_ERR "%s() failed to get frontend(%d)\n", ++ if (core->board.num_frontends) { ++ struct videobuf_dvb_frontend *fe; ++ int i; ++ ++ for (i = 1; i <= core->board.num_frontends; i++) { ++ fe = videobuf_dvb_get_frontend(&core->dvbdev->frontends, i); ++ if (fe == NULL) { ++ printk(KERN_ERR "%s() failed to get frontend(%d)\n", + __func__, i); +- goto fail_probe; +- } +- videobuf_queue_sg_init(&fe->dvb.dvbq, &dvb_qops, ++ goto fail_probe; ++ } ++ videobuf_queue_sg_init(&fe->dvb.dvbq, &dvb_qops, + &dev->pci->dev, &dev->slock, + V4L2_BUF_TYPE_VIDEO_CAPTURE, + V4L2_FIELD_TOP, + sizeof(struct cx88_buffer), + dev); +- /* init struct videobuf_dvb */ +- fe->dvb.name = dev->core->name; ++ /* init struct videobuf_dvb */ ++ fe->dvb.name = dev->core->name; ++ } ++ } else { ++ /* no frontends allocated */ ++ printk(KERN_ERR "%s/2 .num_frontends should be non-zero\n", ++ core->name); ++ goto fail_core; + } +- + err = dvb_register(dev); + if (err) + /* frontends/adapter de-allocated in dvb_register */ +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/drivers/media/video/cx88/cx88.h linux-2.6.29-rc3.owrt/drivers/media/video/cx88/cx88.h +--- linux-2.6.29.owrt/drivers/media/video/cx88/cx88.h 2009-05-10 22:04:38.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/drivers/media/video/cx88/cx88.h 2009-05-10 23:48:28.000000000 +0200 +@@ -336,8 +336,8 @@ + /* config info -- dvb */ + #if defined(CONFIG_VIDEO_CX88_DVB) || defined(CONFIG_VIDEO_CX88_DVB_MODULE) + int (*prev_set_voltage)(struct dvb_frontend *fe, fe_sec_voltage_t voltage); +-#endif + void (*gate_ctrl)(struct cx88_core *core, int open); ++#endif + + /* state info */ + struct task_struct *kthread; +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/drivers/media/video/em28xx/em28xx-audio.c linux-2.6.29-rc3.owrt/drivers/media/video/em28xx/em28xx-audio.c +--- linux-2.6.29.owrt/drivers/media/video/em28xx/em28xx-audio.c 2009-05-10 22:04:38.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/drivers/media/video/em28xx/em28xx-audio.c 2009-05-10 23:48:28.000000000 +0200 +@@ -62,15 +62,9 @@ + + dprintk("Stopping isoc\n"); + for (i = 0; i < EM28XX_AUDIO_BUFS; i++) { +- if (!irqs_disabled()) +- usb_kill_urb(dev->adev.urb[i]); +- else +- usb_unlink_urb(dev->adev.urb[i]); ++ usb_unlink_urb(dev->adev.urb[i]); + usb_free_urb(dev->adev.urb[i]); + dev->adev.urb[i] = NULL; +- +- kfree(dev->adev.transfer_buffer[i]); +- dev->adev.transfer_buffer[i] = NULL; + } + + return 0; +@@ -395,15 +389,11 @@ + static snd_pcm_uframes_t snd_em28xx_capture_pointer(struct snd_pcm_substream + *substream) + { +- unsigned long flags; +- + struct em28xx *dev; +- snd_pcm_uframes_t hwptr_done; + ++ snd_pcm_uframes_t hwptr_done; + dev = snd_pcm_substream_chip(substream); +- spin_lock_irqsave(&dev->adev.slock, flags); + hwptr_done = dev->adev.hwptr_done_capture; +- spin_unlock_irqrestore(&dev->adev.slock, flags); + + return hwptr_done; + } +@@ -463,8 +453,6 @@ + pcm->info_flags = 0; + pcm->private_data = dev; + strcpy(pcm->name, "Empia 28xx Capture"); +- +- snd_card_set_dev(card, &dev->udev->dev); + strcpy(card->driver, "Empia Em28xx Audio"); + strcpy(card->shortname, "Em28xx Audio"); + strcpy(card->longname, "Empia Em28xx Audio"); +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/drivers/media/video/em28xx/em28xx-cards.c linux-2.6.29-rc3.owrt/drivers/media/video/em28xx/em28xx-cards.c +--- linux-2.6.29.owrt/drivers/media/video/em28xx/em28xx-cards.c 2009-05-10 22:04:38.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/drivers/media/video/em28xx/em28xx-cards.c 2009-05-10 23:48:28.000000000 +0200 +@@ -102,18 +102,6 @@ + /* Board - EM2870 Kworld 355u + Analog - No input analog */ + +-static struct em28xx_reg_seq kworld_330u_analog[] = { +- {EM28XX_R08_GPIO, 0x6d, ~EM_GPIO_4, 10}, +- {EM2880_R04_GPO, 0x00, 0xff, 10}, +- { -1, -1, -1, -1}, +-}; +- +-static struct em28xx_reg_seq kworld_330u_digital[] = { +- {EM28XX_R08_GPIO, 0x6e, ~EM_GPIO_4, 10}, +- {EM2880_R04_GPO, 0x08, 0xff, 10}, +- { -1, -1, -1, -1}, +-}; +- + /* Callback for the most boards */ + static struct em28xx_reg_seq default_tuner_gpio[] = { + {EM28XX_R08_GPIO, EM_GPIO_4, EM_GPIO_4, 10}, +@@ -1189,33 +1177,29 @@ + .gpio = hauppauge_wintv_hvr_900_analog, + } }, + }, +- [EM2883_BOARD_KWORLD_HYBRID_330U] = { ++ [EM2883_BOARD_KWORLD_HYBRID_A316] = { + .name = "Kworld PlusTV HD Hybrid 330", + .tuner_type = TUNER_XC2028, + .tuner_gpio = default_tuner_gpio, + .decoder = EM28XX_TVP5150, + .mts_firmware = 1, + .has_dvb = 1, +- .dvb_gpio = kworld_330u_digital, +- .xclk = EM28XX_XCLK_FREQUENCY_12MHZ, +- .i2c_speed = EM28XX_I2C_CLK_WAIT_ENABLE | EM28XX_I2C_EEPROM_ON_BOARD | EM28XX_I2C_EEPROM_KEY_VALID, ++ .dvb_gpio = default_digital, + .input = { { + .type = EM28XX_VMUX_TELEVISION, + .vmux = TVP5150_COMPOSITE0, + .amux = EM28XX_AMUX_VIDEO, +- .gpio = kworld_330u_analog, +- .aout = EM28XX_AOUT_PCM_IN | EM28XX_AOUT_PCM_STEREO, ++ .gpio = default_analog, + }, { + .type = EM28XX_VMUX_COMPOSITE1, + .vmux = TVP5150_COMPOSITE1, + .amux = EM28XX_AMUX_LINE_IN, +- .gpio = kworld_330u_analog, +- .aout = EM28XX_AOUT_PCM_IN | EM28XX_AOUT_PCM_STEREO, ++ .gpio = hauppauge_wintv_hvr_900_analog, + }, { + .type = EM28XX_VMUX_SVIDEO, + .vmux = TVP5150_SVIDEO, + .amux = EM28XX_AMUX_LINE_IN, +- .gpio = kworld_330u_analog, ++ .gpio = hauppauge_wintv_hvr_900_analog, + } }, + }, + [EM2820_BOARD_COMPRO_VIDEOMATE_FORYOU] = { +@@ -1265,7 +1249,7 @@ + { USB_DEVICE(0xeb1a, 0xe310), + .driver_info = EM2880_BOARD_MSI_DIGIVOX_AD }, + { USB_DEVICE(0xeb1a, 0xa316), +- .driver_info = EM2883_BOARD_KWORLD_HYBRID_330U }, ++ .driver_info = EM2883_BOARD_KWORLD_HYBRID_A316 }, + { USB_DEVICE(0xeb1a, 0xe320), + .driver_info = EM2880_BOARD_MSI_DIGIVOX_AD_II }, + { USB_DEVICE(0xeb1a, 0xe323), +@@ -1542,10 +1526,6 @@ + /* FIXME: Better to specify the needed IF */ + ctl->demod = XC3028_FE_DEFAULT; + break; +- case EM2883_BOARD_KWORLD_HYBRID_330U: +- ctl->demod = XC3028_FE_CHINA; +- ctl->fname = XC2028_DEFAULT_FIRMWARE; +- break; + default: + ctl->demod = XC3028_FE_OREN538; + } +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/drivers/media/video/em28xx/em28xx-core.c linux-2.6.29-rc3.owrt/drivers/media/video/em28xx/em28xx-core.c +--- linux-2.6.29.owrt/drivers/media/video/em28xx/em28xx-core.c 2009-05-10 22:04:38.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/drivers/media/video/em28xx/em28xx-core.c 2009-05-10 23:48:28.000000000 +0200 +@@ -438,10 +438,6 @@ + if (dev->audio_mode.ac97 != EM28XX_NO_AC97) { + int vol; + +- em28xx_write_ac97(dev, AC97_POWER_DOWN_CTRL, 0x4200); +- em28xx_write_ac97(dev, AC97_EXT_AUD_CTRL, 0x0031); +- em28xx_write_ac97(dev, AC97_PCM_IN_SRATE, 0xbb80); +- + /* LSB: left channel - both channels with the same level */ + vol = (0x1f - dev->volume) | ((0x1f - dev->volume) << 8); + +@@ -458,15 +454,6 @@ + em28xx_warn("couldn't setup AC97 register %d\n", + outputs[i].reg); + } +- +- if (dev->ctl_aoutput & EM28XX_AOUT_PCM_IN) { +- int sel = ac97_return_record_select(dev->ctl_aoutput); +- +- /* Use the same input for both left and right channels */ +- sel |= (sel << 8); +- +- em28xx_write_ac97(dev, AC97_RECORD_SELECT, sel); +- } + } + + return ret; +@@ -860,11 +847,8 @@ + for (i = 0; i < dev->isoc_ctl.num_bufs; i++) { + urb = dev->isoc_ctl.urb[i]; + if (urb) { +- if (!irqs_disabled()) +- usb_kill_urb(urb); +- else +- usb_unlink_urb(urb); +- ++ usb_kill_urb(urb); ++ usb_unlink_urb(urb); + if (dev->isoc_ctl.transfer_buffer[i]) { + usb_buffer_free(dev->udev, + urb->transfer_buffer_length, +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/drivers/media/video/em28xx/em28xx-dvb.c linux-2.6.29-rc3.owrt/drivers/media/video/em28xx/em28xx-dvb.c +--- linux-2.6.29.owrt/drivers/media/video/em28xx/em28xx-dvb.c 2009-05-10 22:04:38.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/drivers/media/video/em28xx/em28xx-dvb.c 2009-05-10 23:48:28.000000000 +0200 +@@ -28,7 +28,6 @@ + + #include "lgdt330x.h" + #include "zl10353.h" +-#include "s5h1409.h" + #ifdef EM28XX_DRX397XD_SUPPORT + #include "drx397xD.h" + #endif +@@ -233,15 +232,6 @@ + .if2 = 45600, + }; + +-static struct s5h1409_config em28xx_s5h1409_with_xc3028 = { +- .demod_address = 0x32 >> 1, +- .output_mode = S5H1409_PARALLEL_OUTPUT, +- .gpio = S5H1409_GPIO_OFF, +- .inversion = S5H1409_INVERSION_OFF, +- .status_mode = S5H1409_DEMODLOCKING, +- .mpeg_timing = S5H1409_MPEGTIMING_CONTINOUS_NONINVERTING_CLOCK +-}; +- + #ifdef EM28XX_DRX397XD_SUPPORT + /* [TODO] djh - not sure yet what the device config needs to contain */ + static struct drx397xD_config em28xx_drx397xD_with_xc3028 = { +@@ -422,6 +412,7 @@ + case EM2883_BOARD_HAUPPAUGE_WINTV_HVR_850: + case EM2883_BOARD_HAUPPAUGE_WINTV_HVR_950: + case EM2880_BOARD_PINNACLE_PCTV_HD_PRO: ++ case EM2883_BOARD_KWORLD_HYBRID_A316: + case EM2880_BOARD_AMD_ATI_TV_WONDER_HD_600: + dvb->frontend = dvb_attach(lgdt330x_attach, + &em2880_lgdt3303_dev, +@@ -442,15 +433,6 @@ + goto out_free; + } + break; +- case EM2883_BOARD_KWORLD_HYBRID_330U: +- dvb->frontend = dvb_attach(s5h1409_attach, +- &em28xx_s5h1409_with_xc3028, +- &dev->i2c_adap); +- if (attach_xc3028(0x61, dev) < 0) { +- result = -EINVAL; +- goto out_free; +- } +- break; + case EM2880_BOARD_HAUPPAUGE_WINTV_HVR_900_R2: + #ifdef EM28XX_DRX397XD_SUPPORT + /* We don't have the config structure properly populated, so +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/drivers/media/video/em28xx/em28xx.h linux-2.6.29-rc3.owrt/drivers/media/video/em28xx/em28xx.h +--- linux-2.6.29.owrt/drivers/media/video/em28xx/em28xx.h 2009-05-10 22:04:38.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/drivers/media/video/em28xx/em28xx.h 2009-05-10 23:48:28.000000000 +0200 +@@ -94,7 +94,7 @@ + #define EM2882_BOARD_KWORLD_VS_DVBT 54 + #define EM2882_BOARD_TERRATEC_HYBRID_XS 55 + #define EM2882_BOARD_PINNACLE_HYBRID_PRO 56 +-#define EM2883_BOARD_KWORLD_HYBRID_330U 57 ++#define EM2883_BOARD_KWORLD_HYBRID_A316 57 + #define EM2820_BOARD_COMPRO_VIDEOMATE_FORYOU 58 + #define EM2883_BOARD_HAUPPAUGE_WINTV_HVR_850 60 + #define EM2820_BOARD_PROLINK_PLAYTV_BOX4_USB2 61 +@@ -300,32 +300,13 @@ + }; + + enum em28xx_aout { +- /* AC97 outputs */ + EM28XX_AOUT_MASTER = 1 << 0, + EM28XX_AOUT_LINE = 1 << 1, + EM28XX_AOUT_MONO = 1 << 2, + EM28XX_AOUT_LFE = 1 << 3, + EM28XX_AOUT_SURR = 1 << 4, +- +- /* PCM IN Mixer - used by AC97_RECORD_SELECT register */ +- EM28XX_AOUT_PCM_IN = 1 << 7, +- +- /* Bits 10-8 are used to indicate the PCM IN record select */ +- EM28XX_AOUT_PCM_MIC_PCM = 0 << 8, +- EM28XX_AOUT_PCM_CD = 1 << 8, +- EM28XX_AOUT_PCM_VIDEO = 2 << 8, +- EM28XX_AOUT_PCM_AUX = 3 << 8, +- EM28XX_AOUT_PCM_LINE = 4 << 8, +- EM28XX_AOUT_PCM_STEREO = 5 << 8, +- EM28XX_AOUT_PCM_MONO = 6 << 8, +- EM28XX_AOUT_PCM_PHONE = 7 << 8, + }; + +-static inline int ac97_return_record_select(int a_out) +-{ +- return (a_out & 0x700) >> 8; +-} +- + struct em28xx_reg_seq { + int reg; + unsigned char val, mask; +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/drivers/media/video/em28xx/em28xx-video.c linux-2.6.29-rc3.owrt/drivers/media/video/em28xx/em28xx-video.c +--- linux-2.6.29.owrt/drivers/media/video/em28xx/em28xx-video.c 2009-05-10 22:04:38.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/drivers/media/video/em28xx/em28xx-video.c 2009-05-10 23:48:28.000000000 +0200 +@@ -886,10 +886,10 @@ + if (0 == INPUT(i)->type) + return -EINVAL; + +- dev->ctl_input = i; +- + mutex_lock(&dev->lock); +- video_mux(dev, dev->ctl_input); ++ ++ video_mux(dev, i); ++ + mutex_unlock(&dev->lock); + return 0; + } +@@ -939,12 +939,6 @@ + struct em28xx_fh *fh = priv; + struct em28xx *dev = fh->dev; + +- +- if (a->index >= MAX_EM28XX_INPUT) +- return -EINVAL; +- if (0 == INPUT(a->index)->type) +- return -EINVAL; +- + mutex_lock(&dev->lock); + + dev->ctl_ainput = INPUT(a->index)->amux; +@@ -1956,7 +1950,6 @@ + + int em28xx_register_analog_devices(struct em28xx *dev) + { +- u8 val; + int ret; + + printk(KERN_INFO "%s: v4l2 driver version %d.%d.%d\n", +@@ -1964,34 +1957,34 @@ + (EM28XX_VERSION_CODE >> 16) & 0xff, + (EM28XX_VERSION_CODE >> 8) & 0xff, EM28XX_VERSION_CODE & 0xff); + +- /* set default norm */ +- dev->norm = em28xx_video_template.current_norm; +- dev->width = norm_maxw(dev); +- dev->height = norm_maxh(dev); +- dev->interlaced = EM28XX_INTERLACED_DEFAULT; +- dev->hscale = 0; +- dev->vscale = 0; +- dev->ctl_input = 0; +- + /* Analog specific initialization */ + dev->format = &format[0]; +- video_mux(dev, dev->ctl_input); +- +- /* Audio defaults */ +- dev->mute = 1; +- dev->volume = 0x1f; ++ video_mux(dev, 0); + + /* enable vbi capturing */ + + /* em28xx_write_reg(dev, EM28XX_R0E_AUDIOSRC, 0xc0); audio register */ +- val = (u8)em28xx_read_reg(dev, EM28XX_R0F_XCLK); +- em28xx_write_reg(dev, EM28XX_R0F_XCLK, (EM28XX_XCLK_AUDIO_UNMUTE | val)); ++/* em28xx_write_reg(dev, EM28XX_R0F_XCLK, 0x80); clk register */ + em28xx_write_reg(dev, EM28XX_R11_VINCTRL, 0x51); + ++ dev->mute = 1; /* maybe not the right place... */ ++ dev->volume = 0x1f; ++ + em28xx_set_outfmt(dev); + em28xx_colorlevels_set_default(dev); + em28xx_compression_disable(dev); + ++ /* set default norm */ ++ dev->norm = em28xx_video_template.current_norm; ++ dev->width = norm_maxw(dev); ++ dev->height = norm_maxh(dev); ++ dev->interlaced = EM28XX_INTERLACED_DEFAULT; ++ dev->hscale = 0; ++ dev->vscale = 0; ++ ++ /* FIXME: This is a very bad hack! Not all devices have TV on input 2 */ ++ dev->ctl_input = 2; ++ + /* allocate and fill video video_device struct */ + dev->vdev = em28xx_vdev_init(dev, &em28xx_video_template, "video"); + if (!dev->vdev) { +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/drivers/media/video/gspca/gspca.c linux-2.6.29-rc3.owrt/drivers/media/video/gspca/gspca.c +--- linux-2.6.29.owrt/drivers/media/video/gspca/gspca.c 2009-05-10 22:04:38.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/drivers/media/video/gspca/gspca.c 2009-05-10 23:48:28.000000000 +0200 +@@ -422,10 +422,8 @@ + if (urb == NULL) + break; + +- BUG_ON(!gspca_dev->dev); + gspca_dev->urb[i] = NULL; +- if (!gspca_dev->present) +- usb_kill_urb(urb); ++ usb_kill_urb(urb); + if (urb->transfer_buffer != NULL) + usb_buffer_free(gspca_dev->dev, + urb->transfer_buffer_length, +@@ -1951,12 +1949,9 @@ + { + struct gspca_dev *gspca_dev = usb_get_intfdata(intf); + +- mutex_lock(&gspca_dev->usb_lock); + gspca_dev->present = 0; +- mutex_unlock(&gspca_dev->usb_lock); ++ gspca_dev->streaming = 0; + +- destroy_urbs(gspca_dev); +- gspca_dev->dev = NULL; + usb_set_intfdata(intf, NULL); + + /* release the device */ +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/drivers/media/video/gspca/m5602/m5602_s5k4aa.c linux-2.6.29-rc3.owrt/drivers/media/video/gspca/m5602/m5602_s5k4aa.c +--- linux-2.6.29.owrt/drivers/media/video/gspca/m5602/m5602_s5k4aa.c 2009-05-10 22:04:38.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/drivers/media/video/gspca/m5602/m5602_s5k4aa.c 2009-05-10 23:48:28.000000000 +0200 +@@ -102,11 +102,7 @@ + } + + /* Test some registers, but we don't know their exact meaning yet */ +- if (m5602_read_sensor(sd, 0x00, prod_id, 2)) +- return -ENODEV; +- if (m5602_read_sensor(sd, 0x02, prod_id+2, 2)) +- return -ENODEV; +- if (m5602_read_sensor(sd, 0x04, prod_id+4, 2)) ++ if (m5602_read_sensor(sd, 0x00, prod_id, sizeof(prod_id))) + return -ENODEV; + + if (memcmp(prod_id, expected_prod_id, sizeof(prod_id))) +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/drivers/media/video/ivtv/ivtv-driver.c linux-2.6.29-rc3.owrt/drivers/media/video/ivtv/ivtv-driver.c +--- linux-2.6.29.owrt/drivers/media/video/ivtv/ivtv-driver.c 2009-05-10 22:04:38.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/drivers/media/video/ivtv/ivtv-driver.c 2009-05-10 23:48:28.000000000 +0200 +@@ -949,10 +949,8 @@ + itv->instance = atomic_inc_return(&ivtv_instance) - 1; + + retval = v4l2_device_register(&dev->dev, &itv->device); +- if (retval) { +- kfree(itv); ++ if (retval) + return retval; +- } + /* "ivtv + PCI ID" is a bit of a mouthful, so use + "ivtv + instance" instead. */ + snprintf(itv->device.name, sizeof(itv->device.name), +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/drivers/media/video/ivtv/ivtv-ioctl.c linux-2.6.29-rc3.owrt/drivers/media/video/ivtv/ivtv-ioctl.c +--- linux-2.6.29.owrt/drivers/media/video/ivtv/ivtv-ioctl.c 2009-05-10 22:04:38.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/drivers/media/video/ivtv/ivtv-ioctl.c 2009-05-10 23:48:28.000000000 +0200 +@@ -393,7 +393,7 @@ + return 0; + } + +- v4l2_subdev_call(itv->sd_video, video, g_fmt, fmt); ++ v4l2_subdev_call(itv->sd_video, video, s_fmt, fmt); + vbifmt->service_set = ivtv_get_service_set(vbifmt); + return 0; + } +@@ -1748,18 +1748,6 @@ + break; + } + +- case IVTV_IOC_DMA_FRAME: +- case VIDEO_GET_PTS: +- case VIDEO_GET_FRAME_COUNT: +- case VIDEO_GET_EVENT: +- case VIDEO_PLAY: +- case VIDEO_STOP: +- case VIDEO_FREEZE: +- case VIDEO_CONTINUE: +- case VIDEO_COMMAND: +- case VIDEO_TRY_COMMAND: +- return ivtv_decoder_ioctls(file, cmd, (void *)arg); +- + default: + return -EINVAL; + } +@@ -1802,6 +1790,18 @@ + ivtv_vapi(itv, CX2341X_DEC_SET_AUDIO_MODE, 2, itv->audio_bilingual_mode, itv->audio_stereo_mode); + return 0; + ++ case IVTV_IOC_DMA_FRAME: ++ case VIDEO_GET_PTS: ++ case VIDEO_GET_FRAME_COUNT: ++ case VIDEO_GET_EVENT: ++ case VIDEO_PLAY: ++ case VIDEO_STOP: ++ case VIDEO_FREEZE: ++ case VIDEO_CONTINUE: ++ case VIDEO_COMMAND: ++ case VIDEO_TRY_COMMAND: ++ return ivtv_decoder_ioctls(filp, cmd, (void *)arg); ++ + default: + break; + } +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/drivers/media/video/pwc/pwc-if.c linux-2.6.29-rc3.owrt/drivers/media/video/pwc/pwc-if.c +--- linux-2.6.29.owrt/drivers/media/video/pwc/pwc-if.c 2009-05-10 22:04:38.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/drivers/media/video/pwc/pwc-if.c 2009-05-10 23:48:28.000000000 +0200 +@@ -62,6 +62,7 @@ + #include <linux/poll.h> + #include <linux/slab.h> + #include <linux/vmalloc.h> ++#include <linux/version.h> + #include <asm/io.h> + + #include "pwc.h" +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/drivers/media/video/pxa_camera.c linux-2.6.29-rc3.owrt/drivers/media/video/pxa_camera.c +--- linux-2.6.29.owrt/drivers/media/video/pxa_camera.c 2009-05-10 22:04:38.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/drivers/media/video/pxa_camera.c 2009-05-10 23:48:28.000000000 +0200 +@@ -1155,24 +1155,24 @@ + { + struct soc_camera_host *ici = to_soc_camera_host(icd->dev.parent); + struct pxa_camera_dev *pcdev = ici->priv; +- const struct soc_camera_data_format *cam_fmt = NULL; +- const struct soc_camera_format_xlate *xlate = NULL; ++ const struct soc_camera_data_format *host_fmt, *cam_fmt = NULL; ++ const struct soc_camera_format_xlate *xlate; + struct soc_camera_sense sense = { + .master_clock = pcdev->mclk, + .pixel_clock_max = pcdev->ciclk / 4, + }; +- int ret; ++ int ret, buswidth; + +- if (pixfmt) { +- xlate = soc_camera_xlate_by_fourcc(icd, pixfmt); +- if (!xlate) { +- dev_warn(&ici->dev, "Format %x not found\n", pixfmt); +- return -EINVAL; +- } +- +- cam_fmt = xlate->cam_fmt; ++ xlate = soc_camera_xlate_by_fourcc(icd, pixfmt); ++ if (!xlate) { ++ dev_warn(&ici->dev, "Format %x not found\n", pixfmt); ++ return -EINVAL; + } + ++ buswidth = xlate->buswidth; ++ host_fmt = xlate->host_fmt; ++ cam_fmt = xlate->cam_fmt; ++ + /* If PCLK is used to latch data from the sensor, check sense */ + if (pcdev->platform_flags & PXA_CAMERA_PCLK_EN) + icd->sense = &sense; +@@ -1201,8 +1201,8 @@ + } + + if (pixfmt && !ret) { +- icd->buswidth = xlate->buswidth; +- icd->current_fmt = xlate->host_fmt; ++ icd->buswidth = buswidth; ++ icd->current_fmt = host_fmt; + } + + return ret; +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/drivers/media/video/saa7127.c linux-2.6.29-rc3.owrt/drivers/media/video/saa7127.c +--- linux-2.6.29.owrt/drivers/media/video/saa7127.c 2009-05-10 22:04:38.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/drivers/media/video/saa7127.c 2009-05-10 23:48:28.000000000 +0200 +@@ -149,7 +149,7 @@ + { SAA7127_REG_COPYGEN_0, 0x77 }, + { SAA7127_REG_COPYGEN_1, 0x41 }, + { SAA7127_REG_COPYGEN_2, 0x00 }, /* Macrovision enable/disable */ +- { SAA7127_REG_OUTPUT_PORT_CONTROL, 0xbf }, ++ { SAA7127_REG_OUTPUT_PORT_CONTROL, 0x9e }, + { SAA7127_REG_GAIN_LUMINANCE_RGB, 0x00 }, + { SAA7127_REG_GAIN_COLORDIFF_RGB, 0x00 }, + { SAA7127_REG_INPUT_PORT_CONTROL_1, 0x80 }, /* for color bars */ +@@ -488,18 +488,12 @@ + break; + + case SAA7127_OUTPUT_TYPE_COMPOSITE: +- if (state->ident == V4L2_IDENT_SAA7129) +- state->reg_2d = 0x20; /* CVBS only */ +- else +- state->reg_2d = 0x08; /* 00001000 CVBS only, RGB DAC's off (high impedance mode) */ ++ state->reg_2d = 0x08; /* 00001000 CVBS only, RGB DAC's off (high impedance mode) */ + state->reg_3a = 0x13; /* by default switch YUV to RGB-matrix on */ + break; + + case SAA7127_OUTPUT_TYPE_SVIDEO: +- if (state->ident == V4L2_IDENT_SAA7129) +- state->reg_2d = 0x18; /* Y + C */ +- else +- state->reg_2d = 0xff; /*11111111 croma -> R, luma -> CVBS + G + B */ ++ state->reg_2d = 0xff; /* 11111111 croma -> R, luma -> CVBS + G + B */ + state->reg_3a = 0x13; /* by default switch YUV to RGB-matrix on */ + break; + +@@ -514,10 +508,7 @@ + break; + + case SAA7127_OUTPUT_TYPE_BOTH: +- if (state->ident == V4L2_IDENT_SAA7129) +- state->reg_2d = 0x38; +- else +- state->reg_2d = 0xbf; ++ state->reg_2d = 0xbf; + state->reg_3a = 0x13; /* by default switch YUV to RGB-matrix on */ + break; + +@@ -740,6 +731,24 @@ + return -ENODEV; + } + ++ /* Configure Encoder */ ++ ++ v4l2_dbg(1, debug, sd, "Configuring encoder\n"); ++ saa7127_write_inittab(sd, saa7127_init_config_common); ++ saa7127_set_std(sd, V4L2_STD_NTSC); ++ saa7127_set_output_type(sd, SAA7127_OUTPUT_TYPE_BOTH); ++ saa7127_set_vps(sd, &vbi); ++ saa7127_set_wss(sd, &vbi); ++ saa7127_set_cc(sd, &vbi); ++ saa7127_set_xds(sd, &vbi); ++ if (test_image == 1) ++ /* The Encoder has an internal Colorbar generator */ ++ /* This can be used for debugging */ ++ saa7127_set_input_type(sd, SAA7127_INPUT_TYPE_TEST_IMAGE); ++ else ++ saa7127_set_input_type(sd, SAA7127_INPUT_TYPE_NORMAL); ++ saa7127_set_video_enable(sd, 1); ++ + if (id->driver_data) { /* Chip type is already known */ + state->ident = id->driver_data; + } else { /* Needs detection */ +@@ -761,23 +770,6 @@ + + v4l2_info(sd, "%s found @ 0x%x (%s)\n", client->name, + client->addr << 1, client->adapter->name); +- +- v4l2_dbg(1, debug, sd, "Configuring encoder\n"); +- saa7127_write_inittab(sd, saa7127_init_config_common); +- saa7127_set_std(sd, V4L2_STD_NTSC); +- saa7127_set_output_type(sd, SAA7127_OUTPUT_TYPE_BOTH); +- saa7127_set_vps(sd, &vbi); +- saa7127_set_wss(sd, &vbi); +- saa7127_set_cc(sd, &vbi); +- saa7127_set_xds(sd, &vbi); +- if (test_image == 1) +- /* The Encoder has an internal Colorbar generator */ +- /* This can be used for debugging */ +- saa7127_set_input_type(sd, SAA7127_INPUT_TYPE_TEST_IMAGE); +- else +- saa7127_set_input_type(sd, SAA7127_INPUT_TYPE_NORMAL); +- saa7127_set_video_enable(sd, 1); +- + if (state->ident == V4L2_IDENT_SAA7129) + saa7127_write_inittab(sd, saa7129_init_config_extra); + return 0; +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/drivers/media/video/saa7134/saa7134-alsa.c linux-2.6.29-rc3.owrt/drivers/media/video/saa7134/saa7134-alsa.c +--- linux-2.6.29.owrt/drivers/media/video/saa7134/saa7134-alsa.c 2009-05-10 22:04:39.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/drivers/media/video/saa7134/saa7134-alsa.c 2009-05-10 23:48:28.000000000 +0200 +@@ -1089,11 +1089,7 @@ + + list_for_each(list,&saa7134_devlist) { + dev = list_entry(list, struct saa7134_dev, devlist); +- if (dev->pci->device == PCI_DEVICE_ID_PHILIPS_SAA7130) +- printk(KERN_INFO "%s/alsa: %s doesn't support digital audio\n", +- dev->name, saa7134_boards[dev->board].name); +- else +- alsa_device_init(dev); ++ alsa_device_init(dev); + } + + if (dev == NULL) +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/drivers/media/video/saa7134/saa7134-core.c linux-2.6.29-rc3.owrt/drivers/media/video/saa7134/saa7134-core.c +--- linux-2.6.29.owrt/drivers/media/video/saa7134/saa7134-core.c 2009-05-10 22:04:39.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/drivers/media/video/saa7134/saa7134-core.c 2009-05-10 23:48:28.000000000 +0200 +@@ -660,10 +660,6 @@ + + saa_writel(SAA7134_IRQ1, 0); + saa_writel(SAA7134_IRQ2, 0); +- +- /* Clear any stale IRQ reports */ +- saa_writel(SAA7134_IRQ_REPORT, saa_readl(SAA7134_IRQ_REPORT)); +- + mutex_init(&dev->lock); + spin_lock_init(&dev->slock); + +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/drivers/media/video/saa7134/saa7134-dvb.c linux-2.6.29-rc3.owrt/drivers/media/video/saa7134/saa7134-dvb.c +--- linux-2.6.29.owrt/drivers/media/video/saa7134/saa7134-dvb.c 2009-05-10 22:04:38.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/drivers/media/video/saa7134/saa7134-dvb.c 2009-05-10 23:48:28.000000000 +0200 +@@ -860,7 +860,6 @@ + .demod_address = 0x1e>>1, + .no_tuner = 1, + .parallel_ts = 1, +- .disable_i2c_gate_ctrl = 1, + }; + + /* ================================================================== +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/drivers/media/video/saa717x.c linux-2.6.29-rc3.owrt/drivers/media/video/saa717x.c +--- linux-2.6.29.owrt/drivers/media/video/saa717x.c 2009-05-10 22:04:38.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/drivers/media/video/saa717x.c 2009-05-10 23:48:28.000000000 +0200 +@@ -30,6 +30,7 @@ + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + */ + ++#include <linux/version.h> + #include <linux/module.h> + #include <linux/kernel.h> + #include <linux/sched.h> +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/drivers/media/video/sh_mobile_ceu_camera.c linux-2.6.29-rc3.owrt/drivers/media/video/sh_mobile_ceu_camera.c +--- linux-2.6.29.owrt/drivers/media/video/sh_mobile_ceu_camera.c 2009-05-10 22:04:39.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/drivers/media/video/sh_mobile_ceu_camera.c 2009-05-10 23:48:28.000000000 +0200 +@@ -603,18 +603,21 @@ + const struct soc_camera_format_xlate *xlate; + int ret; + +- if (!pixfmt) +- return icd->ops->set_fmt(icd, pixfmt, rect); +- + xlate = soc_camera_xlate_by_fourcc(icd, pixfmt); + if (!xlate) { + dev_warn(&ici->dev, "Format %x not found\n", pixfmt); + return -EINVAL; + } + +- ret = icd->ops->set_fmt(icd, xlate->cam_fmt->fourcc, rect); ++ switch (pixfmt) { ++ case 0: /* Only geometry change */ ++ ret = icd->ops->set_fmt(icd, pixfmt, rect); ++ break; ++ default: ++ ret = icd->ops->set_fmt(icd, xlate->cam_fmt->fourcc, rect); ++ } + +- if (!ret) { ++ if (pixfmt && !ret) { + icd->buswidth = xlate->buswidth; + icd->current_fmt = xlate->host_fmt; + pcdev->camera_fmt = xlate->cam_fmt; +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/drivers/media/video/tda9875.c linux-2.6.29-rc3.owrt/drivers/media/video/tda9875.c +--- linux-2.6.29.owrt/drivers/media/video/tda9875.c 2009-05-10 22:04:38.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/drivers/media/video/tda9875.c 2009-05-10 23:48:28.000000000 +0200 +@@ -242,7 +242,7 @@ + static int tda9875_s_ctrl(struct v4l2_subdev *sd, struct v4l2_control *ctrl) + { + struct tda9875 *t = to_state(sd); +- int chvol = 0, volume = 0, balance = 0, left, right; ++ int chvol=0, volume, balance, left, right; + + switch (ctrl->id) { + case V4L2_CID_AUDIO_VOLUME: +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/drivers/media/video/tvaudio.c linux-2.6.29-rc3.owrt/drivers/media/video/tvaudio.c +--- linux-2.6.29.owrt/drivers/media/video/tvaudio.c 2009-05-10 22:04:38.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/drivers/media/video/tvaudio.c 2009-05-10 23:48:28.000000000 +0200 +@@ -54,7 +54,7 @@ + /* ---------------------------------------------------------------------- */ + /* our structs */ + +-#define MAXREGS 256 ++#define MAXREGS 64 + + struct CHIPSTATE; + typedef int (*getvalue)(int); +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/drivers/media/video/tveeprom.c linux-2.6.29-rc3.owrt/drivers/media/video/tveeprom.c +--- linux-2.6.29.owrt/drivers/media/video/tveeprom.c 2009-05-10 22:04:39.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/drivers/media/video/tveeprom.c 2009-05-10 23:48:28.000000000 +0200 +@@ -427,9 +427,6 @@ + const char *t_fmt_name2[8] = { " none", "", "", "", "", "", "", "" }; + + memset(tvee, 0, sizeof(*tvee)); +- tvee->tuner_type = TUNER_ABSENT; +- tvee->tuner2_type = TUNER_ABSENT; +- + done = len = beenhere = 0; + + /* Different eeprom start offsets for em28xx, cx2388x and cx23418 */ +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/drivers/media/video/tvp514x.c linux-2.6.29-rc3.owrt/drivers/media/video/tvp514x.c +--- linux-2.6.29.owrt/drivers/media/video/tvp514x.c 2009-05-10 22:04:38.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/drivers/media/video/tvp514x.c 2009-05-10 23:48:28.000000000 +0200 +@@ -1401,7 +1401,7 @@ + + decoder->pdata = client->dev.platform_data; + if (!decoder->pdata) { +- v4l_err(client, "No platform data!!\n"); ++ v4l_err(client, "No platform data\n!!"); + return -ENODEV; + } + /* +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/drivers/media/video/upd64031a.c linux-2.6.29-rc3.owrt/drivers/media/video/upd64031a.c +--- linux-2.6.29.owrt/drivers/media/video/upd64031a.c 2009-05-10 22:04:38.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/drivers/media/video/upd64031a.c 2009-05-10 23:48:28.000000000 +0200 +@@ -21,6 +21,7 @@ + */ + + ++#include <linux/version.h> + #include <linux/module.h> + #include <linux/kernel.h> + #include <linux/i2c.h> +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/drivers/media/video/upd64083.c linux-2.6.29-rc3.owrt/drivers/media/video/upd64083.c +--- linux-2.6.29.owrt/drivers/media/video/upd64083.c 2009-05-10 22:04:38.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/drivers/media/video/upd64083.c 2009-05-10 23:48:28.000000000 +0200 +@@ -21,6 +21,7 @@ + * 02110-1301, USA. + */ + ++#include <linux/version.h> + #include <linux/module.h> + #include <linux/kernel.h> + #include <linux/i2c.h> +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/drivers/media/video/usbvision/usbvision-i2c.c linux-2.6.29-rc3.owrt/drivers/media/video/usbvision/usbvision-i2c.c +--- linux-2.6.29.owrt/drivers/media/video/usbvision/usbvision-i2c.c 2009-05-10 22:04:38.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/drivers/media/video/usbvision/usbvision-i2c.c 2009-05-10 23:48:28.000000000 +0200 +@@ -157,7 +157,7 @@ + struct i2c_msg *pmsg; + struct usb_usbvision *usbvision; + int i, ret; +- unsigned char addr = 0; ++ unsigned char addr; + + usbvision = (struct usb_usbvision *)i2c_get_adapdata(i2c_adap); + +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/drivers/media/video/uvc/uvc_ctrl.c linux-2.6.29-rc3.owrt/drivers/media/video/uvc/uvc_ctrl.c +--- linux-2.6.29.owrt/drivers/media/video/uvc/uvc_ctrl.c 2009-05-10 22:04:38.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/drivers/media/video/uvc/uvc_ctrl.c 2009-05-10 23:48:28.000000000 +0200 +@@ -1,7 +1,7 @@ + /* + * uvc_ctrl.c -- USB Video Class driver - Controls + * +- * Copyright (C) 2005-2009 ++ * Copyright (C) 2005-2008 + * Laurent Pinchart (laurent.pinchart@skynet.be) + * + * This program is free software; you can redistribute it and/or modify +@@ -12,6 +12,7 @@ + */ + + #include <linux/kernel.h> ++#include <linux/version.h> + #include <linux/list.h> + #include <linux/module.h> + #include <linux/uaccess.h> +@@ -28,7 +29,7 @@ + #define UVC_CTRL_DATA_BACKUP 1 + + /* ------------------------------------------------------------------------ +- * Controls ++ * Control, formats, ... + */ + + static struct uvc_control_info uvc_ctrls[] = { +@@ -634,7 +635,7 @@ + mask = (1 << bits) - 1; + } + +- /* Sign-extend the value if needed. */ ++ /* Sign-extend the value if needed */ + if (mapping->data_type == UVC_CTRL_DATA_TYPE_SIGNED) + value |= -(value & (1 << (mapping->size - 1))); + +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/drivers/media/video/uvc/uvc_driver.c linux-2.6.29-rc3.owrt/drivers/media/video/uvc/uvc_driver.c +--- linux-2.6.29.owrt/drivers/media/video/uvc/uvc_driver.c 2009-05-10 22:04:38.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/drivers/media/video/uvc/uvc_driver.c 2009-05-10 23:48:28.000000000 +0200 +@@ -1,7 +1,7 @@ + /* + * uvc_driver.c -- USB Video Class driver + * +- * Copyright (C) 2005-2009 ++ * Copyright (C) 2005-2008 + * Laurent Pinchart (laurent.pinchart@skynet.be) + * + * This program is free software; you can redistribute it and/or modify +@@ -24,6 +24,7 @@ + */ + + #include <linux/kernel.h> ++#include <linux/version.h> + #include <linux/list.h> + #include <linux/module.h> + #include <linux/usb.h> +@@ -48,7 +49,7 @@ + unsigned int uvc_trace_param; + + /* ------------------------------------------------------------------------ +- * Video formats ++ * Control, formats, ... + */ + + static struct uvc_format_desc uvc_fmts[] = { +@@ -473,7 +474,7 @@ + + /* Several UVC chipsets screw up dwMaxVideoFrameBufferSize + * completely. Observed behaviours range from setting the +- * value to 1.1x the actual frame size to hardwiring the ++ * value to 1.1x the actual frame size of hardwiring the + * 16 low bits to 0. This results in a higher than necessary + * memory usage as well as a wrong image size information. For + * uncompressed formats this can be fixed by computing the +@@ -486,7 +487,7 @@ + /* Some bogus devices report dwMinFrameInterval equal to + * dwMaxFrameInterval and have dwFrameIntervalStep set to + * zero. Setting all null intervals to 1 fixes the problem and +- * some other divisions by zero that could happen. ++ * some other divisions by zero which could happen. + */ + for (i = 0; i < n; ++i) { + interval = get_unaligned_le32(&buffer[26+4*i]); +@@ -1199,13 +1200,13 @@ + * Scan the UVC descriptors to locate a chain starting at an Output Terminal + * and containing the following units: + * +- * - one Output Terminal (USB Streaming or Display) ++ * - a USB Streaming Output Terminal + * - zero or one Processing Unit + * - zero, one or mode single-input Selector Units + * - zero or one multiple-input Selector Units, provided all inputs are + * connected to input terminals + * - zero, one or mode single-input Extension Units +- * - one or more Input Terminals (Camera, External or USB Streaming) ++ * - one Camera Input Terminal, or one or more External terminals. + * + * A side forward scan is made on each detected entity to check for additional + * extension units. +@@ -1530,6 +1531,10 @@ + + /* Set the driver data before calling video_register_device, otherwise + * uvc_v4l2_open might race us. ++ * ++ * FIXME: usb_set_intfdata hasn't been called so far. Is that a ++ * problem ? Does any function which could be called here get ++ * a pointer to the usb_interface ? + */ + dev->video.vdev = vdev; + video_set_drvdata(vdev, &dev->video); +@@ -1564,7 +1569,7 @@ + struct uvc_device *dev = container_of(kref, struct uvc_device, kref); + struct list_head *p, *n; + +- /* Unregister the video device. */ ++ /* Unregister the video device */ + uvc_unregister_video(dev); + usb_put_intf(dev->intf); + usb_put_dev(dev->udev); +@@ -1607,7 +1612,7 @@ + uvc_trace(UVC_TRACE_PROBE, "Probing generic UVC device %s\n", + udev->devpath); + +- /* Allocate memory for the device and initialize it. */ ++ /* Allocate memory for the device and initialize it */ + if ((dev = kzalloc(sizeof *dev, GFP_KERNEL)) == NULL) + return -ENOMEM; + +@@ -1628,14 +1633,14 @@ + le16_to_cpu(udev->descriptor.idVendor), + le16_to_cpu(udev->descriptor.idProduct)); + +- /* Parse the Video Class control descriptor. */ ++ /* Parse the Video Class control descriptor */ + if (uvc_parse_control(dev) < 0) { + uvc_trace(UVC_TRACE_PROBE, "Unable to parse UVC " + "descriptors.\n"); + goto error; + } + +- uvc_printk(KERN_INFO, "Found UVC %u.%02x device %s (%04x:%04x)\n", ++ uvc_printk(KERN_INFO, "Found UVC %u.%02u device %s (%04x:%04x)\n", + dev->uvc_version >> 8, dev->uvc_version & 0xff, + udev->product ? udev->product : "<unnamed>", + le16_to_cpu(udev->descriptor.idVendor), +@@ -1648,18 +1653,18 @@ + "linux-uvc-devel mailing list.\n"); + } + +- /* Initialize controls. */ ++ /* Initialize controls */ + if (uvc_ctrl_init_device(dev) < 0) + goto error; + +- /* Register the video devices. */ ++ /* Register the video devices */ + if (uvc_register_video(dev) < 0) + goto error; + +- /* Save our data pointer in the interface data. */ ++ /* Save our data pointer in the interface data */ + usb_set_intfdata(intf, dev); + +- /* Initialize the interrupt URB. */ ++ /* Initialize the interrupt URB */ + if ((ret = uvc_status_init(dev)) < 0) { + uvc_printk(KERN_INFO, "Unable to initialize the status " + "endpoint (%d), status interrupt will not be " +@@ -1834,24 +1839,24 @@ + .bInterfaceSubClass = 1, + .bInterfaceProtocol = 0 }, + /* Apple Built-In iSight */ +- { .match_flags = USB_DEVICE_ID_MATCH_DEVICE ++ { .match_flags = USB_DEVICE_ID_MATCH_DEVICE + | USB_DEVICE_ID_MATCH_INT_INFO, + .idVendor = 0x05ac, + .idProduct = 0x8501, +- .bInterfaceClass = USB_CLASS_VIDEO, +- .bInterfaceSubClass = 1, +- .bInterfaceProtocol = 0, ++ .bInterfaceClass = USB_CLASS_VIDEO, ++ .bInterfaceSubClass = 1, ++ .bInterfaceProtocol = 0, + .driver_info = UVC_QUIRK_PROBE_MINMAX + | UVC_QUIRK_BUILTIN_ISIGHT }, + /* Genesys Logic USB 2.0 PC Camera */ +- { .match_flags = USB_DEVICE_ID_MATCH_DEVICE ++ { .match_flags = USB_DEVICE_ID_MATCH_DEVICE + | USB_DEVICE_ID_MATCH_INT_INFO, +- .idVendor = 0x05e3, +- .idProduct = 0x0505, +- .bInterfaceClass = USB_CLASS_VIDEO, +- .bInterfaceSubClass = 1, +- .bInterfaceProtocol = 0, +- .driver_info = UVC_QUIRK_STREAM_NO_FID }, ++ .idVendor = 0x05e3, ++ .idProduct = 0x0505, ++ .bInterfaceClass = USB_CLASS_VIDEO, ++ .bInterfaceSubClass = 1, ++ .bInterfaceProtocol = 0, ++ .driver_info = UVC_QUIRK_STREAM_NO_FID }, + /* MT6227 */ + { .match_flags = USB_DEVICE_ID_MATCH_DEVICE + | USB_DEVICE_ID_MATCH_INT_INFO, +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/drivers/media/video/uvc/uvc_isight.c linux-2.6.29-rc3.owrt/drivers/media/video/uvc/uvc_isight.c +--- linux-2.6.29.owrt/drivers/media/video/uvc/uvc_isight.c 2009-05-10 22:04:38.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/drivers/media/video/uvc/uvc_isight.c 2009-05-10 23:48:28.000000000 +0200 +@@ -3,8 +3,6 @@ + * + * Copyright (C) 2006-2007 + * Ivan N. Zlatev <contact@i-nz.net> +- * Copyright (C) 2008-2009 +- * Laurent Pinchart <laurent.pinchart@skynet.be> + * + * 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 +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/drivers/media/video/uvc/uvc_queue.c linux-2.6.29-rc3.owrt/drivers/media/video/uvc/uvc_queue.c +--- linux-2.6.29.owrt/drivers/media/video/uvc/uvc_queue.c 2009-05-10 22:04:38.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/drivers/media/video/uvc/uvc_queue.c 2009-05-10 23:48:28.000000000 +0200 +@@ -1,7 +1,7 @@ + /* + * uvc_queue.c -- USB Video Class driver - Buffers management + * +- * Copyright (C) 2005-2009 ++ * Copyright (C) 2005-2008 + * Laurent Pinchart (laurent.pinchart@skynet.be) + * + * This program is free software; you can redistribute it and/or modify +@@ -12,6 +12,7 @@ + */ + + #include <linux/kernel.h> ++#include <linux/version.h> + #include <linux/mm.h> + #include <linux/list.h> + #include <linux/module.h> +@@ -36,22 +37,22 @@ + * to user space will return -EBUSY. + * + * Video buffers are managed using two queues. However, unlike most USB video +- * drivers that use an in queue and an out queue, we use a main queue to hold +- * all queued buffers (both 'empty' and 'done' buffers), and an irq queue to +- * hold empty buffers. This design (copied from video-buf) minimizes locking +- * in interrupt, as only one queue is shared between interrupt and user +- * contexts. ++ * drivers which use an in queue and an out queue, we use a main queue which ++ * holds all queued buffers (both 'empty' and 'done' buffers), and an irq ++ * queue which holds empty buffers. This design (copied from video-buf) ++ * minimizes locking in interrupt, as only one queue is shared between ++ * interrupt and user contexts. + * + * Use cases + * --------- + * +- * Unless stated otherwise, all operations that modify the irq buffers queue ++ * Unless stated otherwise, all operations which modify the irq buffers queue + * are protected by the irq spinlock. + * + * 1. The user queues the buffers, starts streaming and dequeues a buffer. + * + * The buffers are added to the main and irq queues. Both operations are +- * protected by the queue lock, and the later is protected by the irq ++ * protected by the queue lock, and the latert is protected by the irq + * spinlock as well. + * + * The completion handler fetches a buffer from the irq queue and fills it +@@ -59,7 +60,7 @@ + * returns immediately. + * + * When the buffer is full, the completion handler removes it from the irq +- * queue, marks it as ready (UVC_BUF_STATE_DONE) and wakes its wait queue. ++ * queue, marks it as ready (UVC_BUF_STATE_DONE) and wake its wait queue. + * At that point, any process waiting on the buffer will be woken up. If a + * process tries to dequeue a buffer after it has been marked ready, the + * dequeing will succeed immediately. +@@ -90,8 +91,8 @@ + /* + * Allocate the video buffers. + * +- * Pages are reserved to make sure they will not be swapped, as they will be +- * filled in the URB completion handler. ++ * Pages are reserved to make sure they will not be swaped, as they will be ++ * filled in URB completion handler. + * + * Buffers will be individually mapped, so they must all be page aligned. + */ +@@ -209,8 +210,8 @@ + __uvc_query_buffer(&queue->buffer[v4l2_buf->index], v4l2_buf); + + done: +- mutex_unlock(&queue->mutex); +- return ret; ++ mutex_unlock(&queue->mutex); ++ return ret; + } + + /* +@@ -235,7 +236,7 @@ + } + + mutex_lock(&queue->mutex); +- if (v4l2_buf->index >= queue->count) { ++ if (v4l2_buf->index >= queue->count) { + uvc_trace(UVC_TRACE_CAPTURE, "[E] Out of range index.\n"); + ret = -EINVAL; + goto done; +@@ -428,7 +429,7 @@ + * Cancel the video buffers queue. + * + * Cancelling the queue marks all buffers on the irq queue as erroneous, +- * wakes them up and removes them from the queue. ++ * wakes them up and remove them from the queue. + * + * If the disconnect parameter is set, further calls to uvc_queue_buffer will + * fail with -ENODEV. +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/drivers/media/video/uvc/uvc_status.c linux-2.6.29-rc3.owrt/drivers/media/video/uvc/uvc_status.c +--- linux-2.6.29.owrt/drivers/media/video/uvc/uvc_status.c 2009-05-10 22:04:38.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/drivers/media/video/uvc/uvc_status.c 2009-05-10 23:48:28.000000000 +0200 +@@ -1,7 +1,7 @@ + /* + * uvc_status.c -- USB Video Class driver - Status endpoint + * +- * Copyright (C) 2007-2009 ++ * Copyright (C) 2007-2008 + * Laurent Pinchart (laurent.pinchart@skynet.be) + * + * This program is free software; you can redistribute it and/or modify +@@ -12,6 +12,7 @@ + */ + + #include <linux/kernel.h> ++#include <linux/version.h> + #include <linux/input.h> + #include <linux/usb.h> + #include <linux/usb/input.h> +@@ -46,8 +47,8 @@ + usb_to_input_id(udev, &input->id); + input->dev.parent = &dev->intf->dev; + +- __set_bit(EV_KEY, input->evbit); +- __set_bit(KEY_CAMERA, input->keybit); ++ set_bit(EV_KEY, input->evbit); ++ set_bit(BTN_0, input->keybit); + + if ((ret = input_register_device(input)) < 0) + goto error; +@@ -70,10 +71,8 @@ + static void uvc_input_report_key(struct uvc_device *dev, unsigned int code, + int value) + { +- if (dev->input) { ++ if (dev->input) + input_report_key(dev->input, code, value); +- input_sync(dev->input); +- } + } + + #else +@@ -98,7 +97,7 @@ + return; + uvc_trace(UVC_TRACE_STATUS, "Button (intf %u) %s len %d\n", + data[1], data[3] ? "pressed" : "released", len); +- uvc_input_report_key(dev, KEY_CAMERA, data[3]); ++ uvc_input_report_key(dev, BTN_0, data[3]); + } else { + uvc_trace(UVC_TRACE_STATUS, "Stream %u error event %02x %02x " + "len %d.\n", data[1], data[2], data[3], len); +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/drivers/media/video/uvc/uvc_v4l2.c linux-2.6.29-rc3.owrt/drivers/media/video/uvc/uvc_v4l2.c +--- linux-2.6.29.owrt/drivers/media/video/uvc/uvc_v4l2.c 2009-05-10 22:04:38.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/drivers/media/video/uvc/uvc_v4l2.c 2009-05-10 23:48:28.000000000 +0200 +@@ -1,7 +1,7 @@ + /* + * uvc_v4l2.c -- USB Video Class driver - V4L2 API + * +- * Copyright (C) 2005-2009 ++ * Copyright (C) 2005-2008 + * Laurent Pinchart (laurent.pinchart@skynet.be) + * + * This program is free software; you can redistribute it and/or modify +@@ -37,7 +37,7 @@ + * must be grouped (for instance the Red Balance, Blue Balance and Do White + * Balance V4L2 controls use the White Balance Component UVC control) or + * otherwise translated. The approach we take here is to use a translation +- * table for the controls that can be mapped directly, and handle the others ++ * table for the controls which can be mapped directly, and handle the others + * manually. + */ + static int uvc_v4l2_query_menu(struct uvc_video_device *video, +@@ -189,7 +189,7 @@ + probe->dwMaxVideoFrameSize = + video->streaming->ctrl.dwMaxVideoFrameSize; + +- /* Probe the device. */ ++ /* Probe the device */ + if ((ret = uvc_probe_video(video, probe)) < 0) + goto done; + +@@ -354,11 +354,11 @@ + * + * Each open instance of a UVC device can either be in a privileged or + * unprivileged state. Only a single instance can be in a privileged state at +- * a given time. Trying to perform an operation that requires privileges will ++ * a given time. Trying to perform an operation which requires privileges will + * automatically acquire the required privileges if possible, or return -EBUSY + * otherwise. Privileges are dismissed when closing the instance. + * +- * Operations that require privileges are: ++ * Operations which require privileges are: + * + * - VIDIOC_S_INPUT + * - VIDIOC_S_PARM +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/drivers/media/video/uvc/uvc_video.c linux-2.6.29-rc3.owrt/drivers/media/video/uvc/uvc_video.c +--- linux-2.6.29.owrt/drivers/media/video/uvc/uvc_video.c 2009-05-10 22:04:38.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/drivers/media/video/uvc/uvc_video.c 2009-05-10 23:48:28.000000000 +0200 +@@ -1,7 +1,7 @@ + /* + * uvc_video.c -- USB Video Class driver - Video handling + * +- * Copyright (C) 2005-2009 ++ * Copyright (C) 2005-2008 + * Laurent Pinchart (laurent.pinchart@skynet.be) + * + * This program is free software; you can redistribute it and/or modify +@@ -12,6 +12,7 @@ + */ + + #include <linux/kernel.h> ++#include <linux/version.h> + #include <linux/list.h> + #include <linux/module.h> + #include <linux/usb.h> +@@ -114,7 +115,7 @@ + ctrl->wCompQuality = le16_to_cpup((__le16 *)data); + ret = 0; + goto out; +- } else if (query == GET_DEF && probe == 1 && ret != size) { ++ } else if (query == GET_DEF && probe == 1) { + /* Many cameras don't support the GET_DEF request on their + * video probe control. Warn once and return, the caller will + * fall back to GET_CUR. +@@ -159,7 +160,7 @@ + } + + /* Some broken devices return a null or wrong dwMaxVideoFrameSize. +- * Try to get the value from the format and frame descriptors. ++ * Try to get the value from the format and frame descriptor. + */ + uvc_fixup_buffer_size(video, ctrl); + ret = 0; +@@ -190,6 +191,9 @@ + *(__le16 *)&data[12] = cpu_to_le16(ctrl->wCompQuality); + *(__le16 *)&data[14] = cpu_to_le16(ctrl->wCompWindowSize); + *(__le16 *)&data[16] = cpu_to_le16(ctrl->wDelay); ++ /* Note: Some of the fields below are not required for IN devices (see ++ * UVC spec, 4.3.1.1), but we still copy them in case support for OUT ++ * devices is added in the future. */ + put_unaligned_le32(ctrl->dwMaxVideoFrameSize, &data[18]); + put_unaligned_le32(ctrl->dwMaxPayloadTransferSize, &data[22]); + +@@ -396,7 +400,7 @@ + * + * Empty buffers (bytesused == 0) don't trigger end of frame detection + * as it doesn't make sense to return an empty buffer. This also +- * avoids detecting end of frame conditions at FID toggling if the ++ * avoids detecting and of frame conditions at FID toggling if the + * previous payload had the EOF bit set. + */ + if (fid != video->last_fid && buf->buf.bytesused != 0) { +@@ -449,17 +453,6 @@ + } + } + +-/* Video payload encoding is handled by uvc_video_encode_header() and +- * uvc_video_encode_data(). Only bulk transfers are currently supported. +- * +- * uvc_video_encode_header is called at the start of a payload. It adds header +- * data to the transfer buffer and returns the header size. As the only known +- * UVC output device transfers a whole frame in a single payload, the EOF bit +- * is always set in the header. +- * +- * uvc_video_encode_data is called for every URB and copies the data from the +- * video buffer to the transfer buffer. +- */ + static int uvc_video_encode_header(struct uvc_video_device *video, + struct uvc_buffer *buf, __u8 *data, int len) + { +@@ -960,7 +953,7 @@ + } + + /* +- * Reconfigure the video interface and restart streaming if it was enabled ++ * Reconfigure the video interface and restart streaming if it was enable + * before suspend. + * + * If an error occurs, disable the video queue. This will wake all pending +@@ -992,8 +985,8 @@ + */ + + /* +- * Initialize the UVC video device by switching to alternate setting 0 and +- * retrieve the default format. ++ * Initialize the UVC video device by retrieving the default format and ++ * committing it. + * + * Some cameras (namely the Fuji Finepix) set the format and frame + * indexes to zero. The UVC standard doesn't clearly make this a spec +@@ -1021,7 +1014,7 @@ + */ + usb_set_interface(video->dev->udev, video->streaming->intfnum, 0); + +- /* Some webcams don't suport GET_DEF requests on the probe control. We ++ /* Some webcams don't suport GET_DEF request on the probe control. We + * fall back to GET_CUR if GET_DEF fails. + */ + if ((ret = uvc_get_video_ctrl(video, probe, 1, GET_DEF)) < 0 && +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/drivers/media/video/uvc/uvcvideo.h linux-2.6.29-rc3.owrt/drivers/media/video/uvc/uvcvideo.h +--- linux-2.6.29.owrt/drivers/media/video/uvc/uvcvideo.h 2009-05-10 22:04:38.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/drivers/media/video/uvc/uvcvideo.h 2009-05-10 23:48:28.000000000 +0200 +@@ -72,149 +72,149 @@ + * UVC constants + */ + +-#define SC_UNDEFINED 0x00 +-#define SC_VIDEOCONTROL 0x01 +-#define SC_VIDEOSTREAMING 0x02 +-#define SC_VIDEO_INTERFACE_COLLECTION 0x03 +- +-#define PC_PROTOCOL_UNDEFINED 0x00 +- +-#define CS_UNDEFINED 0x20 +-#define CS_DEVICE 0x21 +-#define CS_CONFIGURATION 0x22 +-#define CS_STRING 0x23 +-#define CS_INTERFACE 0x24 +-#define CS_ENDPOINT 0x25 ++#define SC_UNDEFINED 0x00 ++#define SC_VIDEOCONTROL 0x01 ++#define SC_VIDEOSTREAMING 0x02 ++#define SC_VIDEO_INTERFACE_COLLECTION 0x03 ++ ++#define PC_PROTOCOL_UNDEFINED 0x00 ++ ++#define CS_UNDEFINED 0x20 ++#define CS_DEVICE 0x21 ++#define CS_CONFIGURATION 0x22 ++#define CS_STRING 0x23 ++#define CS_INTERFACE 0x24 ++#define CS_ENDPOINT 0x25 + + /* VideoControl class specific interface descriptor */ +-#define VC_DESCRIPTOR_UNDEFINED 0x00 +-#define VC_HEADER 0x01 +-#define VC_INPUT_TERMINAL 0x02 +-#define VC_OUTPUT_TERMINAL 0x03 +-#define VC_SELECTOR_UNIT 0x04 +-#define VC_PROCESSING_UNIT 0x05 +-#define VC_EXTENSION_UNIT 0x06 ++#define VC_DESCRIPTOR_UNDEFINED 0x00 ++#define VC_HEADER 0x01 ++#define VC_INPUT_TERMINAL 0x02 ++#define VC_OUTPUT_TERMINAL 0x03 ++#define VC_SELECTOR_UNIT 0x04 ++#define VC_PROCESSING_UNIT 0x05 ++#define VC_EXTENSION_UNIT 0x06 + + /* VideoStreaming class specific interface descriptor */ +-#define VS_UNDEFINED 0x00 +-#define VS_INPUT_HEADER 0x01 +-#define VS_OUTPUT_HEADER 0x02 +-#define VS_STILL_IMAGE_FRAME 0x03 +-#define VS_FORMAT_UNCOMPRESSED 0x04 +-#define VS_FRAME_UNCOMPRESSED 0x05 +-#define VS_FORMAT_MJPEG 0x06 +-#define VS_FRAME_MJPEG 0x07 +-#define VS_FORMAT_MPEG2TS 0x0a +-#define VS_FORMAT_DV 0x0c +-#define VS_COLORFORMAT 0x0d +-#define VS_FORMAT_FRAME_BASED 0x10 +-#define VS_FRAME_FRAME_BASED 0x11 +-#define VS_FORMAT_STREAM_BASED 0x12 ++#define VS_UNDEFINED 0x00 ++#define VS_INPUT_HEADER 0x01 ++#define VS_OUTPUT_HEADER 0x02 ++#define VS_STILL_IMAGE_FRAME 0x03 ++#define VS_FORMAT_UNCOMPRESSED 0x04 ++#define VS_FRAME_UNCOMPRESSED 0x05 ++#define VS_FORMAT_MJPEG 0x06 ++#define VS_FRAME_MJPEG 0x07 ++#define VS_FORMAT_MPEG2TS 0x0a ++#define VS_FORMAT_DV 0x0c ++#define VS_COLORFORMAT 0x0d ++#define VS_FORMAT_FRAME_BASED 0x10 ++#define VS_FRAME_FRAME_BASED 0x11 ++#define VS_FORMAT_STREAM_BASED 0x12 + + /* Endpoint type */ +-#define EP_UNDEFINED 0x00 +-#define EP_GENERAL 0x01 +-#define EP_ENDPOINT 0x02 +-#define EP_INTERRUPT 0x03 ++#define EP_UNDEFINED 0x00 ++#define EP_GENERAL 0x01 ++#define EP_ENDPOINT 0x02 ++#define EP_INTERRUPT 0x03 + + /* Request codes */ +-#define RC_UNDEFINED 0x00 +-#define SET_CUR 0x01 +-#define GET_CUR 0x81 +-#define GET_MIN 0x82 +-#define GET_MAX 0x83 +-#define GET_RES 0x84 +-#define GET_LEN 0x85 +-#define GET_INFO 0x86 +-#define GET_DEF 0x87 ++#define RC_UNDEFINED 0x00 ++#define SET_CUR 0x01 ++#define GET_CUR 0x81 ++#define GET_MIN 0x82 ++#define GET_MAX 0x83 ++#define GET_RES 0x84 ++#define GET_LEN 0x85 ++#define GET_INFO 0x86 ++#define GET_DEF 0x87 + + /* VideoControl interface controls */ +-#define VC_CONTROL_UNDEFINED 0x00 +-#define VC_VIDEO_POWER_MODE_CONTROL 0x01 +-#define VC_REQUEST_ERROR_CODE_CONTROL 0x02 ++#define VC_CONTROL_UNDEFINED 0x00 ++#define VC_VIDEO_POWER_MODE_CONTROL 0x01 ++#define VC_REQUEST_ERROR_CODE_CONTROL 0x02 + + /* Terminal controls */ +-#define TE_CONTROL_UNDEFINED 0x00 ++#define TE_CONTROL_UNDEFINED 0x00 + + /* Selector Unit controls */ +-#define SU_CONTROL_UNDEFINED 0x00 +-#define SU_INPUT_SELECT_CONTROL 0x01 ++#define SU_CONTROL_UNDEFINED 0x00 ++#define SU_INPUT_SELECT_CONTROL 0x01 + + /* Camera Terminal controls */ +-#define CT_CONTROL_UNDEFINED 0x00 +-#define CT_SCANNING_MODE_CONTROL 0x01 +-#define CT_AE_MODE_CONTROL 0x02 +-#define CT_AE_PRIORITY_CONTROL 0x03 +-#define CT_EXPOSURE_TIME_ABSOLUTE_CONTROL 0x04 +-#define CT_EXPOSURE_TIME_RELATIVE_CONTROL 0x05 +-#define CT_FOCUS_ABSOLUTE_CONTROL 0x06 +-#define CT_FOCUS_RELATIVE_CONTROL 0x07 +-#define CT_FOCUS_AUTO_CONTROL 0x08 +-#define CT_IRIS_ABSOLUTE_CONTROL 0x09 +-#define CT_IRIS_RELATIVE_CONTROL 0x0a +-#define CT_ZOOM_ABSOLUTE_CONTROL 0x0b +-#define CT_ZOOM_RELATIVE_CONTROL 0x0c +-#define CT_PANTILT_ABSOLUTE_CONTROL 0x0d +-#define CT_PANTILT_RELATIVE_CONTROL 0x0e +-#define CT_ROLL_ABSOLUTE_CONTROL 0x0f +-#define CT_ROLL_RELATIVE_CONTROL 0x10 +-#define CT_PRIVACY_CONTROL 0x11 ++#define CT_CONTROL_UNDEFINED 0x00 ++#define CT_SCANNING_MODE_CONTROL 0x01 ++#define CT_AE_MODE_CONTROL 0x02 ++#define CT_AE_PRIORITY_CONTROL 0x03 ++#define CT_EXPOSURE_TIME_ABSOLUTE_CONTROL 0x04 ++#define CT_EXPOSURE_TIME_RELATIVE_CONTROL 0x05 ++#define CT_FOCUS_ABSOLUTE_CONTROL 0x06 ++#define CT_FOCUS_RELATIVE_CONTROL 0x07 ++#define CT_FOCUS_AUTO_CONTROL 0x08 ++#define CT_IRIS_ABSOLUTE_CONTROL 0x09 ++#define CT_IRIS_RELATIVE_CONTROL 0x0a ++#define CT_ZOOM_ABSOLUTE_CONTROL 0x0b ++#define CT_ZOOM_RELATIVE_CONTROL 0x0c ++#define CT_PANTILT_ABSOLUTE_CONTROL 0x0d ++#define CT_PANTILT_RELATIVE_CONTROL 0x0e ++#define CT_ROLL_ABSOLUTE_CONTROL 0x0f ++#define CT_ROLL_RELATIVE_CONTROL 0x10 ++#define CT_PRIVACY_CONTROL 0x11 + + /* Processing Unit controls */ +-#define PU_CONTROL_UNDEFINED 0x00 +-#define PU_BACKLIGHT_COMPENSATION_CONTROL 0x01 +-#define PU_BRIGHTNESS_CONTROL 0x02 +-#define PU_CONTRAST_CONTROL 0x03 +-#define PU_GAIN_CONTROL 0x04 +-#define PU_POWER_LINE_FREQUENCY_CONTROL 0x05 +-#define PU_HUE_CONTROL 0x06 +-#define PU_SATURATION_CONTROL 0x07 +-#define PU_SHARPNESS_CONTROL 0x08 +-#define PU_GAMMA_CONTROL 0x09 +-#define PU_WHITE_BALANCE_TEMPERATURE_CONTROL 0x0a +-#define PU_WHITE_BALANCE_TEMPERATURE_AUTO_CONTROL 0x0b +-#define PU_WHITE_BALANCE_COMPONENT_CONTROL 0x0c +-#define PU_WHITE_BALANCE_COMPONENT_AUTO_CONTROL 0x0d +-#define PU_DIGITAL_MULTIPLIER_CONTROL 0x0e +-#define PU_DIGITAL_MULTIPLIER_LIMIT_CONTROL 0x0f +-#define PU_HUE_AUTO_CONTROL 0x10 +-#define PU_ANALOG_VIDEO_STANDARD_CONTROL 0x11 +-#define PU_ANALOG_LOCK_STATUS_CONTROL 0x12 ++#define PU_CONTROL_UNDEFINED 0x00 ++#define PU_BACKLIGHT_COMPENSATION_CONTROL 0x01 ++#define PU_BRIGHTNESS_CONTROL 0x02 ++#define PU_CONTRAST_CONTROL 0x03 ++#define PU_GAIN_CONTROL 0x04 ++#define PU_POWER_LINE_FREQUENCY_CONTROL 0x05 ++#define PU_HUE_CONTROL 0x06 ++#define PU_SATURATION_CONTROL 0x07 ++#define PU_SHARPNESS_CONTROL 0x08 ++#define PU_GAMMA_CONTROL 0x09 ++#define PU_WHITE_BALANCE_TEMPERATURE_CONTROL 0x0a ++#define PU_WHITE_BALANCE_TEMPERATURE_AUTO_CONTROL 0x0b ++#define PU_WHITE_BALANCE_COMPONENT_CONTROL 0x0c ++#define PU_WHITE_BALANCE_COMPONENT_AUTO_CONTROL 0x0d ++#define PU_DIGITAL_MULTIPLIER_CONTROL 0x0e ++#define PU_DIGITAL_MULTIPLIER_LIMIT_CONTROL 0x0f ++#define PU_HUE_AUTO_CONTROL 0x10 ++#define PU_ANALOG_VIDEO_STANDARD_CONTROL 0x11 ++#define PU_ANALOG_LOCK_STATUS_CONTROL 0x12 + + #define LXU_MOTOR_PANTILT_RELATIVE_CONTROL 0x01 + #define LXU_MOTOR_PANTILT_RESET_CONTROL 0x02 + #define LXU_MOTOR_FOCUS_MOTOR_CONTROL 0x03 + + /* VideoStreaming interface controls */ +-#define VS_CONTROL_UNDEFINED 0x00 +-#define VS_PROBE_CONTROL 0x01 +-#define VS_COMMIT_CONTROL 0x02 +-#define VS_STILL_PROBE_CONTROL 0x03 +-#define VS_STILL_COMMIT_CONTROL 0x04 +-#define VS_STILL_IMAGE_TRIGGER_CONTROL 0x05 +-#define VS_STREAM_ERROR_CODE_CONTROL 0x06 +-#define VS_GENERATE_KEY_FRAME_CONTROL 0x07 +-#define VS_UPDATE_FRAME_SEGMENT_CONTROL 0x08 +-#define VS_SYNC_DELAY_CONTROL 0x09 ++#define VS_CONTROL_UNDEFINED 0x00 ++#define VS_PROBE_CONTROL 0x01 ++#define VS_COMMIT_CONTROL 0x02 ++#define VS_STILL_PROBE_CONTROL 0x03 ++#define VS_STILL_COMMIT_CONTROL 0x04 ++#define VS_STILL_IMAGE_TRIGGER_CONTROL 0x05 ++#define VS_STREAM_ERROR_CODE_CONTROL 0x06 ++#define VS_GENERATE_KEY_FRAME_CONTROL 0x07 ++#define VS_UPDATE_FRAME_SEGMENT_CONTROL 0x08 ++#define VS_SYNC_DELAY_CONTROL 0x09 + +-#define TT_VENDOR_SPECIFIC 0x0100 +-#define TT_STREAMING 0x0101 ++#define TT_VENDOR_SPECIFIC 0x0100 ++#define TT_STREAMING 0x0101 + + /* Input Terminal types */ +-#define ITT_VENDOR_SPECIFIC 0x0200 +-#define ITT_CAMERA 0x0201 +-#define ITT_MEDIA_TRANSPORT_INPUT 0x0202 ++#define ITT_VENDOR_SPECIFIC 0x0200 ++#define ITT_CAMERA 0x0201 ++#define ITT_MEDIA_TRANSPORT_INPUT 0x0202 + + /* Output Terminal types */ +-#define OTT_VENDOR_SPECIFIC 0x0300 +-#define OTT_DISPLAY 0x0301 +-#define OTT_MEDIA_TRANSPORT_OUTPUT 0x0302 ++#define OTT_VENDOR_SPECIFIC 0x0300 ++#define OTT_DISPLAY 0x0301 ++#define OTT_MEDIA_TRANSPORT_OUTPUT 0x0302 + + /* External Terminal types */ +-#define EXTERNAL_VENDOR_SPECIFIC 0x0400 +-#define COMPOSITE_CONNECTOR 0x0401 +-#define SVIDEO_CONNECTOR 0x0402 +-#define COMPONENT_CONNECTOR 0x0403 ++#define EXTERNAL_VENDOR_SPECIFIC 0x0400 ++#define COMPOSITE_CONNECTOR 0x0401 ++#define SVIDEO_CONNECTOR 0x0402 ++#define COMPONENT_CONNECTOR 0x0403 + + #define UVC_TERM_INPUT 0x0000 + #define UVC_TERM_OUTPUT 0x8000 +@@ -541,11 +541,11 @@ + }; + + enum uvc_buffer_state { +- UVC_BUF_STATE_IDLE = 0, +- UVC_BUF_STATE_QUEUED = 1, +- UVC_BUF_STATE_ACTIVE = 2, +- UVC_BUF_STATE_DONE = 3, +- UVC_BUF_STATE_ERROR = 4, ++ UVC_BUF_STATE_IDLE = 0, ++ UVC_BUF_STATE_QUEUED = 1, ++ UVC_BUF_STATE_ACTIVE = 2, ++ UVC_BUF_STATE_DONE = 3, ++ UVC_BUF_STATE_ERROR = 4, + }; + + struct uvc_buffer { +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/drivers/media/video/v4l2-subdev.c linux-2.6.29-rc3.owrt/drivers/media/video/v4l2-subdev.c +--- linux-2.6.29.owrt/drivers/media/video/v4l2-subdev.c 2009-05-10 22:04:38.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/drivers/media/video/v4l2-subdev.c 2009-05-10 23:48:28.000000000 +0200 +@@ -28,13 +28,13 @@ + { + switch (cmd) { + case VIDIOC_QUERYCTRL: +- return v4l2_subdev_call(sd, core, queryctrl, arg); ++ return v4l2_subdev_call(sd, core, querymenu, arg); + case VIDIOC_G_CTRL: + return v4l2_subdev_call(sd, core, g_ctrl, arg); + case VIDIOC_S_CTRL: + return v4l2_subdev_call(sd, core, s_ctrl, arg); + case VIDIOC_QUERYMENU: +- return v4l2_subdev_call(sd, core, querymenu, arg); ++ return v4l2_subdev_call(sd, core, queryctrl, arg); + case VIDIOC_LOG_STATUS: + return v4l2_subdev_call(sd, core, log_status); + case VIDIOC_DBG_G_CHIP_IDENT: +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/drivers/media/video/zoran/Kconfig linux-2.6.29-rc3.owrt/drivers/media/video/zoran/Kconfig +--- linux-2.6.29.owrt/drivers/media/video/zoran/Kconfig 2009-05-10 22:04:38.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/drivers/media/video/zoran/Kconfig 2009-05-10 23:48:28.000000000 +0200 +@@ -68,7 +68,6 @@ + tristate "AverMedia 6 Eyes support (EXPERIMENTAL)" + depends on VIDEO_ZORAN_ZR36060 && EXPERIMENTAL && VIDEO_V4L1 + select VIDEO_BT856 if VIDEO_HELPER_CHIPS_AUTO +- select VIDEO_BT866 if VIDEO_HELPER_CHIPS_AUTO + select VIDEO_KS0127 if VIDEO_HELPER_CHIPS_AUTO + help + Support for the AverMedia 6 Eyes video surveillance card. +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/drivers/media/video/zoran/zoran_card.c linux-2.6.29-rc3.owrt/drivers/media/video/zoran/zoran_card.c +--- linux-2.6.29.owrt/drivers/media/video/zoran/zoran_card.c 2009-05-10 22:04:38.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/drivers/media/video/zoran/zoran_card.c 2009-05-10 23:48:28.000000000 +0200 +@@ -61,17 +61,17 @@ + + extern const struct zoran_format zoran_formats[]; + +-static int card[BUZ_MAX] = { [0 ... (BUZ_MAX-1)] = -1 }; ++static int card[BUZ_MAX] = { -1, -1, -1, -1 }; + module_param_array(card, int, NULL, 0444); +-MODULE_PARM_DESC(card, "Card type"); ++MODULE_PARM_DESC(card, "The type of card"); + +-static int encoder[BUZ_MAX] = { [0 ... (BUZ_MAX-1)] = -1 }; ++static int encoder[BUZ_MAX] = { -1, -1, -1, -1 }; + module_param_array(encoder, int, NULL, 0444); +-MODULE_PARM_DESC(encoder, "Video encoder chip"); ++MODULE_PARM_DESC(encoder, "i2c TV encoder"); + +-static int decoder[BUZ_MAX] = { [0 ... (BUZ_MAX-1)] = -1 }; ++static int decoder[BUZ_MAX] = { -1, -1, -1, -1 }; + module_param_array(decoder, int, NULL, 0444); +-MODULE_PARM_DESC(decoder, "Video decoder chip"); ++MODULE_PARM_DESC(decoder, "i2c TV decoder"); + + /* + The video mem address of the video card. +@@ -104,9 +104,9 @@ + MODULE_PARM_DESC(default_norm, "Default norm (0=PAL, 1=NTSC, 2=SECAM)"); + + /* /dev/videoN, -1 for autodetect */ +-static int video_nr[BUZ_MAX] = { [0 ... (BUZ_MAX-1)] = -1 }; ++static int video_nr[BUZ_MAX] = {-1, -1, -1, -1}; + module_param_array(video_nr, int, NULL, 0444); +-MODULE_PARM_DESC(video_nr, "Video device number (-1=Auto)"); ++MODULE_PARM_DESC(video_nr, "video device number (-1=Auto)"); + + /* + Number and size of grab buffers for Video 4 Linux +@@ -153,21 +153,9 @@ + MODULE_AUTHOR("Serguei Miridonov"); + MODULE_LICENSE("GPL"); + +-#define ZR_DEVICE(subven, subdev, data) { \ +- .vendor = PCI_VENDOR_ID_ZORAN, .device = PCI_DEVICE_ID_ZORAN_36057, \ +- .subvendor = (subven), .subdevice = (subdev), .driver_data = (data) } +- +-static struct pci_device_id zr36067_pci_tbl[] = { +- ZR_DEVICE(PCI_VENDOR_ID_MIRO, PCI_DEVICE_ID_MIRO_DC10PLUS, DC10plus), +- ZR_DEVICE(PCI_VENDOR_ID_MIRO, PCI_DEVICE_ID_MIRO_DC30PLUS, DC30plus), +- ZR_DEVICE(PCI_VENDOR_ID_ELECTRONICDESIGNGMBH, PCI_DEVICE_ID_LML_33R10, LML33R10), +- ZR_DEVICE(PCI_VENDOR_ID_IOMEGA, PCI_DEVICE_ID_IOMEGA_BUZ, BUZ), +- ZR_DEVICE(PCI_ANY_ID, PCI_ANY_ID, NUM_CARDS), +- {0} +-}; +-MODULE_DEVICE_TABLE(pci, zr36067_pci_tbl); + +-static unsigned int zoran_num; /* number of cards found */ ++int zoran_num; /* number of Buzs in use */ ++struct zoran *zoran[BUZ_MAX]; + + /* videocodec bus functions ZR36060 */ + static u32 +@@ -484,6 +472,8 @@ + }, { + .type = DC10plus, + .name = "DC10plus", ++ .vendor_id = PCI_VENDOR_ID_MIRO, ++ .device_id = PCI_DEVICE_ID_MIRO_DC10PLUS, + .i2c_decoder = I2C_DRIVERID_SAA7110, + .i2c_encoder = I2C_DRIVERID_ADV7175, + .video_codec = CODEC_TYPE_ZR36060, +@@ -541,6 +531,8 @@ + }, { + .type = DC30plus, + .name = "DC30plus", ++ .vendor_id = PCI_VENDOR_ID_MIRO, ++ .device_id = PCI_DEVICE_ID_MIRO_DC30PLUS, + .i2c_decoder = I2C_DRIVERID_VPX3220, + .i2c_encoder = I2C_DRIVERID_ADV7175, + .video_codec = CODEC_TYPE_ZR36050, +@@ -597,6 +589,8 @@ + }, { + .type = LML33R10, + .name = "LML33R10", ++ .vendor_id = PCI_VENDOR_ID_ELECTRONICDESIGNGMBH, ++ .device_id = PCI_DEVICE_ID_LML_33R10, + .i2c_decoder = I2C_DRIVERID_SAA7114, + .i2c_encoder = I2C_DRIVERID_ADV7170, + .video_codec = CODEC_TYPE_ZR36060, +@@ -624,6 +618,8 @@ + }, { + .type = BUZ, + .name = "Buz", ++ .vendor_id = PCI_VENDOR_ID_IOMEGA, ++ .device_id = PCI_DEVICE_ID_IOMEGA_BUZ, + .i2c_decoder = I2C_DRIVERID_SAA7111A, + .i2c_encoder = I2C_DRIVERID_SAA7185B, + .video_codec = CODEC_TYPE_ZR36060, +@@ -653,6 +649,8 @@ + .name = "6-Eyes", + /* AverMedia chose not to brand the 6-Eyes. Thus it + can't be autodetected, and requires card=x. */ ++ .vendor_id = -1, ++ .device_id = -1, + .i2c_decoder = I2C_DRIVERID_KS0127, + .i2c_encoder = I2C_DRIVERID_BT866, + .video_codec = CODEC_TYPE_ZR36060, +@@ -1140,8 +1138,7 @@ + strcpy(zr->video_dev->name, ZR_DEVNAME(zr)); + err = video_register_device(zr->video_dev, VFL_TYPE_GRABBER, video_nr[zr->id]); + if (err < 0) +- goto exit_free; +- video_set_drvdata(zr->video_dev, zr); ++ goto exit_unregister; + + zoran_init_hardware(zr); + if (zr36067_debug > 2) +@@ -1156,19 +1153,19 @@ + zr->initialized = 1; + return 0; + ++exit_unregister: ++ zoran_unregister_i2c(zr); + exit_free: + kfree(zr->stat_com); + kfree(zr->video_dev); + return err; + } + +-static void __devexit zoran_remove(struct pci_dev *pdev) ++static void ++zoran_release (struct zoran *zr) + { +- struct zoran *zr = pci_get_drvdata(pdev); +- + if (!zr->initialized) + goto exit_free; +- + /* unregister videocodec bus */ + if (zr->codec) { + struct videocodec_master *master = zr->codec->master_data; +@@ -1197,7 +1194,6 @@ + pci_disable_device(zr->pci_dev); + video_unregister_device(zr->video_dev); + exit_free: +- pci_set_drvdata(pdev, NULL); + kfree(zr); + } + +@@ -1260,329 +1256,338 @@ + * Scan for a Buz card (actually for the PCI controller ZR36057), + * request the irq and map the io memory + */ +-static int __devinit zoran_probe(struct pci_dev *pdev, +- const struct pci_device_id *ent) ++static int __devinit ++find_zr36057 (void) + { + unsigned char latency, need_latency; + struct zoran *zr; ++ struct pci_dev *dev = NULL; + int result; + struct videocodec_master *master_vfe = NULL; + struct videocodec_master *master_codec = NULL; + int card_num; + char *i2c_enc_name, *i2c_dec_name, *codec_name, *vfe_name; +- unsigned int nr; +- +- +- nr = zoran_num++; +- if (nr >= BUZ_MAX) { +- dprintk(1, +- KERN_ERR +- "%s: driver limited to %d card(s) maximum\n", +- ZORAN_NAME, BUZ_MAX); +- return -ENOENT; +- } + +- zr = kzalloc(sizeof(struct zoran), GFP_KERNEL); +- if (!zr) { +- dprintk(1, +- KERN_ERR +- "%s: find_zr36057() - kzalloc failed\n", +- ZORAN_NAME); +- return -ENOMEM; +- } +- zr->pci_dev = pdev; +- zr->id = nr; +- snprintf(ZR_DEVNAME(zr), sizeof(ZR_DEVNAME(zr)), "MJPEG[%u]", zr->id); +- spin_lock_init(&zr->spinlock); +- mutex_init(&zr->resource_lock); +- if (pci_enable_device(pdev)) +- goto zr_free_mem; +- pci_read_config_byte(zr->pci_dev, PCI_CLASS_REVISION, &zr->revision); ++ zoran_num = 0; ++ while (zoran_num < BUZ_MAX && ++ (dev = pci_get_device(PCI_VENDOR_ID_ZORAN, PCI_DEVICE_ID_ZORAN_36057, dev)) != NULL) { ++ card_num = card[zoran_num]; ++ zr = kzalloc(sizeof(struct zoran), GFP_KERNEL); ++ if (!zr) { ++ dprintk(1, ++ KERN_ERR ++ "%s: find_zr36057() - kzalloc failed\n", ++ ZORAN_NAME); ++ continue; ++ } ++ zr->pci_dev = dev; ++ //zr->zr36057_mem = NULL; ++ zr->id = zoran_num; ++ snprintf(ZR_DEVNAME(zr), sizeof(ZR_DEVNAME(zr)), "MJPEG[%u]", zr->id); ++ spin_lock_init(&zr->spinlock); ++ mutex_init(&zr->resource_lock); ++ if (pci_enable_device(dev)) ++ goto zr_free_mem; ++ zr->zr36057_adr = pci_resource_start(zr->pci_dev, 0); ++ pci_read_config_byte(zr->pci_dev, PCI_CLASS_REVISION, ++ &zr->revision); ++ if (zr->revision < 2) { ++ dprintk(1, ++ KERN_INFO ++ "%s: Zoran ZR36057 (rev %d) irq: %d, memory: 0x%08x.\n", ++ ZR_DEVNAME(zr), zr->revision, zr->pci_dev->irq, ++ zr->zr36057_adr); + +- dprintk(1, +- KERN_INFO +- "%s: Zoran ZR360%c7 (rev %d), irq: %d, memory: 0x%08llx\n", +- ZR_DEVNAME(zr), zr->revision < 2 ? '5' : '6', zr->revision, +- zr->pci_dev->irq, (uint64_t)pci_resource_start(zr->pci_dev, 0)); +- if (zr->revision >= 2) { +- dprintk(1, +- KERN_INFO +- "%s: Subsystem vendor=0x%04x id=0x%04x\n", +- ZR_DEVNAME(zr), zr->pci_dev->subsystem_vendor, +- zr->pci_dev->subsystem_device); +- } ++ if (card_num == -1) { ++ dprintk(1, ++ KERN_ERR ++ "%s: find_zr36057() - no card specified, please use the card=X insmod option\n", ++ ZR_DEVNAME(zr)); ++ goto zr_free_mem; ++ } ++ } else { ++ int i; ++ unsigned short ss_vendor, ss_device; + +- /* Use auto-detected card type? */ +- if (card[nr] == -1) { +- if (zr->revision < 2) { ++ ss_vendor = zr->pci_dev->subsystem_vendor; ++ ss_device = zr->pci_dev->subsystem_device; + dprintk(1, +- KERN_ERR +- "%s: No card type specified, please use the card=X module parameter\n", +- ZR_DEVNAME(zr)); ++ KERN_INFO ++ "%s: Zoran ZR36067 (rev %d) irq: %d, memory: 0x%08x\n", ++ ZR_DEVNAME(zr), zr->revision, zr->pci_dev->irq, ++ zr->zr36057_adr); + dprintk(1, ++ KERN_INFO ++ "%s: subsystem vendor=0x%04x id=0x%04x\n", ++ ZR_DEVNAME(zr), ss_vendor, ss_device); ++ if (card_num == -1) { ++ dprintk(3, ++ KERN_DEBUG ++ "%s: find_zr36057() - trying to autodetect card type\n", ++ ZR_DEVNAME(zr)); ++ for (i=0;i<NUM_CARDS;i++) { ++ if (ss_vendor == zoran_cards[i].vendor_id && ++ ss_device == zoran_cards[i].device_id) { ++ dprintk(3, ++ KERN_DEBUG ++ "%s: find_zr36057() - card %s detected\n", ++ ZR_DEVNAME(zr), ++ zoran_cards[i].name); ++ card_num = i; ++ break; ++ } ++ } ++ if (i == NUM_CARDS) { ++ dprintk(1, ++ KERN_ERR ++ "%s: find_zr36057() - unknown card\n", ++ ZR_DEVNAME(zr)); ++ goto zr_free_mem; ++ } ++ } ++ } ++ ++ if (card_num < 0 || card_num >= NUM_CARDS) { ++ dprintk(2, + KERN_ERR +- "%s: It is not possible to auto-detect ZR36057 based cards\n", +- ZR_DEVNAME(zr)); ++ "%s: find_zr36057() - invalid cardnum %d\n", ++ ZR_DEVNAME(zr), card_num); + goto zr_free_mem; + } + +- card_num = ent->driver_data; +- if (card_num >= NUM_CARDS) { ++ /* even though we make this a non pointer and thus ++ * theoretically allow for making changes to this struct ++ * on a per-individual card basis at runtime, this is ++ * strongly discouraged. This structure is intended to ++ * keep general card information, no settings or anything */ ++ zr->card = zoran_cards[card_num]; ++ snprintf(ZR_DEVNAME(zr), sizeof(ZR_DEVNAME(zr)), ++ "%s[%u]", zr->card.name, zr->id); ++ ++ zr->zr36057_mem = ioremap_nocache(zr->zr36057_adr, 0x1000); ++ if (!zr->zr36057_mem) { + dprintk(1, + KERN_ERR +- "%s: Unknown card, try specifying card=X module parameter\n", ++ "%s: find_zr36057() - ioremap failed\n", + ZR_DEVNAME(zr)); + goto zr_free_mem; + } +- dprintk(3, +- KERN_DEBUG +- "%s: %s() - card %s detected\n", +- ZR_DEVNAME(zr), __func__, zoran_cards[card_num].name); +- } else { +- card_num = card[nr]; +- if (card_num >= NUM_CARDS || card_num < 0) { +- dprintk(1, +- KERN_ERR +- "%s: User specified card type %d out of range (0 .. %d)\n", +- ZR_DEVNAME(zr), card_num, NUM_CARDS - 1); +- goto zr_free_mem; ++ ++ result = request_irq(zr->pci_dev->irq, ++ zoran_irq, ++ IRQF_SHARED | IRQF_DISABLED, ++ ZR_DEVNAME(zr), ++ (void *) zr); ++ if (result < 0) { ++ if (result == -EINVAL) { ++ dprintk(1, ++ KERN_ERR ++ "%s: find_zr36057() - bad irq number or handler\n", ++ ZR_DEVNAME(zr)); ++ } else if (result == -EBUSY) { ++ dprintk(1, ++ KERN_ERR ++ "%s: find_zr36057() - IRQ %d busy, change your PnP config in BIOS\n", ++ ZR_DEVNAME(zr), zr->pci_dev->irq); ++ } else { ++ dprintk(1, ++ KERN_ERR ++ "%s: find_zr36057() - can't assign irq, error code %d\n", ++ ZR_DEVNAME(zr), result); ++ } ++ goto zr_unmap; + } +- } + +- /* even though we make this a non pointer and thus +- * theoretically allow for making changes to this struct +- * on a per-individual card basis at runtime, this is +- * strongly discouraged. This structure is intended to +- * keep general card information, no settings or anything */ +- zr->card = zoran_cards[card_num]; +- snprintf(ZR_DEVNAME(zr), sizeof(ZR_DEVNAME(zr)), +- "%s[%u]", zr->card.name, zr->id); ++ /* set PCI latency timer */ ++ pci_read_config_byte(zr->pci_dev, PCI_LATENCY_TIMER, ++ &latency); ++ need_latency = zr->revision > 1 ? 32 : 48; ++ if (latency != need_latency) { ++ dprintk(2, ++ KERN_INFO ++ "%s: Changing PCI latency from %d to %d.\n", ++ ZR_DEVNAME(zr), latency, need_latency); ++ pci_write_config_byte(zr->pci_dev, ++ PCI_LATENCY_TIMER, ++ need_latency); ++ } + +- zr->zr36057_mem = pci_ioremap_bar(zr->pci_dev, 0); +- if (!zr->zr36057_mem) { +- dprintk(1, +- KERN_ERR +- "%s: %s() - ioremap failed\n", +- ZR_DEVNAME(zr), __func__); +- goto zr_free_mem; +- } ++ zr36057_restart(zr); ++ /* i2c */ ++ dprintk(2, KERN_INFO "%s: Initializing i2c bus...\n", ++ ZR_DEVNAME(zr)); + +- result = request_irq(zr->pci_dev->irq, zoran_irq, +- IRQF_SHARED | IRQF_DISABLED, ZR_DEVNAME(zr), zr); +- if (result < 0) { +- if (result == -EINVAL) { +- dprintk(1, +- KERN_ERR +- "%s: find_zr36057() - bad irq number or handler\n", +- ZR_DEVNAME(zr)); +- } else if (result == -EBUSY) { +- dprintk(1, +- KERN_ERR +- "%s: find_zr36057() - IRQ %d busy, change your PnP config in BIOS\n", +- ZR_DEVNAME(zr), zr->pci_dev->irq); ++ /* i2c decoder */ ++ if (decoder[zr->id] != -1) { ++ i2c_dec_name = i2cid_to_modulename(decoder[zr->id]); ++ zr->card.i2c_decoder = decoder[zr->id]; ++ } else if (zr->card.i2c_decoder != 0) { ++ i2c_dec_name = ++ i2cid_to_modulename(zr->card.i2c_decoder); + } else { +- dprintk(1, +- KERN_ERR +- "%s: find_zr36057() - can't assign irq, error code %d\n", +- ZR_DEVNAME(zr), result); ++ i2c_dec_name = NULL; + } +- goto zr_unmap; +- } + +- /* set PCI latency timer */ +- pci_read_config_byte(zr->pci_dev, PCI_LATENCY_TIMER, +- &latency); +- need_latency = zr->revision > 1 ? 32 : 48; +- if (latency != need_latency) { +- dprintk(2, +- KERN_INFO +- "%s: Changing PCI latency from %d to %d\n", +- ZR_DEVNAME(zr), latency, need_latency); +- pci_write_config_byte(zr->pci_dev, PCI_LATENCY_TIMER, +- need_latency); +- } +- +- zr36057_restart(zr); +- /* i2c */ +- dprintk(2, KERN_INFO "%s: Initializing i2c bus...\n", +- ZR_DEVNAME(zr)); +- +- /* i2c decoder */ +- if (decoder[zr->id] != -1) { +- i2c_dec_name = i2cid_to_modulename(decoder[zr->id]); +- zr->card.i2c_decoder = decoder[zr->id]; +- } else if (zr->card.i2c_decoder != 0) { +- i2c_dec_name = i2cid_to_modulename(zr->card.i2c_decoder); +- } else { +- i2c_dec_name = NULL; +- } ++ if (i2c_dec_name) { ++ if ((result = request_module(i2c_dec_name)) < 0) { ++ dprintk(1, ++ KERN_ERR ++ "%s: failed to load module %s: %d\n", ++ ZR_DEVNAME(zr), i2c_dec_name, result); ++ } ++ } + +- if (i2c_dec_name) { +- result = request_module(i2c_dec_name); +- if (result < 0) { +- dprintk(1, +- KERN_ERR +- "%s: failed to load module %s: %d\n", +- ZR_DEVNAME(zr), i2c_dec_name, result); ++ /* i2c encoder */ ++ if (encoder[zr->id] != -1) { ++ i2c_enc_name = i2cid_to_modulename(encoder[zr->id]); ++ zr->card.i2c_encoder = encoder[zr->id]; ++ } else if (zr->card.i2c_encoder != 0) { ++ i2c_enc_name = ++ i2cid_to_modulename(zr->card.i2c_encoder); ++ } else { ++ i2c_enc_name = NULL; + } +- } + +- /* i2c encoder */ +- if (encoder[zr->id] != -1) { +- i2c_enc_name = i2cid_to_modulename(encoder[zr->id]); +- zr->card.i2c_encoder = encoder[zr->id]; +- } else if (zr->card.i2c_encoder != 0) { +- i2c_enc_name = i2cid_to_modulename(zr->card.i2c_encoder); +- } else { +- i2c_enc_name = NULL; +- } ++ if (i2c_enc_name) { ++ if ((result = request_module(i2c_enc_name)) < 0) { ++ dprintk(1, ++ KERN_ERR ++ "%s: failed to load module %s: %d\n", ++ ZR_DEVNAME(zr), i2c_enc_name, result); ++ } ++ } + +- if (i2c_enc_name) { +- result = request_module(i2c_enc_name); +- if (result < 0) { ++ if (zoran_register_i2c(zr) < 0) { + dprintk(1, + KERN_ERR +- "%s: failed to load module %s: %d\n", +- ZR_DEVNAME(zr), i2c_enc_name, result); ++ "%s: find_zr36057() - can't initialize i2c bus\n", ++ ZR_DEVNAME(zr)); ++ goto zr_free_irq; + } +- } + +- if (zoran_register_i2c(zr) < 0) { +- dprintk(1, +- KERN_ERR +- "%s: find_zr36057() - can't initialize i2c bus\n", ++ dprintk(2, ++ KERN_INFO "%s: Initializing videocodec bus...\n", + ZR_DEVNAME(zr)); +- goto zr_free_irq; +- } +- +- dprintk(2, +- KERN_INFO "%s: Initializing videocodec bus...\n", +- ZR_DEVNAME(zr)); + +- if (zr->card.video_codec) { +- codec_name = codecid_to_modulename(zr->card.video_codec); +- if (codec_name) { +- result = request_module(codec_name); +- if (result) { ++ if (zr->card.video_codec != 0 && ++ (codec_name = ++ codecid_to_modulename(zr->card.video_codec)) != NULL) { ++ if ((result = request_module(codec_name)) < 0) { + dprintk(1, + KERN_ERR + "%s: failed to load modules %s: %d\n", + ZR_DEVNAME(zr), codec_name, result); + } + } +- } +- if (zr->card.video_vfe) { +- vfe_name = codecid_to_modulename(zr->card.video_vfe); +- if (vfe_name) { +- result = request_module(vfe_name); +- if (result < 0) { ++ if (zr->card.video_vfe != 0 && ++ (vfe_name = ++ codecid_to_modulename(zr->card.video_vfe)) != NULL) { ++ if ((result = request_module(vfe_name)) < 0) { + dprintk(1, + KERN_ERR + "%s: failed to load modules %s: %d\n", + ZR_DEVNAME(zr), vfe_name, result); + } + } +- } + +- /* reset JPEG codec */ +- jpeg_codec_sleep(zr, 1); +- jpeg_codec_reset(zr); +- /* video bus enabled */ +- /* display codec revision */ +- if (zr->card.video_codec != 0) { +- master_codec = zoran_setup_videocodec(zr, zr->card.video_codec); +- if (!master_codec) +- goto zr_unreg_i2c; +- zr->codec = videocodec_attach(master_codec); +- if (!zr->codec) { +- dprintk(1, +- KERN_ERR +- "%s: find_zr36057() - no codec found\n", +- ZR_DEVNAME(zr)); +- goto zr_free_codec; +- } +- if (zr->codec->type != zr->card.video_codec) { +- dprintk(1, +- KERN_ERR +- "%s: find_zr36057() - wrong codec\n", +- ZR_DEVNAME(zr)); +- goto zr_detach_codec; +- } +- } +- if (zr->card.video_vfe != 0) { +- master_vfe = zoran_setup_videocodec(zr, zr->card.video_vfe); +- if (!master_vfe) +- goto zr_detach_codec; +- zr->vfe = videocodec_attach(master_vfe); +- if (!zr->vfe) { +- dprintk(1, +- KERN_ERR +- "%s: find_zr36057() - no VFE found\n", +- ZR_DEVNAME(zr)); +- goto zr_free_vfe; ++ /* reset JPEG codec */ ++ jpeg_codec_sleep(zr, 1); ++ jpeg_codec_reset(zr); ++ /* video bus enabled */ ++ /* display codec revision */ ++ if (zr->card.video_codec != 0) { ++ master_codec = zoran_setup_videocodec(zr, ++ zr->card.video_codec); ++ if (!master_codec) ++ goto zr_unreg_i2c; ++ zr->codec = videocodec_attach(master_codec); ++ if (!zr->codec) { ++ dprintk(1, ++ KERN_ERR ++ "%s: find_zr36057() - no codec found\n", ++ ZR_DEVNAME(zr)); ++ goto zr_free_codec; ++ } ++ if (zr->codec->type != zr->card.video_codec) { ++ dprintk(1, ++ KERN_ERR ++ "%s: find_zr36057() - wrong codec\n", ++ ZR_DEVNAME(zr)); ++ goto zr_detach_codec; ++ } + } +- if (zr->vfe->type != zr->card.video_vfe) { +- dprintk(1, +- KERN_ERR +- "%s: find_zr36057() = wrong VFE\n", +- ZR_DEVNAME(zr)); +- goto zr_detach_vfe; ++ if (zr->card.video_vfe != 0) { ++ master_vfe = zoran_setup_videocodec(zr, ++ zr->card.video_vfe); ++ if (!master_vfe) ++ goto zr_detach_codec; ++ zr->vfe = videocodec_attach(master_vfe); ++ if (!zr->vfe) { ++ dprintk(1, ++ KERN_ERR ++ "%s: find_zr36057() - no VFE found\n", ++ ZR_DEVNAME(zr)); ++ goto zr_free_vfe; ++ } ++ if (zr->vfe->type != zr->card.video_vfe) { ++ dprintk(1, ++ KERN_ERR ++ "%s: find_zr36057() = wrong VFE\n", ++ ZR_DEVNAME(zr)); ++ goto zr_detach_vfe; ++ } + } +- } +- +- /* take care of Natoma chipset and a revision 1 zr36057 */ +- if ((pci_pci_problems & PCIPCI_NATOMA) && zr->revision <= 1) { +- zr->jpg_buffers.need_contiguous = 1; +- dprintk(1, +- KERN_INFO +- "%s: ZR36057/Natoma bug, max. buffer size is 128K\n", +- ZR_DEVNAME(zr)); +- } ++ /* Success so keep the pci_dev referenced */ ++ pci_dev_get(zr->pci_dev); ++ zoran[zoran_num++] = zr; ++ continue; + +- if (zr36057_init(zr) < 0) +- goto zr_detach_vfe; +- +- zoran_proc_init(zr); +- +- pci_set_drvdata(pdev, zr); +- +- return 0; +- +-zr_detach_vfe: +- videocodec_detach(zr->vfe); +-zr_free_vfe: +- kfree(master_vfe); +-zr_detach_codec: +- videocodec_detach(zr->codec); +-zr_free_codec: +- kfree(master_codec); +-zr_unreg_i2c: +- zoran_unregister_i2c(zr); +-zr_free_irq: +- btwrite(0, ZR36057_SPGPPCR); +- free_irq(zr->pci_dev->irq, zr); +-zr_unmap: +- iounmap(zr->zr36057_mem); +-zr_free_mem: +- kfree(zr); ++ // Init errors ++ zr_detach_vfe: ++ videocodec_detach(zr->vfe); ++ zr_free_vfe: ++ kfree(master_vfe); ++ zr_detach_codec: ++ videocodec_detach(zr->codec); ++ zr_free_codec: ++ kfree(master_codec); ++ zr_unreg_i2c: ++ zoran_unregister_i2c(zr); ++ zr_free_irq: ++ btwrite(0, ZR36057_SPGPPCR); ++ free_irq(zr->pci_dev->irq, zr); ++ zr_unmap: ++ iounmap(zr->zr36057_mem); ++ zr_free_mem: ++ kfree(zr); ++ continue; ++ } ++ if (dev) /* Clean up ref count on early exit */ ++ pci_dev_put(dev); + +- return -ENODEV; ++ if (zoran_num == 0) { ++ dprintk(1, KERN_INFO "No known MJPEG cards found.\n"); ++ } ++ return zoran_num; + } + +-static struct pci_driver zoran_driver = { +- .name = "zr36067", +- .id_table = zr36067_pci_tbl, +- .probe = zoran_probe, +- .remove = zoran_remove, +-}; +- +-static int __init zoran_init(void) ++static int __init ++init_dc10_cards (void) + { +- int res; ++ int i; + ++ memset(zoran, 0, sizeof(zoran)); + printk(KERN_INFO "Zoran MJPEG board driver version %d.%d.%d\n", + MAJOR_VERSION, MINOR_VERSION, RELEASE_VERSION); + ++ /* Look for cards */ ++ if (find_zr36057() < 0) { ++ return -EIO; ++ } ++ if (zoran_num == 0) ++ return -ENODEV; ++ dprintk(1, KERN_INFO "%s: %d card(s) found\n", ZORAN_NAME, ++ zoran_num); + /* check the parameters we have been given, adjust if necessary */ + if (v4l_nbufs < 2) + v4l_nbufs = 2; +@@ -1624,22 +1629,37 @@ + ZORAN_NAME); + } + +- res = pci_register_driver(&zoran_driver); +- if (res) { +- dprintk(1, +- KERN_ERR +- "%s: Unable to register ZR36057 driver\n", +- ZORAN_NAME); +- return res; ++ /* take care of Natoma chipset and a revision 1 zr36057 */ ++ for (i = 0; i < zoran_num; i++) { ++ struct zoran *zr = zoran[i]; ++ ++ if ((pci_pci_problems & PCIPCI_NATOMA) && zr->revision <= 1) { ++ zr->jpg_buffers.need_contiguous = 1; ++ dprintk(1, ++ KERN_INFO ++ "%s: ZR36057/Natoma bug, max. buffer size is 128K\n", ++ ZR_DEVNAME(zr)); ++ } ++ ++ if (zr36057_init(zr) < 0) { ++ for (i = 0; i < zoran_num; i++) ++ zoran_release(zoran[i]); ++ return -EIO; ++ } ++ zoran_proc_init(zr); + } + + return 0; + } + +-static void __exit zoran_exit(void) ++static void __exit ++unload_dc10_cards (void) + { +- pci_unregister_driver(&zoran_driver); ++ int i; ++ ++ for (i = 0; i < zoran_num; i++) ++ zoran_release(zoran[i]); + } + +-module_init(zoran_init); +-module_exit(zoran_exit); ++module_init(init_dc10_cards); ++module_exit(unload_dc10_cards); +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/drivers/media/video/zoran/zoran_card.h linux-2.6.29-rc3.owrt/drivers/media/video/zoran/zoran_card.h +--- linux-2.6.29.owrt/drivers/media/video/zoran/zoran_card.h 2009-05-10 22:04:38.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/drivers/media/video/zoran/zoran_card.h 2009-05-10 23:48:28.000000000 +0200 +@@ -40,6 +40,8 @@ + + /* Anybody who uses more than four? */ + #define BUZ_MAX 4 ++extern int zoran_num; ++extern struct zoran *zoran[BUZ_MAX]; + + extern struct video_device zoran_template; + +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/drivers/media/video/zoran/zoran_driver.c linux-2.6.29-rc3.owrt/drivers/media/video/zoran/zoran_driver.c +--- linux-2.6.29.owrt/drivers/media/video/zoran/zoran_driver.c 2009-05-10 22:04:38.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/drivers/media/video/zoran/zoran_driver.c 2009-05-10 23:48:28.000000000 +0200 +@@ -1196,54 +1196,83 @@ + * Open a zoran card. Right now the flags stuff is just playing + */ + +-static int zoran_open(struct file *file) ++static int ++zoran_open(struct file *file) + { +- struct zoran *zr = video_drvdata(file); ++ unsigned int minor = video_devdata(file)->minor; ++ struct zoran *zr = NULL; + struct zoran_fh *fh; +- int res, first_open = 0; +- +- dprintk(2, KERN_INFO "%s: zoran_open(%s, pid=[%d]), users(-)=%d\n", +- ZR_DEVNAME(zr), current->comm, task_pid_nr(current), zr->user + 1); ++ int i, res, first_open = 0, have_module_locks = 0; + + lock_kernel(); ++ /* find the device */ ++ for (i = 0; i < zoran_num; i++) { ++ if (zoran[i]->video_dev->minor == minor) { ++ zr = zoran[i]; ++ break; ++ } ++ } ++ ++ if (!zr) { ++ dprintk(1, KERN_ERR "%s: device not found!\n", ZORAN_NAME); ++ res = -ENODEV; ++ goto open_unlock_and_return; ++ } + + /* see fs/device.c - the kernel already locks during open(), + * so locking ourselves only causes deadlocks */ + /*mutex_lock(&zr->resource_lock);*/ + +- if (zr->user >= 2048) { +- dprintk(1, KERN_ERR "%s: too many users (%d) on device\n", +- ZR_DEVNAME(zr), zr->user); +- res = -EBUSY; +- goto fail_unlock; +- } +- + if (!zr->decoder) { + dprintk(1, + KERN_ERR "%s: no TV decoder loaded for device!\n", + ZR_DEVNAME(zr)); + res = -EIO; +- goto fail_unlock; ++ goto open_unlock_and_return; + } + ++ /* try to grab a module lock */ ++ if (!try_module_get(THIS_MODULE)) { ++ dprintk(1, ++ KERN_ERR ++ "%s: failed to acquire my own lock! PANIC!\n", ++ ZR_DEVNAME(zr)); ++ res = -ENODEV; ++ goto open_unlock_and_return; ++ } + if (!try_module_get(zr->decoder->driver->driver.owner)) { + dprintk(1, + KERN_ERR +- "%s: failed to grab ownership of video decoder\n", ++ "%s: failed to grab ownership of i2c decoder\n", + ZR_DEVNAME(zr)); + res = -EIO; +- goto fail_unlock; ++ module_put(THIS_MODULE); ++ goto open_unlock_and_return; + } + if (zr->encoder && + !try_module_get(zr->encoder->driver->driver.owner)) { + dprintk(1, + KERN_ERR +- "%s: failed to grab ownership of video encoder\n", ++ "%s: failed to grab ownership of i2c encoder\n", + ZR_DEVNAME(zr)); + res = -EIO; +- goto fail_decoder; ++ module_put(zr->decoder->driver->driver.owner); ++ module_put(THIS_MODULE); ++ goto open_unlock_and_return; ++ } ++ ++ have_module_locks = 1; ++ ++ if (zr->user >= 2048) { ++ dprintk(1, KERN_ERR "%s: too many users (%d) on device\n", ++ ZR_DEVNAME(zr), zr->user); ++ res = -EBUSY; ++ goto open_unlock_and_return; + } + ++ dprintk(1, KERN_INFO "%s: zoran_open(%s, pid=[%d]), users(-)=%d\n", ++ ZR_DEVNAME(zr), current->comm, task_pid_nr(current), zr->user); ++ + /* now, create the open()-specific file_ops struct */ + fh = kzalloc(sizeof(struct zoran_fh), GFP_KERNEL); + if (!fh) { +@@ -1252,7 +1281,7 @@ + "%s: zoran_open() - allocation of zoran_fh failed\n", + ZR_DEVNAME(zr)); + res = -ENOMEM; +- goto fail_encoder; ++ goto open_unlock_and_return; + } + /* used to be BUZ_MAX_WIDTH/HEIGHT, but that gives overflows + * on norm-change! */ +@@ -1263,8 +1292,9 @@ + KERN_ERR + "%s: zoran_open() - allocation of overlay_mask failed\n", + ZR_DEVNAME(zr)); ++ kfree(fh); + res = -ENOMEM; +- goto fail_fh; ++ goto open_unlock_and_return; + } + + if (zr->user++ == 0) +@@ -1289,18 +1319,21 @@ + + return 0; + +-fail_fh: +- kfree(fh); +-fail_encoder: +- if (zr->encoder) +- module_put(zr->encoder->driver->driver.owner); +-fail_decoder: +- module_put(zr->decoder->driver->driver.owner); +-fail_unlock: +- unlock_kernel(); ++open_unlock_and_return: ++ /* if we grabbed locks, release them accordingly */ ++ if (have_module_locks) { ++ module_put(zr->decoder->driver->driver.owner); ++ if (zr->encoder) { ++ module_put(zr->encoder->driver->driver.owner); ++ } ++ module_put(THIS_MODULE); ++ } + +- dprintk(2, KERN_INFO "%s: open failed (%d), users(-)=%d\n", +- ZR_DEVNAME(zr), res, zr->user); ++ /* if there's no device found, we didn't obtain the lock either */ ++ if (zr) { ++ /*mutex_unlock(&zr->resource_lock);*/ ++ } ++ unlock_kernel(); + + return res; + } +@@ -1311,8 +1344,8 @@ + struct zoran_fh *fh = file->private_data; + struct zoran *zr = fh->zr; + +- dprintk(2, KERN_INFO "%s: zoran_close(%s, pid=[%d]), users(+)=%d\n", +- ZR_DEVNAME(zr), current->comm, task_pid_nr(current), zr->user - 1); ++ dprintk(1, KERN_INFO "%s: zoran_close(%s, pid=[%d]), users(+)=%d\n", ++ ZR_DEVNAME(zr), current->comm, task_pid_nr(current), zr->user); + + /* kernel locks (fs/device.c), so don't do that ourselves + * (prevents deadlocks) */ +@@ -1358,8 +1391,10 @@ + + /* release locks on the i2c modules */ + module_put(zr->decoder->driver->driver.owner); +- if (zr->encoder) +- module_put(zr->encoder->driver->driver.owner); ++ if (zr->encoder) { ++ module_put(zr->encoder->driver->driver.owner); ++ } ++ module_put(THIS_MODULE); + + /*mutex_unlock(&zr->resource_lock);*/ + +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/drivers/media/video/zoran/zoran.h linux-2.6.29-rc3.owrt/drivers/media/video/zoran/zoran.h +--- linux-2.6.29.owrt/drivers/media/video/zoran/zoran.h 2009-05-10 22:04:38.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/drivers/media/video/zoran/zoran.h 2009-05-10 23:48:28.000000000 +0200 +@@ -349,6 +349,7 @@ + u16 i2c_decoder, i2c_encoder; /* I2C types */ + u16 video_vfe, video_codec; /* videocodec types */ + u16 audio_chip; /* audio type */ ++ u16 vendor_id, device_id; /* subsystem vendor/device ID */ + + int inputs; /* number of video inputs */ + struct input { +@@ -400,6 +401,7 @@ + char name[32]; /* name of this device */ + struct pci_dev *pci_dev; /* PCI device */ + unsigned char revision; /* revision of zr36057 */ ++ unsigned int zr36057_adr; /* bus address of IO mem returned by PCI BIOS */ + unsigned char __iomem *zr36057_mem;/* pointer to mapped IO memory */ + + spinlock_t spinlock; /* Spinlock */ +@@ -488,10 +490,16 @@ + wait_queue_head_t test_q; + }; + +-/* There was something called _ALPHA_BUZ that used the PCI address instead of +- * the kernel iomapped address for btread/btwrite. */ ++/*The following should be done in more portable way. It depends on define ++ of _ALPHA_BUZ in the Makefile.*/ ++ ++#ifdef _ALPHA_BUZ ++#define btwrite(dat,adr) writel((dat), zr->zr36057_adr+(adr)) ++#define btread(adr) readl(zr->zr36057_adr+(adr)) ++#else + #define btwrite(dat,adr) writel((dat), zr->zr36057_mem+(adr)) + #define btread(adr) readl(zr->zr36057_mem+(adr)) ++#endif + + #define btand(dat,adr) btwrite((dat) & btread(adr), adr) + #define btor(dat,adr) btwrite((dat) | btread(adr), adr) +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/drivers/message/fusion/mptbase.c linux-2.6.29-rc3.owrt/drivers/message/fusion/mptbase.c +--- linux-2.6.29.owrt/drivers/message/fusion/mptbase.c 2009-05-10 22:04:39.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/drivers/message/fusion/mptbase.c 2009-05-10 23:48:28.000000000 +0200 +@@ -91,9 +91,9 @@ + controllers (default=0)"); + + static int mpt_msi_enable_sas; +-module_param(mpt_msi_enable_sas, int, 0); ++module_param(mpt_msi_enable_sas, int, 1); + MODULE_PARM_DESC(mpt_msi_enable_sas, " Enable MSI Support for SAS \ +- controllers (default=0)"); ++ controllers (default=1)"); + + + static int mpt_channel_mapping; +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/drivers/mfd/htc-egpio.c linux-2.6.29-rc3.owrt/drivers/mfd/htc-egpio.c +--- linux-2.6.29.owrt/drivers/mfd/htc-egpio.c 2009-05-10 22:04:38.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/drivers/mfd/htc-egpio.c 2009-05-10 23:48:28.000000000 +0200 +@@ -286,7 +286,7 @@ + res = platform_get_resource(pdev, IORESOURCE_MEM, 0); + if (!res) + goto fail; +- ei->base_addr = ioremap_nocache(res->start, resource_size(res)); ++ ei->base_addr = ioremap_nocache(res->start, res->end - res->start); + if (!ei->base_addr) + goto fail; + pr_debug("EGPIO phys=%08x virt=%p\n", (u32)res->start, ei->base_addr); +@@ -307,7 +307,7 @@ + + ei->nchips = pdata->num_chips; + ei->chip = kzalloc(sizeof(struct egpio_chip) * ei->nchips, GFP_KERNEL); +- if (!ei->chip) { ++ if (!ei) { + ret = -ENOMEM; + goto fail; + } +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/drivers/mfd/pcf50633-core.c linux-2.6.29-rc3.owrt/drivers/mfd/pcf50633-core.c +--- linux-2.6.29.owrt/drivers/mfd/pcf50633-core.c 2009-05-10 22:04:38.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/drivers/mfd/pcf50633-core.c 2009-05-10 23:48:28.000000000 +0200 +@@ -626,6 +626,7 @@ + } + + if (client->irq) { ++ set_irq_handler(client->irq, handle_level_irq); + ret = request_irq(client->irq, pcf50633_irq, + IRQF_TRIGGER_LOW, "pcf50633", pcf); + +@@ -678,7 +679,6 @@ + + static struct i2c_device_id pcf50633_id_table[] = { + {"pcf50633", 0x73}, +- {/* end of list */} + }; + + static struct i2c_driver pcf50633_driver = { +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/drivers/mfd/sm501.c linux-2.6.29-rc3.owrt/drivers/mfd/sm501.c +--- linux-2.6.29.owrt/drivers/mfd/sm501.c 2009-05-10 22:04:38.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/drivers/mfd/sm501.c 2009-05-10 23:48:28.000000000 +0200 +@@ -1050,7 +1050,7 @@ + return gpiochip_add(gchip); + } + +-static int __devinit sm501_register_gpio(struct sm501_devdata *sm) ++static int sm501_register_gpio(struct sm501_devdata *sm) + { + struct sm501_gpio *gpio = &sm->gpio; + resource_size_t iobase = sm->io_res->start + SM501_GPIO; +@@ -1321,7 +1321,7 @@ + * Common init code for an SM501 + */ + +-static int __devinit sm501_init_dev(struct sm501_devdata *sm) ++static int sm501_init_dev(struct sm501_devdata *sm) + { + struct sm501_initdata *idata; + struct sm501_platdata *pdata; +@@ -1397,7 +1397,7 @@ + return 0; + } + +-static int __devinit sm501_plat_probe(struct platform_device *dev) ++static int sm501_plat_probe(struct platform_device *dev) + { + struct sm501_devdata *sm; + int ret; +@@ -1586,8 +1586,8 @@ + .gpio_base = -1, + }; + +-static int __devinit sm501_pci_probe(struct pci_dev *dev, +- const struct pci_device_id *id) ++static int sm501_pci_probe(struct pci_dev *dev, ++ const struct pci_device_id *id) + { + struct sm501_devdata *sm; + int err; +@@ -1693,7 +1693,7 @@ + sm501_gpio_remove(sm); + } + +-static void __devexit sm501_pci_remove(struct pci_dev *dev) ++static void sm501_pci_remove(struct pci_dev *dev) + { + struct sm501_devdata *sm = pci_get_drvdata(dev); + +@@ -1727,16 +1727,16 @@ + + MODULE_DEVICE_TABLE(pci, sm501_pci_tbl); + +-static struct pci_driver sm501_pci_driver = { ++static struct pci_driver sm501_pci_drv = { + .name = "sm501", + .id_table = sm501_pci_tbl, + .probe = sm501_pci_probe, +- .remove = __devexit_p(sm501_pci_remove), ++ .remove = sm501_pci_remove, + }; + + MODULE_ALIAS("platform:sm501"); + +-static struct platform_driver sm501_plat_driver = { ++static struct platform_driver sm501_plat_drv = { + .driver = { + .name = "sm501", + .owner = THIS_MODULE, +@@ -1749,14 +1749,14 @@ + + static int __init sm501_base_init(void) + { +- platform_driver_register(&sm501_plat_driver); +- return pci_register_driver(&sm501_pci_driver); ++ platform_driver_register(&sm501_plat_drv); ++ return pci_register_driver(&sm501_pci_drv); + } + + static void __exit sm501_base_exit(void) + { +- platform_driver_unregister(&sm501_plat_driver); +- pci_unregister_driver(&sm501_pci_driver); ++ platform_driver_unregister(&sm501_plat_drv); ++ pci_unregister_driver(&sm501_pci_drv); + } + + module_init(sm501_base_init); +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/drivers/mfd/twl4030-core.c linux-2.6.29-rc3.owrt/drivers/mfd/twl4030-core.c +--- linux-2.6.29.owrt/drivers/mfd/twl4030-core.c 2009-05-10 22:04:38.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/drivers/mfd/twl4030-core.c 2009-05-10 23:48:28.000000000 +0200 +@@ -38,7 +38,7 @@ + #include <linux/i2c.h> + #include <linux/i2c/twl4030.h> + +-#if defined(CONFIG_ARCH_OMAP2) || defined(CONFIG_ARCH_OMAP3) ++#ifdef CONFIG_ARM + #include <mach/cpu.h> + #endif + +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/drivers/mfd/wm8350-core.c linux-2.6.29-rc3.owrt/drivers/mfd/wm8350-core.c +--- linux-2.6.29.owrt/drivers/mfd/wm8350-core.c 2009-05-10 22:04:38.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/drivers/mfd/wm8350-core.c 2009-05-10 23:48:28.000000000 +0200 +@@ -1111,7 +1111,7 @@ + do { + schedule_timeout_interruptible(1); + reg = wm8350_reg_read(wm8350, WM8350_DIGITISER_CONTROL_1); +- } while (--tries && (reg & WM8350_AUXADC_POLL)); ++ } while (tries-- && (reg & WM8350_AUXADC_POLL)); + + if (!tries) + dev_err(wm8350->dev, "adc chn %d read timeout\n", channel); +@@ -1297,29 +1297,14 @@ + int wm8350_device_init(struct wm8350 *wm8350, int irq, + struct wm8350_platform_data *pdata) + { +- int ret; ++ int ret = -EINVAL; + u16 id1, id2, mask_rev; + u16 cust_id, mode, chip_rev; + + /* get WM8350 revision and config mode */ +- ret = wm8350->read_dev(wm8350, WM8350_RESET_ID, sizeof(id1), &id1); +- if (ret != 0) { +- dev_err(wm8350->dev, "Failed to read ID: %d\n", ret); +- goto err; +- } +- +- ret = wm8350->read_dev(wm8350, WM8350_ID, sizeof(id2), &id2); +- if (ret != 0) { +- dev_err(wm8350->dev, "Failed to read ID: %d\n", ret); +- goto err; +- } +- +- ret = wm8350->read_dev(wm8350, WM8350_REVISION, sizeof(mask_rev), +- &mask_rev); +- if (ret != 0) { +- dev_err(wm8350->dev, "Failed to read revision: %d\n", ret); +- goto err; +- } ++ wm8350->read_dev(wm8350, WM8350_RESET_ID, sizeof(id1), &id1); ++ wm8350->read_dev(wm8350, WM8350_ID, sizeof(id2), &id2); ++ wm8350->read_dev(wm8350, WM8350_REVISION, sizeof(mask_rev), &mask_rev); + + id1 = be16_to_cpu(id1); + id2 = be16_to_cpu(id2); +@@ -1383,11 +1368,6 @@ + wm8350->power.rev_g_coeff = 1; + break; + +- case 1: +- dev_info(wm8350->dev, "WM8351 Rev B\n"); +- wm8350->power.rev_g_coeff = 1; +- break; +- + default: + dev_err(wm8350->dev, "Unknown WM8351 CHIP_REV\n"); + ret = -ENODEV; +@@ -1424,12 +1404,14 @@ + return ret; + } + +- wm8350_reg_write(wm8350, WM8350_SYSTEM_INTERRUPTS_MASK, 0xFFFF); +- wm8350_reg_write(wm8350, WM8350_INT_STATUS_1_MASK, 0xFFFF); +- wm8350_reg_write(wm8350, WM8350_INT_STATUS_2_MASK, 0xFFFF); +- wm8350_reg_write(wm8350, WM8350_UNDER_VOLTAGE_INT_STATUS_MASK, 0xFFFF); +- wm8350_reg_write(wm8350, WM8350_GPIO_INT_STATUS_MASK, 0xFFFF); +- wm8350_reg_write(wm8350, WM8350_COMPARATOR_INT_STATUS_MASK, 0xFFFF); ++ if (pdata && pdata->init) { ++ ret = pdata->init(wm8350); ++ if (ret != 0) { ++ dev_err(wm8350->dev, "Platform init() failed: %d\n", ++ ret); ++ goto err; ++ } ++ } + + mutex_init(&wm8350->auxadc_mutex); + mutex_init(&wm8350->irq_mutex); +@@ -1448,15 +1430,6 @@ + } + wm8350->chip_irq = irq; + +- if (pdata && pdata->init) { +- ret = pdata->init(wm8350); +- if (ret != 0) { +- dev_err(wm8350->dev, "Platform init() failed: %d\n", +- ret); +- goto err; +- } +- } +- + wm8350_reg_write(wm8350, WM8350_SYSTEM_INTERRUPTS_MASK, 0x0); + + wm8350_client_dev_register(wm8350, "wm8350-codec", +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/drivers/mfd/wm8350-regmap.c linux-2.6.29-rc3.owrt/drivers/mfd/wm8350-regmap.c +--- linux-2.6.29.owrt/drivers/mfd/wm8350-regmap.c 2009-05-10 22:04:38.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/drivers/mfd/wm8350-regmap.c 2009-05-10 23:48:28.000000000 +0200 +@@ -3188,7 +3188,7 @@ + { 0x7CFF, 0x0C00, 0x7FFF }, /* R1 - ID */ + { 0x0000, 0x0000, 0x0000 }, /* R2 */ + { 0xBE3B, 0xBE3B, 0x8000 }, /* R3 - System Control 1 */ +- { 0xFEF7, 0xFEF7, 0xF800 }, /* R4 - System Control 2 */ ++ { 0xFCF7, 0xFCF7, 0xF800 }, /* R4 - System Control 2 */ + { 0x80FF, 0x80FF, 0x8000 }, /* R5 - System Hibernate */ + { 0xFB0E, 0xFB0E, 0x0000 }, /* R6 - Interface Control */ + { 0x0000, 0x0000, 0x0000 }, /* R7 */ +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/drivers/misc/atmel-ssc.c linux-2.6.29-rc3.owrt/drivers/misc/atmel-ssc.c +--- linux-2.6.29.owrt/drivers/misc/atmel-ssc.c 2009-05-10 22:04:38.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/drivers/misc/atmel-ssc.c 2009-05-10 23:48:28.000000000 +0200 +@@ -35,7 +35,7 @@ + + if (!ssc_valid) { + spin_unlock(&user_lock); +- pr_err("ssc: ssc%d platform device is missing\n", ssc_num); ++ dev_dbg(&ssc->pdev->dev, "could not find requested device\n"); + return ERR_PTR(-ENODEV); + } + +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/drivers/misc/hpilo.c linux-2.6.29-rc3.owrt/drivers/misc/hpilo.c +--- linux-2.6.29.owrt/drivers/misc/hpilo.c 2009-05-10 22:04:38.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/drivers/misc/hpilo.c 2009-05-10 23:48:28.000000000 +0200 +@@ -207,7 +207,7 @@ + &device_ccb->recv_ctrl); + + /* give iLO some time to process stop request */ +- for (retries = MAX_WAIT; retries > 0; retries--) { ++ for (retries = 1000; retries > 0; retries--) { + doorbell_set(driver_ccb); + udelay(1); + if (!(ioread32(&device_ccb->send_ctrl) & (1 << CTRL_BITPOS_A)) +@@ -309,7 +309,7 @@ + doorbell_clr(driver_ccb); + + /* make sure iLO is really handling requests */ +- for (i = MAX_WAIT; i > 0; i--) { ++ for (i = 1000; i > 0; i--) { + if (ilo_pkt_dequeue(hw, driver_ccb, SENDQ, &pkt_id, NULL, NULL)) + break; + udelay(1); +@@ -326,7 +326,7 @@ + + return 0; + free: +- ilo_ccb_close(pdev, data); ++ pci_free_consistent(pdev, data->dma_size, data->dma_va, data->dma_pa); + out: + return error; + } +@@ -710,7 +710,6 @@ + + static struct pci_device_id ilo_devices[] = { + { PCI_DEVICE(PCI_VENDOR_ID_COMPAQ, 0xB204) }, +- { PCI_DEVICE(PCI_VENDOR_ID_HP, 0x3307) }, + { } + }; + MODULE_DEVICE_TABLE(pci, ilo_devices); +@@ -759,7 +758,7 @@ + class_destroy(ilo_class); + } + +-MODULE_VERSION("1.0"); ++MODULE_VERSION("0.05"); + MODULE_ALIAS(ILO_NAME); + MODULE_DESCRIPTION(ILO_NAME); + MODULE_AUTHOR("David Altobelli <david.altobelli@hp.com>"); +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/drivers/misc/hpilo.h linux-2.6.29-rc3.owrt/drivers/misc/hpilo.h +--- linux-2.6.29.owrt/drivers/misc/hpilo.h 2009-05-10 22:04:38.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/drivers/misc/hpilo.h 2009-05-10 23:48:28.000000000 +0200 +@@ -19,8 +19,6 @@ + #define MAX_ILO_DEV 1 + /* max number of files */ + #define MAX_OPEN (MAX_CCB * MAX_ILO_DEV) +-/* spin counter for open/close delay */ +-#define MAX_WAIT 10000 + + /* + * Per device, used to track global memory allocations. +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/drivers/misc/Kconfig linux-2.6.29-rc3.owrt/drivers/misc/Kconfig +--- linux-2.6.29.owrt/drivers/misc/Kconfig 2009-05-10 22:04:38.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/drivers/misc/Kconfig 2009-05-10 23:48:28.000000000 +0200 +@@ -217,7 +217,6 @@ + depends on EXPERIMENTAL + depends on BACKLIGHT_CLASS_DEVICE + depends on RFKILL +- depends on POWER_SUPPLY + default n + ---help--- + This driver adds support for rfkill and backlight control to Dell +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/drivers/misc/sgi-xp/xpc_channel.c linux-2.6.29-rc3.owrt/drivers/misc/sgi-xp/xpc_channel.c +--- linux-2.6.29.owrt/drivers/misc/sgi-xp/xpc_channel.c 2009-05-10 22:04:38.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/drivers/misc/sgi-xp/xpc_channel.c 2009-05-10 23:48:28.000000000 +0200 +@@ -49,6 +49,9 @@ + + if (ch->flags & (XPC_C_CONNECTED | XPC_C_DISCONNECTING)) + return; ++ ++ DBUG_ON(ch->local_msgqueue == NULL); ++ DBUG_ON(ch->remote_msgqueue == NULL); + } + + if (!(ch->flags & XPC_C_OPENREPLY)) { +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/drivers/misc/sgi-xp/xpc.h linux-2.6.29-rc3.owrt/drivers/misc/sgi-xp/xpc.h +--- linux-2.6.29.owrt/drivers/misc/sgi-xp/xpc.h 2009-05-10 22:04:38.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/drivers/misc/sgi-xp/xpc.h 2009-05-10 23:48:28.000000000 +0200 +@@ -3,7 +3,7 @@ + * License. See the file "COPYING" in the main directory of this archive + * for more details. + * +- * Copyright (c) 2004-2009 Silicon Graphics, Inc. All Rights Reserved. ++ * Copyright (c) 2004-2008 Silicon Graphics, Inc. All Rights Reserved. + */ + + /* +@@ -514,8 +514,7 @@ + /* partition's notify mq */ + + struct xpc_send_msg_slot_uv *send_msg_slots; +- void *recv_msg_slots; /* each slot will hold a xpc_notify_mq_msg_uv */ +- /* structure plus the user's payload */ ++ struct xpc_notify_mq_msg_uv *recv_msg_slots; + + struct xpc_fifo_head_uv msg_slot_free_list; + struct xpc_fifo_head_uv recv_msg_list; /* deliverable payloads */ +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/drivers/misc/sgi-xp/xpc_sn2.c linux-2.6.29-rc3.owrt/drivers/misc/sgi-xp/xpc_sn2.c +--- linux-2.6.29.owrt/drivers/misc/sgi-xp/xpc_sn2.c 2009-05-10 22:04:38.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/drivers/misc/sgi-xp/xpc_sn2.c 2009-05-10 23:48:28.000000000 +0200 +@@ -1106,6 +1106,8 @@ + int n_IRQs_expected; + int n_IRQs_detected; + ++ DBUG_ON(xpc_activate_IRQ_rcvd == 0); ++ + spin_lock_irqsave(&xpc_activate_IRQ_rcvd_lock, irq_flags); + n_IRQs_expected = xpc_activate_IRQ_rcvd; + xpc_activate_IRQ_rcvd = 0; +@@ -1724,7 +1726,6 @@ + msg = (struct xpc_msg_sn2 *)((u64)ch_sn2->local_msgqueue + + (get % ch->local_nentries) * + ch->entry_size); +- DBUG_ON(!(msg->flags & XPC_M_SN2_READY)); + msg->flags = 0; + } while (++get < ch_sn2->remote_GP.get); + } +@@ -1739,18 +1740,11 @@ + struct xpc_msg_sn2 *msg; + s64 put; + +- /* flags are zeroed when the buffer is allocated */ +- if (ch_sn2->remote_GP.put < ch->remote_nentries) +- return; +- +- put = max(ch_sn2->w_remote_GP.put, ch->remote_nentries); ++ put = ch_sn2->w_remote_GP.put; + do { + msg = (struct xpc_msg_sn2 *)((u64)ch_sn2->remote_msgqueue + + (put % ch->remote_nentries) * + ch->entry_size); +- DBUG_ON(!(msg->flags & XPC_M_SN2_READY)); +- DBUG_ON(!(msg->flags & XPC_M_SN2_DONE)); +- DBUG_ON(msg->number != put - ch->remote_nentries); + msg->flags = 0; + } while (++put < ch_sn2->remote_GP.put); + } +@@ -1842,7 +1836,6 @@ + */ + xpc_clear_remote_msgqueue_flags_sn2(ch); + +- smp_wmb(); /* ensure flags have been cleared before bte_copy */ + ch_sn2->w_remote_GP.put = ch_sn2->remote_GP.put; + + dev_dbg(xpc_chan, "w_remote_GP.put changed to %ld, partid=%d, " +@@ -1941,7 +1934,7 @@ + break; + + get = ch_sn2->w_local_GP.get; +- smp_rmb(); /* guarantee that .get loads before .put */ ++ rmb(); /* guarantee that .get loads before .put */ + if (get == ch_sn2->w_remote_GP.put) + break; + +@@ -1963,13 +1956,11 @@ + + msg = xpc_pull_remote_msg_sn2(ch, get); + +- if (msg != NULL) { +- DBUG_ON(msg->number != get); +- DBUG_ON(msg->flags & XPC_M_SN2_DONE); +- DBUG_ON(!(msg->flags & XPC_M_SN2_READY)); ++ DBUG_ON(msg != NULL && msg->number != get); ++ DBUG_ON(msg != NULL && (msg->flags & XPC_M_SN2_DONE)); ++ DBUG_ON(msg != NULL && !(msg->flags & XPC_M_SN2_READY)); + +- payload = &msg->payload; +- } ++ payload = &msg->payload; + break; + } + +@@ -2062,7 +2053,7 @@ + while (1) { + + put = ch_sn2->w_local_GP.put; +- smp_rmb(); /* guarantee that .put loads before .get */ ++ rmb(); /* guarantee that .put loads before .get */ + if (put - ch_sn2->w_remote_GP.get < ch->local_nentries) { + + /* There are available message entries. We need to try +@@ -2195,7 +2186,7 @@ + * The preceding store of msg->flags must occur before the following + * load of local_GP->put. + */ +- smp_mb(); ++ mb(); + + /* see if the message is next in line to be sent, if so send it */ + +@@ -2286,9 +2277,8 @@ + dev_dbg(xpc_chan, "msg=0x%p, msg_number=%ld, partid=%d, channel=%d\n", + (void *)msg, msg_number, ch->partid, ch->number); + +- DBUG_ON((((u64)msg - (u64)ch->sn.sn2.remote_msgqueue) / ch->entry_size) != ++ DBUG_ON((((u64)msg - (u64)ch->remote_msgqueue) / ch->entry_size) != + msg_number % ch->remote_nentries); +- DBUG_ON(!(msg->flags & XPC_M_SN2_READY)); + DBUG_ON(msg->flags & XPC_M_SN2_DONE); + + msg->flags |= XPC_M_SN2_DONE; +@@ -2297,7 +2287,7 @@ + * The preceding store of msg->flags must occur before the following + * load of local_GP->get. + */ +- smp_mb(); ++ mb(); + + /* + * See if this message is next in line to be acknowledged as having +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/drivers/misc/sgi-xp/xpc_uv.c linux-2.6.29-rc3.owrt/drivers/misc/sgi-xp/xpc_uv.c +--- linux-2.6.29.owrt/drivers/misc/sgi-xp/xpc_uv.c 2009-05-10 22:04:38.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/drivers/misc/sgi-xp/xpc_uv.c 2009-05-10 23:48:28.000000000 +0200 +@@ -3,7 +3,7 @@ + * License. See the file "COPYING" in the main directory of this archive + * for more details. + * +- * Copyright (c) 2008-2009 Silicon Graphics, Inc. All Rights Reserved. ++ * Copyright (c) 2008 Silicon Graphics, Inc. All Rights Reserved. + */ + + /* +@@ -1010,8 +1010,8 @@ + continue; + + for (entry = 0; entry < nentries; entry++) { +- msg_slot = ch_uv->recv_msg_slots + +- entry * ch->entry_size; ++ msg_slot = ch_uv->recv_msg_slots + entry * ++ ch->entry_size; + + msg_slot->hdr.msg_slot_number = entry; + } +@@ -1308,8 +1308,9 @@ + /* we're dealing with a normal message sent via the notify_mq */ + ch_uv = &ch->sn.uv; + +- msg_slot = ch_uv->recv_msg_slots + +- (msg->hdr.msg_slot_number % ch->remote_nentries) * ch->entry_size; ++ msg_slot = (struct xpc_notify_mq_msg_uv *)((u64)ch_uv->recv_msg_slots + ++ (msg->hdr.msg_slot_number % ch->remote_nentries) * ++ ch->entry_size); + + BUG_ON(msg->hdr.msg_slot_number != msg_slot->hdr.msg_slot_number); + BUG_ON(msg_slot->hdr.size != 0); +@@ -1422,7 +1423,7 @@ + atomic_inc(&ch->n_to_notify); + + msg_slot->key = key; +- smp_wmb(); /* a non-NULL func must hit memory after the key */ ++ wmb(); /* a non-NULL func must hit memory after the key */ + msg_slot->func = func; + + if (ch->flags & XPC_C_DISCONNECTING) { +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/drivers/misc/sgi-xp/xpnet.c linux-2.6.29-rc3.owrt/drivers/misc/sgi-xp/xpnet.c +--- linux-2.6.29.owrt/drivers/misc/sgi-xp/xpnet.c 2009-05-10 22:04:38.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/drivers/misc/sgi-xp/xpnet.c 2009-05-10 23:48:28.000000000 +0200 +@@ -3,7 +3,7 @@ + * License. See the file "COPYING" in the main directory of this archive + * for more details. + * +- * Copyright (C) 1999-2009 Silicon Graphics, Inc. All rights reserved. ++ * Copyright (C) 1999-2008 Silicon Graphics, Inc. All rights reserved. + */ + + /* +@@ -551,7 +551,6 @@ + + netif_carrier_off(xpnet_device); + +- xpnet_device->netdev_ops = &xpnet_netdev_ops; + xpnet_device->mtu = XPNET_DEF_MTU; + + /* +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/drivers/mmc/card/block.c linux-2.6.29-rc3.owrt/drivers/mmc/card/block.c +--- linux-2.6.29.owrt/drivers/mmc/card/block.c 2009-05-10 22:04:38.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/drivers/mmc/card/block.c 2009-05-10 23:48:28.000000000 +0200 +@@ -584,7 +584,7 @@ + if (err) + goto out; + +- string_get_size((u64)get_capacity(md->disk) << 9, STRING_UNITS_2, ++ string_get_size(get_capacity(md->disk) << 9, STRING_UNITS_2, + cap_str, sizeof(cap_str)); + printk(KERN_INFO "%s: %s %s %s %s\n", + md->disk->disk_name, mmc_card_id(card), mmc_card_name(card), +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/drivers/mmc/card/mmc_test.c linux-2.6.29-rc3.owrt/drivers/mmc/card/mmc_test.c +--- linux-2.6.29.owrt/drivers/mmc/card/mmc_test.c 2009-05-10 22:04:38.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/drivers/mmc/card/mmc_test.c 2009-05-10 23:48:28.000000000 +0200 +@@ -494,7 +494,7 @@ + + sg_init_one(&sg, test->buffer, 512); + +- ret = mmc_test_simple_transfer(test, &sg, 1, 0, 1, 512, 0); ++ ret = mmc_test_simple_transfer(test, &sg, 1, 0, 1, 512, 1); + if (ret) + return ret; + +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/drivers/mmc/core/mmc_ops.c linux-2.6.29-rc3.owrt/drivers/mmc/core/mmc_ops.c +--- linux-2.6.29.owrt/drivers/mmc/core/mmc_ops.c 2009-05-10 22:04:38.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/drivers/mmc/core/mmc_ops.c 2009-05-10 23:48:28.000000000 +0200 +@@ -248,15 +248,12 @@ + + sg_init_one(&sg, data_buf, len); + +- if (opcode == MMC_SEND_CSD || opcode == MMC_SEND_CID) { +- /* +- * The spec states that CSR and CID accesses have a timeout +- * of 64 clock cycles. +- */ +- data.timeout_ns = 0; +- data.timeout_clks = 64; +- } else +- mmc_set_data_timeout(&data, card); ++ /* ++ * The spec states that CSR and CID accesses have a timeout ++ * of 64 clock cycles. ++ */ ++ data.timeout_ns = 0; ++ data.timeout_clks = 64; + + mmc_wait_for_req(host, &mrq); + +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/drivers/mmc/host/atmel-mci.c linux-2.6.29-rc3.owrt/drivers/mmc/host/atmel-mci.c +--- linux-2.6.29.owrt/drivers/mmc/host/atmel-mci.c 2009-05-10 22:04:38.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/drivers/mmc/host/atmel-mci.c 2009-05-10 23:48:28.000000000 +0200 +@@ -1548,10 +1548,9 @@ + { + struct dw_dma_slave *dws = slave; + +- if (dws->dma_dev == chan->device->dev) { +- chan->private = dws; ++ if (dws->dma_dev == chan->device->dev) + return true; +- } else ++ else + return false; + } + #endif +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/drivers/mmc/host/Kconfig linux-2.6.29-rc3.owrt/drivers/mmc/host/Kconfig +--- linux-2.6.29.owrt/drivers/mmc/host/Kconfig 2009-05-10 22:04:38.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/drivers/mmc/host/Kconfig 2009-05-10 23:48:28.000000000 +0200 +@@ -145,16 +145,6 @@ + + If unsure, say N. + +-config MMC_MXC +- tristate "Freescale i.MX2/3 Multimedia Card Interface support" +- depends on ARCH_MXC +- help +- This selects the Freescale i.MX2/3 Multimedia card Interface. +- If you have a i.MX platform with a Multimedia Card slot, +- say Y or M here. +- +- If unsure, say N. +- + config MMC_TIFM_SD + tristate "TI Flash Media MMC/SD Interface support (EXPERIMENTAL)" + depends on EXPERIMENTAL && PCI +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/drivers/mmc/host/Makefile linux-2.6.29-rc3.owrt/drivers/mmc/host/Makefile +--- linux-2.6.29.owrt/drivers/mmc/host/Makefile 2009-05-10 22:04:38.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/drivers/mmc/host/Makefile 2009-05-10 23:48:28.000000000 +0200 +@@ -9,7 +9,6 @@ + obj-$(CONFIG_MMC_ARMMMCI) += mmci.o + obj-$(CONFIG_MMC_PXA) += pxamci.o + obj-$(CONFIG_MMC_IMX) += imxmmc.o +-obj-$(CONFIG_MMC_MXC) += mxcmmc.o + obj-$(CONFIG_MMC_SDHCI) += sdhci.o + obj-$(CONFIG_MMC_SDHCI_PCI) += sdhci-pci.o + obj-$(CONFIG_MMC_RICOH_MMC) += ricoh_mmc.o +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/drivers/mmc/host/mmci.c linux-2.6.29-rc3.owrt/drivers/mmc/host/mmci.c +--- linux-2.6.29.owrt/drivers/mmc/host/mmci.c 2009-05-10 22:04:38.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/drivers/mmc/host/mmci.c 2009-05-10 23:48:28.000000000 +0200 +@@ -430,8 +430,6 @@ + clk = 255; + host->cclk = host->mclk / (2 * (clk + 1)); + } +- if (host->hw_designer == 0x80) +- clk |= MCI_FCEN; /* Bug fix in ST IP block */ + clk |= MCI_CLK_ENABLE; + } + +@@ -442,27 +440,15 @@ + case MMC_POWER_OFF: + break; + case MMC_POWER_UP: +- /* The ST version does not have this, fall through to POWER_ON */ +- if (host->hw_designer != 0x80) { +- pwr |= MCI_PWR_UP; +- break; +- } ++ pwr |= MCI_PWR_UP; ++ break; + case MMC_POWER_ON: + pwr |= MCI_PWR_ON; + break; + } + +- if (ios->bus_mode == MMC_BUSMODE_OPENDRAIN) { +- if (host->hw_designer != 0x80) +- pwr |= MCI_ROD; +- else { +- /* +- * The ST Micro variant use the ROD bit for something +- * else and only has OD (Open Drain). +- */ +- pwr |= MCI_OD; +- } +- } ++ if (ios->bus_mode == MMC_BUSMODE_OPENDRAIN) ++ pwr |= MCI_ROD; + + writel(clk, host->base + MMCICLOCK); + +@@ -514,12 +500,6 @@ + } + + host = mmc_priv(mmc); +- /* Bits 12 thru 19 is the designer */ +- host->hw_designer = (dev->periphid >> 12) & 0xff; +- /* Bits 20 thru 23 is the revison */ +- host->hw_revision = (dev->periphid >> 20) & 0xf; +- DBG(host, "designer ID = 0x%02x\n", host->hw_designer); +- DBG(host, "revision = 0x%01x\n", host->hw_revision); + host->clk = clk_get(&dev->dev, NULL); + if (IS_ERR(host->clk)) { + ret = PTR_ERR(host->clk); +@@ -713,15 +693,6 @@ + .id = 0x00041181, + .mask = 0x000fffff, + }, +- /* ST Micro variants */ +- { +- .id = 0x00180180, +- .mask = 0x00ffffff, +- }, +- { +- .id = 0x00280180, +- .mask = 0x00ffffff, +- }, + { 0, 0 }, + }; + +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/drivers/mmc/host/mmci.h linux-2.6.29-rc3.owrt/drivers/mmc/host/mmci.h +--- linux-2.6.29.owrt/drivers/mmc/host/mmci.h 2009-05-10 22:04:38.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/drivers/mmc/host/mmci.h 2009-05-10 23:48:28.000000000 +0200 +@@ -11,23 +11,13 @@ + #define MCI_PWR_OFF 0x00 + #define MCI_PWR_UP 0x02 + #define MCI_PWR_ON 0x03 +-#define MCI_DATA2DIREN (1 << 2) +-#define MCI_CMDDIREN (1 << 3) +-#define MCI_DATA0DIREN (1 << 4) +-#define MCI_DATA31DIREN (1 << 5) + #define MCI_OD (1 << 6) + #define MCI_ROD (1 << 7) +-/* The ST Micro version does not have ROD */ +-#define MCI_FBCLKEN (1 << 7) +-#define MCI_DATA74DIREN (1 << 8) + + #define MMCICLOCK 0x004 + #define MCI_CLK_ENABLE (1 << 8) + #define MCI_CLK_PWRSAVE (1 << 9) + #define MCI_CLK_BYPASS (1 << 10) +-#define MCI_WIDE_BUS (1 << 11) +-/* HW flow control on the ST Micro version */ +-#define MCI_FCEN (1 << 13) + + #define MMCIARGUMENT 0x008 + #define MMCICOMMAND 0x00c +@@ -36,10 +26,6 @@ + #define MCI_CPSM_INTERRUPT (1 << 8) + #define MCI_CPSM_PENDING (1 << 9) + #define MCI_CPSM_ENABLE (1 << 10) +-#define MCI_SDIO_SUSP (1 << 11) +-#define MCI_ENCMD_COMPL (1 << 12) +-#define MCI_NIEN (1 << 13) +-#define MCI_CE_ATACMD (1 << 14) + + #define MMCIRESPCMD 0x010 + #define MMCIRESPONSE0 0x014 +@@ -53,11 +39,6 @@ + #define MCI_DPSM_DIRECTION (1 << 1) + #define MCI_DPSM_MODE (1 << 2) + #define MCI_DPSM_DMAENABLE (1 << 3) +-#define MCI_DPSM_BLOCKSIZE (1 << 4) +-#define MCI_DPSM_RWSTART (1 << 8) +-#define MCI_DPSM_RWSTOP (1 << 9) +-#define MCI_DPSM_RWMOD (1 << 10) +-#define MCI_DPSM_SDIOEN (1 << 11) + + #define MMCIDATACNT 0x030 + #define MMCISTATUS 0x034 +@@ -82,8 +63,6 @@ + #define MCI_RXFIFOEMPTY (1 << 19) + #define MCI_TXDATAAVLBL (1 << 20) + #define MCI_RXDATAAVLBL (1 << 21) +-#define MCI_SDIOIT (1 << 22) +-#define MCI_CEATAEND (1 << 23) + + #define MMCICLEAR 0x038 + #define MCI_CMDCRCFAILCLR (1 << 0) +@@ -96,8 +75,6 @@ + #define MCI_CMDSENTCLR (1 << 7) + #define MCI_DATAENDCLR (1 << 8) + #define MCI_DATABLOCKENDCLR (1 << 10) +-#define MCI_SDIOITC (1 << 22) +-#define MCI_CEATAENDC (1 << 23) + + #define MMCIMASK0 0x03c + #define MCI_CMDCRCFAILMASK (1 << 0) +@@ -121,8 +98,6 @@ + #define MCI_RXFIFOEMPTYMASK (1 << 19) + #define MCI_TXDATAAVLBLMASK (1 << 20) + #define MCI_RXDATAAVLBLMASK (1 << 21) +-#define MCI_SDIOITMASK (1 << 22) +-#define MCI_CEATAENDMASK (1 << 23) + + #define MMCIMASK1 0x040 + #define MMCIFIFOCNT 0x048 +@@ -161,9 +136,6 @@ + u32 pwr; + struct mmc_platform_data *plat; + +- u8 hw_designer; +- u8 hw_revision:4; +- + struct timer_list timer; + unsigned int oldstat; + +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/drivers/mmc/host/mxcmmc.c linux-2.6.29-rc3.owrt/drivers/mmc/host/mxcmmc.c +--- linux-2.6.29.owrt/drivers/mmc/host/mxcmmc.c 2009-05-10 22:04:38.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/drivers/mmc/host/mxcmmc.c 1970-01-01 01:00:00.000000000 +0100 +@@ -1,880 +0,0 @@ +-/* +- * linux/drivers/mmc/host/mxcmmc.c - Freescale i.MX MMCI driver +- * +- * This is a driver for the SDHC controller found in Freescale MX2/MX3 +- * SoCs. It is basically the same hardware as found on MX1 (imxmmc.c). +- * Unlike the hardware found on MX1, this hardware just works and does +- * not need all the quirks found in imxmmc.c, hence the seperate driver. +- * +- * Copyright (C) 2008 Sascha Hauer, Pengutronix <s.hauer@pengutronix.de> +- * Copyright (C) 2006 Pavel Pisa, PiKRON <ppisa@pikron.com> +- * +- * derived from pxamci.c by Russell King +- * +- * This program is free software; you can redistribute it and/or modify +- * it under the terms of the GNU General Public License version 2 as +- * published by the Free Software Foundation. +- * +- */ +- +-#include <linux/module.h> +-#include <linux/init.h> +-#include <linux/ioport.h> +-#include <linux/platform_device.h> +-#include <linux/interrupt.h> +-#include <linux/irq.h> +-#include <linux/blkdev.h> +-#include <linux/dma-mapping.h> +-#include <linux/mmc/host.h> +-#include <linux/mmc/card.h> +-#include <linux/delay.h> +-#include <linux/clk.h> +-#include <linux/io.h> +-#include <linux/gpio.h> +- +-#include <asm/dma.h> +-#include <asm/irq.h> +-#include <asm/sizes.h> +-#include <mach/mmc.h> +- +-#ifdef CONFIG_ARCH_MX2 +-#include <mach/dma-mx1-mx2.h> +-#define HAS_DMA +-#endif +- +-#define DRIVER_NAME "imx-mmc" +- +-#define MMC_REG_STR_STP_CLK 0x00 +-#define MMC_REG_STATUS 0x04 +-#define MMC_REG_CLK_RATE 0x08 +-#define MMC_REG_CMD_DAT_CONT 0x0C +-#define MMC_REG_RES_TO 0x10 +-#define MMC_REG_READ_TO 0x14 +-#define MMC_REG_BLK_LEN 0x18 +-#define MMC_REG_NOB 0x1C +-#define MMC_REG_REV_NO 0x20 +-#define MMC_REG_INT_CNTR 0x24 +-#define MMC_REG_CMD 0x28 +-#define MMC_REG_ARG 0x2C +-#define MMC_REG_RES_FIFO 0x34 +-#define MMC_REG_BUFFER_ACCESS 0x38 +- +-#define STR_STP_CLK_RESET (1 << 3) +-#define STR_STP_CLK_START_CLK (1 << 1) +-#define STR_STP_CLK_STOP_CLK (1 << 0) +- +-#define STATUS_CARD_INSERTION (1 << 31) +-#define STATUS_CARD_REMOVAL (1 << 30) +-#define STATUS_YBUF_EMPTY (1 << 29) +-#define STATUS_XBUF_EMPTY (1 << 28) +-#define STATUS_YBUF_FULL (1 << 27) +-#define STATUS_XBUF_FULL (1 << 26) +-#define STATUS_BUF_UND_RUN (1 << 25) +-#define STATUS_BUF_OVFL (1 << 24) +-#define STATUS_SDIO_INT_ACTIVE (1 << 14) +-#define STATUS_END_CMD_RESP (1 << 13) +-#define STATUS_WRITE_OP_DONE (1 << 12) +-#define STATUS_DATA_TRANS_DONE (1 << 11) +-#define STATUS_READ_OP_DONE (1 << 11) +-#define STATUS_WR_CRC_ERROR_CODE_MASK (3 << 10) +-#define STATUS_CARD_BUS_CLK_RUN (1 << 8) +-#define STATUS_BUF_READ_RDY (1 << 7) +-#define STATUS_BUF_WRITE_RDY (1 << 6) +-#define STATUS_RESP_CRC_ERR (1 << 5) +-#define STATUS_CRC_READ_ERR (1 << 3) +-#define STATUS_CRC_WRITE_ERR (1 << 2) +-#define STATUS_TIME_OUT_RESP (1 << 1) +-#define STATUS_TIME_OUT_READ (1 << 0) +-#define STATUS_ERR_MASK 0x2f +- +-#define CMD_DAT_CONT_CMD_RESP_LONG_OFF (1 << 12) +-#define CMD_DAT_CONT_STOP_READWAIT (1 << 11) +-#define CMD_DAT_CONT_START_READWAIT (1 << 10) +-#define CMD_DAT_CONT_BUS_WIDTH_4 (2 << 8) +-#define CMD_DAT_CONT_INIT (1 << 7) +-#define CMD_DAT_CONT_WRITE (1 << 4) +-#define CMD_DAT_CONT_DATA_ENABLE (1 << 3) +-#define CMD_DAT_CONT_RESPONSE_48BIT_CRC (1 << 0) +-#define CMD_DAT_CONT_RESPONSE_136BIT (2 << 0) +-#define CMD_DAT_CONT_RESPONSE_48BIT (3 << 0) +- +-#define INT_SDIO_INT_WKP_EN (1 << 18) +-#define INT_CARD_INSERTION_WKP_EN (1 << 17) +-#define INT_CARD_REMOVAL_WKP_EN (1 << 16) +-#define INT_CARD_INSERTION_EN (1 << 15) +-#define INT_CARD_REMOVAL_EN (1 << 14) +-#define INT_SDIO_IRQ_EN (1 << 13) +-#define INT_DAT0_EN (1 << 12) +-#define INT_BUF_READ_EN (1 << 4) +-#define INT_BUF_WRITE_EN (1 << 3) +-#define INT_END_CMD_RES_EN (1 << 2) +-#define INT_WRITE_OP_DONE_EN (1 << 1) +-#define INT_READ_OP_EN (1 << 0) +- +-struct mxcmci_host { +- struct mmc_host *mmc; +- struct resource *res; +- void __iomem *base; +- int irq; +- int detect_irq; +- int dma; +- int do_dma; +- unsigned int power_mode; +- struct imxmmc_platform_data *pdata; +- +- struct mmc_request *req; +- struct mmc_command *cmd; +- struct mmc_data *data; +- +- unsigned int dma_nents; +- unsigned int datasize; +- unsigned int dma_dir; +- +- u16 rev_no; +- unsigned int cmdat; +- +- struct clk *clk; +- +- int clock; +- +- struct work_struct datawork; +-}; +- +-static inline int mxcmci_use_dma(struct mxcmci_host *host) +-{ +- return host->do_dma; +-} +- +-static void mxcmci_softreset(struct mxcmci_host *host) +-{ +- int i; +- +- /* reset sequence */ +- writew(STR_STP_CLK_RESET, host->base + MMC_REG_STR_STP_CLK); +- writew(STR_STP_CLK_RESET | STR_STP_CLK_START_CLK, +- host->base + MMC_REG_STR_STP_CLK); +- +- for (i = 0; i < 8; i++) +- writew(STR_STP_CLK_START_CLK, host->base + MMC_REG_STR_STP_CLK); +- +- writew(0xff, host->base + MMC_REG_RES_TO); +-} +- +-static void mxcmci_setup_data(struct mxcmci_host *host, struct mmc_data *data) +-{ +- unsigned int nob = data->blocks; +- unsigned int blksz = data->blksz; +- unsigned int datasize = nob * blksz; +-#ifdef HAS_DMA +- struct scatterlist *sg; +- int i; +-#endif +- if (data->flags & MMC_DATA_STREAM) +- nob = 0xffff; +- +- host->data = data; +- data->bytes_xfered = 0; +- +- writew(nob, host->base + MMC_REG_NOB); +- writew(blksz, host->base + MMC_REG_BLK_LEN); +- host->datasize = datasize; +- +-#ifdef HAS_DMA +- for_each_sg(data->sg, sg, data->sg_len, i) { +- if (sg->offset & 3 || sg->length & 3) { +- host->do_dma = 0; +- return; +- } +- } +- +- if (data->flags & MMC_DATA_READ) { +- host->dma_dir = DMA_FROM_DEVICE; +- host->dma_nents = dma_map_sg(mmc_dev(host->mmc), data->sg, +- data->sg_len, host->dma_dir); +- +- imx_dma_setup_sg(host->dma, data->sg, host->dma_nents, datasize, +- host->res->start + MMC_REG_BUFFER_ACCESS, +- DMA_MODE_READ); +- } else { +- host->dma_dir = DMA_TO_DEVICE; +- host->dma_nents = dma_map_sg(mmc_dev(host->mmc), data->sg, +- data->sg_len, host->dma_dir); +- +- imx_dma_setup_sg(host->dma, data->sg, host->dma_nents, datasize, +- host->res->start + MMC_REG_BUFFER_ACCESS, +- DMA_MODE_WRITE); +- } +- +- wmb(); +- +- imx_dma_enable(host->dma); +-#endif /* HAS_DMA */ +-} +- +-static int mxcmci_start_cmd(struct mxcmci_host *host, struct mmc_command *cmd, +- unsigned int cmdat) +-{ +- WARN_ON(host->cmd != NULL); +- host->cmd = cmd; +- +- switch (mmc_resp_type(cmd)) { +- case MMC_RSP_R1: /* short CRC, OPCODE */ +- case MMC_RSP_R1B:/* short CRC, OPCODE, BUSY */ +- cmdat |= CMD_DAT_CONT_RESPONSE_48BIT_CRC; +- break; +- case MMC_RSP_R2: /* long 136 bit + CRC */ +- cmdat |= CMD_DAT_CONT_RESPONSE_136BIT; +- break; +- case MMC_RSP_R3: /* short */ +- cmdat |= CMD_DAT_CONT_RESPONSE_48BIT; +- break; +- case MMC_RSP_NONE: +- break; +- default: +- dev_err(mmc_dev(host->mmc), "unhandled response type 0x%x\n", +- mmc_resp_type(cmd)); +- cmd->error = -EINVAL; +- return -EINVAL; +- } +- +- if (mxcmci_use_dma(host)) +- writel(INT_READ_OP_EN | INT_WRITE_OP_DONE_EN | +- INT_END_CMD_RES_EN, +- host->base + MMC_REG_INT_CNTR); +- else +- writel(INT_END_CMD_RES_EN, host->base + MMC_REG_INT_CNTR); +- +- writew(cmd->opcode, host->base + MMC_REG_CMD); +- writel(cmd->arg, host->base + MMC_REG_ARG); +- writew(cmdat, host->base + MMC_REG_CMD_DAT_CONT); +- +- return 0; +-} +- +-static void mxcmci_finish_request(struct mxcmci_host *host, +- struct mmc_request *req) +-{ +- writel(0, host->base + MMC_REG_INT_CNTR); +- +- host->req = NULL; +- host->cmd = NULL; +- host->data = NULL; +- +- mmc_request_done(host->mmc, req); +-} +- +-static int mxcmci_finish_data(struct mxcmci_host *host, unsigned int stat) +-{ +- struct mmc_data *data = host->data; +- int data_error; +- +-#ifdef HAS_DMA +- if (mxcmci_use_dma(host)) { +- imx_dma_disable(host->dma); +- dma_unmap_sg(mmc_dev(host->mmc), data->sg, host->dma_nents, +- host->dma_dir); +- } +-#endif +- +- if (stat & STATUS_ERR_MASK) { +- dev_dbg(mmc_dev(host->mmc), "request failed. status: 0x%08x\n", +- stat); +- if (stat & STATUS_CRC_READ_ERR) { +- data->error = -EILSEQ; +- } else if (stat & STATUS_CRC_WRITE_ERR) { +- u32 err_code = (stat >> 9) & 0x3; +- if (err_code == 2) /* No CRC response */ +- data->error = -ETIMEDOUT; +- else +- data->error = -EILSEQ; +- } else if (stat & STATUS_TIME_OUT_READ) { +- data->error = -ETIMEDOUT; +- } else { +- data->error = -EIO; +- } +- } else { +- data->bytes_xfered = host->datasize; +- } +- +- data_error = data->error; +- +- host->data = NULL; +- +- return data_error; +-} +- +-static void mxcmci_read_response(struct mxcmci_host *host, unsigned int stat) +-{ +- struct mmc_command *cmd = host->cmd; +- int i; +- u32 a, b, c; +- +- if (!cmd) +- return; +- +- if (stat & STATUS_TIME_OUT_RESP) { +- dev_dbg(mmc_dev(host->mmc), "CMD TIMEOUT\n"); +- cmd->error = -ETIMEDOUT; +- } else if (stat & STATUS_RESP_CRC_ERR && cmd->flags & MMC_RSP_CRC) { +- dev_dbg(mmc_dev(host->mmc), "cmd crc error\n"); +- cmd->error = -EILSEQ; +- } +- +- if (cmd->flags & MMC_RSP_PRESENT) { +- if (cmd->flags & MMC_RSP_136) { +- for (i = 0; i < 4; i++) { +- a = readw(host->base + MMC_REG_RES_FIFO); +- b = readw(host->base + MMC_REG_RES_FIFO); +- cmd->resp[i] = a << 16 | b; +- } +- } else { +- a = readw(host->base + MMC_REG_RES_FIFO); +- b = readw(host->base + MMC_REG_RES_FIFO); +- c = readw(host->base + MMC_REG_RES_FIFO); +- cmd->resp[0] = a << 24 | b << 8 | c >> 8; +- } +- } +-} +- +-static int mxcmci_poll_status(struct mxcmci_host *host, u32 mask) +-{ +- u32 stat; +- unsigned long timeout = jiffies + HZ; +- +- do { +- stat = readl(host->base + MMC_REG_STATUS); +- if (stat & STATUS_ERR_MASK) +- return stat; +- if (time_after(jiffies, timeout)) +- return STATUS_TIME_OUT_READ; +- if (stat & mask) +- return 0; +- cpu_relax(); +- } while (1); +-} +- +-static int mxcmci_pull(struct mxcmci_host *host, void *_buf, int bytes) +-{ +- unsigned int stat; +- u32 *buf = _buf; +- +- while (bytes > 3) { +- stat = mxcmci_poll_status(host, +- STATUS_BUF_READ_RDY | STATUS_READ_OP_DONE); +- if (stat) +- return stat; +- *buf++ = readl(host->base + MMC_REG_BUFFER_ACCESS); +- bytes -= 4; +- } +- +- if (bytes) { +- u8 *b = (u8 *)buf; +- u32 tmp; +- +- stat = mxcmci_poll_status(host, +- STATUS_BUF_READ_RDY | STATUS_READ_OP_DONE); +- if (stat) +- return stat; +- tmp = readl(host->base + MMC_REG_BUFFER_ACCESS); +- memcpy(b, &tmp, bytes); +- } +- +- return 0; +-} +- +-static int mxcmci_push(struct mxcmci_host *host, void *_buf, int bytes) +-{ +- unsigned int stat; +- u32 *buf = _buf; +- +- while (bytes > 3) { +- stat = mxcmci_poll_status(host, STATUS_BUF_WRITE_RDY); +- if (stat) +- return stat; +- writel(*buf++, host->base + MMC_REG_BUFFER_ACCESS); +- bytes -= 4; +- } +- +- if (bytes) { +- u8 *b = (u8 *)buf; +- u32 tmp; +- +- stat = mxcmci_poll_status(host, STATUS_BUF_WRITE_RDY); +- if (stat) +- return stat; +- +- memcpy(&tmp, b, bytes); +- writel(tmp, host->base + MMC_REG_BUFFER_ACCESS); +- } +- +- stat = mxcmci_poll_status(host, STATUS_BUF_WRITE_RDY); +- if (stat) +- return stat; +- +- return 0; +-} +- +-static int mxcmci_transfer_data(struct mxcmci_host *host) +-{ +- struct mmc_data *data = host->req->data; +- struct scatterlist *sg; +- int stat, i; +- +- host->datasize = 0; +- +- host->data = data; +- host->datasize = 0; +- +- if (data->flags & MMC_DATA_READ) { +- for_each_sg(data->sg, sg, data->sg_len, i) { +- stat = mxcmci_pull(host, sg_virt(sg), sg->length); +- if (stat) +- return stat; +- host->datasize += sg->length; +- } +- } else { +- for_each_sg(data->sg, sg, data->sg_len, i) { +- stat = mxcmci_push(host, sg_virt(sg), sg->length); +- if (stat) +- return stat; +- host->datasize += sg->length; +- } +- stat = mxcmci_poll_status(host, STATUS_WRITE_OP_DONE); +- if (stat) +- return stat; +- } +- return 0; +-} +- +-static void mxcmci_datawork(struct work_struct *work) +-{ +- struct mxcmci_host *host = container_of(work, struct mxcmci_host, +- datawork); +- int datastat = mxcmci_transfer_data(host); +- mxcmci_finish_data(host, datastat); +- +- if (host->req->stop) { +- if (mxcmci_start_cmd(host, host->req->stop, 0)) { +- mxcmci_finish_request(host, host->req); +- return; +- } +- } else { +- mxcmci_finish_request(host, host->req); +- } +-} +- +-#ifdef HAS_DMA +-static void mxcmci_data_done(struct mxcmci_host *host, unsigned int stat) +-{ +- struct mmc_data *data = host->data; +- int data_error; +- +- if (!data) +- return; +- +- data_error = mxcmci_finish_data(host, stat); +- +- mxcmci_read_response(host, stat); +- host->cmd = NULL; +- +- if (host->req->stop) { +- if (mxcmci_start_cmd(host, host->req->stop, 0)) { +- mxcmci_finish_request(host, host->req); +- return; +- } +- } else { +- mxcmci_finish_request(host, host->req); +- } +-} +-#endif /* HAS_DMA */ +- +-static void mxcmci_cmd_done(struct mxcmci_host *host, unsigned int stat) +-{ +- mxcmci_read_response(host, stat); +- host->cmd = NULL; +- +- if (!host->data && host->req) { +- mxcmci_finish_request(host, host->req); +- return; +- } +- +- /* For the DMA case the DMA engine handles the data transfer +- * automatically. For non DMA we have to to it ourselves. +- * Don't do it in interrupt context though. +- */ +- if (!mxcmci_use_dma(host) && host->data) +- schedule_work(&host->datawork); +- +-} +- +-static irqreturn_t mxcmci_irq(int irq, void *devid) +-{ +- struct mxcmci_host *host = devid; +- u32 stat; +- +- stat = readl(host->base + MMC_REG_STATUS); +- writel(stat, host->base + MMC_REG_STATUS); +- +- dev_dbg(mmc_dev(host->mmc), "%s: 0x%08x\n", __func__, stat); +- +- if (stat & STATUS_END_CMD_RESP) +- mxcmci_cmd_done(host, stat); +-#ifdef HAS_DMA +- if (mxcmci_use_dma(host) && +- (stat & (STATUS_DATA_TRANS_DONE | STATUS_WRITE_OP_DONE))) +- mxcmci_data_done(host, stat); +-#endif +- return IRQ_HANDLED; +-} +- +-static void mxcmci_request(struct mmc_host *mmc, struct mmc_request *req) +-{ +- struct mxcmci_host *host = mmc_priv(mmc); +- unsigned int cmdat = host->cmdat; +- +- WARN_ON(host->req != NULL); +- +- host->req = req; +- host->cmdat &= ~CMD_DAT_CONT_INIT; +-#ifdef HAS_DMA +- host->do_dma = 1; +-#endif +- if (req->data) { +- mxcmci_setup_data(host, req->data); +- +- cmdat |= CMD_DAT_CONT_DATA_ENABLE; +- +- if (req->data->flags & MMC_DATA_WRITE) +- cmdat |= CMD_DAT_CONT_WRITE; +- } +- +- if (mxcmci_start_cmd(host, req->cmd, cmdat)) +- mxcmci_finish_request(host, req); +-} +- +-static void mxcmci_set_clk_rate(struct mxcmci_host *host, unsigned int clk_ios) +-{ +- unsigned int divider; +- int prescaler = 0; +- unsigned int clk_in = clk_get_rate(host->clk); +- +- while (prescaler <= 0x800) { +- for (divider = 1; divider <= 0xF; divider++) { +- int x; +- +- x = (clk_in / (divider + 1)); +- +- if (prescaler) +- x /= (prescaler * 2); +- +- if (x <= clk_ios) +- break; +- } +- if (divider < 0x10) +- break; +- +- if (prescaler == 0) +- prescaler = 1; +- else +- prescaler <<= 1; +- } +- +- writew((prescaler << 4) | divider, host->base + MMC_REG_CLK_RATE); +- +- dev_dbg(mmc_dev(host->mmc), "scaler: %d divider: %d in: %d out: %d\n", +- prescaler, divider, clk_in, clk_ios); +-} +- +-static void mxcmci_set_ios(struct mmc_host *mmc, struct mmc_ios *ios) +-{ +- struct mxcmci_host *host = mmc_priv(mmc); +-#ifdef HAS_DMA +- unsigned int blen; +- /* +- * use burstlen of 64 in 4 bit mode (--> reg value 0) +- * use burstlen of 16 in 1 bit mode (--> reg value 16) +- */ +- if (ios->bus_width == MMC_BUS_WIDTH_4) +- blen = 0; +- else +- blen = 16; +- +- imx_dma_config_burstlen(host->dma, blen); +-#endif +- if (ios->bus_width == MMC_BUS_WIDTH_4) +- host->cmdat |= CMD_DAT_CONT_BUS_WIDTH_4; +- else +- host->cmdat &= ~CMD_DAT_CONT_BUS_WIDTH_4; +- +- if (host->power_mode != ios->power_mode) { +- if (host->pdata && host->pdata->setpower) +- host->pdata->setpower(mmc_dev(mmc), ios->vdd); +- host->power_mode = ios->power_mode; +- if (ios->power_mode == MMC_POWER_ON) +- host->cmdat |= CMD_DAT_CONT_INIT; +- } +- +- if (ios->clock) { +- mxcmci_set_clk_rate(host, ios->clock); +- writew(STR_STP_CLK_START_CLK, host->base + MMC_REG_STR_STP_CLK); +- } else { +- writew(STR_STP_CLK_STOP_CLK, host->base + MMC_REG_STR_STP_CLK); +- } +- +- host->clock = ios->clock; +-} +- +-static irqreturn_t mxcmci_detect_irq(int irq, void *data) +-{ +- struct mmc_host *mmc = data; +- +- dev_dbg(mmc_dev(mmc), "%s\n", __func__); +- +- mmc_detect_change(mmc, msecs_to_jiffies(250)); +- return IRQ_HANDLED; +-} +- +-static int mxcmci_get_ro(struct mmc_host *mmc) +-{ +- struct mxcmci_host *host = mmc_priv(mmc); +- +- if (host->pdata && host->pdata->get_ro) +- return !!host->pdata->get_ro(mmc_dev(mmc)); +- /* +- * Board doesn't support read only detection; let the mmc core +- * decide what to do. +- */ +- return -ENOSYS; +-} +- +- +-static const struct mmc_host_ops mxcmci_ops = { +- .request = mxcmci_request, +- .set_ios = mxcmci_set_ios, +- .get_ro = mxcmci_get_ro, +-}; +- +-static int mxcmci_probe(struct platform_device *pdev) +-{ +- struct mmc_host *mmc; +- struct mxcmci_host *host = NULL; +- struct resource *r; +- int ret = 0, irq; +- +- printk(KERN_INFO "i.MX SDHC driver\n"); +- +- r = platform_get_resource(pdev, IORESOURCE_MEM, 0); +- irq = platform_get_irq(pdev, 0); +- if (!r || irq < 0) +- return -EINVAL; +- +- r = request_mem_region(r->start, resource_size(r), pdev->name); +- if (!r) +- return -EBUSY; +- +- mmc = mmc_alloc_host(sizeof(struct mxcmci_host), &pdev->dev); +- if (!mmc) { +- ret = -ENOMEM; +- goto out_release_mem; +- } +- +- mmc->ops = &mxcmci_ops; +- mmc->caps = MMC_CAP_4_BIT_DATA; +- +- /* MMC core transfer sizes tunable parameters */ +- mmc->max_hw_segs = 64; +- mmc->max_phys_segs = 64; +- mmc->max_blk_size = 2048; +- mmc->max_blk_count = 65535; +- mmc->max_req_size = mmc->max_blk_size * mmc->max_blk_count; +- mmc->max_seg_size = mmc->max_seg_size; +- +- host = mmc_priv(mmc); +- host->base = ioremap(r->start, resource_size(r)); +- if (!host->base) { +- ret = -ENOMEM; +- goto out_free; +- } +- +- host->mmc = mmc; +- host->pdata = pdev->dev.platform_data; +- +- if (host->pdata && host->pdata->ocr_avail) +- mmc->ocr_avail = host->pdata->ocr_avail; +- else +- mmc->ocr_avail = MMC_VDD_32_33 | MMC_VDD_33_34; +- +- host->res = r; +- host->irq = irq; +- +- host->clk = clk_get(&pdev->dev, "sdhc_clk"); +- if (IS_ERR(host->clk)) { +- ret = PTR_ERR(host->clk); +- goto out_iounmap; +- } +- clk_enable(host->clk); +- +- mxcmci_softreset(host); +- +- host->rev_no = readw(host->base + MMC_REG_REV_NO); +- if (host->rev_no != 0x400) { +- ret = -ENODEV; +- dev_err(mmc_dev(host->mmc), "wrong rev.no. 0x%08x. aborting.\n", +- host->rev_no); +- goto out_clk_put; +- } +- +- mmc->f_min = clk_get_rate(host->clk) >> 7; +- mmc->f_max = clk_get_rate(host->clk) >> 1; +- +- /* recommended in data sheet */ +- writew(0x2db4, host->base + MMC_REG_READ_TO); +- +- writel(0, host->base + MMC_REG_INT_CNTR); +- +-#ifdef HAS_DMA +- host->dma = imx_dma_request_by_prio(DRIVER_NAME, DMA_PRIO_LOW); +- if (host->dma < 0) { +- dev_err(mmc_dev(host->mmc), "imx_dma_request_by_prio failed\n"); +- ret = -EBUSY; +- goto out_clk_put; +- } +- +- r = platform_get_resource(pdev, IORESOURCE_DMA, 0); +- if (!r) { +- ret = -EINVAL; +- goto out_free_dma; +- } +- +- ret = imx_dma_config_channel(host->dma, +- IMX_DMA_MEMSIZE_32 | IMX_DMA_TYPE_FIFO, +- IMX_DMA_MEMSIZE_32 | IMX_DMA_TYPE_LINEAR, +- r->start, 0); +- if (ret) { +- dev_err(mmc_dev(host->mmc), "failed to config DMA channel\n"); +- goto out_free_dma; +- } +-#endif +- INIT_WORK(&host->datawork, mxcmci_datawork); +- +- ret = request_irq(host->irq, mxcmci_irq, 0, DRIVER_NAME, host); +- if (ret) +- goto out_free_dma; +- +- platform_set_drvdata(pdev, mmc); +- +- if (host->pdata && host->pdata->init) { +- ret = host->pdata->init(&pdev->dev, mxcmci_detect_irq, +- host->mmc); +- if (ret) +- goto out_free_irq; +- } +- +- mmc_add_host(mmc); +- +- return 0; +- +-out_free_irq: +- free_irq(host->irq, host); +-out_free_dma: +-#ifdef HAS_DMA +- imx_dma_free(host->dma); +-#endif +-out_clk_put: +- clk_disable(host->clk); +- clk_put(host->clk); +-out_iounmap: +- iounmap(host->base); +-out_free: +- mmc_free_host(mmc); +-out_release_mem: +- release_mem_region(host->res->start, resource_size(host->res)); +- return ret; +-} +- +-static int mxcmci_remove(struct platform_device *pdev) +-{ +- struct mmc_host *mmc = platform_get_drvdata(pdev); +- struct mxcmci_host *host = mmc_priv(mmc); +- +- platform_set_drvdata(pdev, NULL); +- +- mmc_remove_host(mmc); +- +- if (host->pdata && host->pdata->exit) +- host->pdata->exit(&pdev->dev, mmc); +- +- free_irq(host->irq, host); +- iounmap(host->base); +-#ifdef HAS_DMA +- imx_dma_free(host->dma); +-#endif +- clk_disable(host->clk); +- clk_put(host->clk); +- +- release_mem_region(host->res->start, resource_size(host->res)); +- release_resource(host->res); +- +- mmc_free_host(mmc); +- +- return 0; +-} +- +-#ifdef CONFIG_PM +-static int mxcmci_suspend(struct platform_device *dev, pm_message_t state) +-{ +- struct mmc_host *mmc = platform_get_drvdata(dev); +- int ret = 0; +- +- if (mmc) +- ret = mmc_suspend_host(mmc, state); +- +- return ret; +-} +- +-static int mxcmci_resume(struct platform_device *dev) +-{ +- struct mmc_host *mmc = platform_get_drvdata(dev); +- struct mxcmci_host *host; +- int ret = 0; +- +- if (mmc) { +- host = mmc_priv(mmc); +- ret = mmc_resume_host(mmc); +- } +- +- return ret; +-} +-#else +-#define mxcmci_suspend NULL +-#define mxcmci_resume NULL +-#endif /* CONFIG_PM */ +- +-static struct platform_driver mxcmci_driver = { +- .probe = mxcmci_probe, +- .remove = mxcmci_remove, +- .suspend = mxcmci_suspend, +- .resume = mxcmci_resume, +- .driver = { +- .name = DRIVER_NAME, +- .owner = THIS_MODULE, +- } +-}; +- +-static int __init mxcmci_init(void) +-{ +- return platform_driver_register(&mxcmci_driver); +-} +- +-static void __exit mxcmci_exit(void) +-{ +- platform_driver_unregister(&mxcmci_driver); +-} +- +-module_init(mxcmci_init); +-module_exit(mxcmci_exit); +- +-MODULE_DESCRIPTION("i.MX Multimedia Card Interface Driver"); +-MODULE_AUTHOR("Sascha Hauer, Pengutronix"); +-MODULE_LICENSE("GPL"); +-MODULE_ALIAS("platform:imx-mmc"); +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/drivers/mmc/host/omap_hsmmc.c linux-2.6.29-rc3.owrt/drivers/mmc/host/omap_hsmmc.c +--- linux-2.6.29.owrt/drivers/mmc/host/omap_hsmmc.c 2009-05-10 22:04:38.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/drivers/mmc/host/omap_hsmmc.c 2009-05-10 23:48:28.000000000 +0200 +@@ -55,7 +55,6 @@ + #define VS30 (1 << 25) + #define SDVS18 (0x5 << 9) + #define SDVS30 (0x6 << 9) +-#define SDVS33 (0x7 << 9) + #define SDVSCLR 0xFFFFF1FF + #define SDVSDET 0x00000400 + #define AUTOIDLE 0x1 +@@ -376,32 +375,6 @@ + } + #endif /* CONFIG_MMC_DEBUG */ + +-/* +- * MMC controller internal state machines reset +- * +- * Used to reset command or data internal state machines, using respectively +- * SRC or SRD bit of SYSCTL register +- * Can be called from interrupt context +- */ +-static inline void mmc_omap_reset_controller_fsm(struct mmc_omap_host *host, +- unsigned long bit) +-{ +- unsigned long i = 0; +- unsigned long limit = (loops_per_jiffy * +- msecs_to_jiffies(MMC_TIMEOUT_MS)); +- +- OMAP_HSMMC_WRITE(host->base, SYSCTL, +- OMAP_HSMMC_READ(host->base, SYSCTL) | bit); +- +- while ((OMAP_HSMMC_READ(host->base, SYSCTL) & bit) && +- (i++ < limit)) +- cpu_relax(); +- +- if (OMAP_HSMMC_READ(host->base, SYSCTL) & bit) +- dev_err(mmc_dev(host->mmc), +- "Timeout waiting on controller reset in %s\n", +- __func__); +-} + + /* + * MMC controller IRQ handler +@@ -430,17 +403,21 @@ + (status & CMD_CRC)) { + if (host->cmd) { + if (status & CMD_TIMEOUT) { +- mmc_omap_reset_controller_fsm(host, SRC); ++ OMAP_HSMMC_WRITE(host->base, SYSCTL, ++ OMAP_HSMMC_READ(host->base, ++ SYSCTL) | SRC); ++ while (OMAP_HSMMC_READ(host->base, ++ SYSCTL) & SRC) ++ ; ++ + host->cmd->error = -ETIMEDOUT; + } else { + host->cmd->error = -EILSEQ; + } + end_cmd = 1; + } +- if (host->data) { ++ if (host->data) + mmc_dma_cleanup(host); +- mmc_omap_reset_controller_fsm(host, SRD); +- } + } + if ((status & DATA_TIMEOUT) || + (status & DATA_CRC)) { +@@ -449,7 +426,12 @@ + mmc_dma_cleanup(host); + else + host->data->error = -EILSEQ; +- mmc_omap_reset_controller_fsm(host, SRD); ++ OMAP_HSMMC_WRITE(host->base, SYSCTL, ++ OMAP_HSMMC_READ(host->base, ++ SYSCTL) | SRD); ++ while (OMAP_HSMMC_READ(host->base, ++ SYSCTL) & SRD) ++ ; + end_trans = 1; + } + } +@@ -474,20 +456,13 @@ + } + + /* +- * Switch MMC interface voltage ... only relevant for MMC1. +- * +- * MMC2 and MMC3 use fixed 1.8V levels, and maybe a transceiver. +- * The MMC2 transceiver controls are used instead of DAT4..DAT7. +- * Some chips, like eMMC ones, use internal transceivers. ++ * Switch MMC operating voltage + */ + static int omap_mmc_switch_opcond(struct mmc_omap_host *host, int vdd) + { + u32 reg_val = 0; + int ret; + +- if (host->id != OMAP_MMC1_DEVID) +- return 0; +- + /* Disable the clocks */ + clk_disable(host->fclk); + clk_disable(host->iclk); +@@ -510,26 +485,19 @@ + OMAP_HSMMC_WRITE(host->base, HCTL, + OMAP_HSMMC_READ(host->base, HCTL) & SDVSCLR); + reg_val = OMAP_HSMMC_READ(host->base, HCTL); +- + /* + * If a MMC dual voltage card is detected, the set_ios fn calls + * this fn with VDD bit set for 1.8V. Upon card removal from the + * slot, omap_mmc_set_ios sets the VDD back to 3V on MMC_POWER_OFF. + * +- * Cope with a bit of slop in the range ... per data sheets: +- * - "1.8V" for vdds_mmc1/vdds_mmc1a can be up to 2.45V max, +- * but recommended values are 1.71V to 1.89V +- * - "3.0V" for vdds_mmc1/vdds_mmc1a can be up to 3.5V max, +- * but recommended values are 2.7V to 3.3V +- * +- * Board setup code shouldn't permit anything very out-of-range. +- * TWL4030-family VMMC1 and VSIM regulators are fine (avoiding the +- * middle range) but VSIM can't power DAT4..DAT7 at more than 3V. ++ * Only MMC1 supports 3.0V. MMC2 will not function if SDVS30 is ++ * set in HCTL. + */ +- if ((1 << vdd) <= MMC_VDD_23_24) +- reg_val |= SDVS18; +- else ++ if (host->id == OMAP_MMC1_DEVID && (((1 << vdd) == MMC_VDD_32_33) || ++ ((1 << vdd) == MMC_VDD_33_34))) + reg_val |= SDVS30; ++ if ((1 << vdd) == MMC_VDD_165_195) ++ reg_val |= SDVS18; + + OMAP_HSMMC_WRITE(host->base, HCTL, reg_val); + +@@ -549,15 +517,16 @@ + { + struct mmc_omap_host *host = container_of(work, struct mmc_omap_host, + mmc_carddetect_work); +- struct omap_mmc_slot_data *slot = &mmc_slot(host); +- +- host->carddetect = slot->card_detect(slot->card_detect_irq); + + sysfs_notify(&host->mmc->class_dev.kobj, NULL, "cover_switch"); + if (host->carddetect) { + mmc_detect_change(host->mmc, (HZ * 200) / 1000); + } else { +- mmc_omap_reset_controller_fsm(host, SRD); ++ OMAP_HSMMC_WRITE(host->base, SYSCTL, ++ OMAP_HSMMC_READ(host->base, SYSCTL) | SRD); ++ while (OMAP_HSMMC_READ(host->base, SYSCTL) & SRD) ++ ; ++ + mmc_detect_change(host->mmc, (HZ * 50) / 1000); + } + } +@@ -569,6 +538,7 @@ + { + struct mmc_omap_host *host = (struct mmc_omap_host *)dev_id; + ++ host->carddetect = mmc_slot(host).card_detect(irq); + schedule_work(&host->mmc_carddetect_work); + + return IRQ_HANDLED; +@@ -787,14 +757,10 @@ + case MMC_POWER_OFF: + mmc_slot(host).set_power(host->dev, host->slot_id, 0, 0); + /* +- * Reset interface voltage to 3V if it's 1.8V now; +- * only relevant on MMC-1, the others always use 1.8V. +- * ++ * Reset bus voltage to 3V if it got set to 1.8V earlier. + * REVISIT: If we are able to detect cards after unplugging + * a 1.8V card, this code should not be needed. + */ +- if (host->id != OMAP_MMC1_DEVID) +- break; + if (!(OMAP_HSMMC_READ(host->base, HCTL) & SDVSDET)) { + int vdd = fls(host->mmc->ocr_avail) - 1; + if (omap_mmc_switch_opcond(host, vdd) != 0) +@@ -818,9 +784,7 @@ + } + + if (host->id == OMAP_MMC1_DEVID) { +- /* Only MMC1 can interface at 3V without some flavor +- * of external transceiver; but they all handle 1.8V. +- */ ++ /* Only MMC1 can operate at 3V/1.8V */ + if ((OMAP_HSMMC_READ(host->base, HCTL) & SDVSDET) && + (ios->vdd == DUAL_VOLT_OCR_BIT)) { + /* +@@ -1173,9 +1137,7 @@ + " level suspend\n"); + } + +- if (host->id == OMAP_MMC1_DEVID +- && !(OMAP_HSMMC_READ(host->base, HCTL) +- & SDVSDET)) { ++ if (!(OMAP_HSMMC_READ(host->base, HCTL) & SDVSDET)) { + OMAP_HSMMC_WRITE(host->base, HCTL, + OMAP_HSMMC_READ(host->base, HCTL) + & SDVSCLR); +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/drivers/mmc/host/pxamci.c linux-2.6.29-rc3.owrt/drivers/mmc/host/pxamci.c +--- linux-2.6.29.owrt/drivers/mmc/host/pxamci.c 2009-05-10 22:04:38.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/drivers/mmc/host/pxamci.c 2009-05-10 23:48:28.000000000 +0200 +@@ -180,15 +180,7 @@ + else + DALGN &= ~(1 << host->dma); + DDADR(host->dma) = host->sg_dma; +- +- /* +- * workaround for erratum #91: +- * only start DMA now if we are doing a read, +- * otherwise we wait until CMD/RESP has finished +- * before starting DMA. +- */ +- if (!cpu_is_pxa27x() || data->flags & MMC_DATA_READ) +- DCSR(host->dma) = DCSR_RUN; ++ DCSR(host->dma) = DCSR_RUN; + } + + static void pxamci_start_cmd(struct pxamci_host *host, struct mmc_command *cmd, unsigned int cmdat) +@@ -259,28 +251,23 @@ + if (stat & STAT_TIME_OUT_RESPONSE) { + cmd->error = -ETIMEDOUT; + } else if (stat & STAT_RES_CRC_ERR && cmd->flags & MMC_RSP_CRC) { ++#ifdef CONFIG_PXA27x + /* + * workaround for erratum #42: + * Intel PXA27x Family Processor Specification Update Rev 001 + * A bogus CRC error can appear if the msb of a 136 bit + * response is a one. + */ +- if (cpu_is_pxa27x() && +- (cmd->flags & MMC_RSP_136 && cmd->resp[0] & 0x80000000)) ++ if (cmd->flags & MMC_RSP_136 && cmd->resp[0] & 0x80000000) { + pr_debug("ignoring CRC from command %d - *risky*\n", cmd->opcode); +- else +- cmd->error = -EILSEQ; ++ } else ++#endif ++ cmd->error = -EILSEQ; + } + + pxamci_disable_irq(host, END_CMD_RES); + if (host->data && !cmd->error) { + pxamci_enable_irq(host, DATA_TRAN_DONE); +- /* +- * workaround for erratum #91, if doing write +- * enable DMA late +- */ +- if (cpu_is_pxa27x() && host->data->flags & MMC_DATA_WRITE) +- DCSR(host->dma) = DCSR_RUN; + } else { + pxamci_finish_request(host, host->mrq); + } +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/drivers/mmc/host/ricoh_mmc.c linux-2.6.29-rc3.owrt/drivers/mmc/host/ricoh_mmc.c +--- linux-2.6.29.owrt/drivers/mmc/host/ricoh_mmc.c 2009-05-10 22:04:38.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/drivers/mmc/host/ricoh_mmc.c 2009-05-10 23:48:28.000000000 +0200 +@@ -196,7 +196,7 @@ + pci_set_drvdata(pdev, NULL); + } + +-static int ricoh_mmc_suspend_late(struct pci_dev *pdev, pm_message_t state) ++static int ricoh_mmc_suspend(struct pci_dev *pdev, pm_message_t state) + { + struct pci_dev *fw_dev = NULL; + +@@ -210,7 +210,7 @@ + return 0; + } + +-static int ricoh_mmc_resume_early(struct pci_dev *pdev) ++static int ricoh_mmc_resume(struct pci_dev *pdev) + { + struct pci_dev *fw_dev = NULL; + +@@ -229,8 +229,8 @@ + .id_table = pci_ids, + .probe = ricoh_mmc_probe, + .remove = __devexit_p(ricoh_mmc_remove), +- .suspend_late = ricoh_mmc_suspend_late, +- .resume_early = ricoh_mmc_resume_early, ++ .suspend = ricoh_mmc_suspend, ++ .resume = ricoh_mmc_resume, + }; + + /*****************************************************************************\ +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/drivers/mmc/host/s3cmci.c linux-2.6.29-rc3.owrt/drivers/mmc/host/s3cmci.c +--- linux-2.6.29.owrt/drivers/mmc/host/s3cmci.c 2009-05-10 22:04:38.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/drivers/mmc/host/s3cmci.c 2009-05-10 23:48:28.000000000 +0200 +@@ -329,7 +329,7 @@ + + to_ptr = host->base + host->sdidata; + +- while ((fifo = fifo_free(host)) > 3) { ++ while ((fifo = fifo_free(host))) { + if (!host->pio_bytes) { + res = get_data_buffer(host, &host->pio_bytes, + &host->pio_ptr); +@@ -793,7 +793,8 @@ + host->mem->start + host->sdidata); + + if (!setup_ok) { +- s3c2410_dma_config(host->dma, 4, 0); ++ s3c2410_dma_config(host->dma, 4, ++ (S3C2410_DCON_HWTRIG | S3C2410_DCON_CH0_SDI)); + s3c2410_dma_set_buffdone_fn(host->dma, + s3cmci_dma_done_callback); + s3c2410_dma_setflags(host->dma, S3C2410_DMAF_AUTOSTART); +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/drivers/mmc/host/sdhci.c linux-2.6.29-rc3.owrt/drivers/mmc/host/sdhci.c +--- linux-2.6.29.owrt/drivers/mmc/host/sdhci.c 2009-05-10 22:04:38.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/drivers/mmc/host/sdhci.c 2009-05-10 23:48:28.000000000 +0200 +@@ -1291,11 +1291,8 @@ + if (host->cmd->data) + DBG("Cannot wait for busy signal when also " + "doing a data transfer"); +- else if (!(host->quirks & SDHCI_QUIRK_NO_BUSY_IRQ)) ++ else + return; +- +- /* The controller does not support the end-of-busy IRQ, +- * fall through and take the SDHCI_INT_RESPONSE */ + } + + if (intmask & SDHCI_INT_RESPONSE) +@@ -1639,7 +1636,8 @@ + mmc->f_max = host->max_clk; + mmc->caps = MMC_CAP_4_BIT_DATA | MMC_CAP_SDIO_IRQ; + +- if (caps & SDHCI_CAN_DO_HISPD) ++ if ((caps & SDHCI_CAN_DO_HISPD) || ++ (host->quirks & SDHCI_QUIRK_FORCE_HIGHSPEED)) + mmc->caps |= MMC_CAP_SD_HIGHSPEED; + + mmc->ocr_avail = 0; +@@ -1725,9 +1723,7 @@ + #endif + + #ifdef SDHCI_USE_LEDS_CLASS +- snprintf(host->led_name, sizeof(host->led_name), +- "%s::", mmc_hostname(mmc)); +- host->led.name = host->led_name; ++ host->led.name = mmc_hostname(mmc); + host->led.brightness = LED_OFF; + host->led.default_trigger = mmc_hostname(mmc); + host->led.brightness_set = sdhci_led_control; +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/drivers/mmc/host/sdhci.h linux-2.6.29-rc3.owrt/drivers/mmc/host/sdhci.h +--- linux-2.6.29.owrt/drivers/mmc/host/sdhci.h 2009-05-10 22:04:38.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/drivers/mmc/host/sdhci.h 2009-05-10 23:48:28.000000000 +0200 +@@ -208,8 +208,8 @@ + #define SDHCI_QUIRK_BROKEN_TIMEOUT_VAL (1<<12) + /* Controller has an issue with buffer bits for small transfers */ + #define SDHCI_QUIRK_BROKEN_SMALL_PIO (1<<13) +-/* Controller does not provide transfer-complete interrupt when not busy */ +-#define SDHCI_QUIRK_NO_BUSY_IRQ (1<<14) ++/* Controller supports high speed but doesn't have the caps bit set */ ++#define SDHCI_QUIRK_FORCE_HIGHSPEED (1<<14) + + int irq; /* Device IRQ */ + void __iomem * ioaddr; /* Mapped address */ +@@ -222,7 +222,6 @@ + + #if defined(CONFIG_LEDS_CLASS) || defined(CONFIG_LEDS_CLASS_MODULE) + struct led_classdev led; /* LED control */ +- char led_name[32]; + #endif + + spinlock_t lock; /* Mutex */ +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/drivers/mmc/host/sdhci-pci.c linux-2.6.29-rc3.owrt/drivers/mmc/host/sdhci-pci.c +--- linux-2.6.29.owrt/drivers/mmc/host/sdhci-pci.c 2009-05-10 22:04:38.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/drivers/mmc/host/sdhci-pci.c 2009-05-10 23:48:28.000000000 +0200 +@@ -107,7 +107,6 @@ + + static const struct sdhci_pci_fixes sdhci_cafe = { + .quirks = SDHCI_QUIRK_NO_SIMULT_VDD_AND_POWER | +- SDHCI_QUIRK_NO_BUSY_IRQ | + SDHCI_QUIRK_BROKEN_TIMEOUT_VAL, + }; + +@@ -145,7 +144,8 @@ + SDHCI_QUIRK_32BIT_DMA_SIZE | + SDHCI_QUIRK_32BIT_ADMA_SIZE | + SDHCI_QUIRK_RESET_AFTER_REQUEST | +- SDHCI_QUIRK_BROKEN_SMALL_PIO; ++ SDHCI_QUIRK_BROKEN_SMALL_PIO | ++ SDHCI_QUIRK_FORCE_HIGHSPEED; + } + + /* +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/drivers/mtd/chips/map_rom.c linux-2.6.29-rc3.owrt/drivers/mtd/chips/map_rom.c +--- linux-2.6.29.owrt/drivers/mtd/chips/map_rom.c 2009-05-10 22:04:39.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/drivers/mtd/chips/map_rom.c 2009-05-10 23:48:28.000000000 +0200 +@@ -19,7 +19,6 @@ + static int maprom_write (struct mtd_info *, loff_t, size_t, size_t *, const u_char *); + static void maprom_nop (struct mtd_info *); + static struct mtd_info *map_rom_probe(struct map_info *map); +-static int maprom_erase (struct mtd_info *mtd, struct erase_info *info); + + static struct mtd_chip_driver maprom_chipdrv = { + .probe = map_rom_probe, +@@ -43,7 +42,6 @@ + mtd->read = maprom_read; + mtd->write = maprom_write; + mtd->sync = maprom_nop; +- mtd->erase = maprom_erase; + mtd->flags = MTD_CAP_ROM; + mtd->erasesize = map->size; + mtd->writesize = 1; +@@ -73,12 +71,6 @@ + return -EIO; + } + +-static int maprom_erase (struct mtd_info *mtd, struct erase_info *info) +-{ +- /* We do our best 8) */ +- return -EROFS; +-} +- + static int __init map_rom_init(void) + { + register_mtd_chip_driver(&maprom_chipdrv); +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/drivers/mtd/devices/Kconfig linux-2.6.29-rc3.owrt/drivers/mtd/devices/Kconfig +--- linux-2.6.29.owrt/drivers/mtd/devices/Kconfig 2009-05-10 22:04:39.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/drivers/mtd/devices/Kconfig 2009-05-10 23:48:28.000000000 +0200 +@@ -120,6 +120,13 @@ + doesn't have access to, memory beyond the mem=xxx limit, nvram, + memory on the video card, etc... + ++config MTD_PS3VRAM ++ tristate "PS3 video RAM" ++ depends on FB_PS3 ++ help ++ This driver allows you to use excess PS3 video RAM as volatile ++ storage or system swap. ++ + config MTD_LART + tristate "28F160xx flash driver for LART" + depends on SA1100_LART +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/drivers/mtd/devices/Makefile linux-2.6.29-rc3.owrt/drivers/mtd/devices/Makefile +--- linux-2.6.29.owrt/drivers/mtd/devices/Makefile 2009-05-10 22:04:39.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/drivers/mtd/devices/Makefile 2009-05-10 23:48:28.000000000 +0200 +@@ -16,3 +16,4 @@ + obj-$(CONFIG_MTD_BLOCK2MTD) += block2mtd.o + obj-$(CONFIG_MTD_DATAFLASH) += mtd_dataflash.o + obj-$(CONFIG_MTD_M25P80) += m25p80.o ++obj-$(CONFIG_MTD_PS3VRAM) += ps3vram.o +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/drivers/mtd/devices/mtd_dataflash.c linux-2.6.29-rc3.owrt/drivers/mtd/devices/mtd_dataflash.c +--- linux-2.6.29.owrt/drivers/mtd/devices/mtd_dataflash.c 2009-05-10 22:04:39.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/drivers/mtd/devices/mtd_dataflash.c 2009-05-10 23:48:28.000000000 +0200 +@@ -821,8 +821,7 @@ + if (!(info->flags & IS_POW2PS)) + return info; + } +- } else +- return info; ++ } + } + } + +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/drivers/mtd/devices/ps3vram.c linux-2.6.29-rc3.owrt/drivers/mtd/devices/ps3vram.c +--- linux-2.6.29.owrt/drivers/mtd/devices/ps3vram.c 1970-01-01 01:00:00.000000000 +0100 ++++ linux-2.6.29-rc3.owrt/drivers/mtd/devices/ps3vram.c 2009-05-10 23:48:28.000000000 +0200 +@@ -0,0 +1,768 @@ ++/** ++ * ps3vram - Use extra PS3 video ram as MTD block device. ++ * ++ * Copyright (c) 2007-2008 Jim Paris <jim@jtan.com> ++ * Added support RSX DMA Vivien Chappelier <vivien.chappelier@free.fr> ++ */ ++ ++#include <linux/io.h> ++#include <linux/mm.h> ++#include <linux/init.h> ++#include <linux/kernel.h> ++#include <linux/list.h> ++#include <linux/module.h> ++#include <linux/moduleparam.h> ++#include <linux/slab.h> ++#include <linux/version.h> ++#include <linux/gfp.h> ++#include <linux/delay.h> ++#include <linux/mtd/mtd.h> ++ ++#include <asm/lv1call.h> ++#include <asm/ps3.h> ++ ++#define DEVICE_NAME "ps3vram" ++ ++#define XDR_BUF_SIZE (2 * 1024 * 1024) /* XDR buffer (must be 1MiB aligned) */ ++#define XDR_IOIF 0x0c000000 ++ ++#define FIFO_BASE XDR_IOIF ++#define FIFO_SIZE (64 * 1024) ++ ++#define DMA_PAGE_SIZE (4 * 1024) ++ ++#define CACHE_PAGE_SIZE (256 * 1024) ++#define CACHE_PAGE_COUNT ((XDR_BUF_SIZE - FIFO_SIZE) / CACHE_PAGE_SIZE) ++ ++#define CACHE_OFFSET CACHE_PAGE_SIZE ++#define FIFO_OFFSET 0 ++ ++#define CTRL_PUT 0x10 ++#define CTRL_GET 0x11 ++#define CTRL_TOP 0x15 ++ ++#define UPLOAD_SUBCH 1 ++#define DOWNLOAD_SUBCH 2 ++ ++#define NV_MEMORY_TO_MEMORY_FORMAT_OFFSET_IN 0x0000030c ++#define NV_MEMORY_TO_MEMORY_FORMAT_NOTIFY 0x00000104 ++ ++#define L1GPU_CONTEXT_ATTRIBUTE_FB_BLIT 0x601 ++ ++struct mtd_info ps3vram_mtd; ++ ++#define CACHE_PAGE_PRESENT 1 ++#define CACHE_PAGE_DIRTY 2 ++ ++struct ps3vram_tag { ++ unsigned int address; ++ unsigned int flags; ++}; ++ ++struct ps3vram_cache { ++ unsigned int page_count; ++ unsigned int page_size; ++ struct ps3vram_tag *tags; ++}; ++ ++struct ps3vram_priv { ++ u64 memory_handle; ++ u64 context_handle; ++ u32 *ctrl; ++ u32 *reports; ++ u8 __iomem *ddr_base; ++ u8 *xdr_buf; ++ ++ u32 *fifo_base; ++ u32 *fifo_ptr; ++ ++ struct device *dev; ++ struct ps3vram_cache cache; ++ ++ /* Used to serialize cache/DMA operations */ ++ struct mutex lock; ++}; ++ ++#define DMA_NOTIFIER_HANDLE_BASE 0x66604200 /* first DMA notifier handle */ ++#define DMA_NOTIFIER_OFFSET_BASE 0x1000 /* first DMA notifier offset */ ++#define DMA_NOTIFIER_SIZE 0x40 ++#define NOTIFIER 7 /* notifier used for completion report */ ++ ++/* A trailing '-' means to subtract off ps3fb_videomemory.size */ ++char *size = "256M-"; ++module_param(size, charp, 0); ++MODULE_PARM_DESC(size, "memory size"); ++ ++static u32 *ps3vram_get_notifier(u32 *reports, int notifier) ++{ ++ return (void *) reports + ++ DMA_NOTIFIER_OFFSET_BASE + ++ DMA_NOTIFIER_SIZE * notifier; ++} ++ ++static void ps3vram_notifier_reset(struct mtd_info *mtd) ++{ ++ int i; ++ ++ struct ps3vram_priv *priv = mtd->priv; ++ u32 *notify = ps3vram_get_notifier(priv->reports, NOTIFIER); ++ for (i = 0; i < 4; i++) ++ notify[i] = 0xffffffff; ++} ++ ++static int ps3vram_notifier_wait(struct mtd_info *mtd, unsigned int timeout_ms) ++{ ++ struct ps3vram_priv *priv = mtd->priv; ++ u32 *notify = ps3vram_get_notifier(priv->reports, NOTIFIER); ++ unsigned long timeout = jiffies + msecs_to_jiffies(timeout_ms); ++ ++ do { ++ if (!notify[3]) ++ return 0; ++ msleep(1); ++ } while (time_before(jiffies, timeout)); ++ ++ return -ETIMEDOUT; ++} ++ ++static void ps3vram_init_ring(struct mtd_info *mtd) ++{ ++ struct ps3vram_priv *priv = mtd->priv; ++ ++ priv->ctrl[CTRL_PUT] = FIFO_BASE + FIFO_OFFSET; ++ priv->ctrl[CTRL_GET] = FIFO_BASE + FIFO_OFFSET; ++} ++ ++static int ps3vram_wait_ring(struct mtd_info *mtd, unsigned int timeout_ms) ++{ ++ struct ps3vram_priv *priv = mtd->priv; ++ unsigned long timeout = jiffies + msecs_to_jiffies(timeout_ms); ++ ++ do { ++ if (priv->ctrl[CTRL_PUT] == priv->ctrl[CTRL_GET]) ++ return 0; ++ msleep(1); ++ } while (time_before(jiffies, timeout)); ++ ++ dev_dbg(priv->dev, "%s:%d: FIFO timeout (%08x/%08x/%08x)\n", __func__, ++ __LINE__, priv->ctrl[CTRL_PUT], priv->ctrl[CTRL_GET], ++ priv->ctrl[CTRL_TOP]); ++ ++ return -ETIMEDOUT; ++} ++ ++static void ps3vram_out_ring(struct ps3vram_priv *priv, u32 data) ++{ ++ *(priv->fifo_ptr)++ = data; ++} ++ ++static void ps3vram_begin_ring(struct ps3vram_priv *priv, u32 chan, ++ u32 tag, u32 size) ++{ ++ ps3vram_out_ring(priv, (size << 18) | (chan << 13) | tag); ++} ++ ++static void ps3vram_rewind_ring(struct mtd_info *mtd) ++{ ++ struct ps3vram_priv *priv = mtd->priv; ++ u64 status; ++ ++ ps3vram_out_ring(priv, 0x20000000 | (FIFO_BASE + FIFO_OFFSET)); ++ ++ priv->ctrl[CTRL_PUT] = FIFO_BASE + FIFO_OFFSET; ++ ++ /* asking the HV for a blit will kick the fifo */ ++ status = lv1_gpu_context_attribute(priv->context_handle, ++ L1GPU_CONTEXT_ATTRIBUTE_FB_BLIT, ++ 0, 0, 0, 0); ++ if (status) ++ dev_err(priv->dev, "%s:%d: lv1_gpu_context_attribute failed\n", ++ __func__, __LINE__); ++ ++ priv->fifo_ptr = priv->fifo_base; ++} ++ ++static void ps3vram_fire_ring(struct mtd_info *mtd) ++{ ++ struct ps3vram_priv *priv = mtd->priv; ++ u64 status; ++ ++ mutex_lock(&ps3_gpu_mutex); ++ ++ priv->ctrl[CTRL_PUT] = FIFO_BASE + FIFO_OFFSET + ++ (priv->fifo_ptr - priv->fifo_base) * sizeof(u32); ++ ++ /* asking the HV for a blit will kick the fifo */ ++ status = lv1_gpu_context_attribute(priv->context_handle, ++ L1GPU_CONTEXT_ATTRIBUTE_FB_BLIT, ++ 0, 0, 0, 0); ++ if (status) ++ dev_err(priv->dev, "%s:%d: lv1_gpu_context_attribute failed\n", ++ __func__, __LINE__); ++ ++ if ((priv->fifo_ptr - priv->fifo_base) * sizeof(u32) > ++ FIFO_SIZE - 1024) { ++ dev_dbg(priv->dev, "%s:%d: fifo full, rewinding\n", __func__, ++ __LINE__); ++ ps3vram_wait_ring(mtd, 200); ++ ps3vram_rewind_ring(mtd); ++ } ++ ++ mutex_unlock(&ps3_gpu_mutex); ++} ++ ++static void ps3vram_bind(struct mtd_info *mtd) ++{ ++ struct ps3vram_priv *priv = mtd->priv; ++ ++ ps3vram_begin_ring(priv, UPLOAD_SUBCH, 0, 1); ++ ps3vram_out_ring(priv, 0x31337303); ++ ps3vram_begin_ring(priv, UPLOAD_SUBCH, 0x180, 3); ++ ps3vram_out_ring(priv, DMA_NOTIFIER_HANDLE_BASE + NOTIFIER); ++ ps3vram_out_ring(priv, 0xfeed0001); /* DMA system RAM instance */ ++ ps3vram_out_ring(priv, 0xfeed0000); /* DMA video RAM instance */ ++ ++ ps3vram_begin_ring(priv, DOWNLOAD_SUBCH, 0, 1); ++ ps3vram_out_ring(priv, 0x3137c0de); ++ ps3vram_begin_ring(priv, DOWNLOAD_SUBCH, 0x180, 3); ++ ps3vram_out_ring(priv, DMA_NOTIFIER_HANDLE_BASE + NOTIFIER); ++ ps3vram_out_ring(priv, 0xfeed0000); /* DMA video RAM instance */ ++ ps3vram_out_ring(priv, 0xfeed0001); /* DMA system RAM instance */ ++ ++ ps3vram_fire_ring(mtd); ++} ++ ++static int ps3vram_upload(struct mtd_info *mtd, unsigned int src_offset, ++ unsigned int dst_offset, int len, int count) ++{ ++ struct ps3vram_priv *priv = mtd->priv; ++ ++ ps3vram_begin_ring(priv, UPLOAD_SUBCH, ++ NV_MEMORY_TO_MEMORY_FORMAT_OFFSET_IN, 8); ++ ps3vram_out_ring(priv, XDR_IOIF + src_offset); ++ ps3vram_out_ring(priv, dst_offset); ++ ps3vram_out_ring(priv, len); ++ ps3vram_out_ring(priv, len); ++ ps3vram_out_ring(priv, len); ++ ps3vram_out_ring(priv, count); ++ ps3vram_out_ring(priv, (1 << 8) | 1); ++ ps3vram_out_ring(priv, 0); ++ ++ ps3vram_notifier_reset(mtd); ++ ps3vram_begin_ring(priv, UPLOAD_SUBCH, ++ NV_MEMORY_TO_MEMORY_FORMAT_NOTIFY, 1); ++ ps3vram_out_ring(priv, 0); ++ ps3vram_begin_ring(priv, UPLOAD_SUBCH, 0x100, 1); ++ ps3vram_out_ring(priv, 0); ++ ps3vram_fire_ring(mtd); ++ if (ps3vram_notifier_wait(mtd, 200) < 0) { ++ dev_dbg(priv->dev, "%s:%d: notifier timeout\n", __func__, ++ __LINE__); ++ return -1; ++ } ++ ++ return 0; ++} ++ ++static int ps3vram_download(struct mtd_info *mtd, unsigned int src_offset, ++ unsigned int dst_offset, int len, int count) ++{ ++ struct ps3vram_priv *priv = mtd->priv; ++ ++ ps3vram_begin_ring(priv, DOWNLOAD_SUBCH, ++ NV_MEMORY_TO_MEMORY_FORMAT_OFFSET_IN, 8); ++ ps3vram_out_ring(priv, src_offset); ++ ps3vram_out_ring(priv, XDR_IOIF + dst_offset); ++ ps3vram_out_ring(priv, len); ++ ps3vram_out_ring(priv, len); ++ ps3vram_out_ring(priv, len); ++ ps3vram_out_ring(priv, count); ++ ps3vram_out_ring(priv, (1 << 8) | 1); ++ ps3vram_out_ring(priv, 0); ++ ++ ps3vram_notifier_reset(mtd); ++ ps3vram_begin_ring(priv, DOWNLOAD_SUBCH, ++ NV_MEMORY_TO_MEMORY_FORMAT_NOTIFY, 1); ++ ps3vram_out_ring(priv, 0); ++ ps3vram_begin_ring(priv, DOWNLOAD_SUBCH, 0x100, 1); ++ ps3vram_out_ring(priv, 0); ++ ps3vram_fire_ring(mtd); ++ if (ps3vram_notifier_wait(mtd, 200) < 0) { ++ dev_dbg(priv->dev, "%s:%d: notifier timeout\n", __func__, ++ __LINE__); ++ return -1; ++ } ++ ++ return 0; ++} ++ ++static void ps3vram_cache_evict(struct mtd_info *mtd, int entry) ++{ ++ struct ps3vram_priv *priv = mtd->priv; ++ struct ps3vram_cache *cache = &priv->cache; ++ ++ if (cache->tags[entry].flags & CACHE_PAGE_DIRTY) { ++ dev_dbg(priv->dev, "%s:%d: flushing %d : 0x%08x\n", __func__, ++ __LINE__, entry, cache->tags[entry].address); ++ if (ps3vram_upload(mtd, ++ CACHE_OFFSET + entry * cache->page_size, ++ cache->tags[entry].address, ++ DMA_PAGE_SIZE, ++ cache->page_size / DMA_PAGE_SIZE) < 0) { ++ dev_dbg(priv->dev, "%s:%d: failed to upload from " ++ "0x%x to 0x%x size 0x%x\n", __func__, __LINE__, ++ entry * cache->page_size, ++ cache->tags[entry].address, cache->page_size); ++ } ++ cache->tags[entry].flags &= ~CACHE_PAGE_DIRTY; ++ } ++} ++ ++static void ps3vram_cache_load(struct mtd_info *mtd, int entry, ++ unsigned int address) ++{ ++ struct ps3vram_priv *priv = mtd->priv; ++ struct ps3vram_cache *cache = &priv->cache; ++ ++ dev_dbg(priv->dev, "%s:%d: fetching %d : 0x%08x\n", __func__, __LINE__, ++ entry, address); ++ if (ps3vram_download(mtd, ++ address, ++ CACHE_OFFSET + entry * cache->page_size, ++ DMA_PAGE_SIZE, ++ cache->page_size / DMA_PAGE_SIZE) < 0) { ++ dev_err(priv->dev, "%s:%d: failed to download from " ++ "0x%x to 0x%x size 0x%x\n", __func__, __LINE__, address, ++ entry * cache->page_size, cache->page_size); ++ } ++ ++ cache->tags[entry].address = address; ++ cache->tags[entry].flags |= CACHE_PAGE_PRESENT; ++} ++ ++ ++static void ps3vram_cache_flush(struct mtd_info *mtd) ++{ ++ struct ps3vram_priv *priv = mtd->priv; ++ struct ps3vram_cache *cache = &priv->cache; ++ int i; ++ ++ dev_dbg(priv->dev, "%s:%d: FLUSH\n", __func__, __LINE__); ++ for (i = 0; i < cache->page_count; i++) { ++ ps3vram_cache_evict(mtd, i); ++ cache->tags[i].flags = 0; ++ } ++} ++ ++static unsigned int ps3vram_cache_match(struct mtd_info *mtd, loff_t address) ++{ ++ struct ps3vram_priv *priv = mtd->priv; ++ struct ps3vram_cache *cache = &priv->cache; ++ unsigned int base; ++ unsigned int offset; ++ int i; ++ static int counter; ++ ++ offset = (unsigned int) (address & (cache->page_size - 1)); ++ base = (unsigned int) (address - offset); ++ ++ /* fully associative check */ ++ for (i = 0; i < cache->page_count; i++) { ++ if ((cache->tags[i].flags & CACHE_PAGE_PRESENT) && ++ cache->tags[i].address == base) { ++ dev_dbg(priv->dev, "%s:%d: found entry %d : 0x%08x\n", ++ __func__, __LINE__, i, cache->tags[i].address); ++ return i; ++ } ++ } ++ ++ /* choose a random entry */ ++ i = (jiffies + (counter++)) % cache->page_count; ++ dev_dbg(priv->dev, "%s:%d: using entry %d\n", __func__, __LINE__, i); ++ ++ ps3vram_cache_evict(mtd, i); ++ ps3vram_cache_load(mtd, i, base); ++ ++ return i; ++} ++ ++static int ps3vram_cache_init(struct mtd_info *mtd) ++{ ++ struct ps3vram_priv *priv = mtd->priv; ++ ++ priv->cache.page_count = CACHE_PAGE_COUNT; ++ priv->cache.page_size = CACHE_PAGE_SIZE; ++ priv->cache.tags = kzalloc(sizeof(struct ps3vram_tag) * ++ CACHE_PAGE_COUNT, GFP_KERNEL); ++ if (priv->cache.tags == NULL) { ++ dev_err(priv->dev, "%s:%d: could not allocate cache tags\n", ++ __func__, __LINE__); ++ return -ENOMEM; ++ } ++ ++ dev_info(priv->dev, "created ram cache: %d entries, %d KiB each\n", ++ CACHE_PAGE_COUNT, CACHE_PAGE_SIZE / 1024); ++ ++ return 0; ++} ++ ++static void ps3vram_cache_cleanup(struct mtd_info *mtd) ++{ ++ struct ps3vram_priv *priv = mtd->priv; ++ ++ ps3vram_cache_flush(mtd); ++ kfree(priv->cache.tags); ++} ++ ++static int ps3vram_erase(struct mtd_info *mtd, struct erase_info *instr) ++{ ++ struct ps3vram_priv *priv = mtd->priv; ++ ++ if (instr->addr + instr->len > mtd->size) ++ return -EINVAL; ++ ++ mutex_lock(&priv->lock); ++ ++ ps3vram_cache_flush(mtd); ++ ++ /* Set bytes to 0xFF */ ++ memset_io(priv->ddr_base + instr->addr, 0xFF, instr->len); ++ ++ mutex_unlock(&priv->lock); ++ ++ instr->state = MTD_ERASE_DONE; ++ mtd_erase_callback(instr); ++ ++ return 0; ++} ++ ++static int ps3vram_read(struct mtd_info *mtd, loff_t from, size_t len, ++ size_t *retlen, u_char *buf) ++{ ++ struct ps3vram_priv *priv = mtd->priv; ++ unsigned int cached, count; ++ ++ dev_dbg(priv->dev, "%s:%d: from=0x%08x len=0x%zx\n", __func__, __LINE__, ++ (unsigned int)from, len); ++ ++ if (from >= mtd->size) ++ return -EINVAL; ++ ++ if (len > mtd->size - from) ++ len = mtd->size - from; ++ ++ /* Copy from vram to buf */ ++ count = len; ++ while (count) { ++ unsigned int offset, avail; ++ unsigned int entry; ++ ++ offset = (unsigned int) (from & (priv->cache.page_size - 1)); ++ avail = priv->cache.page_size - offset; ++ ++ mutex_lock(&priv->lock); ++ ++ entry = ps3vram_cache_match(mtd, from); ++ cached = CACHE_OFFSET + entry * priv->cache.page_size + offset; ++ ++ dev_dbg(priv->dev, "%s:%d: from=%08x cached=%08x offset=%08x " ++ "avail=%08x count=%08x\n", __func__, __LINE__, ++ (unsigned int)from, cached, offset, avail, count); ++ ++ if (avail > count) ++ avail = count; ++ memcpy(buf, priv->xdr_buf + cached, avail); ++ ++ mutex_unlock(&priv->lock); ++ ++ buf += avail; ++ count -= avail; ++ from += avail; ++ } ++ ++ *retlen = len; ++ return 0; ++} ++ ++static int ps3vram_write(struct mtd_info *mtd, loff_t to, size_t len, ++ size_t *retlen, const u_char *buf) ++{ ++ struct ps3vram_priv *priv = mtd->priv; ++ unsigned int cached, count; ++ ++ if (to >= mtd->size) ++ return -EINVAL; ++ ++ if (len > mtd->size - to) ++ len = mtd->size - to; ++ ++ /* Copy from buf to vram */ ++ count = len; ++ while (count) { ++ unsigned int offset, avail; ++ unsigned int entry; ++ ++ offset = (unsigned int) (to & (priv->cache.page_size - 1)); ++ avail = priv->cache.page_size - offset; ++ ++ mutex_lock(&priv->lock); ++ ++ entry = ps3vram_cache_match(mtd, to); ++ cached = CACHE_OFFSET + entry * priv->cache.page_size + offset; ++ ++ dev_dbg(priv->dev, "%s:%d: to=%08x cached=%08x offset=%08x " ++ "avail=%08x count=%08x\n", __func__, __LINE__, ++ (unsigned int)to, cached, offset, avail, count); ++ ++ if (avail > count) ++ avail = count; ++ memcpy(priv->xdr_buf + cached, buf, avail); ++ ++ priv->cache.tags[entry].flags |= CACHE_PAGE_DIRTY; ++ ++ mutex_unlock(&priv->lock); ++ ++ buf += avail; ++ count -= avail; ++ to += avail; ++ } ++ ++ *retlen = len; ++ return 0; ++} ++ ++static int __devinit ps3vram_probe(struct ps3_system_bus_device *dev) ++{ ++ struct ps3vram_priv *priv; ++ int status; ++ u64 ddr_lpar; ++ u64 ctrl_lpar; ++ u64 info_lpar; ++ u64 reports_lpar; ++ u64 ddr_size; ++ u64 reports_size; ++ int ret = -ENOMEM; ++ char *rest; ++ ++ ret = -EIO; ++ ps3vram_mtd.priv = kzalloc(sizeof(struct ps3vram_priv), GFP_KERNEL); ++ if (!ps3vram_mtd.priv) ++ goto out; ++ priv = ps3vram_mtd.priv; ++ ++ mutex_init(&priv->lock); ++ priv->dev = &dev->core; ++ ++ /* Allocate XDR buffer (1MiB aligned) */ ++ priv->xdr_buf = (void *)__get_free_pages(GFP_KERNEL, ++ get_order(XDR_BUF_SIZE)); ++ if (priv->xdr_buf == NULL) { ++ dev_dbg(&dev->core, "%s:%d: could not allocate XDR buffer\n", ++ __func__, __LINE__); ++ ret = -ENOMEM; ++ goto out_free_priv; ++ } ++ ++ /* Put FIFO at begginning of XDR buffer */ ++ priv->fifo_base = (u32 *) (priv->xdr_buf + FIFO_OFFSET); ++ priv->fifo_ptr = priv->fifo_base; ++ ++ /* XXX: Need to open GPU, in case ps3fb or snd_ps3 aren't loaded */ ++ if (ps3_open_hv_device(dev)) { ++ dev_err(&dev->core, "%s:%d: ps3_open_hv_device failed\n", ++ __func__, __LINE__); ++ ret = -EAGAIN; ++ goto out_close_gpu; ++ } ++ ++ /* Request memory */ ++ status = -1; ++ ddr_size = memparse(size, &rest); ++ if (*rest == '-') ++ ddr_size -= ps3fb_videomemory.size; ++ ddr_size = ALIGN(ddr_size, 1024*1024); ++ if (ddr_size <= 0) { ++ dev_err(&dev->core, "%s:%d: specified size is too small\n", ++ __func__, __LINE__); ++ ret = -EINVAL; ++ goto out_close_gpu; ++ } ++ ++ while (ddr_size > 0) { ++ status = lv1_gpu_memory_allocate(ddr_size, 0, 0, 0, 0, ++ &priv->memory_handle, ++ &ddr_lpar); ++ if (!status) ++ break; ++ ddr_size -= 1024*1024; ++ } ++ if (status || ddr_size <= 0) { ++ dev_err(&dev->core, "%s:%d: lv1_gpu_memory_allocate failed\n", ++ __func__, __LINE__); ++ ret = -ENOMEM; ++ goto out_free_xdr_buf; ++ } ++ ++ /* Request context */ ++ status = lv1_gpu_context_allocate(priv->memory_handle, ++ 0, ++ &priv->context_handle, ++ &ctrl_lpar, ++ &info_lpar, ++ &reports_lpar, ++ &reports_size); ++ if (status) { ++ dev_err(&dev->core, "%s:%d: lv1_gpu_context_allocate failed\n", ++ __func__, __LINE__); ++ ret = -ENOMEM; ++ goto out_free_memory; ++ } ++ ++ /* Map XDR buffer to RSX */ ++ status = lv1_gpu_context_iomap(priv->context_handle, XDR_IOIF, ++ ps3_mm_phys_to_lpar(__pa(priv->xdr_buf)), ++ XDR_BUF_SIZE, 0); ++ if (status) { ++ dev_err(&dev->core, "%s:%d: lv1_gpu_context_iomap failed\n", ++ __func__, __LINE__); ++ ret = -ENOMEM; ++ goto out_free_context; ++ } ++ ++ priv->ddr_base = ioremap_flags(ddr_lpar, ddr_size, _PAGE_NO_CACHE); ++ ++ if (!priv->ddr_base) { ++ dev_err(&dev->core, "%s:%d: ioremap failed\n", __func__, ++ __LINE__); ++ ret = -ENOMEM; ++ goto out_free_context; ++ } ++ ++ priv->ctrl = ioremap(ctrl_lpar, 64 * 1024); ++ if (!priv->ctrl) { ++ dev_err(&dev->core, "%s:%d: ioremap failed\n", __func__, ++ __LINE__); ++ ret = -ENOMEM; ++ goto out_unmap_vram; ++ } ++ ++ priv->reports = ioremap(reports_lpar, reports_size); ++ if (!priv->reports) { ++ dev_err(&dev->core, "%s:%d: ioremap failed\n", __func__, ++ __LINE__); ++ ret = -ENOMEM; ++ goto out_unmap_ctrl; ++ } ++ ++ mutex_lock(&ps3_gpu_mutex); ++ ps3vram_init_ring(&ps3vram_mtd); ++ mutex_unlock(&ps3_gpu_mutex); ++ ++ ps3vram_mtd.name = "ps3vram"; ++ ps3vram_mtd.size = ddr_size; ++ ps3vram_mtd.flags = MTD_CAP_RAM; ++ ps3vram_mtd.erase = ps3vram_erase; ++ ps3vram_mtd.point = NULL; ++ ps3vram_mtd.unpoint = NULL; ++ ps3vram_mtd.read = ps3vram_read; ++ ps3vram_mtd.write = ps3vram_write; ++ ps3vram_mtd.owner = THIS_MODULE; ++ ps3vram_mtd.type = MTD_RAM; ++ ps3vram_mtd.erasesize = CACHE_PAGE_SIZE; ++ ps3vram_mtd.writesize = 1; ++ ++ ps3vram_bind(&ps3vram_mtd); ++ ++ mutex_lock(&ps3_gpu_mutex); ++ ret = ps3vram_wait_ring(&ps3vram_mtd, 100); ++ mutex_unlock(&ps3_gpu_mutex); ++ if (ret < 0) { ++ dev_err(&dev->core, "%s:%d: failed to initialize channels\n", ++ __func__, __LINE__); ++ ret = -ETIMEDOUT; ++ goto out_unmap_reports; ++ } ++ ++ ps3vram_cache_init(&ps3vram_mtd); ++ ++ if (add_mtd_device(&ps3vram_mtd)) { ++ dev_err(&dev->core, "%s:%d: add_mtd_device failed\n", ++ __func__, __LINE__); ++ ret = -EAGAIN; ++ goto out_cache_cleanup; ++ } ++ ++ dev_info(&dev->core, "reserved %u MiB of gpu memory\n", ++ (unsigned int)(ddr_size / 1024 / 1024)); ++ ++ return 0; ++ ++out_cache_cleanup: ++ ps3vram_cache_cleanup(&ps3vram_mtd); ++out_unmap_reports: ++ iounmap(priv->reports); ++out_unmap_ctrl: ++ iounmap(priv->ctrl); ++out_unmap_vram: ++ iounmap(priv->ddr_base); ++out_free_context: ++ lv1_gpu_context_free(priv->context_handle); ++out_free_memory: ++ lv1_gpu_memory_free(priv->memory_handle); ++out_close_gpu: ++ ps3_close_hv_device(dev); ++out_free_xdr_buf: ++ free_pages((unsigned long) priv->xdr_buf, get_order(XDR_BUF_SIZE)); ++out_free_priv: ++ kfree(ps3vram_mtd.priv); ++ ps3vram_mtd.priv = NULL; ++out: ++ return ret; ++} ++ ++static int ps3vram_shutdown(struct ps3_system_bus_device *dev) ++{ ++ struct ps3vram_priv *priv; ++ ++ priv = ps3vram_mtd.priv; ++ ++ del_mtd_device(&ps3vram_mtd); ++ ps3vram_cache_cleanup(&ps3vram_mtd); ++ iounmap(priv->reports); ++ iounmap(priv->ctrl); ++ iounmap(priv->ddr_base); ++ lv1_gpu_context_free(priv->context_handle); ++ lv1_gpu_memory_free(priv->memory_handle); ++ ps3_close_hv_device(dev); ++ free_pages((unsigned long) priv->xdr_buf, get_order(XDR_BUF_SIZE)); ++ kfree(priv); ++ return 0; ++} ++ ++static struct ps3_system_bus_driver ps3vram_driver = { ++ .match_id = PS3_MATCH_ID_GPU, ++ .match_sub_id = PS3_MATCH_SUB_ID_GPU_RAMDISK, ++ .core.name = DEVICE_NAME, ++ .core.owner = THIS_MODULE, ++ .probe = ps3vram_probe, ++ .remove = ps3vram_shutdown, ++ .shutdown = ps3vram_shutdown, ++}; ++ ++static int __init ps3vram_init(void) ++{ ++ return ps3_system_bus_driver_register(&ps3vram_driver); ++} ++ ++static void __exit ps3vram_exit(void) ++{ ++ ps3_system_bus_driver_unregister(&ps3vram_driver); ++} ++ ++module_init(ps3vram_init); ++module_exit(ps3vram_exit); ++ ++MODULE_LICENSE("GPL"); ++MODULE_AUTHOR("Jim Paris <jim@jtan.com>"); ++MODULE_DESCRIPTION("MTD driver for PS3 video RAM"); ++MODULE_ALIAS(PS3_MODULE_ALIAS_GPU_RAMDISK); +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/drivers/mtd/devices/slram.c linux-2.6.29-rc3.owrt/drivers/mtd/devices/slram.c +--- linux-2.6.29.owrt/drivers/mtd/devices/slram.c 2009-05-10 22:04:39.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/drivers/mtd/devices/slram.c 2009-05-10 23:48:28.000000000 +0200 +@@ -267,28 +267,22 @@ + if (*(szlength) != '+') { + devlength = simple_strtoul(szlength, &buffer, 0); + devlength = handle_unit(devlength, buffer) - devstart; +- if (devlength < devstart) +- goto err_out; +- +- devlength -= devstart; + } else { + devlength = simple_strtoul(szlength + 1, &buffer, 0); + devlength = handle_unit(devlength, buffer); + } + T("slram: devname=%s, devstart=0x%lx, devlength=0x%lx\n", + devname, devstart, devlength); +- if (devlength % SLRAM_BLK_SZ != 0) +- goto err_out; ++ if ((devstart < 0) || (devlength < 0) || (devlength % SLRAM_BLK_SZ != 0)) { ++ E("slram: Illegal start / length parameter.\n"); ++ return(-EINVAL); ++ } + + if ((devstart = register_device(devname, devstart, devlength))){ + unregister_devices(); + return((int)devstart); + } + return(0); +- +-err_out: +- E("slram: Illegal length parameter.\n"); +- return(-EINVAL); + } + + #ifndef MODULE +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/drivers/mtd/lpddr/Kconfig linux-2.6.29-rc3.owrt/drivers/mtd/lpddr/Kconfig +--- linux-2.6.29.owrt/drivers/mtd/lpddr/Kconfig 2009-05-10 22:04:39.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/drivers/mtd/lpddr/Kconfig 2009-05-10 23:48:28.000000000 +0200 +@@ -12,7 +12,6 @@ + DDR memories, intended for battery-operated systems. + + config MTD_QINFO_PROBE +- depends on MTD_LPDDR + tristate "Detect flash chips by QINFO probe" + help + Device Information for LPDDR chips is offered through the Overlay +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/drivers/mtd/maps/bfin-async-flash.c linux-2.6.29-rc3.owrt/drivers/mtd/maps/bfin-async-flash.c +--- linux-2.6.29.owrt/drivers/mtd/maps/bfin-async-flash.c 2009-05-10 22:04:39.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/drivers/mtd/maps/bfin-async-flash.c 2009-05-10 23:48:28.000000000 +0200 +@@ -152,18 +152,14 @@ + + if (gpio_request(state->enet_flash_pin, DRIVER_NAME)) { + pr_devinit(KERN_ERR DRIVER_NAME ": Failed to request gpio %d\n", state->enet_flash_pin); +- kfree(state); + return -EBUSY; + } + gpio_direction_output(state->enet_flash_pin, 1); + + pr_devinit(KERN_NOTICE DRIVER_NAME ": probing %d-bit flash bus\n", state->map.bankwidth * 8); + state->mtd = do_map_probe(memory->name, &state->map); +- if (!state->mtd) { +- gpio_free(state->enet_flash_pin); +- kfree(state); ++ if (!state->mtd) + return -ENXIO; +- } + + #ifdef CONFIG_MTD_PARTITIONS + ret = parse_mtd_partitions(state->mtd, part_probe_types, &pdata->parts, 0); +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/drivers/mtd/maps/ck804xrom.c linux-2.6.29-rc3.owrt/drivers/mtd/maps/ck804xrom.c +--- linux-2.6.29.owrt/drivers/mtd/maps/ck804xrom.c 2009-05-10 22:04:39.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/drivers/mtd/maps/ck804xrom.c 2009-05-10 23:48:28.000000000 +0200 +@@ -342,9 +342,9 @@ + { 0, } + }; + +-#if 0 + MODULE_DEVICE_TABLE(pci, ck804xrom_pci_tbl); + ++#if 0 + static struct pci_driver ck804xrom_driver = { + .name = MOD_NAME, + .id_table = ck804xrom_pci_tbl, +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/drivers/mtd/maps/Kconfig linux-2.6.29-rc3.owrt/drivers/mtd/maps/Kconfig +--- linux-2.6.29.owrt/drivers/mtd/maps/Kconfig 2009-05-10 22:04:39.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/drivers/mtd/maps/Kconfig 2009-05-10 23:48:28.000000000 +0200 +@@ -491,7 +491,7 @@ + + config MTD_BFIN_ASYNC + tristate "Blackfin BF533-STAMP Flash Chip Support" +- depends on BFIN533_STAMP && MTD_CFI && MTD_COMPLEX_MAPPINGS ++ depends on BFIN533_STAMP && MTD_CFI + select MTD_PARTITIONS + default y + help +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/drivers/mtd/maps/physmap.c linux-2.6.29-rc3.owrt/drivers/mtd/maps/physmap.c +--- linux-2.6.29.owrt/drivers/mtd/maps/physmap.c 2009-05-10 22:04:39.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/drivers/mtd/maps/physmap.c 2009-05-10 23:48:28.000000000 +0200 +@@ -29,7 +29,6 @@ + struct map_info map[MAX_RESOURCES]; + #ifdef CONFIG_MTD_PARTITIONS + int nr_parts; +- struct mtd_partition *parts; + #endif + }; + +@@ -46,29 +45,25 @@ + + physmap_data = dev->dev.platform_data; + +- if (info->cmtd) { +-#ifdef CONFIG_MTD_PARTITIONS +- if (info->nr_parts || physmap_data->nr_parts) +- del_mtd_partitions(info->cmtd); +- else +- del_mtd_device(info->cmtd); +-#else +- del_mtd_device(info->cmtd); +-#endif +- } +-#ifdef CONFIG_MTD_PARTITIONS +- if (info->nr_parts) +- kfree(info->parts); +-#endif +- + #ifdef CONFIG_MTD_CONCAT +- if (info->cmtd != info->mtd[0]) ++ if (info->cmtd != info->mtd[0]) { ++ del_mtd_device(info->cmtd); + mtd_concat_destroy(info->cmtd); ++ } + #endif + + for (i = 0; i < MAX_RESOURCES; i++) { +- if (info->mtd[i] != NULL) ++ if (info->mtd[i] != NULL) { ++#ifdef CONFIG_MTD_PARTITIONS ++ if (info->nr_parts || physmap_data->nr_parts) ++ del_mtd_partitions(info->mtd[i]); ++ else ++ del_mtd_device(info->mtd[i]); ++#else ++ del_mtd_device(info->mtd[i]); ++#endif + map_destroy(info->mtd[i]); ++ } + } + return 0; + } +@@ -91,6 +86,9 @@ + int err = 0; + int i; + int devices_found = 0; ++#ifdef CONFIG_MTD_PARTITIONS ++ struct mtd_partition *parts; ++#endif + + physmap_data = dev->dev.platform_data; + if (physmap_data == NULL) +@@ -169,11 +167,10 @@ + goto err_out; + + #ifdef CONFIG_MTD_PARTITIONS +- err = parse_mtd_partitions(info->cmtd, part_probe_types, +- &info->parts, 0); ++ err = parse_mtd_partitions(info->cmtd, part_probe_types, &parts, 0); + if (err > 0) { +- add_mtd_partitions(info->cmtd, info->parts, err); +- info->nr_parts = err; ++ add_mtd_partitions(info->cmtd, parts, err); ++ kfree(parts); + return 0; + } + +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/drivers/mtd/maps/sa1100-flash.c linux-2.6.29-rc3.owrt/drivers/mtd/maps/sa1100-flash.c +--- linux-2.6.29.owrt/drivers/mtd/maps/sa1100-flash.c 2009-05-10 22:04:39.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/drivers/mtd/maps/sa1100-flash.c 2009-05-10 23:48:28.000000000 +0200 +@@ -453,7 +453,7 @@ + .resume = sa1100_mtd_resume, + .shutdown = sa1100_mtd_shutdown, + .driver = { +- .name = "sa1100-mtd", ++ .name = "flash", + .owner = THIS_MODULE, + }, + }; +@@ -474,4 +474,4 @@ + MODULE_AUTHOR("Nicolas Pitre"); + MODULE_DESCRIPTION("SA1100 CFI map driver"); + MODULE_LICENSE("GPL"); +-MODULE_ALIAS("platform:sa1100-mtd"); ++MODULE_ALIAS("platform:flash"); +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/drivers/mtd/nand/atmel_nand.c linux-2.6.29-rc3.owrt/drivers/mtd/nand/atmel_nand.c +--- linux-2.6.29.owrt/drivers/mtd/nand/atmel_nand.c 2009-05-10 22:04:39.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/drivers/mtd/nand/atmel_nand.c 2009-05-10 23:48:28.000000000 +0200 +@@ -139,8 +139,7 @@ + struct nand_chip *nand_chip = mtd->priv; + struct atmel_nand_host *host = nand_chip->priv; + +- return gpio_get_value(host->board->rdy_pin) ^ +- !!host->board->rdy_pin_active_low; ++ return gpio_get_value(host->board->rdy_pin); + } + + /* +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/drivers/mtd/nand/orion_nand.c linux-2.6.29-rc3.owrt/drivers/mtd/nand/orion_nand.c +--- linux-2.6.29.owrt/drivers/mtd/nand/orion_nand.c 2009-05-10 22:04:39.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/drivers/mtd/nand/orion_nand.c 2009-05-10 23:48:28.000000000 +0200 +@@ -149,7 +149,7 @@ + + static struct platform_driver orion_nand_driver = { + .probe = orion_nand_probe, +- .remove = __devexit_p(orion_nand_remove), ++ .remove = orion_nand_remove, + .driver = { + .name = "orion_nand", + .owner = THIS_MODULE, +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/drivers/mtd/ubi/build.c linux-2.6.29-rc3.owrt/drivers/mtd/ubi/build.c +--- linux-2.6.29.owrt/drivers/mtd/ubi/build.c 2009-05-10 22:04:39.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/drivers/mtd/ubi/build.c 2009-05-10 23:48:28.000000000 +0200 +@@ -263,12 +263,8 @@ + return ret; + } + +-static void dev_release(struct device *dev) +-{ +- struct ubi_device *ubi = container_of(dev, struct ubi_device, dev); +- +- kfree(ubi); +-} ++/* Fake "release" method for UBI devices */ ++static void dev_release(struct device *dev) { } + + /** + * ubi_sysfs_init - initialize sysfs for an UBI device. +@@ -384,7 +380,7 @@ + */ + static int uif_init(struct ubi_device *ubi) + { +- int i, err; ++ int i, err, do_free = 0; + dev_t dev; + + sprintf(ubi->ubi_name, UBI_NAME_STR "%d", ubi->ubi_num); +@@ -431,10 +427,13 @@ + + out_volumes: + kill_volumes(ubi); ++ do_free = 0; + out_sysfs: + ubi_sysfs_close(ubi); + cdev_del(&ubi->cdev); + out_unreg: ++ if (do_free) ++ free_user_volumes(ubi); + unregister_chrdev_region(ubi->cdev.dev, ubi->vtbl_slots + 1); + ubi_err("cannot initialize UBI %s, error %d", ubi->ubi_name, err); + return err; +@@ -948,12 +947,6 @@ + if (ubi->bgt_thread) + kthread_stop(ubi->bgt_thread); + +- /* +- * Get a reference to the device in order to prevent 'dev_release()' +- * from freeing @ubi object. +- */ +- get_device(&ubi->dev); +- + uif_close(ubi); + ubi_wl_close(ubi); + free_internal_volumes(ubi); +@@ -965,7 +958,7 @@ + vfree(ubi->dbg_peb_buf); + #endif + ubi_msg("mtd%d is detached from ubi%d", ubi->mtd->index, ubi->ubi_num); +- put_device(&ubi->dev); ++ kfree(ubi); + return 0; + } + +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/drivers/mtd/ubi/cdev.c linux-2.6.29-rc3.owrt/drivers/mtd/ubi/cdev.c +--- linux-2.6.29.owrt/drivers/mtd/ubi/cdev.c 2009-05-10 22:04:39.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/drivers/mtd/ubi/cdev.c 2009-05-10 23:48:28.000000000 +0200 +@@ -40,9 +40,9 @@ + #include <linux/ioctl.h> + #include <linux/capability.h> + #include <linux/uaccess.h> +-#include <linux/compat.h> +-#include <linux/math64.h> ++#include <linux/smp_lock.h> + #include <mtd/ubi-user.h> ++#include <asm/div64.h> + #include "ubi.h" + + /** +@@ -195,6 +195,7 @@ + int err, lnum, off, len, tbuf_size; + size_t count_save = count; + void *tbuf; ++ uint64_t tmp; + + dbg_gen("read %zd bytes from offset %lld of volume %d", + count, *offp, vol->vol_id); +@@ -224,7 +225,10 @@ + return -ENOMEM; + + len = count > tbuf_size ? tbuf_size : count; +- lnum = div_u64_rem(*offp, vol->usable_leb_size, &off); ++ ++ tmp = *offp; ++ off = do_div(tmp, vol->usable_leb_size); ++ lnum = tmp; + + do { + cond_resched(); +@@ -259,9 +263,12 @@ + return err ? err : count_save - count; + } + ++#ifdef CONFIG_MTD_UBI_DEBUG_USERSPACE_IO ++ + /* + * This function allows to directly write to dynamic UBI volumes, without +- * issuing the volume update operation. ++ * issuing the volume update operation. Available only as a debugging feature. ++ * Very useful for testing UBI. + */ + static ssize_t vol_cdev_direct_write(struct file *file, const char __user *buf, + size_t count, loff_t *offp) +@@ -272,9 +279,7 @@ + int lnum, off, len, tbuf_size, err = 0; + size_t count_save = count; + char *tbuf; +- +- if (!vol->direct_writes) +- return -EPERM; ++ uint64_t tmp; + + dbg_gen("requested: write %zd bytes to offset %lld of volume %u", + count, *offp, vol->vol_id); +@@ -282,7 +287,10 @@ + if (vol->vol_type == UBI_STATIC_VOLUME) + return -EROFS; + +- lnum = div_u64_rem(*offp, vol->usable_leb_size, &off); ++ tmp = *offp; ++ off = do_div(tmp, vol->usable_leb_size); ++ lnum = tmp; ++ + if (off & (ubi->min_io_size - 1)) { + dbg_err("unaligned position"); + return -EINVAL; +@@ -339,6 +347,10 @@ + return err ? err : count_save - count; + } + ++#else ++#define vol_cdev_direct_write(file, buf, count, offp) (-EPERM) ++#endif /* CONFIG_MTD_UBI_DEBUG_USERSPACE_IO */ ++ + static ssize_t vol_cdev_write(struct file *file, const char __user *buf, + size_t count, loff_t *offp) + { +@@ -390,8 +402,8 @@ + return count; + } + +-static long vol_cdev_ioctl(struct file *file, unsigned int cmd, +- unsigned long arg) ++static int vol_cdev_ioctl(struct inode *inode, struct file *file, ++ unsigned int cmd, unsigned long arg) + { + int err = 0; + struct ubi_volume_desc *desc = file->private_data; +@@ -475,6 +487,7 @@ + break; + } + ++#ifdef CONFIG_MTD_UBI_DEBUG_USERSPACE_IO + /* Logical eraseblock erasure command */ + case UBI_IOCEBER: + { +@@ -505,77 +518,13 @@ + err = ubi_wl_flush(ubi); + break; + } +- +- /* Logical eraseblock map command */ +- case UBI_IOCEBMAP: +- { +- struct ubi_map_req req; +- +- err = copy_from_user(&req, argp, sizeof(struct ubi_map_req)); +- if (err) { +- err = -EFAULT; +- break; +- } +- err = ubi_leb_map(desc, req.lnum, req.dtype); +- break; +- } +- +- /* Logical eraseblock un-map command */ +- case UBI_IOCEBUNMAP: +- { +- int32_t lnum; +- +- err = get_user(lnum, (__user int32_t *)argp); +- if (err) { +- err = -EFAULT; +- break; +- } +- err = ubi_leb_unmap(desc, lnum); +- break; +- } +- +- /* Check if logical eraseblock is mapped command */ +- case UBI_IOCEBISMAP: +- { +- int32_t lnum; +- +- err = get_user(lnum, (__user int32_t *)argp); +- if (err) { +- err = -EFAULT; +- break; +- } +- err = ubi_is_mapped(desc, lnum); +- break; +- } +- +- /* Set volume property command*/ +- case UBI_IOCSETPROP: +- { +- struct ubi_set_prop_req req; +- +- err = copy_from_user(&req, argp, +- sizeof(struct ubi_set_prop_req)); +- if (err) { +- err = -EFAULT; +- break; +- } +- switch (req.property) { +- case UBI_PROP_DIRECT_WRITE: +- mutex_lock(&ubi->volumes_mutex); +- desc->vol->direct_writes = !!req.value; +- mutex_unlock(&ubi->volumes_mutex); +- break; +- default: +- err = -EINVAL; +- break; +- } +- break; +- } ++#endif + + default: + err = -ENOTTY; + break; + } ++ + return err; + } + +@@ -813,8 +762,8 @@ + return err; + } + +-static long ubi_cdev_ioctl(struct file *file, unsigned int cmd, +- unsigned long arg) ++static int ubi_cdev_ioctl(struct inode *inode, struct file *file, ++ unsigned int cmd, unsigned long arg) + { + int err = 0; + struct ubi_device *ubi; +@@ -824,7 +773,7 @@ + if (!capable(CAP_SYS_RESOURCE)) + return -EPERM; + +- ubi = ubi_get_by_major(imajor(file->f_mapping->host)); ++ ubi = ubi_get_by_major(imajor(inode)); + if (!ubi) + return -ENODEV; + +@@ -894,6 +843,7 @@ + case UBI_IOCRSVOL: + { + int pebs; ++ uint64_t tmp; + struct ubi_rsvol_req req; + + dbg_gen("re-size volume"); +@@ -913,8 +863,9 @@ + break; + } + +- pebs = div_u64(req.bytes + desc->vol->usable_leb_size - 1, +- desc->vol->usable_leb_size); ++ tmp = req.bytes; ++ pebs = !!do_div(tmp, desc->vol->usable_leb_size); ++ pebs += tmp; + + mutex_lock(&ubi->volumes_mutex); + err = ubi_resize_volume(desc, pebs); +@@ -958,8 +909,8 @@ + return err; + } + +-static long ctrl_cdev_ioctl(struct file *file, unsigned int cmd, +- unsigned long arg) ++static int ctrl_cdev_ioctl(struct inode *inode, struct file *file, ++ unsigned int cmd, unsigned long arg) + { + int err = 0; + void __user *argp = (void __user *)arg; +@@ -1035,59 +986,26 @@ + return err; + } + +-#ifdef CONFIG_COMPAT +-static long vol_cdev_compat_ioctl(struct file *file, unsigned int cmd, +- unsigned long arg) +-{ +- unsigned long translated_arg = (unsigned long)compat_ptr(arg); +- +- return vol_cdev_ioctl(file, cmd, translated_arg); +-} +- +-static long ubi_cdev_compat_ioctl(struct file *file, unsigned int cmd, +- unsigned long arg) +-{ +- unsigned long translated_arg = (unsigned long)compat_ptr(arg); +- +- return ubi_cdev_ioctl(file, cmd, translated_arg); +-} +- +-static long ctrl_cdev_compat_ioctl(struct file *file, unsigned int cmd, +- unsigned long arg) +-{ +- unsigned long translated_arg = (unsigned long)compat_ptr(arg); +- +- return ctrl_cdev_ioctl(file, cmd, translated_arg); +-} +-#else +-#define vol_cdev_compat_ioctl NULL +-#define ubi_cdev_compat_ioctl NULL +-#define ctrl_cdev_compat_ioctl NULL +-#endif +- +-/* UBI volume character device operations */ +-const struct file_operations ubi_vol_cdev_operations = { +- .owner = THIS_MODULE, +- .open = vol_cdev_open, +- .release = vol_cdev_release, +- .llseek = vol_cdev_llseek, +- .read = vol_cdev_read, +- .write = vol_cdev_write, +- .unlocked_ioctl = vol_cdev_ioctl, +- .compat_ioctl = vol_cdev_compat_ioctl, ++/* UBI control character device operations */ ++struct file_operations ubi_ctrl_cdev_operations = { ++ .ioctl = ctrl_cdev_ioctl, ++ .owner = THIS_MODULE, + }; + + /* UBI character device operations */ +-const struct file_operations ubi_cdev_operations = { +- .owner = THIS_MODULE, +- .llseek = no_llseek, +- .unlocked_ioctl = ubi_cdev_ioctl, +- .compat_ioctl = ubi_cdev_compat_ioctl, ++struct file_operations ubi_cdev_operations = { ++ .owner = THIS_MODULE, ++ .ioctl = ubi_cdev_ioctl, ++ .llseek = no_llseek, + }; + +-/* UBI control character device operations */ +-const struct file_operations ubi_ctrl_cdev_operations = { +- .owner = THIS_MODULE, +- .unlocked_ioctl = ctrl_cdev_ioctl, +- .compat_ioctl = ctrl_cdev_compat_ioctl, ++/* UBI volume character device operations */ ++struct file_operations ubi_vol_cdev_operations = { ++ .owner = THIS_MODULE, ++ .open = vol_cdev_open, ++ .release = vol_cdev_release, ++ .llseek = vol_cdev_llseek, ++ .read = vol_cdev_read, ++ .write = vol_cdev_write, ++ .ioctl = vol_cdev_ioctl, + }; +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/drivers/mtd/ubi/gluebi.c linux-2.6.29-rc3.owrt/drivers/mtd/ubi/gluebi.c +--- linux-2.6.29.owrt/drivers/mtd/ubi/gluebi.c 2009-05-10 22:04:39.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/drivers/mtd/ubi/gluebi.c 2009-05-10 23:48:28.000000000 +0200 +@@ -28,7 +28,7 @@ + * eraseblock size is equivalent to the logical eraseblock size of the volume. + */ + +-#include <linux/math64.h> ++#include <asm/div64.h> + #include "ubi.h" + + /** +@@ -109,6 +109,7 @@ + int err = 0, lnum, offs, total_read; + struct ubi_volume *vol; + struct ubi_device *ubi; ++ uint64_t tmp = from; + + dbg_gen("read %zd bytes from offset %lld", len, from); + +@@ -118,7 +119,9 @@ + vol = container_of(mtd, struct ubi_volume, gluebi_mtd); + ubi = vol->ubi; + +- lnum = div_u64_rem(from, mtd->erasesize, &offs); ++ offs = do_div(tmp, mtd->erasesize); ++ lnum = tmp; ++ + total_read = len; + while (total_read) { + size_t to_read = mtd->erasesize - offs; +@@ -157,6 +160,7 @@ + int err = 0, lnum, offs, total_written; + struct ubi_volume *vol; + struct ubi_device *ubi; ++ uint64_t tmp = to; + + dbg_gen("write %zd bytes to offset %lld", len, to); + +@@ -169,7 +173,8 @@ + if (ubi->ro_mode) + return -EROFS; + +- lnum = div_u64_rem(to, mtd->erasesize, &offs); ++ offs = do_div(tmp, mtd->erasesize); ++ lnum = tmp; + + if (len % mtd->writesize || offs % mtd->writesize) + return -EINVAL; +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/drivers/mtd/ubi/Kconfig.debug linux-2.6.29-rc3.owrt/drivers/mtd/ubi/Kconfig.debug +--- linux-2.6.29.owrt/drivers/mtd/ubi/Kconfig.debug 2009-05-10 22:04:39.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/drivers/mtd/ubi/Kconfig.debug 2009-05-10 23:48:28.000000000 +0200 +@@ -33,6 +33,16 @@ + This option switches the background thread off by default. The thread + may be also be enabled/disabled via UBI sysfs. + ++config MTD_UBI_DEBUG_USERSPACE_IO ++ bool "Direct user-space write/erase support" ++ default n ++ depends on MTD_UBI_DEBUG ++ help ++ By default, users cannot directly write and erase individual ++ eraseblocks of dynamic volumes, and have to use update operation ++ instead. This option enables this capability - it is very useful for ++ debugging and testing. ++ + config MTD_UBI_DEBUG_EMULATE_BITFLIPS + bool "Emulate flash bit-flips" + depends on MTD_UBI_DEBUG +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/drivers/mtd/ubi/scan.c linux-2.6.29-rc3.owrt/drivers/mtd/ubi/scan.c +--- linux-2.6.29.owrt/drivers/mtd/ubi/scan.c 2009-05-10 22:04:39.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/drivers/mtd/ubi/scan.c 2009-05-10 23:48:28.000000000 +0200 +@@ -42,7 +42,7 @@ + + #include <linux/err.h> + #include <linux/crc32.h> +-#include <linux/math64.h> ++#include <asm/div64.h> + #include "ubi.h" + + #ifdef CONFIG_MTD_UBI_DEBUG_PARANOID +@@ -904,8 +904,10 @@ + dbg_msg("scanning is finished"); + + /* Calculate mean erase counter */ +- if (si->ec_count) +- si->mean_ec = div_u64(si->ec_sum, si->ec_count); ++ if (si->ec_count) { ++ do_div(si->ec_sum, si->ec_count); ++ si->mean_ec = si->ec_sum; ++ } + + if (si->is_empty) + ubi_msg("empty MTD device detected"); +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/drivers/mtd/ubi/ubi.h linux-2.6.29-rc3.owrt/drivers/mtd/ubi/ubi.h +--- linux-2.6.29.owrt/drivers/mtd/ubi/ubi.h 2009-05-10 22:04:39.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/drivers/mtd/ubi/ubi.h 2009-05-10 23:48:28.000000000 +0200 +@@ -206,7 +206,6 @@ + * @upd_marker: %1 if the update marker is set for this volume + * @updating: %1 if the volume is being updated + * @changing_leb: %1 if the atomic LEB change ioctl command is in progress +- * @direct_writes: %1 if direct writes are enabled for this volume + * + * @gluebi_desc: gluebi UBI volume descriptor + * @gluebi_refcount: reference count of the gluebi MTD device +@@ -254,7 +253,6 @@ + unsigned int upd_marker:1; + unsigned int updating:1; + unsigned int changing_leb:1; +- unsigned int direct_writes:1; + + #ifdef CONFIG_MTD_UBI_GLUEBI + /* +@@ -306,8 +304,7 @@ + * @vtbl_size: size of the volume table in bytes + * @vtbl: in-RAM volume table copy + * @volumes_mutex: protects on-flash volume table and serializes volume +- * changes, like creation, deletion, update, re-size, +- * re-name and set property ++ * changes, like creation, deletion, update, re-size and re-name + * + * @max_ec: current highest erase counter value + * @mean_ec: current mean erase counter value +@@ -452,9 +449,9 @@ + }; + + extern struct kmem_cache *ubi_wl_entry_slab; +-extern const struct file_operations ubi_ctrl_cdev_operations; +-extern const struct file_operations ubi_cdev_operations; +-extern const struct file_operations ubi_vol_cdev_operations; ++extern struct file_operations ubi_ctrl_cdev_operations; ++extern struct file_operations ubi_cdev_operations; ++extern struct file_operations ubi_vol_cdev_operations; + extern struct class *ubi_class; + extern struct mutex ubi_devices_mutex; + +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/drivers/mtd/ubi/upd.c linux-2.6.29-rc3.owrt/drivers/mtd/ubi/upd.c +--- linux-2.6.29.owrt/drivers/mtd/ubi/upd.c 2009-05-10 22:04:39.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/drivers/mtd/ubi/upd.c 2009-05-10 23:48:28.000000000 +0200 +@@ -40,7 +40,7 @@ + + #include <linux/err.h> + #include <linux/uaccess.h> +-#include <linux/math64.h> ++#include <asm/div64.h> + #include "ubi.h" + + /** +@@ -89,6 +89,7 @@ + long long bytes) + { + int err; ++ uint64_t tmp; + struct ubi_vtbl_record vtbl_rec; + + dbg_gen("clear update marker for volume %d", vol->vol_id); +@@ -100,9 +101,9 @@ + + if (vol->vol_type == UBI_STATIC_VOLUME) { + vol->corrupted = 0; +- vol->used_bytes = bytes; +- vol->used_ebs = div_u64_rem(bytes, vol->usable_leb_size, +- &vol->last_eb_bytes); ++ vol->used_bytes = tmp = bytes; ++ vol->last_eb_bytes = do_div(tmp, vol->usable_leb_size); ++ vol->used_ebs = tmp; + if (vol->last_eb_bytes) + vol->used_ebs += 1; + else +@@ -130,6 +131,7 @@ + long long bytes) + { + int i, err; ++ uint64_t tmp; + + dbg_gen("start update of volume %d, %llu bytes", vol->vol_id, bytes); + ubi_assert(!vol->updating && !vol->changing_leb); +@@ -159,8 +161,9 @@ + if (!vol->upd_buf) + return -ENOMEM; + +- vol->upd_ebs = div_u64(bytes + vol->usable_leb_size - 1, +- vol->usable_leb_size); ++ tmp = bytes; ++ vol->upd_ebs = !!do_div(tmp, vol->usable_leb_size); ++ vol->upd_ebs += tmp; + vol->upd_bytes = bytes; + vol->upd_received = 0; + return 0; +@@ -279,6 +282,7 @@ + int ubi_more_update_data(struct ubi_device *ubi, struct ubi_volume *vol, + const void __user *buf, int count) + { ++ uint64_t tmp; + int lnum, offs, err = 0, len, to_write = count; + + dbg_gen("write %d of %lld bytes, %lld already passed", +@@ -287,7 +291,10 @@ + if (ubi->ro_mode) + return -EROFS; + +- lnum = div_u64_rem(vol->upd_received, vol->usable_leb_size, &offs); ++ tmp = vol->upd_received; ++ offs = do_div(tmp, vol->usable_leb_size); ++ lnum = tmp; ++ + if (vol->upd_received + count > vol->upd_bytes) + to_write = count = vol->upd_bytes - vol->upd_received; + +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/drivers/mtd/ubi/vmt.c linux-2.6.29-rc3.owrt/drivers/mtd/ubi/vmt.c +--- linux-2.6.29.owrt/drivers/mtd/ubi/vmt.c 2009-05-10 22:04:39.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/drivers/mtd/ubi/vmt.c 2009-05-10 23:48:28.000000000 +0200 +@@ -24,7 +24,7 @@ + */ + + #include <linux/err.h> +-#include <linux/math64.h> ++#include <asm/div64.h> + #include "ubi.h" + + #ifdef CONFIG_MTD_UBI_DEBUG_PARANOID +@@ -205,6 +205,7 @@ + int i, err, vol_id = req->vol_id, do_free = 1; + struct ubi_volume *vol; + struct ubi_vtbl_record vtbl_rec; ++ uint64_t bytes; + dev_t dev; + + if (ubi->ro_mode) +@@ -254,8 +255,10 @@ + + /* Calculate how many eraseblocks are requested */ + vol->usable_leb_size = ubi->leb_size - ubi->leb_size % req->alignment; +- vol->reserved_pebs += div_u64(req->bytes + vol->usable_leb_size - 1, +- vol->usable_leb_size); ++ bytes = req->bytes; ++ if (do_div(bytes, vol->usable_leb_size)) ++ vol->reserved_pebs = 1; ++ vol->reserved_pebs += bytes; + + /* Reserve physical eraseblocks */ + if (vol->reserved_pebs > ubi->avail_pebs) { +@@ -298,10 +301,10 @@ + vol->used_bytes = + (long long)vol->used_ebs * vol->usable_leb_size; + } else { +- vol->used_ebs = div_u64_rem(vol->used_bytes, +- vol->usable_leb_size, +- &vol->last_eb_bytes); +- if (vol->last_eb_bytes != 0) ++ bytes = vol->used_bytes; ++ vol->last_eb_bytes = do_div(bytes, vol->usable_leb_size); ++ vol->used_ebs = bytes; ++ if (vol->last_eb_bytes) + vol->used_ebs += 1; + else + vol->last_eb_bytes = vol->usable_leb_size; +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/drivers/net/3c505.c linux-2.6.29-rc3.owrt/drivers/net/3c505.c +--- linux-2.6.29.owrt/drivers/net/3c505.c 2009-05-10 22:04:38.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/drivers/net/3c505.c 2009-05-10 23:48:28.000000000 +0200 +@@ -493,27 +493,21 @@ + } + /* read the data */ + spin_lock_irqsave(&adapter->lock, flags); +- for (i = 0; i < MAX_PCB_DATA; i++) { +- for (j = 0; j < 20000; j++) { +- stat = get_status(dev->base_addr); +- if (stat & ACRF) +- break; +- } +- pcb->data.raw[i] = inb_command(dev->base_addr); +- if ((stat & ASF_PCB_MASK) == ASF_PCB_END || j >= 20000) +- break; +- } ++ i = 0; ++ do { ++ j = 0; ++ while (((stat = get_status(dev->base_addr)) & ACRF) == 0 && j++ < 20000); ++ pcb->data.raw[i++] = inb_command(dev->base_addr); ++ if (i > MAX_PCB_DATA) ++ INVALID_PCB_MSG(i); ++ } while ((stat & ASF_PCB_MASK) != ASF_PCB_END && j < 20000); + spin_unlock_irqrestore(&adapter->lock, flags); +- if (i >= MAX_PCB_DATA) { +- INVALID_PCB_MSG(i); +- return false; +- } + if (j >= 20000) { + TIMEOUT_MSG(__LINE__); + return false; + } +- /* the last "data" byte was really the length! */ +- total_length = pcb->data.raw[i]; ++ /* woops, the last "data" byte was really the length! */ ++ total_length = pcb->data.raw[--i]; + + /* safety check total length vs data length */ + if (total_length != (pcb->length + 2)) { +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/drivers/net/3c509.c linux-2.6.29-rc3.owrt/drivers/net/3c509.c +--- linux-2.6.29.owrt/drivers/net/3c509.c 2009-05-10 22:04:38.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/drivers/net/3c509.c 2009-05-10 23:48:28.000000000 +0200 +@@ -1475,7 +1475,6 @@ + spin_lock_irqsave(&lp->lock, flags); + + outw(PowerUp, ioaddr + EL3_CMD); +- EL3WINDOW(0); + el3_up(dev); + + if (netif_running(dev)) +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/drivers/net/arm/etherh.c linux-2.6.29-rc3.owrt/drivers/net/arm/etherh.c +--- linux-2.6.29.owrt/drivers/net/arm/etherh.c 2009-05-10 22:04:38.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/drivers/net/arm/etherh.c 2009-05-10 23:48:28.000000000 +0200 +@@ -641,15 +641,15 @@ + .ndo_open = etherh_open, + .ndo_stop = etherh_close, + .ndo_set_config = etherh_set_config, +- .ndo_start_xmit = __ei_start_xmit, +- .ndo_tx_timeout = __ei_tx_timeout, +- .ndo_get_stats = __ei_get_stats, +- .ndo_set_multicast_list = __ei_set_multicast_list, ++ .ndo_start_xmit = ei_start_xmit, ++ .ndo_tx_timeout = ei_tx_timeout, ++ .ndo_get_stats = ei_get_stats, ++ .ndo_set_multicast_list = ei_set_multicast_list, + .ndo_validate_addr = eth_validate_addr, +- .ndo_set_mac_address = eth_mac_addr, ++ .ndo_set_mac_address = eth_set_mac_addr, + .ndo_change_mtu = eth_change_mtu, + #ifdef CONFIG_NET_POLL_CONTROLLER +- .ndo_poll_controller = __ei_poll, ++ .ndo_poll_controller = ei_poll, + #endif + }; + +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/drivers/net/arm/ks8695net.c linux-2.6.29-rc3.owrt/drivers/net/arm/ks8695net.c +--- linux-2.6.29.owrt/drivers/net/arm/ks8695net.c 2009-05-10 22:04:38.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/drivers/net/arm/ks8695net.c 2009-05-10 23:48:28.000000000 +0200 +@@ -560,7 +560,7 @@ + msleep(1); + } + +- if (reset_timeout < 0) { ++ if (reset_timeout == 0) { + dev_crit(ksp->dev, + "Timeout waiting for DMA engines to reset\n"); + /* And blithely carry on */ +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/drivers/net/arm/Makefile linux-2.6.29-rc3.owrt/drivers/net/arm/Makefile +--- linux-2.6.29.owrt/drivers/net/arm/Makefile 2009-05-10 22:04:38.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/drivers/net/arm/Makefile 2009-05-10 23:48:28.000000000 +0200 +@@ -4,7 +4,7 @@ + # + + obj-$(CONFIG_ARM_AM79C961A) += am79c961a.o +-obj-$(CONFIG_ARM_ETHERH) += etherh.o ++obj-$(CONFIG_ARM_ETHERH) += etherh.o ../8390.o + obj-$(CONFIG_ARM_ETHER3) += ether3.o + obj-$(CONFIG_ARM_ETHER1) += ether1.o + obj-$(CONFIG_ARM_AT91_ETHER) += at91_ether.o +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/drivers/net/atl1c/atl1c_ethtool.c linux-2.6.29-rc3.owrt/drivers/net/atl1c/atl1c_ethtool.c +--- linux-2.6.29.owrt/drivers/net/atl1c/atl1c_ethtool.c 2009-05-10 22:04:38.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/drivers/net/atl1c/atl1c_ethtool.c 1970-01-01 01:00:00.000000000 +0100 +@@ -1,317 +0,0 @@ +-/* +- * Copyright(c) 2009 - 2009 Atheros Corporation. All rights reserved. +- * +- * Derived from Intel e1000 driver +- * Copyright(c) 1999 - 2005 Intel Corporation. All rights reserved. +- * +- * 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, MA 02111-1307, USA. +- * +- */ +- +-#include <linux/netdevice.h> +-#include <linux/ethtool.h> +- +-#include "atl1c.h" +- +-static int atl1c_get_settings(struct net_device *netdev, +- struct ethtool_cmd *ecmd) +-{ +- struct atl1c_adapter *adapter = netdev_priv(netdev); +- struct atl1c_hw *hw = &adapter->hw; +- +- ecmd->supported = (SUPPORTED_10baseT_Half | +- SUPPORTED_10baseT_Full | +- SUPPORTED_100baseT_Half | +- SUPPORTED_100baseT_Full | +- SUPPORTED_Autoneg | +- SUPPORTED_TP); +- if (hw->ctrl_flags & ATL1C_LINK_CAP_1000M) +- ecmd->supported |= SUPPORTED_1000baseT_Full; +- +- ecmd->advertising = ADVERTISED_TP; +- +- ecmd->advertising |= hw->autoneg_advertised; +- +- ecmd->port = PORT_TP; +- ecmd->phy_address = 0; +- ecmd->transceiver = XCVR_INTERNAL; +- +- if (adapter->link_speed != SPEED_0) { +- ecmd->speed = adapter->link_speed; +- if (adapter->link_duplex == FULL_DUPLEX) +- ecmd->duplex = DUPLEX_FULL; +- else +- ecmd->duplex = DUPLEX_HALF; +- } else { +- ecmd->speed = -1; +- ecmd->duplex = -1; +- } +- +- ecmd->autoneg = AUTONEG_ENABLE; +- return 0; +-} +- +-static int atl1c_set_settings(struct net_device *netdev, +- struct ethtool_cmd *ecmd) +-{ +- struct atl1c_adapter *adapter = netdev_priv(netdev); +- struct atl1c_hw *hw = &adapter->hw; +- u16 autoneg_advertised; +- +- while (test_and_set_bit(__AT_RESETTING, &adapter->flags)) +- msleep(1); +- +- if (ecmd->autoneg == AUTONEG_ENABLE) { +- autoneg_advertised = ADVERTISED_Autoneg; +- } else { +- if (ecmd->speed == SPEED_1000) { +- if (ecmd->duplex != DUPLEX_FULL) { +- if (netif_msg_link(adapter)) +- dev_warn(&adapter->pdev->dev, +- "1000M half is invalid\n"); +- clear_bit(__AT_RESETTING, &adapter->flags); +- return -EINVAL; +- } +- autoneg_advertised = ADVERTISED_1000baseT_Full; +- } else if (ecmd->speed == SPEED_100) { +- if (ecmd->duplex == DUPLEX_FULL) +- autoneg_advertised = ADVERTISED_100baseT_Full; +- else +- autoneg_advertised = ADVERTISED_100baseT_Half; +- } else { +- if (ecmd->duplex == DUPLEX_FULL) +- autoneg_advertised = ADVERTISED_10baseT_Full; +- else +- autoneg_advertised = ADVERTISED_10baseT_Half; +- } +- } +- +- if (hw->autoneg_advertised != autoneg_advertised) { +- hw->autoneg_advertised = autoneg_advertised; +- if (atl1c_restart_autoneg(hw) != 0) { +- if (netif_msg_link(adapter)) +- dev_warn(&adapter->pdev->dev, +- "ethtool speed/duplex setting failed\n"); +- clear_bit(__AT_RESETTING, &adapter->flags); +- return -EINVAL; +- } +- } +- clear_bit(__AT_RESETTING, &adapter->flags); +- return 0; +-} +- +-static u32 atl1c_get_tx_csum(struct net_device *netdev) +-{ +- return (netdev->features & NETIF_F_HW_CSUM) != 0; +-} +- +-static u32 atl1c_get_msglevel(struct net_device *netdev) +-{ +- struct atl1c_adapter *adapter = netdev_priv(netdev); +- return adapter->msg_enable; +-} +- +-static void atl1c_set_msglevel(struct net_device *netdev, u32 data) +-{ +- struct atl1c_adapter *adapter = netdev_priv(netdev); +- adapter->msg_enable = data; +-} +- +-static int atl1c_get_regs_len(struct net_device *netdev) +-{ +- return AT_REGS_LEN; +-} +- +-static void atl1c_get_regs(struct net_device *netdev, +- struct ethtool_regs *regs, void *p) +-{ +- struct atl1c_adapter *adapter = netdev_priv(netdev); +- struct atl1c_hw *hw = &adapter->hw; +- u32 *regs_buff = p; +- u16 phy_data; +- +- memset(p, 0, AT_REGS_LEN); +- +- regs->version = 0; +- AT_READ_REG(hw, REG_VPD_CAP, p++); +- AT_READ_REG(hw, REG_PM_CTRL, p++); +- AT_READ_REG(hw, REG_MAC_HALF_DUPLX_CTRL, p++); +- AT_READ_REG(hw, REG_TWSI_CTRL, p++); +- AT_READ_REG(hw, REG_PCIE_DEV_MISC_CTRL, p++); +- AT_READ_REG(hw, REG_MASTER_CTRL, p++); +- AT_READ_REG(hw, REG_MANUAL_TIMER_INIT, p++); +- AT_READ_REG(hw, REG_IRQ_MODRT_TIMER_INIT, p++); +- AT_READ_REG(hw, REG_GPHY_CTRL, p++); +- AT_READ_REG(hw, REG_LINK_CTRL, p++); +- AT_READ_REG(hw, REG_IDLE_STATUS, p++); +- AT_READ_REG(hw, REG_MDIO_CTRL, p++); +- AT_READ_REG(hw, REG_SERDES_LOCK, p++); +- AT_READ_REG(hw, REG_MAC_CTRL, p++); +- AT_READ_REG(hw, REG_MAC_IPG_IFG, p++); +- AT_READ_REG(hw, REG_MAC_STA_ADDR, p++); +- AT_READ_REG(hw, REG_MAC_STA_ADDR+4, p++); +- AT_READ_REG(hw, REG_RX_HASH_TABLE, p++); +- AT_READ_REG(hw, REG_RX_HASH_TABLE+4, p++); +- AT_READ_REG(hw, REG_RXQ_CTRL, p++); +- AT_READ_REG(hw, REG_TXQ_CTRL, p++); +- AT_READ_REG(hw, REG_MTU, p++); +- AT_READ_REG(hw, REG_WOL_CTRL, p++); +- +- atl1c_read_phy_reg(hw, MII_BMCR, &phy_data); +- regs_buff[73] = (u32) phy_data; +- atl1c_read_phy_reg(hw, MII_BMSR, &phy_data); +- regs_buff[74] = (u32) phy_data; +-} +- +-static int atl1c_get_eeprom_len(struct net_device *netdev) +-{ +- struct atl1c_adapter *adapter = netdev_priv(netdev); +- +- if (atl1c_check_eeprom_exist(&adapter->hw)) +- return AT_EEPROM_LEN; +- else +- return 0; +-} +- +-static int atl1c_get_eeprom(struct net_device *netdev, +- struct ethtool_eeprom *eeprom, u8 *bytes) +-{ +- struct atl1c_adapter *adapter = netdev_priv(netdev); +- struct atl1c_hw *hw = &adapter->hw; +- u32 *eeprom_buff; +- int first_dword, last_dword; +- int ret_val = 0; +- int i; +- +- if (eeprom->len == 0) +- return -EINVAL; +- +- if (!atl1c_check_eeprom_exist(hw)) /* not exist */ +- return -EINVAL; +- +- eeprom->magic = adapter->pdev->vendor | +- (adapter->pdev->device << 16); +- +- first_dword = eeprom->offset >> 2; +- last_dword = (eeprom->offset + eeprom->len - 1) >> 2; +- +- eeprom_buff = kmalloc(sizeof(u32) * +- (last_dword - first_dword + 1), GFP_KERNEL); +- if (eeprom_buff == NULL) +- return -ENOMEM; +- +- for (i = first_dword; i < last_dword; i++) { +- if (!atl1c_read_eeprom(hw, i * 4, &(eeprom_buff[i-first_dword]))) { +- kfree(eeprom_buff); +- return -EIO; +- } +- } +- +- memcpy(bytes, (u8 *)eeprom_buff + (eeprom->offset & 3), +- eeprom->len); +- kfree(eeprom_buff); +- +- return ret_val; +- return 0; +-} +- +-static void atl1c_get_drvinfo(struct net_device *netdev, +- struct ethtool_drvinfo *drvinfo) +-{ +- struct atl1c_adapter *adapter = netdev_priv(netdev); +- +- strncpy(drvinfo->driver, atl1c_driver_name, sizeof(drvinfo->driver)); +- strncpy(drvinfo->version, atl1c_driver_version, +- sizeof(drvinfo->version)); +- strncpy(drvinfo->fw_version, "N/A", sizeof(drvinfo->fw_version)); +- strncpy(drvinfo->bus_info, pci_name(adapter->pdev), +- sizeof(drvinfo->bus_info)); +- drvinfo->n_stats = 0; +- drvinfo->testinfo_len = 0; +- drvinfo->regdump_len = atl1c_get_regs_len(netdev); +- drvinfo->eedump_len = atl1c_get_eeprom_len(netdev); +-} +- +-static void atl1c_get_wol(struct net_device *netdev, +- struct ethtool_wolinfo *wol) +-{ +- struct atl1c_adapter *adapter = netdev_priv(netdev); +- +- wol->supported = WAKE_MAGIC | WAKE_PHY; +- wol->wolopts = 0; +- +- if (adapter->wol & AT_WUFC_EX) +- wol->wolopts |= WAKE_UCAST; +- if (adapter->wol & AT_WUFC_MC) +- wol->wolopts |= WAKE_MCAST; +- if (adapter->wol & AT_WUFC_BC) +- wol->wolopts |= WAKE_BCAST; +- if (adapter->wol & AT_WUFC_MAG) +- wol->wolopts |= WAKE_MAGIC; +- if (adapter->wol & AT_WUFC_LNKC) +- wol->wolopts |= WAKE_PHY; +- +- return; +-} +- +-static int atl1c_set_wol(struct net_device *netdev, struct ethtool_wolinfo *wol) +-{ +- struct atl1c_adapter *adapter = netdev_priv(netdev); +- +- if (wol->wolopts & (WAKE_ARP | WAKE_MAGICSECURE | +- WAKE_MCAST | WAKE_BCAST | WAKE_MCAST)) +- return -EOPNOTSUPP; +- /* these settings will always override what we currently have */ +- adapter->wol = 0; +- +- if (wol->wolopts & WAKE_MAGIC) +- adapter->wol |= AT_WUFC_MAG; +- if (wol->wolopts & WAKE_PHY) +- adapter->wol |= AT_WUFC_LNKC; +- +- return 0; +-} +- +-static int atl1c_nway_reset(struct net_device *netdev) +-{ +- struct atl1c_adapter *adapter = netdev_priv(netdev); +- if (netif_running(netdev)) +- atl1c_reinit_locked(adapter); +- return 0; +-} +- +-static struct ethtool_ops atl1c_ethtool_ops = { +- .get_settings = atl1c_get_settings, +- .set_settings = atl1c_set_settings, +- .get_drvinfo = atl1c_get_drvinfo, +- .get_regs_len = atl1c_get_regs_len, +- .get_regs = atl1c_get_regs, +- .get_wol = atl1c_get_wol, +- .set_wol = atl1c_set_wol, +- .get_msglevel = atl1c_get_msglevel, +- .set_msglevel = atl1c_set_msglevel, +- .nway_reset = atl1c_nway_reset, +- .get_link = ethtool_op_get_link, +- .get_eeprom_len = atl1c_get_eeprom_len, +- .get_eeprom = atl1c_get_eeprom, +- .get_tx_csum = atl1c_get_tx_csum, +- .get_sg = ethtool_op_get_sg, +- .set_sg = ethtool_op_set_sg, +-}; +- +-void atl1c_set_ethtool_ops(struct net_device *netdev) +-{ +- SET_ETHTOOL_OPS(netdev, &atl1c_ethtool_ops); +-} +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/drivers/net/atl1c/atl1c.h linux-2.6.29-rc3.owrt/drivers/net/atl1c/atl1c.h +--- linux-2.6.29.owrt/drivers/net/atl1c/atl1c.h 2009-05-10 22:04:38.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/drivers/net/atl1c/atl1c.h 1970-01-01 01:00:00.000000000 +0100 +@@ -1,606 +0,0 @@ +-/* +- * Copyright(c) 2008 - 2009 Atheros Corporation. All rights reserved. +- * +- * Derived from Intel e1000 driver +- * Copyright(c) 1999 - 2005 Intel Corporation. All rights reserved. +- * +- * 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, MA 02111-1307, USA. +- */ +- +-#ifndef _ATL1C_H_ +-#define _ATL1C_H_ +- +-#include <linux/version.h> +-#include <linux/init.h> +-#include <linux/types.h> +-#include <linux/errno.h> +-#include <linux/module.h> +-#include <linux/pci.h> +-#include <linux/netdevice.h> +-#include <linux/etherdevice.h> +-#include <linux/skbuff.h> +-#include <linux/ioport.h> +-#include <linux/slab.h> +-#include <linux/list.h> +-#include <linux/delay.h> +-#include <linux/sched.h> +-#include <linux/in.h> +-#include <linux/ip.h> +-#include <linux/ipv6.h> +-#include <linux/udp.h> +-#include <linux/mii.h> +-#include <linux/io.h> +-#include <linux/vmalloc.h> +-#include <linux/pagemap.h> +-#include <linux/tcp.h> +-#include <linux/mii.h> +-#include <linux/ethtool.h> +-#include <linux/if_vlan.h> +-#include <linux/workqueue.h> +-#include <net/checksum.h> +-#include <net/ip6_checksum.h> +- +-#include "atl1c_hw.h" +- +-/* Wake Up Filter Control */ +-#define AT_WUFC_LNKC 0x00000001 /* Link Status Change Wakeup Enable */ +-#define AT_WUFC_MAG 0x00000002 /* Magic Packet Wakeup Enable */ +-#define AT_WUFC_EX 0x00000004 /* Directed Exact Wakeup Enable */ +-#define AT_WUFC_MC 0x00000008 /* Multicast Wakeup Enable */ +-#define AT_WUFC_BC 0x00000010 /* Broadcast Wakeup Enable */ +- +-#define AT_VLAN_TO_TAG(_vlan, _tag) \ +- _tag = ((((_vlan) >> 8) & 0xFF) |\ +- (((_vlan) & 0xFF) << 8)) +- +-#define AT_TAG_TO_VLAN(_tag, _vlan) \ +- _vlan = ((((_tag) >> 8) & 0xFF) |\ +- (((_tag) & 0xFF) << 8)) +- +-#define SPEED_0 0xffff +-#define HALF_DUPLEX 1 +-#define FULL_DUPLEX 2 +- +-#define AT_RX_BUF_SIZE (ETH_FRAME_LEN + VLAN_HLEN + ETH_FCS_LEN) +-#define MAX_JUMBO_FRAME_SIZE (9*1024) +-#define MAX_TX_OFFLOAD_THRESH (9*1024) +- +-#define AT_MAX_RECEIVE_QUEUE 4 +-#define AT_DEF_RECEIVE_QUEUE 1 +-#define AT_MAX_TRANSMIT_QUEUE 2 +- +-#define AT_DMA_HI_ADDR_MASK 0xffffffff00000000ULL +-#define AT_DMA_LO_ADDR_MASK 0x00000000ffffffffULL +- +-#define AT_TX_WATCHDOG (5 * HZ) +-#define AT_MAX_INT_WORK 5 +-#define AT_TWSI_EEPROM_TIMEOUT 100 +-#define AT_HW_MAX_IDLE_DELAY 10 +-#define AT_SUSPEND_LINK_TIMEOUT 28 +- +-#define AT_ASPM_L0S_TIMER 6 +-#define AT_ASPM_L1_TIMER 12 +- +-#define ATL1C_PCIE_L0S_L1_DISABLE 0x01 +-#define ATL1C_PCIE_PHY_RESET 0x02 +- +-#define ATL1C_ASPM_L0s_ENABLE 0x0001 +-#define ATL1C_ASPM_L1_ENABLE 0x0002 +- +-#define AT_REGS_LEN (75 * sizeof(u32)) +-#define AT_EEPROM_LEN 512 +- +-#define ATL1C_GET_DESC(R, i, type) (&(((type *)((R)->desc))[i])) +-#define ATL1C_RFD_DESC(R, i) ATL1C_GET_DESC(R, i, struct atl1c_rx_free_desc) +-#define ATL1C_TPD_DESC(R, i) ATL1C_GET_DESC(R, i, struct atl1c_tpd_desc) +-#define ATL1C_RRD_DESC(R, i) ATL1C_GET_DESC(R, i, struct atl1c_recv_ret_status) +- +-/* tpd word 1 bit 0:7 General Checksum task offload */ +-#define TPD_L4HDR_OFFSET_MASK 0x00FF +-#define TPD_L4HDR_OFFSET_SHIFT 0 +- +-/* tpd word 1 bit 0:7 Large Send task offload (IPv4/IPV6) */ +-#define TPD_TCPHDR_OFFSET_MASK 0x00FF +-#define TPD_TCPHDR_OFFSET_SHIFT 0 +- +-/* tpd word 1 bit 0:7 Custom Checksum task offload */ +-#define TPD_PLOADOFFSET_MASK 0x00FF +-#define TPD_PLOADOFFSET_SHIFT 0 +- +-/* tpd word 1 bit 8:17 */ +-#define TPD_CCSUM_EN_MASK 0x0001 +-#define TPD_CCSUM_EN_SHIFT 8 +-#define TPD_IP_CSUM_MASK 0x0001 +-#define TPD_IP_CSUM_SHIFT 9 +-#define TPD_TCP_CSUM_MASK 0x0001 +-#define TPD_TCP_CSUM_SHIFT 10 +-#define TPD_UDP_CSUM_MASK 0x0001 +-#define TPD_UDP_CSUM_SHIFT 11 +-#define TPD_LSO_EN_MASK 0x0001 /* TCP Large Send Offload */ +-#define TPD_LSO_EN_SHIFT 12 +-#define TPD_LSO_VER_MASK 0x0001 +-#define TPD_LSO_VER_SHIFT 13 /* 0 : ipv4; 1 : ipv4/ipv6 */ +-#define TPD_CON_VTAG_MASK 0x0001 +-#define TPD_CON_VTAG_SHIFT 14 +-#define TPD_INS_VTAG_MASK 0x0001 +-#define TPD_INS_VTAG_SHIFT 15 +-#define TPD_IPV4_PACKET_MASK 0x0001 /* valid when LSO VER is 1 */ +-#define TPD_IPV4_PACKET_SHIFT 16 +-#define TPD_ETH_TYPE_MASK 0x0001 +-#define TPD_ETH_TYPE_SHIFT 17 /* 0 : 802.3 frame; 1 : Ethernet */ +- +-/* tpd word 18:25 Custom Checksum task offload */ +-#define TPD_CCSUM_OFFSET_MASK 0x00FF +-#define TPD_CCSUM_OFFSET_SHIFT 18 +-#define TPD_CCSUM_EPAD_MASK 0x0001 +-#define TPD_CCSUM_EPAD_SHIFT 30 +- +-/* tpd word 18:30 Large Send task offload (IPv4/IPV6) */ +-#define TPD_MSS_MASK 0x1FFF +-#define TPD_MSS_SHIFT 18 +- +-#define TPD_EOP_MASK 0x0001 +-#define TPD_EOP_SHIFT 31 +- +-struct atl1c_tpd_desc { +- __le16 buffer_len; /* include 4-byte CRC */ +- __le16 vlan_tag; +- __le32 word1; +- __le64 buffer_addr; +-}; +- +-struct atl1c_tpd_ext_desc { +- u32 reservd_0; +- __le32 word1; +- __le32 pkt_len; +- u32 reservd_1; +-}; +-/* rrs word 0 bit 0:31 */ +-#define RRS_RX_CSUM_MASK 0xFFFF +-#define RRS_RX_CSUM_SHIFT 0 +-#define RRS_RX_RFD_CNT_MASK 0x000F +-#define RRS_RX_RFD_CNT_SHIFT 16 +-#define RRS_RX_RFD_INDEX_MASK 0x0FFF +-#define RRS_RX_RFD_INDEX_SHIFT 20 +- +-/* rrs flag bit 0:16 */ +-#define RRS_HEAD_LEN_MASK 0x00FF +-#define RRS_HEAD_LEN_SHIFT 0 +-#define RRS_HDS_TYPE_MASK 0x0003 +-#define RRS_HDS_TYPE_SHIFT 8 +-#define RRS_CPU_NUM_MASK 0x0003 +-#define RRS_CPU_NUM_SHIFT 10 +-#define RRS_HASH_FLG_MASK 0x000F +-#define RRS_HASH_FLG_SHIFT 12 +- +-#define RRS_HDS_TYPE_HEAD 1 +-#define RRS_HDS_TYPE_DATA 2 +- +-#define RRS_IS_NO_HDS_TYPE(flag) \ +- (((flag) >> (RRS_HDS_TYPE_SHIFT)) & RRS_HDS_TYPE_MASK == 0) +- +-#define RRS_IS_HDS_HEAD(flag) \ +- (((flag) >> (RRS_HDS_TYPE_SHIFT)) & RRS_HDS_TYPE_MASK == \ +- RRS_HDS_TYPE_HEAD) +- +-#define RRS_IS_HDS_DATA(flag) \ +- (((flag) >> (RRS_HDS_TYPE_SHIFT)) & RRS_HDS_TYPE_MASK == \ +- RRS_HDS_TYPE_DATA) +- +-/* rrs word 3 bit 0:31 */ +-#define RRS_PKT_SIZE_MASK 0x3FFF +-#define RRS_PKT_SIZE_SHIFT 0 +-#define RRS_ERR_L4_CSUM_MASK 0x0001 +-#define RRS_ERR_L4_CSUM_SHIFT 14 +-#define RRS_ERR_IP_CSUM_MASK 0x0001 +-#define RRS_ERR_IP_CSUM_SHIFT 15 +-#define RRS_VLAN_INS_MASK 0x0001 +-#define RRS_VLAN_INS_SHIFT 16 +-#define RRS_PROT_ID_MASK 0x0007 +-#define RRS_PROT_ID_SHIFT 17 +-#define RRS_RX_ERR_SUM_MASK 0x0001 +-#define RRS_RX_ERR_SUM_SHIFT 20 +-#define RRS_RX_ERR_CRC_MASK 0x0001 +-#define RRS_RX_ERR_CRC_SHIFT 21 +-#define RRS_RX_ERR_FAE_MASK 0x0001 +-#define RRS_RX_ERR_FAE_SHIFT 22 +-#define RRS_RX_ERR_TRUNC_MASK 0x0001 +-#define RRS_RX_ERR_TRUNC_SHIFT 23 +-#define RRS_RX_ERR_RUNC_MASK 0x0001 +-#define RRS_RX_ERR_RUNC_SHIFT 24 +-#define RRS_RX_ERR_ICMP_MASK 0x0001 +-#define RRS_RX_ERR_ICMP_SHIFT 25 +-#define RRS_PACKET_BCAST_MASK 0x0001 +-#define RRS_PACKET_BCAST_SHIFT 26 +-#define RRS_PACKET_MCAST_MASK 0x0001 +-#define RRS_PACKET_MCAST_SHIFT 27 +-#define RRS_PACKET_TYPE_MASK 0x0001 +-#define RRS_PACKET_TYPE_SHIFT 28 +-#define RRS_FIFO_FULL_MASK 0x0001 +-#define RRS_FIFO_FULL_SHIFT 29 +-#define RRS_802_3_LEN_ERR_MASK 0x0001 +-#define RRS_802_3_LEN_ERR_SHIFT 30 +-#define RRS_RXD_UPDATED_MASK 0x0001 +-#define RRS_RXD_UPDATED_SHIFT 31 +- +-#define RRS_ERR_L4_CSUM 0x00004000 +-#define RRS_ERR_IP_CSUM 0x00008000 +-#define RRS_VLAN_INS 0x00010000 +-#define RRS_RX_ERR_SUM 0x00100000 +-#define RRS_RX_ERR_CRC 0x00200000 +-#define RRS_802_3_LEN_ERR 0x40000000 +-#define RRS_RXD_UPDATED 0x80000000 +- +-#define RRS_PACKET_TYPE_802_3 1 +-#define RRS_PACKET_TYPE_ETH 0 +-#define RRS_PACKET_IS_ETH(word) \ +- (((word) >> RRS_PACKET_TYPE_SHIFT) & RRS_PACKET_TYPE_MASK == \ +- RRS_PACKET_TYPE_ETH) +-#define RRS_RXD_IS_VALID(word) \ +- ((((word) >> RRS_RXD_UPDATED_SHIFT) & RRS_RXD_UPDATED_MASK) == 1) +- +-#define RRS_PACKET_PROT_IS_IPV4_ONLY(word) \ +- ((((word) >> RRS_PROT_ID_SHIFT) & RRS_PROT_ID_MASK) == 1) +-#define RRS_PACKET_PROT_IS_IPV6_ONLY(word) \ +- ((((word) >> RRS_PROT_ID_SHIFT) & RRS_PROT_ID_MASK) == 6) +- +-struct atl1c_recv_ret_status { +- __le32 word0; +- __le32 rss_hash; +- __le16 vlan_tag; +- __le16 flag; +- __le32 word3; +-}; +- +-/* RFD desciptor */ +-struct atl1c_rx_free_desc { +- __le64 buffer_addr; +-}; +- +-/* DMA Order Settings */ +-enum atl1c_dma_order { +- atl1c_dma_ord_in = 1, +- atl1c_dma_ord_enh = 2, +- atl1c_dma_ord_out = 4 +-}; +- +-enum atl1c_dma_rcb { +- atl1c_rcb_64 = 0, +- atl1c_rcb_128 = 1 +-}; +- +-enum atl1c_mac_speed { +- atl1c_mac_speed_0 = 0, +- atl1c_mac_speed_10_100 = 1, +- atl1c_mac_speed_1000 = 2 +-}; +- +-enum atl1c_dma_req_block { +- atl1c_dma_req_128 = 0, +- atl1c_dma_req_256 = 1, +- atl1c_dma_req_512 = 2, +- atl1c_dma_req_1024 = 3, +- atl1c_dma_req_2048 = 4, +- atl1c_dma_req_4096 = 5 +-}; +- +-enum atl1c_rss_mode { +- atl1c_rss_mode_disable = 0, +- atl1c_rss_sig_que = 1, +- atl1c_rss_mul_que_sig_int = 2, +- atl1c_rss_mul_que_mul_int = 4, +-}; +- +-enum atl1c_rss_type { +- atl1c_rss_disable = 0, +- atl1c_rss_ipv4 = 1, +- atl1c_rss_ipv4_tcp = 2, +- atl1c_rss_ipv6 = 4, +- atl1c_rss_ipv6_tcp = 8 +-}; +- +-enum atl1c_nic_type { +- athr_l1c = 0, +- athr_l2c = 1, +-}; +- +-enum atl1c_trans_queue { +- atl1c_trans_normal = 0, +- atl1c_trans_high = 1 +-}; +- +-struct atl1c_hw_stats { +- /* rx */ +- unsigned long rx_ok; /* The number of good packet received. */ +- unsigned long rx_bcast; /* The number of good broadcast packet received. */ +- unsigned long rx_mcast; /* The number of good multicast packet received. */ +- unsigned long rx_pause; /* The number of Pause packet received. */ +- unsigned long rx_ctrl; /* The number of Control packet received other than Pause frame. */ +- unsigned long rx_fcs_err; /* The number of packets with bad FCS. */ +- unsigned long rx_len_err; /* The number of packets with mismatch of length field and actual size. */ +- unsigned long rx_byte_cnt; /* The number of bytes of good packet received. FCS is NOT included. */ +- unsigned long rx_runt; /* The number of packets received that are less than 64 byte long and with good FCS. */ +- unsigned long rx_frag; /* The number of packets received that are less than 64 byte long and with bad FCS. */ +- unsigned long rx_sz_64; /* The number of good and bad packets received that are 64 byte long. */ +- unsigned long rx_sz_65_127; /* The number of good and bad packets received that are between 65 and 127-byte long. */ +- unsigned long rx_sz_128_255; /* The number of good and bad packets received that are between 128 and 255-byte long. */ +- unsigned long rx_sz_256_511; /* The number of good and bad packets received that are between 256 and 511-byte long. */ +- unsigned long rx_sz_512_1023; /* The number of good and bad packets received that are between 512 and 1023-byte long. */ +- unsigned long rx_sz_1024_1518; /* The number of good and bad packets received that are between 1024 and 1518-byte long. */ +- unsigned long rx_sz_1519_max; /* The number of good and bad packets received that are between 1519-byte and MTU. */ +- unsigned long rx_sz_ov; /* The number of good and bad packets received that are more than MTU size truncated by Selene. */ +- unsigned long rx_rxf_ov; /* The number of frame dropped due to occurrence of RX FIFO overflow. */ +- unsigned long rx_rrd_ov; /* The number of frame dropped due to occurrence of RRD overflow. */ +- unsigned long rx_align_err; /* Alignment Error */ +- unsigned long rx_bcast_byte_cnt; /* The byte count of broadcast packet received, excluding FCS. */ +- unsigned long rx_mcast_byte_cnt; /* The byte count of multicast packet received, excluding FCS. */ +- unsigned long rx_err_addr; /* The number of packets dropped due to address filtering. */ +- +- /* tx */ +- unsigned long tx_ok; /* The number of good packet transmitted. */ +- unsigned long tx_bcast; /* The number of good broadcast packet transmitted. */ +- unsigned long tx_mcast; /* The number of good multicast packet transmitted. */ +- unsigned long tx_pause; /* The number of Pause packet transmitted. */ +- unsigned long tx_exc_defer; /* The number of packets transmitted with excessive deferral. */ +- unsigned long tx_ctrl; /* The number of packets transmitted is a control frame, excluding Pause frame. */ +- unsigned long tx_defer; /* The number of packets transmitted that is deferred. */ +- unsigned long tx_byte_cnt; /* The number of bytes of data transmitted. FCS is NOT included. */ +- unsigned long tx_sz_64; /* The number of good and bad packets transmitted that are 64 byte long. */ +- unsigned long tx_sz_65_127; /* The number of good and bad packets transmitted that are between 65 and 127-byte long. */ +- unsigned long tx_sz_128_255; /* The number of good and bad packets transmitted that are between 128 and 255-byte long. */ +- unsigned long tx_sz_256_511; /* The number of good and bad packets transmitted that are between 256 and 511-byte long. */ +- unsigned long tx_sz_512_1023; /* The number of good and bad packets transmitted that are between 512 and 1023-byte long. */ +- unsigned long tx_sz_1024_1518; /* The number of good and bad packets transmitted that are between 1024 and 1518-byte long. */ +- unsigned long tx_sz_1519_max; /* The number of good and bad packets transmitted that are between 1519-byte and MTU. */ +- unsigned long tx_1_col; /* The number of packets subsequently transmitted successfully with a single prior collision. */ +- unsigned long tx_2_col; /* The number of packets subsequently transmitted successfully with multiple prior collisions. */ +- unsigned long tx_late_col; /* The number of packets transmitted with late collisions. */ +- unsigned long tx_abort_col; /* The number of transmit packets aborted due to excessive collisions. */ +- unsigned long tx_underrun; /* The number of transmit packets aborted due to transmit FIFO underrun, or TRD FIFO underrun */ +- unsigned long tx_rd_eop; /* The number of times that read beyond the EOP into the next frame area when TRD was not written timely */ +- unsigned long tx_len_err; /* The number of transmit packets with length field does NOT match the actual frame size. */ +- unsigned long tx_trunc; /* The number of transmit packets truncated due to size exceeding MTU. */ +- unsigned long tx_bcast_byte; /* The byte count of broadcast packet transmitted, excluding FCS. */ +- unsigned long tx_mcast_byte; /* The byte count of multicast packet transmitted, excluding FCS. */ +-}; +- +-struct atl1c_hw { +- u8 __iomem *hw_addr; /* inner register address */ +- struct atl1c_adapter *adapter; +- enum atl1c_nic_type nic_type; +- enum atl1c_dma_order dma_order; +- enum atl1c_dma_rcb rcb_value; +- enum atl1c_dma_req_block dmar_block; +- enum atl1c_dma_req_block dmaw_block; +- +- u16 device_id; +- u16 vendor_id; +- u16 subsystem_id; +- u16 subsystem_vendor_id; +- u8 revision_id; +- +- u32 intr_mask; +- u8 dmaw_dly_cnt; +- u8 dmar_dly_cnt; +- +- u8 preamble_len; +- u16 max_frame_size; +- u16 min_frame_size; +- +- enum atl1c_mac_speed mac_speed; +- bool mac_duplex; +- bool hibernate; +- u16 media_type; +-#define MEDIA_TYPE_AUTO_SENSOR 0 +-#define MEDIA_TYPE_100M_FULL 1 +-#define MEDIA_TYPE_100M_HALF 2 +-#define MEDIA_TYPE_10M_FULL 3 +-#define MEDIA_TYPE_10M_HALF 4 +- +- u16 autoneg_advertised; +- u16 mii_autoneg_adv_reg; +- u16 mii_1000t_ctrl_reg; +- +- u16 tx_imt; /* TX Interrupt Moderator timer ( 2us resolution) */ +- u16 rx_imt; /* RX Interrupt Moderator timer ( 2us resolution) */ +- u16 ict; /* Interrupt Clear timer (2us resolution) */ +- u16 ctrl_flags; +-#define ATL1C_INTR_CLEAR_ON_READ 0x0001 +-#define ATL1C_INTR_MODRT_ENABLE 0x0002 +-#define ATL1C_CMB_ENABLE 0x0004 +-#define ATL1C_SMB_ENABLE 0x0010 +-#define ATL1C_TXQ_MODE_ENHANCE 0x0020 +-#define ATL1C_RX_IPV6_CHKSUM 0x0040 +-#define ATL1C_ASPM_L0S_SUPPORT 0x0080 +-#define ATL1C_ASPM_L1_SUPPORT 0x0100 +-#define ATL1C_ASPM_CTRL_MON 0x0200 +-#define ATL1C_HIB_DISABLE 0x0400 +-#define ATL1C_LINK_CAP_1000M 0x0800 +-#define ATL1C_FPGA_VERSION 0x8000 +- u16 cmb_tpd; +- u16 cmb_rrd; +- u16 cmb_rx_timer; /* 2us resolution */ +- u16 cmb_tx_timer; +- u32 smb_timer; +- +- u16 rrd_thresh; /* Threshold of number of RRD produced to trigger +- interrupt request */ +- u16 tpd_thresh; +- u8 tpd_burst; /* Number of TPD to prefetch in cache-aligned burst. */ +- u8 rfd_burst; +- enum atl1c_rss_type rss_type; +- enum atl1c_rss_mode rss_mode; +- u8 rss_hash_bits; +- u32 base_cpu; +- u32 indirect_tab; +- u8 mac_addr[ETH_ALEN]; +- u8 perm_mac_addr[ETH_ALEN]; +- +- bool phy_configured; +- bool re_autoneg; +- bool emi_ca; +-}; +- +-/* +- * atl1c_ring_header represents a single, contiguous block of DMA space +- * mapped for the three descriptor rings (tpd, rfd, rrd) and the two +- * message blocks (cmb, smb) described below +- */ +-struct atl1c_ring_header { +- void *desc; /* virtual address */ +- dma_addr_t dma; /* physical address*/ +- unsigned int size; /* length in bytes */ +-}; +- +-/* +- * atl1c_buffer is wrapper around a pointer to a socket buffer +- * so a DMA handle can be stored along with the skb +- */ +-struct atl1c_buffer { +- struct sk_buff *skb; /* socket buffer */ +- u16 length; /* rx buffer length */ +- u16 state; /* state of buffer */ +-#define ATL1_BUFFER_FREE 0 +-#define ATL1_BUFFER_BUSY 1 +- dma_addr_t dma; +-}; +- +-/* transimit packet descriptor (tpd) ring */ +-struct atl1c_tpd_ring { +- void *desc; /* descriptor ring virtual address */ +- dma_addr_t dma; /* descriptor ring physical address */ +- u16 size; /* descriptor ring length in bytes */ +- u16 count; /* number of descriptors in the ring */ +- u16 next_to_use; /* this is protectd by adapter->tx_lock */ +- atomic_t next_to_clean; +- struct atl1c_buffer *buffer_info; +-}; +- +-/* receive free descriptor (rfd) ring */ +-struct atl1c_rfd_ring { +- void *desc; /* descriptor ring virtual address */ +- dma_addr_t dma; /* descriptor ring physical address */ +- u16 size; /* descriptor ring length in bytes */ +- u16 count; /* number of descriptors in the ring */ +- u16 next_to_use; +- u16 next_to_clean; +- struct atl1c_buffer *buffer_info; +-}; +- +-/* receive return desciptor (rrd) ring */ +-struct atl1c_rrd_ring { +- void *desc; /* descriptor ring virtual address */ +- dma_addr_t dma; /* descriptor ring physical address */ +- u16 size; /* descriptor ring length in bytes */ +- u16 count; /* number of descriptors in the ring */ +- u16 next_to_use; +- u16 next_to_clean; +-}; +- +-struct atl1c_cmb { +- void *cmb; +- dma_addr_t dma; +-}; +- +-struct atl1c_smb { +- void *smb; +- dma_addr_t dma; +-}; +- +-/* board specific private data structure */ +-struct atl1c_adapter { +- struct net_device *netdev; +- struct pci_dev *pdev; +- struct vlan_group *vlgrp; +- struct napi_struct napi; +- struct atl1c_hw hw; +- struct atl1c_hw_stats hw_stats; +- struct net_device_stats net_stats; +- struct mii_if_info mii; /* MII interface info */ +- u16 rx_buffer_len; +- +- unsigned long flags; +-#define __AT_TESTING 0x0001 +-#define __AT_RESETTING 0x0002 +-#define __AT_DOWN 0x0003 +- u32 msg_enable; +- +- bool have_msi; +- u32 wol; +- u16 link_speed; +- u16 link_duplex; +- +- spinlock_t mdio_lock; +- spinlock_t tx_lock; +- atomic_t irq_sem; +- +- struct work_struct reset_task; +- struct work_struct link_chg_task; +- struct timer_list watchdog_timer; +- struct timer_list phy_config_timer; +- +- /* All Descriptor memory */ +- struct atl1c_ring_header ring_header; +- struct atl1c_tpd_ring tpd_ring[AT_MAX_TRANSMIT_QUEUE]; +- struct atl1c_rfd_ring rfd_ring[AT_MAX_RECEIVE_QUEUE]; +- struct atl1c_rrd_ring rrd_ring[AT_MAX_RECEIVE_QUEUE]; +- struct atl1c_cmb cmb; +- struct atl1c_smb smb; +- int num_rx_queues; +- u32 bd_number; /* board number;*/ +-}; +- +-#define AT_WRITE_REG(a, reg, value) ( \ +- writel((value), ((a)->hw_addr + reg))) +- +-#define AT_WRITE_FLUSH(a) (\ +- readl((a)->hw_addr)) +- +-#define AT_READ_REG(a, reg, pdata) do { \ +- if (unlikely((a)->hibernate)) { \ +- readl((a)->hw_addr + reg); \ +- *(u32 *)pdata = readl((a)->hw_addr + reg); \ +- } else { \ +- *(u32 *)pdata = readl((a)->hw_addr + reg); \ +- } \ +- } while (0) +- +-#define AT_WRITE_REGB(a, reg, value) (\ +- writeb((value), ((a)->hw_addr + reg))) +- +-#define AT_READ_REGB(a, reg) (\ +- readb((a)->hw_addr + reg)) +- +-#define AT_WRITE_REGW(a, reg, value) (\ +- writew((value), ((a)->hw_addr + reg))) +- +-#define AT_READ_REGW(a, reg) (\ +- readw((a)->hw_addr + reg)) +- +-#define AT_WRITE_REG_ARRAY(a, reg, offset, value) ( \ +- writel((value), (((a)->hw_addr + reg) + ((offset) << 2)))) +- +-#define AT_READ_REG_ARRAY(a, reg, offset) ( \ +- readl(((a)->hw_addr + reg) + ((offset) << 2))) +- +-extern char atl1c_driver_name[]; +-extern char atl1c_driver_version[]; +- +-extern int atl1c_up(struct atl1c_adapter *adapter); +-extern void atl1c_down(struct atl1c_adapter *adapter); +-extern void atl1c_reinit_locked(struct atl1c_adapter *adapter); +-extern s32 atl1c_reset_hw(struct atl1c_hw *hw); +-extern void atl1c_set_ethtool_ops(struct net_device *netdev); +-#endif /* _ATL1C_H_ */ +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/drivers/net/atl1c/atl1c_hw.c linux-2.6.29-rc3.owrt/drivers/net/atl1c/atl1c_hw.c +--- linux-2.6.29.owrt/drivers/net/atl1c/atl1c_hw.c 2009-05-10 22:04:38.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/drivers/net/atl1c/atl1c_hw.c 1970-01-01 01:00:00.000000000 +0100 +@@ -1,527 +0,0 @@ +-/* +- * Copyright(c) 2007 Atheros Corporation. All rights reserved. +- * +- * Derived from Intel e1000 driver +- * Copyright(c) 1999 - 2005 Intel Corporation. All rights reserved. +- * +- * 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, MA 02111-1307, USA. +- */ +-#include <linux/pci.h> +-#include <linux/delay.h> +-#include <linux/mii.h> +-#include <linux/crc32.h> +- +-#include "atl1c.h" +- +-/* +- * check_eeprom_exist +- * return 1 if eeprom exist +- */ +-int atl1c_check_eeprom_exist(struct atl1c_hw *hw) +-{ +- u32 data; +- +- AT_READ_REG(hw, REG_TWSI_DEBUG, &data); +- if (data & TWSI_DEBUG_DEV_EXIST) +- return 1; +- +- return 0; +-} +- +-void atl1c_hw_set_mac_addr(struct atl1c_hw *hw) +-{ +- u32 value; +- /* +- * 00-0B-6A-F6-00-DC +- * 0: 6AF600DC 1: 000B +- * low dword +- */ +- value = (((u32)hw->mac_addr[2]) << 24) | +- (((u32)hw->mac_addr[3]) << 16) | +- (((u32)hw->mac_addr[4]) << 8) | +- (((u32)hw->mac_addr[5])) ; +- AT_WRITE_REG_ARRAY(hw, REG_MAC_STA_ADDR, 0, value); +- /* hight dword */ +- value = (((u32)hw->mac_addr[0]) << 8) | +- (((u32)hw->mac_addr[1])) ; +- AT_WRITE_REG_ARRAY(hw, REG_MAC_STA_ADDR, 1, value); +-} +- +-/* +- * atl1c_get_permanent_address +- * return 0 if get valid mac address, +- */ +-static int atl1c_get_permanent_address(struct atl1c_hw *hw) +-{ +- u32 addr[2]; +- u32 i; +- u32 otp_ctrl_data; +- u32 twsi_ctrl_data; +- u8 eth_addr[ETH_ALEN]; +- +- /* init */ +- addr[0] = addr[1] = 0; +- AT_READ_REG(hw, REG_OTP_CTRL, &otp_ctrl_data); +- if (atl1c_check_eeprom_exist(hw)) { +- /* Enable OTP CLK */ +- if (!(otp_ctrl_data & OTP_CTRL_CLK_EN)) { +- otp_ctrl_data |= OTP_CTRL_CLK_EN; +- AT_WRITE_REG(hw, REG_OTP_CTRL, otp_ctrl_data); +- AT_WRITE_FLUSH(hw); +- msleep(1); +- } +- +- AT_READ_REG(hw, REG_TWSI_CTRL, &twsi_ctrl_data); +- twsi_ctrl_data |= TWSI_CTRL_SW_LDSTART; +- AT_WRITE_REG(hw, REG_TWSI_CTRL, twsi_ctrl_data); +- for (i = 0; i < AT_TWSI_EEPROM_TIMEOUT; i++) { +- msleep(10); +- AT_READ_REG(hw, REG_TWSI_CTRL, &twsi_ctrl_data); +- if ((twsi_ctrl_data & TWSI_CTRL_SW_LDSTART) == 0) +- break; +- } +- if (i >= AT_TWSI_EEPROM_TIMEOUT) +- return -1; +- } +- /* Disable OTP_CLK */ +- if (otp_ctrl_data & OTP_CTRL_CLK_EN) { +- otp_ctrl_data &= ~OTP_CTRL_CLK_EN; +- AT_WRITE_REG(hw, REG_OTP_CTRL, otp_ctrl_data); +- AT_WRITE_FLUSH(hw); +- msleep(1); +- } +- +- /* maybe MAC-address is from BIOS */ +- AT_READ_REG(hw, REG_MAC_STA_ADDR, &addr[0]); +- AT_READ_REG(hw, REG_MAC_STA_ADDR + 4, &addr[1]); +- *(u32 *) ð_addr[2] = swab32(addr[0]); +- *(u16 *) ð_addr[0] = swab16(*(u16 *)&addr[1]); +- +- if (is_valid_ether_addr(eth_addr)) { +- memcpy(hw->perm_mac_addr, eth_addr, ETH_ALEN); +- return 0; +- } +- +- return -1; +-} +- +-bool atl1c_read_eeprom(struct atl1c_hw *hw, u32 offset, u32 *p_value) +-{ +- int i; +- int ret = false; +- u32 otp_ctrl_data; +- u32 control; +- u32 data; +- +- if (offset & 3) +- return ret; /* address do not align */ +- +- AT_READ_REG(hw, REG_OTP_CTRL, &otp_ctrl_data); +- if (!(otp_ctrl_data & OTP_CTRL_CLK_EN)) +- AT_WRITE_REG(hw, REG_OTP_CTRL, +- (otp_ctrl_data | OTP_CTRL_CLK_EN)); +- +- AT_WRITE_REG(hw, REG_EEPROM_DATA_LO, 0); +- control = (offset & EEPROM_CTRL_ADDR_MASK) << EEPROM_CTRL_ADDR_SHIFT; +- AT_WRITE_REG(hw, REG_EEPROM_CTRL, control); +- +- for (i = 0; i < 10; i++) { +- udelay(100); +- AT_READ_REG(hw, REG_EEPROM_CTRL, &control); +- if (control & EEPROM_CTRL_RW) +- break; +- } +- if (control & EEPROM_CTRL_RW) { +- AT_READ_REG(hw, REG_EEPROM_CTRL, &data); +- AT_READ_REG(hw, REG_EEPROM_DATA_LO, p_value); +- data = data & 0xFFFF; +- *p_value = swab32((data << 16) | (*p_value >> 16)); +- ret = true; +- } +- if (!(otp_ctrl_data & OTP_CTRL_CLK_EN)) +- AT_WRITE_REG(hw, REG_OTP_CTRL, otp_ctrl_data); +- +- return ret; +-} +-/* +- * Reads the adapter's MAC address from the EEPROM +- * +- * hw - Struct containing variables accessed by shared code +- */ +-int atl1c_read_mac_addr(struct atl1c_hw *hw) +-{ +- int err = 0; +- +- err = atl1c_get_permanent_address(hw); +- if (err) +- random_ether_addr(hw->perm_mac_addr); +- +- memcpy(hw->mac_addr, hw->perm_mac_addr, sizeof(hw->perm_mac_addr)); +- return 0; +-} +- +-/* +- * atl1c_hash_mc_addr +- * purpose +- * set hash value for a multicast address +- * hash calcu processing : +- * 1. calcu 32bit CRC for multicast address +- * 2. reverse crc with MSB to LSB +- */ +-u32 atl1c_hash_mc_addr(struct atl1c_hw *hw, u8 *mc_addr) +-{ +- u32 crc32; +- u32 value = 0; +- int i; +- +- crc32 = ether_crc_le(6, mc_addr); +- for (i = 0; i < 32; i++) +- value |= (((crc32 >> i) & 1) << (31 - i)); +- +- return value; +-} +- +-/* +- * Sets the bit in the multicast table corresponding to the hash value. +- * hw - Struct containing variables accessed by shared code +- * hash_value - Multicast address hash value +- */ +-void atl1c_hash_set(struct atl1c_hw *hw, u32 hash_value) +-{ +- u32 hash_bit, hash_reg; +- u32 mta; +- +- /* +- * The HASH Table is a register array of 2 32-bit registers. +- * It is treated like an array of 64 bits. We want to set +- * bit BitArray[hash_value]. So we figure out what register +- * the bit is in, read it, OR in the new bit, then write +- * back the new value. The register is determined by the +- * upper bit of the hash value and the bit within that +- * register are determined by the lower 5 bits of the value. +- */ +- hash_reg = (hash_value >> 31) & 0x1; +- hash_bit = (hash_value >> 26) & 0x1F; +- +- mta = AT_READ_REG_ARRAY(hw, REG_RX_HASH_TABLE, hash_reg); +- +- mta |= (1 << hash_bit); +- +- AT_WRITE_REG_ARRAY(hw, REG_RX_HASH_TABLE, hash_reg, mta); +-} +- +-/* +- * Reads the value from a PHY register +- * hw - Struct containing variables accessed by shared code +- * reg_addr - address of the PHY register to read +- */ +-int atl1c_read_phy_reg(struct atl1c_hw *hw, u16 reg_addr, u16 *phy_data) +-{ +- u32 val; +- int i; +- +- val = ((u32)(reg_addr & MDIO_REG_ADDR_MASK)) << MDIO_REG_ADDR_SHIFT | +- MDIO_START | MDIO_SUP_PREAMBLE | MDIO_RW | +- MDIO_CLK_25_4 << MDIO_CLK_SEL_SHIFT; +- +- AT_WRITE_REG(hw, REG_MDIO_CTRL, val); +- +- for (i = 0; i < MDIO_WAIT_TIMES; i++) { +- udelay(2); +- AT_READ_REG(hw, REG_MDIO_CTRL, &val); +- if (!(val & (MDIO_START | MDIO_BUSY))) +- break; +- } +- if (!(val & (MDIO_START | MDIO_BUSY))) { +- *phy_data = (u16)val; +- return 0; +- } +- +- return -1; +-} +- +-/* +- * Writes a value to a PHY register +- * hw - Struct containing variables accessed by shared code +- * reg_addr - address of the PHY register to write +- * data - data to write to the PHY +- */ +-int atl1c_write_phy_reg(struct atl1c_hw *hw, u32 reg_addr, u16 phy_data) +-{ +- int i; +- u32 val; +- +- val = ((u32)(phy_data & MDIO_DATA_MASK)) << MDIO_DATA_SHIFT | +- (reg_addr & MDIO_REG_ADDR_MASK) << MDIO_REG_ADDR_SHIFT | +- MDIO_SUP_PREAMBLE | MDIO_START | +- MDIO_CLK_25_4 << MDIO_CLK_SEL_SHIFT; +- +- AT_WRITE_REG(hw, REG_MDIO_CTRL, val); +- +- for (i = 0; i < MDIO_WAIT_TIMES; i++) { +- udelay(2); +- AT_READ_REG(hw, REG_MDIO_CTRL, &val); +- if (!(val & (MDIO_START | MDIO_BUSY))) +- break; +- } +- +- if (!(val & (MDIO_START | MDIO_BUSY))) +- return 0; +- +- return -1; +-} +- +-/* +- * Configures PHY autoneg and flow control advertisement settings +- * +- * hw - Struct containing variables accessed by shared code +- */ +-static int atl1c_phy_setup_adv(struct atl1c_hw *hw) +-{ +- u16 mii_adv_data = ADVERTISE_DEFAULT_CAP & ~ADVERTISE_SPEED_MASK; +- u16 mii_giga_ctrl_data = GIGA_CR_1000T_DEFAULT_CAP & +- ~GIGA_CR_1000T_SPEED_MASK; +- +- if (hw->autoneg_advertised & ADVERTISED_10baseT_Half) +- mii_adv_data |= ADVERTISE_10HALF; +- if (hw->autoneg_advertised & ADVERTISED_10baseT_Full) +- mii_adv_data |= ADVERTISE_10FULL; +- if (hw->autoneg_advertised & ADVERTISED_100baseT_Half) +- mii_adv_data |= ADVERTISE_100HALF; +- if (hw->autoneg_advertised & ADVERTISED_100baseT_Full) +- mii_adv_data |= ADVERTISE_100FULL; +- +- if (hw->autoneg_advertised & ADVERTISED_Autoneg) +- mii_adv_data |= ADVERTISE_10HALF | ADVERTISE_10FULL | +- ADVERTISE_100HALF | ADVERTISE_100FULL; +- +- if (hw->ctrl_flags & ATL1C_LINK_CAP_1000M) { +- if (hw->autoneg_advertised & ADVERTISED_1000baseT_Half) +- mii_giga_ctrl_data |= ADVERTISE_1000HALF; +- if (hw->autoneg_advertised & ADVERTISED_1000baseT_Full) +- mii_giga_ctrl_data |= ADVERTISE_1000FULL; +- if (hw->autoneg_advertised & ADVERTISED_Autoneg) +- mii_giga_ctrl_data |= ADVERTISE_1000HALF | +- ADVERTISE_1000FULL; +- } +- +- if (atl1c_write_phy_reg(hw, MII_ADVERTISE, mii_adv_data) != 0 || +- atl1c_write_phy_reg(hw, MII_GIGA_CR, mii_giga_ctrl_data) != 0) +- return -1; +- return 0; +-} +- +-void atl1c_phy_disable(struct atl1c_hw *hw) +-{ +- AT_WRITE_REGW(hw, REG_GPHY_CTRL, +- GPHY_CTRL_PW_WOL_DIS | GPHY_CTRL_EXT_RESET); +-} +- +-static void atl1c_phy_magic_data(struct atl1c_hw *hw) +-{ +- u16 data; +- +- data = ANA_LOOP_SEL_10BT | ANA_EN_MASK_TB | ANA_EN_10BT_IDLE | +- ((1 & ANA_INTERVAL_SEL_TIMER_MASK) << +- ANA_INTERVAL_SEL_TIMER_SHIFT); +- +- atl1c_write_phy_reg(hw, MII_DBG_ADDR, MII_ANA_CTRL_18); +- atl1c_write_phy_reg(hw, MII_DBG_DATA, data); +- +- data = (2 & ANA_SERDES_CDR_BW_MASK) | ANA_MS_PAD_DBG | +- ANA_SERDES_EN_DEEM | ANA_SERDES_SEL_HSP | ANA_SERDES_EN_PLL | +- ANA_SERDES_EN_LCKDT; +- +- atl1c_write_phy_reg(hw, MII_DBG_ADDR, MII_ANA_CTRL_5); +- atl1c_write_phy_reg(hw, MII_DBG_DATA, data); +- +- data = (44 & ANA_LONG_CABLE_TH_100_MASK) | +- ((33 & ANA_SHORT_CABLE_TH_100_MASK) << +- ANA_SHORT_CABLE_TH_100_SHIFT) | ANA_BP_BAD_LINK_ACCUM | +- ANA_BP_SMALL_BW; +- +- atl1c_write_phy_reg(hw, MII_DBG_ADDR, MII_ANA_CTRL_54); +- atl1c_write_phy_reg(hw, MII_DBG_DATA, data); +- +- data = (11 & ANA_IECHO_ADJ_MASK) | ((11 & ANA_IECHO_ADJ_MASK) << +- ANA_IECHO_ADJ_2_SHIFT) | ((8 & ANA_IECHO_ADJ_MASK) << +- ANA_IECHO_ADJ_1_SHIFT) | ((8 & ANA_IECHO_ADJ_MASK) << +- ANA_IECHO_ADJ_0_SHIFT); +- +- atl1c_write_phy_reg(hw, MII_DBG_ADDR, MII_ANA_CTRL_4); +- atl1c_write_phy_reg(hw, MII_DBG_DATA, data); +- +- data = ANA_RESTART_CAL | ((7 & ANA_MANUL_SWICH_ON_MASK) << +- ANA_MANUL_SWICH_ON_SHIFT) | ANA_MAN_ENABLE | +- ANA_SEL_HSP | ANA_EN_HB | ANA_OEN_125M; +- +- atl1c_write_phy_reg(hw, MII_DBG_ADDR, MII_ANA_CTRL_0); +- atl1c_write_phy_reg(hw, MII_DBG_DATA, data); +- +- if (hw->ctrl_flags & ATL1C_HIB_DISABLE) { +- atl1c_write_phy_reg(hw, MII_DBG_ADDR, MII_ANA_CTRL_41); +- if (atl1c_read_phy_reg(hw, MII_DBG_DATA, &data) != 0) +- return; +- data &= ~ANA_TOP_PS_EN; +- atl1c_write_phy_reg(hw, MII_DBG_DATA, data); +- +- atl1c_write_phy_reg(hw, MII_DBG_ADDR, MII_ANA_CTRL_11); +- if (atl1c_read_phy_reg(hw, MII_DBG_DATA, &data) != 0) +- return; +- data &= ~ANA_PS_HIB_EN; +- atl1c_write_phy_reg(hw, MII_DBG_DATA, data); +- } +-} +- +-int atl1c_phy_reset(struct atl1c_hw *hw) +-{ +- struct atl1c_adapter *adapter = hw->adapter; +- struct pci_dev *pdev = adapter->pdev; +- u32 phy_ctrl_data = GPHY_CTRL_DEFAULT; +- u32 mii_ier_data = IER_LINK_UP | IER_LINK_DOWN; +- int err; +- +- if (hw->ctrl_flags & ATL1C_HIB_DISABLE) +- phy_ctrl_data &= ~GPHY_CTRL_HIB_EN; +- +- AT_WRITE_REG(hw, REG_GPHY_CTRL, phy_ctrl_data); +- AT_WRITE_FLUSH(hw); +- msleep(40); +- phy_ctrl_data |= GPHY_CTRL_EXT_RESET; +- AT_WRITE_REG(hw, REG_GPHY_CTRL, phy_ctrl_data); +- AT_WRITE_FLUSH(hw); +- msleep(10); +- +- /*Enable PHY LinkChange Interrupt */ +- err = atl1c_write_phy_reg(hw, MII_IER, mii_ier_data); +- if (err) { +- if (netif_msg_hw(adapter)) +- dev_err(&pdev->dev, +- "Error enable PHY linkChange Interrupt\n"); +- return err; +- } +- if (!(hw->ctrl_flags & ATL1C_FPGA_VERSION)) +- atl1c_phy_magic_data(hw); +- return 0; +-} +- +-int atl1c_phy_init(struct atl1c_hw *hw) +-{ +- struct atl1c_adapter *adapter = (struct atl1c_adapter *)hw->adapter; +- struct pci_dev *pdev = adapter->pdev; +- int ret_val; +- u16 mii_bmcr_data = BMCR_RESET; +- u16 phy_id1, phy_id2; +- +- if ((atl1c_read_phy_reg(hw, MII_PHYSID1, &phy_id1) != 0) || +- (atl1c_read_phy_reg(hw, MII_PHYSID2, &phy_id2) != 0)) { +- if (netif_msg_link(adapter)) +- dev_err(&pdev->dev, "Error get phy ID\n"); +- return -1; +- } +- switch (hw->media_type) { +- case MEDIA_TYPE_AUTO_SENSOR: +- ret_val = atl1c_phy_setup_adv(hw); +- if (ret_val) { +- if (netif_msg_link(adapter)) +- dev_err(&pdev->dev, +- "Error Setting up Auto-Negotiation\n"); +- return ret_val; +- } +- mii_bmcr_data |= BMCR_AUTO_NEG_EN | BMCR_RESTART_AUTO_NEG; +- break; +- case MEDIA_TYPE_100M_FULL: +- mii_bmcr_data |= BMCR_SPEED_100 | BMCR_FULL_DUPLEX; +- break; +- case MEDIA_TYPE_100M_HALF: +- mii_bmcr_data |= BMCR_SPEED_100; +- break; +- case MEDIA_TYPE_10M_FULL: +- mii_bmcr_data |= BMCR_SPEED_10 | BMCR_FULL_DUPLEX; +- break; +- case MEDIA_TYPE_10M_HALF: +- mii_bmcr_data |= BMCR_SPEED_10; +- break; +- default: +- if (netif_msg_link(adapter)) +- dev_err(&pdev->dev, "Wrong Media type %d\n", +- hw->media_type); +- return -1; +- break; +- } +- +- ret_val = atl1c_write_phy_reg(hw, MII_BMCR, mii_bmcr_data); +- if (ret_val) +- return ret_val; +- hw->phy_configured = true; +- +- return 0; +-} +- +-/* +- * Detects the current speed and duplex settings of the hardware. +- * +- * hw - Struct containing variables accessed by shared code +- * speed - Speed of the connection +- * duplex - Duplex setting of the connection +- */ +-int atl1c_get_speed_and_duplex(struct atl1c_hw *hw, u16 *speed, u16 *duplex) +-{ +- int err; +- u16 phy_data; +- +- /* Read PHY Specific Status Register (17) */ +- err = atl1c_read_phy_reg(hw, MII_GIGA_PSSR, &phy_data); +- if (err) +- return err; +- +- if (!(phy_data & GIGA_PSSR_SPD_DPLX_RESOLVED)) +- return -1; +- +- switch (phy_data & GIGA_PSSR_SPEED) { +- case GIGA_PSSR_1000MBS: +- *speed = SPEED_1000; +- break; +- case GIGA_PSSR_100MBS: +- *speed = SPEED_100; +- break; +- case GIGA_PSSR_10MBS: +- *speed = SPEED_10; +- break; +- default: +- return -1; +- break; +- } +- +- if (phy_data & GIGA_PSSR_DPLX) +- *duplex = FULL_DUPLEX; +- else +- *duplex = HALF_DUPLEX; +- +- return 0; +-} +- +-int atl1c_restart_autoneg(struct atl1c_hw *hw) +-{ +- int err = 0; +- u16 mii_bmcr_data = BMCR_RESET; +- +- err = atl1c_phy_setup_adv(hw); +- if (err) +- return err; +- mii_bmcr_data |= BMCR_AUTO_NEG_EN | BMCR_RESTART_AUTO_NEG; +- +- return atl1c_write_phy_reg(hw, MII_BMCR, mii_bmcr_data); +-} +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/drivers/net/atl1c/atl1c_hw.h linux-2.6.29-rc3.owrt/drivers/net/atl1c/atl1c_hw.h +--- linux-2.6.29.owrt/drivers/net/atl1c/atl1c_hw.h 2009-05-10 22:04:38.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/drivers/net/atl1c/atl1c_hw.h 1970-01-01 01:00:00.000000000 +0100 +@@ -1,859 +0,0 @@ +-/* +- * Copyright(c) 2008 - 2009 Atheros Corporation. All rights reserved. +- * +- * Derived from Intel e1000 driver +- * Copyright(c) 1999 - 2005 Intel Corporation. All rights reserved. +- * +- * 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, MA 02111-1307, USA. +- */ +- +-#ifndef _ATL1C_HW_H_ +-#define _ATL1C_HW_H_ +- +-#include <linux/types.h> +-#include <linux/mii.h> +- +-struct atl1c_adapter; +-struct atl1c_hw; +- +-/* function prototype */ +-void atl1c_phy_disable(struct atl1c_hw *hw); +-void atl1c_hw_set_mac_addr(struct atl1c_hw *hw); +-int atl1c_phy_reset(struct atl1c_hw *hw); +-int atl1c_read_mac_addr(struct atl1c_hw *hw); +-int atl1c_get_speed_and_duplex(struct atl1c_hw *hw, u16 *speed, u16 *duplex); +-u32 atl1c_hash_mc_addr(struct atl1c_hw *hw, u8 *mc_addr); +-void atl1c_hash_set(struct atl1c_hw *hw, u32 hash_value); +-int atl1c_read_phy_reg(struct atl1c_hw *hw, u16 reg_addr, u16 *phy_data); +-int atl1c_write_phy_reg(struct atl1c_hw *hw, u32 reg_addr, u16 phy_data); +-bool atl1c_read_eeprom(struct atl1c_hw *hw, u32 offset, u32 *p_value); +-int atl1c_phy_init(struct atl1c_hw *hw); +-int atl1c_check_eeprom_exist(struct atl1c_hw *hw); +-int atl1c_restart_autoneg(struct atl1c_hw *hw); +- +-/* register definition */ +-#define REG_DEVICE_CAP 0x5C +-#define DEVICE_CAP_MAX_PAYLOAD_MASK 0x7 +-#define DEVICE_CAP_MAX_PAYLOAD_SHIFT 0 +- +-#define REG_DEVICE_CTRL 0x60 +-#define DEVICE_CTRL_MAX_PAYLOAD_MASK 0x7 +-#define DEVICE_CTRL_MAX_PAYLOAD_SHIFT 5 +-#define DEVICE_CTRL_MAX_RREQ_SZ_MASK 0x7 +-#define DEVICE_CTRL_MAX_RREQ_SZ_SHIFT 12 +- +-#define REG_LINK_CTRL 0x68 +-#define LINK_CTRL_L0S_EN 0x01 +-#define LINK_CTRL_L1_EN 0x02 +- +-#define REG_VPD_CAP 0x6C +-#define VPD_CAP_ID_MASK 0xff +-#define VPD_CAP_ID_SHIFT 0 +-#define VPD_CAP_NEXT_PTR_MASK 0xFF +-#define VPD_CAP_NEXT_PTR_SHIFT 8 +-#define VPD_CAP_VPD_ADDR_MASK 0x7FFF +-#define VPD_CAP_VPD_ADDR_SHIFT 16 +-#define VPD_CAP_VPD_FLAG 0x80000000 +- +-#define REG_VPD_DATA 0x70 +- +-#define REG_PCIE_UC_SEVERITY 0x10C +-#define PCIE_UC_SERVRITY_TRN 0x00000001 +-#define PCIE_UC_SERVRITY_DLP 0x00000010 +-#define PCIE_UC_SERVRITY_PSN_TLP 0x00001000 +-#define PCIE_UC_SERVRITY_FCP 0x00002000 +-#define PCIE_UC_SERVRITY_CPL_TO 0x00004000 +-#define PCIE_UC_SERVRITY_CA 0x00008000 +-#define PCIE_UC_SERVRITY_UC 0x00010000 +-#define PCIE_UC_SERVRITY_ROV 0x00020000 +-#define PCIE_UC_SERVRITY_MLFP 0x00040000 +-#define PCIE_UC_SERVRITY_ECRC 0x00080000 +-#define PCIE_UC_SERVRITY_UR 0x00100000 +- +-#define REG_DEV_SERIALNUM_CTRL 0x200 +-#define REG_DEV_MAC_SEL_MASK 0x0 /* 0:EUI; 1:MAC */ +-#define REG_DEV_MAC_SEL_SHIFT 0 +-#define REG_DEV_SERIAL_NUM_EN_MASK 0x1 +-#define REG_DEV_SERIAL_NUM_EN_SHIFT 1 +- +-#define REG_TWSI_CTRL 0x218 +-#define TWSI_CTRL_LD_OFFSET_MASK 0xFF +-#define TWSI_CTRL_LD_OFFSET_SHIFT 0 +-#define TWSI_CTRL_LD_SLV_ADDR_MASK 0x7 +-#define TWSI_CTRL_LD_SLV_ADDR_SHIFT 8 +-#define TWSI_CTRL_SW_LDSTART 0x800 +-#define TWSI_CTRL_HW_LDSTART 0x1000 +-#define TWSI_CTRL_SMB_SLV_ADDR_MASK 0x7F +-#define TWSI_CTRL_SMB_SLV_ADDR_SHIFT 15 +-#define TWSI_CTRL_LD_EXIST 0x400000 +-#define TWSI_CTRL_READ_FREQ_SEL_MASK 0x3 +-#define TWSI_CTRL_READ_FREQ_SEL_SHIFT 23 +-#define TWSI_CTRL_FREQ_SEL_100K 0 +-#define TWSI_CTRL_FREQ_SEL_200K 1 +-#define TWSI_CTRL_FREQ_SEL_300K 2 +-#define TWSI_CTRL_FREQ_SEL_400K 3 +-#define TWSI_CTRL_SMB_SLV_ADDR +-#define TWSI_CTRL_WRITE_FREQ_SEL_MASK 0x3 +-#define TWSI_CTRL_WRITE_FREQ_SEL_SHIFT 24 +- +- +-#define REG_PCIE_DEV_MISC_CTRL 0x21C +-#define PCIE_DEV_MISC_EXT_PIPE 0x2 +-#define PCIE_DEV_MISC_RETRY_BUFDIS 0x1 +-#define PCIE_DEV_MISC_SPIROM_EXIST 0x4 +-#define PCIE_DEV_MISC_SERDES_ENDIAN 0x8 +-#define PCIE_DEV_MISC_SERDES_SEL_DIN 0x10 +- +-#define REG_PCIE_PHYMISC 0x1000 +-#define PCIE_PHYMISC_FORCE_RCV_DET 0x4 +- +-#define REG_TWSI_DEBUG 0x1108 +-#define TWSI_DEBUG_DEV_EXIST 0x20000000 +- +-#define REG_EEPROM_CTRL 0x12C0 +-#define EEPROM_CTRL_DATA_HI_MASK 0xFFFF +-#define EEPROM_CTRL_DATA_HI_SHIFT 0 +-#define EEPROM_CTRL_ADDR_MASK 0x3FF +-#define EEPROM_CTRL_ADDR_SHIFT 16 +-#define EEPROM_CTRL_ACK 0x40000000 +-#define EEPROM_CTRL_RW 0x80000000 +- +-#define REG_EEPROM_DATA_LO 0x12C4 +- +-#define REG_OTP_CTRL 0x12F0 +-#define OTP_CTRL_CLK_EN 0x0002 +- +-#define REG_PM_CTRL 0x12F8 +-#define PM_CTRL_SDES_EN 0x00000001 +-#define PM_CTRL_RBER_EN 0x00000002 +-#define PM_CTRL_CLK_REQ_EN 0x00000004 +-#define PM_CTRL_ASPM_L1_EN 0x00000008 +-#define PM_CTRL_SERDES_L1_EN 0x00000010 +-#define PM_CTRL_SERDES_PLL_L1_EN 0x00000020 +-#define PM_CTRL_SERDES_PD_EX_L1 0x00000040 +-#define PM_CTRL_SERDES_BUDS_RX_L1_EN 0x00000080 +-#define PM_CTRL_L0S_ENTRY_TIMER_MASK 0xF +-#define PM_CTRL_L0S_ENTRY_TIMER_SHIFT 8 +-#define PM_CTRL_ASPM_L0S_EN 0x00001000 +-#define PM_CTRL_CLK_SWH_L1 0x00002000 +-#define PM_CTRL_CLK_PWM_VER1_1 0x00004000 +-#define PM_CTRL_PCIE_RECV 0x00008000 +-#define PM_CTRL_L1_ENTRY_TIMER_MASK 0xF +-#define PM_CTRL_L1_ENTRY_TIMER_SHIFT 16 +-#define PM_CTRL_PM_REQ_TIMER_MASK 0xF +-#define PM_CTRL_PM_REQ_TIMER_SHIFT 20 +-#define PM_CTRL_LCKDET_TIMER_MASK 0x3F +-#define PM_CTRL_LCKDET_TIMER_SHIFT 24 +-#define PM_CTRL_MAC_ASPM_CHK 0x40000000 +-#define PM_CTRL_HOTRST 0x80000000 +- +-/* Selene Master Control Register */ +-#define REG_MASTER_CTRL 0x1400 +-#define MASTER_CTRL_SOFT_RST 0x1 +-#define MASTER_CTRL_TEST_MODE_MASK 0x3 +-#define MASTER_CTRL_TEST_MODE_SHIFT 2 +-#define MASTER_CTRL_BERT_START 0x10 +-#define MASTER_CTRL_MTIMER_EN 0x100 +-#define MASTER_CTRL_MANUAL_INT 0x200 +-#define MASTER_CTRL_TX_ITIMER_EN 0x400 +-#define MASTER_CTRL_RX_ITIMER_EN 0x800 +-#define MASTER_CTRL_CLK_SEL_DIS 0x1000 +-#define MASTER_CTRL_CLK_SWH_MODE 0x2000 +-#define MASTER_CTRL_INT_RDCLR 0x4000 +-#define MASTER_CTRL_REV_NUM_SHIFT 16 +-#define MASTER_CTRL_REV_NUM_MASK 0xff +-#define MASTER_CTRL_DEV_ID_SHIFT 24 +-#define MASTER_CTRL_DEV_ID_MASK 0x7f +-#define MASTER_CTRL_OTP_SEL 0x80000000 +- +-/* Timer Initial Value Register */ +-#define REG_MANUAL_TIMER_INIT 0x1404 +- +-/* IRQ ModeratorTimer Initial Value Register */ +-#define REG_IRQ_MODRT_TIMER_INIT 0x1408 +-#define IRQ_MODRT_TIMER_MASK 0xffff +-#define IRQ_MODRT_TX_TIMER_SHIFT 0 +-#define IRQ_MODRT_RX_TIMER_SHIFT 16 +- +-#define REG_GPHY_CTRL 0x140C +-#define GPHY_CTRL_EXT_RESET 0x1 +-#define GPHY_CTRL_RTL_MODE 0x2 +-#define GPHY_CTRL_LED_MODE 0x4 +-#define GPHY_CTRL_ANEG_NOW 0x8 +-#define GPHY_CTRL_REV_ANEG 0x10 +-#define GPHY_CTRL_GATE_25M_EN 0x20 +-#define GPHY_CTRL_LPW_EXIT 0x40 +-#define GPHY_CTRL_PHY_IDDQ 0x80 +-#define GPHY_CTRL_PHY_IDDQ_DIS 0x100 +-#define GPHY_CTRL_GIGA_DIS 0x200 +-#define GPHY_CTRL_HIB_EN 0x400 +-#define GPHY_CTRL_HIB_PULSE 0x800 +-#define GPHY_CTRL_SEL_ANA_RST 0x1000 +-#define GPHY_CTRL_PHY_PLL_ON 0x2000 +-#define GPHY_CTRL_PWDOWN_HW 0x4000 +-#define GPHY_CTRL_PHY_PLL_BYPASS 0x8000 +- +-#define GPHY_CTRL_DEFAULT ( \ +- GPHY_CTRL_SEL_ANA_RST |\ +- GPHY_CTRL_HIB_PULSE |\ +- GPHY_CTRL_HIB_EN) +- +-#define GPHY_CTRL_PW_WOL_DIS ( \ +- GPHY_CTRL_SEL_ANA_RST |\ +- GPHY_CTRL_HIB_PULSE |\ +- GPHY_CTRL_HIB_EN |\ +- GPHY_CTRL_PWDOWN_HW |\ +- GPHY_CTRL_PHY_IDDQ) +- +-/* Block IDLE Status Register */ +-#define REG_IDLE_STATUS 0x1410 +-#define IDLE_STATUS_MASK 0x00FF +-#define IDLE_STATUS_RXMAC_NO_IDLE 0x1 +-#define IDLE_STATUS_TXMAC_NO_IDLE 0x2 +-#define IDLE_STATUS_RXQ_NO_IDLE 0x4 +-#define IDLE_STATUS_TXQ_NO_IDLE 0x8 +-#define IDLE_STATUS_DMAR_NO_IDLE 0x10 +-#define IDLE_STATUS_DMAW_NO_IDLE 0x20 +-#define IDLE_STATUS_SMB_NO_IDLE 0x40 +-#define IDLE_STATUS_CMB_NO_IDLE 0x80 +- +-/* MDIO Control Register */ +-#define REG_MDIO_CTRL 0x1414 +-#define MDIO_DATA_MASK 0xffff /* On MDIO write, the 16-bit +- * control data to write to PHY +- * MII management register */ +-#define MDIO_DATA_SHIFT 0 /* On MDIO read, the 16-bit +- * status data that was read +- * from the PHY MII management register */ +-#define MDIO_REG_ADDR_MASK 0x1f /* MDIO register address */ +-#define MDIO_REG_ADDR_SHIFT 16 +-#define MDIO_RW 0x200000 /* 1: read, 0: write */ +-#define MDIO_SUP_PREAMBLE 0x400000 /* Suppress preamble */ +-#define MDIO_START 0x800000 /* Write 1 to initiate the MDIO +- * master. And this bit is self +- * cleared after one cycle */ +-#define MDIO_CLK_SEL_SHIFT 24 +-#define MDIO_CLK_25_4 0 +-#define MDIO_CLK_25_6 2 +-#define MDIO_CLK_25_8 3 +-#define MDIO_CLK_25_10 4 +-#define MDIO_CLK_25_14 5 +-#define MDIO_CLK_25_20 6 +-#define MDIO_CLK_25_28 7 +-#define MDIO_BUSY 0x8000000 +-#define MDIO_AP_EN 0x10000000 +-#define MDIO_WAIT_TIMES 10 +- +-/* MII PHY Status Register */ +-#define REG_PHY_STATUS 0x1418 +-#define PHY_GENERAL_STATUS_MASK 0xFFFF +-#define PHY_STATUS_RECV_ENABLE 0x0001 +-#define PHY_OE_PWSP_STATUS_MASK 0x07FF +-#define PHY_OE_PWSP_STATUS_SHIFT 16 +-#define PHY_STATUS_LPW_STATE 0x80000000 +-/* BIST Control and Status Register0 (for the Packet Memory) */ +-#define REG_BIST0_CTRL 0x141c +-#define BIST0_NOW 0x1 +-#define BIST0_SRAM_FAIL 0x2 /* 1: The SRAM failure is +- * un-repairable because +- * it has address decoder +- * failure or more than 1 cell +- * stuck-to-x failure */ +-#define BIST0_FUSE_FLAG 0x4 +- +-/* BIST Control and Status Register1(for the retry buffer of PCI Express) */ +-#define REG_BIST1_CTRL 0x1420 +-#define BIST1_NOW 0x1 +-#define BIST1_SRAM_FAIL 0x2 +-#define BIST1_FUSE_FLAG 0x4 +- +-/* SerDes Lock Detect Control and Status Register */ +-#define REG_SERDES_LOCK 0x1424 +-#define SERDES_LOCK_DETECT 0x1 /* SerDes lock detected. This signal +- * comes from Analog SerDes */ +-#define SERDES_LOCK_DETECT_EN 0x2 /* 1: Enable SerDes Lock detect function */ +- +-/* MAC Control Register */ +-#define REG_MAC_CTRL 0x1480 +-#define MAC_CTRL_TX_EN 0x1 +-#define MAC_CTRL_RX_EN 0x2 +-#define MAC_CTRL_TX_FLOW 0x4 +-#define MAC_CTRL_RX_FLOW 0x8 +-#define MAC_CTRL_LOOPBACK 0x10 +-#define MAC_CTRL_DUPLX 0x20 +-#define MAC_CTRL_ADD_CRC 0x40 +-#define MAC_CTRL_PAD 0x80 +-#define MAC_CTRL_LENCHK 0x100 +-#define MAC_CTRL_HUGE_EN 0x200 +-#define MAC_CTRL_PRMLEN_SHIFT 10 +-#define MAC_CTRL_PRMLEN_MASK 0xf +-#define MAC_CTRL_RMV_VLAN 0x4000 +-#define MAC_CTRL_PROMIS_EN 0x8000 +-#define MAC_CTRL_TX_PAUSE 0x10000 +-#define MAC_CTRL_SCNT 0x20000 +-#define MAC_CTRL_SRST_TX 0x40000 +-#define MAC_CTRL_TX_SIMURST 0x80000 +-#define MAC_CTRL_SPEED_SHIFT 20 +-#define MAC_CTRL_SPEED_MASK 0x3 +-#define MAC_CTRL_DBG_TX_BKPRESURE 0x400000 +-#define MAC_CTRL_TX_HUGE 0x800000 +-#define MAC_CTRL_RX_CHKSUM_EN 0x1000000 +-#define MAC_CTRL_MC_ALL_EN 0x2000000 +-#define MAC_CTRL_BC_EN 0x4000000 +-#define MAC_CTRL_DBG 0x8000000 +-#define MAC_CTRL_SINGLE_PAUSE_EN 0x10000000 +- +-/* MAC IPG/IFG Control Register */ +-#define REG_MAC_IPG_IFG 0x1484 +-#define MAC_IPG_IFG_IPGT_SHIFT 0 /* Desired back to back +- * inter-packet gap. The +- * default is 96-bit time */ +-#define MAC_IPG_IFG_IPGT_MASK 0x7f +-#define MAC_IPG_IFG_MIFG_SHIFT 8 /* Minimum number of IFG to +- * enforce in between RX frames */ +-#define MAC_IPG_IFG_MIFG_MASK 0xff /* Frame gap below such IFP is dropped */ +-#define MAC_IPG_IFG_IPGR1_SHIFT 16 /* 64bit Carrier-Sense window */ +-#define MAC_IPG_IFG_IPGR1_MASK 0x7f +-#define MAC_IPG_IFG_IPGR2_SHIFT 24 /* 96-bit IPG window */ +-#define MAC_IPG_IFG_IPGR2_MASK 0x7f +- +-/* MAC STATION ADDRESS */ +-#define REG_MAC_STA_ADDR 0x1488 +- +-/* Hash table for multicast address */ +-#define REG_RX_HASH_TABLE 0x1490 +- +-/* MAC Half-Duplex Control Register */ +-#define REG_MAC_HALF_DUPLX_CTRL 0x1498 +-#define MAC_HALF_DUPLX_CTRL_LCOL_SHIFT 0 /* Collision Window */ +-#define MAC_HALF_DUPLX_CTRL_LCOL_MASK 0x3ff +-#define MAC_HALF_DUPLX_CTRL_RETRY_SHIFT 12 +-#define MAC_HALF_DUPLX_CTRL_RETRY_MASK 0xf +-#define MAC_HALF_DUPLX_CTRL_EXC_DEF_EN 0x10000 +-#define MAC_HALF_DUPLX_CTRL_NO_BACK_C 0x20000 +-#define MAC_HALF_DUPLX_CTRL_NO_BACK_P 0x40000 /* No back-off on backpressure, +- * immediately start the +- * transmission after back pressure */ +-#define MAC_HALF_DUPLX_CTRL_ABEBE 0x80000 /* 1: Alternative Binary Exponential Back-off Enabled */ +-#define MAC_HALF_DUPLX_CTRL_ABEBT_SHIFT 20 /* Maximum binary exponential number */ +-#define MAC_HALF_DUPLX_CTRL_ABEBT_MASK 0xf +-#define MAC_HALF_DUPLX_CTRL_JAMIPG_SHIFT 24 /* IPG to start JAM for collision based flow control in half-duplex */ +-#define MAC_HALF_DUPLX_CTRL_JAMIPG_MASK 0xf /* mode. In unit of 8-bit time */ +- +-/* Maximum Frame Length Control Register */ +-#define REG_MTU 0x149c +- +-/* Wake-On-Lan control register */ +-#define REG_WOL_CTRL 0x14a0 +-#define WOL_PATTERN_EN 0x00000001 +-#define WOL_PATTERN_PME_EN 0x00000002 +-#define WOL_MAGIC_EN 0x00000004 +-#define WOL_MAGIC_PME_EN 0x00000008 +-#define WOL_LINK_CHG_EN 0x00000010 +-#define WOL_LINK_CHG_PME_EN 0x00000020 +-#define WOL_PATTERN_ST 0x00000100 +-#define WOL_MAGIC_ST 0x00000200 +-#define WOL_LINKCHG_ST 0x00000400 +-#define WOL_CLK_SWITCH_EN 0x00008000 +-#define WOL_PT0_EN 0x00010000 +-#define WOL_PT1_EN 0x00020000 +-#define WOL_PT2_EN 0x00040000 +-#define WOL_PT3_EN 0x00080000 +-#define WOL_PT4_EN 0x00100000 +-#define WOL_PT5_EN 0x00200000 +-#define WOL_PT6_EN 0x00400000 +- +-/* WOL Length ( 2 DWORD ) */ +-#define REG_WOL_PATTERN_LEN 0x14a4 +-#define WOL_PT_LEN_MASK 0x7f +-#define WOL_PT0_LEN_SHIFT 0 +-#define WOL_PT1_LEN_SHIFT 8 +-#define WOL_PT2_LEN_SHIFT 16 +-#define WOL_PT3_LEN_SHIFT 24 +-#define WOL_PT4_LEN_SHIFT 0 +-#define WOL_PT5_LEN_SHIFT 8 +-#define WOL_PT6_LEN_SHIFT 16 +- +-/* Internal SRAM Partition Register */ +-#define RFDX_HEAD_ADDR_MASK 0x03FF +-#define RFDX_HARD_ADDR_SHIFT 0 +-#define RFDX_TAIL_ADDR_MASK 0x03FF +-#define RFDX_TAIL_ADDR_SHIFT 16 +- +-#define REG_SRAM_RFD0_INFO 0x1500 +-#define REG_SRAM_RFD1_INFO 0x1504 +-#define REG_SRAM_RFD2_INFO 0x1508 +-#define REG_SRAM_RFD3_INFO 0x150C +- +-#define REG_RFD_NIC_LEN 0x1510 /* In 8-bytes */ +-#define RFD_NIC_LEN_MASK 0x03FF +- +-#define REG_SRAM_TRD_ADDR 0x1518 +-#define TPD_HEAD_ADDR_MASK 0x03FF +-#define TPD_HEAD_ADDR_SHIFT 0 +-#define TPD_TAIL_ADDR_MASK 0x03FF +-#define TPD_TAIL_ADDR_SHIFT 16 +- +-#define REG_SRAM_TRD_LEN 0x151C /* In 8-bytes */ +-#define TPD_NIC_LEN_MASK 0x03FF +- +-#define REG_SRAM_RXF_ADDR 0x1520 +-#define REG_SRAM_RXF_LEN 0x1524 +-#define REG_SRAM_TXF_ADDR 0x1528 +-#define REG_SRAM_TXF_LEN 0x152C +-#define REG_SRAM_TCPH_ADDR 0x1530 +-#define REG_SRAM_PKTH_ADDR 0x1532 +- +-/* +- * Load Ptr Register +- * Software sets this bit after the initialization of the head and tail */ +-#define REG_LOAD_PTR 0x1534 +- +-/* +- * addresses of all descriptors, as well as the following descriptor +- * control register, which triggers each function block to load the head +- * pointer to prepare for the operation. This bit is then self-cleared +- * after one cycle. +- */ +-#define REG_RX_BASE_ADDR_HI 0x1540 +-#define REG_TX_BASE_ADDR_HI 0x1544 +-#define REG_SMB_BASE_ADDR_HI 0x1548 +-#define REG_SMB_BASE_ADDR_LO 0x154C +-#define REG_RFD0_HEAD_ADDR_LO 0x1550 +-#define REG_RFD1_HEAD_ADDR_LO 0x1554 +-#define REG_RFD2_HEAD_ADDR_LO 0x1558 +-#define REG_RFD3_HEAD_ADDR_LO 0x155C +-#define REG_RFD_RING_SIZE 0x1560 +-#define RFD_RING_SIZE_MASK 0x0FFF +-#define REG_RX_BUF_SIZE 0x1564 +-#define RX_BUF_SIZE_MASK 0xFFFF +-#define REG_RRD0_HEAD_ADDR_LO 0x1568 +-#define REG_RRD1_HEAD_ADDR_LO 0x156C +-#define REG_RRD2_HEAD_ADDR_LO 0x1570 +-#define REG_RRD3_HEAD_ADDR_LO 0x1574 +-#define REG_RRD_RING_SIZE 0x1578 +-#define RRD_RING_SIZE_MASK 0x0FFF +-#define REG_HTPD_HEAD_ADDR_LO 0x157C +-#define REG_NTPD_HEAD_ADDR_LO 0x1580 +-#define REG_TPD_RING_SIZE 0x1584 +-#define TPD_RING_SIZE_MASK 0xFFFF +-#define REG_CMB_BASE_ADDR_LO 0x1588 +- +-/* RSS about */ +-#define REG_RSS_KEY0 0x14B0 +-#define REG_RSS_KEY1 0x14B4 +-#define REG_RSS_KEY2 0x14B8 +-#define REG_RSS_KEY3 0x14BC +-#define REG_RSS_KEY4 0x14C0 +-#define REG_RSS_KEY5 0x14C4 +-#define REG_RSS_KEY6 0x14C8 +-#define REG_RSS_KEY7 0x14CC +-#define REG_RSS_KEY8 0x14D0 +-#define REG_RSS_KEY9 0x14D4 +-#define REG_IDT_TABLE0 0x14E0 +-#define REG_IDT_TABLE1 0x14E4 +-#define REG_IDT_TABLE2 0x14E8 +-#define REG_IDT_TABLE3 0x14EC +-#define REG_IDT_TABLE4 0x14F0 +-#define REG_IDT_TABLE5 0x14F4 +-#define REG_IDT_TABLE6 0x14F8 +-#define REG_IDT_TABLE7 0x14FC +-#define REG_IDT_TABLE REG_IDT_TABLE0 +-#define REG_RSS_HASH_VALUE 0x15B0 +-#define REG_RSS_HASH_FLAG 0x15B4 +-#define REG_BASE_CPU_NUMBER 0x15B8 +- +-/* TXQ Control Register */ +-#define REG_TXQ_CTRL 0x1590 +-#define TXQ_NUM_TPD_BURST_MASK 0xF +-#define TXQ_NUM_TPD_BURST_SHIFT 0 +-#define TXQ_CTRL_IP_OPTION_EN 0x10 +-#define TXQ_CTRL_EN 0x20 +-#define TXQ_CTRL_ENH_MODE 0x40 +-#define TXQ_CTRL_LS_8023_EN 0x80 +-#define TXQ_TXF_BURST_NUM_SHIFT 16 +-#define TXQ_TXF_BURST_NUM_MASK 0xFFFF +- +-/* Jumbo packet Threshold for task offload */ +-#define REG_TX_TSO_OFFLOAD_THRESH 0x1594 /* In 8-bytes */ +-#define TX_TSO_OFFLOAD_THRESH_MASK 0x07FF +- +-#define REG_TXF_WATER_MARK 0x1598 /* In 8-bytes */ +-#define TXF_WATER_MARK_MASK 0x0FFF +-#define TXF_LOW_WATER_MARK_SHIFT 0 +-#define TXF_HIGH_WATER_MARK_SHIFT 16 +-#define TXQ_CTRL_BURST_MODE_EN 0x80000000 +- +-#define REG_THRUPUT_MON_CTRL 0x159C +-#define THRUPUT_MON_RATE_MASK 0x3 +-#define THRUPUT_MON_RATE_SHIFT 0 +-#define THRUPUT_MON_EN 0x80 +- +-/* RXQ Control Register */ +-#define REG_RXQ_CTRL 0x15A0 +-#define ASPM_THRUPUT_LIMIT_MASK 0x3 +-#define ASPM_THRUPUT_LIMIT_SHIFT 0 +-#define ASPM_THRUPUT_LIMIT_NO 0x00 +-#define ASPM_THRUPUT_LIMIT_1M 0x01 +-#define ASPM_THRUPUT_LIMIT_10M 0x02 +-#define ASPM_THRUPUT_LIMIT_100M 0x04 +-#define RXQ1_CTRL_EN 0x10 +-#define RXQ2_CTRL_EN 0x20 +-#define RXQ3_CTRL_EN 0x40 +-#define IPV6_CHKSUM_CTRL_EN 0x80 +-#define RSS_HASH_BITS_MASK 0x00FF +-#define RSS_HASH_BITS_SHIFT 8 +-#define RSS_HASH_IPV4 0x10000 +-#define RSS_HASH_IPV4_TCP 0x20000 +-#define RSS_HASH_IPV6 0x40000 +-#define RSS_HASH_IPV6_TCP 0x80000 +-#define RXQ_RFD_BURST_NUM_MASK 0x003F +-#define RXQ_RFD_BURST_NUM_SHIFT 20 +-#define RSS_MODE_MASK 0x0003 +-#define RSS_MODE_SHIFT 26 +-#define RSS_NIP_QUEUE_SEL_MASK 0x1 +-#define RSS_NIP_QUEUE_SEL_SHIFT 28 +-#define RRS_HASH_CTRL_EN 0x20000000 +-#define RX_CUT_THRU_EN 0x40000000 +-#define RXQ_CTRL_EN 0x80000000 +- +-#define REG_RFD_FREE_THRESH 0x15A4 +-#define RFD_FREE_THRESH_MASK 0x003F +-#define RFD_FREE_HI_THRESH_SHIFT 0 +-#define RFD_FREE_LO_THRESH_SHIFT 6 +- +-/* RXF flow control register */ +-#define REG_RXQ_RXF_PAUSE_THRESH 0x15A8 +-#define RXQ_RXF_PAUSE_TH_HI_SHIFT 0 +-#define RXQ_RXF_PAUSE_TH_HI_MASK 0x0FFF +-#define RXQ_RXF_PAUSE_TH_LO_SHIFT 16 +-#define RXQ_RXF_PAUSE_TH_LO_MASK 0x0FFF +- +-#define REG_RXD_DMA_CTRL 0x15AC +-#define RXD_DMA_THRESH_MASK 0x0FFF /* In 8-bytes */ +-#define RXD_DMA_THRESH_SHIFT 0 +-#define RXD_DMA_DOWN_TIMER_MASK 0xFFFF +-#define RXD_DMA_DOWN_TIMER_SHIFT 16 +- +-/* DMA Engine Control Register */ +-#define REG_DMA_CTRL 0x15C0 +-#define DMA_CTRL_DMAR_IN_ORDER 0x1 +-#define DMA_CTRL_DMAR_ENH_ORDER 0x2 +-#define DMA_CTRL_DMAR_OUT_ORDER 0x4 +-#define DMA_CTRL_RCB_VALUE 0x8 +-#define DMA_CTRL_DMAR_BURST_LEN_MASK 0x0007 +-#define DMA_CTRL_DMAR_BURST_LEN_SHIFT 4 +-#define DMA_CTRL_DMAW_BURST_LEN_MASK 0x0007 +-#define DMA_CTRL_DMAW_BURST_LEN_SHIFT 7 +-#define DMA_CTRL_DMAR_REQ_PRI 0x400 +-#define DMA_CTRL_DMAR_DLY_CNT_MASK 0x001F +-#define DMA_CTRL_DMAR_DLY_CNT_SHIFT 11 +-#define DMA_CTRL_DMAW_DLY_CNT_MASK 0x000F +-#define DMA_CTRL_DMAW_DLY_CNT_SHIFT 16 +-#define DMA_CTRL_CMB_EN 0x100000 +-#define DMA_CTRL_SMB_EN 0x200000 +-#define DMA_CTRL_CMB_NOW 0x400000 +-#define MAC_CTRL_SMB_DIS 0x1000000 +-#define DMA_CTRL_SMB_NOW 0x80000000 +- +-/* CMB/SMB Control Register */ +-#define REG_SMB_STAT_TIMER 0x15C4 /* 2us resolution */ +-#define SMB_STAT_TIMER_MASK 0xFFFFFF +-#define REG_CMB_TPD_THRESH 0x15C8 +-#define CMB_TPD_THRESH_MASK 0xFFFF +-#define REG_CMB_TX_TIMER 0x15CC /* 2us resolution */ +-#define CMB_TX_TIMER_MASK 0xFFFF +- +-/* Mail box */ +-#define MB_RFDX_PROD_IDX_MASK 0xFFFF +-#define REG_MB_RFD0_PROD_IDX 0x15E0 +-#define REG_MB_RFD1_PROD_IDX 0x15E4 +-#define REG_MB_RFD2_PROD_IDX 0x15E8 +-#define REG_MB_RFD3_PROD_IDX 0x15EC +- +-#define MB_PRIO_PROD_IDX_MASK 0xFFFF +-#define REG_MB_PRIO_PROD_IDX 0x15F0 +-#define MB_HTPD_PROD_IDX_SHIFT 0 +-#define MB_NTPD_PROD_IDX_SHIFT 16 +- +-#define MB_PRIO_CONS_IDX_MASK 0xFFFF +-#define REG_MB_PRIO_CONS_IDX 0x15F4 +-#define MB_HTPD_CONS_IDX_SHIFT 0 +-#define MB_NTPD_CONS_IDX_SHIFT 16 +- +-#define REG_MB_RFD01_CONS_IDX 0x15F8 +-#define MB_RFD0_CONS_IDX_MASK 0x0000FFFF +-#define MB_RFD1_CONS_IDX_MASK 0xFFFF0000 +-#define REG_MB_RFD23_CONS_IDX 0x15FC +-#define MB_RFD2_CONS_IDX_MASK 0x0000FFFF +-#define MB_RFD3_CONS_IDX_MASK 0xFFFF0000 +- +-/* Interrupt Status Register */ +-#define REG_ISR 0x1600 +-#define ISR_SMB 0x00000001 +-#define ISR_TIMER 0x00000002 +-/* +- * Software manual interrupt, for debug. Set when SW_MAN_INT_EN is set +- * in Table 51 Selene Master Control Register (Offset 0x1400). +- */ +-#define ISR_MANUAL 0x00000004 +-#define ISR_HW_RXF_OV 0x00000008 /* RXF overflow interrupt */ +-#define ISR_RFD0_UR 0x00000010 /* RFD0 under run */ +-#define ISR_RFD1_UR 0x00000020 +-#define ISR_RFD2_UR 0x00000040 +-#define ISR_RFD3_UR 0x00000080 +-#define ISR_TXF_UR 0x00000100 +-#define ISR_DMAR_TO_RST 0x00000200 +-#define ISR_DMAW_TO_RST 0x00000400 +-#define ISR_TX_CREDIT 0x00000800 +-#define ISR_GPHY 0x00001000 +-/* GPHY low power state interrupt */ +-#define ISR_GPHY_LPW 0x00002000 +-#define ISR_TXQ_TO_RST 0x00004000 +-#define ISR_TX_PKT 0x00008000 +-#define ISR_RX_PKT_0 0x00010000 +-#define ISR_RX_PKT_1 0x00020000 +-#define ISR_RX_PKT_2 0x00040000 +-#define ISR_RX_PKT_3 0x00080000 +-#define ISR_MAC_RX 0x00100000 +-#define ISR_MAC_TX 0x00200000 +-#define ISR_UR_DETECTED 0x00400000 +-#define ISR_FERR_DETECTED 0x00800000 +-#define ISR_NFERR_DETECTED 0x01000000 +-#define ISR_CERR_DETECTED 0x02000000 +-#define ISR_PHY_LINKDOWN 0x04000000 +-#define ISR_DIS_INT 0x80000000 +- +-/* Interrupt Mask Register */ +-#define REG_IMR 0x1604 +- +-#define IMR_NORMAL_MASK (\ +- ISR_MANUAL |\ +- ISR_HW_RXF_OV |\ +- ISR_RFD0_UR |\ +- ISR_TXF_UR |\ +- ISR_DMAR_TO_RST |\ +- ISR_TXQ_TO_RST |\ +- ISR_DMAW_TO_RST |\ +- ISR_GPHY |\ +- ISR_TX_PKT |\ +- ISR_RX_PKT_0 |\ +- ISR_GPHY_LPW |\ +- ISR_PHY_LINKDOWN) +- +-#define ISR_RX_PKT (\ +- ISR_RX_PKT_0 |\ +- ISR_RX_PKT_1 |\ +- ISR_RX_PKT_2 |\ +- ISR_RX_PKT_3) +- +-#define ISR_OVER (\ +- ISR_RFD0_UR |\ +- ISR_RFD1_UR |\ +- ISR_RFD2_UR |\ +- ISR_RFD3_UR |\ +- ISR_HW_RXF_OV |\ +- ISR_TXF_UR) +- +-#define ISR_ERROR (\ +- ISR_DMAR_TO_RST |\ +- ISR_TXQ_TO_RST |\ +- ISR_DMAW_TO_RST |\ +- ISR_PHY_LINKDOWN) +- +-#define REG_INT_RETRIG_TIMER 0x1608 +-#define INT_RETRIG_TIMER_MASK 0xFFFF +- +-#define REG_HDS_CTRL 0x160C +-#define HDS_CTRL_EN 0x0001 +-#define HDS_CTRL_BACKFILLSIZE_SHIFT 8 +-#define HDS_CTRL_BACKFILLSIZE_MASK 0x0FFF +-#define HDS_CTRL_MAX_HDRSIZE_SHIFT 20 +-#define HDS_CTRL_MAC_HDRSIZE_MASK 0x0FFF +- +-#define REG_MAC_RX_STATUS_BIN 0x1700 +-#define REG_MAC_RX_STATUS_END 0x175c +-#define REG_MAC_TX_STATUS_BIN 0x1760 +-#define REG_MAC_TX_STATUS_END 0x17c0 +- +-/* DEBUG ADDR */ +-#define REG_DEBUG_DATA0 0x1900 +-#define REG_DEBUG_DATA1 0x1904 +- +-/* PHY Control Register */ +-#define MII_BMCR 0x00 +-#define BMCR_SPEED_SELECT_MSB 0x0040 /* bits 6,13: 10=1000, 01=100, 00=10 */ +-#define BMCR_COLL_TEST_ENABLE 0x0080 /* Collision test enable */ +-#define BMCR_FULL_DUPLEX 0x0100 /* FDX =1, half duplex =0 */ +-#define BMCR_RESTART_AUTO_NEG 0x0200 /* Restart auto negotiation */ +-#define BMCR_ISOLATE 0x0400 /* Isolate PHY from MII */ +-#define BMCR_POWER_DOWN 0x0800 /* Power down */ +-#define BMCR_AUTO_NEG_EN 0x1000 /* Auto Neg Enable */ +-#define BMCR_SPEED_SELECT_LSB 0x2000 /* bits 6,13: 10=1000, 01=100, 00=10 */ +-#define BMCR_LOOPBACK 0x4000 /* 0 = normal, 1 = loopback */ +-#define BMCR_RESET 0x8000 /* 0 = normal, 1 = PHY reset */ +-#define BMCR_SPEED_MASK 0x2040 +-#define BMCR_SPEED_1000 0x0040 +-#define BMCR_SPEED_100 0x2000 +-#define BMCR_SPEED_10 0x0000 +- +-/* PHY Status Register */ +-#define MII_BMSR 0x01 +-#define BMMSR_EXTENDED_CAPS 0x0001 /* Extended register capabilities */ +-#define BMSR_JABBER_DETECT 0x0002 /* Jabber Detected */ +-#define BMSR_LINK_STATUS 0x0004 /* Link Status 1 = link */ +-#define BMSR_AUTONEG_CAPS 0x0008 /* Auto Neg Capable */ +-#define BMSR_REMOTE_FAULT 0x0010 /* Remote Fault Detect */ +-#define BMSR_AUTONEG_COMPLETE 0x0020 /* Auto Neg Complete */ +-#define BMSR_PREAMBLE_SUPPRESS 0x0040 /* Preamble may be suppressed */ +-#define BMSR_EXTENDED_STATUS 0x0100 /* Ext. status info in Reg 0x0F */ +-#define BMSR_100T2_HD_CAPS 0x0200 /* 100T2 Half Duplex Capable */ +-#define BMSR_100T2_FD_CAPS 0x0400 /* 100T2 Full Duplex Capable */ +-#define BMSR_10T_HD_CAPS 0x0800 /* 10T Half Duplex Capable */ +-#define BMSR_10T_FD_CAPS 0x1000 /* 10T Full Duplex Capable */ +-#define BMSR_100X_HD_CAPS 0x2000 /* 100X Half Duplex Capable */ +-#define BMMII_SR_100X_FD_CAPS 0x4000 /* 100X Full Duplex Capable */ +-#define BMMII_SR_100T4_CAPS 0x8000 /* 100T4 Capable */ +- +-#define MII_PHYSID1 0x02 +-#define MII_PHYSID2 0x03 +- +-/* Autoneg Advertisement Register */ +-#define MII_ADVERTISE 0x04 +-#define ADVERTISE_SPEED_MASK 0x01E0 +-#define ADVERTISE_DEFAULT_CAP 0x0DE0 +- +-/* 1000BASE-T Control Register */ +-#define MII_GIGA_CR 0x09 +-#define GIGA_CR_1000T_REPEATER_DTE 0x0400 /* 1=Repeater/switch device port 0=DTE device */ +- +-#define GIGA_CR_1000T_MS_VALUE 0x0800 /* 1=Configure PHY as Master 0=Configure PHY as Slave */ +-#define GIGA_CR_1000T_MS_ENABLE 0x1000 /* 1=Master/Slave manual config value 0=Automatic Master/Slave config */ +-#define GIGA_CR_1000T_TEST_MODE_NORMAL 0x0000 /* Normal Operation */ +-#define GIGA_CR_1000T_TEST_MODE_1 0x2000 /* Transmit Waveform test */ +-#define GIGA_CR_1000T_TEST_MODE_2 0x4000 /* Master Transmit Jitter test */ +-#define GIGA_CR_1000T_TEST_MODE_3 0x6000 /* Slave Transmit Jitter test */ +-#define GIGA_CR_1000T_TEST_MODE_4 0x8000 /* Transmitter Distortion test */ +-#define GIGA_CR_1000T_SPEED_MASK 0x0300 +-#define GIGA_CR_1000T_DEFAULT_CAP 0x0300 +- +-/* PHY Specific Status Register */ +-#define MII_GIGA_PSSR 0x11 +-#define GIGA_PSSR_SPD_DPLX_RESOLVED 0x0800 /* 1=Speed & Duplex resolved */ +-#define GIGA_PSSR_DPLX 0x2000 /* 1=Duplex 0=Half Duplex */ +-#define GIGA_PSSR_SPEED 0xC000 /* Speed, bits 14:15 */ +-#define GIGA_PSSR_10MBS 0x0000 /* 00=10Mbs */ +-#define GIGA_PSSR_100MBS 0x4000 /* 01=100Mbs */ +-#define GIGA_PSSR_1000MBS 0x8000 /* 10=1000Mbs */ +- +-/* PHY Interrupt Enable Register */ +-#define MII_IER 0x12 +-#define IER_LINK_UP 0x0400 +-#define IER_LINK_DOWN 0x0800 +- +-/* PHY Interrupt Status Register */ +-#define MII_ISR 0x13 +-#define ISR_LINK_UP 0x0400 +-#define ISR_LINK_DOWN 0x0800 +- +-/* Cable-Detect-Test Control Register */ +-#define MII_CDTC 0x16 +-#define CDTC_EN_OFF 0 /* sc */ +-#define CDTC_EN_BITS 1 +-#define CDTC_PAIR_OFF 8 +-#define CDTC_PAIR_BIT 2 +- +-/* Cable-Detect-Test Status Register */ +-#define MII_CDTS 0x1C +-#define CDTS_STATUS_OFF 8 +-#define CDTS_STATUS_BITS 2 +-#define CDTS_STATUS_NORMAL 0 +-#define CDTS_STATUS_SHORT 1 +-#define CDTS_STATUS_OPEN 2 +-#define CDTS_STATUS_INVALID 3 +- +-#define MII_DBG_ADDR 0x1D +-#define MII_DBG_DATA 0x1E +- +-#define MII_ANA_CTRL_0 0x0 +-#define ANA_RESTART_CAL 0x0001 +-#define ANA_MANUL_SWICH_ON_SHIFT 0x1 +-#define ANA_MANUL_SWICH_ON_MASK 0xF +-#define ANA_MAN_ENABLE 0x0020 +-#define ANA_SEL_HSP 0x0040 +-#define ANA_EN_HB 0x0080 +-#define ANA_EN_HBIAS 0x0100 +-#define ANA_OEN_125M 0x0200 +-#define ANA_EN_LCKDT 0x0400 +-#define ANA_LCKDT_PHY 0x0800 +-#define ANA_AFE_MODE 0x1000 +-#define ANA_VCO_SLOW 0x2000 +-#define ANA_VCO_FAST 0x4000 +-#define ANA_SEL_CLK125M_DSP 0x8000 +- +-#define MII_ANA_CTRL_4 0x4 +-#define ANA_IECHO_ADJ_MASK 0xF +-#define ANA_IECHO_ADJ_3_SHIFT 0 +-#define ANA_IECHO_ADJ_2_SHIFT 4 +-#define ANA_IECHO_ADJ_1_SHIFT 8 +-#define ANA_IECHO_ADJ_0_SHIFT 12 +- +-#define MII_ANA_CTRL_5 0x5 +-#define ANA_SERDES_CDR_BW_SHIFT 0 +-#define ANA_SERDES_CDR_BW_MASK 0x3 +-#define ANA_MS_PAD_DBG 0x0004 +-#define ANA_SPEEDUP_DBG 0x0008 +-#define ANA_SERDES_TH_LOS_SHIFT 4 +-#define ANA_SERDES_TH_LOS_MASK 0x3 +-#define ANA_SERDES_EN_DEEM 0x0040 +-#define ANA_SERDES_TXELECIDLE 0x0080 +-#define ANA_SERDES_BEACON 0x0100 +-#define ANA_SERDES_HALFTXDR 0x0200 +-#define ANA_SERDES_SEL_HSP 0x0400 +-#define ANA_SERDES_EN_PLL 0x0800 +-#define ANA_SERDES_EN 0x1000 +-#define ANA_SERDES_EN_LCKDT 0x2000 +- +-#define MII_ANA_CTRL_11 0xB +-#define ANA_PS_HIB_EN 0x8000 +- +-#define MII_ANA_CTRL_18 0x12 +-#define ANA_TEST_MODE_10BT_01SHIFT 0 +-#define ANA_TEST_MODE_10BT_01MASK 0x3 +-#define ANA_LOOP_SEL_10BT 0x0004 +-#define ANA_RGMII_MODE_SW 0x0008 +-#define ANA_EN_LONGECABLE 0x0010 +-#define ANA_TEST_MODE_10BT_2 0x0020 +-#define ANA_EN_10BT_IDLE 0x0400 +-#define ANA_EN_MASK_TB 0x0800 +-#define ANA_TRIGGER_SEL_TIMER_SHIFT 12 +-#define ANA_TRIGGER_SEL_TIMER_MASK 0x3 +-#define ANA_INTERVAL_SEL_TIMER_SHIFT 14 +-#define ANA_INTERVAL_SEL_TIMER_MASK 0x3 +- +-#define MII_ANA_CTRL_41 0x29 +-#define ANA_TOP_PS_EN 0x8000 +- +-#define MII_ANA_CTRL_54 0x36 +-#define ANA_LONG_CABLE_TH_100_SHIFT 0 +-#define ANA_LONG_CABLE_TH_100_MASK 0x3F +-#define ANA_DESERVED 0x0040 +-#define ANA_EN_LIT_CH 0x0080 +-#define ANA_SHORT_CABLE_TH_100_SHIFT 8 +-#define ANA_SHORT_CABLE_TH_100_MASK 0x3F +-#define ANA_BP_BAD_LINK_ACCUM 0x4000 +-#define ANA_BP_SMALL_BW 0x8000 +- +-#endif /*_ATL1C_HW_H_*/ +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/drivers/net/atl1c/atl1c_main.c linux-2.6.29-rc3.owrt/drivers/net/atl1c/atl1c_main.c +--- linux-2.6.29.owrt/drivers/net/atl1c/atl1c_main.c 2009-05-10 22:04:38.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/drivers/net/atl1c/atl1c_main.c 1970-01-01 01:00:00.000000000 +0100 +@@ -1,2797 +0,0 @@ +-/* +- * Copyright(c) 2008 - 2009 Atheros Corporation. All rights reserved. +- * +- * Derived from Intel e1000 driver +- * Copyright(c) 1999 - 2005 Intel Corporation. All rights reserved. +- * +- * 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, MA 02111-1307, USA. +- */ +- +-#include "atl1c.h" +- +-#define ATL1C_DRV_VERSION "1.0.0.1-NAPI" +-char atl1c_driver_name[] = "atl1c"; +-char atl1c_driver_version[] = ATL1C_DRV_VERSION; +-#define PCI_DEVICE_ID_ATTANSIC_L2C 0x1062 +-#define PCI_DEVICE_ID_ATTANSIC_L1C 0x1063 +-/* +- * atl1c_pci_tbl - PCI Device ID Table +- * +- * Wildcard entries (PCI_ANY_ID) should come last +- * Last entry must be all 0s +- * +- * { Vendor ID, Device ID, SubVendor ID, SubDevice ID, +- * Class, Class Mask, private data (not used) } +- */ +-static struct pci_device_id atl1c_pci_tbl[] = { +- {PCI_DEVICE(PCI_VENDOR_ID_ATTANSIC, PCI_DEVICE_ID_ATTANSIC_L1C)}, +- {PCI_DEVICE(PCI_VENDOR_ID_ATTANSIC, PCI_DEVICE_ID_ATTANSIC_L2C)}, +- /* required last entry */ +- { 0 } +-}; +-MODULE_DEVICE_TABLE(pci, atl1c_pci_tbl); +- +-MODULE_AUTHOR("Jie Yang <jie.yang@atheros.com>"); +-MODULE_DESCRIPTION("Atheros 1000M Ethernet Network Driver"); +-MODULE_LICENSE("GPL"); +-MODULE_VERSION(ATL1C_DRV_VERSION); +- +-static int atl1c_stop_mac(struct atl1c_hw *hw); +-static void atl1c_enable_rx_ctrl(struct atl1c_hw *hw); +-static void atl1c_enable_tx_ctrl(struct atl1c_hw *hw); +-static void atl1c_disable_l0s_l1(struct atl1c_hw *hw); +-static void atl1c_set_aspm(struct atl1c_hw *hw, bool linkup); +-static void atl1c_setup_mac_ctrl(struct atl1c_adapter *adapter); +-static void atl1c_clean_rx_irq(struct atl1c_adapter *adapter, u8 que, +- int *work_done, int work_to_do); +- +-static const u16 atl1c_pay_load_size[] = { +- 128, 256, 512, 1024, 2048, 4096, +-}; +- +-static const u16 atl1c_rfd_prod_idx_regs[AT_MAX_RECEIVE_QUEUE] = +-{ +- REG_MB_RFD0_PROD_IDX, +- REG_MB_RFD1_PROD_IDX, +- REG_MB_RFD2_PROD_IDX, +- REG_MB_RFD3_PROD_IDX +-}; +- +-static const u16 atl1c_rfd_addr_lo_regs[AT_MAX_RECEIVE_QUEUE] = +-{ +- REG_RFD0_HEAD_ADDR_LO, +- REG_RFD1_HEAD_ADDR_LO, +- REG_RFD2_HEAD_ADDR_LO, +- REG_RFD3_HEAD_ADDR_LO +-}; +- +-static const u16 atl1c_rrd_addr_lo_regs[AT_MAX_RECEIVE_QUEUE] = +-{ +- REG_RRD0_HEAD_ADDR_LO, +- REG_RRD1_HEAD_ADDR_LO, +- REG_RRD2_HEAD_ADDR_LO, +- REG_RRD3_HEAD_ADDR_LO +-}; +- +-static const u32 atl1c_default_msg = NETIF_MSG_DRV | NETIF_MSG_PROBE | +- NETIF_MSG_LINK | NETIF_MSG_TIMER | NETIF_MSG_IFDOWN | NETIF_MSG_IFUP; +- +-/* +- * atl1c_init_pcie - init PCIE module +- */ +-static void atl1c_reset_pcie(struct atl1c_hw *hw, u32 flag) +-{ +- u32 data; +- u32 pci_cmd; +- struct pci_dev *pdev = hw->adapter->pdev; +- +- AT_READ_REG(hw, PCI_COMMAND, &pci_cmd); +- pci_cmd &= ~PCI_COMMAND_INTX_DISABLE; +- pci_cmd |= (PCI_COMMAND_MEMORY | PCI_COMMAND_MASTER | +- PCI_COMMAND_IO); +- AT_WRITE_REG(hw, PCI_COMMAND, pci_cmd); +- +- /* +- * Clear any PowerSaveing Settings +- */ +- pci_enable_wake(pdev, PCI_D3hot, 0); +- pci_enable_wake(pdev, PCI_D3cold, 0); +- +- /* +- * Mask some pcie error bits +- */ +- AT_READ_REG(hw, REG_PCIE_UC_SEVERITY, &data); +- data &= ~PCIE_UC_SERVRITY_DLP; +- data &= ~PCIE_UC_SERVRITY_FCP; +- AT_WRITE_REG(hw, REG_PCIE_UC_SEVERITY, data); +- +- if (flag & ATL1C_PCIE_L0S_L1_DISABLE) +- atl1c_disable_l0s_l1(hw); +- if (flag & ATL1C_PCIE_PHY_RESET) +- AT_WRITE_REG(hw, REG_GPHY_CTRL, GPHY_CTRL_DEFAULT); +- else +- AT_WRITE_REG(hw, REG_GPHY_CTRL, +- GPHY_CTRL_DEFAULT | GPHY_CTRL_EXT_RESET); +- +- msleep(1); +-} +- +-/* +- * atl1c_irq_enable - Enable default interrupt generation settings +- * @adapter: board private structure +- */ +-static inline void atl1c_irq_enable(struct atl1c_adapter *adapter) +-{ +- if (likely(atomic_dec_and_test(&adapter->irq_sem))) { +- AT_WRITE_REG(&adapter->hw, REG_ISR, 0x7FFFFFFF); +- AT_WRITE_REG(&adapter->hw, REG_IMR, adapter->hw.intr_mask); +- AT_WRITE_FLUSH(&adapter->hw); +- } +-} +- +-/* +- * atl1c_irq_disable - Mask off interrupt generation on the NIC +- * @adapter: board private structure +- */ +-static inline void atl1c_irq_disable(struct atl1c_adapter *adapter) +-{ +- atomic_inc(&adapter->irq_sem); +- AT_WRITE_REG(&adapter->hw, REG_IMR, 0); +- AT_WRITE_FLUSH(&adapter->hw); +- synchronize_irq(adapter->pdev->irq); +-} +- +-/* +- * atl1c_irq_reset - reset interrupt confiure on the NIC +- * @adapter: board private structure +- */ +-static inline void atl1c_irq_reset(struct atl1c_adapter *adapter) +-{ +- atomic_set(&adapter->irq_sem, 1); +- atl1c_irq_enable(adapter); +-} +- +-/* +- * atl1c_phy_config - Timer Call-back +- * @data: pointer to netdev cast into an unsigned long +- */ +-static void atl1c_phy_config(unsigned long data) +-{ +- struct atl1c_adapter *adapter = (struct atl1c_adapter *) data; +- struct atl1c_hw *hw = &adapter->hw; +- unsigned long flags; +- +- spin_lock_irqsave(&adapter->mdio_lock, flags); +- atl1c_restart_autoneg(hw); +- spin_unlock_irqrestore(&adapter->mdio_lock, flags); +-} +- +-void atl1c_reinit_locked(struct atl1c_adapter *adapter) +-{ +- +- WARN_ON(in_interrupt()); +- atl1c_down(adapter); +- atl1c_up(adapter); +- clear_bit(__AT_RESETTING, &adapter->flags); +-} +- +-static void atl1c_reset_task(struct work_struct *work) +-{ +- struct atl1c_adapter *adapter; +- struct net_device *netdev; +- +- adapter = container_of(work, struct atl1c_adapter, reset_task); +- netdev = adapter->netdev; +- +- netif_device_detach(netdev); +- atl1c_down(adapter); +- atl1c_up(adapter); +- netif_device_attach(netdev); +-} +- +-static void atl1c_check_link_status(struct atl1c_adapter *adapter) +-{ +- struct atl1c_hw *hw = &adapter->hw; +- struct net_device *netdev = adapter->netdev; +- struct pci_dev *pdev = adapter->pdev; +- int err; +- unsigned long flags; +- u16 speed, duplex, phy_data; +- +- spin_lock_irqsave(&adapter->mdio_lock, flags); +- /* MII_BMSR must read twise */ +- atl1c_read_phy_reg(hw, MII_BMSR, &phy_data); +- atl1c_read_phy_reg(hw, MII_BMSR, &phy_data); +- spin_unlock_irqrestore(&adapter->mdio_lock, flags); +- +- if ((phy_data & BMSR_LSTATUS) == 0) { +- /* link down */ +- if (netif_carrier_ok(netdev)) { +- hw->hibernate = true; +- atl1c_set_aspm(hw, false); +- if (atl1c_stop_mac(hw) != 0) +- if (netif_msg_hw(adapter)) +- dev_warn(&pdev->dev, +- "stop mac failed\n"); +- } +- netif_carrier_off(netdev); +- } else { +- /* Link Up */ +- hw->hibernate = false; +- spin_lock_irqsave(&adapter->mdio_lock, flags); +- err = atl1c_get_speed_and_duplex(hw, &speed, &duplex); +- spin_unlock_irqrestore(&adapter->mdio_lock, flags); +- if (unlikely(err)) +- return; +- /* link result is our setting */ +- if (adapter->link_speed != speed || +- adapter->link_duplex != duplex) { +- adapter->link_speed = speed; +- adapter->link_duplex = duplex; +- atl1c_enable_tx_ctrl(hw); +- atl1c_enable_rx_ctrl(hw); +- atl1c_setup_mac_ctrl(adapter); +- atl1c_set_aspm(hw, true); +- if (netif_msg_link(adapter)) +- dev_info(&pdev->dev, +- "%s: %s NIC Link is Up<%d Mbps %s>\n", +- atl1c_driver_name, netdev->name, +- adapter->link_speed, +- adapter->link_duplex == FULL_DUPLEX ? +- "Full Duplex" : "Half Duplex"); +- } +- if (!netif_carrier_ok(netdev)) +- netif_carrier_on(netdev); +- } +-} +- +-/* +- * atl1c_link_chg_task - deal with link change event Out of interrupt context +- * @netdev: network interface device structure +- */ +-static void atl1c_link_chg_task(struct work_struct *work) +-{ +- struct atl1c_adapter *adapter; +- +- adapter = container_of(work, struct atl1c_adapter, link_chg_task); +- atl1c_check_link_status(adapter); +-} +- +-static void atl1c_link_chg_event(struct atl1c_adapter *adapter) +-{ +- struct net_device *netdev = adapter->netdev; +- struct pci_dev *pdev = adapter->pdev; +- u16 phy_data; +- u16 link_up; +- +- spin_lock(&adapter->mdio_lock); +- atl1c_read_phy_reg(&adapter->hw, MII_BMSR, &phy_data); +- atl1c_read_phy_reg(&adapter->hw, MII_BMSR, &phy_data); +- spin_unlock(&adapter->mdio_lock); +- link_up = phy_data & BMSR_LSTATUS; +- /* notify upper layer link down ASAP */ +- if (!link_up) { +- if (netif_carrier_ok(netdev)) { +- /* old link state: Up */ +- netif_carrier_off(netdev); +- if (netif_msg_link(adapter)) +- dev_info(&pdev->dev, +- "%s: %s NIC Link is Down\n", +- atl1c_driver_name, netdev->name); +- adapter->link_speed = SPEED_0; +- } +- } +- schedule_work(&adapter->link_chg_task); +-} +- +-static void atl1c_del_timer(struct atl1c_adapter *adapter) +-{ +- del_timer_sync(&adapter->phy_config_timer); +-} +- +-static void atl1c_cancel_work(struct atl1c_adapter *adapter) +-{ +- cancel_work_sync(&adapter->reset_task); +- cancel_work_sync(&adapter->link_chg_task); +-} +- +-/* +- * atl1c_tx_timeout - Respond to a Tx Hang +- * @netdev: network interface device structure +- */ +-static void atl1c_tx_timeout(struct net_device *netdev) +-{ +- struct atl1c_adapter *adapter = netdev_priv(netdev); +- +- /* Do the reset outside of interrupt context */ +- schedule_work(&adapter->reset_task); +-} +- +-/* +- * atl1c_set_multi - Multicast and Promiscuous mode set +- * @netdev: network interface device structure +- * +- * The set_multi entry point is called whenever the multicast address +- * list or the network interface flags are updated. This routine is +- * responsible for configuring the hardware for proper multicast, +- * promiscuous mode, and all-multi behavior. +- */ +-static void atl1c_set_multi(struct net_device *netdev) +-{ +- struct atl1c_adapter *adapter = netdev_priv(netdev); +- struct atl1c_hw *hw = &adapter->hw; +- struct dev_mc_list *mc_ptr; +- u32 mac_ctrl_data; +- u32 hash_value; +- +- /* Check for Promiscuous and All Multicast modes */ +- AT_READ_REG(hw, REG_MAC_CTRL, &mac_ctrl_data); +- +- if (netdev->flags & IFF_PROMISC) { +- mac_ctrl_data |= MAC_CTRL_PROMIS_EN; +- } else if (netdev->flags & IFF_ALLMULTI) { +- mac_ctrl_data |= MAC_CTRL_MC_ALL_EN; +- mac_ctrl_data &= ~MAC_CTRL_PROMIS_EN; +- } else { +- mac_ctrl_data &= ~(MAC_CTRL_PROMIS_EN | MAC_CTRL_MC_ALL_EN); +- } +- +- AT_WRITE_REG(hw, REG_MAC_CTRL, mac_ctrl_data); +- +- /* clear the old settings from the multicast hash table */ +- AT_WRITE_REG(hw, REG_RX_HASH_TABLE, 0); +- AT_WRITE_REG_ARRAY(hw, REG_RX_HASH_TABLE, 1, 0); +- +- /* comoute mc addresses' hash value ,and put it into hash table */ +- for (mc_ptr = netdev->mc_list; mc_ptr; mc_ptr = mc_ptr->next) { +- hash_value = atl1c_hash_mc_addr(hw, mc_ptr->dmi_addr); +- atl1c_hash_set(hw, hash_value); +- } +-} +- +-static void atl1c_vlan_rx_register(struct net_device *netdev, +- struct vlan_group *grp) +-{ +- struct atl1c_adapter *adapter = netdev_priv(netdev); +- struct pci_dev *pdev = adapter->pdev; +- u32 mac_ctrl_data = 0; +- +- if (netif_msg_pktdata(adapter)) +- dev_dbg(&pdev->dev, "atl1c_vlan_rx_register\n"); +- +- atl1c_irq_disable(adapter); +- +- adapter->vlgrp = grp; +- AT_READ_REG(&adapter->hw, REG_MAC_CTRL, &mac_ctrl_data); +- +- if (grp) { +- /* enable VLAN tag insert/strip */ +- mac_ctrl_data |= MAC_CTRL_RMV_VLAN; +- } else { +- /* disable VLAN tag insert/strip */ +- mac_ctrl_data &= ~MAC_CTRL_RMV_VLAN; +- } +- +- AT_WRITE_REG(&adapter->hw, REG_MAC_CTRL, mac_ctrl_data); +- atl1c_irq_enable(adapter); +-} +- +-static void atl1c_restore_vlan(struct atl1c_adapter *adapter) +-{ +- struct pci_dev *pdev = adapter->pdev; +- +- if (netif_msg_pktdata(adapter)) +- dev_dbg(&pdev->dev, "atl1c_restore_vlan !"); +- atl1c_vlan_rx_register(adapter->netdev, adapter->vlgrp); +-} +-/* +- * atl1c_set_mac - Change the Ethernet Address of the NIC +- * @netdev: network interface device structure +- * @p: pointer to an address structure +- * +- * Returns 0 on success, negative on failure +- */ +-static int atl1c_set_mac_addr(struct net_device *netdev, void *p) +-{ +- struct atl1c_adapter *adapter = netdev_priv(netdev); +- struct sockaddr *addr = p; +- +- if (!is_valid_ether_addr(addr->sa_data)) +- return -EADDRNOTAVAIL; +- +- if (netif_running(netdev)) +- return -EBUSY; +- +- memcpy(netdev->dev_addr, addr->sa_data, netdev->addr_len); +- memcpy(adapter->hw.mac_addr, addr->sa_data, netdev->addr_len); +- +- atl1c_hw_set_mac_addr(&adapter->hw); +- +- return 0; +-} +- +-static void atl1c_set_rxbufsize(struct atl1c_adapter *adapter, +- struct net_device *dev) +-{ +- int mtu = dev->mtu; +- +- adapter->rx_buffer_len = mtu > AT_RX_BUF_SIZE ? +- roundup(mtu + ETH_HLEN + ETH_FCS_LEN + VLAN_HLEN, 8) : AT_RX_BUF_SIZE; +-} +-/* +- * atl1c_change_mtu - Change the Maximum Transfer Unit +- * @netdev: network interface device structure +- * @new_mtu: new value for maximum frame size +- * +- * Returns 0 on success, negative on failure +- */ +-static int atl1c_change_mtu(struct net_device *netdev, int new_mtu) +-{ +- struct atl1c_adapter *adapter = netdev_priv(netdev); +- int old_mtu = netdev->mtu; +- int max_frame = new_mtu + ETH_HLEN + ETH_FCS_LEN + VLAN_HLEN; +- +- if ((max_frame < ETH_ZLEN + ETH_FCS_LEN) || +- (max_frame > MAX_JUMBO_FRAME_SIZE)) { +- if (netif_msg_link(adapter)) +- dev_warn(&adapter->pdev->dev, "invalid MTU setting\n"); +- return -EINVAL; +- } +- /* set MTU */ +- if (old_mtu != new_mtu && netif_running(netdev)) { +- while (test_and_set_bit(__AT_RESETTING, &adapter->flags)) +- msleep(1); +- netdev->mtu = new_mtu; +- adapter->hw.max_frame_size = new_mtu; +- atl1c_set_rxbufsize(adapter, netdev); +- atl1c_down(adapter); +- atl1c_up(adapter); +- clear_bit(__AT_RESETTING, &adapter->flags); +- if (adapter->hw.ctrl_flags & ATL1C_FPGA_VERSION) { +- u32 phy_data; +- +- AT_READ_REG(&adapter->hw, 0x1414, &phy_data); +- phy_data |= 0x10000000; +- AT_WRITE_REG(&adapter->hw, 0x1414, phy_data); +- } +- +- } +- return 0; +-} +- +-/* +- * caller should hold mdio_lock +- */ +-static int atl1c_mdio_read(struct net_device *netdev, int phy_id, int reg_num) +-{ +- struct atl1c_adapter *adapter = netdev_priv(netdev); +- u16 result; +- +- atl1c_read_phy_reg(&adapter->hw, reg_num & MDIO_REG_ADDR_MASK, &result); +- return result; +-} +- +-static void atl1c_mdio_write(struct net_device *netdev, int phy_id, +- int reg_num, int val) +-{ +- struct atl1c_adapter *adapter = netdev_priv(netdev); +- +- atl1c_write_phy_reg(&adapter->hw, reg_num & MDIO_REG_ADDR_MASK, val); +-} +- +-/* +- * atl1c_mii_ioctl - +- * @netdev: +- * @ifreq: +- * @cmd: +- */ +-static int atl1c_mii_ioctl(struct net_device *netdev, +- struct ifreq *ifr, int cmd) +-{ +- struct atl1c_adapter *adapter = netdev_priv(netdev); +- struct pci_dev *pdev = adapter->pdev; +- struct mii_ioctl_data *data = if_mii(ifr); +- unsigned long flags; +- int retval = 0; +- +- if (!netif_running(netdev)) +- return -EINVAL; +- +- spin_lock_irqsave(&adapter->mdio_lock, flags); +- switch (cmd) { +- case SIOCGMIIPHY: +- data->phy_id = 0; +- break; +- +- case SIOCGMIIREG: +- if (!capable(CAP_NET_ADMIN)) { +- retval = -EPERM; +- goto out; +- } +- if (atl1c_read_phy_reg(&adapter->hw, data->reg_num & 0x1F, +- &data->val_out)) { +- retval = -EIO; +- goto out; +- } +- break; +- +- case SIOCSMIIREG: +- if (!capable(CAP_NET_ADMIN)) { +- retval = -EPERM; +- goto out; +- } +- if (data->reg_num & ~(0x1F)) { +- retval = -EFAULT; +- goto out; +- } +- +- dev_dbg(&pdev->dev, "<atl1c_mii_ioctl> write %x %x", +- data->reg_num, data->val_in); +- if (atl1c_write_phy_reg(&adapter->hw, +- data->reg_num, data->val_in)) { +- retval = -EIO; +- goto out; +- } +- break; +- +- default: +- retval = -EOPNOTSUPP; +- break; +- } +-out: +- spin_unlock_irqrestore(&adapter->mdio_lock, flags); +- return retval; +-} +- +-/* +- * atl1c_ioctl - +- * @netdev: +- * @ifreq: +- * @cmd: +- */ +-static int atl1c_ioctl(struct net_device *netdev, struct ifreq *ifr, int cmd) +-{ +- switch (cmd) { +- case SIOCGMIIPHY: +- case SIOCGMIIREG: +- case SIOCSMIIREG: +- return atl1c_mii_ioctl(netdev, ifr, cmd); +- default: +- return -EOPNOTSUPP; +- } +-} +- +-/* +- * atl1c_alloc_queues - Allocate memory for all rings +- * @adapter: board private structure to initialize +- * +- */ +-static int __devinit atl1c_alloc_queues(struct atl1c_adapter *adapter) +-{ +- return 0; +-} +- +-static void atl1c_set_mac_type(struct atl1c_hw *hw) +-{ +- switch (hw->device_id) { +- case PCI_DEVICE_ID_ATTANSIC_L2C: +- hw->nic_type = athr_l2c; +- break; +- +- case PCI_DEVICE_ID_ATTANSIC_L1C: +- hw->nic_type = athr_l1c; +- break; +- +- default: +- break; +- } +-} +- +-static int atl1c_setup_mac_funcs(struct atl1c_hw *hw) +-{ +- u32 phy_status_data; +- u32 link_ctrl_data; +- +- atl1c_set_mac_type(hw); +- AT_READ_REG(hw, REG_PHY_STATUS, &phy_status_data); +- AT_READ_REG(hw, REG_LINK_CTRL, &link_ctrl_data); +- +- hw->ctrl_flags = ATL1C_INTR_CLEAR_ON_READ | +- ATL1C_INTR_MODRT_ENABLE | +- ATL1C_RX_IPV6_CHKSUM | +- ATL1C_TXQ_MODE_ENHANCE; +- if (link_ctrl_data & LINK_CTRL_L0S_EN) +- hw->ctrl_flags |= ATL1C_ASPM_L0S_SUPPORT; +- if (link_ctrl_data & LINK_CTRL_L1_EN) +- hw->ctrl_flags |= ATL1C_ASPM_L1_SUPPORT; +- +- if (hw->nic_type == athr_l1c) { +- hw->ctrl_flags |= ATL1C_ASPM_CTRL_MON; +- hw->ctrl_flags |= ATL1C_LINK_CAP_1000M; +- } +- return 0; +-} +-/* +- * atl1c_sw_init - Initialize general software structures (struct atl1c_adapter) +- * @adapter: board private structure to initialize +- * +- * atl1c_sw_init initializes the Adapter private data structure. +- * Fields are initialized based on PCI device information and +- * OS network device settings (MTU size). +- */ +-static int __devinit atl1c_sw_init(struct atl1c_adapter *adapter) +-{ +- struct atl1c_hw *hw = &adapter->hw; +- struct pci_dev *pdev = adapter->pdev; +- +- adapter->wol = 0; +- adapter->link_speed = SPEED_0; +- adapter->link_duplex = FULL_DUPLEX; +- adapter->num_rx_queues = AT_DEF_RECEIVE_QUEUE; +- adapter->tpd_ring[0].count = 1024; +- adapter->rfd_ring[0].count = 512; +- +- hw->vendor_id = pdev->vendor; +- hw->device_id = pdev->device; +- hw->subsystem_vendor_id = pdev->subsystem_vendor; +- hw->subsystem_id = pdev->subsystem_device; +- +- /* before link up, we assume hibernate is true */ +- hw->hibernate = true; +- hw->media_type = MEDIA_TYPE_AUTO_SENSOR; +- if (atl1c_setup_mac_funcs(hw) != 0) { +- dev_err(&pdev->dev, "set mac function pointers failed\n"); +- return -1; +- } +- hw->intr_mask = IMR_NORMAL_MASK; +- hw->phy_configured = false; +- hw->preamble_len = 7; +- hw->max_frame_size = adapter->netdev->mtu; +- if (adapter->num_rx_queues < 2) { +- hw->rss_type = atl1c_rss_disable; +- hw->rss_mode = atl1c_rss_mode_disable; +- } else { +- hw->rss_type = atl1c_rss_ipv4; +- hw->rss_mode = atl1c_rss_mul_que_mul_int; +- hw->rss_hash_bits = 16; +- } +- hw->autoneg_advertised = ADVERTISED_Autoneg; +- hw->indirect_tab = 0xE4E4E4E4; +- hw->base_cpu = 0; +- +- hw->ict = 50000; /* 100ms */ +- hw->smb_timer = 200000; /* 400ms */ +- hw->cmb_tpd = 4; +- hw->cmb_tx_timer = 1; /* 2 us */ +- hw->rx_imt = 200; +- hw->tx_imt = 1000; +- +- hw->tpd_burst = 5; +- hw->rfd_burst = 8; +- hw->dma_order = atl1c_dma_ord_out; +- hw->dmar_block = atl1c_dma_req_1024; +- hw->dmaw_block = atl1c_dma_req_1024; +- hw->dmar_dly_cnt = 15; +- hw->dmaw_dly_cnt = 4; +- +- if (atl1c_alloc_queues(adapter)) { +- dev_err(&pdev->dev, "Unable to allocate memory for queues\n"); +- return -ENOMEM; +- } +- /* TODO */ +- atl1c_set_rxbufsize(adapter, adapter->netdev); +- atomic_set(&adapter->irq_sem, 1); +- spin_lock_init(&adapter->mdio_lock); +- spin_lock_init(&adapter->tx_lock); +- set_bit(__AT_DOWN, &adapter->flags); +- +- return 0; +-} +- +-/* +- * atl1c_clean_tx_ring - Free Tx-skb +- * @adapter: board private structure +- */ +-static void atl1c_clean_tx_ring(struct atl1c_adapter *adapter, +- enum atl1c_trans_queue type) +-{ +- struct atl1c_tpd_ring *tpd_ring = &adapter->tpd_ring[type]; +- struct atl1c_buffer *buffer_info; +- struct pci_dev *pdev = adapter->pdev; +- u16 index, ring_count; +- +- ring_count = tpd_ring->count; +- for (index = 0; index < ring_count; index++) { +- buffer_info = &tpd_ring->buffer_info[index]; +- if (buffer_info->state == ATL1_BUFFER_FREE) +- continue; +- if (buffer_info->dma) +- pci_unmap_single(pdev, buffer_info->dma, +- buffer_info->length, +- PCI_DMA_TODEVICE); +- if (buffer_info->skb) +- dev_kfree_skb(buffer_info->skb); +- buffer_info->dma = 0; +- buffer_info->skb = NULL; +- buffer_info->state = ATL1_BUFFER_FREE; +- } +- +- /* Zero out Tx-buffers */ +- memset(tpd_ring->desc, 0, sizeof(struct atl1c_tpd_desc) * +- ring_count); +- atomic_set(&tpd_ring->next_to_clean, 0); +- tpd_ring->next_to_use = 0; +-} +- +-/* +- * atl1c_clean_rx_ring - Free rx-reservation skbs +- * @adapter: board private structure +- */ +-static void atl1c_clean_rx_ring(struct atl1c_adapter *adapter) +-{ +- struct atl1c_rfd_ring *rfd_ring = adapter->rfd_ring; +- struct atl1c_rrd_ring *rrd_ring = adapter->rrd_ring; +- struct atl1c_buffer *buffer_info; +- struct pci_dev *pdev = adapter->pdev; +- int i, j; +- +- for (i = 0; i < adapter->num_rx_queues; i++) { +- for (j = 0; j < rfd_ring[i].count; j++) { +- buffer_info = &rfd_ring[i].buffer_info[j]; +- if (buffer_info->state == ATL1_BUFFER_FREE) +- continue; +- if (buffer_info->dma) +- pci_unmap_single(pdev, buffer_info->dma, +- buffer_info->length, +- PCI_DMA_FROMDEVICE); +- if (buffer_info->skb) +- dev_kfree_skb(buffer_info->skb); +- buffer_info->state = ATL1_BUFFER_FREE; +- buffer_info->skb = NULL; +- } +- /* zero out the descriptor ring */ +- memset(rfd_ring[i].desc, 0, rfd_ring[i].size); +- rfd_ring[i].next_to_clean = 0; +- rfd_ring[i].next_to_use = 0; +- rrd_ring[i].next_to_use = 0; +- rrd_ring[i].next_to_clean = 0; +- } +-} +- +-/* +- * Read / Write Ptr Initialize: +- */ +-static void atl1c_init_ring_ptrs(struct atl1c_adapter *adapter) +-{ +- struct atl1c_tpd_ring *tpd_ring = adapter->tpd_ring; +- struct atl1c_rfd_ring *rfd_ring = adapter->rfd_ring; +- struct atl1c_rrd_ring *rrd_ring = adapter->rrd_ring; +- struct atl1c_buffer *buffer_info; +- int i, j; +- +- for (i = 0; i < AT_MAX_TRANSMIT_QUEUE; i++) { +- tpd_ring[i].next_to_use = 0; +- atomic_set(&tpd_ring[i].next_to_clean, 0); +- buffer_info = tpd_ring[i].buffer_info; +- for (j = 0; j < tpd_ring->count; j++) +- buffer_info[i].state = ATL1_BUFFER_FREE; +- } +- for (i = 0; i < adapter->num_rx_queues; i++) { +- rfd_ring[i].next_to_use = 0; +- rfd_ring[i].next_to_clean = 0; +- rrd_ring[i].next_to_use = 0; +- rrd_ring[i].next_to_clean = 0; +- for (j = 0; j < rfd_ring[i].count; j++) { +- buffer_info = &rfd_ring[i].buffer_info[j]; +- buffer_info->state = ATL1_BUFFER_FREE; +- } +- } +-} +- +-/* +- * atl1c_free_ring_resources - Free Tx / RX descriptor Resources +- * @adapter: board private structure +- * +- * Free all transmit software resources +- */ +-static void atl1c_free_ring_resources(struct atl1c_adapter *adapter) +-{ +- struct pci_dev *pdev = adapter->pdev; +- +- pci_free_consistent(pdev, adapter->ring_header.size, +- adapter->ring_header.desc, +- adapter->ring_header.dma); +- adapter->ring_header.desc = NULL; +- +- /* Note: just free tdp_ring.buffer_info, +- * it contain rfd_ring.buffer_info, do not double free */ +- if (adapter->tpd_ring[0].buffer_info) { +- kfree(adapter->tpd_ring[0].buffer_info); +- adapter->tpd_ring[0].buffer_info = NULL; +- } +-} +- +-/* +- * atl1c_setup_mem_resources - allocate Tx / RX descriptor resources +- * @adapter: board private structure +- * +- * Return 0 on success, negative on failure +- */ +-static int atl1c_setup_ring_resources(struct atl1c_adapter *adapter) +-{ +- struct pci_dev *pdev = adapter->pdev; +- struct atl1c_tpd_ring *tpd_ring = adapter->tpd_ring; +- struct atl1c_rfd_ring *rfd_ring = adapter->rfd_ring; +- struct atl1c_rrd_ring *rrd_ring = adapter->rrd_ring; +- struct atl1c_ring_header *ring_header = &adapter->ring_header; +- int num_rx_queues = adapter->num_rx_queues; +- int size; +- int i; +- int count = 0; +- int rx_desc_count = 0; +- u32 offset = 0; +- +- rrd_ring[0].count = rfd_ring[0].count; +- for (i = 1; i < AT_MAX_TRANSMIT_QUEUE; i++) +- tpd_ring[i].count = tpd_ring[0].count; +- +- for (i = 1; i < adapter->num_rx_queues; i++) +- rfd_ring[i].count = rrd_ring[i].count = rfd_ring[0].count; +- +- /* 2 tpd queue, one high priority queue, +- * another normal priority queue */ +- size = sizeof(struct atl1c_buffer) * (tpd_ring->count * 2 + +- rfd_ring->count * num_rx_queues); +- tpd_ring->buffer_info = kzalloc(size, GFP_KERNEL); +- if (unlikely(!tpd_ring->buffer_info)) { +- dev_err(&pdev->dev, "kzalloc failed, size = %d\n", +- size); +- goto err_nomem; +- } +- for (i = 0; i < AT_MAX_TRANSMIT_QUEUE; i++) { +- tpd_ring[i].buffer_info = +- (struct atl1c_buffer *) (tpd_ring->buffer_info + count); +- count += tpd_ring[i].count; +- } +- +- for (i = 0; i < num_rx_queues; i++) { +- rfd_ring[i].buffer_info = +- (struct atl1c_buffer *) (tpd_ring->buffer_info + count); +- count += rfd_ring[i].count; +- rx_desc_count += rfd_ring[i].count; +- } +- /* +- * real ring DMA buffer +- * each ring/block may need up to 8 bytes for alignment, hence the +- * additional bytes tacked onto the end. +- */ +- ring_header->size = size = +- sizeof(struct atl1c_tpd_desc) * tpd_ring->count * 2 + +- sizeof(struct atl1c_rx_free_desc) * rx_desc_count + +- sizeof(struct atl1c_recv_ret_status) * rx_desc_count + +- sizeof(struct atl1c_hw_stats) + +- 8 * 4 + 8 * 2 * num_rx_queues; +- +- ring_header->desc = pci_alloc_consistent(pdev, ring_header->size, +- &ring_header->dma); +- if (unlikely(!ring_header->desc)) { +- dev_err(&pdev->dev, "pci_alloc_consistend failed\n"); +- goto err_nomem; +- } +- memset(ring_header->desc, 0, ring_header->size); +- /* init TPD ring */ +- +- tpd_ring[0].dma = roundup(ring_header->dma, 8); +- offset = tpd_ring[0].dma - ring_header->dma; +- for (i = 0; i < AT_MAX_TRANSMIT_QUEUE; i++) { +- tpd_ring[i].dma = ring_header->dma + offset; +- tpd_ring[i].desc = (u8 *) ring_header->desc + offset; +- tpd_ring[i].size = +- sizeof(struct atl1c_tpd_desc) * tpd_ring[i].count; +- offset += roundup(tpd_ring[i].size, 8); +- } +- /* init RFD ring */ +- for (i = 0; i < num_rx_queues; i++) { +- rfd_ring[i].dma = ring_header->dma + offset; +- rfd_ring[i].desc = (u8 *) ring_header->desc + offset; +- rfd_ring[i].size = sizeof(struct atl1c_rx_free_desc) * +- rfd_ring[i].count; +- offset += roundup(rfd_ring[i].size, 8); +- } +- +- /* init RRD ring */ +- for (i = 0; i < num_rx_queues; i++) { +- rrd_ring[i].dma = ring_header->dma + offset; +- rrd_ring[i].desc = (u8 *) ring_header->desc + offset; +- rrd_ring[i].size = sizeof(struct atl1c_recv_ret_status) * +- rrd_ring[i].count; +- offset += roundup(rrd_ring[i].size, 8); +- } +- +- adapter->smb.dma = ring_header->dma + offset; +- adapter->smb.smb = (u8 *)ring_header->desc + offset; +- return 0; +- +-err_nomem: +- kfree(tpd_ring->buffer_info); +- return -ENOMEM; +-} +- +-static void atl1c_configure_des_ring(struct atl1c_adapter *adapter) +-{ +- struct atl1c_hw *hw = &adapter->hw; +- struct atl1c_rfd_ring *rfd_ring = (struct atl1c_rfd_ring *) +- adapter->rfd_ring; +- struct atl1c_rrd_ring *rrd_ring = (struct atl1c_rrd_ring *) +- adapter->rrd_ring; +- struct atl1c_tpd_ring *tpd_ring = (struct atl1c_tpd_ring *) +- adapter->tpd_ring; +- struct atl1c_cmb *cmb = (struct atl1c_cmb *) &adapter->cmb; +- struct atl1c_smb *smb = (struct atl1c_smb *) &adapter->smb; +- int i; +- +- /* TPD */ +- AT_WRITE_REG(hw, REG_TX_BASE_ADDR_HI, +- (u32)((tpd_ring[atl1c_trans_normal].dma & +- AT_DMA_HI_ADDR_MASK) >> 32)); +- /* just enable normal priority TX queue */ +- AT_WRITE_REG(hw, REG_NTPD_HEAD_ADDR_LO, +- (u32)(tpd_ring[atl1c_trans_normal].dma & +- AT_DMA_LO_ADDR_MASK)); +- AT_WRITE_REG(hw, REG_HTPD_HEAD_ADDR_LO, +- (u32)(tpd_ring[atl1c_trans_high].dma & +- AT_DMA_LO_ADDR_MASK)); +- AT_WRITE_REG(hw, REG_TPD_RING_SIZE, +- (u32)(tpd_ring[0].count & TPD_RING_SIZE_MASK)); +- +- +- /* RFD */ +- AT_WRITE_REG(hw, REG_RX_BASE_ADDR_HI, +- (u32)((rfd_ring[0].dma & AT_DMA_HI_ADDR_MASK) >> 32)); +- for (i = 0; i < adapter->num_rx_queues; i++) +- AT_WRITE_REG(hw, atl1c_rfd_addr_lo_regs[i], +- (u32)(rfd_ring[i].dma & AT_DMA_LO_ADDR_MASK)); +- +- AT_WRITE_REG(hw, REG_RFD_RING_SIZE, +- rfd_ring[0].count & RFD_RING_SIZE_MASK); +- AT_WRITE_REG(hw, REG_RX_BUF_SIZE, +- adapter->rx_buffer_len & RX_BUF_SIZE_MASK); +- +- /* RRD */ +- for (i = 0; i < adapter->num_rx_queues; i++) +- AT_WRITE_REG(hw, atl1c_rrd_addr_lo_regs[i], +- (u32)(rrd_ring[i].dma & AT_DMA_LO_ADDR_MASK)); +- AT_WRITE_REG(hw, REG_RRD_RING_SIZE, +- (rrd_ring[0].count & RRD_RING_SIZE_MASK)); +- +- /* CMB */ +- AT_WRITE_REG(hw, REG_CMB_BASE_ADDR_LO, cmb->dma & AT_DMA_LO_ADDR_MASK); +- +- /* SMB */ +- AT_WRITE_REG(hw, REG_SMB_BASE_ADDR_HI, +- (u32)((smb->dma & AT_DMA_HI_ADDR_MASK) >> 32)); +- AT_WRITE_REG(hw, REG_SMB_BASE_ADDR_LO, +- (u32)(smb->dma & AT_DMA_LO_ADDR_MASK)); +- /* Load all of base address above */ +- AT_WRITE_REG(hw, REG_LOAD_PTR, 1); +-} +- +-static void atl1c_configure_tx(struct atl1c_adapter *adapter) +-{ +- struct atl1c_hw *hw = &adapter->hw; +- u32 dev_ctrl_data; +- u32 max_pay_load; +- u16 tx_offload_thresh; +- u32 txq_ctrl_data; +- u32 extra_size = 0; /* Jumbo frame threshold in QWORD unit */ +- +- extra_size = ETH_HLEN + VLAN_HLEN + ETH_FCS_LEN; +- tx_offload_thresh = MAX_TX_OFFLOAD_THRESH; +- AT_WRITE_REG(hw, REG_TX_TSO_OFFLOAD_THRESH, +- (tx_offload_thresh >> 3) & TX_TSO_OFFLOAD_THRESH_MASK); +- AT_READ_REG(hw, REG_DEVICE_CTRL, &dev_ctrl_data); +- max_pay_load = (dev_ctrl_data >> DEVICE_CTRL_MAX_PAYLOAD_SHIFT) & +- DEVICE_CTRL_MAX_PAYLOAD_MASK; +- hw->dmaw_block = min(max_pay_load, hw->dmaw_block); +- max_pay_load = (dev_ctrl_data >> DEVICE_CTRL_MAX_RREQ_SZ_SHIFT) & +- DEVICE_CTRL_MAX_RREQ_SZ_MASK; +- hw->dmar_block = min(max_pay_load, hw->dmar_block); +- +- txq_ctrl_data = (hw->tpd_burst & TXQ_NUM_TPD_BURST_MASK) << +- TXQ_NUM_TPD_BURST_SHIFT; +- if (hw->ctrl_flags & ATL1C_TXQ_MODE_ENHANCE) +- txq_ctrl_data |= TXQ_CTRL_ENH_MODE; +- txq_ctrl_data |= (atl1c_pay_load_size[hw->dmar_block] & +- TXQ_TXF_BURST_NUM_MASK) << TXQ_TXF_BURST_NUM_SHIFT; +- +- AT_WRITE_REG(hw, REG_TXQ_CTRL, txq_ctrl_data); +-} +- +-static void atl1c_configure_rx(struct atl1c_adapter *adapter) +-{ +- struct atl1c_hw *hw = &adapter->hw; +- u32 rxq_ctrl_data; +- +- rxq_ctrl_data = (hw->rfd_burst & RXQ_RFD_BURST_NUM_MASK) << +- RXQ_RFD_BURST_NUM_SHIFT; +- +- if (hw->ctrl_flags & ATL1C_RX_IPV6_CHKSUM) +- rxq_ctrl_data |= IPV6_CHKSUM_CTRL_EN; +- if (hw->rss_type == atl1c_rss_ipv4) +- rxq_ctrl_data |= RSS_HASH_IPV4; +- if (hw->rss_type == atl1c_rss_ipv4_tcp) +- rxq_ctrl_data |= RSS_HASH_IPV4_TCP; +- if (hw->rss_type == atl1c_rss_ipv6) +- rxq_ctrl_data |= RSS_HASH_IPV6; +- if (hw->rss_type == atl1c_rss_ipv6_tcp) +- rxq_ctrl_data |= RSS_HASH_IPV6_TCP; +- if (hw->rss_type != atl1c_rss_disable) +- rxq_ctrl_data |= RRS_HASH_CTRL_EN; +- +- rxq_ctrl_data |= (hw->rss_mode & RSS_MODE_MASK) << +- RSS_MODE_SHIFT; +- rxq_ctrl_data |= (hw->rss_hash_bits & RSS_HASH_BITS_MASK) << +- RSS_HASH_BITS_SHIFT; +- if (hw->ctrl_flags & ATL1C_ASPM_CTRL_MON) +- rxq_ctrl_data |= (ASPM_THRUPUT_LIMIT_100M & +- ASPM_THRUPUT_LIMIT_MASK) << ASPM_THRUPUT_LIMIT_SHIFT; +- +- AT_WRITE_REG(hw, REG_RXQ_CTRL, rxq_ctrl_data); +-} +- +-static void atl1c_configure_rss(struct atl1c_adapter *adapter) +-{ +- struct atl1c_hw *hw = &adapter->hw; +- +- AT_WRITE_REG(hw, REG_IDT_TABLE, hw->indirect_tab); +- AT_WRITE_REG(hw, REG_BASE_CPU_NUMBER, hw->base_cpu); +-} +- +-static void atl1c_configure_dma(struct atl1c_adapter *adapter) +-{ +- struct atl1c_hw *hw = &adapter->hw; +- u32 dma_ctrl_data; +- +- dma_ctrl_data = DMA_CTRL_DMAR_REQ_PRI; +- if (hw->ctrl_flags & ATL1C_CMB_ENABLE) +- dma_ctrl_data |= DMA_CTRL_CMB_EN; +- if (hw->ctrl_flags & ATL1C_SMB_ENABLE) +- dma_ctrl_data |= DMA_CTRL_SMB_EN; +- else +- dma_ctrl_data |= MAC_CTRL_SMB_DIS; +- +- switch (hw->dma_order) { +- case atl1c_dma_ord_in: +- dma_ctrl_data |= DMA_CTRL_DMAR_IN_ORDER; +- break; +- case atl1c_dma_ord_enh: +- dma_ctrl_data |= DMA_CTRL_DMAR_ENH_ORDER; +- break; +- case atl1c_dma_ord_out: +- dma_ctrl_data |= DMA_CTRL_DMAR_OUT_ORDER; +- break; +- default: +- break; +- } +- +- dma_ctrl_data |= (((u32)hw->dmar_block) & DMA_CTRL_DMAR_BURST_LEN_MASK) +- << DMA_CTRL_DMAR_BURST_LEN_SHIFT; +- dma_ctrl_data |= (((u32)hw->dmaw_block) & DMA_CTRL_DMAW_BURST_LEN_MASK) +- << DMA_CTRL_DMAW_BURST_LEN_SHIFT; +- dma_ctrl_data |= (((u32)hw->dmar_dly_cnt) & DMA_CTRL_DMAR_DLY_CNT_MASK) +- << DMA_CTRL_DMAR_DLY_CNT_SHIFT; +- dma_ctrl_data |= (((u32)hw->dmaw_dly_cnt) & DMA_CTRL_DMAW_DLY_CNT_MASK) +- << DMA_CTRL_DMAW_DLY_CNT_SHIFT; +- +- AT_WRITE_REG(hw, REG_DMA_CTRL, dma_ctrl_data); +-} +- +-/* +- * Stop the mac, transmit and receive units +- * hw - Struct containing variables accessed by shared code +- * return : 0 or idle status (if error) +- */ +-static int atl1c_stop_mac(struct atl1c_hw *hw) +-{ +- u32 data; +- int timeout; +- +- AT_READ_REG(hw, REG_RXQ_CTRL, &data); +- data &= ~(RXQ1_CTRL_EN | RXQ2_CTRL_EN | +- RXQ3_CTRL_EN | RXQ_CTRL_EN); +- AT_WRITE_REG(hw, REG_RXQ_CTRL, data); +- +- AT_READ_REG(hw, REG_TXQ_CTRL, &data); +- data &= ~TXQ_CTRL_EN; +- AT_WRITE_REG(hw, REG_TWSI_CTRL, data); +- +- for (timeout = 0; timeout < AT_HW_MAX_IDLE_DELAY; timeout++) { +- AT_READ_REG(hw, REG_IDLE_STATUS, &data); +- if ((data & (IDLE_STATUS_RXQ_NO_IDLE | +- IDLE_STATUS_TXQ_NO_IDLE)) == 0) +- break; +- msleep(1); +- } +- +- AT_READ_REG(hw, REG_MAC_CTRL, &data); +- data &= ~(MAC_CTRL_TX_EN | MAC_CTRL_RX_EN); +- AT_WRITE_REG(hw, REG_MAC_CTRL, data); +- +- for (timeout = 0; timeout < AT_HW_MAX_IDLE_DELAY; timeout++) { +- AT_READ_REG(hw, REG_IDLE_STATUS, &data); +- if ((data & IDLE_STATUS_MASK) == 0) +- return 0; +- msleep(1); +- } +- return data; +-} +- +-static void atl1c_enable_rx_ctrl(struct atl1c_hw *hw) +-{ +- u32 data; +- +- AT_READ_REG(hw, REG_RXQ_CTRL, &data); +- switch (hw->adapter->num_rx_queues) { +- case 4: +- data |= (RXQ3_CTRL_EN | RXQ2_CTRL_EN | RXQ1_CTRL_EN); +- break; +- case 3: +- data |= (RXQ2_CTRL_EN | RXQ1_CTRL_EN); +- break; +- case 2: +- data |= RXQ1_CTRL_EN; +- break; +- default: +- break; +- } +- data |= RXQ_CTRL_EN; +- AT_WRITE_REG(hw, REG_RXQ_CTRL, data); +-} +- +-static void atl1c_enable_tx_ctrl(struct atl1c_hw *hw) +-{ +- u32 data; +- +- AT_READ_REG(hw, REG_TXQ_CTRL, &data); +- data |= TXQ_CTRL_EN; +- AT_WRITE_REG(hw, REG_TXQ_CTRL, data); +-} +- +-/* +- * Reset the transmit and receive units; mask and clear all interrupts. +- * hw - Struct containing variables accessed by shared code +- * return : 0 or idle status (if error) +- */ +-static int atl1c_reset_mac(struct atl1c_hw *hw) +-{ +- struct atl1c_adapter *adapter = (struct atl1c_adapter *)hw->adapter; +- struct pci_dev *pdev = adapter->pdev; +- u32 idle_status_data = 0; +- int timeout = 0; +- int ret; +- +- AT_WRITE_REG(hw, REG_IMR, 0); +- AT_WRITE_REG(hw, REG_ISR, ISR_DIS_INT); +- +- ret = atl1c_stop_mac(hw); +- if (ret) +- return ret; +- /* +- * Issue Soft Reset to the MAC. This will reset the chip's +- * transmit, receive, DMA. It will not effect +- * the current PCI configuration. The global reset bit is self- +- * clearing, and should clear within a microsecond. +- */ +- AT_WRITE_REGW(hw, REG_MASTER_CTRL, MASTER_CTRL_SOFT_RST); +- AT_WRITE_FLUSH(hw); +- msleep(10); +- /* Wait at least 10ms for All module to be Idle */ +- for (timeout = 0; timeout < AT_HW_MAX_IDLE_DELAY; timeout++) { +- AT_READ_REG(hw, REG_IDLE_STATUS, &idle_status_data); +- if ((idle_status_data & IDLE_STATUS_MASK) == 0) +- break; +- msleep(1); +- } +- if (timeout >= AT_HW_MAX_IDLE_DELAY) { +- dev_err(&pdev->dev, +- "MAC state machine cann't be idle since" +- " disabled for 10ms second\n"); +- return -1; +- } +- return 0; +-} +- +-static void atl1c_disable_l0s_l1(struct atl1c_hw *hw) +-{ +- u32 pm_ctrl_data; +- +- AT_READ_REG(hw, REG_PM_CTRL, &pm_ctrl_data); +- pm_ctrl_data &= ~(PM_CTRL_L1_ENTRY_TIMER_MASK << +- PM_CTRL_L1_ENTRY_TIMER_SHIFT); +- pm_ctrl_data &= ~PM_CTRL_CLK_SWH_L1; +- pm_ctrl_data &= ~PM_CTRL_ASPM_L0S_EN; +- pm_ctrl_data &= ~PM_CTRL_ASPM_L1_EN; +- pm_ctrl_data &= ~PM_CTRL_MAC_ASPM_CHK; +- pm_ctrl_data &= ~PM_CTRL_SERDES_PD_EX_L1; +- +- pm_ctrl_data |= PM_CTRL_SERDES_BUDS_RX_L1_EN; +- pm_ctrl_data |= PM_CTRL_SERDES_PLL_L1_EN; +- pm_ctrl_data |= PM_CTRL_SERDES_L1_EN; +- AT_WRITE_REG(hw, REG_PM_CTRL, pm_ctrl_data); +-} +- +-/* +- * Set ASPM state. +- * Enable/disable L0s/L1 depend on link state. +- */ +-static void atl1c_set_aspm(struct atl1c_hw *hw, bool linkup) +-{ +- u32 pm_ctrl_data; +- +- AT_READ_REG(hw, REG_PM_CTRL, &pm_ctrl_data); +- +- pm_ctrl_data &= PM_CTRL_SERDES_PD_EX_L1; +- pm_ctrl_data |= ~PM_CTRL_SERDES_BUDS_RX_L1_EN; +- pm_ctrl_data |= ~PM_CTRL_SERDES_L1_EN; +- pm_ctrl_data &= ~(PM_CTRL_L1_ENTRY_TIMER_MASK << +- PM_CTRL_L1_ENTRY_TIMER_SHIFT); +- +- pm_ctrl_data |= PM_CTRL_MAC_ASPM_CHK; +- +- if (linkup) { +- pm_ctrl_data |= PM_CTRL_SERDES_PLL_L1_EN; +- pm_ctrl_data &= ~PM_CTRL_CLK_SWH_L1; +- +- if (hw->ctrl_flags & ATL1C_ASPM_L1_SUPPORT) { +- pm_ctrl_data |= AT_ASPM_L1_TIMER << +- PM_CTRL_L1_ENTRY_TIMER_SHIFT; +- pm_ctrl_data |= PM_CTRL_ASPM_L1_EN; +- } else +- pm_ctrl_data &= ~PM_CTRL_ASPM_L1_EN; +- +- if (hw->ctrl_flags & ATL1C_ASPM_L0S_SUPPORT) +- pm_ctrl_data |= PM_CTRL_ASPM_L0S_EN; +- else +- pm_ctrl_data &= ~PM_CTRL_ASPM_L0S_EN; +- +- } else { +- pm_ctrl_data &= ~PM_CTRL_ASPM_L0S_EN; +- pm_ctrl_data &= ~PM_CTRL_SERDES_PLL_L1_EN; +- +- pm_ctrl_data |= PM_CTRL_CLK_SWH_L1; +- +- if (hw->ctrl_flags & ATL1C_ASPM_L1_SUPPORT) +- pm_ctrl_data |= PM_CTRL_ASPM_L1_EN; +- else +- pm_ctrl_data &= ~PM_CTRL_ASPM_L1_EN; +- } +- +- AT_WRITE_REG(hw, REG_PM_CTRL, pm_ctrl_data); +-} +- +-static void atl1c_setup_mac_ctrl(struct atl1c_adapter *adapter) +-{ +- struct atl1c_hw *hw = &adapter->hw; +- struct net_device *netdev = adapter->netdev; +- u32 mac_ctrl_data; +- +- mac_ctrl_data = MAC_CTRL_TX_EN | MAC_CTRL_RX_EN; +- mac_ctrl_data |= (MAC_CTRL_TX_FLOW | MAC_CTRL_RX_FLOW); +- +- if (adapter->link_duplex == FULL_DUPLEX) { +- hw->mac_duplex = true; +- mac_ctrl_data |= MAC_CTRL_DUPLX; +- } +- +- if (adapter->link_speed == SPEED_1000) +- hw->mac_speed = atl1c_mac_speed_1000; +- else +- hw->mac_speed = atl1c_mac_speed_10_100; +- +- mac_ctrl_data |= (hw->mac_speed & MAC_CTRL_SPEED_MASK) << +- MAC_CTRL_SPEED_SHIFT; +- +- mac_ctrl_data |= (MAC_CTRL_ADD_CRC | MAC_CTRL_PAD); +- mac_ctrl_data |= ((hw->preamble_len & MAC_CTRL_PRMLEN_MASK) << +- MAC_CTRL_PRMLEN_SHIFT); +- +- if (adapter->vlgrp) +- mac_ctrl_data |= MAC_CTRL_RMV_VLAN; +- +- mac_ctrl_data |= MAC_CTRL_BC_EN; +- if (netdev->flags & IFF_PROMISC) +- mac_ctrl_data |= MAC_CTRL_PROMIS_EN; +- if (netdev->flags & IFF_ALLMULTI) +- mac_ctrl_data |= MAC_CTRL_MC_ALL_EN; +- +- mac_ctrl_data |= MAC_CTRL_SINGLE_PAUSE_EN; +- AT_WRITE_REG(hw, REG_MAC_CTRL, mac_ctrl_data); +-} +- +-/* +- * atl1c_configure - Configure Transmit&Receive Unit after Reset +- * @adapter: board private structure +- * +- * Configure the Tx /Rx unit of the MAC after a reset. +- */ +-static int atl1c_configure(struct atl1c_adapter *adapter) +-{ +- struct atl1c_hw *hw = &adapter->hw; +- u32 master_ctrl_data = 0; +- u32 intr_modrt_data; +- +- /* clear interrupt status */ +- AT_WRITE_REG(hw, REG_ISR, 0xFFFFFFFF); +- /* Clear any WOL status */ +- AT_WRITE_REG(hw, REG_WOL_CTRL, 0); +- /* set Interrupt Clear Timer +- * HW will enable self to assert interrupt event to system after +- * waiting x-time for software to notify it accept interrupt. +- */ +- AT_WRITE_REG(hw, REG_INT_RETRIG_TIMER, +- hw->ict & INT_RETRIG_TIMER_MASK); +- +- atl1c_configure_des_ring(adapter); +- +- if (hw->ctrl_flags & ATL1C_INTR_MODRT_ENABLE) { +- intr_modrt_data = (hw->tx_imt & IRQ_MODRT_TIMER_MASK) << +- IRQ_MODRT_TX_TIMER_SHIFT; +- intr_modrt_data |= (hw->rx_imt & IRQ_MODRT_TIMER_MASK) << +- IRQ_MODRT_RX_TIMER_SHIFT; +- AT_WRITE_REG(hw, REG_IRQ_MODRT_TIMER_INIT, intr_modrt_data); +- master_ctrl_data |= +- MASTER_CTRL_TX_ITIMER_EN | MASTER_CTRL_RX_ITIMER_EN; +- } +- +- if (hw->ctrl_flags & ATL1C_INTR_CLEAR_ON_READ) +- master_ctrl_data |= MASTER_CTRL_INT_RDCLR; +- +- AT_WRITE_REG(hw, REG_MASTER_CTRL, master_ctrl_data); +- +- if (hw->ctrl_flags & ATL1C_CMB_ENABLE) { +- AT_WRITE_REG(hw, REG_CMB_TPD_THRESH, +- hw->cmb_tpd & CMB_TPD_THRESH_MASK); +- AT_WRITE_REG(hw, REG_CMB_TX_TIMER, +- hw->cmb_tx_timer & CMB_TX_TIMER_MASK); +- } +- +- if (hw->ctrl_flags & ATL1C_SMB_ENABLE) +- AT_WRITE_REG(hw, REG_SMB_STAT_TIMER, +- hw->smb_timer & SMB_STAT_TIMER_MASK); +- /* set MTU */ +- AT_WRITE_REG(hw, REG_MTU, hw->max_frame_size + ETH_HLEN + +- VLAN_HLEN + ETH_FCS_LEN); +- /* HDS, disable */ +- AT_WRITE_REG(hw, REG_HDS_CTRL, 0); +- +- atl1c_configure_tx(adapter); +- atl1c_configure_rx(adapter); +- atl1c_configure_rss(adapter); +- atl1c_configure_dma(adapter); +- +- return 0; +-} +- +-static void atl1c_update_hw_stats(struct atl1c_adapter *adapter) +-{ +- u16 hw_reg_addr = 0; +- unsigned long *stats_item = NULL; +- u32 data; +- +- /* update rx status */ +- hw_reg_addr = REG_MAC_RX_STATUS_BIN; +- stats_item = &adapter->hw_stats.rx_ok; +- while (hw_reg_addr <= REG_MAC_RX_STATUS_END) { +- AT_READ_REG(&adapter->hw, hw_reg_addr, &data); +- *stats_item += data; +- stats_item++; +- hw_reg_addr += 4; +- } +-/* update tx status */ +- hw_reg_addr = REG_MAC_TX_STATUS_BIN; +- stats_item = &adapter->hw_stats.tx_ok; +- while (hw_reg_addr <= REG_MAC_TX_STATUS_END) { +- AT_READ_REG(&adapter->hw, hw_reg_addr, &data); +- *stats_item += data; +- stats_item++; +- hw_reg_addr += 4; +- } +-} +- +-/* +- * atl1c_get_stats - Get System Network Statistics +- * @netdev: network interface device structure +- * +- * Returns the address of the device statistics structure. +- * The statistics are actually updated from the timer callback. +- */ +-static struct net_device_stats *atl1c_get_stats(struct net_device *netdev) +-{ +- struct atl1c_adapter *adapter = netdev_priv(netdev); +- struct atl1c_hw_stats *hw_stats = &adapter->hw_stats; +- struct net_device_stats *net_stats = &adapter->net_stats; +- +- atl1c_update_hw_stats(adapter); +- net_stats->rx_packets = hw_stats->rx_ok; +- net_stats->tx_packets = hw_stats->tx_ok; +- net_stats->rx_bytes = hw_stats->rx_byte_cnt; +- net_stats->tx_bytes = hw_stats->tx_byte_cnt; +- net_stats->multicast = hw_stats->rx_mcast; +- net_stats->collisions = hw_stats->tx_1_col + +- hw_stats->tx_2_col * 2 + +- hw_stats->tx_late_col + hw_stats->tx_abort_col; +- net_stats->rx_errors = hw_stats->rx_frag + hw_stats->rx_fcs_err + +- hw_stats->rx_len_err + hw_stats->rx_sz_ov + +- hw_stats->rx_rrd_ov + hw_stats->rx_align_err; +- net_stats->rx_fifo_errors = hw_stats->rx_rxf_ov; +- net_stats->rx_length_errors = hw_stats->rx_len_err; +- net_stats->rx_crc_errors = hw_stats->rx_fcs_err; +- net_stats->rx_frame_errors = hw_stats->rx_align_err; +- net_stats->rx_over_errors = hw_stats->rx_rrd_ov + hw_stats->rx_rxf_ov; +- +- net_stats->rx_missed_errors = hw_stats->rx_rrd_ov + hw_stats->rx_rxf_ov; +- +- net_stats->tx_errors = hw_stats->tx_late_col + hw_stats->tx_abort_col + +- hw_stats->tx_underrun + hw_stats->tx_trunc; +- net_stats->tx_fifo_errors = hw_stats->tx_underrun; +- net_stats->tx_aborted_errors = hw_stats->tx_abort_col; +- net_stats->tx_window_errors = hw_stats->tx_late_col; +- +- return &adapter->net_stats; +-} +- +-static inline void atl1c_clear_phy_int(struct atl1c_adapter *adapter) +-{ +- u16 phy_data; +- +- spin_lock(&adapter->mdio_lock); +- atl1c_read_phy_reg(&adapter->hw, MII_ISR, &phy_data); +- spin_unlock(&adapter->mdio_lock); +-} +- +-static bool atl1c_clean_tx_irq(struct atl1c_adapter *adapter, +- enum atl1c_trans_queue type) +-{ +- struct atl1c_tpd_ring *tpd_ring = (struct atl1c_tpd_ring *) +- &adapter->tpd_ring[type]; +- struct atl1c_buffer *buffer_info; +- u16 next_to_clean = atomic_read(&tpd_ring->next_to_clean); +- u16 hw_next_to_clean; +- u16 shift; +- u32 data; +- +- if (type == atl1c_trans_high) +- shift = MB_HTPD_CONS_IDX_SHIFT; +- else +- shift = MB_NTPD_CONS_IDX_SHIFT; +- +- AT_READ_REG(&adapter->hw, REG_MB_PRIO_CONS_IDX, &data); +- hw_next_to_clean = (data >> shift) & MB_PRIO_PROD_IDX_MASK; +- +- while (next_to_clean != hw_next_to_clean) { +- buffer_info = &tpd_ring->buffer_info[next_to_clean]; +- if (buffer_info->state == ATL1_BUFFER_BUSY) { +- pci_unmap_page(adapter->pdev, buffer_info->dma, +- buffer_info->length, PCI_DMA_TODEVICE); +- buffer_info->dma = 0; +- if (buffer_info->skb) { +- dev_kfree_skb_irq(buffer_info->skb); +- buffer_info->skb = NULL; +- } +- buffer_info->state = ATL1_BUFFER_FREE; +- } +- if (++next_to_clean == tpd_ring->count) +- next_to_clean = 0; +- atomic_set(&tpd_ring->next_to_clean, next_to_clean); +- } +- +- if (netif_queue_stopped(adapter->netdev) && +- netif_carrier_ok(adapter->netdev)) { +- netif_wake_queue(adapter->netdev); +- } +- +- return true; +-} +- +-/* +- * atl1c_intr - Interrupt Handler +- * @irq: interrupt number +- * @data: pointer to a network interface device structure +- * @pt_regs: CPU registers structure +- */ +-static irqreturn_t atl1c_intr(int irq, void *data) +-{ +- struct net_device *netdev = data; +- struct atl1c_adapter *adapter = netdev_priv(netdev); +- struct pci_dev *pdev = adapter->pdev; +- struct atl1c_hw *hw = &adapter->hw; +- int max_ints = AT_MAX_INT_WORK; +- int handled = IRQ_NONE; +- u32 status; +- u32 reg_data; +- +- do { +- AT_READ_REG(hw, REG_ISR, ®_data); +- status = reg_data & hw->intr_mask; +- +- if (status == 0 || (status & ISR_DIS_INT) != 0) { +- if (max_ints != AT_MAX_INT_WORK) +- handled = IRQ_HANDLED; +- break; +- } +- /* link event */ +- if (status & ISR_GPHY) +- atl1c_clear_phy_int(adapter); +- /* Ack ISR */ +- AT_WRITE_REG(hw, REG_ISR, status | ISR_DIS_INT); +- if (status & ISR_RX_PKT) { +- if (likely(napi_schedule_prep(&adapter->napi))) { +- hw->intr_mask &= ~ISR_RX_PKT; +- AT_WRITE_REG(hw, REG_IMR, hw->intr_mask); +- __napi_schedule(&adapter->napi); +- } +- } +- if (status & ISR_TX_PKT) +- atl1c_clean_tx_irq(adapter, atl1c_trans_normal); +- +- handled = IRQ_HANDLED; +- /* check if PCIE PHY Link down */ +- if (status & ISR_ERROR) { +- if (netif_msg_hw(adapter)) +- dev_err(&pdev->dev, +- "atl1c hardware error (status = 0x%x)\n", +- status & ISR_ERROR); +- /* reset MAC */ +- hw->intr_mask &= ~ISR_ERROR; +- AT_WRITE_REG(hw, REG_IMR, hw->intr_mask); +- schedule_work(&adapter->reset_task); +- break; +- } +- +- if (status & ISR_OVER) +- if (netif_msg_intr(adapter)) +- dev_warn(&pdev->dev, +- "TX/RX over flow (status = 0x%x)\n", +- status & ISR_OVER); +- +- /* link event */ +- if (status & (ISR_GPHY | ISR_MANUAL)) { +- adapter->net_stats.tx_carrier_errors++; +- atl1c_link_chg_event(adapter); +- break; +- } +- +- } while (--max_ints > 0); +- /* re-enable Interrupt*/ +- AT_WRITE_REG(&adapter->hw, REG_ISR, 0); +- return handled; +-} +- +-static inline void atl1c_rx_checksum(struct atl1c_adapter *adapter, +- struct sk_buff *skb, struct atl1c_recv_ret_status *prrs) +-{ +- /* +- * The pid field in RRS in not correct sometimes, so we +- * cannot figure out if the packet is fragmented or not, +- * so we tell the KERNEL CHECKSUM_NONE +- */ +- skb->ip_summed = CHECKSUM_NONE; +-} +- +-static int atl1c_alloc_rx_buffer(struct atl1c_adapter *adapter, const int ringid) +-{ +- struct atl1c_rfd_ring *rfd_ring = &adapter->rfd_ring[ringid]; +- struct pci_dev *pdev = adapter->pdev; +- struct atl1c_buffer *buffer_info, *next_info; +- struct sk_buff *skb; +- void *vir_addr = NULL; +- u16 num_alloc = 0; +- u16 rfd_next_to_use, next_next; +- struct atl1c_rx_free_desc *rfd_desc; +- +- next_next = rfd_next_to_use = rfd_ring->next_to_use; +- if (++next_next == rfd_ring->count) +- next_next = 0; +- buffer_info = &rfd_ring->buffer_info[rfd_next_to_use]; +- next_info = &rfd_ring->buffer_info[next_next]; +- +- while (next_info->state == ATL1_BUFFER_FREE) { +- rfd_desc = ATL1C_RFD_DESC(rfd_ring, rfd_next_to_use); +- +- skb = dev_alloc_skb(adapter->rx_buffer_len); +- if (unlikely(!skb)) { +- if (netif_msg_rx_err(adapter)) +- dev_warn(&pdev->dev, "alloc rx buffer failed\n"); +- break; +- } +- +- /* +- * Make buffer alignment 2 beyond a 16 byte boundary +- * this will result in a 16 byte aligned IP header after +- * the 14 byte MAC header is removed +- */ +- vir_addr = skb->data; +- buffer_info->state = ATL1_BUFFER_BUSY; +- buffer_info->skb = skb; +- buffer_info->length = adapter->rx_buffer_len; +- buffer_info->dma = pci_map_single(pdev, vir_addr, +- buffer_info->length, +- PCI_DMA_FROMDEVICE); +- rfd_desc->buffer_addr = cpu_to_le64(buffer_info->dma); +- rfd_next_to_use = next_next; +- if (++next_next == rfd_ring->count) +- next_next = 0; +- buffer_info = &rfd_ring->buffer_info[rfd_next_to_use]; +- next_info = &rfd_ring->buffer_info[next_next]; +- num_alloc++; +- } +- +- if (num_alloc) { +- /* TODO: update mailbox here */ +- wmb(); +- rfd_ring->next_to_use = rfd_next_to_use; +- AT_WRITE_REG(&adapter->hw, atl1c_rfd_prod_idx_regs[ringid], +- rfd_ring->next_to_use & MB_RFDX_PROD_IDX_MASK); +- } +- +- return num_alloc; +-} +- +-static void atl1c_clean_rrd(struct atl1c_rrd_ring *rrd_ring, +- struct atl1c_recv_ret_status *rrs, u16 num) +-{ +- u16 i; +- /* the relationship between rrd and rfd is one map one */ +- for (i = 0; i < num; i++, rrs = ATL1C_RRD_DESC(rrd_ring, +- rrd_ring->next_to_clean)) { +- rrs->word3 &= ~RRS_RXD_UPDATED; +- if (++rrd_ring->next_to_clean == rrd_ring->count) +- rrd_ring->next_to_clean = 0; +- } +-} +- +-static void atl1c_clean_rfd(struct atl1c_rfd_ring *rfd_ring, +- struct atl1c_recv_ret_status *rrs, u16 num) +-{ +- u16 i; +- u16 rfd_index; +- struct atl1c_buffer *buffer_info = rfd_ring->buffer_info; +- +- rfd_index = (rrs->word0 >> RRS_RX_RFD_INDEX_SHIFT) & +- RRS_RX_RFD_INDEX_MASK; +- for (i = 0; i < num; i++) { +- buffer_info[rfd_index].skb = NULL; +- buffer_info[rfd_index].state = ATL1_BUFFER_FREE; +- if (++rfd_index == rfd_ring->count) +- rfd_index = 0; +- } +- rfd_ring->next_to_clean = rfd_index; +-} +- +-static void atl1c_clean_rx_irq(struct atl1c_adapter *adapter, u8 que, +- int *work_done, int work_to_do) +-{ +- u16 rfd_num, rfd_index; +- u16 count = 0; +- u16 length; +- struct pci_dev *pdev = adapter->pdev; +- struct net_device *netdev = adapter->netdev; +- struct atl1c_rfd_ring *rfd_ring = &adapter->rfd_ring[que]; +- struct atl1c_rrd_ring *rrd_ring = &adapter->rrd_ring[que]; +- struct sk_buff *skb; +- struct atl1c_recv_ret_status *rrs; +- struct atl1c_buffer *buffer_info; +- +- while (1) { +- if (*work_done >= work_to_do) +- break; +- rrs = ATL1C_RRD_DESC(rrd_ring, rrd_ring->next_to_clean); +- if (likely(RRS_RXD_IS_VALID(rrs->word3))) { +- rfd_num = (rrs->word0 >> RRS_RX_RFD_CNT_SHIFT) & +- RRS_RX_RFD_CNT_MASK; +- if (unlikely(rfd_num) != 1) +- /* TODO support mul rfd*/ +- if (netif_msg_rx_err(adapter)) +- dev_warn(&pdev->dev, +- "Multi rfd not support yet!\n"); +- goto rrs_checked; +- } else { +- break; +- } +-rrs_checked: +- atl1c_clean_rrd(rrd_ring, rrs, rfd_num); +- if (rrs->word3 & (RRS_RX_ERR_SUM | RRS_802_3_LEN_ERR)) { +- atl1c_clean_rfd(rfd_ring, rrs, rfd_num); +- if (netif_msg_rx_err(adapter)) +- dev_warn(&pdev->dev, +- "wrong packet! rrs word3 is %x\n", +- rrs->word3); +- continue; +- } +- +- length = le16_to_cpu((rrs->word3 >> RRS_PKT_SIZE_SHIFT) & +- RRS_PKT_SIZE_MASK); +- /* Good Receive */ +- if (likely(rfd_num == 1)) { +- rfd_index = (rrs->word0 >> RRS_RX_RFD_INDEX_SHIFT) & +- RRS_RX_RFD_INDEX_MASK; +- buffer_info = &rfd_ring->buffer_info[rfd_index]; +- pci_unmap_single(pdev, buffer_info->dma, +- buffer_info->length, PCI_DMA_FROMDEVICE); +- skb = buffer_info->skb; +- } else { +- /* TODO */ +- if (netif_msg_rx_err(adapter)) +- dev_warn(&pdev->dev, +- "Multi rfd not support yet!\n"); +- break; +- } +- atl1c_clean_rfd(rfd_ring, rrs, rfd_num); +- skb_put(skb, length - ETH_FCS_LEN); +- skb->protocol = eth_type_trans(skb, netdev); +- skb->dev = netdev; +- atl1c_rx_checksum(adapter, skb, rrs); +- if (unlikely(adapter->vlgrp) && rrs->word3 & RRS_VLAN_INS) { +- u16 vlan; +- +- AT_TAG_TO_VLAN(rrs->vlan_tag, vlan); +- vlan = le16_to_cpu(vlan); +- vlan_hwaccel_receive_skb(skb, adapter->vlgrp, vlan); +- } else +- netif_receive_skb(skb); +- +- netdev->last_rx = jiffies; +- (*work_done)++; +- count++; +- } +- if (count) +- atl1c_alloc_rx_buffer(adapter, que); +-} +- +-/* +- * atl1c_clean - NAPI Rx polling callback +- * @adapter: board private structure +- */ +-static int atl1c_clean(struct napi_struct *napi, int budget) +-{ +- struct atl1c_adapter *adapter = +- container_of(napi, struct atl1c_adapter, napi); +- int work_done = 0; +- +- /* Keep link state information with original netdev */ +- if (!netif_carrier_ok(adapter->netdev)) +- goto quit_polling; +- /* just enable one RXQ */ +- atl1c_clean_rx_irq(adapter, 0, &work_done, budget); +- +- if (work_done < budget) { +-quit_polling: +- napi_complete(napi); +- adapter->hw.intr_mask |= ISR_RX_PKT; +- AT_WRITE_REG(&adapter->hw, REG_IMR, adapter->hw.intr_mask); +- } +- return work_done; +-} +- +-#ifdef CONFIG_NET_POLL_CONTROLLER +- +-/* +- * Polling 'interrupt' - used by things like netconsole to send skbs +- * without having to re-enable interrupts. It's not called while +- * the interrupt routine is executing. +- */ +-static void atl1c_netpoll(struct net_device *netdev) +-{ +- struct atl1c_adapter *adapter = netdev_priv(netdev); +- +- disable_irq(adapter->pdev->irq); +- atl1c_intr(adapter->pdev->irq, netdev); +- enable_irq(adapter->pdev->irq); +-} +-#endif +- +-static inline u16 atl1c_tpd_avail(struct atl1c_adapter *adapter, enum atl1c_trans_queue type) +-{ +- struct atl1c_tpd_ring *tpd_ring = &adapter->tpd_ring[type]; +- u16 next_to_use = 0; +- u16 next_to_clean = 0; +- +- next_to_clean = atomic_read(&tpd_ring->next_to_clean); +- next_to_use = tpd_ring->next_to_use; +- +- return (u16)(next_to_clean > next_to_use) ? +- (next_to_clean - next_to_use - 1) : +- (tpd_ring->count + next_to_clean - next_to_use - 1); +-} +- +-/* +- * get next usable tpd +- * Note: should call atl1c_tdp_avail to make sure +- * there is enough tpd to use +- */ +-static struct atl1c_tpd_desc *atl1c_get_tpd(struct atl1c_adapter *adapter, +- enum atl1c_trans_queue type) +-{ +- struct atl1c_tpd_ring *tpd_ring = &adapter->tpd_ring[type]; +- struct atl1c_tpd_desc *tpd_desc; +- u16 next_to_use = 0; +- +- next_to_use = tpd_ring->next_to_use; +- if (++tpd_ring->next_to_use == tpd_ring->count) +- tpd_ring->next_to_use = 0; +- tpd_desc = ATL1C_TPD_DESC(tpd_ring, next_to_use); +- memset(tpd_desc, 0, sizeof(struct atl1c_tpd_desc)); +- return tpd_desc; +-} +- +-static struct atl1c_buffer * +-atl1c_get_tx_buffer(struct atl1c_adapter *adapter, struct atl1c_tpd_desc *tpd) +-{ +- struct atl1c_tpd_ring *tpd_ring = adapter->tpd_ring; +- +- return &tpd_ring->buffer_info[tpd - +- (struct atl1c_tpd_desc *)tpd_ring->desc]; +-} +- +-/* Calculate the transmit packet descript needed*/ +-static u16 atl1c_cal_tpd_req(const struct sk_buff *skb) +-{ +- u16 tpd_req; +- u16 proto_hdr_len = 0; +- +- tpd_req = skb_shinfo(skb)->nr_frags + 1; +- +- if (skb_is_gso(skb)) { +- proto_hdr_len = skb_transport_offset(skb) + tcp_hdrlen(skb); +- if (proto_hdr_len < skb_headlen(skb)) +- tpd_req++; +- if (skb_shinfo(skb)->gso_type & SKB_GSO_TCPV6) +- tpd_req++; +- } +- return tpd_req; +-} +- +-static int atl1c_tso_csum(struct atl1c_adapter *adapter, +- struct sk_buff *skb, +- struct atl1c_tpd_desc **tpd, +- enum atl1c_trans_queue type) +-{ +- struct pci_dev *pdev = adapter->pdev; +- u8 hdr_len; +- u32 real_len; +- unsigned short offload_type; +- int err; +- +- if (skb_is_gso(skb)) { +- if (skb_header_cloned(skb)) { +- err = pskb_expand_head(skb, 0, 0, GFP_ATOMIC); +- if (unlikely(err)) +- return -1; +- } +- offload_type = skb_shinfo(skb)->gso_type; +- +- if (offload_type & SKB_GSO_TCPV4) { +- real_len = (((unsigned char *)ip_hdr(skb) - skb->data) +- + ntohs(ip_hdr(skb)->tot_len)); +- +- if (real_len < skb->len) +- pskb_trim(skb, real_len); +- +- hdr_len = (skb_transport_offset(skb) + tcp_hdrlen(skb)); +- if (unlikely(skb->len == hdr_len)) { +- /* only xsum need */ +- if (netif_msg_tx_queued(adapter)) +- dev_warn(&pdev->dev, +- "IPV4 tso with zero data??\n"); +- goto check_sum; +- } else { +- ip_hdr(skb)->check = 0; +- tcp_hdr(skb)->check = ~csum_tcpudp_magic( +- ip_hdr(skb)->saddr, +- ip_hdr(skb)->daddr, +- 0, IPPROTO_TCP, 0); +- (*tpd)->word1 |= 1 << TPD_IPV4_PACKET_SHIFT; +- } +- } +- +- if (offload_type & SKB_GSO_TCPV6) { +- struct atl1c_tpd_ext_desc *etpd = +- *(struct atl1c_tpd_ext_desc **)(tpd); +- +- memset(etpd, 0, sizeof(struct atl1c_tpd_ext_desc)); +- *tpd = atl1c_get_tpd(adapter, type); +- ipv6_hdr(skb)->payload_len = 0; +- /* check payload == 0 byte ? */ +- hdr_len = (skb_transport_offset(skb) + tcp_hdrlen(skb)); +- if (unlikely(skb->len == hdr_len)) { +- /* only xsum need */ +- if (netif_msg_tx_queued(adapter)) +- dev_warn(&pdev->dev, +- "IPV6 tso with zero data??\n"); +- goto check_sum; +- } else +- tcp_hdr(skb)->check = ~csum_ipv6_magic( +- &ipv6_hdr(skb)->saddr, +- &ipv6_hdr(skb)->daddr, +- 0, IPPROTO_TCP, 0); +- etpd->word1 |= 1 << TPD_LSO_EN_SHIFT; +- etpd->word1 |= 1 << TPD_LSO_VER_SHIFT; +- etpd->pkt_len = cpu_to_le32(skb->len); +- (*tpd)->word1 |= 1 << TPD_LSO_VER_SHIFT; +- } +- +- (*tpd)->word1 |= 1 << TPD_LSO_EN_SHIFT; +- (*tpd)->word1 |= (skb_transport_offset(skb) & TPD_TCPHDR_OFFSET_MASK) << +- TPD_TCPHDR_OFFSET_SHIFT; +- (*tpd)->word1 |= (skb_shinfo(skb)->gso_size & TPD_MSS_MASK) << +- TPD_MSS_SHIFT; +- return 0; +- } +- +-check_sum: +- if (likely(skb->ip_summed == CHECKSUM_PARTIAL)) { +- u8 css, cso; +- cso = skb_transport_offset(skb); +- +- if (unlikely(cso & 0x1)) { +- if (netif_msg_tx_err(adapter)) +- dev_err(&adapter->pdev->dev, +- "payload offset should not an event number\n"); +- return -1; +- } else { +- css = cso + skb->csum_offset; +- +- (*tpd)->word1 |= ((cso >> 1) & TPD_PLOADOFFSET_MASK) << +- TPD_PLOADOFFSET_SHIFT; +- (*tpd)->word1 |= ((css >> 1) & TPD_CCSUM_OFFSET_MASK) << +- TPD_CCSUM_OFFSET_SHIFT; +- (*tpd)->word1 |= 1 << TPD_CCSUM_EN_SHIFT; +- } +- } +- return 0; +-} +- +-static void atl1c_tx_map(struct atl1c_adapter *adapter, +- struct sk_buff *skb, struct atl1c_tpd_desc *tpd, +- enum atl1c_trans_queue type) +-{ +- struct atl1c_tpd_desc *use_tpd = NULL; +- struct atl1c_buffer *buffer_info = NULL; +- u16 buf_len = skb_headlen(skb); +- u16 map_len = 0; +- u16 mapped_len = 0; +- u16 hdr_len = 0; +- u16 nr_frags; +- u16 f; +- int tso; +- +- nr_frags = skb_shinfo(skb)->nr_frags; +- tso = (tpd->word1 >> TPD_LSO_EN_SHIFT) & TPD_LSO_EN_MASK; +- if (tso) { +- /* TSO */ +- map_len = hdr_len = skb_transport_offset(skb) + tcp_hdrlen(skb); +- use_tpd = tpd; +- +- buffer_info = atl1c_get_tx_buffer(adapter, use_tpd); +- buffer_info->length = map_len; +- buffer_info->dma = pci_map_single(adapter->pdev, +- skb->data, hdr_len, PCI_DMA_TODEVICE); +- buffer_info->state = ATL1_BUFFER_BUSY; +- mapped_len += map_len; +- use_tpd->buffer_addr = cpu_to_le64(buffer_info->dma); +- use_tpd->buffer_len = cpu_to_le16(buffer_info->length); +- } +- +- if (mapped_len < buf_len) { +- /* mapped_len == 0, means we should use the first tpd, +- which is given by caller */ +- if (mapped_len == 0) +- use_tpd = tpd; +- else { +- use_tpd = atl1c_get_tpd(adapter, type); +- memcpy(use_tpd, tpd, sizeof(struct atl1c_tpd_desc)); +- use_tpd = atl1c_get_tpd(adapter, type); +- memcpy(use_tpd, tpd, sizeof(struct atl1c_tpd_desc)); +- } +- buffer_info = atl1c_get_tx_buffer(adapter, use_tpd); +- buffer_info->length = buf_len - mapped_len; +- buffer_info->dma = +- pci_map_single(adapter->pdev, skb->data + mapped_len, +- buffer_info->length, PCI_DMA_TODEVICE); +- buffer_info->state = ATL1_BUFFER_BUSY; +- +- use_tpd->buffer_addr = cpu_to_le64(buffer_info->dma); +- use_tpd->buffer_len = cpu_to_le16(buffer_info->length); +- } +- +- for (f = 0; f < nr_frags; f++) { +- struct skb_frag_struct *frag; +- +- frag = &skb_shinfo(skb)->frags[f]; +- +- use_tpd = atl1c_get_tpd(adapter, type); +- memcpy(use_tpd, tpd, sizeof(struct atl1c_tpd_desc)); +- +- buffer_info = atl1c_get_tx_buffer(adapter, use_tpd); +- buffer_info->length = frag->size; +- buffer_info->dma = +- pci_map_page(adapter->pdev, frag->page, +- frag->page_offset, +- buffer_info->length, +- PCI_DMA_TODEVICE); +- buffer_info->state = ATL1_BUFFER_BUSY; +- +- use_tpd->buffer_addr = cpu_to_le64(buffer_info->dma); +- use_tpd->buffer_len = cpu_to_le16(buffer_info->length); +- } +- +- /* The last tpd */ +- use_tpd->word1 |= 1 << TPD_EOP_SHIFT; +- /* The last buffer info contain the skb address, +- so it will be free after unmap */ +- buffer_info->skb = skb; +-} +- +-static void atl1c_tx_queue(struct atl1c_adapter *adapter, struct sk_buff *skb, +- struct atl1c_tpd_desc *tpd, enum atl1c_trans_queue type) +-{ +- struct atl1c_tpd_ring *tpd_ring = &adapter->tpd_ring[type]; +- u32 prod_data; +- +- AT_READ_REG(&adapter->hw, REG_MB_PRIO_PROD_IDX, &prod_data); +- switch (type) { +- case atl1c_trans_high: +- prod_data &= 0xFFFF0000; +- prod_data |= tpd_ring->next_to_use & 0xFFFF; +- break; +- case atl1c_trans_normal: +- prod_data &= 0x0000FFFF; +- prod_data |= (tpd_ring->next_to_use & 0xFFFF) << 16; +- break; +- default: +- break; +- } +- wmb(); +- AT_WRITE_REG(&adapter->hw, REG_MB_PRIO_PROD_IDX, prod_data); +-} +- +-static int atl1c_xmit_frame(struct sk_buff *skb, struct net_device *netdev) +-{ +- struct atl1c_adapter *adapter = netdev_priv(netdev); +- unsigned long flags; +- u16 tpd_req = 1; +- struct atl1c_tpd_desc *tpd; +- enum atl1c_trans_queue type = atl1c_trans_normal; +- +- if (test_bit(__AT_DOWN, &adapter->flags)) { +- dev_kfree_skb_any(skb); +- return NETDEV_TX_OK; +- } +- +- tpd_req = atl1c_cal_tpd_req(skb); +- if (!spin_trylock_irqsave(&adapter->tx_lock, flags)) { +- if (netif_msg_pktdata(adapter)) +- dev_info(&adapter->pdev->dev, "tx locked\n"); +- return NETDEV_TX_LOCKED; +- } +- if (skb->mark == 0x01) +- type = atl1c_trans_high; +- else +- type = atl1c_trans_normal; +- +- if (atl1c_tpd_avail(adapter, type) < tpd_req) { +- /* no enough descriptor, just stop queue */ +- netif_stop_queue(netdev); +- spin_unlock_irqrestore(&adapter->tx_lock, flags); +- return NETDEV_TX_BUSY; +- } +- +- tpd = atl1c_get_tpd(adapter, type); +- +- /* do TSO and check sum */ +- if (atl1c_tso_csum(adapter, skb, &tpd, type) != 0) { +- spin_unlock_irqrestore(&adapter->tx_lock, flags); +- dev_kfree_skb_any(skb); +- return NETDEV_TX_OK; +- } +- +- if (unlikely(adapter->vlgrp && vlan_tx_tag_present(skb))) { +- u16 vlan = vlan_tx_tag_get(skb); +- __le16 tag; +- +- vlan = cpu_to_le16(vlan); +- AT_VLAN_TO_TAG(vlan, tag); +- tpd->word1 |= 1 << TPD_INS_VTAG_SHIFT; +- tpd->vlan_tag = tag; +- } +- +- if (skb_network_offset(skb) != ETH_HLEN) +- tpd->word1 |= 1 << TPD_ETH_TYPE_SHIFT; /* Ethernet frame */ +- +- atl1c_tx_map(adapter, skb, tpd, type); +- atl1c_tx_queue(adapter, skb, tpd, type); +- +- netdev->trans_start = jiffies; +- spin_unlock_irqrestore(&adapter->tx_lock, flags); +- return NETDEV_TX_OK; +-} +- +-static void atl1c_free_irq(struct atl1c_adapter *adapter) +-{ +- struct net_device *netdev = adapter->netdev; +- +- free_irq(adapter->pdev->irq, netdev); +- +- if (adapter->have_msi) +- pci_disable_msi(adapter->pdev); +-} +- +-static int atl1c_request_irq(struct atl1c_adapter *adapter) +-{ +- struct pci_dev *pdev = adapter->pdev; +- struct net_device *netdev = adapter->netdev; +- int flags = 0; +- int err = 0; +- +- adapter->have_msi = true; +- err = pci_enable_msi(adapter->pdev); +- if (err) { +- if (netif_msg_ifup(adapter)) +- dev_err(&pdev->dev, +- "Unable to allocate MSI interrupt Error: %d\n", +- err); +- adapter->have_msi = false; +- } else +- netdev->irq = pdev->irq; +- +- if (!adapter->have_msi) +- flags |= IRQF_SHARED; +- err = request_irq(adapter->pdev->irq, &atl1c_intr, flags, +- netdev->name, netdev); +- if (err) { +- if (netif_msg_ifup(adapter)) +- dev_err(&pdev->dev, +- "Unable to allocate interrupt Error: %d\n", +- err); +- if (adapter->have_msi) +- pci_disable_msi(adapter->pdev); +- return err; +- } +- if (netif_msg_ifup(adapter)) +- dev_dbg(&pdev->dev, "atl1c_request_irq OK\n"); +- return err; +-} +- +-int atl1c_up(struct atl1c_adapter *adapter) +-{ +- struct net_device *netdev = adapter->netdev; +- int num; +- int err; +- int i; +- +- netif_carrier_off(netdev); +- atl1c_init_ring_ptrs(adapter); +- atl1c_set_multi(netdev); +- atl1c_restore_vlan(adapter); +- +- for (i = 0; i < adapter->num_rx_queues; i++) { +- num = atl1c_alloc_rx_buffer(adapter, i); +- if (unlikely(num == 0)) { +- err = -ENOMEM; +- goto err_alloc_rx; +- } +- } +- +- if (atl1c_configure(adapter)) { +- err = -EIO; +- goto err_up; +- } +- +- err = atl1c_request_irq(adapter); +- if (unlikely(err)) +- goto err_up; +- +- clear_bit(__AT_DOWN, &adapter->flags); +- napi_enable(&adapter->napi); +- atl1c_irq_enable(adapter); +- atl1c_check_link_status(adapter); +- netif_start_queue(netdev); +- return err; +- +-err_up: +-err_alloc_rx: +- atl1c_clean_rx_ring(adapter); +- return err; +-} +- +-void atl1c_down(struct atl1c_adapter *adapter) +-{ +- struct net_device *netdev = adapter->netdev; +- +- atl1c_del_timer(adapter); +- atl1c_cancel_work(adapter); +- +- /* signal that we're down so the interrupt handler does not +- * reschedule our watchdog timer */ +- set_bit(__AT_DOWN, &adapter->flags); +- netif_carrier_off(netdev); +- napi_disable(&adapter->napi); +- atl1c_irq_disable(adapter); +- atl1c_free_irq(adapter); +- AT_WRITE_REG(&adapter->hw, REG_ISR, ISR_DIS_INT); +- /* reset MAC to disable all RX/TX */ +- atl1c_reset_mac(&adapter->hw); +- msleep(1); +- +- adapter->link_speed = SPEED_0; +- adapter->link_duplex = -1; +- atl1c_clean_tx_ring(adapter, atl1c_trans_normal); +- atl1c_clean_tx_ring(adapter, atl1c_trans_high); +- atl1c_clean_rx_ring(adapter); +-} +- +-/* +- * atl1c_open - Called when a network interface is made active +- * @netdev: network interface device structure +- * +- * Returns 0 on success, negative value on failure +- * +- * The open entry point is called when a network interface is made +- * active by the system (IFF_UP). At this point all resources needed +- * for transmit and receive operations are allocated, the interrupt +- * handler is registered with the OS, the watchdog timer is started, +- * and the stack is notified that the interface is ready. +- */ +-static int atl1c_open(struct net_device *netdev) +-{ +- struct atl1c_adapter *adapter = netdev_priv(netdev); +- int err; +- +- /* disallow open during test */ +- if (test_bit(__AT_TESTING, &adapter->flags)) +- return -EBUSY; +- +- /* allocate rx/tx dma buffer & descriptors */ +- err = atl1c_setup_ring_resources(adapter); +- if (unlikely(err)) +- return err; +- +- err = atl1c_up(adapter); +- if (unlikely(err)) +- goto err_up; +- +- if (adapter->hw.ctrl_flags & ATL1C_FPGA_VERSION) { +- u32 phy_data; +- +- AT_READ_REG(&adapter->hw, REG_MDIO_CTRL, &phy_data); +- phy_data |= MDIO_AP_EN; +- AT_WRITE_REG(&adapter->hw, REG_MDIO_CTRL, phy_data); +- } +- return 0; +- +-err_up: +- atl1c_free_irq(adapter); +- atl1c_free_ring_resources(adapter); +- atl1c_reset_mac(&adapter->hw); +- return err; +-} +- +-/* +- * atl1c_close - Disables a network interface +- * @netdev: network interface device structure +- * +- * Returns 0, this is not allowed to fail +- * +- * The close entry point is called when an interface is de-activated +- * by the OS. The hardware is still under the drivers control, but +- * needs to be disabled. A global MAC reset is issued to stop the +- * hardware, and all transmit and receive resources are freed. +- */ +-static int atl1c_close(struct net_device *netdev) +-{ +- struct atl1c_adapter *adapter = netdev_priv(netdev); +- +- WARN_ON(test_bit(__AT_RESETTING, &adapter->flags)); +- atl1c_down(adapter); +- atl1c_free_ring_resources(adapter); +- return 0; +-} +- +-static int atl1c_suspend(struct pci_dev *pdev, pm_message_t state) +-{ +- struct net_device *netdev = pci_get_drvdata(pdev); +- struct atl1c_adapter *adapter = netdev_priv(netdev); +- struct atl1c_hw *hw = &adapter->hw; +- u32 ctrl; +- u32 mac_ctrl_data; +- u32 master_ctrl_data; +- u32 wol_ctrl_data; +- u16 mii_bmsr_data; +- u16 save_autoneg_advertised; +- u16 mii_intr_status_data; +- u32 wufc = adapter->wol; +- u32 i; +- int retval = 0; +- +- if (netif_running(netdev)) { +- WARN_ON(test_bit(__AT_RESETTING, &adapter->flags)); +- atl1c_down(adapter); +- } +- netif_device_detach(netdev); +- atl1c_disable_l0s_l1(hw); +- retval = pci_save_state(pdev); +- if (retval) +- return retval; +- if (wufc) { +- AT_READ_REG(hw, REG_MASTER_CTRL, &master_ctrl_data); +- master_ctrl_data &= ~MASTER_CTRL_CLK_SEL_DIS; +- +- /* get link status */ +- atl1c_read_phy_reg(hw, MII_BMSR, (u16 *)&mii_bmsr_data); +- atl1c_read_phy_reg(hw, MII_BMSR, (u16 *)&mii_bmsr_data); +- save_autoneg_advertised = hw->autoneg_advertised; +- hw->autoneg_advertised = ADVERTISED_10baseT_Half; +- if (atl1c_restart_autoneg(hw) != 0) +- if (netif_msg_link(adapter)) +- dev_warn(&pdev->dev, "phy autoneg failed\n"); +- hw->phy_configured = false; /* re-init PHY when resume */ +- hw->autoneg_advertised = save_autoneg_advertised; +- /* turn on magic packet wol */ +- if (wufc & AT_WUFC_MAG) +- wol_ctrl_data = WOL_MAGIC_EN | WOL_MAGIC_PME_EN; +- +- if (wufc & AT_WUFC_LNKC) { +- for (i = 0; i < AT_SUSPEND_LINK_TIMEOUT; i++) { +- msleep(100); +- atl1c_read_phy_reg(hw, MII_BMSR, +- (u16 *)&mii_bmsr_data); +- if (mii_bmsr_data & BMSR_LSTATUS) +- break; +- } +- if ((mii_bmsr_data & BMSR_LSTATUS) == 0) +- if (netif_msg_link(adapter)) +- dev_warn(&pdev->dev, +- "%s: Link may change" +- "when suspend\n", +- atl1c_driver_name); +- wol_ctrl_data |= WOL_LINK_CHG_EN | WOL_LINK_CHG_PME_EN; +- /* only link up can wake up */ +- if (atl1c_write_phy_reg(hw, MII_IER, IER_LINK_UP) != 0) { +- if (netif_msg_link(adapter)) +- dev_err(&pdev->dev, +- "%s: read write phy " +- "register failed.\n", +- atl1c_driver_name); +- goto wol_dis; +- } +- } +- /* clear phy interrupt */ +- atl1c_read_phy_reg(hw, MII_ISR, &mii_intr_status_data); +- /* Config MAC Ctrl register */ +- mac_ctrl_data = MAC_CTRL_RX_EN; +- /* set to 10/100M halt duplex */ +- mac_ctrl_data |= atl1c_mac_speed_10_100 << MAC_CTRL_SPEED_SHIFT; +- mac_ctrl_data |= (((u32)adapter->hw.preamble_len & +- MAC_CTRL_PRMLEN_MASK) << +- MAC_CTRL_PRMLEN_SHIFT); +- +- if (adapter->vlgrp) +- mac_ctrl_data |= MAC_CTRL_RMV_VLAN; +- +- /* magic packet maybe Broadcast&multicast&Unicast frame */ +- if (wufc & AT_WUFC_MAG) +- mac_ctrl_data |= MAC_CTRL_BC_EN; +- +- if (netif_msg_hw(adapter)) +- dev_dbg(&pdev->dev, +- "%s: suspend MAC=0x%x\n", +- atl1c_driver_name, mac_ctrl_data); +- AT_WRITE_REG(hw, REG_MASTER_CTRL, master_ctrl_data); +- AT_WRITE_REG(hw, REG_WOL_CTRL, wol_ctrl_data); +- AT_WRITE_REG(hw, REG_MAC_CTRL, mac_ctrl_data); +- +- /* pcie patch */ +- AT_READ_REG(hw, REG_PCIE_PHYMISC, &ctrl); +- ctrl |= PCIE_PHYMISC_FORCE_RCV_DET; +- AT_WRITE_REG(hw, REG_PCIE_PHYMISC, ctrl); +- +- pci_enable_wake(pdev, pci_choose_state(pdev, state), 1); +- goto suspend_exit; +- } +-wol_dis: +- +- /* WOL disabled */ +- AT_WRITE_REG(hw, REG_WOL_CTRL, 0); +- +- /* pcie patch */ +- AT_READ_REG(hw, REG_PCIE_PHYMISC, &ctrl); +- ctrl |= PCIE_PHYMISC_FORCE_RCV_DET; +- AT_WRITE_REG(hw, REG_PCIE_PHYMISC, ctrl); +- +- atl1c_phy_disable(hw); +- hw->phy_configured = false; /* re-init PHY when resume */ +- +- pci_enable_wake(pdev, pci_choose_state(pdev, state), 0); +-suspend_exit: +- +- pci_disable_device(pdev); +- pci_set_power_state(pdev, pci_choose_state(pdev, state)); +- +- return 0; +-} +- +-static int atl1c_resume(struct pci_dev *pdev) +-{ +- struct net_device *netdev = pci_get_drvdata(pdev); +- struct atl1c_adapter *adapter = netdev_priv(netdev); +- +- pci_set_power_state(pdev, PCI_D0); +- pci_restore_state(pdev); +- pci_enable_wake(pdev, PCI_D3hot, 0); +- pci_enable_wake(pdev, PCI_D3cold, 0); +- +- AT_WRITE_REG(&adapter->hw, REG_WOL_CTRL, 0); +- +- atl1c_phy_reset(&adapter->hw); +- atl1c_reset_mac(&adapter->hw); +- netif_device_attach(netdev); +- if (netif_running(netdev)) +- atl1c_up(adapter); +- +- return 0; +-} +- +-static void atl1c_shutdown(struct pci_dev *pdev) +-{ +- atl1c_suspend(pdev, PMSG_SUSPEND); +-} +- +-static const struct net_device_ops atl1c_netdev_ops = { +- .ndo_open = atl1c_open, +- .ndo_stop = atl1c_close, +- .ndo_validate_addr = eth_validate_addr, +- .ndo_start_xmit = atl1c_xmit_frame, +- .ndo_set_mac_address = atl1c_set_mac_addr, +- .ndo_set_multicast_list = atl1c_set_multi, +- .ndo_change_mtu = atl1c_change_mtu, +- .ndo_do_ioctl = atl1c_ioctl, +- .ndo_tx_timeout = atl1c_tx_timeout, +- .ndo_get_stats = atl1c_get_stats, +- .ndo_vlan_rx_register = atl1c_vlan_rx_register, +-#ifdef CONFIG_NET_POLL_CONTROLLER +- .ndo_poll_controller = atl1c_netpoll, +-#endif +-}; +- +-static int atl1c_init_netdev(struct net_device *netdev, struct pci_dev *pdev) +-{ +- SET_NETDEV_DEV(netdev, &pdev->dev); +- pci_set_drvdata(pdev, netdev); +- +- netdev->irq = pdev->irq; +- netdev->netdev_ops = &atl1c_netdev_ops; +- netdev->watchdog_timeo = AT_TX_WATCHDOG; +- atl1c_set_ethtool_ops(netdev); +- +- /* TODO: add when ready */ +- netdev->features = NETIF_F_SG | +- NETIF_F_HW_CSUM | +- NETIF_F_HW_VLAN_TX | +- NETIF_F_HW_VLAN_RX | +- NETIF_F_TSO | +- NETIF_F_TSO6; +- return 0; +-} +- +-/* +- * atl1c_probe - Device Initialization Routine +- * @pdev: PCI device information struct +- * @ent: entry in atl1c_pci_tbl +- * +- * Returns 0 on success, negative on failure +- * +- * atl1c_probe initializes an adapter identified by a pci_dev structure. +- * The OS initialization, configuring of the adapter private structure, +- * and a hardware reset occur. +- */ +-static int __devinit atl1c_probe(struct pci_dev *pdev, +- const struct pci_device_id *ent) +-{ +- struct net_device *netdev; +- struct atl1c_adapter *adapter; +- static int cards_found; +- +- int err = 0; +- +- /* enable device (incl. PCI PM wakeup and hotplug setup) */ +- err = pci_enable_device_mem(pdev); +- if (err) { +- dev_err(&pdev->dev, "cannot enable PCI device\n"); +- return err; +- } +- +- /* +- * The atl1c chip can DMA to 64-bit addresses, but it uses a single +- * shared register for the high 32 bits, so only a single, aligned, +- * 4 GB physical address range can be used at a time. +- * +- * Supporting 64-bit DMA on this hardware is more trouble than it's +- * worth. It is far easier to limit to 32-bit DMA than update +- * various kernel subsystems to support the mechanics required by a +- * fixed-high-32-bit system. +- */ +- if ((pci_set_dma_mask(pdev, DMA_32BIT_MASK) != 0) || +- (pci_set_consistent_dma_mask(pdev, DMA_32BIT_MASK) != 0)) { +- dev_err(&pdev->dev, "No usable DMA configuration,aborting\n"); +- goto err_dma; +- } +- +- err = pci_request_regions(pdev, atl1c_driver_name); +- if (err) { +- dev_err(&pdev->dev, "cannot obtain PCI resources\n"); +- goto err_pci_reg; +- } +- +- pci_set_master(pdev); +- +- netdev = alloc_etherdev(sizeof(struct atl1c_adapter)); +- if (netdev == NULL) { +- err = -ENOMEM; +- dev_err(&pdev->dev, "etherdev alloc failed\n"); +- goto err_alloc_etherdev; +- } +- +- err = atl1c_init_netdev(netdev, pdev); +- if (err) { +- dev_err(&pdev->dev, "init netdevice failed\n"); +- goto err_init_netdev; +- } +- adapter = netdev_priv(netdev); +- adapter->bd_number = cards_found; +- adapter->netdev = netdev; +- adapter->pdev = pdev; +- adapter->hw.adapter = adapter; +- adapter->msg_enable = netif_msg_init(-1, atl1c_default_msg); +- adapter->hw.hw_addr = ioremap(pci_resource_start(pdev, 0), pci_resource_len(pdev, 0)); +- if (!adapter->hw.hw_addr) { +- err = -EIO; +- dev_err(&pdev->dev, "cannot map device registers\n"); +- goto err_ioremap; +- } +- netdev->base_addr = (unsigned long)adapter->hw.hw_addr; +- +- /* init mii data */ +- adapter->mii.dev = netdev; +- adapter->mii.mdio_read = atl1c_mdio_read; +- adapter->mii.mdio_write = atl1c_mdio_write; +- adapter->mii.phy_id_mask = 0x1f; +- adapter->mii.reg_num_mask = MDIO_REG_ADDR_MASK; +- netif_napi_add(netdev, &adapter->napi, atl1c_clean, 64); +- setup_timer(&adapter->phy_config_timer, atl1c_phy_config, +- (unsigned long)adapter); +- /* setup the private structure */ +- err = atl1c_sw_init(adapter); +- if (err) { +- dev_err(&pdev->dev, "net device private data init failed\n"); +- goto err_sw_init; +- } +- atl1c_reset_pcie(&adapter->hw, ATL1C_PCIE_L0S_L1_DISABLE | +- ATL1C_PCIE_PHY_RESET); +- +- /* Init GPHY as early as possible due to power saving issue */ +- atl1c_phy_reset(&adapter->hw); +- +- err = atl1c_reset_mac(&adapter->hw); +- if (err) { +- err = -EIO; +- goto err_reset; +- } +- +- device_init_wakeup(&pdev->dev, 1); +- /* reset the controller to +- * put the device in a known good starting state */ +- err = atl1c_phy_init(&adapter->hw); +- if (err) { +- err = -EIO; +- goto err_reset; +- } +- if (atl1c_read_mac_addr(&adapter->hw) != 0) { +- err = -EIO; +- dev_err(&pdev->dev, "get mac address failed\n"); +- goto err_eeprom; +- } +- memcpy(netdev->dev_addr, adapter->hw.mac_addr, netdev->addr_len); +- memcpy(netdev->perm_addr, adapter->hw.mac_addr, netdev->addr_len); +- if (netif_msg_probe(adapter)) +- dev_dbg(&pdev->dev, +- "mac address : %02x-%02x-%02x-%02x-%02x-%02x\n", +- adapter->hw.mac_addr[0], adapter->hw.mac_addr[1], +- adapter->hw.mac_addr[2], adapter->hw.mac_addr[3], +- adapter->hw.mac_addr[4], adapter->hw.mac_addr[5]); +- +- atl1c_hw_set_mac_addr(&adapter->hw); +- INIT_WORK(&adapter->reset_task, atl1c_reset_task); +- INIT_WORK(&adapter->link_chg_task, atl1c_link_chg_task); +- err = register_netdev(netdev); +- if (err) { +- dev_err(&pdev->dev, "register netdevice failed\n"); +- goto err_register; +- } +- +- if (netif_msg_probe(adapter)) +- dev_info(&pdev->dev, "version %s\n", ATL1C_DRV_VERSION); +- cards_found++; +- return 0; +- +-err_reset: +-err_register: +-err_sw_init: +-err_eeprom: +- iounmap(adapter->hw.hw_addr); +-err_init_netdev: +-err_ioremap: +- free_netdev(netdev); +-err_alloc_etherdev: +- pci_release_regions(pdev); +-err_pci_reg: +-err_dma: +- pci_disable_device(pdev); +- return err; +-} +- +-/* +- * atl1c_remove - Device Removal Routine +- * @pdev: PCI device information struct +- * +- * atl1c_remove is called by the PCI subsystem to alert the driver +- * that it should release a PCI device. The could be caused by a +- * Hot-Plug event, or because the driver is going to be removed from +- * memory. +- */ +-static void __devexit atl1c_remove(struct pci_dev *pdev) +-{ +- struct net_device *netdev = pci_get_drvdata(pdev); +- struct atl1c_adapter *adapter = netdev_priv(netdev); +- +- unregister_netdev(netdev); +- atl1c_phy_disable(&adapter->hw); +- +- iounmap(adapter->hw.hw_addr); +- +- pci_release_regions(pdev); +- pci_disable_device(pdev); +- free_netdev(netdev); +-} +- +-/* +- * atl1c_io_error_detected - called when PCI error is detected +- * @pdev: Pointer to PCI device +- * @state: The current pci connection state +- * +- * This function is called after a PCI bus error affecting +- * this device has been detected. +- */ +-static pci_ers_result_t atl1c_io_error_detected(struct pci_dev *pdev, +- pci_channel_state_t state) +-{ +- struct net_device *netdev = pci_get_drvdata(pdev); +- struct atl1c_adapter *adapter = netdev_priv(netdev); +- +- netif_device_detach(netdev); +- +- if (netif_running(netdev)) +- atl1c_down(adapter); +- +- pci_disable_device(pdev); +- +- /* Request a slot slot reset. */ +- return PCI_ERS_RESULT_NEED_RESET; +-} +- +-/* +- * atl1c_io_slot_reset - called after the pci bus has been reset. +- * @pdev: Pointer to PCI device +- * +- * Restart the card from scratch, as if from a cold-boot. Implementation +- * resembles the first-half of the e1000_resume routine. +- */ +-static pci_ers_result_t atl1c_io_slot_reset(struct pci_dev *pdev) +-{ +- struct net_device *netdev = pci_get_drvdata(pdev); +- struct atl1c_adapter *adapter = netdev_priv(netdev); +- +- if (pci_enable_device(pdev)) { +- if (netif_msg_hw(adapter)) +- dev_err(&pdev->dev, +- "Cannot re-enable PCI device after reset\n"); +- return PCI_ERS_RESULT_DISCONNECT; +- } +- pci_set_master(pdev); +- +- pci_enable_wake(pdev, PCI_D3hot, 0); +- pci_enable_wake(pdev, PCI_D3cold, 0); +- +- atl1c_reset_mac(&adapter->hw); +- +- return PCI_ERS_RESULT_RECOVERED; +-} +- +-/* +- * atl1c_io_resume - called when traffic can start flowing again. +- * @pdev: Pointer to PCI device +- * +- * This callback is called when the error recovery driver tells us that +- * its OK to resume normal operation. Implementation resembles the +- * second-half of the atl1c_resume routine. +- */ +-static void atl1c_io_resume(struct pci_dev *pdev) +-{ +- struct net_device *netdev = pci_get_drvdata(pdev); +- struct atl1c_adapter *adapter = netdev_priv(netdev); +- +- if (netif_running(netdev)) { +- if (atl1c_up(adapter)) { +- if (netif_msg_hw(adapter)) +- dev_err(&pdev->dev, +- "Cannot bring device back up after reset\n"); +- return; +- } +- } +- +- netif_device_attach(netdev); +-} +- +-static struct pci_error_handlers atl1c_err_handler = { +- .error_detected = atl1c_io_error_detected, +- .slot_reset = atl1c_io_slot_reset, +- .resume = atl1c_io_resume, +-}; +- +-static struct pci_driver atl1c_driver = { +- .name = atl1c_driver_name, +- .id_table = atl1c_pci_tbl, +- .probe = atl1c_probe, +- .remove = __devexit_p(atl1c_remove), +- /* Power Managment Hooks */ +- .suspend = atl1c_suspend, +- .resume = atl1c_resume, +- .shutdown = atl1c_shutdown, +- .err_handler = &atl1c_err_handler +-}; +- +-/* +- * atl1c_init_module - Driver Registration Routine +- * +- * atl1c_init_module is the first routine called when the driver is +- * loaded. All it does is register with the PCI subsystem. +- */ +-static int __init atl1c_init_module(void) +-{ +- return pci_register_driver(&atl1c_driver); +-} +- +-/* +- * atl1c_exit_module - Driver Exit Cleanup Routine +- * +- * atl1c_exit_module is called just before the driver is removed +- * from memory. +- */ +-static void __exit atl1c_exit_module(void) +-{ +- pci_unregister_driver(&atl1c_driver); +-} +- +-module_init(atl1c_init_module); +-module_exit(atl1c_exit_module); +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/drivers/net/atl1c/Makefile linux-2.6.29-rc3.owrt/drivers/net/atl1c/Makefile +--- linux-2.6.29.owrt/drivers/net/atl1c/Makefile 2009-05-10 22:04:38.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/drivers/net/atl1c/Makefile 1970-01-01 01:00:00.000000000 +0100 +@@ -1,2 +0,0 @@ +-obj-$(CONFIG_ATL1C) += atl1c.o +-atl1c-objs := atl1c_main.o atl1c_hw.o atl1c_ethtool.o +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/drivers/net/b44.c linux-2.6.29-rc3.owrt/drivers/net/b44.c +--- linux-2.6.29.owrt/drivers/net/b44.c 2009-05-10 22:04:38.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/drivers/net/b44.c 2009-05-10 23:48:28.000000000 +0200 +@@ -1264,14 +1264,8 @@ + static void b44_chip_reset(struct b44 *bp, int reset_kind) + { + struct ssb_device *sdev = bp->sdev; +- bool was_enabled; + +- was_enabled = ssb_device_is_enabled(bp->sdev); +- +- ssb_device_enable(bp->sdev, 0); +- ssb_pcicore_dev_irqvecs_enable(&sdev->bus->pcicore, sdev); +- +- if (was_enabled) { ++ if (ssb_device_is_enabled(bp->sdev)) { + bw32(bp, B44_RCV_LAZY, 0); + bw32(bp, B44_ENET_CTRL, ENET_CTRL_DISABLE); + b44_wait_bit(bp, B44_ENET_CTRL, ENET_CTRL_DISABLE, 200, 1); +@@ -1283,8 +1277,10 @@ + } + bw32(bp, B44_DMARX_CTRL, 0); + bp->rx_prod = bp->rx_cons = 0; +- } ++ } else ++ ssb_pcicore_dev_irqvecs_enable(&sdev->bus->pcicore, sdev); + ++ ssb_device_enable(bp->sdev, 0); + b44_clear_stats(bp); + + /* +@@ -2240,7 +2236,6 @@ + struct net_device *dev = ssb_get_drvdata(sdev); + + unregister_netdev(dev); +- ssb_device_disable(sdev, 0); + ssb_bus_may_powerdown(sdev->bus); + free_netdev(dev); + ssb_pcihost_set_power_state(sdev, PCI_D3hot); +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/drivers/net/benet/be_cmds.c linux-2.6.29-rc3.owrt/drivers/net/benet/be_cmds.c +--- linux-2.6.29.owrt/drivers/net/benet/be_cmds.c 2009-05-10 22:04:38.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/drivers/net/benet/be_cmds.c 1970-01-01 01:00:00.000000000 +0100 +@@ -1,861 +0,0 @@ +-/* +- * Copyright (C) 2005 - 2009 ServerEngines +- * All rights reserved. +- * +- * 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. The full GNU General +- * Public License is included in this distribution in the file called COPYING. +- * +- * Contact Information: +- * linux-drivers@serverengines.com +- * +- * ServerEngines +- * 209 N. Fair Oaks Ave +- * Sunnyvale, CA 94085 +- */ +- +-#include "be.h" +- +-static int be_mbox_db_ready_wait(void __iomem *db) +-{ +- int cnt = 0, wait = 5; +- u32 ready; +- +- do { +- ready = ioread32(db) & MPU_MAILBOX_DB_RDY_MASK; +- if (ready) +- break; +- +- if (cnt > 200000) { +- printk(KERN_WARNING DRV_NAME +- ": mbox_db poll timed out\n"); +- return -1; +- } +- +- if (cnt > 50) +- wait = 200; +- cnt += wait; +- udelay(wait); +- } while (true); +- +- return 0; +-} +- +-/* +- * Insert the mailbox address into the doorbell in two steps +- */ +-static int be_mbox_db_ring(struct be_ctrl_info *ctrl) +-{ +- int status; +- u16 compl_status, extd_status; +- u32 val = 0; +- void __iomem *db = ctrl->db + MPU_MAILBOX_DB_OFFSET; +- struct be_dma_mem *mbox_mem = &ctrl->mbox_mem; +- struct be_mcc_mailbox *mbox = mbox_mem->va; +- struct be_mcc_cq_entry *cqe = &mbox->cqe; +- +- memset(cqe, 0, sizeof(*cqe)); +- +- val &= ~MPU_MAILBOX_DB_RDY_MASK; +- val |= MPU_MAILBOX_DB_HI_MASK; +- /* at bits 2 - 31 place mbox dma addr msb bits 34 - 63 */ +- val |= (upper_32_bits(mbox_mem->dma) >> 2) << 2; +- iowrite32(val, db); +- +- /* wait for ready to be set */ +- status = be_mbox_db_ready_wait(db); +- if (status != 0) +- return status; +- +- val = 0; +- val &= ~MPU_MAILBOX_DB_RDY_MASK; +- val &= ~MPU_MAILBOX_DB_HI_MASK; +- /* at bits 2 - 31 place mbox dma addr lsb bits 4 - 33 */ +- val |= (u32)(mbox_mem->dma >> 4) << 2; +- iowrite32(val, db); +- +- status = be_mbox_db_ready_wait(db); +- if (status != 0) +- return status; +- +- /* compl entry has been made now */ +- be_dws_le_to_cpu(cqe, sizeof(*cqe)); +- if (!(cqe->flags & CQE_FLAGS_VALID_MASK)) { +- printk(KERN_WARNING DRV_NAME ": ERROR invalid mbox compl\n"); +- return -1; +- } +- +- compl_status = (cqe->status >> CQE_STATUS_COMPL_SHIFT) & +- CQE_STATUS_COMPL_MASK; +- if (compl_status != MCC_STATUS_SUCCESS) { +- extd_status = (cqe->status >> CQE_STATUS_EXTD_SHIFT) & +- CQE_STATUS_EXTD_MASK; +- printk(KERN_WARNING DRV_NAME +- ": ERROR in cmd compl. status(compl/extd)=%d/%d\n", +- compl_status, extd_status); +- } +- +- return compl_status; +-} +- +-static int be_POST_stage_get(struct be_ctrl_info *ctrl, u16 *stage) +-{ +- u32 sem = ioread32(ctrl->csr + MPU_EP_SEMAPHORE_OFFSET); +- +- *stage = sem & EP_SEMAPHORE_POST_STAGE_MASK; +- if ((sem >> EP_SEMAPHORE_POST_ERR_SHIFT) & EP_SEMAPHORE_POST_ERR_MASK) +- return -1; +- else +- return 0; +-} +- +-static int be_POST_stage_poll(struct be_ctrl_info *ctrl, u16 poll_stage) +-{ +- u16 stage, cnt, error; +- for (cnt = 0; cnt < 5000; cnt++) { +- error = be_POST_stage_get(ctrl, &stage); +- if (error) +- return -1; +- +- if (stage == poll_stage) +- break; +- udelay(1000); +- } +- if (stage != poll_stage) +- return -1; +- return 0; +-} +- +- +-int be_cmd_POST(struct be_ctrl_info *ctrl) +-{ +- u16 stage, error; +- +- error = be_POST_stage_get(ctrl, &stage); +- if (error) +- goto err; +- +- if (stage == POST_STAGE_ARMFW_RDY) +- return 0; +- +- if (stage != POST_STAGE_AWAITING_HOST_RDY) +- goto err; +- +- /* On awaiting host rdy, reset and again poll on awaiting host rdy */ +- iowrite32(POST_STAGE_BE_RESET, ctrl->csr + MPU_EP_SEMAPHORE_OFFSET); +- error = be_POST_stage_poll(ctrl, POST_STAGE_AWAITING_HOST_RDY); +- if (error) +- goto err; +- +- /* Now kickoff POST and poll on armfw ready */ +- iowrite32(POST_STAGE_HOST_RDY, ctrl->csr + MPU_EP_SEMAPHORE_OFFSET); +- error = be_POST_stage_poll(ctrl, POST_STAGE_ARMFW_RDY); +- if (error) +- goto err; +- +- return 0; +-err: +- printk(KERN_WARNING DRV_NAME ": ERROR, stage=%d\n", stage); +- return -1; +-} +- +-static inline void *embedded_payload(struct be_mcc_wrb *wrb) +-{ +- return wrb->payload.embedded_payload; +-} +- +-static inline struct be_sge *nonembedded_sgl(struct be_mcc_wrb *wrb) +-{ +- return &wrb->payload.sgl[0]; +-} +- +-/* Don't touch the hdr after it's prepared */ +-static void be_wrb_hdr_prepare(struct be_mcc_wrb *wrb, int payload_len, +- bool embedded, u8 sge_cnt) +-{ +- if (embedded) +- wrb->embedded |= MCC_WRB_EMBEDDED_MASK; +- else +- wrb->embedded |= (sge_cnt & MCC_WRB_SGE_CNT_MASK) << +- MCC_WRB_SGE_CNT_SHIFT; +- wrb->payload_length = payload_len; +- be_dws_cpu_to_le(wrb, 20); +-} +- +-/* Don't touch the hdr after it's prepared */ +-static void be_cmd_hdr_prepare(struct be_cmd_req_hdr *req_hdr, +- u8 subsystem, u8 opcode, int cmd_len) +-{ +- req_hdr->opcode = opcode; +- req_hdr->subsystem = subsystem; +- req_hdr->request_length = cpu_to_le32(cmd_len - sizeof(*req_hdr)); +-} +- +-static void be_cmd_page_addrs_prepare(struct phys_addr *pages, u32 max_pages, +- struct be_dma_mem *mem) +-{ +- int i, buf_pages = min(PAGES_4K_SPANNED(mem->va, mem->size), max_pages); +- u64 dma = (u64)mem->dma; +- +- for (i = 0; i < buf_pages; i++) { +- pages[i].lo = cpu_to_le32(dma & 0xFFFFFFFF); +- pages[i].hi = cpu_to_le32(upper_32_bits(dma)); +- dma += PAGE_SIZE_4K; +- } +-} +- +-/* Converts interrupt delay in microseconds to multiplier value */ +-static u32 eq_delay_to_mult(u32 usec_delay) +-{ +-#define MAX_INTR_RATE 651042 +- const u32 round = 10; +- u32 multiplier; +- +- if (usec_delay == 0) +- multiplier = 0; +- else { +- u32 interrupt_rate = 1000000 / usec_delay; +- /* Max delay, corresponding to the lowest interrupt rate */ +- if (interrupt_rate == 0) +- multiplier = 1023; +- else { +- multiplier = (MAX_INTR_RATE - interrupt_rate) * round; +- multiplier /= interrupt_rate; +- /* Round the multiplier to the closest value.*/ +- multiplier = (multiplier + round/2) / round; +- multiplier = min(multiplier, (u32)1023); +- } +- } +- return multiplier; +-} +- +-static inline struct be_mcc_wrb *wrb_from_mbox(struct be_dma_mem *mbox_mem) +-{ +- return &((struct be_mcc_mailbox *)(mbox_mem->va))->wrb; +-} +- +-int be_cmd_eq_create(struct be_ctrl_info *ctrl, +- struct be_queue_info *eq, int eq_delay) +-{ +- struct be_mcc_wrb *wrb = wrb_from_mbox(&ctrl->mbox_mem); +- struct be_cmd_req_eq_create *req = embedded_payload(wrb); +- struct be_cmd_resp_eq_create *resp = embedded_payload(wrb); +- struct be_dma_mem *q_mem = &eq->dma_mem; +- int status; +- +- spin_lock(&ctrl->cmd_lock); +- memset(wrb, 0, sizeof(*wrb)); +- +- be_wrb_hdr_prepare(wrb, sizeof(*req), true, 0); +- +- be_cmd_hdr_prepare(&req->hdr, CMD_SUBSYSTEM_COMMON, +- OPCODE_COMMON_EQ_CREATE, sizeof(*req)); +- +- req->num_pages = cpu_to_le16(PAGES_4K_SPANNED(q_mem->va, q_mem->size)); +- +- AMAP_SET_BITS(struct amap_eq_context, func, req->context, +- ctrl->pci_func); +- AMAP_SET_BITS(struct amap_eq_context, valid, req->context, 1); +- /* 4byte eqe*/ +- AMAP_SET_BITS(struct amap_eq_context, size, req->context, 0); +- AMAP_SET_BITS(struct amap_eq_context, count, req->context, +- __ilog2_u32(eq->len/256)); +- AMAP_SET_BITS(struct amap_eq_context, delaymult, req->context, +- eq_delay_to_mult(eq_delay)); +- be_dws_cpu_to_le(req->context, sizeof(req->context)); +- +- be_cmd_page_addrs_prepare(req->pages, ARRAY_SIZE(req->pages), q_mem); +- +- status = be_mbox_db_ring(ctrl); +- if (!status) { +- eq->id = le16_to_cpu(resp->eq_id); +- eq->created = true; +- } +- spin_unlock(&ctrl->cmd_lock); +- return status; +-} +- +-int be_cmd_mac_addr_query(struct be_ctrl_info *ctrl, u8 *mac_addr, +- u8 type, bool permanent, u32 if_handle) +-{ +- struct be_mcc_wrb *wrb = wrb_from_mbox(&ctrl->mbox_mem); +- struct be_cmd_req_mac_query *req = embedded_payload(wrb); +- struct be_cmd_resp_mac_query *resp = embedded_payload(wrb); +- int status; +- +- spin_lock(&ctrl->cmd_lock); +- memset(wrb, 0, sizeof(*wrb)); +- +- be_wrb_hdr_prepare(wrb, sizeof(*req), true, 0); +- +- be_cmd_hdr_prepare(&req->hdr, CMD_SUBSYSTEM_COMMON, +- OPCODE_COMMON_NTWK_MAC_QUERY, sizeof(*req)); +- +- req->type = type; +- if (permanent) { +- req->permanent = 1; +- } else { +- req->if_id = cpu_to_le16((u16)if_handle); +- req->permanent = 0; +- } +- +- status = be_mbox_db_ring(ctrl); +- if (!status) +- memcpy(mac_addr, resp->mac.addr, ETH_ALEN); +- +- spin_unlock(&ctrl->cmd_lock); +- return status; +-} +- +-int be_cmd_pmac_add(struct be_ctrl_info *ctrl, u8 *mac_addr, +- u32 if_id, u32 *pmac_id) +-{ +- struct be_mcc_wrb *wrb = wrb_from_mbox(&ctrl->mbox_mem); +- struct be_cmd_req_pmac_add *req = embedded_payload(wrb); +- int status; +- +- spin_lock(&ctrl->cmd_lock); +- memset(wrb, 0, sizeof(*wrb)); +- +- be_wrb_hdr_prepare(wrb, sizeof(*req), true, 0); +- +- be_cmd_hdr_prepare(&req->hdr, CMD_SUBSYSTEM_COMMON, +- OPCODE_COMMON_NTWK_PMAC_ADD, sizeof(*req)); +- +- req->if_id = cpu_to_le32(if_id); +- memcpy(req->mac_address, mac_addr, ETH_ALEN); +- +- status = be_mbox_db_ring(ctrl); +- if (!status) { +- struct be_cmd_resp_pmac_add *resp = embedded_payload(wrb); +- *pmac_id = le32_to_cpu(resp->pmac_id); +- } +- +- spin_unlock(&ctrl->cmd_lock); +- return status; +-} +- +-int be_cmd_pmac_del(struct be_ctrl_info *ctrl, u32 if_id, u32 pmac_id) +-{ +- struct be_mcc_wrb *wrb = wrb_from_mbox(&ctrl->mbox_mem); +- struct be_cmd_req_pmac_del *req = embedded_payload(wrb); +- int status; +- +- spin_lock(&ctrl->cmd_lock); +- memset(wrb, 0, sizeof(*wrb)); +- +- be_wrb_hdr_prepare(wrb, sizeof(*req), true, 0); +- +- be_cmd_hdr_prepare(&req->hdr, CMD_SUBSYSTEM_COMMON, +- OPCODE_COMMON_NTWK_PMAC_DEL, sizeof(*req)); +- +- req->if_id = cpu_to_le32(if_id); +- req->pmac_id = cpu_to_le32(pmac_id); +- +- status = be_mbox_db_ring(ctrl); +- spin_unlock(&ctrl->cmd_lock); +- +- return status; +-} +- +-int be_cmd_cq_create(struct be_ctrl_info *ctrl, +- struct be_queue_info *cq, struct be_queue_info *eq, +- bool sol_evts, bool no_delay, int coalesce_wm) +-{ +- struct be_mcc_wrb *wrb = wrb_from_mbox(&ctrl->mbox_mem); +- struct be_cmd_req_cq_create *req = embedded_payload(wrb); +- struct be_cmd_resp_cq_create *resp = embedded_payload(wrb); +- struct be_dma_mem *q_mem = &cq->dma_mem; +- void *ctxt = &req->context; +- int status; +- +- spin_lock(&ctrl->cmd_lock); +- memset(wrb, 0, sizeof(*wrb)); +- +- be_wrb_hdr_prepare(wrb, sizeof(*req), true, 0); +- +- be_cmd_hdr_prepare(&req->hdr, CMD_SUBSYSTEM_COMMON, +- OPCODE_COMMON_CQ_CREATE, sizeof(*req)); +- +- req->num_pages = cpu_to_le16(PAGES_4K_SPANNED(q_mem->va, q_mem->size)); +- +- AMAP_SET_BITS(struct amap_cq_context, coalescwm, ctxt, coalesce_wm); +- AMAP_SET_BITS(struct amap_cq_context, nodelay, ctxt, no_delay); +- AMAP_SET_BITS(struct amap_cq_context, count, ctxt, +- __ilog2_u32(cq->len/256)); +- AMAP_SET_BITS(struct amap_cq_context, valid, ctxt, 1); +- AMAP_SET_BITS(struct amap_cq_context, solevent, ctxt, sol_evts); +- AMAP_SET_BITS(struct amap_cq_context, eventable, ctxt, 1); +- AMAP_SET_BITS(struct amap_cq_context, eqid, ctxt, eq->id); +- AMAP_SET_BITS(struct amap_cq_context, armed, ctxt, 0); +- AMAP_SET_BITS(struct amap_cq_context, func, ctxt, ctrl->pci_func); +- be_dws_cpu_to_le(ctxt, sizeof(req->context)); +- +- be_cmd_page_addrs_prepare(req->pages, ARRAY_SIZE(req->pages), q_mem); +- +- status = be_mbox_db_ring(ctrl); +- if (!status) { +- cq->id = le16_to_cpu(resp->cq_id); +- cq->created = true; +- } +- spin_unlock(&ctrl->cmd_lock); +- +- return status; +-} +- +-int be_cmd_txq_create(struct be_ctrl_info *ctrl, +- struct be_queue_info *txq, +- struct be_queue_info *cq) +-{ +- struct be_mcc_wrb *wrb = wrb_from_mbox(&ctrl->mbox_mem); +- struct be_cmd_req_eth_tx_create *req = embedded_payload(wrb); +- struct be_dma_mem *q_mem = &txq->dma_mem; +- void *ctxt = &req->context; +- int status; +- u32 len_encoded; +- +- spin_lock(&ctrl->cmd_lock); +- memset(wrb, 0, sizeof(*wrb)); +- +- be_wrb_hdr_prepare(wrb, sizeof(*req), true, 0); +- +- be_cmd_hdr_prepare(&req->hdr, CMD_SUBSYSTEM_ETH, OPCODE_ETH_TX_CREATE, +- sizeof(*req)); +- +- req->num_pages = PAGES_4K_SPANNED(q_mem->va, q_mem->size); +- req->ulp_num = BE_ULP1_NUM; +- req->type = BE_ETH_TX_RING_TYPE_STANDARD; +- +- len_encoded = fls(txq->len); /* log2(len) + 1 */ +- if (len_encoded == 16) +- len_encoded = 0; +- AMAP_SET_BITS(struct amap_tx_context, tx_ring_size, ctxt, len_encoded); +- AMAP_SET_BITS(struct amap_tx_context, pci_func_id, ctxt, +- ctrl->pci_func); +- AMAP_SET_BITS(struct amap_tx_context, ctx_valid, ctxt, 1); +- AMAP_SET_BITS(struct amap_tx_context, cq_id_send, ctxt, cq->id); +- +- be_dws_cpu_to_le(ctxt, sizeof(req->context)); +- +- be_cmd_page_addrs_prepare(req->pages, ARRAY_SIZE(req->pages), q_mem); +- +- status = be_mbox_db_ring(ctrl); +- if (!status) { +- struct be_cmd_resp_eth_tx_create *resp = embedded_payload(wrb); +- txq->id = le16_to_cpu(resp->cid); +- txq->created = true; +- } +- spin_unlock(&ctrl->cmd_lock); +- +- return status; +-} +- +-int be_cmd_rxq_create(struct be_ctrl_info *ctrl, +- struct be_queue_info *rxq, u16 cq_id, u16 frag_size, +- u16 max_frame_size, u32 if_id, u32 rss) +-{ +- struct be_mcc_wrb *wrb = wrb_from_mbox(&ctrl->mbox_mem); +- struct be_cmd_req_eth_rx_create *req = embedded_payload(wrb); +- struct be_dma_mem *q_mem = &rxq->dma_mem; +- int status; +- +- spin_lock(&ctrl->cmd_lock); +- memset(wrb, 0, sizeof(*wrb)); +- +- be_wrb_hdr_prepare(wrb, sizeof(*req), true, 0); +- +- be_cmd_hdr_prepare(&req->hdr, CMD_SUBSYSTEM_ETH, OPCODE_ETH_RX_CREATE, +- sizeof(*req)); +- +- req->cq_id = cpu_to_le16(cq_id); +- req->frag_size = fls(frag_size) - 1; +- req->num_pages = 2; +- be_cmd_page_addrs_prepare(req->pages, ARRAY_SIZE(req->pages), q_mem); +- req->interface_id = cpu_to_le32(if_id); +- req->max_frame_size = cpu_to_le16(max_frame_size); +- req->rss_queue = cpu_to_le32(rss); +- +- status = be_mbox_db_ring(ctrl); +- if (!status) { +- struct be_cmd_resp_eth_rx_create *resp = embedded_payload(wrb); +- rxq->id = le16_to_cpu(resp->id); +- rxq->created = true; +- } +- spin_unlock(&ctrl->cmd_lock); +- +- return status; +-} +- +-/* Generic destroyer function for all types of queues */ +-int be_cmd_q_destroy(struct be_ctrl_info *ctrl, struct be_queue_info *q, +- int queue_type) +-{ +- struct be_mcc_wrb *wrb = wrb_from_mbox(&ctrl->mbox_mem); +- struct be_cmd_req_q_destroy *req = embedded_payload(wrb); +- u8 subsys = 0, opcode = 0; +- int status; +- +- spin_lock(&ctrl->cmd_lock); +- +- memset(wrb, 0, sizeof(*wrb)); +- be_wrb_hdr_prepare(wrb, sizeof(*req), true, 0); +- +- switch (queue_type) { +- case QTYPE_EQ: +- subsys = CMD_SUBSYSTEM_COMMON; +- opcode = OPCODE_COMMON_EQ_DESTROY; +- break; +- case QTYPE_CQ: +- subsys = CMD_SUBSYSTEM_COMMON; +- opcode = OPCODE_COMMON_CQ_DESTROY; +- break; +- case QTYPE_TXQ: +- subsys = CMD_SUBSYSTEM_ETH; +- opcode = OPCODE_ETH_TX_DESTROY; +- break; +- case QTYPE_RXQ: +- subsys = CMD_SUBSYSTEM_ETH; +- opcode = OPCODE_ETH_RX_DESTROY; +- break; +- default: +- printk(KERN_WARNING DRV_NAME ":bad Q type in Q destroy cmd\n"); +- status = -1; +- goto err; +- } +- be_cmd_hdr_prepare(&req->hdr, subsys, opcode, sizeof(*req)); +- req->id = cpu_to_le16(q->id); +- +- status = be_mbox_db_ring(ctrl); +-err: +- spin_unlock(&ctrl->cmd_lock); +- +- return status; +-} +- +-/* Create an rx filtering policy configuration on an i/f */ +-int be_cmd_if_create(struct be_ctrl_info *ctrl, u32 flags, u8 *mac, +- bool pmac_invalid, u32 *if_handle, u32 *pmac_id) +-{ +- struct be_mcc_wrb *wrb = wrb_from_mbox(&ctrl->mbox_mem); +- struct be_cmd_req_if_create *req = embedded_payload(wrb); +- int status; +- +- spin_lock(&ctrl->cmd_lock); +- memset(wrb, 0, sizeof(*wrb)); +- +- be_wrb_hdr_prepare(wrb, sizeof(*req), true, 0); +- +- be_cmd_hdr_prepare(&req->hdr, CMD_SUBSYSTEM_COMMON, +- OPCODE_COMMON_NTWK_INTERFACE_CREATE, sizeof(*req)); +- +- req->capability_flags = cpu_to_le32(flags); +- req->enable_flags = cpu_to_le32(flags); +- if (!pmac_invalid) +- memcpy(req->mac_addr, mac, ETH_ALEN); +- +- status = be_mbox_db_ring(ctrl); +- if (!status) { +- struct be_cmd_resp_if_create *resp = embedded_payload(wrb); +- *if_handle = le32_to_cpu(resp->interface_id); +- if (!pmac_invalid) +- *pmac_id = le32_to_cpu(resp->pmac_id); +- } +- +- spin_unlock(&ctrl->cmd_lock); +- return status; +-} +- +-int be_cmd_if_destroy(struct be_ctrl_info *ctrl, u32 interface_id) +-{ +- struct be_mcc_wrb *wrb = wrb_from_mbox(&ctrl->mbox_mem); +- struct be_cmd_req_if_destroy *req = embedded_payload(wrb); +- int status; +- +- spin_lock(&ctrl->cmd_lock); +- memset(wrb, 0, sizeof(*wrb)); +- +- be_wrb_hdr_prepare(wrb, sizeof(*req), true, 0); +- +- be_cmd_hdr_prepare(&req->hdr, CMD_SUBSYSTEM_COMMON, +- OPCODE_COMMON_NTWK_INTERFACE_DESTROY, sizeof(*req)); +- +- req->interface_id = cpu_to_le32(interface_id); +- status = be_mbox_db_ring(ctrl); +- +- spin_unlock(&ctrl->cmd_lock); +- +- return status; +-} +- +-/* Get stats is a non embedded command: the request is not embedded inside +- * WRB but is a separate dma memory block +- */ +-int be_cmd_get_stats(struct be_ctrl_info *ctrl, struct be_dma_mem *nonemb_cmd) +-{ +- struct be_mcc_wrb *wrb = wrb_from_mbox(&ctrl->mbox_mem); +- struct be_cmd_req_get_stats *req = nonemb_cmd->va; +- struct be_sge *sge = nonembedded_sgl(wrb); +- int status; +- +- spin_lock(&ctrl->cmd_lock); +- memset(wrb, 0, sizeof(*wrb)); +- +- memset(req, 0, sizeof(*req)); +- +- be_wrb_hdr_prepare(wrb, sizeof(*req), false, 1); +- +- be_cmd_hdr_prepare(&req->hdr, CMD_SUBSYSTEM_ETH, +- OPCODE_ETH_GET_STATISTICS, sizeof(*req)); +- sge->pa_hi = cpu_to_le32(upper_32_bits(nonemb_cmd->dma)); +- sge->pa_lo = cpu_to_le32(nonemb_cmd->dma & 0xFFFFFFFF); +- sge->len = cpu_to_le32(nonemb_cmd->size); +- +- status = be_mbox_db_ring(ctrl); +- if (!status) { +- struct be_cmd_resp_get_stats *resp = nonemb_cmd->va; +- be_dws_le_to_cpu(&resp->hw_stats, sizeof(resp->hw_stats)); +- } +- +- spin_unlock(&ctrl->cmd_lock); +- return status; +-} +- +-int be_cmd_link_status_query(struct be_ctrl_info *ctrl, +- struct be_link_info *link) +-{ +- struct be_mcc_wrb *wrb = wrb_from_mbox(&ctrl->mbox_mem); +- struct be_cmd_req_link_status *req = embedded_payload(wrb); +- int status; +- +- spin_lock(&ctrl->cmd_lock); +- memset(wrb, 0, sizeof(*wrb)); +- +- be_wrb_hdr_prepare(wrb, sizeof(*req), true, 0); +- +- be_cmd_hdr_prepare(&req->hdr, CMD_SUBSYSTEM_COMMON, +- OPCODE_COMMON_NTWK_LINK_STATUS_QUERY, sizeof(*req)); +- +- status = be_mbox_db_ring(ctrl); +- if (!status) { +- struct be_cmd_resp_link_status *resp = embedded_payload(wrb); +- link->speed = resp->mac_speed; +- link->duplex = resp->mac_duplex; +- link->fault = resp->mac_fault; +- } else { +- link->speed = PHY_LINK_SPEED_ZERO; +- } +- +- spin_unlock(&ctrl->cmd_lock); +- return status; +-} +- +-int be_cmd_get_fw_ver(struct be_ctrl_info *ctrl, char *fw_ver) +-{ +- struct be_mcc_wrb *wrb = wrb_from_mbox(&ctrl->mbox_mem); +- struct be_cmd_req_get_fw_version *req = embedded_payload(wrb); +- int status; +- +- spin_lock(&ctrl->cmd_lock); +- memset(wrb, 0, sizeof(*wrb)); +- +- be_wrb_hdr_prepare(wrb, sizeof(*req), true, 0); +- +- be_cmd_hdr_prepare(&req->hdr, CMD_SUBSYSTEM_COMMON, +- OPCODE_COMMON_GET_FW_VERSION, sizeof(*req)); +- +- status = be_mbox_db_ring(ctrl); +- if (!status) { +- struct be_cmd_resp_get_fw_version *resp = embedded_payload(wrb); +- strncpy(fw_ver, resp->firmware_version_string, FW_VER_LEN); +- } +- +- spin_unlock(&ctrl->cmd_lock); +- return status; +-} +- +-/* set the EQ delay interval of an EQ to specified value */ +-int be_cmd_modify_eqd(struct be_ctrl_info *ctrl, u32 eq_id, u32 eqd) +-{ +- struct be_mcc_wrb *wrb = wrb_from_mbox(&ctrl->mbox_mem); +- struct be_cmd_req_modify_eq_delay *req = embedded_payload(wrb); +- int status; +- +- spin_lock(&ctrl->cmd_lock); +- memset(wrb, 0, sizeof(*wrb)); +- +- be_wrb_hdr_prepare(wrb, sizeof(*req), true, 0); +- +- be_cmd_hdr_prepare(&req->hdr, CMD_SUBSYSTEM_COMMON, +- OPCODE_COMMON_MODIFY_EQ_DELAY, sizeof(*req)); +- +- req->num_eq = cpu_to_le32(1); +- req->delay[0].eq_id = cpu_to_le32(eq_id); +- req->delay[0].phase = 0; +- req->delay[0].delay_multiplier = cpu_to_le32(eqd); +- +- status = be_mbox_db_ring(ctrl); +- +- spin_unlock(&ctrl->cmd_lock); +- return status; +-} +- +-int be_cmd_vlan_config(struct be_ctrl_info *ctrl, u32 if_id, u16 *vtag_array, +- u32 num, bool untagged, bool promiscuous) +-{ +- struct be_mcc_wrb *wrb = wrb_from_mbox(&ctrl->mbox_mem); +- struct be_cmd_req_vlan_config *req = embedded_payload(wrb); +- int status; +- +- spin_lock(&ctrl->cmd_lock); +- memset(wrb, 0, sizeof(*wrb)); +- +- be_wrb_hdr_prepare(wrb, sizeof(*req), true, 0); +- +- be_cmd_hdr_prepare(&req->hdr, CMD_SUBSYSTEM_COMMON, +- OPCODE_COMMON_NTWK_VLAN_CONFIG, sizeof(*req)); +- +- req->interface_id = if_id; +- req->promiscuous = promiscuous; +- req->untagged = untagged; +- req->num_vlan = num; +- if (!promiscuous) { +- memcpy(req->normal_vlan, vtag_array, +- req->num_vlan * sizeof(vtag_array[0])); +- } +- +- status = be_mbox_db_ring(ctrl); +- +- spin_unlock(&ctrl->cmd_lock); +- return status; +-} +- +-int be_cmd_promiscuous_config(struct be_ctrl_info *ctrl, u8 port_num, bool en) +-{ +- struct be_mcc_wrb *wrb = wrb_from_mbox(&ctrl->mbox_mem); +- struct be_cmd_req_promiscuous_config *req = embedded_payload(wrb); +- int status; +- +- spin_lock(&ctrl->cmd_lock); +- memset(wrb, 0, sizeof(*wrb)); +- +- be_wrb_hdr_prepare(wrb, sizeof(*req), true, 0); +- +- be_cmd_hdr_prepare(&req->hdr, CMD_SUBSYSTEM_ETH, +- OPCODE_ETH_PROMISCUOUS, sizeof(*req)); +- +- if (port_num) +- req->port1_promiscuous = en; +- else +- req->port0_promiscuous = en; +- +- status = be_mbox_db_ring(ctrl); +- +- spin_unlock(&ctrl->cmd_lock); +- return status; +-} +- +-int be_cmd_mcast_mac_set(struct be_ctrl_info *ctrl, u32 if_id, u8 *mac_table, +- u32 num, bool promiscuous) +-{ +- struct be_mcc_wrb *wrb = wrb_from_mbox(&ctrl->mbox_mem); +- struct be_cmd_req_mcast_mac_config *req = embedded_payload(wrb); +- int status; +- +- spin_lock(&ctrl->cmd_lock); +- memset(wrb, 0, sizeof(*wrb)); +- +- be_wrb_hdr_prepare(wrb, sizeof(*req), true, 0); +- +- be_cmd_hdr_prepare(&req->hdr, CMD_SUBSYSTEM_COMMON, +- OPCODE_COMMON_NTWK_MULTICAST_SET, sizeof(*req)); +- +- req->interface_id = if_id; +- req->promiscuous = promiscuous; +- if (!promiscuous) { +- req->num_mac = cpu_to_le16(num); +- if (num) +- memcpy(req->mac, mac_table, ETH_ALEN * num); +- } +- +- status = be_mbox_db_ring(ctrl); +- +- spin_unlock(&ctrl->cmd_lock); +- return status; +-} +- +-int be_cmd_set_flow_control(struct be_ctrl_info *ctrl, u32 tx_fc, u32 rx_fc) +-{ +- struct be_mcc_wrb *wrb = wrb_from_mbox(&ctrl->mbox_mem); +- struct be_cmd_req_set_flow_control *req = embedded_payload(wrb); +- int status; +- +- spin_lock(&ctrl->cmd_lock); +- +- memset(wrb, 0, sizeof(*wrb)); +- +- be_wrb_hdr_prepare(wrb, sizeof(*req), true, 0); +- +- be_cmd_hdr_prepare(&req->hdr, CMD_SUBSYSTEM_COMMON, +- OPCODE_COMMON_SET_FLOW_CONTROL, sizeof(*req)); +- +- req->tx_flow_control = cpu_to_le16((u16)tx_fc); +- req->rx_flow_control = cpu_to_le16((u16)rx_fc); +- +- status = be_mbox_db_ring(ctrl); +- +- spin_unlock(&ctrl->cmd_lock); +- return status; +-} +- +-int be_cmd_get_flow_control(struct be_ctrl_info *ctrl, u32 *tx_fc, u32 *rx_fc) +-{ +- struct be_mcc_wrb *wrb = wrb_from_mbox(&ctrl->mbox_mem); +- struct be_cmd_req_get_flow_control *req = embedded_payload(wrb); +- int status; +- +- spin_lock(&ctrl->cmd_lock); +- +- memset(wrb, 0, sizeof(*wrb)); +- +- be_wrb_hdr_prepare(wrb, sizeof(*req), true, 0); +- +- be_cmd_hdr_prepare(&req->hdr, CMD_SUBSYSTEM_COMMON, +- OPCODE_COMMON_GET_FLOW_CONTROL, sizeof(*req)); +- +- status = be_mbox_db_ring(ctrl); +- if (!status) { +- struct be_cmd_resp_get_flow_control *resp = +- embedded_payload(wrb); +- *tx_fc = le16_to_cpu(resp->tx_flow_control); +- *rx_fc = le16_to_cpu(resp->rx_flow_control); +- } +- +- spin_unlock(&ctrl->cmd_lock); +- return status; +-} +- +-int be_cmd_query_fw_cfg(struct be_ctrl_info *ctrl, u32 *port_num) +-{ +- struct be_mcc_wrb *wrb = wrb_from_mbox(&ctrl->mbox_mem); +- struct be_cmd_req_query_fw_cfg *req = embedded_payload(wrb); +- int status; +- +- spin_lock(&ctrl->cmd_lock); +- +- memset(wrb, 0, sizeof(*wrb)); +- +- be_wrb_hdr_prepare(wrb, sizeof(*req), true, 0); +- +- be_cmd_hdr_prepare(&req->hdr, CMD_SUBSYSTEM_COMMON, +- OPCODE_COMMON_QUERY_FIRMWARE_CONFIG, sizeof(*req)); +- +- status = be_mbox_db_ring(ctrl); +- if (!status) { +- struct be_cmd_resp_query_fw_cfg *resp = embedded_payload(wrb); +- *port_num = le32_to_cpu(resp->phys_port); +- } +- +- spin_unlock(&ctrl->cmd_lock); +- return status; +-} +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/drivers/net/benet/be_cmds.h linux-2.6.29-rc3.owrt/drivers/net/benet/be_cmds.h +--- linux-2.6.29.owrt/drivers/net/benet/be_cmds.h 2009-05-10 22:04:38.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/drivers/net/benet/be_cmds.h 1970-01-01 01:00:00.000000000 +0100 +@@ -1,688 +0,0 @@ +-/* +- * Copyright (C) 2005 - 2009 ServerEngines +- * All rights reserved. +- * +- * 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. The full GNU General +- * Public License is included in this distribution in the file called COPYING. +- * +- * Contact Information: +- * linux-drivers@serverengines.com +- * +- * ServerEngines +- * 209 N. Fair Oaks Ave +- * Sunnyvale, CA 94085 +- */ +- +-/* +- * The driver sends configuration and managements command requests to the +- * firmware in the BE. These requests are communicated to the processor +- * using Work Request Blocks (WRBs) submitted to the MCC-WRB ring or via one +- * WRB inside a MAILBOX. +- * The commands are serviced by the ARM processor in the BladeEngine's MPU. +- */ +- +-struct be_sge { +- u32 pa_lo; +- u32 pa_hi; +- u32 len; +-}; +- +-#define MCC_WRB_EMBEDDED_MASK 1 /* bit 0 of dword 0*/ +-#define MCC_WRB_SGE_CNT_SHIFT 3 /* bits 3 - 7 of dword 0 */ +-#define MCC_WRB_SGE_CNT_MASK 0x1F /* bits 3 - 7 of dword 0 */ +-struct be_mcc_wrb { +- u32 embedded; /* dword 0 */ +- u32 payload_length; /* dword 1 */ +- u32 tag0; /* dword 2 */ +- u32 tag1; /* dword 3 */ +- u32 rsvd; /* dword 4 */ +- union { +- u8 embedded_payload[236]; /* used by embedded cmds */ +- struct be_sge sgl[19]; /* used by non-embedded cmds */ +- } payload; +-}; +- +-#define CQE_FLAGS_VALID_MASK (1 << 31) +-#define CQE_FLAGS_ASYNC_MASK (1 << 30) +-#define CQE_FLAGS_COMPLETED_MASK (1 << 28) +-#define CQE_FLAGS_CONSUMED_MASK (1 << 27) +- +-/* Completion Status */ +-enum { +- MCC_STATUS_SUCCESS = 0x0, +-/* The client does not have sufficient privileges to execute the command */ +- MCC_STATUS_INSUFFICIENT_PRIVILEGES = 0x1, +-/* A parameter in the command was invalid. */ +- MCC_STATUS_INVALID_PARAMETER = 0x2, +-/* There are insufficient chip resources to execute the command */ +- MCC_STATUS_INSUFFICIENT_RESOURCES = 0x3, +-/* The command is completing because the queue was getting flushed */ +- MCC_STATUS_QUEUE_FLUSHING = 0x4, +-/* The command is completing with a DMA error */ +- MCC_STATUS_DMA_FAILED = 0x5 +-}; +- +-#define CQE_STATUS_COMPL_MASK 0xFFFF +-#define CQE_STATUS_COMPL_SHIFT 0 /* bits 0 - 15 */ +-#define CQE_STATUS_EXTD_MASK 0xFFFF +-#define CQE_STATUS_EXTD_SHIFT 0 /* bits 0 - 15 */ +- +-struct be_mcc_cq_entry { +- u32 status; /* dword 0 */ +- u32 tag0; /* dword 1 */ +- u32 tag1; /* dword 2 */ +- u32 flags; /* dword 3 */ +-}; +- +-struct be_mcc_mailbox { +- struct be_mcc_wrb wrb; +- struct be_mcc_cq_entry cqe; +-}; +- +-#define CMD_SUBSYSTEM_COMMON 0x1 +-#define CMD_SUBSYSTEM_ETH 0x3 +- +-#define OPCODE_COMMON_NTWK_MAC_QUERY 1 +-#define OPCODE_COMMON_NTWK_MAC_SET 2 +-#define OPCODE_COMMON_NTWK_MULTICAST_SET 3 +-#define OPCODE_COMMON_NTWK_VLAN_CONFIG 4 +-#define OPCODE_COMMON_NTWK_LINK_STATUS_QUERY 5 +-#define OPCODE_COMMON_CQ_CREATE 12 +-#define OPCODE_COMMON_EQ_CREATE 13 +-#define OPCODE_COMMON_MCC_CREATE 21 +-#define OPCODE_COMMON_NTWK_RX_FILTER 34 +-#define OPCODE_COMMON_GET_FW_VERSION 35 +-#define OPCODE_COMMON_SET_FLOW_CONTROL 36 +-#define OPCODE_COMMON_GET_FLOW_CONTROL 37 +-#define OPCODE_COMMON_SET_FRAME_SIZE 39 +-#define OPCODE_COMMON_MODIFY_EQ_DELAY 41 +-#define OPCODE_COMMON_FIRMWARE_CONFIG 42 +-#define OPCODE_COMMON_NTWK_INTERFACE_CREATE 50 +-#define OPCODE_COMMON_NTWK_INTERFACE_DESTROY 51 +-#define OPCODE_COMMON_CQ_DESTROY 54 +-#define OPCODE_COMMON_EQ_DESTROY 55 +-#define OPCODE_COMMON_QUERY_FIRMWARE_CONFIG 58 +-#define OPCODE_COMMON_NTWK_PMAC_ADD 59 +-#define OPCODE_COMMON_NTWK_PMAC_DEL 60 +- +-#define OPCODE_ETH_ACPI_CONFIG 2 +-#define OPCODE_ETH_PROMISCUOUS 3 +-#define OPCODE_ETH_GET_STATISTICS 4 +-#define OPCODE_ETH_TX_CREATE 7 +-#define OPCODE_ETH_RX_CREATE 8 +-#define OPCODE_ETH_TX_DESTROY 9 +-#define OPCODE_ETH_RX_DESTROY 10 +- +-struct be_cmd_req_hdr { +- u8 opcode; /* dword 0 */ +- u8 subsystem; /* dword 0 */ +- u8 port_number; /* dword 0 */ +- u8 domain; /* dword 0 */ +- u32 timeout; /* dword 1 */ +- u32 request_length; /* dword 2 */ +- u32 rsvd; /* dword 3 */ +-}; +- +-#define RESP_HDR_INFO_OPCODE_SHIFT 0 /* bits 0 - 7 */ +-#define RESP_HDR_INFO_SUBSYS_SHIFT 8 /* bits 8 - 15 */ +-struct be_cmd_resp_hdr { +- u32 info; /* dword 0 */ +- u32 status; /* dword 1 */ +- u32 response_length; /* dword 2 */ +- u32 actual_resp_len; /* dword 3 */ +-}; +- +-struct phys_addr { +- u32 lo; +- u32 hi; +-}; +- +-/************************** +- * BE Command definitions * +- **************************/ +- +-/* Pseudo amap definition in which each bit of the actual structure is defined +- * as a byte: used to calculate offset/shift/mask of each field */ +-struct amap_eq_context { +- u8 cidx[13]; /* dword 0*/ +- u8 rsvd0[3]; /* dword 0*/ +- u8 epidx[13]; /* dword 0*/ +- u8 valid; /* dword 0*/ +- u8 rsvd1; /* dword 0*/ +- u8 size; /* dword 0*/ +- u8 pidx[13]; /* dword 1*/ +- u8 rsvd2[3]; /* dword 1*/ +- u8 pd[10]; /* dword 1*/ +- u8 count[3]; /* dword 1*/ +- u8 solevent; /* dword 1*/ +- u8 stalled; /* dword 1*/ +- u8 armed; /* dword 1*/ +- u8 rsvd3[4]; /* dword 2*/ +- u8 func[8]; /* dword 2*/ +- u8 rsvd4; /* dword 2*/ +- u8 delaymult[10]; /* dword 2*/ +- u8 rsvd5[2]; /* dword 2*/ +- u8 phase[2]; /* dword 2*/ +- u8 nodelay; /* dword 2*/ +- u8 rsvd6[4]; /* dword 2*/ +- u8 rsvd7[32]; /* dword 3*/ +-} __packed; +- +-struct be_cmd_req_eq_create { +- struct be_cmd_req_hdr hdr; +- u16 num_pages; /* sword */ +- u16 rsvd0; /* sword */ +- u8 context[sizeof(struct amap_eq_context) / 8]; +- struct phys_addr pages[8]; +-} __packed; +- +-struct be_cmd_resp_eq_create { +- struct be_cmd_resp_hdr resp_hdr; +- u16 eq_id; /* sword */ +- u16 rsvd0; /* sword */ +-} __packed; +- +-/******************** Mac query ***************************/ +-enum { +- MAC_ADDRESS_TYPE_STORAGE = 0x0, +- MAC_ADDRESS_TYPE_NETWORK = 0x1, +- MAC_ADDRESS_TYPE_PD = 0x2, +- MAC_ADDRESS_TYPE_MANAGEMENT = 0x3 +-}; +- +-struct mac_addr { +- u16 size_of_struct; +- u8 addr[ETH_ALEN]; +-} __packed; +- +-struct be_cmd_req_mac_query { +- struct be_cmd_req_hdr hdr; +- u8 type; +- u8 permanent; +- u16 if_id; +-} __packed; +- +-struct be_cmd_resp_mac_query { +- struct be_cmd_resp_hdr hdr; +- struct mac_addr mac; +-}; +- +-/******************** PMac Add ***************************/ +-struct be_cmd_req_pmac_add { +- struct be_cmd_req_hdr hdr; +- u32 if_id; +- u8 mac_address[ETH_ALEN]; +- u8 rsvd0[2]; +-} __packed; +- +-struct be_cmd_resp_pmac_add { +- struct be_cmd_resp_hdr hdr; +- u32 pmac_id; +-}; +- +-/******************** PMac Del ***************************/ +-struct be_cmd_req_pmac_del { +- struct be_cmd_req_hdr hdr; +- u32 if_id; +- u32 pmac_id; +-}; +- +-/******************** Create CQ ***************************/ +-/* Pseudo amap definition in which each bit of the actual structure is defined +- * as a byte: used to calculate offset/shift/mask of each field */ +-struct amap_cq_context { +- u8 cidx[11]; /* dword 0*/ +- u8 rsvd0; /* dword 0*/ +- u8 coalescwm[2]; /* dword 0*/ +- u8 nodelay; /* dword 0*/ +- u8 epidx[11]; /* dword 0*/ +- u8 rsvd1; /* dword 0*/ +- u8 count[2]; /* dword 0*/ +- u8 valid; /* dword 0*/ +- u8 solevent; /* dword 0*/ +- u8 eventable; /* dword 0*/ +- u8 pidx[11]; /* dword 1*/ +- u8 rsvd2; /* dword 1*/ +- u8 pd[10]; /* dword 1*/ +- u8 eqid[8]; /* dword 1*/ +- u8 stalled; /* dword 1*/ +- u8 armed; /* dword 1*/ +- u8 rsvd3[4]; /* dword 2*/ +- u8 func[8]; /* dword 2*/ +- u8 rsvd4[20]; /* dword 2*/ +- u8 rsvd5[32]; /* dword 3*/ +-} __packed; +- +-struct be_cmd_req_cq_create { +- struct be_cmd_req_hdr hdr; +- u16 num_pages; +- u16 rsvd0; +- u8 context[sizeof(struct amap_cq_context) / 8]; +- struct phys_addr pages[8]; +-} __packed; +- +-struct be_cmd_resp_cq_create { +- struct be_cmd_resp_hdr hdr; +- u16 cq_id; +- u16 rsvd0; +-} __packed; +- +-/******************** Create TxQ ***************************/ +-#define BE_ETH_TX_RING_TYPE_STANDARD 2 +-#define BE_ULP1_NUM 1 +- +-/* Pseudo amap definition in which each bit of the actual structure is defined +- * as a byte: used to calculate offset/shift/mask of each field */ +-struct amap_tx_context { +- u8 rsvd0[16]; /* dword 0 */ +- u8 tx_ring_size[4]; /* dword 0 */ +- u8 rsvd1[26]; /* dword 0 */ +- u8 pci_func_id[8]; /* dword 1 */ +- u8 rsvd2[9]; /* dword 1 */ +- u8 ctx_valid; /* dword 1 */ +- u8 cq_id_send[16]; /* dword 2 */ +- u8 rsvd3[16]; /* dword 2 */ +- u8 rsvd4[32]; /* dword 3 */ +- u8 rsvd5[32]; /* dword 4 */ +- u8 rsvd6[32]; /* dword 5 */ +- u8 rsvd7[32]; /* dword 6 */ +- u8 rsvd8[32]; /* dword 7 */ +- u8 rsvd9[32]; /* dword 8 */ +- u8 rsvd10[32]; /* dword 9 */ +- u8 rsvd11[32]; /* dword 10 */ +- u8 rsvd12[32]; /* dword 11 */ +- u8 rsvd13[32]; /* dword 12 */ +- u8 rsvd14[32]; /* dword 13 */ +- u8 rsvd15[32]; /* dword 14 */ +- u8 rsvd16[32]; /* dword 15 */ +-} __packed; +- +-struct be_cmd_req_eth_tx_create { +- struct be_cmd_req_hdr hdr; +- u8 num_pages; +- u8 ulp_num; +- u8 type; +- u8 bound_port; +- u8 context[sizeof(struct amap_tx_context) / 8]; +- struct phys_addr pages[8]; +-} __packed; +- +-struct be_cmd_resp_eth_tx_create { +- struct be_cmd_resp_hdr hdr; +- u16 cid; +- u16 rsvd0; +-} __packed; +- +-/******************** Create RxQ ***************************/ +-struct be_cmd_req_eth_rx_create { +- struct be_cmd_req_hdr hdr; +- u16 cq_id; +- u8 frag_size; +- u8 num_pages; +- struct phys_addr pages[2]; +- u32 interface_id; +- u16 max_frame_size; +- u16 rsvd0; +- u32 rss_queue; +-} __packed; +- +-struct be_cmd_resp_eth_rx_create { +- struct be_cmd_resp_hdr hdr; +- u16 id; +- u8 cpu_id; +- u8 rsvd0; +-} __packed; +- +-/******************** Q Destroy ***************************/ +-/* Type of Queue to be destroyed */ +-enum { +- QTYPE_EQ = 1, +- QTYPE_CQ, +- QTYPE_TXQ, +- QTYPE_RXQ +-}; +- +-struct be_cmd_req_q_destroy { +- struct be_cmd_req_hdr hdr; +- u16 id; +- u16 bypass_flush; /* valid only for rx q destroy */ +-} __packed; +- +-/************ I/f Create (it's actually I/f Config Create)**********/ +- +-/* Capability flags for the i/f */ +-enum be_if_flags { +- BE_IF_FLAGS_RSS = 0x4, +- BE_IF_FLAGS_PROMISCUOUS = 0x8, +- BE_IF_FLAGS_BROADCAST = 0x10, +- BE_IF_FLAGS_UNTAGGED = 0x20, +- BE_IF_FLAGS_ULP = 0x40, +- BE_IF_FLAGS_VLAN_PROMISCUOUS = 0x80, +- BE_IF_FLAGS_VLAN = 0x100, +- BE_IF_FLAGS_MCAST_PROMISCUOUS = 0x200, +- BE_IF_FLAGS_PASS_L2_ERRORS = 0x400, +- BE_IF_FLAGS_PASS_L3L4_ERRORS = 0x800 +-}; +- +-/* An RX interface is an object with one or more MAC addresses and +- * filtering capabilities. */ +-struct be_cmd_req_if_create { +- struct be_cmd_req_hdr hdr; +- u32 version; /* ignore currntly */ +- u32 capability_flags; +- u32 enable_flags; +- u8 mac_addr[ETH_ALEN]; +- u8 rsvd0; +- u8 pmac_invalid; /* if set, don't attach the mac addr to the i/f */ +- u32 vlan_tag; /* not used currently */ +-} __packed; +- +-struct be_cmd_resp_if_create { +- struct be_cmd_resp_hdr hdr; +- u32 interface_id; +- u32 pmac_id; +-}; +- +-/****** I/f Destroy(it's actually I/f Config Destroy )**********/ +-struct be_cmd_req_if_destroy { +- struct be_cmd_req_hdr hdr; +- u32 interface_id; +-}; +- +-/*************** HW Stats Get **********************************/ +-struct be_port_rxf_stats { +- u32 rx_bytes_lsd; /* dword 0*/ +- u32 rx_bytes_msd; /* dword 1*/ +- u32 rx_total_frames; /* dword 2*/ +- u32 rx_unicast_frames; /* dword 3*/ +- u32 rx_multicast_frames; /* dword 4*/ +- u32 rx_broadcast_frames; /* dword 5*/ +- u32 rx_crc_errors; /* dword 6*/ +- u32 rx_alignment_symbol_errors; /* dword 7*/ +- u32 rx_pause_frames; /* dword 8*/ +- u32 rx_control_frames; /* dword 9*/ +- u32 rx_in_range_errors; /* dword 10*/ +- u32 rx_out_range_errors; /* dword 11*/ +- u32 rx_frame_too_long; /* dword 12*/ +- u32 rx_address_match_errors; /* dword 13*/ +- u32 rx_vlan_mismatch; /* dword 14*/ +- u32 rx_dropped_too_small; /* dword 15*/ +- u32 rx_dropped_too_short; /* dword 16*/ +- u32 rx_dropped_header_too_small; /* dword 17*/ +- u32 rx_dropped_tcp_length; /* dword 18*/ +- u32 rx_dropped_runt; /* dword 19*/ +- u32 rx_64_byte_packets; /* dword 20*/ +- u32 rx_65_127_byte_packets; /* dword 21*/ +- u32 rx_128_256_byte_packets; /* dword 22*/ +- u32 rx_256_511_byte_packets; /* dword 23*/ +- u32 rx_512_1023_byte_packets; /* dword 24*/ +- u32 rx_1024_1518_byte_packets; /* dword 25*/ +- u32 rx_1519_2047_byte_packets; /* dword 26*/ +- u32 rx_2048_4095_byte_packets; /* dword 27*/ +- u32 rx_4096_8191_byte_packets; /* dword 28*/ +- u32 rx_8192_9216_byte_packets; /* dword 29*/ +- u32 rx_ip_checksum_errs; /* dword 30*/ +- u32 rx_tcp_checksum_errs; /* dword 31*/ +- u32 rx_udp_checksum_errs; /* dword 32*/ +- u32 rx_non_rss_packets; /* dword 33*/ +- u32 rx_ipv4_packets; /* dword 34*/ +- u32 rx_ipv6_packets; /* dword 35*/ +- u32 rx_ipv4_bytes_lsd; /* dword 36*/ +- u32 rx_ipv4_bytes_msd; /* dword 37*/ +- u32 rx_ipv6_bytes_lsd; /* dword 38*/ +- u32 rx_ipv6_bytes_msd; /* dword 39*/ +- u32 rx_chute1_packets; /* dword 40*/ +- u32 rx_chute2_packets; /* dword 41*/ +- u32 rx_chute3_packets; /* dword 42*/ +- u32 rx_management_packets; /* dword 43*/ +- u32 rx_switched_unicast_packets; /* dword 44*/ +- u32 rx_switched_multicast_packets; /* dword 45*/ +- u32 rx_switched_broadcast_packets; /* dword 46*/ +- u32 tx_bytes_lsd; /* dword 47*/ +- u32 tx_bytes_msd; /* dword 48*/ +- u32 tx_unicastframes; /* dword 49*/ +- u32 tx_multicastframes; /* dword 50*/ +- u32 tx_broadcastframes; /* dword 51*/ +- u32 tx_pauseframes; /* dword 52*/ +- u32 tx_controlframes; /* dword 53*/ +- u32 tx_64_byte_packets; /* dword 54*/ +- u32 tx_65_127_byte_packets; /* dword 55*/ +- u32 tx_128_256_byte_packets; /* dword 56*/ +- u32 tx_256_511_byte_packets; /* dword 57*/ +- u32 tx_512_1023_byte_packets; /* dword 58*/ +- u32 tx_1024_1518_byte_packets; /* dword 59*/ +- u32 tx_1519_2047_byte_packets; /* dword 60*/ +- u32 tx_2048_4095_byte_packets; /* dword 61*/ +- u32 tx_4096_8191_byte_packets; /* dword 62*/ +- u32 tx_8192_9216_byte_packets; /* dword 63*/ +- u32 rx_fifo_overflow; /* dword 64*/ +- u32 rx_input_fifo_overflow; /* dword 65*/ +-}; +- +-struct be_rxf_stats { +- struct be_port_rxf_stats port[2]; +- u32 rx_drops_no_pbuf; /* dword 132*/ +- u32 rx_drops_no_txpb; /* dword 133*/ +- u32 rx_drops_no_erx_descr; /* dword 134*/ +- u32 rx_drops_no_tpre_descr; /* dword 135*/ +- u32 management_rx_port_packets; /* dword 136*/ +- u32 management_rx_port_bytes; /* dword 137*/ +- u32 management_rx_port_pause_frames; /* dword 138*/ +- u32 management_rx_port_errors; /* dword 139*/ +- u32 management_tx_port_packets; /* dword 140*/ +- u32 management_tx_port_bytes; /* dword 141*/ +- u32 management_tx_port_pause; /* dword 142*/ +- u32 management_rx_port_rxfifo_overflow; /* dword 143*/ +- u32 rx_drops_too_many_frags; /* dword 144*/ +- u32 rx_drops_invalid_ring; /* dword 145*/ +- u32 forwarded_packets; /* dword 146*/ +- u32 rx_drops_mtu; /* dword 147*/ +- u32 rsvd0[15]; +-}; +- +-struct be_erx_stats { +- u32 rx_drops_no_fragments[44]; /* dwordS 0 to 43*/ +- u32 debug_wdma_sent_hold; /* dword 44*/ +- u32 debug_wdma_pbfree_sent_hold; /* dword 45*/ +- u32 debug_wdma_zerobyte_pbfree_sent_hold; /* dword 46*/ +- u32 debug_pmem_pbuf_dealloc; /* dword 47*/ +-}; +- +-struct be_hw_stats { +- struct be_rxf_stats rxf; +- u32 rsvd[48]; +- struct be_erx_stats erx; +-}; +- +-struct be_cmd_req_get_stats { +- struct be_cmd_req_hdr hdr; +- u8 rsvd[sizeof(struct be_hw_stats)]; +-}; +- +-struct be_cmd_resp_get_stats { +- struct be_cmd_resp_hdr hdr; +- struct be_hw_stats hw_stats; +-}; +- +-struct be_cmd_req_vlan_config { +- struct be_cmd_req_hdr hdr; +- u8 interface_id; +- u8 promiscuous; +- u8 untagged; +- u8 num_vlan; +- u16 normal_vlan[64]; +-} __packed; +- +-struct be_cmd_req_promiscuous_config { +- struct be_cmd_req_hdr hdr; +- u8 port0_promiscuous; +- u8 port1_promiscuous; +- u16 rsvd0; +-} __packed; +- +-struct macaddr { +- u8 byte[ETH_ALEN]; +-}; +- +-struct be_cmd_req_mcast_mac_config { +- struct be_cmd_req_hdr hdr; +- u16 num_mac; +- u8 promiscuous; +- u8 interface_id; +- struct macaddr mac[32]; +-} __packed; +- +-static inline struct be_hw_stats * +-hw_stats_from_cmd(struct be_cmd_resp_get_stats *cmd) +-{ +- return &cmd->hw_stats; +-} +- +-/******************** Link Status Query *******************/ +-struct be_cmd_req_link_status { +- struct be_cmd_req_hdr hdr; +- u32 rsvd; +-}; +- +-struct be_link_info { +- u8 duplex; +- u8 speed; +- u8 fault; +-}; +- +-enum { +- PHY_LINK_DUPLEX_NONE = 0x0, +- PHY_LINK_DUPLEX_HALF = 0x1, +- PHY_LINK_DUPLEX_FULL = 0x2 +-}; +- +-enum { +- PHY_LINK_SPEED_ZERO = 0x0, /* => No link */ +- PHY_LINK_SPEED_10MBPS = 0x1, +- PHY_LINK_SPEED_100MBPS = 0x2, +- PHY_LINK_SPEED_1GBPS = 0x3, +- PHY_LINK_SPEED_10GBPS = 0x4 +-}; +- +-struct be_cmd_resp_link_status { +- struct be_cmd_resp_hdr hdr; +- u8 physical_port; +- u8 mac_duplex; +- u8 mac_speed; +- u8 mac_fault; +- u8 mgmt_mac_duplex; +- u8 mgmt_mac_speed; +- u16 rsvd0; +-} __packed; +- +-/******************** Get FW Version *******************/ +-#define FW_VER_LEN 32 +-struct be_cmd_req_get_fw_version { +- struct be_cmd_req_hdr hdr; +- u8 rsvd0[FW_VER_LEN]; +- u8 rsvd1[FW_VER_LEN]; +-} __packed; +- +-struct be_cmd_resp_get_fw_version { +- struct be_cmd_resp_hdr hdr; +- u8 firmware_version_string[FW_VER_LEN]; +- u8 fw_on_flash_version_string[FW_VER_LEN]; +-} __packed; +- +-/******************** Set Flow Contrl *******************/ +-struct be_cmd_req_set_flow_control { +- struct be_cmd_req_hdr hdr; +- u16 tx_flow_control; +- u16 rx_flow_control; +-} __packed; +- +-/******************** Get Flow Contrl *******************/ +-struct be_cmd_req_get_flow_control { +- struct be_cmd_req_hdr hdr; +- u32 rsvd; +-}; +- +-struct be_cmd_resp_get_flow_control { +- struct be_cmd_resp_hdr hdr; +- u16 tx_flow_control; +- u16 rx_flow_control; +-} __packed; +- +-/******************** Modify EQ Delay *******************/ +-struct be_cmd_req_modify_eq_delay { +- struct be_cmd_req_hdr hdr; +- u32 num_eq; +- struct { +- u32 eq_id; +- u32 phase; +- u32 delay_multiplier; +- } delay[8]; +-} __packed; +- +-struct be_cmd_resp_modify_eq_delay { +- struct be_cmd_resp_hdr hdr; +- u32 rsvd0; +-} __packed; +- +-/******************** Get FW Config *******************/ +-struct be_cmd_req_query_fw_cfg { +- struct be_cmd_req_hdr hdr; +- u32 rsvd[30]; +-}; +- +-struct be_cmd_resp_query_fw_cfg { +- struct be_cmd_resp_hdr hdr; +- u32 be_config_number; +- u32 asic_revision; +- u32 phys_port; +- u32 function_mode; +- u32 rsvd[26]; +-}; +- +-extern int be_pci_fnum_get(struct be_ctrl_info *ctrl); +-extern int be_cmd_POST(struct be_ctrl_info *ctrl); +-extern int be_cmd_mac_addr_query(struct be_ctrl_info *ctrl, u8 *mac_addr, +- u8 type, bool permanent, u32 if_handle); +-extern int be_cmd_pmac_add(struct be_ctrl_info *ctrl, u8 *mac_addr, +- u32 if_id, u32 *pmac_id); +-extern int be_cmd_pmac_del(struct be_ctrl_info *ctrl, u32 if_id, u32 pmac_id); +-extern int be_cmd_if_create(struct be_ctrl_info *ctrl, u32 if_flags, u8 *mac, +- bool pmac_invalid, u32 *if_handle, u32 *pmac_id); +-extern int be_cmd_if_destroy(struct be_ctrl_info *ctrl, u32 if_handle); +-extern int be_cmd_eq_create(struct be_ctrl_info *ctrl, +- struct be_queue_info *eq, int eq_delay); +-extern int be_cmd_cq_create(struct be_ctrl_info *ctrl, +- struct be_queue_info *cq, struct be_queue_info *eq, +- bool sol_evts, bool no_delay, +- int num_cqe_dma_coalesce); +-extern int be_cmd_txq_create(struct be_ctrl_info *ctrl, +- struct be_queue_info *txq, +- struct be_queue_info *cq); +-extern int be_cmd_rxq_create(struct be_ctrl_info *ctrl, +- struct be_queue_info *rxq, u16 cq_id, +- u16 frag_size, u16 max_frame_size, u32 if_id, +- u32 rss); +-extern int be_cmd_q_destroy(struct be_ctrl_info *ctrl, struct be_queue_info *q, +- int type); +-extern int be_cmd_link_status_query(struct be_ctrl_info *ctrl, +- struct be_link_info *link); +-extern int be_cmd_reset(struct be_ctrl_info *ctrl); +-extern int be_cmd_get_stats(struct be_ctrl_info *ctrl, +- struct be_dma_mem *nonemb_cmd); +-extern int be_cmd_get_fw_ver(struct be_ctrl_info *ctrl, char *fw_ver); +- +-extern int be_cmd_modify_eqd(struct be_ctrl_info *ctrl, u32 eq_id, u32 eqd); +-extern int be_cmd_vlan_config(struct be_ctrl_info *ctrl, u32 if_id, +- u16 *vtag_array, u32 num, bool untagged, +- bool promiscuous); +-extern int be_cmd_promiscuous_config(struct be_ctrl_info *ctrl, +- u8 port_num, bool en); +-extern int be_cmd_mcast_mac_set(struct be_ctrl_info *ctrl, u32 if_id, +- u8 *mac_table, u32 num, bool promiscuous); +-extern int be_cmd_set_flow_control(struct be_ctrl_info *ctrl, +- u32 tx_fc, u32 rx_fc); +-extern int be_cmd_get_flow_control(struct be_ctrl_info *ctrl, +- u32 *tx_fc, u32 *rx_fc); +-extern int be_cmd_query_fw_cfg(struct be_ctrl_info *ctrl, u32 *port_num); +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/drivers/net/benet/be_ethtool.c linux-2.6.29-rc3.owrt/drivers/net/benet/be_ethtool.c +--- linux-2.6.29.owrt/drivers/net/benet/be_ethtool.c 2009-05-10 22:04:38.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/drivers/net/benet/be_ethtool.c 1970-01-01 01:00:00.000000000 +0100 +@@ -1,362 +0,0 @@ +-/* +- * Copyright (C) 2005 - 2009 ServerEngines +- * All rights reserved. +- * +- * 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. The full GNU General +- * Public License is included in this distribution in the file called COPYING. +- * +- * Contact Information: +- * linux-drivers@serverengines.com +- * +- * ServerEngines +- * 209 N. Fair Oaks Ave +- * Sunnyvale, CA 94085 +- */ +- +-#include "be.h" +-#include <linux/ethtool.h> +- +-struct be_ethtool_stat { +- char desc[ETH_GSTRING_LEN]; +- int type; +- int size; +- int offset; +-}; +- +-enum {NETSTAT, PORTSTAT, MISCSTAT, DRVSTAT, ERXSTAT}; +-#define FIELDINFO(_struct, field) FIELD_SIZEOF(_struct, field), \ +- offsetof(_struct, field) +-#define NETSTAT_INFO(field) #field, NETSTAT,\ +- FIELDINFO(struct net_device_stats,\ +- field) +-#define DRVSTAT_INFO(field) #field, DRVSTAT,\ +- FIELDINFO(struct be_drvr_stats, field) +-#define MISCSTAT_INFO(field) #field, MISCSTAT,\ +- FIELDINFO(struct be_rxf_stats, field) +-#define PORTSTAT_INFO(field) #field, PORTSTAT,\ +- FIELDINFO(struct be_port_rxf_stats, \ +- field) +-#define ERXSTAT_INFO(field) #field, ERXSTAT,\ +- FIELDINFO(struct be_erx_stats, field) +- +-static const struct be_ethtool_stat et_stats[] = { +- {NETSTAT_INFO(rx_packets)}, +- {NETSTAT_INFO(tx_packets)}, +- {NETSTAT_INFO(rx_bytes)}, +- {NETSTAT_INFO(tx_bytes)}, +- {NETSTAT_INFO(rx_errors)}, +- {NETSTAT_INFO(tx_errors)}, +- {NETSTAT_INFO(rx_dropped)}, +- {NETSTAT_INFO(tx_dropped)}, +- {DRVSTAT_INFO(be_tx_reqs)}, +- {DRVSTAT_INFO(be_tx_stops)}, +- {DRVSTAT_INFO(be_fwd_reqs)}, +- {DRVSTAT_INFO(be_tx_wrbs)}, +- {DRVSTAT_INFO(be_polls)}, +- {DRVSTAT_INFO(be_tx_events)}, +- {DRVSTAT_INFO(be_rx_events)}, +- {DRVSTAT_INFO(be_tx_compl)}, +- {DRVSTAT_INFO(be_rx_compl)}, +- {DRVSTAT_INFO(be_ethrx_post_fail)}, +- {DRVSTAT_INFO(be_802_3_dropped_frames)}, +- {DRVSTAT_INFO(be_802_3_malformed_frames)}, +- {DRVSTAT_INFO(be_tx_rate)}, +- {DRVSTAT_INFO(be_rx_rate)}, +- {PORTSTAT_INFO(rx_unicast_frames)}, +- {PORTSTAT_INFO(rx_multicast_frames)}, +- {PORTSTAT_INFO(rx_broadcast_frames)}, +- {PORTSTAT_INFO(rx_crc_errors)}, +- {PORTSTAT_INFO(rx_alignment_symbol_errors)}, +- {PORTSTAT_INFO(rx_pause_frames)}, +- {PORTSTAT_INFO(rx_control_frames)}, +- {PORTSTAT_INFO(rx_in_range_errors)}, +- {PORTSTAT_INFO(rx_out_range_errors)}, +- {PORTSTAT_INFO(rx_frame_too_long)}, +- {PORTSTAT_INFO(rx_address_match_errors)}, +- {PORTSTAT_INFO(rx_vlan_mismatch)}, +- {PORTSTAT_INFO(rx_dropped_too_small)}, +- {PORTSTAT_INFO(rx_dropped_too_short)}, +- {PORTSTAT_INFO(rx_dropped_header_too_small)}, +- {PORTSTAT_INFO(rx_dropped_tcp_length)}, +- {PORTSTAT_INFO(rx_dropped_runt)}, +- {PORTSTAT_INFO(rx_fifo_overflow)}, +- {PORTSTAT_INFO(rx_input_fifo_overflow)}, +- {PORTSTAT_INFO(rx_ip_checksum_errs)}, +- {PORTSTAT_INFO(rx_tcp_checksum_errs)}, +- {PORTSTAT_INFO(rx_udp_checksum_errs)}, +- {PORTSTAT_INFO(rx_non_rss_packets)}, +- {PORTSTAT_INFO(rx_ipv4_packets)}, +- {PORTSTAT_INFO(rx_ipv6_packets)}, +- {PORTSTAT_INFO(tx_unicastframes)}, +- {PORTSTAT_INFO(tx_multicastframes)}, +- {PORTSTAT_INFO(tx_broadcastframes)}, +- {PORTSTAT_INFO(tx_pauseframes)}, +- {PORTSTAT_INFO(tx_controlframes)}, +- {MISCSTAT_INFO(rx_drops_no_pbuf)}, +- {MISCSTAT_INFO(rx_drops_no_txpb)}, +- {MISCSTAT_INFO(rx_drops_no_erx_descr)}, +- {MISCSTAT_INFO(rx_drops_no_tpre_descr)}, +- {MISCSTAT_INFO(rx_drops_too_many_frags)}, +- {MISCSTAT_INFO(rx_drops_invalid_ring)}, +- {MISCSTAT_INFO(forwarded_packets)}, +- {MISCSTAT_INFO(rx_drops_mtu)}, +- {ERXSTAT_INFO(rx_drops_no_fragments)}, +-}; +-#define ETHTOOL_STATS_NUM ARRAY_SIZE(et_stats) +- +-static void +-be_get_drvinfo(struct net_device *netdev, struct ethtool_drvinfo *drvinfo) +-{ +- struct be_adapter *adapter = netdev_priv(netdev); +- +- strcpy(drvinfo->driver, DRV_NAME); +- strcpy(drvinfo->version, DRV_VER); +- strncpy(drvinfo->fw_version, adapter->fw_ver, FW_VER_LEN); +- strcpy(drvinfo->bus_info, pci_name(adapter->pdev)); +- drvinfo->testinfo_len = 0; +- drvinfo->regdump_len = 0; +- drvinfo->eedump_len = 0; +-} +- +-static int +-be_get_coalesce(struct net_device *netdev, struct ethtool_coalesce *coalesce) +-{ +- struct be_adapter *adapter = netdev_priv(netdev); +- struct be_eq_obj *rx_eq = &adapter->rx_eq; +- struct be_eq_obj *tx_eq = &adapter->tx_eq; +- +- coalesce->rx_max_coalesced_frames = adapter->max_rx_coal; +- +- coalesce->rx_coalesce_usecs = rx_eq->cur_eqd; +- coalesce->rx_coalesce_usecs_high = rx_eq->max_eqd; +- coalesce->rx_coalesce_usecs_low = rx_eq->min_eqd; +- +- coalesce->tx_coalesce_usecs = tx_eq->cur_eqd; +- coalesce->tx_coalesce_usecs_high = tx_eq->max_eqd; +- coalesce->tx_coalesce_usecs_low = tx_eq->min_eqd; +- +- coalesce->use_adaptive_rx_coalesce = rx_eq->enable_aic; +- coalesce->use_adaptive_tx_coalesce = tx_eq->enable_aic; +- +- return 0; +-} +- +-/* +- * This routine is used to set interrup coalescing delay *as well as* +- * the number of pkts to coalesce for LRO. +- */ +-static int +-be_set_coalesce(struct net_device *netdev, struct ethtool_coalesce *coalesce) +-{ +- struct be_adapter *adapter = netdev_priv(netdev); +- struct be_ctrl_info *ctrl = &adapter->ctrl; +- struct be_eq_obj *rx_eq = &adapter->rx_eq; +- struct be_eq_obj *tx_eq = &adapter->tx_eq; +- u32 tx_max, tx_min, tx_cur; +- u32 rx_max, rx_min, rx_cur; +- int status = 0; +- +- if (coalesce->use_adaptive_tx_coalesce == 1) +- return -EINVAL; +- +- adapter->max_rx_coal = coalesce->rx_max_coalesced_frames; +- if (adapter->max_rx_coal > MAX_SKB_FRAGS) +- adapter->max_rx_coal = MAX_SKB_FRAGS - 1; +- +- /* if AIC is being turned on now, start with an EQD of 0 */ +- if (rx_eq->enable_aic == 0 && +- coalesce->use_adaptive_rx_coalesce == 1) { +- rx_eq->cur_eqd = 0; +- } +- rx_eq->enable_aic = coalesce->use_adaptive_rx_coalesce; +- +- rx_max = coalesce->rx_coalesce_usecs_high; +- rx_min = coalesce->rx_coalesce_usecs_low; +- rx_cur = coalesce->rx_coalesce_usecs; +- +- tx_max = coalesce->tx_coalesce_usecs_high; +- tx_min = coalesce->tx_coalesce_usecs_low; +- tx_cur = coalesce->tx_coalesce_usecs; +- +- if (tx_cur > BE_MAX_EQD) +- tx_cur = BE_MAX_EQD; +- if (tx_eq->cur_eqd != tx_cur) { +- status = be_cmd_modify_eqd(ctrl, tx_eq->q.id, tx_cur); +- if (!status) +- tx_eq->cur_eqd = tx_cur; +- } +- +- if (rx_eq->enable_aic) { +- if (rx_max > BE_MAX_EQD) +- rx_max = BE_MAX_EQD; +- if (rx_min > rx_max) +- rx_min = rx_max; +- rx_eq->max_eqd = rx_max; +- rx_eq->min_eqd = rx_min; +- if (rx_eq->cur_eqd > rx_max) +- rx_eq->cur_eqd = rx_max; +- if (rx_eq->cur_eqd < rx_min) +- rx_eq->cur_eqd = rx_min; +- } else { +- if (rx_cur > BE_MAX_EQD) +- rx_cur = BE_MAX_EQD; +- if (rx_eq->cur_eqd != rx_cur) { +- status = be_cmd_modify_eqd(ctrl, rx_eq->q.id, rx_cur); +- if (!status) +- rx_eq->cur_eqd = rx_cur; +- } +- } +- return 0; +-} +- +-static u32 be_get_rx_csum(struct net_device *netdev) +-{ +- struct be_adapter *adapter = netdev_priv(netdev); +- +- return adapter->rx_csum; +-} +- +-static int be_set_rx_csum(struct net_device *netdev, uint32_t data) +-{ +- struct be_adapter *adapter = netdev_priv(netdev); +- +- if (data) +- adapter->rx_csum = true; +- else +- adapter->rx_csum = false; +- +- return 0; +-} +- +-static void +-be_get_ethtool_stats(struct net_device *netdev, +- struct ethtool_stats *stats, uint64_t *data) +-{ +- struct be_adapter *adapter = netdev_priv(netdev); +- struct be_drvr_stats *drvr_stats = &adapter->stats.drvr_stats; +- struct be_hw_stats *hw_stats = hw_stats_from_cmd(adapter->stats.cmd.va); +- struct be_rxf_stats *rxf_stats = &hw_stats->rxf; +- struct be_port_rxf_stats *port_stats = +- &rxf_stats->port[adapter->port_num]; +- struct net_device_stats *net_stats = &adapter->stats.net_stats; +- struct be_erx_stats *erx_stats = &hw_stats->erx; +- void *p = NULL; +- int i; +- +- for (i = 0; i < ETHTOOL_STATS_NUM; i++) { +- switch (et_stats[i].type) { +- case NETSTAT: +- p = net_stats; +- break; +- case DRVSTAT: +- p = drvr_stats; +- break; +- case PORTSTAT: +- p = port_stats; +- break; +- case MISCSTAT: +- p = rxf_stats; +- break; +- case ERXSTAT: /* Currently only one ERX stat is provided */ +- p = (u32 *)erx_stats + adapter->rx_obj.q.id; +- break; +- } +- +- p = (u8 *)p + et_stats[i].offset; +- data[i] = (et_stats[i].size == sizeof(u64)) ? +- *(u64 *)p: *(u32 *)p; +- } +- +- return; +-} +- +-static void +-be_get_stat_strings(struct net_device *netdev, uint32_t stringset, +- uint8_t *data) +-{ +- int i; +- switch (stringset) { +- case ETH_SS_STATS: +- for (i = 0; i < ETHTOOL_STATS_NUM; i++) { +- memcpy(data, et_stats[i].desc, ETH_GSTRING_LEN); +- data += ETH_GSTRING_LEN; +- } +- break; +- } +-} +- +-static int be_get_stats_count(struct net_device *netdev) +-{ +- return ETHTOOL_STATS_NUM; +-} +- +-static int be_get_settings(struct net_device *netdev, struct ethtool_cmd *ecmd) +-{ +- ecmd->speed = SPEED_10000; +- ecmd->duplex = DUPLEX_FULL; +- ecmd->autoneg = AUTONEG_DISABLE; +- return 0; +-} +- +-static void +-be_get_ringparam(struct net_device *netdev, struct ethtool_ringparam *ring) +-{ +- struct be_adapter *adapter = netdev_priv(netdev); +- +- ring->rx_max_pending = adapter->rx_obj.q.len; +- ring->tx_max_pending = adapter->tx_obj.q.len; +- +- ring->rx_pending = atomic_read(&adapter->rx_obj.q.used); +- ring->tx_pending = atomic_read(&adapter->tx_obj.q.used); +-} +- +-static void +-be_get_pauseparam(struct net_device *netdev, struct ethtool_pauseparam *ecmd) +-{ +- struct be_adapter *adapter = netdev_priv(netdev); +- +- be_cmd_get_flow_control(&adapter->ctrl, &ecmd->tx_pause, +- &ecmd->rx_pause); +- ecmd->autoneg = AUTONEG_ENABLE; +-} +- +-static int +-be_set_pauseparam(struct net_device *netdev, struct ethtool_pauseparam *ecmd) +-{ +- struct be_adapter *adapter = netdev_priv(netdev); +- int status; +- +- if (ecmd->autoneg != AUTONEG_ENABLE) +- return -EINVAL; +- +- status = be_cmd_set_flow_control(&adapter->ctrl, ecmd->tx_pause, +- ecmd->rx_pause); +- if (!status) +- dev_warn(&adapter->pdev->dev, "Pause param set failed.\n"); +- +- return status; +-} +- +-struct ethtool_ops be_ethtool_ops = { +- .get_settings = be_get_settings, +- .get_drvinfo = be_get_drvinfo, +- .get_link = ethtool_op_get_link, +- .get_coalesce = be_get_coalesce, +- .set_coalesce = be_set_coalesce, +- .get_ringparam = be_get_ringparam, +- .get_pauseparam = be_get_pauseparam, +- .set_pauseparam = be_set_pauseparam, +- .get_rx_csum = be_get_rx_csum, +- .set_rx_csum = be_set_rx_csum, +- .get_tx_csum = ethtool_op_get_tx_csum, +- .set_tx_csum = ethtool_op_set_tx_csum, +- .get_sg = ethtool_op_get_sg, +- .set_sg = ethtool_op_set_sg, +- .get_tso = ethtool_op_get_tso, +- .set_tso = ethtool_op_set_tso, +- .get_strings = be_get_stat_strings, +- .get_stats_count = be_get_stats_count, +- .get_ethtool_stats = be_get_ethtool_stats, +-}; +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/drivers/net/benet/be.h linux-2.6.29-rc3.owrt/drivers/net/benet/be.h +--- linux-2.6.29.owrt/drivers/net/benet/be.h 2009-05-10 22:04:38.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/drivers/net/benet/be.h 1970-01-01 01:00:00.000000000 +0100 +@@ -1,328 +0,0 @@ +-/* +- * Copyright (C) 2005 - 2009 ServerEngines +- * All rights reserved. +- * +- * 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. The full GNU General +- * Public License is included in this distribution in the file called COPYING. +- * +- * Contact Information: +- * linux-drivers@serverengines.com +- * +- * ServerEngines +- * 209 N. Fair Oaks Ave +- * Sunnyvale, CA 94085 +- */ +- +-#ifndef BE_H +-#define BE_H +- +-#include <linux/pci.h> +-#include <linux/etherdevice.h> +-#include <linux/version.h> +-#include <linux/delay.h> +-#include <net/tcp.h> +-#include <net/ip.h> +-#include <net/ipv6.h> +-#include <linux/if_vlan.h> +-#include <linux/workqueue.h> +-#include <linux/interrupt.h> +-#include <linux/inet_lro.h> +- +-#include "be_hw.h" +- +-#define DRV_VER "2.0.348" +-#define DRV_NAME "be2net" +-#define BE_NAME "ServerEngines BladeEngine2 10Gbps NIC" +-#define DRV_DESC BE_NAME "Driver" +- +-/* Number of bytes of an RX frame that are copied to skb->data */ +-#define BE_HDR_LEN 64 +-#define BE_MAX_JUMBO_FRAME_SIZE 9018 +-#define BE_MIN_MTU 256 +- +-#define BE_NUM_VLANS_SUPPORTED 64 +-#define BE_MAX_EQD 96 +-#define BE_MAX_TX_FRAG_COUNT 30 +- +-#define EVNT_Q_LEN 1024 +-#define TX_Q_LEN 2048 +-#define TX_CQ_LEN 1024 +-#define RX_Q_LEN 1024 /* Does not support any other value */ +-#define RX_CQ_LEN 1024 +-#define MCC_Q_LEN 64 /* total size not to exceed 8 pages */ +-#define MCC_CQ_LEN 256 +- +-#define BE_NAPI_WEIGHT 64 +-#define MAX_RX_POST BE_NAPI_WEIGHT /* Frags posted at a time */ +-#define RX_FRAGS_REFILL_WM (RX_Q_LEN - MAX_RX_POST) +- +-#define BE_MAX_LRO_DESCRIPTORS 16 +-#define BE_MAX_FRAGS_PER_FRAME 16 +- +-struct be_dma_mem { +- void *va; +- dma_addr_t dma; +- u32 size; +-}; +- +-struct be_queue_info { +- struct be_dma_mem dma_mem; +- u16 len; +- u16 entry_size; /* Size of an element in the queue */ +- u16 id; +- u16 tail, head; +- bool created; +- atomic_t used; /* Number of valid elements in the queue */ +-}; +- +-struct be_ctrl_info { +- u8 __iomem *csr; +- u8 __iomem *db; /* Door Bell */ +- u8 __iomem *pcicfg; /* PCI config space */ +- int pci_func; +- +- /* Mbox used for cmd request/response */ +- spinlock_t cmd_lock; /* For serializing cmds to BE card */ +- struct be_dma_mem mbox_mem; +- /* Mbox mem is adjusted to align to 16 bytes. The allocated addr +- * is stored for freeing purpose */ +- struct be_dma_mem mbox_mem_alloced; +-}; +- +-#include "be_cmds.h" +- +-struct be_drvr_stats { +- u32 be_tx_reqs; /* number of TX requests initiated */ +- u32 be_tx_stops; /* number of times TX Q was stopped */ +- u32 be_fwd_reqs; /* number of send reqs through forwarding i/f */ +- u32 be_tx_wrbs; /* number of tx WRBs used */ +- u32 be_tx_events; /* number of tx completion events */ +- u32 be_tx_compl; /* number of tx completion entries processed */ +- u64 be_tx_jiffies; +- ulong be_tx_bytes; +- ulong be_tx_bytes_prev; +- u32 be_tx_rate; +- +- u32 cache_barrier[16]; +- +- u32 be_ethrx_post_fail;/* number of ethrx buffer alloc failures */ +- u32 be_polls; /* number of times NAPI called poll function */ +- u32 be_rx_events; /* number of ucast rx completion events */ +- u32 be_rx_compl; /* number of rx completion entries processed */ +- u32 be_lro_hgram_data[8]; /* histogram of LRO data packets */ +- u32 be_lro_hgram_ack[8]; /* histogram of LRO ACKs */ +- u64 be_rx_jiffies; +- ulong be_rx_bytes; +- ulong be_rx_bytes_prev; +- u32 be_rx_rate; +- /* number of non ether type II frames dropped where +- * frame len > length field of Mac Hdr */ +- u32 be_802_3_dropped_frames; +- /* number of non ether type II frames malformed where +- * in frame len < length field of Mac Hdr */ +- u32 be_802_3_malformed_frames; +- u32 be_rxcp_err; /* Num rx completion entries w/ err set. */ +- ulong rx_fps_jiffies; /* jiffies at last FPS calc */ +- u32 be_rx_frags; +- u32 be_prev_rx_frags; +- u32 be_rx_fps; /* Rx frags per second */ +-}; +- +-struct be_stats_obj { +- struct be_drvr_stats drvr_stats; +- struct net_device_stats net_stats; +- struct be_dma_mem cmd; +-}; +- +-struct be_eq_obj { +- struct be_queue_info q; +- char desc[32]; +- +- /* Adaptive interrupt coalescing (AIC) info */ +- bool enable_aic; +- u16 min_eqd; /* in usecs */ +- u16 max_eqd; /* in usecs */ +- u16 cur_eqd; /* in usecs */ +- +- struct napi_struct napi; +-}; +- +-struct be_tx_obj { +- struct be_queue_info q; +- struct be_queue_info cq; +- /* Remember the skbs that were transmitted */ +- struct sk_buff *sent_skb_list[TX_Q_LEN]; +-}; +- +-/* Struct to remember the pages posted for rx frags */ +-struct be_rx_page_info { +- struct page *page; +- dma_addr_t bus; +- u16 page_offset; +- bool last_page_user; +-}; +- +-struct be_rx_obj { +- struct be_queue_info q; +- struct be_queue_info cq; +- struct be_rx_page_info page_info_tbl[RX_Q_LEN]; +- struct net_lro_mgr lro_mgr; +- struct net_lro_desc lro_desc[BE_MAX_LRO_DESCRIPTORS]; +-}; +- +-#define BE_NUM_MSIX_VECTORS 2 /* 1 each for Tx and Rx */ +-struct be_adapter { +- struct pci_dev *pdev; +- struct net_device *netdev; +- +- /* Mbox, pci config, csr address information */ +- struct be_ctrl_info ctrl; +- +- struct msix_entry msix_entries[BE_NUM_MSIX_VECTORS]; +- bool msix_enabled; +- bool isr_registered; +- +- /* TX Rings */ +- struct be_eq_obj tx_eq; +- struct be_tx_obj tx_obj; +- +- u32 cache_line_break[8]; +- +- /* Rx rings */ +- struct be_eq_obj rx_eq; +- struct be_rx_obj rx_obj; +- u32 big_page_size; /* Compounded page size shared by rx wrbs */ +- bool rx_post_starved; /* Zero rx frags have been posted to BE */ +- +- struct vlan_group *vlan_grp; +- u16 num_vlans; +- u8 vlan_tag[VLAN_GROUP_ARRAY_LEN]; +- +- struct be_stats_obj stats; +- /* Work queue used to perform periodic tasks like getting statistics */ +- struct delayed_work work; +- +- /* Ethtool knobs and info */ +- bool rx_csum; /* BE card must perform rx-checksumming */ +- u32 max_rx_coal; +- char fw_ver[FW_VER_LEN]; +- u32 if_handle; /* Used to configure filtering */ +- u32 pmac_id; /* MAC addr handle used by BE card */ +- +- struct be_link_info link; +- u32 port_num; +-}; +- +-extern struct ethtool_ops be_ethtool_ops; +- +-#define drvr_stats(adapter) (&adapter->stats.drvr_stats) +- +-#define BE_SET_NETDEV_OPS(netdev, ops) (netdev->netdev_ops = ops) +- +-static inline u32 MODULO(u16 val, u16 limit) +-{ +- BUG_ON(limit & (limit - 1)); +- return val & (limit - 1); +-} +- +-static inline void index_adv(u16 *index, u16 val, u16 limit) +-{ +- *index = MODULO((*index + val), limit); +-} +- +-static inline void index_inc(u16 *index, u16 limit) +-{ +- *index = MODULO((*index + 1), limit); +-} +- +-#define PAGE_SHIFT_4K 12 +-#define PAGE_SIZE_4K (1 << PAGE_SHIFT_4K) +- +-/* Returns number of pages spanned by the data starting at the given addr */ +-#define PAGES_4K_SPANNED(_address, size) \ +- ((u32)((((size_t)(_address) & (PAGE_SIZE_4K - 1)) + \ +- (size) + (PAGE_SIZE_4K - 1)) >> PAGE_SHIFT_4K)) +- +-/* Byte offset into the page corresponding to given address */ +-#define OFFSET_IN_PAGE(addr) \ +- ((size_t)(addr) & (PAGE_SIZE_4K-1)) +- +-/* Returns bit offset within a DWORD of a bitfield */ +-#define AMAP_BIT_OFFSET(_struct, field) \ +- (((size_t)&(((_struct *)0)->field))%32) +- +-/* Returns the bit mask of the field that is NOT shifted into location. */ +-static inline u32 amap_mask(u32 bitsize) +-{ +- return (bitsize == 32 ? 0xFFFFFFFF : (1 << bitsize) - 1); +-} +- +-static inline void +-amap_set(void *ptr, u32 dw_offset, u32 mask, u32 offset, u32 value) +-{ +- u32 *dw = (u32 *) ptr + dw_offset; +- *dw &= ~(mask << offset); +- *dw |= (mask & value) << offset; +-} +- +-#define AMAP_SET_BITS(_struct, field, ptr, val) \ +- amap_set(ptr, \ +- offsetof(_struct, field)/32, \ +- amap_mask(sizeof(((_struct *)0)->field)), \ +- AMAP_BIT_OFFSET(_struct, field), \ +- val) +- +-static inline u32 amap_get(void *ptr, u32 dw_offset, u32 mask, u32 offset) +-{ +- u32 *dw = (u32 *) ptr; +- return mask & (*(dw + dw_offset) >> offset); +-} +- +-#define AMAP_GET_BITS(_struct, field, ptr) \ +- amap_get(ptr, \ +- offsetof(_struct, field)/32, \ +- amap_mask(sizeof(((_struct *)0)->field)), \ +- AMAP_BIT_OFFSET(_struct, field)) +- +-#define be_dws_cpu_to_le(wrb, len) swap_dws(wrb, len) +-#define be_dws_le_to_cpu(wrb, len) swap_dws(wrb, len) +-static inline void swap_dws(void *wrb, int len) +-{ +-#ifdef __BIG_ENDIAN +- u32 *dw = wrb; +- BUG_ON(len % 4); +- do { +- *dw = cpu_to_le32(*dw); +- dw++; +- len -= 4; +- } while (len); +-#endif /* __BIG_ENDIAN */ +-} +- +-static inline u8 is_tcp_pkt(struct sk_buff *skb) +-{ +- u8 val = 0; +- +- if (ip_hdr(skb)->version == 4) +- val = (ip_hdr(skb)->protocol == IPPROTO_TCP); +- else if (ip_hdr(skb)->version == 6) +- val = (ipv6_hdr(skb)->nexthdr == NEXTHDR_TCP); +- +- return val; +-} +- +-static inline u8 is_udp_pkt(struct sk_buff *skb) +-{ +- u8 val = 0; +- +- if (ip_hdr(skb)->version == 4) +- val = (ip_hdr(skb)->protocol == IPPROTO_UDP); +- else if (ip_hdr(skb)->version == 6) +- val = (ipv6_hdr(skb)->nexthdr == NEXTHDR_UDP); +- +- return val; +-} +- +-#endif /* BE_H */ +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/drivers/net/benet/be_hw.h linux-2.6.29-rc3.owrt/drivers/net/benet/be_hw.h +--- linux-2.6.29.owrt/drivers/net/benet/be_hw.h 2009-05-10 22:04:38.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/drivers/net/benet/be_hw.h 1970-01-01 01:00:00.000000000 +0100 +@@ -1,211 +0,0 @@ +-/* +- * Copyright (C) 2005 - 2009 ServerEngines +- * All rights reserved. +- * +- * 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. The full GNU General +- * Public License is included in this distribution in the file called COPYING. +- * +- * Contact Information: +- * linux-drivers@serverengines.com +- * +- * ServerEngines +- * 209 N. Fair Oaks Ave +- * Sunnyvale, CA 94085 +- */ +- +-/********* Mailbox door bell *************/ +-/* Used for driver communication with the FW. +- * The software must write this register twice to post any command. First, +- * it writes the register with hi=1 and the upper bits of the physical address +- * for the MAILBOX structure. Software must poll the ready bit until this +- * is acknowledged. Then, sotware writes the register with hi=0 with the lower +- * bits in the address. It must poll the ready bit until the command is +- * complete. Upon completion, the MAILBOX will contain a valid completion +- * queue entry. +- */ +-#define MPU_MAILBOX_DB_OFFSET 0x160 +-#define MPU_MAILBOX_DB_RDY_MASK 0x1 /* bit 0 */ +-#define MPU_MAILBOX_DB_HI_MASK 0x2 /* bit 1 */ +- +-#define MPU_EP_CONTROL 0 +- +-/********** MPU semphore ******************/ +-#define MPU_EP_SEMAPHORE_OFFSET 0xac +-#define EP_SEMAPHORE_POST_STAGE_MASK 0x0000FFFF +-#define EP_SEMAPHORE_POST_ERR_MASK 0x1 +-#define EP_SEMAPHORE_POST_ERR_SHIFT 31 +-/* MPU semphore POST stage values */ +-#define POST_STAGE_AWAITING_HOST_RDY 0x1 /* FW awaiting goahead from host */ +-#define POST_STAGE_HOST_RDY 0x2 /* Host has given go-ahed to FW */ +-#define POST_STAGE_BE_RESET 0x3 /* Host wants to reset chip */ +-#define POST_STAGE_ARMFW_RDY 0xc000 /* FW is done with POST */ +- +-/********* Memory BAR register ************/ +-#define PCICFG_MEMBAR_CTRL_INT_CTRL_OFFSET 0xfc +-/* Host Interrupt Enable, if set interrupts are enabled although "PCI Interrupt +- * Disable" may still globally block interrupts in addition to individual +- * interrupt masks; a mechanism for the device driver to block all interrupts +- * atomically without having to arbitrate for the PCI Interrupt Disable bit +- * with the OS. +- */ +-#define MEMBAR_CTRL_INT_CTRL_HOSTINTR_MASK (1 << 29) /* bit 29 */ +-/* PCI physical function number */ +-#define MEMBAR_CTRL_INT_CTRL_PFUNC_MASK 0x7 /* bits 26 - 28 */ +-#define MEMBAR_CTRL_INT_CTRL_PFUNC_SHIFT 26 +- +-/********* Event Q door bell *************/ +-#define DB_EQ_OFFSET DB_CQ_OFFSET +-#define DB_EQ_RING_ID_MASK 0x1FF /* bits 0 - 8 */ +-/* Clear the interrupt for this eq */ +-#define DB_EQ_CLR_SHIFT (9) /* bit 9 */ +-/* Must be 1 */ +-#define DB_EQ_EVNT_SHIFT (10) /* bit 10 */ +-/* Number of event entries processed */ +-#define DB_EQ_NUM_POPPED_SHIFT (16) /* bits 16 - 28 */ +-/* Rearm bit */ +-#define DB_EQ_REARM_SHIFT (29) /* bit 29 */ +- +-/********* Compl Q door bell *************/ +-#define DB_CQ_OFFSET 0x120 +-#define DB_CQ_RING_ID_MASK 0x3FF /* bits 0 - 9 */ +-/* Number of event entries processed */ +-#define DB_CQ_NUM_POPPED_SHIFT (16) /* bits 16 - 28 */ +-/* Rearm bit */ +-#define DB_CQ_REARM_SHIFT (29) /* bit 29 */ +- +-/********** TX ULP door bell *************/ +-#define DB_TXULP1_OFFSET 0x60 +-#define DB_TXULP_RING_ID_MASK 0x7FF /* bits 0 - 10 */ +-/* Number of tx entries posted */ +-#define DB_TXULP_NUM_POSTED_SHIFT (16) /* bits 16 - 29 */ +-#define DB_TXULP_NUM_POSTED_MASK 0x3FFF /* bits 16 - 29 */ +- +-/********** RQ(erx) door bell ************/ +-#define DB_RQ_OFFSET 0x100 +-#define DB_RQ_RING_ID_MASK 0x3FF /* bits 0 - 9 */ +-/* Number of rx frags posted */ +-#define DB_RQ_NUM_POSTED_SHIFT (24) /* bits 24 - 31 */ +- +-/* +- * BE descriptors: host memory data structures whose formats +- * are hardwired in BE silicon. +- */ +-/* Event Queue Descriptor */ +-#define EQ_ENTRY_VALID_MASK 0x1 /* bit 0 */ +-#define EQ_ENTRY_RES_ID_MASK 0xFFFF /* bits 16 - 31 */ +-#define EQ_ENTRY_RES_ID_SHIFT 16 +-struct be_eq_entry { +- u32 evt; +-}; +- +-/* TX Queue Descriptor */ +-#define ETH_WRB_FRAG_LEN_MASK 0xFFFF +-struct be_eth_wrb { +- u32 frag_pa_hi; /* dword 0 */ +- u32 frag_pa_lo; /* dword 1 */ +- u32 rsvd0; /* dword 2 */ +- u32 frag_len; /* dword 3: bits 0 - 15 */ +-} __packed; +- +-/* Pseudo amap definition for eth_hdr_wrb in which each bit of the +- * actual structure is defined as a byte : used to calculate +- * offset/shift/mask of each field */ +-struct amap_eth_hdr_wrb { +- u8 rsvd0[32]; /* dword 0 */ +- u8 rsvd1[32]; /* dword 1 */ +- u8 complete; /* dword 2 */ +- u8 event; +- u8 crc; +- u8 forward; +- u8 ipsec; +- u8 mgmt; +- u8 ipcs; +- u8 udpcs; +- u8 tcpcs; +- u8 lso; +- u8 vlan; +- u8 gso[2]; +- u8 num_wrb[5]; +- u8 lso_mss[14]; +- u8 len[16]; /* dword 3 */ +- u8 vlan_tag[16]; +-} __packed; +- +-struct be_eth_hdr_wrb { +- u32 dw[4]; +-}; +- +-/* TX Compl Queue Descriptor */ +- +-/* Pseudo amap definition for eth_tx_compl in which each bit of the +- * actual structure is defined as a byte: used to calculate +- * offset/shift/mask of each field */ +-struct amap_eth_tx_compl { +- u8 wrb_index[16]; /* dword 0 */ +- u8 ct[2]; /* dword 0 */ +- u8 port[2]; /* dword 0 */ +- u8 rsvd0[8]; /* dword 0 */ +- u8 status[4]; /* dword 0 */ +- u8 user_bytes[16]; /* dword 1 */ +- u8 nwh_bytes[8]; /* dword 1 */ +- u8 lso; /* dword 1 */ +- u8 cast_enc[2]; /* dword 1 */ +- u8 rsvd1[5]; /* dword 1 */ +- u8 rsvd2[32]; /* dword 2 */ +- u8 pkts[16]; /* dword 3 */ +- u8 ringid[11]; /* dword 3 */ +- u8 hash_val[4]; /* dword 3 */ +- u8 valid; /* dword 3 */ +-} __packed; +- +-struct be_eth_tx_compl { +- u32 dw[4]; +-}; +- +-/* RX Queue Descriptor */ +-struct be_eth_rx_d { +- u32 fragpa_hi; +- u32 fragpa_lo; +-}; +- +-/* RX Compl Queue Descriptor */ +- +-/* Pseudo amap definition for eth_rx_compl in which each bit of the +- * actual structure is defined as a byte: used to calculate +- * offset/shift/mask of each field */ +-struct amap_eth_rx_compl { +- u8 vlan_tag[16]; /* dword 0 */ +- u8 pktsize[14]; /* dword 0 */ +- u8 port; /* dword 0 */ +- u8 ip_opt; /* dword 0 */ +- u8 err; /* dword 1 */ +- u8 rsshp; /* dword 1 */ +- u8 ipf; /* dword 1 */ +- u8 tcpf; /* dword 1 */ +- u8 udpf; /* dword 1 */ +- u8 ipcksm; /* dword 1 */ +- u8 l4_cksm; /* dword 1 */ +- u8 ip_version; /* dword 1 */ +- u8 macdst[6]; /* dword 1 */ +- u8 vtp; /* dword 1 */ +- u8 rsvd0; /* dword 1 */ +- u8 fragndx[10]; /* dword 1 */ +- u8 ct[2]; /* dword 1 */ +- u8 sw; /* dword 1 */ +- u8 numfrags[3]; /* dword 1 */ +- u8 rss_flush; /* dword 2 */ +- u8 cast_enc[2]; /* dword 2 */ +- u8 qnq; /* dword 2 */ +- u8 rss_bank; /* dword 2 */ +- u8 rsvd1[23]; /* dword 2 */ +- u8 lro_pkt; /* dword 2 */ +- u8 rsvd2[2]; /* dword 2 */ +- u8 valid; /* dword 2 */ +- u8 rsshash[32]; /* dword 3 */ +-} __packed; +- +-struct be_eth_rx_compl { +- u32 dw[4]; +-}; +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/drivers/net/benet/be_main.c linux-2.6.29-rc3.owrt/drivers/net/benet/be_main.c +--- linux-2.6.29.owrt/drivers/net/benet/be_main.c 2009-05-10 22:04:38.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/drivers/net/benet/be_main.c 1970-01-01 01:00:00.000000000 +0100 +@@ -1,1911 +0,0 @@ +-/* +- * Copyright (C) 2005 - 2009 ServerEngines +- * All rights reserved. +- * +- * 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. The full GNU General +- * Public License is included in this distribution in the file called COPYING. +- * +- * Contact Information: +- * linux-drivers@serverengines.com +- * +- * ServerEngines +- * 209 N. Fair Oaks Ave +- * Sunnyvale, CA 94085 +- */ +- +-#include "be.h" +- +-MODULE_VERSION(DRV_VER); +-MODULE_DEVICE_TABLE(pci, be_dev_ids); +-MODULE_DESCRIPTION(DRV_DESC " " DRV_VER); +-MODULE_AUTHOR("ServerEngines Corporation"); +-MODULE_LICENSE("GPL"); +- +-static unsigned int rx_frag_size = 2048; +-module_param(rx_frag_size, uint, S_IRUGO); +-MODULE_PARM_DESC(rx_frag_size, "Size of a fragment that holds rcvd data."); +- +-#define BE_VENDOR_ID 0x19a2 +-#define BE2_DEVICE_ID_1 0x0211 +-static DEFINE_PCI_DEVICE_TABLE(be_dev_ids) = { +- { PCI_DEVICE(BE_VENDOR_ID, BE2_DEVICE_ID_1) }, +- { 0 } +-}; +-MODULE_DEVICE_TABLE(pci, be_dev_ids); +- +-static void be_queue_free(struct be_adapter *adapter, struct be_queue_info *q) +-{ +- struct be_dma_mem *mem = &q->dma_mem; +- if (mem->va) +- pci_free_consistent(adapter->pdev, mem->size, +- mem->va, mem->dma); +-} +- +-static int be_queue_alloc(struct be_adapter *adapter, struct be_queue_info *q, +- u16 len, u16 entry_size) +-{ +- struct be_dma_mem *mem = &q->dma_mem; +- +- memset(q, 0, sizeof(*q)); +- q->len = len; +- q->entry_size = entry_size; +- mem->size = len * entry_size; +- mem->va = pci_alloc_consistent(adapter->pdev, mem->size, &mem->dma); +- if (!mem->va) +- return -1; +- memset(mem->va, 0, mem->size); +- return 0; +-} +- +-static inline void *queue_head_node(struct be_queue_info *q) +-{ +- return q->dma_mem.va + q->head * q->entry_size; +-} +- +-static inline void *queue_tail_node(struct be_queue_info *q) +-{ +- return q->dma_mem.va + q->tail * q->entry_size; +-} +- +-static inline void queue_head_inc(struct be_queue_info *q) +-{ +- index_inc(&q->head, q->len); +-} +- +-static inline void queue_tail_inc(struct be_queue_info *q) +-{ +- index_inc(&q->tail, q->len); +-} +- +-static void be_intr_set(struct be_ctrl_info *ctrl, bool enable) +-{ +- u8 __iomem *addr = ctrl->pcicfg + PCICFG_MEMBAR_CTRL_INT_CTRL_OFFSET; +- u32 reg = ioread32(addr); +- u32 enabled = reg & MEMBAR_CTRL_INT_CTRL_HOSTINTR_MASK; +- if (!enabled && enable) { +- reg |= MEMBAR_CTRL_INT_CTRL_HOSTINTR_MASK; +- } else if (enabled && !enable) { +- reg &= ~MEMBAR_CTRL_INT_CTRL_HOSTINTR_MASK; +- } else { +- printk(KERN_WARNING DRV_NAME +- ": bad value in membar_int_ctrl reg=0x%x\n", reg); +- return; +- } +- iowrite32(reg, addr); +-} +- +-static void be_rxq_notify(struct be_ctrl_info *ctrl, u16 qid, u16 posted) +-{ +- u32 val = 0; +- val |= qid & DB_RQ_RING_ID_MASK; +- val |= posted << DB_RQ_NUM_POSTED_SHIFT; +- iowrite32(val, ctrl->db + DB_RQ_OFFSET); +-} +- +-static void be_txq_notify(struct be_ctrl_info *ctrl, u16 qid, u16 posted) +-{ +- u32 val = 0; +- val |= qid & DB_TXULP_RING_ID_MASK; +- val |= (posted & DB_TXULP_NUM_POSTED_MASK) << DB_TXULP_NUM_POSTED_SHIFT; +- iowrite32(val, ctrl->db + DB_TXULP1_OFFSET); +-} +- +-static void be_eq_notify(struct be_ctrl_info *ctrl, u16 qid, +- bool arm, bool clear_int, u16 num_popped) +-{ +- u32 val = 0; +- val |= qid & DB_EQ_RING_ID_MASK; +- if (arm) +- val |= 1 << DB_EQ_REARM_SHIFT; +- if (clear_int) +- val |= 1 << DB_EQ_CLR_SHIFT; +- val |= 1 << DB_EQ_EVNT_SHIFT; +- val |= num_popped << DB_EQ_NUM_POPPED_SHIFT; +- iowrite32(val, ctrl->db + DB_EQ_OFFSET); +-} +- +-static void be_cq_notify(struct be_ctrl_info *ctrl, u16 qid, +- bool arm, u16 num_popped) +-{ +- u32 val = 0; +- val |= qid & DB_CQ_RING_ID_MASK; +- if (arm) +- val |= 1 << DB_CQ_REARM_SHIFT; +- val |= num_popped << DB_CQ_NUM_POPPED_SHIFT; +- iowrite32(val, ctrl->db + DB_CQ_OFFSET); +-} +- +- +-static int be_mac_addr_set(struct net_device *netdev, void *p) +-{ +- struct be_adapter *adapter = netdev_priv(netdev); +- struct sockaddr *addr = p; +- int status = 0; +- +- if (netif_running(netdev)) { +- status = be_cmd_pmac_del(&adapter->ctrl, adapter->if_handle, +- adapter->pmac_id); +- if (status) +- return status; +- +- status = be_cmd_pmac_add(&adapter->ctrl, (u8 *)addr->sa_data, +- adapter->if_handle, &adapter->pmac_id); +- } +- +- if (!status) +- memcpy(netdev->dev_addr, addr->sa_data, netdev->addr_len); +- +- return status; +-} +- +-static void netdev_stats_update(struct be_adapter *adapter) +-{ +- struct be_hw_stats *hw_stats = hw_stats_from_cmd(adapter->stats.cmd.va); +- struct be_rxf_stats *rxf_stats = &hw_stats->rxf; +- struct be_port_rxf_stats *port_stats = +- &rxf_stats->port[adapter->port_num]; +- struct net_device_stats *dev_stats = &adapter->stats.net_stats; +- +- dev_stats->rx_packets = port_stats->rx_total_frames; +- dev_stats->tx_packets = port_stats->tx_unicastframes + +- port_stats->tx_multicastframes + port_stats->tx_broadcastframes; +- dev_stats->rx_bytes = (u64) port_stats->rx_bytes_msd << 32 | +- (u64) port_stats->rx_bytes_lsd; +- dev_stats->tx_bytes = (u64) port_stats->tx_bytes_msd << 32 | +- (u64) port_stats->tx_bytes_lsd; +- +- /* bad pkts received */ +- dev_stats->rx_errors = port_stats->rx_crc_errors + +- port_stats->rx_alignment_symbol_errors + +- port_stats->rx_in_range_errors + +- port_stats->rx_out_range_errors + port_stats->rx_frame_too_long; +- +- /* packet transmit problems */ +- dev_stats->tx_errors = 0; +- +- /* no space in linux buffers */ +- dev_stats->rx_dropped = 0; +- +- /* no space available in linux */ +- dev_stats->tx_dropped = 0; +- +- dev_stats->multicast = port_stats->tx_multicastframes; +- dev_stats->collisions = 0; +- +- /* detailed rx errors */ +- dev_stats->rx_length_errors = port_stats->rx_in_range_errors + +- port_stats->rx_out_range_errors + port_stats->rx_frame_too_long; +- /* receive ring buffer overflow */ +- dev_stats->rx_over_errors = 0; +- dev_stats->rx_crc_errors = port_stats->rx_crc_errors; +- +- /* frame alignment errors */ +- dev_stats->rx_frame_errors = port_stats->rx_alignment_symbol_errors; +- /* receiver fifo overrun */ +- /* drops_no_pbuf is no per i/f, it's per BE card */ +- dev_stats->rx_fifo_errors = port_stats->rx_fifo_overflow + +- port_stats->rx_input_fifo_overflow + +- rxf_stats->rx_drops_no_pbuf; +- /* receiver missed packetd */ +- dev_stats->rx_missed_errors = 0; +- /* detailed tx_errors */ +- dev_stats->tx_aborted_errors = 0; +- dev_stats->tx_carrier_errors = 0; +- dev_stats->tx_fifo_errors = 0; +- dev_stats->tx_heartbeat_errors = 0; +- dev_stats->tx_window_errors = 0; +-} +- +-static void be_link_status_update(struct be_adapter *adapter) +-{ +- struct be_link_info *prev = &adapter->link; +- struct be_link_info now = { 0 }; +- struct net_device *netdev = adapter->netdev; +- +- be_cmd_link_status_query(&adapter->ctrl, &now); +- +- /* If link came up or went down */ +- if (now.speed != prev->speed && (now.speed == PHY_LINK_SPEED_ZERO || +- prev->speed == PHY_LINK_SPEED_ZERO)) { +- if (now.speed == PHY_LINK_SPEED_ZERO) { +- netif_stop_queue(netdev); +- netif_carrier_off(netdev); +- printk(KERN_INFO "%s: Link down\n", netdev->name); +- } else { +- netif_start_queue(netdev); +- netif_carrier_on(netdev); +- printk(KERN_INFO "%s: Link up\n", netdev->name); +- } +- } +- *prev = now; +-} +- +-/* Update the EQ delay n BE based on the RX frags consumed / sec */ +-static void be_rx_eqd_update(struct be_adapter *adapter) +-{ +- u32 eqd; +- struct be_ctrl_info *ctrl = &adapter->ctrl; +- struct be_eq_obj *rx_eq = &adapter->rx_eq; +- struct be_drvr_stats *stats = &adapter->stats.drvr_stats; +- +- /* Update once a second */ +- if (((jiffies - stats->rx_fps_jiffies) < HZ) || rx_eq->enable_aic == 0) +- return; +- +- stats->be_rx_fps = (stats->be_rx_frags - stats->be_prev_rx_frags) / +- ((jiffies - stats->rx_fps_jiffies) / HZ); +- +- stats->rx_fps_jiffies = jiffies; +- stats->be_prev_rx_frags = stats->be_rx_frags; +- eqd = stats->be_rx_fps / 110000; +- eqd = eqd << 3; +- if (eqd > rx_eq->max_eqd) +- eqd = rx_eq->max_eqd; +- if (eqd < rx_eq->min_eqd) +- eqd = rx_eq->min_eqd; +- if (eqd < 10) +- eqd = 0; +- if (eqd != rx_eq->cur_eqd) +- be_cmd_modify_eqd(ctrl, rx_eq->q.id, eqd); +- +- rx_eq->cur_eqd = eqd; +-} +- +-static struct net_device_stats *be_get_stats(struct net_device *dev) +-{ +- struct be_adapter *adapter = netdev_priv(dev); +- +- return &adapter->stats.net_stats; +-} +- +-static void be_tx_stats_update(struct be_adapter *adapter, +- u32 wrb_cnt, u32 copied, bool stopped) +-{ +- struct be_drvr_stats *stats = &adapter->stats.drvr_stats; +- stats->be_tx_reqs++; +- stats->be_tx_wrbs += wrb_cnt; +- stats->be_tx_bytes += copied; +- if (stopped) +- stats->be_tx_stops++; +- +- /* Update tx rate once in two seconds */ +- if ((jiffies - stats->be_tx_jiffies) > 2 * HZ) { +- u32 r; +- r = (stats->be_tx_bytes - stats->be_tx_bytes_prev) / +- ((u32) (jiffies - stats->be_tx_jiffies) / HZ); +- r = (r / 1000000); /* M bytes/s */ +- stats->be_tx_rate = (r * 8); /* M bits/s */ +- stats->be_tx_jiffies = jiffies; +- stats->be_tx_bytes_prev = stats->be_tx_bytes; +- } +-} +- +-/* Determine number of WRB entries needed to xmit data in an skb */ +-static u32 wrb_cnt_for_skb(struct sk_buff *skb, bool *dummy) +-{ +- int cnt = 0; +- while (skb) { +- if (skb->len > skb->data_len) +- cnt++; +- cnt += skb_shinfo(skb)->nr_frags; +- skb = skb_shinfo(skb)->frag_list; +- } +- /* to account for hdr wrb */ +- cnt++; +- if (cnt & 1) { +- /* add a dummy to make it an even num */ +- cnt++; +- *dummy = true; +- } else +- *dummy = false; +- BUG_ON(cnt > BE_MAX_TX_FRAG_COUNT); +- return cnt; +-} +- +-static inline void wrb_fill(struct be_eth_wrb *wrb, u64 addr, int len) +-{ +- wrb->frag_pa_hi = upper_32_bits(addr); +- wrb->frag_pa_lo = addr & 0xFFFFFFFF; +- wrb->frag_len = len & ETH_WRB_FRAG_LEN_MASK; +-} +- +-static void wrb_fill_hdr(struct be_eth_hdr_wrb *hdr, struct sk_buff *skb, +- bool vlan, u32 wrb_cnt, u32 len) +-{ +- memset(hdr, 0, sizeof(*hdr)); +- +- AMAP_SET_BITS(struct amap_eth_hdr_wrb, crc, hdr, 1); +- +- if (skb_shinfo(skb)->gso_segs > 1 && skb_shinfo(skb)->gso_size) { +- AMAP_SET_BITS(struct amap_eth_hdr_wrb, lso, hdr, 1); +- AMAP_SET_BITS(struct amap_eth_hdr_wrb, lso_mss, +- hdr, skb_shinfo(skb)->gso_size); +- } else if (skb->ip_summed == CHECKSUM_PARTIAL) { +- if (is_tcp_pkt(skb)) +- AMAP_SET_BITS(struct amap_eth_hdr_wrb, tcpcs, hdr, 1); +- else if (is_udp_pkt(skb)) +- AMAP_SET_BITS(struct amap_eth_hdr_wrb, udpcs, hdr, 1); +- } +- +- if (vlan && vlan_tx_tag_present(skb)) { +- AMAP_SET_BITS(struct amap_eth_hdr_wrb, vlan, hdr, 1); +- AMAP_SET_BITS(struct amap_eth_hdr_wrb, vlan_tag, +- hdr, vlan_tx_tag_get(skb)); +- } +- +- AMAP_SET_BITS(struct amap_eth_hdr_wrb, event, hdr, 1); +- AMAP_SET_BITS(struct amap_eth_hdr_wrb, complete, hdr, 1); +- AMAP_SET_BITS(struct amap_eth_hdr_wrb, num_wrb, hdr, wrb_cnt); +- AMAP_SET_BITS(struct amap_eth_hdr_wrb, len, hdr, len); +-} +- +- +-static int make_tx_wrbs(struct be_adapter *adapter, +- struct sk_buff *skb, u32 wrb_cnt, bool dummy_wrb) +-{ +- u64 busaddr; +- u32 i, copied = 0; +- struct pci_dev *pdev = adapter->pdev; +- struct sk_buff *first_skb = skb; +- struct be_queue_info *txq = &adapter->tx_obj.q; +- struct be_eth_wrb *wrb; +- struct be_eth_hdr_wrb *hdr; +- +- atomic_add(wrb_cnt, &txq->used); +- hdr = queue_head_node(txq); +- queue_head_inc(txq); +- +- while (skb) { +- if (skb->len > skb->data_len) { +- int len = skb->len - skb->data_len; +- busaddr = pci_map_single(pdev, skb->data, len, +- PCI_DMA_TODEVICE); +- wrb = queue_head_node(txq); +- wrb_fill(wrb, busaddr, len); +- be_dws_cpu_to_le(wrb, sizeof(*wrb)); +- queue_head_inc(txq); +- copied += len; +- } +- +- for (i = 0; i < skb_shinfo(skb)->nr_frags; i++) { +- struct skb_frag_struct *frag = +- &skb_shinfo(skb)->frags[i]; +- busaddr = pci_map_page(pdev, frag->page, +- frag->page_offset, +- frag->size, PCI_DMA_TODEVICE); +- wrb = queue_head_node(txq); +- wrb_fill(wrb, busaddr, frag->size); +- be_dws_cpu_to_le(wrb, sizeof(*wrb)); +- queue_head_inc(txq); +- copied += frag->size; +- } +- skb = skb_shinfo(skb)->frag_list; +- } +- +- if (dummy_wrb) { +- wrb = queue_head_node(txq); +- wrb_fill(wrb, 0, 0); +- be_dws_cpu_to_le(wrb, sizeof(*wrb)); +- queue_head_inc(txq); +- } +- +- wrb_fill_hdr(hdr, first_skb, adapter->vlan_grp ? true : false, +- wrb_cnt, copied); +- be_dws_cpu_to_le(hdr, sizeof(*hdr)); +- +- return copied; +-} +- +-static int be_xmit(struct sk_buff *skb, struct net_device *netdev) +-{ +- struct be_adapter *adapter = netdev_priv(netdev); +- struct be_tx_obj *tx_obj = &adapter->tx_obj; +- struct be_queue_info *txq = &tx_obj->q; +- u32 wrb_cnt = 0, copied = 0; +- u32 start = txq->head; +- bool dummy_wrb, stopped = false; +- +- wrb_cnt = wrb_cnt_for_skb(skb, &dummy_wrb); +- +- copied = make_tx_wrbs(adapter, skb, wrb_cnt, dummy_wrb); +- +- /* record the sent skb in the sent_skb table */ +- BUG_ON(tx_obj->sent_skb_list[start]); +- tx_obj->sent_skb_list[start] = skb; +- +- /* Ensure that txq has space for the next skb; Else stop the queue +- * *BEFORE* ringing the tx doorbell, so that we serialze the +- * tx compls of the current transmit which'll wake up the queue +- */ +- if ((BE_MAX_TX_FRAG_COUNT + atomic_read(&txq->used)) >= txq->len) { +- netif_stop_queue(netdev); +- stopped = true; +- } +- +- be_txq_notify(&adapter->ctrl, txq->id, wrb_cnt); +- +- netdev->trans_start = jiffies; +- +- be_tx_stats_update(adapter, wrb_cnt, copied, stopped); +- return NETDEV_TX_OK; +-} +- +-static int be_change_mtu(struct net_device *netdev, int new_mtu) +-{ +- struct be_adapter *adapter = netdev_priv(netdev); +- if (new_mtu < BE_MIN_MTU || +- new_mtu > BE_MAX_JUMBO_FRAME_SIZE) { +- dev_info(&adapter->pdev->dev, +- "MTU must be between %d and %d bytes\n", +- BE_MIN_MTU, BE_MAX_JUMBO_FRAME_SIZE); +- return -EINVAL; +- } +- dev_info(&adapter->pdev->dev, "MTU changed from %d to %d bytes\n", +- netdev->mtu, new_mtu); +- netdev->mtu = new_mtu; +- return 0; +-} +- +-/* +- * if there are BE_NUM_VLANS_SUPPORTED or lesser number of VLANS configured, +- * program them in BE. If more than BE_NUM_VLANS_SUPPORTED are configured, +- * set the BE in promiscuous VLAN mode. +- */ +-static void be_vid_config(struct net_device *netdev) +-{ +- struct be_adapter *adapter = netdev_priv(netdev); +- u16 vtag[BE_NUM_VLANS_SUPPORTED]; +- u16 ntags = 0, i; +- +- if (adapter->num_vlans <= BE_NUM_VLANS_SUPPORTED) { +- /* Construct VLAN Table to give to HW */ +- for (i = 0; i < VLAN_GROUP_ARRAY_LEN; i++) { +- if (adapter->vlan_tag[i]) { +- vtag[ntags] = cpu_to_le16(i); +- ntags++; +- } +- } +- be_cmd_vlan_config(&adapter->ctrl, adapter->if_handle, +- vtag, ntags, 1, 0); +- } else { +- be_cmd_vlan_config(&adapter->ctrl, adapter->if_handle, +- NULL, 0, 1, 1); +- } +-} +- +-static void be_vlan_register(struct net_device *netdev, struct vlan_group *grp) +-{ +- struct be_adapter *adapter = netdev_priv(netdev); +- struct be_eq_obj *rx_eq = &adapter->rx_eq; +- struct be_eq_obj *tx_eq = &adapter->tx_eq; +- struct be_ctrl_info *ctrl = &adapter->ctrl; +- +- be_eq_notify(ctrl, rx_eq->q.id, false, false, 0); +- be_eq_notify(ctrl, tx_eq->q.id, false, false, 0); +- adapter->vlan_grp = grp; +- be_eq_notify(ctrl, rx_eq->q.id, true, false, 0); +- be_eq_notify(ctrl, tx_eq->q.id, true, false, 0); +-} +- +-static void be_vlan_add_vid(struct net_device *netdev, u16 vid) +-{ +- struct be_adapter *adapter = netdev_priv(netdev); +- +- adapter->num_vlans++; +- adapter->vlan_tag[vid] = 1; +- +- be_vid_config(netdev); +-} +- +-static void be_vlan_rem_vid(struct net_device *netdev, u16 vid) +-{ +- struct be_adapter *adapter = netdev_priv(netdev); +- +- adapter->num_vlans--; +- adapter->vlan_tag[vid] = 0; +- +- vlan_group_set_device(adapter->vlan_grp, vid, NULL); +- be_vid_config(netdev); +-} +- +-static void be_set_multicast_filter(struct net_device *netdev) +-{ +- struct be_adapter *adapter = netdev_priv(netdev); +- struct dev_mc_list *mc_ptr; +- u8 mac_addr[32][ETH_ALEN]; +- int i = 0; +- +- if (netdev->flags & IFF_ALLMULTI) { +- /* set BE in Multicast promiscuous */ +- be_cmd_mcast_mac_set(&adapter->ctrl, +- adapter->if_handle, NULL, 0, true); +- return; +- } +- +- for (mc_ptr = netdev->mc_list; mc_ptr; mc_ptr = mc_ptr->next) { +- memcpy(&mac_addr[i][0], mc_ptr->dmi_addr, ETH_ALEN); +- if (++i >= 32) { +- be_cmd_mcast_mac_set(&adapter->ctrl, +- adapter->if_handle, &mac_addr[0][0], i, false); +- i = 0; +- } +- +- } +- +- if (i) { +- /* reset the promiscuous mode also. */ +- be_cmd_mcast_mac_set(&adapter->ctrl, +- adapter->if_handle, &mac_addr[0][0], i, false); +- } +-} +- +-static void be_set_multicast_list(struct net_device *netdev) +-{ +- struct be_adapter *adapter = netdev_priv(netdev); +- +- if (netdev->flags & IFF_PROMISC) { +- be_cmd_promiscuous_config(&adapter->ctrl, adapter->port_num, 1); +- } else { +- be_cmd_promiscuous_config(&adapter->ctrl, adapter->port_num, 0); +- be_set_multicast_filter(netdev); +- } +-} +- +-static void be_rx_rate_update(struct be_adapter *adapter, u32 pktsize, +- u16 numfrags) +-{ +- struct be_drvr_stats *stats = &adapter->stats.drvr_stats; +- u32 rate; +- +- stats->be_rx_compl++; +- stats->be_rx_frags += numfrags; +- stats->be_rx_bytes += pktsize; +- +- /* Update the rate once in two seconds */ +- if ((jiffies - stats->be_rx_jiffies) < 2 * HZ) +- return; +- +- rate = (stats->be_rx_bytes - stats->be_rx_bytes_prev) / +- ((u32) (jiffies - stats->be_rx_jiffies) / HZ); +- rate = (rate / 1000000); /* MB/Sec */ +- stats->be_rx_rate = (rate * 8); /* Mega Bits/Sec */ +- stats->be_rx_jiffies = jiffies; +- stats->be_rx_bytes_prev = stats->be_rx_bytes; +-} +- +-static struct be_rx_page_info * +-get_rx_page_info(struct be_adapter *adapter, u16 frag_idx) +-{ +- struct be_rx_page_info *rx_page_info; +- struct be_queue_info *rxq = &adapter->rx_obj.q; +- +- rx_page_info = &adapter->rx_obj.page_info_tbl[frag_idx]; +- BUG_ON(!rx_page_info->page); +- +- if (rx_page_info->last_page_user) +- pci_unmap_page(adapter->pdev, pci_unmap_addr(rx_page_info, bus), +- adapter->big_page_size, PCI_DMA_FROMDEVICE); +- +- atomic_dec(&rxq->used); +- return rx_page_info; +-} +- +-/* Throwaway the data in the Rx completion */ +-static void be_rx_compl_discard(struct be_adapter *adapter, +- struct be_eth_rx_compl *rxcp) +-{ +- struct be_queue_info *rxq = &adapter->rx_obj.q; +- struct be_rx_page_info *page_info; +- u16 rxq_idx, i, num_rcvd; +- +- rxq_idx = AMAP_GET_BITS(struct amap_eth_rx_compl, fragndx, rxcp); +- num_rcvd = AMAP_GET_BITS(struct amap_eth_rx_compl, numfrags, rxcp); +- +- for (i = 0; i < num_rcvd; i++) { +- page_info = get_rx_page_info(adapter, rxq_idx); +- put_page(page_info->page); +- memset(page_info, 0, sizeof(*page_info)); +- index_inc(&rxq_idx, rxq->len); +- } +-} +- +-/* +- * skb_fill_rx_data forms a complete skb for an ether frame +- * indicated by rxcp. +- */ +-static void skb_fill_rx_data(struct be_adapter *adapter, +- struct sk_buff *skb, struct be_eth_rx_compl *rxcp) +-{ +- struct be_queue_info *rxq = &adapter->rx_obj.q; +- struct be_rx_page_info *page_info; +- u16 rxq_idx, i, num_rcvd; +- u32 pktsize, hdr_len, curr_frag_len; +- u8 *start; +- +- rxq_idx = AMAP_GET_BITS(struct amap_eth_rx_compl, fragndx, rxcp); +- pktsize = AMAP_GET_BITS(struct amap_eth_rx_compl, pktsize, rxcp); +- num_rcvd = AMAP_GET_BITS(struct amap_eth_rx_compl, numfrags, rxcp); +- +- page_info = get_rx_page_info(adapter, rxq_idx); +- +- start = page_address(page_info->page) + page_info->page_offset; +- prefetch(start); +- +- /* Copy data in the first descriptor of this completion */ +- curr_frag_len = min(pktsize, rx_frag_size); +- +- /* Copy the header portion into skb_data */ +- hdr_len = min((u32)BE_HDR_LEN, curr_frag_len); +- memcpy(skb->data, start, hdr_len); +- skb->len = curr_frag_len; +- if (curr_frag_len <= BE_HDR_LEN) { /* tiny packet */ +- /* Complete packet has now been moved to data */ +- put_page(page_info->page); +- skb->data_len = 0; +- skb->tail += curr_frag_len; +- } else { +- skb_shinfo(skb)->nr_frags = 1; +- skb_shinfo(skb)->frags[0].page = page_info->page; +- skb_shinfo(skb)->frags[0].page_offset = +- page_info->page_offset + hdr_len; +- skb_shinfo(skb)->frags[0].size = curr_frag_len - hdr_len; +- skb->data_len = curr_frag_len - hdr_len; +- skb->tail += hdr_len; +- } +- memset(page_info, 0, sizeof(*page_info)); +- +- if (pktsize <= rx_frag_size) { +- BUG_ON(num_rcvd != 1); +- return; +- } +- +- /* More frags present for this completion */ +- pktsize -= curr_frag_len; /* account for above copied frag */ +- for (i = 1; i < num_rcvd; i++) { +- index_inc(&rxq_idx, rxq->len); +- page_info = get_rx_page_info(adapter, rxq_idx); +- +- curr_frag_len = min(pktsize, rx_frag_size); +- +- skb_shinfo(skb)->frags[i].page = page_info->page; +- skb_shinfo(skb)->frags[i].page_offset = page_info->page_offset; +- skb_shinfo(skb)->frags[i].size = curr_frag_len; +- skb->len += curr_frag_len; +- skb->data_len += curr_frag_len; +- skb_shinfo(skb)->nr_frags++; +- pktsize -= curr_frag_len; +- +- memset(page_info, 0, sizeof(*page_info)); +- } +- +- be_rx_rate_update(adapter, pktsize, num_rcvd); +- return; +-} +- +-/* Process the RX completion indicated by rxcp when LRO is disabled */ +-static void be_rx_compl_process(struct be_adapter *adapter, +- struct be_eth_rx_compl *rxcp) +-{ +- struct sk_buff *skb; +- u32 vtp, vid; +- int l4_cksm; +- +- l4_cksm = AMAP_GET_BITS(struct amap_eth_rx_compl, l4_cksm, rxcp); +- vtp = AMAP_GET_BITS(struct amap_eth_rx_compl, vtp, rxcp); +- +- skb = netdev_alloc_skb(adapter->netdev, BE_HDR_LEN + NET_IP_ALIGN); +- if (!skb) { +- if (net_ratelimit()) +- dev_warn(&adapter->pdev->dev, "skb alloc failed\n"); +- be_rx_compl_discard(adapter, rxcp); +- return; +- } +- +- skb_reserve(skb, NET_IP_ALIGN); +- +- skb_fill_rx_data(adapter, skb, rxcp); +- +- if (l4_cksm && adapter->rx_csum) +- skb->ip_summed = CHECKSUM_UNNECESSARY; +- else +- skb->ip_summed = CHECKSUM_NONE; +- +- skb->truesize = skb->len + sizeof(struct sk_buff); +- skb->protocol = eth_type_trans(skb, adapter->netdev); +- skb->dev = adapter->netdev; +- +- if (vtp) { +- if (!adapter->vlan_grp || adapter->num_vlans == 0) { +- kfree_skb(skb); +- return; +- } +- vid = AMAP_GET_BITS(struct amap_eth_rx_compl, vlan_tag, rxcp); +- vid = be16_to_cpu(vid); +- vlan_hwaccel_receive_skb(skb, adapter->vlan_grp, vid); +- } else { +- netif_receive_skb(skb); +- } +- +- adapter->netdev->last_rx = jiffies; +- +- return; +-} +- +-/* Process the RX completion indicated by rxcp when LRO is enabled */ +-static void be_rx_compl_process_lro(struct be_adapter *adapter, +- struct be_eth_rx_compl *rxcp) +-{ +- struct be_rx_page_info *page_info; +- struct skb_frag_struct rx_frags[BE_MAX_FRAGS_PER_FRAME]; +- struct be_queue_info *rxq = &adapter->rx_obj.q; +- u32 num_rcvd, pkt_size, remaining, vlanf, curr_frag_len; +- u16 i, rxq_idx = 0, vid; +- +- num_rcvd = AMAP_GET_BITS(struct amap_eth_rx_compl, numfrags, rxcp); +- pkt_size = AMAP_GET_BITS(struct amap_eth_rx_compl, pktsize, rxcp); +- vlanf = AMAP_GET_BITS(struct amap_eth_rx_compl, vtp, rxcp); +- rxq_idx = AMAP_GET_BITS(struct amap_eth_rx_compl, fragndx, rxcp); +- +- remaining = pkt_size; +- for (i = 0; i < num_rcvd; i++) { +- page_info = get_rx_page_info(adapter, rxq_idx); +- +- curr_frag_len = min(remaining, rx_frag_size); +- +- rx_frags[i].page = page_info->page; +- rx_frags[i].page_offset = page_info->page_offset; +- rx_frags[i].size = curr_frag_len; +- remaining -= curr_frag_len; +- +- index_inc(&rxq_idx, rxq->len); +- +- memset(page_info, 0, sizeof(*page_info)); +- } +- +- if (likely(!vlanf)) { +- lro_receive_frags(&adapter->rx_obj.lro_mgr, rx_frags, pkt_size, +- pkt_size, NULL, 0); +- } else { +- vid = AMAP_GET_BITS(struct amap_eth_rx_compl, vlan_tag, rxcp); +- vid = be16_to_cpu(vid); +- +- if (!adapter->vlan_grp || adapter->num_vlans == 0) +- return; +- +- lro_vlan_hwaccel_receive_frags(&adapter->rx_obj.lro_mgr, +- rx_frags, pkt_size, pkt_size, adapter->vlan_grp, +- vid, NULL, 0); +- } +- +- be_rx_rate_update(adapter, pkt_size, num_rcvd); +- return; +-} +- +-static struct be_eth_rx_compl *be_rx_compl_get(struct be_adapter *adapter) +-{ +- struct be_eth_rx_compl *rxcp = queue_tail_node(&adapter->rx_obj.cq); +- +- if (rxcp->dw[offsetof(struct amap_eth_rx_compl, valid) / 32] == 0) +- return NULL; +- +- be_dws_le_to_cpu(rxcp, sizeof(*rxcp)); +- +- rxcp->dw[offsetof(struct amap_eth_rx_compl, valid) / 32] = 0; +- +- queue_tail_inc(&adapter->rx_obj.cq); +- return rxcp; +-} +- +-static inline struct page *be_alloc_pages(u32 size) +-{ +- gfp_t alloc_flags = GFP_ATOMIC; +- u32 order = get_order(size); +- if (order > 0) +- alloc_flags |= __GFP_COMP; +- return alloc_pages(alloc_flags, order); +-} +- +-/* +- * Allocate a page, split it to fragments of size rx_frag_size and post as +- * receive buffers to BE +- */ +-static void be_post_rx_frags(struct be_adapter *adapter) +-{ +- struct be_rx_page_info *page_info_tbl = adapter->rx_obj.page_info_tbl; +- struct be_rx_page_info *page_info = NULL; +- struct be_queue_info *rxq = &adapter->rx_obj.q; +- struct page *pagep = NULL; +- struct be_eth_rx_d *rxd; +- u64 page_dmaaddr = 0, frag_dmaaddr; +- u32 posted, page_offset = 0; +- +- +- page_info = &page_info_tbl[rxq->head]; +- for (posted = 0; posted < MAX_RX_POST && !page_info->page; posted++) { +- if (!pagep) { +- pagep = be_alloc_pages(adapter->big_page_size); +- if (unlikely(!pagep)) { +- drvr_stats(adapter)->be_ethrx_post_fail++; +- break; +- } +- page_dmaaddr = pci_map_page(adapter->pdev, pagep, 0, +- adapter->big_page_size, +- PCI_DMA_FROMDEVICE); +- page_info->page_offset = 0; +- } else { +- get_page(pagep); +- page_info->page_offset = page_offset + rx_frag_size; +- } +- page_offset = page_info->page_offset; +- page_info->page = pagep; +- pci_unmap_addr_set(page_info, bus, page_dmaaddr); +- frag_dmaaddr = page_dmaaddr + page_info->page_offset; +- +- rxd = queue_head_node(rxq); +- rxd->fragpa_lo = cpu_to_le32(frag_dmaaddr & 0xFFFFFFFF); +- rxd->fragpa_hi = cpu_to_le32(upper_32_bits(frag_dmaaddr)); +- queue_head_inc(rxq); +- +- /* Any space left in the current big page for another frag? */ +- if ((page_offset + rx_frag_size + rx_frag_size) > +- adapter->big_page_size) { +- pagep = NULL; +- page_info->last_page_user = true; +- } +- page_info = &page_info_tbl[rxq->head]; +- } +- if (pagep) +- page_info->last_page_user = true; +- +- if (posted) { +- atomic_add(posted, &rxq->used); +- be_rxq_notify(&adapter->ctrl, rxq->id, posted); +- } else if (atomic_read(&rxq->used) == 0) { +- /* Let be_worker replenish when memory is available */ +- adapter->rx_post_starved = true; +- } +- +- return; +-} +- +-static struct be_eth_tx_compl * +-be_tx_compl_get(struct be_adapter *adapter) +-{ +- struct be_queue_info *tx_cq = &adapter->tx_obj.cq; +- struct be_eth_tx_compl *txcp = queue_tail_node(tx_cq); +- +- if (txcp->dw[offsetof(struct amap_eth_tx_compl, valid) / 32] == 0) +- return NULL; +- +- be_dws_le_to_cpu(txcp, sizeof(*txcp)); +- +- txcp->dw[offsetof(struct amap_eth_tx_compl, valid) / 32] = 0; +- +- queue_tail_inc(tx_cq); +- return txcp; +-} +- +-static void be_tx_compl_process(struct be_adapter *adapter, u16 last_index) +-{ +- struct be_queue_info *txq = &adapter->tx_obj.q; +- struct be_eth_wrb *wrb; +- struct sk_buff **sent_skbs = adapter->tx_obj.sent_skb_list; +- struct sk_buff *sent_skb; +- u64 busaddr; +- u16 cur_index, num_wrbs = 0; +- +- cur_index = txq->tail; +- sent_skb = sent_skbs[cur_index]; +- BUG_ON(!sent_skb); +- sent_skbs[cur_index] = NULL; +- +- do { +- cur_index = txq->tail; +- wrb = queue_tail_node(txq); +- be_dws_le_to_cpu(wrb, sizeof(*wrb)); +- busaddr = ((u64)wrb->frag_pa_hi << 32) | (u64)wrb->frag_pa_lo; +- if (busaddr != 0) { +- pci_unmap_single(adapter->pdev, busaddr, +- wrb->frag_len, PCI_DMA_TODEVICE); +- } +- num_wrbs++; +- queue_tail_inc(txq); +- } while (cur_index != last_index); +- +- atomic_sub(num_wrbs, &txq->used); +- +- kfree_skb(sent_skb); +-} +- +-static void be_rx_q_clean(struct be_adapter *adapter) +-{ +- struct be_rx_page_info *page_info; +- struct be_queue_info *rxq = &adapter->rx_obj.q; +- struct be_queue_info *rx_cq = &adapter->rx_obj.cq; +- struct be_eth_rx_compl *rxcp; +- u16 tail; +- +- /* First cleanup pending rx completions */ +- while ((rxcp = be_rx_compl_get(adapter)) != NULL) { +- be_rx_compl_discard(adapter, rxcp); +- be_cq_notify(&adapter->ctrl, rx_cq->id, true, 1); +- } +- +- /* Then free posted rx buffer that were not used */ +- tail = (rxq->head + rxq->len - atomic_read(&rxq->used)) % rxq->len; +- for (; tail != rxq->head; index_inc(&tail, rxq->len)) { +- page_info = get_rx_page_info(adapter, tail); +- put_page(page_info->page); +- memset(page_info, 0, sizeof(*page_info)); +- } +- BUG_ON(atomic_read(&rxq->used)); +-} +- +-static void be_tx_q_clean(struct be_adapter *adapter) +-{ +- struct sk_buff **sent_skbs = adapter->tx_obj.sent_skb_list; +- struct sk_buff *sent_skb; +- struct be_queue_info *txq = &adapter->tx_obj.q; +- u16 last_index; +- bool dummy_wrb; +- +- while (atomic_read(&txq->used)) { +- sent_skb = sent_skbs[txq->tail]; +- last_index = txq->tail; +- index_adv(&last_index, +- wrb_cnt_for_skb(sent_skb, &dummy_wrb) - 1, txq->len); +- be_tx_compl_process(adapter, last_index); +- } +-} +- +-static void be_tx_queues_destroy(struct be_adapter *adapter) +-{ +- struct be_queue_info *q; +- +- q = &adapter->tx_obj.q; +- if (q->created) +- be_cmd_q_destroy(&adapter->ctrl, q, QTYPE_TXQ); +- be_queue_free(adapter, q); +- +- q = &adapter->tx_obj.cq; +- if (q->created) +- be_cmd_q_destroy(&adapter->ctrl, q, QTYPE_CQ); +- be_queue_free(adapter, q); +- +- /* No more tx completions can be rcvd now; clean up if there are +- * any pending completions or pending tx requests */ +- be_tx_q_clean(adapter); +- +- q = &adapter->tx_eq.q; +- if (q->created) +- be_cmd_q_destroy(&adapter->ctrl, q, QTYPE_EQ); +- be_queue_free(adapter, q); +-} +- +-static int be_tx_queues_create(struct be_adapter *adapter) +-{ +- struct be_queue_info *eq, *q, *cq; +- +- adapter->tx_eq.max_eqd = 0; +- adapter->tx_eq.min_eqd = 0; +- adapter->tx_eq.cur_eqd = 96; +- adapter->tx_eq.enable_aic = false; +- /* Alloc Tx Event queue */ +- eq = &adapter->tx_eq.q; +- if (be_queue_alloc(adapter, eq, EVNT_Q_LEN, sizeof(struct be_eq_entry))) +- return -1; +- +- /* Ask BE to create Tx Event queue */ +- if (be_cmd_eq_create(&adapter->ctrl, eq, adapter->tx_eq.cur_eqd)) +- goto tx_eq_free; +- /* Alloc TX eth compl queue */ +- cq = &adapter->tx_obj.cq; +- if (be_queue_alloc(adapter, cq, TX_CQ_LEN, +- sizeof(struct be_eth_tx_compl))) +- goto tx_eq_destroy; +- +- /* Ask BE to create Tx eth compl queue */ +- if (be_cmd_cq_create(&adapter->ctrl, cq, eq, false, false, 3)) +- goto tx_cq_free; +- +- /* Alloc TX eth queue */ +- q = &adapter->tx_obj.q; +- if (be_queue_alloc(adapter, q, TX_Q_LEN, sizeof(struct be_eth_wrb))) +- goto tx_cq_destroy; +- +- /* Ask BE to create Tx eth queue */ +- if (be_cmd_txq_create(&adapter->ctrl, q, cq)) +- goto tx_q_free; +- return 0; +- +-tx_q_free: +- be_queue_free(adapter, q); +-tx_cq_destroy: +- be_cmd_q_destroy(&adapter->ctrl, cq, QTYPE_CQ); +-tx_cq_free: +- be_queue_free(adapter, cq); +-tx_eq_destroy: +- be_cmd_q_destroy(&adapter->ctrl, eq, QTYPE_EQ); +-tx_eq_free: +- be_queue_free(adapter, eq); +- return -1; +-} +- +-static void be_rx_queues_destroy(struct be_adapter *adapter) +-{ +- struct be_queue_info *q; +- +- q = &adapter->rx_obj.q; +- if (q->created) { +- be_cmd_q_destroy(&adapter->ctrl, q, QTYPE_RXQ); +- be_rx_q_clean(adapter); +- } +- be_queue_free(adapter, q); +- +- q = &adapter->rx_obj.cq; +- if (q->created) +- be_cmd_q_destroy(&adapter->ctrl, q, QTYPE_CQ); +- be_queue_free(adapter, q); +- +- q = &adapter->rx_eq.q; +- if (q->created) +- be_cmd_q_destroy(&adapter->ctrl, q, QTYPE_EQ); +- be_queue_free(adapter, q); +-} +- +-static int be_rx_queues_create(struct be_adapter *adapter) +-{ +- struct be_queue_info *eq, *q, *cq; +- int rc; +- +- adapter->max_rx_coal = BE_MAX_FRAGS_PER_FRAME; +- adapter->big_page_size = (1 << get_order(rx_frag_size)) * PAGE_SIZE; +- adapter->rx_eq.max_eqd = BE_MAX_EQD; +- adapter->rx_eq.min_eqd = 0; +- adapter->rx_eq.cur_eqd = 0; +- adapter->rx_eq.enable_aic = true; +- +- /* Alloc Rx Event queue */ +- eq = &adapter->rx_eq.q; +- rc = be_queue_alloc(adapter, eq, EVNT_Q_LEN, +- sizeof(struct be_eq_entry)); +- if (rc) +- return rc; +- +- /* Ask BE to create Rx Event queue */ +- rc = be_cmd_eq_create(&adapter->ctrl, eq, adapter->rx_eq.cur_eqd); +- if (rc) +- goto rx_eq_free; +- +- /* Alloc RX eth compl queue */ +- cq = &adapter->rx_obj.cq; +- rc = be_queue_alloc(adapter, cq, RX_CQ_LEN, +- sizeof(struct be_eth_rx_compl)); +- if (rc) +- goto rx_eq_destroy; +- +- /* Ask BE to create Rx eth compl queue */ +- rc = be_cmd_cq_create(&adapter->ctrl, cq, eq, false, false, 3); +- if (rc) +- goto rx_cq_free; +- +- /* Alloc RX eth queue */ +- q = &adapter->rx_obj.q; +- rc = be_queue_alloc(adapter, q, RX_Q_LEN, sizeof(struct be_eth_rx_d)); +- if (rc) +- goto rx_cq_destroy; +- +- /* Ask BE to create Rx eth queue */ +- rc = be_cmd_rxq_create(&adapter->ctrl, q, cq->id, rx_frag_size, +- BE_MAX_JUMBO_FRAME_SIZE, adapter->if_handle, false); +- if (rc) +- goto rx_q_free; +- +- return 0; +-rx_q_free: +- be_queue_free(adapter, q); +-rx_cq_destroy: +- be_cmd_q_destroy(&adapter->ctrl, cq, QTYPE_CQ); +-rx_cq_free: +- be_queue_free(adapter, cq); +-rx_eq_destroy: +- be_cmd_q_destroy(&adapter->ctrl, eq, QTYPE_EQ); +-rx_eq_free: +- be_queue_free(adapter, eq); +- return rc; +-} +-static bool event_get(struct be_eq_obj *eq_obj, u16 *rid) +-{ +- struct be_eq_entry *entry = queue_tail_node(&eq_obj->q); +- u32 evt = entry->evt; +- +- if (!evt) +- return false; +- +- evt = le32_to_cpu(evt); +- *rid = (evt >> EQ_ENTRY_RES_ID_SHIFT) & EQ_ENTRY_RES_ID_MASK; +- entry->evt = 0; +- queue_tail_inc(&eq_obj->q); +- return true; +-} +- +-static int event_handle(struct be_ctrl_info *ctrl, +- struct be_eq_obj *eq_obj) +-{ +- u16 rid = 0, num = 0; +- +- while (event_get(eq_obj, &rid)) +- num++; +- +- /* We can see an interrupt and no event */ +- be_eq_notify(ctrl, eq_obj->q.id, true, true, num); +- if (num) +- napi_schedule(&eq_obj->napi); +- +- return num; +-} +- +-static irqreturn_t be_intx(int irq, void *dev) +-{ +- struct be_adapter *adapter = dev; +- struct be_ctrl_info *ctrl = &adapter->ctrl; +- int rx, tx; +- +- tx = event_handle(ctrl, &adapter->tx_eq); +- rx = event_handle(ctrl, &adapter->rx_eq); +- +- if (rx || tx) +- return IRQ_HANDLED; +- else +- return IRQ_NONE; +-} +- +-static irqreturn_t be_msix_rx(int irq, void *dev) +-{ +- struct be_adapter *adapter = dev; +- +- event_handle(&adapter->ctrl, &adapter->rx_eq); +- +- return IRQ_HANDLED; +-} +- +-static irqreturn_t be_msix_tx(int irq, void *dev) +-{ +- struct be_adapter *adapter = dev; +- +- event_handle(&adapter->ctrl, &adapter->tx_eq); +- +- return IRQ_HANDLED; +-} +- +-static inline bool do_lro(struct be_adapter *adapter, +- struct be_eth_rx_compl *rxcp) +-{ +- int err = AMAP_GET_BITS(struct amap_eth_rx_compl, err, rxcp); +- int tcp_frame = AMAP_GET_BITS(struct amap_eth_rx_compl, tcpf, rxcp); +- +- if (err) +- drvr_stats(adapter)->be_rxcp_err++; +- +- return (!tcp_frame || err || (adapter->max_rx_coal <= 1)) ? +- false : true; +-} +- +-int be_poll_rx(struct napi_struct *napi, int budget) +-{ +- struct be_eq_obj *rx_eq = container_of(napi, struct be_eq_obj, napi); +- struct be_adapter *adapter = +- container_of(rx_eq, struct be_adapter, rx_eq); +- struct be_queue_info *rx_cq = &adapter->rx_obj.cq; +- struct be_eth_rx_compl *rxcp; +- u32 work_done; +- +- for (work_done = 0; work_done < budget; work_done++) { +- rxcp = be_rx_compl_get(adapter); +- if (!rxcp) +- break; +- +- if (do_lro(adapter, rxcp)) +- be_rx_compl_process_lro(adapter, rxcp); +- else +- be_rx_compl_process(adapter, rxcp); +- } +- +- lro_flush_all(&adapter->rx_obj.lro_mgr); +- +- /* Refill the queue */ +- if (atomic_read(&adapter->rx_obj.q.used) < RX_FRAGS_REFILL_WM) +- be_post_rx_frags(adapter); +- +- /* All consumed */ +- if (work_done < budget) { +- napi_complete(napi); +- be_cq_notify(&adapter->ctrl, rx_cq->id, true, work_done); +- } else { +- /* More to be consumed; continue with interrupts disabled */ +- be_cq_notify(&adapter->ctrl, rx_cq->id, false, work_done); +- } +- return work_done; +-} +- +-/* For TX we don't honour budget; consume everything */ +-int be_poll_tx(struct napi_struct *napi, int budget) +-{ +- struct be_eq_obj *tx_eq = container_of(napi, struct be_eq_obj, napi); +- struct be_adapter *adapter = +- container_of(tx_eq, struct be_adapter, tx_eq); +- struct be_tx_obj *tx_obj = &adapter->tx_obj; +- struct be_queue_info *tx_cq = &tx_obj->cq; +- struct be_queue_info *txq = &tx_obj->q; +- struct be_eth_tx_compl *txcp; +- u32 num_cmpl = 0; +- u16 end_idx; +- +- while ((txcp = be_tx_compl_get(adapter))) { +- end_idx = AMAP_GET_BITS(struct amap_eth_tx_compl, +- wrb_index, txcp); +- be_tx_compl_process(adapter, end_idx); +- num_cmpl++; +- } +- +- /* As Tx wrbs have been freed up, wake up netdev queue if +- * it was stopped due to lack of tx wrbs. +- */ +- if (netif_queue_stopped(adapter->netdev) && +- atomic_read(&txq->used) < txq->len / 2) { +- netif_wake_queue(adapter->netdev); +- } +- +- napi_complete(napi); +- +- be_cq_notify(&adapter->ctrl, tx_cq->id, true, num_cmpl); +- +- drvr_stats(adapter)->be_tx_events++; +- drvr_stats(adapter)->be_tx_compl += num_cmpl; +- +- return 1; +-} +- +-static void be_worker(struct work_struct *work) +-{ +- struct be_adapter *adapter = +- container_of(work, struct be_adapter, work.work); +- int status; +- +- /* Check link */ +- be_link_status_update(adapter); +- +- /* Get Stats */ +- status = be_cmd_get_stats(&adapter->ctrl, &adapter->stats.cmd); +- if (!status) +- netdev_stats_update(adapter); +- +- /* Set EQ delay */ +- be_rx_eqd_update(adapter); +- +- if (adapter->rx_post_starved) { +- adapter->rx_post_starved = false; +- be_post_rx_frags(adapter); +- } +- +- schedule_delayed_work(&adapter->work, msecs_to_jiffies(1000)); +-} +- +-static void be_msix_enable(struct be_adapter *adapter) +-{ +- int i, status; +- +- for (i = 0; i < BE_NUM_MSIX_VECTORS; i++) +- adapter->msix_entries[i].entry = i; +- +- status = pci_enable_msix(adapter->pdev, adapter->msix_entries, +- BE_NUM_MSIX_VECTORS); +- if (status == 0) +- adapter->msix_enabled = true; +- return; +-} +- +-static inline int be_msix_vec_get(struct be_adapter *adapter, u32 eq_id) +-{ +- return adapter->msix_entries[eq_id - +- 8 * adapter->ctrl.pci_func].vector; +-} +- +-static int be_msix_register(struct be_adapter *adapter) +-{ +- struct net_device *netdev = adapter->netdev; +- struct be_eq_obj *tx_eq = &adapter->tx_eq; +- struct be_eq_obj *rx_eq = &adapter->rx_eq; +- int status, vec; +- +- sprintf(tx_eq->desc, "%s-tx", netdev->name); +- vec = be_msix_vec_get(adapter, tx_eq->q.id); +- status = request_irq(vec, be_msix_tx, 0, tx_eq->desc, adapter); +- if (status) +- goto err; +- +- sprintf(rx_eq->desc, "%s-rx", netdev->name); +- vec = be_msix_vec_get(adapter, rx_eq->q.id); +- status = request_irq(vec, be_msix_rx, 0, rx_eq->desc, adapter); +- if (status) { /* Free TX IRQ */ +- vec = be_msix_vec_get(adapter, tx_eq->q.id); +- free_irq(vec, adapter); +- goto err; +- } +- return 0; +-err: +- dev_warn(&adapter->pdev->dev, +- "MSIX Request IRQ failed - err %d\n", status); +- pci_disable_msix(adapter->pdev); +- adapter->msix_enabled = false; +- return status; +-} +- +-static int be_irq_register(struct be_adapter *adapter) +-{ +- struct net_device *netdev = adapter->netdev; +- int status; +- +- if (adapter->msix_enabled) { +- status = be_msix_register(adapter); +- if (status == 0) +- goto done; +- } +- +- /* INTx */ +- netdev->irq = adapter->pdev->irq; +- status = request_irq(netdev->irq, be_intx, IRQF_SHARED, netdev->name, +- adapter); +- if (status) { +- dev_err(&adapter->pdev->dev, +- "INTx request IRQ failed - err %d\n", status); +- return status; +- } +-done: +- adapter->isr_registered = true; +- return 0; +-} +- +-static void be_irq_unregister(struct be_adapter *adapter) +-{ +- struct net_device *netdev = adapter->netdev; +- int vec; +- +- if (!adapter->isr_registered) +- return; +- +- /* INTx */ +- if (!adapter->msix_enabled) { +- free_irq(netdev->irq, adapter); +- goto done; +- } +- +- /* MSIx */ +- vec = be_msix_vec_get(adapter, adapter->tx_eq.q.id); +- free_irq(vec, adapter); +- vec = be_msix_vec_get(adapter, adapter->rx_eq.q.id); +- free_irq(vec, adapter); +-done: +- adapter->isr_registered = false; +- return; +-} +- +-static int be_open(struct net_device *netdev) +-{ +- struct be_adapter *adapter = netdev_priv(netdev); +- struct be_ctrl_info *ctrl = &adapter->ctrl; +- struct be_eq_obj *rx_eq = &adapter->rx_eq; +- struct be_eq_obj *tx_eq = &adapter->tx_eq; +- u32 if_flags; +- int status; +- +- if_flags = BE_IF_FLAGS_BROADCAST | BE_IF_FLAGS_PROMISCUOUS | +- BE_IF_FLAGS_MCAST_PROMISCUOUS | BE_IF_FLAGS_UNTAGGED | +- BE_IF_FLAGS_PASS_L3L4_ERRORS; +- status = be_cmd_if_create(ctrl, if_flags, netdev->dev_addr, +- false/* pmac_invalid */, &adapter->if_handle, +- &adapter->pmac_id); +- if (status != 0) +- goto do_none; +- +- be_vid_config(netdev); +- +- status = be_cmd_set_flow_control(ctrl, true, true); +- if (status != 0) +- goto if_destroy; +- +- status = be_tx_queues_create(adapter); +- if (status != 0) +- goto if_destroy; +- +- status = be_rx_queues_create(adapter); +- if (status != 0) +- goto tx_qs_destroy; +- +- /* First time posting */ +- be_post_rx_frags(adapter); +- +- napi_enable(&rx_eq->napi); +- napi_enable(&tx_eq->napi); +- +- be_irq_register(adapter); +- +- be_intr_set(ctrl, true); +- +- /* The evt queues are created in the unarmed state; arm them */ +- be_eq_notify(ctrl, rx_eq->q.id, true, false, 0); +- be_eq_notify(ctrl, tx_eq->q.id, true, false, 0); +- +- /* The compl queues are created in the unarmed state; arm them */ +- be_cq_notify(ctrl, adapter->rx_obj.cq.id, true, 0); +- be_cq_notify(ctrl, adapter->tx_obj.cq.id, true, 0); +- +- be_link_status_update(adapter); +- +- schedule_delayed_work(&adapter->work, msecs_to_jiffies(100)); +- return 0; +- +-tx_qs_destroy: +- be_tx_queues_destroy(adapter); +-if_destroy: +- be_cmd_if_destroy(ctrl, adapter->if_handle); +-do_none: +- return status; +-} +- +-static int be_close(struct net_device *netdev) +-{ +- struct be_adapter *adapter = netdev_priv(netdev); +- struct be_ctrl_info *ctrl = &adapter->ctrl; +- struct be_eq_obj *rx_eq = &adapter->rx_eq; +- struct be_eq_obj *tx_eq = &adapter->tx_eq; +- int vec; +- +- cancel_delayed_work(&adapter->work); +- +- netif_stop_queue(netdev); +- netif_carrier_off(netdev); +- adapter->link.speed = PHY_LINK_SPEED_ZERO; +- +- be_intr_set(ctrl, false); +- +- if (adapter->msix_enabled) { +- vec = be_msix_vec_get(adapter, tx_eq->q.id); +- synchronize_irq(vec); +- vec = be_msix_vec_get(adapter, rx_eq->q.id); +- synchronize_irq(vec); +- } else { +- synchronize_irq(netdev->irq); +- } +- be_irq_unregister(adapter); +- +- napi_disable(&rx_eq->napi); +- napi_disable(&tx_eq->napi); +- +- be_rx_queues_destroy(adapter); +- be_tx_queues_destroy(adapter); +- +- be_cmd_if_destroy(ctrl, adapter->if_handle); +- return 0; +-} +- +-static int be_get_frag_header(struct skb_frag_struct *frag, void **mac_hdr, +- void **ip_hdr, void **tcpudp_hdr, +- u64 *hdr_flags, void *priv) +-{ +- struct ethhdr *eh; +- struct vlan_ethhdr *veh; +- struct iphdr *iph; +- u8 *va = page_address(frag->page) + frag->page_offset; +- unsigned long ll_hlen; +- +- prefetch(va); +- eh = (struct ethhdr *)va; +- *mac_hdr = eh; +- ll_hlen = ETH_HLEN; +- if (eh->h_proto != htons(ETH_P_IP)) { +- if (eh->h_proto == htons(ETH_P_8021Q)) { +- veh = (struct vlan_ethhdr *)va; +- if (veh->h_vlan_encapsulated_proto != htons(ETH_P_IP)) +- return -1; +- +- ll_hlen += VLAN_HLEN; +- } else { +- return -1; +- } +- } +- *hdr_flags = LRO_IPV4; +- iph = (struct iphdr *)(va + ll_hlen); +- *ip_hdr = iph; +- if (iph->protocol != IPPROTO_TCP) +- return -1; +- *hdr_flags |= LRO_TCP; +- *tcpudp_hdr = (u8 *) (*ip_hdr) + (iph->ihl << 2); +- +- return 0; +-} +- +-static void be_lro_init(struct be_adapter *adapter, struct net_device *netdev) +-{ +- struct net_lro_mgr *lro_mgr; +- +- lro_mgr = &adapter->rx_obj.lro_mgr; +- lro_mgr->dev = netdev; +- lro_mgr->features = LRO_F_NAPI; +- lro_mgr->ip_summed = CHECKSUM_UNNECESSARY; +- lro_mgr->ip_summed_aggr = CHECKSUM_UNNECESSARY; +- lro_mgr->max_desc = BE_MAX_LRO_DESCRIPTORS; +- lro_mgr->lro_arr = adapter->rx_obj.lro_desc; +- lro_mgr->get_frag_header = be_get_frag_header; +- lro_mgr->max_aggr = BE_MAX_FRAGS_PER_FRAME; +-} +- +-static struct net_device_ops be_netdev_ops = { +- .ndo_open = be_open, +- .ndo_stop = be_close, +- .ndo_start_xmit = be_xmit, +- .ndo_get_stats = be_get_stats, +- .ndo_set_rx_mode = be_set_multicast_list, +- .ndo_set_mac_address = be_mac_addr_set, +- .ndo_change_mtu = be_change_mtu, +- .ndo_validate_addr = eth_validate_addr, +- .ndo_vlan_rx_register = be_vlan_register, +- .ndo_vlan_rx_add_vid = be_vlan_add_vid, +- .ndo_vlan_rx_kill_vid = be_vlan_rem_vid, +-}; +- +-static void be_netdev_init(struct net_device *netdev) +-{ +- struct be_adapter *adapter = netdev_priv(netdev); +- +- netdev->features |= NETIF_F_SG | NETIF_F_HW_VLAN_RX | NETIF_F_TSO | +- NETIF_F_HW_VLAN_TX | NETIF_F_HW_VLAN_FILTER | NETIF_F_IP_CSUM | +- NETIF_F_IPV6_CSUM | NETIF_F_TSO6; +- +- netdev->flags |= IFF_MULTICAST; +- +- BE_SET_NETDEV_OPS(netdev, &be_netdev_ops); +- +- SET_ETHTOOL_OPS(netdev, &be_ethtool_ops); +- +- be_lro_init(adapter, netdev); +- +- netif_napi_add(netdev, &adapter->rx_eq.napi, be_poll_rx, +- BE_NAPI_WEIGHT); +- netif_napi_add(netdev, &adapter->tx_eq.napi, be_poll_tx, +- BE_NAPI_WEIGHT); +- +- netif_carrier_off(netdev); +- netif_stop_queue(netdev); +-} +- +-static void be_unmap_pci_bars(struct be_adapter *adapter) +-{ +- struct be_ctrl_info *ctrl = &adapter->ctrl; +- if (ctrl->csr) +- iounmap(ctrl->csr); +- if (ctrl->db) +- iounmap(ctrl->db); +- if (ctrl->pcicfg) +- iounmap(ctrl->pcicfg); +-} +- +-static int be_map_pci_bars(struct be_adapter *adapter) +-{ +- u8 __iomem *addr; +- +- addr = ioremap_nocache(pci_resource_start(adapter->pdev, 2), +- pci_resource_len(adapter->pdev, 2)); +- if (addr == NULL) +- return -ENOMEM; +- adapter->ctrl.csr = addr; +- +- addr = ioremap_nocache(pci_resource_start(adapter->pdev, 4), +- 128 * 1024); +- if (addr == NULL) +- goto pci_map_err; +- adapter->ctrl.db = addr; +- +- addr = ioremap_nocache(pci_resource_start(adapter->pdev, 1), +- pci_resource_len(adapter->pdev, 1)); +- if (addr == NULL) +- goto pci_map_err; +- adapter->ctrl.pcicfg = addr; +- +- return 0; +-pci_map_err: +- be_unmap_pci_bars(adapter); +- return -ENOMEM; +-} +- +- +-static void be_ctrl_cleanup(struct be_adapter *adapter) +-{ +- struct be_dma_mem *mem = &adapter->ctrl.mbox_mem_alloced; +- +- be_unmap_pci_bars(adapter); +- +- if (mem->va) +- pci_free_consistent(adapter->pdev, mem->size, +- mem->va, mem->dma); +-} +- +-/* Initialize the mbox required to send cmds to BE */ +-static int be_ctrl_init(struct be_adapter *adapter) +-{ +- struct be_ctrl_info *ctrl = &adapter->ctrl; +- struct be_dma_mem *mbox_mem_alloc = &ctrl->mbox_mem_alloced; +- struct be_dma_mem *mbox_mem_align = &ctrl->mbox_mem; +- int status; +- u32 val; +- +- status = be_map_pci_bars(adapter); +- if (status) +- return status; +- +- mbox_mem_alloc->size = sizeof(struct be_mcc_mailbox) + 16; +- mbox_mem_alloc->va = pci_alloc_consistent(adapter->pdev, +- mbox_mem_alloc->size, &mbox_mem_alloc->dma); +- if (!mbox_mem_alloc->va) { +- be_unmap_pci_bars(adapter); +- return -1; +- } +- mbox_mem_align->size = sizeof(struct be_mcc_mailbox); +- mbox_mem_align->va = PTR_ALIGN(mbox_mem_alloc->va, 16); +- mbox_mem_align->dma = PTR_ALIGN(mbox_mem_alloc->dma, 16); +- memset(mbox_mem_align->va, 0, sizeof(struct be_mcc_mailbox)); +- spin_lock_init(&ctrl->cmd_lock); +- +- val = ioread32(ctrl->pcicfg + PCICFG_MEMBAR_CTRL_INT_CTRL_OFFSET); +- ctrl->pci_func = (val >> MEMBAR_CTRL_INT_CTRL_PFUNC_SHIFT) & +- MEMBAR_CTRL_INT_CTRL_PFUNC_MASK; +- return 0; +-} +- +-static void be_stats_cleanup(struct be_adapter *adapter) +-{ +- struct be_stats_obj *stats = &adapter->stats; +- struct be_dma_mem *cmd = &stats->cmd; +- +- if (cmd->va) +- pci_free_consistent(adapter->pdev, cmd->size, +- cmd->va, cmd->dma); +-} +- +-static int be_stats_init(struct be_adapter *adapter) +-{ +- struct be_stats_obj *stats = &adapter->stats; +- struct be_dma_mem *cmd = &stats->cmd; +- +- cmd->size = sizeof(struct be_cmd_req_get_stats); +- cmd->va = pci_alloc_consistent(adapter->pdev, cmd->size, &cmd->dma); +- if (cmd->va == NULL) +- return -1; +- return 0; +-} +- +-static void __devexit be_remove(struct pci_dev *pdev) +-{ +- struct be_adapter *adapter = pci_get_drvdata(pdev); +- if (!adapter) +- return; +- +- unregister_netdev(adapter->netdev); +- +- be_stats_cleanup(adapter); +- +- be_ctrl_cleanup(adapter); +- +- if (adapter->msix_enabled) { +- pci_disable_msix(adapter->pdev); +- adapter->msix_enabled = false; +- } +- +- pci_set_drvdata(pdev, NULL); +- pci_release_regions(pdev); +- pci_disable_device(pdev); +- +- free_netdev(adapter->netdev); +-} +- +-static int be_hw_up(struct be_adapter *adapter) +-{ +- struct be_ctrl_info *ctrl = &adapter->ctrl; +- int status; +- +- status = be_cmd_POST(ctrl); +- if (status) +- return status; +- +- status = be_cmd_get_fw_ver(ctrl, adapter->fw_ver); +- if (status) +- return status; +- +- status = be_cmd_query_fw_cfg(ctrl, &adapter->port_num); +- return status; +-} +- +-static int __devinit be_probe(struct pci_dev *pdev, +- const struct pci_device_id *pdev_id) +-{ +- int status = 0; +- struct be_adapter *adapter; +- struct net_device *netdev; +- struct be_ctrl_info *ctrl; +- u8 mac[ETH_ALEN]; +- +- status = pci_enable_device(pdev); +- if (status) +- goto do_none; +- +- status = pci_request_regions(pdev, DRV_NAME); +- if (status) +- goto disable_dev; +- pci_set_master(pdev); +- +- netdev = alloc_etherdev(sizeof(struct be_adapter)); +- if (netdev == NULL) { +- status = -ENOMEM; +- goto rel_reg; +- } +- adapter = netdev_priv(netdev); +- adapter->pdev = pdev; +- pci_set_drvdata(pdev, adapter); +- adapter->netdev = netdev; +- +- be_msix_enable(adapter); +- +- status = pci_set_dma_mask(pdev, DMA_64BIT_MASK); +- if (!status) { +- netdev->features |= NETIF_F_HIGHDMA; +- } else { +- status = pci_set_dma_mask(pdev, DMA_32BIT_MASK); +- if (status) { +- dev_err(&pdev->dev, "Could not set PCI DMA Mask\n"); +- goto free_netdev; +- } +- } +- +- ctrl = &adapter->ctrl; +- status = be_ctrl_init(adapter); +- if (status) +- goto free_netdev; +- +- status = be_stats_init(adapter); +- if (status) +- goto ctrl_clean; +- +- status = be_hw_up(adapter); +- if (status) +- goto stats_clean; +- +- status = be_cmd_mac_addr_query(ctrl, mac, MAC_ADDRESS_TYPE_NETWORK, +- true /* permanent */, 0); +- if (status) +- goto stats_clean; +- memcpy(netdev->dev_addr, mac, ETH_ALEN); +- +- INIT_DELAYED_WORK(&adapter->work, be_worker); +- be_netdev_init(netdev); +- SET_NETDEV_DEV(netdev, &adapter->pdev->dev); +- +- status = register_netdev(netdev); +- if (status != 0) +- goto stats_clean; +- +- dev_info(&pdev->dev, BE_NAME " port %d\n", adapter->port_num); +- return 0; +- +-stats_clean: +- be_stats_cleanup(adapter); +-ctrl_clean: +- be_ctrl_cleanup(adapter); +-free_netdev: +- free_netdev(adapter->netdev); +-rel_reg: +- pci_release_regions(pdev); +-disable_dev: +- pci_disable_device(pdev); +-do_none: +- dev_warn(&pdev->dev, BE_NAME " initialization failed\n"); +- return status; +-} +- +-static int be_suspend(struct pci_dev *pdev, pm_message_t state) +-{ +- struct be_adapter *adapter = pci_get_drvdata(pdev); +- struct net_device *netdev = adapter->netdev; +- +- netif_device_detach(netdev); +- if (netif_running(netdev)) { +- rtnl_lock(); +- be_close(netdev); +- rtnl_unlock(); +- } +- +- pci_save_state(pdev); +- pci_disable_device(pdev); +- pci_set_power_state(pdev, pci_choose_state(pdev, state)); +- return 0; +-} +- +-static int be_resume(struct pci_dev *pdev) +-{ +- int status = 0; +- struct be_adapter *adapter = pci_get_drvdata(pdev); +- struct net_device *netdev = adapter->netdev; +- +- netif_device_detach(netdev); +- +- status = pci_enable_device(pdev); +- if (status) +- return status; +- +- pci_set_power_state(pdev, 0); +- pci_restore_state(pdev); +- +- if (netif_running(netdev)) { +- rtnl_lock(); +- be_open(netdev); +- rtnl_unlock(); +- } +- netif_device_attach(netdev); +- return 0; +-} +- +-static struct pci_driver be_driver = { +- .name = DRV_NAME, +- .id_table = be_dev_ids, +- .probe = be_probe, +- .remove = be_remove, +- .suspend = be_suspend, +- .resume = be_resume +-}; +- +-static int __init be_init_module(void) +-{ +- if (rx_frag_size != 8192 && rx_frag_size != 4096 +- && rx_frag_size != 2048) { +- printk(KERN_WARNING DRV_NAME +- " : Module param rx_frag_size must be 2048/4096/8192." +- " Using 2048\n"); +- rx_frag_size = 2048; +- } +- /* Ensure rx_frag_size is aligned to chache line */ +- if (SKB_DATA_ALIGN(rx_frag_size) != rx_frag_size) { +- printk(KERN_WARNING DRV_NAME +- " : Bad module param rx_frag_size. Using 2048\n"); +- rx_frag_size = 2048; +- } +- +- return pci_register_driver(&be_driver); +-} +-module_init(be_init_module); +- +-static void __exit be_exit_module(void) +-{ +- pci_unregister_driver(&be_driver); +-} +-module_exit(be_exit_module); +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/drivers/net/benet/Kconfig linux-2.6.29-rc3.owrt/drivers/net/benet/Kconfig +--- linux-2.6.29.owrt/drivers/net/benet/Kconfig 2009-05-10 22:04:38.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/drivers/net/benet/Kconfig 1970-01-01 01:00:00.000000000 +0100 +@@ -1,7 +0,0 @@ +-config BE2NET +- tristate "ServerEngines' 10Gbps NIC - BladeEngine 2" +- depends on PCI && INET +- select INET_LRO +- help +- This driver implements the NIC functionality for ServerEngines' +- 10Gbps network adapter - BladeEngine 2. +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/drivers/net/benet/Makefile linux-2.6.29-rc3.owrt/drivers/net/benet/Makefile +--- linux-2.6.29.owrt/drivers/net/benet/Makefile 2009-05-10 22:04:38.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/drivers/net/benet/Makefile 1970-01-01 01:00:00.000000000 +0100 +@@ -1,7 +0,0 @@ +-# +-# Makefile to build the network driver for ServerEngine's BladeEngine. +-# +- +-obj-$(CONFIG_BE2NET) += be2net.o +- +-be2net-y := be_main.o be_cmds.o be_ethtool.o +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/drivers/net/bnx2.c linux-2.6.29-rc3.owrt/drivers/net/bnx2.c +--- linux-2.6.29.owrt/drivers/net/bnx2.c 2009-05-10 22:04:38.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/drivers/net/bnx2.c 2009-05-10 23:48:28.000000000 +0200 +@@ -1,6 +1,6 @@ + /* bnx2.c: Broadcom NX2 network driver. + * +- * Copyright (c) 2004-2009 Broadcom Corporation ++ * Copyright (c) 2004-2008 Broadcom Corporation + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by +@@ -57,8 +57,8 @@ + + #define DRV_MODULE_NAME "bnx2" + #define PFX DRV_MODULE_NAME ": " +-#define DRV_MODULE_VERSION "1.9.3" +-#define DRV_MODULE_RELDATE "March 17, 2009" ++#define DRV_MODULE_VERSION "1.9.0" ++#define DRV_MODULE_RELDATE "Dec 16, 2008" + + #define RUN_AT(x) (jiffies + (x)) + +@@ -2910,8 +2910,18 @@ + + rx_hdr = (struct l2_fhdr *) skb->data; + len = rx_hdr->l2_fhdr_pkt_len; +- status = rx_hdr->l2_fhdr_status; + ++ if ((status = rx_hdr->l2_fhdr_status) & ++ (L2_FHDR_ERRORS_BAD_CRC | ++ L2_FHDR_ERRORS_PHY_DECODE | ++ L2_FHDR_ERRORS_ALIGNMENT | ++ L2_FHDR_ERRORS_TOO_SHORT | ++ L2_FHDR_ERRORS_GIANT_FRAME)) { ++ ++ bnx2_reuse_rx_skb(bp, rxr, skb, sw_ring_cons, ++ sw_ring_prod); ++ goto next_rx; ++ } + hdr_len = 0; + if (status & L2_FHDR_STATUS_SPLIT) { + hdr_len = rx_hdr->l2_fhdr_ip_xsum; +@@ -2921,24 +2931,6 @@ + pg_ring_used = 1; + } + +- if (unlikely(status & (L2_FHDR_ERRORS_BAD_CRC | +- L2_FHDR_ERRORS_PHY_DECODE | +- L2_FHDR_ERRORS_ALIGNMENT | +- L2_FHDR_ERRORS_TOO_SHORT | +- L2_FHDR_ERRORS_GIANT_FRAME))) { +- +- bnx2_reuse_rx_skb(bp, rxr, skb, sw_ring_cons, +- sw_ring_prod); +- if (pg_ring_used) { +- int pages; +- +- pages = PAGE_ALIGN(len - hdr_len) >> PAGE_SHIFT; +- +- bnx2_reuse_rx_skb_pages(bp, rxr, NULL, pages); +- } +- goto next_rx; +- } +- + len -= 4; + + if (len <= bp->rx_copy_thresh) { +@@ -5843,6 +5835,9 @@ + for (i = 0; i < BNX2_MAX_MSIX_VEC; i++) { + msix_ent[i].entry = i; + msix_ent[i].vector = 0; ++ ++ snprintf(bp->irq_tbl[i].name, len, "%s-%d", dev->name, i); ++ bp->irq_tbl[i].handler = bnx2_msi_1shot; + } + + rc = pci_enable_msix(bp->pdev, msix_ent, BNX2_MAX_MSIX_VEC); +@@ -5851,11 +5846,8 @@ + + bp->irq_nvecs = msix_vecs; + bp->flags |= BNX2_FLAG_USING_MSIX | BNX2_FLAG_ONE_SHOT_MSI; +- for (i = 0; i < BNX2_MAX_MSIX_VEC; i++) { ++ for (i = 0; i < BNX2_MAX_MSIX_VEC; i++) + bp->irq_tbl[i].vector = msix_ent[i].vector; +- snprintf(bp->irq_tbl[i].name, len, "%s-%d", dev->name, i); +- bp->irq_tbl[i].handler = bnx2_msi_1shot; +- } + } + + static void +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/drivers/net/bnx2_fw2.h linux-2.6.29-rc3.owrt/drivers/net/bnx2_fw2.h +--- linux-2.6.29.owrt/drivers/net/bnx2_fw2.h 2009-05-10 22:04:38.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/drivers/net/bnx2_fw2.h 2009-05-10 23:48:28.000000000 +0200 +@@ -15,847 +15,848 @@ + */ + + static u8 bnx2_COM_b09FwText[] = { +- 0xcd, 0x7c, 0x7b, 0x6c, 0x5c, 0xd7, 0x99, 0xdf, 0x77, 0xef, 0xcc, 0x90, +- 0x43, 0x6a, 0x44, 0x5d, 0x32, 0x13, 0x66, 0x1c, 0x33, 0xcd, 0x3c, 0x2e, +- 0x29, 0xda, 0x64, 0x92, 0x31, 0x77, 0xa4, 0xd0, 0xc9, 0xad, 0x3d, 0x99, +- 0x19, 0xc9, 0x4c, 0xa8, 0x0d, 0xe8, 0x44, 0x2e, 0x52, 0x54, 0x28, 0xd8, +- 0x21, 0xe5, 0x28, 0x8b, 0xec, 0xae, 0xf2, 0x28, 0x9a, 0x2e, 0xd2, 0xd5, +- 0x64, 0x48, 0x29, 0xca, 0x62, 0xc4, 0x19, 0xd3, 0x34, 0x93, 0xa2, 0x01, +- 0x32, 0x19, 0x92, 0x72, 0x76, 0x31, 0x12, 0x15, 0xdb, 0xcd, 0x1a, 0x41, +- 0xe2, 0xb0, 0xd4, 0x23, 0xde, 0x20, 0x2d, 0xb4, 0x1b, 0x17, 0x4d, 0xd3, +- 0x45, 0x21, 0xc8, 0x4e, 0x6c, 0x6c, 0xb3, 0x6d, 0x50, 0x2c, 0x10, 0x77, +- 0x91, 0x64, 0xfa, 0xfb, 0x9d, 0x73, 0xee, 0x70, 0x44, 0x31, 0x4e, 0xba, +- 0x7f, 0x95, 0xc0, 0xe0, 0xdc, 0x7b, 0x9e, 0xdf, 0xf9, 0xce, 0xf7, 0x3e, +- 0xdf, 0xe5, 0x43, 0x22, 0xbd, 0x62, 0xfe, 0xf6, 0xe3, 0x97, 0xf9, 0xfd, +- 0x3f, 0x9c, 0x7b, 0xe0, 0x9d, 0x87, 0xdf, 0x89, 0xc7, 0x43, 0xf6, 0x81, +- 0xae, 0x20, 0xeb, 0x03, 0xf8, 0x45, 0xf1, 0x9b, 0x30, 0xcf, 0x7b, 0xfd, +- 0x39, 0xf8, 0x1d, 0xb6, 0x44, 0x66, 0xff, 0x46, 0xc4, 0xda, 0xd5, 0x16, +- 0xfe, 0x35, 0x63, 0xde, 0xe8, 0xcf, 0xfe, 0x2d, 0xfb, 0x39, 0xff, 0x80, +- 0xb9, 0xfd, 0xbf, 0x80, 0x19, 0xbe, 0xdf, 0xfc, 0x24, 0x6c, 0x7b, 0xb7, +- 0x3e, 0x90, 0x73, 0x25, 0x1c, 0xf0, 0x7e, 0x38, 0x3d, 0xe7, 0x8a, 0x64, +- 0x9b, 0x63, 0xf1, 0xbc, 0xfc, 0xb2, 0x55, 0x8a, 0x06, 0x85, 0xf5, 0x6f, +- 0xf3, 0x7e, 0xf1, 0x95, 0x6f, 0xbf, 0x3b, 0xf1, 0xb3, 0x7a, 0x40, 0xc2, +- 0x8e, 0xf7, 0xba, 0x38, 0x23, 0x12, 0x1e, 0xc2, 0x98, 0x2f, 0x1f, 0x9c, +- 0xb5, 0xa5, 0xcf, 0x9f, 0xeb, 0xb5, 0xd6, 0xb7, 0x0f, 0x4a, 0xc9, 0xf6, +- 0x1c, 0xb9, 0xb2, 0x19, 0x95, 0xef, 0x6c, 0x8a, 0x35, 0x93, 0xe9, 0x11, +- 0x7b, 0xf9, 0xad, 0x92, 0x75, 0x2c, 0x09, 0xb8, 0x5c, 0x27, 0x2e, 0xb9, +- 0xca, 0x20, 0xde, 0x13, 0x31, 0x91, 0x7f, 0xbe, 0x5f, 0x8f, 0x0d, 0x4b, +- 0x60, 0x55, 0xc2, 0x5d, 0xde, 0x0b, 0xd3, 0x37, 0x56, 0x62, 0x12, 0x5c, +- 0x1a, 0x97, 0x72, 0x35, 0x22, 0xa1, 0x55, 0x19, 0x0a, 0xc8, 0x70, 0xec, +- 0x71, 0xf4, 0x28, 0x34, 0x83, 0x72, 0xa4, 0x69, 0x49, 0xd0, 0x0d, 0x03, +- 0xb6, 0x08, 0x7e, 0x0e, 0x7e, 0x51, 0xfc, 0x62, 0xf8, 0x9d, 0xc5, 0x3c, +- 0x43, 0x92, 0x6f, 0x72, 0x4e, 0xac, 0x5b, 0xc5, 0xfa, 0xd5, 0x84, 0x33, +- 0x8b, 0x79, 0x6f, 0x05, 0x62, 0xf2, 0xed, 0x83, 0x84, 0xcb, 0x21, 0x3c, +- 0x80, 0x2d, 0x6c, 0xe5, 0x56, 0xe4, 0x74, 0x3e, 0x2d, 0x71, 0xdb, 0xed, +- 0x95, 0xa2, 0x63, 0xc5, 0xe7, 0x47, 0x07, 0xa4, 0x74, 0x1c, 0xed, 0x55, +- 0xc9, 0xda, 0x98, 0xbf, 0xe8, 0xc8, 0xac, 0x6e, 0x63, 0xdd, 0x17, 0x41, +- 0x27, 0x09, 0x87, 0x08, 0xfb, 0x4e, 0xf5, 0x31, 0x3c, 0x73, 0xbe, 0x78, +- 0x50, 0xc3, 0xbd, 0x8a, 0x77, 0xd6, 0xff, 0x41, 0x44, 0xbf, 0xf3, 0x99, +- 0x7d, 0xfd, 0x75, 0xfd, 0xfd, 0x72, 0xfd, 0x51, 0xec, 0x99, 0x30, 0xf8, +- 0x7b, 0x96, 0x52, 0x08, 0xb0, 0x34, 0x56, 0x22, 0xd6, 0xda, 0xca, 0xb8, +- 0x9c, 0xab, 0x3e, 0x24, 0xb9, 0x74, 0xab, 0x35, 0x97, 0x96, 0xa8, 0x2d, +- 0xc3, 0x4e, 0x1e, 0x1d, 0xb6, 0x9b, 0x62, 0x35, 0x2a, 0x12, 0xee, 0x06, +- 0x5e, 0x5e, 0x5d, 0xe1, 0xdc, 0x41, 0xd4, 0x0d, 0xa2, 0x7f, 0x9f, 0xb5, +- 0xbe, 0x02, 0xf8, 0x3d, 0xe2, 0xa7, 0xd5, 0x5a, 0x4c, 0x0f, 0xc7, 0xe6, +- 0xb1, 0xe6, 0xd5, 0xe6, 0xf0, 0xe4, 0x6d, 0x71, 0x30, 0xe7, 0x00, 0xfa, +- 0x10, 0x57, 0x9c, 0x8b, 0x73, 0x72, 0xbe, 0x08, 0xc6, 0x46, 0xd1, 0x46, +- 0xb8, 0x5a, 0xad, 0x5c, 0xda, 0xe1, 0xbb, 0x6c, 0x01, 0x7f, 0x5b, 0xc4, +- 0x5f, 0xef, 0x90, 0x7c, 0xb7, 0xc9, 0x35, 0xda, 0xb0, 0x97, 0xba, 0xbc, +- 0xe7, 0xed, 0xed, 0x0a, 0xcf, 0x2d, 0x2c, 0xef, 0x0b, 0x26, 0x46, 0x4b, +- 0x8a, 0x4e, 0x66, 0xb1, 0x1f, 0x4b, 0xd1, 0x84, 0x85, 0xe7, 0x64, 0x93, +- 0xfd, 0x89, 0xeb, 0xb8, 0x2c, 0xe0, 0x5c, 0xcb, 0x2b, 0x25, 0xfb, 0x6a, +- 0xf3, 0x17, 0xad, 0x9c, 0xbb, 0x68, 0x6f, 0xaf, 0xb3, 0xff, 0x09, 0xf4, +- 0x0f, 0xca, 0x62, 0xa5, 0x4f, 0x08, 0x93, 0x1e, 0x77, 0x02, 0xe3, 0xc4, +- 0xb1, 0xbd, 0x73, 0xf6, 0xd5, 0xf5, 0xf3, 0xf6, 0x35, 0x75, 0x6e, 0x58, +- 0xab, 0x3d, 0x57, 0x27, 0xde, 0xc6, 0xfe, 0x3f, 0xc4, 0x5b, 0x0c, 0xf3, +- 0x47, 0x51, 0xee, 0xb3, 0x1a, 0xb5, 0x16, 0xd6, 0x8f, 0xe1, 0x79, 0x2f, +- 0x1c, 0xde, 0x52, 0x74, 0x77, 0x05, 0x74, 0xe7, 0x78, 0x31, 0x79, 0x66, +- 0x73, 0x08, 0xfb, 0x88, 0xca, 0xd7, 0xc1, 0x17, 0x03, 0x87, 0xf7, 0x49, +- 0x1e, 0x7c, 0x41, 0x7a, 0x7b, 0x74, 0xf5, 0x9f, 0x49, 0x31, 0x9a, 0x18, +- 0xa5, 0xfc, 0x48, 0x4e, 0x80, 0x9e, 0x0d, 0x6b, 0xe7, 0x96, 0xb2, 0x29, +- 0x5b, 0x1e, 0x16, 0xdb, 0xc3, 0xba, 0x99, 0x31, 0xa7, 0x20, 0x41, 0xb4, +- 0x65, 0x25, 0xe0, 0x45, 0x25, 0xb7, 0xfa, 0x5e, 0x0b, 0x74, 0x19, 0x5f, +- 0xc0, 0xa0, 0xc0, 0x92, 0x58, 0xb6, 0xdb, 0x25, 0xc5, 0xe3, 0xac, 0x0f, +- 0x83, 0xc6, 0xc1, 0xb3, 0x2b, 0x07, 0x00, 0x97, 0x0c, 0xdb, 0xc2, 0xba, +- 0x61, 0xa7, 0x2c, 0x25, 0xb1, 0x2f, 0xff, 0xa1, 0x65, 0x64, 0x9e, 0xc1, +- 0xef, 0xa8, 0x59, 0xab, 0xcd, 0x87, 0x96, 0xbd, 0x1a, 0xb1, 0x02, 0xab, +- 0xe3, 0x72, 0x76, 0x0f, 0xbc, 0x36, 0x80, 0x57, 0x7b, 0xc9, 0xe7, 0xd3, +- 0x20, 0xde, 0x07, 0xd1, 0xb7, 0xcf, 0x0a, 0xae, 0xde, 0x8d, 0xd3, 0xb5, +- 0xe6, 0x70, 0x7a, 0x1b, 0x38, 0xb5, 0x57, 0x07, 0xd0, 0xe7, 0x6e, 0x9c, +- 0x36, 0x80, 0x53, 0x7b, 0x55, 0xe3, 0xb3, 0x01, 0x7c, 0xda, 0x4b, 0x51, +- 0x94, 0xfb, 0x2c, 0x7b, 0x59, 0xe3, 0xb3, 0x61, 0x78, 0xfa, 0x62, 0x93, +- 0xb0, 0x66, 0x3b, 0x68, 0x2e, 0x4b, 0xda, 0x81, 0x9c, 0x2a, 0xc8, 0x5c, +- 0xc5, 0x06, 0xbe, 0x82, 0xe2, 0x4e, 0x58, 0x32, 0xa7, 0xda, 0x0a, 0x92, +- 0x02, 0x0d, 0x95, 0x9c, 0xb1, 0x51, 0x5b, 0x12, 0xf1, 0xac, 0x0d, 0x7c, +- 0x57, 0x81, 0xf7, 0x2a, 0x70, 0xae, 0x64, 0xc2, 0x8b, 0xe0, 0xd7, 0x38, +- 0xce, 0x65, 0x77, 0x7d, 0xc2, 0xa9, 0x2b, 0x9e, 0x8d, 0x9b, 0x33, 0x23, +- 0xed, 0xf3, 0x9c, 0x62, 0x38, 0x2f, 0x75, 0x7e, 0xd6, 0x5f, 0x66, 0xf6, +- 0x49, 0x6a, 0x39, 0xa0, 0xce, 0x2b, 0xbd, 0xfa, 0xae, 0xf6, 0x79, 0xd9, +- 0x13, 0x94, 0x65, 0x3c, 0x23, 0x91, 0xd4, 0x12, 0xcf, 0x29, 0x9b, 0x0a, +- 0x08, 0xcf, 0x2a, 0x24, 0xd9, 0x19, 0x9e, 0x4b, 0x54, 0x92, 0xab, 0x3c, +- 0xb3, 0x0d, 0x73, 0x5e, 0xfa, 0x9c, 0x92, 0x7b, 0x9c, 0x53, 0xd2, 0x9c, +- 0xd3, 0x76, 0xf3, 0x8a, 0x39, 0xa7, 0x7f, 0x2b, 0x86, 0xe6, 0xdf, 0x10, +- 0x07, 0x36, 0x70, 0x10, 0xbc, 0x03, 0x07, 0xdd, 0x6d, 0x1c, 0xc4, 0x6d, +- 0xec, 0xe1, 0xae, 0xfd, 0x77, 0xd6, 0x75, 0xee, 0x5d, 0x4a, 0x41, 0x4f, +- 0xac, 0x85, 0x0a, 0xe1, 0x0e, 0x48, 0x71, 0x86, 0x30, 0x52, 0xae, 0x6b, +- 0x58, 0xf3, 0x2b, 0x94, 0x6d, 0x07, 0x04, 0x34, 0xf1, 0xb6, 0x80, 0x1a, +- 0x53, 0x92, 0x85, 0x26, 0xdb, 0x4a, 0x92, 0xcb, 0x80, 0x5e, 0x6b, 0xac, +- 0x03, 0x83, 0x6e, 0x6a, 0x3e, 0xde, 0xd1, 0x07, 0xd1, 0x36, 0x1e, 0xf3, +- 0x95, 0x38, 0xe4, 0x74, 0x10, 0xe5, 0xd7, 0x50, 0xee, 0xb3, 0x66, 0x6a, +- 0x7f, 0x65, 0x49, 0x5f, 0x4b, 0x9c, 0x09, 0xee, 0x31, 0x36, 0x9d, 0x73, +- 0x4b, 0x31, 0x47, 0xde, 0x26, 0xce, 0x3b, 0x43, 0x22, 0x83, 0x09, 0xa7, +- 0x28, 0xff, 0x05, 0xed, 0x89, 0x58, 0x56, 0xfe, 0xb7, 0x4f, 0xbb, 0xc0, +- 0x43, 0xcf, 0xeb, 0x59, 0xf5, 0xc4, 0x7a, 0x8e, 0xcb, 0xa0, 0x2e, 0x24, +- 0xb3, 0xd0, 0x31, 0x05, 0x97, 0xeb, 0x71, 0xfe, 0xf8, 0x2c, 0xd7, 0xcd, +- 0x37, 0x7d, 0x7d, 0x20, 0xd9, 0x80, 0xc7, 0x36, 0xf2, 0xe5, 0xa4, 0x95, +- 0x6f, 0x12, 0x57, 0x19, 0x71, 0x9b, 0x1a, 0x66, 0x0d, 0x6b, 0x1b, 0x4e, +- 0xf0, 0x6b, 0x16, 0x34, 0x49, 0xd8, 0xe2, 0xe0, 0x9b, 0x73, 0x01, 0xff, +- 0x1c, 0x82, 0xde, 0xa4, 0x2c, 0x42, 0x3f, 0x96, 0x2b, 0x9c, 0xef, 0x33, +- 0x56, 0xe0, 0xb2, 0x3f, 0x3f, 0xcf, 0x86, 0x73, 0xeb, 0xf9, 0xca, 0xcd, +- 0xd7, 0x0c, 0xef, 0x2b, 0x3d, 0x88, 0xf9, 0x4a, 0x1d, 0xf3, 0x95, 0xc8, +- 0xb3, 0x07, 0x94, 0xae, 0x39, 0x4e, 0xfc, 0x9d, 0x47, 0xdb, 0x2d, 0xd0, +- 0x08, 0xf9, 0x81, 0xfc, 0x41, 0x5e, 0x7d, 0xb7, 0x8d, 0xfd, 0x76, 0xe0, +- 0x76, 0x06, 0x72, 0x98, 0xbc, 0x11, 0x96, 0x7c, 0x94, 0xf5, 0x8f, 0x1b, +- 0x98, 0x20, 0x13, 0xd4, 0xfb, 0xf1, 0x1e, 0x5f, 0x3e, 0x82, 0x16, 0x01, +- 0xdb, 0xf3, 0x6a, 0x8f, 0xb6, 0xe7, 0x01, 0x37, 0x9d, 0x30, 0x72, 0xdf, +- 0x9e, 0x91, 0xdb, 0x3e, 0xbc, 0x3c, 0x2b, 0xca, 0x55, 0xb1, 0xd6, 0x33, +- 0x61, 0xc8, 0x70, 0x5b, 0xf2, 0x69, 0xd0, 0x66, 0x3a, 0x60, 0xe4, 0xc3, +- 0x8b, 0xc6, 0x56, 0xd2, 0x38, 0x0e, 0x2a, 0x3d, 0xbe, 0x88, 0x79, 0x4f, +- 0x00, 0x46, 0xce, 0x19, 0xb4, 0xd6, 0x2a, 0x11, 0xe8, 0x6c, 0xc0, 0xe6, +- 0x24, 0xe2, 0x80, 0x09, 0xef, 0x7e, 0x9f, 0x88, 0x2c, 0x6c, 0xfa, 0xeb, +- 0x2e, 0xb6, 0xf5, 0x45, 0x49, 0xe1, 0xdb, 0x99, 0x0d, 0xec, 0xd0, 0xc6, +- 0xcc, 0xc9, 0xca, 0x99, 0x96, 0xed, 0x92, 0x06, 0xdd, 0xd1, 0x86, 0x44, +- 0x26, 0x37, 0x32, 0xef, 0x06, 0xbf, 0xa1, 0x1e, 0x63, 0xca, 0xcd, 0x52, +- 0xc4, 0x76, 0x5d, 0x94, 0x94, 0x3f, 0x27, 0xba, 0x6f, 0xb8, 0x3e, 0xbd, +- 0x0c, 0x49, 0xc8, 0x6d, 0xb5, 0x36, 0x70, 0x26, 0x47, 0x9b, 0xbf, 0x6c, +- 0x7d, 0x35, 0xa8, 0xed, 0x15, 0xdb, 0xfb, 0xa9, 0xa5, 0xd7, 0x8c, 0x4f, +- 0x27, 0x15, 0x1e, 0x62, 0x5d, 0xfa, 0xdd, 0x35, 0xef, 0xd7, 0x22, 0x46, +- 0x87, 0x99, 0xf7, 0xf9, 0xa0, 0xb6, 0x7f, 0xc2, 0x3d, 0xe4, 0xa3, 0xa0, +- 0xe7, 0xf4, 0xe0, 0x9c, 0xc3, 0x21, 0x6f, 0x6a, 0x7c, 0x43, 0xf5, 0x2b, +- 0x99, 0x7e, 0xd1, 0x6e, 0x3d, 0xee, 0xd4, 0xf4, 0x88, 0xa2, 0xa1, 0x4f, +- 0x4f, 0x0f, 0xab, 0xf2, 0xb3, 0xd3, 0x29, 0x55, 0x2e, 0x4e, 0xbb, 0xaa, +- 0x3c, 0xaf, 0xfa, 0x5b, 0xde, 0x90, 0xa9, 0x1f, 0x9d, 0x8e, 0xab, 0x72, +- 0xdc, 0x94, 0x69, 0x53, 0x66, 0x4c, 0x39, 0x69, 0x4a, 0xcf, 0x94, 0x59, +- 0x53, 0x16, 0xcc, 0x7c, 0x53, 0xe6, 0xfd, 0x98, 0x29, 0x67, 0x4c, 0x79, +- 0xdc, 0x94, 0x1f, 0x31, 0xe5, 0x09, 0x03, 0xd7, 0xbc, 0x29, 0x3f, 0x6e, +- 0xea, 0x4f, 0x1b, 0x38, 0x3f, 0x03, 0x78, 0x1e, 0x09, 0xed, 0xd0, 0xca, +- 0x69, 0x4d, 0x5f, 0x15, 0x47, 0xca, 0x9b, 0xdc, 0x7f, 0x1c, 0x32, 0x25, +- 0x88, 0xb3, 0x04, 0xbf, 0x3b, 0xa4, 0x09, 0x17, 0x72, 0x38, 0x88, 0x33, +- 0xe4, 0xf3, 0x69, 0xf9, 0x53, 0xf4, 0x1d, 0xbd, 0xe0, 0xc8, 0x62, 0x95, +- 0xfa, 0xf5, 0x5b, 0xf2, 0x6a, 0x85, 0xe7, 0xf1, 0xbc, 0xdc, 0xa8, 0xa4, +- 0xe2, 0x41, 0x8b, 0x74, 0x94, 0x98, 0x7c, 0x45, 0x12, 0x90, 0xfd, 0x63, +- 0x71, 0x96, 0xd7, 0xa8, 0x54, 0xd0, 0xef, 0xa0, 0x5a, 0xfb, 0x79, 0x01, +- 0x4c, 0x72, 0xa5, 0xd2, 0x0d, 0x99, 0xf5, 0x4a, 0x8b, 0x7a, 0xfd, 0xfc, +- 0xa6, 0xc8, 0xc8, 0x05, 0xe2, 0xf9, 0x5b, 0xb2, 0x51, 0x21, 0xde, 0x9f, +- 0x87, 0xad, 0x90, 0x4a, 0xbf, 0x28, 0x89, 0xd1, 0x8b, 0xc2, 0xf9, 0xc6, +- 0xd2, 0x28, 0xe3, 0x65, 0xfc, 0xce, 0x41, 0xde, 0x76, 0x4f, 0xe8, 0xf9, +- 0x86, 0xcd, 0x7c, 0x2e, 0xec, 0xc2, 0x5b, 0x0e, 0x65, 0xe0, 0x7f, 0xb5, +- 0xf4, 0x9e, 0xb4, 0x3c, 0xcc, 0x3a, 0x41, 0x96, 0xb6, 0xcf, 0x23, 0xf6, +- 0xc4, 0xf5, 0x16, 0xe4, 0x31, 0xf9, 0xdf, 0xd4, 0x6d, 0x1b, 0xfe, 0x92, +- 0x9a, 0xed, 0x81, 0x3e, 0x33, 0xc3, 0x58, 0x83, 0xef, 0x71, 0xd8, 0x9a, +- 0x52, 0x22, 0x1e, 0x8a, 0x95, 0x5f, 0xb5, 0xb2, 0x41, 0x6d, 0x9f, 0x6a, +- 0x19, 0xc1, 0x76, 0x4b, 0xf2, 0xe8, 0xbb, 0x60, 0x64, 0x66, 0xa1, 0x79, +- 0x4b, 0xc9, 0x8d, 0xaf, 0x2b, 0x1a, 0x4e, 0x9c, 0x2f, 0x09, 0x75, 0x86, +- 0x1d, 0xa0, 0x4c, 0xbb, 0x92, 0xae, 0xb7, 0x16, 0xaa, 0x94, 0xc1, 0xc3, +- 0x52, 0xac, 0x0d, 0x97, 0x6c, 0x94, 0xa7, 0xeb, 0x31, 0x39, 0x5d, 0xe1, +- 0x3c, 0xfb, 0xd1, 0xc7, 0x45, 0x1d, 0x18, 0x6b, 0x90, 0xf2, 0x98, 0x6b, +- 0xbe, 0x6e, 0xe9, 0x35, 0xb1, 0x07, 0x77, 0xcb, 0xfa, 0x44, 0xf3, 0x9a, +- 0x55, 0xac, 0xd3, 0x4e, 0x42, 0x7d, 0xb3, 0x53, 0x66, 0xfb, 0xf2, 0xfa, +- 0x79, 0xac, 0x5d, 0xc0, 0x7a, 0x59, 0x25, 0xb3, 0xba, 0x21, 0xf7, 0x7e, +- 0x52, 0xf9, 0x72, 0xab, 0x5c, 0x1d, 0x95, 0x8b, 0x9b, 0x71, 0x39, 0x52, +- 0x19, 0x97, 0x8d, 0x4d, 0x4f, 0x0a, 0x95, 0xb4, 0xac, 0xa3, 0x4f, 0xbe, +- 0x92, 0x91, 0xb5, 0xcd, 0x63, 0xea, 0xac, 0x2f, 0x42, 0x2e, 0x6d, 0xa0, +- 0x4f, 0x63, 0x73, 0x12, 0x3f, 0xdf, 0x1e, 0x88, 0xa1, 0xdf, 0x10, 0xfa, +- 0x88, 0xf5, 0xb3, 0xca, 0x3d, 0xc0, 0x21, 0xe6, 0xae, 0xfa, 0xb6, 0xc1, +- 0xb8, 0x2c, 0x54, 0x79, 0x4e, 0x2f, 0x4c, 0x6f, 0xac, 0xc4, 0xb2, 0xd4, +- 0x77, 0xa7, 0x9b, 0xc3, 0xe0, 0x53, 0xe8, 0xef, 0x2a, 0x65, 0x42, 0x50, +- 0x8a, 0x90, 0xb5, 0x0d, 0xc0, 0x46, 0x58, 0x1b, 0xb0, 0xdf, 0x8b, 0xcd, +- 0x21, 0x94, 0x0e, 0x4a, 0xac, 0x03, 0xd8, 0x8b, 0x4d, 0x17, 0x65, 0x0c, +- 0xa5, 0xd6, 0xed, 0x27, 0x9b, 0x9c, 0x3f, 0xab, 0x74, 0x90, 0xc6, 0xf1, +- 0xd4, 0x1d, 0xb6, 0x7a, 0xc0, 0x5b, 0xb4, 0x8a, 0x2b, 0x62, 0xe7, 0xd2, +- 0x21, 0xfa, 0x0b, 0x90, 0x2b, 0x37, 0x0f, 0x68, 0x58, 0x3e, 0x1b, 0xa0, +- 0xdc, 0x09, 0xba, 0xe7, 0x81, 0xaf, 0x5e, 0xc9, 0x06, 0x69, 0x73, 0xf1, +- 0x59, 0x5a, 0x01, 0xcf, 0xa5, 0xad, 0x12, 0x0c, 0x50, 0x5f, 0x45, 0xd9, +- 0xa7, 0xde, 0xa2, 0x5c, 0xca, 0xd5, 0xb4, 0x6d, 0x5e, 0x6a, 0xdb, 0xe6, +- 0xeb, 0xa8, 0xb7, 0x20, 0x3b, 0xe0, 0x9b, 0xd4, 0x79, 0x1e, 0x03, 0x98, +- 0x33, 0x6b, 0x15, 0x2a, 0xfe, 0x79, 0xd6, 0x5b, 0x4f, 0x54, 0x69, 0xaf, +- 0xd1, 0x6e, 0x53, 0xf2, 0x49, 0x92, 0xcb, 0x71, 0x23, 0x83, 0x23, 0x8a, +- 0x37, 0x88, 0x83, 0xe4, 0x72, 0xda, 0xd4, 0x75, 0x77, 0xd4, 0xf9, 0xb2, +- 0xfa, 0x73, 0x80, 0x61, 0x48, 0x9d, 0xad, 0xed, 0x4d, 0x59, 0x39, 0x65, +- 0x2b, 0xb6, 0x5a, 0x79, 0x37, 0x24, 0xc5, 0xf1, 0x3f, 0xc2, 0x9e, 0xd8, +- 0x56, 0x72, 0x40, 0x5a, 0xe0, 0xbb, 0xca, 0x07, 0xe6, 0xdc, 0x84, 0xb2, +- 0xb3, 0x72, 0x15, 0xf8, 0x38, 0x5a, 0xd5, 0x95, 0xfa, 0xa1, 0x87, 0xdc, +- 0x25, 0xd2, 0x53, 0xbd, 0xb5, 0x0c, 0x9c, 0xce, 0x2c, 0x15, 0xac, 0xe4, +- 0x12, 0xe8, 0x63, 0x10, 0xb6, 0x87, 0x1b, 0x91, 0xdc, 0x65, 0xd2, 0x11, +- 0xfb, 0xb0, 0xbe, 0x4b, 0x66, 0xa2, 0xbb, 0x6d, 0x9b, 0x87, 0x0e, 0x68, +- 0x9d, 0x8f, 0xbe, 0x4b, 0x70, 0xe6, 0x7a, 0xb5, 0x9f, 0x92, 0x5c, 0xa5, +- 0x9c, 0x2d, 0x40, 0xd7, 0x53, 0xe7, 0xf4, 0xc0, 0x9e, 0x61, 0x3d, 0xe7, +- 0x44, 0xdb, 0xc5, 0xac, 0x05, 0xfd, 0x66, 0x97, 0x95, 0x8d, 0x3e, 0x89, +- 0xf2, 0xde, 0x20, 0x6d, 0x5b, 0xea, 0x90, 0xe4, 0xaa, 0x3f, 0x47, 0x27, +- 0x3e, 0xf6, 0x29, 0x9d, 0x34, 0xe0, 0x0d, 0xa8, 0x79, 0x61, 0x97, 0x58, +- 0x73, 0x6a, 0xde, 0x58, 0xc7, 0xbc, 0x68, 0xbb, 0xf8, 0xb7, 0x01, 0x3d, +- 0x0f, 0xf0, 0xac, 0xf6, 0xc4, 0x36, 0x8e, 0x29, 0x58, 0x79, 0xd8, 0x4e, +- 0x33, 0x69, 0x5b, 0x02, 0x83, 0x7e, 0x5f, 0xbd, 0xaf, 0x02, 0xf6, 0x95, +- 0xc3, 0xbe, 0xec, 0xc1, 0xdd, 0xfb, 0x2a, 0x05, 0xf4, 0xbe, 0x06, 0x3a, +- 0x60, 0x8a, 0xee, 0x5a, 0xbf, 0x73, 0x5f, 0x68, 0xbb, 0xb8, 0x7b, 0x8e, +- 0xc7, 0x06, 0xf4, 0x1c, 0xd1, 0x8e, 0x39, 0x06, 0x77, 0xcd, 0x01, 0x7a, +- 0x8e, 0x72, 0xfc, 0xe0, 0x1e, 0xe3, 0x5f, 0xef, 0xd5, 0xe3, 0x39, 0xa6, +- 0x0b, 0x7a, 0x58, 0x9d, 0x75, 0x58, 0xc9, 0xd4, 0xb6, 0xad, 0x76, 0x1a, +- 0x3a, 0xaf, 0x73, 0xcc, 0x9d, 0x76, 0xa6, 0xad, 0xec, 0xcc, 0x3b, 0xe8, +- 0xcc, 0x7a, 0x14, 0x3e, 0x73, 0x6a, 0x19, 0xbe, 0x73, 0xe5, 0xed, 0x58, +- 0xf7, 0xcf, 0xe0, 0x87, 0x42, 0x16, 0x8d, 0xd2, 0x2f, 0x98, 0x14, 0xe5, +- 0x97, 0x8e, 0xc2, 0xff, 0x75, 0xf6, 0x29, 0x5b, 0xb4, 0x38, 0x3a, 0xee, +- 0xfb, 0x0b, 0xd6, 0x2c, 0xe4, 0x46, 0x71, 0x14, 0x36, 0x7d, 0x14, 0xf8, +- 0x72, 0x47, 0x30, 0x8e, 0xf0, 0xbc, 0x3b, 0x44, 0x9f, 0xf5, 0x99, 0xea, +- 0x2c, 0xde, 0xf7, 0xa1, 0xfd, 0xe7, 0x06, 0xce, 0x3e, 0xf4, 0xf9, 0x57, +- 0xa8, 0x63, 0x1b, 0xfb, 0x70, 0x8a, 0x1f, 0xe0, 0xfd, 0x41, 0xf4, 0x01, +- 0x4f, 0x81, 0x53, 0x6c, 0xf7, 0x30, 0x7e, 0x2f, 0xa3, 0xee, 0xdd, 0xa8, +- 0xbb, 0x8e, 0xba, 0x43, 0x78, 0xff, 0xe1, 0xae, 0x79, 0xdf, 0x81, 0xf7, +- 0xcf, 0xa1, 0x1d, 0xfb, 0x77, 0x5e, 0x44, 0xfb, 0x83, 0xf8, 0xfd, 0xc5, +- 0xae, 0x3e, 0x8d, 0x5d, 0xef, 0xbe, 0xbc, 0x79, 0xc9, 0xf0, 0xc0, 0x8e, +- 0x6f, 0x07, 0xfe, 0xb1, 0xa8, 0x8f, 0x0a, 0x15, 0xca, 0x9b, 0xb0, 0x3c, +- 0xb2, 0xe2, 0xcb, 0x1c, 0x91, 0x79, 0xc8, 0xfa, 0x42, 0x45, 0xbc, 0x6e, +- 0x19, 0x9e, 0xfc, 0x31, 0x64, 0xfa, 0x3c, 0xf0, 0x5a, 0x80, 0x7d, 0x71, +- 0x74, 0x25, 0x8c, 0xe7, 0x21, 0xc8, 0x3b, 0xc9, 0x74, 0x09, 0x79, 0x3e, +- 0x02, 0xd9, 0xd2, 0x0b, 0x9e, 0x57, 0x3e, 0x88, 0x3c, 0x0e, 0xb9, 0x34, +- 0x8b, 0xbe, 0xb3, 0xe8, 0xf3, 0xd1, 0xe6, 0xff, 0x31, 0xb4, 0xec, 0xc3, +- 0xf0, 0xec, 0x2e, 0x18, 0xc2, 0xe2, 0xae, 0x92, 0x1f, 0x5f, 0x98, 0x9e, +- 0x5b, 0x89, 0xc8, 0xf0, 0xaa, 0x9d, 0xa4, 0xb3, 0x3f, 0xb2, 0xca, 0x98, +- 0x84, 0x8c, 0x04, 0x85, 0xb2, 0x5f, 0xc6, 0x43, 0xb0, 0xd1, 0x02, 0xde, +- 0x30, 0x74, 0x94, 0x7a, 0x97, 0x2c, 0x60, 0xcb, 0x36, 0x77, 0x62, 0x13, +- 0x47, 0xda, 0xb1, 0x89, 0x21, 0xe8, 0x88, 0xd7, 0x83, 0x5a, 0x5e, 0x45, +- 0x40, 0x27, 0x6f, 0x01, 0xfe, 0x29, 0x5b, 0x42, 0xe0, 0x1f, 0x07, 0xbc, +- 0xf3, 0x26, 0xda, 0x6f, 0xd4, 0x5b, 0xa0, 0x77, 0xc8, 0x38, 0x9b, 0xf5, +- 0x2c, 0xd1, 0x96, 0x21, 0x0f, 0xe0, 0xbd, 0xd1, 0xc9, 0x6b, 0xe7, 0xb4, +- 0x8d, 0x75, 0x97, 0x6f, 0xf3, 0xa0, 0xa3, 0x69, 0x91, 0xf6, 0xfa, 0xe1, +- 0xd0, 0x9d, 0x7b, 0xfc, 0xa3, 0x5d, 0x7b, 0x0c, 0x4a, 0x72, 0x89, 0xf8, +- 0x8d, 0xa8, 0xbd, 0xfa, 0xf8, 0x2d, 0x2a, 0x5b, 0x7e, 0x1c, 0x3e, 0x89, +- 0x40, 0x9a, 0x2b, 0x5b, 0x14, 0x3a, 0xb1, 0x0f, 0xb2, 0x9e, 0x72, 0x9e, +- 0xf8, 0x0e, 0x03, 0x87, 0x11, 0xfc, 0x1c, 0xfc, 0x76, 0x70, 0x7a, 0xb2, +- 0xbd, 0x3f, 0x7f, 0x0f, 0xeb, 0x90, 0x55, 0x2c, 0x09, 0x3f, 0xf0, 0x71, +- 0x91, 0xcf, 0x90, 0xaf, 0x7d, 0x94, 0xb7, 0x3e, 0x4c, 0x8f, 0xed, 0x82, +- 0x89, 0xb8, 0x21, 0x4c, 0xf5, 0x16, 0x6c, 0x8b, 0x28, 0xa3, 0x60, 0xa7, +- 0x9b, 0xd4, 0x29, 0x5c, 0x73, 0x92, 0xf6, 0xb6, 0x81, 0x93, 0x7a, 0xc5, +- 0x93, 0x73, 0x95, 0xb7, 0x1b, 0xb8, 0x78, 0xbe, 0xb0, 0xf9, 0x96, 0xb8, +- 0x7e, 0x54, 0xe9, 0x1e, 0x0d, 0xd3, 0x6e, 0xfc, 0xd0, 0x3f, 0x27, 0x7e, +- 0xa8, 0x0f, 0x88, 0x4b, 0xda, 0xd4, 0xc4, 0xe7, 0xef, 0x00, 0x9f, 0xec, +- 0xeb, 0x1a, 0xdd, 0xf2, 0x2e, 0x03, 0xd7, 0xdd, 0xfa, 0xf8, 0xf4, 0x1d, +- 0xfa, 0xd8, 0xc7, 0xf1, 0x5e, 0x67, 0xf1, 0xfb, 0x7d, 0xbe, 0xcc, 0x1d, +- 0x5e, 0xdd, 0xab, 0x7d, 0xd9, 0xb4, 0xb3, 0xad, 0xb3, 0xfe, 0xdb, 0x7d, +- 0xfe, 0x19, 0x0e, 0x2f, 0xef, 0x6e, 0xeb, 0x3b, 0xb0, 0x33, 0x66, 0xf7, +- 0x7c, 0x3f, 0xee, 0xdb, 0xdb, 0xaf, 0xdd, 0xf1, 0xeb, 0xe0, 0xab, 0xd8, +- 0x3b, 0x7b, 0xc9, 0xda, 0xf3, 0xcd, 0x82, 0xad, 0xf7, 0xc2, 0x3e, 0x68, +- 0x6b, 0x6e, 0xf5, 0x07, 0x95, 0x6e, 0xcc, 0xda, 0xf4, 0x63, 0x4a, 0x6b, +- 0x7c, 0xbe, 0x07, 0x65, 0xe7, 0xd8, 0x21, 0xf0, 0x40, 0x16, 0x7d, 0x39, +- 0xc7, 0xee, 0xf1, 0xbe, 0x8d, 0x94, 0x96, 0x85, 0x5a, 0x08, 0xed, 0x89, +- 0x6c, 0x49, 0x1e, 0x86, 0xaf, 0x98, 0x98, 0xa2, 0xdf, 0x00, 0x7f, 0x79, +- 0x46, 0xe4, 0x98, 0x94, 0x6b, 0x1f, 0x94, 0x85, 0x95, 0x96, 0xbc, 0x1f, +- 0x7a, 0xf0, 0xf7, 0xa0, 0x47, 0xe5, 0x12, 0x84, 0xd7, 0x25, 0x1c, 0xc6, +- 0xa5, 0xa8, 0xd8, 0x4f, 0xc1, 0x96, 0xbf, 0x10, 0x93, 0xe0, 0x05, 0xd2, +- 0x5e, 0xca, 0x79, 0xbf, 0x48, 0xbf, 0x2d, 0x57, 0xe1, 0x08, 0x25, 0x26, +- 0xb3, 0x92, 0x82, 0xfd, 0x37, 0xe6, 0x34, 0x50, 0x96, 0x25, 0x35, 0xfa, +- 0xb4, 0xa0, 0xef, 0x25, 0xf4, 0xc5, 0xb8, 0x9e, 0x8d, 0x38, 0x7e, 0x83, +- 0xd2, 0xbb, 0x41, 0x18, 0x92, 0xa6, 0x24, 0x2c, 0x3f, 0x6c, 0xd1, 0xd7, +- 0x7d, 0x66, 0x33, 0x0c, 0xdd, 0x14, 0x97, 0xe7, 0x20, 0x67, 0x9f, 0x55, +- 0xf1, 0x17, 0xb7, 0xed, 0x8f, 0x3e, 0x7a, 0x18, 0x74, 0xb7, 0x2c, 0xe1, +- 0xa8, 0xf7, 0x73, 0x59, 0x59, 0x6e, 0xc1, 0xef, 0xa1, 0xac, 0x7f, 0x00, +- 0xf2, 0x2a, 0xf1, 0xa5, 0x12, 0x6d, 0x49, 0x37, 0x03, 0xd8, 0x4b, 0x32, +- 0x73, 0xf8, 0x5d, 0x03, 0x9a, 0x3e, 0x8e, 0x49, 0x70, 0xb9, 0x00, 0xfb, +- 0xf9, 0x8c, 0x2c, 0xa6, 0xe1, 0x9f, 0xda, 0xa5, 0x56, 0xc0, 0x75, 0x63, +- 0xd0, 0xdb, 0xd0, 0xa7, 0x2b, 0xf4, 0x87, 0xe5, 0xc8, 0x32, 0xfb, 0x9c, +- 0x01, 0x6d, 0x75, 0x01, 0x77, 0xdd, 0x72, 0x36, 0x9a, 0x28, 0xe5, 0xc1, +- 0x4f, 0xb6, 0xdb, 0x0f, 0x5e, 0x66, 0x49, 0xfd, 0xf6, 0x34, 0xe8, 0x87, +- 0xcf, 0x38, 0xce, 0x55, 0xd6, 0x27, 0x51, 0xb2, 0xde, 0x15, 0x7b, 0x29, +- 0x8c, 0xb9, 0xa0, 0x93, 0x2e, 0x97, 0xe4, 0x6c, 0xe6, 0x98, 0x34, 0x6a, +- 0xf0, 0xc9, 0x33, 0xb0, 0xa3, 0xea, 0x9e, 0x34, 0x2a, 0xb4, 0x9f, 0x4e, +- 0x81, 0x1f, 0x5e, 0x41, 0x39, 0x8f, 0xf2, 0x16, 0xca, 0x8f, 0xa3, 0x7c, +- 0x0d, 0x25, 0x61, 0x3f, 0x25, 0x8d, 0xfa, 0x55, 0xcc, 0xcd, 0x39, 0xa6, +- 0x0c, 0xcc, 0xf0, 0x21, 0x0f, 0x9f, 0x82, 0x9d, 0xe3, 0xd7, 0x9f, 0x12, +- 0x69, 0x7c, 0x0c, 0xbf, 0x96, 0x7a, 0xa7, 0x8f, 0xb9, 0x90, 0x99, 0x84, +- 0xbd, 0x2b, 0xd6, 0xd9, 0xcc, 0xc7, 0xcd, 0x3c, 0x1f, 0xc3, 0x7a, 0xd7, +- 0xb1, 0x76, 0x18, 0xe7, 0xd9, 0x92, 0x47, 0xd3, 0x67, 0xe4, 0x93, 0xe9, +- 0x7b, 0x65, 0x62, 0x20, 0x5c, 0x0a, 0x7b, 0xdc, 0x3f, 0xed, 0xda, 0xbd, +- 0xf6, 0xef, 0xef, 0x9b, 0x7b, 0x8e, 0x60, 0x2f, 0xfb, 0xb5, 0xed, 0x66, +- 0xff, 0x13, 0xe3, 0x73, 0x58, 0x92, 0x1c, 0xe1, 0x7c, 0x9e, 0x04, 0x96, +- 0x47, 0x9c, 0x8c, 0x3d, 0x06, 0xeb, 0x3d, 0x85, 0xdf, 0x19, 0xd0, 0x8a, +- 0x7b, 0x3e, 0x69, 0xff, 0x47, 0xc0, 0x84, 0xb6, 0x06, 0xd7, 0x11, 0x2b, +- 0x78, 0xe8, 0x26, 0xf6, 0x56, 0x92, 0xee, 0x43, 0x9e, 0xdc, 0x6e, 0xf2, +- 0x19, 0x92, 0xf2, 0xd2, 0x31, 0xf9, 0x71, 0xed, 0xba, 0x9c, 0xab, 0x1d, +- 0x93, 0x97, 0x51, 0x2e, 0xd6, 0x4a, 0xc0, 0x23, 0x7d, 0x46, 0xce, 0xd1, +- 0xc2, 0xb9, 0x50, 0x2e, 0xdf, 0x1f, 0x9b, 0xc7, 0xf9, 0xcd, 0x3a, 0x2d, +- 0xd9, 0x48, 0x97, 0x64, 0x63, 0x12, 0x63, 0xea, 0x3d, 0x12, 0xfa, 0x2a, +- 0xf7, 0xdb, 0x27, 0xf9, 0x5a, 0x49, 0x0a, 0x19, 0xfa, 0x34, 0xbd, 0x92, +- 0x87, 0x4d, 0x0e, 0x3b, 0xe8, 0x8c, 0x8e, 0xb3, 0xb9, 0xb1, 0x22, 0x6c, +- 0xf8, 0x85, 0xe6, 0xeb, 0x56, 0xa3, 0x6d, 0xff, 0x6f, 0x59, 0xcf, 0xc2, +- 0x76, 0xfd, 0x0e, 0xe4, 0xc6, 0x73, 0xb0, 0x09, 0x9f, 0xbd, 0x83, 0xc7, +- 0x48, 0x23, 0xd7, 0xac, 0x46, 0x7d, 0x94, 0x7c, 0x66, 0xf8, 0x01, 0x63, +- 0xe1, 0xe7, 0x34, 0x6a, 0xb7, 0x0c, 0xfd, 0x29, 0x5b, 0x00, 0xe7, 0x42, +- 0xbd, 0xf2, 0x77, 0xf0, 0xaf, 0x28, 0x77, 0x7c, 0xbd, 0xaf, 0xfd, 0x86, +- 0x3a, 0x60, 0xcd, 0x47, 0x13, 0x80, 0x4a, 0xa4, 0x5e, 0x2f, 0x28, 0x5c, +- 0xb9, 0xcb, 0x43, 0x52, 0xab, 0x12, 0xbf, 0x09, 0xc7, 0xb6, 0x95, 0x5d, +- 0x0b, 0xbc, 0xba, 0x38, 0x1f, 0xbf, 0x3d, 0x01, 0xff, 0xe1, 0x8c, 0x38, +- 0x13, 0xbd, 0xd8, 0x13, 0x9f, 0x45, 0x66, 0x2e, 0xff, 0x3a, 0x19, 0xd0, +- 0x05, 0xbf, 0x3e, 0x84, 0xb3, 0x8c, 0xc8, 0x59, 0xd8, 0xff, 0xe7, 0x40, +- 0x47, 0x9f, 0xaf, 0x0c, 0xc9, 0xf9, 0x4a, 0x1c, 0xfe, 0x16, 0xed, 0x94, +- 0xe5, 0xe9, 0xe4, 0x3a, 0xcb, 0x27, 0xa6, 0x53, 0x75, 0x96, 0x5f, 0x32, +- 0xfe, 0xe2, 0x97, 0x8d, 0x1f, 0xb9, 0x3e, 0xad, 0x7d, 0xb8, 0xaf, 0x4d, +- 0x8f, 0xaa, 0xb2, 0x39, 0xbd, 0x13, 0x3b, 0x09, 0x1b, 0xbd, 0x9d, 0xa1, +- 0x7e, 0x06, 0x8c, 0x12, 0x3c, 0x09, 0x7a, 0x9a, 0x87, 0xdc, 0xce, 0xc1, +- 0xf7, 0x38, 0x0b, 0x1f, 0xa4, 0xd8, 0x84, 0x4c, 0xf0, 0xd2, 0x28, 0xc5, +- 0xfc, 0xf9, 0x63, 0xbb, 0x18, 0xdf, 0xe4, 0x99, 0x19, 0xff, 0x2b, 0x4d, +- 0xff, 0xab, 0xf3, 0x8f, 0xf3, 0x81, 0x36, 0xa9, 0x2b, 0x7f, 0x09, 0x9f, +- 0x51, 0x82, 0xc5, 0x0c, 0xc7, 0xa6, 0xe9, 0xaf, 0xca, 0x36, 0xec, 0x83, +- 0xb0, 0xf7, 0x3d, 0x09, 0x3f, 0xd5, 0x6a, 0xbd, 0x0a, 0x59, 0x53, 0x82, +- 0xcf, 0x68, 0x5b, 0xa8, 0x5f, 0x67, 0x1b, 0xe5, 0xc8, 0x98, 0x73, 0x1b, +- 0x34, 0x97, 0x3d, 0x2e, 0xf2, 0x5d, 0xd4, 0x35, 0x56, 0x78, 0x06, 0xdf, +- 0xc7, 0x19, 0x98, 0x33, 0x51, 0x75, 0xec, 0x07, 0xfb, 0x3d, 0xca, 0x7d, +- 0x8c, 0x39, 0xdd, 0x18, 0x5f, 0x5f, 0xe7, 0x98, 0xc4, 0x24, 0xaf, 0x74, +- 0xbe, 0xbb, 0xae, 0xf7, 0x77, 0x34, 0x33, 0x2a, 0x57, 0x2b, 0x6a, 0x0e, +- 0xd0, 0xfa, 0xaf, 0x30, 0x66, 0x0b, 0x74, 0xcb, 0x18, 0x95, 0x27, 0x65, +- 0xe8, 0xa4, 0x72, 0x25, 0x05, 0xda, 0x09, 0xca, 0x6c, 0x8c, 0x60, 0xbb, +- 0xb2, 0x5d, 0xf9, 0x72, 0x97, 0x8e, 0x8f, 0xf0, 0x19, 0x3a, 0xac, 0x39, +- 0x23, 0xbc, 0x1b, 0x81, 0x7d, 0x83, 0x3d, 0x75, 0xe2, 0x42, 0xff, 0x15, +- 0x71, 0x16, 0x66, 0x8f, 0xea, 0x4f, 0xaf, 0x83, 0xf1, 0x66, 0x9d, 0x02, +- 0x14, 0x77, 0x1e, 0xeb, 0xa7, 0x2e, 0x05, 0x83, 0x8c, 0xa9, 0x27, 0x2f, +- 0x81, 0xad, 0x3c, 0x83, 0x8b, 0xa6, 0x4f, 0x6b, 0xbe, 0x2f, 0x4a, 0xda, +- 0x22, 0x0e, 0x12, 0xa5, 0x2d, 0x20, 0x7b, 0xc0, 0xbb, 0x21, 0x1f, 0x5a, +- 0xd5, 0x7b, 0xb6, 0x2f, 0x0a, 0xef, 0x5b, 0xe4, 0xf6, 0x4a, 0x22, 0x7d, +- 0x0b, 0xb2, 0x39, 0x1f, 0x4d, 0x83, 0x56, 0x3e, 0xd1, 0x05, 0x9e, 0x9e, +- 0xcc, 0xda, 0x3f, 0xe8, 0xd2, 0xb6, 0x20, 0x7c, 0x7e, 0xc6, 0x01, 0x2a, +- 0x59, 0x8c, 0xe9, 0x96, 0x7f, 0x11, 0xc4, 0x73, 0x93, 0xef, 0xb0, 0x73, +- 0x82, 0x1a, 0xbe, 0xb2, 0xc1, 0x21, 0xfc, 0x04, 0xd1, 0xb1, 0x5c, 0x4b, +- 0x3e, 0x04, 0x29, 0x2f, 0x98, 0x3f, 0x69, 0xd6, 0x4a, 0x5e, 0x0c, 0xb7, +- 0x6d, 0xba, 0xd4, 0xaa, 0x07, 0xdb, 0x22, 0x68, 0x7c, 0x22, 0xca, 0x18, +- 0xd9, 0xc3, 0xa6, 0xee, 0xb4, 0x8f, 0xc3, 0x2a, 0x5e, 0xc7, 0x7b, 0x24, +- 0xd2, 0xd6, 0x94, 0xa1, 0xad, 0x8f, 0x81, 0xb6, 0x4e, 0x29, 0xda, 0x6a, +- 0xc9, 0xab, 0xe9, 0xb4, 0x7c, 0x61, 0x4f, 0xfa, 0xda, 0xfd, 0x17, 0x01, +- 0xbc, 0xfc, 0x0d, 0xca, 0xc2, 0x17, 0xb1, 0x2e, 0xf4, 0x4e, 0xb9, 0x92, +- 0xc8, 0xce, 0xd2, 0x16, 0x82, 0x1e, 0x29, 0xc3, 0xe7, 0x4a, 0x5e, 0x1a, +- 0x52, 0x7d, 0x92, 0xd0, 0x29, 0x0d, 0xd0, 0x1b, 0xf1, 0x5b, 0xae, 0x40, +- 0x0e, 0x5f, 0x0a, 0x41, 0x6f, 0x91, 0x67, 0x65, 0xc0, 0x86, 0x6c, 0x60, +- 0xff, 0x06, 0x78, 0x27, 0x79, 0x29, 0x82, 0x32, 0xae, 0xe6, 0x6a, 0x54, +- 0x5c, 0x35, 0xbe, 0x51, 0x19, 0x55, 0xe3, 0x1a, 0xb0, 0x5f, 0x93, 0x97, +- 0x20, 0xdf, 0x33, 0x69, 0x19, 0xb9, 0x94, 0x91, 0xf8, 0x25, 0x4b, 0x8a, +- 0x33, 0xad, 0x56, 0x18, 0xb0, 0x8f, 0x5e, 0xea, 0x97, 0x5b, 0x2a, 0xb6, +- 0x1a, 0x56, 0xf1, 0xd6, 0xc5, 0xcc, 0x0c, 0x78, 0x93, 0xf8, 0xf3, 0x30, +- 0xa6, 0x00, 0xfd, 0x58, 0x90, 0xb3, 0x2b, 0xc4, 0x0f, 0xe3, 0xe5, 0xdb, +- 0xb1, 0x80, 0x24, 0x20, 0xcb, 0x8e, 0xcb, 0x7c, 0xad, 0x1b, 0xb2, 0x2c, +- 0x08, 0x1d, 0xf8, 0x50, 0xb7, 0xf4, 0x0e, 0x93, 0x1e, 0x80, 0x17, 0x0f, +- 0x73, 0x17, 0x24, 0x8f, 0x31, 0x85, 0x95, 0x9d, 0xfe, 0x45, 0xe9, 0x06, +- 0x4f, 0x1d, 0x97, 0x93, 0x35, 0xce, 0x13, 0x74, 0xca, 0x72, 0x10, 0x34, +- 0xe4, 0x3a, 0x47, 0x30, 0x0f, 0xf4, 0x76, 0xc7, 0x1f, 0xf9, 0x2f, 0xfb, +- 0x06, 0x34, 0xe9, 0xf3, 0x5d, 0xb8, 0xd4, 0xe5, 0xcd, 0x58, 0xdb, 0x19, +- 0x09, 0xce, 0x65, 0x3e, 0x60, 0x7d, 0x37, 0x93, 0xb1, 0xae, 0x65, 0xb2, +- 0xd6, 0xf5, 0x4c, 0xc1, 0xba, 0x01, 0xdd, 0xd4, 0xd8, 0x7c, 0x0e, 0xf4, +- 0x03, 0xdd, 0xcf, 0x98, 0x79, 0xfb, 0x0c, 0xa3, 0x26, 0x66, 0xf0, 0x9a, +- 0x6c, 0x54, 0x68, 0x3b, 0xb4, 0x1e, 0x9e, 0x4b, 0x97, 0xee, 0x01, 0x7c, +- 0x80, 0x83, 0xbe, 0xee, 0x8e, 0xee, 0x08, 0x79, 0xa3, 0xb2, 0xa6, 0x74, +- 0x47, 0x84, 0xba, 0x23, 0x9d, 0x97, 0xfd, 0xb2, 0x5d, 0x03, 0xff, 0x89, +- 0xb2, 0x83, 0x65, 0xbb, 0x1e, 0x95, 0x2f, 0x54, 0x7d, 0x5a, 0xe2, 0x7e, +- 0xcb, 0x6f, 0xea, 0x91, 0x80, 0x4c, 0x29, 0x7d, 0xdd, 0x27, 0x57, 0xd7, +- 0xe1, 0x0f, 0xc1, 0x5a, 0xb0, 0xef, 0x63, 0xac, 0xc0, 0x56, 0xbe, 0xb1, +- 0xf4, 0xf3, 0xee, 0xea, 0x2c, 0x70, 0xc5, 0xfb, 0x25, 0xec, 0xb3, 0x9f, +- 0x3b, 0xf2, 0xdf, 0xc7, 0xc1, 0x93, 0x7c, 0xb6, 0x24, 0x0f, 0xbb, 0x91, +- 0xf7, 0x5c, 0x79, 0xd8, 0x3d, 0xdb, 0x95, 0x31, 0xc0, 0x15, 0x80, 0x4d, +- 0x1e, 0x06, 0x1c, 0x55, 0xd5, 0xde, 0xed, 0x8a, 0x35, 0x07, 0x3d, 0x5c, +- 0x54, 0xf7, 0x57, 0x28, 0xd7, 0xf5, 0xda, 0x79, 0xf8, 0xab, 0xc5, 0xf1, +- 0x1e, 0xea, 0xb7, 0xd1, 0x12, 0xf9, 0x5e, 0xd9, 0xf1, 0x19, 0xf0, 0xdc, +- 0x57, 0xba, 0xa9, 0xdb, 0x8f, 0xa6, 0x27, 0xe5, 0x46, 0x85, 0xcf, 0x6c, +- 0x4f, 0xa4, 0x45, 0xc5, 0x8f, 0x2b, 0xd3, 0x8b, 0xee, 0x6b, 0x86, 0xc7, +- 0x6a, 0xa0, 0xf1, 0x53, 0xf2, 0x8d, 0xcd, 0x79, 0xf9, 0xf7, 0x9b, 0xb3, +- 0xb0, 0x4f, 0x4e, 0xc0, 0x3e, 0xf9, 0x08, 0x78, 0xf8, 0x38, 0x78, 0xf8, +- 0xe3, 0xa0, 0xfb, 0x19, 0x15, 0x77, 0xa8, 0x55, 0x12, 0x57, 0x4a, 0x2a, +- 0xce, 0xfd, 0x1a, 0x68, 0x7e, 0x42, 0x82, 0xab, 0x43, 0xc0, 0x6b, 0xa9, +- 0x15, 0x75, 0x5b, 0x0f, 0xc3, 0x06, 0xc1, 0x59, 0x97, 0x12, 0x41, 0x45, +- 0x23, 0xae, 0xf3, 0x69, 0xe0, 0xf2, 0x4d, 0x5e, 0xa2, 0xc6, 0x23, 0xde, +- 0xa8, 0x8d, 0x4a, 0xf1, 0x32, 0xfa, 0x2f, 0x47, 0x80, 0x37, 0xea, 0xc6, +- 0xc4, 0xf9, 0xa2, 0x6c, 0x81, 0x2e, 0xb2, 0xc0, 0xcf, 0x3b, 0xa4, 0x1c, +- 0x4d, 0x7c, 0x4d, 0x64, 0x52, 0x0e, 0x2d, 0x81, 0xa6, 0x97, 0x6c, 0xec, +- 0x99, 0xb8, 0xc4, 0xf3, 0x65, 0x4f, 0xec, 0x65, 0xca, 0xa2, 0x03, 0xc6, +- 0x37, 0xd1, 0xfa, 0xbe, 0x2e, 0x5c, 0x97, 0xeb, 0x7d, 0x46, 0xe6, 0xa1, +- 0x53, 0x61, 0x7f, 0x43, 0x66, 0xbb, 0x31, 0xac, 0x19, 0x9e, 0xbb, 0xec, +- 0x84, 0xe7, 0x2f, 0x73, 0x9e, 0xb0, 0x04, 0x96, 0x78, 0xb6, 0x9c, 0x07, +- 0x3c, 0x80, 0xb9, 0x53, 0x4b, 0xc4, 0xdb, 0x18, 0xc6, 0xfd, 0x63, 0xe8, +- 0x63, 0x4d, 0x57, 0xb9, 0x65, 0x2d, 0x1f, 0x72, 0x8d, 0x4e, 0x9d, 0x88, +- 0x33, 0x80, 0xfc, 0xc8, 0x36, 0xb4, 0x7e, 0x2b, 0x28, 0xfd, 0xa7, 0x75, +- 0xdf, 0x71, 0x81, 0x51, 0xd7, 0xeb, 0xaa, 0xfd, 0x04, 0x96, 0xb7, 0xa8, +- 0xef, 0xb1, 0x06, 0xc7, 0x84, 0x3a, 0xe0, 0xce, 0x40, 0xee, 0xdc, 0x1b, +- 0x26, 0xee, 0x1f, 0x83, 0x7e, 0x4d, 0x2e, 0xe9, 0x98, 0x7c, 0xf2, 0x72, +- 0x1a, 0xfb, 0x91, 0x41, 0x46, 0x17, 0x6c, 0xec, 0xe1, 0x7d, 0x4a, 0x7e, +- 0x4d, 0x40, 0x66, 0x39, 0xb2, 0x7e, 0x90, 0x67, 0x33, 0x28, 0x8d, 0xa7, +- 0xf9, 0xce, 0x33, 0xe2, 0x79, 0x93, 0x17, 0xa3, 0xd0, 0x2f, 0x38, 0xa7, +- 0xbe, 0x21, 0xa9, 0x6f, 0xb2, 0x6d, 0x48, 0xd1, 0x72, 0x10, 0x67, 0xb0, +- 0x58, 0x69, 0x3d, 0x9c, 0x4b, 0x97, 0x40, 0x6d, 0xc4, 0x39, 0xf1, 0x41, +- 0xbc, 0x8f, 0x03, 0x36, 0xe2, 0xb8, 0x8f, 0xba, 0x18, 0x75, 0xfb, 0xa5, +- 0x58, 0x23, 0x3d, 0xa3, 0xac, 0xef, 0x37, 0xbe, 0xde, 0x67, 0x78, 0x27, +- 0x84, 0xbd, 0x6b, 0x3a, 0x2e, 0x80, 0xa6, 0xca, 0xf0, 0xbb, 0xae, 0x2e, +- 0x49, 0xf8, 0x4d, 0x90, 0xcf, 0x9f, 0xa2, 0x0c, 0x05, 0x7d, 0x95, 0xd7, +- 0x27, 0x40, 0x6b, 0x7d, 0x90, 0x97, 0xad, 0xd6, 0x71, 0xd8, 0xc9, 0xa7, +- 0xd3, 0xc4, 0xd1, 0x4d, 0xe0, 0xa8, 0x3b, 0x76, 0x1a, 0xe7, 0xb5, 0xf6, +- 0xf4, 0x43, 0x4a, 0x5e, 0xc0, 0xd6, 0x51, 0x7a, 0x4b, 0xc7, 0x38, 0xd2, +- 0xb4, 0x8d, 0x14, 0x0f, 0xe7, 0x5c, 0xca, 0xc3, 0x3c, 0xf0, 0x30, 0xae, +- 0xe4, 0xb7, 0x96, 0x2d, 0x3d, 0x52, 0x3c, 0x9e, 0xc5, 0x7e, 0x27, 0x77, +- 0xf5, 0xcb, 0xe0, 0x1d, 0xb6, 0x5f, 0xf3, 0x43, 0x61, 0xc6, 0x43, 0x03, +- 0xde, 0xa4, 0x6c, 0x1c, 0x9c, 0x92, 0x8b, 0x07, 0x13, 0x93, 0xb3, 0x36, +- 0x75, 0xc2, 0x94, 0xd4, 0x9f, 0xce, 0xca, 0x5a, 0x55, 0xeb, 0xe6, 0x39, +- 0x77, 0x52, 0xf2, 0xcd, 0x02, 0xde, 0x3d, 0x94, 0xec, 0xef, 0xcb, 0x5d, +- 0x7f, 0x4f, 0x39, 0xee, 0x09, 0x32, 0x42, 0xeb, 0x5e, 0xdb, 0xee, 0xc6, +- 0xf9, 0x50, 0x2e, 0x7c, 0x10, 0xf5, 0x39, 0xc8, 0x36, 0x9e, 0x67, 0x0a, +- 0x67, 0x77, 0x4a, 0x9d, 0x53, 0x3e, 0x4d, 0x7f, 0x80, 0x63, 0x12, 0xb1, +- 0x39, 0xd4, 0xcf, 0x08, 0x75, 0x28, 0xf7, 0xe6, 0xcf, 0xe7, 0x19, 0xf8, +- 0x03, 0x8c, 0x31, 0xe1, 0xef, 0x33, 0x61, 0xf2, 0x64, 0xc0, 0xf5, 0xeb, +- 0xc7, 0xa0, 0x7f, 0x43, 0x6a, 0x8d, 0x72, 0x95, 0x75, 0x29, 0x87, 0xe3, +- 0xf3, 0x69, 0xbe, 0x8b, 0x3c, 0x66, 0xfc, 0xf2, 0xe3, 0xf0, 0x5b, 0xf3, +- 0xcd, 0xae, 0xdf, 0xa0, 0x7f, 0x77, 0x64, 0x9d, 0x96, 0xcb, 0xdb, 0x31, +- 0xc7, 0xc8, 0xde, 0x93, 0x35, 0xc6, 0xac, 0x2d, 0xe9, 0x82, 0x2c, 0x3d, +- 0x2a, 0xc3, 0x46, 0x8e, 0x72, 0x3f, 0x7d, 0x4a, 0xd7, 0xe5, 0x67, 0x62, +- 0x72, 0x6e, 0xed, 0xff, 0x85, 0xae, 0x7f, 0xbd, 0x5d, 0x57, 0xd8, 0xc3, +- 0xae, 0xbb, 0x79, 0x19, 0xf2, 0xa0, 0x0a, 0x59, 0x51, 0x85, 0xac, 0xa8, +- 0x42, 0x56, 0x54, 0x21, 0x2b, 0xaa, 0x90, 0x15, 0x55, 0xc8, 0x8a, 0xea, +- 0x8c, 0xd1, 0x9b, 0xa7, 0x21, 0x73, 0xe9, 0xf3, 0xd0, 0xcf, 0xe9, 0xb4, +- 0x05, 0xe2, 0x90, 0x25, 0xf4, 0x67, 0x12, 0xa5, 0x5b, 0xc0, 0xcd, 0xd7, +- 0xd3, 0xf4, 0xb9, 0x5b, 0xf2, 0x57, 0xe9, 0xce, 0xdd, 0xab, 0xf8, 0x86, +- 0x3c, 0x0a, 0x7c, 0x7d, 0x08, 0xf8, 0xfa, 0xf0, 0x5d, 0x39, 0x16, 0x7e, +- 0x4c, 0x64, 0xb8, 0x14, 0x80, 0xff, 0x39, 0x73, 0x07, 0xee, 0xe8, 0x7b, +- 0x63, 0x8d, 0xbb, 0x6c, 0x63, 0xfa, 0xdc, 0xa3, 0xea, 0xde, 0x7c, 0x03, +- 0x76, 0xf9, 0x8d, 0x74, 0x29, 0x12, 0x50, 0xf7, 0x73, 0x2e, 0x69, 0x67, +- 0x8f, 0xbf, 0x6f, 0x84, 0xb5, 0x5c, 0xd4, 0x67, 0x9f, 0xcf, 0xf4, 0x81, +- 0x0f, 0x68, 0xdf, 0xdd, 0x50, 0xf6, 0xdd, 0xd1, 0x74, 0x50, 0xb6, 0xa2, +- 0xd4, 0xa9, 0x3f, 0x92, 0x93, 0x2b, 0x91, 0x1e, 0xfa, 0xdf, 0x8b, 0xd5, +- 0x83, 0xb2, 0xad, 0x64, 0xca, 0x07, 0xd1, 0xd7, 0x93, 0x79, 0xd0, 0xc4, +- 0x11, 0xf8, 0x8e, 0x17, 0x65, 0x2c, 0x76, 0x11, 0x7b, 0xfd, 0x3c, 0xc6, +- 0xc0, 0x07, 0x68, 0x15, 0x50, 0x77, 0x1d, 0x7e, 0xc6, 0x6d, 0xe1, 0xf3, +- 0x98, 0x73, 0x1e, 0x88, 0xce, 0x3a, 0x29, 0xe7, 0x35, 0xf1, 0xe9, 0x8c, +- 0x34, 0xc5, 0xbb, 0xb6, 0x41, 0xc9, 0xaf, 0xd3, 0x2f, 0xeb, 0x03, 0x1f, +- 0xfe, 0x08, 0x7a, 0x98, 0x6b, 0x50, 0x2e, 0x70, 0x0f, 0xff, 0x0d, 0xf0, +- 0xc5, 0x67, 0xbb, 0xbd, 0xfb, 0xa1, 0x7b, 0x29, 0xf7, 0xb5, 0xef, 0x94, +- 0xc7, 0x18, 0xa5, 0x1b, 0xd2, 0xbc, 0x77, 0xe0, 0xfe, 0xfe, 0x18, 0x76, +- 0x4e, 0x14, 0x74, 0x80, 0xfa, 0x75, 0xdf, 0xce, 0xf5, 0xed, 0x19, 0x1d, +- 0xeb, 0xbb, 0xa2, 0x6c, 0x9a, 0x1c, 0xf4, 0xd8, 0x31, 0xf4, 0x65, 0xac, +- 0xbd, 0xd5, 0x3a, 0x95, 0x86, 0xdf, 0xf1, 0x24, 0x65, 0xd9, 0x7d, 0xe0, +- 0x69, 0xda, 0x45, 0xd4, 0xb9, 0x62, 0xdd, 0xcc, 0x6c, 0x3b, 0x61, 0xe8, +- 0xcb, 0x19, 0xd0, 0x5c, 0x0e, 0x74, 0x18, 0x78, 0x60, 0x0a, 0xfa, 0x57, +- 0xc5, 0x9c, 0x41, 0xeb, 0x5c, 0xf7, 0x83, 0xd6, 0x5f, 0x64, 0xc6, 0xa1, +- 0x8f, 0x1f, 0x82, 0x3e, 0xe6, 0x7d, 0x74, 0x0e, 0x3a, 0x99, 0xfa, 0xd8, +- 0x91, 0x3f, 0xdd, 0xcc, 0x41, 0x76, 0xdd, 0xd7, 0x43, 0x5e, 0x9b, 0x6a, +- 0xf3, 0x54, 0xc1, 0xf0, 0xdc, 0x01, 0x13, 0xfb, 0x28, 0x28, 0xde, 0x2c, +- 0xaf, 0xd3, 0x0e, 0x01, 0x9f, 0xae, 0x53, 0x46, 0xd0, 0xa6, 0xa4, 0xec, +- 0x80, 0xac, 0x59, 0xff, 0x00, 0xca, 0x29, 0x94, 0xda, 0x56, 0xbb, 0x52, +- 0x7d, 0x35, 0xec, 0xdf, 0x23, 0xef, 0xd8, 0x6b, 0x75, 0xec, 0xef, 0x18, +- 0x73, 0x1b, 0x4a, 0xfd, 0xde, 0x47, 0xb0, 0xc7, 0xe3, 0xa0, 0xc1, 0x19, +- 0xd0, 0xe0, 0x14, 0xf6, 0x7a, 0xde, 0x1a, 0x39, 0x1c, 0x80, 0x3e, 0x3f, +- 0x23, 0x85, 0x34, 0x64, 0xee, 0x5a, 0xc9, 0x9a, 0x58, 0x12, 0xf5, 0x9e, +- 0x4f, 0xf3, 0x4e, 0xfd, 0xbd, 0x2a, 0x3e, 0xb8, 0xbc, 0x19, 0x34, 0x71, +- 0xc4, 0x20, 0xea, 0xa8, 0xc3, 0x21, 0xb3, 0x1c, 0xcc, 0x55, 0xfd, 0x59, +- 0xaf, 0xf4, 0x62, 0xbe, 0xea, 0x34, 0xde, 0x19, 0x5b, 0x38, 0x66, 0xdd, +- 0x59, 0xcf, 0xd8, 0x45, 0xc2, 0xc9, 0xc1, 0x17, 0x0d, 0xba, 0x8c, 0x5f, +- 0xb8, 0x38, 0x9f, 0xac, 0xe4, 0x47, 0x60, 0x93, 0x29, 0x99, 0xdc, 0x6b, +- 0x64, 0x32, 0xe4, 0x5d, 0xcd, 0x93, 0xb5, 0x4d, 0xda, 0x4e, 0x9e, 0xf2, +- 0xa7, 0x29, 0xc7, 0x8a, 0x35, 0xd8, 0x3f, 0xe9, 0xdf, 0xb3, 0xb2, 0x6a, +- 0xce, 0xb0, 0xca, 0xd5, 0x28, 0xad, 0x89, 0xe5, 0x1c, 0xbe, 0x09, 0xff, +- 0x35, 0x03, 0x1e, 0xf6, 0x20, 0x37, 0x1d, 0xc8, 0x45, 0xea, 0xb5, 0xaf, +- 0x76, 0x4b, 0x1f, 0xea, 0x2f, 0xc3, 0xe6, 0x79, 0x92, 0x7c, 0x7b, 0x5d, +- 0xec, 0xc6, 0x1b, 0xc5, 0x47, 0x18, 0x1b, 0x19, 0x32, 0x77, 0xb3, 0xff, +- 0x0b, 0xf0, 0xea, 0x35, 0x42, 0xb0, 0xeb, 0xaf, 0xd6, 0xf6, 0xc1, 0x47, +- 0x3c, 0x66, 0xe5, 0xa3, 0xac, 0x2b, 0xc9, 0x7a, 0x86, 0x76, 0x28, 0x63, +- 0x24, 0x61, 0xd4, 0xef, 0xf6, 0x49, 0xa9, 0xff, 0x9f, 0x53, 0x77, 0x34, +- 0x0b, 0x4a, 0xee, 0xfa, 0xf1, 0xe5, 0xe7, 0x24, 0xd9, 0xf4, 0xe3, 0x54, +- 0x5c, 0x7f, 0xcb, 0x2a, 0x36, 0xff, 0x1c, 0xeb, 0x10, 0x06, 0xee, 0x45, +- 0xaf, 0x63, 0x2f, 0x4f, 0x98, 0x75, 0x1c, 0x2b, 0x74, 0x38, 0x86, 0xfd, +- 0xec, 0xef, 0x93, 0xbe, 0x00, 0xe4, 0xd9, 0x28, 0x9e, 0x6f, 0xa1, 0x6e, +- 0xe7, 0xbd, 0x51, 0x15, 0x2b, 0x70, 0x18, 0xde, 0x33, 0xf4, 0x77, 0x03, +- 0x32, 0xc7, 0x86, 0xfe, 0x6c, 0x54, 0x3f, 0x8e, 0x12, 0xe3, 0x9e, 0xbc, +- 0x2e, 0x73, 0xda, 0xdf, 0x86, 0x4d, 0x39, 0xac, 0x74, 0xf0, 0x4c, 0x9a, +- 0xb1, 0x90, 0x33, 0x90, 0x8f, 0xf7, 0xa3, 0x8e, 0x7e, 0x53, 0x49, 0x9c, +- 0xf7, 0x14, 0x8c, 0xbf, 0xaf, 0xcf, 0x25, 0xa0, 0xf4, 0xf5, 0x0a, 0xce, +- 0x83, 0x73, 0x50, 0xdf, 0xfd, 0x5c, 0x3e, 0xd5, 0x11, 0x47, 0xc9, 0xd9, +- 0xed, 0xb8, 0x41, 0x36, 0x0f, 0x1d, 0xbd, 0x56, 0x25, 0x0f, 0x66, 0x70, +- 0xde, 0x59, 0xf9, 0xda, 0xe6, 0x3d, 0xc0, 0x75, 0x54, 0x02, 0x4f, 0xb5, +- 0x40, 0x3f, 0xd4, 0x0d, 0x63, 0x90, 0xc9, 0x8e, 0xb1, 0x25, 0xa2, 0x12, +- 0x7c, 0x6a, 0x48, 0xba, 0x2f, 0xc4, 0xa4, 0xeb, 0x02, 0xf3, 0x4f, 0x52, +- 0x71, 0xd8, 0xc5, 0xb4, 0x87, 0x78, 0x0f, 0xc9, 0xfb, 0xc3, 0xb8, 0xbe, +- 0x8f, 0xe4, 0x5d, 0x24, 0xfa, 0xc1, 0x76, 0xef, 0xba, 0xe4, 0x00, 0x3f, +- 0x7a, 0xce, 0xdd, 0x63, 0xcb, 0x7a, 0x2c, 0xef, 0x31, 0x63, 0x25, 0x49, +- 0x99, 0x7b, 0xcc, 0x14, 0xc6, 0xa6, 0x26, 0x5f, 0x6e, 0x8f, 0xe7, 0x58, +- 0xea, 0xc4, 0x28, 0xf8, 0xfb, 0xad, 0xd2, 0xf8, 0x22, 0xf9, 0xdc, 0xbf, +- 0xeb, 0x1a, 0x32, 0x77, 0x5f, 0xec, 0x13, 0x37, 0xed, 0x49, 0xd3, 0xee, +- 0x2a, 0x3d, 0x19, 0x6c, 0xc7, 0x5b, 0x78, 0x2f, 0x96, 0x38, 0xcf, 0xe4, +- 0x11, 0x7d, 0x47, 0x46, 0x5f, 0x0a, 0xbe, 0xc5, 0x93, 0xb0, 0x31, 0xeb, +- 0x2c, 0x7b, 0xa4, 0x5c, 0x3f, 0x25, 0xb3, 0xea, 0xf9, 0x43, 0xf2, 0xa8, +- 0x43, 0xdc, 0x9d, 0x91, 0xf4, 0x84, 0xb6, 0xc7, 0xc4, 0xd6, 0xb8, 0xed, +- 0x76, 0xcf, 0xc8, 0xd1, 0xb4, 0xd2, 0x21, 0xce, 0x23, 0xc0, 0x71, 0xb1, +- 0xd9, 0x45, 0x7a, 0x07, 0xec, 0x1e, 0x78, 0x2c, 0x2b, 0x17, 0x37, 0xd1, +- 0x17, 0x67, 0xf5, 0x08, 0xdf, 0xeb, 0xc0, 0x27, 0x63, 0x16, 0x4f, 0x11, +- 0x9f, 0xdc, 0x3b, 0x75, 0x28, 0x71, 0x4a, 0x1c, 0x50, 0x2f, 0x33, 0xe6, +- 0x96, 0x98, 0xbc, 0x2d, 0xf4, 0x9b, 0x89, 0x33, 0xce, 0xe3, 0xef, 0x5b, +- 0x8f, 0xb3, 0x37, 0x06, 0x85, 0xe6, 0x98, 0x7d, 0xc1, 0x11, 0xfb, 0x12, +- 0xcb, 0x08, 0x4a, 0xb6, 0x01, 0xa4, 0x8d, 0xa4, 0x69, 0x73, 0x51, 0x07, +- 0x3b, 0xf2, 0x09, 0xf2, 0x96, 0xce, 0xff, 0x4b, 0x8e, 0x4c, 0xca, 0x95, +- 0xb5, 0xbb, 0xf9, 0x2b, 0x70, 0x41, 0xdb, 0x25, 0x77, 0xf2, 0xd7, 0xe4, +- 0x3f, 0x80, 0xbf, 0xb8, 0xc6, 0x19, 0x95, 0xbb, 0xf0, 0xa9, 0x68, 0x22, +- 0x9e, 0xd5, 0xfe, 0x85, 0x93, 0xb2, 0x47, 0xe2, 0xb4, 0x47, 0x1b, 0x4f, +- 0x8e, 0xe3, 0xdc, 0x5b, 0xf2, 0x44, 0xda, 0xa7, 0x2f, 0xe6, 0xf8, 0xb5, +- 0xa4, 0x06, 0xfd, 0x5c, 0x76, 0x2d, 0x59, 0x70, 0xcf, 0x28, 0x7b, 0xf2, +- 0xc3, 0xd1, 0x96, 0x9c, 0x4e, 0xeb, 0xb1, 0x0b, 0x32, 0x62, 0x68, 0x5c, +- 0xf9, 0x6b, 0x90, 0xbf, 0x3c, 0x2f, 0xbe, 0xdf, 0x23, 0xe9, 0x81, 0x33, +- 0x92, 0x9c, 0xd8, 0x22, 0xbe, 0x70, 0x0e, 0x94, 0x3b, 0xbf, 0x36, 0x16, +- 0xa6, 0x72, 0x9e, 0xf2, 0x15, 0xc2, 0xb4, 0x0f, 0x74, 0x9b, 0x85, 0xbf, +- 0xb4, 0x13, 0x0f, 0x4b, 0x8d, 0x94, 0x5a, 0x21, 0xac, 0x5d, 0x84, 0x3f, +- 0xf1, 0xe1, 0xa8, 0x1b, 0x1f, 0xb6, 0x47, 0x62, 0x67, 0xa5, 0xa6, 0x60, +- 0xfd, 0x44, 0x5a, 0xd3, 0xcb, 0x62, 0x66, 0xaf, 0x18, 0x55, 0x67, 0x8c, +- 0x9a, 0x73, 0x6d, 0x59, 0x9f, 0x6c, 0xea, 0x78, 0xd4, 0x4e, 0x9c, 0x7a, +- 0x47, 0xe6, 0x04, 0x8d, 0x2c, 0x28, 0xd7, 0xde, 0x25, 0xbe, 0xcc, 0xa9, +- 0x65, 0x70, 0x56, 0xcb, 0x3c, 0xa3, 0xb8, 0xb9, 0x47, 0x0a, 0x77, 0xd8, +- 0xca, 0x21, 0xe6, 0xfd, 0xc5, 0xb3, 0xf6, 0x32, 0x64, 0xc3, 0x93, 0x12, +- 0x72, 0xfd, 0xb9, 0x98, 0xd3, 0x19, 0x33, 0xf7, 0x11, 0xfb, 0x19, 0xb7, +- 0x42, 0x9f, 0x07, 0xd1, 0x7e, 0x3f, 0xfa, 0x51, 0x57, 0xf2, 0x1e, 0x80, +- 0x7a, 0x93, 0xb1, 0xf6, 0x01, 0xf4, 0xeb, 0x91, 0x7c, 0x7d, 0xbf, 0xa9, +- 0xf3, 0xe7, 0x38, 0xdc, 0xd1, 0xdf, 0xaf, 0xd3, 0xf7, 0x07, 0x59, 0x1b, +- 0x32, 0x7e, 0x99, 0x7d, 0xe3, 0xed, 0x3b, 0x10, 0xbb, 0xf1, 0xa0, 0xa3, +- 0xc7, 0xb3, 0x1f, 0x65, 0x3e, 0x74, 0x4b, 0x15, 0xfa, 0xa6, 0x3a, 0xc5, +- 0xbb, 0x40, 0x63, 0x57, 0xcc, 0x9a, 0x7c, 0x16, 0xda, 0x17, 0xaf, 0x19, +- 0x7d, 0xbb, 0x93, 0x8b, 0x7a, 0x24, 0xe3, 0xe7, 0xf5, 0x30, 0x17, 0x91, +- 0xeb, 0xf2, 0x3c, 0x40, 0x53, 0x9b, 0xda, 0x96, 0xb6, 0x33, 0x5d, 0xbc, +- 0x6b, 0x83, 0x7e, 0xd7, 0xfa, 0xbf, 0x01, 0xfd, 0xbf, 0xb1, 0x02, 0x9d, +- 0xdf, 0x47, 0xdd, 0xaf, 0xf3, 0x4f, 0xec, 0x76, 0xbe, 0x8f, 0x7f, 0x8f, +- 0xbc, 0xa5, 0xee, 0xf1, 0x7a, 0x3c, 0xca, 0xf4, 0x8c, 0xfc, 0x39, 0x6c, +- 0xad, 0x67, 0x36, 0x27, 0xb1, 0x5e, 0x1a, 0x7e, 0xdd, 0x38, 0xfc, 0xba, +- 0x51, 0xf8, 0x75, 0x2e, 0x74, 0xe1, 0x90, 0xca, 0x27, 0xa3, 0xde, 0x9f, +- 0x38, 0x24, 0xd6, 0xd7, 0x32, 0x62, 0x1d, 0xbc, 0x00, 0x1b, 0x61, 0xe9, +- 0x25, 0xd0, 0x7f, 0xe2, 0x79, 0x11, 0xf2, 0x04, 0xf9, 0xef, 0x31, 0xc9, +- 0xc6, 0x86, 0xe4, 0xf3, 0x9b, 0x6c, 0x23, 0x3d, 0x65, 0xe5, 0x15, 0xf7, +- 0x25, 0xc5, 0x67, 0x17, 0x6b, 0xd7, 0x25, 0xf4, 0x84, 0x96, 0xb5, 0x3f, +- 0x80, 0x3d, 0xd5, 0x48, 0x6b, 0xda, 0xbb, 0x2d, 0xa4, 0x3d, 0xe8, 0xa7, +- 0x35, 0xca, 0xd8, 0x9b, 0x12, 0xbd, 0xf0, 0x92, 0xbc, 0xf9, 0x82, 0xab, +- 0xe2, 0x12, 0x6b, 0x4f, 0x2a, 0xdd, 0x07, 0xb9, 0x16, 0x95, 0xf5, 0xcd, +- 0xdf, 0x91, 0x4f, 0x39, 0x89, 0x2b, 0x94, 0x99, 0x94, 0x5d, 0x5a, 0xa7, +- 0x41, 0xc6, 0x56, 0x12, 0xa5, 0x32, 0x6c, 0xef, 0x2b, 0xf6, 0x98, 0x64, +- 0x83, 0xa5, 0x56, 0x3f, 0xfd, 0x82, 0x9a, 0xeb, 0x24, 0x6d, 0x9e, 0xef, +- 0xbd, 0xb0, 0xad, 0x13, 0x75, 0x25, 0xa3, 0xa8, 0x27, 0x33, 0xd4, 0x9b, +- 0xd4, 0x7d, 0xd4, 0x3f, 0x8c, 0x97, 0xe3, 0x79, 0x8d, 0xba, 0xe9, 0xef, +- 0xd4, 0x9d, 0x67, 0x71, 0xc6, 0x91, 0xfa, 0x1a, 0xe5, 0x13, 0xf4, 0xfc, +- 0x93, 0xb4, 0x73, 0x45, 0xd1, 0x3f, 0xed, 0xdc, 0x47, 0xc5, 0xb7, 0x71, +- 0xd9, 0xb6, 0xdb, 0xc6, 0xfd, 0x83, 0x7d, 0xd2, 0x1b, 0x05, 0x7e, 0xc8, +- 0xff, 0x3b, 0x36, 0x60, 0x2e, 0x73, 0x13, 0xb6, 0x26, 0xf7, 0x61, 0xc9, +- 0xa0, 0x7b, 0x1d, 0x74, 0xc4, 0xb5, 0x6f, 0xb6, 0x3e, 0x1c, 0xe5, 0x1e, +- 0x2c, 0x65, 0x23, 0x6c, 0x0f, 0xfe, 0xa6, 0x3b, 0x0a, 0xca, 0x88, 0x7d, +- 0xb0, 0xcd, 0x6d, 0x43, 0xb3, 0x9f, 0x34, 0xbe, 0x04, 0xf8, 0x79, 0x95, +- 0x7b, 0x28, 0xf3, 0x4e, 0x04, 0x36, 0xd7, 0x22, 0x63, 0x52, 0x6a, 0xdd, +- 0xf7, 0x67, 0x22, 0x92, 0xbc, 0xd0, 0x25, 0xa9, 0xa7, 0xec, 0x41, 0x9d, +- 0xb7, 0xf8, 0x30, 0x74, 0xcf, 0x41, 0xb4, 0x1f, 0x90, 0xb2, 0x13, 0x85, +- 0x3f, 0x33, 0x2a, 0xe5, 0xd1, 0x30, 0x78, 0xe6, 0x01, 0xde, 0x75, 0x28, +- 0x38, 0xca, 0xce, 0x30, 0xca, 0x6e, 0x94, 0xf7, 0x48, 0xf9, 0xc9, 0x4b, +- 0xfb, 0xb4, 0x2d, 0xbb, 0xfb, 0xfd, 0x9f, 0x76, 0xab, 0xd8, 0xb9, 0xf5, +- 0x8e, 0x88, 0xb9, 0x47, 0xff, 0x2d, 0x60, 0xf7, 0xfb, 0x12, 0x9e, 0x90, +- 0xb8, 0x4f, 0x44, 0x64, 0x18, 0xb2, 0x77, 0x04, 0x7a, 0xeb, 0xe0, 0x85, +- 0x21, 0x19, 0xbd, 0x10, 0x97, 0xfb, 0x2e, 0xf8, 0xf6, 0xc0, 0xf2, 0x74, +- 0xca, 0xc4, 0x71, 0xdd, 0xdf, 0x32, 0x8e, 0x7b, 0x9f, 0x9a, 0x1f, 0x30, +- 0xae, 0x41, 0x1e, 0x46, 0x3f, 0xa7, 0xec, 0x06, 0x8d, 0xfb, 0x1f, 0xc9, +- 0x91, 0x95, 0x90, 0x1c, 0x55, 0xbc, 0xe8, 0xdb, 0xf0, 0xff, 0x13, 0xfb, +- 0x48, 0x80, 0x47, 0x4e, 0x18, 0xbf, 0xb3, 0x17, 0x78, 0x25, 0x0e, 0xa1, +- 0xeb, 0xe0, 0x8b, 0x32, 0x3f, 0xb5, 0x98, 0xee, 0x1c, 0xcf, 0xb1, 0x3f, +- 0xc5, 0x98, 0x2c, 0x6c, 0x0b, 0xb6, 0xcb, 0x60, 0x40, 0xf6, 0x6a, 0x7f, +- 0x1f, 0xda, 0x29, 0x73, 0x8e, 0x42, 0xe6, 0xec, 0x6e, 0xcf, 0xa1, 0x8d, +- 0xeb, 0xdf, 0x83, 0x75, 0xc9, 0x8f, 0x5c, 0xd7, 0xc7, 0x09, 0xcf, 0x75, +- 0x10, 0xfe, 0x07, 0xcf, 0xb5, 0x4b, 0x0a, 0x0e, 0x73, 0x37, 0x59, 0xf7, +- 0x16, 0x73, 0xd6, 0x13, 0xe6, 0xac, 0x05, 0xb6, 0x31, 0xed, 0x2d, 0x9d, +- 0xaf, 0x50, 0x88, 0x26, 0x4a, 0x22, 0x71, 0x15, 0xbf, 0x5b, 0xaf, 0xf8, +- 0xf6, 0x49, 0xb6, 0x9f, 0xf7, 0x10, 0x8b, 0x69, 0x15, 0x5b, 0x8b, 0x07, +- 0x3c, 0xda, 0x37, 0xe9, 0x30, 0xf3, 0x92, 0x1b, 0x2b, 0xbc, 0x93, 0x0c, +- 0xe0, 0x07, 0x3c, 0x07, 0x2d, 0x71, 0x5c, 0xd6, 0x95, 0xb4, 0x6e, 0x9b, +- 0x01, 0xff, 0xda, 0xaa, 0x4f, 0x3c, 0x97, 0x1e, 0x34, 0xef, 0x31, 0x59, +- 0xab, 0xbc, 0x63, 0xc8, 0xf6, 0xfe, 0xf6, 0x9e, 0x5c, 0xa6, 0x9f, 0xf7, +- 0x49, 0xa8, 0x23, 0x9f, 0xbc, 0xa4, 0x72, 0x15, 0xb5, 0xef, 0x10, 0xe4, +- 0x3d, 0x24, 0xf6, 0xf9, 0x53, 0xd0, 0xf5, 0xee, 0x3d, 0x77, 0x99, 0x3d, +- 0x73, 0xbf, 0xc4, 0x37, 0xc7, 0xfb, 0x7a, 0x8e, 0x38, 0x0f, 0x77, 0xf8, +- 0x1b, 0x91, 0x81, 0x9d, 0xfb, 0x73, 0xca, 0x42, 0xca, 0xbf, 0x49, 0x95, +- 0xef, 0x72, 0xcb, 0x86, 0x1c, 0xaa, 0x42, 0x2e, 0x55, 0x21, 0x8b, 0xaa, +- 0x90, 0x45, 0xb0, 0x41, 0x9e, 0x85, 0x5c, 0x7d, 0x06, 0xbe, 0xda, 0xd7, +- 0xab, 0xbe, 0xfd, 0x9e, 0x85, 0x1c, 0x53, 0x36, 0x1d, 0xed, 0x9f, 0x9a, +- 0xed, 0x75, 0xff, 0xd6, 0xf9, 0x50, 0x01, 0xcf, 0x1f, 0xd7, 0x2d, 0x45, +- 0x35, 0x26, 0x2e, 0xf3, 0xcd, 0xbd, 0xfa, 0x72, 0x7f, 0xa1, 0x8e, 0xfd, +- 0x9a, 0xbb, 0x7e, 0x15, 0x8b, 0xa0, 0x0c, 0xfe, 0x4d, 0x3c, 0xd0, 0x99, +- 0xa7, 0xc9, 0x33, 0x56, 0x39, 0x42, 0x38, 0x53, 0xe2, 0x9d, 0x76, 0x61, +- 0x59, 0x16, 0x26, 0x17, 0xa5, 0x3c, 0x69, 0xc9, 0xdc, 0x38, 0xce, 0x68, +- 0x7c, 0x18, 0x3a, 0x32, 0x0d, 0x5d, 0xbb, 0x80, 0x79, 0xc8, 0x7f, 0x0f, +- 0xe2, 0x5c, 0x1c, 0x73, 0x27, 0xfe, 0xa5, 0xe9, 0x5c, 0x4d, 0xac, 0x6b, +- 0x2a, 0x47, 0x7c, 0x79, 0xfa, 0xd5, 0x95, 0x87, 0x61, 0x3f, 0x4d, 0xc8, +- 0xd5, 0xc9, 0x87, 0x65, 0xfb, 0x8e, 0xf1, 0x38, 0x07, 0xc8, 0xe1, 0xcf, +- 0x6f, 0xf2, 0x1e, 0xb4, 0x4b, 0x66, 0xa3, 0x8c, 0x81, 0xc1, 0xc6, 0x71, +- 0xfb, 0x65, 0x5b, 0xf9, 0xa1, 0x07, 0xe4, 0xb6, 0xa2, 0x2d, 0xd6, 0x85, +- 0x50, 0xa7, 0xed, 0xd1, 0xb5, 0x8a, 0x6f, 0x5b, 0x28, 0x1c, 0x99, 0x98, +- 0x1f, 0xf5, 0x0d, 0xe3, 0x49, 0x8c, 0x2f, 0xad, 0x45, 0x76, 0x64, 0x01, +- 0x4b, 0xff, 0x5c, 0x3b, 0xfd, 0xe3, 0xbf, 0x8e, 0xe8, 0x6f, 0x0b, 0xba, +- 0xa4, 0x1c, 0x2d, 0xb5, 0xca, 0x6e, 0xd0, 0xba, 0xda, 0xce, 0x69, 0xf5, +- 0xdb, 0x48, 0xcb, 0x36, 0x60, 0x25, 0x1d, 0x24, 0x55, 0xee, 0xce, 0x77, +- 0xaa, 0x03, 0xfb, 0xf4, 0x37, 0x0a, 0x01, 0x8c, 0xe3, 0xfb, 0x89, 0x88, +- 0x7e, 0xf7, 0xef, 0xdd, 0xdf, 0x86, 0xbe, 0x31, 0x25, 0xaf, 0xd6, 0x6a, +- 0x01, 0xf0, 0xf0, 0x20, 0x9e, 0x5f, 0x44, 0x9f, 0x30, 0xce, 0x86, 0xb1, +- 0xa4, 0xb7, 0xa8, 0xfc, 0x9b, 0x80, 0xeb, 0xe7, 0xf5, 0x52, 0x77, 0xff, +- 0x67, 0xd5, 0xfe, 0xf4, 0x4a, 0x37, 0xf3, 0x55, 0x51, 0x52, 0xaf, 0xff, +- 0x0a, 0xbe, 0x56, 0x48, 0xf2, 0x35, 0x17, 0xb6, 0x78, 0x88, 0xf4, 0x8b, +- 0xfa, 0x7b, 0xa1, 0xa3, 0x04, 0xfc, 0xd4, 0x05, 0xbd, 0xa9, 0x70, 0x0d, +- 0x4a, 0xa2, 0x4f, 0xef, 0xe7, 0x99, 0x6a, 0x38, 0x42, 0xde, 0xf7, 0x98, +- 0x6f, 0x10, 0x0e, 0x78, 0x2f, 0x4d, 0xcf, 0x55, 0x68, 0x2b, 0xb5, 0x5a, +- 0xd0, 0x65, 0xd8, 0xc9, 0xcf, 0x94, 0x5f, 0xb1, 0x2d, 0xda, 0x57, 0x5b, +- 0x50, 0xf9, 0x96, 0x37, 0xa7, 0x35, 0x8d, 0x74, 0xde, 0x9f, 0xbc, 0xd1, +- 0xdd, 0x49, 0x58, 0xb6, 0xd3, 0x3d, 0x86, 0x2f, 0xc2, 0xc1, 0x62, 0x25, +- 0x12, 0x9c, 0x53, 0xf7, 0x5b, 0x5b, 0x26, 0x1f, 0xf3, 0xda, 0x74, 0xaa, +- 0x19, 0x56, 0xb9, 0x00, 0xbc, 0x4b, 0xc8, 0x57, 0x78, 0x97, 0xa2, 0xdb, +- 0x53, 0xa6, 0x3d, 0xd9, 0x54, 0x6d, 0x2a, 0xde, 0xc5, 0x18, 0x57, 0x37, +- 0xca, 0xdb, 0x15, 0xca, 0x07, 0xcc, 0xaf, 0x65, 0x09, 0x60, 0x7f, 0x71, +- 0x7a, 0x6e, 0x85, 0xf0, 0x7d, 0x7f, 0x3a, 0xb7, 0xc2, 0x1c, 0xc8, 0xff, +- 0x34, 0x7d, 0x63, 0xc5, 0x92, 0x0d, 0x37, 0xa1, 0xe2, 0x57, 0xeb, 0x8c, +- 0xb1, 0x72, 0x9c, 0x9a, 0xf3, 0x45, 0x23, 0x93, 0xbf, 0x37, 0x3d, 0xbc, +- 0x1e, 0x90, 0x73, 0x66, 0x0e, 0xbe, 0xc7, 0xd7, 0xef, 0xa0, 0x6b, 0xd0, +- 0xca, 0x15, 0xd0, 0x4a, 0x2f, 0x6c, 0x09, 0xd2, 0x37, 0x7d, 0xb2, 0x5e, +- 0xc8, 0x01, 0xae, 0xf3, 0x8c, 0x5a, 0x27, 0x80, 0x75, 0xe6, 0x54, 0xce, +- 0x78, 0x80, 0x79, 0xb7, 0xb0, 0x35, 0x61, 0x13, 0xba, 0x8c, 0x59, 0xdb, +- 0xd8, 0xf3, 0x28, 0xf4, 0x12, 0xf3, 0x3f, 0xfe, 0x7b, 0x64, 0x27, 0x6f, +- 0xfc, 0x39, 0x33, 0xee, 0x9b, 0x18, 0xc7, 0x33, 0x51, 0xf9, 0xe6, 0x6f, +- 0xb6, 0x65, 0x58, 0xd9, 0x90, 0x3a, 0x07, 0x89, 0x30, 0xd4, 0xb1, 0x57, +- 0xea, 0xe2, 0x2e, 0xc9, 0xab, 0x7d, 0x7d, 0x53, 0x8d, 0xb3, 0xbc, 0x6f, +- 0x00, 0x76, 0xda, 0x25, 0x98, 0xbb, 0xaa, 0xe3, 0x6d, 0x79, 0xc5, 0xd3, +- 0xe0, 0x91, 0x49, 0x3f, 0x57, 0x4f, 0x8f, 0xf3, 0xfb, 0x27, 0xd7, 0x8f, +- 0x98, 0x9c, 0x8e, 0xbf, 0x6f, 0x65, 0x8f, 0xf7, 0x2a, 0x1b, 0x6c, 0xe7, +- 0x9b, 0x08, 0x7f, 0x8c, 0xdf, 0xc7, 0xcf, 0x31, 0x7e, 0x74, 0xff, 0x0e, +- 0xcc, 0x5b, 0xe6, 0xcc, 0x39, 0x8e, 0xb1, 0x49, 0x95, 0xaf, 0xcb, 0xba, +- 0xe0, 0x7c, 0x86, 0x73, 0x74, 0xde, 0xf7, 0x8c, 0x83, 0x47, 0xb5, 0xcd, +- 0x57, 0x82, 0x9d, 0x55, 0x06, 0xbf, 0x04, 0x3c, 0xca, 0xf1, 0x61, 0x13, +- 0x57, 0x7b, 0xa3, 0x38, 0x1f, 0xef, 0x12, 0xc7, 0x21, 0x7b, 0xfc, 0xf1, +- 0x3c, 0xc7, 0x6b, 0xd3, 0x37, 0x2a, 0xae, 0x9c, 0xad, 0xea, 0x7c, 0x47, +- 0x8d, 0x07, 0xc6, 0x6e, 0x78, 0xb6, 0x71, 0x99, 0x73, 0xa9, 0x67, 0xe3, +- 0xf2, 0x5d, 0xd7, 0x8f, 0xad, 0xf1, 0x7e, 0x0a, 0xfd, 0x61, 0xeb, 0x2d, +- 0x6c, 0x72, 0xff, 0xdf, 0xc4, 0xfe, 0xe9, 0x53, 0x68, 0x5a, 0x3a, 0x08, +- 0xb9, 0xf5, 0x1f, 0x82, 0xf0, 0x19, 0xa0, 0xbb, 0x6f, 0x05, 0x3b, 0xf7, +- 0xe7, 0xeb, 0x6b, 0x4d, 0x97, 0x41, 0xd0, 0xc8, 0x62, 0x1b, 0xef, 0x96, +- 0x04, 0xde, 0x39, 0x02, 0x1d, 0x64, 0x49, 0x61, 0xdc, 0x8d, 0x2d, 0xf0, +- 0x6e, 0xc1, 0x19, 0x73, 0x1c, 0x95, 0xc7, 0x16, 0x07, 0xbc, 0x7c, 0xe6, +- 0xb7, 0x02, 0xcc, 0x39, 0x8b, 0xab, 0x5c, 0xdd, 0x6c, 0xd4, 0x05, 0xbc, +- 0x8e, 0xb2, 0x4f, 0xb4, 0x5e, 0xfe, 0x97, 0xfb, 0x29, 0x6b, 0xfa, 0x5d, +- 0xff, 0xec, 0x39, 0xf7, 0x8b, 0x98, 0x3b, 0x60, 0xda, 0x7d, 0x1a, 0x09, +- 0x30, 0xe5, 0x4d, 0x76, 0xbe, 0x01, 0xf1, 0xe3, 0x7c, 0xec, 0xff, 0x2d, +- 0x05, 0xcb, 0x1c, 0xf4, 0xd0, 0xbc, 0xda, 0xcf, 0x0b, 0xa0, 0x05, 0xca, +- 0x15, 0x9f, 0x7e, 0x5f, 0x00, 0xfd, 0xee, 0x63, 0x0a, 0xdf, 0x1e, 0xb4, +- 0xe6, 0xd3, 0x18, 0xe9, 0x8b, 0xb4, 0xf5, 0x8a, 0xe2, 0xb9, 0x52, 0xfb, +- 0xdc, 0x29, 0xb3, 0x12, 0x4e, 0xdc, 0xf6, 0xcf, 0x9d, 0xcf, 0x7b, 0xe5, +- 0xb8, 0xfa, 0xfc, 0x91, 0xf9, 0x07, 0x9c, 0x6d, 0xda, 0x9c, 0x6d, 0xa6, +- 0xe3, 0x9b, 0x04, 0x7f, 0x3e, 0xfa, 0xfb, 0xd4, 0xaf, 0xbc, 0x0b, 0xe2, +- 0xf7, 0x12, 0xca, 0x44, 0x90, 0x72, 0x9a, 0x7c, 0x94, 0x8b, 0xf3, 0x3e, +- 0xe5, 0xa4, 0x04, 0xfa, 0x60, 0xb7, 0x8c, 0x86, 0xc4, 0xff, 0x2e, 0xa9, +- 0x4b, 0xb6, 0x9c, 0x56, 0xeb, 0x06, 0xef, 0x8d, 0x2b, 0x41, 0xd9, 0x50, +- 0x77, 0x9f, 0xe0, 0xd1, 0xde, 0xa0, 0x2c, 0xba, 0x6d, 0x3d, 0x27, 0x75, +- 0xf4, 0x59, 0x43, 0xdb, 0xb9, 0x36, 0x6c, 0xd4, 0x07, 0xb0, 0x21, 0xdd, +- 0xbf, 0x6f, 0x15, 0xa3, 0x77, 0xf4, 0x35, 0x32, 0x96, 0xb1, 0x47, 0xc6, +- 0xa7, 0x1d, 0xc9, 0xaf, 0x0f, 0xe0, 0x07, 0x19, 0xaf, 0xe4, 0x02, 0x63, +- 0x91, 0x8c, 0xe7, 0x96, 0xe0, 0x9f, 0x6a, 0x3f, 0x9f, 0xf6, 0xf6, 0x95, +- 0xcd, 0x44, 0xa9, 0x24, 0x6e, 0xfc, 0x91, 0xf6, 0x77, 0x3c, 0x7d, 0xa5, +- 0xb0, 0xd7, 0x19, 0xf3, 0x8d, 0xab, 0xfc, 0xd9, 0x1e, 0x2f, 0x11, 0x3b, +- 0x05, 0xdf, 0xf5, 0xeb, 0x69, 0xc6, 0x7a, 0xef, 0x23, 0xbe, 0xbf, 0xc4, +- 0x4d, 0xda, 0x23, 0xe3, 0xe2, 0x5e, 0x72, 0x47, 0x1f, 0x11, 0xfa, 0xa7, +- 0x89, 0xf8, 0x14, 0xf1, 0xd6, 0xfe, 0xbe, 0x20, 0x68, 0xec, 0xa5, 0x71, +- 0x19, 0xbe, 0xf4, 0x23, 0x15, 0x63, 0xff, 0x70, 0x7a, 0x37, 0x6d, 0xa8, +- 0x58, 0xf1, 0x78, 0xbf, 0x0c, 0x8f, 0xae, 0x89, 0x40, 0x5b, 0xf0, 0x7b, +- 0x03, 0x0b, 0x3e, 0xaa, 0x7a, 0x87, 0xbd, 0x1e, 0x57, 0xdf, 0x5c, 0x65, +- 0x55, 0xde, 0x23, 0x63, 0xc9, 0x3c, 0xd3, 0x88, 0xca, 0x85, 0x7b, 0x16, +- 0x67, 0x5b, 0x68, 0xf2, 0x7c, 0x19, 0x57, 0x66, 0xdc, 0x98, 0xb1, 0x65, +- 0xc6, 0x88, 0xf5, 0xf7, 0x53, 0x47, 0x9a, 0x7b, 0xc5, 0x91, 0x89, 0x8b, +- 0x51, 0xf3, 0x4d, 0x9a, 0x58, 0xdb, 0xd0, 0xbb, 0xf9, 0x9a, 0xa3, 0xee, +- 0xfd, 0x8a, 0x4e, 0xbf, 0x9c, 0x1c, 0xed, 0x06, 0xce, 0x07, 0x54, 0x3e, +- 0xa4, 0xed, 0xbe, 0x07, 0x7e, 0x25, 0xfd, 0x38, 0xea, 0x5b, 0x1f, 0xcf, +- 0x87, 0x50, 0xf7, 0x0b, 0xe0, 0x9e, 0x75, 0xf0, 0x39, 0x95, 0xee, 0xfd, +- 0xb4, 0x6c, 0x57, 0x98, 0x9f, 0x5d, 0x3f, 0x90, 0x53, 0xe7, 0xc1, 0x98, +- 0x8d, 0x2f, 0x9b, 0xfc, 0x5c, 0x35, 0xfa, 0xcc, 0x8e, 0xb9, 0xab, 0x66, +- 0xcc, 0x66, 0x40, 0x8a, 0xeb, 0x94, 0x3f, 0x96, 0x5a, 0xeb, 0x56, 0xe0, +- 0xad, 0x52, 0xaa, 0xef, 0x75, 0xef, 0xde, 0x6a, 0x3d, 0x93, 0x56, 0xbe, +- 0xec, 0xf9, 0x92, 0x39, 0x63, 0xfd, 0x1d, 0x64, 0x70, 0x27, 0x7f, 0x38, +- 0xaa, 0xe3, 0x09, 0xd9, 0x81, 0x5e, 0xfa, 0x0f, 0x7d, 0x1a, 0xbf, 0xf4, +- 0x7b, 0x7f, 0x65, 0x6c, 0x51, 0xfa, 0xbc, 0x03, 0x4a, 0x4f, 0xdb, 0x0d, +- 0x9f, 0x4e, 0x98, 0x73, 0x43, 0x7f, 0xf8, 0xa0, 0x64, 0xeb, 0x90, 0x9b, +- 0x83, 0x7c, 0x3f, 0x6b, 0xc6, 0xf2, 0xb9, 0x25, 0x47, 0x27, 0x76, 0xdf, +- 0xa7, 0x4f, 0x6a, 0x3f, 0xbb, 0xd7, 0xbf, 0x53, 0xf7, 0x73, 0x4d, 0x7d, +- 0x78, 0x15, 0x9c, 0xa0, 0x27, 0x1f, 0x06, 0xbd, 0xd6, 0x11, 0xc0, 0xcb, +- 0x18, 0xe4, 0x80, 0xcb, 0x5c, 0x9d, 0x80, 0x4c, 0x0c, 0x24, 0x98, 0xc3, +- 0xa7, 0xe0, 0x69, 0xd4, 0x43, 0x68, 0xf3, 0xe1, 0xd4, 0xfe, 0x79, 0xa3, +- 0xce, 0xf6, 0x38, 0xd6, 0xea, 0x96, 0x89, 0x41, 0xe2, 0x79, 0x37, 0x1c, +- 0x03, 0x81, 0xbd, 0x73, 0xd4, 0x1e, 0xec, 0x80, 0xef, 0xee, 0xef, 0x47, +- 0x73, 0xf0, 0xc3, 0x72, 0x2b, 0x8c, 0x15, 0x10, 0xc6, 0x01, 0xc8, 0x39, +- 0xec, 0x31, 0xed, 0xe7, 0x0e, 0xfb, 0x78, 0xf1, 0x63, 0x0c, 0x21, 0x45, +- 0x17, 0x73, 0x19, 0xee, 0x25, 0x64, 0x62, 0x0e, 0x84, 0x2b, 0x61, 0xf2, +- 0x0f, 0x09, 0x9f, 0x7d, 0x40, 0x9f, 0xff, 0xfd, 0x66, 0xbf, 0x7e, 0xce, +- 0x22, 0xe7, 0xba, 0x17, 0xe3, 0xbf, 0xd2, 0xc2, 0x5a, 0x34, 0xe8, 0xc0, +- 0xff, 0xbe, 0xaf, 0x7f, 0xaf, 0x9e, 0xab, 0xd7, 0xff, 0xa6, 0x2f, 0x66, +- 0xbe, 0xe3, 0x23, 0x9c, 0xe4, 0x2f, 0x1f, 0x87, 0x9c, 0x63, 0xc0, 0xdc, +- 0x23, 0x10, 0x86, 0x9e, 0x5d, 0x30, 0x24, 0xd2, 0x77, 0xca, 0xb8, 0x43, +- 0x1d, 0x7b, 0x27, 0xad, 0xf5, 0xc9, 0x42, 0xad, 0x57, 0xca, 0x35, 0xe6, +- 0x53, 0xf3, 0xfb, 0x32, 0xda, 0x59, 0xe4, 0x4b, 0x95, 0x37, 0x69, 0xf2, +- 0x15, 0x7d, 0xfe, 0xec, 0x43, 0x3f, 0xea, 0x10, 0x94, 0x75, 0x2d, 0x9f, +- 0xea, 0x72, 0x77, 0xce, 0xe2, 0x7c, 0x3b, 0x67, 0x51, 0xe7, 0x25, 0x15, +- 0xdb, 0x79, 0x22, 0xcc, 0x89, 0xeb, 0xcc, 0x41, 0x2a, 0xc9, 0xa3, 0x87, +- 0x7b, 0x24, 0xb9, 0xdc, 0x6b, 0x68, 0xf4, 0x3d, 0x66, 0x1d, 0xac, 0xb7, +- 0x34, 0x29, 0xc9, 0xa5, 0x3f, 0x86, 0x6f, 0xaf, 0xf2, 0x22, 0x3b, 0xf2, +- 0xdb, 0x87, 0xcd, 0xb7, 0x48, 0x59, 0x8b, 0xf9, 0x28, 0xf9, 0x25, 0x9c, +- 0xd7, 0xe1, 0xc4, 0x68, 0xdc, 0xe6, 0xb7, 0xb8, 0x27, 0x24, 0xb9, 0x3a, +- 0xa9, 0xbf, 0x89, 0x4b, 0xf3, 0x46, 0x3e, 0xa1, 0xec, 0xe9, 0xd4, 0x65, +- 0x3d, 0x9f, 0xbb, 0xc4, 0xf6, 0x14, 0x6c, 0x47, 0xb6, 0xe7, 0x63, 0x01, +- 0x75, 0x6b, 0x7f, 0x3f, 0xe8, 0xa9, 0xcb, 0xd8, 0x03, 0xcc, 0xe9, 0xe4, +- 0x78, 0xda, 0x1e, 0xa7, 0x71, 0x66, 0xf9, 0xb8, 0x2d, 0x1c, 0xa3, 0xe6, +- 0xc3, 0xb3, 0x7f, 0x47, 0x44, 0x5c, 0x8f, 0xcb, 0x7a, 0xd3, 0x05, 0x4f, +- 0xe8, 0x9c, 0xf8, 0x62, 0xdd, 0xcf, 0xe5, 0x7c, 0xb4, 0x9d, 0xcb, 0x49, +- 0x18, 0x0b, 0x95, 0xdd, 0xb4, 0x77, 0xc8, 0xe4, 0x54, 0xf6, 0xa8, 0xfb, +- 0xd9, 0x0e, 0xf9, 0x67, 0xfa, 0x3f, 0x73, 0x80, 0x77, 0xf7, 0x22, 0x6c, +- 0x1f, 0x34, 0xed, 0xb0, 0x8f, 0xa2, 0x51, 0xc5, 0x07, 0xc9, 0x86, 0xdf, +- 0xef, 0xfa, 0x01, 0x9d, 0x0b, 0x4a, 0x3c, 0x79, 0x06, 0xe6, 0x09, 0xf8, +- 0xb1, 0xac, 0x3b, 0x88, 0xb1, 0x3c, 0x27, 0x94, 0x8d, 0x83, 0x2a, 0xd7, +- 0x30, 0xe0, 0x4d, 0x99, 0x7b, 0xc1, 0x41, 0xb5, 0x96, 0xe3, 0x71, 0x7e, +- 0x5f, 0x36, 0xf4, 0x74, 0xac, 0xbf, 0x1b, 0x5e, 0xc6, 0xe0, 0xfc, 0xdc, +- 0x51, 0xb6, 0xf3, 0x7d, 0x77, 0x1f, 0x3f, 0x4f, 0x34, 0x6b, 0x05, 0xdb, +- 0x39, 0xf6, 0xc4, 0x25, 0xef, 0x96, 0x51, 0x5e, 0xf6, 0x00, 0x23, 0x9f, +- 0x51, 0x9a, 0x6f, 0x07, 0x82, 0x4b, 0xfc, 0xed, 0x9e, 0x27, 0x88, 0xb9, +- 0x7d, 0x9e, 0xdd, 0x3b, 0xa7, 0xb4, 0xcb, 0x3b, 0x6f, 0x6d, 0x57, 0x98, +- 0x27, 0x51, 0x92, 0x93, 0x99, 0x3e, 0x99, 0xab, 0xd9, 0xfc, 0xc6, 0x93, +- 0x31, 0x7a, 0xde, 0x83, 0xcb, 0xbc, 0x92, 0x71, 0x23, 0xc6, 0xe7, 0xee, +- 0x81, 0x6f, 0x4e, 0x7a, 0x1e, 0x91, 0xf5, 0xfa, 0x4c, 0x47, 0xfe, 0x6d, +- 0x97, 0xa1, 0xb3, 0x7f, 0x1d, 0x92, 0xde, 0x12, 0x7c, 0x32, 0x9f, 0xa7, +- 0x47, 0xa4, 0x50, 0xef, 0xbc, 0x3b, 0x63, 0xae, 0x4f, 0xe7, 0x37, 0xb4, +- 0x4a, 0x0f, 0xd6, 0x4a, 0xb4, 0xab, 0xa2, 0x8c, 0x4b, 0xb0, 0xdf, 0x7e, +- 0xa3, 0x6f, 0xe1, 0x08, 0xf5, 0xbe, 0xc5, 0x12, 0x97, 0xb0, 0x41, 0x47, +- 0xa8, 0x75, 0x52, 0x72, 0x34, 0x5a, 0x82, 0x8f, 0x3a, 0x62, 0xd6, 0x7d, +- 0x3b, 0xde, 0xd9, 0xf7, 0x80, 0x69, 0xbf, 0xd7, 0xbc, 0xf7, 0x9a, 0xf7, +- 0x00, 0xde, 0xeb, 0xad, 0x5a, 0x95, 0x73, 0xb2, 0xe4, 0xf7, 0x22, 0xbc, +- 0xdb, 0xf2, 0x24, 0x74, 0x59, 0xa0, 0xa7, 0x7a, 0xe5, 0xf1, 0xba, 0xc2, +- 0xaf, 0xe5, 0x2e, 0xd1, 0x20, 0xd8, 0x6f, 0x9e, 0xef, 0xe6, 0xc1, 0x4f, +- 0xde, 0x91, 0x37, 0x3c, 0xec, 0x98, 0xdc, 0xec, 0x0e, 0x78, 0xb3, 0x80, +- 0xf5, 0xd7, 0xe5, 0x41, 0x51, 0x47, 0x69, 0x5f, 0xb9, 0x50, 0xd1, 0xf9, +- 0x3e, 0x27, 0x2b, 0x80, 0xb5, 0xf6, 0x3f, 0x0e, 0xe8, 0xdc, 0x14, 0x3f, +- 0x9f, 0x91, 0xf9, 0xee, 0x23, 0x26, 0x27, 0x82, 0x63, 0x99, 0x57, 0xe9, +- 0xdf, 0x39, 0x76, 0xda, 0xaa, 0xd4, 0x45, 0xd4, 0x33, 0xfc, 0x6e, 0x25, +- 0x8d, 0xbe, 0x8b, 0x94, 0x35, 0xd0, 0x53, 0xbe, 0x2d, 0xf1, 0x39, 0xe5, +- 0x1f, 0x76, 0x7e, 0xf7, 0x73, 0x0e, 0xb0, 0xfe, 0x65, 0x93, 0x71, 0xe1, +- 0x1e, 0x09, 0x2c, 0xfb, 0x79, 0x50, 0x3c, 0x63, 0xda, 0x61, 0xfc, 0xb6, +- 0xfa, 0x77, 0x77, 0xc5, 0x8c, 0x7d, 0x5b, 0x81, 0x74, 0x3e, 0xe7, 0x30, +- 0xc7, 0xd4, 0xf1, 0xfc, 0x38, 0x33, 0x73, 0x6b, 0x68, 0x73, 0x1d, 0x14, +- 0x5b, 0xc5, 0x8d, 0xd8, 0x56, 0x92, 0xfe, 0xc3, 0xbf, 0x4b, 0xde, 0xf8, +- 0x47, 0xfc, 0x16, 0x46, 0xe7, 0x79, 0xab, 0x75, 0xa2, 0xda, 0x86, 0xe4, +- 0x37, 0xda, 0x69, 0xf0, 0xd5, 0xbe, 0x2d, 0x9d, 0xf3, 0x1d, 0xc1, 0x7b, +- 0x06, 0x74, 0x0c, 0x99, 0x2a, 0xfc, 0x1e, 0x9b, 0x7c, 0xc7, 0xef, 0xb1, +- 0x3d, 0x95, 0x6f, 0xb2, 0x6d, 0xbe, 0x2f, 0xba, 0xde, 0x0c, 0x8a, 0xbd, +- 0x34, 0xce, 0x6f, 0xd5, 0xf8, 0x6d, 0x23, 0x6c, 0xb5, 0x38, 0xda, 0x99, +- 0xc7, 0x36, 0xa4, 0xf2, 0x54, 0xca, 0xcd, 0x8f, 0xa0, 0xfc, 0x34, 0xfc, +- 0x75, 0x1d, 0x9f, 0x2f, 0x37, 0x99, 0xaf, 0xe2, 0xa8, 0x7b, 0xcf, 0xe4, +- 0x52, 0x01, 0xeb, 0xf9, 0xdf, 0x3e, 0x47, 0x51, 0x47, 0xf8, 0x4a, 0x86, +- 0x47, 0xfd, 0x5c, 0x84, 0x0d, 0x87, 0x3a, 0xa1, 0xd4, 0x8c, 0xa8, 0x1c, +- 0x17, 0x6d, 0x8f, 0xd0, 0xd6, 0x0b, 0xa3, 0x2f, 0xf7, 0xda, 0x4b, 0x7d, +- 0xd5, 0xa2, 0x4c, 0x4a, 0x61, 0x9d, 0x86, 0xca, 0x0f, 0x24, 0x9e, 0x5d, +- 0xa7, 0x48, 0x7f, 0x4d, 0xc9, 0xf8, 0xc4, 0xe8, 0xac, 0xe4, 0x9d, 0x10, +- 0x7c, 0xb1, 0xb2, 0xf2, 0x73, 0x5e, 0x80, 0x0d, 0x1d, 0xd9, 0x0a, 0x78, +- 0xdc, 0x1b, 0xd7, 0xa6, 0x1f, 0xa2, 0xf7, 0xa3, 0xef, 0x8e, 0xc4, 0x2a, +- 0xab, 0xef, 0xf5, 0x58, 0xcf, 0x7b, 0x01, 0xff, 0x7b, 0x6c, 0xe6, 0xef, +- 0xc3, 0x4f, 0x68, 0x4e, 0xc9, 0xd9, 0xca, 0x7e, 0xe6, 0xc6, 0xa7, 0xb7, +- 0x81, 0xb7, 0x93, 0xed, 0x7c, 0x7d, 0xe6, 0xb0, 0xf9, 0xba, 0x87, 0x67, +- 0xc5, 0x5c, 0x79, 0xd2, 0x19, 0xf3, 0xe5, 0x69, 0x87, 0x0d, 0xc9, 0xe3, +- 0x4d, 0x3f, 0x47, 0x7e, 0x2f, 0x3b, 0x9c, 0x34, 0xf8, 0x59, 0xf8, 0x86, +- 0x7e, 0x2e, 0x24, 0x73, 0x36, 0x5b, 0xad, 0x93, 0x69, 0xde, 0xc7, 0xce, +- 0x1c, 0x5d, 0xc3, 0x1e, 0xaf, 0xd5, 0x81, 0xc3, 0xe3, 0xac, 0x63, 0xee, +- 0x56, 0xb7, 0xe4, 0xc6, 0x55, 0xbc, 0xaf, 0x77, 0xcd, 0xdd, 0x2f, 0x57, +- 0x6b, 0x51, 0x95, 0x87, 0x56, 0x84, 0x9d, 0xdf, 0x90, 0xdb, 0x0e, 0xef, +- 0xa3, 0x8f, 0xa8, 0xf1, 0x3e, 0xbf, 0x73, 0x9d, 0xa8, 0x1c, 0x59, 0xd7, +- 0xf2, 0xe4, 0x54, 0x06, 0x76, 0xcb, 0x25, 0xb1, 0x3e, 0x9a, 0x19, 0x82, +- 0xef, 0xcd, 0xb5, 0x52, 0x18, 0x07, 0xda, 0x89, 0x91, 0xd7, 0x7f, 0xd1, +- 0x6a, 0x00, 0xde, 0xdb, 0x4d, 0xda, 0xeb, 0xb0, 0xa1, 0x66, 0x38, 0xc6, +- 0x13, 0xfb, 0x02, 0xfb, 0x0c, 0x80, 0xfe, 0x42, 0xfa, 0x7b, 0xb4, 0xca, +- 0x01, 0x69, 0x38, 0x6c, 0xe3, 0x73, 0x4c, 0x1a, 0x51, 0xdf, 0x4f, 0xf9, +- 0x21, 0xf0, 0x17, 0x57, 0x32, 0xc9, 0xbf, 0xc3, 0x67, 0x4e, 0xe9, 0x5c, +- 0xed, 0x18, 0x78, 0x28, 0x68, 0x6c, 0xb3, 0x20, 0xe6, 0xf8, 0xbe, 0xa3, +- 0x6d, 0x05, 0xde, 0xf1, 0x6b, 0x5b, 0x44, 0xeb, 0x18, 0xde, 0xfb, 0x05, +- 0xe1, 0x0b, 0xf8, 0x7c, 0x79, 0xc8, 0xd8, 0x14, 0x9d, 0xbe, 0x7c, 0x2a, +- 0x76, 0x91, 0xff, 0x0f, 0x62, 0xf3, 0x83, 0x32, 0x0b, 0x98, 0xcf, 0x9b, +- 0x7d, 0x3e, 0x92, 0x71, 0xe5, 0x56, 0x9d, 0x77, 0xf0, 0x07, 0x51, 0x32, +- 0xdf, 0x90, 0x30, 0x8f, 0x99, 0x9c, 0x4a, 0x0f, 0x7b, 0x3d, 0x21, 0x2f, +- 0xc3, 0xbe, 0x7e, 0xa5, 0x92, 0x4a, 0x1f, 0x51, 0x71, 0xe7, 0x44, 0xec, +- 0xaa, 0x8c, 0xc5, 0xe9, 0x03, 0x96, 0x9c, 0x44, 0xec, 0x16, 0xe8, 0xe1, +- 0x76, 0xe5, 0x50, 0x3f, 0xff, 0x27, 0x45, 0x03, 0xfa, 0xf0, 0xb6, 0xca, +- 0x81, 0x49, 0x30, 0x66, 0x82, 0xf7, 0x21, 0x93, 0x87, 0xc3, 0x75, 0xd8, +- 0x36, 0x24, 0x2f, 0x57, 0xda, 0xfa, 0x97, 0xeb, 0xe8, 0xdc, 0x36, 0xa5, +- 0x5f, 0x8f, 0xf6, 0x53, 0x0e, 0x71, 0x3d, 0x3d, 0x87, 0xdf, 0x87, 0x78, +- 0xf5, 0x63, 0x91, 0x8e, 0xfe, 0xbe, 0xc1, 0x62, 0xde, 0x0b, 0xf7, 0xfe, +- 0x13, 0x47, 0xdb, 0x40, 0x1c, 0x97, 0x72, 0x8e, 0xaa, 0xf9, 0x78, 0xdf, +- 0x3b, 0x24, 0x3f, 0x6e, 0xfa, 0xf3, 0x30, 0x1f, 0x87, 0x39, 0x3f, 0x94, +- 0x7d, 0x9d, 0x30, 0x68, 0xfd, 0xff, 0xb2, 0x8a, 0xeb, 0x4d, 0xa2, 0x3f, +- 0x75, 0x34, 0xe8, 0xa5, 0x1e, 0xd3, 0xff, 0xdf, 0xa1, 0x2d, 0xe3, 0xf8, +- 0x4c, 0x7c, 0x72, 0x1d, 0xd8, 0xf8, 0x0f, 0x38, 0xa6, 0xdd, 0xb7, 0x4b, +- 0x87, 0xc0, 0xaf, 0x27, 0xa4, 0xb1, 0x92, 0x8a, 0x3d, 0x2e, 0xfe, 0xbc, +- 0xad, 0x87, 0x79, 0x2f, 0x56, 0xc8, 0x8c, 0x39, 0x0b, 0x0a, 0x1e, 0xde, +- 0xdd, 0x26, 0x9c, 0xab, 0x58, 0xaf, 0xd1, 0xdc, 0x1d, 0x7b, 0x48, 0x64, +- 0xb7, 0x24, 0x95, 0xd6, 0x67, 0x33, 0x22, 0x5b, 0x38, 0x9b, 0x3f, 0x31, +- 0x67, 0xf3, 0x7e, 0xcc, 0xed, 0x5e, 0x18, 0x97, 0xd4, 0x85, 0x54, 0xfc, +- 0xbc, 0xf0, 0x8e, 0xf9, 0x00, 0xef, 0x98, 0xad, 0x47, 0x32, 0x71, 0xec, +- 0x37, 0x81, 0xfd, 0xa2, 0x6c, 0xf2, 0x99, 0xdf, 0xf7, 0xef, 0x23, 0x6f, +- 0x3f, 0x4c, 0x99, 0x49, 0x5c, 0x14, 0x54, 0x1b, 0xec, 0x93, 0xa7, 0x08, +- 0xd3, 0xbf, 0xe3, 0xf9, 0xa8, 0x58, 0xe8, 0xad, 0x26, 0xbf, 0x5b, 0xd5, +- 0xf0, 0xe5, 0x01, 0xdf, 0xbc, 0x86, 0x2f, 0x3e, 0xdb, 0xb6, 0x5d, 0x13, +- 0xb1, 0xb3, 0x42, 0x7b, 0x89, 0xf6, 0x0b, 0xed, 0xfa, 0xbf, 0xe9, 0xd7, +- 0xb1, 0x3d, 0xf8, 0xb1, 0x0f, 0x64, 0xdb, 0x7b, 0xef, 0x42, 0xdf, 0x6b, +- 0x19, 0x95, 0x63, 0xec, 0x4c, 0xc9, 0x7b, 0x25, 0xfb, 0x91, 0x44, 0x3c, +- 0x6b, 0xb9, 0xc6, 0x06, 0x44, 0x59, 0xe7, 0x33, 0x65, 0xae, 0x6b, 0x6c, +- 0x0b, 0x9e, 0x4d, 0x06, 0x6b, 0x29, 0xdc, 0xc2, 0x67, 0x1a, 0x02, 0xcd, +- 0x93, 0xd6, 0xde, 0x05, 0x1e, 0xd2, 0xff, 0x13, 0xe3, 0x2a, 0xf0, 0x58, +- 0x06, 0x1e, 0x4f, 0xdd, 0x65, 0x83, 0x85, 0xda, 0x36, 0xd8, 0xb6, 0x5a, +- 0xef, 0x26, 0x60, 0xca, 0x3b, 0xb4, 0xbf, 0xca, 0x6d, 0x5a, 0x21, 0x4c, +- 0xe3, 0xfc, 0x2e, 0x5b, 0xae, 0x67, 0x78, 0x1e, 0xb0, 0xc1, 0x30, 0xdf, +- 0xda, 0x0e, 0x2d, 0x61, 0xff, 0x8a, 0x7e, 0x41, 0xbb, 0x09, 0x27, 0x68, +- 0xf1, 0x2c, 0x38, 0x9f, 0x58, 0x37, 0x00, 0xcb, 0xb6, 0xa2, 0x03, 0x4d, +- 0x03, 0xdb, 0xf5, 0xde, 0x37, 0xa0, 0x01, 0xee, 0x93, 0xf4, 0xe7, 0xd3, +- 0x5e, 0xfb, 0xbb, 0x75, 0xf8, 0xb7, 0x25, 0xb9, 0xff, 0x90, 0x27, 0xb9, +- 0x0b, 0x2d, 0x59, 0x48, 0x8b, 0x35, 0x76, 0x88, 0x34, 0x49, 0x3b, 0x01, +- 0x36, 0x64, 0x8c, 0x38, 0xd6, 0xf6, 0xe0, 0xec, 0x57, 0xf7, 0xe3, 0xf7, +- 0x6f, 0xfa, 0x79, 0xbf, 0x94, 0xdb, 0xa0, 0xbc, 0x12, 0xeb, 0xbe, 0x43, +- 0xda, 0x3f, 0xbc, 0x1d, 0x05, 0xce, 0xd1, 0x9e, 0x7c, 0xa2, 0xcb, 0xc4, +- 0x51, 0xb5, 0x5e, 0x4e, 0x3e, 0x41, 0xbc, 0xa2, 0xfc, 0xea, 0x4f, 0x1c, +- 0x3f, 0x27, 0x49, 0xc7, 0x04, 0xc9, 0x17, 0x25, 0x99, 0xcf, 0x30, 0x27, +- 0xb4, 0x57, 0x8e, 0x40, 0xae, 0x4d, 0x55, 0x26, 0xe5, 0x0b, 0x95, 0x88, +- 0xb2, 0x1b, 0xfe, 0x2c, 0x9d, 0x8a, 0x8d, 0x5a, 0x2d, 0x79, 0x04, 0xf6, +- 0xcf, 0xec, 0x50, 0x97, 0xbc, 0x32, 0xae, 0xf3, 0x6f, 0x6f, 0x33, 0xb9, +- 0xce, 0x61, 0xce, 0x28, 0xf7, 0x03, 0xb9, 0x6f, 0xc1, 0x17, 0xb0, 0xba, +- 0x65, 0x36, 0x1a, 0x91, 0xe9, 0x34, 0xca, 0x37, 0xa7, 0xd5, 0x37, 0xa4, +- 0xd9, 0x68, 0xa7, 0x1c, 0x21, 0xcc, 0x2c, 0xdf, 0x62, 0xca, 0x9f, 0xf5, +- 0x77, 0xc0, 0x62, 0xcd, 0x67, 0x02, 0x6a, 0x7f, 0xe5, 0x3a, 0xe5, 0x1b, +- 0xc7, 0x40, 0x9e, 0x34, 0x79, 0x0f, 0x59, 0x92, 0x35, 0xc8, 0x97, 0x62, +- 0x4d, 0xac, 0x8d, 0x0c, 0x2c, 0x6a, 0x57, 0xdb, 0x9f, 0x45, 0xd0, 0xd7, +- 0x5c, 0x8d, 0xf2, 0x6f, 0x4a, 0xe5, 0x4e, 0xcf, 0xc1, 0xd6, 0x85, 0x4f, +- 0x3c, 0xdb, 0xed, 0x99, 0x7b, 0xce, 0x5e, 0xc6, 0x43, 0x3a, 0x65, 0x98, +- 0xff, 0x3f, 0x73, 0x0e, 0x0f, 0x48, 0x5f, 0x09, 0xe7, 0xe2, 0xdb, 0xdc, +- 0xc0, 0x29, 0xd6, 0xcc, 0xa9, 0x73, 0xf2, 0xcf, 0x84, 0xb2, 0xa7, 0x33, +- 0x67, 0xdb, 0xb7, 0x39, 0xc8, 0xb3, 0xd4, 0x17, 0x52, 0x0a, 0xc3, 0xa6, +- 0xed, 0xb9, 0x00, 0xdd, 0x5d, 0xf3, 0x40, 0x2b, 0x93, 0xd0, 0x87, 0x93, +- 0x52, 0x86, 0xed, 0xf6, 0xd1, 0xf4, 0x67, 0xc5, 0x7e, 0xea, 0xa0, 0xac, +- 0xd5, 0x7a, 0x80, 0x0f, 0xea, 0x85, 0x90, 0xf2, 0xaf, 0x6f, 0x1f, 0xa7, +- 0xbe, 0xa3, 0x2e, 0xd1, 0x67, 0xb1, 0x5d, 0xff, 0xc4, 0x80, 0xfe, 0x7e, +- 0x65, 0xbf, 0x6c, 0xd5, 0x7d, 0x5d, 0x08, 0xff, 0xb0, 0x16, 0x32, 0x7a, +- 0xb9, 0x17, 0xb2, 0xfb, 0xaf, 0x43, 0x0d, 0xe5, 0xab, 0x73, 0xff, 0xd4, +- 0x41, 0xea, 0xff, 0x70, 0xf4, 0x36, 0x5c, 0xee, 0xbd, 0x53, 0x07, 0x69, +- 0xbb, 0xc3, 0x39, 0xcc, 0xf5, 0x78, 0x1f, 0xc7, 0x3d, 0x46, 0x25, 0x74, +- 0xf1, 0x84, 0xd8, 0xf0, 0x5b, 0x02, 0x4b, 0xb4, 0xf5, 0xee, 0xf4, 0x5d, +- 0x02, 0x97, 0x6d, 0xf3, 0xad, 0xed, 0xb0, 0xb6, 0x65, 0x32, 0x28, 0x1b, +- 0xfe, 0xf7, 0xb7, 0xfc, 0xdd, 0xe1, 0xdb, 0x1d, 0x78, 0x03, 0x5d, 0x8a, +- 0xbf, 0xff, 0x0b, 0xc4, 0xbf, 0x6d, 0x24, 0x80, 0x4a, 0x00, 0x00, 0x00 }; ++ 0xcd, 0x7c, 0x7f, 0x6c, 0x5c, 0xd7, 0x75, 0xe6, 0x79, 0x6f, 0xde, 0x90, ++ 0x43, 0x8a, 0xa2, 0x1e, 0x99, 0x31, 0x33, 0x8e, 0xd8, 0x7a, 0x86, 0xf3, ++ 0x48, 0xd1, 0x21, 0xe3, 0x3e, 0x33, 0x63, 0x99, 0x76, 0xa6, 0xd6, 0x64, ++ 0x66, 0x28, 0x2b, 0x0e, 0x69, 0xd0, 0x8e, 0x82, 0x4d, 0x01, 0x03, 0xe5, ++ 0x0e, 0xa9, 0x54, 0xd9, 0xf5, 0x22, 0xda, 0x34, 0x45, 0x8a, 0xa2, 0x88, ++ 0x26, 0x24, 0xe5, 0x2a, 0xcd, 0x88, 0x1c, 0xcb, 0x34, 0x1b, 0x14, 0x5e, ++ 0x64, 0x3c, 0xa4, 0x14, 0xb7, 0x1d, 0x89, 0x72, 0xe2, 0x2d, 0xbc, 0x58, ++ 0x07, 0x66, 0xa9, 0x1f, 0x4e, 0x83, 0x14, 0xf0, 0x2e, 0xbc, 0x68, 0x60, ++ 0xa4, 0x80, 0x20, 0xbb, 0x8d, 0xb3, 0xc8, 0x62, 0x83, 0xdd, 0x00, 0x71, ++ 0x02, 0x27, 0x6f, 0xbf, 0xef, 0xde, 0xfb, 0xc8, 0xd1, 0x88, 0x76, 0xd2, ++ 0xfc, 0xb5, 0x04, 0x06, 0xf7, 0xfd, 0xb8, 0x3f, 0xce, 0x3d, 0xf7, 0xdc, ++ 0x73, 0xbe, 0x73, 0xee, 0x79, 0x7c, 0x40, 0xa4, 0x53, 0xcc, 0xdf, 0x5e, ++ 0xfc, 0x32, 0xff, 0xe1, 0xb3, 0xb3, 0x63, 0x77, 0x65, 0xee, 0xc2, 0xe5, ++ 0x87, 0xed, 0xf7, 0x3b, 0x0e, 0x9f, 0x47, 0xf0, 0x8b, 0xe3, 0x37, 0x66, ++ 0xae, 0x77, 0xfb, 0x73, 0xf1, 0x3b, 0x68, 0x89, 0xcc, 0xfc, 0x4f, 0x11, ++ 0xab, 0xe5, 0x5d, 0xec, 0x5d, 0xda, 0xbc, 0xd7, 0x9f, 0xfd, 0x1b, 0xb4, ++ 0xf9, 0xd7, 0xfe, 0x45, 0x34, 0xd9, 0x6a, 0xde, 0xfc, 0x49, 0xcc, 0xce, ++ 0xce, 0x4c, 0xe6, 0x3d, 0x89, 0x45, 0xb2, 0x47, 0xa7, 0x66, 0x3d, 0x91, ++ 0x5c, 0x63, 0x24, 0x59, 0x90, 0x5f, 0x04, 0xe5, 0xb8, 0x23, 0x7c, 0xfe, ++ 0x5b, 0xd9, 0x77, 0xbe, 0xf6, 0xad, 0x7b, 0x53, 0x3f, 0xae, 0x45, 0x24, ++ 0xe6, 0x66, 0xdf, 0x16, 0x77, 0x48, 0x62, 0xfd, 0x68, 0xf3, 0xcc, 0x81, ++ 0x57, 0x6d, 0xe9, 0x0e, 0xfb, 0x72, 0x67, 0x22, 0x59, 0x99, 0x3e, 0x56, ++ 0x39, 0x19, 0xd8, 0x9e, 0x94, 0x9d, 0xac, 0x37, 0x5c, 0x97, 0xae, 0xf1, ++ 0x73, 0x99, 0x7b, 0x05, 0xf7, 0xd3, 0xc7, 0x1a, 0x31, 0x99, 0x6f, 0x94, ++ 0xbb, 0x6c, 0xcf, 0x43, 0x29, 0xb1, 0xb6, 0xec, 0x62, 0xec, 0x9a, 0xc7, ++ 0xb1, 0xbf, 0x8a, 0xb1, 0xf7, 0x4b, 0xd4, 0x0b, 0x82, 0x73, 0x18, 0xfb, ++ 0x70, 0xe3, 0x17, 0xc1, 0xb3, 0x8e, 0x1e, 0xd7, 0xce, 0x9e, 0x88, 0xb0, ++ 0xb4, 0xb2, 0xb5, 0xc9, 0x81, 0x06, 0xef, 0x8b, 0xed, 0x9a, 0x4e, 0xbf, ++ 0x13, 0x74, 0xc6, 0x9c, 0xec, 0x89, 0xce, 0x45, 0x94, 0xd1, 0x6c, 0x7c, ++ 0xec, 0x9c, 0xaa, 0xb7, 0x6e, 0xea, 0x3d, 0x1e, 0xd5, 0xed, 0xde, 0x9a, ++ 0x1c, 0x6a, 0xb0, 0xfc, 0xc9, 0xe4, 0xa0, 0x2a, 0xdf, 0x99, 0x4c, 0xab, ++ 0x52, 0xa6, 0x06, 0x54, 0xe9, 0x4c, 0x79, 0xaa, 0x7c, 0xc6, 0x3c, 0x7f, ++ 0x6e, 0x32, 0xa9, 0xca, 0x86, 0x29, 0x2f, 0x99, 0xf2, 0x05, 0x53, 0xbe, ++ 0x68, 0xca, 0x97, 0x4c, 0xb9, 0x69, 0xca, 0x2b, 0x93, 0xba, 0x9f, 0x6f, ++ 0x9b, 0xfb, 0xef, 0x9a, 0xf2, 0x55, 0x53, 0xbe, 0x66, 0xca, 0xef, 0x99, ++ 0xf2, 0xfb, 0x86, 0xae, 0xeb, 0xa6, 0x7c, 0xd3, 0x94, 0x3f, 0x32, 0xef, ++ 0x7f, 0x6c, 0xe8, 0x7d, 0x1b, 0x74, 0xfd, 0x49, 0xd4, 0xc8, 0x2a, 0xe6, ++ 0x9d, 0x94, 0xd9, 0x8a, 0x23, 0xf3, 0xcb, 0x11, 0x29, 0xa8, 0x35, 0xfc, ++ 0xca, 0x5e, 0xe9, 0x74, 0x64, 0x61, 0x23, 0x26, 0xd7, 0x95, 0x88, 0xbe, ++ 0x15, 0x7c, 0xeb, 0x80, 0x94, 0xed, 0xac, 0x2b, 0x97, 0x36, 0xe2, 0xf2, ++ 0xf2, 0x86, 0x58, 0xd3, 0x99, 0x0e, 0xb1, 0xcf, 0x7e, 0x40, 0x72, 0xae, ++ 0x25, 0x11, 0xc5, 0xd3, 0xa4, 0xe4, 0x2b, 0x7d, 0xb8, 0x4f, 0x25, 0x44, ++ 0xae, 0xee, 0xd5, 0xeb, 0x17, 0x93, 0xc8, 0x2a, 0xd7, 0xe4, 0xfe, 0xa9, ++ 0x6b, 0x2b, 0x09, 0x71, 0x96, 0x46, 0x31, 0x46, 0x97, 0x44, 0x57, 0xa5, ++ 0x3f, 0x22, 0x83, 0x89, 0x4f, 0xa3, 0x46, 0xb1, 0xe1, 0xc8, 0x44, 0xc3, ++ 0x12, 0xc7, 0x8b, 0x41, 0x3e, 0xba, 0xf0, 0x73, 0xf1, 0x8b, 0xe3, 0x97, ++ 0xc0, 0xef, 0x47, 0xe8, 0xa7, 0x5f, 0x0a, 0x0d, 0xf6, 0x89, 0x71, 0x97, ++ 0x31, 0xfe, 0x72, 0xca, 0x9d, 0x11, 0xd2, 0x95, 0x90, 0x6f, 0x1d, 0x20, ++ 0x5d, 0x2e, 0xe9, 0x01, 0x6d, 0x31, 0x2b, 0xbf, 0x22, 0x27, 0x0a, 0xbe, ++ 0x24, 0x6d, 0xaf, 0x53, 0x4a, 0xae, 0x95, 0x9c, 0x1b, 0xee, 0x95, 0xf2, ++ 0x51, 0xbc, 0x5f, 0x96, 0x9c, 0x8d, 0xfe, 0x4b, 0xae, 0xcc, 0xe8, 0x77, ++ 0x7c, 0xf6, 0x36, 0xf6, 0x6a, 0xca, 0xa5, 0xd0, 0xbe, 0xbc, 0xfc, 0xb7, ++ 0xb8, 0x66, 0x7f, 0x3f, 0x77, 0x34, 0xdd, 0x3f, 0xc5, 0x3d, 0x9f, 0x0f, ++ 0x99, 0x79, 0xf0, 0x9a, 0x75, 0xc3, 0x71, 0xc3, 0xf9, 0x72, 0xfc, 0x61, ++ 0xcc, 0x99, 0x34, 0x84, 0x73, 0x96, 0x72, 0x14, 0xb4, 0xd4, 0x57, 0xba, ++ 0xac, 0xb5, 0x95, 0x51, 0x79, 0x62, 0xf9, 0x01, 0xc9, 0xfb, 0x41, 0x30, ++ 0xeb, 0x4b, 0xdc, 0x96, 0x41, 0xb7, 0x80, 0x0a, 0x5b, 0x0d, 0xb1, 0xea, ++ 0x15, 0x89, 0xb5, 0x83, 0x2f, 0x3f, 0x58, 0x61, 0xdf, 0x0e, 0x9e, 0xf5, ++ 0xa1, 0x7e, 0xb7, 0xb5, 0xbe, 0x02, 0xfa, 0xb3, 0xe4, 0x4f, 0x10, 0x2c, ++ 0xfa, 0x83, 0x89, 0x39, 0x8c, 0x79, 0xb9, 0x31, 0x38, 0x7e, 0x43, 0x5c, ++ 0xf4, 0xd9, 0x8b, 0x3a, 0xe4, 0x15, 0xfb, 0x62, 0x9f, 0xec, 0xaf, 0x0b, ++ 0x6d, 0xe3, 0x78, 0x47, 0xba, 0x82, 0x20, 0xef, 0xbb, 0xbc, 0x97, 0x4d, ++ 0xf0, 0x6f, 0x93, 0xfc, 0xeb, 0xec, 0x97, 0x57, 0x1a, 0x1c, 0x63, 0x37, ++ 0xda, 0x47, 0xfe, 0x3f, 0xa4, 0x3d, 0x81, 0xfe, 0xe3, 0x28, 0xf7, 0x58, ++ 0xf5, 0x6a, 0x80, 0xf1, 0x13, 0xb8, 0xde, 0x6d, 0x1e, 0xd7, 0xd5, 0xda, ++ 0x5f, 0xc2, 0xda, 0xbb, 0xd9, 0xb8, 0x3c, 0xbf, 0xd1, 0x8f, 0x79, 0x24, ++ 0xe4, 0x1b, 0x90, 0xcd, 0x9e, 0x83, 0x7b, 0x24, 0x0d, 0xd9, 0xe4, 0x9a, ++ 0x8f, 0xad, 0xce, 0x49, 0x29, 0x9e, 0x1a, 0xa6, 0x1e, 0xcd, 0x8f, 0xed, ++ 0xc3, 0x7c, 0xb5, 0xb6, 0x1a, 0x58, 0xca, 0xed, 0xb7, 0xe5, 0x90, 0xd8, ++ 0x59, 0x8c, 0x9b, 0x19, 0x01, 0x2d, 0x11, 0xbc, 0x8b, 0x8b, 0xb7, 0x9a, ++ 0xc3, 0xb3, 0x54, 0xa2, 0x04, 0x1a, 0xe7, 0x41, 0x63, 0x49, 0xca, 0x62, ++ 0x5f, 0x7c, 0xce, 0x0a, 0xf7, 0x8a, 0xe6, 0xdd, 0xb0, 0xe9, 0x67, 0x5b, ++ 0xce, 0x2d, 0x7b, 0xb5, 0xcb, 0x8a, 0xac, 0x8e, 0xca, 0xa9, 0x5d, 0x78, ++ 0x56, 0x07, 0xcf, 0xec, 0xa5, 0x70, 0x1f, 0x38, 0xb8, 0xef, 0x43, 0xdd, ++ 0x6e, 0xcb, 0x59, 0xbd, 0x95, 0x5f, 0x6b, 0x8d, 0x41, 0x7f, 0x0b, 0xfc, ++ 0xb2, 0x57, 0x7b, 0x51, 0xe7, 0x56, 0x7e, 0xd5, 0xc1, 0x2f, 0x7b, 0x55, ++ 0xf3, 0xaa, 0x0e, 0x5e, 0xd9, 0x4b, 0x71, 0x94, 0x7b, 0x2c, 0xfb, 0xac, ++ 0xe6, 0x55, 0xdd, 0xec, 0x99, 0xf3, 0x4a, 0x5f, 0xe5, 0x40, 0xab, 0x25, ++ 0x5a, 0x67, 0xe5, 0x84, 0xba, 0x29, 0x92, 0x2d, 0x62, 0xaf, 0xdb, 0xe0, ++ 0x85, 0x23, 0xc5, 0x31, 0x4b, 0x66, 0xd5, 0xbb, 0xa2, 0xa4, 0x1b, 0x1f, ++ 0x00, 0x23, 0x47, 0x86, 0x61, 0x29, 0xca, 0x6d, 0xd9, 0x17, 0xed, 0xad, ++ 0x4a, 0x4c, 0x0a, 0x4e, 0x52, 0xbc, 0x25, 0xa5, 0xc7, 0x9b, 0xfa, 0x99, ++ 0x41, 0x3f, 0xdf, 0x01, 0x3f, 0x2c, 0xe8, 0x56, 0xbe, 0x7b, 0x4c, 0xed, ++ 0xfb, 0xf4, 0xaa, 0x23, 0x83, 0x4b, 0xac, 0x53, 0xb6, 0xaf, 0x34, 0xde, ++ 0x09, 0x74, 0xbf, 0x8f, 0x71, 0x4c, 0xd7, 0xce, 0x2e, 0xda, 0x97, 0xd7, ++ 0x4f, 0xdb, 0x57, 0x1b, 0xe8, 0xb7, 0xc1, 0xb5, 0xc0, 0x5a, 0x2d, 0x63, ++ 0xad, 0x96, 0xb1, 0x6e, 0x66, 0x4f, 0xd7, 0xd4, 0xde, 0x4a, 0x9a, 0x75, ++ 0x25, 0x0d, 0x5c, 0xdb, 0x04, 0xd6, 0x94, 0x6b, 0x2b, 0xd6, 0xab, 0x99, ++ 0x3d, 0x12, 0x39, 0x1b, 0x51, 0x6b, 0xda, 0xb3, 0xfa, 0x91, 0xed, 0x35, ++ 0x1d, 0x68, 0x5a, 0x53, 0xfb, 0x5d, 0xd6, 0xd4, 0xd9, 0x65, 0x4d, 0xb7, ++ 0x1a, 0x3f, 0x31, 0x6b, 0xfa, 0x73, 0x31, 0xb2, 0xff, 0x9e, 0xfc, 0x1a, ++ 0x00, 0xbf, 0xbc, 0x5f, 0x83, 0x5f, 0xce, 0xae, 0xfc, 0xea, 0xb3, 0x5b, ++ 0xf9, 0x15, 0x01, 0xbf, 0xa2, 0xbf, 0x36, 0xbf, 0xc0, 0x87, 0x5d, 0x79, ++ 0x15, 0x83, 0xde, 0x2b, 0x4b, 0x3e, 0x23, 0x92, 0xaf, 0x6a, 0x5d, 0x5d, ++ 0x56, 0x3a, 0x9b, 0xba, 0x2a, 0xd4, 0xd9, 0xd4, 0xd7, 0x6a, 0x9f, 0x58, ++ 0x85, 0x4a, 0x12, 0xba, 0xd4, 0x41, 0xf9, 0x1c, 0xca, 0x3d, 0xd6, 0x74, ++ 0xb5, 0x1f, 0x76, 0x36, 0x10, 0x77, 0x2c, 0xb4, 0x97, 0xe5, 0x84, 0x8b, ++ 0xb5, 0x71, 0xef, 0x8a, 0x8a, 0xf4, 0xa5, 0xc0, 0xa7, 0x14, 0xde, 0xa7, ++ 0x12, 0x39, 0xc9, 0xda, 0x21, 0xae, 0xc9, 0x57, 0x3a, 0xde, 0xce, 0xa9, ++ 0x2b, 0x3e, 0x67, 0xbb, 0x0c, 0x9e, 0x45, 0x65, 0x06, 0x76, 0xa0, 0xe8, ++ 0x71, 0x3c, 0xf6, 0x9f, 0x9c, 0xe1, 0xb8, 0x85, 0x46, 0xa8, 0xb3, 0x25, ++ 0x07, 0x1b, 0x8e, 0x77, 0xdc, 0xb7, 0xe3, 0x56, 0x41, 0xd9, 0xa0, 0x8c, ++ 0x78, 0x8d, 0x66, 0xfb, 0xb2, 0x4d, 0x27, 0xf6, 0x73, 0x0e, 0x72, 0x4d, ++ 0xda, 0x92, 0xd8, 0x7b, 0xc7, 0x22, 0xe1, 0xfa, 0x38, 0xd9, 0x71, 0x81, ++ 0x5d, 0x96, 0xf9, 0x0a, 0xfb, 0xfb, 0x63, 0x2b, 0x72, 0x31, 0xec, 0x9f, ++ 0x7c, 0x64, 0xdf, 0xba, 0xbf, 0xf9, 0xc6, 0x5b, 0x46, 0x37, 0x28, 0x5b, ++ 0x85, 0xfe, 0xca, 0x4d, 0xfd, 0x95, 0xad, 0xc8, 0x92, 0xec, 0x53, 0xf6, ++ 0xe0, 0x28, 0xf9, 0x77, 0x1a, 0xef, 0xae, 0x4b, 0x84, 0x32, 0xa3, 0xf6, ++ 0x18, 0xf7, 0xfb, 0x97, 0x38, 0xdf, 0x26, 0xde, 0x4e, 0xc3, 0xc6, 0x71, ++ 0x7f, 0x61, 0x8d, 0xe3, 0x7c, 0x7e, 0xc8, 0xd0, 0xe4, 0x48, 0x4e, 0xdd, ++ 0x7f, 0x63, 0x4f, 0xa8, 0x3f, 0xb1, 0x9f, 0x41, 0xdb, 0x8b, 0x6a, 0x8e, ++ 0x76, 0x36, 0x0b, 0xde, 0x34, 0xd3, 0xc8, 0x79, 0x67, 0xb1, 0xc6, 0xa1, ++ 0x0e, 0x0b, 0xd7, 0x8a, 0xb8, 0xc6, 0xb1, 0x16, 0x2a, 0x5d, 0xb0, 0x8f, ++ 0x31, 0x63, 0x83, 0xd9, 0x7e, 0x11, 0xed, 0xf9, 0x9c, 0x6d, 0xbb, 0x60, ++ 0x8f, 0xd9, 0x7e, 0xd1, 0xb4, 0xdf, 0xb1, 0xcb, 0xdc, 0x2b, 0xb4, 0xc9, ++ 0x57, 0x32, 0xc0, 0x42, 0x2b, 0xb6, 0x14, 0x7c, 0xe0, 0x1c, 0xbf, 0xdf, ++ 0xec, 0x0b, 0x2d, 0x9b, 0x1f, 0x75, 0x2c, 0x69, 0xf7, 0x76, 0x93, 0xcd, ++ 0x7f, 0xb0, 0xb5, 0xad, 0xdb, 0x91, 0xcd, 0x05, 0xe8, 0xa8, 0x53, 0x90, ++ 0x95, 0xc5, 0xed, 0x7a, 0x94, 0x4b, 0x25, 0xa3, 0x90, 0xcd, 0xd4, 0x38, ++ 0xa7, 0x79, 0xa5, 0xd1, 0x2c, 0xa3, 0x61, 0x1f, 0x31, 0x25, 0x07, 0x7a, ++ 0x9c, 0xc5, 0xa6, 0x71, 0x16, 0x9b, 0xc6, 0x59, 0x32, 0xd8, 0x8e, 0xfd, ++ 0x68, 0xbb, 0x7a, 0xfd, 0x26, 0x7b, 0xce, 0x35, 0xfb, 0x24, 0xf6, 0xa4, ++ 0x96, 0x05, 0x60, 0x35, 0xbd, 0x06, 0x15, 0x57, 0xe6, 0x37, 0x2e, 0x84, ++ 0x7b, 0xb5, 0xdc, 0x8e, 0xe7, 0x3f, 0xc4, 0xf3, 0xe1, 0x33, 0x2e, 0xec, ++ 0x14, 0xb1, 0xda, 0x4b, 0x72, 0xae, 0x42, 0x19, 0x79, 0x11, 0x74, 0xa7, ++ 0xfd, 0x36, 0x8b, 0x7c, 0x4d, 0x0d, 0x9f, 0x97, 0x54, 0x72, 0x5e, 0x46, ++ 0x7c, 0x96, 0x4f, 0x88, 0xc2, 0x58, 0xa2, 0x31, 0xd0, 0x8b, 0x90, 0x3f, ++ 0x91, 0x1f, 0x57, 0xda, 0xc5, 0x1e, 0xfb, 0x61, 0x40, 0x3b, 0x78, 0x7a, ++ 0xa3, 0xb5, 0x1f, 0x91, 0xa1, 0x33, 0xaa, 0x1f, 0xf4, 0x91, 0xf6, 0xbf, ++ 0xad, 0xfa, 0x0b, 0xfb, 0xc2, 0x3c, 0xc7, 0x5a, 0xfb, 0x73, 0xe4, 0xba, ++ 0x6b, 0xa3, 0xbf, 0xb4, 0x99, 0x23, 0xaf, 0x21, 0x23, 0xae, 0x83, 0xf2, ++ 0x61, 0x3b, 0x94, 0x19, 0x7b, 0xec, 0x3b, 0x41, 0x6e, 0x9a, 0x73, 0x2b, ++ 0x99, 0x67, 0xff, 0xc3, 0xc8, 0x9b, 0x54, 0xed, 0x2c, 0x78, 0x96, 0x19, ++ 0xc4, 0x78, 0xbc, 0x4f, 0x02, 0x1f, 0x49, 0x99, 0xf8, 0xac, 0x54, 0xf9, ++ 0x65, 0x90, 0x73, 0x34, 0xa6, 0xd2, 0x6b, 0xcf, 0xf7, 0x96, 0x14, 0x50, ++ 0x77, 0xc1, 0xe8, 0x83, 0x62, 0xe3, 0xba, 0xe2, 0xdf, 0xf3, 0x6a, 0x1f, ++ 0xa5, 0x4e, 0x97, 0xa9, 0x37, 0x36, 0xdc, 0x08, 0xf7, 0xf8, 0x25, 0xff, ++ 0xa5, 0x60, 0x61, 0x39, 0x95, 0x4c, 0xda, 0x83, 0x52, 0xaa, 0x0e, 0x96, ++ 0x6d, 0x94, 0x27, 0x6a, 0x09, 0x39, 0x51, 0x61, 0x3f, 0xfb, 0x51, 0x07, ++ 0x8a, 0xc8, 0xc6, 0x26, 0xef, 0xa3, 0xae, 0xe1, 0x98, 0x6f, 0x5b, 0x7a, ++ 0x4c, 0xcc, 0xc1, 0xdb, 0xb4, 0xfe, 0x63, 0xe3, 0x8a, 0x55, 0xaa, 0x71, ++ 0xfd, 0xf1, 0xbc, 0xd1, 0xac, 0x8f, 0x42, 0x5d, 0xb4, 0x83, 0xc5, 0x22, ++ 0xd9, 0x45, 0xab, 0xb4, 0x22, 0x76, 0xde, 0x8f, 0x12, 0x0f, 0x26, 0x45, ++ 0xee, 0x75, 0xf5, 0x3c, 0x3f, 0x19, 0xa1, 0x1e, 0x74, 0xbc, 0xd3, 0xe8, ++ 0xbb, 0x53, 0x72, 0x0e, 0xd7, 0x9f, 0xd7, 0x12, 0x44, 0xb2, 0x1e, 0x6d, ++ 0xa5, 0x13, 0xc9, 0x3a, 0xd8, 0x63, 0xac, 0xf3, 0x52, 0xc0, 0xbd, 0x90, ++ 0xaf, 0x6a, 0x19, 0x29, 0xef, 0x60, 0x2f, 0xd0, 0x9b, 0x83, 0x8e, 0x11, ++ 0x1b, 0x7b, 0xcc, 0x8d, 0x64, 0xf9, 0x7c, 0x1c, 0xd7, 0x9b, 0xa8, 0x4f, ++ 0x1d, 0x0b, 0x4c, 0x5a, 0x53, 0xbc, 0xc3, 0x58, 0x39, 0xab, 0x58, 0x09, ++ 0x79, 0xf2, 0x52, 0xf0, 0xe4, 0x72, 0x88, 0x11, 0x94, 0x6c, 0xc9, 0xc0, ++ 0xd9, 0xa4, 0xd9, 0xd7, 0x5d, 0xdc, 0x73, 0xe4, 0x3f, 0x9e, 0xf9, 0xe6, ++ 0x59, 0x7b, 0xd3, 0xb3, 0x70, 0xff, 0x7f, 0x09, 0xb4, 0xf5, 0x2b, 0xfe, ++ 0xd8, 0xd9, 0x23, 0x56, 0x5e, 0xe1, 0x93, 0x20, 0x28, 0x78, 0x51, 0x29, ++ 0x8d, 0xfe, 0x09, 0xe6, 0xca, 0x77, 0x65, 0x30, 0x9c, 0x76, 0x63, 0x78, ++ 0x72, 0xd6, 0x4b, 0x29, 0xfb, 0x9f, 0xc7, 0xfe, 0xd3, 0x3a, 0x53, 0xca, ++ 0x3d, 0xa0, 0xdd, 0x5b, 0xe2, 0x9a, 0xbc, 0x14, 0x9c, 0x05, 0x16, 0x9e, ++ 0x5e, 0x2a, 0x5a, 0x03, 0xd8, 0x12, 0x76, 0x9f, 0x05, 0x3e, 0x77, 0x49, ++ 0xfe, 0x22, 0xd7, 0x82, 0x75, 0xf8, 0xbc, 0x4d, 0xa6, 0xe3, 0xad, 0xb6, ++ 0xf2, 0xdc, 0x3e, 0xe9, 0x24, 0xbf, 0x51, 0x77, 0xe9, 0xff, 0x46, 0xb4, ++ 0x5e, 0x76, 0x65, 0x60, 0x95, 0x7c, 0x2f, 0x5a, 0xb3, 0x15, 0xea, 0xb1, ++ 0x0e, 0xd8, 0x47, 0x3e, 0x67, 0x9f, 0x78, 0x77, 0xbe, 0xb5, 0x8f, 0xdf, ++ 0x8b, 0xe8, 0x3e, 0xd8, 0x2e, 0xec, 0xa3, 0x99, 0x1f, 0x7b, 0x94, 0x9e, ++ 0xeb, 0xcd, 0xf6, 0xb6, 0xf4, 0x9b, 0x68, 0xea, 0x17, 0xef, 0xce, 0x7f, ++ 0x37, 0x42, 0x5c, 0xf6, 0xf2, 0x32, 0xf8, 0xac, 0xe6, 0xc4, 0x77, 0x6c, ++ 0x53, 0xb4, 0x0a, 0x4b, 0x41, 0x30, 0xed, 0xdb, 0x12, 0xe9, 0x0b, 0xeb, ++ 0xea, 0x79, 0x15, 0x31, 0xaf, 0x3c, 0xe6, 0x65, 0xf7, 0xb5, 0xd2, 0xf4, ++ 0xfb, 0x86, 0xa6, 0xde, 0x26, 0x9a, 0xe2, 0xef, 0x31, 0xaf, 0xf8, 0x2e, ++ 0xf3, 0x7a, 0xa9, 0x57, 0xf7, 0x11, 0x6f, 0xea, 0xa3, 0xaf, 0xa5, 0x0f, ++ 0xe8, 0xfd, 0x38, 0xdb, 0xf7, 0xed, 0xd2, 0xfe, 0x87, 0x1d, 0xba, 0x3d, ++ 0xdb, 0xb4, 0x41, 0xb7, 0xf7, 0x1b, 0xbd, 0x78, 0xa2, 0x49, 0x97, 0x9d, ++ 0x80, 0x2e, 0x6b, 0x6e, 0xd3, 0x2c, 0xff, 0xa1, 0x8f, 0x44, 0xff, 0x28, ++ 0xc4, 0x8a, 0x1f, 0x50, 0x18, 0x64, 0x07, 0x63, 0xc7, 0x80, 0x47, 0xba, ++ 0x60, 0xff, 0xbb, 0xe9, 0x07, 0x19, 0x4c, 0x48, 0xbf, 0x88, 0x38, 0x50, ++ 0x3c, 0xa0, 0x28, 0xe8, 0x96, 0xc1, 0xc4, 0x31, 0x11, 0xe5, 0x07, 0x11, ++ 0x5f, 0xd3, 0x27, 0xe2, 0x38, 0xf4, 0x89, 0xb8, 0xee, 0xbc, 0x2f, 0x6c, ++ 0xfb, 0x48, 0xfd, 0xd8, 0xf7, 0xc4, 0xc7, 0xdc, 0x33, 0xa1, 0xad, 0x69, ++ 0xd6, 0xa7, 0xbb, 0xd1, 0xd4, 0xdf, 0x42, 0x13, 0x74, 0x12, 0x7c, 0xb3, ++ 0x05, 0xc8, 0x23, 0x30, 0x29, 0x74, 0xe0, 0xfd, 0x53, 0xe7, 0x56, 0x44, ++ 0x4a, 0x0d, 0xda, 0xc7, 0x51, 0x81, 0x5f, 0x05, 0xba, 0xd8, 0xb7, 0xb2, ++ 0x91, 0xd0, 0x4d, 0xdd, 0x39, 0x3b, 0x3b, 0x08, 0x3f, 0xdc, 0x91, 0x39, ++ 0x43, 0xdb, 0x8c, 0xf2, 0xe1, 0xba, 0x50, 0x26, 0x94, 0x5c, 0xcd, 0x80, ++ 0x3e, 0x5e, 0xcf, 0x18, 0xec, 0x7e, 0xac, 0xd1, 0x4a, 0xdb, 0xf7, 0x40, ++ 0x9b, 0x07, 0x1a, 0x92, 0xf2, 0x02, 0xb0, 0xfb, 0x37, 0xd5, 0xbe, 0x0c, ++ 0x75, 0x17, 0x65, 0x29, 0x55, 0x2d, 0xcb, 0x66, 0xb0, 0xb2, 0xcc, 0x7d, ++ 0x4b, 0x1b, 0xde, 0x25, 0x65, 0xac, 0xd7, 0xc0, 0x52, 0x2a, 0x99, 0xb3, ++ 0xc5, 0x7a, 0xdf, 0x41, 0xca, 0xd3, 0xe3, 0x32, 0x70, 0x51, 0x2c, 0x67, ++ 0x09, 0x7b, 0xbd, 0x3b, 0xc4, 0x57, 0x9c, 0xdf, 0x6f, 0x63, 0x7e, 0xe8, ++ 0x7b, 0x39, 0x9c, 0x5f, 0x97, 0x94, 0x56, 0x39, 0xbf, 0xed, 0xb9, 0xc5, ++ 0x19, 0x11, 0xf9, 0x1c, 0xf4, 0x35, 0xe6, 0x08, 0x1a, 0xc7, 0x81, 0x73, ++ 0xef, 0x30, 0x73, 0xea, 0xc2, 0x9c, 0x60, 0xa3, 0x97, 0xd8, 0x1e, 0x74, ++ 0x81, 0xe6, 0x12, 0xea, 0xcd, 0x2f, 0x71, 0xcd, 0x41, 0x2b, 0xd6, 0xbd, ++ 0xd4, 0xe0, 0xda, 0x73, 0x6e, 0xda, 0xae, 0x3b, 0x1e, 0xe7, 0xc7, 0x79, ++ 0x0e, 0x63, 0x5e, 0xac, 0xc3, 0x76, 0xad, 0x32, 0x32, 0xfc, 0x1e, 0xeb, ++ 0xf1, 0xdb, 0x2d, 0xeb, 0x21, 0x66, 0x3d, 0x62, 0xd2, 0xb6, 0xaa, 0xfc, ++ 0x65, 0x45, 0x03, 0x7d, 0x08, 0x07, 0xf4, 0x2f, 0xae, 0xc8, 0x68, 0x54, ++ 0x48, 0x7b, 0x82, 0xcf, 0x32, 0x6d, 0x32, 0xe8, 0x5f, 0x81, 0x5c, 0x95, ++ 0x20, 0x0b, 0xf4, 0x07, 0x5e, 0x5e, 0xd6, 0x6b, 0x51, 0x6a, 0x74, 0xc2, ++ 0x47, 0xe7, 0xf8, 0xe4, 0x37, 0xe7, 0xe6, 0xaa, 0x75, 0x68, 0x5e, 0x97, ++ 0x4f, 0xdf, 0xb2, 0x2e, 0xd4, 0xbb, 0xd4, 0x03, 0xc4, 0x3d, 0xd4, 0x05, ++ 0x61, 0x4c, 0xa0, 0xe6, 0xea, 0xfd, 0x14, 0xda, 0x9f, 0xeb, 0xdb, 0xf8, ++ 0x52, 0xaf, 0x59, 0xc2, 0xc4, 0x05, 0xba, 0xc4, 0x5e, 0xbd, 0x83, 0x7a, ++ 0x1f, 0xf6, 0x27, 0x9c, 0xdf, 0xef, 0xe0, 0x3e, 0x71, 0xd3, 0x7a, 0xd8, ++ 0x98, 0x93, 0xa3, 0xe6, 0xa8, 0xd6, 0x62, 0x5b, 0xe6, 0xe6, 0x1a, 0x7a, ++ 0x5e, 0xce, 0xd2, 0x1e, 0xb3, 0x1e, 0x31, 0x3c, 0xe3, 0xbc, 0x42, 0x9b, ++ 0xc3, 0x79, 0x91, 0x5e, 0xd7, 0xc8, 0x1c, 0xe7, 0xc3, 0xfd, 0xd7, 0x2c, ++ 0x6b, 0x2f, 0x05, 0xd5, 0xe5, 0xa8, 0x9a, 0x7b, 0xde, 0xef, 0x26, 0x46, ++ 0xa3, 0x8e, 0x34, 0xfa, 0x89, 0xcf, 0x69, 0x07, 0xf1, 0x2e, 0x43, 0x19, ++ 0xc2, 0x7d, 0x9d, 0xf7, 0xcd, 0x36, 0xed, 0x79, 0x47, 0xeb, 0x01, 0xc6, ++ 0x9f, 0xde, 0xdb, 0xd6, 0x45, 0xb3, 0x62, 0xad, 0x57, 0xe8, 0x33, 0x07, ++ 0xc0, 0x5d, 0x77, 0x40, 0xaf, 0x1c, 0x92, 0x92, 0x0b, 0x7b, 0x3d, 0x7c, ++ 0x3b, 0xe6, 0x3c, 0x2e, 0x2a, 0xde, 0x30, 0xbc, 0x17, 0xd7, 0x7b, 0x94, ++ 0xef, 0x52, 0x1a, 0xfe, 0x90, 0xe4, 0xa6, 0x69, 0xd3, 0x7e, 0x5f, 0x66, ++ 0x60, 0x5b, 0x4b, 0xc3, 0x77, 0x82, 0x3e, 0xde, 0x43, 0x27, 0x7a, 0x43, ++ 0x8c, 0x51, 0xe0, 0xef, 0x71, 0x13, 0x9b, 0x39, 0x80, 0xfb, 0x3d, 0xa8, ++ 0xf3, 0x49, 0x53, 0xa7, 0x1b, 0x75, 0x06, 0x5b, 0xea, 0x70, 0xbc, 0xfb, ++ 0x50, 0x07, 0xf6, 0x14, 0x56, 0xd2, 0xf6, 0x0e, 0xe2, 0x37, 0x81, 0x67, ++ 0xf7, 0xe2, 0xd9, 0x3d, 0x78, 0x76, 0x0f, 0xee, 0x7f, 0xd7, 0xc4, 0x3c, ++ 0xc2, 0x36, 0xdd, 0xb8, 0xff, 0x12, 0xde, 0x43, 0xc7, 0xb9, 0xdf, 0xc6, ++ 0xfb, 0xfb, 0xf0, 0x1b, 0x6b, 0xa9, 0xe3, 0xb6, 0xdc, 0x9f, 0x76, 0x74, ++ 0x8c, 0x84, 0xcf, 0x82, 0xc8, 0xce, 0xf5, 0x7f, 0x35, 0xcf, 0xbd, 0xa6, ++ 0xf7, 0x1f, 0x37, 0xd7, 0xad, 0xb2, 0x94, 0x86, 0x2c, 0xf1, 0xfd, 0x57, ++ 0xf6, 0xe9, 0xb5, 0xb8, 0x43, 0xc7, 0x1f, 0x6e, 0xc2, 0x1b, 0x4a, 0xfc, ++ 0x71, 0xbd, 0x09, 0x9c, 0x41, 0xec, 0xd1, 0x8c, 0x3b, 0x48, 0x8b, 0xab, ++ 0xe4, 0xf5, 0xe5, 0xe5, 0xd7, 0xba, 0xf5, 0x18, 0x62, 0xd5, 0x21, 0x73, ++ 0x13, 0x2a, 0x16, 0xf1, 0x33, 0xf3, 0xcc, 0xdb, 0xb7, 0xf3, 0x6e, 0xaf, ++ 0x4c, 0x54, 0xff, 0x68, 0xdf, 0x0e, 0x6d, 0x93, 0x4d, 0xd7, 0x3b, 0x98, ++ 0x02, 0xfe, 0x84, 0xbd, 0x83, 0x77, 0x72, 0xf6, 0x5c, 0xa3, 0x68, 0xeb, ++ 0x71, 0x59, 0x07, 0xef, 0x1a, 0x9b, 0x3d, 0x8e, 0x92, 0xfd, 0x9c, 0x4d, ++ 0x5f, 0xa3, 0xbc, 0xc6, 0xeb, 0xdb, 0x51, 0x36, 0xb7, 0xed, 0x87, 0x1e, ++ 0xcf, 0xd9, 0x9a, 0xee, 0xd6, 0xf6, 0xe1, 0xbe, 0xf1, 0x65, 0xa1, 0x0a, ++ 0x99, 0xf3, 0x52, 0xc3, 0x65, 0xac, 0xdd, 0xac, 0x9f, 0x9a, 0xa6, 0x4c, ++ 0xc2, 0x9f, 0xfd, 0x94, 0xc8, 0xa4, 0xcc, 0x57, 0x1f, 0x06, 0xfe, 0x0e, ++ 0xe4, 0x21, 0xe0, 0x8a, 0x7f, 0x0f, 0x5c, 0x52, 0x83, 0xac, 0xd7, 0x1a, ++ 0x1e, 0x7e, 0xfd, 0xf2, 0x57, 0x95, 0x84, 0x3c, 0x07, 0x7f, 0x02, 0xb2, ++ 0x06, 0x3d, 0x9c, 0x76, 0x1f, 0x12, 0xe9, 0xb1, 0xe5, 0xf2, 0xbd, 0xb6, ++ 0x8c, 0x24, 0x07, 0xac, 0x74, 0x02, 0x3f, 0xb7, 0x0d, 0xbf, 0x22, 0x7c, ++ 0xb8, 0xb5, 0x06, 0x63, 0x01, 0x71, 0xf9, 0xeb, 0xf5, 0x24, 0x7e, 0x7d, ++ 0xf2, 0x37, 0xeb, 0x1c, 0x7f, 0xc0, 0x94, 0x6a, 0x1f, 0xc3, 0xe7, 0x28, ++ 0xcb, 0x62, 0x26, 0x21, 0x0b, 0x95, 0xe0, 0xa4, 0xf6, 0x99, 0x3d, 0xf8, ++ 0xc8, 0xdc, 0xb3, 0x2f, 0x60, 0xcf, 0xe2, 0xb9, 0xc2, 0x9e, 0xa1, 0xdd, ++ 0x7b, 0x01, 0x76, 0x2f, 0x5c, 0x23, 0xce, 0xb3, 0x75, 0x7d, 0xd8, 0x2f, ++ 0xd7, 0x88, 0x7a, 0x9d, 0xba, 0x3c, 0x06, 0xfc, 0x10, 0xea, 0x76, 0xea, ++ 0x08, 0x6f, 0xdb, 0x0f, 0x7d, 0xe4, 0x60, 0x17, 0xb0, 0x86, 0xc4, 0xe2, ++ 0xd9, 0x9f, 0xca, 0xca, 0x59, 0xee, 0x1b, 0xda, 0xe3, 0xbb, 0x21, 0x6f, ++ 0xa9, 0xaf, 0x96, 0x89, 0x99, 0xbd, 0x0c, 0xf8, 0x51, 0x96, 0xe9, 0x83, ++ 0xab, 0xbd, 0x5a, 0x4e, 0x26, 0xc5, 0x39, 0xfb, 0x85, 0xa8, 0x74, 0x9f, ++ 0x94, 0x45, 0x1f, 0x7e, 0xa9, 0x5d, 0x0e, 0x22, 0x9e, 0x97, 0x28, 0x28, ++ 0xbf, 0x69, 0x05, 0x74, 0xc6, 0x64, 0xe2, 0x2c, 0xeb, 0x9c, 0x84, 0x8c, ++ 0xb5, 0x81, 0xe6, 0x76, 0x39, 0x15, 0x4f, 0x95, 0x0b, 0xf0, 0xf7, 0x6d, ++ 0xaf, 0x47, 0x06, 0xea, 0x2c, 0x89, 0x41, 0xfe, 0x37, 0xe4, 0x87, 0xd7, ++ 0xf0, 0x03, 0x57, 0xf9, 0x7c, 0x00, 0x25, 0x9f, 0x7b, 0xd0, 0x2f, 0xe4, ++ 0x07, 0x70, 0xc3, 0xc5, 0xb2, 0x9c, 0xca, 0x4c, 0x4a, 0xbd, 0x2a, 0xd6, ++ 0x42, 0x06, 0x7b, 0xa0, 0x96, 0x95, 0x3a, 0x78, 0x51, 0x6a, 0x1c, 0x87, ++ 0xdf, 0xf9, 0x26, 0xca, 0x39, 0x94, 0xd7, 0x51, 0x3e, 0x8e, 0xf2, 0x2d, ++ 0x94, 0xa4, 0xfd, 0xb8, 0xd4, 0x6b, 0x7b, 0xda, 0xa4, 0x93, 0x7d, 0x6c, ++ 0x18, 0x9a, 0xe1, 0x3b, 0x1e, 0x3c, 0x0e, 0x2c, 0x1a, 0x3e, 0x3f, 0x2e, ++ 0x52, 0xff, 0x0c, 0x7e, 0x0f, 0xaa, 0x7b, 0xfa, 0x96, 0x0b, 0x99, 0x71, ++ 0xe0, 0x7a, 0xb1, 0x4e, 0x65, 0x1e, 0x37, 0xfd, 0x7c, 0x06, 0xe3, 0x5d, ++ 0xc5, 0xd8, 0x31, 0xc8, 0x48, 0x20, 0x8f, 0xf8, 0x27, 0xe5, 0x73, 0xfe, ++ 0x7e, 0x19, 0xeb, 0x8d, 0x95, 0x63, 0x59, 0xce, 0x9f, 0x7a, 0x6a, 0xb7, ++ 0xf9, 0x87, 0xf3, 0xe6, 0x9c, 0xa1, 0x5b, 0x97, 0xf6, 0x6a, 0xdc, 0x6d, ++ 0x7f, 0x39, 0xaa, 0x69, 0xb1, 0x64, 0x60, 0x88, 0xfd, 0x65, 0x25, 0x72, ++ 0x76, 0xc8, 0xcd, 0xd8, 0x23, 0xf0, 0x52, 0xd2, 0xf8, 0x9d, 0x84, 0xfc, ++ 0x79, 0xa7, 0x07, 0xec, 0xdb, 0x40, 0x13, 0xde, 0xd5, 0x39, 0x0e, 0xec, ++ 0xe9, 0x3d, 0xaf, 0x62, 0x6e, 0x65, 0x69, 0xbf, 0x27, 0x2b, 0x37, 0x1a, ++ 0xbc, 0x86, 0x3d, 0xba, 0x30, 0x29, 0xff, 0x5c, 0xbd, 0x2a, 0x4f, 0x54, ++ 0x27, 0xe5, 0x0d, 0x94, 0x8b, 0xd5, 0x32, 0xf8, 0xc8, 0x58, 0x3c, 0xfb, ++ 0x08, 0xb0, 0x2e, 0x83, 0xf0, 0x8d, 0x3e, 0x98, 0x98, 0xc3, 0xfa, 0xcd, ++ 0xb8, 0x81, 0x9c, 0xf3, 0xcb, 0x72, 0x6e, 0x1c, 0x6d, 0x6a, 0x1d, 0x12, ++ 0x7d, 0x96, 0xf3, 0xed, 0x96, 0x02, 0x2c, 0x7a, 0x31, 0x43, 0x9d, 0xd9, ++ 0x29, 0x85, 0x5a, 0xab, 0xdc, 0x51, 0xde, 0xde, 0xb6, 0xea, 0xdb, 0x3a, ++ 0x60, 0xd3, 0xfa, 0x66, 0x83, 0x36, 0x78, 0x37, 0x7b, 0xaa, 0xe5, 0xae, ++ 0x5e, 0xa3, 0x4d, 0xdd, 0x91, 0xbd, 0x3a, 0xfc, 0xb9, 0x7a, 0xf5, 0xba, ++ 0x91, 0x3f, 0x25, 0xb7, 0x58, 0x17, 0x62, 0xf1, 0x9f, 0x08, 0xb0, 0x1f, ++ 0x78, 0x14, 0xc6, 0x09, 0xb5, 0x7f, 0x54, 0x03, 0xad, 0x85, 0x38, 0x71, ++ 0x06, 0xac, 0x5b, 0xed, 0x0b, 0x8a, 0x57, 0xde, 0xd9, 0x7e, 0xa9, 0x2e, ++ 0x93, 0xbf, 0x29, 0xd7, 0xb6, 0x95, 0x4f, 0x02, 0xbe, 0x7a, 0x58, 0x9f, ++ 0xf0, 0x7d, 0x0a, 0x7e, 0xd2, 0x49, 0x71, 0xc7, 0x3a, 0x31, 0x27, 0x5e, ++ 0x8b, 0x4c, 0x5f, 0x6c, 0xc5, 0x91, 0xa1, 0x9d, 0x68, 0x83, 0x3f, 0x1e, ++ 0xc5, 0x5a, 0x76, 0xc1, 0x9f, 0x86, 0x9f, 0x0a, 0x39, 0xfa, 0x33, 0x60, ++ 0xaf, 0xd3, 0xca, 0xb7, 0xe6, 0x9e, 0xea, 0x9e, 0x1a, 0x58, 0x67, 0xb9, ++ 0x77, 0x2a, 0x5d, 0x63, 0x19, 0x9f, 0xd2, 0xbe, 0x64, 0x62, 0x4a, 0xc7, ++ 0xed, 0x93, 0x53, 0x07, 0x54, 0xe9, 0x4d, 0x0d, 0xab, 0x72, 0x78, 0x6a, ++ 0x27, 0x66, 0x42, 0x9e, 0x8a, 0x95, 0xcf, 0x64, 0xa4, 0x58, 0x21, 0x8d, ++ 0xe2, 0x1c, 0x83, 0x3c, 0xcd, 0x01, 0xcb, 0xe4, 0x2b, 0xbe, 0x9c, 0xda, ++ 0xc8, 0x82, 0x66, 0xe8, 0x99, 0xac, 0x8f, 0x52, 0xcc, 0x5f, 0xd8, 0xb6, ++ 0x8d, 0x31, 0x32, 0xae, 0x99, 0xf1, 0x33, 0x7d, 0xfa, 0x99, 0xcd, 0x7f, ++ 0xec, 0x0f, 0xb2, 0x49, 0xfb, 0xf9, 0x0b, 0xf8, 0xc6, 0xe2, 0x94, 0x32, ++ 0x6c, 0xeb, 0xc3, 0x07, 0x17, 0xd9, 0x5a, 0x91, 0x58, 0x2c, 0xfb, 0x1d, ++ 0x89, 0x3d, 0x1d, 0x04, 0x3f, 0xf0, 0x53, 0x47, 0xca, 0x02, 0x5e, 0x59, ++ 0x78, 0xbe, 0xce, 0x77, 0xd4, 0x4d, 0x23, 0xee, 0x0d, 0xc8, 0x5c, 0xee, ++ 0xa8, 0xc8, 0x2b, 0x78, 0x56, 0x5f, 0xe1, 0x1a, 0x7c, 0x17, 0x6b, 0x60, ++ 0xd6, 0x44, 0x3d, 0x63, 0x3d, 0xf8, 0x58, 0x71, 0xce, 0x63, 0xc4, 0x6d, ++ 0x47, 0xfb, 0xda, 0x3a, 0xdb, 0xa4, 0xc6, 0x79, 0xe4, 0xf5, 0xca, 0xba, ++ 0x9e, 0xdf, 0xe1, 0xcc, 0xb0, 0x5c, 0xae, 0xa8, 0x3e, 0x20, 0xeb, 0xbf, ++ 0x44, 0x9b, 0x4d, 0xc8, 0x2d, 0x63, 0x53, 0x59, 0x99, 0x07, 0x4e, 0x9b, ++ 0xaf, 0xa4, 0x21, 0x3b, 0x8e, 0xcc, 0x24, 0x48, 0xb6, 0x27, 0x5b, 0x95, ++ 0x37, 0xdb, 0x88, 0x85, 0xf3, 0x1e, 0xaf, 0xc7, 0x51, 0x67, 0x5a, 0x88, ++ 0xb7, 0xf2, 0x19, 0xce, 0xa9, 0x99, 0x17, 0xfa, 0xaf, 0x84, 0xb5, 0x30, ++ 0x73, 0x54, 0x7f, 0x7a, 0x1c, 0xb4, 0x37, 0xe3, 0x14, 0x01, 0x53, 0xe0, ++ 0x6b, 0x4a, 0xfa, 0x82, 0xe3, 0xe4, 0x2b, 0x8e, 0x0c, 0x5c, 0xc0, 0xb6, ++ 0xca, 0x1a, 0x5e, 0x34, 0x42, 0x59, 0x0b, 0x31, 0x10, 0x65, 0x8b, 0x3c, ++ 0x48, 0x95, 0x37, 0xc1, 0xec, 0xde, 0xec, 0x35, 0x79, 0x74, 0x55, 0xcf, ++ 0xd9, 0x3e, 0x2f, 0x3c, 0x0b, 0x91, 0x1b, 0x2b, 0x29, 0xff, 0x3a, 0xf4, ++ 0x7d, 0x21, 0xee, 0x43, 0x56, 0xfe, 0x4b, 0x1b, 0xf6, 0xf4, 0x78, 0xce, ++ 0xde, 0xdf, 0xae, 0x6d, 0xac, 0x83, 0x3d, 0x01, 0xac, 0x59, 0xc9, 0xa1, ++ 0x4d, 0xbb, 0xfc, 0x5b, 0x07, 0xd7, 0xc4, 0x9e, 0x78, 0x66, 0xec, 0x22, ++ 0xae, 0x75, 0x7f, 0xf3, 0x98, 0x87, 0x8e, 0x03, 0x5b, 0xf2, 0x28, 0x2c, ++ 0x88, 0xa0, 0xff, 0x01, 0x33, 0xd6, 0xc0, 0xf9, 0x50, 0x36, 0x40, 0xf7, ++ 0x6a, 0x16, 0xf8, 0xdd, 0x31, 0x7e, 0x2b, 0x75, 0x8c, 0xec, 0xe2, 0xf7, ++ 0x34, 0xc7, 0x5e, 0x63, 0x2a, 0x4e, 0x47, 0x2c, 0x47, 0xd9, 0x3a, 0x62, ++ 0x64, 0xeb, 0x33, 0x90, 0xad, 0xe3, 0x4a, 0xb6, 0x02, 0xf9, 0x81, 0xef, ++ 0xcb, 0x97, 0x77, 0x95, 0xaf, 0xd6, 0xbf, 0x2e, 0xd0, 0xcb, 0x5f, 0x9f, ++ 0x2c, 0xfc, 0x05, 0xc6, 0xbd, 0xe0, 0xe2, 0x3a, 0x95, 0x9b, 0x11, 0xf2, ++ 0x31, 0x81, 0xeb, 0x18, 0xca, 0x7e, 0x55, 0x67, 0xe0, 0x02, 0xec, 0x1a, ++ 0xe4, 0x8d, 0xfc, 0x9d, 0x87, 0x8d, 0x1b, 0xb8, 0x10, 0x85, 0x2d, 0xe4, ++ 0x9e, 0x95, 0x5e, 0x1b, 0xba, 0x81, 0xf5, 0xeb, 0xd8, 0x3b, 0x03, 0x17, ++ 0xba, 0x50, 0x26, 0x55, 0x5f, 0xf5, 0x8a, 0xa7, 0xda, 0xd7, 0x2b, 0xc3, ++ 0xaa, 0x5d, 0xbd, 0x32, 0x8a, 0x12, 0xfa, 0x3d, 0xe3, 0xcb, 0xd0, 0x85, ++ 0x8c, 0x24, 0x2f, 0x58, 0x52, 0x9a, 0x0e, 0x82, 0x18, 0x68, 0x1f, 0xbe, ++ 0xd0, 0x23, 0xd7, 0xa7, 0x39, 0x37, 0xea, 0x62, 0xb1, 0x16, 0x33, 0xd3, ++ 0xd8, 0x9b, 0xe4, 0x1f, 0xb0, 0xfe, 0x85, 0x22, 0x6c, 0x6e, 0x51, 0x4e, ++ 0xad, 0x90, 0x3f, 0x8c, 0xb5, 0x6f, 0x25, 0x22, 0x92, 0x82, 0x2e, 0x3b, ++ 0x2a, 0x73, 0xd5, 0x76, 0xe8, 0x32, 0xc7, 0xad, 0xcb, 0x13, 0x58, 0xa3, ++ 0x41, 0xca, 0x03, 0xf8, 0x92, 0x45, 0xdf, 0x45, 0x29, 0xa0, 0x4d, 0x71, ++ 0x65, 0xa7, 0x7e, 0x49, 0xda, 0xb1, 0xa7, 0x8e, 0xca, 0xb1, 0x2a, 0xfb, ++ 0x71, 0xdc, 0x79, 0x39, 0x00, 0x19, 0xf2, 0xdc, 0x09, 0xf4, 0x03, 0x1b, ++ 0xd9, 0xf4, 0xc7, 0xfd, 0x97, 0x7b, 0x0f, 0x99, 0x0c, 0xf7, 0x5d, 0xac, ++ 0xdc, 0x96, 0x9d, 0xb6, 0xb6, 0x32, 0xe2, 0xcc, 0x66, 0x1e, 0xb2, 0x5e, ++ 0xc9, 0x64, 0xac, 0x2b, 0x99, 0x9c, 0x75, 0x35, 0x53, 0xb4, 0xae, 0xc1, ++ 0x36, 0xd5, 0x37, 0xde, 0x81, 0xfc, 0x00, 0x4f, 0x10, 0x7b, 0x6f, 0xaf, ++ 0x61, 0xdc, 0xf8, 0x39, 0x6f, 0xc9, 0xb9, 0x0a, 0xed, 0x74, 0x70, 0x68, ++ 0xd6, 0x2f, 0xdf, 0x0e, 0xfa, 0x40, 0x07, 0xe3, 0x11, 0x3b, 0xb6, 0x23, ++ 0x9a, 0x1d, 0x06, 0x4e, 0xa0, 0xed, 0xe8, 0xa2, 0xed, 0xf0, 0x0b, 0xb2, ++ 0x57, 0xb6, 0xaa, 0x3a, 0x2e, 0x97, 0x07, 0x6e, 0xda, 0xaa, 0xc5, 0xe5, ++ 0xcb, 0xcb, 0xa1, 0x2c, 0x71, 0xbe, 0xf3, 0xef, 0xeb, 0x90, 0x88, 0x1c, ++ 0x51, 0xf6, 0xba, 0x5b, 0x2e, 0xaf, 0x03, 0xd3, 0x02, 0x81, 0xd8, 0x77, ++ 0x32, 0xce, 0x63, 0xab, 0xf8, 0x85, 0xf4, 0xf0, 0x3c, 0xf0, 0x1f, 0xc0, ++ 0x2b, 0x9e, 0xd9, 0x61, 0x9e, 0x3d, 0x9c, 0x51, 0x78, 0x3f, 0x8a, 0x3d, ++ 0xc9, 0x6b, 0x4b, 0x0a, 0xc0, 0xed, 0x5b, 0x15, 0x96, 0x09, 0x94, 0x26, ++ 0x56, 0x0f, 0x5d, 0x10, 0xc9, 0xfe, 0xa3, 0x7a, 0xdf, 0xee, 0x89, 0x35, ++ 0x0b, 0x3b, 0x5c, 0x5a, 0xa1, 0x4c, 0xa3, 0x5c, 0xd7, 0x63, 0x17, 0x7c, ++ 0x60, 0xe6, 0xd1, 0x0e, 0xda, 0x37, 0xe0, 0x27, 0xec, 0x7b, 0x85, 0xed, ++ 0x33, 0xd8, 0x73, 0x3f, 0x68, 0xa7, 0x6d, 0x3f, 0xec, 0x8f, 0xcb, 0xb5, ++ 0x0a, 0xaf, 0xf9, 0x3e, 0xe5, 0x8b, 0x8a, 0x1b, 0xc7, 0xa6, 0x16, 0x3d, ++ 0xdf, 0xec, 0x31, 0x15, 0xd3, 0xb1, 0x3e, 0x06, 0xcc, 0x38, 0x70, 0xa6, ++ 0x4d, 0xd2, 0x4f, 0xdb, 0x7d, 0xfa, 0x7c, 0xe5, 0x90, 0x14, 0xfd, 0x03, ++ 0x98, 0xc3, 0x3e, 0x99, 0x87, 0x2f, 0xb6, 0xb0, 0x31, 0x2c, 0xf3, 0xc3, ++ 0xf0, 0xb9, 0xdd, 0xbb, 0x89, 0xd5, 0xf0, 0xeb, 0xc0, 0xf3, 0x41, 0x94, ++ 0xed, 0x28, 0x6f, 0x97, 0xf9, 0xa7, 0xba, 0x63, 0xba, 0xbf, 0x68, 0xcb, ++ 0xfd, 0xb3, 0x1c, 0x3b, 0x99, 0xb4, 0x7e, 0x15, 0x2e, 0x6c, 0xc6, 0x84, ++ 0xa4, 0x23, 0x2a, 0xde, 0x93, 0x5d, 0x32, 0x78, 0xc6, 0x95, 0xa1, 0x33, ++ 0x09, 0x39, 0x70, 0xa6, 0x5f, 0x86, 0xcf, 0x24, 0xe5, 0xce, 0x33, 0x21, ++ 0xfe, 0xea, 0x9e, 0x4a, 0x1b, 0x5b, 0xe1, 0xfd, 0x9a, 0xb6, 0xe2, 0xce, ++ 0x86, 0xc6, 0xa8, 0xf3, 0x6b, 0xc4, 0x74, 0xaf, 0x62, 0xef, 0x6e, 0xaa, ++ 0xf3, 0xca, 0x4b, 0x1b, 0x41, 0x70, 0xc9, 0x6f, 0x77, 0xa7, 0x85, 0xfc, ++ 0xce, 0x00, 0x9f, 0xf9, 0xd0, 0x61, 0xa3, 0xd0, 0x61, 0xe3, 0xca, 0x36, ++ 0xd6, 0xbf, 0x2e, 0xd6, 0xb1, 0xcc, 0x03, 0xb2, 0x06, 0xd9, 0x7e, 0xd0, ++ 0x4f, 0x7d, 0x75, 0x53, 0xf1, 0x47, 0x62, 0x3d, 0xd0, 0x67, 0x77, 0xaf, ++ 0xb6, 0xcb, 0x1b, 0xf1, 0x20, 0x38, 0x0b, 0x1d, 0x50, 0xaf, 0x68, 0xf9, ++ 0xcd, 0x7b, 0xd4, 0x05, 0x0f, 0x61, 0xfe, 0xa3, 0x78, 0x96, 0x33, 0xba, ++ 0xbd, 0x43, 0x6e, 0xc4, 0x13, 0xb2, 0x7e, 0x60, 0xbc, 0xa5, 0x5e, 0x06, ++ 0xf7, 0xc0, 0x3d, 0x8d, 0xdf, 0x23, 0xbf, 0xf0, 0xdc, 0x95, 0x73, 0xf0, ++ 0x99, 0xcf, 0x1f, 0x48, 0x8d, 0x27, 0x6d, 0xea, 0xc3, 0xa4, 0xd4, 0xbe, ++ 0x9e, 0x90, 0xb5, 0x65, 0x6d, 0x97, 0x66, 0xbd, 0x71, 0x29, 0x00, 0xfb, ++ 0xae, 0x2d, 0x67, 0x51, 0xb2, 0x7e, 0xa8, 0x73, 0xb4, 0x5c, 0x16, 0x33, ++ 0x79, 0xec, 0x63, 0xee, 0x0f, 0x6d, 0x77, 0x6c, 0xbb, 0x1d, 0x72, 0xc4, ++ 0x3d, 0xf1, 0x30, 0x9e, 0xe7, 0xb1, 0xaf, 0x69, 0xc7, 0xd3, 0x90, 0xaf, ++ 0xcf, 0xc6, 0x28, 0x1f, 0x05, 0x9f, 0xf8, 0x9a, 0x6d, 0x52, 0x89, 0x34, ++ 0x9e, 0x4f, 0x4b, 0x5a, 0x9d, 0x0b, 0xcd, 0xfa, 0x61, 0x7f, 0x59, 0xa3, ++ 0x17, 0x22, 0x8c, 0x81, 0xe1, 0xef, 0x64, 0x8c, 0xf2, 0x18, 0xf1, 0xc2, ++ 0xe7, 0x23, 0xb0, 0x3d, 0x51, 0x35, 0xc6, 0xfc, 0x32, 0x9f, 0xa5, 0x5d, ++ 0xb6, 0x2f, 0xf8, 0xbc, 0x17, 0xf9, 0x44, 0x83, 0xf1, 0x9a, 0x98, 0x3c, ++ 0xda, 0xe8, 0x02, 0xbd, 0x6d, 0xbf, 0xc2, 0xf6, 0xec, 0xec, 0x73, 0x3b, ++ 0xbb, 0x95, 0x70, 0x95, 0x6e, 0xa1, 0x1e, 0xa1, 0x0e, 0x69, 0x17, 0x67, ++ 0x8c, 0xfb, 0x0c, 0x6b, 0xb2, 0x8c, 0x35, 0x5a, 0xc6, 0x1a, 0x2d, 0x63, ++ 0x8d, 0x96, 0xb1, 0x7e, 0xcb, 0xd4, 0x2d, 0x83, 0xd8, 0xcf, 0x39, 0x73, ++ 0x86, 0x40, 0xfd, 0xf2, 0x1c, 0xd6, 0x76, 0x5a, 0xfe, 0x76, 0x63, 0x52, ++ 0xfe, 0xf3, 0xc6, 0x11, 0xe0, 0xee, 0x22, 0xd6, 0x35, 0x87, 0x75, 0xcd, ++ 0x62, 0x5d, 0x8f, 0x62, 0x5d, 0xc7, 0x55, 0xcc, 0xb3, 0x5a, 0x49, 0x5d, ++ 0x2a, 0x2b, 0x8c, 0xff, 0x16, 0xe4, 0x61, 0x4c, 0x9c, 0xd5, 0x7e, 0xe8, ++ 0x8b, 0x72, 0x10, 0xf7, 0x82, 0x43, 0xc0, 0xd6, 0x18, 0xbb, 0x9c, 0x72, ++ 0x94, 0xee, 0xf3, 0xdc, 0xcf, 0x63, 0xaf, 0xbc, 0x2f, 0x9b, 0xaa, 0x52, ++ 0x75, 0x9d, 0xab, 0x0e, 0x4b, 0xe9, 0x22, 0xea, 0x9f, 0xed, 0x02, 0xad, ++ 0xc4, 0x7c, 0xa9, 0xd3, 0x25, 0xd9, 0x84, 0xbe, 0xcb, 0x81, 0xc6, 0x0f, ++ 0xc9, 0x7c, 0x3c, 0xf5, 0x9c, 0xc8, 0xb8, 0xdc, 0x03, 0x3f, 0x9d, 0xf1, ++ 0xcc, 0x9c, 0x8a, 0xb1, 0xe1, 0xfa, 0x62, 0x16, 0xfe, 0x36, 0x6d, 0xec, ++ 0x3e, 0xe3, 0x87, 0x6b, 0x1c, 0x5b, 0x13, 0x8e, 0xcb, 0xf1, 0xfe, 0x58, ++ 0xe6, 0x80, 0x15, 0xe1, 0xeb, 0x03, 0x8b, 0x78, 0x09, 0x8c, 0x19, 0x9b, ++ 0xbd, 0xe8, 0xc6, 0xe6, 0x2e, 0xb2, 0x9f, 0x98, 0x44, 0x96, 0xa8, 0xb3, ++ 0xd8, 0x0f, 0x74, 0x3b, 0xfa, 0x4e, 0xab, 0x33, 0xb3, 0x11, 0xb4, 0xfb, ++ 0x5d, 0xe0, 0x4c, 0xcd, 0xc7, 0xfc, 0x59, 0x6d, 0xf7, 0xf2, 0xf5, 0x66, ++ 0xac, 0x07, 0xdd, 0x02, 0xbb, 0x98, 0xab, 0x6b, 0xdc, 0x56, 0x54, 0xb8, ++ 0x4e, 0x63, 0xba, 0xa3, 0x72, 0xa8, 0x43, 0x3a, 0x3d, 0x35, 0x9f, 0xc8, ++ 0xd9, 0x4d, 0xe2, 0x58, 0x8c, 0xc1, 0x36, 0xd1, 0x26, 0xba, 0x33, 0xb0, ++ 0xa7, 0xb7, 0x77, 0x50, 0x66, 0x3e, 0x09, 0xdc, 0x38, 0xb0, 0xa4, 0xcf, ++ 0x98, 0x06, 0x2e, 0xfa, 0x98, 0x8f, 0xf4, 0x31, 0xb2, 0x69, 0x63, 0x0e, ++ 0x1f, 0x55, 0x76, 0x79, 0x0c, 0xb6, 0xd8, 0x85, 0xac, 0x53, 0xe7, 0xf4, ++ 0x61, 0xff, 0xf0, 0x9e, 0xba, 0x87, 0x7a, 0x8c, 0x32, 0x13, 0x07, 0x6e, ++ 0x82, 0xfe, 0xe9, 0xee, 0x97, 0xda, 0x06, 0xdf, 0xf5, 0x2b, 0x1d, 0xed, ++ 0x60, 0x0d, 0x16, 0x2b, 0xc1, 0xa1, 0xbc, 0x5f, 0x86, 0x16, 0x25, 0xcf, ++ 0xc9, 0x0f, 0xf2, 0x7d, 0x14, 0xb4, 0x91, 0xc7, 0xdd, 0x65, 0x7d, 0x6e, ++ 0xb9, 0x57, 0x4a, 0x55, 0xea, 0x69, 0x94, 0xb5, 0xbd, 0xf0, 0x9d, 0x5c, ++ 0x85, 0x65, 0x73, 0xd3, 0x9c, 0x7b, 0xac, 0xec, 0x42, 0x6e, 0xdd, 0x83, ++ 0x93, 0x2a, 0xa6, 0x72, 0x79, 0x29, 0xe5, 0xd7, 0x6c, 0x8c, 0x09, 0x9d, ++ 0x69, 0x9f, 0x1f, 0x93, 0xb9, 0x95, 0x6e, 0x19, 0x5c, 0xe5, 0xf9, 0xf2, ++ 0x50, 0x4c, 0xba, 0x83, 0xe0, 0x9c, 0x9f, 0x57, 0xb1, 0xc7, 0x81, 0x55, ++ 0x60, 0x82, 0xa3, 0x9a, 0x77, 0x9c, 0x2f, 0x74, 0xc4, 0xbf, 0x82, 0x8f, ++ 0xef, 0x8e, 0x8f, 0x8b, 0xbb, 0xe0, 0xe3, 0x57, 0x2f, 0x42, 0xfe, 0x96, ++ 0x21, 0x9b, 0xcb, 0x90, 0xcd, 0x65, 0xc8, 0xe6, 0x32, 0x64, 0x73, 0x19, ++ 0xb2, 0x89, 0xfd, 0xf3, 0xfc, 0xf2, 0xb8, 0xc1, 0x1f, 0x9f, 0x82, 0x2c, ++ 0x7f, 0xdb, 0xe0, 0x8f, 0x51, 0xc8, 0x70, 0x12, 0xb2, 0xeb, 0x43, 0x6e, ++ 0x87, 0x21, 0xcb, 0x1e, 0x64, 0xb9, 0x1f, 0x72, 0x9c, 0x50, 0xfe, 0xe3, ++ 0x04, 0xb0, 0xe8, 0x83, 0xf0, 0x41, 0xce, 0x57, 0xfb, 0x65, 0x51, 0xd1, ++ 0x12, 0xc8, 0x96, 0xbf, 0x49, 0x1e, 0x62, 0x5f, 0xd0, 0x3f, 0x77, 0xe5, ++ 0xfc, 0x5a, 0x48, 0xdb, 0xab, 0xf2, 0xcd, 0xca, 0x6b, 0xf2, 0x42, 0x85, ++ 0x34, 0xe6, 0x64, 0x11, 0xef, 0xd6, 0x9e, 0xa2, 0x1f, 0xa9, 0xe8, 0x83, ++ 0xcc, 0x9d, 0x94, 0xff, 0x03, 0x5e, 0xae, 0x6f, 0x7c, 0x58, 0x3e, 0xe7, ++ 0x52, 0x86, 0xe3, 0xd0, 0x35, 0xb8, 0x3f, 0x40, 0xbd, 0x04, 0x3f, 0xb4, ++ 0x92, 0x2a, 0x97, 0xa0, 0x27, 0xaa, 0xf6, 0x08, 0x30, 0x58, 0x39, 0xe8, ++ 0xa1, 0x0e, 0xab, 0x7a, 0xee, 0x80, 0x4d, 0xde, 0xec, 0x87, 0xbc, 0xa4, ++ 0xbe, 0x0a, 0xe1, 0xc5, 0x33, 0xda, 0x73, 0x94, 0x35, 0xe8, 0xcf, 0xa7, ++ 0xc8, 0x47, 0xfa, 0xb5, 0xb8, 0x56, 0xba, 0xf7, 0x27, 0x2a, 0x7e, 0x5c, ++ 0x9a, 0x86, 0x2f, 0xbf, 0x46, 0x3e, 0x41, 0x56, 0x9e, 0x22, 0x1f, 0x49, ++ 0x9f, 0xe6, 0xe3, 0x23, 0x12, 0xf2, 0x90, 0xef, 0x5a, 0x79, 0x08, 0x27, ++ 0xaa, 0x33, 0x8e, 0xb9, 0x7f, 0x2d, 0x66, 0x62, 0xc8, 0xc6, 0x26, 0xbf, ++ 0x2a, 0xd3, 0x0d, 0xce, 0xc7, 0x92, 0xdb, 0xbc, 0xab, 0xf0, 0xa9, 0x38, ++ 0xf6, 0xab, 0xc1, 0xa3, 0x71, 0xce, 0x81, 0xeb, 0xba, 0x47, 0xea, 0x7d, ++ 0xbe, 0x89, 0xaf, 0xfc, 0x2a, 0x5b, 0xc4, 0x7a, 0xe0, 0x3b, 0xf4, 0xcb, ++ 0x0b, 0xcb, 0xe0, 0x37, 0xfc, 0xae, 0x6f, 0xc0, 0xef, 0x62, 0x9c, 0x53, ++ 0xaf, 0xcf, 0xb8, 0x89, 0xd9, 0xb6, 0xc6, 0x6a, 0x93, 0x58, 0x23, 0xfa, ++ 0xed, 0xa9, 0xf2, 0x75, 0xe8, 0xc1, 0xe7, 0x7d, 0xc6, 0xf8, 0x02, 0xf9, ++ 0xef, 0x7e, 0xb3, 0xa6, 0x53, 0xf1, 0x6d, 0x79, 0x04, 0xba, 0xf1, 0x51, ++ 0xe8, 0xc6, 0x4f, 0xdc, 0x92, 0xe7, 0x43, 0x79, 0xbb, 0x7f, 0x6a, 0x76, ++ 0x65, 0xb0, 0x1c, 0xb1, 0xfb, 0x31, 0xa7, 0xe6, 0xb6, 0x8c, 0xf1, 0x25, ++ 0x4d, 0x2c, 0xb6, 0x19, 0xb3, 0x86, 0xf1, 0x56, 0xca, 0x74, 0x20, 0xd7, ++ 0xfc, 0x72, 0x57, 0x44, 0x9d, 0x3f, 0x7b, 0xb4, 0x13, 0xbb, 0xfc, 0xbd, ++ 0xd8, 0xa1, 0xed, 0xf3, 0x5b, 0x46, 0xc6, 0x76, 0x72, 0x99, 0x26, 0x32, ++ 0xe1, 0x99, 0x73, 0x37, 0x6c, 0x1e, 0xf7, 0x6d, 0x2a, 0x99, 0xc3, 0xde, ++ 0x9e, 0xdf, 0xa0, 0x5d, 0x20, 0x9e, 0x6c, 0x63, 0x4c, 0x6f, 0xa6, 0x3d, ++ 0xcb, 0xd8, 0x41, 0x37, 0xfc, 0x97, 0xd7, 0xe5, 0xdc, 0xca, 0x3f, 0x75, ++ 0xe8, 0xfd, 0xa4, 0x73, 0xcf, 0xec, 0x8b, 0xad, 0x71, 0x54, 0xbd, 0x46, ++ 0x85, 0x4c, 0x37, 0x30, 0x0c, 0xfd, 0xa5, 0x6b, 0xca, 0x5f, 0x3a, 0xec, ++ 0x3b, 0xb2, 0x19, 0x67, 0x9f, 0xaf, 0xcb, 0xb1, 0x95, 0xe1, 0x4e, 0xc6, ++ 0x2b, 0x17, 0x97, 0x0f, 0xc8, 0x96, 0xd2, 0x65, 0x0f, 0xa3, 0x6e, 0x16, ++ 0x7b, 0x36, 0x08, 0x26, 0xfc, 0xb4, 0x7b, 0x5e, 0x46, 0x12, 0xe7, 0xc1, ++ 0xd3, 0x3f, 0x43, 0x1b, 0xf8, 0xd4, 0x41, 0x11, 0xcf, 0xae, 0xc2, 0x6f, ++ 0xbf, 0x21, 0xbc, 0x1e, 0x71, 0x4f, 0x43, 0x18, 0x72, 0x6e, 0xda, 0x7d, ++ 0x4b, 0x42, 0xdb, 0x45, 0x3b, 0xc5, 0x33, 0xeb, 0x3e, 0x29, 0xac, 0x6b, ++ 0x5a, 0xe7, 0x41, 0xeb, 0xa9, 0x15, 0x8e, 0xc1, 0x79, 0x91, 0xde, 0x7f, ++ 0xe2, 0x19, 0x07, 0xe6, 0xf2, 0x41, 0x60, 0x59, 0xe2, 0x28, 0x1d, 0x8b, ++ 0x28, 0xa0, 0x8d, 0xc2, 0x5a, 0x3e, 0xcf, 0x2b, 0xc9, 0xc7, 0x2f, 0xc2, ++ 0x6f, 0x88, 0x43, 0x8e, 0xf1, 0x7c, 0xbd, 0x39, 0xe6, 0xcb, 0xfa, 0xfa, ++ 0x1c, 0xed, 0x92, 0xf2, 0x11, 0xf2, 0xc0, 0x85, 0x93, 0xa8, 0xcb, 0x78, ++ 0x67, 0x10, 0x1c, 0xf7, 0xe1, 0xc7, 0x3f, 0x45, 0xd9, 0xbb, 0x53, 0x4a, ++ 0xca, 0xe7, 0x20, 0x86, 0x65, 0xfe, 0xc6, 0x96, 0x1b, 0xc3, 0xfe, 0x9c, ++ 0x86, 0x6d, 0xcb, 0xc3, 0xb6, 0x45, 0xee, 0x3e, 0x02, 0x3c, 0xab, 0xce, ++ 0xd9, 0x60, 0x3f, 0x39, 0xee, 0xc3, 0xd6, 0xdf, 0x67, 0x46, 0x81, 0x6f, ++ 0x1f, 0x00, 0xbe, 0x65, 0x1e, 0x59, 0x1e, 0x18, 0x97, 0xf8, 0xd6, 0x95, ++ 0xbf, 0xda, 0xc8, 0x43, 0xb7, 0x4d, 0x74, 0x52, 0x17, 0x1f, 0xd9, 0xb6, ++ 0xd3, 0x45, 0x63, 0xc7, 0xf7, 0x49, 0x41, 0x9d, 0xbb, 0x15, 0x95, 0xbd, ++ 0x9f, 0x5f, 0x27, 0xae, 0x87, 0xed, 0x5f, 0x87, 0xef, 0x57, 0xa1, 0x8f, ++ 0x96, 0xc3, 0xfd, 0x03, 0xb8, 0x7f, 0x08, 0xe5, 0x11, 0x94, 0xda, 0xf7, ++ 0xb9, 0xb4, 0x1c, 0xe9, 0xd4, 0x31, 0xde, 0x44, 0x93, 0xff, 0x43, 0x39, ++ 0x8c, 0x4f, 0xcd, 0x56, 0xc3, 0x38, 0xfd, 0x21, 0x39, 0xee, 0xeb, 0xb3, ++ 0xf5, 0x09, 0xf8, 0xeb, 0x9d, 0xc0, 0x60, 0x0f, 0x3d, 0x0d, 0x9b, 0x71, ++ 0xdf, 0x21, 0xb1, 0xef, 0xb3, 0x64, 0x76, 0x14, 0x74, 0x8f, 0x0e, 0x42, ++ 0x3f, 0xf7, 0xc3, 0xdf, 0x56, 0x7e, 0xb0, 0xc1, 0x9c, 0xd4, 0xfb, 0x71, ++ 0xf9, 0xf3, 0x8d, 0x10, 0x7b, 0xb6, 0x01, 0xa7, 0x32, 0x56, 0x98, 0x54, ++ 0xb8, 0xd9, 0xbe, 0x8d, 0xeb, 0xdf, 0x25, 0xf9, 0xdb, 0xc8, 0x53, 0x3e, ++ 0x03, 0xa6, 0x51, 0xd7, 0x71, 0x49, 0x9f, 0xe1, 0xba, 0xb5, 0x9b, 0x18, ++ 0x2f, 0x6d, 0x06, 0xcb, 0xbf, 0xec, 0xdc, 0xc6, 0x96, 0x8c, 0x01, 0x59, ++ 0xe3, 0x9d, 0x3b, 0x79, 0x69, 0xa1, 0xdc, 0x87, 0xf9, 0x04, 0x94, 0xff, ++ 0x4b, 0xa0, 0x9f, 0xf6, 0x9e, 0xb6, 0xc1, 0xb5, 0xa2, 0x07, 0x89, 0x05, ++ 0x22, 0xd2, 0xe6, 0x71, 0x9f, 0xd2, 0x4e, 0x1d, 0xc1, 0x9c, 0x88, 0x0d, ++ 0x3e, 0xdf, 0x2d, 0xdd, 0xc4, 0x07, 0x49, 0x3c, 0xbb, 0x8e, 0x7a, 0xbc, ++ 0x67, 0x3d, 0xf8, 0x52, 0xcb, 0x62, 0x45, 0x0e, 0xce, 0x41, 0xae, 0x3d, ++ 0x5c, 0x1f, 0x47, 0x39, 0x8c, 0xf2, 0x71, 0x94, 0xd4, 0x4f, 0x57, 0x65, ++ 0x56, 0xc7, 0x7f, 0x14, 0x0e, 0xa1, 0xed, 0x9c, 0xf6, 0xa9, 0x53, 0x4f, ++ 0x8a, 0x3d, 0xf6, 0x41, 0x3c, 0xa3, 0x1f, 0x8f, 0x91, 0xee, 0xff, 0x82, ++ 0x89, 0x3f, 0x6d, 0xc7, 0xac, 0x8c, 0x4e, 0x5e, 0x51, 0x31, 0xfc, 0xf5, ++ 0xa7, 0xe8, 0x23, 0xff, 0x54, 0x1e, 0xbd, 0x29, 0xb6, 0xb7, 0x1d, 0xcb, ++ 0x1a, 0x2f, 0x28, 0x5d, 0x4c, 0x7e, 0x40, 0x0f, 0xbb, 0x19, 0xf9, 0xfa, ++ 0x46, 0x0f, 0xf4, 0x5b, 0x5c, 0xde, 0x58, 0x09, 0x80, 0xd5, 0xb9, 0x37, ++ 0x47, 0x60, 0x33, 0x5d, 0x83, 0x03, 0xe2, 0xf2, 0x2f, 0x90, 0xf3, 0x7f, ++ 0xae, 0x24, 0xe4, 0xcd, 0x4a, 0x10, 0x5c, 0xf3, 0xd3, 0xfe, 0x61, 0x91, ++ 0xbb, 0xdb, 0x74, 0x0e, 0x00, 0x6a, 0xe8, 0x73, 0xfb, 0x79, 0x75, 0x76, ++ 0x8f, 0x7a, 0xd0, 0x3b, 0x6f, 0x36, 0x7e, 0x01, 0xbe, 0xea, 0x3e, 0x5b, ++ 0xdb, 0x6e, 0xe9, 0xb6, 0x3c, 0xfb, 0x4f, 0x6c, 0x4a, 0xda, 0xe4, 0x10, ++ 0xa4, 0xd1, 0x36, 0x3d, 0xbc, 0xb6, 0xdd, 0x9e, 0x6d, 0x33, 0xca, 0x5e, ++ 0x94, 0xd6, 0x7b, 0xa5, 0xfe, 0x17, 0xdc, 0x2b, 0xf0, 0x63, 0xd5, 0x99, ++ 0x11, 0x4b, 0x9e, 0x55, 0xb0, 0x4e, 0xd2, 0xbc, 0x1f, 0x30, 0xef, 0x3d, ++ 0x85, 0x5f, 0x9d, 0xed, 0x18, 0x20, 0x7c, 0xdb, 0xe5, 0xd4, 0x69, 0x65, ++ 0x47, 0x18, 0xb7, 0x5d, 0xa6, 0x7f, 0x4f, 0x5d, 0x3e, 0x69, 0xec, 0x09, ++ 0x7c, 0x8f, 0xda, 0x71, 0x99, 0x51, 0xd7, 0x9f, 0x90, 0x47, 0x5c, 0xf2, ++ 0xee, 0xa4, 0xf8, 0x63, 0x1a, 0x4b, 0x89, 0x89, 0x09, 0x76, 0x78, 0x27, ++ 0xe1, 0x9b, 0x29, 0x7b, 0xec, 0x7e, 0x4c, 0xc8, 0xe3, 0x36, 0xda, 0x8f, ++ 0x9c, 0x6d, 0x01, 0x83, 0x3d, 0x99, 0x91, 0xe7, 0x36, 0x50, 0x17, 0xeb, ++ 0xf5, 0x31, 0xc1, 0xfd, 0xb3, 0xb8, 0x67, 0x1c, 0xed, 0xe9, 0xb8, 0x44, ++ 0x9e, 0xee, 0x97, 0xf6, 0x33, 0xc4, 0x29, 0xe4, 0x69, 0x42, 0xda, 0xce, ++ 0x10, 0x2f, 0x33, 0xb6, 0x9c, 0x1a, 0xbf, 0x21, 0x8c, 0xe5, 0xa4, 0xfc, ++ 0x2b, 0xf8, 0x6d, 0x61, 0xde, 0xed, 0xf0, 0xc3, 0xdb, 0x2e, 0xe8, 0x76, ++ 0xf6, 0xb9, 0x3e, 0x00, 0xc3, 0x98, 0xd8, 0xf0, 0x59, 0xec, 0x0b, 0x2c, ++ 0xbb, 0x50, 0xf2, 0x1d, 0x48, 0x3a, 0x37, 0x60, 0xde, 0x41, 0x37, 0x5e, ++ 0xe0, 0xf8, 0xb0, 0x8f, 0xbe, 0xce, 0x17, 0x1d, 0x18, 0xf2, 0xe5, 0xd2, ++ 0x1a, 0x65, 0x93, 0x71, 0x74, 0x62, 0x97, 0x57, 0xc5, 0x5e, 0xca, 0x48, ++ 0xe4, 0x4c, 0x06, 0x72, 0xe8, 0xc3, 0xee, 0x12, 0xf3, 0xd1, 0xd6, 0xe1, ++ 0x39, 0xf0, 0x56, 0xfd, 0x29, 0xce, 0xe9, 0xaa, 0xd8, 0xf5, 0x5f, 0x65, ++ 0xc3, 0xc2, 0x7d, 0xc1, 0x31, 0x4e, 0xc2, 0xfe, 0x46, 0xe5, 0x73, 0x71, ++ 0xca, 0x8a, 0x96, 0xbd, 0xb4, 0x3d, 0xa4, 0x64, 0xb5, 0x48, 0xbb, 0xfc, ++ 0xd4, 0xed, 0x7b, 0xe0, 0xa7, 0x9d, 0x2e, 0x6f, 0xcb, 0x18, 0xf3, 0x42, ++ 0x03, 0xa9, 0x02, 0xef, 0xcc, 0x7b, 0x96, 0x2c, 0x78, 0x27, 0x15, 0x1e, ++ 0x7c, 0x14, 0xed, 0x4f, 0x98, 0xf6, 0x0b, 0x32, 0x64, 0x64, 0x5d, 0xc5, ++ 0x11, 0xa0, 0xc7, 0xb8, 0x66, 0xbc, 0xff, 0x2d, 0xf1, 0x7b, 0xb9, 0x9e, ++ 0x27, 0x65, 0x60, 0x4c, 0xe3, 0x90, 0x92, 0x4d, 0x1c, 0xf2, 0xae, 0x71, ++ 0x5a, 0x95, 0xcb, 0x57, 0xa8, 0xd0, 0xce, 0xec, 0x85, 0xfc, 0xc2, 0x27, ++ 0xda, 0x08, 0x63, 0xb5, 0x6a, 0x5f, 0x25, 0x06, 0x6c, 0x4b, 0xbc, 0xa1, ++ 0xa1, 0xe1, 0x12, 0xf0, 0xc9, 0x3c, 0x7c, 0x5e, 0xd2, 0xb1, 0x00, 0x3b, ++ 0xb7, 0xe6, 0xff, 0x4b, 0x70, 0x22, 0x9e, 0x3a, 0x3d, 0xf3, 0xae, 0xf1, ++ 0xfb, 0x30, 0x6e, 0xdf, 0x7c, 0x9e, 0xb2, 0x69, 0xfd, 0x61, 0xe3, 0x88, ++ 0xd2, 0x91, 0x37, 0xe3, 0xae, 0x30, 0x7e, 0x3f, 0x7d, 0x53, 0x1c, 0xb5, ++ 0xd4, 0x08, 0x73, 0xf0, 0x42, 0x3d, 0x7f, 0x1a, 0xba, 0x3a, 0x22, 0x37, ++ 0x80, 0x41, 0x27, 0xc0, 0xbb, 0x73, 0x6b, 0x65, 0xeb, 0x4a, 0x45, 0xd4, ++ 0x7d, 0xc1, 0x67, 0x4e, 0xde, 0x47, 0xc0, 0x3b, 0xd8, 0x98, 0x0d, 0xc7, ++ 0x9c, 0x29, 0x39, 0x78, 0x66, 0x2b, 0x9f, 0xb9, 0xa4, 0x74, 0xf3, 0xe1, ++ 0x2e, 0x9e, 0xb9, 0x5c, 0x5a, 0xfe, 0x28, 0xee, 0x79, 0xf6, 0x71, 0xa4, ++ 0xe5, 0xf9, 0x66, 0x4f, 0x54, 0x63, 0x37, 0xf0, 0x5d, 0xf3, 0xcd, 0x01, ++ 0xbf, 0x8b, 0x8c, 0xe7, 0x35, 0x88, 0x83, 0x3b, 0x0d, 0x0e, 0x26, 0xce, ++ 0xc2, 0x7a, 0x6d, 0x30, 0x0e, 0x43, 0xac, 0x15, 0x57, 0x7e, 0xa1, 0xc2, ++ 0x5e, 0xfe, 0x31, 0x93, 0x7f, 0x71, 0xab, 0x5c, 0xcd, 0x56, 0x42, 0x3c, ++ 0xd7, 0x2c, 0x57, 0xee, 0x6f, 0x20, 0x57, 0x13, 0x5d, 0x3a, 0xdf, 0x81, ++ 0x36, 0xcd, 0x92, 0x37, 0xaa, 0x7b, 0x64, 0xab, 0xfa, 0x20, 0x70, 0xb4, ++ 0xca, 0xfb, 0x90, 0x2d, 0xac, 0xc5, 0x83, 0x95, 0x49, 0x99, 0xa8, 0xc6, ++ 0xe4, 0x5a, 0xd5, 0x7e, 0xa0, 0x5d, 0x18, 0x07, 0x27, 0x36, 0xf9, 0x1b, ++ 0xa5, 0xdf, 0x7e, 0xe0, 0xef, 0xb4, 0xe7, 0xb9, 0xca, 0x0d, 0xb4, 0x9f, ++ 0xad, 0xde, 0x2b, 0x25, 0xd5, 0xbe, 0x7e, 0xcb, 0x18, 0x51, 0x33, 0x46, ++ 0xbd, 0x7a, 0x97, 0x89, 0xdf, 0x95, 0xe5, 0x12, 0xb0, 0xaf, 0x7d, 0x96, ++ 0xf3, 0xbd, 0xc3, 0xe4, 0x77, 0xc5, 0x9a, 0xfc, 0x91, 0xa8, 0xf1, 0x47, ++ 0x7e, 0x06, 0x3d, 0xfe, 0x94, 0x44, 0xbd, 0xb0, 0x2f, 0xe6, 0x6a, 0x27, ++ 0x4c, 0x6e, 0xc7, 0x5e, 0xf4, 0x75, 0x10, 0xef, 0xee, 0xc3, 0xef, 0x49, ++ 0xd4, 0xa3, 0xbd, 0xe2, 0xd9, 0x28, 0x31, 0x02, 0xcf, 0xeb, 0x7a, 0x51, ++ 0xaf, 0x03, 0x58, 0x72, 0xbf, 0x79, 0x16, 0xf6, 0x11, 0xd6, 0x0d, 0xef, ++ 0x9b, 0xcf, 0x53, 0x59, 0x2f, 0xd9, 0x74, 0x9e, 0x0a, 0x45, 0xa5, 0xda, ++ 0x86, 0xb6, 0x36, 0xb4, 0x51, 0xc9, 0x26, 0x1b, 0xf5, 0x56, 0x53, 0x9e, ++ 0xa7, 0xc6, 0x61, 0x57, 0x33, 0x9c, 0x6b, 0x5f, 0x53, 0x0e, 0x4a, 0xaa, ++ 0x4c, 0xfb, 0xc8, 0x78, 0xdf, 0x7a, 0x25, 0xb4, 0x1f, 0xb9, 0x1e, 0x9e, ++ 0x5b, 0x2c, 0xfa, 0x2a, 0x16, 0x97, 0x8c, 0x64, 0x69, 0x7f, 0xfc, 0xd8, ++ 0x16, 0x70, 0x65, 0x5d, 0x9d, 0xeb, 0x47, 0xf0, 0x83, 0x5d, 0x76, 0x2c, ++ 0x71, 0x3d, 0x3e, 0x2b, 0x1b, 0xbd, 0x03, 0x5d, 0x6e, 0xab, 0x3a, 0xc9, ++ 0xbc, 0xdf, 0x67, 0xee, 0x13, 0xb2, 0x56, 0xf9, 0x50, 0xbf, 0x9d, 0xfd, ++ 0x5f, 0xb7, 0xe7, 0x33, 0x3d, 0x3c, 0x7f, 0xc2, 0x33, 0xe2, 0xf5, 0xd7, ++ 0x54, 0x4e, 0xa3, 0xc6, 0x46, 0x0e, 0xcf, 0x2f, 0x81, 0x73, 0x7e, 0x04, ++ 0x9e, 0x84, 0xb8, 0xfb, 0x75, 0x99, 0x50, 0x98, 0xaa, 0x0d, 0xb6, 0xd2, ++ 0x60, 0xaa, 0xee, 0x14, 0x30, 0x15, 0xdb, 0xb7, 0xe2, 0x40, 0xbd, 0x97, ++ 0x22, 0x59, 0x1d, 0x57, 0x6d, 0x89, 0x15, 0x5b, 0x8f, 0x64, 0xc4, 0x3a, ++ 0x81, 0x1f, 0x65, 0xd4, 0x5e, 0x7a, 0x4d, 0xbc, 0xa5, 0x54, 0x95, 0xf9, ++ 0xb1, 0x0b, 0x1b, 0x3c, 0xc7, 0x03, 0x16, 0x4b, 0x50, 0x96, 0xf9, 0x6e, ++ 0x1a, 0x63, 0xbc, 0x06, 0xff, 0x73, 0x0f, 0xf8, 0x6d, 0x1b, 0x1e, 0xf9, ++ 0x26, 0x46, 0x11, 0x63, 0x2c, 0x18, 0x7b, 0x71, 0x5e, 0x61, 0x89, 0x52, ++ 0x7c, 0x11, 0xe5, 0x0f, 0x0d, 0x76, 0x78, 0xbd, 0x2b, 0x3c, 0xb7, 0x2f, ++ 0xc5, 0xbf, 0x84, 0xe7, 0xaf, 0xc3, 0x1f, 0x8c, 0x4a, 0x9b, 0x5a, 0xb3, ++ 0x10, 0x3b, 0xff, 0x3d, 0xea, 0x90, 0xfe, 0x3b, 0x4d, 0x7e, 0x0d, 0xf3, ++ 0x06, 0xd8, 0x1f, 0xec, 0x96, 0xca, 0xe1, 0xca, 0xa1, 0x64, 0x3b, 0xb6, ++ 0x79, 0x05, 0x75, 0x73, 0x98, 0x37, 0x9f, 0x4b, 0x5f, 0x44, 0x9a, 0x9f, ++ 0x7f, 0x14, 0xcf, 0x29, 0x87, 0xef, 0x37, 0x72, 0x18, 0xbe, 0xcb, 0x1b, ++ 0x3e, 0xdd, 0x8e, 0x31, 0xc8, 0xab, 0x66, 0xba, 0x38, 0x9f, 0x70, 0xcd, ++ 0xdb, 0x4c, 0xae, 0x01, 0x9f, 0xbd, 0xdf, 0x3c, 0x73, 0xcc, 0x1c, 0x3f, ++ 0xde, 0x65, 0xb0, 0x04, 0x76, 0x7b, 0xb8, 0x1f, 0x49, 0x67, 0xac, 0x09, ++ 0xb3, 0xfe, 0x61, 0xef, 0x4e, 0x1e, 0x26, 0x65, 0xce, 0x53, 0xb1, 0x23, ++ 0xe6, 0x8f, 0xe5, 0x6c, 0x9d, 0xb3, 0xf1, 0x8d, 0x9b, 0xe2, 0xdd, 0x4a, ++ 0xd7, 0xf2, 0x0c, 0xa4, 0x6a, 0x67, 0xdb, 0x7f, 0xed, 0xbc, 0xbb, 0x48, ++ 0x36, 0x6c, 0x07, 0x9c, 0xa6, 0xda, 0x24, 0x65, 0xae, 0xf1, 0x6e, 0x39, ++ 0x7a, 0xca, 0xbf, 0x30, 0x79, 0x10, 0xfb, 0x55, 0x1e, 0x04, 0xf5, 0xe2, ++ 0x5a, 0x35, 0x02, 0x5e, 0xf7, 0x31, 0x37, 0x0a, 0x7e, 0x4c, 0x0c, 0x73, ++ 0x45, 0x5f, 0xf1, 0xf7, 0xab, 0x5c, 0xa9, 0x88, 0x17, 0xe6, 0xf5, 0x72, ++ 0x1f, 0xde, 0xa1, 0xde, 0x7f, 0x7d, 0xa5, 0x9d, 0xf9, 0xaa, 0x28, 0xb9, ++ 0x47, 0x7f, 0x09, 0xfd, 0x18, 0x95, 0x42, 0xd5, 0x03, 0xfe, 0x89, 0x52, ++ 0x2e, 0xf1, 0x7c, 0x3f, 0xfc, 0x61, 0xc1, 0x3e, 0x69, 0x83, 0x6f, 0xa2, ++ 0x7c, 0x1d, 0xcc, 0x68, 0x87, 0x0e, 0x62, 0x70, 0x9d, 0x1f, 0x1a, 0x40, ++ 0x87, 0xcf, 0xcb, 0xda, 0xf8, 0xa2, 0xd4, 0xc7, 0x9b, 0x31, 0x2c, 0x30, ++ 0xaa, 0x5b, 0x0e, 0xea, 0x9e, 0x8a, 0x65, 0x1a, 0xdd, 0x72, 0xc2, 0xe0, ++ 0x4e, 0xae, 0x83, 0x2d, 0x85, 0xd1, 0x05, 0x25, 0x5f, 0x75, 0xb5, 0x1e, ++ 0x8e, 0x75, 0x59, 0xe5, 0xf9, 0x72, 0x0c, 0xe6, 0xfa, 0x46, 0x0c, 0x0e, ++ 0x3b, 0x65, 0xd6, 0xd5, 0xd9, 0x1b, 0xe6, 0xcc, 0x47, 0xb3, 0x87, 0x99, ++ 0xdb, 0x01, 0x6c, 0x3d, 0x3d, 0x35, 0x5b, 0xa1, 0x2d, 0x0c, 0x82, 0xba, ++ 0xbf, 0x89, 0x1e, 0x7f, 0xac, 0x30, 0xe4, 0x96, 0x68, 0xdd, 0xbe, 0xa0, ++ 0x72, 0x66, 0x27, 0xa7, 0xf2, 0x2a, 0x5e, 0xd8, 0x7c, 0x76, 0xf3, 0x5e, ++ 0xe7, 0x36, 0x31, 0xf8, 0xfe, 0x1d, 0x66, 0xfd, 0x63, 0x4e, 0xa9, 0xd2, ++ 0xe5, 0xcc, 0xaa, 0xb3, 0xb5, 0xac, 0xf9, 0x16, 0x27, 0x37, 0x95, 0x6e, ++ 0x7c, 0x76, 0x2f, 0xb1, 0x3e, 0xcf, 0x31, 0x0a, 0x15, 0x9e, 0xe3, 0xe8, ++ 0xf7, 0x69, 0xf3, 0x7e, 0xa0, 0xa1, 0xde, 0xa9, 0x78, 0x23, 0x63, 0x8c, ++ 0xed, 0x28, 0x6f, 0x54, 0xa8, 0x6b, 0xd0, 0x7f, 0x5c, 0xcf, 0x21, 0x92, ++ 0x2d, 0xc2, 0x3f, 0x25, 0x7d, 0x47, 0xa6, 0xf2, 0x2b, 0xcc, 0xdb, 0x7a, ++ 0x68, 0xea, 0x1a, 0xfc, 0xa5, 0x73, 0x9e, 0xce, 0x2b, 0x5f, 0x67, 0x1c, ++ 0x8c, 0xed, 0x54, 0x9f, 0x45, 0x13, 0xab, 0x3d, 0x3c, 0x35, 0xb8, 0x1e, ++ 0x91, 0x27, 0x4c, 0x1f, 0xbc, 0x4f, 0x6e, 0xfb, 0x52, 0x4a, 0xff, 0xc1, ++ 0x3f, 0x18, 0x85, 0x7f, 0xd0, 0x09, 0x5d, 0x4f, 0x3f, 0x83, 0xf8, 0xbb, ++ 0x13, 0x7b, 0x85, 0xe3, 0xdc, 0xa5, 0xc6, 0x89, 0x60, 0x9c, 0x59, 0xf8, ++ 0x38, 0x8c, 0x47, 0xe6, 0x3d, 0x07, 0x58, 0x02, 0xb6, 0xde, 0x63, 0xbc, ++ 0xdc, 0xc6, 0x9c, 0x87, 0xa1, 0x27, 0x98, 0xa3, 0x32, 0x11, 0xe6, 0x0d, ++ 0xa1, 0x9d, 0x6f, 0xda, 0x1d, 0x44, 0x3b, 0xfa, 0x07, 0x6c, 0x2b, 0xb7, ++ 0xd9, 0x32, 0xa8, 0xb0, 0x81, 0xf6, 0x6b, 0x48, 0x43, 0x0d, 0x73, 0xa5, ++ 0x5d, 0xc5, 0x9e, 0x53, 0xf3, 0x3a, 0xa8, 0xda, 0x59, 0xd9, 0x31, 0xd0, ++ 0x4e, 0xfc, 0x87, 0xbe, 0x97, 0x75, 0xbc, 0xb3, 0xa0, 0xe4, 0x08, 0x72, ++ 0x32, 0x1e, 0xe6, 0xbd, 0xe8, 0x76, 0x61, 0xfd, 0x81, 0xf5, 0x86, 0x19, ++ 0xff, 0xe7, 0x41, 0xee, 0x68, 0xa7, 0xf2, 0xad, 0x5f, 0xbe, 0x29, 0x07, ++ 0x8d, 0x6d, 0xc2, 0x3a, 0x91, 0x30, 0x2f, 0xb9, 0x89, 0xe6, 0xac, 0x59, ++ 0x73, 0xb6, 0x63, 0x6c, 0x58, 0xe5, 0xe2, 0xf3, 0x99, 0x33, 0x97, 0x61, ++ 0x1f, 0xcd, 0x67, 0x4d, 0xa3, 0xc0, 0x19, 0xda, 0x86, 0x94, 0x37, 0x3c, ++ 0xd8, 0xeb, 0x36, 0xac, 0x1d, 0x6d, 0xc2, 0xa0, 0xf1, 0x2d, 0xde, 0x2b, ++ 0xce, 0xca, 0x73, 0xcc, 0x51, 0xf8, 0xf5, 0x61, 0x7b, 0xae, 0x63, 0x6e, ++ 0xea, 0x5a, 0xc5, 0x93, 0x53, 0xcb, 0x3a, 0x3f, 0x4c, 0xf3, 0x81, 0x3a, ++ 0x9b, 0x6b, 0x9b, 0x94, 0x59, 0x8f, 0xb1, 0x9c, 0xa4, 0xbc, 0xe2, 0x35, ++ 0xe7, 0x39, 0xa1, 0xfe, 0xc6, 0xa8, 0xc9, 0xc7, 0x3e, 0x88, 0xf9, 0x13, ++ 0x37, 0x6a, 0x59, 0x3a, 0x00, 0x3b, 0xf4, 0x77, 0x0e, 0x70, 0x21, 0xf6, ++ 0xd3, 0x75, 0xa7, 0x79, 0x7e, 0xdb, 0xf9, 0xdf, 0x4a, 0x2e, 0x1d, 0xc8, ++ 0xc8, 0xe2, 0x36, 0xdf, 0xe1, 0xb7, 0xdf, 0x35, 0x04, 0x7d, 0x6f, 0x49, ++ 0x71, 0xd4, 0x4b, 0x2c, 0xf0, 0x5c, 0xc3, 0x1d, 0x01, 0xca, 0xa7, 0x1f, ++ 0x9d, 0x04, 0xbd, 0xbc, 0x1e, 0x04, 0x3e, 0x62, 0x4e, 0x22, 0xee, 0x99, ++ 0x13, 0x18, 0xf7, 0x40, 0xaf, 0xab, 0xce, 0x2b, 0xb4, 0xce, 0xfe, 0xfe, ++ 0x5e, 0xe6, 0xc0, 0xf5, 0x78, 0xe1, 0xda, 0xab, 0xef, 0xda, 0xd0, 0x77, ++ 0xc4, 0xbc, 0x9f, 0xd8, 0xe6, 0xbf, 0xf4, 0xb1, 0xdc, 0xce, 0x35, 0x33, ++ 0xb1, 0x17, 0xd6, 0x1f, 0x57, 0xb4, 0xcc, 0x42, 0x57, 0xcf, 0xa9, 0xf9, ++ 0xdc, 0x0f, 0x59, 0x88, 0xc8, 0xfc, 0xb6, 0xfc, 0xde, 0x0f, 0xf9, 0xdd, ++ 0xc3, 0x14, 0xcf, 0x5d, 0x64, 0x2d, 0x94, 0x31, 0xca, 0x17, 0x65, 0xeb, ++ 0xe3, 0xdd, 0xdc, 0x73, 0xe5, 0xed, 0x75, 0x77, 0x94, 0xcd, 0x4d, 0xda, ++ 0xe1, 0xba, 0xf3, 0x7a, 0xb7, 0xdc, 0xaa, 0x70, 0x7f, 0x64, 0x7e, 0x83, ++ 0xb5, 0xf5, 0xcd, 0xda, 0x66, 0x9a, 0xbe, 0x83, 0x08, 0xfb, 0x63, 0x0c, ++ 0x94, 0x36, 0x88, 0xe7, 0x50, 0xed, 0x52, 0x56, 0x32, 0x68, 0x29, 0x6c, ++ 0x9d, 0x73, 0xf3, 0x49, 0xc6, 0xbc, 0x8f, 0xc9, 0xbf, 0x03, 0xcd, 0xb9, ++ 0xe1, 0xa8, 0xe8, 0xb6, 0x33, 0xe0, 0xf7, 0xa6, 0x0b, 0x7f, 0x90, 0x67, ++ 0xd6, 0x15, 0x47, 0xce, 0xa9, 0x73, 0x57, 0xec, 0xd1, 0x4e, 0x47, 0x16, ++ 0xbd, 0xed, 0x73, 0x78, 0xa9, 0xa1, 0xce, 0x1a, 0xde, 0x3d, 0xb1, 0x4d, ++ 0x1b, 0xfd, 0x09, 0xf8, 0x52, 0xde, 0xcf, 0x83, 0x52, 0xfc, 0xa6, 0xba, ++ 0x46, 0xaf, 0x33, 0x4e, 0xc3, 0xf3, 0x01, 0x57, 0x0a, 0xf0, 0x0b, 0x0b, ++ 0xf0, 0x09, 0x0b, 0x4a, 0x2f, 0x30, 0x6e, 0xc3, 0x18, 0x5b, 0x19, 0x3e, ++ 0x48, 0x39, 0x68, 0xf7, 0x4e, 0xaa, 0x18, 0xe2, 0xa5, 0x8d, 0x54, 0xb9, ++ 0x2c, 0x5e, 0xf2, 0xc1, 0xed, 0x7c, 0xba, 0xee, 0x72, 0x2c, 0xdb, 0x1c, ++ 0x87, 0x4b, 0xaa, 0x5c, 0xb4, 0x0e, 0x60, 0xe4, 0xe3, 0xd0, 0xd5, 0xcf, ++ 0xfb, 0x8c, 0xbf, 0xdd, 0x49, 0x7e, 0x7f, 0x95, 0x93, 0xb4, 0x87, 0x46, ++ 0xc5, 0xbb, 0xe0, 0x0d, 0x3f, 0x28, 0xf4, 0x3f, 0x52, 0xc9, 0x23, 0xe4, ++ 0xdb, 0xf6, 0x37, 0x0d, 0xa1, 0x7d, 0x1d, 0x95, 0xc1, 0x0b, 0xaf, 0xab, ++ 0x33, 0x8e, 0x4f, 0xf8, 0xad, 0xb2, 0xa1, 0xe2, 0x77, 0xa3, 0x3d, 0x32, ++ 0x08, 0xdf, 0x57, 0x60, 0xa1, 0xf8, 0x8d, 0x83, 0x05, 0xdf, 0x43, 0xdd, ++ 0xcb, 0x74, 0x23, 0x69, 0xf2, 0x54, 0x69, 0x5f, 0x19, 0xdf, 0xd3, 0x79, ++ 0x7a, 0xcc, 0x4d, 0x65, 0xfe, 0x64, 0x51, 0xe5, 0xeb, 0x31, 0xd6, 0xc7, ++ 0x58, 0x1e, 0xe3, 0x7d, 0x8c, 0xdb, 0xe9, 0x5c, 0xbd, 0x89, 0xc6, 0x6e, ++ 0xb1, 0xbd, 0x30, 0x5f, 0x52, 0xdb, 0xad, 0xad, 0xcc, 0x3e, 0xd8, 0x3a, ++ 0x57, 0xc5, 0x4e, 0x4a, 0x6e, 0x8f, 0x1c, 0x1b, 0x6e, 0x07, 0xcf, 0x7b, ++ 0x55, 0x3e, 0x9d, 0xed, 0xdd, 0x0f, 0x1c, 0xcb, 0xf8, 0x1c, 0xb1, 0x69, ++ 0xc8, 0xe7, 0x7b, 0xf0, 0xec, 0x1d, 0xf0, 0x9e, 0xcf, 0x80, 0x5b, 0x95, ++ 0x1d, 0xfa, 0xbc, 0x6c, 0x55, 0x98, 0x03, 0x5f, 0xdb, 0x97, 0x57, 0xeb, ++ 0x41, 0xdf, 0x3c, 0xd4, 0x4d, 0x61, 0xfe, 0x28, 0x7d, 0x2a, 0xd7, 0x9c, ++ 0x93, 0xd3, 0x37, 0xef, 0x85, 0xbf, 0x4e, 0xfd, 0x63, 0xa9, 0xb1, 0xae, ++ 0x47, 0x3e, 0x20, 0xe5, 0xda, 0x6e, 0x67, 0xfe, 0x41, 0xf0, 0x0d, 0x5f, ++ 0xe5, 0xac, 0xc2, 0x9f, 0xd4, 0x6b, 0xac, 0xbf, 0x8f, 0x74, 0x76, 0xf2, ++ 0xcb, 0xe3, 0xda, 0x67, 0xcc, 0xf5, 0x02, 0xb3, 0x78, 0xa7, 0xbb, 0x77, ++ 0xb0, 0xf3, 0x2f, 0x0d, 0xae, 0x25, 0x6e, 0xee, 0x55, 0xd8, 0xc0, 0xae, ++ 0x87, 0x72, 0xc2, 0x7c, 0x1f, 0x62, 0xea, 0x03, 0x92, 0xab, 0x41, 0x6f, ++ 0xf6, 0xf1, 0xfe, 0x47, 0xa6, 0x2d, 0xaf, 0x03, 0x39, 0x3c, 0xd6, 0x7a, ++ 0x96, 0x3f, 0xae, 0x71, 0x7d, 0x67, 0x78, 0x9e, 0x1f, 0xe6, 0xbc, 0xdf, ++ 0x94, 0x5b, 0x0b, 0x79, 0x0a, 0x69, 0xd0, 0x63, 0x4d, 0x80, 0xde, 0x7a, ++ 0x35, 0x21, 0xbd, 0x1e, 0xf3, 0x84, 0x22, 0x32, 0xd6, 0x9b, 0x82, 0x13, ++ 0xaf, 0xe9, 0xa9, 0xd7, 0x60, 0xf3, 0xab, 0x21, 0x9d, 0x1a, 0xe3, 0xd7, ++ 0x6b, 0x7c, 0x9f, 0xc4, 0x58, 0xed, 0x32, 0xd6, 0x47, 0x3e, 0xb7, 0xd2, ++ 0x91, 0x34, 0xf9, 0xdc, 0xad, 0xcf, 0xef, 0x6b, 0xa2, 0xef, 0xd6, 0xef, ++ 0x4a, 0xf3, 0x8c, 0x8b, 0xad, 0xd0, 0x3f, 0x21, 0x8d, 0xbd, 0xd0, 0x73, ++ 0x98, 0xa3, 0x1f, 0xfa, 0x1a, 0x21, 0x5f, 0x42, 0x1f, 0x25, 0xaa, 0xe4, ++ 0x62, 0x36, 0xc3, 0xb9, 0x44, 0x8d, 0xcf, 0x42, 0xba, 0x14, 0x6d, 0x11, ++ 0x9e, 0x25, 0x46, 0xbd, 0xcf, 0xec, 0xd3, 0xeb, 0xff, 0xa4, 0x99, 0xaf, ++ 0x6b, 0xea, 0xb0, 0xaf, 0xfd, 0x68, 0xff, 0xb5, 0x00, 0x63, 0x31, 0x08, ++ 0x87, 0xfd, 0x1f, 0x62, 0xf7, 0xfd, 0xba, 0xaf, 0xce, 0x10, 0xbf, 0x87, ++ 0xdf, 0xa1, 0x91, 0x4e, 0xee, 0xaf, 0x90, 0x87, 0xec, 0xa3, 0xd7, 0xc4, ++ 0x5c, 0x49, 0x43, 0x47, 0x0b, 0x0d, 0x29, 0xff, 0x66, 0x1d, 0x77, 0x4f, ++ 0xd3, 0xdc, 0x29, 0x6b, 0xdd, 0xb2, 0x50, 0xed, 0x94, 0xf9, 0xaa, 0xf2, ++ 0x75, 0x86, 0x45, 0x88, 0xed, 0xb8, 0x2f, 0x55, 0x2e, 0xb3, 0xc9, 0x99, ++ 0x0c, 0xf7, 0x67, 0x37, 0xea, 0xd1, 0x86, 0xa0, 0xac, 0x69, 0xfd, 0x54, ++ 0x93, 0x5b, 0xbf, 0xd3, 0x98, 0x6b, 0xb4, 0xe6, 0xe3, 0x5d, 0x6f, 0xca, ++ 0xc7, 0x6b, 0xce, 0x7f, 0x2a, 0xcb, 0x23, 0x07, 0x3b, 0x64, 0xe0, 0x6c, ++ 0xa7, 0x91, 0xd1, 0xfb, 0xcd, 0x38, 0x18, 0x6f, 0x69, 0x5c, 0x06, 0x96, ++ 0xbe, 0x28, 0xa5, 0x69, 0x95, 0xff, 0xde, 0xf4, 0xfd, 0xc3, 0xa0, 0xf9, ++ 0xfe, 0x29, 0x67, 0x31, 0x17, 0xa6, 0xb0, 0x84, 0xf5, 0x3a, 0x98, 0x1a, ++ 0x4e, 0xda, 0xfc, 0x46, 0xf7, 0x31, 0x19, 0x58, 0x1d, 0x97, 0xf4, 0x12, ++ 0x31, 0x03, 0xb3, 0x01, 0x52, 0x2a, 0x2e, 0x9a, 0xbe, 0xa8, 0xfb, 0xf3, ++ 0x96, 0xf8, 0x3e, 0x0d, 0xbc, 0xca, 0xf7, 0x85, 0x44, 0x44, 0x65, 0x0c, ++ 0x7c, 0x10, 0xf2, 0xd4, 0x66, 0xf0, 0x80, 0x23, 0xf9, 0x25, 0xb6, 0x27, ++ 0xf6, 0xf8, 0x47, 0xac, 0x59, 0x21, 0x69, 0x0b, 0xdb, 0xa8, 0xfe, 0x70, ++ 0x1d, 0xc6, 0xd3, 0xc9, 0xeb, 0x51, 0x59, 0x6f, 0x78, 0xd8, 0x13, 0xfa, ++ 0x9b, 0x89, 0x52, 0x2d, 0xcc, 0x27, 0x7d, 0xc4, 0xc4, 0x00, 0x34, 0x8d, ++ 0xc5, 0x4a, 0xab, 0xec, 0x3d, 0x63, 0xbe, 0x9d, 0xe8, 0x50, 0x67, 0x68, ++ 0x4d, 0xfa, 0xcf, 0xd4, 0xbf, 0xdd, 0x65, 0xde, 0x80, 0x08, 0xdf, 0x37, ++ 0xf9, 0x24, 0xf1, 0xb8, 0xda, 0x07, 0x03, 0xf5, 0xb0, 0xde, 0xa8, 0xab, ++ 0x7d, 0x60, 0xf2, 0x29, 0x6b, 0x68, 0x1e, 0x83, 0xcf, 0xc3, 0x67, 0x07, ++ 0xd0, 0x96, 0xeb, 0x84, 0xb2, 0x7e, 0x40, 0xe5, 0x39, 0x46, 0xb2, 0x47, ++ 0xcc, 0x59, 0x5a, 0x9f, 0x1a, 0xcb, 0xcd, 0xb2, 0xff, 0x50, 0x37, 0x74, ++ 0x34, 0x8d, 0xdf, 0x4a, 0x2f, 0x7d, 0xf8, 0x9f, 0x19, 0x79, 0xe1, 0x7b, ++ 0xde, 0xb7, 0xd6, 0xf9, 0xa3, 0x7d, 0xe1, 0x7b, 0x67, 0xfb, 0x1b, 0x0c, ++ 0xf2, 0x92, 0x67, 0x80, 0x28, 0x2f, 0x32, 0x97, 0x9d, 0xd7, 0x28, 0xcd, ++ 0xb7, 0x25, 0xce, 0x12, 0x7f, 0xad, 0xfd, 0x38, 0xe8, 0x3b, 0xdc, 0xb3, ++ 0xbb, 0xe5, 0x06, 0x51, 0x17, 0x9f, 0xb6, 0xb6, 0x2a, 0x8c, 0x5d, 0x94, ++ 0xe5, 0x58, 0xa6, 0x5b, 0x66, 0xab, 0x36, 0xbf, 0x4d, 0x65, 0x2c, 0x96, ++ 0x67, 0x95, 0x32, 0xa7, 0x74, 0xdc, 0x90, 0xe8, 0xef, 0x76, 0x3b, 0xa4, ++ 0xe8, 0x52, 0x9e, 0x87, 0x64, 0xbd, 0x36, 0xdd, 0x94, 0x03, 0xdc, 0x66, ++ 0xe4, 0xec, 0xef, 0xa2, 0xd2, 0xc9, 0x38, 0x52, 0xb8, 0xa7, 0x87, 0xa4, ++ 0x58, 0x6b, 0x3e, 0x67, 0x60, 0x9e, 0x11, 0xe5, 0xb6, 0xbf, 0x69, 0xef, ++ 0x31, 0x57, 0x0f, 0xb8, 0x2a, 0x4e, 0x9f, 0x95, 0xf5, 0xf6, 0x1a, 0x7b, ++ 0xfb, 0x15, 0xac, 0xc7, 0xfb, 0x2d, 0xf1, 0x48, 0x1b, 0x6c, 0x84, 0xc9, ++ 0x35, 0x3e, 0x1c, 0x2f, 0xc3, 0x3f, 0x1b, 0x32, 0xe3, 0xde, 0x81, 0x7b, ++ 0xd6, 0xdd, 0x67, 0xde, 0xef, 0x37, 0xf7, 0x9d, 0xe6, 0x3e, 0x82, 0x7b, ++ 0xe6, 0x8d, 0xb3, 0x4f, 0x96, 0xfc, 0x9e, 0x88, 0xdf, 0xeb, 0x64, 0x25, ++ 0x7a, 0x11, 0xe8, 0xa9, 0xd1, 0x29, 0x9f, 0xae, 0x29, 0xfe, 0x5a, 0xde, ++ 0x12, 0x01, 0xc1, 0x7e, 0x73, 0x7d, 0xeb, 0x1e, 0xfc, 0xdc, 0x4d, 0xdf, ++ 0x4a, 0x55, 0x8c, 0xac, 0x34, 0xd3, 0x9b, 0x03, 0xad, 0xef, 0x96, 0x83, ++ 0x45, 0x1b, 0xa5, 0xfd, 0xc6, 0x62, 0x45, 0xe7, 0x1a, 0x1d, 0x83, 0xdf, ++ 0x78, 0xb8, 0xfa, 0xa8, 0xab, 0xf3, 0x62, 0xc2, 0x5c, 0xca, 0x4e, 0xcc, ++ 0x6b, 0xc8, 0x9c, 0x5b, 0xb3, 0x2d, 0x73, 0x3a, 0xc3, 0xf3, 0x99, 0x66, ++ 0xac, 0x4a, 0x5b, 0x44, 0x3b, 0xc3, 0xef, 0x9a, 0x7c, 0xd4, 0x5d, 0xa4, ++ 0xae, 0x69, 0xca, 0xcd, 0xff, 0x52, 0x4b, 0x6e, 0x3e, 0xbf, 0xfb, 0x16, ++ 0xf9, 0x6f, 0x0d, 0xc6, 0x95, 0x3a, 0x24, 0x72, 0x36, 0xcc, 0xc1, 0xe2, ++ 0x1a, 0x13, 0x87, 0xf1, 0x7b, 0xef, 0xa9, 0x5d, 0x62, 0x4e, 0xa1, 0x9c, ++ 0x7f, 0xc7, 0x65, 0x7e, 0xab, 0x9b, 0x0d, 0xe3, 0x54, 0xcc, 0xeb, 0x21, ++ 0xe6, 0x3a, 0x60, 0x62, 0x0a, 0x7c, 0x57, 0x96, 0x9e, 0x83, 0x53, 0xdc, ++ 0x1b, 0xbf, 0x1d, 0xd9, 0xce, 0xfd, 0x57, 0xe3, 0xc4, 0x35, 0x86, 0xe4, ++ 0x77, 0xe3, 0x3e, 0xf6, 0xd5, 0x9e, 0xcd, 0xf0, 0x9b, 0x8c, 0xcb, 0x8d, ++ 0x8c, 0xfa, 0xf6, 0x83, 0x67, 0x1e, 0x5b, 0x0d, 0xee, 0x3b, 0x7e, 0x23, ++ 0x9e, 0x55, 0x39, 0x01, 0x5b, 0xe6, 0x9b, 0xe7, 0xab, 0x0d, 0xfd, 0x1d, ++ 0xcb, 0xe2, 0xb2, 0xca, 0xcb, 0x07, 0x56, 0x4b, 0xe2, 0x3d, 0x73, 0xe8, ++ 0xfa, 0x55, 0x2e, 0xc1, 0x7c, 0xe3, 0x53, 0x28, 0x3f, 0x2f, 0x6b, 0x15, ++ 0x1d, 0x7f, 0x9d, 0x6f, 0x30, 0xa7, 0xc0, 0x55, 0x67, 0x44, 0x03, 0x4b, ++ 0x45, 0x8c, 0x17, 0x7e, 0xb3, 0x1d, 0xc7, 0x33, 0xd2, 0x57, 0x36, 0x7b, ++ 0x34, 0xcc, 0x05, 0xe9, 0xea, 0xa1, 0x4d, 0x28, 0x37, 0xba, 0x54, 0x1e, ++ 0x82, 0xc6, 0x23, 0xc4, 0x7a, 0x31, 0xd4, 0xe5, 0x5c, 0x3b, 0x69, 0xaf, ++ 0x02, 0xea, 0xa4, 0x34, 0xc6, 0xa9, 0xab, 0xdc, 0x44, 0xf2, 0xd9, 0x73, ++ 0x4b, 0xf4, 0xd7, 0x94, 0x8e, 0x4f, 0x0d, 0xcf, 0x48, 0xc1, 0x8d, 0xc2, ++ 0x17, 0x9b, 0x57, 0x7e, 0xce, 0xfd, 0xc0, 0xd0, 0x5d, 0x9b, 0x91, 0x2c, ++ 0xe7, 0xc6, 0xb1, 0xe9, 0x87, 0xe8, 0xf9, 0xe8, 0x33, 0x02, 0xb1, 0xe6, ++ 0xd5, 0xf7, 0x8f, 0x7c, 0xce, 0x78, 0x6f, 0xf8, 0xcd, 0x90, 0xfe, 0x26, ++ 0x64, 0xa6, 0x71, 0x44, 0x4e, 0x55, 0xf6, 0xf2, 0x5b, 0x09, 0x7f, 0x0b, ++ 0x7c, 0x3b, 0xd6, 0xe8, 0x52, 0xdf, 0xa5, 0xcc, 0x34, 0x98, 0x3f, 0x17, ++ 0xda, 0x1e, 0xae, 0x55, 0xdc, 0x7c, 0x37, 0x91, 0x30, 0xdf, 0x4d, 0xf0, ++ 0xdb, 0x8f, 0x1f, 0xed, 0x0d, 0xf7, 0xfb, 0xad, 0x38, 0x9c, 0x32, 0xf8, ++ 0xa7, 0xf0, 0x0d, 0xc3, 0x3c, 0x4c, 0xe6, 0x8b, 0x06, 0xc1, 0x31, 0x9f, ++ 0xf1, 0xdb, 0xe9, 0xc3, 0x6b, 0x98, 0xe3, 0x95, 0x1a, 0x78, 0x78, 0x94, ++ 0xcf, 0x98, 0x37, 0xd6, 0x2e, 0xf9, 0xd1, 0x76, 0xea, 0xf2, 0xce, 0x35, ++ 0x6f, 0xaf, 0x5c, 0xae, 0xc6, 0x55, 0x0e, 0x5c, 0x09, 0x38, 0xbf, 0x2e, ++ 0x1f, 0xeb, 0xe1, 0xd9, 0xdd, 0x84, 0x6a, 0x1f, 0xee, 0x77, 0x1d, 0x37, ++ 0x98, 0x58, 0xd7, 0xfa, 0xe4, 0x78, 0x06, 0xb8, 0xe5, 0x82, 0x58, 0x7f, ++ 0x90, 0xe9, 0x87, 0xef, 0xcd, 0xb1, 0xd2, 0x68, 0x07, 0xd9, 0x49, 0x70, ++ 0xaf, 0xbf, 0x13, 0xd4, 0x41, 0xef, 0x8d, 0x06, 0xf1, 0x3a, 0x30, 0xd4, ++ 0x34, 0xdb, 0x64, 0xc5, 0x3e, 0xc3, 0x3a, 0xbd, 0x90, 0xbf, 0x28, 0xe6, ++ 0xe3, 0xc0, 0x17, 0xd8, 0x27, 0x75, 0x97, 0xef, 0x1c, 0x7d, 0xa6, 0x12, ++ 0x0f, 0xfd, 0x94, 0xef, 0x81, 0x7f, 0x49, 0xa5, 0x93, 0xc2, 0xf3, 0x4e, ++ 0xe6, 0xb3, 0xce, 0x56, 0x27, 0xb1, 0x87, 0x1c, 0x83, 0xcd, 0x1c, 0xf4, ++ 0xf1, 0xe1, 0x1e, 0x8d, 0x15, 0x78, 0x1e, 0xaa, 0xb1, 0x88, 0xb6, 0x31, ++ 0x3c, 0xdf, 0x71, 0xe0, 0x0b, 0x84, 0xfb, 0xf2, 0x99, 0x7d, 0x37, 0x7f, ++ 0x0b, 0x43, 0x1c, 0x93, 0x4e, 0x9c, 0xe7, 0x79, 0xdc, 0xc6, 0xc3, 0x32, ++ 0x03, 0x9a, 0x4f, 0x9b, 0x79, 0x3e, 0x98, 0xf1, 0xe4, 0x7a, 0x8d, 0xe7, ++ 0x95, 0x07, 0x50, 0x32, 0xd7, 0x91, 0x34, 0x8f, 0x98, 0x7c, 0xce, 0x2c, ++ 0xe6, 0xfa, 0x98, 0xbc, 0x01, 0x7c, 0xfd, 0x66, 0x25, 0xed, 0x4f, 0xa8, ++ 0x3c, 0xa4, 0x54, 0xe2, 0xb2, 0x8c, 0x24, 0xe9, 0x03, 0x96, 0xdd, 0x54, ++ 0xe2, 0x3a, 0xe4, 0xe1, 0x46, 0xe5, 0x99, 0x1e, 0xfe, 0xaf, 0x8a, 0x3a, ++ 0xec, 0xe1, 0x0d, 0x95, 0x83, 0x94, 0x62, 0xcc, 0x04, 0xf7, 0xfd, 0x26, ++ 0x0f, 0x8a, 0xe3, 0xf0, 0x5d, 0xbf, 0xbc, 0x51, 0xd9, 0xb6, 0xbf, 0x1c, ++ 0xc7, 0x7c, 0x03, 0xcf, 0xb1, 0x2e, 0xf4, 0x50, 0x0f, 0x71, 0x3c, 0xdd, ++ 0x47, 0x58, 0x87, 0x7c, 0x0d, 0xe3, 0x9a, 0xea, 0x5b, 0xcb, 0xa4, 0x58, ++ 0x96, 0xb4, 0x79, 0x9c, 0xfb, 0x54, 0x8f, 0xc6, 0x40, 0x6c, 0x97, 0x76, ++ 0x0f, 0xab, 0xfe, 0x78, 0xb6, 0xc7, 0xf3, 0xaf, 0xb0, 0x1f, 0xe6, 0x43, ++ 0x31, 0xe7, 0x8a, 0xba, 0xaf, 0x99, 0x06, 0x6d, 0xff, 0xdf, 0x50, 0xb1, ++ 0xf4, 0x71, 0xd4, 0xa7, 0x8d, 0x86, 0xbc, 0xd4, 0x12, 0xdb, 0xdf, 0x7c, ++ 0x68, 0x5e, 0xf2, 0xfa, 0x99, 0xed, 0x6f, 0x32, 0xec, 0xbb, 0x5d, 0xf3, ++ 0x3e, 0xc4, 0xa5, 0xfd, 0xd8, 0xaf, 0x8f, 0x49, 0x7d, 0x25, 0x9d, 0xf8, ++ 0xb4, 0x84, 0xfd, 0x06, 0x87, 0x78, 0xde, 0x51, 0xcc, 0x8c, 0xb8, 0x0b, ++ 0x8a, 0x9e, 0x54, 0x82, 0x39, 0xc8, 0x97, 0x31, 0x5e, 0xbd, 0xd1, 0x1a, ++ 0x7b, 0x48, 0xe5, 0x36, 0x25, 0xed, 0xeb, 0xb5, 0x19, 0x92, 0x4d, 0xac, ++ 0xcd, 0x9f, 0x9b, 0xb5, 0xf9, 0x18, 0xfa, 0xf6, 0xce, 0x8c, 0x4a, 0xfa, ++ 0x4c, 0x3a, 0x79, 0x5a, 0x78, 0x96, 0xb8, 0x8f, 0x31, 0x2c, 0xeb, 0xc1, ++ 0x4c, 0x12, 0xf3, 0x4d, 0x61, 0xbe, 0x28, 0x1b, 0xbc, 0x1e, 0x81, 0x6f, ++ 0xbe, 0x87, 0x7b, 0xfb, 0x10, 0x75, 0x26, 0x79, 0x51, 0x54, 0xef, 0x80, ++ 0x4f, 0x9e, 0x26, 0x4d, 0x00, 0xca, 0x9d, 0x29, 0x15, 0x07, 0xbc, 0xde, ++ 0xe0, 0xf9, 0xa2, 0xa6, 0xaf, 0x00, 0xfa, 0xe6, 0x34, 0x7d, 0xc9, 0x99, ++ 0x6d, 0xec, 0x9a, 0x4a, 0x9c, 0x12, 0xe2, 0x25, 0xe2, 0x17, 0xe2, 0xfa, ++ 0x47, 0x7a, 0xc3, 0x6f, 0x5a, 0xf2, 0x77, 0xe7, 0xb6, 0xe7, 0xde, 0x86, ++ 0xba, 0x57, 0x32, 0x2a, 0xbf, 0xd9, 0x3d, 0x22, 0x1f, 0x91, 0xdc, 0xa7, ++ 0x52, 0xc9, 0x9c, 0xe5, 0x19, 0x0c, 0x88, 0xb2, 0xc6, 0x6b, 0xea, 0x5c, ++ 0xcf, 0x60, 0x0b, 0xae, 0x4d, 0x06, 0x63, 0x29, 0xde, 0xc2, 0x67, 0xea, ++ 0x87, 0xcc, 0x53, 0xd6, 0x7e, 0x07, 0x7b, 0x48, 0xff, 0x9f, 0x8e, 0xcb, ++ 0xe0, 0xe3, 0x3c, 0xf8, 0x78, 0xfc, 0x16, 0x0c, 0x16, 0xdd, 0xc6, 0x60, ++ 0x5b, 0x6a, 0xbc, 0x7b, 0x41, 0x53, 0xc1, 0x25, 0xfe, 0x9a, 0xdf, 0x96, ++ 0x15, 0xd2, 0x34, 0xca, 0xff, 0xb5, 0x23, 0x57, 0x33, 0x5c, 0x0f, 0x60, ++ 0x30, 0xf4, 0xb7, 0xb6, 0x23, 0x4b, 0x98, 0xbf, 0x92, 0x5f, 0xc8, 0x6e, ++ 0xca, 0x75, 0x2c, 0xae, 0x05, 0xfb, 0x13, 0xeb, 0x1a, 0x68, 0xd9, 0x52, ++ 0x72, 0xa0, 0x65, 0x60, 0xab, 0xd6, 0xf9, 0x1e, 0x32, 0xc0, 0x79, 0x52, ++ 0xfe, 0x42, 0xd9, 0xdb, 0xc9, 0xa7, 0xe8, 0x00, 0x4f, 0x3e, 0x78, 0x4f, ++ 0x56, 0xf2, 0x67, 0x78, 0x16, 0x26, 0xd6, 0xc8, 0x3d, 0x94, 0x49, 0xe2, ++ 0x04, 0x60, 0xc8, 0x04, 0x79, 0xac, 0xf1, 0xe0, 0xcc, 0xb3, 0x7b, 0xf1, ++ 0x7b, 0xb3, 0x87, 0x39, 0x33, 0xf9, 0x73, 0xd4, 0x57, 0x62, 0xdd, 0x79, ++ 0x8f, 0xf6, 0x0f, 0x6f, 0xc4, 0xc1, 0x73, 0xbc, 0x1f, 0x78, 0xb2, 0x0d, ++ 0xfa, 0xca, 0x31, 0xf3, 0xe6, 0x3d, 0xf9, 0x8a, 0xf2, 0xd9, 0x29, 0xa3, ++ 0x03, 0xa8, 0x47, 0xc4, 0xec, 0x8b, 0xb2, 0xcc, 0x31, 0x46, 0x9f, 0xe9, ++ 0x94, 0x09, 0xe8, 0xb5, 0x23, 0x95, 0x71, 0xf9, 0x72, 0xa5, 0x4b, 0xe1, ++ 0x86, 0xbf, 0xf6, 0xd3, 0x89, 0x61, 0x2b, 0x90, 0x07, 0x81, 0x7f, 0x66, ++ 0xfa, 0xdb, 0xe4, 0xcd, 0x51, 0x9d, 0xfb, 0x7b, 0x83, 0xc9, 0x8d, 0x2e, ++ 0xf3, 0x55, 0x39, 0x1f, 0xe8, 0x7d, 0x0b, 0xbe, 0x80, 0xd5, 0x2e, 0x33, ++ 0xf1, 0x2e, 0xf9, 0xb8, 0x8f, 0xf2, 0x36, 0x5f, 0x7d, 0x63, 0x9c, 0x8b, ++ 0x37, 0xeb, 0x91, 0x37, 0xcd, 0xd8, 0x5f, 0x34, 0xe5, 0xbf, 0xe9, 0x6d, ++ 0xa2, 0xc5, 0x9a, 0xcb, 0x44, 0xd4, 0xfc, 0xe6, 0x6b, 0xd4, 0x6f, 0x6c, ++ 0x03, 0x7d, 0xd2, 0xe0, 0x39, 0x51, 0x59, 0xd6, 0xa0, 0x5f, 0x4a, 0x55, ++ 0xb1, 0xce, 0x65, 0x80, 0xa8, 0x3d, 0x8d, 0x3f, 0x4b, 0x90, 0xaf, 0xd9, ++ 0xaa, 0x8a, 0x59, 0xaa, 0xbc, 0xed, 0x59, 0x60, 0x5d, 0xf8, 0xc4, 0xc0, ++ 0x10, 0x26, 0x7f, 0xa5, 0x93, 0xf1, 0x90, 0x66, 0x1d, 0x16, 0xfe, 0x2f, ++ 0x9d, 0xff, 0xd4, 0x2b, 0xdd, 0x65, 0xac, 0x4b, 0x88, 0xb9, 0xc1, 0x53, ++ 0x8c, 0x99, 0x57, 0xeb, 0x14, 0xae, 0x09, 0x75, 0x4f, 0x73, 0xbe, 0x78, ++ 0x88, 0x39, 0xb8, 0x67, 0x69, 0x2f, 0xa4, 0x1c, 0x03, 0xa6, 0xed, 0x38, ++ 0x03, 0xdb, 0x5d, 0xcd, 0x42, 0x56, 0xc6, 0x55, 0xde, 0xe7, 0x3c, 0xb0, ++ 0xdb, 0x1f, 0xf8, 0x7f, 0x2a, 0xf6, 0xd3, 0x07, 0x64, 0xad, 0xda, 0x01, ++ 0x7e, 0xd0, 0x2e, 0x44, 0x95, 0x7f, 0x7d, 0xe3, 0x28, 0xed, 0x1d, 0x6d, ++ 0x89, 0x5e, 0x8b, 0xad, 0xda, 0xf7, 0x7a, 0xf5, 0xb7, 0x33, 0x7b, 0x65, ++ 0xb3, 0x16, 0xda, 0x42, 0xf8, 0x87, 0xd5, 0xa8, 0xb1, 0xcb, 0x9d, 0xd0, ++ 0xdd, 0xdf, 0x8f, 0xd6, 0x95, 0xaf, 0xce, 0xf9, 0xd3, 0x06, 0x45, 0x99, ++ 0x17, 0xd7, 0x59, 0xf7, 0x38, 0xf7, 0x66, 0x1b, 0xa4, 0x71, 0x87, 0x7b, ++ 0x90, 0xe3, 0x31, 0x87, 0x82, 0x73, 0x8c, 0x4b, 0xf4, 0xfc, 0x63, 0x62, ++ 0xc3, 0x6f, 0x89, 0x2c, 0x11, 0xeb, 0xdd, 0xec, 0xbb, 0x44, 0x2e, 0xba, ++ 0xe6, 0x5b, 0xec, 0x41, 0x8d, 0x65, 0x32, 0x28, 0xeb, 0xe1, 0xf7, 0xd9, ++ 0xfc, 0x35, 0xdb, 0xcd, 0xd0, 0xb7, 0xd8, 0xd5, 0x96, 0xe2, 0xef, 0xff, ++ 0x01, 0x37, 0x64, 0x26, 0x2b, 0x1c, 0x4c, 0x00, 0x00, 0x00 }; + + static const u32 bnx2_COM_b09FwData[(0x0/4) + 1] = { 0x0 }; + static const u32 bnx2_COM_b09FwRodata[(0x30/4) + 1] = { +- 0x80080100, 0x80080080, 0x80080000, 0x80080240, 0x08000ea4, 0x08000efc, +- 0x08000f40, 0x08000fd4, 0x08001018, 0x80080100, 0x80080080, 0x80080000, ++ 0x80080100, 0x80080080, 0x80080000, 0x80080240, 0x08000e20, 0x08000e78, ++ 0x08000ebc, 0x08000f50, 0x08000f94, 0x80080100, 0x80080080, 0x80080000, + 0x00000000 }; + + static struct fw_info bnx2_com_fw_09 = { +- /* Firmware version: 4.6.15 */ ++ /* Firmware version: 4.4.23 */ + .ver_major = 0x4, +- .ver_minor = 0x6, +- .ver_fix = 0xf, ++ .ver_minor = 0x4, ++ .ver_fix = 0x17, + + .start_addr = 0x080000f8, + + .text_addr = 0x08000000, +- .text_len = 0x4a7c, ++ .text_len = 0x4c18, + .text_index = 0x0, + .gz_text = bnx2_COM_b09FwText, + .gz_text_len = sizeof(bnx2_COM_b09FwText), +@@ -865,1189 +866,1210 @@ + .data_index = 0x0, + .data = bnx2_COM_b09FwData, + +- .sbss_addr = 0x08004ae0, ++ .sbss_addr = 0x08004c60, + .sbss_len = 0x38, + .sbss_index = 0x0, + +- .bss_addr = 0x08004b18, +- .bss_len = 0xc0, ++ .bss_addr = 0x08004c98, ++ .bss_len = 0xbc, + .bss_index = 0x0, + +- .rodata_addr = 0x08004a7c, ++ .rodata_addr = 0x08004c18, + .rodata_len = 0x30, + .rodata_index = 0x0, + .rodata = bnx2_COM_b09FwRodata, + }; + + static u8 bnx2_CP_b09FwText[] = { +- 0xa5, 0xbc, 0x0d, 0x74, 0x1c, 0xe5, 0x95, 0x26, 0xfc, 0x54, 0x75, 0xb7, +- 0xd4, 0x92, 0x5a, 0x52, 0x49, 0x6e, 0x8b, 0x36, 0x68, 0x70, 0xb5, 0x55, +- 0x2d, 0x0b, 0x4b, 0x40, 0xb5, 0x24, 0x3b, 0xed, 0x6c, 0x83, 0x3b, 0xb6, +- 0x6c, 0x64, 0x63, 0x40, 0x36, 0x06, 0xc4, 0xb7, 0xfe, 0x3e, 0x7a, 0xfc, +- 0x03, 0x86, 0x38, 0x19, 0x91, 0xcd, 0xce, 0x0a, 0xd6, 0x59, 0x55, 0xe4, +- 0x3f, 0xd9, 0x6e, 0x75, 0x4b, 0x42, 0xfe, 0xe1, 0xec, 0x9c, 0xa5, 0x2d, +- 0xcb, 0x96, 0x21, 0xad, 0x16, 0x24, 0x6c, 0xc6, 0x39, 0x27, 0x09, 0x1a, +- 0x63, 0x83, 0x0d, 0x18, 0xc8, 0x24, 0xf9, 0x86, 0xc9, 0xd9, 0x5d, 0x34, +- 0xc6, 0xfc, 0x19, 0x70, 0x1c, 0x92, 0xc9, 0x9a, 0x19, 0x4c, 0xed, 0x73, +- 0xab, 0xd5, 0xb6, 0xec, 0x30, 0xc9, 0xcc, 0x59, 0x9d, 0xd3, 0xa7, 0xab, +- 0xab, 0xde, 0x9f, 0xfb, 0xde, 0xf7, 0xde, 0xe7, 0x3e, 0xf7, 0x7d, 0xdf, +- 0x92, 0x0e, 0x14, 0x63, 0xf2, 0xaf, 0x94, 0x9f, 0x9b, 0x9a, 0x3b, 0xd6, +- 0xce, 0x0d, 0xdf, 0x34, 0x4f, 0x7e, 0xbb, 0xcb, 0x0b, 0xdc, 0xf8, 0xb2, +- 0xbf, 0x28, 0x22, 0x57, 0xdf, 0xd2, 0xbf, 0xb4, 0xe0, 0xbf, 0xf0, 0x17, +- 0x41, 0x50, 0xe1, 0x57, 0xfd, 0xe4, 0x4f, 0x17, 0xa0, 0xe5, 0xfb, 0x97, +- 0x0f, 0xbc, 0x6a, 0xd4, 0xb8, 0x77, 0xa1, 0x01, 0xaf, 0x2b, 0xba, 0xaa, +- 0x7d, 0xad, 0x01, 0xc4, 0x32, 0xf5, 0xfa, 0x22, 0x5c, 0xb4, 0x2d, 0xbf, +- 0x1b, 0x72, 0xff, 0xcf, 0xa2, 0x9f, 0x3f, 0xf5, 0x93, 0xaf, 0x04, 0xcf, +- 0xa7, 0x5d, 0xf0, 0x6a, 0x51, 0x0b, 0x5a, 0x2d, 0xbc, 0xd5, 0xac, 0xf3, +- 0x57, 0xb3, 0xb7, 0xa9, 0x28, 0xcb, 0xb7, 0x15, 0x0c, 0xa4, 0x11, 0xd4, +- 0x2c, 0x04, 0xeb, 0x2c, 0x20, 0xee, 0x8e, 0x22, 0x5e, 0x18, 0xf5, 0xa2, +- 0xc0, 0x28, 0x40, 0x5c, 0xeb, 0xd4, 0xb7, 0x34, 0x03, 0x0b, 0x13, 0x5e, +- 0xfd, 0x74, 0x06, 0x58, 0x9b, 0xf0, 0x62, 0xc2, 0xe5, 0xd3, 0xdf, 0xc9, +- 0x44, 0xca, 0x72, 0xfa, 0x88, 0xc1, 0x65, 0x20, 0xae, 0x46, 0xe5, 0x3e, +- 0xf4, 0x45, 0x19, 0xa9, 0x0b, 0x6c, 0x4b, 0x7d, 0x5b, 0x7f, 0x37, 0x11, +- 0xd4, 0xb6, 0xa1, 0x3e, 0x30, 0x84, 0x42, 0xc4, 0xfd, 0xc1, 0x3a, 0xe0, +- 0xf3, 0x8b, 0x3b, 0x53, 0x0a, 0x3c, 0xc6, 0x34, 0xb4, 0xec, 0x07, 0x76, +- 0xa4, 0x82, 0x31, 0x83, 0xc3, 0xeb, 0x19, 0x93, 0xba, 0x41, 0x2d, 0xcd, +- 0xe7, 0x5b, 0x52, 0xc0, 0xd6, 0xd4, 0x34, 0x6c, 0xeb, 0xb3, 0xf1, 0xa2, +- 0x59, 0xa3, 0x1d, 0x60, 0x0f, 0xdd, 0xce, 0xf3, 0x69, 0xb0, 0xd2, 0xf2, +- 0xfc, 0x03, 0xfb, 0x27, 0xb3, 0x35, 0x3c, 0x3b, 0xe6, 0xc7, 0x0b, 0x63, +- 0x15, 0xd8, 0xd1, 0x57, 0x81, 0xed, 0x7d, 0x75, 0x50, 0x0d, 0x1b, 0x75, +- 0xe1, 0x3a, 0x14, 0xcc, 0xb7, 0xf1, 0x8e, 0xd9, 0x80, 0xad, 0x6c, 0xf8, +- 0xcd, 0x86, 0x2a, 0xac, 0xd1, 0xaa, 0xb1, 0xc5, 0xf8, 0x0a, 0x72, 0x63, +- 0xfd, 0xfc, 0x62, 0x2a, 0x85, 0xb8, 0x27, 0xea, 0x56, 0x55, 0xe3, 0x56, +- 0x9c, 0xdb, 0x1d, 0xc5, 0x27, 0xbb, 0xb1, 0xba, 0x0c, 0xb6, 0x9d, 0x09, +- 0x87, 0xda, 0x36, 0x2a, 0x9a, 0xfe, 0x4c, 0x86, 0x02, 0xad, 0x74, 0xb3, +- 0x3d, 0xe8, 0x43, 0x99, 0xa9, 0x53, 0xc1, 0xfe, 0x52, 0xec, 0x37, 0x25, +- 0xb2, 0x04, 0xf0, 0x93, 0xd9, 0x7f, 0x41, 0x7b, 0xc8, 0x8d, 0x69, 0x6b, +- 0xea, 0x2d, 0xca, 0xa4, 0x53, 0x9e, 0x6a, 0xfc, 0x60, 0x2c, 0x80, 0xef, +- 0x53, 0xb6, 0xe7, 0xc6, 0x44, 0xc6, 0xe0, 0x3e, 0x0b, 0x15, 0x18, 0xee, +- 0xab, 0xc6, 0xb3, 0x46, 0x03, 0x9e, 0xa3, 0x8c, 0x9b, 0xcd, 0x3a, 0xac, +- 0x89, 0xdc, 0x4f, 0x79, 0x14, 0xac, 0x6c, 0xf8, 0xf3, 0x49, 0xb9, 0x82, +- 0x3a, 0x54, 0x15, 0xb1, 0xca, 0x60, 0x9d, 0xae, 0x4a, 0x9b, 0x97, 0xe5, +- 0xed, 0x4d, 0xc1, 0xf2, 0x46, 0x45, 0xe6, 0x5b, 0x91, 0xa1, 0xbc, 0xdf, +- 0xdb, 0x1d, 0x32, 0x37, 0xa8, 0x58, 0xee, 0xa3, 0xcc, 0x8f, 0x84, 0x43, +- 0x91, 0x39, 0x94, 0x79, 0x24, 0xa3, 0x72, 0x3c, 0x7e, 0xfd, 0x10, 0x65, +- 0x8f, 0xad, 0x54, 0x29, 0x3b, 0x65, 0x49, 0x51, 0x96, 0x14, 0x65, 0x49, +- 0x51, 0x16, 0x47, 0xee, 0x3a, 0xca, 0x9c, 0x9b, 0xa3, 0xa1, 0xcc, 0x04, +- 0xe5, 0x9d, 0x2a, 0x67, 0x35, 0x65, 0x47, 0xbc, 0x22, 0xfa, 0x6d, 0xbd, +- 0x26, 0x49, 0x7d, 0xa7, 0x6c, 0xfb, 0x4d, 0xd3, 0xb6, 0x3f, 0x35, 0x7d, +- 0xd4, 0x5f, 0x8a, 0x76, 0x90, 0x97, 0x67, 0xa6, 0x55, 0x10, 0x45, 0x0b, +- 0x4d, 0xd0, 0x3e, 0xde, 0x1c, 0x8a, 0x54, 0x2a, 0x2a, 0xdc, 0x86, 0xa6, +- 0xcf, 0xce, 0x06, 0x4d, 0xea, 0x47, 0x0f, 0x65, 0xa1, 0x1b, 0x59, 0xb6, +- 0x75, 0x45, 0xbf, 0x41, 0x6d, 0x1c, 0xd2, 0xaf, 0xce, 0xfe, 0x27, 0x26, +- 0xe7, 0x4e, 0xda, 0x0f, 0xb0, 0x4f, 0xe9, 0x5f, 0xda, 0xb6, 0xed, 0xdf, +- 0x98, 0x30, 0x34, 0x84, 0xac, 0x7e, 0xda, 0x9f, 0x2b, 0xaa, 0xe9, 0x1d, +- 0x19, 0x3e, 0xbf, 0xd4, 0x46, 0x6e, 0x3e, 0xd6, 0x64, 0xf4, 0xc9, 0x31, +- 0x04, 0x29, 0x82, 0xd8, 0x41, 0x20, 0xee, 0x8b, 0x6a, 0x22, 0x7b, 0xdb, +- 0xbe, 0xde, 0x2e, 0x7b, 0x86, 0x21, 0xba, 0x32, 0x3a, 0x67, 0xb8, 0x7c, +- 0x91, 0x73, 0x73, 0x1f, 0xb5, 0x4a, 0x9b, 0xc3, 0x28, 0x36, 0xe0, 0x2b, +- 0x32, 0xd0, 0x96, 0x1c, 0x2d, 0xb6, 0x4a, 0xa2, 0x3f, 0xbe, 0xbb, 0x77, +- 0xd4, 0x8b, 0xe2, 0x51, 0x03, 0x45, 0xa3, 0x4f, 0xbb, 0x51, 0xd6, 0x80, +- 0x5d, 0x63, 0x0f, 0xb9, 0x73, 0x63, 0x5b, 0x32, 0x39, 0x46, 0xc7, 0xf6, +- 0xbd, 0xef, 0x26, 0xce, 0xdb, 0x05, 0x46, 0xd1, 0x7d, 0xae, 0xa8, 0xa1, +- 0x1f, 0x02, 0xce, 0xaf, 0x69, 0x5e, 0x84, 0x6e, 0x4d, 0xc1, 0x4c, 0xe3, +- 0x95, 0x12, 0x94, 0x45, 0x60, 0x8d, 0x55, 0xc5, 0x0b, 0xa2, 0xfe, 0x38, +- 0xe7, 0x06, 0x2f, 0x27, 0xd2, 0xf0, 0xf4, 0xda, 0xb6, 0x94, 0x7d, 0x07, +- 0x77, 0xdf, 0xad, 0x46, 0x8f, 0xde, 0xec, 0x41, 0x0b, 0xcb, 0x63, 0xd3, +- 0x89, 0xe6, 0x4f, 0x15, 0x75, 0x77, 0x1b, 0xac, 0x11, 0x17, 0x62, 0x5a, +- 0x9c, 0xdf, 0xd7, 0x5f, 0xbf, 0x3c, 0xd2, 0x86, 0xc4, 0xc8, 0x05, 0xde, +- 0x77, 0xf3, 0x5e, 0x04, 0xc9, 0xd4, 0xf5, 0xd7, 0xdf, 0x11, 0x89, 0xa3, +- 0x77, 0x44, 0xae, 0xdd, 0x18, 0xaf, 0x88, 0x63, 0xfb, 0x5e, 0x1d, 0xe5, +- 0x46, 0x1b, 0x52, 0x23, 0x72, 0x6d, 0xdb, 0x67, 0xcc, 0xef, 0x62, 0x5f, +- 0x03, 0xfd, 0xff, 0x9a, 0x36, 0x6c, 0xdb, 0x6b, 0xa1, 0xd0, 0xb0, 0xa8, +- 0x7b, 0xc5, 0xfd, 0xf7, 0x0d, 0x0a, 0xf4, 0xbb, 0xe1, 0x2e, 0x30, 0x44, +- 0x6f, 0x11, 0xf7, 0xfa, 0x44, 0x54, 0x9b, 0x69, 0xd8, 0xf6, 0x90, 0x39, +- 0x07, 0x0f, 0xb4, 0xad, 0x81, 0x75, 0xc0, 0x07, 0x6b, 0x95, 0x7c, 0xb7, +- 0x51, 0x87, 0x6b, 0xd0, 0x7d, 0x60, 0x0d, 0x7a, 0x9e, 0xa0, 0xe3, 0x56, +- 0x68, 0xce, 0x3c, 0xfd, 0x64, 0xb6, 0xc8, 0x24, 0xf2, 0xb5, 0xf3, 0x23, +- 0xba, 0xfd, 0x4b, 0x7e, 0x4b, 0x99, 0x0b, 0x36, 0xa6, 0x5f, 0x2e, 0xb3, +- 0x9d, 0x65, 0xb6, 0x5d, 0x51, 0x26, 0x82, 0xa7, 0xc6, 0x44, 0x17, 0xa2, +- 0xb2, 0x3f, 0xa5, 0x8b, 0x9f, 0xda, 0xdd, 0x7e, 0xd1, 0x85, 0xd5, 0xee, +- 0x41, 0xb0, 0xed, 0x41, 0xc5, 0x8d, 0xa5, 0xbd, 0x60, 0x1d, 0x3a, 0x41, +- 0x71, 0x30, 0x56, 0xab, 0x44, 0x51, 0xdc, 0xab, 0x60, 0x69, 0xb8, 0x08, +- 0x7a, 0x85, 0xb4, 0xf7, 0x4b, 0xdb, 0xd2, 0x44, 0xde, 0x13, 0x28, 0xe1, +- 0xfd, 0x75, 0xe1, 0x9f, 0x13, 0xcf, 0x44, 0xa6, 0x30, 0xcb, 0xaf, 0xe0, +- 0xfd, 0x37, 0xa6, 0xfc, 0x96, 0x72, 0xb6, 0xbd, 0x99, 0x3e, 0xdf, 0x43, +- 0x1b, 0xdf, 0x9e, 0x8a, 0x05, 0xa9, 0x25, 0xcb, 0x13, 0xe5, 0xfd, 0x68, +- 0xa8, 0xb5, 0x1b, 0xd2, 0x0f, 0x94, 0xe2, 0x28, 0xdc, 0x99, 0xe6, 0x09, +- 0xef, 0xa9, 0x84, 0xd1, 0xfe, 0x8c, 0xe2, 0xa1, 0xb1, 0x4b, 0x3f, 0x13, +- 0xde, 0x37, 0x12, 0x0a, 0xde, 0x37, 0x42, 0x1d, 0x67, 0x95, 0x09, 0xef, +- 0xeb, 0x19, 0x0d, 0x33, 0x7a, 0x83, 0xed, 0x96, 0x12, 0xc1, 0x8f, 0x32, +- 0x7e, 0x04, 0x7a, 0xa3, 0x38, 0x92, 0x31, 0xf1, 0xf4, 0x15, 0x38, 0xf0, +- 0xa5, 0x7f, 0x96, 0x8b, 0x63, 0x5f, 0x97, 0xd0, 0xd1, 0x6d, 0x5e, 0xb4, +- 0x63, 0x1a, 0xe2, 0xe5, 0xd1, 0x09, 0xef, 0x27, 0xbd, 0x50, 0xca, 0xa2, +- 0x46, 0x20, 0xab, 0xfc, 0x83, 0x1d, 0xf7, 0x4b, 0x31, 0xca, 0xe7, 0x60, +- 0x59, 0x94, 0x76, 0x47, 0x8c, 0x4a, 0x9d, 0xb7, 0x4b, 0x68, 0xb3, 0x05, +- 0xd1, 0x6b, 0x31, 0x32, 0x68, 0xe0, 0xe9, 0x84, 0x6d, 0x7f, 0x6c, 0x8e, +- 0x47, 0x7c, 0x30, 0xda, 0x3e, 0x42, 0x30, 0x36, 0x87, 0x7a, 0x39, 0x91, +- 0x31, 0x30, 0x9c, 0x88, 0xe2, 0xc5, 0x44, 0x8d, 0xb6, 0x19, 0x4d, 0x88, +- 0x05, 0x72, 0x31, 0x64, 0x94, 0x72, 0x0f, 0x85, 0xda, 0x50, 0x1e, 0x8d, +- 0xe0, 0x28, 0xe5, 0x3e, 0x37, 0x57, 0xda, 0x31, 0xf1, 0xfa, 0xbf, 0x42, +- 0x56, 0xe2, 0x3b, 0x9e, 0xa4, 0xac, 0x91, 0xa6, 0x8b, 0x36, 0xa6, 0x79, +- 0x71, 0xda, 0xbc, 0x86, 0x76, 0x08, 0xab, 0x28, 0xea, 0x75, 0xf7, 0x24, +- 0x34, 0x1c, 0xce, 0xf8, 0xdc, 0x9b, 0x13, 0x7e, 0x1c, 0xa0, 0xbf, 0xcd, +- 0x88, 0xc2, 0x0a, 0xb0, 0xdd, 0x19, 0xc4, 0xb5, 0xec, 0x60, 0x35, 0xc6, +- 0x06, 0x83, 0xe6, 0x1b, 0x4a, 0x00, 0x87, 0x86, 0xaf, 0xc5, 0xe8, 0xa0, +- 0x82, 0x91, 0x10, 0x65, 0xe7, 0xf5, 0xf7, 0x06, 0xaf, 0x47, 0x66, 0xd0, +- 0x85, 0x5d, 0x8e, 0x5e, 0x1d, 0x9c, 0x99, 0xfc, 0xbe, 0x16, 0xe9, 0x61, +- 0xb8, 0xe7, 0xf4, 0x6a, 0x78, 0x26, 0xe3, 0x76, 0x1b, 0xbd, 0x7e, 0x0c, +- 0x67, 0x7e, 0xca, 0x79, 0x93, 0xb6, 0x75, 0x0c, 0x25, 0x0e, 0x39, 0x73, +- 0x58, 0x1e, 0x65, 0x63, 0xb9, 0xf8, 0xca, 0x58, 0xa6, 0x33, 0xce, 0x34, +- 0x13, 0x87, 0xc4, 0xc7, 0xbd, 0xc4, 0x20, 0xf1, 0xf1, 0xb7, 0x14, 0x94, +- 0x35, 0x63, 0xf3, 0x58, 0xfe, 0xb9, 0x42, 0xfb, 0x77, 0x63, 0x9d, 0xd6, +- 0x80, 0x44, 0x4a, 0xec, 0x34, 0x8f, 0xcb, 0x72, 0x2d, 0xf3, 0x5f, 0x0c, +- 0xeb, 0x60, 0x31, 0x76, 0xd1, 0xc7, 0x76, 0xee, 0x96, 0xfb, 0xb6, 0xfd, +- 0x50, 0xb8, 0x9c, 0x36, 0x86, 0xc5, 0x45, 0x08, 0x99, 0x1f, 0x38, 0xb2, +- 0x59, 0x38, 0x94, 0x91, 0x18, 0xaa, 0x33, 0xbe, 0x9d, 0x60, 0x5f, 0xcd, +- 0xec, 0xc7, 0xc4, 0x4f, 0x39, 0x37, 0x7f, 0x3d, 0x56, 0x87, 0x1f, 0x8e, +- 0x19, 0xf8, 0xef, 0x63, 0x3a, 0x9e, 0xbf, 0x02, 0xd7, 0xef, 0xa6, 0xae, +- 0x04, 0xc3, 0x1a, 0xb0, 0x25, 0x55, 0x80, 0x6d, 0x83, 0xc5, 0xd8, 0x3c, +- 0x58, 0x53, 0xf7, 0x22, 0xf1, 0xf8, 0x87, 0xe6, 0x1d, 0x18, 0xaf, 0x6c, +- 0x76, 0x7c, 0x66, 0x07, 0xef, 0xef, 0x1c, 0xac, 0xe1, 0x1c, 0xda, 0xb6, +- 0x1a, 0xae, 0x8f, 0x1c, 0x25, 0xbe, 0x4f, 0xf8, 0x83, 0xfa, 0xb8, 0x1a, +- 0xd4, 0x63, 0xf0, 0x20, 0xd1, 0xa0, 0xc2, 0x9a, 0x1e, 0x4c, 0xd3, 0x8b, +- 0xe1, 0x37, 0x1e, 0xe2, 0xd8, 0x82, 0xba, 0xa5, 0x36, 0xd0, 0x7e, 0x19, +- 0x33, 0x54, 0x93, 0xf8, 0x52, 0x8c, 0x4f, 0x06, 0x83, 0x3d, 0x96, 0xba, +- 0x02, 0x56, 0xa5, 0x6d, 0x7f, 0x3f, 0x8c, 0x8e, 0x6b, 0xa2, 0x88, 0x4d, +- 0x67, 0x2c, 0xb8, 0x3e, 0x1a, 0x05, 0xe3, 0x18, 0xce, 0xf5, 0x1a, 0x81, +- 0xbf, 0x53, 0xee, 0xc6, 0x7f, 0x6c, 0x0b, 0xea, 0xba, 0x5a, 0x6f, 0x1d, +- 0x50, 0x49, 0x36, 0xaa, 0xa0, 0x07, 0xa2, 0xcb, 0xd0, 0xe9, 0xf0, 0x04, +- 0x05, 0x9a, 0x61, 0x62, 0x73, 0x8a, 0x95, 0xfc, 0x35, 0xed, 0xfd, 0x6a, +- 0xcd, 0x05, 0x53, 0x0d, 0x9e, 0x68, 0x53, 0x89, 0xb7, 0x4d, 0xe7, 0x6c, +- 0xbd, 0xca, 0xb6, 0x1b, 0x9b, 0xa4, 0x4f, 0x1d, 0x95, 0x9c, 0xe7, 0x0a, +- 0xce, 0x73, 0x63, 0xb6, 0x18, 0x67, 0x07, 0x61, 0x5d, 0x13, 0x0d, 0xb6, +- 0x3e, 0xa2, 0x16, 0xe3, 0xc3, 0xe1, 0x62, 0xbc, 0x33, 0xe8, 0xc6, 0x07, +- 0x83, 0xb6, 0xbd, 0xde, 0x2c, 0x47, 0x41, 0x18, 0xd3, 0x0b, 0x10, 0x3a, +- 0x3f, 0x04, 0x0b, 0x5f, 0xb0, 0xec, 0xef, 0x06, 0x03, 0xf8, 0xc7, 0xc1, +- 0xaf, 0xe2, 0xf9, 0xca, 0xd8, 0xc9, 0x69, 0x8c, 0x91, 0x17, 0x68, 0x3f, +- 0xe7, 0x12, 0xc1, 0xf6, 0x19, 0xae, 0x60, 0x27, 0x79, 0xcb, 0x86, 0xc7, +- 0x94, 0x60, 0xfc, 0x0d, 0x25, 0xa8, 0xf7, 0x2a, 0x7e, 0x7c, 0x44, 0x3b, +- 0x3d, 0x93, 0xa9, 0x89, 0xfc, 0x9c, 0xfd, 0xff, 0xde, 0xfc, 0xa1, 0x3d, +- 0x5e, 0x25, 0x3a, 0x14, 0x7d, 0x51, 0xe7, 0x29, 0xea, 0x9c, 0xfe, 0xfb, +- 0xc3, 0x14, 0x75, 0x4e, 0x79, 0x9e, 0xff, 0x83, 0xf8, 0x25, 0xf3, 0x15, +- 0xe1, 0x3c, 0x5e, 0x87, 0xff, 0xe2, 0x8c, 0xed, 0xa4, 0xfd, 0x9f, 0xfc, +- 0x32, 0xbe, 0xcf, 0xfd, 0x39, 0x0c, 0x92, 0x71, 0x9e, 0xb0, 0xe3, 0x9a, +- 0x8c, 0x51, 0xc6, 0xea, 0xe8, 0x52, 0xef, 0x50, 0x1e, 0x55, 0x51, 0x6c, +- 0xdb, 0x4f, 0x98, 0x93, 0xcf, 0xfd, 0xf9, 0xb1, 0x7e, 0x95, 0xf7, 0x65, +- 0xbc, 0x67, 0x5d, 0xa2, 0x7b, 0x5d, 0xbd, 0x89, 0xbf, 0x83, 0x56, 0x0c, +- 0xa7, 0x0b, 0xf9, 0xbb, 0x2e, 0x76, 0xe9, 0xf7, 0x93, 0xa5, 0x57, 0x3e, +- 0xa7, 0x9d, 0x3a, 0xfd, 0xdd, 0xcd, 0xdf, 0x32, 0x96, 0x37, 0x69, 0x37, +- 0x5f, 0x66, 0x27, 0x62, 0x23, 0x75, 0xb4, 0xa7, 0x33, 0x12, 0x57, 0x2c, +- 0x7f, 0xd4, 0x6b, 0xa9, 0x51, 0xe8, 0x74, 0x7d, 0xaf, 0x12, 0xed, 0x80, +- 0x9e, 0xb1, 0x70, 0x4f, 0xb3, 0x0b, 0xdf, 0x6a, 0x56, 0x30, 0xcd, 0xe8, +- 0x40, 0xdf, 0x3c, 0xcb, 0xae, 0x30, 0xf6, 0xab, 0xe2, 0x03, 0x05, 0x49, +- 0x58, 0xf4, 0x3b, 0x44, 0xc8, 0x95, 0xca, 0xff, 0x9d, 0x82, 0xd3, 0xe1, +- 0x10, 0x6d, 0x6e, 0x0b, 0x39, 0x15, 0x50, 0x98, 0x84, 0xb7, 0x94, 0xf3, +- 0x3f, 0xda, 0x0b, 0x6f, 0x31, 0x7d, 0x7f, 0x59, 0x6f, 0x4d, 0xc7, 0x7b, +- 0xc4, 0x8a, 0xac, 0x12, 0x6c, 0xa7, 0xbe, 0xcd, 0x32, 0x25, 0xd8, 0x7a, +- 0x3b, 0xf5, 0x5d, 0xab, 0x48, 0x3f, 0x51, 0xd4, 0x65, 0xb6, 0x10, 0x73, +- 0xe4, 0x3a, 0x02, 0x23, 0xf3, 0xab, 0x49, 0xd9, 0xe1, 0xf5, 0x50, 0x86, +- 0x83, 0x89, 0x77, 0xed, 0xb4, 0x16, 0xd4, 0xd3, 0xce, 0xef, 0x0d, 0xfc, +- 0x0d, 0x6f, 0x41, 0x74, 0x23, 0x5e, 0x4a, 0x3c, 0xe5, 0xcf, 0x97, 0xcb, +- 0xc9, 0x7a, 0xb5, 0x3c, 0xff, 0xd3, 0x8e, 0xf9, 0x73, 0xf2, 0xf8, 0x92, +- 0x5b, 0x40, 0x8e, 0xe2, 0x2d, 0x64, 0x5f, 0xef, 0x3b, 0xf5, 0x23, 0xac, +- 0x5f, 0xd3, 0xde, 0xab, 0x04, 0xeb, 0x3e, 0x42, 0xbd, 0xfe, 0x3d, 0x04, +- 0x5b, 0x8f, 0x92, 0x5b, 0x1a, 0x93, 0xf2, 0x84, 0x32, 0x0e, 0x9f, 0x71, +- 0xe4, 0x99, 0x95, 0x81, 0xe2, 0xea, 0x85, 0x6f, 0xa6, 0x51, 0x8b, 0x2e, +- 0x67, 0x4e, 0xa1, 0x04, 0x7a, 0x75, 0x94, 0x91, 0xbf, 0x04, 0x46, 0x81, +- 0xb1, 0x01, 0x72, 0xb9, 0x70, 0x0d, 0xbe, 0xc9, 0x58, 0x30, 0x83, 0x65, +- 0x1e, 0xd3, 0x2e, 0xe1, 0x97, 0xd2, 0x93, 0x20, 0xc0, 0x4c, 0xcf, 0xf1, +- 0xb2, 0xf8, 0xbd, 0x88, 0xc9, 0xbd, 0x27, 0x13, 0x50, 0x52, 0x89, 0xe0, +- 0x3e, 0xc0, 0x18, 0x0f, 0xbb, 0x62, 0x0f, 0x07, 0xd0, 0x85, 0x73, 0xe1, +- 0x50, 0x3c, 0xab, 0x84, 0xda, 0x07, 0x14, 0xd3, 0xbb, 0x8b, 0xfd, 0x6d, +- 0x67, 0x99, 0x1d, 0xfc, 0x9c, 0x35, 0x0c, 0x73, 0x85, 0x12, 0xbb, 0xa1, +- 0x80, 0x65, 0x6a, 0xc2, 0x21, 0xf2, 0xcc, 0xd0, 0x85, 0x95, 0x30, 0xbd, +- 0x4f, 0x65, 0xa4, 0xad, 0x88, 0xb2, 0x25, 0xfb, 0xa4, 0x9a, 0xc3, 0xa3, +- 0xdf, 0x4f, 0xea, 0xec, 0x1d, 0xf9, 0xed, 0xf4, 0xed, 0xee, 0xfd, 0xaf, +- 0x85, 0x7f, 0x78, 0xef, 0xaf, 0xa7, 0x5d, 0x79, 0xaf, 0x5e, 0x1b, 0xa6, +- 0xff, 0xb9, 0x8c, 0x22, 0xce, 0x9d, 0xf0, 0xa3, 0x58, 0x9d, 0x07, 0x72, +- 0xcf, 0x85, 0xb4, 0x3b, 0x16, 0x70, 0xe1, 0x73, 0x3b, 0xb6, 0x4a, 0xee, +- 0x15, 0x23, 0xde, 0x56, 0x1f, 0x70, 0xa3, 0x3e, 0xb2, 0x95, 0x58, 0x30, +- 0xb1, 0x6a, 0x21, 0x9f, 0x85, 0xcc, 0x17, 0x51, 0xa3, 0x6f, 0x85, 0x5c, +- 0x7f, 0x46, 0x9b, 0x5d, 0x28, 0x75, 0x59, 0x26, 0xc7, 0x7d, 0x04, 0x6b, +- 0xb6, 0x98, 0x36, 0x5e, 0x22, 0x4c, 0x14, 0x46, 0x8f, 0x28, 0xa7, 0x13, +- 0x5f, 0xd8, 0x31, 0x37, 0x96, 0xd3, 0x2f, 0x4d, 0xea, 0x59, 0xf7, 0x46, +- 0x43, 0xfa, 0x09, 0x66, 0x0a, 0xae, 0xa8, 0xa5, 0x4c, 0x64, 0xb6, 0x28, +- 0xef, 0x66, 0x7a, 0x94, 0x33, 0x19, 0xa9, 0x7b, 0x44, 0x79, 0x27, 0x23, +- 0xf1, 0xb0, 0x5a, 0x3f, 0x4e, 0x7e, 0x43, 0x4e, 0xa5, 0x6e, 0x36, 0xa1, +- 0x6c, 0x33, 0xcb, 0xc8, 0xf3, 0x8d, 0xba, 0x21, 0xca, 0x7b, 0xb0, 0x19, +- 0xe6, 0x76, 0xd3, 0x83, 0x09, 0x0d, 0xbe, 0xcd, 0xa6, 0x5b, 0x7e, 0x33, +- 0x1f, 0x90, 0xba, 0xd5, 0xfa, 0xd6, 0xcc, 0x45, 0xfa, 0x57, 0xee, 0xf7, +- 0xc1, 0xe6, 0xfc, 0xbd, 0xdf, 0xda, 0xe3, 0xab, 0x54, 0xfe, 0xfe, 0x77, +- 0x2e, 0x0e, 0x85, 0x75, 0xa7, 0xf2, 0x73, 0xe1, 0x52, 0x2a, 0xf9, 0x63, +- 0x05, 0x2c, 0x2d, 0x68, 0xa5, 0x99, 0x0e, 0x6d, 0x4e, 0x35, 0xd2, 0xdf, +- 0x02, 0x8c, 0x95, 0x51, 0xe2, 0x3b, 0x79, 0x2f, 0xfb, 0x2c, 0x30, 0x7c, +- 0x58, 0x9c, 0xa8, 0x71, 0xe5, 0xf4, 0xa7, 0x12, 0xc3, 0x5c, 0x8c, 0xe9, +- 0xc2, 0xf1, 0xae, 0xe6, 0xdc, 0xd5, 0xfa, 0x07, 0x94, 0xbb, 0xc8, 0x30, +- 0xea, 0x8a, 0x94, 0x6a, 0xfd, 0xdd, 0x4c, 0x94, 0x3e, 0xde, 0xce, 0x7e, +- 0x7d, 0x78, 0x37, 0x51, 0xc6, 0x1c, 0x24, 0x18, 0xb3, 0xd8, 0xe0, 0x92, +- 0xe6, 0x00, 0xc8, 0xf9, 0xa6, 0xfc, 0xb5, 0x81, 0xf1, 0x5f, 0x62, 0xb4, +- 0x7a, 0xdb, 0xdc, 0x08, 0x36, 0x64, 0xe0, 0x5e, 0xd7, 0x1c, 0xc5, 0x7a, +- 0xc6, 0xf6, 0x87, 0x18, 0x2f, 0x37, 0x32, 0x16, 0xee, 0x0a, 0x73, 0x6c, +- 0x15, 0xb6, 0x5d, 0x68, 0x74, 0x49, 0x3e, 0x83, 0x5e, 0xc6, 0xe2, 0xb5, +- 0x8c, 0x2f, 0x5b, 0x78, 0x7d, 0x2a, 0xf3, 0xcf, 0xf6, 0x43, 0xcc, 0xa7, +- 0x5e, 0xba, 0xa2, 0x4d, 0xa8, 0xc3, 0x46, 0x7d, 0xdd, 0x56, 0xc6, 0x62, +- 0xb6, 0x6b, 0x95, 0x45, 0x6d, 0xfb, 0x86, 0x50, 0x30, 0xe6, 0x51, 0x4c, +- 0xbc, 0x38, 0x3a, 0x61, 0xeb, 0xd3, 0x25, 0x97, 0xca, 0xc7, 0x41, 0x19, +- 0xab, 0xe4, 0x08, 0x82, 0x0f, 0x92, 0x27, 0x4c, 0xc5, 0x08, 0x15, 0x4b, +- 0x06, 0x25, 0x4f, 0x08, 0x60, 0x65, 0xe2, 0xbb, 0x78, 0xb1, 0xc1, 0x8d, +- 0x56, 0xe6, 0x58, 0xb7, 0x25, 0x7c, 0x58, 0x41, 0x2c, 0x5d, 0x9a, 0x60, +- 0xee, 0xa4, 0xf9, 0xb1, 0x2c, 0xe1, 0xc6, 0xb1, 0x06, 0xe6, 0x40, 0xfe, +- 0x42, 0x7c, 0x64, 0xba, 0x70, 0xdc, 0xd4, 0x90, 0x76, 0xfc, 0x61, 0x17, +- 0x31, 0x90, 0x7a, 0x54, 0x25, 0x77, 0x10, 0x1d, 0xba, 0xa8, 0x4f, 0x15, +- 0xf1, 0x4b, 0x3a, 0xfc, 0xb2, 0x5c, 0x40, 0xe4, 0x92, 0x7c, 0xe0, 0x37, +- 0x76, 0x7c, 0xba, 0xd4, 0x87, 0xe5, 0x8b, 0xca, 0x38, 0x84, 0xdf, 0x12, +- 0x27, 0x47, 0x4d, 0x72, 0xbb, 0xa9, 0x43, 0x3d, 0x4f, 0x6e, 0x5d, 0x8e, +- 0xb7, 0x0c, 0xe1, 0xd6, 0x6f, 0x42, 0xa3, 0xef, 0xf6, 0x8c, 0x86, 0x3a, +- 0xce, 0x2b, 0x2e, 0x9c, 0x32, 0xca, 0xc8, 0xfb, 0x38, 0x0f, 0xa3, 0x70, +- 0x6f, 0x9d, 0x6b, 0x22, 0x39, 0xda, 0x1d, 0x29, 0xe5, 0x78, 0xdd, 0x73, +- 0x73, 0x9c, 0xe8, 0xeb, 0xd4, 0xed, 0x9a, 0xb0, 0xc3, 0x89, 0x72, 0x7c, +- 0x40, 0xb3, 0xed, 0x77, 0x0c, 0xd1, 0x33, 0x70, 0x78, 0x52, 0xc7, 0x07, +- 0x79, 0xdd, 0x33, 0xa9, 0xe3, 0x2d, 0x6c, 0x8f, 0xfe, 0x87, 0x6d, 0x57, +- 0xf0, 0x18, 0x1d, 0xcc, 0x29, 0xc9, 0x6f, 0x88, 0xc3, 0xc4, 0x95, 0x18, +- 0x75, 0xfc, 0x72, 0x66, 0x83, 0xe0, 0x36, 0xa7, 0xbb, 0xd1, 0xc1, 0xef, +- 0x98, 0x7a, 0x98, 0x76, 0x20, 0x7a, 0x78, 0x6b, 0x32, 0xb7, 0xb1, 0xed, +- 0x01, 0x53, 0x74, 0x9c, 0xcf, 0xcb, 0x44, 0xd7, 0x37, 0x4a, 0x8e, 0xd5, +- 0x03, 0x7c, 0xc1, 0xb2, 0x2e, 0xe2, 0xee, 0x42, 0xfc, 0xa0, 0x4d, 0x6c, +- 0xa7, 0xd4, 0x89, 0x95, 0xf3, 0x6b, 0x6d, 0x3b, 0xdc, 0xa4, 0xe3, 0x82, +- 0x51, 0x1f, 0x69, 0x54, 0x67, 0x51, 0xd6, 0x28, 0xf6, 0x91, 0x0f, 0x74, +- 0xa7, 0x66, 0x22, 0xe6, 0x17, 0x5b, 0x43, 0x47, 0x41, 0x0e, 0xc3, 0x71, +- 0x26, 0x61, 0xd4, 0x6d, 0xc3, 0x0c, 0x1c, 0xf0, 0xb7, 0x90, 0xc7, 0xa9, +- 0x2d, 0x4c, 0xff, 0xc9, 0x9f, 0x0c, 0x6b, 0x07, 0xce, 0xda, 0x69, 0xbf, +- 0xcd, 0x38, 0x49, 0x18, 0xa0, 0x2e, 0x5f, 0xd1, 0x5c, 0x78, 0xb5, 0xee, +- 0x9a, 0x49, 0xbe, 0x29, 0x9c, 0xe5, 0x3d, 0xfb, 0x98, 0x5f, 0xfa, 0x62, +- 0x9e, 0xa7, 0x2e, 0x73, 0x49, 0x1e, 0xe8, 0x36, 0xa4, 0x6d, 0xe6, 0x0b, +- 0x63, 0x57, 0xcb, 0x30, 0x61, 0x4f, 0xf8, 0x45, 0x86, 0xa0, 0xa6, 0xab, +- 0x7f, 0x6c, 0x1e, 0xaf, 0xc3, 0xcf, 0x35, 0x37, 0x7c, 0xe4, 0xc5, 0xaf, +- 0xf9, 0x73, 0x6d, 0xf4, 0x9a, 0xe3, 0x33, 0x4a, 0x1d, 0xac, 0x3c, 0xa2, +- 0x24, 0x89, 0x0f, 0xe3, 0x1e, 0x68, 0xe5, 0x51, 0xb7, 0xae, 0x11, 0x13, +- 0x36, 0x13, 0x13, 0x2c, 0x62, 0x42, 0x5f, 0xe6, 0x88, 0x92, 0xca, 0x7c, +- 0x46, 0x5d, 0x48, 0x1d, 0xb1, 0x9d, 0x2d, 0x94, 0xe5, 0x27, 0x36, 0xaa, +- 0x44, 0x9e, 0x0b, 0xbc, 0xdf, 0x42, 0x1e, 0x92, 0x97, 0x53, 0x7c, 0x95, +- 0x10, 0x54, 0x2c, 0xcf, 0x52, 0xb9, 0xdf, 0xaa, 0x5c, 0xcf, 0x70, 0x4b, +- 0xb9, 0xee, 0xb1, 0xa3, 0x4b, 0xdd, 0x58, 0x80, 0xd9, 0xe1, 0x85, 0x8b, +- 0x44, 0x17, 0x6a, 0x34, 0xa6, 0x7b, 0x61, 0x55, 0xb9, 0x88, 0xe5, 0xef, +- 0x35, 0x34, 0x60, 0x11, 0x73, 0xce, 0xb3, 0x04, 0xa7, 0x6e, 0xc3, 0x85, +- 0x71, 0xea, 0xe7, 0x69, 0x53, 0xd6, 0x1b, 0x6c, 0xdc, 0x16, 0xb6, 0xe2, +- 0xf4, 0x78, 0xab, 0x94, 0xb6, 0x57, 0x6c, 0x08, 0x4f, 0x28, 0x43, 0x49, +- 0xd4, 0x5d, 0x77, 0x16, 0x41, 0x73, 0x17, 0x79, 0x92, 0x5e, 0x31, 0x3b, +- 0xe2, 0xa1, 0xe6, 0x5e, 0x4f, 0x84, 0x22, 0xc7, 0x95, 0x9c, 0x3f, 0xbd, +- 0x4c, 0xdb, 0x78, 0x2b, 0x61, 0x74, 0x16, 0xba, 0x72, 0xbf, 0xdf, 0x70, +- 0xf2, 0xd9, 0xbc, 0x3f, 0x05, 0x26, 0x71, 0xc7, 0xeb, 0x3d, 0x93, 0xc0, +- 0x79, 0xb5, 0x59, 0xf2, 0x5a, 0x9c, 0xdf, 0x6c, 0x8e, 0x2b, 0x1e, 0xa3, +- 0x8c, 0xfa, 0x10, 0x2c, 0x2e, 0x20, 0xa7, 0x14, 0xee, 0xe0, 0xf5, 0x9e, +- 0x65, 0x19, 0x72, 0xc2, 0x89, 0xba, 0xf9, 0xf5, 0x11, 0x2f, 0x62, 0x56, +- 0x21, 0xfd, 0xba, 0x34, 0xea, 0xf7, 0xde, 0x98, 0xb5, 0xaa, 0x7c, 0xf4, +- 0x8b, 0x12, 0xe6, 0xbb, 0xb3, 0x93, 0x0b, 0xcb, 0x24, 0x57, 0xdc, 0x38, +- 0xca, 0x91, 0x55, 0xf6, 0x57, 0xa9, 0x51, 0x59, 0xc3, 0xd0, 0xe0, 0xa9, +- 0xdc, 0x78, 0x8b, 0x1a, 0x9d, 0x40, 0x7b, 0xb3, 0xb7, 0x25, 0x92, 0x85, +- 0xb7, 0x22, 0xba, 0x09, 0xe1, 0xa4, 0xe4, 0xad, 0x82, 0xb1, 0xb1, 0xad, +- 0x44, 0xbd, 0xaa, 0xf2, 0x79, 0xf9, 0xb9, 0x82, 0x5a, 0x16, 0x95, 0xfc, +- 0x55, 0x6f, 0x79, 0xc3, 0xc1, 0x62, 0x8d, 0xf9, 0xc6, 0xaf, 0x02, 0xff, +- 0x77, 0xf5, 0x5b, 0xdd, 0x32, 0x77, 0x1e, 0x43, 0xbe, 0x65, 0xdd, 0x00, +- 0x6e, 0x95, 0x58, 0xda, 0x3d, 0xe2, 0x66, 0x7e, 0x26, 0xf3, 0x25, 0xf1, +- 0xf8, 0xc8, 0xbd, 0x2f, 0xd1, 0xdf, 0x3c, 0xd4, 0xfd, 0x0e, 0xc3, 0x62, +- 0x98, 0xb0, 0x6d, 0x23, 0x1c, 0x0c, 0x14, 0x28, 0x3a, 0xb6, 0x37, 0xfc, +- 0x13, 0xed, 0x0b, 0xc4, 0x41, 0x90, 0x98, 0x97, 0x61, 0xcb, 0x48, 0xc1, +- 0x94, 0x7a, 0x91, 0xfb, 0xf2, 0xf5, 0x7a, 0x0d, 0x2b, 0x2e, 0xf5, 0x86, +- 0xc3, 0xc1, 0xf6, 0x6d, 0xac, 0xb7, 0x93, 0xf5, 0x62, 0x8c, 0xbd, 0xeb, +- 0x47, 0x35, 0x27, 0x1f, 0xb4, 0x46, 0x8a, 0xa7, 0xf6, 0x77, 0xa9, 0xde, +- 0x93, 0x86, 0x35, 0xee, 0xf4, 0xd7, 0x14, 0xec, 0x2c, 0x70, 0xb9, 0x91, +- 0x64, 0xbd, 0x71, 0xd6, 0x7b, 0x77, 0x54, 0xd6, 0x33, 0x70, 0xcb, 0x48, +- 0x22, 0x35, 0xe1, 0x32, 0x0c, 0xed, 0x1d, 0xc4, 0x88, 0xd9, 0xce, 0x5c, +- 0xde, 0x72, 0x28, 0xd3, 0x85, 0xed, 0xc6, 0xd1, 0x70, 0x21, 0xeb, 0x1d, +- 0x37, 0x8e, 0x06, 0x3c, 0xf4, 0x99, 0x75, 0x6c, 0xaf, 0x9b, 0x79, 0x91, +- 0x4a, 0x8c, 0xdc, 0x32, 0x22, 0xdc, 0xc1, 0xc4, 0x6c, 0xe6, 0x67, 0x8e, +- 0x6d, 0xca, 0xda, 0x09, 0x64, 0x4e, 0x65, 0x7c, 0xc1, 0xba, 0x11, 0x67, +- 0x7c, 0xca, 0x35, 0x87, 0x25, 0x57, 0xae, 0xb0, 0xb0, 0xb9, 0x41, 0xe2, +- 0xa7, 0x42, 0xec, 0x0e, 0xd6, 0x8d, 0x33, 0x9e, 0x6c, 0x1b, 0xfb, 0x33, +- 0x8c, 0x6b, 0x95, 0xcc, 0x65, 0x6d, 0xfb, 0x15, 0x63, 0x61, 0x05, 0x43, +- 0xbc, 0xd7, 0x4b, 0x99, 0xbd, 0xa1, 0x62, 0x89, 0xd3, 0x4e, 0x5b, 0x31, +- 0x08, 0x3e, 0x29, 0x48, 0x1a, 0xd6, 0x06, 0x91, 0xff, 0x58, 0x38, 0x18, +- 0x3f, 0xac, 0xd4, 0xb7, 0x6f, 0xc3, 0x3f, 0x11, 0x2f, 0x41, 0xac, 0x9b, +- 0x89, 0x21, 0x93, 0xd6, 0xd2, 0x66, 0x31, 0x42, 0x4a, 0x8c, 0x77, 0x9f, +- 0x58, 0xc4, 0x08, 0xe7, 0x46, 0xb0, 0xb3, 0x95, 0xe5, 0x23, 0xb9, 0x75, +- 0x16, 0x5c, 0x18, 0x0d, 0x32, 0x0e, 0x8b, 0x2e, 0x80, 0xad, 0x99, 0x7c, +- 0x2c, 0xb0, 0xed, 0x83, 0xa6, 0x6d, 0xbf, 0x64, 0xce, 0xc4, 0x61, 0x33, +- 0x18, 0x17, 0x1f, 0x78, 0xdf, 0x5c, 0x78, 0x83, 0xe4, 0xc5, 0x80, 0xc8, +- 0xa6, 0x30, 0x76, 0x29, 0x28, 0xe1, 0x27, 0x10, 0x72, 0xeb, 0x25, 0x8a, +- 0x0d, 0x6f, 0x53, 0x6d, 0x67, 0x2d, 0xf5, 0x5e, 0x36, 0x5f, 0xc1, 0x27, +- 0x37, 0x2a, 0x38, 0x7a, 0x63, 0x28, 0x30, 0xa4, 0x94, 0x32, 0x2e, 0x84, +- 0xda, 0x5a, 0x14, 0xeb, 0x04, 0xeb, 0xc6, 0x1a, 0x5c, 0xc1, 0x00, 0x94, +- 0x72, 0x62, 0xd6, 0x6c, 0x5d, 0x68, 0x8b, 0xbb, 0x37, 0x14, 0xd8, 0xc9, +- 0x6f, 0xd7, 0xa8, 0x82, 0x51, 0x23, 0x18, 0x83, 0xd3, 0x3e, 0xfb, 0x66, +- 0xca, 0x7c, 0x53, 0xc8, 0xb6, 0x4f, 0x86, 0xeb, 0xb5, 0x93, 0x78, 0x9f, +- 0xb8, 0x2c, 0xfd, 0xe4, 0x65, 0x03, 0xf3, 0x70, 0x23, 0xd6, 0xa2, 0xdc, +- 0x24, 0xb4, 0x84, 0x71, 0x52, 0x62, 0x79, 0x5e, 0xde, 0x7c, 0x4c, 0xb7, +- 0xed, 0xf7, 0xcd, 0x5c, 0x5b, 0x5a, 0x73, 0x30, 0x0e, 0xcc, 0xc4, 0x98, +- 0x11, 0x6c, 0x1d, 0xa7, 0x1e, 0x02, 0xf4, 0xf5, 0x19, 0x46, 0x15, 0x26, +- 0x3c, 0x41, 0x6d, 0x42, 0x59, 0xf4, 0x99, 0x8a, 0x39, 0x1b, 0x9e, 0x52, +- 0xea, 0x3b, 0x8a, 0x60, 0x90, 0x9f, 0x5e, 0x23, 0xf3, 0x11, 0xf0, 0x91, +- 0x0b, 0xae, 0x83, 0xc3, 0x2f, 0x70, 0x7b, 0xc2, 0x1d, 0xbb, 0x80, 0x1a, +- 0xfa, 0x9d, 0xd1, 0xfe, 0x90, 0x12, 0x64, 0xf2, 0xf2, 0x35, 0x26, 0x38, +- 0x22, 0x6b, 0x15, 0xe2, 0xf7, 0xd8, 0xf6, 0xc3, 0x94, 0x75, 0x17, 0x65, +- 0xdd, 0x18, 0xfe, 0xd8, 0xfe, 0x07, 0xa7, 0xcd, 0x5b, 0x31, 0x64, 0x5c, +- 0xdd, 0xee, 0x47, 0x36, 0xa6, 0x4b, 0xbb, 0x1e, 0x2c, 0x99, 0xce, 0x5c, +- 0xab, 0x59, 0xf0, 0xaa, 0xd2, 0x43, 0x7c, 0x62, 0x7b, 0x8c, 0x7f, 0xea, +- 0xd5, 0x1c, 0xc2, 0x05, 0xc6, 0xe6, 0x40, 0x5c, 0x51, 0xab, 0x4b, 0xa0, +- 0xc1, 0x6b, 0xd8, 0x78, 0x84, 0x7c, 0x27, 0x36, 0xbd, 0x1c, 0xdf, 0xe4, +- 0x9c, 0x96, 0x86, 0xd4, 0x6b, 0x5d, 0x9c, 0x93, 0xc3, 0x61, 0xf9, 0xed, +- 0xc1, 0xf8, 0x74, 0x17, 0xba, 0x38, 0xcb, 0x5a, 0x48, 0x9d, 0x21, 0xf7, +- 0xbd, 0x8d, 0xf2, 0x9b, 0xf2, 0x5f, 0xa3, 0xe0, 0x61, 0x5a, 0xa4, 0x1a, +- 0xea, 0x0e, 0xc8, 0xfd, 0x56, 0x53, 0x7e, 0x2b, 0xe4, 0x92, 0x6e, 0xce, +- 0x8b, 0x0d, 0x97, 0x2c, 0x4d, 0x84, 0x78, 0x3f, 0x2c, 0xd7, 0xb1, 0x87, +- 0x39, 0xee, 0xd8, 0x01, 0x45, 0x30, 0xee, 0x97, 0xf6, 0x2b, 0x8c, 0x81, +- 0x1a, 0x9f, 0x7f, 0x93, 0x7d, 0x9f, 0x08, 0xbf, 0x64, 0xcf, 0xa8, 0x50, +- 0x70, 0x32, 0xa2, 0x63, 0xe6, 0x8d, 0xd5, 0x98, 0xb8, 0x5b, 0xc6, 0xac, +- 0xa0, 0xd4, 0x38, 0xe8, 0x91, 0x1c, 0xb9, 0xcc, 0xb8, 0x06, 0x4b, 0x56, +- 0xe4, 0xee, 0x15, 0x85, 0x64, 0x8d, 0x53, 0x47, 0xd1, 0x8d, 0x95, 0xd0, +- 0x27, 0xef, 0x2d, 0x0a, 0xb9, 0xdb, 0x4a, 0x15, 0x43, 0xbb, 0x5d, 0x91, +- 0xe7, 0xbf, 0x23, 0x2f, 0xb7, 0xed, 0x47, 0x38, 0x5f, 0xb3, 0xc3, 0x3e, +- 0x9c, 0x63, 0x3f, 0xdd, 0xd4, 0xdf, 0xf2, 0x4b, 0xf3, 0x95, 0xaf, 0xff, +- 0xa9, 0xad, 0xdf, 0x23, 0x75, 0xa5, 0x8d, 0xda, 0xd6, 0x25, 0xca, 0x03, +- 0x1e, 0xc9, 0x91, 0x36, 0x86, 0x1d, 0x9d, 0xb1, 0xec, 0x73, 0xce, 0x6f, +- 0xad, 0xf9, 0xad, 0x4b, 0xeb, 0x75, 0xe7, 0x9d, 0x58, 0xba, 0x70, 0xbe, +- 0x86, 0x09, 0xbb, 0xa2, 0xd1, 0xd2, 0x0a, 0x21, 0x31, 0xb5, 0xa6, 0xee, +- 0x39, 0xb6, 0xfb, 0x73, 0x33, 0x17, 0x6f, 0x0f, 0x9a, 0xc1, 0x3e, 0x8b, +- 0xfe, 0x13, 0x67, 0x8e, 0xdb, 0x22, 0xbc, 0x63, 0xec, 0x16, 0xce, 0xc3, +- 0x4c, 0x14, 0x36, 0x06, 0x7b, 0x66, 0x31, 0xe7, 0x73, 0x35, 0x4b, 0x9c, +- 0x96, 0xf9, 0x71, 0xca, 0xb0, 0xaf, 0x22, 0x2c, 0xa2, 0x8c, 0xe1, 0xc6, +- 0x3f, 0x15, 0xdf, 0xa4, 0x1d, 0xb1, 0xce, 0x60, 0x4f, 0x0c, 0x7f, 0xaa, +- 0x2c, 0xc8, 0x28, 0x64, 0x2d, 0xcc, 0x7b, 0x4b, 0x3c, 0xa3, 0x92, 0x23, +- 0x15, 0x68, 0xdd, 0xcd, 0x55, 0xfc, 0xc8, 0x73, 0xf7, 0x2d, 0x6b, 0x32, +- 0x97, 0xd6, 0x20, 0xd1, 0x67, 0x16, 0x40, 0xbd, 0x49, 0xe2, 0x05, 0x7d, +- 0x59, 0x93, 0xf1, 0x59, 0xb4, 0x72, 0x59, 0x5f, 0x30, 0x56, 0xad, 0x25, +- 0x5e, 0xbc, 0xc8, 0x1e, 0x87, 0xc9, 0xc5, 0x2c, 0xc7, 0x33, 0x9c, 0xf8, +- 0x37, 0x65, 0x4d, 0x52, 0xe2, 0x57, 0x7e, 0x5d, 0xb3, 0x12, 0xfd, 0x7b, +- 0x57, 0x40, 0xaf, 0xca, 0x61, 0xa0, 0x1a, 0x6d, 0xc2, 0xc2, 0xbe, 0x40, +- 0x41, 0x2e, 0x7f, 0x28, 0x43, 0xef, 0xde, 0x30, 0xd2, 0xd3, 0x9d, 0xfa, +- 0xbc, 0xe7, 0x85, 0x60, 0xf4, 0xf6, 0xbd, 0xd7, 0xca, 0x7a, 0x40, 0x40, +- 0xda, 0x8d, 0xd3, 0x77, 0x54, 0xe3, 0x43, 0xdb, 0xd2, 0xa4, 0xfd, 0xa3, +- 0x37, 0x10, 0x47, 0xcc, 0xc5, 0xa8, 0x6f, 0x3f, 0x84, 0x33, 0xe4, 0xa4, +- 0x4e, 0xbe, 0xa4, 0x17, 0x46, 0xc7, 0x1f, 0xf6, 0x20, 0x14, 0x1f, 0x21, +- 0x0e, 0xf8, 0x46, 0xbd, 0xe4, 0x56, 0x33, 0x9d, 0x75, 0xaf, 0x85, 0xc4, +- 0x96, 0x38, 0x79, 0xf9, 0xd7, 0xdc, 0x6e, 0xac, 0x25, 0x66, 0x1c, 0x34, +- 0xea, 0x3b, 0x0e, 0xe1, 0x1f, 0x89, 0xb3, 0x52, 0x5e, 0x65, 0x7f, 0xd2, +- 0xa6, 0x9b, 0xfd, 0xc1, 0x4b, 0x2e, 0x70, 0x2f, 0xf9, 0xac, 0xdb, 0x63, +- 0xfc, 0xc4, 0x23, 0xbc, 0x43, 0x78, 0xf7, 0xae, 0xbd, 0x0a, 0x5a, 0xd8, +- 0xce, 0x4e, 0xda, 0xcc, 0xc3, 0x21, 0xb8, 0x5b, 0x6f, 0x24, 0xbf, 0x02, +- 0x5d, 0x70, 0xba, 0x0f, 0x3b, 0x46, 0x10, 0xc9, 0x18, 0xe3, 0x33, 0x7c, +- 0xa8, 0x62, 0x3b, 0x12, 0x53, 0x0a, 0x26, 0xdb, 0x89, 0xdc, 0x77, 0x65, +- 0x3b, 0x65, 0x78, 0x72, 0xb2, 0x9d, 0x7d, 0x6c, 0xe7, 0xe6, 0xd9, 0x70, +- 0x97, 0xdd, 0x2c, 0x73, 0xd5, 0x40, 0xff, 0x29, 0x43, 0xca, 0x89, 0x2b, +- 0xe4, 0xa3, 0x5f, 0x85, 0x62, 0xd4, 0x4a, 0xee, 0x72, 0xd6, 0xa9, 0xb7, +- 0xb8, 0x61, 0xfc, 0x02, 0x69, 0x91, 0x72, 0x7e, 0xf6, 0x38, 0x1d, 0x35, +- 0xaf, 0x9b, 0x2a, 0x6c, 0xdd, 0x5b, 0x9c, 0x97, 0x97, 0xfd, 0xe4, 0xfb, +- 0xa8, 0xe4, 0x3d, 0x3f, 0x76, 0x30, 0x07, 0x5d, 0xcc, 0x7e, 0x0e, 0x9b, +- 0xc2, 0x23, 0xeb, 0xcd, 0x22, 0x45, 0x72, 0xf2, 0x00, 0x39, 0x45, 0x25, +- 0x36, 0x3b, 0x71, 0x28, 0xc0, 0xfa, 0x0d, 0x65, 0x39, 0x7e, 0x02, 0xcf, +- 0x32, 0x96, 0x6d, 0x09, 0xe7, 0xfa, 0x23, 0x0e, 0x33, 0xcf, 0x6d, 0xc4, +- 0xc1, 0xc1, 0x4b, 0xcf, 0x83, 0x8b, 0x8d, 0xa9, 0xf3, 0x35, 0x1e, 0xf4, +- 0xa0, 0x8d, 0xdf, 0x05, 0x12, 0x67, 0xae, 0x18, 0xfb, 0x96, 0x91, 0x47, +- 0xf8, 0x5d, 0x8c, 0xad, 0x23, 0x36, 0xb6, 0x38, 0x39, 0x4e, 0x01, 0xba, +- 0x1b, 0x04, 0x0f, 0xc5, 0x96, 0xa6, 0x4b, 0xec, 0x88, 0xa4, 0x21, 0xf1, +- 0x55, 0xec, 0x27, 0xea, 0xd8, 0x8f, 0x4b, 0x99, 0x6a, 0x3f, 0x5d, 0x78, +- 0xcd, 0x38, 0xba, 0xa2, 0x10, 0x47, 0xef, 0x97, 0xb5, 0xfb, 0x8e, 0x30, +- 0x8e, 0xdd, 0x46, 0xdf, 0x7c, 0x97, 0xd8, 0xb2, 0x65, 0x36, 0xe3, 0x97, +- 0x83, 0x59, 0x0a, 0x0a, 0xc9, 0x2b, 0xb6, 0xed, 0x0d, 0xea, 0x05, 0xaa, +- 0xc6, 0x3e, 0xaf, 0xc6, 0x2e, 0x91, 0xdf, 0x64, 0x9e, 0x7e, 0xf4, 0xb1, +- 0x42, 0xf8, 0x24, 0x5f, 0x7a, 0xfb, 0x0c, 0xdb, 0x58, 0x6c, 0xe6, 0x75, +- 0xe5, 0xe8, 0x69, 0xb2, 0x9d, 0x4a, 0x24, 0xf7, 0xe6, 0xeb, 0x2b, 0x38, +- 0x15, 0x0a, 0x4c, 0xae, 0x9d, 0x57, 0xa2, 0x77, 0xe4, 0xe8, 0x49, 0xf2, +- 0x1c, 0xc6, 0xa9, 0xa3, 0x9d, 0x01, 0xca, 0x72, 0x3e, 0x9c, 0x9f, 0x53, +- 0xf1, 0xcd, 0xa9, 0x6d, 0x88, 0xed, 0x42, 0x29, 0xab, 0xc5, 0x96, 0x32, +- 0xda, 0x68, 0x26, 0x84, 0x78, 0x49, 0xb4, 0x0c, 0x89, 0x11, 0xfa, 0xd6, +- 0x68, 0x01, 0xdc, 0xf3, 0x24, 0xee, 0x0a, 0xd7, 0x72, 0xdf, 0x72, 0x3a, +- 0x51, 0x80, 0x07, 0xcc, 0x8b, 0xb6, 0xe0, 0xe2, 0x49, 0x03, 0xd7, 0x15, +- 0x10, 0x13, 0x6b, 0xc3, 0xa1, 0xd8, 0x3a, 0xe6, 0xb4, 0xc7, 0x1b, 0xdc, +- 0xb7, 0x7c, 0x90, 0xf9, 0x3d, 0x79, 0xf1, 0xd5, 0xe3, 0x11, 0x7d, 0xe0, +- 0xc4, 0xd2, 0x90, 0xf4, 0x29, 0xfd, 0xe5, 0x6d, 0x54, 0xfa, 0xb7, 0xed, +- 0x50, 0xd8, 0xe7, 0xcc, 0x79, 0x7e, 0x0c, 0xef, 0x19, 0xf9, 0x31, 0xf8, +- 0x9c, 0xf8, 0xcd, 0x1c, 0x98, 0x98, 0x23, 0x79, 0xc1, 0x11, 0xe5, 0xa8, +- 0x93, 0x03, 0x5b, 0x31, 0xe6, 0xbe, 0x91, 0x9e, 0xc9, 0xdc, 0x77, 0x9c, +- 0x3c, 0xf7, 0x38, 0x79, 0xee, 0xcb, 0x93, 0xb9, 0xef, 0x8b, 0x19, 0xa9, +- 0x33, 0xb5, 0x7c, 0x24, 0x26, 0x6b, 0xd6, 0x23, 0x89, 0x50, 0x5d, 0xbe, +- 0xce, 0xcb, 0x2c, 0x7f, 0xfc, 0x52, 0xf9, 0xd5, 0xcc, 0x57, 0x57, 0x61, +- 0x5b, 0xaa, 0x04, 0x0f, 0x6a, 0x4e, 0x6e, 0xe9, 0x2d, 0x8c, 0x9e, 0xb8, +- 0xef, 0x7d, 0x63, 0xbc, 0xce, 0x45, 0x1c, 0x1a, 0xe1, 0xe0, 0x5b, 0x12, +- 0x0a, 0xfd, 0xce, 0x83, 0x1e, 0xad, 0x1c, 0x6b, 0xcd, 0x7f, 0xb2, 0x1f, +- 0x5c, 0x25, 0xcf, 0xf2, 0x7b, 0x14, 0x52, 0xfe, 0x35, 0x96, 0x0f, 0x9a, +- 0x23, 0x93, 0xb9, 0xe0, 0xd1, 0x04, 0xfa, 0x24, 0xcf, 0x5a, 0xd3, 0x1c, +- 0xd2, 0xbb, 0x9d, 0x75, 0x63, 0x1d, 0xeb, 0x32, 0x3a, 0xd6, 0x53, 0x9e, +- 0xb4, 0x7b, 0x32, 0x47, 0xca, 0xc5, 0x62, 0x4b, 0x78, 0xe6, 0x22, 0x96, +- 0xdb, 0x3c, 0x89, 0x33, 0x2d, 0x97, 0x78, 0xae, 0x6d, 0xf7, 0x9b, 0x79, +- 0xae, 0xcb, 0x58, 0x50, 0x29, 0xb9, 0x35, 0x68, 0x17, 0x15, 0x48, 0xfb, +- 0x65, 0x4f, 0x66, 0xea, 0x18, 0x11, 0x2b, 0x8c, 0x86, 0xf4, 0xd9, 0xea, +- 0x54, 0xec, 0x92, 0xb1, 0x0a, 0x6e, 0x59, 0x8e, 0x7e, 0x8e, 0x5d, 0x1a, +- 0x6f, 0x7d, 0xa1, 0x60, 0xd6, 0xc1, 0x44, 0x77, 0x01, 0x6d, 0x4b, 0x2d, +- 0x10, 0x7b, 0x40, 0xee, 0x1e, 0xb2, 0xb6, 0xbd, 0xfd, 0x0a, 0xdd, 0x15, +- 0xc4, 0x98, 0x0a, 0xe0, 0xe9, 0x44, 0x28, 0x76, 0x16, 0x96, 0x72, 0x32, +- 0xe3, 0xa6, 0xad, 0x4b, 0xbb, 0x5b, 0xd8, 0x5e, 0x8f, 0x72, 0xe2, 0x52, +- 0x9b, 0x17, 0x2e, 0x6e, 0x76, 0xd6, 0x71, 0xf3, 0xbe, 0xe2, 0xc5, 0x43, +- 0x7d, 0xf9, 0xbd, 0xc6, 0x18, 0xde, 0x33, 0x05, 0x17, 0xbd, 0xe4, 0x3d, +- 0xcc, 0xd2, 0x13, 0xdb, 0x90, 0xf3, 0x4b, 0xf9, 0xe4, 0xe7, 0xfd, 0xa0, +- 0x5b, 0x30, 0xec, 0x27, 0xb3, 0x63, 0x93, 0x6b, 0x2e, 0x7f, 0xac, 0x4c, +- 0x1e, 0xdb, 0x2f, 0x5c, 0xec, 0x4b, 0x55, 0x4f, 0xc9, 0xb3, 0x69, 0x5f, +- 0x03, 0xc1, 0x1e, 0x0b, 0x95, 0x6c, 0xc3, 0x8d, 0xbf, 0x65, 0xfc, 0x76, +- 0x0f, 0x1c, 0xbd, 0x41, 0x52, 0x32, 0xcf, 0xa1, 0x18, 0x36, 0x37, 0x7b, +- 0xe0, 0x1a, 0xaa, 0x2e, 0xcc, 0xad, 0xf3, 0x91, 0x3c, 0x3b, 0xdf, 0x8a, +- 0x83, 0xd3, 0x6a, 0x56, 0xf2, 0x6a, 0xd2, 0x88, 0x43, 0xa2, 0xd7, 0x4a, +- 0x7e, 0x8b, 0x5e, 0xfc, 0xfc, 0x16, 0x1d, 0x55, 0xf1, 0xbb, 0x1c, 0xb1, +- 0x2a, 0xd9, 0xf3, 0x6a, 0x47, 0x82, 0x98, 0x55, 0x12, 0xed, 0xc4, 0xd7, +- 0x7b, 0x6d, 0xbb, 0x87, 0x7e, 0x59, 0xc4, 0x18, 0xff, 0x48, 0xa8, 0x3e, +- 0x32, 0x47, 0x29, 0x20, 0xdf, 0x69, 0x47, 0xcf, 0x48, 0x41, 0xbc, 0x3c, +- 0x5a, 0xc5, 0x98, 0xae, 0xe1, 0x93, 0xb9, 0x6d, 0xc8, 0x8e, 0x5e, 0xbd, +- 0x57, 0x36, 0x75, 0x9f, 0x2c, 0xbf, 0x3f, 0x26, 0xe3, 0x11, 0xb9, 0x45, +- 0xfe, 0x0b, 0x17, 0xb7, 0xa6, 0x44, 0x36, 0x0f, 0x0e, 0xf4, 0x89, 0xbc, +- 0x36, 0x3a, 0xcc, 0x5b, 0x29, 0x27, 0x91, 0xbe, 0x72, 0xea, 0xfc, 0xe6, +- 0xdb, 0x91, 0x75, 0xf0, 0x4e, 0x65, 0x98, 0xf3, 0x65, 0xb9, 0x0b, 0xc5, +- 0xbf, 0x34, 0xe6, 0x15, 0xca, 0x73, 0x19, 0x69, 0xa3, 0x45, 0x19, 0x49, +- 0x4f, 0xad, 0xd3, 0xa9, 0x1c, 0xca, 0x3c, 0x5c, 0x28, 0x9c, 0xe3, 0xb2, +- 0x1e, 0xf3, 0x32, 0x90, 0xdc, 0xd2, 0x5e, 0x2a, 0x92, 0xa2, 0x7f, 0xd1, +- 0x8f, 0x0e, 0x77, 0x96, 0xbf, 0xb3, 0x5f, 0xd6, 0xe7, 0xd5, 0x3e, 0x36, +- 0xf7, 0x0a, 0x9f, 0x3c, 0x4e, 0x9f, 0x1c, 0xff, 0xa3, 0x3e, 0x39, 0xef, +- 0x4f, 0x94, 0xcf, 0xaf, 0xb7, 0xda, 0xf6, 0x6e, 0x53, 0xd6, 0xe8, 0x65, +- 0xdd, 0xb5, 0xe1, 0x4b, 0xf6, 0x5e, 0x65, 0x3d, 0x7e, 0x36, 0xd2, 0x95, +- 0xc1, 0xb4, 0xac, 0xbf, 0x0c, 0xa4, 0x80, 0x45, 0x49, 0xe9, 0x27, 0x46, +- 0x7d, 0xa9, 0xb7, 0x32, 0x1a, 0x31, 0x43, 0xe8, 0xc2, 0x19, 0xd3, 0xd8, +- 0xf7, 0x20, 0x79, 0x77, 0x37, 0x73, 0xd2, 0x83, 0xe6, 0x72, 0xfa, 0x7b, +- 0x31, 0x36, 0x34, 0xd0, 0x18, 0x57, 0x98, 0xf4, 0x7b, 0xab, 0x9d, 0xae, +- 0xe8, 0xf5, 0x45, 0xdb, 0x57, 0x25, 0x42, 0xc1, 0xb6, 0x8d, 0xc4, 0xf3, +- 0xa5, 0xbd, 0x5e, 0xe8, 0x8a, 0xc3, 0x07, 0x5a, 0x7f, 0xa1, 0x0a, 0x46, +- 0x9d, 0x29, 0xc8, 0xe5, 0xcd, 0xb2, 0xe6, 0x22, 0xfd, 0x2c, 0x67, 0x5e, +- 0x22, 0x75, 0x75, 0xb4, 0xd7, 0x2a, 0x48, 0xd5, 0x06, 0xfb, 0xe0, 0xb2, +- 0xed, 0xdf, 0x91, 0x17, 0x8e, 0x3b, 0xb9, 0x7c, 0x7d, 0xdd, 0x6e, 0xf5, +- 0x7f, 0x10, 0x0b, 0x9d, 0x36, 0x34, 0x59, 0xf3, 0x7f, 0xe1, 0x4f, 0xae, +- 0x7b, 0x9b, 0x90, 0xbd, 0x89, 0x42, 0x63, 0x89, 0x32, 0xe2, 0xcf, 0x71, +- 0x8a, 0xdb, 0x06, 0x3e, 0xbf, 0xf8, 0x64, 0x4a, 0xec, 0x1c, 0x55, 0x01, +- 0x63, 0x06, 0x66, 0x1f, 0x28, 0xc5, 0xb2, 0x01, 0xe1, 0x0a, 0x3e, 0xab, +- 0x30, 0x1a, 0xc0, 0x9c, 0x03, 0x95, 0x68, 0xd9, 0x23, 0xfb, 0x50, 0x76, +- 0x57, 0x45, 0x74, 0x35, 0xdc, 0x87, 0x34, 0x3c, 0xb0, 0xc7, 0xb6, 0x67, +- 0xcd, 0x23, 0xb5, 0x63, 0x4c, 0x7c, 0xb7, 0x69, 0x15, 0x3c, 0xd9, 0x6a, +- 0x2c, 0x49, 0xd6, 0x39, 0x6b, 0xad, 0x1f, 0x26, 0x5a, 0x5b, 0xce, 0xf5, +- 0xd6, 0x6e, 0xa8, 0x55, 0x82, 0xe6, 0x29, 0x25, 0x82, 0x82, 0x6c, 0x04, +- 0xae, 0xa4, 0x82, 0x57, 0x0d, 0x74, 0x95, 0x45, 0xa3, 0x70, 0x65, 0xa3, +- 0xf0, 0x25, 0xdd, 0x68, 0xa0, 0xbe, 0x4b, 0x38, 0xf7, 0xd3, 0x92, 0xd5, +- 0x98, 0x96, 0xbd, 0x0e, 0xfa, 0x81, 0x06, 0xfa, 0x48, 0x25, 0xfb, 0xf3, +- 0xa3, 0x25, 0xd9, 0x86, 0x69, 0x46, 0x33, 0x6d, 0xa3, 0x19, 0x33, 0x93, +- 0x7e, 0x2c, 0xe0, 0x7c, 0x2c, 0x4e, 0xb6, 0xb2, 0x1f, 0x1f, 0xda, 0x07, +- 0xee, 0x44, 0x60, 0xc8, 0x8b, 0xf2, 0x01, 0x1d, 0x1f, 0xce, 0xf5, 0xa2, +- 0x68, 0x28, 0x80, 0xd2, 0xa4, 0xec, 0x8d, 0x21, 0xb6, 0xb1, 0x39, 0x00, +- 0x5f, 0x16, 0x28, 0x19, 0xb0, 0xf1, 0xad, 0xf0, 0xa8, 0x7a, 0x77, 0xa5, +- 0x65, 0x4f, 0x73, 0x62, 0x41, 0x6b, 0xfb, 0x16, 0xe3, 0xce, 0x49, 0xbf, +- 0x77, 0x33, 0xcf, 0x52, 0xc8, 0xd7, 0x25, 0x06, 0xb6, 0xb6, 0x1f, 0x4c, +- 0xc8, 0xda, 0x46, 0x88, 0x7e, 0xeb, 0x81, 0x77, 0xa8, 0x53, 0xe9, 0xa3, +- 0xed, 0xa0, 0x40, 0xf4, 0xaf, 0xd2, 0xbf, 0xa0, 0x95, 0xd2, 0xce, 0xb7, +- 0x66, 0x5a, 0x94, 0x64, 0xba, 0x53, 0xe9, 0xcd, 0x94, 0x78, 0x51, 0x2c, +- 0xf3, 0xf2, 0x15, 0x8c, 0x36, 0x3c, 0x69, 0xa7, 0x2b, 0x9c, 0xb9, 0xb5, +- 0x3c, 0x90, 0x9c, 0xdb, 0x5a, 0x15, 0xae, 0x0d, 0x76, 0x56, 0xa8, 0xb2, +- 0x9f, 0x42, 0x1c, 0x52, 0x72, 0x7d, 0x69, 0x46, 0x12, 0xcf, 0xfa, 0x65, +- 0x7d, 0x55, 0xe6, 0xbf, 0xb5, 0x3d, 0xd1, 0x7b, 0xe1, 0xa2, 0xcc, 0xe9, +- 0xc7, 0xb4, 0xc3, 0xdb, 0x93, 0x9f, 0x5f, 0xdc, 0x97, 0x6a, 0x63, 0x9e, +- 0x66, 0xe2, 0x55, 0xfe, 0x5e, 0xc4, 0x71, 0xbf, 0x98, 0xf1, 0x61, 0x61, +- 0xb2, 0xd9, 0xd9, 0x8b, 0x5b, 0x96, 0x8c, 0xe0, 0x15, 0x7e, 0xb7, 0x24, +- 0x57, 0xe1, 0x18, 0xf3, 0xd4, 0x07, 0x92, 0x51, 0xbc, 0x9d, 0x09, 0xe0, +- 0x7e, 0xea, 0x6f, 0x06, 0xed, 0xf4, 0xae, 0xa4, 0x8e, 0x37, 0x32, 0xc0, +- 0xcf, 0xfa, 0x6c, 0x84, 0x1a, 0xbf, 0xa3, 0x3e, 0xed, 0xac, 0x8d, 0x35, +- 0xe3, 0x67, 0x09, 0x13, 0x6f, 0x24, 0x6a, 0xcc, 0x9b, 0xd5, 0xdf, 0x62, +- 0xdc, 0x9d, 0xa0, 0x4d, 0x9d, 0x47, 0xbc, 0x52, 0xd6, 0xf1, 0x72, 0xf2, +- 0x77, 0x8f, 0x79, 0x98, 0x63, 0x6d, 0xc0, 0x11, 0xbf, 0xb3, 0x2e, 0x71, +- 0x85, 0x5c, 0xb2, 0x36, 0xb1, 0x88, 0x72, 0x3d, 0x95, 0x22, 0x57, 0x34, +- 0xaa, 0x29, 0x8f, 0x17, 0x0b, 0x07, 0xbc, 0xa8, 0xa4, 0x6d, 0x9c, 0x3e, +- 0x10, 0xc5, 0xce, 0x54, 0x11, 0x5a, 0xfa, 0x03, 0x38, 0xc3, 0xeb, 0xad, +- 0xb4, 0xf1, 0x1f, 0xb1, 0x6f, 0xa3, 0x49, 0xc3, 0x80, 0x56, 0x84, 0x9e, +- 0xba, 0x1f, 0x93, 0xef, 0xa9, 0xcc, 0x39, 0x98, 0x1b, 0x18, 0x25, 0xd8, +- 0xc1, 0xb4, 0xbe, 0xb0, 0x39, 0x88, 0xfe, 0x3a, 0xda, 0x7a, 0x15, 0xe3, +- 0x87, 0x11, 0x43, 0x39, 0x31, 0x26, 0xc5, 0x5c, 0xb1, 0x30, 0x6a, 0x51, +- 0x06, 0x15, 0xfb, 0x34, 0x55, 0xd6, 0xe4, 0xf8, 0x2c, 0x80, 0x63, 0x09, +- 0xd8, 0xc5, 0x51, 0xe3, 0xc2, 0x4e, 0x84, 0x4e, 0xbc, 0xcf, 0xb8, 0xfe, +- 0xf7, 0x99, 0x12, 0x7c, 0xbf, 0x6f, 0x36, 0xfe, 0x36, 0x2d, 0xeb, 0xbd, +- 0x3e, 0xac, 0x1f, 0x0c, 0xab, 0xb9, 0xb5, 0x4a, 0x1f, 0x1e, 0x1a, 0x84, +- 0x35, 0x93, 0xf6, 0xf8, 0xf2, 0x70, 0x19, 0xd6, 0xf4, 0xbd, 0x60, 0x33, +- 0x77, 0xa6, 0x5d, 0x7b, 0x71, 0x34, 0x2d, 0x32, 0x96, 0x53, 0xc6, 0x22, +- 0x1c, 0xe3, 0x75, 0x0f, 0x6d, 0xbf, 0xb2, 0xf7, 0xdb, 0xf8, 0x2c, 0x55, +- 0x53, 0x77, 0xbf, 0xda, 0x8e, 0xe3, 0xce, 0x7e, 0x6c, 0x03, 0xde, 0xa2, +- 0x1e, 0xcb, 0x77, 0xdb, 0xf6, 0x6f, 0xc2, 0x31, 0xfc, 0x2c, 0x73, 0x2d, +- 0x8a, 0x78, 0x6d, 0x86, 0x5b, 0xf0, 0x66, 0xa6, 0x1a, 0x65, 0xbd, 0xad, +- 0x78, 0x9d, 0x9c, 0xbf, 0x74, 0x77, 0x27, 0x4e, 0xb1, 0x7d, 0x5f, 0xbf, +- 0x17, 0xaf, 0xa5, 0xbd, 0x78, 0xb5, 0xcf, 0xd0, 0xd6, 0x2a, 0x7f, 0xa7, +- 0xc4, 0x2b, 0x73, 0xfd, 0x0c, 0xa4, 0x72, 0xfa, 0xdc, 0x3e, 0x56, 0x00, +- 0xc1, 0xf2, 0x43, 0x7e, 0x59, 0xbf, 0x95, 0xf3, 0x31, 0xad, 0xed, 0x5a, +- 0xf2, 0x77, 0x17, 0x13, 0xd4, 0xe7, 0x9b, 0xa3, 0x01, 0xdc, 0x91, 0x14, +- 0xdd, 0x7e, 0x7e, 0x71, 0x17, 0xb1, 0xa3, 0x77, 0x34, 0x82, 0x13, 0x09, +- 0x8f, 0xb3, 0xe7, 0xd8, 0x33, 0x2a, 0xfb, 0xb1, 0xdf, 0xe5, 0xdc, 0x00, +- 0x6b, 0x47, 0x73, 0x6d, 0x6d, 0x19, 0x2b, 0xa4, 0xee, 0x6e, 0xc7, 0xd3, +- 0x5a, 0x81, 0xc4, 0xdf, 0x9c, 0x8d, 0x1a, 0x41, 0xda, 0xee, 0x77, 0x9d, +- 0xf5, 0xbd, 0x81, 0x54, 0xbd, 0x36, 0x0d, 0xf9, 0x79, 0xac, 0xc1, 0x4c, +- 0xe3, 0xf7, 0xf6, 0x0b, 0x7e, 0x59, 0x77, 0x15, 0xbe, 0xd8, 0xda, 0xbe, +- 0x36, 0x21, 0xfd, 0xe8, 0xd8, 0x3c, 0x7a, 0xe1, 0x62, 0x3f, 0xf9, 0xfa, +- 0x12, 0xda, 0xc8, 0xba, 0x90, 0x1f, 0x8b, 0x6b, 0xeb, 0x50, 0x9b, 0x95, +- 0x35, 0xdd, 0x08, 0x39, 0xab, 0x89, 0x8e, 0x50, 0xd4, 0xd9, 0xd7, 0x82, +- 0x9a, 0xbf, 0xe7, 0xc5, 0xbb, 0x7f, 0xe0, 0x2b, 0xc0, 0xac, 0x81, 0x36, +- 0xf6, 0x6b, 0x63, 0x99, 0xf9, 0x0f, 0x76, 0xcb, 0x3d, 0xd2, 0x7f, 0x4d, +- 0x59, 0xee, 0x19, 0x27, 0xbc, 0x58, 0x7e, 0x37, 0xd1, 0x97, 0x1a, 0x71, +- 0xd8, 0x2f, 0x3c, 0x43, 0xfc, 0xa0, 0xb5, 0x3d, 0x4c, 0xfb, 0xd9, 0x41, +- 0x19, 0x56, 0xd0, 0x76, 0x96, 0x11, 0x17, 0xca, 0x8d, 0x0b, 0x17, 0x7b, +- 0x53, 0x26, 0xe6, 0x8c, 0xfa, 0x68, 0xcb, 0x45, 0xec, 0xaf, 0x19, 0xc6, +- 0x28, 0x71, 0x84, 0xf6, 0xbd, 0x60, 0xd4, 0x4f, 0x7b, 0xd6, 0x31, 0x7f, +- 0x54, 0x7c, 0xdc, 0x40, 0x88, 0xb1, 0xac, 0x9d, 0x75, 0x22, 0xa3, 0x15, +- 0xb8, 0x79, 0xbf, 0x1b, 0x77, 0x26, 0xc3, 0xd4, 0x4f, 0x1d, 0x63, 0xdc, +- 0x65, 0x7d, 0x6f, 0x1b, 0x9b, 0x85, 0x0a, 0xe3, 0x88, 0xfd, 0x9c, 0x83, +- 0x61, 0x85, 0x8e, 0x9e, 0x02, 0xec, 0x37, 0x90, 0x82, 0x55, 0xce, 0xf8, +- 0x72, 0x61, 0xf4, 0xb9, 0x2f, 0xe2, 0xf7, 0x8a, 0x2e, 0xa7, 0x8e, 0x47, +- 0x30, 0xe5, 0x02, 0xb1, 0x0e, 0x68, 0x7c, 0xc2, 0xc6, 0xe2, 0xc6, 0x8d, +- 0xca, 0x0f, 0x1c, 0x5b, 0x92, 0x76, 0x85, 0x3b, 0xe4, 0xf5, 0x9f, 0xd7, +- 0xf9, 0x6f, 0x0a, 0x72, 0x3a, 0xcf, 0x8f, 0x33, 0xb8, 0x4f, 0x70, 0x7a, +- 0x7d, 0x63, 0x1e, 0xa7, 0xa5, 0xbc, 0xdc, 0x5f, 0x61, 0xf7, 0x6a, 0x70, +- 0x17, 0x1a, 0x2e, 0x6c, 0xaf, 0x7b, 0x46, 0x99, 0xd0, 0xc4, 0xe7, 0x15, +- 0x62, 0xc7, 0xed, 0x36, 0xdd, 0x96, 0x76, 0xfd, 0x12, 0xcb, 0x41, 0x29, +- 0xbc, 0x34, 0x97, 0xc2, 0x3f, 0xba, 0x27, 0xe7, 0x52, 0x78, 0x6f, 0x7e, +- 0x4c, 0x79, 0x59, 0x23, 0xe4, 0x76, 0x22, 0xaf, 0xd8, 0x86, 0x94, 0x79, +- 0xb0, 0xc8, 0x59, 0x8f, 0x46, 0xf7, 0x14, 0x7b, 0xc8, 0x73, 0x18, 0xa7, +- 0x0d, 0x0d, 0x97, 0xec, 0xc1, 0x8d, 0xb6, 0xa4, 0xcc, 0x3b, 0xac, 0x62, +- 0xea, 0xa1, 0x6d, 0xd4, 0xc3, 0xf9, 0x13, 0x2e, 0xae, 0x62, 0x89, 0xb9, +- 0x5d, 0x19, 0xf7, 0xef, 0x64, 0x1b, 0x9f, 0x5f, 0x64, 0x1d, 0xde, 0xeb, +- 0xe5, 0xf5, 0x75, 0xb8, 0x9d, 0x38, 0xba, 0x36, 0x6c, 0x29, 0xb9, 0x73, +- 0x05, 0x45, 0xb8, 0x71, 0xa0, 0x12, 0x3e, 0x43, 0xd6, 0x2d, 0xfe, 0xb3, +- 0xe2, 0xab, 0x90, 0xf1, 0x3b, 0x9c, 0x81, 0x76, 0x72, 0x1d, 0x16, 0x0f, +- 0x30, 0x64, 0x3b, 0x7b, 0x04, 0x0b, 0xf1, 0x74, 0xf3, 0x75, 0x58, 0xea, +- 0x70, 0x9d, 0x10, 0x6e, 0x1a, 0x12, 0x0c, 0xed, 0x54, 0xfa, 0x89, 0x9d, +- 0x4c, 0x38, 0xe8, 0xd7, 0x31, 0xa5, 0x8f, 0x98, 0xb9, 0xcf, 0xf1, 0x11, +- 0x59, 0x2f, 0xee, 0x54, 0x52, 0x99, 0x0a, 0x8e, 0x43, 0x6c, 0xf7, 0xb2, +- 0x8c, 0x33, 0x29, 0xe3, 0x79, 0x62, 0xd1, 0xfc, 0x49, 0x19, 0x67, 0x37, +- 0x49, 0x2e, 0x2b, 0x32, 0x16, 0xa1, 0x96, 0x72, 0x54, 0x52, 0x8e, 0x63, +- 0x66, 0x85, 0x32, 0xa0, 0xe5, 0x64, 0xab, 0x61, 0xff, 0x8c, 0x39, 0x58, +- 0x63, 0xfa, 0x94, 0x65, 0xce, 0xbd, 0xbc, 0x6c, 0x9f, 0x5f, 0xec, 0x49, +- 0x7d, 0x61, 0xfb, 0x8c, 0x9c, 0x9c, 0x65, 0xfd, 0x3a, 0x4e, 0xcd, 0xbd, +- 0x0e, 0xa5, 0xfb, 0x8b, 0xd0, 0x48, 0x5c, 0xaf, 0x1f, 0x30, 0xfa, 0x36, +- 0x2a, 0x22, 0xab, 0x87, 0xbf, 0x9d, 0x75, 0x03, 0xea, 0xf3, 0xff, 0x2f, +- 0xbc, 0xd2, 0x8e, 0xdd, 0x58, 0x91, 0xcc, 0xd9, 0xb0, 0xe3, 0xbf, 0xb5, +- 0x62, 0xbf, 0xb2, 0x46, 0x48, 0x7b, 0xce, 0xb8, 0xb0, 0x84, 0x7d, 0x1f, +- 0x33, 0x1f, 0x56, 0x2c, 0xed, 0xc2, 0x45, 0xd9, 0xaf, 0x57, 0x29, 0x63, +- 0x77, 0xfa, 0x3a, 0xdc, 0x31, 0x30, 0x6e, 0x7b, 0x8d, 0x05, 0xc8, 0x84, +- 0x43, 0xed, 0x3d, 0x8a, 0x17, 0xbb, 0xd2, 0x2e, 0x2c, 0x1a, 0x20, 0x5f, +- 0x33, 0xe3, 0x4a, 0x6c, 0x7a, 0x8e, 0x87, 0x2f, 0x4c, 0x32, 0x1f, 0xcd, +- 0x4a, 0x7e, 0xd8, 0xd6, 0xbe, 0x30, 0xf1, 0x80, 0x12, 0xd3, 0x3e, 0xbf, +- 0x98, 0x4c, 0x1d, 0xfd, 0xae, 0xea, 0xf0, 0x30, 0x1f, 0xde, 0x3c, 0xe8, +- 0xa3, 0x2f, 0x28, 0xf4, 0x13, 0x3f, 0x7d, 0xbf, 0x01, 0x6f, 0xd3, 0x37, +- 0xee, 0x67, 0x5c, 0xfc, 0xfb, 0xd1, 0x2a, 0xdc, 0xb6, 0x27, 0x8a, 0x97, +- 0x0f, 0xfa, 0xd1, 0xbe, 0xe7, 0x56, 0xbc, 0xc5, 0x72, 0x63, 0x8c, 0x07, +- 0x63, 0xc3, 0x95, 0xfc, 0xf8, 0xf9, 0xa9, 0xe2, 0x67, 0x2d, 0xf1, 0xa8, +- 0x02, 0x27, 0xf7, 0xbb, 0xd0, 0x32, 0xa0, 0x62, 0xc0, 0x54, 0x70, 0xf7, +- 0x4d, 0x32, 0x1e, 0x2f, 0xd6, 0xd4, 0x5e, 0xb6, 0x8b, 0x25, 0x49, 0xe1, +- 0x70, 0x5e, 0xce, 0x93, 0x8e, 0x43, 0xf4, 0xcb, 0xdb, 0xc8, 0xc1, 0x76, +- 0xf4, 0xb5, 0xd1, 0x8f, 0x6c, 0xcc, 0x0a, 0xff, 0x18, 0x2b, 0xb4, 0x1e, +- 0xc9, 0x6b, 0x9d, 0x75, 0xfe, 0x14, 0xe7, 0x71, 0xc2, 0x53, 0x6f, 0x4d, +- 0x43, 0x51, 0x2c, 0x10, 0x0d, 0x69, 0x47, 0xb0, 0x1c, 0x7d, 0x63, 0xd0, +- 0x64, 0xcd, 0x7f, 0x1b, 0x79, 0xd4, 0x76, 0xf2, 0xa8, 0xee, 0xcc, 0x11, +- 0xce, 0xb1, 0xcf, 0x2b, 0x7b, 0xdf, 0xdb, 0xa8, 0xbb, 0xc5, 0x0e, 0x27, +- 0xf2, 0x5a, 0x45, 0x6c, 0xff, 0x38, 0x63, 0xd2, 0x82, 0xfe, 0x1c, 0x6e, +- 0x7c, 0xd6, 0xf4, 0x3c, 0x8c, 0x69, 0x3d, 0xf4, 0xf9, 0x5c, 0xdb, 0x3b, +- 0x85, 0x9b, 0x79, 0xca, 0x62, 0x65, 0xd1, 0xd0, 0x86, 0xd7, 0xa9, 0x7c, +- 0x2f, 0xdb, 0xdc, 0x3a, 0xb9, 0x8f, 0xd0, 0xcb, 0x36, 0x7b, 0x58, 0xb7, +- 0xbe, 0xdf, 0xe2, 0x5c, 0xba, 0x59, 0x3f, 0x14, 0xd8, 0xa8, 0x98, 0xac, +- 0xeb, 0xe4, 0x11, 0xa8, 0xd9, 0x7f, 0x79, 0xae, 0xda, 0x88, 0x31, 0xfd, +- 0x93, 0xfe, 0x7e, 0x7e, 0xf4, 0x3a, 0x84, 0x68, 0x24, 0x4f, 0x9b, 0x9b, +- 0xa0, 0xd3, 0x66, 0x5d, 0x93, 0x7d, 0x6d, 0x97, 0x71, 0xb8, 0x67, 0xc6, +- 0x66, 0xb2, 0x8f, 0xbe, 0x4c, 0x48, 0xeb, 0x42, 0xfd, 0x89, 0x69, 0x90, +- 0x71, 0x48, 0x7f, 0xcb, 0xf1, 0xe4, 0xd8, 0xd5, 0xe3, 0xa8, 0x26, 0x3e, +- 0x5d, 0x2c, 0x98, 0x3c, 0x33, 0xe7, 0xe4, 0xe2, 0x31, 0xc7, 0xc7, 0x76, +- 0x38, 0xf2, 0x7b, 0xd8, 0x66, 0x36, 0xb7, 0x07, 0x22, 0x69, 0x95, 0x32, +- 0xc2, 0x58, 0xd1, 0x96, 0x54, 0x62, 0x15, 0xd1, 0xfa, 0xce, 0x69, 0x08, +- 0x45, 0x7e, 0xc6, 0xb6, 0xa7, 0xb1, 0xed, 0x67, 0xd9, 0x76, 0x8a, 0x6d, +- 0x8f, 0xb0, 0xed, 0x1f, 0x5c, 0x6a, 0x5b, 0xc5, 0xfd, 0x7b, 0xf2, 0xb6, +- 0xe5, 0x46, 0xa4, 0x89, 0x59, 0xdf, 0x34, 0xd9, 0x03, 0xad, 0xe6, 0xdc, +- 0x8b, 0xee, 0x74, 0xc6, 0xf6, 0x9c, 0xbd, 0x2d, 0x60, 0xec, 0xb9, 0x6b, +- 0x8f, 0x82, 0xf7, 0xc3, 0xef, 0x63, 0xc2, 0x9f, 0xe3, 0x11, 0x79, 0x1b, +- 0xd2, 0x68, 0x43, 0x5a, 0xf2, 0x7f, 0xd2, 0xf4, 0xa5, 0x8e, 0xd8, 0x8f, +- 0xec, 0x3f, 0x90, 0x3f, 0x27, 0x44, 0x1f, 0xbf, 0x23, 0xee, 0x86, 0x4e, +- 0xbc, 0xc7, 0xd8, 0xf9, 0xa3, 0x8c, 0x07, 0xe9, 0xb4, 0x0f, 0xcf, 0x66, +- 0x04, 0x1b, 0xdb, 0x88, 0x8d, 0x82, 0xf7, 0xe4, 0x81, 0xc3, 0x47, 0x1f, +- 0x0b, 0xb0, 0xf2, 0xb3, 0xb4, 0x9f, 0x67, 0x69, 0x3f, 0xcf, 0x0e, 0xfb, +- 0x70, 0xf3, 0x21, 0x2f, 0xce, 0x11, 0x6b, 0x7a, 0x59, 0x26, 0x91, 0x6a, +- 0xc0, 0x4d, 0xe4, 0x59, 0x87, 0x7b, 0x19, 0x97, 0x19, 0xff, 0xeb, 0xb2, +- 0x1a, 0x76, 0xf5, 0x57, 0xa0, 0x7e, 0x48, 0x62, 0x70, 0x05, 0x1e, 0xe9, +- 0xf3, 0x62, 0xce, 0x7e, 0xd9, 0x87, 0x24, 0x2f, 0xec, 0xbb, 0x13, 0xc3, +- 0x8e, 0x8f, 0x4f, 0xa3, 0x7f, 0x54, 0xa2, 0x76, 0x48, 0xae, 0xc9, 0x53, +- 0x68, 0xb3, 0x0b, 0x0e, 0x55, 0x71, 0xbc, 0xb7, 0x62, 0xfe, 0xa1, 0x00, +- 0xf1, 0xdc, 0x8f, 0x48, 0x76, 0xf9, 0x45, 0xc1, 0xe4, 0xed, 0x63, 0x53, +- 0x63, 0x9a, 0xf8, 0xa1, 0x83, 0x61, 0x91, 0x3c, 0x86, 0x5d, 0x7e, 0x3e, +- 0x15, 0x27, 0x7f, 0xcb, 0x67, 0x52, 0x26, 0x1f, 0x7b, 0xa6, 0xe2, 0xe2, +- 0x65, 0x7c, 0x6a, 0x1c, 0x90, 0x6f, 0x0d, 0xed, 0xf3, 0xc4, 0xd7, 0xaf, +- 0x43, 0xc4, 0x91, 0xe7, 0xfe, 0x62, 0x96, 0x0b, 0xe4, 0xfc, 0x7d, 0x2a, +- 0x9e, 0xfb, 0x26, 0xfd, 0xd4, 0x85, 0x58, 0x45, 0x8e, 0x0b, 0xdf, 0xbe, +- 0xa7, 0x01, 0xbb, 0xa8, 0x8f, 0x56, 0xfa, 0x91, 0x2f, 0x1c, 0xb5, 0xad, +- 0x0a, 0xc9, 0x5b, 0x2b, 0x71, 0xe7, 0x1e, 0x3f, 0x63, 0xf8, 0xb5, 0x48, +- 0x0e, 0xcf, 0x66, 0x5b, 0xd5, 0xe8, 0x9d, 0xcc, 0xe7, 0xb7, 0xa7, 0x96, +- 0xd9, 0x0f, 0x39, 0x7b, 0xf2, 0xb2, 0xf6, 0xff, 0xda, 0x7d, 0xde, 0xd0, +- 0xb8, 0xce, 0x7c, 0xde, 0x64, 0xce, 0x41, 0x0e, 0x76, 0x02, 0xa1, 0x4a, +- 0xe6, 0xe7, 0x46, 0x39, 0x16, 0x31, 0x9f, 0x7f, 0xc8, 0x2f, 0xcf, 0x6e, +- 0x15, 0x59, 0x9c, 0xf2, 0x97, 0xc7, 0xb8, 0x6b, 0xca, 0x18, 0xeb, 0x23, +- 0xd3, 0x90, 0xe7, 0x63, 0x5f, 0xd8, 0x7f, 0x6f, 0x40, 0xe9, 0x0f, 0xd1, +- 0x6a, 0x1b, 0x83, 0x7d, 0x0f, 0x29, 0x86, 0xd6, 0xa4, 0x12, 0xba, 0x46, +- 0xdf, 0xc4, 0x92, 0xec, 0x2f, 0x10, 0xcb, 0xae, 0xf6, 0x8a, 0x2c, 0xf7, +- 0x67, 0x57, 0x61, 0x9c, 0x73, 0x5c, 0xc4, 0x3a, 0x37, 0xf4, 0xfa, 0x68, +- 0xa3, 0x50, 0x0e, 0x37, 0xd7, 0xe1, 0x43, 0xf2, 0x9c, 0xb6, 0xe4, 0x9b, +- 0xd0, 0x18, 0x5f, 0xef, 0x4c, 0xfe, 0x02, 0x65, 0xc4, 0x94, 0x3b, 0x92, +- 0x5f, 0xd8, 0x23, 0xa1, 0x7d, 0x4e, 0xbd, 0xc2, 0xd1, 0x03, 0x17, 0xfb, +- 0x2e, 0xc7, 0x27, 0xad, 0xd0, 0x78, 0xe5, 0x2a, 0x3c, 0x6c, 0x68, 0xd9, +- 0x9c, 0x18, 0xfd, 0x5f, 0x9e, 0xe8, 0xaf, 0x7f, 0xfa, 0xfd, 0xe6, 0x9c, +- 0x5d, 0xea, 0x99, 0xbb, 0xf0, 0x2d, 0x07, 0x77, 0xd7, 0x6c, 0x74, 0x47, +- 0x3b, 0x1e, 0x93, 0xb5, 0xd0, 0x35, 0xce, 0x3a, 0x41, 0x3b, 0x76, 0xee, +- 0x6d, 0xc3, 0xe6, 0xbd, 0x82, 0xad, 0xf5, 0xad, 0x8b, 0x94, 0x19, 0xf4, +- 0xc3, 0x01, 0x27, 0x97, 0x71, 0x1b, 0x9f, 0xca, 0x9a, 0xab, 0xea, 0x71, +- 0xf6, 0xc0, 0x74, 0xac, 0x19, 0xcd, 0xb5, 0x35, 0x2b, 0x53, 0x4a, 0xff, +- 0x8a, 0x22, 0xc9, 0x9c, 0xc5, 0xc7, 0xd8, 0xc9, 0x79, 0xc1, 0xa9, 0x7e, +- 0x89, 0x3b, 0x0a, 0x7c, 0xf7, 0xc8, 0x5e, 0xe6, 0x32, 0xe4, 0xf9, 0x7a, +- 0x4c, 0xdb, 0xcc, 0xdf, 0x3b, 0x8a, 0x73, 0x72, 0x6d, 0xbe, 0x8a, 0x17, +- 0xe5, 0xed, 0x41, 0x74, 0x97, 0xb7, 0xa1, 0x4f, 0x39, 0x06, 0xe6, 0xd8, +- 0xe4, 0x83, 0x97, 0xfd, 0xf9, 0x8b, 0x22, 0x67, 0x5d, 0x30, 0x3b, 0x35, +- 0xbe, 0x6f, 0x9f, 0xd4, 0xfd, 0x75, 0xc5, 0xf9, 0xd8, 0x94, 0x93, 0xd7, +- 0x24, 0x16, 0x5e, 0x83, 0x98, 0x3f, 0xef, 0xff, 0xdf, 0xe4, 0xf3, 0xcd, +- 0x82, 0x01, 0x93, 0x75, 0xef, 0x2e, 0x41, 0xf1, 0x76, 0x87, 0xc3, 0x5d, +- 0x6e, 0x9f, 0x64, 0xf8, 0x8a, 0xf6, 0xa7, 0xda, 0xaf, 0xb4, 0x2f, 0x71, +- 0x5a, 0x74, 0xda, 0xc8, 0xba, 0xa2, 0x3f, 0x07, 0xa3, 0x65, 0x4d, 0x96, +- 0xdc, 0xad, 0xcd, 0xd9, 0xa7, 0x29, 0x26, 0x6f, 0xee, 0x66, 0x0e, 0x55, +- 0xb2, 0x9f, 0xd7, 0xe4, 0x3e, 0x4b, 0x07, 0x02, 0x28, 0xda, 0xef, 0x21, +- 0xae, 0xcf, 0x80, 0x7b, 0x7f, 0x01, 0xed, 0x55, 0x38, 0xc2, 0x6b, 0xf7, +- 0x6d, 0x31, 0xae, 0x85, 0x6b, 0x7f, 0x21, 0x79, 0xb9, 0x70, 0xbe, 0x13, +- 0xf7, 0xad, 0x65, 0x1c, 0x57, 0xf7, 0x7b, 0x19, 0x9f, 0xab, 0xe1, 0x61, +- 0xcc, 0x5b, 0x32, 0xf0, 0x67, 0x28, 0xd8, 0x5f, 0x8c, 0x07, 0x06, 0xae, +- 0xc7, 0xcc, 0xfd, 0x25, 0xb8, 0x7f, 0x60, 0x26, 0x66, 0xec, 0x97, 0xdc, +- 0x49, 0x47, 0x60, 0x7f, 0x29, 0x56, 0x0c, 0x04, 0x51, 0xb1, 0xbf, 0x0c, +- 0x6d, 0x03, 0xb3, 0xa0, 0xed, 0x2f, 0xc7, 0x5d, 0x03, 0x35, 0x28, 0xdf, +- 0xaf, 0xe1, 0xce, 0x01, 0x03, 0x65, 0xfb, 0x2b, 0x18, 0xd3, 0x42, 0x8c, +- 0x9d, 0x7e, 0x2c, 0xdf, 0xc3, 0xb9, 0x39, 0x58, 0x45, 0xbf, 0x58, 0x45, +- 0x4e, 0xbd, 0x1a, 0xfb, 0x52, 0x73, 0x50, 0x72, 0x30, 0x80, 0xa5, 0x7b, +- 0xc6, 0x35, 0x52, 0x1a, 0x2c, 0x0e, 0x35, 0xa0, 0xe8, 0xa0, 0xe4, 0x7e, +- 0xc1, 0x13, 0x2d, 0x08, 0x5e, 0x58, 0x84, 0x72, 0xe6, 0xbe, 0xc0, 0x7b, +- 0x63, 0xc0, 0xec, 0x31, 0x17, 0x8e, 0x68, 0xab, 0xb0, 0x75, 0xec, 0x9b, +- 0x93, 0x36, 0x2f, 0xfb, 0x47, 0xe5, 0x9c, 0x5f, 0xb9, 0x96, 0x7b, 0xab, +- 0xd1, 0x33, 0x96, 0x5f, 0x07, 0x0b, 0xf6, 0x6d, 0xa7, 0x06, 0xc7, 0x33, +- 0xf2, 0x4c, 0x7c, 0x04, 0xb4, 0x6f, 0xa5, 0x5b, 0xce, 0x8f, 0xbb, 0xa2, +- 0x6a, 0x59, 0x77, 0xf3, 0x86, 0x5b, 0xe2, 0x99, 0x4d, 0xcc, 0xbb, 0x24, +- 0x87, 0xdd, 0x78, 0xcb, 0x9a, 0xcc, 0x07, 0x97, 0xf6, 0x13, 0xfa, 0xcc, +- 0x85, 0x01, 0x0d, 0x5f, 0xc3, 0x1a, 0x67, 0x0d, 0x55, 0xe5, 0x9c, 0xc9, +- 0x79, 0x56, 0xe7, 0x2c, 0x39, 0xed, 0x2c, 0x0e, 0xd3, 0xc1, 0xd4, 0x75, +- 0xa8, 0xc9, 0x38, 0x6b, 0xb5, 0x75, 0x71, 0xbc, 0xa0, 0xb6, 0x1a, 0xd6, +- 0xe4, 0xd9, 0x0f, 0x6b, 0xbe, 0x86, 0x98, 0xa9, 0x5d, 0x3a, 0x1f, 0x12, +- 0xd4, 0x47, 0x10, 0x0c, 0x6c, 0xc3, 0x3a, 0xe7, 0x7c, 0xa0, 0x12, 0x6d, +- 0x97, 0x73, 0x46, 0xfc, 0x5e, 0x0d, 0x23, 0x93, 0x5f, 0x6b, 0x94, 0xb3, +- 0xd7, 0xb2, 0x8f, 0x65, 0x33, 0xe7, 0x97, 0x3c, 0xf9, 0x88, 0xa2, 0xf6, +- 0x3a, 0xeb, 0x63, 0xab, 0x5c, 0x8c, 0x01, 0x2d, 0x0a, 0xe2, 0x45, 0xd1, +- 0x90, 0xfe, 0xe1, 0xe4, 0xba, 0x83, 0x67, 0x74, 0x8b, 0x52, 0x30, 0xda, +- 0xa3, 0xb8, 0x47, 0x73, 0xeb, 0x0e, 0x2e, 0xf2, 0xd8, 0x6d, 0xa9, 0x4a, +- 0x96, 0xd1, 0x30, 0x7b, 0xae, 0x1b, 0xaf, 0x26, 0xca, 0x9c, 0xb3, 0xc7, +- 0x5b, 0xe7, 0x16, 0xe0, 0x11, 0xda, 0x7e, 0xeb, 0x8d, 0xc7, 0xf0, 0x41, +- 0x86, 0x5c, 0x23, 0x61, 0x85, 0x87, 0xd9, 0xe7, 0xd1, 0x84, 0x8a, 0x17, +- 0x07, 0xb7, 0x84, 0x87, 0x9c, 0xfe, 0xbf, 0x8d, 0xcd, 0x23, 0x92, 0x77, +- 0xb5, 0xd9, 0xdb, 0x53, 0xed, 0xb6, 0xc4, 0xdd, 0x6c, 0xa2, 0x92, 0xb9, +- 0xb9, 0x86, 0x0f, 0xe6, 0x6e, 0xc0, 0x39, 0x96, 0x19, 0x4d, 0x6c, 0xc4, +- 0x27, 0xe4, 0x08, 0x99, 0xc4, 0x72, 0xbc, 0xc6, 0x5c, 0xf2, 0x7b, 0x89, +- 0x56, 0xe6, 0x96, 0xab, 0xf0, 0xca, 0xa0, 0xf0, 0x8f, 0x16, 0x2c, 0x4c, +- 0x28, 0x58, 0x1a, 0x5a, 0x85, 0x93, 0xc3, 0xcc, 0x29, 0x07, 0xe5, 0xbc, +- 0xeb, 0x35, 0x58, 0x93, 0x3b, 0x0f, 0xc5, 0xe7, 0x31, 0x3e, 0x5f, 0x89, +- 0xa3, 0xc3, 0x01, 0x1c, 0x60, 0x0e, 0xf9, 0x0e, 0x31, 0x64, 0x28, 0xd1, +- 0x80, 0xd3, 0xcc, 0x95, 0x7e, 0x94, 0x88, 0xe0, 0x33, 0xfe, 0x3e, 0x92, +- 0x90, 0xf5, 0xef, 0x66, 0x5c, 0xc8, 0xfc, 0x18, 0x05, 0xbd, 0x33, 0x70, +- 0xbc, 0xed, 0x79, 0x52, 0xc9, 0x23, 0xfc, 0xb4, 0xe2, 0xf4, 0x70, 0x2b, +- 0xce, 0x0c, 0x2e, 0xc3, 0x99, 0xe1, 0x5f, 0xe1, 0x83, 0x41, 0x91, 0x57, +- 0xce, 0x2c, 0x3a, 0xef, 0x16, 0xb0, 0x5d, 0xe2, 0xd4, 0xf0, 0xbf, 0xa5, +- 0xed, 0x8f, 0xec, 0xe3, 0xab, 0xa4, 0xdd, 0xe7, 0xff, 0x48, 0xdb, 0xa2, +- 0x4b, 0x89, 0xf5, 0x5e, 0x9c, 0x4c, 0x78, 0x99, 0x57, 0x8d, 0xdf, 0x50, +- 0x84, 0xf1, 0xf9, 0xcc, 0x36, 0xb1, 0x3d, 0x53, 0x88, 0x17, 0xfb, 0xdc, +- 0xe4, 0x8a, 0x5f, 0x25, 0x7e, 0x74, 0xd2, 0x0e, 0x0b, 0x99, 0xbf, 0x79, +- 0xa9, 0xe3, 0xf9, 0xc4, 0xfb, 0x55, 0xd4, 0x9f, 0x0f, 0xa7, 0x12, 0x7e, +- 0xbc, 0x9e, 0xa8, 0x8f, 0x67, 0x95, 0x46, 0x58, 0x15, 0xb9, 0xbc, 0xf2, +- 0x68, 0xa2, 0xc3, 0x91, 0xe9, 0xd5, 0x44, 0x9b, 0xbd, 0x95, 0x3a, 0xee, +- 0x49, 0x7d, 0xdb, 0x39, 0x6f, 0xf8, 0x4a, 0xe2, 0x82, 0x2d, 0xe7, 0x88, +- 0x9f, 0xa1, 0x4e, 0x4f, 0x26, 0xe2, 0x28, 0x62, 0x9e, 0x72, 0x2c, 0x31, +- 0x8e, 0x61, 0xda, 0xe5, 0x3b, 0x7d, 0xc6, 0x89, 0x35, 0xd8, 0x84, 0xcf, +- 0xd2, 0x85, 0x78, 0x8b, 0x7d, 0x94, 0x37, 0xb9, 0x31, 0xe1, 0xb4, 0xb7, +- 0x09, 0x9f, 0xf4, 0x29, 0xc8, 0xcc, 0xdd, 0x84, 0x8f, 0xf9, 0xec, 0x0d, +- 0x5e, 0x9f, 0x0b, 0x53, 0xc2, 0xc9, 0x67, 0x67, 0xfa, 0x54, 0x27, 0x07, +- 0xee, 0x6e, 0xde, 0x84, 0xd3, 0xe9, 0x8f, 0x71, 0x80, 0xb9, 0xf4, 0x63, +- 0xe6, 0x34, 0x44, 0xa6, 0x11, 0x70, 0x8d, 0x42, 0x9c, 0xe4, 0xf3, 0x5a, +- 0x59, 0xef, 0xd1, 0x72, 0xe5, 0x3f, 0xe2, 0x78, 0x1e, 0x61, 0x5b, 0x67, +- 0xd3, 0xdf, 0x61, 0xbb, 0xc2, 0x39, 0xbf, 0xc3, 0x76, 0x7f, 0x85, 0x91, +- 0x49, 0x7d, 0x9c, 0x36, 0x65, 0x5c, 0x1b, 0x7c, 0x28, 0xf6, 0x73, 0x1c, +- 0x0f, 0xf3, 0xbb, 0x03, 0x13, 0x99, 0x9d, 0xfc, 0x7e, 0x0d, 0x87, 0x33, +- 0x12, 0xdb, 0xf3, 0x67, 0x87, 0x64, 0x7d, 0x4b, 0xfc, 0x47, 0x9f, 0x5c, +- 0x97, 0x9b, 0x8e, 0x54, 0x7f, 0x59, 0x7c, 0x1a, 0xed, 0xe8, 0x3f, 0xcc, +- 0x2b, 0xc7, 0x47, 0x61, 0x0b, 0xbb, 0x0e, 0xb8, 0x91, 0xea, 0x25, 0x9f, +- 0xed, 0xad, 0xc4, 0x53, 0xbb, 0x35, 0x3c, 0xb9, 0xfb, 0x5a, 0x6c, 0xd9, +- 0x7d, 0x3d, 0xf6, 0xed, 0xae, 0x46, 0x92, 0xb9, 0xf2, 0x27, 0x4d, 0xb6, +- 0x3d, 0x87, 0x9f, 0x1d, 0xf4, 0x05, 0x2f, 0xbf, 0x5f, 0x0e, 0x8b, 0x9f, +- 0x18, 0xb8, 0xd1, 0xf1, 0x97, 0x16, 0xdc, 0xe0, 0x7c, 0xc7, 0x30, 0x27, +- 0xd3, 0x19, 0xde, 0x90, 0xdd, 0x14, 0x7e, 0x28, 0x3b, 0x1d, 0x5b, 0xfb, +- 0xab, 0xd0, 0xbf, 0xbb, 0x32, 0x5e, 0xc9, 0x7e, 0x56, 0xce, 0xb3, 0x31, +- 0xc4, 0xba, 0x66, 0x63, 0x4f, 0x78, 0x4d, 0xf6, 0x79, 0xb4, 0x65, 0xfd, +- 0xd8, 0xdc, 0x1f, 0x60, 0x5f, 0xb2, 0x86, 0xef, 0x3e, 0xf1, 0x20, 0x6c, +- 0xfb, 0x42, 0xd3, 0x11, 0xc6, 0xb7, 0x1f, 0xa3, 0x9d, 0xcf, 0x92, 0xfd, +- 0x1b, 0xc8, 0xa9, 0x0a, 0xe2, 0xde, 0xa8, 0x8d, 0x53, 0xe1, 0x71, 0xdc, +- 0xc1, 0xf6, 0x76, 0xf6, 0x97, 0x51, 0xa6, 0xe2, 0x78, 0x21, 0xef, 0x2d, +- 0x0d, 0x6f, 0xc4, 0xae, 0x31, 0x59, 0x03, 0x3c, 0x81, 0xa5, 0xe4, 0x2c, +- 0x15, 0x73, 0x7f, 0x56, 0x82, 0x32, 0xcd, 0x7d, 0xbe, 0x59, 0xec, 0x2f, +- 0x4e, 0xfb, 0x13, 0xac, 0x5c, 0x87, 0xb5, 0xce, 0xd9, 0xc2, 0x76, 0xbc, +- 0x94, 0x10, 0x9c, 0x5e, 0x8d, 0x83, 0x89, 0x75, 0xd8, 0x92, 0x92, 0x7d, +- 0xc0, 0xe5, 0xa8, 0xc9, 0xfe, 0x55, 0x78, 0x3d, 0xe3, 0xa9, 0x2b, 0xfb, +- 0x3f, 0xb0, 0x38, 0x9b, 0xa6, 0x5c, 0xc3, 0xe1, 0xb5, 0xd9, 0x7d, 0xe1, +- 0x07, 0xb3, 0xad, 0x98, 0x95, 0x95, 0xf5, 0xb4, 0x36, 0xe2, 0xbb, 0xac, +- 0xa7, 0x4d, 0x60, 0x61, 0xf6, 0x0c, 0x16, 0x65, 0xdf, 0x62, 0x2c, 0x16, +- 0xdc, 0x90, 0x75, 0xb6, 0x5f, 0x31, 0x39, 0x91, 0x7d, 0xc3, 0xbf, 0xc4, +- 0xd6, 0xbd, 0x71, 0xc6, 0xc2, 0x3c, 0x46, 0xd5, 0x6b, 0x07, 0x04, 0x5f, +- 0xc6, 0x3c, 0x4e, 0x2c, 0xe8, 0x4b, 0xdd, 0x43, 0x7b, 0x54, 0xc9, 0xf3, +- 0x25, 0xce, 0xac, 0xa3, 0x2f, 0x77, 0x92, 0x9f, 0x4b, 0xfc, 0xbb, 0x6b, +- 0xf2, 0xbe, 0xf0, 0x3a, 0x89, 0x7d, 0x3a, 0x8e, 0x66, 0x9c, 0xbd, 0x0c, +- 0xdd, 0x6b, 0xdc, 0xc1, 0x67, 0x52, 0xff, 0x2f, 0x91, 0xdc, 0xbb, 0xca, +- 0xde, 0xe9, 0xac, 0x19, 0x29, 0x38, 0x1e, 0x62, 0x5f, 0xa4, 0x91, 0x4b, +- 0xf7, 0xcb, 0x59, 0xce, 0x75, 0x72, 0x96, 0xd3, 0x72, 0x19, 0x6d, 0xf6, +- 0x96, 0x14, 0x1e, 0x2c, 0x45, 0x00, 0xcb, 0x47, 0x0b, 0x10, 0x3b, 0x58, +- 0x8c, 0xdb, 0x77, 0xb7, 0xd3, 0x96, 0x2d, 0xda, 0xaf, 0x61, 0xae, 0x55, +- 0x8a, 0xb1, 0x84, 0xf7, 0x1e, 0xe8, 0x0f, 0xb6, 0x02, 0xa1, 0x13, 0xa7, +- 0x5d, 0xc5, 0xb8, 0x9f, 0xb1, 0x23, 0x9d, 0x5e, 0x8e, 0xd8, 0xfe, 0xe3, +- 0xb0, 0xd2, 0xb4, 0xc9, 0x3d, 0xc4, 0x99, 0xbd, 0x6e, 0xa8, 0xd1, 0x5f, +- 0x61, 0xdf, 0xb0, 0x8a, 0xf2, 0x3d, 0x2f, 0xd8, 0x01, 0x43, 0x31, 0xce, +- 0x85, 0xb2, 0xe4, 0x40, 0x6e, 0x94, 0x26, 0x5b, 0x30, 0x4a, 0xac, 0xf1, +- 0x25, 0x63, 0xc8, 0x64, 0xda, 0x90, 0x26, 0x96, 0xa4, 0xc9, 0x9b, 0x4a, +- 0x92, 0x26, 0x63, 0x79, 0x1d, 0x76, 0xd1, 0x5f, 0x0a, 0x98, 0xcb, 0x6f, +- 0xcb, 0xdc, 0x0a, 0x6b, 0xf8, 0x4e, 0x6c, 0x1f, 0x6e, 0xe3, 0x87, 0xfc, +- 0x71, 0xf8, 0xdb, 0x58, 0x38, 0x7a, 0x02, 0x3d, 0x99, 0x38, 0xed, 0xf1, +- 0x63, 0x6c, 0x4f, 0x1f, 0xc3, 0x53, 0x7d, 0x5d, 0xcc, 0x11, 0x8e, 0xe1, +- 0x49, 0x5e, 0xf7, 0xf5, 0x19, 0x9d, 0x01, 0xf5, 0x18, 0x52, 0xe9, 0x4d, +- 0xb8, 0xb3, 0x5f, 0x61, 0x0e, 0xb7, 0x09, 0x77, 0xec, 0xa7, 0x2d, 0x3e, +- 0xd1, 0x81, 0xd6, 0xd1, 0xd7, 0x90, 0xc8, 0xbc, 0xc4, 0xfc, 0x6a, 0x23, +- 0x7a, 0x52, 0x1b, 0xc8, 0xbd, 0x9e, 0x67, 0x3b, 0x47, 0xe8, 0xe7, 0x9d, +- 0x1c, 0xe3, 0xe3, 0xfc, 0x5c, 0xc2, 0x70, 0x4d, 0x57, 0xf2, 0x58, 0x4d, +- 0xbf, 0x4f, 0x49, 0xee, 0xb0, 0x8e, 0x38, 0x71, 0x6f, 0x29, 0x8a, 0x45, +- 0xbf, 0xf9, 0x35, 0x69, 0x99, 0x0b, 0xb1, 0x7d, 0x59, 0x9b, 0x76, 0xa3, +- 0x28, 0x29, 0xeb, 0xd1, 0xe3, 0xc1, 0x22, 0x72, 0x00, 0x6f, 0x52, 0x74, +- 0xd8, 0x6e, 0x77, 0xa7, 0x04, 0x4b, 0x72, 0xdc, 0xfc, 0xe5, 0xcc, 0xaf, +- 0xb0, 0x75, 0x70, 0x1a, 0x16, 0xf5, 0x55, 0x23, 0xee, 0xb7, 0xed, 0xe7, +- 0xe8, 0x6b, 0x09, 0xe6, 0x58, 0xbb, 0xfa, 0x63, 0xc4, 0x94, 0x12, 0xe4, +- 0x72, 0x3d, 0xd1, 0x4d, 0xd0, 0xd4, 0xaf, 0xd8, 0x23, 0x99, 0xc5, 0x79, +- 0x13, 0xee, 0x3a, 0x7e, 0x43, 0x29, 0xce, 0x97, 0xe4, 0xd6, 0xc5, 0xff, +- 0xfc, 0x12, 0xb7, 0xf9, 0xd7, 0x95, 0xbf, 0xff, 0xdf, 0x58, 0x7e, 0x62, +- 0xca, 0xd9, 0xb5, 0xfc, 0x7b, 0x39, 0x32, 0xd6, 0xeb, 0xe5, 0xdc, 0x9a, +- 0x25, 0x7c, 0x49, 0xce, 0xdc, 0x1e, 0x4f, 0x14, 0x30, 0x4e, 0xaa, 0x0b, +- 0x3c, 0x50, 0xfd, 0x1e, 0x14, 0x32, 0x9e, 0x55, 0x61, 0xb3, 0xdf, 0xc6, +- 0x62, 0xb3, 0x00, 0x87, 0x1b, 0x62, 0x72, 0xce, 0xa2, 0xdd, 0xe3, 0xf0, +- 0xd1, 0xd5, 0xf7, 0xfc, 0xe1, 0xba, 0xf5, 0x26, 0x72, 0x37, 0x39, 0x5f, +- 0xd0, 0x86, 0x53, 0x15, 0xf2, 0xae, 0xd0, 0x26, 0xe7, 0xdc, 0x59, 0x51, +- 0xad, 0xac, 0xa3, 0xe9, 0x38, 0x61, 0xd4, 0xeb, 0x95, 0x2a, 0xe3, 0xb9, +- 0xf2, 0xae, 0x6d, 0xf9, 0xa3, 0x8c, 0xf5, 0x72, 0x86, 0xe2, 0x5f, 0xda, +- 0xa7, 0x58, 0x83, 0xed, 0x4f, 0x34, 0x63, 0x62, 0x95, 0xc4, 0xff, 0xff, +- 0xe6, 0xcb, 0x73, 0xba, 0x6d, 0xa9, 0x1f, 0x96, 0xca, 0xb9, 0x24, 0x69, +- 0x7b, 0x3b, 0xf3, 0x27, 0x8f, 0x11, 0xc6, 0xbb, 0xc2, 0xd2, 0x9c, 0xfd, +- 0xa4, 0x1c, 0xa7, 0x28, 0x34, 0xce, 0x4f, 0xbe, 0x3b, 0xf2, 0xd7, 0xa5, +- 0xc2, 0x0f, 0xb7, 0xa5, 0x36, 0x91, 0x9b, 0x8b, 0x3c, 0xbf, 0xb7, 0xd7, +- 0xf8, 0x2b, 0x59, 0xf6, 0xee, 0xc9, 0xf6, 0xc4, 0x16, 0xe4, 0x4c, 0x8e, +- 0xdc, 0x93, 0x3a, 0xa2, 0xb3, 0xa9, 0x75, 0x5c, 0xcc, 0x85, 0x6f, 0xc0, +- 0xa3, 0xf4, 0xc1, 0x99, 0xc6, 0xeb, 0x76, 0x97, 0x9c, 0x9f, 0xa9, 0xd5, +- 0xa6, 0xf4, 0xf5, 0x0b, 0x47, 0x96, 0x42, 0xca, 0xd2, 0x9f, 0x92, 0xb3, +- 0xa8, 0x9f, 0xd9, 0xb5, 0x55, 0xf2, 0xfc, 0xc2, 0x64, 0xfb, 0x35, 0xce, +- 0xd9, 0xbe, 0x7d, 0xa9, 0xbc, 0xdc, 0xb2, 0xde, 0xea, 0xcf, 0xf7, 0x55, +- 0x77, 0x79, 0x3c, 0x22, 0x5b, 0xbc, 0xf4, 0x4a, 0x99, 0xe1, 0xcb, 0x9f, +- 0x59, 0x9d, 0xe1, 0xd4, 0xc9, 0xf7, 0x29, 0x32, 0x6e, 0x62, 0x9e, 0x7a, +- 0xf5, 0x18, 0xb5, 0x29, 0x63, 0x92, 0x3a, 0x32, 0x2e, 0x6d, 0xd2, 0x0e, +- 0x4a, 0xcb, 0x50, 0x2c, 0x75, 0x84, 0xbb, 0x6a, 0x0e, 0x07, 0x2f, 0x17, +- 0x5e, 0x2e, 0xb6, 0x51, 0x66, 0xdb, 0xef, 0x39, 0x31, 0x53, 0xda, 0xe1, +- 0x38, 0xc6, 0x56, 0xd1, 0xce, 0xed, 0x2e, 0xe2, 0xa7, 0xfd, 0x5e, 0x73, +- 0x00, 0x5b, 0x13, 0xa2, 0x6b, 0x23, 0x70, 0x88, 0xd8, 0xb1, 0xd9, 0xe1, +- 0x1b, 0x1e, 0x74, 0xa7, 0xf3, 0xfb, 0xa3, 0x85, 0x72, 0xf6, 0x36, 0x20, +- 0x3a, 0xef, 0x36, 0xc9, 0xb3, 0xb4, 0x85, 0xba, 0x9b, 0x5c, 0x69, 0x3d, +- 0xfe, 0x99, 0xf3, 0x2b, 0xe7, 0x8f, 0x73, 0x7b, 0x95, 0x71, 0xda, 0x51, +- 0x2e, 0x5e, 0x81, 0xf1, 0x9d, 0x3c, 0x69, 0xf2, 0x5c, 0x66, 0x77, 0xe6, +- 0x9f, 0xed, 0x71, 0xe7, 0x5c, 0xe6, 0xe5, 0x77, 0x3a, 0xd2, 0x9a, 0x6d, +- 0x1f, 0xe0, 0xb3, 0xcb, 0x67, 0x34, 0x19, 0xd3, 0x0d, 0x39, 0xcb, 0xf9, +- 0x4f, 0x9c, 0xbb, 0xa9, 0x65, 0xc7, 0x2b, 0x72, 0x67, 0x96, 0x63, 0xea, +- 0x42, 0x23, 0x8f, 0xab, 0x41, 0xcb, 0x72, 0x70, 0xf5, 0x0e, 0x67, 0x0f, +- 0x3e, 0x8d, 0x60, 0x6b, 0x1b, 0x2c, 0xbb, 0xd8, 0xc8, 0xe3, 0x80, 0x61, +- 0xce, 0x51, 0xba, 0x30, 0x3b, 0x5c, 0x2c, 0x1c, 0x3b, 0xe8, 0x8e, 0x06, +- 0xb5, 0x0f, 0x10, 0xaa, 0x3b, 0xe6, 0xec, 0x95, 0x0a, 0x36, 0x18, 0x58, +- 0x9f, 0x21, 0xdf, 0x1e, 0x93, 0x77, 0x1d, 0xe5, 0xda, 0x69, 0x9f, 0xd7, +- 0x82, 0xa5, 0xed, 0xc4, 0x52, 0xeb, 0xcf, 0x3d, 0x4e, 0x7b, 0xc1, 0xf6, +- 0x61, 0x25, 0xd8, 0xba, 0x51, 0xc9, 0xb7, 0xe7, 0xfb, 0x92, 0xf6, 0xea, +- 0x58, 0xbf, 0x7a, 0xf2, 0xfd, 0x42, 0x83, 0x6d, 0x5c, 0xbd, 0x9f, 0x3c, +- 0x3d, 0x2e, 0x7b, 0x51, 0x87, 0x27, 0x39, 0xe1, 0xb1, 0x3f, 0xd8, 0x8b, +- 0xfa, 0xd2, 0x3e, 0x63, 0xec, 0xb3, 0xb5, 0x58, 0x89, 0x91, 0x31, 0x74, +- 0xa1, 0x30, 0x1c, 0xaa, 0x7b, 0x19, 0xd0, 0xdd, 0xd1, 0x50, 0x60, 0xd8, +- 0xd9, 0xd3, 0x35, 0xbd, 0x8b, 0x9c, 0xfa, 0xd5, 0xe4, 0xc5, 0x7f, 0x5c, +- 0x27, 0x25, 0x86, 0xd1, 0x56, 0xaf, 0xc4, 0xe6, 0x17, 0xb3, 0x9d, 0xba, +- 0x30, 0xf4, 0x82, 0x68, 0x5e, 0x47, 0xa1, 0xba, 0x0f, 0x38, 0x9f, 0x47, +- 0x9b, 0x43, 0x81, 0x21, 0xe7, 0x8c, 0xa7, 0xe8, 0xc5, 0xf4, 0xe6, 0xe6, +- 0x5e, 0x17, 0xbe, 0xcd, 0x7c, 0x32, 0x8e, 0x91, 0x84, 0x97, 0x63, 0xa9, +- 0xd7, 0xb6, 0xa3, 0x82, 0x36, 0x8e, 0xd8, 0xe6, 0x06, 0xe2, 0x77, 0x02, +- 0x31, 0xd7, 0x8d, 0xe5, 0x88, 0x93, 0x40, 0xbb, 0x8c, 0x38, 0x39, 0x51, +- 0x7d, 0xdd, 0x0e, 0xda, 0x6f, 0xda, 0x1f, 0x0c, 0x58, 0x88, 0xe3, 0xc5, +- 0xc4, 0xc2, 0xff, 0xc7, 0x05, 0xcb, 0x2c, 0x81, 0xbc, 0x5f, 0x90, 0xbe, +- 0x67, 0x59, 0x28, 0xa8, 0xbf, 0x32, 0xb9, 0x27, 0xdd, 0x9d, 0xf8, 0xad, +- 0xbc, 0xc7, 0xc4, 0x7a, 0x7f, 0xac, 0x8c, 0xf4, 0xed, 0xc5, 0xa1, 0xbe, +- 0x3e, 0x6c, 0x79, 0x82, 0x32, 0x1a, 0x36, 0x16, 0x9a, 0x5d, 0xcc, 0xa5, +- 0x7d, 0x58, 0xa7, 0xcd, 0x8e, 0xa8, 0x2c, 0x37, 0x94, 0xce, 0xad, 0x3b, +- 0x6e, 0x75, 0xf6, 0xbc, 0x7b, 0x98, 0xa3, 0x38, 0xf1, 0x53, 0xf3, 0x46, +- 0x63, 0xca, 0xce, 0x4c, 0x8b, 0xb2, 0x23, 0x2d, 0x6d, 0x75, 0x2a, 0x3d, +- 0x99, 0xbf, 0xa5, 0x4f, 0x58, 0x38, 0x6d, 0xca, 0xbb, 0x39, 0xd2, 0xae, +- 0x85, 0xe1, 0xe6, 0x7f, 0xcd, 0x3b, 0x3a, 0xa2, 0xd3, 0x4e, 0x6c, 0x1e, +- 0x7c, 0x1c, 0xdd, 0x83, 0xa7, 0x9c, 0x33, 0x46, 0x1e, 0xc3, 0x6b, 0x5d, +- 0x1f, 0x0d, 0x1e, 0xb1, 0x90, 0x2d, 0x97, 0xf3, 0xf9, 0x55, 0xd1, 0x13, +- 0xd8, 0xa9, 0xc9, 0xbb, 0x27, 0x3d, 0xe4, 0x11, 0xb2, 0x6f, 0xbb, 0x1a, +- 0x5f, 0xef, 0x95, 0x39, 0x2c, 0xb3, 0x0a, 0xa3, 0xc1, 0xd8, 0x3a, 0x67, +- 0x0e, 0x1b, 0x70, 0x32, 0xfb, 0x38, 0xde, 0xdb, 0xd3, 0x05, 0x35, 0x1c, +- 0x0c, 0xdc, 0x06, 0xbb, 0xeb, 0xb8, 0x19, 0xb3, 0x3c, 0x08, 0x1e, 0x76, +- 0xa9, 0xc0, 0x0b, 0x7b, 0xe0, 0x9d, 0xc1, 0xf9, 0x9f, 0xcf, 0x18, 0x5d, +- 0x6e, 0xd8, 0x0b, 0xfe, 0xb1, 0x29, 0xd8, 0x63, 0xb8, 0xac, 0xbf, 0x99, +- 0x8e, 0x60, 0x5f, 0x44, 0x35, 0xda, 0xef, 0x52, 0xa1, 0xf8, 0xa2, 0xf2, +- 0x5e, 0x69, 0x17, 0xee, 0x6c, 0xf4, 0x59, 0xa5, 0xd1, 0x60, 0xdf, 0x29, +- 0x25, 0x58, 0x67, 0xa9, 0x6d, 0x9c, 0xe7, 0x3a, 0xbc, 0x42, 0x0e, 0xd2, +- 0xca, 0xd8, 0xbb, 0x34, 0xa9, 0x3b, 0xeb, 0x4c, 0xaa, 0x51, 0x13, 0x29, +- 0x52, 0x34, 0xdc, 0x96, 0x05, 0x8e, 0xa6, 0x57, 0xe3, 0x9d, 0x3d, 0x26, +- 0xf3, 0x54, 0x9d, 0xb8, 0xf5, 0xbd, 0x32, 0xc1, 0x80, 0x0e, 0xd3, 0xaa, +- 0x57, 0x19, 0xfb, 0x3d, 0x2a, 0x16, 0xce, 0x8c, 0x86, 0xc6, 0x17, 0xb8, +- 0xdc, 0x88, 0x64, 0x65, 0xfd, 0x53, 0x97, 0xb3, 0xc9, 0xb8, 0x2b, 0xe9, +- 0x25, 0xff, 0xac, 0xc6, 0x6f, 0xc8, 0x83, 0x7f, 0x4d, 0xbe, 0x3b, 0xc1, +- 0x78, 0x3e, 0x91, 0x29, 0x66, 0xbe, 0xe8, 0x91, 0x1c, 0x78, 0xdc, 0xc3, +- 0xb9, 0x28, 0x6b, 0xf4, 0xe3, 0xdc, 0xb0, 0x17, 0x77, 0xec, 0x09, 0xee, +- 0x9b, 0x50, 0xab, 0xf0, 0xc9, 0x70, 0x31, 0x96, 0x0f, 0x78, 0x29, 0x9b, +- 0x8d, 0x5d, 0xc4, 0xff, 0x8f, 0xf8, 0xac, 0x65, 0x0f, 0x94, 0xcc, 0xdc, +- 0x59, 0xe4, 0xec, 0x06, 0xeb, 0x97, 0x60, 0xd9, 0x80, 0xf0, 0x34, 0x15, +- 0x1f, 0x0e, 0x2b, 0xf8, 0x20, 0x6d, 0x62, 0x21, 0xfb, 0xdb, 0x9c, 0x7a, +- 0xc1, 0xf6, 0xd2, 0xcf, 0xd7, 0x64, 0x4c, 0x3c, 0x98, 0xd6, 0x19, 0x53, +- 0xde, 0xb6, 0x5d, 0x46, 0x23, 0xde, 0xde, 0x6d, 0x9c, 0x78, 0xd7, 0x15, +- 0x1a, 0x9f, 0xeb, 0x6a, 0xc4, 0x5b, 0x07, 0x1b, 0xf1, 0xb3, 0xfe, 0x05, +- 0xb8, 0xb9, 0x31, 0x86, 0xf3, 0x73, 0x1b, 0xf1, 0xe6, 0x7e, 0x1d, 0x3b, +- 0x52, 0xcd, 0xd0, 0x47, 0xc7, 0xc9, 0x4f, 0x23, 0xa8, 0x67, 0x4e, 0x65, +- 0xf4, 0xdb, 0x5d, 0x25, 0xd1, 0x2e, 0xec, 0x34, 0xa3, 0x98, 0xb3, 0x5f, +- 0xf4, 0x60, 0xdb, 0xeb, 0xe6, 0x46, 0xf1, 0x72, 0x9f, 0x41, 0x3f, 0x8d, +- 0x52, 0x0f, 0x3a, 0x9e, 0x24, 0x36, 0x87, 0x9e, 0x30, 0x2e, 0x1c, 0xe0, +- 0xef, 0x05, 0x07, 0x9a, 0xd1, 0xce, 0xfe, 0x13, 0xa9, 0x18, 0xf6, 0x8d, +- 0x36, 0x70, 0xcc, 0x26, 0xc7, 0x5f, 0x63, 0xfd, 0x46, 0x69, 0x41, 0xdf, +- 0x68, 0x2b, 0xf9, 0x66, 0x17, 0x79, 0x66, 0x2b, 0x7a, 0xd9, 0xd6, 0xd6, +- 0x94, 0x89, 0x65, 0xc9, 0x56, 0x3c, 0x9d, 0x90, 0x33, 0x8d, 0x46, 0x64, +- 0x9e, 0x22, 0xef, 0x7d, 0xb5, 0xe2, 0x10, 0x75, 0xb2, 0x70, 0x60, 0x39, +- 0xed, 0xd0, 0x8b, 0x45, 0x7b, 0x74, 0x3c, 0x95, 0xba, 0x13, 0xef, 0x8c, +- 0x98, 0x68, 0x4b, 0x8a, 0xbe, 0xe5, 0x5c, 0x4d, 0x1c, 0xc7, 0x19, 0x5b, +- 0x7e, 0x33, 0x10, 0xfb, 0x1b, 0x4e, 0xf3, 0x49, 0x15, 0xc1, 0xce, 0x19, +- 0x9c, 0xf0, 0x9b, 0x1a, 0xe5, 0x6c, 0x94, 0x8b, 0xa8, 0x16, 0xb4, 0xca, +- 0x55, 0x4b, 0xe7, 0x7d, 0xcb, 0xad, 0x6e, 0xc2, 0x37, 0x06, 0xdc, 0xe4, +- 0xf4, 0x2a, 0x73, 0x11, 0xab, 0x83, 0xb6, 0x61, 0x95, 0xa9, 0xb9, 0x79, +- 0xdb, 0x2e, 0xef, 0xa1, 0x19, 0x2e, 0xec, 0x32, 0x6b, 0xda, 0x4a, 0x58, +- 0x6f, 0x69, 0x38, 0x18, 0x2b, 0x52, 0x9b, 0x99, 0x27, 0x3e, 0x8e, 0x75, +- 0x7b, 0x1e, 0xc7, 0x1a, 0x7e, 0x3a, 0xf6, 0xd8, 0x5d, 0x4b, 0x4c, 0x05, +- 0x2f, 0x1a, 0x76, 0x57, 0x97, 0x69, 0x70, 0x6e, 0x65, 0x5e, 0x1f, 0x47, +- 0xe7, 0xa1, 0xc7, 0xf1, 0x28, 0xed, 0xab, 0x92, 0x7e, 0xbc, 0x32, 0x69, +- 0x77, 0xdd, 0xdc, 0x58, 0x87, 0x4f, 0x9d, 0xfc, 0x43, 0xec, 0x75, 0xab, +- 0x93, 0x13, 0xa7, 0x55, 0xb9, 0xde, 0xed, 0x5c, 0x5b, 0xea, 0x2b, 0x65, +- 0xf9, 0xd8, 0xf2, 0x5b, 0xb6, 0xfb, 0xbb, 0x3d, 0xe5, 0x78, 0xa2, 0x52, +- 0xe2, 0x87, 0xac, 0xed, 0x42, 0x31, 0xe6, 0x32, 0xcf, 0x7a, 0xe2, 0x38, +- 0xb6, 0x93, 0xb7, 0xf9, 0xc3, 0x92, 0x03, 0xd7, 0x9b, 0x5b, 0xd4, 0x5b, +- 0x89, 0xed, 0x0a, 0x76, 0xd6, 0xf6, 0xa1, 0x97, 0xbe, 0xba, 0xab, 0x36, +- 0x18, 0xef, 0x45, 0xd4, 0xde, 0x35, 0xbd, 0xe7, 0xdf, 0xf0, 0x5e, 0x96, +- 0xbc, 0xb7, 0x9d, 0x7f, 0x37, 0xeb, 0x71, 0x74, 0xed, 0x91, 0xf9, 0x7f, +- 0x1c, 0x8f, 0x51, 0xfe, 0xce, 0x81, 0xc7, 0xf1, 0x4d, 0xda, 0x4e, 0x45, +- 0xd3, 0xd1, 0xc7, 0x2a, 0x30, 0xbb, 0xaf, 0x1c, 0xe3, 0x0f, 0x57, 0xca, +- 0x39, 0x28, 0x62, 0x62, 0xaf, 0xf2, 0x38, 0xd6, 0x0f, 0x1d, 0xa0, 0x2f, +- 0x3a, 0xfe, 0x47, 0x2c, 0xce, 0xc7, 0xab, 0x00, 0xd6, 0x11, 0x93, 0x73, +- 0xb8, 0xee, 0xc7, 0x9a, 0xc4, 0x61, 0xc7, 0xf7, 0x0b, 0xa2, 0xab, 0xe8, +- 0xf7, 0x6d, 0xf4, 0xfb, 0xe5, 0xf4, 0xfb, 0x56, 0xfa, 0x7d, 0x0b, 0xfd, +- 0x3e, 0x46, 0xbf, 0x8f, 0xd2, 0xef, 0x23, 0xf4, 0xfb, 0x66, 0xfa, 0xbd, +- 0x49, 0xbf, 0x87, 0x72, 0xa2, 0xf9, 0x38, 0x3c, 0xfd, 0x5e, 0xda, 0x50, +- 0xee, 0x3d, 0x99, 0x83, 0xc4, 0x9f, 0xd3, 0xe6, 0x9c, 0xc0, 0x62, 0xc6, +- 0xd5, 0x61, 0x62, 0x44, 0x7a, 0xe4, 0xaf, 0x9c, 0x77, 0x2a, 0xd2, 0xc4, +- 0xfd, 0x57, 0xa8, 0x8f, 0xa5, 0xe1, 0x1a, 0xf3, 0x69, 0xc6, 0xb0, 0x5f, +- 0x18, 0xf5, 0x3d, 0x7e, 0x96, 0xf9, 0x41, 0xaa, 0xbe, 0x6f, 0x1a, 0x0c, +- 0xab, 0x51, 0xdd, 0x0a, 0xac, 0xf4, 0x73, 0xcc, 0x72, 0xde, 0x6e, 0x25, +- 0x1e, 0x1b, 0x6c, 0xc3, 0x7f, 0x19, 0xd4, 0xa8, 0x8b, 0x9a, 0xf1, 0x5b, +- 0x5d, 0xf8, 0x71, 0x00, 0x2e, 0xff, 0x35, 0xc0, 0xe7, 0x55, 0x98, 0x73, +- 0x58, 0xde, 0xef, 0x4b, 0x57, 0xb9, 0x1a, 0x66, 0x42, 0x6c, 0x04, 0x44, +- 0x6a, 0x17, 0x33, 0xc1, 0x39, 0xce, 0x3b, 0x40, 0xb1, 0x55, 0x82, 0xe9, +- 0x45, 0xd8, 0x5a, 0xe7, 0xe0, 0xec, 0xb3, 0x72, 0x6e, 0xb0, 0x8a, 0x78, +- 0xe4, 0x8b, 0xb6, 0x62, 0x5b, 0xaf, 0x75, 0x7f, 0x15, 0x96, 0xa3, 0xa7, +- 0x37, 0xa7, 0x83, 0x87, 0xc3, 0x1a, 0xa9, 0x42, 0x48, 0x9f, 0xa3, 0xc0, +- 0xdd, 0xd1, 0x1c, 0xc1, 0x83, 0x99, 0x04, 0xfa, 0x38, 0xc6, 0x0d, 0xf4, +- 0xb3, 0x75, 0x7f, 0xfa, 0xdd, 0x4e, 0x7c, 0x33, 0xa1, 0xd3, 0xfe, 0x2f, +- 0xda, 0xe9, 0x8a, 0x39, 0x7d, 0x55, 0x30, 0x3a, 0x57, 0xa8, 0xf3, 0x98, +- 0xd3, 0x06, 0x8f, 0xc8, 0xc2, 0xf7, 0xf4, 0xa8, 0xd7, 0xaa, 0x20, 0x36, +- 0xcf, 0x1a, 0x80, 0x32, 0x9c, 0x94, 0xf7, 0x20, 0xba, 0xf0, 0xff, 0x99, +- 0x6d, 0x8e, 0xfd, 0x8c, 0xbb, 0x34, 0xcc, 0x4c, 0xca, 0x7d, 0x7b, 0xc1, +- 0x67, 0x4d, 0xc1, 0x3a, 0xdd, 0xb5, 0x81, 0xf7, 0xab, 0xf1, 0x23, 0xc6, +- 0xd9, 0xc0, 0xc0, 0x02, 0xa8, 0x4d, 0x5e, 0xdc, 0xdd, 0x50, 0x8a, 0xf8, +- 0x4a, 0xe1, 0xa1, 0x92, 0xef, 0xbb, 0xa9, 0xcf, 0xff, 0x17, 0x0f, 0x99, +- 0xcf, 0x61, 0xc2, 0x9f, 0x70, 0xf6, 0xdd, 0xd7, 0x99, 0x77, 0x28, 0x16, +- 0xaf, 0xb7, 0xa5, 0x2c, 0x6c, 0x30, 0x99, 0x0b, 0xdd, 0x53, 0xc9, 0x9c, +- 0x44, 0xca, 0x4b, 0xbb, 0x5b, 0x9d, 0xf6, 0x0e, 0xa6, 0xe4, 0x7a, 0xf7, +- 0x64, 0x9f, 0x77, 0x01, 0x95, 0x5e, 0xe2, 0xad, 0x82, 0x33, 0xb5, 0x09, +- 0xfa, 0x34, 0x7e, 0xec, 0x46, 0x4d, 0xba, 0x5f, 0x75, 0xfd, 0xf8, 0x1a, +- 0xcc, 0x31, 0x7f, 0xaf, 0xca, 0x7c, 0xc4, 0xf0, 0x54, 0x48, 0x41, 0xa5, +- 0x61, 0x9c, 0xff, 0x19, 0x7d, 0x6b, 0xc2, 0x95, 0xc0, 0x53, 0x63, 0xa7, +- 0xec, 0xf1, 0x6b, 0xfc, 0x9c, 0x73, 0xa9, 0xdb, 0x86, 0x0f, 0x06, 0x65, +- 0xce, 0x64, 0x9d, 0x9f, 0xb1, 0x5d, 0xd5, 0x51, 0xca, 0x7b, 0xa7, 0x87, +- 0x4d, 0xe6, 0x3a, 0x6d, 0xf8, 0xc7, 0xc1, 0x95, 0xf8, 0xfd, 0x60, 0x4d, +- 0xdb, 0x7f, 0x52, 0x6d, 0x7b, 0x69, 0xf8, 0x6b, 0xf8, 0x65, 0xa5, 0x86, +- 0xa7, 0x69, 0x43, 0xbf, 0x4f, 0x58, 0x4b, 0xaf, 0x21, 0x16, 0xfc, 0xef, +- 0x44, 0xf0, 0xc2, 0x49, 0x67, 0x5f, 0xa9, 0xde, 0xfc, 0xd0, 0x15, 0x8c, +- 0x9f, 0x51, 0x83, 0xd6, 0x36, 0x65, 0x39, 0xec, 0x4c, 0x2b, 0xce, 0x67, +- 0xa6, 0xda, 0x42, 0x97, 0x8d, 0x2a, 0xb1, 0x03, 0xb1, 0x07, 0xda, 0x22, +- 0x73, 0xb9, 0x9f, 0x92, 0x47, 0x77, 0x7f, 0x95, 0xf6, 0x98, 0xa2, 0x3d, +- 0xa6, 0x68, 0x8f, 0xc4, 0xa4, 0xe7, 0x89, 0x55, 0x3f, 0x48, 0xd1, 0x1e, +- 0xe9, 0x3f, 0xcf, 0xd1, 0x7f, 0x72, 0x5c, 0xb9, 0xdd, 0x39, 0xb7, 0xf6, +- 0x06, 0x63, 0x62, 0xe2, 0x09, 0x79, 0x27, 0xad, 0x66, 0x43, 0x16, 0xc1, +- 0xf6, 0x5e, 0xe5, 0xb3, 0x72, 0x39, 0x67, 0xfb, 0xed, 0x90, 0xf8, 0x40, +- 0x6e, 0x3f, 0xe0, 0xc8, 0xc8, 0x63, 0x65, 0xf2, 0x7e, 0xd4, 0xc1, 0xbd, +- 0xff, 0x92, 0xce, 0xfe, 0x3b, 0xe5, 0x10, 0x7d, 0xfd, 0x5b, 0xc7, 0x2e, +- 0xba, 0xfc, 0x1b, 0xfb, 0x97, 0x55, 0x32, 0xfe, 0x55, 0xf8, 0x62, 0xb0, +- 0x05, 0xe7, 0x19, 0x7f, 0xdf, 0x6a, 0x1a, 0xef, 0x0c, 0x20, 0xd8, 0x51, +- 0xae, 0x46, 0x91, 0xcd, 0xb4, 0xe0, 0xb3, 0x44, 0x14, 0x07, 0x12, 0x35, +- 0xed, 0x35, 0xae, 0xb3, 0x6a, 0x7c, 0x86, 0x58, 0x54, 0x0c, 0x9f, 0x92, +- 0x5f, 0x2e, 0xac, 0x8d, 0x60, 0x88, 0x6d, 0x7a, 0xa2, 0x1a, 0x46, 0x9a, +- 0xc5, 0x56, 0x73, 0xef, 0x4e, 0xfd, 0xa9, 0xbf, 0x2e, 0xda, 0xe3, 0x7b, +- 0x4d, 0x17, 0xed, 0x71, 0xcd, 0x6b, 0x69, 0xf4, 0xe1, 0xd2, 0x3d, 0xf2, +- 0x6e, 0xa9, 0xf8, 0xb3, 0x82, 0x1f, 0x84, 0xc7, 0xdb, 0xa6, 0x21, 0xf8, +- 0xec, 0x7d, 0xb4, 0xf5, 0x93, 0x49, 0x59, 0x53, 0x6c, 0xc1, 0xfb, 0x2c, +- 0xef, 0xa6, 0x5f, 0x9c, 0xcc, 0xb8, 0xdd, 0xbf, 0x4c, 0x2a, 0xcc, 0x4b, +- 0x97, 0xe3, 0x97, 0x99, 0x37, 0xd5, 0x8f, 0x35, 0x13, 0x67, 0xb2, 0x2b, +- 0x69, 0x4f, 0x92, 0xff, 0xc7, 0x98, 0xff, 0x07, 0x3b, 0x8f, 0x60, 0x25, +- 0xca, 0x0f, 0xad, 0x42, 0xd9, 0x1e, 0xe2, 0x67, 0x88, 0xf9, 0x3f, 0xaf, +- 0x67, 0xec, 0x91, 0xf7, 0x0d, 0xca, 0xed, 0xed, 0xab, 0x44, 0x2f, 0x82, +- 0x27, 0x7f, 0x57, 0x8e, 0xb2, 0x55, 0xc0, 0x21, 0xa9, 0x67, 0xb0, 0xde, +- 0x4a, 0x54, 0xee, 0xa9, 0x89, 0x2c, 0x46, 0xcd, 0xf9, 0xdb, 0xd4, 0x95, +- 0xb8, 0xfe, 0xd0, 0x3f, 0x73, 0x0e, 0xa4, 0x6c, 0x35, 0x9e, 0xa0, 0xdd, +- 0x16, 0x92, 0x13, 0xb6, 0x24, 0x7f, 0x6d, 0xcf, 0xa4, 0x2f, 0x7e, 0xf6, +- 0x15, 0x60, 0x5d, 0xd6, 0x60, 0xbc, 0x2b, 0x46, 0x7c, 0xe8, 0x29, 0xbb, +- 0x3c, 0xea, 0xc6, 0x9a, 0x6c, 0x03, 0x16, 0x0f, 0xd8, 0xf6, 0xb9, 0xb9, +- 0x31, 0xf8, 0xa2, 0x3e, 0x62, 0x98, 0x0f, 0x8f, 0x26, 0x4b, 0xf8, 0x2d, +- 0xc7, 0x4f, 0x42, 0xe3, 0xb3, 0x55, 0x63, 0xc3, 0x0c, 0x97, 0xd1, 0x9e, +- 0x55, 0x24, 0xee, 0xfb, 0xf0, 0x08, 0xe3, 0xf3, 0xd2, 0x64, 0x00, 0xf1, +- 0xac, 0x6d, 0xbf, 0xd9, 0xec, 0xc7, 0xc3, 0xac, 0xdf, 0x9a, 0xec, 0x41, +- 0x37, 0xed, 0x22, 0x7e, 0xc8, 0xd0, 0x35, 0xc6, 0xfb, 0x75, 0x59, 0x2f, +- 0x63, 0x58, 0x25, 0x6e, 0x63, 0x2c, 0x7a, 0x54, 0xce, 0xca, 0xd0, 0x07, +- 0xdf, 0x31, 0xad, 0x1b, 0x5c, 0x30, 0xd0, 0x99, 0xf5, 0x63, 0x79, 0x32, +- 0x78, 0x41, 0xde, 0xcd, 0xfb, 0xcc, 0xac, 0xc3, 0xc6, 0x6c, 0x00, 0xb7, +- 0x27, 0x8f, 0x3e, 0x3a, 0x13, 0xd6, 0x7f, 0x9e, 0x81, 0x06, 0x7c, 0x3d, +- 0x5b, 0xcd, 0xf6, 0x83, 0x1b, 0xde, 0x50, 0xaa, 0xf1, 0x8d, 0x43, 0x26, +- 0xdb, 0x57, 0xb1, 0x8c, 0xed, 0x2c, 0x49, 0x5e, 0x8f, 0x47, 0x0e, 0x35, +- 0xe3, 0xc1, 0x6c, 0x13, 0x16, 0x31, 0x3e, 0x75, 0x30, 0x37, 0xc4, 0xbd, +- 0xc0, 0xed, 0x03, 0xa2, 0x7b, 0x28, 0x6f, 0x36, 0x8f, 0x33, 0x5f, 0x36, +- 0x41, 0x43, 0x74, 0xf6, 0x92, 0x77, 0xd2, 0x56, 0x6f, 0xdf, 0xdf, 0x84, +- 0xa5, 0x03, 0x2a, 0x6a, 0xc2, 0x85, 0x88, 0xb7, 0x29, 0x68, 0x19, 0x90, +- 0x38, 0x2b, 0xdc, 0xc6, 0x64, 0x5c, 0x0d, 0xb1, 0x0f, 0x93, 0x71, 0x35, +- 0x77, 0xbf, 0x3b, 0x25, 0x6b, 0x0b, 0x6f, 0x93, 0x2f, 0x85, 0xd1, 0xe2, +- 0xc4, 0x68, 0x59, 0x13, 0xb7, 0xe0, 0x66, 0xec, 0x0e, 0xd3, 0xc6, 0x17, +- 0x34, 0x4a, 0xac, 0xd6, 0x9d, 0xbd, 0xa9, 0xb1, 0x7e, 0xa3, 0xe3, 0x82, +- 0x42, 0xfb, 0xda, 0x2f, 0x31, 0xd1, 0x8f, 0x8d, 0xc9, 0x28, 0xde, 0xe9, +- 0x63, 0xbc, 0xb9, 0x31, 0xb6, 0xb4, 0x04, 0x86, 0xf9, 0x08, 0x42, 0xd6, +- 0x49, 0xc6, 0xf6, 0xf3, 0xe9, 0x4a, 0x2c, 0xde, 0x23, 0x65, 0x1a, 0xf1, +- 0xee, 0xb0, 0xec, 0x4d, 0x6e, 0xc2, 0x53, 0x7d, 0x2e, 0x0c, 0x99, 0x35, +- 0x3d, 0x2a, 0xe3, 0xe7, 0xfc, 0xc6, 0xa0, 0xf6, 0x23, 0x72, 0xd5, 0x0b, +- 0x4d, 0x8c, 0xca, 0xd7, 0x34, 0xa3, 0x85, 0x72, 0xb5, 0x18, 0xe2, 0x93, +- 0x16, 0x1e, 0x6c, 0xde, 0x84, 0x93, 0x7d, 0x86, 0xf5, 0xb4, 0xac, 0x03, +- 0x34, 0xf2, 0xf9, 0x74, 0x37, 0x36, 0x1b, 0xc2, 0x69, 0x75, 0xfa, 0x16, +- 0x59, 0xa7, 0xd1, 0x8c, 0x77, 0x68, 0xaf, 0x3d, 0xe9, 0x05, 0x8c, 0xfd, +- 0x12, 0xf3, 0xbd, 0x56, 0x80, 0xf5, 0xca, 0xbf, 0xa2, 0xe0, 0xf4, 0x01, +- 0xe1, 0x58, 0x0b, 0x70, 0xff, 0x80, 0xec, 0x0b, 0xa8, 0x98, 0x7f, 0x68, +- 0x35, 0xce, 0xed, 0xce, 0x71, 0xae, 0x37, 0xc3, 0xd6, 0xd7, 0xc9, 0xb9, +- 0xda, 0x4b, 0xc9, 0xb9, 0xc8, 0xe5, 0xea, 0x36, 0x2a, 0x6e, 0x84, 0xb2, +- 0x11, 0xf2, 0x0a, 0xe1, 0x17, 0x01, 0x3c, 0x93, 0x69, 0xc6, 0x6d, 0xc9, +- 0x6a, 0x8c, 0x90, 0x6f, 0xa5, 0x89, 0x17, 0xe9, 0x0c, 0xe3, 0xca, 0x70, +- 0x15, 0x3f, 0x3a, 0x3f, 0xb3, 0xf8, 0x31, 0x9c, 0x7b, 0x6b, 0x68, 0xcb, +- 0xb1, 0x36, 0xc5, 0xd9, 0xdb, 0x18, 0xca, 0x48, 0xac, 0x56, 0x98, 0xb7, +- 0xde, 0xa5, 0x49, 0x6e, 0x2a, 0xe7, 0x0e, 0x7e, 0xde, 0xa7, 0xe3, 0x5b, +- 0x8d, 0x3b, 0x95, 0x58, 0xa5, 0xf3, 0x5e, 0x92, 0x55, 0x4c, 0xd9, 0x6e, +- 0x9b, 0x2b, 0x6b, 0x94, 0x62, 0x97, 0x6c, 0x83, 0x39, 0xfa, 0xc3, 0x66, +- 0x05, 0xf4, 0x0a, 0x5d, 0xce, 0x50, 0xd2, 0xdf, 0xfd, 0x78, 0x35, 0x11, +- 0x47, 0x26, 0x51, 0xdf, 0xb3, 0x51, 0x71, 0xc9, 0xd9, 0xf3, 0xba, 0xb8, +- 0x22, 0x3e, 0x16, 0x87, 0x27, 0xe9, 0xb5, 0xca, 0x59, 0xff, 0x9d, 0xb9, +- 0x1d, 0x8c, 0x07, 0xf5, 0x9c, 0x62, 0xd5, 0x39, 0x7f, 0x9e, 0x46, 0x07, +- 0xd6, 0x25, 0x0c, 0xc6, 0xc0, 0xd5, 0x76, 0x37, 0xe7, 0xe1, 0x58, 0xa2, +- 0x03, 0xf7, 0x27, 0xea, 0xc7, 0x9f, 0xa4, 0x6d, 0xe1, 0xee, 0x0e, 0xb4, +- 0xf0, 0xd9, 0x50, 0xaa, 0xe6, 0x42, 0x37, 0x75, 0x3d, 0x31, 0xad, 0xce, +- 0x59, 0x97, 0x77, 0x1b, 0x3a, 0xcb, 0xeb, 0xc4, 0xb3, 0xfa, 0xd8, 0x80, +- 0xfa, 0xef, 0x15, 0x4c, 0x97, 0x5c, 0x32, 0x82, 0xe3, 0x09, 0x1f, 0xbe, +- 0x9e, 0xb4, 0xe8, 0x03, 0xc0, 0xfa, 0x6c, 0x33, 0xf3, 0x88, 0xa7, 0xec, +- 0x0a, 0x87, 0xeb, 0xba, 0x69, 0x83, 0x0b, 0x70, 0x82, 0xb1, 0xb7, 0x66, +- 0x9e, 0xa1, 0x2d, 0x52, 0xe4, 0x7d, 0xeb, 0x5f, 0xdb, 0xee, 0x68, 0x09, +- 0x36, 0x0c, 0x85, 0x22, 0x2b, 0x19, 0x67, 0x9f, 0x6a, 0x36, 0xc6, 0x6d, +- 0xc6, 0xc0, 0x19, 0xd1, 0x04, 0xe7, 0x3a, 0x24, 0xff, 0xaf, 0x03, 0x7f, +- 0x41, 0x3b, 0xff, 0x24, 0x21, 0x7e, 0x62, 0x10, 0x37, 0xfd, 0xf8, 0x06, +- 0xed, 0xfc, 0x7c, 0xa2, 0x0e, 0x59, 0xfa, 0x65, 0x07, 0xfd, 0xe3, 0xdd, +- 0x44, 0x30, 0x7e, 0x93, 0xca, 0x7c, 0x8f, 0xfe, 0xf1, 0x51, 0x22, 0x42, +- 0xdf, 0xf9, 0x2a, 0x3f, 0x0d, 0xf4, 0x87, 0x3a, 0xd6, 0xd1, 0xe9, 0x07, +- 0x7e, 0x9c, 0x65, 0xf9, 0x03, 0xa9, 0x9a, 0xd6, 0x15, 0x4a, 0x8d, 0x59, +- 0xa3, 0x54, 0x30, 0x9f, 0xd5, 0x68, 0xff, 0xb7, 0xe0, 0x43, 0x59, 0x4f, +- 0x4e, 0x12, 0x8b, 0x92, 0xe8, 0x2f, 0x22, 0x97, 0x5b, 0xe9, 0x9c, 0xe5, +- 0xaf, 0x3f, 0xf1, 0xa9, 0x12, 0x1c, 0x3f, 0xe3, 0x0a, 0x76, 0xcc, 0x20, +- 0x8f, 0xfe, 0x0b, 0xfa, 0xc1, 0x37, 0x59, 0xf6, 0x93, 0xbe, 0x62, 0x7c, +- 0x63, 0x88, 0x31, 0x37, 0x55, 0x80, 0x82, 0x3d, 0x5e, 0x3c, 0x78, 0x48, +- 0xc7, 0x3e, 0x27, 0x57, 0x17, 0x9d, 0x52, 0x77, 0xc4, 0x88, 0x73, 0x73, +- 0x81, 0x19, 0x07, 0x56, 0xe3, 0xd4, 0x6e, 0x9d, 0x71, 0x2f, 0x67, 0x27, +- 0xcf, 0x86, 0x1d, 0x6e, 0x1e, 0x17, 0x6e, 0x5e, 0xc0, 0x71, 0x6d, 0x4d, +- 0x85, 0xda, 0xb7, 0x51, 0x17, 0xb7, 0x67, 0xc5, 0xfe, 0x22, 0x78, 0x8e, +- 0x63, 0xeb, 0xa7, 0xad, 0x1c, 0x48, 0x54, 0x33, 0x47, 0xf7, 0xc1, 0xa2, +- 0xad, 0x58, 0xf2, 0x0e, 0x13, 0x6d, 0xc5, 0xa2, 0xad, 0x58, 0xb4, 0x15, +- 0x8b, 0xb6, 0x62, 0x65, 0x16, 0xe0, 0x99, 0x3e, 0x03, 0x23, 0xec, 0x73, +- 0xe7, 0x30, 0x39, 0xbc, 0xf3, 0x3e, 0x50, 0x9d, 0xe4, 0x29, 0xca, 0xc4, +- 0xdd, 0xb7, 0x60, 0xa8, 0xef, 0x56, 0x7e, 0x14, 0xb4, 0xd2, 0x66, 0x7a, +- 0xd2, 0x62, 0x83, 0x22, 0x93, 0x17, 0xc3, 0x99, 0x9b, 0x2b, 0x51, 0x2c, +- 0xf1, 0x5d, 0xc1, 0x0e, 0xe7, 0x7e, 0xde, 0xd6, 0xe4, 0x9e, 0x85, 0x9a, +- 0x79, 0x9b, 0xf0, 0x48, 0x9f, 0x8a, 0xdb, 0xc2, 0xf2, 0x7f, 0x08, 0x9a, +- 0x99, 0x0f, 0xc8, 0xfe, 0x7c, 0x82, 0xfe, 0x99, 0xb3, 0x15, 0x19, 0x53, +- 0xa6, 0x7f, 0x13, 0x4e, 0xf4, 0x1b, 0x8c, 0x59, 0x26, 0x32, 0xe9, 0x04, +- 0x7d, 0x42, 0xfc, 0xdc, 0xc0, 0x33, 0x6c, 0x6b, 0xf6, 0x80, 0x0b, 0x95, +- 0x8d, 0x6e, 0x94, 0xd0, 0xdf, 0x6f, 0x4b, 0xd7, 0x04, 0xbe, 0xa5, 0x24, +- 0x9c, 0xf5, 0xd7, 0x5d, 0x29, 0x8c, 0xcf, 0x34, 0x2a, 0xb1, 0x6f, 0xb0, +- 0x11, 0x8f, 0xed, 0x76, 0xd1, 0x46, 0xed, 0x05, 0xe5, 0x4d, 0x46, 0xc7, +- 0x02, 0x97, 0xe0, 0x45, 0x23, 0xbe, 0xc1, 0x1c, 0x60, 0x7d, 0x7f, 0xd0, +- 0x7c, 0x05, 0x41, 0xf3, 0x24, 0x16, 0xe0, 0x59, 0x93, 0xb8, 0x39, 0xaf, +- 0x11, 0x1b, 0xf7, 0x1b, 0xb4, 0x29, 0x37, 0xf3, 0x63, 0xf9, 0xbf, 0x37, +- 0xba, 0xb3, 0xc6, 0xf3, 0x32, 0xe4, 0x9c, 0x43, 0xb3, 0xfc, 0x4f, 0x06, +- 0xa5, 0x87, 0xf8, 0x34, 0xa3, 0xd7, 0xe0, 0xb8, 0x5f, 0xb0, 0x4b, 0x0d, +- 0xf9, 0x7f, 0x1c, 0xc4, 0x11, 0x8e, 0xfb, 0xc2, 0xcd, 0x6f, 0xdb, 0x95, +- 0x86, 0xc4, 0x50, 0xe2, 0x49, 0x5a, 0xfa, 0x8f, 0xed, 0x08, 0x10, 0x3b, +- 0x3a, 0xfa, 0x8d, 0x78, 0x29, 0x63, 0xd8, 0x46, 0x07, 0x63, 0x04, 0x5f, +- 0x8c, 0xb6, 0x6f, 0x21, 0xa4, 0xad, 0x20, 0xee, 0x9c, 0xe6, 0x58, 0x7a, +- 0x52, 0x82, 0x51, 0x3a, 0x8a, 0x7a, 0x63, 0xb8, 0x81, 0x39, 0x63, 0x41, +- 0x6f, 0x0b, 0x6a, 0x99, 0x3f, 0xba, 0x7b, 0x5b, 0x61, 0x30, 0x97, 0x9c, +- 0xd9, 0xbb, 0x1c, 0x0b, 0xc6, 0xf2, 0x1c, 0x5a, 0xc7, 0x11, 0x67, 0xdd, +- 0xea, 0x29, 0x78, 0xee, 0xd3, 0x69, 0x53, 0x72, 0xe6, 0xc5, 0x6b, 0x55, +- 0x12, 0x37, 0xcf, 0x50, 0xd7, 0xed, 0x03, 0xab, 0xed, 0x81, 0x94, 0xf0, +- 0xa6, 0x2e, 0x78, 0x9a, 0x24, 0xf7, 0xd1, 0x31, 0x46, 0x8e, 0x3c, 0xcc, +- 0x1c, 0xec, 0x8d, 0xfd, 0xab, 0x71, 0xff, 0x9e, 0xcb, 0x39, 0x9b, 0xd9, +- 0x64, 0xfd, 0x7b, 0xda, 0xc5, 0x86, 0x12, 0xda, 0x85, 0x97, 0x76, 0xb1, +- 0x2b, 0x15, 0x32, 0x0f, 0xd3, 0x2e, 0x6a, 0x89, 0x21, 0x1d, 0xbd, 0x92, +- 0xef, 0x38, 0xef, 0xed, 0x55, 0x78, 0x10, 0xc0, 0x9b, 0xb4, 0x8f, 0x8d, +- 0xbd, 0x76, 0x97, 0x9b, 0xb1, 0xa7, 0xa7, 0xb9, 0x1a, 0xaf, 0x65, 0x6e, +- 0xc5, 0xa3, 0xfd, 0xd5, 0x78, 0x85, 0xb6, 0xf3, 0x76, 0x02, 0xf3, 0x2b, +- 0xa0, 0xce, 0xac, 0x60, 0xac, 0xbe, 0x4d, 0x09, 0xb5, 0x2e, 0x42, 0xfd, +- 0xf8, 0xcb, 0x4a, 0xb0, 0x93, 0x9c, 0xe5, 0xc4, 0x05, 0x62, 0xff, 0xeb, +- 0x19, 0x39, 0x77, 0xe7, 0xc3, 0x38, 0xed, 0x6a, 0x9c, 0xf5, 0xbe, 0xd1, +- 0x5f, 0xc7, 0x79, 0xf3, 0xa0, 0xd0, 0xf0, 0xe3, 0x14, 0xb1, 0xb4, 0x63, +- 0x37, 0xc6, 0x03, 0x86, 0x71, 0xa2, 0x55, 0xa9, 0xc2, 0x9b, 0xc3, 0xb7, +- 0x62, 0x63, 0x7f, 0x50, 0x8f, 0xd1, 0x37, 0x5f, 0xe3, 0xb3, 0xf5, 0xbb, +- 0x67, 0xe1, 0x38, 0x6d, 0x6f, 0x9c, 0xb6, 0xb7, 0xb6, 0x5f, 0xc5, 0x8b, +- 0xc3, 0xb7, 0xb0, 0x5f, 0x05, 0xb3, 0x6a, 0x15, 0x27, 0xff, 0xda, 0x91, +- 0x72, 0xfe, 0x77, 0x81, 0xf3, 0x8e, 0xde, 0x9c, 0x51, 0x13, 0xb3, 0xf7, +- 0xcb, 0xf8, 0xc8, 0xc3, 0x9c, 0xb5, 0xe9, 0x46, 0xdc, 0xbc, 0xa7, 0x12, +- 0xe7, 0xf6, 0x1a, 0x56, 0xb9, 0xcb, 0x5e, 0x70, 0x2a, 0x1c, 0xe2, 0x3c, +- 0x34, 0xa2, 0xe1, 0x50, 0x23, 0x42, 0x03, 0xb9, 0x18, 0xa1, 0x19, 0x0b, +- 0xf0, 0x3d, 0xce, 0xfb, 0x5a, 0xe6, 0x80, 0x35, 0x43, 0x82, 0xbd, 0x36, +- 0x73, 0xc5, 0x66, 0x4c, 0x8c, 0x8d, 0x73, 0x6c, 0x11, 0x9c, 0x25, 0xbf, +- 0x7d, 0x9f, 0x31, 0xe3, 0x43, 0xe6, 0x80, 0x1f, 0x3a, 0x31, 0x43, 0xde, +- 0xa5, 0xbd, 0x32, 0x6e, 0xec, 0xe2, 0x9c, 0x6e, 0xec, 0x37, 0xea, 0xfa, +- 0xf8, 0x7b, 0xbd, 0x33, 0xc7, 0x31, 0xe2, 0xb9, 0x60, 0x85, 0xe0, 0x7f, +- 0x0b, 0x73, 0xde, 0x56, 0x9c, 0xed, 0x0b, 0x99, 0x0b, 0x95, 0x56, 0xbc, +- 0x47, 0x99, 0xfb, 0x28, 0x5f, 0x92, 0xbc, 0x6c, 0x66, 0xd2, 0x18, 0xff, +- 0xd0, 0x25, 0x18, 0xd3, 0x8a, 0xf2, 0xec, 0xad, 0x38, 0xd5, 0xbf, 0x1c, +- 0xa5, 0x43, 0xc2, 0x35, 0xa5, 0x4d, 0x37, 0xb6, 0xee, 0xbe, 0x13, 0xeb, +- 0x0f, 0xe6, 0x72, 0xbe, 0xf5, 0x89, 0x4d, 0xcc, 0x75, 0x85, 0xbf, 0xd7, +- 0xe1, 0x50, 0x2a, 0x26, 0x47, 0x42, 0x77, 0x30, 0x9f, 0x8b, 0xac, 0x20, +- 0x7e, 0x2e, 0x0d, 0x13, 0x63, 0x2b, 0x82, 0x81, 0x97, 0x61, 0xe9, 0xbc, +- 0x17, 0x58, 0x07, 0xd1, 0x89, 0x85, 0x65, 0x8c, 0x3b, 0xb7, 0xf5, 0xbb, +- 0x29, 0xbb, 0x3c, 0xaf, 0xc3, 0x8f, 0x52, 0x56, 0x5c, 0x9e, 0x6f, 0x84, +- 0xf8, 0x8a, 0xe8, 0xc9, 0x05, 0xb3, 0xa9, 0x26, 0xd6, 0x41, 0x8c, 0x2e, +- 0x0d, 0x07, 0xcd, 0x6f, 0xa0, 0x99, 0x73, 0x2f, 0x32, 0x47, 0xb0, 0xfe, +- 0x10, 0x9c, 0x7d, 0x7f, 0x79, 0x47, 0xe4, 0x3f, 0xf4, 0xed, 0x76, 0xec, +- 0x69, 0x7d, 0xe3, 0x65, 0x1b, 0x3c, 0x90, 0xaa, 0xef, 0x74, 0xa1, 0xc6, +- 0x2a, 0x87, 0x91, 0xee, 0x23, 0x2f, 0x8d, 0x23, 0xd8, 0x13, 0x87, 0xc4, +- 0x8c, 0x7a, 0x4b, 0x43, 0x35, 0xdb, 0x8e, 0xe0, 0xad, 0x84, 0x4b, 0xb0, +- 0x09, 0xf2, 0x4f, 0x8a, 0x22, 0xc4, 0xe1, 0x37, 0x12, 0xc5, 0xd0, 0x87, +- 0x12, 0xce, 0xff, 0x11, 0xba, 0x39, 0x6b, 0x91, 0xaf, 0x2d, 0xc0, 0xab, +- 0xfd, 0x3e, 0xcc, 0x27, 0x4f, 0xa9, 0x4b, 0x3e, 0x65, 0x97, 0x12, 0x87, +- 0xeb, 0x87, 0x42, 0x9a, 0x47, 0xb1, 0xed, 0x03, 0x73, 0x7f, 0x6d, 0x4f, +- 0x8b, 0x4a, 0x59, 0x23, 0xb2, 0x48, 0xfe, 0x9f, 0xd4, 0x3c, 0xa3, 0xf5, +- 0x2c, 0x7c, 0xb8, 0x81, 0x58, 0x7a, 0xac, 0xb7, 0x12, 0x6f, 0xed, 0xee, +- 0x91, 0x35, 0x4b, 0x18, 0xfc, 0xfd, 0x5a, 0x6f, 0x00, 0x3a, 0xb1, 0x4c, +- 0xe7, 0x75, 0x03, 0x31, 0x5a, 0x27, 0x3e, 0xbf, 0xdd, 0x6b, 0x2f, 0xf0, +- 0x35, 0x59, 0x6c, 0xbd, 0x0e, 0x0b, 0x88, 0xd1, 0x6f, 0xf4, 0x06, 0x4f, +- 0x2c, 0x51, 0x15, 0x94, 0x34, 0x99, 0xec, 0xdb, 0x87, 0x17, 0x69, 0xdf, +- 0x4f, 0xa4, 0x8e, 0x7e, 0x6d, 0x06, 0xac, 0xfa, 0x12, 0x04, 0x37, 0x78, +- 0x14, 0x59, 0xe3, 0x90, 0xd8, 0x56, 0x8d, 0x1b, 0xc9, 0x4d, 0x74, 0xe2, +- 0x77, 0x4d, 0x56, 0xe2, 0x1c, 0xb0, 0x66, 0x68, 0x35, 0x3e, 0x1c, 0x14, +- 0x1f, 0xc5, 0x42, 0xb1, 0xff, 0x05, 0xe1, 0x90, 0x79, 0x86, 0xb8, 0x5c, +- 0x3b, 0x96, 0x20, 0xfe, 0xca, 0xb9, 0x3c, 0x8c, 0xab, 0xc4, 0x81, 0xca, +- 0x94, 0x60, 0x57, 0x00, 0x8d, 0xcc, 0xf7, 0xca, 0x53, 0xe2, 0x93, 0x96, +- 0x9c, 0x1b, 0xc1, 0xcd, 0x63, 0x3e, 0xe8, 0x63, 0x1a, 0x3f, 0x7e, 0xe8, +- 0x23, 0x55, 0xfc, 0x50, 0xd6, 0x91, 0x59, 0xfc, 0x50, 0x56, 0xc6, 0x31, +- 0x73, 0x44, 0xc1, 0x4d, 0x8e, 0x6d, 0x89, 0x0f, 0x7a, 0xf1, 0xec, 0x28, +- 0xb0, 0xa1, 0xdf, 0xc4, 0xe1, 0xfd, 0x39, 0x9c, 0xdb, 0xcc, 0x3e, 0x42, +- 0x03, 0x61, 0xac, 0x4f, 0x8b, 0x7d, 0x36, 0xe2, 0xb7, 0x7b, 0x8d, 0xb6, +- 0x35, 0x6a, 0x28, 0xb2, 0x9c, 0x18, 0xf6, 0xfe, 0x48, 0x23, 0x3e, 0x7c, +- 0x62, 0x01, 0x8c, 0x70, 0x23, 0xce, 0x1c, 0xd8, 0x84, 0xf2, 0x27, 0x54, +- 0xe2, 0x8f, 0x8a, 0xf1, 0xe9, 0x82, 0xed, 0x82, 0xa3, 0x5e, 0xab, 0x8c, +- 0xb8, 0xb5, 0x8d, 0xb8, 0xf5, 0xb3, 0xb9, 0xe3, 0x98, 0x9f, 0x94, 0x73, +- 0xad, 0xcc, 0xaf, 0xd4, 0x08, 0x9e, 0x24, 0x6e, 0xed, 0xea, 0x93, 0xf9, +- 0xe2, 0xdc, 0x12, 0xb3, 0xb6, 0xa6, 0x73, 0x9c, 0xe8, 0x70, 0xbf, 0xa1, +- 0xb9, 0x68, 0xcb, 0x43, 0x93, 0x78, 0xf5, 0x5b, 0xc6, 0xff, 0x47, 0xe6, +- 0x45, 0x71, 0x36, 0x2d, 0x7e, 0x25, 0x71, 0x45, 0xc7, 0x87, 0xb4, 0xf1, +- 0xa5, 0xd4, 0xf5, 0x19, 0xe6, 0x16, 0x2d, 0x8c, 0x73, 0x1f, 0xd3, 0x9e, +- 0x97, 0x93, 0x3f, 0xbe, 0x97, 0x12, 0x1b, 0x59, 0x8e, 0x25, 0x59, 0xb1, +- 0x05, 0x67, 0x9d, 0x95, 0xdf, 0x31, 0x9c, 0x4e, 0xfc, 0xb1, 0xb8, 0xb0, +- 0x12, 0xaf, 0x0e, 0xca, 0x79, 0x17, 0x03, 0xde, 0xde, 0xa0, 0x56, 0xa2, +- 0xc8, 0x9e, 0x6e, 0x9e, 0xfb, 0x4e, 0x38, 0x39, 0x76, 0x69, 0x34, 0xbf, +- 0xbf, 0x98, 0xdf, 0x77, 0xb0, 0xf0, 0xfd, 0xb9, 0x01, 0xf2, 0x4f, 0x28, +- 0x87, 0xe7, 0x16, 0xe0, 0xf6, 0x3d, 0x6d, 0x18, 0xd9, 0xfd, 0x31, 0x8a, +- 0xfa, 0xd5, 0x7b, 0x7d, 0xa8, 0xa9, 0x7b, 0x48, 0xe9, 0xc2, 0xa2, 0xb0, +- 0xbc, 0xe7, 0x23, 0x6b, 0xe6, 0x7d, 0xd8, 0x7c, 0x80, 0x79, 0xcc, 0xd8, +- 0x75, 0x38, 0xaa, 0x31, 0x1e, 0x9a, 0x1f, 0xa3, 0xa0, 0xdf, 0xe3, 0x9c, +- 0x05, 0x3c, 0x6a, 0x36, 0x61, 0xe5, 0xe4, 0x59, 0x40, 0x54, 0x5d, 0xbd, +- 0x97, 0x00, 0x5f, 0xe9, 0xe4, 0xff, 0x1f, 0xc8, 0xbd, 0xdb, 0x63, 0xa0, +- 0x77, 0xf4, 0x7f, 0x95, 0xe7, 0xce, 0x06, 0xfd, 0x6b, 0xca, 0x76, 0xa2, +- 0x7d, 0xcf, 0xe3, 0x58, 0xb1, 0xe7, 0x3b, 0xb8, 0x73, 0xa0, 0xb6, 0x33, +- 0xc2, 0x5c, 0xe7, 0x83, 0xf0, 0x38, 0x8e, 0x85, 0x8b, 0x60, 0xf9, 0xc9, +- 0xb1, 0x6e, 0xfc, 0x8a, 0xbc, 0x4e, 0xca, 0xbf, 0xd3, 0xb6, 0x7e, 0xaf, +- 0xb4, 0xf7, 0xf6, 0xa4, 0x7f, 0xfd, 0x7c, 0x9a, 0x9c, 0xa7, 0x79, 0x21, +- 0xf5, 0x2b, 0x5b, 0x77, 0x9e, 0xe7, 0xef, 0xbf, 0x65, 0xc7, 0xfc, 0x72, +- 0x7f, 0xd6, 0x64, 0xbd, 0xef, 0xe0, 0x01, 0xe6, 0xbf, 0xa7, 0x9b, 0xbe, +- 0x83, 0x85, 0x43, 0x97, 0xea, 0xa0, 0x68, 0xf7, 0x3a, 0x07, 0xbb, 0xe9, +- 0x61, 0xe4, 0x48, 0xb2, 0x57, 0x25, 0xfb, 0x27, 0x7f, 0x89, 0xcd, 0x7b, +- 0x65, 0x6d, 0xd3, 0xb6, 0xd7, 0x1b, 0xb2, 0xc7, 0x97, 0x3f, 0x37, 0x27, +- 0xed, 0x58, 0x8a, 0x95, 0x91, 0xba, 0x5b, 0x94, 0xbe, 0xcc, 0xd4, 0x31, +- 0x4d, 0x93, 0xff, 0x97, 0xa7, 0x95, 0x44, 0xa7, 0x8e, 0xad, 0x47, 0xd9, +- 0x9e, 0x39, 0xa2, 0xec, 0xca, 0x5c, 0xad, 0x8f, 0xe7, 0xec, 0x58, 0x9b, +- 0xb4, 0x21, 0x32, 0xc1, 0x8f, 0x62, 0x91, 0x2b, 0xff, 0xec, 0x99, 0x49, +- 0xb9, 0x0b, 0xa1, 0x57, 0xe6, 0xe4, 0xbe, 0x9f, 0x72, 0x9b, 0x4d, 0x31, +- 0xa8, 0xf3, 0xa6, 0xca, 0x9e, 0x1f, 0xe7, 0x7f, 0xbb, 0xd4, 0x56, 0xae, +- 0xdc, 0xcd, 0x7e, 0xb1, 0x21, 0x75, 0xde, 0xd4, 0x35, 0xfb, 0x02, 0xe2, +- 0x47, 0x48, 0xdb, 0x8a, 0x5c, 0xbe, 0xb7, 0xe6, 0xca, 0x7c, 0x4f, 0xb0, +- 0x0b, 0x23, 0x09, 0x0d, 0xef, 0x99, 0x92, 0xdf, 0xc9, 0xad, 0x28, 0xbe, +- 0xc7, 0xfc, 0xf1, 0x99, 0x44, 0xb0, 0x75, 0x9d, 0x52, 0x1f, 0x9b, 0xc3, +- 0x38, 0x87, 0x0a, 0x59, 0x4f, 0x8f, 0x38, 0xff, 0xaf, 0x2a, 0x13, 0x8a, +- 0x20, 0x43, 0x7f, 0x78, 0x23, 0x11, 0xec, 0x38, 0xa3, 0xe4, 0xfe, 0x0f, +- 0xd6, 0xeb, 0xce, 0xfb, 0x1c, 0x79, 0xbb, 0x13, 0xce, 0x39, 0x75, 0x3d, +- 0x57, 0x6c, 0x30, 0xd8, 0x97, 0x46, 0xa5, 0xac, 0x9b, 0x58, 0x16, 0xf3, +- 0xa1, 0xee, 0x94, 0x15, 0x50, 0xf1, 0x15, 0xc4, 0xfd, 0xb2, 0x47, 0x72, +- 0xcb, 0xe4, 0xff, 0xa9, 0x11, 0x7e, 0xf4, 0x2f, 0xaf, 0x4f, 0xc9, 0xff, +- 0x06, 0xca, 0xdb, 0x8b, 0x35, 0x76, 0x3d, 0xd2, 0x9a, 0xac, 0x7d, 0xc0, +- 0x9a, 0x46, 0x5d, 0xfb, 0x8d, 0x4d, 0x1c, 0xb7, 0x07, 0xd3, 0x99, 0xdb, +- 0x85, 0x6b, 0xeb, 0xdb, 0x1a, 0xd5, 0x6b, 0x10, 0xab, 0x08, 0x6a, 0x31, +- 0x72, 0xcd, 0x1e, 0xe7, 0xff, 0xed, 0xc8, 0xb9, 0x14, 0xab, 0xd5, 0x4b, +- 0x4c, 0x6f, 0x52, 0x14, 0x14, 0x84, 0xe0, 0x7e, 0x28, 0xe3, 0x86, 0x56, +- 0xfb, 0x5b, 0xfb, 0x17, 0x7e, 0x03, 0xdb, 0xc6, 0x6e, 0xb9, 0xf4, 0xff, +- 0x87, 0xfe, 0x63, 0xf6, 0xea, 0xec, 0x37, 0xdf, 0xe6, 0xc7, 0x76, 0x6c, +- 0xba, 0xf4, 0x2d, 0xed, 0xfe, 0x31, 0x59, 0xf3, 0xef, 0x7a, 0xd4, 0xe8, +- 0x2e, 0x94, 0x63, 0xab, 0xb9, 0xde, 0x2f, 0x67, 0xe5, 0xd6, 0x43, 0xf6, +- 0xff, 0x65, 0x0e, 0xe4, 0x1d, 0xc3, 0x08, 0xf3, 0x6e, 0xd1, 0x4b, 0x14, +- 0x0f, 0x66, 0xe4, 0x9d, 0xa0, 0x59, 0x90, 0xff, 0xfb, 0xf5, 0x60, 0x26, +- 0xa7, 0xbf, 0x47, 0x33, 0x3e, 0xe6, 0x00, 0x3e, 0xda, 0x60, 0x07, 0xf9, +- 0x0b, 0xf9, 0xd3, 0x25, 0x5d, 0xde, 0xeb, 0x97, 0x75, 0x85, 0xef, 0xd3, +- 0xa7, 0xdd, 0xb5, 0x72, 0x6d, 0xc9, 0xb9, 0x51, 0x25, 0x77, 0x7d, 0xde, +- 0x79, 0x37, 0x52, 0x8d, 0xae, 0xc3, 0xc2, 0xc4, 0x34, 0x39, 0x3f, 0x29, +- 0x6b, 0x36, 0x96, 0x3f, 0x2a, 0xef, 0x61, 0xf8, 0x88, 0xb1, 0x5f, 0xf5, +- 0x4f, 0xbe, 0x73, 0xd5, 0xba, 0x82, 0x38, 0x36, 0x27, 0x6c, 0xc4, 0x9a, +- 0x94, 0xa0, 0xbe, 0x52, 0x69, 0x63, 0xbd, 0x3a, 0xf4, 0x64, 0xa5, 0x0d, +- 0xc5, 0xf9, 0xdf, 0x92, 0x1e, 0xb6, 0x71, 0x30, 0x51, 0xaf, 0x7b, 0xd4, +- 0x4f, 0x6d, 0xcb, 0x39, 0x03, 0x29, 0xfb, 0xf6, 0x71, 0xbc, 0x94, 0x98, +- 0x4e, 0x94, 0xba, 0xba, 0xdd, 0x4b, 0xeb, 0xe7, 0x7f, 0xa3, 0x21, 0xc6, +- 0xb6, 0x82, 0x9d, 0x61, 0x57, 0x70, 0xc3, 0x05, 0xe2, 0x4a, 0x36, 0x6c, +- 0xc4, 0x7f, 0xc0, 0x3e, 0xfe, 0x56, 0xa9, 0x43, 0x62, 0x4a, 0xfb, 0xb9, +- 0xb6, 0xea, 0xdb, 0x0b, 0xd4, 0xf3, 0xce, 0xbb, 0xf8, 0xd2, 0xbe, 0x16, +- 0x5d, 0x0d, 0x2d, 0x69, 0xd9, 0x7e, 0xb6, 0x39, 0x33, 0x1a, 0xdc, 0x57, +- 0x41, 0x30, 0xfa, 0xb6, 0xda, 0x85, 0x35, 0x72, 0x3c, 0x24, 0x1a, 0xd4, +- 0x1f, 0xa0, 0x7d, 0x34, 0x3a, 0x6d, 0xc4, 0xea, 0x0a, 0x20, 0x9c, 0xf2, +- 0x4b, 0xed, 0x84, 0x39, 0x81, 0x70, 0x31, 0x96, 0x73, 0xce, 0x03, 0xc8, +- 0xb9, 0x49, 0xe6, 0x0d, 0x09, 0xf9, 0xbf, 0x7d, 0x4e, 0x37, 0x93, 0x7b, +- 0x5a, 0xcc, 0xd7, 0x19, 0xaf, 0xd7, 0xcb, 0xff, 0x48, 0x2a, 0xf6, 0xe1, +- 0xc1, 0x84, 0xac, 0x81, 0xfc, 0x1f, 0x05, 0x3f, 0x96, 0xb4, 0x1c, 0x54, +- 0x00, 0x00, 0x00 }; ++ 0xad, 0xbc, 0x0b, 0x74, 0x1c, 0xd5, 0x95, 0x2e, 0xfc, 0x55, 0x75, 0xb7, ++ 0xd4, 0x92, 0xda, 0x52, 0x4b, 0x6e, 0xcb, 0x6d, 0xd0, 0xe0, 0x6a, 0xab, ++ 0xda, 0x6a, 0x2c, 0x01, 0xd5, 0xb2, 0x0c, 0x4d, 0xa6, 0xc0, 0x1d, 0x5b, ++ 0x80, 0x0c, 0x26, 0x11, 0xc6, 0xb9, 0x23, 0xe6, 0x7a, 0xfe, 0xf4, 0x18, ++ 0x03, 0x86, 0x90, 0x5c, 0x33, 0x93, 0x9b, 0x71, 0xb8, 0x9e, 0xeb, 0x8a, ++ 0xe4, 0x87, 0xc0, 0xa5, 0xee, 0x96, 0x90, 0x1f, 0xac, 0x35, 0xeb, 0xa7, ++ 0x2d, 0xcb, 0x92, 0x21, 0xad, 0x16, 0x49, 0x98, 0x19, 0xe7, 0xe6, 0x81, ++ 0xc6, 0xd8, 0x60, 0x93, 0xf0, 0xc8, 0x6b, 0xfd, 0x4c, 0xfe, 0xb9, 0x7f, ++ 0x3c, 0xb6, 0x79, 0x83, 0xe3, 0x3c, 0x47, 0x9e, 0xc1, 0xa9, 0xff, 0xdb, ++ 0xd5, 0xdd, 0xb6, 0xec, 0x40, 0x1e, 0xeb, 0x8e, 0xd6, 0xaa, 0xa5, 0xee, ++ 0xaa, 0x73, 0xf6, 0x39, 0x67, 0x9f, 0xbd, 0xbf, 0xfd, 0xed, 0x73, 0x4e, ++ 0xb5, 0x06, 0x54, 0xa3, 0xf4, 0x37, 0x8b, 0xd7, 0xd5, 0x1d, 0x1b, 0xee, ++ 0x5e, 0xdc, 0x7e, 0x75, 0x87, 0x7c, 0xf7, 0xce, 0xf5, 0x7a, 0xf1, 0x61, ++ 0x7f, 0x26, 0x12, 0x97, 0xde, 0xd2, 0x3e, 0xb4, 0xe0, 0x47, 0xfc, 0x25, ++ 0x10, 0x91, 0x7f, 0xad, 0xa5, 0xaf, 0x1e, 0x20, 0x58, 0x6e, 0x5f, 0x2e, ++ 0xf8, 0x55, 0xb3, 0xf3, 0xbf, 0x2e, 0xd3, 0xe1, 0xf7, 0x98, 0x9f, 0xff, ++ 0x8b, 0xbb, 0x75, 0x20, 0x99, 0x6f, 0xd5, 0x96, 0xe3, 0x9c, 0x63, 0x85, ++ 0xbc, 0x90, 0xfb, 0x7f, 0x62, 0x7e, 0xf0, 0xc4, 0xb7, 0xae, 0x8b, 0x9c, ++ 0xc9, 0x79, 0xe0, 0x0f, 0x9a, 0x16, 0x82, 0x0b, 0xe1, 0x6f, 0x62, 0x9d, ++ 0xbf, 0x6b, 0xd9, 0xa6, 0xa2, 0xb6, 0x2c, 0x2b, 0x12, 0xce, 0x21, 0x12, ++ 0xb4, 0x10, 0x89, 0x59, 0x40, 0xca, 0x6b, 0x22, 0x55, 0x69, 0xfa, 0x51, ++ 0xa1, 0x57, 0x20, 0x15, 0xdc, 0xa8, 0x6d, 0xe1, 0x18, 0x97, 0xd9, 0x7e, ++ 0xed, 0x44, 0x1e, 0xb8, 0xdb, 0xf6, 0xe3, 0xb8, 0x27, 0xa0, 0x9d, 0xcc, ++ 0xef, 0xab, 0x2b, 0xea, 0x23, 0x09, 0x8f, 0x8e, 0x94, 0x6a, 0xca, 0x7d, ++ 0x68, 0xcb, 0xf3, 0x48, 0xf9, 0xcc, 0xcf, 0x6b, 0xe3, 0x36, 0xd0, 0x9b, ++ 0x69, 0x36, 0x4e, 0xa0, 0x35, 0x7c, 0x18, 0x95, 0x48, 0x85, 0x22, 0x31, ++ 0xe0, 0x83, 0x73, 0x8f, 0x66, 0x14, 0xf8, 0xf4, 0xd9, 0xe8, 0xdc, 0x0b, ++ 0x3c, 0x92, 0x89, 0x24, 0x75, 0x05, 0xe8, 0x9f, 0x94, 0xba, 0x91, 0x60, ++ 0x8e, 0xcf, 0xb7, 0x64, 0x80, 0xad, 0x99, 0xd9, 0xd8, 0x96, 0x75, 0xf0, ++ 0x9c, 0xd1, 0x1c, 0xdc, 0xc7, 0x16, 0x7a, 0xdd, 0xe7, 0xb3, 0x61, 0xe5, ++ 0xe4, 0xf9, 0x5b, 0xce, 0xb7, 0x5a, 0x82, 0x78, 0x7a, 0x32, 0x84, 0x67, ++ 0x27, 0xeb, 0xf1, 0x48, 0xb6, 0x1e, 0xdb, 0xb3, 0x31, 0xa8, 0xba, 0x83, ++ 0x58, 0x3c, 0x86, 0x8a, 0xeb, 0x1d, 0x9c, 0x34, 0xda, 0xb0, 0x95, 0x82, ++ 0x5f, 0x6d, 0x6b, 0xc4, 0xda, 0x60, 0x13, 0xb6, 0xe8, 0xd7, 0xa1, 0x38, ++ 0xd6, 0x0f, 0xce, 0x65, 0x32, 0xd2, 0x3f, 0xaf, 0xaa, 0xea, 0x37, 0xe2, ++ 0xf4, 0x4e, 0x13, 0xef, 0xef, 0xc4, 0x9a, 0x5a, 0x38, 0x4e, 0x3e, 0x1e, ++ 0xed, 0x7e, 0x50, 0x09, 0x6a, 0x4f, 0xe5, 0xd9, 0xa1, 0x55, 0x5e, 0xca, ++ 0x83, 0x36, 0x92, 0x9f, 0x39, 0x15, 0x6c, 0x2f, 0xc3, 0x76, 0x33, 0xd2, ++ 0x97, 0x30, 0xbe, 0xd5, 0xf2, 0xdf, 0x68, 0x0f, 0xc5, 0x31, 0x6d, 0xcd, ++ 0xbc, 0xc6, 0x3e, 0x69, 0xec, 0x4f, 0x13, 0xbe, 0x36, 0x19, 0xc6, 0x57, ++ 0xd9, 0xb7, 0xaf, 0x4c, 0x4a, 0x1f, 0x23, 0x7b, 0x2c, 0xd4, 0x63, 0x34, ++ 0xdb, 0x84, 0xa7, 0xf5, 0x36, 0x7c, 0x85, 0x7d, 0xec, 0x33, 0x62, 0x58, ++ 0x9b, 0xb8, 0x8b, 0xfd, 0x51, 0xb0, 0xaa, 0xed, 0x2f, 0x4b, 0xfd, 0x8a, ++ 0x68, 0x50, 0x55, 0x24, 0x1b, 0x22, 0x31, 0x4d, 0x15, 0x99, 0x17, 0xfa, ++ 0x3b, 0x90, 0x81, 0xe5, 0x37, 0xa5, 0xcf, 0x37, 0x22, 0xcf, 0xfe, 0x7e, ++ 0x79, 0x67, 0xd4, 0x58, 0xaf, 0x62, 0x65, 0x80, 0x7d, 0x7e, 0x20, 0x1e, ++ 0x4d, 0x2c, 0x62, 0x9f, 0xc7, 0xf3, 0x2a, 0xc7, 0x13, 0xd2, 0xc6, 0xd8, ++ 0xf7, 0xe4, 0x2a, 0x95, 0x7d, 0x67, 0x5f, 0x32, 0xec, 0x4b, 0x86, 0x7d, ++ 0xc9, 0xb0, 0x2f, 0x6e, 0xbf, 0x63, 0xec, 0x73, 0x71, 0x8e, 0x46, 0xf2, ++ 0xc7, 0xd9, 0xdf, 0x99, 0xfd, 0x6c, 0x62, 0xdf, 0x91, 0xaa, 0xe7, 0xbc, ++ 0x35, 0xa7, 0x65, 0xde, 0x1c, 0xe7, 0x55, 0xc3, 0x71, 0x7e, 0x6e, 0x04, ++ 0xa8, 0xbf, 0x0c, 0xed, 0xa0, 0xdc, 0x9f, 0xf9, 0x56, 0x85, 0x89, 0x4e, ++ 0x9a, 0xa0, 0x73, 0xa4, 0x23, 0x9a, 0x68, 0x50, 0x54, 0x78, 0xf5, 0xa0, ++ 0xd6, 0x52, 0x88, 0x18, 0xd4, 0x8f, 0x16, 0x2d, 0x40, 0xd3, 0x0b, 0x94, ++ 0x75, 0x51, 0xbb, 0x91, 0xe0, 0x14, 0xa4, 0x5d, 0x8d, 0xed, 0x1f, 0x2f, ++ 0xcd, 0x9d, 0xc8, 0x0f, 0xb3, 0x4d, 0x69, 0x5f, 0x64, 0x3b, 0xce, 0xcf, ++ 0x0c, 0xe8, 0x41, 0x44, 0xad, 0x41, 0xda, 0x9f, 0xc7, 0x0c, 0x6a, 0x1b, ++ 0xf2, 0x7c, 0x7e, 0x5e, 0x46, 0x71, 0x3e, 0xd6, 0xe6, 0xb5, 0xd2, 0x18, ++ 0x22, 0xec, 0x82, 0xd8, 0x41, 0x38, 0x15, 0x30, 0x83, 0xd2, 0xf7, 0xee, ++ 0x3d, 0x03, 0x9b, 0x9d, 0x79, 0xba, 0xe8, 0x4a, 0xdf, 0x38, 0xcf, 0x13, ++ 0x48, 0x9c, 0x5e, 0xf2, 0x90, 0x35, 0xab, 0x23, 0x8e, 0x6a, 0x1d, 0x81, ++ 0x2a, 0x1d, 0xdd, 0xe9, 0x89, 0x6a, 0xab, 0xc6, 0xfc, 0xe6, 0x9d, 0x03, ++ 0x13, 0x7e, 0x54, 0x4f, 0xe8, 0xa8, 0x9a, 0x78, 0xdc, 0x8b, 0x5a, 0x03, ++ 0x3b, 0x26, 0xff, 0xcc, 0x5b, 0x1c, 0xdb, 0xcd, 0xa5, 0x31, 0xba, 0xb6, ++ 0xef, 0x7f, 0xdd, 0x3e, 0xe3, 0x54, 0xe8, 0x55, 0x7f, 0xe6, 0x31, 0x75, ++ 0x6d, 0x0c, 0x38, 0xb3, 0xb6, 0x63, 0x39, 0x7a, 0x83, 0x0a, 0xe6, 0xeb, ++ 0x7f, 0x32, 0x0b, 0xb5, 0x26, 0xac, 0xc9, 0xc6, 0x54, 0x85, 0x19, 0x4a, ++ 0x71, 0x6e, 0xf0, 0x82, 0x9d, 0x83, 0x6f, 0xc0, 0x71, 0xa4, 0xec, 0x49, ++ 0xdc, 0x79, 0xa7, 0x6a, 0x1e, 0xba, 0xc6, 0x87, 0x4e, 0x96, 0xc7, 0xa6, ++ 0xa3, 0x1d, 0x3f, 0x57, 0xd4, 0x9d, 0xdd, 0xb0, 0xc6, 0x3d, 0x48, 0x06, ++ 0x53, 0xfc, 0x7f, 0xc5, 0x15, 0x2b, 0x13, 0xdd, 0xb0, 0xc7, 0xa7, 0x79, ++ 0xdf, 0xcb, 0x7b, 0x26, 0xd2, 0x99, 0x2b, 0xae, 0xb8, 0x3d, 0x91, 0xc2, ++ 0xc0, 0xb8, 0x7c, 0xf6, 0x62, 0xaa, 0x3e, 0x85, 0xed, 0xbb, 0x35, 0xd4, ++ 0xe9, 0xdd, 0xc8, 0x8c, 0xcb, 0x67, 0xc7, 0x39, 0x65, 0x7c, 0x09, 0x7b, ++ 0xda, 0xe8, 0xff, 0x73, 0xbb, 0xb1, 0x6d, 0xb7, 0x85, 0x4a, 0xdd, 0xa2, ++ 0xee, 0x15, 0xef, 0x3f, 0xb7, 0x29, 0xd0, 0xee, 0x84, 0xb7, 0x42, 0x17, ++ 0xbd, 0x25, 0xbc, 0xf7, 0xd8, 0x66, 0x70, 0xbe, 0xee, 0x38, 0x23, 0xc6, ++ 0x22, 0x7c, 0xba, 0x7b, 0x2d, 0xac, 0x7d, 0x01, 0x58, 0xab, 0xe5, 0x7f, ++ 0x37, 0x75, 0xb8, 0x16, 0xbd, 0xfb, 0xd6, 0xa2, 0xff, 0x31, 0x3a, 0x6e, ++ 0x7d, 0xd0, 0x9d, 0xa7, 0x6f, 0xb5, 0x48, 0x9f, 0xa4, 0x7f, 0x3d, 0xbc, ++ 0x44, 0xb7, 0x5f, 0xe0, 0x7f, 0x29, 0x33, 0xed, 0x60, 0xce, 0x85, 0x32, ++ 0xdb, 0x59, 0x66, 0xdb, 0x45, 0x65, 0x4c, 0x3c, 0x31, 0x29, 0xba, 0x10, ++ 0x95, 0xfd, 0x3e, 0x5d, 0x7c, 0xdb, 0xe9, 0x0d, 0x89, 0x2e, 0xac, 0x1e, ++ 0x1f, 0x22, 0xdd, 0xf7, 0x2a, 0x5e, 0xac, 0x18, 0x00, 0xeb, 0xd0, 0x09, ++ 0xaa, 0x23, 0xc9, 0x85, 0x8a, 0x89, 0xea, 0x01, 0x05, 0x2b, 0xe2, 0x55, ++ 0xd0, 0xea, 0x45, 0xde, 0x8f, 0x1c, 0x2b, 0x28, 0xfd, 0x3d, 0x8a, 0x1a, ++ 0xde, 0x5f, 0x17, 0xff, 0x01, 0xf1, 0x4c, 0xfa, 0x14, 0x67, 0xf9, 0x3b, ++ 0x78, 0xff, 0x95, 0x19, 0xdf, 0xa5, 0x9c, 0xe3, 0xf4, 0x19, 0x06, 0xfa, ++ 0x33, 0x6d, 0xd8, 0x9e, 0x49, 0x46, 0xa8, 0x25, 0xcb, 0x67, 0xf2, 0xbe, ++ 0x19, 0xed, 0xea, 0x85, 0xb4, 0x03, 0xa5, 0xda, 0x84, 0x37, 0xdf, 0x71, ++ 0xdc, 0xff, 0x92, 0xad, 0xf7, 0x3c, 0xa5, 0xf8, 0x68, 0xec, 0xd2, 0xce, ++ 0x71, 0xff, 0x2b, 0xb6, 0x82, 0x37, 0xf5, 0xe8, 0x86, 0x77, 0x94, 0xe3, ++ 0xfe, 0x97, 0xf3, 0x41, 0xcc, 0x1b, 0x88, 0xf4, 0x58, 0x4a, 0x02, 0x5f, ++ 0xcf, 0x87, 0x10, 0x1e, 0x30, 0x71, 0x30, 0x6f, 0xe0, 0xc9, 0x8b, 0x70, ++ 0xe0, 0x43, 0xff, 0x2c, 0x0f, 0xc7, 0xbe, 0xce, 0xd6, 0xd0, 0x6b, 0x9c, ++ 0x73, 0x92, 0x41, 0xa4, 0xea, 0xcc, 0xe3, 0xfe, 0xf7, 0x07, 0xa0, 0xd4, ++ 0x9a, 0x7a, 0xb8, 0xa0, 0xfc, 0xab, 0x93, 0x0a, 0x49, 0x31, 0xf6, 0xcf, ++ 0xc5, 0xb2, 0x24, 0xed, 0xce, 0x20, 0xce, 0x9d, 0x71, 0x6a, 0x68, 0xb3, ++ 0x15, 0xe6, 0x65, 0x18, 0x1f, 0xd6, 0xf1, 0xa4, 0xed, 0x38, 0xef, 0x19, ++ 0x53, 0x89, 0x00, 0xf4, 0xee, 0x77, 0x11, 0x49, 0x2e, 0xa2, 0x5e, 0x8e, ++ 0xe6, 0x75, 0x8c, 0xda, 0x26, 0x9e, 0xb3, 0x9b, 0x83, 0x7d, 0x58, 0x8c, ++ 0x64, 0xb8, 0x18, 0x43, 0x26, 0xd8, 0xef, 0x91, 0x68, 0x37, 0xea, 0xcc, ++ 0x04, 0x0e, 0xb1, 0xdf, 0xa7, 0x97, 0x88, 0x1c, 0x03, 0x2f, 0xff, 0x01, ++ 0x7d, 0x25, 0xbe, 0xe3, 0x71, 0xf6, 0x35, 0xb1, 0xf8, 0x9c, 0x83, 0xd9, ++ 0x7e, 0x9c, 0x30, 0xe6, 0xd2, 0x0e, 0x61, 0x55, 0x99, 0x7e, 0x6f, 0xbf, ++ 0x1d, 0xc4, 0x81, 0x7c, 0xc0, 0xdb, 0x67, 0x87, 0xb0, 0x8f, 0xfe, 0x36, ++ 0x8f, 0xa6, 0x1e, 0xa6, 0xdc, 0x79, 0xc4, 0xb5, 0xc2, 0x70, 0x13, 0x26, ++ 0x87, 0x23, 0xc6, 0x2b, 0x4a, 0x18, 0x63, 0xa3, 0x97, 0x61, 0x62, 0x58, ++ 0xc1, 0x78, 0x94, 0x7d, 0xe7, 0xe7, 0x2f, 0x0f, 0x5f, 0x81, 0xfc, 0xb0, ++ 0x07, 0x3b, 0x5c, 0xbd, 0xba, 0x38, 0x53, 0xfa, 0x7f, 0x19, 0x72, 0xa3, ++ 0xf0, 0x2e, 0x1a, 0x08, 0xe2, 0xa9, 0xbc, 0xd7, 0xab, 0x0f, 0x84, 0x30, ++ 0x9a, 0xff, 0x36, 0xe7, 0x4d, 0x64, 0x6b, 0x18, 0xb1, 0xc7, 0xdc, 0x39, ++ 0xac, 0x33, 0x29, 0xac, 0x18, 0x5f, 0x19, 0xcb, 0x34, 0xc6, 0x99, 0x04, ++ 0x71, 0x48, 0x7c, 0xdc, 0x4f, 0x0c, 0x12, 0x1f, 0x7f, 0x4d, 0x41, 0x6d, ++ 0x02, 0x7d, 0x93, 0xe5, 0xe7, 0x0a, 0xed, 0xdf, 0x8b, 0x75, 0x41, 0x03, ++ 0x76, 0x46, 0xec, 0xb4, 0x8c, 0xcb, 0xf2, 0x59, 0xe6, 0xbf, 0x1a, 0xd6, ++ 0xfe, 0x6a, 0xec, 0xa0, 0x8f, 0x3d, 0xba, 0x53, 0xee, 0x3b, 0xce, 0x7d, ++ 0xf1, 0x3a, 0xda, 0x18, 0x6e, 0xaa, 0x42, 0xd4, 0x78, 0xcb, 0xed, 0x9b, ++ 0x85, 0xb1, 0xbc, 0xc4, 0x50, 0x8d, 0xf1, 0xed, 0x28, 0xdb, 0xea, 0x60, ++ 0x3b, 0x06, 0xbe, 0x3d, 0xd9, 0x86, 0x7f, 0x9c, 0x8c, 0xe1, 0x1f, 0x26, ++ 0x75, 0xfc, 0xfd, 0xa4, 0x86, 0x67, 0x2e, 0xc2, 0xf5, 0x3b, 0xa9, 0x2b, ++ 0xc1, 0x30, 0x03, 0x5b, 0x32, 0x15, 0xd8, 0x36, 0x5c, 0x8d, 0xbe, 0xe1, ++ 0xe6, 0xd8, 0x73, 0xc4, 0xe3, 0x7f, 0x30, 0x6e, 0xc7, 0x54, 0x43, 0x87, ++ 0xeb, 0x33, 0x8f, 0xf0, 0xfe, 0xa3, 0xc3, 0xcd, 0x9c, 0x43, 0xc7, 0x51, ++ 0xe3, 0xad, 0x89, 0x43, 0xc4, 0xf7, 0xe3, 0xa1, 0x88, 0x36, 0xa5, 0x46, ++ 0xb4, 0x24, 0x7c, 0xb0, 0xdb, 0x54, 0x58, 0x73, 0x22, 0x39, 0x7a, 0x31, ++ 0x42, 0xfa, 0x7d, 0x1c, 0x5b, 0x44, 0xb3, 0x54, 0x83, 0xf6, 0xcb, 0x98, ++ 0xa1, 0x76, 0x10, 0x5f, 0xaa, 0xf1, 0xfe, 0x70, 0xa4, 0xdf, 0x52, 0xef, ++ 0x80, 0xd5, 0xe0, 0x38, 0x5f, 0x8d, 0x63, 0xc3, 0x5c, 0x13, 0xc9, 0x39, ++ 0x8c, 0x05, 0x57, 0x98, 0x49, 0x30, 0x8e, 0xe1, 0xf4, 0x80, 0x1e, 0xfe, ++ 0x7f, 0x94, 0x3b, 0xf1, 0xdf, 0xbb, 0x23, 0x9a, 0xa6, 0xb6, 0x5a, 0xfb, ++ 0x54, 0x92, 0x8d, 0x46, 0x68, 0x61, 0xf3, 0x56, 0x6c, 0x74, 0x79, 0x82, ++ 0x82, 0xa0, 0xde, 0x81, 0xbe, 0x0c, 0x2b, 0x85, 0x9a, 0x7b, 0x06, 0xd5, ++ 0xe6, 0x69, 0x43, 0x8d, 0x1c, 0xed, 0x56, 0x89, 0xb7, 0x8b, 0x4f, 0x3b, ++ 0x5a, 0xa3, 0xe3, 0xb4, 0x2f, 0x96, 0x36, 0x35, 0x34, 0x70, 0x9e, 0xeb, ++ 0x39, 0xcf, 0xed, 0x85, 0x6a, 0xbc, 0x33, 0x0c, 0x6b, 0xae, 0x19, 0xe9, ++ 0x7a, 0x40, 0xad, 0xc6, 0xdb, 0xa3, 0xd5, 0x38, 0x39, 0xec, 0xc5, 0x5b, ++ 0xc3, 0x8e, 0x73, 0x8f, 0x51, 0x87, 0x8a, 0x38, 0xe6, 0x54, 0x20, 0x7a, ++ 0x66, 0x04, 0x16, 0x7e, 0xc3, 0xb2, 0xbf, 0x1c, 0x0e, 0xe3, 0x57, 0xc3, ++ 0x1f, 0xc3, 0x33, 0x0d, 0xc9, 0x63, 0xb3, 0x19, 0x23, 0xa7, 0x69, 0x3f, ++ 0xa7, 0xed, 0x48, 0xcf, 0x3c, 0x4f, 0x64, 0x23, 0x79, 0xcb, 0xfa, 0x2f, ++ 0x2a, 0x91, 0xd4, 0x2b, 0x4a, 0x44, 0x1b, 0x50, 0x42, 0x78, 0x97, 0x76, ++ 0x7a, 0x2a, 0xdf, 0x9c, 0xf8, 0x01, 0xdb, 0xff, 0xb5, 0xf1, 0x0f, 0xce, ++ 0x54, 0xa3, 0xe8, 0x50, 0xf4, 0x45, 0x9d, 0xd3, 0x77, 0xff, 0x91, 0x31, ++ 0xea, 0x1f, 0x32, 0xd4, 0x39, 0xfb, 0xf3, 0xcc, 0x6f, 0xc5, 0x2f, 0x99, ++ 0xaf, 0x04, 0xe7, 0xf1, 0x72, 0xfc, 0x4f, 0x77, 0x6c, 0xc7, 0x9c, 0xbf, ++ 0x09, 0xc9, 0xf8, 0x3a, 0x1b, 0x8b, 0x18, 0x24, 0xe3, 0x3c, 0xea, 0xa4, ++ 0x82, 0x32, 0x46, 0x19, 0xab, 0xab, 0x4b, 0x6d, 0x83, 0xf2, 0x90, 0x8a, ++ 0x6a, 0xc7, 0x79, 0xcc, 0x28, 0x3d, 0x0f, 0x95, 0xc7, 0xfa, 0x31, 0xde, ++ 0x97, 0xf1, 0xbe, 0xe3, 0x11, 0xdd, 0x6b, 0xea, 0xd5, 0xfc, 0x1e, 0xb1, ++ 0x92, 0xb8, 0x33, 0xc0, 0xef, 0xb1, 0xe4, 0xf9, 0xef, 0xde, 0xba, 0x8b, ++ 0x9f, 0xd3, 0x4e, 0xdd, 0xf6, 0xee, 0xe4, 0x77, 0x19, 0xcb, 0xab, 0xb4, ++ 0x9b, 0x0f, 0xb3, 0x13, 0xb1, 0x91, 0x18, 0xed, 0xe9, 0x94, 0xc4, 0x15, ++ 0x2b, 0x64, 0xfa, 0x2d, 0xd5, 0x84, 0x46, 0x9c, 0xf0, 0x2b, 0xe6, 0x06, ++ 0x68, 0x79, 0x0b, 0x9f, 0xea, 0xf0, 0xe0, 0xaf, 0x3a, 0x14, 0xcc, 0xd6, ++ 0x37, 0x20, 0x7b, 0xad, 0xe5, 0xd4, 0xeb, 0x7b, 0x55, 0xf1, 0x81, 0x8a, ++ 0x34, 0x2c, 0xfa, 0x1d, 0x12, 0xe4, 0x4a, 0x75, 0x7f, 0xaa, 0xe0, 0x44, ++ 0x3c, 0x4a, 0x9b, 0xdb, 0x82, 0x6d, 0x9c, 0xf3, 0x59, 0x69, 0xf8, 0x03, ++ 0xa6, 0x09, 0x7b, 0x00, 0xfe, 0x2a, 0xfa, 0xfe, 0x95, 0x03, 0xcd, 0x1b, ++ 0xc6, 0x94, 0x48, 0x22, 0xad, 0x44, 0xba, 0xa9, 0x6f, 0xe3, 0xb4, 0x8b, ++ 0x1b, 0x11, 0xad, 0x42, 0x91, 0x76, 0x4c, 0xb4, 0xe4, 0xb7, 0x60, 0x60, ++ 0x52, 0x3e, 0x27, 0xa0, 0xe7, 0x7f, 0x5c, 0xea, 0x3b, 0xfc, 0x3e, 0xf6, ++ 0x61, 0xbf, 0xfd, 0xba, 0x93, 0x0b, 0x46, 0xb4, 0x9c, 0xfb, 0x7d, 0x3d, ++ 0xbf, 0xc3, 0x5f, 0x61, 0x3e, 0x88, 0xe7, 0xed, 0x37, 0xe7, 0x94, 0xcb, ++ 0x15, 0xfb, 0x7a, 0x69, 0x7f, 0xfe, 0xb7, 0x93, 0x0c, 0xb9, 0xfd, 0xf1, ++ 0xd7, 0xb0, 0x8d, 0xcf, 0x0c, 0xb0, 0x8d, 0x4c, 0xb9, 0x3f, 0x40, 0x20, ++ 0x2d, 0x71, 0x38, 0xa2, 0x2d, 0x50, 0x9a, 0x8d, 0x01, 0x25, 0x12, 0xbb, ++ 0x57, 0x69, 0x4d, 0x8c, 0x91, 0x5f, 0x6e, 0x47, 0xb1, 0x4f, 0xd1, 0x7c, ++ 0xb1, 0x3f, 0x0b, 0xf2, 0x50, 0x3c, 0x03, 0x08, 0xcc, 0xd7, 0x17, 0x62, ++ 0xb3, 0x3b, 0xa7, 0x50, 0xc2, 0x03, 0x1a, 0x6a, 0xc9, 0x5f, 0xc2, 0x13, ++ 0xc0, 0xe4, 0x10, 0xb9, 0x5c, 0xbc, 0x19, 0x9f, 0x63, 0x2c, 0x98, 0xc7, ++ 0x32, 0x5f, 0x0c, 0x9e, 0xc7, 0x2f, 0xa5, 0xdf, 0x26, 0xc0, 0xcc, 0x29, ++ 0xf2, 0xb2, 0xd4, 0x7f, 0x41, 0x52, 0xee, 0x3d, 0x6e, 0x43, 0xc9, 0xd8, ++ 0x91, 0x3d, 0x80, 0x3e, 0x15, 0xf7, 0x24, 0xef, 0x0f, 0x63, 0x33, 0x4e, ++ 0xc7, 0xa3, 0xa9, 0x82, 0x12, 0x35, 0x86, 0x14, 0xc3, 0xbf, 0x8d, 0xed, ++ 0xed, 0x60, 0x99, 0xed, 0xbc, 0x1e, 0x88, 0xea, 0x5d, 0x77, 0x28, 0xc9, ++ 0x2b, 0xab, 0x58, 0xe6, 0xa4, 0x11, 0x25, 0xcf, 0x8c, 0x4e, 0xaf, 0x82, ++ 0xe1, 0x7f, 0x22, 0x2f, 0xb2, 0x12, 0xca, 0x96, 0xc2, 0xe3, 0x6a, 0x11, ++ 0x8f, 0x7e, 0x5d, 0xd2, 0xd9, 0x49, 0xf9, 0xee, 0xb6, 0xed, 0x1d, 0x68, ++ 0xaa, 0xf9, 0xed, 0x7b, 0xda, 0x9c, 0x8b, 0xef, 0xb5, 0x06, 0x47, 0xe9, ++ 0x7f, 0x1e, 0xbd, 0x8a, 0x73, 0x27, 0xfc, 0x28, 0x19, 0xf3, 0x41, 0xee, ++ 0x79, 0x90, 0xf3, 0x26, 0xc3, 0x1e, 0x7c, 0xe0, 0x24, 0x57, 0xcb, 0xbd, ++ 0x6a, 0xa4, 0xba, 0x5b, 0xc3, 0x5e, 0xb4, 0x26, 0xb6, 0x12, 0x0b, 0x8e, ++ 0xaf, 0x5e, 0xc6, 0x67, 0x51, 0xe3, 0x39, 0x34, 0x6b, 0x5b, 0x21, 0x9f, ++ 0xcf, 0xd2, 0x66, 0x97, 0x49, 0x5d, 0x96, 0x29, 0x72, 0x1f, 0xc1, 0x9a, ++ 0x2d, 0x86, 0x83, 0xe7, 0x0d, 0x58, 0x95, 0xe6, 0x41, 0xe5, 0x84, 0xfd, ++ 0x1b, 0x27, 0xe9, 0xc5, 0x4a, 0xfa, 0xa5, 0x41, 0xda, 0xab, 0xf9, 0xcd, ++ 0xa8, 0x76, 0x94, 0x99, 0x82, 0xc7, 0xb4, 0x94, 0xe3, 0xf9, 0x2d, 0xca, ++ 0xeb, 0xf9, 0x7e, 0xe5, 0x54, 0x5e, 0xea, 0x1e, 0x54, 0x4e, 0xe6, 0x25, ++ 0x1e, 0x36, 0x69, 0x47, 0xc8, 0x6f, 0xc8, 0xa9, 0xd4, 0x3e, 0x03, 0xca, ++ 0x36, 0xa3, 0x96, 0x3c, 0x5f, 0x8f, 0x8d, 0xb0, 0xbf, 0xfb, 0x3b, 0x60, ++ 0x6c, 0x37, 0x7c, 0x38, 0x1e, 0x44, 0xa0, 0xcf, 0xf0, 0xca, 0x77, 0xe6, ++ 0x03, 0x52, 0xb7, 0x49, 0xdb, 0x9a, 0x3f, 0x47, 0xff, 0x2a, 0x7e, 0xdf, ++ 0xdf, 0x51, 0xbe, 0xf7, 0x0b, 0x67, 0x6a, 0xb5, 0xca, 0xef, 0x7f, 0xea, ++ 0xe1, 0x50, 0x58, 0x77, 0x26, 0x3f, 0x17, 0x2e, 0xa5, 0x92, 0x3f, 0xd6, ++ 0xc3, 0x0a, 0x46, 0xac, 0x1c, 0x73, 0x85, 0xbe, 0x4c, 0x3b, 0xfd, 0x2d, ++ 0xcc, 0x58, 0x99, 0x24, 0xbe, 0x93, 0xf7, 0xb2, 0xcd, 0x0a, 0x3d, 0x80, ++ 0x9b, 0xec, 0x66, 0x4f, 0x51, 0x7f, 0x2a, 0x31, 0xcc, 0xc3, 0x98, 0x2e, ++ 0x1c, 0xef, 0x52, 0xce, 0xdd, 0xa4, 0xbd, 0xc5, 0x7e, 0x57, 0xe9, 0x7a, ++ 0xac, 0x4a, 0x69, 0xd2, 0x5e, 0xcf, 0x27, 0xe9, 0xe3, 0x3d, 0x6c, 0x37, ++ 0x80, 0xd7, 0xed, 0x5a, 0xe6, 0x20, 0x91, 0xa4, 0x45, 0x81, 0x37, 0x77, ++ 0x84, 0x41, 0xce, 0x37, 0xe3, 0xaf, 0x1b, 0x8c, 0xff, 0x12, 0xa3, 0xd5, ++ 0x5b, 0x96, 0x24, 0xb0, 0x3e, 0x0f, 0xef, 0xba, 0x0e, 0x13, 0xf7, 0x30, ++ 0xb6, 0xdf, 0xc7, 0x78, 0xf9, 0x20, 0x63, 0xe1, 0x8e, 0x38, 0xc7, 0x56, ++ 0xef, 0x38, 0x95, 0xfa, 0x66, 0xc9, 0x67, 0x30, 0xc0, 0x58, 0x7c, 0x37, ++ 0xe3, 0xcb, 0x16, 0x7e, 0x7e, 0x29, 0xff, 0x1f, 0xce, 0x7d, 0xcc, 0xa7, ++ 0x9e, 0xbf, 0x48, 0x26, 0xd4, 0x51, 0xbd, 0x35, 0xb6, 0x95, 0xb1, 0x98, ++ 0x72, 0xad, 0x5a, 0xd3, 0x71, 0xae, 0x8c, 0x46, 0x92, 0x3e, 0xc5, 0xc0, ++ 0x73, 0x13, 0xc7, 0x1d, 0x6d, 0x8e, 0xe4, 0x52, 0xe5, 0x38, 0x28, 0x63, ++ 0x95, 0x1c, 0x41, 0xf0, 0x41, 0xf2, 0x84, 0x99, 0x18, 0xa1, 0xe2, 0xe6, ++ 0x61, 0xc9, 0x13, 0xc2, 0x58, 0x65, 0x7f, 0x09, 0xcf, 0xb5, 0x79, 0xd1, ++ 0xc5, 0x1c, 0xeb, 0x16, 0x3b, 0x80, 0x3b, 0x88, 0xa5, 0x2b, 0x6c, 0xe6, ++ 0x4e, 0xc1, 0x10, 0x6e, 0xb5, 0xbd, 0x38, 0xdc, 0xc6, 0x1c, 0x28, 0x54, ++ 0x89, 0x77, 0x0d, 0x0f, 0x8e, 0x18, 0x41, 0xe4, 0x5c, 0x7f, 0xd8, 0x41, ++ 0x0c, 0xa4, 0x1e, 0x55, 0xc9, 0x1d, 0x44, 0x87, 0x1e, 0xea, 0x53, 0x45, ++ 0xea, 0xbc, 0x0e, 0x3f, 0x2c, 0x17, 0x90, 0x7e, 0x49, 0x3e, 0xf0, 0x33, ++ 0x27, 0x35, 0x47, 0xea, 0xc3, 0x0a, 0x98, 0x32, 0x0e, 0xe1, 0xb7, 0x06, ++ 0xfa, 0x26, 0x3a, 0xc8, 0xed, 0x66, 0x0e, 0xf5, 0x0c, 0xb9, 0x75, 0x1d, ++ 0x5e, 0xd3, 0x85, 0x5b, 0xbf, 0x8a, 0x20, 0x7d, 0xb7, 0x7f, 0x22, 0xba, ++ 0xe1, 0x8c, 0xe2, 0xc1, 0x4b, 0x7a, 0x2d, 0x79, 0x9f, 0x89, 0xed, 0x13, ++ 0xf0, 0x6e, 0x5d, 0x62, 0x20, 0x3d, 0xd1, 0x9b, 0x98, 0xc5, 0xb4, 0xd7, ++ 0xbb, 0xa4, 0xc8, 0x89, 0x3e, 0x43, 0xdd, 0xae, 0x8d, 0xbb, 0x9c, 0xa8, ++ 0xc8, 0x07, 0x82, 0x8e, 0x73, 0x52, 0x17, 0x3d, 0x03, 0x07, 0x4a, 0x3a, ++ 0xde, 0xcf, 0xcf, 0xfd, 0x25, 0x1d, 0x6f, 0xa1, 0x3c, 0xfa, 0x1f, 0xb6, ++ 0x5d, 0xc4, 0x63, 0x34, 0x54, 0x9a, 0xc2, 0x6f, 0x88, 0xc3, 0xc4, 0x93, ++ 0x24, 0x75, 0xfc, 0x42, 0x7e, 0xbd, 0xe0, 0x36, 0xa7, 0xbb, 0xdd, 0xc5, ++ 0xef, 0xa4, 0x7a, 0x80, 0x76, 0x20, 0x7a, 0x78, 0xad, 0x94, 0xdb, 0x38, ++ 0xce, 0x90, 0x21, 0x3a, 0x2e, 0xe7, 0x65, 0xa2, 0xeb, 0x36, 0xc9, 0xb1, ++ 0xfa, 0x81, 0xdf, 0xb0, 0xac, 0x87, 0xb8, 0x6b, 0xe2, 0x6b, 0xdd, 0x62, ++ 0x3b, 0xb3, 0xdc, 0x58, 0x79, 0xd5, 0x42, 0xc7, 0xf9, 0x4a, 0x5c, 0xc3, ++ 0x7b, 0x7a, 0x6b, 0xa2, 0x5d, 0x8d, 0xb0, 0xaf, 0x49, 0xd8, 0x93, 0x1d, ++ 0x9c, 0xbb, 0x2b, 0x90, 0x0c, 0x89, 0xad, 0x61, 0x43, 0x45, 0x11, 0xc3, ++ 0x71, 0xca, 0xd6, 0x63, 0xdb, 0x38, 0x67, 0xfb, 0x42, 0x5d, 0xe4, 0x71, ++ 0x6a, 0x27, 0xd3, 0x7f, 0xf2, 0x27, 0xdd, 0x7a, 0x04, 0xef, 0x38, 0xb9, ++ 0x90, 0xc3, 0x38, 0x29, 0xb9, 0xd1, 0x7c, 0x1c, 0x0e, 0x7a, 0xf0, 0x62, ++ 0xac, 0x11, 0xc9, 0x7a, 0x05, 0x35, 0xfa, 0x9b, 0xce, 0x77, 0x42, 0xd2, ++ 0x0e, 0x73, 0x3c, 0xf5, 0x56, 0x8f, 0xe4, 0x80, 0x5e, 0x5d, 0xe4, 0x76, ++ 0x31, 0xc7, 0xbd, 0xb4, 0xfd, 0x7f, 0x75, 0x8e, 0x87, 0xa4, 0xfd, 0x48, ++ 0x50, 0x53, 0x7f, 0xd7, 0x1c, 0x7e, 0xdf, 0xf9, 0x81, 0x2b, 0x33, 0xe3, ++ 0xea, 0x01, 0xaa, 0xc8, 0x23, 0x54, 0x54, 0x8b, 0xcc, 0x72, 0x3b, 0xe2, ++ 0x67, 0x73, 0x79, 0x4f, 0x9e, 0x89, 0x8d, 0x6c, 0x61, 0xbb, 0xcf, 0x39, ++ 0x68, 0x94, 0xef, 0xd3, 0x1e, 0x29, 0x6b, 0x4d, 0x1e, 0x5a, 0xe1, 0xc5, ++ 0x52, 0xb4, 0xc4, 0x97, 0x2d, 0x97, 0xb1, 0xa8, 0x66, 0x52, 0xf3, 0xc3, ++ 0x6a, 0xf4, 0x10, 0x8b, 0xdf, 0x68, 0x6b, 0xc3, 0x72, 0xe6, 0x8c, 0xef, ++ 0x10, 0x5c, 0x7a, 0x75, 0x0f, 0xa6, 0x38, 0xbe, 0x27, 0x0d, 0x59, 0x2f, ++ 0x70, 0x70, 0x4b, 0xdc, 0x4a, 0xd1, 0x63, 0xad, 0x59, 0xb4, 0x9d, 0x6a, ++ 0x5d, 0xe2, 0x7c, 0x2d, 0x6a, 0x4c, 0x6f, 0xec, 0x1d, 0x44, 0x8c, 0x1d, ++ 0xe4, 0x39, 0x5a, 0x7d, 0x4b, 0xc2, 0x47, 0xed, 0xbe, 0x6c, 0x47, 0x13, ++ 0x47, 0x94, 0xa2, 0x3f, 0xbc, 0xc0, 0xb9, 0x7d, 0xcd, 0xd6, 0x37, 0x56, ++ 0x7a, 0x8a, 0xdf, 0x5f, 0x71, 0xf3, 0xd1, 0xb2, 0x3f, 0x84, 0x4b, 0xb8, ++ 0xe1, 0xf7, 0x9f, 0xb2, 0x71, 0x86, 0x54, 0x88, 0x79, 0x29, 0xce, 0xf4, ++ 0x19, 0x53, 0x8a, 0x4f, 0xaf, 0x25, 0xae, 0x0a, 0x96, 0x56, 0x90, 0x13, ++ 0x4a, 0xec, 0xf7, 0xfb, 0xdf, 0x61, 0x19, 0x72, 0xba, 0xe3, 0xb1, 0xeb, ++ 0x5b, 0x13, 0x7e, 0x24, 0xad, 0x4a, 0xfa, 0xe5, 0x2c, 0x33, 0xe4, 0xbf, ++ 0xaa, 0x60, 0x35, 0x06, 0x68, 0xd7, 0x35, 0xcc, 0x57, 0x5b, 0xd2, 0x13, ++ 0x8c, 0xe1, 0x6d, 0x78, 0x70, 0x82, 0x23, 0x6b, 0x18, 0x6c, 0x54, 0x4d, ++ 0x59, 0x83, 0x08, 0xc2, 0xd7, 0xf0, 0xe0, 0x0d, 0xaa, 0x79, 0x1c, 0x3d, ++ 0x1d, 0xfe, 0xce, 0x44, 0x01, 0xfe, 0x7a, 0x73, 0x13, 0xe2, 0x69, 0xc9, ++ 0x3b, 0x05, 0x23, 0x93, 0x5b, 0x89, 0x5a, 0x8d, 0x75, 0xd7, 0x96, 0xf5, ++ 0x0d, 0xb5, 0xd6, 0x94, 0xfc, 0x53, 0xeb, 0x7c, 0xc5, 0xc5, 0xd2, 0x20, ++ 0xf3, 0x85, 0x1f, 0x87, 0xff, 0xcf, 0xea, 0x27, 0x38, 0x27, 0xd2, 0x17, ++ 0xf9, 0x2f, 0x79, 0x3f, 0xbc, 0x2a, 0xb1, 0xb0, 0x77, 0xdc, 0xcb, 0xfc, ++ 0x4a, 0xe6, 0x4c, 0xe2, 0xf1, 0x6b, 0xff, 0xf5, 0x79, 0xfa, 0x8b, 0x8f, ++ 0xba, 0x7f, 0x44, 0xb7, 0x08, 0xf3, 0x8e, 0xa3, 0xc7, 0x23, 0xe1, 0x0a, ++ 0x45, 0xc3, 0xf6, 0xb6, 0x7f, 0xa7, 0x8d, 0x80, 0x38, 0x06, 0x12, 0xeb, ++ 0x5a, 0x6c, 0x19, 0xaf, 0x98, 0x51, 0xaf, 0x67, 0x4d, 0xb9, 0xde, 0x80, ++ 0x6e, 0xa5, 0xa4, 0xde, 0x68, 0x3c, 0xd2, 0xb3, 0x8d, 0xf5, 0x1e, 0x65, ++ 0xbd, 0x24, 0x63, 0xe7, 0x3d, 0x13, 0x41, 0x37, 0x9f, 0xb3, 0xc6, 0xab, ++ 0x67, 0xb6, 0x77, 0xbe, 0xde, 0xe3, 0xba, 0x35, 0xe5, 0xb6, 0xb7, 0x38, ++ 0xb2, 0xb1, 0xc2, 0xe3, 0x45, 0x9a, 0xf5, 0xa6, 0x58, 0xef, 0xf5, 0x09, ++ 0x59, 0x8f, 0xc0, 0x0d, 0xe3, 0x76, 0xe6, 0xb8, 0x47, 0xd7, 0x83, 0x27, ++ 0x91, 0x24, 0xe6, 0xba, 0x73, 0x79, 0xc3, 0x58, 0x7e, 0x33, 0xb6, 0xeb, ++ 0x87, 0xe2, 0x95, 0xac, 0x77, 0x44, 0x3f, 0x14, 0xf6, 0xd1, 0xaf, 0xd6, ++ 0x51, 0x5e, 0x2f, 0xf3, 0x1a, 0x95, 0xfe, 0xb2, 0x65, 0x5c, 0x62, 0xbf, ++ 0x41, 0x5e, 0x12, 0xa2, 0xcd, 0xc9, 0x98, 0xa5, 0x5d, 0x99, 0x53, 0x19, ++ 0x5f, 0x24, 0x36, 0xee, 0x8e, 0x4f, 0x99, 0x7b, 0x40, 0x72, 0xdd, 0x7a, ++ 0x0b, 0x7d, 0x6d, 0x12, 0xff, 0x14, 0x62, 0x6f, 0x03, 0xf3, 0x4f, 0x69, ++ 0x23, 0x84, 0x6d, 0xf4, 0xed, 0xfd, 0x86, 0xe3, 0x3c, 0x6f, 0xcc, 0xc7, ++ 0x01, 0x23, 0x92, 0x12, 0x3b, 0x7c, 0xd3, 0x58, 0x76, 0xa5, 0xe4, 0x96, ++ 0xc0, 0x9f, 0x60, 0x8a, 0xb6, 0x51, 0xa5, 0x8b, 0xbf, 0x29, 0x08, 0x47, ++ 0xbd, 0x5a, 0x8d, 0xe2, 0xc0, 0xbf, 0x78, 0xe1, 0xc6, 0x85, 0x1c, 0x7b, ++ 0xed, 0xf5, 0x0a, 0xde, 0xbf, 0x4a, 0xc1, 0xa1, 0xab, 0xa2, 0xe1, 0x11, ++ 0x65, 0x16, 0xb1, 0x35, 0xda, 0xdd, 0xa9, 0x58, 0x47, 0x59, 0x37, 0xd9, ++ 0xe6, 0x89, 0x84, 0xa1, 0xd4, 0xd1, 0xef, 0x5b, 0x34, 0x09, 0xfd, 0xde, ++ 0x81, 0x68, 0xf8, 0x51, 0xfe, 0xf7, 0x4c, 0x28, 0x98, 0xd0, 0x23, 0x49, ++ 0xb8, 0xf2, 0xd9, 0x36, 0xd3, 0xce, 0xab, 0xa3, 0x8e, 0x73, 0x2c, 0xde, ++ 0x1a, 0x3c, 0x86, 0x37, 0x89, 0x6d, 0xd2, 0x4e, 0x19, 0xeb, 0xc1, 0x5c, ++ 0x56, 0x4f, 0x76, 0x2a, 0x8e, 0x57, 0xf8, 0xc3, 0xfa, 0xbc, 0xc4, 0xc3, ++ 0x72, 0x7f, 0xcb, 0x71, 0xd1, 0x71, 0xde, 0x34, 0x8a, 0xb2, 0x82, 0x1d, ++ 0x91, 0x14, 0x30, 0x1f, 0x93, 0x7a, 0xa4, 0x6b, 0x8a, 0x3a, 0x08, 0xd3, ++ 0xdf, 0xe6, 0xe9, 0x8d, 0x38, 0xee, 0x8b, 0x04, 0x8f, 0x2b, 0xcb, 0xcf, ++ 0xaa, 0x58, 0xb4, 0xfe, 0x09, 0xa5, 0x75, 0x43, 0x15, 0xf4, 0x64, 0x41, ++ 0x99, 0x2b, 0x3a, 0x09, 0x07, 0xc8, 0xa5, 0xd6, 0xc1, 0x8d, 0xd1, 0xb8, ++ 0xcd, 0xf6, 0x26, 0xa7, 0xd1, 0x4c, 0xdb, 0xd7, 0x7b, 0xee, 0x23, 0x0f, ++ 0x04, 0x3e, 0xce, 0x24, 0x41, 0xfa, 0xda, 0x88, 0xd4, 0xa7, 0x1c, 0xe7, ++ 0x7e, 0xf6, 0x75, 0x07, 0xfb, 0xfa, 0x60, 0xfc, 0x3d, 0xe7, 0x5f, 0x5d, ++ 0x99, 0x37, 0x62, 0x44, 0xbf, 0x54, 0xee, 0xbb, 0xcc, 0xf5, 0x45, 0xae, ++ 0x0f, 0x37, 0xcf, 0x61, 0xbe, 0xd2, 0x21, 0xb8, 0x71, 0xd2, 0x4b, 0xdc, ++ 0xa0, 0x3c, 0xc6, 0x10, 0xf5, 0xd2, 0x38, 0xec, 0x01, 0xe3, 0x5b, 0x38, ++ 0xa5, 0xa8, 0x24, 0x42, 0x41, 0xf8, 0x75, 0x07, 0x0f, 0x90, 0x33, 0x24, ++ 0xe7, 0xd4, 0xe1, 0x73, 0x86, 0x1f, 0xb3, 0xa2, 0xea, 0x65, 0x1e, 0xce, ++ 0xc9, 0x81, 0xb8, 0x7c, 0xf7, 0x61, 0x6a, 0x8e, 0x07, 0x9b, 0xc9, 0x25, ++ 0x82, 0x51, 0x75, 0x9e, 0xdc, 0xf7, 0xb7, 0xcb, 0x77, 0xf6, 0x7f, 0xae, ++ 0x82, 0xfb, 0x69, 0x15, 0x6a, 0xb4, 0x37, 0x2c, 0xf7, 0xbb, 0x0c, 0xf9, ++ 0xae, 0xa0, 0x39, 0xee, 0xe5, 0xbc, 0x38, 0xf0, 0x48, 0x7a, 0x1f, 0xe5, ++ 0xfd, 0xb8, 0x7c, 0x4e, 0xde, 0xcf, 0x71, 0x27, 0xf7, 0x29, 0x82, 0x33, ++ 0x3f, 0x72, 0x5e, 0x64, 0x1c, 0x09, 0xf2, 0xf9, 0xe7, 0xd8, 0xf6, 0xd1, ++ 0xf8, 0xf3, 0xce, 0x3c, 0xe2, 0xeb, 0xb1, 0x84, 0x86, 0xf9, 0x57, 0x35, ++ 0xe1, 0xf8, 0x9d, 0x32, 0x66, 0x05, 0xb3, 0xf4, 0x2f, 0xf8, 0x24, 0xcf, ++ 0xac, 0xd5, 0xe7, 0xe2, 0xe6, 0x3b, 0x8a, 0xf7, 0xaa, 0xa2, 0xb2, 0x4e, ++ 0xa8, 0xa1, 0xea, 0xaa, 0x06, 0x68, 0xa5, 0x7b, 0xcb, 0xa3, 0xde, 0xee, ++ 0x59, 0x8a, 0x1e, 0xbc, 0x4d, 0x91, 0xe7, 0xbf, 0x24, 0xb7, 0x75, 0x9c, ++ 0x07, 0x38, 0x5f, 0x2d, 0xf1, 0x00, 0x4e, 0xb3, 0x9d, 0x5e, 0xea, 0x6f, ++ 0xe5, 0xf9, 0xf9, 0x2a, 0xd7, 0xff, 0xb9, 0xa3, 0x7d, 0x4a, 0xea, 0x8a, ++ 0x8c, 0x85, 0x5d, 0x37, 0x2b, 0x1c, 0x50, 0xb5, 0xe8, 0xd9, 0xd5, 0x19, ++ 0xcb, 0xf6, 0xba, 0xdf, 0x83, 0x1d, 0xaf, 0x9d, 0x5f, 0xf3, 0x3a, 0xe3, ++ 0xc6, 0xa3, 0x65, 0xd7, 0x07, 0x71, 0xdc, 0xa9, 0x6f, 0xb7, 0x82, 0x95, ++ 0x90, 0xb8, 0xd4, 0x1c, 0xfb, 0x0a, 0xe5, 0xfe, 0xc0, 0x28, 0xc6, 0xac, ++ 0xfd, 0x46, 0x24, 0x6b, 0xd1, 0x1f, 0x52, 0xcc, 0x13, 0x3b, 0x25, 0x76, ++ 0x4f, 0xd6, 0xfa, 0x50, 0x3b, 0x1f, 0x95, 0xed, 0x91, 0xfe, 0x05, 0xcc, ++ 0x9b, 0x3c, 0x1d, 0x12, 0xeb, 0x64, 0x7e, 0xdc, 0x32, 0x6c, 0xab, 0x0a, ++ 0xcb, 0xd9, 0xc7, 0x78, 0xfb, 0xef, 0x8b, 0x13, 0x22, 0x47, 0xac, 0x33, ++ 0xd2, 0x9f, 0xc4, 0xef, 0x2b, 0x0b, 0x46, 0x65, 0x59, 0x4f, 0xf2, 0xdf, ++ 0x90, 0xca, 0xab, 0xe4, 0x19, 0x15, 0xc1, 0xde, 0x8e, 0x46, 0x5e, 0xf2, ++ 0xdc, 0x7b, 0xc3, 0xda, 0xfc, 0xf9, 0x75, 0x3c, 0x64, 0x8d, 0x0a, 0xa8, ++ 0x57, 0x0b, 0x66, 0x13, 0x7d, 0x83, 0x32, 0x3e, 0x8b, 0x56, 0x2e, 0x39, ++ 0x7a, 0xe7, 0x5d, 0x77, 0xd3, 0x9f, 0x9f, 0x63, 0x8b, 0xa3, 0xe4, 0x33, ++ 0x96, 0xeb, 0x19, 0xe2, 0xeb, 0x33, 0xd7, 0xf5, 0x24, 0x86, 0x94, 0xd7, ++ 0x06, 0x1b, 0x30, 0xb8, 0xfb, 0x0e, 0x68, 0x8d, 0x45, 0x1c, 0x52, 0xcd, ++ 0xc5, 0x58, 0x96, 0x7d, 0xdb, 0x57, 0xe4, 0xe0, 0xb5, 0x18, 0xd8, 0x1d, ++ 0x47, 0x6e, 0x8e, 0x3c, 0x93, 0x7b, 0x7e, 0x08, 0x4e, 0x6e, 0xdf, 0x7d, ++ 0x99, 0xe4, 0xd4, 0x61, 0x91, 0x9b, 0xa2, 0xef, 0xa8, 0xfa, 0xdb, 0x8e, ++ 0x15, 0x14, 0xf9, 0x87, 0xae, 0xf4, 0x52, 0x87, 0x37, 0xa1, 0xb5, 0x67, ++ 0x0c, 0xa7, 0xc8, 0xeb, 0xdc, 0x35, 0x54, 0xad, 0xd2, 0x9c, 0xba, 0xdf, ++ 0x87, 0x68, 0x6a, 0x9c, 0x38, 0x10, 0x98, 0xf0, 0x93, 0x9f, 0xcc, 0x77, ++ 0xd7, 0x8e, 0x96, 0x91, 0x7f, 0xa4, 0xc8, 0x6d, 0x3f, 0xee, 0xf5, 0xe2, ++ 0x6e, 0x62, 0xc6, 0x7e, 0xbd, 0x75, 0xc3, 0x18, 0x7e, 0x45, 0xac, 0x93, ++ 0xf2, 0x3f, 0x60, 0x7b, 0x22, 0xd3, 0xcb, 0xf6, 0xe0, 0xf7, 0x12, 0x8f, ++ 0xc9, 0x09, 0xbd, 0x3e, 0x3d, 0xed, 0x93, 0xf8, 0x2d, 0xdc, 0x75, 0xc7, ++ 0x6e, 0x05, 0x9d, 0x94, 0xf3, 0x28, 0x6d, 0xe6, 0xfe, 0x28, 0xbc, 0x5d, ++ 0x57, 0x91, 0xa3, 0x90, 0xf3, 0x61, 0x4e, 0x00, 0x8f, 0x8c, 0x23, 0x91, ++ 0xd7, 0xa7, 0xe6, 0x05, 0xf0, 0x26, 0xe5, 0x08, 0xae, 0x57, 0x94, 0xe4, ++ 0xf4, 0xac, 0xb9, 0x58, 0x4e, 0x2d, 0x1e, 0x2f, 0xc9, 0xd9, 0x43, 0x39, ++ 0xd7, 0xb4, 0xc0, 0x5b, 0x7b, 0x8d, 0xcc, 0x55, 0x1b, 0xfd, 0xa7, 0x16, ++ 0x19, 0x17, 0xdb, 0xc9, 0xe9, 0x3e, 0x06, 0x45, 0x5f, 0x28, 0xfc, 0xff, ++ 0x1b, 0x6e, 0xbd, 0x9b, 0xda, 0xa6, 0xa6, 0xeb, 0x09, 0x9e, 0x67, 0x5a, ++ 0xa6, 0xe8, 0xa8, 0x65, 0xdd, 0x34, 0x62, 0xeb, 0xee, 0xea, 0x72, 0x7f, ++ 0xd9, 0x4e, 0xb9, 0x8d, 0x06, 0xde, 0x0b, 0xe1, 0x11, 0xe6, 0x71, 0x37, ++ 0xb1, 0x9d, 0x03, 0x86, 0x70, 0xb1, 0x56, 0xa3, 0x4a, 0x91, 0xbc, 0x36, ++ 0xcc, 0xb8, 0xde, 0x80, 0x3e, 0x37, 0x16, 0x84, 0x59, 0x7f, 0x77, 0x5d, ++ 0x91, 0x4f, 0xc0, 0x77, 0x2b, 0xcb, 0x76, 0xc6, 0x8b, 0xed, 0xf9, 0x74, ++ 0xc9, 0x15, 0xdb, 0xb1, 0x7f, 0xf8, 0xfc, 0xf3, 0xc8, 0x4d, 0xfa, 0xcc, ++ 0xf9, 0x9a, 0x8a, 0x10, 0x4b, 0x2b, 0x50, 0x5d, 0x21, 0x58, 0x7f, 0xd1, ++ 0xd8, 0xb7, 0x8c, 0xff, 0x29, 0xef, 0x57, 0x63, 0xeb, 0xb8, 0x83, 0x2d, ++ 0x6e, 0x9e, 0x50, 0x81, 0xde, 0x36, 0xc1, 0x43, 0xb1, 0xa5, 0x39, 0x92, ++ 0x27, 0x25, 0x72, 0x90, 0x18, 0x27, 0xf6, 0xb3, 0xc6, 0xb5, 0x1f, 0x8f, ++ 0x32, 0xd3, 0x7e, 0x36, 0xe3, 0xbb, 0xfa, 0xa1, 0x3b, 0x2a, 0x71, 0xe8, ++ 0x2e, 0x59, 0xff, 0xde, 0x10, 0xc7, 0xe1, 0x5b, 0xe8, 0x9b, 0xaf, 0x13, ++ 0x5b, 0xb6, 0xb4, 0x30, 0x86, 0xb8, 0x98, 0xa5, 0xa0, 0x92, 0xb1, 0x7d, ++ 0xdb, 0x6e, 0xe6, 0xc0, 0x6a, 0x90, 0x6d, 0x5e, 0x8a, 0x5d, 0xd2, 0x7f, ++ 0x83, 0xb9, 0xee, 0xa1, 0x2f, 0x56, 0x22, 0x20, 0x39, 0xc7, 0x4f, 0x4e, ++ 0x51, 0xc6, 0x4d, 0x46, 0x59, 0x57, 0xa2, 0xa7, 0xb2, 0x9c, 0x06, 0xa4, ++ 0x77, 0x97, 0xeb, 0x2b, 0x78, 0x29, 0x1a, 0x2e, 0xad, 0x3f, 0x37, 0x60, ++ 0x60, 0xfc, 0xd0, 0x31, 0x72, 0x0d, 0x27, 0xd1, 0x72, 0x68, 0x63, 0x98, ++ 0x7d, 0x39, 0x13, 0x2f, 0xcf, 0xa9, 0xf8, 0xe6, 0x4c, 0x19, 0x62, 0xbb, ++ 0x50, 0x6a, 0x17, 0x62, 0x4b, 0x2d, 0x6d, 0x34, 0x1f, 0x45, 0xaa, 0xc6, ++ 0xac, 0x85, 0x3d, 0x4e, 0xdf, 0x9a, 0xa8, 0x80, 0xf7, 0x5a, 0x89, 0x7d, ++ 0xc2, 0x77, 0xbc, 0x37, 0x9c, 0xb0, 0x2b, 0xf0, 0x69, 0xe3, 0x9c, 0x23, ++ 0xb8, 0x78, 0x4c, 0xc7, 0xe5, 0x15, 0xc4, 0xc4, 0x85, 0xf1, 0x68, 0x72, ++ 0x1d, 0xf3, 0xc2, 0x23, 0x6d, 0xde, 0x1b, 0xde, 0xca, 0xff, 0x9a, 0xdc, ++ 0xf2, 0xd2, 0xf1, 0x88, 0x3e, 0x70, 0x74, 0x45, 0x54, 0xda, 0x94, 0xf6, ++ 0xca, 0x36, 0x2a, 0xed, 0x3b, 0x4e, 0x34, 0x1e, 0x70, 0xe7, 0xbc, 0x3c, ++ 0x86, 0x37, 0xf4, 0xf2, 0x18, 0x02, 0x8c, 0xa7, 0x49, 0x72, 0x57, 0xe1, ++ 0xd5, 0x7e, 0xe6, 0x91, 0x5e, 0xf2, 0xf1, 0x6e, 0x08, 0xdf, 0x3b, 0x4a, ++ 0x7e, 0xf2, 0xa4, 0x0d, 0xbc, 0x93, 0x75, 0xb0, 0x2c, 0x3e, 0x8b, 0xf8, ++ 0xd2, 0x4f, 0xd9, 0xb2, 0xa6, 0x76, 0x50, 0x19, 0x67, 0xae, 0x79, 0xdc, ++ 0x5b, 0x95, 0x54, 0x99, 0x5b, 0x1e, 0xc8, 0x47, 0xc3, 0x87, 0x98, 0x67, ++ 0xfa, 0x99, 0xeb, 0x72, 0x06, 0x94, 0x27, 0x99, 0x67, 0xee, 0x2b, 0xe5, ++ 0x99, 0x07, 0xf2, 0x01, 0xe4, 0xb3, 0xc4, 0xc6, 0x38, 0xf3, 0x5b, 0x37, ++ 0x4f, 0x0f, 0x60, 0x32, 0xab, 0x32, 0x1f, 0x7f, 0xdf, 0x99, 0xaa, 0x77, ++ 0xf7, 0x0b, 0xf0, 0x75, 0xbb, 0x01, 0x07, 0x87, 0x9b, 0x70, 0x36, 0x3f, ++ 0x45, 0xbb, 0xb8, 0x0c, 0xd3, 0xa3, 0xb5, 0x98, 0x18, 0x7e, 0x95, 0x9f, ++ 0xdb, 0xf0, 0xfe, 0xa8, 0x9b, 0xe3, 0x12, 0x0f, 0xa5, 0x7f, 0x07, 0x95, ++ 0x43, 0x6e, 0x8e, 0x6b, 0x25, 0x99, 0xdb, 0x26, 0xfa, 0x4b, 0xb9, 0xed, ++ 0x14, 0x73, 0xdb, 0x23, 0x6c, 0xf3, 0x85, 0x52, 0x9b, 0xcf, 0xb9, 0xff, ++ 0xa5, 0x2f, 0x52, 0x77, 0x66, 0xbd, 0x44, 0x52, 0xd6, 0xa6, 0xc7, 0xed, ++ 0x68, 0xac, 0x5c, 0xf7, 0x05, 0xd6, 0x3b, 0x72, 0xbe, 0xde, 0x6a, 0x0c, ++ 0x64, 0xd6, 0x90, 0xe7, 0xcb, 0xda, 0xca, 0x7b, 0x6b, 0x6c, 0xea, 0xf2, ++ 0xcb, 0xd1, 0xa9, 0xee, 0x59, 0xa8, 0xc3, 0xfa, 0xb8, 0x70, 0xa2, 0xb7, ++ 0xc8, 0x89, 0x22, 0x89, 0x95, 0x8c, 0x0f, 0x9e, 0x68, 0x84, 0x58, 0x0f, ++ 0x44, 0x27, 0x98, 0x03, 0xe4, 0xeb, 0x70, 0x37, 0x73, 0x31, 0xb5, 0x7e, ++ 0x75, 0x69, 0x0f, 0xab, 0x94, 0xe3, 0x78, 0xd6, 0xa0, 0x6f, 0x52, 0xe4, ++ 0xad, 0x26, 0xbf, 0xae, 0xc1, 0x2d, 0xc5, 0x75, 0x0b, 0xbf, 0x9f, 0xb2, ++ 0xfd, 0xd1, 0xa9, 0x18, 0x5d, 0xc6, 0x38, 0xc0, 0x1b, 0xcf, 0xd9, 0x0a, ++ 0x96, 0xe9, 0x3e, 0xac, 0x0b, 0xd6, 0x61, 0x99, 0xf1, 0xef, 0xce, 0x2d, ++ 0xab, 0xe5, 0xd9, 0x79, 0x1e, 0xe1, 0xaf, 0x64, 0xbb, 0x6f, 0x92, 0x53, ++ 0x8f, 0xf3, 0xcb, 0x54, 0xbe, 0x78, 0xdf, 0xca, 0x53, 0x36, 0xe5, 0x6e, ++ 0xa3, 0xdc, 0x7b, 0x83, 0x6e, 0xbe, 0x5b, 0x2a, 0x37, 0x15, 0xf3, 0x10, ++ 0xd7, 0xa5, 0x6c, 0x27, 0xe5, 0xde, 0x4d, 0xb9, 0xfd, 0x41, 0xe9, 0xdf, ++ 0xbf, 0x3b, 0xf7, 0xae, 0x96, 0x67, 0xe5, 0x7d, 0x13, 0x29, 0xff, 0x9e, ++ 0xc8, 0x35, 0xc6, 0x4b, 0x6d, 0x1d, 0xb2, 0x91, 0x95, 0xdc, 0x6f, 0x6d, ++ 0x47, 0x54, 0xeb, 0x75, 0xd7, 0xb2, 0x35, 0xac, 0xcb, 0x6b, 0xb8, 0x87, ++ 0xba, 0xcb, 0x79, 0xcb, 0x63, 0x72, 0xfb, 0x64, 0x09, 0x77, 0x5e, 0xce, ++ 0x72, 0x7d, 0x25, 0xdc, 0xee, 0xcc, 0x8b, 0x0d, 0xcd, 0xdc, 0x4f, 0x6a, ++ 0x2a, 0xf9, 0xb3, 0x17, 0x4f, 0xdb, 0x1f, 0x9c, 0x1b, 0xcc, 0x48, 0x3c, ++ 0x93, 0xf5, 0x10, 0x0d, 0xd9, 0xfc, 0xe5, 0x68, 0x1e, 0x0a, 0x62, 0xad, ++ 0x31, 0x9b, 0xbe, 0xfe, 0xa5, 0xf3, 0x36, 0x75, 0x80, 0xed, 0xc0, 0xe7, ++ 0x8a, 0x57, 0x9e, 0xce, 0xb7, 0x06, 0x1b, 0x70, 0xe9, 0x1e, 0xd2, 0xfc, ++ 0x64, 0x8d, 0x19, 0xed, 0xfe, 0x0e, 0xe7, 0xae, 0xca, 0xe5, 0xd0, 0x5b, ++ 0x94, 0x1c, 0xe7, 0xef, 0xa9, 0xd2, 0xfc, 0x3d, 0x99, 0xbf, 0xae, 0xb2, ++ 0x88, 0x45, 0x97, 0xa3, 0x65, 0x48, 0xfe, 0x07, 0xf1, 0x46, 0xc7, 0xc7, ++ 0x79, 0xef, 0x72, 0x2c, 0x1c, 0xf9, 0x54, 0x25, 0xb9, 0xb5, 0x51, 0xcc, ++ 0xc1, 0x2f, 0xcd, 0x33, 0x22, 0xfd, 0x16, 0x16, 0xb0, 0x5c, 0x13, 0x75, ++ 0x26, 0x18, 0x28, 0xfd, 0x7a, 0xe4, 0x7c, 0xbf, 0xbe, 0xcc, 0x7e, 0xa5, ++ 0x7c, 0xb2, 0xd6, 0x2a, 0xfd, 0x52, 0x92, 0xb5, 0x66, 0x13, 0xde, 0x1f, ++ 0x40, 0x30, 0x68, 0x46, 0x53, 0x2f, 0xd3, 0xde, 0x27, 0xd8, 0xd7, 0x7a, ++ 0xf4, 0x2b, 0x79, 0x77, 0xaf, 0xea, 0x20, 0xcb, 0xcc, 0x8c, 0xa3, 0xd2, ++ 0x4f, 0xaf, 0xe4, 0x59, 0x3e, 0xd9, 0x67, 0xf2, 0xe9, 0x22, 0xff, 0x6d, ++ 0x72, 0xc5, 0x3e, 0xca, 0x4f, 0x72, 0xfe, 0xfc, 0x6c, 0x03, 0x56, 0xb5, ++ 0xd9, 0xed, 0x72, 0x55, 0x2f, 0xfd, 0x6e, 0x19, 0x6d, 0xea, 0xc9, 0x9c, ++ 0x82, 0x51, 0x2a, 0xfd, 0x68, 0x56, 0xd6, 0x89, 0xc3, 0x38, 0x90, 0xf3, ++ 0xe1, 0x85, 0xec, 0x3c, 0x8c, 0xe7, 0x2a, 0xf0, 0x5c, 0xf6, 0x32, 0xec, ++ 0xcb, 0x11, 0xfd, 0xb2, 0x97, 0x63, 0x24, 0xe7, 0xc7, 0x4f, 0xb2, 0xd4, ++ 0x53, 0xae, 0x0a, 0xff, 0x9c, 0xfd, 0x13, 0x7c, 0x3d, 0x57, 0x8d, 0xd7, ++ 0xb2, 0x57, 0xe0, 0x60, 0xae, 0x06, 0xaf, 0x64, 0xc9, 0x27, 0x73, 0x01, ++ 0xbc, 0x9c, 0xd5, 0x50, 0xc8, 0xcd, 0xc2, 0x4b, 0xd9, 0x08, 0x26, 0x72, ++ 0xb5, 0xf8, 0x6e, 0x76, 0x01, 0xf2, 0xb9, 0x3a, 0x7c, 0x27, 0xdb, 0x8c, ++ 0x2f, 0xe7, 0x82, 0x78, 0x31, 0xab, 0xe3, 0xa9, 0x5c, 0x3d, 0x8e, 0x65, ++ 0xa3, 0x6c, 0x37, 0x84, 0xa3, 0xc3, 0x31, 0x1c, 0x18, 0x6d, 0xc4, 0x0b, ++ 0xc3, 0x8b, 0x30, 0x3e, 0x1a, 0xc6, 0x73, 0xc3, 0x6d, 0xd8, 0x37, 0xfa, ++ 0x6f, 0x15, 0xa2, 0x9f, 0x23, 0xf6, 0xff, 0x38, 0xaf, 0xc7, 0x6d, 0x1f, ++ 0x31, 0xdf, 0xaf, 0xda, 0xa2, 0x37, 0xbf, 0x55, 0xcf, 0x39, 0x7a, 0x3a, ++ 0xef, 0xce, 0x3b, 0xf4, 0x21, 0x77, 0x7f, 0x06, 0x7d, 0xc6, 0x65, 0xcc, ++ 0xd9, 0xfa, 0x25, 0x7e, 0xd0, 0x16, 0x0e, 0x2a, 0xdb, 0x5d, 0x1c, 0xa9, ++ 0x4d, 0xce, 0xa2, 0x2e, 0x39, 0xec, 0x60, 0x0d, 0x7d, 0x32, 0x4b, 0x7f, ++ 0xb6, 0x38, 0xaf, 0x76, 0xfe, 0xa0, 0xb2, 0x83, 0x39, 0xe2, 0x95, 0x43, ++ 0x96, 0x53, 0xed, 0xe2, 0x69, 0x34, 0xb9, 0x88, 0x3e, 0x17, 0x1b, 0x11, ++ 0x7d, 0xde, 0x59, 0x21, 0xfa, 0xac, 0xd0, 0x3f, 0xcc, 0x4e, 0xca, 0x7a, ++ 0x0f, 0x94, 0xec, 0xe1, 0xfb, 0x95, 0xc5, 0xbc, 0xaa, 0x3c, 0xef, 0x8e, ++ 0x33, 0x68, 0x94, 0xe7, 0x9e, 0xfc, 0xaf, 0x41, 0xd6, 0xa4, 0xc0, 0x58, ++ 0x50, 0x8f, 0x5c, 0x48, 0xf2, 0xf5, 0x99, 0x98, 0x81, 0x64, 0xa5, 0x19, ++ 0xd5, 0x5a, 0xd4, 0x99, 0x7c, 0x45, 0xb0, 0x43, 0xe4, 0x5b, 0x2e, 0xee, ++ 0x1c, 0x3e, 0x8f, 0x1f, 0x67, 0x2b, 0x85, 0xa7, 0xec, 0xb7, 0xa5, 0x6f, ++ 0x50, 0x2b, 0xa4, 0xcf, 0x28, 0xde, 0x43, 0xa1, 0xac, 0xaf, 0x99, 0x76, ++ 0xa7, 0x52, 0xb7, 0x62, 0x7b, 0x5e, 0xfa, 0xc2, 0x72, 0x89, 0x7b, 0xec, ++ 0x47, 0x13, 0x5e, 0xb0, 0x8b, 0x7b, 0x33, 0xe3, 0x79, 0xd1, 0xb7, 0x86, ++ 0xad, 0xe4, 0x5e, 0x87, 0x87, 0x15, 0xea, 0xee, 0x2f, 0x51, 0xdc, 0x3f, ++ 0xf2, 0xd2, 0x57, 0xd7, 0xb2, 0x3c, 0x63, 0x7c, 0x61, 0xda, 0xdd, 0x1b, ++ 0xae, 0x73, 0xf3, 0xee, 0x30, 0x0a, 0x03, 0x1f, 0x9c, 0xdb, 0x96, 0xf9, ++ 0xe5, 0xb9, 0x3d, 0x99, 0x68, 0x4a, 0xf6, 0x67, 0xf2, 0x13, 0x3e, 0xe4, ++ 0xf6, 0x06, 0xf0, 0xd4, 0x84, 0x1f, 0x35, 0x69, 0xc9, 0xf3, 0x83, 0x78, ++ 0x6a, 0xff, 0xa1, 0x15, 0x35, 0x68, 0xe0, 0xff, 0x10, 0xaf, 0x46, 0x5e, ++ 0x01, 0x1c, 0x1b, 0xf5, 0xe3, 0x2d, 0x5b, 0x7c, 0x58, 0xfc, 0xa3, 0x8d, ++ 0xd8, 0x1f, 0x60, 0xbc, 0x55, 0x19, 0x47, 0x9a, 0x70, 0x38, 0x1f, 0xc4, ++ 0xf2, 0x6c, 0x3d, 0x9e, 0xcb, 0x25, 0xf1, 0x44, 0xa6, 0x1e, 0x67, 0x1f, ++ 0xf3, 0x63, 0xde, 0x3e, 0xf1, 0x87, 0x06, 0x9c, 0x1e, 0xfc, 0x04, 0x0a, ++ 0x7b, 0x93, 0xb0, 0x33, 0xb3, 0xb1, 0x63, 0xb0, 0x01, 0xdf, 0x61, 0x99, ++ 0x7e, 0xea, 0xa9, 0x7a, 0xa7, 0x89, 0x17, 0x69, 0x43, 0x55, 0x3b, 0x6f, ++ 0xa4, 0xec, 0x30, 0x7c, 0x03, 0x21, 0x1c, 0xc9, 0x7b, 0x85, 0xd7, 0x71, ++ 0x1e, 0x7f, 0x5a, 0x9c, 0x17, 0x08, 0x6f, 0xbd, 0x98, 0x07, 0x1e, 0x3f, ++ 0xcf, 0x03, 0x81, 0x5c, 0x5e, 0xd6, 0x18, 0xdb, 0x3a, 0xfb, 0xec, 0x89, ++ 0xff, 0xcf, 0x6f, 0xfe, 0xf4, 0xdb, 0x15, 0x4b, 0x0c, 0x62, 0x9d, 0x8c, ++ 0x7f, 0xed, 0x83, 0xd5, 0xe6, 0x86, 0x2f, 0xae, 0x58, 0x52, 0x89, 0xfb, ++ 0xdd, 0xf9, 0xea, 0x81, 0xbd, 0xbb, 0x9b, 0xf1, 0xb5, 0xb5, 0x67, 0x40, ++ 0xb9, 0x02, 0xa9, 0xfa, 0x21, 0xde, 0x53, 0x4b, 0x3e, 0x07, 0x55, 0x6c, ++ 0xad, 0x8e, 0xfa, 0x54, 0x0b, 0x1a, 0x4e, 0xd0, 0xc8, 0x6a, 0xd3, 0x11, ++ 0x4c, 0xd5, 0xcb, 0x38, 0x63, 0xcc, 0xb3, 0x3c, 0xb2, 0x77, 0x8d, 0x4f, ++ 0x33, 0xc6, 0x9d, 0x5d, 0xac, 0x20, 0xf1, 0x67, 0xe2, 0x83, 0xb7, 0x96, ++ 0xf6, 0x80, 0x65, 0x3f, 0x4c, 0xe6, 0xad, 0xac, 0xff, 0xbd, 0xb2, 0xee, ++ 0xc9, 0x3f, 0xc1, 0x0a, 0x2f, 0x0e, 0xdb, 0x39, 0xe6, 0x08, 0x32, 0x07, ++ 0x32, 0xa6, 0xed, 0xac, 0x27, 0xe3, 0x92, 0xe7, 0xad, 0x89, 0xfa, 0x8f, ++ 0x1c, 0x97, 0x8c, 0x67, 0xad, 0x1f, 0xd5, 0x32, 0x86, 0xb2, 0x2e, 0xfa, ++ 0x58, 0xf7, 0x51, 0xde, 0x93, 0x7a, 0x8e, 0xb3, 0xfd, 0xa2, 0x98, 0x55, ++ 0x91, 0xac, 0x66, 0xdf, 0x9f, 0xb4, 0xa3, 0xc9, 0x77, 0x88, 0x8b, 0xc7, ++ 0xa8, 0xc3, 0x51, 0x5b, 0xec, 0x6f, 0x0b, 0xed, 0xae, 0x5f, 0x39, 0x7a, ++ 0xde, 0xf6, 0x80, 0x83, 0xb6, 0xcc, 0xaf, 0xf0, 0x29, 0x19, 0xaf, 0x86, ++ 0xe9, 0x89, 0xa0, 0xcb, 0xc7, 0xdf, 0xb6, 0xc5, 0x26, 0x62, 0xcc, 0xcf, ++ 0xa6, 0xcf, 0xf5, 0x66, 0x0c, 0x1c, 0xe3, 0xdc, 0x9e, 0xb6, 0xab, 0x88, ++ 0x37, 0x1d, 0x90, 0xbd, 0xce, 0xf7, 0xed, 0x04, 0x5e, 0x22, 0x66, 0xbd, ++ 0x47, 0x5b, 0xfb, 0x2e, 0x31, 0xec, 0x5d, 0x5b, 0xc7, 0x77, 0x68, 0x7b, ++ 0xef, 0xd8, 0x31, 0xbc, 0x98, 0xaf, 0xc7, 0x51, 0xe2, 0xd0, 0x49, 0x7e, ++ 0x5e, 0x9e, 0xf7, 0xc1, 0x0a, 0xc9, 0xbe, 0xda, 0x1e, 0x3f, 0x6a, 0x7b, ++ 0xd9, 0xe7, 0x48, 0x97, 0x1c, 0x44, 0x79, 0x96, 0xe3, 0xd3, 0x94, 0x32, ++ 0x0f, 0x29, 0xe7, 0x04, 0x49, 0x64, 0x33, 0x33, 0xb1, 0x21, 0xd2, 0x9f, ++ 0xa3, 0xdd, 0xfa, 0xd2, 0xe5, 0x38, 0xc0, 0xd8, 0x59, 0x10, 0xdb, 0xf6, ++ 0xc0, 0x33, 0x24, 0xf6, 0x7f, 0x0d, 0x75, 0x3d, 0x7d, 0x4e, 0xf6, 0xd2, ++ 0x54, 0x7d, 0x8a, 0xfe, 0x5e, 0x85, 0xde, 0xdc, 0xe5, 0xa8, 0x19, 0x5a, ++ 0x8a, 0xfb, 0xe3, 0xe2, 0xf7, 0x7e, 0xf4, 0xe7, 0x3c, 0xa8, 0x1c, 0x22, ++ 0x77, 0x61, 0xd9, 0xa9, 0x50, 0x31, 0x1e, 0xa9, 0x69, 0xc3, 0xf5, 0x83, ++ 0x05, 0x85, 0x0f, 0xce, 0xd9, 0x99, 0x43, 0xf3, 0x54, 0x4c, 0x9f, 0x4b, ++ 0x67, 0x02, 0xe8, 0xa3, 0x4d, 0xab, 0x69, 0x05, 0x75, 0x7a, 0x88, 0xf9, ++ 0x5f, 0x1b, 0x7a, 0xa9, 0x8b, 0xf9, 0xe9, 0x26, 0x3c, 0x31, 0xd1, 0x88, ++ 0x79, 0xbb, 0x4c, 0x3c, 0x4e, 0xdb, 0x0f, 0xef, 0xba, 0x11, 0x7b, 0x58, ++ 0xee, 0x15, 0x3e, 0x7b, 0x65, 0x7f, 0x03, 0xaf, 0x10, 0xaf, 0x46, 0x5e, ++ 0xf5, 0x18, 0xd8, 0xab, 0x97, 0xce, 0x61, 0x78, 0xd0, 0x30, 0x24, 0xf8, ++ 0xa2, 0xe2, 0x8e, 0x76, 0x05, 0xc6, 0xd5, 0x6c, 0x73, 0xe1, 0x87, 0x61, ++ 0x4d, 0xc3, 0x1f, 0xd0, 0xef, 0x1f, 0x38, 0x53, 0xe7, 0xed, 0xc7, 0x0f, ++ 0x6f, 0xfa, 0xfb, 0xae, 0xfd, 0x2c, 0x28, 0x48, 0x3b, 0xef, 0x12, 0x33, ++ 0xc4, 0x86, 0x7e, 0x17, 0x9e, 0x95, 0xf5, 0xfe, 0xdb, 0x67, 0x2b, 0x70, ++ 0xde, 0xbe, 0x2e, 0x5a, 0x77, 0x47, 0x9e, 0x36, 0xb1, 0xc3, 0x3d, 0x3b, ++ 0x22, 0xb9, 0x4e, 0xa4, 0x2b, 0x47, 0xfd, 0xf4, 0x33, 0x87, 0xb9, 0x87, ++ 0x38, 0xb1, 0x3d, 0x13, 0xb1, 0x2c, 0xb6, 0xe5, 0x23, 0x36, 0x3c, 0x30, ++ 0xe8, 0x97, 0xf5, 0x6e, 0xcd, 0xa7, 0xcf, 0xc3, 0x3b, 0x39, 0xb1, 0xf9, ++ 0x2a, 0x1c, 0xce, 0x86, 0x71, 0xca, 0xfd, 0x5c, 0xcd, 0x58, 0xe3, 0xa0, ++ 0xd3, 0x98, 0x85, 0xbe, 0x60, 0x15, 0x06, 0x62, 0x37, 0x22, 0x77, 0x07, ++ 0x73, 0x6c, 0xfa, 0x58, 0xad, 0xee, 0x47, 0x3a, 0x28, 0xf9, 0x8b, 0x07, ++ 0x99, 0xd8, 0xed, 0x38, 0x5e, 0xef, 0xc5, 0x3c, 0x59, 0x6f, 0xe1, 0xb3, ++ 0x3d, 0x41, 0x28, 0xf4, 0xbd, 0xa4, 0x8f, 0xb8, 0x34, 0x6b, 0x00, 0x4e, ++ 0xad, 0xa9, 0xcb, 0x1e, 0x4c, 0xcf, 0x56, 0xe2, 0x52, 0xcd, 0x44, 0x0d, ++ 0xe3, 0x4e, 0x0b, 0xaa, 0xf7, 0xca, 0x5e, 0x40, 0x00, 0xeb, 0x86, 0xaf, ++ 0x95, 0xbd, 0x81, 0x98, 0xa6, 0x04, 0x70, 0xef, 0xb0, 0xc4, 0x8f, 0x35, ++ 0xa8, 0xd8, 0x5f, 0x8b, 0x2f, 0x66, 0xbd, 0xc4, 0x78, 0xe2, 0x0d, 0xcb, ++ 0xed, 0xc9, 0xd4, 0xa1, 0xee, 0xb1, 0x67, 0x9d, 0x30, 0x75, 0x5c, 0xb7, ++ 0x57, 0xb0, 0x88, 0xb6, 0x9b, 0xf9, 0x3c, 0x0a, 0x76, 0x33, 0xe5, 0xf6, ++ 0x70, 0x7c, 0x21, 0xbc, 0x4b, 0xec, 0xaa, 0x99, 0x08, 0xe3, 0x9d, 0xdd, ++ 0x92, 0xab, 0x24, 0xe1, 0x9d, 0xb8, 0x0c, 0x6f, 0xf2, 0xf3, 0x09, 0xa3, ++ 0x13, 0xea, 0x44, 0x13, 0x4e, 0x66, 0xba, 0xe0, 0x99, 0xa8, 0x2d, 0x62, ++ 0xd8, 0x5e, 0x3f, 0xea, 0x06, 0xf5, 0xd8, 0x34, 0xe7, 0xc8, 0xb7, 0x97, ++ 0x04, 0xa7, 0x51, 0xda, 0x3f, 0x6f, 0xdb, 0xc6, 0x85, 0x7d, 0x87, 0xf2, ++ 0xd9, 0x15, 0xb1, 0xef, 0xef, 0x3a, 0x4f, 0x04, 0xd9, 0xbf, 0x8e, 0x08, ++ 0xfa, 0x62, 0xc7, 0x64, 0x3f, 0x9f, 0xe3, 0x4b, 0x72, 0xee, 0x9f, 0x77, ++ 0xe4, 0x5c, 0x88, 0xcf, 0x94, 0x33, 0x19, 0xcf, 0x39, 0xdb, 0x57, 0xcb, ++ 0xfd, 0xdb, 0xab, 0x50, 0xcd, 0xc4, 0xc9, 0x14, 0x99, 0x3b, 0x64, 0x6e, ++ 0x19, 0x75, 0x3e, 0x4c, 0xe6, 0x3f, 0x3a, 0x8f, 0x9f, 0x2f, 0x8f, 0xa0, ++ 0xcf, 0x5d, 0x13, 0xbf, 0xe0, 0xcb, 0x35, 0x9c, 0xbb, 0xf5, 0x25, 0x5f, ++ 0x7e, 0xc7, 0x96, 0xf9, 0x93, 0xf3, 0x4b, 0x01, 0x72, 0x30, 0x03, 0xd5, ++ 0x9c, 0xbb, 0xf7, 0x6d, 0x28, 0xb7, 0x76, 0x74, 0x63, 0xd6, 0x44, 0x80, ++ 0xbe, 0x1e, 0x59, 0x6f, 0xc1, 0x66, 0x5b, 0x1d, 0xa8, 0x62, 0x9d, 0x93, ++ 0xb6, 0x87, 0x7e, 0x9e, 0xe0, 0x98, 0x83, 0x70, 0x5c, 0x5e, 0xbf, 0x1a, ++ 0xf3, 0xa9, 0xa7, 0xb3, 0xb6, 0x89, 0x79, 0xd4, 0xd3, 0xb4, 0xed, 0x25, ++ 0x4e, 0x34, 0x11, 0x0f, 0x34, 0xd4, 0x12, 0x1b, 0x2b, 0x06, 0x1d, 0x1c, ++ 0x32, 0xea, 0xc8, 0xf5, 0xc5, 0x4e, 0x3b, 0x10, 0x1e, 0x30, 0x30, 0x6f, ++ 0xa0, 0x79, 0xe3, 0x3c, 0x8f, 0x07, 0xc7, 0x7d, 0xc5, 0xd8, 0x93, 0x9b, ++ 0x23, 0xfa, 0x91, 0x31, 0xb9, 0xb9, 0xfc, 0x87, 0x60, 0xc0, 0x6a, 0x80, ++ 0xb2, 0x0a, 0xc4, 0x8c, 0xcf, 0xb1, 0xad, 0x37, 0xec, 0x57, 0x71, 0xf3, ++ 0x84, 0xe0, 0xcb, 0x0f, 0xb1, 0x92, 0xfd, 0x78, 0x97, 0xb8, 0x76, 0x5f, ++ 0xf4, 0x1b, 0x1c, 0x6b, 0x13, 0x6e, 0x99, 0x98, 0x3e, 0xd7, 0xe7, 0x8e, ++ 0xb3, 0x9c, 0xff, 0xf9, 0x71, 0x5f, 0xb6, 0x7c, 0x06, 0x2d, 0x49, 0x9f, ++ 0x91, 0x38, 0xe1, 0x87, 0xf8, 0x4d, 0xb7, 0xbd, 0x0d, 0xc5, 0x78, 0x2e, ++ 0x57, 0x59, 0x8f, 0x3b, 0xbd, 0x92, 0x97, 0x17, 0x7d, 0x43, 0xfa, 0xf3, ++ 0xbb, 0xca, 0x14, 0x7d, 0x43, 0xfc, 0xe2, 0xcb, 0xae, 0x7e, 0x85, 0x77, ++ 0x69, 0xb8, 0x6d, 0xe2, 0x97, 0xc4, 0xc7, 0x48, 0x32, 0x47, 0xcc, 0x7e, ++ 0x9d, 0xfa, 0xdd, 0x4e, 0xfd, 0x32, 0x07, 0x60, 0xbc, 0x4a, 0x50, 0x9f, ++ 0x3e, 0x72, 0x15, 0x2f, 0x31, 0xd3, 0xa4, 0x2e, 0x41, 0x0c, 0x64, 0xee, ++ 0x1e, 0x2c, 0x8e, 0x37, 0x77, 0x7e, 0xfe, 0xd8, 0x96, 0x92, 0xc0, 0x09, ++ 0xfb, 0x87, 0x55, 0x72, 0x26, 0xe8, 0xa4, 0xed, 0x3e, 0x97, 0x35, 0xcd, ++ 0x19, 0x65, 0x2e, 0xb4, 0xbd, 0xcf, 0x16, 0xfe, 0x5c, 0x49, 0xbb, 0xd6, ++ 0x28, 0xaf, 0xa6, 0x84, 0xa9, 0x52, 0x57, 0xf6, 0x60, 0xa5, 0xfd, 0x6e, ++ 0xe1, 0x20, 0x78, 0x83, 0x3e, 0x77, 0xc4, 0xa8, 0xc0, 0xa8, 0x3b, 0x17, ++ 0x62, 0x8f, 0xc5, 0x76, 0x2f, 0xd8, 0x4d, 0xba, 0xae, 0x74, 0x1e, 0xab, ++ 0xba, 0xc8, 0xc9, 0x2e, 0x6d, 0xa3, 0xe2, 0x3f, 0xb1, 0x8d, 0x44, 0xa9, ++ 0x8d, 0x8f, 0x3a, 0xe3, 0x06, 0x3c, 0x65, 0x4b, 0xec, 0x97, 0xfd, 0x0f, ++ 0x0d, 0x8b, 0x26, 0x04, 0x5f, 0xe8, 0xbb, 0x03, 0xd3, 0x2e, 0xf7, 0xcf, ++ 0x41, 0xf6, 0xb6, 0x42, 0xf0, 0x45, 0x35, 0x9c, 0xd2, 0x63, 0x58, 0x58, ++ 0x90, 0xfd, 0xa9, 0x7d, 0x75, 0xc2, 0xe1, 0xce, 0xe8, 0xc2, 0x3b, 0x64, ++ 0xbe, 0xca, 0xf7, 0xfc, 0xd8, 0xaf, 0x17, 0xfb, 0x9a, 0x54, 0x8b, 0xdc, ++ 0xd1, 0x43, 0xee, 0xd8, 0x6b, 0xf8, 0x69, 0x97, 0xad, 0xc1, 0xd9, 0xbf, ++ 0x73, 0x2f, 0xab, 0xdc, 0xdf, 0xdf, 0x57, 0xee, 0xc2, 0x7a, 0x5c, 0xf6, ++ 0xa2, 0xfd, 0x21, 0x19, 0xd3, 0x5c, 0xa0, 0x41, 0xe2, 0x55, 0x91, 0xa3, ++ 0x6e, 0x3d, 0x9f, 0xff, 0x58, 0xca, 0x60, 0xfe, 0x31, 0xd4, 0xeb, 0x0b, ++ 0x50, 0xdf, 0x50, 0xc3, 0xb8, 0x1c, 0xed, 0xa2, 0x7b, 0x4b, 0x2c, 0xb3, ++ 0x82, 0xa6, 0xe4, 0xbf, 0xc2, 0x5b, 0xa5, 0xcd, 0x7e, 0xa5, 0xaa, 0x20, ++ 0xed, 0x1e, 0x54, 0xfc, 0x85, 0x0f, 0x6b, 0x5b, 0xce, 0xfb, 0x4d, 0x9f, ++ 0x1b, 0xca, 0x74, 0xbb, 0x7b, 0x8c, 0xcb, 0x86, 0x1c, 0xdc, 0x69, 0x34, ++ 0xe1, 0xee, 0x06, 0x69, 0xa3, 0x98, 0xc3, 0x68, 0xea, 0x34, 0x39, 0xdc, ++ 0x6f, 0x1c, 0x55, 0x97, 0xcf, 0x3e, 0x78, 0x1e, 0xd3, 0xa7, 0xd7, 0x42, ++ 0xc5, 0xd9, 0xeb, 0x24, 0x9f, 0xf1, 0x91, 0x7f, 0x6d, 0xaa, 0x2e, 0xee, ++ 0x2f, 0x8b, 0x1d, 0x4b, 0x3f, 0xfc, 0xf4, 0xb3, 0x0b, 0xfd, 0xd8, 0xf6, ++ 0x07, 0xf5, 0xc3, 0x8f, 0x9b, 0x86, 0x92, 0x18, 0x35, 0x4e, 0x38, 0x56, ++ 0x68, 0x66, 0xdb, 0x3e, 0xac, 0x1c, 0xfa, 0x8d, 0x33, 0xcb, 0x6d, 0x5b, ++ 0x27, 0xa7, 0x52, 0xf1, 0xc0, 0x12, 0x1f, 0x6e, 0x1d, 0x89, 0x62, 0xc5, ++ 0x90, 0x8a, 0xd8, 0x12, 0xe9, 0x43, 0x14, 0x5d, 0x23, 0xbb, 0xbd, 0xc5, ++ 0xf2, 0xc0, 0x2d, 0x1c, 0xc3, 0x1b, 0x46, 0x0d, 0x7e, 0x40, 0x0c, 0xac, ++ 0x75, 0xb9, 0xfd, 0x46, 0x25, 0x23, 0xdc, 0xde, 0xa7, 0x62, 0xb6, 0x8e, ++ 0x60, 0x83, 0x99, 0xa4, 0xee, 0x3a, 0x95, 0xc7, 0x72, 0x1b, 0x95, 0xa1, ++ 0x7c, 0xb9, 0xef, 0x01, 0x7c, 0xa2, 0x10, 0xc4, 0x27, 0xc6, 0x1a, 0x78, ++ 0x85, 0x78, 0x35, 0xf2, 0x7a, 0xf1, 0xfc, 0xb8, 0xca, 0x67, 0x3c, 0x9f, ++ 0x65, 0x4e, 0xb1, 0xcd, 0xf5, 0x4b, 0x89, 0x0b, 0x9a, 0x9c, 0xd5, 0xc1, ++ 0x5b, 0x59, 0xc9, 0x27, 0xb6, 0xd1, 0x86, 0x65, 0x4d, 0xb8, 0x92, 0x39, ++ 0x45, 0x24, 0x36, 0x85, 0xbf, 0xaa, 0x2e, 0xce, 0x7d, 0xd1, 0x86, 0x71, ++ 0xde, 0x86, 0x7d, 0x78, 0x3b, 0xab, 0xa2, 0x25, 0xfe, 0x6f, 0xce, 0xf1, ++ 0xa0, 0xe0, 0xc9, 0xa5, 0xcf, 0xcb, 0x9c, 0x65, 0xfa, 0x5c, 0x36, 0xd3, ++ 0x34, 0x63, 0x5f, 0x56, 0x41, 0xc5, 0x90, 0xf0, 0xf3, 0xeb, 0x5c, 0xbe, ++ 0xf7, 0x7d, 0xc3, 0x07, 0xef, 0xd0, 0xa1, 0x2b, 0xe5, 0x68, 0x93, 0x6f, ++ 0x8c, 0x71, 0xab, 0x83, 0xf3, 0x32, 0xf2, 0xf1, 0x92, 0xce, 0xca, 0xba, ++ 0x50, 0xdc, 0x35, 0x49, 0xd5, 0x8d, 0xe9, 0x41, 0xa8, 0x63, 0xc2, 0x43, ++ 0xc9, 0x0d, 0xc6, 0x24, 0x1f, 0x08, 0xf1, 0xbf, 0xe4, 0x06, 0x8d, 0xfc, ++ 0xcf, 0xc4, 0xa2, 0x51, 0xe2, 0x78, 0x0f, 0xfa, 0x19, 0x9f, 0x2a, 0xa3, ++ 0x3d, 0xd8, 0x3e, 0xfe, 0x61, 0x31, 0xbf, 0x98, 0x63, 0x3d, 0x7b, 0xde, ++ 0xcf, 0xdc, 0x39, 0x62, 0x9f, 0xa6, 0xcf, 0x89, 0xcf, 0xc8, 0x5c, 0xed, ++ 0xcb, 0x4a, 0x1f, 0x1c, 0x6c, 0x30, 0x6e, 0x64, 0xdb, 0x3e, 0xa8, 0x0d, ++ 0x33, 0xb9, 0xe7, 0x79, 0x3e, 0x4d, 0xdd, 0x6d, 0x54, 0x46, 0x39, 0x27, ++ 0x96, 0xb7, 0x52, 0xd6, 0x87, 0x82, 0x15, 0x9c, 0x93, 0xaf, 0xe4, 0x45, ++ 0x46, 0xa7, 0x32, 0x9e, 0x9b, 0x59, 0x67, 0xa3, 0x32, 0x96, 0xff, 0x55, ++ 0xb5, 0xac, 0x99, 0x5f, 0xd0, 0x4d, 0xb9, 0x0f, 0x62, 0x63, 0x1a, 0xea, ++ 0xd3, 0xa2, 0x67, 0x19, 0xb3, 0x06, 0x2f, 0x79, 0x5c, 0x7d, 0xe1, 0x43, ++ 0xdb, 0x6c, 0xac, 0x72, 0xcf, 0x62, 0xc6, 0x18, 0x8b, 0x02, 0x56, 0x25, ++ 0x39, 0x1f, 0x6d, 0x34, 0xe5, 0x33, 0xbb, 0x3a, 0xf7, 0xd9, 0x0b, 0x83, ++ 0x87, 0x4b, 0x6b, 0x11, 0x6b, 0x21, 0xbc, 0x54, 0x71, 0x71, 0xd6, 0xa3, ++ 0x47, 0xb1, 0x9c, 0xb9, 0xee, 0x4d, 0xb9, 0x62, 0x7f, 0xc7, 0xd8, 0xdf, ++ 0x29, 0xd7, 0xf7, 0x92, 0xca, 0x68, 0x5e, 0x75, 0xfb, 0xed, 0x35, 0xa5, ++ 0xbf, 0x52, 0x97, 0xe3, 0xc9, 0xbf, 0x56, 0xca, 0xa9, 0x92, 0x18, 0xcc, ++ 0xcc, 0xf4, 0x61, 0xe9, 0x73, 0x2d, 0xda, 0x86, 0x3e, 0xa0, 0x9f, 0xc9, ++ 0xbc, 0x0a, 0xfe, 0xcc, 0xc3, 0xca, 0x91, 0x59, 0x68, 0x1d, 0x0a, 0xe3, ++ 0xb6, 0x91, 0x06, 0x2c, 0xda, 0xb5, 0x06, 0xd5, 0x63, 0x41, 0x5c, 0xb9, ++ 0x4b, 0xd6, 0xf8, 0x57, 0xa3, 0xb2, 0x70, 0x5b, 0x8d, 0xe4, 0xb8, 0x7a, ++ 0x3a, 0xc1, 0xf9, 0x4b, 0xa0, 0x22, 0x1d, 0x49, 0x24, 0x21, 0x6b, 0xa4, ++ 0x26, 0x2a, 0x0a, 0x26, 0xf9, 0xa4, 0xb3, 0x79, 0xbe, 0xe9, 0x73, 0xcf, ++ 0x9b, 0x2d, 0x2b, 0xd0, 0xe6, 0x39, 0x6e, 0x1f, 0x2f, 0x4f, 0xda, 0x71, ++ 0xce, 0x5e, 0x87, 0xcd, 0x35, 0x66, 0x13, 0x3c, 0x85, 0xcb, 0x91, 0x1c, ++ 0x69, 0xc3, 0xbc, 0x42, 0x03, 0x3a, 0x47, 0x42, 0x88, 0xa5, 0xc5, 0xc7, ++ 0x23, 0x5a, 0x4a, 0xed, 0x80, 0xbf, 0xc0, 0x78, 0x9a, 0xfe, 0x8d, 0xf3, ++ 0x16, 0xed, 0xa0, 0x87, 0xfa, 0xba, 0x26, 0xdd, 0x85, 0xba, 0x42, 0x00, ++ 0x57, 0x0f, 0x7d, 0x02, 0xb5, 0x23, 0x7e, 0xcc, 0x1a, 0xd2, 0x90, 0x5f, ++ 0xe2, 0x47, 0x60, 0x24, 0x8c, 0xea, 0xb4, 0xde, 0x75, 0x9b, 0x82, 0xe4, ++ 0xc2, 0x25, 0x61, 0xb6, 0x4d, 0x7b, 0xa3, 0x7f, 0x8d, 0x90, 0x7f, 0x2d, ++ 0xef, 0x06, 0x36, 0xa7, 0x05, 0x1b, 0x45, 0x27, 0x9f, 0x72, 0xcf, 0x9f, ++ 0xac, 0x4b, 0x7f, 0x18, 0xce, 0x95, 0xed, 0x5b, 0xfc, 0xdc, 0x72, 0xcf, ++ 0xc4, 0x32, 0x07, 0x52, 0xa6, 0x5b, 0xf4, 0xec, 0x3c, 0xde, 0xfb, 0x39, ++ 0xe3, 0xf3, 0x43, 0xe9, 0x80, 0x55, 0x6b, 0x6e, 0xc6, 0x55, 0xed, 0x11, ++ 0xab, 0xa0, 0xbc, 0xca, 0xf1, 0xff, 0x90, 0x41, 0xbb, 0x89, 0xfd, 0xfc, ++ 0x63, 0xe5, 0x5f, 0xba, 0xce, 0xb6, 0xe4, 0xa2, 0xf5, 0xb9, 0x23, 0xcc, ++ 0xe7, 0xa7, 0x2e, 0x5a, 0x9f, 0x13, 0xbc, 0x2f, 0x9f, 0x83, 0x90, 0xb9, ++ 0xd2, 0x66, 0xd8, 0xb7, 0xac, 0x17, 0x09, 0x36, 0xca, 0x7c, 0x95, 0xd7, ++ 0x8b, 0x7c, 0x58, 0x3e, 0x24, 0xb9, 0x92, 0xca, 0x3c, 0xa1, 0x05, 0xc9, ++ 0xd0, 0xa3, 0x9c, 0x03, 0x77, 0x4d, 0x89, 0xf7, 0x06, 0xf8, 0x59, 0xd6, ++ 0x7b, 0x34, 0xe2, 0x8f, 0x56, 0xca, 0x0b, 0xaa, 0x70, 0xeb, 0x50, 0x83, ++ 0xbb, 0x1f, 0xb5, 0x22, 0x7e, 0x39, 0x62, 0xf5, 0x5f, 0x62, 0x99, 0x0b, ++ 0x6b, 0x43, 0x57, 0x31, 0xdf, 0xa8, 0x71, 0xcf, 0x4a, 0x2c, 0xa3, 0xbe, ++ 0x2f, 0x47, 0xdb, 0x48, 0x11, 0xcf, 0x6e, 0x1b, 0x29, 0xe2, 0x56, 0x5a, ++ 0x6c, 0xce, 0x57, 0xb4, 0xb9, 0x2c, 0x6d, 0x2e, 0xa8, 0x77, 0x2a, 0xd9, ++ 0xdc, 0x47, 0xc5, 0x13, 0x04, 0xeb, 0xcc, 0xf2, 0x99, 0x6a, 0x62, 0x5e, ++ 0xfe, 0x48, 0xcd, 0x1f, 0x16, 0x7f, 0x2e, 0xd5, 0xd9, 0xb5, 0x7f, 0xa4, ++ 0xce, 0xca, 0x31, 0xeb, 0x82, 0xce, 0x06, 0x2f, 0xd1, 0xd9, 0x02, 0xea, ++ 0xa0, 0x41, 0x2f, 0xea, 0x6d, 0xb9, 0x71, 0x19, 0x52, 0xae, 0xde, 0xaa, ++ 0x64, 0x6d, 0x8c, 0xf7, 0x04, 0xaf, 0xe7, 0xe0, 0xfb, 0xc1, 0x2f, 0xb9, ++ 0xf7, 0x16, 0x51, 0x27, 0x45, 0x7d, 0x05, 0xa9, 0xaf, 0x0b, 0xb1, 0x00, ++ 0xea, 0x07, 0xcc, 0xa7, 0x8a, 0xb1, 0x40, 0x74, 0xf7, 0xda, 0xa0, 0x86, ++ 0xba, 0xeb, 0x2e, 0xc7, 0x2b, 0x7b, 0xab, 0xd0, 0x3e, 0xe2, 0xa3, 0x7f, ++ 0x49, 0x7c, 0x28, 0xc6, 0xa4, 0xd6, 0x11, 0x77, 0x3f, 0x8a, 0xf8, 0xda, ++ 0x10, 0xf8, 0xc3, 0x63, 0xb0, 0x8c, 0x47, 0xce, 0xe5, 0xc9, 0xb9, 0x39, ++ 0x19, 0x97, 0x3e, 0xc3, 0x16, 0x1c, 0xe7, 0x19, 0xce, 0x77, 0xaa, 0x21, ++ 0x92, 0x95, 0xf5, 0xa6, 0x2c, 0x39, 0x99, 0x27, 0x2d, 0x3a, 0x13, 0xbe, ++ 0xad, 0xde, 0xe8, 0x81, 0xda, 0xe6, 0xc1, 0x66, 0x9c, 0x32, 0xf4, 0xfe, ++ 0x7b, 0xf1, 0x27, 0xe8, 0x0d, 0x39, 0xd8, 0x6f, 0xac, 0x64, 0x3e, 0x51, ++ 0x8d, 0xf5, 0x6d, 0x34, 0xcf, 0x3b, 0x3a, 0x88, 0x09, 0x56, 0x8f, 0x07, ++ 0xb2, 0x9e, 0xbb, 0xf1, 0x2e, 0x3b, 0x1a, 0xe9, 0x7e, 0x50, 0x01, 0x56, ++ 0x0c, 0xf8, 0xa1, 0x29, 0x2e, 0xdf, 0x89, 0x0d, 0xa9, 0xb2, 0xb6, 0xfc, ++ 0x2f, 0x15, 0xc5, 0xb3, 0x10, 0x2a, 0xb4, 0x46, 0x69, 0x67, 0x25, 0xac, ++ 0xc9, 0x0e, 0x17, 0x4f, 0x6a, 0x16, 0x2a, 0xb8, 0x75, 0x61, 0xc4, 0x4a, ++ 0x29, 0x8e, 0xb3, 0x2a, 0xee, 0x75, 0x9f, 0xef, 0x98, 0x6c, 0x4d, 0xdd, ++ 0xa9, 0xfe, 0x8b, 0x63, 0xb9, 0xeb, 0xd9, 0x91, 0x60, 0x52, 0x65, 0x9f, ++ 0x3f, 0xf2, 0xac, 0xa2, 0x8c, 0x93, 0x5c, 0x9c, 0xbc, 0xfb, 0xc9, 0xd2, ++ 0xfa, 0xaf, 0xcf, 0x5c, 0xff, 0x17, 0xfb, 0x75, 0xc9, 0xf7, 0xbe, 0xe4, ++ 0x9e, 0xfb, 0xc8, 0x66, 0x64, 0xfd, 0xf0, 0xe1, 0x00, 0xaa, 0x57, 0xa2, ++ 0x77, 0xf2, 0x3a, 0x4c, 0xb4, 0xfd, 0xab, 0x93, 0x2b, 0xf6, 0x5d, 0xcc, ++ 0xd0, 0x3f, 0xcf, 0xcc, 0xdd, 0x75, 0x7d, 0x4b, 0x84, 0x1c, 0x5c, 0xce, ++ 0x7a, 0x92, 0x0b, 0x2b, 0x45, 0x1e, 0x3e, 0x5f, 0xbf, 0x09, 0xcf, 0x5e, ++ 0x24, 0x53, 0xd6, 0x12, 0xca, 0x32, 0x77, 0x51, 0x9e, 0xc8, 0x65, 0x3c, ++ 0xd0, 0xff, 0xcd, 0x19, 0x09, 0xcd, 0x2c, 0x17, 0xab, 0x2a, 0xc6, 0x2a, ++ 0x29, 0x57, 0x6e, 0xb7, 0x82, 0xf5, 0xde, 0x77, 0x46, 0x2f, 0x2a, 0xf7, ++ 0xd3, 0x52, 0xb9, 0x67, 0x02, 0x72, 0x66, 0x24, 0x9b, 0x11, 0xce, 0x7a, ++ 0xca, 0x19, 0xbb, 0xa8, 0x4c, 0x4b, 0xf5, 0xc5, 0x65, 0x9a, 0x89, 0xd1, ++ 0xff, 0xaf, 0x33, 0x7e, 0x51, 0x99, 0xe4, 0x25, 0x65, 0x16, 0x10, 0x13, ++ 0xbf, 0xef, 0xec, 0xbb, 0xa8, 0x4c, 0xed, 0x25, 0x65, 0x16, 0xd3, 0x1e, ++ 0x9f, 0x71, 0x0e, 0x5c, 0x54, 0x66, 0xcc, 0x7f, 0x71, 0x19, 0xd9, 0xe3, ++ 0x58, 0xff, 0x17, 0x5b, 0xf4, 0x75, 0x25, 0x9f, 0xbb, 0x70, 0xbf, 0x58, ++ 0xfe, 0xf1, 0x4b, 0xfa, 0x1f, 0xb1, 0x64, 0xbe, 0x7d, 0xed, 0xe5, 0xf9, ++ 0x7e, 0xb8, 0x74, 0xff, 0x7b, 0x35, 0x17, 0x97, 0xbb, 0x22, 0x70, 0x69, ++ 0x3b, 0x45, 0x79, 0x47, 0x2f, 0x69, 0xff, 0xe6, 0xca, 0x8b, 0xbf, 0xbf, ++ 0x5d, 0x51, 0xfc, 0x5e, 0xd6, 0xe9, 0xa1, 0x4b, 0x9e, 0xff, 0x7d, 0xc5, ++ 0xc5, 0xdf, 0x37, 0x54, 0x7e, 0x78, 0x3b, 0xb5, 0x97, 0xb4, 0xa3, 0xf4, ++ 0xca, 0xbb, 0x38, 0x1e, 0x53, 0xad, 0xed, 0xed, 0x58, 0x7f, 0x43, 0x2a, ++ 0xbf, 0x89, 0xf6, 0x29, 0xb6, 0xf5, 0xe0, 0x0d, 0x6b, 0xf3, 0x6f, 0xcd, ++ 0xe0, 0xb1, 0xcb, 0xc2, 0x41, 0x7c, 0x1c, 0x6b, 0xdd, 0xbd, 0x34, 0x95, ++ 0x38, 0x69, 0xb9, 0xb6, 0x40, 0x8e, 0xe9, 0x57, 0xcc, 0x14, 0x0c, 0xf7, ++ 0xbc, 0xe5, 0x3a, 0x34, 0xe7, 0xdd, 0x3d, 0xbb, 0x58, 0x0a, 0xcf, 0xaa, ++ 0x5d, 0xba, 0x55, 0x3a, 0x47, 0x67, 0x5d, 0x1f, 0x44, 0x72, 0x66, 0x7e, ++ 0xaa, 0x8d, 0x23, 0x12, 0xde, 0x86, 0x75, 0xee, 0x59, 0x6b, 0xc5, 0xec, ++ 0x29, 0x9d, 0xd7, 0x5c, 0x03, 0x3d, 0x5f, 0xe6, 0x4d, 0xb2, 0x9e, 0x2b, ++ 0xe7, 0x19, 0x1c, 0xfa, 0xa0, 0xc4, 0xf9, 0x83, 0x8a, 0x3a, 0xe0, 0xae, ++ 0x99, 0xae, 0xf6, 0x20, 0x9a, 0xe8, 0x54, 0x90, 0xaa, 0x32, 0xa3, 0xda, ++ 0xdb, 0x25, 0x4c, 0xf3, 0x4d, 0x6c, 0x51, 0x2a, 0x26, 0xfa, 0x15, 0xef, ++ 0x44, 0x11, 0xd3, 0x3c, 0x13, 0xb2, 0xb6, 0xd0, 0xc0, 0x32, 0x41, 0xb4, ++ 0x2c, 0xf1, 0xe2, 0x3b, 0x76, 0xad, 0xfb, 0x1e, 0xc7, 0xd6, 0x25, 0x15, ++ 0x78, 0x20, 0xae, 0xa0, 0xeb, 0xaa, 0xc3, 0x78, 0x2b, 0x2f, 0xeb, 0x6c, ++ 0x56, 0x7c, 0x94, 0x6d, 0x1e, 0xb2, 0x65, 0xbd, 0x74, 0x4b, 0x7c, 0xc4, ++ 0x6d, 0xff, 0xf3, 0xe8, 0x73, 0xf7, 0xad, 0xba, 0x9d, 0xed, 0x99, 0x1e, ++ 0x67, 0x1b, 0x73, 0x8d, 0x82, 0xdd, 0x90, 0xaa, 0x63, 0xfd, 0xb7, 0x96, ++ 0xac, 0xc7, 0x69, 0x96, 0x99, 0xb0, 0x1f, 0xc4, 0xfb, 0xf9, 0x20, 0xf2, ++ 0xf6, 0x4a, 0x7c, 0x37, 0x1f, 0x60, 0xce, 0xd7, 0x85, 0xef, 0xe4, 0x57, ++ 0xe3, 0xc5, 0x61, 0xf7, 0x7d, 0x29, 0x2c, 0xb3, 0x15, 0xac, 0x88, 0xae, ++ 0xc6, 0xb1, 0xd1, 0xd5, 0x38, 0x3c, 0x2c, 0xef, 0x0e, 0xcc, 0x25, 0x8f, ++ 0x2c, 0xda, 0x9b, 0x4a, 0x8c, 0x59, 0x66, 0xaf, 0xc2, 0xa1, 0xd1, 0x30, ++ 0x73, 0x29, 0x03, 0x27, 0xf3, 0x21, 0x8c, 0xd8, 0x6d, 0x38, 0x91, 0x0f, ++ 0xe3, 0xeb, 0x76, 0x02, 0x67, 0xf9, 0xfd, 0xa0, 0x2d, 0x9c, 0xa5, 0x03, ++ 0xd3, 0xf9, 0x6f, 0x32, 0xcf, 0x99, 0x87, 0x23, 0xdd, 0xcf, 0x30, 0x1c, ++ 0x1d, 0xe4, 0xd5, 0x85, 0x13, 0xa3, 0x5d, 0x38, 0x35, 0x7c, 0x2b, 0x4e, ++ 0x8d, 0xfe, 0x18, 0x6f, 0x0d, 0x4b, 0x7f, 0xe5, 0xfc, 0xb7, 0xc8, 0xd5, ++ 0x29, 0x77, 0x35, 0xa6, 0x46, 0xff, 0x18, 0xd9, 0xef, 0x3a, 0x47, 0x56, ++ 0x8b, 0xdc, 0x67, 0x7e, 0x87, 0x6c, 0xd1, 0xa5, 0x60, 0xbf, 0x1f, 0xc7, ++ 0x6c, 0x3f, 0x8e, 0xda, 0x53, 0x57, 0x56, 0x61, 0xea, 0x7a, 0x22, 0x1d, ++ 0xb6, 0xe7, 0x2b, 0xf1, 0x5c, 0x56, 0xd6, 0xd8, 0x3e, 0x86, 0x64, 0x70, ++ 0x23, 0xb6, 0x4e, 0x56, 0xe2, 0x3b, 0x59, 0x3f, 0x75, 0x7c, 0x3d, 0x92, ++ 0xf5, 0xab, 0xa9, 0xbf, 0x00, 0x5e, 0xb2, 0x43, 0x78, 0xd9, 0x6e, 0x4d, ++ 0x15, 0x94, 0x76, 0x58, 0x2e, 0xfe, 0x07, 0xa8, 0xef, 0x0d, 0x6e, 0x9f, ++ 0xbe, 0x63, 0x77, 0x3b, 0x5b, 0xa9, 0xe3, 0xfe, 0xcc, 0xe7, 0xdd, 0xb3, ++ 0xdb, 0x2f, 0xda, 0xd3, 0x8e, 0xbc, 0x93, 0xf1, 0x14, 0x75, 0x7a, 0xcc, ++ 0x4e, 0x91, 0xdb, 0x35, 0x71, 0x8e, 0xa6, 0x30, 0x4a, 0xbb, 0x3c, 0x99, ++ 0xd5, 0x8f, 0xae, 0xc5, 0x26, 0x9c, 0xcd, 0x55, 0xe2, 0x35, 0xb6, 0x51, ++ 0xb7, 0xd8, 0x8b, 0xe3, 0xae, 0xbc, 0x4d, 0x78, 0x3f, 0xab, 0x30, 0xde, ++ 0x6e, 0xc2, 0x7b, 0x7c, 0xf6, 0x0a, 0x3f, 0x9f, 0x8e, 0xb3, 0x87, 0xa5, ++ 0x67, 0xa7, 0xc8, 0xcf, 0x65, 0xcd, 0xa8, 0xb7, 0x63, 0x13, 0x4e, 0xe4, ++ 0xde, 0x23, 0xa7, 0x75, 0xf0, 0x45, 0x63, 0x36, 0x12, 0xb3, 0xc9, 0x9b, ++ 0xf4, 0x4a, 0x1c, 0xe3, 0xf3, 0x85, 0xc4, 0xdf, 0xe2, 0xfa, 0xd9, 0x26, ++ 0xbc, 0xcb, 0xf1, 0x3c, 0x40, 0x59, 0xef, 0xe4, 0xfe, 0x96, 0x72, 0x97, ++ 0x22, 0x1f, 0xff, 0x5b, 0xca, 0xfd, 0x31, 0xc6, 0x4b, 0xfa, 0x38, 0x61, ++ 0xc8, 0xb8, 0xbe, 0x31, 0x0b, 0xd5, 0x21, 0x8e, 0xe3, 0x9b, 0xfc, 0xbf, ++ 0x01, 0xc7, 0xf3, 0xff, 0x9b, 0xff, 0xbf, 0x8b, 0x03, 0x79, 0x59, 0xaf, ++ 0x9e, 0x19, 0x4b, 0xc5, 0x7f, 0xca, 0x1c, 0x64, 0x0e, 0x32, 0x83, 0xb5, ++ 0xa9, 0xd9, 0xb4, 0xa3, 0xbf, 0xbe, 0xb6, 0x0e, 0xef, 0xc6, 0x2d, 0xec, ++ 0xd8, 0xe7, 0x45, 0x86, 0xb8, 0xbb, 0x63, 0xa0, 0x01, 0x4f, 0xec, 0x0c, ++ 0xe2, 0xf1, 0x9d, 0x97, 0x61, 0xcb, 0xce, 0x2b, 0xb0, 0x67, 0x67, 0x13, ++ 0xd2, 0x3b, 0x1d, 0xe7, 0xfd, 0xc5, 0x8e, 0xb3, 0x88, 0xd7, 0x23, 0xf4, ++ 0x05, 0x3f, 0xff, 0xbf, 0x10, 0x17, 0x3f, 0xd1, 0x71, 0x95, 0xeb, 0x2f, ++ 0x9d, 0xb8, 0xd2, 0xfd, 0x9f, 0xc4, 0xa2, 0xfc, 0xc6, 0xf8, 0xfa, 0xc2, ++ 0xa6, 0xf8, 0x7d, 0x85, 0x39, 0xd8, 0x3a, 0xd8, 0x88, 0xc1, 0x9d, 0x0d, ++ 0xa9, 0x06, 0xb6, 0xb3, 0xea, 0x5a, 0xe1, 0x76, 0x8e, 0x63, 0xb4, 0xf7, ++ 0xc7, 0xd7, 0x16, 0x9e, 0x41, 0x77, 0x21, 0x84, 0xbe, 0xc1, 0x30, 0xdb, ++ 0x92, 0xbd, 0x5c, 0xef, 0xd1, 0x7b, 0xe1, 0x38, 0xd3, 0x8b, 0x0f, 0xe2, ++ 0xae, 0xc2, 0x37, 0xc9, 0x1b, 0x43, 0x48, 0x0f, 0xae, 0x47, 0x66, 0xb2, ++ 0x22, 0xe5, 0x37, 0x1d, 0xbc, 0x14, 0x9f, 0xc2, 0xed, 0x94, 0xf7, 0xe8, ++ 0x60, 0x2d, 0xfb, 0x54, 0x9d, 0xaa, 0x34, 0x25, 0x86, 0x3f, 0xc8, 0x18, ++ 0x25, 0xfc, 0xe2, 0x28, 0x56, 0x30, 0xbf, 0xaa, 0x5f, 0xa2, 0xcf, 0x42, ++ 0x6d, 0xd0, 0x7b, 0xa6, 0x43, 0xec, 0x2f, 0x45, 0xfb, 0x93, 0x7d, 0xf5, ++ 0x75, 0xb8, 0xdb, 0x3d, 0xe7, 0xdd, 0x83, 0xe7, 0x6d, 0xc1, 0x9d, 0x35, ++ 0xd8, 0x6f, 0xaf, 0x63, 0xce, 0x25, 0xf1, 0x7a, 0x25, 0x9a, 0x0b, 0x7f, ++ 0x17, 0xbf, 0xa7, 0xb0, 0x9a, 0x7c, 0xf6, 0x5f, 0x70, 0x53, 0x21, 0xc7, ++ 0x7e, 0x8d, 0xc6, 0xef, 0x2e, 0xec, 0x89, 0xdf, 0x5b, 0xe8, 0xc2, 0x02, ++ 0x37, 0xa7, 0x64, 0xfe, 0x55, 0x90, 0x38, 0x77, 0x9c, 0x5c, 0xf8, 0x14, ++ 0x96, 0x17, 0x5e, 0xc3, 0xcd, 0x05, 0xc1, 0x0d, 0x89, 0x7f, 0x2f, 0x7a, ++ 0x51, 0x2d, 0x71, 0xef, 0x0b, 0xd8, 0xba, 0x3b, 0x85, 0xbe, 0xdd, 0x65, ++ 0x8c, 0x6a, 0x0d, 0xee, 0x13, 0x7c, 0x99, 0xf4, 0x95, 0x62, 0xd4, 0xa7, ++ 0x68, 0x8f, 0x2a, 0x63, 0xa3, 0xac, 0xd3, 0xaf, 0xa3, 0x2f, 0x6f, 0x24, ++ 0x66, 0xca, 0x7a, 0xfc, 0x27, 0x4b, 0xf7, 0x25, 0xd6, 0xcb, 0x5a, 0xbc, ++ 0x86, 0x43, 0x79, 0x77, 0x4f, 0x5b, 0xf3, 0xeb, 0xb7, 0xf3, 0x99, 0xd4, ++ 0xff, 0x02, 0xd2, 0xbb, 0x57, 0x3b, 0x8f, 0x66, 0x8a, 0xfb, 0x66, 0x47, ++ 0xa2, 0x6c, 0x6b, 0x9c, 0xb1, 0x7d, 0x2f, 0xfc, 0xb3, 0x38, 0xb6, 0x89, ++ 0x01, 0x58, 0x1e, 0xbd, 0xdb, 0xd9, 0x92, 0xc1, 0xbd, 0xb3, 0x10, 0xc6, ++ 0xca, 0x89, 0x0a, 0x24, 0xf7, 0x57, 0xe3, 0xb6, 0x9d, 0x3d, 0xb4, 0x65, ++ 0x8b, 0xf6, 0xab, 0x1b, 0x77, 0x2b, 0xd5, 0xb8, 0x99, 0xf7, 0x3e, 0x3d, ++ 0x28, 0x6b, 0x58, 0xd1, 0xa3, 0x27, 0x3c, 0xd5, 0xb8, 0x6b, 0xaf, 0x1f, ++ 0xb9, 0xdc, 0x4a, 0x24, 0xf7, 0x1e, 0x81, 0x95, 0xa3, 0x4d, 0xee, 0x22, ++ 0xce, 0x30, 0xcd, 0x51, 0xcd, 0x1f, 0x63, 0xcf, 0xa8, 0x8a, 0xba, 0x5d, ++ 0xb2, 0xfe, 0xa8, 0xe8, 0xa7, 0xa3, 0x05, 0xa4, 0x47, 0xbd, 0x98, 0x95, ++ 0xee, 0xc4, 0x04, 0xb1, 0x26, 0x90, 0x4e, 0x22, 0x9f, 0xef, 0x46, 0x8e, ++ 0x58, 0x92, 0x1b, 0x0d, 0xa0, 0x26, 0x6d, 0x20, 0xa0, 0xc7, 0xb0, 0x83, ++ 0xfe, 0x52, 0x91, 0xd6, 0xb1, 0x2d, 0x7f, 0x23, 0xac, 0xd1, 0x4f, 0x60, ++ 0xfb, 0x68, 0x37, 0x2f, 0x13, 0x7d, 0xa3, 0x9f, 0xc7, 0xb2, 0x89, 0xa3, ++ 0xe8, 0xcf, 0xa7, 0x68, 0x8f, 0xef, 0x61, 0x7b, 0xee, 0x30, 0x9e, 0xc8, ++ 0x6e, 0xc6, 0xd9, 0xc5, 0x87, 0xf1, 0x38, 0x3f, 0x67, 0xb3, 0xfa, 0xc6, ++ 0xb0, 0x7a, 0x18, 0x99, 0xdc, 0x26, 0x7c, 0x62, 0x50, 0xc1, 0x4b, 0xb4, ++ 0xf5, 0xdb, 0xf7, 0xd2, 0x16, 0x1f, 0xdb, 0x80, 0xae, 0x89, 0xef, 0xc2, ++ 0xce, 0x3f, 0x8f, 0x1d, 0xb9, 0x07, 0xd1, 0x9f, 0x59, 0xcf, 0xfc, 0xff, ++ 0x19, 0xca, 0x39, 0x48, 0x3f, 0xdf, 0xc8, 0x31, 0x3e, 0xcc, 0xeb, 0xc2, ++ 0x1a, 0xe3, 0x85, 0x35, 0x39, 0xfa, 0x7d, 0x46, 0x72, 0xcf, 0x75, 0xc4, ++ 0x89, 0x27, 0x6b, 0x65, 0x5d, 0xb2, 0x4a, 0x9f, 0xb9, 0x56, 0x2f, 0xb6, ++ 0x1f, 0x76, 0x73, 0xed, 0xaa, 0xb4, 0xe4, 0x75, 0x53, 0x91, 0x2a, 0x72, ++ 0x0c, 0x7f, 0x5a, 0x74, 0xd8, 0xe3, 0xf4, 0x66, 0x04, 0x4b, 0x64, 0x3e, ++ 0x34, 0xbc, 0x90, 0xff, 0x31, 0xb6, 0x0e, 0xcf, 0xc6, 0xf2, 0x6c, 0x1b, ++ 0x39, 0xa5, 0xe3, 0x7c, 0x85, 0xbe, 0x66, 0x93, 0xeb, 0xec, 0x18, 0x4c, ++ 0x12, 0x53, 0x66, 0x23, 0x39, 0xa7, 0xc8, 0x4f, 0xc2, 0x69, 0x69, 0xcb, ++ 0x57, 0xda, 0xab, 0x9b, 0xba, 0x32, 0xcc, 0x7b, 0x75, 0x69, 0x99, 0xb7, ++ 0x88, 0xa1, 0xb9, 0xfb, 0x69, 0x8e, 0xf3, 0x52, 0xb4, 0xcc, 0x95, 0xa6, ++ 0xae, 0xac, 0xc3, 0x6c, 0x59, 0x77, 0x4d, 0xc8, 0x39, 0xdf, 0x6f, 0xb5, ++ 0x2c, 0xa7, 0xaf, 0x7e, 0x01, 0x03, 0xe3, 0xe5, 0x77, 0x23, 0xff, 0xb3, ++ 0xe4, 0xdd, 0xf5, 0x9f, 0x2c, 0xaf, 0xbc, 0x07, 0x2a, 0xe7, 0x8c, 0xcb, ++ 0xef, 0x50, 0x8a, 0x2e, 0xaf, 0x90, 0xfd, 0x03, 0xab, 0xb8, 0x4f, 0x0a, ++ 0x1c, 0xb1, 0x2b, 0x18, 0x87, 0xd5, 0xa5, 0x64, 0x63, 0x21, 0x1f, 0x2a, ++ 0x19, 0x2f, 0x1b, 0xd1, 0x47, 0xbe, 0x7a, 0x93, 0x51, 0x81, 0x03, 0x6d, ++ 0x49, 0x39, 0xcf, 0xd7, 0xe3, 0x73, 0x79, 0xea, 0xa6, 0x3f, 0xff, 0x6d, ++ 0x9e, 0xba, 0x09, 0xe9, 0x8c, 0x9c, 0x63, 0xeb, 0xc6, 0x4b, 0xf5, 0xf2, ++ 0x5e, 0xe7, 0x26, 0xf7, 0x9c, 0x70, 0xd5, 0x42, 0x62, 0x46, 0x5c, 0xc3, ++ 0x51, 0xbd, 0x55, 0x6b, 0x50, 0x23, 0x06, 0x94, 0xd7, 0x1d, 0x2b, 0x94, ++ 0x44, 0xff, 0xa4, 0x9c, 0xd5, 0xfb, 0xa8, 0x3d, 0x84, 0xb5, 0xd8, 0xfe, ++ 0x58, 0x07, 0x8e, 0xaf, 0x96, 0xb5, 0xbc, 0x9f, 0x95, 0xde, 0xdb, 0x93, ++ 0x3e, 0x46, 0xea, 0xe4, 0x0c, 0xaa, 0xc8, 0xde, 0x9e, 0x51, 0x19, 0x7b, ++ 0xe2, 0x78, 0x3d, 0xe8, 0x8e, 0x37, 0x56, 0x3e, 0x97, 0x59, 0xa9, 0x2f, ++ 0x2f, 0x95, 0x5f, 0x50, 0x27, 0xbc, 0x64, 0x5b, 0x66, 0x13, 0xb9, 0xb6, ++ 0xf4, 0xe7, 0xd7, 0xce, 0xda, 0x50, 0x03, 0xcb, 0x8e, 0x95, 0x9e, 0x8b, ++ 0xad, 0x45, 0x8c, 0x24, 0xe4, 0x9e, 0xd4, 0x11, 0x9d, 0xcd, 0xac, 0xe3, ++ 0x41, 0xbd, 0x7e, 0x25, 0x1e, 0xa2, 0x8f, 0xcf, 0xd7, 0x5f, 0x76, 0x36, ++ 0xcb, 0x39, 0xcd, 0x85, 0xc1, 0x19, 0x6d, 0x2d, 0x75, 0xfb, 0x52, 0xc9, ++ 0xbe, 0x0c, 0x66, 0xe4, 0xbd, 0x81, 0xb3, 0xce, 0xc2, 0x46, 0x79, 0x7e, ++ 0x5b, 0x6d, 0x51, 0x7e, 0xb3, 0x7b, 0x0e, 0x7b, 0x4f, 0xa6, 0xdc, 0x6f, ++ 0x39, 0xe3, 0x1e, 0x2a, 0xb7, 0x15, 0xbb, 0x30, 0x1e, 0xe9, 0xdb, 0xd7, ++ 0x6a, 0x2f, 0xee, 0xf3, 0x9d, 0xb3, 0xca, 0xef, 0x17, 0xcc, 0x73, 0xeb, ++ 0x94, 0xdb, 0x94, 0x3e, 0x6e, 0xc2, 0xe3, 0x93, 0x97, 0x8e, 0xf1, 0xee, ++ 0x19, 0x63, 0x92, 0x3a, 0x32, 0xae, 0x60, 0xc9, 0x0e, 0x36, 0xb2, 0x8c, ++ 0xd4, 0x91, 0x75, 0x82, 0xa0, 0x9b, 0x3f, 0xd4, 0xed, 0x16, 0x79, 0x22, ++ 0xc3, 0x71, 0xde, 0x70, 0x63, 0xf2, 0x02, 0xb7, 0xcc, 0xe0, 0xe4, 0x6a, ++ 0xfa, 0x91, 0xb3, 0x99, 0xf8, 0xec, 0xbc, 0xd1, 0x11, 0xc6, 0x56, 0x5b, ++ 0x74, 0xad, 0x87, 0xc7, 0x88, 0x4d, 0x7d, 0x2e, 0x9f, 0xf1, 0xa1, 0x37, ++ 0x57, 0x3e, 0xeb, 0x52, 0x29, 0x7b, 0x21, 0x61, 0xd1, 0x79, 0xaf, 0x41, ++ 0x1e, 0x17, 0x5c, 0xa6, 0x79, 0xc9, 0xc5, 0xee, 0xc1, 0x7f, 0xc8, 0xfc, ++ 0xc6, 0x7c, 0xa5, 0x75, 0x93, 0x14, 0xed, 0xa8, 0x18, 0x0f, 0x41, 0xfe, ++ 0x40, 0x1e, 0x56, 0x3a, 0x43, 0xdf, 0x9b, 0xff, 0x0f, 0x67, 0xca, 0x3d, ++ 0x43, 0x7f, 0xe1, 0x2c, 0x4a, 0x2e, 0xe8, 0x38, 0xfb, 0xf8, 0xec, 0xc2, ++ 0x79, 0x7a, 0x72, 0x06, 0x5d, 0xce, 0xdd, 0xff, 0x3b, 0xe7, 0x6e, 0x66, ++ 0xd9, 0xa9, 0xfa, 0xe2, 0xfb, 0x25, 0x49, 0x75, 0x99, 0x5e, 0xc6, 0x6d, ++ 0xd9, 0x27, 0x12, 0xdc, 0x3e, 0x58, 0x57, 0x5c, 0x3f, 0x8e, 0x74, 0x75, ++ 0x43, 0xf6, 0xe4, 0xcb, 0x38, 0xa3, 0x1b, 0x8b, 0x94, 0xcd, 0x68, 0x89, ++ 0x57, 0xcb, 0xf9, 0xba, 0x88, 0xd7, 0x8c, 0x04, 0xdf, 0x42, 0x34, 0x76, ++ 0xd8, 0x3d, 0x43, 0x22, 0xd8, 0xa3, 0xe3, 0x9e, 0xbc, 0x4e, 0x9b, 0x95, ++ 0xf7, 0xd2, 0xe5, 0x73, 0xf1, 0xdd, 0xc7, 0x64, 0x5e, 0xb0, 0xba, 0x87, ++ 0x58, 0x6d, 0xfd, 0xa5, 0xcf, 0x95, 0x17, 0xe9, 0x19, 0x55, 0x22, 0x5d, ++ 0x0f, 0x2a, 0x65, 0x79, 0x81, 0x0f, 0x91, 0x17, 0x63, 0x7d, 0xad, 0xf4, ++ 0x2e, 0xb8, 0x4e, 0x19, 0x97, 0x9e, 0x0d, 0x9a, 0x93, 0x92, 0x3c, 0xfa, ++ 0x40, 0x89, 0x73, 0x1e, 0xfe, 0xad, 0x3c, 0xfa, 0x43, 0xdb, 0x4c, 0xb2, ++ 0xcd, 0xae, 0x6a, 0x25, 0x19, 0x97, 0xf7, 0x80, 0x2a, 0xe3, 0xd1, 0xd8, ++ 0x0b, 0x74, 0x72, 0xaf, 0x19, 0x0d, 0x8f, 0xba, 0x67, 0x5d, 0x0c, 0xff, ++ 0xf2, 0x7c, 0xd1, 0x7f, 0xac, 0xc9, 0xdf, 0xad, 0x93, 0x1a, 0x5d, 0xef, ++ 0x6e, 0x55, 0x92, 0xd7, 0x57, 0x53, 0x4e, 0x2c, 0x0e, 0xad, 0xc2, 0x2c, ++ 0xeb, 0x28, 0x1a, 0x7b, 0x8b, 0xf3, 0x79, 0xa8, 0x23, 0x1a, 0x1e, 0x71, ++ 0x73, 0x74, 0xd1, 0x8b, 0xe1, 0x2f, 0xce, 0xbd, 0x2e, 0x7c, 0xde, 0xf2, ++ 0x31, 0x36, 0x8f, 0xdb, 0x7e, 0x8e, 0xa5, 0x35, 0xb8, 0x1d, 0xf5, 0xb4, ++ 0x71, 0x24, 0xfb, 0xda, 0x18, 0x1f, 0x6c, 0x24, 0x3d, 0x57, 0xd5, 0x21, ++ 0x45, 0x82, 0xee, 0xd1, 0x53, 0xe4, 0x5c, 0xad, 0xb1, 0x47, 0x68, 0xbf, ++ 0xb9, 0x50, 0x24, 0x6c, 0x21, 0x85, 0xe7, 0xec, 0x65, 0x7f, 0xee, 0x81, ++ 0x65, 0xd4, 0x70, 0xa2, 0xab, 0xcd, 0xa9, 0x3f, 0xbf, 0x35, 0x1a, 0xd1, ++ 0x5e, 0x2c, 0x9d, 0xd5, 0xe9, 0xb5, 0x7f, 0xe1, 0xee, 0x51, 0x79, 0xf4, ++ 0xdf, 0x55, 0x46, 0xda, 0xf6, 0x63, 0x2c, 0x9b, 0xc5, 0x96, 0xc7, 0xd8, ++ 0x47, 0xdd, 0xc1, 0x32, 0x63, 0x33, 0x96, 0x1b, 0x01, 0xac, 0x0b, 0xb6, ++ 0x24, 0xe4, 0x2c, 0xd2, 0x48, 0xae, 0xb8, 0x36, 0x52, 0x5c, 0x0b, 0xef, ++ 0xc7, 0xa3, 0x19, 0x37, 0x3e, 0x07, 0xfd, 0x66, 0x52, 0x79, 0x34, 0xdf, ++ 0xa9, 0x3c, 0x52, 0x5a, 0x8f, 0xeb, 0xcf, 0xdf, 0x10, 0x44, 0xb5, 0x85, ++ 0x13, 0x86, 0xbc, 0x47, 0x29, 0x72, 0x2d, 0x8c, 0x76, 0xfc, 0x21, 0xef, ++ 0x53, 0x8a, 0x4e, 0x37, 0xa2, 0x6f, 0xf8, 0x61, 0xf4, 0x0e, 0xbf, 0xe4, ++ 0x9e, 0x65, 0xf5, 0xe9, 0x7e, 0xeb, 0x0a, 0x33, 0x72, 0xd0, 0xc2, 0xbc, ++ 0x7a, 0x59, 0x13, 0x6e, 0x34, 0x8f, 0xe2, 0xd1, 0xa0, 0xbc, 0x27, 0xd8, ++ 0x4f, 0x9e, 0x22, 0xef, 0x9c, 0xad, 0xc1, 0x67, 0x06, 0x64, 0x0e, 0x6b, ++ 0xad, 0x4a, 0x33, 0x92, 0x5c, 0xe7, 0xce, 0x61, 0x1b, 0x8e, 0x15, 0x1e, ++ 0xc6, 0x1b, 0xbb, 0x36, 0x43, 0x8d, 0x47, 0xc2, 0xb7, 0xc0, 0xd9, 0x7c, ++ 0xc4, 0x48, 0x5a, 0x3e, 0x44, 0x0e, 0x78, 0x54, 0xe0, 0xd9, 0x5d, 0x92, ++ 0x4f, 0xf7, 0xe0, 0x7a, 0x72, 0x80, 0x3a, 0xdd, 0x59, 0xfa, 0xab, 0xc5, ++ 0x91, 0x7e, 0xdd, 0x63, 0xfd, 0xd3, 0x1c, 0x44, 0xb2, 0x09, 0x55, 0xef, ++ 0xf9, 0xa4, 0x0a, 0x25, 0x60, 0xca, 0x6f, 0x00, 0x6c, 0xc6, 0x27, 0xda, ++ 0x03, 0xd6, 0x2c, 0x33, 0x92, 0x7d, 0x49, 0x89, 0xc4, 0x2c, 0xf5, 0x1b, ++ 0x9c, 0xe7, 0x18, 0x5e, 0x24, 0xc7, 0xe9, 0x62, 0x6c, 0x5f, 0x21, 0x31, ++ 0xdd, 0xc5, 0xbe, 0xe6, 0x44, 0x95, 0x12, 0xc4, 0x2d, 0x05, 0xe0, 0x50, ++ 0x6e, 0x0d, 0x4e, 0xee, 0x32, 0xd0, 0xc9, 0x67, 0x83, 0x19, 0x02, 0x16, ++ 0x31, 0x60, 0x83, 0x61, 0xb5, 0xaa, 0xe4, 0x16, 0x3e, 0x15, 0xcb, 0xe6, ++ 0x9b, 0xd1, 0xa9, 0xa5, 0x1e, 0x2f, 0x12, 0x05, 0x2f, 0xee, 0x60, 0x99, ++ 0xed, 0x8c, 0x0b, 0x9f, 0x4c, 0xfb, 0xc9, 0x6f, 0x9b, 0xf0, 0x33, 0xf2, ++ 0xec, 0x9f, 0x92, 0x4f, 0x1f, 0x27, 0x5f, 0x38, 0x9e, 0xaf, 0x46, 0xf7, ++ 0x90, 0x4f, 0xce, 0x1f, 0x4d, 0xf9, 0x38, 0x17, 0xb5, 0xed, 0x21, 0x9c, ++ 0x1e, 0xf5, 0xe3, 0xf6, 0x5d, 0x91, 0x3d, 0xc7, 0xd5, 0x46, 0xbc, 0x3f, ++ 0x5a, 0x8d, 0x95, 0x43, 0x7e, 0xf6, 0xcd, 0xc1, 0x0e, 0xe2, 0xff, 0xbb, ++ 0x7c, 0xd6, 0xb9, 0x0b, 0x4a, 0x7e, 0xc9, 0x02, 0xe6, 0x04, 0x3a, 0xeb, ++ 0xd7, 0xe0, 0xd6, 0x21, 0xe1, 0x81, 0x2a, 0xde, 0x1e, 0x55, 0xf0, 0x56, ++ 0xce, 0xc0, 0x32, 0xb6, 0xd7, 0x97, 0x79, 0xd6, 0xf1, 0xd3, 0xcf, 0xd7, ++ 0xe6, 0x0d, 0xdc, 0x9b, 0xd3, 0x19, 0x53, 0x7e, 0xe2, 0x78, 0xf4, 0x76, ++ 0xfc, 0x64, 0xa7, 0x7e, 0xf4, 0x75, 0x4f, 0x74, 0x6a, 0x89, 0xa7, 0x1d, ++ 0xaf, 0xed, 0x6f, 0xc7, 0xf7, 0x06, 0x97, 0xe2, 0x9a, 0xf6, 0x24, 0xce, ++ 0x2c, 0x69, 0xc7, 0xab, 0x7b, 0x75, 0x3c, 0x92, 0xe9, 0x80, 0x36, 0x31, ++ 0x45, 0xfe, 0x9b, 0x40, 0xeb, 0x84, 0x09, 0x7d, 0xd0, 0xd9, 0x5c, 0x63, ++ 0x6e, 0xc6, 0xa3, 0x86, 0x89, 0x45, 0x7b, 0x45, 0x0f, 0x8e, 0xb3, 0x6e, ++ 0x89, 0x89, 0x17, 0xb2, 0x3a, 0xfd, 0xd4, 0xa4, 0x1e, 0x74, 0x3c, 0x9e, ++ 0x31, 0x11, 0x7d, 0x4c, 0x9f, 0xde, 0xc7, 0xef, 0x4b, 0xf7, 0x75, 0xa0, ++ 0x87, 0xed, 0xdb, 0xc4, 0xeb, 0x3d, 0x13, 0x6d, 0x1c, 0xb3, 0xc1, 0xf1, ++ 0x37, 0x5b, 0x3f, 0x53, 0x3a, 0x91, 0x9d, 0xe8, 0x22, 0x9f, 0xdd, 0x4c, ++ 0x1e, 0xdb, 0xe5, 0xee, 0xb9, 0x6f, 0xcd, 0x18, 0xb8, 0x35, 0xdd, 0x85, ++ 0x27, 0x6d, 0x39, 0x3b, 0xaf, 0x27, 0xae, 0x55, 0xe4, 0x1d, 0xdd, 0x2e, ++ 0x8c, 0x51, 0x27, 0xcb, 0x86, 0x56, 0xba, 0xe7, 0x9d, 0x96, 0xef, 0xd2, ++ 0xf1, 0x44, 0xe6, 0x13, 0x38, 0x39, 0x6e, 0xa0, 0x3b, 0x2d, 0xfa, 0x96, ++ 0xf3, 0x9b, 0x29, 0x1c, 0x61, 0x6c, 0xf9, 0xd9, 0x50, 0xf2, 0x9f, 0x38, ++ 0xcd, 0xc7, 0x54, 0xc8, 0x7a, 0x89, 0x8a, 0xab, 0xdb, 0xe5, 0x0c, 0xae, ++ 0x87, 0xa8, 0x16, 0xb1, 0xea, 0x54, 0x4b, 0xe3, 0x7d, 0xcb, 0xab, 0x6e, ++ 0xc2, 0x67, 0x87, 0xbc, 0xcc, 0x19, 0x54, 0xe6, 0x3a, 0xd6, 0x06, 0xda, ++ 0x86, 0x55, 0xab, 0x16, 0xe7, 0xcd, 0xdd, 0x63, 0xd0, 0x3d, 0xd8, 0x61, ++ 0x34, 0x77, 0xd7, 0xb0, 0xde, 0x8a, 0x78, 0x24, 0x59, 0xa5, 0x76, 0x30, ++ 0x0f, 0x7d, 0x18, 0xeb, 0x76, 0x3d, 0x8c, 0xb5, 0xbc, 0x36, 0xec, 0x72, ++ 0x36, 0xdf, 0x6c, 0x28, 0x78, 0x4e, 0x77, 0x36, 0x6f, 0x36, 0x74, 0xce, ++ 0xad, 0xcc, 0xeb, 0xc3, 0xd8, 0x38, 0xf6, 0x30, 0x1e, 0xa2, 0x7d, 0x35, ++ 0xd0, 0x8f, 0x57, 0xa5, 0x9d, 0xcd, 0xd7, 0xb4, 0xc7, 0xf0, 0x73, 0x37, ++ 0xbf, 0x11, 0x7b, 0x3d, 0xe3, 0xe6, 0xdc, 0x39, 0xd5, 0xb5, 0xdd, 0xa0, ++ 0x7c, 0xb6, 0xd4, 0x25, 0xc1, 0x72, 0x6c, 0xf9, 0x05, 0xe5, 0xfe, 0x72, ++ 0x57, 0x1d, 0x1e, 0x6b, 0x90, 0xf8, 0xe1, 0xb7, 0xaa, 0x4c, 0x28, 0xfa, ++ 0x12, 0xe6, 0x71, 0x8f, 0x1d, 0xc1, 0x76, 0xf2, 0xc2, 0x50, 0x5c, 0x72, ++ 0xec, 0x56, 0x63, 0x8b, 0x7a, 0x23, 0xb1, 0x5d, 0xc1, 0xa3, 0x0b, 0xb3, ++ 0x18, 0xa0, 0xaf, 0xee, 0x58, 0x18, 0x49, 0x0d, 0xc0, 0x74, 0x76, 0xcc, ++ 0xe9, 0xff, 0x23, 0xde, 0xa1, 0x2d, 0xef, 0x4b, 0xca, 0x7b, 0xb4, 0x0f, ++ 0x63, 0xf3, 0x2e, 0x99, 0xff, 0x87, 0xf1, 0x45, 0xf6, 0x7f, 0xe3, 0xd0, ++ 0xc3, 0xf8, 0x1c, 0x6d, 0xa7, 0x7e, 0xf1, 0xa1, 0x2f, 0xd6, 0xa3, 0x25, ++ 0x5b, 0x87, 0xa9, 0xfb, 0x1b, 0xe4, 0xbc, 0x2d, 0x31, 0x71, 0x40, 0x79, ++ 0x18, 0xf7, 0x8c, 0xd4, 0xd2, 0x17, 0xdd, 0x31, 0x10, 0x8b, 0xcb, 0xf1, ++ 0x2a, 0x8c, 0x75, 0xf9, 0xa6, 0x12, 0xae, 0x87, 0xb0, 0xd6, 0x3e, 0xe0, ++ 0xfa, 0x7e, 0x85, 0xb9, 0x9a, 0x7e, 0xdf, 0x4d, 0xbf, 0x5f, 0x49, 0xbf, ++ 0xef, 0xa2, 0xdf, 0x77, 0xd2, 0xef, 0x93, 0xf4, 0x7b, 0x93, 0x7e, 0x9f, ++ 0xa0, 0xdf, 0x77, 0xd0, 0xef, 0x0d, 0xd9, 0x3b, 0x54, 0x8e, 0x76, 0x1c, ++ 0x81, 0x6f, 0xd0, 0x4f, 0x1b, 0x2a, 0xbe, 0xd3, 0xb8, 0x9f, 0xf8, 0x73, ++ 0xc2, 0x58, 0x14, 0xbe, 0x89, 0xaa, 0x1a, 0x25, 0x46, 0xe4, 0xc6, 0xff, ++ 0xce, 0x7d, 0xff, 0x2d, 0x47, 0xdc, 0x7f, 0x91, 0xfa, 0x58, 0x11, 0x6f, ++ 0x36, 0x9e, 0x64, 0x0c, 0xfb, 0xa1, 0xde, 0xda, 0x1f, 0x62, 0x99, 0xaf, ++ 0x65, 0x5a, 0xb3, 0xb3, 0xa1, 0x5b, 0xed, 0xea, 0x56, 0x60, 0x55, 0x88, ++ 0x63, 0x96, 0x73, 0xdd, 0xab, 0xf0, 0xc5, 0xe1, 0x6e, 0xfc, 0xcf, 0xe1, ++ 0x20, 0x75, 0xd1, 0x3c, 0x75, 0xa3, 0x07, 0xdf, 0x0c, 0xc3, 0x13, 0x9a, ++ 0x0b, 0x7c, 0xd0, 0x88, 0x45, 0x07, 0xe4, 0x5d, 0xec, 0x5c, 0xa3, 0xa7, ++ 0x6d, 0x3e, 0xc4, 0x46, 0x40, 0xa4, 0xf6, 0x30, 0xd3, 0x5c, 0xe4, 0xbe, ++ 0xaf, 0x99, 0x5c, 0x2d, 0x98, 0x5e, 0x85, 0xad, 0x31, 0x17, 0x67, 0x9f, ++ 0x96, 0xf3, 0xe9, 0x8d, 0xc4, 0xa3, 0x80, 0xd9, 0x85, 0x6d, 0x03, 0xd6, ++ 0x5d, 0x8d, 0x58, 0x89, 0xfe, 0x81, 0xa2, 0x0e, 0xee, 0x8f, 0x13, 0xf2, ++ 0xcc, 0xa8, 0xb6, 0x48, 0x81, 0x77, 0x43, 0x47, 0x02, 0xf7, 0xe6, 0x6d, ++ 0x64, 0x39, 0xc6, 0xf5, 0xf4, 0xb3, 0x75, 0xbf, 0xff, 0x3d, 0x7c, 0x7c, ++ 0xce, 0xd6, 0x68, 0xff, 0xe7, 0x9c, 0x5c, 0xfd, 0xa2, 0x6c, 0x23, 0xf4, ++ 0x8d, 0x77, 0xa8, 0xd7, 0x32, 0x67, 0x8e, 0x1c, 0xe4, 0x23, 0x6b, 0x8e, ++ 0x7b, 0x8e, 0xce, 0x8f, 0x05, 0x43, 0x50, 0x46, 0xd3, 0xf2, 0xce, 0xda, ++ 0x66, 0xfc, 0x5f, 0xc6, 0x37, 0x5c, 0x5b, 0x9a, 0xf2, 0xc8, 0x99, 0x16, ++ 0xb9, 0xef, 0x2c, 0x3d, 0xbb, 0x38, 0x12, 0xd3, 0x3c, 0x3f, 0xa8, 0x93, ++ 0xfd, 0x8b, 0xaf, 0x33, 0xce, 0x86, 0x87, 0x96, 0x42, 0x5d, 0xec, 0xc7, ++ 0x9d, 0x6d, 0xb3, 0x90, 0x5a, 0x25, 0x3c, 0xd4, 0xdd, 0x5f, 0xa1, 0x3e, ++ 0xff, 0x02, 0xf7, 0x19, 0x5f, 0xc1, 0xf1, 0x90, 0x8d, 0x21, 0xe2, 0xd7, ++ 0x3a, 0xe3, 0x76, 0xc5, 0xe2, 0x67, 0xe6, 0x44, 0x58, 0x6f, 0x30, 0xd7, ++ 0xfa, 0x54, 0x03, 0x1a, 0x76, 0x49, 0x79, 0x91, 0x7b, 0xc6, 0x95, 0xb7, ++ 0x3f, 0x23, 0x9f, 0x8b, 0x36, 0x3b, 0xe5, 0xf9, 0x24, 0xd0, 0x20, 0xe7, ++ 0x84, 0x15, 0xbc, 0xbd, 0xd0, 0xc6, 0x63, 0x19, 0x7c, 0xb3, 0x0a, 0xcd, ++ 0xb9, 0x41, 0xd5, 0xf3, 0xcd, 0xb9, 0x58, 0x64, 0xfc, 0x5a, 0x95, 0xf9, ++ 0x48, 0xe2, 0xbe, 0x85, 0x72, 0x1e, 0x4d, 0x3f, 0xf3, 0x3d, 0xfa, 0xd6, ++ 0x71, 0xd8, 0xd8, 0x3e, 0xf9, 0x92, 0x33, 0x35, 0x37, 0x84, 0xa7, 0x26, ++ 0xa5, 0x6e, 0x37, 0x4e, 0x70, 0x4e, 0xbe, 0xec, 0xee, 0xe7, 0x45, 0x92, ++ 0x27, 0x54, 0x79, 0xe7, 0xb0, 0x1b, 0x6f, 0x8d, 0x1a, 0xd8, 0xc7, 0x1c, ++ 0xea, 0x57, 0xc3, 0xab, 0xf0, 0xeb, 0xe1, 0x66, 0xed, 0x6f, 0x14, 0x39, ++ 0x03, 0xff, 0x71, 0xfc, 0xa8, 0x21, 0x88, 0x83, 0xb4, 0xa1, 0x69, 0xbb, ++ 0x0b, 0x6f, 0xdb, 0x56, 0x64, 0x2e, 0x22, 0x7b, 0xbc, 0x9e, 0xc8, 0x01, ++ 0x79, 0xcf, 0x79, 0x9d, 0x1a, 0x39, 0xb8, 0x44, 0x89, 0x58, 0x6f, 0xa8, ++ 0x2b, 0xf1, 0x8b, 0x7c, 0x17, 0xce, 0xe4, 0x67, 0xda, 0xc2, 0x66, 0x07, ++ 0x8d, 0x62, 0x07, 0x62, 0x0f, 0xb4, 0x45, 0xe6, 0x8a, 0xdf, 0x26, 0x8f, ++ 0xee, 0xfd, 0x18, 0xed, 0x31, 0x43, 0x7b, 0xcc, 0xd0, 0x1e, 0x89, 0x49, ++ 0xcf, 0x10, 0xab, 0xbe, 0x96, 0xa1, 0x3d, 0xd2, 0x7f, 0xbe, 0x42, 0xff, ++ 0x29, 0x72, 0xe5, 0x1e, 0x77, 0x4d, 0xff, 0x15, 0xc6, 0x44, 0xfb, 0x31, ++ 0x79, 0x7f, 0xb8, 0x79, 0x7d, 0x01, 0x91, 0x9e, 0x01, 0x65, 0x5d, 0xbd, ++ 0xbc, 0xcf, 0xf1, 0xf9, 0xa8, 0xf8, 0x80, 0xbc, 0x7b, 0x46, 0xbf, 0x1a, ++ 0x3f, 0x55, 0x27, 0xef, 0xb2, 0xee, 0xdf, 0xfd, 0x51, 0x3a, 0xfb, 0x7b, ++ 0xf6, 0x43, 0xf4, 0xf5, 0xc7, 0x8e, 0x5d, 0x74, 0xf9, 0x4f, 0xce, 0x8f, ++ 0x1a, 0x65, 0xfc, 0xab, 0xf1, 0xf3, 0xe1, 0x4e, 0x9c, 0x65, 0xfc, 0xfd, ++ 0x74, 0xfb, 0x94, 0x45, 0x9b, 0xdd, 0x68, 0x78, 0x4c, 0x4c, 0xe6, 0x3b, ++ 0x71, 0xda, 0x36, 0x91, 0xb7, 0x9b, 0xd7, 0x7f, 0x57, 0x79, 0x53, 0xcd, ++ 0xcd, 0x2b, 0xf2, 0xf9, 0xdf, 0x90, 0x5f, 0x1e, 0x6a, 0x91, 0xf7, 0x5d, ++ 0x13, 0x18, 0xc9, 0x8b, 0x9d, 0x06, 0x71, 0xd3, 0x12, 0x43, 0xde, 0x11, ++ 0xfb, 0xbd, 0x7f, 0xf7, 0xd9, 0xb2, 0x97, 0x72, 0xce, 0x99, 0x0a, 0xfa, ++ 0xad, 0x20, 0x7d, 0xd8, 0xb3, 0x4b, 0x7e, 0x07, 0x40, 0xfc, 0x59, 0xc1, ++ 0x67, 0x8c, 0x29, 0xad, 0x06, 0x91, 0xa7, 0x77, 0x33, 0x81, 0x7a, 0x2d, ++ 0x2d, 0x67, 0x88, 0x3b, 0xf1, 0x26, 0xcb, 0x57, 0xd1, 0x2f, 0x5e, 0xcb, ++ 0x7b, 0xbd, 0x3f, 0x4a, 0xcb, 0x7b, 0xec, 0x2b, 0xf1, 0xa3, 0xfc, 0xcb, ++ 0xea, 0x2f, 0x82, 0x06, 0xde, 0x2e, 0xac, 0xc2, 0xfc, 0x5d, 0xb2, 0xbe, ++ 0x90, 0xc4, 0x7e, 0x3b, 0x72, 0xf4, 0x59, 0xac, 0xc2, 0xbc, 0xb1, 0xd5, ++ 0xcc, 0xa3, 0x15, 0xbc, 0x17, 0x5d, 0x8d, 0x00, 0x3f, 0xd7, 0xee, 0x72, ++ 0x9c, 0xc3, 0xf1, 0x3a, 0x67, 0xfb, 0x6a, 0x99, 0x3b, 0xc1, 0x93, 0x65, ++ 0xf5, 0xa8, 0x5d, 0x0d, 0x8c, 0x09, 0x57, 0xd1, 0x71, 0xeb, 0xc0, 0x2a, ++ 0x5c, 0xb1, 0xab, 0x39, 0x76, 0x2b, 0x9a, 0xb3, 0x47, 0x3c, 0xab, 0xd0, ++ 0x30, 0x76, 0x2f, 0xe7, 0x40, 0xca, 0x6a, 0xb4, 0x3f, 0x0b, 0x95, 0xe4, ++ 0x84, 0x9d, 0xe9, 0x9f, 0x3a, 0xf3, 0x4d, 0x77, 0x1f, 0x0e, 0xeb, 0x0a, ++ 0x3a, 0xe3, 0x5d, 0x35, 0x52, 0x23, 0x4f, 0x38, 0x75, 0xa6, 0x17, 0x6b, ++ 0x0b, 0x6d, 0xb8, 0x69, 0xc8, 0x71, 0x4e, 0x2f, 0x49, 0x22, 0x60, 0x06, ++ 0x88, 0x61, 0x01, 0x3c, 0x94, 0xae, 0xe1, 0x7f, 0x07, 0x15, 0x8c, 0xc9, ++ 0x2d, 0xaa, 0xbe, 0x7e, 0x9e, 0x47, 0xef, 0x29, 0x28, 0x12, 0xf7, 0x03, ++ 0x78, 0x80, 0xf1, 0x79, 0x45, 0x3a, 0x8c, 0x54, 0xc1, 0x71, 0x5e, 0xed, ++ 0x08, 0xe1, 0x7e, 0xd6, 0xef, 0x4a, 0xf7, 0xa3, 0x97, 0x76, 0x91, 0x1a, ++ 0xd3, 0xb5, 0x20, 0xe3, 0xfd, 0xba, 0x82, 0x9f, 0x31, 0xac, 0x01, 0xb7, ++ 0xec, 0xd2, 0xf0, 0x50, 0x21, 0xc0, 0xf8, 0xe6, 0x2c, 0x3d, 0x69, 0x58, ++ 0x57, 0x7a, 0xa0, 0x63, 0x63, 0x21, 0x84, 0x95, 0xe9, 0xc8, 0xb4, 0xbc, ++ 0x47, 0x7d, 0xd6, 0x88, 0xe1, 0xc1, 0x42, 0x18, 0xb7, 0xa5, 0x0f, 0x3d, ++ 0x34, 0x1f, 0xd6, 0xff, 0x98, 0x87, 0x36, 0x7c, 0xa6, 0xd0, 0x44, 0xf9, ++ 0x91, 0xf5, 0xaf, 0x28, 0x4d, 0xf8, 0xec, 0x98, 0x41, 0xf9, 0x2a, 0x6e, ++ 0xa5, 0x9c, 0x9b, 0xd3, 0x57, 0xe0, 0x81, 0xb1, 0x0e, 0xdc, 0x5b, 0x58, ++ 0x8c, 0xe5, 0x8c, 0x4f, 0x1b, 0x98, 0x1b, 0xe2, 0xbf, 0x00, 0xb7, 0x0d, ++ 0x89, 0xee, 0xa1, 0xbc, 0xda, 0x31, 0xc5, 0x7c, 0xdc, 0x00, 0x0d, 0x91, ++ 0xf7, 0x74, 0x72, 0x30, 0x03, 0xb7, 0xed, 0x5d, 0xec, 0xee, 0xc9, 0x37, ++ 0xc7, 0x2b, 0x91, 0xea, 0x56, 0xd0, 0x39, 0x24, 0x71, 0x56, 0xb8, 0x8d, ++ 0xc1, 0xb8, 0x1a, 0x65, 0x1b, 0x06, 0xe3, 0x6a, 0xf1, 0x7e, 0x6f, 0x46, ++ 0xd6, 0x2e, 0x7e, 0x42, 0xbe, 0x14, 0x47, 0xa7, 0x1b, 0xa3, 0xfd, 0xe4, ++ 0xd7, 0x16, 0xbc, 0x8c, 0xdd, 0x71, 0xda, 0xf8, 0xd2, 0x76, 0x89, 0xd5, ++ 0x3a, 0x06, 0xe8, 0x0f, 0x93, 0x83, 0xfa, 0x86, 0x69, 0xc5, 0x44, 0x61, ++ 0xaf, 0xc4, 0xc4, 0x10, 0x1e, 0x4c, 0x9b, 0x38, 0x29, 0xe7, 0xf8, 0xaf, ++ 0x4a, 0xae, 0xa8, 0x81, 0x6e, 0x3c, 0x80, 0xa8, 0x75, 0x8c, 0xb1, 0xfd, ++ 0x4c, 0xae, 0x01, 0x37, 0xed, 0x92, 0x32, 0xed, 0x78, 0x7d, 0xd4, 0x8b, ++ 0x9b, 0xd2, 0x9b, 0xf0, 0x44, 0xd6, 0x83, 0x11, 0xa3, 0xb9, 0x5f, 0x65, ++ 0xfc, 0xbc, 0xbe, 0x3d, 0x12, 0xfc, 0x3a, 0xb9, 0xea, 0xf4, 0x62, 0x46, ++ 0xe5, 0xb9, 0x1d, 0xe8, 0x64, 0xbf, 0x3a, 0x75, 0xf1, 0x49, 0x0b, 0xf7, ++ 0x76, 0x6c, 0xc2, 0xb1, 0xac, 0x6e, 0x3d, 0x29, 0xeb, 0x0c, 0xed, 0x7c, ++ 0x3e, 0xc7, 0x8b, 0x3e, 0x5d, 0x38, 0xad, 0x4e, 0xdf, 0x22, 0xeb, 0xd4, ++ 0x3b, 0x70, 0x92, 0xf6, 0xda, 0x9f, 0x5b, 0xca, 0xd8, 0x2f, 0x31, 0xdf, ++ 0x6f, 0x85, 0x59, 0xaf, 0xee, 0x3a, 0x05, 0x27, 0xf6, 0x09, 0xc7, 0x5a, ++ 0x8a, 0xbb, 0xa8, 0xa7, 0xce, 0xb4, 0x8a, 0xeb, 0xc7, 0xd6, 0xe0, 0xf4, ++ 0xce, 0x22, 0xe7, 0x7a, 0x35, 0x6e, 0x7d, 0x86, 0x9c, 0xab, 0x67, 0x16, ++ 0x39, 0x17, 0xb9, 0x5c, 0xec, 0x41, 0xc5, 0x8b, 0x68, 0x21, 0x41, 0x5e, ++ 0x21, 0xfc, 0x22, 0x8c, 0xa7, 0xf2, 0x1d, 0xb8, 0x25, 0xdd, 0x84, 0x71, ++ 0xf2, 0xad, 0x1c, 0xf1, 0x22, 0x97, 0x67, 0x5c, 0x19, 0x6d, 0xe4, 0xa5, ++ 0xf1, 0x5a, 0xc0, 0x4b, 0x77, 0xef, 0xad, 0xa5, 0x2d, 0x27, 0xbb, 0x25, ++ 0x4f, 0x23, 0xff, 0xcd, 0x4b, 0xac, 0x56, 0x98, 0xb7, 0xfe, 0xaf, 0x7a, ++ 0xc9, 0x4d, 0x83, 0xba, 0x82, 0xaf, 0x65, 0x35, 0xfc, 0x55, 0xfb, 0x76, ++ 0x25, 0xd9, 0xe0, 0xbe, 0x83, 0x4a, 0xdf, 0xb6, 0x70, 0x92, 0x63, 0xba, ++ 0x37, 0x2b, 0x76, 0x49, 0x19, 0xcc, 0xd1, 0x8f, 0x19, 0xf5, 0xd0, 0xea, ++ 0x35, 0x39, 0xd7, 0xc4, 0xd8, 0xc1, 0xf8, 0x6b, 0xa7, 0xc8, 0xa3, 0x5a, ++ 0xbb, 0x5b, 0x55, 0x8f, 0xbc, 0x9f, 0x67, 0x68, 0xaa, 0xf8, 0x58, 0x0a, ++ 0x15, 0x69, 0xbf, 0x55, 0x27, 0xf5, 0x97, 0x6c, 0x60, 0x3c, 0x68, 0x5d, ++ 0xff, 0xb2, 0xf0, 0xfb, 0x39, 0x11, 0x6d, 0x0a, 0x1b, 0xb0, 0xce, 0xd6, ++ 0x19, 0x03, 0xd7, 0x38, 0xbd, 0x9c, 0x87, 0x51, 0x7b, 0x03, 0xee, 0xb2, ++ 0x5b, 0xa7, 0x1e, 0xa7, 0x6d, 0xe1, 0xce, 0x0d, 0xe8, 0xe4, 0xb3, 0x91, ++ 0x4c, 0xf3, 0x74, 0x2f, 0x75, 0x7d, 0x7c, 0x76, 0xcc, 0x5d, 0xf7, 0x97, ++ 0x33, 0xe4, 0xa3, 0xe4, 0xd7, 0x5f, 0xcd, 0xb4, 0x26, 0x87, 0xd4, 0x1e, ++ 0x05, 0x73, 0x24, 0x97, 0x4c, 0x90, 0x53, 0x05, 0xf0, 0x99, 0xb4, 0x45, ++ 0x1f, 0x00, 0x6d, 0xae, 0x83, 0x79, 0xc5, 0x13, 0x4e, 0xbd, 0x19, 0x35, ++ 0x44, 0x3f, 0xeb, 0x0b, 0x4b, 0xf1, 0x14, 0x63, 0x6f, 0xf3, 0xb5, 0x7a, ++ 0xf0, 0x39, 0x68, 0xf0, 0x99, 0x3f, 0x75, 0x1a, 0xcc, 0x1a, 0x3c, 0x30, ++ 0x12, 0x4d, 0xdc, 0xc4, 0x38, 0xdb, 0x79, 0xad, 0x7e, 0xf4, 0x14, 0x63, ++ 0xe0, 0x7c, 0xd3, 0x96, 0xf3, 0x26, 0xe4, 0x3b, 0x01, 0xd7, 0xce, 0x4f, ++ 0xdb, 0xe2, 0x27, 0x3a, 0x71, 0x33, 0x84, 0xcf, 0xd1, 0xce, 0xdf, 0xb7, ++ 0x63, 0x98, 0x24, 0xdf, 0xf8, 0x2c, 0xfd, 0xe3, 0x8c, 0x1d, 0x49, 0x5d, ++ 0xa3, 0xea, 0xd8, 0x40, 0xff, 0x78, 0xd7, 0x4e, 0xd0, 0x77, 0x3e, 0xc6, ++ 0xab, 0x8d, 0xfe, 0x10, 0x63, 0x1d, 0x8d, 0x7e, 0x10, 0x72, 0xcf, 0x95, ++ 0x8e, 0x65, 0x9a, 0xbb, 0x1f, 0x42, 0x73, 0xec, 0x66, 0xa5, 0x8e, 0x79, ++ 0x6a, 0x10, 0xf7, 0x14, 0x6e, 0xc0, 0x89, 0x6c, 0x64, 0x9a, 0x39, 0xf9, ++ 0xc6, 0xa5, 0x0a, 0xee, 0x20, 0x67, 0x5b, 0x5f, 0xad, 0xb4, 0x4e, 0x3d, ++ 0xa5, 0x44, 0x68, 0x93, 0x8c, 0x97, 0xf4, 0xcf, 0xcf, 0xb2, 0xcc, 0x99, ++ 0x6c, 0x35, 0x36, 0x8c, 0xd8, 0xe8, 0xcf, 0x54, 0xa0, 0x6a, 0xa7, 0x1f, ++ 0xf7, 0x8f, 0xe9, 0xc8, 0x64, 0x64, 0x1d, 0xd9, 0x6f, 0xd5, 0x12, 0x37, ++ 0x46, 0x89, 0x0d, 0x2f, 0x2d, 0x01, 0xa6, 0xf7, 0xae, 0xc1, 0x81, 0x9d, ++ 0x3a, 0xe3, 0x5d, 0xd1, 0x3e, 0x82, 0x71, 0x97, 0x93, 0xa7, 0x84, 0x93, ++ 0x57, 0x99, 0x12, 0xfb, 0xa2, 0x3d, 0x8f, 0x50, 0x07, 0xb7, 0x15, 0xc4, ++ 0xee, 0x12, 0x9c, 0xa3, 0x30, 0x06, 0x69, 0x23, 0xfb, 0xec, 0x26, 0xe6, ++ 0xe6, 0x01, 0x58, 0xb4, 0x11, 0x4b, 0xde, 0x53, 0xa5, 0x8d, 0x58, 0xb4, ++ 0x11, 0x8b, 0x36, 0x62, 0xd1, 0x46, 0xac, 0xfc, 0x52, 0xe6, 0x4c, 0x3a, ++ 0xc6, 0xd9, 0xe6, 0xb6, 0x51, 0x72, 0xf7, 0xa0, 0xd8, 0x4a, 0x0c, 0x5f, ++ 0xcf, 0xf4, 0x2b, 0xda, 0x9d, 0x37, 0x60, 0x24, 0x7b, 0x23, 0x2f, 0x05, ++ 0xb7, 0xd2, 0x56, 0x1e, 0xcd, 0x89, 0xed, 0xe9, 0xee, 0xef, 0xd3, 0x3c, ++ 0x9b, 0xdf, 0x33, 0x1b, 0xd5, 0xe2, 0x03, 0x8c, 0x45, 0xee, 0x7d, 0x39, ++ 0x73, 0xec, 0xc7, 0x68, 0xfe, 0x82, 0x5f, 0x7c, 0x4f, 0xce, 0xab, 0xb4, ++ 0xcb, 0x6f, 0xc5, 0x74, 0x30, 0x0f, 0x90, 0x73, 0xee, 0x32, 0x4e, 0x19, ++ 0x57, 0x71, 0x4c, 0x55, 0x83, 0x9b, 0xf0, 0xf5, 0x41, 0x9d, 0xb1, 0xca, ++ 0xc0, 0x93, 0x39, 0x89, 0xe5, 0xe2, 0xdf, 0x32, 0x0f, 0xe2, 0xeb, 0x1e, ++ 0xd4, 0xb4, 0x7b, 0x11, 0x70, 0xfd, 0xbc, 0x39, 0xbc, 0x43, 0xb1, 0xe9, ++ 0x3b, 0xba, 0x9c, 0x03, 0x9d, 0x0a, 0xeb, 0x0d, 0x38, 0xbd, 0xbb, 0x1d, ++ 0xff, 0x6d, 0xa7, 0x87, 0x3c, 0xc0, 0x59, 0xfa, 0x52, 0x5c, 0x4f, 0x4e, ++ 0x2b, 0xd1, 0xd8, 0x2c, 0xa5, 0x1d, 0xf7, 0x90, 0xfb, 0x6f, 0x18, 0x8c, ++ 0x74, 0x33, 0x66, 0x1b, 0xb7, 0x28, 0x4b, 0x51, 0xc5, 0x1c, 0xa0, 0x8d, ++ 0x39, 0xc0, 0x83, 0xc4, 0x80, 0xaf, 0x66, 0xbc, 0x68, 0x59, 0x2c, 0xbf, ++ 0x4d, 0xa6, 0xbb, 0x6b, 0x3b, 0x2f, 0x90, 0xa3, 0xce, 0x37, 0x3b, 0xe4, ++ 0x2c, 0x8e, 0x72, 0xf6, 0xba, 0x29, 0x24, 0x28, 0x7f, 0xcc, 0xcd, 0x2f, ++ 0x12, 0x38, 0x98, 0x27, 0x6e, 0x70, 0xdc, 0xaf, 0xb4, 0xfd, 0x84, 0xf9, ++ 0xb0, 0x70, 0x7b, 0x13, 0x13, 0x39, 0x97, 0xff, 0x47, 0xea, 0x88, 0x19, ++ 0xd9, 0x41, 0xbd, 0xcb, 0xaf, 0x9a, 0x78, 0x64, 0xaf, 0xf8, 0xb0, 0x89, ++ 0xf6, 0x21, 0x3d, 0x7c, 0x9b, 0x1a, 0x0d, 0xae, 0xe3, 0xb3, 0x05, 0x9c, ++ 0xcf, 0xc7, 0x33, 0x32, 0x8f, 0x1a, 0x5a, 0x18, 0x9b, 0xdf, 0x9c, 0xd0, ++ 0xb1, 0x88, 0x71, 0xfa, 0x9d, 0x89, 0x18, 0x96, 0x32, 0x66, 0x3b, 0xcc, ++ 0x1f, 0x12, 0x19, 0xf1, 0x45, 0xf2, 0x81, 0x09, 0x8d, 0x71, 0x56, 0xd6, ++ 0x87, 0x9e, 0xc0, 0xd8, 0x6a, 0x0d, 0xfb, 0xdc, 0xf3, 0x7c, 0x7e, 0xab, ++ 0x81, 0x58, 0xd9, 0x39, 0xe0, 0xc7, 0xa7, 0x87, 0x36, 0xe3, 0xf5, 0xc5, ++ 0xc2, 0x95, 0xd6, 0x38, 0xa2, 0x9f, 0xc7, 0x29, 0x73, 0x8c, 0xbc, 0x78, ++ 0x94, 0x79, 0xd7, 0xc2, 0x7d, 0x6b, 0xf0, 0xc9, 0x5d, 0x17, 0xf2, 0xb4, ++ 0x33, 0x71, 0xeb, 0x6e, 0xda, 0xc4, 0xfa, 0x00, 0x6d, 0xa2, 0x96, 0x36, ++ 0x61, 0x67, 0xa2, 0xc9, 0x02, 0x6d, 0x22, 0x46, 0xdc, 0xc8, 0x0e, 0x48, ++ 0x39, 0xf7, 0x9d, 0x99, 0xbb, 0xe4, 0xdd, 0x65, 0x83, 0xbe, 0xb3, 0x75, ++ 0xc0, 0xd9, 0xec, 0x65, 0xbc, 0x79, 0xa4, 0xa3, 0x89, 0xd8, 0x72, 0x23, ++ 0xf6, 0x0c, 0x36, 0xa1, 0x85, 0x31, 0x63, 0x61, 0x1a, 0x77, 0x84, 0xa1, ++ 0xce, 0x0f, 0x23, 0xb2, 0xe1, 0x1d, 0x44, 0xa7, 0xef, 0x56, 0x5a, 0x8f, ++ 0xbe, 0xa8, 0x44, 0x36, 0xfe, 0x84, 0x36, 0x7c, 0x56, 0x91, 0xb6, 0x9b, ++ 0x70, 0x35, 0xfd, 0xe4, 0x2a, 0xfa, 0x84, 0xc6, 0x5c, 0x52, 0x63, 0xdd, ++ 0xfe, 0x41, 0x1f, 0xe6, 0x33, 0xd7, 0x93, 0xb3, 0xca, 0xb1, 0x31, 0x2f, ++ 0xb2, 0x3b, 0xf5, 0xa9, 0x47, 0xd0, 0x08, 0x63, 0xec, 0x46, 0x6c, 0x1d, ++ 0xd4, 0x10, 0xe5, 0xbd, 0xbe, 0x9d, 0x0b, 0xd0, 0x4c, 0xfb, 0xd6, 0xe8, ++ 0xa7, 0xbd, 0x83, 0x2a, 0x16, 0x8c, 0xdd, 0x80, 0x1d, 0x83, 0x0a, 0xee, ++ 0x8b, 0x2a, 0x68, 0x19, 0x91, 0x1c, 0x2c, 0x86, 0xa7, 0x32, 0xc2, 0x15, ++ 0xa1, 0xb4, 0x5c, 0x4b, 0x8e, 0x4c, 0xee, 0xf9, 0x93, 0x9c, 0xcc, 0xb9, ++ 0xe8, 0x53, 0x7e, 0x53, 0xa6, 0x1d, 0x9f, 0xdb, 0xd9, 0x80, 0xab, 0x76, ++ 0xeb, 0xd6, 0x69, 0xc5, 0x59, 0x7a, 0x80, 0x7c, 0xde, 0xaf, 0x16, 0xe7, ++ 0xfc, 0xc1, 0xc1, 0x67, 0x19, 0x2f, 0x7e, 0xe2, 0x04, 0xf5, 0xa5, 0xe8, ++ 0x8b, 0x27, 0xb1, 0xb6, 0xa3, 0x1d, 0x6b, 0xf7, 0x8a, 0xbe, 0x1c, 0xe6, ++ 0x87, 0xcc, 0xfd, 0x26, 0xa7, 0xf0, 0x0e, 0xfd, 0x77, 0x11, 0x39, 0xed, ++ 0x52, 0xc6, 0x89, 0x37, 0x16, 0x9b, 0xd4, 0x9f, 0xee, 0x9e, 0xf5, 0x9b, ++ 0x67, 0x9a, 0xa8, 0x1d, 0xd4, 0x19, 0x67, 0x4c, 0xcc, 0xda, 0x2b, 0xed, ++ 0x99, 0xb8, 0x67, 0x50, 0x4f, 0x3d, 0xcd, 0xb9, 0x14, 0xbb, 0x11, 0xcc, ++ 0xae, 0x61, 0xec, 0x3f, 0x39, 0x29, 0x38, 0xd5, 0x89, 0x13, 0xcc, 0x03, ++ 0xde, 0x7c, 0x2c, 0xda, 0xfd, 0x33, 0xe6, 0x74, 0xef, 0x50, 0x46, 0x96, ++ 0xfd, 0x1b, 0xe0, 0xbc, 0x56, 0xa4, 0xf5, 0x8d, 0xff, 0x8c, 0x28, 0xfd, ++ 0xbb, 0x0b, 0xb5, 0xd4, 0xc9, 0x81, 0xc1, 0x95, 0xf0, 0xd3, 0x16, 0x1e, ++ 0xc9, 0x88, 0xdd, 0x10, 0xbf, 0x77, 0x7e, 0x02, 0x5b, 0xf7, 0x17, 0xf3, ++ 0xbc, 0x7b, 0x06, 0x36, 0xd1, 0xc6, 0x85, 0xb3, 0xc7, 0x68, 0xef, 0x98, ++ 0xe7, 0x43, 0xb2, 0x9e, 0x18, 0x91, 0x58, 0x4e, 0xcc, 0x7c, 0xd4, 0x20, ++ 0xae, 0xd6, 0x47, 0xc2, 0x2d, 0xaa, 0x95, 0x60, 0x5e, 0x17, 0xbe, 0x0f, ++ 0xd2, 0xbe, 0x85, 0x75, 0x4b, 0x36, 0x61, 0x4f, 0xd6, 0x8b, 0xaa, 0xc5, ++ 0x1e, 0xe2, 0xb1, 0x60, 0x94, 0x15, 0x94, 0xe7, 0x6b, 0x21, 0x7e, 0x22, ++ 0xf3, 0xeb, 0xc1, 0x99, 0x78, 0xf3, 0x86, 0xac, 0xfc, 0x96, 0x05, 0x73, ++ 0xbe, 0xcf, 0xa2, 0x83, 0x73, 0x2f, 0xfe, 0x98, 0xc0, 0x3d, 0x63, 0xc2, ++ 0xd5, 0xc8, 0xe7, 0x6c, 0x3f, 0xfe, 0x3a, 0x2b, 0x9c, 0x6e, 0x33, 0xee, ++ 0x69, 0x2f, 0xe7, 0x6e, 0x62, 0x77, 0xad, 0xd3, 0x1e, 0x34, 0x93, 0x93, ++ 0xe9, 0xb9, 0xac, 0x1a, 0xb1, 0x52, 0x88, 0xf4, 0xa7, 0x20, 0x71, 0xa2, ++ 0xd5, 0xe2, 0x0c, 0x53, 0x36, 0xb9, 0xa5, 0xed, 0x41, 0x1d, 0x7d, 0x5c, ++ 0x7e, 0x44, 0xae, 0x9d, 0xf6, 0xf3, 0xac, 0x5d, 0x0d, 0xcd, 0xb5, 0x75, ++ 0x2f, 0x96, 0x16, 0x2c, 0xe2, 0xed, 0x52, 0xb4, 0x3d, 0x16, 0xc0, 0x35, ++ 0xe4, 0x26, 0x57, 0xa7, 0x9f, 0x70, 0x66, 0x11, 0x7b, 0xdb, 0x46, 0xa2, ++ 0xc1, 0x23, 0xe4, 0x81, 0x07, 0x96, 0xfc, 0xd4, 0xf1, 0x98, 0xae, 0x5f, ++ 0x68, 0xf4, 0x00, 0xe7, 0x33, 0x1d, 0xfa, 0xd4, 0x0e, 0x04, 0x90, 0x20, ++ 0x7e, 0x5e, 0x99, 0x69, 0x40, 0xfb, 0xee, 0x7e, 0xce, 0x7f, 0x10, 0x57, ++ 0xf2, 0xfb, 0x62, 0xc6, 0x37, 0x8d, 0xd8, 0xaa, 0xc9, 0xe7, 0x82, 0xd8, ++ 0x4b, 0x98, 0x7e, 0xe4, 0x2c, 0xbd, 0xb3, 0xdd, 0xba, 0x63, 0x36, 0xf5, ++ 0xd5, 0x42, 0x5c, 0x5e, 0x9a, 0x89, 0x6c, 0xbc, 0x59, 0x51, 0xb0, 0xb2, ++ 0xdd, 0x60, 0xdb, 0x01, 0xc4, 0x32, 0xb2, 0x36, 0x70, 0xe8, 0xa1, 0x3a, ++ 0x58, 0xad, 0x01, 0xda, 0xe9, 0x11, 0x45, 0xd6, 0x35, 0x44, 0x6f, 0x4d, ++ 0xb8, 0x8a, 0x7c, 0x44, 0x23, 0x66, 0xc7, 0x0a, 0xa2, 0x43, 0x60, 0x6d, ++ 0x6e, 0x0d, 0xf6, 0x0c, 0x8b, 0x7f, 0x0a, 0x76, 0x3a, 0x4e, 0xe5, 0xe2, ++ 0xa8, 0xf1, 0x36, 0x75, 0xf8, 0xc6, 0x84, 0x60, 0x90, 0x82, 0x79, 0xb4, ++ 0x63, 0x55, 0x97, 0x58, 0x2b, 0xb8, 0x15, 0xa6, 0xdf, 0x76, 0xe0, 0xd3, ++ 0x8c, 0x6d, 0xd5, 0x9c, 0x83, 0x55, 0x4b, 0x9a, 0xe8, 0xbf, 0xc4, 0xc9, ++ 0x89, 0x20, 0xaf, 0x10, 0x8e, 0xef, 0x6f, 0xe4, 0xa5, 0xf1, 0x5a, 0xc0, ++ 0x4b, 0xe7, 0x3d, 0x15, 0x67, 0xf6, 0x93, 0x33, 0xed, 0x15, 0x0e, 0x22, ++ 0x3e, 0xe8, 0xc7, 0xd3, 0x13, 0x20, 0x8f, 0x31, 0xc8, 0x43, 0x04, 0xff, ++ 0x64, 0x9e, 0x98, 0xc7, 0x0c, 0xc6, 0x11, 0x1d, 0x29, 0x72, 0x8e, 0x93, ++ 0xc3, 0x7a, 0xcf, 0x5a, 0x44, 0xb5, 0xbf, 0x26, 0x7e, 0x9d, 0x1a, 0x6d, ++ 0xc7, 0x74, 0x96, 0xb8, 0xb5, 0xb8, 0x1d, 0x6f, 0xe7, 0x36, 0xd1, 0xff, ++ 0x55, 0x9c, 0x25, 0x66, 0x69, 0x73, 0x05, 0xd7, 0x05, 0x43, 0xfd, 0xb4, ++ 0xd7, 0x0e, 0x59, 0x03, 0x55, 0xe2, 0xc4, 0xac, 0x6b, 0xd2, 0xcf, 0x3a, ++ 0xb5, 0x3a, 0x73, 0x2a, 0x35, 0x81, 0x0c, 0x31, 0xcb, 0xce, 0xca, 0x7c, ++ 0x6d, 0xc6, 0x56, 0xe2, 0xd5, 0xd6, 0x9c, 0xd8, 0x37, 0x6d, 0x7a, 0x50, ++ 0x0f, 0x16, 0x68, 0xdb, 0xea, 0x5e, 0x91, 0x61, 0xa2, 0x8f, 0xb1, 0xfd, ++ 0x33, 0x1d, 0x26, 0x76, 0xe4, 0x24, 0x0e, 0x0a, 0x07, 0xd3, 0x98, 0x97, ++ 0x24, 0xd1, 0x43, 0x9c, 0x7a, 0xdb, 0xee, 0xc4, 0x0a, 0xe2, 0xd4, 0x2f, ++ 0x98, 0xa7, 0xdc, 0x49, 0x9c, 0x7a, 0xc3, 0x2e, 0xe2, 0xd4, 0xcd, 0x13, ++ 0x62, 0x0b, 0x45, 0x5e, 0x7e, 0xc2, 0x6e, 0x6b, 0x90, 0xdf, 0x39, 0xab, ++ 0x36, 0x7f, 0x57, 0x5c, 0x58, 0x85, 0x97, 0x86, 0xcb, 0x7b, 0xc5, 0x91, ++ 0xe4, 0xed, 0xe4, 0xcc, 0x47, 0x47, 0xcb, 0x9c, 0xf7, 0xb8, 0x9b, 0x5b, ++ 0xcf, 0x32, 0xcb, 0xfb, 0x96, 0xe5, 0xfd, 0x06, 0x0b, 0x5f, 0x5d, 0x22, ++ 0x3c, 0x53, 0xd6, 0x81, 0x2a, 0xc8, 0x27, 0xbb, 0x31, 0xbe, 0xf3, 0x3d, ++ 0x3c, 0x32, 0xa8, 0xde, 0x5c, 0xc3, 0xd8, 0x7a, 0x8b, 0xb2, 0x19, 0x9e, ++ 0xb8, 0xbc, 0x47, 0x2a, 0x6b, 0xe5, 0xcc, 0x5d, 0x26, 0xb3, 0xe8, 0xdb, ++ 0x57, 0x83, 0x43, 0x41, 0xc7, 0x79, 0xda, 0x98, 0x27, 0x3f, 0x13, 0x20, ++ 0xb8, 0x19, 0xa8, 0xa0, 0x2f, 0xdc, 0xfc, 0x5b, 0xbf, 0xdd, 0x58, 0xde, ++ 0x3b, 0xd8, 0x88, 0xbb, 0x76, 0x3d, 0x8c, 0x9e, 0x5d, 0x7f, 0x8b, 0x4f, ++ 0x0e, 0x2d, 0xec, 0x9f, 0xe7, 0x71, 0x9c, 0xab, 0xdb, 0xa7, 0x70, 0x2a, ++ 0xce, 0xd8, 0x18, 0x52, 0xf0, 0xbd, 0xab, 0x16, 0x8a, 0x1c, 0xfe, 0xbd, ++ 0xef, 0x68, 0xae, 0xbc, 0x5b, 0x4b, 0x3e, 0x92, 0x98, 0xc3, 0xf1, 0x53, ++ 0xf6, 0x8a, 0xfa, 0xd2, 0xbb, 0xc2, 0x7f, 0x40, 0x5b, 0x3f, 0x16, 0x19, ++ 0xfc, 0x2b, 0xcb, 0x78, 0xcd, 0x49, 0xae, 0x96, 0x7a, 0x15, 0xa5, 0x36, ++ 0xfe, 0x96, 0x9c, 0x90, 0xbc, 0xd0, 0xe0, 0xff, 0x91, 0xeb, 0x44, 0x3e, ++ 0x9f, 0x95, 0xe5, 0xbf, 0xe4, 0x24, 0xbb, 0xe5, 0xbb, 0x94, 0x59, 0xc7, ++ 0x67, 0x52, 0xae, 0xfc, 0xec, 0xf9, 0x92, 0x9c, 0x4a, 0x68, 0x0d, 0x45, ++ 0x39, 0x9f, 0xa6, 0x9c, 0x33, 0x8b, 0x93, 0x50, 0xaf, 0x9d, 0x29, 0xab, ++ 0xdc, 0xee, 0xff, 0x3a, 0x2f, 0xab, 0x58, 0xee, 0x6f, 0xe6, 0xc8, 0xbe, ++ 0x80, 0x7a, 0xed, 0xcc, 0x75, 0xf2, 0x0a, 0xfa, 0x6f, 0x34, 0xb8, 0xd5, ++ 0x5d, 0x9f, 0x36, 0xb0, 0xf6, 0xe2, 0x1c, 0x4b, 0xb0, 0x03, 0xe3, 0x76, ++ 0xb0, 0x94, 0x53, 0xc9, 0x2d, 0x13, 0x5f, 0x66, 0xce, 0xf6, 0x94, 0x1d, ++ 0xe9, 0x5a, 0xa7, 0xb4, 0x26, 0x17, 0x31, 0xce, 0xa0, 0x5e, 0xd6, 0xb0, ++ 0x13, 0xee, 0xef, 0xf9, 0xe5, 0xa3, 0x09, 0xe4, 0x69, 0x8f, 0xaf, 0xd8, ++ 0x91, 0x0d, 0xa7, 0xdc, 0xfd, 0x3b, 0x13, 0x2f, 0xe7, 0x5f, 0x2d, 0xed, ++ 0x33, 0x95, 0x7f, 0x4f, 0x6c, 0xe6, 0x1a, 0xaa, 0xcc, 0xbf, 0x9c, 0xb1, ++ 0x6e, 0x90, 0xb5, 0x0a, 0xcb, 0xa2, 0x9f, 0xf7, 0x66, 0xac, 0xb0, 0x8a, ++ 0xeb, 0x90, 0x0a, 0xc9, 0xbe, 0xc4, 0xd6, 0xd2, 0x6f, 0x52, 0xb1, 0xde, ++ 0xef, 0x58, 0x13, 0x02, 0x8c, 0xd2, 0x39, 0xb6, 0x18, 0xac, 0xc9, 0x2b, ++ 0xc8, 0xc5, 0x64, 0xbd, 0x01, 0xd6, 0x6c, 0x53, 0x43, 0x48, 0x3f, 0xcc, ++ 0x71, 0xfb, 0x30, 0x87, 0xf9, 0x54, 0x7c, 0x61, 0x6b, 0x77, 0xbb, 0x3a, ++ 0x57, 0x70, 0x36, 0x98, 0x54, 0x63, 0x12, 0x07, 0x50, 0x99, 0x96, 0xb3, ++ 0x26, 0x56, 0x97, 0x9f, 0x98, 0xba, 0x98, 0xd8, 0x52, 0x11, 0x85, 0xf7, ++ 0xbe, 0xbc, 0x17, 0xc1, 0x85, 0xbf, 0x70, 0x7e, 0x18, 0x8a, 0x61, 0xdb, ++ 0x64, 0xb9, 0x0f, 0x06, 0xfe, 0x7b, 0xe1, 0xd2, 0x8c, 0xb3, 0x2c, 0xf3, ++ 0x3d, 0x27, 0x39, 0x47, 0xda, 0x2e, 0xca, 0xfd, 0xe8, 0xbe, 0x4a, 0x1f, ++ 0xa5, 0xaf, 0xcd, 0x1a, 0x51, 0x15, 0x5b, 0x8d, 0x89, 0x39, 0xf2, 0x9b, ++ 0x3f, 0xf7, 0xb8, 0x67, 0xd3, 0x65, 0x0e, 0xe4, 0xfd, 0xf1, 0x04, 0xee, ++ 0x93, 0xf7, 0x30, 0x19, 0xb3, 0xee, 0xcd, 0xbb, 0xef, 0x77, 0x42, 0x7e, ++ 0x17, 0xf1, 0xde, 0x7c, 0x51, 0x7f, 0x0f, 0xe5, 0x03, 0xe4, 0xdd, 0x01, ++ 0xcb, 0x6b, 0x6e, 0x80, 0x4f, 0x97, 0x33, 0x67, 0x65, 0x5d, 0xfe, 0xdf, ++ 0x73, 0x24, 0x97, 0xff, 0x2a, 0xfd, 0xc9, 0xbb, 0x50, 0x3e, 0x5b, 0xf2, ++ 0xae, 0xa2, 0x52, 0xfc, 0x7c, 0xc6, 0x7d, 0xef, 0x5d, 0x35, 0xd7, 0xd1, ++ 0x2f, 0x67, 0xbb, 0xef, 0xeb, 0x89, 0x7e, 0x42, 0xa6, 0xe5, 0xcc, 0xd6, ++ 0x03, 0xb4, 0x91, 0xde, 0x39, 0xa5, 0x77, 0x0f, 0xba, 0xee, 0x20, 0x8e, ++ 0x2c, 0x22, 0xb7, 0x5a, 0xac, 0x44, 0xb4, 0x55, 0x4a, 0x37, 0xeb, 0x51, ++ 0x4f, 0x05, 0x91, 0xa1, 0xb8, 0xbf, 0xbd, 0xeb, 0xa3, 0x8c, 0xfd, 0x76, ++ 0xab, 0xe6, 0x53, 0x7f, 0x5e, 0x3a, 0x7b, 0x2d, 0x7b, 0xf1, 0x29, 0x3c, ++ 0x6f, 0xcf, 0xc1, 0xd4, 0x6f, 0xc9, 0x3d, 0xbf, 0x66, 0xfd, 0x4f, 0x41, ++ 0x62, 0x88, 0x4f, 0x8f, 0x6c, 0x8c, 0x7b, 0x22, 0xeb, 0xa7, 0xe9, 0xd3, ++ 0x85, 0xb8, 0x9e, 0xfa, 0x1a, 0xdb, 0xf8, 0x3e, 0xb9, 0x85, 0x3d, 0x43, ++ 0x7e, 0x51, 0x56, 0x6b, 0x4f, 0x85, 0x7a, 0xc6, 0x29, 0xbe, 0x77, 0x2d, ++ 0xbf, 0xfb, 0xbb, 0x06, 0xc1, 0xb4, 0xe5, 0x84, 0x28, 0x73, 0xbe, 0x19, ++ 0xd9, 0x53, 0xaf, 0xea, 0xd9, 0xcf, 0xab, 0x9b, 0xb1, 0x56, 0x8e, 0x7c, ++ 0x98, 0x11, 0xed, 0xd3, 0xb4, 0x8f, 0x76, 0x57, 0x46, 0x32, 0x56, 0x81, ++ 0x8f, 0x3a, 0xd3, 0xc6, 0xf1, 0x41, 0xd6, 0x28, 0x59, 0xce, 0xdd, 0xe3, ++ 0x97, 0xf7, 0x77, 0x98, 0x63, 0xdb, 0xf2, 0xbb, 0xa6, 0x6e, 0x33, 0xa5, ++ 0x7d, 0x24, 0xe6, 0xc8, 0x8c, 0x97, 0xf7, 0xc8, 0x6f, 0xc8, 0x55, 0x07, ++ 0x70, 0xaf, 0x2d, 0xeb, 0x0e, 0xff, 0x3f, 0x45, 0x18, 0xff, 0x64, 0x3c, ++ 0x59, 0x00, 0x00, 0x00 }; + + static const u32 bnx2_CP_b09FwData[(0x84/4) + 1] = { + 0x00000000, 0x0000001b, 0x0000000f, 0x0000000a, 0x00000008, 0x00000006, +@@ -2057,1088 +2079,1076 @@ + 0x00000002, 0x00000002, 0x00000002, 0x00000002, 0x00000002, 0x00000002, + 0x00000001, 0x00000001, 0x00000001, 0x00000000 }; + static const u32 bnx2_CP_b09FwRodata[(0x16c/4) + 1] = { +- 0x80080100, 0x80080080, 0x80080000, 0x08001800, 0x08001800, 0x08001838, +- 0x08001838, 0x0800184c, 0x0800181c, 0x08001a74, 0x08001a40, 0x08001acc, +- 0x08001acc, 0x08001b54, 0x08001a84, 0x80080240, 0x080021c4, 0x08002010, +- 0x080021ec, 0x08002284, 0x080023d4, 0x08002420, 0x08002544, 0x0800244c, +- 0x080024d0, 0x08002080, 0x080029f8, 0x0800299c, 0x0800202c, 0x0800202c, +- 0x0800202c, 0x080025b8, 0x080025b8, 0x0800202c, 0x0800202c, 0x08002874, +- 0x0800202c, 0x0800202c, 0x0800202c, 0x0800202c, 0x080028d4, 0x0800202c, +- 0x0800202c, 0x0800202c, 0x0800202c, 0x0800202c, 0x0800202c, 0x0800202c, +- 0x0800202c, 0x0800202c, 0x0800202c, 0x0800202c, 0x0800202c, 0x0800202c, +- 0x0800202c, 0x08002440, 0x0800202c, 0x0800202c, 0x08002944, 0x0800202c, +- 0x0800202c, 0x0800202c, 0x0800202c, 0x0800202c, 0x0800202c, 0x0800202c, +- 0x0800202c, 0x0800202c, 0x0800202c, 0x0800202c, 0x0800202c, 0x0800202c, +- 0x0800202c, 0x0800202c, 0x0800202c, 0x0800202c, 0x08002798, 0x0800202c, +- 0x0800202c, 0x08002700, 0x0800265c, 0x080037c0, 0x08003794, 0x08003760, +- 0x08003734, 0x08003714, 0x080036c8, 0x80080100, 0x80080080, 0x80080000, ++ 0x80080100, 0x80080080, 0x80080000, 0x08001744, 0x08001744, 0x0800177c, ++ 0x0800177c, 0x08001790, 0x08001760, 0x080019b8, 0x08001984, 0x08001a10, ++ 0x08001a10, 0x08001a98, 0x080019c8, 0x80080240, 0x08003260, 0x080031cc, ++ 0x08003288, 0x080032b0, 0x080032d8, 0x080032fc, 0x08003344, 0x08003320, ++ 0x08003368, 0x08003234, 0x0800345c, 0x0800344c, 0x080031e8, 0x080031e8, ++ 0x080031e8, 0x080033bc, 0x080033bc, 0x080031e8, 0x080031e8, 0x0800343c, ++ 0x080031e8, 0x080031e8, 0x080031e8, 0x080031e8, 0x0800342c, 0x080031e8, ++ 0x080031e8, 0x080031e8, 0x080031e8, 0x080031e8, 0x080031e8, 0x080031e8, ++ 0x080031e8, 0x080031e8, 0x080031e8, 0x080031e8, 0x080031e8, 0x080031e8, ++ 0x080031e8, 0x0800341c, 0x080031e8, 0x080031e8, 0x0800340c, 0x080031e8, ++ 0x080031e8, 0x080031e8, 0x080031e8, 0x080031e8, 0x080031e8, 0x080031e8, ++ 0x080031e8, 0x080031e8, 0x080031e8, 0x080031e8, 0x080031e8, 0x080031e8, ++ 0x080031e8, 0x080031e8, 0x080031e8, 0x080031e8, 0x080033f4, 0x080031e8, ++ 0x080031e8, 0x080033e4, 0x080033d4, 0x08003d6c, 0x08003d40, 0x08003d0c, ++ 0x08003ce0, 0x08003cc0, 0x08003c74, 0x80080100, 0x80080080, 0x80080000, + 0x80080080, 0x00000000 }; + + static struct fw_info bnx2_cp_fw_09 = { +- /* Firmware version: 4.6.15 */ ++ /* Firmware version: 4.4.23 */ + .ver_major = 0x4, +- .ver_minor = 0x6, +- .ver_fix = 0xf, ++ .ver_minor = 0x4, ++ .ver_fix = 0x17, + + .start_addr = 0x08000080, + + .text_addr = 0x08000000, +- .text_len = 0x5418, ++ .text_len = 0x5938, + .text_index = 0x0, + .gz_text = bnx2_CP_b09FwText, + .gz_text_len = sizeof(bnx2_CP_b09FwText), + +- .data_addr = 0x080055a0, ++ .data_addr = 0x08005ac0, + .data_len = 0x84, + .data_index = 0x0, + .data = bnx2_CP_b09FwData, + +- .sbss_addr = 0x08005624, ++ .sbss_addr = 0x08005b44, + .sbss_len = 0x91, + .sbss_index = 0x0, + +- .bss_addr = 0x080056b8, ++ .bss_addr = 0x08005bd8, + .bss_len = 0x19c, + .bss_index = 0x0, + +- .rodata_addr = 0x08005418, ++ .rodata_addr = 0x08005938, + .rodata_len = 0x16c, + .rodata_index = 0x0, + .rodata = bnx2_CP_b09FwRodata, + }; + + static u8 bnx2_RXP_b09FwText[] = { +- 0xec, 0x5c, 0x7d, 0x70, 0x1c, 0xe5, 0x79, 0xff, 0xbd, 0x7b, 0x7b, 0xd2, +- 0x4a, 0x3a, 0x9d, 0x56, 0xa7, 0x93, 0x7c, 0x22, 0x04, 0xef, 0xa2, 0x3d, +- 0xf9, 0xb0, 0x0c, 0xec, 0x9d, 0x4f, 0xb6, 0xa0, 0xdb, 0xb2, 0x83, 0x0d, +- 0x11, 0x21, 0x13, 0x84, 0x4d, 0x52, 0x33, 0x49, 0x27, 0x37, 0xc6, 0x18, +- 0x81, 0x4d, 0x70, 0x0d, 0x6d, 0x55, 0x86, 0x19, 0x6f, 0x2c, 0x7f, 0x01, +- 0x27, 0x9d, 0x62, 0x64, 0x63, 0xd2, 0x0e, 0x68, 0x6c, 0x59, 0x08, 0x7c, +- 0xd2, 0x61, 0x20, 0xad, 0xe8, 0x84, 0xfa, 0x26, 0xd8, 0xe0, 0x94, 0xcf, +- 0x21, 0x0c, 0xc3, 0x1f, 0xcd, 0xa0, 0x62, 0x3e, 0xcc, 0x94, 0xa1, 0x26, +- 0x38, 0xa9, 0xdd, 0xb8, 0x7e, 0xfb, 0x3c, 0x7b, 0x3a, 0x9b, 0x90, 0x26, +- 0x9d, 0xfc, 0xd1, 0xff, 0xf6, 0x99, 0xb9, 0xb9, 0xbd, 0x77, 0xdf, 0xf7, +- 0xf9, 0xfe, 0x7c, 0x3d, 0xf2, 0x5f, 0x47, 0x50, 0x8f, 0x39, 0x68, 0xa4, +- 0x4f, 0x76, 0xc3, 0xc0, 0xc6, 0xf4, 0x65, 0x4b, 0x2e, 0xa3, 0xc7, 0xee, +- 0x50, 0x53, 0x8d, 0xca, 0xeb, 0x02, 0x01, 0x04, 0x10, 0x40, 0x00, 0x01, +- 0x04, 0x10, 0x40, 0x00, 0x01, 0x04, 0x10, 0x40, 0x00, 0x01, 0x04, 0x10, +- 0x40, 0x00, 0x01, 0x04, 0x10, 0x40, 0x00, 0x01, 0x04, 0x10, 0x40, 0x00, +- 0x01, 0x04, 0x10, 0x40, 0x00, 0x01, 0x04, 0x10, 0x40, 0x00, 0x01, 0x04, +- 0x10, 0x40, 0x00, 0x01, 0x04, 0x10, 0x40, 0x00, 0x01, 0x04, 0x10, 0x40, +- 0x00, 0x01, 0x04, 0x10, 0x40, 0x00, 0x01, 0xfc, 0x7f, 0x40, 0x08, 0xd0, +- 0xf9, 0xbb, 0x71, 0xee, 0x03, 0x4d, 0x71, 0xdc, 0x7b, 0xaf, 0xb6, 0xa0, +- 0x85, 0x9c, 0x99, 0x7b, 0x6f, 0xb1, 0x00, 0xb7, 0xd8, 0x65, 0x2c, 0xc3, +- 0x7f, 0x4b, 0x2f, 0xae, 0x82, 0xd7, 0xbf, 0xea, 0x9c, 0x79, 0xec, 0xf9, +- 0xa5, 0xe6, 0x89, 0xb1, 0x10, 0x34, 0xdd, 0x79, 0x27, 0xad, 0x77, 0x42, +- 0xbb, 0x90, 0xce, 0xfc, 0xfd, 0x82, 0x95, 0x31, 0x44, 0xab, 0xb8, 0xe0, +- 0x29, 0x8e, 0x94, 0xfb, 0x6d, 0x89, 0x17, 0x6d, 0x4f, 0x2c, 0xcb, 0xc2, +- 0xd3, 0x9c, 0x19, 0x51, 0x37, 0x74, 0x56, 0x1a, 0xe1, 0x0a, 0xe5, 0x35, +- 0x45, 0x05, 0xaa, 0xa5, 0xe1, 0xd6, 0xf1, 0x7a, 0xac, 0x1d, 0x6b, 0xc0, +- 0x9a, 0xb1, 0x04, 0x6e, 0x2b, 0x42, 0x0f, 0x39, 0x1a, 0x66, 0x43, 0x33, +- 0x22, 0x34, 0x85, 0x5c, 0xd8, 0x39, 0x75, 0xc3, 0xde, 0xfc, 0x59, 0xe9, +- 0xfa, 0x7f, 0x63, 0x52, 0xbe, 0x61, 0xdc, 0x7f, 0x0f, 0x45, 0x75, 0x0e, +- 0xd3, 0x33, 0xef, 0x3b, 0x75, 0xc3, 0xbe, 0xe2, 0x71, 0xf9, 0xfc, 0x82, +- 0x38, 0x0e, 0x95, 0x74, 0x3c, 0x55, 0xda, 0x4f, 0x3c, 0x98, 0x9e, 0x07, +- 0xcd, 0x53, 0x1d, 0x0f, 0x5b, 0xb3, 0x61, 0x4c, 0x8c, 0x9c, 0x95, 0x21, +- 0xcb, 0x34, 0xa0, 0x58, 0xfa, 0x0b, 0xa0, 0x7d, 0x05, 0xda, 0x57, 0x08, +- 0x63, 0xef, 0x58, 0x29, 0x86, 0xfa, 0x04, 0x9e, 0x5f, 0xc0, 0xe7, 0xf9, +- 0x2c, 0xe3, 0x78, 0x3b, 0x5a, 0x3d, 0x5f, 0x43, 0xe7, 0x8f, 0x64, 0x81, +- 0xf1, 0x91, 0x3e, 0x3a, 0x2a, 0x31, 0x68, 0xd7, 0x62, 0xb5, 0x0e, 0xaf, +- 0xce, 0x61, 0x5c, 0x55, 0x3c, 0x9e, 0x30, 0xa6, 0x8e, 0x34, 0x55, 0xf0, +- 0x40, 0x68, 0x16, 0xbc, 0xda, 0x2f, 0xbd, 0x3f, 0x5e, 0xac, 0xbe, 0xdf, +- 0x41, 0x74, 0x34, 0xd2, 0xc3, 0x06, 0xfc, 0x73, 0xa9, 0x1f, 0xff, 0x50, +- 0xca, 0xe1, 0xd9, 0x52, 0x1f, 0xd1, 0xbd, 0x87, 0xe8, 0xae, 0xc7, 0x3f, +- 0x96, 0xd6, 0xe0, 0xc7, 0xa5, 0xef, 0xe2, 0x99, 0xd2, 0x2a, 0x3c, 0x5d, +- 0xba, 0x09, 0x07, 0x4b, 0x1e, 0xc2, 0xdd, 0x8c, 0x2f, 0x25, 0x3e, 0xcb, +- 0xd7, 0x11, 0x1f, 0x5b, 0x30, 0x5b, 0x64, 0x79, 0x24, 0x46, 0x6c, 0x73, +- 0x0c, 0x58, 0x90, 0xa8, 0x81, 0xc0, 0x6a, 0xdb, 0x7c, 0x0a, 0xb8, 0x0d, +- 0x6e, 0xdc, 0x3c, 0xc1, 0x5a, 0x7a, 0x62, 0xc4, 0x40, 0x98, 0xf8, 0xb5, +- 0xd2, 0x6d, 0xd8, 0xaa, 0xf7, 0xa1, 0xde, 0x1a, 0xc2, 0x03, 0xbe, 0x8d, +- 0xa1, 0x45, 0x9c, 0x7f, 0x45, 0x7e, 0x48, 0xe0, 0xc1, 0x24, 0x34, 0x41, +- 0xcf, 0x5d, 0xc5, 0xbf, 0x6b, 0xa9, 0xd8, 0x8c, 0x78, 0x28, 0x10, 0x5f, +- 0x05, 0xe2, 0xa3, 0x40, 0xbc, 0x15, 0x88, 0x97, 0x02, 0xf1, 0x57, 0x20, +- 0x7e, 0x0a, 0xc4, 0x4f, 0x81, 0xf8, 0x29, 0x10, 0xaf, 0x05, 0xd6, 0xf9, +- 0x00, 0xc9, 0x52, 0xb1, 0x71, 0xab, 0x63, 0x63, 0xac, 0xd4, 0x26, 0xf6, +- 0xee, 0x56, 0xc5, 0x73, 0xc3, 0x06, 0xe6, 0x3b, 0x88, 0x3c, 0xbd, 0xc4, +- 0x2a, 0x5f, 0x15, 0xea, 0x9a, 0x49, 0xc0, 0x4d, 0xcf, 0x83, 0x8d, 0x89, +- 0x92, 0x2a, 0xa6, 0x87, 0xa5, 0x5c, 0x69, 0xbb, 0x68, 0x72, 0xcc, 0x9e, +- 0x8d, 0x8a, 0xd5, 0xff, 0xba, 0x68, 0xc4, 0x2f, 0x47, 0x7a, 0x31, 0xd6, +- 0xec, 0xe2, 0x70, 0xd6, 0xc0, 0xb2, 0x8c, 0x82, 0x5c, 0xdc, 0xc3, 0xb6, +- 0xac, 0x69, 0x7b, 0x18, 0x45, 0x39, 0xce, 0xe7, 0x34, 0xd2, 0xb5, 0x87, +- 0x64, 0xb7, 0x86, 0xc9, 0x11, 0x17, 0x35, 0xe9, 0x1a, 0x94, 0xfb, 0x58, +- 0x7f, 0x2a, 0xc9, 0xb4, 0x0f, 0xf5, 0xb1, 0x18, 0x1a, 0xac, 0x4b, 0xd0, +- 0x10, 0xe3, 0x35, 0x88, 0x56, 0xd2, 0xd5, 0x3c, 0xe7, 0x02, 0xf1, 0xf9, +- 0xee, 0x28, 0x3e, 0x1d, 0xd5, 0x50, 0xda, 0xa9, 0xe2, 0x1b, 0x19, 0x29, +- 0xff, 0x2a, 0xa3, 0xf6, 0x7f, 0x2a, 0x1c, 0x4c, 0x95, 0x54, 0x7c, 0x9e, +- 0x4f, 0xc3, 0x6b, 0xd6, 0xf0, 0x9f, 0x79, 0x0f, 0x21, 0xc2, 0x3b, 0x40, +- 0x78, 0x6b, 0x17, 0xa7, 0x30, 0x1b, 0x67, 0x71, 0xfa, 0xb0, 0x31, 0xdf, +- 0xb1, 0x63, 0xa3, 0x52, 0x03, 0xa3, 0x06, 0x64, 0xff, 0x2c, 0x36, 0xe5, +- 0x3b, 0x8e, 0x6e, 0x52, 0xb6, 0xe0, 0xe2, 0x5a, 0x0d, 0x9b, 0x87, 0x79, +- 0x6d, 0x39, 0xca, 0x45, 0x41, 0xfe, 0xf0, 0xc7, 0xea, 0x6b, 0x26, 0x42, +- 0x7e, 0x65, 0xfc, 0xf1, 0x7a, 0x4e, 0x34, 0xa2, 0xde, 0x34, 0xca, 0x58, +- 0x1f, 0xe7, 0xf3, 0x39, 0xe5, 0x5d, 0xe9, 0xc6, 0x99, 0x0f, 0xcd, 0x0b, +- 0x91, 0x6e, 0x6e, 0xc9, 0x66, 0xb1, 0x26, 0xdf, 0xa1, 0xaf, 0x51, 0x48, +- 0xdb, 0x6a, 0xc5, 0xc6, 0x71, 0x07, 0xe9, 0xd1, 0x61, 0x81, 0x91, 0x4e, +- 0xb6, 0x31, 0xd2, 0x76, 0xd1, 0x8f, 0x09, 0xc3, 0x50, 0x2a, 0x31, 0xf1, +- 0x58, 0x36, 0x89, 0xb3, 0x0f, 0xf1, 0x6f, 0x15, 0x3f, 0x5b, 0x9a, 0xc4, +- 0xc7, 0xfb, 0x4a, 0x73, 0x71, 0xfb, 0x68, 0xa4, 0xb2, 0xef, 0x1a, 0xa2, +- 0xc9, 0x32, 0x32, 0xae, 0xc9, 0x7b, 0x47, 0x3b, 0x6b, 0xe9, 0x77, 0xc5, +- 0xd6, 0xfd, 0xf9, 0x0e, 0xbb, 0x5f, 0xd1, 0x50, 0x4e, 0x44, 0x48, 0xf7, +- 0xd0, 0xea, 0x08, 0xff, 0x25, 0x43, 0x67, 0xb0, 0x22, 0x63, 0x4e, 0xf2, +- 0xdf, 0x80, 0x25, 0x93, 0x15, 0x9a, 0xc9, 0xa2, 0x8d, 0x03, 0x25, 0x1b, +- 0x77, 0xe4, 0x3b, 0xdc, 0x95, 0x62, 0x16, 0x68, 0x5f, 0x98, 0x9b, 0x54, +- 0x7e, 0x21, 0xbd, 0x56, 0xa6, 0xb3, 0x10, 0x93, 0xb1, 0x8e, 0x81, 0x49, +- 0xc5, 0xdc, 0xd3, 0xaf, 0x48, 0xf9, 0xab, 0xb4, 0x82, 0xaf, 0x65, 0xb2, +- 0x98, 0xd5, 0x75, 0xdc, 0x9c, 0xd1, 0xbc, 0x16, 0xe2, 0x71, 0xc3, 0x12, +- 0x0d, 0x17, 0xed, 0x74, 0xf1, 0xf6, 0xe2, 0x9f, 0xa3, 0xbc, 0x82, 0x75, +- 0xcf, 0x7c, 0xb1, 0x1c, 0x09, 0xc4, 0xac, 0x3a, 0xc4, 0xf6, 0x86, 0x31, +- 0x6f, 0xe7, 0x59, 0x99, 0xb0, 0x78, 0xdd, 0x9a, 0x3c, 0xa5, 0xb0, 0x0c, +- 0x61, 0xb4, 0xee, 0xbd, 0x82, 0x72, 0x8a, 0x99, 0x02, 0xbe, 0x16, 0xe7, +- 0xbd, 0x35, 0x56, 0x55, 0x96, 0x08, 0x76, 0xef, 0xac, 0xc8, 0xff, 0x68, +- 0xb6, 0x07, 0x2f, 0x15, 0xb0, 0xaf, 0x0d, 0x3f, 0xc0, 0xc8, 0x12, 0xce, +- 0x4f, 0x8c, 0x63, 0x88, 0x64, 0xff, 0xc1, 0x89, 0x70, 0xa6, 0x6a, 0xe3, +- 0xea, 0x39, 0x81, 0x6f, 0x5e, 0x29, 0xf0, 0x6a, 0x7a, 0x5a, 0x8e, 0xb5, +- 0x32, 0xbf, 0x0f, 0x37, 0x56, 0xfe, 0x16, 0xae, 0xee, 0x94, 0x8b, 0x36, +- 0xa2, 0x55, 0xdd, 0xc7, 0x38, 0x2e, 0x69, 0x25, 0xfd, 0xa5, 0x66, 0xf1, +- 0x5f, 0x11, 0xd4, 0xb3, 0x9d, 0xef, 0x96, 0x46, 0x4b, 0x85, 0xe6, 0xfd, +- 0x44, 0xb3, 0x63, 0x48, 0xc5, 0xe6, 0x7c, 0xc7, 0xa9, 0xf7, 0x94, 0xef, +- 0xcb, 0xd9, 0xf9, 0x4c, 0xa7, 0xc3, 0x3e, 0xa6, 0x08, 0xfc, 0x54, 0x35, +- 0x67, 0x72, 0x48, 0x60, 0xb2, 0x04, 0xaf, 0xdd, 0xd1, 0x29, 0xfe, 0xe3, +- 0x94, 0x07, 0x0c, 0xd1, 0xf9, 0xb0, 0x8d, 0x85, 0x43, 0xdf, 0x85, 0xb5, +- 0xcb, 0xc1, 0x4c, 0xc1, 0xc6, 0x54, 0x41, 0xca, 0xed, 0xb6, 0x94, 0xef, +- 0xda, 0xe6, 0x86, 0xe3, 0x21, 0xb8, 0x97, 0x2f, 0xed, 0x4a, 0xd5, 0x86, +- 0x54, 0xd6, 0x4d, 0xee, 0x75, 0x91, 0x5c, 0xb5, 0x5f, 0xf4, 0xe2, 0x89, +- 0x92, 0x81, 0x62, 0x29, 0x85, 0x27, 0x4b, 0xac, 0x7f, 0x8b, 0xbe, 0x17, +- 0x51, 0x7c, 0x66, 0x29, 0xb7, 0x30, 0xbf, 0x3a, 0xc6, 0x17, 0xd8, 0x98, +- 0x2c, 0x28, 0x08, 0x91, 0xce, 0x73, 0x3a, 0xed, 0x2f, 0x9c, 0x25, 0xdb, +- 0x69, 0xe8, 0xf8, 0xa1, 0x8b, 0xdb, 0xed, 0x16, 0x18, 0x37, 0x5a, 0x18, +- 0x2f, 0x68, 0x94, 0xbb, 0x55, 0xf4, 0xe6, 0xc7, 0x31, 0xaf, 0x39, 0x4e, +- 0xb1, 0x26, 0xb0, 0x2a, 0x13, 0x01, 0x56, 0xf2, 0xbb, 0x08, 0xda, 0xad, +- 0x32, 0xda, 0x63, 0x8d, 0x98, 0xbf, 0xf0, 0x9f, 0x30, 0xdb, 0x12, 0x25, +- 0x1d, 0xd7, 0x93, 0x1e, 0x04, 0x54, 0xb2, 0x53, 0x9b, 0x65, 0x11, 0x4e, +- 0x01, 0x2b, 0x49, 0x7b, 0x29, 0x7e, 0x13, 0x24, 0x7b, 0x78, 0x69, 0x1c, +- 0x8f, 0x13, 0xff, 0xa5, 0xbc, 0x94, 0x91, 0xac, 0xb9, 0x61, 0x3b, 0xe5, +- 0x84, 0xe9, 0x62, 0x0f, 0x4a, 0xa5, 0x6f, 0x62, 0x6a, 0x84, 0xf8, 0xcc, +- 0x3b, 0xc4, 0x93, 0xaa, 0x17, 0x85, 0xd9, 0xb7, 0x5a, 0x64, 0xf1, 0x24, +- 0xf9, 0xce, 0x44, 0xc1, 0x34, 0x8e, 0x93, 0x9f, 0xbd, 0x60, 0x37, 0x10, +- 0x9f, 0x2e, 0xe1, 0x32, 0xf0, 0x5c, 0xbe, 0x00, 0xab, 0x85, 0xed, 0x15, +- 0xc1, 0xfd, 0x3b, 0xb3, 0x84, 0x13, 0x83, 0x75, 0xf0, 0xa0, 0x2e, 0xf1, +- 0x4e, 0x6c, 0xb5, 0x87, 0x22, 0x55, 0x1f, 0xaf, 0x27, 0x9a, 0x7d, 0xdd, +- 0x36, 0x42, 0xc3, 0x3d, 0x84, 0x97, 0xfc, 0x15, 0xb7, 0x92, 0xbf, 0x7a, +- 0xb8, 0x9c, 0xe2, 0x21, 0xea, 0xec, 0x49, 0xbf, 0x36, 0xe4, 0xc9, 0x5a, +- 0xcb, 0xea, 0xff, 0x48, 0x6c, 0xc2, 0x27, 0x69, 0xb6, 0x83, 0x4a, 0xf2, +- 0xea, 0x78, 0x39, 0x3d, 0x82, 0x57, 0x8b, 0x7f, 0x82, 0x5c, 0xb3, 0x99, +- 0xda, 0x2c, 0xd6, 0x61, 0x66, 0xe4, 0x0a, 0xe0, 0xcf, 0xd9, 0x7e, 0x02, +- 0xf3, 0xad, 0x75, 0x38, 0x34, 0x76, 0x2f, 0x8e, 0x8c, 0xd6, 0xe3, 0x39, +- 0x2b, 0x86, 0xf6, 0x89, 0x0a, 0x9d, 0x6b, 0xe6, 0x72, 0x93, 0x9e, 0xa6, +- 0xe0, 0x6b, 0xe3, 0x98, 0x14, 0xb8, 0x3e, 0xb3, 0x0e, 0x39, 0xdf, 0xcf, +- 0x3d, 0xac, 0xa1, 0xdc, 0x96, 0xcf, 0xbb, 0x14, 0xd7, 0x75, 0xd8, 0xd9, +- 0x0c, 0x71, 0x0b, 0xd5, 0x93, 0x3b, 0x29, 0x5e, 0xef, 0x54, 0x62, 0x70, +- 0x13, 0x2e, 0xd9, 0x55, 0xe0, 0x22, 0xcb, 0xc0, 0x9e, 0x22, 0x70, 0x77, +- 0x51, 0xc5, 0xdf, 0x14, 0x2f, 0x45, 0xb9, 0x8d, 0xcf, 0x2e, 0x40, 0x79, +- 0x1e, 0x7f, 0x87, 0x31, 0x16, 0x33, 0x13, 0x20, 0x9d, 0xed, 0x2f, 0xa8, +- 0xf8, 0xb1, 0xbd, 0xeb, 0xec, 0xd8, 0x0a, 0x53, 0xcf, 0x51, 0xac, 0x85, +- 0xac, 0xd3, 0xe4, 0x67, 0xfc, 0x0c, 0x7c, 0x3f, 0xff, 0x99, 0xfc, 0xb9, +- 0x4f, 0x53, 0xc5, 0x6d, 0xf9, 0x8e, 0x81, 0x8f, 0x94, 0x8f, 0xe5, 0xbf, +- 0x85, 0x19, 0xff, 0x77, 0xa2, 0x15, 0x7f, 0xdd, 0xc3, 0x79, 0xc4, 0xad, +- 0xf8, 0xed, 0xbc, 0x2f, 0xf8, 0x6d, 0xc5, 0x3f, 0x47, 0xb2, 0xcc, 0x47, +- 0x35, 0xc6, 0x62, 0xb8, 0x68, 0x22, 0x89, 0xba, 0x9d, 0xfc, 0x9b, 0xd7, +- 0x05, 0x2e, 0xee, 0xe6, 0xf8, 0x4a, 0x42, 0xd9, 0x7b, 0x2d, 0xe1, 0x63, +- 0xd9, 0xab, 0xb9, 0xe2, 0x7b, 0x73, 0xf8, 0xcf, 0xe7, 0x98, 0x76, 0xc2, +- 0xb7, 0x74, 0x29, 0x3f, 0xf3, 0x99, 0x3a, 0xfc, 0x7a, 0xaf, 0x69, 0x97, +- 0x95, 0xa5, 0x44, 0x93, 0x63, 0x92, 0x63, 0xf3, 0x2f, 0xe6, 0xce, 0x24, +- 0xc8, 0xce, 0xd3, 0xb2, 0xbc, 0x8a, 0xf1, 0x55, 0xcf, 0x27, 0x11, 0x3a, +- 0x47, 0x57, 0xc5, 0xea, 0xec, 0x97, 0xe9, 0xda, 0x94, 0xf7, 0x5b, 0xd1, +- 0xb0, 0xd0, 0x22, 0x3b, 0xb5, 0xa1, 0x91, 0xe2, 0x3a, 0x62, 0xad, 0x92, +- 0x91, 0x6f, 0xb3, 0x8f, 0x6a, 0x5e, 0xd8, 0xf9, 0x0a, 0x4a, 0x23, 0xcf, +- 0x93, 0x7d, 0xa3, 0xec, 0x8b, 0x1b, 0x3e, 0x12, 0x5f, 0xc1, 0xf4, 0x98, +- 0x88, 0xb2, 0xac, 0xab, 0x28, 0xb6, 0xe7, 0x53, 0x7d, 0xf8, 0xe0, 0xe1, +- 0xbb, 0xe4, 0x58, 0x9f, 0x8e, 0x17, 0xb3, 0x49, 0x5a, 0x67, 0x5f, 0xb2, +- 0xf1, 0x4c, 0x5e, 0xc3, 0xee, 0xe1, 0x84, 0xef, 0xc7, 0xf7, 0x74, 0xd6, +- 0x9d, 0x2a, 0x2b, 0x36, 0x9e, 0x25, 0x3f, 0x3c, 0x58, 0x60, 0x1d, 0xab, +- 0xb8, 0x38, 0xf3, 0x75, 0x59, 0xd3, 0xc6, 0xbe, 0x1d, 0xa1, 0x33, 0x3a, +- 0xe1, 0x8e, 0x42, 0xb7, 0x96, 0xcb, 0x37, 0x56, 0xf0, 0x73, 0x03, 0xad, +- 0xb5, 0xd1, 0xf7, 0x12, 0xd9, 0xf8, 0x3b, 0x7c, 0xe8, 0xff, 0x1b, 0x1f, +- 0xf4, 0x1d, 0xa3, 0x75, 0x90, 0xbf, 0xcc, 0x88, 0xd5, 0x95, 0xfe, 0x46, +- 0x53, 0xad, 0x19, 0xb1, 0xc6, 0xef, 0x69, 0xfc, 0x34, 0x4e, 0x38, 0x7a, +- 0xb1, 0x77, 0x54, 0xca, 0x2d, 0x76, 0x3b, 0x5c, 0x3d, 0x86, 0x2d, 0x16, +- 0xc5, 0xeb, 0x28, 0x9f, 0x91, 0x32, 0x95, 0x5e, 0xd8, 0xa3, 0x8a, 0x16, +- 0xca, 0x99, 0x9e, 0x58, 0x9b, 0x35, 0xc4, 0x9d, 0xa3, 0x2a, 0xf2, 0x85, +- 0x0b, 0x28, 0x27, 0x4b, 0xf9, 0x64, 0x1a, 0xee, 0x60, 0xba, 0x01, 0x2f, +- 0x8f, 0xe9, 0x14, 0x3b, 0x67, 0xe5, 0xf2, 0x64, 0x2f, 0x4a, 0x84, 0xe7, +- 0xd3, 0x74, 0x57, 0xea, 0xb0, 0x88, 0x60, 0x2c, 0x1e, 0xc1, 0x9e, 0x42, +- 0x1c, 0x87, 0xc7, 0x23, 0xd8, 0x46, 0xfe, 0xf7, 0xd3, 0x2c, 0xd3, 0x8c, +- 0x60, 0x73, 0x89, 0x7b, 0x8d, 0x10, 0xe9, 0xc0, 0x13, 0xef, 0xf9, 0x6b, +- 0x0d, 0x58, 0x3e, 0xc6, 0x7b, 0xcf, 0xca, 0x76, 0xcb, 0xd2, 0xdb, 0x43, +- 0xd5, 0x7d, 0xef, 0x50, 0x1f, 0x63, 0x50, 0xef, 0x72, 0x21, 0xe5, 0xaa, +- 0x04, 0xf5, 0x2a, 0x71, 0xea, 0x55, 0xac, 0xb9, 0xfe, 0xcb, 0xa4, 0x48, +- 0x93, 0xf2, 0x19, 0xca, 0x53, 0x6f, 0xd2, 0xe7, 0xa4, 0x4d, 0xe5, 0x96, +- 0x64, 0xbc, 0x78, 0x98, 0x65, 0xf4, 0x84, 0xbd, 0x84, 0x3a, 0xce, 0x69, +- 0xd3, 0x70, 0x95, 0x5f, 0x50, 0x9f, 0x65, 0xa0, 0x63, 0x9a, 0x79, 0x50, +- 0xb1, 0xb5, 0x00, 0x0c, 0x16, 0xe0, 0x1d, 0xa6, 0xd8, 0x6e, 0x99, 0x88, +- 0x22, 0x36, 0xa1, 0x23, 0x3c, 0x91, 0xa2, 0xbd, 0x1a, 0xe2, 0xf4, 0xdb, +- 0xa3, 0xbe, 0xab, 0xc9, 0x69, 0x13, 0x8b, 0x76, 0x9f, 0x91, 0x0f, 0x52, +- 0xac, 0xdd, 0x91, 0x34, 0x7b, 0x6f, 0x14, 0x70, 0x53, 0x43, 0x52, 0xd6, +- 0xa6, 0x6b, 0xa9, 0x7e, 0xcb, 0x43, 0x71, 0x92, 0x3d, 0xea, 0xc8, 0x4d, +- 0xaf, 0x76, 0x5b, 0xf6, 0xab, 0x20, 0xbc, 0x25, 0x3e, 0xc3, 0xeb, 0x9e, +- 0xf8, 0xac, 0xdb, 0xda, 0xf3, 0x16, 0x3a, 0xb1, 0x78, 0x42, 0x15, 0xbf, +- 0x1c, 0x5a, 0x84, 0xcc, 0x34, 0xf4, 0x1a, 0xe2, 0xeb, 0xc3, 0x29, 0xe2, +- 0xbb, 0x40, 0xb2, 0x14, 0x48, 0x96, 0x02, 0xc9, 0x42, 0x7a, 0x39, 0xe8, +- 0xf7, 0x6d, 0x2c, 0x6b, 0x8a, 0xea, 0xef, 0x3b, 0x7e, 0x6f, 0x79, 0xb0, +- 0xc4, 0x72, 0x98, 0xae, 0x07, 0x96, 0x9b, 0xe5, 0x94, 0xf2, 0x2d, 0x9b, +- 0xe5, 0x31, 0x0d, 0x4f, 0x21, 0x6b, 0x4d, 0x1b, 0x48, 0x4d, 0x57, 0xf5, +- 0x21, 0xe5, 0xe7, 0x36, 0xeb, 0x83, 0x65, 0x94, 0xf2, 0x69, 0x92, 0x69, +- 0x2b, 0xc9, 0x38, 0x58, 0x90, 0x87, 0x6a, 0x2c, 0xcb, 0x98, 0x20, 0xde, +- 0x62, 0x24, 0x53, 0x7c, 0x42, 0x23, 0x59, 0x3b, 0xa1, 0x92, 0xac, 0xa1, +- 0x09, 0xe8, 0x0a, 0xeb, 0x69, 0xfa, 0xff, 0xe2, 0x87, 0xfb, 0x6a, 0x4f, +- 0x5c, 0x43, 0xfd, 0xb4, 0x4a, 0xfb, 0x07, 0xc9, 0x77, 0x72, 0x2a, 0x8c, +- 0x5a, 0x4b, 0xa1, 0x3c, 0xac, 0xe1, 0xf1, 0xf1, 0x06, 0x4c, 0x90, 0xdd, +- 0xc7, 0xc6, 0xa1, 0x87, 0xe9, 0xfd, 0xd6, 0x73, 0xfe, 0x04, 0xf2, 0xa7, +- 0x0d, 0x18, 0xa7, 0xfc, 0xf3, 0x40, 0x3e, 0x26, 0x26, 0x46, 0x54, 0x6c, +- 0x29, 0x9c, 0x20, 0xd9, 0x24, 0xe5, 0xd8, 0xcd, 0x09, 0xda, 0x22, 0x36, +- 0xdb, 0x66, 0x0f, 0x70, 0x05, 0xf9, 0x5a, 0x08, 0x6b, 0x2d, 0xb8, 0xdb, +- 0xed, 0x2b, 0x30, 0xdb, 0x07, 0x63, 0x87, 0xed, 0xe9, 0x35, 0x30, 0x8f, +- 0x5e, 0x43, 0xa3, 0xc0, 0xe5, 0x24, 0xc7, 0x80, 0xe5, 0x6d, 0xa0, 0x84, +- 0x44, 0xf9, 0xdb, 0xec, 0x3f, 0x42, 0x36, 0x28, 0x52, 0x5d, 0x2b, 0x52, +- 0x0f, 0x78, 0x60, 0xf4, 0x8c, 0xbc, 0x3d, 0x6d, 0xba, 0x49, 0x5a, 0x0b, +- 0x0f, 0x69, 0xd8, 0x5f, 0xd2, 0x28, 0x5e, 0x4c, 0x1b, 0xe0, 0x98, 0x87, +- 0x56, 0x4b, 0x3d, 0xda, 0x47, 0xd6, 0xa3, 0xd4, 0x0b, 0x6b, 0xa0, 0x3e, +- 0x19, 0x57, 0x8f, 0x08, 0xec, 0xa7, 0xf8, 0x9d, 0x5a, 0x64, 0x1e, 0x5d, +- 0x0d, 0xaf, 0xdc, 0x0e, 0x73, 0xa0, 0x96, 0x18, 0xf9, 0x74, 0xa8, 0x86, +- 0xfa, 0xc2, 0x4e, 0xfb, 0x35, 0x98, 0xfa, 0xfe, 0xd0, 0xaf, 0xe4, 0x64, +- 0x1c, 0x17, 0x84, 0x71, 0x52, 0x1a, 0xdf, 0xe2, 0x33, 0x2c, 0xf7, 0x06, +- 0x6c, 0xcf, 0x42, 0x0b, 0x3b, 0x6a, 0x7a, 0x7f, 0x1e, 0x38, 0x96, 0x37, +- 0x30, 0xb9, 0xa8, 0x0e, 0x68, 0xee, 0xe8, 0xb9, 0x03, 0xde, 0xaa, 0xb0, +- 0xdf, 0xe7, 0x6a, 0xe9, 0x3c, 0xf9, 0xc8, 0x7a, 0x21, 0xf0, 0x24, 0xd1, +- 0x5a, 0x30, 0xc5, 0x7d, 0x89, 0x9a, 0x5e, 0x48, 0x79, 0x76, 0x5b, 0x49, +- 0xa0, 0xd6, 0x32, 0xf5, 0x59, 0xb0, 0x6e, 0x74, 0xd2, 0xe9, 0x19, 0x89, +- 0x66, 0x96, 0xdd, 0xcb, 0x91, 0x9c, 0xab, 0xb6, 0x12, 0xff, 0x6b, 0x48, +- 0xa6, 0xdb, 0x2d, 0xaf, 0x87, 0xb0, 0x52, 0xed, 0x31, 0x13, 0x1f, 0x90, +- 0xec, 0x6b, 0x29, 0x47, 0x8c, 0x95, 0x86, 0x9b, 0x38, 0x1f, 0x4c, 0x94, +- 0x78, 0x4e, 0xea, 0xc1, 0xd5, 0xf9, 0x6a, 0x2c, 0xb0, 0xdd, 0xd9, 0xe6, +- 0x17, 0xfa, 0xf5, 0xfb, 0xa0, 0xef, 0x23, 0xdc, 0x3f, 0xf5, 0x60, 0xb4, +- 0x53, 0xa1, 0xde, 0x5c, 0xca, 0x15, 0x96, 0x39, 0xc2, 0xf9, 0x99, 0x7c, +- 0xdd, 0xdd, 0x67, 0x37, 0x51, 0x6c, 0xc2, 0x7b, 0xc2, 0x36, 0x50, 0xe3, +- 0xb0, 0x4f, 0x34, 0x90, 0x8f, 0x47, 0xb0, 0x9d, 0x7c, 0x44, 0xb3, 0xac, +- 0x14, 0x35, 0x53, 0xfa, 0xb1, 0x2c, 0xed, 0x2d, 0xc1, 0x28, 0xd9, 0xf5, +- 0x98, 0x6d, 0x55, 0xd1, 0xec, 0x1c, 0x92, 0x2d, 0xd6, 0x7f, 0x10, 0x7d, +- 0x4b, 0xbf, 0x1b, 0xab, 0x61, 0xb4, 0x1a, 0x68, 0x70, 0xf8, 0xfd, 0x69, +- 0x39, 0xdb, 0x1c, 0x21, 0xff, 0xe2, 0x3d, 0x96, 0x77, 0x10, 0xbf, 0x96, +- 0x88, 0xf1, 0x5e, 0x97, 0xf2, 0x27, 0xc4, 0x0c, 0xd1, 0x42, 0x0b, 0xc7, +- 0x2d, 0xf7, 0xe7, 0xd6, 0xd1, 0x43, 0x54, 0x53, 0x8c, 0x16, 0x50, 0x2e, +- 0x55, 0x11, 0x72, 0x2c, 0x7d, 0x1f, 0x8e, 0x92, 0xcd, 0xd9, 0x45, 0x2e, +- 0x12, 0xd7, 0xed, 0xba, 0x50, 0xf4, 0xee, 0x92, 0xb2, 0x33, 0x0d, 0x9a, +- 0xc2, 0x92, 0xc6, 0x4b, 0xb4, 0xba, 0x85, 0x7c, 0xbf, 0xd1, 0x89, 0x88, +- 0xe2, 0x2e, 0xe8, 0x07, 0x6c, 0x8d, 0xf2, 0xae, 0x94, 0xdb, 0xd2, 0x06, +- 0xa6, 0x6d, 0xea, 0xc7, 0x5b, 0xc3, 0x68, 0xb6, 0xa0, 0xeb, 0x8e, 0x35, +- 0xf0, 0x14, 0xee, 0x26, 0x3e, 0x11, 0x99, 0x4f, 0x35, 0x90, 0xd6, 0xc4, +- 0x5e, 0xbb, 0x0e, 0xee, 0x4d, 0x02, 0x11, 0x27, 0x4e, 0xbc, 0xd5, 0x20, +- 0xe7, 0x3f, 0xb3, 0x8c, 0x70, 0xdf, 0xb7, 0x7f, 0x44, 0xf2, 0x8a, 0xf9, +- 0xf5, 0x0e, 0xaf, 0x59, 0x76, 0x11, 0xeb, 0xa9, 0xe7, 0xa7, 0x25, 0x7a, +- 0xbf, 0x85, 0xde, 0x3f, 0x44, 0xb8, 0x73, 0x31, 0x7f, 0xd6, 0x6b, 0x6a, +- 0x77, 0xac, 0xf2, 0x73, 0x78, 0x90, 0x64, 0xe0, 0xfc, 0xcd, 0x6b, 0xcc, +- 0xf3, 0x22, 0xe6, 0x99, 0x6a, 0x37, 0xfb, 0x95, 0x8d, 0x8f, 0xf2, 0x77, +- 0x73, 0x0f, 0xef, 0xee, 0xb0, 0x21, 0x26, 0xec, 0x3d, 0x28, 0xeb, 0x68, +- 0x8a, 0x3a, 0x56, 0xff, 0x34, 0xa0, 0x44, 0x9c, 0x51, 0x14, 0x9b, 0x81, +- 0x87, 0x0a, 0x96, 0xb7, 0x51, 0x31, 0x07, 0xe2, 0xd4, 0xf7, 0x9e, 0xfc, +- 0xa1, 0x8a, 0x9d, 0x9d, 0x65, 0x33, 0x46, 0x46, 0x8f, 0x3a, 0x51, 0xf1, +- 0xe2, 0x2e, 0x05, 0x0b, 0x96, 0xa8, 0x78, 0x8b, 0x72, 0xc8, 0x36, 0x9a, +- 0x45, 0xc2, 0x96, 0xda, 0x54, 0xe9, 0x89, 0x7f, 0x5f, 0x3c, 0x9a, 0xa4, +- 0xb1, 0x6a, 0x4c, 0x5a, 0x7d, 0x07, 0xf0, 0xa8, 0x74, 0x9b, 0xd9, 0x16, +- 0x11, 0xca, 0xc3, 0xe7, 0xf2, 0x50, 0x6a, 0x8a, 0xf0, 0x0f, 0x76, 0xbf, +- 0xeb, 0xfb, 0x0c, 0xd9, 0xd2, 0x7d, 0x23, 0x0f, 0xd1, 0x94, 0x71, 0x30, +- 0xdb, 0xcc, 0x76, 0xe1, 0xf9, 0x99, 0x94, 0x37, 0x4c, 0xc3, 0x47, 0x8b, +- 0x8a, 0xc5, 0x19, 0x34, 0x29, 0x8e, 0x75, 0x6a, 0x2f, 0xf1, 0xdc, 0xee, +- 0x34, 0xe1, 0x74, 0x0b, 0xe7, 0xc4, 0xa8, 0xf8, 0xd9, 0xa8, 0xd9, 0x43, +- 0x3d, 0xee, 0xaa, 0x8d, 0x30, 0xfb, 0xee, 0x11, 0xd4, 0x97, 0x11, 0xef, +- 0x56, 0x92, 0xf8, 0xb4, 0x55, 0xc4, 0x93, 0x65, 0x33, 0x8e, 0x2a, 0xbf, +- 0x67, 0x65, 0xcc, 0xb2, 0xbc, 0x98, 0xf2, 0x1b, 0x99, 0xce, 0xb0, 0x8f, +- 0xdf, 0x85, 0xda, 0x98, 0x40, 0x4d, 0x66, 0xc4, 0xd7, 0x6d, 0x94, 0xec, +- 0xdd, 0x94, 0x51, 0x89, 0xb6, 0x4a, 0x39, 0x9d, 0x68, 0x2f, 0x1e, 0xa0, +- 0x9e, 0x85, 0x75, 0xfa, 0x92, 0xcc, 0x7d, 0x9b, 0xe5, 0xbc, 0x65, 0x4e, +- 0x66, 0xd2, 0x6c, 0x3d, 0xff, 0x96, 0x0d, 0xac, 0xfb, 0x43, 0x94, 0xcf, +- 0x17, 0x2f, 0xed, 0xda, 0x31, 0xa0, 0x3c, 0x20, 0x8d, 0x15, 0x6c, 0xdb, +- 0x46, 0x7a, 0xef, 0xdb, 0x9d, 0xfa, 0xa9, 0x77, 0xf0, 0xda, 0x50, 0x54, +- 0x34, 0xed, 0xf6, 0xfc, 0xda, 0xf9, 0x2a, 0xf1, 0xf5, 0x61, 0x9a, 0xf9, +- 0xe1, 0x78, 0x7b, 0x07, 0x97, 0x16, 0xff, 0x94, 0xf6, 0x86, 0x88, 0x17, +- 0x68, 0x31, 0x92, 0x75, 0x05, 0xcd, 0x25, 0x57, 0x67, 0x0e, 0x48, 0x57, +- 0x67, 0xfc, 0xa4, 0xf7, 0x51, 0xd6, 0x3b, 0xcf, 0x45, 0x55, 0xdd, 0xf3, +- 0x7e, 0x3e, 0x3f, 0x4c, 0x31, 0xc9, 0xb6, 0x44, 0x53, 0x83, 0xc3, 0xfa, +- 0x85, 0xa8, 0x73, 0xba, 0x8c, 0x85, 0x62, 0x87, 0xf4, 0xe2, 0xd5, 0x7c, +- 0x16, 0x15, 0x13, 0xfe, 0x79, 0xa6, 0xfd, 0xe5, 0xf3, 0x6d, 0xe2, 0xd8, +- 0xc3, 0x54, 0x7c, 0xeb, 0x7d, 0x7f, 0xe9, 0x7d, 0x92, 0xe2, 0x49, 0x73, +- 0x6e, 0x95, 0xa9, 0x56, 0xf6, 0x37, 0x28, 0x2f, 0xdb, 0xb7, 0xc8, 0x5c, +- 0x2b, 0xfb, 0x1d, 0xbc, 0x38, 0xe1, 0xd9, 0xb9, 0xfb, 0x3c, 0x1f, 0xd7, +- 0x74, 0x4a, 0x39, 0x61, 0x5f, 0x45, 0xba, 0x60, 0x3c, 0x55, 0x5d, 0xfc, +- 0xe5, 0x9c, 0x6e, 0xa8, 0x89, 0xae, 0xaf, 0xd4, 0x2b, 0xce, 0x69, 0x35, +- 0xce, 0x1b, 0x78, 0x31, 0xaf, 0xb4, 0x85, 0xd1, 0x84, 0x3e, 0x5b, 0xe0, +- 0xdd, 0x1e, 0x81, 0xd3, 0x97, 0x47, 0x10, 0xba, 0xcc, 0x2a, 0x77, 0x84, +- 0xfa, 0x25, 0xe6, 0x95, 0xc9, 0x51, 0xce, 0x48, 0xad, 0x53, 0x45, 0xed, +- 0xa5, 0x5c, 0xa7, 0xd8, 0x0e, 0x0a, 0xfe, 0x85, 0xf6, 0x5d, 0x77, 0xa9, +- 0x65, 0x74, 0x50, 0x4b, 0xe0, 0xf5, 0x5d, 0x9d, 0x09, 0x9f, 0xf3, 0x43, +- 0xe6, 0xe1, 0x4a, 0x5f, 0x06, 0xf6, 0xc7, 0xc5, 0x64, 0xc7, 0xdc, 0x0a, +- 0x05, 0xe9, 0x25, 0xf0, 0x22, 0xf4, 0x7e, 0xdb, 0x2e, 0xf6, 0x85, 0x47, +- 0x74, 0x9e, 0x09, 0x81, 0xae, 0x84, 0x0e, 0x6b, 0xd5, 0x0b, 0x44, 0x9b, +- 0xfa, 0x4d, 0xd2, 0x07, 0xd3, 0xaa, 0xe2, 0xa9, 0xe2, 0x88, 0x8a, 0xd3, +- 0x0f, 0xf3, 0x19, 0x08, 0xd6, 0x51, 0x7a, 0x01, 0xc5, 0x76, 0x46, 0x9d, +- 0x93, 0x6d, 0x40, 0xaf, 0xf4, 0x61, 0x51, 0x31, 0x35, 0xca, 0xf8, 0x7c, +- 0x3f, 0x42, 0x91, 0x7d, 0x2b, 0xcd, 0x7b, 0x7e, 0x23, 0x17, 0x64, 0xfe, +- 0x9d, 0xf6, 0x30, 0xde, 0xa8, 0x38, 0xe2, 0xd3, 0xae, 0xe8, 0x68, 0x8a, +- 0x74, 0x3d, 0x91, 0xae, 0xe2, 0xd9, 0x48, 0x7b, 0xd8, 0xe7, 0x98, 0x87, +- 0x5e, 0xf1, 0x78, 0x9e, 0xf2, 0x0a, 0xd5, 0xdc, 0x89, 0xac, 0x62, 0xd5, +- 0x42, 0x62, 0xb3, 0xad, 0x63, 0x99, 0x5e, 0xa9, 0x57, 0xf7, 0xe7, 0xab, +- 0xf7, 0x3f, 0xbd, 0xa2, 0x90, 0x57, 0xa8, 0x7f, 0x83, 0x5e, 0xef, 0x28, +- 0xf7, 0x34, 0x51, 0x2c, 0xbd, 0x46, 0xb5, 0xeb, 0xd5, 0xb1, 0x5e, 0x91, +- 0xcf, 0xeb, 0x78, 0x65, 0x7c, 0xb9, 0x78, 0x30, 0x6f, 0xe1, 0xe5, 0x62, +- 0xe5, 0x2e, 0xe8, 0x81, 0xa2, 0x2b, 0xc6, 0xf3, 0xdc, 0xfb, 0x98, 0xa9, +- 0x32, 0x66, 0xc4, 0x5a, 0xc2, 0x53, 0x56, 0x2f, 0xf4, 0xeb, 0xc8, 0x78, +- 0xb1, 0x01, 0x93, 0x63, 0x95, 0x7a, 0x77, 0xeb, 0xb9, 0x7a, 0xf7, 0xc5, +- 0x3b, 0x9d, 0x48, 0x4e, 0x77, 0xd0, 0xd7, 0x38, 0xbc, 0x49, 0x46, 0xad, +- 0x10, 0xd5, 0x49, 0x2b, 0x37, 0x2d, 0x22, 0x3d, 0x3b, 0xba, 0x99, 0x5f, +- 0xf4, 0x69, 0xd4, 0x63, 0x4c, 0x14, 0xd9, 0x5f, 0x0d, 0x18, 0xc5, 0x6f, +- 0xb5, 0x56, 0xec, 0xdc, 0x96, 0xd3, 0x1c, 0xa0, 0x9e, 0xfa, 0x8b, 0x06, +- 0x9a, 0x0d, 0xea, 0x9c, 0x1b, 0xbd, 0x8e, 0x6e, 0xe4, 0x54, 0xc7, 0xea, +- 0xb9, 0x5e, 0xac, 0x5c, 0xa9, 0x38, 0xf7, 0xad, 0x0c, 0x4d, 0x1b, 0xc6, +- 0x16, 0xbf, 0x0e, 0x9d, 0x1c, 0xd8, 0x4f, 0x33, 0x50, 0x0d, 0xcd, 0xa5, +- 0xef, 0xe9, 0xb8, 0x2f, 0xd4, 0x7d, 0x1f, 0x36, 0xe5, 0x07, 0xf0, 0xb7, +- 0x79, 0xce, 0x13, 0x3a, 0x1e, 0x63, 0x1e, 0x0a, 0x7c, 0xff, 0x73, 0xb0, +- 0x85, 0x6b, 0xdf, 0x23, 0x25, 0x8a, 0xc3, 0x21, 0xe4, 0x12, 0x8e, 0x9f, +- 0x47, 0x12, 0xa7, 0xc4, 0xf9, 0xfd, 0xbf, 0xbb, 0x97, 0xf5, 0x46, 0xfd, +- 0x1c, 0xcd, 0x4e, 0x4a, 0xf6, 0x4a, 0xbe, 0x7f, 0xf2, 0x03, 0x74, 0x3b, +- 0xe5, 0x91, 0x0f, 0x6c, 0x13, 0x63, 0x7a, 0xc5, 0x7e, 0xdb, 0x47, 0xb9, +- 0x1e, 0x7d, 0x42, 0xf5, 0x28, 0x2a, 0xb6, 0xd2, 0x73, 0xa3, 0xf3, 0x4a, +- 0x7a, 0x8a, 0x78, 0x3f, 0x46, 0x39, 0x26, 0xe1, 0x1c, 0x47, 0xa2, 0xc0, +- 0xb3, 0xfa, 0x51, 0x9a, 0xd5, 0xcd, 0xdc, 0x32, 0x8a, 0xe7, 0x03, 0x76, +- 0xd7, 0xc0, 0xa0, 0x30, 0x8f, 0x52, 0x6d, 0x4e, 0x1c, 0xa0, 0xb9, 0x8b, +- 0xbe, 0x37, 0xb4, 0x87, 0xba, 0xec, 0x75, 0x30, 0xdd, 0x85, 0xc2, 0x34, +- 0x5e, 0x17, 0xa6, 0x5e, 0x23, 0x58, 0x27, 0x9f, 0x60, 0x91, 0xaf, 0x9b, +- 0xe3, 0xb0, 0xfc, 0xef, 0x57, 0xd2, 0x1d, 0xfe, 0xf7, 0xd1, 0xf4, 0xc5, +- 0xe7, 0x7b, 0x0b, 0x77, 0x07, 0xd5, 0xc6, 0x7c, 0x21, 0x83, 0x48, 0x33, +- 0xd7, 0x8a, 0xa8, 0x38, 0xb0, 0x0b, 0x5a, 0xbd, 0xf3, 0x3e, 0xbe, 0x3e, +- 0x04, 0x4d, 0x73, 0xa8, 0xd2, 0x12, 0x2f, 0xd4, 0x1b, 0xa4, 0xae, 0x13, +- 0xdc, 0x0f, 0x74, 0xe5, 0x9e, 0x80, 0xd9, 0x53, 0x43, 0x34, 0x3e, 0x01, +- 0xe3, 0x7a, 0x1f, 0x49, 0x1f, 0xe7, 0x2c, 0xce, 0xe3, 0x8c, 0x8a, 0xc1, +- 0xd1, 0xa8, 0xd8, 0x4c, 0xb2, 0xb4, 0x3b, 0x27, 0x71, 0x85, 0xcf, 0xff, +- 0x2b, 0xc4, 0x3f, 0xe7, 0x9c, 0x13, 0x94, 0x73, 0x18, 0xef, 0xd1, 0x34, +- 0xe3, 0x1d, 0xa0, 0x3e, 0xf3, 0x7a, 0xdb, 0x4c, 0xf5, 0x84, 0xcc, 0x44, +- 0x97, 0x30, 0x29, 0xa9, 0xb1, 0x3c, 0x5d, 0xfd, 0x33, 0xe0, 0xb9, 0xd8, +- 0x97, 0xa9, 0xa7, 0x9e, 0x64, 0x1a, 0x22, 0x7a, 0x1f, 0xfa, 0xf4, 0x4e, +- 0xce, 0xd1, 0x3b, 0xf1, 0x07, 0x64, 0x52, 0xdd, 0xfb, 0xc9, 0x1e, 0xdb, +- 0x0a, 0xaf, 0xc8, 0xce, 0xd6, 0x8a, 0x4c, 0x83, 0x3e, 0x2f, 0x3f, 0x49, +- 0x33, 0x2f, 0x51, 0x67, 0x86, 0xe6, 0x48, 0xa6, 0x6d, 0xae, 0x22, 0xba, +- 0x44, 0xb3, 0xcb, 0x18, 0x10, 0x66, 0x3f, 0xe9, 0xad, 0x6f, 0xdc, 0xd7, +- 0xdb, 0x4f, 0xd2, 0x5d, 0x3e, 0xce, 0x19, 0xea, 0x39, 0xbe, 0xe8, 0x93, +- 0xec, 0x73, 0xd5, 0xbb, 0xca, 0x94, 0x78, 0x8a, 0x7a, 0x97, 0xa7, 0x8a, +- 0xaa, 0xd8, 0x47, 0xf6, 0x1c, 0xa7, 0xb8, 0x19, 0xf4, 0xef, 0x1f, 0xa9, +- 0x06, 0x96, 0xbe, 0xd7, 0x3c, 0x97, 0x6f, 0xc8, 0xae, 0x65, 0xb2, 0x6b, +- 0x27, 0x65, 0x65, 0xee, 0xd9, 0xb8, 0xde, 0x1d, 0xa6, 0x7a, 0x27, 0xf0, +- 0xa1, 0x9f, 0x63, 0x0f, 0xa3, 0xb3, 0xc8, 0x3d, 0xa1, 0x25, 0x96, 0xe7, +- 0x8d, 0xdc, 0x7c, 0xc2, 0xfd, 0x7e, 0xa9, 0x92, 0x1f, 0xa9, 0x36, 0xba, +- 0x21, 0xa7, 0x47, 0xbc, 0x50, 0xe4, 0x9f, 0x54, 0x4c, 0x62, 0xec, 0x5b, +- 0xae, 0x68, 0xea, 0xf4, 0xd0, 0xde, 0xe9, 0x49, 0xd5, 0xb2, 0xca, 0xef, +- 0x0b, 0xeb, 0x94, 0x15, 0x72, 0x6f, 0x9f, 0x8f, 0x4d, 0xb8, 0x6c, 0xb1, +- 0x7b, 0x73, 0x02, 0xfe, 0x4c, 0x6c, 0x50, 0x4c, 0xa2, 0xb7, 0x3b, 0xd9, +- 0x33, 0x2d, 0x92, 0xd4, 0x43, 0x25, 0xbd, 0x94, 0x48, 0xa6, 0x8e, 0xc3, +- 0xd6, 0x8e, 0x14, 0x6d, 0xed, 0x8d, 0x62, 0xf5, 0x6e, 0x93, 0xe5, 0x62, +- 0x5f, 0xe5, 0xf8, 0xb0, 0xdc, 0xfb, 0x29, 0x0f, 0xc1, 0xef, 0x43, 0xe4, +- 0xa1, 0x46, 0x8a, 0xb1, 0x3b, 0x51, 0x4b, 0x4d, 0xb3, 0xdc, 0xde, 0x44, +- 0xf3, 0xcf, 0x5d, 0x44, 0xbf, 0xdc, 0x9a, 0x03, 0xd7, 0x93, 0x47, 0xf8, +- 0xc2, 0xb9, 0x85, 0x79, 0x7a, 0x33, 0x52, 0x91, 0x91, 0xca, 0x70, 0xe5, +- 0xff, 0x17, 0xd2, 0x1a, 0x28, 0x06, 0xd7, 0x0d, 0x09, 0xea, 0xef, 0x2b, +- 0xf1, 0xb8, 0x90, 0xef, 0x4e, 0xfd, 0x7b, 0xb3, 0x57, 0x64, 0xa5, 0xde, +- 0x7f, 0xdc, 0xcc, 0x77, 0x51, 0x8a, 0x33, 0x1c, 0xfb, 0xed, 0xb3, 0x15, +- 0xdd, 0xf2, 0x1c, 0x7f, 0xa8, 0xe4, 0x8a, 0x6b, 0xf3, 0xd8, 0x40, 0xbd, +- 0x83, 0x1b, 0x26, 0x1c, 0xd7, 0x16, 0x7b, 0x49, 0x37, 0x96, 0x31, 0x48, +- 0x44, 0xb7, 0xea, 0x5d, 0xfa, 0x38, 0xf5, 0x5a, 0x84, 0xcb, 0xa0, 0x7e, +- 0x94, 0x62, 0x7c, 0x1e, 0x76, 0xcc, 0xc5, 0x54, 0xbd, 0xc3, 0x77, 0xbb, +- 0x03, 0x62, 0xe1, 0x54, 0x25, 0xcd, 0x1f, 0x3a, 0x27, 0xdf, 0x69, 0xb9, +- 0xfd, 0x26, 0x7e, 0x5f, 0x3f, 0x67, 0x93, 0x2b, 0x99, 0x26, 0xfd, 0x7e, +- 0x76, 0x8e, 0x87, 0x3f, 0x74, 0xf6, 0x8e, 0xaf, 0xfe, 0xf6, 0x99, 0x59, +- 0xe2, 0x93, 0x7b, 0x45, 0x78, 0x31, 0x87, 0xfb, 0xc4, 0x0b, 0xe7, 0x7c, +- 0xe1, 0x52, 0xc2, 0xbd, 0x01, 0x37, 0xd2, 0x7c, 0xd4, 0x49, 0x73, 0x28, +- 0xcd, 0x2e, 0x48, 0x0d, 0xb3, 0x3e, 0xce, 0x90, 0x3e, 0xd8, 0xe6, 0xa7, +- 0xc8, 0xe6, 0x1d, 0x39, 0x8a, 0x99, 0xd4, 0x7a, 0x61, 0xf6, 0x92, 0xbf, +- 0x51, 0xed, 0x32, 0x13, 0x1f, 0xc3, 0x34, 0xd6, 0xfa, 0x3e, 0x7d, 0x66, +- 0xce, 0xa7, 0x4f, 0xb1, 0x4f, 0xa3, 0x6f, 0x38, 0x04, 0x25, 0xf3, 0x29, +- 0xe9, 0x8c, 0xe2, 0x4d, 0x30, 0x4e, 0xce, 0x53, 0x67, 0x40, 0xfd, 0xb2, +- 0x36, 0x9f, 0xf6, 0xc8, 0x42, 0x47, 0xe2, 0x28, 0xf5, 0xdb, 0xfb, 0xc0, +- 0x25, 0xa3, 0xeb, 0xe8, 0x31, 0x61, 0x96, 0xdf, 0x0b, 0x71, 0x0e, 0x10, +- 0x68, 0xcc, 0x54, 0xf0, 0x5d, 0x5e, 0x4c, 0x60, 0x47, 0xa9, 0x82, 0xf3, +- 0x32, 0xf2, 0xe1, 0x31, 0xff, 0x7e, 0x41, 0x81, 0x96, 0x79, 0x9b, 0x6b, +- 0x33, 0xc1, 0x25, 0x73, 0xf2, 0x7f, 0x67, 0xce, 0x06, 0x6f, 0xce, 0xe9, +- 0x67, 0x4b, 0x8c, 0x6b, 0x8f, 0x96, 0xe1, 0x7c, 0x0d, 0xb1, 0x26, 0xff, +- 0x67, 0x54, 0x03, 0x34, 0xea, 0x81, 0xfd, 0xbc, 0x8f, 0x5c, 0x11, 0x94, +- 0xbf, 0xcb, 0xb5, 0x47, 0xec, 0xf0, 0x5c, 0xfe, 0xfa, 0x06, 0xad, 0xf5, +- 0xd1, 0x87, 0x75, 0xc6, 0x77, 0x12, 0x37, 0xd1, 0xb3, 0xeb, 0xef, 0xeb, +- 0xcf, 0xa3, 0xa7, 0x36, 0x4d, 0xfd, 0xad, 0xbf, 0xcf, 0xbf, 0xaf, 0xa0, +- 0x3d, 0xcb, 0xf9, 0xdd, 0x08, 0xdf, 0xb5, 0xac, 0xce, 0x26, 0x8d, 0xcd, +- 0x60, 0x3a, 0x06, 0xd6, 0x14, 0x0d, 0xdc, 0x4a, 0x75, 0x61, 0xcc, 0xbf, +- 0x07, 0x3d, 0x3f, 0xf7, 0x28, 0xb4, 0x6f, 0x19, 0xed, 0x1b, 0xf4, 0xd7, +- 0x0c, 0x2c, 0x2f, 0x9e, 0x9f, 0xe9, 0x54, 0x3a, 0x77, 0xe8, 0xdc, 0x1c, +- 0xcb, 0x76, 0x70, 0xc5, 0xce, 0x7c, 0xaf, 0x18, 0xc9, 0x47, 0x89, 0x96, +- 0x42, 0x19, 0x40, 0xa2, 0x23, 0x73, 0x33, 0xe5, 0x5d, 0x2b, 0xa5, 0x2a, +- 0x4d, 0x58, 0x9b, 0x22, 0x3f, 0xd6, 0x97, 0xe2, 0x8e, 0x54, 0x0d, 0xf5, +- 0x34, 0xc3, 0xb8, 0x4d, 0xaf, 0x45, 0x7f, 0xea, 0x52, 0xe0, 0xc6, 0x3a, +- 0xea, 0x41, 0x06, 0xfc, 0x9e, 0xbe, 0x86, 0xe8, 0xd5, 0x59, 0x4f, 0xe1, +- 0xf6, 0x73, 0xff, 0xae, 0x42, 0x34, 0x7e, 0xef, 0x3c, 0x77, 0x33, 0xdc, +- 0xe6, 0x1e, 0xaa, 0x83, 0xdd, 0x58, 0x97, 0x0a, 0x53, 0x6f, 0xcd, 0xf9, +- 0x61, 0x3e, 0x22, 0xd6, 0x67, 0x72, 0xfd, 0xb9, 0x3e, 0x67, 0x46, 0xcc, +- 0x90, 0x5c, 0xa8, 0xf5, 0xc4, 0x73, 0x34, 0xbf, 0x65, 0x4a, 0x7c, 0x1f, +- 0xa5, 0x20, 0x66, 0xf1, 0xcc, 0x48, 0xc3, 0x1f, 0xcd, 0x59, 0xe9, 0xc7, +- 0xeb, 0x71, 0xd5, 0xbe, 0x06, 0x64, 0xf6, 0xe9, 0xb0, 0x1f, 0xb7, 0x68, +- 0x2d, 0x45, 0x9f, 0x19, 0xb1, 0xb7, 0xf8, 0x87, 0x68, 0x77, 0x60, 0x8d, +- 0xfe, 0x3f, 0x95, 0x7d, 0x0b, 0x70, 0x54, 0xe7, 0x95, 0xe6, 0x77, 0xfb, +- 0x21, 0xb5, 0x9e, 0x5c, 0x09, 0x09, 0x5a, 0x20, 0x9b, 0x6e, 0xf7, 0x6d, +- 0xa9, 0x8d, 0x3a, 0xe1, 0x36, 0x88, 0xb5, 0x9c, 0xed, 0x2d, 0x1a, 0x2c, +- 0x8c, 0x08, 0x60, 0xcb, 0xb6, 0x3c, 0x83, 0x77, 0x32, 0x6b, 0xc5, 0x36, +- 0x18, 0x3f, 0x92, 0x91, 0x09, 0x5b, 0x25, 0x53, 0x53, 0xd1, 0x1d, 0x01, +- 0x42, 0x40, 0xbf, 0x24, 0xc1, 0x00, 0x33, 0x53, 0xe3, 0x46, 0x0f, 0x20, +- 0xb8, 0x5b, 0xc2, 0x71, 0x66, 0x4a, 0xc9, 0xd4, 0x56, 0x34, 0x20, 0x0c, +- 0x04, 0x63, 0x3c, 0x93, 0x99, 0x29, 0xb2, 0xeb, 0x2d, 0x13, 0x1c, 0xc0, +- 0x0f, 0xfc, 0x4c, 0xb2, 0x16, 0xf1, 0xc4, 0x77, 0xbf, 0x73, 0xbb, 0x1b, +- 0x04, 0x45, 0x3c, 0x35, 0x54, 0x75, 0xb5, 0x6e, 0xdf, 0xff, 0xfe, 0x8f, +- 0xf3, 0x9f, 0xf3, 0x9d, 0xef, 0x9c, 0xf3, 0xdf, 0xa2, 0x84, 0xfe, 0xfb, +- 0xdf, 0xcc, 0x75, 0x8c, 0x4f, 0xdc, 0x0b, 0x69, 0x66, 0xb3, 0x65, 0xbc, +- 0x0b, 0x5f, 0x0e, 0x24, 0x9c, 0xe8, 0xea, 0x77, 0xe0, 0xda, 0xa2, 0x73, +- 0xa6, 0x67, 0xf6, 0x8d, 0xfc, 0x4e, 0xc4, 0xe6, 0xc4, 0x33, 0xfd, 0xf2, +- 0xed, 0x40, 0x60, 0x71, 0x36, 0xe7, 0xba, 0x61, 0xd0, 0x89, 0xa7, 0xd9, +- 0xf6, 0xa2, 0x6e, 0xcb, 0xed, 0xb1, 0x55, 0x1b, 0xc0, 0x73, 0xfd, 0x8c, +- 0x6d, 0x34, 0x13, 0xcf, 0x86, 0x8a, 0x71, 0x7f, 0x75, 0x76, 0x1d, 0xc3, +- 0x5c, 0x87, 0xe1, 0x30, 0x94, 0x4c, 0xa3, 0x13, 0xe5, 0x9c, 0x3f, 0xb9, +- 0x18, 0x7e, 0x98, 0x29, 0xc1, 0xe8, 0x81, 0x71, 0x25, 0x9d, 0xce, 0xb6, +- 0x19, 0xb2, 0x62, 0x5a, 0x43, 0x19, 0x6b, 0xb4, 0x61, 0x26, 0xfd, 0xfb, +- 0x85, 0x8c, 0x03, 0x9f, 0x65, 0x5c, 0xf8, 0x74, 0xa4, 0x18, 0xbf, 0x3e, +- 0x50, 0xc2, 0x8f, 0x8a, 0x4f, 0x46, 0x34, 0xfe, 0xde, 0xac, 0xbc, 0x12, +- 0x95, 0xd8, 0x23, 0x80, 0x4f, 0x33, 0xe3, 0xca, 0xd1, 0xaf, 0x5c, 0x6b, +- 0xc6, 0xfc, 0x8e, 0x6a, 0x70, 0xcc, 0xbf, 0x36, 0xbf, 0x3b, 0x4d, 0xae, +- 0xd3, 0xc7, 0xaa, 0xd4, 0x4a, 0xf0, 0xd9, 0x01, 0x19, 0x47, 0xfa, 0x6f, +- 0x56, 0x5e, 0x8d, 0x8a, 0x7c, 0x2b, 0xf1, 0xeb, 0x11, 0x91, 0xe3, 0x27, +- 0xd4, 0x69, 0xe9, 0x7f, 0x5c, 0x39, 0x9e, 0x7b, 0xe6, 0xe7, 0xdc, 0x8b, +- 0x8d, 0xa3, 0x0e, 0x90, 0x4c, 0xf0, 0x59, 0x17, 0x5e, 0x38, 0x68, 0x23, +- 0x27, 0x2e, 0xc6, 0xc6, 0xc1, 0x12, 0xbc, 0x30, 0xa8, 0xa2, 0xe3, 0x60, +- 0xb3, 0x42, 0xbe, 0xaf, 0xce, 0x20, 0xef, 0xed, 0x18, 0x0d, 0xb0, 0xdd, +- 0xb8, 0x72, 0x2e, 0xdd, 0x30, 0x33, 0xdb, 0x4f, 0x36, 0xf7, 0x93, 0xe5, +- 0x31, 0x86, 0xc2, 0x38, 0x8d, 0x5c, 0x72, 0xdf, 0xe6, 0xd7, 0x18, 0x21, +- 0x3e, 0x9c, 0xb6, 0x53, 0xc7, 0x24, 0x1e, 0x15, 0xbb, 0x4f, 0x6d, 0xbe, +- 0x12, 0x95, 0xb9, 0x1a, 0xca, 0x91, 0x46, 0x9b, 0xc5, 0xb1, 0x5f, 0x67, +- 0x5c, 0xb8, 0x82, 0xb6, 0xf2, 0x10, 0xe5, 0xb1, 0x9a, 0xf2, 0x68, 0xa6, +- 0x3c, 0x5a, 0x39, 0xdf, 0x97, 0xa3, 0x82, 0x93, 0xde, 0x40, 0x44, 0xd1, +- 0xb0, 0x2a, 0x23, 0x7d, 0x58, 0xe3, 0xb8, 0x1c, 0xe1, 0xbf, 0xd9, 0xbc, +- 0x35, 0x7a, 0xab, 0x5c, 0xa0, 0x96, 0x87, 0xc5, 0xaf, 0x89, 0x6c, 0x02, +- 0xe4, 0x50, 0xe3, 0xca, 0xa8, 0x15, 0x23, 0xef, 0xdb, 0xec, 0x49, 0xe5, +- 0x6d, 0xa7, 0x44, 0xec, 0x53, 0xf2, 0xe1, 0xca, 0x3e, 0x72, 0xb5, 0x1a, +- 0x2d, 0x7b, 0xff, 0xde, 0x94, 0x7c, 0xa7, 0x36, 0x2f, 0xb4, 0xf0, 0xe6, +- 0x6f, 0x36, 0x37, 0x5d, 0x5f, 0xd3, 0xb8, 0xf2, 0x36, 0xd7, 0x73, 0x81, +- 0x7a, 0x7a, 0x92, 0x73, 0x2d, 0x92, 0xbd, 0x4b, 0x73, 0xef, 0x38, 0xd7, +- 0x4f, 0x87, 0x8b, 0xf1, 0x5e, 0xaa, 0x84, 0x1f, 0xca, 0x76, 0x98, 0x7b, +- 0x97, 0x6e, 0x56, 0x4e, 0x59, 0xf2, 0x0d, 0xe0, 0x5d, 0x8e, 0x7d, 0xec, +- 0x7a, 0x1f, 0x59, 0xde, 0x96, 0xad, 0xc3, 0xe5, 0xed, 0x57, 0xf0, 0x54, +- 0xd6, 0x66, 0x28, 0x91, 0xeb, 0xb5, 0x34, 0xc9, 0x8b, 0x49, 0x7d, 0x91, +- 0x3e, 0x46, 0x95, 0xfc, 0xa8, 0x42, 0x8c, 0xa1, 0xfe, 0xa9, 0xcb, 0x3c, +- 0x0e, 0xe2, 0xe2, 0x3a, 0x7c, 0xc1, 0x38, 0x21, 0x42, 0x8b, 0x92, 0xb5, +- 0x48, 0x8e, 0xb4, 0x50, 0x62, 0x42, 0xeb, 0xdf, 0x20, 0xb9, 0xd4, 0x6b, +- 0xe4, 0xb9, 0x54, 0x21, 0x74, 0xa7, 0xbf, 0x30, 0x27, 0xaa, 0xe8, 0x57, +- 0xb5, 0xeb, 0x79, 0x37, 0xae, 0xd9, 0x34, 0x87, 0x78, 0xaf, 0x27, 0x8d, +- 0xdc, 0x3f, 0x72, 0x2f, 0xf2, 0xdd, 0x27, 0xb5, 0xdf, 0x99, 0x4f, 0xdc, +- 0xd4, 0x36, 0x8f, 0xe5, 0xf9, 0x78, 0x5f, 0xb0, 0xbc, 0x14, 0x3d, 0xbb, +- 0xbd, 0xc9, 0x14, 0xaa, 0x90, 0xd4, 0x6c, 0x73, 0x0b, 0x38, 0x3b, 0x3b, +- 0xbc, 0xbd, 0xcd, 0xb0, 0xf2, 0x20, 0x9e, 0x14, 0xfe, 0x61, 0xa6, 0xd8, +- 0x8c, 0x53, 0x6b, 0xf0, 0x54, 0xd8, 0x2a, 0x65, 0xee, 0xd6, 0xac, 0xec, +- 0xfd, 0x45, 0x58, 0x17, 0x2c, 0x42, 0xaa, 0x95, 0x18, 0xd7, 0x6f, 0xb4, +- 0xb0, 0x7b, 0xf2, 0xa7, 0xc0, 0x8b, 0xdf, 0xf4, 0x0b, 0x1f, 0x03, 0x0a, +- 0x63, 0x1c, 0x13, 0x39, 0x0c, 0xec, 0xf7, 0x1a, 0x36, 0x9b, 0x3c, 0xff, +- 0x99, 0x69, 0xb4, 0xc9, 0xb3, 0xd2, 0x47, 0xad, 0xc5, 0x1b, 0x6f, 0xd6, +- 0x7b, 0x0f, 0xe5, 0xf4, 0xaf, 0x33, 0x25, 0xe7, 0xa8, 0xd6, 0x31, 0xee, +- 0xe9, 0x97, 0x9a, 0x4d, 0x04, 0xbb, 0xaa, 0x7d, 0x1d, 0xba, 0xad, 0x18, +- 0x67, 0xbf, 0xf6, 0xdf, 0x88, 0xe9, 0x05, 0x70, 0xd5, 0x01, 0xf7, 0xc5, +- 0x6d, 0xb0, 0xd5, 0x11, 0xab, 0xa9, 0xd3, 0xcd, 0xa3, 0x36, 0xcc, 0xeb, +- 0x57, 0xf0, 0x58, 0xd2, 0x86, 0x07, 0x92, 0x76, 0xac, 0x4a, 0xe2, 0xfb, +- 0xf3, 0x80, 0xc9, 0x1a, 0xf8, 0xdb, 0xa7, 0xe8, 0x9a, 0xcb, 0xe1, 0x6f, +- 0x8d, 0x91, 0x17, 0xac, 0x62, 0x2c, 0xba, 0x72, 0x94, 0x38, 0xc8, 0xb6, +- 0xce, 0x3e, 0xea, 0x66, 0x9f, 0x1d, 0x35, 0x7d, 0xb8, 0xb3, 0x10, 0xa0, +- 0x75, 0xfb, 0xa7, 0xe8, 0x97, 0x2a, 0x1d, 0xf0, 0xd3, 0xaf, 0xf8, 0x3b, +- 0x6b, 0xec, 0x0c, 0xc4, 0xea, 0xfe, 0xd5, 0xe2, 0xb4, 0x0f, 0xd2, 0x5e, +- 0xe6, 0xf5, 0xb3, 0x7d, 0x9d, 0x0d, 0x2a, 0xf5, 0xf9, 0x93, 0x3f, 0x96, +- 0x7c, 0xaf, 0xdc, 0x93, 0xba, 0xab, 0x82, 0xf2, 0x7e, 0x3b, 0xf1, 0xf0, +- 0x8c, 0x79, 0xb6, 0xda, 0xaa, 0x41, 0xe1, 0x31, 0xce, 0xcd, 0xcd, 0xdf, +- 0xd4, 0x3a, 0x17, 0x16, 0xdc, 0xa3, 0x62, 0xed, 0xa0, 0xb4, 0x85, 0xd5, +- 0x8f, 0x93, 0xb8, 0x53, 0xa0, 0x4d, 0x98, 0x07, 0xab, 0xa4, 0xad, 0x8d, +- 0x6b, 0xb4, 0xa3, 0xa4, 0x1f, 0x58, 0x19, 0xc7, 0xc3, 0xa5, 0xf0, 0x47, +- 0x64, 0x8e, 0xf5, 0x8b, 0x1d, 0x7c, 0xb6, 0x14, 0x2d, 0xa3, 0xd9, 0xe7, +- 0x56, 0x8c, 0xbe, 0x37, 0x33, 0x9b, 0xfb, 0xfe, 0xc3, 0x75, 0xe3, 0x2d, +- 0x8d, 0x7e, 0xac, 0x4b, 0x52, 0xe7, 0x6c, 0x1e, 0x0c, 0xe6, 0x72, 0xd0, +- 0x4f, 0xa4, 0xbc, 0xd3, 0xea, 0xba, 0x7f, 0x5b, 0x9a, 0xab, 0xf9, 0xd2, +- 0x8e, 0xa7, 0xd8, 0x8f, 0x65, 0xc3, 0x18, 0x1c, 0x33, 0x11, 0xd5, 0x4d, +- 0x64, 0xf8, 0x79, 0x43, 0x87, 0x51, 0x42, 0x1b, 0x7f, 0x2a, 0x26, 0x98, +- 0x97, 0xd5, 0xa4, 0x1f, 0x24, 0x02, 0xca, 0x86, 0x18, 0x70, 0x84, 0xf1, +- 0xe3, 0x21, 0x7e, 0x86, 0x13, 0x5c, 0x03, 0xe7, 0x6d, 0x23, 0x6e, 0x6c, +- 0x4b, 0x01, 0x43, 0x09, 0x44, 0xf6, 0x2f, 0x96, 0x58, 0xa6, 0x84, 0xe3, +- 0x01, 0xe3, 0x6c, 0x93, 0xe6, 0xe7, 0x20, 0x3f, 0x63, 0xdc, 0x53, 0x8e, +- 0x87, 0x00, 0xf1, 0x30, 0x92, 0xd1, 0x60, 0x64, 0x02, 0x98, 0xa0, 0x6d, +- 0x5d, 0x1b, 0x56, 0x51, 0x76, 0xa8, 0x12, 0x1f, 0x8d, 0x64, 0x63, 0xa5, +- 0x75, 0x19, 0xa9, 0x5d, 0xcb, 0xda, 0xa4, 0x7e, 0x2d, 0xb6, 0x54, 0x84, +- 0x43, 0xc9, 0x4a, 0xab, 0x86, 0xfd, 0x8e, 0xce, 0x7e, 0x55, 0xa9, 0xb1, +- 0xb6, 0xe2, 0x70, 0xd4, 0xe7, 0xe9, 0xa5, 0xbe, 0x1b, 0x0e, 0xb1, 0xaf, +- 0x46, 0x1c, 0x89, 0xe6, 0x6b, 0x67, 0xbe, 0x96, 0x9f, 0x49, 0x8e, 0xc8, +- 0x59, 0x49, 0xd9, 0xca, 0xbd, 0xbc, 0xdf, 0x95, 0xf5, 0x4a, 0x0e, 0x3f, +- 0xcf, 0x71, 0xa6, 0xff, 0x7e, 0x8a, 0xe3, 0x05, 0x69, 0x07, 0xde, 0xde, +- 0x14, 0x74, 0xcb, 0x97, 0x8e, 0xd4, 0x7b, 0x93, 0x06, 0x64, 0x6f, 0x1b, +- 0x39, 0x87, 0xd7, 0xa8, 0xf7, 0x01, 0xca, 0xf9, 0x2f, 0xe8, 0x23, 0x5c, +- 0x8c, 0x65, 0x2b, 0xb0, 0xab, 0xaf, 0x12, 0x3b, 0xfb, 0x0c, 0xf4, 0x2c, +- 0x6e, 0xc3, 0xa9, 0xa8, 0x89, 0x75, 0x21, 0x13, 0x2b, 0x19, 0x23, 0xfc, +- 0x00, 0x0d, 0x4d, 0x87, 0xf1, 0x20, 0x63, 0x65, 0x95, 0xf2, 0xf8, 0x16, +- 0xde, 0xde, 0xed, 0xc0, 0x7a, 0xfd, 0x8f, 0x68, 0xbf, 0xa6, 0xf9, 0xab, +- 0x45, 0xb5, 0x18, 0x4c, 0x34, 0xa8, 0xdd, 0x9c, 0x5f, 0xa4, 0x8d, 0xfb, +- 0x14, 0x74, 0xe0, 0x69, 0xfd, 0xfb, 0x6c, 0xeb, 0xb6, 0x39, 0x34, 0xb9, +- 0x96, 0xba, 0x96, 0xec, 0xa3, 0x41, 0xdd, 0xca, 0xfb, 0xac, 0x6c, 0xad, +- 0x74, 0x7d, 0xa3, 0xe4, 0x44, 0x4a, 0x71, 0x92, 0x32, 0x3b, 0x96, 0x8c, +- 0xd0, 0x55, 0x43, 0x79, 0xba, 0xb1, 0x0b, 0x8f, 0x93, 0x9b, 0xbc, 0x4d, +- 0xd2, 0x70, 0x6f, 0x5c, 0x41, 0x53, 0xbd, 0x8e, 0xf3, 0xe9, 0x6f, 0xe1, +- 0xcd, 0xe1, 0x30, 0xde, 0x20, 0x07, 0x58, 0xf0, 0x97, 0xc2, 0xe9, 0x3d, +- 0x38, 0x9b, 0x0e, 0xe3, 0x4c, 0xd4, 0xdb, 0xfa, 0xbc, 0x52, 0x8b, 0x9f, +- 0x11, 0xd3, 0xee, 0x8e, 0x03, 0xef, 0xb1, 0x1f, 0x7f, 0xdc, 0x81, 0x4b, +- 0x69, 0x15, 0x87, 0xb9, 0x37, 0x8e, 0xd0, 0x02, 0x18, 0x6d, 0x1e, 0x1c, +- 0x1c, 0x78, 0x00, 0x13, 0xa9, 0x07, 0x70, 0x22, 0xf9, 0xb6, 0xe9, 0xd2, +- 0xa4, 0x06, 0xe6, 0xc2, 0x25, 0x62, 0xea, 0x24, 0xa5, 0x51, 0x7a, 0x4f, +- 0x2b, 0x71, 0x51, 0x33, 0x44, 0xee, 0x6f, 0xf2, 0xb7, 0x7b, 0xe3, 0x4d, +- 0xd8, 0x9f, 0xa1, 0x48, 0x13, 0x3a, 0x12, 0x31, 0x19, 0xab, 0x11, 0x31, +- 0x72, 0xc8, 0x5d, 0x7d, 0xe2, 0x37, 0xef, 0xc6, 0xca, 0x0a, 0x28, 0x2d, +- 0x75, 0x63, 0xb9, 0x75, 0x34, 0x4d, 0xab, 0x6d, 0x4a, 0xbc, 0x49, 0xb9, +- 0xf2, 0xb9, 0x1f, 0x26, 0x28, 0xf7, 0x04, 0x65, 0x7b, 0x7d, 0x3f, 0x9a, +- 0xb8, 0x1f, 0xdf, 0xc2, 0xf9, 0xdd, 0x6d, 0x78, 0x93, 0x58, 0x57, 0xbe, +- 0xc8, 0xd7, 0xe9, 0xb4, 0x35, 0xb0, 0xef, 0xb4, 0x99, 0xaa, 0x16, 0x99, +- 0xb6, 0xe1, 0x17, 0x51, 0x91, 0x69, 0x9a, 0xd8, 0xe7, 0xf3, 0xf8, 0xed, +- 0x23, 0x55, 0xd4, 0x65, 0x5b, 0x77, 0x30, 0x5b, 0xaf, 0x2b, 0xbd, 0xc7, +- 0x85, 0xcb, 0xd6, 0xdc, 0x64, 0xae, 0x5f, 0x35, 0xbf, 0x5f, 0x98, 0x2b, +- 0xab, 0x65, 0x7e, 0x86, 0xc9, 0x98, 0x3a, 0xc0, 0x78, 0x91, 0xb6, 0x13, +- 0x80, 0xe4, 0x9c, 0xeb, 0xe3, 0x5d, 0xb0, 0x87, 0x4a, 0x0d, 0x35, 0xec, +- 0x9d, 0xea, 0xc0, 0x9b, 0xb8, 0x42, 0x8e, 0x72, 0x57, 0x5c, 0x63, 0x7c, +- 0x7b, 0x81, 0x63, 0xfd, 0x0b, 0x2e, 0xf2, 0xda, 0x17, 0xcf, 0xda, 0x5a, +- 0x77, 0x63, 0x1b, 0xee, 0x4b, 0xcb, 0xfa, 0xfe, 0x0b, 0x07, 0xd2, 0x11, +- 0x49, 0xcb, 0x3a, 0x63, 0xb4, 0x0b, 0x59, 0x67, 0xe5, 0x7f, 0xb0, 0xce, +- 0x23, 0xec, 0xaf, 0x96, 0x76, 0x94, 0xf7, 0x1b, 0x65, 0x38, 0x98, 0x54, +- 0x71, 0x52, 0x2f, 0xc5, 0x05, 0x55, 0xf2, 0xf5, 0xd9, 0x5a, 0x66, 0x33, +- 0xe3, 0xd3, 0x21, 0x7e, 0x9e, 0x62, 0x0c, 0x75, 0x5a, 0x77, 0xe0, 0x84, +- 0x5e, 0x4b, 0x9c, 0xbf, 0x55, 0x87, 0xe5, 0x1e, 0x03, 0x83, 0x8a, 0x4a, +- 0x9c, 0x91, 0x9c, 0xaa, 0x75, 0x5f, 0xce, 0x16, 0xb8, 0x20, 0x39, 0x8d, +- 0x82, 0xd8, 0x6f, 0xcd, 0xcb, 0x16, 0xce, 0xdc, 0x3a, 0xbf, 0x5b, 0xfb, +- 0x21, 0x55, 0xd0, 0xde, 0x33, 0x9f, 0xad, 0xce, 0xf9, 0x2d, 0x65, 0x47, +- 0x55, 0x16, 0x2b, 0xc4, 0x87, 0x8d, 0xe7, 0x71, 0x83, 0x7c, 0x7c, 0xdf, +- 0xa3, 0xf4, 0x41, 0xf4, 0xcf, 0xcd, 0xdf, 0xdb, 0xaa, 0x49, 0x9c, 0x97, +- 0x7a, 0x74, 0x99, 0x56, 0x00, 0xbb, 0xe5, 0x67, 0x0f, 0x6f, 0xce, 0xf2, +- 0xf9, 0xf4, 0xe6, 0x6c, 0x8c, 0x7a, 0x74, 0xf3, 0x5d, 0xd6, 0xf7, 0x8f, +- 0x36, 0xfb, 0x52, 0x37, 0x7c, 0x55, 0x96, 0x2f, 0x5b, 0x67, 0x6d, 0xd0, +- 0xab, 0x1b, 0xca, 0x8a, 0x46, 0xf1, 0xd7, 0x79, 0x8e, 0x22, 0x6d, 0x02, +- 0xca, 0x89, 0xa8, 0x61, 0xba, 0xb5, 0x62, 0xfa, 0x7a, 0x28, 0x63, 0x8c, +- 0xc5, 0xa6, 0xac, 0xba, 0xa7, 0x86, 0x37, 0xd2, 0x12, 0x13, 0x83, 0xfa, +- 0xfb, 0xbf, 0xb1, 0x6b, 0x37, 0xda, 0x8b, 0x16, 0x93, 0xb3, 0xd3, 0xcf, +- 0x3d, 0x1b, 0x72, 0xe0, 0xfd, 0x74, 0x76, 0x3d, 0xef, 0x0d, 0x97, 0xe0, +- 0xdd, 0x94, 0xf8, 0x6b, 0xa8, 0x85, 0xec, 0xf7, 0x64, 0x5a, 0x63, 0x6c, +- 0x2a, 0xe3, 0xb6, 0x61, 0xdb, 0x98, 0x03, 0xfb, 0xa3, 0x1a, 0x62, 0x89, +- 0x9f, 0x9a, 0x45, 0x9a, 0x6f, 0xc2, 0x6f, 0x77, 0x60, 0x5f, 0x7a, 0x12, +- 0x63, 0x7d, 0x1f, 0x9b, 0x76, 0xad, 0x0b, 0x1f, 0x85, 0x26, 0xc9, 0xeb, +- 0xa4, 0xfe, 0xa9, 0x63, 0xd7, 0x80, 0xc6, 0x58, 0xda, 0x86, 0x9d, 0x8b, +- 0x5b, 0xb0, 0x6b, 0xac, 0x19, 0xc6, 0x21, 0x0f, 0x76, 0x92, 0xf0, 0x4d, +- 0x0c, 0x4f, 0xe2, 0x54, 0x52, 0x6b, 0x2a, 0x52, 0x26, 0x71, 0x92, 0xe3, +- 0x6c, 0x4d, 0xbc, 0x05, 0x83, 0x7d, 0x6c, 0x4b, 0x4a, 0x8e, 0x57, 0xc6, +- 0x99, 0x44, 0x77, 0xea, 0x76, 0x35, 0x8f, 0x36, 0xec, 0x48, 0x6c, 0x69, +- 0xcf, 0xd6, 0x3d, 0x88, 0xab, 0x69, 0x4d, 0xe9, 0xe5, 0x1e, 0x1d, 0x4e, +- 0xe7, 0x6b, 0x20, 0x82, 0xa1, 0x59, 0x3c, 0xdc, 0x96, 0xd6, 0xd1, 0x3b, +- 0xd0, 0xc2, 0xf6, 0x1a, 0xba, 0x13, 0x52, 0x3f, 0xf6, 0x71, 0x3c, 0x13, +- 0xef, 0xe9, 0x5e, 0xf7, 0x5d, 0xfc, 0x1e, 0xd1, 0x3b, 0xb1, 0x81, 0xfd, +- 0x08, 0xe7, 0xd2, 0x14, 0x6f, 0x93, 0x01, 0x3b, 0x7e, 0xa5, 0xdb, 0x61, +- 0x54, 0xd9, 0x71, 0x44, 0x2f, 0x23, 0x3f, 0xb7, 0xa3, 0x21, 0x44, 0xdf, +- 0x9c, 0xf3, 0xd5, 0x1f, 0x26, 0x15, 0x3c, 0x40, 0x2c, 0x3d, 0x16, 0x6a, +- 0x68, 0x5f, 0x2e, 0x6c, 0xf7, 0x80, 0x82, 0x2b, 0xda, 0x35, 0xd3, 0xa0, +- 0xbf, 0x72, 0xf9, 0xf3, 0x7b, 0xf3, 0x6b, 0x33, 0x5b, 0x03, 0xfe, 0xc2, +- 0xcc, 0x3f, 0x37, 0xc5, 0xf9, 0x3d, 0xc6, 0xe7, 0xee, 0x5a, 0xd4, 0xd0, +- 0x29, 0xcf, 0xb9, 0x89, 0xe3, 0xf2, 0x9c, 0xe4, 0xf6, 0x6f, 0x3c, 0xa7, +- 0x63, 0xdb, 0x40, 0xc4, 0x9a, 0xef, 0xf6, 0x04, 0x16, 0x3a, 0x20, 0x76, +- 0xd4, 0xa0, 0x5e, 0x02, 0xba, 0x26, 0xf5, 0x19, 0xe4, 0x37, 0xfe, 0xc0, +- 0x53, 0x10, 0x39, 0x49, 0xbc, 0xf9, 0x16, 0x76, 0x46, 0x87, 0xc1, 0x98, +- 0x93, 0xf8, 0xe6, 0x5f, 0x3b, 0x84, 0x14, 0x9e, 0x4b, 0xa7, 0xf0, 0xbc, +- 0x70, 0x6c, 0x2b, 0xc7, 0x96, 0xc6, 0x77, 0xa2, 0x6f, 0x21, 0x66, 0xc5, +- 0x55, 0x87, 0xf1, 0x44, 0xf4, 0xdd, 0x6a, 0xc9, 0x65, 0x6e, 0x4d, 0x2c, +- 0x65, 0xff, 0x22, 0x53, 0x6f, 0xab, 0x81, 0x2f, 0xd9, 0xff, 0x52, 0x6c, +- 0x19, 0x92, 0x9c, 0x90, 0x89, 0xd7, 0xc9, 0xa9, 0xae, 0x50, 0x8f, 0x5a, +- 0x1a, 0xa5, 0xff, 0x71, 0x45, 0xb3, 0x7c, 0x57, 0x1b, 0xf7, 0x78, 0x16, +- 0xdc, 0x94, 0x73, 0x59, 0x46, 0x53, 0xee, 0x8a, 0xc9, 0x9e, 0x3b, 0x60, +- 0xcb, 0x78, 0xf0, 0x18, 0x79, 0x49, 0xe1, 0xc8, 0x8f, 0x14, 0xf1, 0x5f, +- 0x35, 0xe4, 0xa2, 0xee, 0x03, 0x1e, 0x65, 0xc1, 0x1e, 0x17, 0x1e, 0x88, +- 0x91, 0xa3, 0xc6, 0x9a, 0xb1, 0x65, 0xaf, 0xc6, 0x36, 0x5e, 0xfd, 0x1c, +- 0xe3, 0xd6, 0x93, 0xf0, 0x79, 0x86, 0xc8, 0xa5, 0xdc, 0xc4, 0x60, 0xc7, +- 0x48, 0x39, 0x4a, 0xc8, 0xb3, 0xa5, 0xdc, 0x5c, 0x3a, 0xe2, 0x46, 0x0d, +- 0xfd, 0x99, 0x3b, 0x73, 0x1e, 0x63, 0x7b, 0xa0, 0x96, 0x84, 0x3f, 0x37, +- 0x0b, 0x35, 0xa9, 0x57, 0x06, 0x50, 0x9e, 0xd9, 0x84, 0x74, 0x2c, 0x88, +- 0x52, 0xf2, 0xfb, 0x06, 0x8e, 0x77, 0x7f, 0x4c, 0x63, 0x3f, 0x59, 0x6e, +- 0xb3, 0x9c, 0xcf, 0xf4, 0x26, 0xbc, 0x6b, 0xa5, 0xde, 0x78, 0x45, 0x7f, +- 0x0d, 0x45, 0x7d, 0x37, 0xce, 0x9c, 0x69, 0x21, 0xcc, 0x21, 0xf7, 0x68, +- 0x7d, 0x1a, 0xd9, 0xf3, 0x67, 0x2b, 0x72, 0xeb, 0x09, 0xca, 0x7a, 0x9c, +- 0x6d, 0xd4, 0x83, 0xd9, 0x98, 0xc1, 0xf5, 0x5c, 0xa4, 0xde, 0xdc, 0xcb, +- 0xb9, 0x5e, 0x63, 0xec, 0xd0, 0xc9, 0xb5, 0xbc, 0x3f, 0xfc, 0x23, 0xa5, +- 0x86, 0x6b, 0x99, 0x22, 0x57, 0xfd, 0x38, 0xe5, 0x51, 0x7c, 0x5c, 0xcb, +- 0x77, 0x79, 0xff, 0x3b, 0x5c, 0xcb, 0xd6, 0xbd, 0xde, 0xd6, 0xe3, 0x8a, +- 0xb7, 0x7d, 0x8d, 0xe2, 0x53, 0xb7, 0x2a, 0xa5, 0xb8, 0x38, 0x5c, 0x8e, +- 0x4b, 0xf4, 0xbd, 0xd7, 0x86, 0x2b, 0x71, 0x79, 0xb8, 0x8a, 0x36, 0xa2, +- 0xb1, 0x0f, 0xd3, 0x2c, 0xd3, 0xdc, 0x98, 0x4a, 0x3f, 0x8f, 0x19, 0xb1, +- 0x5a, 0x7c, 0x9c, 0xde, 0x80, 0xf2, 0x98, 0xc4, 0x00, 0x1e, 0x7c, 0xc4, +- 0xfb, 0x1f, 0xa6, 0x47, 0x51, 0xbc, 0xe7, 0x73, 0xb6, 0x31, 0xcd, 0xfb, +- 0xb9, 0xbe, 0xcb, 0xe9, 0x0e, 0x94, 0xee, 0xd9, 0x08, 0xc7, 0x1e, 0xb3, +- 0x6b, 0x4b, 0x08, 0x3f, 0xb3, 0x73, 0x2d, 0xdd, 0xba, 0x77, 0xe2, 0x2e, +- 0x7b, 0x90, 0x7d, 0x8c, 0x2b, 0x0b, 0x32, 0x1b, 0x51, 0xbe, 0xc7, 0x83, +- 0x67, 0x29, 0xc3, 0x51, 0x68, 0x81, 0x35, 0xca, 0x46, 0x14, 0x8c, 0x64, +- 0xd7, 0xbf, 0x2e, 0x93, 0xb5, 0x8b, 0xfb, 0x1b, 0xa7, 0xc7, 0x32, 0x6e, +- 0x8b, 0x77, 0x4f, 0xa6, 0x4b, 0x70, 0x3a, 0x25, 0xf2, 0x81, 0xea, 0x08, +- 0x8f, 0xa2, 0x70, 0x0f, 0x31, 0x71, 0x58, 0xb7, 0xf8, 0x82, 0xd8, 0xc4, +- 0x70, 0xfa, 0x76, 0x36, 0x15, 0xc4, 0xce, 0x44, 0x0d, 0xed, 0xa9, 0x16, +- 0x2b, 0xf7, 0x48, 0x8d, 0x79, 0xe2, 0x5e, 0x17, 0xb5, 0xe8, 0x50, 0xfa, +- 0x56, 0x7b, 0x6a, 0xa4, 0x6e, 0x0a, 0xb6, 0x9a, 0x98, 0xd4, 0xb3, 0x78, +- 0x73, 0xcc, 0xaa, 0x61, 0x8b, 0x4d, 0xb6, 0x62, 0xcb, 0x00, 0xda, 0xf7, +- 0x37, 0x8a, 0x4d, 0x3a, 0x31, 0x44, 0xbe, 0x7f, 0x91, 0xb1, 0xc3, 0x0c, +- 0xed, 0x73, 0x62, 0x42, 0x01, 0x06, 0x87, 0x5d, 0xf8, 0xf1, 0xb0, 0x07, +- 0xee, 0x58, 0x31, 0xc6, 0x29, 0xe3, 0x31, 0x72, 0x9c, 0x8f, 0x18, 0x65, +- 0x8f, 0xd2, 0xa7, 0x7e, 0x18, 0xad, 0x42, 0x26, 0x5d, 0x8b, 0xab, 0xc4, +- 0x94, 0x34, 0xf7, 0xe3, 0x83, 0x68, 0x00, 0x2f, 0xa7, 0x83, 0x78, 0x3f, +- 0x2a, 0xd8, 0x13, 0xc4, 0x11, 0xca, 0xaf, 0x28, 0xe6, 0x66, 0xbf, 0x82, +- 0x43, 0x1e, 0x38, 0x63, 0x9a, 0x67, 0x28, 0xa7, 0x0b, 0x8e, 0x4c, 0x2b, +- 0xed, 0x46, 0xce, 0x44, 0x88, 0x1f, 0x70, 0xe8, 0x43, 0x8c, 0xb9, 0x07, +- 0x83, 0xf9, 0xfc, 0xaf, 0xd7, 0x3d, 0x81, 0x99, 0xb4, 0x9d, 0x2f, 0x4d, +- 0x55, 0x93, 0x98, 0x2a, 0x19, 0xba, 0x12, 0xd5, 0x24, 0x17, 0x48, 0x6c, +- 0x37, 0x14, 0xe7, 0x62, 0x72, 0x89, 0xaa, 0xad, 0x92, 0x17, 0xe6, 0xfc, +- 0xe5, 0x6c, 0x99, 0xc9, 0x76, 0x57, 0x31, 0xff, 0xc0, 0xd6, 0x59, 0xb9, +- 0x1c, 0x93, 0x7a, 0x83, 0xf7, 0xe5, 0x31, 0x5e, 0xe2, 0xb5, 0xdd, 0xa1, +- 0xd7, 0xa2, 0x7f, 0x3f, 0x4b, 0xea, 0x71, 0xc7, 0x11, 0xa4, 0x4c, 0x6e, +- 0x17, 0x0f, 0x98, 0x78, 0x93, 0x18, 0x72, 0x39, 0x29, 0xbc, 0x48, 0xf8, +- 0x50, 0x17, 0x7d, 0x4f, 0x19, 0xf9, 0x80, 0x86, 0x6d, 0xe4, 0xeb, 0xbe, +- 0xf8, 0x04, 0xe3, 0x91, 0xaf, 0x93, 0x93, 0x95, 0xb3, 0x9b, 0x1f, 0x70, +- 0xbc, 0x56, 0xec, 0xa4, 0x2d, 0x16, 0x69, 0x77, 0x61, 0x25, 0xf9, 0x8e, +- 0x43, 0xa3, 0xcb, 0x78, 0x58, 0xfc, 0x86, 0xe4, 0x70, 0x54, 0xa9, 0x95, +- 0xad, 0x7d, 0x1d, 0xf7, 0xa2, 0xbd, 0xda, 0x05, 0xa9, 0x6f, 0xbd, 0x81, +- 0x25, 0x48, 0x3d, 0x2a, 0xbe, 0x93, 0x1c, 0x39, 0xac, 0x19, 0xe7, 0x31, +- 0xcf, 0x62, 0xdd, 0xc5, 0x61, 0x99, 0x4f, 0x15, 0x65, 0xaf, 0xe2, 0x1d, +- 0xca, 0xf5, 0x52, 0xd4, 0x37, 0x75, 0x1f, 0x1a, 0x4e, 0x5d, 0xb2, 0x4b, +- 0xed, 0x4f, 0xda, 0x07, 0xa1, 0xb1, 0xbf, 0x4f, 0xa3, 0x21, 0xf4, 0xa9, +- 0x72, 0x2d, 0xfc, 0xb0, 0x15, 0xdd, 0x43, 0x32, 0x07, 0xd3, 0xac, 0x24, +- 0x1e, 0x3e, 0x6c, 0x8d, 0x2f, 0x63, 0xdf, 0x1a, 0x5b, 0x78, 0x19, 0x49, +- 0xe7, 0xe3, 0x8b, 0x49, 0x1c, 0x4e, 0x52, 0xfe, 0x8b, 0xdf, 0xa6, 0x1c, +- 0x26, 0x31, 0x9c, 0xd2, 0xc8, 0x1d, 0x4b, 0xe0, 0xa9, 0x0e, 0x62, 0x17, +- 0xfd, 0x75, 0x8c, 0xed, 0xd3, 0xb1, 0x12, 0x18, 0xd5, 0xd9, 0x31, 0xbf, +- 0x1e, 0xbf, 0x6a, 0x4e, 0x3c, 0x64, 0xc5, 0xa9, 0xbc, 0xfe, 0x1d, 0x9f, +- 0x99, 0x2d, 0xc7, 0x32, 0xb1, 0x3e, 0x76, 0xd9, 0x9c, 0x68, 0x9d, 0xfe, +- 0x7b, 0x85, 0x75, 0xa6, 0x2a, 0x62, 0xab, 0xe6, 0x77, 0x56, 0x2e, 0xdd, +- 0x94, 0xcb, 0x0c, 0xed, 0x2d, 0xf3, 0x41, 0x6b, 0x5e, 0xef, 0xcd, 0x12, +- 0x2e, 0x5f, 0x17, 0xf7, 0xcc, 0x46, 0x71, 0x15, 0xdb, 0x10, 0x43, 0xc3, +- 0x5a, 0xd3, 0x29, 0xfc, 0x8b, 0x79, 0xe1, 0xa6, 0x7e, 0x66, 0xf2, 0x9e, +- 0xf8, 0x9e, 0x0b, 0xb9, 0x9c, 0x8f, 0x3b, 0xc7, 0xf7, 0x27, 0x71, 0x3c, +- 0x29, 0xd8, 0xef, 0xc1, 0x13, 0x92, 0x9b, 0x52, 0xbd, 0xbd, 0x06, 0x26, +- 0xc8, 0xf1, 0xde, 0xa6, 0xec, 0x25, 0xff, 0x38, 0x41, 0x9e, 0x37, 0xdd, +- 0x37, 0x45, 0x90, 0xaa, 0x92, 0x1a, 0x8c, 0xe0, 0xe7, 0x24, 0xb6, 0x27, +- 0x7f, 0x4a, 0x1c, 0xfb, 0x98, 0xbc, 0xa7, 0x8b, 0x9c, 0x7a, 0x12, 0x5b, +- 0x52, 0xcd, 0x78, 0x69, 0x6f, 0x0b, 0x71, 0x45, 0xb0, 0xd1, 0x77, 0xea, +- 0xa2, 0xbd, 0x19, 0xfb, 0x0f, 0xa5, 0x91, 0x1a, 0x11, 0x7f, 0x28, 0x3e, +- 0x57, 0x7c, 0xa1, 0x86, 0x68, 0xe2, 0x24, 0x0c, 0x7e, 0xef, 0x4c, 0x6c, +- 0x44, 0x64, 0xe4, 0x2d, 0xf2, 0xf8, 0x49, 0x2c, 0xef, 0xd3, 0xd6, 0x1e, +- 0xc4, 0x24, 0x56, 0xd1, 0x57, 0x26, 0x13, 0x2d, 0xec, 0xbf, 0x19, 0x3d, +- 0x7b, 0xbd, 0x56, 0xbe, 0x49, 0x62, 0xf8, 0x6d, 0x63, 0x11, 0x18, 0x43, +- 0x72, 0x36, 0xc3, 0x85, 0x60, 0xdc, 0xa3, 0x7c, 0x48, 0x3e, 0xdc, 0x10, +- 0xf7, 0x32, 0x06, 0xf3, 0x1a, 0xab, 0x14, 0x9f, 0xa7, 0xc0, 0x26, 0xb5, +- 0xc0, 0x19, 0x38, 0xa5, 0x2b, 0x28, 0xba, 0x57, 0x41, 0x88, 0xbe, 0xca, +- 0x33, 0x8b, 0x3e, 0x64, 0x48, 0x47, 0xcf, 0x00, 0xd7, 0x7b, 0x7d, 0xdf, +- 0x64, 0xbf, 0x56, 0xb3, 0x3f, 0xd9, 0xbb, 0x16, 0xf4, 0x8c, 0xf9, 0x3a, +- 0x4e, 0xc1, 0x6d, 0x71, 0xab, 0x9e, 0x81, 0xeb, 0x79, 0x81, 0xd2, 0x8f, +- 0x1b, 0xbd, 0x81, 0x19, 0x8a, 0xb4, 0xdd, 0x4a, 0xcc, 0x9a, 0xde, 0xde, +- 0x50, 0x92, 0x8b, 0xc9, 0x3f, 0x6d, 0x62, 0x17, 0xdd, 0x96, 0xbd, 0x88, +- 0x2c, 0x7a, 0x92, 0x11, 0xea, 0xf4, 0x4f, 0xcc, 0x54, 0x6b, 0x2b, 0xe7, +- 0xd9, 0x28, 0xb5, 0x31, 0x0b, 0x13, 0xce, 0x4a, 0x2e, 0xce, 0x29, 0x98, +- 0xd0, 0xdd, 0xee, 0xa2, 0x3e, 0x15, 0x12, 0x97, 0x8a, 0x46, 0x5d, 0x70, +- 0x1d, 0x2c, 0x41, 0xe1, 0xa0, 0xf0, 0x31, 0xc9, 0x41, 0xa8, 0xb0, 0x8f, +- 0x96, 0xd2, 0x06, 0xb8, 0x87, 0xa3, 0xb4, 0xb1, 0xa8, 0x1b, 0xf3, 0x46, +- 0xdd, 0xf8, 0x31, 0x31, 0xa0, 0x66, 0x54, 0xc3, 0x38, 0x31, 0xc0, 0x3d, +- 0x1a, 0xc0, 0x58, 0x34, 0x88, 0x19, 0xa3, 0xe3, 0xca, 0x1b, 0xe9, 0x66, +- 0xee, 0xb7, 0x8c, 0x23, 0x32, 0xcc, 0xef, 0xa9, 0xec, 0x67, 0x0b, 0xb1, +- 0x4e, 0xf6, 0x36, 0x80, 0x1d, 0x03, 0x69, 0x2c, 0xdb, 0x63, 0xe2, 0x9f, +- 0xf4, 0x06, 0x77, 0x91, 0x22, 0xb1, 0x80, 0x89, 0x34, 0xfd, 0xda, 0x0a, +- 0xdd, 0xbb, 0x56, 0xce, 0x3b, 0xb7, 0x57, 0x99, 0x28, 0x08, 0x79, 0x75, +- 0xa2, 0xfb, 0xda, 0x22, 0x45, 0x7c, 0x54, 0x83, 0x67, 0x03, 0xe6, 0x22, +- 0x5b, 0x57, 0xbc, 0x0f, 0x1b, 0x54, 0x85, 0xb6, 0xd8, 0x82, 0x9d, 0x15, +- 0x86, 0xeb, 0x4a, 0xa3, 0x69, 0xae, 0x0b, 0xd5, 0xcd, 0xb2, 0x72, 0xd0, +- 0xb6, 0xf5, 0xfc, 0x6e, 0xe3, 0x9a, 0x65, 0xdd, 0x1d, 0x88, 0xed, 0x56, +- 0x90, 0xf6, 0x77, 0x20, 0x3a, 0xdc, 0x21, 0xfc, 0x89, 0x78, 0xd0, 0x4b, +- 0x3c, 0x30, 0xbb, 0x9e, 0x0e, 0x3d, 0x88, 0xcb, 0x96, 0xc7, 0x97, 0x67, +- 0xbc, 0x01, 0x8f, 0x6d, 0xfa, 0x1e, 0xe8, 0xb3, 0x25, 0xcf, 0x21, 0x76, +- 0xd3, 0xdc, 0x27, 0xbc, 0xd9, 0xdf, 0xdb, 0xc3, 0xbd, 0x7f, 0xe8, 0x80, +- 0xf8, 0x17, 0xd3, 0xec, 0x25, 0x2f, 0x45, 0x85, 0xac, 0x41, 0x43, 0x3c, +- 0x61, 0x7e, 0x5c, 0xa3, 0xf9, 0xa6, 0x76, 0xd1, 0x8f, 0x9f, 0xdf, 0xd3, +- 0xb0, 0x61, 0x83, 0x70, 0x96, 0x45, 0x1a, 0x63, 0xe9, 0x34, 0xce, 0x8d, +- 0xcc, 0x47, 0xea, 0x21, 0xae, 0x87, 0xfb, 0xe4, 0x8c, 0x7f, 0xc1, 0x38, +- 0x43, 0xb0, 0x4f, 0x53, 0x0f, 0x13, 0xf7, 0x6c, 0xa3, 0x7e, 0x6c, 0xa9, +- 0x80, 0x71, 0xa5, 0x51, 0xc6, 0xbf, 0x3e, 0x7f, 0xae, 0xb7, 0x19, 0xbb, +- 0xf6, 0x0a, 0xaf, 0x10, 0xfe, 0xe5, 0x33, 0x3e, 0x40, 0x0b, 0x92, 0x63, +- 0xd9, 0xb1, 0xa2, 0x89, 0x5b, 0xf5, 0x44, 0xf6, 0xfc, 0x24, 0x76, 0x50, +- 0x27, 0x5d, 0xec, 0x9f, 0x3e, 0x85, 0xfd, 0x69, 0x81, 0x22, 0x19, 0x6f, +- 0xf4, 0x27, 0xe6, 0xce, 0x6a, 0x91, 0x8d, 0xf4, 0xff, 0x9b, 0x6a, 0xc1, +- 0x8b, 0x75, 0xa1, 0xaf, 0x5a, 0xeb, 0x15, 0x7e, 0x4b, 0xce, 0x3a, 0x3f, +- 0x1f, 0x79, 0xe6, 0x76, 0xf3, 0xf9, 0x9c, 0xed, 0x64, 0x4e, 0x1d, 0xd8, +- 0xb1, 0x1b, 0x46, 0xb1, 0xa6, 0x45, 0xe6, 0x2b, 0x1d, 0xe8, 0xa5, 0x7c, +- 0xb7, 0x25, 0x3b, 0xb0, 0x9f, 0xf6, 0x3a, 0xa8, 0x1f, 0xab, 0xb1, 0xa1, +- 0x7e, 0xca, 0x8e, 0x89, 0x7f, 0x94, 0x9a, 0xc5, 0x82, 0x45, 0x7e, 0xda, +- 0x56, 0x07, 0xe2, 0xa9, 0x73, 0xb3, 0xad, 0x9a, 0xa8, 0x4d, 0x7c, 0x9e, +- 0xc8, 0xa2, 0x13, 0xc5, 0x7d, 0x27, 0xe1, 0xec, 0xeb, 0x44, 0x91, 0x7f, +- 0x09, 0x56, 0x84, 0x2e, 0x98, 0x97, 0x35, 0x87, 0xfb, 0x38, 0xe5, 0x73, +- 0x2c, 0x58, 0xc3, 0x98, 0x91, 0x71, 0xca, 0xd0, 0x1c, 0xda, 0x7d, 0x23, +- 0x76, 0x8c, 0xc9, 0x59, 0x08, 0x1b, 0x56, 0x2d, 0x96, 0x58, 0x5c, 0xa1, +- 0x5e, 0xcf, 0x62, 0x3c, 0xa9, 0xa9, 0xcf, 0x59, 0xe7, 0x56, 0xc8, 0xb9, +- 0xaa, 0x3c, 0x78, 0xd2, 0x3a, 0xaf, 0x21, 0xf7, 0x37, 0x31, 0x0e, 0xd8, +- 0x84, 0x9a, 0x98, 0x61, 0x8a, 0xbc, 0x8f, 0x23, 0xf2, 0xa2, 0x8d, 0xf3, +- 0x68, 0x5a, 0xe4, 0xdf, 0x30, 0xa5, 0x88, 0x3e, 0xfb, 0xdb, 0x47, 0x15, +- 0xdd, 0xb5, 0x3a, 0xa3, 0x20, 0xd0, 0xc7, 0xbe, 0x42, 0x23, 0xb3, 0xb3, +- 0xb9, 0xf1, 0x3c, 0xbf, 0xdb, 0x44, 0x5e, 0xb0, 0x09, 0x65, 0x31, 0xe1, +- 0xe4, 0x82, 0x0b, 0x91, 0xa5, 0xe5, 0x7c, 0x3e, 0x1d, 0xf2, 0xb7, 0x96, +- 0x2a, 0xc2, 0x7d, 0xfc, 0x4d, 0xab, 0x14, 0xe1, 0x2a, 0xf2, 0x9c, 0xee, +- 0xaa, 0xcf, 0x9c, 0xcf, 0xd5, 0x31, 0x1b, 0x89, 0x0d, 0x72, 0xce, 0x24, +- 0x7f, 0xd6, 0xea, 0x46, 0xce, 0xda, 0x19, 0x97, 0xd8, 0xe1, 0x68, 0x68, +- 0x59, 0xb4, 0x89, 0x38, 0x67, 0x2e, 0x39, 0x44, 0xbd, 0xbf, 0x88, 0x2a, +- 0xfc, 0x73, 0x54, 0x30, 0xcd, 0x83, 0x9f, 0x47, 0x0b, 0x25, 0x26, 0x4e, +- 0x49, 0x5e, 0xf6, 0x4c, 0xd2, 0x30, 0x29, 0xd7, 0x96, 0x55, 0xd4, 0xa5, +- 0x40, 0xa8, 0x14, 0xa8, 0xee, 0x7e, 0xd2, 0x69, 0xc5, 0xe8, 0x65, 0xa8, +- 0x20, 0xfe, 0xf7, 0x0d, 0xfd, 0xa1, 0xf3, 0x0e, 0xc4, 0xe0, 0x62, 0xc9, +- 0x15, 0xda, 0xb1, 0x2d, 0xf4, 0x1b, 0x33, 0xd5, 0x26, 0xcf, 0xd4, 0xe2, +- 0xdc, 0x6e, 0xd1, 0xd3, 0x00, 0x0a, 0xe3, 0xe7, 0xa9, 0x93, 0x2a, 0xce, +- 0x46, 0x7d, 0xfa, 0x1a, 0xdb, 0xb7, 0xa8, 0xff, 0xf3, 0x6e, 0xc2, 0xed, +- 0x79, 0xda, 0x03, 0x78, 0xdc, 0xc2, 0xed, 0x30, 0xb6, 0xd0, 0x2f, 0x90, +- 0xb7, 0xed, 0x7b, 0xd2, 0xa6, 0xd2, 0x9f, 0xfb, 0x54, 0x1f, 0x63, 0xea, +- 0x2d, 0x1c, 0x43, 0xf8, 0xe4, 0x4c, 0xf2, 0xbd, 0xa7, 0xa3, 0x0d, 0x9e, +- 0x5f, 0xe3, 0x09, 0xda, 0xa3, 0x8c, 0x21, 0x6b, 0xd2, 0x50, 0xca, 0xd8, +- 0xf1, 0x04, 0xd7, 0xb1, 0xad, 0x22, 0x3b, 0x6e, 0x79, 0xae, 0xef, 0xf8, +- 0x90, 0xf0, 0xad, 0x7b, 0xb0, 0xc6, 0xea, 0x3b, 0x68, 0xd9, 0xe6, 0xbe, +- 0xa8, 0x82, 0x19, 0xf5, 0x1a, 0x12, 0xe9, 0x66, 0x6c, 0xac, 0xac, 0xc5, +- 0xfe, 0xc4, 0x26, 0x2c, 0x24, 0xe7, 0x7d, 0xa4, 0xd2, 0xa0, 0x5f, 0x24, +- 0x06, 0xc5, 0x35, 0x75, 0xbe, 0xf2, 0x8d, 0x5c, 0xae, 0xba, 0x0a, 0x8e, +- 0xb8, 0xf8, 0xbb, 0x02, 0xf4, 0xab, 0x73, 0x51, 0x62, 0x9d, 0x81, 0xcc, +- 0xf6, 0xbd, 0x6b, 0xc8, 0x9b, 0xf3, 0x81, 0x44, 0x8d, 0xb8, 0x75, 0x4e, +- 0x25, 0xf0, 0x3c, 0x79, 0x44, 0x8a, 0xde, 0xaf, 0x20, 0xac, 0xa5, 0xd6, +- 0xa3, 0x08, 0xc6, 0x2c, 0xc1, 0x43, 0x79, 0x66, 0xce, 0x2d, 0x73, 0xaa, +- 0xcc, 0xcd, 0x29, 0x7f, 0xff, 0x34, 0xef, 0x89, 0x6e, 0x09, 0xb7, 0x90, +- 0xdf, 0x8b, 0xd1, 0x4a, 0x7d, 0xaa, 0xe2, 0x9c, 0x13, 0x09, 0xb9, 0xef, +- 0xd5, 0x0d, 0x5b, 0x23, 0x3e, 0xdb, 0x93, 0xd5, 0xc1, 0xb5, 0x75, 0xdc, +- 0xff, 0xf2, 0x46, 0x4c, 0x8d, 0x88, 0x2f, 0xfb, 0xc3, 0x67, 0x50, 0x8c, +- 0xeb, 0x67, 0x50, 0x44, 0xae, 0xde, 0x53, 0xef, 0xa0, 0x61, 0xe2, 0x31, +- 0xdb, 0x61, 0x13, 0x33, 0x45, 0xc6, 0x71, 0xb7, 0xc4, 0x9a, 0x36, 0x72, +- 0x08, 0x23, 0x3d, 0xee, 0x16, 0x3f, 0xe9, 0x88, 0x03, 0xf3, 0xe2, 0x06, +- 0x0a, 0xc3, 0xda, 0xbe, 0x2b, 0xf6, 0x6b, 0x66, 0xfb, 0xac, 0x39, 0x8c, +- 0xf9, 0x6e, 0xac, 0xb9, 0x97, 0x73, 0xb7, 0x6b, 0x3f, 0x31, 0xef, 0xab, +- 0x92, 0x39, 0xfe, 0xd2, 0x9d, 0x3d, 0xfb, 0x70, 0x07, 0xe5, 0x92, 0x97, +- 0x89, 0x49, 0xfd, 0xf9, 0x2b, 0xf3, 0x9b, 0x37, 0xdd, 0x17, 0x2e, 0x23, +- 0x7a, 0x3a, 0xfd, 0x3c, 0xa0, 0xe8, 0xac, 0xd4, 0x56, 0x26, 0x71, 0x28, +- 0x29, 0xba, 0x2b, 0x32, 0x8e, 0xe0, 0x22, 0x79, 0x61, 0x41, 0xff, 0x24, +- 0x06, 0xc9, 0x0b, 0xed, 0x71, 0xef, 0x3e, 0x4a, 0x12, 0x1b, 0xd5, 0x25, +- 0xc4, 0xea, 0x32, 0xce, 0x23, 0x3f, 0x87, 0x3a, 0x4b, 0xee, 0xe2, 0x5f, +- 0x76, 0x72, 0xbd, 0x45, 0xe4, 0x48, 0xcd, 0xb1, 0x42, 0x68, 0x15, 0xe5, +- 0x28, 0xd5, 0xe4, 0x0c, 0x7c, 0xb6, 0x5d, 0x94, 0x73, 0x29, 0xd1, 0xe6, +- 0x62, 0x95, 0xd5, 0xd6, 0x63, 0x9d, 0x01, 0xd1, 0x2a, 0xc5, 0xff, 0x8a, +- 0xcf, 0x25, 0xdf, 0x5e, 0x2c, 0x3e, 0x37, 0xcc, 0xb9, 0xcd, 0xc9, 0xd5, +- 0x99, 0x56, 0x59, 0xf7, 0xf7, 0x25, 0x2e, 0x7c, 0xd9, 0x9f, 0xf8, 0x3d, +- 0x9f, 0xe9, 0x80, 0xba, 0xb7, 0x18, 0x0f, 0xfd, 0x65, 0x09, 0xf4, 0xca, +- 0x6c, 0xae, 0x7c, 0x5e, 0x38, 0x1a, 0x32, 0x13, 0xc2, 0x93, 0xee, 0x84, +- 0x67, 0xb6, 0x8c, 0x25, 0x18, 0x20, 0x7b, 0x21, 0x7b, 0x27, 0x39, 0xdc, +- 0xdb, 0xd5, 0x18, 0xbc, 0xea, 0xc4, 0xf5, 0x7d, 0x98, 0x0f, 0xed, 0xe1, +- 0x2a, 0xae, 0x2d, 0xeb, 0x23, 0x76, 0xd0, 0x47, 0x04, 0xfc, 0x59, 0x0c, +- 0x93, 0x1a, 0xbd, 0x93, 0x3e, 0x62, 0x84, 0x3e, 0xe2, 0xa2, 0x5e, 0x8e, +- 0xe5, 0x39, 0x1f, 0xd1, 0x6e, 0xd3, 0xad, 0xfe, 0x9d, 0xda, 0x7d, 0x35, +- 0xc4, 0x30, 0x8e, 0xf1, 0xb5, 0x9b, 0xb8, 0xd8, 0x4c, 0xed, 0x97, 0xe6, +- 0x23, 0x55, 0xb2, 0xc6, 0xe6, 0x9a, 0x6c, 0x8e, 0xbc, 0x03, 0xfb, 0x88, +- 0x8f, 0x35, 0x9a, 0x3c, 0xa3, 0x25, 0x6b, 0xec, 0x1d, 0xe8, 0x67, 0xff, +- 0x7d, 0xc4, 0xc8, 0x18, 0x31, 0x52, 0x5f, 0x78, 0xec, 0x45, 0x15, 0xf5, +- 0x1d, 0x64, 0x0f, 0xdf, 0x16, 0x6c, 0x79, 0x99, 0xd8, 0xf2, 0x3c, 0x31, +- 0x72, 0x67, 0x4a, 0xc6, 0x91, 0xf1, 0xf2, 0xe3, 0x48, 0x9f, 0xff, 0x66, +- 0xae, 0xaf, 0x92, 0xb9, 0xde, 0x6e, 0x1e, 0xf2, 0xdb, 0x9f, 0xf2, 0xef, +- 0x62, 0x8b, 0x43, 0xf5, 0x26, 0xa6, 0x9f, 0xa9, 0x98, 0x24, 0xbe, 0x5a, +- 0x71, 0x00, 0xfd, 0x6b, 0x04, 0x2b, 0x17, 0xab, 0xb8, 0x1c, 0x9d, 0x44, +- 0xd1, 0x81, 0x3c, 0x16, 0x99, 0x4b, 0x4e, 0x10, 0x87, 0x06, 0x21, 0xd8, +- 0xd3, 0xc4, 0x3d, 0x30, 0x68, 0x13, 0x65, 0x18, 0x4d, 0xca, 0xd9, 0x0b, +- 0x13, 0xbb, 0x42, 0x2e, 0x72, 0xd8, 0xee, 0xe3, 0x05, 0x96, 0x4f, 0x28, +- 0x23, 0x5e, 0xe7, 0xf9, 0xb5, 0x70, 0x6b, 0xc1, 0x1a, 0xc6, 0x11, 0x43, +- 0x76, 0x14, 0x2c, 0xca, 0xc6, 0x0e, 0xe7, 0xda, 0xa4, 0x5d, 0x2d, 0x06, +- 0x77, 0x8b, 0xae, 0xf9, 0x50, 0xa3, 0x9d, 0x67, 0x2c, 0x01, 0xbc, 0x1b, +- 0xb5, 0xdd, 0xe9, 0x22, 0x07, 0xee, 0xd2, 0x17, 0xe3, 0xda, 0xcc, 0x2d, +- 0xb4, 0x6f, 0x37, 0x7f, 0x9b, 0xc0, 0xc1, 0xa8, 0x0b, 0x05, 0x56, 0x8d, +- 0xb2, 0x9c, 0xeb, 0xc9, 0xea, 0xcb, 0x36, 0xea, 0x4b, 0x21, 0x63, 0xb3, +- 0x15, 0x96, 0x5d, 0x4a, 0x3f, 0x93, 0xd6, 0xbb, 0x32, 0xda, 0x62, 0xe1, +- 0xad, 0x41, 0xfa, 0xc0, 0x32, 0xc4, 0xfb, 0xba, 0x70, 0x36, 0x54, 0x86, +- 0xd8, 0x01, 0xb1, 0xa7, 0x5a, 0xc1, 0x4d, 0x8e, 0xdb, 0x44, 0xf9, 0xa8, +- 0xc4, 0x95, 0x86, 0x4e, 0xbb, 0xbd, 0x0c, 0x17, 0x2a, 0x18, 0xaf, 0x5a, +- 0xef, 0x13, 0xb5, 0x62, 0x7f, 0x6e, 0x8f, 0x54, 0xf2, 0x9b, 0xd6, 0xeb, +- 0x7c, 0x39, 0xbf, 0x96, 0xbc, 0x7d, 0x66, 0x6b, 0xe4, 0x3d, 0xe4, 0x30, +- 0x2f, 0x49, 0x3e, 0xc8, 0xe6, 0xa3, 0xdf, 0x60, 0x5c, 0x34, 0x26, 0xb2, +- 0xce, 0xeb, 0xd6, 0xeb, 0x35, 0xd9, 0x33, 0x3d, 0xf9, 0x3d, 0xc8, 0x5f, +- 0x6b, 0x6b, 0x8b, 0x95, 0x5f, 0x98, 0xcf, 0x56, 0xcb, 0xfc, 0xae, 0x32, +- 0x0e, 0xfb, 0x31, 0x7f, 0x5f, 0x86, 0x9e, 0xa1, 0xe9, 0x7e, 0x41, 0x6c, +- 0xce, 0x73, 0xd3, 0xd9, 0xc3, 0x8a, 0xb8, 0xbc, 0xbf, 0x75, 0x34, 0xf4, +- 0x24, 0xf7, 0xc1, 0xbf, 0xb0, 0xc1, 0xca, 0xa5, 0x90, 0xe3, 0x32, 0xfe, +- 0x10, 0x3c, 0x35, 0xe8, 0xcf, 0xcb, 0xf0, 0xb3, 0xa4, 0xf8, 0x57, 0x13, +- 0x85, 0xa1, 0x12, 0xfa, 0xbb, 0xee, 0xe7, 0x2a, 0x2c, 0xce, 0x5c, 0x86, +- 0x4a, 0xea, 0x5e, 0xff, 0xd0, 0xed, 0xf4, 0xfc, 0x86, 0x0f, 0x48, 0x87, +- 0x14, 0x62, 0xc2, 0x6f, 0xcc, 0x5d, 0x8f, 0x66, 0x9f, 0x39, 0x97, 0x74, +- 0xe1, 0xa3, 0x50, 0x3b, 0x26, 0x2a, 0xc2, 0x18, 0x48, 0x14, 0xa1, 0x7d, +- 0x56, 0xbd, 0xf5, 0xce, 0x45, 0x4d, 0xdc, 0x83, 0xf3, 0x51, 0x27, 0x9a, +- 0x66, 0x7b, 0xac, 0x7c, 0x92, 0x8d, 0x76, 0xf1, 0x76, 0x34, 0x42, 0x5f, +- 0xe0, 0xb9, 0xc9, 0x3f, 0x14, 0x68, 0x8b, 0x70, 0x7f, 0x0e, 0xc3, 0xf7, +- 0x27, 0x3e, 0x27, 0xc6, 0x94, 0x1b, 0x33, 0xc3, 0x65, 0xb8, 0x7b, 0x40, +- 0xce, 0x29, 0x48, 0x9d, 0x4a, 0x9b, 0x9a, 0xaf, 0x94, 0x61, 0xc9, 0x90, +- 0xe0, 0xb9, 0x9c, 0xfd, 0x48, 0x87, 0x5c, 0xb1, 0x36, 0xee, 0x51, 0x27, +- 0xea, 0xf7, 0x5a, 0x72, 0x55, 0xed, 0x8a, 0xd9, 0x75, 0x49, 0x8f, 0xe8, +- 0xf4, 0x67, 0x9d, 0xf7, 0x53, 0xef, 0xa7, 0x42, 0xde, 0xf6, 0x99, 0x76, +- 0xad, 0xe3, 0x57, 0x4a, 0x10, 0xa3, 0x19, 0xa0, 0x6f, 0x24, 0x80, 0x0f, +- 0x12, 0xc2, 0xed, 0x03, 0x78, 0x7f, 0x2c, 0x88, 0x77, 0xe8, 0x87, 0x8a, +- 0xe2, 0xde, 0xc8, 0x33, 0x8c, 0xdd, 0xde, 0xe5, 0x75, 0x61, 0x5c, 0xc7, +- 0x15, 0xca, 0xcf, 0x19, 0x6f, 0xc4, 0xa5, 0xb1, 0x6f, 0xe0, 0xf2, 0x5e, +- 0x05, 0xc7, 0xb4, 0x6f, 0xe0, 0xe2, 0xa1, 0x4e, 0x2c, 0xda, 0x2b, 0x67, +- 0xf5, 0x8e, 0x86, 0x54, 0xfa, 0x81, 0x27, 0xeb, 0xcc, 0xae, 0x17, 0xf4, +- 0x7a, 0x62, 0x86, 0x57, 0x6f, 0x67, 0x6c, 0x24, 0xf8, 0x1d, 0xb1, 0xc9, +- 0x9e, 0xc9, 0xde, 0x75, 0xe2, 0xb2, 0x85, 0xd9, 0xb7, 0xc7, 0x89, 0x1b, +- 0x78, 0x2d, 0xe3, 0x88, 0x6d, 0xdf, 0x81, 0x57, 0x19, 0x94, 0x6e, 0x61, +- 0x3b, 0x17, 0x71, 0xee, 0xe9, 0x68, 0x11, 0x0a, 0xab, 0xcb, 0x2d, 0x7b, +- 0x2b, 0x8e, 0x07, 0x70, 0x9a, 0xb2, 0x5b, 0x59, 0xed, 0xe5, 0xb5, 0xf8, +- 0xd8, 0x20, 0xe3, 0x93, 0x99, 0xf8, 0xe0, 0x26, 0xdf, 0xfa, 0xaa, 0x85, +- 0x0d, 0x0e, 0xed, 0x81, 0x39, 0x59, 0x6c, 0x20, 0xa0, 0x13, 0x93, 0x25, +- 0x27, 0x58, 0xae, 0x69, 0x1b, 0xbe, 0x4b, 0x1b, 0x4f, 0x87, 0x8e, 0xfd, +- 0x49, 0x29, 0x39, 0xf0, 0x0b, 0xa1, 0x7a, 0xa3, 0x02, 0x2b, 0x78, 0x7f, +- 0x62, 0x91, 0x8a, 0x75, 0xfc, 0xf6, 0xb3, 0x5d, 0x90, 0xf3, 0xb8, 0x6a, +- 0xa6, 0x54, 0x1f, 0xff, 0xae, 0xa5, 0x2f, 0xdf, 0x84, 0xb3, 0xb1, 0x86, +- 0xf6, 0x11, 0xe5, 0x8a, 0x69, 0x54, 0xd7, 0xf1, 0xb7, 0x2a, 0x9c, 0x8b, +- 0x7a, 0x27, 0x0e, 0xa1, 0xc1, 0x33, 0xa5, 0xec, 0x37, 0x0d, 0x55, 0xf6, +- 0x47, 0xd6, 0x2b, 0xcf, 0xdf, 0xc5, 0xfb, 0x17, 0xa6, 0xe9, 0xe1, 0x8d, +- 0xf8, 0xca, 0x79, 0x5d, 0xff, 0x84, 0x83, 0x98, 0x4b, 0x86, 0xf5, 0x06, +- 0x75, 0x0b, 0xb1, 0x20, 0xa2, 0xde, 0x4e, 0xff, 0x8a, 0xa8, 0x7f, 0x61, +- 0xc6, 0x8b, 0x65, 0x50, 0x2d, 0x5f, 0xd4, 0x8a, 0xe4, 0xd0, 0x74, 0x1e, +- 0x29, 0x7a, 0x97, 0xe5, 0xa4, 0xed, 0x15, 0xdd, 0xc7, 0x9d, 0xf4, 0x87, +- 0x09, 0x62, 0x78, 0x9c, 0x18, 0x5e, 0x48, 0x0c, 0xbf, 0xba, 0xa7, 0x18, +- 0x67, 0xf7, 0x34, 0x21, 0x5d, 0x21, 0xcf, 0xd8, 0xe1, 0xe4, 0xea, 0x52, +- 0x96, 0x6f, 0xb7, 0xa1, 0xa6, 0x7f, 0xa9, 0x9c, 0x75, 0x85, 0xf8, 0xd0, +- 0x82, 0x38, 0x11, 0xb1, 0xd5, 0x0e, 0x87, 0xf5, 0x7e, 0xc1, 0x8c, 0x9b, +- 0xf4, 0xcf, 0xa5, 0x15, 0xa2, 0xa5, 0x4a, 0xf0, 0xe1, 0xe2, 0x1c, 0xf1, +- 0x99, 0x3f, 0xe5, 0x5c, 0x8e, 0x53, 0xa7, 0x9f, 0xd2, 0xef, 0x91, 0x1a, +- 0x1d, 0xdb, 0xcb, 0x73, 0x12, 0xc3, 0x98, 0xd8, 0x41, 0x0d, 0xab, 0xaf, +- 0x36, 0x91, 0xd0, 0xc3, 0xf4, 0x4f, 0x21, 0x44, 0x2a, 0x82, 0xf4, 0x4b, +- 0x72, 0xad, 0xe2, 0x12, 0xe3, 0xaf, 0x4c, 0x50, 0xc1, 0x47, 0x5f, 0x13, +- 0xbf, 0xef, 0xd7, 0xcf, 0x2a, 0xa7, 0x67, 0x65, 0xdf, 0x6b, 0x10, 0x8c, +- 0x28, 0xb7, 0x30, 0xa2, 0xd0, 0xe2, 0x40, 0xb3, 0x2d, 0x6c, 0xf1, 0xd8, +- 0xe4, 0x4c, 0x51, 0x34, 0x74, 0x6f, 0xa2, 0x61, 0xc2, 0x67, 0x27, 0x1f, +- 0xfb, 0xe3, 0xaf, 0x91, 0x87, 0x59, 0x7c, 0x60, 0xba, 0xdf, 0x69, 0x02, +- 0xa6, 0xcb, 0x23, 0x7f, 0x76, 0xd9, 0x93, 0xc5, 0xca, 0x72, 0xe1, 0x6d, +- 0xff, 0xcf, 0x6c, 0xbd, 0x69, 0xfe, 0x79, 0x1c, 0xf9, 0x25, 0xaf, 0xe5, +- 0x79, 0xb1, 0x3b, 0xea, 0x45, 0xfc, 0x1f, 0xcd, 0xc7, 0x2d, 0xee, 0x76, +- 0x6c, 0x8e, 0x9c, 0xcb, 0x74, 0xf4, 0xff, 0xfd, 0x1c, 0x79, 0x9f, 0xc1, +- 0x36, 0x8d, 0x03, 0x64, 0xfd, 0xea, 0x3b, 0xe6, 0x2a, 0x6b, 0xae, 0xa7, +- 0x73, 0xed, 0x24, 0x56, 0x96, 0xb9, 0x28, 0xf8, 0x81, 0xd6, 0xa0, 0x9e, +- 0x46, 0xa9, 0xe0, 0x49, 0x44, 0xea, 0x91, 0xc5, 0x9a, 0xcf, 0x7d, 0x90, +- 0xdf, 0xbb, 0x78, 0xff, 0x35, 0xcd, 0xd1, 0xf4, 0x2c, 0xa4, 0x06, 0x6b, +- 0xe3, 0x5e, 0x35, 0xb8, 0x4f, 0xc3, 0x1f, 0x29, 0x54, 0xa6, 0xcc, 0xf6, +- 0x2a, 0x69, 0x93, 0xad, 0xc5, 0x42, 0x39, 0x6f, 0xe5, 0x49, 0xb2, 0x3a, +- 0x53, 0x4b, 0x9d, 0x11, 0xec, 0x12, 0xde, 0xb1, 0x80, 0x6b, 0x57, 0x31, +- 0x34, 0x26, 0x1c, 0xc1, 0x65, 0xf1, 0x20, 0xb5, 0xae, 0xce, 0xb3, 0x1e, +- 0xca, 0x5c, 0x62, 0x2c, 0xb6, 0xea, 0xb8, 0xd3, 0x86, 0xb7, 0xee, 0xb4, +- 0x85, 0x97, 0xfe, 0xd9, 0xfd, 0x8d, 0x77, 0xcf, 0x95, 0x77, 0x5f, 0xc8, +- 0xe6, 0x24, 0x2f, 0xeb, 0x96, 0xba, 0xe1, 0x72, 0xf2, 0xaa, 0x41, 0xc6, +- 0xf2, 0xcb, 0x83, 0xbf, 0x33, 0xbf, 0xed, 0x88, 0x78, 0xec, 0xa8, 0xf3, +- 0xf4, 0xe0, 0x9a, 0x99, 0xaa, 0xb2, 0xee, 0xcf, 0x95, 0xf7, 0x0d, 0x9c, +- 0xd2, 0x3f, 0xb9, 0xc8, 0xdd, 0x75, 0x26, 0xe3, 0x64, 0xdb, 0x32, 0x3b, +- 0xed, 0x82, 0x32, 0x33, 0xeb, 0x67, 0xd5, 0xb9, 0x6d, 0x4a, 0x3d, 0xb5, +- 0xa3, 0x0a, 0x47, 0xa8, 0xbf, 0x47, 0xc6, 0xc4, 0xff, 0xa9, 0x38, 0x4c, +- 0x3b, 0x3d, 0x54, 0xef, 0xeb, 0xbc, 0xcc, 0xb8, 0xf1, 0x43, 0xf2, 0xf9, +- 0x37, 0x34, 0x6f, 0xfb, 0x29, 0xc9, 0x29, 0x86, 0x1c, 0x38, 0x13, 0xbc, +- 0x66, 0xe5, 0x78, 0x63, 0x07, 0x54, 0x0c, 0x26, 0xb2, 0xf6, 0xfe, 0x0a, +- 0xed, 0xf8, 0xc6, 0x99, 0x03, 0x1d, 0x5b, 0x06, 0xc4, 0x3e, 0x1a, 0x2d, +- 0x3b, 0xba, 0x91, 0x13, 0x12, 0xbc, 0x16, 0xbb, 0x78, 0x42, 0x6a, 0x71, +- 0x46, 0x0a, 0x0e, 0xca, 0x77, 0x39, 0xf9, 0xae, 0xf8, 0xd8, 0x00, 0x63, +- 0x5b, 0x07, 0xed, 0xe7, 0x14, 0xe3, 0x0c, 0xce, 0x2d, 0x6c, 0x9a, 0xef, +- 0x30, 0xee, 0x1a, 0x42, 0x83, 0x7a, 0x02, 0x6b, 0xc8, 0x59, 0xc9, 0x67, +- 0xc6, 0x9a, 0xb1, 0xd3, 0x8a, 0x9b, 0x7c, 0xea, 0x0a, 0x65, 0x21, 0xd7, +- 0xdf, 0x8c, 0xee, 0x43, 0xb5, 0xe4, 0x35, 0xa6, 0xb9, 0x5a, 0xff, 0x73, +- 0x54, 0x0e, 0x74, 0x77, 0x56, 0x52, 0x1e, 0x9f, 0x86, 0x8c, 0x0e, 0x62, +- 0xfa, 0x86, 0x13, 0x4a, 0xc3, 0xda, 0x98, 0xf2, 0x6d, 0xee, 0x87, 0xe4, +- 0x41, 0x3c, 0x8c, 0xc7, 0x57, 0xd3, 0x9f, 0xfd, 0x0f, 0xec, 0x50, 0x95, +- 0x25, 0xb6, 0xb0, 0xf0, 0x41, 0xf8, 0xd5, 0xb0, 0x76, 0xea, 0xa2, 0x7d, +- 0x33, 0xbd, 0x4f, 0x23, 0xef, 0x89, 0x5f, 0x97, 0xb6, 0x72, 0xb6, 0xbe, +- 0x13, 0xc7, 0xd3, 0xd4, 0xeb, 0x68, 0x2f, 0x4e, 0xa4, 0x65, 0x4c, 0xe1, +- 0x53, 0x01, 0xc4, 0x06, 0xec, 0x18, 0xd5, 0x7d, 0x91, 0x72, 0xca, 0xa5, +- 0x38, 0xe4, 0x8d, 0xac, 0x51, 0x02, 0xe4, 0x6d, 0x69, 0x9c, 0xd9, 0xed, +- 0x6d, 0xaf, 0x67, 0x8c, 0x18, 0x1d, 0x83, 0xfa, 0xcc, 0xe2, 0x34, 0x4e, +- 0x0f, 0x3f, 0x04, 0xcf, 0x2c, 0xaf, 0x67, 0xb9, 0xd2, 0x82, 0xad, 0x63, +- 0xff, 0x51, 0x2e, 0xc9, 0xc3, 0xb1, 0x5b, 0x60, 0x50, 0xf6, 0xdb, 0xd1, +- 0x3f, 0x57, 0x6c, 0xbe, 0x67, 0xac, 0x14, 0xf3, 0xe8, 0x8f, 0x5e, 0xb2, +- 0xfc, 0x6c, 0xd6, 0x8e, 0x6a, 0xb4, 0x8f, 0xcc, 0xc7, 0x72, 0x3e, 0xfc, +- 0xab, 0xe5, 0xf5, 0x77, 0x66, 0x44, 0x15, 0x79, 0xc9, 0x73, 0x35, 0x28, +- 0x62, 0x3f, 0x3b, 0x72, 0xfe, 0xba, 0x42, 0xfb, 0xbf, 0xe6, 0x43, 0x56, +- 0x1f, 0x4f, 0xcd, 0x95, 0xa0, 0x60, 0x9b, 0x15, 0xd3, 0xcb, 0xba, 0x75, +- 0x7c, 0x16, 0x95, 0x9c, 0x86, 0x8a, 0x13, 0xba, 0xe0, 0x48, 0x0b, 0x6d, +- 0xd5, 0x89, 0x0d, 0x41, 0x9a, 0xa3, 0x95, 0xcf, 0x9f, 0xc4, 0xce, 0xe4, +- 0xbf, 0x9b, 0xcf, 0x51, 0x8f, 0x56, 0x92, 0xc3, 0x78, 0x88, 0x03, 0x4f, +- 0x85, 0x56, 0x93, 0x73, 0x72, 0xcd, 0x09, 0x07, 0x31, 0x48, 0x41, 0xa2, +- 0x89, 0xf6, 0x1f, 0x5a, 0x80, 0x09, 0xab, 0x7d, 0xd5, 0xdc, 0x6c, 0x0e, +- 0xf1, 0x83, 0xb9, 0xd9, 0x38, 0x50, 0xe4, 0xff, 0x9f, 0x91, 0xdf, 0x2b, +- 0xa6, 0xa7, 0x52, 0xe4, 0xe7, 0x80, 0x9b, 0x7e, 0x6b, 0x1f, 0xdb, 0x9c, +- 0xdb, 0xed, 0x40, 0xbf, 0xd6, 0x82, 0xfe, 0x31, 0x78, 0x3e, 0x65, 0x9b, +- 0x7f, 0x1a, 0x1e, 0x98, 0x9b, 0xe5, 0x0a, 0x6f, 0xa1, 0x3b, 0xfa, 0xbc, +- 0xb9, 0xac, 0x52, 0xd6, 0xeb, 0x84, 0x9b, 0xeb, 0xdd, 0x77, 0x3d, 0x9f, +- 0xb7, 0xde, 0x7c, 0xd8, 0xf2, 0x13, 0xbb, 0xe7, 0x4a, 0xbd, 0xec, 0xa7, +- 0x09, 0x13, 0x97, 0xf4, 0xa3, 0x56, 0x1c, 0x2e, 0xd8, 0xd0, 0x93, 0x90, +- 0xbd, 0x95, 0xb9, 0x6d, 0xcd, 0xc9, 0xe3, 0xff, 0x54, 0xdf, 0x3c, 0xef, +- 0x65, 0x39, 0x5d, 0x96, 0x5a, 0x75, 0x9e, 0xe3, 0x8b, 0x2e, 0x8b, 0x1e, +- 0x5b, 0xef, 0xfd, 0x24, 0xe5, 0xfd, 0xd9, 0x27, 0xd4, 0xdf, 0x73, 0x0c, +- 0xc9, 0xa9, 0xb4, 0xb0, 0x0f, 0xd3, 0x5c, 0xaf, 0x37, 0x78, 0x4e, 0xe0, +- 0x8f, 0xa8, 0xdb, 0x3a, 0xb6, 0x0f, 0x48, 0xbe, 0xd5, 0xa3, 0x38, 0xf6, +- 0xac, 0xc1, 0x25, 0xfa, 0xff, 0x9d, 0x96, 0x1e, 0x0a, 0xae, 0xc8, 0x3c, +- 0x04, 0x5b, 0xda, 0xe8, 0xc7, 0xad, 0xb3, 0x2e, 0x91, 0x9a, 0x70, 0xa7, +- 0xf2, 0x61, 0x7d, 0x27, 0x8e, 0x86, 0x0c, 0xb3, 0x5c, 0xf3, 0xaf, 0x65, +- 0xd0, 0x5f, 0x34, 0xd6, 0x58, 0x88, 0xf1, 0x90, 0xf0, 0x47, 0xb8, 0xd2, +- 0x69, 0xaf, 0x31, 0xc3, 0xae, 0xba, 0x5e, 0x4e, 0xe7, 0xb0, 0xd2, 0xf6, +- 0xc0, 0x5c, 0x89, 0x97, 0x92, 0x16, 0x8e, 0x7c, 0x1d, 0xf7, 0x59, 0x7b, +- 0xab, 0xd2, 0x87, 0x4a, 0xbe, 0xf7, 0x68, 0xe8, 0x4a, 0x54, 0x30, 0xc5, +- 0x5c, 0xd2, 0x1c, 0x6a, 0x50, 0xb7, 0xe3, 0x4e, 0x62, 0xd7, 0x12, 0x9c, +- 0xd1, 0xa5, 0xae, 0x61, 0x7c, 0xdb, 0x01, 0xa9, 0xc1, 0x1d, 0x0e, 0x6d, +- 0x8d, 0x2e, 0xc5, 0xbe, 0x01, 0x43, 0x71, 0x86, 0xbd, 0x91, 0x18, 0xb9, +- 0x10, 0xe3, 0x71, 0x2b, 0xdf, 0x27, 0xf9, 0x84, 0xc1, 0xc6, 0x4e, 0x6c, +- 0xd7, 0x0b, 0xd1, 0xa3, 0x47, 0x8a, 0xb6, 0x2c, 0xee, 0xc2, 0x7e, 0xbd, +- 0xd4, 0x98, 0x17, 0x36, 0x88, 0xe9, 0xda, 0x86, 0x24, 0xfc, 0x2d, 0x17, +- 0xc9, 0x39, 0x8e, 0xc3, 0xdb, 0xb1, 0xc4, 0x4e, 0xcc, 0xbd, 0xc7, 0xe1, +- 0x8a, 0x65, 0x9a, 0x90, 0x18, 0xab, 0x72, 0xed, 0xc8, 0x04, 0x11, 0x1f, +- 0xe3, 0x7e, 0x33, 0xae, 0x75, 0x64, 0x96, 0x92, 0x83, 0x8a, 0x1c, 0xed, +- 0xd4, 0xc5, 0x7a, 0x3c, 0xd3, 0x7a, 0xc1, 0x7c, 0xd2, 0x2f, 0xf8, 0x59, +- 0x8b, 0x67, 0x55, 0x9f, 0xc5, 0x29, 0x23, 0xb6, 0xaf, 0xb2, 0x0f, 0x3b, +- 0x75, 0xee, 0x55, 0xd3, 0xf3, 0xa8, 0xc8, 0x8d, 0xc1, 0x56, 0xf1, 0x6a, +- 0xe2, 0xa7, 0xfc, 0x2d, 0xb2, 0x13, 0x19, 0x9a, 0x58, 0xa7, 0x4b, 0x2e, +- 0xaf, 0x91, 0x36, 0xe3, 0xc6, 0xdb, 0xea, 0x8d, 0x7d, 0x78, 0x5a, 0xf7, +- 0xe9, 0x87, 0x20, 0x39, 0xbc, 0xff, 0xce, 0xe7, 0x24, 0xdf, 0xd2, 0x84, +- 0x17, 0x2b, 0xb2, 0xf1, 0x87, 0xc7, 0x56, 0x42, 0xdc, 0xcd, 0xfb, 0x11, +- 0xb9, 0xef, 0x4d, 0x46, 0xa8, 0xa7, 0x1b, 0x83, 0x53, 0x66, 0xa4, 0xd2, +- 0xe8, 0x94, 0xb3, 0x28, 0xee, 0xf0, 0xea, 0x17, 0xdd, 0xf5, 0xde, 0x8e, +- 0x29, 0x05, 0x38, 0x13, 0xa3, 0x1f, 0xb6, 0xfe, 0xbb, 0x47, 0xe9, 0xdb, +- 0x89, 0xa1, 0xe0, 0x1d, 0x68, 0x6f, 0x93, 0xb1, 0x9a, 0xd1, 0xbb, 0xd7, +- 0x34, 0x4b, 0x43, 0x3e, 0x35, 0x0d, 0x27, 0x56, 0x04, 0xed, 0xb8, 0xa0, +- 0x9a, 0x70, 0x84, 0xfe, 0xdd, 0xcc, 0xd0, 0x3f, 0x0e, 0xd3, 0x4e, 0x76, +- 0x50, 0xc7, 0xe4, 0x5d, 0x28, 0x3f, 0xed, 0x24, 0x4e, 0x3b, 0x39, 0x13, +- 0x9a, 0x9f, 0x7b, 0x57, 0x52, 0x23, 0xaf, 0x98, 0xc4, 0x92, 0x01, 0x15, +- 0x9f, 0xde, 0x33, 0x89, 0xd0, 0x50, 0x7e, 0xee, 0x62, 0x97, 0xf9, 0xf9, +- 0x4b, 0x6d, 0x50, 0xe6, 0x2e, 0x73, 0x94, 0xb5, 0xc8, 0xdf, 0xf9, 0x7b, +- 0xf9, 0xdf, 0xc4, 0xcf, 0x3a, 0xd1, 0x6a, 0xad, 0xed, 0x2f, 0x6a, 0xb2, +- 0x98, 0x91, 0x5f, 0x93, 0xeb, 0x96, 0xeb, 0x4b, 0xb7, 0x5c, 0x3f, 0xee, +- 0xbe, 0xf9, 0x7a, 0xfb, 0x9c, 0x9b, 0xaf, 0xf3, 0x36, 0x71, 0x43, 0xae, +- 0x1d, 0xba, 0x6f, 0xe2, 0x28, 0xd7, 0x3a, 0x63, 0xc1, 0x21, 0xf3, 0x42, +- 0x85, 0xcc, 0x45, 0x62, 0xd6, 0xec, 0x5c, 0x97, 0x65, 0xa6, 0xcf, 0xf5, +- 0xcd, 0x5c, 0x6d, 0xc0, 0x3a, 0xf7, 0x4b, 0xbb, 0xd1, 0xe4, 0x1d, 0xdf, +- 0xdc, 0x3b, 0x74, 0xd9, 0xb3, 0x88, 0xa5, 0xe1, 0x80, 0xd2, 0x1b, 0x33, +- 0xcc, 0x19, 0x5a, 0xb1, 0x21, 0xef, 0x4a, 0xa9, 0x7e, 0x03, 0x25, 0x7e, +- 0x6d, 0xc3, 0x0c, 0x5b, 0x17, 0x9c, 0x0b, 0xb5, 0x8e, 0x3f, 0x53, 0x92, +- 0x88, 0x67, 0xbc, 0x81, 0x43, 0x94, 0x55, 0x2c, 0x73, 0x95, 0x71, 0x75, +- 0x17, 0x9e, 0x09, 0x39, 0x8c, 0xe2, 0xb0, 0xd7, 0x3d, 0x5f, 0x59, 0x86, +- 0xed, 0x43, 0x7f, 0x8e, 0xf5, 0x49, 0xe1, 0xf8, 0xb5, 0xd8, 0x32, 0x66, +- 0xc3, 0x31, 0xea, 0x77, 0x2f, 0xc7, 0x21, 0xfe, 0xb9, 0x53, 0x90, 0xb3, +- 0x79, 0x8d, 0x8c, 0x91, 0x75, 0xeb, 0xb3, 0x75, 0xe8, 0x75, 0xac, 0x8f, +- 0x9a, 0xf8, 0x54, 0xa7, 0xef, 0xd1, 0x64, 0x7e, 0x12, 0x3b, 0xb7, 0x5a, +- 0x58, 0xfa, 0x48, 0x9c, 0xfb, 0x39, 0x4b, 0x6c, 0x75, 0x29, 0x6d, 0x56, +- 0xc1, 0x67, 0x52, 0x77, 0xac, 0xe4, 0x9c, 0xc9, 0x0d, 0xc7, 0xa3, 0x9b, +- 0x30, 0x1c, 0x35, 0xe4, 0x7d, 0xc0, 0xde, 0x1a, 0x7b, 0xe4, 0x85, 0x0a, +- 0xf2, 0xec, 0x84, 0xee, 0x6f, 0x3f, 0xa7, 0xc0, 0x53, 0x16, 0xf6, 0xd3, +- 0xcf, 0x7c, 0x89, 0xdf, 0xea, 0x92, 0x4f, 0xd3, 0x5d, 0xab, 0xa8, 0xef, +- 0x7b, 0x86, 0x02, 0x56, 0x7e, 0xe0, 0xef, 0x6e, 0x9b, 0xbf, 0x90, 0x1a, +- 0xb3, 0x9e, 0xcb, 0x35, 0xbe, 0x8e, 0x83, 0x69, 0x17, 0x1e, 0x8b, 0x7b, +- 0x94, 0x79, 0x7b, 0x54, 0xdc, 0x1f, 0xf7, 0x4e, 0x2c, 0xb1, 0x93, 0x7f, +- 0x2c, 0x9a, 0xc1, 0xfe, 0x14, 0xfc, 0x68, 0xa1, 0xf8, 0x82, 0xff, 0x0a, +- 0x63, 0x56, 0x84, 0x7d, 0xa2, 0xb4, 0x60, 0xb1, 0x57, 0x3d, 0x68, 0xf3, +- 0xb9, 0x7f, 0x8b, 0xad, 0xb0, 0x67, 0x56, 0xa3, 0x9b, 0xf3, 0x5f, 0x19, +- 0x97, 0x9a, 0x55, 0x03, 0x50, 0xd1, 0x8c, 0x1d, 0x87, 0xc4, 0x36, 0xe5, +- 0x9d, 0x75, 0x78, 0xaa, 0xc2, 0x2d, 0x77, 0xa0, 0xf8, 0x4b, 0x72, 0xed, +- 0x49, 0x89, 0x3f, 0x37, 0x94, 0xdb, 0x4c, 0xc6, 0x2f, 0xf3, 0x73, 0x35, +- 0x89, 0xa5, 0xd8, 0x3a, 0x20, 0xf9, 0x76, 0xe2, 0xb6, 0xce, 0x38, 0xa8, +- 0x42, 0x0b, 0x3c, 0x65, 0x93, 0x3a, 0xd0, 0x26, 0xf8, 0x62, 0x9b, 0x10, +- 0x88, 0x89, 0xcd, 0x6a, 0x6a, 0x07, 0x22, 0xa7, 0x25, 0xcf, 0x37, 0x2f, +- 0xe4, 0xe7, 0xbc, 0xfc, 0xbd, 0x55, 0x76, 0xdd, 0xf5, 0xca, 0xa8, 0x8a, +- 0x09, 0x35, 0x1b, 0x47, 0x1e, 0x4a, 0x6a, 0x6b, 0x0b, 0x6d, 0x72, 0x26, +- 0xe2, 0xb2, 0x19, 0xb1, 0xfa, 0x55, 0x6a, 0x51, 0xde, 0x8c, 0xbe, 0xbd, +- 0xef, 0xd2, 0x07, 0xc9, 0x18, 0xbf, 0x37, 0x9d, 0xd4, 0xcb, 0xe5, 0x6d, +- 0x1e, 0xdc, 0x17, 0x97, 0x3c, 0x69, 0x4f, 0x75, 0xf6, 0x4c, 0x87, 0x5c, +- 0x3b, 0xd0, 0xa1, 0x13, 0x64, 0x67, 0x7d, 0x61, 0x56, 0x59, 0x71, 0xe9, +- 0x97, 0x59, 0x9d, 0x49, 0xdc, 0x7d, 0x87, 0xd8, 0x78, 0xcf, 0x58, 0x83, +- 0x3b, 0xab, 0x77, 0x4d, 0xbc, 0x96, 0xbe, 0xb4, 0x7d, 0x9b, 0xe4, 0x34, +- 0x2e, 0xf9, 0xcc, 0x23, 0xa3, 0xd3, 0xdb, 0xe7, 0x73, 0x30, 0x55, 0x39, +- 0x4e, 0x95, 0xd7, 0x37, 0xa9, 0xf5, 0x45, 0x94, 0x87, 0xa3, 0x2d, 0xca, +- 0xaa, 0xa8, 0xd4, 0xfb, 0x6c, 0xd1, 0x12, 0xeb, 0x5c, 0xab, 0x89, 0xef, +- 0x85, 0xc6, 0x95, 0x6d, 0xd6, 0x99, 0x59, 0x43, 0x49, 0x36, 0x02, 0x95, +- 0xa3, 0xcd, 0xca, 0xf6, 0xe8, 0x27, 0xe6, 0x53, 0x56, 0x5d, 0x7d, 0xa6, +- 0x75, 0xbe, 0xa6, 0x70, 0xd4, 0x85, 0x8a, 0x83, 0x25, 0x28, 0x18, 0xd4, +- 0x30, 0x73, 0xf4, 0x41, 0xf2, 0x56, 0xe1, 0x3a, 0x46, 0x8b, 0xc3, 0x3a, +- 0xa3, 0xf6, 0xfa, 0xf5, 0x33, 0x6a, 0x0e, 0xe2, 0x82, 0x01, 0xeb, 0x1f, +- 0x63, 0xa5, 0xc3, 0x8c, 0x95, 0xcc, 0x25, 0xdf, 0x0b, 0x19, 0x3b, 0x66, +- 0xc2, 0x1b, 0xa8, 0xb4, 0x19, 0xa6, 0xe4, 0x6e, 0x5e, 0x21, 0x61, 0x5c, +- 0x53, 0x67, 0x60, 0x45, 0x9d, 0xbc, 0x9b, 0xe9, 0x30, 0xec, 0xe1, 0x2e, +- 0x1c, 0x0e, 0x75, 0xe1, 0x3d, 0xbd, 0x0b, 0x3b, 0xf5, 0x62, 0xa3, 0x3c, +- 0x5c, 0x2a, 0x67, 0xd9, 0x27, 0xa2, 0xd0, 0xf4, 0xb4, 0xa2, 0x9d, 0xba, +- 0x0a, 0xef, 0x3e, 0x9f, 0xe2, 0x35, 0x96, 0x29, 0x1a, 0x2e, 0x67, 0xbc, +- 0x53, 0xe5, 0xb4, 0x81, 0x6b, 0x99, 0x00, 0xa6, 0x88, 0xab, 0xc9, 0x31, +- 0x39, 0x4f, 0x52, 0x8b, 0x81, 0xb1, 0xff, 0x29, 0xdc, 0xc0, 0x20, 0x26, +- 0x59, 0x67, 0x2a, 0x9f, 0x93, 0x5a, 0xa6, 0x33, 0x98, 0xe3, 0x30, 0x86, +- 0xb2, 0xae, 0xb1, 0x0c, 0xd7, 0xe8, 0x9d, 0x7e, 0x98, 0xee, 0x64, 0x3c, +- 0x87, 0xd7, 0x6a, 0x60, 0xff, 0xbe, 0x1b, 0xf5, 0xc9, 0x19, 0x38, 0x56, +- 0x5f, 0x89, 0x02, 0x1c, 0x1d, 0xee, 0x20, 0xc7, 0xef, 0x6e, 0x2f, 0x67, +- 0x7c, 0x3a, 0x3a, 0xec, 0x44, 0x2a, 0x25, 0x39, 0x07, 0xab, 0x36, 0x39, +- 0xe9, 0xa0, 0x2d, 0xed, 0x4a, 0xa0, 0xbe, 0x26, 0xec, 0x4f, 0xd6, 0xd8, +- 0x55, 0xf6, 0x51, 0x85, 0x54, 0x5a, 0xe3, 0x27, 0xc0, 0x4f, 0x90, 0x9f, +- 0x26, 0x7c, 0x8f, 0x36, 0x5b, 0x41, 0xbc, 0x7d, 0x35, 0x5d, 0x86, 0x4f, +- 0x92, 0x5a, 0x40, 0xa7, 0x1e, 0x0c, 0x33, 0x46, 0x30, 0x2c, 0x39, 0x95, +- 0xe1, 0x2a, 0xed, 0xf4, 0xa5, 0x50, 0x19, 0xcc, 0xd4, 0xed, 0x62, 0x42, +- 0x79, 0xff, 0x25, 0x7f, 0x0e, 0x33, 0x5b, 0x5f, 0x3d, 0x92, 0x81, 0xf2, +- 0x78, 0x9d, 0x41, 0x7d, 0x61, 0x0c, 0xbb, 0x48, 0x6a, 0x29, 0x5a, 0xe7, +- 0x25, 0x7b, 0xb1, 0x51, 0x13, 0xf6, 0x7a, 0x6a, 0xec, 0x1a, 0xce, 0xa5, +- 0x27, 0x11, 0x4f, 0xca, 0xbb, 0x6d, 0xa2, 0xc7, 0xef, 0x9b, 0x46, 0x85, +- 0x9c, 0xc9, 0xe8, 0x44, 0x5c, 0xab, 0x64, 0x1c, 0x24, 0xef, 0x3e, 0x1e, +- 0x0e, 0x45, 0x63, 0xa5, 0xf2, 0x9e, 0xf0, 0x92, 0x97, 0x43, 0xde, 0x96, +- 0x7e, 0xc5, 0x78, 0xa8, 0xc4, 0x7a, 0xaf, 0xa3, 0x8b, 0x58, 0xac, 0xa9, +- 0x4e, 0xc5, 0xdb, 0xb4, 0x05, 0x01, 0x1c, 0x4b, 0x8b, 0xdc, 0x28, 0xa7, +- 0xb1, 0xac, 0xdc, 0x6e, 0x9c, 0x9d, 0xce, 0xea, 0xc1, 0xc6, 0xa8, 0x83, +- 0xdf, 0xb2, 0xf7, 0x72, 0xae, 0x95, 0x3e, 0xc2, 0xda, 0xff, 0x9f, 0xdf, +- 0x91, 0x3b, 0xbf, 0xda, 0x5e, 0x19, 0x76, 0x05, 0x97, 0xc7, 0xed, 0x9f, +- 0xc8, 0xfb, 0xc8, 0x4f, 0x34, 0xca, 0x7b, 0x6b, 0xae, 0xe0, 0xe3, 0xa3, +- 0xae, 0xe0, 0xda, 0xf8, 0x51, 0x85, 0xf2, 0xda, 0x57, 0x63, 0x77, 0x05, +- 0x1f, 0xb9, 0xd1, 0x9e, 0xfb, 0xde, 0x85, 0xb1, 0x50, 0xb1, 0xa1, 0x86, +- 0xc5, 0xa7, 0x7b, 0x03, 0x9f, 0x28, 0x96, 0x2f, 0x37, 0x4a, 0xe8, 0x63, +- 0x9f, 0xcf, 0x8c, 0x9b, 0xed, 0xb3, 0x04, 0xab, 0xec, 0x1c, 0xeb, 0x2a, +- 0x5e, 0x49, 0xdd, 0x78, 0xae, 0x85, 0xcf, 0x15, 0xf3, 0xb9, 0x92, 0xb0, +- 0xc4, 0x8d, 0x5e, 0x7d, 0x95, 0xa2, 0x79, 0x8a, 0x14, 0xa9, 0x87, 0x69, +- 0xf8, 0x55, 0xfa, 0x9f, 0xef, 0x90, 0x78, 0xb7, 0x67, 0xac, 0x12, 0x6b, +- 0x76, 0x9b, 0x4b, 0xe6, 0x2d, 0x34, 0x97, 0xa4, 0x43, 0x31, 0xf3, 0xa5, +- 0x6a, 0xd9, 0x4f, 0xa9, 0xf1, 0xc9, 0x33, 0x9a, 0xea, 0x63, 0x9c, 0xf9, +- 0x4d, 0x7d, 0xbb, 0xbc, 0xa3, 0x07, 0x79, 0x7f, 0xa9, 0x90, 0x63, 0x9c, +- 0x4c, 0x89, 0x8e, 0x6c, 0x6d, 0x77, 0x31, 0x16, 0x95, 0x77, 0x67, 0x0f, +- 0x73, 0xef, 0x0f, 0xa6, 0xfe, 0xd7, 0x1d, 0x72, 0x76, 0x5d, 0xce, 0x06, +- 0x00, 0xff, 0x1f, 0x17, 0x23, 0xca, 0x76, 0xf8, 0x78, 0x00, 0x00, 0x00 }; ++ 0xec, 0x5c, 0x7f, 0x70, 0x1c, 0xd5, 0x7d, 0xff, 0xbc, 0xbd, 0xbd, 0xbb, ++ 0x95, 0x74, 0x3e, 0xed, 0x9d, 0x4e, 0xb2, 0x04, 0x06, 0xef, 0xa2, 0x95, ++ 0x74, 0x58, 0xc6, 0xec, 0x9d, 0x4e, 0xb6, 0x48, 0xb7, 0xc9, 0xd5, 0x36, ++ 0x20, 0x17, 0x52, 0x84, 0xa1, 0xc1, 0xcc, 0x30, 0x9d, 0x1b, 0x63, 0x8c, ++ 0xb0, 0x1d, 0xa2, 0x00, 0x33, 0xc8, 0x29, 0x13, 0x16, 0xfc, 0xb3, 0xf8, ++ 0xa4, 0x93, 0x8d, 0x8c, 0xc9, 0xf4, 0xd7, 0x21, 0xcb, 0x8a, 0x81, 0x93, ++ 0xce, 0x04, 0xda, 0x98, 0x69, 0xa8, 0x15, 0x6c, 0x53, 0x87, 0x5f, 0x21, ++ 0x19, 0x68, 0x4d, 0x9b, 0x99, 0xa8, 0x06, 0x1c, 0xd3, 0xa6, 0xd4, 0xb4, ++ 0x0e, 0xb5, 0x8b, 0xeb, 0xd7, 0xef, 0x77, 0x4f, 0x97, 0x50, 0x42, 0xcb, ++ 0x64, 0xa6, 0x7f, 0xee, 0x77, 0xe6, 0xe6, 0xf6, 0xde, 0xfb, 0xbe, 0xef, ++ 0x7b, 0xdf, 0xdf, 0x9f, 0xb7, 0x1a, 0xfb, 0xbe, 0x08, 0x6a, 0x31, 0x4b, ++ 0x73, 0xe8, 0x93, 0x19, 0x18, 0xbc, 0x27, 0xbd, 0x28, 0xb3, 0x88, 0x1e, ++ 0xbb, 0x02, 0x73, 0x55, 0x95, 0xc7, 0x05, 0x7c, 0xf2, 0xc9, 0x27, 0x9f, ++ 0x7c, 0xf2, 0xc9, 0x27, 0x9f, 0x7c, 0xf2, 0xc9, 0x27, 0x9f, 0x7c, 0xf2, ++ 0xc9, 0x27, 0x9f, 0x7c, 0xf2, 0xc9, 0x27, 0x9f, 0x7c, 0xf2, 0xc9, 0x27, ++ 0x9f, 0x7c, 0xf2, 0xc9, 0x27, 0x9f, 0x7c, 0xf2, 0xc9, 0x27, 0x9f, 0x7c, ++ 0xf2, 0xc9, 0x27, 0x9f, 0x7c, 0xf2, 0xc9, 0x27, 0x9f, 0x7c, 0xf2, 0xc9, ++ 0x27, 0x9f, 0x7c, 0xf2, 0xc9, 0x27, 0x9f, 0x7c, 0xfa, 0xff, 0xa4, 0x00, ++ 0xa0, 0xf3, 0xf7, 0x9c, 0xd9, 0x0f, 0x34, 0xc5, 0x71, 0x37, 0x2e, 0xb5, ++ 0xa0, 0x05, 0x9c, 0x33, 0x1b, 0x6f, 0xb7, 0x80, 0x6c, 0xa9, 0xd3, 0x58, ++ 0x86, 0xff, 0x92, 0x6e, 0x42, 0x05, 0x8f, 0x5f, 0xe2, 0x9c, 0xff, 0xf3, ++ 0x17, 0x96, 0x98, 0xa7, 0x8b, 0x01, 0x68, 0xba, 0xf3, 0x46, 0x4a, 0x6f, ++ 0x87, 0x36, 0x8f, 0xd6, 0xfc, 0x49, 0xc7, 0x95, 0x71, 0x44, 0xab, 0xb2, ++ 0xe0, 0x2a, 0x8e, 0x94, 0xfb, 0x6c, 0x89, 0x97, 0x6c, 0x57, 0xf4, 0x66, ++ 0xe0, 0x06, 0x9c, 0x83, 0xe2, 0xae, 0xfc, 0x05, 0x69, 0x04, 0x2b, 0x3b, ++ 0xab, 0x93, 0x1a, 0x82, 0xfb, 0xa0, 0xab, 0x8e, 0x82, 0xa0, 0x55, 0x8b, ++ 0xd0, 0x13, 0x75, 0x08, 0x3e, 0xd1, 0x8c, 0xf0, 0xe4, 0x01, 0x91, 0x2b, ++ 0x6a, 0x98, 0x09, 0x1c, 0x14, 0x6b, 0x4a, 0xc8, 0x05, 0x9d, 0xb3, 0x37, ++ 0x8c, 0xd1, 0xba, 0xac, 0xf7, 0xef, 0x4b, 0xa6, 0x6f, 0x18, 0x2f, 0x41, ++ 0x0f, 0x38, 0x50, 0x54, 0xe7, 0x08, 0x3d, 0x33, 0xdf, 0xd9, 0x1b, 0xf6, ++ 0x96, 0x4e, 0xc9, 0x17, 0x3a, 0x12, 0x38, 0x54, 0xd6, 0x71, 0xa0, 0xfc, ++ 0x10, 0x9d, 0xc3, 0x74, 0x5d, 0x68, 0xae, 0xea, 0xb8, 0xd8, 0x92, 0x09, ++ 0x62, 0x62, 0xe4, 0x82, 0x0c, 0x58, 0xa6, 0x01, 0xc5, 0xd2, 0x0f, 0x83, ++ 0xf8, 0x0a, 0xc4, 0x57, 0x08, 0x62, 0xac, 0xb8, 0x23, 0x8e, 0xda, 0x66, ++ 0xbc, 0xd0, 0xc1, 0xeb, 0x79, 0x2d, 0xcb, 0xf8, 0x38, 0x5a, 0x5d, 0x1f, ++ 0xa2, 0xf5, 0x47, 0x33, 0xc0, 0xf8, 0x48, 0x1f, 0x2d, 0x95, 0xd8, 0x64, ++ 0x87, 0xb1, 0x5a, 0x87, 0x5b, 0xe3, 0xb0, 0xac, 0xaa, 0x1c, 0x57, 0x18, ++ 0x93, 0xff, 0x5c, 0x5f, 0x91, 0x03, 0xa1, 0x59, 0x70, 0xc3, 0x9f, 0x9a, ++ 0x3f, 0x55, 0xaa, 0xce, 0x6f, 0xa7, 0x7d, 0x34, 0x9a, 0xef, 0xc7, 0x5f, ++ 0x96, 0xd7, 0xe0, 0x2f, 0xca, 0xb7, 0xe1, 0xd9, 0x72, 0x1f, 0xed, 0x7b, ++ 0x1f, 0xed, 0x3b, 0x80, 0xbf, 0x2e, 0x6f, 0xc0, 0x77, 0xcb, 0x39, 0x3c, ++ 0x57, 0x5e, 0x85, 0xef, 0x94, 0x6f, 0xc6, 0x33, 0x65, 0x78, 0x67, 0x38, ++ 0x95, 0x49, 0x8a, 0x1f, 0xe5, 0x6b, 0xa0, 0xee, 0xdc, 0x8c, 0xe9, 0x52, ++ 0x10, 0xc1, 0x9d, 0x12, 0x23, 0xb6, 0xf9, 0x38, 0xd0, 0xa1, 0x07, 0x21, ++ 0xb0, 0xcc, 0x36, 0xf7, 0x03, 0x5f, 0x40, 0x2e, 0x61, 0x1e, 0x00, 0x9a, ++ 0xc4, 0x8f, 0x47, 0x9b, 0xc4, 0x6b, 0xa3, 0xaa, 0x78, 0x3d, 0x2f, 0x50, ++ 0xef, 0x20, 0xf2, 0x72, 0x46, 0xca, 0xeb, 0xd2, 0x52, 0x96, 0x52, 0x56, ++ 0xef, 0x0f, 0x85, 0x69, 0x3f, 0x22, 0x2e, 0x85, 0xd1, 0x68, 0x66, 0xd7, ++ 0x09, 0xcd, 0xad, 0x25, 0xf9, 0x2b, 0xba, 0x01, 0x6b, 0xa7, 0x41, 0x7e, ++ 0x60, 0x1d, 0x37, 0xe1, 0x0e, 0x2f, 0x26, 0xfa, 0xd0, 0x60, 0x2d, 0xc5, ++ 0xbd, 0x7d, 0x36, 0x8a, 0x65, 0x68, 0x31, 0xe7, 0x0c, 0x52, 0xc3, 0x02, ++ 0x36, 0xf9, 0x5b, 0xd0, 0xb3, 0x5d, 0x5a, 0xdf, 0x50, 0xf1, 0x37, 0x9d, ++ 0xbd, 0x40, 0x67, 0x2f, 0xd0, 0xd9, 0x0b, 0xa4, 0x57, 0x81, 0xf4, 0x2a, ++ 0x90, 0x0e, 0x05, 0xd2, 0xad, 0x40, 0x7a, 0x14, 0x48, 0x8f, 0x02, 0xe9, ++ 0x58, 0x60, 0x5f, 0x0d, 0x92, 0x0d, 0x22, 0xf8, 0xbb, 0xfc, 0x3c, 0x9c, ++ 0xe1, 0xcf, 0x4a, 0x1d, 0xc7, 0xe9, 0x8c, 0x8a, 0xf5, 0x9b, 0xca, 0xf8, ++ 0x6e, 0x84, 0x7c, 0x64, 0xfc, 0xe6, 0x7b, 0x2f, 0xc4, 0xc9, 0xfc, 0xbb, ++ 0x32, 0x34, 0x97, 0xf7, 0xfc, 0x22, 0xe4, 0x28, 0x70, 0xe9, 0x6e, 0x29, ++ 0xcf, 0x75, 0xcd, 0xc8, 0xb7, 0x6f, 0x61, 0x59, 0x0e, 0x4e, 0x8c, 0x2a, ++ 0x08, 0xd0, 0xd8, 0xb5, 0xf6, 0xdf, 0xcb, 0x3b, 0x13, 0xcc, 0xf7, 0x51, ++ 0x04, 0xb5, 0x6c, 0x27, 0x68, 0x0d, 0xce, 0xbb, 0x1b, 0xef, 0x6d, 0x87, ++ 0x1b, 0x75, 0x54, 0xf1, 0xe6, 0x90, 0x81, 0xb9, 0x4e, 0x16, 0x73, 0x1c, ++ 0x6b, 0x64, 0x8f, 0xd2, 0x39, 0x18, 0x47, 0xf6, 0xf2, 0x7a, 0xd8, 0xd8, ++ 0x57, 0x56, 0xc5, 0xab, 0x43, 0x73, 0x10, 0xdf, 0x69, 0xad, 0x1a, 0x12, ++ 0x0a, 0x72, 0x8d, 0x59, 0x8c, 0x67, 0x4c, 0xa3, 0x08, 0x03, 0xab, 0xd2, ++ 0x0a, 0x30, 0xd7, 0xc5, 0xd6, 0x8c, 0x69, 0xbb, 0x78, 0x08, 0xd3, 0x09, ++ 0x1b, 0x13, 0x65, 0x8d, 0x72, 0xc3, 0xc5, 0x9d, 0x19, 0x0d, 0x72, 0x24, ++ 0x8b, 0x93, 0x5d, 0x21, 0x4c, 0xf7, 0x71, 0x8c, 0xa8, 0xb4, 0xf7, 0x56, ++ 0x28, 0xf1, 0x38, 0xf9, 0xe5, 0xb0, 0x0c, 0xc6, 0x79, 0x0c, 0xe2, 0x5f, ++ 0x32, 0xbc, 0xff, 0x45, 0xe2, 0xd5, 0xdd, 0x51, 0xd4, 0xee, 0xd6, 0xf0, ++ 0xf4, 0x4e, 0x15, 0x2b, 0xc8, 0xb7, 0x7b, 0x52, 0xaa, 0xb1, 0x4e, 0x38, ++ 0x18, 0x2f, 0xab, 0x48, 0x0c, 0xb5, 0xc0, 0x88, 0x69, 0xb8, 0x74, 0xc8, ++ 0xc5, 0x3b, 0x24, 0x77, 0x90, 0xe4, 0xd6, 0x77, 0xe9, 0x98, 0x69, 0xac, ++ 0xf8, 0xf5, 0xeb, 0xf9, 0x56, 0x77, 0xa7, 0x12, 0x02, 0x42, 0x70, 0x35, ++ 0x27, 0x83, 0xfb, 0xf3, 0xad, 0xa4, 0xc3, 0xad, 0x58, 0x1a, 0xd2, 0xb0, ++ 0x7a, 0x98, 0xc7, 0x96, 0x03, 0x93, 0x73, 0xe7, 0xa0, 0x96, 0xf5, 0xe7, ++ 0x7c, 0x5e, 0x4a, 0xcf, 0x1c, 0x07, 0xbf, 0x9d, 0x60, 0xbb, 0xbb, 0xca, ++ 0x7f, 0xc8, 0x6c, 0x82, 0xf9, 0x2a, 0x39, 0x72, 0x38, 0x93, 0xc1, 0xc6, ++ 0x7c, 0x6b, 0xf6, 0x5b, 0x4a, 0x03, 0x10, 0x34, 0x0d, 0x43, 0x81, 0x96, ++ 0x70, 0x90, 0x1a, 0xa5, 0x78, 0x79, 0xd4, 0x8b, 0x17, 0xa4, 0xba, 0x4a, ++ 0x9c, 0x97, 0x9a, 0xab, 0x13, 0xff, 0xfc, 0xc5, 0x6d, 0xf8, 0xe8, 0x51, ++ 0xe6, 0x53, 0xf1, 0x03, 0x7a, 0x7e, 0x7f, 0xef, 0x8e, 0xd9, 0xda, 0xf1, ++ 0xa7, 0x9e, 0x5f, 0x0d, 0xa5, 0xba, 0xb7, 0x8d, 0x3b, 0xf3, 0xad, 0x67, ++ 0xb7, 0x29, 0xe4, 0xbf, 0x8b, 0x23, 0xa8, 0xa1, 0xfa, 0x13, 0x24, 0x59, ++ 0xfb, 0xf2, 0xe7, 0xb1, 0x32, 0x6d, 0x1e, 0xe4, 0x7f, 0x6f, 0x36, 0x66, ++ 0x55, 0xe4, 0x5f, 0x56, 0xb2, 0xf1, 0x64, 0xd9, 0xc6, 0xed, 0x74, 0x8e, ++ 0xfb, 0xf0, 0x8f, 0x40, 0xcb, 0x02, 0xe3, 0x94, 0x72, 0x42, 0xba, 0x37, ++ 0xb3, 0xbc, 0x79, 0x38, 0x15, 0x6f, 0xcd, 0x9d, 0x52, 0xcc, 0xe2, 0x76, ++ 0x85, 0x6d, 0xa5, 0xe0, 0xcb, 0xe9, 0x0c, 0x8a, 0x31, 0x1d, 0xb7, 0xa6, ++ 0x35, 0xf7, 0x52, 0x3a, 0xd3, 0x1b, 0x4b, 0x34, 0x34, 0xed, 0xca, 0xe2, ++ 0xad, 0xf4, 0x9b, 0x28, 0xae, 0x64, 0x3b, 0xf0, 0x3a, 0x3e, 0x73, 0x33, ++ 0xe2, 0x56, 0x0d, 0xe2, 0x63, 0x41, 0xd4, 0xef, 0xba, 0x20, 0x9b, 0x2d, ++ 0x1e, 0xb7, 0x06, 0xce, 0x0a, 0x3e, 0x73, 0x10, 0xd1, 0xb1, 0xab, 0xa0, ++ 0x5a, 0x66, 0x92, 0x1c, 0x9b, 0x60, 0xde, 0x90, 0x55, 0x3d, 0xbb, 0xc0, ++ 0x75, 0x5f, 0x10, 0x58, 0x97, 0xfa, 0xbe, 0xcc, 0x36, 0xf2, 0x9a, 0x67, ++ 0x68, 0x9c, 0xcf, 0x50, 0x73, 0x36, 0x8b, 0x26, 0x5a, 0x53, 0xe5, 0x8b, ++ 0xa0, 0x7f, 0x57, 0xe5, 0x0c, 0x6f, 0x2f, 0xc1, 0xb3, 0x1a, 0x7a, 0xd0, ++ 0x51, 0x78, 0x08, 0x6f, 0x2d, 0xf6, 0xf6, 0x3f, 0xbd, 0x2f, 0xbd, 0x83, ++ 0x6c, 0xc2, 0x75, 0xf4, 0xd3, 0x7e, 0xe1, 0xf9, 0xff, 0x64, 0x7f, 0x24, ++ 0x21, 0x9a, 0x69, 0x8c, 0xe3, 0x77, 0xa7, 0x34, 0x6e, 0xaa, 0xf8, 0x25, ++ 0x4c, 0xf2, 0xde, 0xcf, 0xf4, 0xa0, 0x75, 0x48, 0x85, 0xcc, 0xb7, 0xda, ++ 0x3f, 0x0d, 0x3c, 0x22, 0xa7, 0x6f, 0xe3, 0xb9, 0x56, 0xfd, 0x70, 0x40, ++ 0x60, 0xa9, 0x6a, 0x9e, 0xce, 0xa1, 0x19, 0xfb, 0xa9, 0xc6, 0xb4, 0x38, ++ 0x3a, 0xd5, 0x9c, 0x04, 0xd5, 0x1e, 0x43, 0x74, 0xec, 0xb1, 0xb1, 0x60, ++ 0xe8, 0x36, 0x7c, 0x69, 0xb7, 0x83, 0x83, 0x05, 0x1b, 0x4f, 0x17, 0xa4, ++ 0x3c, 0x69, 0x4b, 0xf9, 0xaf, 0x5d, 0x66, 0xff, 0x31, 0x6a, 0x07, 0x8b, ++ 0x96, 0x74, 0xe6, 0xea, 0x03, 0x2a, 0xd9, 0xa7, 0xcd, 0xd8, 0x20, 0xcc, ++ 0xe6, 0x29, 0x61, 0x53, 0xcc, 0xf5, 0x92, 0xed, 0x0d, 0xec, 0x2d, 0x27, ++ 0xf1, 0x54, 0xd9, 0xa2, 0xcf, 0x42, 0x8a, 0x95, 0x0c, 0xd5, 0x33, 0xd6, ++ 0x55, 0xc7, 0x78, 0x07, 0xe5, 0x45, 0x41, 0xc1, 0x7e, 0x9b, 0xe2, 0x3f, ++ 0x46, 0xbc, 0x85, 0x0b, 0xe4, 0x3f, 0x0d, 0xc9, 0x9d, 0x59, 0xd4, 0xa4, ++ 0x1a, 0x60, 0xdc, 0x68, 0x61, 0xbc, 0xa0, 0xb9, 0x41, 0x8a, 0xf9, 0xb1, ++ 0xfc, 0x38, 0xfe, 0x40, 0x4f, 0xa0, 0x96, 0xec, 0xb7, 0x2a, 0x1d, 0x01, ++ 0x6e, 0xe2, 0xb9, 0x08, 0x5a, 0xac, 0xef, 0xa3, 0x25, 0x3e, 0x07, 0xa1, ++ 0x05, 0x7f, 0x85, 0x69, 0x3d, 0x8a, 0x30, 0xf5, 0x8c, 0xf9, 0xc4, 0x33, ++ 0x9f, 0x7c, 0xd5, 0x68, 0x59, 0x24, 0x53, 0xc0, 0x6a, 0x23, 0x5e, 0xca, ++ 0xa7, 0x66, 0xd2, 0x3d, 0xb8, 0x24, 0x81, 0x32, 0x9d, 0x7f, 0x2a, 0x2f, ++ 0x65, 0x24, 0x63, 0xf6, 0x17, 0x28, 0x37, 0x27, 0x4b, 0x3d, 0x98, 0x2a, ++ 0xff, 0x1e, 0xd5, 0x73, 0x1b, 0x7b, 0xf3, 0x0e, 0xc6, 0x0a, 0xea, 0xaa, ++ 0x3c, 0xcc, 0xbe, 0xf5, 0xc8, 0xe0, 0x29, 0x8a, 0x9f, 0x89, 0x82, 0x69, ++ 0xbc, 0x18, 0xd0, 0x70, 0xcc, 0xae, 0xa3, 0x73, 0x52, 0xde, 0x92, 0x4e, ++ 0xcf, 0xe7, 0x47, 0x60, 0x35, 0xb0, 0xfd, 0xd9, 0x4f, 0x19, 0x7c, 0xbb, ++ 0xe0, 0xc5, 0xf7, 0x75, 0x1a, 0x5c, 0xd8, 0xdd, 0xec, 0x1b, 0xf7, 0x74, ++ 0x30, 0x5d, 0xa9, 0xa3, 0x7d, 0xdd, 0x36, 0xc2, 0xc3, 0x3d, 0x24, 0xb7, ++ 0xd5, 0x3e, 0x81, 0x3b, 0x30, 0xdd, 0xec, 0x62, 0x11, 0xc5, 0xbf, 0xea, ++ 0x3c, 0x9e, 0xda, 0x9c, 0x77, 0x65, 0xbd, 0x65, 0xf5, 0xff, 0x50, 0x3c, ++ 0x88, 0x57, 0x53, 0x5c, 0xd7, 0x55, 0xca, 0x7b, 0x1d, 0x3b, 0xec, 0x11, ++ 0xbc, 0x56, 0xfa, 0x2d, 0xe4, 0x62, 0x66, 0x72, 0x93, 0x58, 0x8f, 0x83, ++ 0x23, 0x57, 0x01, 0xb7, 0x70, 0x9e, 0x90, 0x6e, 0xd6, 0x7a, 0x1c, 0x2a, ++ 0x7e, 0x03, 0x47, 0x47, 0x6b, 0xf1, 0xbc, 0x15, 0x47, 0xcb, 0x44, 0x65, ++ 0x9f, 0xab, 0xbb, 0x35, 0x8c, 0x51, 0x4e, 0x5f, 0x6b, 0xab, 0x98, 0x49, ++ 0x70, 0xfd, 0xa0, 0x58, 0x4b, 0x6f, 0xa0, 0x5a, 0xe3, 0xb5, 0x5e, 0xac, ++ 0xc9, 0x18, 0xc8, 0xe7, 0xb3, 0x54, 0xff, 0x6a, 0xb0, 0x2b, 0x06, 0x71, ++ 0x3b, 0xf5, 0xb0, 0xbb, 0xf3, 0xad, 0xfd, 0xc3, 0x4a, 0x1c, 0xc5, 0x96, ++ 0x2c, 0xf9, 0x42, 0xa0, 0xc9, 0x32, 0xb0, 0xa5, 0x44, 0x15, 0xb4, 0xa4, ++ 0xe2, 0x9b, 0xa5, 0x2b, 0x50, 0x6c, 0xe2, 0xb5, 0x1d, 0x98, 0xf6, 0xbe, ++ 0x83, 0x98, 0x89, 0x9b, 0xcd, 0x20, 0x9b, 0x8d, 0x17, 0x54, 0xec, 0xb6, ++ 0xf7, 0x5c, 0x28, 0xae, 0x34, 0xf5, 0x1c, 0xe5, 0x5b, 0xc0, 0x8b, 0x5b, ++ 0x7e, 0x06, 0xbe, 0x96, 0xff, 0x50, 0x9e, 0xf1, 0xf6, 0x54, 0x39, 0xff, ++ 0xa7, 0xdf, 0x0e, 0xbc, 0x2f, 0x45, 0x98, 0xe5, 0xdf, 0x1f, 0xad, 0xfc, ++ 0x5b, 0xd1, 0x67, 0x99, 0x37, 0x0b, 0x70, 0x1c, 0xcc, 0xfd, 0x44, 0xcc, ++ 0x57, 0xea, 0x80, 0xbe, 0x98, 0xcf, 0x51, 0xcd, 0xb3, 0x38, 0x9a, 0x26, ++ 0xda, 0x50, 0xb3, 0x8b, 0x7f, 0xf3, 0xb8, 0xc0, 0x65, 0xdd, 0x9c, 0x63, ++ 0x6d, 0x50, 0xc6, 0x56, 0x47, 0x2b, 0x35, 0xb8, 0x5a, 0x1f, 0xfe, 0x70, ++ 0x56, 0xbe, 0xd7, 0xeb, 0xe9, 0x77, 0xa5, 0x86, 0x7e, 0x33, 0xc3, 0xcf, ++ 0xbc, 0xa6, 0x06, 0x6f, 0xed, 0x35, 0xed, 0xa2, 0xb2, 0x84, 0xf7, 0xac, ++ 0xe4, 0x08, 0x36, 0xce, 0xae, 0xa1, 0x98, 0x2f, 0x4c, 0x49, 0xdc, 0xca, ++ 0xf2, 0xaa, 0xeb, 0xdb, 0x10, 0xfa, 0xe5, 0xbe, 0x2a, 0x5e, 0xcc, 0x7c, ++ 0x7a, 0xdf, 0xdb, 0x64, 0xed, 0xca, 0x38, 0xc5, 0x59, 0x23, 0xd4, 0x05, ++ 0xd4, 0xe0, 0xf5, 0x26, 0xd4, 0x51, 0xde, 0x06, 0xac, 0x5b, 0x64, 0xe0, ++ 0x2b, 0x1c, 0xa7, 0x9a, 0x1b, 0x71, 0x2e, 0xc6, 0xf0, 0xce, 0x17, 0xc8, ++ 0xc7, 0x51, 0x8e, 0x47, 0xf2, 0xf3, 0xc5, 0x18, 0x7a, 0xe2, 0x92, 0x28, ++ 0xeb, 0xbb, 0x2a, 0x0d, 0x77, 0x3e, 0xd5, 0xec, 0xf7, 0xf6, 0xdc, 0x2d, ++ 0x8b, 0x7d, 0x3a, 0x5e, 0xca, 0xfc, 0x0e, 0x8d, 0x73, 0x3c, 0xd9, 0x78, ++ 0x2e, 0xaf, 0xe1, 0xfe, 0xe1, 0x66, 0x3a, 0x27, 0xd7, 0xca, 0x9a, 0xb3, ++ 0x33, 0x8a, 0x8d, 0x67, 0x29, 0x16, 0x9f, 0x29, 0xb0, 0xad, 0x54, 0x5c, ++ 0x96, 0x5e, 0x21, 0xc3, 0x4d, 0x1c, 0xdf, 0x49, 0x5a, 0xa3, 0x93, 0xec, ++ 0x28, 0x74, 0x6b, 0x99, 0x3c, 0xb0, 0x92, 0x9f, 0x3b, 0x68, 0xac, 0x89, ++ 0xbe, 0xbb, 0x65, 0xdd, 0xaf, 0x9d, 0x43, 0xff, 0xac, 0x73, 0x50, 0xdc, ++ 0x9b, 0xf6, 0x5a, 0x74, 0x12, 0x0e, 0x52, 0x91, 0xa5, 0x3e, 0x3f, 0x41, ++ 0x31, 0xb0, 0x8d, 0x7a, 0xf0, 0x7b, 0x84, 0xf5, 0xb6, 0x78, 0x78, 0xca, ++ 0x83, 0x67, 0x1e, 0x5e, 0x5b, 0x5d, 0xc1, 0x5d, 0x9a, 0x6a, 0x31, 0x16, ++ 0xab, 0xce, 0x71, 0x9e, 0xf6, 0x62, 0x6c, 0x54, 0xca, 0xcd, 0x76, 0x0b, ++ 0xc9, 0x88, 0x63, 0xb3, 0x45, 0x39, 0x3d, 0xca, 0x6b, 0xa4, 0x4c, 0xa6, ++ 0x16, 0xf4, 0xa8, 0xa2, 0x01, 0x33, 0xba, 0x2b, 0xd6, 0x66, 0x0c, 0xf1, ++ 0xd5, 0x51, 0x15, 0xf9, 0xc2, 0x45, 0x64, 0x2f, 0x29, 0x9f, 0x4a, 0x21, ++ 0xbb, 0x29, 0x55, 0x87, 0x57, 0x8a, 0x3a, 0x72, 0xfa, 0x05, 0xb9, 0xbc, ++ 0xad, 0x17, 0x65, 0x92, 0xf3, 0x41, 0xaa, 0x33, 0x79, 0x44, 0x44, 0x50, ++ 0x4c, 0x44, 0xf0, 0x78, 0x21, 0x81, 0x23, 0xe3, 0x11, 0x6c, 0xa5, 0x18, ++ 0x7d, 0x31, 0xc3, 0x7b, 0x46, 0xf0, 0x70, 0x99, 0x31, 0x55, 0x80, 0x6c, ++ 0xe4, 0x8a, 0x13, 0xde, 0x58, 0x1d, 0x96, 0x17, 0x99, 0xf7, 0x82, 0x6c, ++ 0xb1, 0x2c, 0xbd, 0x25, 0x50, 0xe5, 0x3b, 0x4e, 0xf8, 0xca, 0xa0, 0x5a, ++ 0x36, 0x8f, 0x70, 0x55, 0x33, 0x61, 0xa8, 0x04, 0x61, 0x28, 0x6b, 0x16, ++ 0x17, 0x9a, 0x94, 0x8d, 0x52, 0x3e, 0x4b, 0xb5, 0xec, 0xc7, 0xf4, 0x39, ++ 0x43, 0xf5, 0x34, 0x46, 0x3a, 0x5e, 0x36, 0xcc, 0x3a, 0xba, 0xc2, 0xa6, ++ 0x7a, 0x9b, 0x55, 0x94, 0x7a, 0xee, 0x43, 0x81, 0x29, 0xde, 0x5f, 0xc5, ++ 0x96, 0x02, 0xb0, 0xa9, 0x00, 0xf7, 0x08, 0xe5, 0x7e, 0xc3, 0x44, 0x14, ++ 0xf1, 0x09, 0x1d, 0xc1, 0x89, 0x24, 0xcd, 0x6b, 0x48, 0xd0, 0x6f, 0x97, ++ 0xb0, 0x60, 0xbd, 0xd3, 0x24, 0x16, 0x3e, 0x76, 0x5e, 0xee, 0x48, 0xa9, ++ 0x58, 0xd7, 0x66, 0xf6, 0xde, 0x28, 0x90, 0x4d, 0x0e, 0x49, 0x19, 0x4e, ++ 0x85, 0x29, 0x37, 0xe5, 0xa1, 0x04, 0xe9, 0x1d, 0x75, 0xe4, 0x83, 0xaf, ++ 0x75, 0x5b, 0xf6, 0x6b, 0x20, 0xb9, 0x65, 0x5e, 0xc3, 0xe3, 0xae, 0xf8, ++ 0xb0, 0xdb, 0x7a, 0xfc, 0x4d, 0xb4, 0xa3, 0x6b, 0x42, 0x15, 0xff, 0x36, ++ 0xb4, 0x10, 0xe9, 0x29, 0xe8, 0x21, 0xe7, 0x80, 0x98, 0x79, 0xe2, 0xa0, ++ 0x38, 0x39, 0x49, 0xe7, 0x2e, 0x90, 0x2e, 0x05, 0xd2, 0xa5, 0x40, 0xba, ++ 0x90, 0x5d, 0x9e, 0xf1, 0xf0, 0x24, 0xeb, 0x9a, 0x24, 0x2c, 0x73, 0xdc, ++ 0xc3, 0xbc, 0x8c, 0x11, 0x63, 0x8e, 0x99, 0x75, 0xc1, 0x7a, 0xb3, 0x9e, ++ 0x52, 0xbe, 0x69, 0x57, 0xf4, 0x71, 0xa9, 0xdc, 0x6a, 0x53, 0x55, 0x5b, ++ 0x48, 0xf9, 0xef, 0x36, 0xdb, 0x82, 0x75, 0x94, 0xf2, 0x3b, 0xa4, 0xd3, ++ 0x16, 0xd2, 0x71, 0x53, 0x41, 0x1e, 0x0a, 0x59, 0x96, 0x31, 0x41, 0x67, ++ 0x8b, 0x93, 0x4e, 0x89, 0x09, 0x8d, 0x74, 0x6d, 0x87, 0x4a, 0xba, 0x06, ++ 0x26, 0xa0, 0x2b, 0x74, 0x1e, 0x63, 0x8c, 0xec, 0x34, 0xf5, 0x79, 0xe7, ++ 0x61, 0xcc, 0xef, 0x8a, 0xab, 0x09, 0x9f, 0xa8, 0x64, 0xd7, 0x4d, 0x14, ++ 0x3b, 0x39, 0x15, 0x46, 0xd8, 0x52, 0xa8, 0x27, 0x6a, 0xf8, 0xf6, 0x78, ++ 0x1d, 0x26, 0xc8, 0xef, 0xc5, 0x71, 0xe8, 0x41, 0x92, 0xe9, 0x16, 0x0f, ++ 0x8a, 0x4f, 0xc6, 0x5b, 0xd0, 0x19, 0x20, 0x9c, 0x04, 0x3c, 0x92, 0x8f, ++ 0x8b, 0x89, 0x11, 0x15, 0x9b, 0x0b, 0xa7, 0x49, 0x3f, 0x89, 0xc3, 0xf6, ++ 0xc3, 0xcd, 0xc4, 0x22, 0x1e, 0xb6, 0xcd, 0x1e, 0xe0, 0x2a, 0x8a, 0xb7, ++ 0x00, 0xd6, 0x5a, 0xc8, 0x6e, 0xb3, 0xaf, 0xc2, 0x4c, 0x1f, 0x8c, 0xed, ++ 0xb6, 0xab, 0x87, 0x60, 0x1e, 0xbb, 0x9a, 0x7a, 0xd3, 0x95, 0xa4, 0xcf, ++ 0xa0, 0xe5, 0x0e, 0x50, 0xe1, 0x42, 0xb9, 0x6c, 0xf6, 0x1f, 0x25, 0x5f, ++ 0x94, 0xa8, 0xff, 0x95, 0xca, 0x4d, 0xe2, 0xe9, 0xd1, 0xf3, 0xf2, 0xae, ++ 0x94, 0x99, 0x6d, 0xa3, 0xb1, 0xe0, 0x90, 0x46, 0x38, 0x4d, 0xa3, 0x9c, ++ 0x32, 0x6d, 0x80, 0x6b, 0x03, 0xb4, 0x30, 0xd5, 0xe2, 0x9f, 0x59, 0x47, ++ 0x08, 0xa7, 0x6b, 0x20, 0x0c, 0x8f, 0xa5, 0x23, 0x02, 0xfb, 0x28, 0xc7, ++ 0x27, 0x17, 0x9a, 0xc7, 0x56, 0xc3, 0x9d, 0x6e, 0x81, 0x39, 0x18, 0x0e, ++ 0x9c, 0xc6, 0x07, 0x43, 0x21, 0xc2, 0x0d, 0xed, 0xf6, 0xeb, 0x30, 0xf5, ++ 0x7d, 0x81, 0x5f, 0xc8, 0xfd, 0x09, 0x5c, 0x14, 0xc4, 0x19, 0x69, 0xfc, ++ 0x3e, 0xaf, 0x61, 0xdd, 0x07, 0xb0, 0x2d, 0xc3, 0x38, 0x45, 0x25, 0x9c, ++ 0x02, 0xbc, 0x93, 0x37, 0xb0, 0x7f, 0x61, 0x0d, 0xf5, 0x93, 0xd6, 0x9e, ++ 0x75, 0x70, 0x57, 0xd1, 0xf5, 0x47, 0x8b, 0xd0, 0x5e, 0x79, 0x8a, 0x95, ++ 0x0d, 0x42, 0xe0, 0x29, 0xeb, 0xac, 0xdd, 0x31, 0xc9, 0x18, 0x46, 0x4d, ++ 0x2d, 0xa0, 0x5c, 0xdc, 0x5a, 0x16, 0xd4, 0xdb, 0x4c, 0x7d, 0x06, 0x6c, ++ 0x1b, 0x9d, 0xec, 0x7a, 0x5e, 0x22, 0xc6, 0xba, 0xbb, 0x39, 0xd2, 0x73, ++ 0xd5, 0x16, 0x3a, 0xff, 0x1a, 0xd2, 0xe9, 0x2e, 0xcb, 0xed, 0x21, 0xa9, ++ 0xd4, 0xa3, 0xcc, 0xe6, 0xf7, 0x48, 0xf7, 0xb5, 0x54, 0x47, 0x8a, 0xe5, ++ 0xe7, 0xea, 0xb9, 0x66, 0x4c, 0x94, 0xf9, 0x1e, 0xd7, 0x83, 0xa5, 0xf9, ++ 0x6a, 0x3e, 0xb0, 0xff, 0xd9, 0xf7, 0x1c, 0x0b, 0x1c, 0x33, 0x1c, 0x27, ++ 0x8c, 0xd1, 0x7a, 0x30, 0xda, 0xae, 0x20, 0x9b, 0x90, 0x72, 0xa5, 0x65, ++ 0x8e, 0x70, 0x1d, 0xa7, 0x98, 0xcf, 0xee, 0xb5, 0xeb, 0x29, 0x3f, 0xe1, ++ 0x3e, 0x69, 0x1b, 0x08, 0x39, 0x1c, 0x1b, 0x75, 0x14, 0xeb, 0x11, 0x6c, ++ 0xa3, 0x58, 0xd1, 0x2c, 0x2b, 0x49, 0x97, 0x0d, 0xfd, 0x9d, 0x0c, 0xf1, ++ 0x96, 0x61, 0x94, 0xed, 0x5a, 0xc2, 0x95, 0x2a, 0x62, 0xce, 0x21, 0xd9, ++ 0x60, 0x35, 0xea, 0xd4, 0xb8, 0xf5, 0x7b, 0xb1, 0x9a, 0xee, 0x17, 0x06, ++ 0xea, 0x1c, 0x9e, 0x3f, 0x27, 0x67, 0x62, 0x11, 0x8a, 0x33, 0xe6, 0xb1, ++ 0xdc, 0x67, 0xf0, 0x91, 0x44, 0x9c, 0x79, 0xb3, 0x58, 0x9d, 0x81, 0x38, ++ 0x48, 0x7b, 0xa1, 0x81, 0x73, 0xd7, 0xc0, 0x7c, 0xc7, 0x3a, 0x76, 0x88, ++ 0x7a, 0x8f, 0xd1, 0x00, 0xaa, 0xb9, 0x2a, 0x02, 0x8e, 0xa5, 0xef, 0xc5, ++ 0x51, 0xaf, 0x4e, 0x11, 0x52, 0x17, 0x2b, 0x76, 0xcf, 0x13, 0xbd, 0x84, ++ 0xcd, 0xdb, 0x53, 0x70, 0x34, 0xb4, 0x19, 0x7f, 0x43, 0xa3, 0x9b, 0x29, ++ 0xfe, 0xe7, 0x38, 0x11, 0x51, 0xda, 0x0d, 0xfd, 0x69, 0x5b, 0xa3, 0x3e, ++ 0x2a, 0xe5, 0xd6, 0x94, 0x81, 0x29, 0x9b, 0x70, 0x74, 0x63, 0x10, 0x31, ++ 0x0b, 0xba, 0xee, 0x58, 0x83, 0x07, 0x30, 0xc0, 0xf8, 0x37, 0x3a, 0x9f, ++ 0x7a, 0x25, 0x8d, 0x89, 0x31, 0xbb, 0x06, 0xd9, 0x9b, 0x05, 0x22, 0x4e, ++ 0x82, 0xce, 0x16, 0x42, 0xce, 0x7b, 0x66, 0x1d, 0x91, 0x7d, 0xd7, 0xde, ++ 0x43, 0xfa, 0x8a, 0xf9, 0xb5, 0x0e, 0x8f, 0x59, 0x76, 0x09, 0x77, 0x11, ++ 0x56, 0xa7, 0x21, 0x9a, 0xdf, 0x4c, 0xf3, 0x8f, 0x92, 0xec, 0x5c, 0xdc, ++ 0xbb, 0x87, 0xd6, 0xb7, 0x38, 0xd6, 0xf4, 0xf3, 0xd8, 0x4e, 0x3a, 0x70, ++ 0x8d, 0xe7, 0x31, 0x3e, 0xf3, 0x42, 0x3e, 0x33, 0xf5, 0x78, 0x8e, 0x2b, ++ 0x1b, 0x3f, 0xcb, 0xd3, 0xde, 0x09, 0x64, 0xb7, 0xdb, 0x10, 0x13, 0xf6, ++ 0x6e, 0xc2, 0x2f, 0xa8, 0x8f, 0x3a, 0x56, 0xff, 0x14, 0xa0, 0x44, 0x9c, ++ 0x9d, 0x28, 0xc5, 0x80, 0x47, 0x0b, 0x96, 0x7b, 0x8f, 0x62, 0x0e, 0x26, ++ 0x08, 0x13, 0x9f, 0x21, 0x4c, 0xbf, 0xab, 0x7d, 0xda, 0x8c, 0x83, 0xb1, ++ 0x7e, 0x54, 0xbc, 0xb4, 0x5b, 0x41, 0xc7, 0x62, 0xea, 0x4b, 0x54, 0x4b, ++ 0xae, 0xb1, 0xf9, 0xbe, 0x7c, 0x79, 0x7d, 0x05, 0x2f, 0xff, 0x6f, 0x39, ++ 0x69, 0x92, 0xc5, 0xaa, 0x79, 0x69, 0xf5, 0x3d, 0x8d, 0x3f, 0x93, 0xd9, ++ 0x18, 0xfb, 0x22, 0x42, 0xb5, 0xf8, 0x97, 0xf5, 0x28, 0x39, 0x49, 0xf2, ++ 0x37, 0x75, 0x07, 0x75, 0x8e, 0x19, 0xf2, 0x65, 0xf6, 0x8d, 0x3c, 0x44, ++ 0x7d, 0x9a, 0xf2, 0x2a, 0xc6, 0x7e, 0xe1, 0xfb, 0x3d, 0x19, 0x6f, 0x38, ++ 0x41, 0xba, 0xa9, 0xe8, 0x4a, 0xa3, 0x5e, 0x71, 0xac, 0xb3, 0x63, 0x74, ++ 0xe6, 0x16, 0xa7, 0x1e, 0xe7, 0x1a, 0xb8, 0x36, 0x46, 0xc5, 0x0f, 0x46, ++ 0xcd, 0x1e, 0xc2, 0xc3, 0xab, 0xee, 0x21, 0x1c, 0x75, 0x9f, 0x50, 0xd1, ++ 0x4b, 0x67, 0xb7, 0xda, 0xc8, 0x07, 0x84, 0x4d, 0x12, 0x6d, 0xd3, 0x66, ++ 0x02, 0xd5, 0xf3, 0x5e, 0x90, 0x71, 0xcb, 0x72, 0xe3, 0xca, 0xc7, 0x32, ++ 0x95, 0xe6, 0x18, 0xdf, 0x80, 0x70, 0x5c, 0x20, 0x94, 0x1e, 0xf2, 0x6c, ++ 0x4b, 0x77, 0x2a, 0xd4, 0xa7, 0x1f, 0x62, 0x1f, 0x11, 0x7e, 0x7b, 0x59, ++ 0xe6, 0xbe, 0xc2, 0xba, 0x6d, 0x9f, 0xd5, 0x73, 0x2d, 0xc7, 0x15, 0xfd, ++ 0x96, 0x73, 0xd8, 0xde, 0x87, 0xa8, 0x8e, 0x77, 0x2d, 0xe9, 0xdc, 0x3e, ++ 0xa8, 0x0c, 0x49, 0x63, 0x25, 0xfb, 0x93, 0x2e, 0x37, 0xb5, 0x9e, 0xaf, ++ 0xb5, 0xa8, 0x73, 0x1c, 0xaf, 0x0f, 0x45, 0x45, 0xfd, 0x63, 0xae, 0xd7, ++ 0x53, 0x5f, 0xa3, 0xb3, 0x9c, 0x4c, 0xf1, 0x19, 0x38, 0xc7, 0x8e, 0xe3, ++ 0x8a, 0xd2, 0xed, 0xc4, 0x1b, 0xa0, 0xfd, 0xa1, 0x51, 0xbc, 0x41, 0x52, ++ 0x9f, 0x39, 0xd7, 0x35, 0x25, 0x8d, 0x06, 0x96, 0x4f, 0xb6, 0x1e, 0x65, ++ 0x5b, 0xf3, 0xdd, 0xb2, 0x6a, 0x6f, 0xe6, 0xe7, 0xf5, 0x74, 0xe9, 0x8e, ++ 0xb1, 0xff, 0x50, 0x5f, 0xe7, 0xb0, 0x4d, 0x21, 0x6a, 0x9c, 0x4e, 0x63, ++ 0x81, 0xd8, 0x21, 0xdd, 0x44, 0xb5, 0x86, 0x45, 0xc5, 0x84, 0xb7, 0x9e, ++ 0xf7, 0xfe, 0xf4, 0xfa, 0x26, 0xf1, 0xce, 0x9e, 0xdf, 0xa5, 0x67, 0x2f, ++ 0x46, 0x7a, 0x9f, 0xa2, 0x1c, 0xd2, 0x9c, 0x7e, 0x99, 0x6c, 0xe4, 0x18, ++ 0x83, 0xf2, 0x8a, 0xbd, 0x56, 0xe6, 0x1a, 0x39, 0xd6, 0xe0, 0x26, 0x48, ++ 0xce, 0xae, 0xc7, 0x7e, 0x75, 0x8e, 0xab, 0xdb, 0xa5, 0x9c, 0xb0, 0xd7, ++ 0x90, 0x2d, 0x58, 0x4e, 0xd5, 0x16, 0x7b, 0x66, 0x6d, 0xd3, 0x5e, 0xf1, ++ 0x5f, 0xc1, 0x3b, 0x83, 0x16, 0x72, 0xde, 0xc0, 0x4b, 0x79, 0xa5, 0x89, ++ 0x6e, 0x2b, 0xe8, 0xb3, 0x05, 0x7e, 0xda, 0x43, 0xfa, 0x5d, 0x49, 0x58, ++ 0x65, 0x91, 0x35, 0xdd, 0x1a, 0x58, 0x2f, 0x31, 0x77, 0x9a, 0x82, 0xe3, ++ 0xbc, 0xd4, 0xda, 0x55, 0x84, 0xaf, 0xe0, 0x1e, 0xc5, 0xb6, 0x57, 0xf0, ++ 0x32, 0xf1, 0xad, 0xb8, 0xc2, 0x32, 0x5a, 0x05, 0xf5, 0xb5, 0xbe, 0xa5, ++ 0xe9, 0xe0, 0x2f, 0x63, 0x8f, 0xcf, 0x90, 0xf3, 0x74, 0xe0, 0x18, 0xec, ++ 0x22, 0xdf, 0xe5, 0x56, 0x2a, 0x48, 0x2d, 0x06, 0x61, 0x8d, 0xa8, 0xd8, ++ 0xba, 0x9b, 0xfd, 0xff, 0x3d, 0x9a, 0x67, 0xbe, 0xce, 0x66, 0x1d, 0xd6, ++ 0xaa, 0xc3, 0x74, 0xb1, 0x24, 0x2c, 0x4a, 0xf6, 0xe0, 0xbd, 0xaa, 0x72, ++ 0xaa, 0x32, 0xa2, 0x62, 0x72, 0x94, 0x79, 0x59, 0x17, 0xaa, 0xcd, 0x1c, ++ 0x2b, 0x29, 0x8e, 0x8f, 0x8f, 0x65, 0x47, 0x3a, 0x1a, 0x43, 0x2d, 0xaf, ++ 0x89, 0x0a, 0x7d, 0x0f, 0xcb, 0x85, 0x60, 0x3b, 0xc6, 0x48, 0xff, 0xf6, ++ 0xf4, 0xe5, 0xb3, 0xfa, 0xff, 0xb1, 0x5e, 0xc1, 0x71, 0x51, 0x71, 0xd4, ++ 0xdb, 0xbb, 0x62, 0xa3, 0x49, 0xb2, 0xf5, 0x44, 0xaa, 0xca, 0xf3, 0x38, ++ 0xf1, 0x70, 0x9c, 0x7d, 0x66, 0x4f, 0x22, 0xea, 0x15, 0x8f, 0xe4, 0xe9, ++ 0x92, 0x6a, 0x29, 0xd7, 0xd7, 0x52, 0x9e, 0x3c, 0x49, 0xbd, 0x69, 0x7f, ++ 0xb1, 0x57, 0x6c, 0xcb, 0xeb, 0xd4, 0xa7, 0x96, 0x8b, 0xad, 0x79, 0x8b, ++ 0x71, 0xd1, 0x6c, 0x9f, 0xaa, 0xbc, 0x8b, 0xda, 0x52, 0xfa, 0xe4, 0x3b, ++ 0xa2, 0x48, 0x4e, 0x77, 0xd0, 0x37, 0x7f, 0xf8, 0x41, 0xa9, 0x58, 0xfc, ++ 0x3e, 0xc8, 0x3a, 0x76, 0x22, 0x10, 0xe9, 0xe9, 0x59, 0x12, 0x40, 0xbd, ++ 0x85, 0xbe, 0x66, 0xc2, 0x07, 0x57, 0x7a, 0x35, 0xdd, 0x80, 0x51, 0x6a, ++ 0x6f, 0xac, 0xf8, 0x89, 0xf3, 0x0e, 0x6a, 0xad, 0x83, 0x5c, 0x0d, 0xd5, ++ 0x91, 0x6b, 0xba, 0x43, 0xda, 0xd1, 0xee, 0xde, 0x96, 0xf6, 0xc9, 0xa6, ++ 0x5c, 0xad, 0x73, 0x7d, 0x4b, 0xdb, 0xa4, 0xdb, 0xb2, 0x70, 0x08, 0xf8, ++ 0xf2, 0x90, 0x0e, 0xcd, 0xb9, 0xd1, 0x0d, 0x74, 0x23, 0xa7, 0x52, 0x5c, ++ 0xec, 0xe8, 0xb6, 0x7a, 0xa6, 0xc4, 0x4d, 0x37, 0x91, 0x1e, 0x2d, 0x9d, ++ 0x93, 0x86, 0xb1, 0x39, 0xf3, 0xc0, 0x4d, 0x81, 0x29, 0xee, 0x2f, 0x1b, ++ 0x06, 0xf7, 0xf1, 0x7b, 0x33, 0xba, 0x9b, 0x9e, 0xd0, 0xf1, 0xc0, 0xb2, ++ 0xee, 0x41, 0x0c, 0xe4, 0x1f, 0x40, 0x7f, 0x9e, 0xdf, 0x3b, 0x69, 0x18, ++ 0xe1, 0x1a, 0x5f, 0xe0, 0x77, 0x4e, 0x0f, 0x35, 0x30, 0x6e, 0xdc, 0x5e, ++ 0x56, 0x71, 0xed, 0x10, 0xcf, 0x99, 0xcd, 0xef, 0xa3, 0xca, 0xfb, 0x59, ++ 0x7c, 0x9f, 0xd4, 0x93, 0x6b, 0x1e, 0xb2, 0x81, 0x61, 0x29, 0x95, 0x0c, ++ 0xdf, 0x63, 0x4e, 0x13, 0xd6, 0xe3, 0xbd, 0x7f, 0x4e, 0xbd, 0x71, 0x2e, ++ 0xbf, 0x0b, 0x63, 0xca, 0x86, 0x87, 0x79, 0xee, 0xd4, 0xec, 0xdc, 0xbb, ++ 0x34, 0x07, 0x71, 0x92, 0xea, 0xfa, 0x74, 0x25, 0x2f, 0xb2, 0xb5, 0xc3, ++ 0x1a, 0xfe, 0xa8, 0xc0, 0x3c, 0x33, 0xb3, 0x3c, 0x3f, 0x21, 0x9e, 0x04, ++ 0x56, 0xc4, 0xb8, 0x76, 0x53, 0xce, 0xec, 0xae, 0xbe, 0x2b, 0x93, 0xf2, ++ 0x25, 0xfb, 0xc3, 0x68, 0xe5, 0x5d, 0x59, 0x54, 0x68, 0x8f, 0xd1, 0x33, ++ 0x61, 0x95, 0x50, 0x2a, 0x2a, 0x42, 0x8f, 0xf1, 0xfa, 0x57, 0x53, 0x95, ++ 0xf5, 0xc7, 0x52, 0xbc, 0xfe, 0xd7, 0xd7, 0xa8, 0xd9, 0xc8, 0x30, 0xdd, ++ 0xa9, 0x0a, 0xff, 0x24, 0x77, 0x34, 0x56, 0x64, 0x57, 0xd6, 0x7d, 0x6f, ++ 0x76, 0xdd, 0x41, 0x5a, 0xb7, 0x8f, 0x62, 0x8c, 0xd7, 0xb2, 0x9e, 0x1c, ++ 0xa3, 0xd5, 0xf7, 0x86, 0x49, 0x71, 0x80, 0x7a, 0xf5, 0x81, 0x92, 0x2a, ++ 0xf6, 0x52, 0x1d, 0x1c, 0xcf, 0x13, 0x36, 0xf2, 0xde, 0x05, 0x52, 0xcd, ++ 0x2f, 0x7f, 0x23, 0x56, 0xf1, 0x21, 0xf7, 0xd5, 0x69, 0xea, 0xab, 0xed, ++ 0x54, 0xdf, 0x55, 0x4f, 0xa7, 0xb0, 0x73, 0x84, 0xea, 0xbb, 0xc0, 0x49, ++ 0xaf, 0xbe, 0x1c, 0x41, 0x7b, 0x89, 0xfb, 0x80, 0x25, 0xce, 0x15, 0x8c, ++ 0x5c, 0x33, 0xc9, 0x6e, 0x29, 0x57, 0x6a, 0x03, 0xf5, 0x82, 0x2c, 0xf5, ++ 0x64, 0xf1, 0x62, 0x89, 0x7f, 0x52, 0xf1, 0x8c, 0xf3, 0x19, 0xb2, 0x62, ++ 0x4e, 0xbb, 0x8b, 0xfa, 0x76, 0x97, 0x71, 0xec, 0xc0, 0xf3, 0xc2, 0x9a, ++ 0x3e, 0x27, 0xb2, 0xb7, 0x36, 0xe3, 0x41, 0xfc, 0x3c, 0x95, 0x5d, 0x11, ++ 0xa5, 0x6f, 0xc2, 0xcc, 0x86, 0xc6, 0xef, 0x48, 0xbb, 0xdb, 0x7a, 0x36, ++ 0x88, 0x36, 0xaa, 0x37, 0x6d, 0xee, 0x16, 0xb4, 0x51, 0xcf, 0xb7, 0xb5, ++ 0xc3, 0x25, 0x5b, 0x7b, 0xa3, 0x54, 0xb5, 0x03, 0xc7, 0x29, 0xdb, 0x80, ++ 0x42, 0xdf, 0xb1, 0xb2, 0x0b, 0x04, 0xf5, 0x55, 0xea, 0xbb, 0xc3, 0xd4, ++ 0xb3, 0x2b, 0xf7, 0xce, 0x30, 0xe1, 0x16, 0xde, 0x7b, 0xdd, 0xec, 0xbb, ++ 0x96, 0x7f, 0x90, 0x95, 0x1e, 0xf5, 0x0a, 0xd9, 0x83, 0xcf, 0xfc, 0xa3, ++ 0x48, 0x65, 0xfc, 0x4c, 0x6c, 0xf6, 0xff, 0xf9, 0x21, 0x9c, 0x42, 0xf7, ++ 0xc8, 0x21, 0x81, 0x1d, 0x6d, 0x95, 0x58, 0xee, 0xe4, 0xf7, 0x98, 0xde, ++ 0x7b, 0xb7, 0x2a, 0x4f, 0xc5, 0x86, 0x0a, 0xe1, 0x99, 0x43, 0xe5, 0xac, ++ 0xb8, 0x26, 0x8f, 0x01, 0xea, 0x89, 0xd9, 0x20, 0xf1, 0x5e, 0x53, 0xea, ++ 0x15, 0xcb, 0xf3, 0x96, 0xb1, 0x89, 0x74, 0xdd, 0xa2, 0x77, 0xea, 0xe3, ++ 0x84, 0x21, 0x68, 0x3f, 0x23, 0x4c, 0xf1, 0xaf, 0x39, 0x73, 0xb1, 0x7d, ++ 0x36, 0x76, 0x28, 0x1f, 0x28, 0x7f, 0x06, 0xc5, 0x82, 0x49, 0xfe, 0xa9, ++ 0x7b, 0xb1, 0x5b, 0xd1, 0xe3, 0x9c, 0xdc, 0x76, 0x33, 0xcf, 0x5f, 0x31, ++ 0x6b, 0xfb, 0xa6, 0x38, 0xed, 0x49, 0xbf, 0x47, 0x66, 0xcf, 0xff, 0x7f, ++ 0xad, 0xbd, 0xf6, 0x92, 0xff, 0xb9, 0x66, 0x86, 0xce, 0xc9, 0x18, 0x08, ++ 0x6e, 0xdc, 0x61, 0xfc, 0x33, 0x6f, 0xd6, 0xe7, 0xd4, 0x15, 0xa3, 0x03, ++ 0xb8, 0x71, 0x31, 0xdd, 0x7c, 0xe9, 0x0e, 0xb6, 0x8d, 0x7c, 0x95, 0x1c, ++ 0x66, 0xbd, 0xcf, 0x93, 0xde, 0xd0, 0x6a, 0x9c, 0xb3, 0xb8, 0x7c, 0xa8, ++ 0xb5, 0x3f, 0x2c, 0xcc, 0xe4, 0x90, 0x30, 0xfb, 0xa8, 0xbe, 0xd9, 0x93, ++ 0x30, 0x9b, 0x17, 0x08, 0xd3, 0x58, 0x0b, 0xb6, 0xc9, 0x79, 0xb4, 0x95, ++ 0xf8, 0xfb, 0x2c, 0x2c, 0xf2, 0x6b, 0xdf, 0x70, 0x00, 0x4a, 0xfa, 0x03, ++ 0xb2, 0x2b, 0xe1, 0x35, 0xd1, 0x4c, 0xb9, 0xc4, 0xb1, 0x77, 0x1e, 0x9b, ++ 0xf3, 0xd0, 0x5a, 0x88, 0xe7, 0x2a, 0xaa, 0xd1, 0xad, 0xc3, 0xe6, 0x59, ++ 0xc2, 0x9c, 0x83, 0x5f, 0x0a, 0xb4, 0x26, 0xfb, 0x61, 0x0e, 0x6c, 0x41, ++ 0xe7, 0xf4, 0x51, 0x61, 0x66, 0xcf, 0x12, 0x16, 0x0c, 0xa7, 0x2b, 0x32, ++ 0x17, 0xcd, 0xca, 0x4c, 0x32, 0x3e, 0xf6, 0x72, 0x88, 0x30, 0x74, 0xfa, ++ 0x6f, 0xe5, 0xb4, 0x67, 0xb3, 0xe0, 0xac, 0xfe, 0x4b, 0xe2, 0x15, 0x1f, ++ 0x3c, 0x37, 0x6b, 0x1f, 0x42, 0x24, 0xb5, 0xcc, 0xc7, 0xf7, 0x30, 0x88, ++ 0x35, 0xf9, 0x2f, 0xe2, 0x61, 0xc2, 0x43, 0x59, 0x6f, 0x7d, 0x2f, 0x72, ++ 0x25, 0x88, 0xb5, 0xf9, 0xe9, 0xf0, 0x51, 0x3b, 0x88, 0xa2, 0x27, 0xe7, ++ 0x7a, 0x1a, 0xeb, 0xa3, 0x0f, 0xdb, 0x8c, 0xef, 0xe4, 0x37, 0xd3, 0x73, ++ 0xd6, 0xe3, 0xeb, 0xcf, 0xa3, 0x27, 0x9c, 0x22, 0xdc, 0xe6, 0xf1, 0x79, ++ 0xf7, 0x75, 0xe2, 0x59, 0xce, 0x73, 0x23, 0xfc, 0xae, 0x61, 0x75, 0xa6, ++ 0xcd, 0x78, 0xd8, 0xbb, 0x23, 0x1a, 0x58, 0x53, 0x32, 0x70, 0x07, 0xd5, ++ 0xd5, 0xa2, 0x57, 0x57, 0x7f, 0x85, 0xe7, 0x15, 0xe2, 0x5b, 0x46, 0x7c, ++ 0x9b, 0xbc, 0x31, 0x03, 0xcb, 0x4b, 0xc7, 0xbd, 0x58, 0x51, 0x1d, 0xf6, ++ 0x03, 0xdb, 0x9e, 0xf1, 0x68, 0xf5, 0xae, 0xc6, 0x3e, 0xc9, 0x8a, 0x47, ++ 0xf3, 0xbd, 0x62, 0x67, 0x3e, 0x4a, 0xfb, 0xb9, 0x62, 0x24, 0xa3, 0x8c, ++ 0xc6, 0x20, 0xb1, 0x2c, 0x7d, 0x35, 0xd5, 0x19, 0x2b, 0x69, 0xd1, 0xb5, ++ 0x65, 0x6d, 0x72, 0x2e, 0x61, 0xa7, 0x25, 0x58, 0x97, 0x0c, 0x51, 0xff, ++ 0xfe, 0x16, 0xee, 0xd4, 0xc3, 0xe8, 0x4f, 0xde, 0x0b, 0xdc, 0x58, 0x43, ++ 0xfd, 0xf6, 0x61, 0x0f, 0xb3, 0x86, 0x68, 0xdf, 0x1a, 0xaa, 0x0d, 0x77, ++ 0x79, 0x7a, 0x4f, 0xb1, 0xae, 0x74, 0xce, 0xe5, 0x62, 0x84, 0xea, 0x7d, ++ 0xa2, 0x82, 0x01, 0x36, 0x66, 0x8a, 0xfc, 0x3d, 0xb3, 0xb1, 0xcb, 0xb3, ++ 0xf3, 0x4f, 0x36, 0xda, 0xa5, 0x5f, 0xc4, 0x2b, 0x3d, 0x75, 0x29, 0xb2, ++ 0x8d, 0xdd, 0x58, 0x9f, 0xec, 0xc1, 0x1c, 0x6b, 0x39, 0xbe, 0xaa, 0xbb, ++ 0x88, 0x5a, 0x63, 0xb8, 0xdb, 0x93, 0xc1, 0xf2, 0xbc, 0xbf, 0x6d, 0x10, ++ 0x4d, 0x13, 0xc8, 0xf9, 0xbc, 0xfb, 0x50, 0xe5, 0xdd, 0x42, 0x4e, 0x09, ++ 0x62, 0xd3, 0x2e, 0xfe, 0x56, 0x71, 0x77, 0xa6, 0xf2, 0xce, 0x70, 0x78, ++ 0x2c, 0x88, 0xa1, 0x5d, 0xd4, 0xfb, 0x52, 0x21, 0xb8, 0x8d, 0x9f, 0x96, ++ 0xdd, 0x4f, 0xb2, 0x2b, 0xf7, 0xef, 0xaf, 0x91, 0x5d, 0x67, 0x82, 0x41, ++ 0x34, 0x13, 0x0c, 0x4b, 0x10, 0x4f, 0xc3, 0x54, 0x1d, 0x9a, 0xc7, 0xf8, ++ 0xef, 0x23, 0x07, 0xc5, 0x7d, 0xa5, 0x0a, 0xcf, 0x46, 0xfe, 0x9b, 0x4a, ++ 0x58, 0xc1, 0x7c, 0x8b, 0xd5, 0x55, 0x89, 0x47, 0xa3, 0x7b, 0x5c, 0x2d, ++ 0xe6, 0x8f, 0xd5, 0xd1, 0x47, 0x47, 0x6c, 0x82, 0x26, 0xa6, 0x96, 0x8b, ++ 0xaf, 0xe7, 0x93, 0x88, 0xd1, 0xfd, 0x32, 0xee, 0x54, 0xd6, 0xdf, 0x53, ++ 0xfa, 0xbc, 0xf3, 0x07, 0xff, 0xbb, 0xb2, 0x6f, 0x01, 0x8e, 0xea, 0xbc, ++ 0xd2, 0xfc, 0x6e, 0x3f, 0xa4, 0xd6, 0x93, 0xab, 0x27, 0x2d, 0x1e, 0xa6, ++ 0x9b, 0xbe, 0x2d, 0xb5, 0xad, 0x4e, 0xb8, 0x0d, 0xa2, 0x90, 0x3d, 0xbd, ++ 0xa5, 0x06, 0x0b, 0x5b, 0x04, 0x63, 0xcb, 0xb6, 0x32, 0x83, 0x67, 0x53, ++ 0x63, 0x05, 0x03, 0xc6, 0xd8, 0x33, 0x91, 0x09, 0x35, 0x25, 0xef, 0xce, ++ 0x44, 0x77, 0x25, 0x10, 0x02, 0xf5, 0x4b, 0x12, 0x04, 0x98, 0xaa, 0x2d, ++ 0x37, 0x92, 0x40, 0xd8, 0x69, 0x49, 0x78, 0x92, 0xec, 0x90, 0x4c, 0xd5, ++ 0x58, 0x01, 0x61, 0x20, 0x04, 0xe3, 0xec, 0x4e, 0x6d, 0x91, 0x5d, 0xcf, ++ 0x98, 0xc2, 0x06, 0x9c, 0x18, 0x3f, 0x33, 0x59, 0x8b, 0x78, 0xe2, 0xbb, ++ 0xdf, 0xb9, 0xdd, 0x0d, 0x82, 0x21, 0x99, 0x1a, 0x57, 0x75, 0x89, 0xee, ++ 0x7b, 0xff, 0xff, 0x9e, 0xff, 0xfc, 0xe7, 0x7c, 0xe7, 0x3b, 0xe7, 0xfc, ++ 0xb7, 0x4c, 0x2e, 0x2d, 0xfb, 0xb5, 0x08, 0xc5, 0xda, 0x94, 0xf9, 0x42, ++ 0x96, 0xe3, 0x48, 0x1c, 0xed, 0xbe, 0xd9, 0x8f, 0x11, 0x99, 0x84, 0xcb, ++ 0x41, 0xad, 0x08, 0x4b, 0x9e, 0xc7, 0x1f, 0xad, 0x3c, 0x51, 0x64, 0x90, ++ 0xb9, 0x0b, 0x91, 0x3f, 0x2c, 0x73, 0x17, 0x21, 0xef, 0xa6, 0x2c, 0xf2, ++ 0x1c, 0xa6, 0x5c, 0x13, 0x12, 0x5b, 0xe5, 0x79, 0xc7, 0x95, 0xa1, 0xb4, ++ 0xc8, 0x90, 0x7b, 0xee, 0x59, 0x73, 0xa3, 0x5a, 0xc4, 0x18, 0x3e, 0x62, ++ 0x6e, 0x62, 0x5e, 0xe2, 0x5f, 0xfa, 0x86, 0x99, 0x6a, 0x93, 0xb5, 0xba, ++ 0xcd, 0xbd, 0x09, 0x27, 0xfa, 0xa9, 0xb7, 0xad, 0xa1, 0xa3, 0xc2, 0x67, ++ 0xb3, 0xff, 0xe5, 0xf4, 0xf6, 0x97, 0xd4, 0xdb, 0xa9, 0xec, 0x3e, 0x1e, ++ 0x57, 0x4e, 0xde, 0x8c, 0xf5, 0x22, 0xa3, 0xc8, 0xa5, 0xa0, 0x42, 0x13, ++ 0xb9, 0x6c, 0x28, 0x67, 0xdc, 0xac, 0xa0, 0x7e, 0xca, 0x2d, 0x99, 0x9a, ++ 0x95, 0x9f, 0x47, 0xa1, 0xce, 0x21, 0x17, 0x2c, 0x9b, 0xc8, 0xc8, 0x35, ++ 0x45, 0xfd, 0x5c, 0xb8, 0x69, 0x13, 0xb3, 0xf5, 0x2c, 0x74, 0x46, 0x7c, ++ 0xfa, 0xe2, 0x4b, 0x3b, 0x92, 0x32, 0xaf, 0x5d, 0xf2, 0x04, 0x2b, 0xdf, ++ 0xb3, 0xd1, 0x9e, 0x56, 0x45, 0x33, 0x3a, 0xb0, 0x59, 0x7b, 0x20, 0x3e, ++ 0x20, 0xeb, 0xcf, 0xad, 0xbd, 0x59, 0x79, 0x3a, 0x2a, 0xe3, 0x35, 0x2c, ++ 0xb2, 0xc6, 0x59, 0xfb, 0xce, 0x71, 0x6f, 0x73, 0x5c, 0x80, 0x63, 0x32, ++ 0xb6, 0xe9, 0x49, 0x7d, 0x26, 0x7e, 0xcd, 0x7d, 0x3a, 0xae, 0x74, 0xf2, ++ 0x99, 0xb0, 0xf6, 0xf6, 0xfd, 0xac, 0xaf, 0x1f, 0xa7, 0x6f, 0xf2, 0x37, ++ 0xa7, 0x8d, 0xf6, 0x5e, 0x04, 0xc7, 0xb0, 0xcb, 0xaa, 0x49, 0xc8, 0xdc, ++ 0xcf, 0x45, 0xcb, 0x51, 0x70, 0x24, 0x37, 0x36, 0x13, 0xc3, 0x33, 0xbd, ++ 0xac, 0x9c, 0x3f, 0x0a, 0x3e, 0x0a, 0x76, 0x1b, 0x4a, 0xe4, 0x66, 0x3f, ++ 0x4a, 0x6a, 0x38, 0xd2, 0xa7, 0xcb, 0xa7, 0x3c, 0x52, 0xef, 0x53, 0x88, ++ 0x19, 0xcc, 0x07, 0xd5, 0x55, 0x1e, 0x07, 0x71, 0x6e, 0x13, 0xbe, 0x20, ++ 0xb7, 0x8d, 0x04, 0x9c, 0x96, 0x0f, 0x4b, 0xcd, 0x2f, 0x1f, 0x19, 0x0c, ++ 0x02, 0x86, 0xa3, 0x8c, 0xbb, 0x5c, 0x2b, 0x63, 0x3d, 0xba, 0xd3, 0x5f, ++ 0x98, 0x53, 0x95, 0xcc, 0xd9, 0xb5, 0x9b, 0x35, 0x22, 0xfa, 0x9d, 0x69, ++ 0x8e, 0xf0, 0x5a, 0x6f, 0x3a, 0xb7, 0x4f, 0xe4, 0x10, 0xe4, 0x68, 0xcf, ++ 0x68, 0xbf, 0x35, 0x37, 0xdc, 0x76, 0x6f, 0x0e, 0x9b, 0x73, 0x79, 0xa9, ++ 0x60, 0x73, 0x31, 0x7a, 0xf7, 0x7a, 0x93, 0x29, 0x54, 0x22, 0xa9, 0xd9, ++ 0xe6, 0xd3, 0x4b, 0x98, 0xf5, 0x7b, 0xfb, 0x9a, 0x61, 0xe5, 0xeb, 0x9e, ++ 0x14, 0xfa, 0x2b, 0xc4, 0x8f, 0x9c, 0x5a, 0xbd, 0xa7, 0xcc, 0x56, 0x2e, ++ 0xb2, 0x5b, 0x52, 0xd9, 0x07, 0x0b, 0xb0, 0x89, 0xb9, 0x76, 0xaa, 0x95, ++ 0x98, 0x35, 0x68, 0xb4, 0x70, 0x7a, 0x57, 0x61, 0x38, 0xd5, 0xf9, 0x35, ++ 0xbf, 0x97, 0xf1, 0x10, 0xc8, 0x67, 0xde, 0x7f, 0x09, 0x59, 0x4c, 0x1b, ++ 0xf4, 0x1a, 0x36, 0x9b, 0x8c, 0xff, 0xcc, 0x34, 0xda, 0x64, 0xac, 0xcc, ++ 0xc1, 0x67, 0xff, 0x1b, 0x5f, 0xf0, 0x50, 0x4f, 0x87, 0x2b, 0xa4, 0x7e, ++ 0xa6, 0xd6, 0x92, 0xab, 0x0f, 0x16, 0xa3, 0x88, 0xb9, 0x6b, 0x7f, 0x95, ++ 0xaf, 0x43, 0xb7, 0x15, 0xe2, 0xfc, 0x57, 0xfe, 0x13, 0x52, 0x55, 0x79, ++ 0x70, 0xd5, 0x02, 0x0f, 0xc6, 0x6d, 0xb0, 0xd5, 0x12, 0x7b, 0x1b, 0x80, ++ 0xe6, 0x09, 0xee, 0xdb, 0xa0, 0x82, 0xa7, 0x92, 0x36, 0x3c, 0x9a, 0xb4, ++ 0x63, 0x6d, 0x12, 0xdf, 0x59, 0x04, 0x4c, 0xd7, 0xc0, 0xdf, 0x3e, 0xa3, ++ 0x60, 0x6b, 0x29, 0xfc, 0xad, 0x31, 0xc5, 0xdf, 0xb2, 0x96, 0x39, 0xd3, ++ 0x9a, 0x09, 0xe2, 0x19, 0xef, 0x75, 0x0e, 0x70, 0x5f, 0x07, 0xec, 0xa8, ++ 0x19, 0xc0, 0x3d, 0xf9, 0x40, 0x83, 0x13, 0xfe, 0x19, 0xc6, 0x99, 0x72, ++ 0x07, 0xfc, 0x53, 0x97, 0xed, 0xfe, 0xce, 0x1a, 0x3b, 0x37, 0xb7, 0x56, ++ 0x64, 0x71, 0xe1, 0x31, 0xda, 0xf3, 0xa2, 0x41, 0xde, 0xcf, 0xfc, 0x5d, ++ 0x65, 0x9e, 0xf3, 0xc9, 0x9f, 0x48, 0xfd, 0x52, 0xae, 0x49, 0xef, 0x52, ++ 0x41, 0xe9, 0xa0, 0x9d, 0x18, 0x76, 0xce, 0x3c, 0x5f, 0x25, 0xf8, 0x0d, ++ 0x3c, 0x45, 0xd9, 0xdc, 0xfc, 0x4d, 0xad, 0x25, 0x37, 0x5d, 0xa1, 0x62, ++ 0xfd, 0xb0, 0xdc, 0x0b, 0x6b, 0x1e, 0x27, 0x7d, 0x2a, 0x8f, 0x3e, 0x7e, ++ 0xc4, 0xea, 0x77, 0xd9, 0xb8, 0x46, 0x3b, 0x8a, 0x06, 0x81, 0x35, 0x71, ++ 0x3c, 0x51, 0x0c, 0x7f, 0x44, 0x64, 0xac, 0x5b, 0xee, 0xe0, 0xd8, 0x62, ++ 0xb4, 0x4c, 0x64, 0xc6, 0x3d, 0x3c, 0xf1, 0xa3, 0x8a, 0x4c, 0x2d, 0xf7, ++ 0xf7, 0xf7, 0x5e, 0x7b, 0x1a, 0xfc, 0xd8, 0x94, 0xa4, 0xcd, 0xd9, 0x3c, ++ 0x18, 0xce, 0xd6, 0x54, 0x37, 0xa4, 0xbc, 0xb3, 0x7a, 0xa3, 0xff, 0xbd, ++ 0x38, 0xdb, 0x37, 0xa5, 0x2f, 0xcc, 0x70, 0x1e, 0x43, 0xd9, 0x40, 0xdd, ++ 0x0d, 0x4f, 0x9a, 0x88, 0xea, 0x26, 0xc6, 0xf9, 0x79, 0x53, 0x87, 0x51, ++ 0x44, 0x5f, 0xd8, 0x18, 0xfb, 0xd2, 0x34, 0xb2, 0xfe, 0xfc, 0x4a, 0x22, ++ 0xa0, 0x6c, 0x21, 0x57, 0x7e, 0x95, 0xf1, 0x74, 0x8c, 0x9f, 0x51, 0xe6, ++ 0x70, 0x4e, 0xca, 0x6d, 0xa3, 0x5f, 0xef, 0x4c, 0x01, 0x23, 0xcc, 0xd1, ++ 0x0f, 0x2e, 0x17, 0xfe, 0x5e, 0xc4, 0xe7, 0xd1, 0x6b, 0x78, 0x4f, 0x9a, ++ 0x9f, 0x23, 0xfc, 0x4c, 0x72, 0x4f, 0xf9, 0x3c, 0x04, 0xc6, 0x1d, 0x88, ++ 0x8c, 0x13, 0x68, 0xc7, 0x03, 0x98, 0x62, 0x0c, 0xbc, 0x31, 0xaa, 0xa2, ++ 0x64, 0xac, 0x1c, 0x1f, 0x1d, 0x26, 0x3e, 0x1e, 0xca, 0x70, 0xfe, 0x4d, ++ 0xe3, 0xd2, 0xdf, 0x92, 0xf5, 0x49, 0x1f, 0x58, 0xfc, 0xa9, 0x00, 0x63, ++ 0xa4, 0x1f, 0xd2, 0x0b, 0x7e, 0x57, 0xe7, 0xdc, 0xaa, 0xf4, 0xf1, 0x5a, ++ 0x71, 0x34, 0xea, 0xf3, 0xf4, 0xd1, 0xe6, 0x0d, 0x87, 0xf8, 0x58, 0x03, ++ 0x5e, 0x8d, 0xe6, 0x7a, 0x42, 0xbe, 0x96, 0x9f, 0x4a, 0x3d, 0x83, 0x21, ++ 0x3b, 0x4f, 0x93, 0x6b, 0xb9, 0x58, 0x2a, 0x6b, 0x96, 0xba, 0x74, 0x8e, ++ 0xb7, 0xcc, 0xfe, 0xfd, 0x8c, 0x29, 0x7d, 0xca, 0xd7, 0x26, 0xbd, 0x7d, ++ 0x29, 0xe8, 0x56, 0xac, 0x3c, 0x5c, 0xe7, 0x4d, 0x1a, 0x90, 0xfd, 0x6d, ++ 0xa0, 0x0c, 0xdf, 0xa5, 0xed, 0x07, 0x44, 0xd7, 0x8c, 0xed, 0x52, 0xef, ++ 0x2d, 0x43, 0xff, 0x40, 0x39, 0xf6, 0x0c, 0x18, 0xe8, 0x5d, 0xde, 0x86, ++ 0x33, 0x51, 0x13, 0x9b, 0x42, 0x26, 0xd6, 0x84, 0xbc, 0x81, 0x57, 0x50, ++ 0xdf, 0x78, 0x14, 0x8f, 0x91, 0x43, 0xa8, 0xd4, 0xc9, 0x37, 0xf0, 0xce, ++ 0x5e, 0x07, 0x36, 0xeb, 0x7f, 0x4c, 0x1f, 0x36, 0xcd, 0xf7, 0x96, 0x2d, ++ 0xc0, 0x70, 0xa2, 0x5e, 0xed, 0xa6, 0x7c, 0x91, 0x36, 0xee, 0x55, 0xd0, ++ 0x81, 0x67, 0xf5, 0xef, 0xf0, 0x5e, 0xb7, 0xcd, 0xa1, 0xc9, 0x77, 0x1b, ++ 0xe3, 0xa9, 0xec, 0xa5, 0x41, 0xfb, 0xca, 0xc4, 0xb2, 0x48, 0xb6, 0xce, ++ 0xbe, 0xb9, 0x41, 0x30, 0xbf, 0x18, 0xa7, 0xa9, 0xb7, 0x13, 0xc9, 0x08, ++ 0xc3, 0x2e, 0x94, 0x67, 0x1b, 0xba, 0xf0, 0x34, 0xf9, 0xc6, 0x3b, 0x24, ++ 0x02, 0xf7, 0xc7, 0x15, 0x34, 0xd6, 0xe9, 0xb8, 0x98, 0xfe, 0x06, 0xde, ++ 0x1a, 0x0d, 0xe3, 0x4d, 0xc6, 0xf4, 0x25, 0xdf, 0xf5, 0x92, 0x83, 0x7a, ++ 0x70, 0x3e, 0x1d, 0xc6, 0xb9, 0xa8, 0xb7, 0xf5, 0x05, 0x65, 0x01, 0x7e, ++ 0x9a, 0x76, 0xe0, 0xde, 0x38, 0xf0, 0x4b, 0xce, 0xe3, 0x8f, 0x3b, 0x70, ++ 0x25, 0xad, 0xe2, 0x28, 0xf7, 0xc7, 0x11, 0x5a, 0x02, 0xa3, 0xcd, 0x83, ++ 0x23, 0x43, 0x8f, 0x62, 0x2a, 0xf5, 0x28, 0x4e, 0x25, 0xdf, 0x31, 0x5d, ++ 0x9a, 0xf4, 0x75, 0x5c, 0xb8, 0xc2, 0x7c, 0x6c, 0x9a, 0xda, 0x28, 0x5e, ++ 0xd1, 0xca, 0x38, 0xaf, 0x19, 0xa2, 0xf7, 0xb7, 0xf8, 0xdb, 0xfd, 0xf1, ++ 0x46, 0x1c, 0x1c, 0xa7, 0x4a, 0x13, 0x3a, 0x12, 0x31, 0x79, 0x56, 0x03, ++ 0x62, 0xe4, 0x85, 0xfd, 0x4c, 0xdb, 0xb7, 0x86, 0xee, 0x95, 0x5c, 0x43, ++ 0x69, 0xa9, 0xed, 0xcf, 0xae, 0xa3, 0x71, 0x56, 0xcf, 0x4e, 0x72, 0x28, ++ 0xea, 0x95, 0xe3, 0xfe, 0x36, 0x11, 0xb4, 0x62, 0xd3, 0xb1, 0x9b, 0xfb, ++ 0xd1, 0xc8, 0xfd, 0xf8, 0x06, 0x2e, 0xee, 0x6d, 0xc3, 0x5b, 0xc4, 0xbb, ++ 0xd2, 0x65, 0xbe, 0x4e, 0xa7, 0xad, 0x9e, 0x73, 0xa7, 0xcd, 0x54, 0x95, ++ 0xe8, 0xb4, 0x0d, 0xbf, 0x88, 0x8a, 0x4e, 0xd3, 0xc4, 0x3f, 0x9f, 0xc7, ++ 0x6f, 0xff, 0xcb, 0x4a, 0xda, 0xb3, 0xad, 0x3b, 0x98, 0xe9, 0x41, 0x15, ++ 0xaf, 0x70, 0xe1, 0xaa, 0x25, 0x9b, 0xc8, 0xfa, 0x87, 0xe4, 0xfb, 0x85, ++ 0xb9, 0xa6, 0x4a, 0xe4, 0x33, 0xcc, 0x3c, 0x4d, 0x0b, 0xe4, 0x29, 0x12, ++ 0x67, 0x03, 0x56, 0x3d, 0xbe, 0x2e, 0xde, 0x05, 0x7b, 0xa8, 0x98, 0x79, ++ 0x98, 0x77, 0xa6, 0x03, 0x6f, 0xe1, 0xda, 0xa4, 0x0b, 0x8b, 0xe3, 0x1a, ++ 0x5e, 0x9e, 0x7c, 0x8d, 0xcf, 0xfa, 0x47, 0x5c, 0xe6, 0x77, 0x5f, 0x3c, ++ 0xe3, 0x6f, 0xdd, 0x0d, 0x6d, 0x78, 0x30, 0x2d, 0xeb, 0xcb, 0xe3, 0x83, ++ 0x74, 0x44, 0xd2, 0xb2, 0xce, 0x18, 0x7d, 0x43, 0xd6, 0x59, 0xfe, 0xef, ++ 0xac, 0xf3, 0xbf, 0x72, 0xbe, 0x05, 0xf4, 0xa5, 0x5c, 0xec, 0x28, 0xc1, ++ 0x91, 0xa4, 0x8a, 0xd3, 0x7a, 0x31, 0x2e, 0xa9, 0x52, 0x5f, 0x76, 0x31, ++ 0x86, 0x38, 0xd0, 0xcc, 0x9c, 0x71, 0x84, 0x9f, 0x8d, 0xcc, 0x7f, 0xce, ++ 0xea, 0x0e, 0x9c, 0xd2, 0x17, 0x10, 0xeb, 0xef, 0xb4, 0x61, 0xb9, 0x46, ++ 0xb2, 0x5f, 0x56, 0x8e, 0x73, 0x52, 0xff, 0xb3, 0xae, 0xbb, 0xa4, 0x2f, ++ 0x89, 0x31, 0xea, 0x2b, 0x2f, 0xf6, 0x1b, 0xf3, 0xaa, 0x85, 0x35, 0x77, ++ 0xca, 0x77, 0xe7, 0x3c, 0x12, 0x82, 0x7f, 0x69, 0x6e, 0xad, 0xca, 0xc6, ++ 0x2e, 0xe5, 0x4f, 0x2b, 0x33, 0x78, 0x21, 0x71, 0xec, 0xef, 0x72, 0xd8, ++ 0x21, 0xf9, 0x64, 0x1b, 0xe3, 0x10, 0xe3, 0xf2, 0xf1, 0x6d, 0x92, 0xe7, ++ 0xd9, 0xc2, 0xef, 0xb5, 0xad, 0xd2, 0xf2, 0x60, 0xb7, 0xf8, 0xde, 0x7b, ++ 0x2f, 0x65, 0x38, 0xfa, 0xfb, 0x2f, 0x69, 0xd6, 0xdf, 0xeb, 0x2f, 0x2d, ++ 0xb6, 0xfe, 0x7e, 0xf2, 0x92, 0x2f, 0x75, 0x2b, 0x5e, 0x65, 0x38, 0xb0, ++ 0x75, 0x6e, 0x05, 0x7d, 0xba, 0xa1, 0x3c, 0xdc, 0x20, 0x5c, 0x72, 0x36, ++ 0x8f, 0x08, 0x28, 0x67, 0xa3, 0x92, 0xa7, 0x15, 0x1a, 0xcc, 0xe3, 0x95, ++ 0x46, 0xbf, 0x46, 0x3c, 0xee, 0x42, 0xc9, 0x32, 0x0d, 0x17, 0xa8, 0x73, ++ 0xc2, 0x28, 0xed, 0xf8, 0xff, 0x20, 0xba, 0x17, 0xed, 0x85, 0x16, 0xf6, ++ 0x98, 0x66, 0x7f, 0x48, 0x6a, 0x0c, 0x32, 0xaf, 0x03, 0x1f, 0x70, 0x2f, ++ 0x7f, 0x35, 0x5a, 0x84, 0xf7, 0x53, 0x1a, 0x2e, 0xa5, 0xdb, 0xb0, 0x7b, ++ 0x32, 0xc3, 0x33, 0x4e, 0x59, 0xfc, 0x5b, 0x63, 0x8e, 0xe9, 0xc0, 0xc1, ++ 0xa8, 0x86, 0x58, 0xe2, 0x75, 0xb3, 0x40, 0xf3, 0x4d, 0xf9, 0xed, 0x0e, ++ 0x1c, 0x48, 0x4f, 0x63, 0x72, 0xe0, 0x63, 0xd3, 0xae, 0x75, 0xe1, 0xa3, ++ 0xd0, 0x34, 0x26, 0x0e, 0x49, 0x5f, 0x4f, 0x47, 0xff, 0x90, 0x86, 0xde, ++ 0x84, 0x0d, 0x7b, 0x96, 0xb7, 0xa0, 0x7f, 0xb2, 0x19, 0xc6, 0x98, 0x07, ++ 0x7b, 0xd2, 0x69, 0x4c, 0x8d, 0x4e, 0xe3, 0x4c, 0x52, 0x6b, 0x2c, 0x50, ++ 0xa6, 0x71, 0x9a, 0xcf, 0xd9, 0x91, 0x78, 0x1b, 0x06, 0xe7, 0xd8, 0x99, ++ 0x94, 0x9a, 0xa4, 0x3c, 0x67, 0x1a, 0xdd, 0xa9, 0xbb, 0xd5, 0x44, 0x28, ++ 0x4f, 0xa2, 0xa7, 0x3d, 0x53, 0xab, 0x27, 0xbe, 0xa6, 0x35, 0xa5, 0x8f, ++ 0xfb, 0x74, 0x34, 0x9d, 0xab, 0xdb, 0xdf, 0x59, 0x0b, 0xd1, 0xd1, 0x37, ++ 0xd4, 0xc2, 0x31, 0x1a, 0xba, 0x13, 0xd2, 0x1b, 0xf5, 0xf1, 0x99, 0x26, ++ 0x7e, 0xa9, 0x7b, 0xdd, 0x8b, 0xf9, 0xf7, 0xb0, 0xde, 0x89, 0x2d, 0x9c, ++ 0x6b, 0x8a, 0x79, 0x90, 0xa6, 0x78, 0x1b, 0x0d, 0xd8, 0xf1, 0x9e, 0x4e, ++ 0xce, 0x53, 0x69, 0xc7, 0xab, 0x7a, 0x09, 0x22, 0x65, 0x76, 0xd4, 0x87, ++ 0x18, 0xa7, 0xb3, 0x71, 0xfb, 0xc3, 0xa4, 0x82, 0x47, 0x89, 0xa9, 0x27, ++ 0x42, 0xf5, 0xed, 0xab, 0x85, 0xd1, 0x1d, 0x52, 0x70, 0x4d, 0xbb, 0x61, ++ 0x1a, 0x8c, 0x5d, 0x2e, 0x7f, 0x6e, 0x8f, 0x7e, 0x6d, 0x66, 0xfa, 0x9b, ++ 0x5f, 0x98, 0xb9, 0x71, 0x33, 0x94, 0xf1, 0x29, 0x8e, 0x5b, 0xbc, 0xac, ++ 0xbe, 0x53, 0xc6, 0xb9, 0x89, 0xe9, 0x32, 0x4e, 0xea, 0xd1, 0xb7, 0xc6, ++ 0xe9, 0xd8, 0x39, 0x14, 0xb1, 0xe4, 0xdd, 0x95, 0xc0, 0x52, 0x07, 0xc4, ++ 0x9f, 0xea, 0xd5, 0x2b, 0x40, 0xd7, 0xb4, 0x3e, 0x87, 0x5c, 0xc7, 0x1f, ++ 0xd8, 0x08, 0xd1, 0x95, 0xe4, 0x92, 0x6f, 0x63, 0x4f, 0x74, 0x14, 0xcc, ++ 0x27, 0x89, 0x73, 0xfe, 0xf5, 0x23, 0x48, 0xe1, 0xf9, 0x74, 0x0a, 0x2f, ++ 0x50, 0x47, 0x86, 0x75, 0x6e, 0x29, 0x8d, 0x3f, 0x8f, 0xbe, 0x8d, 0x98, ++ 0xb5, 0x67, 0x47, 0xb1, 0x21, 0xfa, 0xf7, 0x55, 0xc2, 0x11, 0x77, 0x24, ++ 0x56, 0x72, 0x7e, 0xd1, 0xab, 0xb7, 0xd5, 0xc0, 0x97, 0x9c, 0x7f, 0x25, ++ 0x7a, 0x46, 0x4c, 0xf3, 0x7b, 0x8c, 0x5f, 0x3f, 0x23, 0xbf, 0xba, 0x96, ++ 0x3d, 0x03, 0x55, 0x40, 0x7d, 0x6b, 0x56, 0x1c, 0x6b, 0xe3, 0x3e, 0x57, ++ 0x0b, 0xaf, 0x47, 0xc9, 0xb8, 0xa6, 0x2c, 0x8e, 0xc9, 0xbe, 0x93, 0x37, ++ 0x8e, 0x7b, 0xf0, 0x14, 0x39, 0x4a, 0xfe, 0xe1, 0x1f, 0x28, 0x12, 0xcb, ++ 0x6a, 0x0e, 0x91, 0xef, 0x1f, 0xf2, 0x28, 0x4b, 0xf6, 0xb9, 0xf0, 0x68, ++ 0x4c, 0xea, 0x37, 0xcd, 0xe8, 0xd9, 0xaf, 0xf1, 0x1e, 0xaf, 0x7e, 0x81, ++ 0x39, 0xe9, 0x69, 0xf8, 0x3c, 0x23, 0xe4, 0x55, 0x6e, 0x62, 0xb1, 0xe3, ++ 0x70, 0x29, 0x8a, 0x0e, 0xab, 0xb0, 0x1d, 0x2e, 0x47, 0xf1, 0x61, 0x37, ++ 0x6a, 0x18, 0xdb, 0xdc, 0xe3, 0x17, 0x31, 0xb9, 0x0f, 0x6a, 0x51, 0xf8, ++ 0x73, 0x33, 0x5f, 0x93, 0x3e, 0x5b, 0x00, 0xa5, 0xe3, 0xdb, 0x91, 0x8e, ++ 0x05, 0x51, 0x3c, 0x4e, 0x2a, 0x35, 0x7e, 0x5c, 0xa9, 0xe7, 0x33, 0x1f, ++ 0x8a, 0x69, 0x9c, 0x2b, 0xc3, 0x75, 0x56, 0x73, 0x5c, 0x5f, 0xc2, 0xbb, ++ 0x5e, 0x7a, 0x65, 0xd7, 0xf4, 0x37, 0x50, 0x30, 0x70, 0xeb, 0x2c, 0x97, ++ 0x16, 0xc2, 0x3c, 0x72, 0x91, 0xd6, 0x67, 0x91, 0x39, 0xd7, 0xf5, 0x70, ++ 0x76, 0x4d, 0x41, 0x59, 0x93, 0xb3, 0x8d, 0xb6, 0x30, 0x57, 0xea, 0x5f, ++ 0xb8, 0x4c, 0xfb, 0xb9, 0x9f, 0xf2, 0xde, 0x60, 0x6e, 0xd8, 0x19, 0x13, ++ 0xbb, 0xff, 0x81, 0x42, 0xbf, 0xc1, 0x4c, 0xaa, 0x08, 0x1f, 0xa7, 0x3c, ++ 0x8a, 0x8f, 0xeb, 0xf9, 0x0b, 0x5e, 0xff, 0x73, 0xae, 0x67, 0xc7, 0x7e, ++ 0x6f, 0xeb, 0x49, 0xc5, 0xdb, 0xbe, 0x4e, 0xf1, 0xa9, 0x3b, 0x94, 0x62, ++ 0x5c, 0x1e, 0x2d, 0xc5, 0x15, 0xc6, 0xe2, 0x1b, 0xa3, 0xe5, 0xb8, 0x3a, ++ 0x5a, 0x49, 0x5f, 0xd1, 0x38, 0x87, 0x69, 0x96, 0x68, 0x6e, 0xcc, 0xa4, ++ 0x5f, 0xc0, 0x9c, 0xd8, 0x02, 0x7c, 0x9c, 0xde, 0x82, 0xd2, 0x98, 0x70, ++ 0x76, 0x0f, 0x3e, 0xe2, 0xf5, 0x0f, 0xd3, 0x13, 0x28, 0xdc, 0xf7, 0x39, ++ 0xef, 0x31, 0xcd, 0x87, 0xb8, 0xc6, 0xab, 0xe9, 0x0e, 0x14, 0xef, 0xdb, ++ 0x06, 0xc7, 0x3e, 0xb3, 0xab, 0x27, 0x84, 0x9f, 0xda, 0xb9, 0x96, 0x6e, ++ 0xdd, 0x3b, 0xb5, 0xd8, 0x1e, 0xe4, 0x1c, 0x3a, 0xe7, 0x3c, 0xae, 0x2c, ++ 0x19, 0xdf, 0x86, 0xd2, 0x7d, 0x1e, 0x6c, 0xa5, 0x2e, 0x27, 0xa0, 0x05, ++ 0xd6, 0x29, 0xdb, 0x90, 0x77, 0x38, 0xa3, 0x83, 0x4d, 0xe3, 0x19, 0x1f, ++ 0x79, 0xa8, 0x41, 0xea, 0x43, 0xc7, 0x95, 0x11, 0xcb, 0x47, 0xdc, 0x72, ++ 0xfe, 0x04, 0xd3, 0xe9, 0x22, 0x9c, 0x4d, 0x89, 0x8e, 0xe4, 0xec, 0xda, ++ 0x04, 0xf2, 0xf7, 0x11, 0x23, 0x47, 0x75, 0x8b, 0x43, 0x88, 0x6f, 0x8c, ++ 0xa6, 0xef, 0xe6, 0x5f, 0x41, 0xec, 0x49, 0xd4, 0xd0, 0xb7, 0x16, 0x60, ++ 0xcd, 0x3e, 0xe9, 0x91, 0x4e, 0xdd, 0xef, 0xa2, 0x35, 0x8d, 0xa5, 0xef, ++ 0xe6, 0x5b, 0x0d, 0xb4, 0x53, 0x6f, 0x8b, 0x01, 0x39, 0xab, 0x61, 0x62, ++ 0x5a, 0x3f, 0xae, 0xd8, 0x62, 0x92, 0x6f, 0xb5, 0xd1, 0xe7, 0x5b, 0xd1, ++ 0x33, 0x84, 0xf6, 0x83, 0x0d, 0xd2, 0xb7, 0x75, 0x62, 0x84, 0xf9, 0xd3, ++ 0x65, 0xe6, 0x1c, 0xd4, 0xb9, 0x9a, 0x17, 0xce, 0xc3, 0xf0, 0xa8, 0x0b, ++ 0x3f, 0x1a, 0xf5, 0xa0, 0x31, 0xf6, 0x39, 0x31, 0xa3, 0x10, 0xc7, 0xa9, ++ 0xef, 0x49, 0xf2, 0x9f, 0x8f, 0xa2, 0x2a, 0x26, 0x18, 0x6b, 0x3f, 0x8c, ++ 0x56, 0x62, 0x9c, 0xb9, 0xd6, 0x75, 0xe2, 0x4c, 0x9a, 0x7b, 0xf3, 0x01, ++ 0xf3, 0x8e, 0xef, 0xa5, 0x83, 0xf8, 0x55, 0x34, 0x88, 0x57, 0xa9, 0xc7, ++ 0xba, 0x98, 0x9b, 0x32, 0x1d, 0x53, 0x70, 0xe8, 0xb8, 0x92, 0x47, 0xbb, ++ 0xf0, 0xc7, 0x34, 0xcf, 0x48, 0xd6, 0x2e, 0xb4, 0xf1, 0x56, 0xfa, 0x91, ++ 0xf4, 0xff, 0x25, 0x3e, 0x38, 0xf4, 0x11, 0x90, 0xd3, 0x05, 0x73, 0x75, ++ 0x42, 0xaf, 0x7b, 0x0a, 0x15, 0xf4, 0xa5, 0x2f, 0x4d, 0x55, 0x93, 0x9a, ++ 0x58, 0x32, 0x74, 0x2d, 0xaa, 0xa9, 0x57, 0xad, 0x35, 0x18, 0x8a, 0x73, ++ 0x39, 0x39, 0x46, 0xe5, 0x0e, 0xae, 0x5f, 0x23, 0x66, 0x38, 0xe8, 0x32, ++ 0x26, 0xef, 0xbb, 0x8e, 0xfb, 0x0e, 0xfd, 0x69, 0x75, 0x86, 0x03, 0xd1, ++ 0x9f, 0x6d, 0x77, 0xd6, 0xb1, 0xa4, 0x96, 0xbd, 0x37, 0xf4, 0x46, 0x34, ++ 0x56, 0x2d, 0x3d, 0xa5, 0x93, 0x08, 0x52, 0x2f, 0x77, 0xcb, 0x15, 0x4c, ++ 0xbc, 0x45, 0x4c, 0xb9, 0x9a, 0x14, 0xbe, 0x24, 0x3c, 0xa9, 0x8b, 0x31, ++ 0xa9, 0x84, 0x3c, 0x41, 0xc3, 0x4e, 0x72, 0x79, 0x5f, 0x7c, 0x8a, 0xb9, ++ 0xca, 0x57, 0xc9, 0xd5, 0x4a, 0x39, 0x8d, 0xc1, 0xe7, 0xb5, 0x62, 0x0f, ++ 0x7d, 0xb3, 0x40, 0x5b, 0x8c, 0x35, 0xe4, 0x41, 0x0e, 0x8d, 0xa1, 0xe4, ++ 0x09, 0x89, 0x27, 0x40, 0x6d, 0x5c, 0x95, 0x7e, 0xcf, 0xfa, 0x9f, 0xe1, ++ 0x7e, 0xb4, 0x57, 0xb9, 0x20, 0x3d, 0x9a, 0x37, 0xd1, 0x84, 0xd4, 0xd7, ++ 0xad, 0xde, 0x30, 0xdc, 0x61, 0xcd, 0xb8, 0x88, 0x45, 0x16, 0x23, 0x2f, ++ 0x0c, 0x8b, 0x3c, 0x95, 0xd4, 0xbf, 0x8a, 0x77, 0xa9, 0xd7, 0x2b, 0x51, ++ 0xdf, 0xcc, 0x83, 0xa8, 0x3f, 0x73, 0xc5, 0x2e, 0xfd, 0x2b, 0xb9, 0x3f, ++ 0x08, 0x8d, 0xf3, 0x7d, 0x1a, 0x0d, 0x61, 0x40, 0x95, 0xef, 0xc2, 0x1b, ++ 0x5b, 0xd1, 0x3d, 0x22, 0x32, 0x98, 0x66, 0x39, 0xf1, 0xf1, 0x09, 0xeb, ++ 0xf9, 0xf2, 0xec, 0x3b, 0xf3, 0x0e, 0xaf, 0x6a, 0x20, 0x97, 0x7b, 0x4c, ++ 0xe3, 0x68, 0xd2, 0x03, 0xc7, 0xf2, 0xff, 0x41, 0x3d, 0x4c, 0x63, 0x34, ++ 0xa5, 0x91, 0x53, 0x16, 0xc1, 0x53, 0x15, 0x44, 0x3f, 0xe3, 0x78, 0x8c, ++ 0xf7, 0xa7, 0x63, 0x45, 0x30, 0xaa, 0x32, 0xcf, 0xfc, 0x6a, 0xfc, 0xba, ++ 0x39, 0xf5, 0xb8, 0xcc, 0x29, 0xdf, 0x7f, 0xce, 0x31, 0x73, 0xe5, 0xd8, ++ 0x23, 0x36, 0xc7, 0xae, 0x9a, 0x53, 0xad, 0xb3, 0x7f, 0x2f, 0xb3, 0xce, ++ 0x10, 0x45, 0x6c, 0x55, 0x52, 0x6f, 0xb1, 0xf4, 0xd2, 0x4d, 0xbd, 0xcc, ++ 0xd1, 0xde, 0x36, 0x1f, 0xb3, 0xe4, 0x9a, 0xaa, 0x16, 0x9e, 0x5f, 0x1b, ++ 0xff, 0xbc, 0x5a, 0xea, 0xa5, 0x12, 0xc3, 0x5c, 0x61, 0xad, 0xf1, 0x0c, ++ 0xfe, 0xd1, 0xbc, 0x74, 0xdb, 0x3c, 0x15, 0xbc, 0x26, 0xf1, 0xe8, 0x52, ++ 0xb6, 0x1f, 0xed, 0xce, 0xe6, 0x02, 0xd3, 0x38, 0x99, 0x94, 0x58, 0xe0, ++ 0xc1, 0x06, 0xa9, 0x43, 0xa9, 0xde, 0x3e, 0x03, 0x53, 0xe4, 0x7e, 0xef, ++ 0x50, 0xf7, 0x4c, 0x80, 0xfc, 0x53, 0xe4, 0x7f, 0xb3, 0xe3, 0x55, 0x04, ++ 0xa9, 0x4a, 0xe9, 0x29, 0x08, 0x9e, 0x4e, 0x63, 0x57, 0xf2, 0x75, 0xe2, ++ 0xda, 0xc7, 0xe4, 0x43, 0x5d, 0xe4, 0xda, 0xd3, 0xe8, 0x49, 0x35, 0xe3, ++ 0xe5, 0xfd, 0x2d, 0xc4, 0x18, 0xc1, 0x4a, 0xdf, 0x99, 0xcb, 0xf6, 0x66, ++ 0x1c, 0x1c, 0x4b, 0x23, 0x75, 0x58, 0x62, 0xa4, 0x9c, 0xc7, 0x92, 0xf8, ++ 0xa8, 0x21, 0x9a, 0x38, 0x0d, 0x83, 0x7f, 0xf7, 0x24, 0xb6, 0x21, 0x72, ++ 0xf8, 0x6d, 0x72, 0xfc, 0x69, 0xac, 0x1e, 0xd0, 0xd6, 0x1f, 0xc1, 0x34, ++ 0xd6, 0x32, 0x7e, 0x26, 0x13, 0x2d, 0x9c, 0xbf, 0x19, 0xbd, 0xfb, 0xbd, ++ 0x01, 0x87, 0x6d, 0x0e, 0x63, 0x94, 0x07, 0x3b, 0x27, 0x23, 0x30, 0x46, ++ 0xe4, 0x8c, 0x81, 0x0b, 0xc1, 0xb8, 0x47, 0xf9, 0x90, 0x3c, 0xb9, 0x3e, ++ 0xee, 0x65, 0x7e, 0xe6, 0x35, 0xd6, 0x2a, 0x3e, 0x4f, 0x9e, 0x4d, 0xfa, ++ 0x59, 0x73, 0x70, 0x46, 0x57, 0x50, 0x70, 0xbf, 0x82, 0x10, 0x63, 0x97, ++ 0xa7, 0x9a, 0x31, 0x65, 0x44, 0x47, 0xef, 0x10, 0xd7, 0x7b, 0x73, 0xdf, ++ 0x64, 0xbf, 0x1e, 0xe1, 0x7c, 0xb2, 0x77, 0x2d, 0xe8, 0x9d, 0xf4, 0x75, ++ 0x9c, 0x81, 0xdb, 0xe2, 0x5c, 0xbd, 0x43, 0xb9, 0x7b, 0x50, 0xfc, 0x71, ++ 0x83, 0x37, 0x30, 0x47, 0x91, 0x7b, 0x77, 0x10, 0xbf, 0x66, 0xdf, 0x6f, ++ 0x28, 0xc9, 0xe5, 0xe4, 0xa5, 0x36, 0xf1, 0x8b, 0x6e, 0xcb, 0x5f, 0x44, ++ 0x17, 0xbd, 0xc9, 0x08, 0x6d, 0xfa, 0xc7, 0x66, 0xaa, 0xb5, 0x95, 0x72, ++ 0x36, 0x48, 0xaf, 0xc7, 0xe2, 0x26, 0xe7, 0xa5, 0xee, 0xe6, 0x94, 0xd8, ++ 0xdd, 0xdd, 0xee, 0xa2, 0x3d, 0xe5, 0x13, 0x9f, 0x0a, 0x26, 0x5c, 0x70, ++ 0x1d, 0x29, 0x42, 0xfe, 0xb0, 0xf0, 0x34, 0xa8, 0xa5, 0xcc, 0xfb, 0xe5, ++ 0x3c, 0xc3, 0x30, 0x6d, 0xd4, 0x36, 0x41, 0x1f, 0x8b, 0xba, 0xb1, 0x68, ++ 0xc2, 0x8d, 0x1f, 0x11, 0x03, 0x6a, 0x26, 0x34, 0x1c, 0x27, 0x06, 0xb8, ++ 0x27, 0x02, 0x98, 0x24, 0x06, 0xcc, 0xc9, 0xd6, 0x3e, 0xde, 0x4c, 0xcf, ++ 0x9f, 0x8b, 0x42, 0x79, 0x96, 0xe8, 0x31, 0xb7, 0xaf, 0xb2, 0xa7, 0x2d, ++ 0xc4, 0x3d, 0xd9, 0xdf, 0x00, 0x76, 0x0f, 0xa5, 0xb1, 0x6a, 0x9f, 0x89, ++ 0x9f, 0xeb, 0xf5, 0xee, 0x02, 0x45, 0xf2, 0x04, 0x13, 0x69, 0x5d, 0xce, ++ 0x4d, 0x7a, 0xd7, 0xcb, 0xb9, 0xe2, 0xf6, 0x4a, 0x13, 0x79, 0x21, 0xaf, ++ 0x4e, 0xb4, 0x5f, 0x5f, 0xa0, 0x48, 0xdc, 0xaa, 0xf7, 0x6c, 0xc1, 0x7c, ++ 0x64, 0x7a, 0x65, 0x0f, 0x62, 0x8b, 0xaa, 0xd0, 0x1f, 0x5b, 0xb0, 0xa7, ++ 0xcc, 0x70, 0x5d, 0x6b, 0x30, 0xcd, 0x4d, 0xa1, 0xdf, 0x56, 0x59, 0xb5, ++ 0x65, 0xdb, 0x1f, 0x71, 0xed, 0x6d, 0x5c, 0xb7, 0xac, 0xbd, 0x03, 0xb1, ++ 0xbd, 0x0a, 0xd2, 0xfe, 0x0e, 0x44, 0x47, 0x3b, 0xd0, 0xbf, 0x57, 0x30, ++ 0xa1, 0x8f, 0x98, 0x60, 0x76, 0x3d, 0x1b, 0x7a, 0x0c, 0x57, 0x2d, 0x16, ++ 0x20, 0x63, 0xbc, 0x01, 0x8f, 0x6d, 0xf6, 0x3e, 0xe4, 0x53, 0xfe, 0x8c, ++ 0xef, 0x34, 0x0f, 0x08, 0xa7, 0xf6, 0xf7, 0xf5, 0x72, 0xff, 0x1f, 0x3f, ++ 0x24, 0xf1, 0xc6, 0x34, 0xfb, 0xc8, 0x59, 0x51, 0x26, 0x6b, 0xd0, 0xa4, ++ 0x3e, 0xfe, 0x71, 0x8d, 0xe6, 0x9b, 0xe9, 0x67, 0x6c, 0xbf, 0xb8, 0xaf, ++ 0x7e, 0xcb, 0x16, 0xe1, 0x31, 0xcb, 0x84, 0xdb, 0xa5, 0x71, 0xe1, 0xf0, ++ 0x7d, 0x48, 0x3d, 0xce, 0xf5, 0x70, 0xaf, 0x9c, 0xf1, 0x2f, 0x4c, 0xe1, ++ 0x72, 0x76, 0x4d, 0x53, 0x8f, 0x12, 0xfb, 0x6c, 0x13, 0x7e, 0xf4, 0x94, ++ 0xc1, 0xb8, 0xd6, 0x20, 0xcf, 0xbf, 0x29, 0x3f, 0xd7, 0xdb, 0x8c, 0xfe, ++ 0xfd, 0xc2, 0x35, 0x84, 0x97, 0xf9, 0x8c, 0x0f, 0xd0, 0x82, 0xe4, 0x64, ++ 0xe6, 0x59, 0xd1, 0xc4, 0x9d, 0xb6, 0x22, 0xfb, 0x7e, 0x1a, 0xbb, 0x69, ++ 0x97, 0x2e, 0xce, 0xcf, 0xf8, 0xc2, 0xf9, 0xb4, 0x40, 0x81, 0x3c, 0x6f, ++ 0xe2, 0xc7, 0xe6, 0x9e, 0x2a, 0xd1, 0x8d, 0xcc, 0x7f, 0xba, 0x4a, 0x30, ++ 0x63, 0x53, 0xe8, 0x0f, 0xad, 0xf5, 0x75, 0xfe, 0xf5, 0xb6, 0x64, 0xf4, ++ 0x21, 0xf7, 0x9e, 0xfe, 0x3d, 0xf2, 0x5c, 0xe0, 0x7d, 0x22, 0x53, 0x07, ++ 0x76, 0xef, 0x85, 0x51, 0xa8, 0x49, 0xaf, 0xa0, 0x03, 0x7d, 0xd4, 0xef, ++ 0xce, 0x64, 0x07, 0x0e, 0xd2, 0x67, 0x87, 0xf5, 0x13, 0x35, 0x36, 0xd4, ++ 0xcd, 0xd8, 0x31, 0xf5, 0x93, 0x45, 0xc4, 0xd3, 0x25, 0xcb, 0xfc, 0xf4, ++ 0xaf, 0x0e, 0xc4, 0x53, 0x63, 0x73, 0xad, 0x3e, 0x9f, 0x4d, 0xe2, 0x9f, ++ 0xe8, 0xa2, 0x13, 0x85, 0x03, 0xa7, 0xe1, 0x1c, 0xe8, 0x44, 0x81, 0xbf, ++ 0x09, 0x0f, 0x87, 0x2e, 0x99, 0x57, 0x35, 0x87, 0xfb, 0x24, 0xf5, 0x73, ++ 0x22, 0x58, 0xc3, 0x7c, 0x92, 0x39, 0xcc, 0xc8, 0x3c, 0xfa, 0x7e, 0x03, ++ 0xf9, 0xae, 0xf4, 0xf4, 0x6d, 0x58, 0xbb, 0x5c, 0x72, 0x75, 0x85, 0xb6, ++ 0x5d, 0xcd, 0x5c, 0x53, 0x53, 0x9f, 0xb7, 0xce, 0x5f, 0x90, 0x87, 0x55, ++ 0x7a, 0xf0, 0x8c, 0x75, 0xee, 0x40, 0xae, 0x6f, 0x67, 0x8e, 0xb0, 0x1d, ++ 0x35, 0x31, 0xc3, 0x14, 0x7d, 0x9f, 0x44, 0xe4, 0x25, 0x1b, 0xe5, 0x68, ++ 0x5c, 0xe6, 0xdf, 0x32, 0xa3, 0x88, 0x4d, 0xfb, 0xdb, 0x27, 0x14, 0xdd, ++ 0xf5, 0xc8, 0xb8, 0x82, 0xc0, 0x00, 0xe7, 0x0a, 0xfd, 0xf5, 0xdc, 0x4c, ++ 0x7d, 0x2c, 0xc7, 0xf9, 0xb6, 0x93, 0x27, 0x6c, 0x47, 0x09, 0xc7, 0xbb, ++ 0x35, 0xc1, 0x86, 0xc8, 0x4a, 0xe9, 0xa5, 0xa4, 0x43, 0xfe, 0xd6, 0x62, ++ 0x45, 0xf8, 0x90, 0xbf, 0x71, 0xad, 0x22, 0xdc, 0x45, 0xc6, 0xe9, 0xae, ++ 0xba, 0xf1, 0x8b, 0xd9, 0x9e, 0x57, 0x03, 0xf1, 0xc1, 0x63, 0x9d, 0x85, ++ 0x7c, 0xed, 0xe6, 0x79, 0x89, 0x4c, 0xbd, 0xda, 0x19, 0x97, 0xbc, 0xe2, ++ 0x58, 0x68, 0x55, 0xb4, 0x91, 0x58, 0x67, 0x36, 0x8d, 0xd1, 0xee, 0x2f, ++ 0xa3, 0x12, 0xff, 0x33, 0x2a, 0xb8, 0xe6, 0xc1, 0xff, 0x8a, 0xe6, 0x4b, ++ 0xbe, 0x9c, 0x92, 0x7a, 0xe4, 0xb9, 0xa4, 0x61, 0x52, 0xaf, 0x2d, 0x6b, ++ 0x69, 0x4b, 0x81, 0x50, 0x31, 0x50, 0xd5, 0xfd, 0x8c, 0xd3, 0xca, 0xdf, ++ 0x4b, 0x50, 0xc6, 0x18, 0x30, 0x30, 0xf2, 0xfb, 0x6a, 0xaf, 0xc4, 0xe1, ++ 0x42, 0xa9, 0x81, 0xda, 0xb1, 0x33, 0xf4, 0x2f, 0x66, 0x2a, 0x7b, 0x76, ++ 0xf5, 0xc2, 0x5e, 0xb1, 0xd3, 0x00, 0xf2, 0xe3, 0x17, 0x69, 0x93, 0x2a, ++ 0xce, 0x47, 0x7d, 0xfa, 0x3a, 0xdb, 0x37, 0x68, 0xff, 0x8b, 0x6e, 0xc3, ++ 0xee, 0x45, 0xda, 0xa3, 0x78, 0xda, 0xc2, 0xee, 0x30, 0x7a, 0x18, 0x1b, ++ 0xc8, 0xe3, 0x0e, 0x3c, 0x63, 0x53, 0x51, 0x10, 0xf3, 0xa9, 0x3e, 0xe6, ++ 0xdb, 0x3d, 0x7c, 0x86, 0x70, 0xcc, 0x0a, 0x72, 0xc0, 0x67, 0xa3, 0xf5, ++ 0x9e, 0x5f, 0x63, 0x03, 0xfd, 0x51, 0x9e, 0x21, 0x6b, 0xd2, 0x50, 0xcc, ++ 0xbc, 0xf2, 0x14, 0xd7, 0xb1, 0xb3, 0x2c, 0xf3, 0xdc, 0xd2, 0xec, 0xdc, ++ 0xf1, 0x11, 0xe1, 0x5f, 0x2b, 0xb0, 0xce, 0x9a, 0x3b, 0x68, 0xf9, 0xe6, ++ 0x01, 0x39, 0x5b, 0x5e, 0xa7, 0x21, 0x91, 0x6e, 0xc6, 0xb6, 0xf2, 0x05, ++ 0x38, 0x98, 0xd8, 0x8e, 0xa5, 0xe4, 0xc1, 0x4f, 0x96, 0x1b, 0x8c, 0x8d, ++ 0xc4, 0xa1, 0xb8, 0xa6, 0xde, 0xa7, 0x3c, 0x90, 0xed, 0x3f, 0x54, 0xc2, ++ 0x11, 0x97, 0x98, 0x97, 0x87, 0x41, 0x75, 0x3e, 0x8a, 0xac, 0x33, 0x7f, ++ 0x99, 0xb9, 0xfb, 0x47, 0xbc, 0xd9, 0x38, 0x48, 0xd4, 0x88, 0x5b, 0xe7, ++ 0x2d, 0x02, 0x2f, 0x90, 0x4b, 0xa4, 0x18, 0x01, 0xf3, 0xc2, 0x5a, 0x6a, ++ 0x33, 0x0a, 0x60, 0x54, 0x0b, 0x26, 0xca, 0x98, 0x79, 0x77, 0xc8, 0x54, ++ 0x9e, 0x95, 0x29, 0x77, 0x3d, 0xc5, 0x6b, 0x62, 0x5b, 0xc2, 0x2f, 0xe4, ++ 0xf7, 0x42, 0xb4, 0xd2, 0x9e, 0x2a, 0x29, 0x73, 0xc2, 0x3a, 0xb7, 0xe9, ++ 0xd5, 0x0d, 0x5b, 0x03, 0x3e, 0xdb, 0x97, 0xb1, 0xc1, 0xf5, 0xb5, 0xdc, ++ 0xff, 0xd2, 0x06, 0xcc, 0x1c, 0x96, 0x78, 0xf6, 0xfb, 0xcf, 0x52, 0x18, ++ 0x37, 0xcf, 0x52, 0x88, 0x5e, 0xbd, 0x67, 0xde, 0x45, 0xfd, 0xd4, 0x53, ++ 0xb6, 0xa3, 0x26, 0x2a, 0x44, 0xc7, 0x9b, 0xdd, 0x92, 0x87, 0xda, 0xc8, ++ 0x23, 0x8c, 0x74, 0xd2, 0x2d, 0xb1, 0xd2, 0x11, 0x07, 0x16, 0xc5, 0x0d, ++ 0xe4, 0x87, 0xb5, 0x03, 0xd7, 0xec, 0x37, 0xcc, 0xf6, 0xea, 0x79, 0xcc, ++ 0x03, 0x6f, 0xad, 0xb9, 0x8f, 0xb2, 0xdb, 0xb5, 0x1f, 0x9b, 0x0f, 0x56, ++ 0x8a, 0x8c, 0x3f, 0x72, 0x67, 0xea, 0xcc, 0x0b, 0xa9, 0x97, 0x9c, 0x4e, ++ 0x4c, 0xda, 0xcf, 0xdf, 0x98, 0x5f, 0xbb, 0xed, 0xba, 0xf0, 0x19, 0xb1, ++ 0xd3, 0xd9, 0x67, 0xdb, 0xc4, 0x66, 0x3d, 0xb4, 0xd3, 0x69, 0x8c, 0x25, ++ 0x1b, 0x30, 0x90, 0x10, 0x1d, 0x47, 0x70, 0x99, 0xfc, 0xb0, 0x76, 0x70, ++ 0x1a, 0xc3, 0xe4, 0x87, 0xbe, 0xb8, 0xf7, 0x00, 0x35, 0x89, 0x6d, 0x6a, ++ 0x93, 0xc5, 0x93, 0x5c, 0x5a, 0x4e, 0x86, 0xaf, 0x5a, 0x7a, 0x97, 0x18, ++ 0xb3, 0x87, 0xeb, 0xbd, 0x97, 0x3c, 0xa9, 0x39, 0x96, 0x0f, 0xad, 0xac, ++ 0x14, 0xc5, 0x9a, 0xf4, 0x2b, 0x32, 0xf7, 0x45, 0x29, 0x4b, 0x91, 0xe6, ++ 0xc3, 0x5a, 0xeb, 0x5e, 0x8f, 0x75, 0xae, 0xc1, 0x51, 0x2e, 0x31, 0x58, ++ 0xe2, 0x2e, 0xf9, 0xf7, 0x72, 0x89, 0xbb, 0x61, 0xca, 0xb6, 0x98, 0x7b, ++ 0xb6, 0x14, 0xee, 0x07, 0x3c, 0xa8, 0x79, 0x80, 0x31, 0x72, 0x89, 0x82, ++ 0xf2, 0x25, 0x7e, 0x63, 0xa9, 0xad, 0x19, 0xa8, 0xd6, 0x88, 0x3f, 0x6e, ++ 0xb3, 0x27, 0xf1, 0x3b, 0xce, 0xd1, 0x01, 0x73, 0x6f, 0x21, 0x36, 0xec, ++ 0x9d, 0x43, 0x5b, 0xf5, 0x48, 0x7d, 0xdd, 0xe5, 0x0a, 0x47, 0x43, 0xae, ++ 0x58, 0xbd, 0xee, 0x54, 0x16, 0x33, 0x1e, 0xcb, 0xfe, 0xc9, 0xf3, 0xbf, ++ 0x72, 0x1b, 0x5f, 0xaa, 0x60, 0x7c, 0x7b, 0xd2, 0x92, 0x41, 0x6a, 0xc0, ++ 0x32, 0xee, 0xdf, 0xee, 0xd3, 0xd4, 0xcd, 0x7d, 0xba, 0x0f, 0x8e, 0x27, ++ 0x2a, 0xc9, 0xbf, 0xee, 0x1e, 0x43, 0x0a, 0x18, 0x43, 0xee, 0x8d, 0x99, ++ 0x5d, 0x5b, 0x43, 0x45, 0x52, 0x17, 0xb2, 0x62, 0x48, 0xbb, 0x8d, 0x38, ++ 0x5a, 0x2a, 0x76, 0xe1, 0xab, 0x21, 0xc6, 0xe9, 0x99, 0xdf, 0xc4, 0x3e, ++ 0xac, 0x3a, 0x5e, 0xf6, 0xb7, 0x0e, 0xec, 0x22, 0x66, 0xca, 0xd9, 0x6e, ++ 0xa7, 0xa6, 0xd1, 0xff, 0x3b, 0xd0, 0xc3, 0x39, 0x5f, 0x26, 0x6e, 0x0e, ++ 0x10, 0x37, 0x6f, 0x2c, 0x3b, 0xf1, 0x93, 0x1a, 0xd4, 0xd1, 0x08, 0xa6, ++ 0xfe, 0x5b, 0xb9, 0xe0, 0xe6, 0x52, 0x7f, 0xc7, 0x27, 0x16, 0x6e, 0xca, ++ 0xdc, 0x32, 0xdf, 0xec, 0xb9, 0x17, 0xf2, 0xdf, 0x85, 0x52, 0x4b, 0x34, ++ 0x9d, 0xda, 0xff, 0x36, 0x77, 0x56, 0x8a, 0xac, 0x77, 0x93, 0x43, 0xb0, ++ 0x76, 0x76, 0x4f, 0x7e, 0x9a, 0x98, 0x6b, 0xe5, 0x08, 0x8c, 0xb9, 0x11, ++ 0xac, 0x59, 0xae, 0xe2, 0x6a, 0x74, 0x1a, 0x05, 0x87, 0x72, 0xf8, 0x64, ++ 0x36, 0x9d, 0x22, 0x36, 0x0d, 0x43, 0xf0, 0xa8, 0x91, 0xfb, 0x62, 0xd0, ++ 0x4f, 0x4a, 0x30, 0x91, 0xd4, 0x88, 0x99, 0x26, 0xfa, 0x43, 0x2e, 0x72, ++ 0xdb, 0xee, 0x93, 0x79, 0x56, 0x9c, 0x28, 0x21, 0x86, 0xe7, 0x78, 0xb7, ++ 0x70, 0x6e, 0xc1, 0x1f, 0xe6, 0x18, 0x23, 0x76, 0xe4, 0x2d, 0x93, 0xbc, ++ 0xe2, 0x73, 0xf3, 0x42, 0x9b, 0xdc, 0xb7, 0x00, 0xc3, 0x7b, 0xc5, 0xfe, ++ 0x7c, 0xa8, 0xd1, 0x2e, 0x32, 0xcf, 0x00, 0xde, 0x8f, 0xda, 0xee, 0x71, ++ 0x91, 0x1b, 0x77, 0xe9, 0xcb, 0x71, 0xa3, 0xa2, 0x87, 0x3e, 0xef, 0xe6, ++ 0x6f, 0x53, 0x38, 0x12, 0x75, 0x21, 0xcf, 0xd2, 0x69, 0x29, 0xd7, 0x90, ++ 0xb1, 0xa1, 0x9d, 0xb4, 0xa1, 0x7c, 0xe6, 0x6f, 0x0f, 0x5b, 0xbe, 0x2a, ++ 0xf3, 0x4c, 0xe3, 0x15, 0x72, 0x5a, 0x6d, 0xb9, 0xf0, 0xd9, 0x20, 0xe3, ++ 0x62, 0x09, 0xe2, 0x03, 0x5d, 0x38, 0x1f, 0x2a, 0x41, 0xec, 0x90, 0xf8, ++ 0xd8, 0x02, 0xc1, 0x52, 0x3e, 0xb7, 0x91, 0x3a, 0x51, 0x89, 0x35, 0xf5, ++ 0x9d, 0x76, 0x7b, 0x09, 0x2e, 0x95, 0x31, 0xaf, 0xb5, 0xde, 0xe3, 0x69, ++ 0xc5, 0xc1, 0xac, 0x5d, 0xa8, 0xb4, 0x8b, 0xd6, 0x9b, 0x3c, 0x3a, 0xb7, ++ 0x96, 0x9c, 0xcf, 0x66, 0xfa, 0xe1, 0xbd, 0xe4, 0x36, 0x2f, 0x4b, 0xfd, ++ 0xc8, 0xe6, 0x63, 0x2c, 0x61, 0xce, 0x34, 0x29, 0xfa, 0xfd, 0xeb, 0xb9, ++ 0x19, 0xac, 0x78, 0xa5, 0x26, 0x73, 0x76, 0x25, 0xa7, 0xf7, 0xdc, 0x77, ++ 0x6d, 0x7d, 0xa1, 0xf2, 0x0b, 0x73, 0x6b, 0x95, 0xc8, 0x77, 0x9d, 0x79, ++ 0xda, 0x77, 0xf9, 0xfb, 0x2a, 0xf4, 0x8e, 0xcc, 0x8e, 0x15, 0xe2, 0x87, ++ 0x9e, 0xdb, 0xce, 0xd5, 0x95, 0xc5, 0xe5, 0xdd, 0xa9, 0x63, 0xa1, 0x67, ++ 0xb8, 0x0f, 0xfe, 0xa5, 0xf5, 0x56, 0xdd, 0x85, 0xdc, 0x97, 0x79, 0x89, ++ 0x60, 0xac, 0xc1, 0x18, 0x5f, 0x82, 0x9f, 0x26, 0x25, 0xe6, 0x9a, 0xc8, ++ 0xa7, 0xfd, 0x5d, 0xaa, 0xec, 0x7e, 0xbe, 0xcc, 0xe2, 0xd2, 0x25, 0x28, ++ 0xa7, 0xbd, 0x0f, 0x8e, 0xdc, 0xcd, 0xb6, 0x6f, 0xc5, 0x85, 0x74, 0x48, ++ 0x21, 0x4e, 0xfc, 0x8b, 0xd9, 0xff, 0xf5, 0xcc, 0x98, 0x0b, 0x49, 0x17, ++ 0x3e, 0x0a, 0xb5, 0x63, 0xaa, 0x2c, 0x8c, 0xa1, 0x44, 0x01, 0xda, 0xab, ++ 0xeb, 0xac, 0x77, 0x0a, 0x6a, 0xe2, 0x1e, 0x5c, 0x8c, 0x3a, 0xd1, 0x38, ++ 0xd7, 0x63, 0xd5, 0xd3, 0x6c, 0xf4, 0x85, 0x77, 0xa2, 0x11, 0xcb, 0xe7, ++ 0x66, 0xc7, 0x8c, 0x3c, 0x6d, 0x19, 0x1e, 0xca, 0xe2, 0xfa, 0xc1, 0xc4, ++ 0xe7, 0xc4, 0x9d, 0x52, 0xa3, 0x22, 0x5c, 0x82, 0x7b, 0x87, 0x0c, 0xc1, ++ 0x64, 0xa3, 0x24, 0xac, 0xcd, 0xdc, 0xa7, 0x94, 0xa0, 0x69, 0x44, 0x30, ++ 0x5e, 0x7c, 0x35, 0x4d, 0x5f, 0x6d, 0xe3, 0x1e, 0x75, 0xa2, 0x6e, 0xbf, ++ 0xa5, 0x57, 0xd5, 0xae, 0x98, 0x5d, 0x57, 0xf4, 0x88, 0xce, 0x18, 0xd7, ++ 0xf9, 0x10, 0xed, 0x7e, 0x26, 0xe4, 0x6d, 0xaf, 0xb0, 0x6b, 0x1d, 0xef, ++ 0x29, 0x41, 0x4c, 0x8c, 0x03, 0x03, 0x87, 0x03, 0xf8, 0x20, 0x21, 0x9c, ++ 0x3f, 0x80, 0x5f, 0x4d, 0x06, 0xf1, 0x2e, 0x63, 0x53, 0x41, 0xdc, 0x1b, ++ 0x79, 0x8e, 0x39, 0xdd, 0xfb, 0xfc, 0x9e, 0x1f, 0xd7, 0x71, 0x8d, 0xfa, ++ 0x73, 0xc6, 0x1b, 0x70, 0x65, 0xf2, 0x01, 0x5c, 0xdd, 0xaf, 0xe0, 0x84, ++ 0xf6, 0x00, 0x2e, 0x8f, 0x75, 0x62, 0xd9, 0x7e, 0x39, 0x87, 0x76, 0x2c, ++ 0xa4, 0x32, 0x36, 0x3c, 0x53, 0x6b, 0x76, 0xbd, 0xa8, 0xd7, 0x41, 0x2f, ++ 0xf7, 0xea, 0xed, 0xcc, 0x99, 0x04, 0xd3, 0x23, 0x36, 0xd9, 0x33, 0xd9, ++ 0xbb, 0x4e, 0x5c, 0xb5, 0x70, 0xfc, 0xee, 0xd8, 0x70, 0x0b, 0xc3, 0xe5, ++ 0x39, 0x82, 0x27, 0x0b, 0xf1, 0x7d, 0x26, 0xab, 0x3d, 0xbc, 0xcf, 0x45, ++ 0xec, 0x7b, 0x36, 0x5a, 0x80, 0xfc, 0xaa, 0x52, 0x2b, 0x97, 0x29, 0x8c, ++ 0x07, 0x70, 0x96, 0xba, 0x5b, 0x53, 0xe5, 0xe5, 0x77, 0x89, 0xbb, 0x41, ++ 0xe6, 0x2d, 0x15, 0xf8, 0xe0, 0xb6, 0x78, 0xfb, 0x7d, 0xf3, 0x49, 0x0b, ++ 0x9f, 0xeb, 0xe7, 0x09, 0xff, 0x7a, 0x3d, 0xf1, 0xeb, 0x1a, 0xc1, 0x69, ++ 0xa9, 0x21, 0x96, 0x6a, 0xda, 0x96, 0xbf, 0x80, 0xbc, 0x6f, 0x75, 0xe2, ++ 0x3f, 0x17, 0x93, 0x17, 0xbf, 0x18, 0xaa, 0x33, 0xca, 0xa0, 0xf1, 0xbe, ++ 0xa9, 0x65, 0x2a, 0x56, 0xf1, 0xaf, 0x9f, 0xf7, 0x05, 0x29, 0xc7, 0x75, ++ 0x33, 0xa5, 0xfa, 0xf8, 0xef, 0x05, 0x8c, 0xef, 0xdb, 0x71, 0x3e, 0x56, ++ 0xdf, 0x7e, 0x58, 0xb9, 0x66, 0x1a, 0x55, 0xb5, 0xfc, 0xad, 0x12, 0x17, ++ 0xa2, 0xde, 0xa9, 0x31, 0xd4, 0x7b, 0x66, 0x94, 0x83, 0xa6, 0xa1, 0xca, ++ 0xfe, 0xc8, 0x7a, 0x65, 0xfc, 0x62, 0x5e, 0xbf, 0x34, 0xcb, 0x0e, 0x6f, ++ 0xe5, 0x5d, 0xce, 0x9b, 0xf6, 0x27, 0xbc, 0xc4, 0x6c, 0x1a, 0xd5, 0xeb, ++ 0xd5, 0x1e, 0x62, 0x41, 0x44, 0xbd, 0x9b, 0xfd, 0x15, 0xd0, 0xfe, 0xc2, ++ 0xcc, 0x23, 0x4b, 0xa0, 0x5a, 0xf1, 0xa9, 0x15, 0xc9, 0x91, 0xd9, 0xdc, ++ 0x52, 0xec, 0x2e, 0xc3, 0x53, 0xdb, 0xcb, 0xba, 0x4f, 0x3a, 0x89, 0x45, ++ 0x09, 0xe2, 0x78, 0x9c, 0x38, 0x9e, 0x4f, 0x1c, 0xbf, 0xbe, 0xaf, 0x10, ++ 0xe7, 0xf7, 0x35, 0x22, 0x5d, 0x26, 0x63, 0xec, 0x70, 0x72, 0x75, 0xa9, ++ 0xec, 0x79, 0x85, 0x9a, 0xc1, 0x95, 0x72, 0x8e, 0x13, 0x82, 0x5f, 0x79, ++ 0x71, 0xe6, 0x59, 0xad, 0x76, 0x38, 0xac, 0x33, 0xf6, 0x73, 0x6e, 0xb3, ++ 0x3f, 0x97, 0x96, 0x8f, 0x96, 0x4a, 0xc1, 0x87, 0xd7, 0xe7, 0x49, 0x1c, ++ 0x7d, 0x9d, 0xb2, 0x9c, 0xa4, 0x4d, 0x6f, 0xd4, 0x57, 0x48, 0x5f, 0x8f, ++ 0xf7, 0xcb, 0x38, 0xc9, 0x6d, 0x4c, 0xec, 0xa6, 0x85, 0xd5, 0x55, 0x99, ++ 0x48, 0xe8, 0x61, 0xc6, 0xac, 0x10, 0x22, 0x65, 0x41, 0xc6, 0x2a, 0xf9, ++ 0xae, 0xe2, 0x0a, 0xf3, 0xb2, 0xf1, 0xa0, 0x82, 0x8f, 0xbe, 0x22, 0x5c, ++ 0xc0, 0xaf, 0x9f, 0x57, 0x84, 0x0b, 0xc8, 0x78, 0xc1, 0x88, 0x52, 0x0b, ++ 0x23, 0xf2, 0x2d, 0x5e, 0x34, 0xd7, 0xc2, 0x16, 0x79, 0x47, 0xa9, 0x86, ++ 0x71, 0xe7, 0xfe, 0x44, 0xfd, 0x94, 0xcf, 0x4e, 0x8e, 0xf6, 0x27, 0x5f, ++ 0x21, 0x37, 0xb3, 0x38, 0x02, 0xf1, 0x3e, 0x87, 0x0d, 0x72, 0xee, 0x76, ++ 0xb6, 0x3e, 0x72, 0xe7, 0x72, 0x3d, 0x19, 0xac, 0x2c, 0x15, 0x2e, 0xf7, ++ 0xff, 0xcc, 0xd6, 0xdb, 0xe4, 0xcf, 0xe1, 0xc8, 0x3f, 0xf0, 0xbb, 0x8c, ++ 0x17, 0xbf, 0xa3, 0x5d, 0xc4, 0x7f, 0x62, 0x3e, 0x6d, 0xf1, 0xb9, 0x97, ++ 0xe7, 0xc9, 0xf9, 0x43, 0xc7, 0xe0, 0xd0, 0x3c, 0x39, 0x6f, 0x65, 0x9b, ++ 0xc5, 0x0b, 0x32, 0xb1, 0xf6, 0x5d, 0x73, 0xad, 0x25, 0xeb, 0x91, 0xec, ++ 0x7d, 0x92, 0x43, 0x8b, 0x2c, 0x0a, 0x5e, 0xd1, 0xea, 0xd5, 0xb3, 0x28, ++ 0x16, 0x3c, 0x89, 0x48, 0x0f, 0xb3, 0x50, 0xf3, 0xb9, 0x8f, 0xf0, 0x6f, ++ 0x3f, 0xaf, 0xbf, 0xa1, 0x39, 0x1a, 0xb7, 0x42, 0xfa, 0xb6, 0x36, 0xee, ++ 0x55, 0xbd, 0xfb, 0x2c, 0xfc, 0x91, 0x7c, 0x65, 0xc6, 0x6c, 0xaf, 0x94, ++ 0x7b, 0x32, 0xfd, 0x5b, 0x28, 0x17, 0xad, 0xfa, 0x49, 0xc6, 0x66, 0x16, ++ 0xd0, 0x66, 0x04, 0xbb, 0x84, 0x8b, 0x2c, 0xe1, 0xda, 0x55, 0x8c, 0x4c, ++ 0x02, 0x79, 0x83, 0x2e, 0x8b, 0x1b, 0xa9, 0xb5, 0xb5, 0x9e, 0xcd, 0xf8, ++ 0xe7, 0x79, 0xf2, 0xee, 0xd1, 0x0e, 0x1d, 0xf7, 0xd8, 0xf0, 0xf6, 0x3d, ++ 0xb6, 0xf0, 0xca, 0x6f, 0x3d, 0xd4, 0x90, 0x37, 0x5f, 0xde, 0xff, 0x20, ++ 0xc3, 0x93, 0xfa, 0xad, 0x5b, 0x7a, 0x8d, 0xab, 0x19, 0xc3, 0x86, 0x99, ++ 0xe3, 0xaf, 0x0e, 0xfe, 0xd6, 0xfc, 0xa6, 0x23, 0xe2, 0xb1, 0xa3, 0xd6, ++ 0xd3, 0x8b, 0x1b, 0x66, 0xaa, 0x52, 0xae, 0xcb, 0x1c, 0xf2, 0x6e, 0xa1, ++ 0xf4, 0x4b, 0x4c, 0xf3, 0xde, 0x5a, 0x93, 0xf9, 0xb3, 0x6d, 0x95, 0x9d, ++ 0x7e, 0x91, 0xaf, 0x5d, 0x36, 0xeb, 0xaa, 0x6b, 0xdd, 0x36, 0xa5, 0x8e, ++ 0xd6, 0x51, 0x89, 0x57, 0x69, 0xbf, 0xaf, 0x4e, 0x4a, 0xcc, 0x53, 0x71, ++ 0x94, 0x7e, 0x3a, 0x56, 0xe7, 0xeb, 0xbc, 0xca, 0x5c, 0xf2, 0x43, 0x72, ++ 0xfc, 0x37, 0x35, 0x6f, 0xfb, 0x19, 0xa9, 0x3b, 0x86, 0x1c, 0x38, 0x17, ++ 0xbc, 0x61, 0xd5, 0x82, 0x63, 0x87, 0x54, 0x0c, 0x27, 0x32, 0xfe, 0xfe, ++ 0x1a, 0xfd, 0xf8, 0xd6, 0xd9, 0x05, 0x1d, 0x3d, 0x43, 0xe2, 0x1f, 0x0d, ++ 0x96, 0x1f, 0xdd, 0xaa, 0x15, 0x09, 0x5e, 0x8b, 0x5f, 0x6c, 0x90, 0xde, ++ 0x9d, 0x91, 0x02, 0xb9, 0xcc, 0xe0, 0x6a, 0x72, 0x60, 0x89, 0xb1, 0x01, ++ 0xe6, 0xbb, 0x0e, 0xfa, 0xcf, 0x19, 0xe6, 0x1e, 0x94, 0x2d, 0x6c, 0x9a, ++ 0xef, 0x32, 0x17, 0x1b, 0x41, 0xbd, 0x7a, 0x0a, 0xeb, 0xc8, 0x63, 0xc9, ++ 0x71, 0x26, 0x9b, 0xb1, 0xc7, 0xca, 0xa5, 0x7c, 0xea, 0xc3, 0xca, 0x52, ++ 0xae, 0xbf, 0x19, 0xdd, 0x63, 0x0b, 0x70, 0x80, 0xeb, 0x7a, 0x44, 0xff, ++ 0x2b, 0x94, 0x0f, 0x75, 0x77, 0x96, 0x53, 0x1f, 0x9f, 0x86, 0x8c, 0x0e, ++ 0x62, 0xfa, 0x96, 0x53, 0x4a, 0xfd, 0xfa, 0x98, 0xf2, 0x4d, 0xee, 0x87, ++ 0xd4, 0x47, 0x3c, 0xcc, 0xd3, 0x1f, 0x61, 0x3c, 0xfb, 0x33, 0xec, 0x56, ++ 0x95, 0x26, 0x5b, 0x58, 0x38, 0x22, 0xfc, 0xaa, 0x75, 0x76, 0xf0, 0xbf, ++ 0x40, 0x9f, 0xdb, 0xc0, 0x6b, 0x12, 0xd7, 0xe5, 0x5e, 0x39, 0x37, 0xde, ++ 0x89, 0x93, 0x69, 0xda, 0x75, 0xb4, 0x0f, 0xa7, 0xd2, 0xf2, 0x4c, 0xe1, ++ 0x58, 0x01, 0xc4, 0x86, 0xec, 0x98, 0xd0, 0x7d, 0x91, 0x52, 0xea, 0xa5, ++ 0x30, 0xe4, 0x8d, 0xac, 0x53, 0x02, 0xe4, 0x72, 0x69, 0x9c, 0xdb, 0xeb, ++ 0x6d, 0xaf, 0x63, 0xde, 0x18, 0x9d, 0x84, 0xfa, 0xdc, 0xf2, 0x34, 0xce, ++ 0x8e, 0x3e, 0x0e, 0x4f, 0xb5, 0xd7, 0xb3, 0x5a, 0x69, 0xc1, 0x8e, 0xc9, ++ 0x7f, 0xaf, 0xc6, 0xe4, 0xe1, 0xb3, 0x5b, 0x60, 0x50, 0xf7, 0xbb, 0xf0, ++ 0xad, 0xf9, 0xe2, 0xf3, 0xbd, 0x93, 0xc5, 0x58, 0xc4, 0x78, 0xf4, 0xb2, ++ 0x15, 0x67, 0x33, 0x7e, 0x54, 0xa3, 0x7d, 0x64, 0x3e, 0x95, 0x8d, 0xe1, ++ 0x7f, 0x58, 0x5f, 0x3f, 0x34, 0x23, 0xaa, 0xe8, 0x4b, 0xc6, 0xd5, 0xa0, ++ 0x80, 0xf3, 0xec, 0xce, 0xc6, 0xeb, 0x32, 0xed, 0x9f, 0xcc, 0xc7, 0xad, ++ 0x39, 0x56, 0xce, 0x97, 0x44, 0x61, 0xa7, 0x95, 0xe7, 0xcb, 0xba, 0x75, ++ 0x7c, 0x16, 0x95, 0x5a, 0x87, 0x8a, 0x53, 0xba, 0xe0, 0x48, 0x0b, 0x7d, ++ 0xd5, 0x89, 0x2d, 0x41, 0xba, 0xa3, 0x55, 0xf7, 0x9f, 0xc6, 0x9e, 0xe4, ++ 0xbf, 0x9a, 0xcf, 0xd3, 0x8e, 0xd6, 0x90, 0xc3, 0x78, 0x88, 0x03, 0x1b, ++ 0x43, 0x8f, 0x90, 0x87, 0x72, 0xcd, 0x09, 0x07, 0x31, 0x48, 0x41, 0xa2, ++ 0x91, 0xfe, 0x1f, 0x5a, 0x82, 0x29, 0xeb, 0xfe, 0x4f, 0xe7, 0x65, 0x6a, ++ 0x8b, 0x67, 0xe6, 0x67, 0x72, 0x43, 0xd1, 0xff, 0x7f, 0x44, 0x7f, 0xaf, ++ 0x99, 0x9e, 0x72, 0xd1, 0x9f, 0x03, 0x6e, 0xc6, 0xad, 0x03, 0xbc, 0xe7, ++ 0xc2, 0x5e, 0x07, 0x06, 0xb5, 0x16, 0x0c, 0x4e, 0xc2, 0xf3, 0x29, 0xef, ++ 0xf9, 0xf9, 0x68, 0xc7, 0xfc, 0x0c, 0x57, 0x78, 0x1b, 0xdd, 0xd1, 0x17, ++ 0xcc, 0x55, 0xe5, 0xb2, 0x5e, 0x39, 0xaf, 0xd3, 0xca, 0xfb, 0x73, 0x75, ++ 0xbe, 0xcd, 0xe6, 0x13, 0x56, 0x9c, 0x78, 0x71, 0xbe, 0xf4, 0xd7, 0x5e, ++ 0x4f, 0x98, 0xb8, 0xa2, 0xf7, 0x58, 0xb9, 0xb9, 0x60, 0x43, 0x6f, 0x42, ++ 0xf6, 0x56, 0x64, 0xfb, 0x66, 0x56, 0x1f, 0x13, 0x55, 0xb7, 0xcb, 0xbd, ++ 0x2a, 0x6b, 0xcb, 0xd2, 0xdf, 0xce, 0xf1, 0x7e, 0xb1, 0x65, 0xb1, 0x63, ++ 0xeb, 0xbd, 0x96, 0xa4, 0xbc, 0xd3, 0xb9, 0x41, 0xfd, 0x1d, 0x9f, 0x21, ++ 0x75, 0x96, 0x16, 0xce, 0x61, 0x9a, 0x9b, 0xf5, 0x7a, 0xcf, 0x29, 0xfc, ++ 0x31, 0x6d, 0x5b, 0xc7, 0xae, 0x21, 0xa9, 0xc3, 0x7a, 0x14, 0xc7, 0xbe, ++ 0x75, 0xb8, 0xc2, 0xf8, 0xbf, 0xc7, 0xb2, 0x43, 0xc1, 0x15, 0x91, 0x43, ++ 0xb0, 0xa5, 0x8d, 0x71, 0x5c, 0x6a, 0xdd, 0x46, 0xa4, 0x26, 0xdc, 0xa9, ++ 0x7c, 0x58, 0xd7, 0x89, 0x63, 0x21, 0xc3, 0x2c, 0xd5, 0xfc, 0xeb, 0x6b, ++ 0x6c, 0x28, 0x98, 0x6c, 0xc8, 0xc7, 0xf1, 0x90, 0xf0, 0x47, 0xb8, 0xd2, ++ 0x69, 0xaf, 0x31, 0xc7, 0xae, 0xba, 0xbe, 0x97, 0xce, 0x62, 0xa5, 0xad, ++ 0x7e, 0xbe, 0xe4, 0x50, 0x49, 0x0b, 0x47, 0xbe, 0x8a, 0x07, 0xad, 0xbd, ++ 0x55, 0x19, 0x43, 0xa5, 0x0e, 0x7c, 0x2c, 0x74, 0x2d, 0x2a, 0x98, 0x62, ++ 0x36, 0x35, 0x87, 0xea, 0xd5, 0x5d, 0xb8, 0x87, 0xd8, 0xd5, 0x84, 0x73, ++ 0xba, 0xf4, 0x3f, 0x8c, 0x6f, 0x3a, 0xac, 0xb3, 0x34, 0x47, 0x43, 0x3b, ++ 0xa2, 0x2b, 0x71, 0x60, 0xc8, 0x50, 0x9c, 0x61, 0x6f, 0x24, 0x46, 0x2e, ++ 0xc4, 0x1c, 0xdd, 0xaa, 0x03, 0x4a, 0x8d, 0x61, 0xb8, 0xa1, 0x13, 0xbb, ++ 0xf4, 0x7c, 0xf4, 0xea, 0x91, 0x82, 0x9e, 0xe5, 0x5d, 0x38, 0xa8, 0x17, ++ 0x1b, 0x8b, 0xc2, 0x06, 0x31, 0x5d, 0xdb, 0x92, 0x84, 0xbf, 0xe5, 0x32, ++ 0x39, 0xc7, 0x49, 0x78, 0x3b, 0x9a, 0xec, 0xc4, 0xdc, 0x15, 0x0e, 0x57, ++ 0x6c, 0xbc, 0x11, 0x89, 0xc9, 0x4a, 0xd7, 0xee, 0xf1, 0x20, 0xe2, 0x93, ++ 0xdc, 0x6f, 0xe6, 0xba, 0x8e, 0xf1, 0x95, 0xe4, 0xa0, 0xa2, 0x47, 0x3b, ++ 0x6d, 0xb1, 0x0e, 0xcf, 0xb5, 0x5e, 0x32, 0x9f, 0xf1, 0x0b, 0x7e, 0x2e, ++ 0xc0, 0x56, 0xd5, 0x67, 0x71, 0xca, 0x88, 0xed, 0x0f, 0xf9, 0x87, 0x9d, ++ 0x36, 0xf7, 0x7d, 0xd3, 0xf3, 0x75, 0xd1, 0x9b, 0x63, 0x01, 0x0a, 0x1f, ++ 0x21, 0x7e, 0xca, 0xbf, 0x45, 0x77, 0xa2, 0x43, 0x13, 0x9b, 0x74, 0xa9, ++ 0xf1, 0x35, 0xd0, 0x67, 0xdc, 0x78, 0x47, 0xbd, 0xb5, 0x0f, 0xcf, 0xea, ++ 0x3e, 0x7d, 0x0c, 0x52, 0xdb, 0x5b, 0xc1, 0x71, 0x52, 0x83, 0x69, 0xc4, ++ 0x4b, 0xd9, 0x9c, 0xc3, 0x63, 0x2b, 0x22, 0xee, 0xe6, 0xe2, 0x88, 0x5c, ++ 0xf7, 0x26, 0x23, 0xb4, 0xd3, 0x6d, 0xc1, 0x19, 0x33, 0x52, 0x6e, 0x74, ++ 0xca, 0xf9, 0x15, 0x77, 0x78, 0xba, 0xd3, 0x5d, 0xe7, 0xed, 0x98, 0x51, ++ 0x80, 0x73, 0x31, 0xc6, 0x61, 0xeb, 0x7f, 0xb1, 0x28, 0x73, 0x3b, 0x31, ++ 0x12, 0x5c, 0x88, 0xf6, 0x36, 0x79, 0x56, 0x33, 0xfa, 0xf6, 0x9b, 0x66, ++ 0x71, 0xc8, 0xa7, 0xa6, 0xe1, 0xc4, 0xc3, 0x41, 0x3b, 0x2e, 0xa9, 0x26, ++ 0x1c, 0xa1, 0x7f, 0x35, 0xc7, 0x19, 0x1f, 0x47, 0xe9, 0x27, 0xbb, 0x69, ++ 0x63, 0xf2, 0xbe, 0x8f, 0x9f, 0x7e, 0x12, 0xa7, 0x9f, 0x9c, 0x0b, 0xdd, ++ 0x97, 0x7d, 0x5f, 0x50, 0x23, 0xaf, 0x98, 0x46, 0xd3, 0x90, 0x8a, 0x4f, ++ 0x57, 0x4c, 0x23, 0x34, 0x92, 0x93, 0x5d, 0xfc, 0x32, 0x27, 0xbf, 0xf4, ++ 0x11, 0x45, 0x76, 0x91, 0x51, 0xd6, 0x22, 0xff, 0xce, 0x5d, 0xcb, 0xfd, ++ 0x26, 0x71, 0xd6, 0x89, 0x56, 0x6b, 0x6d, 0x7f, 0x56, 0x93, 0xc1, 0x8c, ++ 0xdc, 0x9a, 0x2e, 0xb9, 0x6f, 0xff, 0x7e, 0xe2, 0x8e, 0xeb, 0x2b, 0xee, ++ 0xb8, 0xbe, 0x71, 0xde, 0xed, 0xdf, 0x73, 0x3e, 0x71, 0x4b, 0xaf, 0x1d, ++ 0xba, 0x6f, 0xea, 0x18, 0xd7, 0x3a, 0x67, 0xc9, 0x98, 0x79, 0xa9, 0x4c, ++ 0x64, 0x91, 0x3c, 0x36, 0x23, 0xeb, 0xaa, 0xf1, 0xd9, 0xb2, 0xbe, 0x95, ++ 0xed, 0x19, 0x58, 0x67, 0x7c, 0xe9, 0x37, 0x1a, 0x7e, 0x78, 0xdb, 0xb9, ++ 0x43, 0xb1, 0xb5, 0x80, 0xd2, 0x17, 0x93, 0xf7, 0x33, 0x0b, 0xad, 0x77, ++ 0xac, 0x55, 0xbf, 0x81, 0x22, 0xbf, 0xb6, 0x65, 0x8e, 0xad, 0x0b, 0xce, ++ 0xa5, 0x5a, 0xc7, 0xb7, 0x94, 0x24, 0xe2, 0xe3, 0xde, 0xc0, 0x18, 0x75, ++ 0x15, 0x1b, 0xbf, 0xce, 0x5c, 0xbb, 0x0b, 0xcf, 0x85, 0x1c, 0x46, 0x61, ++ 0x58, 0xce, 0x82, 0xae, 0xc2, 0xae, 0x91, 0xbf, 0xc2, 0xe6, 0xa4, 0x70, ++ 0xfc, 0x05, 0xe8, 0x99, 0xb4, 0xe1, 0x04, 0xed, 0xbb, 0x8f, 0xcf, 0x21, ++ 0xfe, 0xb9, 0x53, 0x90, 0xf7, 0x6b, 0x1a, 0x98, 0x37, 0xeb, 0xd6, 0x67, ++ 0xc7, 0xc8, 0xcf, 0xb0, 0x39, 0x6a, 0xe2, 0x53, 0x9d, 0xb1, 0x47, 0x13, ++ 0xf9, 0x1c, 0xd0, 0xca, 0x5b, 0x2d, 0x2c, 0x7d, 0x32, 0xce, 0xfd, 0xac, ++ 0x16, 0x5f, 0x5d, 0x49, 0x9f, 0x55, 0xf0, 0x99, 0xf4, 0x27, 0xcb, 0x29, ++ 0x33, 0xb9, 0xe1, 0xf1, 0xe8, 0x76, 0x8c, 0x5a, 0xfd, 0x67, 0xad, 0xaf, ++ 0xc6, 0x1e, 0x79, 0xb1, 0x8c, 0x3c, 0x3b, 0xa1, 0xfb, 0xdb, 0x2f, 0x28, ++ 0xf0, 0x94, 0x84, 0xfd, 0x8c, 0x33, 0x5f, 0xe2, 0x37, 0xba, 0xd4, 0xd8, ++ 0x74, 0xd7, 0x5a, 0xda, 0xfb, 0xbe, 0x91, 0x80, 0x55, 0x33, 0xf8, 0xe1, ++ 0x5d, 0x6b, 0x1a, 0x99, 0x77, 0xab, 0x33, 0xf5, 0xc7, 0x9f, 0xe1, 0x48, ++ 0xda, 0x85, 0xa7, 0xe2, 0x1e, 0x65, 0xd1, 0x3e, 0x15, 0x0f, 0xc5, 0xbd, ++ 0x53, 0x4d, 0x76, 0xf2, 0x8f, 0x65, 0x73, 0x38, 0x9f, 0x82, 0x1f, 0x2c, ++ 0x95, 0x58, 0xf0, 0x47, 0x30, 0xaa, 0x23, 0x9c, 0x13, 0xc5, 0x79, 0xcb, ++ 0xbd, 0xea, 0x11, 0x9b, 0xcf, 0xfd, 0x1b, 0xec, 0x80, 0x7d, 0xfc, 0x11, ++ 0x74, 0x53, 0xfe, 0x35, 0x71, 0xe9, 0x69, 0xd5, 0x03, 0x65, 0xcd, 0xd8, ++ 0x3d, 0x26, 0xbe, 0x09, 0xa3, 0x2a, 0x0c, 0x4f, 0x65, 0xd8, 0xbf, 0x10, ++ 0x85, 0x5f, 0x92, 0x6b, 0x4f, 0x4b, 0xfe, 0xb9, 0xa5, 0xd4, 0x66, 0x32, ++ 0x7f, 0xb9, 0x2f, 0xdb, 0xab, 0x58, 0x89, 0x1d, 0x43, 0x52, 0x87, 0x27, ++ 0x6e, 0xeb, 0xcc, 0x83, 0xca, 0xb4, 0xc0, 0x46, 0x9b, 0xf4, 0x87, 0xb6, ++ 0xc3, 0x17, 0xdb, 0x8e, 0x40, 0x4c, 0x7c, 0x56, 0x53, 0x3b, 0x10, 0x39, ++ 0x2b, 0xb5, 0xbf, 0x45, 0x21, 0x3f, 0xe5, 0xf2, 0xf7, 0x55, 0xda, 0x75, ++ 0xd7, 0x6b, 0x13, 0x2a, 0xa6, 0xd4, 0x4c, 0x1e, 0x39, 0x96, 0xd4, 0xd6, ++ 0xe7, 0xdb, 0xe4, 0x0c, 0xc5, 0x55, 0xeb, 0x3d, 0xeb, 0x88, 0xed, 0x9f, ++ 0x89, 0x47, 0xcd, 0x18, 0xd8, 0xff, 0x3e, 0x63, 0x90, 0x3c, 0xe3, 0x77, ++ 0xcc, 0xaf, 0x9d, 0x58, 0xdd, 0xe6, 0xc1, 0x83, 0x71, 0xa9, 0x9d, 0xae, ++ 0xaf, 0xca, 0x9c, 0x01, 0x91, 0xef, 0x0e, 0x74, 0xe8, 0x04, 0xd9, 0xea, ++ 0x2f, 0xcc, 0x4a, 0x2b, 0x2f, 0xfd, 0xbf, 0x19, 0x9b, 0x49, 0xe4, 0x2d, ++ 0x14, 0x1f, 0xef, 0x9d, 0x64, 0x02, 0x69, 0xd9, 0x5d, 0x15, 0xbf, 0xcb, ++ 0x5c, 0xda, 0x81, 0xed, 0xd8, 0x56, 0x25, 0x7c, 0xe6, 0xc9, 0x89, 0xd9, ++ 0xf7, 0xe7, 0xea, 0x32, 0x95, 0x59, 0x4e, 0x95, 0xb3, 0x37, 0xe9, 0x05, ++ 0x46, 0x94, 0x27, 0xa2, 0x2d, 0xca, 0xda, 0xa8, 0xf4, 0x03, 0x6d, 0xd1, ++ 0x22, 0x72, 0x18, 0xdf, 0x52, 0x13, 0xdf, 0x0e, 0x1d, 0x57, 0x76, 0x5a, ++ 0xe7, 0x66, 0xe5, 0xac, 0x2b, 0x50, 0x3e, 0xd1, 0xac, 0xec, 0x8a, 0x7e, ++ 0x62, 0x6e, 0xb4, 0x7a, 0xf0, 0x79, 0xd6, 0x79, 0x9c, 0xfc, 0x09, 0x17, ++ 0xca, 0x8e, 0xc8, 0xf9, 0x41, 0x0d, 0x15, 0x13, 0x8f, 0x91, 0xb7, 0x0a, ++ 0xd7, 0x31, 0x5a, 0x1c, 0xd6, 0xb9, 0xb6, 0xe6, 0x97, 0x72, 0xe7, 0xda, ++ 0x1c, 0x31, 0x79, 0x1b, 0xd9, 0xfa, 0x8f, 0xb9, 0xd2, 0x51, 0xe6, 0x4a, ++ 0x66, 0xd3, 0xb7, 0x43, 0xc6, 0xee, 0x0a, 0x78, 0x03, 0xe5, 0x36, 0xc3, ++ 0x94, 0x7a, 0xce, 0x6b, 0x24, 0x8c, 0xeb, 0x6a, 0x0d, 0x3c, 0x5c, 0x2b, ++ 0xef, 0x1f, 0xca, 0xbb, 0xc7, 0x5d, 0x38, 0x1a, 0xea, 0xc2, 0x2f, 0xf5, ++ 0x2e, 0xec, 0xd1, 0xe5, 0x4c, 0x43, 0x31, 0x65, 0xd5, 0xa6, 0xa2, 0xd0, ++ 0xf4, 0xb4, 0xa2, 0x9d, 0xb9, 0x0e, 0xef, 0x01, 0x9f, 0xe2, 0x35, 0x56, ++ 0x29, 0x1a, 0xae, 0x8e, 0x7b, 0x67, 0x4a, 0xe9, 0x03, 0x37, 0xc6, 0x03, ++ 0x98, 0x21, 0xae, 0x26, 0x27, 0xe5, 0xfc, 0xc9, 0x02, 0x0c, 0x4d, 0x7e, ++ 0x4d, 0xb8, 0x81, 0x41, 0x4c, 0xb2, 0xce, 0x48, 0x3e, 0x2f, 0xbd, 0x4e, ++ 0x67, 0x30, 0xcb, 0x61, 0x0c, 0x65, 0x53, 0x43, 0x09, 0x6e, 0x30, 0x3a, ++ 0xfd, 0x6d, 0xba, 0x93, 0xf9, 0x1c, 0xde, 0xa8, 0x81, 0xfd, 0x3b, 0x6e, ++ 0xd4, 0x25, 0xe7, 0xe0, 0x44, 0x5d, 0x39, 0xf2, 0x70, 0x6c, 0xf4, 0x45, ++ 0x72, 0xfc, 0xee, 0xf6, 0x52, 0xe6, 0xa7, 0x13, 0xa3, 0x4e, 0xa4, 0x52, ++ 0x52, 0x73, 0xb0, 0x7a, 0x96, 0xd3, 0x0e, 0xfa, 0x52, 0x7f, 0x02, 0x75, ++ 0x35, 0x61, 0x7f, 0xb2, 0xc6, 0xae, 0x72, 0x8e, 0x4a, 0xa4, 0xd2, 0x1a, ++ 0x3f, 0x01, 0x7e, 0x82, 0xfc, 0x34, 0xe2, 0xdb, 0xf4, 0xd9, 0x32, 0xe2, ++ 0xed, 0xf7, 0xd3, 0x25, 0xf8, 0x24, 0xa9, 0x05, 0x74, 0xda, 0xc1, 0x28, ++ 0x73, 0x04, 0xc3, 0xd2, 0x53, 0x09, 0xae, 0xd3, 0x4f, 0x5f, 0x0e, 0x95, ++ 0xc0, 0x4c, 0xdd, 0x2d, 0x27, 0x94, 0xdc, 0x16, 0x6a, 0x61, 0x58, 0xf8, ++ 0xe2, 0x31, 0x25, 0x95, 0x3d, 0xf3, 0xf5, 0xea, 0x38, 0xda, 0xcb, 0xc3, ++ 0xae, 0xe0, 0xea, 0xb8, 0xfd, 0x13, 0x79, 0x9f, 0x75, 0x43, 0x83, 0xbc, ++ 0xf3, 0xe4, 0x0a, 0x3e, 0x3d, 0xe1, 0x0a, 0xae, 0x8f, 0x1f, 0x53, 0x28, ++ 0xcf, 0x81, 0x1a, 0xbb, 0x2b, 0xf8, 0xe4, 0xc4, 0xb1, 0x85, 0x99, 0xbc, ++ 0x0f, 0xca, 0xd3, 0xb5, 0x06, 0x6d, 0x8c, 0x79, 0xef, 0x32, 0xe9, 0xcb, ++ 0x68, 0x9d, 0x57, 0xec, 0x85, 0x46, 0x4d, 0xd8, 0xeb, 0xa9, 0xb1, 0xcb, ++ 0xd9, 0x90, 0x69, 0xc4, 0x93, 0xf2, 0xae, 0x97, 0xd8, 0xfe, 0x3f, 0x99, ++ 0x46, 0x99, 0x9c, 0xf5, 0xe8, 0x44, 0x5c, 0x2b, 0x67, 0xee, 0x24, 0x67, ++ 0xcd, 0x8f, 0x86, 0xa2, 0xb1, 0x62, 0x79, 0x77, 0xb6, 0xe9, 0x7b, 0x21, ++ 0x6f, 0xcb, 0xa0, 0x62, 0x3c, 0x5e, 0x04, 0xd9, 0xd7, 0x2e, 0xe2, 0xb7, ++ 0xa6, 0x3a, 0x15, 0x6f, 0x63, 0x0f, 0x02, 0x38, 0x91, 0x16, 0x5d, 0x07, ++ 0xe5, 0x8c, 0xba, 0xa5, 0xeb, 0x5b, 0x67, 0xae, 0x33, 0xb6, 0xb3, 0x2d, ++ 0xea, 0xe0, 0x5f, 0xb1, 0x17, 0x1b, 0x63, 0x0a, 0xe3, 0x8a, 0x65, 0x33, ++ 0xb7, 0x64, 0x5c, 0x57, 0xdb, 0x85, 0xc9, 0x50, 0xa1, 0xbc, 0x77, 0xcd, ++ 0xb8, 0xee, 0x0d, 0x7c, 0xa2, 0x58, 0xf1, 0xdc, 0x28, 0x62, 0x9c, 0x7d, ++ 0x61, 0xfc, 0xef, 0xcc, 0xf6, 0x6a, 0xc1, 0x2b, 0x3b, 0xc7, 0x5e, 0xc7, ++ 0x6b, 0xa9, 0x5b, 0xe3, 0x5a, 0x38, 0xae, 0x90, 0xe3, 0x8a, 0xc2, 0x92, ++ 0x3b, 0x7a, 0xf5, 0xb5, 0x8a, 0xe6, 0x29, 0x50, 0xa4, 0x57, 0xa6, 0xe1, ++ 0xbd, 0xf4, 0xe4, 0x42, 0xc9, 0x79, 0x7b, 0x27, 0xcb, 0xb1, 0x6e, 0xaf, ++ 0xd9, 0xb4, 0x68, 0xa9, 0xd9, 0x94, 0x0e, 0x45, 0xcd, 0x97, 0xab, 0x64, ++ 0x4f, 0xa5, 0xff, 0x27, 0x63, 0x34, 0xd5, 0xc7, 0x5c, 0xf3, 0x6b, 0x7a, ++ 0x6f, 0xf6, 0xcc, 0x2e, 0xed, 0x9a, 0xcf, 0x38, 0x9d, 0x12, 0x3b, 0xd9, ++ 0xd1, 0xee, 0x62, 0x3e, 0x2a, 0xef, 0x87, 0x1e, 0xe5, 0xfe, 0x1f, 0x49, ++ 0xfd, 0xcd, 0x42, 0x39, 0xc3, 0x2e, 0x67, 0x08, 0x80, 0xff, 0x0f, 0x1d, ++ 0xab, 0x22, 0x97, 0x70, 0x78, 0x00, 0x00, 0x00 }; + + static const u32 bnx2_RXP_b09FwData[(0x0/4) + 1] = { 0x0 }; +-static const u32 bnx2_RXP_b09FwRodata[(0x124/4) + 1] = { ++static const u32 bnx2_RXP_b09FwRodata[(0xf0/4) + 1] = { + 0x5f865437, 0xe4ac62cc, 0x50103a45, 0x36621985, 0xbf14c0e8, 0x1bc27a1e, + 0x84f4b556, 0x094ea6fe, 0x7dda01e7, 0xc04d7481, 0x80080100, 0x80080080, +- 0x80080000, 0x08004fbc, 0x08004fbc, 0x08005098, 0x0800506c, 0x08005050, +- 0x08004f8c, 0x08004f8c, 0x08004f8c, 0x08004fc4, 0x080072ac, 0x080072f8, +- 0x080072b8, 0x080071dc, 0x080072b8, 0x080072e8, 0x080072b8, 0x080071dc, +- 0x080071dc, 0x080071dc, 0x080071dc, 0x080071dc, 0x080071dc, 0x080071dc, +- 0x080071dc, 0x080071dc, 0x080071dc, 0x080072d8, 0x080072c8, 0x080071dc, +- 0x080071dc, 0x080071dc, 0x080071dc, 0x080071dc, 0x080071dc, 0x080071dc, +- 0x080071dc, 0x080071dc, 0x080071dc, 0x080071dc, 0x080071dc, 0x080072c8, +- 0x0800787c, 0x08007748, 0x08007844, 0x08007748, 0x08007814, 0x08007630, +- 0x08007748, 0x08007748, 0x08007748, 0x08007748, 0x08007748, 0x08007748, +- 0x08007748, 0x08007748, 0x08007748, 0x08007748, 0x08007748, 0x08007748, +- 0x08007770, 0x00000000 }; ++ 0x80080000, 0x08004efc, 0x08004efc, 0x08004fd8, 0x08004fac, 0x08004f90, ++ 0x08004ecc, 0x08004ecc, 0x08004ecc, 0x08004f04, 0x08007220, 0x0800726c, ++ 0x0800722c, 0x08007150, 0x0800722c, 0x0800725c, 0x0800722c, 0x08007150, ++ 0x08007150, 0x08007150, 0x08007150, 0x08007150, 0x08007150, 0x08007150, ++ 0x08007150, 0x08007150, 0x08007150, 0x0800724c, 0x0800723c, 0x08007150, ++ 0x08007150, 0x08007150, 0x08007150, 0x08007150, 0x08007150, 0x08007150, ++ 0x08007150, 0x08007150, 0x08007150, 0x08007150, 0x08007150, 0x0800723c, ++ 0x080077f4, 0x080076bc, 0x080077bc, 0x08007718, 0x080076e8, 0x080075a4, ++ 0x00000000 }; + + static struct fw_info bnx2_rxp_fw_09 = { +- /* Firmware version: 4.6.15 */ ++ /* Firmware version: 4.4.23 */ + .ver_major = 0x4, +- .ver_minor = 0x6, +- .ver_fix = 0xf, ++ .ver_minor = 0x4, ++ .ver_fix = 0x17, + +- .start_addr = 0x080031d8, ++ .start_addr = 0x080031d0, + + .text_addr = 0x08000000, +- .text_len = 0x78f4, ++ .text_len = 0x786c, + .text_index = 0x0, + .gz_text = bnx2_RXP_b09FwText, + .gz_text_len = sizeof(bnx2_RXP_b09FwText), +@@ -3148,492 +3158,548 @@ + .data_index = 0x0, + .data = bnx2_RXP_b09FwData, + +- .sbss_addr = 0x08007a40, ++ .sbss_addr = 0x08007980, + .sbss_len = 0x58, + .sbss_index = 0x0, + +- .bss_addr = 0x08007a98, +- .bss_len = 0x20, ++ .bss_addr = 0x080079d8, ++ .bss_len = 0x1c, + .bss_index = 0x0, + +- .rodata_addr = 0x080078f4, +- .rodata_len = 0x124, ++ .rodata_addr = 0x0800786c, ++ .rodata_len = 0xf0, + .rodata_index = 0x0, + .rodata = bnx2_RXP_b09FwRodata, + }; + + static u8 bnx2_xi_rv2p_proc1[] = { +- /* Date: 01/27/2009 19:01 */ +-#define XI_RV2P_PROC1_POST_WAIT_TIMEOUT_MSK 0xffff +- 0xa5, 0x56, 0xdd, 0x6b, 0x1c, 0x55, 0x14, 0x3f, 0x33, 0xbb, 0x33, 0xb3, +- 0xd9, 0x9d, 0xd9, 0x5d, 0x9a, 0x34, 0x8e, 0xb1, 0x34, 0xdb, 0x20, 0xca, +- 0xa6, 0x13, 0xdd, 0x68, 0x1f, 0x04, 0x03, 0x2d, 0x01, 0x29, 0x98, 0xe2, +- 0x43, 0xa0, 0x52, 0x8a, 0x60, 0x5c, 0xb4, 0x08, 0xf6, 0x2f, 0x10, 0xc1, +- 0x21, 0x31, 0x11, 0xc4, 0xaf, 0x7d, 0xe8, 0x42, 0x02, 0x6a, 0x40, 0x50, +- 0x09, 0x11, 0x77, 0xdf, 0x24, 0x16, 0x7c, 0x68, 0xf1, 0x41, 0xda, 0xa7, +- 0x16, 0xd4, 0x97, 0x46, 0x11, 0xbf, 0x5e, 0x04, 0xd1, 0xc7, 0x9a, 0xf1, +- 0x9e, 0x8f, 0xbb, 0x3b, 0x73, 0xb3, 0x9b, 0x14, 0x5c, 0x48, 0x7e, 0x9c, +- 0x7b, 0xcf, 0x39, 0xf7, 0x7c, 0x9f, 0xa9, 0x02, 0x80, 0x0d, 0x71, 0x77, +- 0x52, 0x21, 0x58, 0xb9, 0x5c, 0x01, 0x01, 0x60, 0x1b, 0xf8, 0xe7, 0xf8, +- 0x44, 0xc7, 0x8f, 0x0a, 0x7d, 0x92, 0x21, 0x3e, 0x59, 0x55, 0xff, 0x2f, +- 0xc3, 0xe9, 0x1a, 0x62, 0x0e, 0x4e, 0x9f, 0x40, 0x7c, 0x12, 0xbe, 0xae, +- 0x85, 0x0a, 0xff, 0x4d, 0x20, 0x46, 0xfa, 0x68, 0xe7, 0xcb, 0x6e, 0x89, +- 0xf4, 0xef, 0x8a, 0xfc, 0xf7, 0x39, 0xc6, 0x27, 0xa2, 0x02, 0xeb, 0x11, +- 0x84, 0x99, 0x2a, 0xc1, 0xed, 0x16, 0xd2, 0xe7, 0xcf, 0x83, 0x8b, 0x7a, +- 0xde, 0x53, 0x0c, 0x48, 0x1f, 0xb3, 0xe2, 0x19, 0xb1, 0xcb, 0x66, 0xbe, +- 0x3b, 0xad, 0x0a, 0x9e, 0xc3, 0x8f, 0xf3, 0x48, 0xdf, 0x57, 0x7c, 0xa3, +- 0x85, 0x38, 0x0e, 0x97, 0x0a, 0x3e, 0xfb, 0x53, 0x17, 0x9c, 0x64, 0xf5, +- 0xbb, 0xd3, 0x28, 0xaf, 0x64, 0xa6, 0x45, 0xbf, 0x83, 0xfa, 0x7f, 0x4f, +- 0x58, 0x3f, 0xea, 0x4d, 0xeb, 0xbb, 0x5f, 0xe9, 0xc3, 0x73, 0x57, 0xec, +- 0x73, 0x0d, 0xfb, 0x5c, 0x65, 0x0f, 0xca, 0xaf, 0x00, 0xfb, 0x39, 0xaa, +- 0xde, 0x45, 0xfa, 0xaf, 0xbe, 0xbe, 0x2e, 0xa2, 0x6f, 0xb1, 0xbc, 0xfa, +- 0x13, 0xfb, 0x59, 0xee, 0x35, 0x25, 0xa7, 0xe3, 0x92, 0xb5, 0xd3, 0x8b, +- 0xb4, 0x7f, 0x3a, 0xfe, 0xc8, 0x7f, 0x2b, 0xc9, 0xf2, 0xc3, 0x21, 0xfc, +- 0x37, 0x15, 0x7f, 0x56, 0x2f, 0x9f, 0x7f, 0xdb, 0x3f, 0x1f, 0x18, 0x1f, +- 0xc7, 0x88, 0xcf, 0x75, 0xf1, 0xe7, 0x29, 0x78, 0xd0, 0x0e, 0x89, 0x2f, +- 0x0f, 0x21, 0xc5, 0x09, 0x62, 0xc4, 0xe3, 0x82, 0x2f, 0x09, 0x7e, 0x2e, +- 0xb8, 0x2d, 0x08, 0xff, 0x13, 0xff, 0x1e, 0x72, 0x7e, 0x54, 0xf0, 0x01, +- 0xe3, 0xfc, 0x9a, 0xe0, 0x23, 0x86, 0xfc, 0x71, 0x8b, 0xf1, 0x0f, 0xa1, +- 0xe7, 0x85, 0x7e, 0xc6, 0x90, 0x8f, 0x81, 0xe3, 0x63, 0x19, 0x71, 0xfb, +- 0x58, 0xea, 0x19, 0xf3, 0x2f, 0xf7, 0x75, 0xcd, 0x57, 0xa0, 0x38, 0xc2, +- 0x74, 0x9a, 0xff, 0x83, 0x03, 0xf8, 0x99, 0x6d, 0xbe, 0x3e, 0x48, 0xae, +- 0x9d, 0xb0, 0x1d, 0x57, 0x44, 0xbe, 0xd8, 0xb9, 0x3a, 0xa4, 0x7f, 0xe6, +- 0xa2, 0x41, 0xfd, 0x52, 0x17, 0x3f, 0xbe, 0x92, 0xba, 0xdc, 0xb1, 0x9a, +- 0x51, 0xc8, 0x79, 0xa5, 0x3c, 0x06, 0x52, 0x8f, 0x23, 0x46, 0x3d, 0x7b, +- 0xaa, 0x9e, 0xa5, 0xae, 0xea, 0xba, 0xbe, 0xb2, 0x75, 0xc5, 0xf5, 0xe1, +- 0x1a, 0xf5, 0x11, 0x1f, 0x12, 0x97, 0x92, 0xe1, 0xdf, 0xab, 0x09, 0x86, +- 0x18, 0x7f, 0xb6, 0xcd, 0xb8, 0xc1, 0x18, 0xf9, 0x6e, 0x1e, 0xf1, 0x94, +- 0xff, 0x0d, 0xeb, 0x9b, 0x04, 0x44, 0x3f, 0x6c, 0x53, 0x1f, 0xe5, 0xa1, +- 0xed, 0x2a, 0x9b, 0xe1, 0x6e, 0xf2, 0x0e, 0xf3, 0x4d, 0x38, 0x37, 0x09, +- 0xc3, 0x8d, 0x1b, 0xcc, 0xff, 0x5d, 0x8d, 0xed, 0x7e, 0x56, 0xe6, 0x53, +- 0xff, 0xa7, 0xef, 0xa5, 0xff, 0x2a, 0x48, 0xff, 0x63, 0xc5, 0x5d, 0xfd, +- 0x8e, 0xc8, 0xbd, 0xa2, 0xeb, 0x9b, 0x7f, 0xcb, 0x6e, 0x95, 0xfc, 0x7d, +- 0xab, 0x4b, 0xe4, 0x98, 0xbf, 0x56, 0xa5, 0xdb, 0xb7, 0xbb, 0xda, 0x1f, +- 0xe9, 0xf3, 0x69, 0xed, 0x3f, 0xcb, 0x07, 0x72, 0x6d, 0x3b, 0x3a, 0x7e, +- 0x7c, 0x5e, 0x24, 0x3b, 0x46, 0x3b, 0x9b, 0x46, 0x3e, 0x6b, 0xf7, 0x34, +- 0x07, 0xff, 0x4c, 0xfa, 0x73, 0x30, 0x1d, 0x1f, 0x3d, 0x07, 0x0b, 0xb0, +- 0x74, 0xb6, 0x42, 0xf6, 0x94, 0x5d, 0x56, 0x73, 0xa1, 0xc2, 0xf8, 0x62, +- 0x91, 0xf1, 0x97, 0x22, 0xc6, 0x2f, 0x49, 0x2e, 0x95, 0x98, 0x7e, 0x21, +- 0x40, 0xbd, 0xa3, 0xea, 0x61, 0x2d, 0xaf, 0xed, 0x3a, 0xc8, 0x1e, 0x7c, +- 0x5f, 0xbf, 0xa3, 0xed, 0xd0, 0xef, 0x65, 0xeb, 0x65, 0xf8, 0xbb, 0x8c, +- 0x4d, 0x3b, 0x1b, 0x87, 0xfc, 0x2c, 0xe3, 0x46, 0x03, 0xed, 0xba, 0x9a, +- 0xf4, 0xfa, 0xb0, 0x5e, 0x25, 0xbe, 0x29, 0x60, 0x7a, 0x51, 0xea, 0x73, +- 0x91, 0xfa, 0xa7, 0xac, 0xae, 0x10, 0x27, 0x20, 0xa6, 0xbd, 0x60, 0x17, +- 0xaf, 0x53, 0xbd, 0xe4, 0xe4, 0x5c, 0xe5, 0x67, 0x2a, 0xdb, 0x77, 0xbb, +- 0x5c, 0x8f, 0x85, 0x6c, 0x1d, 0x3f, 0x9c, 0x9a, 0xaf, 0x69, 0x7f, 0xad, +- 0x5e, 0xfd, 0xee, 0xcf, 0x53, 0x36, 0x1f, 0xb7, 0x5b, 0xda, 0x7f, 0x73, +- 0x6f, 0x30, 0x7b, 0xdc, 0x90, 0x40, 0xcd, 0xca, 0xfd, 0x8c, 0xd9, 0x2f, +- 0x83, 0xfa, 0xad, 0x6a, 0xf4, 0xcf, 0x11, 0xe9, 0xb7, 0x91, 0xce, 0x66, +- 0xeb, 0xb0, 0x7e, 0x46, 0xfe, 0x2f, 0x64, 0x9e, 0x54, 0xa1, 0xb7, 0x97, +- 0xb6, 0x91, 0x2e, 0x81, 0xf4, 0x61, 0x27, 0xce, 0x65, 0xf2, 0x70, 0x06, +- 0x06, 0xce, 0x95, 0x0f, 0x45, 0x4f, 0x43, 0xe6, 0x8b, 0x9b, 0xda, 0x5f, +- 0xc4, 0x5e, 0x06, 0xb2, 0xc3, 0x33, 0xe6, 0xc3, 0xdd, 0x3d, 0xdd, 0xef, +- 0xcb, 0xee, 0x20, 0x7f, 0x3d, 0xf8, 0xcd, 0xe7, 0xfa, 0x68, 0x52, 0xbf, +- 0x38, 0x63, 0x97, 0x77, 0x32, 0x79, 0x02, 0x38, 0xa1, 0xf7, 0x52, 0xda, +- 0xae, 0xf4, 0x5e, 0x45, 0x7d, 0x21, 0x34, 0x67, 0xd3, 0xfb, 0xf5, 0xfd, +- 0x44, 0xcf, 0xf5, 0x80, 0xfa, 0xa4, 0xbc, 0xaf, 0xef, 0xf4, 0x1c, 0xad, +- 0x45, 0xe9, 0xfe, 0x1d, 0x93, 0xb9, 0x69, 0x03, 0xcf, 0xcd, 0x92, 0xe9, +- 0xa7, 0xda, 0xb7, 0x83, 0xf3, 0xc5, 0xfe, 0xde, 0xd9, 0xbb, 0xb7, 0x39, +- 0x7b, 0x58, 0xde, 0x8b, 0x46, 0xde, 0x6f, 0xf5, 0xe2, 0x68, 0x3b, 0x83, +- 0xbe, 0x2b, 0x4e, 0x29, 0xbd, 0xc2, 0x2f, 0x73, 0xe1, 0x79, 0x9a, 0x77, +- 0x67, 0x84, 0x6f, 0x2e, 0x55, 0xaf, 0x83, 0xf8, 0x62, 0xa3, 0xae, 0x0b, +- 0xfb, 0xf8, 0xb2, 0x73, 0x4c, 0xfb, 0xb3, 0xb5, 0xc5, 0xf5, 0x71, 0x31, +- 0xd5, 0xaf, 0xe9, 0xf9, 0x3f, 0x22, 0xf5, 0xa0, 0xf8, 0xc8, 0x8f, 0x9d, +- 0xbd, 0xfe, 0xbe, 0x48, 0xd7, 0xd7, 0xa2, 0xd4, 0xb5, 0x3d, 0xb7, 0x49, +- 0x7d, 0xe4, 0x35, 0x7f, 0x35, 0xf2, 0x35, 0x1b, 0x61, 0x9d, 0xbc, 0x0e, +- 0x5d, 0xb1, 0xf3, 0x87, 0x8c, 0xbd, 0x81, 0xf4, 0xa1, 0x0b, 0x9f, 0x75, +- 0xb5, 0x5f, 0x7c, 0x5d, 0x8b, 0x18, 0x3f, 0x8d, 0xa4, 0x9f, 0x7a, 0xfe, +- 0xe1, 0xbb, 0x0b, 0xf2, 0x6e, 0x15, 0x3e, 0xe9, 0xed, 0x03, 0x9c, 0x6f, +- 0x1e, 0x34, 0x64, 0x7e, 0x2e, 0xc9, 0x1c, 0xfb, 0xa9, 0xc8, 0x73, 0xb2, +- 0xb9, 0x40, 0xf5, 0x0a, 0xe3, 0x32, 0xcf, 0x9a, 0x01, 0xd3, 0x13, 0x01, +- 0x7f, 0x07, 0x37, 0x3c, 0x9f, 0xf8, 0x26, 0x02, 0xc6, 0xf1, 0x12, 0xca, +- 0x85, 0xf0, 0xf3, 0x39, 0x62, 0x8f, 0xd6, 0x7d, 0xde, 0x73, 0xeb, 0x37, +- 0x64, 0x9e, 0x54, 0x74, 0xdc, 0xc4, 0xcf, 0xc7, 0xf1, 0x7c, 0x5c, 0xcd, +- 0x2d, 0xa6, 0xb9, 0x1e, 0xfc, 0x5e, 0xfd, 0x7f, 0x24, 0x59, 0xa9, 0x55, +- 0xd2, 0x71, 0xd6, 0xfd, 0xf6, 0xae, 0x11, 0x5f, 0x9d, 0x9f, 0x87, 0x12, +- 0x3d, 0xe7, 0xa7, 0xce, 0xa2, 0xbd, 0x15, 0x28, 0x7b, 0x5c, 0x3f, 0x8c, +- 0x4a, 0x8f, 0xed, 0xa1, 0xd8, 0xb1, 0x55, 0x99, 0x9b, 0xab, 0xcb, 0xa4, +- 0xe6, 0xdc, 0xaa, 0x3e, 0x9f, 0xa7, 0x86, 0x59, 0xdc, 0xba, 0x46, 0xe7, +- 0xe5, 0x6e, 0x8e, 0xcf, 0xbd, 0x05, 0x1d, 0xaf, 0x0a, 0xf9, 0xdf, 0xe6, +- 0x78, 0x3d, 0x77, 0x85, 0xf1, 0x22, 0x3c, 0x4d, 0x58, 0x6c, 0x4b, 0x9f, +- 0xaf, 0xfb, 0x05, 0x42, 0xa0, 0x78, 0xd9, 0x8f, 0xf1, 0x7e, 0x77, 0x64, +- 0x2f, 0x17, 0x52, 0xf9, 0x33, 0xf7, 0xe4, 0x41, 0x79, 0x3c, 0x62, 0xec, +- 0x0b, 0xbd, 0xd7, 0x2d, 0xe3, 0xfb, 0x36, 0x30, 0xea, 0xf1, 0xe5, 0x21, +- 0xf5, 0x08, 0x43, 0xea, 0xd9, 0x9c, 0x6f, 0x4b, 0xd2, 0xef, 0x79, 0x70, +- 0x72, 0xb4, 0x78, 0xfd, 0xfc, 0x0a, 0xe5, 0xd5, 0x5e, 0xe5, 0xef, 0x1a, +- 0xdf, 0x59, 0xb3, 0x28, 0x5e, 0xfe, 0x1a, 0xf3, 0xe5, 0xf9, 0x3c, 0xd4, +- 0xf8, 0xe6, 0x0a, 0xf7, 0x95, 0x0d, 0xff, 0x01, 0xd7, 0x0e, 0x41, 0x60, +- 0x88, 0x0d, 0x00, 0x00, 0x00 }; ++ /* Date: 06/17/2008 16:52 */ ++ 0xbd, 0x56, 0xcf, 0x6b, 0x1c, 0x75, 0x14, 0x7f, 0x3b, 0xbb, 0x33, 0x3b, ++ 0x99, 0x9d, 0xdd, 0x99, 0xda, 0x34, 0x4c, 0xb7, 0x2b, 0xd9, 0x86, 0x5e, ++ 0x36, 0x99, 0x62, 0xa2, 0x11, 0x0a, 0x46, 0x5b, 0x72, 0x09, 0xd8, 0x9e, ++ 0x02, 0x95, 0x22, 0x82, 0x71, 0xa9, 0x3d, 0xd8, 0x96, 0xe2, 0x5f, 0xe0, ++ 0x90, 0x9a, 0x08, 0x45, 0x0f, 0x0b, 0x36, 0x90, 0x20, 0x1a, 0x7b, 0x50, ++ 0x09, 0x0a, 0x3b, 0x07, 0x41, 0x44, 0x2d, 0xa8, 0x88, 0x60, 0x3d, 0x08, ++ 0x85, 0xda, 0x8b, 0x51, 0x8b, 0x8a, 0x07, 0x0f, 0x01, 0x8f, 0x9a, 0xf1, ++ 0xfb, 0x7e, 0x7c, 0x37, 0x33, 0x93, 0xdd, 0x24, 0x27, 0x03, 0xed, 0x87, ++ 0xf7, 0x9d, 0xf7, 0x7d, 0xdf, 0xf7, 0xde, 0xf7, 0xf3, 0x3e, 0xdf, 0xf5, ++ 0x01, 0xc0, 0x80, 0x28, 0x1e, 0x55, 0x08, 0x87, 0x8c, 0xa2, 0xad, 0xa0, ++ 0x00, 0xf0, 0x21, 0xf0, 0x9f, 0xe9, 0x92, 0x1d, 0x3d, 0x22, 0xf6, 0x04, ++ 0x43, 0x34, 0xe1, 0xab, 0xff, 0xaf, 0xc2, 0xe9, 0x26, 0x62, 0x11, 0x4e, ++ 0x1f, 0x47, 0x7c, 0x12, 0x6e, 0x37, 0x03, 0x85, 0xff, 0x26, 0x10, 0xa1, ++ 0x3d, 0xdc, 0xfd, 0x24, 0xae, 0x50, 0xfc, 0x4d, 0xd9, 0xff, 0x63, 0x91, ++ 0xf1, 0x54, 0x68, 0x73, 0x1c, 0x41, 0x38, 0xe9, 0x13, 0xdc, 0xed, 0xa0, ++ 0x7d, 0xfe, 0x3c, 0x58, 0x18, 0xe7, 0x6d, 0xe5, 0x80, 0x76, 0xa3, 0x10, ++ 0x9d, 0x94, 0xbc, 0x0c, 0xf6, 0xfb, 0xa9, 0xe3, 0xe1, 0x3a, 0xfc, 0x3c, ++ 0x8b, 0xf6, 0x51, 0xe7, 0xd5, 0x0e, 0x62, 0x00, 0x97, 0x6c, 0x97, 0xeb, ++ 0x19, 0xe5, 0xb0, 0x9b, 0xe3, 0xb8, 0x4f, 0xf9, 0x8e, 0x4b, 0x5c, 0x13, ++ 0xe3, 0xfe, 0x99, 0x70, 0x5c, 0x8c, 0x97, 0x8e, 0xd3, 0x50, 0x71, 0x70, ++ 0xdd, 0x92, 0xbc, 0xac, 0x5c, 0x5e, 0x96, 0xca, 0x43, 0xfa, 0x00, 0x3a, ++ 0x0f, 0xc4, 0x23, 0xea, 0x5c, 0x8c, 0xbb, 0x25, 0x75, 0x03, 0x3c, 0xdf, ++ 0x94, 0xf8, 0x31, 0xa2, 0x5b, 0xe0, 0x78, 0xea, 0x9f, 0xd4, 0xb1, 0x3b, ++ 0x8e, 0xee, 0x53, 0x36, 0xff, 0x72, 0xa8, 0xbf, 0xeb, 0xfb, 0xc0, 0x73, ++ 0x7e, 0x50, 0xe7, 0xa4, 0xfd, 0x61, 0x1f, 0xff, 0xef, 0x94, 0x7f, 0x36, ++ 0x2e, 0xaf, 0x7f, 0xbb, 0xb3, 0xde, 0xea, 0xd7, 0x37, 0x33, 0xd7, 0xb7, ++ 0x2f, 0xa5, 0x6f, 0x73, 0x70, 0xc2, 0x08, 0xc8, 0xaf, 0x04, 0x88, 0xc7, ++ 0x54, 0x02, 0x88, 0x0f, 0x0b, 0x5e, 0x13, 0xbc, 0x25, 0xf8, 0xae, 0xe0, ++ 0x11, 0xc1, 0x61, 0xc1, 0xc3, 0x82, 0x0f, 0x09, 0x6e, 0x09, 0xfa, 0x82, ++ 0x9e, 0x60, 0x4d, 0xf0, 0x2f, 0x41, 0x57, 0xb0, 0x92, 0x8b, 0x57, 0x17, ++ 0xb4, 0x05, 0x3f, 0x17, 0x7c, 0x22, 0xb7, 0xff, 0x68, 0x81, 0xf1, 0x81, ++ 0xd8, 0x4f, 0x89, 0x7d, 0x41, 0x6c, 0x6c, 0xa8, 0xf0, 0x3e, 0xd3, 0xaf, ++ 0x5b, 0xbd, 0xfb, 0xbd, 0xdb, 0x91, 0xef, 0x2d, 0xed, 0x67, 0x53, 0xff, ++ 0x60, 0x3c, 0xed, 0xff, 0xd6, 0x1e, 0xfe, 0xec, 0x36, 0xdb, 0xea, 0xb7, ++ 0xef, 0x66, 0xc2, 0x79, 0xbc, 0x29, 0xfb, 0x83, 0xee, 0x67, 0x03, 0xe6, ++ 0x68, 0x26, 0xcc, 0xf3, 0xab, 0xdf, 0x1c, 0x3d, 0x2e, 0x73, 0x34, 0xbd, ++ 0x8b, 0xbf, 0xcc, 0xd3, 0x33, 0xb2, 0x7f, 0x46, 0xf8, 0xd9, 0x18, 0xe0, ++ 0x17, 0xa5, 0xe6, 0x95, 0xce, 0x1b, 0x30, 0x0f, 0x1f, 0x15, 0xda, 0x61, ++ 0xc0, 0xfc, 0x89, 0xf6, 0xca, 0x0f, 0xf7, 0x0b, 0x7f, 0x5b, 0x9a, 0xc7, ++ 0x59, 0xfe, 0x32, 0x0f, 0xad, 0x1c, 0x0f, 0x5f, 0xde, 0xe7, 0x1e, 0x2a, ++ 0xb9, 0x7e, 0x5e, 0x56, 0xfe, 0x6c, 0x1a, 0x06, 0xe3, 0x1a, 0x63, 0xe8, ++ 0x5a, 0x25, 0xc4, 0x69, 0xf7, 0x1b, 0x8e, 0x37, 0x4a, 0x75, 0xb8, 0xc1, ++ 0x0a, 0xcd, 0x6d, 0x09, 0x56, 0xac, 0x21, 0x85, 0xff, 0x24, 0x6f, 0xb0, ++ 0x5f, 0xdd, 0xfc, 0x9e, 0x30, 0x58, 0xbb, 0xc3, 0xfe, 0xf7, 0x9a, 0x9c, ++ 0xf7, 0x33, 0x13, 0x90, 0xfb, 0xd3, 0xdf, 0x65, 0xde, 0x3d, 0xb4, 0xff, ++ 0x2e, 0x44, 0xb1, 0x3e, 0x47, 0xf6, 0x5d, 0xd6, 0x73, 0xc4, 0x7f, 0x8b, ++ 0x96, 0x4f, 0xf5, 0xde, 0x88, 0xc9, 0x1c, 0x76, 0x97, 0x7d, 0xfa, 0xfa, ++ 0x7a, 0xac, 0xeb, 0x11, 0x5d, 0x19, 0xd7, 0xf5, 0xf3, 0xfe, 0x2a, 0x9d, ++ 0x77, 0xb8, 0xbb, 0x9e, 0xe3, 0x49, 0xf3, 0x40, 0x3a, 0xbb, 0x95, 0xec, ++ 0xe8, 0x6c, 0xba, 0x0f, 0x5a, 0x67, 0x6d, 0x58, 0x98, 0xf3, 0xe8, 0xdc, ++ 0x9a, 0xc5, 0x61, 0x2e, 0x78, 0x8c, 0x17, 0x1d, 0xc6, 0xdf, 0x1c, 0xec, ++ 0x53, 0x92, 0x5c, 0xaa, 0xb0, 0xfd, 0x42, 0x55, 0xcf, 0xb7, 0xde, 0xaf, ++ 0xf3, 0xda, 0x2b, 0x1f, 0x3c, 0x5f, 0x9f, 0xa3, 0xf3, 0xd0, 0xe7, 0x65, ++ 0x79, 0x31, 0xf8, 0x5c, 0xc6, 0xb6, 0x91, 0xed, 0xc3, 0xda, 0x24, 0x63, ++ 0x69, 0x0a, 0xf3, 0xba, 0x9d, 0xf4, 0xe6, 0xbb, 0xe5, 0x93, 0xdf, 0x18, ++ 0xb0, 0x3d, 0x2f, 0x3c, 0x9c, 0xa7, 0xb9, 0x54, 0xba, 0x63, 0x20, 0xd6, ++ 0x21, 0xa2, 0x77, 0xc7, 0x70, 0xbe, 0x26, 0x5e, 0x14, 0x65, 0x5d, 0xdd, ++ 0xc3, 0x58, 0x76, 0x9e, 0x37, 0x99, 0x77, 0x76, 0x96, 0xaf, 0xc7, 0x84, ++ 0xaf, 0x4e, 0x77, 0xbd, 0xb3, 0xdf, 0x3c, 0x48, 0xc1, 0xbd, 0xfe, 0x6b, ++ 0x3d, 0xd4, 0xef, 0xb2, 0xd6, 0x3d, 0xfa, 0xdc, 0x8d, 0x8a, 0x99, 0x3a, ++ 0xcf, 0x40, 0xd8, 0xef, 0x7e, 0x3f, 0x16, 0x3d, 0x99, 0x16, 0x7d, 0x53, ++ 0x97, 0x18, 0x65, 0xf6, 0xd5, 0x80, 0xf2, 0x29, 0xe7, 0xe6, 0xac, 0xd4, ++ 0x9b, 0x9b, 0x45, 0x6b, 0x80, 0xde, 0x99, 0xfc, 0x7e, 0x2e, 0xcc, 0xe1, ++ 0xb9, 0x76, 0xe3, 0x06, 0xcd, 0x7f, 0x19, 0xfe, 0x70, 0xf9, 0x5e, 0xda, ++ 0x26, 0xda, 0xe6, 0xf0, 0x95, 0x4f, 0x33, 0xfd, 0x01, 0x38, 0xae, 0xdf, ++ 0x97, 0xf4, 0x1c, 0x07, 0xd0, 0x9e, 0x3a, 0xe8, 0x7b, 0x99, 0xe6, 0x7d, ++ 0x6d, 0x17, 0xef, 0xb5, 0x3e, 0x36, 0xc3, 0xf4, 0x9c, 0xe0, 0x3b, 0xc1, ++ 0xf7, 0xcd, 0xfa, 0x54, 0xc9, 0xf7, 0x41, 0xbd, 0x9f, 0xba, 0xbe, 0x7e, ++ 0xef, 0xe8, 0xaf, 0xdb, 0x07, 0xd3, 0xb3, 0x74, 0x9f, 0xfa, 0xe9, 0x99, ++ 0x93, 0xd3, 0xa7, 0x7b, 0xdb, 0x3d, 0x7d, 0x32, 0xfb, 0xd5, 0xff, 0x7f, ++ 0xe8, 0x36, 0xf7, 0xd3, 0x81, 0x74, 0x3d, 0x1b, 0x1b, 0xcc, 0x9f, 0xab, ++ 0xa9, 0x79, 0x49, 0xdf, 0xff, 0x90, 0xf0, 0x45, 0xf9, 0x51, 0x1d, 0x5f, ++ 0x6c, 0xef, 0xe8, 0x72, 0x9a, 0x7f, 0x2f, 0x0a, 0xff, 0x8d, 0x99, 0x75, ++ 0xe6, 0x47, 0xfb, 0xf7, 0xdc, 0x7d, 0x4d, 0x85, 0xc8, 0x97, 0x57, 0x20, ++ 0x96, 0x3c, 0xef, 0x67, 0xf2, 0xad, 0x8a, 0x2e, 0x95, 0xe1, 0x83, 0x58, ++ 0xd7, 0xc5, 0x9f, 0x9b, 0x21, 0xe3, 0xfb, 0xe4, 0xef, 0xef, 0xf3, 0x2e, ++ 0xf9, 0xf0, 0x5e, 0x4f, 0x7f, 0x3d, 0x8a, 0x37, 0x29, 0x3a, 0xb6, 0x20, ++ 0x7a, 0xf2, 0x8b, 0xc3, 0x7a, 0xd5, 0x3e, 0x4b, 0xfc, 0x85, 0x11, 0xd1, ++ 0x95, 0x76, 0x95, 0xed, 0x7a, 0x95, 0x7f, 0xef, 0x4e, 0x96, 0x5d, 0xf2, ++ 0xab, 0x57, 0x19, 0x47, 0x2a, 0xb8, 0x2f, 0x80, 0x07, 0xe7, 0xc8, 0x3d, ++ 0x5c, 0x75, 0xf9, 0x5d, 0x59, 0xbd, 0x23, 0x7a, 0xe7, 0xe9, 0xfe, 0x49, ++ 0xbd, 0x8f, 0xe1, 0xfa, 0x88, 0xd2, 0x0f, 0xb6, 0x99, 0x17, 0x6e, 0x6f, ++ 0x1e, 0xde, 0x91, 0xec, 0x9b, 0x5e, 0xba, 0xdf, 0x7a, 0x2e, 0x3b, 0xb9, ++ 0x3e, 0xeb, 0x7b, 0x3a, 0x95, 0x68, 0xbd, 0x1d, 0x9b, 0xc3, 0x7c, 0x3d, ++ 0xa8, 0x95, 0x99, 0x47, 0x8c, 0x2a, 0x8e, 0x51, 0xc6, 0x6d, 0x8d, 0x25, ++ 0xd1, 0xaf, 0xa5, 0x45, 0x0a, 0x73, 0x6e, 0x49, 0xaf, 0xcf, 0xd2, 0xe0, ++ 0xcc, 0x6f, 0x7c, 0x45, 0xeb, 0xb5, 0xb8, 0xc8, 0xeb, 0xe5, 0xb3, 0xba, ++ 0x5f, 0x1e, 0xd5, 0xbf, 0xc2, 0xfd, 0x7a, 0xee, 0x26, 0xe3, 0xb3, 0xf0, ++ 0x34, 0xa1, 0xb3, 0x22, 0x73, 0xbf, 0xea, 0xda, 0x84, 0x40, 0xfd, 0x32, ++ 0x1e, 0xe5, 0xf7, 0xd4, 0x94, 0x77, 0x70, 0x28, 0x75, 0x8f, 0xf9, 0xf7, ++ 0xea, 0xa0, 0xf7, 0x99, 0xd6, 0x6f, 0xfd, 0x9e, 0x16, 0x72, 0xbf, 0x5f, ++ 0xab, 0x39, 0x7e, 0xbe, 0x34, 0x80, 0x9f, 0x87, 0x06, 0xf0, 0x3b, 0xaf, ++ 0x87, 0x6d, 0x99, 0xff, 0x12, 0x98, 0x45, 0x7a, 0x08, 0xdd, 0xd2, 0x75, ++ 0xba, 0x5f, 0x63, 0x89, 0x7f, 0x4f, 0xb8, 0xe6, 0x72, 0x81, 0xfa, 0xe6, ++ 0x2e, 0xb3, 0x5f, 0x89, 0xd7, 0x03, 0x8d, 0xaf, 0x5d, 0xe7, 0x39, 0x33, ++ 0xe0, 0x3f, 0xdd, 0xd1, 0x99, 0x07, 0x78, 0x0d, 0x00, 0x00, 0x00 }; + + static u8 bnx2_xi_rv2p_proc2[] = { +- /* Date: 01/27/2009 19:01 */ ++ /* Date: 06/17/2008 16:52 */ + #define XI_RV2P_PROC2_MAX_BD_PAGE_LOC 5 + #define XI_RV2P_PROC2_BD_PAGE_SIZE_MSK 0xffff + #define XI_RV2P_PROC2_BD_PAGE_SIZE ((BCM_PAGE_SIZE / 16) - 1) +- 0xad, 0x57, 0x4d, 0x68, 0x5c, 0x55, 0x14, 0xbe, 0x33, 0x6f, 0x7e, 0xde, +- 0xcc, 0xbc, 0xc9, 0x4c, 0x93, 0x38, 0x99, 0x26, 0xc5, 0xa4, 0x09, 0x8d, +- 0x4e, 0x9d, 0x69, 0x27, 0x3f, 0x44, 0xb0, 0x42, 0x43, 0x90, 0xb4, 0xb5, +- 0x4a, 0xd3, 0x28, 0xc5, 0x5d, 0x92, 0xa9, 0x1d, 0x8c, 0x69, 0x23, 0x18, +- 0x70, 0xe1, 0xc6, 0x47, 0x5a, 0xd3, 0xcd, 0x2c, 0x4c, 0x31, 0x3f, 0x8a, +- 0xa0, 0xd8, 0x9d, 0xb8, 0x19, 0x50, 0xdb, 0x8a, 0x22, 0x14, 0x0c, 0x52, +- 0x17, 0x45, 0xb0, 0x58, 0x37, 0x8a, 0x58, 0x1b, 0x1a, 0x11, 0x8d, 0x8b, +- 0xae, 0x24, 0xe3, 0xbd, 0xe7, 0x3b, 0xf7, 0xcd, 0xbc, 0xc9, 0x8b, 0x89, +- 0x62, 0x36, 0x27, 0xe7, 0xbe, 0x73, 0xcf, 0x39, 0xf7, 0x9c, 0xef, 0x7c, +- 0xf7, 0x4e, 0x52, 0x08, 0x11, 0x10, 0x76, 0xb9, 0x5d, 0x4a, 0xe1, 0x33, +- 0x0c, 0x53, 0x8a, 0x8a, 0x10, 0xc1, 0xb4, 0xd2, 0x85, 0x5f, 0xf0, 0xdf, +- 0xfe, 0x24, 0x89, 0x6f, 0xcb, 0x96, 0x32, 0x13, 0x76, 0x46, 0xd9, 0x45, +- 0xc4, 0xb3, 0xfe, 0x88, 0x94, 0x87, 0xc5, 0x68, 0x06, 0xf6, 0x01, 0xa1, +- 0xa4, 0xb4, 0xb5, 0x95, 0xdc, 0xc5, 0xf2, 0x38, 0xcb, 0xc7, 0x7d, 0x90, +- 0x87, 0x58, 0x3e, 0x56, 0x27, 0x05, 0xdb, 0x3d, 0xcd, 0xfa, 0x00, 0x4b, +- 0x8b, 0xd7, 0x47, 0x59, 0xff, 0x90, 0xa5, 0xcd, 0xeb, 0x61, 0xd6, 0x1f, +- 0xf0, 0xa9, 0x25, 0xe4, 0xab, 0xf4, 0xb5, 0x4a, 0x55, 0xb7, 0xe0, 0x3e, +- 0x83, 0x73, 0x3c, 0xd3, 0xa1, 0xbe, 0xdf, 0xad, 0xb8, 0xed, 0xef, 0x38, +- 0xfa, 0xac, 0xa1, 0xf4, 0x1f, 0xa5, 0xee, 0x53, 0x6a, 0x73, 0x0a, 0xdb, +- 0x9b, 0xd3, 0x25, 0xb5, 0xdf, 0x10, 0xcb, 0xf3, 0x26, 0x55, 0x67, 0xd1, +- 0x82, 0x6e, 0x97, 0x4d, 0xaa, 0xcb, 0xa2, 0xc5, 0xfe, 0x58, 0xee, 0x8e, +- 0x23, 0xde, 0xa9, 0x0e, 0xd4, 0xed, 0xbb, 0x47, 0x60, 0x67, 0x27, 0x74, +- 0x61, 0xf1, 0xbd, 0x5d, 0xf0, 0xf7, 0x29, 0xa5, 0xaf, 0xfb, 0x9a, 0x7c, +- 0xa8, 0x47, 0x98, 0xad, 0xfc, 0x41, 0xb5, 0xbe, 0xb7, 0x7f, 0x71, 0x1e, +- 0xf6, 0x63, 0x1d, 0x58, 0x7f, 0x30, 0xab, 0xfc, 0x85, 0x84, 0xcd, 0x52, +- 0xe4, 0x28, 0x2f, 0x9f, 0x9d, 0x73, 0xfb, 0xff, 0x61, 0x1e, 0xda, 0x44, +- 0x1c, 0x7e, 0xa3, 0x2e, 0xbf, 0xa9, 0x4d, 0x7e, 0x6f, 0x47, 0x6a, 0xfd, +- 0x37, 0xf8, 0xe0, 0x3f, 0xba, 0xad, 0xff, 0x42, 0x1c, 0xb2, 0x29, 0xeb, +- 0x15, 0x27, 0xb2, 0x4d, 0xfe, 0x2f, 0x6e, 0xeb, 0xff, 0x55, 0x27, 0x7f, +- 0xbd, 0x5e, 0x5f, 0x3f, 0x52, 0x3f, 0xb0, 0x0f, 0xf2, 0xf6, 0xfd, 0xfa, +- 0xdc, 0x9c, 0x9f, 0x01, 0x39, 0x98, 0x25, 0x51, 0x3a, 0xcd, 0x00, 0x1f, +- 0xee, 0x56, 0x71, 0x1b, 0x45, 0xc0, 0xaf, 0xfc, 0x1d, 0x30, 0x43, 0xd7, +- 0xb0, 0xfe, 0x1c, 0xf7, 0xe9, 0x79, 0x3e, 0xc8, 0x2f, 0x51, 0x55, 0x98, +- 0x4a, 0xa5, 0x18, 0x63, 0xff, 0xdc, 0x67, 0x3b, 0x86, 0xfd, 0x2b, 0x96, +- 0xca, 0xef, 0x86, 0xc4, 0x8d, 0x57, 0xdf, 0x8d, 0x7f, 0xe8, 0x3b, 0xf6, +- 0xef, 0x7a, 0x08, 0x5f, 0xdf, 0x28, 0x42, 0x6f, 0xbb, 0x9c, 0xa4, 0xfa, +- 0x2c, 0x97, 0xbd, 0x70, 0x52, 0xef, 0x5f, 0xce, 0x71, 0x02, 0x71, 0x44, +- 0xa7, 0x49, 0xc9, 0xa1, 0xae, 0xd2, 0x26, 0xe7, 0x59, 0x27, 0xb1, 0xb8, +- 0x4f, 0xcf, 0x05, 0xf4, 0x62, 0x88, 0x44, 0x7a, 0x62, 0x4e, 0x9d, 0x33, +- 0x21, 0xc6, 0xfd, 0x2a, 0x61, 0x3f, 0xd7, 0xc5, 0x30, 0xad, 0x4f, 0x60, +- 0xff, 0x45, 0xbb, 0x45, 0x67, 0x28, 0xf6, 0x61, 0x5f, 0x73, 0x2f, 0xe4, +- 0x42, 0x6f, 0x50, 0x89, 0x6c, 0x71, 0x86, 0xd4, 0x03, 0x3f, 0xf7, 0x98, +- 0x64, 0x67, 0xe7, 0xf4, 0xdc, 0xe9, 0xbe, 0xa9, 0x3a, 0xbd, 0x52, 0x9d, +- 0xbf, 0x2e, 0xd4, 0xf5, 0xee, 0x3e, 0x65, 0x2f, 0x8b, 0xdb, 0x89, 0x38, +- 0xa3, 0x93, 0x5e, 0x73, 0xfb, 0x92, 0x53, 0xdf, 0x9d, 0xf6, 0x7f, 0x90, +- 0xea, 0x30, 0xc8, 0xf5, 0xe8, 0x60, 0x9c, 0xed, 0xf1, 0xc0, 0x59, 0x82, +- 0xfe, 0x5f, 0x1b, 0x4a, 0x52, 0x3d, 0x4f, 0x60, 0xfd, 0xd2, 0xf0, 0x15, +- 0xf4, 0xe3, 0x18, 0xd5, 0x41, 0x44, 0x2f, 0x7c, 0x8c, 0x5d, 0x13, 0x34, +- 0xdf, 0xe7, 0xfa, 0x8b, 0x9f, 0x42, 0x2f, 0x18, 0x4a, 0x9f, 0xb2, 0x4e, +- 0x5f, 0x85, 0x7d, 0xf0, 0x7c, 0x92, 0xea, 0x77, 0x82, 0xa3, 0x1c, 0x33, +- 0x88, 0x4f, 0x4a, 0xa1, 0xf3, 0xa4, 0x5a, 0x2b, 0xf4, 0x3d, 0x29, 0x2e, +- 0x96, 0xf1, 0x7d, 0x3a, 0xa6, 0xce, 0x37, 0xe2, 0xf0, 0xce, 0x64, 0x08, +- 0xfb, 0x4b, 0xf3, 0xe0, 0x8d, 0x7b, 0x1f, 0x29, 0x7d, 0x2c, 0x7b, 0x0f, +- 0xf6, 0xd9, 0xc9, 0x39, 0x76, 0xec, 0x47, 0xfd, 0xd6, 0xfc, 0xb0, 0x67, +- 0x58, 0x46, 0x03, 0xd4, 0x3f, 0x9f, 0xb0, 0x86, 0x21, 0x5f, 0xa7, 0xef, +- 0x7f, 0xf9, 0x4a, 0x54, 0xb7, 0x53, 0x0d, 0x81, 0x2b, 0xba, 0x3e, 0x2c, +- 0x13, 0xfa, 0x5c, 0x90, 0x3b, 0xc5, 0xfd, 0x9c, 0xb5, 0x15, 0xde, 0xb9, +- 0x8f, 0x99, 0xed, 0xf0, 0x0e, 0x39, 0xdc, 0x0d, 0x19, 0xea, 0x22, 0xbe, +- 0xf8, 0x17, 0xb8, 0xe7, 0xbc, 0x36, 0xcd, 0x15, 0x56, 0xab, 0xf8, 0x24, +- 0x21, 0x71, 0xe9, 0xc2, 0xa9, 0x9c, 0x03, 0xe2, 0x57, 0xd9, 0x07, 0x8d, +- 0x37, 0xe5, 0x30, 0x2c, 0xa6, 0xd8, 0xef, 0x24, 0xd7, 0xe3, 0x2c, 0xd7, +- 0xe3, 0x37, 0x96, 0xd3, 0x31, 0x5d, 0x07, 0xc8, 0x8b, 0x34, 0xff, 0x69, +- 0x8f, 0x7b, 0x43, 0xdf, 0x0f, 0xe8, 0xcf, 0x32, 0xf7, 0xf3, 0x2d, 0xe7, +- 0x9e, 0xd0, 0x75, 0xdd, 0xea, 0xbe, 0xd0, 0xf8, 0xc7, 0xfa, 0xe8, 0xa4, +- 0xe7, 0x39, 0x4b, 0x5f, 0x76, 0xc2, 0x4d, 0x63, 0x17, 0xa4, 0x53, 0xdf, +- 0x6e, 0x9a, 0xdf, 0x86, 0x96, 0xab, 0xfa, 0x7c, 0x2a, 0xcf, 0x5f, 0xf5, +- 0xfc, 0x35, 0x2c, 0xcd, 0x92, 0x8c, 0x36, 0x5e, 0x56, 0xf1, 0x5a, 0x3d, +- 0xf8, 0xc3, 0x3d, 0xc7, 0xf5, 0xf5, 0x9d, 0x8e, 0x13, 0xb1, 0xf6, 0xdf, +- 0x5c, 0x75, 0xcf, 0x2b, 0xe6, 0x33, 0xec, 0xe0, 0xbb, 0x79, 0x80, 0xfb, +- 0xc0, 0x32, 0xf5, 0xa8, 0xf2, 0x3b, 0xc2, 0x71, 0xf2, 0x1c, 0xc7, 0xaa, +- 0xe1, 0x0b, 0x95, 0xe7, 0xfa, 0x86, 0xe6, 0x09, 0x8d, 0x8f, 0x2a, 0x5f, +- 0xe8, 0x3e, 0x50, 0xfc, 0xec, 0xcd, 0x55, 0xb5, 0xbf, 0x6d, 0x1b, 0xfe, +- 0x58, 0x75, 0xfc, 0xdd, 0x72, 0x78, 0x22, 0x49, 0x71, 0x0f, 0xb3, 0xea, +- 0xe6, 0xc1, 0x3f, 0x24, 0x0f, 0xaa, 0xef, 0xa6, 0x69, 0x39, 0xf3, 0xc2, +- 0xfc, 0x37, 0xa3, 0xe2, 0xa5, 0x39, 0xff, 0xb4, 0xbe, 0xbf, 0x64, 0xfe, +- 0xcc, 0x93, 0x63, 0xb5, 0x7c, 0x77, 0xdb, 0x23, 0xee, 0x7f, 0xf5, 0xc7, +- 0xf3, 0x95, 0x65, 0xbe, 0xcf, 0x51, 0x9e, 0x95, 0xf1, 0x3c, 0xe3, 0x25, +- 0x57, 0xdf, 0x07, 0xf4, 0x15, 0xf6, 0xb2, 0xbf, 0x9a, 0xf7, 0xfa, 0xb4, +- 0x7f, 0xa8, 0x76, 0x4f, 0xad, 0x7d, 0x7d, 0xff, 0x03, 0x5b, 0xf0, 0xf8, +- 0xe7, 0x1b, 0x78, 0x7f, 0x7d, 0xb6, 0x51, 0x7d, 0x4f, 0x79, 0xe2, 0xc4, +- 0x16, 0x74, 0x3f, 0x85, 0x25, 0x9e, 0xe9, 0xbd, 0x26, 0xb4, 0xbd, 0x3f, +- 0x88, 0xf7, 0xa4, 0x60, 0xfc, 0x9e, 0x7b, 0x98, 0xfd, 0x64, 0xc0, 0xc7, +- 0x2f, 0x9c, 0xa1, 0xfe, 0xbe, 0x79, 0xf6, 0x3e, 0xf1, 0xf2, 0x7b, 0x2f, +- 0x5f, 0x53, 0x7e, 0x77, 0x8b, 0xd5, 0x19, 0x8b, 0xf2, 0x1a, 0xda, 0x0b, +- 0xf3, 0xfb, 0x87, 0xea, 0xfb, 0xad, 0xfc, 0x9a, 0x8c, 0x07, 0x69, 0x37, +- 0xe1, 0x7e, 0x97, 0x6c, 0xce, 0x13, 0x73, 0x7f, 0x24, 0x81, 0x7d, 0x9a, +- 0xbf, 0xdc, 0xf8, 0x79, 0x77, 0xa3, 0x7a, 0xff, 0xc0, 0xcd, 0xad, 0x83, +- 0xde, 0x73, 0x71, 0xb2, 0xaf, 0x36, 0x4e, 0x46, 0xac, 0x94, 0xe1, 0x7f, +- 0x84, 0x79, 0x65, 0x9c, 0x13, 0xf9, 0x29, 0x9a, 0xa0, 0x78, 0x85, 0xe3, +- 0x84, 0x6b, 0x91, 0x8a, 0xe1, 0xdc, 0x85, 0xa7, 0xf0, 0xbd, 0x10, 0xc7, +- 0x7a, 0x6b, 0x1c, 0xef, 0xcd, 0x91, 0xb0, 0x45, 0xf6, 0xad, 0x71, 0xc8, +- 0x14, 0xf3, 0xcf, 0x8a, 0xc3, 0xcb, 0x90, 0xcb, 0xa1, 0xad, 0x78, 0x19, +- 0xf7, 0xdb, 0xf5, 0x90, 0x5a, 0x97, 0x8f, 0xa0, 0x0c, 0x78, 0x69, 0xa8, +- 0xdb, 0xa2, 0xef, 0xa3, 0x19, 0xe0, 0x48, 0x74, 0x7a, 0x9f, 0xab, 0x0d, +- 0xfc, 0xd2, 0x5a, 0xe5, 0xef, 0x5a, 0x9e, 0xb7, 0x7a, 0x97, 0x1c, 0x1e, +- 0x75, 0xe7, 0x01, 0xfe, 0x52, 0xfe, 0x49, 0x95, 0x7c, 0xb5, 0x13, 0x7e, +- 0x37, 0x18, 0x2f, 0xbf, 0xf3, 0xbd, 0xdf, 0x24, 0xbe, 0x2a, 0xa3, 0x0e, +- 0x2b, 0xe5, 0xfa, 0xfe, 0xe8, 0x3c, 0x74, 0x1c, 0x9c, 0x4b, 0x9f, 0xb3, +- 0x1a, 0x17, 0x79, 0x9d, 0xe1, 0xfc, 0xef, 0xd0, 0xfb, 0x2f, 0xc5, 0xe7, +- 0x55, 0x7e, 0xb1, 0x7e, 0x94, 0xee, 0xa1, 0xa0, 0x7c, 0xdf, 0x6b, 0xdd, +- 0x7d, 0x3f, 0x8c, 0x50, 0x5e, 0x8d, 0x72, 0x41, 0xef, 0x77, 0x9f, 0xbb, +- 0x39, 0x0f, 0xb9, 0x90, 0xd7, 0x7d, 0xd3, 0xfd, 0xd5, 0xfd, 0x44, 0xdf, +- 0x53, 0x3d, 0x64, 0xd6, 0x5f, 0xe8, 0x21, 0x9c, 0xe7, 0x0b, 0xeb, 0xee, +- 0x77, 0xf2, 0xc9, 0xac, 0xb2, 0x7f, 0x4d, 0x7c, 0x43, 0xf3, 0x28, 0xc4, +- 0xf7, 0x2c, 0xab, 0x7c, 0x29, 0xf8, 0xaf, 0x96, 0x77, 0x0d, 0x71, 0x3d, +- 0xc8, 0xcb, 0x7d, 0x7a, 0xee, 0xdc, 0xf3, 0x5b, 0xad, 0xbb, 0x3a, 0xc7, +- 0x13, 0x1e, 0xfc, 0xa4, 0xcf, 0xa9, 0xec, 0xf3, 0x8c, 0x5f, 0x53, 0x0c, +- 0x1d, 0xc1, 0xfb, 0xb0, 0x21, 0x8c, 0x39, 0x69, 0x08, 0x7b, 0xdd, 0xef, +- 0x12, 0x3f, 0x11, 0xfa, 0x05, 0xb3, 0xa7, 0x31, 0x42, 0xe7, 0xba, 0x74, +- 0xe3, 0x6b, 0x32, 0x7b, 0x7f, 0x29, 0x86, 0xf5, 0x96, 0x21, 0x84, 0x09, +- 0x10, 0xde, 0x0d, 0x71, 0x01, 0xf3, 0xf0, 0xce, 0x02, 0xe4, 0xdb, 0xe2, +- 0x49, 0xf8, 0x69, 0x9c, 0xa5, 0xfb, 0xd4, 0x6c, 0x41, 0x79, 0x4b, 0x4b, +- 0x8c, 0xf3, 0xb4, 0x9f, 0x7e, 0xaf, 0x56, 0x44, 0x9c, 0x7f, 0x47, 0xf0, +- 0xbc, 0x02, 0xcf, 0x81, 0x9a, 0xbe, 0xef, 0x14, 0xdf, 0x4a, 0x8f, 0x4b, +- 0xfc, 0xc2, 0x0d, 0xe3, 0xdc, 0xac, 0xc7, 0xb9, 0xee, 0x6f, 0xda, 0xef, +- 0x89, 0xeb, 0x81, 0xcd, 0xb8, 0xd6, 0xf9, 0xa9, 0x3a, 0xff, 0xe9, 0xbc, +- 0x7b, 0x37, 0xfb, 0x57, 0xfb, 0x62, 0x12, 0xdf, 0xff, 0x17, 0xae, 0x21, +- 0x8f, 0x76, 0xa9, 0xf8, 0x2d, 0x35, 0xf8, 0xf4, 0x9e, 0x3b, 0xf0, 0x9b, +- 0x21, 0x79, 0xfc, 0x6f, 0x6a, 0x8c, 0x09, 0xd0, 0x18, 0x10, 0x00, 0x00, +- 0x00 }; ++ 0xad, 0x58, 0x4d, 0x4c, 0x54, 0x57, 0x14, 0xbe, 0xf3, 0xc3, 0xcc, 0x30, ++ 0xbc, 0x99, 0x41, 0x98, 0x0e, 0x7f, 0xa6, 0x22, 0x28, 0x82, 0x1d, 0x14, ++ 0x06, 0xd4, 0xb6, 0x36, 0xa9, 0xc1, 0x06, 0xb5, 0xb5, 0x11, 0x69, 0x63, ++ 0xba, 0x68, 0x8a, 0x60, 0x45, 0x06, 0xc1, 0x10, 0x31, 0x2e, 0xdc, 0x74, ++ 0x02, 0x16, 0xbb, 0x98, 0x85, 0x98, 0xe2, 0x60, 0xd3, 0x18, 0x52, 0x37, ++ 0xa6, 0x3b, 0x92, 0xb6, 0x62, 0xbb, 0x30, 0x31, 0x2d, 0xb1, 0xb6, 0x89, ++ 0x36, 0xb1, 0x7f, 0x9b, 0xa6, 0xa6, 0x5a, 0x8a, 0x4a, 0x2d, 0xda, 0xb2, ++ 0xaa, 0xd0, 0x77, 0xcf, 0x77, 0xee, 0x9b, 0x37, 0x33, 0x6f, 0x44, 0x53, ++ 0xd9, 0x1c, 0xee, 0x7d, 0xe7, 0x9e, 0x7b, 0xce, 0x77, 0x7e, 0xef, 0xe4, ++ 0x0b, 0x21, 0x9c, 0x22, 0x36, 0xbe, 0x4c, 0xa7, 0x62, 0x89, 0xdd, 0xe1, ++ 0xd1, 0xc9, 0x82, 0x10, 0x39, 0xc5, 0x72, 0x2d, 0xec, 0x82, 0xff, 0x56, ++ 0xe7, 0x13, 0xb9, 0x36, 0x2e, 0xbf, 0xbb, 0xc5, 0xeb, 0x76, 0x7c, 0x77, ++ 0x0a, 0x49, 0x03, 0x42, 0xc4, 0x24, 0xcd, 0x67, 0xba, 0x9d, 0xe9, 0x4a, ++ 0x1b, 0xe8, 0x46, 0xa6, 0x51, 0xa6, 0x2b, 0x98, 0xd6, 0xdb, 0x41, 0x57, ++ 0x31, 0xad, 0xe6, 0x7d, 0x8d, 0xcf, 0xd7, 0xf2, 0xfe, 0x7b, 0x4c, 0x8f, ++ 0xf2, 0xbe, 0xa6, 0xf3, 0x29, 0xbd, 0xe4, 0x7a, 0x66, 0x41, 0xc4, 0xf4, ++ 0x33, 0x42, 0xdf, 0xae, 0x51, 0xfb, 0x1a, 0x91, 0x58, 0x0d, 0xf4, 0x7e, ++ 0xad, 0x5c, 0xf2, 0xfd, 0x61, 0xc1, 0x27, 0xf7, 0x6f, 0x2e, 0x28, 0x79, ++ 0x03, 0x0e, 0xb9, 0xfe, 0x55, 0x5f, 0xdb, 0xe4, 0x32, 0x18, 0x82, 0x98, ++ 0x60, 0x71, 0x5c, 0xca, 0x71, 0x88, 0xd1, 0x61, 0x0f, 0xa1, 0x72, 0x52, ++ 0xc3, 0x3a, 0x46, 0x78, 0xd8, 0xf4, 0x35, 0xcb, 0x63, 0x5a, 0xe2, 0xc3, ++ 0xbd, 0xbb, 0xca, 0x71, 0xdf, 0x8f, 0xcf, 0x80, 0x2f, 0x16, 0x50, 0x80, ++ 0xe2, 0xfb, 0x32, 0xc1, 0xdf, 0xf7, 0xcb, 0xf5, 0xac, 0xad, 0xd0, 0x06, ++ 0x5c, 0xdd, 0xcc, 0x65, 0xcf, 0x91, 0xfb, 0xcb, 0x1b, 0x4f, 0x0e, 0x83, ++ 0xbf, 0xad, 0x1c, 0xfb, 0x4f, 0x87, 0xa5, 0x3c, 0x97, 0x88, 0x31, 0x15, ++ 0xb5, 0xa4, 0x97, 0x2d, 0x56, 0x9b, 0x2a, 0xff, 0x97, 0x61, 0xac, 0xda, ++ 0x7d, 0x90, 0xeb, 0x4d, 0x91, 0x1b, 0xca, 0x90, 0xfb, 0x53, 0xae, 0x59, ++ 0xbe, 0xdf, 0x06, 0xf9, 0xde, 0x45, 0xe5, 0x77, 0xf8, 0x40, 0x0b, 0xc3, ++ 0x56, 0xf7, 0xe4, 0x2e, 0xa2, 0x7f, 0xf7, 0xa2, 0xf2, 0x8f, 0x18, 0xfa, ++ 0x2b, 0xff, 0xa9, 0xef, 0xe9, 0x38, 0xd2, 0xf2, 0xe3, 0xd8, 0x5a, 0x16, ++ 0xb3, 0x5a, 0xd9, 0xcf, 0x7a, 0x3a, 0x40, 0x37, 0x85, 0x89, 0xc4, 0xf7, ++ 0x70, 0x80, 0x37, 0x57, 0xc9, 0xfb, 0x0b, 0x84, 0xd3, 0x2e, 0xe5, 0xd5, ++ 0x79, 0x5c, 0xe7, 0xb1, 0xff, 0x06, 0xfb, 0xeb, 0x6d, 0x36, 0xe8, 0xa6, ++ 0x57, 0x02, 0xb4, 0xb0, 0xd0, 0x99, 0xc7, 0xf2, 0xd9, 0xdf, 0xb1, 0x3c, ++ 0x9c, 0x9f, 0xd4, 0xa4, 0x9e, 0x5f, 0xeb, 0xf1, 0x63, 0xe5, 0x7f, 0xc7, ++ 0x43, 0xfc, 0x8f, 0xf3, 0x4b, 0x56, 0xe1, 0xeb, 0xf1, 0x4e, 0xac, 0xcb, ++ 0xce, 0xe4, 0x13, 0x4e, 0xa3, 0xe3, 0x56, 0xf1, 0x92, 0x2e, 0x5f, 0xcf, ++ 0xe3, 0x00, 0xee, 0x11, 0x15, 0x1e, 0x52, 0x0e, 0xf8, 0xea, 0x3c, 0xb5, ++ 0x96, 0x38, 0x89, 0x93, 0x2b, 0xe5, 0xbe, 0x5d, 0xb4, 0x3a, 0x34, 0xba, ++ 0xa7, 0x35, 0xaa, 0xf2, 0x06, 0xdf, 0x3b, 0x5d, 0x44, 0x8a, 0xdb, 0x87, ++ 0xa4, 0xdd, 0x01, 0xb1, 0xdb, 0x1e, 0x20, 0x7e, 0xe0, 0xe4, 0xf0, 0x68, ++ 0x9f, 0x81, 0xff, 0xc2, 0x32, 0x8d, 0x6c, 0xea, 0x6c, 0xc0, 0xb9, 0x60, ++ 0x04, 0x74, 0x24, 0x92, 0x23, 0x49, 0xb8, 0xb3, 0x9f, 0x96, 0x6b, 0x7e, ++ 0xab, 0xf7, 0x10, 0x5f, 0xac, 0x56, 0xe5, 0xa5, 0xf2, 0xa3, 0xc4, 0xed, ++ 0x90, 0x91, 0x87, 0xa2, 0x12, 0x38, 0xff, 0xbe, 0x52, 0xf2, 0xeb, 0x60, ++ 0x57, 0xe0, 0x9e, 0xa4, 0x7e, 0xe6, 0xbc, 0xee, 0x35, 0xe5, 0xf5, 0xe3, ++ 0xc5, 0xc5, 0x26, 0xc2, 0x67, 0x13, 0xe3, 0x54, 0xce, 0x71, 0xb8, 0xd4, ++ 0x22, 0x0e, 0x03, 0xf4, 0xff, 0xad, 0xa6, 0x7c, 0xc2, 0x79, 0x07, 0xf6, ++ 0x4f, 0x34, 0x9f, 0x83, 0x9f, 0xb6, 0x11, 0x1e, 0xc2, 0x7b, 0xf4, 0x53, ++ 0x9c, 0x6a, 0xa7, 0xfc, 0xef, 0x6d, 0xec, 0xfc, 0x1c, 0xeb, 0x0e, 0x87, ++ 0x5c, 0xef, 0xd7, 0xf6, 0x4c, 0x80, 0x3f, 0x67, 0x10, 0xb8, 0xef, 0xe0, ++ 0x5b, 0xb6, 0x39, 0xa8, 0xde, 0xc4, 0x5d, 0x83, 0xb4, 0xd4, 0x26, 0xe9, ++ 0x7b, 0xbe, 0x38, 0x36, 0x8e, 0xef, 0x07, 0xf2, 0xa4, 0x9d, 0xaf, 0x1a, ++ 0x75, 0x29, 0xea, 0xc2, 0xf9, 0xf8, 0x30, 0xea, 0xca, 0xf4, 0x27, 0x72, ++ 0xdd, 0x16, 0x9e, 0x06, 0x7f, 0x38, 0x3a, 0xc4, 0x82, 0xed, 0xc0, 0xf1, ++ 0x96, 0x1d, 0xfc, 0x1c, 0xae, 0x5e, 0x27, 0xf9, 0xd1, 0x26, 0xb4, 0x66, ++ 0xd0, 0x77, 0xe9, 0xfb, 0xbf, 0xb6, 0x38, 0xe1, 0xb6, 0xcb, 0xef, 0x3c, ++ 0xa7, 0xf0, 0x61, 0x1a, 0x50, 0x76, 0x81, 0x3e, 0x6a, 0x3e, 0x0c, 0x69, ++ 0xd9, 0xf2, 0x80, 0xfd, 0x59, 0xb3, 0x58, 0x1e, 0x80, 0x36, 0x57, 0x81, ++ 0xba, 0x2a, 0xa9, 0x9e, 0x3c, 0x46, 0x3e, 0xb0, 0x5e, 0x19, 0xf9, 0x86, ++ 0xdd, 0x64, 0x9c, 0x12, 0xd1, 0xe3, 0x33, 0x25, 0x5e, 0x39, 0x3f, 0x96, ++ 0xeb, 0x7e, 0x50, 0x71, 0x27, 0x05, 0xba, 0xc5, 0x7e, 0x96, 0x1b, 0x65, ++ 0x3c, 0x7a, 0x18, 0x8f, 0x19, 0xa6, 0x07, 0xf2, 0x14, 0x0e, 0xa0, 0xc7, ++ 0x34, 0xdc, 0xdb, 0x1a, 0x95, 0x7e, 0x0c, 0x5a, 0xf4, 0x17, 0xd5, 0x47, ++ 0xe0, 0xa7, 0x51, 0xf6, 0xeb, 0x29, 0xa3, 0x9f, 0x28, 0x7c, 0xb3, 0xf5, ++ 0x95, 0xd4, 0x7c, 0x4a, 0xb3, 0x33, 0xfe, 0x55, 0x05, 0x8e, 0x17, 0x54, ++ 0x82, 0x1a, 0xf8, 0x56, 0x51, 0x1e, 0xfb, 0x8b, 0x26, 0x94, 0x7d, 0x52, ++ 0xbf, 0x3b, 0x2a, 0x0f, 0xfd, 0x89, 0x01, 0xa2, 0xde, 0x82, 0x33, 0xf2, ++ 0x9e, 0x52, 0x8b, 0xba, 0x92, 0x9a, 0xcf, 0xe9, 0xf8, 0x1e, 0xf0, 0x51, ++ 0xc1, 0x6d, 0xbc, 0x32, 0x95, 0x9a, 0xb7, 0xc8, 0x4f, 0xb7, 0x11, 0xdf, ++ 0xc1, 0xf5, 0xec, 0x07, 0xa6, 0xa1, 0x0d, 0x52, 0x6e, 0x0b, 0xdf, 0x53, ++ 0xc7, 0xf7, 0x68, 0xa6, 0xba, 0x21, 0xf5, 0xfc, 0x73, 0x5e, 0xd5, 0x0b, ++ 0x15, 0x1f, 0xc9, 0xba, 0xa1, 0xfc, 0x40, 0xf7, 0x87, 0xaf, 0x4c, 0xc9, ++ 0xf3, 0x65, 0x8b, 0xd4, 0x91, 0x1b, 0x86, 0xbc, 0xef, 0x8d, 0x3a, 0x21, ++ 0xbf, 0xe7, 0x89, 0x17, 0x79, 0x99, 0x5a, 0x0f, 0xff, 0xd2, 0xeb, 0x21, ++ 0xd9, 0xe1, 0xd1, 0xce, 0x71, 0xfd, 0xeb, 0x97, 0xf7, 0x14, 0xb3, 0xde, ++ 0xc5, 0xaa, 0xaf, 0xe9, 0x7a, 0x73, 0x9d, 0x6c, 0x33, 0xd7, 0xbb, 0x1f, ++ 0xe6, 0x93, 0x75, 0x4b, 0xae, 0xaf, 0xcd, 0x67, 0xce, 0x27, 0x96, 0xb8, ++ 0xc6, 0x44, 0x00, 0x73, 0x58, 0x2c, 0x20, 0xcf, 0xe5, 0xd8, 0x32, 0xeb, ++ 0x5f, 0xba, 0x1d, 0xc0, 0xa5, 0xdd, 0xee, 0x23, 0xbe, 0xeb, 0x7d, 0xf2, ++ 0xdc, 0xb4, 0x50, 0xf6, 0xa2, 0x0e, 0x96, 0x73, 0xbf, 0x5f, 0xca, 0x7a, ++ 0xeb, 0xf2, 0x6a, 0x29, 0x1f, 0x3c, 0xd7, 0xfb, 0xcc, 0x7a, 0x5f, 0x98, ++ 0xcf, 0x7e, 0x9f, 0x75, 0x1c, 0xf4, 0x71, 0x9f, 0xe5, 0x39, 0xc1, 0xb3, ++ 0xe7, 0x0b, 0xa5, 0x17, 0xdf, 0x1f, 0x50, 0x7a, 0x68, 0xe4, 0xa7, 0xa9, ++ 0x7e, 0x29, 0xa7, 0x50, 0x70, 0xd8, 0x88, 0xde, 0x6a, 0xd4, 0xdf, 0x99, ++ 0xbd, 0xb0, 0xa3, 0xb7, 0x4a, 0xea, 0xa1, 0x7b, 0x25, 0x86, 0x3c, 0x17, ++ 0xdc, 0x8f, 0xbe, 0x1c, 0xb6, 0xf2, 0xeb, 0xb7, 0xcc, 0x17, 0x64, 0xfb, ++ 0xf2, 0xd9, 0xbe, 0xb0, 0x48, 0xaf, 0xf3, 0x6d, 0xe5, 0xd4, 0x0f, 0x98, ++ 0xef, 0x05, 0xd5, 0x0f, 0x74, 0x3e, 0xc2, 0x99, 0xe5, 0x58, 0xe1, 0x64, ++ 0x25, 0x67, 0x82, 0xe3, 0xa0, 0x8b, 0xf9, 0x9c, 0x59, 0xe7, 0x9b, 0xb9, ++ 0x55, 0xd4, 0x57, 0x4e, 0x1f, 0xa1, 0xfe, 0xe0, 0x33, 0xe2, 0x34, 0xd5, ++ 0x8e, 0xe3, 0x4f, 0x10, 0x77, 0x9a, 0xff, 0xc4, 0x3e, 0x7f, 0x36, 0x7c, ++ 0x9d, 0x72, 0x7b, 0x6c, 0x76, 0x42, 0xf9, 0x47, 0x23, 0x7b, 0xa7, 0xfa, ++ 0xd5, 0x9c, 0x6f, 0xc6, 0xdd, 0x6e, 0xc2, 0x1d, 0xfc, 0x98, 0xef, 0xfe, ++ 0x0f, 0xde, 0x56, 0xf3, 0x41, 0x9f, 0x91, 0x9f, 0x03, 0x2e, 0xab, 0xfa, ++ 0xbf, 0xd6, 0x88, 0x97, 0x83, 0x3c, 0xe7, 0xcd, 0x69, 0xf4, 0x4f, 0x64, ++ 0x26, 0x4e, 0x4b, 0xad, 0xe4, 0xac, 0xe4, 0x5b, 0x1d, 0x39, 0xc8, 0x76, ++ 0x5d, 0x76, 0xc0, 0xee, 0xae, 0xbd, 0x58, 0x5f, 0xe1, 0x7a, 0x7d, 0x8f, ++ 0xeb, 0xe3, 0x4e, 0x0f, 0xe8, 0x4c, 0x35, 0xe1, 0x11, 0x39, 0x78, 0x5e, ++ 0xc9, 0x27, 0xb9, 0xda, 0x1c, 0xe3, 0xf9, 0x92, 0x83, 0xed, 0xac, 0x20, ++ 0x3f, 0x46, 0xee, 0x52, 0x3d, 0x70, 0x8a, 0xa6, 0xe5, 0x92, 0x96, 0xe8, ++ 0xb8, 0xb1, 0x3e, 0x1b, 0x41, 0x5b, 0xd5, 0x80, 0x5f, 0x93, 0xee, 0x67, ++ 0x6c, 0xbb, 0x2a, 0xf8, 0x7c, 0x3b, 0xd6, 0x6e, 0xae, 0x67, 0x09, 0xd6, ++ 0xeb, 0xfd, 0x6a, 0x50, 0x7f, 0x0d, 0xe6, 0x84, 0x29, 0xea, 0x0b, 0x81, ++ 0x48, 0xff, 0x04, 0xec, 0xe9, 0xd9, 0x0c, 0x7b, 0xef, 0x33, 0x0e, 0x4c, ++ 0xfd, 0xa7, 0x06, 0xa9, 0xef, 0xf8, 0x87, 0x30, 0x67, 0xf8, 0x5d, 0x83, ++ 0xb0, 0xa3, 0x67, 0x0e, 0xeb, 0xfb, 0xcf, 0x81, 0xfe, 0xf3, 0x3c, 0xce, ++ 0x1d, 0x3a, 0xc2, 0xf8, 0x6c, 0xb6, 0x3e, 0xd7, 0xf5, 0x37, 0xf8, 0x7a, ++ 0xab, 0xe5, 0xfd, 0x6f, 0x8d, 0xf1, 0xfc, 0x21, 0xa2, 0x34, 0xef, 0xbc, ++ 0xa9, 0xcd, 0xf1, 0xba, 0x9b, 0xfb, 0xe2, 0x6d, 0x9e, 0x17, 0x7a, 0xd2, ++ 0xe6, 0x85, 0x69, 0xd4, 0xe9, 0xb1, 0xb9, 0xb8, 0xdc, 0xd0, 0xeb, 0x65, ++ 0xae, 0x95, 0x7f, 0x7d, 0x91, 0x22, 0xf6, 0x5b, 0x70, 0x1d, 0xe8, 0xc8, ++ 0x3a, 0xf4, 0xeb, 0x9e, 0xc3, 0x8c, 0x4f, 0x23, 0xf9, 0x69, 0xcd, 0xec, ++ 0x44, 0xfa, 0x79, 0x19, 0x3f, 0xed, 0xf3, 0x78, 0x3f, 0x6e, 0xd6, 0xa9, ++ 0xba, 0x0f, 0xe7, 0x3a, 0xe8, 0x7d, 0x71, 0xcf, 0x98, 0x3f, 0xa7, 0x49, ++ 0xff, 0xb2, 0xb1, 0x39, 0x92, 0x53, 0x2a, 0x0a, 0x29, 0x0e, 0x4b, 0xfc, ++ 0xb3, 0xb0, 0x27, 0x92, 0x60, 0x1c, 0xfa, 0x9e, 0x05, 0x3d, 0xcc, 0x71, ++ 0xa0, 0xfc, 0x7b, 0x75, 0x83, 0x46, 0xe7, 0xa6, 0xfa, 0x71, 0x8f, 0xca, ++ 0xa3, 0xf4, 0xb9, 0x58, 0xc5, 0x45, 0x49, 0x03, 0xad, 0x45, 0xd7, 0x21, ++ 0xb2, 0x53, 0xf7, 0xa7, 0x8c, 0x27, 0x1d, 0x2b, 0xee, 0xdb, 0xa9, 0xf1, ++ 0x22, 0xe3, 0x49, 0xc5, 0xad, 0x39, 0xce, 0xcc, 0x71, 0x94, 0x1a, 0x3f, ++ 0x7e, 0xea, 0x2f, 0x7a, 0x31, 0xa0, 0x77, 0x89, 0x2b, 0x92, 0x18, 0x7e, ++ 0x38, 0x8e, 0xa7, 0x80, 0x63, 0x84, 0xf5, 0xd6, 0xa2, 0x34, 0x8f, 0x3e, ++ 0x25, 0x86, 0xd8, 0x9f, 0xd3, 0xd5, 0x9c, 0xff, 0x15, 0xf0, 0x67, 0xdf, ++ 0x0a, 0xe8, 0xd3, 0xc7, 0x79, 0x74, 0x87, 0xe7, 0x0c, 0xc4, 0x81, 0x5b, ++ 0xeb, 0x9c, 0x60, 0xbf, 0x73, 0x3c, 0x76, 0x33, 0x0e, 0xb7, 0x81, 0x83, ++ 0xa6, 0x70, 0x88, 0x1a, 0x38, 0xa8, 0x7a, 0x63, 0x96, 0x53, 0xa0, 0xc7, ++ 0x93, 0xa4, 0x4b, 0xb4, 0xab, 0x34, 0x8f, 0xe5, 0xb0, 0xdd, 0x3a, 0x5f, ++ 0x83, 0xb4, 0xcf, 0xcf, 0xf6, 0xf9, 0xc4, 0xbe, 0x35, 0xe6, 0x73, 0x79, ++ 0x7c, 0xce, 0xab, 0x9f, 0xc3, 0x3e, 0xf2, 0x55, 0xcb, 0x82, 0xaf, 0xc4, ++ 0x51, 0xc9, 0x4d, 0xcf, 0x4b, 0x33, 0x9e, 0x54, 0xa9, 0xe9, 0x0f, 0xf5, ++ 0x48, 0xf7, 0x1b, 0xd5, 0x2d, 0xcd, 0xa8, 0x43, 0xf7, 0xa8, 0xae, 0x7b, ++ 0x4f, 0xf7, 0xa2, 0x6e, 0x9c, 0xee, 0x3d, 0xcb, 0x7d, 0x98, 0x71, 0x69, ++ 0xa1, 0xf7, 0x83, 0x8e, 0x5d, 0x45, 0x6a, 0x1d, 0x4a, 0xd5, 0xa3, 0xcc, ++ 0xa4, 0x87, 0xba, 0x77, 0xb1, 0x39, 0x01, 0x73, 0xea, 0x16, 0x9a, 0x13, ++ 0x3c, 0xc6, 0xbc, 0x9d, 0xda, 0x4f, 0x26, 0x1f, 0x3c, 0x6e, 0x3f, 0xd9, ++ 0xd9, 0x60, 0xbe, 0xaf, 0x46, 0x4c, 0x8e, 0xe3, 0x9e, 0x16, 0xee, 0xdf, ++ 0xbb, 0x39, 0xcf, 0xaf, 0x7b, 0x03, 0x74, 0x6f, 0xc7, 0x2b, 0x64, 0xaf, ++ 0x08, 0xe5, 0xc1, 0xbe, 0x8e, 0xed, 0xf8, 0xde, 0xe1, 0xc3, 0x7e, 0xa9, ++ 0x0f, 0xbf, 0xa3, 0xb4, 0xb8, 0x35, 0xe2, 0x2f, 0xf5, 0x81, 0x86, 0xb8, ++ 0x3e, 0x4c, 0x1a, 0xef, 0x09, 0xd0, 0x51, 0x57, 0xb6, 0xf7, 0x04, 0xde, ++ 0x65, 0x17, 0x5d, 0xa8, 0x1f, 0xa2, 0x06, 0x73, 0x74, 0x53, 0x95, 0x46, ++ 0xdf, 0x5b, 0x6b, 0xd0, 0xa7, 0x51, 0x9f, 0x33, 0xed, 0x2a, 0x43, 0xbc, ++ 0x96, 0x26, 0xdf, 0x1d, 0xe6, 0xf7, 0x89, 0x16, 0x49, 0x18, 0xf3, 0x7f, ++ 0xaa, 0x1e, 0xc8, 0x33, 0x29, 0x9f, 0x96, 0xfa, 0x9c, 0xfd, 0x28, 0xef, ++ 0x12, 0x07, 0xcf, 0x6d, 0x77, 0xf9, 0x77, 0x82, 0x42, 0x71, 0x69, 0x1c, ++ 0x38, 0x4c, 0x8e, 0x5b, 0xe5, 0xb1, 0xd4, 0x43, 0xdd, 0x03, 0xbb, 0x94, ++ 0x9d, 0xc9, 0x7b, 0xa1, 0xd7, 0x5e, 0xd6, 0xff, 0x06, 0xfd, 0x9e, 0x11, ++ 0x62, 0x7b, 0xa5, 0x5c, 0xec, 0x6f, 0xa5, 0xf7, 0x53, 0x8e, 0x88, 0x19, ++ 0xeb, 0xd4, 0x77, 0x4d, 0x0b, 0xe9, 0x55, 0xc0, 0xfd, 0x3d, 0x64, 0x9a, ++ 0x43, 0xc0, 0x1f, 0xac, 0x03, 0x1d, 0xa9, 0x53, 0x7e, 0x53, 0xfe, 0x55, ++ 0xfe, 0x84, 0xdf, 0x43, 0xf5, 0xc4, 0xd6, 0xd8, 0x51, 0x4f, 0x09, 0x5f, ++ 0xd7, 0x31, 0xab, 0xfa, 0x3d, 0xce, 0xef, 0x0c, 0x4b, 0xfe, 0x77, 0xc4, ++ 0x77, 0x61, 0x34, 0xd8, 0x9f, 0x99, 0x26, 0xe7, 0x7c, 0xc1, 0x7f, 0xe6, ++ 0xf7, 0x82, 0x43, 0x5c, 0xcc, 0xe1, 0xed, 0x06, 0x35, 0xff, 0x66, 0x7b, ++ 0xf7, 0x48, 0x3b, 0xba, 0x1f, 0xa4, 0xcf, 0xd3, 0xc9, 0x79, 0x58, 0xd9, ++ 0x2b, 0xcf, 0xd5, 0x71, 0x1c, 0x7b, 0x44, 0xd3, 0x16, 0xfc, 0xce, 0xe1, ++ 0x77, 0x23, 0x6f, 0xfc, 0x6e, 0xab, 0xf7, 0xa9, 0x1e, 0x47, 0xb9, 0x54, ++ 0x30, 0x96, 0x16, 0xe4, 0x92, 0x7d, 0x27, 0x2e, 0x7f, 0x43, 0x6c, 0x1f, ++ 0x25, 0xf2, 0xb0, 0x5f, 0xd4, 0x84, 0x6b, 0x9c, 0x14, 0xf7, 0x0e, 0x71, ++ 0x14, 0x79, 0xf1, 0xe1, 0x08, 0xe8, 0x07, 0xe2, 0x65, 0xc8, 0x29, 0x18, ++ 0xa0, 0xbe, 0xea, 0x29, 0x02, 0xcc, 0xf1, 0x04, 0xc7, 0x7b, 0xb1, 0x9d, ++ 0x7e, 0x87, 0x5d, 0x10, 0x3e, 0xfe, 0x9d, 0x8c, 0xf3, 0x17, 0x71, 0xed, ++ 0x34, 0xf9, 0xff, 0x51, 0xe3, 0x1c, 0xfd, 0x33, 0xc1, 0x7e, 0xe7, 0x78, ++ 0xf7, 0xa4, 0xc7, 0xbb, 0xc2, 0xa9, 0xd8, 0x6e, 0x19, 0xdf, 0xeb, 0x33, ++ 0xe3, 0x5b, 0xe9, 0x97, 0xda, 0x3f, 0x33, 0xe5, 0xe3, 0x1d, 0x75, 0xe9, ++ 0x89, 0xc5, 0x37, 0xe8, 0xd6, 0x4a, 0x79, 0x7f, 0x51, 0xc6, 0xbc, 0x9c, ++ 0x9e, 0x7f, 0xa8, 0x77, 0xd5, 0x7a, 0x3c, 0xfc, 0x07, 0xd7, 0x0d, 0x36, ++ 0x4f, 0xf0, 0x16, 0x00, 0x00, 0x00 }; + + static u8 bnx2_TPAT_b09FwText[] = { +- 0xbd, 0x58, 0x5d, 0x6c, 0x1c, 0x57, 0x15, 0x3e, 0x73, 0xe7, 0xee, 0xee, +- 0x78, 0xb1, 0xe3, 0x71, 0x3b, 0xa4, 0xdb, 0x62, 0xc8, 0x8c, 0x7d, 0xfd, +- 0x03, 0xb6, 0xc2, 0x94, 0x6e, 0xdb, 0xad, 0x18, 0x45, 0xc3, 0xec, 0xda, +- 0xb1, 0xa2, 0x3c, 0xb8, 0x52, 0xa4, 0x46, 0x6a, 0x04, 0x66, 0x1d, 0x93, +- 0x3e, 0xa6, 0x88, 0x07, 0xa4, 0x3e, 0x64, 0x59, 0x3b, 0xa9, 0x1f, 0x96, +- 0x2c, 0xb8, 0xc8, 0x7e, 0x41, 0x28, 0x72, 0x6a, 0xbb, 0x48, 0x8b, 0x37, +- 0x11, 0x48, 0x3c, 0x45, 0x8d, 0x1c, 0x14, 0x55, 0xea, 0x0b, 0x0f, 0xfc, +- 0x3d, 0x46, 0x6a, 0x45, 0xfb, 0x50, 0x90, 0x55, 0xa9, 0xa8, 0x82, 0xe0, +- 0xcb, 0x77, 0x66, 0x67, 0x9c, 0x4d, 0xec, 0x08, 0x9e, 0xb0, 0xb4, 0xba, +- 0x33, 0x73, 0xef, 0x39, 0xf7, 0xdc, 0x73, 0xbe, 0xef, 0x9c, 0x73, 0x3d, +- 0x64, 0x50, 0x9e, 0x92, 0xbf, 0x3e, 0xfc, 0x8a, 0xdf, 0xbd, 0xf8, 0x83, +- 0x67, 0x8f, 0xbf, 0x70, 0x1c, 0x8f, 0xcf, 0x1b, 0xfd, 0x59, 0x49, 0xff, +- 0xc7, 0x3f, 0x93, 0xc8, 0x4e, 0xed, 0xe0, 0x1f, 0x59, 0x22, 0xb8, 0xfd, +- 0x54, 0xa4, 0xc8, 0x32, 0x83, 0xdf, 0x7c, 0x6d, 0x5e, 0x11, 0x85, 0xad, +- 0x09, 0xb7, 0x4c, 0xff, 0xd6, 0x35, 0x47, 0x12, 0x7f, 0xff, 0x72, 0x70, +- 0xff, 0xeb, 0xb7, 0x5e, 0xf4, 0x76, 0xaf, 0x99, 0x64, 0xd9, 0xc1, 0xb2, +- 0xb4, 0x47, 0xc9, 0x1a, 0x84, 0xcc, 0xcf, 0xc7, 0xbe, 0x2d, 0xe8, 0x48, +- 0xaa, 0xab, 0xa6, 0x85, 0xba, 0xa7, 0x6f, 0x8d, 0x29, 0xbb, 0x8e, 0x0d, +- 0x6e, 0xb4, 0x5d, 0x8a, 0xda, 0x05, 0x7a, 0xb7, 0xed, 0xd0, 0xcd, 0xb6, +- 0xa4, 0x85, 0xb7, 0x2e, 0xd1, 0x92, 0xef, 0x15, 0x2a, 0xa6, 0x45, 0x22, +- 0xf0, 0x0a, 0x55, 0x72, 0x69, 0xc3, 0xf7, 0x6a, 0x73, 0xe6, 0x80, 0x61, +- 0x05, 0x16, 0xbd, 0x31, 0x26, 0xe8, 0x9a, 0x73, 0x8e, 0xbe, 0xa7, 0xce, +- 0xe2, 0x27, 0x49, 0xac, 0x48, 0xa3, 0xbc, 0x26, 0x49, 0xae, 0xf4, 0xd3, +- 0x49, 0x5f, 0xeb, 0x79, 0x3f, 0x84, 0xfc, 0xf0, 0xf8, 0x05, 0xea, 0xa1, +- 0x9a, 0xed, 0xcd, 0x10, 0x65, 0x78, 0x0d, 0x45, 0x7e, 0x86, 0x42, 0xbb, +- 0x73, 0xae, 0x6b, 0xf1, 0x78, 0x5f, 0x6f, 0x40, 0xbe, 0x47, 0xa5, 0xf3, +- 0x4f, 0x24, 0xf3, 0x76, 0x32, 0x2f, 0x48, 0xac, 0x7a, 0xee, 0x16, 0x8d, +- 0x84, 0xd2, 0xd8, 0xd3, 0x91, 0x3a, 0x6a, 0x47, 0x5b, 0x92, 0xcc, 0x15, +- 0xb6, 0x5f, 0xd9, 0x65, 0xd2, 0x90, 0x31, 0x59, 0x46, 0x8a, 0xe0, 0xfb, +- 0x88, 0xdb, 0x48, 0x28, 0x0c, 0xa2, 0x9d, 0x46, 0xc1, 0x8e, 0xda, 0x3f, +- 0x34, 0xa2, 0xe6, 0x9e, 0x0e, 0x65, 0x9e, 0x84, 0x0a, 0x8d, 0x68, 0x8b, +- 0x75, 0xf5, 0x90, 0x54, 0x39, 0xc8, 0x0c, 0xdb, 0x82, 0x78, 0x8c, 0x92, +- 0xef, 0xac, 0xbb, 0x82, 0xe7, 0x69, 0x23, 0xdc, 0x92, 0x46, 0xb4, 0x36, +- 0x83, 0x67, 0x0b, 0xf2, 0xf0, 0x8b, 0x6f, 0x50, 0x38, 0x6b, 0x40, 0x8e, +- 0xcf, 0x69, 0xe3, 0x5d, 0x50, 0xe8, 0xd8, 0xb4, 0x58, 0xf4, 0x0a, 0x35, +- 0x3a, 0x65, 0x94, 0xb7, 0x0e, 0x04, 0xcd, 0x9e, 0x69, 0x1f, 0xfc, 0xc6, +- 0xb6, 0x7c, 0x4b, 0x6a, 0x2d, 0x9e, 0xcd, 0x25, 0x67, 0x64, 0x7d, 0x61, +- 0xc7, 0x7e, 0x87, 0xdf, 0x61, 0x73, 0x13, 0xb6, 0xb7, 0xb2, 0xb0, 0x47, +- 0x6b, 0xde, 0x27, 0x52, 0x65, 0xd8, 0x19, 0xe2, 0xe7, 0x2d, 0x57, 0x01, +- 0x85, 0xa1, 0xd5, 0x3e, 0x72, 0x07, 0xb4, 0xae, 0xf8, 0x9e, 0xbd, 0x45, +- 0x01, 0x2d, 0x36, 0x07, 0xed, 0xa9, 0x66, 0x1d, 0xf3, 0x35, 0x5e, 0x03, +- 0x7f, 0x10, 0x4d, 0xb5, 0xb4, 0xde, 0xf4, 0x7f, 0x9b, 0xa1, 0x23, 0x62, +- 0x32, 0x43, 0x9e, 0x1b, 0xe2, 0xdb, 0xd0, 0xe6, 0xa3, 0x3e, 0x3b, 0x96, +- 0xd8, 0xc0, 0x7e, 0xc7, 0x3e, 0xfe, 0x97, 0x92, 0xf7, 0x5e, 0x3b, 0x5a, +- 0x4b, 0xfd, 0x1c, 0xdb, 0x0d, 0xbf, 0xfa, 0x14, 0x15, 0x61, 0xff, 0x63, +- 0xcf, 0x94, 0xca, 0xb1, 0x2d, 0x6c, 0x37, 0xd6, 0xab, 0x07, 0x36, 0xbd, +- 0x7a, 0xc0, 0x26, 0xb6, 0x47, 0x90, 0x5c, 0xb5, 0x68, 0x49, 0x7d, 0x64, +- 0xd0, 0x11, 0xad, 0x97, 0x7c, 0x69, 0x54, 0xd6, 0x3e, 0x4b, 0x9e, 0x81, +- 0xc3, 0x26, 0x70, 0xd8, 0x04, 0x2e, 0x9b, 0x64, 0x8b, 0xc0, 0xa5, 0x5b, +- 0x63, 0x16, 0xdd, 0x33, 0x11, 0xcf, 0x36, 0xcf, 0xe7, 0xa8, 0xee, 0x2b, +- 0xba, 0xdc, 0x64, 0xcf, 0xe4, 0x68, 0x51, 0x7d, 0xae, 0xcf, 0xc3, 0x1f, +- 0x6f, 0x93, 0x3e, 0x16, 0x01, 0xb3, 0x11, 0xdc, 0xf9, 0x86, 0x1a, 0xa7, +- 0xcb, 0x6d, 0x45, 0xf5, 0x36, 0xcb, 0x2d, 0x51, 0x47, 0xae, 0x1f, 0x72, +- 0x93, 0x90, 0x2b, 0xd2, 0x95, 0x58, 0xb6, 0x1f, 0xb2, 0xbb, 0x89, 0xec, +- 0x44, 0x61, 0x9a, 0x7c, 0xc8, 0x0c, 0xbb, 0xd3, 0xc0, 0xdc, 0x9c, 0x33, +- 0x09, 0xd9, 0x49, 0x5a, 0xc2, 0xaf, 0xde, 0xa4, 0x9a, 0x2c, 0xb2, 0x5e, +- 0xaf, 0x70, 0x9e, 0x7d, 0x1e, 0xeb, 0xac, 0x41, 0xa7, 0x83, 0x39, 0x0b, +- 0x7a, 0x24, 0xc6, 0x0f, 0x75, 0xbd, 0x09, 0x6c, 0x3b, 0xfc, 0xfc, 0xae, +- 0x16, 0x01, 0xfc, 0x50, 0x54, 0x6e, 0x9d, 0xf8, 0x3d, 0x4b, 0x65, 0xc4, +- 0x52, 0xa8, 0x7e, 0xaa, 0xda, 0x86, 0x21, 0x02, 0x93, 0xaa, 0xf0, 0x42, +- 0x38, 0x2b, 0xe3, 0x6f, 0x73, 0xb6, 0x01, 0x8e, 0x1d, 0x17, 0x9d, 0x9c, +- 0x93, 0xc1, 0x1a, 0xc4, 0x5f, 0xf5, 0x52, 0xd5, 0x19, 0xc0, 0x5a, 0x10, +- 0x2d, 0x3f, 0x02, 0x8e, 0x0e, 0x60, 0x0d, 0x8f, 0x1c, 0x07, 0xac, 0x57, +- 0xbc, 0xbe, 0x17, 0x36, 0xa6, 0xdf, 0x7a, 0xa9, 0xf6, 0x50, 0x7c, 0xd8, +- 0xc6, 0x38, 0x2e, 0xd8, 0x5f, 0x26, 0xb1, 0xed, 0x8e, 0x57, 0x3a, 0x6f, +- 0x63, 0x7e, 0xe7, 0xab, 0x82, 0x76, 0xf5, 0x75, 0x15, 0x15, 0xf0, 0xe9, +- 0xf3, 0x8a, 0x0a, 0x07, 0xcc, 0x18, 0x4b, 0x29, 0xa6, 0x78, 0xe4, 0x7c, +- 0x43, 0x85, 0x79, 0x65, 0x98, 0x4b, 0x93, 0x4f, 0x52, 0xcd, 0xf1, 0xfc, +- 0x32, 0x15, 0x68, 0xa9, 0x39, 0x01, 0xdf, 0xf5, 0xe3, 0xdc, 0x9e, 0x4f, +- 0x34, 0x8c, 0xe7, 0xf0, 0x69, 0xc8, 0x20, 0x5f, 0xd4, 0xa0, 0x8b, 0xc7, +- 0x41, 0xe8, 0xf7, 0x60, 0x23, 0xfc, 0xa1, 0x26, 0xec, 0x29, 0xf8, 0x23, +- 0x74, 0x78, 0x8e, 0xf3, 0x98, 0xf3, 0x4c, 0xa4, 0x3c, 0xbf, 0x1a, 0xdb, +- 0xe2, 0xd9, 0xb7, 0x89, 0xf3, 0x51, 0x9a, 0x83, 0x38, 0x27, 0x59, 0x73, +- 0x32, 0xa0, 0xd9, 0x7a, 0xe3, 0x92, 0x36, 0x15, 0xcd, 0x65, 0x03, 0xc6, +- 0x6e, 0x6f, 0x09, 0x58, 0x9c, 0xad, 0xb7, 0x06, 0x4f, 0xef, 0x34, 0xa8, +- 0xf6, 0x4c, 0x20, 0x8e, 0x0a, 0xec, 0x1f, 0xf9, 0xcc, 0x29, 0xec, 0xd5, +- 0x1e, 0x3c, 0x7d, 0xa7, 0x71, 0x0c, 0xbe, 0xa2, 0xfb, 0xf0, 0x3f, 0xf6, +- 0xdf, 0x79, 0xda, 0x84, 0x9d, 0x1c, 0x33, 0x70, 0x2b, 0x7c, 0x75, 0xcc, +- 0x00, 0x96, 0xf1, 0x0c, 0x6c, 0xd4, 0xda, 0x83, 0x73, 0x22, 0xa8, 0x51, +- 0xd8, 0x5e, 0xc2, 0xcf, 0xa2, 0xa9, 0x86, 0x65, 0xdd, 0x81, 0x4e, 0x51, +- 0xf4, 0xdc, 0xc8, 0xdc, 0x65, 0xae, 0xf0, 0x39, 0x58, 0x97, 0x65, 0x04, +- 0xae, 0x1c, 0x6a, 0xf5, 0xbc, 0x22, 0x82, 0x00, 0x98, 0x90, 0x88, 0x4d, +- 0x11, 0x58, 0xe1, 0x38, 0x5c, 0x45, 0x1c, 0x80, 0x03, 0xd8, 0x0c, 0xff, +- 0xd7, 0x44, 0x70, 0x91, 0x2a, 0x45, 0xa2, 0xc5, 0x06, 0x61, 0x3f, 0xec, +- 0x55, 0xc2, 0x0f, 0x78, 0x0e, 0xed, 0x12, 0x6c, 0xf0, 0xc2, 0x1a, 0x79, +- 0xfe, 0x1c, 0xbc, 0x9e, 0xfb, 0x31, 0x59, 0x99, 0xe0, 0x9c, 0xdc, 0x68, +- 0x90, 0x25, 0x83, 0xb3, 0x72, 0xa9, 0x31, 0xec, 0xff, 0x15, 0xbe, 0x26, +- 0xf2, 0xc6, 0x37, 0x69, 0xc2, 0xdf, 0x04, 0x6f, 0xeb, 0xf8, 0x5d, 0x21, +- 0xde, 0xfb, 0x9c, 0x1c, 0x69, 0xf1, 0x78, 0x56, 0xaa, 0x56, 0xb7, 0xde, +- 0xbf, 0x69, 0xf6, 0xfb, 0x3d, 0x2a, 0xd1, 0x9b, 0xc9, 0xde, 0xf0, 0x0d, +- 0x9d, 0x6c, 0x94, 0x80, 0xef, 0x03, 0xfa, 0x4b, 0xa9, 0xfe, 0xad, 0x58, +- 0x37, 0x63, 0x77, 0xc2, 0xdf, 0x3a, 0x74, 0x8f, 0xa3, 0x69, 0x7e, 0x42, +- 0x1e, 0xec, 0xe4, 0xeb, 0xc5, 0x66, 0x0e, 0x9c, 0xd0, 0xba, 0xaa, 0x7e, +- 0x8f, 0xf3, 0xe6, 0x81, 0x5f, 0x1b, 0x3f, 0xc4, 0x72, 0x96, 0xe7, 0x0c, +- 0xaa, 0xa2, 0x0e, 0xd5, 0xdb, 0xfc, 0xcc, 0x73, 0x9c, 0xcf, 0x72, 0x18, +- 0xff, 0x8c, 0xb5, 0x1f, 0xea, 0x5a, 0x9b, 0xb9, 0xc6, 0xbe, 0x02, 0x47, +- 0xda, 0x96, 0x51, 0x6e, 0x92, 0x51, 0x69, 0x92, 0x5b, 0xf5, 0x65, 0x1c, +- 0x97, 0xd0, 0xb6, 0xe1, 0x53, 0xc6, 0xc3, 0xa4, 0x8c, 0x1a, 0x46, 0x5c, +- 0xc3, 0x0c, 0x3c, 0x0f, 0xb5, 0x7e, 0x9d, 0x01, 0x27, 0x42, 0xf8, 0x5f, +- 0x2c, 0x20, 0x47, 0x5e, 0x73, 0xa8, 0x5f, 0xa8, 0x39, 0x51, 0x77, 0xa8, +- 0x4f, 0x28, 0xb6, 0xed, 0x3d, 0x01, 0xdb, 0x78, 0x3e, 0xac, 0xfa, 0xbf, +- 0xc2, 0x9e, 0x41, 0xcc, 0xc7, 0x4a, 0x23, 0xcd, 0xfb, 0xd0, 0xa9, 0x38, +- 0x67, 0x58, 0x49, 0xfe, 0x8f, 0x92, 0xdc, 0x2e, 0x81, 0x5b, 0xad, 0x5f, +- 0x46, 0x5e, 0xaf, 0xc7, 0xb8, 0xf1, 0x6a, 0xae, 0xd8, 0xd3, 0xc3, 0xa3, +- 0xcc, 0x51, 0xad, 0x2f, 0xfa, 0xd3, 0x58, 0x2b, 0x4d, 0xca, 0xcf, 0x20, +- 0xb7, 0x73, 0x3d, 0x60, 0xdb, 0x02, 0xd8, 0xd6, 0xd7, 0xc9, 0xfb, 0xa8, +- 0x09, 0xf5, 0xb8, 0x06, 0xf4, 0x90, 0xa9, 0x0c, 0xfc, 0x3c, 0x77, 0x8e, +- 0xf8, 0x3b, 0xf5, 0x08, 0xbc, 0x57, 0xc1, 0xeb, 0xa5, 0xe2, 0x29, 0xa3, +- 0xb2, 0x75, 0xcc, 0x4c, 0xfa, 0x08, 0xd8, 0x0d, 0x5e, 0x3b, 0x2c, 0x97, +- 0x85, 0x5c, 0x1f, 0x64, 0xbe, 0x82, 0xb9, 0x0c, 0xc6, 0x6e, 0x3d, 0x71, +- 0x2d, 0xc1, 0x5e, 0x2e, 0xf6, 0x9a, 0x21, 0x19, 0xe4, 0x51, 0xaf, 0x47, +- 0xdc, 0x0a, 0x3d, 0x97, 0xd4, 0x6d, 0xe6, 0xf2, 0x89, 0x2e, 0x2e, 0xbb, +- 0x64, 0xc6, 0x9c, 0x78, 0x29, 0xc9, 0x41, 0x9c, 0xc7, 0x5f, 0x48, 0xe6, +- 0x1d, 0xe4, 0xe3, 0xe7, 0x92, 0xba, 0x62, 0xe1, 0x39, 0xa0, 0xe5, 0x38, +- 0x37, 0x67, 0x39, 0x37, 0x17, 0x90, 0x9b, 0x4b, 0xe0, 0xa7, 0xff, 0x31, +- 0x19, 0xc8, 0x4d, 0x44, 0xbf, 0x6b, 0x48, 0xe4, 0x21, 0x13, 0xf2, 0xdc, +- 0x1b, 0xcc, 0xc1, 0x36, 0xcf, 0xfe, 0x18, 0x67, 0x0a, 0xcf, 0x70, 0xde, +- 0xd4, 0x3a, 0x13, 0x28, 0xf7, 0x32, 0x8d, 0x16, 0x2e, 0x23, 0x4f, 0x9a, +- 0x34, 0x81, 0xdd, 0x78, 0xdf, 0xb4, 0x96, 0xa7, 0x3d, 0x05, 0xff, 0xbd, +- 0x6f, 0x90, 0xe2, 0xfa, 0xfb, 0x1d, 0xe8, 0x18, 0x71, 0xa7, 0xc0, 0xfb, +- 0xc5, 0xd2, 0x7f, 0x93, 0xf9, 0x43, 0x22, 0x83, 0xba, 0x56, 0xe4, 0x7d, +- 0x89, 0x2a, 0x2d, 0xf6, 0x83, 0xdf, 0x85, 0x07, 0x1f, 0x78, 0x20, 0xaa, +- 0x36, 0xc1, 0x3f, 0xc4, 0x38, 0xc6, 0x1a, 0xd6, 0x8b, 0x22, 0x72, 0xaa, +- 0xc3, 0xb8, 0x66, 0xbc, 0x9f, 0x49, 0xf0, 0x3e, 0x0b, 0xbc, 0x7b, 0xe3, +- 0x37, 0xc0, 0xa3, 0x1b, 0x0f, 0xf1, 0xe8, 0x4c, 0x82, 0xf1, 0x59, 0x60, +- 0xfc, 0x97, 0xc0, 0x96, 0x85, 0x9a, 0x0e, 0xdc, 0x36, 0xc8, 0x88, 0x50, +- 0x1b, 0x80, 0x83, 0x44, 0xcf, 0xe9, 0x44, 0xcf, 0xcc, 0x63, 0xf4, 0x9c, +- 0x4e, 0xf4, 0xcc, 0x74, 0xeb, 0x81, 0x5c, 0x25, 0x91, 0x0b, 0x1f, 0x23, +- 0x57, 0x49, 0xe4, 0xc2, 0x2e, 0x39, 0x0b, 0x67, 0xe2, 0x73, 0x71, 0x1e, +- 0xdb, 0x45, 0x2c, 0x7c, 0x8a, 0xb1, 0x62, 0x87, 0x18, 0xef, 0x61, 0x04, +- 0x66, 0x9a, 0x37, 0xb1, 0x96, 0xfd, 0x90, 0x61, 0x0e, 0x3c, 0xe2, 0xbb, +- 0x3d, 0xf8, 0x6e, 0x1f, 0xef, 0xf8, 0xfb, 0x66, 0x82, 0x15, 0xae, 0x45, +- 0x5e, 0x2d, 0x7c, 0x68, 0x6d, 0x46, 0xb0, 0x9f, 0xc5, 0xd5, 0xc3, 0x62, +- 0x60, 0x61, 0x0e, 0x35, 0xa7, 0x69, 0x52, 0x59, 0x32, 0x57, 0x5f, 0x91, +- 0x31, 0x76, 0xb7, 0xb1, 0x7e, 0xbb, 0xc3, 0xab, 0x99, 0x46, 0x8e, 0x68, +- 0xbd, 0x97, 0x16, 0x50, 0x4f, 0xce, 0x03, 0x4b, 0xd7, 0x7d, 0xb0, 0x90, +- 0x86, 0x81, 0x0b, 0x0d, 0x5c, 0x7b, 0x71, 0x6c, 0x23, 0xb5, 0x08, 0x66, +- 0xfc, 0x88, 0x76, 0x26, 0xf3, 0x94, 0xd9, 0xec, 0xd4, 0x43, 0xb9, 0xde, +- 0xbd, 0x8f, 0x8b, 0x7d, 0x02, 0xd4, 0xe0, 0x3f, 0xa2, 0x17, 0x70, 0x48, +- 0x8e, 0x22, 0x97, 0x36, 0x39, 0x27, 0x80, 0xa3, 0x9b, 0x5c, 0xeb, 0x39, +- 0xe7, 0x5a, 0xc0, 0x62, 0x9a, 0x7f, 0x72, 0xe8, 0x5b, 0x3e, 0x41, 0xed, +- 0x10, 0x34, 0x5f, 0xd4, 0x7a, 0xca, 0xff, 0x04, 0xb8, 0xc2, 0xb7, 0x75, +- 0x9e, 0xdb, 0xc5, 0x77, 0xfe, 0x66, 0x51, 0x76, 0xf5, 0x49, 0xec, 0x89, +- 0xfd, 0xce, 0xf0, 0xfa, 0x1c, 0x7a, 0x1a, 0xce, 0xf3, 0x18, 0xd7, 0xf9, +- 0xdd, 0x48, 0x7c, 0x6a, 0x62, 0xfc, 0x02, 0x46, 0x3e, 0x4f, 0x0f, 0xce, +- 0xa7, 0xf5, 0x5d, 0x9f, 0x9f, 0xb5, 0x96, 0x41, 0x2f, 0x95, 0x1b, 0x0a, +- 0xf5, 0x7d, 0xa4, 0xb0, 0x00, 0x9e, 0x95, 0x5b, 0xe9, 0x3c, 0xcf, 0xd9, +- 0x5d, 0x73, 0x78, 0x6e, 0xf1, 0x77, 0x41, 0x3b, 0x6a, 0x11, 0x75, 0x11, +- 0xfd, 0xd3, 0x3a, 0xf7, 0x61, 0xdc, 0x53, 0xc5, 0xf5, 0x72, 0x9c, 0x7b, +- 0xb0, 0x77, 0x90, 0xff, 0xd7, 0xc1, 0x29, 0xf0, 0xfb, 0x29, 0x41, 0x4f, +- 0x50, 0xd9, 0x49, 0xcf, 0xa3, 0x35, 0x38, 0x5b, 0x30, 0x0d, 0xe6, 0xe2, +- 0xb0, 0x3d, 0x4d, 0xdc, 0x6b, 0x8d, 0x84, 0x55, 0x96, 0x69, 0x21, 0x1f, +- 0xac, 0x68, 0xaa, 0x76, 0xf4, 0xd8, 0xb3, 0xc8, 0xd1, 0xd1, 0x4f, 0xb8, +- 0xb6, 0xb1, 0x6f, 0x4f, 0xc0, 0x1e, 0xf4, 0x05, 0xeb, 0x92, 0xde, 0x6e, +- 0xb0, 0x9e, 0x3c, 0x99, 0xe8, 0x11, 0x97, 0xfd, 0x54, 0xcf, 0x9f, 0xa0, +- 0x87, 0x1c, 0x41, 0xdc, 0xff, 0x4a, 0xe8, 0x62, 0x1f, 0x64, 0xd0, 0x8f, +- 0x8f, 0xd3, 0xbc, 0x5a, 0x8c, 0x6b, 0xf1, 0x79, 0xd4, 0xde, 0xa8, 0x98, +- 0x85, 0xef, 0x72, 0xb1, 0x9e, 0x7a, 0xf3, 0x5f, 0x9a, 0xf3, 0x0f, 0xea, +- 0x24, 0xf4, 0xe3, 0xbd, 0x8d, 0xb9, 0x95, 0x80, 0xde, 0x6c, 0xc6, 0xb5, +- 0xdb, 0xbe, 0x88, 0x9e, 0xbf, 0xd2, 0xf8, 0x47, 0xda, 0xcb, 0x84, 0xc0, +- 0x71, 0xe1, 0x02, 0x7c, 0x23, 0xb7, 0x7b, 0xe9, 0x35, 0xf4, 0xa8, 0x99, +- 0x15, 0xd4, 0x65, 0xf8, 0x4d, 0x5c, 0xad, 0x8d, 0x73, 0x9f, 0x79, 0x03, +- 0x5c, 0x9f, 0x2f, 0x2a, 0xdf, 0x34, 0x46, 0x69, 0xf9, 0x67, 0x5c, 0x67, +- 0xe2, 0x7a, 0x0d, 0xfc, 0xb8, 0x74, 0xa5, 0xa5, 0x68, 0xb9, 0x65, 0xc3, +- 0x2e, 0xfb, 0x41, 0x2f, 0xae, 0x38, 0x1f, 0x57, 0xf0, 0x8b, 0xf3, 0x2d, +- 0xce, 0x04, 0x3e, 0x04, 0xec, 0x0f, 0xee, 0xbd, 0x39, 0x66, 0x9c, 0xff, +- 0x4e, 0xe1, 0x99, 0xcf, 0xca, 0xbd, 0x32, 0xfb, 0x81, 0x7b, 0xe2, 0xee, +- 0xfe, 0x9d, 0x73, 0x23, 0x74, 0x6e, 0x33, 0x87, 0xb8, 0x47, 0xa9, 0xc8, +- 0xf9, 0x86, 0x1d, 0xf3, 0xaa, 0xde, 0xee, 0xf8, 0x3b, 0xf2, 0x59, 0xa7, +- 0x57, 0x0a, 0xe9, 0xce, 0x8b, 0x22, 0xee, 0x3b, 0x42, 0xe4, 0x15, 0x3e, +- 0xcb, 0x04, 0xee, 0x27, 0x1e, 0x7c, 0xe7, 0xa1, 0x2f, 0xe9, 0xf0, 0x73, +- 0x38, 0xe1, 0xe7, 0x50, 0xeb, 0x44, 0x26, 0xed, 0xc7, 0x0e, 0x72, 0xee, +- 0x17, 0xe2, 0x7f, 0xe7, 0xdc, 0x46, 0xc2, 0xb9, 0x6c, 0x8c, 0x4d, 0xb1, +- 0xd2, 0x3d, 0xf7, 0x0e, 0xe6, 0x72, 0x5d, 0xf7, 0xa2, 0xc3, 0x62, 0x12, +- 0xf3, 0x03, 0x9c, 0xe4, 0x75, 0x88, 0xff, 0x4a, 0x2f, 0x99, 0x57, 0x99, +- 0x97, 0x29, 0x46, 0x5c, 0xe0, 0x31, 0xd5, 0xd1, 0x83, 0x3d, 0x70, 0xd7, +- 0x59, 0xcd, 0xc4, 0xf8, 0x37, 0x83, 0x74, 0x4d, 0x81, 0xa6, 0x1b, 0x9e, +- 0x7f, 0x87, 0xc7, 0x16, 0xcf, 0x4b, 0xca, 0xae, 0x58, 0xf4, 0xfa, 0x98, +- 0xe7, 0xba, 0xc2, 0xf3, 0x77, 0x60, 0xf7, 0x5d, 0xe5, 0x50, 0x66, 0x94, +- 0x39, 0xc9, 0x15, 0x2a, 0x0b, 0xdc, 0xe0, 0x0e, 0xd8, 0xd4, 0x97, 0xd0, +- 0x1f, 0xb9, 0x12, 0xb1, 0xfd, 0x29, 0x6c, 0xe1, 0x7c, 0x0b, 0xbb, 0xc6, +- 0xd7, 0x81, 0x83, 0x05, 0x7e, 0xdf, 0xc7, 0x18, 0xdf, 0x2d, 0x78, 0x7f, +- 0x07, 0x67, 0xb0, 0x28, 0xb7, 0xaa, 0x71, 0xf7, 0x7b, 0x20, 0x77, 0x25, +- 0xc1, 0x6b, 0x06, 0xdf, 0xe7, 0x63, 0xbc, 0x72, 0x1c, 0xd9, 0xe7, 0x5a, +- 0x7f, 0x80, 0x38, 0x96, 0xe9, 0x2f, 0x31, 0x8f, 0xef, 0xfa, 0x31, 0x7e, +- 0x61, 0x0f, 0x64, 0x5a, 0x9f, 0xca, 0x98, 0xe7, 0xe0, 0xc3, 0x65, 0x3f, +- 0xc6, 0xd7, 0xf8, 0x4d, 0x1c, 0xbb, 0x83, 0xfd, 0x6e, 0x3d, 0xc3, 0xf6, +- 0x49, 0x8a, 0x39, 0xe5, 0x2e, 0x72, 0x8f, 0xe9, 0x8f, 0x20, 0xdf, 0x62, +- 0x5d, 0x2b, 0xe5, 0x7d, 0x16, 0x7c, 0x67, 0x5f, 0x33, 0xf7, 0x07, 0x92, +- 0xe7, 0x2f, 0x22, 0xb6, 0x36, 0xfc, 0xd8, 0xe9, 0x05, 0xcc, 0x15, 0xb6, +- 0xad, 0x97, 0xd4, 0xd5, 0xd4, 0xae, 0x4f, 0x63, 0x7b, 0x1e, 0xd6, 0x89, +- 0xf9, 0xed, 0xc3, 0xe4, 0xec, 0x2e, 0xb9, 0xbf, 0x1f, 0x22, 0x87, 0xf9, +- 0x6d, 0x96, 0xc9, 0xef, 0xf7, 0x20, 0xe5, 0x7d, 0x3c, 0x87, 0xc0, 0x3b, +- 0xcb, 0x3e, 0x7a, 0xef, 0xec, 0xc6, 0x7e, 0x5a, 0xfb, 0x19, 0xdf, 0xbc, +- 0xa7, 0xe7, 0x72, 0xef, 0xde, 0xc1, 0x76, 0x1e, 0x79, 0x2f, 0xf6, 0x03, +- 0x72, 0xa6, 0x37, 0x3e, 0x47, 0x29, 0xfe, 0x1f, 0x60, 0x7c, 0x01, 0x76, +- 0x55, 0x68, 0xa2, 0xc4, 0xe3, 0xc9, 0x03, 0x18, 0xe7, 0xfb, 0x3a, 0xd7, +- 0xa6, 0x3c, 0xee, 0x61, 0x5c, 0xe7, 0xf9, 0x2e, 0xd6, 0xc9, 0x53, 0x95, +- 0x35, 0x7e, 0xff, 0x2c, 0x79, 0xe7, 0xbc, 0xcc, 0x7d, 0xd4, 0x0d, 0x9c, +- 0x9f, 0xeb, 0xd1, 0x18, 0xd5, 0x1d, 0xf8, 0xd5, 0x67, 0x1b, 0x2e, 0xd0, +- 0x83, 0x1e, 0xec, 0xb0, 0xba, 0xb2, 0x6a, 0x76, 0x71, 0xe5, 0xb0, 0x7e, +- 0x8c, 0xef, 0x27, 0x46, 0x79, 0xcd, 0x48, 0x7a, 0x78, 0xee, 0xbf, 0xf6, +- 0xb4, 0x19, 0xf7, 0x62, 0x9c, 0x17, 0xb8, 0x07, 0x7b, 0x0d, 0xfb, 0xf6, +- 0xc5, 0xef, 0xe1, 0x16, 0x8f, 0xec, 0x17, 0x8a, 0x79, 0xd1, 0xe1, 0x79, +- 0x6a, 0x77, 0x84, 0x75, 0xf0, 0x8f, 0x88, 0x52, 0x9b, 0xa8, 0xfa, 0x16, +- 0xd7, 0x54, 0x3b, 0xc9, 0xff, 0x17, 0x31, 0x3e, 0x9f, 0x60, 0x20, 0x3d, +- 0x4b, 0xec, 0x57, 0xec, 0xaf, 0xf5, 0x2c, 0x30, 0xf5, 0xba, 0x9f, 0xda, +- 0x0a, 0x6c, 0x7f, 0x23, 0xcd, 0x31, 0x88, 0x97, 0xda, 0xd3, 0x72, 0x34, +- 0x84, 0x2d, 0xfc, 0xff, 0x82, 0x0a, 0x7a, 0x3b, 0xb6, 0x65, 0xc6, 0x78, +- 0x79, 0xff, 0x7f, 0x04, 0x8f, 0xf6, 0x71, 0x1c, 0x3f, 0x8e, 0xef, 0x7e, +- 0xfc, 0xac, 0x1c, 0x7c, 0xff, 0x51, 0xc3, 0xb3, 0x07, 0x04, 0xe7, 0x23, +- 0xb2, 0xb2, 0x88, 0xc1, 0x5d, 0xc4, 0x28, 0x24, 0xaf, 0xf4, 0x41, 0xdc, +- 0x9b, 0x13, 0x38, 0x37, 0x11, 0xe2, 0x19, 0x1c, 0xc0, 0xd9, 0x46, 0x3d, +- 0xff, 0x3d, 0xe2, 0x38, 0x58, 0xb8, 0x6b, 0x74, 0x62, 0x37, 0x96, 0xc4, +- 0x6e, 0xb4, 0xf5, 0xf0, 0x99, 0x5d, 0xf1, 0x52, 0xf2, 0xce, 0x67, 0xe2, +- 0x5e, 0xc1, 0xe5, 0x1e, 0x09, 0x3e, 0x28, 0x19, 0x9d, 0x7b, 0x7b, 0x93, +- 0xef, 0x97, 0x35, 0xce, 0xe5, 0xdc, 0xcf, 0x81, 0x6b, 0xa8, 0x96, 0x23, +- 0xb8, 0x6b, 0x68, 0x5d, 0x2f, 0x31, 0x76, 0x27, 0xc6, 0xa7, 0x62, 0x0c, +- 0x8b, 0x41, 0x41, 0x29, 0xb7, 0xba, 0x9f, 0x31, 0x96, 0xf8, 0x9e, 0xc6, +- 0xef, 0x1d, 0x1d, 0x1b, 0xc0, 0x1d, 0x6e, 0x32, 0xb8, 0x1d, 0xb2, 0x7e, +- 0xa3, 0xd3, 0x13, 0xdb, 0x11, 0xf3, 0x1e, 0xb8, 0x7b, 0x1f, 0x76, 0x85, +- 0xe0, 0x6d, 0xe7, 0x6e, 0x37, 0x87, 0x9c, 0x72, 0x1b, 0xb1, 0xbd, 0xab, +- 0x3a, 0x75, 0x71, 0x83, 0xfb, 0xae, 0x16, 0xf2, 0x4d, 0x1e, 0xbd, 0xb2, +- 0x4a, 0xef, 0xa2, 0x16, 0x5d, 0xc3, 0x9a, 0xeb, 0x98, 0xbb, 0xd2, 0x4a, +- 0x71, 0x84, 0x1e, 0x0f, 0xd8, 0x9c, 0x57, 0xff, 0xd4, 0x55, 0xa7, 0x7b, +- 0x2d, 0xff, 0xfd, 0x07, 0x5d, 0xe7, 0x92, 0xbb, 0xa8, 0x13, 0x00, 0x00, +- 0x00 }; ++ 0xbd, 0x58, 0x5d, 0x6c, 0x1c, 0x57, 0x15, 0x3e, 0x73, 0xe7, 0xee, 0x7a, ++ 0x6d, 0x39, 0xf1, 0xb8, 0x99, 0x96, 0x4d, 0x63, 0xd4, 0x99, 0x78, 0xfc, ++ 0x43, 0x6d, 0x95, 0x69, 0x59, 0x15, 0x17, 0x56, 0x68, 0xba, 0xbb, 0x71, ++ 0xad, 0xaa, 0xaa, 0x5c, 0x29, 0x88, 0x4a, 0x8d, 0x90, 0x59, 0x37, 0x6d, ++ 0x79, 0x4b, 0x11, 0x0f, 0x48, 0x45, 0xca, 0xb2, 0x76, 0xd2, 0x08, 0x2d, ++ 0x99, 0xd6, 0x85, 0x44, 0x42, 0x7d, 0x88, 0x9c, 0x3a, 0xee, 0xc3, 0xca, ++ 0x9b, 0x8a, 0x07, 0x24, 0xa4, 0xa8, 0x55, 0x80, 0xc0, 0x1b, 0x7d, 0xa8, ++ 0xf8, 0x79, 0x22, 0x12, 0x0f, 0x54, 0x08, 0x90, 0x85, 0x04, 0x2a, 0xa5, ++ 0xe4, 0xf2, 0x7d, 0x77, 0x67, 0x92, 0xc5, 0x4d, 0x41, 0xe5, 0x81, 0x95, ++ 0x56, 0x77, 0xe6, 0xde, 0x73, 0xce, 0x3d, 0xf7, 0xfc, 0x7c, 0xe7, 0xdc, ++ 0x39, 0xec, 0xc8, 0x88, 0x64, 0xbf, 0x7d, 0xf8, 0x57, 0xbe, 0x72, 0xe2, ++ 0xeb, 0x0f, 0xdc, 0x57, 0xb9, 0x0f, 0x8f, 0x0f, 0x3a, 0x77, 0x6b, 0x2d, ++ 0xff, 0xc7, 0x9f, 0x2b, 0xe2, 0xe5, 0x7a, 0xf0, 0x2f, 0x25, 0x55, 0x4d, ++ 0x0e, 0xd6, 0x22, 0x29, 0xb9, 0xd5, 0xea, 0xfc, 0x6a, 0x24, 0x92, 0x74, ++ 0xe7, 0x82, 0xba, 0xfc, 0xd3, 0xb4, 0x7c, 0x2d, 0x9c, 0xff, 0x64, 0xf5, ++ 0x83, 0x4f, 0x5f, 0xf9, 0x6c, 0xb8, 0x7b, 0xc1, 0x95, 0x92, 0x57, 0x3d, ++ 0xa3, 0xbd, 0x69, 0x29, 0x4d, 0x80, 0xe7, 0xd5, 0x99, 0x6f, 0x17, 0x64, ++ 0x7f, 0x2e, 0xab, 0x65, 0x54, 0x74, 0xdd, 0x5c, 0x99, 0x89, 0xbc, 0x36, ++ 0x36, 0xb8, 0xdc, 0x0b, 0xa4, 0xd6, 0x2b, 0xcb, 0x9b, 0x3d, 0x5f, 0xde, ++ 0xe8, 0x69, 0x39, 0xfe, 0xca, 0x49, 0x59, 0x8f, 0xc3, 0x72, 0xc3, 0x2d, ++ 0x89, 0xaa, 0x86, 0xe5, 0xa6, 0x04, 0xb2, 0x15, 0x87, 0xad, 0x15, 0x77, ++ 0xdc, 0x29, 0x55, 0x4b, 0xf2, 0xc2, 0x8c, 0x92, 0x0b, 0xfe, 0x31, 0x79, ++ 0x26, 0x7a, 0x12, 0x7f, 0x2d, 0x6a, 0x43, 0x3b, 0xf5, 0xf3, 0x5a, 0xf4, ++ 0xc6, 0x98, 0x3c, 0x12, 0x1b, 0xb3, 0x1a, 0x27, 0xe0, 0x9f, 0x9c, 0x7d, ++ 0x56, 0x86, 0xa5, 0xe5, 0x85, 0x4b, 0x22, 0x05, 0xd2, 0x48, 0x2d, 0x2e, ++ 0x48, 0xe2, 0xf5, 0xcf, 0x75, 0xc1, 0x8e, 0x1f, 0x98, 0x2d, 0xf0, 0x0f, ++ 0x47, 0xf9, 0xfa, 0x1d, 0xd9, 0xba, 0x97, 0xad, 0x2b, 0x51, 0xe7, 0xc2, ++ 0x60, 0x5b, 0xa6, 0x12, 0xed, 0xdc, 0x30, 0xb5, 0xe8, 0x2e, 0xaf, 0xb6, ++ 0xad, 0xc5, 0xdd, 0xa0, 0xfe, 0x91, 0x57, 0x17, 0x03, 0x1e, 0x97, 0x3c, ++ 0x5a, 0x55, 0xbf, 0x06, 0xbf, 0x4d, 0x25, 0xca, 0x11, 0xb9, 0xda, 0x29, ++ 0x7b, 0xb5, 0xde, 0x37, 0x9c, 0x5a, 0x7a, 0xc3, 0x24, 0x7a, 0x44, 0x54, ++ 0x94, 0x38, 0xb5, 0x6d, 0xca, 0x1a, 0x16, 0x1d, 0x0d, 0x81, 0x67, 0xd2, ++ 0x53, 0xc2, 0xb1, 0x96, 0xcd, 0x53, 0x76, 0x03, 0xcf, 0x8b, 0x4e, 0xb2, ++ 0xad, 0x9d, 0xda, 0xf9, 0x25, 0x3c, 0x97, 0xc0, 0x0f, 0xbb, 0xc4, 0x8e, ++ 0x24, 0xcb, 0x0e, 0xf8, 0x78, 0x4e, 0x0f, 0xef, 0x4a, 0x12, 0xdf, 0x93, ++ 0xb5, 0x4a, 0x58, 0x6e, 0xc9, 0xa3, 0x4e, 0x7d, 0xfb, 0x43, 0x4e, 0xf3, ++ 0x96, 0x7a, 0x1f, 0x9e, 0xa3, 0x2e, 0x0f, 0x6b, 0x63, 0xd4, 0xfd, 0x43, ++ 0xd9, 0x19, 0x29, 0x2f, 0xe9, 0xeb, 0xef, 0xf3, 0x1d, 0x3a, 0xa7, 0xd0, ++ 0xbd, 0x5b, 0x84, 0x3e, 0xc6, 0x70, 0x9f, 0x5a, 0x54, 0x87, 0x9e, 0x09, ++ 0xfe, 0xe1, 0x99, 0x26, 0x42, 0xe1, 0xf0, 0xb9, 0x7d, 0x12, 0x8c, 0x1b, ++ 0xd3, 0x88, 0x43, 0x6f, 0x5b, 0x26, 0x64, 0x2d, 0x9d, 0xf0, 0x8e, 0xa4, ++ 0x6d, 0xac, 0xb7, 0x48, 0x03, 0x7b, 0x88, 0x1c, 0xe9, 0x1a, 0x73, 0x29, ++ 0x3e, 0x50, 0x94, 0xfd, 0x6a, 0xbe, 0x20, 0x61, 0x90, 0x60, 0xee, 0xf0, ++ 0xa5, 0xbd, 0x36, 0xbb, 0x27, 0xd3, 0x81, 0x76, 0xc7, 0x3e, 0xf1, 0xa1, ++ 0xec, 0x7d, 0xd4, 0xab, 0x9d, 0xcf, 0xed, 0x6c, 0xf5, 0x86, 0x5d, 0x63, ++ 0xa9, 0x55, 0xa0, 0xff, 0x47, 0x9e, 0x29, 0xe7, 0xa3, 0x2e, 0xd4, 0x1b, ++ 0xf4, 0xd1, 0x2d, 0x9d, 0x9e, 0xfa, 0x90, 0x4e, 0xd4, 0x47, 0x89, 0x3e, ++ 0x57, 0x92, 0xf5, 0xe8, 0x71, 0x25, 0xfb, 0x8d, 0x59, 0x8f, 0xb5, 0xd3, ++ 0x38, 0x7f, 0x2c, 0x7b, 0x46, 0x1c, 0xa6, 0x88, 0xc3, 0x14, 0x71, 0x99, ++ 0x8a, 0xa7, 0xaa, 0x81, 0x5c, 0x99, 0x29, 0xc9, 0x75, 0x17, 0xfe, 0xec, ++ 0xcd, 0x79, 0xaf, 0x21, 0xa6, 0x12, 0xcf, 0x11, 0x37, 0x4a, 0x66, 0x0b, ++ 0xc2, 0x77, 0xc4, 0x92, 0x4e, 0xca, 0x2e, 0x62, 0x29, 0x39, 0xca, 0xb9, ++ 0x21, 0x59, 0xb1, 0x67, 0x99, 0xf3, 0x4e, 0x09, 0x7d, 0x55, 0xc3, 0xda, ++ 0x64, 0x70, 0x4a, 0x76, 0x11, 0x1f, 0x35, 0xac, 0x53, 0x56, 0xe8, 0xb5, ++ 0x40, 0xd1, 0x4e, 0xdf, 0x45, 0x0e, 0xf8, 0x88, 0xfb, 0x99, 0xb2, 0x12, ++ 0x47, 0x56, 0xe7, 0x61, 0x8b, 0xf9, 0x29, 0xd8, 0x88, 0x39, 0xc1, 0xb8, ++ 0xfa, 0xeb, 0xb4, 0x8e, 0x4e, 0x22, 0x7e, 0x40, 0x8b, 0xf3, 0x9f, 0x4a, ++ 0x67, 0xc0, 0x1f, 0x15, 0xa9, 0xe7, 0x56, 0xac, 0x65, 0x3d, 0xbd, 0xa2, ++ 0x0a, 0xd1, 0xef, 0x1d, 0xd9, 0x1f, 0xb6, 0x12, 0x09, 0x5b, 0x4a, 0x29, ++ 0x9f, 0x5b, 0xbf, 0x84, 0x3c, 0x7a, 0xd3, 0xea, 0xaf, 0xc1, 0x57, 0xce, ++ 0xf4, 0xa7, 0xdd, 0x45, 0x36, 0x3b, 0x61, 0xbc, 0x08, 0xdd, 0xae, 0xc2, ++ 0xff, 0xb4, 0xf9, 0xa5, 0x2e, 0x64, 0x77, 0x1c, 0xe6, 0xae, 0xb4, 0xbb, ++ 0xa4, 0xb3, 0x69, 0xbe, 0xa2, 0xab, 0xb2, 0xdc, 0xee, 0x9c, 0x34, 0x6e, ++ 0x24, 0x2b, 0x85, 0x2a, 0xfd, 0x36, 0xba, 0x00, 0x3f, 0x2c, 0xb7, 0xbb, ++ 0x13, 0x8f, 0x6d, 0x76, 0xa4, 0x75, 0x77, 0x55, 0x5a, 0x6e, 0x45, 0xdd, ++ 0xa5, 0x64, 0x0c, 0x72, 0xab, 0xd8, 0x87, 0x71, 0x15, 0x06, 0x75, 0x77, ++ 0xe2, 0xb1, 0x8b, 0x9d, 0x7b, 0x90, 0xb7, 0xf2, 0x41, 0xad, 0x12, 0x21, ++ 0x77, 0xaf, 0x1e, 0x74, 0x25, 0x92, 0xb5, 0x5e, 0x49, 0x6a, 0xe9, 0x84, ++ 0xac, 0xf7, 0x24, 0x79, 0x6a, 0x06, 0xfb, 0x55, 0xf0, 0xde, 0x9b, 0x97, ++ 0x56, 0x6f, 0x62, 0x45, 0x55, 0x5b, 0x92, 0xf4, 0xd6, 0xf1, 0x2f, 0x49, ++ 0xa3, 0x53, 0x2a, 0x5d, 0xec, 0xb4, 0xc8, 0x5f, 0x72, 0xaa, 0x81, 0x3e, ++ 0xdc, 0xdd, 0x65, 0xdc, 0x40, 0xce, 0xf0, 0x97, 0x54, 0x55, 0x4b, 0xd3, ++ 0xf7, 0x21, 0xc3, 0x81, 0x4d, 0xa8, 0xeb, 0x2c, 0xf6, 0xed, 0x8f, 0xad, ++ 0x1e, 0x7d, 0x37, 0x24, 0xed, 0x78, 0x1e, 0x76, 0x62, 0xd4, 0x0e, 0xc9, ++ 0x5a, 0xf4, 0x9e, 0x79, 0x1a, 0xb1, 0xfa, 0x9a, 0x98, 0x7b, 0x6a, 0xc0, ++ 0x93, 0x1a, 0x4c, 0xfa, 0x42, 0x54, 0x96, 0x53, 0xd8, 0xb7, 0xcf, 0xb7, ++ 0x0e, 0x1d, 0xc8, 0x37, 0x06, 0xbe, 0x06, 0xf8, 0x7c, 0x39, 0x6d, 0x79, ++ 0xc7, 0xc0, 0xbb, 0x9b, 0xf1, 0xce, 0x95, 0x17, 0x25, 0x06, 0xcf, 0x64, ++ 0xb0, 0x08, 0x7f, 0xae, 0xf8, 0x0d, 0xf0, 0x36, 0xa0, 0x03, 0xc6, 0x54, ++ 0x5a, 0xba, 0x42, 0xb9, 0x61, 0xf9, 0x69, 0xe6, 0x83, 0x95, 0xd9, 0x82, ++ 0x4c, 0xe8, 0x95, 0x96, 0x20, 0x67, 0x01, 0xe3, 0x3b, 0xa6, 0x9d, 0x02, ++ 0x77, 0x7c, 0x3e, 0xbf, 0x69, 0x54, 0x15, 0x31, 0x5a, 0x89, 0x82, 0xb6, ++ 0xf0, 0xbd, 0x28, 0x75, 0xe4, 0x99, 0x8a, 0xc6, 0xa4, 0xe9, 0x39, 0x8e, ++ 0xaa, 0xba, 0xd2, 0x44, 0x84, 0x26, 0xcb, 0xda, 0xce, 0xad, 0x20, 0xce, ++ 0x54, 0xf5, 0x7b, 0xaa, 0x5f, 0x0f, 0x0a, 0xa0, 0x41, 0x6e, 0x46, 0xa3, ++ 0xb0, 0xc1, 0x38, 0x68, 0xcf, 0x62, 0x7e, 0x0a, 0xf8, 0x39, 0x0e, 0x1a, ++ 0x8e, 0xcc, 0x11, 0xda, 0x85, 0xf4, 0x15, 0xe8, 0x98, 0xcf, 0x55, 0x60, ++ 0x9b, 0xc1, 0xb4, 0xc9, 0x7d, 0x0c, 0x9a, 0x54, 0x67, 0x79, 0x37, 0x98, ++ 0x4b, 0xf9, 0x7a, 0x80, 0xf5, 0xab, 0x9f, 0x52, 0xb2, 0x6b, 0x2e, 0x46, ++ 0x8c, 0x61, 0x79, 0xaf, 0x11, 0x25, 0xe3, 0xae, 0xcd, 0xf3, 0x3c, 0xdf, ++ 0x39, 0xb2, 0x16, 0x9c, 0x39, 0xb8, 0x1a, 0x39, 0xee, 0xfa, 0xfc, 0x01, ++ 0x69, 0xf9, 0x61, 0x5c, 0x87, 0xbf, 0xd7, 0x53, 0xe6, 0xc6, 0x18, 0xce, ++ 0x1d, 0x22, 0xea, 0x26, 0xf1, 0x9c, 0x1c, 0x04, 0x0f, 0xfc, 0xd8, 0x82, ++ 0x2c, 0x8e, 0x88, 0x99, 0x34, 0x84, 0x8e, 0xb0, 0x47, 0x34, 0xe7, 0x1d, ++ 0x61, 0x3c, 0xfa, 0x5c, 0x63, 0x8d, 0x79, 0xf5, 0x50, 0x2d, 0x0a, 0xe3, ++ 0x66, 0x96, 0x2b, 0x6f, 0xc1, 0xb6, 0xed, 0x94, 0xf5, 0x22, 0xaf, 0x11, ++ 0xcc, 0x0f, 0xc6, 0x4a, 0x8e, 0xb1, 0xe0, 0x89, 0x98, 0x9f, 0xa5, 0x0c, ++ 0x6b, 0x6b, 0x19, 0x8e, 0x2e, 0x40, 0x0f, 0x63, 0x9e, 0x00, 0x86, 0xb6, ++ 0x63, 0x1b, 0x9f, 0xad, 0x40, 0xdd, 0x30, 0x93, 0xd3, 0xb4, 0xb9, 0x31, ++ 0x27, 0xe2, 0x45, 0xd0, 0xfe, 0x16, 0xf6, 0x5a, 0x02, 0x8e, 0x12, 0x7b, ++ 0xb9, 0x77, 0x55, 0xd7, 0x3a, 0xfb, 0xa0, 0x4b, 0x00, 0x7c, 0x83, 0x0d, ++ 0x2c, 0xde, 0x0e, 0x23, 0xdf, 0x99, 0xf3, 0x61, 0xb0, 0x22, 0x9c, 0x97, ++ 0x61, 0x85, 0xf7, 0x26, 0xfc, 0xb4, 0x5e, 0x79, 0xd4, 0x69, 0x6c, 0xbf, ++ 0x9f, 0xf9, 0x48, 0xc6, 0x14, 0x6a, 0x49, 0xd3, 0x27, 0x5f, 0x11, 0x7c, ++ 0xfb, 0xc0, 0xf3, 0x77, 0xac, 0x15, 0x30, 0x0e, 0xca, 0xb1, 0xb8, 0x8d, ++ 0xbd, 0x02, 0xec, 0xb5, 0x24, 0xba, 0xfa, 0x3c, 0xb0, 0x67, 0x2a, 0x68, ++ 0xc8, 0xf7, 0x55, 0xbf, 0x46, 0xd2, 0x37, 0x5f, 0x18, 0xf0, 0x4d, 0x20, ++ 0xae, 0xcd, 0xc1, 0x87, 0xb2, 0x98, 0x22, 0x66, 0x3e, 0x98, 0xad, 0xfb, ++ 0xc0, 0xbe, 0xcf, 0x64, 0x18, 0x5e, 0x22, 0x0e, 0xca, 0x19, 0x8b, 0x83, ++ 0x45, 0xe2, 0x20, 0x70, 0xa5, 0xb5, 0x00, 0x7b, 0xc7, 0xef, 0x02, 0x5f, ++ 0xea, 0xf0, 0xc4, 0x4f, 0x3a, 0x1a, 0x71, 0xe5, 0x82, 0x9f, 0x75, 0xf8, ++ 0xf3, 0xae, 0x8c, 0x84, 0xde, 0xbb, 0xc0, 0x9b, 0xe4, 0x28, 0xf3, 0xc0, ++ 0x18, 0xe4, 0x3a, 0xb0, 0x6a, 0xba, 0x7c, 0x0a, 0x71, 0xef, 0x02, 0x27, ++ 0xb4, 0x70, 0xdf, 0xbc, 0x6e, 0xe6, 0xf5, 0x9b, 0xbf, 0xb7, 0x1d, 0xb8, ++ 0x19, 0xb5, 0xee, 0x73, 0x90, 0x31, 0x15, 0x1c, 0x81, 0x1f, 0xd7, 0x16, ++ 0xfe, 0x1b, 0xcf, 0x6f, 0x32, 0x1e, 0xd4, 0x90, 0x0a, 0xf7, 0x15, 0x69, ++ 0x74, 0x69, 0x87, 0x18, 0x76, 0xb0, 0x18, 0x84, 0x9c, 0x8f, 0x91, 0xf3, ++ 0x22, 0x4d, 0x62, 0x05, 0x30, 0x8c, 0xb8, 0xb7, 0x06, 0x7a, 0x55, 0x19, ++ 0x82, 0x5d, 0x11, 0x4b, 0x4a, 0x4a, 0xba, 0x7a, 0x54, 0xaf, 0x83, 0xb6, ++ 0x50, 0x5d, 0xd6, 0x5b, 0xd1, 0x31, 0x37, 0xef, 0x97, 0xda, 0x1d, 0x71, ++ 0x6a, 0x7d, 0x3f, 0x67, 0x74, 0x8f, 0x65, 0x74, 0x4b, 0x83, 0x74, 0x98, ++ 0x6f, 0x64, 0xf3, 0x09, 0xe6, 0x3f, 0x91, 0xd9, 0x9c, 0xb5, 0xa0, 0x84, ++ 0x3a, 0xcb, 0x3a, 0x10, 0x06, 0x81, 0xfa, 0x4f, 0x75, 0x60, 0x61, 0x00, ++ 0xbb, 0x45, 0xd9, 0xbe, 0xc2, 0x67, 0x4c, 0x0e, 0x9e, 0x75, 0x58, 0x49, ++ 0x74, 0x33, 0x3e, 0xf1, 0xdb, 0xcc, 0xf6, 0x21, 0x2d, 0xf1, 0x7a, 0x90, ++ 0x16, 0x69, 0x04, 0xbb, 0xa8, 0xb3, 0xb7, 0xb3, 0xd9, 0x01, 0xac, 0x21, ++ 0xe7, 0x53, 0x57, 0x1e, 0xd6, 0xcc, 0xef, 0x7b, 0xb5, 0x3d, 0xc7, 0x0e, ++ 0xe8, 0x77, 0x26, 0x2c, 0xce, 0x2c, 0x75, 0x86, 0x20, 0x7e, 0x54, 0x8e, ++ 0x23, 0x9f, 0x9f, 0x86, 0xef, 0x2f, 0xc6, 0x0a, 0xdd, 0x02, 0x6b, 0x8e, ++ 0x41, 0x1c, 0x86, 0xd6, 0x17, 0xb5, 0x68, 0x0d, 0x91, 0xfc, 0x2d, 0xb9, ++ 0x3a, 0x3f, 0x22, 0x85, 0x4b, 0xd4, 0x01, 0xfd, 0xd2, 0xe6, 0xe0, 0x3e, ++ 0x73, 0xd8, 0x67, 0x02, 0x18, 0x78, 0x3f, 0xea, 0x8b, 0x2f, 0x7a, 0x1a, ++ 0x58, 0x9b, 0x96, 0x9c, 0x3a, 0xe4, 0xab, 0x4b, 0x3c, 0x3f, 0x31, 0xb8, ++ 0x94, 0xd5, 0x36, 0xe6, 0xd6, 0x10, 0x6a, 0xfa, 0x1f, 0x91, 0xbb, 0x4a, ++ 0x56, 0x2b, 0xc6, 0x1c, 0x89, 0x7f, 0x00, 0xfb, 0x62, 0x6e, 0x93, 0x6b, ++ 0xbb, 0x98, 0xe7, 0x1c, 0x65, 0x30, 0x16, 0x0f, 0xa0, 0xae, 0x61, 0xcf, ++ 0xa3, 0xe4, 0x19, 0x42, 0xcd, 0x27, 0xfe, 0x63, 0xdc, 0xe4, 0x3b, 0xcf, ++ 0x44, 0x6c, 0x73, 0x31, 0x8e, 0x60, 0xe4, 0x99, 0x7e, 0x91, 0xf9, 0x8a, ++ 0xcf, 0xc6, 0xe8, 0xea, 0xa8, 0xd4, 0x3b, 0x11, 0x30, 0x76, 0xaa, 0x7c, ++ 0x5c, 0xb8, 0x86, 0xf7, 0x2e, 0xe7, 0xbd, 0x81, 0x79, 0x3c, 0x77, 0xad, ++ 0xce, 0xa8, 0xed, 0x79, 0xff, 0xb2, 0x06, 0xc3, 0xa2, 0xc7, 0xd8, 0x64, ++ 0xaf, 0xc2, 0xfa, 0x67, 0x71, 0x6b, 0x96, 0x7d, 0xca, 0xeb, 0x1d, 0xd6, ++ 0x42, 0xcd, 0xbc, 0x44, 0x00, 0x1c, 0x92, 0xba, 0x9f, 0x9f, 0x0b, 0x71, ++ 0x1c, 0x53, 0x36, 0x65, 0x4c, 0xc2, 0x76, 0xec, 0x47, 0xa2, 0xb2, 0x76, ++ 0xa6, 0x92, 0x26, 0xf9, 0xba, 0x05, 0x29, 0x6c, 0xcc, 0x8b, 0x7b, 0xd6, ++ 0xc8, 0x66, 0x5f, 0x9e, 0xb7, 0x2c, 0xbe, 0xd4, 0x5e, 0xa2, 0x1e, 0x98, ++ 0xdf, 0x61, 0x3d, 0x0c, 0x81, 0x67, 0xc5, 0x6c, 0xdf, 0xb2, 0x34, 0x3b, ++ 0x91, 0xd7, 0x10, 0x8c, 0xdd, 0x3b, 0xe0, 0xbb, 0x22, 0xce, 0xac, 0xe5, ++ 0x62, 0xa7, 0xbf, 0x17, 0x73, 0xee, 0xb9, 0xb8, 0xbf, 0x57, 0x43, 0x7e, ++ 0x89, 0xbd, 0xc4, 0x57, 0xc2, 0x3e, 0x12, 0x7d, 0xe3, 0x39, 0x8d, 0xfd, ++ 0x68, 0xa3, 0x02, 0x7a, 0xdb, 0xd9, 0xec, 0x3c, 0x21, 0xe8, 0x34, 0x6c, ++ 0x4e, 0x5b, 0x73, 0x0f, 0xc6, 0xe2, 0x3f, 0x0c, 0xf1, 0x05, 0x75, 0x05, ++ 0xfa, 0xe2, 0xbd, 0xc7, 0x3d, 0x26, 0xe4, 0xc5, 0xd4, 0x62, 0xad, 0x77, ++ 0x02, 0x98, 0xd5, 0xe8, 0xfc, 0x2d, 0xaf, 0x3d, 0x49, 0x1b, 0xf8, 0xfb, ++ 0xac, 0x8c, 0x8a, 0xde, 0x19, 0x95, 0xe7, 0xd0, 0xef, 0x15, 0x36, 0x50, ++ 0xe7, 0x61, 0x63, 0x75, 0xb6, 0x35, 0xcb, 0x9e, 0xed, 0x32, 0x72, 0x79, ++ 0xb5, 0x12, 0xc5, 0xae, 0x33, 0x2d, 0x67, 0xbe, 0x1b, 0xce, 0x6e, 0xdb, ++ 0x7c, 0xc6, 0xfa, 0x4e, 0x20, 0xa7, 0xbb, 0x91, 0x9c, 0xe9, 0x7a, 0xd0, ++ 0xcb, 0xbb, 0xd5, 0xd7, 0x46, 0xc4, 0xdb, 0x06, 0xfe, 0xc4, 0x53, 0x9e, ++ 0x0b, 0x3e, 0xa8, 0xd2, 0x6e, 0xec, 0x63, 0xe9, 0x5f, 0xe2, 0xdb, 0xa3, ++ 0x78, 0x1e, 0x11, 0xf7, 0x1c, 0xfb, 0x4e, 0xc6, 0x24, 0xfd, 0x33, 0xd8, ++ 0x0b, 0x13, 0xfb, 0x20, 0x73, 0x87, 0xb9, 0x9f, 0xe7, 0x66, 0x9e, 0xab, ++ 0xc4, 0x01, 0xed, 0x2c, 0xc2, 0x5e, 0xd7, 0x62, 0xe6, 0xeb, 0x0d, 0x73, ++ 0xcd, 0xf6, 0x6e, 0x1e, 0xfb, 0xe2, 0x81, 0xde, 0x2d, 0xef, 0x7b, 0x18, ++ 0xaf, 0xe5, 0x81, 0x7c, 0xbd, 0x6e, 0x73, 0xf5, 0x0d, 0xe4, 0xed, 0xcb, ++ 0x69, 0xd9, 0xe6, 0xec, 0xe1, 0x07, 0x6e, 0x97, 0xb3, 0x97, 0x3f, 0x46, ++ 0xce, 0xfe, 0x30, 0xcb, 0xd9, 0xa2, 0x8d, 0x6b, 0xb5, 0x31, 0xb8, 0xf6, ++ 0x23, 0xac, 0x0d, 0x65, 0x77, 0x0a, 0x6d, 0x3b, 0xe8, 0xc3, 0x0f, 0xd2, ++ 0x47, 0xb9, 0x7f, 0xfa, 0x71, 0x5a, 0xd7, 0xa4, 0x81, 0x0f, 0x37, 0x46, ++ 0x11, 0x4f, 0xcc, 0xe9, 0x3c, 0x9e, 0x02, 0xc4, 0x72, 0xce, 0x8f, 0x7e, ++ 0xf3, 0x28, 0x63, 0xa1, 0x60, 0xf3, 0xc6, 0xad, 0xe6, 0x34, 0x65, 0x59, ++ 0x44, 0x2f, 0xf7, 0x63, 0x8e, 0xdd, 0x7e, 0xac, 0x14, 0x37, 0x4a, 0xf2, ++ 0xfc, 0x0c, 0xb1, 0x2b, 0x8c, 0xaf, 0x42, 0xe7, 0x6b, 0x91, 0x2f, 0x85, ++ 0x69, 0xe6, 0x33, 0xab, 0x51, 0x11, 0x31, 0x84, 0xbb, 0x55, 0x6a, 0x4e, ++ 0xa2, 0xdf, 0x0a, 0x34, 0xfc, 0xfc, 0x32, 0xe2, 0x88, 0xd8, 0x8a, 0x98, ++ 0x98, 0xdd, 0x44, 0x4c, 0x1c, 0xe7, 0xbb, 0xdd, 0xb7, 0x60, 0x69, 0x5d, ++ 0xbb, 0xbf, 0x0f, 0xfd, 0x4b, 0x32, 0x74, 0xce, 0xe0, 0x4e, 0x75, 0x8b, ++ 0xef, 0xb4, 0x8d, 0x5f, 0x60, 0x09, 0xe6, 0x57, 0x6d, 0xfc, 0xd2, 0xa7, ++ 0x8c, 0x7b, 0x63, 0x7e, 0x67, 0xf3, 0xe6, 0xd7, 0x16, 0x03, 0xae, 0xc5, ++ 0x36, 0x9e, 0x63, 0xf6, 0x9b, 0xa7, 0xbb, 0x3f, 0xd7, 0x16, 0x23, 0x36, ++ 0x8c, 0x9c, 0x8a, 0x6d, 0xac, 0xcd, 0xbe, 0x81, 0x63, 0xbf, 0xd6, 0xcf, ++ 0x85, 0x01, 0x39, 0x93, 0xde, 0x23, 0x90, 0x83, 0x9a, 0x17, 0xac, 0xb1, ++ 0x3f, 0x88, 0xa7, 0xd0, 0x2f, 0x81, 0xae, 0xbb, 0x17, 0x2f, 0xc6, 0x31, ++ 0xd2, 0xde, 0x7f, 0x80, 0x5c, 0x0f, 0x36, 0xa4, 0x1c, 0xea, 0x4d, 0xbd, ++ 0x46, 0x25, 0x3a, 0x9b, 0xeb, 0xf4, 0x17, 0xab, 0xcb, 0xbf, 0xcb, 0xc3, ++ 0xfa, 0xce, 0xed, 0xf8, 0xbc, 0x01, 0xbe, 0x3f, 0xdf, 0x86, 0x0f, 0xeb, ++ 0x3b, 0xe4, 0x19, 0xb9, 0xd9, 0x6b, 0xd4, 0x6f, 0xc6, 0x75, 0x82, 0xb8, ++ 0x27, 0xef, 0xde, 0xbb, 0xdc, 0x60, 0x0e, 0xe4, 0x35, 0x9e, 0x71, 0xce, ++ 0x3d, 0xf3, 0x58, 0xcf, 0x63, 0x3c, 0x8f, 0xf9, 0x3c, 0xd6, 0xc3, 0xf8, ++ 0x19, 0xe9, 0xfb, 0x57, 0x6f, 0x84, 0xd8, 0x7f, 0xe4, 0x7f, 0xb8, 0xb7, ++ 0x10, 0x23, 0x24, 0xb9, 0x75, 0xd7, 0xfb, 0x69, 0xd6, 0xaf, 0x94, 0x98, ++ 0x6b, 0xf8, 0xb3, 0x8f, 0xdf, 0x45, 0x7f, 0x10, 0x67, 0xb6, 0x4d, 0xb2, ++ 0xb1, 0x4f, 0xd3, 0xef, 0x07, 0xbf, 0x9a, 0x61, 0xf2, 0x17, 0xfb, 0xf5, ++ 0x47, 0xf2, 0x9c, 0x62, 0x0e, 0xd9, 0x9c, 0xe2, 0x79, 0x70, 0x0f, 0x37, ++ 0x66, 0x19, 0x7e, 0x7c, 0x3e, 0xce, 0xf3, 0x08, 0xf1, 0xf4, 0x40, 0x9e, ++ 0xe3, 0xb0, 0x53, 0x74, 0xc3, 0xe8, 0xe9, 0x04, 0x36, 0xe3, 0xdd, 0xb7, ++ 0x81, 0xde, 0x89, 0x76, 0x5a, 0x72, 0x9e, 0xb8, 0x79, 0xdf, 0xdd, 0xdb, ++ 0x27, 0xd1, 0x6e, 0xb4, 0xeb, 0xa0, 0xdd, 0xc2, 0x78, 0x5c, 0x11, 0x03, ++ 0x6e, 0x87, 0x13, 0x79, 0x3d, 0x07, 0x06, 0x4d, 0xe7, 0x76, 0xfa, 0xd8, ++ 0x35, 0x3d, 0xe9, 0x7f, 0x2b, 0xd8, 0x8b, 0x0f, 0xdb, 0xee, 0x00, 0x3e, ++ 0xdc, 0xa6, 0xe7, 0xa4, 0x0c, 0xda, 0x00, 0xf5, 0xcd, 0xf6, 0x21, 0xec, ++ 0x31, 0x6f, 0x18, 0xd7, 0xf6, 0x9b, 0xc4, 0x46, 0xf6, 0x99, 0xdf, 0x2c, ++ 0xc8, 0xc8, 0x3e, 0xfb, 0x9e, 0x6c, 0x73, 0x64, 0x4c, 0x48, 0xbf, 0x6e, ++ 0x59, 0xfd, 0x1f, 0xcf, 0xf4, 0xef, 0xeb, 0x2c, 0xea, 0xa3, 0x30, 0x8d, ++ 0xba, 0x7a, 0xd0, 0x35, 0xcc, 0xed, 0xd2, 0x52, 0xd5, 0x13, 0xd2, 0xa8, ++ 0xb0, 0x5f, 0x12, 0xdc, 0xb5, 0xa0, 0xc3, 0x02, 0xf5, 0x28, 0x43, 0x8f, ++ 0x51, 0xdc, 0x4d, 0xc2, 0xa5, 0x96, 0x84, 0xc9, 0x0a, 0x08, 0x67, 0xbe, ++ 0x43, 0xbb, 0x1d, 0xd3, 0x5b, 0x1d, 0xda, 0xed, 0x49, 0xbd, 0xde, 0x99, ++ 0x44, 0x7f, 0x18, 0xc2, 0xdb, 0xe1, 0xec, 0x25, 0x61, 0x8c, 0xcd, 0xc5, ++ 0x1c, 0x4f, 0x0b, 0xfb, 0xb1, 0x63, 0x7a, 0xaa, 0xcb, 0xf1, 0x49, 0x1d, ++ 0x75, 0x07, 0xe5, 0xfe, 0xc9, 0x00, 0x13, 0x93, 0xeb, 0xc8, 0xa3, 0x17, ++ 0x7b, 0xfd, 0xbd, 0x71, 0x3f, 0xcc, 0xe4, 0x62, 0x2e, 0xcd, 0x65, 0x0b, ++ 0x71, 0x8a, 0xb2, 0x21, 0x77, 0x32, 0xfe, 0x99, 0xdd, 0x83, 0xf7, 0xa3, ++ 0x8f, 0xda, 0xe3, 0xae, 0xfc, 0xfb, 0x04, 0x72, 0xa7, 0x60, 0xb1, 0x67, ++ 0x2d, 0xc5, 0x9d, 0xda, 0x37, 0xa6, 0x19, 0xbd, 0x0d, 0xdb, 0xa1, 0x47, ++ 0x98, 0xf7, 0xf0, 0x07, 0xae, 0x2e, 0x73, 0x0d, 0x7d, 0x38, 0xee, 0x82, ++ 0xbc, 0xcf, 0xad, 0xa5, 0x5c, 0x63, 0x8c, 0xa3, 0x57, 0x9c, 0xff, 0x15, ++ 0x68, 0xdf, 0x31, 0xad, 0x9e, 0xb2, 0xf7, 0x75, 0x15, 0xe1, 0x1e, 0xd6, ++ 0x63, 0x3f, 0x23, 0x4e, 0x23, 0x95, 0xa0, 0x19, 0x2f, 0xd8, 0xfb, 0x5a, ++ 0xe2, 0x05, 0xbc, 0x93, 0xa2, 0x07, 0x9d, 0x1f, 0xe8, 0x41, 0xe7, 0xd1, ++ 0x83, 0x8e, 0x15, 0x11, 0xe7, 0x09, 0xee, 0xa1, 0xaa, 0xd9, 0xcf, 0x9b, ++ 0x31, 0xde, 0x39, 0xdb, 0xbe, 0xec, 0x43, 0x77, 0x05, 0xdd, 0x22, 0xec, ++ 0xcf, 0xf5, 0x3b, 0xb3, 0xef, 0x5a, 0xa3, 0xa0, 0x4f, 0x6c, 0x3f, 0xd6, ++ 0xf6, 0x8b, 0xd2, 0x8c, 0x49, 0x73, 0x28, 0xa3, 0xf9, 0xf2, 0x1e, 0x9a, ++ 0x3b, 0x79, 0x46, 0xca, 0x96, 0xe6, 0x2b, 0xcc, 0x3b, 0xd6, 0xd2, 0x62, ++ 0x96, 0x6f, 0x27, 0xf0, 0x3c, 0x94, 0x3d, 0xe7, 0xf4, 0xf7, 0xee, 0xe1, ++ 0x7f, 0xc8, 0xe9, 0xbf, 0xf3, 0x99, 0x3a, 0x27, 0xec, 0x93, 0x21, 0x6f, ++ 0xc1, 0xe9, 0x7f, 0x27, 0xc1, 0x85, 0x73, 0x84, 0x3e, 0xe9, 0xf7, 0x17, ++ 0xc0, 0x60, 0x74, 0x5f, 0x53, 0xb0, 0xbb, 0x31, 0xed, 0x05, 0xe2, 0xda, ++ 0xdc, 0xec, 0x11, 0x8b, 0x6f, 0x6a, 0x42, 0x49, 0x8e, 0xb9, 0x83, 0xcf, ++ 0x18, 0x17, 0xec, 0x37, 0x03, 0xbc, 0xf7, 0x65, 0x6c, 0xe1, 0xfe, 0x2c, ++ 0xc8, 0xe1, 0x96, 0xd5, 0xcb, 0xe9, 0xdf, 0x8b, 0xbc, 0x1a, 0xeb, 0x01, ++ 0xea, 0xc6, 0x0c, 0xf5, 0xba, 0xf9, 0x6d, 0x63, 0x05, 0xb5, 0xe6, 0x2d, ++ 0xc4, 0x3e, 0xf2, 0xd3, 0xf6, 0x58, 0x5b, 0xf6, 0xdb, 0x02, 0xea, 0xd0, ++ 0x08, 0xee, 0x4b, 0xd1, 0xcd, 0x6f, 0x0c, 0x72, 0x01, 0x34, 0x17, 0xb1, ++ 0x76, 0xba, 0x9b, 0xf7, 0xbc, 0xe8, 0xf3, 0x81, 0x7b, 0xab, 0xd1, 0xfb, ++ 0xa6, 0xe9, 0x0f, 0xd2, 0xf2, 0xf7, 0x2f, 0x97, 0xa2, 0x15, 0x3a, 0x18, ++ 0x15, 0x00, 0x00, 0x00 }; + + static const u32 bnx2_TPAT_b09FwData[(0x0/4) + 1] = { 0x0 }; + static const u32 bnx2_TPAT_b09FwRodata[(0x4/4) + 1] = { + 0x00000001, 0x00000000 }; + + static struct fw_info bnx2_tpat_fw_09 = { +- /* Firmware version: 4.6.15 */ ++ /* Firmware version: 4.4.26 */ + .ver_major = 0x4, +- .ver_minor = 0x6, +- .ver_fix = 0xf, ++ .ver_minor = 0x4, ++ .ver_fix = 0x1a, + + .start_addr = 0x08000488, + + .text_addr = 0x08000400, +- .text_len = 0x13a4, ++ .text_len = 0x1514, + .text_index = 0x0, + .gz_text = bnx2_TPAT_b09FwText, + .gz_text_len = sizeof(bnx2_TPAT_b09FwText), +@@ -3643,868 +3709,871 @@ + .data_index = 0x0, + .data = bnx2_TPAT_b09FwData, + +- .sbss_addr = 0x080017c0, +- .sbss_len = 0x40, ++ .sbss_addr = 0x08001940, ++ .sbss_len = 0x48, + .sbss_index = 0x0, + +- .bss_addr = 0x08001800, ++ .bss_addr = 0x08001988, + .bss_len = 0x12b4, + .bss_index = 0x0, + +- .rodata_addr = 0x080017a4, ++ .rodata_addr = 0x08001914, + .rodata_len = 0x4, + .rodata_index = 0x0, + .rodata = bnx2_TPAT_b09FwRodata, + }; + + static u8 bnx2_TXP_b09FwText[] = { +- 0xc5, 0x7b, 0x7d, 0x70, 0x1b, 0xe7, 0x79, 0xe7, 0xef, 0xc5, 0x02, 0xe4, +- 0x02, 0x04, 0x41, 0x90, 0x82, 0x64, 0xf0, 0xca, 0x44, 0x58, 0x61, 0x41, +- 0xc1, 0x26, 0x2d, 0x2f, 0x28, 0x50, 0x82, 0xcb, 0x55, 0x85, 0x4a, 0xb4, +- 0x44, 0xc7, 0x74, 0x43, 0x3b, 0x6a, 0x4b, 0x67, 0x3c, 0x09, 0x2a, 0x51, +- 0x16, 0x2d, 0xcb, 0x16, 0xed, 0xf8, 0x7a, 0xec, 0x9c, 0x27, 0xda, 0x50, +- 0x1f, 0x96, 0x25, 0x10, 0x00, 0x3f, 0x64, 0xca, 0x9d, 0xce, 0x19, 0x26, +- 0x29, 0x51, 0xb6, 0xf1, 0x21, 0xc7, 0x4a, 0x6a, 0xcf, 0x24, 0x11, 0x4e, +- 0x96, 0x65, 0xd9, 0x89, 0x3f, 0x92, 0xf8, 0x7a, 0x4e, 0xa7, 0x37, 0xd5, +- 0x48, 0xfe, 0x90, 0x2c, 0xf9, 0xa3, 0x69, 0x6f, 0x2a, 0xb5, 0x4e, 0xf7, +- 0x9e, 0x67, 0x17, 0x94, 0x15, 0xd7, 0x9d, 0x9b, 0xf6, 0xfe, 0x38, 0xce, +- 0x70, 0x00, 0xec, 0xbe, 0xfb, 0xbe, 0xcf, 0xf7, 0xf3, 0x7b, 0x9e, 0xf7, +- 0xdd, 0x56, 0xc0, 0x83, 0xea, 0x5f, 0x3d, 0xfd, 0xc7, 0x87, 0x86, 0x1f, +- 0x8e, 0x2d, 0x5b, 0xb1, 0x8c, 0xbe, 0x76, 0xa2, 0xa1, 0xc6, 0xc9, 0x37, +- 0x57, 0x08, 0x20, 0xf5, 0x21, 0xfe, 0x43, 0x7f, 0x5f, 0xf9, 0x8f, 0x3d, +- 0x66, 0xfd, 0x49, 0x80, 0x7f, 0x9e, 0x2e, 0xfe, 0x87, 0xec, 0xd0, 0x93, +- 0x5d, 0x6b, 0x54, 0xc8, 0x92, 0x7e, 0x79, 0xd5, 0x26, 0x15, 0x48, 0x16, +- 0xda, 0x42, 0x6b, 0xf1, 0x1b, 0xd3, 0x08, 0x38, 0xc1, 0xd7, 0xbf, 0xa2, +- 0x7f, 0xb6, 0xe3, 0xc7, 0x2b, 0x95, 0x4f, 0xf3, 0x12, 0x64, 0xbf, 0x7e, +- 0x10, 0xfe, 0x56, 0xc8, 0x2d, 0xf4, 0xcc, 0x5f, 0x2c, 0x2d, 0x39, 0xe1, +- 0x9b, 0x9f, 0x0b, 0x86, 0x4b, 0xd7, 0xb0, 0x33, 0x3b, 0x84, 0x23, 0x71, +- 0xa0, 0x76, 0x34, 0xa2, 0xed, 0x04, 0x72, 0x0e, 0x3d, 0x12, 0x3a, 0x81, +- 0x10, 0x66, 0x0b, 0x2a, 0x1e, 0x2d, 0xc3, 0x70, 0xea, 0x21, 0x3c, 0x96, +- 0xfe, 0x17, 0x33, 0xe4, 0xe2, 0x47, 0x86, 0xb0, 0x8b, 0xc6, 0xee, 0x4e, +- 0x43, 0x0e, 0xea, 0x8f, 0x20, 0x98, 0x85, 0x5c, 0xaf, 0x0f, 0xa3, 0x38, +- 0x1a, 0x3e, 0x3d, 0x07, 0xa5, 0xaf, 0x59, 0x52, 0x86, 0x80, 0xb6, 0xd4, +- 0x5d, 0x42, 0xe9, 0x2f, 0x09, 0x25, 0xb1, 0x4d, 0x40, 0x16, 0x34, 0xee, +- 0x86, 0x02, 0x7f, 0x0e, 0x63, 0x69, 0x41, 0xc6, 0x19, 0x89, 0xe7, 0x59, +- 0x45, 0xf2, 0x16, 0x70, 0xaa, 0x1a, 0x76, 0x67, 0x79, 0x0d, 0x81, 0x9d, +- 0xf1, 0x88, 0x7f, 0x06, 0x7c, 0x3f, 0x84, 0x11, 0x6b, 0x9c, 0x42, 0x5c, +- 0x9b, 0xe6, 0x2e, 0xcd, 0x34, 0x0f, 0x69, 0xb5, 0x30, 0xfc, 0x4a, 0x10, +- 0x10, 0x18, 0xd1, 0x1c, 0x48, 0xfa, 0xd7, 0x84, 0x9c, 0x50, 0x82, 0x9b, +- 0xf1, 0xcf, 0xc4, 0x73, 0x32, 0xea, 0x82, 0x3d, 0x3e, 0x85, 0x5a, 0x54, +- 0xfc, 0xb6, 0xd4, 0xa6, 0xd3, 0xa6, 0x79, 0x4a, 0x75, 0xe2, 0x10, 0xc9, +- 0x67, 0xa4, 0xf0, 0xcf, 0x66, 0x85, 0x64, 0xb3, 0x4b, 0x9d, 0x5f, 0x5f, +- 0x46, 0xde, 0x6f, 0x9a, 0x33, 0x74, 0x6f, 0x4f, 0x61, 0x5e, 0xce, 0xa6, +- 0xe9, 0x50, 0x4d, 0x73, 0x93, 0xfa, 0x4f, 0xe6, 0xc6, 0xdf, 0x1a, 0x1b, +- 0xc3, 0x33, 0x39, 0x3f, 0x9e, 0xcd, 0x26, 0x51, 0x48, 0x9b, 0x90, 0x74, +- 0x27, 0x06, 0x47, 0x43, 0xd8, 0x56, 0xec, 0x46, 0x31, 0xad, 0xa4, 0xce, +- 0xd0, 0x73, 0x1b, 0xe3, 0x2a, 0xee, 0x2f, 0xf6, 0x60, 0x2e, 0x0d, 0xd3, +- 0xad, 0xab, 0x15, 0xb7, 0x88, 0x62, 0x4b, 0xb1, 0x17, 0xa5, 0xb4, 0x7a, +- 0x7a, 0x44, 0x44, 0x86, 0x9b, 0x25, 0x27, 0xb6, 0x17, 0xdb, 0xf1, 0x40, +- 0x31, 0x41, 0xcf, 0x98, 0xf8, 0x5a, 0xac, 0x85, 0xc6, 0x77, 0xe0, 0xe9, +- 0x49, 0xd3, 0x8c, 0xc6, 0xfc, 0x18, 0x2c, 0x6a, 0x98, 0xcb, 0x39, 0x90, +- 0x3a, 0xe4, 0x44, 0xea, 0x29, 0x60, 0xcb, 0x53, 0x1d, 0x98, 0xc9, 0x99, +- 0xd8, 0xa8, 0x8d, 0x34, 0x3b, 0xe0, 0x42, 0xca, 0x2f, 0xe0, 0x52, 0x7d, +- 0xd8, 0xec, 0xb7, 0x69, 0x3f, 0x23, 0x09, 0x6c, 0x7d, 0x2a, 0x8a, 0x77, +- 0xd2, 0x06, 0xbe, 0xd6, 0x19, 0xc4, 0x70, 0x31, 0x80, 0x37, 0xd3, 0x01, +- 0x5a, 0x43, 0xc3, 0x1b, 0x69, 0x99, 0xd6, 0x69, 0xc7, 0xc9, 0x34, 0x8f, +- 0xe1, 0xb1, 0x5e, 0x0c, 0x14, 0x5b, 0xf0, 0x7a, 0x3a, 0x48, 0x6b, 0x06, +- 0xf0, 0x2a, 0x8d, 0xbb, 0xb7, 0xa8, 0xe2, 0x34, 0x8d, 0x1b, 0x2c, 0x86, +- 0xf0, 0x4a, 0xda, 0x4b, 0xb4, 0x06, 0x70, 0x22, 0x3d, 0x84, 0x9d, 0xe9, +- 0xb6, 0xd3, 0x6b, 0x49, 0x86, 0xa1, 0x05, 0xbc, 0x0e, 0x5f, 0x7b, 0xd7, +- 0xec, 0x0d, 0x58, 0xa6, 0x42, 0xeb, 0xcc, 0xaf, 0x3b, 0x84, 0x91, 0xf4, +- 0xa9, 0xaa, 0xbf, 0x68, 0x78, 0x2c, 0x77, 0xd9, 0xfc, 0xf1, 0xd2, 0x16, +- 0x1c, 0xc9, 0x02, 0x4f, 0xcf, 0x00, 0x33, 0x59, 0xc3, 0xac, 0xd7, 0x4d, +- 0x73, 0xba, 0xb3, 0x9d, 0xe4, 0xa5, 0xf6, 0x6f, 0xa4, 0x51, 0xcf, 0x96, +- 0x9d, 0xc0, 0x53, 0x4a, 0x7f, 0x05, 0x0e, 0xe4, 0xe7, 0x9c, 0xa8, 0x19, +- 0x55, 0x7a, 0xf2, 0x50, 0x4e, 0x6f, 0x21, 0x8f, 0x3a, 0x94, 0x55, 0xfa, +- 0x0c, 0xec, 0x30, 0x83, 0x7a, 0x6b, 0xa8, 0x5d, 0x32, 0xe1, 0x23, 0x5b, +- 0x48, 0xb7, 0x9b, 0x66, 0xc3, 0x4a, 0xd3, 0x7c, 0xbd, 0x13, 0xa6, 0x43, +- 0x57, 0x4f, 0x97, 0xa1, 0x56, 0x3e, 0x82, 0x3a, 0x7c, 0x02, 0x95, 0xaf, +- 0x78, 0x11, 0x19, 0x0c, 0x4b, 0x91, 0xa1, 0xcb, 0xf4, 0x6c, 0x7d, 0x91, +- 0xcc, 0x99, 0x78, 0x51, 0x47, 0x81, 0x62, 0x59, 0x86, 0x93, 0xf8, 0x69, +- 0x1f, 0x35, 0x4d, 0xa7, 0xea, 0x85, 0x97, 0xe4, 0xbb, 0xfe, 0x80, 0x69, +- 0xbe, 0xaf, 0xf9, 0x51, 0x43, 0xba, 0xb9, 0x65, 0xcc, 0xc4, 0xb4, 0x76, +- 0x82, 0xe4, 0x29, 0x90, 0xea, 0x8b, 0xd3, 0x33, 0x01, 0x1a, 0x9f, 0xc0, +- 0xfa, 0xd1, 0x20, 0x9e, 0xc9, 0xca, 0xf8, 0xf1, 0xd2, 0x28, 0xea, 0x68, +- 0x2e, 0x0f, 0xc9, 0xaa, 0x96, 0xe4, 0x87, 0x22, 0x99, 0x5b, 0xd1, 0xb6, +- 0x47, 0x14, 0xcf, 0x10, 0x8f, 0x41, 0x7c, 0xbf, 0x1c, 0xc0, 0x73, 0x65, +- 0x3f, 0x8e, 0x96, 0x5b, 0x70, 0xbc, 0xac, 0xe1, 0x60, 0x4e, 0xd9, 0x5b, +- 0x81, 0x89, 0x7a, 0x7d, 0x07, 0x1a, 0x96, 0x03, 0x6f, 0xe6, 0x63, 0xc8, +- 0xe4, 0x4c, 0xb3, 0x40, 0x74, 0x7b, 0x88, 0x8f, 0x37, 0xf2, 0x5f, 0xc5, +- 0xe1, 0x49, 0x27, 0x42, 0xd3, 0x01, 0x3c, 0x9b, 0x76, 0xe2, 0xfa, 0x8c, +- 0x62, 0xe4, 0xa1, 0x46, 0xb7, 0x09, 0x35, 0x79, 0x83, 0x50, 0x72, 0x06, +- 0x22, 0x21, 0x97, 0x70, 0xa0, 0xf5, 0xb0, 0x13, 0x6a, 0x29, 0x04, 0x57, +- 0xab, 0x0c, 0xb5, 0xf5, 0x21, 0xc0, 0xe7, 0x40, 0x0d, 0xf9, 0xc6, 0xfa, +- 0xf1, 0x28, 0x5d, 0x0b, 0xd0, 0x35, 0x7c, 0xb5, 0x16, 0xd2, 0x22, 0x09, +- 0x24, 0x3b, 0x55, 0x42, 0xd2, 0x69, 0x9a, 0x92, 0xda, 0x81, 0xbb, 0x1e, +- 0x37, 0xcd, 0xf0, 0x72, 0x1e, 0xef, 0x47, 0xb8, 0x44, 0x72, 0x68, 0x25, +- 0xba, 0xb2, 0x44, 0x67, 0x96, 0xe8, 0xcc, 0x12, 0x9d, 0x59, 0x89, 0xec, +- 0x46, 0xd1, 0x80, 0x47, 0x48, 0x5f, 0x21, 0xe2, 0xf1, 0x1d, 0x4b, 0x57, +- 0xcf, 0x95, 0x83, 0xc4, 0x43, 0xc8, 0xe2, 0xe1, 0xe9, 0x9c, 0x80, 0x43, +- 0x55, 0xfa, 0xce, 0x60, 0x35, 0xc2, 0x31, 0x25, 0x99, 0x47, 0x92, 0x9e, +- 0x53, 0xf6, 0x1a, 0x50, 0x7a, 0x2a, 0x64, 0x03, 0x1b, 0xfd, 0x09, 0xcc, +- 0x65, 0x5d, 0xa8, 0x53, 0x95, 0x10, 0xe9, 0x2c, 0x5a, 0xc1, 0x02, 0xdc, +- 0xe7, 0xa7, 0x39, 0x1d, 0xb2, 0xb0, 0x63, 0xc9, 0x23, 0x88, 0x8c, 0x3b, +- 0x30, 0xab, 0x49, 0xe4, 0xa3, 0x1a, 0xa4, 0x56, 0x5a, 0xae, 0x14, 0xa7, +- 0x4f, 0x9a, 0x3f, 0x4b, 0x6b, 0x11, 0x3d, 0x34, 0x1f, 0xf9, 0x26, 0xcb, +- 0x32, 0x4a, 0x34, 0x3c, 0x6a, 0xd1, 0x7b, 0xb4, 0xfc, 0x75, 0x61, 0xdb, +- 0x90, 0x4e, 0x36, 0xa3, 0x84, 0x20, 0x94, 0x68, 0x48, 0x28, 0x5a, 0x52, +- 0xf8, 0x31, 0x53, 0x7e, 0x83, 0xc6, 0x04, 0xae, 0x19, 0xd3, 0x87, 0x91, +- 0xac, 0xc0, 0x5a, 0xd5, 0xc4, 0x1a, 0xad, 0x0f, 0x3b, 0xcb, 0xf3, 0xbe, +- 0xc9, 0x31, 0xcc, 0xef, 0x9b, 0x49, 0x77, 0x63, 0x57, 0x36, 0x84, 0x9d, +- 0x85, 0xa0, 0x6f, 0x3a, 0xcd, 0xf7, 0x54, 0xf2, 0x79, 0xbe, 0x17, 0xb8, +- 0xe6, 0x5e, 0xcb, 0x35, 0xf7, 0x12, 0x18, 0x99, 0xf8, 0x1d, 0x8a, 0x23, +- 0x0d, 0xd8, 0xa9, 0x7e, 0x4a, 0xf6, 0xa2, 0x26, 0x06, 0xd0, 0x8c, 0x33, +- 0xfe, 0x76, 0xec, 0x9f, 0xea, 0xc5, 0xae, 0xa9, 0x65, 0x78, 0x6c, 0xa2, +- 0x25, 0xe5, 0xd1, 0x49, 0x38, 0x9e, 0x70, 0x72, 0x40, 0x28, 0x43, 0x92, +- 0x08, 0x47, 0x07, 0xc8, 0x7e, 0x5b, 0x1b, 0x4d, 0xf3, 0x44, 0x8c, 0xec, +- 0x5b, 0x6b, 0xd3, 0xd6, 0x93, 0x00, 0x2a, 0x7d, 0x4a, 0xcf, 0xbb, 0xf0, +- 0xe2, 0x76, 0xb2, 0xbb, 0x99, 0x18, 0x06, 0x24, 0x48, 0xed, 0x5e, 0xfc, +- 0xbd, 0xf9, 0x94, 0x93, 0xe5, 0x6e, 0xee, 0xd8, 0xa4, 0xed, 0x15, 0x1c, +- 0xeb, 0x6a, 0xae, 0xc6, 0x13, 0x9e, 0x9f, 0x9f, 0x21, 0xdd, 0xd1, 0x3c, +- 0x83, 0xb1, 0xb6, 0xc4, 0x20, 0x2e, 0x9b, 0x67, 0x36, 0xf4, 0x62, 0xe7, +- 0xdc, 0x32, 0xec, 0x9b, 0x70, 0x21, 0xd9, 0x28, 0xd0, 0xa0, 0x86, 0x2b, +- 0xf7, 0x61, 0x19, 0x8c, 0x19, 0x7e, 0xae, 0x17, 0x07, 0xe7, 0xec, 0xdf, +- 0xd9, 0xab, 0xbf, 0xe7, 0xe7, 0x3b, 0x4f, 0x3a, 0x65, 0x79, 0x72, 0xac, +- 0x24, 0x15, 0xe8, 0x6d, 0x38, 0x32, 0x11, 0x20, 0xdd, 0x76, 0x0b, 0xe7, +- 0xe1, 0x45, 0x3e, 0xcf, 0xe3, 0x26, 0x4e, 0x69, 0xa4, 0xe7, 0xec, 0x3a, +- 0xe1, 0x39, 0xdc, 0x23, 0x5c, 0xa5, 0x3b, 0x45, 0xcd, 0xf4, 0x37, 0x85, +- 0x7c, 0x38, 0x25, 0x6a, 0x4b, 0xed, 0x24, 0xfb, 0x7e, 0xe1, 0x3e, 0xac, +- 0x84, 0x42, 0xe2, 0x11, 0xd2, 0xe7, 0x06, 0x21, 0x95, 0xe0, 0x77, 0xe8, +- 0xc3, 0xc2, 0x51, 0xa2, 0x39, 0x2c, 0x1b, 0xe2, 0x75, 0x82, 0xa4, 0x37, +- 0x18, 0x92, 0x3e, 0x84, 0x8d, 0x14, 0xff, 0x6f, 0x4d, 0xeb, 0x78, 0x34, +- 0x5b, 0x4b, 0x31, 0x92, 0x7d, 0xff, 0x32, 0xad, 0xab, 0xe2, 0x31, 0xca, +- 0x15, 0xb2, 0xbe, 0x0f, 0x3e, 0xf2, 0xb9, 0xd7, 0x63, 0xec, 0x8f, 0x40, +- 0x21, 0x1b, 0xee, 0x7f, 0x54, 0x98, 0xe6, 0xd6, 0x88, 0xb9, 0x78, 0x5d, +- 0xac, 0x2d, 0x7a, 0x12, 0xff, 0x68, 0xe6, 0x03, 0x43, 0xa8, 0xef, 0xa4, +- 0x7b, 0xa3, 0x90, 0x5d, 0xfa, 0x2e, 0x1c, 0xa2, 0x5c, 0xe2, 0xd1, 0x29, +- 0xbe, 0x8c, 0x86, 0xfb, 0x1f, 0x13, 0x1c, 0xf3, 0x95, 0xca, 0xb3, 0x18, +- 0x39, 0x5d, 0x0b, 0x25, 0xb4, 0x46, 0xb4, 0x69, 0x75, 0x92, 0x91, 0x68, +- 0xa6, 0x14, 0xe7, 0xee, 0x54, 0x86, 0xf7, 0x40, 0xf1, 0x5f, 0x00, 0xfb, +- 0x2a, 0xe7, 0x93, 0x5d, 0x48, 0x58, 0x79, 0xc5, 0xc0, 0x4d, 0x57, 0xf3, +- 0x8a, 0x4e, 0x76, 0x52, 0x8b, 0x3d, 0x44, 0xd7, 0xcb, 0x9a, 0x12, 0x9c, +- 0x86, 0xb9, 0x78, 0x40, 0xe3, 0x7b, 0x3a, 0x76, 0x95, 0xcd, 0x90, 0xa4, +- 0xb3, 0xac, 0x90, 0xaa, 0xd5, 0x99, 0x56, 0x3f, 0xf9, 0xc6, 0x6f, 0xcc, +- 0x81, 0xb8, 0xac, 0xbd, 0x57, 0xf0, 0x93, 0xbc, 0xe0, 0x73, 0x16, 0xbf, +- 0x2c, 0xff, 0x9a, 0x70, 0xe8, 0xbf, 0x31, 0xbf, 0x1d, 0x87, 0x6f, 0x71, +- 0xd1, 0x99, 0xaa, 0xd3, 0xd1, 0x37, 0x3c, 0xba, 0xc3, 0x6c, 0x56, 0x1d, +- 0x14, 0xab, 0x54, 0x8a, 0xed, 0xde, 0xc4, 0xa5, 0x4e, 0xb7, 0x78, 0xbd, +- 0x33, 0xd8, 0xfb, 0x51, 0xc1, 0x4d, 0x7a, 0x46, 0xdf, 0xb6, 0x62, 0xc2, +- 0xf9, 0x21, 0xd9, 0x5a, 0x0d, 0xc5, 0x55, 0x14, 0x5b, 0x7a, 0x2f, 0x50, +- 0x2e, 0xba, 0x25, 0xe6, 0xfe, 0xe3, 0x1a, 0xdd, 0xf1, 0x55, 0x37, 0x1e, +- 0xbc, 0x69, 0x36, 0xd1, 0x40, 0xb1, 0xdd, 0x8f, 0xd3, 0xf1, 0x1e, 0x8c, +- 0x94, 0x6b, 0xc9, 0x0e, 0x9f, 0xaf, 0xec, 0x56, 0x5b, 0x7a, 0x2f, 0xa6, +- 0x17, 0x53, 0x2c, 0xc1, 0x67, 0x85, 0x4e, 0xb5, 0x6f, 0x9b, 0x38, 0x71, +- 0xab, 0x07, 0x71, 0x92, 0xab, 0x2c, 0x5f, 0x49, 0xe3, 0xd3, 0xc5, 0xaa, +- 0x5a, 0x59, 0x2d, 0xb5, 0x0e, 0xc9, 0x52, 0xeb, 0x70, 0x0d, 0xc5, 0xe1, +- 0xf3, 0x37, 0x0a, 0x9c, 0xba, 0x31, 0x92, 0xa8, 0x11, 0x6e, 0x9c, 0xe9, +- 0x4b, 0x90, 0x9d, 0xb4, 0xa4, 0xdc, 0x3a, 0xc5, 0x8f, 0x51, 0x01, 0x49, +- 0x4d, 0x60, 0xe7, 0x0c, 0x1e, 0x19, 0xd1, 0x7a, 0x61, 0xcc, 0xb1, 0x0d, +- 0xb5, 0x63, 0x64, 0xae, 0x0f, 0x46, 0x59, 0x42, 0x3e, 0x40, 0xcc, 0x97, +- 0x91, 0x72, 0xe9, 0xed, 0xdd, 0xf9, 0xc2, 0x5d, 0x2e, 0xdb, 0x87, 0x89, +- 0xff, 0xec, 0xa4, 0x0f, 0x1e, 0xd6, 0xf3, 0x69, 0x92, 0x51, 0x3b, 0x9e, +- 0x2f, 0x47, 0x29, 0xde, 0x69, 0x24, 0x17, 0x95, 0xe2, 0x45, 0x88, 0xec, +- 0x4b, 0xc6, 0xc6, 0x09, 0xe5, 0x20, 0xc5, 0x85, 0x5c, 0x9e, 0x40, 0x51, +- 0x32, 0xe0, 0xa7, 0xfc, 0xfd, 0x6a, 0x35, 0x06, 0x0c, 0xd2, 0xa7, 0x62, +- 0x24, 0x81, 0x93, 0x0e, 0xa0, 0xa3, 0x59, 0x8f, 0xec, 0x6d, 0x26, 0x7d, +- 0x34, 0x96, 0xdc, 0xd8, 0x3e, 0xd1, 0x84, 0x07, 0xa6, 0x3c, 0xd8, 0x3a, +- 0x61, 0xe2, 0x52, 0x8c, 0x6d, 0x43, 0xe9, 0x27, 0x12, 0xbb, 0xeb, 0x48, +- 0xae, 0xb7, 0xc6, 0x22, 0x09, 0xb7, 0x70, 0xa2, 0xb6, 0xd4, 0x47, 0x38, +- 0x20, 0xc9, 0x7e, 0xa1, 0xd1, 0x1c, 0xa1, 0x9d, 0xda, 0xed, 0x48, 0x05, +- 0x64, 0xb8, 0x4a, 0x5e, 0x8a, 0x25, 0xec, 0xc7, 0x7c, 0xef, 0xeb, 0xd8, +- 0x58, 0xe3, 0x85, 0x94, 0x91, 0x91, 0x23, 0x0c, 0x80, 0x45, 0x35, 0xe8, +- 0x69, 0x75, 0xd0, 0x7f, 0xc0, 0x37, 0x3b, 0xd9, 0xe2, 0x3b, 0x44, 0xf1, +- 0x75, 0x4b, 0xd6, 0xc1, 0xeb, 0x30, 0x66, 0xa0, 0xb9, 0xfd, 0x78, 0x9a, +- 0xe2, 0xf5, 0x43, 0x14, 0x7f, 0x8e, 0x94, 0xcb, 0x82, 0xe3, 0x89, 0xc5, +- 0x4f, 0x96, 0x78, 0xcb, 0x12, 0x6f, 0x59, 0xe2, 0x8b, 0xe2, 0xc2, 0xd1, +- 0x2c, 0xf3, 0xf1, 0x6b, 0xf2, 0xd1, 0x04, 0xf1, 0xee, 0xc6, 0x66, 0xa2, +- 0xf7, 0xc1, 0xa9, 0x3a, 0x6c, 0x23, 0x7a, 0x8b, 0x9a, 0xa2, 0x3d, 0x27, +- 0x4c, 0xec, 0x8f, 0x29, 0xc6, 0x4f, 0x29, 0x10, 0x39, 0x5a, 0x4d, 0xb3, +- 0x4f, 0x63, 0x9e, 0x29, 0x5e, 0x39, 0x2c, 0x9e, 0xf7, 0x26, 0xe1, 0xc6, +- 0x20, 0x3d, 0x33, 0x30, 0x85, 0xcf, 0x1c, 0xc4, 0x93, 0x9b, 0x78, 0xdc, +- 0xa7, 0x29, 0x89, 0x1b, 0x28, 0xae, 0x9f, 0x53, 0x23, 0x95, 0x73, 0x12, +- 0x7e, 0x9f, 0xe4, 0x31, 0xcc, 0xf2, 0xb8, 0x89, 0xf8, 0x79, 0x80, 0xf0, +- 0x4e, 0x3d, 0xc5, 0xa5, 0xc2, 0x81, 0x48, 0xf4, 0x97, 0xc4, 0x7b, 0xa4, +- 0x44, 0xb4, 0x8f, 0xda, 0xb4, 0xdf, 0xc7, 0xb4, 0xc7, 0x4c, 0xdc, 0x43, +- 0xb4, 0x1f, 0x26, 0xda, 0x07, 0xb3, 0x2c, 0x0f, 0xce, 0x3b, 0x36, 0xfd, +- 0x47, 0xca, 0xbc, 0xee, 0x97, 0xf1, 0x30, 0x4f, 0x7f, 0x13, 0x36, 0x4e, +- 0xcd, 0xcb, 0xcb, 0x34, 0xbf, 0xad, 0x1d, 0x33, 0xff, 0x84, 0x64, 0xb6, +- 0xb8, 0xc4, 0x72, 0x83, 0x51, 0xab, 0x47, 0x0e, 0x6e, 0xc1, 0x7d, 0x0e, +- 0x78, 0xbc, 0x58, 0x50, 0xe2, 0x5c, 0x10, 0xc2, 0x31, 0xd2, 0xef, 0x71, +- 0xca, 0x67, 0xcf, 0x97, 0xaf, 0xcd, 0x6f, 0xac, 0xeb, 0x49, 0xd2, 0xb1, +- 0x92, 0x37, 0x28, 0xb6, 0xa5, 0xca, 0x49, 0xec, 0x9e, 0x42, 0x72, 0x56, +- 0xfb, 0x6f, 0x14, 0x60, 0x16, 0x91, 0x7d, 0xd5, 0x26, 0xfd, 0xaa, 0x07, +- 0x9b, 0x66, 0x02, 0x18, 0x2a, 0xaf, 0x41, 0x96, 0xe2, 0xcd, 0x36, 0x8a, +- 0xcf, 0x1f, 0xc7, 0x92, 0x5b, 0x7d, 0x88, 0x90, 0x7e, 0x03, 0xb8, 0x8f, +- 0x9e, 0xd9, 0x37, 0xc5, 0x3c, 0xf8, 0xab, 0x7a, 0x0e, 0x60, 0x0b, 0x5d, +- 0xdb, 0x33, 0x25, 0xe3, 0x25, 0xed, 0x49, 0xc2, 0x34, 0x36, 0xc6, 0xb8, +- 0x27, 0x0b, 0x3f, 0xb9, 0x27, 0x61, 0xc0, 0x48, 0xf4, 0x25, 0xfa, 0xbd, +- 0xb9, 0xec, 0xf1, 0x8d, 0x4c, 0xe2, 0x7b, 0x8b, 0x75, 0x1f, 0x16, 0x10, +- 0x1e, 0xbb, 0x4b, 0x8b, 0x90, 0xdd, 0x3b, 0x31, 0x5c, 0x76, 0xe0, 0x3b, +- 0x33, 0x1e, 0x3c, 0x34, 0xf1, 0x99, 0x59, 0x13, 0x77, 0xe2, 0x8e, 0x56, +- 0x0f, 0x1e, 0x9c, 0x49, 0x62, 0xef, 0x14, 0x42, 0xb5, 0xb1, 0x31, 0x8a, +- 0xdd, 0x76, 0x3e, 0xa8, 0x23, 0xde, 0x1f, 0x9b, 0xf2, 0xfa, 0x06, 0x0f, +- 0xb0, 0x0c, 0xd6, 0x04, 0xdd, 0x40, 0xa5, 0x36, 0x26, 0x61, 0xb3, 0x26, +- 0x2d, 0xa8, 0x25, 0x43, 0x7f, 0x92, 0xe6, 0x9b, 0x86, 0xf4, 0xda, 0x62, +- 0x44, 0x0e, 0x36, 0x4b, 0x95, 0xdc, 0x02, 0x34, 0xe1, 0xa1, 0xb9, 0x24, +- 0xc6, 0xc8, 0x46, 0xb7, 0x4f, 0x8c, 0x7c, 0xaf, 0x91, 0x62, 0x88, 0xaf, +- 0x43, 0x19, 0x7c, 0x53, 0xe8, 0x28, 0x44, 0xdc, 0xd8, 0x36, 0xe3, 0xf5, +- 0x6d, 0x3d, 0x60, 0xae, 0x66, 0x7b, 0xba, 0x77, 0xae, 0x09, 0xf7, 0x4f, +- 0xd1, 0xb5, 0x09, 0xb6, 0x61, 0xb2, 0xb5, 0x48, 0x2d, 0xf1, 0x16, 0x4e, +- 0xba, 0x09, 0x33, 0x49, 0xb1, 0x3a, 0x92, 0x87, 0x1b, 0x5b, 0x2c, 0x5b, +- 0xf0, 0x63, 0xf3, 0x94, 0x89, 0xb3, 0x5a, 0x14, 0x39, 0xb2, 0xeb, 0x83, +- 0x53, 0xca, 0xe5, 0x6e, 0xc2, 0x3b, 0xef, 0x49, 0xca, 0xc1, 0x56, 0x29, +- 0x89, 0xa6, 0xe5, 0x14, 0xe3, 0x9b, 0x4c, 0xf3, 0x9e, 0x8e, 0xb6, 0xa1, +- 0xb7, 0x88, 0xe6, 0x46, 0x7d, 0x11, 0x2a, 0x8d, 0x4a, 0x8e, 0xb0, 0xf3, +- 0x70, 0x8d, 0xe3, 0x46, 0x9c, 0x59, 0x48, 0x7a, 0x06, 0xc7, 0xf2, 0x80, +- 0xaf, 0x29, 0x63, 0xe7, 0xb8, 0x26, 0xb2, 0x93, 0xc6, 0x4c, 0xd0, 0xd7, +- 0x58, 0x82, 0xaf, 0xa6, 0x04, 0xbc, 0x40, 0xf1, 0x65, 0xc1, 0xf2, 0xdf, +- 0x98, 0xa9, 0x26, 0x0b, 0x13, 0xfa, 0x5e, 0x9c, 0x54, 0x8c, 0x0a, 0x94, +- 0xbd, 0x14, 0x2a, 0xf1, 0xc4, 0x9c, 0xd3, 0x77, 0x98, 0xf0, 0x5f, 0x93, +- 0x1a, 0xc5, 0x1e, 0xd2, 0xe7, 0x0e, 0xb2, 0x85, 0xbf, 0x27, 0x7c, 0xf2, +- 0x58, 0x26, 0x1c, 0xd2, 0x44, 0x3f, 0x4d, 0x0c, 0xec, 0x2a, 0x51, 0xcc, +- 0x77, 0xac, 0xa5, 0x20, 0xa6, 0x44, 0x29, 0xad, 0x21, 0x9d, 0x71, 0xc1, +- 0x58, 0x68, 0xeb, 0xe4, 0xfe, 0xec, 0x71, 0xd3, 0xa7, 0xaa, 0xf9, 0x12, +- 0xe9, 0xec, 0xe1, 0xb2, 0x17, 0xc3, 0x84, 0x07, 0x16, 0x10, 0x8e, 0x7c, +- 0x90, 0xec, 0x62, 0xfb, 0x84, 0x44, 0xf4, 0xf1, 0xb8, 0x24, 0x92, 0x8b, +- 0x6c, 0x3c, 0xfa, 0xd0, 0x0c, 0xdb, 0x25, 0xd9, 0x11, 0xd9, 0xe2, 0x31, +- 0xca, 0xf9, 0xcf, 0xff, 0x16, 0x06, 0x51, 0xfc, 0xc6, 0xd5, 0xdc, 0x6f, +- 0xcb, 0x63, 0x64, 0x8a, 0x79, 0x56, 0x0e, 0xc2, 0x91, 0xc4, 0x2d, 0xda, +- 0xaf, 0x28, 0x27, 0x30, 0xef, 0x84, 0x83, 0xa7, 0xa2, 0x94, 0x57, 0x08, +- 0xdb, 0xc4, 0x2e, 0x99, 0x5b, 0x02, 0x2c, 0x03, 0xe6, 0xe7, 0x66, 0x89, +- 0xf3, 0x67, 0x13, 0xe1, 0xdf, 0xff, 0x77, 0xbb, 0xdb, 0x64, 0xa6, 0x2c, +- 0x3c, 0x4b, 0x38, 0x9b, 0xec, 0x29, 0x75, 0xd5, 0x7e, 0x1e, 0x34, 0xcf, +- 0x04, 0x38, 0x5f, 0x37, 0x21, 0x75, 0xd5, 0x16, 0xd8, 0x96, 0xb0, 0x58, +- 0xeb, 0xd8, 0xf9, 0xa0, 0x1f, 0x6c, 0x0f, 0xd1, 0x6b, 0xec, 0xc1, 0x43, +- 0x34, 0xf9, 0xb1, 0x75, 0x8e, 0xed, 0xd7, 0xfc, 0x64, 0xb1, 0xfe, 0x2f, +- 0xe6, 0x95, 0x95, 0xea, 0xc1, 0x5f, 0xe1, 0xeb, 0x74, 0x3d, 0x80, 0xef, +- 0x90, 0x1f, 0xdd, 0x47, 0x7c, 0x6e, 0xed, 0x7c, 0xc0, 0xf2, 0xdb, 0xad, +- 0xe5, 0xdf, 0xa3, 0xeb, 0x2c, 0xef, 0x6e, 0x8a, 0x73, 0x1a, 0xf6, 0x65, +- 0x2b, 0x9c, 0x87, 0xc8, 0xe6, 0xe3, 0xf8, 0x4b, 0x8a, 0xb3, 0xc7, 0xca, +- 0x8c, 0xc9, 0x12, 0x16, 0x1e, 0xfb, 0x61, 0xb9, 0x1d, 0x3f, 0x20, 0x9f, +- 0x7c, 0x9e, 0x62, 0xee, 0xf7, 0x2d, 0x9c, 0xe6, 0x14, 0x8f, 0xa6, 0x55, +- 0x3c, 0x4d, 0x58, 0x7f, 0x5f, 0x21, 0x84, 0x23, 0xe9, 0xf0, 0xde, 0x0b, +- 0x50, 0x5e, 0x20, 0x79, 0xf9, 0xf6, 0x52, 0x8d, 0x76, 0x38, 0xad, 0xe4, +- 0x81, 0xa0, 0x6f, 0x4f, 0xc1, 0xef, 0x1b, 0x49, 0x07, 0x7c, 0x23, 0x84, +- 0x81, 0x76, 0xa6, 0x5b, 0x7c, 0x3b, 0x0b, 0xcb, 0x11, 0x6a, 0x82, 0xb1, +- 0x88, 0x72, 0xc2, 0x7d, 0x13, 0x1b, 0x90, 0x6a, 0xb4, 0xe3, 0xfc, 0x03, +- 0x53, 0x1c, 0x83, 0xdb, 0x52, 0x37, 0x3a, 0xbe, 0x5e, 0xd5, 0xb7, 0x1f, +- 0x43, 0x74, 0xad, 0xa1, 0x03, 0xbe, 0x37, 0xad, 0x58, 0x0b, 0x3c, 0x4f, +- 0xb6, 0xf5, 0x50, 0xc7, 0x6f, 0xcc, 0x64, 0xd5, 0xb6, 0x7e, 0x30, 0xe9, +- 0xa4, 0xf8, 0x6a, 0x9a, 0x47, 0x3b, 0x04, 0x02, 0x1d, 0xdd, 0x30, 0x9a, +- 0xe6, 0x6b, 0xc8, 0x64, 0xbe, 0xb9, 0x83, 0x22, 0x94, 0x7a, 0x0b, 0x12, +- 0x0b, 0x28, 0xb5, 0x74, 0xac, 0xae, 0xde, 0x93, 0xf1, 0x9d, 0x09, 0x37, +- 0x52, 0x4d, 0x7e, 0xcc, 0x12, 0x36, 0xd9, 0x68, 0xc5, 0xa2, 0xb6, 0xd3, +- 0xc7, 0xa9, 0x96, 0x09, 0x7d, 0xc3, 0x4f, 0xbc, 0x26, 0x21, 0x77, 0x10, +- 0x90, 0xa8, 0xd2, 0xc4, 0xbf, 0x73, 0x73, 0x51, 0xec, 0x2e, 0xff, 0xd8, +- 0x61, 0xe7, 0x13, 0x25, 0x9f, 0xc4, 0x4f, 0x28, 0x2f, 0xd2, 0xbd, 0xec, +- 0x9b, 0x66, 0xc8, 0xb2, 0x33, 0x81, 0xc7, 0x97, 0x45, 0xf6, 0xfe, 0x4f, +- 0xc7, 0x75, 0xc4, 0x17, 0xc9, 0x2a, 0x6b, 0xd5, 0x8e, 0x0d, 0xd7, 0xa9, +- 0x0f, 0xe2, 0x2f, 0xfd, 0x2c, 0xcb, 0x61, 0x91, 0xa5, 0x3a, 0xf5, 0x8c, +- 0x0b, 0x0d, 0x41, 0x35, 0x8b, 0x17, 0xfa, 0xf8, 0x5a, 0xc0, 0xf7, 0x44, +- 0x3a, 0xe9, 0x08, 0xa8, 0xf0, 0xbb, 0xf4, 0x6e, 0xf1, 0x04, 0x61, 0xc0, +- 0x89, 0x74, 0x8f, 0x98, 0x28, 0xdc, 0x29, 0x8c, 0xfc, 0x37, 0x85, 0x31, +- 0x9b, 0x12, 0x46, 0xa1, 0x9f, 0x3e, 0x37, 0x88, 0xc9, 0xc2, 0xb0, 0xd8, +- 0x5d, 0xe0, 0x79, 0x49, 0x27, 0x34, 0xf7, 0x0f, 0x29, 0xc6, 0xfe, 0x80, +- 0x62, 0xec, 0x31, 0x8a, 0xb1, 0xcf, 0x93, 0x5d, 0x7f, 0xff, 0x2a, 0x96, +- 0x65, 0x5b, 0x4e, 0x32, 0x06, 0xf1, 0xfd, 0xbc, 0xf4, 0x12, 0xe9, 0x95, +- 0x65, 0xf6, 0x13, 0xb2, 0x61, 0x96, 0xc5, 0x7f, 0xe6, 0x9c, 0x40, 0xfa, +- 0xf8, 0xd0, 0xb2, 0xd9, 0xc7, 0x97, 0x31, 0x66, 0x1a, 0x16, 0x3b, 0x98, +- 0xae, 0x5a, 0xaa, 0xdb, 0x55, 0xc2, 0x21, 0xd9, 0x61, 0xb1, 0xb1, 0xc0, +- 0xd7, 0xf7, 0xe1, 0x3e, 0xaa, 0xff, 0xb6, 0xc6, 0xc2, 0x89, 0x6e, 0xc2, +- 0x48, 0x17, 0x54, 0x73, 0x71, 0x34, 0x46, 0x98, 0xe1, 0xc6, 0x2b, 0x54, +- 0xab, 0x22, 0xb9, 0x2d, 0xae, 0xe4, 0xf3, 0x76, 0x5e, 0xcd, 0xa5, 0xc1, +- 0x75, 0x3a, 0x1a, 0x9c, 0xaa, 0x72, 0x24, 0x89, 0xf0, 0xde, 0xb8, 0x03, +- 0x46, 0x8d, 0xee, 0xc2, 0x80, 0x55, 0x17, 0xae, 0x41, 0x66, 0x42, 0xe0, +- 0x65, 0xf2, 0x01, 0x17, 0xc9, 0xe8, 0x50, 0x27, 0x3e, 0x23, 0xb5, 0x0a, +- 0xaa, 0xe3, 0x4f, 0x9f, 0xa5, 0x9c, 0x73, 0x17, 0xe5, 0xd6, 0x89, 0xec, +- 0x0a, 0x04, 0x3b, 0x64, 0x34, 0x74, 0x38, 0xf1, 0x8d, 0xd2, 0xef, 0xe3, +- 0x4c, 0x63, 0xe4, 0xe0, 0x0b, 0xf0, 0xf8, 0x5e, 0x9a, 0x64, 0x7a, 0xf0, +- 0xbd, 0x3a, 0xaa, 0xd7, 0xb6, 0x12, 0x4e, 0x1a, 0x27, 0x1a, 0x7a, 0x3a, +- 0x22, 0x3d, 0xb7, 0x09, 0xf8, 0x6b, 0xf5, 0x1a, 0x8c, 0xb7, 0xfa, 0xe0, +- 0x57, 0x53, 0xe2, 0xd5, 0x02, 0xe5, 0x0d, 0xc7, 0x37, 0xc5, 0x5b, 0xb3, +- 0x3a, 0xf6, 0x96, 0xfb, 0xc5, 0x2f, 0x66, 0x65, 0x90, 0x4e, 0x28, 0x3e, +- 0x69, 0xc8, 0x10, 0x5d, 0x2e, 0xc2, 0x42, 0x2f, 0xdf, 0x21, 0x70, 0x9d, +- 0x9a, 0xc4, 0x77, 0x56, 0xb0, 0xcd, 0xdb, 0xb1, 0x2b, 0x98, 0x51, 0x42, +- 0x49, 0x47, 0xb7, 0x08, 0x52, 0xec, 0x6a, 0xc8, 0xf4, 0x88, 0x06, 0xc2, +- 0x9e, 0x0b, 0xa7, 0x37, 0x88, 0x05, 0x25, 0xc6, 0x9a, 0xf0, 0x2f, 0x24, +- 0xd9, 0x2c, 0x2c, 0x7d, 0x20, 0xd9, 0x18, 0xdf, 0xc5, 0xb6, 0x43, 0x39, +- 0x4a, 0xf6, 0xfd, 0x7a, 0x32, 0x89, 0x5b, 0x3b, 0xd6, 0x20, 0x64, 0xd9, +- 0xc7, 0xb0, 0xd8, 0x47, 0xf2, 0x4b, 0x5a, 0xfd, 0x07, 0xbf, 0xef, 0xc0, +- 0x24, 0x5c, 0x7e, 0x1d, 0x21, 0x89, 0x72, 0x43, 0xa9, 0x23, 0x32, 0xf8, +- 0x96, 0xe8, 0x15, 0xa3, 0x85, 0x80, 0x2f, 0x9d, 0x86, 0xbf, 0x8e, 0x74, +- 0x9c, 0x26, 0x1d, 0xef, 0x21, 0x1d, 0xef, 0xf9, 0x12, 0x1d, 0xef, 0x24, +- 0x1d, 0xef, 0x2f, 0xfc, 0x9d, 0xa5, 0x33, 0xa7, 0xae, 0x63, 0x94, 0x72, +- 0xee, 0x78, 0xab, 0xcd, 0x4f, 0x81, 0x30, 0xea, 0x9e, 0x58, 0xaf, 0x13, +- 0x1e, 0x9d, 0x62, 0x66, 0x2f, 0x3d, 0xd3, 0x5c, 0xb5, 0x65, 0xbf, 0xef, +- 0xc9, 0x74, 0xb7, 0x78, 0xd2, 0xf2, 0x2b, 0xc6, 0x8d, 0x49, 0x34, 0xaa, +- 0x3d, 0x34, 0x17, 0xdb, 0xca, 0x9d, 0x02, 0x4f, 0xb1, 0xbd, 0x7c, 0x93, +- 0x04, 0xcf, 0x36, 0x93, 0x12, 0x28, 0xb2, 0xdd, 0xf4, 0xd3, 0x6f, 0xb6, +- 0x9d, 0x0d, 0xa2, 0xb1, 0xf8, 0x45, 0xfb, 0x81, 0xdf, 0xa9, 0xb3, 0xfd, +- 0xb0, 0x1d, 0x0d, 0x0b, 0x67, 0x91, 0x7c, 0x96, 0xe6, 0x1f, 0x21, 0xba, +- 0x77, 0xa6, 0xf7, 0x3b, 0x99, 0x36, 0x59, 0x67, 0x3b, 0x62, 0xfb, 0xb9, +- 0x48, 0xb4, 0xb2, 0xcd, 0x5f, 0xed, 0xd9, 0xd0, 0xdf, 0xef, 0x4a, 0x50, +- 0xb7, 0x38, 0x6d, 0x1e, 0x38, 0x87, 0x73, 0xce, 0xe6, 0x78, 0xea, 0xb7, +- 0x6a, 0xba, 0x63, 0x57, 0x73, 0x39, 0xe7, 0x75, 0xc8, 0x0b, 0xf4, 0x80, +- 0xfe, 0x9d, 0xd6, 0x2b, 0x34, 0xdf, 0x10, 0xb4, 0x15, 0x90, 0x03, 0xfa, +- 0xa4, 0x3e, 0xd9, 0x4a, 0xf1, 0x96, 0xe6, 0x94, 0x33, 0x80, 0x9a, 0x11, +- 0xd8, 0x99, 0x10, 0x84, 0x47, 0x17, 0x91, 0xbf, 0xc1, 0xf0, 0xe8, 0x4a, +- 0x4f, 0x92, 0xee, 0x2d, 0x25, 0x7c, 0xbe, 0x58, 0xdf, 0x06, 0x33, 0x0b, +- 0xb9, 0x41, 0x1f, 0xc4, 0x27, 0xa3, 0x61, 0xff, 0x79, 0x28, 0xa9, 0xb3, +- 0x92, 0x52, 0xa1, 0x3c, 0x35, 0x34, 0x22, 0x94, 0xc1, 0xcb, 0x42, 0x49, +- 0x96, 0xac, 0x1e, 0xcf, 0x36, 0xb4, 0x5b, 0x58, 0x7c, 0x10, 0xd1, 0x02, +- 0x70, 0x1b, 0x01, 0xbc, 0x7b, 0x6e, 0x26, 0x9b, 0xd4, 0x3e, 0xe2, 0xd8, +- 0x9e, 0x3c, 0x43, 0x54, 0x2f, 0xce, 0x70, 0xcf, 0x68, 0x5b, 0xb5, 0x67, +- 0x34, 0x68, 0xf5, 0x8c, 0xce, 0x4b, 0x4a, 0x62, 0xbe, 0x67, 0x74, 0x05, +- 0x3c, 0x97, 0xd2, 0xef, 0xad, 0xce, 0xb7, 0xb4, 0x3a, 0x5f, 0x5b, 0x01, +- 0x22, 0x9a, 0x31, 0xcc, 0x1a, 0xd5, 0x43, 0xfc, 0x26, 0x1d, 0xae, 0x88, +- 0xda, 0x73, 0x18, 0x21, 0x44, 0xa9, 0xde, 0xbd, 0x9e, 0xf2, 0xa0, 0x3b, +- 0xb3, 0x03, 0x33, 0x9a, 0xd2, 0x37, 0x00, 0xb6, 0x9d, 0x6e, 0xec, 0xa3, +- 0x18, 0xba, 0xb7, 0xcc, 0xf5, 0xc8, 0xb0, 0x38, 0xcb, 0x76, 0xe3, 0xb4, +- 0xa5, 0x66, 0xaf, 0xff, 0x70, 0x75, 0xfd, 0x21, 0x6b, 0xfd, 0x0b, 0x92, +- 0xd2, 0x5f, 0x5d, 0x5f, 0xfb, 0x33, 0xa1, 0xa4, 0x68, 0xfd, 0x9e, 0x3d, +- 0xb4, 0xbe, 0x4b, 0xe5, 0xb5, 0x1f, 0xe6, 0xb5, 0xe9, 0x73, 0x08, 0xd7, +- 0x93, 0xdd, 0xbc, 0x57, 0x90, 0xc5, 0xbb, 0xb9, 0x35, 0xd8, 0x35, 0xb3, +- 0x06, 0x3b, 0xc9, 0xdf, 0xb6, 0x6a, 0x0d, 0x54, 0xa7, 0xa1, 0xde, 0xa7, +- 0xe2, 0xb2, 0x23, 0x22, 0xa4, 0xf5, 0xed, 0x2d, 0x84, 0x41, 0x4e, 0x34, +- 0xcb, 0xf8, 0xd4, 0x1c, 0x50, 0xd7, 0xf4, 0x39, 0x91, 0xfc, 0x7d, 0x0f, +- 0xfe, 0x5c, 0x22, 0xff, 0x7d, 0x67, 0x81, 0x40, 0xd2, 0x63, 0xd5, 0x1c, +- 0x09, 0xe1, 0x29, 0xfe, 0xd8, 0x69, 0xdb, 0x7b, 0x2b, 0x7c, 0x8d, 0x68, +- 0x68, 0x50, 0x6f, 0x40, 0x43, 0xa3, 0x6c, 0x38, 0xa8, 0x8e, 0x59, 0x4f, +- 0x21, 0xd1, 0xcc, 0xf5, 0x51, 0x3c, 0x35, 0x71, 0x65, 0xf9, 0xdf, 0x9b, +- 0x89, 0xeb, 0xf8, 0x39, 0x02, 0x15, 0x56, 0x4c, 0xfc, 0xb2, 0x39, 0xe2, +- 0xe4, 0xbf, 0x6d, 0x54, 0x97, 0xd6, 0x51, 0xf0, 0xed, 0xc1, 0x9e, 0xac, +- 0x92, 0xda, 0x43, 0x75, 0xe5, 0xfe, 0x48, 0x5b, 0xcf, 0x26, 0x51, 0x83, +- 0xd0, 0xc2, 0xf0, 0xe0, 0x00, 0x92, 0xcd, 0xf5, 0x55, 0x3a, 0x1e, 0x46, +- 0xb3, 0x8b, 0x9e, 0xe3, 0x79, 0xae, 0xb1, 0xa7, 0x22, 0xd9, 0x13, 0xdf, +- 0xe7, 0xef, 0x57, 0xef, 0xcb, 0xbf, 0xa3, 0x4f, 0xae, 0xfa, 0xaf, 0x4b, +- 0xbf, 0xec, 0xfa, 0xb1, 0x2f, 0xb9, 0xfe, 0x6f, 0xd5, 0xe7, 0x95, 0x46, +- 0xa7, 0x95, 0xfb, 0x93, 0x0e, 0xee, 0x4b, 0x3a, 0xf5, 0x42, 0xd7, 0x2e, +- 0xf5, 0x3f, 0x51, 0xcc, 0xe2, 0x7e, 0x04, 0xe7, 0xdb, 0x33, 0x56, 0x3f, +- 0xe2, 0xf8, 0x6f, 0x61, 0x4f, 0x8e, 0x1d, 0x6e, 0x51, 0x37, 0x6e, 0x98, +- 0x4d, 0xea, 0x1f, 0x51, 0x7d, 0xb2, 0x03, 0x03, 0x31, 0x0d, 0x63, 0x59, +- 0xa5, 0xef, 0x0e, 0xa8, 0xc9, 0x3b, 0x05, 0x4d, 0x54, 0x72, 0x0b, 0x69, +- 0xbc, 0x7a, 0x4f, 0x33, 0xa8, 0xe6, 0xaa, 0xa0, 0x96, 0x62, 0x8f, 0x53, +- 0xf5, 0xcb, 0x28, 0x05, 0x64, 0x67, 0x29, 0x28, 0xd7, 0x94, 0x5a, 0xe4, +- 0x5a, 0x1a, 0xe7, 0x1d, 0x57, 0x2e, 0xdf, 0x81, 0x1d, 0xb8, 0xbc, 0xdc, +- 0x63, 0x34, 0xeb, 0x8a, 0xbf, 0x59, 0xda, 0x81, 0x5d, 0x31, 0x7e, 0xb6, +- 0x9b, 0x6a, 0x2f, 0x88, 0xc6, 0x0c, 0x21, 0x5c, 0x5d, 0x60, 0x37, 0xd5, +- 0x97, 0x4b, 0x1c, 0x6a, 0xcf, 0xaf, 0x85, 0x53, 0x76, 0x97, 0x20, 0x7c, +- 0x19, 0x07, 0x0e, 0x76, 0xc2, 0xed, 0x5e, 0xa1, 0x0c, 0x9e, 0x10, 0xc3, +- 0x78, 0x36, 0x16, 0xe9, 0xdb, 0x2c, 0x42, 0xb2, 0x87, 0xee, 0xb9, 0x32, +- 0x10, 0x72, 0xc6, 0x70, 0xbb, 0x56, 0x28, 0x41, 0x87, 0x48, 0x62, 0x40, +- 0x55, 0xb5, 0x71, 0xc8, 0xb4, 0x26, 0x44, 0x6d, 0x46, 0xb9, 0x7c, 0x96, +- 0xb0, 0xd1, 0x95, 0xa5, 0xc3, 0xe8, 0x58, 0x1e, 0xd9, 0xdb, 0xef, 0x50, +- 0x65, 0xc2, 0x6c, 0xc2, 0x99, 0xf1, 0xe2, 0xa6, 0x03, 0xf3, 0xfd, 0x19, +- 0xd3, 0xfc, 0x38, 0x56, 0xb9, 0x97, 0x44, 0x28, 0xd7, 0x97, 0xa2, 0xb2, +- 0x97, 0xf0, 0x79, 0xdb, 0x01, 0xc6, 0x4b, 0x9c, 0x0f, 0x2a, 0x64, 0x37, +- 0xed, 0xc4, 0x63, 0x1f, 0x66, 0xd2, 0x8c, 0x9f, 0x74, 0x4c, 0x53, 0x6d, +- 0xa3, 0x8e, 0xb6, 0x50, 0xae, 0x4f, 0x60, 0x2e, 0xcd, 0x7d, 0x9c, 0x41, +- 0x92, 0x71, 0x3f, 0xd1, 0xbf, 0x81, 0xea, 0xda, 0x14, 0xc5, 0x2b, 0x96, +- 0xf1, 0x00, 0xf7, 0x6b, 0xa9, 0x96, 0xfe, 0x79, 0xd7, 0xd7, 0xc6, 0x20, +- 0xbb, 0xf5, 0xd7, 0xba, 0xae, 0x3f, 0x80, 0x46, 0xca, 0xe7, 0x3a, 0x55, +- 0x2e, 0x88, 0x46, 0x22, 0xda, 0x79, 0x44, 0x82, 0x2f, 0x93, 0x3e, 0x46, +- 0x54, 0x60, 0xa7, 0x55, 0x33, 0x3b, 0x61, 0x14, 0xd8, 0xa6, 0xe0, 0xae, +- 0xed, 0x6c, 0xc4, 0xfb, 0xb9, 0xa8, 0xd5, 0x0b, 0x32, 0xa8, 0x8e, 0x79, +- 0x49, 0x53, 0x52, 0x79, 0x7a, 0x6e, 0xa3, 0xff, 0x7f, 0xed, 0xa9, 0x8b, +- 0x43, 0xae, 0x53, 0xd9, 0xbf, 0xfe, 0xdc, 0x73, 0x96, 0x6c, 0xf4, 0xae, +- 0xc9, 0xbf, 0xf0, 0x7c, 0x12, 0xcf, 0x7b, 0x3e, 0x8a, 0x9b, 0x66, 0x82, +- 0x70, 0x65, 0x3f, 0xd5, 0xcd, 0x1f, 0x8f, 0x1a, 0x9e, 0xf3, 0x71, 0xee, +- 0xe9, 0x3a, 0xf1, 0x07, 0xf4, 0xfb, 0xe9, 0x51, 0x19, 0xb7, 0x16, 0x9b, +- 0xe1, 0x1a, 0x93, 0xc8, 0x3f, 0xd7, 0x52, 0xae, 0x72, 0xe0, 0x9e, 0xe8, +- 0x51, 0x54, 0x02, 0x0e, 0x1a, 0xb3, 0x9f, 0x7e, 0x73, 0x6f, 0xea, 0x71, +- 0x6c, 0xf6, 0xcf, 0x7a, 0xde, 0x8f, 0x33, 0xbd, 0x15, 0xa6, 0x97, 0x72, +- 0xe4, 0xed, 0xd8, 0x78, 0x07, 0x0c, 0x9f, 0x6e, 0xfd, 0xbb, 0x5f, 0xee, +- 0x6c, 0xc2, 0xe1, 0x5c, 0x33, 0x5e, 0xcc, 0x19, 0xee, 0x9f, 0x76, 0x46, +- 0x31, 0x38, 0x6a, 0xe2, 0x15, 0xcd, 0x18, 0xae, 0x25, 0x3b, 0x4f, 0x50, +- 0xad, 0x14, 0x5e, 0xae, 0xf8, 0x2f, 0x0b, 0x44, 0x24, 0x44, 0x86, 0x08, +- 0x2c, 0xde, 0x4d, 0xa1, 0x2b, 0x55, 0xaf, 0x47, 0xb4, 0xd7, 0x85, 0x59, +- 0x73, 0x6f, 0xa7, 0x93, 0x68, 0x00, 0xd6, 0x51, 0x4c, 0x9e, 0x4b, 0x47, +- 0x71, 0x6b, 0x44, 0xc6, 0xfa, 0xa2, 0x86, 0x17, 0xd3, 0x5e, 0xdc, 0x55, +- 0x8c, 0x13, 0x86, 0xf6, 0x13, 0xed, 0x09, 0x94, 0xd3, 0x01, 0x7c, 0xbd, +- 0xd8, 0x42, 0xf2, 0x0e, 0x62, 0x6d, 0x91, 0x31, 0x16, 0xe7, 0x67, 0xdd, +- 0xbd, 0x31, 0xde, 0x82, 0x1e, 0x8a, 0xdf, 0xb3, 0x69, 0xb8, 0xb7, 0xc7, +- 0x43, 0xe8, 0x2e, 0x46, 0x51, 0x24, 0x2c, 0x76, 0x3b, 0xcd, 0x79, 0x17, +- 0xe9, 0xa4, 0x9d, 0xea, 0xfb, 0x25, 0x11, 0x42, 0xa8, 0x45, 0xaf, 0x18, +- 0x26, 0xcc, 0x94, 0x28, 0x36, 0xe1, 0xfc, 0x18, 0xdb, 0xf9, 0x5b, 0x5d, +- 0xbb, 0x72, 0x7e, 0x84, 0x8a, 0xb8, 0x49, 0x06, 0xb6, 0x51, 0x95, 0x97, +- 0x2a, 0x12, 0xbd, 0xfb, 0x3a, 0xed, 0x7e, 0xec, 0x0d, 0xc5, 0xcf, 0xf9, +- 0x6d, 0x20, 0x3d, 0x7d, 0x72, 0x60, 0xd6, 0x73, 0x85, 0x64, 0xe0, 0xd3, +- 0x7f, 0xd4, 0xf5, 0xc6, 0x01, 0x20, 0x3a, 0xc5, 0xbc, 0x71, 0x7c, 0x0d, +- 0x27, 0x28, 0xbe, 0xb6, 0xcb, 0xf8, 0xb5, 0x49, 0xb5, 0x64, 0x68, 0x86, +- 0x7b, 0xff, 0xaa, 0x97, 0xe8, 0xf0, 0x23, 0x49, 0x6b, 0xdf, 0x56, 0xfc, +- 0xa1, 0xb9, 0x71, 0x61, 0x10, 0x5f, 0x8b, 0xd8, 0xb2, 0x7a, 0x9d, 0x74, +- 0x38, 0x3d, 0xd6, 0x8c, 0xb9, 0x31, 0xee, 0xad, 0x9c, 0xea, 0x3a, 0x34, +- 0x69, 0x62, 0x9d, 0x66, 0x78, 0x7e, 0xda, 0x79, 0x03, 0x1e, 0x38, 0x30, +- 0x72, 0xba, 0x86, 0xf4, 0x7a, 0x59, 0xbb, 0x1b, 0x8f, 0x4e, 0xe1, 0xab, +- 0xcd, 0xc0, 0x23, 0x41, 0x70, 0xff, 0x59, 0x09, 0x1d, 0x41, 0xa4, 0x67, +- 0x3b, 0x22, 0x7e, 0x55, 0x28, 0xda, 0x2b, 0x14, 0xab, 0xea, 0x08, 0x3b, +- 0xdc, 0x46, 0xb5, 0x7c, 0x0d, 0x79, 0xf0, 0x5d, 0x45, 0x27, 0xc9, 0x28, +- 0x88, 0xf2, 0x58, 0x0d, 0x24, 0xf2, 0x93, 0x0b, 0x2a, 0xd6, 0x35, 0x90, +- 0xac, 0x25, 0x21, 0x93, 0x9e, 0xdb, 0x71, 0x68, 0x74, 0x5e, 0x56, 0x5e, +- 0xdc, 0x42, 0x32, 0x7c, 0x76, 0xd4, 0xdc, 0xa1, 0xc6, 0x02, 0x24, 0x6b, +- 0x3f, 0xd1, 0x37, 0x2f, 0x27, 0x96, 0xdf, 0xbc, 0x9c, 0xee, 0xc6, 0xae, +- 0x39, 0x96, 0xdb, 0xbf, 0x47, 0x5e, 0xb3, 0x96, 0xdd, 0xad, 0x9b, 0x8c, +- 0xa2, 0xf9, 0xc0, 0x55, 0xd9, 0x31, 0x7d, 0x8f, 0x10, 0x1f, 0xdf, 0xf3, +- 0xad, 0x8c, 0x0c, 0x5e, 0x14, 0x5e, 0xa2, 0xc7, 0x4f, 0xba, 0x39, 0xeb, +- 0x62, 0x0c, 0x4e, 0x32, 0xb9, 0x2a, 0xe3, 0x20, 0xc9, 0x38, 0x38, 0xc5, +- 0xb2, 0xfe, 0x11, 0xc9, 0x1a, 0x78, 0x83, 0x70, 0xd7, 0xcd, 0xb1, 0x28, +- 0xea, 0x0f, 0x28, 0xc9, 0x66, 0x29, 0x9c, 0x68, 0x10, 0xa0, 0xea, 0x02, +- 0xed, 0xf5, 0xf8, 0x98, 0xe5, 0xac, 0x91, 0x9c, 0xbf, 0x37, 0x42, 0xfc, +- 0xac, 0xa1, 0xf9, 0xd6, 0x91, 0x9c, 0x93, 0xc4, 0xff, 0x6d, 0xd6, 0xbc, +- 0x2d, 0x34, 0xef, 0x06, 0xaa, 0x21, 0x66, 0x3d, 0x17, 0x88, 0x9e, 0xe8, +- 0xe7, 0xb4, 0x10, 0xca, 0x8e, 0x04, 0x2f, 0x52, 0xad, 0xbc, 0xd6, 0x1a, +- 0xe7, 0xa7, 0x71, 0x4c, 0xfb, 0x5b, 0xb5, 0x0e, 0xf5, 0xcb, 0x7a, 0xc7, +- 0x77, 0x83, 0x7b, 0x07, 0x06, 0xfa, 0xb1, 0x37, 0xbb, 0x81, 0x6a, 0x1e, +- 0x99, 0x30, 0xa4, 0x81, 0xef, 0xc7, 0x95, 0x68, 0xa3, 0xe0, 0xf8, 0x67, +- 0x90, 0x1f, 0x56, 0xa8, 0xde, 0x09, 0x87, 0xe6, 0x10, 0x94, 0x1d, 0x25, +- 0x99, 0xf0, 0x5e, 0x8b, 0x2c, 0x95, 0xc8, 0x5f, 0x83, 0xfd, 0x84, 0x93, +- 0x9d, 0x78, 0xb9, 0xe0, 0xc4, 0xab, 0xe9, 0x0d, 0x94, 0xe7, 0xdc, 0x84, +- 0x87, 0x0d, 0xb7, 0x73, 0xc5, 0x81, 0x1a, 0x3b, 0x26, 0x2f, 0x45, 0xef, +- 0xf8, 0xc3, 0xa8, 0xcb, 0x38, 0xfb, 0x28, 0x47, 0x6b, 0xb7, 0x91, 0x5c, +- 0xd6, 0x95, 0xf8, 0x7e, 0x0b, 0x32, 0xe9, 0x14, 0xb2, 0xd9, 0x30, 0xd5, +- 0x32, 0x4e, 0xe4, 0x9b, 0x5b, 0xac, 0xfe, 0x6c, 0x8e, 0xae, 0xe5, 0xca, +- 0x5f, 0xec, 0x1b, 0x7f, 0xab, 0xda, 0x2f, 0x1e, 0xa4, 0x9c, 0xd2, 0x4f, +- 0xd8, 0x73, 0x03, 0xc5, 0x77, 0x9b, 0xc6, 0xd9, 0x78, 0x1f, 0xf6, 0x14, +- 0xf4, 0xab, 0xf1, 0x63, 0xba, 0x60, 0xf7, 0x05, 0xb7, 0x90, 0x3c, 0xce, +- 0xa5, 0x4d, 0x3c, 0xaa, 0xb1, 0x3e, 0x29, 0x2e, 0xa5, 0xb9, 0x37, 0x68, +- 0xe2, 0x19, 0x4d, 0x70, 0xbc, 0xa1, 0x3c, 0xba, 0x01, 0x4b, 0x0a, 0x26, +- 0x4e, 0x6b, 0x2a, 0xc5, 0x2e, 0x18, 0x6e, 0xc2, 0x7e, 0x91, 0xd1, 0x7f, +- 0x31, 0xf3, 0xce, 0x21, 0xb4, 0x75, 0x02, 0x9b, 0x47, 0x25, 0xcc, 0xcd, +- 0x5c, 0xcd, 0xd1, 0x78, 0xf1, 0xf3, 0x3c, 0x9d, 0x98, 0x81, 0xb9, 0xc3, +- 0xa9, 0x2b, 0xc3, 0xbc, 0xd7, 0x32, 0x12, 0x57, 0x12, 0xb5, 0x56, 0xce, +- 0x56, 0xfb, 0x97, 0x48, 0x8a, 0x56, 0x12, 0x6d, 0xa9, 0x4f, 0x50, 0x59, +- 0x2f, 0x43, 0x09, 0xfe, 0x0c, 0x91, 0xe8, 0x20, 0xef, 0x29, 0x94, 0xed, +- 0xfc, 0xbd, 0xb4, 0x9a, 0xbf, 0xc3, 0x05, 0x8f, 0x50, 0xc7, 0x1c, 0xc8, +- 0xcf, 0x98, 0x94, 0x67, 0x05, 0x66, 0x49, 0xc1, 0x2f, 0x64, 0x77, 0xe0, +- 0xeb, 0x31, 0xd3, 0xbc, 0x2b, 0xae, 0x0e, 0x36, 0x4b, 0xf8, 0xd3, 0x06, +- 0xc2, 0x14, 0x64, 0xf7, 0x84, 0x01, 0x10, 0xda, 0xda, 0x69, 0x98, 0x32, +- 0xd5, 0x0c, 0x35, 0x3a, 0xf7, 0x1a, 0x7b, 0x45, 0x7b, 0x71, 0x83, 0xb8, +- 0xa1, 0xd8, 0x2f, 0x42, 0x87, 0xee, 0x14, 0xd1, 0xa7, 0x6c, 0xdc, 0xd6, +- 0x5a, 0xfc, 0xbc, 0x1f, 0xda, 0x43, 0x7c, 0xef, 0xd3, 0x4c, 0x3c, 0x4d, +- 0xbc, 0xed, 0x2d, 0xdb, 0xb5, 0xc8, 0xee, 0xb4, 0xcd, 0xdb, 0xa3, 0x74, +- 0xff, 0x62, 0x9a, 0xfd, 0xf1, 0x61, 0xab, 0xd7, 0xd9, 0x4c, 0xcf, 0xdc, +- 0x9c, 0x0d, 0x87, 0x06, 0x85, 0x32, 0x34, 0x0b, 0xee, 0x77, 0xb6, 0x55, +- 0x4e, 0x0a, 0xca, 0x3d, 0x12, 0xc7, 0x57, 0xf6, 0x79, 0x9b, 0xf6, 0x65, +- 0x05, 0x58, 0x71, 0x91, 0xe9, 0xbf, 0x91, 0xea, 0xbe, 0x9f, 0xa5, 0xdb, +- 0xfa, 0xdd, 0x24, 0xb6, 0xf3, 0xf1, 0x6e, 0x71, 0x89, 0xea, 0xbe, 0x57, +- 0xd3, 0xc9, 0x85, 0x75, 0xe8, 0x11, 0x17, 0x0a, 0x7d, 0xe2, 0xc3, 0x7c, +- 0x2f, 0x9c, 0x63, 0xf7, 0x8b, 0x77, 0xf3, 0x4c, 0x5b, 0xbf, 0x38, 0x33, +- 0x7b, 0xde, 0x92, 0xfd, 0x2e, 0x8d, 0xfb, 0x9a, 0xf5, 0xb5, 0xf0, 0x99, +- 0x04, 0x4f, 0x59, 0x8f, 0xdc, 0xe7, 0xb3, 0xfb, 0x43, 0xeb, 0xe2, 0x39, +- 0xd3, 0xa9, 0x72, 0xaf, 0x37, 0x68, 0xf1, 0x38, 0x43, 0x78, 0x79, 0x36, +- 0xbf, 0x41, 0x1c, 0x2e, 0xd8, 0xfc, 0x4d, 0x17, 0xd8, 0x6e, 0x65, 0xca, +- 0x0d, 0x5f, 0xcc, 0xcf, 0x06, 0xfc, 0x9d, 0x41, 0xd4, 0x58, 0xfd, 0x24, +- 0x13, 0xe3, 0x5a, 0x24, 0xf4, 0x0a, 0x82, 0x70, 0x96, 0xd8, 0xa6, 0x4d, +- 0x3c, 0xa7, 0xb9, 0x20, 0x8d, 0xcb, 0x24, 0x17, 0xb2, 0x21, 0x9f, 0x0b, +- 0x8e, 0x69, 0xae, 0x01, 0xe2, 0xb5, 0xdc, 0x67, 0x08, 0x39, 0xf8, 0xfb, +- 0x17, 0x6d, 0xcd, 0x45, 0x79, 0x80, 0xfb, 0xe3, 0x6f, 0xd6, 0xd8, 0x36, +- 0xc7, 0xf9, 0x68, 0xbe, 0xa7, 0x4d, 0x39, 0xb6, 0x93, 0x7b, 0xd9, 0x6e, +- 0xcc, 0xe5, 0x6a, 0xb8, 0xc5, 0xe0, 0xae, 0xe9, 0x34, 0x71, 0x4e, 0x73, +- 0x52, 0x5d, 0xf2, 0x10, 0xe5, 0x26, 0x07, 0x64, 0xf5, 0x6e, 0x94, 0x26, +- 0x9d, 0x0e, 0xde, 0x73, 0xfa, 0x59, 0x8c, 0x7b, 0x00, 0xc0, 0x7e, 0xe2, +- 0xe1, 0x99, 0x5c, 0x88, 0xea, 0x7f, 0xb9, 0x5a, 0x43, 0xfc, 0x01, 0x8e, +- 0xe7, 0x24, 0xd1, 0xac, 0x43, 0x4a, 0xac, 0x34, 0xf1, 0xc9, 0xf2, 0x48, +- 0xf4, 0x32, 0xc5, 0x2f, 0x3f, 0xe5, 0xaa, 0xdd, 0x85, 0x46, 0xfc, 0x2c, +- 0xd7, 0x88, 0x57, 0x73, 0xa4, 0xc3, 0xd8, 0x48, 0xbf, 0x87, 0x62, 0xe4, +- 0xd2, 0x98, 0x0b, 0x5b, 0x23, 0x86, 0xdf, 0x83, 0x28, 0xce, 0x25, 0xae, +- 0x47, 0x2a, 0x10, 0xee, 0x19, 0x41, 0x13, 0xde, 0xcc, 0x81, 0x30, 0x04, +- 0xdc, 0x4b, 0x68, 0x8e, 0xf7, 0x62, 0xc6, 0x90, 0x0b, 0x0a, 0xd5, 0x1f, +- 0x88, 0xd7, 0xc3, 0xac, 0x39, 0x19, 0xa7, 0x1c, 0x5d, 0x6c, 0x44, 0x6f, +- 0xae, 0x09, 0xfd, 0x94, 0xab, 0x56, 0xaf, 0x8c, 0xe3, 0xdd, 0xac, 0x57, +- 0xdc, 0x94, 0x1d, 0xe9, 0xf7, 0xd3, 0x9c, 0xae, 0xe5, 0xca, 0xd0, 0xb3, +- 0x04, 0xd8, 0x64, 0x84, 0xd9, 0xbc, 0xb7, 0xfb, 0x28, 0xde, 0x1e, 0x16, +- 0x9f, 0xe1, 0x49, 0xb2, 0xc1, 0x2d, 0x9a, 0x52, 0xb9, 0x20, 0x45, 0x4e, +- 0xaf, 0x87, 0x32, 0x7c, 0x9b, 0x30, 0xa2, 0x0d, 0x14, 0x47, 0x9a, 0xed, +- 0x18, 0x61, 0x44, 0x84, 0x4c, 0x98, 0xdc, 0x09, 0xb7, 0x6a, 0xa0, 0xa7, +- 0x93, 0x65, 0xea, 0x86, 0xfb, 0x29, 0xb2, 0x1b, 0xc7, 0x17, 0xfb, 0xf3, +- 0x8d, 0x78, 0x83, 0xf2, 0xe4, 0xeb, 0x39, 0xc8, 0xb5, 0x14, 0xfb, 0x3f, +- 0xa0, 0xd8, 0x7f, 0x2a, 0x36, 0x12, 0xe2, 0x98, 0x5f, 0x88, 0xe1, 0x5b, +- 0x04, 0x83, 0x5b, 0xbc, 0xb4, 0xe6, 0x26, 0xc1, 0xeb, 0x20, 0xb9, 0x58, +- 0xe7, 0xbe, 0x9a, 0xc5, 0x0f, 0xc5, 0x61, 0xe6, 0xe9, 0xff, 0x27, 0xed, +- 0xdb, 0x6b, 0xe1, 0x69, 0x22, 0x5d, 0xce, 0xf7, 0x24, 0xaf, 0xed, 0x47, +- 0x72, 0x1d, 0x63, 0xe3, 0xc2, 0x1a, 0xbd, 0x4e, 0xbc, 0x94, 0x63, 0x9b, +- 0x33, 0xf1, 0xbc, 0xa6, 0x51, 0xcd, 0xc2, 0xb5, 0xf6, 0x10, 0xd5, 0x2d, +- 0xdc, 0x27, 0x32, 0xdc, 0x27, 0x89, 0xc2, 0xbd, 0x39, 0xfc, 0x9e, 0x0c, +- 0x69, 0x59, 0x2d, 0xa6, 0x90, 0x77, 0x3a, 0x09, 0x6b, 0x70, 0x8c, 0x65, +- 0x3f, 0x7a, 0xab, 0x4b, 0xcd, 0xc3, 0xf0, 0xea, 0x3d, 0x30, 0x2c, 0xdf, +- 0xad, 0x13, 0x0f, 0x90, 0x8d, 0xbc, 0x1c, 0xab, 0x45, 0x9e, 0xea, 0x1e, +- 0xc2, 0xdf, 0xee, 0x3f, 0xa3, 0xe7, 0x13, 0x13, 0xd8, 0x13, 0x84, 0xf4, +- 0x5d, 0x3f, 0xfe, 0x02, 0x67, 0x5d, 0x8c, 0xcb, 0xe1, 0xee, 0x8b, 0x1b, +- 0x9e, 0xf5, 0xf1, 0x3a, 0x71, 0x7b, 0xae, 0x1d, 0x17, 0x27, 0x1b, 0xc9, +- 0xbe, 0x9b, 0xb0, 0x78, 0x3c, 0x88, 0xf7, 0x88, 0x96, 0x61, 0x8d, 0xb1, +- 0xba, 0x31, 0xdc, 0x0c, 0x65, 0x88, 0xea, 0xa1, 0xbe, 0x9f, 0x0b, 0xf6, +- 0x01, 0xa5, 0xe7, 0x0e, 0xe1, 0x81, 0x1a, 0x49, 0x92, 0xec, 0x4d, 0x73, +- 0x4c, 0x6b, 0xd3, 0xbc, 0xe0, 0xfe, 0xcf, 0xdd, 0xd8, 0x3f, 0xc7, 0xb4, +- 0x9c, 0xea, 0xba, 0x61, 0x96, 0x3f, 0x4f, 0x77, 0x5d, 0x6f, 0x7d, 0xbe, +- 0x56, 0xfd, 0xac, 0x74, 0x85, 0xac, 0xcf, 0x1f, 0xd1, 0x27, 0xf7, 0x99, +- 0xc3, 0x46, 0x8d, 0xf8, 0xbe, 0x8b, 0xfb, 0xcd, 0x49, 0xf0, 0xff, 0x71, +- 0x97, 0xdd, 0xaf, 0xbb, 0x1b, 0x86, 0xd5, 0x13, 0xf9, 0xb5, 0xd5, 0x8b, +- 0x0e, 0x91, 0x1b, 0xc8, 0xc4, 0x9f, 0x4c, 0x58, 0x2b, 0x10, 0xa3, 0xc2, +- 0xbc, 0x49, 0x36, 0x16, 0xeb, 0xfd, 0x54, 0x1b, 0xc8, 0xc4, 0xaf, 0x81, +- 0x3d, 0x9d, 0x02, 0xfb, 0x55, 0x1d, 0x3f, 0x2d, 0x70, 0x0c, 0x77, 0xe2, +- 0x99, 0xb4, 0x12, 0x4a, 0x89, 0x30, 0xd5, 0xf9, 0x0e, 0x84, 0x9a, 0xfb, +- 0xb1, 0x9f, 0xf2, 0xc9, 0x6c, 0x9a, 0xf3, 0x07, 0x7d, 0x52, 0x3c, 0x6f, +- 0xa0, 0xf8, 0xf3, 0xf1, 0xa8, 0x1d, 0xef, 0x8b, 0x71, 0x65, 0xef, 0x1f, +- 0x90, 0x4e, 0x9f, 0x2b, 0xf2, 0x9c, 0x06, 0xae, 0xac, 0x64, 0x1f, 0x56, +- 0xa2, 0x29, 0xc7, 0x7d, 0x08, 0xcd, 0x70, 0x6c, 0xa1, 0xe5, 0x68, 0xad, +- 0x83, 0xd9, 0x1a, 0xf4, 0xc5, 0x7b, 0x45, 0x7f, 0xa9, 0x8f, 0xf7, 0x14, +- 0xfc, 0x0b, 0xf4, 0x3b, 0xc5, 0x9a, 0x69, 0xee, 0x09, 0x6e, 0x10, 0x7d, +- 0x25, 0xee, 0x0b, 0x0e, 0x8b, 0x6f, 0x94, 0xd8, 0xe7, 0xe7, 0xfb, 0x83, +- 0xf3, 0xfa, 0xe7, 0xbe, 0xa0, 0xe1, 0x7e, 0x89, 0x64, 0xbf, 0x3d, 0xc7, +- 0x71, 0x58, 0x7a, 0xc0, 0x87, 0xe5, 0xc8, 0xbb, 0xe0, 0x3e, 0x11, 0xff, +- 0x1d, 0xdc, 0x45, 0xb8, 0x60, 0xb1, 0x6a, 0xeb, 0x6f, 0x75, 0xde, 0x81, +- 0xc4, 0x72, 0x12, 0xfa, 0x02, 0xd6, 0xe9, 0x00, 0xc5, 0xb3, 0x8c, 0x39, +- 0x18, 0x60, 0x5d, 0xb2, 0xbd, 0x59, 0x7d, 0x27, 0xca, 0x2b, 0x06, 0x22, +- 0x9d, 0x6e, 0xcc, 0xe6, 0x16, 0x51, 0x4d, 0x60, 0x62, 0xaf, 0x56, 0x8f, +- 0x5a, 0x2b, 0x06, 0xb8, 0x09, 0x47, 0x42, 0xf6, 0xd2, 0x3c, 0xe9, 0x31, +- 0x19, 0x1e, 0xba, 0x77, 0x92, 0x72, 0xd3, 0xfe, 0x4e, 0x7b, 0xee, 0xb6, +- 0xfc, 0x4d, 0xd8, 0x47, 0x1e, 0x5f, 0xaf, 0x46, 0x31, 0xea, 0xf7, 0x52, +- 0xac, 0xf9, 0x56, 0x75, 0xce, 0xcf, 0xc8, 0x36, 0x79, 0xbd, 0x4d, 0xb5, +- 0xb6, 0x1e, 0x96, 0xc9, 0x76, 0xed, 0x25, 0x1b, 0x75, 0xb4, 0xd6, 0xd6, +- 0xce, 0x0d, 0xe8, 0x19, 0xf5, 0x8a, 0x57, 0xd3, 0xf7, 0x98, 0xa1, 0x46, +- 0x1a, 0x47, 0x36, 0x5b, 0x53, 0xa5, 0xb7, 0x35, 0xff, 0xcf, 0xb5, 0x5c, +- 0xa7, 0x7b, 0x29, 0x8f, 0x3c, 0x98, 0x73, 0x20, 0x50, 0xbd, 0x1e, 0xcf, +- 0x87, 0xa0, 0x75, 0xd4, 0x01, 0x4d, 0x82, 0xae, 0xf1, 0xdc, 0xbc, 0x86, +- 0x8c, 0x46, 0xf2, 0x93, 0x6f, 0xc7, 0x13, 0xf8, 0x20, 0xeb, 0xc4, 0x7a, +- 0xca, 0xef, 0x6b, 0xd3, 0x3a, 0xce, 0x95, 0x6b, 0x79, 0x3d, 0xb2, 0xc3, +- 0xf9, 0x71, 0x4e, 0x1a, 0xe7, 0xc6, 0x74, 0xfe, 0x8b, 0xf4, 0x05, 0x88, +- 0xe6, 0x22, 0x8d, 0xe5, 0x7b, 0xe7, 0xad, 0xbe, 0xc0, 0xf1, 0x6b, 0xea, +- 0x29, 0xc7, 0x38, 0xf7, 0x8a, 0xec, 0x5c, 0xd0, 0xad, 0xb1, 0x2e, 0x7d, +- 0xb8, 0x3c, 0x61, 0xe0, 0xdc, 0xca, 0x06, 0x5c, 0x99, 0x68, 0xc5, 0x03, +- 0x39, 0x0f, 0x2e, 0x4c, 0x98, 0xb8, 0x69, 0x39, 0xee, 0x09, 0x12, 0x06, +- 0x6b, 0x20, 0xbf, 0xff, 0x29, 0xd5, 0x3c, 0x14, 0x4f, 0x89, 0xd2, 0x48, +- 0x62, 0x1d, 0xd9, 0x75, 0x34, 0x86, 0xd4, 0x2d, 0xf1, 0x48, 0xe8, 0x3c, +- 0xbe, 0x67, 0x52, 0x2c, 0xf6, 0x4b, 0x7a, 0xaf, 0x70, 0x5a, 0xfb, 0x84, +- 0x1b, 0xac, 0x7d, 0x45, 0xc7, 0xf4, 0xb0, 0x90, 0x4a, 0xd7, 0xfa, 0xf5, +- 0x97, 0xe5, 0x21, 0xce, 0x3d, 0x9c, 0x23, 0xc7, 0x4d, 0x97, 0xba, 0xc1, +- 0xea, 0xd3, 0xec, 0xce, 0x5f, 0xcd, 0x4d, 0x57, 0xf3, 0xd1, 0xce, 0x6a, +- 0x1e, 0x1a, 0x29, 0xbc, 0xf3, 0x05, 0xfc, 0x14, 0xaa, 0xee, 0x57, 0x70, +- 0xfe, 0x71, 0x8b, 0xb3, 0x64, 0x0e, 0x7b, 0xc8, 0x07, 0x8f, 0x6a, 0x27, +- 0x82, 0x94, 0x21, 0xe0, 0xec, 0x10, 0x78, 0x90, 0xcf, 0x8b, 0x04, 0x4c, +- 0xdc, 0xa9, 0xd9, 0xf6, 0xb0, 0xbc, 0xd3, 0x85, 0x41, 0xca, 0x49, 0xae, +- 0x98, 0x97, 0x7c, 0xdd, 0x8f, 0xd7, 0x34, 0xb6, 0xe1, 0x5b, 0xaa, 0x39, +- 0x89, 0xf7, 0xbf, 0xed, 0xbd, 0xea, 0xdf, 0xee, 0x5b, 0xcf, 0xdb, 0xa6, +- 0x86, 0xe4, 0x42, 0x78, 0xde, 0x8b, 0xab, 0x54, 0x37, 0xc8, 0x54, 0x33, +- 0xac, 0x47, 0x62, 0x81, 0x92, 0x64, 0xfd, 0xfb, 0x68, 0xee, 0x5f, 0x76, +- 0x0e, 0xe2, 0xfe, 0x71, 0x07, 0xea, 0x54, 0x8e, 0xb3, 0x06, 0xf6, 0x37, +- 0x72, 0x9c, 0xea, 0xc5, 0x8e, 0x71, 0xb7, 0x38, 0x99, 0x73, 0xe2, 0xc9, +- 0xbe, 0x47, 0xb0, 0xa0, 0x63, 0x4b, 0xb5, 0xd7, 0xc9, 0xdf, 0xbf, 0x89, +- 0xd4, 0x22, 0x5e, 0x9f, 0x7b, 0x68, 0x02, 0xde, 0x0e, 0xe6, 0x03, 0x9e, +- 0x8b, 0x34, 0xff, 0xe6, 0x51, 0xa7, 0x38, 0x9f, 0xfe, 0x1b, 0xf3, 0x48, +- 0x80, 0x71, 0x01, 0xdf, 0xab, 0x87, 0xd1, 0xc8, 0x63, 0x59, 0x87, 0x5e, +- 0xaa, 0x49, 0x07, 0x31, 0x4a, 0x74, 0xbd, 0x6e, 0xcd, 0x75, 0xb6, 0x4a, +- 0xbf, 0x57, 0x34, 0x64, 0x64, 0x23, 0x48, 0xb4, 0xf8, 0x57, 0xf6, 0xa1, +- 0xa1, 0x74, 0x6d, 0xbe, 0x25, 0xa3, 0xf7, 0x30, 0x7f, 0x9c, 0x13, 0x06, +- 0xf0, 0x41, 0x5a, 0xe0, 0x7d, 0xcb, 0x06, 0x07, 0xd0, 0x5a, 0xa0, 0xfa, +- 0xdf, 0x8a, 0x21, 0x3c, 0x2e, 0x6e, 0xdb, 0xb6, 0x63, 0x10, 0xdb, 0x89, +- 0x97, 0x7a, 0xe2, 0xe5, 0xe3, 0xd8, 0x12, 0x5a, 0x87, 0xaf, 0x1d, 0x93, +- 0xab, 0xfd, 0x87, 0xea, 0x5c, 0xab, 0xc0, 0xbd, 0x29, 0xa7, 0x1a, 0xc1, +- 0xb6, 0xf1, 0x48, 0xbf, 0xd7, 0xc1, 0x76, 0x18, 0xc1, 0x7d, 0xd3, 0x49, +- 0xba, 0xcf, 0x73, 0x05, 0xb1, 0x29, 0xe3, 0x14, 0xef, 0x52, 0x9d, 0x74, +- 0x3c, 0xed, 0x58, 0x24, 0xe1, 0x07, 0xe6, 0x93, 0x81, 0x1d, 0xb8, 0x45, +- 0xeb, 0xc5, 0xbd, 0x64, 0x83, 0xdd, 0xad, 0x3b, 0x30, 0x41, 0x36, 0xb0, +- 0xb9, 0x89, 0x6a, 0xb7, 0x58, 0xd9, 0x1c, 0x08, 0xb0, 0x1c, 0x05, 0x7a, +- 0xe8, 0x7a, 0x23, 0xd5, 0x73, 0x8e, 0x18, 0x59, 0x1b, 0xf9, 0x85, 0xac, +- 0x2a, 0xb9, 0x24, 0xea, 0xad, 0x35, 0x1b, 0x29, 0x4f, 0xbb, 0x18, 0x1f, +- 0xf8, 0x18, 0x27, 0x7c, 0x91, 0x1e, 0xc3, 0xac, 0x55, 0xd5, 0xe8, 0x7a, +- 0x47, 0x6b, 0x6e, 0x8e, 0x6c, 0x76, 0x4d, 0xc7, 0xb5, 0xcf, 0xcd, 0xcb, +- 0x48, 0x43, 0x4d, 0xc7, 0x8c, 0x59, 0xf1, 0x8f, 0xc0, 0xdf, 0x71, 0xad, +- 0xee, 0xe7, 0xe7, 0x60, 0x9a, 0xed, 0xb8, 0x16, 0x72, 0x44, 0xfc, 0xf7, +- 0xe0, 0xaf, 0x68, 0x8d, 0x20, 0x36, 0x96, 0x7a, 0x31, 0x30, 0x2e, 0x7d, +- 0x8e, 0x4f, 0x7c, 0x6c, 0xcb, 0x9f, 0xf3, 0xbf, 0x75, 0x3c, 0xd2, 0xe3, +- 0xa9, 0xf2, 0x7f, 0xef, 0xf4, 0xe7, 0x73, 0x0d, 0x67, 0x38, 0xaf, 0xf2, +- 0x7c, 0xbc, 0xef, 0x37, 0x2f, 0xdf, 0x20, 0xb6, 0x5b, 0xf3, 0xed, 0x75, +- 0xb3, 0x0f, 0xbb, 0xc8, 0xd7, 0xd7, 0x75, 0x18, 0x78, 0x2d, 0xf1, 0x80, +- 0xb9, 0xd5, 0x92, 0xc1, 0x9f, 0x58, 0xcf, 0xf7, 0xb4, 0x56, 0x2c, 0x7b, +- 0xb7, 0xfd, 0x96, 0xf7, 0x04, 0x78, 0x8f, 0x60, 0x7e, 0x5f, 0x20, 0x6a, +- 0xed, 0xd7, 0xd9, 0x7b, 0x03, 0xdf, 0xa2, 0x38, 0xcb, 0xfb, 0x06, 0xb2, +- 0x70, 0x8e, 0xd7, 0x09, 0xd7, 0x38, 0xd3, 0xf6, 0x81, 0x6c, 0xfb, 0xd8, +- 0x5f, 0x21, 0x19, 0xe0, 0xfe, 0xa4, 0x6d, 0xff, 0xd1, 0xce, 0xfb, 0x80, +- 0xa7, 0x0c, 0x77, 0xed, 0x0a, 0x50, 0x8d, 0xdf, 0x67, 0xd9, 0xc3, 0x75, +- 0xfa, 0xdb, 0xab, 0xfe, 0xb1, 0x95, 0xeb, 0x7c, 0xee, 0x09, 0xbe, 0xbb, +- 0x6a, 0xb2, 0x55, 0x22, 0x3c, 0xc5, 0x6b, 0xf2, 0xde, 0x02, 0xe7, 0x55, +- 0x2b, 0xee, 0x7a, 0x1a, 0x57, 0x18, 0xee, 0x05, 0x2b, 0x9c, 0x62, 0x51, +- 0xa6, 0x9f, 0x6c, 0x4f, 0x45, 0x22, 0x63, 0x78, 0x9a, 0x57, 0x84, 0xf0, +- 0x50, 0x66, 0x3e, 0x26, 0xb7, 0xa3, 0x7d, 0x0a, 0xf8, 0xdf, 0x99, 0x20, +- 0xda, 0x26, 0xc2, 0x43, 0xb7, 0x3b, 0xc2, 0xc3, 0xef, 0x38, 0xf8, 0x5e, +- 0xa1, 0xeb, 0x26, 0x0b, 0x7f, 0x1f, 0xed, 0x5a, 0x66, 0x7d, 0xbe, 0xdd, +- 0x75, 0x63, 0xe1, 0x6e, 0xa4, 0xe7, 0xdc, 0x97, 0xf3, 0x0e, 0x13, 0x0f, +- 0xc5, 0x1c, 0xf8, 0x9a, 0xf6, 0xd7, 0xe4, 0x5b, 0x82, 0x6c, 0xe3, 0x18, +- 0xe7, 0x60, 0x4b, 0xa7, 0xae, 0x15, 0x2a, 0xda, 0x32, 0x8d, 0x84, 0xd7, +- 0x9a, 0xa8, 0xe6, 0x6f, 0xc4, 0x0f, 0x73, 0x8c, 0xd7, 0x4c, 0x8a, 0xfb, +- 0x26, 0x5e, 0xef, 0x30, 0x86, 0x82, 0x50, 0x8c, 0x37, 0x85, 0x92, 0xba, +- 0xdd, 0xa1, 0x1c, 0x69, 0x72, 0xf8, 0xb1, 0x2f, 0x62, 0xe7, 0xd1, 0x4e, +- 0x2b, 0x6f, 0xbe, 0xd3, 0x65, 0xf7, 0xec, 0x4e, 0x56, 0xf3, 0xeb, 0xa9, +- 0x2e, 0x6d, 0x56, 0x39, 0x9a, 0x22, 0xff, 0x59, 0x48, 0xf1, 0x73, 0x3c, +- 0x9b, 0xb2, 0xce, 0x82, 0xfc, 0x32, 0x53, 0x43, 0xb6, 0x11, 0xd6, 0xc6, +- 0x11, 0x8e, 0x3e, 0x64, 0xd1, 0xfa, 0xb3, 0xae, 0x58, 0xa1, 0x8c, 0x8a, +- 0x53, 0x39, 0x08, 0x14, 0x09, 0x37, 0xb4, 0xf9, 0x5f, 0x46, 0x99, 0xfb, +- 0xa1, 0x56, 0xa0, 0x67, 0x1e, 0x5a, 0x0b, 0x40, 0x2e, 0xe3, 0xbe, 0x0c, +- 0xab, 0x17, 0xeb, 0xc0, 0x5a, 0x6d, 0x3b, 0xe1, 0x42, 0xde, 0xff, 0x15, +- 0x54, 0x63, 0x37, 0xa2, 0xb2, 0xc1, 0x89, 0xf1, 0x0c, 0xe7, 0xe1, 0x63, +- 0x5d, 0xf2, 0x28, 0x2a, 0x6e, 0x7b, 0x4f, 0x33, 0xe1, 0xa6, 0x0c, 0x3d, +- 0x57, 0x22, 0x4c, 0x4a, 0xb1, 0x63, 0x6b, 0xec, 0x37, 0x66, 0xb2, 0xd1, +- 0xde, 0x53, 0x19, 0x9d, 0x14, 0x58, 0xa0, 0x26, 0x31, 0x3a, 0xe7, 0xf4, +- 0xa5, 0xd3, 0x51, 0xa4, 0xcb, 0xfc, 0xbc, 0xfb, 0x72, 0xd2, 0x9a, 0x3f, +- 0xb2, 0x77, 0x89, 0xc3, 0x81, 0x65, 0x1d, 0x87, 0x50, 0x59, 0x68, 0xd3, +- 0x10, 0x24, 0x4c, 0xc0, 0x35, 0x6c, 0x13, 0xf1, 0x7a, 0xe7, 0xe3, 0x5c, +- 0x47, 0xfc, 0xa4, 0xeb, 0xe6, 0x29, 0xf6, 0xeb, 0x63, 0x5d, 0x1f, 0xa4, +- 0x95, 0x64, 0x93, 0x04, 0xb9, 0x8e, 0xf8, 0xbf, 0x6f, 0x94, 0xfb, 0x08, +- 0xbf, 0xe0, 0x3e, 0x02, 0xe5, 0x65, 0x65, 0xb8, 0x59, 0x78, 0xc5, 0xba, +- 0x0c, 0xd5, 0x15, 0x44, 0xf3, 0xa5, 0x88, 0xd2, 0x53, 0x22, 0x8c, 0xb2, +- 0x45, 0x50, 0x5d, 0x57, 0xb6, 0xe5, 0x65, 0x9f, 0xcd, 0xab, 0x5c, 0xc5, +- 0x21, 0x51, 0x0b, 0x77, 0xf0, 0x3e, 0x34, 0xe7, 0x71, 0x6b, 0x4f, 0x9f, +- 0xae, 0xff, 0xbc, 0x6b, 0x09, 0xd5, 0x16, 0x23, 0x4c, 0x1f, 0x78, 0xaf, +- 0x8f, 0x6a, 0xd0, 0xec, 0xf1, 0x2a, 0x2e, 0xf1, 0x56, 0xe5, 0xc2, 0xdf, +- 0xf9, 0x4c, 0xe2, 0x6b, 0x5d, 0x9b, 0x26, 0xf9, 0x8c, 0xe2, 0x4f, 0xba, +- 0xd6, 0x4c, 0x2a, 0xa1, 0x8d, 0xb4, 0xee, 0x6e, 0xde, 0x5f, 0xa7, 0x39, +- 0x67, 0x35, 0xa6, 0xbb, 0xd0, 0x75, 0x73, 0x96, 0x7b, 0xcb, 0xc7, 0xba, +- 0xcc, 0x6c, 0x98, 0x31, 0xa8, 0x65, 0x2b, 0x89, 0x02, 0x55, 0xf3, 0xd7, +- 0xd9, 0xbc, 0xba, 0x48, 0x1f, 0x87, 0xd2, 0x84, 0x76, 0xe2, 0xb6, 0x6e, +- 0x56, 0x17, 0xd6, 0x20, 0xd5, 0xd4, 0x4d, 0x35, 0xa8, 0xdf, 0xb7, 0x36, +- 0xd3, 0x8d, 0x09, 0xd2, 0xe1, 0xa6, 0x52, 0xd0, 0xd7, 0x9d, 0x51, 0x31, +- 0x50, 0xe2, 0x7a, 0xb3, 0xd2, 0xb5, 0x6b, 0x72, 0xaa, 0x5a, 0xff, 0xf6, +- 0x53, 0xcd, 0x4a, 0x76, 0x91, 0xb1, 0x6d, 0xae, 0xb5, 0x40, 0x34, 0x0b, +- 0x7b, 0x5e, 0x37, 0xad, 0x73, 0xfd, 0xe8, 0x77, 0xcd, 0xd0, 0x42, 0xb6, +- 0x85, 0xbb, 0xf1, 0xf8, 0x94, 0xcf, 0x08, 0xe8, 0x7e, 0x74, 0x76, 0x9c, +- 0xa2, 0x67, 0xdb, 0xf1, 0xf8, 0xe1, 0x5b, 0x90, 0xff, 0x23, 0x27, 0x2e, +- 0x66, 0x92, 0x58, 0xda, 0xf1, 0x55, 0x9c, 0xd9, 0x20, 0xe3, 0xef, 0x32, +- 0x5e, 0x5c, 0x22, 0xfe, 0x0c, 0x6b, 0x8e, 0x7f, 0xcf, 0xfe, 0x90, 0x5b, +- 0xb8, 0xc7, 0x35, 0xc6, 0x9e, 0xbf, 0xe7, 0x06, 0xf7, 0xde, 0x0c, 0xd4, +- 0x10, 0x0e, 0x0a, 0x13, 0xcd, 0x6a, 0x86, 0xcf, 0x38, 0x05, 0x7c, 0x9c, +- 0x2b, 0xa7, 0x89, 0x27, 0x47, 0xa9, 0xc5, 0xe7, 0x24, 0x7e, 0x9c, 0xa5, +- 0x73, 0x14, 0x03, 0xd8, 0x07, 0xdc, 0x97, 0x43, 0x96, 0x1d, 0x5c, 0xbb, +- 0xf6, 0x7e, 0x0f, 0xef, 0xf1, 0x1f, 0xcf, 0x72, 0x6c, 0x14, 0x54, 0xbb, +- 0x84, 0x90, 0x9c, 0x5d, 0x82, 0x9e, 0xd9, 0xed, 0x74, 0x5d, 0x45, 0x5f, +- 0xd5, 0xd7, 0x42, 0x05, 0x8f, 0x87, 0xf1, 0x49, 0x2e, 0x63, 0xff, 0x8e, +- 0x5c, 0xfd, 0xed, 0x16, 0x8d, 0xe3, 0x84, 0x1d, 0x11, 0xb7, 0xf2, 0xb0, +- 0xda, 0xf1, 0xef, 0xe2, 0xe5, 0x72, 0xca, 0xa2, 0x61, 0x37, 0xcd, 0xc5, +- 0xb2, 0x79, 0xce, 0x4c, 0xdd, 0xc9, 0xf2, 0x0b, 0xf8, 0x7e, 0x48, 0xfa, +- 0x98, 0xa4, 0x67, 0x1e, 0x27, 0x1e, 0xca, 0xc4, 0x5b, 0xb6, 0xf4, 0x5d, +- 0x1a, 0xc3, 0xf7, 0x40, 0xfa, 0x32, 0x14, 0x67, 0xf5, 0x6c, 0xe6, 0x08, +- 0xe5, 0xcb, 0x5a, 0x8a, 0x45, 0x67, 0xe3, 0xf7, 0x62, 0x6d, 0x4e, 0x49, +- 0x1a, 0x14, 0x2e, 0x53, 0x7e, 0x08, 0xa7, 0xce, 0x36, 0xfc, 0x36, 0xd9, +- 0x70, 0x0b, 0x61, 0x80, 0x70, 0xe8, 0x1c, 0x8d, 0x37, 0x9c, 0x32, 0x1e, +- 0x9b, 0x90, 0x70, 0x8e, 0xf7, 0x80, 0x85, 0xfd, 0xbc, 0x01, 0x1e, 0x3b, +- 0xff, 0xbd, 0x8e, 0xea, 0xba, 0x70, 0x82, 0xb2, 0xaa, 0x51, 0x4f, 0xb8, +- 0xbd, 0xd0, 0xf9, 0x08, 0xf6, 0x53, 0x7d, 0xbf, 0x35, 0x46, 0x32, 0x69, +- 0x8c, 0x53, 0xbd, 0xd1, 0x36, 0x74, 0x01, 0x7f, 0x67, 0x56, 0x78, 0x1f, +- 0x5d, 0x84, 0x13, 0x17, 0xf0, 0x99, 0x29, 0xa9, 0xea, 0xe9, 0x19, 0xa8, +- 0x95, 0x73, 0x68, 0x1b, 0xbe, 0x82, 0x0f, 0x4d, 0xde, 0x63, 0x97, 0x25, +- 0x89, 0x30, 0x60, 0xd8, 0xef, 0x44, 0x00, 0x95, 0x80, 0x84, 0x5b, 0x35, +- 0xee, 0x49, 0x2b, 0xc3, 0x4f, 0x13, 0x96, 0x7f, 0x5f, 0xb4, 0x0d, 0x7e, +- 0x8c, 0x33, 0x66, 0xbe, 0x91, 0xd7, 0x15, 0x48, 0xdc, 0xd8, 0x76, 0xba, +- 0x06, 0x4a, 0x8f, 0x4b, 0xa8, 0x89, 0x66, 0xe9, 0xaf, 0xcd, 0x33, 0x81, +- 0xcf, 0x4c, 0x35, 0xf2, 0x19, 0xe1, 0x20, 0x35, 0x38, 0x4d, 0x3e, 0x31, +- 0x88, 0x79, 0xda, 0xfe, 0x81, 0xf8, 0xd7, 0x88, 0x06, 0xc6, 0x7d, 0x86, +- 0x7b, 0x0f, 0xd1, 0xf6, 0x53, 0xc2, 0x01, 0x5b, 0x63, 0x17, 0xcc, 0xe4, +- 0x42, 0xeb, 0xfc, 0x5e, 0x9d, 0xdd, 0xfb, 0x66, 0x5f, 0xb9, 0x1b, 0x9b, +- 0xd2, 0x4e, 0x92, 0xd3, 0x3c, 0x5e, 0x73, 0x51, 0x0c, 0x66, 0x8c, 0x53, +- 0xb9, 0x9e, 0x4a, 0x33, 0xc7, 0xac, 0x0a, 0xec, 0xa2, 0xb8, 0xb0, 0xd3, +- 0xca, 0x05, 0xf0, 0x2c, 0x5e, 0xd1, 0x81, 0x2b, 0x53, 0xff, 0xc3, 0x43, +- 0xfa, 0x5b, 0xad, 0x2e, 0x87, 0x08, 0x66, 0x0c, 0xd1, 0xa0, 0x4b, 0xf8, +- 0xb8, 0x53, 0xe9, 0x71, 0x48, 0xc3, 0xb8, 0x31, 0x66, 0x98, 0x5e, 0x55, +- 0xed, 0x6f, 0x17, 0x91, 0xbe, 0x92, 0x88, 0xa2, 0xae, 0xe4, 0x95, 0xeb, +- 0x4a, 0xed, 0xb2, 0xa7, 0x64, 0xb8, 0xfd, 0x2b, 0xee, 0xa5, 0xba, 0x65, +- 0x07, 0xd5, 0xb6, 0x5e, 0xaa, 0xaf, 0x15, 0xb2, 0xc7, 0x1a, 0x92, 0x7f, +- 0x88, 0xe2, 0x80, 0x0e, 0x67, 0x66, 0x1b, 0x5c, 0x99, 0xb0, 0x7f, 0x37, +- 0x76, 0x20, 0x19, 0xb4, 0xb1, 0xad, 0x4c, 0xba, 0xaa, 0xed, 0x64, 0x2c, +- 0x73, 0x2f, 0xce, 0xe4, 0x19, 0x9f, 0x27, 0xb0, 0x31, 0xcd, 0xbf, 0xe1, +- 0x79, 0x39, 0xae, 0xe3, 0x28, 0xd5, 0x4e, 0xee, 0x8e, 0x66, 0xd2, 0x43, +- 0x0b, 0x46, 0xca, 0x82, 0x4d, 0x90, 0x74, 0x01, 0xcf, 0xd1, 0x4e, 0x19, +- 0xfb, 0x66, 0x28, 0x91, 0x50, 0x9e, 0x72, 0x92, 0x9d, 0xef, 0x26, 0x1b, +- 0xf2, 0xaa, 0x5e, 0xfa, 0x1d, 0xe0, 0x73, 0x47, 0x64, 0x93, 0x3f, 0xe9, +- 0x6a, 0xb7, 0x62, 0xcd, 0x2f, 0xa8, 0xc6, 0xf9, 0x15, 0xf1, 0xc2, 0xb2, +- 0xd0, 0x51, 0x37, 0x3e, 0x5f, 0x13, 0xae, 0xb9, 0xa3, 0x0e, 0x41, 0x9a, +- 0x33, 0x58, 0xdd, 0x23, 0x13, 0x58, 0x13, 0xeb, 0x40, 0x31, 0x27, 0xaa, +- 0x18, 0x6b, 0x44, 0xf1, 0x62, 0x35, 0xf6, 0x53, 0xed, 0xef, 0x53, 0x37, +- 0x22, 0xe3, 0xaf, 0x78, 0xde, 0x89, 0x73, 0x0d, 0x00, 0xcf, 0x00, 0x61, +- 0xa8, 0xd1, 0xf4, 0x57, 0x90, 0x5f, 0x08, 0xf7, 0x3d, 0x71, 0x3e, 0x9f, +- 0x49, 0x21, 0x4a, 0x5d, 0x8d, 0x86, 0xe5, 0xbd, 0xf8, 0xb8, 0x91, 0xf1, +- 0xaf, 0x97, 0x62, 0x83, 0x8c, 0xdd, 0x33, 0x01, 0xeb, 0x5c, 0x04, 0xc5, +- 0xc0, 0x2a, 0xcd, 0xd7, 0xd2, 0xfa, 0x65, 0x34, 0xb2, 0x4c, 0xfe, 0x6f, +- 0x34, 0x92, 0xcd, 0x12, 0xe6, 0xc9, 0xa5, 0x07, 0xf0, 0x4a, 0x9a, 0xe7, +- 0x0d, 0x27, 0x35, 0xe1, 0xe7, 0x9e, 0xbc, 0x25, 0x13, 0x63, 0x86, 0xd7, +- 0xf0, 0x5a, 0xb1, 0xc9, 0x5e, 0x27, 0xc0, 0xbd, 0xa2, 0xff, 0xe0, 0x5a, +- 0x1a, 0xe5, 0xc7, 0xd5, 0x54, 0x77, 0x46, 0xa1, 0x7e, 0xa3, 0x42, 0xfa, +- 0xe0, 0x1e, 0xf5, 0x12, 0xc2, 0xbc, 0x70, 0xbf, 0x1a, 0xe7, 0x73, 0xc8, +- 0xe6, 0x0e, 0x59, 0x37, 0x4d, 0x57, 0xa7, 0xea, 0x7f, 0x0f, 0x6c, 0x87, +- 0x5e, 0xde, 0xeb, 0x70, 0xef, 0xee, 0xf4, 0x62, 0x1f, 0xe5, 0xc0, 0x67, +- 0xd3, 0x6d, 0x06, 0xd7, 0x7e, 0x60, 0x1c, 0x2a, 0x52, 0xf4, 0xec, 0x50, +- 0x1d, 0x9f, 0x09, 0xda, 0x55, 0xde, 0x06, 0x47, 0xe6, 0xb6, 0x3a, 0xae, +- 0x37, 0x6a, 0xa8, 0x4e, 0x1e, 0x49, 0x33, 0xbd, 0xdc, 0x7b, 0x33, 0xcd, +- 0x9d, 0x71, 0xf5, 0xf2, 0x5a, 0xb2, 0x8b, 0x66, 0x9d, 0xe5, 0x18, 0xc0, +- 0x93, 0x34, 0x36, 0x54, 0x66, 0x59, 0x7e, 0xb7, 0x8e, 0xfb, 0x9d, 0x7b, +- 0x48, 0xbf, 0x0d, 0x59, 0x7b, 0x9e, 0x6c, 0x79, 0x10, 0x4b, 0x46, 0x5f, +- 0xa8, 0xb3, 0x6b, 0x1f, 0xae, 0xcb, 0x87, 0xb0, 0x27, 0x1d, 0xc0, 0x4c, +- 0xba, 0xcd, 0xff, 0x12, 0x9c, 0xd5, 0xbc, 0xca, 0xe7, 0x88, 0xe7, 0xc7, +- 0x04, 0x30, 0x7d, 0xf5, 0x3b, 0xcb, 0xc7, 0xee, 0x99, 0x1e, 0xb7, 0x30, +- 0xbf, 0x8c, 0x7c, 0xc0, 0xae, 0x63, 0x28, 0x56, 0x78, 0x1e, 0x25, 0xbd, +- 0xbe, 0x4f, 0x7a, 0x75, 0x90, 0x5e, 0x5f, 0xd2, 0xfe, 0x92, 0x31, 0x8b, +- 0x7b, 0x57, 0xdc, 0xcb, 0xfb, 0x43, 0x06, 0x81, 0x16, 0x6b, 0x4c, 0x26, +- 0xee, 0xc4, 0xeb, 0x94, 0x07, 0x6b, 0x28, 0xfe, 0x9d, 0x4a, 0x9b, 0xab, +- 0xe7, 0x62, 0x6d, 0xa9, 0xf7, 0x29, 0x4f, 0x1b, 0x7f, 0xa8, 0x68, 0x67, +- 0xc8, 0x4f, 0xb3, 0x13, 0x7f, 0x8a, 0x33, 0x8d, 0x6d, 0xfe, 0xb7, 0x60, +- 0xb8, 0x9f, 0x88, 0x3f, 0x42, 0x35, 0x3f, 0xd5, 0x0d, 0xcb, 0xff, 0x0b, +- 0x39, 0x59, 0x1c, 0x92, 0xda, 0x76, 0xf9, 0x25, 0xfc, 0x15, 0xce, 0x5c, +- 0x17, 0xd6, 0x5e, 0x02, 0x8f, 0xb1, 0xeb, 0xf1, 0xf0, 0xec, 0xfd, 0x7c, +- 0x1e, 0x2a, 0x48, 0xe9, 0xcc, 0xde, 0xc7, 0x4a, 0xf3, 0xbe, 0x9b, 0x40, +- 0x7e, 0x03, 0xd5, 0xd2, 0xd6, 0x39, 0x54, 0x78, 0x9e, 0x26, 0xbf, 0x88, +- 0x8e, 0xf1, 0xf8, 0x63, 0x5d, 0x6a, 0x21, 0x04, 0x89, 0x30, 0x0e, 0x61, +- 0x84, 0x1e, 0x3e, 0x9f, 0xf1, 0x74, 0x3a, 0x48, 0xb9, 0xa0, 0xad, 0x2f, +- 0x2a, 0xbe, 0x0d, 0x1b, 0x03, 0x70, 0x9e, 0x3b, 0x46, 0x79, 0x4e, 0x49, +- 0x3d, 0x8d, 0xb6, 0x7e, 0xaf, 0xb8, 0x1b, 0xa9, 0xc6, 0xb6, 0xc1, 0xa3, +- 0x08, 0x13, 0x66, 0x50, 0xa2, 0x67, 0x60, 0xcf, 0xb3, 0xb4, 0x20, 0x51, +- 0x9d, 0xc8, 0x71, 0x26, 0x8d, 0xa3, 0x7e, 0x09, 0x37, 0x74, 0xa8, 0x97, +- 0xa7, 0x31, 0x6f, 0x2f, 0xf6, 0x98, 0xd5, 0x05, 0x1a, 0x2f, 0xf9, 0x09, +- 0xdb, 0xd4, 0xc0, 0x49, 0xb5, 0xbf, 0xa4, 0x6f, 0xc3, 0xd6, 0x34, 0xe7, +- 0x69, 0x92, 0x0b, 0xf9, 0x66, 0x5f, 0x64, 0x1b, 0x86, 0x0a, 0x01, 0xec, +- 0xcf, 0x86, 0xf7, 0xee, 0x26, 0x5c, 0x37, 0x56, 0x0e, 0x87, 0x36, 0x8b, +- 0x00, 0xe9, 0x9b, 0xea, 0xff, 0xa6, 0x20, 0xd5, 0xc9, 0x7e, 0xfa, 0xb7, +- 0xeb, 0x99, 0x53, 0x54, 0xcf, 0xbc, 0x4e, 0xbe, 0xe6, 0xad, 0xd6, 0xaa, +- 0x4b, 0xf3, 0x26, 0xe6, 0x62, 0xeb, 0x71, 0xc9, 0xd2, 0x59, 0x90, 0x6c, +- 0x8c, 0x73, 0x08, 0x9f, 0x8d, 0x71, 0x8b, 0xcd, 0x63, 0x86, 0xfb, 0xc1, +- 0xce, 0x20, 0xe5, 0x34, 0xc6, 0x9c, 0x8e, 0x3f, 0x92, 0x48, 0x1e, 0x33, +- 0xea, 0x0e, 0xac, 0x8b, 0xed, 0xc0, 0x90, 0xf6, 0x5d, 0xd4, 0x34, 0x71, +- 0x3c, 0x92, 0x8d, 0x06, 0x9a, 0xf7, 0x42, 0x67, 0x2f, 0xc2, 0x4f, 0x31, +- 0x3e, 0xfa, 0x19, 0xe1, 0x23, 0xf6, 0x5d, 0x9e, 0xbf, 0x51, 0x5f, 0x46, +- 0xb8, 0xa2, 0xbe, 0xd3, 0xce, 0xf3, 0x37, 0x16, 0xf8, 0x4c, 0x26, 0xa8, +- 0x36, 0x85, 0xe7, 0xdd, 0x95, 0x3a, 0x9e, 0xa0, 0x18, 0x93, 0x58, 0xee, +- 0x02, 0x16, 0xf0, 0xd9, 0x63, 0xbb, 0x8e, 0x61, 0x7e, 0x97, 0x14, 0x04, +- 0x66, 0xe3, 0x64, 0x1f, 0xff, 0xea, 0x8c, 0x51, 0xa8, 0x7a, 0x36, 0x94, +- 0xfb, 0x27, 0x07, 0xcc, 0x24, 0xbf, 0x33, 0xe0, 0xa8, 0xf3, 0x52, 0xbc, +- 0x0d, 0x56, 0x20, 0x79, 0x39, 0x2e, 0x4b, 0xea, 0xbc, 0xdc, 0x59, 0xd6, +- 0x47, 0x38, 0xbe, 0x5b, 0xba, 0x70, 0xd2, 0x33, 0xbb, 0x26, 0x95, 0xe1, +- 0xdd, 0x68, 0x1b, 0xfa, 0x40, 0xd4, 0x5a, 0x3b, 0x97, 0xd3, 0xed, 0x48, +- 0x2d, 0xd6, 0x9d, 0x1b, 0xae, 0x64, 0x57, 0x13, 0x1d, 0xe7, 0x4c, 0x5c, +- 0xb7, 0xc6, 0xda, 0xdf, 0x9a, 0x6e, 0xff, 0x73, 0x9a, 0x9b, 0xbf, 0x3f, +- 0xe0, 0xe5, 0x33, 0x93, 0xc7, 0xb3, 0x2f, 0x9a, 0xd1, 0x85, 0xb6, 0x7c, +- 0x4e, 0x90, 0xef, 0x07, 0x75, 0x07, 0x9a, 0xd5, 0xc8, 0xe5, 0x7e, 0xfa, +- 0xfd, 0xb7, 0x05, 0x42, 0xfb, 0x2b, 0x07, 0xf1, 0xab, 0xbc, 0x8e, 0xc7, +- 0x28, 0x0f, 0x34, 0xa8, 0x8a, 0x3f, 0xcf, 0xfb, 0xd7, 0x31, 0x9b, 0xff, +- 0x9b, 0xf2, 0xe4, 0x87, 0x8d, 0x7e, 0xab, 0xc6, 0xb0, 0xf9, 0x2b, 0x10, +- 0x7f, 0x03, 0x5e, 0xf6, 0x85, 0xc5, 0xe4, 0x17, 0x7b, 0xc9, 0x5f, 0x1f, +- 0x23, 0x5b, 0xa3, 0x0a, 0x9e, 0xfc, 0x40, 0xd9, 0x0b, 0xf2, 0xd7, 0xb1, +- 0x34, 0xcb, 0x3f, 0xe8, 0x1b, 0x18, 0xe5, 0xb8, 0x6b, 0xf5, 0x55, 0xb5, +- 0x90, 0x83, 0xe3, 0xae, 0x15, 0x4f, 0x8d, 0x90, 0xe3, 0xd7, 0x75, 0x4c, +- 0xd7, 0x48, 0x39, 0x1c, 0xf4, 0xf0, 0x79, 0x7e, 0x02, 0x87, 0x03, 0x9a, +- 0x9d, 0x2b, 0xe7, 0x28, 0x1f, 0x5d, 0x22, 0x3a, 0xf6, 0xc7, 0x9a, 0x91, +- 0xa2, 0x7c, 0x94, 0x51, 0x6d, 0x5b, 0x52, 0x67, 0x19, 0x63, 0xfe, 0x82, +- 0x30, 0xa6, 0x12, 0x72, 0x49, 0x6d, 0xc3, 0x27, 0xb1, 0xcd, 0x3c, 0xd3, +- 0xc8, 0x36, 0xe5, 0xc2, 0xe1, 0xf6, 0x59, 0xb3, 0x12, 0x60, 0x7e, 0x25, +- 0xbc, 0xa8, 0x91, 0xcd, 0x5c, 0x17, 0x0e, 0xbe, 0x48, 0x39, 0x75, 0xa6, +- 0xaa, 0x8f, 0x70, 0x61, 0xde, 0x1e, 0x63, 0x2c, 0xeb, 0x68, 0x0a, 0x6a, +- 0xa2, 0x80, 0x3f, 0xa6, 0xef, 0xad, 0xc1, 0x4b, 0x55, 0x5b, 0x5d, 0x36, +- 0xfb, 0xdf, 0xbd, 0xd5, 0x77, 0x6c, 0xac, 0x67, 0x42, 0x85, 0xfb, 0xe9, +- 0x37, 0xcf, 0x19, 0xe0, 0xb3, 0x2d, 0x7c, 0xd6, 0xca, 0xb3, 0xb5, 0xb3, +- 0x86, 0xfd, 0xc5, 0xcf, 0xef, 0x15, 0xac, 0x1b, 0xe3, 0xbe, 0x30, 0xf7, +- 0x68, 0x24, 0xec, 0xbe, 0xfa, 0xde, 0x03, 0x7f, 0xf6, 0xe0, 0xd6, 0x31, +- 0xee, 0x45, 0x9c, 0xb8, 0x59, 0xc6, 0x3f, 0x51, 0x1e, 0x96, 0xd9, 0xe7, +- 0xc9, 0xd7, 0x7f, 0xd4, 0x75, 0x6a, 0x92, 0x73, 0xea, 0xdb, 0x5d, 0x9b, +- 0xd2, 0xf3, 0x3a, 0xbe, 0xca, 0xd3, 0xe9, 0x7b, 0x28, 0xee, 0x64, 0xd2, +- 0xca, 0x70, 0x44, 0xb2, 0xf6, 0xd5, 0x52, 0x25, 0xf1, 0x15, 0x2a, 0xd2, +- 0x78, 0xbe, 0x5e, 0xf4, 0x8f, 0x85, 0xa8, 0xb6, 0xf1, 0xfb, 0x1e, 0x38, +- 0x60, 0x52, 0xae, 0x70, 0xe2, 0xe9, 0xd1, 0xb0, 0xf6, 0x26, 0xe1, 0x9d, +- 0x67, 0x46, 0x4d, 0xf3, 0x4d, 0x0d, 0x7f, 0xd2, 0x40, 0x35, 0x72, 0xbb, +- 0x50, 0x12, 0x84, 0x0d, 0x42, 0xeb, 0x45, 0x5b, 0xb0, 0x00, 0xe5, 0xf4, +- 0x4e, 0x9a, 0xef, 0x50, 0x11, 0x78, 0xb1, 0xe8, 0xc1, 0x0b, 0x63, 0xdc, +- 0xfb, 0xf3, 0xa0, 0xf4, 0x54, 0x93, 0x6f, 0xdb, 0x81, 0x10, 0xc5, 0x58, +- 0x19, 0xbd, 0x87, 0x12, 0xb8, 0xf5, 0x80, 0x40, 0x34, 0x92, 0x40, 0xcf, +- 0xa1, 0x7a, 0xac, 0x1f, 0x93, 0x71, 0x31, 0x5e, 0x8f, 0xdb, 0x9e, 0x9a, +- 0xe7, 0xe3, 0x9d, 0x6a, 0x9d, 0x27, 0x5b, 0xe7, 0xd8, 0x8e, 0x66, 0x39, +- 0x66, 0x53, 0xbe, 0xc8, 0x72, 0x0c, 0x34, 0xcd, 0x60, 0xa7, 0xdd, 0xe7, +- 0x78, 0x8e, 0xf2, 0xc7, 0x13, 0x9d, 0x6a, 0x30, 0xe8, 0xd0, 0x71, 0xc3, +- 0x44, 0xe5, 0xdb, 0x0d, 0x30, 0x8f, 0xf3, 0x1e, 0xc6, 0xa7, 0xed, 0xa6, +- 0x79, 0x6b, 0x3c, 0x72, 0x99, 0x2a, 0x3b, 0xf2, 0xa9, 0xb7, 0xc9, 0xa7, +- 0x5a, 0xf0, 0x44, 0x76, 0x7e, 0xaf, 0x4b, 0xed, 0xbf, 0x20, 0x19, 0x3b, +- 0xfc, 0x30, 0x3f, 0xa9, 0xd5, 0xcd, 0x4f, 0x5d, 0x7a, 0x24, 0xb8, 0x5d, +- 0xf0, 0x19, 0x11, 0xee, 0x89, 0x9b, 0xe6, 0xd9, 0xb8, 0x69, 0x16, 0xe3, +- 0x86, 0x7b, 0xd9, 0x0a, 0x3f, 0x0e, 0x2d, 0xe5, 0x77, 0x0d, 0xc2, 0xc9, +- 0x66, 0xb2, 0x2f, 0xcf, 0x52, 0x35, 0xb8, 0x91, 0xea, 0x2b, 0x83, 0x82, +- 0x5c, 0x68, 0xa1, 0xd2, 0x0f, 0xb4, 0xf8, 0xf6, 0x8f, 0x36, 0xe1, 0x99, +- 0xb9, 0xdf, 0xe5, 0xe3, 0x39, 0x56, 0x3f, 0xed, 0x13, 0x0d, 0xab, 0x1b, +- 0x10, 0x49, 0x6e, 0x01, 0xf7, 0x46, 0xf9, 0x4c, 0xaa, 0x81, 0xdb, 0xe2, +- 0x83, 0xd8, 0x3a, 0xc6, 0xfb, 0x6b, 0x3f, 0xef, 0xfa, 0x64, 0xcc, 0xfc, +- 0x5b, 0x37, 0xd1, 0xbf, 0xba, 0xb3, 0x2d, 0xe5, 0xb1, 0xde, 0x55, 0x3a, +- 0x49, 0x75, 0x40, 0x23, 0xca, 0x33, 0x6a, 0x65, 0xb1, 0x48, 0xbe, 0xe9, +- 0x45, 0x24, 0xd8, 0x4c, 0xb1, 0x6a, 0x8e, 0x7c, 0x77, 0xa6, 0xcc, 0x75, +- 0xc0, 0x2f, 0xbb, 0xcc, 0x89, 0x45, 0x98, 0x9e, 0xa3, 0xb9, 0xb2, 0x6a, +- 0xcf, 0x47, 0x84, 0xf3, 0xea, 0x74, 0xb3, 0xc1, 0xa3, 0x47, 0x4e, 0xb7, +- 0x09, 0x09, 0x97, 0x97, 0x9b, 0x66, 0x6f, 0xa7, 0x3a, 0x5c, 0x2f, 0x30, +- 0xe4, 0xd0, 0xd5, 0x44, 0xbb, 0x84, 0xaf, 0x06, 0x11, 0xe9, 0x39, 0x8b, +- 0x48, 0xff, 0x39, 0x8a, 0x61, 0xcf, 0x96, 0xf9, 0x9c, 0xef, 0x23, 0xf8, +- 0xdb, 0xb1, 0x85, 0x38, 0x3e, 0xf3, 0x50, 0xb5, 0x27, 0x06, 0xcf, 0x8d, +- 0x2b, 0x74, 0x1c, 0x26, 0xbd, 0x9e, 0xd4, 0x6a, 0x28, 0xae, 0xcb, 0x70, +- 0xb4, 0x42, 0x6e, 0xa4, 0x3a, 0x21, 0xf6, 0xb8, 0x69, 0x2e, 0x6b, 0xb5, +- 0x6b, 0x9e, 0x65, 0xb3, 0xd7, 0xbe, 0xa3, 0x30, 0xdf, 0xef, 0x09, 0x92, +- 0xfe, 0xda, 0x52, 0x5b, 0xc5, 0x49, 0xd3, 0xf8, 0x43, 0x41, 0x3c, 0xdf, +- 0x56, 0x0f, 0x0f, 0xf3, 0x2d, 0x63, 0xe7, 0x04, 0xf7, 0xe1, 0x58, 0x6f, +- 0xf0, 0xf4, 0xc4, 0x79, 0x9f, 0x9c, 0x75, 0x54, 0xf1, 0xac, 0x8b, 0x53, +- 0x4c, 0x14, 0x3e, 0xc2, 0x53, 0x86, 0xbb, 0x9b, 0xf2, 0x53, 0xed, 0x18, +- 0xbf, 0x2f, 0xe1, 0xc5, 0x63, 0x14, 0x37, 0x2e, 0x69, 0x75, 0xd8, 0xdf, +- 0xc8, 0xb6, 0xc3, 0x74, 0x72, 0xcf, 0x70, 0x1b, 0xee, 0xe5, 0x77, 0x4e, +- 0xca, 0xbf, 0x6b, 0x9d, 0x0d, 0xa4, 0x6b, 0x84, 0x0d, 0x98, 0x8e, 0xf9, +- 0xf5, 0x7b, 0xb0, 0x78, 0x94, 0xf5, 0x78, 0xac, 0x2b, 0x48, 0x32, 0x7a, +- 0x82, 0xec, 0xc2, 0xa1, 0x77, 0x43, 0x26, 0x5b, 0x5c, 0x1b, 0xbf, 0x76, +- 0x0e, 0x75, 0xe8, 0x9c, 0x44, 0xf5, 0x9d, 0xc4, 0xfb, 0x79, 0x4a, 0xe2, +- 0x88, 0xb8, 0x76, 0xce, 0x7c, 0x3d, 0xf7, 0x13, 0x8d, 0x19, 0x3b, 0x2f, +- 0x1d, 0xa6, 0xbc, 0xf4, 0x4a, 0x8e, 0x7d, 0xe4, 0x17, 0x96, 0x8f, 0x38, +- 0x28, 0xd6, 0xae, 0x49, 0x87, 0x70, 0x4e, 0x83, 0x5a, 0x83, 0x18, 0xd1, +- 0x1d, 0xe9, 0xe9, 0xae, 0x62, 0x3e, 0x17, 0xc5, 0xff, 0x99, 0x9c, 0x32, +- 0x68, 0xf5, 0x9f, 0x54, 0xa5, 0x8f, 0x3f, 0x79, 0xef, 0x3f, 0xa8, 0x0f, +- 0xa1, 0x61, 0x25, 0x70, 0x7e, 0x94, 0xfb, 0x55, 0xbc, 0xcf, 0x35, 0x2c, +- 0xae, 0xf0, 0x7b, 0x61, 0xb5, 0x43, 0x78, 0x2f, 0xce, 0xef, 0x5b, 0xb1, +- 0xef, 0x3d, 0x0c, 0xf6, 0xbd, 0x06, 0x1a, 0xfb, 0xc9, 0x68, 0x38, 0xd4, +- 0x43, 0x7e, 0x33, 0x00, 0xeb, 0xbc, 0x90, 0x36, 0x6b, 0xf7, 0xc7, 0x93, +- 0xa7, 0xaa, 0xfb, 0x5b, 0x91, 0xea, 0xde, 0x5c, 0xb4, 0xd0, 0x23, 0x2e, +- 0x15, 0x98, 0xa6, 0xb7, 0x89, 0xa6, 0x6e, 0xf1, 0xe1, 0xec, 0x3a, 0x71, +- 0x71, 0xb6, 0x57, 0x9c, 0x2d, 0x70, 0x4c, 0xfe, 0x79, 0xd7, 0xae, 0x1c, +- 0xe7, 0xb3, 0x3b, 0xc5, 0xbb, 0xf9, 0x0d, 0xe2, 0x42, 0xa1, 0x5f, 0x7c, +- 0x34, 0x6b, 0xe0, 0xfe, 0x78, 0x2f, 0x0a, 0x63, 0xf0, 0xbb, 0xf5, 0xfb, +- 0xc5, 0xa5, 0xbc, 0xdd, 0x27, 0xbc, 0x50, 0x68, 0xf1, 0x15, 0xd2, 0x5c, +- 0x03, 0x1f, 0xa3, 0x1a, 0x78, 0x91, 0xef, 0x99, 0xc9, 0x80, 0xaf, 0x34, +- 0xa9, 0x0c, 0xde, 0x23, 0x4c, 0xf3, 0xb6, 0xd8, 0x69, 0xd6, 0xa1, 0xf9, +- 0x5a, 0xcc, 0xc6, 0x07, 0x3b, 0x49, 0x1e, 0x9b, 0x29, 0xb7, 0x4c, 0x6b, +- 0x6d, 0x55, 0x2c, 0xc2, 0xb6, 0xce, 0xbc, 0x72, 0xae, 0xe6, 0xfd, 0xa7, +- 0x21, 0x38, 0x3b, 0x81, 0xbd, 0xe9, 0xcf, 0x79, 0xbd, 0x44, 0xbc, 0x1a, +- 0xae, 0x21, 0x7c, 0x4c, 0xbc, 0xbe, 0x3e, 0xfa, 0xf9, 0x7e, 0x9e, 0x93, +- 0xc6, 0xee, 0x4a, 0x87, 0x53, 0x47, 0x84, 0x52, 0x29, 0xd8, 0xfb, 0x79, +- 0x9a, 0x57, 0x52, 0x4e, 0x8f, 0x50, 0x1d, 0xd1, 0x2a, 0xd9, 0xbc, 0x26, +- 0xaa, 0xbc, 0xde, 0x44, 0xbc, 0x5e, 0x2c, 0x70, 0x7d, 0xfe, 0x76, 0xd7, +- 0x1b, 0xa3, 0x63, 0x66, 0x3d, 0xd5, 0xff, 0x75, 0x6a, 0xb7, 0xb8, 0x40, +- 0x3c, 0x7f, 0x48, 0x3c, 0x7f, 0x5c, 0xb8, 0x53, 0x7c, 0x44, 0x7c, 0x5e, +- 0x2c, 0xf0, 0x1e, 0x9e, 0x5b, 0x7c, 0x98, 0xb3, 0x79, 0xfc, 0xf0, 0x2a, +- 0x8f, 0x41, 0xdf, 0xfe, 0x74, 0x93, 0xef, 0xd1, 0x49, 0xbf, 0x6f, 0xcf, +- 0xa4, 0x69, 0x7e, 0xa8, 0x49, 0x3e, 0xe6, 0xeb, 0x55, 0xed, 0x8b, 0x7c, +- 0xdd, 0x4c, 0x7c, 0xf1, 0xfe, 0xeb, 0x6f, 0xeb, 0x70, 0x9e, 0xaf, 0xc7, +- 0xac, 0x73, 0x6c, 0xf6, 0x19, 0xa9, 0x7a, 0xde, 0x83, 0x25, 0xbe, 0x7c, +- 0x74, 0xfd, 0x95, 0x7f, 0xcd, 0xd7, 0xe0, 0x05, 0xd2, 0x5f, 0xb1, 0xca, +- 0x57, 0xfd, 0xbf, 0xc9, 0x17, 0xd5, 0xba, 0x63, 0xcc, 0x57, 0xa3, 0xfe, +- 0xc6, 0x98, 0x49, 0xfa, 0x92, 0xac, 0x77, 0xc1, 0x8a, 0xd9, 0x1d, 0x78, +- 0x25, 0xc6, 0xef, 0xc7, 0x45, 0x42, 0x47, 0x28, 0x9e, 0xce, 0x96, 0x3d, +- 0xa2, 0xc6, 0xda, 0x87, 0xc5, 0x1b, 0xb5, 0x44, 0xd3, 0xe1, 0x19, 0x7e, +- 0xff, 0x0b, 0x1a, 0x61, 0x01, 0x3f, 0xbf, 0x37, 0x37, 0x0d, 0xee, 0x97, +- 0xf5, 0x8a, 0x86, 0x22, 0xef, 0xbb, 0x6e, 0x10, 0xbe, 0x22, 0x9f, 0xa3, +- 0xeb, 0x11, 0xde, 0x62, 0xb7, 0xf0, 0x1c, 0x32, 0x4c, 0x8f, 0xba, 0x4e, +- 0xd4, 0x1d, 0xba, 0x53, 0x78, 0xaa, 0x7b, 0xb0, 0xee, 0x62, 0xd0, 0x97, +- 0xbe, 0x46, 0x1e, 0x17, 0xb5, 0x9b, 0x2d, 0x79, 0xbc, 0xa6, 0xcd, 0xef, +- 0x1f, 0x5a, 0xe7, 0x10, 0xf9, 0x1c, 0x9c, 0x27, 0x48, 0xb5, 0x53, 0x43, +- 0xb5, 0x76, 0x7a, 0x37, 0xc6, 0xe7, 0x7b, 0x0c, 0x92, 0x3f, 0x42, 0x4e, +- 0x5d, 0xe9, 0x3f, 0x21, 0xd4, 0xd4, 0xfd, 0x22, 0x79, 0xab, 0x97, 0xea, +- 0x9f, 0xad, 0xb1, 0x48, 0xf2, 0x06, 0x11, 0x49, 0x38, 0x05, 0xe7, 0x15, +- 0x4d, 0xae, 0x2d, 0x19, 0xd8, 0x43, 0xf1, 0xed, 0xe5, 0x9c, 0x83, 0xb0, +- 0x03, 0xbf, 0x43, 0xe6, 0xc4, 0x5a, 0xbf, 0x17, 0x4f, 0x12, 0xee, 0x78, +- 0x22, 0x3b, 0x88, 0x27, 0x0b, 0x03, 0x78, 0xa2, 0xf0, 0xaf, 0xde, 0x95, +- 0x91, 0x3d, 0xfa, 0xf9, 0x95, 0xd5, 0x33, 0x08, 0x89, 0xeb, 0x23, 0x1c, +- 0xa3, 0x1f, 0x6e, 0x97, 0x23, 0x5c, 0xeb, 0xbe, 0x75, 0xf3, 0x07, 0x2a, +- 0xfb, 0xa2, 0xba, 0xe2, 0x94, 0x85, 0x45, 0x1e, 0x59, 0x7e, 0xc8, 0x3a, +- 0x1b, 0x95, 0xbe, 0x69, 0x97, 0xf5, 0x4e, 0xe7, 0x3b, 0x2b, 0x36, 0xa9, +- 0xec, 0x0f, 0x0f, 0xc7, 0xd7, 0x58, 0xf9, 0xf5, 0x6f, 0x56, 0xd9, 0x3d, +- 0x9a, 0x77, 0x56, 0x5d, 0x6f, 0xf7, 0xd1, 0x56, 0x45, 0xad, 0xcf, 0x33, +- 0xab, 0xec, 0xfd, 0xed, 0x4f, 0x57, 0xb5, 0x5a, 0x9f, 0xe7, 0x57, 0xd9, +- 0x3e, 0xf5, 0xee, 0x2a, 0xd5, 0xfa, 0xfc, 0x87, 0x55, 0x76, 0x5e, 0xbe, +- 0xb4, 0x6a, 0xc9, 0xd5, 0xf7, 0x63, 0xf8, 0xef, 0xff, 0x00, 0x88, 0xf4, +- 0x23, 0x6f, 0xec, 0x3a, 0x00, 0x00, 0x00 }; ++ 0xc5, 0x7b, 0x7b, 0x74, 0x1c, 0x55, 0x9a, 0xdf, 0xef, 0x56, 0x3f, 0x54, ++ 0xdd, 0x6a, 0xb5, 0x4a, 0x72, 0xdb, 0x6e, 0xed, 0x68, 0xc6, 0x5d, 0xee, ++ 0x6a, 0xb9, 0xb1, 0x84, 0x5d, 0x2d, 0xb5, 0xec, 0x66, 0x5d, 0xb1, 0x7b, ++ 0x8c, 0xb0, 0x65, 0x10, 0x3b, 0xc2, 0xeb, 0x9d, 0x88, 0x09, 0x27, 0xf4, ++ 0x18, 0x19, 0x64, 0x63, 0x40, 0x30, 0x64, 0xa3, 0xd9, 0x25, 0xeb, 0x1a, ++ 0xf9, 0x81, 0x1f, 0xad, 0xee, 0xd6, 0xc3, 0xc8, 0xec, 0xd9, 0x13, 0x64, ++ 0x49, 0xb6, 0xcc, 0xd0, 0x0f, 0x33, 0xc0, 0xcc, 0x30, 0x27, 0x13, 0x77, ++ 0x8c, 0x01, 0x03, 0x63, 0x98, 0xdd, 0x6c, 0x92, 0x99, 0x3d, 0x49, 0xd6, ++ 0x07, 0xf3, 0xb0, 0xc1, 0x60, 0x32, 0x43, 0x12, 0xb1, 0xcb, 0x4c, 0xe5, ++ 0xfb, 0xaa, 0x25, 0x63, 0x58, 0xb2, 0x9b, 0x6c, 0xfe, 0x88, 0xce, 0xd1, ++ 0xe9, 0xee, 0xaa, 0x5b, 0xf7, 0x7e, 0xef, 0xef, 0xf7, 0x7d, 0xf7, 0x56, ++ 0x04, 0xf0, 0x62, 0xee, 0xaf, 0x86, 0xfe, 0xe3, 0xfd, 0x03, 0x0f, 0xb7, ++ 0xae, 0x88, 0xaf, 0xa0, 0xaf, 0x6d, 0x58, 0xec, 0x74, 0xf2, 0xcd, 0x55, ++ 0x02, 0x48, 0xbd, 0x87, 0x7f, 0xd4, 0xdf, 0x57, 0xff, 0x71, 0x8f, 0xc1, ++ 0x01, 0x28, 0xf3, 0x34, 0xf1, 0x3f, 0x64, 0xc9, 0x30, 0xd7, 0xac, 0xd7, ++ 0x20, 0x3b, 0x8c, 0xc4, 0xda, 0xbb, 0x34, 0x20, 0x99, 0x6f, 0x0e, 0xdd, ++ 0x88, 0xdf, 0x58, 0x66, 0xc0, 0x09, 0xbe, 0xfe, 0x55, 0xe3, 0xd3, 0x5d, ++ 0x3f, 0x5d, 0xad, 0x7e, 0x34, 0xe1, 0x80, 0xac, 0x18, 0x63, 0x50, 0x9a, ++ 0x20, 0x37, 0xd2, 0x33, 0x7f, 0xb6, 0xec, 0x79, 0x27, 0xfc, 0xf3, 0x73, ++ 0xc1, 0x74, 0x19, 0x3a, 0x76, 0x67, 0xfb, 0x31, 0x13, 0x07, 0x2e, 0xa6, ++ 0x23, 0xfa, 0x6e, 0x20, 0x27, 0x19, 0x91, 0xd0, 0x69, 0x84, 0x30, 0x9d, ++ 0x87, 0x59, 0x65, 0x68, 0xd8, 0x5f, 0x0a, 0xe1, 0x52, 0xfa, 0xb7, 0x56, ++ 0xc8, 0xd5, 0x8f, 0xb7, 0xe2, 0x90, 0x83, 0xc6, 0x23, 0x08, 0x66, 0x21, ++ 0xd7, 0x18, 0x03, 0x28, 0x0c, 0x01, 0x7b, 0xd3, 0x6a, 0x3f, 0xa0, 0xf6, ++ 0x14, 0x45, 0xf8, 0xec, 0x09, 0xa8, 0xdd, 0x0d, 0x8e, 0xe6, 0xd4, 0xed, ++ 0x42, 0x4d, 0xee, 0x14, 0x90, 0x05, 0x8d, 0x5d, 0x9e, 0xe7, 0xcf, 0x01, ++ 0x44, 0xf3, 0x32, 0xce, 0x3b, 0x78, 0x59, 0x83, 0xe4, 0x2c, 0xe0, 0xd4, ++ 0x74, 0xec, 0xcd, 0xc2, 0x74, 0x1a, 0x02, 0xbb, 0xe3, 0x11, 0x65, 0x0a, ++ 0x7c, 0x3f, 0x84, 0x41, 0x7b, 0x9c, 0x4a, 0x1c, 0x5b, 0xd6, 0x1e, 0xdd, ++ 0xb2, 0x8e, 0xe9, 0x55, 0x30, 0x15, 0x35, 0x08, 0x08, 0x0c, 0xea, 0x12, ++ 0x92, 0xca, 0xfa, 0x90, 0x13, 0x6a, 0x70, 0x1b, 0xfe, 0x96, 0xf8, 0x4d, ++ 0x46, 0x5d, 0xa8, 0x8c, 0x4f, 0xa1, 0x0a, 0x65, 0xa5, 0x22, 0xb1, 0xc9, ++ 0xb4, 0x65, 0xbd, 0xa4, 0x39, 0x71, 0x8c, 0x64, 0x33, 0x98, 0xff, 0x5b, ++ 0xab, 0x4c, 0x72, 0xd9, 0xa3, 0xcd, 0xaf, 0x2f, 0x63, 0x42, 0xb1, 0xac, ++ 0x29, 0xba, 0xb7, 0x2f, 0x3f, 0x2f, 0x63, 0xcb, 0x92, 0x34, 0xcb, 0xba, ++ 0x4b, 0xfb, 0x1b, 0x6b, 0xeb, 0xe7, 0xc6, 0xc6, 0xf0, 0xfd, 0x9c, 0x82, ++ 0xa7, 0xb2, 0x49, 0xe4, 0xd3, 0x16, 0x1c, 0x86, 0x13, 0x7d, 0x43, 0x21, ++ 0xec, 0x2c, 0x74, 0xa0, 0x90, 0x56, 0x53, 0xe7, 0xe9, 0xb9, 0xad, 0x71, ++ 0x0d, 0xf7, 0x15, 0x3a, 0x31, 0x93, 0x86, 0xe5, 0x31, 0xb4, 0xb2, 0x47, ++ 0x44, 0x71, 0x4f, 0xa1, 0x0b, 0xc5, 0xb4, 0x76, 0x76, 0x50, 0x44, 0x06, ++ 0x1a, 0x1c, 0x4e, 0x3c, 0x50, 0x68, 0xc1, 0xfd, 0x85, 0x04, 0x3d, 0x63, ++ 0xe1, 0xe6, 0x58, 0x23, 0x8d, 0x6f, 0xc5, 0x93, 0x63, 0x96, 0x15, 0x8d, ++ 0x29, 0xe8, 0x2b, 0xe8, 0x98, 0xc9, 0x49, 0x48, 0x1d, 0x73, 0x22, 0x75, ++ 0x14, 0xb8, 0xe7, 0x68, 0x2b, 0xa6, 0x72, 0x16, 0xb6, 0xea, 0x83, 0x0d, ++ 0x12, 0x5c, 0x48, 0x29, 0x02, 0x2e, 0xcd, 0x8f, 0x6d, 0x4a, 0x85, 0xf6, ++ 0xf3, 0x0e, 0x81, 0x1d, 0x47, 0xa3, 0xf8, 0x45, 0xda, 0xc4, 0xcd, 0xed, ++ 0x41, 0x0c, 0x14, 0x02, 0x78, 0x23, 0x1d, 0xa0, 0x35, 0x74, 0xbc, 0x9e, ++ 0x96, 0x69, 0x9d, 0x16, 0x9c, 0x49, 0xf3, 0x18, 0x1e, 0xeb, 0x43, 0x6f, ++ 0xa1, 0x11, 0xe7, 0xd2, 0x41, 0x5a, 0x33, 0x80, 0x57, 0x68, 0xdc, 0xf6, ++ 0x82, 0x86, 0xb3, 0x34, 0xae, 0xaf, 0x10, 0xc2, 0xcb, 0x69, 0x1f, 0xd1, ++ 0x1a, 0xc0, 0xe9, 0x74, 0x3f, 0x76, 0xa7, 0x9b, 0xcf, 0xde, 0x48, 0x32, ++ 0x0c, 0x2d, 0xe0, 0x75, 0xf8, 0xda, 0x5b, 0x56, 0x57, 0xc0, 0x36, 0x13, ++ 0x5a, 0x67, 0x7e, 0xdd, 0x7e, 0x0c, 0xa6, 0xcf, 0xcc, 0xf9, 0x89, 0x8e, ++ 0x03, 0xb9, 0x59, 0xeb, 0xa7, 0xcb, 0x1a, 0x71, 0x22, 0x0b, 0x3c, 0x39, ++ 0x05, 0x4c, 0x65, 0x4d, 0xab, 0xc6, 0xb0, 0xac, 0xc9, 0xf6, 0x16, 0x92, ++ 0x97, 0xd6, 0xb3, 0x95, 0x46, 0x3d, 0x55, 0x72, 0x02, 0x47, 0xd5, 0x9e, ++ 0x32, 0x24, 0x4c, 0xcc, 0x38, 0xe1, 0x1e, 0x52, 0x3b, 0x27, 0xa0, 0x9e, ++ 0xbd, 0x87, 0x3c, 0xe9, 0x58, 0x56, 0xed, 0x36, 0xb1, 0xcb, 0x0a, 0x1a, ++ 0x4d, 0xa1, 0x16, 0x87, 0x05, 0x3f, 0xd9, 0x42, 0xba, 0xc5, 0xb2, 0x6a, ++ 0x57, 0x5b, 0xd6, 0xb9, 0x76, 0x58, 0x92, 0xa1, 0x9d, 0x2d, 0x41, 0x2b, ++ 0x7f, 0x00, 0x6d, 0xe0, 0x34, 0xca, 0x5f, 0xf5, 0x21, 0xd2, 0x17, 0x76, ++ 0x44, 0xfa, 0x67, 0xe9, 0xd9, 0x9a, 0x02, 0x99, 0x32, 0xf1, 0xa2, 0x91, ++ 0x0d, 0x16, 0x4a, 0x32, 0x9c, 0xc4, 0x4f, 0xcb, 0x90, 0x65, 0x39, 0x35, ++ 0x1f, 0x7c, 0x24, 0xdf, 0x8d, 0x87, 0x2d, 0xeb, 0x1d, 0x5d, 0x81, 0x9b, ++ 0x74, 0x73, 0xd3, 0xb0, 0x85, 0x49, 0xfd, 0x34, 0xc9, 0x53, 0x20, 0xd5, ++ 0x1d, 0xa7, 0x67, 0x02, 0x34, 0x3e, 0x81, 0x8d, 0x43, 0x41, 0x7c, 0x3f, ++ 0x2b, 0xe3, 0xa7, 0xcb, 0xa2, 0xa8, 0xa6, 0xb9, 0xbc, 0x24, 0xab, 0x2a, ++ 0x92, 0x1f, 0x0a, 0x64, 0x6e, 0x85, 0x8a, 0x3d, 0xa2, 0x70, 0x9e, 0x78, ++ 0x0c, 0xe2, 0x07, 0xa5, 0x00, 0x9e, 0x2e, 0x29, 0x38, 0x59, 0x6a, 0xc4, ++ 0xa9, 0x92, 0x8e, 0x6c, 0x4e, 0xdd, 0x5f, 0x86, 0x85, 0x1a, 0x32, 0xe7, ++ 0x37, 0x26, 0x62, 0xc8, 0xe4, 0x2c, 0x2b, 0x4f, 0x34, 0x7b, 0x89, 0x87, ++ 0xd7, 0x27, 0xbe, 0x86, 0xe3, 0x63, 0x4e, 0x84, 0x26, 0x03, 0x78, 0x2a, ++ 0xed, 0xc4, 0x75, 0x19, 0xd5, 0x9c, 0x80, 0x16, 0xdd, 0x29, 0xb4, 0xe4, ++ 0x72, 0xa1, 0xe6, 0x4c, 0x44, 0x42, 0x2e, 0x21, 0xa1, 0xe9, 0xb8, 0x13, ++ 0x5a, 0x31, 0x04, 0x57, 0x93, 0x0c, 0xad, 0x89, 0xdc, 0xc8, 0x2f, 0xc1, ++ 0x4d, 0x7e, 0xb1, 0x71, 0x24, 0x4a, 0xd7, 0x02, 0x74, 0x0d, 0x5f, 0xab, ++ 0x82, 0x63, 0x91, 0x03, 0x24, 0x37, 0xcd, 0x81, 0xa4, 0xd3, 0xb2, 0x1c, ++ 0x5a, 0x2b, 0x7a, 0x1e, 0xa3, 0xcf, 0x36, 0x1e, 0xaf, 0x20, 0x5c, 0x24, ++ 0x19, 0x34, 0x11, 0x4d, 0x59, 0xa2, 0x31, 0x4b, 0x34, 0x66, 0x89, 0xc6, ++ 0xac, 0x83, 0x6c, 0x46, 0xd5, 0x81, 0x3f, 0x22, 0x5d, 0x85, 0x88, 0xbf, ++ 0x5f, 0xd8, 0x7a, 0x7a, 0xba, 0x14, 0x24, 0xfa, 0x43, 0x36, 0xfd, 0x4f, ++ 0xe6, 0x04, 0x24, 0x4d, 0xed, 0x3e, 0x8f, 0x75, 0x08, 0xc7, 0xd4, 0xe4, ++ 0x04, 0x92, 0xf4, 0x9c, 0xba, 0xdf, 0x84, 0xda, 0x59, 0x26, 0xfd, 0x6f, ++ 0x55, 0x12, 0x98, 0xc9, 0xba, 0x50, 0xad, 0xa9, 0x21, 0xd2, 0x57, 0xb4, ++ 0x8c, 0x05, 0xb8, 0x57, 0xa1, 0x39, 0x25, 0xb7, 0xa8, 0xc4, 0x90, 0x47, ++ 0x10, 0x19, 0x91, 0x30, 0xad, 0x3b, 0xc8, 0x3f, 0x75, 0x38, 0x9a, 0x68, ++ 0xb9, 0x62, 0x9c, 0x3e, 0x69, 0xfe, 0x2c, 0xad, 0x45, 0xf4, 0xd0, 0x7c, ++ 0xe4, 0x97, 0x2c, 0xc7, 0x28, 0xd1, 0xb0, 0xd7, 0xa6, 0xf7, 0x64, 0xa9, ++ 0x4b, 0x54, 0xec, 0xc7, 0x20, 0x7b, 0x51, 0x43, 0x10, 0x6a, 0x34, 0x24, ++ 0x54, 0x3d, 0x29, 0x14, 0x4c, 0x95, 0x7e, 0x46, 0x63, 0x02, 0xd7, 0x8c, ++ 0xe9, 0xc6, 0x60, 0x56, 0xe0, 0x46, 0xcd, 0xc2, 0x7a, 0xbd, 0x1b, 0xbb, ++ 0x4b, 0xf3, 0x7e, 0xc9, 0xb1, 0x4b, 0xf1, 0x4f, 0xa5, 0x3b, 0xb0, 0x27, ++ 0x1b, 0xc2, 0xee, 0x7c, 0xd0, 0x3f, 0x99, 0xe6, 0x7b, 0x1a, 0xf9, 0x3b, ++ 0xdf, 0x0b, 0x5c, 0x73, 0xaf, 0xf1, 0x9a, 0x7b, 0x09, 0x0c, 0x8e, 0x7e, ++ 0x85, 0x62, 0x48, 0x2d, 0x76, 0x6b, 0x1f, 0x91, 0xad, 0x68, 0x89, 0x5e, ++ 0x34, 0xe0, 0xbc, 0xd2, 0x82, 0x43, 0xe3, 0x5d, 0xd8, 0x33, 0xbe, 0x02, ++ 0x07, 0x46, 0x1b, 0x53, 0x5e, 0x63, 0x88, 0xd6, 0x0f, 0x27, 0x7b, 0x85, ++ 0xda, 0xef, 0x10, 0xe1, 0x68, 0x2f, 0xd9, 0x6e, 0x53, 0x9d, 0x65, 0x9d, ++ 0x8e, 0x91, 0x6d, 0xeb, 0xcd, 0xfa, 0x46, 0x12, 0x40, 0xb9, 0x5b, 0xed, ++ 0x7c, 0x0b, 0x3e, 0xdc, 0x4a, 0x36, 0x37, 0x15, 0x43, 0xaf, 0x03, 0x8e, ++ 0x16, 0x1f, 0x7e, 0x6d, 0x1d, 0x75, 0xb2, 0xdc, 0xad, 0x5d, 0x77, 0xe9, ++ 0x7b, 0x05, 0xc7, 0x39, 0xf7, 0xd5, 0x58, 0xc2, 0xf3, 0xf3, 0x33, 0x96, ++ 0x15, 0xa6, 0x79, 0xfa, 0x62, 0xcd, 0x89, 0x3e, 0xcc, 0x5a, 0xe7, 0xb7, ++ 0x74, 0x61, 0xf7, 0xcc, 0x0a, 0x1c, 0x1c, 0x75, 0x21, 0x59, 0x27, 0x50, ++ 0xab, 0x85, 0xcb, 0xf7, 0x62, 0x05, 0xcc, 0x29, 0x7e, 0xae, 0x0b, 0x47, ++ 0x66, 0x2a, 0xbf, 0xb3, 0x57, 0x7f, 0xcf, 0xcf, 0x77, 0x91, 0x74, 0xca, ++ 0xf2, 0xe4, 0x38, 0x49, 0x2a, 0x30, 0x9a, 0x71, 0x62, 0x34, 0x40, 0xba, ++ 0xed, 0x10, 0xce, 0xe3, 0x8b, 0xfc, 0xde, 0xc7, 0x2c, 0xbc, 0xa4, 0x93, ++ 0x9e, 0xb3, 0x1b, 0x84, 0xf7, 0x78, 0xa7, 0x70, 0x15, 0x37, 0x0b, 0xf7, ++ 0xe4, 0xb7, 0x84, 0x7c, 0x3c, 0x25, 0xaa, 0x8a, 0x2d, 0x24, 0xfb, 0x1e, ++ 0xe1, 0x39, 0xae, 0x86, 0x42, 0xe2, 0xbb, 0xa4, 0xcf, 0x2d, 0xc2, 0x51, ++ 0x84, 0x22, 0x19, 0x03, 0x42, 0x2a, 0xd2, 0x1c, 0xb6, 0x0d, 0xf1, 0x3a, ++ 0x41, 0xd2, 0x1b, 0x4c, 0x87, 0xd1, 0x8f, 0xad, 0x94, 0x23, 0x6e, 0x49, ++ 0x1b, 0x38, 0x98, 0xad, 0xa2, 0xf8, 0xc8, 0x7e, 0x3f, 0x4b, 0xeb, 0x6a, ++ 0x38, 0x54, 0x82, 0xe9, 0x31, 0x0e, 0x62, 0x05, 0xf9, 0xdb, 0xb9, 0x18, ++ 0xfb, 0x22, 0x90, 0xcf, 0x86, 0x93, 0x07, 0x85, 0x65, 0x55, 0x45, 0xac, ++ 0x25, 0xef, 0xe8, 0xcd, 0xd1, 0x33, 0xf8, 0x9f, 0xd6, 0x44, 0xa0, 0x1f, ++ 0xd1, 0x76, 0xc8, 0x55, 0xc6, 0x1e, 0xbc, 0x9b, 0x86, 0xec, 0x36, 0x4c, ++ 0xbc, 0x94, 0x06, 0x7c, 0x43, 0x83, 0x8a, 0x17, 0x64, 0x07, 0x08, 0x07, ++ 0x0f, 0x09, 0xb5, 0xfb, 0x02, 0xa5, 0xb3, 0x44, 0xbb, 0x39, 0x20, 0x81, ++ 0xe2, 0x91, 0x50, 0x7b, 0xce, 0x90, 0x3d, 0x7e, 0x57, 0xa8, 0xca, 0xac, ++ 0x60, 0x3f, 0xe5, 0x5c, 0xb2, 0x67, 0x2e, 0xa7, 0x98, 0xb8, 0xee, 0x9a, ++ 0x9c, 0x32, 0x48, 0x74, 0xed, 0x23, 0xba, 0x5e, 0xd4, 0xd5, 0xe0, 0x24, ++ 0xac, 0x25, 0xbd, 0x3a, 0xdf, 0x33, 0xb0, 0xa7, 0x64, 0x85, 0x1c, 0x06, ++ 0xcb, 0x0a, 0xa9, 0x2a, 0x03, 0xa6, 0x6c, 0x28, 0xe4, 0x1b, 0xbf, 0xb1, ++ 0x7a, 0xe3, 0xb2, 0xfe, 0x76, 0x5e, 0x21, 0x79, 0xc1, 0xef, 0x2c, 0x7c, ++ 0x59, 0xde, 0xb5, 0x20, 0x19, 0xbf, 0xb1, 0xee, 0x8c, 0xc3, 0xbf, 0xa4, ++ 0xe0, 0x4c, 0x55, 0x1b, 0xe8, 0x1e, 0x18, 0xda, 0x65, 0x35, 0x68, 0x12, ++ 0xc5, 0x29, 0x8d, 0xe2, 0xba, 0x2f, 0x71, 0xb9, 0xdd, 0x23, 0xce, 0xb5, ++ 0x07, 0xbb, 0x3e, 0xc8, 0x7b, 0x48, 0xcf, 0xe8, 0xde, 0x59, 0x48, 0x38, ++ 0xdf, 0x23, 0x5b, 0x73, 0x53, 0x4c, 0x45, 0xa1, 0xb1, 0xeb, 0x12, 0xe5, ++ 0xa1, 0x9b, 0x62, 0x9e, 0x7f, 0xea, 0x36, 0xa4, 0xaf, 0x79, 0xf0, 0xe0, ++ 0xca, 0xe9, 0x44, 0x2d, 0xc5, 0x75, 0x05, 0x67, 0xe3, 0x9d, 0x18, 0x2c, ++ 0x55, 0x91, 0x1d, 0x3e, 0x53, 0xde, 0xab, 0x35, 0x76, 0xbd, 0x9f, 0x5e, ++ 0xc2, 0x71, 0xe4, 0xd3, 0x7c, 0xbb, 0xd6, 0xbd, 0x53, 0x9c, 0xde, 0xe4, ++ 0x45, 0x1c, 0x07, 0x4a, 0xb2, 0xfc, 0x49, 0x1a, 0x1f, 0x2d, 0xd1, 0xb4, ++ 0xf2, 0x3a, 0x47, 0x53, 0xbf, 0xec, 0x68, 0x1a, 0x70, 0x53, 0x0c, 0xbe, ++ 0x78, 0xbd, 0xc0, 0x4b, 0xd7, 0x47, 0x12, 0x6e, 0xe1, 0xc1, 0xf9, 0xee, ++ 0x04, 0xd9, 0x49, 0x63, 0xca, 0x63, 0x50, 0xfc, 0x20, 0x93, 0x75, 0x68, ++ 0x09, 0xec, 0x9e, 0xc2, 0x23, 0x83, 0x7a, 0x17, 0xcc, 0x19, 0xb6, 0xa1, ++ 0x16, 0x0c, 0xce, 0x74, 0xc3, 0x2c, 0x39, 0x30, 0x11, 0x20, 0xe6, 0x4b, ++ 0x48, 0xb9, 0x8c, 0x96, 0x8e, 0x89, 0x7c, 0xaf, 0xab, 0xe2, 0xc3, 0xc4, ++ 0x7f, 0xf6, 0xa8, 0x1f, 0x5e, 0xd6, 0xf3, 0x59, 0x92, 0x51, 0x0b, 0x9e, ++ 0x29, 0x45, 0x29, 0xd6, 0xe9, 0x24, 0x17, 0x8d, 0xe2, 0x45, 0x88, 0xec, ++ 0x4b, 0xc6, 0xd6, 0x51, 0xf5, 0x08, 0xc5, 0x85, 0xdc, 0x04, 0xda, 0x91, ++ 0x0c, 0x28, 0x94, 0xbb, 0x5f, 0x9a, 0x8b, 0x01, 0xdb, 0xe8, 0x53, 0x35, ++ 0x93, 0xc0, 0x19, 0x09, 0x68, 0x6d, 0x30, 0x22, 0xfb, 0x1b, 0x48, 0x1f, ++ 0x75, 0x45, 0x0f, 0x1e, 0x18, 0xad, 0xc7, 0xfd, 0xe3, 0x5e, 0xec, 0x18, ++ 0xb5, 0x70, 0x39, 0xc6, 0xb6, 0xa1, 0xf6, 0x10, 0x89, 0x1d, 0xd5, 0x24, ++ 0xd7, 0x4d, 0xb1, 0x48, 0xc2, 0x23, 0x9c, 0xa8, 0x2a, 0x76, 0x13, 0x06, ++ 0x48, 0xb2, 0x5f, 0xe8, 0x34, 0x47, 0x68, 0xb7, 0x7e, 0x2b, 0x52, 0x01, ++ 0x19, 0xae, 0xa2, 0x8f, 0x62, 0x09, 0xfb, 0x31, 0xdf, 0xfb, 0x06, 0xb6, ++ 0xba, 0x7d, 0x70, 0x64, 0x64, 0xe4, 0x28, 0xff, 0x63, 0x91, 0x1b, 0x9d, ++ 0x4d, 0x12, 0xfd, 0x07, 0xfc, 0xd3, 0x63, 0x8d, 0xfe, 0x63, 0x14, 0x5f, ++ 0xef, 0xc9, 0x4a, 0xbc, 0x0e, 0xe3, 0x05, 0x9a, 0x5b, 0xc1, 0x93, 0x14, ++ 0xab, 0x1f, 0xa2, 0xf8, 0x73, 0xa2, 0x94, 0x17, 0x1c, 0x4f, 0x6c, 0x7e, ++ 0xb2, 0xc4, 0x5b, 0x96, 0x78, 0xcb, 0x12, 0x5f, 0x14, 0x17, 0x4e, 0x66, ++ 0x99, 0x8f, 0x2b, 0xe4, 0xa3, 0x09, 0xe2, 0xdd, 0x83, 0x6d, 0x44, 0xef, ++ 0x83, 0xe3, 0xd5, 0xb8, 0x8f, 0xe8, 0x2d, 0xea, 0x6a, 0xcf, 0x9f, 0x0b, ++ 0x0b, 0xf9, 0x98, 0x6a, 0xee, 0x14, 0x5e, 0x48, 0x4d, 0x96, 0xd5, 0xad, ++ 0x33, 0xcf, 0x64, 0xa7, 0x92, 0xcd, 0xf3, 0xfe, 0x24, 0x3c, 0xe8, 0xa3, ++ 0x67, 0x7a, 0xc7, 0xf1, 0xa9, 0x44, 0x3c, 0x79, 0x88, 0xc7, 0x83, 0xba, ++ 0x9a, 0x58, 0x4e, 0x71, 0xfd, 0x82, 0x16, 0x29, 0x5f, 0x70, 0xe0, 0xeb, ++ 0x24, 0x0f, 0x9d, 0xe5, 0xd1, 0x44, 0xfc, 0x3c, 0x40, 0x58, 0xc7, 0x6f, ++ 0x30, 0x9f, 0x91, 0xe8, 0xaf, 0x89, 0xf7, 0x48, 0x31, 0xe0, 0x3f, 0x77, ++ 0xb8, 0xd1, 0xff, 0xe2, 0x50, 0x85, 0xfe, 0x9d, 0x44, 0xff, 0x74, 0xcc, ++ 0xc2, 0x21, 0xa2, 0xff, 0x29, 0xa2, 0xbf, 0x8f, 0xe3, 0xf9, 0x1c, 0xfd, ++ 0x27, 0x4a, 0xbc, 0xee, 0x97, 0xf1, 0x30, 0x4f, 0x7f, 0x3d, 0xb6, 0x8e, ++ 0xcf, 0xcb, 0xcb, 0xb2, 0xee, 0xd4, 0x9f, 0xb5, 0xbe, 0x4d, 0x32, 0x5b, ++ 0x52, 0x64, 0xb9, 0x31, 0x8e, 0x8b, 0x1c, 0xb9, 0x07, 0x7d, 0x12, 0xbc, ++ 0x3e, 0x2c, 0x28, 0x72, 0x2e, 0x08, 0xe1, 0x59, 0xd2, 0xef, 0x29, 0xca, ++ 0x65, 0xcf, 0x94, 0xae, 0xcd, 0x6d, 0xac, 0xeb, 0x31, 0xd2, 0xb1, 0x3a, ++ 0x61, 0x52, 0x6c, 0x4b, 0x95, 0x92, 0xd8, 0x3b, 0x8e, 0xe4, 0xb4, 0xfe, ++ 0xaf, 0x29, 0xc0, 0x2c, 0x22, 0xfb, 0xaa, 0x4a, 0x2a, 0x9a, 0x17, 0x77, ++ 0x4d, 0x05, 0xd0, 0x5f, 0x5a, 0x8f, 0x2c, 0xc5, 0x9b, 0x9d, 0x14, 0x9f, ++ 0x3f, 0x8c, 0x25, 0x77, 0xf8, 0x11, 0x21, 0xfd, 0x06, 0x70, 0x2f, 0x3d, ++ 0x73, 0x70, 0x9c, 0xe9, 0x57, 0xe6, 0xf4, 0x1c, 0xc0, 0x3d, 0x74, 0x6d, ++ 0xdf, 0xb8, 0x8c, 0x17, 0xf4, 0x27, 0x08, 0xcf, 0x54, 0xf0, 0xc5, 0xdd, ++ 0x59, 0x28, 0xe4, 0x9e, 0x84, 0xff, 0x22, 0xd1, 0x17, 0xe8, 0xf7, 0xb6, ++ 0x92, 0xd7, 0x3f, 0x38, 0x86, 0xef, 0x2d, 0x31, 0xfc, 0x58, 0x40, 0x58, ++ 0xec, 0x76, 0x3d, 0x42, 0x76, 0xef, 0xc4, 0x40, 0x49, 0xc2, 0x77, 0xa6, ++ 0xbc, 0x78, 0x68, 0xf4, 0x53, 0xcb, 0x1d, 0x77, 0xe2, 0xb6, 0x26, 0x2f, ++ 0x1e, 0x9c, 0x4a, 0x62, 0xff, 0x38, 0x42, 0x55, 0xb1, 0x61, 0x8a, 0xdd, ++ 0x95, 0x7c, 0x50, 0x4d, 0xbc, 0x1f, 0x18, 0xf7, 0xf9, 0xfb, 0x0e, 0xb3, ++ 0x0c, 0xd6, 0x07, 0x3d, 0x40, 0xb9, 0x2a, 0xe6, 0xc0, 0x36, 0xdd, 0xb1, ++ 0xa0, 0x8a, 0x0c, 0xfd, 0x09, 0x9a, 0x6f, 0x12, 0x8e, 0x57, 0x97, 0x20, ++ 0x72, 0xa4, 0xc1, 0x51, 0xce, 0x2d, 0x40, 0x3d, 0x1e, 0x9a, 0x49, 0x62, ++ 0x98, 0x6c, 0xf4, 0x81, 0xd1, 0xc1, 0xef, 0xd5, 0x51, 0x0c, 0xf1, 0xb7, ++ 0xaa, 0x7d, 0x6f, 0x08, 0x03, 0xf9, 0x88, 0x07, 0x3b, 0xa7, 0x7c, 0xfe, ++ 0x1d, 0x87, 0xad, 0x75, 0x6c, 0x4f, 0xdb, 0x67, 0xea, 0x71, 0xdf, 0x38, ++ 0x5d, 0x1b, 0x65, 0x1b, 0x26, 0x5b, 0x8b, 0x54, 0x11, 0x6f, 0xe1, 0xa4, ++ 0x87, 0xf0, 0x92, 0x23, 0x56, 0x4d, 0xf2, 0xf0, 0xe0, 0x1e, 0xdb, 0x16, ++ 0x14, 0x6c, 0x1b, 0xb7, 0xf0, 0xa6, 0x1e, 0x45, 0x8e, 0xec, 0xfa, 0xc8, ++ 0xb8, 0x3a, 0xdb, 0x41, 0x58, 0xe7, 0x6d, 0x87, 0x7a, 0xa4, 0xc9, 0x91, ++ 0x44, 0x7d, 0x1b, 0xc5, 0xf8, 0x7a, 0xcb, 0xba, 0xbb, 0xb5, 0xb9, 0xff, ++ 0xe7, 0x44, 0x73, 0x9d, 0xb1, 0x08, 0xe5, 0x3a, 0x35, 0x07, 0x34, 0x0f, ++ 0xb8, 0xa5, 0xeb, 0x71, 0x7e, 0x21, 0xc7, 0x41, 0x8e, 0xe5, 0x01, 0x7f, ++ 0x7d, 0xa6, 0x92, 0xe3, 0xea, 0x8b, 0x8d, 0xfe, 0xba, 0x4c, 0xd0, 0x5f, ++ 0x57, 0x84, 0xdf, 0x5d, 0x04, 0x7e, 0x4c, 0xf1, 0x65, 0x41, 0xdb, 0x6f, ++ 0xac, 0x54, 0xbd, 0x8d, 0x07, 0xfd, 0xcf, 0x8f, 0xa9, 0x66, 0x19, 0xea, ++ 0x7e, 0x0a, 0x9b, 0x78, 0x7c, 0xc6, 0xe9, 0x3f, 0x4e, 0xd8, 0xaf, 0x5e, ++ 0x8b, 0x62, 0x1f, 0xe9, 0x73, 0x17, 0xd9, 0xc2, 0xaf, 0xdb, 0x80, 0x03, ++ 0x99, 0x70, 0x48, 0x17, 0x3d, 0x34, 0x31, 0xb0, 0xa7, 0x48, 0x31, 0x5f, ++ 0x4a, 0x52, 0x10, 0x53, 0xa3, 0x94, 0xd6, 0x90, 0xce, 0xb8, 0x60, 0x2e, ++ 0xac, 0xe8, 0xe4, 0xbe, 0xec, 0x29, 0xcb, 0xaf, 0x69, 0x13, 0x45, 0xd2, ++ 0xd9, 0xc3, 0x25, 0x1f, 0x06, 0x08, 0x0f, 0x2c, 0x20, 0x0c, 0xf9, 0x20, ++ 0xd9, 0xc5, 0x03, 0xa3, 0x0e, 0xa2, 0x8f, 0xc7, 0x25, 0x91, 0x5c, 0x54, ++ 0xc1, 0xa2, 0x0f, 0x4d, 0xb1, 0x5d, 0x92, 0x1d, 0x91, 0x2d, 0x3e, 0x4b, ++ 0x39, 0xff, 0x99, 0xcf, 0x61, 0x10, 0x55, 0x31, 0xaf, 0xe6, 0xfe, 0x8a, ++ 0x3c, 0x06, 0xc7, 0x99, 0x67, 0xf5, 0x08, 0xa4, 0x24, 0x6e, 0xd2, 0x7f, ++ 0x49, 0x39, 0x81, 0x79, 0x27, 0x0c, 0x3c, 0x1e, 0xc5, 0xa3, 0x59, 0xc2, ++ 0x34, 0xb1, 0xcb, 0xd6, 0x3d, 0x01, 0x96, 0x01, 0xf3, 0xb3, 0xca, 0xc1, ++ 0xf9, 0xb3, 0x9e, 0xb0, 0xef, 0xff, 0xbb, 0xdd, 0xdd, 0x65, 0xa5, 0x6c, ++ 0x2c, 0x4b, 0x18, 0x9b, 0xec, 0x29, 0x75, 0xd5, 0x7e, 0x1e, 0xb4, 0xce, ++ 0x07, 0x38, 0x5f, 0xd7, 0x23, 0x75, 0xd5, 0x16, 0xd8, 0x96, 0xb0, 0x44, ++ 0x6f, 0xdd, 0xfd, 0xa0, 0x02, 0xb6, 0x87, 0xe8, 0x35, 0xf6, 0x50, 0x45, ++ 0x34, 0x29, 0xd8, 0x31, 0xc3, 0xf6, 0x6b, 0x5d, 0x59, 0x62, 0xfc, 0xd6, ++ 0xfa, 0x64, 0xb5, 0x76, 0xe4, 0x97, 0xe8, 0xa2, 0xeb, 0x01, 0x7c, 0x87, ++ 0xfc, 0xe8, 0x5e, 0xe2, 0x73, 0x47, 0xfb, 0xbd, 0xb6, 0xdf, 0xee, 0x28, ++ 0xad, 0xa1, 0xeb, 0x2c, 0xef, 0x0e, 0xec, 0xcf, 0xea, 0x48, 0x67, 0xcb, ++ 0x9c, 0x87, 0xc8, 0xe6, 0xe3, 0xf8, 0x11, 0xc5, 0xd9, 0x67, 0x4b, 0x8c, ++ 0xc9, 0x12, 0x36, 0x1e, 0xfb, 0x61, 0xa9, 0x05, 0xcf, 0x91, 0x4f, 0x3e, ++ 0x43, 0x31, 0xf7, 0x07, 0x36, 0x4e, 0x73, 0x8a, 0x43, 0x69, 0xc2, 0xa4, ++ 0x43, 0x26, 0xd2, 0xf9, 0x10, 0x3c, 0x87, 0xc3, 0xfb, 0x77, 0x08, 0xf5, ++ 0xc7, 0x24, 0x2f, 0xff, 0x81, 0xe9, 0xa5, 0xa8, 0x3a, 0xac, 0x4e, 0x10, ++ 0xdd, 0xfe, 0x47, 0xa7, 0x35, 0xc2, 0xd4, 0x41, 0xff, 0xbe, 0xbc, 0xe2, ++ 0xdf, 0x3b, 0x16, 0xf0, 0xef, 0x9d, 0xae, 0x27, 0x3f, 0x5a, 0xe4, 0x1f, ++ 0x9c, 0x0e, 0xfa, 0x77, 0xa7, 0x1b, 0xfd, 0xbb, 0xf3, 0x6d, 0x08, 0xd5, ++ 0xc3, 0x5c, 0x44, 0x39, 0xe2, 0xbe, 0xd1, 0x6f, 0x62, 0xa2, 0xae, 0x12, ++ 0xf7, 0xfb, 0xc9, 0x36, 0x6a, 0xc9, 0x0e, 0x57, 0x4a, 0xb7, 0xa1, 0xbc, ++ 0xb0, 0x72, 0xed, 0x3b, 0x74, 0xed, 0xa1, 0x56, 0xf8, 0xff, 0xc2, 0x8e, ++ 0xbd, 0xc0, 0x73, 0x64, 0x6b, 0xcf, 0xb6, 0x52, 0x5d, 0x79, 0xd5, 0xd6, ++ 0x9c, 0x14, 0x6f, 0x2d, 0x4b, 0x6f, 0x13, 0x08, 0xb6, 0x6e, 0x00, 0x16, ++ 0xcc, 0xd7, 0x92, 0xc9, 0x09, 0x67, 0x6b, 0x12, 0x4b, 0xb4, 0x8d, 0x78, ++ 0x42, 0xa1, 0x54, 0xd3, 0xfa, 0x75, 0xcc, 0x3d, 0x83, 0xef, 0x8c, 0x7a, ++ 0x90, 0xda, 0xac, 0x60, 0x9a, 0xb0, 0xca, 0x76, 0x9a, 0x7f, 0x59, 0xac, ++ 0x59, 0x99, 0x21, 0x3d, 0x24, 0x15, 0xbe, 0x46, 0x3e, 0xd1, 0xba, 0x8a, ++ 0x7c, 0xa2, 0xb2, 0xfe, 0xd3, 0xa4, 0xaf, 0xdc, 0x4c, 0x14, 0x7b, 0x4b, ++ 0x3f, 0x91, 0x2a, 0xf9, 0x45, 0x9d, 0x48, 0xe2, 0xac, 0x3d, 0xf6, 0xe9, ++ 0xec, 0x1b, 0x56, 0xc8, 0xb6, 0x3b, 0x81, 0xc7, 0x56, 0x44, 0xf6, 0xff, ++ 0x27, 0xa9, 0x81, 0xf8, 0x22, 0xd9, 0x65, 0xed, 0x3a, 0xb2, 0x76, 0xb1, ++ 0xf6, 0x2f, 0xf0, 0x23, 0x85, 0x65, 0x3b, 0x20, 0xf6, 0x53, 0xbd, 0x4a, ++ 0xa5, 0x53, 0xed, 0x02, 0xed, 0x30, 0x9e, 0xe9, 0xe6, 0x6b, 0x01, 0xff, ++ 0x81, 0xb1, 0xa4, 0x14, 0xd0, 0xa0, 0xb8, 0x8c, 0x0e, 0x71, 0x60, 0x7a, ++ 0x91, 0xff, 0xd1, 0xb1, 0x0d, 0xe2, 0xd1, 0xe9, 0x46, 0xff, 0x60, 0xba, ++ 0x53, 0x0c, 0xe6, 0x37, 0x0b, 0x73, 0xe2, 0x5b, 0xc2, 0x9c, 0x4e, 0x09, ++ 0x33, 0xdf, 0x43, 0x9f, 0x5b, 0xc4, 0x58, 0x7e, 0x40, 0xec, 0xcd, 0xf3, ++ 0xfc, 0xa4, 0x2b, 0x5a, 0xe3, 0x87, 0x14, 0x7b, 0x9f, 0xa3, 0xd8, 0xfb, ++ 0x2c, 0xc5, 0xde, 0x67, 0xc8, 0xde, 0x7f, 0x70, 0x15, 0xe3, 0xb2, 0x8d, ++ 0x27, 0x19, 0x9b, 0xf8, 0xff, 0xbc, 0x78, 0x86, 0xf4, 0xcd, 0xb2, 0xfb, ++ 0x37, 0x64, 0xdb, 0x2c, 0x93, 0x87, 0x38, 0x57, 0x90, 0x9e, 0xde, 0xb7, ++ 0x6d, 0xf9, 0xb1, 0x15, 0x8c, 0xa5, 0x06, 0xc4, 0x56, 0xa2, 0x2f, 0xe9, ++ 0x24, 0x0c, 0xa4, 0x11, 0x3e, 0xc9, 0x0e, 0x88, 0xbb, 0xf3, 0x7c, 0xfd, ++ 0x20, 0x76, 0x52, 0x4d, 0x78, 0x28, 0x16, 0xee, 0xee, 0x25, 0xec, 0xb4, ++ 0x89, 0xb0, 0xd3, 0xb2, 0x98, 0x8c, 0x8b, 0x2d, 0x9f, 0x58, 0x58, 0x88, ++ 0xe4, 0xfd, 0x71, 0x75, 0x62, 0xa2, 0x92, 0x6f, 0x73, 0x19, 0x70, 0xdd, ++ 0x8e, 0xda, 0x1a, 0x4d, 0x3d, 0x91, 0x44, 0x78, 0x7f, 0x5c, 0x82, 0xe9, ++ 0x36, 0x5c, 0xb8, 0xcf, 0xae, 0x15, 0xd7, 0x63, 0x74, 0x54, 0x60, 0x5b, ++ 0x6b, 0xf2, 0x8f, 0x5c, 0x24, 0xab, 0xb7, 0xdb, 0x11, 0x20, 0xf5, 0x0a, ++ 0x99, 0xea, 0xfa, 0x4e, 0x92, 0x5e, 0x07, 0xe5, 0xdc, 0x27, 0xb2, 0xab, ++ 0xd0, 0xd0, 0x2a, 0x93, 0x0e, 0x9d, 0xb8, 0xb3, 0x78, 0x13, 0xe9, 0x31, ++ 0x72, 0xe4, 0x79, 0x78, 0xfd, 0x2f, 0x8c, 0x19, 0x18, 0xca, 0xe2, 0x7b, ++ 0x3e, 0xaa, 0xe1, 0xee, 0x25, 0xfc, 0xf4, 0x03, 0xa2, 0x61, 0x63, 0x6b, ++ 0xa4, 0x93, 0x6a, 0x79, 0xc5, 0x6b, 0xb8, 0x31, 0xd2, 0xe4, 0x87, 0xa2, ++ 0xa5, 0xc4, 0x2b, 0xf9, 0xc8, 0x91, 0x1d, 0xd2, 0xb7, 0xc4, 0xcf, 0xa7, ++ 0x0d, 0x3c, 0x5a, 0xea, 0x11, 0x7f, 0x31, 0x2d, 0x83, 0x74, 0x43, 0x71, ++ 0x4b, 0xc7, 0x11, 0xa2, 0xcb, 0x45, 0x18, 0xc9, 0xf5, 0xfb, 0x02, 0x8b, ++ 0xb5, 0x24, 0xbe, 0xb3, 0x8a, 0x7d, 0xa1, 0x12, 0xd3, 0x9c, 0xab, 0x80, ++ 0xfd, 0x64, 0x93, 0x0d, 0x99, 0x0e, 0xb1, 0x84, 0xbe, 0x5f, 0xa4, 0xbc, ++ 0x96, 0x94, 0x3a, 0x45, 0x03, 0x61, 0xd3, 0x85, 0x93, 0x5b, 0xc4, 0x82, ++ 0x22, 0x63, 0x51, 0x28, 0x0b, 0x49, 0x46, 0x0b, 0x8b, 0x17, 0x1d, 0x95, ++ 0x1a, 0xc0, 0xc5, 0xb6, 0x64, 0xfa, 0x0c, 0xd9, 0x7f, 0x88, 0x62, 0xfb, ++ 0x8e, 0x58, 0x27, 0xe1, 0x64, 0xbe, 0x3e, 0x20, 0x86, 0x48, 0x8e, 0x13, ++ 0x2e, 0xdb, 0x76, 0xfc, 0x4f, 0x8c, 0xc1, 0xd5, 0x60, 0x20, 0xe4, 0xa6, ++ 0xdc, 0xf1, 0xdf, 0xdb, 0x22, 0xe6, 0xf3, 0x52, 0x97, 0xc8, 0xe5, 0x03, ++ 0xfe, 0x23, 0x63, 0x9c, 0x67, 0x3a, 0xc4, 0x11, 0xd2, 0x79, 0x96, 0x74, ++ 0x9e, 0x25, 0x9d, 0x67, 0x48, 0xe7, 0x99, 0x2f, 0xd1, 0xf9, 0x3e, 0xd2, ++ 0xf9, 0xee, 0xfc, 0xaf, 0x6c, 0x1d, 0x3a, 0x0d, 0x03, 0x59, 0xca, 0xcb, ++ 0x23, 0x4d, 0x15, 0xfe, 0x3e, 0x24, 0x59, 0xbc, 0x14, 0xfb, 0x86, 0x13, ++ 0x5e, 0x83, 0x62, 0x6b, 0x17, 0x3d, 0xf3, 0x95, 0x39, 0x1b, 0x57, 0xfc, ++ 0xc3, 0x63, 0x1d, 0x62, 0x98, 0xfc, 0x6e, 0x84, 0xe6, 0x1f, 0x21, 0xbf, ++ 0x1b, 0x4c, 0xff, 0x9f, 0xd8, 0x0d, 0xdb, 0x1d, 0x4c, 0x2f, 0xe5, 0xad, ++ 0x6a, 0xb2, 0x4b, 0xa7, 0xc1, 0x36, 0xb4, 0x59, 0x24, 0x8f, 0x7e, 0x4b, ++ 0x24, 0x8f, 0xa5, 0x44, 0xb2, 0xd0, 0x43, 0x9f, 0x5b, 0xc4, 0x2d, 0x76, ++ 0x1d, 0x3a, 0x20, 0x3a, 0x0a, 0x01, 0xff, 0x38, 0xad, 0x33, 0x4e, 0x7c, ++ 0x3c, 0x46, 0xeb, 0x3c, 0x66, 0xdb, 0x2e, 0x15, 0x99, 0x5e, 0x5e, 0x8b, ++ 0xed, 0x8c, 0xed, 0xeb, 0x32, 0xd1, 0xce, 0xbe, 0x71, 0xb5, 0xc7, 0x43, ++ 0x7f, 0x37, 0x38, 0xa0, 0xed, 0x74, 0x56, 0x78, 0xe2, 0xdc, 0xcf, 0xb9, ++ 0x9e, 0xe3, 0xb0, 0x62, 0xd7, 0x82, 0xcf, 0x5e, 0xc5, 0x00, 0x8c, 0x07, ++ 0x20, 0x2f, 0x30, 0xb6, 0x18, 0xdf, 0x69, 0xfa, 0x1f, 0x34, 0x5f, 0x3f, ++ 0xf4, 0x55, 0x90, 0x03, 0xc6, 0x5f, 0x1a, 0x63, 0x4d, 0x14, 0xa7, 0x69, ++ 0x4e, 0x39, 0x03, 0x68, 0x19, 0x81, 0xdd, 0x09, 0x41, 0x38, 0x76, 0x11, ++ 0xf9, 0x25, 0xd3, 0xaf, 0x76, 0x52, 0x36, 0xc1, 0xd2, 0x21, 0xc8, 0x4b, ++ 0x8c, 0x9d, 0xb0, 0xb2, 0x90, 0x6b, 0x8d, 0x3e, 0x5c, 0x19, 0x0a, 0x07, ++ 0x3b, 0xa1, 0xa6, 0x2e, 0x38, 0xd4, 0x32, 0xe5, 0xb7, 0xfe, 0xdd, 0x42, ++ 0xed, 0x9b, 0x15, 0xdc, 0x27, 0x62, 0xec, 0xbe, 0x13, 0x2d, 0x36, 0x86, ++ 0xef, 0x43, 0x73, 0x1e, 0x54, 0x87, 0x0b, 0xbc, 0x43, 0x73, 0xbe, 0xa8, ++ 0x7f, 0xc0, 0x39, 0x21, 0x49, 0x58, 0xf0, 0x0b, 0x73, 0x81, 0x70, 0x0c, ++ 0xcf, 0xc3, 0x73, 0x84, 0x95, 0x3e, 0x9a, 0xf7, 0x4d, 0x47, 0x73, 0xff, ++ 0xa0, 0x50, 0x13, 0x5f, 0x9c, 0x6f, 0x59, 0x1e, 0x62, 0x59, 0xc6, 0xb4, ++ 0xaa, 0x35, 0x2f, 0xe3, 0x21, 0xe9, 0x1d, 0x4d, 0x4b, 0xbe, 0x86, 0x10, ++ 0x96, 0x51, 0x9d, 0x1c, 0x2d, 0x32, 0x0f, 0xbb, 0x70, 0x46, 0x57, 0xbb, ++ 0xa9, 0x1a, 0xa5, 0xba, 0xa5, 0x03, 0x07, 0x29, 0xf6, 0x3e, 0x5a, 0xe2, ++ 0x3e, 0xd7, 0x80, 0x58, 0x3e, 0x44, 0x7e, 0x69, 0xdb, 0x13, 0xe4, 0x06, ++ 0xe3, 0x61, 0xdc, 0x40, 0xeb, 0xfb, 0xa9, 0xf6, 0x79, 0x9d, 0xd6, 0x97, ++ 0x32, 0xea, 0x00, 0xad, 0x9f, 0x7a, 0x43, 0x84, 0x67, 0x89, 0xaf, 0x9e, ++ 0x75, 0x8e, 0xe6, 0xbe, 0x5d, 0x42, 0x4d, 0x12, 0xe9, 0xe4, 0xc7, 0xbc, ++ 0xf6, 0xc3, 0xcc, 0x0b, 0x7d, 0x52, 0x9d, 0x43, 0x76, 0xd4, 0x54, 0x90, ++ 0x45, 0x64, 0x78, 0x3d, 0xf6, 0x4e, 0xad, 0xc7, 0x1e, 0xf2, 0xc7, 0x03, ++ 0x7a, 0x2d, 0x42, 0x75, 0xa8, 0xa9, 0xd5, 0x30, 0x7b, 0x41, 0x13, 0x8e, ++ 0x1d, 0x2d, 0x8d, 0x64, 0xc7, 0xa7, 0x1b, 0xaa, 0xf0, 0x91, 0xd5, 0xab, ++ 0xad, 0xef, 0xa4, 0x88, 0x78, 0x83, 0x07, 0xe3, 0x0e, 0xf2, 0xef, 0x5f, ++ 0xfc, 0x9a, 0x02, 0xaa, 0xc7, 0x60, 0xdc, 0x96, 0x10, 0x97, 0xf2, 0x67, ++ 0x9d, 0x15, 0x3f, 0x68, 0xc2, 0x15, 0x05, 0xb5, 0x41, 0x6d, 0x39, 0x66, ++ 0x15, 0x99, 0xe2, 0x85, 0x69, 0xd7, 0x64, 0x37, 0xe7, 0xba, 0xd1, 0x40, ++ 0xf5, 0xf1, 0x9d, 0xb1, 0x5f, 0x5b, 0x9f, 0x2c, 0xe6, 0xe7, 0x4e, 0x7a, ++ 0x2a, 0xb1, 0xf3, 0xcb, 0xe6, 0x88, 0x53, 0xbc, 0x69, 0xa6, 0x7a, 0xb6, ++ 0x9a, 0x82, 0x74, 0x27, 0xe5, 0x23, 0xb5, 0x27, 0x4d, 0xf5, 0x68, 0x5f, ++ 0xa4, 0x59, 0x77, 0x08, 0x37, 0xca, 0x81, 0x70, 0x7f, 0x2f, 0x92, 0xdb, ++ 0xfd, 0x73, 0x74, 0x3c, 0x2b, 0x34, 0x17, 0x3d, 0xc7, 0xf3, 0x5c, 0x63, ++ 0x4f, 0x27, 0xc9, 0x9e, 0xf8, 0x3e, 0x7f, 0xbf, 0x7a, 0x5f, 0xfe, 0x8a, ++ 0xf1, 0x97, 0xff, 0xe4, 0x8f, 0x97, 0x7d, 0xd9, 0xf5, 0x8f, 0xbf, 0xe4, ++ 0xfa, 0xff, 0xae, 0xae, 0x2f, 0xd7, 0x39, 0x6d, 0xcc, 0x90, 0x94, 0xb8, ++ 0x8f, 0xe9, 0x34, 0x2e, 0xaf, 0xd9, 0xa3, 0xfd, 0x0e, 0xc5, 0x34, 0xee, ++ 0x63, 0x70, 0x9e, 0x3e, 0x6f, 0xf7, 0x31, 0x4e, 0x7d, 0x0e, 0xb3, 0x72, ++ 0x6c, 0xf1, 0x88, 0xea, 0x11, 0xd3, 0xaa, 0xd7, 0xbe, 0x4d, 0x75, 0xcd, ++ 0x2e, 0xf4, 0xc6, 0x74, 0x0c, 0x67, 0xd5, 0xee, 0xdb, 0xa0, 0x25, 0x37, ++ 0x0b, 0x9a, 0xa8, 0xe8, 0x11, 0x8e, 0x91, 0xb9, 0x7b, 0xba, 0x49, 0xb5, ++ 0x5a, 0x19, 0x55, 0x14, 0x9b, 0x9c, 0x9a, 0x22, 0xa3, 0x18, 0x90, 0x9d, ++ 0xc5, 0xa0, 0xec, 0x2e, 0x36, 0xca, 0x55, 0x34, 0xce, 0x37, 0xa2, 0xce, ++ 0xde, 0x86, 0x5d, 0x98, 0x6d, 0xf3, 0x9a, 0x0d, 0x86, 0xaa, 0x34, 0x38, ++ 0x76, 0x61, 0x4f, 0x8c, 0x9f, 0xed, 0xa0, 0x9a, 0x0d, 0xa2, 0x2e, 0x43, ++ 0xc8, 0xd8, 0x10, 0xd8, 0xdb, 0xae, 0x0e, 0x2c, 0x95, 0xb4, 0xce, 0x5f, ++ 0x09, 0xa7, 0xec, 0x29, 0x42, 0xf8, 0x33, 0x12, 0x8e, 0xb4, 0xc3, 0xe3, ++ 0x59, 0xa5, 0xf6, 0x9d, 0x16, 0x03, 0x78, 0x2a, 0x16, 0xe9, 0xde, 0x26, ++ 0x42, 0xb2, 0x97, 0xee, 0xb9, 0x32, 0x14, 0x7f, 0x33, 0xa6, 0xc7, 0xb5, ++ 0x4a, 0x0d, 0x4a, 0x22, 0x89, 0x5e, 0x4d, 0xd3, 0x47, 0x20, 0xd3, 0x9a, ++ 0x10, 0x55, 0x19, 0x75, 0xf6, 0x4d, 0xc2, 0x54, 0x9f, 0x2c, 0x1b, 0x40, ++ 0x6b, 0x5b, 0x64, 0x7f, 0x8f, 0xa4, 0xc9, 0x84, 0xf5, 0x84, 0x33, 0xe3, ++ 0xc3, 0xca, 0xc3, 0xf3, 0x7d, 0x1d, 0xcb, 0xfa, 0x30, 0x56, 0x26, 0xbd, ++ 0x40, 0xae, 0x29, 0x46, 0x65, 0x1f, 0xe1, 0xfa, 0xe6, 0xc3, 0x8c, 0xb3, ++ 0x2c, 0x6b, 0x47, 0xac, 0xfc, 0x75, 0x2f, 0x5a, 0x88, 0xc7, 0x6e, 0x4c, ++ 0xa5, 0x19, 0x77, 0x19, 0x98, 0xa4, 0x9a, 0x48, 0x1b, 0x6a, 0xc4, 0x71, ++ 0x8a, 0x43, 0x33, 0x69, 0xee, 0xff, 0xf4, 0x91, 0x8c, 0x7b, 0x88, 0xfe, ++ 0x2d, 0x54, 0x0f, 0xa7, 0x28, 0x7e, 0xb1, 0x8c, 0x7b, 0xc9, 0xee, 0x21, ++ 0x7b, 0x8d, 0x3a, 0xe3, 0xe6, 0x61, 0xc8, 0x1e, 0xc3, 0x6b, 0x5c, 0x77, ++ 0x18, 0x75, 0x94, 0xf7, 0x0d, 0xaa, 0x78, 0x10, 0x8d, 0x44, 0xf4, 0x8b, ++ 0x88, 0x04, 0x5f, 0x24, 0x7d, 0x0c, 0x6a, 0xc0, 0x6e, 0xbb, 0xd6, 0x76, ++ 0xc2, 0xcc, 0x73, 0x0d, 0x0d, 0x4f, 0x55, 0x7b, 0x1d, 0xde, 0xc9, 0x45, ++ 0xed, 0x1e, 0x92, 0x49, 0xf5, 0xcf, 0x0b, 0xba, 0x9a, 0x9a, 0xa0, 0xe7, ++ 0xb6, 0x2a, 0xff, 0x65, 0x5f, 0x75, 0x1c, 0x32, 0xc5, 0x34, 0xb2, 0xbd, ++ 0x3f, 0xf5, 0xbe, 0x49, 0x36, 0x7a, 0xfb, 0xd8, 0x9f, 0x79, 0xaf, 0xc4, ++ 0x27, 0xbc, 0x1f, 0xc4, 0x2d, 0x2b, 0x41, 0x78, 0xb4, 0x87, 0xea, 0xed, ++ 0x0f, 0x87, 0x4c, 0xef, 0xc5, 0x38, 0xf7, 0x81, 0x9d, 0xf8, 0x3d, 0xfa, ++ 0xfd, 0xe4, 0x90, 0x8c, 0x4d, 0x85, 0x06, 0xb8, 0x86, 0x1d, 0x98, 0xd2, ++ 0x6f, 0x44, 0xaf, 0x22, 0xe1, 0xee, 0xe8, 0x49, 0xb2, 0x49, 0x89, 0xc6, ++ 0x1c, 0xa2, 0xdf, 0xdc, 0xd3, 0x7a, 0x0c, 0xdb, 0x94, 0x69, 0xef, 0x3b, ++ 0x71, 0xa6, 0x17, 0x4c, 0xaf, 0x2c, 0x69, 0xb7, 0x62, 0xeb, 0x6d, 0x5c, ++ 0x5b, 0xd9, 0xff, 0x9e, 0x17, 0xdb, 0xeb, 0x71, 0x3c, 0xd7, 0x80, 0xe7, ++ 0x73, 0xa6, 0xe7, 0xb5, 0xf6, 0x28, 0xfa, 0x86, 0x2c, 0xbc, 0xac, 0x9b, ++ 0x03, 0x55, 0x64, 0xe7, 0x09, 0xaa, 0xaf, 0xc2, 0x6d, 0xdc, 0x4b, 0x40, ++ 0xc4, 0x81, 0x48, 0x3f, 0x81, 0xcc, 0x3b, 0x28, 0x74, 0xa5, 0x6a, 0xa8, ++ 0x4e, 0x3b, 0x27, 0x2c, 0xf7, 0xf6, 0x76, 0x27, 0xd1, 0x00, 0x6c, 0x28, ++ 0xb4, 0x90, 0xdc, 0xa2, 0xd8, 0x14, 0x91, 0xb1, 0xb1, 0xa0, 0xe3, 0xf9, ++ 0xb4, 0x0f, 0xb7, 0x17, 0xe2, 0x84, 0xbd, 0x15, 0xa2, 0x3d, 0x81, 0x52, ++ 0x3a, 0x80, 0x6f, 0x14, 0x1a, 0x49, 0xde, 0x41, 0xdc, 0x58, 0x08, 0xe1, ++ 0x44, 0x9a, 0xf3, 0xb7, 0xe1, 0xd9, 0x1a, 0x6f, 0x44, 0x67, 0x41, 0xc3, ++ 0x74, 0x1a, 0x9e, 0x07, 0xe2, 0x21, 0x74, 0x14, 0xa2, 0x28, 0x10, 0x86, ++ 0xbb, 0x95, 0xe6, 0xbc, 0x9d, 0x74, 0xd2, 0x52, 0x08, 0x60, 0x69, 0x84, ++ 0x22, 0x72, 0xc1, 0x27, 0x06, 0x08, 0x5b, 0x25, 0x0a, 0xf5, 0xb8, 0x38, ++ 0xcc, 0x76, 0xae, 0x18, 0x7b, 0x72, 0x0a, 0x42, 0x05, 0xac, 0x94, 0x01, ++ 0x0a, 0xd6, 0x91, 0x54, 0x81, 0xe8, 0x3d, 0xd8, 0x5e, 0xe9, 0xe1, 0x2e, ++ 0x2f, 0x7c, 0xc6, 0x6f, 0x2d, 0xe9, 0xe9, 0xca, 0xe1, 0x69, 0xef, 0x27, ++ 0x71, 0x8e, 0x4d, 0x9f, 0xae, 0x79, 0xfd, 0x30, 0x10, 0x1d, 0x67, 0xde, ++ 0xec, 0xd8, 0xc8, 0xf1, 0xb0, 0x45, 0xc6, 0xaf, 0x2c, 0xaa, 0x41, 0x43, ++ 0x53, 0xbc, 0x57, 0xa0, 0xf9, 0x88, 0x0e, 0x05, 0x49, 0x5a, 0xfb, 0x96, ++ 0xc2, 0x0f, 0xad, 0xad, 0x0b, 0x83, 0xb8, 0x39, 0x52, 0x91, 0xd5, 0x39, ++ 0xd2, 0xe1, 0xe4, 0x70, 0x03, 0x66, 0x88, 0x06, 0x97, 0xe1, 0x36, 0x8e, ++ 0x8d, 0x59, 0xd8, 0xa0, 0x9b, 0xde, 0xd7, 0xda, 0x97, 0xe3, 0xfe, 0xc3, ++ 0x83, 0x67, 0xdd, 0xa4, 0xd7, 0x59, 0xfd, 0x0e, 0x3c, 0x3a, 0x8e, 0xaf, ++ 0x35, 0x00, 0x8f, 0x04, 0xc1, 0x3d, 0x6b, 0x35, 0x74, 0x02, 0x91, 0xce, ++ 0x07, 0x10, 0x51, 0x34, 0xa1, 0xea, 0x2f, 0x0b, 0x24, 0xab, 0x8d, 0xc8, ++ 0xd9, 0x5b, 0x80, 0x33, 0x6e, 0xf2, 0xe0, 0xdb, 0x0b, 0x4e, 0x92, 0x51, ++ 0x10, 0xa5, 0x61, 0x37, 0x1c, 0xe4, 0x27, 0x97, 0x34, 0x6c, 0xa8, 0x25, ++ 0x59, 0x3b, 0x84, 0x4c, 0x7a, 0x6e, 0xc1, 0xb1, 0xa1, 0x79, 0x59, 0xf9, ++ 0x70, 0x13, 0xc9, 0xf0, 0xa9, 0x21, 0x6b, 0x97, 0x16, 0x0b, 0x90, 0xac, ++ 0x15, 0xa2, 0x6f, 0x5e, 0x4e, 0x2c, 0xbf, 0x79, 0x39, 0xdd, 0x81, 0x3d, ++ 0x33, 0x2c, 0xb7, 0xff, 0x1b, 0x79, 0x4d, 0xdb, 0x76, 0xb7, 0x61, 0x2c, ++ 0x8a, 0x86, 0xc3, 0x57, 0x65, 0xc7, 0xf4, 0x3d, 0x42, 0x7c, 0x7c, 0xcf, ++ 0xbf, 0x3a, 0xd2, 0xf7, 0xbe, 0xf0, 0x11, 0x3d, 0x0a, 0xe9, 0xe6, 0x03, ++ 0x17, 0x63, 0x77, 0x92, 0xc9, 0x55, 0x19, 0x07, 0x49, 0xc6, 0xc1, 0x71, ++ 0x96, 0xf5, 0xa7, 0x6b, 0xae, 0x90, 0x7c, 0x5f, 0x27, 0x5c, 0x76, 0x43, ++ 0x2c, 0x8a, 0x9a, 0xc3, 0x6a, 0xb2, 0xc1, 0x11, 0x4e, 0xd4, 0x0a, 0x50, ++ 0x55, 0x82, 0x96, 0x1a, 0x7c, 0xc8, 0x72, 0xd6, 0x49, 0xce, 0xdf, 0x1b, ++ 0x24, 0x7e, 0xd6, 0xd3, 0x7c, 0x1b, 0x48, 0xce, 0x49, 0xe2, 0xff, 0x16, ++ 0x7b, 0xde, 0x46, 0x9a, 0x77, 0x0b, 0xd5, 0x1e, 0xd3, 0xde, 0x4b, 0x44, ++ 0x4f, 0xf4, 0x33, 0x5a, 0x08, 0x8d, 0x47, 0x82, 0xef, 0x53, 0x8d, 0x7d, ++ 0xa3, 0x3d, 0x4e, 0xa1, 0x71, 0x4c, 0xfb, 0xcf, 0xab, 0x24, 0xed, 0xcb, ++ 0xfa, 0xcd, 0xdf, 0x02, 0xf7, 0x1c, 0x4c, 0xf4, 0x50, 0x1d, 0xb1, 0x85, ++ 0x6a, 0x25, 0x99, 0x72, 0x9b, 0x89, 0x1f, 0xc4, 0xd5, 0x68, 0x9d, 0xe0, ++ 0xf8, 0x67, 0x92, 0x1f, 0x96, 0xa9, 0x4e, 0x0a, 0x87, 0x66, 0x10, 0x94, ++ 0xa5, 0xa2, 0x4c, 0x78, 0xb0, 0x51, 0x76, 0x14, 0xc9, 0x5f, 0x83, 0x3d, ++ 0x84, 0xa7, 0x9d, 0x78, 0x31, 0xef, 0xc4, 0x2b, 0xe9, 0x2d, 0x38, 0x50, ++ 0xf2, 0x10, 0x6e, 0x36, 0x3d, 0xce, 0x55, 0x13, 0xee, 0x4a, 0x4c, 0x5e, ++ 0x86, 0xae, 0x91, 0x87, 0x51, 0x9d, 0x71, 0x76, 0x53, 0x3e, 0xd5, 0x6f, ++ 0x21, 0xb9, 0x6c, 0x28, 0xf2, 0xfd, 0x46, 0x64, 0xd2, 0x29, 0xc2, 0x40, ++ 0x61, 0xaa, 0x81, 0x9c, 0x98, 0x68, 0x68, 0xb4, 0xfb, 0xba, 0x39, 0xba, ++ 0x96, 0x2b, 0x7d, 0xb1, 0xdf, 0x7c, 0xc7, 0x5c, 0x9f, 0xb9, 0x0f, 0xfb, ++ 0xb2, 0x3d, 0x84, 0x4d, 0xb7, 0x50, 0x7c, 0xaf, 0xd0, 0x38, 0x1d, 0xef, ++ 0xc6, 0xbe, 0xbc, 0x71, 0x35, 0x7e, 0x4c, 0xda, 0xf1, 0xa3, 0x1f, 0x55, ++ 0xed, 0xbc, 0x7f, 0xb5, 0x05, 0x77, 0xa5, 0x81, 0xf7, 0xd2, 0xdc, 0x4f, ++ 0x24, 0x4c, 0x41, 0xf9, 0xe0, 0x90, 0xce, 0x39, 0x74, 0x0b, 0x96, 0xe6, ++ 0x2d, 0xe4, 0x75, 0x0b, 0x67, 0x75, 0x8d, 0x72, 0x34, 0xe7, 0xea, 0x01, ++ 0xa1, 0x51, 0x7e, 0x36, 0x9d, 0xfd, 0x88, 0xb4, 0xb3, 0x8e, 0x1e, 0x9e, ++ 0xdb, 0x87, 0xea, 0xb7, 0xf7, 0xa1, 0x66, 0xd2, 0x0e, 0x3c, 0x45, 0x8a, ++ 0x78, 0x3e, 0x1b, 0x0e, 0xbd, 0x07, 0x6b, 0x97, 0xc3, 0x50, 0x13, 0x4e, ++ 0x07, 0xef, 0xcf, 0xf0, 0xfe, 0x94, 0xd6, 0xbd, 0xd4, 0xa1, 0xea, 0x45, ++ 0xd1, 0xdc, 0xf3, 0x16, 0xca, 0x1b, 0x65, 0xa8, 0xa1, 0xd7, 0x10, 0x89, ++ 0x76, 0xf2, 0x1e, 0x44, 0xa9, 0x92, 0xbb, 0x97, 0xcd, 0xe5, 0x6e, 0x2d, ++ 0xef, 0x15, 0xe1, 0x61, 0x09, 0x13, 0x53, 0x96, 0x29, 0x91, 0xfd, 0x4e, ++ 0xd1, 0x9c, 0x3f, 0xce, 0xee, 0x42, 0x36, 0x66, 0x59, 0xb7, 0xc7, 0xb5, ++ 0xbe, 0x06, 0x07, 0xfe, 0x90, 0x32, 0x39, 0xc8, 0xe6, 0x53, 0xe4, 0x6b, ++ 0xa1, 0x1d, 0xed, 0xa6, 0xe5, 0xb6, 0xeb, 0x0a, 0xee, 0x4f, 0x76, 0x89, ++ 0x96, 0xc2, 0x16, 0xb1, 0x9c, 0xb0, 0x5b, 0xe8, 0xd8, 0x66, 0xd1, 0x74, ++ 0xb4, 0x82, 0xdd, 0x22, 0x85, 0xcf, 0x7a, 0xa8, 0x37, 0xa7, 0x2d, 0xa4, ++ 0x89, 0xaf, 0xa7, 0xfe, 0x0e, 0x5f, 0xac, 0x8b, 0x7e, 0x5c, 0xd7, 0xce, ++ 0xbe, 0xf8, 0x30, 0x8e, 0xa5, 0xd9, 0xce, 0xfb, 0xb1, 0x87, 0xe4, 0xb3, ++ 0x62, 0x88, 0xf7, 0xc3, 0xd4, 0xb3, 0x83, 0x08, 0xf7, 0xbd, 0x2a, 0xd4, ++ 0x72, 0x01, 0xcd, 0x7a, 0x8d, 0x83, 0xe3, 0xab, 0x3a, 0xd0, 0xe4, 0xa8, ++ 0xd0, 0x9f, 0xc8, 0x83, 0xe2, 0x69, 0x85, 0x87, 0x95, 0xf9, 0xa5, 0x64, ++ 0xab, 0xa6, 0xe7, 0x52, 0xbc, 0xb9, 0xbf, 0x1a, 0x1b, 0xc4, 0x07, 0xd3, ++ 0x21, 0x78, 0x0f, 0x27, 0x17, 0xfa, 0xd1, 0x21, 0xde, 0xb3, 0xeb, 0xc5, ++ 0x4e, 0xf1, 0x4e, 0xbe, 0x5b, 0x5c, 0x9e, 0xe8, 0x42, 0x64, 0xf8, 0x3e, ++ 0xf1, 0xf6, 0x04, 0xd3, 0xd9, 0x23, 0xce, 0x4f, 0x73, 0x9f, 0xd4, 0xc2, ++ 0x1e, 0x9d, 0xfb, 0xa2, 0x8b, 0xab, 0xe0, 0xb7, 0x70, 0x4c, 0x67, 0x7d, ++ 0x72, 0x9f, 0xb0, 0xd2, 0x5f, 0xda, 0x10, 0xcf, 0x59, 0x4e, 0x8d, 0x7b, ++ 0xc5, 0x41, 0x9b, 0xdf, 0x29, 0xc2, 0xd1, 0xd3, 0x13, 0x5b, 0xc4, 0xf1, ++ 0x7c, 0x85, 0xd7, 0xc9, 0x3c, 0xdb, 0xaf, 0x4c, 0x3a, 0xfe, 0x62, 0x9e, ++ 0x36, 0xa1, 0xb4, 0x07, 0xe1, 0xb6, 0xfb, 0x51, 0x16, 0x46, 0xf4, 0x48, ++ 0xe8, 0x65, 0x04, 0xe1, 0x2c, 0xb2, 0x6d, 0x5b, 0x78, 0x5a, 0x77, 0xc1, ++ 0x31, 0x22, 0x93, 0x8c, 0xc8, 0x96, 0xfc, 0x2e, 0x48, 0x93, 0x5c, 0x1b, ++ 0x7c, 0xbd, 0x8a, 0xfb, 0x14, 0x21, 0x89, 0xbf, 0x7f, 0xd1, 0xe6, 0x5c, ++ 0x94, 0x0f, 0xb8, 0xbf, 0xfe, 0x57, 0xee, 0x8a, 0xed, 0xb1, 0x5d, 0xcd, ++ 0xf7, 0xc4, 0x29, 0xd7, 0xb6, 0x73, 0x2f, 0xdc, 0x83, 0x99, 0x9c, 0x9b, ++ 0x5b, 0x14, 0x1e, 0x77, 0xbb, 0x85, 0x0b, 0xba, 0x93, 0xea, 0x97, 0x87, ++ 0x28, 0x47, 0x49, 0x90, 0xb5, 0x3b, 0x50, 0x1c, 0x73, 0x4a, 0xbc, 0x5f, ++ 0xf5, 0xb3, 0x18, 0xf7, 0x10, 0x80, 0x43, 0xc4, 0xc3, 0xf7, 0x73, 0x21, ++ 0x6c, 0xa2, 0xba, 0x2b, 0x64, 0xd7, 0x18, 0xbf, 0x87, 0x53, 0x39, 0x87, ++ 0xa0, 0xba, 0xc2, 0x91, 0x58, 0x6d, 0xe1, 0x4a, 0x5b, 0x24, 0xca, 0x7d, ++ 0x68, 0x85, 0x72, 0xd6, 0xde, 0x7c, 0x1d, 0x7e, 0x96, 0xab, 0xc3, 0x2b, ++ 0x39, 0x0b, 0x07, 0x63, 0x83, 0x3d, 0x5e, 0x8a, 0x95, 0xcb, 0x62, 0x2e, ++ 0xec, 0x88, 0x98, 0x8a, 0x17, 0x51, 0x5c, 0x48, 0x5c, 0x87, 0x54, 0x20, ++ 0xdc, 0x39, 0x88, 0x7a, 0xbc, 0x91, 0x03, 0x61, 0x09, 0x78, 0x96, 0xd2, ++ 0x1c, 0x6f, 0xc7, 0xcc, 0x7e, 0x17, 0xe1, 0xd8, 0x9f, 0x0b, 0xc4, 0x6b, ++ 0x60, 0xb9, 0xcf, 0xc4, 0x29, 0x57, 0x17, 0xea, 0xd0, 0x95, 0xab, 0x47, ++ 0x0f, 0xe5, 0xac, 0x75, 0xab, 0xe3, 0x78, 0x2b, 0xeb, 0x13, 0x2b, 0xb3, ++ 0x83, 0x3d, 0x0a, 0xcd, 0xe9, 0x6a, 0x53, 0xfb, 0x9f, 0x22, 0xe0, 0x26, ++ 0x23, 0x4c, 0xe6, 0x8e, 0x07, 0xfc, 0x14, 0x77, 0x8f, 0x8b, 0x4f, 0xf1, ++ 0x04, 0xd9, 0xe3, 0x3d, 0xba, 0x5a, 0xbe, 0xe4, 0x88, 0x9c, 0xdd, 0x08, ++ 0x75, 0xe0, 0x16, 0x61, 0x46, 0x6b, 0x29, 0x9e, 0x34, 0x54, 0x62, 0x85, ++ 0x19, 0x11, 0x32, 0x61, 0x73, 0x27, 0x3c, 0x9a, 0x89, 0xce, 0x76, 0x96, ++ 0xa9, 0x07, 0x9e, 0xa3, 0x64, 0x47, 0xd2, 0x17, 0xfb, 0xfb, 0x75, 0x78, ++ 0x9d, 0xf2, 0xe5, 0xb9, 0x1c, 0xf7, 0xe6, 0xdd, 0xc6, 0xbb, 0x94, 0x03, ++ 0x5e, 0x8a, 0x0d, 0x86, 0x38, 0xf6, 0xe7, 0x63, 0xf8, 0xe7, 0x64, 0x96, ++ 0x8d, 0x3e, 0x5a, 0xf3, 0x2e, 0xc1, 0xeb, 0x20, 0xb9, 0xc4, 0xe0, 0xbe, ++ 0x9c, 0xcd, 0x0f, 0xc5, 0x63, 0xe6, 0xe9, 0xff, 0x27, 0xed, 0x8f, 0x54, ++ 0xc1, 0x5b, 0x4f, 0xba, 0x9c, 0xef, 0x69, 0x5e, 0xdb, 0xcf, 0xe4, 0x7a, ++ 0xa6, 0x82, 0x0f, 0xdd, 0x46, 0xb5, 0x78, 0x21, 0xc7, 0x36, 0x67, 0xe1, ++ 0x19, 0x5d, 0xa7, 0xda, 0x85, 0x6b, 0xf2, 0x7e, 0xaa, 0x5f, 0xb8, 0xcf, ++ 0x64, 0x7a, 0xce, 0x10, 0x85, 0xfb, 0x73, 0x58, 0x2b, 0xc3, 0xb1, 0xa2, ++ 0x0a, 0xe3, 0x98, 0x70, 0x3a, 0x09, 0x73, 0x70, 0xac, 0x65, 0x7f, 0x52, ++ 0x0c, 0x6d, 0x82, 0xeb, 0xcf, 0x4e, 0x98, 0xb6, 0x1f, 0x57, 0x8b, 0xfb, ++ 0xc9, 0x46, 0x5e, 0x8c, 0x55, 0x61, 0x82, 0xea, 0x1f, 0xc9, 0x30, 0x3d, ++ 0xdf, 0xa5, 0xe7, 0x13, 0xa3, 0xd8, 0x17, 0x84, 0xe3, 0x4f, 0x14, 0xfc, ++ 0x19, 0xde, 0x74, 0xc9, 0x74, 0x1d, 0x9e, 0xee, 0xb8, 0xe9, 0xdd, 0x18, ++ 0xaf, 0x16, 0xb7, 0xe6, 0x5a, 0xf0, 0xfe, 0x58, 0x1d, 0xd9, 0x77, 0x3d, ++ 0x96, 0x8c, 0x04, 0xf1, 0x36, 0xd1, 0x32, 0x40, 0xb4, 0x7c, 0xd2, 0x66, ++ 0x0e, 0x34, 0x40, 0xed, 0xa7, 0xba, 0xa8, 0x9b, 0xfb, 0xcd, 0x4f, 0xeb, ++ 0x6a, 0xe7, 0x6d, 0xc2, 0x0b, 0x2d, 0x92, 0x24, 0xd9, 0x5b, 0xd6, 0xb0, ++ 0xde, 0xac, 0xfb, 0xc0, 0xfd, 0xa3, 0x3b, 0x70, 0x68, 0x86, 0x69, 0x71, ++ 0x1b, 0xcb, 0xa7, 0xf9, 0x53, 0x36, 0xae, 0xb3, 0x3f, 0xbd, 0x73, 0x9f, ++ 0x30, 0x42, 0xf6, 0xe7, 0xa7, 0x6b, 0x42, 0xd3, 0xdc, 0xa7, 0x0e, 0x9b, ++ 0x6e, 0xf1, 0x53, 0x17, 0xf7, 0xab, 0x93, 0xe0, 0xff, 0x57, 0x5d, 0x95, ++ 0x7e, 0xdf, 0x1d, 0x30, 0xed, 0x1e, 0xca, 0x15, 0xbb, 0x97, 0x1d, 0x22, ++ 0x37, 0x90, 0x89, 0x3f, 0x99, 0x30, 0x57, 0x20, 0x46, 0x05, 0x7c, 0xbd, ++ 0x6c, 0x2e, 0x31, 0x7a, 0xa8, 0x46, 0x90, 0x89, 0x5f, 0x13, 0xfb, 0xda, ++ 0x05, 0x0e, 0x69, 0x06, 0x5e, 0xcb, 0x73, 0x2c, 0x77, 0xe2, 0xfb, 0x69, ++ 0x35, 0x94, 0x12, 0xe1, 0xce, 0x5b, 0x84, 0x84, 0x50, 0x43, 0x0f, 0x0e, ++ 0x51, 0x5e, 0x99, 0x4e, 0x73, 0x1e, 0x71, 0xda, 0xe7, 0x05, 0x6a, 0x29, ++ 0x0e, 0x7d, 0x38, 0x54, 0x89, 0xfb, 0x85, 0xb8, 0xba, 0xff, 0xf7, 0x48, ++ 0xa7, 0x4f, 0x17, 0x78, 0x4e, 0x13, 0x9f, 0xac, 0x66, 0x1f, 0x56, 0xa3, ++ 0x29, 0xe9, 0x5e, 0x84, 0xa6, 0x38, 0xb6, 0xd0, 0x72, 0xb4, 0xd6, 0x91, ++ 0xac, 0x1b, 0xdd, 0xf1, 0x2e, 0xd1, 0x53, 0xfc, 0x67, 0xbc, 0x27, 0xa1, ++ 0x2c, 0x30, 0x36, 0x8b, 0xf5, 0x93, 0xdc, 0x53, 0xdc, 0x22, 0xba, 0x8b, ++ 0xdc, 0x57, 0x1c, 0x10, 0xbf, 0x5f, 0x64, 0x9f, 0x9f, 0xef, 0x2f, 0xce, ++ 0xeb, 0x9f, 0xfb, 0x8a, 0xa6, 0xe7, 0x05, 0x92, 0xfd, 0x03, 0x39, 0x8e, ++ 0xc9, 0x8e, 0xfb, 0xfd, 0x68, 0xc3, 0x84, 0x0b, 0x9e, 0xd3, 0xf1, 0xaf, ++ 0xe0, 0x76, 0xc2, 0x07, 0x4b, 0xb4, 0x8a, 0xfe, 0xd6, 0x4d, 0x48, 0x48, ++ 0xb4, 0x91, 0xd0, 0x17, 0xb0, 0x4e, 0x7b, 0x29, 0x9e, 0x65, 0xac, 0xbe, ++ 0x00, 0xeb, 0x92, 0xed, 0xcd, 0x2e, 0xf7, 0x28, 0x0e, 0x9b, 0x94, 0x57, ++ 0x3c, 0x98, 0xce, 0x2d, 0xa2, 0xda, 0xc0, 0xc2, 0x7e, 0xbd, 0x06, 0x55, ++ 0x76, 0x0c, 0xf0, 0x10, 0x9e, 0x84, 0xec, 0xa3, 0x79, 0xd2, 0xc3, 0x32, ++ 0xbc, 0x74, 0xef, 0x8c, 0x4e, 0x72, 0x69, 0xaf, 0xcc, 0xdd, 0x3c, 0xb1, ++ 0x12, 0x07, 0xc9, 0xe3, 0x6b, 0xb4, 0x28, 0x86, 0x14, 0x1f, 0xc5, 0x9a, ++ 0x3b, 0xe6, 0xe6, 0xf4, 0xd0, 0x60, 0x5e, 0xaf, 0xbf, 0xaa, 0xa2, 0x87, ++ 0x35, 0x72, 0xa5, 0x06, 0x93, 0xcd, 0x6a, 0x5a, 0x6b, 0x47, 0xfb, 0x16, ++ 0x74, 0x0e, 0xf9, 0xc4, 0x2b, 0xe9, 0xbb, 0xad, 0x50, 0x1d, 0x8d, 0x23, ++ 0x9b, 0x75, 0xcf, 0xd1, 0xdb, 0x34, 0x21, 0xf3, 0x58, 0xee, 0x79, 0xe0, ++ 0xc1, 0x9c, 0x84, 0xc0, 0xdc, 0xf5, 0xf8, 0x44, 0x08, 0x7a, 0x6b, 0x35, ++ 0x50, 0x2f, 0xe8, 0x1a, 0xcf, 0xcd, 0x6b, 0xc8, 0xa8, 0x23, 0x3f, 0xb9, ++ 0x33, 0x9e, 0xc0, 0xbb, 0x59, 0x27, 0x36, 0x52, 0x9e, 0xbf, 0x31, 0x6d, ++ 0xe0, 0x42, 0x29, 0x60, 0xcf, 0x21, 0x19, 0xf3, 0xe3, 0x9c, 0x34, 0xce, ++ 0x83, 0xc9, 0x89, 0x2f, 0xd2, 0x17, 0x20, 0x9a, 0x7f, 0x42, 0xdf, 0xf9, ++ 0xde, 0x45, 0xbb, 0x3f, 0x70, 0xea, 0x9a, 0xba, 0x4a, 0x1a, 0xe1, 0x9e, ++ 0x52, 0x25, 0x17, 0x74, 0xe8, 0xac, 0x4b, 0x3f, 0x66, 0x47, 0x4d, 0x5c, ++ 0x58, 0x5d, 0x8b, 0x4f, 0x46, 0x9b, 0x70, 0x7f, 0xce, 0x8b, 0x4b, 0xa3, ++ 0x16, 0x56, 0xb6, 0xe1, 0xee, 0x20, 0x61, 0xb1, 0x5a, 0xf2, 0xfb, 0xd7, ++ 0xa8, 0xf6, 0xa1, 0x78, 0x4a, 0x94, 0x46, 0x12, 0x1b, 0xc8, 0xae, 0xa3, ++ 0x31, 0xa4, 0x6e, 0x8a, 0x47, 0x42, 0x17, 0xf1, 0x3d, 0x8b, 0x62, 0xb1, ++ 0xe2, 0x30, 0xba, 0x84, 0xd3, 0xde, 0x67, 0xdc, 0x62, 0xef, 0x4b, 0x4a, ++ 0x93, 0x03, 0xc2, 0x51, 0xbc, 0xd6, 0xaf, 0xbf, 0x2c, 0x0f, 0x71, 0xee, ++ 0xe1, 0x1e, 0xc6, 0x88, 0xe5, 0xd2, 0xb8, 0x57, 0xb3, 0x59, 0xec, 0x9d, ++ 0xb8, 0x9a, 0x9b, 0xae, 0xe6, 0xa3, 0xdd, 0x73, 0x79, 0x68, 0x30, 0xff, ++ 0x8b, 0x2f, 0xe0, 0xa8, 0xd0, 0xdc, 0x7e, 0x07, 0xe7, 0x1f, 0x8f, 0x78, ++ 0x93, 0xcc, 0x61, 0x1f, 0xf9, 0xe0, 0x49, 0xfd, 0x74, 0x90, 0x32, 0x04, ++ 0x9c, 0xad, 0x02, 0x0f, 0xf2, 0x59, 0x93, 0x80, 0x85, 0xcd, 0x7a, 0xc5, ++ 0x1e, 0xda, 0xda, 0x5d, 0xe8, 0xa3, 0x9c, 0xe4, 0x8a, 0xf9, 0xc8, 0xd7, ++ 0x15, 0xbc, 0xaa, 0xb3, 0x0d, 0x6f, 0x9e, 0xcb, 0x49, 0xbc, 0x7f, 0x5e, ++ 0xd9, 0xeb, 0xfe, 0x7c, 0xdf, 0x7b, 0xde, 0x36, 0x75, 0x24, 0x17, 0xc2, ++ 0xfb, 0x76, 0x5c, 0xa3, 0xfa, 0x41, 0xa6, 0xda, 0x61, 0x23, 0x12, 0x0b, ++ 0x54, 0x6e, 0x6d, 0x10, 0xf6, 0x36, 0xf1, 0xef, 0xdb, 0xfb, 0x70, 0xdf, ++ 0x88, 0x84, 0x6a, 0x8d, 0xe3, 0xac, 0x89, 0x43, 0x75, 0x1c, 0xa7, 0xba, ++ 0xb0, 0x6b, 0xc4, 0x23, 0xce, 0xe4, 0x9c, 0x78, 0xa2, 0xfb, 0x11, 0x2c, ++ 0x68, 0xbd, 0x07, 0xb0, 0x6d, 0x90, 0xbf, 0x7f, 0x0b, 0xa9, 0x45, 0xbc, ++ 0x3e, 0xf7, 0xda, 0x04, 0x7c, 0xad, 0xcc, 0x07, 0xbc, 0xef, 0xd3, 0xfc, ++ 0xdb, 0x86, 0x9c, 0xe2, 0x62, 0xfa, 0x3f, 0x5b, 0x27, 0x02, 0x8c, 0x13, ++ 0xf8, 0x5e, 0x0d, 0xcc, 0x3a, 0x1e, 0xcb, 0x3a, 0xf4, 0x51, 0x6d, 0xda, ++ 0x87, 0x21, 0xa2, 0xeb, 0x9c, 0x3d, 0xd7, 0x95, 0x39, 0xfa, 0x7d, 0xa2, ++ 0x36, 0x23, 0x9b, 0x41, 0xa2, 0x45, 0x59, 0xdd, 0x8d, 0xda, 0xe2, 0xb5, ++ 0xf9, 0xb6, 0xc6, 0xc3, 0xfd, 0x4a, 0xd2, 0x15, 0xe5, 0x84, 0x5e, 0xbc, ++ 0x9b, 0x16, 0x78, 0xc7, 0xb6, 0xc1, 0x5e, 0x34, 0xe5, 0x6b, 0x00, 0x3b, ++ 0x86, 0xf0, 0xb8, 0xaf, 0x57, 0x6c, 0x5b, 0xea, 0xc3, 0x03, 0xc4, 0x4b, ++ 0x0d, 0xf1, 0xf2, 0x61, 0x6c, 0x29, 0xad, 0xc3, 0xd7, 0xfe, 0x9d, 0x3c, ++ 0x77, 0xd6, 0x68, 0x6e, 0x2e, 0x4a, 0x18, 0x7e, 0xae, 0xf7, 0x22, 0xd8, ++ 0x39, 0x12, 0xe9, 0xf1, 0x49, 0x6c, 0x87, 0x11, 0xdc, 0x3b, 0x79, 0x2b, ++ 0xdd, 0xe7, 0xb9, 0x82, 0xb8, 0x2b, 0xe3, 0x14, 0x6f, 0x51, 0xbd, 0x74, ++ 0x2a, 0x2d, 0x2d, 0x72, 0xe0, 0x39, 0xeb, 0x89, 0xc0, 0x2e, 0xdc, 0xa4, ++ 0x77, 0x61, 0x3b, 0xd9, 0x60, 0x47, 0xd3, 0x2e, 0x8c, 0x92, 0x0d, 0x6c, ++ 0xab, 0xa7, 0x1a, 0x2e, 0x56, 0xb2, 0x7a, 0x03, 0x2c, 0x47, 0x81, 0x4e, ++ 0xba, 0x5e, 0x47, 0x75, 0x9d, 0x14, 0x23, 0x6b, 0x23, 0xbf, 0x90, 0x35, ++ 0x35, 0x97, 0xc4, 0xef, 0xd8, 0x6b, 0xd6, 0x51, 0x9e, 0x76, 0x31, 0x3e, ++ 0xf0, 0x33, 0x4e, 0xf8, 0x22, 0x3d, 0xa6, 0x55, 0xa5, 0x69, 0xd1, 0x8d, ++ 0x52, 0x53, 0x6e, 0x86, 0x6c, 0x76, 0x7d, 0xeb, 0xb5, 0xcf, 0xcd, 0xcb, ++ 0x48, 0x87, 0xbb, 0x75, 0xca, 0x2a, 0x2b, 0x83, 0x50, 0x5a, 0xaf, 0xd5, ++ 0xfd, 0xfc, 0x1c, 0x4c, 0x73, 0x25, 0xae, 0x85, 0xa4, 0x88, 0x72, 0x37, ++ 0x2e, 0xd0, 0x1a, 0x41, 0x6c, 0x2d, 0x76, 0xa1, 0x77, 0xc4, 0xf1, 0x19, ++ 0x3e, 0xf1, 0xb3, 0x2d, 0x7f, 0xc6, 0xff, 0x8e, 0x91, 0x48, 0xa7, 0x77, ++ 0x8e, 0xff, 0xed, 0x93, 0x9f, 0xcd, 0x35, 0x90, 0xe1, 0xbc, 0xca, 0xf3, ++ 0xf1, 0xb9, 0xa1, 0x79, 0xf9, 0x06, 0xf1, 0x80, 0x3d, 0xdf, 0x61, 0x0f, ++ 0xfb, 0xb0, 0x8b, 0x7c, 0x7d, 0x43, 0xab, 0x89, 0x57, 0x13, 0xf7, 0x5b, ++ 0x3b, 0x6c, 0x19, 0xdc, 0x6f, 0x3f, 0xdf, 0xd9, 0x74, 0x76, 0x0e, 0xfb, ++ 0x54, 0xfa, 0xb0, 0xa7, 0x4a, 0x2d, 0xf6, 0x1e, 0xc3, 0x0f, 0x29, 0x0f, ++ 0x3e, 0xf7, 0xb9, 0x3e, 0xdf, 0x76, 0x17, 0xef, 0x4d, 0x3c, 0x5d, 0x92, ++ 0x85, 0x73, 0xa4, 0x5a, 0xb8, 0x46, 0x98, 0xb6, 0x8f, 0xe5, 0x8a, 0x8f, ++ 0xfd, 0x57, 0x24, 0x03, 0xbc, 0xcf, 0x58, 0xb1, 0xff, 0x68, 0xfb, 0xbd, ++ 0xc0, 0x51, 0xd3, 0x53, 0xb5, 0x0a, 0x54, 0xeb, 0x77, 0xdb, 0xf6, 0xb0, ++ 0xd0, 0x08, 0xac, 0x7d, 0xae, 0x89, 0xeb, 0x7d, 0xee, 0x0d, 0x6a, 0x6b, ++ 0xc7, 0x08, 0x80, 0x6e, 0x55, 0x78, 0x4d, 0xf5, 0x04, 0xf7, 0xeb, 0xb9, ++ 0x8f, 0x4f, 0x71, 0xd7, 0x5b, 0xb7, 0xca, 0xf4, 0x2c, 0x58, 0xe5, 0x14, ++ 0x8b, 0x33, 0x3d, 0x64, 0x7b, 0x1a, 0x12, 0x19, 0xd3, 0xdb, 0xb0, 0x2a, ++ 0x84, 0x87, 0x32, 0xf3, 0x31, 0xb9, 0x05, 0x2d, 0xe3, 0xc0, 0x0f, 0x33, ++ 0x41, 0x34, 0x8f, 0x86, 0xfb, 0x6f, 0x95, 0xc2, 0x03, 0xb3, 0x12, 0xdf, ++ 0xbb, 0xbc, 0x66, 0xa5, 0x8d, 0xc5, 0x3f, 0x5a, 0xb3, 0xc2, 0xfe, 0x0c, ++ 0x18, 0xd7, 0xe7, 0xef, 0x40, 0x7a, 0xc6, 0x33, 0x5b, 0x96, 0x2c, 0x3c, ++ 0x14, 0x93, 0x70, 0xb3, 0xfe, 0x6f, 0xc9, 0xb7, 0x04, 0xd9, 0xc6, 0xab, ++ 0x9c, 0x83, 0xed, 0x60, 0xb6, 0x64, 0x95, 0x86, 0x55, 0x99, 0x3a, 0x8a, ++ 0x49, 0xf5, 0x14, 0x9f, 0xea, 0x70, 0x85, 0x62, 0xd2, 0x8a, 0x36, 0x0b, ++ 0x8b, 0xdb, 0xcc, 0xbe, 0xc5, 0xe0, 0x3d, 0x68, 0xd5, 0x2c, 0x0a, 0xb5, ++ 0xa7, 0x4b, 0x52, 0xbb, 0xeb, 0x25, 0x05, 0xdb, 0x23, 0x3c, 0x77, 0xd0, ++ 0x58, 0x95, 0xaf, 0xe4, 0xd3, 0x4a, 0x5e, 0x75, 0xce, 0xe5, 0x53, 0xb7, ++ 0xa1, 0x4f, 0xab, 0x3f, 0x4e, 0x49, 0xbc, 0x6f, 0xd2, 0x83, 0x91, 0x6c, ++ 0x0a, 0x7b, 0xb3, 0x21, 0xfc, 0x3a, 0xe3, 0x26, 0xdb, 0x08, 0xeb, 0x3f, ++ 0x00, 0x8f, 0xf1, 0x19, 0xb1, 0x7c, 0x38, 0xfa, 0x90, 0xf4, 0x13, 0x94, ++ 0x9d, 0xea, 0x11, 0xaa, 0x12, 0x08, 0x37, 0x34, 0x87, 0x5e, 0xc4, 0x4f, ++ 0xec, 0x7d, 0x36, 0xa0, 0xc2, 0x43, 0x53, 0x1e, 0xc8, 0x65, 0x3c, 0xb3, ++ 0xb0, 0x7b, 0xb2, 0xbc, 0x6f, 0x2c, 0x61, 0xbd, 0x7e, 0x3f, 0xc9, 0x59, ++ 0xa0, 0xa9, 0xb5, 0x0e, 0xe5, 0x2d, 0x4e, 0x8c, 0x64, 0x38, 0x0f, 0x7f, ++ 0xbc, 0x46, 0x1e, 0x42, 0x79, 0x6e, 0x4f, 0x34, 0xe1, 0xa0, 0x0c, 0xfd, ++ 0x72, 0x11, 0x38, 0x48, 0xb1, 0x63, 0x53, 0xec, 0x37, 0x56, 0x05, 0x8f, ++ 0xca, 0xfe, 0xf4, 0x98, 0xc0, 0x02, 0x2d, 0x49, 0xf2, 0x70, 0xfa, 0x0f, ++ 0xa5, 0xa3, 0x76, 0x0e, 0x1e, 0xa1, 0xf9, 0x93, 0xf6, 0xfc, 0x91, 0xfd, ++ 0x4b, 0x25, 0x09, 0xd7, 0xb7, 0x1e, 0xc5, 0xc4, 0xc2, 0x0a, 0x0d, 0x41, ++ 0xc2, 0x04, 0x5c, 0xcb, 0xd6, 0x13, 0x8f, 0x9b, 0x1f, 0xe3, 0xbe, 0xe6, ++ 0x6f, 0xd7, 0xdc, 0x30, 0xce, 0x7e, 0xfd, 0xf1, 0x9a, 0x77, 0xd3, 0x6a, ++ 0xb2, 0x9e, 0xea, 0x87, 0x6a, 0x92, 0xc3, 0xbd, 0x43, 0xdc, 0x4f, 0xa8, ++ 0x37, 0x5e, 0x3f, 0xcc, 0x79, 0x59, 0x1d, 0x68, 0x10, 0x3e, 0x71, 0x73, ++ 0x46, 0xed, 0x63, 0xc2, 0x2f, 0x47, 0xd4, 0x20, 0xc9, 0xae, 0xf3, 0x1e, ++ 0xd1, 0xc7, 0x35, 0x8b, 0x2d, 0xb7, 0xeb, 0xf2, 0x15, 0xdc, 0x11, 0x9e, ++ 0xc3, 0x21, 0x51, 0x1b, 0x77, 0x58, 0xd6, 0x9e, 0x18, 0xe7, 0x71, 0xfb, ++ 0x4c, 0x00, 0x5d, 0xaf, 0x33, 0x96, 0x52, 0x6d, 0x31, 0xc8, 0xf4, 0xf1, ++ 0x19, 0x0f, 0x89, 0x6a, 0xd1, 0xec, 0xab, 0x73, 0xb8, 0xc4, 0x87, 0x7d, ++ 0x74, 0xbd, 0x6c, 0xe3, 0x13, 0x3e, 0xa7, 0xe8, 0x35, 0x94, 0xc7, 0xf8, ++ 0x6c, 0xe3, 0x6f, 0xd7, 0xac, 0x1f, 0x53, 0x43, 0x12, 0xf1, 0xb1, 0x97, ++ 0xf7, 0xe7, 0x69, 0xce, 0x69, 0x9d, 0xe9, 0xbe, 0xbc, 0x86, 0xfb, 0xb1, ++ 0x4b, 0x88, 0x6e, 0x2b, 0x1b, 0x66, 0x0c, 0x6a, 0xdb, 0x4a, 0x22, 0x4f, ++ 0x55, 0xfd, 0xe2, 0x0a, 0xaf, 0x2e, 0xd2, 0xc9, 0xb1, 0x74, 0x12, 0xa7, ++ 0xe2, 0x15, 0xfd, 0xac, 0xcb, 0x7f, 0x03, 0xa9, 0xfa, 0x0e, 0xe4, 0xb2, ++ 0x8a, 0x7f, 0x43, 0xa6, 0x03, 0xa3, 0xa4, 0xc3, 0xbb, 0x8b, 0x41, 0x7f, ++ 0x47, 0x46, 0x43, 0x6f, 0x91, 0xeb, 0x2b, 0x18, 0x7b, 0xc6, 0x26, 0xe7, ++ 0xea, 0xe0, 0x4a, 0x2e, 0x39, 0x90, 0xa9, 0xd8, 0x5c, 0x38, 0xef, 0x99, ++ 0x0d, 0x89, 0xca, 0xbc, 0x32, 0xad, 0x23, 0x0f, 0xfd, 0x89, 0x85, 0x85, ++ 0x6c, 0x0b, 0x77, 0x60, 0x6c, 0xdc, 0x6f, 0x2e, 0x36, 0x14, 0xac, 0x6a, ++ 0xfd, 0x73, 0x7a, 0xb6, 0x05, 0x1f, 0x1f, 0xff, 0x3a, 0xca, 0xdf, 0x24, ++ 0x7c, 0x94, 0x49, 0xa2, 0xb9, 0xf5, 0x16, 0xa4, 0xfe, 0x40, 0xc6, 0xd3, ++ 0x19, 0x1f, 0x9e, 0xcf, 0x54, 0xf6, 0xec, 0x7f, 0x94, 0x25, 0x3f, 0x24, ++ 0x1f, 0x78, 0xee, 0x4b, 0xf7, 0x49, 0x29, 0x9e, 0x3b, 0x78, 0x0f, 0xff, ++ 0x1f, 0x1e, 0x77, 0xde, 0x1e, 0xe7, 0x11, 0x75, 0x23, 0xf3, 0xf3, 0x5a, ++ 0xd0, 0x5a, 0xff, 0xbe, 0x67, 0x08, 0xf3, 0x81, 0x62, 0x48, 0xe5, 0x8c, ++ 0x83, 0x90, 0x47, 0xec, 0x7d, 0x23, 0xc2, 0xb9, 0x11, 0xfd, 0x02, 0x4c, ++ 0xb8, 0x09, 0x5f, 0x2d, 0x25, 0x59, 0x68, 0x99, 0x80, 0x5f, 0x2a, 0x2a, ++ 0xf4, 0xdf, 0xe8, 0x77, 0x92, 0x7c, 0x9c, 0xc5, 0x8f, 0x28, 0xa6, 0xb0, ++ 0x4f, 0x55, 0x72, 0x9c, 0x54, 0x7c, 0xc4, 0x4b, 0xc0, 0x87, 0x3e, 0x2b, ++ 0x36, 0x1d, 0xca, 0x2f, 0xf6, 0x32, 0x96, 0xc9, 0x65, 0x2a, 0xbf, 0x23, ++ 0x57, 0x7f, 0x93, 0x9e, 0x6d, 0x99, 0x8d, 0xd0, 0x6f, 0x96, 0xc5, 0x73, ++ 0x56, 0x6a, 0x33, 0xcb, 0x2b, 0xe0, 0x7f, 0x83, 0xe4, 0x3f, 0x46, 0x34, ++ 0x66, 0x69, 0x8d, 0xd7, 0x69, 0xcd, 0x4c, 0xf1, 0x10, 0x8d, 0xe1, 0x7b, ++ 0x24, 0x67, 0xdb, 0x76, 0x0f, 0x7b, 0xf9, 0x7c, 0xc2, 0xf3, 0x19, 0x60, ++ 0x30, 0x6b, 0xaa, 0xce, 0xb9, 0x73, 0x9d, 0x83, 0x94, 0x2f, 0xab, 0x28, ++ 0x16, 0xbd, 0x19, 0xdf, 0x8e, 0x1b, 0x73, 0x6a, 0xd2, 0x24, 0x3c, 0x96, ++ 0x52, 0x20, 0x48, 0x77, 0x64, 0xc3, 0x01, 0xe3, 0xdd, 0x74, 0x23, 0xf1, ++ 0x14, 0x0e, 0x5d, 0xa0, 0xf1, 0xa6, 0x53, 0xc6, 0x81, 0x51, 0x07, 0x2e, ++ 0xf0, 0x1e, 0xb2, 0xa8, 0x3c, 0x6f, 0x82, 0xc7, 0xce, 0x7f, 0xaf, 0xa6, ++ 0xba, 0x2e, 0x9c, 0xa0, 0xac, 0x6a, 0xd6, 0x10, 0x6e, 0xcf, 0xb7, 0x3f, ++ 0x82, 0x43, 0x54, 0xeb, 0xef, 0x88, 0x85, 0x90, 0xac, 0x8b, 0x53, 0xbd, ++ 0xd1, 0xdc, 0x7f, 0x09, 0xff, 0xcd, 0x2a, 0xf3, 0x3e, 0xbc, 0x08, 0x27, ++ 0x2e, 0xe1, 0x53, 0xcb, 0xa1, 0x69, 0x67, 0xa7, 0xa0, 0x95, 0x2f, 0xa0, ++ 0x79, 0xe0, 0x13, 0xbc, 0x67, 0xf1, 0x1e, 0xbd, 0xec, 0x70, 0x10, 0x06, ++ 0x0c, 0x2b, 0x4e, 0x04, 0x50, 0x0e, 0x38, 0xb0, 0x49, 0xe7, 0xde, 0xb4, ++ 0x3a, 0xf0, 0x24, 0x61, 0xf9, 0x77, 0x44, 0x73, 0xdf, 0x87, 0x38, 0x6f, ++ 0x4d, 0xd4, 0xf1, 0xba, 0x02, 0x89, 0xeb, 0x9b, 0xcf, 0xba, 0xa1, 0x76, ++ 0xba, 0x84, 0x96, 0x68, 0x70, 0xfc, 0x95, 0x75, 0x3e, 0xf0, 0xa9, 0xa5, ++ 0x45, 0x3e, 0x25, 0x1c, 0xa4, 0x05, 0x27, 0xc9, 0xf6, 0xfb, 0x30, 0x4f, ++ 0x9b, 0xa8, 0x86, 0x57, 0x27, 0x1a, 0x18, 0xf7, 0x99, 0x9e, 0x7d, 0x44, ++ 0xdb, 0x6b, 0x84, 0x03, 0x76, 0xc4, 0x2e, 0x59, 0xc9, 0x85, 0x7c, 0xfe, ++ 0x4f, 0xa9, 0xae, 0xf4, 0xc0, 0xb9, 0x6f, 0x72, 0x07, 0xee, 0x4a, 0x3b, ++ 0x49, 0x4e, 0xf3, 0x78, 0xcd, 0x45, 0x31, 0x98, 0x63, 0x7f, 0xf9, 0x3a, ++ 0x2a, 0xcd, 0x24, 0x2a, 0xf1, 0xb1, 0x87, 0xe2, 0xc2, 0x6e, 0x3b, 0x17, ++ 0xc0, 0xbb, 0x64, 0x55, 0x2b, 0x3e, 0x19, 0x7f, 0xd3, 0x4b, 0xbe, 0xb4, ++ 0x4e, 0x6b, 0x83, 0x08, 0x66, 0x4c, 0x51, 0x6b, 0x38, 0xf0, 0x61, 0xbb, ++ 0xda, 0x29, 0x39, 0x06, 0x70, 0x7d, 0xcc, 0xb4, 0x7c, 0x9a, 0xd6, 0xd3, ++ 0x22, 0x22, 0xdd, 0x45, 0x11, 0x45, 0x75, 0xd1, 0x27, 0x57, 0x17, 0x5b, ++ 0x64, 0x6f, 0xd1, 0xf4, 0x28, 0xab, 0xb6, 0x53, 0xdd, 0xb2, 0x8b, 0x6a, ++ 0x5b, 0x1f, 0xd5, 0xd7, 0xaa, 0x7e, 0x11, 0x6e, 0x92, 0x7f, 0x08, 0xfb, ++ 0x4a, 0x06, 0x9c, 0x99, 0x9d, 0x70, 0x65, 0xc2, 0xca, 0x5e, 0xec, 0x42, ++ 0x32, 0x58, 0xc1, 0xb6, 0x32, 0xe9, 0xaa, 0xaa, 0x9d, 0xb1, 0xcc, 0x76, ++ 0x9c, 0x9f, 0x60, 0x7c, 0x9e, 0xc0, 0xd6, 0x34, 0xff, 0x86, 0xf7, 0xc5, ++ 0xb8, 0x81, 0x93, 0x54, 0x3b, 0x79, 0x5a, 0x1b, 0x48, 0x0f, 0x8d, 0x18, ++ 0x2c, 0x09, 0x36, 0x2b, 0xd2, 0x05, 0xbc, 0x27, 0xdb, 0x65, 0x1c, 0x9c, ++ 0xa2, 0x44, 0x42, 0xf9, 0xca, 0x99, 0x51, 0x28, 0x4e, 0xc8, 0xf0, 0x69, ++ 0x3e, 0xfa, 0x1d, 0xe0, 0x73, 0x4b, 0x64, 0x67, 0xbf, 0x5d, 0xd3, 0x62, ++ 0xc7, 0x9a, 0x7a, 0xaa, 0x75, 0xde, 0x21, 0x5e, 0x58, 0x16, 0x06, 0xaa, ++ 0x47, 0xe6, 0x6b, 0xc2, 0xf5, 0xb7, 0x55, 0x23, 0x48, 0x73, 0x32, 0x0e, ++ 0xac, 0x9c, 0x57, 0x5d, 0x1f, 0x6b, 0x45, 0x21, 0x27, 0xe6, 0x30, 0xd6, ++ 0xa0, 0xea, 0xc3, 0x3a, 0x1c, 0xa2, 0xda, 0xdf, 0xaf, 0x6d, 0x45, 0x46, ++ 0x29, 0x7b, 0x7f, 0x11, 0xe7, 0x1a, 0x00, 0xde, 0x5e, 0xc2, 0x50, 0x43, ++ 0xe9, 0xaf, 0x72, 0xcc, 0xf4, 0xdc, 0x1d, 0xd7, 0x71, 0x24, 0x47, 0x21, ++ 0x4a, 0x5b, 0x87, 0xda, 0xb6, 0x2e, 0x7c, 0x58, 0xc7, 0xf8, 0x97, 0x62, ++ 0x15, 0xd1, 0xb3, 0x77, 0x2a, 0x60, 0x9f, 0xab, 0xd8, 0x57, 0x9a, 0xa7, ++ 0xf9, 0x5a, 0x5a, 0xbf, 0x8c, 0x46, 0x96, 0xc9, 0x3f, 0x44, 0x23, 0xd9, ++ 0x2c, 0x61, 0x9e, 0x5c, 0xba, 0x17, 0x2f, 0xa7, 0x79, 0xde, 0x70, 0x52, ++ 0x17, 0x0a, 0xf7, 0xe6, 0x6d, 0x99, 0x98, 0x53, 0xbc, 0x06, 0xaf, 0x3f, ++ 0xbf, 0x4e, 0x80, 0x6a, 0x85, 0x7f, 0xec, 0x5a, 0x14, 0x37, 0x72, 0xeb, ++ 0xa8, 0xee, 0x8c, 0x42, 0xfb, 0xfd, 0x32, 0xe9, 0x83, 0x7b, 0xd5, 0x4b, ++ 0x09, 0xf3, 0xc2, 0xf3, 0x4a, 0x9c, 0xcf, 0x30, 0x5b, 0xbb, 0x64, 0xc3, ++ 0xb2, 0x5c, 0xed, 0x9a, 0xf2, 0x36, 0xd8, 0x0e, 0x7d, 0xbc, 0xe7, 0xe1, ++ 0xd9, 0xdb, 0xee, 0xc3, 0x41, 0xca, 0x81, 0x4f, 0xa5, 0x9b, 0x4d, 0xae, ++ 0xfd, 0xc0, 0x38, 0x54, 0xa4, 0xe8, 0xd9, 0x7f, 0x55, 0xcd, 0x3e, 0xbb, ++ 0xa7, 0xb4, 0x13, 0x52, 0xa6, 0xa7, 0x9a, 0xeb, 0x0d, 0x37, 0xd5, 0xc9, ++ 0x83, 0x69, 0xa6, 0xd7, 0xda, 0xe5, 0xa4, 0xb9, 0x76, 0xc7, 0xb5, 0xd9, ++ 0x1b, 0xc9, 0x2e, 0x1a, 0x0c, 0x96, 0x63, 0x00, 0x4f, 0xd0, 0xd8, 0x50, ++ 0x89, 0x65, 0x79, 0xa8, 0x9a, 0xfb, 0x9e, 0xfb, 0x48, 0xbf, 0xb5, 0xd9, ++ 0xca, 0x3c, 0xd9, 0x52, 0x1f, 0x96, 0x0e, 0xbd, 0x58, 0x5d, 0xa9, 0x7d, ++ 0xb8, 0x2e, 0xef, 0xc7, 0xbe, 0x74, 0x00, 0x53, 0xe9, 0x66, 0xe5, 0x05, ++ 0xfb, 0xcc, 0x40, 0xa5, 0x47, 0x36, 0x98, 0x9e, 0x1f, 0x13, 0xc0, 0xe4, ++ 0xd5, 0xef, 0x2c, 0x9f, 0x4a, 0xef, 0xf4, 0x94, 0x8d, 0xf9, 0x65, 0x4c, ++ 0x04, 0x2a, 0x78, 0x88, 0x62, 0x85, 0xf7, 0x51, 0xd2, 0xeb, 0x3b, 0xa4, ++ 0x57, 0x89, 0xf4, 0xfa, 0x82, 0xfe, 0x23, 0xc6, 0x2c, 0x9e, 0x3d, 0x71, ++ 0x1f, 0xef, 0x13, 0x99, 0x04, 0x5a, 0xec, 0x31, 0x99, 0xb8, 0x13, 0xe7, ++ 0x86, 0xf8, 0x6c, 0xe2, 0x47, 0x6b, 0x5e, 0x4a, 0x5b, 0xeb, 0x66, 0x62, ++ 0xcd, 0xa9, 0x77, 0x08, 0x4f, 0x9b, 0x7f, 0xa0, 0xea, 0xe7, 0xc9, 0x4f, ++ 0xb3, 0xa3, 0x7f, 0x88, 0xf3, 0x75, 0xcd, 0xca, 0xcf, 0x61, 0x7a, 0x1e, ++ 0x8f, 0x3f, 0x42, 0x35, 0x3f, 0xd5, 0x0d, 0x6d, 0xff, 0x92, 0x9c, 0x2c, ++ 0x0e, 0x87, 0xd6, 0x3c, 0xfb, 0x02, 0xfe, 0x23, 0xce, 0x2f, 0x0e, 0xeb, ++ 0x2f, 0x80, 0xc7, 0x54, 0xea, 0xf1, 0xf0, 0xf4, 0x7d, 0x7c, 0x9e, 0x2a, ++ 0x48, 0x69, 0xb4, 0xb2, 0x9f, 0x95, 0xe6, 0xfd, 0x37, 0x81, 0x89, 0x2d, ++ 0x54, 0x4b, 0xdb, 0xe7, 0x58, 0xe1, 0x7d, 0x92, 0xfc, 0x22, 0x3a, 0xcc, ++ 0xe3, 0x3f, 0x5e, 0xa3, 0xe5, 0x43, 0x70, 0x10, 0xc6, 0x49, 0x05, 0xd4, ++ 0x4e, 0x20, 0xe8, 0x7f, 0x32, 0x1d, 0xa4, 0x1a, 0xad, 0xb9, 0x3b, 0x2a, ++ 0xee, 0x9c, 0xdb, 0xf7, 0xe6, 0x3c, 0xf7, 0xf1, 0x9a, 0x63, 0x69, 0x35, ++ 0xf5, 0x24, 0x9a, 0x7b, 0x7c, 0xe2, 0x0e, 0xa4, 0xea, 0x9a, 0xfb, 0x4e, ++ 0x22, 0x9c, 0xf0, 0x08, 0x35, 0x7a, 0x1e, 0x95, 0x79, 0x96, 0xe5, 0x1d, ++ 0x54, 0x27, 0x72, 0x9c, 0x49, 0xe3, 0xa4, 0xe2, 0xc0, 0xf2, 0x56, 0x6d, ++ 0x76, 0x12, 0xf3, 0xf6, 0x52, 0x19, 0xb3, 0x2e, 0x4f, 0xe3, 0x1d, 0x0a, ++ 0xd5, 0xfb, 0x6e, 0x38, 0xeb, 0x79, 0x4f, 0x71, 0x27, 0x76, 0xa4, 0x39, ++ 0x4f, 0x93, 0x5c, 0xc8, 0x37, 0xbb, 0x23, 0x3b, 0xd1, 0x9f, 0x0f, 0xe0, ++ 0x50, 0x36, 0xbc, 0x7f, 0x2f, 0xe1, 0xba, 0xe1, 0x52, 0x38, 0xb4, 0x4d, ++ 0x04, 0x48, 0xdf, 0x54, 0xff, 0xd7, 0x07, 0xa9, 0x4e, 0x56, 0xe8, 0xbf, ++ 0x52, 0xcf, 0xbc, 0x44, 0xf5, 0xcc, 0x39, 0xf2, 0x35, 0xdf, 0x5c, 0xad, ++ 0xba, 0x6c, 0xc2, 0xc2, 0x4c, 0x6c, 0x23, 0x2e, 0xdb, 0x3a, 0x0b, 0x92, ++ 0x8d, 0x71, 0x2e, 0xe2, 0xb3, 0x35, 0x1e, 0xb1, 0x6d, 0xd8, 0xf4, 0x3c, ++ 0xd8, 0x1e, 0x44, 0x38, 0xc3, 0x98, 0x53, 0xfa, 0xa6, 0x83, 0xe4, 0x31, ++ 0xa5, 0xed, 0xc2, 0x86, 0xd8, 0x2e, 0xf4, 0xeb, 0x7f, 0x02, 0x77, 0x3d, ++ 0xc7, 0x23, 0xd9, 0xac, 0xa5, 0x79, 0x2f, 0xb5, 0x77, 0x21, 0x7c, 0x94, ++ 0x73, 0x30, 0x55, 0xc3, 0x43, 0xec, 0xbb, 0x3c, 0xff, 0x6d, 0xc6, 0x0a, ++ 0xc2, 0x15, 0x35, 0xed, 0x95, 0x3c, 0x7f, 0x7d, 0x9e, 0xcf, 0x74, 0x82, ++ 0x6a, 0x53, 0x78, 0xdf, 0x5a, 0x6d, 0xe0, 0x71, 0x8a, 0x31, 0x89, 0x36, ++ 0x17, 0xb0, 0x80, 0xcf, 0x2e, 0x57, 0xea, 0x18, 0xe6, 0x77, 0x69, 0x5e, ++ 0x60, 0x3a, 0x4e, 0xf6, 0xf1, 0x77, 0xce, 0x28, 0x85, 0xe6, 0xce, 0x96, ++ 0x72, 0xff, 0xe4, 0xb0, 0x95, 0xe4, 0xf7, 0x0d, 0xa4, 0xa0, 0x8f, 0xe2, ++ 0x6d, 0xb0, 0x0c, 0x2a, 0xea, 0x29, 0x2e, 0x3b, 0xb4, 0x79, 0xb9, 0xb3, ++ 0xac, 0x4f, 0x58, 0x13, 0x73, 0xba, 0x70, 0xd2, 0x33, 0x7b, 0xc6, 0xd4, ++ 0x81, 0xbd, 0x68, 0xee, 0x7f, 0x57, 0x54, 0xd9, 0x3b, 0x98, 0x93, 0x2d, ++ 0x48, 0x2d, 0x31, 0x9c, 0x5b, 0x3e, 0xc9, 0xae, 0x23, 0x3a, 0x2e, 0x10, ++ 0x08, 0x5d, 0x6f, 0xef, 0x73, 0x4d, 0xb6, 0xfc, 0x29, 0xcd, 0xcd, 0xdf, ++ 0xff, 0xd8, 0xc7, 0x67, 0x2e, 0x4f, 0x65, 0x9f, 0xb7, 0xa2, 0x0b, 0x2b, ++ 0xf2, 0x39, 0x4d, 0xbe, 0x1f, 0x34, 0x24, 0x34, 0x68, 0x91, 0xd9, 0x1e, ++ 0xfa, 0xfd, 0xd7, 0x79, 0x42, 0xfb, 0xab, 0xfb, 0xf0, 0xcb, 0x09, 0x03, ++ 0x07, 0x28, 0x0f, 0xd4, 0x6a, 0xaa, 0x32, 0x81, 0x10, 0xd7, 0xd2, 0x36, ++ 0xff, 0x2b, 0x27, 0xc8, 0x0f, 0xeb, 0x14, 0xbb, 0xc6, 0xa8, 0xf0, 0x77, ++ 0x99, 0xf8, 0x7b, 0xd0, 0xc7, 0xbe, 0xb0, 0x84, 0xfc, 0x62, 0x3f, 0xf9, ++ 0xeb, 0x01, 0xb2, 0x35, 0xaa, 0xe0, 0xc9, 0x0f, 0xd4, 0xfd, 0x20, 0x7f, ++ 0x1d, 0x4e, 0xb3, 0xfc, 0x83, 0xfe, 0x5e, 0x3e, 0xde, 0xac, 0xd9, 0x7d, ++ 0x55, 0x3d, 0x24, 0x71, 0xdc, 0xb5, 0xe3, 0xa9, 0x19, 0x92, 0xac, 0x6a, ++ 0xa6, 0x6b, 0xb0, 0x14, 0x0e, 0x7a, 0xf9, 0x5d, 0x00, 0x02, 0x87, 0xbd, ++ 0x7a, 0x25, 0x57, 0xce, 0x50, 0x3e, 0xba, 0x4c, 0x74, 0x1c, 0x8a, 0x35, ++ 0x20, 0x45, 0xf9, 0x28, 0xa3, 0x55, 0x6c, 0x49, 0x9b, 0x66, 0x8c, 0x59, ++ 0x6f, 0x04, 0xc7, 0xd5, 0x90, 0xcb, 0xd1, 0x3c, 0x70, 0x06, 0x3b, 0xad, ++ 0xf3, 0x75, 0x6c, 0x53, 0x2e, 0x1c, 0x6f, 0x99, 0xb6, 0xca, 0x01, 0xe6, ++ 0xd7, 0x81, 0xe7, 0x75, 0xb2, 0x99, 0xc5, 0xe1, 0xe0, 0xf3, 0x94, 0x53, ++ 0xa7, 0xe6, 0xf4, 0x11, 0xce, 0xcf, 0xdb, 0xe3, 0x5a, 0x96, 0x75, 0x34, ++ 0x05, 0x2d, 0x91, 0x47, 0x2f, 0x7d, 0x6f, 0x0a, 0x5e, 0x9e, 0xb3, 0xd5, ++ 0x15, 0xd3, 0xaf, 0xfb, 0xe6, 0xde, 0xcb, 0xb1, 0x9f, 0x09, 0xe5, 0xff, ++ 0x88, 0x7e, 0xf3, 0x9c, 0x01, 0xc6, 0x32, 0x7c, 0x56, 0xcb, 0xbb, 0xa3, ++ 0xdd, 0xcd, 0xfe, 0xa2, 0xf0, 0x3b, 0x09, 0x1b, 0x86, 0xb9, 0x2f, 0xcc, ++ 0x3d, 0x1a, 0x07, 0xf6, 0x5e, 0x7d, 0x67, 0x82, 0x3f, 0x3b, 0xb1, 0x69, ++ 0x98, 0x7b, 0x11, 0xa7, 0x6f, 0x90, 0xf1, 0x37, 0x94, 0x87, 0x65, 0xf6, ++ 0x79, 0xf2, 0xf5, 0x4f, 0xd7, 0xbc, 0x34, 0xc6, 0x39, 0x35, 0x60, 0xdc, ++ 0x95, 0x9e, 0xd7, 0xf1, 0x55, 0x9e, 0xce, 0xde, 0x4d, 0x71, 0x27, 0x93, ++ 0x56, 0x07, 0x22, 0x0e, 0x7b, 0x7f, 0x2d, 0x55, 0x14, 0x5f, 0xa5, 0x22, ++ 0x8d, 0xe7, 0x53, 0xfc, 0x03, 0x87, 0x43, 0xc8, 0x64, 0xbb, 0xf0, 0x8d, ++ 0x61, 0xcb, 0x72, 0xb7, 0x39, 0xf1, 0xca, 0x90, 0x85, 0x0f, 0x62, 0xc0, ++ 0xcb, 0x43, 0xe1, 0x81, 0x73, 0xc0, 0xb7, 0x6b, 0xa9, 0x46, 0x6e, 0x11, ++ 0x6a, 0x37, 0x61, 0x83, 0xd0, 0x7b, 0x68, 0x0e, 0xe6, 0xa1, 0x9e, 0xdd, ++ 0x4d, 0xf3, 0xbd, 0x58, 0x00, 0x7e, 0x59, 0xf0, 0xe2, 0x17, 0xc3, 0x3c, ++ 0xa7, 0x17, 0xe7, 0x8e, 0xd6, 0xfb, 0x77, 0xd2, 0x5c, 0x07, 0x29, 0xbe, ++ 0x77, 0x1d, 0x4b, 0x60, 0xd3, 0x61, 0x81, 0x68, 0x24, 0x81, 0xce, 0x63, ++ 0x35, 0xd8, 0x38, 0x2c, 0xe3, 0xfd, 0x78, 0x0d, 0x6e, 0x39, 0x3a, 0xcf, ++ 0x47, 0xa5, 0xaf, 0xc1, 0x67, 0x35, 0xf9, 0x1c, 0xdc, 0xc9, 0x2c, 0xc7, ++ 0x6c, 0xca, 0x17, 0x59, 0x8e, 0x81, 0x96, 0x15, 0x6c, 0xaf, 0xf4, 0x39, ++ 0x9e, 0xa6, 0xfc, 0xf1, 0x78, 0xbb, 0x16, 0x0c, 0x4a, 0x06, 0x96, 0x8f, ++ 0x96, 0xef, 0xac, 0x85, 0x75, 0x8a, 0xf7, 0x33, 0x3e, 0x6a, 0xb1, 0xac, ++ 0x4d, 0xf1, 0xc8, 0xec, 0xbd, 0x36, 0xae, 0x0d, 0x90, 0x4f, 0x35, 0xe2, ++ 0xf1, 0xec, 0xfc, 0x9e, 0x97, 0xd6, 0x73, 0xc9, 0x61, 0xee, 0x52, 0x60, ++ 0x5d, 0xa9, 0x32, 0xac, 0x8f, 0x5c, 0x46, 0x24, 0xf8, 0x80, 0xe0, 0xb3, ++ 0x22, 0xdc, 0x13, 0xb7, 0xac, 0x37, 0xe3, 0x96, 0x55, 0x88, 0x9b, 0x9e, ++ 0x15, 0xab, 0x14, 0x1c, 0x5b, 0xc6, 0xef, 0x2a, 0x84, 0x93, 0x0d, 0x64, ++ 0x5f, 0xde, 0x65, 0x5a, 0x70, 0x2b, 0x54, 0xd3, 0xa4, 0x20, 0x17, 0x5a, ++ 0xa8, 0xf6, 0x00, 0x8d, 0xfe, 0x43, 0x43, 0xf5, 0xf8, 0xfe, 0xcc, 0xef, ++ 0xf2, 0xf1, 0x1d, 0xbb, 0x9f, 0x76, 0x45, 0xc7, 0xba, 0x5a, 0x44, 0x92, ++ 0xf7, 0x80, 0x7b, 0xa3, 0x7c, 0xa6, 0xd5, 0xc4, 0x2d, 0xf1, 0x3e, 0xec, ++ 0x18, 0xe6, 0x7d, 0xb6, 0x3a, 0xe3, 0xca, 0xb0, 0xf5, 0xd7, 0x1e, 0xa2, ++ 0x7f, 0x5d, 0x7b, 0x73, 0xca, 0x6b, 0xbf, 0xe3, 0xe4, 0x34, 0xd6, 0x8f, ++ 0xd5, 0xa1, 0x34, 0xa5, 0x95, 0x97, 0x88, 0xe4, 0x1b, 0x3e, 0x44, 0x82, ++ 0x0d, 0x14, 0xab, 0x66, 0xc8, 0x77, 0xa7, 0x4a, 0x5c, 0x07, 0x2c, 0x30, ++ 0xac, 0xd1, 0x45, 0x98, 0x9c, 0xa1, 0xb9, 0xb2, 0x5a, 0xe7, 0x07, 0x84, ++ 0xf3, 0xaa, 0x0d, 0xab, 0xd6, 0x6b, 0x44, 0xce, 0x36, 0x0b, 0x07, 0x66, ++ 0xdb, 0x2c, 0xab, 0xab, 0x5d, 0x1b, 0xa8, 0x11, 0xe8, 0x97, 0x0c, 0x2d, ++ 0xd1, 0xe2, 0xc0, 0xd7, 0x82, 0x88, 0x74, 0xbe, 0x89, 0x48, 0xcf, 0x05, ++ 0x8a, 0x61, 0x4f, 0x95, 0xf8, 0x9c, 0xf0, 0x23, 0xf8, 0xeb, 0xe1, 0x85, ++ 0x38, 0x35, 0xd5, 0x3f, 0xd7, 0x13, 0x83, 0xf7, 0xfa, 0x55, 0x06, 0x8e, ++ 0x0f, 0x87, 0xc8, 0x7e, 0xdc, 0x14, 0xd7, 0x65, 0x48, 0x4d, 0x90, 0xeb, ++ 0xa8, 0x4e, 0x88, 0x3d, 0x66, 0x59, 0x2b, 0x9a, 0x2a, 0x35, 0xcf, 0x8a, ++ 0xe9, 0x6b, 0xdf, 0x71, 0x98, 0xef, 0xf7, 0x04, 0x49, 0x7f, 0xcd, 0xa9, ++ 0x1d, 0xe2, 0x8c, 0x65, 0xfe, 0x81, 0x20, 0x9e, 0x7b, 0x6a, 0xe0, 0x65, ++ 0xbe, 0x65, 0xec, 0x1e, 0xe5, 0x3e, 0x1c, 0xeb, 0x0d, 0xde, 0xce, 0x38, ++ 0xef, 0x97, 0xb3, 0x8e, 0xca, 0xde, 0x0d, 0x71, 0x8a, 0x89, 0xc2, 0x4f, ++ 0x78, 0xca, 0xf4, 0x74, 0x50, 0x7e, 0xaa, 0x1a, 0xe6, 0xf7, 0x2d, 0x7c, ++ 0x38, 0x40, 0x71, 0xe3, 0xb2, 0x5e, 0x8d, 0x43, 0x75, 0x6a, 0x82, 0xeb, ++ 0xe9, 0x27, 0x4b, 0xdc, 0x33, 0xdc, 0x89, 0xed, 0xfc, 0xbe, 0x4a, 0x69, ++ 0xb5, 0x7d, 0xb6, 0x90, 0xae, 0x11, 0x36, 0x60, 0x3a, 0xe6, 0xd7, 0xef, ++ 0xc4, 0x92, 0x21, 0xd6, 0xe3, 0xc7, 0x6b, 0x82, 0x24, 0xa3, 0xc7, 0xc9, ++ 0x2e, 0x24, 0xa3, 0x03, 0xf2, 0x90, 0x65, 0xdd, 0x18, 0xbf, 0x76, 0x0e, ++ 0xad, 0xff, 0x82, 0x83, 0xea, 0x3b, 0x07, 0xef, 0xeb, 0xa9, 0x89, 0x13, ++ 0xe2, 0xda, 0x39, 0x0b, 0x35, 0xdc, 0x4f, 0x34, 0xa7, 0x2a, 0x79, 0xe9, ++ 0x38, 0xe5, 0xa5, 0x97, 0x73, 0xec, 0x23, 0xf5, 0x06, 0xfb, 0x88, 0x44, ++ 0xb1, 0x76, 0x7d, 0x3a, 0x84, 0x0b, 0x3a, 0x34, 0x37, 0x62, 0x44, 0x77, ++ 0xa4, 0xbb, 0x63, 0x0e, 0xf3, 0xb9, 0x28, 0xfe, 0x4f, 0xe5, 0x78, 0xaf, ++ 0x4d, 0xa0, 0x46, 0x63, 0x1b, 0xb0, 0x73, 0x01, 0xc5, 0xb4, 0x7e, 0xd4, ++ 0xae, 0x06, 0x2e, 0x0d, 0xf1, 0xfe, 0x8c, 0x86, 0x03, 0xa5, 0x01, 0xd1, ++ 0x30, 0xf4, 0x5b, 0x2b, 0x54, 0x35, 0xbf, 0x07, 0xf8, 0x30, 0xef, 0x01, ++ 0x92, 0x0d, 0xf4, 0xdb, 0xe7, 0x7c, 0xde, 0x4c, 0xf3, 0x39, 0x9f, 0x70, ++ 0x68, 0x13, 0xf9, 0x4e, 0x2f, 0x9a, 0xf5, 0x69, 0xc2, 0xce, 0xb3, 0x44, ++ 0x67, 0x93, 0xa8, 0xec, 0x73, 0x45, 0xe6, 0xf6, 0xe9, 0x96, 0xe5, 0x3b, ++ 0x45, 0x4d, 0x81, 0x69, 0x0a, 0x10, 0x4d, 0x1d, 0xa2, 0xfa, 0xd8, 0x06, ++ 0xe1, 0x3b, 0xd6, 0x25, 0xa4, 0x02, 0xc7, 0xe4, 0x3a, 0x63, 0x4f, 0x8e, ++ 0xf3, 0xd9, 0x66, 0xe1, 0x3c, 0xba, 0x45, 0x78, 0x0b, 0x3d, 0xc2, 0x7f, ++ 0xcc, 0xc4, 0xfd, 0xf1, 0x2e, 0x9c, 0x1b, 0xe6, 0xb3, 0x6c, 0xf7, 0x89, ++ 0x9a, 0xb9, 0xbd, 0x39, 0x6f, 0xa1, 0xd1, 0x5f, 0x48, 0x73, 0x7f, 0xf7, ++ 0xe3, 0x35, 0xe9, 0xa1, 0x45, 0xfe, 0xa7, 0xc6, 0x02, 0xfe, 0x27, 0xc7, ++ 0xd4, 0xfe, 0x7d, 0xc2, 0xb2, 0x76, 0xc6, 0xfe, 0x03, 0xeb, 0xd0, 0x6a, ++ 0x8e, 0x55, 0xf0, 0xc1, 0x6e, 0x92, 0xc7, 0x36, 0xca, 0x2d, 0x93, 0x7a, ++ 0xf3, 0x1c, 0x16, 0x51, 0x53, 0xfc, 0xee, 0x1b, 0xfd, 0x77, 0x73, 0x6e, ++ 0xe3, 0x7d, 0x4d, 0x67, 0x3b, 0x28, 0xee, 0x7e, 0xc6, 0x6b, 0xcd, 0x10, ++ 0x9f, 0x51, 0xeb, 0x87, 0xff, 0x4b, 0xf6, 0xf5, 0xce, 0x7d, 0xb6, 0xaf, ++ 0x97, 0x78, 0x52, 0xa8, 0xe5, 0x19, 0xe2, 0xb7, 0xca, 0xf1, 0xb9, 0x3d, ++ 0xbd, 0xb9, 0xfd, 0xbc, 0x4e, 0xe1, 0x2b, 0x70, 0x7d, 0x1e, 0x30, 0x5e, ++ 0x1f, 0xea, 0x10, 0xde, 0x63, 0xc3, 0x94, 0x1f, 0x37, 0x10, 0xcf, 0x7c, ++ 0x76, 0xac, 0x4b, 0xf8, 0x0b, 0x9b, 0x85, 0x8f, 0xf8, 0xac, 0x26, 0x3e, ++ 0x71, 0xcc, 0x23, 0xbc, 0xc4, 0xa3, 0x87, 0x78, 0xf4, 0xce, 0xf1, 0xe8, ++ 0x29, 0x04, 0xfd, 0xe9, 0x74, 0xbd, 0xff, 0xd1, 0x31, 0xc5, 0xbf, 0x6f, ++ 0xcc, 0xb2, 0xde, 0xd7, 0x15, 0x3f, 0xf3, 0xf5, 0xaa, 0xfe, 0x45, 0xbe, ++ 0x6e, 0x20, 0xbe, 0x2a, 0x7b, 0xb1, 0xa4, 0xc3, 0x14, 0xeb, 0x90, 0xcf, ++ 0x71, 0xcc, 0xf3, 0x75, 0x30, 0xcd, 0xfb, 0x95, 0xbc, 0x6f, 0x39, 0x20, ++ 0x56, 0x10, 0x5f, 0x65, 0xe2, 0x6b, 0xe5, 0x97, 0xf0, 0xf5, 0xe1, 0x35, ++ 0x7c, 0xbd, 0xfa, 0xf7, 0xf2, 0xe5, 0x11, 0xcb, 0x87, 0x39, 0x0e, 0xdd, ++ 0x66, 0xc8, 0xc3, 0x16, 0x61, 0x47, 0x07, 0xbe, 0x3f, 0x05, 0x14, 0xb3, ++ 0xbb, 0x20, 0x53, 0xbc, 0x39, 0x1d, 0x8f, 0x84, 0x5e, 0xa1, 0x7a, 0x72, ++ 0xba, 0xe4, 0x15, 0xcb, 0xec, 0x3d, 0x59, 0xac, 0x90, 0x89, 0xa6, 0x19, ++ 0xfb, 0x5d, 0x33, 0xe8, 0xb5, 0x1a, 0xeb, 0x52, 0x3b, 0xbb, 0x15, 0x91, ++ 0x72, 0xc4, 0xd1, 0x25, 0x12, 0x05, 0xde, 0x83, 0xdd, 0x22, 0x56, 0xda, ++ 0xfb, 0xaf, 0x9d, 0xe2, 0xfa, 0x42, 0x87, 0x68, 0x21, 0xbb, 0x68, 0x3e, ++ 0xc6, 0xe7, 0xc1, 0x36, 0x8b, 0xe6, 0x39, 0x79, 0x2c, 0x27, 0x79, 0x0c, ++ 0x7d, 0x4e, 0x1e, 0x1b, 0x6c, 0x79, 0xfc, 0x4c, 0xbf, 0x78, 0x4d, 0x0f, ++ 0x8d, 0xeb, 0x2a, 0xca, 0x86, 0x54, 0x3b, 0xd5, 0xce, 0xd5, 0x4e, 0x6f, ++ 0xc5, 0xf8, 0x9c, 0x8f, 0x69, 0xd5, 0x68, 0x08, 0x39, 0x0d, 0xb5, 0xe7, ++ 0xb4, 0xd0, 0x52, 0xf7, 0x89, 0xe4, 0x26, 0x1f, 0xd5, 0x3f, 0x3b, 0x62, ++ 0x91, 0xe4, 0x72, 0x11, 0x49, 0x38, 0x05, 0xe7, 0x15, 0x5d, 0xae, 0x2a, ++ 0x9a, 0xd8, 0x47, 0xf1, 0xed, 0xc5, 0x9c, 0x44, 0xd8, 0x81, 0xdf, 0x3f, ++ 0x73, 0xe2, 0x46, 0x82, 0x12, 0x4f, 0x10, 0xee, 0x78, 0x3c, 0xdb, 0x87, ++ 0x27, 0xf2, 0xbd, 0x78, 0x3c, 0xff, 0x77, 0xde, 0xb5, 0x91, 0xbd, 0x46, ++ 0x63, 0xa2, 0x72, 0x16, 0xe1, 0xe3, 0xc4, 0x75, 0x11, 0x96, 0xcd, 0x89, ++ 0x16, 0x39, 0xc2, 0xb5, 0xae, 0xf3, 0x77, 0xdf, 0xd5, 0xd8, 0x17, 0x7b, ++ 0x56, 0xbd, 0x64, 0x63, 0x91, 0x93, 0x6d, 0xc7, 0xec, 0x33, 0x52, 0xe5, ++ 0x95, 0x7b, 0xec, 0x77, 0x41, 0x7d, 0xab, 0xef, 0xd2, 0xd8, 0x1f, 0x4e, ++ 0xc4, 0xd7, 0xdb, 0xf9, 0xb5, 0x71, 0x6d, 0xe5, 0x3d, 0x99, 0xe0, 0xda, ++ 0x4a, 0xaf, 0x26, 0xb0, 0x36, 0x6a, 0x7f, 0x86, 0xd6, 0x56, 0xf6, 0xba, ++ 0xf5, 0xb5, 0x4d, 0xf6, 0x67, 0x74, 0x6d, 0xc5, 0xa7, 0xb4, 0xb5, 0x9a, ++ 0xfd, 0x19, 0x5f, 0x5b, 0xc9, 0xcb, 0x2d, 0x6b, 0x97, 0x5e, 0x7d, 0xbf, ++ 0x86, 0xff, 0xfe, 0x17, 0x9f, 0xed, 0x4e, 0xb2, 0x20, 0x3b, 0x00, 0x00, ++ 0x00 }; + + static const u32 bnx2_TXP_b09FwData[(0x0/4) + 1] = { 0x0 }; + static const u32 bnx2_TXP_b09FwRodata[(0x30/4) + 1] = { +@@ -4513,15 +4582,15 @@ + 0x00000000 }; + + static struct fw_info bnx2_txp_fw_09 = { +- /* Firmware version: 4.6.15 */ ++ /* Firmware version: 4.4.23 */ + .ver_major = 0x4, +- .ver_minor = 0x6, +- .ver_fix = 0xf, ++ .ver_minor = 0x4, ++ .ver_fix = 0x17, + +- .start_addr = 0x08000098, ++ .start_addr = 0x08000094, + + .text_addr = 0x08000000, +- .text_len = 0x3ae8, ++ .text_len = 0x3b1c, + .text_index = 0x0, + .gz_text = bnx2_TXP_b09FwText, + .gz_text_len = sizeof(bnx2_TXP_b09FwText), +@@ -4531,15 +4600,15 @@ + .data_index = 0x0, + .data = bnx2_TXP_b09FwData, + +- .sbss_addr = 0x08003b40, ++ .sbss_addr = 0x08003b80, + .sbss_len = 0x6c, + .sbss_index = 0x0, + +- .bss_addr = 0x08003bac, ++ .bss_addr = 0x08003bec, + .bss_len = 0x24c, + .bss_index = 0x0, + +- .rodata_addr = 0x08003ae8, ++ .rodata_addr = 0x08003b1c, + .rodata_len = 0x30, + .rodata_index = 0x0, + .rodata = bnx2_TXP_b09FwRodata, +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/drivers/net/bnx2_fw.h linux-2.6.29-rc3.owrt/drivers/net/bnx2_fw.h +--- linux-2.6.29.owrt/drivers/net/bnx2_fw.h 2009-05-10 22:04:38.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/drivers/net/bnx2_fw.h 2009-05-10 23:48:28.000000000 +0200 +@@ -15,849 +15,854 @@ + */ + + static u8 bnx2_COM_b06FwText[] = { +- 0xcd, 0x7c, 0x0d, 0x70, 0x5c, 0xd7, 0x75, 0xde, 0xd9, 0xb7, 0xbb, 0xc0, +- 0x12, 0x04, 0xc1, 0x07, 0x68, 0x05, 0xad, 0x24, 0x24, 0xde, 0x87, 0x7d, +- 0x00, 0x56, 0x22, 0xe4, 0x3c, 0x32, 0x10, 0x0d, 0xb9, 0x5b, 0x72, 0xbd, +- 0x0b, 0x50, 0x90, 0x43, 0x23, 0x90, 0x84, 0x28, 0x6a, 0x86, 0xe3, 0x41, +- 0x97, 0xa0, 0x62, 0x69, 0xdc, 0x86, 0x1e, 0x2b, 0x29, 0xe5, 0x2a, 0xe6, +- 0x6a, 0x01, 0xca, 0x94, 0x02, 0x72, 0x61, 0x12, 0x04, 0xd5, 0x54, 0x6d, +- 0xd7, 0x0b, 0x80, 0x54, 0xd4, 0x25, 0x97, 0x94, 0xfc, 0xa3, 0x99, 0xd8, +- 0x21, 0x4a, 0xd1, 0x92, 0xed, 0x71, 0xa7, 0x92, 0xc7, 0x9d, 0xaa, 0x33, +- 0x9a, 0x94, 0xa5, 0xe4, 0xda, 0xf1, 0x34, 0x8d, 0x6a, 0x7b, 0x1a, 0x25, +- 0xb1, 0xf3, 0xfa, 0x7d, 0xf7, 0xdd, 0x0b, 0x2c, 0x20, 0x48, 0x56, 0x92, +- 0xf1, 0x4c, 0x30, 0xb3, 0xbc, 0xef, 0xde, 0x77, 0x7f, 0xcf, 0x39, 0xf7, +- 0x9c, 0xef, 0x9c, 0x7b, 0x1f, 0x77, 0x89, 0xb4, 0x88, 0xfe, 0xdb, 0x82, +- 0xdf, 0xc0, 0xbf, 0xf8, 0x9d, 0xfd, 0xdb, 0x3f, 0xb8, 0xf3, 0x83, 0x78, +- 0xdc, 0x69, 0xd9, 0x4d, 0x11, 0x96, 0x87, 0xf1, 0x8b, 0xe3, 0xb7, 0x43, +- 0x3f, 0x6f, 0xf4, 0x67, 0xb3, 0x41, 0x48, 0x64, 0xe2, 0x87, 0x22, 0xa1, +- 0x75, 0xef, 0x62, 0xef, 0xd2, 0xe6, 0xbd, 0xfe, 0xac, 0xf7, 0x59, 0xcf, +- 0xfe, 0x7b, 0xf4, 0x6d, 0xfe, 0xc2, 0xba, 0xf9, 0x16, 0xfd, 0x93, 0x98, +- 0x95, 0xb9, 0xfa, 0xb1, 0x9c, 0x2b, 0xb1, 0x70, 0xe6, 0xbb, 0xa3, 0xfb, +- 0x5d, 0x91, 0x6c, 0x6d, 0x5b, 0x32, 0x2f, 0x3f, 0xf3, 0x8b, 0xf1, 0x88, +- 0xb0, 0xfc, 0x97, 0x32, 0x3f, 0x3d, 0xfc, 0xb5, 0x0f, 0x39, 0x6f, 0x55, +- 0xc2, 0x12, 0xb3, 0x33, 0x6f, 0x8b, 0xdd, 0x2b, 0xb1, 0x2e, 0xb4, 0x79, +- 0xba, 0xef, 0x59, 0x4b, 0xda, 0x4c, 0x5f, 0xf6, 0x44, 0x38, 0x23, 0x63, +- 0x93, 0x33, 0x87, 0x7d, 0xcb, 0x95, 0xe2, 0x4d, 0x19, 0x37, 0x59, 0x92, +- 0xd6, 0xc1, 0xe9, 0x81, 0x0f, 0x09, 0xf2, 0x63, 0x93, 0xb5, 0x98, 0xe4, +- 0xea, 0xc5, 0x56, 0xcb, 0x75, 0x91, 0xc6, 0x8a, 0x37, 0x67, 0x24, 0xd6, +- 0x94, 0x79, 0xba, 0xf9, 0x25, 0x97, 0xe3, 0x27, 0x46, 0x73, 0xee, 0xcd, +- 0x12, 0x71, 0x7d, 0x7f, 0x1a, 0xe3, 0xef, 0xa9, 0xfd, 0xcc, 0x7f, 0x2c, +- 0x12, 0x8c, 0x6d, 0x65, 0x8a, 0x61, 0xa6, 0xa1, 0x4c, 0x72, 0xb4, 0xbb, +- 0xa6, 0xf2, 0x4d, 0x41, 0xde, 0x35, 0xf9, 0x2d, 0x41, 0x7e, 0x42, 0xe7, +- 0xed, 0x96, 0x60, 0x2d, 0xb1, 0x4d, 0x58, 0x4b, 0x2c, 0x92, 0x19, 0xda, +- 0x84, 0x3e, 0x63, 0xd1, 0x8c, 0x9b, 0x59, 0x52, 0xf5, 0x3e, 0xa1, 0xeb, +- 0x1d, 0x8c, 0x06, 0xed, 0x26, 0x47, 0x7b, 0x6b, 0x4c, 0x1f, 0x1e, 0xed, +- 0x51, 0xe9, 0xa3, 0xa3, 0x29, 0x95, 0x16, 0x55, 0xbd, 0x50, 0x66, 0x7a, +- 0xd4, 0x55, 0x69, 0x97, 0x2e, 0x4f, 0x8f, 0x26, 0x55, 0xda, 0xaf, 0x53, +- 0x4f, 0xa7, 0x03, 0x3a, 0x1d, 0xd4, 0x69, 0x46, 0xa7, 0x59, 0x9d, 0x0e, +- 0xe9, 0x7e, 0x46, 0x74, 0x7e, 0xaf, 0x4e, 0xc7, 0x74, 0x3a, 0xae, 0xd3, +- 0xfb, 0x75, 0xba, 0x4f, 0xcf, 0xeb, 0x93, 0x3a, 0x7f, 0x50, 0xcf, 0xef, +- 0x10, 0xe6, 0xf1, 0x93, 0x26, 0x2d, 0xbf, 0x58, 0x67, 0x52, 0xf6, 0xcf, +- 0xc4, 0xa4, 0x54, 0x0e, 0x4b, 0x5e, 0xf1, 0xb5, 0x3f, 0x2a, 0x2d, 0x31, +- 0x99, 0xaa, 0xc7, 0xe4, 0xaa, 0x12, 0xdb, 0x1f, 0xf8, 0x5f, 0xeb, 0xb3, +- 0xe5, 0x42, 0x3d, 0x2e, 0x97, 0xea, 0x12, 0x1a, 0xeb, 0xdb, 0x24, 0xd6, +- 0x89, 0x9b, 0x24, 0x6b, 0x87, 0x24, 0xac, 0xe8, 0x9b, 0x94, 0xdc, 0x4c, +- 0x27, 0xf2, 0x4e, 0x42, 0x64, 0x32, 0x1a, 0xf0, 0x33, 0x26, 0xe1, 0x79, +- 0xf2, 0x67, 0x7e, 0xf4, 0xa5, 0xb9, 0x84, 0x44, 0x8e, 0x27, 0xd1, 0x7f, +- 0xab, 0x44, 0xe7, 0xa5, 0x2b, 0x2c, 0x3d, 0x89, 0x07, 0x50, 0x63, 0xa8, +- 0x16, 0x91, 0xe1, 0x5a, 0x08, 0x3c, 0x8b, 0x41, 0x5e, 0x5a, 0xf1, 0xb3, +- 0xf1, 0x8b, 0xe3, 0x97, 0xc0, 0xef, 0x09, 0xf4, 0xd3, 0x25, 0xf9, 0x1a, +- 0xfb, 0xc4, 0xb8, 0x65, 0x8c, 0x5f, 0x76, 0xec, 0x09, 0xe1, 0x9c, 0x12, +- 0xf2, 0xb5, 0xbe, 0x60, 0x4e, 0x97, 0xea, 0xb1, 0x50, 0xee, 0xb4, 0x1c, +- 0xcc, 0x7b, 0x92, 0xb4, 0xdc, 0x16, 0x29, 0xd8, 0xa1, 0xe4, 0x64, 0xba, +- 0x43, 0x8a, 0xe3, 0x78, 0x57, 0x96, 0xac, 0x85, 0xbe, 0x0b, 0xb6, 0x4c, +- 0x04, 0xef, 0x58, 0xf6, 0x37, 0xd8, 0xb7, 0x8e, 0x4d, 0x01, 0xbe, 0x54, +- 0xfe, 0x63, 0x3c, 0xb3, 0xaf, 0xff, 0x17, 0x0e, 0xe6, 0xfc, 0xd7, 0xc8, +- 0xb3, 0xfc, 0xcb, 0x5b, 0x83, 0x3c, 0x9f, 0x59, 0xd7, 0x8c, 0x69, 0xd6, +- 0xca, 0xb1, 0xfb, 0xb0, 0x5e, 0x8e, 0xbf, 0xb2, 0x5e, 0xcc, 0xa3, 0x35, +- 0x94, 0x3f, 0x9d, 0x94, 0x23, 0xe5, 0x5d, 0x92, 0xf3, 0x7c, 0x7f, 0xbf, +- 0x27, 0x71, 0x4b, 0x7a, 0xec, 0x3c, 0xde, 0x56, 0x6b, 0x12, 0xca, 0x95, +- 0x0d, 0x3d, 0xd8, 0x6f, 0x04, 0x65, 0x9d, 0xa8, 0xdf, 0x16, 0x1a, 0x3a, +- 0x8d, 0xb9, 0x67, 0x48, 0x17, 0xc8, 0xae, 0xd7, 0x93, 0x98, 0xc4, 0x78, +- 0x0b, 0xb5, 0x1e, 0xef, 0xb2, 0xd8, 0xe8, 0xb3, 0x03, 0x75, 0x48, 0x23, +- 0xf6, 0xc5, 0x3e, 0xd9, 0x5f, 0x2b, 0xda, 0xc6, 0xf1, 0x8e, 0x73, 0xf2, +- 0xfd, 0x9c, 0x67, 0x33, 0x2f, 0x15, 0xd0, 0xad, 0x42, 0xba, 0xb5, 0x74, +- 0xc9, 0x99, 0x1a, 0xc7, 0xd8, 0x68, 0xde, 0xb7, 0xfe, 0x23, 0x9b, 0x77, +- 0x02, 0xfd, 0xc7, 0x91, 0x6e, 0x0e, 0xe5, 0x4e, 0xfa, 0x18, 0x3f, 0x81, +- 0xe7, 0x8d, 0xd6, 0x70, 0x55, 0xcb, 0x60, 0x02, 0x73, 0x8f, 0xcb, 0x45, +- 0x25, 0x87, 0x9b, 0x25, 0x0c, 0x39, 0x24, 0x8f, 0xdb, 0xe7, 0x6f, 0x97, +- 0x42, 0xdc, 0x49, 0x52, 0x87, 0x76, 0xef, 0xd8, 0x84, 0x35, 0x6a, 0x6d, +- 0x78, 0x3c, 0x0e, 0x39, 0xbc, 0xdc, 0x6e, 0xa1, 0xc4, 0x12, 0xc7, 0xfe, +- 0x2d, 0x29, 0x4a, 0x7e, 0xf1, 0x91, 0x90, 0xb4, 0x58, 0xa8, 0xb7, 0x2d, +- 0x14, 0xd0, 0x80, 0xf4, 0xc9, 0x82, 0x3e, 0x21, 0x09, 0xf6, 0x73, 0x56, +- 0xba, 0x6b, 0xea, 0x7d, 0xd2, 0x52, 0xef, 0x86, 0xf0, 0x2e, 0x22, 0xa9, +- 0x1d, 0xe6, 0xfd, 0x10, 0xde, 0xdf, 0x24, 0x13, 0x36, 0xe6, 0x52, 0x7e, +- 0xc1, 0xca, 0x61, 0x8e, 0x1f, 0x89, 0xa8, 0xb5, 0xa2, 0xee, 0x44, 0x43, +- 0x3f, 0x13, 0xa8, 0xf7, 0x34, 0xc6, 0xc2, 0x7c, 0xcb, 0x49, 0xcc, 0xa5, +- 0x13, 0x73, 0xe1, 0x1c, 0x8b, 0x56, 0xae, 0x1e, 0x41, 0x7e, 0xda, 0xca, +- 0x9f, 0x3d, 0x8a, 0x67, 0xb1, 0xad, 0xcc, 0x0b, 0x4c, 0xd1, 0x7e, 0x5f, +- 0x43, 0xfb, 0x7d, 0x68, 0xcf, 0x31, 0xd8, 0x3e, 0x90, 0xff, 0xa2, 0x92, +- 0xc5, 0xe4, 0x7b, 0xd0, 0x23, 0xfc, 0xf7, 0xa0, 0xc7, 0xd7, 0x34, 0x3d, +- 0x7e, 0x26, 0xbf, 0x78, 0x7a, 0x5c, 0xfd, 0x05, 0xd1, 0x43, 0xa4, 0x70, +- 0x92, 0xcf, 0x11, 0x29, 0x2a, 0xbd, 0xc5, 0x7d, 0x4b, 0x79, 0xa7, 0xce, +- 0x22, 0x9d, 0x28, 0xc7, 0xd8, 0x03, 0xf5, 0x08, 0xd2, 0x67, 0x90, 0x6e, +- 0x0e, 0x8d, 0x9d, 0x7c, 0x13, 0xfc, 0xf7, 0xc5, 0xde, 0x61, 0xec, 0x47, +- 0x31, 0x61, 0x4b, 0x97, 0xd8, 0x1f, 0x84, 0xf1, 0xee, 0x74, 0xec, 0x82, +- 0x7c, 0x9f, 0xef, 0x43, 0xc6, 0xce, 0xe7, 0x66, 0x36, 0xbd, 0x9d, 0x55, +- 0x4f, 0x51, 0xd2, 0x33, 0x6b, 0x65, 0x22, 0xa1, 0x7c, 0x39, 0x39, 0x61, +- 0x65, 0xe2, 0xd0, 0x53, 0xcc, 0x0f, 0x86, 0x82, 0x39, 0x0f, 0xa0, 0xae, +- 0xd1, 0x59, 0x66, 0xee, 0x03, 0x98, 0xfb, 0x7a, 0xdd, 0x95, 0xc5, 0x5c, +- 0x38, 0x07, 0xce, 0xab, 0xa8, 0x75, 0x10, 0xfb, 0x39, 0xa4, 0xfa, 0x09, +- 0x67, 0x06, 0x85, 0xb6, 0xb4, 0x30, 0xc3, 0x7d, 0xc0, 0x76, 0xec, 0x2b, +- 0xd0, 0xc9, 0x85, 0x9a, 0xe9, 0xa3, 0xd8, 0xd8, 0x07, 0xe6, 0x23, 0x5b, +- 0x2d, 0x37, 0x0a, 0xde, 0xb3, 0xab, 0xa3, 0x78, 0xf7, 0xb4, 0xe4, 0xce, +- 0xde, 0x61, 0x61, 0x0d, 0xe8, 0x97, 0x34, 0x1a, 0x83, 0xce, 0xe6, 0x3e, +- 0x8b, 0x49, 0x3e, 0xce, 0xb2, 0x49, 0x3d, 0x6e, 0x44, 0xb2, 0x2a, 0x9f, +- 0x6b, 0x5b, 0x9d, 0xc7, 0x0b, 0x7a, 0x3d, 0x19, 0xac, 0x87, 0x73, 0x30, +- 0x6b, 0xc9, 0x34, 0xac, 0xc5, 0xd0, 0x9a, 0xb4, 0xb0, 0xa1, 0xe3, 0x63, +- 0xda, 0x86, 0xb0, 0xdd, 0x74, 0x03, 0xef, 0xa6, 0xd1, 0x86, 0xb4, 0x47, +- 0x9d, 0x75, 0x76, 0x85, 0x36, 0x65, 0x08, 0xfd, 0x94, 0xe6, 0x2c, 0xc9, +- 0x7b, 0xb0, 0xd9, 0xde, 0xcd, 0x5a, 0x5e, 0x57, 0x65, 0x29, 0xba, 0xa1, +- 0x2c, 0x3d, 0x66, 0x05, 0xfa, 0x1a, 0xb6, 0x05, 0xf6, 0x67, 0x6a, 0xce, +- 0x49, 0x1b, 0x59, 0x2a, 0xcd, 0xbc, 0x1f, 0x59, 0x32, 0xed, 0x63, 0x90, +- 0x5d, 0x33, 0xc6, 0xfa, 0x39, 0x9b, 0x3a, 0x98, 0x63, 0x79, 0x48, 0x63, +- 0x15, 0x8e, 0x13, 0xd8, 0x86, 0xca, 0x1a, 0xdb, 0x70, 0x14, 0x6d, 0x25, +- 0x94, 0xef, 0x6b, 0x95, 0x03, 0x73, 0xa6, 0x8f, 0xa3, 0x4a, 0x66, 0x27, +- 0x67, 0x1c, 0x7b, 0x38, 0x2c, 0xd9, 0xe1, 0xd9, 0x41, 0x19, 0xaa, 0x77, +- 0x81, 0xa7, 0x6f, 0xfb, 0xb0, 0x9d, 0x1f, 0x8c, 0x8a, 0x0b, 0xbd, 0x88, +- 0x35, 0x0f, 0x80, 0xc6, 0xf5, 0xa8, 0x58, 0x19, 0x0f, 0x69, 0x23, 0xd6, +- 0x8a, 0x44, 0x86, 0xd7, 0xe4, 0x9b, 0x50, 0x07, 0x7d, 0x0f, 0xac, 0xaf, +- 0x07, 0xf9, 0x04, 0x6d, 0x73, 0xde, 0xcf, 0x7c, 0xd8, 0x61, 0x6d, 0xb3, +- 0x58, 0x4a, 0x3d, 0x61, 0x74, 0xc4, 0x6f, 0x60, 0x7f, 0xab, 0xbd, 0x50, +- 0x04, 0x76, 0x41, 0x1f, 0xa2, 0xe4, 0xb4, 0x54, 0x7f, 0xce, 0xec, 0x7b, +- 0x55, 0xbe, 0x67, 0x80, 0xb2, 0x57, 0x01, 0x26, 0xe0, 0x9a, 0x16, 0xd5, +- 0x5e, 0xcf, 0xdb, 0x71, 0x99, 0x2e, 0x73, 0x3d, 0x8b, 0x92, 0xaa, 0xfd, +- 0x7b, 0xc9, 0x9f, 0x15, 0xf9, 0xd6, 0x0c, 0xeb, 0x7d, 0x55, 0xd7, 0x7b, +- 0x01, 0xf5, 0x52, 0xc9, 0xa1, 0x90, 0x03, 0x3b, 0xe0, 0x60, 0x9b, 0x6c, +- 0x4b, 0x22, 0xb5, 0x47, 0xf0, 0x1b, 0xa2, 0x91, 0x41, 0xbd, 0x00, 0xfb, +- 0xbc, 0x00, 0x7a, 0x88, 0xdc, 0x5d, 0x6e, 0x86, 0x3e, 0xf9, 0x9f, 0x98, +- 0x6b, 0x5c, 0x9e, 0xc4, 0x3a, 0x5e, 0x9a, 0x21, 0xbe, 0xfa, 0xaa, 0x2c, +- 0xcd, 0x10, 0x6f, 0xbd, 0x20, 0xd3, 0x33, 0x29, 0xef, 0x5b, 0xa0, 0xf3, +- 0x19, 0xe1, 0x5a, 0xb6, 0x79, 0x48, 0x81, 0x05, 0x9d, 0xe4, 0xe3, 0xd0, +- 0x67, 0x7d, 0x3b, 0x82, 0xfe, 0x7a, 0x74, 0x7f, 0x6e, 0xcd, 0x91, 0xab, +- 0x36, 0xf5, 0xd3, 0x3b, 0xf7, 0x78, 0x4e, 0xef, 0xf1, 0x31, 0xaf, 0x4b, +- 0x2c, 0xec, 0xeb, 0xec, 0x78, 0x11, 0xd6, 0x8f, 0xfb, 0xfa, 0x6d, 0x6b, +- 0x15, 0xff, 0x24, 0x80, 0x59, 0x1d, 0x65, 0xef, 0xfe, 0x6e, 0x7b, 0xbc, +- 0x71, 0x6f, 0x73, 0xfc, 0x36, 0xb4, 0x89, 0x20, 0x7d, 0xef, 0x7d, 0x8d, +- 0x3e, 0x1a, 0xda, 0x0e, 0x72, 0x5f, 0xa0, 0xcd, 0xbf, 0x05, 0x2d, 0x48, +- 0xff, 0xf7, 0xb3, 0x9f, 0x6f, 0x0b, 0xbf, 0xaf, 0xfd, 0x3c, 0xfe, 0x5e, +- 0xfb, 0xb9, 0x71, 0x2f, 0x5f, 0x20, 0x2d, 0x30, 0xb6, 0xcc, 0x06, 0xb2, +- 0xd5, 0x03, 0x5a, 0x27, 0x21, 0xa7, 0x98, 0x43, 0xf9, 0x6f, 0xfd, 0x6c, +- 0x24, 0xc0, 0x73, 0x81, 0x3c, 0xb1, 0x9e, 0xa9, 0x13, 0xe8, 0xde, 0xa1, +- 0xfa, 0x55, 0xa5, 0x67, 0x2f, 0x2a, 0x3d, 0xeb, 0x1c, 0x2d, 0x0a, 0xe5, +- 0xed, 0xf6, 0x30, 0xe9, 0x7e, 0xc1, 0xfb, 0x7d, 0xcc, 0xd1, 0x49, 0x26, +- 0xad, 0x9e, 0xa2, 0x65, 0xfd, 0xbe, 0x1c, 0x5c, 0x78, 0x58, 0x0e, 0x96, +- 0xd9, 0xc7, 0x2e, 0xbc, 0x77, 0x51, 0xb6, 0x09, 0xba, 0x96, 0x3a, 0xfd, +- 0xed, 0x50, 0x30, 0x96, 0x05, 0xfb, 0xb5, 0x1c, 0xba, 0xbb, 0x7e, 0x25, +- 0x94, 0x5b, 0xe0, 0xde, 0x45, 0x79, 0xbd, 0x51, 0xe7, 0x1b, 0x7d, 0xff, +- 0x0a, 0xc6, 0x34, 0x72, 0xee, 0x35, 0xe8, 0xd4, 0x69, 0xe2, 0x41, 0x2b, +- 0xe7, 0x91, 0x7f, 0xb4, 0x2d, 0x8f, 0xd8, 0xc1, 0xfa, 0x0f, 0x81, 0x66, +- 0xb4, 0x49, 0xa4, 0x21, 0xec, 0x61, 0x84, 0xfb, 0x97, 0xcf, 0xe2, 0x87, +- 0x33, 0xdc, 0x83, 0x12, 0x09, 0x67, 0x80, 0x7f, 0xe3, 0xac, 0xb3, 0x0b, +- 0x73, 0x0e, 0xf6, 0x77, 0x71, 0x65, 0x7f, 0x77, 0xcb, 0xc4, 0x42, 0x16, +- 0x3a, 0x20, 0xaf, 0xfa, 0x89, 0xba, 0x6b, 0x6c, 0x0b, 0xea, 0x27, 0x35, +- 0x1f, 0x36, 0x1b, 0xfd, 0x87, 0x32, 0x4f, 0x97, 0x35, 0x35, 0x94, 0x19, +- 0x7e, 0x15, 0x30, 0x16, 0x6d, 0xc4, 0x88, 0xc6, 0x3d, 0xbe, 0x9f, 0x27, +- 0x9f, 0xfb, 0xf7, 0x09, 0xf7, 0xc4, 0xa5, 0x72, 0xd1, 0x0e, 0x2b, 0xd9, +- 0x5c, 0xfc, 0xd8, 0xaa, 0x6c, 0x02, 0x27, 0xab, 0x5e, 0x48, 0x5b, 0xce, +- 0xa5, 0x15, 0xb4, 0x1c, 0xc2, 0x1a, 0x40, 0xb3, 0xce, 0x10, 0xe8, 0xd6, +- 0x2a, 0x85, 0xfa, 0x2e, 0xfd, 0x8e, 0xe5, 0x11, 0x19, 0x8b, 0x1b, 0x3b, +- 0xf4, 0xe7, 0x5b, 0x03, 0xac, 0x8b, 0x3a, 0xe5, 0xff, 0x1d, 0x0e, 0x64, +- 0xdf, 0x96, 0xc2, 0xe9, 0x21, 0xc8, 0x18, 0xb1, 0xd8, 0x26, 0x2d, 0x63, +- 0xec, 0x07, 0xe5, 0x67, 0x29, 0xc3, 0xa2, 0xf5, 0xe7, 0x20, 0xd2, 0x1f, +- 0x87, 0x69, 0xb7, 0xd9, 0x57, 0xe1, 0xb4, 0x69, 0x6f, 0xe6, 0xd1, 0xb1, +- 0xd2, 0xcf, 0x98, 0x67, 0x49, 0x58, 0xcd, 0x05, 0x65, 0x67, 0xd7, 0xce, +- 0xc5, 0xea, 0x34, 0x73, 0x79, 0x34, 0x1c, 0xcc, 0xa5, 0xa3, 0xa1, 0xaf, +- 0x78, 0xc3, 0x5c, 0x9a, 0x30, 0x97, 0xb8, 0xb2, 0x37, 0x9c, 0xcb, 0x05, +- 0xf0, 0xbe, 0x70, 0xf6, 0xc6, 0xeb, 0x82, 0x36, 0xf1, 0x86, 0x36, 0x9d, +- 0xeb, 0xda, 0xb0, 0xbe, 0x19, 0x03, 0xef, 0xce, 0x5e, 0xdd, 0x1c, 0xb4, +- 0x61, 0xbd, 0x26, 0xd8, 0x37, 0xbe, 0x53, 0x7e, 0x5b, 0x83, 0xfc, 0x1f, +- 0x84, 0xfc, 0x1b, 0xb9, 0x32, 0xb6, 0xd9, 0xf0, 0x75, 0x53, 0x28, 0x7f, +- 0xf2, 0x03, 0xf4, 0x3d, 0x43, 0x63, 0xe5, 0x25, 0xf8, 0x0f, 0x49, 0x29, +- 0xa4, 0xe1, 0x9b, 0xd8, 0x83, 0xa2, 0xfc, 0x89, 0x34, 0x7c, 0x16, 0x7b, +- 0xb3, 0xc2, 0x5b, 0x85, 0x74, 0xbf, 0xb6, 0x59, 0xdf, 0x97, 0x09, 0xc8, +- 0x70, 0x21, 0x9d, 0xc6, 0x78, 0xd0, 0xd5, 0x6e, 0x2f, 0xda, 0x71, 0xdc, +- 0xb7, 0x22, 0xb4, 0x23, 0x17, 0xca, 0x1f, 0x47, 0x7e, 0x33, 0xde, 0xff, +- 0xa9, 0x9e, 0x4f, 0x1b, 0xea, 0x7c, 0x5a, 0xf9, 0x26, 0x17, 0x54, 0x1d, +- 0xf6, 0x71, 0x19, 0xf9, 0x3b, 0x50, 0x07, 0x9b, 0x1c, 0x12, 0x68, 0xb9, +- 0x3b, 0xf1, 0xfb, 0x36, 0xca, 0x3e, 0x84, 0xb2, 0x2f, 0xa3, 0xec, 0x76, +- 0xe4, 0x5f, 0x5c, 0xd7, 0xef, 0x36, 0xe4, 0x1f, 0xc3, 0x7b, 0xac, 0xd3, +- 0xfe, 0x06, 0xde, 0xdf, 0x81, 0xdf, 0x97, 0xd7, 0xd5, 0xf9, 0x37, 0xeb, +- 0xf2, 0xc6, 0x2f, 0xf8, 0x63, 0x2d, 0x73, 0xc6, 0x27, 0x08, 0xf4, 0xe8, +- 0x54, 0xb9, 0x35, 0x34, 0x7c, 0x3a, 0x16, 0xda, 0x73, 0x9a, 0x78, 0x23, +- 0xa2, 0xfc, 0x80, 0x08, 0xfc, 0x80, 0xe9, 0x39, 0x3a, 0x88, 0x11, 0x94, +- 0x11, 0xbb, 0xcb, 0x40, 0x93, 0xf4, 0x78, 0x57, 0xb0, 0x4f, 0x0a, 0xb5, +- 0x2e, 0xe4, 0xb9, 0x7f, 0x20, 0x63, 0xb5, 0x16, 0xc8, 0x75, 0x4f, 0xba, +- 0x0a, 0x19, 0x3b, 0x00, 0xdf, 0x64, 0x02, 0x36, 0x70, 0xa2, 0xd6, 0x25, +- 0x0f, 0xd4, 0xae, 0x44, 0x02, 0x39, 0x32, 0x63, 0x3f, 0xbd, 0x6e, 0xec, +- 0x18, 0xfd, 0x0a, 0xc8, 0xfd, 0xfc, 0xe8, 0xfe, 0x39, 0x8e, 0x6f, 0x75, +- 0x47, 0xa4, 0x0d, 0x73, 0xa0, 0xff, 0x28, 0xbd, 0x11, 0xe9, 0x49, 0x4e, +- 0x29, 0x07, 0xb5, 0x28, 0xe1, 0x4c, 0x0f, 0xec, 0x83, 0xca, 0xc3, 0x5f, +- 0x84, 0xbe, 0xab, 0xad, 0xfa, 0x91, 0xc3, 0x2b, 0x7e, 0x64, 0x17, 0xfc, +- 0xcc, 0x17, 0x23, 0xc1, 0xde, 0x6f, 0x85, 0x6e, 0xb8, 0x9e, 0x38, 0x47, +- 0xe9, 0x77, 0xee, 0xf1, 0x9c, 0xd7, 0xae, 0xf3, 0x94, 0x65, 0xe8, 0x0b, +- 0x2b, 0xaa, 0xf4, 0x95, 0x58, 0x78, 0x37, 0x40, 0xf9, 0x45, 0x7e, 0xa1, +- 0x71, 0x7f, 0xff, 0x0e, 0xf6, 0x32, 0xdf, 0x1b, 0x39, 0xc3, 0x3f, 0x4a, +- 0xc6, 0x18, 0xbf, 0xf8, 0x8b, 0x75, 0x6b, 0x3b, 0xb0, 0x6e, 0x6d, 0x91, +- 0x15, 0xba, 0x72, 0x8d, 0x51, 0xac, 0x71, 0x69, 0x8e, 0xb4, 0xed, 0x87, +- 0x7c, 0x8a, 0x1b, 0x11, 0xca, 0x31, 0xf5, 0x6a, 0x1b, 0x74, 0x35, 0x69, +- 0x17, 0x11, 0xc6, 0x3c, 0x26, 0xb0, 0xa6, 0x09, 0xac, 0x69, 0xa2, 0x81, +- 0x8e, 0x07, 0x56, 0xd6, 0x64, 0xe6, 0x8d, 0x7a, 0x6a, 0xbf, 0xf1, 0x99, +- 0x3f, 0xe8, 0xa9, 0x36, 0x83, 0x69, 0x38, 0x97, 0xdc, 0xba, 0xb9, 0x90, +- 0x16, 0x9c, 0xcb, 0xca, 0x3c, 0xe2, 0x8c, 0x1c, 0x1d, 0xac, 0x91, 0xaf, +- 0x1c, 0x73, 0xaf, 0x4c, 0x96, 0x3f, 0xa0, 0xe7, 0xd1, 0x8a, 0x79, 0x8c, +- 0x41, 0x6f, 0x70, 0x3c, 0xec, 0xff, 0xda, 0x38, 0x9e, 0xe3, 0xe4, 0xbf, +- 0x9e, 0x8b, 0xa1, 0x05, 0xfd, 0xb6, 0x84, 0xc6, 0xe2, 0x86, 0x5e, 0xae, +- 0xc2, 0x0e, 0x97, 0xca, 0xff, 0x6d, 0x6b, 0x30, 0xb7, 0xa4, 0x9e, 0x47, +- 0x40, 0x63, 0x60, 0x78, 0x60, 0xa9, 0xbc, 0xd6, 0x07, 0x8d, 0x74, 0xbd, +- 0xbb, 0x49, 0xeb, 0x2b, 0xc8, 0x40, 0x63, 0xf9, 0xa7, 0x9a, 0x56, 0xeb, +- 0x32, 0x3f, 0xaf, 0xf3, 0x5b, 0x42, 0xc3, 0x27, 0x4d, 0xd9, 0xd5, 0xa6, +- 0x77, 0xf6, 0xf7, 0xd5, 0x26, 0xa3, 0x3f, 0x2e, 0x95, 0x1b, 0xf7, 0xfb, +- 0x21, 0x2b, 0xb0, 0x3b, 0x45, 0x29, 0x0d, 0x64, 0xa1, 0xe7, 0x68, 0x7f, +- 0x86, 0xac, 0xc0, 0xf6, 0xb0, 0xce, 0x21, 0x85, 0x1d, 0x23, 0x99, 0x2a, +- 0xe5, 0x1e, 0xb4, 0xac, 0x8d, 0xe6, 0x66, 0x7c, 0x7f, 0xca, 0x5b, 0x4e, +- 0x84, 0x85, 0x7a, 0x99, 0xb8, 0x8d, 0xe5, 0xcf, 0xa0, 0x1c, 0x76, 0xbd, +- 0x3e, 0x26, 0x6c, 0xb7, 0x31, 0x3e, 0x4b, 0x6a, 0x7c, 0x16, 0x00, 0xbb, +- 0x9c, 0xc2, 0x53, 0x4f, 0x8d, 0xc2, 0xfe, 0xeb, 0xe7, 0xa7, 0xf1, 0x9c, +- 0x6c, 0xc4, 0x80, 0xe8, 0xb7, 0x32, 0x9a, 0x9b, 0x53, 0x76, 0x00, 0xfb, +- 0x81, 0xbc, 0x3a, 0x03, 0x5e, 0x85, 0x64, 0x5a, 0xd9, 0x04, 0xce, 0x83, +- 0xed, 0x2a, 0xa3, 0xdd, 0x8b, 0x4c, 0xab, 0xa3, 0xee, 0x62, 0x58, 0x0e, +- 0xc4, 0x83, 0xb6, 0xcc, 0x27, 0x17, 0x8d, 0xdd, 0x6e, 0x91, 0x68, 0x86, +- 0xba, 0xcd, 0x49, 0x03, 0x87, 0x62, 0x3d, 0x47, 0x47, 0xa7, 0x5d, 0xda, +- 0xcb, 0xff, 0x03, 0x79, 0x68, 0x91, 0x26, 0x25, 0x27, 0x4f, 0xea, 0xb1, +- 0xce, 0x60, 0xac, 0xad, 0x98, 0x6b, 0x18, 0x3a, 0x32, 0x92, 0xc0, 0x38, +- 0x87, 0x2d, 0x77, 0x1b, 0xc6, 0xa3, 0xd7, 0xd8, 0x25, 0x53, 0x75, 0xca, +- 0xfa, 0xdf, 0x44, 0x56, 0x7d, 0xc5, 0x13, 0x68, 0x67, 0x7c, 0x14, 0x8e, +- 0x57, 0x05, 0x46, 0x69, 0xc1, 0x3a, 0x1c, 0x3b, 0x17, 0x86, 0xed, 0x9b, +- 0x33, 0x75, 0x38, 0xa7, 0xe3, 0xa3, 0xa9, 0xc5, 0x14, 0xfa, 0xea, 0xa2, +- 0xec, 0x41, 0xe6, 0xc2, 0xf8, 0xb1, 0x6f, 0xb6, 0x83, 0x4e, 0x1e, 0x34, +- 0x76, 0x7c, 0xb5, 0xbd, 0x69, 0xd7, 0xbd, 0x38, 0xa2, 0x65, 0xf7, 0xaf, +- 0xfc, 0xec, 0x38, 0xdf, 0x37, 0xc6, 0x07, 0x4c, 0x3b, 0x53, 0x27, 0xac, +- 0xf5, 0xf1, 0x7d, 0xd1, 0xd5, 0x79, 0x3e, 0x35, 0x1a, 0xf8, 0x31, 0x12, +- 0xc9, 0xf7, 0x0d, 0x6a, 0xbe, 0x3d, 0x8d, 0x32, 0xb6, 0xc7, 0x5e, 0xa8, +- 0x37, 0x62, 0xf0, 0xa0, 0xdf, 0x22, 0xb0, 0x47, 0xa9, 0xdc, 0x04, 0x5d, +- 0x93, 0x6d, 0x0f, 0x62, 0x22, 0xef, 0x85, 0xbb, 0xc1, 0x53, 0xf4, 0x53, +- 0x5a, 0x69, 0xab, 0xe2, 0x93, 0xa3, 0x2f, 0xa1, 0xff, 0x23, 0xe5, 0x60, +- 0xaf, 0x05, 0x74, 0x20, 0x5e, 0x0a, 0xc9, 0x92, 0x9b, 0x84, 0x7f, 0x47, +- 0x3b, 0x94, 0x94, 0x97, 0x5d, 0x83, 0x9f, 0x88, 0x9d, 0x50, 0xbf, 0xce, +- 0xf9, 0x70, 0xdd, 0x27, 0xb0, 0x6e, 0x5f, 0x66, 0xbd, 0x40, 0x3e, 0xfa, +- 0xb0, 0x37, 0xff, 0x53, 0xc4, 0x39, 0x4a, 0x3f, 0xe0, 0x6a, 0xa4, 0x71, +- 0x5d, 0xc6, 0x9e, 0x3d, 0xa5, 0x63, 0x93, 0x27, 0x34, 0x2f, 0x2b, 0xe0, +- 0xe5, 0xb6, 0xa4, 0x2d, 0xbd, 0x98, 0x3b, 0xea, 0xf4, 0xf7, 0x00, 0x8f, +- 0xd3, 0xd7, 0x4b, 0x60, 0x3e, 0x36, 0x64, 0x7d, 0xab, 0xb6, 0xfb, 0x9f, +- 0x89, 0x52, 0x5f, 0xb4, 0xab, 0xb8, 0xe7, 0x09, 0x25, 0x6b, 0x81, 0xec, +- 0x85, 0xf5, 0x7b, 0xc3, 0xef, 0x30, 0xcd, 0xae, 0xac, 0xc6, 0xf9, 0x8c, +- 0xae, 0x66, 0xfd, 0x39, 0xd4, 0x0f, 0x61, 0x4d, 0xbe, 0x3f, 0xa9, 0xe6, +- 0x3b, 0x0f, 0x5e, 0x87, 0xa5, 0xb4, 0x22, 0x8f, 0xf3, 0x90, 0xc7, 0x26, +- 0x91, 0x8e, 0x46, 0xb9, 0xa1, 0xac, 0xbc, 0x1e, 0x65, 0x4c, 0x2e, 0x69, +- 0x19, 0xde, 0x45, 0x88, 0xdd, 0x90, 0x37, 0xbc, 0xe3, 0xf3, 0x46, 0x18, +- 0x90, 0x71, 0x27, 0xdf, 0x5f, 0xf2, 0x18, 0x23, 0x6c, 0x96, 0xa2, 0x1d, +- 0xe0, 0x97, 0x92, 0x47, 0x39, 0xcd, 0x25, 0x23, 0xe2, 0x24, 0x0e, 0xc8, +- 0x9b, 0xe8, 0x3b, 0x9b, 0x8e, 0x4a, 0xe0, 0xa7, 0x4e, 0x80, 0x6e, 0xcb, +- 0xb6, 0xef, 0xbf, 0x04, 0xbf, 0xba, 0x0a, 0xbf, 0x66, 0x09, 0x69, 0xa9, +- 0x86, 0x3d, 0xd0, 0x12, 0xc1, 0x9e, 0x32, 0x7b, 0x25, 0x26, 0x15, 0xd4, +- 0x59, 0xc0, 0xbb, 0xc7, 0x6b, 0x86, 0xcb, 0xbe, 0x6f, 0x61, 0x5d, 0xfb, +- 0xdd, 0xbf, 0xf6, 0x0b, 0xf1, 0xc6, 0xba, 0x06, 0x77, 0x11, 0x33, 0x11, +- 0xf3, 0x10, 0xab, 0xf0, 0x1d, 0xf1, 0xc7, 0x61, 0xcc, 0x85, 0x32, 0xdc, +- 0x26, 0xb1, 0x8c, 0x93, 0x18, 0x11, 0xa3, 0x8b, 0x5f, 0x03, 0xff, 0x8b, +- 0x7e, 0xb3, 0xdb, 0x25, 0xcf, 0x83, 0xd7, 0xcf, 0xd5, 0x0d, 0xef, 0x93, +- 0xe0, 0xbd, 0x53, 0x2c, 0x8a, 0x2f, 0x17, 0x3d, 0x37, 0xf9, 0x39, 0xa4, +- 0xdf, 0xf1, 0x7e, 0x85, 0xb4, 0x78, 0x0a, 0x26, 0x0f, 0x38, 0x1b, 0x7a, +- 0x75, 0xd6, 0xe0, 0xc7, 0x36, 0xe2, 0x7d, 0x4d, 0xc7, 0xab, 0xe8, 0xd3, +- 0xb1, 0x2d, 0x80, 0xa5, 0x3b, 0x51, 0x2f, 0x90, 0x6b, 0x53, 0x76, 0x18, +- 0x75, 0x39, 0x07, 0xfa, 0x62, 0xdf, 0xc5, 0x5e, 0xf2, 0xfd, 0x7b, 0xbd, +- 0xc9, 0x86, 0x3d, 0x31, 0x0f, 0x1e, 0x28, 0xd9, 0x1c, 0x68, 0x17, 0xc6, +- 0xee, 0xa4, 0xbf, 0x43, 0xf9, 0x0a, 0x7c, 0x86, 0x8c, 0x0e, 0xd0, 0x26, +- 0x24, 0x55, 0xdc, 0x8f, 0xb6, 0xe7, 0x39, 0xd0, 0xfe, 0xd3, 0x35, 0xf2, +- 0xa1, 0x55, 0xe9, 0xfe, 0xe7, 0xcb, 0xb4, 0xef, 0x01, 0x46, 0x9b, 0x50, +- 0xb1, 0x5c, 0xda, 0x84, 0x34, 0x78, 0x13, 0xc4, 0xf0, 0x1e, 0x50, 0x6d, +- 0x59, 0x8f, 0x6d, 0x1b, 0xf9, 0xc7, 0x3a, 0x5b, 0x81, 0xaf, 0x28, 0x83, +- 0x6d, 0xc0, 0x25, 0xed, 0x72, 0x20, 0xdd, 0x0c, 0xba, 0x77, 0x28, 0x3c, +- 0x65, 0xb9, 0x1f, 0x86, 0xed, 0x02, 0xa6, 0xb3, 0x1d, 0x6f, 0xd5, 0xf7, +- 0xb8, 0x1d, 0x65, 0x3f, 0x05, 0xfd, 0x59, 0xb6, 0x49, 0xc7, 0xaf, 0x1f, +- 0xc6, 0xfe, 0xab, 0x6c, 0x0d, 0xe2, 0x22, 0xe4, 0x83, 0xd1, 0x03, 0xc6, +- 0xfe, 0xd9, 0x1a, 0x47, 0x92, 0x37, 0x41, 0x0c, 0xc5, 0x52, 0x75, 0x89, +- 0xe7, 0x1b, 0xfd, 0x16, 0xee, 0x3b, 0xdf, 0xbf, 0xe8, 0x29, 0x7b, 0x0a, +- 0x1e, 0xec, 0x86, 0x0d, 0x8b, 0x68, 0x5a, 0xb7, 0x82, 0xd6, 0x81, 0x8d, +- 0x4d, 0x76, 0x40, 0xef, 0xb8, 0x56, 0x53, 0x40, 0x3f, 0x62, 0x85, 0xbf, +- 0x85, 0x1f, 0x4f, 0xff, 0x81, 0x38, 0x81, 0x73, 0x47, 0xbb, 0x05, 0xd6, +- 0xa5, 0x2d, 0x7e, 0x0c, 0x63, 0x84, 0x25, 0xd9, 0xc9, 0xfc, 0x03, 0xba, +- 0x0d, 0x9f, 0x7d, 0xe9, 0xdd, 0xd1, 0x28, 0xcf, 0x83, 0x98, 0x27, 0xd7, +- 0x63, 0xe2, 0x7a, 0x5d, 0x4a, 0x07, 0xac, 0xca, 0x85, 0x99, 0x93, 0x19, +- 0x97, 0x73, 0x4b, 0x48, 0x07, 0xe6, 0x76, 0x37, 0x74, 0xf4, 0x8e, 0x0e, +- 0xf6, 0x69, 0xc6, 0x6e, 0x9c, 0x93, 0xc1, 0x2f, 0x81, 0xdd, 0x8d, 0xba, +- 0xcd, 0xb2, 0xa3, 0x93, 0xb4, 0xeb, 0x52, 0xba, 0x7a, 0x95, 0x1f, 0xb4, +- 0xbf, 0x1c, 0x7b, 0x7d, 0xf9, 0x1d, 0x0d, 0xf3, 0x6a, 0x3c, 0x03, 0x20, +- 0x76, 0xd8, 0x89, 0x77, 0x9c, 0x13, 0x9c, 0xe4, 0xb8, 0x2f, 0x7b, 0x14, +- 0xdd, 0x38, 0xb7, 0xc6, 0x79, 0x10, 0x43, 0x71, 0xce, 0x9c, 0xc3, 0x7a, +- 0x6c, 0xc2, 0xf9, 0xfc, 0x57, 0xcd, 0xc3, 0x4d, 0x7a, 0x5d, 0x06, 0xcb, +- 0xa4, 0xd0, 0xf6, 0x3f, 0x60, 0x0d, 0x7c, 0xe6, 0x3a, 0x8c, 0xcd, 0x4e, +- 0x05, 0xfd, 0xb4, 0x98, 0x78, 0xb0, 0x89, 0x6b, 0x70, 0x5e, 0xdc, 0x33, +- 0x86, 0x4e, 0x1d, 0x9a, 0x47, 0xbb, 0xd7, 0x8d, 0xeb, 0x78, 0x6b, 0xf5, +- 0xc8, 0xed, 0x0d, 0xeb, 0xeb, 0x97, 0xe2, 0x02, 0xe5, 0xe2, 0x36, 0xa4, +- 0x06, 0x13, 0x0c, 0x40, 0xf7, 0xbf, 0x2b, 0x26, 0xe0, 0x59, 0xd5, 0x78, +- 0x01, 0x3e, 0x99, 0xd2, 0xfd, 0x6a, 0x2f, 0xc6, 0x90, 0x87, 0x3e, 0xa9, +- 0xdf, 0x43, 0x19, 0x1b, 0x9f, 0xa8, 0x79, 0xe3, 0x93, 0xb5, 0x81, 0x71, +- 0xe2, 0xa9, 0x40, 0xe6, 0x50, 0xbf, 0x26, 0x13, 0xf0, 0xb3, 0xc7, 0x73, +- 0xaa, 0x9d, 0x8a, 0x31, 0x6c, 0xd0, 0x8f, 0x70, 0x3f, 0x4e, 0x04, 0x63, +- 0xc5, 0xc6, 0xf3, 0xd0, 0x41, 0x0b, 0xb3, 0xb0, 0x4b, 0xae, 0x93, 0xa5, +- 0x5c, 0xee, 0xf7, 0x9c, 0x11, 0x25, 0x7b, 0x71, 0x67, 0x8c, 0xbc, 0xac, +- 0xce, 0xfe, 0xb2, 0x2c, 0xcc, 0xf9, 0x72, 0x17, 0x74, 0xe1, 0x43, 0x90, +- 0x55, 0x39, 0x07, 0x45, 0x78, 0x0e, 0xca, 0xeb, 0x5c, 0x5c, 0xac, 0x53, +- 0x5d, 0x12, 0x3d, 0x96, 0x90, 0xc8, 0x31, 0x62, 0xcb, 0x94, 0x7d, 0x97, +- 0x08, 0xec, 0xd8, 0x8b, 0x1f, 0xb2, 0xc4, 0x19, 0xcc, 0x4a, 0x2a, 0xf9, +- 0x38, 0x6c, 0x6f, 0x15, 0x69, 0x49, 0x52, 0xe9, 0xb3, 0xe8, 0x2b, 0x7a, +- 0x0e, 0x75, 0xd1, 0x6e, 0xd3, 0x52, 0x12, 0xbf, 0x4e, 0x69, 0x59, 0x0a, +- 0xf6, 0x4a, 0xcb, 0xd2, 0x5a, 0xff, 0x7c, 0x68, 0xc5, 0x3f, 0xe7, 0xfb, +- 0xb7, 0x75, 0x5c, 0xe1, 0x8b, 0xfa, 0x8c, 0x81, 0x32, 0x42, 0x7b, 0xa4, +- 0x7c, 0x63, 0xe8, 0xfd, 0x2f, 0xc2, 0xc7, 0x02, 0x0e, 0x2c, 0xc3, 0x97, +- 0xca, 0xf8, 0xf2, 0xac, 0x57, 0xf4, 0x73, 0x03, 0xbe, 0xbc, 0xe6, 0xb9, +- 0xc5, 0x82, 0x38, 0x6f, 0x53, 0xdf, 0xfd, 0x85, 0xf7, 0x4f, 0xe4, 0xfe, +- 0x76, 0xe7, 0xfe, 0x6c, 0xa8, 0xe8, 0xb7, 0xc2, 0xb7, 0xba, 0x31, 0x73, +- 0x58, 0xf6, 0x6f, 0x5f, 0x86, 0x0f, 0x9c, 0xbd, 0x11, 0x38, 0x2b, 0x51, +- 0x50, 0xba, 0xea, 0x75, 0xe5, 0xb7, 0x7d, 0xa2, 0xe7, 0xb0, 0x6c, 0xd9, +- 0xee, 0xd8, 0xd7, 0xc2, 0xc4, 0x40, 0x87, 0x25, 0x0f, 0xfd, 0x9f, 0x0f, +- 0xbb, 0xf6, 0x5e, 0x71, 0x46, 0x1e, 0x11, 0x9e, 0x0d, 0xba, 0xd2, 0x7d, +- 0xcc, 0x4d, 0x7c, 0x32, 0xd4, 0x7b, 0xf0, 0x93, 0xc0, 0xae, 0xdd, 0xe7, +- 0x98, 0xf7, 0x25, 0xb6, 0xdd, 0xc6, 0x73, 0x5c, 0xba, 0x4f, 0x25, 0x25, +- 0x05, 0xba, 0xf4, 0x29, 0x9a, 0xf0, 0x6c, 0x22, 0x21, 0xbd, 0xc7, 0x88, +- 0x49, 0x14, 0x6d, 0xfa, 0x40, 0x9b, 0x34, 0x68, 0x03, 0x9f, 0x66, 0x9b, +- 0x7d, 0x0d, 0xe9, 0x65, 0x49, 0x0d, 0x7e, 0x0f, 0xb4, 0xe9, 0x03, 0x6d, +- 0x7a, 0xcf, 0x25, 0xd1, 0x1e, 0x7d, 0x2c, 0x75, 0x23, 0x6d, 0x91, 0x5f, +- 0xbb, 0xbe, 0x13, 0xcf, 0xae, 0xa4, 0x8e, 0xc5, 0x30, 0x46, 0x48, 0xf6, +- 0xf4, 0x14, 0x65, 0x78, 0x3b, 0x30, 0x74, 0xfc, 0xb0, 0x5c, 0x81, 0x1d, +- 0x2a, 0xc3, 0x7f, 0x7b, 0x76, 0xd0, 0x19, 0x5b, 0x86, 0x2e, 0xad, 0xdf, +- 0xed, 0xcb, 0x37, 0xb6, 0x7f, 0xd3, 0x4f, 0x5c, 0xef, 0xdc, 0x2f, 0xa1, +- 0x01, 0x99, 0x2e, 0x2b, 0xfb, 0x90, 0xc8, 0x85, 0x15, 0xd6, 0xc1, 0x1a, +- 0x8b, 0xb0, 0x31, 0x3c, 0xf3, 0x74, 0xa1, 0xeb, 0x1f, 0x91, 0x87, 0x2a, +- 0x53, 0xf8, 0x01, 0x77, 0xcf, 0xb0, 0xee, 0x41, 0xe0, 0xed, 0x87, 0xe5, +- 0xc0, 0x0c, 0xb0, 0x58, 0x06, 0xf3, 0x1e, 0x70, 0x81, 0xcb, 0x33, 0xcd, +- 0xd2, 0x86, 0x32, 0xd0, 0x76, 0xac, 0xbe, 0x1e, 0xd7, 0x2e, 0x83, 0x0f, +- 0x83, 0xf2, 0x27, 0xf5, 0x01, 0xf9, 0x4a, 0xbd, 0x5f, 0xbe, 0x04, 0xdb, +- 0xf2, 0x5c, 0xbd, 0x0b, 0x7b, 0x25, 0x01, 0x9e, 0x64, 0xc0, 0x1f, 0x4f, +- 0xbe, 0x5c, 0x4f, 0xcb, 0x17, 0x41, 0xab, 0xe7, 0xf1, 0x1b, 0x2e, 0xa7, +- 0x65, 0x4f, 0xb9, 0x5f, 0xf3, 0x88, 0xfc, 0x71, 0x31, 0x1f, 0x17, 0x6b, +- 0x77, 0x9e, 0x29, 0x62, 0xff, 0x2d, 0xd4, 0xdd, 0xb7, 0xaa, 0x34, 0xb2, +- 0x6d, 0xb6, 0x9c, 0x59, 0xb1, 0x2f, 0x45, 0xdf, 0x76, 0x9d, 0xa3, 0x13, +- 0xe0, 0x43, 0x15, 0xfb, 0x74, 0x4c, 0xd1, 0x7e, 0xd5, 0xf6, 0x54, 0x03, +- 0xdb, 0x63, 0xd6, 0x37, 0x5b, 0x90, 0xef, 0x48, 0xee, 0xc4, 0xb4, 0xec, +- 0x3f, 0xe9, 0xcb, 0x6f, 0x7a, 0x3e, 0xe4, 0x98, 0xba, 0x78, 0x80, 0x3a, +- 0x3e, 0x39, 0x11, 0xb6, 0x94, 0x9f, 0x1b, 0x60, 0x8d, 0xef, 0x75, 0x60, +- 0xcf, 0xa6, 0xb3, 0xd6, 0x94, 0xa4, 0x4e, 0x4c, 0x49, 0xf7, 0x09, 0xc8, +- 0x82, 0xc7, 0xbe, 0x96, 0x6d, 0xeb, 0x1d, 0xf2, 0xc0, 0x71, 0x9c, 0xc1, +- 0xbc, 0xb8, 0xf6, 0x5b, 0x92, 0xc6, 0xf8, 0x87, 0xa4, 0x07, 0x6d, 0x5c, +- 0xb4, 0xb9, 0xa6, 0xc6, 0x6e, 0xc5, 0xd8, 0xcd, 0x72, 0x24, 0xee, 0x40, +- 0xd6, 0x68, 0xc3, 0xff, 0xaf, 0xe4, 0xaa, 0x4c, 0x7f, 0x24, 0xb9, 0x33, +- 0x6f, 0x37, 0x4b, 0x0b, 0x9f, 0xa1, 0x1a, 0xe6, 0x59, 0xde, 0x8d, 0x94, +- 0xe5, 0xae, 0x58, 0xc7, 0x7f, 0x22, 0xb9, 0xf3, 0x1c, 0xfb, 0x2d, 0x94, +- 0x7f, 0x43, 0x72, 0xc7, 0x7f, 0x8a, 0xfc, 0x15, 0xa4, 0x6f, 0x23, 0x1d, +- 0x93, 0xee, 0xe3, 0xf0, 0x91, 0xcf, 0x7f, 0x1b, 0x79, 0xf8, 0x74, 0xe7, +- 0x8f, 0xa0, 0xde, 0x6e, 0xcc, 0xef, 0xde, 0x18, 0xb0, 0x06, 0x74, 0x5e, +- 0xec, 0xba, 0x60, 0xfe, 0x2c, 0x67, 0x19, 0xdf, 0x1d, 0x81, 0x4e, 0xfb, +- 0x1f, 0xd0, 0x69, 0xfa, 0x79, 0x81, 0x79, 0xea, 0x36, 0x3e, 0x4f, 0x81, +- 0x26, 0x87, 0x90, 0xf7, 0xe5, 0x61, 0x8f, 0xf6, 0x66, 0xa7, 0x8c, 0xdb, +- 0x45, 0xbf, 0x05, 0xb8, 0xa2, 0x15, 0xfb, 0x60, 0x6a, 0xc7, 0xc6, 0xfb, +- 0xe0, 0x68, 0xef, 0x61, 0xd9, 0xb4, 0xdd, 0xac, 0xdf, 0xac, 0xd7, 0xb5, +- 0x7f, 0xa8, 0xe8, 0xe0, 0x14, 0x3f, 0x29, 0x5c, 0x87, 0x9b, 0x78, 0xd2, +- 0xea, 0xbd, 0xff, 0x21, 0xec, 0x03, 0xeb, 0x3c, 0xf3, 0xc1, 0x3e, 0xb0, +- 0xce, 0x43, 0x37, 0xcc, 0xc3, 0x47, 0x9b, 0xef, 0x92, 0xe6, 0xe3, 0xab, +- 0xfb, 0xa0, 0xe9, 0xf8, 0xcf, 0xdf, 0x07, 0xcd, 0xe7, 0x51, 0xef, 0x3c, +- 0x69, 0x86, 0x3e, 0xce, 0x90, 0x66, 0x9d, 0x48, 0x1f, 0xc1, 0x5a, 0x39, +- 0xf7, 0x66, 0xcc, 0x3d, 0xc0, 0x45, 0x1f, 0x82, 0xbc, 0x7f, 0x62, 0xfb, +- 0x21, 0x5d, 0xfe, 0x9f, 0xfd, 0x91, 0xb8, 0x53, 0x91, 0x10, 0x69, 0x8a, +- 0xba, 0x55, 0xd2, 0xf0, 0x79, 0xd0, 0xe6, 0xa0, 0x74, 0x93, 0x7e, 0xd5, +- 0xbd, 0xc8, 0x17, 0xfd, 0x28, 0x7d, 0x74, 0x45, 0x4f, 0xe0, 0xa4, 0x01, +- 0x96, 0xbf, 0x0a, 0x99, 0x21, 0xc6, 0x7c, 0x5d, 0xf6, 0xcf, 0xf8, 0x32, +- 0xee, 0x71, 0xfd, 0x6f, 0x62, 0xfd, 0xd9, 0xed, 0x71, 0x59, 0x4e, 0xc6, +- 0x41, 0x93, 0x05, 0xe8, 0xf6, 0x2b, 0x12, 0xd0, 0x81, 0x31, 0xe7, 0x3d, +- 0xe2, 0x26, 0x86, 0xc5, 0x4d, 0x7f, 0x0f, 0x74, 0x18, 0x86, 0xec, 0xe7, +- 0xeb, 0x94, 0x9d, 0x57, 0x64, 0x08, 0x32, 0xf1, 0x86, 0xe7, 0xa4, 0x81, +- 0x85, 0xa0, 0x2f, 0x28, 0x17, 0x94, 0x89, 0x36, 0xa5, 0x93, 0xe6, 0x3d, +- 0xe7, 0xa9, 0xaa, 0xdc, 0x2a, 0xf3, 0x0a, 0x9b, 0xe2, 0xdd, 0x71, 0x65, +- 0x2f, 0xd2, 0x13, 0x56, 0x0f, 0x74, 0x74, 0x5a, 0xec, 0xde, 0x9b, 0x9b, +- 0xcd, 0x3d, 0x85, 0xc2, 0x89, 0x90, 0x4c, 0xf5, 0x92, 0x57, 0xec, 0x17, +- 0xf9, 0x6a, 0xd1, 0x8f, 0xb8, 0x6f, 0xf9, 0xa7, 0x3b, 0x93, 0xf2, 0xe9, +- 0xde, 0x15, 0xb9, 0xac, 0x88, 0x04, 0xfb, 0x62, 0x48, 0xf1, 0xc3, 0xcc, +- 0xdb, 0xac, 0xc5, 0xbc, 0xeb, 0x6f, 0x78, 0xc7, 0xb5, 0x50, 0xd6, 0x57, +- 0xf6, 0x4e, 0xf2, 0x9d, 0x73, 0xfd, 0x5d, 0xd0, 0xcc, 0x79, 0xaa, 0x24, +- 0xaf, 0x41, 0xf6, 0x40, 0xc3, 0xf3, 0x4c, 0x49, 0xc3, 0x29, 0xc8, 0xfd, +- 0xab, 0xb2, 0xe7, 0x04, 0xf7, 0xcc, 0xab, 0x58, 0xab, 0xd2, 0x25, 0xd0, +- 0x11, 0xec, 0xcf, 0x97, 0x69, 0x8f, 0xb1, 0x92, 0x5b, 0x13, 0x93, 0xf0, +- 0xe1, 0x26, 0x6c, 0x5f, 0x96, 0xbc, 0xa2, 0x2c, 0x0d, 0xa2, 0x4d, 0xf5, +- 0x11, 0xfc, 0xda, 0xf4, 0xda, 0x3e, 0x0b, 0xba, 0x3b, 0xc9, 0x8a, 0xf5, +- 0x19, 0xd0, 0xfd, 0x61, 0x49, 0x1d, 0x5f, 0xd1, 0x35, 0x90, 0xbb, 0x40, +- 0xd7, 0xa4, 0xce, 0xdb, 0x52, 0x2d, 0xbb, 0xf2, 0x71, 0xea, 0x90, 0x32, +- 0xd7, 0x05, 0x1d, 0xc3, 0xf3, 0xdb, 0x32, 0xf4, 0x4c, 0x19, 0x3a, 0x05, +- 0x3a, 0xe4, 0x4b, 0x28, 0xff, 0x22, 0xea, 0x3c, 0x0f, 0x9f, 0xe7, 0x39, +- 0x60, 0xbf, 0x8b, 0xc0, 0x14, 0x17, 0xca, 0x59, 0xed, 0x1b, 0xaa, 0xf5, +- 0xc2, 0x66, 0x29, 0x7f, 0x45, 0xaa, 0x15, 0xd2, 0xe3, 0x27, 0x8a, 0xb7, +- 0x39, 0x6f, 0x2b, 0x71, 0x16, 0x66, 0x26, 0x52, 0xa9, 0x18, 0x9a, 0x50, +- 0xf7, 0x31, 0xf6, 0x6f, 0x74, 0x65, 0xeb, 0x3a, 0x5d, 0x29, 0xf2, 0x62, +- 0x2d, 0xc0, 0x93, 0xc4, 0xc7, 0xa5, 0x99, 0xe4, 0xca, 0x19, 0x59, 0x09, +- 0x76, 0xf3, 0x32, 0xfc, 0x92, 0x58, 0xe6, 0x5b, 0x12, 0x3b, 0xe5, 0xfb, +- 0xdf, 0x87, 0xdd, 0x2c, 0x82, 0x27, 0x56, 0x08, 0xe5, 0x8b, 0x7c, 0x47, +- 0xb9, 0xa7, 0x6c, 0x87, 0x18, 0x2b, 0x97, 0x97, 0x51, 0x56, 0x55, 0x3e, +- 0xd3, 0xb7, 0x31, 0x1f, 0x3d, 0x3f, 0x55, 0xc6, 0x7a, 0xcd, 0x92, 0x1f, +- 0x4f, 0xcb, 0xe3, 0xe5, 0x6d, 0x76, 0x33, 0xda, 0x57, 0x16, 0xd9, 0xc6, +- 0x19, 0xe4, 0x95, 0x9d, 0x97, 0x17, 0x59, 0xde, 0x25, 0x57, 0x66, 0x32, +- 0x6a, 0x0e, 0xd5, 0xb9, 0x8c, 0x04, 0x31, 0x49, 0xea, 0x2b, 0xce, 0x15, +- 0x79, 0xfa, 0x96, 0x65, 0xda, 0xd9, 0x88, 0x14, 0x13, 0xa4, 0x75, 0x42, +- 0x2e, 0xcf, 0xc4, 0x37, 0x31, 0x86, 0x93, 0x73, 0xf9, 0x6c, 0x62, 0x07, +- 0xf6, 0xfb, 0x88, 0x1d, 0x30, 0x5e, 0x10, 0x81, 0x2d, 0x53, 0x31, 0x04, +- 0xa4, 0xc9, 0x06, 0x9f, 0x95, 0xef, 0x03, 0x6c, 0xb4, 0x8a, 0x1f, 0x89, +- 0x27, 0xb9, 0x5e, 0xa7, 0xb8, 0x0c, 0xfd, 0xd1, 0x91, 0x79, 0x49, 0xee, +- 0x99, 0x0f, 0xd6, 0x67, 0x9d, 0x11, 0xde, 0xd3, 0x90, 0x6b, 0x73, 0x8e, +- 0x77, 0x15, 0x98, 0x22, 0x1f, 0xf7, 0xc0, 0xaf, 0x3f, 0x8b, 0x41, 0x7f, +- 0x0d, 0x66, 0xad, 0x3d, 0x9b, 0x02, 0x7c, 0x16, 0x91, 0xa9, 0x19, 0x9e, +- 0xa9, 0x41, 0xb7, 0x01, 0x43, 0xfe, 0xf3, 0x08, 0x9e, 0x6b, 0xcc, 0xc3, +- 0x4f, 0x0b, 0x7c, 0x50, 0x3c, 0x07, 0xfd, 0x91, 0xe6, 0xd6, 0x3c, 0xd7, +- 0x1e, 0x92, 0x7b, 0x80, 0x4e, 0x04, 0xfd, 0x77, 0xeb, 0xb1, 0xba, 0xcf, +- 0xa4, 0x19, 0xc3, 0x93, 0x14, 0xf4, 0x45, 0x6e, 0x2e, 0x82, 0xb1, 0xba, +- 0x34, 0x36, 0xe7, 0xbb, 0xf5, 0xd8, 0xd3, 0xf8, 0x78, 0x69, 0x79, 0xa2, +- 0x6c, 0xb0, 0x5e, 0x1a, 0x36, 0x56, 0x22, 0x23, 0x7d, 0xbe, 0x7c, 0xdf, +- 0x23, 0xbd, 0xfa, 0x91, 0xf7, 0xe4, 0x68, 0xfd, 0xdd, 0xce, 0xce, 0x1a, +- 0xff, 0x5a, 0x31, 0x47, 0xfe, 0x30, 0x3f, 0xe0, 0x23, 0xce, 0xdd, 0x82, +- 0x3d, 0x2f, 0x01, 0x77, 0x59, 0xe7, 0xba, 0xd4, 0x3b, 0x0b, 0xd8, 0xa0, +- 0x3a, 0x03, 0xdd, 0x78, 0x8e, 0xe7, 0x89, 0xd0, 0x6d, 0xe7, 0xa2, 0x52, +- 0x9a, 0xa5, 0x5c, 0x4a, 0x87, 0x05, 0x7e, 0xb1, 0x7e, 0x75, 0xa6, 0x0b, +- 0x69, 0x2b, 0xd2, 0xa4, 0xea, 0xa7, 0x3a, 0xe3, 0xaa, 0xf6, 0xd5, 0x99, +- 0xb4, 0x6a, 0x57, 0x9d, 0xe9, 0x47, 0xea, 0x49, 0xd3, 0x39, 0x38, 0x4e, +- 0xe7, 0x7a, 0x65, 0xea, 0x34, 0xec, 0xcb, 0x80, 0xa5, 0xce, 0xe2, 0x27, +- 0x60, 0x7f, 0x22, 0xf0, 0xb2, 0xae, 0xda, 0x83, 0xc0, 0x58, 0x3b, 0x81, +- 0x41, 0x76, 0x8a, 0x7b, 0x8a, 0xeb, 0xa7, 0xee, 0xbd, 0xcc, 0x78, 0x52, +- 0xe2, 0x41, 0xc9, 0xca, 0x81, 0xd9, 0x66, 0xec, 0xd7, 0x88, 0x5d, 0x92, +- 0x1e, 0x7b, 0x18, 0xf9, 0x42, 0x85, 0x74, 0xbb, 0x4f, 0xf9, 0x6e, 0x39, +- 0xef, 0x1c, 0x78, 0x92, 0xc1, 0x18, 0xef, 0xa7, 0x7d, 0x1f, 0xe4, 0xcf, +- 0xd5, 0x7d, 0x64, 0x30, 0x9f, 0x46, 0x7a, 0xf0, 0x1c, 0x31, 0xfb, 0x73, +- 0xce, 0x11, 0x29, 0xd7, 0xa4, 0xef, 0x7d, 0x72, 0xd9, 0xcd, 0xc8, 0xcb, +- 0x6e, 0x5a, 0xae, 0xb8, 0x3b, 0xe4, 0xeb, 0xb0, 0xd3, 0x2f, 0xb9, 0x7d, +- 0x9b, 0x88, 0x05, 0xaa, 0xea, 0x6c, 0xc6, 0xf0, 0xca, 0xd5, 0xf1, 0xc4, +- 0x1f, 0xc8, 0xd2, 0x0c, 0xb1, 0xb3, 0xbf, 0x7b, 0xbf, 0x57, 0xa4, 0xdd, +- 0xc2, 0x1c, 0x88, 0xd5, 0x8a, 0xb0, 0x7f, 0x87, 0x65, 0xd8, 0xa3, 0xdd, +- 0x53, 0x36, 0x2a, 0x31, 0x1c, 0xec, 0x67, 0xaf, 0x00, 0xbd, 0x7a, 0x79, +- 0x16, 0xfb, 0x49, 0x28, 0xff, 0x78, 0xae, 0x90, 0xef, 0xae, 0x3c, 0x59, +- 0xe6, 0x3a, 0x4b, 0xd7, 0xb5, 0x48, 0x58, 0x46, 0x14, 0x5e, 0x68, 0x93, +- 0x17, 0x17, 0x37, 0x8b, 0x05, 0x0b, 0x65, 0xdd, 0x12, 0x55, 0xb7, 0x18, +- 0xe8, 0x7f, 0x4b, 0x3b, 0xef, 0x22, 0xbd, 0x05, 0xda, 0x30, 0x16, 0x80, +- 0xb5, 0xb5, 0x73, 0x25, 0x26, 0xdf, 0x8f, 0xfd, 0xf5, 0x96, 0xda, 0x6b, +- 0x79, 0x37, 0x8e, 0x67, 0xa6, 0xdc, 0x73, 0x8c, 0x3b, 0x85, 0x75, 0xfc, +- 0xf7, 0xaf, 0xd4, 0xfb, 0x66, 0x77, 0x17, 0x70, 0x1d, 0xe5, 0x15, 0xe9, +- 0x52, 0x30, 0x6e, 0x1e, 0x38, 0xae, 0xd0, 0xcf, 0x3b, 0x14, 0x4e, 0xba, +- 0x88, 0xbd, 0x30, 0xa1, 0xea, 0xef, 0xc4, 0x7e, 0xda, 0xd4, 0x42, 0xfc, +- 0xb0, 0x07, 0xb2, 0xf8, 0xd2, 0x0c, 0x9f, 0xf9, 0x9e, 0xfe, 0x15, 0xe3, +- 0x6b, 0x17, 0x46, 0xa7, 0xdd, 0xdf, 0xd2, 0xfb, 0x47, 0x42, 0x77, 0xf5, +- 0x01, 0x87, 0x1e, 0x6b, 0xc2, 0x5a, 0x9c, 0x64, 0x32, 0x64, 0x75, 0x5a, +- 0xc0, 0xf1, 0xc3, 0xca, 0xe6, 0xf6, 0x61, 0xfe, 0x69, 0x39, 0x93, 0x6e, +- 0x93, 0xaa, 0xed, 0xaa, 0x3b, 0x57, 0xcb, 0xf6, 0x76, 0x62, 0x7d, 0xfc, +- 0x36, 0xa1, 0xac, 0x07, 0x69, 0x33, 0xd2, 0xdb, 0xa4, 0x74, 0xb2, 0xaf, +- 0x25, 0xe8, 0x2f, 0xba, 0x2e, 0xff, 0x75, 0x3d, 0xce, 0x5f, 0x6a, 0x7f, +- 0x8a, 0xe3, 0x44, 0xc5, 0xfd, 0x7c, 0xab, 0xf4, 0x1c, 0xb3, 0x81, 0x6d, +- 0x13, 0xc0, 0xba, 0x5d, 0x92, 0x3e, 0x96, 0x94, 0x5b, 0x8e, 0x99, 0x38, +- 0xd1, 0x97, 0x47, 0x53, 0x2a, 0x66, 0xf8, 0xa5, 0x51, 0xb7, 0xa2, 0xce, +- 0x53, 0xf5, 0xdd, 0xb0, 0x65, 0x7d, 0x67, 0xec, 0x1b, 0xa3, 0x7d, 0x2a, +- 0xfd, 0xf6, 0x68, 0x5a, 0xa5, 0xaf, 0x8c, 0xde, 0x52, 0x0b, 0xfc, 0xa3, +- 0xd2, 0x42, 0x5a, 0x3e, 0x57, 0x26, 0xbe, 0x1c, 0x00, 0x76, 0xf4, 0xa0, +- 0x67, 0xfa, 0xa1, 0x67, 0xd2, 0xd0, 0x33, 0x83, 0xd4, 0x33, 0xd0, 0xdb, +- 0xaf, 0x40, 0x6f, 0x7b, 0xf2, 0x06, 0xe4, 0xf5, 0x82, 0xd7, 0x0c, 0x5c, +- 0xe8, 0xfb, 0xc1, 0x5a, 0x9d, 0xa7, 0x96, 0xc1, 0xdf, 0xea, 0x59, 0x89, +- 0xb5, 0x43, 0x07, 0x6d, 0x9f, 0x6f, 0x92, 0x85, 0xb8, 0xef, 0x9f, 0xf0, +- 0x5c, 0xb9, 0x86, 0xfa, 0x39, 0x97, 0xfb, 0x78, 0xa2, 0x85, 0xfe, 0xd8, +- 0xb5, 0x99, 0x1d, 0xd0, 0x49, 0x94, 0xf7, 0x98, 0x54, 0xc7, 0x13, 0xb2, +- 0x08, 0xff, 0x6c, 0xb5, 0x4e, 0x1a, 0xcf, 0xdc, 0xff, 0xff, 0x12, 0x75, +- 0xd3, 0xb0, 0x0f, 0xb6, 0x2c, 0xf5, 0x25, 0xe5, 0x4c, 0x9f, 0x33, 0x98, +- 0xb4, 0xa8, 0xbb, 0x92, 0x52, 0x81, 0xaf, 0x5f, 0x2d, 0xb3, 0x3e, 0xeb, +- 0x61, 0x7f, 0x96, 0x83, 0x76, 0xd3, 0x65, 0xa3, 0x27, 0x20, 0x9f, 0x73, +- 0x8c, 0x03, 0x06, 0x36, 0xc0, 0xb2, 0x9a, 0x21, 0x07, 0x1e, 0xe8, 0x3f, +- 0x8e, 0xf2, 0x01, 0xde, 0x25, 0x40, 0x19, 0xb1, 0x50, 0x49, 0xf1, 0x38, +- 0xef, 0x8d, 0xa3, 0x8c, 0x6d, 0x9c, 0x44, 0x0a, 0xe5, 0x63, 0x92, 0x4a, +- 0x14, 0xd4, 0xbd, 0xa6, 0x4e, 0x94, 0xb1, 0x8f, 0xb0, 0x8e, 0xc7, 0xcc, +- 0xb6, 0x50, 0x8e, 0xc2, 0xae, 0x29, 0xdf, 0xa6, 0x62, 0x03, 0x59, 0xdb, +- 0xc3, 0x7e, 0x60, 0x59, 0xca, 0x66, 0xbb, 0xbc, 0xe7, 0x29, 0x5d, 0x78, +- 0xaf, 0x3e, 0xb7, 0xb8, 0xa7, 0xd6, 0x2a, 0xf9, 0x5a, 0xd3, 0x7b, 0xe8, +- 0x7f, 0xb3, 0x27, 0x2f, 0x27, 0x6c, 0xe1, 0x19, 0x7b, 0xb0, 0xcf, 0x23, +- 0x3b, 0xb8, 0x27, 0x40, 0x77, 0xd8, 0xdf, 0xe7, 0xb1, 0xde, 0xe7, 0x60, +- 0x7f, 0x2f, 0xc2, 0xfe, 0x5e, 0x28, 0xaf, 0xea, 0x8f, 0xc0, 0xee, 0x52, +- 0x07, 0x3c, 0x03, 0x9e, 0x8d, 0x01, 0xf7, 0xef, 0x85, 0x3f, 0x30, 0x02, +- 0xec, 0x3f, 0x04, 0xfe, 0x65, 0xc0, 0xbb, 0x71, 0xde, 0x45, 0x01, 0x1f, +- 0x07, 0xd5, 0x59, 0xe6, 0xac, 0x3a, 0xcf, 0xff, 0x81, 0xb2, 0xbd, 0x8f, +- 0x97, 0x2d, 0xd8, 0x87, 0xa2, 0x7f, 0x9d, 0xeb, 0x00, 0xff, 0xad, 0xec, +- 0xe7, 0xc1, 0x17, 0xa1, 0x57, 0x7e, 0x8c, 0x79, 0x3d, 0x37, 0x4b, 0x7b, +- 0x8e, 0x3a, 0x01, 0xde, 0xf6, 0x18, 0xeb, 0xc2, 0x7e, 0x3e, 0x7a, 0x59, +- 0x96, 0x81, 0x3b, 0xb2, 0x94, 0x63, 0xf8, 0x0f, 0xce, 0x85, 0x8a, 0xf4, +- 0x52, 0x07, 0x02, 0x13, 0x0d, 0xca, 0xc0, 0xf1, 0x04, 0xb0, 0x1e, 0x90, +- 0xbc, 0x3a, 0xaf, 0xc3, 0xf3, 0xf9, 0x2d, 0x62, 0x11, 0xef, 0x79, 0x3c, +- 0x9b, 0xa1, 0xde, 0x30, 0x18, 0x69, 0x79, 0xb0, 0x43, 0xb2, 0xdb, 0x3b, +- 0x94, 0xee, 0x70, 0xbc, 0x97, 0x31, 0xee, 0x1e, 0xb8, 0x20, 0x6f, 0x00, +- 0x21, 0x58, 0x99, 0x43, 0xf2, 0xbf, 0x3c, 0xc6, 0xa8, 0x02, 0xdf, 0x0f, +- 0x73, 0x89, 0x81, 0x66, 0x9b, 0xf6, 0xbb, 0x76, 0x6c, 0x4f, 0x9d, 0xfd, +- 0xc7, 0x14, 0xc6, 0xca, 0x0b, 0xfb, 0x87, 0x9d, 0xc0, 0x98, 0xa9, 0xe3, +- 0x94, 0xfd, 0x6d, 0xe0, 0xdb, 0x3f, 0x05, 0x06, 0x22, 0x55, 0x87, 0x36, +- 0x07, 0xfb, 0x85, 0xf3, 0x5f, 0x26, 0x9e, 0x60, 0x4c, 0x3d, 0xf0, 0xcb, +- 0x57, 0xe6, 0xb6, 0x13, 0xf6, 0xeb, 0xb6, 0xcd, 0x94, 0x81, 0x71, 0x0f, +- 0x7e, 0xdf, 0xf1, 0xc0, 0x5e, 0x77, 0x9f, 0x47, 0xab, 0x13, 0xd2, 0xc9, +- 0xd3, 0x4e, 0x4b, 0x6e, 0x91, 0x8f, 0x44, 0x82, 0x7e, 0xac, 0x79, 0x1b, +- 0xb2, 0x4a, 0x3d, 0xd0, 0x09, 0x39, 0x67, 0x9e, 0x3a, 0x85, 0x3a, 0x81, +- 0xb2, 0xe0, 0x4a, 0xa9, 0x0e, 0x9d, 0xd0, 0xd6, 0x25, 0x15, 0xd2, 0x6c, +- 0x9e, 0x7a, 0xe2, 0x07, 0x32, 0xbd, 0x4e, 0x57, 0x0e, 0x89, 0xf1, 0x6b, +- 0x5b, 0x25, 0x9a, 0x71, 0xed, 0x7b, 0xd5, 0x1a, 0x03, 0x7d, 0x79, 0x80, +- 0xf8, 0x73, 0x36, 0xeb, 0x74, 0x88, 0xc6, 0x9e, 0x0a, 0x3f, 0xbd, 0x89, +- 0xb5, 0xb2, 0x0f, 0x45, 0xa7, 0xc1, 0xa1, 0xc0, 0x17, 0x50, 0x31, 0x3f, +- 0xe0, 0xe0, 0xc4, 0x8f, 0xa1, 0x6b, 0xf3, 0xc4, 0x25, 0xa0, 0x73, 0xf7, +- 0x09, 0xca, 0xd1, 0x75, 0xea, 0x6c, 0xbc, 0x62, 0xa5, 0xa9, 0xaf, 0x65, +- 0xf1, 0x38, 0x30, 0x97, 0xb5, 0x4b, 0x0a, 0x94, 0x57, 0x9e, 0x7d, 0x2f, +- 0x5a, 0x32, 0x3d, 0xd7, 0x26, 0x3d, 0xf3, 0x8c, 0xaf, 0xee, 0x6e, 0x91, +- 0x36, 0xc6, 0x58, 0x69, 0x83, 0x06, 0x24, 0x8f, 0xf2, 0xee, 0xf9, 0xb0, +- 0x8a, 0x87, 0x55, 0x2c, 0xd2, 0xa8, 0x1f, 0xfa, 0xc0, 0x49, 0x2f, 0x5b, +- 0xff, 0x25, 0x16, 0x60, 0x48, 0xc8, 0x52, 0x19, 0x32, 0x56, 0x86, 0x8c, +- 0x95, 0x21, 0x63, 0x65, 0xc8, 0x18, 0xb0, 0xdf, 0x73, 0xd8, 0x7f, 0x17, +- 0xcb, 0x83, 0xda, 0xae, 0xdf, 0xaf, 0xec, 0xfa, 0x91, 0x32, 0xcf, 0xf0, +- 0xe9, 0x83, 0x26, 0x95, 0x0e, 0xb9, 0xa4, 0x7c, 0x51, 0xe3, 0xa3, 0xbe, +- 0x22, 0xcf, 0xcc, 0xbe, 0x2a, 0x67, 0x66, 0x57, 0x71, 0xe0, 0x54, 0xd9, +- 0x97, 0x97, 0x3d, 0xf8, 0x9f, 0x0b, 0xc4, 0x54, 0xd9, 0xf6, 0x66, 0x85, +- 0xad, 0x0e, 0x4b, 0x41, 0xe1, 0x64, 0x65, 0x47, 0x80, 0xaf, 0x14, 0x2e, +- 0xe4, 0xde, 0x94, 0x8e, 0xed, 0xaf, 0xc9, 0x45, 0xd8, 0xf1, 0xc5, 0xfa, +- 0xeb, 0xf2, 0xbc, 0xc2, 0xe3, 0xa4, 0xc3, 0x07, 0xe4, 0x47, 0x76, 0x70, +- 0x4e, 0x7c, 0x06, 0x58, 0x63, 0xb1, 0x8f, 0xba, 0x23, 0x02, 0x5b, 0xe0, +- 0x14, 0xbb, 0xb1, 0xaf, 0x0f, 0x5a, 0x37, 0x00, 0xd3, 0xf0, 0xfd, 0x16, +- 0x79, 0x71, 0xb6, 0xd8, 0x20, 0x13, 0xd4, 0x0f, 0xce, 0x51, 0xb1, 0x68, +- 0xa7, 0x68, 0x37, 0xb9, 0x5e, 0xda, 0xa9, 0x3f, 0xd8, 0xcc, 0xb3, 0xd4, +- 0xea, 0xc9, 0x73, 0x2d, 0x8c, 0x37, 0xc6, 0x5d, 0xd2, 0xf4, 0x35, 0x39, +- 0x58, 0x63, 0xd9, 0xab, 0xe0, 0x0f, 0xd3, 0xef, 0xf9, 0xf7, 0xc4, 0x39, +- 0x1e, 0xfb, 0x05, 0x6e, 0xea, 0xc4, 0x5a, 0xcb, 0x7f, 0xa9, 0x63, 0x5e, +- 0xfd, 0x0a, 0x47, 0xbf, 0x13, 0x2f, 0x9b, 0x7b, 0x0d, 0xaf, 0xa9, 0x78, +- 0xe0, 0x06, 0x71, 0xe2, 0xa7, 0xb0, 0xaf, 0x8a, 0x57, 0x85, 0x31, 0x4b, +- 0xc6, 0x73, 0x19, 0x2b, 0x6e, 0xd4, 0x18, 0xea, 0xbc, 0x54, 0xee, 0x86, +- 0x7e, 0xb9, 0x07, 0xfa, 0xe5, 0xde, 0x77, 0xdc, 0xaf, 0x35, 0x71, 0xfb, +- 0x9e, 0x62, 0xd8, 0xea, 0x92, 0xb1, 0x5a, 0x63, 0x5b, 0xc6, 0x71, 0x37, +- 0x8a, 0xdb, 0x32, 0xa6, 0x9b, 0x5e, 0x17, 0x0b, 0xa4, 0x6c, 0xf8, 0xf2, +- 0x92, 0xc7, 0xb8, 0x9b, 0xb9, 0x9b, 0xbd, 0x11, 0xfe, 0xfa, 0xc3, 0xcd, +- 0x26, 0xe6, 0x1c, 0xc9, 0x5c, 0x15, 0xde, 0xd1, 0x2e, 0xcd, 0x10, 0x0f, +- 0xa8, 0xb3, 0x40, 0x15, 0xbb, 0xce, 0x07, 0xf1, 0x03, 0x94, 0xc3, 0xea, +- 0xc2, 0xdf, 0x61, 0xec, 0xda, 0xde, 0xe1, 0xd8, 0x63, 0xe1, 0xe0, 0xae, +- 0x1f, 0xf7, 0x72, 0xa0, 0xcb, 0x20, 0x8b, 0xf5, 0xd5, 0x3b, 0x74, 0x43, +- 0x4a, 0x5f, 0x5c, 0xc5, 0x1e, 0x20, 0xbf, 0xe0, 0x2f, 0x60, 0x9f, 0x4c, +- 0x41, 0x3f, 0x15, 0x54, 0x7f, 0x31, 0xca, 0x45, 0x36, 0x17, 0xb6, 0x24, +- 0x7a, 0x8a, 0xbe, 0x50, 0x10, 0x6b, 0xc9, 0x87, 0x1d, 0xa5, 0xbf, 0x31, +- 0x77, 0xe0, 0x33, 0xee, 0xcf, 0xe4, 0x44, 0x73, 0xa6, 0x09, 0x76, 0x15, +- 0xfc, 0xab, 0x33, 0x26, 0x80, 0xbd, 0xbb, 0xf4, 0x5d, 0x39, 0x30, 0x77, +- 0x69, 0x73, 0x20, 0xff, 0x8c, 0x23, 0x73, 0x7d, 0x66, 0x0e, 0x6b, 0xfb, +- 0xb6, 0x4e, 0x49, 0xac, 0x05, 0x36, 0xed, 0xa3, 0xa7, 0x88, 0x07, 0x9a, +- 0x65, 0x39, 0xce, 0x7e, 0x83, 0x3d, 0x33, 0x5d, 0x66, 0xdf, 0xdf, 0x95, +- 0xe1, 0xb9, 0x74, 0x2b, 0xf5, 0xc8, 0x12, 0xf4, 0xc0, 0x65, 0x9b, 0x36, +- 0x74, 0x1c, 0x36, 0xae, 0x53, 0xde, 0x9c, 0xa3, 0x7d, 0x4c, 0xd9, 0x67, +- 0x64, 0x5b, 0xe2, 0x0c, 0xe6, 0xf4, 0x84, 0x17, 0xa1, 0x8f, 0xe6, 0x0f, +- 0xa1, 0xec, 0xeb, 0x92, 0xb2, 0xbb, 0x43, 0x7c, 0xde, 0x66, 0x3f, 0x29, +- 0xbc, 0x6f, 0x90, 0xb2, 0x6f, 0x0d, 0x51, 0x8e, 0xe0, 0x73, 0x2f, 0xad, +- 0xce, 0xf3, 0x7b, 0x73, 0xca, 0x4f, 0x52, 0x7a, 0x66, 0xc9, 0xe3, 0x78, +- 0x97, 0xb4, 0x6e, 0xbb, 0x15, 0xfa, 0x24, 0xa6, 0xcf, 0xc2, 0xd0, 0x86, +- 0xd8, 0xc6, 0x8b, 0xe8, 0xfc, 0x67, 0x25, 0x77, 0x3a, 0x0e, 0x7d, 0xc6, +- 0xbe, 0x8c, 0xef, 0x40, 0x1b, 0x69, 0xf0, 0x36, 0xed, 0xdd, 0x2e, 0xd8, +- 0xbd, 0x9b, 0xd4, 0x7c, 0x46, 0xbc, 0x7e, 0x99, 0x3a, 0xc9, 0xb1, 0xfb, +- 0xa0, 0xcb, 0x13, 0x4a, 0x6e, 0x4b, 0xe5, 0xcb, 0x89, 0x18, 0x74, 0x72, +- 0x6c, 0x3b, 0xe9, 0xf9, 0x61, 0xb9, 0xd3, 0x1d, 0x97, 0xbb, 0x20, 0x3b, +- 0x43, 0xae, 0x27, 0xc3, 0xe0, 0xc5, 0x1e, 0x17, 0x76, 0x47, 0x61, 0xe8, +- 0x66, 0xf8, 0x5d, 0x1c, 0x9b, 0xf7, 0xc4, 0xd9, 0x36, 0xc0, 0x8f, 0x7f, +- 0x54, 0x0f, 0x68, 0x94, 0x9b, 0xfb, 0x88, 0xa2, 0xcd, 0x88, 0xb7, 0x53, +- 0xdb, 0xd9, 0x36, 0xc9, 0xab, 0x7a, 0x3b, 0x95, 0x3d, 0x2e, 0x2d, 0xde, +- 0x87, 0x14, 0xb6, 0x79, 0x11, 0xfa, 0x06, 0x98, 0xbb, 0x54, 0xdb, 0x81, +- 0x3c, 0x6c, 0xe8, 0x62, 0x06, 0xe9, 0x87, 0x91, 0xb2, 0x6e, 0xa8, 0x35, +- 0x88, 0xe5, 0x1a, 0x3c, 0xba, 0x7a, 0xbf, 0xf0, 0xa3, 0x0a, 0x97, 0x5e, +- 0x55, 0xf7, 0xcb, 0x2c, 0x60, 0x9d, 0x1c, 0xf4, 0x4a, 0x2b, 0x30, 0xd0, +- 0xcc, 0x29, 0x27, 0x3d, 0x1c, 0xda, 0x2d, 0xbf, 0x06, 0x5f, 0xbe, 0xea, +- 0x91, 0x97, 0x3b, 0xe4, 0xc1, 0x3b, 0x28, 0x23, 0xbb, 0x65, 0xff, 0x1d, +- 0x21, 0xd9, 0xdf, 0xef, 0x64, 0x39, 0xef, 0x5b, 0x6e, 0x33, 0xfe, 0x74, +- 0xcf, 0x48, 0x2a, 0x34, 0x20, 0x4f, 0x42, 0xc6, 0x8a, 0x90, 0xaf, 0xe1, +- 0x3a, 0x69, 0x4e, 0x7d, 0x4f, 0x3d, 0x9f, 0x06, 0x56, 0x36, 0xd8, 0xcf, +- 0x95, 0x99, 0x7a, 0x93, 0x24, 0xaf, 0x67, 0x3c, 0x39, 0x19, 0x9c, 0x71, +- 0x5c, 0x4f, 0x99, 0x80, 0x0f, 0x72, 0x7d, 0xb0, 0x3f, 0xd5, 0xbd, 0x2e, +- 0xf5, 0x1c, 0xa7, 0xff, 0xeb, 0x13, 0xe7, 0x15, 0x14, 0x5f, 0x68, 0x23, +- 0x98, 0xfe, 0xbb, 0xd6, 0x15, 0x7c, 0xd7, 0x46, 0xff, 0x61, 0x67, 0xeb, +- 0xea, 0xbd, 0xf4, 0xf5, 0xb2, 0x68, 0xe2, 0x6e, 0x15, 0xac, 0x99, 0x36, +- 0xdd, 0xb1, 0xa9, 0x0b, 0xdb, 0xdd, 0xfb, 0xe5, 0x4f, 0x60, 0xdf, 0xbf, +- 0xb2, 0x62, 0xdf, 0xf7, 0x81, 0x1e, 0xeb, 0x31, 0x80, 0x6b, 0xdf, 0x8d, +- 0xb5, 0x8c, 0x80, 0x9f, 0x77, 0xe1, 0x77, 0x67, 0x79, 0x4d, 0x1c, 0x6f, +- 0xb6, 0x08, 0x3c, 0xd9, 0xe4, 0xb2, 0xbf, 0x35, 0xf1, 0xbc, 0x62, 0x41, +- 0x56, 0x62, 0x85, 0x83, 0xd7, 0x84, 0x76, 0xef, 0x2d, 0x89, 0xf6, 0xba, +- 0x6f, 0x75, 0x87, 0xdc, 0x17, 0xac, 0x10, 0xcf, 0x95, 0x3d, 0x39, 0x5b, +- 0x27, 0x0e, 0xbb, 0x22, 0xd6, 0x79, 0x62, 0xb0, 0x6f, 0xa8, 0x18, 0x54, +- 0xb5, 0xfc, 0x6d, 0xa4, 0xa8, 0x0f, 0xfd, 0x18, 0x0e, 0xe2, 0x14, 0x0a, +- 0xab, 0x50, 0xcf, 0xde, 0x05, 0x3e, 0x4c, 0xe1, 0xd7, 0xbd, 0xfd, 0x56, +- 0xec, 0x5f, 0xca, 0x29, 0x63, 0x5f, 0xbd, 0xf6, 0xf6, 0x10, 0xdf, 0x6d, +- 0x14, 0x07, 0xfb, 0x8e, 0x44, 0x4e, 0xc0, 0xd6, 0x59, 0xd4, 0x0f, 0x5c, +- 0x07, 0xed, 0xa4, 0x2d, 0x0b, 0x27, 0xb9, 0xd7, 0x37, 0xaa, 0x6f, 0xea, +- 0x9a, 0xb5, 0x28, 0xbb, 0x91, 0x2d, 0x30, 0xc6, 0x59, 0x26, 0x0f, 0x3c, +- 0xf0, 0xc0, 0x97, 0x53, 0x5e, 0x3b, 0xf4, 0x76, 0x5c, 0xc2, 0xa7, 0x7c, +- 0x19, 0x52, 0xd8, 0x75, 0x1b, 0x30, 0xd7, 0x16, 0x8d, 0x1b, 0xe2, 0x12, +- 0x39, 0xd5, 0x25, 0xcd, 0xc0, 0xd5, 0x4d, 0xc7, 0x68, 0x23, 0x53, 0xc9, +- 0x21, 0x08, 0x41, 0x44, 0xdd, 0x55, 0x74, 0x06, 0xdf, 0x94, 0x6d, 0xc9, +- 0x37, 0x85, 0x78, 0xe9, 0x86, 0x2d, 0xf0, 0x09, 0xbc, 0x2b, 0x1b, 0xd4, +- 0x2f, 0xad, 0xd6, 0x87, 0x1c, 0x31, 0xb6, 0xc6, 0x36, 0x8c, 0xb5, 0xa5, +- 0x06, 0xdf, 0x60, 0x8c, 0x0d, 0xbe, 0x66, 0xd3, 0xb9, 0x60, 0x0e, 0xd6, +- 0x52, 0x87, 0x54, 0x4f, 0x73, 0x8f, 0x32, 0xce, 0x62, 0x07, 0x7e, 0x6a, +- 0x99, 0xfe, 0x2a, 0xdf, 0x27, 0xf5, 0xfb, 0x6e, 0xfd, 0x9e, 0xfe, 0x68, +- 0xd1, 0x6f, 0x02, 0x4d, 0xf7, 0x40, 0x7f, 0xde, 0xb7, 0xc3, 0x55, 0xb8, +- 0xe1, 0xbe, 0x15, 0x9e, 0xed, 0x15, 0xeb, 0x38, 0xfc, 0xd4, 0xf2, 0x61, +- 0x71, 0xb7, 0x2f, 0xa7, 0x23, 0x32, 0x06, 0x5e, 0x30, 0x9f, 0xe5, 0x7c, +- 0xd2, 0x47, 0xe4, 0xa0, 0xe2, 0x4d, 0xf5, 0xa4, 0x73, 0x34, 0x19, 0x9a, +- 0x12, 0xab, 0xca, 0xe7, 0x47, 0x90, 0x1e, 0x01, 0xde, 0x09, 0x62, 0x97, +- 0x56, 0x75, 0x2d, 0x2d, 0x81, 0x31, 0xec, 0x3d, 0x6b, 0xe2, 0x58, 0xab, +- 0x31, 0x2e, 0xbe, 0x1f, 0x52, 0xef, 0xd3, 0x6b, 0xe2, 0x5c, 0x79, 0x8b, +- 0x58, 0xc6, 0xbc, 0x27, 0x2f, 0xc8, 0x2f, 0xd8, 0xe2, 0x93, 0x26, 0xe6, +- 0xd5, 0xa6, 0xf9, 0x42, 0xfe, 0xcc, 0xc8, 0x45, 0xdb, 0x19, 0xa1, 0xfc, +- 0xfd, 0xea, 0x8e, 0x1b, 0x65, 0xa2, 0x93, 0xf1, 0xb6, 0xc6, 0x39, 0xac, +- 0x8f, 0xa3, 0x35, 0x8e, 0xbf, 0x3e, 0xfe, 0xc6, 0xb1, 0x83, 0x18, 0x5b, +- 0x6e, 0x4d, 0x8c, 0xad, 0x71, 0x3c, 0x8e, 0xb5, 0x05, 0xfe, 0x53, 0xd1, +- 0x8f, 0xbb, 0xe4, 0x51, 0x4f, 0x72, 0x8e, 0xf9, 0x2f, 0x58, 0xe0, 0x63, +- 0x1c, 0x76, 0x84, 0xbc, 0x34, 0x67, 0xcf, 0xe4, 0x69, 0x2a, 0x79, 0x24, +- 0xe0, 0xe7, 0x60, 0xc0, 0xf7, 0x80, 0xff, 0x57, 0x56, 0xf8, 0x48, 0xfb, +- 0x40, 0x3e, 0x76, 0x8a, 0x40, 0xcf, 0x5a, 0xc7, 0xc8, 0x43, 0xa6, 0xe4, +- 0x21, 0xdf, 0x91, 0x87, 0xdd, 0xfa, 0x1d, 0xf9, 0x07, 0x9c, 0xf6, 0x79, +- 0x60, 0x0c, 0x2f, 0xa7, 0xbe, 0xb1, 0xe9, 0xee, 0x35, 0x7b, 0x31, 0x2d, +- 0xcf, 0x2f, 0xb4, 0x88, 0x9d, 0x09, 0xd6, 0x35, 0xbe, 0x26, 0xde, 0xce, +- 0xf3, 0xab, 0x7e, 0x62, 0x4f, 0xb3, 0xae, 0x04, 0xd7, 0x75, 0x50, 0x5e, +- 0x93, 0xc2, 0x4c, 0x04, 0x3e, 0x60, 0x1a, 0x38, 0xa7, 0x1f, 0xfa, 0x96, +- 0xf1, 0x51, 0x94, 0xd5, 0x88, 0x57, 0x68, 0xeb, 0xd2, 0xd8, 0x2b, 0xd4, +- 0xc1, 0xc4, 0x23, 0xaf, 0x4a, 0xbe, 0x62, 0x74, 0x0c, 0xfa, 0xb7, 0x4c, +- 0xff, 0xa4, 0x73, 0xf6, 0x96, 0xeb, 0x64, 0x39, 0x79, 0x9d, 0x38, 0xc9, +- 0x45, 0x59, 0xe5, 0xeb, 0xf8, 0xc6, 0x74, 0xf7, 0xee, 0x0b, 0xaf, 0xca, +- 0xc6, 0xf8, 0x06, 0xbc, 0x9f, 0x14, 0xf3, 0xde, 0xf0, 0x7e, 0x43, 0x3e, +- 0x14, 0x5f, 0x11, 0xf2, 0x82, 0x34, 0x20, 0x1e, 0x8e, 0xca, 0xef, 0xc6, +- 0xb9, 0x1f, 0x8b, 0xea, 0x7c, 0x33, 0x65, 0xf5, 0x2a, 0x9d, 0x31, 0xe4, +- 0x05, 0xf2, 0x5a, 0xc4, 0x38, 0xb1, 0x9e, 0xdf, 0xf3, 0x87, 0xe2, 0xf0, +- 0x73, 0x7b, 0xa8, 0x5f, 0xcc, 0x9e, 0x6e, 0x51, 0x7b, 0xfa, 0x09, 0x2f, +- 0x24, 0x25, 0x37, 0x24, 0x53, 0xee, 0x61, 0x85, 0xf1, 0x7f, 0x03, 0x7d, +- 0x3d, 0xa8, 0xfb, 0x9a, 0x92, 0x5e, 0xad, 0x7f, 0x0e, 0x41, 0xce, 0x7d, +- 0xb9, 0xd7, 0xdb, 0x21, 0xbf, 0xda, 0xce, 0x3d, 0x60, 0xd6, 0x7f, 0x58, +- 0x7a, 0x76, 0x2c, 0x27, 0xe1, 0x19, 0xdc, 0x12, 0x5d, 0xa1, 0x01, 0xf7, +- 0x99, 0x91, 0xef, 0x80, 0x0e, 0xc1, 0xfa, 0xd7, 0xac, 0x55, 0xaf, 0x93, +- 0x6b, 0x66, 0x3d, 0xae, 0x35, 0xc0, 0xf2, 0xab, 0x6b, 0x35, 0xf5, 0x5b, +- 0x21, 0x4b, 0x4e, 0x52, 0x42, 0x8d, 0xb4, 0x59, 0xd1, 0x51, 0x23, 0x8c, +- 0x91, 0x2c, 0xdb, 0x4e, 0x3a, 0x19, 0x32, 0xb1, 0xe8, 0x00, 0xeb, 0x76, +- 0x03, 0x87, 0xbb, 0xbd, 0xbd, 0xe9, 0x82, 0x8a, 0x91, 0x5a, 0x6a, 0x5d, +- 0x53, 0xc0, 0x64, 0x0b, 0xde, 0x2b, 0xfe, 0xa7, 0x81, 0x59, 0x27, 0xe4, +- 0x61, 0x09, 0xaf, 0x89, 0xe5, 0x22, 0x7f, 0x9e, 0xf1, 0x5c, 0x27, 0x99, +- 0x05, 0x8f, 0x7f, 0x13, 0x3e, 0x7c, 0x15, 0x7a, 0xff, 0xe3, 0xb4, 0x0d, +- 0x65, 0xd8, 0x0b, 0xe0, 0x92, 0xaf, 0xbc, 0x27, 0x86, 0x9f, 0x68, 0x88, +- 0xe5, 0x06, 0xf8, 0xf4, 0xa2, 0xc2, 0xa4, 0xc4, 0xed, 0x47, 0x43, 0x77, +- 0xf7, 0x85, 0xe1, 0x67, 0x14, 0xfd, 0x98, 0x4b, 0x1c, 0x77, 0x58, 0xee, +- 0x04, 0x7f, 0xce, 0x2e, 0x14, 0x43, 0x7b, 0xca, 0x46, 0x56, 0xe1, 0x57, +- 0xd6, 0x9d, 0xf4, 0x65, 0xd0, 0xe3, 0x19, 0x8d, 0xf9, 0x78, 0x5e, 0x53, +- 0xd5, 0x3e, 0x0b, 0x63, 0x43, 0xa5, 0xfa, 0x61, 0x99, 0xf6, 0x18, 0xdb, +- 0xe9, 0x91, 0x52, 0x3c, 0x7b, 0x63, 0xf3, 0x0a, 0x8d, 0x1c, 0x1b, 0x3e, +- 0x5f, 0x9a, 0xfa, 0xbb, 0xaa, 0xcf, 0x3b, 0x9e, 0x51, 0xf2, 0x65, 0xe2, +- 0xc2, 0xf4, 0x8f, 0x78, 0x5e, 0xd5, 0x63, 0x8f, 0xf0, 0xb9, 0x42, 0x19, +- 0x50, 0x3e, 0x13, 0x68, 0xf9, 0x90, 0x64, 0xc7, 0x92, 0x0a, 0xb7, 0x3c, +- 0x5e, 0xe6, 0x7e, 0x21, 0xfe, 0x7f, 0x0d, 0xd8, 0x3f, 0x02, 0x9e, 0xd1, +- 0x0f, 0xe0, 0xd8, 0xdc, 0x17, 0x28, 0xab, 0xd9, 0xef, 0xb2, 0x2f, 0x5e, +- 0x6b, 0x23, 0xc6, 0xb8, 0x54, 0x16, 0x45, 0xbf, 0x65, 0x31, 0xb1, 0x73, +- 0x85, 0x05, 0x8b, 0xb9, 0x70, 0x48, 0x52, 0x27, 0xfe, 0x35, 0x64, 0xe8, +- 0xd7, 0xe1, 0x23, 0xa9, 0x7a, 0xea, 0xfc, 0x6a, 0x08, 0x98, 0xcb, 0x72, +- 0x6f, 0x90, 0x92, 0x1d, 0x95, 0x92, 0xba, 0xa3, 0xc9, 0xf3, 0xdc, 0xb0, +- 0x8a, 0xed, 0x94, 0x6c, 0x62, 0xfe, 0xff, 0xde, 0x16, 0xd8, 0xfa, 0x0e, +- 0xe4, 0xd9, 0x8e, 0x79, 0x96, 0x4f, 0x49, 0xf4, 0xc4, 0x21, 0x69, 0x3a, +- 0xf1, 0xb0, 0x34, 0x1f, 0x27, 0xc6, 0x63, 0xec, 0xde, 0xda, 0xd5, 0x2c, +- 0xc4, 0xdc, 0x43, 0x18, 0xfb, 0xb0, 0x7c, 0xdf, 0x33, 0x73, 0x5a, 0xc4, +- 0x1c, 0x59, 0xc7, 0xe4, 0x0d, 0x1e, 0xdf, 0x85, 0xf9, 0x70, 0xfd, 0x49, +- 0x8d, 0xfb, 0x76, 0x35, 0xf8, 0xae, 0x4d, 0xda, 0x77, 0x65, 0xbb, 0x4f, +- 0x61, 0xad, 0x27, 0x25, 0xea, 0x9a, 0xf6, 0xbb, 0x51, 0x2f, 0xd1, 0x70, +- 0x07, 0x82, 0x75, 0xf4, 0x9d, 0x80, 0x36, 0xe2, 0x1e, 0x9e, 0xb7, 0xb3, +- 0x2c, 0x38, 0xf3, 0xb7, 0xaa, 0xbb, 0xc2, 0x6b, 0xc7, 0xdf, 0xd9, 0x50, +- 0xd7, 0x94, 0x99, 0x36, 0xd1, 0xc0, 0xe7, 0x1f, 0x88, 0x36, 0xb4, 0x83, +- 0x71, 0x53, 0x69, 0xe0, 0x7b, 0x04, 0x7e, 0x10, 0xd7, 0x90, 0x6e, 0xc0, +- 0x39, 0x6b, 0xbf, 0x45, 0xcc, 0xa3, 0xbc, 0x30, 0x67, 0xee, 0x91, 0x59, +- 0x58, 0x8b, 0x53, 0xa4, 0xff, 0x62, 0xf3, 0x4e, 0xee, 0x5c, 0x11, 0xf3, +- 0xbe, 0x49, 0xdd, 0x25, 0xe2, 0xdd, 0x0d, 0xd4, 0x4b, 0x06, 0xf8, 0x93, +- 0xf9, 0x04, 0x78, 0x7e, 0x5b, 0x97, 0x95, 0xf9, 0xf3, 0x1b, 0x73, 0x03, +- 0xc4, 0x37, 0x5b, 0x79, 0x0e, 0x09, 0xdc, 0x4c, 0x39, 0xfb, 0x2e, 0xe4, +- 0xac, 0x59, 0x9d, 0xfb, 0x94, 0xca, 0xf4, 0xe7, 0x0a, 0x90, 0x1f, 0xde, +- 0x87, 0xa3, 0xdf, 0x57, 0xd0, 0xf1, 0x58, 0xce, 0x93, 0x98, 0xde, 0xf8, +- 0x07, 0xec, 0x73, 0xfd, 0x19, 0x6c, 0xe3, 0xfd, 0x12, 0xca, 0x5b, 0x42, +- 0xcd, 0x79, 0x78, 0x9d, 0xbf, 0x72, 0x04, 0xba, 0x60, 0x01, 0xf2, 0x3c, +- 0x09, 0x1d, 0x38, 0x14, 0xe6, 0xfe, 0x6c, 0xd1, 0xbe, 0xac, 0x4b, 0xbf, +- 0x3d, 0x34, 0x86, 0x3e, 0xac, 0xe3, 0xaf, 0xcb, 0x14, 0xf4, 0xff, 0x74, +- 0x3d, 0xa5, 0xbe, 0x17, 0xc9, 0x26, 0x78, 0x07, 0x8c, 0xe5, 0x63, 0x18, +- 0xff, 0x75, 0xe0, 0xe1, 0xcd, 0xa0, 0xa7, 0xa5, 0x79, 0xf5, 0x2b, 0x3a, +- 0x16, 0x15, 0x63, 0x2c, 0x1e, 0x7a, 0xb3, 0x14, 0x60, 0xcd, 0xf8, 0x34, +- 0xd2, 0xcd, 0x2d, 0x81, 0xbc, 0x4e, 0x6e, 0xd5, 0x77, 0x2f, 0x50, 0xfe, +- 0x98, 0x8a, 0x41, 0x06, 0x6b, 0x72, 0xb4, 0xaf, 0x12, 0x85, 0xcc, 0x71, +- 0x5d, 0xf7, 0xa2, 0x1e, 0x65, 0xad, 0x4f, 0x9f, 0xcd, 0xb6, 0x28, 0xfd, +- 0x98, 0x87, 0x2c, 0x15, 0x94, 0x1f, 0x01, 0x7c, 0xef, 0xb1, 0xdd, 0xaf, +- 0x6f, 0xe5, 0xd9, 0x67, 0x93, 0xab, 0x7c, 0x8b, 0xce, 0xb0, 0x98, 0xb2, +- 0x8f, 0xa0, 0x8c, 0x72, 0x76, 0x03, 0x78, 0xc3, 0xb2, 0x1c, 0xf2, 0x1c, +- 0xeb, 0x46, 0x3d, 0x0e, 0xc7, 0xb8, 0xb4, 0x79, 0xed, 0x9c, 0xb8, 0x96, +- 0xce, 0x75, 0x77, 0xe7, 0x59, 0x76, 0x83, 0x2e, 0x8b, 0xe8, 0xf5, 0xfd, +- 0xa9, 0xfe, 0xb6, 0xc1, 0x39, 0x9a, 0x5d, 0xc1, 0xc6, 0x9c, 0x5f, 0x4c, +- 0xb5, 0xcb, 0xda, 0x81, 0xec, 0x1c, 0x01, 0x3f, 0x22, 0x99, 0xaf, 0xf1, +- 0x4c, 0x19, 0xf4, 0x35, 0x7b, 0x22, 0xa1, 0xfc, 0xce, 0xa4, 0x15, 0xdc, +- 0x5d, 0xba, 0x58, 0x6e, 0xf4, 0x19, 0xcc, 0xfd, 0x6f, 0x57, 0xc6, 0x56, +- 0x78, 0x45, 0xbe, 0x91, 0x5f, 0xef, 0xc6, 0x2b, 0xf2, 0x91, 0xfc, 0x2a, +- 0x48, 0x69, 0x96, 0x7c, 0xa2, 0xbc, 0x8c, 0x29, 0x79, 0x29, 0x55, 0x0c, +- 0x4e, 0xa6, 0x2e, 0xe1, 0x37, 0x0f, 0x1b, 0x9d, 0xd7, 0x9b, 0xbb, 0x61, +- 0xbf, 0x44, 0xfa, 0x85, 0x86, 0xe1, 0x1e, 0x2d, 0xcc, 0x2a, 0x9d, 0x02, +- 0xbb, 0x98, 0x50, 0xba, 0xa2, 0x30, 0xce, 0xfc, 0xd2, 0x56, 0x7e, 0x9b, +- 0x8b, 0x79, 0xa0, 0xbc, 0x53, 0xf3, 0xf5, 0x06, 0x75, 0xbf, 0x89, 0x7b, +- 0xb0, 0x54, 0xa9, 0xab, 0xf7, 0x67, 0xe7, 0x9a, 0x54, 0xfd, 0xb3, 0x73, +- 0xeb, 0xef, 0x28, 0xb1, 0xec, 0x66, 0xc6, 0x55, 0x64, 0x71, 0xa6, 0x49, +- 0x96, 0xe6, 0xfe, 0x90, 0x7e, 0x22, 0x8c, 0xc1, 0xca, 0xf7, 0x1d, 0xfa, +- 0x5b, 0x2c, 0x5f, 0x86, 0x21, 0x37, 0x0b, 0x83, 0xd3, 0x52, 0x1d, 0xa4, +- 0x1f, 0xa4, 0xee, 0x0e, 0x62, 0xbd, 0x4d, 0xc0, 0xc0, 0xc0, 0x85, 0x2e, +- 0xe3, 0xcf, 0x5b, 0xb4, 0x3e, 0x79, 0xb0, 0x75, 0x25, 0x2e, 0x1d, 0x2f, +- 0xfa, 0x55, 0xd7, 0x7c, 0x33, 0xc3, 0x3e, 0xf9, 0xdd, 0x0c, 0x79, 0x66, +- 0xa1, 0x3d, 0xef, 0x64, 0x76, 0x33, 0xae, 0xad, 0xf9, 0x1c, 0x46, 0x7d, +- 0xa6, 0xbf, 0xa7, 0xf3, 0x73, 0x3a, 0xfd, 0xac, 0xec, 0x3f, 0xf9, 0x19, +- 0xcc, 0x7b, 0x53, 0x70, 0xef, 0x4a, 0x1a, 0xbf, 0x9b, 0x88, 0xe8, 0x6f, +- 0x34, 0x3e, 0x8b, 0x32, 0xc6, 0xe2, 0x3e, 0xab, 0xd6, 0xc4, 0xbb, 0x7d, +- 0x45, 0xf9, 0x79, 0x77, 0x54, 0x8c, 0x3f, 0xc8, 0xfb, 0x53, 0x2d, 0xba, +- 0xbf, 0x3d, 0x5a, 0x96, 0xc6, 0x65, 0x3f, 0xec, 0x5d, 0x01, 0xb8, 0x98, +- 0x77, 0xce, 0x26, 0xc2, 0x8d, 0x63, 0x9a, 0xfd, 0x14, 0xc4, 0x1a, 0xcc, +- 0xdd, 0x87, 0xb0, 0xf2, 0x89, 0x56, 0xe2, 0x16, 0xba, 0x7c, 0x5c, 0x0e, +- 0x94, 0x55, 0xfc, 0x42, 0x9d, 0x59, 0x4e, 0x43, 0x2f, 0x0c, 0x29, 0x9b, +- 0x16, 0x0b, 0x0d, 0xd7, 0x32, 0x52, 0x38, 0xbd, 0x17, 0xe3, 0x30, 0x16, +- 0x98, 0xd5, 0x67, 0x83, 0xfb, 0x64, 0x7f, 0x3d, 0x18, 0x7b, 0xb2, 0xcc, +- 0xf7, 0x29, 0xe0, 0x04, 0xbe, 0xcf, 0x27, 0xc2, 0xea, 0x74, 0xe3, 0x56, +- 0xb4, 0x6d, 0xd2, 0x74, 0xe6, 0xbd, 0x6b, 0xb6, 0xa7, 0x0e, 0x00, 0xc0, +- 0x69, 0xc9, 0xe3, 0x3d, 0xdb, 0x98, 0xfe, 0x26, 0x61, 0xb7, 0xe8, 0x9f, +- 0x3f, 0x2a, 0xcb, 0x95, 0x69, 0xb9, 0x5c, 0x31, 0xb2, 0xce, 0xbb, 0xd7, +- 0x9c, 0xfb, 0x5d, 0xc1, 0xb7, 0xbf, 0xe5, 0x2c, 0xf8, 0xb3, 0x96, 0x56, +- 0xf9, 0x35, 0xdf, 0xdb, 0xfc, 0x2b, 0x3b, 0xf8, 0xe6, 0x6d, 0xb7, 0xba, +- 0xc3, 0xb5, 0x76, 0xcf, 0xb1, 0x9f, 0xfd, 0x36, 0xcf, 0x3a, 0x82, 0x7b, +- 0x68, 0x9d, 0x0d, 0xef, 0xe3, 0xfa, 0xee, 0xd7, 0xa7, 0xec, 0x80, 0x8f, +- 0xa4, 0xe7, 0x98, 0x9e, 0xef, 0xad, 0xd8, 0xff, 0xec, 0xf3, 0x31, 0xcd, +- 0x37, 0xa4, 0x0b, 0x7c, 0xe6, 0xfe, 0x5a, 0xd6, 0xe7, 0xbf, 0xb6, 0x1e, +- 0xa3, 0xf1, 0xee, 0x5d, 0x53, 0xc3, 0xb8, 0x6c, 0x4f, 0xfb, 0x64, 0xee, +- 0x80, 0xb3, 0xec, 0xa4, 0xbe, 0xe3, 0x77, 0xb5, 0xa1, 0xcc, 0xdc, 0x45, +- 0x23, 0xbd, 0x18, 0xd3, 0x44, 0x5a, 0x1f, 0xd3, 0xcf, 0x63, 0x0d, 0xdf, +- 0xc8, 0x98, 0x3e, 0x23, 0xe8, 0xc3, 0xdc, 0x41, 0x6f, 0xbc, 0x53, 0xcc, +- 0xef, 0x83, 0x28, 0x8b, 0x16, 0xbf, 0x61, 0xa6, 0x1f, 0x08, 0xec, 0xb6, +- 0x45, 0x26, 0xd5, 0x7c, 0x8a, 0xea, 0xbe, 0x06, 0xbf, 0x9b, 0x19, 0xb2, +- 0x83, 0xfc, 0xe4, 0xc2, 0x7a, 0x39, 0x65, 0xf9, 0x33, 0xcd, 0xd2, 0x52, +- 0xc4, 0x38, 0x7c, 0xbf, 0xd1, 0xf7, 0xf4, 0x51, 0xfd, 0x9d, 0x90, 0x87, +- 0x36, 0x4f, 0x50, 0xde, 0x8b, 0xc5, 0x95, 0x7b, 0xa2, 0xc5, 0xe0, 0x1b, +- 0x26, 0xcb, 0xdc, 0xd7, 0xe4, 0x37, 0xda, 0x22, 0x17, 0x6a, 0xfc, 0x3e, +- 0x69, 0xb7, 0xba, 0x47, 0x13, 0x9c, 0x4d, 0x72, 0x5e, 0x3d, 0xca, 0x2e, +- 0x54, 0x6b, 0x25, 0xd2, 0x54, 0xdb, 0xf6, 0xa8, 0xb6, 0xed, 0xa4, 0xf1, +- 0x08, 0x68, 0xfc, 0x25, 0xcd, 0x17, 0xb6, 0xcf, 0xaa, 0xfb, 0xdd, 0xd9, +- 0x38, 0xcf, 0xc7, 0x1e, 0x53, 0x6b, 0xa1, 0x9d, 0x40, 0xdb, 0x5f, 0x0e, +- 0xab, 0x78, 0xa7, 0xfa, 0x06, 0x1c, 0xf2, 0xc9, 0x6f, 0xba, 0xa1, 0xe3, +- 0xcb, 0xfc, 0x76, 0x7b, 0x04, 0x29, 0xbf, 0xd9, 0xde, 0xab, 0xee, 0xff, +- 0x57, 0xd5, 0x37, 0x01, 0x46, 0x1e, 0xc3, 0x7a, 0xac, 0x6f, 0x62, 0x8c, +- 0x80, 0xef, 0x85, 0x32, 0xbf, 0xe5, 0x36, 0x77, 0x4c, 0x37, 0x2f, 0x73, +- 0x4f, 0x88, 0xf2, 0xf3, 0x83, 0x6f, 0xfb, 0xab, 0xea, 0x3b, 0x82, 0x24, +- 0xbf, 0x2b, 0x84, 0xfd, 0xba, 0x1f, 0xcf, 0x3c, 0x57, 0xde, 0x87, 0x14, +- 0xfa, 0xa7, 0x36, 0x81, 0xf4, 0x61, 0xc9, 0xab, 0xb8, 0x5f, 0x2b, 0xf2, +- 0x93, 0x6a, 0xec, 0x52, 0xed, 0x13, 0xb2, 0xff, 0xf4, 0x43, 0xfc, 0x5e, +- 0x42, 0x7d, 0x77, 0x9e, 0xf3, 0x38, 0xc7, 0xb8, 0x4c, 0xa9, 0x75, 0x17, +- 0x35, 0xed, 0xcd, 0x59, 0xcc, 0xcf, 0xd4, 0xb7, 0x19, 0xc5, 0x5a, 0x2b, +- 0xe6, 0x18, 0xd2, 0xf7, 0x4c, 0xe9, 0x0f, 0x98, 0xf5, 0xb7, 0xf0, 0xee, +- 0xa2, 0xcf, 0xf3, 0xc3, 0xfd, 0x65, 0xde, 0x23, 0x4d, 0xe9, 0x38, 0x01, +- 0x63, 0x87, 0x3c, 0x9f, 0xa0, 0x8c, 0x3b, 0xe9, 0x09, 0x58, 0xa0, 0xa8, +- 0x24, 0x78, 0xb6, 0xad, 0xd7, 0xd2, 0xda, 0xb0, 0x16, 0xde, 0x9d, 0x0d, +- 0xd6, 0xc3, 0xef, 0x21, 0x0a, 0xe5, 0xc6, 0x6f, 0x2a, 0xd4, 0x37, 0xd0, +- 0xfc, 0x76, 0x46, 0x26, 0x6a, 0x9f, 0x94, 0x07, 0xca, 0x5b, 0xf4, 0xf7, +- 0x14, 0x31, 0x79, 0xa0, 0xf6, 0xba, 0xa2, 0x69, 0x41, 0x7d, 0xd7, 0x11, +- 0xd5, 0x3c, 0x33, 0xdf, 0x54, 0x04, 0xfd, 0x1d, 0xa8, 0x39, 0x0d, 0xdf, +- 0x2f, 0x44, 0x65, 0x62, 0xe1, 0x47, 0x91, 0x8d, 0xbf, 0x61, 0x78, 0x54, +- 0x72, 0xa7, 0x69, 0xa3, 0xa7, 0xe5, 0xf1, 0x8a, 0xef, 0xdf, 0xe9, 0x11, +- 0x5b, 0x6e, 0x96, 0xcb, 0xf1, 0xb1, 0x3d, 0x6f, 0xb8, 0x1d, 0xa1, 0xea, +- 0x6c, 0x33, 0x74, 0x2f, 0xf1, 0x8c, 0xb4, 0x30, 0xbf, 0x30, 0xcb, 0x7d, +- 0x1a, 0xc1, 0x1a, 0x1d, 0xfb, 0x9a, 0xdc, 0xde, 0xce, 0xb8, 0xdb, 0x9d, +- 0xf0, 0x65, 0x7f, 0xdb, 0x0b, 0xf4, 0xf5, 0xe7, 0x16, 0xf7, 0xca, 0xe7, +- 0x6a, 0xb1, 0x50, 0x75, 0x86, 0xf7, 0x0d, 0x9d, 0x91, 0x8a, 0xa4, 0x50, +- 0x8f, 0xfd, 0x43, 0x5e, 0x12, 0xd7, 0xc9, 0xb3, 0x27, 0x7f, 0xea, 0x5f, +- 0x73, 0xf1, 0x1e, 0xba, 0xe6, 0xb2, 0x67, 0x62, 0x8b, 0x63, 0xf0, 0x5d, +- 0x59, 0xef, 0x3a, 0xc8, 0x01, 0xb0, 0x03, 0xf6, 0x1c, 0xfd, 0xdc, 0x6b, +- 0x5a, 0x6f, 0x59, 0xc7, 0x6e, 0x92, 0x6b, 0x2b, 0xf7, 0x95, 0x5f, 0x83, +- 0x6c, 0x27, 0x03, 0xfa, 0xab, 0x58, 0xfc, 0x21, 0x09, 0x7f, 0x1e, 0x36, +- 0xe5, 0xf3, 0x4d, 0x4a, 0xb7, 0xd3, 0xb6, 0xc1, 0x07, 0x82, 0x9f, 0x13, +- 0x41, 0x3f, 0xa9, 0xf6, 0x40, 0x66, 0xa7, 0x45, 0xbe, 0xb0, 0x49, 0xb2, +- 0xed, 0xf4, 0xa3, 0xe5, 0xe7, 0xe8, 0xaf, 0xc6, 0x7d, 0x96, 0x96, 0x3f, +- 0xe2, 0x1e, 0xaf, 0x73, 0x2d, 0xa9, 0xc4, 0x9f, 0xc9, 0xa7, 0x65, 0x22, +- 0xc1, 0xb5, 0x3c, 0x2a, 0xc5, 0xca, 0x63, 0xf8, 0x71, 0x9d, 0x9c, 0xf7, +- 0xc7, 0xf4, 0x5d, 0x86, 0x31, 0x29, 0xcd, 0x64, 0x64, 0x6a, 0x6e, 0x92, +- 0xdf, 0xa0, 0x8e, 0xdc, 0xa9, 0xce, 0xf8, 0x9c, 0x44, 0x2a, 0xb4, 0x2d, +- 0x39, 0xc5, 0xbb, 0x1b, 0x6a, 0x3d, 0x93, 0x58, 0xcf, 0xe3, 0xed, 0xbc, +- 0xb3, 0x7e, 0x0d, 0xfa, 0xd7, 0x3a, 0x45, 0x39, 0x74, 0xec, 0xee, 0x10, +- 0xf3, 0xfb, 0xe0, 0xbf, 0xb3, 0x6c, 0x9f, 0x84, 0x8f, 0xad, 0xe8, 0x79, +- 0x94, 0xeb, 0xb3, 0x66, 0xd5, 0xfe, 0x14, 0xda, 0xa2, 0xde, 0x31, 0xd3, +- 0xd6, 0xd4, 0x61, 0x5b, 0xae, 0x73, 0xaf, 0x34, 0x9f, 0x33, 0xf3, 0x82, +- 0x1c, 0x26, 0x1a, 0xe9, 0xdd, 0xb2, 0x8e, 0xde, 0x11, 0x62, 0x5e, 0xd0, +- 0x8b, 0x34, 0x0e, 0x6b, 0x1a, 0x7f, 0x05, 0xfd, 0x1b, 0x1e, 0xdc, 0x89, +- 0x32, 0x5b, 0x7f, 0x93, 0xf4, 0x7e, 0xe8, 0x4e, 0x9a, 0xb3, 0x3e, 0xe9, +- 0x4e, 0xd9, 0xe2, 0x7c, 0x36, 0xa2, 0xf9, 0xeb, 0x9a, 0x2f, 0xfb, 0x40, +- 0x2f, 0xde, 0x2b, 0xdd, 0xa6, 0xbe, 0x2f, 0xc8, 0x8e, 0xef, 0x83, 0xec, +- 0x98, 0x75, 0x6d, 0x83, 0x8c, 0xf1, 0xdc, 0x84, 0xf5, 0x1b, 0x69, 0x12, +- 0xd8, 0xbd, 0x30, 0x63, 0x1f, 0x2e, 0xd7, 0x0a, 0x5c, 0xfa, 0x05, 0xda, +- 0x28, 0x7e, 0x63, 0x7d, 0xb3, 0xb6, 0x51, 0x3f, 0x8f, 0xc7, 0x3f, 0x6a, +- 0x0f, 0x6c, 0x94, 0x0d, 0x9a, 0xb4, 0xe9, 0x36, 0xfb, 0x80, 0x91, 0x19, +- 0x0f, 0x4e, 0x25, 0x1e, 0x14, 0x33, 0x8e, 0xbf, 0x9b, 0x7e, 0xef, 0xd0, +- 0xc0, 0x36, 0xa0, 0x16, 0x75, 0x67, 0x27, 0xc1, 0x3b, 0x40, 0xa9, 0xd0, +- 0x3e, 0x75, 0x7f, 0x63, 0xed, 0xf7, 0x23, 0x69, 0x79, 0x76, 0x55, 0x56, +- 0x46, 0x7e, 0x28, 0x8e, 0x24, 0x6f, 0xa4, 0xac, 0xb0, 0xdf, 0x49, 0xae, +- 0x33, 0xf1, 0x90, 0x5a, 0xa7, 0x0d, 0x3f, 0x92, 0x77, 0x2d, 0xec, 0x50, +- 0x75, 0x8e, 0x7c, 0x47, 0xba, 0xc8, 0x67, 0x73, 0xde, 0xab, 0xf4, 0x0a, +- 0xc6, 0x65, 0x19, 0x75, 0x23, 0xdf, 0x67, 0xf4, 0x79, 0x70, 0x7b, 0x07, +- 0xef, 0x24, 0x14, 0x50, 0x56, 0x59, 0xdc, 0x78, 0x6e, 0xbf, 0xad, 0xe4, +- 0xe0, 0x51, 0xd0, 0xfd, 0x9f, 0xa1, 0xee, 0x63, 0x48, 0xb9, 0xc6, 0xcc, +- 0x0a, 0xdf, 0x49, 0xef, 0x8f, 0xca, 0x20, 0xe4, 0x82, 0xf9, 0x47, 0x81, +- 0x37, 0x69, 0x4f, 0x91, 0x56, 0xf8, 0x4c, 0x5d, 0xef, 0x6a, 0x7b, 0xca, +- 0xb9, 0xec, 0xc3, 0x5c, 0xd4, 0x3a, 0xb5, 0x3c, 0xdd, 0xaf, 0xdb, 0x8d, +- 0xaf, 0xd0, 0xea, 0xa1, 0x77, 0xe0, 0x8d, 0xe8, 0x0a, 0xde, 0x08, 0xc6, +- 0xca, 0x76, 0x18, 0xac, 0x11, 0xac, 0x21, 0xc0, 0x1a, 0x81, 0x9c, 0x4f, +- 0x4a, 0x04, 0x72, 0x1c, 0x5e, 0x95, 0x63, 0xe0, 0x9e, 0x60, 0xcf, 0x4c, +- 0xf1, 0x1c, 0x53, 0xd1, 0x99, 0x72, 0x48, 0xf9, 0x25, 0x1f, 0x1b, 0x79, +- 0x7d, 0xfb, 0xbb, 0xf0, 0xba, 0xd4, 0x61, 0xf0, 0xc3, 0x3f, 0x6c, 0x1f, +- 0x3c, 0xd2, 0xb1, 0xba, 0x0f, 0x6e, 0xfa, 0x05, 0xed, 0x83, 0xf5, 0x72, +- 0xd9, 0x28, 0x53, 0x36, 0xe4, 0x89, 0xfc, 0xa2, 0x3c, 0x51, 0x8e, 0x48, +- 0x4b, 0xea, 0xd3, 0x66, 0xfa, 0x6f, 0x89, 0xab, 0xea, 0xdb, 0x91, 0x69, +- 0xe8, 0xa0, 0x8e, 0x50, 0xa5, 0x12, 0x97, 0xd2, 0xe2, 0x4f, 0x94, 0x4c, +- 0x3f, 0x5b, 0xa7, 0x5e, 0x7a, 0xaf, 0xb5, 0xaf, 0xd5, 0xb9, 0x85, 0x75, +- 0x3a, 0xb7, 0xb0, 0xa2, 0x73, 0xdb, 0xb5, 0xcf, 0xf6, 0x0f, 0xd1, 0xb9, +- 0xf1, 0x86, 0xb3, 0x21, 0x73, 0x2e, 0x24, 0xa1, 0x5c, 0x5f, 0x8b, 0xec, +- 0x81, 0x1d, 0x19, 0x99, 0xd9, 0x2b, 0x7f, 0x30, 0x33, 0xad, 0xee, 0x49, +- 0x7d, 0xd3, 0x4b, 0x25, 0x3e, 0x11, 0xf2, 0xe5, 0xa3, 0xf0, 0xb9, 0x27, +- 0xba, 0x9a, 0x64, 0xcf, 0x6d, 0xea, 0xbc, 0xd3, 0xce, 0x85, 0x3a, 0x85, +- 0x91, 0xf8, 0xbc, 0xe7, 0x78, 0xc9, 0x10, 0xef, 0xcc, 0x35, 0xcb, 0x44, +- 0xbc, 0x55, 0xf6, 0x02, 0x3b, 0x15, 0xaf, 0xf7, 0xd4, 0x37, 0xd3, 0x59, +- 0x75, 0x9e, 0xf4, 0x86, 0xe6, 0x3b, 0xe8, 0xd0, 0x66, 0xcb, 0x7f, 0xac, +- 0x33, 0xcf, 0xf2, 0x07, 0xd7, 0xe5, 0xf9, 0xfc, 0x04, 0xfc, 0xb9, 0x38, +- 0x68, 0xd5, 0x78, 0xff, 0x28, 0xac, 0xe8, 0x59, 0xaa, 0x8c, 0xab, 0x7b, +- 0x5d, 0x57, 0xc3, 0xa4, 0x97, 0xf2, 0xa1, 0x12, 0xb9, 0x30, 0x30, 0xce, +- 0x2c, 0x90, 0xb4, 0x4b, 0xbf, 0x53, 0xe3, 0x4f, 0xe8, 0xff, 0xfd, 0xea, +- 0x7c, 0x79, 0x19, 0xb4, 0xf1, 0x55, 0xfc, 0xb9, 0x10, 0x27, 0xae, 0x5f, +- 0xbd, 0xc3, 0xfc, 0x4e, 0x7c, 0xaf, 0xb0, 0xbd, 0x39, 0x0b, 0xd1, 0xf1, +- 0x2a, 0x1d, 0x07, 0x50, 0x67, 0x7b, 0x1b, 0xfd, 0xbf, 0x0b, 0xc4, 0x7a, +- 0xfc, 0xae, 0x9f, 0xd8, 0xce, 0x39, 0x5a, 0x91, 0x1f, 0x2a, 0x5f, 0x34, +- 0x4b, 0xfa, 0x56, 0xc1, 0xa7, 0xe3, 0x09, 0x63, 0xcf, 0x43, 0xdd, 0xe7, +- 0x1b, 0x7d, 0x51, 0xf6, 0x11, 0x53, 0x77, 0x42, 0x56, 0xff, 0x9f, 0x17, +- 0xc6, 0x98, 0xb2, 0xa1, 0xbb, 0xcb, 0xd3, 0x12, 0x3e, 0x31, 0x26, 0x91, +- 0xe3, 0x8c, 0xe7, 0x67, 0xa5, 0x14, 0xf7, 0xe5, 0x01, 0x6f, 0xad, 0x6f, +- 0xd2, 0x6d, 0xad, 0x9f, 0xfb, 0xa3, 0x32, 0x74, 0xfa, 0x31, 0x89, 0x9e, +- 0xe0, 0xbb, 0x35, 0x67, 0x39, 0xd0, 0x47, 0x9b, 0xa5, 0x12, 0x67, 0x4c, +- 0x3b, 0xaa, 0xce, 0xc6, 0x2f, 0x8f, 0xbf, 0x1e, 0x2d, 0x01, 0x2b, 0x14, +- 0x94, 0x6e, 0x41, 0xba, 0xe2, 0x4b, 0xe4, 0xae, 0xe3, 0x9e, 0x82, 0xbf, +- 0x19, 0x9a, 0xa8, 0x44, 0xd5, 0x1d, 0xa5, 0xcb, 0x71, 0xd6, 0x7d, 0x0c, +- 0x7e, 0x37, 0x71, 0x06, 0x74, 0xc7, 0x98, 0xb4, 0x30, 0x1f, 0x3e, 0xb1, +- 0x8a, 0x33, 0xa8, 0x13, 0x86, 0xbc, 0xb8, 0x44, 0xce, 0x04, 0x6b, 0xe7, +- 0x7f, 0x1c, 0x64, 0xcd, 0xef, 0x95, 0xf0, 0x71, 0x3e, 0x37, 0xfa, 0x43, +- 0xc4, 0xee, 0xb0, 0x0d, 0xe7, 0x7f, 0x1f, 0xfd, 0xf1, 0x5d, 0x56, 0x7f, +- 0x87, 0x8b, 0x7c, 0xf5, 0xef, 0xfa, 0x7f, 0x04, 0x50, 0xf6, 0xff, 0x3f, +- 0xc3, 0x8e, 0xbb, 0xb0, 0xa8, 0x4d, 0x00, 0x00, 0x00 }; ++ 0xcd, 0x7c, 0x0d, 0x70, 0x5b, 0xd7, 0x95, 0xde, 0xc1, 0x03, 0x40, 0x82, ++ 0x10, 0x45, 0x3d, 0x52, 0x30, 0x0d, 0x3b, 0x4c, 0x82, 0x47, 0x3c, 0x92, ++ 0xb0, 0xc9, 0x64, 0x9f, 0x64, 0x46, 0x66, 0x12, 0xac, 0x05, 0x03, 0xa4, ++ 0x4c, 0x27, 0xea, 0x92, 0xb6, 0x19, 0x47, 0x6d, 0x35, 0x09, 0x17, 0x92, ++ 0x12, 0xdb, 0x4d, 0xa7, 0x9a, 0xc6, 0xe9, 0x2a, 0x1b, 0xc7, 0x82, 0x41, ++ 0xca, 0x51, 0x52, 0x8a, 0x60, 0x24, 0x4a, 0xf2, 0x74, 0xb3, 0xbb, 0x0c, ++ 0x48, 0x4a, 0x8e, 0x03, 0x09, 0x96, 0xec, 0x75, 0xdc, 0xad, 0xb3, 0x62, ++ 0x68, 0xad, 0xec, 0x4d, 0xb3, 0xad, 0x9d, 0x49, 0x3a, 0x9a, 0xa9, 0xb7, ++ 0x55, 0x95, 0xa4, 0xf9, 0x99, 0xfe, 0xb8, 0x49, 0xa6, 0x75, 0xbb, 0xf1, ++ 0xbe, 0x7e, 0xdf, 0x7d, 0xf7, 0x11, 0x20, 0xc5, 0x28, 0xde, 0xec, 0x64, ++ 0x66, 0x39, 0x83, 0xb9, 0xef, 0xde, 0x77, 0x7f, 0xce, 0x3d, 0xf7, 0xfc, ++ 0x7c, 0xe7, 0xde, 0xfb, 0x78, 0x87, 0x48, 0x54, 0xf4, 0xdf, 0x46, 0xfc, ++ 0xfa, 0xff, 0xe9, 0x3f, 0xdb, 0xb3, 0xf5, 0xdd, 0xfd, 0xef, 0x66, 0xde, ++ 0x30, 0x42, 0x21, 0xa6, 0x41, 0xfc, 0x62, 0xf8, 0x6d, 0xd5, 0xcf, 0xeb, ++ 0xfd, 0x99, 0xf8, 0x6d, 0x0b, 0x88, 0x8c, 0xff, 0x44, 0x24, 0xb0, 0xe6, ++ 0x5d, 0x64, 0x9d, 0xfa, 0xae, 0xfb, 0x4b, 0x3a, 0xd2, 0x7f, 0x06, 0x7e, ++ 0x89, 0xeb, 0x57, 0x59, 0x19, 0xf7, 0xd7, 0xfd, 0x0b, 0xea, 0xe6, 0x1b, ++ 0xf5, 0x4f, 0x22, 0x46, 0x5a, 0x46, 0xb2, 0xb6, 0x44, 0x82, 0xe9, 0x9f, ++ 0x8f, 0xec, 0xb1, 0x45, 0x32, 0x95, 0xde, 0x44, 0x4e, 0xde, 0x74, 0x0b, ++ 0xb1, 0x90, 0xb0, 0xfc, 0xed, 0xe9, 0x5f, 0x1c, 0xfc, 0xfa, 0xed, 0xd6, ++ 0xeb, 0x73, 0x41, 0x89, 0x98, 0xe9, 0x37, 0xc4, 0xec, 0x96, 0x48, 0x07, ++ 0xda, 0x7c, 0xa9, 0xe7, 0x49, 0x43, 0x5a, 0xfc, 0xbe, 0xcc, 0xf1, 0x60, ++ 0x5a, 0x46, 0xf7, 0x4e, 0x1d, 0x74, 0x0d, 0x5b, 0x0a, 0x37, 0xa7, 0xed, ++ 0x44, 0x51, 0x9a, 0x07, 0x26, 0xfb, 0x6f, 0x17, 0xe4, 0x47, 0xf7, 0x56, ++ 0x22, 0x92, 0xad, 0x16, 0x9a, 0x0d, 0xdb, 0x46, 0x1a, 0x29, 0xbc, 0x2d, ++ 0x2d, 0x91, 0x86, 0xf4, 0x6c, 0xe3, 0x25, 0x9b, 0xe3, 0x0f, 0x60, 0xfc, ++ 0xb7, 0x49, 0xc8, 0x76, 0xdd, 0x49, 0x8c, 0xbf, 0xa3, 0xf2, 0xa6, 0xfb, ++ 0x58, 0xc8, 0x1b, 0xdb, 0x48, 0x1f, 0x08, 0x32, 0x0d, 0xa4, 0x33, 0x23, ++ 0x9d, 0x15, 0x95, 0x6f, 0xf0, 0xf2, 0x83, 0x3a, 0x1f, 0x89, 0x7a, 0xb4, ++ 0x4b, 0x13, 0x68, 0x8f, 0x84, 0xd2, 0xe9, 0x26, 0xf4, 0x11, 0x09, 0xa7, ++ 0x97, 0x7e, 0x7b, 0x51, 0xd5, 0x3b, 0xac, 0xeb, 0x3d, 0x10, 0xf6, 0xda, ++ 0x4d, 0x8e, 0x74, 0x57, 0x98, 0xce, 0x8e, 0x74, 0xa9, 0xf4, 0x4b, 0x23, ++ 0x49, 0x95, 0xce, 0xa9, 0x7a, 0x81, 0xf4, 0xc2, 0x88, 0xad, 0xd2, 0xb4, ++ 0x2e, 0x1f, 0x1e, 0x49, 0xa8, 0x74, 0xa7, 0x4e, 0x47, 0x75, 0x3a, 0xa6, ++ 0xd3, 0x5d, 0x3a, 0xdd, 0xad, 0xd3, 0x71, 0x9d, 0xee, 0xd5, 0xfd, 0x3c, ++ 0xa0, 0xf3, 0x9f, 0xd0, 0xe9, 0x7e, 0x9d, 0x3e, 0xac, 0xd3, 0x03, 0x3a, ++ 0x7d, 0x44, 0xd3, 0x55, 0xd0, 0xe9, 0x94, 0x2e, 0x9f, 0xd1, 0x74, 0x3e, ++ 0x01, 0x7a, 0xfe, 0x71, 0xa3, 0x96, 0x5b, 0xcc, 0x37, 0x21, 0x7b, 0xa6, ++ 0x22, 0x52, 0x2c, 0x05, 0x25, 0xa7, 0xd6, 0xf3, 0xe3, 0x61, 0x89, 0x46, ++ 0x64, 0xa2, 0x1a, 0x91, 0x2b, 0x4a, 0x5c, 0x7f, 0xe4, 0x7e, 0xbd, 0xc7, ++ 0x94, 0xa7, 0xab, 0x31, 0xb9, 0x50, 0x95, 0xc0, 0x68, 0x4f, 0x93, 0x18, ++ 0x47, 0x6f, 0x96, 0x8c, 0x19, 0x90, 0xa0, 0xe2, 0x6b, 0x42, 0xb2, 0x53, ++ 0xed, 0xc8, 0x5b, 0x71, 0x91, 0xc5, 0xb0, 0xb7, 0x8e, 0x11, 0x09, 0x9e, ++ 0xe0, 0xba, 0x3c, 0x37, 0x72, 0x69, 0x36, 0x2e, 0xa1, 0xe9, 0x04, 0xfa, ++ 0x6f, 0x96, 0xf0, 0x09, 0xe9, 0x08, 0x4a, 0x57, 0xfc, 0x63, 0xa8, 0x31, ++ 0x58, 0x09, 0xc9, 0x50, 0x25, 0x80, 0xb5, 0x8a, 0x40, 0x4e, 0x9a, 0xf1, ++ 0x33, 0xf1, 0x8b, 0xe1, 0x17, 0xc7, 0xef, 0xaf, 0xd0, 0x4f, 0x87, 0xe4, ++ 0x2a, 0xec, 0x13, 0xe3, 0x96, 0x30, 0x7e, 0xc9, 0x32, 0xc7, 0x85, 0x34, ++ 0xc5, 0xe5, 0xeb, 0x3d, 0x1e, 0x4d, 0x17, 0xaa, 0x91, 0x40, 0xf6, 0xa4, ++ 0xec, 0xcf, 0x39, 0x92, 0x30, 0xec, 0xa8, 0xe4, 0xcd, 0x40, 0x62, 0x6f, ++ 0xaa, 0x4d, 0x0a, 0x63, 0x78, 0x57, 0x92, 0x8c, 0x81, 0xbe, 0xf3, 0xa6, ++ 0x8c, 0x7b, 0xef, 0x58, 0xf6, 0x7f, 0xa1, 0xaf, 0x96, 0x49, 0xc1, 0xbd, ++ 0x50, 0xfa, 0xd7, 0x78, 0x66, 0x5f, 0x2f, 0x86, 0x3c, 0x9a, 0xdf, 0x40, ++ 0x9e, 0xe5, 0xee, 0x26, 0x2f, 0xcf, 0x67, 0xd6, 0xf5, 0xc7, 0xf4, 0xe7, ++ 0xca, 0xb1, 0x7b, 0x30, 0x5f, 0x8e, 0xbf, 0x32, 0x5f, 0xd0, 0xd1, 0x1c, ++ 0xc8, 0x9d, 0x4c, 0xc8, 0xa1, 0xd2, 0x1d, 0x92, 0x75, 0x5c, 0x77, 0x8f, ++ 0x23, 0x31, 0x43, 0xba, 0xcc, 0x1c, 0xde, 0x96, 0x2b, 0x12, 0xc8, 0x96, ++ 0x7c, 0x7e, 0xb0, 0xdf, 0x10, 0xca, 0xda, 0x51, 0xbf, 0x25, 0x30, 0x78, ++ 0x12, 0xb4, 0xa7, 0xc9, 0x17, 0xc8, 0xac, 0xd3, 0x15, 0xdf, 0x8b, 0xf1, ++ 0xe6, 0x2b, 0x5d, 0xce, 0xb2, 0x98, 0xe8, 0xb3, 0x0d, 0x75, 0xc8, 0x23, ++ 0xf6, 0xc5, 0x3e, 0xd9, 0x5f, 0x33, 0xda, 0xc6, 0xf0, 0x8e, 0x34, 0xb9, ++ 0x6e, 0xd6, 0x31, 0x99, 0x97, 0x39, 0xf0, 0x6d, 0x8e, 0x7c, 0x8b, 0x76, ++ 0xc8, 0xa9, 0x0a, 0xc7, 0x58, 0x8f, 0xee, 0x5b, 0xff, 0x9e, 0xd1, 0x1d, ++ 0x47, 0xff, 0x31, 0xa4, 0x1b, 0x02, 0xd9, 0x63, 0x2e, 0xc6, 0x8f, 0xe3, ++ 0x79, 0xbd, 0x39, 0x5c, 0xd1, 0x32, 0x18, 0x07, 0xed, 0x31, 0x39, 0xa7, ++ 0xe4, 0x70, 0x83, 0x04, 0x21, 0x87, 0x5c, 0xe3, 0xd6, 0x13, 0xef, 0x91, ++ 0x7c, 0xcc, 0x4a, 0xd0, 0x76, 0x76, 0x6e, 0x6d, 0xc2, 0x1c, 0xb5, 0x15, ++ 0x9c, 0x8e, 0x41, 0x0e, 0x97, 0x5b, 0x0d, 0x94, 0x18, 0x62, 0x99, 0xff, ++ 0x48, 0x0a, 0x92, 0x5b, 0xf8, 0xbd, 0x80, 0x44, 0x0d, 0xd4, 0xbb, 0x25, ++ 0xe0, 0xf1, 0x80, 0xfc, 0xc9, 0x80, 0x3f, 0x01, 0xd1, 0xf6, 0x41, 0x3a, ++ 0x2b, 0x7c, 0xdf, 0x9b, 0x30, 0xd4, 0xbb, 0x41, 0xbc, 0x0b, 0x49, 0x72, ++ 0xab, 0xff, 0x7e, 0x10, 0xef, 0x6f, 0x96, 0x71, 0x13, 0xb4, 0x94, 0x9e, ++ 0x37, 0xb2, 0xa0, 0xf1, 0xce, 0x90, 0x9a, 0x2b, 0xea, 0x8e, 0xd7, 0xf5, ++ 0x33, 0x8e, 0x7a, 0xff, 0x0a, 0x63, 0x81, 0xde, 0x52, 0x02, 0xb4, 0xb4, ++ 0x83, 0x16, 0xd2, 0x58, 0x30, 0xb2, 0xd5, 0x10, 0xf2, 0x93, 0x46, 0xee, ++ 0xf4, 0x61, 0x3c, 0x8b, 0x69, 0xa4, 0x9f, 0x67, 0x8a, 0xf6, 0xbb, 0xeb, ++ 0xda, 0xef, 0x46, 0x7b, 0x8e, 0xc1, 0xf6, 0x9e, 0xfc, 0x17, 0x94, 0x2c, ++ 0x26, 0xae, 0xc3, 0x8f, 0xe0, 0xaf, 0xc1, 0x8f, 0x7f, 0xa3, 0xf9, 0xf1, ++ 0xd7, 0xf2, 0x9b, 0xe7, 0xc7, 0x7f, 0xfa, 0x0d, 0xf1, 0x43, 0x24, 0x7f, ++ 0x8c, 0xcf, 0x21, 0x29, 0x28, 0xbb, 0x45, 0xbd, 0xa5, 0xbc, 0xd3, 0x66, ++ 0x91, 0x4f, 0x94, 0x63, 0xe8, 0x40, 0x35, 0x84, 0xf4, 0x49, 0xa4, 0x1b, ++ 0x02, 0xa3, 0xc7, 0xae, 0x62, 0xfd, 0x5d, 0x31, 0xb7, 0xfa, 0x7e, 0xa3, ++ 0x10, 0x37, 0xa5, 0x43, 0xcc, 0x77, 0xc3, 0x69, 0xb7, 0x5b, 0x66, 0x5e, ++ 0x7e, 0x80, 0xf7, 0x6f, 0x06, 0x7c, 0xff, 0x9e, 0x9d, 0x6a, 0x7a, 0x23, ++ 0xa3, 0x9e, 0xc2, 0xe4, 0x67, 0xc6, 0x48, 0x87, 0x02, 0xb9, 0x52, 0x62, ++ 0xdc, 0x48, 0xc7, 0x60, 0xa7, 0x98, 0x1f, 0x08, 0x78, 0x34, 0xf7, 0xa3, ++ 0xae, 0x6f, 0xb3, 0x7c, 0xda, 0xfb, 0x41, 0xfb, 0x5a, 0xdb, 0x95, 0x01, ++ 0x2d, 0xa4, 0x81, 0x74, 0x15, 0x82, 0x9a, 0xf7, 0xe8, 0xe7, 0x80, 0xea, ++ 0x27, 0x98, 0x1e, 0x10, 0xfa, 0xd0, 0xfc, 0x14, 0xf5, 0x80, 0xed, 0xd8, ++ 0x97, 0x67, 0x93, 0xf3, 0x15, 0xbf, 0x8f, 0x42, 0x7d, 0x1f, 0xa0, 0x47, ++ 0x36, 0x19, 0x76, 0x18, 0x6b, 0xcf, 0xae, 0x0e, 0xe3, 0xdd, 0x97, 0x24, ++ 0x7b, 0xfa, 0x76, 0x03, 0x73, 0x40, 0xbf, 0xe4, 0xd1, 0x28, 0x6c, 0x36, ++ 0xf5, 0x2c, 0x22, 0xb9, 0x18, 0xcb, 0x3e, 0xa2, 0xc7, 0x0d, 0x49, 0x46, ++ 0xe5, 0xbf, 0xd2, 0x52, 0xa3, 0xe3, 0x79, 0x3d, 0x9f, 0x34, 0xe6, 0x43, ++ 0x1a, 0xfc, 0xb9, 0xa4, 0xeb, 0xe6, 0xe2, 0xf3, 0x9a, 0xbc, 0x30, 0x61, ++ 0xe3, 0x23, 0xda, 0x87, 0xb0, 0xdd, 0x64, 0xdd, 0xda, 0x4d, 0xa2, 0x0d, ++ 0x79, 0x8f, 0x3a, 0x6b, 0xfc, 0x0a, 0x7d, 0xca, 0x20, 0xfa, 0x29, 0xce, ++ 0x1a, 0x92, 0x73, 0xe0, 0xab, 0x9d, 0xb7, 0x69, 0x79, 0xad, 0xc9, 0x52, ++ 0x78, 0x5d, 0x59, 0x3a, 0x68, 0x78, 0xf6, 0x1a, 0xbe, 0x05, 0xfe, 0x67, ++ 0x62, 0xd6, 0x4a, 0xf9, 0xb2, 0x54, 0x9c, 0x7a, 0x2b, 0xb2, 0xe4, 0xb7, ++ 0x8f, 0x40, 0x76, 0xfd, 0x31, 0xd6, 0xd2, 0xec, 0xd7, 0x01, 0x8d, 0xa5, ++ 0xac, 0xc6, 0x28, 0x1c, 0xc7, 0xf3, 0x0d, 0x73, 0xab, 0x7c, 0xc3, 0x61, ++ 0xb4, 0x95, 0x40, 0xae, 0xa7, 0x59, 0xf6, 0xcd, 0xfa, 0x7d, 0x1c, 0x56, ++ 0x32, 0xbb, 0x77, 0xca, 0x32, 0x87, 0x82, 0x92, 0x19, 0x9a, 0x19, 0x90, ++ 0xc1, 0x6a, 0x07, 0xd6, 0xf4, 0x0d, 0x17, 0xbe, 0xf3, 0xdd, 0x61, 0xb1, ++ 0x61, 0x17, 0x31, 0xe7, 0x7e, 0xf0, 0xb8, 0x1a, 0x16, 0x23, 0xed, 0x20, ++ 0xad, 0xc7, 0x58, 0xa1, 0xd0, 0xd0, 0xaa, 0x7c, 0x03, 0xea, 0xa0, 0xef, ++ 0xfe, 0xb5, 0xf5, 0x20, 0x9f, 0xe0, 0x6d, 0xd6, 0x79, 0xd3, 0x85, 0x1f, ++ 0xd6, 0x3e, 0x8b, 0xa5, 0xb4, 0x13, 0xbe, 0x8d, 0xf8, 0x10, 0xf4, 0x5b, ++ 0xe9, 0x42, 0xc1, 0x48, 0xef, 0x47, 0x1f, 0xa2, 0xe4, 0xb4, 0x58, 0x7d, ++ 0xda, 0xd7, 0x7b, 0x55, 0xbe, 0xa3, 0x9f, 0xb2, 0x37, 0x07, 0x4c, 0xc0, ++ 0x39, 0x2d, 0x28, 0x5d, 0xcf, 0x99, 0x31, 0x99, 0x2c, 0x29, 0x4c, 0x23, ++ 0xc9, 0xca, 0x1f, 0x49, 0xee, 0xb4, 0xc8, 0x37, 0xa7, 0x58, 0xef, 0x05, ++ 0x5d, 0xef, 0x79, 0xd4, 0x4b, 0x26, 0x06, 0x03, 0x16, 0xfc, 0x80, 0x05, ++ 0x35, 0xe9, 0x4d, 0x20, 0x35, 0x87, 0xf1, 0x1b, 0xa4, 0x93, 0x41, 0x3d, ++ 0x0f, 0x03, 0x3d, 0x0f, 0x7e, 0x88, 0xdc, 0x53, 0x6a, 0x84, 0x3d, 0xf9, ++ 0x2f, 0xa0, 0x35, 0x26, 0x5f, 0xc0, 0x3c, 0x2e, 0x4d, 0x11, 0x67, 0xbd, ++ 0x20, 0x8b, 0x53, 0xc4, 0x5d, 0xcf, 0xcb, 0xe4, 0x54, 0xd2, 0xf9, 0x26, ++ 0xf8, 0x7c, 0x4a, 0x38, 0x97, 0x5e, 0x07, 0x29, 0x30, 0xa0, 0x95, 0x78, ++ 0x1c, 0xf6, 0xac, 0x67, 0xab, 0xd7, 0x5f, 0x97, 0xee, 0xcf, 0xae, 0x58, ++ 0x72, 0xc5, 0xa4, 0x7d, 0xba, 0x56, 0xc7, 0xb3, 0x5a, 0xc7, 0x47, 0x9d, ++ 0x0e, 0x31, 0xa0, 0xd7, 0x99, 0xb1, 0x02, 0xbc, 0x1f, 0xf5, 0xfa, 0x7f, ++ 0x1b, 0x35, 0xfc, 0x33, 0x00, 0xac, 0x6a, 0x29, 0x7f, 0xf7, 0xb7, 0xd3, ++ 0xf1, 0x7a, 0xdd, 0xe6, 0xf8, 0x2d, 0x68, 0x13, 0x42, 0x7a, 0x7d, 0xbd, ++ 0x46, 0x1f, 0x75, 0x6d, 0x07, 0xa8, 0x17, 0x68, 0xf3, 0x07, 0xe0, 0x05, ++ 0xf9, 0xff, 0x56, 0xf4, 0xb9, 0x37, 0xf8, 0x96, 0xf4, 0x79, 0xec, 0x7a, ++ 0xfa, 0x5c, 0xaf, 0xcb, 0x67, 0xc9, 0x0b, 0x8c, 0x2d, 0x33, 0x9e, 0x6c, ++ 0x75, 0x81, 0xd7, 0x09, 0xc8, 0x29, 0x68, 0x28, 0xfd, 0x8d, 0x9b, 0x09, ++ 0x79, 0x78, 0xce, 0x93, 0x27, 0xd6, 0xf3, 0xeb, 0x78, 0xb6, 0x77, 0xb0, ++ 0x7a, 0x45, 0xd9, 0xd9, 0x73, 0xca, 0xce, 0x5a, 0x87, 0x0b, 0x42, 0x79, ++ 0xbb, 0x2d, 0x48, 0xbe, 0x3f, 0xed, 0x7c, 0x16, 0x34, 0x5a, 0x89, 0x84, ++ 0xd1, 0x55, 0x30, 0x8c, 0xcf, 0xca, 0xfe, 0xf9, 0x87, 0x65, 0x7f, 0x89, ++ 0x7d, 0xa4, 0xf1, 0xde, 0x46, 0x59, 0x13, 0x6c, 0x2d, 0x6d, 0xfa, 0x1b, ++ 0x01, 0x6f, 0x2c, 0x03, 0xfe, 0x6b, 0x29, 0x70, 0x4f, 0xf5, 0x62, 0x20, ++ 0x3b, 0x4f, 0xdd, 0x45, 0x79, 0xb5, 0xde, 0xe6, 0xfb, 0xf6, 0xbe, 0x66, ++ 0xff, 0x06, 0x4b, 0x93, 0xc4, 0x80, 0x46, 0xd6, 0xe1, 0x9a, 0x51, 0x37, ++ 0x2f, 0x98, 0xde, 0x9c, 0x3f, 0x09, 0x3e, 0x51, 0xaf, 0xc9, 0x37, 0xf8, ++ 0xc0, 0x10, 0x75, 0x96, 0xcf, 0xe2, 0x06, 0xd3, 0xd4, 0x3b, 0x09, 0x05, ++ 0x41, 0x46, 0x2e, 0xc6, 0x3a, 0x77, 0x80, 0xce, 0xb5, 0x3a, 0xcd, 0x75, ++ 0x14, 0x6d, 0x43, 0x58, 0x36, 0x80, 0xe7, 0x4e, 0x19, 0x9f, 0xcf, 0x60, ++ 0xcc, 0x3b, 0x75, 0xdf, 0xab, 0x7c, 0x0c, 0xfa, 0x48, 0xe8, 0xf5, 0xd8, ++ 0xe0, 0xdb, 0x41, 0x94, 0x39, 0xba, 0xac, 0xa1, 0xae, 0xcc, 0x5f, 0xb7, ++ 0x8f, 0x62, 0x7c, 0xfa, 0x8a, 0x61, 0x8d, 0x7f, 0x5c, 0x37, 0xc7, 0xf5, ++ 0xee, 0xfb, 0x87, 0x42, 0xdd, 0xb8, 0x50, 0x2a, 0x98, 0x41, 0x25, 0xa3, ++ 0x2f, 0xfc, 0x4e, 0x4d, 0x46, 0x81, 0x97, 0x55, 0x2f, 0xe4, 0x31, 0x69, ++ 0x69, 0x06, 0x4f, 0x07, 0x41, 0x2b, 0x78, 0xd7, 0x1e, 0x00, 0xff, 0x9a, ++ 0x25, 0x5f, 0x4d, 0xeb, 0x77, 0x2c, 0x0f, 0xc9, 0x68, 0xcc, 0xf7, 0x47, ++ 0xb7, 0x99, 0x1e, 0xe6, 0x45, 0x9d, 0xd2, 0x8f, 0x83, 0x9e, 0x0e, 0x98, ++ 0x92, 0x3f, 0x39, 0x08, 0x59, 0x23, 0x26, 0x6b, 0x80, 0xac, 0xc5, 0x94, ++ 0xad, 0x37, 0x6c, 0xd6, 0xc7, 0xbb, 0xd3, 0xbf, 0x17, 0xf4, 0xda, 0xb0, ++ 0x9e, 0xdf, 0xc6, 0x1f, 0xbb, 0x6d, 0xa5, 0xed, 0xa8, 0x63, 0x48, 0x50, ++ 0x8d, 0x8f, 0xb2, 0xd3, 0xab, 0xc7, 0x37, 0xda, 0xfd, 0xf1, 0x1f, 0xd1, ++ 0x7d, 0xb5, 0xd5, 0xf5, 0x15, 0xbb, 0xce, 0xf8, 0x78, 0x77, 0xfa, 0xa3, ++ 0x9b, 0xbd, 0x36, 0xb1, 0xba, 0x36, 0xed, 0x6b, 0xda, 0xb0, 0xbe, 0x3f, ++ 0x06, 0xde, 0x9d, 0xbe, 0xab, 0xd9, 0x6b, 0xc3, 0x7a, 0x0d, 0xf0, 0x6d, ++ 0x7c, 0x47, 0xd9, 0xdf, 0x5f, 0x27, 0xfb, 0xfb, 0x21, 0xfb, 0xbe, 0x4c, ++ 0xad, 0xc5, 0xc9, 0x7e, 0xbc, 0xc3, 0x38, 0x87, 0xd8, 0xaa, 0x16, 0xd7, ++ 0x84, 0x4e, 0x34, 0x03, 0xb7, 0xb4, 0x30, 0x96, 0xd1, 0xb8, 0x98, 0xb1, ++ 0x0d, 0x71, 0xb0, 0xd8, 0x21, 0xe9, 0x82, 0x8d, 0xea, 0x8a, 0xef, 0xa3, ++ 0xc2, 0x55, 0x62, 0x0a, 0x2f, 0x67, 0xf4, 0x18, 0x8c, 0x6b, 0xc8, 0x77, ++ 0xe6, 0x73, 0x2b, 0x71, 0x4e, 0x07, 0xe2, 0x20, 0xe2, 0x5d, 0xe2, 0x25, ++ 0x9f, 0x7e, 0x9f, 0x9e, 0x03, 0x46, 0x4d, 0x27, 0x32, 0xc6, 0x60, 0x75, ++ 0xd0, 0xf0, 0x74, 0x82, 0xef, 0x0f, 0x68, 0x9f, 0xb6, 0x96, 0xde, 0xb7, ++ 0xaf, 0xa1, 0x97, 0xb8, 0x2a, 0x21, 0x13, 0x90, 0x91, 0xd0, 0x09, 0xda, ++ 0xd8, 0xe7, 0x46, 0x16, 0x67, 0x89, 0x1f, 0xfa, 0xc0, 0x17, 0xd2, 0x4b, ++ 0xfe, 0x51, 0x97, 0x5b, 0x60, 0x1f, 0xba, 0x52, 0x65, 0xd4, 0x67, 0x7c, ++ 0x3d, 0xae, 0xe2, 0xb2, 0x66, 0xa4, 0x08, 0x9e, 0x40, 0xeb, 0x38, 0x68, ++ 0x1d, 0xd7, 0x31, 0xd9, 0x3e, 0xd8, 0xef, 0xd0, 0xb4, 0x4f, 0xeb, 0x8d, ++ 0x21, 0x7f, 0x6d, 0x56, 0xd3, 0x5e, 0xef, 0x77, 0x3c, 0xfc, 0x75, 0x4f, ++ 0x0f, 0x65, 0xc6, 0x2a, 0x10, 0xb3, 0x8d, 0x2b, 0xf9, 0x00, 0xf6, 0x33, ++ 0xc4, 0xd3, 0xa5, 0x16, 0xdf, 0xff, 0x72, 0x3e, 0xf4, 0xff, 0xd4, 0x79, ++ 0x7f, 0x0e, 0xcd, 0xd2, 0x79, 0x82, 0x73, 0x58, 0xa1, 0x3f, 0xc6, 0xdd, ++ 0x8d, 0xfd, 0xb0, 0x9b, 0x79, 0x45, 0xeb, 0x4e, 0xd9, 0x5b, 0x7a, 0xa7, ++ 0xa6, 0xbf, 0x19, 0xf4, 0x8f, 0x42, 0xb6, 0x6b, 0x36, 0x23, 0x5f, 0x19, ++ 0x43, 0xde, 0xc3, 0x62, 0xe4, 0x71, 0xbe, 0x42, 0xfb, 0xa1, 0xe7, 0x13, ++ 0xe5, 0x7c, 0xd6, 0xda, 0x96, 0xf5, 0xf8, 0xfa, 0x8e, 0x35, 0x7c, 0x15, ++ 0xcd, 0xd7, 0x88, 0x34, 0x9c, 0x50, 0x71, 0x2d, 0xfa, 0x25, 0xaf, 0xe9, ++ 0xbf, 0x9e, 0x1b, 0x99, 0x9c, 0x95, 0xbe, 0xb0, 0x90, 0xbe, 0x38, 0xcb, ++ 0xfa, 0x1b, 0xa4, 0xcb, 0xb9, 0x88, 0x79, 0xe7, 0xb1, 0xde, 0xc6, 0xb4, ++ 0x27, 0xdf, 0xe4, 0x6f, 0xbe, 0x12, 0x45, 0x2c, 0xcd, 0xb1, 0xc9, 0x33, ++ 0xd2, 0x6f, 0x2a, 0x7a, 0x56, 0xf8, 0x0d, 0xfa, 0x3e, 0x56, 0x59, 0xcb, ++ 0xdb, 0x7a, 0x3b, 0xe3, 0xc7, 0xec, 0xdf, 0x35, 0x3d, 0xbd, 0x58, 0x2f, ++ 0x66, 0x6f, 0x86, 0x7d, 0x0c, 0xd1, 0x36, 0x82, 0xf7, 0xdc, 0x5f, 0x59, ++ 0x0a, 0x11, 0x83, 0x5f, 0x28, 0x85, 0x95, 0xcd, 0xcb, 0x3a, 0x2d, 0x5a, ++ 0x3f, 0x6e, 0xd3, 0xbe, 0x23, 0xac, 0x6c, 0xb6, 0x18, 0x26, 0x71, 0x09, ++ 0xca, 0x90, 0x9f, 0x67, 0xde, 0xa7, 0xe3, 0xde, 0x5d, 0x61, 0xfb, 0x0f, ++ 0x43, 0xbe, 0x4d, 0xa8, 0xd1, 0x55, 0x1f, 0x93, 0xbb, 0xc0, 0x72, 0xef, ++ 0x84, 0xdc, 0xde, 0x89, 0xb8, 0x3b, 0x21, 0xf9, 0x14, 0xf5, 0x68, 0x40, ++ 0xc5, 0x26, 0x86, 0xbd, 0x0f, 0x65, 0x4d, 0x28, 0x83, 0x13, 0x33, 0x31, ++ 0x7f, 0xfb, 0x77, 0x65, 0x1c, 0x32, 0x9e, 0x4f, 0xf5, 0x82, 0x0e, 0xda, ++ 0x60, 0x60, 0x1c, 0x3b, 0xc5, 0xb8, 0x1d, 0x7f, 0xfd, 0x61, 0x6f, 0x5e, ++ 0xbb, 0x90, 0x47, 0x0c, 0x9f, 0xea, 0xd4, 0x75, 0x36, 0x08, 0xf7, 0x7f, ++ 0xf2, 0x66, 0x0b, 0xd2, 0xee, 0x35, 0x75, 0xdf, 0x8f, 0xfc, 0x7b, 0x75, ++ 0xff, 0x05, 0xbc, 0xdf, 0x86, 0xdf, 0x20, 0xca, 0x6e, 0x47, 0x99, 0x83, ++ 0xb2, 0xf7, 0x20, 0xff, 0x7e, 0xbd, 0x1f, 0xe0, 0xb7, 0x69, 0x41, 0xfe, ++ 0x31, 0xbc, 0x87, 0xad, 0x30, 0x5f, 0xc6, 0xfb, 0xf7, 0xe2, 0xf7, 0xee, ++ 0x35, 0x75, 0xda, 0xd6, 0xe4, 0x3f, 0xb5, 0xc2, 0x83, 0x0b, 0xa5, 0x9f, ++ 0x69, 0xbb, 0x46, 0x79, 0x66, 0xfe, 0x94, 0x7e, 0xf7, 0xce, 0xd0, 0xea, ++ 0xf2, 0x1d, 0x7e, 0xbe, 0x6e, 0x0d, 0x3b, 0xb1, 0x86, 0x3e, 0xc6, 0x7c, ++ 0xbb, 0xf6, 0x5d, 0x6f, 0xf7, 0xe2, 0xf4, 0x92, 0xdf, 0x8e, 0x7e, 0xed, ++ 0xce, 0x35, 0x63, 0x3c, 0xdf, 0x50, 0xcb, 0x37, 0x07, 0x86, 0x4e, 0xb2, ++ 0xec, 0x72, 0xc3, 0xea, 0x3a, 0x6f, 0xd6, 0xe5, 0x37, 0x06, 0x86, 0x94, ++ 0x8f, 0xbb, 0xab, 0x71, 0x75, 0x9d, 0x64, 0x63, 0x6d, 0x1e, 0x35, 0x5b, ++ 0x18, 0x4a, 0x2f, 0x53, 0x8e, 0xa1, 0x0b, 0xdf, 0x1a, 0xc9, 0x4e, 0xb9, ++ 0xee, 0x84, 0xb3, 0x14, 0x0f, 0x0a, 0x7d, 0x10, 0xb1, 0x2a, 0xcb, 0x5f, ++ 0x46, 0x39, 0xb0, 0x4c, 0x75, 0x54, 0x68, 0x93, 0xd6, 0xc7, 0xa4, 0x09, ++ 0x8d, 0x49, 0x55, 0x36, 0x94, 0x55, 0x18, 0xf2, 0xf9, 0x11, 0x60, 0x1e, ++ 0xfd, 0xfc, 0x02, 0x9e, 0x13, 0xf5, 0xb8, 0x17, 0xfd, 0x2e, 0x8d, 0x64, ++ 0x67, 0xe9, 0xf3, 0x2e, 0x8e, 0xec, 0x99, 0xa5, 0xce, 0x5f, 0x82, 0xce, ++ 0x07, 0x64, 0x52, 0xf9, 0x3f, 0xd2, 0xc1, 0x76, 0x4b, 0x23, 0x9d, 0x0b, ++ 0x4c, 0x97, 0x47, 0xec, 0x85, 0xa0, 0xec, 0x8b, 0x79, 0x6d, 0x99, 0x4f, ++ 0x2c, 0xf8, 0x3a, 0x10, 0x95, 0x70, 0x9a, 0x32, 0x69, 0xa5, 0x80, 0xbd, ++ 0x31, 0x9f, 0x27, 0x47, 0x26, 0x6d, 0xca, 0xe7, 0x87, 0x1a, 0xa4, 0x25, ++ 0x2a, 0x0d, 0xca, 0xde, 0x3c, 0xa5, 0xc7, 0xba, 0x84, 0xb1, 0x36, 0x29, ++ 0x7d, 0xca, 0xda, 0xa1, 0x38, 0xc6, 0x39, 0x68, 0xd8, 0xbd, 0x18, 0x8f, ++ 0x91, 0x72, 0x87, 0x4c, 0x54, 0xa9, 0x37, 0xdb, 0xc2, 0xb5, 0xf8, 0xf8, ++ 0x3c, 0xda, 0xf9, 0x71, 0x19, 0xc7, 0x2b, 0x03, 0x97, 0x41, 0x96, 0xd3, ++ 0x96, 0x99, 0x0d, 0xc2, 0xcf, 0xcf, 0xfa, 0x75, 0x48, 0xd3, 0xd9, 0x91, ++ 0xe4, 0x42, 0x12, 0x7d, 0x75, 0xd0, 0x86, 0xc1, 0x76, 0x05, 0xf1, 0x63, ++ 0xdf, 0x6c, 0x07, 0x5f, 0x34, 0x40, 0x3f, 0x72, 0x1e, 0x7e, 0xa4, 0x43, ++ 0x0e, 0x95, 0x54, 0x1f, 0x09, 0xf6, 0x51, 0xd4, 0x6d, 0x3b, 0x17, 0x1a, ++ 0x10, 0xdb, 0x24, 0xcd, 0x17, 0xa5, 0xd6, 0x76, 0x48, 0xbc, 0x76, 0x5e, ++ 0xdf, 0x3f, 0x77, 0x33, 0xb1, 0x7a, 0xdd, 0x8f, 0x4a, 0x10, 0x74, 0xe4, ++ 0xd0, 0x07, 0xc7, 0xaf, 0xf5, 0xed, 0xf7, 0x97, 0x34, 0x97, 0xaf, 0xe9, ++ 0x6b, 0x93, 0x8e, 0xb9, 0xac, 0x44, 0xee, 0xd7, 0x1a, 0x5b, 0xc5, 0x00, ++ 0x90, 0x07, 0x09, 0xe5, 0x7a, 0x60, 0x17, 0xab, 0x03, 0x5a, 0x46, 0x5e, ++ 0x40, 0x59, 0x7d, 0x6c, 0xe3, 0xc9, 0x57, 0x01, 0x98, 0xae, 0x08, 0x3d, ++ 0x0f, 0xa6, 0x33, 0xad, 0xde, 0x5e, 0xd3, 0xf5, 0xe2, 0x19, 0xc8, 0x0d, ++ 0xfa, 0x2c, 0xae, 0xb4, 0xe5, 0x9c, 0x5e, 0x18, 0xb9, 0x34, 0x15, 0xc7, ++ 0x9c, 0x3c, 0xbf, 0xe0, 0xf1, 0x9a, 0x3e, 0x27, 0x20, 0x8b, 0x76, 0x02, ++ 0x71, 0x33, 0x7d, 0x7c, 0x42, 0x5e, 0xb2, 0x7d, 0xff, 0x43, 0x5f, 0x84, ++ 0xfa, 0x55, 0xd2, 0x46, 0xda, 0xcf, 0x63, 0x6e, 0xae, 0xcc, 0x38, 0x9e, ++ 0x0c, 0xf6, 0xc0, 0x8f, 0x7c, 0x23, 0x64, 0x1d, 0x66, 0x7c, 0x75, 0x25, ++ 0x54, 0x3f, 0x1f, 0x1f, 0x2b, 0x3c, 0xaf, 0xf7, 0x7e, 0xcf, 0x6b, 0x79, ++ 0x59, 0x82, 0xbc, 0xf4, 0x26, 0x4c, 0xe9, 0x06, 0xed, 0xa8, 0xd3, 0xd7, ++ 0x85, 0x38, 0x87, 0x31, 0x74, 0x1c, 0xf4, 0x98, 0xb0, 0x1d, 0x9b, 0x34, ++ 0x66, 0xff, 0x77, 0x61, 0xfa, 0xb6, 0x56, 0xb5, 0xaf, 0x7c, 0x5e, 0xc9, ++ 0xb3, 0x27, 0xdf, 0x41, 0xfd, 0xde, 0x97, 0xa9, 0x20, 0x21, 0x8d, 0xd4, ++ 0xf6, 0x4f, 0x59, 0xff, 0x39, 0x5d, 0xff, 0x59, 0xd4, 0x0f, 0x60, 0x4e, ++ 0xae, 0xbb, 0x57, 0xd1, 0xfb, 0x1c, 0xf8, 0x1e, 0x94, 0xe2, 0x8a, 0xcc, ++ 0x3f, 0x07, 0x99, 0xa7, 0x7c, 0x9f, 0x87, 0xbe, 0x82, 0xf8, 0x7b, 0x29, ++ 0xf7, 0x65, 0x19, 0x3c, 0x9d, 0x6b, 0xe0, 0x5e, 0x67, 0xc2, 0x60, 0xec, ++ 0x49, 0x99, 0xec, 0x90, 0xc7, 0x4b, 0x49, 0x73, 0xa2, 0x6e, 0x2d, 0x77, ++ 0xac, 0x5a, 0x4b, 0xca, 0x80, 0xaa, 0x9f, 0x62, 0xfd, 0x72, 0x9d, 0x0c, ++ 0xcc, 0xcf, 0x5e, 0xaf, 0x1d, 0x65, 0x80, 0xed, 0xd6, 0xc3, 0xe9, 0xdc, ++ 0x1b, 0x74, 0xdd, 0x45, 0x87, 0xfb, 0xb8, 0x8d, 0x52, 0x50, 0x32, 0x16, ++ 0x90, 0xa2, 0x43, 0xbd, 0xca, 0x26, 0x42, 0x62, 0x01, 0x2b, 0x7d, 0x10, ++ 0x74, 0x66, 0x52, 0x61, 0xf1, 0xf6, 0x12, 0xc6, 0xb1, 0x06, 0x4b, 0xa6, ++ 0xeb, 0x5e, 0xb2, 0x45, 0xca, 0x88, 0x3d, 0x17, 0x91, 0x16, 0x2b, 0xd0, ++ 0xd9, 0x68, 0x08, 0x36, 0xc0, 0x97, 0xf1, 0x88, 0xcc, 0xa1, 0xce, 0x3c, ++ 0xde, 0x3d, 0x5e, 0xf1, 0x25, 0xc6, 0x75, 0x0d, 0xf0, 0x68, 0x8f, 0xfd, ++ 0xff, 0xdc, 0x7c, 0xac, 0xbe, 0xae, 0x8f, 0x89, 0x89, 0x65, 0x89, 0x4d, ++ 0x89, 0x29, 0xf9, 0x8e, 0x38, 0xf1, 0x20, 0x68, 0xa1, 0xce, 0xb6, 0x48, ++ 0x24, 0x6d, 0xc5, 0x87, 0xc5, 0xf7, 0xfd, 0x97, 0x21, 0x4b, 0x05, 0xb7, ++ 0xd1, 0xee, 0x90, 0x67, 0x20, 0x37, 0xe7, 0x57, 0x70, 0x4c, 0x02, 0x72, ++ 0x44, 0x3f, 0xea, 0xca, 0x39, 0xc7, 0x4e, 0x7c, 0x0e, 0xe9, 0xb7, 0x9d, ++ 0xdf, 0x22, 0xdf, 0x9e, 0x10, 0xe9, 0x43, 0x2c, 0x04, 0xbb, 0x3e, 0xe3, ++ 0x63, 0xfb, 0x16, 0xc6, 0x64, 0x5a, 0x96, 0xae, 0xa0, 0x4f, 0xcb, 0x34, ++ 0x00, 0x6a, 0xef, 0x42, 0x3d, 0x4f, 0x37, 0xfc, 0xb2, 0x83, 0xa8, 0x4b, ++ 0x1a, 0x18, 0x2f, 0x7f, 0x07, 0x3a, 0xeb, 0xba, 0xf7, 0x39, 0x8b, 0x75, ++ 0xb6, 0xe6, 0x39, 0xac, 0xbf, 0x92, 0xf3, 0xfe, 0x56, 0xe1, 0xfe, 0xaa, ++ 0xf4, 0xb5, 0xa9, 0x78, 0x8e, 0xcf, 0x90, 0xf7, 0x7e, 0x62, 0xa1, 0x84, ++ 0xc2, 0x9a, 0xc4, 0x0d, 0xe7, 0xc1, 0xfb, 0x4f, 0x2a, 0x4c, 0x43, 0xfc, ++ 0x06, 0xfa, 0x4b, 0xc4, 0x14, 0x1e, 0x96, 0xf6, 0x70, 0x1d, 0xb1, 0x45, ++ 0x0a, 0x6b, 0xe3, 0xe3, 0x0b, 0xb6, 0x65, 0x3d, 0xb6, 0xad, 0x5f, 0x3f, ++ 0xd6, 0xd9, 0x14, 0xc8, 0x1d, 0xa3, 0x3c, 0xd3, 0x3f, 0xb6, 0xca, 0xbe, ++ 0x54, 0x23, 0xf8, 0xde, 0xa6, 0xfd, 0xf8, 0xfb, 0x80, 0xd9, 0x80, 0xbd, ++ 0x4d, 0xcb, 0xa9, 0xd9, 0x9e, 0xf7, 0xa0, 0xec, 0x17, 0xe0, 0x3f, 0xcb, ++ 0xf6, 0x37, 0x78, 0x7e, 0xf2, 0x61, 0xe8, 0xf2, 0xdc, 0x26, 0x6f, 0xef, ++ 0x8a, 0xeb, 0xe0, 0xe3, 0x04, 0x1f, 0xf7, 0x99, 0x1a, 0xef, 0x73, 0x6d, ++ 0xbc, 0x7d, 0x2e, 0x43, 0xd5, 0x65, 0xac, 0x55, 0x1f, 0x5b, 0x52, 0x87, ++ 0x5d, 0xf7, 0x9c, 0xe3, 0xe3, 0xc8, 0xed, 0xf0, 0xa1, 0x21, 0xcd, 0xeb, ++ 0x66, 0xf0, 0x9a, 0x18, 0x25, 0x22, 0x89, 0x36, 0x62, 0x8a, 0x07, 0x1b, ++ 0x6a, 0x58, 0xe6, 0x6f, 0xdc, 0xa0, 0xcd, 0x78, 0x8f, 0x38, 0x86, 0xb4, ++ 0x6f, 0xd7, 0x78, 0x86, 0xd8, 0xe6, 0x31, 0x8c, 0x11, 0x94, 0x44, 0x3b, ++ 0xf3, 0x7f, 0xa9, 0xdb, 0xf0, 0xd9, 0x95, 0xee, 0xad, 0xf5, 0xf2, 0x3c, ++ 0x00, 0x3a, 0x39, 0x1f, 0x7f, 0xef, 0xb5, 0x43, 0xd9, 0x93, 0x9a, 0x5c, ++ 0xf8, 0x34, 0xf9, 0xe3, 0x92, 0xb6, 0xb8, 0xb4, 0x81, 0xb6, 0x7b, 0xe0, ++ 0x53, 0xb6, 0xb6, 0xb1, 0x4f, 0x7f, 0xec, 0x7a, 0x9a, 0xea, 0xf1, 0x55, ++ 0x02, 0x63, 0x34, 0xca, 0xd6, 0x76, 0xf2, 0xae, 0x43, 0xf9, 0x96, 0xda, ++ 0x7a, 0xd0, 0xf7, 0x73, 0xec, 0xb5, 0xe5, 0xef, 0xad, 0xa3, 0x6b, 0x2d, ++ 0xe6, 0xdb, 0x86, 0x77, 0xa4, 0xc9, 0x84, 0x5d, 0x72, 0x65, 0x87, 0xe3, ++ 0xe3, 0xbb, 0x7a, 0x3a, 0x88, 0xf1, 0x48, 0x33, 0x69, 0xf0, 0x31, 0x39, ++ 0x7f, 0x5c, 0x1b, 0xd2, 0x93, 0xd6, 0xe7, 0x44, 0xfb, 0xf5, 0xbc, 0x6e, ++ 0xd3, 0x75, 0x92, 0x68, 0xfb, 0xc7, 0x98, 0x03, 0x9f, 0x39, 0x0f, 0x1f, ++ 0x1b, 0x26, 0xbd, 0x7e, 0xa2, 0xeb, 0xc5, 0x00, 0xd4, 0x19, 0x9f, 0x4f, ++ 0x6d, 0x7a, 0x8d, 0xb6, 0xaf, 0x19, 0xd7, 0x72, 0x56, 0xdb, 0x91, 0xf7, ++ 0xd4, 0xcd, 0xaf, 0x4f, 0x0a, 0xf3, 0x94, 0x8b, 0x77, 0x21, 0xf5, 0x63, ++ 0xa3, 0x7e, 0xf8, 0x91, 0x0c, 0x62, 0x21, 0xc6, 0x48, 0xd7, 0xc4, 0x47, ++ 0x3c, 0x47, 0x1c, 0xcb, 0x23, 0x5e, 0x56, 0x7e, 0xc4, 0xf3, 0x91, 0xc8, ++ 0xc3, 0x9e, 0x54, 0xef, 0xa5, 0x8c, 0x8d, 0x8d, 0x57, 0x9c, 0xb1, 0xbd, ++ 0x95, 0xfe, 0x31, 0xc6, 0x11, 0x9e, 0xcc, 0xa1, 0x7e, 0x45, 0xc6, 0x0d, ++ 0xb4, 0xcb, 0xaa, 0x76, 0x6a, 0x1f, 0x68, 0x9d, 0x7e, 0x84, 0xfa, 0x38, ++ 0xee, 0x8d, 0x15, 0x19, 0xcb, 0xc1, 0x06, 0xcd, 0xcf, 0xc0, 0xc7, 0xd9, ++ 0x56, 0x86, 0x72, 0xb9, 0xc7, 0xb1, 0x86, 0x95, 0xec, 0xc5, 0xac, 0x51, ++ 0xae, 0x65, 0x79, 0xe6, 0x1d, 0xb0, 0xa1, 0xae, 0xdc, 0x0d, 0x5b, 0xf8, ++ 0x10, 0x64, 0x55, 0xce, 0xc0, 0x10, 0x9e, 0x81, 0xf1, 0x3a, 0x13, 0x13, ++ 0xe3, 0x78, 0x87, 0x84, 0x8f, 0xc4, 0x25, 0x74, 0x84, 0xb1, 0x58, 0xd2, ++ 0xbc, 0x5b, 0x04, 0x3e, 0xf1, 0xc5, 0xdb, 0x0d, 0xb1, 0x06, 0x32, 0x92, ++ 0x44, 0x3c, 0xd9, 0x6b, 0x96, 0x91, 0x16, 0x25, 0x99, 0x3a, 0x8d, 0xbe, ++ 0xc2, 0x67, 0x50, 0x17, 0xed, 0x9a, 0x16, 0x13, 0xf8, 0xb5, 0x4b, 0x74, ++ 0xd1, 0xd3, 0x95, 0xe8, 0xe2, 0xea, 0x3d, 0x94, 0xc1, 0x95, 0x3d, 0x14, ++ 0xbe, 0x7f, 0x43, 0xef, 0xfd, 0x3c, 0xab, 0xe3, 0x1a, 0xca, 0x08, 0x7d, ++ 0x9b, 0x8a, 0xcd, 0x60, 0xc7, 0x9f, 0x45, 0x2c, 0x6c, 0x4b, 0xae, 0x04, ++ 0xcc, 0x9e, 0x76, 0xe5, 0x29, 0xa7, 0xe0, 0x66, 0xfb, 0x5d, 0xb9, 0xec, ++ 0xd8, 0x85, 0xbc, 0x58, 0x6f, 0xd0, 0xde, 0xfd, 0x4f, 0xe7, 0xfd, 0xb2, ++ 0xab, 0xd5, 0xda, 0x95, 0x09, 0x14, 0xdc, 0x66, 0x3b, 0x2a, 0x37, 0xa5, ++ 0x0f, 0xca, 0x9e, 0x2d, 0x4b, 0x66, 0x50, 0x32, 0x37, 0x01, 0x17, 0xc6, ++ 0xf3, 0xca, 0x56, 0xbd, 0xa6, 0xe2, 0xeb, 0x07, 0xba, 0x0e, 0xca, 0xc6, ++ 0x2d, 0x96, 0x79, 0x35, 0x48, 0xcc, 0x76, 0x10, 0xb1, 0x80, 0x15, 0xcf, ++ 0x05, 0x6d, 0x73, 0xa7, 0x58, 0xc3, 0x9f, 0x16, 0x9e, 0xdb, 0xda, 0xd2, ++ 0x79, 0xc4, 0x8e, 0x7f, 0x22, 0xd0, 0xbd, 0xff, 0x13, 0x8c, 0xef, 0xce, ++ 0x30, 0xef, 0x4a, 0x64, 0x8b, 0x89, 0xe7, 0x98, 0x74, 0x1e, 0x4f, 0x48, ++ 0x12, 0x7c, 0xe9, 0x51, 0x3c, 0xe1, 0xf9, 0x51, 0x5c, 0xba, 0x8f, 0x10, ++ 0x43, 0x29, 0xde, 0xf4, 0x80, 0x37, 0x29, 0xf0, 0x06, 0x31, 0x55, 0xaf, ++ 0x79, 0x15, 0xe9, 0xb2, 0x24, 0x07, 0x7e, 0x00, 0xde, 0xf4, 0x80, 0x37, ++ 0xdd, 0x67, 0x12, 0x68, 0x8f, 0x3e, 0x16, 0x3b, 0x91, 0x46, 0xe5, 0x83, ++ 0x37, 0xb4, 0xe3, 0xd9, 0x96, 0xe4, 0x91, 0x08, 0xc6, 0x08, 0xc8, 0x8e, ++ 0xae, 0x82, 0x0c, 0x6d, 0x41, 0x6c, 0x16, 0x3b, 0x28, 0x17, 0xe1, 0x87, ++ 0x4a, 0x88, 0x11, 0x9e, 0x1a, 0xb0, 0x46, 0x97, 0x60, 0x4b, 0xab, 0xf7, ++ 0xb8, 0xf2, 0xf2, 0x96, 0xbf, 0x70, 0xe3, 0x37, 0x58, 0xbb, 0x24, 0xd0, ++ 0x2f, 0x93, 0x25, 0xe5, 0x1f, 0xe2, 0xd9, 0xa0, 0xc2, 0x65, 0x98, 0x63, ++ 0x01, 0x3e, 0x86, 0xe7, 0xd1, 0x36, 0x6c, 0xfd, 0xa7, 0xe5, 0xa1, 0xb9, ++ 0x09, 0xfc, 0x10, 0x6f, 0x4e, 0xb1, 0xee, 0x7e, 0xc4, 0x73, 0x0f, 0xcb, ++ 0xbe, 0x29, 0x60, 0xc7, 0x34, 0xe8, 0xee, 0xb7, 0x11, 0xcf, 0xcd, 0x37, ++ 0x4a, 0x0b, 0xca, 0xc0, 0xdb, 0xd1, 0xea, 0xda, 0x38, 0x6e, 0x09, 0xeb, ++ 0x30, 0x20, 0x7f, 0x56, 0xed, 0x97, 0xaf, 0x55, 0xfb, 0xe4, 0x4f, 0xe0, ++ 0x5b, 0xce, 0x57, 0x3b, 0xa0, 0x2b, 0x71, 0xac, 0x49, 0x1a, 0xeb, 0xe3, ++ 0xc8, 0x73, 0xd5, 0x94, 0x3c, 0x0b, 0x5e, 0x3d, 0x83, 0xdf, 0x50, 0x29, ++ 0x25, 0x3b, 0x4a, 0x7d, 0x7a, 0x8d, 0xb8, 0x3e, 0x36, 0xe8, 0xb1, 0x31, ++ 0x77, 0xeb, 0xc9, 0x02, 0xf4, 0x6f, 0xbe, 0x6a, 0xbf, 0x5e, 0x96, 0x8f, ++ 0x37, 0x72, 0x8f, 0xf7, 0xd4, 0x8a, 0x7f, 0x29, 0xb8, 0xa6, 0x6d, 0x1d, ++ 0x1e, 0xc7, 0x3a, 0x94, 0xa1, 0xa7, 0xa3, 0x8a, 0xf7, 0x35, 0xdf, 0x53, ++ 0xf6, 0x7c, 0x8f, 0x3f, 0xbf, 0x99, 0xbc, 0x7c, 0x5b, 0xb2, 0x47, 0x27, ++ 0x65, 0xcf, 0x31, 0x57, 0x3e, 0xec, 0xb8, 0x90, 0x63, 0xda, 0xe2, 0x7e, ++ 0xda, 0xf8, 0xc4, 0x78, 0xd0, 0x50, 0xb1, 0x94, 0x87, 0x5b, 0x7a, 0x37, ++ 0x43, 0x67, 0x53, 0x19, 0x63, 0x42, 0x92, 0x47, 0x27, 0xa4, 0xf3, 0x28, ++ 0x64, 0xc1, 0x61, 0x5f, 0x4b, 0xa6, 0x71, 0x8d, 0x3c, 0x70, 0x1c, 0x6b, ++ 0x20, 0x27, 0xb6, 0xf9, 0xba, 0xa4, 0x30, 0xfe, 0x01, 0xe9, 0x42, 0x1b, ++ 0x1b, 0x6d, 0xae, 0xaa, 0xb1, 0x9b, 0x31, 0x76, 0xa3, 0x1c, 0x8a, 0x59, ++ 0x90, 0x35, 0xfa, 0xf0, 0xff, 0x25, 0xd9, 0x32, 0xd3, 0x9f, 0x4a, 0xf6, ++ 0xd4, 0x47, 0x23, 0x12, 0xe5, 0x33, 0x4c, 0xc3, 0x09, 0x96, 0x77, 0x22, ++ 0x65, 0xb9, 0x8d, 0x38, 0xfa, 0xe7, 0x92, 0x3d, 0xcb, 0xb1, 0x5f, 0x47, ++ 0xf9, 0xcb, 0x92, 0x9d, 0xfe, 0x05, 0xf2, 0x17, 0x91, 0xbe, 0x81, 0x74, ++ 0x54, 0x3a, 0xa7, 0x25, 0x90, 0x3d, 0xfb, 0x2d, 0xe4, 0x43, 0x48, 0x0f, ++ 0xa1, 0xde, 0x76, 0xd0, 0xf7, 0xa7, 0xe8, 0x2f, 0x03, 0x9b, 0xf7, 0x3b, ++ 0x9a, 0x7e, 0x96, 0xb3, 0x8c, 0xef, 0x0e, 0xc1, 0xa6, 0xfd, 0x67, 0xd8, ++ 0x34, 0xfd, 0x3c, 0xcf, 0x3c, 0x6d, 0x1b, 0x9f, 0x27, 0xc0, 0x93, 0x03, ++ 0xc8, 0xbb, 0xf2, 0xb0, 0x43, 0x7f, 0xb3, 0x4d, 0xc6, 0xcc, 0x82, 0x1b, ++ 0x05, 0xae, 0x68, 0x86, 0x1e, 0x4c, 0x6c, 0x5d, 0x5f, 0x0f, 0x0e, 0x77, ++ 0x1f, 0x94, 0xa6, 0x2d, 0xfe, 0xfc, 0xfd, 0xf9, 0xda, 0xe6, 0x4f, 0x14, ++ 0x1f, 0xac, 0xc2, 0x27, 0x84, 0xf3, 0xb0, 0xe3, 0x5f, 0x30, 0xba, 0x77, ++ 0x3d, 0x04, 0x3d, 0x30, 0xce, 0x32, 0xef, 0xe9, 0x81, 0x71, 0x16, 0xb6, ++ 0xe1, 0x04, 0x62, 0xc4, 0x13, 0x1d, 0xd2, 0x38, 0x5d, 0xd3, 0x83, 0x86, ++ 0xe9, 0x5f, 0xad, 0x07, 0x8d, 0x67, 0x51, 0xef, 0x2c, 0x79, 0x86, 0x3e, ++ 0x4e, 0x91, 0x67, 0xed, 0x48, 0x3f, 0x8d, 0xb9, 0x92, 0xf6, 0x46, 0xd0, ++ 0xee, 0xe1, 0xa2, 0xdb, 0x21, 0xef, 0x0f, 0x6c, 0x39, 0xa0, 0xcb, 0xff, ++ 0xd2, 0x1d, 0x8e, 0x59, 0x73, 0x12, 0x20, 0x4f, 0x51, 0xb7, 0x4c, 0x1e, ++ 0xde, 0xdc, 0x24, 0xd1, 0xfd, 0xd2, 0x49, 0xfe, 0x95, 0x77, 0x22, 0x5f, ++ 0x70, 0xc3, 0x76, 0xb3, 0xe6, 0x27, 0x70, 0x52, 0x3f, 0xcb, 0x5f, 0x85, ++ 0xcc, 0x10, 0xaf, 0xbe, 0x26, 0x7b, 0xa6, 0x5c, 0x19, 0x73, 0x38, 0xff, ++ 0xef, 0x63, 0xfe, 0x99, 0x2d, 0x31, 0x59, 0x4a, 0xc4, 0xc0, 0x93, 0x79, ++ 0xd8, 0xf6, 0x8b, 0xe2, 0xf1, 0x81, 0xe7, 0x02, 0x3b, 0xc4, 0x8e, 0x0f, ++ 0x89, 0x9d, 0xfa, 0x01, 0xf8, 0x30, 0x04, 0xd9, 0xcf, 0x55, 0x29, 0x3b, ++ 0xaf, 0xc8, 0x20, 0x64, 0xe2, 0x7b, 0x8e, 0x95, 0x02, 0x16, 0x82, 0xbd, ++ 0xa0, 0x5c, 0x50, 0x26, 0x5a, 0x94, 0x4d, 0x3a, 0xe1, 0x58, 0x4f, 0x94, ++ 0xe5, 0x56, 0x39, 0xd1, 0x46, 0xda, 0xf1, 0x6e, 0x5a, 0xf9, 0x8b, 0xd4, ++ 0xb8, 0xd1, 0x05, 0x1b, 0x9d, 0x12, 0xb3, 0xbb, 0xd8, 0xe8, 0xdf, 0x21, ++ 0xc9, 0x1f, 0x0d, 0xc8, 0x44, 0x37, 0xd7, 0x8a, 0xfd, 0x22, 0x5f, 0x2e, ++ 0xb8, 0x21, 0xfb, 0x75, 0xf7, 0x64, 0x7b, 0x42, 0x3e, 0xd9, 0xbd, 0x22, ++ 0x97, 0x73, 0x22, 0x9e, 0x5e, 0x0c, 0xaa, 0xf5, 0xf0, 0xe9, 0xf6, 0xe7, ++ 0xe2, 0xbf, 0xeb, 0xab, 0x7b, 0xc7, 0xb9, 0x50, 0xd6, 0x57, 0x74, 0x27, ++ 0x71, 0x2d, 0xad, 0xaf, 0x41, 0x9e, 0xac, 0x27, 0x8a, 0x72, 0x19, 0xb2, ++ 0x07, 0x1e, 0x9e, 0x65, 0x4a, 0x1e, 0x4e, 0x40, 0xee, 0x5f, 0x95, 0x1d, ++ 0x47, 0xa9, 0x33, 0xaf, 0x62, 0xae, 0xca, 0x96, 0xc0, 0x46, 0xb0, 0x3f, ++ 0x57, 0x26, 0x9d, 0xae, 0xd4, 0x29, 0xb9, 0x35, 0xbe, 0x17, 0x31, 0xe7, ++ 0xb8, 0xe9, 0xca, 0xa2, 0x53, 0x90, 0xc5, 0x01, 0xb4, 0x29, 0x7f, 0x1a, ++ 0xbf, 0x4f, 0xe9, 0xb9, 0x3d, 0x0a, 0xbe, 0x5b, 0x89, 0x39, 0xe3, 0xf7, ++ 0xc1, 0xf7, 0x87, 0x25, 0x39, 0xbd, 0x62, 0x6b, 0x20, 0x77, 0x9e, 0xad, ++ 0x49, 0x9e, 0x35, 0xa5, 0x5c, 0xb2, 0xe5, 0x23, 0xb4, 0x21, 0x25, 0xce, ++ 0x0b, 0x36, 0x86, 0x67, 0xec, 0x25, 0xd8, 0x99, 0x12, 0x6c, 0x0a, 0x6c, ++ 0xc8, 0x9f, 0xa0, 0xfc, 0x59, 0xd4, 0x79, 0x06, 0xf1, 0xd3, 0x79, 0x60, ++ 0xbf, 0x73, 0xc0, 0x14, 0x4f, 0x97, 0x32, 0x3a, 0x96, 0x55, 0xf3, 0x85, ++ 0xcf, 0x52, 0xb1, 0x8f, 0x94, 0xe7, 0xd4, 0x7d, 0x1e, 0xb5, 0xb6, 0x59, ++ 0x67, 0x13, 0x71, 0x16, 0x28, 0x13, 0x99, 0x9b, 0xf3, 0x79, 0x42, 0xdb, ++ 0xc7, 0xf3, 0x19, 0xdf, 0x56, 0x36, 0xaf, 0xb1, 0x95, 0x22, 0x2f, 0x56, ++ 0x3c, 0x3c, 0x49, 0x7c, 0x5c, 0x9c, 0x4a, 0xac, 0x9c, 0x63, 0x16, 0xe1, ++ 0x37, 0x97, 0x11, 0x67, 0x44, 0xd2, 0xdf, 0x94, 0xc8, 0x71, 0xd7, 0xfd, ++ 0x21, 0xfc, 0x66, 0x01, 0x6b, 0x62, 0x04, 0x50, 0xbe, 0xc0, 0x77, 0x94, ++ 0x7b, 0xca, 0x76, 0x80, 0xe7, 0x19, 0xf2, 0x12, 0xca, 0xca, 0x2a, 0xfe, ++ 0xfa, 0x16, 0xe8, 0xd1, 0xf4, 0xa9, 0x32, 0xd6, 0x6b, 0x94, 0xdc, 0x58, ++ 0x0a, 0x31, 0x4e, 0xaf, 0xd9, 0x88, 0xf6, 0x73, 0x0b, 0x6c, 0x63, 0x0d, ++ 0xf0, 0x3a, 0xd5, 0x4b, 0x0b, 0x2c, 0xef, 0x90, 0x8b, 0x88, 0x45, 0x49, ++ 0x43, 0x79, 0x36, 0x2d, 0xde, 0xde, 0x31, 0xed, 0x15, 0x69, 0x45, 0x1e, ++ 0xfc, 0xca, 0x96, 0xe8, 0x67, 0x43, 0x52, 0x88, 0x93, 0xd7, 0x71, 0x59, ++ 0x9e, 0xfa, 0x4c, 0x13, 0xf7, 0x66, 0xb3, 0x36, 0x9f, 0xfd, 0xbd, 0x0e, ++ 0xf3, 0x2d, 0xec, 0x75, 0x70, 0x7f, 0x23, 0x04, 0x5f, 0xa6, 0xf6, 0x3c, ++ 0x90, 0x26, 0xea, 0xe2, 0x5f, 0xbe, 0xf7, 0xb0, 0x51, 0x0d, 0x3f, 0x12, ++ 0x4f, 0x72, 0xbe, 0x56, 0x61, 0x09, 0xf6, 0xa3, 0x2d, 0x7d, 0x49, 0xee, ++ 0x3d, 0xe1, 0xcd, 0xcf, 0x38, 0x25, 0xbc, 0x4b, 0x23, 0x57, 0x67, 0x2d, ++ 0xe7, 0x0a, 0x30, 0x45, 0x2e, 0xe6, 0x60, 0xbd, 0x46, 0x9b, 0x60, 0xbf, ++ 0x06, 0x32, 0xc6, 0x99, 0x26, 0x0f, 0x9f, 0x85, 0x64, 0x62, 0x8a, 0xe7, ++ 0x9e, 0xb0, 0x6d, 0xc0, 0x90, 0xbf, 0x1b, 0xc2, 0x73, 0x85, 0x79, 0xc4, ++ 0xa4, 0x5e, 0x3c, 0x8b, 0x67, 0xaf, 0x3f, 0xf2, 0xdc, 0x38, 0xc1, 0xb9, ++ 0x07, 0xe4, 0x5e, 0xa0, 0x13, 0x41, 0xff, 0x9d, 0x7a, 0xac, 0xce, 0x53, ++ 0x29, 0xee, 0x65, 0x4b, 0x12, 0xf6, 0x22, 0x8b, 0x58, 0x32, 0x17, 0xeb, ++ 0xd0, 0xd8, 0x9c, 0xef, 0xd6, 0x62, 0x4f, 0x3f, 0xc6, 0x4b, 0xc9, 0xe7, ++ 0x4b, 0x3e, 0xd6, 0x4b, 0xc1, 0xc7, 0x4a, 0x68, 0xb8, 0xc7, 0x95, 0x1f, ++ 0x3a, 0xe4, 0x57, 0x1f, 0xf2, 0x8e, 0x1c, 0xae, 0xfe, 0xb2, 0xf3, 0xcd, ++ 0xfa, 0xbf, 0x66, 0xd0, 0xc8, 0x1f, 0xe8, 0x03, 0x3e, 0x22, 0xed, 0x06, ++ 0xfc, 0x79, 0x11, 0xb8, 0xcb, 0x38, 0xd3, 0xa1, 0xde, 0x19, 0xc0, 0x06, ++ 0xe5, 0x29, 0xd8, 0xc6, 0x33, 0x3c, 0xf3, 0x85, 0x6d, 0x3b, 0x13, 0x96, ++ 0xe2, 0x0c, 0xe5, 0x52, 0xda, 0x0c, 0xac, 0x17, 0xeb, 0x97, 0xa7, 0x3a, ++ 0x90, 0x36, 0x23, 0x4d, 0xa8, 0x7e, 0xca, 0x53, 0xb6, 0x6a, 0x5f, 0x9e, ++ 0x4a, 0xa9, 0x76, 0xe5, 0xa9, 0x3e, 0xa4, 0x8e, 0x34, 0x9c, 0x41, 0xe0, ++ 0x74, 0xa6, 0x5b, 0x26, 0x4e, 0xc2, 0xbf, 0xf4, 0x1b, 0xea, 0xbe, 0xc4, ++ 0x38, 0xfc, 0x4f, 0x08, 0x51, 0xd6, 0x15, 0x73, 0x00, 0x18, 0x6b, 0x1b, ++ 0x30, 0xc8, 0x36, 0xb1, 0x8f, 0x73, 0xfe, 0xb4, 0xbd, 0xcb, 0xdc, 0xff, ++ 0x8a, 0x3f, 0x28, 0x19, 0xd9, 0x37, 0xd3, 0x08, 0x7d, 0x0d, 0x99, 0x45, ++ 0xe9, 0x32, 0x87, 0x90, 0xcf, 0xcf, 0x91, 0x6f, 0xf7, 0xab, 0xd8, 0x2d, ++ 0xeb, 0xc4, 0xa2, 0x12, 0x4d, 0x63, 0x8c, 0xb7, 0xd2, 0xbe, 0x07, 0xf2, ++ 0x67, 0xeb, 0x3e, 0xd2, 0xa0, 0xa7, 0x9e, 0x1f, 0x3c, 0xeb, 0xcd, 0xfc, ++ 0x8a, 0xb3, 0x5e, 0xca, 0x35, 0xf9, 0x7b, 0xbf, 0x2c, 0xdb, 0x69, 0x79, ++ 0xc9, 0x4e, 0xc9, 0x45, 0x7b, 0xab, 0xfc, 0x39, 0xfc, 0xf4, 0x25, 0x7b, ++ 0xba, 0x89, 0x58, 0xa0, 0xac, 0xce, 0xcf, 0xfc, 0xb5, 0xb2, 0xf5, 0x3e, ++ 0xfa, 0x8f, 0x64, 0x71, 0x8a, 0xd8, 0xd9, 0xdd, 0xbe, 0xc7, 0x29, 0xd0, ++ 0x6f, 0x81, 0x06, 0x62, 0xb5, 0x02, 0xfc, 0xdf, 0x41, 0x19, 0x72, 0xe8, ++ 0xf7, 0x94, 0x8f, 0x8a, 0x0f, 0x79, 0xfa, 0xec, 0xe4, 0x61, 0x57, 0x97, ++ 0x67, 0xa0, 0x4f, 0x42, 0xf9, 0xc7, 0xf3, 0x1c, 0xd7, 0xdd, 0x96, 0x2f, ++ 0x94, 0x38, 0xcf, 0xe2, 0xe6, 0xa8, 0x04, 0x65, 0x58, 0xe1, 0x85, 0x16, ++ 0x79, 0x71, 0x61, 0x83, 0x18, 0xf0, 0x50, 0xc6, 0x2d, 0x61, 0x75, 0xd3, ++ 0x84, 0xf1, 0xb7, 0xb4, 0xf2, 0xbe, 0xd8, 0x87, 0xc1, 0x1b, 0xee, 0x05, ++ 0x60, 0x6e, 0xad, 0x9c, 0x89, 0x9f, 0xef, 0x83, 0x7e, 0xf1, 0x39, 0x20, ++ 0x39, 0x3b, 0x86, 0x67, 0xa6, 0xd4, 0x39, 0xee, 0x93, 0x05, 0xc5, 0xc3, ++ 0xdc, 0xe3, 0xea, 0x7d, 0xa3, 0x7d, 0x07, 0x70, 0x1d, 0xe5, 0x15, 0xe9, ++ 0xa2, 0x37, 0x6e, 0x0e, 0x38, 0x2e, 0xdf, 0xd7, 0xa4, 0xce, 0xff, 0x0a, ++ 0xd0, 0x85, 0x71, 0x55, 0xbf, 0x5f, 0x2e, 0x4d, 0xed, 0x8f, 0x7a, 0xfa, ++ 0x31, 0xa0, 0x9f, 0xf9, 0x9e, 0xf1, 0x15, 0xf7, 0x4b, 0x5e, 0x19, 0x99, ++ 0xb4, 0xbf, 0xa1, 0xf5, 0x47, 0x02, 0x77, 0xf7, 0x00, 0x87, 0x1e, 0x69, ++ 0xc0, 0x5c, 0xac, 0x44, 0x22, 0x60, 0xb4, 0x1b, 0xc0, 0xf1, 0x43, 0xca, ++ 0xe7, 0xf6, 0xa8, 0xfd, 0xe8, 0x53, 0xa9, 0x16, 0x29, 0x9b, 0xb6, 0xba, ++ 0x17, 0xb7, 0x64, 0x6e, 0x21, 0xd6, 0xc7, 0xaf, 0x09, 0x65, 0x5d, 0x48, ++ 0x1b, 0x91, 0xbe, 0x4b, 0x8a, 0xc7, 0xa6, 0xf5, 0x78, 0xe1, 0x35, 0xf9, ++ 0x3e, 0x9d, 0x7e, 0x44, 0xc7, 0x53, 0x1c, 0x27, 0x2c, 0xf6, 0x17, 0x9b, ++ 0xa5, 0xeb, 0x88, 0x09, 0x6c, 0x1b, 0x07, 0xd6, 0xed, 0x90, 0xd4, 0x91, ++ 0x84, 0xdc, 0x72, 0xc4, 0xdf, 0x73, 0xfa, 0x0f, 0x23, 0x49, 0xb5, 0xc7, ++ 0xf9, 0xdd, 0x11, 0x7b, 0x8e, 0xe9, 0x6b, 0xfa, 0xfe, 0xde, 0x15, 0x7d, ++ 0xaf, 0xef, 0x47, 0x23, 0x3d, 0x2a, 0xfd, 0x6f, 0x23, 0x29, 0x95, 0xbe, ++ 0x3e, 0x72, 0x4b, 0xc5, 0x8b, 0x8f, 0x8a, 0xf3, 0x29, 0xf9, 0x5c, 0x89, ++ 0xf8, 0xb2, 0x1f, 0xd8, 0xd1, 0x81, 0x9d, 0xe9, 0x83, 0x9d, 0x49, 0xc1, ++ 0xce, 0x0c, 0xd0, 0xce, 0xc0, 0x6e, 0xbf, 0x02, 0xbb, 0xed, 0xc8, 0xf7, ++ 0x20, 0xaf, 0x4f, 0x3b, 0x8d, 0xc0, 0x85, 0xae, 0xeb, 0xcd, 0xd5, 0x7a, ++ 0x62, 0x09, 0xeb, 0x5b, 0x3e, 0x2d, 0x91, 0x56, 0xd8, 0xa0, 0x2d, 0x27, ++ 0x1a, 0x64, 0x3e, 0xe6, 0xba, 0x47, 0x1d, 0x5b, 0xae, 0xa2, 0x7e, 0xd6, ++ 0xa6, 0x1e, 0xbf, 0x14, 0x65, 0x3c, 0x76, 0x75, 0x6a, 0x2b, 0x6c, 0x12, ++ 0xe5, 0x3d, 0x22, 0xe5, 0xb1, 0xb8, 0x2c, 0x20, 0x3e, 0xab, 0xd5, 0x49, ++ 0xe1, 0x99, 0xfa, 0xff, 0x5d, 0xd4, 0x4d, 0xc1, 0x3f, 0x98, 0xb2, 0xd8, ++ 0x93, 0x90, 0x53, 0x3d, 0xd6, 0x40, 0xc2, 0xa0, 0xed, 0x4a, 0xc8, 0x1c, ++ 0x62, 0xfd, 0x72, 0x89, 0xf5, 0x59, 0x0f, 0xfa, 0x59, 0xf2, 0xda, 0x4d, ++ 0x96, 0x7c, 0x3b, 0xd1, 0xcf, 0x7d, 0xc8, 0x50, 0xae, 0xc7, 0xf3, 0x01, ++ 0x86, 0xd1, 0x08, 0x39, 0x70, 0xc0, 0xff, 0x31, 0x94, 0xf7, 0xf3, 0xbe, ++ 0x07, 0xca, 0x88, 0x85, 0x7e, 0x1c, 0x25, 0x46, 0xcc, 0x39, 0x63, 0x28, ++ 0x63, 0x1b, 0x2b, 0x9e, 0x44, 0xf9, 0xa8, 0x24, 0xe3, 0x79, 0x75, 0xf7, ++ 0xac, 0x1d, 0x65, 0xec, 0x23, 0xa8, 0xf7, 0x63, 0xfe, 0x8f, 0x92, 0xa3, ++ 0xa0, 0xed, 0x97, 0xf7, 0xaa, 0xbd, 0x81, 0x8c, 0xe9, 0x40, 0x1f, 0x58, ++ 0x96, 0x34, 0xd9, 0x2e, 0xe7, 0x38, 0xca, 0x16, 0xde, 0x57, 0xe1, 0x19, ++ 0x5e, 0x44, 0xee, 0xad, 0x34, 0x4b, 0xae, 0xd2, 0x70, 0x1d, 0xfb, 0xef, ++ 0xeb, 0xe4, 0x72, 0xdc, 0x14, 0xde, 0x83, 0xf0, 0xf4, 0x3c, 0xb4, 0x95, ++ 0x3a, 0x31, 0xc0, 0x73, 0x03, 0xf8, 0x5b, 0xac, 0x05, 0xfc, 0xef, 0x39, ++ 0xf8, 0xdf, 0xa7, 0x4b, 0x35, 0xfb, 0xe1, 0xf9, 0x5d, 0xda, 0x80, 0x27, ++ 0xb1, 0x66, 0xa3, 0xc0, 0xfd, 0x3b, 0x11, 0x0f, 0x0c, 0x03, 0xfb, 0x0f, ++ 0x62, 0xfd, 0xd2, 0x58, 0xbb, 0x31, 0xde, 0x17, 0xc2, 0x3a, 0x0e, 0xa8, ++ 0x73, 0xe6, 0x19, 0x75, 0xe7, 0xe2, 0x47, 0xca, 0xf7, 0x3e, 0x5e, 0x32, ++ 0xe0, 0x1f, 0x0a, 0xee, 0x66, 0xdb, 0x02, 0xfe, 0x5b, 0xd1, 0xe7, 0x81, ++ 0x17, 0x61, 0x57, 0x7e, 0x06, 0xba, 0xce, 0xcf, 0xd0, 0x9f, 0xa3, 0x8e, ++ 0x87, 0xb7, 0x1d, 0xee, 0x75, 0x41, 0x9f, 0x0f, 0x2f, 0xcb, 0x12, 0x70, ++ 0x47, 0x86, 0x72, 0x8c, 0xf8, 0xc1, 0x7a, 0x7a, 0x4e, 0xba, 0x69, 0x03, ++ 0xe7, 0xa8, 0x2b, 0xfd, 0xd3, 0x71, 0x60, 0x3d, 0x20, 0x79, 0x75, 0xae, ++ 0x8a, 0xe7, 0xb3, 0x1b, 0xc5, 0x20, 0xde, 0x73, 0x6e, 0x40, 0x19, 0xed, ++ 0x86, 0x8f, 0x91, 0x96, 0x06, 0xda, 0x24, 0xb3, 0xa5, 0x4d, 0xd9, 0x0e, ++ 0xcb, 0x79, 0x09, 0xe3, 0xee, 0x90, 0x46, 0x60, 0xb8, 0x02, 0xc6, 0x38, ++ 0x20, 0xff, 0xd5, 0xe1, 0x1e, 0x95, 0x17, 0xfb, 0x81, 0x96, 0x08, 0x78, ++ 0xd6, 0xb4, 0xc7, 0x36, 0x23, 0x3b, 0xaa, 0xec, 0x3f, 0xa2, 0x30, 0x56, ++ 0x4e, 0xd8, 0x3f, 0xfc, 0x04, 0xc6, 0x4c, 0x4e, 0x53, 0xf6, 0x7b, 0xb1, ++ 0x6e, 0xbf, 0x0d, 0x0c, 0x44, 0xae, 0x7e, 0x75, 0x83, 0xa7, 0x2f, 0xa4, ++ 0x7f, 0x89, 0x78, 0x82, 0x67, 0x00, 0x5e, 0x5c, 0xbe, 0x42, 0x5b, 0x3f, ++ 0xe8, 0x9d, 0xdd, 0xe0, 0x9f, 0x25, 0x77, 0x4e, 0x7b, 0xfe, 0xba, 0xf3, ++ 0x2c, 0x5a, 0x1d, 0x95, 0x76, 0x9e, 0x4a, 0x1b, 0x72, 0x8b, 0xdc, 0x19, ++ 0xf2, 0xfa, 0x31, 0x4e, 0x98, 0x90, 0x55, 0xda, 0x81, 0x76, 0xc8, 0x39, ++ 0xf3, 0xb4, 0x29, 0xb4, 0x09, 0x94, 0x05, 0x5b, 0x8a, 0x55, 0xd8, 0x84, ++ 0x96, 0x0e, 0x99, 0x23, 0xcf, 0x4e, 0xd0, 0x4e, 0xfc, 0x48, 0x26, 0xd7, ++ 0xd8, 0xca, 0x41, 0xf1, 0xe3, 0xda, 0x66, 0x09, 0xa7, 0x6d, 0xf3, 0x3e, ++ 0x35, 0x47, 0xcf, 0x5e, 0xee, 0x23, 0xfe, 0x9c, 0xc9, 0x58, 0x6d, 0xa2, ++ 0xb1, 0xa7, 0xc2, 0x4f, 0xdf, 0xc7, 0x5c, 0xd9, 0x87, 0xe2, 0xd3, 0xc0, ++ 0xa0, 0x17, 0x0b, 0xa8, 0x3d, 0x3f, 0xe0, 0xe0, 0xf8, 0xcf, 0x60, 0x6b, ++ 0x73, 0xc4, 0x25, 0xe0, 0x73, 0xe7, 0x51, 0xca, 0xd1, 0x66, 0xda, 0x32, ++ 0xe0, 0xbc, 0x14, 0xed, 0xb5, 0x2c, 0x4c, 0x03, 0x73, 0x19, 0x77, 0x48, ++ 0x9e, 0xf2, 0xca, 0xbb, 0x0a, 0x0b, 0x86, 0x4c, 0xce, 0xb6, 0x48, 0xd7, ++ 0x09, 0xee, 0xaf, 0x9e, 0x8a, 0x4a, 0x0b, 0xf7, 0x58, 0xe9, 0x83, 0xfa, ++ 0x25, 0x87, 0xf2, 0xce, 0x13, 0x41, 0xb5, 0x1f, 0x36, 0x67, 0x90, 0x47, ++ 0x7d, 0xb0, 0x07, 0x56, 0x6a, 0xc9, 0xd8, 0xd6, 0xe4, 0x61, 0x48, 0xc8, ++ 0x52, 0x09, 0x32, 0x56, 0x82, 0x8c, 0x95, 0x20, 0x63, 0x25, 0xc8, 0x18, ++ 0xb0, 0xdf, 0x79, 0xe8, 0xdf, 0xb9, 0xd2, 0x80, 0xf6, 0xeb, 0xbb, 0x94, ++ 0x5f, 0x3f, 0x54, 0x7a, 0xc5, 0x65, 0xfa, 0xac, 0x8a, 0x4d, 0xfb, 0x20, ++ 0x83, 0x8c, 0x45, 0xfd, 0x18, 0xf5, 0x15, 0x79, 0x72, 0xe6, 0x55, 0x39, ++ 0x35, 0x53, 0xc3, 0x81, 0x13, 0x25, 0x57, 0x5e, 0x72, 0x10, 0x7f, 0xce, ++ 0x13, 0x53, 0x65, 0x5a, 0x1b, 0x15, 0xb6, 0x3a, 0x28, 0x79, 0x85, 0x93, ++ 0x95, 0x1f, 0x01, 0xbe, 0x52, 0xb8, 0x90, 0xba, 0x29, 0x6d, 0x5b, 0x2e, ++ 0xcb, 0x39, 0xf8, 0xf1, 0x85, 0xea, 0x6b, 0xf2, 0x8c, 0xc2, 0xe3, 0xe4, ++ 0xc3, 0x3b, 0xe5, 0xa7, 0xa6, 0x77, 0x9e, 0x7f, 0x0a, 0x58, 0x63, 0xa1, ++ 0x87, 0xb6, 0x23, 0x04, 0x5f, 0x60, 0x15, 0x3a, 0xa1, 0xd7, 0xfb, 0x8d, ++ 0x1b, 0x81, 0x69, 0xf8, 0x7e, 0xa3, 0xbc, 0x38, 0x53, 0xa8, 0x93, 0x09, ++ 0xda, 0x07, 0xeb, 0xb0, 0x18, 0xf4, 0x53, 0xf4, 0x9b, 0x9c, 0x2f, 0xfd, ++ 0xd4, 0x4f, 0x37, 0xf0, 0x0e, 0x57, 0xf9, 0x58, 0x6c, 0x03, 0xf7, 0x1b, ++ 0x63, 0x36, 0x79, 0x7a, 0x59, 0xf6, 0x57, 0x58, 0xf6, 0x2a, 0xd6, 0x87, ++ 0xe9, 0x0f, 0xdc, 0x7b, 0x63, 0x1c, 0x8f, 0xfd, 0x02, 0x37, 0xb5, 0x63, ++ 0xae, 0xa5, 0x8f, 0x68, 0xcc, 0xdd, 0xa7, 0x70, 0xf4, 0xb5, 0x78, 0x99, ++ 0x7c, 0x72, 0xc0, 0xa7, 0xcb, 0x6a, 0x3f, 0x70, 0x9d, 0x7d, 0xe2, 0x27, ++ 0xa0, 0x57, 0x85, 0x2b, 0xc2, 0x3d, 0x4b, 0xee, 0xe7, 0x72, 0xaf, 0xb8, ++ 0xde, 0x62, 0xa8, 0x7b, 0x03, 0x72, 0x0f, 0xec, 0xcb, 0xbd, 0xb0, 0x2f, ++ 0xf7, 0x5d, 0x73, 0x07, 0xda, 0x3f, 0x03, 0xe8, 0x2a, 0x04, 0x8d, 0x0e, ++ 0x19, 0xad, 0xd4, 0xb7, 0xe5, 0x3e, 0xee, 0x7a, 0xfb, 0xb6, 0xdc, 0xd3, ++ 0x4d, 0xad, 0xd9, 0x0b, 0xa4, 0x6c, 0xb8, 0x72, 0xc9, 0xe1, 0xbe, 0x9b, ++ 0x7f, 0x6f, 0x7e, 0x3d, 0xfc, 0x15, 0x68, 0xf6, 0xf7, 0x9c, 0x43, 0xe9, ++ 0x2b, 0xc2, 0xfb, 0xf3, 0xc5, 0x29, 0xe2, 0x81, 0x98, 0xba, 0x17, 0x63, ++ 0xa8, 0x7d, 0x3e, 0xaf, 0x6d, 0x71, 0x4a, 0x9d, 0x31, 0x15, 0xb8, 0x77, ++ 0x6d, 0x6e, 0xb5, 0xcc, 0xd1, 0xa0, 0x77, 0x1f, 0x93, 0xba, 0xec, 0xd9, ++ 0x32, 0xc8, 0x62, 0xb5, 0x76, 0xcf, 0x71, 0x50, 0xd9, 0x8b, 0x2b, 0xd0, ++ 0x01, 0xae, 0x17, 0xe2, 0x05, 0xe8, 0xc9, 0x04, 0xec, 0x53, 0x5e, 0xf5, ++ 0x17, 0xa1, 0x5c, 0x64, 0xb2, 0x41, 0x43, 0xc2, 0xc7, 0x19, 0x0b, 0x79, ++ 0x7b, 0x2d, 0xb9, 0xa0, 0xa5, 0xec, 0x37, 0x68, 0x07, 0x3e, 0xa3, 0x7e, ++ 0x26, 0xc6, 0x1b, 0xd3, 0x0d, 0xf0, 0xab, 0x58, 0xbf, 0x2a, 0xf7, 0x04, ++ 0xa0, 0xbb, 0x8b, 0xdf, 0x91, 0x7d, 0xb3, 0xdd, 0xcd, 0x9e, 0xfc, 0x73, ++ 0x1f, 0x99, 0xf3, 0xf3, 0x69, 0x58, 0xdd, 0xb7, 0x71, 0x5c, 0x22, 0x51, ++ 0xf8, 0xb4, 0x0f, 0x20, 0xce, 0xd8, 0x01, 0x59, 0x59, 0x8a, 0xb1, 0x5f, ++ 0x4f, 0x67, 0x26, 0x4b, 0xec, 0xfb, 0x3b, 0x32, 0x34, 0x5b, 0x6a, 0xa6, ++ 0x2f, 0x59, 0x84, 0x1d, 0x58, 0x36, 0xe9, 0x43, 0xc7, 0xe0, 0xe3, 0xda, ++ 0xe5, 0xfb, 0xb3, 0xf4, 0x8f, 0x49, 0xf3, 0x94, 0xf4, 0xc6, 0x4f, 0x81, ++ 0xa6, 0xcf, 0x3b, 0x21, 0xc6, 0x68, 0xee, 0x20, 0xca, 0xfe, 0x5c, 0x92, ++ 0x66, 0x67, 0x80, 0xcf, 0xbd, 0xe6, 0x17, 0x80, 0x61, 0x33, 0x66, 0xd2, ++ 0xbc, 0x35, 0x40, 0x39, 0x42, 0xcc, 0xbd, 0x58, 0xa3, 0xf3, 0x07, 0xb3, ++ 0x2a, 0x4e, 0x52, 0x76, 0x66, 0xd1, 0xe1, 0x78, 0xa0, 0x5b, 0xd9, 0xac, ++ 0x5b, 0x61, 0x4f, 0x22, 0xfa, 0xfc, 0x0d, 0x6d, 0x88, 0x6d, 0x9c, 0x90, ++ 0xce, 0x3f, 0x2a, 0xd9, 0x93, 0x31, 0xd8, 0x33, 0xf6, 0xe5, 0xc7, 0x0e, ++ 0xf4, 0x91, 0x3e, 0xde, 0xa6, 0xbf, 0xbb, 0x03, 0x7e, 0xef, 0x66, 0x45, ++ 0xcf, 0xb0, 0xd3, 0x27, 0x13, 0xc7, 0x38, 0x76, 0x0f, 0x6c, 0x79, 0x5c, ++ 0xc9, 0x6d, 0xb1, 0xb4, 0x1c, 0x8f, 0xc0, 0x26, 0x47, 0xb6, 0x90, 0x9f, ++ 0xef, 0x93, 0xbb, 0xec, 0x31, 0xb9, 0x1b, 0xb2, 0x33, 0x68, 0x3b, 0x32, ++ 0x84, 0xb5, 0xd8, 0x61, 0xc3, 0xef, 0x28, 0x0c, 0xdd, 0x88, 0xb8, 0x8b, ++ 0x63, 0xb7, 0xeb, 0xfb, 0x17, 0x1e, 0x7e, 0xfc, 0x4a, 0xd5, 0xe3, 0x51, ++ 0x76, 0xf6, 0x49, 0xc5, 0x9b, 0x61, 0x67, 0x9b, 0xf6, 0xb3, 0x2d, 0x92, ++ 0x53, 0xf5, 0xb6, 0x29, 0x7f, 0x5c, 0x5c, 0xb8, 0x1f, 0x29, 0x7c, 0xf3, ++ 0x02, 0xec, 0x0d, 0x30, 0x77, 0xb1, 0xb2, 0x15, 0x79, 0xf8, 0xd0, 0x85, ++ 0x34, 0xd2, 0xf7, 0x21, 0x65, 0xdd, 0x07, 0x9a, 0xbd, 0xbd, 0xdc, 0xb5, ++ 0xf7, 0xb8, 0x24, 0xf0, 0x01, 0x85, 0x4b, 0xaf, 0xa8, 0x3b, 0x80, 0x88, ++ 0xa1, 0x47, 0xb2, 0xb0, 0x2b, 0xcd, 0xc0, 0x40, 0x53, 0xc7, 0xad, 0xd4, ++ 0x50, 0x60, 0xbb, 0x7c, 0x10, 0xb1, 0x7c, 0xd9, 0xe1, 0x5a, 0x6e, 0x95, ++ 0x07, 0xdf, 0x4b, 0x19, 0xd9, 0x2e, 0x7b, 0xde, 0x1b, 0x90, 0x3d, 0x7d, ++ 0x56, 0x86, 0x74, 0xdf, 0xf2, 0x2e, 0x3f, 0x9e, 0xee, 0x1a, 0x4e, 0x06, ++ 0xfa, 0xe5, 0x0b, 0x90, 0xb1, 0x02, 0xe4, 0x6b, 0xa8, 0x4a, 0x9e, 0xd3, ++ 0xde, 0xd3, 0xce, 0xa7, 0x80, 0x95, 0x7d, 0xec, 0x67, 0xcb, 0x54, 0xb5, ++ 0x41, 0x12, 0x37, 0x70, 0x3f, 0x39, 0xe1, 0x9d, 0x71, 0xdc, 0x40, 0x99, ++ 0x40, 0x0c, 0x72, 0x83, 0xa7, 0x9f, 0xea, 0xee, 0xdd, 0x0d, 0x9e, 0x5f, ++ 0x41, 0xfc, 0xeb, 0x12, 0xe7, 0x79, 0x77, 0x0d, 0xbe, 0xa1, 0x6d, 0x69, ++ 0x68, 0xe3, 0x0a, 0xbe, 0x6b, 0x61, 0xfc, 0xf0, 0x87, 0xcd, 0xb5, 0x6f, ++ 0x07, 0xd6, 0xca, 0xa2, 0xbf, 0xef, 0x36, 0x87, 0x39, 0xd3, 0xa7, 0x5b, ++ 0x26, 0x6d, 0x61, 0xab, 0xbd, 0x4b, 0xfe, 0x0c, 0xfe, 0xfd, 0x6b, 0x2b, ++ 0xfe, 0x7d, 0x37, 0xf8, 0xb1, 0x16, 0x03, 0xd8, 0xe6, 0x3d, 0x98, 0xcb, ++ 0x30, 0xd6, 0xf3, 0x6e, 0xfc, 0xee, 0x2a, 0xad, 0xda, 0xc7, 0x9b, 0x29, ++ 0x00, 0x4f, 0x36, 0xd8, 0xec, 0x6f, 0xd5, 0x7e, 0x5e, 0x21, 0x2f, 0x2b, ++ 0x7b, 0x85, 0x03, 0x57, 0x85, 0x7e, 0xef, 0x75, 0x09, 0x77, 0xdb, 0xaf, ++ 0x77, 0x06, 0xec, 0xe7, 0x8d, 0x00, 0xcf, 0xc1, 0x1d, 0x39, 0x5d, 0x25, ++ 0x0e, 0xbb, 0x28, 0xc6, 0x59, 0x62, 0xb0, 0x97, 0xd5, 0x1e, 0x54, 0xb9, ++ 0xf4, 0x2d, 0xa4, 0xa8, 0x0f, 0xfb, 0x18, 0xf4, 0xf6, 0x29, 0x14, 0x56, ++ 0xa1, 0x9d, 0xbd, 0x1b, 0xeb, 0x30, 0x81, 0x5f, 0xe7, 0x96, 0x5b, 0xa1, ++ 0xbf, 0x94, 0x53, 0xee, 0x7d, 0x75, 0x9b, 0x5b, 0x02, 0x7c, 0xb7, 0xde, ++ 0x3e, 0xd8, 0xb7, 0x25, 0x74, 0x14, 0xbe, 0xce, 0xa0, 0x7d, 0xe0, 0x3c, ++ 0xe8, 0x27, 0x4d, 0x99, 0x3f, 0x46, 0x5d, 0x5f, 0xaf, 0xbe, 0x5f, 0xd7, ++ 0x9f, 0x8b, 0xf2, 0x1b, 0x99, 0x3c, 0xf7, 0x38, 0x4b, 0x5c, 0x03, 0x07, ++ 0x6b, 0xe0, 0xca, 0x71, 0xa7, 0x95, 0x36, 0x5d, 0x82, 0xc7, 0x5d, 0x19, ++ 0x54, 0xd8, 0xb5, 0x17, 0x98, 0x6b, 0xa3, 0xc6, 0x0d, 0x31, 0x09, 0x1d, ++ 0xef, 0x90, 0x46, 0xe0, 0xea, 0x86, 0x23, 0xf4, 0x91, 0xc9, 0xc4, 0x20, ++ 0x84, 0x20, 0xa4, 0xee, 0x93, 0x5a, 0x03, 0xdf, 0x97, 0xde, 0xc4, 0xf7, ++ 0x85, 0x78, 0xe9, 0x51, 0xac, 0x9f, 0xe5, 0x5c, 0x5c, 0xa7, 0x7e, 0xb1, ++ 0x56, 0x1f, 0x72, 0xc4, 0xbd, 0x35, 0xb6, 0xe1, 0x5e, 0x5b, 0x72, 0xe0, ++ 0x7b, 0xdc, 0x63, 0x43, 0xac, 0xd9, 0x70, 0xc6, 0xa3, 0xc1, 0x58, 0x6c, ++ 0x93, 0xf2, 0x49, 0xea, 0x28, 0xf7, 0x59, 0x4c, 0x2f, 0x4e, 0x2d, 0x31, ++ 0x5e, 0xe5, 0xfb, 0x84, 0x7e, 0xdf, 0xa9, 0xdf, 0x33, 0x1e, 0x2d, 0xb8, ++ 0x0d, 0xe0, 0xe9, 0x0e, 0xd8, 0xcf, 0xfb, 0xb7, 0xda, 0x0a, 0x37, 0xdc, ++ 0xbf, 0xb2, 0x66, 0x3b, 0xd5, 0xdd, 0xa2, 0x72, 0xe9, 0xa0, 0xd8, 0x5b, ++ 0x96, 0x52, 0x21, 0x19, 0xc5, 0x5a, 0x30, 0x9f, 0x21, 0x3d, 0xa9, 0x43, ++ 0xb2, 0x5f, 0xad, 0x4d, 0xf9, 0x98, 0x75, 0x38, 0x11, 0x98, 0x10, 0xa3, ++ 0xcc, 0xe7, 0x4f, 0x23, 0x3d, 0x04, 0xbc, 0xe3, 0xed, 0x5d, 0x1a, 0xe5, ++ 0xd5, 0xbc, 0x04, 0xc6, 0x30, 0x77, 0xac, 0xda, 0xc7, 0xaa, 0xed, 0x71, ++ 0xf1, 0xfd, 0xa0, 0x7a, 0x9f, 0x5a, 0xb5, 0xcf, 0x95, 0x33, 0x88, 0x65, ++ 0xfc, 0xf7, 0x5c, 0x0b, 0xae, 0x17, 0x7c, 0xf1, 0x31, 0x7f, 0xcf, 0xab, ++ 0x45, 0xaf, 0x0b, 0xd7, 0x67, 0x4a, 0xce, 0x99, 0xd6, 0x30, 0xe5, 0xef, ++ 0xb6, 0xad, 0x37, 0xc9, 0x78, 0x3b, 0xf7, 0xdb, 0xea, 0x69, 0x58, 0xbb, ++ 0x8f, 0x56, 0x3f, 0xfe, 0xda, 0xfd, 0x37, 0x8e, 0xed, 0xed, 0xb1, 0x65, ++ 0x57, 0xed, 0xb1, 0xd5, 0x8f, 0xc7, 0xb1, 0x36, 0x22, 0x7e, 0x2a, 0xb8, ++ 0x31, 0x9b, 0x6b, 0xd4, 0x95, 0x98, 0x65, 0xfe, 0xcb, 0x06, 0xd6, 0x31, ++ 0x06, 0x3f, 0xc2, 0xb5, 0xf4, 0xcf, 0x9e, 0xb9, 0xa6, 0xc9, 0xc4, 0x21, ++ 0x6f, 0x3d, 0x07, 0xbc, 0x75, 0xf7, 0xd6, 0xff, 0xe2, 0xca, 0x3a, 0xd2, ++ 0x3f, 0x70, 0x1d, 0xdb, 0x45, 0x60, 0x67, 0x8d, 0x23, 0x5c, 0x43, 0xa6, ++ 0x5c, 0x43, 0xbe, 0xe3, 0x1a, 0x76, 0xea, 0x77, 0x5c, 0x3f, 0xe0, 0xb4, ++ 0x2f, 0x02, 0x63, 0x38, 0x59, 0xf5, 0x1d, 0x54, 0x67, 0xb7, 0xaf, 0x8b, ++ 0x29, 0x79, 0x66, 0x3e, 0x2a, 0x66, 0xda, 0x9b, 0xd7, 0xd8, 0xaa, 0xfd, ++ 0x76, 0x9e, 0x5f, 0xf5, 0x11, 0x7b, 0xfa, 0xf3, 0x8a, 0x73, 0x5e, 0xfb, ++ 0xe5, 0xb2, 0xe4, 0xa7, 0x42, 0x88, 0x01, 0x53, 0xc0, 0x39, 0x7d, 0xb0, ++ 0xb7, 0xdc, 0x1f, 0x45, 0x59, 0x85, 0x78, 0x85, 0xbe, 0x2e, 0x05, 0x5d, ++ 0xa1, 0x0d, 0x26, 0x1e, 0x79, 0x55, 0x72, 0x73, 0xbe, 0x8d, 0x41, 0xff, ++ 0x86, 0xdf, 0x3f, 0xf9, 0x9c, 0xb9, 0x65, 0xb3, 0x2c, 0x25, 0x36, 0x8b, ++ 0x95, 0x58, 0x90, 0xda, 0xba, 0x8e, 0xad, 0xcf, 0x77, 0xe7, 0xfe, 0x60, ++ 0x4d, 0x36, 0xc6, 0xd6, 0x59, 0xfb, 0xbd, 0xe2, 0xbf, 0xf7, 0xd7, 0x7e, ++ 0xdd, 0x75, 0x28, 0xbc, 0x22, 0x5c, 0x0b, 0xf2, 0x80, 0x78, 0x38, 0x2c, ++ 0x9f, 0x8a, 0x51, 0x1f, 0x0b, 0xea, 0x7c, 0x33, 0x69, 0x74, 0x2b, 0x9b, ++ 0x31, 0xe8, 0x78, 0xf2, 0x5a, 0xc0, 0x38, 0x91, 0xae, 0x7f, 0xe1, 0x0e, ++ 0xc6, 0x10, 0xe7, 0x76, 0xd1, 0xbe, 0xf8, 0x3a, 0x1d, 0x55, 0x3a, 0xfd, ++ 0x79, 0x27, 0x20, 0x45, 0x3b, 0x20, 0x13, 0xf6, 0x41, 0x85, 0xf1, 0x3f, ++ 0x84, 0xbe, 0x1e, 0xd4, 0x7d, 0x4d, 0x48, 0xb7, 0xb6, 0x3f, 0x07, 0x20, ++ 0xe7, 0xae, 0xdc, 0xe7, 0x6c, 0x95, 0xdb, 0x5a, 0xa9, 0x03, 0xfe, 0xfc, ++ 0x0f, 0x4a, 0xd7, 0xd6, 0xa5, 0x04, 0x22, 0x83, 0x5b, 0xc2, 0x2b, 0x3c, ++ 0xa0, 0x9e, 0xf9, 0xf2, 0xed, 0xf1, 0xc1, 0x9b, 0xff, 0xaa, 0xb9, 0xea, ++ 0x79, 0x72, 0xce, 0xac, 0xc7, 0xb9, 0x7a, 0x58, 0xbe, 0x36, 0x57, 0xbf, ++ 0x7e, 0x33, 0x64, 0xc9, 0x4a, 0x48, 0xa0, 0x9e, 0x37, 0x2b, 0x36, 0x6a, ++ 0x98, 0x7b, 0x24, 0x4b, 0xa6, 0x95, 0x4a, 0x04, 0xfc, 0xbd, 0x68, 0x0f, ++ 0xeb, 0x76, 0x02, 0x87, 0xdb, 0xdd, 0xdd, 0xa9, 0xbc, 0xda, 0x23, 0x35, ++ 0xd4, 0xbc, 0x26, 0x80, 0xc9, 0xe6, 0x9d, 0x57, 0xdc, 0x4f, 0x02, 0xb3, ++ 0x8e, 0xcb, 0xc3, 0x12, 0x5c, 0xb5, 0x97, 0x8b, 0xfc, 0x59, 0xee, 0xe7, ++ 0x5a, 0x89, 0x0c, 0xd6, 0xf8, 0xc3, 0x88, 0xe1, 0xcb, 0xb0, 0xfb, 0x1f, ++ 0xa1, 0x6f, 0x28, 0xc1, 0x5f, 0x00, 0x97, 0x7c, 0xed, 0xba, 0x18, 0x7e, ++ 0xbc, 0x6e, 0x2f, 0xd7, 0xc3, 0xa7, 0xe7, 0x14, 0x26, 0x25, 0x6e, 0x3f, ++ 0x1c, 0xb8, 0xa7, 0x27, 0x88, 0x38, 0xa3, 0xe0, 0x46, 0x6c, 0xe2, 0xb8, ++ 0x83, 0x72, 0x17, 0xd6, 0xe7, 0xf4, 0x7c, 0x21, 0xb0, 0xa3, 0xe4, 0xcb, ++ 0x2a, 0xe2, 0xca, 0xaa, 0x95, 0x5a, 0x06, 0x3f, 0x9e, 0xd4, 0x98, 0x8f, ++ 0xe7, 0x35, 0x65, 0x1d, 0xb3, 0x70, 0x6f, 0xa8, 0x58, 0x3d, 0x28, 0x93, ++ 0x0e, 0xf7, 0x76, 0xba, 0xa4, 0x18, 0xcb, 0xdc, 0xd4, 0xb8, 0xc2, 0x23, ++ 0xcb, 0x44, 0xcc, 0x97, 0xa2, 0xfd, 0x2e, 0xeb, 0xf3, 0x8e, 0x27, 0x95, ++ 0x7c, 0xf9, 0xfb, 0xc2, 0x8c, 0x8f, 0x78, 0x5e, 0xd5, 0x65, 0x0e, 0xf3, ++ 0x79, 0x8e, 0x32, 0xa0, 0x62, 0x26, 0xf0, 0xf2, 0x21, 0xc9, 0x8c, 0x26, ++ 0x14, 0x6e, 0x79, 0xbc, 0x44, 0x7d, 0x21, 0xfe, 0xbf, 0x0c, 0xec, 0x1f, ++ 0xc2, 0x9a, 0x31, 0x0e, 0xe0, 0xd8, 0xd4, 0x0b, 0x94, 0x55, 0xcc, 0x5f, ++ 0xa2, 0x17, 0xdb, 0x37, 0x11, 0x63, 0x5c, 0x28, 0x7d, 0x5c, 0xf1, 0x6f, ++ 0x49, 0xfc, 0xbd, 0x73, 0x85, 0x05, 0x0b, 0xd9, 0x60, 0x40, 0x92, 0x47, ++ 0x3f, 0x03, 0x19, 0x1a, 0x41, 0x8c, 0xc4, 0x7a, 0xa2, 0xce, 0xaf, 0x06, ++ 0x81, 0xb9, 0x0c, 0xfb, 0x46, 0x29, 0x9a, 0x61, 0x29, 0xaa, 0x7b, 0x80, ++ 0x3c, 0xcf, 0x0d, 0xaa, 0xbd, 0x9d, 0xa2, 0x49, 0xcc, 0x9f, 0xd9, 0xe4, ++ 0xdf, 0x03, 0x2c, 0x9a, 0x6c, 0xc7, 0x3c, 0xcb, 0x27, 0x24, 0x7c, 0xf4, ++ 0x80, 0x34, 0x1c, 0x7d, 0x58, 0x1a, 0xa7, 0x89, 0xf1, 0xb8, 0x77, 0x6f, ++ 0xdc, 0xd1, 0x28, 0xc4, 0xdc, 0x5f, 0xc5, 0xd8, 0x07, 0xe5, 0x87, 0x8e, ++ 0x4f, 0xd3, 0x86, 0x8d, 0xd2, 0xc2, 0x3a, 0x7e, 0xde, 0xc7, 0xe3, 0x77, ++ 0x80, 0x1e, 0xce, 0x3f, 0xa1, 0x71, 0xdf, 0x1d, 0x75, 0xb1, 0x6b, 0x83, ++ 0x8e, 0x5d, 0xd9, 0xee, 0x32, 0x7c, 0xf6, 0x31, 0x09, 0xdb, 0x7e, 0xfb, ++ 0xed, 0xa8, 0x17, 0xaf, 0xbb, 0x03, 0xc1, 0x3a, 0xfa, 0x4e, 0x40, 0x0b, ++ 0x71, 0x0f, 0xcf, 0xdb, 0x59, 0xe6, 0x9d, 0xf9, 0x1b, 0xe5, 0x74, 0x70, ++ 0xf5, 0xf8, 0xdb, 0xea, 0xea, 0xfa, 0x65, 0x7e, 0x9b, 0xb0, 0x17, 0xf3, ++ 0xf7, 0x87, 0xeb, 0xda, 0x7d, 0xd7, 0xf4, 0x52, 0x2f, 0xf6, 0xf0, 0xe2, ++ 0x20, 0xce, 0x21, 0x55, 0x87, 0x73, 0x56, 0x7f, 0x2f, 0x9a, 0x43, 0x79, ++ 0x7e, 0xd6, 0xbf, 0x3b, 0x64, 0x60, 0x2e, 0x56, 0x81, 0xf1, 0x8b, 0xc9, ++ 0x6f, 0x33, 0x67, 0x0b, 0xa0, 0xfb, 0x66, 0x75, 0xef, 0x88, 0x77, 0x37, ++ 0x50, 0x2f, 0xe1, 0xe1, 0x4f, 0xe6, 0xe3, 0x58, 0xf3, 0x77, 0x75, 0x18, ++ 0xe9, 0xff, 0x7e, 0x53, 0xb6, 0x9f, 0xf8, 0x66, 0x13, 0xcf, 0x21, 0x81, ++ 0x9b, 0x29, 0x67, 0xdf, 0x81, 0x9c, 0x35, 0xaa, 0x73, 0x9f, 0x62, 0x89, ++ 0xf1, 0x5c, 0x1e, 0xf2, 0xc3, 0xfb, 0x7b, 0x8c, 0xfb, 0xf2, 0x7a, 0x3f, ++ 0x96, 0x74, 0x12, 0xd3, 0xfb, 0xf1, 0x01, 0xfb, 0x5c, 0xef, 0x9e, 0xb2, ++ 0x1f, 0xb3, 0x51, 0xde, 0xe2, 0x8a, 0xe6, 0xa1, 0x35, 0xf1, 0xca, 0x21, ++ 0xd8, 0x82, 0x79, 0xc8, 0xf3, 0x5e, 0xd8, 0xc0, 0xc1, 0x20, 0xf5, 0x33, ++ 0xaa, 0x63, 0x59, 0x9b, 0x71, 0x7b, 0x60, 0x14, 0x7d, 0x18, 0xd3, 0xaf, ++ 0xc9, 0x04, 0xec, 0xff, 0x64, 0x35, 0xa9, 0xbe, 0xe9, 0xc9, 0xc4, 0x79, ++ 0x9f, 0x8c, 0xe5, 0x5f, 0x83, 0xbc, 0xbe, 0x06, 0x3c, 0xbc, 0x01, 0xfc, ++ 0x34, 0xf4, 0x5a, 0xfd, 0x96, 0xde, 0x8b, 0x8a, 0x70, 0x2f, 0x1e, 0x76, ++ 0xb3, 0xe8, 0x61, 0xcd, 0xd8, 0x24, 0xd2, 0x7f, 0x1e, 0xf5, 0xe4, 0xf5, ++ 0xdf, 0x6a, 0x79, 0x6b, 0x42, 0xf9, 0x63, 0x6a, 0x0f, 0xd2, 0x9b, 0x93, ++ 0xa5, 0x63, 0x95, 0x30, 0x64, 0x8e, 0xf3, 0xfa, 0x53, 0xd4, 0xa3, 0xac, ++ 0xf5, 0xe8, 0xb3, 0xd9, 0xa8, 0xb2, 0x8f, 0x39, 0xc8, 0x52, 0x5e, 0xc5, ++ 0x11, 0xc0, 0xf7, 0x0e, 0xdb, 0x3d, 0xb7, 0x89, 0x67, 0x9f, 0x0d, 0xb6, ++ 0x8a, 0x2d, 0xda, 0x83, 0xe2, 0x97, 0xdd, 0x89, 0x32, 0xca, 0xd9, 0x8d, ++ 0x58, 0x1b, 0x96, 0x65, 0x91, 0xe7, 0x58, 0x37, 0xe9, 0x71, 0x38, 0x46, ++ 0x77, 0xf3, 0x6a, 0x9a, 0x38, 0x97, 0xf6, 0x35, 0xdf, 0x35, 0xb0, 0xec, ++ 0x46, 0x5d, 0x16, 0xd2, 0xf3, 0x1b, 0xd2, 0xdf, 0xd2, 0x5a, 0x87, 0x33, ++ 0x2b, 0xd8, 0x98, 0xf4, 0x45, 0x54, 0xbb, 0x8c, 0xe9, 0xc9, 0xce, 0x21, ++ 0xac, 0x47, 0x28, 0x1d, 0xe4, 0x99, 0x2c, 0xf8, 0xeb, 0xeb, 0x44, 0x5c, ++ 0xc5, 0x9d, 0x09, 0xc3, 0xbb, 0xbb, 0x74, 0xee, 0x9a, 0xfb, 0xd9, 0xde, ++ 0x5d, 0xf7, 0xa1, 0x9e, 0x26, 0x99, 0x9f, 0x89, 0xe8, 0x7b, 0x93, 0x71, ++ 0xa5, 0xb3, 0xf9, 0x31, 0xe6, 0xff, 0xc7, 0x26, 0x7e, 0xc7, 0x6c, 0xd8, ++ 0x2c, 0x6f, 0xd7, 0xfc, 0xbd, 0x51, 0xdd, 0x33, 0xa2, 0x2e, 0x14, 0xe7, ++ 0xde, 0x50, 0xef, 0x4f, 0xcf, 0x36, 0xa8, 0xfa, 0xa7, 0x67, 0xd7, 0xde, ++ 0x15, 0x62, 0xd9, 0xdb, 0xb8, 0xbf, 0x21, 0x0b, 0x53, 0x0d, 0xb2, 0x38, ++ 0x1b, 0x60, 0xbc, 0x96, 0x6e, 0xac, 0x7d, 0x0b, 0xa3, 0xbf, 0x5b, 0x73, ++ 0x65, 0x08, 0xeb, 0x37, 0x3f, 0x30, 0x29, 0xe5, 0x01, 0xc6, 0x23, 0xea, ++ 0x3e, 0x20, 0x64, 0xa4, 0x01, 0x58, 0xb4, 0xe0, 0x96, 0x6d, 0xee, 0x03, ++ 0xb7, 0x68, 0xbd, 0x7e, 0x45, 0xc7, 0x7c, 0xe4, 0x91, 0x21, 0xb9, 0xbe, ++ 0x09, 0x45, 0x57, 0x59, 0xf1, 0xca, 0xff, 0xd6, 0x88, 0xfd, 0xf3, 0x7b, ++ 0xa3, 0xa0, 0xc6, 0xb2, 0xfb, 0x35, 0xcf, 0xff, 0x4a, 0xa7, 0x8f, 0xca, ++ 0x9e, 0x63, 0xbf, 0x0f, 0x5a, 0x9b, 0xbc, 0x3b, 0x4f, 0x52, 0xff, 0x3d, ++ 0x49, 0x48, 0x7d, 0xcf, 0x12, 0xb2, 0x1f, 0x45, 0x19, 0xf7, 0xc1, 0x1e, ++ 0x55, 0xf3, 0xe0, 0xbd, 0xba, 0x82, 0xfc, 0xaa, 0xfb, 0x21, 0x7e, 0x2c, ++ 0xc6, 0xbb, 0x4b, 0x51, 0xdd, 0xdf, 0x0e, 0xbd, 0x8e, 0x63, 0xb2, 0x07, ++ 0xbe, 0x26, 0x0f, 0x4c, 0xca, 0xfb, 0x5e, 0xe3, 0xc1, 0xfa, 0x31, 0x7d, ++ 0x59, 0xf6, 0xe2, 0x7c, 0xff, 0xde, 0x41, 0x50, 0xc5, 0x23, 0x2b, 0x7b, ++ 0x06, 0xba, 0x7c, 0x4c, 0xf6, 0x95, 0xd4, 0xde, 0x81, 0x3a, 0x2f, 0x9c, ++ 0x84, 0x4e, 0x0e, 0x2a, 0x7f, 0x12, 0x09, 0x0c, 0x55, 0xd2, 0x92, 0x3f, ++ 0xb9, 0x13, 0xe3, 0x70, 0x1f, 0x2e, 0xa3, 0xcf, 0xe5, 0x76, 0xcb, 0x9e, ++ 0xaa, 0x37, 0xf6, 0xde, 0x12, 0xdf, 0x27, 0xe1, 0xa3, 0xf9, 0x3e, 0x17, ++ 0x0f, 0xaa, 0x93, 0x85, 0x5b, 0xd1, 0xb6, 0x41, 0xf3, 0x96, 0xf7, 0xfc, ++ 0xd9, 0x9e, 0xfa, 0xf7, 0x4f, 0x4c, 0x89, 0xe6, 0xf0, 0x9e, 0x6d, 0xfc, ++ 0xfe, 0xf6, 0xc2, 0x67, 0x30, 0x36, 0x7e, 0x44, 0x96, 0xe6, 0x26, 0x65, ++ 0x79, 0xce, 0x97, 0x33, 0xde, 0xb9, 0x26, 0xed, 0x77, 0xeb, 0x3b, 0xd7, ++ 0x19, 0xac, 0xc3, 0x6a, 0x5e, 0xe5, 0x56, 0x7d, 0x8f, 0xf4, 0x75, 0xd3, ++ 0xfb, 0x26, 0x70, 0xbb, 0xba, 0x3f, 0xb5, 0x5a, 0xde, 0xd9, 0xcf, 0x57, ++ 0x4c, 0x9e, 0x33, 0x78, 0x77, 0xc0, 0xda, 0xeb, 0xde, 0xc7, 0xf4, 0xbd, ++ 0xab, 0xaf, 0xe9, 0xbb, 0xfa, 0xe4, 0xe7, 0xa8, 0xa6, 0xf7, 0x56, 0xe8, ++ 0x1e, 0xfb, 0x7c, 0x4c, 0xaf, 0x1b, 0xd2, 0x79, 0x3e, 0xab, 0xbb, 0xa6, ++ 0xfa, 0xec, 0xd5, 0xd4, 0x63, 0xd4, 0xdf, 0x7b, 0x6b, 0xa8, 0x1b, 0x97, ++ 0xed, 0xe9, 0x1b, 0xfc, 0x3b, 0xe0, 0x2c, 0x3b, 0xa6, 0xef, 0xd7, 0xf9, ++ 0x77, 0xbe, 0x59, 0xe6, 0xdf, 0x03, 0x23, 0xbf, 0xb8, 0x9f, 0x88, 0xb4, ++ 0x3a, 0xaa, 0x9f, 0x47, 0xeb, 0xbe, 0x1d, 0xf2, 0xfb, 0x0c, 0xa1, 0x8f, ++ 0x3b, 0x83, 0xd7, 0xde, 0x11, 0xe7, 0xb7, 0x54, 0x94, 0x45, 0x83, 0xdf, ++ 0x78, 0x33, 0x06, 0x03, 0x6e, 0xda, 0x28, 0x7b, 0x15, 0x3d, 0x05, 0x75, ++ 0x57, 0x22, 0xeb, 0x34, 0xc9, 0xa0, 0xe9, 0xe5, 0xf7, 0xce, 0xaf, 0x95, ++ 0x53, 0x96, 0x6f, 0x8a, 0x48, 0x94, 0xdf, 0x70, 0xf1, 0xfd, 0x7a, 0xdf, ++ 0x2e, 0x84, 0xf5, 0xf7, 0x53, 0x0e, 0xda, 0x7c, 0x9e, 0xf2, 0x5e, 0x28, ++ 0xac, 0xdc, 0xd1, 0x2c, 0xa8, 0x3d, 0x52, 0x00, 0x73, 0x7d, 0x57, 0x92, ++ 0xdf, 0xb0, 0x8b, 0x3c, 0x5d, 0xe1, 0xb7, 0x5c, 0xdb, 0xd5, 0x1d, 0x16, ++ 0xef, 0x5c, 0x90, 0x74, 0x75, 0x29, 0x9b, 0x5c, 0xae, 0x14, 0xc9, 0x53, ++ 0xed, 0x57, 0xc3, 0xda, 0xaf, 0x92, 0xc7, 0xc3, 0xe0, 0xf1, 0x5f, 0xeb, ++ 0x75, 0x61, 0xfb, 0x8c, 0xba, 0x0b, 0x9e, 0x89, 0xf1, 0x6c, 0xea, 0x31, ++ 0x35, 0x17, 0xda, 0x68, 0xb4, 0x7d, 0x47, 0x50, 0xe9, 0xae, 0xfa, 0x46, ++ 0x1e, 0xf2, 0xc9, 0x6f, 0xde, 0x61, 0x5f, 0x4b, 0xfc, 0xb6, 0x7d, 0x58, ++ 0x7d, 0x67, 0x52, 0xae, 0x70, 0x5d, 0xf9, 0x4d, 0xfb, 0x68, 0x9d, 0x3c, ++ 0x06, 0xf5, 0x58, 0x9b, 0x5a, 0x25, 0xea, 0xad, 0x3b, 0xbf, 0x51, 0x29, ++ 0x57, 0xfc, 0xfb, 0x9d, 0x1b, 0x96, 0xa8, 0x13, 0xa2, 0x62, 0x6c, 0xef, ++ 0x3b, 0x9b, 0xb2, 0xfa, 0x6e, 0x25, 0xc1, 0xef, 0x2e, 0xe1, 0x3b, 0x76, ++ 0xe1, 0x99, 0x67, 0xba, 0xbb, 0x91, 0xc2, 0xe6, 0x54, 0xc6, 0x91, 0x3e, ++ 0x2c, 0x39, 0xb5, 0xe7, 0xd6, 0x8c, 0xfc, 0x5e, 0x35, 0x76, 0xb1, 0xf2, ++ 0x80, 0xec, 0x39, 0xf9, 0x10, 0xbf, 0xed, 0x51, 0xdf, 0xe5, 0x67, 0x1d, ++ 0xd2, 0x18, 0x93, 0x09, 0x35, 0xef, 0x42, 0xed, 0x9b, 0x11, 0xc5, 0xfb, ++ 0x5c, 0x2b, 0xd7, 0xb4, 0x50, 0x69, 0x06, 0x8d, 0x01, 0x7d, 0xc7, 0x93, ++ 0x58, 0xdc, 0x9f, 0x7f, 0x94, 0xf7, 0x06, 0x5d, 0x9e, 0xdd, 0xed, 0x29, ++ 0xf1, 0x0e, 0x67, 0x52, 0xc7, 0xe8, 0xdc, 0xb7, 0xe3, 0xd9, 0x00, 0x65, ++ 0xdc, 0x4a, 0x8d, 0xc3, 0xfa, 0x87, 0x25, 0xce, 0x73, 0x65, 0x3d, 0x97, ++ 0xe6, 0xba, 0xb9, 0xf0, 0xde, 0xaa, 0x37, 0x1f, 0x7e, 0x0b, 0x93, 0x2f, ++ 0xd5, 0x7f, 0xc7, 0xa3, 0xbe, 0x11, 0x57, 0xdf, 0xcd, 0x8c, 0x57, 0x3e, ++ 0x21, 0x1f, 0x2b, 0x6d, 0xd4, 0xdf, 0xf0, 0x44, 0xe4, 0x63, 0x95, 0xd7, ++ 0x14, 0x4f, 0xf3, 0xea, 0xfb, 0xa3, 0xb0, 0x5e, 0xb3, 0x98, 0xea, 0xa3, ++ 0xf6, 0x1d, 0x92, 0x55, 0xf7, 0x4d, 0x4a, 0x58, 0xc6, 0xe7, 0x7f, 0xd9, ++ 0xb7, 0x48, 0x8f, 0x08, 0xbf, 0x47, 0xb9, 0xe4, 0x4c, 0xca, 0xe3, 0x73, ++ 0xae, 0x7b, 0x97, 0x43, 0x5c, 0xb7, 0x41, 0x96, 0x63, 0xa3, 0x3b, 0xbe, ++ 0x67, 0xb7, 0x05, 0xca, 0x33, 0x8d, 0xb0, 0xd7, 0xc4, 0x12, 0x12, 0x65, ++ 0x7e, 0x7e, 0x86, 0x7a, 0x1a, 0xc2, 0x1c, 0x2d, 0xf3, 0xaa, 0x7c, 0xa6, ++ 0x95, 0x7b, 0x5e, 0x77, 0x21, 0x8e, 0xfc, 0xb8, 0xe3, 0xd9, 0xe5, 0xcf, ++ 0x2d, 0xec, 0x94, 0xcf, 0x55, 0x22, 0x81, 0xf2, 0x14, 0xef, 0xfa, 0x59, ++ 0xc3, 0x73, 0x92, 0x44, 0x3d, 0xf6, 0x0f, 0x79, 0x89, 0x6f, 0x96, 0xa7, ++ 0x8e, 0xfd, 0xc2, 0xbd, 0x6a, 0xe3, 0x3d, 0x6c, 0xcd, 0xb2, 0xe3, 0xef, ++ 0xeb, 0x21, 0x86, 0x3f, 0xc2, 0x7a, 0x9b, 0x21, 0x07, 0xf0, 0xdb, 0xd0, ++ 0x39, 0xc6, 0x98, 0x57, 0xb5, 0xdd, 0x32, 0x8e, 0xdc, 0x2c, 0x57, 0x57, ++ 0xee, 0x0a, 0x5f, 0x86, 0x6c, 0x27, 0x3c, 0xfe, 0xab, 0x7d, 0xf0, 0x03, ++ 0x12, 0xfc, 0x22, 0xfc, 0xc4, 0x17, 0x1b, 0x94, 0x6d, 0xa7, 0x3f, 0x43, ++ 0xfc, 0x81, 0x18, 0x23, 0x84, 0x7e, 0x1e, 0x6c, 0xf5, 0x64, 0x76, 0x52, ++ 0xe4, 0xcb, 0x4d, 0x92, 0x69, 0x65, 0x0c, 0x2b, 0xbf, 0xc2, 0x7e, 0xd5, ++ 0xeb, 0x59, 0x4a, 0xbe, 0x42, 0x1d, 0xaf, 0x72, 0x2e, 0xc9, 0xf8, 0x8f, ++ 0xe5, 0x93, 0x32, 0x1e, 0xe7, 0x5c, 0x1e, 0x91, 0xc2, 0xdc, 0x63, 0xf8, ++ 0x71, 0x9e, 0xa4, 0xfb, 0x1f, 0xe8, 0x7b, 0x04, 0xa3, 0x52, 0x9c, 0x4a, ++ 0xcb, 0xc4, 0xec, 0x5e, 0x7e, 0xa3, 0x3b, 0x7c, 0x97, 0x3a, 0x5f, 0xb3, ++ 0xe2, 0xc9, 0x40, 0x6f, 0x62, 0x82, 0xf7, 0x26, 0xd4, 0x7c, 0xf6, 0x62, ++ 0x3e, 0xdf, 0x6a, 0xe5, 0xdd, 0xf3, 0xab, 0xb0, 0xbf, 0xc6, 0x71, 0xca, ++ 0xa1, 0x65, 0x76, 0x06, 0x98, 0xdf, 0x8d, 0xd8, 0x99, 0x65, 0xbb, 0x25, ++ 0x78, 0x64, 0xc5, 0xce, 0xa3, 0x5c, 0x9f, 0xf3, 0xaa, 0xf6, 0xff, 0x11, ++ 0x6d, 0x51, 0xef, 0x88, 0xdf, 0xd6, 0xaf, 0xc3, 0xb6, 0x9c, 0xe7, 0x4e, ++ 0xc4, 0xec, 0x3e, 0x5d, 0x90, 0xc3, 0x78, 0x3d, 0xbf, 0xa3, 0x6b, 0xf8, ++ 0x1d, 0x22, 0xde, 0x04, 0xbf, 0xc8, 0xe3, 0xa0, 0xe6, 0xf1, 0x9b, 0xe8, ++ 0xdf, 0x5f, 0x83, 0xbb, 0x50, 0x66, 0xea, 0x6f, 0x03, 0xdf, 0x0a, 0xdf, ++ 0xc9, 0x73, 0xd6, 0x7f, 0xb0, 0xd5, 0x93, 0x35, 0xd2, 0xb3, 0x1e, 0xcf, ++ 0x3b, 0xdb, 0xbc, 0x75, 0xd9, 0x0d, 0x7e, 0xf1, 0x4e, 0x67, 0xaf, 0xfa, ++ 0x4e, 0x20, 0x33, 0xb6, 0x1b, 0xb2, 0xe3, 0xcf, 0xab, 0x17, 0x32, 0xc6, ++ 0x33, 0x0b, 0xd6, 0xaf, 0xe7, 0x89, 0xe7, 0xf7, 0x82, 0xdc, 0x77, 0xb0, ++ 0x39, 0x57, 0x60, 0xc2, 0x2f, 0xab, 0xef, 0x82, 0x60, 0x27, 0xdf, 0xb6, ++ 0xf2, 0x5d, 0xd0, 0xf5, 0xd7, 0x78, 0xa0, 0xcd, 0xf3, 0x51, 0x26, 0x78, ++ 0xd2, 0xa2, 0xdb, 0xec, 0x06, 0x3e, 0xe5, 0x5e, 0x6c, 0x32, 0xfe, 0xa0, ++ 0xf8, 0xe3, 0xb8, 0xdb, 0x19, 0x73, 0x0e, 0xf6, 0xf7, 0x22, 0xbe, 0x56, ++ 0xf7, 0x65, 0xe2, 0xbc, 0x7f, 0x93, 0x0c, 0xec, 0x56, 0x77, 0x27, 0x2e, ++ 0xac, 0xfa, 0xb6, 0x2b, 0x25, 0x4f, 0xd5, 0x64, 0x65, 0xf8, 0x27, 0x62, ++ 0x49, 0xe2, 0x26, 0xca, 0x0a, 0xfb, 0xdd, 0xcb, 0x79, 0xc6, 0x1f, 0x52, ++ 0xf3, 0x34, 0x11, 0xc3, 0xf1, 0x9e, 0x83, 0x19, 0x28, 0xcf, 0x72, 0xdd, ++ 0x91, 0x2e, 0xf0, 0xd9, 0x3f, 0x6b, 0x55, 0x76, 0x05, 0xe3, 0xb2, 0x8c, ++ 0xb6, 0x91, 0xef, 0xd3, 0xfa, 0x2c, 0xf6, 0xc3, 0x6d, 0xbc, 0x0f, 0x90, ++ 0x47, 0xd9, 0xdc, 0xc2, 0xfa, 0xb4, 0x7d, 0x5c, 0xc9, 0xc1, 0x23, 0xe0, ++ 0xfb, 0x1f, 0xa3, 0xee, 0x63, 0x48, 0x39, 0xc7, 0xf4, 0xca, 0xba, 0x93, ++ 0xdf, 0x1f, 0x90, 0x01, 0xc8, 0x05, 0xf3, 0x8f, 0x48, 0x51, 0xdd, 0x63, ++ 0x42, 0x3a, 0xc7, 0x67, 0xda, 0x7a, 0x5b, 0xfb, 0x53, 0xd2, 0xb2, 0x5b, ++ 0x7f, 0x4f, 0xe6, 0xcb, 0xd3, 0x2e, 0xdd, 0x6e, 0x6c, 0x85, 0x57, 0x0f, ++ 0x5d, 0x83, 0x37, 0xc2, 0x2b, 0x78, 0xc3, 0x1b, 0xeb, 0xf1, 0x36, 0x1f, ++ 0x6b, 0x78, 0x73, 0xf0, 0xb0, 0x86, 0x27, 0xe7, 0x7b, 0x25, 0x04, 0x39, ++ 0x0e, 0xd6, 0xe4, 0x18, 0xb8, 0xc7, 0xd3, 0x99, 0x09, 0x9e, 0x21, 0x2a, ++ 0x3e, 0x53, 0x0e, 0x29, 0xbf, 0x5c, 0xc7, 0xfa, 0xb5, 0x7e, 0xcf, 0x2f, ++ 0x59, 0xeb, 0x97, 0xdb, 0x7c, 0xfc, 0xf0, 0x77, 0xd3, 0x83, 0x0b, 0x6d, ++ 0x35, 0x3d, 0xb8, 0xf9, 0x37, 0xa4, 0x07, 0x6b, 0xe5, 0xb2, 0x5e, 0xa6, ++ 0x4c, 0xc8, 0x13, 0xd7, 0x8b, 0xf2, 0x44, 0x39, 0x22, 0x2f, 0x69, 0x4f, ++ 0x1b, 0x19, 0x3b, 0xc5, 0xaf, 0xa8, 0xef, 0x36, 0x26, 0x61, 0x83, 0xda, ++ 0x02, 0x73, 0x73, 0x31, 0x29, 0x2e, 0xbc, 0x4f, 0xc9, 0xf4, 0x53, 0x55, ++ 0xda, 0xa5, 0xeb, 0xcd, 0x7d, 0xb5, 0xcd, 0xcd, 0xaf, 0xb1, 0xb9, 0xf9, ++ 0x15, 0x9b, 0xdb, 0xaa, 0xe3, 0xa5, 0xbf, 0x8b, 0xcd, 0x8d, 0xd5, 0x9d, ++ 0xcb, 0xf8, 0x67, 0x32, 0x12, 0xc8, 0xf6, 0x44, 0x65, 0x07, 0xfc, 0xc8, ++ 0xf0, 0xd4, 0x4e, 0xf9, 0x97, 0x53, 0x93, 0xea, 0x8e, 0xd2, 0x5f, 0x38, ++ 0xc9, 0xf8, 0x03, 0x01, 0x57, 0x3e, 0x80, 0x78, 0x77, 0xbc, 0xa3, 0x41, ++ 0x76, 0xbc, 0x4b, 0x9d, 0x35, 0x9a, 0xd9, 0x40, 0xbb, 0x70, 0x17, 0x3c, ++ 0xe7, 0x58, 0x4e, 0x22, 0xc0, 0xfb, 0x6a, 0x8d, 0x32, 0x1e, 0x6b, 0x96, ++ 0x9d, 0xc0, 0x4e, 0x85, 0x1b, 0x1c, 0xf5, 0x2d, 0x79, 0x46, 0x9d, 0xe5, ++ 0xdc, 0xb2, 0xd9, 0x1b, 0x17, 0x7c, 0x68, 0x31, 0xe5, 0xab, 0xd5, 0x5b, ++ 0xd4, 0x77, 0xd1, 0x17, 0x4a, 0xd5, 0xd6, 0xd5, 0x79, 0x3e, 0xff, 0x7b, ++ 0xd4, 0x89, 0x81, 0x57, 0xf5, 0x77, 0x7f, 0x82, 0x8a, 0x9f, 0xc5, 0xb9, ++ 0x31, 0x75, 0xa7, 0xea, 0x4a, 0x90, 0xfc, 0x52, 0x71, 0x53, 0x3c, 0x1b, ++ 0x04, 0xc6, 0x99, 0x01, 0x92, 0xb6, 0x19, 0xf3, 0x69, 0xfc, 0x09, 0xfb, ++ 0xbf, 0x47, 0x9d, 0xed, 0x2e, 0x81, 0x37, 0xae, 0xda, 0xfb, 0xcd, 0xc7, ++ 0x88, 0xeb, 0x6b, 0xf7, 0x87, 0xaf, 0xc5, 0xf7, 0xde, 0xb7, 0x67, 0xfa, ++ 0x1c, 0x42, 0xef, 0x15, 0xe9, 0x18, 0x5c, 0x9d, 0xab, 0xad, 0xf7, 0x7f, ++ 0x29, 0x88, 0xf5, 0xf8, 0x7f, 0x0f, 0x88, 0xed, 0xac, 0xc3, 0x73, 0xe2, ++ 0xa8, 0x38, 0x30, 0x43, 0xfe, 0x96, 0xb1, 0x4e, 0xd3, 0x71, 0xdf, 0x9f, ++ 0x07, 0x3a, 0xcf, 0xd6, 0xc7, 0x81, 0xec, 0x23, 0xa2, 0xee, 0x63, 0xd4, ++ 0xfe, 0x0f, 0x0e, 0xf7, 0x77, 0x32, 0x81, 0x7b, 0x4a, 0x93, 0x12, 0x3c, ++ 0x3a, 0x2a, 0xa1, 0x69, 0xee, 0xa5, 0x67, 0xa4, 0x18, 0x73, 0xe5, 0x63, ++ 0xce, 0xea, 0xd8, 0xa4, 0xd3, 0x58, 0x4b, 0xfb, 0x23, 0x32, 0x78, 0xf2, ++ 0x31, 0x09, 0x1f, 0xe5, 0xbb, 0x55, 0xe7, 0x28, 0xb0, 0x47, 0x1b, 0x64, ++ 0x2e, 0xc6, 0xfd, 0xe4, 0xb0, 0x3a, 0x97, 0x5e, 0x1e, 0x7b, 0x2d, 0x5c, ++ 0x04, 0x56, 0xc8, 0x2b, 0xdb, 0x82, 0x74, 0x25, 0x96, 0x38, 0xbc, 0x99, ++ 0x3a, 0x85, 0x18, 0x33, 0x30, 0x3e, 0x17, 0x56, 0xf7, 0x83, 0x96, 0x63, ++ 0xac, 0x8b, 0xf8, 0xfd, 0x28, 0x71, 0x06, 0x6c, 0xc7, 0xa8, 0x44, 0x99, ++ 0x0f, 0x1e, 0xad, 0xe1, 0x0c, 0xda, 0x84, 0x41, 0x27, 0x26, 0xa1, 0x53, ++ 0xde, 0xdc, 0xf9, 0x8f, 0x95, 0x8c, 0x13, 0x3b, 0x25, 0x38, 0xcd, 0xe7, ++ 0xfa, 0x78, 0x88, 0xd8, 0x1d, 0xbe, 0xe1, 0xec, 0x67, 0xd1, 0x1f, 0xdf, ++ 0x65, 0xf4, 0x37, 0xba, 0xc8, 0x97, 0xff, 0xb6, 0xff, 0x43, 0x81, 0xb2, ++ 0xff, 0xff, 0x01, 0xe6, 0x8e, 0x9a, 0x21, 0xc0, 0x4e, 0x00, 0x00, 0x00 }; + + static const u32 bnx2_COM_b06FwData[(0x0/4) + 1] = { 0x0 }; + static const u32 bnx2_COM_b06FwRodata[(0x14/4) + 1] = { +- 0x08000e7c, 0x08000ec4, 0x08000f04, 0x08000f50, 0x08000f84, 0x00000000 ++ 0x08000e7c, 0x08000ec4, 0x08000ef8, 0x08000f44, 0x08000f78, 0x00000000 + }; + + static struct fw_info bnx2_com_fw_06 = { +- /* Firmware version: 4.6.16 */ ++ /* Firmware version: 4.4.2 */ + .ver_major = 0x4, +- .ver_minor = 0x6, +- .ver_fix = 0x10, ++ .ver_minor = 0x4, ++ .ver_fix = 0x2, + + .start_addr = 0x080000f8, + + .text_addr = 0x08000000, +- .text_len = 0x4da4, ++ .text_len = 0x4ebc, + .text_index = 0x0, + .gz_text = bnx2_COM_b06FwText, + .gz_text_len = sizeof(bnx2_COM_b06FwText), +@@ -867,15 +872,15 @@ + .data_index = 0x0, + .data = bnx2_COM_b06FwData, + +- .sbss_addr = 0x08004de0, ++ .sbss_addr = 0x08004f00, + .sbss_len = 0x38, + .sbss_index = 0x0, + +- .bss_addr = 0x08004e18, ++ .bss_addr = 0x08004f38, + .bss_len = 0xbc, + .bss_index = 0x0, + +- .rodata_addr = 0x08004da4, ++ .rodata_addr = 0x08004ebc, + .rodata_len = 0x14, + .rodata_index = 0x0, + .rodata = bnx2_COM_b06FwRodata, +@@ -898,1219 +903,1232 @@ + }; + + static u8 bnx2_CP_b06FwText[] = { +- 0x9d, 0xbc, 0x0d, 0x7c, 0x1b, 0xe5, 0x95, 0x2e, 0xfe, 0xcc, 0x48, 0xb2, +- 0x65, 0x5b, 0xb6, 0xc7, 0x8e, 0x92, 0x28, 0xac, 0x37, 0xd1, 0xc4, 0x23, +- 0x47, 0xc1, 0xa6, 0x8c, 0x12, 0x27, 0xa8, 0xac, 0x4a, 0x54, 0xc7, 0x24, +- 0x4e, 0x48, 0xc1, 0x29, 0x69, 0x6b, 0xb8, 0x2d, 0xa8, 0xf9, 0xc2, 0x84, +- 0x40, 0x43, 0xcb, 0xde, 0x6b, 0xee, 0xed, 0xae, 0x55, 0xdb, 0x49, 0x9c, +- 0x44, 0x96, 0x6c, 0xc7, 0x24, 0xa1, 0xdb, 0xff, 0xa2, 0xc4, 0xce, 0x07, +- 0x54, 0xb6, 0xd2, 0x96, 0xee, 0x86, 0xde, 0x74, 0xd1, 0x4d, 0x02, 0x18, +- 0xca, 0x47, 0xda, 0xe5, 0x76, 0x69, 0x7f, 0xbd, 0xc5, 0x97, 0x42, 0x08, +- 0x5b, 0x0a, 0xe9, 0xe7, 0x86, 0x7e, 0x30, 0xf7, 0x39, 0x23, 0x29, 0x31, +- 0x2c, 0xdb, 0x76, 0xff, 0xfa, 0xfd, 0xe6, 0x27, 0xcd, 0xe8, 0xfd, 0x38, +- 0xef, 0x79, 0xcf, 0x79, 0xce, 0x73, 0xde, 0x79, 0x67, 0xfc, 0x40, 0x39, +- 0x0a, 0x9f, 0x4a, 0x1e, 0x1f, 0x6a, 0xde, 0xb6, 0x61, 0x69, 0xe8, 0x43, +- 0x4b, 0xe5, 0xdc, 0xa9, 0x95, 0x38, 0xf1, 0x67, 0x7e, 0xfc, 0x7f, 0x6e, +- 0xc1, 0xc2, 0x47, 0xe1, 0xd1, 0x58, 0xf8, 0xed, 0x00, 0xb4, 0x62, 0xff, +- 0x72, 0xc0, 0xad, 0x46, 0xc6, 0x3a, 0x5a, 0x0c, 0xb8, 0x1d, 0x91, 0x6d, +- 0xb7, 0x6f, 0x30, 0x80, 0x68, 0xa6, 0xd1, 0xbf, 0x1c, 0x7f, 0xb0, 0xe2, +- 0x5e, 0x27, 0xe4, 0xfa, 0x5f, 0x46, 0x7e, 0xdf, 0xfd, 0xed, 0x6b, 0xf4, +- 0x0b, 0x69, 0x07, 0xdc, 0x5a, 0x24, 0x0e, 0xad, 0x01, 0xee, 0x3a, 0xd6, +- 0xf9, 0xca, 0x82, 0xaf, 0x28, 0xa8, 0x2a, 0xb6, 0x75, 0xde, 0xfa, 0xf6, +- 0x02, 0x5f, 0xac, 0x2c, 0xa2, 0xe1, 0xf1, 0x2c, 0xda, 0x9b, 0x06, 0xba, +- 0xad, 0x4a, 0x23, 0x04, 0xb7, 0x61, 0x74, 0x0c, 0x28, 0x9e, 0xf0, 0x96, +- 0x25, 0xf0, 0x94, 0x1a, 0x88, 0x5f, 0x11, 0x41, 0xfb, 0x95, 0xe3, 0xe5, +- 0x71, 0x67, 0xc4, 0x8d, 0xb6, 0xac, 0x3b, 0xfe, 0x17, 0x11, 0x03, 0x2b, +- 0xb3, 0x46, 0x19, 0xaa, 0x34, 0xf4, 0x65, 0x5f, 0x77, 0xe7, 0xdb, 0x6b, +- 0x2e, 0x7c, 0xdf, 0x56, 0x9b, 0xff, 0x9e, 0x15, 0x73, 0x46, 0x80, 0xed, +- 0x09, 0xcb, 0x2a, 0x89, 0xdc, 0x7c, 0xb3, 0x1a, 0x31, 0x7c, 0x47, 0xb0, +- 0x0c, 0xeb, 0x35, 0x7c, 0x71, 0x47, 0xf3, 0x2f, 0x94, 0x53, 0x23, 0x4d, +- 0x88, 0x1f, 0x75, 0x20, 0xaa, 0x3d, 0xcb, 0xef, 0xb9, 0x73, 0x3b, 0xc2, +- 0x4d, 0x38, 0x70, 0xf4, 0x22, 0xaf, 0x3b, 0xed, 0x6b, 0xbd, 0xfb, 0xe7, +- 0xce, 0xbd, 0x25, 0xfc, 0x2c, 0x1e, 0x3c, 0x2a, 0xbf, 0xef, 0x40, 0x77, +- 0x93, 0x82, 0xa9, 0x9b, 0x37, 0xc3, 0x61, 0x34, 0xa1, 0x6f, 0xbf, 0xe2, +- 0xec, 0x69, 0x52, 0x11, 0xf5, 0xea, 0xc1, 0x18, 0x27, 0xc1, 0x69, 0x20, +- 0x56, 0x1a, 0x09, 0x3b, 0xdf, 0x48, 0x44, 0x34, 0x87, 0x61, 0x59, 0xc1, +- 0xd0, 0x6c, 0x38, 0x6a, 0x2c, 0xeb, 0x31, 0xd3, 0x03, 0xff, 0xa7, 0x9e, +- 0x47, 0x7c, 0xb4, 0x1d, 0xaa, 0xf1, 0x3c, 0x7a, 0x46, 0x9f, 0xc7, 0x43, +- 0x7b, 0xcb, 0x31, 0x35, 0x83, 0xe3, 0x4d, 0xf9, 0xf0, 0xed, 0x05, 0xd2, +- 0xb7, 0xc8, 0xd1, 0xcc, 0xc3, 0x8d, 0x29, 0xc7, 0x39, 0x7e, 0x4b, 0x99, +- 0x8b, 0xd6, 0xd4, 0xec, 0xcb, 0x65, 0xb6, 0xb3, 0x4c, 0xdf, 0xfb, 0xca, +- 0xc4, 0x47, 0x23, 0xf8, 0x4e, 0x42, 0xc1, 0x96, 0x50, 0x15, 0xa2, 0x35, +- 0x32, 0x5e, 0xcb, 0x3a, 0x6a, 0x9e, 0xb3, 0xa6, 0x34, 0xe9, 0x6b, 0x12, +- 0xcf, 0xf2, 0xbf, 0x1d, 0xa1, 0x57, 0xad, 0x9c, 0x57, 0xda, 0xfb, 0x3c, +- 0x6d, 0x68, 0x2d, 0xaf, 0x3b, 0x91, 0x4a, 0x20, 0x56, 0x15, 0xf9, 0x04, +- 0xcf, 0x75, 0xf3, 0x2d, 0xc5, 0xed, 0x7e, 0x3b, 0xe1, 0xfe, 0x54, 0xa5, +- 0xa1, 0xde, 0x57, 0x0d, 0x27, 0x9e, 0xa3, 0xcc, 0x27, 0xcc, 0xcd, 0x70, +- 0x19, 0x5f, 0x10, 0x9b, 0xe3, 0xb8, 0x5e, 0xb4, 0x30, 0xbb, 0x58, 0x5f, +- 0xda, 0xd5, 0xb0, 0x23, 0x65, 0x59, 0xbb, 0xcc, 0xe8, 0x87, 0xcb, 0x68, +- 0x10, 0xa7, 0x13, 0xed, 0x70, 0x47, 0x02, 0xfe, 0xf3, 0x08, 0x63, 0x79, +- 0xd6, 0x8b, 0x27, 0x12, 0x70, 0xb6, 0x2c, 0xa8, 0x43, 0x4f, 0x36, 0x82, +- 0xeb, 0xb3, 0x26, 0x5a, 0xb3, 0x7f, 0xda, 0xca, 0x6e, 0x48, 0xf9, 0x39, +- 0x86, 0x3f, 0x58, 0xf9, 0x31, 0xc8, 0xf8, 0xe4, 0x9b, 0xf3, 0x9a, 0xba, +- 0x02, 0xbb, 0x47, 0x0c, 0xec, 0xe4, 0xfc, 0xad, 0x0a, 0xe5, 0xa2, 0x65, +- 0xd0, 0xcd, 0xf3, 0x88, 0x60, 0x45, 0xd6, 0xe0, 0x9c, 0x46, 0xb0, 0x3c, +- 0x55, 0xaf, 0x8d, 0x62, 0x21, 0xa2, 0xbe, 0xbc, 0x6d, 0xef, 0xe1, 0x78, +- 0xd7, 0x07, 0xda, 0x51, 0x49, 0x1b, 0xc9, 0x2c, 0x09, 0xa3, 0x85, 0xfd, +- 0xaf, 0xf9, 0x33, 0xfa, 0xbf, 0x89, 0xfd, 0xbf, 0xc5, 0xfe, 0x73, 0x76, +- 0xff, 0x70, 0xae, 0xe6, 0xb9, 0x9b, 0xf6, 0xb8, 0x3b, 0xe3, 0x74, 0xae, +- 0x4a, 0x79, 0xb1, 0x2b, 0x63, 0xd2, 0xe6, 0xe4, 0x2f, 0x1f, 0x76, 0x8c, +- 0xd4, 0x61, 0xe7, 0x88, 0xee, 0x7b, 0x8a, 0xbf, 0x7b, 0xc7, 0xae, 0xc0, +- 0xf6, 0x11, 0x05, 0x87, 0x8c, 0x2b, 0xd0, 0xc3, 0xdf, 0x07, 0x46, 0xe6, +- 0xe2, 0xc1, 0x11, 0x07, 0xc2, 0x33, 0xa6, 0x8f, 0x43, 0xbe, 0xaf, 0x40, +- 0x7c, 0xcc, 0x8f, 0x9e, 0xc4, 0xb3, 0xb6, 0x0e, 0x2b, 0x23, 0xdf, 0x2e, +- 0xfa, 0x33, 0x7d, 0xc7, 0x8f, 0x0d, 0x09, 0x1f, 0x7a, 0x52, 0xe2, 0x07, +- 0x6e, 0xda, 0xa6, 0xf8, 0xc1, 0xaf, 0x80, 0x2a, 0xb6, 0x9f, 0x2d, 0xfe, +- 0xaf, 0xc0, 0xc9, 0x79, 0xdb, 0xc8, 0xff, 0x76, 0xa5, 0xc4, 0x26, 0xa4, +- 0x4d, 0xb1, 0x0b, 0xf9, 0x5d, 0x4b, 0xbb, 0x2b, 0x87, 0xff, 0x70, 0x39, +- 0x82, 0x0f, 0x68, 0x78, 0xad, 0x59, 0xae, 0xd3, 0xde, 0x43, 0x52, 0x66, +- 0x10, 0x47, 0x32, 0xe2, 0xa7, 0x7e, 0xb4, 0x24, 0x26, 0xd9, 0x7e, 0x33, +- 0xdb, 0x36, 0xf1, 0x4f, 0xd9, 0x26, 0xfc, 0x63, 0x36, 0x88, 0x7f, 0xa0, +- 0x1e, 0xbf, 0x99, 0xf5, 0xe3, 0xd1, 0x6c, 0x1d, 0xbe, 0x91, 0xf5, 0xe1, +- 0xeb, 0x9c, 0xbf, 0xaf, 0x65, 0xdb, 0x69, 0xfb, 0x1a, 0x8e, 0x67, 0x45, +- 0xff, 0x25, 0x1c, 0x6f, 0x39, 0x7a, 0x47, 0xea, 0x83, 0xa7, 0x69, 0x5b, +- 0xff, 0x60, 0xae, 0x46, 0xae, 0xb6, 0xd9, 0xb6, 0xc9, 0x5d, 0xbc, 0xbe, +- 0x7b, 0xa4, 0x3e, 0x7a, 0xa5, 0x62, 0x59, 0x6a, 0xa8, 0x31, 0x7c, 0x4a, +- 0x55, 0x31, 0xe5, 0xd5, 0xfd, 0x39, 0x55, 0xf7, 0x47, 0xe1, 0x42, 0x82, +- 0xbe, 0x11, 0x9f, 0xa9, 0xa7, 0xe3, 0xb4, 0x29, 0xaf, 0x31, 0xca, 0xf1, +- 0xe8, 0xfe, 0xb8, 0xaa, 0x61, 0x67, 0x4a, 0x3f, 0x10, 0x57, 0xbd, 0x88, +- 0x67, 0xcb, 0xf1, 0xb3, 0x11, 0xbd, 0x3f, 0xae, 0xde, 0x88, 0x78, 0xad, +- 0x65, 0x7d, 0x3d, 0x84, 0x6d, 0xb3, 0x23, 0x88, 0xce, 0x8c, 0x20, 0x36, +- 0x37, 0x52, 0x87, 0x54, 0x0a, 0x78, 0x6b, 0xc0, 0xf0, 0xfd, 0x8b, 0xd2, +- 0x8e, 0xbf, 0x6e, 0xd7, 0xfd, 0x7e, 0xb5, 0x31, 0x3e, 0xaa, 0x2e, 0xa1, +- 0x4b, 0xc3, 0xef, 0x8b, 0xac, 0x44, 0x97, 0x7d, 0x4d, 0x81, 0x66, 0x78, +- 0xd1, 0x9b, 0xfa, 0x30, 0x62, 0xde, 0xfa, 0x8e, 0x21, 0xb5, 0xfe, 0xa2, +- 0xa9, 0xea, 0x93, 0xed, 0xaa, 0x65, 0xfd, 0x7c, 0xf1, 0x5b, 0x96, 0x7f, +- 0x96, 0x65, 0x2d, 0x5a, 0x2c, 0x7d, 0xfa, 0x51, 0x13, 0x31, 0xb1, 0xd6, +- 0x9e, 0xc3, 0x72, 0x9c, 0x1b, 0xa9, 0x65, 0x1f, 0x1a, 0xfe, 0xf7, 0x35, +- 0x7a, 0x70, 0xb3, 0x5a, 0x8e, 0xd7, 0xc6, 0xca, 0xf1, 0x0a, 0xc7, 0xf3, +- 0x8b, 0x11, 0x1f, 0x7e, 0x35, 0x62, 0x59, 0x9f, 0x32, 0xff, 0x0a, 0xc3, +- 0xb5, 0x83, 0xf8, 0xc7, 0x09, 0x2f, 0x7e, 0x96, 0xd0, 0xf0, 0x6a, 0x22, +- 0x7a, 0xef, 0x0c, 0xe8, 0xd1, 0x09, 0xe5, 0xf4, 0xed, 0x55, 0x68, 0x6c, +- 0xaf, 0x52, 0xf4, 0xb6, 0x3d, 0xd0, 0x7d, 0x57, 0x2a, 0x5e, 0x9c, 0xcf, +- 0x68, 0xf8, 0x49, 0xa6, 0x3e, 0xfc, 0xcf, 0xec, 0xf3, 0x37, 0xe6, 0x63, +- 0x56, 0x6e, 0x96, 0xe8, 0x4d, 0x74, 0x44, 0x3d, 0xa7, 0xa8, 0xe7, 0x14, +- 0xf5, 0x9c, 0xa2, 0x9e, 0x29, 0xc3, 0xa3, 0x29, 0xea, 0x99, 0xba, 0xfb, +- 0x3a, 0x6d, 0xea, 0x6b, 0x9c, 0xc7, 0xe3, 0xf6, 0x3c, 0x86, 0x39, 0x5f, +- 0x7f, 0x81, 0xbf, 0xb5, 0xb1, 0xf5, 0x59, 0xeb, 0xbf, 0x79, 0x65, 0x4c, +- 0x0f, 0xcf, 0xcc, 0xe3, 0x97, 0x8c, 0xed, 0x3b, 0x56, 0x4c, 0x93, 0x71, +- 0xc9, 0xf8, 0x6c, 0xfd, 0xf9, 0xb7, 0x29, 0x3b, 0x15, 0x94, 0x5b, 0xd6, +- 0x5e, 0xb3, 0xf0, 0xbf, 0xb7, 0x38, 0xbe, 0x9b, 0x95, 0xbc, 0x5d, 0xfd, +- 0x5d, 0x29, 0xf5, 0x1d, 0x8c, 0xaa, 0x2b, 0x79, 0xae, 0xc7, 0xa3, 0xf8, +- 0xa8, 0xe3, 0xbd, 0xe7, 0xf7, 0x7a, 0x65, 0x3e, 0xfc, 0x97, 0xce, 0x69, +- 0x8f, 0x76, 0x7f, 0x77, 0xf2, 0x5c, 0xc6, 0x22, 0xb6, 0x28, 0x36, 0xe0, +- 0xa5, 0xbd, 0x5c, 0x53, 0xf8, 0x0f, 0x71, 0x35, 0xb2, 0x0d, 0xed, 0xcd, +- 0x8f, 0xd8, 0x7d, 0x94, 0x24, 0xc5, 0x6f, 0x14, 0xbc, 0xf5, 0x61, 0x05, +- 0xa7, 0x42, 0x06, 0x6d, 0xe6, 0x18, 0x71, 0x01, 0x28, 0x4d, 0xc2, 0xed, +- 0x89, 0x44, 0x90, 0x18, 0x80, 0xbb, 0x2c, 0x12, 0xc6, 0xc2, 0x81, 0xfa, +- 0xce, 0x73, 0xd0, 0x83, 0x03, 0x8a, 0xde, 0xce, 0x58, 0x62, 0x8e, 0x53, +- 0x8f, 0x57, 0x2a, 0xba, 0xbf, 0x44, 0x81, 0x5b, 0x61, 0xb9, 0x40, 0xe6, +- 0x18, 0x76, 0x66, 0xe5, 0x77, 0x18, 0x46, 0xe6, 0x37, 0xc5, 0xbe, 0x24, +- 0xa6, 0xd0, 0xee, 0xcf, 0x71, 0xec, 0xba, 0x9f, 0xf8, 0xea, 0x76, 0x45, +- 0x3a, 0x71, 0x38, 0x01, 0x77, 0x49, 0x64, 0x2b, 0x9e, 0x4c, 0x84, 0x67, +- 0x16, 0xcb, 0x29, 0x2c, 0xe7, 0xcf, 0x4c, 0x97, 0xe5, 0xc7, 0x56, 0xd4, +- 0x9b, 0x97, 0xa5, 0x3c, 0x79, 0x0c, 0x7b, 0x52, 0x52, 0x37, 0x62, 0xd7, +- 0x75, 0xb2, 0x8f, 0xbe, 0x44, 0x7d, 0xdb, 0x0d, 0x8a, 0x1e, 0x7e, 0x98, +- 0xf3, 0xd7, 0x83, 0xc6, 0xe8, 0x1b, 0xd0, 0xb5, 0x4e, 0xe4, 0x65, 0x59, +- 0x90, 0xc9, 0xcb, 0x31, 0x3f, 0x03, 0xe5, 0xf6, 0x14, 0xac, 0x39, 0x06, +- 0x3c, 0x3e, 0xc3, 0xf0, 0xbf, 0xe3, 0xa8, 0xc5, 0x01, 0xce, 0x4f, 0x1f, +- 0x7d, 0x45, 0xf0, 0xec, 0xee, 0xbd, 0x7e, 0x78, 0x0c, 0x0b, 0x47, 0x42, +- 0xb5, 0x78, 0x96, 0x58, 0x5b, 0x45, 0xdf, 0x7c, 0x5e, 0x43, 0x74, 0x4e, +- 0x24, 0xac, 0xdc, 0x92, 0x1d, 0x2d, 0xcc, 0xc1, 0x8b, 0x35, 0x05, 0x19, +- 0xdf, 0x77, 0xbd, 0x5a, 0xf9, 0xe0, 0xeb, 0x50, 0x3a, 0x52, 0x7a, 0x30, +- 0x0e, 0x0b, 0xd5, 0x8b, 0x75, 0xff, 0x94, 0xf2, 0x96, 0x8a, 0x2a, 0x62, +- 0x75, 0xf6, 0xfd, 0xe5, 0x1a, 0xb5, 0x31, 0xc6, 0x65, 0x07, 0x43, 0x5f, +- 0x54, 0xd3, 0x4d, 0x36, 0x13, 0x74, 0xd9, 0xd7, 0x1c, 0x48, 0x3b, 0xa3, +- 0x3e, 0x07, 0x7e, 0x6f, 0x45, 0xd7, 0xc9, 0xb5, 0x72, 0xc4, 0xda, 0x1b, +- 0x7d, 0x4e, 0x34, 0x86, 0xb7, 0xd3, 0x07, 0xa7, 0xd6, 0xb5, 0xf0, 0xbf, +- 0x80, 0x79, 0x1a, 0xf5, 0xfe, 0xed, 0x90, 0xdf, 0xef, 0xd0, 0x6e, 0x5a, +- 0xa4, 0x2e, 0xcb, 0x88, 0x1d, 0xea, 0x9a, 0xf8, 0x78, 0x9f, 0x69, 0x59, +- 0x87, 0xcd, 0x13, 0x4a, 0x4b, 0xea, 0x5d, 0x2b, 0xea, 0x8c, 0x47, 0x4b, +- 0x23, 0x01, 0x73, 0x27, 0xc1, 0xd8, 0x11, 0x89, 0x2b, 0xd1, 0x6c, 0x9f, +- 0x72, 0x7d, 0xb6, 0x5f, 0x59, 0x91, 0x95, 0xf2, 0x27, 0x94, 0xe5, 0x59, +- 0x29, 0x5f, 0x2c, 0x1b, 0x66, 0x59, 0xe0, 0x48, 0x22, 0x10, 0x2c, 0x96, +- 0x5f, 0xc1, 0xb2, 0xd7, 0x5f, 0x2a, 0x1b, 0xa6, 0xad, 0x9a, 0x9c, 0x97, +- 0x0a, 0x6c, 0xd6, 0xf4, 0x68, 0x9c, 0x3a, 0x2f, 0x8d, 0xf8, 0x6e, 0x7d, +- 0xdd, 0xc8, 0x05, 0x1d, 0x9c, 0x83, 0xa3, 0x1c, 0x59, 0x2b, 0x71, 0x6e, +- 0x83, 0xe1, 0x42, 0xbf, 0x56, 0x8d, 0x0d, 0xe6, 0x6f, 0xad, 0xcd, 0xeb, +- 0xe4, 0xbf, 0xbc, 0x6c, 0xb0, 0xcb, 0xd7, 0xb1, 0xbc, 0x6e, 0x1e, 0x2d, +- 0x60, 0xeb, 0xa9, 0x04, 0x06, 0x1d, 0x11, 0x62, 0x7e, 0x73, 0xc0, 0xdf, +- 0x03, 0x99, 0x1b, 0x3f, 0xae, 0xa7, 0x2c, 0x69, 0xe7, 0x74, 0xfc, 0x45, +- 0xfc, 0x72, 0x19, 0xb9, 0x26, 0xe5, 0xa6, 0x68, 0xdf, 0x82, 0x75, 0x96, +- 0x35, 0x64, 0x8a, 0x9d, 0xfb, 0x68, 0xe7, 0x33, 0xe1, 0xaf, 0xd5, 0xe3, +- 0x69, 0x56, 0x38, 0x9c, 0x98, 0x81, 0xb4, 0xa6, 0x12, 0x73, 0xef, 0xf2, +- 0xa0, 0x2a, 0xaa, 0x94, 0x90, 0xdb, 0x60, 0x42, 0xc6, 0x59, 0x89, 0xa8, +- 0x53, 0x0f, 0xca, 0xdc, 0x95, 0x30, 0xe6, 0x35, 0xa8, 0xac, 0x77, 0xc9, +- 0x97, 0x65, 0xcc, 0x7e, 0xfa, 0x72, 0xdc, 0xd6, 0x51, 0xeb, 0xa5, 0x71, +- 0x4b, 0x7b, 0x45, 0x1d, 0xfd, 0x67, 0xea, 0x59, 0xd6, 0x8e, 0x4b, 0xba, +- 0x2d, 0x89, 0x96, 0x51, 0xb7, 0xc7, 0x12, 0x81, 0xf0, 0xd3, 0x88, 0x2b, +- 0x6d, 0x59, 0x27, 0xc6, 0x12, 0x52, 0xaf, 0x8f, 0xe5, 0xfb, 0x95, 0x95, +- 0x97, 0xea, 0x4c, 0x15, 0xfc, 0x56, 0xc6, 0x23, 0xe3, 0xbb, 0x0e, 0x1b, +- 0xf6, 0xea, 0xf1, 0x38, 0xc4, 0xae, 0xa2, 0x58, 0x6f, 0xea, 0x7e, 0xda, +- 0x1f, 0xed, 0x06, 0xa8, 0x49, 0xc6, 0xdc, 0x79, 0x0c, 0x00, 0xee, 0xd8, +- 0xdb, 0xce, 0xb1, 0x5a, 0x78, 0xcd, 0xac, 0xc5, 0x18, 0xbd, 0xb4, 0x3a, +- 0x29, 0xd7, 0xa7, 0xcb, 0x18, 0x51, 0xd6, 0x1f, 0xf5, 0x97, 0xa1, 0x5c, +- 0xe4, 0xfc, 0x1b, 0x35, 0x6f, 0xbf, 0x1f, 0x54, 0xff, 0x17, 0xd6, 0x98, +- 0x37, 0x7f, 0xad, 0x3a, 0x29, 0x9c, 0xaf, 0x1d, 0x5a, 0xd2, 0xc3, 0x78, +- 0x17, 0xb7, 0x2a, 0x0c, 0xbd, 0xfd, 0x82, 0xd2, 0x8d, 0x1b, 0x43, 0x7a, +- 0xec, 0x87, 0x8a, 0x1e, 0x1d, 0x50, 0x0c, 0xfa, 0x61, 0x10, 0xab, 0xb2, +- 0xef, 0xef, 0xeb, 0xfb, 0x50, 0x0f, 0x4b, 0x3f, 0xd2, 0xdf, 0x59, 0xf4, +- 0xdb, 0x63, 0x2a, 0x8e, 0x47, 0xc6, 0xa6, 0x60, 0xb3, 0x3d, 0xa6, 0x15, +- 0xb6, 0x7f, 0x7c, 0xd7, 0x74, 0x61, 0xe3, 0xde, 0x53, 0x0b, 0xc5, 0x40, +- 0x36, 0x1d, 0x8d, 0xa2, 0xb7, 0xd9, 0x85, 0x0d, 0xa3, 0x37, 0xa9, 0x22, +- 0x1b, 0xd4, 0xf9, 0x65, 0xf9, 0x6f, 0x85, 0xbc, 0xc5, 0x83, 0xf5, 0x59, +- 0xce, 0x1d, 0x31, 0x74, 0xfd, 0x51, 0x99, 0xdb, 0x5a, 0x7e, 0xcb, 0xdc, +- 0x7a, 0xf9, 0x2d, 0xf3, 0x3c, 0x8b, 0xdf, 0xd5, 0xf0, 0xcf, 0x12, 0x59, +- 0x9a, 0x91, 0xd8, 0x0f, 0x77, 0x45, 0xa4, 0x0b, 0x77, 0x0d, 0x58, 0x56, +- 0x7f, 0xc0, 0xb2, 0xca, 0x42, 0xe4, 0x59, 0x81, 0xc6, 0xf0, 0x95, 0x4a, +- 0x09, 0xa6, 0xb4, 0x66, 0xf4, 0x1f, 0x2d, 0x89, 0x55, 0x47, 0x66, 0xd1, +- 0xf7, 0x35, 0xfc, 0x6c, 0x49, 0x3b, 0x26, 0xc6, 0xa7, 0x8f, 0x21, 0x6f, +- 0x67, 0xdf, 0x5e, 0x50, 0xb4, 0x33, 0x91, 0x5f, 0x64, 0xd7, 0xfb, 0xd3, +- 0xf4, 0xcb, 0xb8, 0x86, 0x18, 0xfd, 0x83, 0x32, 0xd5, 0xa2, 0xe7, 0x12, +- 0xa7, 0xfe, 0xa0, 0xfa, 0x17, 0x1b, 0x3b, 0x13, 0xef, 0x5a, 0x0c, 0xa7, +- 0xfc, 0xe4, 0x1a, 0xef, 0xcd, 0xbc, 0xd7, 0x6e, 0xca, 0x6c, 0xbb, 0x91, +- 0xb2, 0x17, 0x1b, 0xef, 0xcc, 0xac, 0xb0, 0xc7, 0x9c, 0x66, 0xe1, 0x4d, +- 0x7b, 0x45, 0xa7, 0xa2, 0x03, 0x0b, 0xc7, 0xcd, 0xeb, 0x88, 0x15, 0xaf, +- 0x5b, 0x8e, 0x59, 0xd2, 0x46, 0x97, 0xd2, 0x4a, 0x7b, 0x8a, 0x3b, 0x4b, +- 0x41, 0x4e, 0xad, 0x95, 0x44, 0xa2, 0xca, 0x5a, 0x5b, 0xff, 0xad, 0xca, +- 0xca, 0xd1, 0xe9, 0x6d, 0x77, 0xd1, 0x77, 0x1f, 0x57, 0xf3, 0xf3, 0x7d, +- 0xde, 0x1e, 0x43, 0x5e, 0x7e, 0x3f, 0xda, 0x53, 0xd2, 0x8e, 0xe8, 0x35, +- 0xef, 0x6f, 0xed, 0x12, 0x23, 0x2e, 0xc9, 0x9c, 0xe7, 0x1e, 0x97, 0x31, +- 0x61, 0xc9, 0x7b, 0xf0, 0xe3, 0x7a, 0xe2, 0x47, 0xf4, 0x3f, 0xc4, 0x8f, +- 0xa5, 0x7f, 0xa2, 0xec, 0x59, 0xca, 0x21, 0x3c, 0x45, 0xe2, 0x9e, 0xf0, +- 0x16, 0xe1, 0x2b, 0x41, 0xca, 0x25, 0xfc, 0xa5, 0x68, 0x1b, 0x96, 0xf5, +- 0x4d, 0x73, 0x01, 0x62, 0xb5, 0xfa, 0x20, 0x50, 0x87, 0x41, 0xca, 0xea, +- 0x48, 0x22, 0xce, 0x71, 0x52, 0xd7, 0xea, 0x75, 0x0e, 0xa8, 0x4d, 0x0e, +- 0x74, 0xe3, 0x55, 0xd3, 0xe8, 0xdf, 0x8c, 0xbf, 0x44, 0x8f, 0xd7, 0xc2, +- 0x61, 0x33, 0x48, 0x5c, 0x2a, 0x47, 0x67, 0x13, 0x27, 0x62, 0xad, 0x17, +- 0x43, 0xa9, 0x78, 0x07, 0x61, 0x83, 0x31, 0xec, 0xd9, 0x4f, 0x26, 0x02, +- 0x7a, 0xfb, 0x56, 0xa6, 0x40, 0xab, 0x06, 0xdc, 0xf0, 0x4b, 0x2a, 0xc4, +- 0x98, 0xf1, 0x75, 0xc6, 0xf9, 0x4d, 0xe6, 0x15, 0xd4, 0x6d, 0x1f, 0x6d, +- 0x48, 0xa5, 0xbd, 0x48, 0x3f, 0x41, 0xf2, 0x19, 0xa9, 0xcb, 0xb8, 0xd0, +- 0xa0, 0xe0, 0x86, 0x06, 0xda, 0x27, 0x79, 0xd1, 0xe7, 0x43, 0x4e, 0xfb, +- 0xff, 0x44, 0xb6, 0x31, 0x7a, 0xb3, 0xfa, 0x23, 0x0b, 0x33, 0xed, 0x36, +- 0xb4, 0xa8, 0x4a, 0xb9, 0xff, 0x28, 0x27, 0x30, 0x21, 0x5c, 0xad, 0xd2, +- 0xf8, 0x0d, 0xc6, 0xbd, 0x52, 0xa7, 0x0a, 0x15, 0xc3, 0xf1, 0x59, 0xe5, +- 0xb4, 0xe1, 0xd2, 0x88, 0x8e, 0xbb, 0x46, 0x2b, 0xe1, 0x18, 0xd6, 0x2f, +- 0xae, 0x74, 0x20, 0x56, 0x22, 0xfc, 0x70, 0xb4, 0x16, 0x35, 0xfb, 0xac, +- 0x6e, 0x77, 0xc4, 0xb2, 0x3c, 0x4b, 0x22, 0xb8, 0xf7, 0xa8, 0x06, 0x75, +- 0x9f, 0x0b, 0x15, 0xcc, 0x43, 0xd6, 0x99, 0x7d, 0xb8, 0x8f, 0xfc, 0x6e, +- 0x4e, 0x32, 0x88, 0xd5, 0xc4, 0xa2, 0x8b, 0xa9, 0xb6, 0xd6, 0x17, 0x12, +- 0x0d, 0xdb, 0xe6, 0x38, 0x84, 0xfb, 0xaf, 0xc1, 0xe6, 0xec, 0x1a, 0xdc, +- 0xc9, 0xd8, 0xf9, 0x9c, 0x81, 0xee, 0x39, 0xf4, 0xd7, 0x3b, 0xc9, 0xff, +- 0x36, 0xa6, 0xd6, 0x61, 0x63, 0x76, 0x1b, 0xff, 0xeb, 0xc0, 0xdd, 0x3c, +- 0x36, 0xa5, 0xc4, 0xbf, 0x3f, 0x8d, 0x4d, 0xd9, 0x7a, 0xc4, 0x46, 0x37, +- 0x62, 0x2b, 0x39, 0xc1, 0x5d, 0xa3, 0x5e, 0xea, 0xb6, 0x0d, 0x1b, 0xb2, +- 0x6d, 0xb8, 0x97, 0x63, 0xb9, 0x97, 0xf3, 0xa1, 0x26, 0xb7, 0xd2, 0xc7, +- 0x3c, 0xf0, 0x0e, 0x2f, 0xc5, 0x7d, 0xa3, 0xd7, 0x61, 0x0b, 0xe3, 0xe4, +- 0xed, 0x4b, 0xae, 0x43, 0xf7, 0xe8, 0x7d, 0xe8, 0x4a, 0x19, 0x5d, 0x73, +- 0x98, 0x6a, 0xbd, 0xb5, 0xe4, 0x3e, 0xdc, 0x43, 0x39, 0xb6, 0xed, 0xb5, +- 0x50, 0xb6, 0x68, 0xb1, 0x6a, 0xd4, 0xc4, 0x2d, 0x9f, 0x21, 0xb1, 0xf9, +- 0xc0, 0xad, 0x7d, 0xc6, 0xee, 0x02, 0xb6, 0x38, 0x51, 0x62, 0x28, 0x62, +- 0xa3, 0xf9, 0xeb, 0x89, 0xbf, 0xc1, 0xe6, 0x51, 0x17, 0xee, 0x18, 0xed, +- 0x52, 0x56, 0x8b, 0xad, 0xb8, 0x54, 0xce, 0x67, 0x94, 0xd8, 0xd7, 0xaa, +- 0xb4, 0x8c, 0xda, 0xf3, 0xac, 0x79, 0x23, 0x5d, 0xca, 0xba, 0xec, 0x9d, +- 0x0e, 0x94, 0xcb, 0x5c, 0x5c, 0x83, 0xf1, 0xa6, 0xaf, 0x58, 0xe9, 0xfc, +- 0x7c, 0xa6, 0xe9, 0x3e, 0x6e, 0x5f, 0xe4, 0x57, 0x9f, 0xf4, 0x2d, 0xd0, +- 0xbb, 0x0e, 0xa8, 0xc2, 0x2b, 0xdd, 0xc8, 0xd9, 0xf3, 0x59, 0xc2, 0x7e, +- 0x6a, 0x70, 0xc4, 0x9b, 0xe7, 0x12, 0xf3, 0xd8, 0x97, 0x95, 0x72, 0x71, +- 0xac, 0x94, 0x9b, 0xe3, 0x99, 0x93, 0xf4, 0xe1, 0x7e, 0xea, 0xa7, 0x8b, +- 0x73, 0xd4, 0x45, 0xbd, 0x7c, 0x2e, 0x75, 0x8a, 0x31, 0x62, 0x1b, 0x3e, +- 0x57, 0xe8, 0xa7, 0x2f, 0x5b, 0x8a, 0x72, 0xa3, 0x0f, 0x8f, 0x68, 0x25, +- 0xf4, 0x31, 0xe1, 0x19, 0x07, 0x6e, 0x3d, 0x6c, 0xac, 0xe3, 0x18, 0xbe, +- 0xc4, 0x36, 0x44, 0xae, 0x46, 0xad, 0x06, 0xf9, 0xb2, 0x3d, 0xc4, 0xec, +- 0x72, 0xe3, 0x37, 0xd6, 0x23, 0xde, 0x76, 0xbb, 0x6c, 0x15, 0xcb, 0x3e, +- 0x3f, 0xe0, 0xc7, 0x8d, 0xb4, 0xef, 0xb2, 0x64, 0x94, 0x7a, 0x77, 0x93, +- 0x53, 0xb5, 0x52, 0xe7, 0x9c, 0x63, 0xea, 0xf5, 0x0e, 0xda, 0xb3, 0x33, +- 0xb9, 0x86, 0xf3, 0xa0, 0xa1, 0x32, 0xd9, 0xc7, 0x79, 0xf0, 0xc2, 0x9d, +- 0x6c, 0x47, 0x27, 0xe5, 0x72, 0x25, 0xd7, 0x71, 0x2e, 0xea, 0xe0, 0x49, +- 0x76, 0x70, 0x2e, 0x80, 0xbb, 0xa8, 0xcb, 0xfb, 0x42, 0xbf, 0x56, 0x7a, +- 0x6b, 0x65, 0x18, 0x6d, 0x9c, 0xbf, 0x28, 0x36, 0xa7, 0xea, 0xc3, 0x3b, +- 0x24, 0xee, 0x3b, 0x99, 0x90, 0x19, 0x3f, 0x26, 0x17, 0xa6, 0xf5, 0x1b, +- 0x3d, 0xfc, 0x5d, 0x94, 0xb3, 0x88, 0xe3, 0x22, 0xa7, 0xc4, 0xd7, 0xa2, +- 0x9c, 0x2e, 0x94, 0x19, 0xcf, 0x5a, 0x0f, 0x7b, 0xe1, 0x77, 0xb1, 0x6c, +- 0x39, 0xcb, 0xae, 0xa6, 0x9c, 0xab, 0x29, 0xff, 0xbc, 0xe4, 0xa7, 0xd1, +- 0x4d, 0x39, 0xe7, 0x0c, 0xbb, 0xc9, 0x51, 0x75, 0xdc, 0x4f, 0xdd, 0x1f, +- 0x48, 0x95, 0xa1, 0x9a, 0xf3, 0xfc, 0x39, 0xfe, 0xde, 0x41, 0x3f, 0x7a, +- 0x7e, 0xd0, 0xc2, 0x99, 0x90, 0x86, 0x41, 0xad, 0x0c, 0xbd, 0xc1, 0xad, +- 0xe4, 0xe5, 0x32, 0x57, 0xcc, 0xa7, 0x8c, 0x0a, 0xc6, 0x75, 0xc4, 0x5d, +- 0xcd, 0x3a, 0xb6, 0x07, 0xdd, 0x48, 0x7b, 0x11, 0x75, 0x19, 0x51, 0xda, +- 0xb8, 0x0b, 0x03, 0x9a, 0x02, 0x17, 0xf1, 0xb0, 0x94, 0xfe, 0xb4, 0x93, +- 0x71, 0xd7, 0x15, 0x91, 0xff, 0x68, 0x27, 0xe4, 0x60, 0xd5, 0x11, 0x23, +- 0xfe, 0x82, 0x12, 0x68, 0x73, 0xa9, 0xf7, 0x51, 0x47, 0x15, 0x38, 0x33, +- 0xf8, 0x25, 0x6c, 0x64, 0x5f, 0x7d, 0x29, 0x0f, 0x73, 0x93, 0xbf, 0x53, +- 0x72, 0x36, 0x7e, 0x7a, 0x90, 0x1c, 0x79, 0xdc, 0x9a, 0x67, 0x88, 0xdd, +- 0x44, 0x70, 0xcf, 0xd1, 0x2a, 0x0c, 0x0e, 0x5e, 0x87, 0x6d, 0x2c, 0xb7, +- 0x2b, 0x55, 0x0d, 0x63, 0x68, 0x99, 0x5d, 0x67, 0x84, 0xfe, 0x35, 0x90, +- 0xbc, 0x0f, 0x2b, 0x53, 0xf5, 0xc1, 0xa3, 0x4a, 0x8c, 0x3a, 0xf4, 0xa2, +- 0x3f, 0xb9, 0xd1, 0xd6, 0x69, 0x62, 0x5f, 0x27, 0xb6, 0x1e, 0xbd, 0x02, +- 0x7b, 0xf6, 0x6d, 0xc1, 0x5d, 0x47, 0x99, 0xbf, 0xda, 0xb6, 0xac, 0xa2, +- 0x77, 0xdf, 0x75, 0xca, 0x06, 0xb6, 0xb7, 0x7b, 0x98, 0xf6, 0x4c, 0x9b, +- 0xbe, 0x7f, 0xaf, 0x91, 0x5b, 0xe6, 0xd8, 0xa2, 0xf8, 0x6b, 0xaf, 0x43, +- 0x97, 0x6d, 0x7b, 0x79, 0xbd, 0xed, 0xc8, 0xce, 0x67, 0x9e, 0xf3, 0xb7, +- 0xd6, 0xa3, 0xde, 0x52, 0x7b, 0x7e, 0x55, 0xea, 0xad, 0x25, 0xc1, 0xdc, +- 0xbf, 0x96, 0xb9, 0x57, 0xc1, 0x5e, 0x7a, 0xb3, 0x8b, 0xc9, 0x1b, 0xbd, +- 0xc8, 0x68, 0x41, 0xea, 0xa3, 0x38, 0x0f, 0x0d, 0x05, 0x7b, 0x79, 0x8b, +- 0x65, 0x6c, 0x5b, 0x7e, 0x9f, 0x2f, 0xc8, 0xfc, 0xb6, 0xa3, 0x86, 0xf1, +- 0x75, 0x43, 0x68, 0x9d, 0x72, 0xaf, 0x76, 0x69, 0xce, 0x7c, 0xc5, 0x39, +- 0x93, 0x3c, 0xd1, 0x6e, 0x2b, 0xf1, 0x25, 0xdb, 0x76, 0xaf, 0xcf, 0x36, +- 0xa3, 0x73, 0x74, 0x7a, 0xfb, 0xc5, 0x3a, 0x65, 0x9c, 0x8b, 0xe2, 0x3c, +- 0xeb, 0xfd, 0x82, 0x65, 0x81, 0x45, 0x45, 0x2c, 0xbb, 0xb3, 0xd0, 0xff, +- 0x41, 0x8b, 0x31, 0xc9, 0xe9, 0x32, 0x1c, 0x18, 0x09, 0xfe, 0x57, 0x25, +- 0x5e, 0xeb, 0xa4, 0xcc, 0x0a, 0xb1, 0xe4, 0xef, 0xac, 0x3d, 0xeb, 0x64, +- 0x5e, 0x3e, 0x42, 0x43, 0x86, 0xe2, 0xba, 0xe4, 0xb3, 0x6b, 0xb0, 0x3e, +- 0x25, 0xb2, 0xb6, 0x63, 0x43, 0xca, 0x96, 0xcb, 0x5f, 0x94, 0xab, 0x8f, +- 0x36, 0xa3, 0x25, 0x77, 0xdb, 0x32, 0xb5, 0xd3, 0xae, 0xee, 0xd9, 0xab, +- 0xe2, 0xe9, 0xd0, 0x26, 0xc5, 0x3f, 0x53, 0xe2, 0x70, 0x3d, 0xba, 0xf6, +- 0xca, 0xb7, 0x9f, 0x7c, 0x37, 0xa6, 0x4c, 0xcd, 0x1c, 0x60, 0xb9, 0x65, +- 0x58, 0xbf, 0xb7, 0x16, 0x73, 0x38, 0xd6, 0xdb, 0xcd, 0xff, 0xa2, 0xbc, +- 0x33, 0x43, 0xc6, 0xb3, 0xa2, 0x10, 0xcb, 0xeb, 0x71, 0xdf, 0x5e, 0xf1, +- 0x21, 0xf9, 0xdd, 0x82, 0xde, 0xa5, 0xf5, 0x85, 0x38, 0xff, 0x37, 0x9c, +- 0x97, 0x2e, 0xe5, 0x06, 0xe2, 0x42, 0x8c, 0xb8, 0x40, 0x9b, 0x52, 0xda, +- 0x89, 0x0b, 0xd7, 0x17, 0x70, 0xc1, 0x43, 0x5c, 0x58, 0x93, 0x7d, 0x9b, +- 0xf2, 0x88, 0x2f, 0xbe, 0x57, 0x9e, 0xbb, 0x29, 0xcf, 0xb1, 0xd0, 0x1c, +- 0xc0, 0x96, 0x67, 0x19, 0x79, 0x4c, 0x2d, 0xe7, 0xd0, 0x62, 0x7c, 0x50, +- 0x94, 0x11, 0x5b, 0xcf, 0xcb, 0x28, 0xb3, 0xd8, 0x94, 0x45, 0xb9, 0x7f, +- 0x8f, 0x06, 0x7b, 0x7d, 0xe0, 0xb2, 0x3c, 0xeb, 0xf7, 0xbe, 0xcb, 0x1c, +- 0x41, 0x7e, 0x13, 0x2f, 0x9a, 0xeb, 0x89, 0x73, 0xcb, 0x88, 0x7b, 0x2e, +- 0x8e, 0x4b, 0xb0, 0x4e, 0x64, 0x73, 0xd1, 0x2f, 0xa4, 0x6d, 0xd1, 0xc9, +- 0x52, 0x47, 0x7e, 0x1e, 0x8a, 0xf3, 0xec, 0xa4, 0x1f, 0xbb, 0x51, 0x1d, +- 0xd1, 0xa3, 0x37, 0x39, 0x64, 0xce, 0x88, 0xf2, 0x43, 0xed, 0x85, 0xbe, +- 0xfe, 0xbb, 0xd2, 0x50, 0xd3, 0x4f, 0x39, 0x4f, 0x28, 0xb7, 0x70, 0x5c, +- 0xfe, 0xd2, 0xaa, 0xa8, 0x27, 0x12, 0xe8, 0x48, 0xbc, 0x2f, 0x36, 0xde, +- 0x90, 0xcd, 0xf3, 0x4b, 0x75, 0x28, 0x6e, 0x95, 0xd3, 0xf6, 0x9d, 0x46, +- 0xe0, 0xe2, 0x6a, 0xf6, 0x30, 0xef, 0xa0, 0xf0, 0x19, 0x93, 0x6d, 0x15, +- 0xfb, 0xaa, 0x23, 0x96, 0x84, 0x0a, 0x76, 0xb0, 0x46, 0x61, 0xde, 0xd0, +- 0x16, 0xb5, 0xed, 0x61, 0x17, 0xf5, 0x75, 0x42, 0xf9, 0x98, 0x70, 0x66, +- 0x9b, 0x63, 0xc4, 0x95, 0x55, 0xc4, 0x95, 0xea, 0xa4, 0x12, 0xf5, 0x46, +- 0x1a, 0xb7, 0xd5, 0x20, 0xd0, 0xf6, 0x28, 0xfb, 0xac, 0x21, 0xcf, 0xbc, +- 0x89, 0xb1, 0x36, 0xc9, 0x3e, 0x57, 0xb1, 0xcf, 0xb5, 0xd9, 0x2d, 0x6c, +- 0x57, 0xb0, 0x55, 0xc5, 0x9c, 0x7d, 0x70, 0x7b, 0x69, 0x07, 0x23, 0x0d, +- 0x4e, 0x84, 0x17, 0xff, 0x02, 0x98, 0x81, 0x98, 0xca, 0xfc, 0x7d, 0x5e, +- 0x52, 0x72, 0xa9, 0x03, 0xb7, 0x2e, 0xcb, 0x08, 0x96, 0x6a, 0xf0, 0x0c, +- 0x7b, 0x25, 0x1e, 0xa1, 0x2f, 0x54, 0xa7, 0xec, 0xb1, 0xf1, 0x56, 0x45, +- 0xd9, 0x3e, 0x05, 0x57, 0x85, 0xbe, 0xae, 0xa4, 0x67, 0xe6, 0x31, 0x5f, +- 0xa5, 0x3e, 0x7a, 0x26, 0x04, 0x1b, 0xd3, 0xc4, 0xc6, 0x63, 0x4a, 0x7e, +- 0x3d, 0x86, 0x7e, 0x9f, 0x42, 0xbc, 0x2a, 0x22, 0x6b, 0x20, 0x81, 0xce, +- 0x0f, 0x29, 0xf7, 0x11, 0x0b, 0x5d, 0x8c, 0x43, 0x1e, 0x62, 0xa3, 0xc4, +- 0xe9, 0xf4, 0xad, 0x89, 0x81, 0x3a, 0xf4, 0xd3, 0xb7, 0x37, 0x1e, 0x3d, +- 0x75, 0x8b, 0x07, 0xb5, 0xfc, 0xf6, 0xf2, 0x98, 0xc5, 0xc3, 0x4d, 0x5f, +- 0x76, 0xc3, 0x31, 0x20, 0x7c, 0xaf, 0x89, 0xb1, 0xca, 0x83, 0xf2, 0x01, +- 0x13, 0x5b, 0x28, 0x4f, 0xe9, 0x50, 0x33, 0xe3, 0x09, 0xfd, 0x3c, 0x55, +- 0x83, 0xeb, 0x07, 0x97, 0x60, 0x93, 0x8d, 0x5f, 0xb5, 0x38, 0x3b, 0xb8, +- 0xd4, 0xc6, 0x8d, 0x87, 0x52, 0x33, 0xf0, 0xce, 0xde, 0x6b, 0x6c, 0x8c, +- 0x1b, 0x64, 0x6c, 0xf6, 0xed, 0x0b, 0xa3, 0x8b, 0x6d, 0x7a, 0xf7, 0x5d, +- 0x8b, 0xfb, 0x8e, 0xfa, 0xa8, 0x23, 0x83, 0x71, 0x40, 0x7d, 0xd7, 0xff, +- 0x49, 0xb1, 0xf3, 0xe9, 0xd8, 0x2f, 0x73, 0x2d, 0x75, 0x32, 0x34, 0x56, +- 0xf9, 0xed, 0xb4, 0xb9, 0x70, 0x5e, 0x47, 0x79, 0x9d, 0x5c, 0x4d, 0x9d, +- 0xdc, 0x94, 0xa5, 0x39, 0x0c, 0x3b, 0x39, 0xd7, 0xe4, 0x10, 0x35, 0xb5, +- 0xf4, 0xcb, 0x12, 0x1e, 0xb4, 0xff, 0xd1, 0xbf, 0x60, 0x6c, 0xcf, 0x71, +- 0x3e, 0xf9, 0xdb, 0x94, 0xf9, 0x94, 0xf8, 0xe9, 0x20, 0xe6, 0x2a, 0xd4, +- 0xef, 0xff, 0x02, 0x66, 0xe7, 0x73, 0x9b, 0xa2, 0xae, 0x54, 0x8e, 0xbf, +- 0x25, 0x91, 0xb3, 0x39, 0x3d, 0x33, 0x22, 0x5d, 0xe5, 0x7f, 0x1b, 0x8f, +- 0x92, 0x73, 0x27, 0xc5, 0x67, 0xbd, 0xb4, 0xe7, 0x26, 0xea, 0x4b, 0x63, +- 0xec, 0x30, 0x89, 0x73, 0xb3, 0xe0, 0xe2, 0x38, 0x36, 0x51, 0x3f, 0x1e, +- 0x8e, 0x63, 0x2b, 0xcb, 0xdd, 0xc5, 0xff, 0xee, 0x3a, 0x5a, 0xcb, 0xc3, +- 0xcb, 0x63, 0x16, 0x8f, 0x9f, 0x12, 0xb3, 0x9a, 0x69, 0xc7, 0x0e, 0x94, +- 0x0c, 0xab, 0x78, 0xca, 0x54, 0x70, 0xa1, 0x89, 0xfd, 0x35, 0x5c, 0xc6, +- 0x3a, 0x89, 0x65, 0xde, 0xe4, 0x97, 0x88, 0x73, 0x7e, 0xac, 0x23, 0x27, +- 0xe8, 0xdc, 0xab, 0xc1, 0x15, 0xca, 0x30, 0x67, 0x12, 0x19, 0x4e, 0x14, +- 0x38, 0xe6, 0x3c, 0xe6, 0x3a, 0x8d, 0x61, 0xda, 0x90, 0xb6, 0xd9, 0xb6, +- 0xa1, 0x38, 0xe3, 0x73, 0x90, 0xb9, 0x7e, 0xde, 0x76, 0x5b, 0xde, 0x63, +- 0x47, 0xf4, 0x31, 0x8e, 0x67, 0x4e, 0x44, 0xf7, 0xdf, 0x42, 0x5f, 0x10, +- 0xce, 0x57, 0x9a, 0x04, 0x0e, 0x0c, 0xb6, 0xa3, 0x9a, 0x36, 0xe3, 0x5d, +- 0x7c, 0x14, 0xa9, 0xda, 0x7e, 0xdb, 0x56, 0xf3, 0x6d, 0x97, 0x45, 0x2b, +- 0x23, 0x8d, 0x31, 0x69, 0x7b, 0xbc, 0xd0, 0xf6, 0x0a, 0xb6, 0x9d, 0x60, +- 0xdb, 0x2b, 0xff, 0x5d, 0xdb, 0xd3, 0xe3, 0x5d, 0x4f, 0x21, 0x2e, 0x4b, +- 0xde, 0x5c, 0xc4, 0xed, 0x22, 0xc7, 0xf8, 0x8d, 0xf7, 0x32, 0x4e, 0xee, +- 0x90, 0xb9, 0xf3, 0xe5, 0x7d, 0xf6, 0xbd, 0xd8, 0x7c, 0xb9, 0xad, 0x3d, +- 0xc5, 0x18, 0x6f, 0xd6, 0x4c, 0x6b, 0x6b, 0x0e, 0xff, 0xff, 0x70, 0x4a, +- 0xb8, 0x44, 0x3b, 0x2c, 0xca, 0xfa, 0xac, 0xa1, 0x77, 0x2d, 0x73, 0x18, +- 0xdb, 0x2e, 0x32, 0xd7, 0xb9, 0xf1, 0x52, 0x5f, 0xb2, 0x36, 0xd2, 0x8e, +- 0x85, 0x03, 0x7a, 0xe7, 0x2e, 0xf2, 0xd1, 0xc3, 0x21, 0x3d, 0xfa, 0x2d, +- 0xe8, 0xf1, 0x52, 0xe5, 0x25, 0x94, 0x4c, 0x9c, 0xc5, 0x60, 0xf6, 0x47, +- 0x92, 0x6f, 0xb2, 0x4d, 0xb7, 0xe2, 0x99, 0xe8, 0x43, 0x8c, 0xf5, 0xdc, +- 0xac, 0xe7, 0x1e, 0x80, 0xbb, 0x92, 0xf5, 0xc6, 0x07, 0xe2, 0x96, 0x8b, +- 0x5c, 0x50, 0x8d, 0xe8, 0x1d, 0x95, 0x8a, 0x11, 0xdb, 0xc4, 0xb6, 0xd7, +- 0x30, 0x96, 0x95, 0x27, 0xbb, 0xc9, 0x03, 0x74, 0xdf, 0x97, 0x55, 0xbd, +- 0x6b, 0x3d, 0x5e, 0xc2, 0xbf, 0x92, 0x3c, 0xce, 0x4b, 0x9e, 0x45, 0x8a, +- 0xed, 0x59, 0xe3, 0x1a, 0xf9, 0xcc, 0xbb, 0x56, 0x78, 0x41, 0x85, 0x53, +- 0xda, 0xbd, 0x38, 0xbe, 0xe0, 0xdd, 0xc4, 0x65, 0x3c, 0xd7, 0x5c, 0x46, +- 0xe3, 0xfb, 0xf0, 0xa9, 0xa9, 0x75, 0x45, 0x62, 0xfd, 0x56, 0x57, 0x64, +- 0xdb, 0xfd, 0xc7, 0x9b, 0xf3, 0x76, 0xeb, 0xcf, 0xb8, 0x71, 0xd6, 0x2b, +- 0xbe, 0xc4, 0xfc, 0x67, 0x7f, 0x13, 0x76, 0xef, 0x67, 0x5e, 0xa9, 0x36, +- 0x86, 0xcb, 0x95, 0x1a, 0xe6, 0x44, 0xc3, 0x36, 0x1f, 0x76, 0x1a, 0xbb, +- 0xec, 0x9c, 0x59, 0xe2, 0x83, 0xd4, 0x99, 0x9f, 0x91, 0xf8, 0x27, 0xeb, +- 0x39, 0x07, 0x6e, 0xdd, 0x90, 0xa0, 0xdf, 0x6a, 0xbd, 0x2c, 0xb3, 0xae, +- 0xb0, 0x4e, 0x2f, 0x6b, 0x18, 0xbd, 0xd3, 0x38, 0xc9, 0xba, 0x69, 0xb1, +- 0xaa, 0xd1, 0x5f, 0x73, 0x29, 0x8e, 0x74, 0x14, 0xca, 0x33, 0xd9, 0xb3, +- 0x65, 0x73, 0x4f, 0xc3, 0xb3, 0x1d, 0xbc, 0x96, 0xf7, 0x85, 0xcb, 0xf1, +- 0x6e, 0x67, 0x61, 0x6e, 0x0e, 0xb9, 0xf2, 0xb8, 0xff, 0x69, 0x77, 0x71, +- 0xbd, 0x28, 0x5f, 0xe6, 0xda, 0x12, 0x94, 0xef, 0xb9, 0x14, 0x5b, 0xe2, +- 0xc4, 0xf2, 0x6d, 0x7b, 0xf3, 0xeb, 0x93, 0x95, 0x4b, 0x05, 0xb7, 0xeb, +- 0x71, 0xb7, 0xed, 0xf7, 0x5f, 0x75, 0xe5, 0xed, 0xc0, 0x59, 0x18, 0x97, +- 0x49, 0x1b, 0xbc, 0x52, 0xd6, 0xfc, 0x0b, 0xf8, 0x39, 0x9b, 0xff, 0xf7, +- 0x42, 0xe6, 0xc2, 0x45, 0xff, 0x7c, 0xdc, 0x74, 0x60, 0x6a, 0x46, 0x9e, +- 0xaf, 0xab, 0xfb, 0x9a, 0xd0, 0x33, 0x46, 0xbc, 0xa1, 0x0f, 0xb5, 0x85, +- 0xd6, 0x5a, 0xa8, 0x91, 0x75, 0x83, 0x5a, 0x54, 0xec, 0x13, 0xde, 0x4c, +- 0x9e, 0x31, 0x76, 0xca, 0x1e, 0x4b, 0x6f, 0x26, 0xbf, 0x2e, 0xb2, 0x33, +- 0xd5, 0xf7, 0xee, 0x1d, 0x9a, 0xe0, 0x85, 0xd8, 0x46, 0xdd, 0xad, 0x0b, +- 0x03, 0x39, 0xbf, 0x03, 0xba, 0xb9, 0x4b, 0x56, 0x92, 0x12, 0xb7, 0x61, +- 0x7b, 0xad, 0x82, 0x2e, 0xa3, 0x1a, 0x8e, 0xc5, 0xbf, 0xb5, 0xee, 0x58, +- 0x27, 0xff, 0xbd, 0x5b, 0xc0, 0x97, 0x0f, 0xb2, 0x6f, 0x19, 0xb7, 0x70, +- 0x3a, 0x37, 0x2a, 0xe8, 0x53, 0x37, 0x38, 0x84, 0x73, 0x2a, 0x8c, 0x9d, +- 0xf6, 0x5c, 0xa0, 0x37, 0xad, 0x60, 0x77, 0x5a, 0x30, 0xd3, 0x49, 0x1c, +- 0xf4, 0x61, 0x67, 0x5a, 0x70, 0xd0, 0x45, 0x1c, 0x9c, 0x83, 0xed, 0x69, +- 0xc1, 0xc1, 0x12, 0xbc, 0x3c, 0x78, 0x05, 0x1e, 0xe2, 0xef, 0x07, 0x53, +- 0xa5, 0x08, 0xef, 0xfd, 0x0b, 0x1c, 0x48, 0x0b, 0x7f, 0x72, 0x23, 0x35, +- 0x5c, 0x87, 0x54, 0x3a, 0xcf, 0x25, 0xaa, 0x86, 0xff, 0x12, 0x49, 0xfe, +- 0x1e, 0x20, 0xef, 0xcb, 0x0c, 0xcd, 0x45, 0x82, 0xbf, 0x65, 0xbd, 0xcd, +- 0x43, 0xf9, 0x13, 0x81, 0x0a, 0x6c, 0x18, 0x92, 0x1c, 0xda, 0x77, 0xeb, +- 0x5d, 0x81, 0x79, 0xec, 0xb3, 0x0e, 0xbb, 0xc9, 0xd9, 0xda, 0x86, 0xfc, +- 0xe8, 0xe7, 0xef, 0x9d, 0xa9, 0x4a, 0xbc, 0x36, 0xa8, 0xdb, 0xfd, 0xf5, +- 0xa4, 0x56, 0xac, 0x70, 0x19, 0x55, 0x58, 0x31, 0x38, 0x1f, 0x3b, 0xd2, +- 0x82, 0xbd, 0xd5, 0xc4, 0xde, 0x7a, 0x3c, 0x98, 0x16, 0x7e, 0xa9, 0xc1, +- 0xbb, 0xd7, 0xc0, 0x48, 0x5a, 0xd6, 0x84, 0x6b, 0x70, 0x61, 0x28, 0x80, +- 0x41, 0xbb, 0x7f, 0x13, 0xc9, 0x54, 0x98, 0xf2, 0x79, 0x51, 0xb9, 0x2f, +- 0xe7, 0xab, 0x82, 0x82, 0xc9, 0x40, 0x10, 0x03, 0x63, 0xb3, 0x50, 0xbe, +- 0x4f, 0x37, 0xb7, 0x42, 0xbf, 0x78, 0x17, 0xae, 0xc4, 0xee, 0x31, 0x1f, +- 0x4a, 0xf7, 0x55, 0xc3, 0x1d, 0x6a, 0xc2, 0xce, 0xb1, 0x0f, 0x61, 0xfb, +- 0x58, 0x1d, 0xb1, 0x13, 0x78, 0x3a, 0x63, 0xa2, 0x9f, 0x18, 0x3c, 0x87, +- 0x31, 0xe6, 0x95, 0xac, 0xcc, 0xa3, 0xcc, 0x8f, 0x02, 0x4f, 0xa0, 0x9a, +- 0x31, 0x4a, 0x7e, 0xcb, 0xb5, 0xb0, 0x8d, 0xed, 0xf9, 0x75, 0x2a, 0x3d, +- 0xbe, 0x13, 0xb6, 0xbe, 0x91, 0xcb, 0x88, 0xee, 0x65, 0x4d, 0x68, 0xba, +- 0x3d, 0xed, 0xb4, 0xd7, 0xe8, 0x2f, 0xdb, 0xe5, 0x5f, 0x15, 0xec, 0xd2, +- 0x5e, 0x53, 0xc3, 0x93, 0x97, 0xf2, 0x5c, 0xb4, 0x96, 0x20, 0x60, 0x3a, +- 0x15, 0xf8, 0x99, 0xef, 0xfa, 0x9f, 0x7a, 0xdf, 0xda, 0xda, 0xe5, 0xf5, +- 0x9f, 0xe9, 0x6b, 0xb0, 0x72, 0x6f, 0x49, 0x65, 0x3c, 0x2f, 0x41, 0x5c, +- 0x93, 0x35, 0xaa, 0x46, 0x8d, 0x5a, 0x79, 0x5f, 0xde, 0x5d, 0x15, 0x2b, +- 0x8b, 0x34, 0xc3, 0x3f, 0x5e, 0xe7, 0x7f, 0x2d, 0x21, 0x3a, 0xfd, 0xbd, +- 0xe5, 0x36, 0x0c, 0xdf, 0x31, 0xd4, 0xf9, 0x7f, 0x92, 0x79, 0xbb, 0x04, +- 0x55, 0x1e, 0x5c, 0x9f, 0xf8, 0xe0, 0x7a, 0x6a, 0x04, 0xca, 0xca, 0x66, +- 0x1f, 0x79, 0x3f, 0x9c, 0xab, 0x17, 0x60, 0xda, 0x87, 0x7c, 0x24, 0x02, +- 0xf5, 0x74, 0x73, 0x98, 0xb9, 0x7e, 0xfe, 0x7e, 0xce, 0xf2, 0xac, 0xee, +- 0x8b, 0x2a, 0xf9, 0x7b, 0x36, 0x9d, 0xa1, 0x3f, 0xd0, 0xae, 0xbb, 0x85, +- 0xb3, 0xb0, 0x2f, 0x60, 0x6b, 0xc2, 0xb2, 0x9e, 0xa4, 0x0e, 0xe4, 0x5e, +- 0xe0, 0x9b, 0x99, 0xdf, 0x59, 0x93, 0x5e, 0x27, 0x5e, 0x37, 0xa6, 0xb7, +- 0x47, 0xae, 0x17, 0x31, 0x19, 0xfb, 0xec, 0x13, 0x75, 0xdc, 0x68, 0xdc, +- 0x76, 0x98, 0x79, 0xf2, 0xc2, 0x80, 0xee, 0x4f, 0xe2, 0xff, 0x5a, 0xc2, +- 0x0b, 0xd3, 0x4a, 0x71, 0xdd, 0xee, 0xfd, 0x6b, 0x27, 0x55, 0x31, 0x17, +- 0xc7, 0x77, 0x28, 0xa1, 0xf7, 0xc7, 0x99, 0xb7, 0x45, 0xbd, 0x88, 0x39, +- 0x23, 0x75, 0xfe, 0x9d, 0x09, 0x7b, 0x9c, 0xe6, 0x79, 0xce, 0xdd, 0xe9, +- 0xe6, 0x3a, 0x7f, 0x6f, 0x46, 0x6c, 0x50, 0xe1, 0x58, 0x9a, 0xf1, 0x70, +- 0x46, 0xc5, 0x9d, 0x0f, 0x78, 0xb1, 0x69, 0xc0, 0x83, 0x6d, 0x03, 0x5f, +- 0x82, 0x71, 0x95, 0x13, 0x77, 0x30, 0xf7, 0xdb, 0x3c, 0x50, 0x4a, 0x3d, +- 0x6a, 0xd8, 0x32, 0xe0, 0x44, 0xd3, 0x55, 0x55, 0x88, 0xcf, 0x2c, 0xc5, +- 0xf3, 0xf4, 0xdd, 0xab, 0x42, 0x15, 0x48, 0xdb, 0x9c, 0x43, 0xb0, 0x41, +- 0x78, 0x9b, 0xe8, 0x8d, 0x71, 0xd0, 0x10, 0x0c, 0xf9, 0xa0, 0xf5, 0x99, +- 0xdf, 0x58, 0xb9, 0x99, 0x7b, 0x6c, 0x3e, 0xe9, 0x88, 0x88, 0x6e, 0xa4, +- 0xae, 0xac, 0x35, 0x79, 0x19, 0x23, 0xdf, 0xa3, 0x47, 0x65, 0x5e, 0x24, +- 0x30, 0xb9, 0x4c, 0x71, 0x20, 0x1c, 0xa8, 0x8a, 0x55, 0x47, 0xc2, 0x58, +- 0x99, 0xed, 0xf1, 0xf9, 0xec, 0x7b, 0x59, 0x11, 0x9c, 0x5f, 0x62, 0xe2, +- 0x96, 0x2c, 0x9c, 0x2b, 0xa9, 0xfb, 0x56, 0xea, 0x75, 0x87, 0xf9, 0x07, +- 0x2b, 0x9f, 0xd7, 0xb8, 0x89, 0x97, 0x96, 0xb5, 0x99, 0xfa, 0x65, 0x4e, +- 0x81, 0x9f, 0x16, 0xf4, 0x2b, 0x3a, 0xad, 0x18, 0xff, 0x9d, 0x75, 0x9a, +- 0xfa, 0x75, 0xb3, 0x3d, 0x37, 0xdb, 0x2b, 0x1b, 0x7f, 0xaf, 0x9e, 0x4b, +- 0x29, 0xcf, 0x4a, 0x5b, 0x86, 0xd9, 0x72, 0x2f, 0xc0, 0x1f, 0x55, 0x8a, +- 0x3c, 0xf4, 0x4f, 0x8d, 0xe9, 0x25, 0x7b, 0xbd, 0xed, 0xeb, 0x59, 0xcb, +- 0x1a, 0x36, 0x45, 0xff, 0x7e, 0xea, 0x5f, 0xd6, 0x5d, 0x64, 0x0e, 0x9a, +- 0x10, 0xad, 0xd5, 0xfb, 0x01, 0x49, 0x7c, 0x15, 0xcc, 0x60, 0xae, 0xf5, +- 0x8d, 0x76, 0x0f, 0x5e, 0x4b, 0x54, 0xda, 0xe3, 0xbe, 0xaa, 0xc1, 0xb2, +- 0xbe, 0x16, 0xf2, 0xe3, 0x4d, 0xa3, 0x31, 0xbc, 0x48, 0xd5, 0x19, 0x13, +- 0x64, 0xed, 0x83, 0xba, 0x48, 0xcd, 0xe5, 0x7c, 0x89, 0xcf, 0x63, 0x1b, +- 0xed, 0xc9, 0xef, 0x88, 0x00, 0xaf, 0x26, 0x8c, 0xe0, 0x0e, 0xf6, 0x3f, +- 0xea, 0x8d, 0x60, 0x7b, 0x4a, 0x6d, 0x75, 0x92, 0x7c, 0x96, 0x31, 0xd7, +- 0xdb, 0x85, 0x7f, 0xb5, 0xd2, 0x5e, 0x0b, 0x25, 0x21, 0x89, 0x25, 0xf3, +- 0x70, 0x46, 0x73, 0xe0, 0x99, 0xe0, 0x2c, 0x44, 0x6b, 0x1c, 0xe4, 0x33, +- 0xaf, 0x5b, 0xff, 0xec, 0x95, 0x7e, 0x64, 0x2c, 0x7f, 0xe0, 0x38, 0x14, +- 0x1b, 0xef, 0x76, 0xa6, 0x22, 0xd4, 0xf7, 0xfb, 0xfb, 0xff, 0xbf, 0xd6, +- 0x94, 0x57, 0xfa, 0xd7, 0x35, 0x3f, 0xf9, 0xf9, 0xe3, 0x1f, 0xb8, 0xce, +- 0x12, 0xe4, 0x78, 0xbf, 0x67, 0x7d, 0xc7, 0x6e, 0xf3, 0x23, 0xa5, 0x79, +- 0x5e, 0x2f, 0xed, 0x3d, 0xcd, 0xf1, 0x49, 0x9b, 0xc5, 0x7e, 0x44, 0x6f, +- 0x93, 0xa5, 0x82, 0xd7, 0x3b, 0x53, 0xa2, 0x3f, 0xc9, 0x97, 0x4e, 0x5b, +- 0x98, 0x25, 0xe7, 0x0f, 0xdb, 0x65, 0xe3, 0xd4, 0x57, 0x0f, 0x6d, 0x88, +- 0xb1, 0x81, 0xf1, 0x42, 0xee, 0xb2, 0x6a, 0xc4, 0x5c, 0x0b, 0xdb, 0x19, +- 0xb2, 0xd2, 0xde, 0x6a, 0xec, 0x34, 0x69, 0x77, 0x86, 0x3a, 0xdf, 0x09, +- 0x0b, 0xa7, 0x4d, 0x39, 0x77, 0x61, 0xca, 0xeb, 0xc0, 0x2e, 0xd3, 0x89, +- 0x4e, 0x43, 0xd5, 0xe5, 0xba, 0x23, 0x24, 0xe7, 0x2e, 0xf8, 0x67, 0x2a, +- 0xd8, 0x13, 0x56, 0xb1, 0xc5, 0xe8, 0xf1, 0xcb, 0xf5, 0xe5, 0x21, 0x39, +- 0x57, 0xb0, 0x91, 0x3a, 0x89, 0x33, 0x57, 0xde, 0xca, 0x76, 0x7b, 0x43, +- 0xf9, 0x75, 0xf1, 0x18, 0x2c, 0x6b, 0x8f, 0xd9, 0xf2, 0xe1, 0x0a, 0x96, +- 0x3b, 0x67, 0x4a, 0xec, 0x38, 0x70, 0xcb, 0xc2, 0x40, 0x3c, 0x5a, 0x02, +- 0x3d, 0x56, 0x46, 0x3f, 0xdd, 0x39, 0x30, 0x8f, 0xf5, 0x04, 0xfb, 0x9d, +- 0xbe, 0xdd, 0x90, 0xf5, 0xae, 0x80, 0xff, 0x27, 0xe4, 0xde, 0x69, 0xef, +- 0x02, 0x6a, 0xd6, 0xf0, 0xbf, 0xc2, 0x79, 0xab, 0x36, 0x9c, 0xdb, 0x5e, +- 0x80, 0xde, 0x59, 0xa6, 0x2c, 0x08, 0x56, 0xc1, 0x85, 0x38, 0xf9, 0xf9, +- 0xd8, 0x38, 0xf3, 0xeb, 0x94, 0xa1, 0x1d, 0xb1, 0xd7, 0xcc, 0x3d, 0xd4, +- 0x85, 0x87, 0xf1, 0x22, 0xa0, 0x4d, 0x2a, 0xc5, 0xf3, 0x79, 0x82, 0x0d, +- 0x31, 0x47, 0x44, 0xf0, 0x2d, 0x6e, 0x3d, 0xd1, 0x4c, 0xd5, 0x19, 0x6e, +- 0x7f, 0x2c, 0xe3, 0xe1, 0xa1, 0xf1, 0xf0, 0xfa, 0x37, 0x65, 0x7c, 0xfe, +- 0x8d, 0x19, 0xf8, 0xd7, 0x67, 0x8a, 0x76, 0x59, 0xf4, 0x6d, 0xc1, 0x36, +- 0xcb, 0x92, 0x7b, 0xc9, 0x8f, 0x67, 0xa5, 0xad, 0x7c, 0x1c, 0x2b, 0xa1, +- 0xec, 0x4f, 0xd2, 0xd6, 0x5d, 0x8c, 0x55, 0xbb, 0x8c, 0x38, 0xa1, 0xd2, +- 0xb2, 0x0c, 0xf2, 0x99, 0x12, 0xc5, 0x8f, 0x9d, 0x4d, 0xbf, 0xe5, 0x7c, +- 0x02, 0x9b, 0x32, 0x01, 0x77, 0x7e, 0x3e, 0xc4, 0xcf, 0x04, 0x03, 0xfc, +- 0x8c, 0xbf, 0x3e, 0x7f, 0x0f, 0xfb, 0xd9, 0x9e, 0x99, 0xee, 0x03, 0x0a, +- 0x56, 0xb3, 0xad, 0x96, 0x10, 0x9c, 0x2b, 0x9a, 0xfe, 0xcd, 0xca, 0x79, +- 0xa7, 0xdf, 0x37, 0x75, 0x33, 0xe6, 0xc2, 0xb9, 0xbe, 0x49, 0xce, 0x15, +- 0xb4, 0x84, 0xe5, 0x5c, 0xc1, 0x7a, 0x43, 0xce, 0x89, 0xd9, 0x59, 0x39, +- 0xb7, 0xac, 0xcb, 0xe7, 0xef, 0xc7, 0x22, 0x13, 0x77, 0xa5, 0x64, 0xed, +- 0x4d, 0xb0, 0xc8, 0xed, 0xff, 0x4e, 0xa6, 0x09, 0x5b, 0x52, 0x72, 0x7f, +- 0x8c, 0xb9, 0x86, 0xe1, 0xf1, 0x3f, 0x93, 0xb9, 0x16, 0x77, 0xee, 0x0f, +- 0xa3, 0x73, 0x3f, 0x9a, 0xca, 0x38, 0x86, 0xd2, 0x50, 0xc0, 0x7f, 0x14, +- 0x9a, 0xff, 0x0c, 0x75, 0x72, 0x8a, 0x72, 0x9e, 0x7e, 0x8f, 0x9c, 0xa2, +- 0x43, 0xf8, 0xef, 0x4e, 0xb8, 0x91, 0x09, 0xbd, 0x63, 0xc5, 0xed, 0x5c, +- 0xc8, 0xeb, 0xbf, 0x27, 0xe1, 0x47, 0xce, 0xce, 0xc9, 0xde, 0x28, 0x15, +- 0xec, 0xee, 0x4b, 0xc5, 0xa3, 0x2a, 0x8a, 0xf3, 0xab, 0x87, 0x65, 0x6e, +- 0x5f, 0x4d, 0xc8, 0x7f, 0xd1, 0x2f, 0xa9, 0x8c, 0x4b, 0x2a, 0x73, 0xf9, +- 0x41, 0x59, 0xdf, 0x57, 0x4b, 0x45, 0x3f, 0x72, 0x8f, 0x22, 0x2e, 0x39, +- 0x63, 0x13, 0xaf, 0x6b, 0x8b, 0x10, 0xab, 0xa1, 0x9e, 0xca, 0x0d, 0xaf, +- 0xbf, 0x71, 0xc2, 0xe7, 0x37, 0x27, 0xe0, 0xbf, 0x72, 0x62, 0xba, 0x08, +- 0xe4, 0x0a, 0xea, 0x07, 0x61, 0x81, 0xd7, 0xbf, 0x39, 0x31, 0x8f, 0x3c, +- 0x33, 0x6e, 0x2d, 0x6f, 0x3e, 0x6f, 0xcd, 0x8b, 0x18, 0xb9, 0xd3, 0x94, +- 0xe1, 0x9d, 0x6b, 0xf4, 0xf8, 0x1c, 0xc7, 0xa9, 0xfb, 0xb5, 0x69, 0x7d, +- 0x5c, 0x08, 0xfd, 0xff, 0xed, 0xa3, 0x18, 0xe7, 0x68, 0x0f, 0xcd, 0x32, +- 0x06, 0x89, 0x77, 0xcc, 0x85, 0x6a, 0x65, 0x2c, 0x81, 0x02, 0x6f, 0x2b, +- 0x8e, 0x4b, 0xe1, 0x5c, 0xbb, 0xa9, 0x8b, 0x62, 0x0c, 0xb3, 0xac, 0x5e, +- 0xc3, 0x57, 0x58, 0x03, 0xe7, 0x9c, 0x65, 0x4f, 0x7d, 0xd8, 0xc9, 0x9c, +- 0xfd, 0x9c, 0xd9, 0xf2, 0x57, 0x4e, 0x44, 0x7d, 0xa5, 0x8c, 0xad, 0xb2, +- 0xf6, 0x74, 0xa6, 0x69, 0xca, 0x9a, 0x64, 0x1e, 0xd4, 0x92, 0x95, 0xfb, +- 0x4b, 0x0e, 0xda, 0xb7, 0x85, 0x87, 0x4d, 0xf9, 0x5f, 0x70, 0x26, 0x1e, +- 0x73, 0xd0, 0x56, 0xdc, 0x86, 0xde, 0xf1, 0x65, 0xa5, 0x8a, 0xae, 0xec, +- 0x0c, 0x4e, 0x42, 0x0f, 0x6f, 0x51, 0xe8, 0x87, 0x35, 0x0b, 0x4c, 0x99, +- 0x82, 0x37, 0x12, 0x01, 0x33, 0x50, 0x88, 0x4b, 0xe7, 0x38, 0x77, 0x6f, +- 0x25, 0x8c, 0xce, 0x27, 0x0b, 0xe7, 0x3f, 0xcb, 0x4c, 0x5f, 0x1f, 0x17, +- 0x7b, 0x74, 0xbb, 0xb7, 0x27, 0x70, 0xc1, 0xd1, 0x8c, 0x0b, 0x87, 0xcc, +- 0x12, 0x2c, 0x6f, 0x17, 0x3b, 0x75, 0xbb, 0x77, 0x26, 0x30, 0xe5, 0xe4, +- 0xb5, 0x73, 0xe6, 0x5c, 0x62, 0x9a, 0xbd, 0x7e, 0x29, 0x31, 0x22, 0xa6, +- 0x31, 0xbe, 0x96, 0x47, 0xbc, 0xee, 0xf2, 0x09, 0x68, 0x65, 0xe4, 0x40, +- 0xee, 0x08, 0x5a, 0x1d, 0x49, 0xdd, 0xdf, 0xe6, 0x68, 0xc2, 0xaa, 0xac, +- 0x9f, 0x3c, 0xfa, 0x05, 0xf2, 0x4e, 0xfb, 0x3e, 0x1f, 0x6d, 0xd2, 0xc9, +- 0x0a, 0x43, 0xb3, 0xd4, 0x88, 0xe4, 0x76, 0x55, 0xb8, 0x4b, 0xdb, 0xfa, +- 0x11, 0x35, 0x32, 0x88, 0x9b, 0x9a, 0xdd, 0xad, 0xd5, 0x13, 0x45, 0x9d, +- 0x20, 0xe6, 0x89, 0x40, 0xab, 0x32, 0xa0, 0x56, 0x46, 0x44, 0x37, 0xfe, +- 0xd6, 0xe4, 0xb8, 0xc8, 0xaa, 0xb9, 0x07, 0xc6, 0x7f, 0xe3, 0x46, 0x79, +- 0x94, 0x58, 0xf5, 0x43, 0xdf, 0x7f, 0xae, 0xde, 0x33, 0x6e, 0xc1, 0x7b, +- 0x97, 0x21, 0xdf, 0xb6, 0x6d, 0x31, 0x1f, 0x19, 0xfb, 0x8c, 0x3b, 0x60, +- 0x59, 0x8c, 0x93, 0x3e, 0x28, 0x73, 0x39, 0x1e, 0xfa, 0x1a, 0xe3, 0xd2, +- 0xc6, 0xcc, 0x1f, 0xac, 0x8f, 0x3a, 0x6d, 0x0e, 0x40, 0xde, 0xe4, 0xbf, +- 0xed, 0x75, 0xe3, 0xf7, 0x96, 0xf0, 0x11, 0x27, 0x7d, 0xba, 0x84, 0x78, +- 0xbe, 0xdb, 0x74, 0xb6, 0xad, 0x50, 0x14, 0xf4, 0x19, 0x0b, 0xb4, 0x32, +- 0xc6, 0xa9, 0x5e, 0xfa, 0x75, 0xcc, 0x6b, 0x04, 0x0f, 0x81, 0xe5, 0x32, +- 0x9b, 0x37, 0xbb, 0x22, 0xf7, 0x7c, 0x76, 0xac, 0x59, 0xb0, 0x60, 0xea, +- 0xb6, 0x27, 0x8d, 0x0e, 0xf2, 0xaf, 0xaf, 0x90, 0xa7, 0xe5, 0xfb, 0xc9, +- 0x61, 0xde, 0x07, 0xf4, 0xb3, 0x79, 0x73, 0x69, 0x44, 0x78, 0x58, 0xfa, +- 0xb6, 0xc3, 0x46, 0x1b, 0x73, 0xb0, 0x7b, 0x3e, 0x7b, 0xae, 0xf9, 0x00, +- 0xbf, 0xf3, 0x75, 0xd2, 0xa8, 0xfe, 0xc0, 0x3a, 0x15, 0x11, 0xe9, 0xc3, +- 0xcf, 0x3e, 0xee, 0xf9, 0x6c, 0xe7, 0x92, 0x31, 0x6c, 0xcf, 0x6e, 0xfb, +- 0x93, 0xfd, 0x54, 0x46, 0x64, 0x3d, 0x34, 0x76, 0xfb, 0xea, 0xc0, 0x3d, +- 0x9f, 0xcd, 0x2c, 0x19, 0x64, 0x1f, 0x9f, 0x66, 0x7c, 0xc9, 0xd7, 0x89, +- 0x2a, 0x8e, 0x0f, 0xd4, 0x41, 0x59, 0x64, 0xdb, 0xed, 0x0b, 0x03, 0xbf, +- 0xb7, 0x16, 0x0c, 0x94, 0xd8, 0x3a, 0x70, 0x51, 0x07, 0x0f, 0x9a, 0xce, +- 0x5c, 0xc0, 0x61, 0xeb, 0xa0, 0xcb, 0x47, 0x1d, 0x24, 0xa9, 0x83, 0xdc, +- 0x4c, 0x23, 0xfc, 0x36, 0x75, 0xb0, 0x60, 0x7c, 0xf3, 0xe6, 0xb2, 0x08, +- 0x9c, 0x0e, 0xe3, 0x47, 0x0e, 0xe6, 0x45, 0xaa, 0xcb, 0xd8, 0x4c, 0xbd, +- 0xdd, 0xf3, 0xd9, 0xf9, 0x4b, 0x6c, 0x9d, 0xdf, 0xea, 0x0e, 0xdc, 0x47, +- 0xbb, 0x69, 0xa5, 0xad, 0x6f, 0xe5, 0xd1, 0xce, 0xa3, 0x8f, 0x47, 0x02, +- 0xbb, 0xb3, 0x1b, 0xa9, 0xab, 0x35, 0x1c, 0xc7, 0x3a, 0xca, 0xd5, 0xc5, +- 0xdf, 0x31, 0xfe, 0x8e, 0xf3, 0xb7, 0xcc, 0x8f, 0x7a, 0x49, 0xb6, 0xd8, +- 0x25, 0xd9, 0x1c, 0x94, 0xc7, 0x63, 0xaf, 0x55, 0x96, 0x47, 0x8e, 0xdf, +- 0xba, 0x3a, 0xd0, 0xc9, 0x36, 0xfe, 0xbf, 0x32, 0xd9, 0x57, 0xe0, 0x32, +- 0xe2, 0x3e, 0x27, 0x44, 0x3e, 0xbd, 0xa3, 0x13, 0x39, 0x62, 0xef, 0xef, +- 0xf2, 0xd8, 0x4b, 0xd9, 0xaa, 0x38, 0x3f, 0xcf, 0x2d, 0x49, 0xcf, 0xf6, +- 0x18, 0xf0, 0xb9, 0x8d, 0x7e, 0x0c, 0x64, 0x47, 0xa8, 0x03, 0xb1, 0x93, +- 0x2f, 0x52, 0x7f, 0xdd, 0xac, 0x73, 0x8a, 0xb1, 0x4c, 0x8f, 0xd2, 0x67, +- 0x69, 0xb3, 0x7a, 0x98, 0x07, 0xed, 0xe5, 0x51, 0xb6, 0x9b, 0xa6, 0x4c, +- 0x25, 0xb4, 0x5f, 0x05, 0x72, 0x0f, 0xf7, 0x0c, 0xdb, 0x3f, 0x6c, 0xfc, +- 0xba, 0xe2, 0x14, 0xc7, 0x1e, 0xf5, 0x6e, 0xc6, 0x68, 0x93, 0xe8, 0x2a, +- 0x46, 0x5d, 0xe9, 0x3e, 0xff, 0x34, 0x5d, 0x5e, 0x96, 0xf7, 0x0a, 0xf2, +- 0x09, 0xcb, 0xfa, 0x89, 0xd1, 0xb2, 0x90, 0x49, 0x21, 0xd2, 0x76, 0xae, +- 0x64, 0x59, 0x25, 0xf6, 0xfe, 0xb3, 0xd8, 0xed, 0x1b, 0x0c, 0x91, 0xb7, +- 0xb1, 0x7d, 0x3b, 0x8d, 0x73, 0x73, 0x86, 0xfe, 0x1c, 0xf8, 0x9d, 0x15, +- 0x9d, 0x29, 0xf5, 0xe6, 0xe1, 0x15, 0xc6, 0xde, 0xa8, 0x16, 0xef, 0x74, +- 0x0b, 0xbf, 0x37, 0x9c, 0xe1, 0x35, 0x88, 0x33, 0xa1, 0xd4, 0x83, 0x77, +- 0x92, 0x7b, 0x9e, 0x33, 0xf2, 0x7e, 0x7c, 0x24, 0xa3, 0x47, 0x1f, 0xe6, +- 0x39, 0x39, 0x30, 0xb9, 0x54, 0x31, 0x4e, 0x05, 0xc9, 0x7b, 0x3d, 0x70, +- 0x32, 0x87, 0x6a, 0x75, 0xf4, 0x04, 0x5d, 0xa0, 0x2f, 0x96, 0xcb, 0xb8, +- 0xe2, 0x1c, 0xa3, 0xe0, 0xb6, 0x5b, 0xdb, 0x68, 0x63, 0x79, 0x7c, 0xa1, +- 0x0b, 0x1e, 0x6d, 0x53, 0xa6, 0x18, 0xe3, 0x3c, 0xda, 0xfa, 0x84, 0xe0, +- 0x82, 0xdc, 0x77, 0x0d, 0x53, 0xcf, 0x82, 0x0f, 0xaf, 0xda, 0x7b, 0xd5, +- 0x88, 0x11, 0x55, 0x4e, 0x23, 0xdf, 0xae, 0xc6, 0x76, 0xdb, 0x1d, 0x1a, +- 0x2e, 0xfb, 0xb8, 0xae, 0xb5, 0x3b, 0x64, 0x1f, 0x1d, 0xd1, 0x2b, 0x53, +- 0xa8, 0x97, 0xc7, 0xb9, 0x65, 0x2e, 0x1b, 0xe7, 0xd8, 0x06, 0xf3, 0x8e, +- 0xe5, 0x89, 0xf7, 0xf7, 0x2f, 0xfd, 0x49, 0xbf, 0x3d, 0x35, 0x2a, 0x64, +- 0x9f, 0x8f, 0xdc, 0x13, 0xeb, 0x64, 0xbe, 0x36, 0x7d, 0xaf, 0x8f, 0x7e, +- 0x82, 0xed, 0x1f, 0x8f, 0x73, 0x3e, 0xe7, 0x1a, 0xb2, 0x0f, 0x48, 0xee, +- 0xa1, 0x4d, 0xdf, 0xf7, 0x63, 0xdf, 0x9f, 0x2c, 0x17, 0x2e, 0x73, 0x98, +- 0x38, 0x19, 0x6d, 0x97, 0xfa, 0x96, 0xf5, 0xe3, 0x05, 0x41, 0xe4, 0x66, +- 0x38, 0x31, 0xd2, 0x00, 0x0c, 0x27, 0x45, 0xd7, 0xe9, 0xcf, 0x6c, 0x30, +- 0xfe, 0xcd, 0x8a, 0xd6, 0x36, 0x6a, 0xbd, 0xaa, 0xac, 0x67, 0x8c, 0xdd, +- 0xda, 0x67, 0xd4, 0x6b, 0x7d, 0x6a, 0xee, 0x18, 0xe3, 0xd0, 0x01, 0xe6, +- 0xe8, 0xe5, 0x82, 0x15, 0x35, 0x46, 0xb4, 0xbf, 0x06, 0x0d, 0xf0, 0xdb, +- 0xf7, 0x24, 0xf4, 0xf8, 0x37, 0x54, 0x23, 0xb8, 0x56, 0xf8, 0xa7, 0xfa, +- 0x8e, 0x95, 0xa6, 0x0d, 0x7c, 0xa1, 0xe1, 0x67, 0x65, 0x79, 0x6c, 0x8f, +- 0x76, 0xce, 0xe2, 0xbc, 0xbc, 0xb9, 0x48, 0xf7, 0x67, 0x14, 0xd1, 0x91, +- 0x70, 0xae, 0x11, 0xec, 0x62, 0x3c, 0xfe, 0xb7, 0x86, 0x08, 0x8e, 0xf0, +- 0xfb, 0xa7, 0xd7, 0xca, 0x1e, 0x37, 0xcb, 0x0a, 0x06, 0x16, 0x84, 0x6b, +- 0x38, 0x86, 0x67, 0xf8, 0x7f, 0x7f, 0xf6, 0x75, 0xeb, 0xdc, 0x2c, 0x63, +- 0x70, 0x25, 0x83, 0xe2, 0xf0, 0x84, 0xae, 0x4d, 0xa9, 0xff, 0xd9, 0x3d, +- 0x37, 0xf6, 0x3a, 0xe3, 0x67, 0x9e, 0x0f, 0x34, 0x6a, 0x49, 0xb5, 0xae, +- 0x5c, 0xf4, 0x3a, 0x3c, 0xf1, 0x52, 0x21, 0xce, 0xe7, 0xef, 0x75, 0x3e, +- 0x7e, 0x49, 0x3f, 0x72, 0xdf, 0x76, 0x1e, 0x6d, 0x2e, 0x1a, 0xa7, 0xde, +- 0xdd, 0x33, 0x38, 0xe6, 0x2f, 0x34, 0xdc, 0x69, 0x8f, 0xb3, 0xd6, 0x98, +- 0xc3, 0x31, 0x2a, 0xd0, 0x1a, 0x9c, 0xe5, 0x79, 0xfe, 0xd8, 0x42, 0x96, +- 0x96, 0xb6, 0x5a, 0xe9, 0x43, 0x25, 0xac, 0x73, 0xbd, 0x79, 0x70, 0x76, +- 0x4f, 0x93, 0xee, 0xfb, 0x02, 0x6d, 0x35, 0xd4, 0xf0, 0x2b, 0x2b, 0xaa, +- 0x39, 0xcd, 0xaf, 0x73, 0xd4, 0x77, 0x26, 0xa4, 0xac, 0xcc, 0xab, 0x11, +- 0x6d, 0x50, 0xde, 0xb2, 0x30, 0x33, 0x10, 0x6e, 0xb0, 0xc7, 0x0f, 0xdc, +- 0x91, 0x19, 0x61, 0xae, 0x2c, 0x6d, 0x2a, 0x58, 0x19, 0x78, 0xc3, 0xf2, +- 0xcf, 0x1a, 0xc1, 0xce, 0xec, 0x1f, 0xe3, 0xb0, 0x5f, 0x21, 0x87, 0xd6, +- 0x3b, 0xe2, 0x79, 0xbf, 0x6b, 0x03, 0xfb, 0x2d, 0x37, 0xec, 0x3c, 0xfc, +- 0xb6, 0x44, 0x40, 0xd6, 0x8c, 0xc6, 0x3e, 0x33, 0x1e, 0x90, 0xbd, 0x19, +- 0x5e, 0xe4, 0xda, 0xa5, 0x4c, 0xbd, 0x36, 0x8e, 0x1c, 0x19, 0xa6, 0xec, +- 0x23, 0x39, 0x54, 0x9e, 0x5f, 0x47, 0x70, 0xc8, 0x3a, 0xb8, 0xf6, 0x2a, +- 0x39, 0x61, 0x9b, 0x21, 0x6d, 0x28, 0x58, 0x18, 0x98, 0x81, 0xc6, 0xb5, +- 0x3f, 0x7a, 0xb9, 0x24, 0x90, 0xf7, 0xdb, 0x3e, 0xc3, 0xd8, 0x76, 0x1a, +- 0xbf, 0x26, 0x56, 0xc9, 0x3e, 0x93, 0xb4, 0xd4, 0x63, 0x5b, 0x0d, 0xc8, +- 0x68, 0x4e, 0x8c, 0x1a, 0xb2, 0x0f, 0xd2, 0xb2, 0x56, 0x07, 0x5e, 0xa3, +- 0xdf, 0x51, 0x9e, 0xac, 0xb3, 0x50, 0x57, 0xca, 0x14, 0xf6, 0x70, 0x28, +- 0x2d, 0x9f, 0x15, 0x9d, 0x3c, 0x61, 0xc6, 0x99, 0x35, 0x48, 0x7c, 0x18, +- 0xfb, 0xcc, 0xeb, 0x86, 0x70, 0x78, 0xdd, 0x5c, 0xa9, 0x54, 0x33, 0xde, +- 0x3a, 0xfd, 0x63, 0xf6, 0x7a, 0x86, 0x9f, 0x58, 0x2e, 0x3c, 0x54, 0x72, +- 0x43, 0x27, 0x9e, 0x34, 0x6a, 0xf0, 0x84, 0x96, 0xe7, 0x74, 0xc4, 0x44, +- 0xbc, 0x90, 0x58, 0x90, 0xa3, 0x87, 0x90, 0x1b, 0x1b, 0x9d, 0x17, 0x95, +- 0x5f, 0x33, 0x6f, 0x04, 0x9e, 0xcb, 0x74, 0xe1, 0x41, 0xb9, 0x8f, 0xa5, +- 0xd4, 0xb7, 0x35, 0x3a, 0xa4, 0xbf, 0x2e, 0xec, 0xb2, 0xd7, 0x65, 0xc7, +- 0x3e, 0x73, 0xd8, 0x78, 0xa4, 0x20, 0xab, 0x60, 0xfe, 0xd8, 0x67, 0x9e, +- 0x34, 0x4e, 0xdb, 0x73, 0x27, 0x7b, 0x16, 0xfa, 0x4d, 0xc1, 0xc6, 0x72, +- 0xa8, 0xcc, 0x2f, 0x1c, 0xc6, 0xa7, 0xe1, 0xa8, 0x19, 0xa3, 0xed, 0xc9, +- 0x7a, 0xcf, 0xed, 0x70, 0xd6, 0xb8, 0xe8, 0x9b, 0x77, 0xc0, 0x55, 0x23, +- 0x9c, 0xbe, 0xc8, 0xb7, 0xdb, 0xf8, 0xbf, 0xe8, 0x76, 0xca, 0xd6, 0xad, +- 0x93, 0xd8, 0xd3, 0x27, 0xf9, 0x9f, 0x51, 0x4d, 0x1d, 0xe9, 0x1d, 0xb2, +- 0xae, 0x5d, 0x49, 0x6c, 0x65, 0x1c, 0x75, 0x57, 0xb3, 0xcc, 0xdb, 0xd4, +- 0xfb, 0x82, 0x81, 0x0a, 0x72, 0x7d, 0xcb, 0x7a, 0x87, 0x5c, 0x7f, 0x61, +- 0xa0, 0x31, 0x67, 0x30, 0xfe, 0xe1, 0x66, 0xbd, 0x4d, 0xee, 0x11, 0x6f, +- 0x30, 0x2e, 0x5a, 0xb1, 0x75, 0x52, 0x46, 0xf7, 0xc5, 0x94, 0x62, 0x1f, +- 0x8b, 0xe0, 0x9f, 0x61, 0xc1, 0x15, 0xb1, 0x88, 0x5d, 0xba, 0x19, 0x45, +- 0x8b, 0xec, 0xf5, 0x69, 0x97, 0xf1, 0xbb, 0xe4, 0x7e, 0x03, 0xa2, 0x93, +- 0x2e, 0x18, 0xb9, 0x23, 0x32, 0x67, 0xb3, 0x2d, 0x04, 0x16, 0xff, 0x8e, +- 0x39, 0x93, 0xcc, 0x4f, 0x7d, 0xae, 0x49, 0xc9, 0x05, 0x7d, 0xe4, 0xfe, +- 0x8f, 0x40, 0x6f, 0x4f, 0x50, 0xd7, 0xad, 0x21, 0x1b, 0xf3, 0x7c, 0x09, +- 0xd8, 0x7c, 0xdf, 0x7c, 0x05, 0x1f, 0x45, 0x25, 0x73, 0xdc, 0x86, 0xf1, +- 0x35, 0xa8, 0xaa, 0x89, 0xfa, 0xca, 0xb1, 0x94, 0xe7, 0x5b, 0x99, 0xc7, +- 0x7c, 0x12, 0x55, 0x6b, 0x63, 0x48, 0x70, 0xec, 0x95, 0xc6, 0xad, 0xbc, +- 0xd6, 0x87, 0x64, 0xca, 0xc5, 0x71, 0xfc, 0xd0, 0xaa, 0x9a, 0x29, 0xb2, +- 0x99, 0xde, 0x0a, 0x83, 0x79, 0xb7, 0xad, 0x0b, 0x62, 0x79, 0x4a, 0xb8, +- 0x54, 0x63, 0x74, 0x0b, 0xfe, 0x40, 0xdb, 0xd5, 0x3b, 0x36, 0x2a, 0x71, +- 0xda, 0x6c, 0x82, 0x3a, 0x97, 0xb2, 0x96, 0xb5, 0x2a, 0xf0, 0x5b, 0xea, +- 0x38, 0xce, 0x73, 0xc3, 0xff, 0x1a, 0xd4, 0xa5, 0xa5, 0x38, 0x6b, 0xc5, +- 0x35, 0x1f, 0xed, 0x52, 0x5d, 0x27, 0xbc, 0x6b, 0x45, 0x48, 0xad, 0x40, +- 0xb9, 0x56, 0xb0, 0xd3, 0x74, 0x41, 0x97, 0x53, 0xb7, 0xf5, 0x19, 0x6f, +- 0x94, 0xcb, 0x75, 0x87, 0x7d, 0xdd, 0x5f, 0xb8, 0x9e, 0xe6, 0xf5, 0xf3, +- 0xbc, 0x3e, 0x48, 0xdd, 0xab, 0x57, 0x48, 0xfd, 0xcd, 0xa6, 0xd4, 0x27, +- 0x1d, 0x31, 0x12, 0x85, 0xf9, 0x88, 0xdd, 0x9e, 0x2f, 0xbb, 0xed, 0xf6, +- 0x7c, 0x1b, 0x4e, 0xb6, 0x11, 0x8f, 0x96, 0xc3, 0x44, 0x45, 0x40, 0x70, +- 0x5e, 0xe4, 0xe2, 0xdc, 0x65, 0x45, 0xae, 0xad, 0x8c, 0x8b, 0x3d, 0x4f, +- 0x97, 0x23, 0xde, 0x35, 0xc7, 0xb6, 0xc3, 0x34, 0x79, 0x8a, 0xee, 0x7f, +- 0x5d, 0x69, 0xf1, 0xc9, 0xb2, 0x4e, 0x8a, 0x9c, 0xf7, 0x7e, 0xd3, 0x19, +- 0x6e, 0x72, 0x2c, 0xc8, 0x95, 0xc2, 0x88, 0x5d, 0x54, 0x66, 0x57, 0x08, +- 0x3e, 0x24, 0x32, 0x2d, 0xcc, 0xd0, 0xe2, 0x41, 0xe6, 0x56, 0xc1, 0x2c, +- 0x75, 0xbb, 0x9e, 0x88, 0x7d, 0xc2, 0xde, 0xb3, 0xe4, 0x9c, 0x5c, 0x83, +- 0x16, 0xdd, 0x81, 0x05, 0xe1, 0x39, 0xcc, 0xd0, 0x68, 0x97, 0x66, 0xa9, +- 0x43, 0xf7, 0xdf, 0x84, 0xff, 0x62, 0xd7, 0x3b, 0x92, 0xc9, 0x75, 0x96, +- 0x73, 0x4e, 0xbf, 0x4a, 0x39, 0x76, 0x07, 0x44, 0x8e, 0xb1, 0x82, 0x1c, +- 0x31, 0xc6, 0x5c, 0x53, 0xbb, 0x21, 0x30, 0x78, 0x49, 0x6f, 0x4f, 0xdb, +- 0x7a, 0xeb, 0xe3, 0x79, 0x29, 0x76, 0x90, 0x3f, 0x9e, 0x6a, 0xf2, 0x16, +- 0xd6, 0xf6, 0x25, 0xa7, 0x13, 0xfc, 0x3d, 0xfb, 0xa9, 0x0d, 0x86, 0x1e, +- 0x76, 0xd8, 0xfc, 0xdf, 0x8d, 0xb8, 0xcd, 0xad, 0x1d, 0x10, 0xee, 0xf8, +- 0xb0, 0x5d, 0xce, 0x45, 0x9d, 0x54, 0xe0, 0x91, 0x82, 0xbf, 0x54, 0x30, +- 0xbe, 0x7d, 0xd5, 0xfe, 0x9d, 0xe6, 0xdc, 0xba, 0xe8, 0xab, 0xc5, 0x18, +- 0x25, 0xeb, 0x83, 0xfd, 0xb6, 0xef, 0xa7, 0xf1, 0x7d, 0xfb, 0x3b, 0x97, +- 0xcf, 0xcb, 0xd0, 0x47, 0x9f, 0x70, 0xb0, 0x8d, 0x5e, 0x7b, 0x2f, 0xaa, +- 0xac, 0x15, 0x5c, 0x8b, 0x1d, 0x1c, 0x95, 0xdb, 0xe8, 0x44, 0xbf, 0x26, +- 0x36, 0xd1, 0x8d, 0xa4, 0x66, 0x7a, 0xb3, 0x4d, 0xd3, 0x73, 0x2a, 0x13, +- 0x87, 0x9a, 0x7e, 0xcf, 0x58, 0x2e, 0xd7, 0xce, 0x5a, 0x87, 0x8d, 0x53, +- 0x21, 0x7a, 0x70, 0x67, 0x89, 0xad, 0xdf, 0xa9, 0xdb, 0xec, 0x7d, 0x5b, +- 0x94, 0xf9, 0xe9, 0x84, 0xc4, 0xd1, 0x79, 0xc8, 0x98, 0x22, 0x9b, 0xb3, +- 0x7d, 0x0f, 0xe7, 0xa4, 0x2f, 0x15, 0x88, 0x5e, 0xc9, 0xff, 0x26, 0x19, +- 0xcb, 0x7a, 0xa9, 0xcf, 0x58, 0xbb, 0xf0, 0xb8, 0xad, 0x38, 0x40, 0x1b, +- 0x9b, 0x30, 0x2d, 0xeb, 0x08, 0x31, 0xa2, 0x7a, 0x81, 0x8a, 0xdc, 0xcc, +- 0xad, 0x48, 0x31, 0x36, 0x1d, 0x31, 0x5a, 0x3e, 0x5a, 0x82, 0xb8, 0x9f, +- 0x31, 0xdc, 0xb7, 0x93, 0xa3, 0xb9, 0x9f, 0xf3, 0x75, 0xca, 0x14, 0x7e, +- 0xe9, 0xbc, 0xb8, 0x02, 0x46, 0x78, 0x99, 0xe3, 0x87, 0xd6, 0x94, 0xc8, +- 0x9e, 0xea, 0xf9, 0x5f, 0x94, 0x61, 0x9b, 0x38, 0x6f, 0x35, 0xe7, 0xf8, +- 0xed, 0x80, 0xde, 0xf6, 0x02, 0xfb, 0x69, 0x1c, 0x68, 0xe9, 0x14, 0x19, +- 0x0e, 0x87, 0x9c, 0xb1, 0x23, 0x08, 0xb4, 0x6f, 0x55, 0x8a, 0x39, 0x04, +- 0x70, 0xe5, 0xb8, 0x89, 0xa3, 0x4d, 0xcf, 0x90, 0xef, 0x48, 0xfd, 0x52, +- 0x3c, 0x66, 0x3e, 0x65, 0xd5, 0xcf, 0x7e, 0xde, 0x3a, 0x66, 0xa8, 0x5b, +- 0xa8, 0xed, 0x58, 0x25, 0x64, 0x4d, 0x33, 0x7d, 0xdb, 0x5d, 0x01, 0xdd, +- 0xdc, 0xc3, 0xb6, 0xce, 0x24, 0x4e, 0x05, 0xdd, 0x6c, 0xeb, 0x11, 0x53, +- 0x72, 0x08, 0x67, 0x5b, 0x1b, 0xe7, 0xb6, 0x27, 0x15, 0xf0, 0xc9, 0xba, +- 0xad, 0xe4, 0x79, 0xb7, 0x27, 0x64, 0xcf, 0xf8, 0x18, 0xc7, 0x13, 0xdd, +- 0xe6, 0x42, 0xcb, 0xfd, 0x55, 0xb4, 0x9f, 0x6a, 0x14, 0x6d, 0x5d, 0xf7, +- 0x11, 0xef, 0x70, 0x17, 0xcb, 0xbc, 0x1c, 0x98, 0x87, 0xe7, 0x42, 0x2d, +- 0x6b, 0xe7, 0xc1, 0x19, 0x3b, 0xa6, 0x04, 0xda, 0xb6, 0x2a, 0x71, 0x4d, +- 0x6c, 0xf1, 0xce, 0x8c, 0x1e, 0x6c, 0x85, 0x60, 0x77, 0x8c, 0xfa, 0x98, +- 0x87, 0x77, 0x16, 0x8b, 0x5c, 0xce, 0x70, 0xd0, 0x11, 0xe8, 0x7a, 0x8a, +- 0xf3, 0x5b, 0xb5, 0x40, 0x64, 0x07, 0xb2, 0x19, 0x91, 0x3f, 0x86, 0x64, +- 0xf6, 0xec, 0xdb, 0x87, 0x0d, 0x38, 0x4f, 0x34, 0x3d, 0x68, 0xc1, 0xde, +- 0x63, 0xde, 0x22, 0xf3, 0xd0, 0x21, 0xf3, 0x50, 0x4e, 0x7f, 0x5a, 0x4d, +- 0xb9, 0xb7, 0xd8, 0x72, 0xcf, 0xc3, 0xa8, 0x29, 0xeb, 0x64, 0x4e, 0xed, +- 0x4e, 0x0c, 0x12, 0x3b, 0x03, 0x17, 0x7b, 0xd8, 0xcf, 0xcb, 0x94, 0x79, +- 0x01, 0xf5, 0x3e, 0xd5, 0x2e, 0xfc, 0xb6, 0x0f, 0x03, 0xa9, 0xe2, 0x1e, +- 0x74, 0x05, 0x92, 0x7a, 0x4f, 0x39, 0xfa, 0xc8, 0xf7, 0x7a, 0xac, 0xa9, +- 0x99, 0x72, 0x3d, 0x8d, 0x1d, 0xa9, 0xa8, 0x46, 0x7f, 0xa0, 0xde, 0xa1, +- 0xcf, 0x83, 0x3e, 0xf9, 0xaa, 0x23, 0x4a, 0x1f, 0x30, 0xbd, 0x17, 0x89, +- 0x0d, 0x27, 0xd0, 0x65, 0xa1, 0xc6, 0xb6, 0x87, 0x9f, 0x8e, 0x19, 0x0e, +- 0x59, 0x6b, 0x0f, 0xe6, 0xa8, 0x03, 0x95, 0x73, 0x22, 0x3a, 0xa8, 0xa4, +- 0xcf, 0x8e, 0x07, 0x74, 0xff, 0x73, 0x94, 0x67, 0x0f, 0xe5, 0x59, 0x93, +- 0x9f, 0x43, 0xdf, 0x0e, 0x45, 0x7c, 0x3a, 0xd0, 0xbe, 0x81, 0xd7, 0x77, +- 0x53, 0x9e, 0xc0, 0x80, 0x82, 0x34, 0xd1, 0xac, 0x8f, 0x7c, 0xf6, 0xc0, +- 0x34, 0x79, 0xdc, 0xf6, 0x9c, 0xc5, 0xc9, 0x05, 0x4a, 0x71, 0xd8, 0x14, +- 0xfc, 0xd6, 0x30, 0x4a, 0x3b, 0x3d, 0xc4, 0x19, 0x89, 0x7a, 0x55, 0x94, +- 0x1a, 0x82, 0x01, 0x33, 0x79, 0xcd, 0xc5, 0xb9, 0xa9, 0xc6, 0x31, 0x2d, +- 0xcd, 0x38, 0x59, 0xe4, 0x76, 0x7f, 0xb0, 0x8e, 0x7a, 0x85, 0x9f, 0xc9, +- 0x3a, 0x9a, 0xac, 0x35, 0x7d, 0xb9, 0x22, 0xbf, 0xbf, 0x52, 0xf6, 0x3f, +- 0xe4, 0xaf, 0x3f, 0xad, 0x09, 0x47, 0x2e, 0x96, 0xff, 0xb9, 0xf5, 0x84, +- 0x5d, 0x5e, 0xca, 0xb9, 0x6c, 0x2e, 0x5f, 0x6e, 0x97, 0xfb, 0xb9, 0xf5, +- 0x8c, 0xe6, 0x9c, 0x56, 0xae, 0xb8, 0x07, 0xef, 0xd4, 0x97, 0x5c, 0xc4, +- 0x3c, 0x47, 0xc3, 0x32, 0x3c, 0x61, 0x9c, 0xad, 0x5f, 0xdf, 0xd4, 0xcd, +- 0x38, 0x56, 0xe4, 0x5a, 0x75, 0xf4, 0x2b, 0x0b, 0x43, 0xe6, 0xa9, 0xa1, +- 0x12, 0xf4, 0x90, 0x3b, 0x0a, 0x17, 0x10, 0x8e, 0x2a, 0xeb, 0x7c, 0xb7, +- 0x96, 0x5f, 0xce, 0x79, 0xf5, 0xa0, 0x5f, 0x6d, 0xb3, 0xb9, 0x61, 0x54, +- 0x15, 0xdc, 0xad, 0xb3, 0xc7, 0x7e, 0x39, 0xfe, 0x4b, 0xac, 0x98, 0xbe, +- 0x6e, 0xd7, 0x8d, 0x43, 0x46, 0x91, 0xb3, 0x9c, 0x7a, 0x50, 0x25, 0x4e, +- 0x0e, 0x9b, 0xcb, 0x24, 0x36, 0xfb, 0x59, 0x3f, 0x18, 0x53, 0xa7, 0x73, +- 0x9b, 0xbf, 0xa9, 0x40, 0x55, 0xcf, 0x2e, 0x07, 0x64, 0xff, 0xaf, 0xec, +- 0xd9, 0x96, 0xbe, 0xca, 0x0a, 0xeb, 0x57, 0x1f, 0xc4, 0x35, 0x8a, 0x7d, +- 0x09, 0xdf, 0xa8, 0x28, 0xca, 0x18, 0x8c, 0xda, 0x72, 0xfe, 0xd2, 0x5a, +- 0xab, 0xe5, 0xe6, 0x68, 0x78, 0xaf, 0xec, 0xd1, 0x82, 0xec, 0xb1, 0x0f, +- 0x5c, 0x7f, 0x93, 0x7e, 0xa6, 0xb7, 0x59, 0xdc, 0x7b, 0x2a, 0x6b, 0xb3, +- 0xf2, 0x9f, 0x82, 0x1e, 0xe2, 0x50, 0x54, 0x6b, 0x61, 0x9c, 0xd7, 0x7d, +- 0x9b, 0x38, 0x1f, 0x71, 0xaf, 0xec, 0x6b, 0x2d, 0xc6, 0xc8, 0x52, 0xe4, +- 0xd7, 0x48, 0x81, 0x43, 0x85, 0x75, 0x51, 0xda, 0x3d, 0x7a, 0x32, 0xbf, +- 0xb3, 0x72, 0x5e, 0x27, 0x63, 0xe1, 0xe5, 0xfd, 0xf7, 0x69, 0xea, 0x75, +- 0x94, 0xff, 0xed, 0xb8, 0xb4, 0xee, 0x22, 0x6b, 0x4f, 0x12, 0x7b, 0x7f, +- 0x6b, 0xad, 0x7f, 0x4f, 0xd9, 0xe9, 0x7b, 0x5f, 0x67, 0xc6, 0x64, 0x3f, +- 0xda, 0xd1, 0xc2, 0xfa, 0x7c, 0xeb, 0xbf, 0xdf, 0x8f, 0x46, 0x5b, 0x42, +- 0x74, 0x07, 0xb9, 0x5d, 0x1c, 0x7d, 0x38, 0x9a, 0x68, 0xd4, 0x76, 0x42, +- 0x93, 0x75, 0x69, 0x7e, 0xfa, 0x70, 0x2c, 0x81, 0x68, 0xc9, 0x55, 0xd5, +- 0xe4, 0x5b, 0x88, 0x3a, 0x64, 0x8f, 0x50, 0xa2, 0xb1, 0x6d, 0x37, 0xc7, +- 0xe4, 0x5f, 0xdb, 0x87, 0xd1, 0x44, 0xcb, 0xad, 0x8c, 0x23, 0xfe, 0x8a, +- 0x3c, 0xd7, 0xe9, 0x38, 0x4c, 0x1c, 0xd8, 0x5e, 0x58, 0x1b, 0x5b, 0x9f, +- 0xf8, 0x15, 0xe5, 0xb7, 0x85, 0x64, 0xbd, 0x3f, 0x56, 0xee, 0x2c, 0x7a, +- 0x53, 0x67, 0xb1, 0x79, 0x50, 0x11, 0xfb, 0xc2, 0xa6, 0xb4, 0xc8, 0x73, +- 0x16, 0x1b, 0x07, 0xbf, 0x87, 0x43, 0x83, 0xb3, 0xd1, 0x6a, 0xeb, 0xa6, +- 0x0b, 0x5b, 0xf7, 0x9e, 0xc4, 0x9e, 0x94, 0x85, 0xdd, 0x21, 0x0f, 0xb6, +- 0x1c, 0x54, 0xb0, 0x2a, 0x70, 0x06, 0x3b, 0xf7, 0x5a, 0x98, 0x1f, 0xea, +- 0x46, 0x9b, 0x59, 0x81, 0xd2, 0x9a, 0x05, 0x9d, 0x2a, 0xcb, 0xad, 0x1f, +- 0xed, 0x52, 0x6e, 0xe4, 0xb8, 0x73, 0xae, 0xe3, 0xc4, 0x02, 0x15, 0x3e, +- 0x03, 0x5a, 0x75, 0x24, 0xaa, 0xdc, 0x92, 0x6d, 0x55, 0x3a, 0x46, 0x6d, +- 0x3e, 0xa5, 0xdc, 0x94, 0xf5, 0x55, 0x4a, 0x4c, 0x3f, 0x14, 0x3a, 0x8b, +- 0x74, 0xba, 0xaa, 0x32, 0xef, 0x2f, 0x67, 0xc9, 0x1d, 0x24, 0xe7, 0x30, +- 0x69, 0x53, 0x7f, 0xec, 0xb9, 0x02, 0xb1, 0xbb, 0x29, 0xfc, 0x64, 0xe4, +- 0x15, 0xbc, 0x32, 0xf2, 0x2f, 0x58, 0xae, 0x49, 0x9e, 0x69, 0x75, 0x3b, +- 0x23, 0x96, 0xb5, 0xbf, 0x39, 0x6e, 0xcd, 0x34, 0x2c, 0xb6, 0x57, 0x85, +- 0x59, 0x91, 0xef, 0x62, 0xb7, 0xc6, 0xb6, 0x52, 0xc7, 0xed, 0x7b, 0xb7, +- 0xbe, 0xc8, 0xa7, 0xe1, 0x4b, 0xe5, 0xcc, 0x5a, 0x44, 0x87, 0x6a, 0xa1, +- 0x6f, 0xab, 0x71, 0x18, 0x5d, 0xff, 0x5b, 0x69, 0xc2, 0x4d, 0xd9, 0x57, +- 0xf0, 0xe6, 0x48, 0x37, 0x31, 0x53, 0xef, 0xf8, 0x96, 0x62, 0x75, 0xef, +- 0x0e, 0xe9, 0x6d, 0xff, 0x55, 0x89, 0xc6, 0xcb, 0x69, 0x53, 0x65, 0xcc, +- 0x09, 0x6e, 0x1e, 0x91, 0x7c, 0xb9, 0x03, 0xee, 0x01, 0x3d, 0xb7, 0x82, +- 0x3c, 0xfb, 0x0b, 0x8b, 0xe2, 0x73, 0x66, 0xd0, 0x2e, 0x1d, 0x8a, 0x1e, +- 0x34, 0xd4, 0x6e, 0x3c, 0x6e, 0xea, 0x93, 0xbf, 0x75, 0x18, 0xe9, 0x6f, +- 0xa2, 0x09, 0xeb, 0xb2, 0x7a, 0x7a, 0x29, 0xf3, 0xb0, 0x9d, 0x49, 0x13, +- 0xa9, 0xa4, 0xde, 0xd1, 0xe5, 0xe8, 0xc7, 0xdd, 0x81, 0xfa, 0x6d, 0x6f, +- 0x93, 0xcb, 0x79, 0x88, 0x29, 0xc9, 0x89, 0x0c, 0xf3, 0xdc, 0x7e, 0x6c, +- 0x3d, 0x18, 0xc1, 0x96, 0xfd, 0x26, 0xfa, 0x92, 0x19, 0xca, 0xf6, 0x1a, +- 0x6d, 0xdb, 0xb2, 0xda, 0x43, 0xf1, 0x1b, 0x54, 0x04, 0xa2, 0xec, 0xb3, +- 0x45, 0x8d, 0x04, 0xfc, 0xaa, 0xc2, 0xe8, 0x3f, 0xe1, 0x44, 0x2f, 0xcb, +- 0x0c, 0xa4, 0x68, 0x73, 0x49, 0x37, 0xe3, 0x65, 0x1d, 0x46, 0xc7, 0x7d, +- 0x38, 0x32, 0xee, 0x41, 0x7a, 0x5c, 0xe3, 0x51, 0x8e, 0x87, 0x86, 0x2d, +- 0x62, 0xb9, 0x17, 0x8f, 0x1d, 0x76, 0x63, 0xfb, 0x3e, 0x0f, 0xe6, 0x45, +- 0x66, 0xe1, 0xf0, 0xe1, 0x72, 0x1c, 0xe0, 0xf5, 0x9a, 0xc5, 0x7e, 0x7c, +- 0x8d, 0xd7, 0x07, 0xf7, 0xb9, 0x38, 0x0f, 0xf3, 0x71, 0x9c, 0x86, 0x9d, +- 0x1e, 0xaf, 0x40, 0x6a, 0x98, 0x26, 0x4f, 0xce, 0xfa, 0x3a, 0x33, 0x8c, +- 0xa3, 0x87, 0x19, 0x1b, 0x0f, 0x9a, 0x48, 0xb0, 0x9f, 0x3d, 0xd4, 0x55, +- 0x1f, 0x71, 0x6d, 0xeb, 0xb8, 0x60, 0xfc, 0x3a, 0xac, 0x1e, 0xd0, 0xdb, +- 0x5a, 0x15, 0x23, 0xba, 0x44, 0x09, 0xca, 0x73, 0x2b, 0x6e, 0x95, 0xd7, +- 0x5a, 0x12, 0xba, 0xd9, 0x8a, 0x6e, 0x9c, 0xe6, 0xb8, 0xff, 0x3b, 0xfd, +- 0x76, 0x99, 0x43, 0xef, 0xbf, 0x5e, 0x3d, 0x89, 0xa1, 0x6c, 0x8e, 0x5c, +- 0x1d, 0x08, 0x1f, 0x3a, 0x49, 0xfe, 0xf6, 0x38, 0xf1, 0xe7, 0x65, 0xcb, +- 0x67, 0xa8, 0xb8, 0xe9, 0x01, 0x23, 0x7c, 0x41, 0x09, 0x6c, 0xfb, 0x25, +- 0x75, 0x70, 0xe3, 0x61, 0x15, 0x1f, 0x1b, 0x5a, 0x86, 0x4c, 0x28, 0x8a, +- 0x3d, 0x4b, 0x54, 0xdc, 0x70, 0xf0, 0x24, 0x71, 0xff, 0xac, 0xcd, 0x93, +- 0x73, 0x99, 0x2f, 0x22, 0x38, 0x20, 0x6b, 0xf7, 0x6e, 0xc6, 0xef, 0x4a, +- 0x9c, 0x19, 0xec, 0xa6, 0xdf, 0x56, 0xe2, 0x54, 0xfa, 0x24, 0xed, 0xb1, +- 0x12, 0x8f, 0x0f, 0x1a, 0x93, 0x3f, 0x71, 0x54, 0xe2, 0x31, 0x9e, 0x0f, +- 0xf1, 0x7c, 0xf1, 0xb0, 0x31, 0xd8, 0xa5, 0x56, 0x62, 0xd1, 0xa1, 0x66, +- 0x0c, 0x26, 0xc5, 0x36, 0x35, 0x6c, 0x1b, 0x6f, 0x2a, 0xe8, 0x5e, 0x74, +- 0xee, 0xc5, 0x3d, 0xd4, 0xd5, 0xdd, 0x43, 0xdd, 0xec, 0xcf, 0x47, 0x9d, +- 0x9f, 0xc4, 0x43, 0xcc, 0xeb, 0x76, 0x27, 0x7d, 0x38, 0x9f, 0x32, 0xfc, +- 0x9f, 0x52, 0x0c, 0xb3, 0x4c, 0x09, 0x68, 0x67, 0xe0, 0xc3, 0x2b, 0xd9, +- 0x72, 0xf4, 0x0e, 0xd7, 0xe1, 0x27, 0xb4, 0xcf, 0x07, 0xf7, 0x9d, 0xb4, +- 0xed, 0xff, 0x40, 0x6a, 0x2e, 0x1e, 0x1b, 0x33, 0xd9, 0xb6, 0xcc, 0x93, +- 0xc3, 0xde, 0xdb, 0xe4, 0x4a, 0x89, 0x6f, 0x44, 0x87, 0x68, 0x16, 0xc4, +- 0xc4, 0x93, 0xc8, 0x0e, 0xea, 0xfd, 0x37, 0xab, 0xc2, 0xab, 0x55, 0xea, +- 0xd2, 0x81, 0x29, 0x4d, 0x8f, 0xd7, 0xa8, 0xf1, 0x41, 0xe6, 0xaf, 0xf1, +- 0x5a, 0xea, 0xe4, 0xb1, 0x41, 0x27, 0x16, 0x2c, 0x56, 0x79, 0x3d, 0x7e, +- 0x91, 0xb1, 0x2d, 0x3e, 0x4f, 0x35, 0x71, 0xc0, 0x96, 0x15, 0xf1, 0x12, +- 0x72, 0xfb, 0xea, 0xc5, 0xf5, 0x8c, 0x5f, 0x0e, 0xb1, 0xbd, 0x58, 0xa5, +- 0xea, 0xa4, 0xde, 0x5f, 0xc1, 0x18, 0xed, 0xfa, 0x11, 0x1e, 0xc7, 0x47, +- 0xac, 0xee, 0x55, 0xe4, 0xdc, 0xf3, 0x03, 0x56, 0xf7, 0xcd, 0xa6, 0xe1, +- 0x2b, 0x51, 0x03, 0xd1, 0x2f, 0xe0, 0x15, 0x1c, 0x1b, 0x93, 0x32, 0xb2, +- 0x0f, 0x24, 0x86, 0x91, 0xa4, 0xd5, 0x3d, 0x64, 0xce, 0x47, 0xb3, 0x9d, +- 0x1b, 0xbb, 0x2a, 0xf3, 0x98, 0x29, 0x7e, 0x24, 0x6b, 0x25, 0x53, 0xf8, +- 0x25, 0xdb, 0xb9, 0x30, 0x52, 0x8d, 0x19, 0xb5, 0xe2, 0x07, 0x67, 0xf1, +- 0xc6, 0xe0, 0x77, 0x71, 0x7e, 0xd0, 0xc2, 0xa2, 0x90, 0x05, 0x67, 0xa8, +- 0xd1, 0x6c, 0x55, 0x97, 0x12, 0x23, 0x14, 0xac, 0x6e, 0xf8, 0x1e, 0xde, +- 0x1a, 0x94, 0xfd, 0xa6, 0x96, 0x2d, 0xcb, 0x00, 0x16, 0x5b, 0x7b, 0x66, +- 0x8a, 0xdf, 0x48, 0xbd, 0x3f, 0x95, 0x07, 0xeb, 0x8c, 0x86, 0xc5, 0x5c, +- 0xf8, 0x15, 0x8c, 0x8e, 0x18, 0xd1, 0xcd, 0x45, 0x39, 0x07, 0x5f, 0xa1, +- 0x0e, 0xec, 0xf8, 0x74, 0xb0, 0x06, 0x0b, 0x2e, 0x32, 0x6b, 0xfc, 0xf0, +- 0x3c, 0xda, 0xce, 0xa2, 0xc5, 0x01, 0x73, 0xa5, 0xfa, 0x6f, 0xf4, 0xd3, +- 0x57, 0x70, 0x24, 0x5d, 0xc4, 0x6b, 0x1f, 0x5a, 0xe9, 0xe7, 0xf9, 0x7d, +- 0xfe, 0x5e, 0xb4, 0xa4, 0x4e, 0xd8, 0xeb, 0x0f, 0xc7, 0x89, 0x8f, 0x83, +- 0x29, 0x29, 0xa3, 0x61, 0x2c, 0xdb, 0x4a, 0x6c, 0x88, 0xe2, 0x9f, 0xb2, +- 0x11, 0xe2, 0x43, 0x98, 0xf8, 0xd0, 0x4c, 0x7c, 0x30, 0x89, 0x0f, 0x4d, +- 0xc4, 0x87, 0x20, 0xf1, 0xc1, 0xb0, 0xd7, 0xd6, 0xd3, 0x47, 0xbf, 0x8b, +- 0x92, 0xe1, 0xb3, 0x70, 0xd1, 0x07, 0xce, 0x98, 0x16, 0xf9, 0x49, 0xa3, +- 0xb6, 0x11, 0xf3, 0x95, 0xa8, 0xe6, 0x45, 0x9a, 0xed, 0x95, 0x0d, 0x6b, +- 0x1c, 0x8b, 0x85, 0x60, 0xa8, 0x3e, 0xdc, 0x4f, 0xac, 0xfe, 0x95, 0xd1, +- 0xd8, 0xef, 0x45, 0xe3, 0x81, 0x99, 0x30, 0x06, 0x17, 0xab, 0x0d, 0x4a, +- 0xf4, 0xe3, 0x5e, 0x8e, 0xb3, 0x16, 0x73, 0xf7, 0x69, 0x98, 0xc7, 0xe3, +- 0x1f, 0x53, 0xf5, 0x93, 0x2f, 0x3b, 0xe0, 0x9d, 0x4d, 0xba, 0x33, 0x87, +- 0x4c, 0x80, 0xac, 0xd6, 0xeb, 0xc3, 0x95, 0xc7, 0x5f, 0x51, 0x15, 0xe4, +- 0x3e, 0x2e, 0x31, 0xaf, 0x31, 0xd8, 0xa7, 0xaa, 0xb2, 0x96, 0x44, 0x0c, +- 0xe7, 0xa1, 0x22, 0x42, 0x16, 0x51, 0xc7, 0xfc, 0xc2, 0xda, 0x68, 0x96, +- 0x61, 0x47, 0x13, 0x39, 0xa7, 0x57, 0x3f, 0x21, 0x31, 0x6a, 0x36, 0x63, +- 0x44, 0x79, 0x32, 0x7e, 0xe7, 0x6c, 0x78, 0x50, 0x96, 0xb4, 0xac, 0xaf, +- 0x86, 0x34, 0x78, 0x22, 0x81, 0xe8, 0x56, 0xa6, 0x91, 0x1f, 0x5f, 0x10, +- 0xc6, 0xea, 0xec, 0x09, 0x0c, 0x73, 0x7c, 0xab, 0xb2, 0xc5, 0x67, 0xc5, +- 0xfe, 0xf8, 0xe7, 0xf2, 0x33, 0x67, 0x57, 0x1e, 0x98, 0x0d, 0x43, 0xbb, +- 0x57, 0x1d, 0xae, 0x22, 0x07, 0x3f, 0xce, 0xb8, 0xa7, 0x4c, 0x7d, 0x42, +- 0x41, 0xc7, 0x70, 0x1c, 0x33, 0x42, 0x2f, 0x28, 0xb1, 0x5a, 0xdd, 0xef, +- 0x57, 0x6a, 0xf1, 0x89, 0x7d, 0xd4, 0xf5, 0xa2, 0x1f, 0x7a, 0xe4, 0xb9, +- 0xb0, 0x6f, 0x1e, 0x15, 0xdd, 0xd6, 0xa7, 0x87, 0x38, 0x8e, 0xc9, 0x86, +- 0x13, 0x82, 0x93, 0x8f, 0xba, 0xe1, 0x78, 0x74, 0x16, 0xa2, 0x68, 0x6a, +- 0xb8, 0xb2, 0xeb, 0x5f, 0x54, 0xd1, 0x8b, 0xf0, 0x6b, 0x7d, 0x30, 0xae, +- 0x18, 0xda, 0xcf, 0x95, 0x13, 0xf6, 0x7d, 0xb8, 0xaf, 0x66, 0x4f, 0x52, +- 0x97, 0xc7, 0x0b, 0xf9, 0xd2, 0x3a, 0x24, 0x06, 0x64, 0x5f, 0xfe, 0x59, +- 0xcc, 0x1d, 0xd6, 0xdb, 0x77, 0x29, 0x46, 0xf0, 0x06, 0xe5, 0x2c, 0xe6, +- 0x0c, 0x07, 0x39, 0x97, 0x1a, 0x56, 0x26, 0x8b, 0xf8, 0x29, 0x18, 0xbc, +- 0x8e, 0x18, 0x6c, 0x2d, 0xfb, 0x89, 0x19, 0xd7, 0x65, 0x4f, 0x82, 0x53, +- 0xd1, 0x3b, 0x1a, 0x94, 0x38, 0x63, 0xa8, 0x71, 0x71, 0x3d, 0xeb, 0x78, +- 0x86, 0x9b, 0x70, 0x3b, 0xc7, 0xdc, 0xc6, 0x79, 0xfb, 0xee, 0x62, 0x0b, +- 0x4b, 0x16, 0xeb, 0x07, 0xca, 0x1c, 0xd1, 0x7b, 0x6b, 0x90, 0xeb, 0x9a, +- 0x49, 0xbb, 0xb9, 0x7b, 0x91, 0x1e, 0x7e, 0x81, 0xb8, 0x4b, 0x9c, 0x46, +- 0x2f, 0xe3, 0xce, 0x46, 0xc6, 0xa2, 0xf2, 0x88, 0xde, 0xcf, 0x1c, 0xf5, +- 0xc2, 0x1d, 0x8e, 0x68, 0x48, 0x9e, 0xff, 0xf8, 0x32, 0x96, 0xc1, 0x1d, +- 0xaa, 0x22, 0x0e, 0xea, 0xb9, 0xef, 0x42, 0x3f, 0x70, 0x3b, 0xfa, 0xf1, +- 0x03, 0xf2, 0xbb, 0x99, 0x57, 0xe5, 0x88, 0x51, 0x19, 0x3c, 0x98, 0x3d, +- 0x89, 0x03, 0xd9, 0x47, 0xb1, 0x37, 0xbb, 0x5b, 0x49, 0xdb, 0xf7, 0x20, +- 0x15, 0x79, 0xee, 0x26, 0x5a, 0xa5, 0x7c, 0x06, 0x95, 0xa1, 0xaf, 0x5b, +- 0xe9, 0x1a, 0x15, 0xd5, 0xa1, 0x20, 0x56, 0x27, 0xe3, 0x70, 0x44, 0xde, +- 0xb6, 0xe4, 0xb9, 0xcf, 0x2d, 0x13, 0x06, 0xae, 0x4f, 0x96, 0x23, 0x76, +- 0xc8, 0xb2, 0xfa, 0x9b, 0x9d, 0xd8, 0x34, 0xd1, 0x84, 0x95, 0xc3, 0x0f, +- 0x59, 0xf3, 0x18, 0x73, 0xde, 0xbd, 0xc6, 0x83, 0x3b, 0x0e, 0x79, 0xb0, +- 0x3e, 0x19, 0x85, 0x2f, 0x52, 0xc1, 0xdf, 0x01, 0x73, 0x39, 0x8c, 0xc9, +- 0x49, 0x18, 0xfd, 0xd7, 0x39, 0x02, 0xc7, 0xc2, 0xaa, 0x07, 0x7f, 0x4d, +- 0x1c, 0x5f, 0x45, 0xdc, 0x89, 0x4d, 0x58, 0xa8, 0x8e, 0x78, 0x71, 0x27, +- 0xeb, 0x7f, 0x8c, 0x73, 0xff, 0xd6, 0x92, 0xe3, 0xc4, 0x02, 0x23, 0x36, +- 0xa1, 0x68, 0xd8, 0x3a, 0xe1, 0xa6, 0xae, 0xdc, 0x88, 0x1d, 0xa9, 0xc5, +- 0xf5, 0xfb, 0xfc, 0xb8, 0x63, 0xc2, 0x83, 0x96, 0xa4, 0xb5, 0xec, 0xb8, +- 0x19, 0x5f, 0xab, 0xc1, 0xc0, 0xfa, 0x09, 0x2f, 0x6e, 0x4b, 0xea, 0xbe, +- 0x1b, 0x98, 0xf3, 0x8f, 0x99, 0x41, 0xfc, 0xed, 0x84, 0x0f, 0xb7, 0x24, +- 0x4f, 0x49, 0x1e, 0xb9, 0xdc, 0xc9, 0xd8, 0x73, 0xff, 0x44, 0x1d, 0xd6, +- 0x26, 0xf5, 0x8b, 0x93, 0xe4, 0x76, 0xdd, 0x47, 0x4c, 0xdc, 0x3b, 0xa1, +- 0xa2, 0x83, 0xed, 0x7c, 0x22, 0x39, 0x17, 0x5d, 0x47, 0x9a, 0x29, 0xc3, +- 0x62, 0xac, 0x1a, 0x76, 0xc2, 0x24, 0x8b, 0xc7, 0x27, 0x81, 0x76, 0xfa, +- 0x47, 0x22, 0xf5, 0x45, 0xec, 0x19, 0x30, 0x71, 0xd7, 0x84, 0x9c, 0x9f, +- 0xb4, 0x9f, 0x95, 0xbb, 0x70, 0x70, 0x31, 0x6e, 0x1c, 0x56, 0x89, 0x03, +- 0xa5, 0x48, 0xaf, 0x55, 0x70, 0x1b, 0xaf, 0xef, 0x4a, 0xd9, 0x7b, 0xab, +- 0x11, 0x1a, 0x0a, 0x1c, 0xab, 0x21, 0x67, 0x58, 0x72, 0x30, 0x7f, 0xfd, +- 0x41, 0xe2, 0x7c, 0x19, 0x71, 0xbe, 0x82, 0x1c, 0xf6, 0xba, 0xd1, 0x93, +- 0x78, 0x80, 0xb8, 0x7c, 0x62, 0xb8, 0x9b, 0x71, 0xa7, 0x12, 0x5f, 0x63, +- 0x1c, 0x48, 0xf2, 0xfc, 0xec, 0x90, 0xd1, 0x55, 0x46, 0x9c, 0x7e, 0x81, +- 0xf8, 0xdb, 0x4f, 0xcc, 0xb8, 0x3b, 0x49, 0xb7, 0x1f, 0x62, 0x0e, 0x70, +- 0x55, 0x74, 0xa1, 0x87, 0x39, 0xd6, 0x0d, 0x4a, 0xc0, 0xf7, 0x1a, 0x2a, +- 0xe1, 0x38, 0x58, 0x8b, 0x96, 0x7d, 0x52, 0x46, 0xf0, 0x4b, 0x85, 0x7a, +- 0xd8, 0x49, 0x9d, 0x9f, 0x84, 0x35, 0xe8, 0xe0, 0x78, 0xeb, 0x4d, 0x32, +- 0x70, 0xfc, 0xd8, 0xd4, 0xb5, 0x7f, 0x22, 0xd6, 0xbe, 0x43, 0x4c, 0xf5, +- 0xcf, 0x6e, 0x46, 0xab, 0x61, 0xf2, 0x38, 0x89, 0x57, 0x06, 0x0d, 0xf3, +- 0x10, 0x9c, 0x78, 0x99, 0x3c, 0x6f, 0x6a, 0x36, 0x63, 0xa6, 0x21, 0x7e, +- 0x98, 0xe1, 0x78, 0x54, 0xc9, 0x4b, 0xe0, 0x18, 0x07, 0xde, 0x38, 0xb8, +- 0x8c, 0xe3, 0x92, 0x58, 0x2a, 0xf1, 0x2e, 0x43, 0x59, 0x97, 0x61, 0x0d, +- 0xf5, 0xd1, 0x9a, 0x54, 0x91, 0x39, 0x12, 0xc1, 0x5d, 0xfb, 0xf3, 0x71, +- 0x78, 0x5b, 0x28, 0x7e, 0x33, 0xe3, 0x70, 0xb8, 0x9c, 0x71, 0xd8, 0x15, +- 0x11, 0xd9, 0x9c, 0x18, 0x65, 0xdc, 0xde, 0x91, 0x0a, 0xa3, 0x8d, 0x73, +- 0x38, 0x99, 0x61, 0xbf, 0xc9, 0x3a, 0x9c, 0xc9, 0x78, 0x18, 0xb3, 0x34, +- 0x1e, 0x44, 0xb5, 0xb1, 0x59, 0x3c, 0xfc, 0x3c, 0xe6, 0xf3, 0x30, 0xec, +- 0x6b, 0x1b, 0x93, 0x0a, 0xe2, 0xed, 0x8a, 0xcd, 0xe7, 0xcf, 0x64, 0x04, +- 0x9b, 0x65, 0x2d, 0x73, 0x7b, 0x95, 0x3c, 0x8b, 0x32, 0x98, 0xfa, 0x1e, +- 0xaa, 0xa9, 0xff, 0xaa, 0x02, 0x0e, 0xfd, 0x34, 0x24, 0xb8, 0x5b, 0x4f, +- 0xdc, 0x95, 0xe7, 0x04, 0x2c, 0x6b, 0x5d, 0x60, 0x3a, 0x1e, 0xfd, 0x9f, +- 0x77, 0xa3, 0xf6, 0x33, 0x17, 0x82, 0x49, 0xc4, 0xbf, 0x14, 0xf1, 0x8f, +- 0x63, 0xe8, 0xb9, 0x96, 0x18, 0x48, 0x99, 0xfe, 0x21, 0x45, 0x0c, 0x24, +- 0x4e, 0x3f, 0x4a, 0x9c, 0xfe, 0x06, 0x71, 0xfa, 0xeb, 0xc4, 0xe9, 0xaf, +- 0x11, 0x13, 0xf2, 0x6b, 0x7a, 0x6d, 0x72, 0xff, 0x85, 0xf3, 0xf1, 0x96, +- 0xbd, 0xb6, 0x38, 0x93, 0xba, 0x9a, 0x3b, 0xac, 0x60, 0x9e, 0xa1, 0x1f, +- 0x13, 0xbb, 0xff, 0x01, 0xe7, 0xc9, 0x3f, 0xa3, 0xce, 0x7e, 0x26, 0xa6, +- 0x35, 0xd9, 0x07, 0x77, 0xb2, 0x51, 0xeb, 0x87, 0xfd, 0x2c, 0xb2, 0x29, +- 0x5c, 0xb4, 0x24, 0xb9, 0x11, 0x8e, 0x64, 0xe3, 0xb1, 0xd3, 0x72, 0x9f, +- 0x77, 0x96, 0xe4, 0xf5, 0x1b, 0xe1, 0x4c, 0xea, 0xc7, 0xe2, 0x94, 0x65, +- 0x25, 0xff, 0x73, 0x25, 0x1b, 0xcd, 0xd7, 0x60, 0x63, 0x9b, 0x7f, 0xca, +- 0xfe, 0xaf, 0xfe, 0xc2, 0x03, 0xd4, 0x57, 0x8e, 0x6d, 0x66, 0xa8, 0xfb, +- 0x72, 0xf2, 0x95, 0x47, 0xb2, 0xf2, 0xbb, 0xb1, 0x23, 0xa1, 0x1e, 0x43, +- 0x6c, 0xa6, 0xf0, 0xf1, 0x30, 0x6e, 0x4a, 0x7a, 0x68, 0x07, 0x71, 0x54, +- 0xd1, 0xb7, 0x3e, 0x37, 0xd1, 0x4c, 0x5f, 0x7b, 0xc8, 0xd2, 0x22, 0x81, +- 0x8e, 0x09, 0x72, 0x9e, 0x2d, 0x13, 0xcb, 0xb0, 0x62, 0xd8, 0xb2, 0x3c, +- 0x4b, 0x8d, 0xf0, 0x56, 0xc5, 0x0f, 0x17, 0x7d, 0xd0, 0x41, 0xbf, 0xda, +- 0x7c, 0x28, 0xa0, 0xbd, 0x46, 0x3c, 0xed, 0x6c, 0x3e, 0x41, 0xfb, 0x30, +- 0x2e, 0xb6, 0x11, 0x4b, 0x9d, 0x91, 0x00, 0xf3, 0x44, 0x0f, 0x6d, 0xdf, +- 0x8b, 0x8b, 0x09, 0xf1, 0x2f, 0xbd, 0xeb, 0x9f, 0x98, 0x9b, 0x74, 0xd1, +- 0x37, 0x7e, 0x9e, 0xa8, 0xa3, 0x0f, 0xb8, 0xf1, 0x46, 0xc2, 0xa0, 0xbf, +- 0x79, 0xf0, 0x56, 0xa2, 0x89, 0x7d, 0x05, 0x59, 0xc6, 0x8f, 0x7b, 0x26, +- 0xc2, 0xf4, 0xb3, 0x6b, 0x79, 0xc8, 0x73, 0x99, 0xf5, 0xf1, 0x6f, 0x2a, +- 0xf5, 0x83, 0x73, 0xd5, 0x1a, 0x44, 0x6b, 0x35, 0x7c, 0x7e, 0xe2, 0x23, +- 0xf8, 0x57, 0xc6, 0xed, 0x4d, 0x49, 0x70, 0x0e, 0x11, 0x22, 0x0f, 0x9c, +- 0x3c, 0x22, 0xf7, 0x1c, 0xd1, 0x18, 0x6d, 0x70, 0xe8, 0xcc, 0x6d, 0xf5, +- 0xdc, 0x79, 0x87, 0x93, 0x7d, 0x92, 0x15, 0xb3, 0xec, 0xcf, 0x07, 0xcb, +- 0x71, 0xef, 0xa1, 0x13, 0xf4, 0x91, 0x12, 0x2c, 0x7a, 0xc0, 0x8d, 0xcf, +- 0x1f, 0xc9, 0x90, 0x3b, 0xa8, 0x90, 0xfd, 0xbc, 0x69, 0x12, 0x85, 0x39, +- 0xa3, 0x11, 0xdc, 0xb9, 0x3f, 0x83, 0xe1, 0x02, 0xcf, 0x0b, 0x85, 0xe2, +- 0xff, 0x43, 0xc5, 0x09, 0xf2, 0x88, 0x40, 0xe7, 0xd5, 0xb4, 0xb1, 0xaa, +- 0x48, 0x20, 0x2e, 0xe3, 0x6e, 0xa7, 0x8d, 0xf5, 0x71, 0x3e, 0x33, 0x1c, +- 0x47, 0x82, 0x36, 0xf6, 0x55, 0xca, 0xbf, 0x87, 0x36, 0x16, 0xa7, 0x8d, +- 0xc5, 0x69, 0x4f, 0x71, 0xda, 0x98, 0x3c, 0xfb, 0x1b, 0xa7, 0x8d, 0xc5, +- 0x69, 0x63, 0xf1, 0xcc, 0x32, 0x1c, 0x25, 0xd3, 0xd8, 0x39, 0xd6, 0x4c, +- 0x1c, 0x53, 0xec, 0xa8, 0x94, 0xbb, 0xf9, 0x23, 0xe4, 0xec, 0xd7, 0xf1, +- 0x50, 0xd0, 0x46, 0x9f, 0xec, 0x4f, 0x67, 0xc8, 0x79, 0xdc, 0xf8, 0x75, +- 0x56, 0x38, 0x7e, 0x33, 0xf3, 0xd8, 0x93, 0xe4, 0xf9, 0x2a, 0x9e, 0x30, +- 0x25, 0x0f, 0x36, 0x79, 0xce, 0x58, 0x93, 0x12, 0xbe, 0x76, 0x12, 0x77, +- 0x0f, 0x02, 0x37, 0x90, 0x17, 0xd6, 0x92, 0x97, 0x1c, 0x5e, 0xc4, 0xdf, +- 0x07, 0x4f, 0xd0, 0xe6, 0x4f, 0xda, 0x7b, 0xbb, 0x54, 0xb6, 0x75, 0x66, +- 0xb0, 0xde, 0x77, 0x3d, 0x7d, 0xf0, 0x7e, 0xd6, 0x75, 0x1e, 0x94, 0x3a, +- 0x27, 0xd8, 0xb6, 0x1e, 0xfe, 0x35, 0xe7, 0xbf, 0xe3, 0x81, 0x5a, 0xbc, +- 0xb1, 0x5f, 0x0f, 0xbf, 0x43, 0xcc, 0xab, 0x75, 0x58, 0xcb, 0xae, 0x0e, +- 0x05, 0xb6, 0x5d, 0xad, 0xe6, 0xf9, 0x5e, 0xfb, 0x90, 0x13, 0xc7, 0x42, +- 0xcb, 0xe0, 0x59, 0x54, 0xe4, 0x7c, 0xb4, 0xa5, 0x5a, 0xe1, 0x58, 0x7a, +- 0xf8, 0x3c, 0xb9, 0x4a, 0x92, 0xed, 0x1f, 0xcd, 0x3c, 0x4e, 0x0c, 0xf9, +- 0x22, 0x9e, 0x63, 0x7e, 0x3e, 0xf6, 0xa1, 0x97, 0xc9, 0x1d, 0xdd, 0x18, +- 0x27, 0x07, 0x3c, 0x3e, 0x18, 0xfd, 0xa8, 0x93, 0xb8, 0xef, 0x59, 0x54, +- 0x89, 0x4c, 0x5a, 0xb8, 0x62, 0x25, 0x9e, 0x19, 0x34, 0xb4, 0x1b, 0x94, +- 0x3c, 0x2f, 0xcc, 0xef, 0xfd, 0x32, 0x2e, 0x8e, 0x22, 0x30, 0x79, 0x9e, +- 0xdc, 0xf0, 0x9d, 0xb4, 0xc4, 0xb0, 0x93, 0xf4, 0x71, 0x3f, 0xc2, 0x49, +- 0x0d, 0x27, 0xc6, 0x0d, 0x2c, 0x4c, 0x7a, 0xf1, 0xf0, 0x78, 0x10, 0x57, +- 0xd3, 0x77, 0xb3, 0xe4, 0x87, 0x1f, 0x4a, 0x8a, 0x2f, 0xd6, 0x61, 0x62, +- 0xbc, 0x8e, 0x3e, 0x22, 0xbc, 0xfc, 0x67, 0xf0, 0xd4, 0x9e, 0xb5, 0xf7, +- 0x36, 0x8f, 0xa6, 0xf4, 0xfe, 0x18, 0xc7, 0x13, 0xf3, 0xea, 0xc7, 0x62, +- 0xd0, 0xd3, 0xc0, 0x87, 0xdf, 0x4d, 0x7f, 0x52, 0xe2, 0xa3, 0xf8, 0xa3, +- 0x86, 0x09, 0xf2, 0x9d, 0x52, 0x62, 0x6a, 0x79, 0xa4, 0xfe, 0xc2, 0xf7, +- 0x15, 0x3d, 0xf7, 0x94, 0x6a, 0x59, 0xdf, 0x5b, 0xac, 0xc1, 0x77, 0x44, +- 0x23, 0xf7, 0x30, 0xed, 0xe7, 0x62, 0xe4, 0x79, 0xf3, 0xd9, 0xfb, 0x6a, +- 0x31, 0x63, 0x5f, 0x12, 0xff, 0xad, 0x36, 0xfe, 0xd1, 0x59, 0x8c, 0xf3, +- 0xb3, 0x64, 0x7f, 0x76, 0xf2, 0xf4, 0x6c, 0xb9, 0x57, 0x34, 0xa9, 0x36, +- 0x76, 0x1c, 0x83, 0x7e, 0xec, 0x15, 0x45, 0xf7, 0x7d, 0x95, 0xb1, 0xc1, +- 0x45, 0x1b, 0x75, 0x4c, 0x68, 0xf4, 0xdd, 0xc6, 0x13, 0x33, 0x60, 0xc4, +- 0xaf, 0x51, 0x5d, 0x16, 0x6c, 0x79, 0x6e, 0xa8, 0xca, 0xe7, 0x45, 0x82, +- 0x3b, 0x12, 0x17, 0xc8, 0x17, 0x89, 0xc1, 0x9d, 0xf4, 0x97, 0x35, 0x76, +- 0x2c, 0x3a, 0x61, 0xef, 0xfd, 0xde, 0x3a, 0x11, 0xa7, 0x8f, 0x2c, 0x43, +- 0xc5, 0xb0, 0x07, 0x9f, 0xb3, 0xe3, 0xd0, 0x43, 0x56, 0x0d, 0xfd, 0xe5, +- 0xae, 0x43, 0x81, 0xce, 0xeb, 0xe9, 0x2f, 0xf5, 0x4b, 0x25, 0x86, 0x31, +- 0x6e, 0xa7, 0x0c, 0x73, 0x94, 0xd8, 0xf2, 0x50, 0xb3, 0x31, 0xf9, 0x32, +- 0xf2, 0x3e, 0xb3, 0x6b, 0xa0, 0x16, 0x7f, 0xff, 0xc0, 0x71, 0x7b, 0x2d, +- 0xe4, 0x4e, 0x9e, 0x27, 0x07, 0x7c, 0xb6, 0x7f, 0xc4, 0xf8, 0xfb, 0x1e, +- 0xc6, 0xbc, 0x18, 0xfd, 0x68, 0xe7, 0x80, 0xb5, 0xec, 0xf9, 0xc5, 0xf1, +- 0xb5, 0x55, 0x08, 0x32, 0x26, 0xb9, 0xd1, 0x3f, 0xa0, 0x0f, 0x76, 0x30, +- 0x06, 0x9d, 0x5d, 0x6c, 0x52, 0x16, 0x0f, 0x86, 0x06, 0x04, 0x53, 0x4f, +- 0xdd, 0x52, 0x8b, 0xf8, 0xff, 0xd0, 0x38, 0xbe, 0xcf, 0xd9, 0xf7, 0x08, +- 0xeb, 0xb0, 0xe9, 0xc8, 0x52, 0xca, 0xdc, 0x44, 0x1f, 0x64, 0x5e, 0xcd, +- 0x7c, 0x67, 0xc3, 0x7e, 0xf1, 0x0b, 0xb4, 0x48, 0x9e, 0xd6, 0x6d, 0x06, +- 0xcc, 0x57, 0xe9, 0x43, 0x25, 0xe4, 0x3a, 0x0f, 0xa6, 0xec, 0xe7, 0x73, +- 0x72, 0x15, 0x46, 0x18, 0x8b, 0x69, 0xa3, 0x25, 0x86, 0x0f, 0x33, 0xc8, +- 0xeb, 0x16, 0x72, 0x3e, 0xca, 0xb2, 0x1e, 0x80, 0x1c, 0x02, 0xc4, 0x27, +- 0x1c, 0x25, 0x08, 0x1e, 0xf5, 0xf3, 0x98, 0xcf, 0x83, 0x8a, 0xc8, 0xaa, +- 0x98, 0x79, 0x94, 0x75, 0x47, 0x33, 0xb6, 0x2d, 0xfe, 0x3d, 0xe7, 0x3d, +- 0x41, 0x5b, 0xff, 0x04, 0xb1, 0x7e, 0x72, 0x2f, 0xd0, 0x7f, 0x30, 0x6f, +- 0xdb, 0x29, 0xb6, 0xdf, 0x4e, 0xcc, 0xbb, 0x40, 0x9b, 0xed, 0xe3, 0x7c, +- 0x0f, 0x8d, 0x18, 0xc1, 0x46, 0x35, 0xa0, 0x4d, 0x70, 0x9e, 0x7b, 0xc6, +- 0x54, 0x0c, 0x0c, 0x2e, 0xc3, 0x28, 0xf3, 0xa0, 0xde, 0xb4, 0xf8, 0x88, +- 0x94, 0x39, 0x89, 0x6e, 0xfa, 0xc8, 0x2f, 0x17, 0x2b, 0x88, 0x7d, 0x5c, +- 0xf6, 0xbe, 0x3b, 0x99, 0xef, 0x7f, 0x11, 0x9b, 0x12, 0x8f, 0x5b, 0x95, +- 0x86, 0xde, 0x9f, 0x56, 0x99, 0x67, 0xd1, 0x36, 0x7b, 0x98, 0x9f, 0x2c, +- 0x67, 0x7e, 0xd2, 0x5b, 0xb0, 0xcb, 0x33, 0xb4, 0xc3, 0x01, 0xc6, 0xb1, +- 0x97, 0xd3, 0xf9, 0xb8, 0xf7, 0x83, 0x21, 0x3f, 0x16, 0x5e, 0x53, 0x89, +- 0xa7, 0x0f, 0xe6, 0x65, 0xdb, 0x4b, 0x9b, 0x7c, 0x8a, 0x7a, 0xbe, 0x83, +- 0x7a, 0x7d, 0x29, 0x25, 0x18, 0x15, 0xc4, 0x33, 0xe4, 0xd1, 0x5b, 0xc8, +- 0x05, 0xbe, 0x97, 0xca, 0xdb, 0xe4, 0xe7, 0x27, 0xd6, 0x68, 0xf9, 0xf8, +- 0xe0, 0x85, 0xba, 0x4f, 0xf6, 0x00, 0x5a, 0xd6, 0x72, 0x33, 0xd7, 0x49, +- 0x5e, 0xc3, 0xb6, 0x23, 0xe4, 0x46, 0x4e, 0xcc, 0x49, 0x46, 0xb0, 0x22, +- 0x55, 0xdf, 0xd6, 0x20, 0x9b, 0x3d, 0xe6, 0xe4, 0x39, 0xa0, 0x2b, 0x29, +- 0xef, 0x0e, 0xd0, 0x50, 0xc1, 0xdc, 0xe9, 0xaf, 0x0b, 0xef, 0x2b, 0xf8, +- 0xc4, 0x9f, 0xc1, 0x1d, 0xd7, 0x50, 0xa6, 0x14, 0xb9, 0xe3, 0x54, 0xe1, +- 0x7d, 0x05, 0x37, 0xdb, 0xef, 0x2b, 0x70, 0x63, 0xc6, 0x84, 0xd3, 0xf9, +- 0xa9, 0x94, 0x07, 0xb3, 0x27, 0x2e, 0x71, 0x50, 0x77, 0x49, 0xa4, 0x15, +- 0x4f, 0x26, 0x14, 0xcc, 0x32, 0xfe, 0x27, 0xbe, 0x6f, 0xaf, 0x09, 0xd4, +- 0xda, 0x7b, 0xf6, 0x5d, 0x91, 0x28, 0x0e, 0x27, 0xf4, 0xb6, 0xc7, 0x78, +- 0x5e, 0x46, 0x3c, 0xad, 0xda, 0xa7, 0xe0, 0xa9, 0x80, 0x17, 0xa5, 0x47, +- 0x64, 0xaf, 0xbb, 0x65, 0x39, 0x17, 0xaf, 0xb2, 0x76, 0xac, 0x13, 0xfb, +- 0xe6, 0x1c, 0x1e, 0x09, 0x54, 0x09, 0x06, 0x1e, 0x36, 0x65, 0xdd, 0xd2, +- 0x40, 0x5f, 0xa2, 0x96, 0xfc, 0xba, 0xbe, 0xb3, 0x15, 0xf5, 0xe6, 0xcf, +- 0x1c, 0xb5, 0x28, 0x39, 0x72, 0x87, 0x26, 0x6b, 0xf6, 0xdf, 0xe0, 0x9c, +- 0xf5, 0x12, 0xbb, 0x7a, 0x52, 0xf9, 0xf8, 0xd9, 0x9a, 0xb1, 0xaa, 0x45, +- 0x2f, 0xbd, 0xe4, 0x27, 0x6a, 0xf2, 0xa2, 0x5d, 0xa6, 0x22, 0x92, 0x23, +- 0xfe, 0xd4, 0xe1, 0x04, 0xf9, 0x82, 0xc4, 0xd2, 0x0a, 0x1e, 0x95, 0xe4, +- 0x8d, 0x3f, 0x67, 0x2c, 0xbd, 0x27, 0x94, 0x0b, 0xca, 0x9b, 0x2c, 0x6a, +- 0xc8, 0xc5, 0xe9, 0x03, 0x38, 0x12, 0xd2, 0xdb, 0x37, 0x38, 0xa2, 0x4f, +- 0x33, 0x07, 0x0b, 0x2f, 0x63, 0x4e, 0xbe, 0x2a, 0x90, 0xc1, 0x2e, 0xf2, +- 0xc0, 0x9d, 0xcc, 0xc5, 0x3b, 0x68, 0x9b, 0x9d, 0xfb, 0x19, 0xdb, 0x1c, +- 0x97, 0x73, 0x71, 0x2d, 0x14, 0xdf, 0x40, 0x0e, 0xd0, 0xe5, 0x51, 0xc5, +- 0x5e, 0xc5, 0x77, 0x02, 0x1d, 0xaf, 0x12, 0xa3, 0x1b, 0x19, 0x37, 0xc4, +- 0xde, 0xf7, 0xa4, 0xf4, 0x4e, 0x2a, 0xa0, 0xa6, 0x92, 0xb9, 0xe3, 0xbd, +- 0xe3, 0xcd, 0xf4, 0x9b, 0xfc, 0x33, 0x73, 0xce, 0x25, 0x75, 0xcc, 0x39, +- 0xaf, 0x43, 0xef, 0x10, 0xed, 0x9f, 0xbe, 0x74, 0xff, 0x00, 0xc8, 0xcf, +- 0xd4, 0x9d, 0x9c, 0xbf, 0xdc, 0x11, 0x04, 0x2e, 0xb6, 0xa3, 0xb1, 0xad, +- 0xc4, 0x21, 0x32, 0xe8, 0xed, 0x6f, 0x90, 0xa7, 0x75, 0x31, 0x3f, 0xdd, +- 0xc2, 0x5c, 0x3e, 0xc6, 0x5c, 0x3e, 0xc6, 0x7a, 0xa9, 0x21, 0xb9, 0x4f, +- 0x64, 0xb4, 0x9f, 0x61, 0xfe, 0xf3, 0x39, 0xf2, 0x9f, 0xa1, 0x07, 0x44, +- 0xae, 0x59, 0xb8, 0xf7, 0xf0, 0x75, 0x48, 0xd2, 0x9e, 0xee, 0xe1, 0xb5, +- 0x81, 0x07, 0xe6, 0xe3, 0x6e, 0xe6, 0xf1, 0xb1, 0xf1, 0x65, 0x18, 0x64, +- 0x26, 0xba, 0xed, 0xf0, 0x47, 0xd0, 0x43, 0x3e, 0xb5, 0x9c, 0x18, 0xbd, +- 0xe1, 0x60, 0xc6, 0xc6, 0x6c, 0xc1, 0xfc, 0x1f, 0x67, 0x80, 0xd7, 0xc8, +- 0xc9, 0x06, 0x53, 0x27, 0x6c, 0x9e, 0xe6, 0x62, 0x7c, 0x28, 0x25, 0x2e, +- 0x85, 0xf7, 0x1b, 0x5d, 0x2b, 0x55, 0x6b, 0x59, 0xd9, 0xe2, 0x40, 0xff, +- 0x1b, 0xf4, 0xd5, 0x9a, 0x23, 0x2a, 0x6a, 0x87, 0x25, 0x57, 0x27, 0x3f, +- 0x22, 0x46, 0x3f, 0x47, 0x8c, 0xae, 0x3c, 0x94, 0xcf, 0xcb, 0x13, 0xcc, +- 0xbb, 0x6a, 0x8d, 0x7c, 0x6e, 0xbe, 0x67, 0x40, 0xf6, 0xe8, 0xb8, 0xf1, +- 0x1d, 0xda, 0xfe, 0xa9, 0x82, 0xed, 0x9f, 0x2e, 0x60, 0xb0, 0xc5, 0xdc, +- 0xfc, 0x35, 0x1b, 0x7f, 0xf3, 0xb9, 0xf9, 0xc2, 0x61, 0xa3, 0x2b, 0x4c, +- 0x8c, 0xbe, 0xfa, 0x90, 0xf4, 0xaf, 0xa1, 0x96, 0x78, 0x32, 0x93, 0x58, +- 0x52, 0x35, 0x2c, 0xeb, 0x33, 0x81, 0xce, 0x09, 0xd5, 0x67, 0xf7, 0xb1, +- 0x9d, 0xb2, 0xf5, 0xd2, 0x07, 0xbe, 0x9a, 0x30, 0xb4, 0xad, 0x4a, 0xc0, +- 0x5c, 0x4d, 0x7d, 0x1e, 0xc9, 0x5c, 0x87, 0xce, 0xc1, 0x3a, 0x1c, 0x4b, +- 0x4b, 0x7c, 0x91, 0xf6, 0x25, 0x17, 0x77, 0xe2, 0x9d, 0xfd, 0x73, 0xf1, +- 0xce, 0xd8, 0xe5, 0x3c, 0x7c, 0x47, 0x2a, 0x7a, 0x3f, 0xc3, 0xeb, 0x2a, +- 0xc9, 0xc3, 0xbf, 0xc7, 0x3c, 0xfc, 0x0d, 0x45, 0xd6, 0x10, 0x55, 0x7c, +- 0x62, 0x91, 0x83, 0xf1, 0x45, 0xf7, 0x7f, 0xd7, 0x11, 0x97, 0xfb, 0xc8, +- 0xfe, 0x07, 0xf8, 0xff, 0xb3, 0x8c, 0xe7, 0xc3, 0x9c, 0x89, 0x68, 0xad, +- 0x03, 0x4f, 0x2f, 0x8e, 0x47, 0x65, 0x9d, 0xb4, 0x9f, 0x3c, 0x65, 0x0e, +- 0xe3, 0xe1, 0xdf, 0xa7, 0xea, 0xc3, 0x0b, 0x1d, 0x0e, 0x5c, 0x34, 0xf5, +- 0xf6, 0x03, 0xbc, 0xf6, 0x4c, 0x56, 0x7c, 0x31, 0x4c, 0xfc, 0x5a, 0x59, +- 0xf0, 0xc5, 0x5a, 0x94, 0xd3, 0xce, 0xe7, 0xd2, 0x5e, 0x7f, 0x9c, 0xd2, +- 0x07, 0x9f, 0xa1, 0x9d, 0xd6, 0x5e, 0xb2, 0x53, 0x59, 0xa3, 0x95, 0xbc, +- 0xa6, 0x9d, 0x79, 0xcd, 0xf4, 0xe7, 0xa5, 0x8f, 0xa3, 0x2f, 0x7b, 0x1f, +- 0xee, 0xdd, 0xab, 0x77, 0x39, 0x1d, 0x71, 0x4b, 0x33, 0xba, 0x99, 0xa3, +- 0x75, 0x23, 0xb0, 0xc8, 0xe8, 0xb8, 0xa0, 0xe8, 0x9d, 0x3f, 0x54, 0xca, +- 0x99, 0xf3, 0x9d, 0xc1, 0xf6, 0x51, 0x3d, 0x98, 0x51, 0x0c, 0xdc, 0x40, +- 0x8c, 0x7b, 0x78, 0xa4, 0x84, 0x76, 0xb8, 0x1e, 0x47, 0x06, 0xf5, 0x70, +- 0x1c, 0x26, 0x31, 0xb4, 0xde, 0x5f, 0xa6, 0x5c, 0xc0, 0x69, 0xf3, 0x2c, +- 0xb6, 0x67, 0xe7, 0x60, 0xbd, 0x26, 0x7b, 0x9a, 0xd6, 0x63, 0x62, 0xf0, +- 0x02, 0x71, 0xa8, 0x9d, 0xdc, 0x4a, 0xf2, 0x06, 0x0b, 0x7b, 0x42, 0x57, +- 0x63, 0x8b, 0xed, 0xbf, 0xa5, 0xf2, 0x4e, 0x0b, 0xcf, 0x3c, 0xc3, 0x20, +- 0x4e, 0x48, 0x6e, 0xee, 0x9b, 0xb6, 0x3f, 0x57, 0xd6, 0x75, 0x1b, 0xab, +- 0xf2, 0xf7, 0x95, 0xff, 0x58, 0x99, 0x29, 0x1c, 0x1a, 0x91, 0xf5, 0x85, +- 0x19, 0xca, 0xe3, 0x83, 0x0d, 0xbe, 0x1e, 0xc6, 0x8f, 0xfb, 0xcd, 0x1c, +- 0x5e, 0x5f, 0x5c, 0x86, 0x29, 0xaf, 0x82, 0xd0, 0xd5, 0x61, 0xe9, 0x83, +- 0x9f, 0x73, 0x96, 0xff, 0x93, 0xd2, 0xce, 0x82, 0xc2, 0x9a, 0xc3, 0x3b, +- 0x35, 0x8c, 0x55, 0x3c, 0x97, 0xe7, 0x03, 0xe5, 0xbc, 0x78, 0xfd, 0x47, +- 0x56, 0xd4, 0x2b, 0xd7, 0x89, 0xd9, 0xb3, 0xc4, 0x7f, 0x67, 0x28, 0x77, +- 0x12, 0x6f, 0xe7, 0x87, 0x66, 0x28, 0xeb, 0xd3, 0xc5, 0x3a, 0x2f, 0x22, +- 0x3b, 0xf2, 0x22, 0xe7, 0x53, 0x0f, 0x4e, 0xc1, 0x55, 0x78, 0x56, 0x5e, +- 0xf6, 0x81, 0xb9, 0xc8, 0x43, 0x65, 0x2d, 0xfe, 0x1c, 0x86, 0xf6, 0x0b, +- 0x6f, 0xb4, 0xac, 0x40, 0xc3, 0x39, 0x6c, 0x3f, 0x7a, 0x42, 0xe9, 0x48, +- 0xbd, 0x6b, 0xa1, 0x74, 0x46, 0x6c, 0x8e, 0xbd, 0xdf, 0x59, 0xda, 0xe8, +- 0x53, 0xda, 0xb3, 0x81, 0xf0, 0xfd, 0x0c, 0xbe, 0x5a, 0x44, 0x9e, 0x63, +- 0x97, 0xb1, 0x9d, 0xe0, 0x35, 0xc3, 0x7e, 0x66, 0xe8, 0xb8, 0x3d, 0xce, +- 0xf7, 0xeb, 0xe1, 0x9b, 0x56, 0xb4, 0x5d, 0xea, 0x16, 0xe5, 0x9a, 0xcf, +- 0x89, 0x16, 0xd9, 0x8a, 0xff, 0x8f, 0x17, 0x64, 0x2f, 0x25, 0x77, 0xce, +- 0x97, 0xe9, 0xa4, 0xec, 0x25, 0xa1, 0x28, 0x4e, 0x35, 0x4f, 0x97, 0xbf, +- 0x38, 0xd6, 0x83, 0xef, 0x69, 0x2f, 0x5f, 0xf6, 0xe3, 0xb5, 0xb2, 0x4f, +- 0xea, 0x54, 0xf3, 0x24, 0xfe, 0xce, 0x5e, 0xd7, 0x78, 0xd3, 0xde, 0xdf, +- 0xb9, 0xcb, 0x6c, 0x89, 0x96, 0xe1, 0xa3, 0x50, 0xaf, 0x8a, 0x2f, 0x2c, +- 0xb3, 0xf9, 0x76, 0xb4, 0xbd, 0x8c, 0x39, 0xb7, 0xdb, 0x88, 0xde, 0xef, +- 0x46, 0x2e, 0x47, 0x9e, 0xd0, 0x71, 0x51, 0x39, 0xa6, 0xdc, 0x11, 0xd0, +- 0xb7, 0xbd, 0x4d, 0xfe, 0xf3, 0x6c, 0x20, 0xce, 0x39, 0x37, 0x7c, 0x03, +- 0x8a, 0x6e, 0x6e, 0x62, 0x8c, 0x7d, 0x86, 0x39, 0xed, 0xc6, 0x40, 0xbf, +- 0x7d, 0xcf, 0x53, 0x89, 0xac, 0xc1, 0x95, 0xf6, 0xfb, 0x26, 0xda, 0x61, +- 0x64, 0x5e, 0x94, 0x35, 0x38, 0xfe, 0x8e, 0x61, 0xa1, 0x7d, 0x6d, 0x23, +- 0x82, 0xf6, 0xf7, 0xba, 0xc2, 0x3b, 0x29, 0x3a, 0x50, 0x6f, 0x7f, 0x7f, +- 0x1a, 0x0d, 0x99, 0x4b, 0x6b, 0xd5, 0xe8, 0x35, 0x2d, 0xeb, 0x49, 0x53, +- 0x9e, 0x57, 0xbb, 0xb4, 0xb7, 0x7c, 0x8d, 0x83, 0x39, 0x10, 0x21, 0x25, +- 0x96, 0x7f, 0x27, 0xcf, 0xe5, 0xe7, 0xc5, 0x56, 0xbc, 0x67, 0x6f, 0xb9, +- 0xfd, 0xac, 0x93, 0xfd, 0xce, 0xa5, 0x05, 0x4b, 0x9c, 0xf8, 0x4e, 0xa2, +- 0x2a, 0xe6, 0xe1, 0xef, 0xed, 0x4b, 0x4a, 0xb0, 0x25, 0x44, 0x0e, 0x7a, +- 0xd5, 0x19, 0x9c, 0xcf, 0x38, 0x71, 0x26, 0x11, 0x0f, 0x8d, 0xb1, 0xbf, +- 0x53, 0x09, 0x15, 0xa7, 0x47, 0xfa, 0x42, 0x87, 0xec, 0xbe, 0x5f, 0x45, +- 0xef, 0x51, 0xb9, 0x0f, 0xd9, 0x8e, 0x0d, 0x89, 0xf3, 0x8c, 0xbb, 0xd2, +- 0x96, 0xac, 0x05, 0xe8, 0xb9, 0x8d, 0xcc, 0x9f, 0x55, 0x47, 0x10, 0xb7, +- 0x30, 0xde, 0x3d, 0x97, 0xe8, 0x86, 0x6b, 0xb1, 0xde, 0xf5, 0x2d, 0x72, +- 0x96, 0xaa, 0x88, 0x1e, 0x7c, 0x4b, 0xe9, 0x20, 0x37, 0x74, 0x63, 0x32, +- 0x21, 0x7e, 0x21, 0xef, 0xac, 0xf9, 0x34, 0x8e, 0x91, 0x23, 0x3f, 0x9b, +- 0xd0, 0x70, 0xbe, 0xd9, 0x83, 0x0c, 0x39, 0xf3, 0x77, 0x12, 0x6e, 0x7c, +- 0x95, 0x9c, 0xf9, 0x91, 0x11, 0x59, 0xb3, 0x6c, 0x45, 0x4b, 0x42, 0xd6, +- 0xab, 0xc9, 0x03, 0xc7, 0xbc, 0xb4, 0x6d, 0xcb, 0xea, 0x35, 0x67, 0xd3, +- 0x9f, 0xce, 0xb2, 0x4f, 0x59, 0xe7, 0x8c, 0x62, 0x35, 0x79, 0xd0, 0x23, +- 0x63, 0x3e, 0x3c, 0xcf, 0x5c, 0x21, 0xc9, 0x7a, 0xcf, 0x25, 0xfc, 0x18, +- 0xc8, 0xf8, 0xf0, 0x14, 0x73, 0x86, 0x9d, 0x3c, 0x97, 0xf7, 0x1f, 0x95, +- 0x18, 0x41, 0xf2, 0xf2, 0x93, 0xa8, 0x18, 0xb8, 0x02, 0x9b, 0xd7, 0x3e, +- 0x0a, 0x75, 0xe0, 0x04, 0x8f, 0x6b, 0xc9, 0x21, 0xae, 0x45, 0x6a, 0x24, +- 0x82, 0xd4, 0xd8, 0x8b, 0xe8, 0x1f, 0x91, 0x71, 0xc9, 0x7b, 0x6c, 0x64, +- 0x0f, 0x12, 0xb9, 0xe7, 0x80, 0x17, 0xe9, 0x31, 0xe9, 0xa7, 0x96, 0x7d, +- 0xff, 0xb9, 0xed, 0xff, 0xab, 0xb5, 0xf9, 0x13, 0xd2, 0xf6, 0xa3, 0x7f, +- 0xa4, 0x7d, 0xd1, 0x95, 0xac, 0xbd, 0xb4, 0x17, 0xd6, 0x5e, 0xdc, 0x6c, +- 0xd3, 0x03, 0x47, 0x24, 0xb7, 0xb6, 0x12, 0x7a, 0x74, 0xb7, 0x62, 0xb4, +- 0x55, 0x28, 0xe7, 0xb1, 0x3b, 0x2b, 0xef, 0x45, 0x28, 0xc5, 0x53, 0xc4, +- 0x6b, 0x57, 0x48, 0xd7, 0xbe, 0x45, 0xdb, 0x59, 0x4e, 0x8c, 0x7b, 0xd5, +- 0xbc, 0x1a, 0x71, 0x4d, 0xf4, 0x57, 0x8a, 0x17, 0x06, 0xdd, 0xc4, 0xa6, +- 0x08, 0xf2, 0xcf, 0xc8, 0x79, 0xf0, 0x83, 0x84, 0x97, 0xf3, 0xd5, 0x98, +- 0x33, 0x1c, 0x0d, 0xf2, 0x0c, 0x9e, 0x7d, 0xed, 0x54, 0x62, 0x23, 0x0e, +- 0x51, 0xde, 0xe7, 0x12, 0x17, 0x39, 0x3f, 0x9d, 0xd4, 0xbf, 0xe8, 0x3b, +- 0x5e, 0xd0, 0x75, 0x1f, 0x75, 0x5d, 0x87, 0x67, 0x12, 0x5f, 0xc4, 0x23, +- 0x94, 0xff, 0xe1, 0x41, 0x23, 0x3a, 0x5f, 0x39, 0x49, 0xfc, 0x2e, 0xc5, +- 0x69, 0xb6, 0x7d, 0x07, 0x33, 0xf7, 0x29, 0xe9, 0x2b, 0x25, 0xeb, 0xa5, +- 0x0a, 0xde, 0x5a, 0x72, 0x12, 0x13, 0xfc, 0xef, 0x07, 0x83, 0xf2, 0x1c, +- 0x5a, 0x35, 0xfb, 0x10, 0xfd, 0xf8, 0xed, 0xdc, 0xa4, 0x87, 0xbc, 0x6b, +- 0x55, 0xf3, 0x49, 0xec, 0x4a, 0xcb, 0xb5, 0xf5, 0xe8, 0x1f, 0xbc, 0x00, +- 0x47, 0xa8, 0x04, 0x77, 0x78, 0x9b, 0x69, 0xeb, 0x39, 0xec, 0xce, 0x34, +- 0xcf, 0xc8, 0x73, 0xe2, 0xaa, 0x19, 0xf2, 0x4c, 0xd6, 0xa9, 0x44, 0x29, +- 0xbe, 0xc3, 0x3a, 0x9b, 0x89, 0x15, 0xf9, 0x7b, 0x38, 0xe4, 0xfe, 0xc4, +- 0xfa, 0x0c, 0xfb, 0x48, 0xd8, 0x6d, 0xcc, 0x50, 0x0e, 0xd0, 0x0f, 0xab, +- 0x17, 0xcf, 0x50, 0x52, 0x69, 0xc9, 0x35, 0x5e, 0xc4, 0x13, 0x0f, 0xe4, +- 0x75, 0x78, 0xc8, 0xdc, 0x88, 0x74, 0xa6, 0xba, 0xd0, 0xde, 0x4b, 0x85, +- 0x7b, 0x6d, 0xf2, 0x3c, 0x88, 0x51, 0x78, 0x17, 0xc0, 0xe5, 0x7b, 0x6c, +- 0xdf, 0xc8, 0x56, 0x91, 0xcf, 0x97, 0xd3, 0xd6, 0x4a, 0x62, 0x5e, 0xc6, +- 0xf9, 0x8d, 0x8b, 0x34, 0xec, 0x5d, 0xfa, 0xd9, 0x5a, 0x54, 0x69, 0xce, +- 0x5f, 0x35, 0xbf, 0xc8, 0x7e, 0xaa, 0x62, 0x35, 0x91, 0x47, 0xec, 0x7d, +- 0x59, 0xa1, 0xa5, 0x33, 0x19, 0xe7, 0xe4, 0x5e, 0x75, 0x0c, 0xaf, 0x27, +- 0x6a, 0x63, 0xb5, 0x91, 0x6a, 0xe6, 0xf6, 0x17, 0x30, 0x30, 0xea, 0x44, +- 0x15, 0x79, 0x7c, 0x65, 0xb2, 0x16, 0x6e, 0x7b, 0x5d, 0xf1, 0x0a, 0xf2, +- 0xa7, 0xb9, 0xe4, 0x48, 0x75, 0xa8, 0x26, 0x4f, 0xf2, 0x84, 0x2c, 0xeb, +- 0xa7, 0x8b, 0x2d, 0xeb, 0x4a, 0x1e, 0x65, 0x3c, 0xce, 0x85, 0xc4, 0x4f, +- 0xa3, 0x68, 0xb4, 0xfd, 0xd5, 0x40, 0x93, 0xfd, 0xdd, 0x4a, 0x5f, 0xef, +- 0x0a, 0x2d, 0x9c, 0xf8, 0x62, 0xa8, 0x61, 0x62, 0x26, 0xd4, 0xe1, 0x59, +- 0x70, 0xb0, 0xad, 0x8f, 0x2f, 0xb5, 0xd0, 0x6a, 0xca, 0xfb, 0x04, 0x84, +- 0xa7, 0x6d, 0x24, 0x4f, 0xeb, 0x0f, 0x19, 0x13, 0x8f, 0xe2, 0x7a, 0xc6, +- 0x5d, 0xf7, 0xb0, 0x8f, 0xfd, 0x48, 0xce, 0xef, 0xcc, 0xcd, 0x23, 0xff, +- 0xbf, 0x7a, 0xb1, 0x70, 0xb6, 0x0e, 0x79, 0x97, 0x08, 0x3a, 0x26, 0x4e, +- 0xe2, 0x26, 0x96, 0xf1, 0x0c, 0xbf, 0x84, 0x64, 0xf6, 0x47, 0x18, 0xc8, +- 0x4a, 0x3c, 0xc9, 0xe1, 0x06, 0xb6, 0x5d, 0x3e, 0xdc, 0x46, 0xae, 0xba, +- 0x06, 0x9b, 0x27, 0x2c, 0xac, 0x0a, 0x4d, 0x62, 0xd5, 0x04, 0x39, 0xf0, +- 0x44, 0xd1, 0x5f, 0x85, 0xbf, 0xad, 0x81, 0x3c, 0x7f, 0xe6, 0x26, 0xb6, +- 0xc8, 0xda, 0x9e, 0x4a, 0x3f, 0x6c, 0xa1, 0x7d, 0x3f, 0x9e, 0x8a, 0x63, +- 0xc3, 0x84, 0x60, 0xee, 0x7d, 0xe8, 0x9d, 0x90, 0xb5, 0xe2, 0xaf, 0x84, +- 0xe6, 0x4f, 0xfc, 0x08, 0x2d, 0x13, 0xe9, 0xd0, 0x82, 0x89, 0x31, 0xca, +- 0x9d, 0xa0, 0x6c, 0x83, 0xa1, 0xfa, 0x89, 0x91, 0x50, 0x70, 0xe2, 0x40, +- 0x28, 0x30, 0xd1, 0x8e, 0x9d, 0x13, 0xeb, 0xb0, 0x63, 0x62, 0x1b, 0xb6, +- 0x4f, 0x08, 0x6e, 0x4f, 0x61, 0xe5, 0xc4, 0xab, 0x58, 0x31, 0xf1, 0x2c, +- 0x5a, 0x27, 0xce, 0x62, 0xf9, 0xc4, 0x8b, 0x68, 0x9b, 0x78, 0x89, 0x63, +- 0x91, 0xb5, 0x67, 0x59, 0x77, 0x2e, 0xde, 0xe7, 0x9b, 0xbe, 0x97, 0x5a, +- 0xd6, 0x56, 0xe4, 0x59, 0x30, 0x99, 0x43, 0x17, 0xd6, 0x6a, 0xe7, 0xd0, +- 0xb7, 0x5f, 0xde, 0xb5, 0xd6, 0xa8, 0xf5, 0x42, 0xee, 0xe1, 0xbe, 0x28, +- 0xcf, 0x06, 0xd0, 0xc6, 0xa6, 0xef, 0x1b, 0xd6, 0xb5, 0xa9, 0x4b, 0xf7, +- 0x3c, 0xe5, 0x99, 0x2c, 0x89, 0x3d, 0xe7, 0xd1, 0x93, 0xfd, 0x8d, 0x15, +- 0xd5, 0xa4, 0xac, 0x3c, 0x2b, 0x26, 0xf6, 0x70, 0x0e, 0x0f, 0xed, 0x3f, +- 0x4f, 0x0e, 0x35, 0x69, 0xaf, 0x1d, 0xbd, 0xbd, 0x40, 0xde, 0xd3, 0xe3, +- 0x27, 0x36, 0x9d, 0x43, 0xea, 0x28, 0x30, 0x71, 0x50, 0xfc, 0x70, 0x23, +- 0xfd, 0x70, 0x52, 0x7c, 0x32, 0x4e, 0x4c, 0xbe, 0xcd, 0x83, 0xfb, 0xc8, +- 0x93, 0x4a, 0x90, 0x1b, 0x2b, 0xc7, 0xd3, 0x23, 0x71, 0x6b, 0x9e, 0x21, +- 0xef, 0x2e, 0x31, 0x72, 0x57, 0x32, 0xee, 0xbf, 0xc4, 0x6b, 0x93, 0x83, +- 0xf0, 0xfb, 0x8c, 0x80, 0x6f, 0x1e, 0xcf, 0x4f, 0xa7, 0x27, 0xc9, 0x71, +- 0xba, 0x30, 0xc5, 0x6f, 0xc9, 0x89, 0x81, 0x5e, 0xa4, 0xd3, 0xa2, 0xcf, +- 0x76, 0xea, 0x53, 0x70, 0x51, 0xef, 0x6a, 0x25, 0x1e, 0x5a, 0x8a, 0xe0, +- 0xa1, 0x8a, 0x8a, 0x7d, 0xc2, 0x25, 0xec, 0x77, 0x9f, 0x98, 0x03, 0xca, +- 0x8b, 0xf8, 0x0e, 0x73, 0x98, 0xf2, 0x7d, 0xe4, 0x43, 0xc4, 0xca, 0xaa, +- 0x88, 0x62, 0xac, 0x0a, 0x9c, 0xc3, 0xd3, 0x63, 0x4e, 0xb8, 0x93, 0x4e, +- 0x4c, 0x12, 0x27, 0x1d, 0x49, 0xd9, 0x3f, 0xa0, 0x51, 0x16, 0x59, 0xa7, +- 0x3a, 0x8b, 0x9c, 0x7d, 0x7f, 0x4f, 0xee, 0xcf, 0x7c, 0xd7, 0xee, 0xc7, +- 0x49, 0xd9, 0xfb, 0x88, 0xa5, 0x3d, 0xa9, 0xef, 0xa1, 0x35, 0xed, 0xb1, +- 0x9f, 0xf3, 0xdb, 0x9d, 0x7a, 0x15, 0xa9, 0xfd, 0x75, 0xb8, 0xdd, 0x7e, +- 0xd6, 0xcf, 0x84, 0x46, 0xbd, 0xdd, 0x32, 0x6e, 0x22, 0x7a, 0x78, 0x1d, +- 0xd6, 0x1e, 0xfe, 0x24, 0x8f, 0x59, 0xb8, 0xe9, 0x70, 0x27, 0x6e, 0x1c, +- 0x8f, 0xa3, 0x63, 0xbc, 0x8f, 0xc7, 0x7a, 0x7c, 0x6c, 0xa8, 0x1a, 0x99, +- 0x90, 0xc6, 0x1c, 0x7f, 0x3d, 0x73, 0x7c, 0xe1, 0x67, 0x1b, 0xf0, 0x34, +- 0x71, 0x27, 0x18, 0xda, 0x80, 0x49, 0xdb, 0x17, 0x65, 0x8f, 0xe5, 0x06, +- 0x6c, 0x67, 0xfe, 0x3e, 0x8a, 0x0d, 0xe8, 0xe1, 0xb5, 0x21, 0x7b, 0x0e, +- 0x4e, 0x62, 0x19, 0xf3, 0xb3, 0x77, 0xae, 0x39, 0x89, 0x0f, 0x1f, 0x92, +- 0xbe, 0x2f, 0x20, 0xb5, 0x77, 0x23, 0xdb, 0xcc, 0xa1, 0x7d, 0xfc, 0x9f, +- 0x71, 0xe3, 0x10, 0xee, 0xac, 0x46, 0x35, 0x9e, 0x0d, 0x05, 0x3a, 0x06, +- 0x94, 0x7f, 0xb6, 0xdb, 0xde, 0x9e, 0xfa, 0x11, 0x76, 0xa5, 0xce, 0xe3, +- 0xe1, 0xcc, 0x4b, 0xe8, 0x4f, 0x4d, 0x9f, 0x53, 0x99, 0xcb, 0x37, 0x19, +- 0x0f, 0xbe, 0x8f, 0x23, 0x63, 0x53, 0xc4, 0xde, 0x57, 0x78, 0xbc, 0xff, +- 0x7e, 0x7a, 0xfe, 0x39, 0xdc, 0xbc, 0xdd, 0x48, 0x3e, 0x55, 0xe4, 0x6f, +- 0x71, 0xab, 0xda, 0xc8, 0xed, 0x9a, 0x03, 0x7d, 0x5b, 0x58, 0x95, 0xfb, +- 0x81, 0x46, 0xec, 0x05, 0x45, 0x6f, 0xff, 0x96, 0xe2, 0x61, 0xae, 0x21, +- 0xcf, 0x45, 0xea, 0xd1, 0x1b, 0xa8, 0xef, 0xb2, 0x07, 0xbe, 0x0f, 0xe7, +- 0x03, 0x4e, 0x94, 0x26, 0x65, 0x2d, 0x47, 0xde, 0x2b, 0x23, 0xef, 0x30, +- 0xc9, 0xe9, 0xa5, 0xf2, 0xae, 0x89, 0xe4, 0x24, 0x63, 0x7f, 0x6e, 0x61, +- 0x09, 0xe4, 0x39, 0xec, 0xeb, 0xb0, 0x71, 0x30, 0x8a, 0x1e, 0x53, 0x9e, +- 0x31, 0xca, 0x8f, 0x7f, 0x5e, 0xf3, 0xf7, 0xd1, 0xcb, 0xf8, 0xb3, 0x9e, +- 0x98, 0x78, 0xbb, 0x7d, 0x6f, 0xf6, 0xfb, 0xe8, 0x1b, 0xf9, 0x47, 0xb7, +- 0xf0, 0x9d, 0x3e, 0x53, 0x9e, 0xe3, 0xd6, 0xcd, 0xf7, 0xbe, 0xc3, 0x66, +- 0xbe, 0xec, 0x69, 0xa3, 0x4d, 0xe4, 0x16, 0xba, 0xb0, 0xbd, 0x36, 0xff, +- 0x1e, 0x95, 0x0f, 0x7a, 0xe7, 0xd0, 0x5f, 0xda, 0xef, 0x1c, 0x92, 0xfb, +- 0xfa, 0xf2, 0xbe, 0xaa, 0x27, 0x12, 0xf2, 0x1e, 0x09, 0x75, 0x99, 0x0b, +- 0xaa, 0xd7, 0x45, 0x5e, 0xf8, 0xaa, 0x39, 0x13, 0xbd, 0x5e, 0x0b, 0xd7, +- 0x53, 0x96, 0x63, 0x4d, 0x1f, 0x63, 0xe6, 0x12, 0xef, 0x70, 0xd9, 0xef, +- 0x26, 0x39, 0xff, 0xa9, 0x7f, 0xff, 0x6e, 0x92, 0x37, 0x89, 0x93, 0x0a, +- 0x2a, 0x8d, 0x5b, 0xf0, 0x9c, 0x1d, 0x13, 0x14, 0x54, 0x34, 0xc8, 0xba, +- 0xa8, 0x1f, 0xcf, 0x18, 0x8d, 0xfe, 0x1a, 0xb9, 0xdf, 0xa5, 0x9c, 0xb3, +- 0xe2, 0xde, 0x3a, 0xc6, 0x97, 0xff, 0x68, 0x2f, 0xfe, 0xf3, 0xd8, 0xb9, +- 0x37, 0x4c, 0xce, 0xe8, 0x95, 0x67, 0x23, 0x67, 0x14, 0x9f, 0xc5, 0xdc, +- 0x91, 0x92, 0x3d, 0xec, 0x0c, 0x8a, 0xe5, 0x6f, 0xd2, 0xcf, 0xde, 0x94, +- 0x3d, 0x58, 0xe4, 0x3c, 0x7f, 0x85, 0x60, 0xcd, 0x8c, 0xfc, 0x73, 0x52, +- 0xf6, 0x5e, 0x5f, 0x59, 0x0f, 0xd8, 0x5e, 0x78, 0xef, 0xa2, 0x94, 0x95, +- 0x7a, 0x6f, 0xda, 0x6b, 0xc2, 0x2e, 0xe3, 0x37, 0xd6, 0x6b, 0xde, 0x5a, +- 0x96, 0xfd, 0x45, 0xe1, 0xff, 0xf3, 0xe2, 0x33, 0x66, 0x14, 0x72, 0x4d, +- 0xea, 0x88, 0xae, 0x2e, 0xd7, 0xe9, 0x4d, 0x39, 0x88, 0x7b, 0x67, 0xad, +- 0x6e, 0xaf, 0x8c, 0x61, 0xec, 0x7d, 0x75, 0x54, 0xfb, 0x1d, 0x84, 0x79, +- 0xfd, 0x8a, 0x3c, 0xff, 0xbe, 0x4f, 0x59, 0x3f, 0x2e, 0x31, 0x2a, 0x70, +- 0xae, 0x26, 0xbf, 0xae, 0x73, 0x59, 0xc6, 0x47, 0xbc, 0xb2, 0xef, 0xaf, +- 0xd4, 0x3e, 0xb7, 0xfb, 0x35, 0x2f, 0xd7, 0xfb, 0x46, 0x61, 0xbc, 0xb5, +- 0xf6, 0xb3, 0x4a, 0x0f, 0xda, 0xbc, 0xc6, 0x31, 0x6d, 0xdc, 0xcb, 0xbc, +- 0xef, 0xed, 0x67, 0xa4, 0xd0, 0xaf, 0x6a, 0x3f, 0xef, 0x75, 0xb9, 0x0f, +- 0x91, 0xeb, 0xa9, 0x42, 0x1d, 0x3d, 0x1c, 0xb5, 0xfb, 0x57, 0x99, 0xbf, +- 0x15, 0xfb, 0xa4, 0x3f, 0x2d, 0x2e, 0xb6, 0x31, 0x29, 0xf6, 0xd5, 0x5d, +- 0xca, 0xd8, 0x74, 0xae, 0xf9, 0x3e, 0x6c, 0x4f, 0x88, 0x9e, 0xe5, 0x1d, +- 0x95, 0xc4, 0x60, 0x9b, 0x6b, 0xb9, 0xe8, 0x6f, 0x4b, 0x91, 0xd6, 0xe2, +- 0x38, 0xd4, 0x24, 0xcf, 0xe6, 0xb9, 0x68, 0xd3, 0x71, 0x94, 0x91, 0xdb, +- 0x46, 0x79, 0x4d, 0xf6, 0xb4, 0x1c, 0x31, 0xf5, 0xe8, 0x13, 0xf8, 0x12, +- 0x1c, 0x57, 0xd9, 0xeb, 0x5f, 0x6d, 0x69, 0xc8, 0x75, 0x93, 0xb9, 0xc9, +- 0xf4, 0x15, 0x83, 0x32, 0xda, 0x8e, 0xbd, 0x17, 0xdb, 0x94, 0x67, 0xf7, +- 0x06, 0x12, 0xf2, 0x0c, 0x59, 0x63, 0x8c, 0xfc, 0x10, 0xcf, 0x65, 0x64, +- 0xff, 0xc3, 0x6f, 0xad, 0xf8, 0x4c, 0xd9, 0x67, 0x39, 0xbd, 0x4e, 0x09, +- 0x71, 0x29, 0x10, 0xae, 0x52, 0x8a, 0xcf, 0x91, 0x5d, 0xfe, 0xdc, 0x44, +- 0x9b, 0x39, 0x6f, 0x3f, 0xfb, 0x27, 0x67, 0x11, 0xb4, 0xa4, 0xe4, 0x5d, +- 0x8c, 0xfa, 0xe4, 0x2a, 0x34, 0xe6, 0xea, 0x1d, 0xce, 0x02, 0xff, 0x08, +- 0x63, 0x0d, 0xed, 0x66, 0x47, 0x20, 0x6c, 0x3f, 0xe3, 0x26, 0xef, 0xdc, +- 0x78, 0x18, 0x7a, 0xe7, 0x1b, 0x2c, 0xff, 0xb1, 0xec, 0xf3, 0x56, 0xda, +- 0x2b, 0x63, 0x2a, 0xfa, 0xb8, 0xbc, 0xdb, 0x87, 0x7a, 0x8c, 0x88, 0x7f, +- 0x78, 0x50, 0x13, 0x09, 0xd3, 0x0f, 0x25, 0x7e, 0xcb, 0xf3, 0x71, 0xfa, +- 0x01, 0xc9, 0xab, 0x5a, 0xb2, 0xf2, 0xfc, 0xb7, 0xec, 0x9b, 0xd6, 0xfd, +- 0x6b, 0x1d, 0xc1, 0xc2, 0xfe, 0xe5, 0x62, 0xbc, 0xb7, 0xbc, 0x85, 0xbd, +- 0xd5, 0xee, 0x79, 0x8c, 0x6f, 0x96, 0xbd, 0x6f, 0x60, 0xa3, 0x8d, 0x0d, +- 0x9a, 0xa1, 0x1f, 0xfb, 0xa5, 0xa3, 0x1b, 0x8f, 0x2d, 0x32, 0xba, 0x8e, +- 0xab, 0xb9, 0xb4, 0x8f, 0x38, 0x71, 0xad, 0x23, 0x3a, 0xc4, 0x6f, 0xff, +- 0x77, 0x89, 0xcd, 0x37, 0xd9, 0x75, 0xf5, 0xe0, 0x3a, 0xb5, 0xf8, 0x6c, +- 0xb5, 0x3c, 0x73, 0xa1, 0x77, 0x7c, 0x43, 0xe9, 0xc6, 0xd6, 0x90, 0xd1, +- 0xbe, 0x4d, 0xd1, 0xdb, 0xbe, 0xac, 0xe8, 0xfe, 0x90, 0x22, 0xe5, 0xec, +- 0x77, 0xe8, 0x5c, 0x8a, 0x9d, 0x2e, 0xf6, 0x71, 0x38, 0xa1, 0x87, 0x67, +- 0xb0, 0xec, 0x39, 0xd3, 0xf0, 0x5d, 0x60, 0x9b, 0x3f, 0xe4, 0x31, 0x84, +- 0x20, 0x96, 0xdb, 0xed, 0x46, 0x17, 0xba, 0xec, 0xf7, 0xa4, 0x76, 0x30, +- 0x26, 0xc8, 0xfb, 0xb0, 0x62, 0xd0, 0x92, 0x75, 0x34, 0x31, 0xbd, 0xff, +- 0x66, 0x48, 0x4e, 0xdd, 0xc3, 0x80, 0xed, 0x81, 0x37, 0xd2, 0x8d, 0x86, +- 0x45, 0x86, 0x6f, 0x89, 0x6a, 0xd7, 0x0f, 0xca, 0xfb, 0x81, 0x96, 0x73, +- 0x9c, 0x23, 0x90, 0x36, 0x72, 0x96, 0xd6, 0x50, 0x6d, 0xd7, 0x59, 0xa4, +- 0x7e, 0x14, 0xae, 0x0f, 0xfd, 0xca, 0x4a, 0x6b, 0xd0, 0x6a, 0x0d, 0xa9, +- 0x13, 0x1f, 0xd2, 0xf0, 0x1f, 0xd5, 0x13, 0x5c, 0xf9, 0xa5, 0x85, 0x59, +- 0x52, 0x4f, 0xf6, 0xac, 0x7d, 0x1a, 0x77, 0x0d, 0xc8, 0x7b, 0x22, 0xc4, +- 0x1f, 0xf5, 0xe8, 0x17, 0xc8, 0x35, 0xcb, 0xed, 0xf7, 0x6f, 0x49, 0x2c, +- 0x59, 0x4f, 0x3c, 0xeb, 0x86, 0x16, 0xd2, 0xfb, 0xaf, 0x50, 0xe5, 0x1d, +- 0x43, 0x8f, 0xc9, 0xbe, 0x9d, 0x03, 0x0b, 0xd4, 0xfc, 0xfe, 0x9e, 0xd8, +- 0x1f, 0x7d, 0x5f, 0x11, 0xfb, 0x2a, 0x97, 0xf7, 0x15, 0xd5, 0xd9, 0xcf, +- 0xa7, 0xac, 0x4f, 0x38, 0x0a, 0xfb, 0x15, 0x2f, 0xbf, 0xc7, 0x73, 0x23, +- 0x79, 0xfd, 0x26, 0x79, 0x67, 0x1f, 0xc7, 0xba, 0x39, 0x21, 0x4b, 0x5a, +- 0xff, 0x0f, 0xdd, 0x0f, 0x6b, 0xf2, 0xd0, 0x56, 0x00, 0x00, 0x00 }; ++ 0x9d, 0xbc, 0x0d, 0x78, 0x1b, 0xe5, 0x95, 0x36, 0x7c, 0xcf, 0x48, 0xb2, ++ 0x65, 0x5b, 0xb6, 0xc7, 0x8e, 0x9c, 0x28, 0x6c, 0x9a, 0x68, 0xf0, 0x28, ++ 0x51, 0xb0, 0x69, 0x47, 0x89, 0x03, 0x82, 0x55, 0x89, 0xea, 0x98, 0xc4, ++ 0x81, 0x50, 0x9c, 0x12, 0x5a, 0xb3, 0x4b, 0x5b, 0xe1, 0xfc, 0x60, 0x42, ++ 0xa0, 0xa1, 0xb0, 0xef, 0x9a, 0xef, 0x65, 0x5f, 0xab, 0xb6, 0x93, 0x38, ++ 0x89, 0x2c, 0x39, 0x8e, 0x21, 0x61, 0xbf, 0x5e, 0x8b, 0x89, 0x9d, 0x38, ++ 0x80, 0x6c, 0x85, 0x36, 0xdd, 0x0d, 0x7d, 0xd3, 0x8d, 0x36, 0x09, 0x60, ++ 0xfe, 0xda, 0x40, 0xbb, 0x2c, 0xed, 0xcb, 0x07, 0xde, 0x14, 0x42, 0xd8, ++ 0xb6, 0x40, 0xb7, 0x3f, 0x1b, 0x5a, 0xca, 0xbc, 0xf7, 0x19, 0x49, 0x89, ++ 0x13, 0x28, 0xed, 0x7e, 0xbe, 0xae, 0xb9, 0xac, 0x99, 0x79, 0x7e, 0xce, ++ 0x73, 0x9e, 0x73, 0xee, 0x73, 0x9f, 0x67, 0x9e, 0x19, 0x3f, 0x50, 0x8a, ++ 0xfc, 0x5f, 0x39, 0x8f, 0x4f, 0x37, 0x6c, 0x5c, 0xbd, 0x60, 0xc1, 0xa7, ++ 0x1b, 0xe4, 0xdc, 0x39, 0xdd, 0xe9, 0xc4, 0x9f, 0xf9, 0xe7, 0xff, 0x73, ++ 0x0b, 0x7e, 0xcc, 0x9f, 0x03, 0xd0, 0x0a, 0xfd, 0xcb, 0x01, 0xb7, 0x1a, ++ 0x71, 0xde, 0xdc, 0x68, 0xc0, 0xed, 0x88, 0x4c, 0xb4, 0xad, 0x36, 0x80, ++ 0x68, 0xba, 0xce, 0xbf, 0x04, 0x7f, 0xb0, 0xe2, 0x5e, 0x27, 0xe4, 0xfa, ++ 0xa7, 0x22, 0x1f, 0x74, 0x7e, 0xef, 0x72, 0xfd, 0xbd, 0x21, 0x07, 0xdc, ++ 0x5a, 0x24, 0x0e, 0x6d, 0x2e, 0xdc, 0xb3, 0x58, 0xe7, 0x9b, 0xf3, 0xbe, ++ 0xa9, 0xa0, 0xa2, 0xd0, 0xd6, 0x69, 0xeb, 0x7b, 0xf3, 0x7c, 0xb1, 0x92, ++ 0x88, 0x86, 0x23, 0x19, 0xb4, 0xd4, 0xf7, 0x75, 0x5a, 0xe5, 0x46, 0x08, ++ 0x6e, 0xc3, 0x68, 0xed, 0x53, 0x3c, 0xe1, 0xf5, 0x8b, 0xe0, 0x29, 0x36, ++ 0x10, 0xbf, 0x28, 0x82, 0x96, 0x4b, 0xc6, 0x4a, 0xe3, 0xce, 0x88, 0x1b, ++ 0xcd, 0x19, 0x77, 0xfc, 0x2f, 0x22, 0x06, 0x96, 0x65, 0x66, 0x95, 0xa2, ++ 0xc2, 0x8d, 0x9e, 0xcc, 0xeb, 0x25, 0xb9, 0xf6, 0xea, 0xf3, 0xff, 0x83, ++ 0xd3, 0x72, 0xff, 0xa7, 0xc7, 0x9c, 0x11, 0x60, 0x53, 0xc2, 0xb2, 0x8a, ++ 0x22, 0x37, 0xdc, 0xa0, 0x46, 0x0c, 0xdf, 0x3e, 0x2c, 0x46, 0x9b, 0x86, ++ 0xfb, 0x36, 0x37, 0xfc, 0xa7, 0x72, 0x74, 0x90, 0x0d, 0x8f, 0x3a, 0x10, ++ 0xd5, 0x8e, 0xf3, 0xff, 0xec, 0xd9, 0xad, 0x61, 0x03, 0xbb, 0x47, 0xcf, ++ 0xf0, 0xba, 0xd3, 0xbe, 0xd6, 0xbd, 0x6b, 0xf6, 0xec, 0x9b, 0xc2, 0xc7, ++ 0xf1, 0xe0, 0xa8, 0xfc, 0xbe, 0x15, 0x9d, 0xf5, 0x0a, 0x26, 0x6f, 0x58, ++ 0x07, 0x87, 0x61, 0xa0, 0x67, 0x97, 0xe2, 0xec, 0xaa, 0x57, 0x11, 0xf5, ++ 0xea, 0xc1, 0x18, 0x27, 0xc1, 0x69, 0x20, 0x56, 0x1c, 0x09, 0x3b, 0xdf, ++ 0x4e, 0x44, 0x34, 0x87, 0x61, 0x59, 0xc1, 0xd0, 0x0c, 0x38, 0xaa, 0x2c, ++ 0xeb, 0x09, 0xd3, 0x03, 0xff, 0x97, 0x9e, 0x42, 0x7c, 0xb8, 0x05, 0xaa, ++ 0xf1, 0x14, 0xba, 0x86, 0x9f, 0xc2, 0x43, 0x3b, 0x4b, 0x31, 0x39, 0x8d, ++ 0xe3, 0x4d, 0xf9, 0xf0, 0xbd, 0x79, 0xd2, 0xb7, 0xc8, 0x51, 0xcf, 0xc3, ++ 0x8d, 0x49, 0xc7, 0x6b, 0xfc, 0x2f, 0x65, 0xce, 0x58, 0x93, 0x33, 0xce, ++ 0x95, 0xd9, 0xc4, 0x32, 0x3d, 0x17, 0x94, 0x89, 0x0f, 0x47, 0xf0, 0x5c, ++ 0x42, 0xc1, 0xfa, 0x50, 0x05, 0xa2, 0x55, 0x32, 0x5e, 0xcb, 0x1a, 0x35, ++ 0x4f, 0x59, 0x93, 0x9a, 0xf4, 0x35, 0x81, 0xe7, 0x79, 0x6f, 0x73, 0xe8, ++ 0x0d, 0x2b, 0xeb, 0x95, 0xf6, 0xbe, 0x4e, 0x1b, 0x5a, 0xc9, 0xeb, 0x4e, ++ 0xa4, 0x12, 0x88, 0x55, 0x44, 0x6e, 0xe4, 0xb9, 0x6e, 0xbe, 0xa3, 0xb8, ++ 0xdd, 0xef, 0x26, 0xdc, 0x5f, 0x2a, 0x37, 0xd4, 0x7b, 0x2a, 0xe1, 0xc4, ++ 0x0b, 0x94, 0xf9, 0x90, 0xb9, 0x0e, 0x2e, 0xe3, 0x6e, 0xb1, 0x39, 0x8e, ++ 0xeb, 0x47, 0x16, 0x66, 0x14, 0xea, 0x4b, 0xbb, 0x6e, 0x6c, 0x4e, 0x59, ++ 0xd6, 0x56, 0x33, 0x7a, 0x45, 0x09, 0x0d, 0xe2, 0x58, 0xa2, 0x05, 0xee, ++ 0x48, 0xc0, 0x7f, 0x1a, 0x61, 0x2c, 0xc9, 0x78, 0xf1, 0x64, 0x02, 0xce, ++ 0xc6, 0x79, 0x5e, 0x74, 0x65, 0x22, 0xb8, 0x3a, 0x63, 0xa2, 0x29, 0xf3, ++ 0xa7, 0x2d, 0xeb, 0xda, 0x94, 0x9f, 0x63, 0xf8, 0x83, 0x95, 0x1b, 0x83, ++ 0x8c, 0x2f, 0xf7, 0xbf, 0x27, 0x75, 0x11, 0xb6, 0x71, 0x8e, 0xb6, 0x70, ++ 0xfe, 0x96, 0x87, 0xb2, 0xd1, 0x12, 0xe8, 0xe6, 0x69, 0x44, 0xb0, 0x34, ++ 0x63, 0x70, 0x4e, 0x23, 0x58, 0x92, 0xaa, 0xd5, 0x86, 0x31, 0x1f, 0x51, ++ 0x5f, 0xce, 0xb6, 0xb7, 0x73, 0xbc, 0x6d, 0x81, 0x16, 0x94, 0xd3, 0x46, ++ 0xd2, 0x8b, 0xc2, 0x68, 0x64, 0xff, 0x2b, 0xfe, 0x8c, 0xfe, 0xaf, 0x67, ++ 0xff, 0xef, 0xb0, 0xff, 0xac, 0xdd, 0x3f, 0x9c, 0xd7, 0xf0, 0xdc, 0x4d, ++ 0x7b, 0xdc, 0x96, 0x76, 0x3a, 0x97, 0xa7, 0xbc, 0xd8, 0x9a, 0x36, 0x69, ++ 0x73, 0x72, 0xcb, 0x87, 0xcd, 0x83, 0xb3, 0xb0, 0x65, 0x50, 0xf7, 0x3d, ++ 0xcd, 0xdf, 0xdd, 0x23, 0x17, 0x61, 0xd3, 0xa0, 0x82, 0x3d, 0xc6, 0x45, ++ 0xe8, 0xe2, 0xef, 0xdd, 0x83, 0xb3, 0xf1, 0xe0, 0xa0, 0x03, 0xe1, 0x69, ++ 0xe7, 0x8f, 0x63, 0xd2, 0x71, 0x11, 0xe2, 0x23, 0x7e, 0x74, 0x25, 0x9e, ++ 0xb7, 0x75, 0x58, 0x1e, 0xf9, 0x5e, 0xc1, 0x9f, 0xe9, 0x3b, 0x7e, 0xac, ++ 0x4e, 0x68, 0xe8, 0x4a, 0x89, 0x1f, 0xb8, 0x69, 0x9b, 0xe2, 0x07, 0xbf, ++ 0x06, 0x2a, 0x34, 0x74, 0x67, 0x0a, 0xf7, 0x15, 0x38, 0x39, 0x6f, 0x6b, ++ 0x34, 0x37, 0xb6, 0xa6, 0xc4, 0x26, 0xa4, 0x4d, 0xb1, 0x0b, 0xf9, 0x5d, ++ 0x4d, 0xbb, 0x2b, 0x85, 0x7f, 0x6f, 0x29, 0x82, 0xf7, 0x6b, 0x78, 0xb3, ++ 0x41, 0xae, 0xd3, 0xde, 0x43, 0x52, 0xa6, 0x1f, 0xfb, 0xd2, 0xe2, 0xa7, ++ 0x7e, 0x34, 0x26, 0x26, 0xd8, 0x7e, 0x03, 0xdb, 0x36, 0xf1, 0xcf, 0x99, ++ 0x7a, 0xfc, 0x53, 0x26, 0x88, 0x7f, 0xa4, 0x1e, 0xbf, 0x93, 0xf1, 0xe3, ++ 0x60, 0x66, 0x16, 0xbe, 0x9d, 0xf1, 0xe1, 0x5b, 0x9c, 0xbf, 0xc7, 0x33, ++ 0x2d, 0xb4, 0x7d, 0x0d, 0x07, 0x32, 0xa2, 0xff, 0x22, 0x8e, 0xb7, 0x14, ++ 0xdd, 0x83, 0xb5, 0xc1, 0x63, 0xb4, 0xad, 0x7f, 0x34, 0xaf, 0x41, 0xb6, ++ 0xba, 0xc1, 0xb6, 0xc9, 0xad, 0xbc, 0xbe, 0x6d, 0xb0, 0x36, 0x7a, 0x89, ++ 0x62, 0x59, 0x6a, 0xa8, 0x2e, 0x7c, 0x54, 0x55, 0x31, 0xe9, 0xd5, 0xfd, ++ 0x59, 0x55, 0xf7, 0x47, 0xe1, 0x42, 0x82, 0xbe, 0x11, 0xaf, 0xd1, 0x87, ++ 0xe2, 0xb4, 0x29, 0xaf, 0x31, 0xcc, 0xf1, 0xe8, 0xfe, 0xb8, 0xea, 0xc6, ++ 0x96, 0x94, 0xbe, 0x3b, 0xae, 0x7a, 0x10, 0xcf, 0x94, 0xe2, 0x17, 0x83, ++ 0x7a, 0x6f, 0x5c, 0xfd, 0x3c, 0xe2, 0xd5, 0x96, 0xf5, 0xad, 0x10, 0x36, ++ 0xce, 0x88, 0x20, 0x5a, 0x13, 0x41, 0x6c, 0x76, 0xc4, 0x8b, 0x54, 0x0a, ++ 0x78, 0xa7, 0xcf, 0xf0, 0xfd, 0x9b, 0xd2, 0x82, 0xbf, 0x69, 0xd1, 0xfd, ++ 0x7e, 0xb5, 0x2e, 0x3e, 0xac, 0x2e, 0xa2, 0x4b, 0xc3, 0xef, 0x8b, 0x2c, ++ 0x43, 0x87, 0x7d, 0x4d, 0x81, 0x66, 0x78, 0xd0, 0x9d, 0xba, 0x02, 0x31, ++ 0x6f, 0x6d, 0xeb, 0x0e, 0xb5, 0xf6, 0x8c, 0xa9, 0xea, 0x13, 0x2d, 0xaa, ++ 0x65, 0xfd, 0x72, 0xe1, 0x3b, 0x96, 0x7f, 0xba, 0x65, 0x2d, 0x58, 0x28, ++ 0x7d, 0xfa, 0x51, 0x15, 0x31, 0xb1, 0xd2, 0x9e, 0xc3, 0x52, 0x9c, 0x1a, ++ 0xac, 0x66, 0x1f, 0x1a, 0xfe, 0xf5, 0x72, 0x3d, 0xb8, 0x4e, 0x2d, 0xc5, ++ 0x9b, 0x23, 0xa5, 0x38, 0xc9, 0xf1, 0xfc, 0xe7, 0xa0, 0x0f, 0xbf, 0x1e, ++ 0xb4, 0xac, 0x2f, 0x99, 0x7f, 0x89, 0x81, 0xea, 0x7e, 0xfc, 0xd3, 0xb8, ++ 0x17, 0xbf, 0xe0, 0xdc, 0xbc, 0x91, 0x88, 0xde, 0x35, 0x0d, 0x7a, 0x74, ++ 0x5c, 0x39, 0xf6, 0xd5, 0x0a, 0xd4, 0xb5, 0x54, 0x28, 0x7a, 0xf3, 0x76, ++ 0xe8, 0xbe, 0x4b, 0x14, 0x2f, 0x4e, 0xa7, 0x35, 0xfc, 0x34, 0x5d, 0x1b, ++ 0xfe, 0x21, 0xfb, 0xfc, 0xad, 0xf9, 0x84, 0x95, 0x9d, 0x2e, 0x7a, 0x13, ++ 0x1d, 0x51, 0xcf, 0x29, 0xea, 0x39, 0x45, 0x3d, 0xa7, 0xa8, 0x67, 0xca, ++ 0x70, 0x30, 0x45, 0x3d, 0x53, 0x77, 0xdf, 0xa2, 0x4d, 0x3d, 0xce, 0x79, ++ 0x3c, 0x60, 0xcf, 0x63, 0x98, 0xf3, 0xf5, 0x17, 0xf8, 0x5f, 0x36, 0xb6, ++ 0x3e, 0x6f, 0xfd, 0xad, 0x57, 0xc6, 0xd4, 0x3d, 0x3d, 0x87, 0x5f, 0x32, ++ 0xb6, 0xe7, 0xac, 0x98, 0x26, 0xe3, 0x92, 0xf1, 0xd9, 0xfa, 0xf3, 0x6f, ++ 0x54, 0xb6, 0x28, 0x28, 0xb5, 0xac, 0x9d, 0x66, 0xfe, 0xbe, 0xb7, 0x30, ++ 0xbe, 0x1b, 0x94, 0x9c, 0x5d, 0xed, 0x74, 0x53, 0xdf, 0xc1, 0xa8, 0xba, ++ 0x8c, 0xe7, 0x7a, 0x3c, 0x8a, 0xb9, 0xc5, 0xe7, 0x9f, 0x5f, 0x5b, 0x23, ++ 0xf3, 0xe1, 0x3f, 0x7b, 0x4e, 0x7b, 0xb4, 0xfb, 0xbb, 0x8d, 0xe7, 0x32, ++ 0x16, 0xb1, 0x45, 0xb1, 0x01, 0x2f, 0xed, 0xe5, 0xf2, 0xfc, 0x3d, 0xc4, ++ 0xd5, 0xc8, 0x46, 0xb4, 0x34, 0x3c, 0x6a, 0xf7, 0x51, 0x94, 0x14, 0xbf, ++ 0x51, 0xf0, 0xce, 0x15, 0x0a, 0x8e, 0x86, 0x0c, 0xda, 0xcc, 0x10, 0x71, ++ 0x01, 0x28, 0x4e, 0xc2, 0xed, 0x89, 0x44, 0x90, 0xe8, 0x83, 0xbb, 0x24, ++ 0x12, 0xc6, 0xfc, 0xbe, 0xda, 0xf6, 0x53, 0xd0, 0x83, 0x7d, 0x8a, 0xde, ++ 0x02, 0xd4, 0x99, 0x63, 0xd4, 0xe3, 0x25, 0x8a, 0xee, 0x2f, 0x52, 0xe0, ++ 0x56, 0x58, 0x2e, 0x90, 0x1e, 0xc2, 0x96, 0x8c, 0xfc, 0x0e, 0xc3, 0x48, ++ 0xff, 0xb6, 0xd0, 0x17, 0xed, 0x7e, 0x23, 0xed, 0xfe, 0x14, 0xc7, 0xae, ++ 0xfb, 0x89, 0xaf, 0x6e, 0x57, 0xa4, 0x1d, 0x7b, 0x13, 0x70, 0x17, 0x45, ++ 0x36, 0xe0, 0xa9, 0x44, 0xf5, 0xf4, 0x42, 0x39, 0x85, 0xe5, 0xfc, 0xe9, ++ 0xa9, 0xb2, 0xbc, 0x66, 0x45, 0xbd, 0x39, 0x59, 0x4a, 0x93, 0x43, 0xd8, ++ 0x9e, 0x92, 0xba, 0x11, 0xbb, 0xae, 0x93, 0x7d, 0xf4, 0x24, 0x6a, 0x9b, ++ 0xaf, 0x55, 0xf4, 0xf0, 0x23, 0xa8, 0x8b, 0xbe, 0xcd, 0x39, 0xec, 0x82, ++ 0x7e, 0xa6, 0x1d, 0x39, 0x59, 0xe6, 0xa5, 0x73, 0x72, 0x2c, 0x4e, 0x43, ++ 0xb9, 0x29, 0x05, 0x8f, 0xcf, 0x98, 0x96, 0xf7, 0x65, 0x28, 0xd7, 0x71, ++ 0xfe, 0x54, 0xc3, 0x8f, 0xeb, 0x68, 0x43, 0x1b, 0x76, 0x5a, 0xe8, 0x0e, ++ 0x55, 0xd3, 0x57, 0x5b, 0x50, 0x41, 0xbf, 0xbc, 0x53, 0x43, 0xb4, 0x32, ++ 0x12, 0x56, 0xae, 0xcf, 0x0c, 0xe7, 0xf5, 0x7f, 0xb4, 0x9a, 0xf2, 0x29, ++ 0x4d, 0xa9, 0x0b, 0xaf, 0x57, 0xe6, 0xe3, 0xde, 0x85, 0xd7, 0x3d, 0x45, ++ 0x1f, 0x5f, 0xbe, 0x4e, 0x1b, 0x81, 0xc2, 0x78, 0x53, 0x42, 0xfd, 0xea, ++ 0x26, 0xab, 0x05, 0x5d, 0xf6, 0x35, 0x07, 0x86, 0x9c, 0x51, 0x9f, 0x03, ++ 0x1f, 0x58, 0xd1, 0x55, 0x72, 0xad, 0x14, 0xb1, 0x96, 0x3a, 0x9f, 0x13, ++ 0x75, 0xe1, 0x4d, 0xf4, 0xb7, 0xc9, 0x55, 0x8d, 0xbc, 0x17, 0x30, 0x8f, ++ 0xa1, 0xd6, 0xbf, 0x09, 0xf2, 0xfb, 0x7d, 0xda, 0x48, 0xa3, 0xd4, 0x65, ++ 0x19, 0xb1, 0x39, 0x5d, 0x3b, 0x06, 0x2f, 0x36, 0xd1, 0xfe, 0x8a, 0x23, ++ 0xba, 0xb9, 0xcc, 0xe1, 0xc4, 0x7e, 0xe2, 0xb8, 0xc3, 0xe8, 0x45, 0x31, ++ 0xc7, 0xc8, 0xf8, 0x8a, 0x47, 0x12, 0xc0, 0xb3, 0xfd, 0x16, 0x1a, 0x43, ++ 0x1e, 0x2c, 0xb1, 0x6d, 0xf3, 0x90, 0x72, 0x75, 0xea, 0x43, 0x6b, 0xc8, ++ 0x59, 0x12, 0x55, 0x23, 0x01, 0xdf, 0x49, 0xb2, 0x81, 0xa2, 0x48, 0x9d, ++ 0xe6, 0x44, 0x5c, 0x69, 0xce, 0xf4, 0x28, 0xcb, 0x33, 0xbd, 0xca, 0x92, ++ 0x8c, 0xb4, 0x7d, 0x48, 0x59, 0x9a, 0xf1, 0x20, 0xdd, 0xaf, 0x60, 0x7b, ++ 0x88, 0x72, 0xd5, 0xe4, 0xec, 0x38, 0xd3, 0xaf, 0x12, 0x63, 0xdf, 0x21, ++ 0xc6, 0xea, 0x61, 0xb0, 0xef, 0x27, 0x12, 0xd5, 0x38, 0x44, 0x2c, 0xfd, ++ 0x71, 0x5a, 0x57, 0x51, 0x7a, 0x11, 0x5e, 0x19, 0xa9, 0xc0, 0xd8, 0xa0, ++ 0xc9, 0xdf, 0xf5, 0x78, 0x61, 0xc4, 0xb2, 0x7a, 0x4c, 0xcb, 0xda, 0x6b, ++ 0x1e, 0x52, 0x1a, 0xd9, 0x67, 0xd4, 0x19, 0x8f, 0x16, 0x47, 0x02, 0xe6, ++ 0x16, 0xf6, 0xe9, 0x88, 0xc4, 0x95, 0x28, 0xfb, 0xbb, 0x9a, 0xfd, 0x2d, ++ 0xcd, 0xf7, 0x97, 0xeb, 0x57, 0x64, 0x91, 0x7a, 0x85, 0x3a, 0x61, 0xd6, ++ 0x01, 0xf6, 0x25, 0x02, 0xc1, 0x42, 0xbd, 0xa5, 0xac, 0x73, 0xf5, 0xd9, ++ 0x3a, 0xc0, 0x70, 0x22, 0xc8, 0x39, 0x15, 0x5b, 0xf7, 0x33, 0x76, 0x7d, ++ 0x83, 0x18, 0xdb, 0x80, 0xb6, 0x61, 0xc1, 0xdf, 0x6b, 0xd4, 0xdc, 0x3c, ++ 0xe5, 0xb0, 0x56, 0x62, 0x5e, 0x0e, 0x6f, 0x83, 0xe8, 0xa3, 0x5f, 0x77, ++ 0xa5, 0xc4, 0xc6, 0xef, 0xf9, 0x72, 0x22, 0xa0, 0xe0, 0xb1, 0x40, 0xb6, ++ 0xa5, 0x1c, 0x95, 0x68, 0x0f, 0x89, 0x6d, 0x6e, 0xfc, 0xf2, 0x53, 0x86, ++ 0x1e, 0x5e, 0xa1, 0x70, 0xce, 0x02, 0x7a, 0xf3, 0x52, 0x05, 0x08, 0x8c, ++ 0x01, 0x6f, 0xa4, 0x2b, 0xb1, 0xda, 0x74, 0x40, 0xad, 0x0a, 0xa2, 0x37, ++ 0x33, 0x35, 0x2e, 0x98, 0xc4, 0x78, 0x69, 0x2f, 0x48, 0xbf, 0x2e, 0xc3, ++ 0x32, 0x2d, 0x67, 0xd3, 0x6e, 0xb6, 0xed, 0x0e, 0x64, 0x83, 0x2a, 0xe3, ++ 0xdd, 0x7e, 0x5e, 0x38, 0x46, 0xfc, 0x6f, 0x34, 0x5c, 0xc4, 0xff, 0x4a, ++ 0x34, 0x9a, 0xbf, 0xb3, 0x96, 0xad, 0x92, 0x7b, 0x85, 0x76, 0xe0, 0x2e, ++ 0x66, 0xbf, 0x6f, 0x19, 0xba, 0x7f, 0x94, 0x27, 0xd9, 0x74, 0xee, 0x7a, ++ 0x9c, 0x31, 0xab, 0x9b, 0xed, 0x6e, 0x66, 0xbb, 0xeb, 0x34, 0x3d, 0x1a, ++ 0x3f, 0x5b, 0x2e, 0x1b, 0x74, 0x40, 0xd7, 0xa4, 0x6c, 0x13, 0xdb, 0x5d, ++ 0xcd, 0x76, 0x7b, 0x35, 0x91, 0xef, 0x77, 0xd6, 0xba, 0x55, 0x72, 0x2f, ++ 0x67, 0x1f, 0xb9, 0x76, 0xef, 0x91, 0x76, 0xcd, 0xd1, 0x7c, 0x5f, 0x47, ++ 0x13, 0xe8, 0x77, 0x44, 0x18, 0x63, 0x1b, 0x02, 0xfe, 0x2e, 0xc6, 0xdb, ++ 0x26, 0xc6, 0x8e, 0x9c, 0x4d, 0x4c, 0x8d, 0x77, 0x88, 0x9f, 0x2b, 0x23, ++ 0xd7, 0xa4, 0x9c, 0xd8, 0xda, 0x24, 0xf5, 0x2c, 0xf1, 0xc5, 0x47, 0xfd, ++ 0x0a, 0xb6, 0x38, 0x71, 0x20, 0x41, 0xfc, 0xc7, 0x37, 0x68, 0x77, 0x7e, ++ 0xb4, 0x64, 0x6a, 0xb1, 0x66, 0x27, 0xe3, 0xa0, 0x59, 0x45, 0x5b, 0xcf, ++ 0xd9, 0xdb, 0x32, 0xb6, 0x3d, 0x69, 0xb7, 0x1d, 0x57, 0x5a, 0x32, 0x75, ++ 0x5a, 0x15, 0x63, 0xee, 0x91, 0xb3, 0xd8, 0x39, 0x27, 0x5a, 0x1a, 0x09, ++ 0x34, 0xaf, 0xe7, 0x24, 0xb9, 0x19, 0xdf, 0xbe, 0x37, 0xaf, 0x87, 0x76, ++ 0xd1, 0x4b, 0x3b, 0xcc, 0xcd, 0x6f, 0x73, 0x66, 0x8f, 0x2a, 0x18, 0x07, ++ 0xb5, 0x16, 0xeb, 0x76, 0xca, 0x7f, 0x72, 0x95, 0x86, 0xc7, 0x78, 0xad, ++ 0x16, 0xab, 0x87, 0xbf, 0x47, 0x3b, 0xd3, 0x7d, 0x62, 0x87, 0x5d, 0x67, ++ 0xe5, 0x12, 0x99, 0x44, 0x36, 0x91, 0xa9, 0x8f, 0xe5, 0x66, 0x51, 0x3f, ++ 0x82, 0x8d, 0xd5, 0x94, 0x67, 0x2b, 0xf9, 0xd0, 0x21, 0xe5, 0xf3, 0x94, ++ 0x27, 0xeb, 0xf2, 0xe2, 0xa1, 0x94, 0xc8, 0xa3, 0x44, 0x67, 0x46, 0x66, ++ 0xe1, 0x4c, 0x2a, 0x10, 0x7f, 0x02, 0x22, 0x5b, 0x8f, 0xd2, 0x2a, 0xf5, ++ 0x53, 0xbd, 0xbc, 0x57, 0x90, 0x11, 0x5a, 0xa5, 0x2d, 0x5b, 0x4e, 0xa6, ++ 0xeb, 0x39, 0xd7, 0x2e, 0xe3, 0x6f, 0xcb, 0x51, 0xe1, 0xa4, 0xad, 0x49, ++ 0xdb, 0xff, 0x61, 0x45, 0xb5, 0x6e, 0x5e, 0xf3, 0x72, 0x9e, 0xdc, 0xe4, ++ 0x05, 0x7a, 0xf0, 0x3a, 0x87, 0xd2, 0xe2, 0x91, 0x78, 0x4d, 0xfb, 0x4c, ++ 0xa7, 0x9d, 0x38, 0x9e, 0x58, 0xba, 0xb4, 0xcc, 0xf8, 0x34, 0x1e, 0x1b, ++ 0xf1, 0x61, 0x84, 0x73, 0xfb, 0x6c, 0x42, 0xe2, 0xeb, 0x2c, 0x3c, 0x9a, ++ 0xf6, 0xe0, 0x99, 0x84, 0x1f, 0x8f, 0x30, 0xfe, 0x4c, 0x24, 0x0c, 0xec, ++ 0x4f, 0x7b, 0xf1, 0x34, 0xed, 0x79, 0x34, 0xed, 0xa3, 0xbd, 0xd4, 0x63, ++ 0x38, 0xdd, 0x66, 0x8f, 0xe1, 0xc9, 0xc4, 0xbf, 0xcb, 0x58, 0x83, 0x32, ++ 0xd6, 0xcd, 0xf6, 0x58, 0x0b, 0x71, 0x7e, 0xd6, 0xd9, 0x79, 0x38, 0x91, ++ 0xb0, 0x71, 0xa0, 0x77, 0x99, 0x43, 0xe6, 0x81, 0x36, 0x3b, 0x20, 0x58, ++ 0xa0, 0xf7, 0xc7, 0x61, 0x61, 0x8f, 0x39, 0x93, 0xfe, 0xdf, 0x4b, 0x79, ++ 0xa9, 0x53, 0x8e, 0x1f, 0xae, 0x8a, 0x68, 0x79, 0x24, 0x10, 0xeb, 0xa3, ++ 0xde, 0x9d, 0x11, 0xd1, 0x43, 0x4e, 0xef, 0x2b, 0x32, 0x87, 0x14, 0xe1, ++ 0x7a, 0x97, 0x0c, 0xc4, 0xad, 0x32, 0x43, 0xf4, 0x1d, 0x20, 0xce, 0x02, ++ 0xf3, 0xf7, 0x38, 0x39, 0xbe, 0x9b, 0x38, 0x66, 0x13, 0x45, 0x46, 0x9d, ++ 0x56, 0x4d, 0xd9, 0x8f, 0x7c, 0x24, 0x06, 0x8a, 0x8e, 0xfe, 0x36, 0x3f, ++ 0x5f, 0xba, 0x83, 0xf2, 0xfa, 0x81, 0xc2, 0xbc, 0x58, 0xd6, 0x0e, 0xb3, ++ 0x30, 0x37, 0x35, 0xf0, 0x57, 0xeb, 0xf1, 0x21, 0x5a, 0xc4, 0x48, 0x62, ++ 0x1a, 0xe2, 0x9a, 0x9a, 0x6f, 0x3b, 0xaa, 0x14, 0x31, 0xff, 0xc0, 0xb8, ++ 0xf8, 0x7e, 0x39, 0xa2, 0x4e, 0xa9, 0x8f, 0x68, 0x51, 0x24, 0x10, 0x9c, ++ 0xab, 0x4e, 0xb5, 0x19, 0xc1, 0x01, 0xe9, 0x2b, 0x4e, 0x59, 0xcf, 0xc7, ++ 0x82, 0x91, 0x44, 0x01, 0x37, 0xfe, 0x3b, 0xf5, 0x2e, 0xd4, 0xa9, 0xc8, ++ 0x29, 0x7a, 0x55, 0x71, 0x74, 0x50, 0xf4, 0xe7, 0xc4, 0x4a, 0x73, 0x7a, ++ 0x5e, 0xe6, 0x59, 0x9c, 0x17, 0x62, 0x0e, 0xe7, 0xeb, 0x85, 0x7e, 0x2f, ++ 0xe5, 0xb6, 0x90, 0x0e, 0x5d, 0x8c, 0x4d, 0x36, 0xe7, 0x5c, 0x95, 0xcf, ++ 0x5b, 0x38, 0x4f, 0xea, 0x76, 0xea, 0xfa, 0xb3, 0x8e, 0xdc, 0x79, 0x9d, ++ 0xef, 0xa3, 0xfa, 0xd2, 0xb5, 0x18, 0x0a, 0x3a, 0x03, 0x86, 0xd2, 0x88, ++ 0xb9, 0x23, 0xf5, 0x4d, 0xce, 0xbe, 0xb6, 0x0d, 0xf4, 0xef, 0x7b, 0x4f, ++ 0x35, 0x7c, 0x16, 0x9b, 0xa9, 0x17, 0xa7, 0x6d, 0x67, 0x51, 0xc5, 0x65, ++ 0x2c, 0xb1, 0xfd, 0x49, 0x1d, 0x5f, 0x91, 0xef, 0x23, 0x6a, 0xe7, 0x2c, ++ 0x50, 0x5b, 0xf2, 0xe7, 0x77, 0x53, 0xdf, 0x32, 0x0e, 0x15, 0x3f, 0x20, ++ 0x97, 0x7d, 0x27, 0xf4, 0x59, 0x64, 0x6d, 0xcc, 0x76, 0xd2, 0xdf, 0xaf, ++ 0x62, 0x5d, 0xe2, 0xdf, 0xb8, 0xc4, 0x52, 0xc4, 0x4b, 0xe8, 0xd7, 0x45, ++ 0xf4, 0xd5, 0x6b, 0x32, 0xf7, 0xa0, 0x3d, 0x15, 0x08, 0x97, 0x28, 0xf7, ++ 0xe0, 0xd6, 0x8c, 0x0b, 0xb1, 0x61, 0x0f, 0xd6, 0x51, 0x27, 0xce, 0xa4, ++ 0xf8, 0xb9, 0x86, 0x75, 0xa3, 0x47, 0x67, 0x3a, 0xe9, 0x37, 0xeb, 0x46, ++ 0xbd, 0x3c, 0xa6, 0xf3, 0x70, 0x63, 0x35, 0x8f, 0x3d, 0xb4, 0xcb, 0x36, ++ 0xc6, 0x86, 0x23, 0x09, 0x13, 0x9d, 0xd4, 0xd5, 0x13, 0x89, 0x06, 0xdc, ++ 0x4b, 0xbd, 0x1d, 0x4a, 0x7c, 0x8a, 0x3a, 0x0a, 0xa3, 0x83, 0x73, 0xfc, ++ 0x58, 0x42, 0xb5, 0xf3, 0xab, 0xdb, 0x33, 0xff, 0x62, 0x45, 0xa7, 0x8b, ++ 0x9c, 0xa2, 0x0b, 0x99, 0xcf, 0x8f, 0xe8, 0x81, 0xfe, 0x3b, 0x55, 0x17, ++ 0xf5, 0xd8, 0xb6, 0xcb, 0xc0, 0xf6, 0x5d, 0x75, 0xb4, 0xbb, 0x8c, 0xe5, ++ 0xaf, 0x1a, 0xa0, 0x0e, 0xa6, 0xea, 0xe1, 0x08, 0x79, 0x81, 0xe8, 0x41, ++ 0xda, 0xbc, 0x8f, 0x63, 0xee, 0xe6, 0x3d, 0x1f, 0x1e, 0x4f, 0x7c, 0x97, ++ 0xbf, 0xc3, 0xca, 0x5d, 0x19, 0xf1, 0x79, 0xf1, 0xb7, 0x7f, 0x70, 0xe4, ++ 0x62, 0x6f, 0xa1, 0xdc, 0x16, 0x96, 0xb3, 0xac, 0xcd, 0x67, 0xe3, 0x4a, ++ 0x51, 0xb4, 0x84, 0x71, 0x65, 0x7f, 0x22, 0x10, 0x7e, 0xc6, 0x8e, 0x7d, ++ 0x4e, 0xda, 0x8e, 0xd8, 0x47, 0x8f, 0x6d, 0x1b, 0xcb, 0xce, 0xda, 0xc6, ++ 0xe4, 0x59, 0x0e, 0xd5, 0x9f, 0x9a, 0xea, 0x73, 0x39, 0xbb, 0x70, 0x26, ++ 0xf5, 0x5e, 0xdb, 0x8e, 0xd3, 0x82, 0x8f, 0x0e, 0x38, 0x06, 0x9c, 0x68, ++ 0x33, 0x2f, 0xa5, 0xbe, 0xab, 0x19, 0x6f, 0x8a, 0x78, 0x30, 0x4f, 0x1d, ++ 0xfe, 0x0b, 0x94, 0x0e, 0x64, 0xad, 0x12, 0xfe, 0x6e, 0x0e, 0x89, 0xbe, ++ 0xaf, 0xc2, 0xad, 0xc3, 0x0e, 0x14, 0x0d, 0x28, 0x78, 0xd2, 0xac, 0xc7, ++ 0x90, 0x37, 0x87, 0xbb, 0x6a, 0xf2, 0x52, 0x7b, 0x9e, 0x2e, 0x1e, 0x3f, ++ 0xfa, 0x8c, 0xc4, 0x85, 0x7b, 0x47, 0x3d, 0xf0, 0x25, 0x15, 0x78, 0x88, ++ 0x2b, 0x65, 0x46, 0x3d, 0xf5, 0xaa, 0xa1, 0x32, 0x69, 0xe2, 0x6b, 0x19, ++ 0xd2, 0xa6, 0x07, 0xc2, 0xb8, 0x93, 0xf3, 0x52, 0xfe, 0xc0, 0x95, 0xb8, ++ 0x83, 0xe5, 0x36, 0xf0, 0xde, 0x86, 0xd1, 0x6a, 0x1e, 0x5e, 0x1e, 0xd3, ++ 0x79, 0x34, 0xe0, 0xf6, 0xe1, 0x5a, 0x44, 0xab, 0xf5, 0xa0, 0x5f, 0x75, ++ 0xa0, 0x7a, 0x40, 0xf4, 0xae, 0x62, 0xe5, 0x02, 0x05, 0xe6, 0xa7, 0x8b, ++ 0xa1, 0xce, 0xfd, 0x38, 0xdf, 0xfd, 0x53, 0xb2, 0xbe, 0x6c, 0x0d, 0xd9, ++ 0x98, 0x2e, 0x3a, 0x16, 0x3b, 0xf9, 0x57, 0xce, 0x85, 0xc8, 0x2b, 0x7d, ++ 0x48, 0xac, 0x15, 0x1d, 0x7f, 0x12, 0x36, 0x30, 0xb2, 0x54, 0x74, 0xb1, ++ 0xcc, 0x47, 0x7d, 0x01, 0x67, 0xe7, 0x7f, 0x2a, 0x67, 0x95, 0xb8, 0xaf, ++ 0x87, 0x87, 0x6c, 0x8e, 0xe3, 0x67, 0xbe, 0xa8, 0xc7, 0x45, 0xe7, 0xe4, ++ 0x34, 0x6e, 0xd5, 0x80, 0xbf, 0xc8, 0xb8, 0x19, 0xb7, 0x71, 0x9e, 0xf6, ++ 0x26, 0xd4, 0xa5, 0x2e, 0xa8, 0xb3, 0x5c, 0x4c, 0x9c, 0x47, 0x4c, 0x1d, ++ 0xed, 0xc3, 0xcc, 0xb5, 0x86, 0xcb, 0xd1, 0xa5, 0x29, 0xee, 0x6d, 0xf5, ++ 0x8b, 0x24, 0xa7, 0xf6, 0x57, 0x1a, 0x50, 0xcb, 0x18, 0xff, 0xb7, 0x6b, ++ 0x70, 0x16, 0x19, 0x8a, 0x9a, 0xa8, 0x6f, 0x42, 0xbc, 0x0a, 0xce, 0x0a, ++ 0x03, 0x0a, 0x73, 0x66, 0xf4, 0x69, 0x10, 0xec, 0x89, 0x16, 0x19, 0xf7, ++ 0xe0, 0xb6, 0x14, 0xac, 0xd2, 0x08, 0xf3, 0xa1, 0x88, 0x41, 0x8e, 0x1b, ++ 0xf0, 0x15, 0xd1, 0x3f, 0x56, 0x93, 0x57, 0xac, 0x1d, 0x16, 0x39, 0x3c, ++ 0xe4, 0x1b, 0x86, 0xbf, 0x0d, 0xcc, 0xe1, 0x5b, 0xf4, 0xe0, 0x24, 0xf3, ++ 0xd8, 0xd5, 0xd4, 0xfd, 0x48, 0xe2, 0x1e, 0x34, 0xa6, 0x8e, 0x58, 0x1e, ++ 0xf2, 0xc8, 0x22, 0xa3, 0xf6, 0x4c, 0x17, 0x62, 0xf4, 0x0d, 0xe1, 0x47, ++ 0x6b, 0xe8, 0x1b, 0x3e, 0x64, 0x12, 0xea, 0x71, 0xb2, 0x0b, 0x74, 0x8c, ++ 0xae, 0xc7, 0xd7, 0x46, 0x67, 0x61, 0x3c, 0xb1, 0x01, 0x77, 0x66, 0xc8, ++ 0x95, 0xfa, 0xaf, 0xc2, 0x1d, 0xc3, 0x57, 0xe1, 0xf6, 0x9d, 0x46, 0x70, ++ 0x03, 0x75, 0xbd, 0x76, 0x98, 0x81, 0x72, 0xba, 0xb4, 0x5b, 0xd0, 0x95, ++ 0xf0, 0x45, 0xea, 0x22, 0xaf, 0xa7, 0x2c, 0x0a, 0x1c, 0xe6, 0x5f, 0x2d, ++ 0x5e, 0x8a, 0x17, 0x35, 0x28, 0xfe, 0xdd, 0xf5, 0x2f, 0x31, 0xb7, 0x17, ++ 0xd9, 0x11, 0x9d, 0x69, 0xfc, 0xc0, 0x7a, 0x50, 0xa3, 0x7f, 0x47, 0x10, ++ 0x9f, 0xd3, 0xf0, 0xbc, 0xf5, 0xd0, 0x2a, 0xb9, 0x7e, 0x9b, 0x13, 0xa5, ++ 0x2a, 0xaf, 0x49, 0x9b, 0x82, 0x4b, 0x75, 0x44, 0xe2, 0x8f, 0x6b, 0x33, ++ 0x6b, 0x25, 0xcf, 0x96, 0x27, 0x2f, 0x24, 0x16, 0x3f, 0x91, 0xf0, 0xa2, ++ 0x37, 0x95, 0xe3, 0x56, 0x37, 0x65, 0x84, 0x53, 0xb9, 0x51, 0xda, 0x27, ++ 0x71, 0x25, 0x8a, 0xf5, 0xfc, 0x5d, 0xd2, 0xa7, 0xb7, 0xc4, 0x91, 0x60, ++ 0x9b, 0x4d, 0x9c, 0x0b, 0xda, 0x6b, 0x9f, 0x03, 0x25, 0x46, 0x73, 0xce, ++ 0x56, 0xfb, 0x56, 0xd0, 0x56, 0x35, 0x54, 0xf4, 0xf5, 0x70, 0xac, 0xb4, ++ 0x55, 0xd6, 0xbb, 0x83, 0xba, 0xf0, 0xf4, 0xad, 0xa2, 0xbd, 0xce, 0x42, ++ 0x59, 0x5f, 0x2b, 0xf1, 0x01, 0x8c, 0xeb, 0x16, 0x8e, 0x9a, 0x95, 0x79, ++ 0x7e, 0xda, 0x8c, 0x5b, 0x53, 0x51, 0xb4, 0xa5, 0x6a, 0xa3, 0x27, 0x65, ++ 0xad, 0xca, 0x95, 0xc3, 0xb0, 0x68, 0x8d, 0xe8, 0x62, 0x32, 0x8f, 0xa7, ++ 0x7a, 0x73, 0x8e, 0xd3, 0xe9, 0x9a, 0x5f, 0x29, 0xc8, 0xde, 0x83, 0x18, ++ 0xf3, 0x8f, 0x39, 0x91, 0x16, 0x58, 0x29, 0x91, 0x3b, 0x6e, 0xf9, 0x98, ++ 0x53, 0x7a, 0x22, 0xfa, 0xc6, 0xc5, 0x0e, 0xa3, 0xe3, 0x15, 0x25, 0x88, ++ 0xeb, 0x29, 0x43, 0x59, 0x5f, 0x27, 0x5e, 0x08, 0xe9, 0xbe, 0xef, 0x2a, ++ 0xfa, 0x99, 0x0d, 0x78, 0x05, 0x3f, 0xe3, 0xb5, 0xa2, 0xbe, 0x09, 0x3c, ++ 0x94, 0x79, 0x15, 0xa7, 0x28, 0xab, 0xda, 0xf7, 0xa1, 0xb5, 0xcc, 0x78, ++ 0x86, 0xe3, 0x77, 0x2b, 0x6f, 0x65, 0xa6, 0xda, 0xe2, 0x55, 0x58, 0xbd, ++ 0x53, 0xec, 0x4f, 0x0f, 0xc6, 0x89, 0xbd, 0x6d, 0x66, 0x85, 0x70, 0x79, ++ 0x89, 0x4f, 0x94, 0xbf, 0x45, 0xb0, 0x85, 0xfe, 0x41, 0x3b, 0xb0, 0xc7, ++ 0xd0, 0x6a, 0x63, 0xb2, 0x33, 0x09, 0x1b, 0x4b, 0x73, 0x7a, 0x8e, 0x28, ++ 0x6d, 0xa3, 0xbe, 0x52, 0x94, 0xfa, 0xf2, 0x7e, 0x90, 0x5b, 0xb3, 0x38, ++ 0x57, 0xf7, 0x3f, 0xad, 0x11, 0xef, 0xf9, 0x75, 0x2b, 0x98, 0x83, 0x55, ++ 0x72, 0x3c, 0xef, 0xf6, 0xc5, 0xad, 0xd2, 0xdc, 0x58, 0x9a, 0x7f, 0xa0, ++ 0x88, 0x4d, 0x06, 0xc9, 0xed, 0x3b, 0x71, 0x69, 0x48, 0x6f, 0xfd, 0xae, ++ 0x22, 0x65, 0xf5, 0xf0, 0x06, 0xa5, 0xd0, 0xcf, 0xcb, 0x38, 0x39, 0x22, ++ 0x7d, 0x48, 0x5f, 0x13, 0xcc, 0xc9, 0x72, 0x63, 0x10, 0x5f, 0x7a, 0xc4, ++ 0x9e, 0x4b, 0xf1, 0x27, 0x3f, 0x96, 0x73, 0x4c, 0xae, 0x3e, 0x1f, 0x0f, ++ 0x17, 0xed, 0xd5, 0x87, 0xb5, 0x99, 0x15, 0x58, 0xcd, 0xbc, 0x76, 0x75, ++ 0xa6, 0x85, 0xba, 0xdf, 0x48, 0x7c, 0x67, 0x46, 0xa0, 0xe5, 0x74, 0x7c, ++ 0xce, 0x3e, 0x74, 0xff, 0x24, 0x56, 0xf0, 0xfe, 0xcf, 0x9d, 0xa8, 0x68, ++ 0x61, 0x79, 0xfb, 0xbe, 0x29, 0xf8, 0x7d, 0xae, 0xcc, 0x47, 0x78, 0x98, ++ 0x1d, 0xe7, 0xf7, 0xda, 0x1c, 0xb1, 0xc5, 0xce, 0xbd, 0xae, 0xb6, 0xe7, ++ 0x5c, 0x38, 0x82, 0x85, 0x63, 0x66, 0x31, 0xf3, 0xaf, 0xba, 0xe0, 0xf9, ++ 0x9c, 0x50, 0x67, 0x16, 0x5a, 0xc0, 0x03, 0xe9, 0x4b, 0xf4, 0x72, 0xa2, ++ 0x26, 0xa7, 0x97, 0x4f, 0x2a, 0x7b, 0x3e, 0x76, 0xec, 0x49, 0x48, 0xdf, ++ 0x45, 0x36, 0x2f, 0x6d, 0xcc, 0x94, 0x22, 0xee, 0x15, 0x1d, 0x49, 0x7b, ++ 0xba, 0x5f, 0x64, 0x5a, 0xbb, 0x53, 0xec, 0xd8, 0xc2, 0x08, 0x65, 0xe8, ++ 0xb6, 0xe7, 0x2d, 0xc7, 0x25, 0x8f, 0x9c, 0x17, 0x9f, 0x65, 0x4c, 0x85, ++ 0xbe, 0x6f, 0x73, 0xe5, 0xf8, 0x66, 0x81, 0x2b, 0x58, 0xd6, 0x80, 0x59, ++ 0xe0, 0x0a, 0x32, 0xe6, 0xbf, 0x00, 0x63, 0x9d, 0x3d, 0xde, 0x35, 0xf9, ++ 0xb6, 0xbb, 0xcc, 0x00, 0xed, 0x5a, 0xb8, 0x54, 0x44, 0x59, 0xb3, 0x2b, ++ 0xc3, 0xb9, 0x95, 0xdc, 0x06, 0xb8, 0x93, 0xf7, 0xcb, 0x79, 0xff, 0xc5, ++ 0x90, 0x0b, 0x97, 0x4e, 0x97, 0xbe, 0xaf, 0x42, 0xc7, 0xce, 0x28, 0x2a, ++ 0x17, 0x06, 0x30, 0x69, 0x73, 0x89, 0x02, 0xef, 0x75, 0xe1, 0x8e, 0x9d, ++ 0x1f, 0x5a, 0x15, 0x36, 0x17, 0x33, 0x62, 0xe3, 0x8a, 0x8a, 0xed, 0x8b, ++ 0x84, 0xff, 0xba, 0x88, 0xef, 0xe4, 0xa2, 0xc2, 0xad, 0x5d, 0x65, 0xe4, ++ 0xb0, 0xc2, 0xe1, 0x02, 0xd9, 0x9b, 0x54, 0x68, 0x5a, 0x44, 0xb8, 0xdc, ++ 0x2c, 0x9b, 0xc3, 0x0a, 0x97, 0xfd, 0x56, 0xea, 0xd0, 0x14, 0x2e, 0x7b, ++ 0x96, 0x73, 0x30, 0xf7, 0x69, 0x61, 0x7e, 0xef, 0x81, 0x3b, 0xa2, 0xb7, ++ 0x6c, 0x52, 0x3a, 0xb1, 0x3c, 0x64, 0x98, 0x92, 0x53, 0x5f, 0xa9, 0xe8, ++ 0xc1, 0xd3, 0x08, 0x12, 0x6f, 0x5f, 0xc6, 0xc8, 0x60, 0xdc, 0x25, 0x76, ++ 0xb4, 0x29, 0x73, 0x4e, 0x9e, 0x5b, 0x29, 0x8f, 0x3b, 0x27, 0x8f, 0x79, ++ 0x1a, 0x2a, 0x9e, 0x6c, 0x70, 0x11, 0xb7, 0xfe, 0x0e, 0x6d, 0x3b, 0x55, ++ 0x2c, 0xb1, 0xb9, 0xf9, 0xdf, 0x11, 0x7f, 0x2f, 0x2a, 0xcd, 0x95, 0x07, ++ 0x3a, 0xe9, 0xdf, 0xef, 0x2f, 0x2c, 0x41, 0x68, 0x9a, 0x82, 0x2a, 0xa3, ++ 0x83, 0xf9, 0xf1, 0x87, 0x56, 0xdc, 0x49, 0x3a, 0x6b, 0x40, 0x2b, 0x89, ++ 0x44, 0x29, 0x5b, 0x93, 0x72, 0xcd, 0xf0, 0x20, 0xfb, 0xe9, 0x20, 0xef, ++ 0xf7, 0xe0, 0x2e, 0xda, 0xce, 0x5d, 0x8c, 0x65, 0x77, 0x31, 0x96, 0xdd, ++ 0x35, 0xfa, 0x2f, 0xbc, 0x3e, 0xdd, 0xfe, 0xbd, 0x29, 0x55, 0xb0, 0x65, ++ 0x27, 0xe3, 0x82, 0xe8, 0x77, 0x33, 0x7d, 0x47, 0xe2, 0x02, 0x28, 0x93, ++ 0x85, 0x93, 0x9c, 0xc7, 0x25, 0x9a, 0x1e, 0xcc, 0xe2, 0xeb, 0xae, 0x73, ++ 0x79, 0x5f, 0x21, 0xb6, 0xc8, 0x3c, 0xba, 0x70, 0x1b, 0x65, 0x0c, 0x86, ++ 0xfe, 0xcb, 0x42, 0x95, 0xf8, 0xee, 0x85, 0xf7, 0x73, 0xf3, 0x7a, 0xe4, ++ 0x2c, 0x07, 0x54, 0xc4, 0x4e, 0xe9, 0xf3, 0x7b, 0x6c, 0x4e, 0xf1, 0xa2, ++ 0xc9, 0xdc, 0x6d, 0xe7, 0xd1, 0xf9, 0x62, 0x2a, 0x6b, 0x47, 0xa3, 0xe8, ++ 0xe6, 0xb8, 0x57, 0x0f, 0x3f, 0x96, 0xd7, 0x4b, 0x61, 0xbc, 0x0a, 0xd5, ++ 0xe2, 0xa1, 0xff, 0xe4, 0x72, 0x95, 0xb6, 0x51, 0xe1, 0xb6, 0xd5, 0xfc, ++ 0x2f, 0xdc, 0xd6, 0xcb, 0xff, 0xc2, 0x73, 0xa7, 0xf3, 0xbf, 0x13, 0xfe, ++ 0xe9, 0x62, 0xc7, 0xf5, 0xe8, 0xdd, 0x65, 0x59, 0xc5, 0x81, 0x7a, 0x6c, ++ 0x19, 0xfd, 0x48, 0xbc, 0xbc, 0x40, 0x1e, 0x7b, 0x0e, 0xe8, 0x47, 0x2e, ++ 0xc1, 0x22, 0xbf, 0x5f, 0x95, 0xbe, 0x2d, 0x6c, 0x34, 0xaf, 0x62, 0x9f, ++ 0x8c, 0x80, 0xd5, 0x53, 0xfd, 0xa2, 0xd0, 0x46, 0x41, 0xdf, 0xc5, 0xf4, ++ 0x73, 0x68, 0x2e, 0xea, 0x7b, 0x65, 0x46, 0xea, 0x36, 0x29, 0x4b, 0x87, ++ 0xa7, 0x96, 0xef, 0x20, 0x1f, 0x3e, 0x4d, 0x5d, 0x17, 0xfc, 0xc8, 0x9b, ++ 0xcf, 0x2b, 0x98, 0x4b, 0xa4, 0x44, 0x97, 0x32, 0xbe, 0x5c, 0xae, 0x28, ++ 0xb6, 0x74, 0xe4, 0x6c, 0x1f, 0xa2, 0xb7, 0xf8, 0xf4, 0x12, 0x43, 0xec, ++ 0x28, 0x48, 0x5c, 0xd1, 0xc3, 0xcd, 0x84, 0xed, 0x53, 0x09, 0xc4, 0x1c, ++ 0x91, 0xe6, 0xa6, 0xb5, 0x89, 0xb9, 0xda, 0xf1, 0x7c, 0x2e, 0xba, 0x87, ++ 0x38, 0xae, 0x1a, 0xb2, 0x0e, 0x42, 0x5b, 0x19, 0x16, 0xdd, 0x75, 0x28, ++ 0xe7, 0xf2, 0xce, 0x28, 0x79, 0x97, 0x6a, 0xcb, 0xe8, 0x8c, 0x88, 0x6c, ++ 0x52, 0x87, 0xb2, 0x5f, 0xc0, 0xbf, 0x72, 0xba, 0xa8, 0x80, 0x67, 0x40, ++ 0x78, 0x97, 0x8e, 0x0d, 0x8c, 0xf3, 0x65, 0x03, 0x7e, 0xfa, 0x42, 0x35, ++ 0x4a, 0x1f, 0x88, 0x60, 0xfd, 0xa8, 0x86, 0x92, 0x07, 0x2c, 0x6b, 0x6e, ++ 0xa8, 0x87, 0x5c, 0xf6, 0xb2, 0x22, 0xc9, 0x9d, 0x9c, 0x49, 0x62, 0x16, ++ 0xf1, 0xad, 0x3d, 0xa5, 0xe0, 0x6a, 0xc6, 0xd3, 0x28, 0x71, 0xa8, 0xdd, ++ 0xc6, 0x39, 0xab, 0x73, 0x4e, 0xc4, 0x45, 0x1b, 0x5a, 0xc5, 0xfb, 0xad, ++ 0xc4, 0xc0, 0x56, 0x62, 0x9a, 0x65, 0xbd, 0x7f, 0x39, 0x3a, 0xcb, 0x22, ++ 0x37, 0x13, 0x0b, 0x6b, 0xc9, 0x89, 0x25, 0x7e, 0x5f, 0x8e, 0x35, 0x8c, ++ 0xfd, 0xc5, 0x49, 0x3b, 0x9f, 0xa2, 0xee, 0x18, 0xa3, 0x32, 0x8c, 0x71, ++ 0x94, 0xfd, 0x69, 0x72, 0x5c, 0xe1, 0xbb, 0x95, 0xc9, 0x0d, 0x8c, 0x75, ++ 0x1e, 0x54, 0x0c, 0x5c, 0x86, 0x3b, 0x19, 0xcf, 0xef, 0xd8, 0xe9, 0x47, ++ 0x7a, 0xd1, 0x55, 0x94, 0xef, 0x1e, 0xac, 0x4f, 0x19, 0x92, 0x43, 0x45, ++ 0x83, 0x8b, 0xc8, 0xb7, 0x33, 0x82, 0x3b, 0x92, 0x8f, 0x95, 0x61, 0x49, ++ 0x0b, 0x10, 0x4c, 0x16, 0xf0, 0x2d, 0x2a, 0x6b, 0x47, 0x30, 0x92, 0xe7, ++ 0x63, 0xdb, 0x39, 0x5e, 0x24, 0xeb, 0x70, 0x2d, 0x98, 0xcf, 0x58, 0x20, ++ 0xf6, 0xa5, 0x31, 0xc7, 0x2c, 0x51, 0x0c, 0xdf, 0x1e, 0xfa, 0xa9, 0xe4, ++ 0x3d, 0x57, 0x24, 0x0b, 0xb1, 0x4f, 0xcf, 0x2e, 0x76, 0x74, 0x12, 0x47, ++ 0xf4, 0x8d, 0xbf, 0x53, 0xf4, 0xf6, 0x13, 0xca, 0x2b, 0xd8, 0x37, 0xf6, ++ 0x2a, 0x86, 0xc6, 0xdc, 0xca, 0xe8, 0x98, 0xf4, 0x35, 0x81, 0xbe, 0xcc, ++ 0x9f, 0xea, 0x6b, 0xea, 0xfa, 0xcb, 0xa2, 0xf3, 0xd6, 0x6c, 0xae, 0xce, ++ 0xe7, 0x89, 0x4b, 0xcf, 0xe3, 0xc7, 0x32, 0x27, 0x62, 0x97, 0x5e, 0xf4, ++ 0xa4, 0xce, 0xad, 0x0b, 0xf4, 0x27, 0xb6, 0xd9, 0xfe, 0xd9, 0x92, 0x11, ++ 0x7b, 0x55, 0x19, 0x33, 0x2f, 0xce, 0xe7, 0x2c, 0xb5, 0xd4, 0x41, 0x9f, ++ 0x7d, 0x6f, 0x9f, 0xf9, 0x29, 0x64, 0xed, 0x6b, 0x8b, 0xe9, 0x9b, 0xd5, ++ 0x28, 0x26, 0x26, 0x06, 0x43, 0x3e, 0x14, 0x57, 0xc9, 0x3a, 0xce, 0xb9, ++ 0xdc, 0x7f, 0xc3, 0x4e, 0x86, 0x64, 0x1b, 0x73, 0x1a, 0x89, 0x7f, 0xb5, ++ 0x9c, 0xef, 0x1c, 0xce, 0xac, 0xa7, 0x0d, 0x5d, 0x27, 0x36, 0xe4, 0xca, ++ 0xd9, 0xd0, 0x47, 0xd7, 0x17, 0x54, 0x90, 0xfb, 0x69, 0x15, 0x76, 0xde, ++ 0xd7, 0xa4, 0x5c, 0x9f, 0xb7, 0xab, 0xcf, 0x67, 0x1e, 0x2d, 0xca, 0xe7, ++ 0x66, 0x17, 0x94, 0xff, 0x38, 0x1d, 0x5c, 0xf6, 0x67, 0xe8, 0x40, 0xe2, ++ 0x81, 0xe4, 0x04, 0xa2, 0x83, 0xf3, 0xf3, 0xf2, 0xfe, 0x44, 0x35, 0x71, ++ 0xef, 0x42, 0x5d, 0xcc, 0xcc, 0xeb, 0x62, 0x31, 0xb1, 0x4b, 0xfe, 0x5b, ++ 0x38, 0x65, 0x7a, 0xf1, 0xa2, 0x26, 0xe3, 0x5e, 0x8c, 0xf5, 0x1c, 0xaf, ++ 0x9b, 0xba, 0x58, 0x1e, 0xaa, 0x44, 0xf0, 0xbc, 0x78, 0x50, 0xcb, 0xd8, ++ 0xf1, 0x21, 0x79, 0xa6, 0xfc, 0xf6, 0xe3, 0x05, 0xea, 0xe2, 0x8e, 0xe1, ++ 0xc5, 0xb8, 0x8b, 0xfe, 0x94, 0xe3, 0x90, 0xb9, 0xd8, 0xb0, 0x76, 0x58, ++ 0xda, 0x14, 0x8c, 0xfb, 0xd9, 0xd9, 0x71, 0xfe, 0x71, 0x5e, 0xfe, 0x0a, ++ 0xe5, 0x97, 0x67, 0x07, 0xb2, 0x16, 0x2d, 0xcf, 0x11, 0x64, 0x2c, 0xc6, ++ 0x14, 0xdc, 0xb1, 0xac, 0x83, 0xe6, 0x3c, 0xc4, 0xaa, 0xf5, 0x7e, 0x89, ++ 0x8f, 0xfd, 0xc4, 0x03, 0x07, 0xf3, 0xc8, 0xa2, 0x48, 0x94, 0xfe, 0xac, ++ 0x5e, 0xe5, 0x80, 0x5a, 0xef, 0x40, 0x27, 0xde, 0x30, 0x8d, 0xde, 0x75, ++ 0xf8, 0x14, 0xba, 0xbc, 0x16, 0xf6, 0xb2, 0x9d, 0xee, 0x54, 0x09, 0xda, ++ 0xeb, 0x69, 0x56, 0x2b, 0x3d, 0xd8, 0x91, 0x8a, 0xb7, 0x12, 0x16, 0x18, ++ 0x73, 0x1a, 0xfe, 0x2a, 0x11, 0xd0, 0x5b, 0x36, 0x90, 0xb7, 0x2c, 0xef, ++ 0x73, 0xc3, 0xaf, 0xe4, 0x72, 0xb4, 0x01, 0x55, 0xd6, 0x09, 0x23, 0x94, ++ 0xbd, 0xc7, 0xce, 0xf7, 0xfc, 0xd3, 0xa5, 0x1f, 0x3f, 0xe2, 0x19, 0xa9, ++ 0xeb, 0x47, 0xe9, 0x5c, 0x05, 0xcb, 0xe7, 0xea, 0xf1, 0xa8, 0x62, 0x59, ++ 0x0b, 0x42, 0x4e, 0xfb, 0xfe, 0xb6, 0x4c, 0x5d, 0xeb, 0x0d, 0xea, 0xab, ++ 0x56, 0x6e, 0x6d, 0x52, 0xd7, 0xa2, 0x4c, 0x0a, 0x8e, 0xfc, 0xd1, 0xf5, ++ 0xf9, 0x20, 0xe4, 0xb9, 0x89, 0xdb, 0x58, 0x89, 0xfd, 0xf9, 0xf5, 0x39, ++ 0x57, 0xe4, 0xbd, 0x2f, 0xef, 0x35, 0x24, 0x6f, 0x11, 0x9d, 0x4b, 0x7f, ++ 0x62, 0x0b, 0xd7, 0x15, 0x0b, 0x06, 0x76, 0x65, 0x16, 0xd2, 0x16, 0x7f, ++ 0x6b, 0x8d, 0x7a, 0xa7, 0x96, 0xbd, 0x51, 0xcd, 0xad, 0xb7, 0x4b, 0xd9, ++ 0x42, 0xb9, 0x8b, 0x89, 0x09, 0x8d, 0x18, 0x3e, 0xaf, 0x4d, 0xc9, 0x75, ++ 0x0b, 0x6d, 0xde, 0xc6, 0x72, 0xd2, 0xae, 0xe0, 0xef, 0x7f, 0x59, 0xfb, ++ 0xce, 0x6b, 0xaf, 0xd5, 0x95, 0x6b, 0xef, 0xee, 0x62, 0xc9, 0xdd, 0xfb, ++ 0x53, 0x45, 0xac, 0xf3, 0x4e, 0x9e, 0x07, 0x16, 0xca, 0x7c, 0xea, 0x82, ++ 0x32, 0xc4, 0x79, 0xe3, 0x4d, 0x6b, 0xcf, 0x79, 0x65, 0x96, 0x3b, 0xcf, ++ 0x2f, 0xe3, 0xc4, 0x1c, 0xe3, 0x55, 0xeb, 0xc8, 0x79, 0x65, 0xd2, 0x17, ++ 0x94, 0xb9, 0x1c, 0x63, 0xf5, 0x8f, 0x58, 0x43, 0xb9, 0xb9, 0xc9, 0xd2, ++ 0x7d, 0xdc, 0x33, 0x23, 0xad, 0x7f, 0x75, 0xc5, 0x3c, 0xbd, 0x63, 0xa6, ++ 0x43, 0x9e, 0xd9, 0xb8, 0x91, 0xcd, 0xcd, 0x4d, 0x5c, 0xe6, 0xc6, 0xb5, ++ 0xa0, 0x30, 0x37, 0xd7, 0xe5, 0xeb, 0x17, 0xda, 0xbd, 0xae, 0xe8, 0xfc, ++ 0x76, 0x0b, 0xd7, 0xaf, 0xb8, 0x40, 0xee, 0xef, 0x5c, 0x50, 0xee, 0xb7, ++ 0x7f, 0xa4, 0xde, 0x2f, 0x1c, 0xe7, 0x5f, 0x3f, 0xa0, 0x9e, 0x7f, 0xde, ++ 0x9c, 0x3f, 0x2f, 0xe8, 0xbf, 0xea, 0x82, 0xf2, 0x35, 0x17, 0x94, 0x7f, ++ 0x59, 0xfd, 0xf8, 0x7e, 0xd6, 0x5d, 0x50, 0xcf, 0x5e, 0xab, 0xc6, 0x53, ++ 0x67, 0x7d, 0x1e, 0x4d, 0x45, 0x08, 0x98, 0x4e, 0x05, 0x7e, 0xfa, 0xbe, ++ 0xff, 0xe9, 0x0b, 0xd6, 0xac, 0x9b, 0xce, 0xfa, 0xfe, 0x79, 0x9c, 0x33, ++ 0x56, 0x1c, 0x91, 0x18, 0x56, 0x44, 0xee, 0x2c, 0x3c, 0xb0, 0x4e, 0x3b, ++ 0x97, 0x67, 0x15, 0x62, 0x65, 0x45, 0xac, 0x24, 0xd2, 0x00, 0xff, 0xd8, ++ 0x2c, 0xff, 0x9b, 0x09, 0x59, 0xb7, 0xfc, 0x80, 0x5c, 0xca, 0xf0, 0xed, ++ 0xc7, 0x2c, 0xff, 0x4f, 0xd3, 0x6f, 0x15, 0xa3, 0xc2, 0x83, 0xab, 0x13, ++ 0x1f, 0x5f, 0x4f, 0x8d, 0x40, 0x59, 0xd6, 0xe0, 0x63, 0x7e, 0x05, 0xe7, ++ 0x35, 0xf3, 0x30, 0xe5, 0xaf, 0x45, 0xf2, 0x3d, 0xf5, 0x58, 0x43, 0x98, ++ 0xf1, 0x39, 0xf7, 0xbc, 0x76, 0x49, 0x46, 0xf7, 0x45, 0x95, 0xdc, 0x33, ++ 0xd9, 0xf6, 0xd0, 0x1f, 0xc8, 0x77, 0x3a, 0x29, 0x97, 0xc5, 0xbe, 0x80, ++ 0x0d, 0x09, 0xcb, 0x7a, 0x8a, 0x79, 0xaa, 0x3c, 0xeb, 0xff, 0x79, 0xfa, ++ 0xf7, 0xd6, 0x84, 0xd7, 0x89, 0xb7, 0x8c, 0xa9, 0xed, 0xf9, 0x51, 0x19, ++ 0x31, 0x99, 0x2f, 0xd9, 0x27, 0xea, 0x98, 0x51, 0xb7, 0x71, 0x2f, 0xfd, ++ 0x6e, 0x7e, 0x40, 0xf7, 0x27, 0xf1, 0xef, 0x96, 0xbf, 0x46, 0x0f, 0x0e, ++ 0x29, 0x85, 0x75, 0xe2, 0x0b, 0xd7, 0x83, 0x2b, 0x62, 0x2e, 0x8e, 0x6f, ++ 0x8f, 0xcd, 0xf7, 0x8b, 0x88, 0x71, 0x88, 0x39, 0x23, 0xb3, 0xfc, 0x5b, ++ 0x12, 0xf6, 0x38, 0xc9, 0x17, 0x15, 0x1c, 0x6b, 0x98, 0xe5, 0xef, 0x4e, ++ 0x7b, 0xb1, 0x9d, 0xf1, 0xb8, 0xc4, 0x68, 0xc0, 0x23, 0x69, 0x15, 0xb7, ++ 0xdd, 0xef, 0xc5, 0x5a, 0x72, 0xd1, 0x8d, 0x7d, 0xdf, 0x80, 0x71, 0xa9, ++ 0x13, 0xb7, 0xd2, 0xfe, 0xd6, 0xf5, 0x15, 0xdb, 0x39, 0xc8, 0xfa, 0x3e, ++ 0x27, 0xea, 0x2f, 0xad, 0x40, 0xbc, 0xa6, 0x18, 0xdf, 0x37, 0x1d, 0xcc, ++ 0x7b, 0xca, 0x30, 0x64, 0x63, 0xa2, 0xe4, 0xb2, 0x82, 0x73, 0xa2, 0x37, ++ 0x87, 0xbd, 0x2e, 0xf9, 0xf1, 0x58, 0xfe, 0x5b, 0x2b, 0x5b, 0xb3, 0xdd, ++ 0xc6, 0x5f, 0x47, 0xc4, 0xb4, 0xe3, 0x25, 0x90, 0xe3, 0x69, 0x5d, 0xe7, ++ 0x3d, 0x57, 0x6e, 0x51, 0xe6, 0x44, 0x02, 0x13, 0x8b, 0x15, 0x07, 0xc2, ++ 0x81, 0x8a, 0x58, 0x65, 0x24, 0x8c, 0x65, 0x99, 0x2e, 0x9f, 0xcf, 0x7e, ++ 0x56, 0x1d, 0xc1, 0xe9, 0x45, 0x26, 0x73, 0x60, 0x38, 0x97, 0x51, 0xf7, ++ 0x4d, 0xd4, 0xeb, 0x66, 0xf3, 0x0f, 0x56, 0xd6, 0xf6, 0x7b, 0x37, 0x62, ++ 0x9a, 0x65, 0xad, 0xa3, 0x7e, 0x1d, 0xd4, 0xe3, 0xcf, 0xf2, 0xfa, 0x15, ++ 0x9d, 0x96, 0x8d, 0xfd, 0xde, 0x3a, 0x46, 0xfd, 0xba, 0xd9, 0x9e, 0x9b, ++ 0xed, 0x95, 0x8c, 0x9d, 0xaf, 0xe7, 0x62, 0xca, 0xb3, 0xcc, 0x96, 0xa1, ++ 0x52, 0x9e, 0xf5, 0xf9, 0xa3, 0x4a, 0x01, 0xb7, 0xff, 0xd4, 0x98, 0x5e, ++ 0x99, 0x92, 0x83, 0x88, 0xfe, 0xfd, 0xd4, 0xbf, 0x60, 0xb8, 0xcc, 0x41, ++ 0xbd, 0xac, 0xfb, 0xf4, 0x02, 0xa3, 0x4c, 0xd6, 0x15, 0x4c, 0x33, 0x22, ++ 0xf8, 0x76, 0x8b, 0x07, 0x6f, 0x26, 0xca, 0xed, 0x71, 0x5f, 0x3a, 0xd7, ++ 0xb2, 0x1e, 0x0f, 0xf9, 0xf1, 0x73, 0xa3, 0x2e, 0xbc, 0x40, 0xd5, 0x31, ++ 0xa9, 0x79, 0x91, 0x20, 0xce, 0x76, 0xa5, 0x66, 0x73, 0xbe, 0xbc, 0xd8, ++ 0x92, 0xc2, 0x46, 0xda, 0x93, 0xdf, 0x11, 0x01, 0xde, 0x48, 0x18, 0xc1, ++ 0xcd, 0xec, 0x7f, 0xd8, 0xdb, 0x40, 0xfe, 0xad, 0x36, 0x91, 0xaa, 0xc5, ++ 0x4b, 0x22, 0x46, 0x7c, 0x2b, 0xfe, 0xc3, 0x1a, 0x22, 0xce, 0x17, 0x85, ++ 0x64, 0x6d, 0x6e, 0x0e, 0x8e, 0x6b, 0x0e, 0x3c, 0x1b, 0x9c, 0x8e, 0x28, ++ 0xdd, 0xb1, 0xcc, 0x78, 0xcb, 0xfa, 0xa1, 0x57, 0xfa, 0x91, 0xb1, 0xfc, ++ 0x86, 0xe3, 0x50, 0x6c, 0x2c, 0xdc, 0x92, 0x6a, 0xa0, 0xbe, 0x2f, 0xec, ++ 0xff, 0xdf, 0xad, 0x49, 0xaf, 0xf4, 0xcf, 0x5c, 0x9e, 0xf1, 0xec, 0xc8, ++ 0x1f, 0xc5, 0xee, 0x97, 0xac, 0xe7, 0xec, 0x36, 0x17, 0xb9, 0x73, 0x71, ++ 0x50, 0xda, 0xfb, 0x17, 0x8e, 0x4f, 0xda, 0x2c, 0xf4, 0x23, 0x7a, 0xcb, ++ 0xba, 0xc5, 0x9f, 0xb7, 0xa4, 0x44, 0x7f, 0x82, 0x57, 0xc7, 0x2c, 0x4c, ++ 0x97, 0xf3, 0x87, 0xed, 0xb2, 0x71, 0xea, 0xab, 0x8b, 0x36, 0xc4, 0xd8, ++ 0xcb, 0x3c, 0x4e, 0x76, 0x51, 0x68, 0x76, 0x9e, 0xb6, 0x89, 0xdc, 0x7e, ++ 0xc8, 0x5b, 0x89, 0x2d, 0x26, 0xed, 0xce, 0x50, 0x2f, 0x76, 0x42, 0x72, ++ 0x53, 0x39, 0x77, 0x61, 0xd2, 0xeb, 0xc0, 0x56, 0xd3, 0x89, 0x76, 0x43, ++ 0xd5, 0xe5, 0xba, 0x23, 0x24, 0xe7, 0x2e, 0xf8, 0x6b, 0x14, 0x6c, 0x0f, ++ 0xab, 0x58, 0x6f, 0x74, 0xf9, 0xe5, 0xfa, 0x92, 0x90, 0x9c, 0x2b, 0x58, ++ 0x43, 0x9d, 0xc4, 0x35, 0x05, 0x1b, 0x0c, 0x79, 0xbe, 0x98, 0xe3, 0xbe, ++ 0x31, 0x58, 0xd6, 0x76, 0xb3, 0xf1, 0x8a, 0x32, 0x48, 0x9c, 0x17, 0x2e, ++ 0xf7, 0xde, 0xcd, 0xf3, 0x03, 0x71, 0x12, 0x31, 0x3d, 0x56, 0x42, 0x3f, ++ 0xdd, 0xd2, 0x37, 0x87, 0xf5, 0x14, 0x72, 0x1c, 0xa7, 0x6f, 0x1b, 0x24, ++ 0x7e, 0x06, 0xfc, 0x3f, 0x65, 0xf2, 0x34, 0xe4, 0x9d, 0x47, 0xcd, 0x1a, ++ 0xfe, 0x93, 0x9c, 0xb7, 0x4a, 0xc3, 0xb9, 0xf1, 0x07, 0xd0, 0xdb, 0x4b, ++ 0x94, 0x79, 0xc1, 0x0a, 0xe6, 0x00, 0x71, 0xe2, 0xfb, 0xc8, 0x98, 0x13, ++ 0x9b, 0x53, 0x86, 0xb6, 0xcf, 0xe6, 0x6e, 0x4e, 0xea, 0xc2, 0xc9, 0x1c, ++ 0x3f, 0xa0, 0x4d, 0x28, 0x85, 0xf3, 0x39, 0x82, 0x0d, 0xe4, 0xe2, 0x82, ++ 0x6f, 0x71, 0xeb, 0xc9, 0x06, 0x49, 0xdb, 0xdc, 0xfe, 0x58, 0xda, 0xc3, ++ 0x43, 0xe3, 0xe1, 0xf5, 0xaf, 0x4d, 0xfb, 0xfc, 0x6b, 0xd2, 0xf0, 0xb7, ++ 0xa5, 0x0b, 0x76, 0x59, 0xf0, 0x6d, 0xc1, 0x36, 0x8b, 0x7c, 0x33, 0x97, ++ 0x73, 0x75, 0x49, 0x4e, 0x03, 0x79, 0x3e, 0xf6, 0xde, 0xcd, 0x4f, 0xd1, ++ 0xd6, 0x5d, 0xe4, 0xf2, 0x5b, 0x8d, 0x78, 0x54, 0x9e, 0xd7, 0x19, 0x21, ++ 0xdd, 0x57, 0xa4, 0xf8, 0xb1, 0xa5, 0xfe, 0x77, 0x9c, 0x4f, 0x72, 0xdc, ++ 0xf4, 0xa7, 0x4a, 0x72, 0xf3, 0x21, 0x7e, 0x26, 0x18, 0xe0, 0x67, 0x1e, ++ 0xe4, 0xf3, 0x77, 0xb1, 0x9f, 0x4d, 0xe9, 0xa9, 0x3e, 0xa0, 0xe0, 0x1a, ++ 0xb6, 0xd5, 0x18, 0x82, 0x73, 0x69, 0xfd, 0x7f, 0x59, 0x59, 0xef, 0xd4, ++ 0x7d, 0x11, 0x20, 0x87, 0x80, 0xb3, 0xad, 0x5e, 0xce, 0x15, 0x34, 0x86, ++ 0xe5, 0x5c, 0x41, 0x9b, 0x91, 0x93, 0x4f, 0x7c, 0xb7, 0x9b, 0xb8, 0x7d, ++ 0xee, 0xfc, 0x42, 0x2c, 0x32, 0x71, 0x7b, 0x0a, 0xb1, 0xa2, 0x88, 0x60, ++ 0x91, 0xdb, 0xff, 0x5c, 0xba, 0x9e, 0x5c, 0x5c, 0x9e, 0x7f, 0xbb, 0x39, ++ 0xe7, 0x1e, 0xff, 0xb3, 0xe9, 0x2b, 0x71, 0xdb, 0xae, 0x30, 0xda, 0x77, ++ 0xc9, 0x86, 0x23, 0xe6, 0x60, 0xa1, 0x80, 0x7f, 0x14, 0x9a, 0xff, 0x38, ++ 0x75, 0x72, 0x94, 0x72, 0x1e, 0x3b, 0x4f, 0x4e, 0xd1, 0x21, 0xfc, 0x77, ++ 0x24, 0xdc, 0x48, 0x87, 0xde, 0xb7, 0xe2, 0x36, 0xe7, 0xf0, 0xfa, 0xef, ++ 0x4c, 0xf8, 0x91, 0xb5, 0xb9, 0xe7, 0xbf, 0xbb, 0x25, 0x47, 0xec, 0x49, ++ 0xc5, 0xa3, 0x4c, 0x79, 0xf3, 0xf3, 0xab, 0x87, 0x65, 0x6e, 0xdf, 0x48, ++ 0xc8, 0xbd, 0xe8, 0x37, 0x54, 0xe8, 0x7e, 0x95, 0xb1, 0xb4, 0xdf, 0x14, ++ 0xfb, 0xb5, 0xec, 0x67, 0xfb, 0xac, 0x18, 0xf7, 0x44, 0x02, 0xad, 0xf5, ++ 0xbc, 0xae, 0x2d, 0x40, 0xac, 0x8a, 0x7a, 0x2a, 0x35, 0xbc, 0xfe, 0xba, ++ 0x71, 0x9f, 0xdf, 0x1c, 0x87, 0xff, 0x92, 0xf1, 0xa9, 0x22, 0x90, 0xa3, ++ 0xab, 0x1f, 0x87, 0x05, 0x5e, 0xff, 0xba, 0xc4, 0x1c, 0xa8, 0x91, 0xb8, ++ 0xb5, 0xa4, 0xe1, 0xb4, 0x35, 0x27, 0x62, 0x64, 0x8f, 0x51, 0x86, 0xf7, ++ 0x2f, 0xd7, 0xe3, 0x33, 0x1d, 0x47, 0xef, 0xd5, 0xa6, 0xf4, 0xf1, 0x5e, ++ 0xe8, 0xff, 0x6f, 0x1f, 0x85, 0x38, 0x47, 0x7b, 0x68, 0x90, 0x31, 0x48, ++ 0xbc, 0x2b, 0x62, 0xce, 0x29, 0x63, 0xf9, 0x54, 0xe1, 0xb9, 0x47, 0x7e, ++ 0x5c, 0x0a, 0xe7, 0x1a, 0x36, 0x0f, 0xce, 0xc5, 0x30, 0xcb, 0xea, 0x36, ++ 0x7c, 0xf9, 0xe7, 0x67, 0x9c, 0xb3, 0xcc, 0xd1, 0x2b, 0x9c, 0x58, 0x4c, ++ 0x3f, 0x68, 0xfc, 0x4b, 0x27, 0xa2, 0xbe, 0x62, 0xc6, 0x56, 0x59, 0x17, ++ 0x3a, 0x5e, 0x3f, 0x69, 0x4d, 0x18, 0xf5, 0x68, 0xcc, 0xc8, 0xf3, 0x4c, ++ 0x07, 0xed, 0xdb, 0xc2, 0x23, 0xa6, 0xdc, 0x17, 0x9c, 0x89, 0xc7, 0x1c, ++ 0xb4, 0x15, 0xb7, 0xa1, 0xb7, 0xfe, 0xbd, 0x52, 0x81, 0xd2, 0x88, 0x33, ++ 0x38, 0x01, 0x3d, 0xbc, 0x5e, 0xa1, 0x1f, 0x56, 0xcd, 0x33, 0x65, 0x0a, ++ 0xde, 0x4e, 0x04, 0xcc, 0x40, 0x3e, 0x2e, 0x9d, 0xe2, 0xdc, 0xbd, 0x93, ++ 0x30, 0xda, 0x9f, 0xca, 0x9f, 0xff, 0x22, 0x3d, 0x35, 0xa7, 0x15, 0x7b, ++ 0x74, 0xbb, 0x37, 0x25, 0xf0, 0x9e, 0xa3, 0x01, 0xef, 0xed, 0x31, 0x8b, ++ 0x98, 0x8b, 0x89, 0x9d, 0xba, 0xdd, 0x5b, 0x12, 0x98, 0x74, 0xf2, 0xda, ++ 0x29, 0x73, 0x36, 0x31, 0x4d, 0xe5, 0xb5, 0xb0, 0xd8, 0x59, 0x4c, 0x63, ++ 0x7c, 0x2d, 0x8d, 0x78, 0xdd, 0xa5, 0xe3, 0xd0, 0x4a, 0x8c, 0x0a, 0xe6, ++ 0xba, 0x68, 0x72, 0x24, 0x75, 0x7f, 0xb3, 0xa3, 0x9e, 0x39, 0xaf, 0x5f, ++ 0x71, 0x19, 0xdf, 0x63, 0x5e, 0x2f, 0x6b, 0x61, 0x61, 0xda, 0xa4, 0x93, ++ 0x15, 0x76, 0x4c, 0x57, 0x23, 0x0a, 0xb1, 0xb0, 0x02, 0xb7, 0x6b, 0x1b, ++ 0x3e, 0xab, 0x46, 0xfa, 0x71, 0x7d, 0x83, 0xbb, 0xa9, 0x72, 0xbc, 0xa0, ++ 0x13, 0xc4, 0x3c, 0x11, 0xe6, 0x25, 0x06, 0xd4, 0xf2, 0x88, 0xe8, 0xc6, ++ 0xdf, 0x94, 0x1c, 0x13, 0x59, 0x35, 0x77, 0xdf, 0xd8, 0x3b, 0x25, 0x28, ++ 0x0d, 0x13, 0xab, 0x7e, 0xe2, 0xfb, 0xef, 0xd5, 0x3b, 0x5a, 0x22, 0x78, ++ 0xef, 0x32, 0xe4, 0xbf, 0x6d, 0x5b, 0x6e, 0x77, 0xe4, 0x83, 0x98, 0x3b, ++ 0x60, 0x59, 0x8c, 0x93, 0x3e, 0x28, 0xb3, 0x39, 0x1e, 0xfa, 0x1a, 0xe7, ++ 0x66, 0x4d, 0xfa, 0x0f, 0xd6, 0xe7, 0x9c, 0x36, 0x07, 0x70, 0x17, 0x47, ++ 0x3a, 0x6e, 0x79, 0xcb, 0xf8, 0xc0, 0x7a, 0x33, 0xc1, 0x5c, 0xd9, 0x90, ++ 0x67, 0x43, 0x73, 0xb0, 0xcd, 0x74, 0x36, 0x2f, 0x55, 0x14, 0xf4, 0x18, ++ 0xf3, 0xb4, 0x12, 0xc6, 0xa9, 0x6e, 0xfa, 0x75, 0xcc, 0x6b, 0x04, 0xf7, ++ 0x80, 0xe5, 0xd2, 0xeb, 0xd6, 0xb9, 0x22, 0x77, 0xde, 0x32, 0xd2, 0x20, ++ 0x58, 0x10, 0x6e, 0x7b, 0xca, 0x68, 0x41, 0x4f, 0x66, 0x10, 0xbd, 0x99, ++ 0x5c, 0x3f, 0x59, 0xcc, 0xf9, 0x98, 0x7e, 0xd6, 0xad, 0x2b, 0x8e, 0x08, ++ 0xf7, 0x3a, 0x73, 0xcb, 0x5e, 0x23, 0x8a, 0xcd, 0x99, 0x3b, 0x6f, 0x39, ++ 0xd5, 0xd0, 0xcf, 0xff, 0xb9, 0x3a, 0x43, 0xa8, 0xfc, 0xd8, 0x3a, 0x65, ++ 0x11, 0xe9, 0xa3, 0xe3, 0x96, 0xa7, 0x8c, 0x3b, 0x6f, 0x69, 0x5f, 0xf4, ++ 0x4d, 0x6c, 0xca, 0xb4, 0xff, 0xc9, 0x7e, 0xca, 0x59, 0xa7, 0x34, 0x72, ++ 0xa8, 0xed, 0x9a, 0xc0, 0x9d, 0xb7, 0xa4, 0x17, 0xf5, 0xb2, 0x8f, 0x55, ++ 0x8c, 0x2f, 0xb9, 0x3a, 0x51, 0xc6, 0xf6, 0x8f, 0xd3, 0x41, 0x49, 0x64, ++ 0xa2, 0x6d, 0x7e, 0xe0, 0x03, 0x6b, 0x5e, 0x5f, 0x91, 0xad, 0x03, 0x17, ++ 0x75, 0xf0, 0xa0, 0xe9, 0xcc, 0x06, 0x1c, 0xb6, 0x0e, 0x3a, 0x7c, 0xd4, ++ 0x41, 0x92, 0x3a, 0xc8, 0xd6, 0x18, 0xe1, 0x77, 0xa9, 0x83, 0x79, 0x63, ++ 0xeb, 0xd6, 0x95, 0x44, 0xe0, 0x74, 0x18, 0xaf, 0x3a, 0x9c, 0x9c, 0x0b, ++ 0x97, 0xb1, 0x8e, 0x7a, 0xbb, 0xf3, 0x96, 0x8b, 0x17, 0xd9, 0x3a, 0xff, ++ 0xb2, 0x3b, 0xb0, 0xc1, 0xde, 0x3b, 0xd7, 0x9d, 0x59, 0xc3, 0xa3, 0x99, ++ 0xc7, 0x7d, 0x3c, 0x7a, 0x98, 0xb3, 0xdc, 0x4c, 0x5d, 0x35, 0x71, 0x1c, ++ 0x2b, 0x28, 0xd7, 0x46, 0xfe, 0x6e, 0xe5, 0xef, 0x0e, 0xfe, 0x96, 0xf9, ++ 0x51, 0xcf, 0xca, 0x16, 0x3b, 0x2b, 0x9b, 0x83, 0xf2, 0x78, 0x88, 0x57, ++ 0x32, 0x26, 0xf7, 0x57, 0xae, 0x09, 0xc4, 0xd8, 0xc6, 0xfd, 0xa5, 0xb2, ++ 0x6f, 0xc8, 0x65, 0xc4, 0x7d, 0x4e, 0x88, 0x7c, 0x7a, 0x6b, 0x3b, 0xb2, ++ 0xc4, 0xde, 0xdf, 0xe7, 0xb0, 0x97, 0xb2, 0x55, 0x70, 0x7e, 0x5e, 0x58, ++ 0x34, 0x34, 0xc3, 0x63, 0xc0, 0xe7, 0x36, 0xe2, 0xcc, 0xf9, 0x13, 0xd4, ++ 0x81, 0xd8, 0xc9, 0x3d, 0xd4, 0x5f, 0x27, 0xeb, 0x1c, 0x65, 0x2c, 0xdb, ++ 0xcd, 0xfe, 0xed, 0xf5, 0xdb, 0xb0, 0xfd, 0x9c, 0x0c, 0xba, 0x79, 0x9c, ++ 0xed, 0xed, 0x35, 0x7e, 0x53, 0x76, 0xb4, 0x5e, 0xf6, 0x53, 0x3a, 0x31, ++ 0x6c, 0xcf, 0xbb, 0x42, 0x2e, 0x73, 0x11, 0x79, 0x82, 0x65, 0xfd, 0xd4, ++ 0x68, 0x9c, 0xef, 0xb0, 0xed, 0xea, 0x50, 0x9b, 0x3b, 0xe0, 0xc6, 0x90, ++ 0xbd, 0x06, 0x6e, 0x59, 0x45, 0xb6, 0x7d, 0x89, 0x2c, 0x75, 0xcd, 0x9b, ++ 0x68, 0x78, 0xeb, 0xd2, 0x1f, 0x90, 0x27, 0x8a, 0xfc, 0x73, 0x70, 0x92, ++ 0x31, 0x35, 0xaa, 0xc5, 0xdb, 0x45, 0xd6, 0x32, 0xc3, 0x19, 0xbe, 0x16, ++ 0xf1, 0x16, 0x27, 0xfb, 0x6b, 0x26, 0xa7, 0x3c, 0x95, 0xc7, 0xee, 0x7d, ++ 0x69, 0x3d, 0xb6, 0x5f, 0xc9, 0xf1, 0xd3, 0xde, 0xb1, 0x42, 0xfc, 0x09, ++ 0x92, 0xcf, 0x7a, 0xe0, 0x8c, 0xe8, 0xfe, 0x26, 0x47, 0x57, 0xd0, 0x05, ++ 0xfa, 0x58, 0xa9, 0xc8, 0x1b, 0xa7, 0xec, 0x82, 0xc7, 0x6e, 0x6d, 0x8d, ++ 0x8d, 0xd1, 0xf1, 0xf9, 0x2e, 0x78, 0xb4, 0xb5, 0xe9, 0x42, 0xec, 0xf2, ++ 0x68, 0x6d, 0x09, 0xf1, 0x77, 0x59, 0xab, 0x0f, 0xdb, 0xdc, 0xe3, 0x48, ++ 0xe6, 0xa5, 0x52, 0xd9, 0x8b, 0x47, 0xdf, 0xaf, 0x70, 0x1a, 0xb9, 0x76, ++ 0x35, 0xb6, 0xdb, 0xe2, 0xd0, 0x70, 0xce, 0x77, 0x75, 0xad, 0xc5, 0x21, ++ 0xfb, 0x5f, 0x89, 0x4a, 0xe9, 0x7c, 0xbd, 0x1c, 0x7e, 0x2d, 0x76, 0xd9, ++ 0xf8, 0xc5, 0x36, 0x4a, 0x81, 0x25, 0x89, 0x0b, 0xfb, 0x97, 0xfe, 0xa4, ++ 0xdf, 0xae, 0x2a, 0x15, 0x13, 0xf6, 0xb3, 0x92, 0x83, 0x99, 0x18, 0x06, ++ 0x53, 0x53, 0xf7, 0xe8, 0xe9, 0x87, 0xd8, 0xfe, 0x81, 0x38, 0xe7, 0x69, ++ 0xb6, 0x21, 0xfb, 0xf7, 0x64, 0xcf, 0xde, 0xd4, 0xfd, 0x7a, 0x22, 0x5b, ++ 0x65, 0x19, 0x81, 0x0d, 0x7b, 0x89, 0x7f, 0xd1, 0x16, 0xa9, 0x6f, 0x59, ++ 0xaf, 0xcd, 0x0b, 0x22, 0x3b, 0xcd, 0x89, 0xc1, 0xb9, 0xc0, 0x40, 0x52, ++ 0xf6, 0x53, 0x9d, 0x89, 0xad, 0x66, 0x1e, 0x19, 0xad, 0xae, 0xd3, 0xba, ++ 0x55, 0xd9, 0x0b, 0xf5, 0xc1, 0x97, 0x7b, 0x8c, 0x5a, 0xad, 0x47, 0xcd, ++ 0xee, 0x67, 0x7c, 0xd9, 0x0d, 0xcc, 0x2e, 0x13, 0x0c, 0xa8, 0x32, 0xa2, ++ 0xbd, 0x55, 0x98, 0x0b, 0x7f, 0xb5, 0x8d, 0xcb, 0xf1, 0x6f, 0xab, 0x46, ++ 0x70, 0xa5, 0xf0, 0x4a, 0xf5, 0x7d, 0x6b, 0x88, 0xdc, 0xe4, 0xee, 0xb9, ++ 0xff, 0xa7, 0x34, 0xbf, 0xee, 0xd4, 0x3e, 0x9d, 0xf3, 0xf2, 0xf3, 0x05, ++ 0xba, 0x3f, 0xad, 0x88, 0x8e, 0x84, 0x4b, 0x25, 0xb0, 0x95, 0x71, 0xf6, ++ 0xbf, 0xe6, 0x46, 0xb0, 0x8f, 0xff, 0x7f, 0x76, 0xa5, 0xec, 0x4d, 0xb5, ++ 0xac, 0x60, 0x60, 0x5e, 0xb8, 0x8a, 0x63, 0x78, 0x96, 0xf7, 0x7b, 0x33, ++ 0x6f, 0x59, 0xa7, 0xa6, 0x1b, 0xfd, 0xcb, 0x18, 0xec, 0x06, 0xc6, 0x75, ++ 0x6d, 0x52, 0xfd, 0xef, 0xee, 0x95, 0x83, 0xbb, 0x82, 0x63, 0xf9, 0x7e, ++ 0xa0, 0x4e, 0x4b, 0xaa, 0xa5, 0x65, 0xa2, 0xd7, 0x81, 0xf1, 0x57, 0xa6, ++ 0x3c, 0x3b, 0x28, 0xf0, 0x59, 0x7b, 0x5d, 0xa5, 0x77, 0x88, 0xbe, 0x3e, ++ 0xa4, 0x45, 0xe3, 0xd4, 0xbb, 0x7b, 0x1a, 0xc7, 0x7c, 0xf7, 0xdc, 0x2f, ++ 0xd9, 0xe3, 0xac, 0x36, 0x66, 0x72, 0x8c, 0x0a, 0xb4, 0xb9, 0xff, 0x99, ++ 0x5f, 0x7f, 0x6d, 0x24, 0xfb, 0x1a, 0xb2, 0x9a, 0xe8, 0x1b, 0x45, 0xac, ++ 0x73, 0xb5, 0xf9, 0xf0, 0x8c, 0xae, 0x7a, 0xdd, 0x77, 0x37, 0x6d, 0x34, ++ 0x34, 0xf7, 0xd7, 0x16, 0x6d, 0xda, 0xfc, 0x16, 0x47, 0x7d, 0x5b, 0xc2, ++ 0x8e, 0x55, 0x9c, 0x57, 0x23, 0x3a, 0x57, 0x79, 0xc7, 0x42, 0x4d, 0x20, ++ 0x3c, 0xd7, 0x1e, 0x3f, 0x70, 0x6b, 0x3a, 0x81, 0x6d, 0x29, 0x69, 0x53, ++ 0xc1, 0xb2, 0xc0, 0xdb, 0x96, 0x7f, 0x7a, 0x02, 0x5b, 0x32, 0x9f, 0xc4, ++ 0x4d, 0x07, 0xc9, 0x8d, 0xf5, 0xd6, 0x38, 0xf4, 0x68, 0xee, 0xd9, 0xd4, ++ 0x1c, 0x59, 0xdb, 0x96, 0xbd, 0x45, 0xb7, 0x24, 0x02, 0x70, 0x97, 0x13, ++ 0x83, 0xc7, 0x02, 0xf2, 0x2c, 0xd3, 0x8b, 0x6c, 0x8b, 0x94, 0xa9, 0xd5, ++ 0xc6, 0x90, 0x25, 0x73, 0x94, 0xb5, 0xd0, 0xfe, 0xb2, 0xdc, 0x3e, 0x09, ++ 0x1a, 0x5e, 0x8d, 0xae, 0xbd, 0x41, 0xae, 0xd7, 0x6c, 0x48, 0x1b, 0x0a, ++ 0xe6, 0x07, 0xa6, 0xa1, 0x6e, 0xe5, 0xab, 0xaf, 0x17, 0x05, 0x8a, 0x18, ++ 0x4f, 0xc4, 0xb7, 0x8c, 0x8d, 0xc7, 0xf0, 0x1b, 0x62, 0x90, 0xec, 0x19, ++ 0x4b, 0x4a, 0x3d, 0xb6, 0x35, 0x17, 0x69, 0xf1, 0x53, 0x43, 0xf6, 0x2f, ++ 0x5b, 0xd6, 0x35, 0x81, 0x37, 0xad, 0x68, 0x0d, 0xe5, 0x21, 0x5f, 0xcb, ++ 0xd5, 0x95, 0x32, 0xf9, 0xbd, 0x40, 0x4a, 0xe3, 0x2d, 0xa2, 0x93, 0x27, ++ 0xcd, 0x38, 0xb3, 0x01, 0xc1, 0xfd, 0x0f, 0x62, 0x6f, 0x19, 0x8a, 0xfd, ++ 0x8c, 0x71, 0x99, 0x52, 0xc9, 0x38, 0xea, 0xf4, 0x8f, 0xd8, 0xeb, 0x05, ++ 0x1d, 0xc4, 0x68, 0xe1, 0x97, 0x92, 0xf3, 0x39, 0xf1, 0x94, 0x51, 0x85, ++ 0x27, 0xb5, 0x1c, 0x57, 0x23, 0xd6, 0xe1, 0x07, 0x89, 0x79, 0x59, 0x7a, ++ 0x08, 0x39, 0xaf, 0xd1, 0x7e, 0x46, 0xf9, 0x0d, 0xfd, 0x1c, 0x78, 0x21, ++ 0xbd, 0x11, 0x0f, 0xca, 0x1a, 0xa2, 0x52, 0xdb, 0x5c, 0xe7, 0x90, 0xfe, ++ 0x36, 0x62, 0x6b, 0x46, 0xda, 0xfa, 0x20, 0xb6, 0xd7, 0xd8, 0x9d, 0x97, ++ 0x55, 0xb0, 0xfc, 0x83, 0xd8, 0x53, 0xc6, 0xe3, 0xf6, 0xdc, 0xc9, 0x73, ++ 0xaf, 0x5e, 0x53, 0x30, 0xaf, 0x14, 0x2a, 0xf3, 0x06, 0x87, 0x71, 0x33, ++ 0x1c, 0x55, 0xdf, 0xa4, 0xed, 0xc9, 0xbe, 0x9a, 0xaf, 0xc2, 0x59, 0xe5, ++ 0xa2, 0x6f, 0xde, 0x0a, 0x57, 0x95, 0x70, 0xf5, 0x02, 0x8f, 0x8e, 0xf2, ++ 0xbe, 0xe8, 0x36, 0xdc, 0x26, 0xba, 0x75, 0x12, 0x87, 0x7a, 0x24, 0xaf, ++ 0x33, 0x2a, 0xa9, 0x23, 0xbd, 0x95, 0x9c, 0x1e, 0xe5, 0xc4, 0x4c, 0xc6, ++ 0x47, 0x37, 0xf3, 0xb7, 0xb6, 0x77, 0xa9, 0xf7, 0x79, 0x7d, 0x65, 0xe4, ++ 0xf0, 0x96, 0xf5, 0x3e, 0x39, 0xfc, 0xfc, 0x40, 0x5d, 0xd6, 0x20, 0x4e, ++ 0xe1, 0x06, 0xbd, 0x39, 0x4e, 0xbc, 0x59, 0x6d, 0x9c, 0xb1, 0x62, 0xab, ++ 0xa4, 0x8c, 0xee, 0x8b, 0x29, 0x85, 0x3e, 0x16, 0xc0, 0x3f, 0xcd, 0x82, ++ 0x2b, 0x22, 0xcf, 0x14, 0x64, 0xbd, 0xb8, 0x51, 0x9e, 0xf5, 0xb5, 0xc8, ++ 0xf8, 0x5d, 0xb2, 0xee, 0x86, 0xe8, 0x84, 0x0b, 0x46, 0x76, 0x9f, 0xcc, ++ 0xd9, 0x0c, 0x0b, 0x81, 0x85, 0xbf, 0x67, 0x2e, 0x24, 0xf3, 0x53, 0x9b, ++ 0xad, 0x57, 0xb2, 0x41, 0x1f, 0x39, 0xfd, 0xa3, 0xd0, 0x5b, 0x12, 0xd4, ++ 0x75, 0x53, 0x48, 0x9e, 0xdf, 0x3b, 0x7d, 0x09, 0xd8, 0x3c, 0xde, 0x3c, ++ 0x89, 0xcf, 0xa1, 0x9c, 0xb9, 0xeb, 0xdc, 0xb1, 0x15, 0xa8, 0xa8, 0x8a, ++ 0xfa, 0x4a, 0x71, 0x19, 0xcf, 0xd7, 0x30, 0x3f, 0xf9, 0x22, 0x2a, 0x56, ++ 0xb6, 0x22, 0xc1, 0xb1, 0x97, 0x1b, 0x7f, 0xc5, 0x6b, 0xf7, 0x21, 0x99, ++ 0x72, 0x71, 0x1c, 0x3f, 0xb1, 0x2a, 0x6a, 0x44, 0x36, 0xd3, 0x5b, 0x66, ++ 0x30, 0x9f, 0xb6, 0x75, 0x41, 0xdc, 0x4e, 0x09, 0x47, 0xaa, 0x8b, 0xae, ++ 0x07, 0x73, 0xfb, 0x1a, 0xbd, 0x75, 0x8d, 0xd2, 0x41, 0x9b, 0xed, 0xa1, ++ 0xce, 0xa5, 0xac, 0x65, 0x2d, 0x0f, 0x9c, 0xa6, 0x8e, 0x3b, 0x78, 0x6e, ++ 0xf8, 0xdf, 0x84, 0x7a, 0x59, 0x31, 0x4e, 0x58, 0x71, 0xcd, 0x47, 0xbb, ++ 0x54, 0x57, 0x09, 0x9f, 0x5a, 0x1a, 0x7a, 0x8f, 0xf7, 0xb5, 0xbc, 0x9d, ++ 0x9e, 0xb9, 0x25, 0xa7, 0xcb, 0x30, 0x75, 0xf9, 0x6f, 0xf6, 0x75, 0x87, ++ 0x7d, 0xbd, 0x23, 0x7f, 0xfd, 0xcc, 0x2d, 0x3d, 0xc6, 0xcb, 0xbc, 0xde, ++ 0x4b, 0xdd, 0xab, 0x17, 0x49, 0xfd, 0x75, 0xa6, 0xd4, 0x67, 0x4a, 0x65, ++ 0xf4, 0xe4, 0xe7, 0xe3, 0x50, 0x7e, 0x3e, 0x26, 0xf2, 0x6d, 0x38, 0xd9, ++ 0x46, 0x3c, 0x5a, 0x0a, 0x13, 0x65, 0x01, 0xc1, 0x79, 0x91, 0x8b, 0x73, ++ 0x97, 0x11, 0xb9, 0xd6, 0x30, 0xde, 0x75, 0x3d, 0x53, 0x8a, 0x78, 0xc7, ++ 0x4c, 0xdb, 0x0e, 0xcf, 0xdc, 0x22, 0xfb, 0xde, 0xde, 0x52, 0x1a, 0x7d, ++ 0xb2, 0x65, 0x23, 0x45, 0x2e, 0x7b, 0xaf, 0xe9, 0x0c, 0xd7, 0x3b, 0xe6, ++ 0x65, 0x8b, 0x61, 0xc4, 0xce, 0x28, 0x2e, 0x8f, 0xe0, 0x43, 0x22, 0xdd, ++ 0xc8, 0xcc, 0x2b, 0x1e, 0x64, 0xce, 0x14, 0xcc, 0x50, 0xb7, 0x6d, 0x44, ++ 0xec, 0x43, 0xf6, 0xde, 0x37, 0xe7, 0xc4, 0x0a, 0x34, 0xea, 0x0e, 0xcc, ++ 0x0b, 0xcf, 0x64, 0xe6, 0x45, 0xbb, 0x34, 0x8b, 0x1d, 0xba, 0xff, 0x7a, ++ 0x2c, 0xb7, 0xeb, 0xed, 0x4b, 0x67, 0xdb, 0x4b, 0x39, 0xa7, 0x8f, 0x51, ++ 0x8e, 0x6d, 0x01, 0x91, 0xe3, 0x9b, 0x79, 0x39, 0x5a, 0x19, 0x4b, 0x4d, ++ 0xed, 0xda, 0x40, 0xef, 0x59, 0xbd, 0x3d, 0x63, 0xeb, 0xed, 0x3e, 0x9e, ++ 0x17, 0x33, 0xbf, 0x2f, 0xc2, 0xd1, 0x7a, 0x6f, 0x7e, 0x1f, 0x9b, 0xe4, ++ 0x6a, 0x82, 0xbf, 0x0d, 0x7f, 0xbd, 0xda, 0xd0, 0xc3, 0x0e, 0x9b, 0xd7, ++ 0xbb, 0x11, 0xb7, 0x39, 0xb3, 0x3c, 0xf3, 0xae, 0xc0, 0x23, 0x76, 0x39, ++ 0x17, 0x75, 0x52, 0x86, 0x47, 0xf3, 0xfe, 0x22, 0x7b, 0x0e, 0x1e, 0xb3, ++ 0x7f, 0xef, 0xe6, 0xdc, 0xba, 0xe8, 0xab, 0x85, 0x18, 0x25, 0xeb, 0xed, ++ 0xff, 0xc3, 0xf6, 0xfd, 0x21, 0x1c, 0xb7, 0xff, 0x67, 0x73, 0xf9, 0x16, ++ 0x7a, 0x4c, 0xd9, 0x3b, 0x53, 0x86, 0x6e, 0x7b, 0x0f, 0xb9, 0xac, 0x01, ++ 0x5c, 0x89, 0xcd, 0x9a, 0xac, 0x07, 0x93, 0xfb, 0x68, 0x62, 0x13, 0x9d, ++ 0x48, 0x6a, 0xa6, 0x37, 0x53, 0x3f, 0x35, 0x57, 0x32, 0xb1, 0xa7, 0xfe, ++ 0x03, 0x2b, 0x6a, 0xe7, 0x4f, 0x27, 0xac, 0xbd, 0xc6, 0xd1, 0x10, 0x3d, ++ 0xb8, 0xbd, 0xc8, 0xd6, 0x6f, 0xb8, 0xcd, 0xde, 0xff, 0x47, 0x99, 0x9f, ++ 0x49, 0x48, 0x1c, 0x9d, 0x83, 0xb4, 0x69, 0xc7, 0xe2, 0x96, 0xed, 0x9c, ++ 0x93, 0x9e, 0x54, 0x20, 0x7a, 0x09, 0xef, 0x4d, 0x30, 0x96, 0x75, 0x53, ++ 0x9f, 0xb1, 0x16, 0xe1, 0x67, 0x6b, 0xb0, 0x9b, 0x36, 0x36, 0x6e, 0x5a, ++ 0xd6, 0x3e, 0x62, 0x44, 0xe5, 0x3c, 0x15, 0xd9, 0x9a, 0x35, 0x48, 0x31, ++ 0x36, 0xed, 0x33, 0x1a, 0x3f, 0x57, 0x84, 0xb8, 0xdf, 0x0d, 0xdd, 0xb7, ++ 0x85, 0xa3, 0xb9, 0x97, 0xf3, 0x75, 0xd4, 0x14, 0xde, 0xe8, 0x3c, 0xb3, ++ 0x14, 0x46, 0x78, 0xb1, 0xe3, 0x27, 0xd6, 0xa4, 0xfd, 0xec, 0xb8, 0xeb, ++ 0x5f, 0x28, 0xc3, 0x46, 0x71, 0xde, 0x4a, 0xce, 0xf1, 0xbb, 0x01, 0x79, ++ 0x7e, 0x0d, 0xd4, 0xf5, 0x35, 0xb6, 0x8b, 0x0c, 0x7b, 0x43, 0xce, 0xd8, ++ 0x3e, 0x04, 0x5a, 0x36, 0x28, 0xe7, 0x72, 0x83, 0x4b, 0xc6, 0x4c, 0x8c, ++ 0xd6, 0x3f, 0x4b, 0x1e, 0x23, 0xf5, 0x8b, 0xf1, 0x84, 0xf9, 0xb4, 0x55, ++ 0x3b, 0xe3, 0xfb, 0xd6, 0x7e, 0x43, 0x5d, 0x4f, 0x6d, 0xc7, 0xca, 0xd9, ++ 0x56, 0x19, 0xdb, 0xba, 0x3d, 0xa0, 0x9b, 0xdb, 0xd9, 0xd6, 0xf1, 0xc4, ++ 0xd1, 0xa0, 0x9b, 0x6d, 0x3d, 0x6a, 0x4a, 0x6e, 0xe0, 0x6c, 0x6e, 0xe6, ++ 0xdc, 0x76, 0xa5, 0x02, 0xbe, 0xad, 0x94, 0x4b, 0xf2, 0xb7, 0xaf, 0x26, ++ 0xe4, 0x5d, 0x8f, 0x6f, 0x72, 0x3c, 0xd1, 0x8d, 0x2e, 0x34, 0xde, 0x5b, ++ 0x41, 0xfb, 0xa9, 0x44, 0xc1, 0xd6, 0x75, 0x1f, 0xf1, 0x0e, 0xb7, 0xb3, ++ 0xcc, 0xeb, 0x81, 0x39, 0x78, 0x21, 0xd4, 0xb8, 0x72, 0x0e, 0x9c, 0xe4, ++ 0x21, 0x81, 0xe6, 0x0d, 0x4a, 0x5c, 0x13, 0x5b, 0xbc, 0x2d, 0xad, 0x07, ++ 0x9b, 0x20, 0xd8, 0xdd, 0x4a, 0x7d, 0xcc, 0xc1, 0xfb, 0x0b, 0x45, 0x2e, ++ 0x67, 0x38, 0xe8, 0x08, 0x74, 0x3c, 0xcd, 0xf9, 0xad, 0x98, 0x97, 0xcb, ++ 0x53, 0x33, 0xf6, 0x7e, 0xcd, 0x56, 0x24, 0x33, 0x27, 0xde, 0xdd, 0x6b, ++ 0xc0, 0x79, 0xa8, 0xfe, 0x41, 0x0b, 0xf6, 0xbb, 0x21, 0x8d, 0x32, 0x0f, ++ 0xad, 0x32, 0x0f, 0xa5, 0xf4, 0xa7, 0x6b, 0x28, 0xf7, 0x7a, 0x5b, 0xee, ++ 0x39, 0x18, 0x36, 0x65, 0xfd, 0xcb, 0xa9, 0xdd, 0x86, 0x5e, 0x62, 0x67, ++ 0xe0, 0x4c, 0x17, 0xfb, 0x79, 0x9d, 0x32, 0xcf, 0xa3, 0xde, 0x27, 0x5b, ++ 0x84, 0xb7, 0xde, 0x87, 0xbe, 0x54, 0xe1, 0xdd, 0x11, 0x05, 0xe9, 0x80, ++ 0xf4, 0x71, 0x1f, 0x79, 0x5c, 0x97, 0x35, 0x59, 0x23, 0xd7, 0x77, 0x33, ++ 0xf7, 0x8f, 0x6a, 0xf4, 0x07, 0xea, 0x1d, 0xfa, 0x1c, 0xe8, 0x13, 0x6f, ++ 0x38, 0xa2, 0xf4, 0x01, 0xd3, 0x7b, 0x86, 0xd8, 0x70, 0x08, 0x1d, 0x16, ++ 0xaa, 0x6c, 0x7b, 0xf8, 0xd9, 0x88, 0xf1, 0xa1, 0x22, 0xb1, 0x3d, 0x4b, ++ 0x1d, 0xa8, 0x9c, 0x13, 0xd1, 0x41, 0x39, 0x7d, 0x76, 0x2c, 0xa0, 0xfb, ++ 0x5f, 0xa0, 0x3c, 0xdb, 0x29, 0xcf, 0x8a, 0xdc, 0x1c, 0xfa, 0x36, 0x2b, ++ 0xe2, 0xd3, 0x81, 0x96, 0xd5, 0xbc, 0xbe, 0x8d, 0xf2, 0x04, 0xfa, 0x14, ++ 0x0c, 0xb5, 0xf4, 0x90, 0x2b, 0x76, 0x50, 0x07, 0xe7, 0xe4, 0x71, 0xdb, ++ 0x73, 0xd6, 0x41, 0x2e, 0x50, 0x8c, 0xbd, 0xa6, 0xe0, 0xb7, 0x86, 0x61, ++ 0xda, 0xe9, 0x1e, 0xce, 0x48, 0xd4, 0xab, 0xa2, 0xd8, 0x10, 0x0c, 0xa8, ++ 0xe1, 0x35, 0x17, 0xe7, 0xa6, 0x12, 0xfb, 0xb5, 0xdd, 0xf6, 0x5e, 0xe5, ++ 0x1c, 0xb7, 0xfb, 0x83, 0x35, 0xea, 0x15, 0x7e, 0x26, 0xeb, 0x63, 0xb2, ++ 0x86, 0xd4, 0xeb, 0xc9, 0xed, 0xd7, 0x72, 0x51, 0x27, 0xb9, 0xeb, 0xcf, ++ 0x68, 0xc2, 0x7d, 0x0b, 0xe5, 0x7f, 0x69, 0x3d, 0x69, 0x97, 0x97, 0x72, ++ 0x2e, 0x9b, 0xa3, 0x97, 0xda, 0xe5, 0x7e, 0x69, 0x3d, 0xab, 0x39, 0xa7, ++ 0x94, 0x2b, 0x3c, 0x2f, 0x3c, 0xfa, 0x0d, 0x27, 0x31, 0xaf, 0x78, 0xee, ++ 0x62, 0x1c, 0x33, 0x4e, 0xd4, 0x9e, 0xac, 0xef, 0x64, 0x1c, 0x9b, 0xba, ++ 0x7f, 0xcb, 0xc2, 0xe3, 0x76, 0x1e, 0xde, 0x45, 0x3e, 0x7b, 0x74, 0x47, ++ 0x11, 0x84, 0xa3, 0xca, 0xfa, 0x5d, 0x73, 0xd9, 0xb9, 0x5c, 0x56, 0xf6, ++ 0x35, 0x5d, 0x66, 0x73, 0xc3, 0xa8, 0x2a, 0xb8, 0xfb, 0x49, 0x7b, 0xf8, ++ 0x84, 0xbb, 0x74, 0x62, 0x8f, 0x51, 0xe0, 0x2c, 0x47, 0x1f, 0x54, 0x89, ++ 0x93, 0x03, 0xe6, 0x62, 0x89, 0xcd, 0x7e, 0xd6, 0x0f, 0xc6, 0xd4, 0xa9, ++ 0xdc, 0xe6, 0x76, 0x0f, 0x2a, 0xba, 0xb6, 0x3a, 0x20, 0xfb, 0x47, 0x65, ++ 0x2f, 0xa8, 0xf4, 0x55, 0x92, 0x5f, 0x97, 0xfa, 0x38, 0xae, 0x51, 0xe8, ++ 0x4b, 0xf8, 0xc6, 0xfb, 0xa5, 0x85, 0x7d, 0x86, 0x51, 0x5b, 0xce, 0x5f, ++ 0x59, 0x2b, 0xb5, 0xec, 0x4c, 0x0d, 0xe7, 0xcb, 0x1e, 0xcd, 0xcb, 0x1e, ++ 0xfb, 0xd8, 0x75, 0xb5, 0xa9, 0xfb, 0xee, 0x82, 0xf9, 0xe7, 0x5d, 0xf2, ++ 0x0c, 0x46, 0xd6, 0x5c, 0xe5, 0x9e, 0x82, 0x2e, 0xe2, 0x50, 0x54, 0x6b, ++ 0x64, 0x9c, 0xd7, 0x7d, 0x6b, 0x39, 0x1f, 0x71, 0xaf, 0xec, 0x51, 0x2f, ++ 0xc4, 0xc8, 0x62, 0xe4, 0xd6, 0x3e, 0x65, 0x9f, 0x45, 0x6e, 0xbd, 0x93, ++ 0x76, 0x8f, 0xae, 0xf4, 0xef, 0xad, 0xac, 0xd7, 0xc9, 0x58, 0x78, 0x6e, ++ 0x7f, 0xf4, 0x10, 0xf5, 0x3a, 0xcc, 0x7b, 0x9b, 0xcf, 0xae, 0xa7, 0xc8, ++ 0x9a, 0x92, 0xc4, 0xde, 0xdf, 0x59, 0x6d, 0xe7, 0x95, 0x9d, 0xba, 0x57, ++ 0xbc, 0x26, 0x26, 0xcf, 0xdc, 0x46, 0xf3, 0xeb, 0xee, 0x4d, 0x1f, 0x79, ++ 0xe6, 0x36, 0x41, 0x5b, 0x42, 0x74, 0x33, 0xb9, 0x5d, 0x1c, 0x3d, 0x18, ++ 0x4d, 0xd4, 0x69, 0x5b, 0xa0, 0xc9, 0x7a, 0x33, 0xff, 0x7a, 0xb0, 0x3f, ++ 0x81, 0x68, 0xd1, 0xa5, 0x95, 0xe4, 0x5b, 0x88, 0x3a, 0x18, 0xa3, 0x1e, ++ 0x4d, 0xd4, 0x35, 0x6f, 0xe3, 0x98, 0xfc, 0x2b, 0x7b, 0x30, 0x9c, 0x68, ++ 0xfc, 0x2b, 0xc6, 0x11, 0x7f, 0x99, 0xcd, 0x75, 0xe2, 0x7f, 0xbd, 0x97, ++ 0x38, 0xb0, 0x29, 0xbf, 0xe6, 0xd5, 0x96, 0xf8, 0x35, 0xe5, 0xb7, 0x85, ++ 0x64, 0xbd, 0x4f, 0x2a, 0x37, 0xc1, 0x3c, 0xff, 0x04, 0xd6, 0xf5, 0x2b, ++ 0x78, 0xd2, 0x38, 0x81, 0xb5, 0x43, 0x22, 0xcf, 0x09, 0xac, 0xe9, 0x7f, ++ 0x09, 0x7b, 0xfa, 0x67, 0xa0, 0xc9, 0xd6, 0x4d, 0x07, 0x36, 0xec, 0x3c, ++ 0x88, 0xed, 0x29, 0x0b, 0xdb, 0x42, 0x1e, 0xac, 0x7f, 0x58, 0xc1, 0xf2, ++ 0xc0, 0x61, 0x6c, 0xd9, 0x69, 0xe1, 0xe2, 0x50, 0x27, 0x9a, 0xcd, 0x32, ++ 0x14, 0x57, 0xcd, 0x6b, 0x57, 0x59, 0xae, 0x6d, 0xb8, 0x23, 0xbf, 0x2f, ++ 0x79, 0x3f, 0xb1, 0x40, 0x85, 0xcf, 0x90, 0x3d, 0xc7, 0x51, 0xe5, 0xa6, ++ 0x4c, 0x93, 0xd2, 0x9a, 0x7f, 0x66, 0x79, 0x7d, 0xa6, 0xa8, 0x02, 0xa5, ++ 0x71, 0xec, 0x09, 0x9d, 0xc0, 0xd0, 0xd0, 0x07, 0xe5, 0x39, 0x7f, 0x99, ++ 0x20, 0x77, 0x90, 0x9c, 0xc3, 0xa4, 0x4d, 0x7d, 0xd2, 0xfb, 0x40, 0x62, ++ 0x77, 0x93, 0xf8, 0xe9, 0xe0, 0x49, 0x9c, 0x1c, 0xfc, 0x37, 0x2c, 0xd1, ++ 0x24, 0x7f, 0xb4, 0x3a, 0x9d, 0x11, 0xcb, 0xda, 0xd5, 0x10, 0xb7, 0x6a, ++ 0x8c, 0x5f, 0xb0, 0xed, 0x0a, 0x4c, 0x8f, 0xbc, 0x88, 0x6d, 0x1a, 0xdb, ++ 0x4a, 0xed, 0xc7, 0x0e, 0xc6, 0x75, 0x5f, 0xe4, 0x66, 0xf8, 0x52, 0x59, ++ 0xb3, 0x1a, 0xd1, 0x1d, 0xd5, 0xd0, 0x37, 0x56, 0x39, 0x8c, 0x8e, 0x7f, ++ 0x55, 0xea, 0x71, 0x7d, 0xe6, 0x24, 0x7e, 0x3e, 0x68, 0xef, 0xa5, 0x6a, ++ 0xfd, 0xae, 0x62, 0x75, 0x6e, 0x0b, 0xe9, 0xcd, 0xff, 0x43, 0x89, 0xc6, ++ 0x4b, 0x69, 0x53, 0x25, 0xcc, 0x09, 0x6e, 0x18, 0x94, 0x1c, 0xb1, 0x15, ++ 0xee, 0x3e, 0x3d, 0xbb, 0x94, 0x3c, 0xfb, 0xee, 0x05, 0xf1, 0x99, 0xd3, ++ 0x68, 0x97, 0x0e, 0x45, 0x0f, 0x1a, 0x6a, 0x27, 0x8e, 0x98, 0xfa, 0xc4, ++ 0xef, 0x1c, 0xc6, 0xd0, 0x77, 0x50, 0x8f, 0x55, 0x19, 0x7d, 0xe8, 0x32, ++ 0xe6, 0x61, 0x5b, 0x92, 0x26, 0x52, 0x49, 0xbd, 0xb5, 0xc3, 0xd1, 0x8b, ++ 0x3b, 0x02, 0xb5, 0x1b, 0xdf, 0x25, 0x97, 0xf3, 0x10, 0x53, 0x92, 0xe3, ++ 0x23, 0xcc, 0x5f, 0x7b, 0xb1, 0xe1, 0xe1, 0x08, 0xd6, 0xef, 0x32, 0xd1, ++ 0x93, 0x1c, 0xa1, 0x6c, 0x3f, 0x2c, 0x97, 0xbd, 0x34, 0x2d, 0xa1, 0xf8, ++ 0xb5, 0x2a, 0x02, 0x51, 0xf6, 0xd9, 0xa8, 0x46, 0x02, 0x7e, 0x55, 0x61, ++ 0xf4, 0x1f, 0x77, 0xa2, 0x9b, 0x65, 0xfa, 0x52, 0xb4, 0xb9, 0xa4, 0x9b, ++ 0xf1, 0x72, 0x16, 0x86, 0xc7, 0x7c, 0xd8, 0x37, 0xe6, 0xc1, 0xd0, 0x98, ++ 0xc6, 0xa3, 0x14, 0x0f, 0x0d, 0xc8, 0x9e, 0x14, 0x2f, 0x9e, 0xd8, 0xeb, ++ 0xc6, 0xa6, 0x07, 0x3c, 0x98, 0x13, 0x99, 0x8e, 0xbd, 0x7b, 0x4b, 0xb1, ++ 0x9b, 0xd7, 0xab, 0x16, 0xfa, 0xf1, 0x38, 0xaf, 0xf7, 0x3f, 0xe0, 0xe2, ++ 0x3c, 0x5c, 0x8c, 0x03, 0x34, 0xec, 0xa1, 0xb1, 0x32, 0xa4, 0x06, 0x68, ++ 0xf2, 0xe4, 0xac, 0x6f, 0x31, 0xc3, 0x18, 0xdd, 0xcb, 0xd8, 0xf8, 0xb0, ++ 0x89, 0x04, 0xfb, 0xd9, 0x4e, 0x5d, 0xf5, 0x10, 0xd7, 0x36, 0x8c, 0x09, ++ 0xc6, 0xaf, 0xc2, 0x35, 0x7d, 0x7a, 0x73, 0x93, 0x62, 0x44, 0x17, 0xd9, ++ 0xfb, 0xb4, 0xe4, 0xbd, 0xad, 0x55, 0x68, 0x4c, 0xe8, 0x66, 0x13, 0x3a, ++ 0x71, 0x8c, 0xe3, 0xfe, 0x7f, 0xe8, 0xb7, 0x8b, 0x1d, 0x7a, 0xef, 0xd5, ++ 0xea, 0x41, 0xec, 0xc8, 0x1c, 0x22, 0x57, 0x07, 0xc2, 0x7b, 0x0e, 0x92, ++ 0xbf, 0x1d, 0x21, 0xfe, 0xbc, 0x6e, 0xf9, 0x0c, 0x15, 0xd7, 0xdf, 0x6f, ++ 0x84, 0xdf, 0x53, 0x02, 0x1b, 0x7f, 0x45, 0x1d, 0x7c, 0x7e, 0xaf, 0x8a, ++ 0xeb, 0x76, 0x2c, 0x46, 0x3a, 0x14, 0xc5, 0xf6, 0x45, 0x2a, 0xae, 0x7d, ++ 0xf8, 0x20, 0x71, 0x7f, 0xc2, 0xe6, 0xc9, 0xd9, 0xf4, 0x7d, 0x08, 0xf6, ++ 0xc9, 0x9a, 0xbc, 0x9b, 0xf1, 0xbb, 0x1c, 0xc7, 0xfb, 0x3b, 0xe9, 0xb7, ++ 0xe5, 0x38, 0x3a, 0x74, 0x90, 0xf6, 0x58, 0x8e, 0x23, 0xfd, 0xc6, 0xc4, ++ 0x4f, 0x1d, 0xe5, 0x78, 0x82, 0xe7, 0x3b, 0x78, 0xbe, 0x70, 0xc0, 0xe8, ++ 0xef, 0x50, 0xcb, 0xb1, 0x60, 0x4f, 0x03, 0xfa, 0x93, 0x62, 0x9b, 0x1a, ++ 0x36, 0x8e, 0xd5, 0xe7, 0x75, 0x2f, 0x3a, 0xf7, 0xe2, 0x4e, 0xea, 0xea, ++ 0x8e, 0x1d, 0x9d, 0xec, 0xcf, 0x47, 0x9d, 0x1f, 0xc4, 0x43, 0xcc, 0xeb, ++ 0xb6, 0x25, 0x7d, 0x38, 0x9d, 0x32, 0xfc, 0x5f, 0x52, 0x0c, 0xb3, 0x44, ++ 0x09, 0x68, 0xc7, 0xe1, 0xc3, 0xc9, 0x4c, 0x29, 0xba, 0x07, 0x66, 0xe1, ++ 0xa7, 0xb4, 0xcf, 0x07, 0x1f, 0x90, 0xfe, 0x26, 0x18, 0x1f, 0x66, 0xe3, ++ 0x89, 0x11, 0x93, 0x6d, 0xcb, 0x3c, 0x49, 0xcc, 0xe9, 0x81, 0x2b, 0x25, ++ 0xbe, 0x11, 0xdd, 0x41, 0xb3, 0x20, 0x26, 0x1e, 0x46, 0xa6, 0x5f, 0xef, ++ 0xbd, 0x41, 0x15, 0x5e, 0xad, 0x52, 0x97, 0x0e, 0x4c, 0x6a, 0x7a, 0xbc, ++ 0x4a, 0x8d, 0xf7, 0x33, 0x7f, 0x8d, 0x57, 0xab, 0x87, 0xf1, 0x44, 0xbf, ++ 0x13, 0xf3, 0x16, 0xaa, 0xbc, 0x1e, 0x3f, 0xc3, 0xd8, 0x16, 0x9f, 0xa3, ++ 0x9a, 0xd8, 0x6d, 0xcb, 0x8a, 0x78, 0x11, 0xb9, 0x7d, 0xe5, 0xc2, 0x5a, ++ 0xc6, 0x2f, 0x87, 0xd8, 0x5e, 0xac, 0x5c, 0x75, 0x52, 0xef, 0x27, 0x31, ++ 0x42, 0xbb, 0x7e, 0x94, 0xc7, 0x81, 0x41, 0xab, 0x73, 0x39, 0x39, 0xf7, ++ 0xc5, 0x01, 0xab, 0xf3, 0x06, 0xd3, 0xf0, 0x15, 0xa9, 0x81, 0xe8, 0xdd, ++ 0x38, 0x89, 0xfd, 0x23, 0x52, 0x06, 0x6e, 0x6f, 0x84, 0x79, 0x75, 0xd2, ++ 0xea, 0xdc, 0x61, 0x5e, 0x8c, 0x06, 0x3b, 0x37, 0xfe, 0x55, 0x79, 0x0e, ++ 0x33, 0xc5, 0x8f, 0x64, 0x0d, 0x64, 0x12, 0xbf, 0x62, 0x3b, 0xef, 0x0d, ++ 0x56, 0x62, 0x5a, 0xb5, 0xf8, 0xc1, 0x09, 0xbc, 0xdd, 0xff, 0x22, 0x4e, ++ 0xf7, 0x5b, 0x58, 0x10, 0xb2, 0xe0, 0x0c, 0xd5, 0x99, 0x4d, 0xea, 0x65, ++ 0xc4, 0x08, 0x05, 0xd7, 0xcc, 0x7d, 0x09, 0xef, 0xd0, 0xff, 0xaf, 0x9d, ++ 0x6b, 0xd9, 0xb2, 0xf4, 0x61, 0xa1, 0xb5, 0xbd, 0x46, 0xfc, 0xc6, 0xb4, ++ 0xf7, 0xf5, 0x7c, 0x72, 0x1e, 0x5c, 0xd8, 0xb7, 0x26, 0xb9, 0xf0, 0x49, ++ 0x0c, 0x0f, 0x1a, 0xd1, 0x75, 0x05, 0x39, 0xfb, 0x4f, 0x52, 0x07, 0x16, ++ 0x76, 0x98, 0x47, 0x1f, 0xae, 0xc2, 0xbc, 0x33, 0xcc, 0x1a, 0xaf, 0x98, ++ 0x43, 0xdb, 0x59, 0xb0, 0x30, 0x60, 0x2e, 0x53, 0xdf, 0xa4, 0x9f, 0x9e, ++ 0xc4, 0xbe, 0xa1, 0x02, 0x5e, 0xfb, 0xd0, 0x44, 0x3f, 0xcf, 0xed, 0x65, ++ 0xf7, 0xa2, 0x31, 0x75, 0xc8, 0x5e, 0x7f, 0x38, 0x40, 0x7c, 0xcc, 0x3d, ++ 0xd3, 0xd4, 0x30, 0x92, 0x69, 0x22, 0x36, 0x44, 0xf1, 0xcf, 0x99, 0x08, ++ 0xf1, 0x21, 0x4c, 0x7c, 0x68, 0x20, 0x3e, 0x98, 0xc4, 0x87, 0x7a, 0xe2, ++ 0x43, 0xd0, 0x7e, 0xd6, 0x2f, 0x6b, 0xe6, 0x43, 0xa3, 0x2f, 0xa2, 0x68, ++ 0xe0, 0x04, 0x5c, 0xf4, 0x81, 0xe3, 0xa6, 0x45, 0x7e, 0x52, 0xa7, 0xad, ++ 0xc1, 0xc5, 0x4a, 0x54, 0xf3, 0x62, 0x28, 0x73, 0x02, 0x25, 0x03, 0x1a, ++ 0xc7, 0x22, 0xfb, 0x33, 0x6a, 0xc3, 0xbd, 0xc4, 0xea, 0x5f, 0x1b, 0x75, ++ 0xbd, 0x5e, 0xd4, 0xed, 0xae, 0x81, 0xd1, 0xbf, 0x50, 0x9d, 0xab, 0x44, ++ 0xbf, 0xe0, 0xe5, 0x38, 0xab, 0x31, 0xfb, 0x01, 0x0d, 0x73, 0x78, 0xfc, ++ 0x53, 0xaa, 0x76, 0xe2, 0x75, 0x07, 0xbc, 0x33, 0x48, 0x77, 0x66, 0x92, ++ 0x09, 0x90, 0xd5, 0x7a, 0x7d, 0xb8, 0xe4, 0xc0, 0x49, 0x55, 0x41, 0xf6, ++ 0x0b, 0x12, 0xf3, 0xea, 0x82, 0x3d, 0xaa, 0x2a, 0x6b, 0x48, 0xc4, 0x70, ++ 0x1e, 0x2a, 0x22, 0x64, 0x11, 0xb3, 0x98, 0x5f, 0x58, 0x6b, 0xcc, 0x12, ++ 0x6c, 0xae, 0x57, 0x65, 0x6f, 0xc8, 0x21, 0x89, 0x51, 0x33, 0x18, 0x23, ++ 0x4a, 0x93, 0xf1, 0xdb, 0x66, 0xc0, 0x83, 0x92, 0xa4, 0x65, 0x3d, 0x16, ++ 0xd2, 0xe0, 0x89, 0x04, 0xa2, 0x1b, 0x98, 0x46, 0x7e, 0x61, 0x5e, 0x18, ++ 0xd7, 0x64, 0x0e, 0x60, 0x80, 0xe3, 0x5b, 0x9e, 0x29, 0xbc, 0xe3, 0xf9, ++ 0xc9, 0x7f, 0xe7, 0xde, 0x15, 0xbd, 0x64, 0xf7, 0x0c, 0x18, 0xda, 0x5d, ++ 0x6a, 0xbc, 0x92, 0x1c, 0xfc, 0x00, 0xe3, 0x9e, 0x32, 0x79, 0xa3, 0x82, ++ 0xd6, 0x81, 0x38, 0xa6, 0x85, 0x7e, 0xa0, 0xc4, 0xaa, 0x75, 0xbf, 0x5f, ++ 0xa9, 0xc6, 0x8d, 0x0f, 0x50, 0xd7, 0x0b, 0x26, 0x68, 0x2b, 0x3e, 0x7c, ++ 0x67, 0x54, 0x74, 0x5b, 0x3b, 0xb4, 0x83, 0xe3, 0x98, 0x98, 0x7b, 0x40, ++ 0x70, 0xf2, 0xa0, 0x1b, 0x8e, 0x83, 0xd3, 0x99, 0x9b, 0xd6, 0xcf, 0xbd, ++ 0xa4, 0xe3, 0xdf, 0x54, 0xd1, 0x8b, 0xf0, 0x6b, 0xbd, 0x3f, 0xae, 0x18, ++ 0xda, 0x2f, 0x95, 0x03, 0xe4, 0x6c, 0x5e, 0x3c, 0x96, 0x39, 0x4c, 0x5d, ++ 0xee, 0xcf, 0xe7, 0x4b, 0xab, 0x90, 0xe8, 0x93, 0x7d, 0x81, 0x27, 0x30, ++ 0x7b, 0x40, 0x6f, 0xd9, 0xaa, 0x18, 0xc1, 0x6b, 0x95, 0x13, 0x98, 0x39, ++ 0x10, 0xe4, 0x5c, 0x6a, 0x58, 0x96, 0x2c, 0xe0, 0xa7, 0x60, 0xf0, 0x2a, ++ 0x62, 0xb0, 0xb5, 0xf8, 0xa7, 0x66, 0x9c, 0x39, 0x8e, 0x6e, 0x3a, 0x15, ++ 0xbd, 0x75, 0xae, 0x22, 0xfb, 0x80, 0x8c, 0x33, 0x6d, 0xac, 0xe3, 0x19, ++ 0xa8, 0xc7, 0x57, 0x39, 0xe6, 0x66, 0xce, 0xdb, 0x8b, 0x0b, 0x2d, 0x2c, ++ 0x5a, 0xa8, 0xef, 0x2e, 0x71, 0x44, 0xef, 0xaa, 0x42, 0xb6, 0xa3, 0x86, ++ 0x76, 0x73, 0xc7, 0x02, 0x3d, 0xfc, 0x03, 0xe2, 0x2e, 0x71, 0x1a, 0xdd, ++ 0x8c, 0x3b, 0x6b, 0x18, 0x8b, 0x4a, 0x23, 0x7a, 0x2f, 0x73, 0xd4, 0xf7, ++ 0x6e, 0x75, 0x44, 0x43, 0xf2, 0x1e, 0xd1, 0xdf, 0x63, 0x31, 0xdc, 0xa1, ++ 0x0a, 0xe2, 0xa0, 0x9e, 0x7d, 0x11, 0xfa, 0xee, 0xaf, 0x92, 0x93, 0xfe, ++ 0x98, 0xfc, 0xae, 0xe6, 0xd2, 0x43, 0xc4, 0xa8, 0x11, 0x3c, 0x98, 0x39, ++ 0x88, 0xdd, 0x99, 0x34, 0x76, 0x66, 0xb6, 0x29, 0x43, 0xf6, 0xb3, 0x45, ++ 0x45, 0xde, 0x99, 0x8b, 0x56, 0x28, 0x5f, 0x46, 0x79, 0xe8, 0x5b, 0xd6, ++ 0x50, 0x95, 0x8a, 0xca, 0x50, 0x10, 0xd7, 0x24, 0xe3, 0x70, 0x44, 0xde, ++ 0xb5, 0xe4, 0x7d, 0xed, 0xf5, 0xe3, 0x06, 0xae, 0x4e, 0x96, 0x22, 0xb6, ++ 0xc7, 0xb2, 0x7a, 0x1b, 0x9c, 0x58, 0x3b, 0x5e, 0x8f, 0x65, 0x03, 0x0f, ++ 0x59, 0x73, 0x18, 0x73, 0x3e, 0xbc, 0xdc, 0x83, 0x5b, 0xf7, 0x78, 0xd0, ++ 0x96, 0x8c, 0xc2, 0x17, 0x29, 0xe3, 0xef, 0x80, 0xb9, 0x04, 0xc6, 0xc4, ++ 0x04, 0x8c, 0xde, 0xab, 0x1c, 0x81, 0xfd, 0x61, 0xd5, 0x83, 0xbf, 0x21, ++ 0x8e, 0x2f, 0x27, 0xee, 0xc4, 0xc6, 0x2d, 0x54, 0x46, 0xbc, 0xb8, 0x8d, ++ 0xf5, 0xaf, 0xe3, 0xdc, 0xbf, 0xb3, 0x68, 0x3f, 0xb1, 0x40, 0xf6, 0x42, ++ 0x6a, 0xd8, 0x30, 0xee, 0xa6, 0xae, 0xdc, 0x88, 0xed, 0xab, 0xc6, 0xd5, ++ 0x0f, 0xf8, 0x71, 0xeb, 0xb8, 0x07, 0x8d, 0x49, 0x6b, 0xf1, 0x01, 0x33, ++ 0xbe, 0x52, 0x83, 0x81, 0xb6, 0x71, 0x2f, 0xbe, 0x92, 0xd4, 0x7d, 0xd7, ++ 0x32, 0xe7, 0x1f, 0x31, 0x83, 0xf8, 0x5f, 0xe3, 0x3e, 0xdc, 0x94, 0x3c, ++ 0x2a, 0x79, 0xe4, 0x12, 0x27, 0x63, 0xcf, 0xbd, 0xe3, 0xb3, 0xb0, 0x32, ++ 0xa9, 0x9f, 0x99, 0x20, 0xb7, 0xeb, 0xdc, 0x67, 0xe2, 0xae, 0x71, 0x15, ++ 0xad, 0x6c, 0xe7, 0xc6, 0xe4, 0x6c, 0x74, 0xec, 0x6b, 0xa0, 0x0c, 0x0b, ++ 0xb1, 0x7c, 0xc0, 0x09, 0x93, 0x2c, 0x1e, 0x5f, 0x04, 0x5a, 0x06, 0x26, ++ 0x98, 0xc7, 0xdd, 0x87, 0xed, 0x7d, 0x26, 0x6e, 0x1f, 0x97, 0xf3, 0x83, ++ 0xf6, 0x3b, 0xae, 0xef, 0x3d, 0xbc, 0x10, 0x9f, 0x1f, 0x50, 0x89, 0x03, ++ 0xc5, 0x18, 0x5a, 0xa9, 0xe0, 0x2b, 0xbc, 0xbe, 0x35, 0x25, 0x7b, 0x90, ++ 0x81, 0xd0, 0x8e, 0xc0, 0xfe, 0x2a, 0x72, 0x86, 0x45, 0x0f, 0xe7, 0xae, ++ 0x3f, 0x48, 0x9c, 0x2f, 0x21, 0xce, 0x97, 0x91, 0xc3, 0x5e, 0x35, 0x7c, ++ 0x10, 0xf7, 0x13, 0x97, 0x0f, 0x0d, 0x74, 0x32, 0xee, 0x94, 0xe3, 0x71, ++ 0xc6, 0x81, 0x24, 0xcf, 0x4f, 0xec, 0x30, 0x3a, 0x4a, 0x88, 0xd3, 0x3f, ++ 0x20, 0xfe, 0xf6, 0x12, 0x33, 0xee, 0x48, 0x32, 0xdc, 0xef, 0x60, 0x0e, ++ 0x70, 0x69, 0x74, 0xbe, 0x87, 0x39, 0xd6, 0xb5, 0x4a, 0xc0, 0xf7, 0x26, ++ 0xca, 0xe1, 0x78, 0xb8, 0x1a, 0x8d, 0x0f, 0x48, 0x19, 0xc1, 0x2f, 0x15, ++ 0xea, 0x5e, 0x27, 0x75, 0x7e, 0x18, 0x56, 0xbf, 0x83, 0xe3, 0xad, 0x35, ++ 0xc9, 0xc0, 0xf1, 0x9a, 0xa9, 0x6b, 0xff, 0x4c, 0xac, 0x7d, 0x9f, 0x98, ++ 0xea, 0x9f, 0xd1, 0x80, 0x26, 0xc3, 0xe4, 0x71, 0x18, 0x27, 0xfb, 0x0d, ++ 0x53, 0xf6, 0xe4, 0xbd, 0x4e, 0x9e, 0x37, 0x39, 0x83, 0x31, 0xd3, 0x10, ++ 0x3f, 0x1c, 0xe1, 0x78, 0x54, 0xc9, 0x4b, 0xe0, 0x18, 0x03, 0xde, 0x7e, ++ 0x78, 0x31, 0xc7, 0x25, 0xb1, 0x54, 0xe2, 0xdd, 0x08, 0x65, 0x5d, 0x8c, ++ 0x15, 0xd4, 0x47, 0x53, 0x52, 0x45, 0x7a, 0x5f, 0x04, 0xb7, 0xef, 0xca, ++ 0xc5, 0xe1, 0x8d, 0xa1, 0xf8, 0x0d, 0x8c, 0xc3, 0xe1, 0x52, 0xc6, 0x61, ++ 0x57, 0x44, 0x64, 0x73, 0x62, 0x98, 0x71, 0x7b, 0x73, 0x2a, 0x8c, 0x66, ++ 0xce, 0xe1, 0x44, 0x9a, 0xfd, 0x26, 0x67, 0xe1, 0x78, 0xda, 0xc3, 0x98, ++ 0xa5, 0xf1, 0x20, 0xaa, 0x8d, 0x4c, 0xe7, 0xe1, 0xe7, 0x71, 0x31, 0x0f, ++ 0xc3, 0xbe, 0xb6, 0x26, 0xa9, 0x20, 0xde, 0xa2, 0xd8, 0x7c, 0xfe, 0x78, ++ 0x5a, 0xb0, 0x59, 0xd6, 0x32, 0xef, 0xae, 0x94, 0x3d, 0xa8, 0xfd, 0xa9, ++ 0x97, 0x50, 0x49, 0x7c, 0xaa, 0xc8, 0xe3, 0xd0, 0xcf, 0x42, 0x82, 0xbb, ++ 0xb5, 0xc4, 0x5d, 0xd9, 0x4f, 0x64, 0x59, 0xab, 0x02, 0x53, 0xf1, 0xe8, ++ 0xff, 0xfb, 0x30, 0x6a, 0xef, 0xab, 0x15, 0x4c, 0x22, 0xfe, 0xa5, 0x88, ++ 0x7f, 0x1c, 0x43, 0xd7, 0x95, 0xc4, 0x40, 0xca, 0xf4, 0x8f, 0x29, 0x62, ++ 0x20, 0x71, 0xfa, 0x20, 0x71, 0xfa, 0xdb, 0xc4, 0xe9, 0x6f, 0x11, 0xa7, ++ 0x1f, 0x27, 0x26, 0xe4, 0xd6, 0xf4, 0x9a, 0xe5, 0xb9, 0x0a, 0xe7, 0xe3, ++ 0x1d, 0x7b, 0x6d, 0xb1, 0x86, 0xba, 0x9a, 0x3d, 0xa0, 0x60, 0x8e, 0xa1, ++ 0xef, 0x17, 0xbb, 0xff, 0x31, 0xe7, 0xc9, 0x3f, 0x2d, 0xb7, 0xe7, 0xb7, ++ 0x29, 0xd9, 0x03, 0x77, 0xb2, 0x4e, 0xeb, 0x85, 0xfd, 0x0d, 0x01, 0x53, ++ 0xb8, 0x68, 0x51, 0x72, 0x0d, 0x1c, 0xc9, 0xba, 0xfd, 0xc7, 0xe4, 0xf9, ++ 0xed, 0x74, 0xc9, 0xeb, 0xd7, 0xc8, 0x1e, 0xed, 0xfd, 0xb2, 0x37, 0x6c, ++ 0x19, 0xef, 0xb9, 0x92, 0x75, 0xe6, 0x9b, 0xb0, 0xb1, 0xcd, 0x3f, 0x69, ++ 0xdf, 0xab, 0x7d, 0xef, 0x7e, 0xea, 0x2b, 0xcb, 0x36, 0xd3, 0x29, 0xd9, ++ 0x17, 0x3b, 0x0b, 0x8f, 0x66, 0xe4, 0x77, 0x5d, 0x6b, 0x42, 0xdd, 0x8f, ++ 0x58, 0x8d, 0xf0, 0xf1, 0x30, 0xae, 0x4f, 0x7a, 0x68, 0x07, 0x71, 0x54, ++ 0xd0, 0xb7, 0xbe, 0x36, 0xde, 0x40, 0x5f, 0x7b, 0xc8, 0xd2, 0x22, 0x81, ++ 0xd6, 0x71, 0x72, 0x9e, 0xf5, 0xe3, 0x8b, 0xb1, 0x74, 0xc0, 0xb2, 0x3c, ++ 0x97, 0x19, 0xe1, 0x0d, 0x8a, 0x1f, 0x2e, 0xfa, 0xa0, 0x83, 0x7e, 0xb5, ++ 0x6e, 0x4f, 0x40, 0x7b, 0x93, 0x78, 0xda, 0xde, 0x70, 0x80, 0xf6, 0x61, ++ 0x9c, 0x69, 0x26, 0x96, 0x3a, 0x23, 0x01, 0xe6, 0x89, 0x1e, 0xda, 0xbe, ++ 0x17, 0x67, 0x12, 0xe2, 0x5f, 0x7a, 0xc7, 0x3f, 0x33, 0x37, 0xe9, 0xa0, ++ 0x6f, 0xfc, 0x32, 0x31, 0x8b, 0x3e, 0xe0, 0xc6, 0xdb, 0x09, 0x83, 0xfe, ++ 0xe6, 0xc1, 0x3b, 0x89, 0x7a, 0xf6, 0x15, 0x64, 0x19, 0x3f, 0xee, 0x1c, ++ 0x0f, 0xd3, 0xcf, 0xae, 0xe4, 0x21, 0xef, 0x53, 0xd7, 0xc6, 0xbf, 0xa3, ++ 0xd4, 0xf6, 0xcf, 0x56, 0xab, 0x10, 0xad, 0xd6, 0xf0, 0xf5, 0xf1, 0xcf, ++ 0xe2, 0x3f, 0x18, 0xb7, 0xd7, 0x26, 0xc1, 0x39, 0x44, 0x88, 0x3c, 0x70, ++ 0x62, 0x9f, 0x3c, 0x4b, 0x44, 0x5d, 0x74, 0xae, 0x43, 0x67, 0x6e, 0xab, ++ 0x67, 0x4f, 0x3b, 0x9c, 0xec, 0x93, 0xac, 0x98, 0x65, 0x7f, 0xd9, 0x5f, ++ 0x8a, 0xbb, 0xf6, 0x1c, 0xa0, 0x8f, 0x14, 0x61, 0xc1, 0xfd, 0x6e, 0x7c, ++ 0x7d, 0xdf, 0x08, 0xb9, 0x83, 0x8a, 0x99, 0xcc, 0x95, 0x86, 0x48, 0x14, ++ 0x66, 0x0e, 0x47, 0x70, 0xdb, 0xae, 0x11, 0x0c, 0xe4, 0x79, 0x5e, 0x28, ++ 0x14, 0xff, 0x9f, 0x2a, 0x0e, 0x90, 0x47, 0x04, 0xda, 0x3f, 0x43, 0x1b, ++ 0xab, 0x88, 0x04, 0xe2, 0x32, 0xee, 0x16, 0xda, 0x58, 0x0f, 0xe7, 0x33, ++ 0xcd, 0x71, 0x24, 0x68, 0x63, 0x8f, 0x51, 0xfe, 0xed, 0xb4, 0xb1, 0x38, ++ 0x6d, 0x2c, 0x4e, 0x7b, 0x8a, 0xd3, 0xc6, 0xe4, 0x9d, 0xfd, 0x38, 0x6d, ++ 0x2c, 0x4e, 0x1b, 0x8b, 0xa7, 0x17, 0x63, 0x94, 0x4c, 0x63, 0xcb, 0x48, ++ 0x03, 0x71, 0x4c, 0xb1, 0xa3, 0x52, 0xf6, 0x86, 0xcf, 0x92, 0xb3, 0x5f, ++ 0xc5, 0x43, 0x41, 0x33, 0x7d, 0xb2, 0x77, 0x68, 0x84, 0x9c, 0xc7, 0x8d, ++ 0xdf, 0x64, 0x84, 0xe3, 0x37, 0x30, 0x8f, 0x3d, 0x4c, 0x9e, 0xaf, 0xe2, ++ 0x49, 0x53, 0xf2, 0x60, 0x93, 0xe7, 0x8c, 0x35, 0x29, 0xe1, 0x6b, 0x87, ++ 0x71, 0x47, 0x3f, 0x70, 0x2d, 0x79, 0x61, 0x35, 0x79, 0xc9, 0xde, 0x05, ++ 0xfc, 0xfd, 0xf0, 0x01, 0xda, 0xbc, 0xf8, 0x63, 0x6e, 0xaf, 0xeb, 0xf1, ++ 0xfe, 0x5a, 0xdf, 0xd5, 0xf4, 0xc1, 0x7b, 0x59, 0xd7, 0xf9, 0xb0, 0xd4, ++ 0x39, 0xc0, 0xb6, 0xf5, 0xf0, 0x6f, 0x38, 0xff, 0xad, 0xf7, 0x57, 0xe3, ++ 0xed, 0x5d, 0x7a, 0xf8, 0x7d, 0x62, 0x5e, 0xb5, 0xc3, 0x5a, 0xfc, 0x99, ++ 0x50, 0x60, 0xe3, 0x67, 0xd4, 0x1c, 0xdf, 0x6b, 0xd9, 0xe1, 0xc4, 0xfe, ++ 0xd0, 0x62, 0x78, 0x16, 0x14, 0x38, 0x1f, 0x6d, 0xa9, 0x5a, 0x38, 0x96, ++ 0x1e, 0x3e, 0x4d, 0xae, 0x92, 0x64, 0xfb, 0xa3, 0xe9, 0x23, 0xc4, 0x90, ++ 0xfb, 0xf0, 0x02, 0xf3, 0xf3, 0x91, 0x4f, 0xbf, 0x4e, 0xee, 0xe8, 0xc6, ++ 0x18, 0x39, 0xe0, 0x81, 0xfe, 0xe8, 0xe7, 0x9c, 0xc4, 0x7d, 0xcf, 0x82, ++ 0x72, 0xa4, 0x87, 0x84, 0x2b, 0x96, 0xe3, 0xd9, 0x7e, 0x43, 0xbb, 0x56, ++ 0xc9, 0xf1, 0xc2, 0x2d, 0x3c, 0x7f, 0xb3, 0xdf, 0x38, 0x33, 0x8c, 0xc0, ++ 0xc4, 0x69, 0x72, 0xc3, 0xf7, 0x87, 0x24, 0x86, 0x1d, 0xa4, 0x8f, 0xfb, ++ 0x11, 0x4e, 0x6a, 0x38, 0x34, 0x66, 0x60, 0x7e, 0xd2, 0x8b, 0x47, 0xc6, ++ 0x82, 0xf8, 0x0c, 0x7d, 0x37, 0x43, 0x7e, 0xf8, 0xe9, 0xa4, 0xf8, 0xe2, ++ 0x2c, 0x8c, 0x8f, 0xcd, 0xb2, 0xf7, 0x54, 0x7a, 0x8c, 0x5f, 0xc0, 0x53, ++ 0x2d, 0x3e, 0x49, 0x6e, 0x9d, 0xd2, 0x7b, 0x63, 0x1c, 0x4f, 0xcc, 0xab, ++ 0xef, 0x8f, 0x41, 0x1f, 0x02, 0xae, 0xf8, 0x70, 0xe8, 0x8b, 0x12, 0x1f, ++ 0xc5, 0x1f, 0x35, 0x8c, 0x93, 0xef, 0x14, 0x13, 0x53, 0x4b, 0x23, 0xb5, ++ 0xef, 0xbd, 0xac, 0xe8, 0xd9, 0xa7, 0x55, 0xcb, 0x7a, 0x69, 0xa1, 0x06, ++ 0xdf, 0x3e, 0x8d, 0xdc, 0xc3, 0x64, 0xec, 0x16, 0x3f, 0xd5, 0x30, 0xe3, ++ 0x81, 0x6a, 0x4c, 0x7b, 0x20, 0x89, 0xbf, 0xad, 0x8e, 0x7f, 0x6e, 0x3a, ++ 0xe3, 0xfc, 0x74, 0xe2, 0x7a, 0x65, 0xf2, 0xd8, 0x0c, 0x37, 0xf9, 0xf2, ++ 0x84, 0x5a, 0xd7, 0xba, 0x1f, 0xfa, 0xfe, 0x93, 0x8a, 0xee, 0x7b, 0x8c, ++ 0xb1, 0xc1, 0x45, 0x1b, 0x75, 0x8c, 0x6b, 0xf4, 0xdd, 0xba, 0x43, 0xd3, ++ 0x60, 0xc4, 0x2f, 0x57, 0x5d, 0x16, 0x6c, 0x79, 0xae, 0xa8, 0xcc, 0xe5, ++ 0x45, 0x82, 0x3b, 0x12, 0x17, 0x1c, 0xb2, 0xff, 0x13, 0xed, 0xf4, 0x97, ++ 0x15, 0x76, 0x2c, 0x3a, 0x60, 0xef, 0x8f, 0xdb, 0x30, 0x1e, 0xa7, 0x8f, ++ 0x2c, 0x46, 0xd9, 0x80, 0x07, 0x5f, 0xb3, 0xe3, 0xd0, 0x43, 0x56, 0x15, ++ 0xfd, 0xe5, 0xf6, 0x3d, 0x81, 0xf6, 0xab, 0xe9, 0x2f, 0xb5, 0x97, 0x49, ++ 0x0c, 0x63, 0xdc, 0x4e, 0x19, 0xe6, 0x30, 0xb1, 0xe5, 0xa1, 0x06, 0x63, ++ 0xe2, 0x75, 0xe4, 0x7c, 0x66, 0x6b, 0x5f, 0x35, 0xfe, 0xe1, 0xfe, 0xfd, ++ 0xf6, 0x5a, 0xc8, 0x6d, 0x3c, 0x4f, 0xf6, 0xf9, 0x6c, 0xff, 0x88, 0xf1, ++ 0xf7, 0x9d, 0x8c, 0x79, 0x31, 0xfa, 0xd1, 0x96, 0x3e, 0x6b, 0xf1, 0xf7, ++ 0x17, 0xc6, 0x57, 0x56, 0x20, 0xc8, 0x98, 0xe4, 0x46, 0x6f, 0x9f, 0xde, ++ 0xdf, 0xca, 0x18, 0x74, 0x62, 0xa1, 0x49, 0x59, 0x3c, 0xd8, 0xd1, 0x27, ++ 0x98, 0x7a, 0xf4, 0xa6, 0x6a, 0xc4, 0xff, 0xa7, 0xc6, 0xf1, 0x7d, 0xcd, ++ 0x7e, 0xf6, 0x37, 0x0b, 0x6b, 0xf7, 0x5d, 0x46, 0x99, 0xeb, 0xe9, 0x83, ++ 0xcc, 0xab, 0x99, 0xef, 0xac, 0xde, 0x25, 0x7e, 0x81, 0x46, 0xc9, 0xd3, ++ 0x3a, 0xcd, 0x80, 0xf9, 0x06, 0x7d, 0xa8, 0x88, 0x5c, 0xe7, 0x41, 0x62, ++ 0x59, 0x31, 0x21, 0xb3, 0xcc, 0x08, 0x63, 0x21, 0x6d, 0x54, 0xde, 0xe1, ++ 0x98, 0x46, 0x5e, 0x37, 0x9f, 0xf3, 0x51, 0x92, 0xf1, 0x00, 0xe4, 0x10, ++ 0x20, 0x3e, 0x61, 0x94, 0x20, 0x38, 0xea, 0xe7, 0x71, 0x31, 0x0f, 0x2a, ++ 0x22, 0xa3, 0xa2, 0x66, 0x94, 0x75, 0x87, 0x47, 0x6c, 0x5b, 0xfc, 0x07, ++ 0xce, 0x7b, 0x82, 0xb6, 0x7e, 0x23, 0xb1, 0x7e, 0x62, 0x27, 0xd0, 0xfb, ++ 0x70, 0xce, 0xb6, 0x53, 0x6c, 0xbf, 0x85, 0x98, 0xf7, 0x1e, 0x6d, 0xb6, ++ 0x87, 0xf3, 0xbd, 0x63, 0xd0, 0x08, 0xd6, 0xa9, 0x01, 0x6d, 0x9c, 0xf3, ++ 0xdc, 0x35, 0xa2, 0xa2, 0xaf, 0x7f, 0x31, 0x86, 0x99, 0x07, 0x75, 0x0f, ++ 0x89, 0x8f, 0x48, 0x99, 0xc3, 0xe8, 0xa4, 0x8f, 0xfc, 0x6a, 0xa1, 0x82, ++ 0xd8, 0x17, 0xe4, 0x1d, 0x51, 0x27, 0xf3, 0xfd, 0xfb, 0xb0, 0x36, 0x71, ++ 0xc4, 0x2a, 0x37, 0xf4, 0xde, 0x21, 0x95, 0x79, 0x16, 0x6d, 0xb3, 0x8b, ++ 0xf9, 0xc9, 0x12, 0xe6, 0x27, 0xdd, 0x79, 0xbb, 0x3c, 0x4e, 0x3b, 0xec, ++ 0x63, 0x1c, 0x7b, 0x7d, 0x28, 0x17, 0xf7, 0x7e, 0xbc, 0xc3, 0x8f, 0xf9, ++ 0x97, 0x97, 0xe3, 0x99, 0x87, 0x73, 0xb2, 0xed, 0xa4, 0x4d, 0x3e, 0x4d, ++ 0x3d, 0xdf, 0x4a, 0xbd, 0xbe, 0x92, 0x12, 0x8c, 0x0a, 0xe2, 0x59, 0xf2, ++ 0xe8, 0xf5, 0xe4, 0x02, 0x2f, 0xa5, 0x72, 0x36, 0xf9, 0xf5, 0xf1, 0x2b, ++ 0xab, 0x72, 0xf1, 0xc1, 0x0b, 0xf5, 0x01, 0x79, 0x27, 0xcf, 0xb2, 0x96, ++ 0x98, 0xd9, 0x76, 0xf2, 0x1a, 0xb6, 0x1d, 0x21, 0x37, 0x72, 0x62, 0x66, ++ 0x32, 0x82, 0xa5, 0xa9, 0xda, 0xe6, 0xb9, 0xb2, 0x89, 0x63, 0x66, 0x8e, ++ 0x03, 0xba, 0x92, 0xf2, 0xcd, 0x0f, 0x0d, 0x65, 0xcc, 0x9d, 0xfe, 0x26, ++ 0xff, 0x9d, 0x91, 0x1b, 0xff, 0x0c, 0xee, 0xb8, 0x82, 0x32, 0xa5, 0xc8, ++ 0x1d, 0x27, 0xf3, 0xdf, 0x19, 0xb9, 0xc1, 0xfe, 0xce, 0x88, 0x1b, 0xd3, ++ 0xc6, 0x9d, 0xce, 0x2f, 0xa5, 0x3c, 0x98, 0x31, 0x7e, 0x96, 0x83, 0xba, ++ 0x8b, 0x22, 0x4d, 0x78, 0x2a, 0xa1, 0x60, 0xba, 0xf1, 0xbf, 0xf1, 0xb2, ++ 0xbd, 0x26, 0x50, 0x8d, 0x99, 0x0f, 0xc8, 0x7a, 0x42, 0x54, 0xde, 0x89, ++ 0x69, 0x7e, 0x82, 0xe7, 0x25, 0xc4, 0xd3, 0x8a, 0x07, 0x14, 0x3c, 0x1d, ++ 0xf0, 0xa2, 0x98, 0xbf, 0x7d, 0xe4, 0x9a, 0xce, 0x85, 0xcb, 0xad, 0xcd, ++ 0xab, 0xc4, 0xbe, 0x39, 0x87, 0xfb, 0xa6, 0x55, 0x0a, 0x06, 0xee, 0x35, ++ 0x65, 0xdd, 0xd2, 0x40, 0x4f, 0xa2, 0x9a, 0xfc, 0xba, 0xb6, 0xbd, 0x09, ++ 0xb5, 0xe6, 0x2f, 0x1c, 0xd5, 0x28, 0xda, 0x77, 0x63, 0x95, 0xac, 0xd9, ++ 0x7f, 0x9b, 0x73, 0xd6, 0x4d, 0xec, 0xea, 0x4a, 0xe5, 0xe2, 0x67, 0x53, ++ 0xfa, 0x17, 0x9a, 0xe8, 0xa5, 0x9b, 0xfc, 0x44, 0x4d, 0x9e, 0xb2, 0xcb, ++ 0x94, 0x45, 0x0e, 0x11, 0x7f, 0x66, 0xe1, 0x10, 0xf3, 0x1a, 0x89, 0xa5, ++ 0x65, 0x3c, 0xca, 0xc9, 0x1b, 0x7f, 0xc9, 0x58, 0x7a, 0x67, 0x28, 0x1b, ++ 0x94, 0x2f, 0xd0, 0x54, 0x91, 0x8b, 0xd3, 0x07, 0xb0, 0x2f, 0xa4, 0xb7, ++ 0xac, 0x76, 0x44, 0x9f, 0x61, 0x0e, 0x16, 0x5e, 0xcc, 0x9c, 0x7c, 0x79, ++ 0x60, 0x04, 0x5b, 0xc9, 0x03, 0xb7, 0x30, 0x17, 0x6f, 0xa5, 0x6d, 0xb6, ++ 0xef, 0x62, 0x6c, 0x73, 0x9c, 0xcb, 0xc5, 0xb5, 0x50, 0x7c, 0x35, 0x39, ++ 0x40, 0x87, 0x47, 0x15, 0x7b, 0x15, 0xdf, 0x09, 0xb4, 0xbe, 0x41, 0x8c, ++ 0xae, 0x63, 0xdc, 0x10, 0x7b, 0xdf, 0x9e, 0xd2, 0xdb, 0xa9, 0x80, 0xaa, ++ 0x72, 0xe6, 0x8e, 0x77, 0x8d, 0x35, 0xd0, 0x6f, 0xac, 0x4e, 0x37, 0xed, ++ 0xda, 0xb9, 0x68, 0x16, 0x73, 0xce, 0xab, 0xd0, 0xbd, 0x83, 0xf6, 0x4f, ++ 0x5f, 0xba, 0xb7, 0x0f, 0xe4, 0x67, 0xea, 0x16, 0xce, 0x5f, 0x76, 0x1f, ++ 0x02, 0x67, 0x5a, 0x50, 0xd7, 0x5c, 0xe4, 0x10, 0x19, 0xf4, 0x96, 0xb7, ++ 0xc9, 0xd3, 0x3a, 0x98, 0x9f, 0xae, 0x67, 0x2e, 0x1f, 0x63, 0x2e, 0x1f, ++ 0x63, 0xbd, 0xd4, 0x0e, 0x79, 0x4e, 0x64, 0xb4, 0x1c, 0x67, 0xfe, 0xf3, ++ 0x35, 0xf2, 0x9f, 0x1d, 0xf7, 0x8b, 0x5c, 0xd3, 0x71, 0xd7, 0xde, 0xab, ++ 0x90, 0xa4, 0x3d, 0xdd, 0xc9, 0x6b, 0x7d, 0xf7, 0x5f, 0x8c, 0x3b, 0x98, ++ 0xc7, 0xc7, 0xc6, 0x16, 0xa3, 0x9f, 0x99, 0xe8, 0xc6, 0xbd, 0x9f, 0x45, ++ 0x17, 0xf9, 0xd4, 0x12, 0x62, 0xf4, 0xea, 0x87, 0x47, 0x6c, 0xcc, 0x16, ++ 0xcc, 0x7f, 0x2d, 0x0d, 0xbc, 0x49, 0x4e, 0xd6, 0x9f, 0x3a, 0x60, 0xf3, ++ 0x34, 0x17, 0xe3, 0x43, 0x31, 0x71, 0x29, 0xbc, 0xcb, 0xe8, 0x58, 0xa6, ++ 0x5a, 0x8b, 0x4b, 0x16, 0x06, 0x7a, 0xdf, 0xa6, 0xaf, 0x56, 0xed, 0x53, ++ 0x51, 0x3d, 0x20, 0xb9, 0x3a, 0xf9, 0x11, 0x31, 0xfa, 0x05, 0x62, 0x74, ++ 0xf9, 0x9e, 0x5c, 0x5e, 0x9e, 0x60, 0xde, 0x55, 0x6d, 0xe4, 0x72, 0xf3, ++ 0xed, 0x7d, 0xb2, 0xf7, 0xc6, 0x8d, 0xe7, 0x68, 0xfb, 0x47, 0xf3, 0xb6, ++ 0x7f, 0x2c, 0x8f, 0xc1, 0x16, 0x73, 0xf3, 0x37, 0x6d, 0xfc, 0xcd, 0xe5, ++ 0xe6, 0xf3, 0x07, 0x8c, 0x8e, 0x30, 0x31, 0xfa, 0x33, 0x7b, 0xa4, 0x7f, ++ 0x0d, 0xd5, 0xc4, 0x93, 0x1a, 0x62, 0x49, 0xc5, 0x80, 0xac, 0xcf, 0x04, ++ 0xda, 0xc7, 0x55, 0x9f, 0xdd, 0xc7, 0x26, 0xca, 0xd6, 0x9d, 0x92, 0x77, ++ 0x6c, 0x0d, 0x6d, 0x83, 0x12, 0x30, 0xaf, 0xa1, 0x3e, 0xf7, 0xa5, 0xaf, ++ 0x42, 0x7b, 0xff, 0x2c, 0xec, 0x1f, 0x92, 0xf8, 0x22, 0xed, 0x4b, 0x2e, ++ 0xee, 0xc4, 0xfb, 0xbb, 0x66, 0xe3, 0xfd, 0x91, 0x73, 0x79, 0xf8, 0xe6, ++ 0x54, 0xf4, 0x5e, 0x86, 0xd7, 0xe5, 0x92, 0x87, 0xbf, 0xc4, 0x3c, 0xfc, ++ 0x6d, 0x45, 0xd6, 0x10, 0x55, 0xdc, 0xb8, 0xc0, 0xc1, 0xf8, 0xa2, 0xfb, ++ 0x5f, 0x74, 0xc4, 0xe5, 0x39, 0xb2, 0xff, 0x7e, 0xde, 0x7f, 0x9e, 0xf1, ++ 0x7c, 0x80, 0x33, 0x11, 0xad, 0x76, 0xe0, 0x99, 0x85, 0xf1, 0xa8, 0x8b, ++ 0xd7, 0x7b, 0xc9, 0x53, 0x66, 0x1a, 0x07, 0xe9, 0x9b, 0xb5, 0xe1, 0xf9, ++ 0x0e, 0x07, 0xce, 0x98, 0x7a, 0xcb, 0x6e, 0x5e, 0x7b, 0x36, 0x23, 0xbe, ++ 0x18, 0x26, 0x7e, 0x2d, 0xca, 0xfb, 0xa2, 0xbc, 0x8f, 0x01, 0xf7, 0x6c, ++ 0xda, 0xeb, 0x6b, 0x29, 0xbd, 0xff, 0x59, 0xda, 0x69, 0xf5, 0x59, 0x3b, ++ 0x2d, 0xec, 0xd3, 0x82, 0xbb, 0x2a, 0xd2, 0x82, 0x50, 0xb2, 0xb0, 0x5f, ++ 0x6b, 0x3f, 0x7a, 0x32, 0xf7, 0x60, 0xe3, 0x4e, 0x7d, 0xa3, 0xac, 0x11, ++ 0xbd, 0x10, 0x8a, 0x5b, 0x95, 0x46, 0x27, 0x5c, 0x0b, 0x8c, 0x16, 0xe6, ++ 0x2f, 0xb1, 0xef, 0x2a, 0xa5, 0xb4, 0xdf, 0xc3, 0xd8, 0x34, 0xac, 0x07, ++ 0xb7, 0x2b, 0x06, 0xe3, 0x86, 0x86, 0xfd, 0x83, 0x45, 0xb8, 0x75, 0x57, ++ 0x1b, 0xf6, 0xf5, 0x9b, 0xc4, 0xcf, 0x5a, 0xff, 0x69, 0xbc, 0x87, 0x63, ++ 0xa6, 0xbc, 0xaf, 0x54, 0x82, 0x36, 0x4d, 0xf6, 0x29, 0x31, 0xfb, 0x9c, ++ 0x7e, 0xde, 0x3b, 0xe0, 0x9e, 0x12, 0xa3, 0xf0, 0x2e, 0xbf, 0xc1, 0x7c, ++ 0x71, 0x12, 0x7b, 0x06, 0x65, 0x6d, 0x60, 0x9a, 0x72, 0xa4, 0x7f, 0xae, ++ 0xaf, 0x8b, 0xd8, 0x7f, 0xaf, 0x99, 0xc5, 0x99, 0x85, 0xd5, 0xc0, 0x0c, ++ 0x05, 0xa1, 0xcf, 0x04, 0xe4, 0x5b, 0x35, 0xfc, 0x7b, 0xd7, 0xf2, 0x7f, ++ 0x51, 0xda, 0xa9, 0xa9, 0xc8, 0xad, 0x17, 0xbc, 0x5e, 0x2d, 0xef, 0xf2, ++ 0x1d, 0x49, 0xcd, 0xac, 0xcc, 0x3d, 0x77, 0xfe, 0xa4, 0x3e, 0x5e, 0xb3, ++ 0xfc, 0x76, 0x1b, 0x85, 0xba, 0xaf, 0x5a, 0x51, 0xaf, 0x94, 0x2f, 0x62, ++ 0xdb, 0xe2, 0x9f, 0xd3, 0x94, 0x76, 0xe2, 0xa9, 0x1a, 0x9a, 0xa6, 0xb4, ++ 0x0d, 0x5d, 0xd8, 0xee, 0x8b, 0x56, 0xb4, 0x45, 0xce, 0x0b, 0xe5, 0xdc, ++ 0xd3, 0x50, 0x2a, 0x65, 0x0b, 0xf7, 0x9f, 0xc9, 0xb7, 0x55, 0x4c, 0xae, ++ 0x9a, 0x2b, 0x73, 0x6b, 0xbf, 0xec, 0xad, 0x8a, 0xe2, 0x68, 0xc3, 0xd4, ++ 0xf6, 0x0a, 0x7d, 0x7f, 0xef, 0xbc, 0xf6, 0x72, 0x65, 0x67, 0xb1, 0x4d, ++ 0x29, 0x9f, 0xc5, 0xff, 0x6b, 0xaf, 0x23, 0xbc, 0x61, 0xef, 0x93, 0xdc, ++ 0x6a, 0x36, 0x46, 0x4b, 0xf0, 0x39, 0xa8, 0x97, 0xc6, 0xe7, 0x97, 0xd8, ++ 0xfc, 0x36, 0xda, 0x52, 0xc2, 0x1c, 0xd7, 0x6d, 0x44, 0xef, 0x75, 0x23, ++ 0x9b, 0x65, 0x5c, 0x6e, 0x3d, 0xa3, 0xec, 0x57, 0x6e, 0x0d, 0xe8, 0x1b, ++ 0xdf, 0x25, 0xdf, 0x78, 0x3e, 0x10, 0x27, 0xd6, 0x1b, 0xbe, 0x3e, 0x45, ++ 0x37, 0xd7, 0x32, 0xa6, 0x3d, 0xcb, 0x1c, 0x72, 0x4d, 0xa0, 0xd7, 0x7e, ++ 0xc6, 0xa8, 0x44, 0x56, 0xe0, 0x12, 0xfb, 0xbb, 0x2c, 0x2d, 0x30, 0xd2, ++ 0xcf, 0xcb, 0x9a, 0x17, 0x7f, 0xc7, 0x30, 0xdf, 0xbe, 0xb6, 0x06, 0x41, ++ 0xfb, 0xff, 0xaa, 0xfc, 0xb7, 0x5b, 0x5a, 0x51, 0x6b, 0xff, 0xbf, 0x19, ++ 0x73, 0xd3, 0x67, 0xd7, 0x86, 0xd1, 0x6d, 0x5a, 0xd6, 0x53, 0xa6, 0x85, ++ 0x37, 0xce, 0xed, 0xd1, 0x5e, 0xe1, 0x60, 0xce, 0x41, 0x17, 0x8e, 0xe5, ++ 0xbe, 0x5d, 0x75, 0xee, 0xfd, 0x8c, 0xa5, 0xe7, 0xed, 0xd1, 0x96, 0xf7, ++ 0xe2, 0xab, 0xed, 0x6f, 0x93, 0xcd, 0x5b, 0xe4, 0xc4, 0x73, 0x89, 0x8a, ++ 0x98, 0x87, 0xbf, 0x37, 0x2d, 0x2a, 0xc2, 0xfa, 0x10, 0x39, 0xdf, 0xa5, ++ 0xc7, 0x71, 0xda, 0xfe, 0x46, 0x43, 0x3c, 0x24, 0xdf, 0x66, 0x38, 0x9a, ++ 0x50, 0x71, 0x6c, 0xb0, 0x27, 0xb4, 0xc7, 0xee, 0xfb, 0x55, 0x74, 0x8f, ++ 0xca, 0x73, 0xbf, 0x16, 0xac, 0x4e, 0x4c, 0xda, 0x7b, 0xda, 0x36, 0xa7, ++ 0x24, 0xf7, 0xd6, 0xb3, 0x6b, 0x98, 0xaf, 0xaa, 0x8e, 0x20, 0x6e, 0x62, ++ 0x7c, 0x79, 0x21, 0x41, 0x3b, 0x5d, 0xa8, 0x77, 0x7c, 0x97, 0x1c, 0xa1, ++ 0x22, 0xa2, 0x07, 0xdf, 0x51, 0x5a, 0xc9, 0xc5, 0xdc, 0x98, 0x48, 0x88, ++ 0x2d, 0xca, 0xb7, 0x9d, 0x6e, 0xc6, 0x7e, 0x72, 0xd2, 0xe7, 0x13, 0x1a, ++ 0x4e, 0x37, 0x78, 0x90, 0x26, 0x47, 0x7d, 0x2e, 0xe1, 0xc6, 0x63, 0xe4, ++ 0xa8, 0x8f, 0x0e, 0xca, 0x1a, 0x61, 0x13, 0x1a, 0x13, 0xb2, 0x3e, 0x4c, ++ 0xde, 0x35, 0xe2, 0xa5, 0x3d, 0x5a, 0x56, 0x37, 0x6d, 0xb7, 0x4d, 0x9b, ++ 0x60, 0x9f, 0xb2, 0xae, 0x18, 0xc5, 0x35, 0xe4, 0x1d, 0x8f, 0x8e, 0xf8, ++ 0xf0, 0x7d, 0x72, 0xf3, 0x24, 0xeb, 0xbd, 0x90, 0xf0, 0xa3, 0x2f, 0xed, ++ 0xc3, 0xd3, 0xe4, 0xe8, 0x5b, 0x78, 0x2e, 0xdf, 0x09, 0x2b, 0x32, 0x82, ++ 0xe4, 0xc1, 0x87, 0x51, 0xd6, 0x77, 0x11, 0xd6, 0xad, 0x3c, 0x08, 0xb5, ++ 0xef, 0x10, 0x8f, 0x2b, 0x19, 0xb3, 0xaf, 0x44, 0x6a, 0x30, 0x82, 0xd4, ++ 0xc8, 0x8f, 0xd0, 0x3b, 0x28, 0xe3, 0x92, 0xef, 0x3d, 0xc9, 0xbe, 0x27, ++ 0x72, 0xbd, 0x3e, 0x2f, 0x86, 0x46, 0xa4, 0x9f, 0x6a, 0xf6, 0xfd, 0xe7, ++ 0xb6, 0xff, 0x1f, 0xd6, 0xba, 0x1b, 0xa5, 0xed, 0x83, 0x9f, 0xd0, 0xbe, ++ 0xe8, 0xaa, 0xf0, 0x9e, 0xa1, 0xac, 0x75, 0xb8, 0xd9, 0xa6, 0x07, 0x8e, ++ 0x48, 0x76, 0x65, 0x39, 0xf4, 0xe8, 0x36, 0xc5, 0x68, 0x2e, 0x53, 0x26, ++ 0xb1, 0x2d, 0x23, 0xef, 0x8d, 0x15, 0xe3, 0x69, 0xe2, 0xa3, 0x2b, 0xa4, ++ 0x6b, 0xdf, 0xa5, 0xed, 0x2c, 0x21, 0xa6, 0xbc, 0x61, 0x7e, 0x06, 0x71, ++ 0x4d, 0xf4, 0x57, 0x8c, 0x1f, 0xf4, 0xbb, 0xf1, 0x4e, 0x28, 0x82, 0xdc, ++ 0xb7, 0xbd, 0x3c, 0xf8, 0x71, 0xc2, 0xcb, 0xf9, 0xaa, 0xcb, 0x1a, 0x8e, ++ 0xb9, 0xc0, 0xb4, 0xdc, 0xb5, 0xa3, 0x89, 0x35, 0xd8, 0x43, 0x79, 0x5f, ++ 0x48, 0x9c, 0xe1, 0xfc, 0xb4, 0x53, 0xff, 0xa2, 0xef, 0x78, 0x5e, 0xd7, ++ 0x3d, 0xd4, 0xf5, 0x2c, 0x3c, 0x9b, 0xb8, 0x0f, 0x8f, 0x52, 0xfe, 0x47, ++ 0xfa, 0x8d, 0xe8, 0xc5, 0xca, 0x61, 0xe2, 0x65, 0x31, 0x8e, 0xb1, 0xed, ++ 0x5b, 0x99, 0x29, 0x4f, 0x4a, 0x5f, 0x29, 0x59, 0x9f, 0x54, 0xf0, 0xce, ++ 0xa2, 0xc3, 0x18, 0xe7, 0xbd, 0x1f, 0xf3, 0x77, 0x78, 0x61, 0x25, 0xfb, ++ 0x10, 0xfd, 0xf8, 0xed, 0x5c, 0xa0, 0x8b, 0x3c, 0x67, 0x79, 0xc3, 0x61, ++ 0x6c, 0x1d, 0x92, 0x6b, 0x6d, 0xe8, 0xed, 0x7f, 0x0f, 0x8e, 0x10, 0x71, ++ 0xc8, 0xdb, 0x40, 0x5b, 0xcf, 0x62, 0x5b, 0xfa, 0xc3, 0x69, 0x39, 0x0e, ++ 0xfa, 0xca, 0x34, 0xd9, 0x8b, 0x7c, 0x34, 0x51, 0x8c, 0xe7, 0x58, 0x67, ++ 0x5d, 0xc8, 0x95, 0x7f, 0x66, 0x72, 0x98, 0xfc, 0xc9, 0x89, 0x34, 0xfb, ++ 0x48, 0xd8, 0x6d, 0x4c, 0x53, 0x76, 0xd3, 0x0f, 0x2b, 0x17, 0x4e, 0x53, ++ 0x52, 0x43, 0xc2, 0xed, 0x7f, 0x84, 0x27, 0xef, 0xcf, 0xe9, 0x70, 0x8f, ++ 0xb9, 0x06, 0x43, 0xe9, 0x1f, 0x17, 0xda, 0x9b, 0xf2, 0x2e, 0x9c, 0xbc, ++ 0x9f, 0x53, 0x78, 0x57, 0x27, 0xf7, 0x4c, 0xeb, 0xdb, 0x99, 0x0a, 0xf2, ++ 0xe7, 0x52, 0xda, 0x5a, 0x51, 0xcc, 0xcb, 0xb8, 0xba, 0x66, 0x81, 0x86, ++ 0x9d, 0x97, 0xd5, 0x4d, 0x43, 0x85, 0xe6, 0xfc, 0x75, 0xc3, 0xf3, 0xec, ++ 0xa7, 0x22, 0x56, 0x15, 0xd9, 0x63, 0xef, 0x83, 0x0a, 0x5d, 0x56, 0xc3, ++ 0xb8, 0x22, 0xcf, 0x86, 0x63, 0x78, 0x2b, 0x51, 0x1d, 0xab, 0x8e, 0x54, ++ 0x12, 0x6f, 0x4f, 0xa3, 0x6f, 0xd8, 0x89, 0x0a, 0xf2, 0xe6, 0xf2, 0x64, ++ 0x35, 0xdc, 0xf6, 0x3a, 0xde, 0x45, 0xe4, 0x2b, 0xb3, 0xc9, 0x49, 0x66, ++ 0xa1, 0x92, 0xbc, 0xc4, 0x13, 0xb2, 0xac, 0x9f, 0x2d, 0xb4, 0xac, 0x4b, ++ 0x78, 0x94, 0xf0, 0x38, 0x15, 0x12, 0x3f, 0x8d, 0xa2, 0xce, 0xf6, 0x57, ++ 0x03, 0xf5, 0xf6, 0xff, 0x26, 0xfa, 0x7a, 0x47, 0x68, 0xfe, 0xf8, 0x7d, ++ 0xa1, 0xb9, 0xe3, 0x35, 0x50, 0x07, 0xa6, 0xc3, 0xc1, 0xb6, 0xbe, 0x70, ++ 0x99, 0x85, 0x26, 0xfa, 0xf0, 0x5a, 0x53, 0x78, 0xd1, 0x1a, 0xf2, 0xa2, ++ 0xde, 0x90, 0x31, 0x7e, 0x10, 0x57, 0x33, 0xce, 0xb9, 0x07, 0x7c, 0xec, ++ 0x47, 0x72, 0x6c, 0x67, 0x76, 0x0e, 0xf9, 0xf6, 0x67, 0x16, 0x0a, 0x47, ++ 0x6a, 0x25, 0x47, 0x3a, 0x84, 0xd6, 0xf1, 0xc3, 0xb8, 0x9e, 0x65, 0x3c, ++ 0xe4, 0x2a, 0xc9, 0xcc, 0x8f, 0xd0, 0x97, 0xb1, 0xb0, 0x3d, 0x94, 0xc5, ++ 0xb5, 0x6c, 0xbb, 0x74, 0xa0, 0x99, 0xdc, 0x70, 0x05, 0xd6, 0x8d, 0xcb, ++ 0xbb, 0x52, 0x13, 0x58, 0x3e, 0x4e, 0xce, 0x39, 0x5e, 0xf0, 0x57, 0xe1, ++ 0x4b, 0x2b, 0xc8, 0x97, 0x64, 0x2d, 0x6d, 0x95, 0xbd, 0x96, 0xa6, 0xd2, ++ 0x0f, 0x1b, 0x13, 0xf2, 0x9e, 0x50, 0x1c, 0xab, 0xc7, 0x05, 0xab, 0xef, ++ 0x41, 0xf7, 0xb8, 0xac, 0xcd, 0x7e, 0x33, 0x74, 0xf1, 0xf8, 0xab, 0x68, ++ 0x1c, 0x1f, 0x0a, 0xcd, 0x1b, 0x1f, 0xa1, 0xdc, 0x09, 0xca, 0xd6, 0x1f, ++ 0xaa, 0x1d, 0x1f, 0x0c, 0x05, 0xc7, 0x77, 0x87, 0x02, 0xe3, 0x2d, 0xd8, ++ 0x32, 0xbe, 0x0a, 0x9b, 0xc7, 0x37, 0x62, 0xd3, 0xb8, 0xe0, 0xfc, 0x24, ++ 0x96, 0x8d, 0xbf, 0x81, 0xa5, 0xe3, 0xcf, 0xa3, 0x69, 0xfc, 0x04, 0x96, ++ 0x8c, 0xff, 0x08, 0xcd, 0xe3, 0xaf, 0x70, 0x2c, 0xb2, 0xd6, 0x2b, 0xeb, ++ 0xbc, 0x85, 0xe7, 0x6a, 0x53, 0xf7, 0x24, 0xcb, 0x5a, 0x86, 0x7c, 0xbf, ++ 0x43, 0xe6, 0xd0, 0x85, 0x95, 0xda, 0x6b, 0xe8, 0xd9, 0x25, 0xdf, 0x24, ++ 0xac, 0xd3, 0xba, 0xe5, 0xf9, 0xa3, 0xf7, 0x79, 0xd9, 0x63, 0x4f, 0x1b, ++ 0x3b, 0xff, 0xbd, 0xbc, 0xc9, 0xb3, 0xcf, 0x18, 0xe5, 0x1b, 0x18, 0xf2, ++ 0xec, 0x73, 0x12, 0x5d, 0x99, 0xdf, 0x5a, 0x51, 0x4d, 0xca, 0xca, 0xf7, ++ 0x3f, 0xc4, 0x1e, 0x5e, 0xc3, 0x43, 0xbb, 0x26, 0xc9, 0x59, 0xb2, 0xf6, ++ 0x5a, 0xcd, 0xbb, 0xf3, 0xe4, 0x9b, 0x56, 0xf2, 0xce, 0xfe, 0x6b, 0x48, ++ 0x8d, 0x02, 0xe3, 0x0f, 0x8b, 0x1f, 0xae, 0xa1, 0x1f, 0x66, 0xc5, 0x27, ++ 0xe3, 0xc4, 0xe4, 0xaf, 0x78, 0x70, 0x0f, 0x79, 0x49, 0x11, 0xb2, 0x23, ++ 0xa5, 0x78, 0x66, 0x30, 0x6e, 0xcd, 0x31, 0x3c, 0x28, 0x8f, 0x18, 0xd9, ++ 0x4b, 0x18, 0x67, 0x5f, 0xe1, 0xb5, 0x89, 0x7e, 0xf8, 0x7d, 0x46, 0xc0, ++ 0x37, 0x87, 0xe7, 0xc7, 0x86, 0xb2, 0xe4, 0x14, 0x1d, 0x98, 0xe4, 0x7f, ++ 0xc9, 0x41, 0x81, 0x6e, 0x0c, 0x0d, 0x89, 0x3e, 0x5b, 0xa8, 0x4f, 0xc1, ++ 0x45, 0xbd, 0xa3, 0x89, 0x78, 0x68, 0x29, 0x82, 0x87, 0x2a, 0xca, 0x1e, ++ 0xe8, 0xa4, 0xbf, 0xea, 0xb1, 0x9f, 0x30, 0x16, 0xf4, 0x29, 0x3f, 0xc2, ++ 0x73, 0xcc, 0x19, 0x4a, 0x1f, 0x20, 0xff, 0x20, 0x56, 0x56, 0x44, 0x14, ++ 0x63, 0x79, 0xe0, 0x14, 0x9e, 0x19, 0x71, 0xc2, 0x9d, 0x74, 0x62, 0x82, ++ 0x38, 0xe9, 0x48, 0xca, 0xf3, 0x7a, 0x8d, 0xb2, 0xc8, 0xba, 0xd0, 0x09, ++ 0x64, 0xed, 0xe7, 0x69, 0xf2, 0x3c, 0xe4, 0x45, 0xbb, 0x1f, 0x27, 0x65, ++ 0xef, 0x21, 0x96, 0x76, 0xa5, 0x5e, 0x42, 0xd3, 0x90, 0x07, 0x73, 0x92, ++ 0x13, 0xcc, 0x5f, 0x5e, 0x45, 0x6a, 0xd7, 0x2c, 0x7c, 0x95, 0x3c, 0x70, ++ 0x66, 0xd2, 0x84, 0x46, 0xbd, 0xdd, 0x34, 0x66, 0x22, 0xba, 0x77, 0x15, ++ 0x56, 0xee, 0xfd, 0x22, 0x8f, 0xe9, 0xb8, 0x7e, 0x6f, 0x3b, 0x3e, 0x3f, ++ 0x16, 0x47, 0xeb, 0x58, 0x0f, 0x8f, 0x36, 0x5c, 0xb7, 0xa3, 0x12, 0xe9, ++ 0x90, 0xc6, 0x9c, 0xba, 0x8d, 0x39, 0xb5, 0xf0, 0xa1, 0xd5, 0x78, 0x86, ++ 0xb8, 0x13, 0x0c, 0xad, 0xc6, 0x84, 0xed, 0x8b, 0xb2, 0x97, 0x71, 0x35, ++ 0x36, 0x31, 0x5f, 0x1e, 0xc6, 0x6a, 0x74, 0xf1, 0xda, 0x0e, 0x7b, 0x0e, ++ 0x0e, 0x63, 0x31, 0xf3, 0xa1, 0xf7, 0x2f, 0x3f, 0x8c, 0x2b, 0xf6, 0x48, ++ 0xdf, 0xa7, 0x91, 0xda, 0xb9, 0x86, 0x6d, 0x66, 0xd1, 0x32, 0xf6, 0x43, ++ 0x7c, 0x7e, 0x07, 0x6e, 0xab, 0x44, 0x25, 0x9e, 0x0f, 0x05, 0x5a, 0xfb, ++ 0x94, 0x1f, 0xda, 0x6d, 0x6f, 0xa2, 0x1f, 0x6f, 0x65, 0xb9, 0x47, 0xd2, ++ 0x27, 0xd0, 0x9b, 0x9a, 0x3a, 0xa7, 0xf6, 0x7b, 0xed, 0x8c, 0x07, 0x2f, ++ 0x63, 0xdf, 0xc8, 0x24, 0xb1, 0xf7, 0x24, 0x8f, 0x0b, 0x9f, 0x5f, 0x7b, ++ 0xed, 0x7c, 0x26, 0x67, 0x37, 0x92, 0xbf, 0xc8, 0x3a, 0x70, 0x0b, 0x7c, ++ 0x29, 0xe1, 0x44, 0xd9, 0xad, 0x33, 0xa1, 0x6f, 0x0c, 0xdb, 0x1c, 0xc9, ++ 0x88, 0x91, 0x1b, 0xb5, 0x7c, 0x57, 0xf1, 0x90, 0x1b, 0x05, 0xb1, 0x22, ++ 0xa3, 0x47, 0xaf, 0xa5, 0xbe, 0x4b, 0xee, 0x7f, 0x19, 0xce, 0xfb, 0x9d, ++ 0x28, 0x4e, 0xca, 0xda, 0xc9, 0x04, 0x7a, 0x33, 0xf2, 0xfe, 0x6e, 0x56, ++ 0x2f, 0x26, 0xae, 0x16, 0x25, 0xb3, 0x8c, 0xfd, 0xd9, 0xf9, 0x45, 0x90, ++ 0x77, 0xf1, 0xaf, 0xc2, 0x9a, 0xfe, 0x28, 0xba, 0x4c, 0x79, 0x57, 0x27, ++ 0x37, 0xfe, 0x39, 0x0d, 0x2f, 0xa3, 0x9b, 0xf1, 0xa7, 0x8d, 0x98, 0xf8, ++ 0x55, 0xfb, 0x59, 0xe8, 0xcb, 0xe8, 0x19, 0x2c, 0xbc, 0xbb, 0x2e, 0x6d, ++ 0x3e, 0x4f, 0xbd, 0xb9, 0xf2, 0xdf, 0xec, 0x91, 0x36, 0x75, 0xd3, 0xaf, ++ 0x4e, 0xcb, 0xbd, 0x8b, 0x03, 0xfb, 0x19, 0x36, 0xed, 0xe3, 0x35, 0xf4, ++ 0xee, 0x2a, 0x8c, 0x99, 0xb9, 0x41, 0xe0, 0x35, 0xf4, 0x8f, 0xca, 0xd8, ++ 0xaf, 0x9f, 0x96, 0x7b, 0xc7, 0x78, 0xaa, 0x3e, 0x0a, 0x75, 0x1d, 0xb4, ++ 0xe7, 0xc2, 0xfd, 0x8f, 0xfb, 0x6e, 0xd0, 0xa7, 0xec, 0x6f, 0xf0, 0xe4, ++ 0xbe, 0x81, 0x04, 0x3c, 0x99, 0x90, 0x77, 0xfb, 0xd5, 0xc5, 0x2e, 0xa8, ++ 0x5e, 0x17, 0x8a, 0x19, 0x2f, 0x6a, 0xd0, 0xed, 0xb5, 0x70, 0x35, 0xc7, ++ 0xb2, 0xbf, 0xfe, 0x3a, 0x66, 0x1a, 0xf1, 0x56, 0x97, 0xfd, 0xce, 0xe1, ++ 0x8a, 0xbf, 0xfe, 0xe8, 0x3b, 0x87, 0x6f, 0x10, 0x67, 0x15, 0x94, 0x1b, ++ 0x37, 0xe1, 0x05, 0x3b, 0xa6, 0x28, 0x28, 0x9b, 0x2b, 0xeb, 0x98, 0x7e, ++ 0x3c, 0x6b, 0xd4, 0xf9, 0xab, 0xe4, 0xf9, 0x94, 0x72, 0xca, 0x92, 0x6f, ++ 0x06, 0x6c, 0xcb, 0xfc, 0xb1, 0x3d, 0xf1, 0x4f, 0x61, 0xcb, 0xce, 0x30, ++ 0xe4, 0xfd, 0x15, 0xa7, 0xa1, 0x79, 0x73, 0xfc, 0x4a, 0x64, 0x93, 0xbd, ++ 0xe4, 0xb7, 0x12, 0x9c, 0xde, 0xa0, 0x9f, 0xbe, 0x21, 0x7b, 0xa6, 0xc8, ++ 0x99, 0xfe, 0x12, 0xc1, 0xaa, 0xc2, 0x38, 0x65, 0xaf, 0xa9, 0x92, 0x1b, ++ 0xab, 0x5d, 0x47, 0xca, 0x4a, 0xbd, 0x37, 0xec, 0x35, 0x5c, 0x97, 0xf1, ++ 0x5b, 0xeb, 0x4d, 0x6f, 0x35, 0xcb, 0x1e, 0xce, 0xdf, 0x9f, 0x14, 0x9f, ++ 0x33, 0xe5, 0x1b, 0x56, 0x4e, 0xbb, 0x8e, 0xe8, 0xf7, 0x5c, 0x9d, 0xee, ++ 0x94, 0x83, 0xb8, 0x79, 0xc2, 0xea, 0xf4, 0xca, 0x18, 0xee, 0xbc, 0xa0, ++ 0x8e, 0xac, 0x2b, 0x68, 0xd2, 0x6f, 0x58, 0xc6, 0xdc, 0x95, 0xf9, 0x68, ++ 0x9f, 0xb2, 0xde, 0x5b, 0x64, 0x94, 0xe1, 0x54, 0x55, 0x6e, 0x1d, 0xe6, ++ 0x9c, 0x8c, 0x3d, 0x35, 0xb2, 0x4f, 0xaf, 0xd8, 0x3e, 0xb7, 0xfb, 0x35, ++ 0xcf, 0xd5, 0xfb, 0xbb, 0xfc, 0x78, 0xab, 0xed, 0x77, 0x86, 0x1e, 0xb4, ++ 0x79, 0x91, 0x63, 0xca, 0xb8, 0x4b, 0x6a, 0xce, 0xef, 0xe7, 0x2b, 0xf9, ++ 0x7e, 0x45, 0x1e, 0xef, 0x94, 0x3e, 0x44, 0xae, 0x87, 0xf3, 0x75, 0xf4, ++ 0x70, 0xd4, 0xee, 0x5f, 0x65, 0xbe, 0x55, 0xe8, 0x93, 0xfe, 0xb8, 0xb0, ++ 0xd0, 0x46, 0x56, 0xec, 0xb3, 0xb3, 0x98, 0xb1, 0xed, 0x54, 0xc3, 0x3d, ++ 0xd8, 0x94, 0x10, 0x3d, 0xcb, 0xb7, 0x60, 0x89, 0xe1, 0x36, 0x57, 0x73, ++ 0xd1, 0x5f, 0x2f, 0xc3, 0x90, 0x16, 0xc7, 0x9e, 0x7a, 0x79, 0x47, 0xce, ++ 0x45, 0x9f, 0x88, 0xa3, 0xc4, 0x28, 0x96, 0xfd, 0xc7, 0xf6, 0x1e, 0x94, ++ 0x7d, 0xa6, 0x1e, 0x7d, 0x52, 0xbe, 0x55, 0x76, 0xa9, 0xbd, 0x5e, 0xd5, ++ 0x3c, 0x04, 0xb9, 0x6e, 0xe2, 0xda, 0xf3, 0xf2, 0xfe, 0x12, 0xda, 0x8e, ++ 0xbd, 0x27, 0xda, 0x94, 0x77, 0xe8, 0xfa, 0x12, 0xf2, 0x2e, 0x57, 0x5d, ++ 0x8c, 0xfc, 0x12, 0x2f, 0xa4, 0x65, 0xbf, 0xc2, 0xef, 0xac, 0x78, 0x8d, ++ 0xec, 0x8b, 0x9c, 0x5a, 0xa7, 0x88, 0xb8, 0x16, 0x08, 0x57, 0x28, 0x85, ++ 0xf7, 0xb9, 0xce, 0xfd, 0x5d, 0x4f, 0x9b, 0x39, 0x6d, 0xbf, 0x83, 0x27, ++ 0x67, 0x11, 0x34, 0xa6, 0xe4, 0x9b, 0xa7, 0xfa, 0xc4, 0x72, 0xd4, 0x65, ++ 0x6b, 0x1d, 0xce, 0x3c, 0x7f, 0x09, 0x63, 0x05, 0xed, 0x66, 0x73, 0x20, ++ 0x6c, 0xbf, 0x6b, 0xb6, 0x2c, 0x55, 0x1b, 0x7c, 0x04, 0x7a, 0xfb, 0xdb, ++ 0x2c, 0x7f, 0x5d, 0xe6, 0xfb, 0xd6, 0x90, 0x57, 0xc6, 0x54, 0xc0, 0x88, ++ 0x13, 0xf4, 0x0d, 0xea, 0x31, 0x22, 0xfe, 0xe1, 0x41, 0x55, 0x24, 0x4c, ++ 0x3f, 0x96, 0xf8, 0x2f, 0xef, 0xa9, 0xe9, 0xbb, 0xe3, 0x30, 0xd1, 0xc8, ++ 0x1c, 0xdd, 0x65, 0xef, 0x73, 0xd6, 0xfd, 0x2b, 0x19, 0x87, 0x8e, 0x9c, ++ 0xdd, 0x13, 0x20, 0x7c, 0xe1, 0xc7, 0x35, 0xf9, 0xbd, 0xd0, 0xee, 0x39, ++ 0x8c, 0x8f, 0x96, 0xfd, 0x9c, 0x7f, 0x8d, 0x8d, 0x2d, 0x9a, 0xa1, 0xef, ++ 0xff, 0x95, 0xa3, 0x13, 0x4f, 0x2c, 0x30, 0x3a, 0x0e, 0xa8, 0xd9, 0x21, ++ 0x1f, 0x71, 0xe6, 0x4a, 0x47, 0x74, 0x07, 0xff, 0xfb, 0x5f, 0xb4, 0xbf, ++ 0xa1, 0x22, 0x75, 0xf5, 0xe0, 0x2a, 0x55, 0xf6, 0x0f, 0xb5, 0x60, 0xac, ++ 0x4f, 0xde, 0x7d, 0xd0, 0x5b, 0xbf, 0xad, 0x74, 0x62, 0x43, 0xc8, 0x68, ++ 0xd9, 0xa8, 0xe8, 0xcd, 0x7f, 0xaf, 0xe8, 0xfe, 0x90, 0x22, 0xe5, 0x82, ++ 0xb2, 0xb6, 0x77, 0x36, 0xf6, 0xba, 0xd8, 0xc7, 0xde, 0x84, 0x1e, 0x9e, ++ 0xc6, 0xb2, 0xa7, 0x4c, 0xc3, 0xf7, 0x1e, 0xdb, 0xfc, 0x09, 0x8f, 0x1d, ++ 0xf6, 0x3b, 0xec, 0x52, 0x3e, 0x3a, 0xdf, 0x65, 0x7f, 0x8f, 0xb8, 0x95, ++ 0x31, 0x45, 0xbe, 0x35, 0x1c, 0x83, 0x96, 0x9c, 0x45, 0x13, 0xd3, 0x7b, ++ 0x6f, 0x80, 0xe4, 0xc0, 0x37, 0x4f, 0x47, 0xa9, 0x07, 0xde, 0x48, 0x27, ++ 0xe6, 0x2e, 0x30, 0x7c, 0x8b, 0x54, 0xbb, 0x7e, 0x30, 0xaa, 0x4a, 0x7d, ++ 0xdd, 0x3f, 0x08, 0x69, 0x23, 0x6b, 0x69, 0x73, 0x2b, 0xed, 0x3a, 0x0b, ++ 0xd4, 0xcf, 0xc1, 0xf5, 0xe9, 0x5f, 0xcb, 0x37, 0x8b, 0xb4, 0x6a, 0x43, ++ 0xea, 0xc4, 0x77, 0x68, 0xf8, 0x63, 0xf5, 0x04, 0x57, 0x7e, 0x65, 0x61, ++ 0xba, 0xd4, 0x93, 0x3d, 0x66, 0x37, 0xe3, 0x76, 0xfb, 0xbb, 0x2b, 0xe2, ++ 0x8f, 0x7a, 0xf4, 0x6e, 0x72, 0xd5, 0x52, 0x45, 0x78, 0xaa, 0xc4, 0xa2, ++ 0x36, 0xe2, 0x61, 0x27, 0xb4, 0x90, 0xde, 0x7b, 0x91, 0xea, 0x41, 0x71, ++ 0x64, 0x54, 0xf6, 0xd9, 0xec, 0x9e, 0xa7, 0xe6, 0xf6, 0xe3, 0xc4, 0xd8, ++ 0xee, 0x91, 0x3f, 0xfa, 0xdc, 0x97, 0x7d, 0x95, 0x9a, 0xf2, 0xce, 0x8e, ++ 0xfd, 0x9e, 0x48, 0x5b, 0xc2, 0x91, 0xdf, 0x5f, 0x58, 0x98, 0x5b, 0x0d, ++ 0x6b, 0x98, 0x17, 0xac, 0x95, 0x6f, 0x63, 0x72, 0xac, 0xeb, 0x12, 0xb2, ++ 0x0a, 0xf5, 0x7f, 0x01, 0x28, 0xfc, 0xfc, 0x40, 0x38, 0x5a, 0x00, 0x00, ++ 0x00 }; + + static const u32 bnx2_CP_b06FwData[(0x84/4) + 1] = { + 0x00000000, 0x0000001b, 0x0000000f, 0x0000000a, 0x00000008, 0x00000006, +@@ -2119,51 +2137,50 @@ + 0x00000002, 0x00000002, 0x00000002, 0x00000002, 0x00000002, 0x00000002, + 0x00000002, 0x00000002, 0x00000002, 0x00000002, 0x00000002, 0x00000002, + 0x00000001, 0x00000001, 0x00000001, 0x00000000 }; +-static const u32 bnx2_CP_b06FwRodata[(0x134/4) + 1] = { +- 0x08000f30, 0x08000d88, 0x08000fc4, 0x0800106c, 0x08000f58, 0x08000f98, +- 0x080011a4, 0x08000da4, 0x080011c8, 0x08000df4, 0x08001498, 0x08001440, +- 0x08000da4, 0x08000da4, 0x08000da4, 0x08001254, 0x08001254, 0x08000da4, +- 0x08000da4, 0x080016e0, 0x08000da4, 0x08000da4, 0x08000da4, 0x08000da4, +- 0x080013d4, 0x08000da4, 0x08000da4, 0x08000da4, 0x08000da4, 0x08000da4, +- 0x08000da4, 0x08000da4, 0x08000da4, 0x08000da4, 0x08000da4, 0x08000da4, +- 0x08000da4, 0x08000da4, 0x08000da4, 0x08000fb8, 0x08000da4, 0x08000da4, +- 0x08001690, 0x08000da4, 0x08000da4, 0x08000da4, 0x08000da4, 0x08000da4, +- 0x08000da4, 0x08000da4, 0x08000da4, 0x08000da4, 0x08000da4, 0x08000da4, +- 0x08000da4, 0x08000da4, 0x08000da4, 0x08000da4, 0x08000da4, 0x08000da4, +- 0x080015bc, 0x08000da4, 0x08000da4, 0x08001348, 0x080012b8, 0x08002e50, +- 0x08002e58, 0x08002e20, 0x08002e2c, 0x08002e38, 0x08002e44, 0x0800532c, +- 0x080052ec, 0x080052b8, 0x0800528c, 0x08005268, 0x08005224, 0x00000000 +-}; ++static const u32 bnx2_CP_b06FwRodata[(0x130/4) + 1] = { ++ 0x08001e8c, 0x08001d18, 0x08001e68, 0x08001e44, 0x08001e20, 0x08001dfc, ++ 0x08001dd4, 0x08001dac, 0x08001d80, 0x08001f84, 0x08001f74, 0x08001d34, ++ 0x08001d34, 0x08001d34, 0x08001eb4, 0x08001eb4, 0x08001d34, 0x08001d34, ++ 0x08001f64, 0x08001d34, 0x08001d34, 0x08001d34, 0x08001d34, 0x08001f54, ++ 0x08001d34, 0x08001d34, 0x08001d34, 0x08001d34, 0x08001d34, 0x08001d34, ++ 0x08001d34, 0x08001d34, 0x08001d34, 0x08001d34, 0x08001d34, 0x08001d34, ++ 0x08001d34, 0x08001d34, 0x08001f44, 0x08001d34, 0x08001d34, 0x08001f34, ++ 0x08001d34, 0x08001d34, 0x08001d34, 0x08001d34, 0x08001d34, 0x08001d34, ++ 0x08001d34, 0x08001d34, 0x08001d34, 0x08001d34, 0x08001d34, 0x08001d34, ++ 0x08001d34, 0x08001d34, 0x08001d34, 0x08001d34, 0x08001d34, 0x08001f1c, ++ 0x08001d34, 0x08001d34, 0x08001f0c, 0x08001efc, 0x08003208, 0x08003210, ++ 0x080031d8, 0x080031e4, 0x080031f0, 0x080031fc, 0x08005694, 0x08005654, ++ 0x08005620, 0x080055f4, 0x080055d0, 0x0800558c, 0x00000000 }; + + static struct fw_info bnx2_cp_fw_06 = { +- /* Firmware version: 4.6.16 */ ++ /* Firmware version: 4.4.22 */ + .ver_major = 0x4, +- .ver_minor = 0x6, +- .ver_fix = 0x10, ++ .ver_minor = 0x4, ++ .ver_fix = 0x16, + + .start_addr = 0x08000080, + + .text_addr = 0x08000000, +- .text_len = 0x56cc, ++ .text_len = 0x5a34, + .text_index = 0x0, + .gz_text = bnx2_CP_b06FwText, + .gz_text_len = sizeof(bnx2_CP_b06FwText), + +- .data_addr = 0x08005820, ++ .data_addr = 0x08005b80, + .data_len = 0x84, + .data_index = 0x0, + .data = bnx2_CP_b06FwData, + +- .sbss_addr = 0x080058a4, +- .sbss_len = 0xf1, ++ .sbss_addr = 0x08005c04, ++ .sbss_len = 0xe9, + .sbss_index = 0x0, + +- .bss_addr = 0x08005998, ++ .bss_addr = 0x08005cf0, + .bss_len = 0x5d8, + .bss_index = 0x0, + +- .rodata_addr = 0x080056cc, +- .rodata_len = 0x134, ++ .rodata_addr = 0x08005a34, ++ .rodata_len = 0x130, + .rodata_index = 0x0, + .rodata = bnx2_CP_b06FwRodata, + }; +@@ -2185,747 +2202,761 @@ + }; + + static u8 bnx2_RXP_b06FwText[] = { +- 0xec, 0x5b, 0x5d, 0x6c, 0x1c, 0xd7, 0x75, 0x3e, 0x33, 0x3b, 0x24, 0x57, +- 0x14, 0x45, 0x8e, 0xa8, 0x15, 0xb5, 0xb2, 0x99, 0x64, 0x97, 0x1c, 0x89, +- 0x1b, 0x93, 0x50, 0x86, 0xec, 0x5a, 0x66, 0x92, 0x45, 0xbc, 0x59, 0x52, +- 0x16, 0x53, 0x08, 0xf0, 0xda, 0x56, 0x5c, 0xa3, 0x31, 0x90, 0xc5, 0x92, +- 0x76, 0xd2, 0x37, 0xc9, 0xa9, 0x5d, 0x21, 0xb1, 0xab, 0xf5, 0x92, 0x91, +- 0x15, 0x75, 0xc5, 0x61, 0x24, 0x26, 0x72, 0x1b, 0xb7, 0xa0, 0xf9, 0x23, +- 0xaa, 0xc1, 0x4a, 0xe3, 0x9f, 0xd8, 0xf5, 0x43, 0x64, 0x31, 0xb2, 0xad, +- 0xfa, 0xa5, 0x80, 0xd3, 0x1f, 0xc0, 0x28, 0x8c, 0x56, 0x90, 0x6b, 0xd9, +- 0x68, 0x81, 0x42, 0x6d, 0x51, 0xd4, 0x6d, 0x64, 0x4d, 0xbf, 0xef, 0xce, +- 0x0c, 0xb9, 0x22, 0x94, 0xc6, 0x2f, 0x7d, 0x9b, 0x0b, 0x2c, 0xee, 0xdc, +- 0x3b, 0xe7, 0x9e, 0x7b, 0xce, 0xb9, 0xe7, 0xf7, 0x0e, 0xf9, 0x44, 0x9b, +- 0xb4, 0x4a, 0xd0, 0x36, 0xe1, 0x97, 0x3d, 0x70, 0xe8, 0xb1, 0xc1, 0x5d, +- 0xbb, 0x77, 0xe1, 0x71, 0x77, 0xcc, 0x6c, 0x36, 0x38, 0xaf, 0x49, 0xd4, +- 0xa2, 0x16, 0xb5, 0xa8, 0x45, 0x2d, 0x6a, 0x51, 0x8b, 0x5a, 0xd4, 0xa2, +- 0x16, 0xb5, 0xa8, 0x45, 0x2d, 0x6a, 0x51, 0x8b, 0x5a, 0xd4, 0xa2, 0x16, +- 0xb5, 0xa8, 0x45, 0x2d, 0x6a, 0x51, 0x8b, 0x5a, 0xd4, 0xa2, 0x16, 0xb5, +- 0xa8, 0x45, 0x2d, 0x6a, 0x51, 0x8b, 0x5a, 0xd4, 0xa2, 0x16, 0xb5, 0xa8, +- 0x45, 0x2d, 0x6a, 0x51, 0x8b, 0x5a, 0xd4, 0xa2, 0x16, 0xb5, 0xa8, 0x45, +- 0x2d, 0x6a, 0x51, 0x8b, 0x5a, 0xd4, 0xfe, 0x3f, 0x5a, 0x4c, 0xc4, 0x64, +- 0xbf, 0x29, 0xf8, 0x49, 0x5c, 0xcf, 0xa5, 0x0e, 0x16, 0x2c, 0x89, 0xc7, +- 0x72, 0x6f, 0x3f, 0x3e, 0x6e, 0x89, 0xe4, 0xeb, 0xfd, 0xa9, 0x11, 0xf9, +- 0xc4, 0xab, 0x24, 0x0c, 0xe1, 0xfc, 0x67, 0x72, 0xd7, 0x0f, 0x9f, 0xbf, +- 0x2b, 0x7d, 0x6d, 0x2e, 0x26, 0x71, 0x33, 0xf7, 0xee, 0xa0, 0xb9, 0x53, +- 0xe2, 0xdd, 0x58, 0xf3, 0x5c, 0xdf, 0xc4, 0x66, 0x69, 0x0f, 0x71, 0x79, +- 0xde, 0x92, 0xed, 0xc9, 0x25, 0xbb, 0xa2, 0x8d, 0xf4, 0xbd, 0xa6, 0x15, +- 0x9c, 0x1b, 0x5e, 0xde, 0xd0, 0x45, 0x07, 0xbe, 0x89, 0x7a, 0x5c, 0x1e, +- 0x59, 0x6c, 0x95, 0x47, 0xe7, 0x36, 0x4a, 0x79, 0x4e, 0x4c, 0x3d, 0x97, +- 0x94, 0x6f, 0x61, 0xee, 0x72, 0x0c, 0x70, 0xae, 0x94, 0x62, 0xb9, 0x8f, +- 0xef, 0x2d, 0xd7, 0x08, 0x2f, 0xba, 0x9e, 0x5b, 0xb9, 0x77, 0xa2, 0xfe, +- 0xe6, 0xbd, 0xe5, 0x3a, 0xe1, 0x08, 0x83, 0x77, 0xf5, 0x8f, 0xbc, 0xf3, +- 0x7d, 0x09, 0xb9, 0xe0, 0x9a, 0xf2, 0x82, 0xfb, 0x32, 0xf6, 0x4c, 0x57, +- 0x2a, 0xd2, 0x24, 0xe5, 0x93, 0x37, 0xbc, 0x98, 0x95, 0x4e, 0x61, 0x13, +- 0x73, 0x44, 0xf0, 0xde, 0xc1, 0x7b, 0x07, 0xf3, 0x0b, 0x3f, 0xdf, 0x2c, +- 0xad, 0x49, 0x39, 0xdf, 0xc7, 0x75, 0x5c, 0xc3, 0xb5, 0x8b, 0xed, 0xfe, +- 0x3a, 0xc1, 0xba, 0xa2, 0xc4, 0x2c, 0x4f, 0x0a, 0xb6, 0x21, 0x23, 0x09, +- 0xd1, 0x74, 0xab, 0x02, 0x3a, 0x7e, 0xd1, 0x26, 0xad, 0xc4, 0x55, 0xd1, +- 0xf2, 0x2e, 0xfb, 0x10, 0xdf, 0x53, 0x1d, 0x3e, 0xae, 0x67, 0x81, 0xab, +- 0x24, 0xaf, 0xbb, 0x0f, 0xcb, 0x5f, 0xb8, 0x63, 0xf2, 0x92, 0x3b, 0x01, +- 0x9c, 0x0f, 0xc9, 0xab, 0xee, 0x7e, 0x79, 0xc5, 0x2d, 0xca, 0xcf, 0xdc, +- 0x7d, 0xf2, 0xb2, 0x3b, 0x2a, 0x2f, 0xba, 0x79, 0xec, 0x97, 0xd1, 0x8a, +- 0xce, 0xdd, 0x32, 0x7e, 0x92, 0x34, 0xa6, 0xaf, 0x41, 0x36, 0xf2, 0x98, +- 0xdd, 0x67, 0xea, 0xa2, 0x61, 0xcf, 0xf4, 0x6b, 0x22, 0x8f, 0x4a, 0x3e, +- 0x31, 0x2c, 0x73, 0x6e, 0x97, 0x56, 0x38, 0xd9, 0xa9, 0x8d, 0x9c, 0x24, +- 0x2d, 0x9e, 0x8c, 0xdb, 0xe9, 0x54, 0x21, 0x96, 0x36, 0x47, 0x62, 0x92, +- 0xdf, 0x03, 0xb9, 0x55, 0x9d, 0xa4, 0xe4, 0x4d, 0xc9, 0x1f, 0xb5, 0x0c, +- 0xc8, 0x53, 0x93, 0x58, 0x8e, 0x7c, 0x6e, 0xe1, 0x1c, 0x5a, 0x9b, 0x2c, +- 0xd4, 0x6c, 0x29, 0x3b, 0xf3, 0x5a, 0x39, 0xa1, 0x51, 0x04, 0x18, 0x0f, +- 0x60, 0xfc, 0x67, 0xc1, 0xf8, 0x4b, 0x52, 0x3e, 0x25, 0xf9, 0xc9, 0x59, +- 0xcf, 0x2b, 0xd8, 0x7f, 0x1c, 0xcc, 0x0d, 0x63, 0x4e, 0x97, 0xd8, 0x8f, +- 0x38, 0x37, 0x1b, 0xcc, 0x51, 0x1e, 0x9e, 0x8c, 0xd8, 0x14, 0x23, 0xe8, +- 0x35, 0x8b, 0xe8, 0x9b, 0xd1, 0x73, 0x8f, 0x8d, 0x9b, 0xfc, 0xff, 0x03, +- 0xe2, 0xf9, 0x26, 0xf0, 0x6c, 0x83, 0x66, 0x89, 0x7f, 0x36, 0x77, 0xf4, +- 0xe0, 0x3f, 0xf4, 0xad, 0x8d, 0xf5, 0xdc, 0x7b, 0x52, 0xa8, 0x69, 0x4a, +- 0x57, 0x34, 0x3c, 0xf7, 0xd4, 0x9f, 0xea, 0xf4, 0xf5, 0xc2, 0x69, 0x97, +- 0x56, 0xc8, 0xc9, 0x21, 0xfd, 0x29, 0xd0, 0xbf, 0x49, 0xb6, 0xfc, 0x90, +- 0x3c, 0xf4, 0xa7, 0x74, 0xc9, 0xa7, 0x0d, 0xb1, 0x65, 0xd1, 0x35, 0xb4, +- 0x11, 0x27, 0x2f, 0x7a, 0xce, 0x4a, 0x96, 0x45, 0x97, 0x52, 0x22, 0x2f, +- 0xcf, 0x64, 0xd3, 0xc3, 0x15, 0x49, 0x49, 0x79, 0xc8, 0x96, 0x65, 0x17, +- 0x90, 0x89, 0x8a, 0x5c, 0xcd, 0xa6, 0xed, 0xcb, 0xb2, 0x51, 0x56, 0x4c, +- 0x5b, 0x4e, 0xbb, 0x71, 0x79, 0xeb, 0xe4, 0x3e, 0xf9, 0x96, 0xc3, 0x73, +- 0x92, 0xfe, 0x26, 0x79, 0x5a, 0x96, 0xb2, 0x4f, 0x5f, 0x5b, 0xb2, 0x8f, +- 0xb7, 0x49, 0x3b, 0x75, 0xb0, 0xd6, 0xee, 0xd3, 0xfd, 0x15, 0xf0, 0x96, +- 0x87, 0x6c, 0xdb, 0x21, 0x33, 0x43, 0xf1, 0x55, 0x78, 0xb0, 0x13, 0x3d, +- 0xd7, 0xfd, 0xfd, 0x16, 0xe8, 0x83, 0x2d, 0x5a, 0x48, 0x63, 0x93, 0x14, +- 0xba, 0xb8, 0xe6, 0x25, 0xe0, 0xc0, 0xfb, 0x55, 0xda, 0x6f, 0xd3, 0x0a, +- 0xa7, 0xda, 0xc5, 0xf8, 0xd1, 0x9d, 0x38, 0x4f, 0x43, 0x1e, 0x19, 0xf2, +- 0xbc, 0xaf, 0xdb, 0x46, 0x6a, 0x42, 0x72, 0xa4, 0x5d, 0x36, 0x1f, 0xdf, +- 0x2a, 0x73, 0x66, 0x5c, 0x12, 0xc7, 0xc3, 0xbd, 0x5a, 0x82, 0xf3, 0xf9, +- 0x32, 0xf1, 0xa7, 0x52, 0xfa, 0xa6, 0x60, 0x1c, 0xd2, 0x34, 0x8a, 0x33, +- 0xea, 0x35, 0x7b, 0xf4, 0x21, 0x2d, 0xaf, 0xfe, 0x8f, 0x6a, 0x2c, 0x18, +- 0xef, 0xd2, 0xbe, 0x6a, 0x74, 0x89, 0x61, 0xcd, 0x43, 0xae, 0x86, 0x5c, +- 0x74, 0xc2, 0xf9, 0xb8, 0xf8, 0x70, 0x94, 0xb3, 0x0c, 0xae, 0xc9, 0x59, +- 0x06, 0x7b, 0xea, 0x4f, 0x07, 0x38, 0xf3, 0x01, 0xec, 0x06, 0xc9, 0x27, +- 0xdb, 0x78, 0xa6, 0x01, 0xec, 0x75, 0xf9, 0xce, 0x50, 0xfa, 0x0c, 0xff, +- 0x57, 0x6b, 0x6d, 0x0d, 0xdf, 0xdb, 0x32, 0xef, 0xaa, 0x35, 0xc9, 0xfb, +- 0x70, 0xb6, 0xa5, 0xe4, 0x1d, 0xe6, 0x82, 0x1e, 0xd3, 0xf2, 0x09, 0xe2, +- 0x6a, 0x96, 0xc7, 0x13, 0xbd, 0x18, 0x6b, 0x52, 0xfe, 0x12, 0xf5, 0xf5, +- 0x13, 0xf1, 0xe7, 0x39, 0x97, 0x3e, 0xda, 0xab, 0x1f, 0x03, 0x7d, 0x94, +- 0x41, 0x3a, 0x29, 0x10, 0x7e, 0x79, 0xe8, 0x36, 0xf0, 0x67, 0xa2, 0x0f, +- 0xf9, 0xdf, 0x2c, 0xf9, 0x22, 0xe9, 0x57, 0x76, 0x0a, 0x39, 0x27, 0xb1, +- 0xdf, 0xdd, 0xb0, 0xc9, 0xf5, 0xf6, 0x0a, 0x1b, 0x6d, 0xa7, 0xad, 0x7e, +- 0x11, 0x3c, 0xa7, 0x33, 0x22, 0x16, 0xe4, 0x95, 0x94, 0x66, 0x6b, 0x1a, +- 0x3c, 0x51, 0x2f, 0xb7, 0x61, 0x7e, 0xc3, 0xc7, 0x79, 0xc5, 0x7a, 0x38, +- 0xf7, 0x41, 0x20, 0xcb, 0x7d, 0x32, 0xe1, 0xec, 0x57, 0x3c, 0x57, 0xf5, +- 0xcb, 0x92, 0xef, 0xee, 0x35, 0xa7, 0x40, 0x6f, 0xc1, 0x48, 0xcf, 0x55, +- 0x24, 0x29, 0x0b, 0xf0, 0x13, 0x2f, 0xc2, 0xe6, 0x5f, 0x71, 0x53, 0xb0, +- 0xaf, 0xbc, 0x3c, 0xea, 0xe4, 0x64, 0xe2, 0x14, 0x6d, 0x2c, 0x9d, 0x29, +- 0xc4, 0x72, 0x32, 0xef, 0xa4, 0x33, 0x0b, 0xd0, 0xbd, 0x05, 0xc7, 0xf3, +- 0xa6, 0xec, 0xfe, 0xd4, 0x28, 0x30, 0x5e, 0x74, 0x76, 0x24, 0x27, 0x20, +- 0xc8, 0x25, 0x2b, 0x25, 0x4b, 0x6e, 0x06, 0x3a, 0x86, 0xf7, 0xae, 0x85, +- 0x7e, 0x00, 0x3a, 0x9e, 0x85, 0x7d, 0x93, 0x16, 0x53, 0x16, 0xfb, 0x20, +- 0x3b, 0x47, 0x07, 0x2e, 0x4d, 0xf2, 0xfb, 0x6f, 0x40, 0xbe, 0x21, 0xdf, +- 0x77, 0x81, 0xb6, 0x04, 0x70, 0x92, 0xae, 0xdb, 0xa4, 0xda, 0x05, 0xf9, +- 0x0d, 0x25, 0x94, 0x5d, 0x16, 0x3a, 0xb7, 0x4a, 0xe1, 0x8e, 0x66, 0xbc, +- 0xef, 0xc2, 0x98, 0xf2, 0x6f, 0xc1, 0x1c, 0xdf, 0xff, 0x4b, 0x60, 0x5f, +- 0x4d, 0xeb, 0xc6, 0x57, 0xd1, 0xb7, 0xcb, 0x36, 0x8b, 0xbd, 0x89, 0xfe, +- 0x9f, 0xd1, 0x77, 0xa2, 0xef, 0xc5, 0x5e, 0xe7, 0x21, 0x43, 0xca, 0x0f, +- 0xcf, 0x0b, 0x5c, 0xb3, 0x3d, 0xd8, 0x97, 0x78, 0xdb, 0x81, 0x67, 0x53, +- 0xb0, 0x57, 0x3b, 0xc6, 0xad, 0xc1, 0x5e, 0x16, 0x68, 0x8e, 0x29, 0x19, +- 0x16, 0xac, 0xf8, 0xba, 0xb1, 0x86, 0x3e, 0x0e, 0xdc, 0x84, 0xd7, 0xe5, +- 0x4a, 0x57, 0x17, 0x9e, 0xb9, 0x27, 0x61, 0xf8, 0x1e, 0xbd, 0x4b, 0xfc, +- 0x1c, 0xe7, 0xe5, 0x09, 0x07, 0xfe, 0x89, 0xfa, 0xe6, 0x52, 0x8e, 0xbb, +- 0x65, 0x02, 0xbc, 0x8f, 0x3b, 0xe9, 0x99, 0xaa, 0xee, 0x79, 0x7a, 0xd6, +- 0x30, 0xab, 0x92, 0x86, 0x1d, 0x8f, 0xc9, 0x38, 0xe4, 0x77, 0xda, 0x89, +- 0xcb, 0x45, 0x65, 0x7b, 0xe4, 0xe9, 0x21, 0xc8, 0x05, 0xf1, 0xa4, 0x8b, +- 0xf6, 0x49, 0x9b, 0x82, 0xfc, 0x8a, 0xa6, 0x5c, 0xca, 0xd2, 0x96, 0xb3, +- 0xb2, 0xbc, 0x6a, 0xcb, 0x15, 0xd8, 0x32, 0xed, 0xb8, 0x02, 0x7b, 0xf6, +- 0xf5, 0xfa, 0x41, 0xd9, 0x06, 0xbd, 0x4e, 0x62, 0x3f, 0xea, 0xf5, 0xb3, +- 0xd0, 0x6b, 0xc8, 0xd4, 0x86, 0xae, 0x9b, 0xd4, 0x89, 0x6f, 0xc3, 0xa7, +- 0x81, 0xdf, 0x44, 0xf0, 0xbc, 0xfc, 0x5d, 0x29, 0x9c, 0x6a, 0x05, 0xdd, +- 0x7b, 0xdb, 0x29, 0xb3, 0xf2, 0x32, 0x7f, 0xa1, 0x2e, 0x3e, 0x05, 0xf9, +- 0xc1, 0x8f, 0x2a, 0x1d, 0x04, 0x6f, 0xd9, 0x3d, 0x80, 0x19, 0xc6, 0x39, +- 0xb7, 0x02, 0x3f, 0x69, 0xbc, 0x15, 0x1c, 0xdf, 0x83, 0xee, 0x2c, 0xf5, +- 0x15, 0xf3, 0x0b, 0xe1, 0x79, 0xb7, 0xa9, 0x3d, 0xcb, 0x43, 0xad, 0x01, +- 0x7f, 0x94, 0x03, 0xf5, 0x3e, 0x09, 0xbd, 0xd5, 0x64, 0x5c, 0xe9, 0x6e, +- 0x5e, 0xc9, 0x61, 0xde, 0xa1, 0xfe, 0x02, 0x87, 0x4d, 0x19, 0x98, 0x72, +- 0xbf, 0x82, 0x4f, 0xae, 0xd9, 0x77, 0x37, 0x69, 0xe7, 0x78, 0x83, 0xf4, +- 0x28, 0x1f, 0xd4, 0x1d, 0xe8, 0x76, 0x13, 0x6c, 0x9f, 0xef, 0x1e, 0x92, +- 0xc7, 0xdc, 0x61, 0x9c, 0x43, 0x52, 0x0e, 0xba, 0xdd, 0xf2, 0xfb, 0xee, +- 0x46, 0xb9, 0xdc, 0x09, 0xba, 0x56, 0x6d, 0xec, 0x6e, 0xf9, 0x03, 0xc6, +- 0x3c, 0xf5, 0x0c, 0x3f, 0xa9, 0xdf, 0x05, 0x1a, 0x68, 0x4f, 0xb4, 0x2b, +- 0xc2, 0xc5, 0xa4, 0xa4, 0xf6, 0xfc, 0x89, 0xef, 0xdb, 0x80, 0x77, 0xae, +- 0x93, 0xf6, 0x4b, 0xda, 0x8c, 0xc0, 0x66, 0xd3, 0x66, 0x49, 0xc8, 0x33, +- 0x69, 0xe5, 0x73, 0xa3, 0x2c, 0xd8, 0x37, 0xca, 0x20, 0xc4, 0x13, 0xda, +- 0xe5, 0xa8, 0xe4, 0x5d, 0xf6, 0xf4, 0x97, 0x88, 0x91, 0x0e, 0x62, 0xa4, +- 0x83, 0xd8, 0x08, 0x5b, 0x78, 0xc5, 0x41, 0x6c, 0x74, 0x10, 0x1b, 0xe1, +- 0xcf, 0x5e, 0x72, 0x10, 0x1f, 0xa1, 0x43, 0x2f, 0x38, 0x8c, 0xeb, 0xdf, +- 0x46, 0x4c, 0x35, 0xe4, 0x99, 0x9a, 0xc8, 0x91, 0x5a, 0x1a, 0xd4, 0xa5, +- 0x87, 0x3f, 0x90, 0xfe, 0xcc, 0x07, 0x92, 0xb6, 0x2f, 0xe2, 0xf7, 0x96, +- 0xe0, 0x9d, 0xca, 0x11, 0xf0, 0xbe, 0x1e, 0xe6, 0x13, 0x38, 0x7f, 0x8b, +- 0x39, 0x83, 0x3f, 0x0f, 0x97, 0x88, 0xb8, 0x41, 0x9b, 0x1e, 0x93, 0xf9, +- 0x59, 0xda, 0xf2, 0xed, 0x38, 0x8b, 0x4e, 0x99, 0xb2, 0xfc, 0x71, 0xc1, +- 0xbe, 0xc3, 0x1c, 0xa5, 0xee, 0x98, 0x31, 0xd0, 0x76, 0x1b, 0x7e, 0x29, +- 0xc4, 0xda, 0x3f, 0xd2, 0x0a, 0x0b, 0x71, 0xc4, 0x56, 0xc6, 0x5b, 0xc9, +- 0xfb, 0x7a, 0x74, 0xc3, 0x1b, 0x5f, 0x5d, 0xd3, 0x0f, 0xfd, 0x86, 0xdc, +- 0x13, 0x09, 0xc0, 0xcc, 0x6a, 0x23, 0xcb, 0x6f, 0xfb, 0x76, 0x92, 0xe5, +- 0xf8, 0x46, 0x60, 0x7b, 0xdc, 0x1f, 0x63, 0x97, 0x78, 0xf9, 0x4c, 0x9c, +- 0x97, 0x91, 0x1f, 0x24, 0x91, 0x17, 0x24, 0xe0, 0x7b, 0x98, 0x73, 0x74, +- 0x23, 0x3f, 0xf0, 0xbc, 0x17, 0x6d, 0xcf, 0x7b, 0x07, 0xbf, 0x7f, 0xb7, +- 0x57, 0x79, 0x40, 0xab, 0x68, 0xa3, 0x6e, 0x4a, 0x46, 0xdd, 0x9f, 0xb6, +- 0xfb, 0x72, 0x8c, 0xcb, 0xa4, 0x93, 0x90, 0x29, 0xa7, 0xa6, 0xdd, 0xb7, +- 0x3c, 0xad, 0x15, 0x97, 0x67, 0xb0, 0xaf, 0x81, 0x39, 0xa9, 0x54, 0xed, +- 0x33, 0xda, 0x88, 0x7b, 0x54, 0xbb, 0x7f, 0xb9, 0x5d, 0xd9, 0x79, 0xd5, +- 0x61, 0xce, 0x70, 0x5d, 0xe5, 0x2e, 0x05, 0x2b, 0x6d, 0xfe, 0x2e, 0x14, +- 0xaf, 0x50, 0x23, 0xdd, 0xcd, 0x01, 0xcd, 0xb0, 0xc3, 0x9c, 0x77, 0xb8, +- 0x90, 0xb5, 0x60, 0x8b, 0xa4, 0x51, 0xcd, 0x5d, 0xf0, 0xe9, 0x3e, 0xad, +- 0x15, 0x96, 0xdb, 0xb4, 0x91, 0x53, 0x8c, 0xc7, 0xd2, 0x1d, 0x13, 0xae, +- 0xdb, 0x01, 0x7b, 0xad, 0x63, 0x0f, 0xe6, 0x5b, 0x94, 0x2d, 0xe8, 0x86, +- 0x0e, 0xbf, 0x04, 0x7a, 0x5e, 0x54, 0xf9, 0x0f, 0xf9, 0x4b, 0xe1, 0xac, +- 0x42, 0xfe, 0x3c, 0xef, 0xaf, 0xed, 0x90, 0xfe, 0x74, 0x2a, 0xaf, 0x87, +- 0xfc, 0x7a, 0xde, 0xbf, 0xd9, 0xe4, 0x99, 0x3c, 0x79, 0xde, 0x0b, 0x76, +- 0x02, 0xf4, 0x7b, 0x17, 0x74, 0xab, 0x06, 0x7e, 0x18, 0xdb, 0x29, 0xf3, +- 0x69, 0xf0, 0x71, 0x14, 0x3c, 0x9e, 0x06, 0x7f, 0x33, 0xa0, 0xe5, 0x37, +- 0xed, 0xd9, 0x98, 0x4b, 0x4a, 0x8a, 0xb2, 0x2e, 0x2f, 0x32, 0xa7, 0x64, +- 0x1e, 0x69, 0x4a, 0x69, 0x31, 0x5c, 0x1f, 0xea, 0xc3, 0x01, 0xd9, 0xeb, +- 0x74, 0x42, 0x3e, 0x94, 0xe7, 0x35, 0xd0, 0x4b, 0x9f, 0x5f, 0xcd, 0xe8, +- 0x08, 0x80, 0x65, 0x1b, 0xb1, 0x5e, 0x46, 0x94, 0x2e, 0x2c, 0x5a, 0x92, +- 0x2f, 0xdb, 0x26, 0xed, 0x36, 0x55, 0xb6, 0x2b, 0xc8, 0x0c, 0x7c, 0x39, +- 0x8e, 0xd4, 0x0c, 0xbc, 0xe3, 0x58, 0x60, 0xf3, 0xa1, 0x6c, 0x0d, 0xd8, +- 0x5d, 0x28, 0xf3, 0x70, 0xee, 0xc1, 0x0e, 0xfa, 0xcc, 0x79, 0xf7, 0x0b, +- 0xc0, 0x41, 0xbc, 0xbf, 0x09, 0x47, 0x1c, 0x31, 0x84, 0x78, 0xe2, 0x72, +- 0xc6, 0x21, 0x3c, 0xf3, 0x8b, 0xb8, 0xb4, 0x22, 0x26, 0x6f, 0xc8, 0x89, +- 0xf6, 0xf9, 0x1d, 0x69, 0x73, 0x31, 0x16, 0x93, 0x63, 0x09, 0xb9, 0xc3, +- 0x60, 0x00, 0xd8, 0xec, 0x67, 0xea, 0x85, 0x19, 0x0d, 0xba, 0xdc, 0x26, +- 0x93, 0x03, 0x69, 0x73, 0x1e, 0x7b, 0xe8, 0xd8, 0xe3, 0x6b, 0x9c, 0xaf, +- 0xfd, 0x87, 0x57, 0x4a, 0xec, 0x84, 0x9d, 0x48, 0xdc, 0xc8, 0x19, 0x83, +- 0x53, 0xb5, 0x03, 0xc2, 0xfc, 0x6a, 0x72, 0x60, 0x03, 0xec, 0xbc, 0x77, +- 0x78, 0xaf, 0x30, 0x97, 0x8f, 0x0f, 0x8e, 0x5b, 0x3e, 0x5d, 0x23, 0xb0, +- 0xeb, 0x49, 0xe4, 0x79, 0x7b, 0xeb, 0xcc, 0x01, 0x8c, 0xc1, 0xde, 0xba, +- 0x21, 0x47, 0x60, 0xaf, 0xcd, 0xd0, 0x9f, 0x15, 0xa5, 0xcb, 0x26, 0x64, +- 0x4d, 0xdf, 0x3a, 0x0c, 0xdc, 0xef, 0x40, 0x6e, 0x16, 0x62, 0x67, 0x37, +- 0xf2, 0xd9, 0x0c, 0xce, 0x33, 0x85, 0xd8, 0xd7, 0xa8, 0xd7, 0x12, 0xdf, +- 0x0a, 0xb8, 0x57, 0x76, 0x32, 0x2f, 0xf3, 0xbc, 0x07, 0xac, 0xf4, 0xb3, +- 0xe4, 0x65, 0xca, 0x91, 0x7c, 0xd5, 0x56, 0xbe, 0x10, 0x3a, 0x9b, 0x62, +- 0x3e, 0x07, 0xfd, 0x83, 0x4e, 0x16, 0x39, 0x5e, 0xd5, 0xc1, 0xe4, 0xa4, +- 0xcc, 0x43, 0x76, 0x62, 0x16, 0xb2, 0x84, 0x0d, 0xe1, 0x5a, 0x02, 0xdd, +- 0xf6, 0xbc, 0x18, 0x74, 0x77, 0x3c, 0x4b, 0x38, 0xa9, 0x28, 0x9b, 0x83, +- 0xcc, 0x26, 0xdd, 0x5d, 0x1d, 0x7e, 0x3e, 0x09, 0x5f, 0x99, 0xe0, 0x5e, +- 0x9f, 0x85, 0x0e, 0x77, 0x23, 0x86, 0x78, 0x1e, 0x6c, 0x38, 0xa1, 0x0b, +- 0x75, 0x18, 0xf6, 0xe2, 0xf2, 0x5d, 0x1b, 0xe6, 0xc5, 0x9c, 0x84, 0x4f, +- 0x2b, 0x99, 0x9e, 0x77, 0x0f, 0x68, 0xa9, 0xda, 0x1d, 0x58, 0xd7, 0x24, +- 0x08, 0x7b, 0xa6, 0xbf, 0xdf, 0x46, 0x15, 0x3b, 0x30, 0x6e, 0xc7, 0x7e, +- 0x9b, 0x98, 0x7b, 0x4e, 0xd2, 0x16, 0xb2, 0xb4, 0x7d, 0x23, 0xf0, 0xe7, +- 0x6f, 0x82, 0x4e, 0xae, 0x51, 0x70, 0xf1, 0xa6, 0x5c, 0x56, 0x96, 0x6a, +- 0xdb, 0x65, 0x6e, 0x3f, 0xf7, 0xe8, 0xa6, 0x1d, 0x22, 0xfe, 0xf3, 0x99, +- 0x74, 0xd3, 0x8f, 0x74, 0x06, 0x63, 0xed, 0x73, 0xfe, 0x1e, 0x62, 0x32, +- 0xdf, 0x1d, 0x51, 0xf4, 0x8a, 0x7e, 0xd1, 0xde, 0xe8, 0xc7, 0xa8, 0x5c, +- 0xbb, 0x76, 0x0f, 0x72, 0xf0, 0xbd, 0xbb, 0xa9, 0x03, 0x86, 0x5c, 0xb2, +- 0x3c, 0xef, 0x92, 0xdd, 0x04, 0xfe, 0x74, 0x69, 0xb2, 0x8e, 0x9b, 0xd2, +- 0x0a, 0x99, 0x3b, 0x5a, 0x20, 0x97, 0x36, 0x25, 0x97, 0x49, 0x15, 0xf7, +- 0xde, 0xc5, 0xd9, 0x70, 0x6d, 0x45, 0xc5, 0x97, 0x82, 0x5a, 0xc7, 0x35, +- 0x3c, 0xd3, 0x77, 0x91, 0x73, 0x1f, 0xc3, 0xda, 0x98, 0xb4, 0x28, 0xdd, +- 0x66, 0xfc, 0x27, 0xaf, 0xd2, 0xe1, 0xe3, 0x61, 0xac, 0xa5, 0x0e, 0x87, +- 0xfc, 0x8f, 0x06, 0x3c, 0x12, 0xaf, 0x0d, 0xbc, 0x6d, 0xaa, 0xce, 0x28, +- 0xfb, 0xe7, 0xd7, 0x11, 0x53, 0xf2, 0x40, 0x5d, 0x94, 0x0b, 0x7d, 0x21, +- 0x41, 0x43, 0xba, 0x9f, 0xc1, 0x3e, 0xa4, 0x61, 0x13, 0xf2, 0x5e, 0xd1, +- 0xaa, 0xe4, 0xcb, 0x0c, 0xf7, 0x11, 0x3d, 0x96, 0x6b, 0x91, 0x11, 0x68, +- 0x5d, 0xd5, 0xb1, 0xcc, 0x07, 0xa0, 0x7b, 0x5f, 0x07, 0x8f, 0x85, 0x19, +- 0xfa, 0xaa, 0x2f, 0x61, 0xdd, 0x4a, 0x5a, 0xf7, 0xb7, 0x95, 0x23, 0x0e, +- 0x65, 0xfa, 0x0e, 0x64, 0xaa, 0x77, 0x35, 0x4b, 0x87, 0x14, 0x91, 0x4f, +- 0xcd, 0x0f, 0x83, 0xaf, 0x81, 0x36, 0x89, 0xed, 0xa2, 0xaf, 0x42, 0xed, +- 0x93, 0x58, 0x41, 0x60, 0xb8, 0xee, 0xe9, 0x3b, 0xb1, 0x7e, 0x20, 0x01, +- 0xf9, 0x52, 0x66, 0x7a, 0x00, 0x47, 0x18, 0x14, 0x4a, 0x66, 0xa1, 0xb3, +- 0x59, 0x88, 0x9b, 0xef, 0xfa, 0x93, 0xa6, 0x70, 0x1e, 0x3e, 0xbd, 0xc8, +- 0xb5, 0xa4, 0xd9, 0x5f, 0xd3, 0x64, 0x85, 0xb2, 0xfe, 0x2b, 0xf8, 0xa7, +- 0x5f, 0x79, 0x7b, 0x87, 0xc2, 0xf7, 0xe4, 0x87, 0x7c, 0xe1, 0x0c, 0x41, +- 0xd3, 0xe6, 0x9c, 0x25, 0x83, 0xd3, 0xa2, 0x15, 0x90, 0x7b, 0x50, 0x47, +- 0x7a, 0x86, 0xd2, 0x95, 0x94, 0xbe, 0x0d, 0xbc, 0x1a, 0xb2, 0x7f, 0x88, +- 0xfc, 0x6e, 0x0d, 0xf2, 0x8e, 0x46, 0x9e, 0x3b, 0x02, 0x9e, 0xd5, 0x7e, +- 0xc3, 0x79, 0x7d, 0x8d, 0xf7, 0xd1, 0x99, 0x70, 0x5f, 0x03, 0xb6, 0xbc, +- 0x82, 0x9a, 0x87, 0xfb, 0x93, 0x9e, 0x1b, 0x9e, 0x6e, 0x59, 0x95, 0x1e, +- 0xfd, 0x57, 0xde, 0xfd, 0x43, 0x9a, 0xca, 0xd3, 0x74, 0xe4, 0x8c, 0xfa, +- 0x10, 0x78, 0x1d, 0xe2, 0x79, 0xe9, 0x72, 0xff, 0x6e, 0xe2, 0x3b, 0x42, +- 0xde, 0x80, 0xb3, 0xd5, 0xaf, 0x61, 0x86, 0xc2, 0x3d, 0x1a, 0xf5, 0x27, +- 0xc4, 0x49, 0x5c, 0x84, 0xe1, 0x99, 0xd0, 0xdf, 0x4a, 0xbc, 0x60, 0xc7, +- 0x83, 0xb3, 0x0e, 0xd7, 0x89, 0x66, 0x58, 0xeb, 0xd7, 0xc1, 0x68, 0x1f, +- 0xa4, 0xde, 0xf5, 0x04, 0x76, 0x16, 0xea, 0x21, 0xf7, 0x64, 0x7f, 0x2b, +- 0x9d, 0xe5, 0x3a, 0xae, 0x27, 0x3c, 0x61, 0xe0, 0x33, 0xe0, 0x83, 0x7e, +- 0x06, 0xdb, 0x78, 0xf9, 0x26, 0x5f, 0xce, 0xd8, 0x4e, 0x1f, 0x63, 0xaf, +- 0xf7, 0xe7, 0xac, 0x7d, 0xf0, 0xac, 0xc3, 0x7e, 0x1b, 0xfd, 0x3a, 0xe7, +- 0x50, 0x4f, 0x2c, 0x8e, 0xa2, 0xb7, 0x64, 0xed, 0x1e, 0x80, 0x7e, 0x3e, +- 0xac, 0xe7, 0xdb, 0x4a, 0x46, 0x8e, 0x35, 0xbd, 0x14, 0xab, 0xb5, 0xc3, +- 0x88, 0xc9, 0x52, 0xb9, 0x4d, 0xd5, 0xc6, 0x6d, 0xc3, 0x85, 0x2c, 0xe6, +- 0xea, 0x8c, 0xcb, 0x30, 0x7f, 0xac, 0x43, 0x6c, 0x88, 0xeb, 0xd3, 0xf1, +- 0xca, 0xed, 0x39, 0xda, 0x49, 0x4a, 0x52, 0xf5, 0x6b, 0x88, 0x79, 0xc8, +- 0x1f, 0x95, 0x0e, 0x7d, 0xf1, 0x76, 0xd2, 0x5f, 0x45, 0xec, 0x32, 0x72, +- 0x62, 0xe8, 0xb9, 0xe6, 0xf8, 0x64, 0xb6, 0x0d, 0xb1, 0x7e, 0x6c, 0xbb, +- 0x7e, 0x6e, 0xdf, 0xf6, 0xd8, 0xb9, 0xae, 0x52, 0x53, 0xae, 0xb2, 0x5d, +- 0x9f, 0x86, 0x2f, 0xaf, 0x89, 0x8e, 0x98, 0x8a, 0x1a, 0x01, 0xe3, 0x73, +- 0x0f, 0x3c, 0xa0, 0xe7, 0x62, 0x52, 0x4e, 0xc8, 0x93, 0x8b, 0x59, 0xf8, +- 0xf5, 0x5a, 0x3a, 0x55, 0x94, 0x27, 0xa5, 0x5a, 0x3b, 0x24, 0x93, 0xb5, +- 0xf0, 0xde, 0x80, 0x77, 0x06, 0x49, 0xe5, 0xbf, 0xe8, 0x5f, 0x27, 0x03, +- 0xda, 0x41, 0x73, 0x7e, 0x84, 0x31, 0x3a, 0x4b, 0xdf, 0x7d, 0x0d, 0x3a, +- 0xd1, 0x12, 0xd4, 0xda, 0xbe, 0xfe, 0x19, 0xb9, 0x8f, 0x30, 0x47, 0xfd, +- 0xdb, 0xb0, 0x7a, 0x6e, 0x7b, 0x4e, 0xfd, 0x89, 0x8a, 0xa9, 0x4b, 0x36, +- 0x9f, 0x09, 0xf3, 0xf6, 0xe0, 0x94, 0x75, 0xdd, 0x64, 0x6d, 0x70, 0xc1, +- 0x21, 0x3e, 0x53, 0x9d, 0xb5, 0x91, 0xbb, 0x8c, 0xb5, 0xad, 0xa4, 0x0b, +- 0xcd, 0xc0, 0x3c, 0xf6, 0x77, 0x9a, 0x83, 0x71, 0xb8, 0xf6, 0xb5, 0x86, +- 0xb5, 0x9c, 0x63, 0x4f, 0xdc, 0xd8, 0xa3, 0xe1, 0xce, 0xe4, 0x82, 0x9b, +- 0x51, 0x35, 0x7b, 0xc1, 0x55, 0xb9, 0x02, 0x6a, 0x74, 0xe8, 0x93, 0xba, +- 0x43, 0x81, 0x3f, 0x72, 0xff, 0xce, 0xf4, 0xcf, 0x9d, 0xfe, 0x63, 0x45, +- 0x18, 0xdf, 0xa8, 0x6f, 0x53, 0xca, 0x4f, 0xbd, 0xd9, 0x70, 0x17, 0xf0, +- 0x26, 0xfc, 0xd2, 0x9d, 0x9b, 0xfd, 0x9a, 0xc6, 0x0c, 0x7c, 0x5a, 0xab, +- 0xca, 0x53, 0x7c, 0x9f, 0x96, 0x6a, 0x80, 0x4d, 0xf1, 0xde, 0xa0, 0xc3, +- 0xaf, 0xbd, 0x7f, 0x2b, 0x58, 0xc3, 0xfc, 0xc1, 0x32, 0x99, 0x3b, 0xf8, +- 0xb2, 0xf0, 0x9e, 0x59, 0x1d, 0x27, 0x4a, 0x01, 0xbe, 0xa6, 0xe0, 0xdd, +- 0x5b, 0x6d, 0x3e, 0x4d, 0xe1, 0xda, 0x3f, 0x0d, 0xee, 0xa6, 0x94, 0x2f, +- 0xcc, 0x03, 0x16, 0x3c, 0xa4, 0x4a, 0x3a, 0xf4, 0x66, 0xa4, 0xee, 0xcb, +- 0x1b, 0xf1, 0x8e, 0xf7, 0x4f, 0x8a, 0xb6, 0x0b, 0x2a, 0xe7, 0x68, 0xe4, +- 0x3f, 0x4f, 0xbe, 0xf3, 0x06, 0x69, 0x74, 0xc7, 0xb0, 0x56, 0x0e, 0xf8, +- 0x77, 0x14, 0xa6, 0x4c, 0x98, 0xfd, 0xe6, 0x24, 0xf1, 0x26, 0x04, 0xf8, +- 0x90, 0x97, 0xe4, 0xc2, 0x33, 0xfc, 0x26, 0xf7, 0x06, 0xde, 0x8d, 0x1c, +- 0xa3, 0xff, 0x66, 0x40, 0xcb, 0x8f, 0x03, 0x79, 0x85, 0xef, 0x7f, 0xb1, +- 0xf9, 0xe6, 0xf1, 0x3d, 0xb7, 0x07, 0xf2, 0xc4, 0xf3, 0xa1, 0x5f, 0x43, +- 0x13, 0xf5, 0xfd, 0x34, 0xf0, 0xa8, 0x18, 0x5c, 0xd1, 0x73, 0x88, 0xf9, +- 0x59, 0x64, 0x34, 0x35, 0xd8, 0xb4, 0x20, 0xf6, 0xbb, 0x69, 0xbb, 0x84, +- 0x55, 0x1f, 0xd5, 0xe8, 0x57, 0xaf, 0xc3, 0xaf, 0xf2, 0xac, 0x3f, 0x96, +- 0xa9, 0x5a, 0xaf, 0xdd, 0xac, 0xa9, 0xfc, 0x3a, 0x73, 0x5a, 0xfa, 0xed, +- 0xd3, 0xc8, 0x3d, 0x50, 0xa3, 0xa5, 0x8e, 0x08, 0x65, 0x7e, 0x5d, 0x76, +- 0xa8, 0x9c, 0xe0, 0x63, 0xb1, 0x20, 0x93, 0x22, 0xea, 0x04, 0x7d, 0xe8, +- 0x5f, 0x3d, 0x95, 0xd3, 0x68, 0xa8, 0x42, 0x6f, 0x81, 0xeb, 0x6d, 0x85, +- 0x87, 0xf8, 0x1a, 0x71, 0x69, 0xd2, 0x32, 0x14, 0xe2, 0x4b, 0xc9, 0x51, +- 0x37, 0xc4, 0x69, 0xc8, 0x65, 0x64, 0x2d, 0xfa, 0x90, 0x17, 0xf0, 0xcf, +- 0xe7, 0x5f, 0x7a, 0xcc, 0x09, 0xf4, 0xdc, 0xdd, 0x81, 0x0c, 0x7e, 0x8f, +- 0x32, 0xc0, 0x18, 0x3a, 0xef, 0x7c, 0xc5, 0xaf, 0x45, 0x54, 0x2d, 0x37, +- 0x86, 0x9a, 0x82, 0x73, 0x2b, 0x2d, 0x05, 0x3b, 0x3c, 0xe3, 0x7d, 0x98, +- 0x2b, 0xe2, 0x47, 0xb9, 0x10, 0x66, 0x3f, 0x9e, 0xf3, 0x01, 0x9c, 0x0c, +- 0xfb, 0x35, 0x79, 0x58, 0x8b, 0x84, 0x39, 0xa1, 0xcc, 0xe8, 0x39, 0xe6, +- 0xef, 0x3b, 0x40, 0x2b, 0x73, 0x56, 0x9c, 0xe7, 0xaa, 0xff, 0x59, 0x85, +- 0xa9, 0xac, 0xc1, 0xf8, 0xb9, 0xe7, 0xa8, 0x1b, 0xe6, 0xbb, 0xcc, 0x69, +- 0xc3, 0xdc, 0x27, 0xaf, 0x15, 0x9d, 0x31, 0xed, 0x3e, 0x87, 0xf0, 0xfa, +- 0xec, 0x66, 0xb1, 0x52, 0x3d, 0xba, 0x27, 0x23, 0x43, 0xac, 0x9d, 0x8f, +- 0xe1, 0xcc, 0x3b, 0xa4, 0x9c, 0x41, 0x1e, 0x60, 0xde, 0x85, 0xbe, 0x19, +- 0x73, 0x5f, 0xc6, 0x1c, 0x74, 0x23, 0xc3, 0xfc, 0x66, 0x83, 0xaa, 0x41, +- 0x4a, 0x2a, 0x76, 0xec, 0x08, 0xf4, 0xe5, 0x89, 0x4e, 0x5f, 0x3f, 0xbe, +- 0x87, 0xf1, 0x46, 0xcc, 0x7f, 0x03, 0xbd, 0xe7, 0xf5, 0x0c, 0x85, 0xf3, +- 0xd4, 0xfb, 0x61, 0xcc, 0xdf, 0x09, 0x1c, 0x15, 0x3c, 0x7f, 0x0e, 0xcf, +- 0x7f, 0xb8, 0x6e, 0xed, 0x77, 0x31, 0xae, 0x60, 0xbe, 0xb0, 0x6e, 0x3e, +- 0xf4, 0xb3, 0xdc, 0xaf, 0xa2, 0x15, 0xdd, 0x29, 0x2d, 0xaf, 0xea, 0x88, +- 0x63, 0xa8, 0x55, 0xe8, 0x6b, 0x59, 0xb3, 0xcc, 0x20, 0x17, 0xa7, 0x9f, +- 0x3d, 0x88, 0x35, 0x8b, 0xd0, 0xbb, 0x56, 0x95, 0x65, 0xea, 0xca, 0x1e, +- 0x0f, 0x1d, 0xec, 0x99, 0x63, 0x5f, 0x39, 0x68, 0xd7, 0x09, 0xc3, 0xe7, +- 0x27, 0x0f, 0xf6, 0xd4, 0x0f, 0x01, 0x96, 0xf9, 0x7a, 0xe3, 0x1d, 0xef, +- 0x37, 0xd6, 0xed, 0xe9, 0xd7, 0x38, 0x45, 0x75, 0x37, 0x78, 0xe8, 0x60, +- 0x61, 0x86, 0x71, 0x9a, 0xf5, 0x26, 0xf3, 0xd2, 0xca, 0xc1, 0xf1, 0xda, +- 0x54, 0x50, 0xd3, 0x84, 0xef, 0xf9, 0x8e, 0xf2, 0xbf, 0x15, 0x6d, 0xa4, +- 0xab, 0x11, 0x8f, 0xca, 0x6b, 0x80, 0xe7, 0x49, 0xe0, 0x61, 0x6d, 0xa4, +- 0xee, 0x90, 0x15, 0xbd, 0xa9, 0xb9, 0x5b, 0xd1, 0x46, 0x5c, 0xdc, 0x2b, +- 0xc4, 0x77, 0x02, 0x75, 0xc7, 0x77, 0x48, 0x2f, 0xf0, 0x7c, 0x26, 0xc8, +- 0x6d, 0x78, 0x37, 0x65, 0xf8, 0x77, 0x38, 0x6a, 0x1c, 0xd6, 0xbe, 0x4d, +- 0xeb, 0x6a, 0xdf, 0xa6, 0xe0, 0x1e, 0x8b, 0xb0, 0x7a, 0x00, 0xab, 0xee, +- 0xd0, 0x31, 0x97, 0x0a, 0xee, 0x94, 0xe3, 0xbc, 0x53, 0x6e, 0x90, 0x45, +- 0x53, 0x20, 0x7f, 0xd2, 0x11, 0xd6, 0x2b, 0x8d, 0xf4, 0xf1, 0xbe, 0x79, +- 0x0a, 0xef, 0xc3, 0xb3, 0x09, 0x79, 0x5f, 0xc4, 0x3c, 0xe9, 0x3d, 0x03, +- 0xf8, 0x90, 0xde, 0x4f, 0x7b, 0xa6, 0x5c, 0x7b, 0x06, 0xbf, 0x70, 0xbf, +- 0x50, 0x2e, 0xa4, 0xf5, 0xd7, 0xd5, 0x5a, 0xa1, 0xdf, 0x5b, 0x0c, 0x62, +- 0x3a, 0xe9, 0xa2, 0x0f, 0xa2, 0x3f, 0x0e, 0xef, 0xc0, 0x59, 0x63, 0x33, +- 0x56, 0xf0, 0xbc, 0x5a, 0xa0, 0x2b, 0x84, 0xd3, 0x90, 0x5f, 0xeb, 0xcc, +- 0xc3, 0x52, 0xa8, 0x35, 0x92, 0x8f, 0xc8, 0x0f, 0xb0, 0x57, 0x3e, 0xd3, +- 0xa4, 0xec, 0x88, 0xf7, 0x08, 0xcd, 0xb2, 0x02, 0x9d, 0xbe, 0x84, 0xfa, +- 0x63, 0x1e, 0xb5, 0xd1, 0x12, 0xef, 0xb5, 0xeb, 0x27, 0x3b, 0x79, 0x1f, +- 0x32, 0x65, 0xad, 0xd5, 0xf1, 0x73, 0x80, 0x59, 0xb0, 0x58, 0xeb, 0x4b, +- 0xd0, 0x10, 0x23, 0x91, 0x67, 0x8c, 0x5b, 0xff, 0xe3, 0x95, 0x13, 0x8d, +- 0xb0, 0xb7, 0xaa, 0xb3, 0xdb, 0xa4, 0x3a, 0x9b, 0x3e, 0x3a, 0x87, 0x7a, +- 0x77, 0xc6, 0xd2, 0xb7, 0xe8, 0x7e, 0xad, 0x34, 0x03, 0xdf, 0xa4, 0x6a, +- 0xad, 0x39, 0x79, 0xae, 0x93, 0x67, 0xd7, 0x64, 0xf5, 0x9b, 0x9d, 0xfa, +- 0xef, 0x50, 0x17, 0x15, 0xe5, 0xb1, 0x13, 0x1b, 0xa4, 0x3c, 0x70, 0x1f, +- 0x72, 0x2d, 0xc8, 0xf3, 0x44, 0x05, 0x95, 0x21, 0xf5, 0xea, 0xbd, 0x03, +- 0xe3, 0x16, 0x6b, 0x26, 0xf1, 0xe3, 0x9a, 0xf8, 0x3c, 0xc6, 0x4e, 0xb4, +- 0x29, 0x9f, 0xe4, 0xdf, 0x99, 0xf7, 0x9a, 0x45, 0xe4, 0x63, 0x85, 0x01, +- 0x24, 0x8d, 0xc8, 0x5e, 0xcc, 0x9d, 0x22, 0x3d, 0xcc, 0x19, 0xe1, 0x8f, +- 0x7b, 0xce, 0xc1, 0xcb, 0x9d, 0x20, 0xbc, 0x2e, 0xc6, 0x89, 0x98, 0x34, +- 0x9d, 0x60, 0x9d, 0x2d, 0x5d, 0xa8, 0x51, 0x88, 0xb3, 0xc7, 0x40, 0x3f, +- 0x8a, 0xdf, 0x1e, 0xe4, 0x51, 0x26, 0xf2, 0xda, 0x5b, 0xc0, 0x03, 0x96, +- 0x6b, 0x6e, 0x05, 0xff, 0x6a, 0x27, 0xeb, 0xce, 0x9e, 0x73, 0x84, 0xe7, +- 0x7d, 0x76, 0x17, 0xe8, 0xf1, 0xf7, 0x27, 0x0e, 0xe3, 0x84, 0x48, 0xef, +- 0xb4, 0x74, 0xea, 0x6a, 0x8d, 0x21, 0xe3, 0x59, 0xbe, 0x6b, 0x03, 0xfc, +- 0xab, 0xca, 0x3e, 0x7b, 0xd5, 0x3a, 0xff, 0xce, 0xa2, 0xbc, 0x46, 0x37, +- 0xe6, 0x34, 0x3c, 0x23, 0x57, 0xca, 0x9a, 0xd2, 0x3b, 0xef, 0xc3, 0xf6, +- 0x9c, 0xeb, 0xd8, 0xe2, 0xdf, 0xed, 0xf8, 0xb4, 0xf1, 0x6e, 0xb0, 0x0c, +- 0xa9, 0x1a, 0x3b, 0x59, 0xf3, 0x13, 0x86, 0xdf, 0x52, 0xd8, 0x73, 0x2d, +- 0xe5, 0xe7, 0xcf, 0xe9, 0xfa, 0xff, 0xa5, 0x5f, 0xeb, 0xbf, 0xe1, 0x84, +- 0x77, 0x4b, 0xa9, 0x86, 0xbb, 0xa5, 0x74, 0xc3, 0xb7, 0x97, 0x9f, 0xb4, +- 0x05, 0x7a, 0x27, 0x93, 0xb6, 0x27, 0xe1, 0xf7, 0xa5, 0xbd, 0x37, 0xe5, +- 0x90, 0x19, 0x15, 0xa7, 0xc7, 0x21, 0xfb, 0x2b, 0x75, 0xd2, 0x8b, 0x98, +- 0x53, 0x8f, 0xcb, 0xfb, 0x8b, 0xad, 0x72, 0x65, 0xce, 0xcf, 0x29, 0xaf, +- 0xa8, 0x6f, 0x4e, 0xa6, 0x7c, 0x80, 0xc2, 0xff, 0x72, 0x3d, 0x83, 0x5f, +- 0xa7, 0x5c, 0x5d, 0xbc, 0x39, 0xa7, 0xbc, 0xe0, 0xde, 0x0d, 0x5a, 0x3a, +- 0x03, 0x1b, 0x46, 0xdd, 0x86, 0x18, 0x58, 0x09, 0xee, 0xea, 0x55, 0xce, +- 0x62, 0xd0, 0x16, 0x78, 0x27, 0x1f, 0xde, 0x57, 0xf7, 0x9a, 0x17, 0x21, +- 0xe3, 0xaf, 0x1a, 0x9d, 0xa8, 0xa3, 0x79, 0xd7, 0x16, 0xc6, 0xec, 0x30, +- 0xf6, 0x90, 0xee, 0xb7, 0x81, 0x7b, 0x00, 0x7a, 0x4a, 0xdd, 0xb4, 0xa1, +- 0xb3, 0xa6, 0x2c, 0xf5, 0xa5, 0x67, 0x2a, 0xc2, 0xef, 0x02, 0x59, 0xec, +- 0xb9, 0x0c, 0xbd, 0xcc, 0x40, 0x1e, 0xcc, 0xf5, 0x28, 0x57, 0x9c, 0xed, +- 0xf4, 0x94, 0x94, 0xdd, 0xad, 0xc0, 0x97, 0x97, 0x92, 0x3b, 0x8c, 0xbd, +- 0x8e, 0x43, 0x6f, 0x7f, 0xb9, 0x85, 0x77, 0x99, 0xcd, 0x56, 0x16, 0x34, +- 0xde, 0x25, 0xe3, 0x27, 0xa7, 0x64, 0xc2, 0x59, 0xfd, 0x66, 0x94, 0xe1, +- 0xf7, 0x94, 0x45, 0xd4, 0xb4, 0xbe, 0x3d, 0xe6, 0x64, 0xfc, 0x14, 0x70, +- 0x38, 0xac, 0x8d, 0x7b, 0xa1, 0x37, 0xfd, 0xaa, 0x36, 0x2e, 0x29, 0x9f, +- 0xc4, 0xf9, 0xef, 0x01, 0x57, 0x6f, 0x65, 0x0f, 0xe0, 0xca, 0xa8, 0x9f, +- 0x8b, 0xc8, 0x85, 0x17, 0x1c, 0x43, 0xca, 0x36, 0x7c, 0x6b, 0x31, 0xa9, +- 0xeb, 0xbb, 0xba, 0x65, 0xde, 0xe9, 0x37, 0x75, 0xde, 0x3d, 0x26, 0x7c, +- 0xdf, 0x57, 0x56, 0xf6, 0x9d, 0xd4, 0x0d, 0xab, 0x5b, 0x16, 0x9d, 0x8a, +- 0x54, 0x07, 0x38, 0xe6, 0xf9, 0x55, 0xc4, 0xb4, 0x7c, 0x5f, 0x99, 0xd7, +- 0x35, 0x75, 0xb7, 0x5d, 0x76, 0xd5, 0xfd, 0x68, 0xca, 0x94, 0xc3, 0xa0, +- 0x0f, 0xcf, 0x0b, 0xd0, 0xf1, 0x69, 0xe6, 0x78, 0xfe, 0x9d, 0xf1, 0x81, +- 0xe5, 0x22, 0x68, 0x68, 0x97, 0xde, 0x1f, 0xd3, 0xc6, 0x1e, 0xc2, 0x1c, +- 0xc7, 0x69, 0xe8, 0xeb, 0xc3, 0x78, 0x26, 0x6c, 0x12, 0x3d, 0xe5, 0xd0, +- 0x8d, 0xde, 0x04, 0x2d, 0xd0, 0x4b, 0xd6, 0xa5, 0xfb, 0x53, 0x32, 0x7f, +- 0x72, 0xb7, 0x94, 0x16, 0x76, 0x03, 0xff, 0x3f, 0x22, 0xe7, 0xbf, 0x33, +- 0xb8, 0x8b, 0x65, 0xde, 0xcf, 0x7d, 0x5e, 0xdc, 0xa2, 0x6c, 0x63, 0x9a, +- 0xf3, 0xec, 0xf7, 0x61, 0x3d, 0xea, 0x07, 0x47, 0xdd, 0x4f, 0x03, 0x06, +- 0x67, 0xe7, 0x36, 0x7e, 0xfb, 0xeb, 0x84, 0x9f, 0xae, 0xb0, 0x76, 0x40, +- 0x6c, 0x99, 0x1b, 0x2c, 0xd4, 0xd2, 0x66, 0x41, 0x7d, 0x97, 0xc8, 0x88, +- 0x1f, 0x6f, 0x38, 0x17, 0x17, 0x6b, 0x1a, 0xf5, 0x68, 0x8e, 0xef, 0x0e, +- 0xab, 0xfb, 0x1f, 0xf5, 0x7d, 0x4e, 0xde, 0x95, 0x51, 0xe8, 0x58, 0xef, +- 0x74, 0x06, 0x39, 0xf1, 0x7b, 0xc8, 0x27, 0x7f, 0x1e, 0xc8, 0x60, 0x38, +- 0xd0, 0x8d, 0xd6, 0x06, 0x9d, 0xc0, 0x39, 0x3b, 0x38, 0x7b, 0x07, 0x7a, +- 0xe0, 0xe0, 0xac, 0x57, 0xf5, 0x63, 0xb8, 0xc1, 0xe7, 0x6e, 0x92, 0xbf, +- 0x9c, 0x49, 0x67, 0x56, 0xa0, 0x3f, 0x57, 0xc1, 0xeb, 0x0a, 0xea, 0xbc, +- 0x2b, 0x88, 0x23, 0x0b, 0x35, 0x7e, 0x4b, 0xe0, 0xb7, 0x38, 0x8e, 0xb7, +- 0xe1, 0x3c, 0x42, 0x7f, 0xfc, 0x52, 0x60, 0x17, 0x9b, 0xd4, 0x7d, 0xe7, +- 0xfb, 0x38, 0xc3, 0x15, 0xd3, 0xcf, 0x17, 0xfd, 0x35, 0x9b, 0x24, 0xfc, +- 0xde, 0xe7, 0xeb, 0x0f, 0x69, 0xa1, 0xfe, 0x7c, 0xb2, 0xc5, 0xcf, 0xfb, +- 0xf9, 0x0d, 0x8c, 0xf5, 0x0b, 0x9f, 0xef, 0xdf, 0xe2, 0xe3, 0x6a, 0xd4, +- 0xdb, 0x8f, 0x3d, 0xd6, 0x6a, 0x85, 0x3e, 0xf8, 0x6c, 0xd7, 0x93, 0x63, +- 0xf6, 0xcd, 0xf6, 0x76, 0x8f, 0x13, 0xca, 0x87, 0xf2, 0x2b, 0xca, 0x11, +- 0x37, 0x0d, 0x5b, 0xa0, 0xec, 0xac, 0x06, 0xd9, 0x89, 0xfc, 0xb9, 0x23, +- 0xbc, 0xef, 0xc2, 0x3b, 0x25, 0xbb, 0x64, 0x21, 0xd6, 0xca, 0xfb, 0x5a, +- 0xe8, 0xe3, 0xdf, 0xca, 0xc4, 0xac, 0xc8, 0x32, 0xde, 0x2f, 0x39, 0xb4, +- 0xd1, 0x0c, 0xf2, 0xd7, 0x8d, 0x32, 0x3f, 0x87, 0x3a, 0xcb, 0x91, 0x52, +- 0xe1, 0x4e, 0xc6, 0x99, 0xb8, 0x5c, 0x51, 0xf7, 0x7b, 0x22, 0x3b, 0xcf, +- 0x1a, 0x62, 0x9c, 0x45, 0x41, 0x07, 0x99, 0x9f, 0xef, 0x0b, 0xef, 0xfb, +- 0x7c, 0x5b, 0xaf, 0xd6, 0xb0, 0xd6, 0xe9, 0x55, 0xfe, 0xb1, 0x5a, 0x1f, +- 0x97, 0xf2, 0x0c, 0xf7, 0x42, 0x3f, 0x97, 0xc2, 0x3b, 0x5b, 0x26, 0x4f, +- 0x66, 0xe4, 0xfb, 0xfc, 0x5e, 0x93, 0x1d, 0xc5, 0x1e, 0x05, 0xa9, 0x2c, +- 0x63, 0xbe, 0xfe, 0x4f, 0x32, 0xb7, 0x38, 0x2e, 0xf3, 0x33, 0x17, 0x1a, +- 0xee, 0x73, 0x31, 0x9e, 0x6b, 0xac, 0x4f, 0x8b, 0xac, 0xa9, 0x50, 0x7f, +- 0x5a, 0x18, 0xc3, 0x06, 0xea, 0x93, 0xa5, 0x9b, 0xef, 0x1f, 0x1b, 0xeb, +- 0xd2, 0x51, 0x39, 0x8a, 0x33, 0xae, 0x9e, 0xcc, 0xa8, 0xba, 0xa6, 0x25, +- 0x37, 0xfb, 0xf8, 0x87, 0x88, 0x11, 0x63, 0x42, 0x3d, 0xbb, 0x2e, 0x5f, +- 0xb3, 0x8f, 0xca, 0x23, 0x88, 0x1d, 0x47, 0x90, 0x5f, 0xff, 0x36, 0xea, +- 0xba, 0xd4, 0x66, 0x9e, 0x21, 0xe8, 0xb5, 0x58, 0x57, 0x7a, 0x32, 0x6a, +- 0xdf, 0x61, 0xfe, 0x00, 0x92, 0x7d, 0xbf, 0xce, 0xf8, 0xf8, 0xdf, 0x5e, +- 0x1e, 0xf1, 0xee, 0x43, 0x0b, 0x3e, 0x41, 0xc1, 0x69, 0x3e, 0xdc, 0x0c, +- 0xe1, 0xfa, 0xcd, 0x63, 0x84, 0x9b, 0xd3, 0x02, 0x38, 0x0d, 0x70, 0x31, +- 0xb9, 0x68, 0x1b, 0xd0, 0x8d, 0x51, 0xf0, 0x09, 0xdf, 0x3e, 0x18, 0x7e, +- 0x6f, 0xdc, 0x80, 0x98, 0xba, 0xb6, 0xfe, 0x8d, 0x60, 0xfd, 0xf7, 0x83, +- 0xf5, 0x97, 0x56, 0xd7, 0x87, 0x71, 0xf5, 0x13, 0x4f, 0x1a, 0xe8, 0x7a, +- 0xa3, 0xe6, 0xc3, 0x1f, 0x0d, 0xe8, 0xba, 0xb4, 0x4a, 0x57, 0x08, 0x0f, +- 0x79, 0x2a, 0x9e, 0xe9, 0x93, 0xe9, 0x9b, 0x7b, 0x21, 0x47, 0x7e, 0x47, +- 0x86, 0x4d, 0x38, 0xfc, 0x7e, 0x4b, 0x3b, 0xd1, 0x65, 0x25, 0x71, 0x54, +- 0xc6, 0xac, 0xf4, 0xf0, 0xa4, 0xc4, 0xa0, 0xc3, 0xf4, 0x29, 0x31, 0x99, +- 0xa7, 0xaf, 0x41, 0x5f, 0xb6, 0x6f, 0x4d, 0xeb, 0xfb, 0x0d, 0xb4, 0xc6, +- 0x9e, 0x27, 0x8d, 0x3e, 0xad, 0xf1, 0x1d, 0x6b, 0xb4, 0xfa, 0xf0, 0x3e, +- 0xad, 0xef, 0xd7, 0x1a, 0xe0, 0xcf, 0x1a, 0x01, 0xbc, 0xd1, 0x00, 0x4f, +- 0x7d, 0x66, 0x3e, 0x41, 0x7d, 0x26, 0x6d, 0x5f, 0x50, 0xf7, 0x66, 0x1b, +- 0x72, 0xb3, 0x07, 0x3f, 0xbf, 0xc3, 0x93, 0x38, 0xf2, 0x8c, 0x66, 0xbc, +- 0xbb, 0x32, 0xc3, 0x1c, 0x44, 0xef, 0x69, 0x96, 0x9d, 0xd0, 0x59, 0x9e, +- 0x5d, 0xe3, 0x9d, 0xab, 0x27, 0x8f, 0xd8, 0xa4, 0xe5, 0x3f, 0xbd, 0x33, +- 0x89, 0x9d, 0x76, 0x55, 0xfa, 0xcc, 0x66, 0xe1, 0x9d, 0xae, 0xc2, 0x99, +- 0x21, 0x2d, 0xa7, 0xfb, 0x7a, 0xcd, 0xb7, 0xc0, 0xe7, 0xe8, 0x8c, 0x26, +- 0xf3, 0x56, 0x3a, 0x79, 0x1e, 0x38, 0xf6, 0xe0, 0x6c, 0xe6, 0x07, 0x48, +- 0x8f, 0xc8, 0x04, 0xf4, 0x7b, 0x5e, 0xc5, 0x43, 0xea, 0x71, 0x7a, 0xac, +- 0x82, 0x1c, 0xe7, 0xa7, 0x2a, 0xa6, 0x79, 0xde, 0x87, 0x88, 0x6b, 0x63, +- 0xeb, 0x74, 0x4f, 0x3f, 0xeb, 0xeb, 0x9e, 0x7e, 0x16, 0xb5, 0xf1, 0xf1, +- 0xb8, 0xb4, 0x2c, 0xc1, 0x7e, 0x9e, 0xef, 0x52, 0xfa, 0xa7, 0x3f, 0xcf, +- 0x6f, 0x19, 0xf0, 0x73, 0xc7, 0x0d, 0xb1, 0x8e, 0xab, 0x38, 0x00, 0x79, +- 0x17, 0x64, 0xf2, 0x14, 0x7d, 0xa9, 0x25, 0x3b, 0x8e, 0xf3, 0x3c, 0x98, +- 0xcf, 0xcc, 0x0d, 0x8e, 0xc3, 0x46, 0xa6, 0xf8, 0x7d, 0x70, 0xe9, 0x23, +- 0x19, 0xb7, 0x28, 0x07, 0x94, 0xfa, 0x4b, 0xa6, 0xc4, 0x96, 0xe0, 0x13, +- 0x96, 0x92, 0xd2, 0x04, 0xdb, 0xd2, 0xcf, 0x26, 0xb4, 0xea, 0xec, 0x7f, +- 0xc1, 0x1e, 0xf8, 0x4d, 0x20, 0x83, 0x71, 0x52, 0xab, 0xd6, 0x06, 0xd0, +- 0x53, 0xcf, 0x91, 0x46, 0x9d, 0xa5, 0x9e, 0x93, 0x8e, 0xd0, 0x5e, 0xf0, +- 0x7c, 0x36, 0xa3, 0xee, 0x6c, 0x3f, 0xb4, 0xc9, 0xcb, 0xdf, 0x48, 0x61, +- 0x26, 0xfc, 0x1b, 0x10, 0xd9, 0x8c, 0x1c, 0xa6, 0xa3, 0x60, 0xef, 0x18, +- 0xbe, 0x22, 0x9f, 0x96, 0xaf, 0x6d, 0x9f, 0x82, 0x2f, 0xf2, 0xd1, 0xc8, +- 0x17, 0x79, 0x6a, 0x97, 0x26, 0xc5, 0x57, 0xc8, 0x0f, 0x04, 0x0d, 0x7e, +- 0x7a, 0x8e, 0x27, 0x81, 0xff, 0x61, 0xf8, 0x80, 0x6e, 0xf4, 0x0f, 0xa1, +- 0x47, 0x28, 0x3b, 0x4b, 0xde, 0xc9, 0xeb, 0x55, 0xe4, 0x8b, 0x21, 0x9f, +- 0x25, 0x3c, 0xbf, 0x2e, 0x93, 0xb3, 0xde, 0x61, 0xc4, 0x53, 0xde, 0x27, +- 0x77, 0xea, 0x4a, 0x77, 0xd7, 0xf3, 0xfe, 0xba, 0xf8, 0xf2, 0xe1, 0x5d, +- 0x3c, 0x9e, 0x17, 0xd7, 0xcb, 0xa2, 0xd1, 0x77, 0x24, 0x83, 0xbf, 0x7b, +- 0xa1, 0x9f, 0xa0, 0x8c, 0xae, 0x4a, 0x61, 0x96, 0x77, 0x5a, 0x3e, 0xbe, +- 0xd2, 0xea, 0xdf, 0xbe, 0x34, 0xae, 0x19, 0x00, 0x5c, 0x37, 0xe0, 0x48, +- 0xd7, 0x0a, 0xe5, 0x07, 0x9f, 0xb3, 0xbd, 0xc1, 0xd7, 0x34, 0xae, 0xcb, +- 0xca, 0x33, 0x88, 0xff, 0x6f, 0xd8, 0x37, 0xc9, 0xb5, 0xc4, 0x1c, 0x68, +- 0xbe, 0xbe, 0x0f, 0x36, 0xd9, 0x04, 0x5f, 0x66, 0xca, 0x95, 0x5a, 0xb3, +- 0xcc, 0x23, 0xcf, 0x59, 0x58, 0xa4, 0x2f, 0x24, 0xed, 0xad, 0x98, 0xf7, +- 0xfd, 0x17, 0x7d, 0xed, 0x95, 0x1a, 0xe2, 0x2b, 0x6c, 0xfb, 0x4a, 0x2d, +- 0x81, 0xbe, 0x1b, 0xbd, 0x85, 0x3e, 0x85, 0x3e, 0x83, 0x7e, 0x00, 0xfd, +- 0x00, 0x7a, 0x0b, 0x6b, 0x93, 0xe8, 0xc3, 0x5a, 0x82, 0xb8, 0xd6, 0xf8, +- 0xae, 0xaa, 0xfd, 0xf8, 0xdd, 0x90, 0xb1, 0xcc, 0xb0, 0x47, 0x50, 0x63, +- 0x17, 0x06, 0xc2, 0xbf, 0xb9, 0xb9, 0xe1, 0x99, 0x16, 0x6b, 0xf7, 0x8a, +- 0xb6, 0x47, 0x7d, 0x5f, 0x98, 0x41, 0x5c, 0x78, 0x6e, 0xab, 0xb4, 0x5a, +- 0xe6, 0x3d, 0xea, 0xee, 0x68, 0x16, 0x63, 0x3e, 0xa3, 0x3e, 0x4e, 0x4c, +- 0x21, 0x3e, 0xd1, 0x7f, 0xfe, 0x6f, 0xe7, 0xd6, 0x1b, 0xdb, 0xc6, 0x59, +- 0xc6, 0x1f, 0x9f, 0x9d, 0x34, 0xe9, 0x9a, 0xf6, 0x92, 0x38, 0xa9, 0x93, +- 0x85, 0xcd, 0x8e, 0x2f, 0xad, 0x45, 0xd2, 0x71, 0xed, 0x2c, 0x16, 0xa6, +- 0x8c, 0x78, 0x76, 0x92, 0x76, 0x30, 0xa6, 0xb4, 0x74, 0xd3, 0x84, 0x10, +- 0x58, 0xc9, 0xba, 0x75, 0x13, 0xd2, 0x28, 0x30, 0x34, 0x89, 0xa2, 0x18, +- 0x27, 0x61, 0x19, 0x18, 0xc7, 0x0b, 0x81, 0x4e, 0xf0, 0xc5, 0x38, 0xd1, +- 0x06, 0x22, 0x4a, 0x3a, 0x8d, 0x0f, 0x08, 0x6d, 0x74, 0xb8, 0x83, 0xef, +- 0xfc, 0x11, 0x62, 0x12, 0x1f, 0xaa, 0xa8, 0x63, 0x20, 0x21, 0xe0, 0x23, +- 0xd2, 0x98, 0x8e, 0xdf, 0xef, 0x79, 0xef, 0x12, 0xc7, 0x64, 0x54, 0xf0, +- 0xc1, 0x3a, 0xbf, 0x77, 0xf7, 0xbe, 0xf7, 0xde, 0xfb, 0x3c, 0xef, 0xef, +- 0xf9, 0x3d, 0x7f, 0xce, 0x43, 0x9f, 0x19, 0xe0, 0xf8, 0x11, 0x61, 0x0c, +- 0x36, 0x9b, 0xc6, 0xff, 0xea, 0xc5, 0x1e, 0x63, 0x4b, 0xc1, 0xdb, 0x77, +- 0xb8, 0x61, 0x60, 0xab, 0x46, 0xd0, 0x67, 0x3f, 0x9f, 0x00, 0x36, 0xb0, +- 0x92, 0xa8, 0x54, 0xb1, 0x07, 0x7f, 0xed, 0xce, 0x29, 0xa7, 0xa3, 0x2c, +- 0x16, 0xc1, 0x4d, 0x73, 0x65, 0x72, 0x97, 0xcb, 0xf0, 0x47, 0xe0, 0xcb, +- 0x45, 0xe9, 0xbb, 0xd3, 0x16, 0x90, 0x83, 0xfe, 0x12, 0x73, 0xa3, 0x1d, +- 0xf8, 0x26, 0x9e, 0x87, 0xf7, 0x5a, 0xf3, 0xb0, 0x66, 0xa7, 0xc1, 0x05, +- 0x3d, 0x2f, 0xe2, 0x4c, 0x4a, 0xfc, 0x1c, 0x31, 0x47, 0xd0, 0xdf, 0xc4, +- 0xb2, 0xc8, 0xab, 0x32, 0xd3, 0x9a, 0x83, 0x84, 0x72, 0xfd, 0x0e, 0x7d, +- 0x7b, 0xc4, 0xc4, 0xa7, 0x18, 0x7f, 0x16, 0x99, 0x2c, 0x1b, 0x2e, 0x0b, +- 0xbf, 0xac, 0x61, 0xbc, 0xbb, 0xfd, 0xf1, 0x78, 0xdd, 0xd2, 0x71, 0x6a, +- 0xd2, 0x6b, 0x62, 0xbb, 0x63, 0x23, 0xb0, 0x11, 0x51, 0xa9, 0x43, 0x2e, +- 0xd7, 0x21, 0x93, 0x37, 0x4b, 0xd4, 0xf5, 0x61, 0xe8, 0x7d, 0x0b, 0xf3, +- 0xb3, 0x18, 0x6b, 0x44, 0x9f, 0x5d, 0x2f, 0x01, 0x3b, 0x6d, 0xf5, 0x4f, +- 0x7b, 0xc9, 0x0b, 0x69, 0x07, 0xcd, 0x38, 0x03, 0xe6, 0x3e, 0x09, 0xae, +- 0x75, 0xeb, 0x7c, 0x6a, 0x1a, 0x03, 0xe3, 0x3a, 0x41, 0x07, 0x4b, 0xdd, +- 0xfe, 0x3d, 0x5e, 0x8f, 0xa9, 0x77, 0xe2, 0x39, 0xbe, 0xc7, 0x88, 0x64, +- 0xcb, 0x41, 0xbf, 0x4e, 0xf4, 0x6b, 0x6f, 0x18, 0xeb, 0x68, 0xd3, 0x3b, +- 0x58, 0xfe, 0x3b, 0xf0, 0x7a, 0x33, 0xdf, 0x4f, 0xd8, 0x05, 0x09, 0x38, +- 0x3f, 0xed, 0x2f, 0x65, 0x93, 0xd6, 0xfc, 0xb6, 0x91, 0xcf, 0x80, 0xef, +- 0x03, 0x24, 0x96, 0x0a, 0x02, 0xbe, 0x18, 0xa5, 0x8c, 0xd2, 0xd8, 0xd7, +- 0x3f, 0x89, 0xca, 0x61, 0x57, 0x2a, 0xa5, 0x03, 0x62, 0x75, 0xb5, 0x68, +- 0x8d, 0x4e, 0xdc, 0x6a, 0x7c, 0xe6, 0x67, 0xfd, 0x67, 0xc2, 0xf7, 0x5e, +- 0x69, 0xd7, 0xb8, 0x34, 0xec, 0x0c, 0xee, 0x39, 0xd4, 0x34, 0xb7, 0x87, +- 0xfd, 0xfb, 0x78, 0xdd, 0x91, 0x02, 0xf8, 0x67, 0xae, 0x0c, 0x26, 0x0f, +- 0xfc, 0xb6, 0xc6, 0x98, 0xe3, 0x61, 0x0c, 0x6f, 0x38, 0x3e, 0x8f, 0x39, +- 0x16, 0xec, 0x31, 0xc6, 0xcd, 0x30, 0x46, 0x5f, 0xd3, 0x18, 0x13, 0xfe, +- 0x18, 0x59, 0x29, 0x5e, 0x99, 0xc0, 0x5e, 0x1b, 0x83, 0x7d, 0x4f, 0xda, +- 0xa7, 0xe5, 0x23, 0x22, 0x9d, 0x38, 0xf7, 0x72, 0x0a, 0x72, 0xf2, 0xbc, +- 0x49, 0x77, 0x1a, 0xf3, 0x7e, 0x0d, 0xb6, 0x35, 0xe0, 0x3c, 0xc5, 0x58, +- 0x18, 0x36, 0xec, 0xf3, 0x2e, 0xe3, 0x62, 0x05, 0x30, 0xb2, 0x84, 0x6d, +- 0x85, 0x86, 0x53, 0x35, 0xf0, 0xba, 0x2a, 0x2c, 0x69, 0xd1, 0xe1, 0x7b, +- 0x76, 0x48, 0xd1, 0x0e, 0x8d, 0x87, 0xc1, 0x6b, 0xb2, 0x65, 0xee, 0x23, +- 0x19, 0x0a, 0x8f, 0xb5, 0x82, 0x8b, 0x7a, 0xf2, 0x36, 0xa0, 0xa6, 0x58, +- 0x5a, 0x92, 0xfa, 0x86, 0x8d, 0xe3, 0x05, 0xc8, 0xe1, 0x45, 0xfc, 0x7f, +- 0x3e, 0xaa, 0x75, 0x4a, 0xe0, 0xeb, 0x8b, 0x78, 0x1f, 0xf2, 0x19, 0xf2, +- 0x88, 0x1a, 0xec, 0xad, 0x05, 0x5b, 0x03, 0x5e, 0x35, 0x4a, 0xde, 0xf5, +- 0xdc, 0xda, 0x4d, 0x79, 0x73, 0x35, 0x81, 0x67, 0xd1, 0x2e, 0x9f, 0x21, +- 0x1e, 0xd8, 0x0b, 0x69, 0x9c, 0x5b, 0x37, 0xdc, 0xb7, 0xb8, 0x85, 0x0d, +- 0xd4, 0x05, 0x8e, 0x00, 0x8e, 0xbd, 0x0d, 0x0c, 0x2c, 0xe2, 0xfe, 0xfa, +- 0x6a, 0x44, 0xd6, 0x1c, 0xf2, 0x22, 0x89, 0x67, 0x71, 0x6f, 0x7d, 0x7d, +- 0xb1, 0xd7, 0xe4, 0x51, 0xd8, 0x7f, 0x42, 0x0a, 0xe0, 0x75, 0xa7, 0xb5, +- 0xef, 0xad, 0xe4, 0xcc, 0x39, 0x35, 0xfa, 0x77, 0xb3, 0x52, 0xe7, 0x7e, +- 0xd2, 0xdc, 0x03, 0xb9, 0xc1, 0x65, 0xe8, 0x2c, 0x39, 0x3b, 0xfd, 0x00, +- 0xfc, 0xdf, 0xe0, 0x75, 0xbe, 0x3b, 0x8e, 0xd5, 0x24, 0xd6, 0x86, 0xfb, +- 0xbe, 0x10, 0x9a, 0x3e, 0x0e, 0x3b, 0x6a, 0x71, 0xaf, 0x17, 0x15, 0x0b, +- 0x8a, 0xcb, 0xb3, 0xb0, 0x29, 0xac, 0xb5, 0xe8, 0x83, 0x2e, 0x3e, 0x08, +- 0x59, 0xa6, 0x71, 0x5f, 0x93, 0x2d, 0xd9, 0x2c, 0x2a, 0x2f, 0xb3, 0x5e, +- 0x32, 0xb8, 0x66, 0xd5, 0xc0, 0xd1, 0xb0, 0x7f, 0xac, 0x4d, 0xe8, 0x16, +- 0xf6, 0x90, 0xb5, 0x19, 0xc5, 0x11, 0x78, 0xbc, 0x09, 0xbf, 0x02, 0xf8, +- 0x66, 0x6d, 0xc2, 0x27, 0x00, 0xbe, 0x59, 0x9b, 0x29, 0x1c, 0x81, 0xf1, +- 0x9b, 0x01, 0xae, 0x71, 0xfc, 0x94, 0xe6, 0xe1, 0x0d, 0xbe, 0x90, 0x4b, +- 0x12, 0x5f, 0x02, 0x3e, 0x69, 0x74, 0xe1, 0xeb, 0xcb, 0xc4, 0x10, 0xea, +- 0x75, 0x12, 0xb8, 0x45, 0x5d, 0x30, 0x5c, 0x72, 0xbd, 0x62, 0xd6, 0x6c, +- 0x7e, 0xeb, 0x9a, 0xda, 0x88, 0x29, 0x71, 0xa0, 0x63, 0x5c, 0x3b, 0x5c, +- 0x53, 0x1b, 0xf0, 0xba, 0x64, 0xf4, 0xc8, 0x35, 0xfb, 0xb9, 0x64, 0xd6, +- 0x53, 0xf2, 0x0d, 0xc5, 0xad, 0x00, 0xb3, 0xc8, 0x21, 0x63, 0x58, 0x3f, +- 0x47, 0x9e, 0xff, 0xf6, 0x4d, 0xc9, 0x7e, 0x87, 0xb8, 0x35, 0x1c, 0x6b, +- 0x0f, 0x11, 0xab, 0x3c, 0xd9, 0x80, 0x6d, 0x3a, 0xed, 0x26, 0x1e, 0x65, +- 0xfd, 0x66, 0x1e, 0xba, 0xd2, 0x7a, 0x32, 0xe1, 0xc6, 0x43, 0xc9, 0x47, +- 0xdb, 0x43, 0xb4, 0x8d, 0xc3, 0xf6, 0x45, 0x39, 0xe5, 0xc7, 0xa3, 0x0e, +- 0xc8, 0x45, 0xe5, 0xfe, 0x2c, 0xcf, 0x78, 0x57, 0x73, 0x23, 0xef, 0xa4, +- 0xb9, 0xd6, 0x68, 0x6f, 0x6a, 0xdc, 0xa8, 0xed, 0x9d, 0x74, 0x8b, 0x14, +- 0x7b, 0x3c, 0xef, 0xc2, 0xc9, 0xb7, 0xa2, 0x26, 0xce, 0xd5, 0x7f, 0xd4, +- 0x60, 0x01, 0x00, 0x4c, 0xdb, 0x9f, 0xc0, 0x91, 0xba, 0x4d, 0x7b, 0x4b, +- 0xfb, 0x48, 0xb9, 0xe1, 0xb8, 0xce, 0xff, 0xb4, 0xbd, 0x4b, 0xb0, 0xbd, +- 0xb4, 0x97, 0x47, 0x24, 0xc7, 0x9c, 0x9c, 0xa5, 0xe7, 0x0b, 0x86, 0x4b, +- 0xfb, 0xf7, 0x55, 0xf2, 0x32, 0x5f, 0x21, 0x87, 0xaa, 0xc3, 0x96, 0xb1, +- 0xf6, 0x91, 0x36, 0x6d, 0x0e, 0xf6, 0x9c, 0xb9, 0x5a, 0x5c, 0xab, 0xb2, +- 0x5f, 0x22, 0x15, 0xb7, 0xf0, 0xce, 0x3b, 0x3a, 0x55, 0x82, 0xfe, 0x51, +- 0x9f, 0x20, 0xf7, 0x17, 0xe8, 0x5b, 0x0c, 0xa9, 0x8e, 0x64, 0x7f, 0xc0, +- 0xb5, 0xf7, 0xbc, 0x33, 0x2e, 0xd4, 0xb0, 0xd3, 0xec, 0x01, 0xf2, 0x80, +- 0x8f, 0x63, 0x5d, 0xa6, 0xdc, 0x9b, 0xb4, 0xdd, 0x7f, 0xb7, 0x9c, 0xe1, +- 0xd4, 0xc5, 0x10, 0xf7, 0x36, 0xda, 0xeb, 0x61, 0xa9, 0x46, 0xf9, 0xfe, +- 0x58, 0xaf, 0x10, 0xf7, 0xce, 0x7e, 0xeb, 0xd0, 0xbc, 0x06, 0x59, 0xac, +- 0x01, 0xd7, 0x32, 0x58, 0x03, 0xfe, 0x9f, 0x80, 0xbc, 0xe8, 0x33, 0x10, +- 0x87, 0xf1, 0x7f, 0xcb, 0x3c, 0x9b, 0x75, 0x99, 0xbb, 0x73, 0xe6, 0x7c, +- 0x29, 0xd3, 0xd7, 0x25, 0xa7, 0xf2, 0x5d, 0x92, 0x5c, 0xe5, 0x75, 0x99, +- 0xac, 0x2c, 0xc9, 0x03, 0xce, 0x38, 0xde, 0xf7, 0x86, 0x37, 0xeb, 0xa8, +- 0xaf, 0x32, 0x3a, 0x83, 0x67, 0xcf, 0x8e, 0xf4, 0xc9, 0x9f, 0x5d, 0x47, +- 0x16, 0xd7, 0x6c, 0xc9, 0xdb, 0x69, 0x79, 0x5e, 0x63, 0xf9, 0xf4, 0x4f, +- 0x42, 0xe0, 0xa4, 0xcc, 0xc9, 0xb7, 0x89, 0xf4, 0x38, 0xb1, 0x6d, 0x21, +- 0xa7, 0x6c, 0x81, 0xac, 0xe3, 0x86, 0x37, 0xdb, 0xe6, 0xfa, 0xb1, 0x17, +- 0xc0, 0xdd, 0xdd, 0xb7, 0x7a, 0x83, 0xf8, 0xb0, 0xe1, 0xb7, 0x7f, 0xf0, +- 0xf3, 0x62, 0x69, 0xa9, 0x30, 0x07, 0xa7, 0x38, 0xeb, 0x40, 0x97, 0x98, +- 0xc3, 0x8f, 0x69, 0xdc, 0xa1, 0xa5, 0x4c, 0x8c, 0xba, 0x0a, 0x8c, 0x1a, +- 0x25, 0x76, 0x8d, 0xaf, 0xb9, 0x8c, 0x0b, 0x44, 0xe5, 0xb7, 0x25, 0xe2, +- 0x70, 0x5c, 0x7e, 0x53, 0x7a, 0x16, 0xf3, 0x49, 0x54, 0x19, 0xcf, 0xbc, +- 0x5e, 0x29, 0x90, 0x27, 0x29, 0x9f, 0xcf, 0xba, 0x5f, 0x54, 0x3b, 0x10, +- 0xb7, 0x8a, 0xdd, 0x2d, 0x8a, 0x37, 0x4f, 0x6b, 0x1e, 0x36, 0x6e, 0x0d, +- 0xc8, 0xf5, 0x55, 0xbe, 0x6f, 0x0a, 0x63, 0x47, 0x43, 0xb9, 0x75, 0xda, +- 0xa5, 0x64, 0x6c, 0xc6, 0x3a, 0x20, 0x17, 0xa2, 0x8c, 0x53, 0x8f, 0x11, +- 0x9f, 0x61, 0x0b, 0x87, 0xed, 0x19, 0xd6, 0x38, 0xa9, 0xfd, 0x89, 0x35, +- 0xe1, 0xec, 0xd3, 0x3e, 0xce, 0xf2, 0xda, 0x18, 0x64, 0x4a, 0x5b, 0x94, +- 0xa8, 0x4c, 0x58, 0x49, 0xd8, 0x3c, 0xfc, 0xdf, 0xe0, 0xf8, 0x71, 0xf9, +- 0xc2, 0xc6, 0x45, 0xf0, 0xef, 0x61, 0xfb, 0x1c, 0xed, 0xaa, 0x3d, 0x8a, +- 0x7b, 0xf9, 0xfc, 0x0f, 0x34, 0x8d, 0xf5, 0x69, 0x7f, 0x2c, 0x5e, 0xc7, +- 0x3e, 0x2f, 0x3b, 0x32, 0x5b, 0x62, 0x2e, 0xda, 0xcc, 0x75, 0xef, 0xbd, +- 0x67, 0x77, 0x9e, 0xbb, 0xb0, 0x4c, 0x7e, 0x63, 0xea, 0xdc, 0x8a, 0xe0, +- 0x42, 0x9f, 0xec, 0xe2, 0x33, 0xf9, 0xbc, 0xc3, 0x92, 0x7d, 0x04, 0xf8, +- 0x52, 0xe6, 0xaf, 0xe0, 0xd7, 0xde, 0xc2, 0x5f, 0x89, 0xf6, 0xef, 0x63, +- 0x9b, 0xee, 0xf3, 0xc7, 0xfb, 0x3d, 0x74, 0x28, 0xda, 0x70, 0x3f, 0x63, +- 0x2a, 0x6c, 0xc7, 0xa5, 0xb0, 0xc1, 0xa3, 0xe7, 0x75, 0x39, 0xad, 0x72, +- 0xce, 0xbe, 0xbd, 0x69, 0x8c, 0x13, 0x38, 0x67, 0x38, 0x41, 0xb8, 0x1c, +- 0xf2, 0xb9, 0xc5, 0x9d, 0xe4, 0x4d, 0xfe, 0xff, 0x36, 0x8d, 0xc5, 0xc4, +- 0xad, 0xfe, 0xa6, 0xf7, 0xb8, 0x73, 0xc7, 0x0e, 0xc7, 0x2d, 0x62, 0xe7, +- 0x8f, 0x71, 0x8d, 0x3a, 0xe4, 0x29, 0x8f, 0x8f, 0x80, 0xe7, 0xe7, 0x80, +- 0x05, 0x51, 0xe7, 0xb6, 0x18, 0x8b, 0x4d, 0xae, 0x2d, 0x9b, 0x7a, 0x54, +- 0x72, 0xe0, 0x6b, 0xfb, 0xe6, 0x6a, 0x53, 0xd0, 0x65, 0x8c, 0x7f, 0x90, +- 0xe3, 0x8f, 0xf8, 0xeb, 0x9c, 0x70, 0x0b, 0xd6, 0x87, 0x65, 0x66, 0xd5, +- 0xe8, 0x5f, 0xd6, 0x81, 0xee, 0x1d, 0x46, 0x7b, 0x9d, 0x36, 0xe1, 0xfd, +- 0xc6, 0x09, 0x6c, 0x43, 0x4a, 0x6d, 0xc3, 0xfc, 0x32, 0xf5, 0x93, 0x7a, +- 0x19, 0xe8, 0x63, 0x80, 0x79, 0xd4, 0x51, 0xe2, 0x6c, 0x5a, 0x5e, 0x58, +- 0xe6, 0xda, 0x64, 0x34, 0xa7, 0x35, 0xb4, 0x32, 0xab, 0xf5, 0x3d, 0x83, +- 0xe5, 0xc4, 0x8b, 0x05, 0x19, 0x97, 0xab, 0x2e, 0xd7, 0x2c, 0x51, 0xcd, +- 0x87, 0x3b, 0x1a, 0xde, 0xff, 0x9c, 0xbf, 0x66, 0x29, 0xd5, 0xab, 0xc1, +- 0xf2, 0xe5, 0x1d, 0x79, 0xe7, 0xad, 0xc3, 0x4d, 0xeb, 0x14, 0x70, 0xb8, +- 0xb8, 0x90, 0x3f, 0x44, 0xba, 0xd8, 0x87, 0xcf, 0x25, 0xe7, 0xe3, 0xb3, +- 0x68, 0x5b, 0xef, 0x60, 0x3d, 0x83, 0xd0, 0x8f, 0x8b, 0x3c, 0x62, 0xb8, +- 0x45, 0xde, 0x7a, 0x18, 0xeb, 0x76, 0x50, 0xeb, 0x28, 0xe7, 0xbf, 0xfb, +- 0x1e, 0xfa, 0xe7, 0x7d, 0x7e, 0x9e, 0xc6, 0x78, 0x7c, 0x77, 0xee, 0xa9, +- 0xd2, 0x49, 0xea, 0xe6, 0xa4, 0xe6, 0x03, 0xd9, 0x87, 0xfb, 0x96, 0x6b, +- 0x44, 0x39, 0x5c, 0x8e, 0x19, 0x7b, 0x7a, 0xa2, 0x69, 0x3e, 0x49, 0x7f, +- 0x3e, 0xc1, 0xf5, 0x16, 0x89, 0xf4, 0xa6, 0xb4, 0x96, 0x24, 0x59, 0xa6, +- 0x8f, 0x02, 0x5b, 0x35, 0xcd, 0xb1, 0x6e, 0x8d, 0xbd, 0xf9, 0xff, 0x13, +- 0x7b, 0xf3, 0x56, 0x49, 0xe7, 0xd8, 0xe2, 0xfc, 0x2f, 0x72, 0x6c, 0xac, +- 0xa7, 0x37, 0x72, 0x7b, 0x6e, 0x99, 0xf6, 0x29, 0xa3, 0xb1, 0xe3, 0x3f, +- 0x95, 0xb8, 0x96, 0x9c, 0xe3, 0x55, 0xce, 0x71, 0xbc, 0xae, 0xb5, 0x74, +- 0x0f, 0xe9, 0x9e, 0x5d, 0x5c, 0x26, 0xa6, 0x74, 0xc8, 0x5a, 0x25, 0xc0, +- 0x95, 0x07, 0x7c, 0x4e, 0x5b, 0xec, 0x6e, 0xc5, 0x3e, 0x39, 0xe3, 0x5a, +- 0x5a, 0x47, 0x68, 0x3d, 0xcc, 0x73, 0x03, 0x52, 0x5b, 0xa5, 0x9d, 0x4d, +- 0xc2, 0xaf, 0x88, 0x86, 0x6a, 0xeb, 0xcc, 0x45, 0xb2, 0x4e, 0x64, 0x5c, +- 0x98, 0xbb, 0xcf, 0xd9, 0xf3, 0xd8, 0x5f, 0x31, 0xf8, 0xfd, 0xe4, 0xf0, +- 0x8c, 0x8f, 0x35, 0xcb, 0x7b, 0x74, 0x87, 0x03, 0xee, 0x95, 0xf3, 0x2f, +- 0xb0, 0xde, 0xd4, 0x6b, 0xc7, 0xbe, 0x0e, 0x3b, 0x99, 0x8b, 0xf2, 0xff, +- 0x0c, 0xb8, 0x3f, 0x7d, 0x8d, 0xb8, 0xfa, 0x1a, 0xb5, 0x6a, 0x46, 0x96, +- 0x54, 0xf7, 0x3b, 0xfc, 0x58, 0x52, 0x87, 0xea, 0x07, 0x75, 0x2c, 0xaf, +- 0x9c, 0x7b, 0x54, 0x71, 0xaa, 0x58, 0x1a, 0x36, 0x75, 0x26, 0x76, 0xcc, +- 0xaf, 0x27, 0x6f, 0x7c, 0x7e, 0xcc, 0x7f, 0xfe, 0x5f, 0x7c, 0xf9, 0xda, +- 0x8a, 0x31, 0xba, 0xd6, 0x56, 0x52, 0x7d, 0xcb, 0xf9, 0x65, 0xea, 0x07, +- 0xf5, 0x84, 0x38, 0x17, 0xdc, 0x17, 0xc8, 0x24, 0x68, 0xf3, 0x7e, 0xea, +- 0x7c, 0x63, 0x4d, 0x41, 0xb0, 0x3f, 0x83, 0x73, 0x81, 0x8c, 0x78, 0xad, +- 0xd1, 0x0e, 0x70, 0xaf, 0xc5, 0x21, 0xa7, 0xdd, 0xfd, 0xd6, 0x55, 0xde, +- 0x95, 0x4d, 0xf6, 0x14, 0xe7, 0x7f, 0x99, 0x71, 0x5c, 0xec, 0xb1, 0xfd, +- 0xe4, 0xf3, 0x65, 0x95, 0x4f, 0x1e, 0xf2, 0xe9, 0x52, 0xdc, 0xa7, 0x8f, +- 0x77, 0xc9, 0xd7, 0xb9, 0x0e, 0xac, 0x19, 0xe3, 0xb2, 0xc0, 0xb7, 0xf3, +- 0xc4, 0xf9, 0xbe, 0x3e, 0xe2, 0x0b, 0x63, 0x8a, 0x99, 0xe9, 0x43, 0xc0, +- 0x30, 0xb6, 0x8f, 0x2b, 0x07, 0x31, 0x3e, 0x56, 0x5c, 0x63, 0x8b, 0x61, +- 0x60, 0x72, 0xad, 0x04, 0x7e, 0xc6, 0xba, 0xaf, 0x3d, 0xf2, 0x7a, 0xca, +- 0x5f, 0xaf, 0x89, 0x3e, 0xca, 0x87, 0xfb, 0x80, 0x58, 0xd9, 0x89, 0xf1, +- 0xce, 0x46, 0x53, 0xd0, 0xb1, 0x71, 0x9c, 0x1f, 0x52, 0x1f, 0x22, 0x8c, +- 0x7d, 0xbe, 0x5d, 0xea, 0xf5, 0xfd, 0x36, 0x07, 0x6d, 0xf8, 0xaa, 0xa5, +- 0x2e, 0xfa, 0x11, 0x1a, 0x47, 0x6c, 0x2d, 0xc3, 0x67, 0x05, 0x76, 0xd7, +- 0xd5, 0x06, 0x8d, 0xe0, 0xfa, 0x6d, 0xac, 0x89, 0xd3, 0xda, 0xe0, 0x6d, +- 0x95, 0x19, 0x7d, 0xcd, 0x63, 0xba, 0xa6, 0xb5, 0x52, 0x22, 0xf6, 0xb8, +- 0xf8, 0xe7, 0xa6, 0xf9, 0xdc, 0xc1, 0x86, 0x79, 0x4d, 0xca, 0xd9, 0x1d, +- 0x1b, 0x41, 0xdf, 0x19, 0xbc, 0xbd, 0x62, 0x6c, 0x40, 0xb1, 0x9a, 0xd2, +- 0xfa, 0xa5, 0xf0, 0xd8, 0x06, 0xd6, 0x92, 0x3c, 0xf4, 0x06, 0xb8, 0xf7, +- 0x08, 0xd6, 0x90, 0x5c, 0xdb, 0x9b, 0x5b, 0x70, 0x33, 0xcc, 0x85, 0xc1, +- 0x86, 0xcd, 0x49, 0x0e, 0xbe, 0x40, 0x2e, 0x7c, 0x98, 0x31, 0x64, 0xf0, +- 0xc1, 0x82, 0x1f, 0x6f, 0x1c, 0x61, 0x9c, 0x54, 0x56, 0xd6, 0x39, 0x77, +- 0xee, 0x6f, 0xe3, 0x6f, 0xd7, 0x4a, 0x9c, 0xaf, 0x89, 0x3d, 0xb0, 0x6d, +- 0x95, 0x5d, 0x1c, 0xb9, 0x16, 0x69, 0x1c, 0xef, 0xc5, 0x9e, 0xe0, 0xbd, +- 0x38, 0xae, 0xdf, 0x90, 0x5f, 0xad, 0x06, 0xf6, 0x3c, 0x24, 0x6f, 0x3a, +- 0xde, 0xdc, 0xbc, 0xdb, 0xcd, 0x35, 0x70, 0x0b, 0xcc, 0x65, 0x3b, 0x8e, +- 0x5b, 0x14, 0xcf, 0xab, 0xbb, 0xf5, 0x6e, 0x4b, 0x65, 0x49, 0x0c, 0xf8, +- 0x1a, 0xd6, 0xf0, 0x8d, 0xbb, 0x2d, 0x31, 0xf2, 0xa3, 0x6c, 0xae, 0xfd, +- 0x57, 0xfc, 0x0f, 0x30, 0x90, 0xfa, 0x48, 0xbd, 0xbc, 0x21, 0x53, 0x8a, +- 0xf9, 0xfb, 0xf5, 0x6b, 0xc4, 0x89, 0x80, 0xd3, 0x12, 0xd3, 0xa9, 0x8b, +- 0x31, 0xf5, 0x09, 0x8e, 0x95, 0x9b, 0x71, 0xe1, 0x33, 0x7e, 0x0e, 0x61, +- 0x3f, 0xdd, 0x7b, 0xd4, 0xc7, 0x86, 0x31, 0xe5, 0xcb, 0x19, 0x9b, 0x18, +- 0xc1, 0xf9, 0x1c, 0x94, 0xd9, 0x2b, 0x8d, 0x38, 0x4c, 0x5f, 0xcf, 0xe0, +- 0x87, 0x7e, 0xe3, 0xa1, 0xfc, 0xd7, 0x92, 0xc1, 0x15, 0xf2, 0x25, 0x07, +- 0x58, 0xda, 0x23, 0xf9, 0xe9, 0xb0, 0x24, 0x57, 0x7e, 0xd6, 0x67, 0xf8, +- 0x2d, 0xf5, 0x0f, 0xfb, 0x4d, 0xcf, 0xb1, 0x5d, 0xc7, 0xf9, 0x23, 0xc2, +- 0x67, 0x1b, 0x7d, 0xc6, 0x7e, 0x3e, 0x1f, 0x5c, 0xb3, 0x9b, 0x74, 0xf4, +- 0x5e, 0x5f, 0x47, 0x79, 0xdd, 0x32, 0xb9, 0x0e, 0xdc, 0x3b, 0xb8, 0xc2, +- 0x39, 0x9a, 0x7e, 0x83, 0x2b, 0xc6, 0x47, 0xdf, 0xdb, 0x6f, 0x64, 0xa7, +- 0x1f, 0xae, 0x83, 0xef, 0x9a, 0xb1, 0xa7, 0x46, 0xc1, 0xe3, 0x46, 0x58, +- 0x83, 0x44, 0x9b, 0x3d, 0xe4, 0x4e, 0x09, 0xf5, 0x3d, 0xe1, 0xeb, 0x1c, +- 0xf1, 0xa6, 0xcb, 0xc7, 0x9b, 0x5d, 0x1b, 0x93, 0x33, 0x35, 0x27, 0x8c, +- 0x83, 0x34, 0xd8, 0x18, 0xe9, 0xff, 0x4f, 0x1b, 0x73, 0xc4, 0x1f, 0x27, +- 0xb8, 0x16, 0xe0, 0x4a, 0xd0, 0x0e, 0x70, 0xa5, 0x99, 0xc7, 0x06, 0xb2, +- 0x6f, 0x3c, 0xdf, 0xe8, 0xe7, 0x65, 0x7c, 0x7f, 0xde, 0xd2, 0xfd, 0xf3, +- 0xca, 0x8e, 0x1f, 0x4f, 0x19, 0x27, 0xa0, 0x7a, 0x25, 0xec, 0xed, 0xf7, +- 0xd4, 0x6f, 0x5e, 0xbc, 0x32, 0xa1, 0xb1, 0x9c, 0x9a, 0xca, 0xfa, 0xab, +- 0x58, 0x9f, 0x33, 0xd8, 0x47, 0x0f, 0x46, 0x77, 0xeb, 0x86, 0x56, 0x9f, +- 0xc9, 0xfa, 0xbc, 0x25, 0x23, 0x5d, 0x98, 0x5f, 0x5a, 0xeb, 0xb0, 0xda, +- 0x9d, 0xaf, 0xc8, 0x03, 0x66, 0xee, 0x6d, 0x6d, 0x63, 0xeb, 0xcf, 0xb4, +- 0x7d, 0x2b, 0xd0, 0x73, 0xea, 0xcf, 0xea, 0x33, 0xb3, 0x15, 0x6f, 0x3c, +- 0x72, 0x72, 0xd8, 0x2e, 0x0a, 0x6b, 0xbd, 0xc7, 0xe5, 0x09, 0x97, 0xd7, +- 0x7f, 0x88, 0xeb, 0xd3, 0xf4, 0x21, 0x13, 0x11, 0xfd, 0xfe, 0x20, 0x11, +- 0x7b, 0x0c, 0x7b, 0x6f, 0x46, 0xbf, 0xf7, 0x38, 0xa4, 0x35, 0xe2, 0x35, +- 0x21, 0x97, 0x62, 0x8d, 0xc1, 0xb3, 0xf2, 0xb8, 0x3b, 0xe4, 0xd6, 0xc5, +- 0x70, 0xdc, 0x19, 0xcd, 0xf7, 0x1c, 0x90, 0xc7, 0xdc, 0x48, 0x5b, 0x76, +- 0xcb, 0xe8, 0xfc, 0x44, 0x38, 0xd3, 0xbe, 0xe0, 0x44, 0xdb, 0xa6, 0xb6, +- 0xb0, 0xa7, 0xb7, 0x80, 0xf7, 0x5b, 0xb1, 0x50, 0x6e, 0x83, 0xef, 0x1e, +- 0x36, 0x35, 0x1d, 0xea, 0x5f, 0x11, 0x43, 0xee, 0x93, 0x6d, 0xfb, 0xb8, +- 0x6c, 0xa7, 0xf8, 0x4d, 0xd6, 0x29, 0xb4, 0x07, 0x35, 0xe7, 0xb2, 0x0d, +- 0xbc, 0xd9, 0x4e, 0xb5, 0xa9, 0x0e, 0xaa, 0x1f, 0x06, 0x9c, 0xda, 0xb6, +- 0x89, 0x4f, 0x77, 0xf0, 0x88, 0x77, 0x9e, 0x83, 0x1c, 0x58, 0xef, 0x71, +- 0x02, 0x6d, 0xe2, 0x9a, 0xdd, 0x74, 0xbe, 0x1f, 0xed, 0xbb, 0x31, 0x46, +- 0xab, 0xbe, 0xa3, 0xe5, 0x9c, 0x34, 0x79, 0xcc, 0x3d, 0xf7, 0x74, 0x36, +- 0xb5, 0x3f, 0x77, 0xd4, 0x7c, 0x6f, 0xf4, 0x3d, 0xca, 0xb8, 0x90, 0x91, +- 0xbf, 0xc5, 0xf6, 0xb6, 0x97, 0xfb, 0xf6, 0xb6, 0x0f, 0x4b, 0x7b, 0x0f, +- 0x45, 0xd1, 0xdd, 0x74, 0x5f, 0xa0, 0x43, 0x41, 0xfb, 0x28, 0x71, 0x85, +- 0x76, 0x4b, 0x7d, 0xa6, 0xed, 0x28, 0x9f, 0xb5, 0xd8, 0xd4, 0x87, 0xff, +- 0xd9, 0x87, 0x7d, 0x19, 0xbf, 0xfb, 0xbe, 0xd1, 0x33, 0x8b, 0xbe, 0x3f, +- 0xe3, 0x17, 0xd4, 0xd3, 0xfd, 0xfc, 0xa9, 0x84, 0x7e, 0x1f, 0xb4, 0xbf, +- 0xae, 0x05, 0x38, 0x12, 0xf3, 0x63, 0x0a, 0x26, 0xef, 0x64, 0xe2, 0xbe, +- 0x94, 0x9d, 0xe6, 0x9d, 0x62, 0xd7, 0x21, 0xe7, 0x0b, 0x90, 0xf3, 0x64, +- 0x98, 0xbe, 0x1f, 0xf3, 0x4b, 0x8e, 0xe4, 0xb6, 0x28, 0x6f, 0xda, 0x75, +- 0xea, 0x26, 0x78, 0xc4, 0x16, 0x31, 0xc5, 0x02, 0x07, 0xca, 0x60, 0x8e, +- 0xaf, 0xe1, 0xbc, 0xe5, 0xd7, 0x6f, 0xa4, 0x61, 0xd3, 0x5c, 0xfc, 0x28, +- 0x77, 0xf8, 0xf4, 0x6b, 0x94, 0x31, 0xeb, 0xd9, 0x18, 0x0b, 0xe0, 0xfc, +- 0x98, 0x63, 0x77, 0xa1, 0xd3, 0x13, 0xd0, 0xdd, 0x88, 0x38, 0xe5, 0x13, +- 0x52, 0x98, 0x9e, 0x50, 0xfb, 0x3f, 0x08, 0xfb, 0x34, 0xef, 0x66, 0x65, +- 0xe1, 0xe5, 0x3b, 0xb1, 0x4f, 0xe9, 0xe7, 0x6b, 0x0c, 0xc3, 0x6b, 0x51, +- 0x9d, 0x26, 0xe7, 0x60, 0xdc, 0xcd, 0xe4, 0x92, 0xfd, 0xef, 0xaa, 0xfa, +- 0xe5, 0x70, 0x56, 0x2a, 0x57, 0x6c, 0xad, 0x85, 0xc9, 0xc8, 0x7b, 0x1e, +- 0x65, 0x38, 0x73, 0x3e, 0x0e, 0x9c, 0x22, 0x77, 0xff, 0x60, 0xd4, 0xac, +- 0xe9, 0x5f, 0xfb, 0xe9, 0x03, 0x27, 0xcb, 0x8d, 0x63, 0x68, 0xfd, 0x0c, +- 0xae, 0x3d, 0x74, 0xd4, 0xec, 0x1f, 0xfa, 0xc3, 0x37, 0xbd, 0x4c, 0x94, +- 0xcf, 0xe4, 0xbd, 0xcc, 0xd1, 0x52, 0x57, 0x38, 0xb7, 0x77, 0x7d, 0xbd, +- 0xfe, 0x28, 0xc6, 0x8b, 0xcb, 0xe0, 0xe6, 0x84, 0xfa, 0xf1, 0xf3, 0x7b, +- 0x7c, 0x56, 0x13, 0x1f, 0x30, 0x7e, 0xeb, 0x1b, 0xf2, 0xd8, 0x06, 0xe5, +- 0x44, 0xfb, 0x1e, 0x92, 0x1f, 0x39, 0xc3, 0xf6, 0x93, 0x5a, 0x77, 0x9c, +- 0xc8, 0x30, 0x1f, 0x73, 0xd0, 0x49, 0xda, 0x6b, 0x12, 0x19, 0xfd, 0x98, +- 0xf0, 0x9b, 0x16, 0xd6, 0x7a, 0x0c, 0xbb, 0x4f, 0x4a, 0x50, 0xef, 0x31, +- 0x94, 0x39, 0x10, 0xfa, 0xa7, 0xf7, 0xc6, 0x79, 0xde, 0x63, 0xea, 0x3d, +- 0x24, 0x44, 0xb9, 0xfd, 0xf1, 0x0e, 0x7e, 0xe3, 0xb9, 0x37, 0xde, 0x77, +- 0xff, 0xd3, 0xe7, 0xd2, 0x89, 0x25, 0xfa, 0xac, 0x2d, 0xce, 0xbf, 0xfa, +- 0xcd, 0xbb, 0x16, 0x0a, 0x9d, 0xa2, 0xf9, 0xb2, 0x4b, 0xef, 0x38, 0xac, +- 0x7b, 0x48, 0xc4, 0x0e, 0x58, 0x8c, 0x7b, 0x13, 0xdf, 0x98, 0x43, 0x61, +- 0x8c, 0x0d, 0x6d, 0x70, 0x86, 0x97, 0x46, 0x2c, 0xb9, 0x3f, 0x92, 0x89, +- 0x5b, 0x72, 0x2c, 0xbe, 0x22, 0x78, 0x26, 0xf3, 0x29, 0x1b, 0x89, 0x02, +- 0xef, 0x8f, 0x94, 0x39, 0x5e, 0x5c, 0xfd, 0x93, 0xe4, 0x31, 0xcf, 0xbb, +- 0xe4, 0x4a, 0x28, 0x79, 0xd7, 0xdb, 0x1e, 0x73, 0xde, 0xd6, 0xe6, 0xfb, +- 0xd5, 0x23, 0x10, 0x37, 0x16, 0x9e, 0x32, 0xb5, 0x87, 0x4b, 0x97, 0x06, +- 0x37, 0xf4, 0x9b, 0xb9, 0x69, 0xd3, 0x2e, 0xa1, 0xdd, 0xea, 0xd7, 0x41, +- 0x55, 0x2e, 0x0d, 0x56, 0x8f, 0xdc, 0x6e, 0xfc, 0x6d, 0xf2, 0xab, 0xc0, +- 0x87, 0x89, 0xef, 0xa9, 0x0b, 0x3b, 0xbb, 0x7c, 0x26, 0x74, 0x66, 0xd9, +- 0x5a, 0x6d, 0x63, 0x0e, 0xec, 0x94, 0x27, 0xdd, 0x27, 0x83, 0x38, 0x15, +- 0xe3, 0x5a, 0x22, 0x9d, 0x9b, 0x13, 0x26, 0xe7, 0xb1, 0x69, 0x29, 0x17, +- 0xea, 0x7a, 0x89, 0xb1, 0xaa, 0xa8, 0x62, 0x43, 0xf7, 0x26, 0xeb, 0xc1, +- 0x7a, 0x64, 0x46, 0x31, 0xa3, 0x47, 0xf1, 0xc0, 0xe8, 0x5d, 0x97, 0xc6, +- 0x61, 0xc9, 0x97, 0xae, 0x2d, 0xbb, 0x03, 0xac, 0xe1, 0x79, 0x75, 0xf9, +- 0x09, 0xb4, 0x89, 0x33, 0xf7, 0x34, 0x9d, 0x6f, 0xcc, 0xc9, 0x26, 0xec, +- 0x41, 0xab, 0x39, 0x1f, 0xcb, 0x73, 0xcd, 0x79, 0xd8, 0x57, 0x25, 0xdf, +- 0xcb, 0xdc, 0x6b, 0x10, 0x6f, 0x77, 0xfd, 0x78, 0xfb, 0x87, 0x06, 0xa8, +- 0x83, 0xf0, 0x6f, 0xf2, 0x91, 0xb1, 0xb6, 0x91, 0xf9, 0x52, 0xf8, 0x1f, +- 0xbb, 0xb1, 0x53, 0xb4, 0x37, 0x76, 0xf2, 0xe3, 0xb8, 0xf6, 0x25, 0x70, +- 0x92, 0x22, 0xf8, 0x45, 0xc1, 0xaf, 0xc3, 0xe7, 0xf5, 0x9d, 0xfe, 0xb7, +- 0x98, 0xd3, 0x41, 0xcd, 0xad, 0x0f, 0xee, 0xc9, 0xad, 0xdf, 0x35, 0xc0, +- 0xda, 0xe3, 0xe2, 0xd6, 0x6e, 0xdf, 0x88, 0xdf, 0x77, 0xe2, 0x96, 0xef, +- 0x63, 0xf6, 0x4c, 0x51, 0xf7, 0xcc, 0x65, 0x8d, 0x11, 0xcf, 0x6f, 0x2d, +- 0xc9, 0x8c, 0xd3, 0x25, 0xb9, 0xd5, 0xc0, 0x4e, 0x78, 0xe3, 0xb3, 0x6e, +- 0xa1, 0x2f, 0x2c, 0xec, 0xcf, 0xe7, 0x29, 0x47, 0x8b, 0xe5, 0xc2, 0x1c, +- 0xff, 0x90, 0x44, 0xc6, 0x68, 0x3b, 0x68, 0x13, 0x3e, 0x05, 0x2c, 0x03, +- 0x4f, 0xdf, 0x6a, 0xcc, 0x7d, 0xbf, 0x9f, 0x1c, 0x29, 0xc3, 0xe0, 0x9d, +- 0x0b, 0x5e, 0x2b, 0xf6, 0xdf, 0x31, 0xd6, 0xb4, 0xec, 0xcc, 0x95, 0x36, +- 0x4b, 0x6d, 0x93, 0xbe, 0xc7, 0x94, 0xff, 0x1e, 0x61, 0xcc, 0x67, 0xb6, +- 0x14, 0xdc, 0x33, 0x27, 0xc7, 0x4f, 0x25, 0x62, 0x49, 0x4b, 0xe7, 0xa5, +- 0xf6, 0x2b, 0xeb, 0xce, 0xc1, 0x2e, 0xd1, 0x86, 0x29, 0xae, 0x81, 0xab, +- 0x12, 0xd7, 0x68, 0x9f, 0xd4, 0xa6, 0xc5, 0x8b, 0x98, 0x67, 0x6e, 0x4b, +- 0xf3, 0x0f, 0xb1, 0xd3, 0xe1, 0x44, 0x65, 0x46, 0xb1, 0x0e, 0x7c, 0x55, +- 0xe7, 0x0e, 0x7b, 0x1c, 0x6a, 0xcc, 0x2d, 0xd1, 0xbf, 0x64, 0x1e, 0xa6, +- 0x43, 0xb2, 0x15, 0x91, 0x57, 0xa0, 0xdf, 0x57, 0xd7, 0xb9, 0xe7, 0xc2, +- 0xbd, 0xc6, 0x47, 0xac, 0xdf, 0x63, 0x49, 0xaf, 0xe6, 0x6b, 0x8b, 0x58, +- 0x2f, 0xf0, 0xab, 0xf1, 0xf0, 0x29, 0xf8, 0x09, 0x5a, 0x27, 0xc1, 0x18, +- 0xeb, 0x2c, 0x7c, 0xca, 0xc6, 0xb8, 0x10, 0x30, 0x62, 0x9a, 0xe7, 0x67, +- 0xc0, 0x8b, 0x77, 0x73, 0x35, 0xc5, 0xea, 0x82, 0xc6, 0x63, 0x6b, 0xeb, +- 0x1d, 0x6a, 0x2f, 0x6a, 0xd5, 0x3e, 0xac, 0x8b, 0x1c, 0xb7, 0xc6, 0x8a, +- 0xfe, 0xf9, 0x16, 0xa9, 0x56, 0xd9, 0x96, 0x81, 0x56, 0xd5, 0x97, 0x20, +- 0x1f, 0x65, 0xcb, 0x1a, 0xb8, 0x6e, 0x75, 0xc3, 0xc1, 0x2f, 0x85, 0xdf, +- 0x08, 0x7e, 0x0f, 0x4a, 0xb6, 0x4c, 0xfe, 0xcd, 0xfc, 0x53, 0x47, 0xd3, +- 0xf3, 0x5b, 0xf4, 0xfb, 0x11, 0xd6, 0xb4, 0x15, 0x7d, 0x3f, 0xad, 0x58, +- 0xdd, 0x8f, 0x9b, 0x32, 0xbe, 0x9b, 0xf2, 0xb1, 0xee, 0xa7, 0x7e, 0x6d, +- 0xed, 0xbf, 0x01, 0x17, 0x24, 0x5e, 0x9d, 0xe0, 0x70, 0x00, 0x00, 0x00 }; ++ 0xec, 0x5b, 0x5f, 0x6c, 0x5b, 0xd7, 0x79, 0xff, 0xee, 0x21, 0x25, 0x51, ++ 0xb2, 0xfe, 0x5c, 0xc9, 0x8c, 0x43, 0x27, 0x4a, 0x43, 0x4a, 0x57, 0x12, ++ 0x13, 0x69, 0xe9, 0x95, 0xc6, 0x26, 0x2a, 0x46, 0x34, 0x2c, 0x29, 0xdb, ++ 0x4a, 0xe3, 0x07, 0xc5, 0xf5, 0xda, 0xac, 0xeb, 0x30, 0x81, 0xb2, 0xb1, ++ 0xec, 0x61, 0x83, 0x67, 0xac, 0x41, 0xb6, 0xb9, 0x30, 0x41, 0x29, 0x8e, ++ 0x92, 0xd2, 0x22, 0x67, 0x2b, 0x73, 0xb1, 0x65, 0x80, 0x42, 0x49, 0x76, ++ 0xb6, 0xd1, 0x62, 0xda, 0xbd, 0x74, 0x45, 0x1c, 0x0b, 0x8a, 0xe7, 0xe5, ++ 0xa1, 0x0f, 0x69, 0x17, 0x60, 0xed, 0xd0, 0x61, 0x86, 0xe2, 0xda, 0x79, ++ 0x28, 0xb6, 0x6c, 0x40, 0x96, 0x6c, 0x71, 0x73, 0xf7, 0xfb, 0x9d, 0x7b, ++ 0xaf, 0x4c, 0x2b, 0x1a, 0x9a, 0x87, 0x3d, 0xde, 0x03, 0x08, 0xe7, 0x9e, ++ 0x73, 0xbe, 0xf3, 0x9d, 0xef, 0xfb, 0xce, 0xf7, 0xf7, 0xd0, 0xfe, 0xc3, ++ 0x76, 0x69, 0x13, 0xaf, 0x75, 0xe0, 0x2f, 0x75, 0xec, 0x99, 0xe3, 0x63, ++ 0x0f, 0xa5, 0x1e, 0xe2, 0x38, 0xa4, 0xc2, 0x61, 0xf6, 0x86, 0x04, 0x2d, ++ 0x68, 0x41, 0x0b, 0x5a, 0xd0, 0x82, 0x16, 0xb4, 0xa0, 0x05, 0x2d, 0x68, ++ 0x41, 0x0b, 0x5a, 0xd0, 0x82, 0x16, 0xb4, 0xa0, 0x05, 0x2d, 0x68, 0x41, ++ 0x0b, 0x5a, 0xd0, 0x82, 0x16, 0xb4, 0xa0, 0x05, 0x2d, 0x68, 0x41, 0x0b, ++ 0x5a, 0xd0, 0x82, 0x16, 0xb4, 0xa0, 0x05, 0x2d, 0x68, 0x41, 0x0b, 0x5a, ++ 0xd0, 0x82, 0x16, 0xb4, 0xa0, 0x05, 0x2d, 0x68, 0x41, 0x0b, 0x5a, 0xd0, ++ 0x82, 0x16, 0xb4, 0xa0, 0x05, 0xed, 0xff, 0xb3, 0x85, 0x44, 0x4c, 0xf6, ++ 0x1d, 0xde, 0x9f, 0x44, 0x54, 0x3a, 0x7e, 0x3c, 0x6b, 0x49, 0x24, 0x94, ++ 0xbe, 0xf2, 0xf4, 0x8c, 0x25, 0x92, 0xa9, 0x0d, 0xc7, 0x73, 0xf2, 0x0b, ++ 0xa7, 0x10, 0x0d, 0x0b, 0xe7, 0xef, 0x4b, 0xdf, 0x3a, 0x79, 0xe9, 0x91, ++ 0xc4, 0x7b, 0x4b, 0x21, 0x89, 0x98, 0xe9, 0xb7, 0x46, 0xcd, 0x41, 0x89, ++ 0xf4, 0x62, 0xcf, 0x4b, 0x43, 0x97, 0xbb, 0xa4, 0xd3, 0xc7, 0x25, 0x52, ++ 0x2d, 0x25, 0xec, 0xfd, 0x32, 0x6c, 0x6e, 0x48, 0x58, 0x32, 0x38, 0xe3, ++ 0x7c, 0x4d, 0xa4, 0x58, 0x32, 0x88, 0x43, 0x8a, 0xb5, 0x88, 0x5c, 0x0b, ++ 0x11, 0xea, 0x7b, 0x46, 0xb6, 0xfc, 0xb1, 0x93, 0x09, 0xe3, 0x5c, 0x0b, ++ 0xdf, 0x75, 0x7f, 0x3e, 0x22, 0x2a, 0x9d, 0x48, 0x66, 0x43, 0x93, 0x52, ++ 0x5d, 0x74, 0x9c, 0x39, 0xfb, 0x5e, 0xe0, 0xe8, 0x91, 0x39, 0xcb, 0x1d, ++ 0x67, 0xed, 0x07, 0xcd, 0x09, 0xb9, 0x1b, 0x73, 0x21, 0x51, 0xd6, 0x3d, ++ 0xf8, 0x8b, 0x1b, 0xb9, 0xb3, 0xdf, 0x32, 0xb2, 0xcb, 0xed, 0x52, 0x2c, ++ 0x3b, 0x32, 0x63, 0x4b, 0x26, 0x6b, 0xb7, 0x62, 0xfd, 0x63, 0x67, 0x66, ++ 0x6b, 0xcf, 0xb0, 0x99, 0x93, 0x26, 0xc9, 0x44, 0x63, 0x80, 0x59, 0x34, ++ 0x72, 0x17, 0xfe, 0xae, 0x5d, 0xda, 0x40, 0x4f, 0x8a, 0xe3, 0x8f, 0x9d, ++ 0x90, 0x65, 0x61, 0x9d, 0xe7, 0x63, 0x5c, 0x27, 0x5e, 0x7e, 0x13, 0xe7, ++ 0x35, 0xe7, 0xd2, 0x50, 0x4c, 0xbe, 0x5b, 0x8f, 0xca, 0x77, 0xea, 0xa6, ++ 0xbc, 0x5a, 0xef, 0x95, 0xcb, 0x75, 0xc7, 0xf9, 0x8e, 0xed, 0x38, 0x6f, ++ 0xe1, 0xef, 0x3f, 0xed, 0x2d, 0x1e, 0xd0, 0x0a, 0xc6, 0x44, 0xfd, 0x2f, ++ 0xda, 0xa5, 0x33, 0x11, 0x17, 0xd5, 0x2e, 0xb3, 0xe5, 0x98, 0xcc, 0x95, ++ 0x4b, 0xc6, 0x13, 0x17, 0x16, 0x8c, 0xa9, 0x0b, 0x15, 0x9c, 0x19, 0xc6, ++ 0x9c, 0x14, 0x8a, 0xf6, 0x2b, 0x46, 0xae, 0x3e, 0x6f, 0x1c, 0xba, 0xd0, ++ 0x09, 0x1a, 0x79, 0xfe, 0x1e, 0x23, 0x7b, 0xf6, 0x96, 0x64, 0x6d, 0xca, ++ 0x38, 0x61, 0x7e, 0x0d, 0x62, 0xcf, 0x96, 0x48, 0x73, 0xb3, 0x47, 0xaf, ++ 0xe3, 0xa8, 0xb4, 0x73, 0x32, 0x9b, 0xb2, 0xcc, 0xa2, 0x90, 0x3e, 0x3d, ++ 0x77, 0xd9, 0xa5, 0xf9, 0xbc, 0x91, 0xbd, 0xd0, 0x6e, 0xe4, 0xce, 0x85, ++ 0x41, 0x87, 0xf4, 0x86, 0x84, 0xfb, 0x06, 0x62, 0x79, 0xa9, 0xe1, 0x0c, ++ 0x31, 0x55, 0x9a, 0x72, 0x05, 0xcd, 0xa0, 0xe5, 0xbb, 0x65, 0xf0, 0x50, ++ 0x06, 0x0f, 0x65, 0xf2, 0x16, 0x97, 0x4b, 0x43, 0x3e, 0x6f, 0x8e, 0xf3, ++ 0x23, 0x9b, 0xb4, 0x27, 0xe2, 0x19, 0xe5, 0xf3, 0xe9, 0x38, 0xff, 0x61, ++ 0x93, 0x57, 0xf2, 0xe3, 0x38, 0xaf, 0xda, 0x31, 0xd0, 0xee, 0x5c, 0x56, ++ 0x56, 0x09, 0xbc, 0x58, 0xc0, 0x4f, 0x59, 0x2f, 0x80, 0x87, 0x79, 0xf0, ++ 0x77, 0x1e, 0xbc, 0x55, 0x40, 0xc7, 0x2f, 0x3b, 0xaf, 0x60, 0xe4, 0x86, ++ 0xb6, 0xe4, 0x15, 0xa7, 0x8c, 0xf3, 0x2b, 0x0a, 0xb2, 0xde, 0x25, 0xf9, ++ 0x25, 0x53, 0xa6, 0x57, 0xfc, 0xfd, 0xbe, 0x1e, 0x1c, 0x93, 0x83, 0xe5, ++ 0x1e, 0xc8, 0x86, 0xb2, 0x4c, 0xd8, 0x22, 0x0e, 0x64, 0x54, 0x4c, 0x2a, ++ 0x11, 0x23, 0x6f, 0x9f, 0xd4, 0xf7, 0xbf, 0x62, 0x49, 0x26, 0x6f, 0x53, ++ 0x8e, 0x12, 0xcf, 0xdb, 0x85, 0x58, 0x18, 0xfa, 0xb6, 0x62, 0x15, 0xcc, ++ 0xb0, 0x50, 0x8e, 0x89, 0xd8, 0x1f, 0x43, 0x96, 0x47, 0x4b, 0x92, 0xf9, ++ 0x52, 0xc9, 0x97, 0xb1, 0x2b, 0xdf, 0xc7, 0x4b, 0x5f, 0xec, 0x90, 0x36, ++ 0xf5, 0x99, 0x26, 0xf9, 0x3d, 0xec, 0x25, 0xee, 0x3b, 0xf6, 0x62, 0x9f, ++ 0x0b, 0xe7, 0xee, 0x4d, 0x3c, 0x29, 0x42, 0xd8, 0x62, 0x7f, 0x93, 0xb6, ++ 0x11, 0x31, 0xb2, 0x56, 0x21, 0x16, 0x02, 0x5c, 0x5e, 0x8a, 0xa3, 0xde, ++ 0x5c, 0x53, 0xd6, 0xba, 0x15, 0x9a, 0xb3, 0x13, 0xf1, 0xa2, 0xdc, 0x0a, ++ 0x5d, 0xb5, 0xf5, 0x5c, 0x6b, 0xd6, 0x72, 0x64, 0x15, 0xd8, 0x9f, 0x83, ++ 0x3d, 0x6c, 0x80, 0xa3, 0xdf, 0x2d, 0xe9, 0xf9, 0x0e, 0xec, 0x4f, 0x36, ++ 0x01, 0x67, 0x9b, 0x24, 0x92, 0x55, 0xcc, 0x5f, 0x75, 0xe7, 0xbb, 0x5d, ++ 0xbc, 0xc5, 0xfe, 0x36, 0x8d, 0x5b, 0xe4, 0x15, 0x77, 0xfe, 0x2e, 0x17, ++ 0x77, 0xf1, 0x01, 0xcc, 0x03, 0xff, 0xe0, 0xe4, 0x90, 0xa1, 0xe7, 0xf7, ++ 0xd2, 0x9e, 0x7e, 0xa7, 0x74, 0x2b, 0xb4, 0x6a, 0x3b, 0x92, 0x1b, 0x1d, ++ 0x9c, 0x1c, 0x34, 0x5c, 0x7c, 0xa7, 0xdc, 0x7d, 0xf7, 0xb9, 0xf8, 0x06, ++ 0x27, 0x93, 0x86, 0x8b, 0x6f, 0xa5, 0xa4, 0xf7, 0x4a, 0xbe, 0x44, 0xd8, ++ 0xc1, 0x49, 0xcb, 0xb8, 0x4f, 0xa6, 0xbb, 0x07, 0x27, 0xfb, 0x0c, 0xf5, ++ 0x99, 0x5d, 0x2e, 0x1f, 0x09, 0x9f, 0x86, 0x5d, 0x9a, 0x06, 0x9e, 0xab, ++ 0xe7, 0x07, 0xb2, 0x56, 0xf1, 0x81, 0x5d, 0xfa, 0x7c, 0x9e, 0xa9, 0xe7, ++ 0x1e, 0x20, 0x5d, 0x3c, 0x7b, 0x66, 0xf4, 0x8e, 0x73, 0x7f, 0xe5, 0xb6, ++ 0x7c, 0x76, 0x3a, 0x93, 0xe7, 0x49, 0x24, 0x9c, 0x0e, 0x8f, 0xce, 0x95, ++ 0x8e, 0x49, 0xb6, 0x1c, 0x97, 0xd9, 0x91, 0x56, 0x99, 0x36, 0xfb, 0xa7, ++ 0x0f, 0x0a, 0x7d, 0x4f, 0x64, 0x74, 0xc6, 0xbb, 0xc3, 0x9c, 0x18, 0x32, ++ 0x0b, 0x1e, 0x0f, 0xd6, 0x24, 0x62, 0x00, 0xbe, 0xbf, 0x16, 0x96, 0xe7, ++ 0xeb, 0x86, 0x34, 0x6b, 0xfb, 0x4c, 0x98, 0xeb, 0xd0, 0xc3, 0x67, 0xcb, ++ 0xd4, 0x63, 0xea, 0xac, 0x64, 0xaa, 0x5a, 0x67, 0x7d, 0x7b, 0x6d, 0xe3, ++ 0xdd, 0x16, 0x0a, 0x02, 0x73, 0x4c, 0x5b, 0x66, 0x55, 0x5a, 0x24, 0x33, ++ 0x25, 0x85, 0xaa, 0xbd, 0x65, 0x3f, 0xb1, 0x65, 0xd9, 0x80, 0x1e, 0x88, ++ 0x99, 0x4d, 0x71, 0x9e, 0xf0, 0x0d, 0xb0, 0xa6, 0x6b, 0x7b, 0x21, 0xd8, ++ 0xde, 0x4c, 0x8a, 0xb0, 0x52, 0xd0, 0xfe, 0xa2, 0x0e, 0x7d, 0xac, 0xdf, ++ 0xd7, 0xe1, 0xfa, 0xbb, 0x08, 0x6c, 0xb4, 0x1d, 0x76, 0xfe, 0x19, 0xd8, ++ 0x60, 0xaf, 0x91, 0x3d, 0xe7, 0x38, 0xf0, 0x3f, 0x51, 0x25, 0xb4, 0x41, ++ 0xd8, 0x7b, 0x9d, 0x6b, 0xed, 0x98, 0x17, 0x73, 0xd6, 0xee, 0x06, 0x8f, ++ 0x8e, 0x33, 0x69, 0xc7, 0xa5, 0x68, 0x77, 0x61, 0x5f, 0x93, 0xf4, 0x58, ++ 0xd4, 0x79, 0xda, 0xf5, 0x2e, 0x9c, 0x67, 0x70, 0xdc, 0x89, 0xf3, 0x3a, ++ 0x30, 0x17, 0x9b, 0xa5, 0x2d, 0xa7, 0xe8, 0xb7, 0x5c, 0x1f, 0x2a, 0x72, ++ 0x1d, 0xb4, 0x72, 0x8f, 0x86, 0x8b, 0xb4, 0xa4, 0x53, 0x72, 0xb3, 0xb4, ++ 0x57, 0xae, 0x45, 0x29, 0x03, 0xe0, 0x2c, 0xc3, 0x27, 0x46, 0x0d, 0xd0, ++ 0x4f, 0xba, 0xe9, 0x03, 0x77, 0x7b, 0x63, 0xe3, 0x7e, 0xf7, 0x0c, 0x31, ++ 0x43, 0xe9, 0x4e, 0xc9, 0xe9, 0x39, 0x51, 0x6a, 0x74, 0x97, 0xb7, 0xde, ++ 0x69, 0xec, 0x3f, 0xa7, 0xe4, 0xc0, 0xc3, 0xf0, 0x5b, 0x38, 0xeb, 0xaa, ++ 0xe5, 0x38, 0x57, 0xed, 0xf7, 0x61, 0xf7, 0x4a, 0x9a, 0xac, 0x6b, 0x9d, ++ 0xd2, 0x46, 0x7b, 0x36, 0x1a, 0x64, 0x18, 0x93, 0x53, 0x65, 0xee, 0x29, ++ 0x48, 0xd8, 0x22, 0x0c, 0xe1, 0xff, 0x05, 0x70, 0x21, 0x69, 0x81, 0x3d, ++ 0x6e, 0xd8, 0x51, 0xd2, 0xdb, 0xe5, 0xc2, 0x77, 0xe3, 0x0c, 0xd2, 0x4e, ++ 0xfb, 0x73, 0xb4, 0xfd, 0x65, 0x43, 0x2a, 0x33, 0xb1, 0x08, 0x6b, 0x1a, ++ 0xa1, 0xbc, 0xb3, 0xdd, 0x70, 0xff, 0x32, 0x3b, 0x54, 0x30, 0x95, 0xbe, ++ 0x6f, 0x91, 0x5c, 0xe9, 0x7e, 0x99, 0xb3, 0x71, 0x9e, 0x15, 0x06, 0xcd, ++ 0xf4, 0x35, 0x03, 0x85, 0x90, 0x82, 0x95, 0xf5, 0x50, 0x56, 0x3e, 0xad, ++ 0xff, 0x8c, 0xf3, 0x0a, 0x46, 0xd8, 0xe2, 0x19, 0xbf, 0xe5, 0xc9, 0x87, ++ 0xba, 0x67, 0x4b, 0xb6, 0xd4, 0xce, 0x31, 0xe8, 0x68, 0xd3, 0x74, 0x84, ++ 0xd2, 0xfa, 0xee, 0x0c, 0x95, 0xf6, 0x63, 0x00, 0x41, 0xef, 0xc0, 0x03, ++ 0x3e, 0xb8, 0xd7, 0xc2, 0xde, 0x08, 0x68, 0xec, 0x68, 0xa0, 0xbf, 0x8d, ++ 0xf0, 0x90, 0x55, 0xc4, 0x3b, 0x43, 0xf3, 0x6d, 0xb8, 0x7c, 0xfb, 0xb2, ++ 0x7a, 0x1d, 0xb2, 0xfa, 0xc8, 0x39, 0x30, 0x46, 0x1c, 0x29, 0xe0, 0x80, ++ 0xdc, 0x4d, 0xfa, 0x2c, 0xfa, 0x29, 0x73, 0x0b, 0x17, 0x6c, 0x41, 0x85, ++ 0xd2, 0xed, 0x92, 0x33, 0x75, 0x1c, 0x00, 0xec, 0xb8, 0x68, 0x3f, 0x6f, ++ 0x91, 0x47, 0x6f, 0x6c, 0x25, 0xb4, 0xde, 0xe4, 0x2b, 0x8c, 0x05, 0x45, ++ 0xd0, 0xb6, 0x9e, 0x50, 0x9a, 0xb5, 0x76, 0xc8, 0x5c, 0x22, 0x4d, 0xe9, ++ 0xb7, 0x64, 0xb5, 0xa4, 0xf6, 0x34, 0x4b, 0x97, 0x4c, 0x41, 0x46, 0xd5, ++ 0x71, 0xc4, 0xb0, 0x91, 0x76, 0x09, 0x3d, 0xc4, 0x58, 0x10, 0x03, 0xad, ++ 0xeb, 0x09, 0x53, 0x6e, 0x39, 0x6a, 0x10, 0xfb, 0x47, 0x70, 0x0f, 0x87, ++ 0x79, 0xa7, 0xca, 0x83, 0x23, 0x4c, 0x88, 0x32, 0xef, 0x69, 0x16, 0xe2, ++ 0xe6, 0xda, 0x70, 0xcc, 0x14, 0xce, 0x23, 0x5e, 0x4e, 0x71, 0x2f, 0xf9, ++ 0x73, 0xf7, 0x7c, 0x92, 0x3f, 0x7f, 0x9d, 0x32, 0xa3, 0xec, 0xa0, 0x63, ++ 0xa0, 0xa9, 0x1b, 0x72, 0x1b, 0x5d, 0x80, 0x4f, 0xb4, 0x1f, 0xd7, 0x3a, ++ 0xdc, 0x37, 0x76, 0xaf, 0x5c, 0x83, 0xdd, 0xc5, 0x95, 0x18, 0x55, 0x7b, ++ 0xaf, 0x9e, 0x53, 0x96, 0x2f, 0x4f, 0xca, 0x60, 0xf7, 0x36, 0x19, 0x10, ++ 0xe7, 0xce, 0x72, 0x38, 0x52, 0x21, 0x0d, 0x2e, 0x2d, 0x73, 0xd6, 0x7a, ++ 0x22, 0x2c, 0x8d, 0xf4, 0x7c, 0xec, 0x28, 0xcb, 0x2a, 0xf4, 0x29, 0xe2, ++ 0x6f, 0x16, 0xb5, 0x27, 0x2c, 0x4f, 0x8c, 0x19, 0x12, 0x3f, 0xa4, 0xe4, ++ 0xd0, 0xc3, 0xc4, 0xf9, 0x13, 0xf2, 0x38, 0x9e, 0xe1, 0xfa, 0x18, 0x75, ++ 0x21, 0x8c, 0x5e, 0xf3, 0x87, 0xb9, 0x46, 0x5d, 0x7f, 0xdd, 0xd3, 0xf5, ++ 0x8f, 0x9c, 0x43, 0x63, 0x61, 0x0f, 0x36, 0xd2, 0x00, 0x2b, 0xb8, 0xef, ++ 0x9d, 0x60, 0x09, 0xd3, 0xa8, 0x17, 0x84, 0x2d, 0xec, 0x00, 0x8b, 0xe0, ++ 0xf4, 0x15, 0xda, 0x50, 0xb7, 0xe7, 0x33, 0x7c, 0x9b, 0xe2, 0x39, 0xec, ++ 0x77, 0xb2, 0x3f, 0xee, 0xe3, 0x7e, 0xc2, 0x6f, 0x8f, 0xa7, 0xb8, 0x06, ++ 0xd9, 0x31, 0xa6, 0xa2, 0x4d, 0xe2, 0x5b, 0xc1, 0xff, 0x34, 0xc6, 0x56, ++ 0xce, 0x99, 0x18, 0x4f, 0xa0, 0xb7, 0x24, 0x5f, 0xa3, 0x1d, 0x71, 0x3f, ++ 0x63, 0xed, 0xbb, 0x9e, 0xef, 0x6c, 0x9f, 0x0e, 0xa7, 0xa3, 0xf0, 0x9d, ++ 0x32, 0x55, 0x2c, 0x9d, 0x44, 0x3e, 0x24, 0x85, 0x7b, 0xd2, 0xd4, 0x8b, ++ 0xf6, 0x71, 0xf8, 0xc6, 0xa9, 0x62, 0x8d, 0x39, 0x11, 0xdc, 0x17, 0xf6, ++ 0x21, 0x3e, 0x47, 0xd4, 0x42, 0xa4, 0x70, 0x6f, 0x9a, 0x3e, 0x39, 0x2e, ++ 0xf1, 0xda, 0x7b, 0xc8, 0x39, 0x4c, 0xc9, 0x6a, 0x1d, 0xfb, 0xf6, 0x5e, ++ 0xd2, 0x5c, 0x44, 0xfe, 0x10, 0x4e, 0x4b, 0x58, 0xa5, 0x9b, 0x23, 0xb3, ++ 0xa9, 0x76, 0xe4, 0x59, 0x93, 0x7b, 0xd5, 0xda, 0xc1, 0xbd, 0xa1, 0xb5, ++ 0x3d, 0xd3, 0x4d, 0xe9, 0xc2, 0x5e, 0xb5, 0x20, 0xb2, 0x5c, 0x12, 0x85, ++ 0x9c, 0x26, 0x76, 0x44, 0x30, 0x5e, 0xfb, 0xf2, 0x97, 0x55, 0x3a, 0x24, ++ 0xf9, 0xa8, 0x9c, 0x58, 0x49, 0x85, 0x99, 0x3f, 0xc6, 0xa7, 0xe4, 0x04, ++ 0x72, 0xc6, 0x67, 0x64, 0xb6, 0x04, 0xba, 0x34, 0xdf, 0x31, 0xf0, 0xdb, ++ 0x0b, 0xdc, 0xa4, 0x3d, 0x0a, 0xdf, 0xea, 0xd2, 0x0e, 0x9a, 0x33, 0x39, ++ 0xe6, 0x48, 0x29, 0xc6, 0x94, 0xf7, 0xa0, 0x27, 0xb4, 0x93, 0x9f, 0xcb, ++ 0xaa, 0xd5, 0x2a, 0x79, 0xd7, 0x2f, 0x68, 0x3d, 0x0d, 0xa7, 0xdf, 0xf5, ++ 0xd6, 0xae, 0x63, 0x8d, 0xfa, 0xba, 0xab, 0xe1, 0xee, 0xbe, 0xa5, 0xf3, ++ 0x9c, 0xab, 0x36, 0xbf, 0x09, 0xfb, 0x83, 0x51, 0x17, 0xf6, 0xcd, 0xd1, ++ 0x55, 0xeb, 0x2b, 0x5d, 0xd2, 0x86, 0x73, 0xca, 0x3c, 0x27, 0x4a, 0xdf, ++ 0x8a, 0xf5, 0x6b, 0x1e, 0xae, 0x9f, 0x02, 0x57, 0x3b, 0xe9, 0x46, 0x0b, ++ 0x63, 0x1d, 0xf4, 0x21, 0xdf, 0xc9, 0x6f, 0xf9, 0x18, 0xc2, 0xbe, 0xe6, ++ 0xe1, 0xfa, 0x5e, 0x03, 0x2e, 0xae, 0xb1, 0xe7, 0x99, 0x38, 0xbb, 0x8d, ++ 0xbc, 0x91, 0x1f, 0xde, 0x01, 0xef, 0x23, 0x69, 0x4c, 0xc1, 0xa7, 0x4f, ++ 0xd5, 0x75, 0x5e, 0x67, 0xe4, 0xca, 0xc8, 0xb7, 0xea, 0x2f, 0x82, 0x46, ++ 0xe4, 0x61, 0xf5, 0x01, 0x2f, 0xd7, 0xa6, 0xad, 0xac, 0x6b, 0x9f, 0x45, ++ 0x7f, 0x53, 0xd4, 0xf6, 0x74, 0x05, 0x63, 0x9d, 0x67, 0xe3, 0x6e, 0xae, ++ 0x48, 0x5f, 0xad, 0xdc, 0xe5, 0xfe, 0xbf, 0x6d, 0x53, 0x42, 0xfa, 0x3e, ++ 0x19, 0xd7, 0xa8, 0x67, 0x77, 0xc3, 0x9f, 0x3b, 0x1f, 0x30, 0xbe, 0x4c, ++ 0x31, 0xf6, 0x4c, 0x31, 0x66, 0x18, 0x9e, 0x1f, 0x8c, 0x37, 0xe0, 0x88, ++ 0x03, 0xc7, 0x79, 0x4f, 0x6f, 0x4f, 0x7b, 0xb8, 0xfc, 0xdc, 0xd3, 0xf7, ++ 0xa5, 0x2f, 0xdd, 0x73, 0xe7, 0xba, 0x61, 0xba, 0xe3, 0x66, 0xed, 0x87, ++ 0x61, 0xf7, 0xa0, 0x3f, 0x3e, 0xad, 0xa0, 0x5f, 0xb9, 0x9a, 0x7b, 0x1f, ++ 0xb0, 0x71, 0xe8, 0x1e, 0x3f, 0xfd, 0xbb, 0x75, 0x73, 0x6f, 0x57, 0x06, ++ 0xbc, 0xd3, 0x0c, 0xf9, 0xce, 0x84, 0x49, 0x4b, 0x7d, 0x12, 0xfb, 0xe5, ++ 0x18, 0x63, 0x62, 0x1e, 0x7c, 0x1c, 0x31, 0x87, 0xcd, 0x59, 0xe2, 0x8e, ++ 0x0a, 0x70, 0x22, 0x8f, 0x4c, 0xb7, 0x78, 0xf7, 0xfc, 0x7d, 0x9e, 0x0f, ++ 0xdc, 0xbb, 0x38, 0x46, 0xff, 0x7d, 0x8f, 0x9e, 0x1b, 0x9d, 0x2e, 0x3d, ++ 0xfe, 0xfa, 0x80, 0x79, 0xe7, 0x78, 0x75, 0xaf, 0x27, 0x4f, 0x7c, 0x3f, ++ 0xe3, 0xd1, 0xc5, 0xbb, 0x69, 0xa4, 0x89, 0xf7, 0xf2, 0x5f, 0xc0, 0xa3, ++ 0xf3, 0x8c, 0x82, 0x4a, 0x23, 0x6f, 0x49, 0x31, 0x56, 0xc1, 0xe6, 0xc5, ++ 0xc2, 0x9d, 0x24, 0xec, 0x69, 0xec, 0x7a, 0xb7, 0xc4, 0x7b, 0xbe, 0x05, ++ 0x1f, 0xcd, 0x7b, 0xff, 0x50, 0xe6, 0x4a, 0xfd, 0x76, 0xb3, 0x41, 0x7b, ++ 0x4d, 0x24, 0xcf, 0xcb, 0xb0, 0x7d, 0x5e, 0xe7, 0x4f, 0x89, 0xf8, 0x29, ++ 0xa1, 0x6c, 0x6f, 0xc9, 0x80, 0xce, 0x6b, 0x3e, 0x14, 0x0b, 0x72, 0x99, ++ 0x2a, 0xc3, 0xc6, 0xc6, 0xfe, 0xcd, 0xd1, 0xf9, 0x28, 0xf2, 0xa5, 0x1b, ++ 0x3b, 0xe0, 0x7a, 0x53, 0xe3, 0x21, 0xbe, 0x46, 0x5c, 0x86, 0xb4, 0x8c, ++ 0xf9, 0xf8, 0x2c, 0x99, 0xaf, 0xfb, 0x38, 0xc3, 0xf0, 0xc3, 0xf0, 0x01, ++ 0x63, 0xbf, 0xe1, 0xe9, 0x0b, 0xbf, 0x7f, 0xe8, 0x30, 0x07, 0x52, 0xe9, ++ 0x3f, 0xf7, 0xe6, 0xae, 0x50, 0x06, 0x18, 0xfb, 0x72, 0x7f, 0xd1, 0xf3, ++ 0x39, 0x05, 0x23, 0x53, 0xa7, 0x0c, 0xa8, 0x2b, 0xb8, 0x7f, 0xad, 0x9f, ++ 0xb0, 0x99, 0xf2, 0x17, 0x10, 0x1f, 0xbb, 0xdd, 0xbc, 0x01, 0xb5, 0x55, ++ 0xa6, 0xce, 0xb9, 0xf5, 0x96, 0xac, 0xdd, 0xe4, 0xd9, 0xd2, 0x41, 0xcc, ++ 0x4d, 0xe1, 0x8f, 0xb2, 0x23, 0xcc, 0x61, 0x7c, 0x67, 0x3c, 0x38, 0x19, ++ 0xcf, 0x22, 0x66, 0x65, 0x0e, 0x4f, 0x60, 0x6c, 0x78, 0x35, 0x96, 0x96, ++ 0x7b, 0x05, 0x39, 0x0a, 0xe4, 0x39, 0x00, 0x7e, 0xe2, 0x32, 0x51, 0xc7, ++ 0x9d, 0x6f, 0xf9, 0xb3, 0x2d, 0x98, 0xc2, 0x6d, 0x18, 0xd7, 0xf7, 0x4d, ++ 0xd4, 0x7f, 0xec, 0xd0, 0x1f, 0xfc, 0xad, 0xb6, 0x97, 0x78, 0x43, 0xde, ++ 0x97, 0x31, 0x9e, 0x28, 0x4f, 0x1a, 0x87, 0xca, 0xdc, 0xa3, 0x5e, 0xea, ++ 0x11, 0x2b, 0x9e, 0x55, 0xc8, 0x51, 0xc7, 0x3a, 0x71, 0xe6, 0x29, 0xe8, ++ 0x46, 0xc1, 0x98, 0x1a, 0xea, 0x92, 0x7c, 0xb2, 0x07, 0x34, 0x3f, 0x82, ++ 0x1e, 0xb1, 0xc3, 0xfa, 0x35, 0xcc, 0x43, 0x8f, 0x92, 0xb4, 0x8f, 0x56, ++ 0x5d, 0x57, 0x4e, 0xeb, 0xb8, 0x35, 0xe0, 0xe9, 0xd6, 0x3f, 0x99, 0xae, ++ 0x2e, 0x3d, 0x8d, 0xf1, 0x2e, 0xcc, 0xff, 0x26, 0x7a, 0xc4, 0xac, 0x31, ++ 0x7f, 0x9e, 0x36, 0x38, 0x8e, 0xf9, 0xcf, 0x01, 0xc7, 0x9f, 0xe0, 0xfb, ++ 0x7e, 0x7c, 0xff, 0xd1, 0xb6, 0xbd, 0xdf, 0xe0, 0xd9, 0x98, 0xcf, 0x6e, ++ 0x9b, 0xf7, 0xfd, 0xb7, 0x8e, 0x93, 0xd2, 0xbd, 0x06, 0xc6, 0xd7, 0x22, ++ 0xb2, 0xfb, 0x7c, 0x9b, 0xa8, 0xaa, 0xeb, 0xc3, 0x55, 0xd5, 0x94, 0x9e, ++ 0xf3, 0xf4, 0xdf, 0x3f, 0xc2, 0x1e, 0x4b, 0xd4, 0x1a, 0x2e, 0x8d, 0x77, ++ 0xab, 0x6d, 0xf4, 0x99, 0xe3, 0x7d, 0x4b, 0xec, 0x0b, 0xc7, 0x47, 0x6b, ++ 0x84, 0xe1, 0xf7, 0x89, 0xe3, 0x7d, 0xb5, 0x9f, 0x00, 0x16, 0x72, 0x29, ++ 0xfb, 0xf8, 0x09, 0xff, 0xda, 0xb6, 0x33, 0xb5, 0x6c, 0x71, 0x26, 0xed, ++ 0xfe, 0x99, 0xe3, 0xd9, 0x0a, 0xf3, 0x83, 0x44, 0x4c, 0x74, 0x1e, 0x5e, ++ 0x38, 0x3e, 0x53, 0x0a, 0x4b, 0x48, 0xd3, 0xe2, 0xaf, 0x73, 0x8d, 0xf7, ++ 0xb0, 0x13, 0x6d, 0xa4, 0xab, 0x11, 0x0f, 0xe3, 0x0c, 0xf1, 0x9c, 0x00, ++ 0x9e, 0x24, 0xf0, 0x30, 0xde, 0xb8, 0xf4, 0xc6, 0x97, 0x76, 0xa2, 0x8d, ++ 0xb8, 0x78, 0x96, 0x8f, 0xaf, 0x47, 0xd4, 0xf9, 0xb7, 0x49, 0xaf, 0xc9, ++ 0x9c, 0xd6, 0xf5, 0x35, 0x4d, 0x92, 0x3f, 0x8b, 0xdc, 0xc6, 0x1e, 0xf3, ++ 0xc6, 0x77, 0x9b, 0xac, 0xb7, 0xe3, 0x8a, 0xf3, 0xec, 0xb1, 0x96, 0x8a, ++ 0x63, 0x0e, 0xe3, 0x65, 0x1f, 0x56, 0x79, 0xb0, 0x1d, 0x0d, 0x7c, 0x37, ++ 0x79, 0xb2, 0xe6, 0x99, 0x7e, 0xdd, 0xd9, 0x48, 0x0b, 0x40, 0x71, 0x0f, ++ 0xdd, 0x5b, 0xf7, 0xe0, 0xf3, 0x89, 0x85, 0x35, 0xd2, 0x96, 0x04, 0xaf, ++ 0x3e, 0x6d, 0x9f, 0xf6, 0xfe, 0xb8, 0x37, 0x89, 0x3f, 0xff, 0x3c, 0x5f, ++ 0x06, 0xa4, 0x8b, 0x3d, 0x74, 0xf9, 0x13, 0x75, 0x73, 0x12, 0x76, 0xc7, ++ 0x37, 0x10, 0xc7, 0x59, 0xb5, 0x29, 0xfb, 0x16, 0xdc, 0xbb, 0xf6, 0xb1, ++ 0xa8, 0x21, 0x14, 0x73, 0xb9, 0x38, 0xeb, 0xd5, 0xa3, 0xb2, 0x09, 0x5c, ++ 0x19, 0xd4, 0x94, 0x6e, 0x5d, 0x34, 0x0d, 0xff, 0xb8, 0x0e, 0xfd, 0xbc, ++ 0x6a, 0xf1, 0x2d, 0x26, 0xcc, 0x78, 0x27, 0xc5, 0xda, 0xcf, 0x01, 0xc3, ++ 0x3c, 0xea, 0xf6, 0x3b, 0xcb, 0x12, 0x60, 0x96, 0xb1, 0x76, 0xca, 0xf5, ++ 0xcb, 0xf4, 0xed, 0xc8, 0xa9, 0x50, 0xc3, 0x58, 0xff, 0xe3, 0xe4, 0xa3, ++ 0x8d, 0xb0, 0x3b, 0xbd, 0x83, 0x20, 0xe6, 0x2c, 0x26, 0xe6, 0x97, 0xe0, ++ 0xc3, 0x2b, 0x96, 0xda, 0xad, 0xb4, 0x46, 0x26, 0x2a, 0xf0, 0x49, 0xa8, ++ 0x78, 0x13, 0xf1, 0x25, 0x79, 0x5f, 0xdf, 0x43, 0x93, 0x35, 0x6c, 0xf6, ++ 0xa8, 0xaf, 0x52, 0xaf, 0x34, 0xe5, 0xa1, 0x33, 0x88, 0xcb, 0x23, 0x4f, ++ 0x20, 0xe6, 0x40, 0x5e, 0x67, 0x0a, 0xa8, 0xe2, 0xa9, 0x23, 0x3f, 0xf8, ++ 0x83, 0x19, 0xcb, 0xcd, 0xff, 0x75, 0x3c, 0x13, 0x97, 0xc7, 0xd0, 0x99, ++ 0x76, 0xed, 0x67, 0xf2, 0xda, 0xdf, 0xf4, 0x9b, 0x53, 0xaa, 0x0d, 0x39, ++ 0x06, 0x12, 0x4f, 0x64, 0x38, 0xe6, 0xa0, 0x48, 0x1f, 0xf3, 0x4e, 0xf8, ++ 0xe1, 0xbe, 0x35, 0x78, 0xb7, 0x33, 0x84, 0x57, 0x12, 0x3e, 0x13, 0x92, ++ 0xa6, 0x33, 0x7c, 0x0b, 0x91, 0x3d, 0xa8, 0xc3, 0x88, 0xb3, 0x2f, 0x8c, ++ 0x7e, 0x02, 0x7f, 0xfb, 0x90, 0x5f, 0x99, 0xc8, 0x8d, 0x77, 0x80, 0x07, ++ 0x2c, 0xf7, 0xec, 0x04, 0xdf, 0xd5, 0x2d, 0x6d, 0x11, 0xec, 0x21, 0x3c, ++ 0xf2, 0x43, 0x6b, 0x0f, 0xe8, 0x71, 0xcf, 0x27, 0x8e, 0xf0, 0x19, 0x91, ++ 0xfe, 0x05, 0xe9, 0x51, 0x7a, 0x4f, 0x58, 0x66, 0x52, 0x5c, 0x6b, 0x07, ++ 0x3c, 0xf7, 0x61, 0x4d, 0xef, 0x73, 0xdf, 0x94, 0xf2, 0xb7, 0xe9, 0xc6, ++ 0x9c, 0x81, 0x6f, 0xe4, 0x53, 0x29, 0x53, 0xfa, 0xab, 0x2e, 0x6c, 0xdf, ++ 0xda, 0x53, 0xdd, 0x7c, 0x97, 0x52, 0x96, 0x4b, 0x9b, 0x42, 0xee, 0x9b, ++ 0x87, 0x54, 0xc3, 0x83, 0x7c, 0x9b, 0x21, 0x0c, 0xeb, 0xd9, 0x2e, 0x0d, ++ 0x63, 0x0e, 0x52, 0x7e, 0xee, 0x9c, 0x52, 0xff, 0xd7, 0x9b, 0x4b, 0x63, ++ 0x4e, 0xa1, 0x6d, 0x05, 0xfb, 0xbf, 0xa9, 0x6d, 0x45, 0x54, 0xdc, 0xb3, ++ 0x15, 0x8c, 0x97, 0x39, 0xf6, 0x63, 0xf1, 0xf1, 0x7b, 0x5c, 0x7f, 0xef, ++ 0xc8, 0xac, 0xcd, 0xf7, 0x0b, 0x47, 0xae, 0xda, 0x05, 0xe3, 0xc0, 0x1d, ++ 0x79, 0x66, 0x52, 0xc7, 0xe7, 0x19, 0xc8, 0x7e, 0xb3, 0xa6, 0x6b, 0x35, ++ 0xb9, 0x56, 0x8b, 0xc8, 0x3b, 0x2b, 0x6d, 0xb2, 0xb9, 0xe4, 0xea, 0xfc, ++ 0xe6, 0x12, 0xf5, 0xdc, 0x94, 0x9f, 0xad, 0x58, 0x58, 0x4b, 0xe2, 0xaf, ++ 0x47, 0x6e, 0xac, 0xdc, 0x99, 0x77, 0x5e, 0xae, 0x3f, 0x0a, 0x5a, 0x7a, ++ 0x24, 0x64, 0x39, 0xba, 0xee, 0xca, 0x21, 0xf6, 0x15, 0x64, 0x42, 0xf2, ++ 0xe5, 0x7e, 0xd4, 0x7e, 0x08, 0xce, 0x61, 0xc6, 0x20, 0xdc, 0x7f, 0xf9, ++ 0xf3, 0xc8, 0x4d, 0x12, 0x30, 0x9e, 0x7e, 0xfd, 0xa6, 0xf8, 0xc5, 0x70, ++ 0x8f, 0x34, 0x5b, 0xdf, 0xec, 0x76, 0x63, 0x95, 0xe9, 0xd6, 0xa7, 0x96, ++ 0x1f, 0xaf, 0xdf, 0x04, 0xee, 0x11, 0xe8, 0x29, 0x75, 0xd3, 0x86, 0xce, ++ 0x9a, 0xb2, 0x3a, 0x94, 0xa8, 0x14, 0x84, 0xfe, 0x21, 0xc5, 0x7c, 0x11, ++ 0xfb, 0x92, 0x90, 0x47, 0xab, 0xce, 0x85, 0x32, 0x0a, 0x77, 0xbb, 0x30, ++ 0x27, 0xf9, 0xfa, 0xef, 0x63, 0x3e, 0x23, 0xd3, 0xf5, 0x71, 0x9c, 0x75, ++ 0x1a, 0x7a, 0xfb, 0x60, 0x8f, 0xb4, 0xf1, 0x9c, 0x14, 0x68, 0x7c, 0x44, ++ 0x66, 0xce, 0xce, 0xc9, 0x91, 0x32, 0xe9, 0xe4, 0x1b, 0x63, 0x22, 0x99, ++ 0x93, 0xe1, 0xf8, 0x0a, 0x72, 0x27, 0xd7, 0x1e, 0xd3, 0x32, 0x73, 0x0e, ++ 0x38, 0xca, 0xac, 0xff, 0xfb, 0xa1, 0x37, 0xc3, 0xba, 0x7e, 0x99, 0xd6, ++ 0x7e, 0x87, 0xf3, 0x6f, 0xe3, 0x9e, 0xfa, 0x0b, 0xfb, 0x00, 0x97, 0x47, ++ 0xad, 0x33, 0x85, 0x7c, 0x79, 0xb9, 0x8c, 0x3a, 0xcf, 0x0e, 0x31, 0xf7, ++ 0x52, 0xea, 0xa1, 0x5e, 0xa9, 0x96, 0x87, 0x4d, 0xa5, 0x98, 0x53, 0xf1, ++ 0x2e, 0xb8, 0x46, 0xfb, 0x8e, 0xa9, 0xb0, 0xd5, 0x2b, 0x2b, 0xe5, 0x02, ++ 0xea, 0x65, 0xe5, 0xbd, 0x67, 0x14, 0xc4, 0xb4, 0x5c, 0xbf, 0xa7, 0x6b, ++ 0x1b, 0xe6, 0x9f, 0xf5, 0x2f, 0x80, 0xc6, 0x0c, 0x2e, 0xf3, 0x24, 0xe8, ++ 0xc3, 0xf7, 0x32, 0x74, 0x7c, 0x81, 0x39, 0x5c, 0x06, 0x6b, 0x69, 0x39, ++ 0x76, 0x61, 0x0a, 0x34, 0x74, 0x4a, 0xff, 0x9f, 0xd1, 0xc6, 0x9e, 0xc4, ++ 0x1c, 0xc7, 0x09, 0xe8, 0xeb, 0xd7, 0xf1, 0x4d, 0xd8, 0x18, 0x7a, 0xca, ++ 0xa1, 0x17, 0xbd, 0x09, 0x5a, 0x58, 0x07, 0x43, 0xfe, 0x87, 0xe3, 0x52, ++ 0x3d, 0xfb, 0xb0, 0x4c, 0x2f, 0x3f, 0x0c, 0xfc, 0xff, 0x8a, 0xba, 0x00, ++ 0xf1, 0x6d, 0x99, 0x67, 0x31, 0xff, 0xe3, 0x39, 0x10, 0x10, 0x6d, 0x63, ++ 0x81, 0xf3, 0xec, 0x0f, 0x62, 0x3f, 0x6a, 0x8c, 0x72, 0x46, 0x66, 0xca, ++ 0x3c, 0x0b, 0x77, 0x87, 0x7c, 0x2a, 0x7f, 0x76, 0xca, 0xbb, 0xe3, 0x1e, ++ 0xc9, 0x45, 0x0b, 0xac, 0x2f, 0x10, 0x27, 0x96, 0x46, 0xb3, 0xa5, 0x84, ++ 0x99, 0x55, 0xc4, 0x95, 0x14, 0xc6, 0x06, 0x77, 0x2e, 0x22, 0xd6, 0x02, ++ 0x6a, 0xda, 0x34, 0xd7, 0x4e, 0x7a, 0x6f, 0x06, 0xc4, 0xf5, 0x63, 0x99, ++ 0x80, 0x8e, 0xf5, 0x2f, 0x8c, 0x20, 0x17, 0xfe, 0x29, 0x72, 0xc9, 0xb8, ++ 0x27, 0x83, 0x71, 0x4f, 0x37, 0xda, 0x1a, 0x74, 0x02, 0xf7, 0x5c, 0xc6, ++ 0xdd, 0x97, 0xa1, 0x07, 0xf0, 0xd5, 0xaf, 0x6e, 0xe9, 0xc7, 0x78, 0x43, ++ 0x8e, 0xd9, 0x21, 0xff, 0x50, 0x49, 0x24, 0xd7, 0xa1, 0x3f, 0x37, 0x50, ++ 0x0b, 0xac, 0xa3, 0x3e, 0xdc, 0xb4, 0x23, 0xa8, 0x4b, 0x0e, 0x83, 0x7e, ++ 0xe6, 0x94, 0x1c, 0xc7, 0x74, 0xae, 0xd3, 0x62, 0x3d, 0x7f, 0x8f, 0x7e, ++ 0xd7, 0x95, 0xaf, 0xf6, 0xb0, 0xa6, 0x64, 0x3d, 0xce, 0x37, 0xe9, 0x77, ++ 0x70, 0x8f, 0xeb, 0x26, 0xd7, 0xfd, 0x7d, 0xac, 0x05, 0x7c, 0xfd, 0x21, ++ 0x2d, 0xd4, 0x1f, 0xee, 0x21, 0x4c, 0x8f, 0xb6, 0x93, 0xbc, 0xc6, 0x47, ++ 0x9d, 0xfd, 0x9b, 0x6e, 0xd7, 0xce, 0x74, 0x9e, 0x65, 0x5e, 0x13, 0x5f, ++ 0x7f, 0x3f, 0x74, 0x58, 0xd7, 0x65, 0x87, 0xe0, 0xbb, 0xeb, 0x8e, 0xbc, ++ 0x60, 0xdf, 0x69, 0x77, 0xfb, 0xcb, 0xbe, 0x9c, 0x28, 0xc7, 0xc3, 0x72, ++ 0xaa, 0x9e, 0x80, 0x4d, 0x50, 0x86, 0x56, 0x83, 0x0c, 0x45, 0xfe, 0xaa, ++ 0x2c, 0xf2, 0x4a, 0x99, 0x6b, 0x5a, 0x86, 0xb1, 0x6c, 0xa8, 0x8d, 0xef, ++ 0xea, 0xd0, 0xcb, 0xb7, 0xe5, 0xc8, 0xa2, 0xc8, 0x05, 0xac, 0xaf, 0x96, ++ 0x69, 0xab, 0x23, 0xc8, 0x5f, 0x77, 0x49, 0x75, 0x09, 0x35, 0x59, 0x59, ++ 0xa6, 0xb3, 0x9f, 0x63, 0xbc, 0x89, 0xc8, 0xa6, 0x7e, 0x8f, 0x15, 0x19, ++ 0xbc, 0x18, 0x96, 0xf0, 0x45, 0x14, 0x7f, 0x90, 0xfd, 0xa5, 0x21, 0xff, ++ 0x7d, 0xd6, 0xb5, 0xf9, 0x62, 0x09, 0x7b, 0xcb, 0xfd, 0xda, 0x4f, 0x16, ++ 0x6b, 0x33, 0x92, 0xaf, 0xf0, 0x2c, 0xf4, 0x4b, 0x71, 0xac, 0xa5, 0x64, ++ 0xf6, 0xec, 0x88, 0x3c, 0x8b, 0x33, 0x50, 0xff, 0xe1, 0x8c, 0x09, 0x29, ++ 0x5c, 0xc0, 0x7c, 0xed, 0xba, 0x2c, 0xad, 0xcc, 0x48, 0xb5, 0x72, 0xb9, ++ 0xe1, 0xdd, 0x1d, 0xe3, 0xa5, 0xc6, 0x5a, 0xf6, 0x30, 0xeb, 0x19, 0xd4, ++ 0xaa, 0x16, 0xc6, 0x90, 0x59, 0x6d, 0x76, 0xfa, 0xce, 0xf7, 0xe2, 0xc6, ++ 0x1a, 0x76, 0x52, 0xe6, 0xcb, 0x29, 0x29, 0x9e, 0x1d, 0xd1, 0x6f, 0x0a, ++ 0x2d, 0xe9, 0xca, 0xd3, 0x37, 0x11, 0x2b, 0x26, 0xf5, 0x7b, 0xf1, 0x2d, ++ 0x79, 0xcc, 0x9e, 0x97, 0xa3, 0xd6, 0x41, 0x39, 0x85, 0xfc, 0xfa, 0x4b, ++ 0x76, 0xab, 0xc4, 0xbb, 0x79, 0x8f, 0xa0, 0xd7, 0x62, 0x0d, 0xea, 0xc8, ++ 0x84, 0xfd, 0xa0, 0xf9, 0x3c, 0x24, 0xfb, 0x4e, 0x8d, 0x71, 0xf2, 0xbf, ++ 0x9d, 0x0c, 0xe2, 0xde, 0x4d, 0xd4, 0x8e, 0x19, 0x0d, 0x67, 0xb8, 0x70, ++ 0x15, 0xc2, 0x0d, 0x9b, 0x2f, 0x10, 0x6e, 0xc9, 0xf0, 0xe0, 0x0c, 0xc0, ++ 0x85, 0x64, 0xc3, 0x0e, 0x43, 0x47, 0x26, 0xc1, 0x27, 0x7c, 0xfc, 0x68, ++ 0x87, 0x97, 0x07, 0xb7, 0x22, 0xb6, 0xde, 0xde, 0xff, 0x86, 0xb7, 0xff, ++ 0x59, 0x6f, 0xff, 0xd5, 0xad, 0xfd, 0x7e, 0x7c, 0xfd, 0x85, 0x23, 0x0d, ++ 0x74, 0xbd, 0x51, 0x72, 0xe1, 0xe7, 0x3d, 0xba, 0xae, 0x6e, 0xd1, 0xe5, ++ 0xc3, 0x43, 0x9e, 0x9a, 0x67, 0xfa, 0x66, 0xfa, 0xe8, 0x7e, 0xc8, 0xd1, ++ 0x91, 0x9c, 0x0d, 0xdb, 0x28, 0x27, 0xc6, 0x0b, 0xfa, 0x2d, 0x4d, 0xc9, ++ 0x7a, 0x74, 0x5e, 0x26, 0xad, 0xc4, 0xf8, 0xac, 0x84, 0xa0, 0xcb, 0xf4, ++ 0x2d, 0x21, 0xa9, 0xd2, 0xe7, 0xa0, 0xcf, 0xdb, 0x3b, 0xd3, 0xfa, 0x4e, ++ 0x03, 0xad, 0xa1, 0x97, 0x49, 0xa3, 0x4b, 0x6b, 0x64, 0xe0, 0x36, 0xad, ++ 0x2e, 0xbc, 0x4b, 0xeb, 0x3b, 0xa5, 0x06, 0xf8, 0x8b, 0x61, 0x0f, 0x3e, ++ 0xdc, 0x00, 0x4f, 0x7d, 0x66, 0x5e, 0x41, 0x7d, 0x26, 0x6d, 0x9f, 0x85, ++ 0x6d, 0x48, 0xa4, 0x35, 0x5d, 0x39, 0xfe, 0xc0, 0x80, 0x23, 0x11, 0xe4, ++ 0x1b, 0xcd, 0x58, 0xdb, 0xac, 0x30, 0x17, 0x51, 0x7d, 0xcd, 0x32, 0x08, ++ 0x9d, 0xe5, 0xdd, 0xb9, 0x6f, 0x82, 0x8f, 0xe9, 0x9c, 0xc0, 0x91, 0xa3, ++ 0x36, 0x69, 0x79, 0xdf, 0x79, 0x25, 0x3a, 0x68, 0x17, 0x65, 0xc8, 0x6c, ++ 0xc6, 0xf9, 0xd5, 0xba, 0xc6, 0x99, 0x24, 0x2d, 0xe7, 0x87, 0xfa, 0xcd, ++ 0xbf, 0x07, 0x9f, 0x13, 0x15, 0x43, 0xaa, 0x56, 0x22, 0x76, 0x09, 0x38, ++ 0xf6, 0xe1, 0x6e, 0xaa, 0x23, 0xa4, 0x47, 0xe4, 0x08, 0xf4, 0xbb, 0xaa, ++ 0xe3, 0x22, 0xf5, 0x38, 0x31, 0x59, 0x40, 0xae, 0xf3, 0xd7, 0x3a, 0xb6, ++ 0x39, 0xce, 0x4d, 0xc4, 0xb7, 0xc9, 0x6d, 0xba, 0xa7, 0x2e, 0xba, 0xba, ++ 0xa7, 0x2e, 0xa2, 0x06, 0x3e, 0x1d, 0x91, 0x96, 0x55, 0xd8, 0xcf, 0xcb, ++ 0x7b, 0xdc, 0x7c, 0xee, 0x65, 0xfe, 0xe6, 0x04, 0x7f, 0x77, 0x3a, 0x2c, ++ 0xd6, 0x69, 0x1d, 0x0f, 0x20, 0xef, 0x09, 0x99, 0x3d, 0x47, 0x9f, 0x6a, ++ 0xc9, 0xc0, 0x69, 0xde, 0x07, 0xf3, 0x9a, 0xa5, 0xd1, 0x19, 0xd8, 0xc8, ++ 0x1c, 0xfc, 0x82, 0x5a, 0x7d, 0x57, 0x66, 0x2c, 0xca, 0xa1, 0x53, 0xda, ++ 0x56, 0x51, 0x8f, 0xaf, 0xc2, 0x37, 0xac, 0xc6, 0xa4, 0x09, 0xb6, 0xa5, ++ 0x2e, 0x46, 0x8d, 0xe2, 0xe2, 0x07, 0xb0, 0x07, 0xfe, 0x7e, 0x83, 0xdc, ++ 0xf2, 0x62, 0xcc, 0xa0, 0x6d, 0xa9, 0x8b, 0xd4, 0x73, 0xa4, 0x53, 0x17, ++ 0xa9, 0xe7, 0xa4, 0xc3, 0xb7, 0x17, 0x7c, 0x5f, 0x1c, 0xd1, 0xef, 0xd3, ++ 0x37, 0x6d, 0xf2, 0xf2, 0x8f, 0x92, 0xad, 0x30, 0x47, 0x24, 0x3f, 0xd2, ++ 0x8d, 0x5c, 0xa6, 0x2b, 0x6b, 0x0f, 0x8c, 0x6f, 0xca, 0xa7, 0xe5, 0xeb, ++ 0xee, 0x4f, 0xc1, 0x17, 0xf9, 0x68, 0xe4, 0x8b, 0x3c, 0x75, 0x4a, 0x93, ++ 0xe6, 0xcb, 0xe7, 0x07, 0x82, 0x06, 0x3f, 0x7d, 0xa7, 0x63, 0xc0, 0xff, ++ 0x75, 0xf8, 0x80, 0x5e, 0xf4, 0x4f, 0xa2, 0x47, 0x48, 0xbb, 0x48, 0xde, ++ 0xc9, 0xeb, 0x0d, 0xe4, 0x8d, 0x3e, 0x9f, 0xd3, 0xf8, 0x7e, 0x5d, 0x66, ++ 0x17, 0x9d, 0x93, 0x88, 0xab, 0x7c, 0x3b, 0xef, 0x71, 0xdf, 0x81, 0xb7, ++ 0xf3, 0xfe, 0xba, 0xb8, 0xf2, 0x49, 0x98, 0x55, 0xc1, 0xf7, 0xca, 0x76, ++ 0x59, 0x34, 0xfa, 0x8e, 0x98, 0xce, 0xc3, 0x8f, 0xd4, 0xe8, 0x27, 0x28, ++ 0xa3, 0x1b, 0x92, 0x5d, 0xe4, 0xfb, 0x97, 0x8b, 0x6f, 0xba, 0xe6, 0xfb, ++ 0x8d, 0xc6, 0x3d, 0x36, 0xe0, 0x7a, 0x01, 0x47, 0xba, 0xd6, 0x29, 0x3f, ++ 0xf8, 0x9c, 0xbd, 0x0d, 0xbe, 0xa6, 0x71, 0xdf, 0xb8, 0x3c, 0x87, 0x3c, ++ 0xe0, 0x0d, 0xfb, 0x0e, 0xb9, 0x4e, 0x33, 0x17, 0xaa, 0xd6, 0xa6, 0x60, ++ 0x93, 0x4d, 0xf0, 0x65, 0xa6, 0x6c, 0x96, 0x9a, 0xa5, 0x8a, 0x7c, 0x67, ++ 0x79, 0x85, 0xbe, 0x90, 0xb4, 0xb7, 0x61, 0xde, 0xf5, 0x5f, 0xf4, 0xb5, ++ 0x9b, 0x25, 0xc4, 0x59, 0xd8, 0xf6, 0x66, 0x29, 0x8a, 0xbe, 0x17, 0xbd, ++ 0x85, 0x3e, 0x8e, 0x3e, 0x89, 0x7e, 0x04, 0xfd, 0x08, 0x7a, 0x0b, 0x7b, ++ 0x63, 0xe8, 0xfd, 0x9a, 0x81, 0xb8, 0x6e, 0xf3, 0x5d, 0xd4, 0xe7, 0x21, ++ 0x57, 0xb4, 0x18, 0xd3, 0xc2, 0x76, 0x0e, 0x75, 0x44, 0x76, 0x84, 0xb9, ++ 0x1e, 0x73, 0xbe, 0x8f, 0x1d, 0xd3, 0x62, 0x5d, 0x5e, 0x30, 0xf6, 0x0d, ++ 0x31, 0x2e, 0x54, 0x10, 0x17, 0x3e, 0xd8, 0x8d, 0xfa, 0xd1, 0xdc, 0xaf, ++ 0xdf, 0x8e, 0x16, 0x31, 0xe6, 0x37, 0x6a, 0xde, 0xe8, 0x1c, 0xe2, 0x14, ++ 0xfd, 0xa7, 0x83, 0x3d, 0x79, 0xf8, 0xf1, 0x2e, 0xd8, 0x5f, 0x06, 0x7e, ++ 0x1b, 0xdf, 0x4b, 0x6f, 0xec, 0x76, 0x63, 0x2a, 0xf2, 0x77, 0xb5, 0xfd, ++ 0xbd, 0xc6, 0xc6, 0x9e, 0x9d, 0x6a, 0x83, 0x0e, 0xe0, 0x48, 0x54, 0x96, ++ 0x60, 0x83, 0x3f, 0xb4, 0x4f, 0xea, 0xdc, 0x8e, 0x77, 0xf1, 0x2c, 0x72, ++ 0xd4, 0xdc, 0x02, 0x73, 0x98, 0x13, 0xa8, 0x4b, 0x50, 0x9f, 0x45, 0x59, ++ 0x93, 0x33, 0x16, 0xe8, 0x5c, 0x34, 0x2a, 0x6d, 0x8c, 0x03, 0x37, 0x70, ++ 0x1e, 0xf8, 0x5a, 0x76, 0x20, 0xb3, 0x03, 0xc8, 0x09, 0x1d, 0x27, 0x6c, ++ 0xed, 0x93, 0xf8, 0x21, 0xfa, 0x1c, 0xc1, 0x7e, 0x53, 0xdc, 0xf7, 0x74, ++ 0xf8, 0xdd, 0x29, 0xfd, 0x5b, 0x31, 0x94, 0xeb, 0xb3, 0xd8, 0x7b, 0x17, ++ 0x70, 0x71, 0x9e, 0x6f, 0xd9, 0x22, 0xfb, 0x16, 0xdc, 0x9c, 0x56, 0x59, ++ 0x8d, 0xf8, 0x7e, 0xd5, 0xc3, 0xc7, 0x75, 0xe5, 0xfd, 0xa6, 0xb1, 0xc7, ++ 0x7d, 0x1b, 0xc6, 0x1d, 0x9f, 0x42, 0xfe, 0xbc, 0x81, 0x7b, 0x79, 0x03, ++ 0x77, 0x72, 0xa5, 0x44, 0x5d, 0x1f, 0x86, 0xde, 0x43, 0x86, 0x53, 0xc4, ++ 0x35, 0xa2, 0xcf, 0xde, 0x28, 0xc1, 0x77, 0xd2, 0xff, 0x29, 0x64, 0x77, ++ 0x6d, 0x6e, 0x4c, 0x77, 0xf1, 0xf4, 0xba, 0x70, 0xe2, 0xaf, 0xed, 0xd6, ++ 0xf4, 0x54, 0xf5, 0x3b, 0x18, 0xe5, 0x04, 0x1d, 0xe4, 0x6f, 0x03, 0x1a, ++ 0xe6, 0x6b, 0x51, 0xfd, 0xfe, 0xae, 0x38, 0x47, 0x3e, 0x46, 0x24, 0xbb, ++ 0xe0, 0xef, 0xeb, 0xc6, 0xbe, 0xd6, 0x06, 0x5c, 0x77, 0x6f, 0xe3, 0x41, ++ 0x79, 0x3c, 0x70, 0xfd, 0x93, 0x6f, 0xc3, 0x85, 0xad, 0xb7, 0x61, 0xc6, ++ 0x5f, 0xde, 0x4d, 0x0a, 0xfb, 0xfd, 0xfb, 0xe9, 0xf5, 0x6a, 0x81, 0xc4, ++ 0x7c, 0x41, 0x98, 0xab, 0xf0, 0x8e, 0xc6, 0x61, 0xd7, 0x5d, 0xc0, 0x6f, ++ 0x4b, 0xa5, 0xd4, 0x22, 0xaa, 0x87, 0xb5, 0x31, 0x73, 0xe5, 0xc6, 0x33, ++ 0x7f, 0xdb, 0x3b, 0x13, 0xf5, 0xf4, 0x19, 0xe6, 0xcd, 0x3a, 0xce, 0x00, ++ 0xa6, 0x7d, 0x1b, 0x6d, 0xbf, 0xee, 0xc1, 0x71, 0x3d, 0x29, 0x05, 0xe4, ++ 0xa1, 0xb9, 0x05, 0x64, 0xf4, 0xf0, 0xdf, 0x2a, 0xcd, 0xdf, 0xb3, 0xf8, ++ 0x86, 0x37, 0x1c, 0x9f, 0x05, 0x8d, 0x05, 0x33, 0xc3, 0x77, 0x33, 0xe0, ++ 0xd8, 0xbb, 0x0d, 0xc7, 0x84, 0x87, 0x63, 0x42, 0x8a, 0xe7, 0x26, 0x61, ++ 0x6b, 0x19, 0xc4, 0xf7, 0x7e, 0xf3, 0x80, 0x7c, 0x1e, 0xc5, 0x35, 0xe6, ++ 0x2e, 0x8c, 0xe0, 0x9e, 0x1c, 0x67, 0x9f, 0x7d, 0x18, 0x74, 0xbf, 0x86, ++ 0xd8, 0xea, 0xe7, 0x3c, 0xc5, 0x58, 0x08, 0x31, 0xec, 0x98, 0xfe, 0x0d, ++ 0xb6, 0x60, 0x9a, 0xd0, 0x57, 0x65, 0x0c, 0x27, 0x51, 0xde, 0x23, 0xbe, ++ 0xcd, 0x23, 0x56, 0x91, 0xcf, 0x0e, 0x29, 0x9a, 0xc6, 0xa3, 0x21, 0xe4, ++ 0x35, 0xd9, 0x05, 0xda, 0x91, 0x0c, 0x84, 0xd2, 0xcd, 0xc8, 0x49, 0x1d, ++ 0xf9, 0x99, 0xcd, 0x7f, 0xa3, 0x30, 0x2f, 0x1b, 0x35, 0x13, 0xfd, 0x3a, ++ 0xee, 0xe1, 0xdb, 0xf8, 0xbe, 0xde, 0x83, 0xbc, 0x0f, 0x2b, 0x19, 0xe8, ++ 0x6e, 0x52, 0xe7, 0x33, 0xcc, 0x23, 0xaa, 0x88, 0xb7, 0x0a, 0xb1, 0x06, ++ 0x79, 0xd5, 0x38, 0x73, 0xd7, 0xe7, 0x96, 0xaf, 0xcb, 0x95, 0x45, 0xfe, ++ 0x06, 0xca, 0xb8, 0x7c, 0x90, 0xfe, 0xc0, 0x9c, 0x4b, 0x61, 0x6e, 0x85, ++ 0xbe, 0x0c, 0xe3, 0x3a, 0x0c, 0xa8, 0x07, 0x39, 0x02, 0x72, 0xed, 0x4d, ++ 0x2b, 0x09, 0x3e, 0xaf, 0xcb, 0xc6, 0x62, 0x58, 0x96, 0x2d, 0xe6, 0x45, ++ 0x12, 0xcf, 0x02, 0x76, 0x63, 0xe5, 0x9a, 0xab, 0x13, 0x84, 0x47, 0xcd, ++ 0x53, 0x40, 0x5e, 0x77, 0x40, 0xef, 0xfd, 0x65, 0xf7, 0x4c, 0x9a, 0x1a, ++ 0xeb, 0xbc, 0x19, 0xd9, 0xa0, 0x3d, 0xd9, 0x7c, 0x93, 0x62, 0x6e, 0x70, ++ 0x02, 0x3a, 0xcb, 0xdc, 0x9d, 0xf5, 0x00, 0xbe, 0x6b, 0x5c, 0x27, 0xef, ++ 0xe8, 0x97, 0xfa, 0x21, 0x1b, 0xda, 0x3d, 0xdf, 0xc4, 0x10, 0x47, 0x15, ++ 0x6d, 0xbd, 0xa8, 0x7d, 0x41, 0xb1, 0x3c, 0x83, 0x98, 0x02, 0x1f, 0xc0, ++ 0xdf, 0x70, 0xa6, 0xa6, 0x70, 0x97, 0xe3, 0x80, 0xdb, 0x16, 0x4b, 0xd6, ++ 0x8a, 0x3a, 0x2f, 0x53, 0xe7, 0x6f, 0xbf, 0xdf, 0xe4, 0x61, 0x3f, 0x6a, ++ 0x0d, 0xba, 0x05, 0x1b, 0x52, 0x6b, 0x51, 0xf4, 0xf0, 0xc7, 0x6b, 0xa8, ++ 0x2f, 0x4a, 0x7c, 0x1f, 0x42, 0x6d, 0x50, 0xe2, 0xdb, 0x49, 0x12, 0xfd, ++ 0x08, 0xdf, 0x8b, 0x3c, 0xbf, 0x46, 0xfc, 0xa4, 0xc3, 0xf7, 0x2f, 0xcc, ++ 0x25, 0xe9, 0x5f, 0xfc, 0x7c, 0xd2, 0xd5, 0x85, 0x53, 0x65, 0xfa, 0x10, ++ 0xea, 0x75, 0x3f, 0xfc, 0x16, 0x75, 0xc1, 0xcd, 0x25, 0x57, 0x2a, 0xae, ++ 0xcc, 0x66, 0xeb, 0x97, 0x75, 0x8c, 0xd8, 0x2f, 0x16, 0x74, 0x8c, 0xb2, ++ 0xc3, 0x9a, 0x8e, 0x01, 0x97, 0x24, 0xa3, 0x7b, 0xca, 0xec, 0x75, 0xc9, ++ 0xac, 0x8c, 0xc8, 0x0b, 0xda, 0x6f, 0xf9, 0x3e, 0x8b, 0x39, 0x64, 0x0c, ++ 0xf2, 0x4b, 0xca, 0xf3, 0x67, 0xaf, 0x4b, 0xf6, 0x45, 0xfa, 0xad, 0xe1, ++ 0x58, 0xab, 0x41, 0x5f, 0xe5, 0x48, 0x0d, 0xb1, 0xe9, 0x80, 0xcd, 0x7f, ++ 0x07, 0x10, 0x42, 0x4d, 0xe7, 0x48, 0xf3, 0x68, 0xc2, 0x8e, 0x1b, 0xfd, ++ 0x4f, 0xb6, 0x1a, 0x8c, 0x8d, 0xc3, 0xe6, 0x53, 0xe2, 0xbf, 0x47, 0xb5, ++ 0xc8, 0x53, 0xfa, 0xad, 0x02, 0x66, 0xbb, 0xf0, 0x91, 0xfe, 0x1d, 0xe5, ++ 0x66, 0x8a, 0xb2, 0xc6, 0x78, 0x8d, 0xf3, 0x85, 0xc8, 0xcd, 0x54, 0x93, ++ 0x14, 0xef, 0x72, 0x9c, 0xa3, 0xa3, 0xa9, 0xdd, 0xee, 0xbf, 0x15, 0xf9, ++ 0xc6, 0x5d, 0xae, 0x2f, 0x38, 0xea, 0x8d, 0x5f, 0x41, 0x4f, 0xdd, 0x66, ++ 0xbc, 0x65, 0x7c, 0xe4, 0xbd, 0xa1, 0x5f, 0xe1, 0x37, 0x63, 0xef, 0x3c, ++ 0x62, 0x2f, 0xe3, 0x65, 0x97, 0xe4, 0x0e, 0x6b, 0x9f, 0xc1, 0xf9, 0x82, ++ 0x9b, 0x4b, 0x7b, 0x70, 0x95, 0x69, 0x99, 0xad, 0x30, 0x87, 0xda, 0x40, ++ 0x2c, 0x1b, 0x82, 0xae, 0x32, 0xa6, 0x9d, 0x44, 0x3c, 0xe7, 0xef, 0xd2, ++ 0x58, 0x5b, 0xe2, 0xbe, 0x44, 0x32, 0xae, 0xc0, 0xf3, 0x96, 0x4e, 0xdd, ++ 0x8c, 0xf2, 0x3d, 0xea, 0xd2, 0x10, 0xee, 0xfd, 0x4f, 0x59, 0x5b, 0x0c, ++ 0x68, 0x1d, 0xc9, 0xbe, 0x4c, 0xd9, 0xbb, 0xbf, 0x5b, 0x4b, 0xb7, 0x6b, ++ 0x03, 0xcc, 0x03, 0x1e, 0x87, 0x5c, 0xf6, 0xdb, 0xd7, 0x19, 0xbb, 0xff, ++ 0x5d, 0x59, 0xc3, 0xc9, 0xa7, 0x0c, 0xda, 0x36, 0xc6, 0x2b, 0x21, 0x59, ++ 0x8a, 0x92, 0x7f, 0xc8, 0xcb, 0xa0, 0xed, 0xec, 0x24, 0x87, 0xed, 0x32, ++ 0xf8, 0x4b, 0xc8, 0x80, 0xb2, 0xf4, 0x65, 0xc0, 0xef, 0x49, 0xdc, 0x17, ++ 0x6b, 0x86, 0x7e, 0x5d, 0x47, 0x16, 0xeb, 0xee, 0xd9, 0xc5, 0x72, 0x23, ++ 0xcd, 0xa4, 0x97, 0x77, 0x7a, 0x49, 0x72, 0xfa, 0x7e, 0xe7, 0x25, 0x57, ++ 0xb9, 0x24, 0xfb, 0x2a, 0xf3, 0xf2, 0x98, 0xf5, 0x28, 0xf8, 0xbd, 0xe6, ++ 0xcc, 0x58, 0xba, 0x56, 0x19, 0xcf, 0xff, 0x6f, 0xe7, 0x56, 0x1b, 0xdb, ++ 0x56, 0x75, 0x86, 0x5f, 0x5f, 0xdb, 0x69, 0x1a, 0x9a, 0x70, 0xeb, 0x3a, ++ 0x89, 0x9b, 0x66, 0xad, 0x1d, 0xdf, 0x7e, 0x88, 0xa4, 0xe8, 0x36, 0x64, ++ 0x34, 0xea, 0x82, 0x62, 0x9c, 0x50, 0xc2, 0xe8, 0x44, 0xda, 0x75, 0x55, ++ 0xb5, 0x31, 0x64, 0x39, 0xe9, 0x07, 0xd3, 0x06, 0xa3, 0xb0, 0x82, 0x18, ++ 0x52, 0x8d, 0xdb, 0x6a, 0x9d, 0x96, 0xc6, 0xe9, 0x07, 0x6b, 0x37, 0x69, ++ 0x9a, 0xe5, 0xa4, 0x2d, 0x48, 0x11, 0x2e, 0x88, 0x6e, 0xfb, 0xb1, 0x8d, ++ 0x2a, 0x65, 0xec, 0xff, 0xf6, 0x67, 0xda, 0xd0, 0x16, 0x15, 0x18, 0xfc, ++ 0xd8, 0xa4, 0xfe, 0xe0, 0x47, 0x25, 0xe8, 0xbc, 0xe7, 0x79, 0xcf, 0xbd, ++ 0x8e, 0x6d, 0x82, 0x26, 0x2d, 0x52, 0xe4, 0x7b, 0xce, 0x3d, 0xf7, 0x9c, ++ 0x73, 0xcf, 0xfb, 0xfd, 0xbe, 0xcf, 0xc5, 0xda, 0x13, 0x7d, 0x6b, 0xe5, ++ 0x63, 0xf8, 0x1d, 0x27, 0x67, 0x6d, 0xc9, 0xd8, 0x83, 0xf2, 0x63, 0xcd, ++ 0xe5, 0x33, 0x3e, 0x09, 0xc0, 0x27, 0x35, 0xb8, 0x02, 0x69, 0x77, 0x62, ++ 0x37, 0x85, 0x3e, 0x65, 0x18, 0xb4, 0x8e, 0x1b, 0xbf, 0xd9, 0x36, 0xf7, ++ 0x37, 0x9d, 0x81, 0xef, 0xee, 0x0e, 0xb4, 0xfb, 0x39, 0x5f, 0xe3, 0xdf, ++ 0xfe, 0xc5, 0xab, 0xa1, 0x0d, 0xca, 0x0c, 0xf6, 0xf3, 0x96, 0xea, 0x59, ++ 0x07, 0xbc, 0xc4, 0xdc, 0x74, 0x4c, 0xf3, 0x0f, 0xe1, 0x69, 0xea, 0xa8, ++ 0xab, 0xd0, 0x51, 0x43, 0xd4, 0x5d, 0xc3, 0xb3, 0x2e, 0xf3, 0x03, 0x51, ++ 0xf9, 0xf3, 0x14, 0xf5, 0x70, 0x5c, 0xfe, 0x34, 0xf5, 0x02, 0xf6, 0x93, ++ 0x28, 0x32, 0x47, 0x79, 0x63, 0x26, 0x47, 0x3f, 0x49, 0xfd, 0xf9, 0xb4, ++ 0xfb, 0xac, 0xda, 0x81, 0xb8, 0x95, 0x5f, 0x13, 0x56, 0x7d, 0xf3, 0xb4, ++ 0xd6, 0x74, 0xe3, 0x56, 0xb7, 0xdc, 0x38, 0x6f, 0x74, 0x6c, 0x78, 0x3a, ++ 0x1a, 0x18, 0x99, 0xa3, 0x5d, 0x4a, 0xc6, 0xb2, 0xd6, 0x0a, 0x39, 0x10, ++ 0x65, 0xee, 0x39, 0x45, 0xfd, 0x0c, 0x5b, 0xd8, 0x6b, 0x67, 0xad, 0x66, ++ 0xcf, 0xfe, 0xc4, 0x1a, 0xf4, 0xec, 0xd3, 0x9e, 0x9e, 0xe5, 0xbd, 0x14, ++ 0x68, 0x4a, 0x5b, 0x94, 0x98, 0x19, 0xb5, 0x92, 0xb0, 0x79, 0xb8, 0x9e, ++ 0xe7, 0xfc, 0x71, 0x39, 0x32, 0x7f, 0x18, 0xfe, 0x77, 0xaf, 0xbd, 0x87, ++ 0x76, 0xd5, 0x1e, 0x22, 0x16, 0x07, 0xeb, 0x7f, 0xa9, 0x61, 0xae, 0xc7, ++ 0xbd, 0xb9, 0x78, 0x1f, 0x72, 0x3e, 0xed, 0xc8, 0x04, 0x6c, 0xc9, 0x88, ++ 0x6d, 0xf6, 0x5a, 0x3f, 0x76, 0x77, 0x75, 0xdd, 0x13, 0x05, 0xc7, 0xc3, ++ 0x85, 0xe1, 0x17, 0xbe, 0xd0, 0xd7, 0x23, 0x5c, 0x93, 0xeb, 0xb5, 0x49, ++ 0x7a, 0x1f, 0xf4, 0xcb, 0x34, 0xff, 0x73, 0x5e, 0xed, 0x0a, 0xf1, 0x4a, ++ 0xb4, 0x6b, 0x19, 0xdb, 0xf4, 0x80, 0x37, 0xdf, 0xb6, 0x0e, 0x69, 0x89, ++ 0xd6, 0x8c, 0x67, 0x6e, 0x85, 0xed, 0xb8, 0xe4, 0xe6, 0xf9, 0x5b, 0xa9, ++ 0x44, 0x9c, 0x26, 0xd9, 0x63, 0xaf, 0x6b, 0x98, 0x63, 0x2b, 0xfa, 0x8c, ++ 0x4f, 0x10, 0x9c, 0x0e, 0x78, 0xbe, 0xc5, 0x06, 0xfa, 0x4d, 0xde, 0x75, ++ 0xb3, 0xe6, 0x64, 0xe2, 0x56, 0x57, 0xc3, 0x7b, 0x6c, 0xa8, 0xda, 0xe1, ++ 0xb8, 0x45, 0xdd, 0xd9, 0x14, 0x95, 0x36, 0xf2, 0x50, 0x45, 0xfd, 0xf8, ++ 0x90, 0x63, 0xb0, 0x16, 0x51, 0xe7, 0x60, 0x07, 0x73, 0xf6, 0x6f, 0xeb, ++ 0xb9, 0xb5, 0xd2, 0x27, 0xc0, 0x35, 0xf8, 0xe4, 0x73, 0xf9, 0x5e, 0xe6, ++ 0x7a, 0x31, 0x7f, 0x0b, 0xe7, 0x77, 0xbd, 0x73, 0x4e, 0xb8, 0x39, 0xeb, ++ 0x7e, 0xc9, 0x9e, 0x37, 0xfc, 0x97, 0x76, 0xc0, 0x7b, 0x6d, 0x68, 0xcf, ++ 0xd1, 0x26, 0x7c, 0xd1, 0x3c, 0xbe, 0x6d, 0xd8, 0xa2, 0xb6, 0xe1, 0x78, ++ 0x81, 0xfc, 0x49, 0xbe, 0xf4, 0xf9, 0xd1, 0xd7, 0x79, 0xe4, 0x51, 0xea, ++ 0xd9, 0x41, 0x39, 0x53, 0xe0, 0xd9, 0xa4, 0xb4, 0xa6, 0xb5, 0xf1, 0xec, ++ 0x84, 0xe2, 0xb1, 0x7a, 0xa6, 0x13, 0x17, 0x73, 0x32, 0x2c, 0x57, 0x5d, ++ 0x9e, 0x59, 0xa2, 0x98, 0x09, 0xb6, 0xd6, 0xbc, 0xff, 0x3e, 0x3d, 0xb3, ++ 0xb0, 0xfa, 0x8c, 0x31, 0x8c, 0x7d, 0xc9, 0xa3, 0x77, 0x9b, 0x9e, 0x6d, ++ 0xa6, 0x8e, 0x3e, 0x8f, 0xea, 0x39, 0x85, 0xa1, 0x13, 0x59, 0xc7, 0x0f, ++ 0x47, 0xf8, 0x0c, 0xd7, 0xa5, 0xcf, 0xc7, 0xb5, 0xc8, 0x7b, 0x3d, 0xb0, ++ 0xd8, 0xfd, 0x12, 0xdc, 0x01, 0xd1, 0xdf, 0xc1, 0x3a, 0x72, 0x00, 0xb2, ++ 0xba, 0xd1, 0x60, 0x5f, 0xc6, 0x8d, 0xaf, 0x91, 0xb1, 0xde, 0xc2, 0x39, ++ 0x22, 0x56, 0x81, 0x1f, 0x7d, 0xfc, 0xa7, 0x77, 0x30, 0x5f, 0xc6, 0xf3, ++ 0xd7, 0x07, 0x30, 0x3f, 0xcf, 0x82, 0x32, 0x36, 0xb5, 0x8d, 0xbc, 0x3a, ++ 0xaa, 0xf5, 0x41, 0x3e, 0x43, 0x39, 0xe6, 0x99, 0x91, 0x2e, 0x7f, 0xc3, ++ 0xf3, 0x6c, 0x6f, 0x6d, 0xa0, 0x63, 0xd2, 0xdb, 0x9f, 0x7f, 0x3f, 0x2c, ++ 0xe1, 0x0e, 0xea, 0xb8, 0xa8, 0x24, 0xa7, 0x19, 0xb3, 0xc0, 0x76, 0x8d, ++ 0x73, 0xae, 0xff, 0xad, 0x8b, 0x33, 0xff, 0xa7, 0x2e, 0xce, 0x58, 0x1f, ++ 0x29, 0xef, 0x84, 0x35, 0x8f, 0xf5, 0xc5, 0x74, 0x2d, 0xd6, 0xd1, 0xd5, ++ 0xaf, 0xdd, 0x47, 0xab, 0x74, 0xfc, 0x51, 0x81, 0xf6, 0x2a, 0xa5, 0x39, ++ 0xe5, 0x7f, 0x4e, 0xf1, 0x6c, 0xb9, 0xc7, 0xab, 0xdc, 0xe3, 0xf0, 0x82, ++ 0x62, 0x20, 0xbf, 0xa6, 0x32, 0x7c, 0xb2, 0x40, 0x1d, 0xd3, 0x2a, 0xb3, ++ 0x33, 0xbe, 0x9e, 0x19, 0xf3, 0x7c, 0xdc, 0xfc, 0x9a, 0x26, 0xd5, 0x33, ++ 0xf0, 0x6e, 0x9c, 0x11, 0xcf, 0xbe, 0x74, 0x4b, 0xe9, 0x3c, 0xed, 0x6e, ++ 0x12, 0x7d, 0xd1, 0x40, 0x69, 0x8e, 0xb5, 0x49, 0x62, 0x50, 0x86, 0x85, ++ 0x75, 0xff, 0x11, 0xfb, 0x38, 0xe4, 0x2d, 0x26, 0xef, 0x4f, 0xd1, 0xa7, ++ 0x6f, 0x82, 0x6f, 0xdc, 0xd6, 0x70, 0xbe, 0xdb, 0xab, 0x3e, 0x61, 0x3d, ++ 0xdd, 0x37, 0x74, 0x4a, 0x0b, 0xf9, 0xdc, 0xb1, 0x6f, 0x08, 0x7d, 0x30, ++ 0x5e, 0x67, 0x11, 0x0b, 0x30, 0xf6, 0x88, 0x6b, 0xec, 0x51, 0x2a, 0xb2, ++ 0xaf, 0xd5, 0xcb, 0x2b, 0xb5, 0x2a, 0xaf, 0x90, 0xdf, 0x32, 0xea, 0x7f, ++ 0x0f, 0xa9, 0xce, 0xca, 0x4f, 0xf5, 0x1a, 0xfc, 0x8a, 0x1d, 0x53, 0xde, ++ 0x93, 0x3a, 0xde, 0x8b, 0x79, 0x6b, 0x3f, 0xdc, 0x69, 0x7c, 0x2b, 0x5b, ++ 0xf5, 0x4d, 0x58, 0xc7, 0xd1, 0xae, 0x70, 0x7e, 0xf2, 0x06, 0x79, 0x84, ++ 0x3a, 0xcf, 0x1f, 0xe7, 0xd3, 0xc3, 0x6f, 0x73, 0x3c, 0xf9, 0xbf, 0x16, ++ 0x8b, 0xe0, 0xcb, 0xaa, 0xdf, 0xe7, 0xcb, 0x1d, 0xef, 0xd5, 0xda, 0x04, ++ 0xca, 0x5d, 0x6d, 0x7d, 0xd2, 0x96, 0xc8, 0xf4, 0x12, 0x5d, 0xd2, 0xfd, ++ 0xdc, 0xff, 0x4b, 0xcc, 0xed, 0x42, 0xde, 0x96, 0xa3, 0xcd, 0x51, 0xa5, ++ 0x4d, 0x06, 0xb4, 0x89, 0x28, 0x6d, 0x18, 0xef, 0x3d, 0xe3, 0xf1, 0x5b, ++ 0x2b, 0xce, 0x8b, 0xb9, 0x5a, 0xe8, 0xba, 0xbd, 0xd4, 0xf9, 0xcf, 0x77, ++ 0x6a, 0x7d, 0xd0, 0xa1, 0xee, 0x5b, 0x05, 0x7d, 0xc6, 0xf6, 0x66, 0xf5, ++ 0x47, 0x4c, 0xbc, 0x15, 0xd7, 0x3c, 0x68, 0x10, 0xfa, 0xb9, 0x34, 0x05, ++ 0x5f, 0x8d, 0x78, 0xb7, 0x3a, 0x5a, 0x7d, 0xc7, 0x3b, 0xaf, 0x92, 0xd2, ++ 0x86, 0x32, 0x40, 0xbd, 0xb9, 0x1a, 0xf3, 0xed, 0x8e, 0xf6, 0x81, 0xbf, ++ 0x7e, 0x81, 0xfe, 0x8d, 0x1a, 0x4f, 0x04, 0x21, 0xf3, 0x37, 0xa7, 0x3a, ++ 0xbc, 0x18, 0xce, 0x41, 0x1b, 0x71, 0xeb, 0x54, 0x84, 0x31, 0x05, 0xda, ++ 0x5b, 0xa4, 0x69, 0x1a, 0xf1, 0x2b, 0xf4, 0xf8, 0x82, 0xda, 0xa3, 0x3e, ++ 0xdc, 0xbf, 0x8b, 0x18, 0x3f, 0x5c, 0x1f, 0xc6, 0x73, 0xbd, 0x06, 0x8b, ++ 0x10, 0xdd, 0xa4, 0x67, 0x5a, 0x9a, 0x4a, 0xc4, 0x0e, 0x8a, 0xd7, 0x37, ++ 0xee, 0xaa, 0x3e, 0x58, 0xda, 0xd7, 0x43, 0xb2, 0xbb, 0x6a, 0x2f, 0x18, ++ 0x47, 0xc3, 0x87, 0x9f, 0x31, 0xf6, 0x20, 0x5f, 0xec, 0x53, 0x5c, 0x54, ++ 0x70, 0x68, 0x1e, 0x67, 0x49, 0x9f, 0x74, 0x11, 0x7e, 0xb8, 0x8b, 0x33, ++ 0xa4, 0xdf, 0x5d, 0x39, 0x76, 0xc2, 0x4d, 0xb1, 0x3e, 0x06, 0x7d, 0x70, ++ 0x4c, 0x46, 0x10, 0x17, 0x8c, 0x04, 0xdb, 0x98, 0x57, 0x86, 0x6f, 0x98, ++ 0xf3, 0x72, 0x8f, 0x7d, 0xcc, 0x99, 0xca, 0xd9, 0x39, 0xee, 0x9d, 0xb2, ++ 0x6d, 0x62, 0xef, 0xd2, 0x14, 0xf7, 0x6b, 0xf2, 0x10, 0x6c, 0x5b, 0xd3, ++ 0x2e, 0x7e, 0x79, 0x16, 0x03, 0xf8, 0x1d, 0x84, 0x3c, 0x70, 0x2c, 0x7e, ++ 0xe7, 0x16, 0xe5, 0xdd, 0xf3, 0xbe, 0x6d, 0x0f, 0xc8, 0x3b, 0x4e, 0xe5, ++ 0xd8, 0x71, 0x77, 0x0d, 0xcf, 0xc0, 0xcd, 0xb1, 0x66, 0xed, 0x38, 0x6e, ++ 0x5e, 0x2a, 0x95, 0x05, 0x77, 0x61, 0x8d, 0xa5, 0xb4, 0xa4, 0xfc, 0xff, ++ 0x03, 0x67, 0x78, 0xfd, 0x3e, 0x4b, 0x0c, 0xfd, 0x48, 0x9b, 0xcf, 0xd7, ++ 0xfe, 0x6a, 0x6d, 0x81, 0xaf, 0xff, 0xc8, 0x8f, 0xe4, 0xcb, 0x45, 0xd9, ++ 0xa9, 0xfa, 0x7f, 0xb9, 0xe7, 0x6a, 0x75, 0xbf, 0xef, 0xdf, 0x52, 0xbf, ++ 0x93, 0x17, 0x63, 0x1a, 0x1f, 0x6c, 0x9a, 0x6e, 0xd4, 0x09, 0x4f, 0x78, ++ 0x75, 0x85, 0xe5, 0x78, 0x6f, 0xbf, 0xa7, 0x17, 0x52, 0xea, 0x3b, 0xa7, ++ 0x6c, 0xea, 0x07, 0xee, 0xa7, 0x45, 0x26, 0x2e, 0xdc, 0x01, 0x4d, 0x7c, ++ 0x1d, 0xcc, 0xb8, 0xcf, 0xd7, 0x1d, 0x6d, 0x9e, 0x2f, 0x6c, 0x49, 0xcf, ++ 0x59, 0xfa, 0x4e, 0x0e, 0xf4, 0x68, 0xbb, 0x64, 0xc6, 0x83, 0x92, 0x3c, ++ 0x1b, 0x8b, 0x19, 0x5f, 0x97, 0xfc, 0x07, 0x79, 0xd3, 0x3e, 0xad, 0x45, ++ 0xa1, 0xff, 0x6e, 0xe1, 0xda, 0x86, 0x9f, 0x21, 0xcf, 0x7b, 0xfd, 0x7b, ++ 0x76, 0x03, 0x8f, 0xee, 0xf0, 0x78, 0x94, 0xf7, 0x2d, 0x53, 0xff, 0xc0, ++ 0xd8, 0x9e, 0xb3, 0xdc, 0xa3, 0x79, 0xae, 0xe7, 0xac, 0x89, 0xd7, 0xeb, ++ 0x9f, 0xeb, 0xab, 0x3e, 0x87, 0xfb, 0xf0, 0x7d, 0xcd, 0xdc, 0x3b, 0x07, ++ 0xe1, 0xd3, 0xf5, 0xd1, 0xe6, 0xd0, 0x7e, 0x6f, 0x74, 0x77, 0x0a, 0xf9, ++ 0x3d, 0xe1, 0xf1, 0x1c, 0xf5, 0x4d, 0xc4, 0xd3, 0x37, 0x4b, 0xf6, 0x65, ++ 0xc4, 0xe0, 0x4f, 0x98, 0x13, 0xa9, 0xb1, 0x2f, 0x4f, 0x98, 0x77, 0xab, ++ 0xb3, 0x2f, 0x77, 0x7b, 0xf3, 0xf8, 0xf7, 0x7c, 0xbd, 0xe2, 0xb7, 0x7d, ++ 0xbd, 0xd2, 0xe8, 0xd3, 0xfa, 0xb4, 0xaf, 0xed, 0xaf, 0x8f, 0xf9, 0xf2, ++ 0xcb, 0xe6, 0x5d, 0xb2, 0x88, 0xd9, 0xe8, 0x53, 0x26, 0x72, 0x06, 0x2f, ++ 0x6d, 0x9d, 0xb1, 0x88, 0xfb, 0x70, 0x7e, 0x22, 0xe9, 0xc8, 0x1d, 0x8d, ++ 0xad, 0x4f, 0x5e, 0x18, 0xd3, 0x3c, 0x4f, 0xc9, 0xf5, 0xf4, 0x4e, 0x74, ++ 0x17, 0xe4, 0xea, 0x4a, 0x64, 0x09, 0x53, 0x34, 0x73, 0x34, 0x0d, 0x3b, ++ 0x94, 0xd2, 0x7a, 0xd9, 0xf7, 0xb0, 0xdf, 0x41, 0xc5, 0x73, 0xad, 0x74, ++ 0x5e, 0x94, 0x47, 0xec, 0x8a, 0xd6, 0x6e, 0x9a, 0x87, 0x8a, 0x47, 0x9b, ++ 0x4f, 0xfb, 0x7c, 0x4f, 0x7e, 0x9a, 0x39, 0x3a, 0x31, 0x53, 0x19, 0x0e, ++ 0x6d, 0xeb, 0xb5, 0xf3, 0x42, 0xbc, 0xfe, 0xb0, 0x1c, 0x52, 0xdc, 0xf0, ++ 0xab, 0xb8, 0xbf, 0x97, 0xf1, 0x65, 0x22, 0xa4, 0x78, 0xe0, 0x44, 0x6c, ++ 0x12, 0xb2, 0x98, 0x75, 0x89, 0xef, 0x5f, 0xa5, 0x38, 0xff, 0x92, 0xd0, ++ 0xcf, 0x22, 0xa6, 0xe0, 0x05, 0x39, 0xe8, 0x6e, 0x74, 0x17, 0xc4, 0xf8, ++ 0xbf, 0x59, 0xad, 0x09, 0xad, 0x90, 0x49, 0x37, 0xd4, 0x9c, 0x2e, 0x1b, ++ 0x19, 0x18, 0x0d, 0xa6, 0x56, 0x9e, 0x70, 0xa2, 0xcd, 0x3b, 0xcb, 0x90, ++ 0xf1, 0x32, 0xf4, 0x7f, 0x39, 0x16, 0x18, 0x51, 0x6c, 0xda, 0x57, 0x24, ++ 0xdd, 0x41, 0x3f, 0x9f, 0xfa, 0xe4, 0x01, 0xb9, 0x69, 0x6f, 0x96, 0x9b, ++ 0x5b, 0x88, 0xc3, 0xec, 0x47, 0x9b, 0xba, 0x64, 0x10, 0x7d, 0x49, 0xf4, ++ 0x35, 0x2b, 0x3f, 0x6a, 0x7c, 0x06, 0x9d, 0x75, 0xd3, 0xa6, 0xae, 0x5a, ++ 0xcf, 0x5f, 0xbc, 0xeb, 0x22, 0x68, 0x42, 0x6c, 0xc7, 0x56, 0xb4, 0xa9, ++ 0xe3, 0xec, 0x86, 0xfe, 0x2e, 0xb4, 0xef, 0xc3, 0x1c, 0x4d, 0xfa, 0x7e, ++ 0x96, 0xb3, 0xcd, 0xd4, 0x39, 0xeb, 0xc6, 0xac, 0x6e, 0x68, 0xff, 0xb1, ++ 0xdd, 0xe0, 0x13, 0x3e, 0x25, 0xbd, 0x73, 0x29, 0xd9, 0xd5, 0x59, 0xdf, ++ 0xfe, 0x77, 0x43, 0xbb, 0x4d, 0x56, 0xb6, 0x93, 0x0c, 0x4f, 0x75, 0xd4, ++ 0xf7, 0xfb, 0xfc, 0xe4, 0xb7, 0x3b, 0xf1, 0xbe, 0x09, 0x18, 0xbc, 0xa4, ++ 0xc6, 0x52, 0x37, 0xa3, 0x5c, 0xeb, 0x83, 0x86, 0x67, 0x78, 0xcd, 0x67, ++ 0xf8, 0x2c, 0xf3, 0x7a, 0x9f, 0xb1, 0x1f, 0xcf, 0x30, 0x27, 0xc0, 0xbc, ++ 0x06, 0x79, 0x76, 0xb9, 0x38, 0x8b, 0x63, 0x3e, 0x9f, 0x6f, 0xc8, 0x54, ++ 0x79, 0xcf, 0xd7, 0x2b, 0xb1, 0x2a, 0x56, 0x6d, 0x67, 0xc1, 0xcf, 0x09, ++ 0x93, 0x76, 0x5a, 0x93, 0x8a, 0xdd, 0x00, 0x9d, 0x0f, 0x80, 0xce, 0x0f, ++ 0x05, 0x19, 0x17, 0xb6, 0x78, 0xb4, 0x76, 0x64, 0xa4, 0xfc, 0x5b, 0xc8, ++ 0x38, 0x79, 0x14, 0x3e, 0x45, 0xd9, 0xf2, 0xf0, 0x19, 0x03, 0xb0, 0x69, ++ 0xae, 0x04, 0x35, 0xef, 0x80, 0xf8, 0x7e, 0xf6, 0xba, 0x8c, 0x4c, 0x31, ++ 0x27, 0x40, 0x7e, 0x66, 0x5c, 0x9f, 0xc2, 0xbd, 0x5b, 0x18, 0xeb, 0x42, ++ 0x86, 0xc7, 0xc0, 0xaf, 0x21, 0x71, 0xa6, 0xb7, 0x4a, 0x6e, 0x7c, 0x4c, ++ 0x7d, 0x80, 0x1e, 0xd8, 0xa8, 0xe3, 0xee, 0xa8, 0x9c, 0xb8, 0xb2, 0x01, ++ 0xb2, 0xca, 0xb8, 0x5f, 0x73, 0x1a, 0x95, 0xb0, 0xfa, 0xe6, 0xf4, 0x39, ++ 0x98, 0x87, 0x33, 0x35, 0x66, 0x23, 0xb7, 0x93, 0x31, 0x69, 0x1b, 0x95, ++ 0x99, 0x0b, 0xb6, 0xe2, 0x5d, 0x52, 0x72, 0xa7, 0x42, 0xda, 0x65, 0xf7, ++ 0xc6, 0xa1, 0xab, 0xe8, 0xcb, 0x9f, 0x8c, 0x98, 0xb3, 0x7c, 0x74, 0x2d, ++ 0x63, 0xe2, 0xe4, 0x74, 0xed, 0x1c, 0x8a, 0x91, 0xc1, 0xbd, 0xd7, 0xda, ++ 0x8d, 0xcc, 0x30, 0x3e, 0xfe, 0xa0, 0x92, 0x8a, 0x72, 0x4d, 0x8e, 0x65, ++ 0xed, 0x96, 0x3c, 0xc2, 0xbd, 0x7d, 0xea, 0xf1, 0xf2, 0xcf, 0x30, 0x5f, ++ 0x5c, 0x7a, 0x5e, 0x1f, 0xd3, 0xb8, 0xfe, 0x78, 0x5d, 0x0c, 0x6b, 0xf2, ++ 0x05, 0x26, 0x8e, 0xbd, 0x2e, 0x93, 0xf3, 0xa4, 0x0f, 0x6d, 0x7c, 0x40, ++ 0x5e, 0x73, 0x7a, 0xed, 0x27, 0xb5, 0xd6, 0x98, 0x48, 0xb1, 0x3e, 0xd3, ++ 0xe2, 0x24, 0xed, 0x59, 0x09, 0x0d, 0x7e, 0x15, 0xd7, 0x8c, 0x6b, 0xf3, ++ 0x6e, 0xaf, 0xfb, 0xa4, 0xf8, 0x38, 0x90, 0x8d, 0xa9, 0x15, 0x81, 0xdb, ++ 0x95, 0xeb, 0x7b, 0x39, 0xc6, 0xe0, 0x40, 0x24, 0x40, 0x5a, 0xbd, 0xb7, ++ 0x9e, 0xf8, 0x99, 0xfa, 0xfc, 0xdf, 0x83, 0x4f, 0xef, 0x19, 0x48, 0x9c, ++ 0x62, 0x0c, 0x1b, 0x76, 0xbe, 0xb5, 0xd6, 0xbc, 0x6b, 0x2e, 0xb7, 0x5a, ++ 0xb4, 0x7e, 0x76, 0xe4, 0x23, 0x87, 0x78, 0x88, 0x44, 0x6c, 0x85, 0xc5, ++ 0x3c, 0x38, 0x75, 0x1c, 0x6b, 0x2a, 0xcc, 0xb9, 0x11, 0xc7, 0xdf, 0x2c, ++ 0x97, 0xfb, 0x2c, 0x79, 0x30, 0x94, 0x8a, 0x5b, 0xb2, 0x29, 0x7e, 0x56, ++ 0xb0, 0x26, 0xeb, 0x2b, 0xf3, 0x89, 0x1c, 0xc7, 0x87, 0xa6, 0x39, 0x5f, ++ 0x5c, 0xe3, 0x95, 0xe4, 0xa6, 0x4a, 0xe5, 0x19, 0x57, 0x02, 0xc9, 0x7b, ++ 0x3f, 0xac, 0xb0, 0x16, 0x6e, 0xbd, 0xfe, 0x45, 0x38, 0x05, 0xea, 0x8a, ++ 0x55, 0x93, 0x06, 0x73, 0x78, 0xe2, 0x48, 0xcf, 0x3c, 0xdb, 0xdf, 0x7d, ++ 0xc4, 0xb4, 0x4f, 0xa1, 0xdd, 0xe4, 0x61, 0x9d, 0xa6, 0x8e, 0xf4, 0x14, ++ 0x9f, 0x5a, 0x6b, 0xe2, 0xef, 0x45, 0xc5, 0x7f, 0xbd, 0x5d, 0x17, 0xd3, ++ 0xa4, 0x02, 0xe3, 0x85, 0xb1, 0xc0, 0x58, 0xc1, 0xea, 0x6b, 0x06, 0xad, ++ 0xe6, 0x5c, 0xe6, 0x6a, 0xfc, 0x9c, 0x15, 0xf3, 0xfd, 0x22, 0xdf, 0x57, ++ 0x8c, 0x14, 0x6b, 0x8a, 0x96, 0xfa, 0x42, 0x07, 0xe6, 0x98, 0xe3, 0x8f, ++ 0xa8, 0x3e, 0x38, 0x38, 0xdf, 0x26, 0x79, 0x7b, 0x8d, 0xe4, 0x55, 0xc6, ++ 0xa3, 0xaa, 0x03, 0x2c, 0xe7, 0x5e, 0xf4, 0x71, 0xdf, 0x4f, 0x28, 0x2e, ++ 0xe2, 0xcd, 0x42, 0x17, 0xda, 0xcc, 0x35, 0x6f, 0x6f, 0xe8, 0xaf, 0xad, ++ 0xcb, 0x26, 0x6c, 0xcb, 0x6a, 0xac, 0xc9, 0xb2, 0xaf, 0xb1, 0x16, 0x7b, ++ 0x52, 0xae, 0x93, 0x6f, 0xca, 0x7e, 0xce, 0xdd, 0xf5, 0x72, 0xee, 0xdf, ++ 0xee, 0x32, 0x18, 0x61, 0xc9, 0x84, 0x86, 0x9a, 0xfb, 0x8e, 0x4f, 0x05, ++ 0x6f, 0x2d, 0xe5, 0x4f, 0xd1, 0x9e, 0xaf, 0xd6, 0xca, 0x71, 0xef, 0x39, ++ 0x62, 0xc5, 0xe1, 0x57, 0xe4, 0xbc, 0xef, 0x0e, 0x78, 0xbf, 0xfa, 0xfc, ++ 0xff, 0xd8, 0x53, 0x8b, 0xd6, 0xd9, 0xad, 0xba, 0x3a, 0xfb, 0xe3, 0x78, ++ 0x96, 0x35, 0xf6, 0x5c, 0xa5, 0x09, 0xbc, 0xdb, 0x44, 0x9c, 0x48, 0x75, ++ 0x3c, 0x75, 0xbc, 0xea, 0x72, 0x9d, 0x6b, 0xa7, 0x37, 0x57, 0x10, 0x7a, ++ 0x7e, 0x62, 0xca, 0x1f, 0x73, 0x4c, 0x56, 0xf4, 0x27, 0x62, 0x41, 0x8b, ++ 0x63, 0x8c, 0xbe, 0x4f, 0xbb, 0xc7, 0xa0, 0xc7, 0xa9, 0xf3, 0xf9, 0xde, ++ 0x0e, 0x7c, 0x3d, 0xea, 0x02, 0xea, 0x73, 0xb5, 0x01, 0xf1, 0x3c, 0x74, ++ 0xfd, 0x48, 0x59, 0x73, 0xf9, 0xb1, 0x87, 0x83, 0x89, 0x99, 0xac, 0xea, ++ 0x06, 0xf8, 0x7b, 0xe5, 0x6b, 0xcc, 0x07, 0x9d, 0x92, 0x40, 0x6d, 0x9d, ++ 0x86, 0xb1, 0x19, 0x6b, 0x1a, 0xad, 0xd0, 0x0d, 0x22, 0x57, 0xc1, 0x1b, ++ 0x6f, 0xcc, 0x91, 0x5f, 0x83, 0x1d, 0x26, 0xbe, 0x5a, 0xd8, 0x6e, 0x49, ++ 0x87, 0xd6, 0x3e, 0xf3, 0x4e, 0x84, 0xfe, 0xc9, 0x70, 0xb2, 0x1f, 0x7e, ++ 0xb6, 0x62, 0x0f, 0x98, 0xaf, 0x9c, 0x40, 0x3c, 0x56, 0x9b, 0x63, 0x81, ++ 0x7c, 0x8d, 0xb3, 0x3f, 0x0b, 0xbf, 0x72, 0xa9, 0xee, 0x91, 0x2f, 0x9e, ++ 0xd0, 0xdc, 0x66, 0x69, 0xae, 0x55, 0x75, 0x6c, 0xa9, 0xf8, 0x30, 0xce, ++ 0x45, 0x36, 0x5b, 0x43, 0x79, 0xaf, 0x3f, 0x2c, 0xc5, 0x22, 0xdb, 0xd2, ++ 0xdd, 0xa4, 0xe7, 0xee, 0xd7, 0x76, 0x6c, 0x99, 0x85, 0xaf, 0x58, 0x9c, ++ 0x77, 0xf0, 0xbf, 0x05, 0xff, 0x7d, 0xf8, 0xdf, 0x25, 0xe9, 0x69, 0xfa, ++ 0xaf, 0xac, 0xe5, 0xb4, 0x36, 0xac, 0x1f, 0xf6, 0x70, 0xe0, 0xf4, 0x6b, ++ 0x4d, 0x9c, 0x93, 0x2f, 0x36, 0xca, 0x09, 0xf3, 0xa4, 0xbe, 0x8e, 0x60, ++ 0xbe, 0xd4, 0xaf, 0xf5, 0xd5, 0xd6, 0xb0, 0x2c, 0xaf, 0xee, 0x45, 0x9e, ++ 0x6e, 0x91, 0x83, 0x45, 0xbf, 0x76, 0x15, 0x93, 0x43, 0xd5, 0xda, 0x95, ++ 0x64, 0x82, 0x43, 0xb7, 0x1f, 0xcb, 0x4e, 0x29, 0x9e, 0xc0, 0xb2, 0x86, ++ 0xae, 0x3f, 0x36, 0x39, 0xff, 0xce, 0x63, 0x4b, 0x98, 0x70, 0xdc, 0x9b, ++ 0x5f, 0x0e, 0x33, 0x44, 0x2c, 0x1d, 0xbf, 0x93, 0x53, 0xdf, 0x0d, 0xfb, ++ 0xf6, 0x63, 0x1e, 0xe2, 0xec, 0xe2, 0xf6, 0x12, 0x7e, 0xd9, 0x8f, 0x47, ++ 0x89, 0x23, 0xe5, 0x73, 0xb5, 0xd8, 0x8f, 0x10, 0xce, 0x5f, 0x02, 0x96, ++ 0x93, 0xc3, 0x3e, 0x2e, 0x76, 0x19, 0x3f, 0x90, 0x38, 0xd3, 0x44, 0x0d, ++ 0xf6, 0xc8, 0xc7, 0x9a, 0x5e, 0xc4, 0x5c, 0x19, 0xf9, 0x7d, 0xf9, 0x71, ++ 0xf9, 0x75, 0x79, 0x0c, 0xf2, 0x3d, 0x89, 0x39, 0xf7, 0xcb, 0xaf, 0xca, ++ 0x7b, 0xe5, 0x5a, 0x79, 0x5c, 0xde, 0x2a, 0xef, 0x42, 0x4c, 0x35, 0x4a, ++ 0xac, 0xa7, 0x87, 0x95, 0x1e, 0x96, 0x89, 0x73, 0x8a, 0x01, 0xbc, 0x45, ++ 0xbf, 0xe7, 0x88, 0xfa, 0xd9, 0x01, 0xf2, 0xf4, 0x6f, 0x18, 0xcf, 0x13, ++ 0x9b, 0x59, 0x2c, 0xfb, 0x18, 0x8e, 0x43, 0xdd, 0x58, 0xdb, 0xe6, 0x37, ++ 0x29, 0x23, 0xe7, 0x22, 0x81, 0xd1, 0x73, 0xa1, 0xc0, 0x43, 0xfa, 0x7d, ++ 0x0b, 0xeb, 0x9d, 0x15, 0x39, 0xe1, 0x3a, 0xe4, 0xcd, 0xc1, 0x11, 0xc8, ++ 0xc2, 0x28, 0x54, 0xfd, 0x23, 0xce, 0x1a, 0x01, 0x49, 0x53, 0x1f, 0xc3, ++ 0xcf, 0x4c, 0x9e, 0x76, 0x25, 0x5b, 0x98, 0x0d, 0x18, 0x3c, 0x9a, 0x8d, ++ 0x76, 0x1f, 0xda, 0xbf, 0xf4, 0xda, 0x3b, 0x24, 0x7b, 0x41, 0x52, 0xef, ++ 0xab, 0x3f, 0xfc, 0x73, 0xaf, 0x6f, 0x10, 0x7d, 0xe0, 0xcc, 0x57, 0xd8, ++ 0xf7, 0x8a, 0xd7, 0xc7, 0x33, 0x61, 0xad, 0x3e, 0xae, 0x7c, 0x95, 0xb5, ++ 0xc7, 0x85, 0xdf, 0x2f, 0x18, 0x4c, 0xe8, 0xfb, 0x5d, 0x46, 0xb7, 0x11, ++ 0x13, 0xf8, 0xaf, 0x2e, 0xc6, 0x60, 0x45, 0xc8, 0xd7, 0x7a, 0xe8, 0xc4, ++ 0xbf, 0x6f, 0x5e, 0x6a, 0x5b, 0x43, 0x9f, 0xd4, 0x60, 0xb4, 0x3f, 0x91, ++ 0x9e, 0xf9, 0xdb, 0x1e, 0x9e, 0xf7, 0x30, 0xde, 0x0d, 0x67, 0x55, 0x20, ++ 0x6e, 0x3c, 0x0e, 0xd9, 0x6e, 0x95, 0x35, 0x67, 0x48, 0xaf, 0x5e, 0xe8, ++ 0xea, 0x14, 0xe4, 0xd6, 0x95, 0xb9, 0x72, 0x28, 0x30, 0x52, 0x48, 0x89, ++ 0xc1, 0x53, 0x5b, 0x92, 0x89, 0xa6, 0xe4, 0xe4, 0x40, 0x62, 0x0b, 0xf3, ++ 0x90, 0xd9, 0x7e, 0x57, 0x2e, 0x95, 0x69, 0x8f, 0x73, 0x72, 0x79, 0x20, ++ 0xe1, 0x16, 0x85, 0xb8, 0x18, 0x57, 0x2e, 0x43, 0x36, 0xff, 0x70, 0x6e, ++ 0x97, 0x1c, 0x2a, 0xa8, 0x1f, 0xdc, 0x1b, 0x96, 0x97, 0xe5, 0xd2, 0xc0, ++ 0xcb, 0xb7, 0x2e, 0xb9, 0x93, 0x38, 0x53, 0xf2, 0xe1, 0x81, 0x6e, 0xb3, ++ 0x6f, 0xc5, 0x21, 0x09, 0xf3, 0x21, 0x5a, 0x53, 0x73, 0x56, 0x48, 0x7a, ++ 0x5f, 0xc4, 0x8b, 0xcb, 0xe1, 0x73, 0x07, 0xee, 0x33, 0xf5, 0x94, 0x80, ++ 0xbf, 0xcf, 0x30, 0xfc, 0x18, 0x3e, 0xe7, 0xd3, 0xc6, 0x9f, 0xa7, 0x2b, ++ 0x90, 0xbe, 0xd0, 0x26, 0xa1, 0x57, 0xbe, 0x0c, 0xba, 0x86, 0xe4, 0x40, ++ 0x7f, 0xa5, 0xf2, 0x0d, 0x37, 0x14, 0x9f, 0x44, 0x8c, 0x82, 0xfd, 0xcb, ++ 0xea, 0xd3, 0xed, 0xa0, 0x49, 0xb3, 0x44, 0x4f, 0xfb, 0xeb, 0xad, 0xf0, ++ 0xb0, 0x0c, 0xe7, 0x57, 0x1b, 0x5b, 0xe6, 0x63, 0x1b, 0xfc, 0xf9, 0x0c, ++ 0xa6, 0xac, 0xc7, 0xea, 0x0f, 0x78, 0xdf, 0x49, 0x78, 0xed, 0x7b, 0x03, ++ 0x0f, 0x86, 0x3a, 0x24, 0xe4, 0xfc, 0x70, 0x1d, 0xb1, 0x91, 0x0b, 0x05, ++ 0xbf, 0x1f, 0x7e, 0x62, 0xc8, 0xf7, 0x87, 0x65, 0xdb, 0xd2, 0x59, 0xcb, ++ 0xb6, 0x9e, 0xf9, 0x6f, 0x7a, 0x73, 0xa6, 0xbc, 0xb1, 0x88, 0x39, 0x62, ++ 0xab, 0xd4, 0x3e, 0x99, 0xb1, 0x9f, 0xc9, 0xb3, 0xfd, 0x89, 0x57, 0x15, ++ 0x27, 0x5b, 0x7d, 0x86, 0xf7, 0x11, 0x43, 0x96, 0xf5, 0x99, 0xd8, 0x6e, ++ 0xd0, 0x37, 0x13, 0xbb, 0xc7, 0x9e, 0xb5, 0x82, 0x01, 0xe3, 0x8f, 0x34, ++ 0xc9, 0x0f, 0xa2, 0xb0, 0xdb, 0x88, 0xf1, 0xb2, 0xcc, 0x7f, 0xb9, 0x77, ++ 0x3c, 0x3f, 0x85, 0x7d, 0x89, 0x53, 0x49, 0x6b, 0x02, 0xfb, 0xe3, 0x19, ++ 0x10, 0x03, 0x6a, 0x81, 0x4e, 0x5d, 0x78, 0x3f, 0xc4, 0x4f, 0xfd, 0xfe, ++ 0xfb, 0xaf, 0x86, 0x0e, 0xe3, 0xfe, 0x0d, 0x2e, 0x4c, 0x2c, 0xe6, 0x42, ++ 0x86, 0x3d, 0x0c, 0x6c, 0xad, 0xdc, 0xfa, 0xd8, 0x58, 0x1f, 0x4f, 0x47, ++ 0x8c, 0x52, 0x0c, 0x7e, 0x20, 0x65, 0x82, 0xbc, 0xd9, 0x89, 0xfe, 0x95, ++ 0xb7, 0x53, 0xfa, 0xea, 0x7e, 0xdf, 0x87, 0x55, 0x6c, 0xf7, 0x64, 0x61, ++ 0xaf, 0xc1, 0xe6, 0x59, 0x8b, 0x92, 0xea, 0x4e, 0xda, 0x27, 0xb0, 0xdf, ++ 0x74, 0x28, 0x51, 0xcc, 0x49, 0x4c, 0x66, 0xa1, 0x2f, 0xde, 0x80, 0xec, ++ 0x5f, 0x2b, 0xc7, 0x03, 0x69, 0xec, 0xe9, 0x60, 0x61, 0x48, 0x26, 0x2f, ++ 0xe8, 0x37, 0x5f, 0xd0, 0xfb, 0x43, 0x52, 0x2a, 0x24, 0xb6, 0xcc, 0x82, ++ 0xff, 0x66, 0x0b, 0xc4, 0x17, 0xf5, 0xc6, 0x47, 0x31, 0xe3, 0x42, 0x61, ++ 0x23, 0xec, 0x83, 0xa4, 0x2e, 0xc1, 0xff, 0xb9, 0x54, 0xde, 0x02, 0x3e, ++ 0xc3, 0xfd, 0xb2, 0x83, 0x5f, 0xe8, 0xcc, 0xf2, 0x00, 0xe4, 0x9c, 0x7b, ++ 0xb1, 0x65, 0x6e, 0x33, 0xce, 0x8e, 0x38, 0x22, 0xc5, 0x8f, 0xff, 0x07, ++ 0xe7, 0xeb, 0xbf, 0xf7, 0x76, 0xb5, 0xd3, 0xb3, 0xba, 0x2f, 0xd8, 0x65, ++ 0xc4, 0x00, 0xd9, 0x7e, 0x63, 0xb7, 0xd3, 0x91, 0x76, 0x49, 0xdf, 0x43, ++ 0x3b, 0xde, 0xa1, 0x31, 0xa2, 0xf2, 0x62, 0x84, 0xf7, 0xdf, 0x59, 0x67, ++ 0xe8, 0x17, 0x6e, 0x68, 0xbf, 0x8d, 0xdf, 0x36, 0xe9, 0x74, 0xf8, 0x6b, ++ 0xe3, 0xf7, 0xc6, 0x3a, 0xd6, 0x77, 0x3b, 0x9d, 0x24, 0xd6, 0xfa, 0x9d, ++ 0x97, 0x2f, 0xc0, 0xf5, 0x2c, 0x9f, 0x59, 0xeb, 0xad, 0xcb, 0x79, 0xdb, ++ 0x30, 0x4f, 0xab, 0xb7, 0x56, 0x9b, 0xe6, 0x27, 0xcd, 0x5a, 0x88, 0x71, ++ 0x0b, 0xef, 0xad, 0xd3, 0xef, 0x8c, 0x61, 0x2f, 0xea, 0xdb, 0x7f, 0x5d, ++ 0x47, 0xdc, 0x5c, 0xa7, 0xd3, 0xa6, 0x18, 0xcf, 0x9b, 0x1d, 0x1d, 0xb8, ++ 0xe6, 0x9a, 0x1c, 0x63, 0xf2, 0xe1, 0xa5, 0x32, 0xe7, 0x67, 0x3b, 0x25, ++ 0x47, 0x35, 0x9f, 0x61, 0xb0, 0x7c, 0xa5, 0xc2, 0xfd, 0x32, 0x79, 0x4e, ++ 0xf1, 0x75, 0x33, 0x79, 0x8b, 0xdf, 0xbd, 0xf0, 0x3b, 0x39, 0xfa, 0x12, ++ 0x63, 0x32, 0x81, 0xf3, 0xbb, 0x0c, 0x9f, 0x6a, 0xc1, 0x7c, 0x13, 0x8b, ++ 0xbf, 0xfd, 0x38, 0x97, 0x10, 0x64, 0x8c, 0x32, 0x4a, 0x99, 0xc2, 0xf9, ++ 0x8d, 0xdb, 0xf2, 0xee, 0x00, 0xe5, 0x79, 0x40, 0xae, 0x54, 0xe5, 0x39, ++ 0x07, 0x79, 0xa6, 0x2c, 0xe7, 0x20, 0xd3, 0x86, 0xaf, 0xf7, 0xf1, 0x1b, ++ 0x6b, 0x84, 0xeb, 0x25, 0xf5, 0x21, 0x2e, 0x82, 0xaf, 0x6d, 0x13, 0x97, ++ 0x2b, 0x2e, 0xfe, 0x30, 0xf4, 0x5a, 0x93, 0xf7, 0x1d, 0x00, 0xae, 0xaf, ++ 0xbc, 0x28, 0xe9, 0x0b, 0x2d, 0xd8, 0x77, 0xbc, 0x9b, 0x67, 0x96, 0xbd, ++ 0xc2, 0x7f, 0x9f, 0x17, 0x89, 0x37, 0xa5, 0x3f, 0xcb, 0x6b, 0xc6, 0x79, ++ 0xeb, 0x31, 0x66, 0x10, 0x74, 0x6e, 0xc1, 0xfc, 0xdc, 0xe3, 0x72, 0xe3, ++ 0x78, 0x3f, 0x54, 0x83, 0x4f, 0xf5, 0xe9, 0xbd, 0x4a, 0xd7, 0xcc, 0xea, ++ 0x37, 0x5a, 0x46, 0x06, 0x27, 0x0a, 0xe4, 0xfb, 0x18, 0xf8, 0x96, 0x3e, ++ 0x31, 0xf9, 0x25, 0xa5, 0xe7, 0x50, 0x2a, 0x90, 0x7f, 0x43, 0x9a, 0xc3, ++ 0xc8, 0xc2, 0xb6, 0xec, 0xd1, 0xf1, 0xb1, 0x25, 0xf9, 0xee, 0x0e, 0x68, ++ 0xdc, 0x9d, 0x2d, 0xac, 0x94, 0x1e, 0xd5, 0x41, 0xdd, 0x1e, 0x6f, 0xc3, ++ 0x5e, 0x28, 0x96, 0x7b, 0xbf, 0x1c, 0x29, 0x0f, 0x82, 0x0e, 0x31, 0x79, ++ 0x06, 0x7e, 0xf3, 0x73, 0xe5, 0xbb, 0x64, 0x31, 0x82, 0x7d, 0x55, 0x65, ++ 0x6c, 0x58, 0x9e, 0x9f, 0x8d, 0x7b, 0xd7, 0x09, 0x77, 0xd1, 0xda, 0x8e, ++ 0x3d, 0x50, 0x9e, 0x28, 0x57, 0x1c, 0x17, 0x44, 0x2c, 0xc2, 0x79, 0x8f, ++ 0x18, 0xdd, 0x86, 0x79, 0x8b, 0x11, 0xca, 0x2f, 0xf7, 0x16, 0xf2, 0x64, ++ 0x96, 0x71, 0x15, 0xdf, 0xd9, 0xd8, 0xa4, 0x4c, 0xdd, 0x59, 0x24, 0x14, ++ 0x07, 0xba, 0x74, 0x06, 0xfe, 0x3c, 0xbe, 0x5c, 0xfa, 0xdf, 0x51, 0x50, ++ 0x8f, 0xc2, 0x56, 0x16, 0x60, 0x2b, 0x0b, 0xb0, 0x91, 0x90, 0x85, 0x6b, ++ 0x05, 0xd8, 0xc8, 0x02, 0x6c, 0x24, 0xf4, 0xd9, 0x9b, 0x88, 0xed, 0xde, ++ 0x00, 0x0f, 0x19, 0x5f, 0xfb, 0x30, 0x7d, 0x6d, 0xfc, 0xfd, 0x17, 0xea, ++ 0x52, 0x61, 0x78, 0xd0, 0x71, 0x00, 0x00, 0x00 }; + + static const u32 bnx2_RXP_b06FwData[(0x0/4) + 1] = { 0x0 }; + static const u32 bnx2_RXP_b06FwRodata[(0x24/4) + 1] = { +- 0x08004c28, 0x08004c28, 0x08004ba0, 0x08004bd8, 0x08004c0c, 0x08004c30, +- 0x08004c30, 0x08004c30, 0x08004b10, 0x00000000 }; ++ 0x0800458c, 0x0800458c, 0x08004504, 0x0800453c, 0x08004570, 0x08004594, ++ 0x08004594, 0x08004594, 0x08004474, 0x00000000 }; + + static struct fw_info bnx2_rxp_fw_06 = { +- /* Firmware version: 4.6.16 */ ++ /* Firmware version: 4.4.2 */ + .ver_major = 0x4, +- .ver_minor = 0x6, +- .ver_fix = 0x10, ++ .ver_minor = 0x4, ++ .ver_fix = 0x2, + +- .start_addr = 0x080031d8, ++ .start_addr = 0x080031d0, + + .text_addr = 0x08000000, +- .text_len = 0x70dc, ++ .text_len = 0x71cc, + .text_index = 0x0, + .gz_text = bnx2_RXP_b06FwText, + .gz_text_len = sizeof(bnx2_RXP_b06FwText), +@@ -2935,15 +2966,15 @@ + .data_index = 0x0, + .data = bnx2_RXP_b06FwData, + +- .sbss_addr = 0x08007120, +- .sbss_len = 0x54, ++ .sbss_addr = 0x08007220, ++ .sbss_len = 0x58, + .sbss_index = 0x0, + +- .bss_addr = 0x08007178, +- .bss_len = 0x450, ++ .bss_addr = 0x08007278, ++ .bss_len = 0x44c, + .bss_index = 0x0, + +- .rodata_addr = 0x080070dc, ++ .rodata_addr = 0x080071cc, + .rodata_len = 0x24, + .rodata_index = 0x0, + .rodata = bnx2_RXP_b06FwRodata, +@@ -2966,571 +2997,639 @@ + }; + + static u8 bnx2_rv2p_proc1[] = { +- /* Date: 02/03/2009 14:20 */ +- 0xa5, 0x56, 0x4f, 0x68, 0x14, 0x67, 0x14, 0x7f, 0x33, 0xbb, 0xb3, 0xb3, +- 0x99, 0x9d, 0xd9, 0xdd, 0x92, 0x18, 0x96, 0x18, 0xcc, 0x1a, 0x84, 0x92, +- 0x75, 0xb7, 0x6e, 0x6c, 0x0f, 0x42, 0x03, 0x29, 0xb9, 0x08, 0x35, 0x87, +- 0x12, 0x11, 0x8a, 0x2d, 0x68, 0xb7, 0x22, 0x14, 0x0a, 0xa5, 0x07, 0x8f, +- 0xa5, 0x83, 0x71, 0x53, 0x5a, 0xbc, 0xe4, 0xd0, 0x80, 0x42, 0x35, 0x27, +- 0x5b, 0x62, 0x0e, 0x3b, 0xe0, 0xa1, 0x88, 0xe0, 0x41, 0x8f, 0x7a, 0xaa, +- 0x7f, 0x5a, 0x28, 0x46, 0x29, 0xb5, 0x87, 0x82, 0xc7, 0xde, 0x9a, 0xe9, +- 0xf7, 0xfe, 0x7c, 0xbb, 0x33, 0x5f, 0x66, 0x13, 0xa1, 0x42, 0xfc, 0xf1, +- 0xbd, 0x79, 0xef, 0xfb, 0xde, 0x9f, 0xdf, 0x7b, 0x6f, 0xab, 0x00, 0x60, +- 0x43, 0x18, 0x4d, 0x29, 0x04, 0x2b, 0x67, 0x15, 0x11, 0x00, 0x36, 0x81, +- 0xff, 0x39, 0x3e, 0x9d, 0xc3, 0x23, 0x72, 0x3e, 0xcc, 0x10, 0x1e, 0xae, +- 0xaa, 0xff, 0x3f, 0x85, 0xf9, 0x3a, 0x62, 0x0e, 0xe6, 0x0f, 0x22, 0x1e, +- 0x85, 0xbb, 0xf5, 0x9a, 0xc2, 0x7f, 0x63, 0x08, 0xf1, 0x1c, 0xf4, 0x7e, +- 0x8e, 0x4a, 0x74, 0xff, 0x96, 0xd8, 0xff, 0x9a, 0x63, 0x3c, 0xd6, 0xac, +- 0x12, 0x3e, 0x5a, 0xc5, 0xf7, 0x4e, 0x9d, 0x82, 0x02, 0xda, 0x5d, 0x50, +- 0x17, 0x23, 0x96, 0xd4, 0x83, 0x45, 0xb2, 0x03, 0xbb, 0xa2, 0x70, 0x12, +- 0x9e, 0x2f, 0xa0, 0xfe, 0x1b, 0xde, 0xa5, 0x55, 0xc4, 0x12, 0x74, 0x9a, +- 0xa8, 0x77, 0x00, 0xb2, 0xf5, 0x6a, 0x4a, 0x0f, 0xe5, 0x11, 0x84, 0x4d, +- 0xc4, 0x11, 0x80, 0x56, 0xf2, 0x3d, 0xd7, 0x0a, 0x5b, 0x68, 0xff, 0x85, +- 0xbc, 0xb7, 0x4f, 0xee, 0x51, 0x71, 0x47, 0x88, 0x3d, 0xb1, 0x53, 0x7f, +- 0x2d, 0x96, 0xb3, 0xfe, 0x67, 0x4a, 0x4f, 0xc7, 0xe3, 0x73, 0xde, 0xa6, +- 0x38, 0x1e, 0x57, 0xe2, 0x79, 0xb6, 0xaa, 0xf3, 0x86, 0xfa, 0xbf, 0xc7, +- 0x69, 0x7d, 0xd8, 0x43, 0xff, 0x89, 0xd2, 0x4f, 0xdf, 0xcb, 0xf2, 0x5f, +- 0x06, 0xf2, 0x99, 0xf4, 0xf7, 0xad, 0x06, 0xfa, 0xe7, 0x00, 0x34, 0x24, +- 0x8f, 0xa4, 0xff, 0x30, 0xe6, 0x78, 0xe6, 0xe0, 0x90, 0x5d, 0x23, 0xbd, +- 0x3c, 0xd4, 0x28, 0x3f, 0x1c, 0xef, 0x01, 0xc1, 0x25, 0xc1, 0x6b, 0x82, +- 0x3f, 0x08, 0xc2, 0xff, 0xc4, 0xad, 0x21, 0xf2, 0x7d, 0x82, 0xfb, 0x0d, +- 0xf9, 0x2d, 0xc1, 0xb7, 0x0c, 0x7b, 0xcf, 0x62, 0x7c, 0xac, 0xbf, 0xcb, +- 0xf9, 0x5d, 0xc3, 0xfe, 0x4b, 0xe0, 0xfc, 0x58, 0x46, 0xde, 0x36, 0x85, +- 0x87, 0x58, 0x77, 0xf9, 0x3e, 0xa3, 0xf5, 0x84, 0x37, 0x8d, 0xa4, 0xfe, +- 0x8d, 0x5d, 0xf4, 0x59, 0x6d, 0x61, 0x26, 0xcb, 0xee, 0x7a, 0x2c, 0x79, +- 0x14, 0x7b, 0xaf, 0x77, 0x67, 0x08, 0xef, 0xe7, 0x32, 0x79, 0x3f, 0x2e, +- 0x71, 0xa8, 0xa6, 0x23, 0xfb, 0xdb, 0x16, 0xf3, 0xdb, 0x11, 0x5e, 0xee, +- 0xc6, 0x63, 0xe1, 0xd5, 0x8c, 0xe6, 0x57, 0x9a, 0x57, 0xcc, 0x8f, 0x82, +- 0xc1, 0x8f, 0x6f, 0xf7, 0xc8, 0x4b, 0xc9, 0x88, 0x6f, 0x39, 0xd6, 0xf9, +- 0xb6, 0x45, 0x7c, 0xb1, 0x50, 0xa5, 0x7b, 0xbf, 0x8b, 0xe8, 0x38, 0xe6, +- 0xaf, 0xe0, 0x39, 0x0f, 0x97, 0x23, 0x6d, 0x27, 0xfd, 0xd4, 0xd0, 0xef, +- 0xb0, 0x7d, 0x20, 0x9f, 0x6d, 0x47, 0xfb, 0xc9, 0x72, 0x0f, 0xf0, 0x3c, +- 0xda, 0x5b, 0x37, 0xf2, 0x56, 0xa7, 0xb8, 0x41, 0xe2, 0x07, 0x23, 0x7e, +- 0x9d, 0xbf, 0x57, 0xc2, 0xf7, 0x49, 0x95, 0x0f, 0xfe, 0x3e, 0x05, 0xfa, +- 0x7e, 0x9c, 0x0b, 0x45, 0x38, 0x7b, 0xbc, 0x42, 0xfe, 0x94, 0x0b, 0x7c, +- 0xcd, 0x87, 0x15, 0xc6, 0x73, 0x1e, 0xe3, 0x9f, 0x9e, 0xca, 0x2d, 0xc4, +- 0xf1, 0xf9, 0x12, 0x9f, 0x3f, 0x09, 0xf0, 0xde, 0x51, 0xf5, 0xb0, 0xb6, +- 0xd7, 0x7e, 0xed, 0xe6, 0x0f, 0xbe, 0xaf, 0xdf, 0xd1, 0x7e, 0xe8, 0xf7, +- 0xd2, 0x75, 0x19, 0xfe, 0x2e, 0x63, 0xc7, 0x4e, 0xe7, 0x21, 0x3f, 0xcb, +- 0x78, 0xb5, 0x4d, 0x50, 0x5b, 0xf3, 0xd9, 0xee, 0x8a, 0x9f, 0xc7, 0xf3, +- 0x3b, 0x57, 0x1e, 0xe0, 0xfd, 0xf6, 0xd1, 0xb5, 0x48, 0xfc, 0xab, 0xe8, +- 0xba, 0x92, 0x1c, 0xa6, 0x81, 0xcf, 0x4b, 0xc2, 0x93, 0x25, 0xe2, 0x71, +- 0x59, 0x7d, 0x42, 0x9c, 0x80, 0xd0, 0x26, 0x3d, 0xef, 0x3e, 0xd9, 0xe7, +- 0x44, 0xae, 0xea, 0x37, 0x9d, 0xe6, 0xff, 0x16, 0xf3, 0xa2, 0x98, 0xe6, +- 0xd3, 0x7c, 0x62, 0xce, 0x25, 0xf3, 0x61, 0xf5, 0x79, 0xb4, 0xb3, 0x8e, +- 0xe9, 0x7a, 0x3d, 0x5a, 0xd5, 0xf9, 0x61, 0xbe, 0xb2, 0x9e, 0x2a, 0x56, +- 0x8b, 0xd5, 0xc3, 0xb6, 0x24, 0x72, 0x56, 0xbe, 0xb7, 0x4c, 0xde, 0x66, +- 0xf1, 0xbe, 0x6a, 0xf0, 0xb8, 0x21, 0xbc, 0x1f, 0xe9, 0xad, 0xbf, 0xd6, +- 0x7e, 0xb8, 0x29, 0xbc, 0xaf, 0x0e, 0xf6, 0xc3, 0x26, 0xed, 0x27, 0x75, +- 0x26, 0xf5, 0x5e, 0x98, 0x4b, 0xd5, 0xe9, 0x3d, 0xc8, 0xec, 0xef, 0xab, +- 0x72, 0x4f, 0x5b, 0xfa, 0xbc, 0x90, 0xd8, 0x23, 0xa4, 0x5e, 0x06, 0xf2, +- 0xc3, 0x35, 0xfa, 0x74, 0x2c, 0x96, 0x77, 0x54, 0xbf, 0x65, 0xc5, 0xeb, +- 0xc2, 0x5f, 0xc2, 0x83, 0x0e, 0xf5, 0x93, 0x33, 0xf6, 0xf9, 0xed, 0x54, +- 0x9d, 0x00, 0x0e, 0xea, 0xfd, 0x90, 0xf4, 0x2b, 0xb9, 0xdf, 0xf0, 0xbe, +- 0x1a, 0x74, 0x66, 0x93, 0x7b, 0xee, 0x72, 0xbf, 0xdf, 0x03, 0xea, 0xa3, +- 0xf2, 0x8e, 0xbe, 0xd4, 0xf3, 0xac, 0xde, 0x4c, 0xf6, 0xf7, 0x98, 0xcc, +- 0x2f, 0x5b, 0xf6, 0x73, 0xc9, 0x8c, 0x53, 0xed, 0xbd, 0xec, 0x7a, 0x71, +- 0xbc, 0xff, 0x6c, 0xbf, 0xde, 0xbc, 0xdb, 0xab, 0xee, 0x9e, 0x51, 0xf7, +- 0xbf, 0xb7, 0x75, 0x1e, 0x6d, 0x27, 0x6b, 0xbf, 0x7f, 0xa0, 0xee, 0x15, +- 0x7d, 0x99, 0x1b, 0x67, 0xea, 0x59, 0x7c, 0x2d, 0xee, 0xd0, 0x4b, 0xcf, +- 0x2f, 0xed, 0xe7, 0xc6, 0x06, 0xd7, 0xfd, 0xa3, 0xb8, 0xbf, 0x97, 0x52, +- 0xf3, 0x75, 0x44, 0xea, 0xac, 0xf4, 0xc8, 0xbf, 0xa7, 0xdb, 0x83, 0x79, +- 0x9c, 0xe4, 0xcd, 0x49, 0xe1, 0xab, 0x3d, 0xb7, 0x4e, 0xfd, 0xe1, 0x76, +- 0x5e, 0x1a, 0x75, 0x98, 0x6d, 0x62, 0xfd, 0xbf, 0x86, 0x48, 0xfc, 0xfc, +- 0x2d, 0xe5, 0x6f, 0x20, 0xfd, 0x55, 0x80, 0x9f, 0x22, 0x1d, 0x97, 0xae, +- 0x1b, 0xe3, 0x8f, 0x4d, 0xe9, 0x93, 0x7e, 0x7c, 0xf8, 0xee, 0xa2, 0xbc, +- 0x5b, 0x85, 0x1b, 0x91, 0x9e, 0x63, 0x38, 0xd7, 0x5c, 0x68, 0xcb, 0xdc, +- 0x3c, 0x2b, 0xf3, 0xeb, 0x85, 0xc7, 0xf3, 0xb1, 0x73, 0x82, 0x78, 0x08, +- 0xe3, 0x32, 0xc7, 0x3a, 0x01, 0x9f, 0x27, 0x02, 0xfe, 0x7d, 0xd8, 0x76, +- 0x7d, 0xd2, 0x9b, 0x08, 0x18, 0xc7, 0x4b, 0x68, 0x57, 0x83, 0x3f, 0x16, +- 0x49, 0xbd, 0x39, 0x98, 0x63, 0xe6, 0xfc, 0x92, 0x38, 0xdf, 0x46, 0xb9, +- 0xda, 0x93, 0xd3, 0x7c, 0xe6, 0x3a, 0xfb, 0x7d, 0x5e, 0x5f, 0x97, 0xaa, +- 0xd4, 0x2b, 0xc9, 0x3c, 0xeb, 0x3e, 0xba, 0x69, 0xe4, 0x57, 0xd7, 0xe7, +- 0xcd, 0x58, 0xcf, 0xf7, 0xe9, 0xe3, 0xe8, 0x6f, 0x05, 0xca, 0x2e, 0xf3, +- 0x82, 0x51, 0xdd, 0x63, 0xbb, 0x68, 0x36, 0xd9, 0x95, 0x79, 0xd8, 0xbd, +- 0x48, 0xd7, 0x2c, 0x76, 0xb5, 0x7c, 0x81, 0x1a, 0x61, 0x69, 0xe3, 0x1e, +- 0xc9, 0xcb, 0x51, 0x8e, 0xe5, 0xee, 0x09, 0x9d, 0xaf, 0x0a, 0xc5, 0xbf, +- 0xc6, 0xf9, 0xfa, 0xf8, 0x7b, 0xc6, 0xd3, 0xf0, 0x3e, 0xa1, 0x37, 0x98, +- 0xe3, 0x45, 0x42, 0x08, 0x92, 0x73, 0xdc, 0x51, 0xee, 0x55, 0xc9, 0x9f, +- 0x41, 0xfd, 0xcc, 0xfd, 0xb8, 0x5b, 0x1d, 0x47, 0x13, 0xfc, 0xd3, 0x75, +- 0x34, 0xe7, 0x39, 0xf1, 0xc4, 0xe0, 0x63, 0x77, 0x08, 0x1f, 0xad, 0x21, +- 0x7c, 0x36, 0xe7, 0xd6, 0x57, 0xd2, 0xc7, 0x79, 0x70, 0x72, 0xb4, 0x70, +- 0xfd, 0xfc, 0x32, 0xd5, 0xd5, 0xee, 0xf2, 0x0f, 0x08, 0xdf, 0x59, 0xb1, +- 0x28, 0x5f, 0xfe, 0x0a, 0xeb, 0xe5, 0x59, 0x5e, 0xd3, 0xf8, 0xcd, 0xb2, +- 0xfe, 0xbd, 0xf1, 0x1f, 0xb6, 0x34, 0x9b, 0xb9, 0xa0, 0x0c, 0x00, 0x00, +- 0x00 }; ++ /* Date: 05/13/2008 13:50 */ ++ 0xa5, 0x56, 0x4f, 0x48, 0x14, 0x61, 0x14, 0x7f, 0x3b, 0xfb, 0x67, 0xd6, ++ 0xdd, 0xd9, 0x9d, 0x25, 0xff, 0x6d, 0x66, 0xb8, 0x49, 0x97, 0xd5, 0x15, ++ 0xb5, 0x22, 0x3a, 0x18, 0x86, 0x17, 0x21, 0x3b, 0x84, 0x20, 0x45, 0x04, ++ 0xd9, 0x12, 0xde, 0x82, 0x0e, 0xd1, 0x29, 0x68, 0xd1, 0x34, 0x8a, 0x0a, ++ 0x16, 0x52, 0x30, 0xa2, 0xa4, 0x43, 0x85, 0x04, 0xed, 0x74, 0x0a, 0x12, ++ 0x82, 0x8a, 0x88, 0xea, 0x12, 0x78, 0xa8, 0x4b, 0x16, 0x61, 0xd0, 0xa1, ++ 0x83, 0x9d, 0xba, 0xe4, 0xf4, 0xbd, 0xef, 0xbd, 0xcf, 0x9d, 0xf9, 0x9c, ++ 0x55, 0x21, 0x41, 0x7f, 0xbc, 0x6f, 0xde, 0x7b, 0xdf, 0x9b, 0xdf, 0x7b, ++ 0xef, 0x37, 0x66, 0x00, 0xc0, 0x80, 0x92, 0xd3, 0x26, 0x10, 0x52, 0x46, ++ 0x28, 0x2e, 0x20, 0x04, 0xf0, 0x18, 0xe8, 0x27, 0x6a, 0x49, 0xbb, 0xd4, ++ 0xcd, 0x76, 0x27, 0x41, 0xa9, 0x33, 0x23, 0xfe, 0x9e, 0x85, 0xfe, 0x1c, ++ 0x62, 0x18, 0xfa, 0x77, 0x21, 0x1e, 0x84, 0x17, 0xb9, 0xac, 0xc0, 0xbf, ++ 0x2e, 0x94, 0xd0, 0x6e, 0xa8, 0x3c, 0x73, 0x92, 0x32, 0xff, 0x12, 0xc7, ++ 0x7f, 0x0a, 0x13, 0x1e, 0x28, 0xc4, 0x29, 0x0f, 0x23, 0x74, 0x65, 0x24, ++ 0x2c, 0x96, 0xd1, 0x1e, 0x19, 0x81, 0x18, 0xe6, 0x99, 0x12, 0x0e, 0x68, ++ 0xb7, 0x86, 0x4a, 0x5d, 0x5c, 0x97, 0x41, 0x7e, 0x5f, 0xca, 0x36, 0x9e, ++ 0xc3, 0xd7, 0x01, 0xb4, 0xb7, 0x27, 0x2e, 0x97, 0x11, 0xb3, 0x30, 0x16, ++ 0xb7, 0xe8, 0x7d, 0xda, 0x28, 0xed, 0x52, 0x07, 0xc6, 0x09, 0xdf, 0x0e, ++ 0xce, 0x1b, 0xc5, 0xbc, 0x3f, 0x5d, 0xca, 0x8b, 0xf9, 0xbc, 0x79, 0x5a, ++ 0x45, 0x1e, 0x3c, 0x8f, 0x71, 0x5d, 0x31, 0xad, 0xae, 0x98, 0xa8, 0x83, ++ 0x79, 0x00, 0x55, 0x07, 0x62, 0xa3, 0xb8, 0x17, 0xf3, 0xae, 0xf0, 0x7b, ++ 0x03, 0x9c, 0xca, 0x71, 0x7e, 0x07, 0xb1, 0xc2, 0xf9, 0xc4, 0x2f, 0xbf, ++ 0xc7, 0xfa, 0x3c, 0x8a, 0x27, 0x7f, 0xfd, 0x66, 0x41, 0x3d, 0x57, 0xfd, ++ 0xc0, 0x7b, 0x3e, 0x8a, 0x7b, 0xbc, 0xfe, 0xb0, 0x89, 0xff, 0x7b, 0xe1, ++ 0xef, 0xcf, 0x4b, 0xe7, 0x6f, 0xab, 0xe7, 0xf9, 0x20, 0xde, 0xa2, 0x1a, ++ 0x6f, 0x2f, 0x99, 0xb7, 0x41, 0xd8, 0x6d, 0x64, 0xa5, 0x5f, 0x04, 0x10, ++ 0x77, 0x88, 0x02, 0x10, 0x77, 0x32, 0x1e, 0x63, 0xbc, 0xc9, 0x78, 0x83, ++ 0xb1, 0x91, 0xb1, 0x81, 0xb1, 0x9e, 0x71, 0x1b, 0xe3, 0x3b, 0xc6, 0x0c, ++ 0xa3, 0xcd, 0x98, 0x66, 0x7c, 0xc3, 0x68, 0x31, 0x26, 0xb5, 0x7c, 0x2d, ++ 0x8c, 0x71, 0xc6, 0xbb, 0x8c, 0xfb, 0xb5, 0xf8, 0xdf, 0x8c, 0x0b, 0x8c, ++ 0xcd, 0x21, 0xc2, 0x43, 0x6c, 0x23, 0xa1, 0x3c, 0xf7, 0x3e, 0xbe, 0xee, ++ 0xaf, 0xf5, 0x77, 0xb1, 0xcc, 0xcf, 0xf3, 0xca, 0x2f, 0x2e, 0xf9, 0x83, ++ 0x0e, 0xaf, 0xff, 0x9d, 0x0d, 0xfc, 0xc9, 0x6d, 0x20, 0x1f, 0x14, 0x37, ++ 0xed, 0x52, 0x1d, 0xb7, 0x38, 0xbe, 0xbe, 0xb2, 0x50, 0x63, 0x8f, 0xfa, ++ 0x0a, 0xfa, 0x7c, 0x05, 0xed, 0xd1, 0x4e, 0xde, 0xa3, 0xa3, 0xeb, 0xe6, ++ 0x97, 0xe6, 0xd4, 0xbb, 0x87, 0x32, 0x4f, 0x8d, 0x39, 0x7f, 0x1a, 0x2a, ++ 0x16, 0xb2, 0x34, 0x17, 0xa5, 0x8d, 0xee, 0xc5, 0x78, 0x9e, 0xcb, 0xbc, ++ 0x9a, 0x4f, 0xff, 0x5c, 0xd2, 0x7c, 0xc5, 0xb4, 0xf9, 0xba, 0xb0, 0x09, ++ 0xbf, 0x49, 0x8d, 0xa7, 0x73, 0xae, 0xea, 0x97, 0xc1, 0xc7, 0xe3, 0xb1, ++ 0x8c, 0xcc, 0x7b, 0xcd, 0x91, 0x66, 0x83, 0x35, 0x85, 0x76, 0x04, 0xae, ++ 0x3b, 0x2a, 0x8e, 0xf7, 0xb2, 0x43, 0xdd, 0x43, 0xf1, 0x29, 0x20, 0x9e, ++ 0xe7, 0x34, 0x9e, 0x73, 0x5b, 0xd2, 0xa9, 0x15, 0xb7, 0xaa, 0x53, 0xf4, ++ 0xbc, 0x0d, 0xbc, 0x3a, 0x15, 0x87, 0xd1, 0x41, 0x5b, 0xde, 0x9b, 0x8e, ++ 0x51, 0x9a, 0xe3, 0x36, 0xe1, 0x99, 0x04, 0xe1, 0x72, 0xa2, 0x4e, 0xfc, ++ 0x75, 0xdd, 0xb1, 0x24, 0xd9, 0xa7, 0x53, 0x6a, 0x3f, 0x54, 0xbc, 0xaa, ++ 0x6b, 0xa3, 0x7a, 0xf0, 0x7e, 0x75, 0x8f, 0xaa, 0x43, 0xdd, 0xe7, 0xe7, ++ 0xbf, 0xf6, 0xbd, 0x84, 0x45, 0xc3, 0xcf, 0xc3, 0xed, 0x1e, 0xc2, 0x48, ++ 0xaf, 0x84, 0xec, 0x8c, 0x45, 0x71, 0xb3, 0x56, 0x04, 0xed, 0x7d, 0xb3, ++ 0x1f, 0x30, 0xbf, 0xb1, 0x67, 0xc6, 0xe1, 0xfa, 0x6c, 0xd5, 0x3f, 0x79, ++ 0x0e, 0xed, 0x40, 0xf6, 0x30, 0xcf, 0xc3, 0xb0, 0x9c, 0x7b, 0xb1, 0xd7, ++ 0x06, 0x62, 0x0b, 0x94, 0xa4, 0xae, 0x1b, 0x89, 0xd7, 0x32, 0x3e, 0xcc, ++ 0xe7, 0xa2, 0x4f, 0xed, 0xfe, 0x7d, 0x59, 0xa2, 0xfe, 0xc7, 0xfd, 0x73, ++ 0xd3, 0xed, 0x06, 0xcf, 0x63, 0xa2, 0x32, 0x57, 0x0e, 0xea, 0xd7, 0x73, ++ 0xd6, 0xbd, 0x2c, 0x14, 0x7b, 0x6b, 0xe9, 0xb1, 0xfa, 0x0e, 0x2a, 0x3d, ++ 0x92, 0xc7, 0x95, 0x52, 0xd8, 0xc7, 0xcb, 0x21, 0x28, 0x04, 0xe5, 0x7f, ++ 0xa2, 0xbe, 0x2f, 0x01, 0x7b, 0xb4, 0xd9, 0xbd, 0xbe, 0xfc, 0x69, 0x28, ++ 0x04, 0xed, 0x81, 0xa9, 0xed, 0x8d, 0xcd, 0x7b, 0xd3, 0xbc, 0x6e, 0x7e, ++ 0x95, 0x4e, 0xe4, 0x36, 0xd4, 0x89, 0xff, 0xd5, 0x05, 0x03, 0x48, 0x17, ++ 0x50, 0x8f, 0xfd, 0xf7, 0x9b, 0xaa, 0x7e, 0x6d, 0xff, 0xa9, 0xee, 0x3f, ++ 0xab, 0x5b, 0xd3, 0x11, 0xef, 0xfb, 0x07, 0xe9, 0x48, 0x42, 0xd3, 0x85, ++ 0x5f, 0xab, 0x55, 0x1d, 0xc1, 0xe7, 0xf3, 0xf3, 0xd4, 0x97, 0x8b, 0xee, ++ 0x9a, 0xae, 0xfb, 0xf8, 0xac, 0x63, 0x3e, 0x85, 0x9f, 0x8c, 0x5f, 0xd6, ++ 0xe2, 0x55, 0x5f, 0xcf, 0x33, 0xcf, 0x46, 0x1f, 0xcd, 0x95, 0x59, 0xfc, ++ 0xa1, 0xf1, 0xdd, 0x5b, 0xc0, 0xbd, 0xb8, 0x04, 0x0e, 0xf3, 0xf6, 0xd9, ++ 0xc7, 0x5f, 0x8a, 0xf5, 0xc1, 0x84, 0x47, 0x8e, 0xe2, 0x59, 0xf5, 0x87, ++ 0xf0, 0xa1, 0xf4, 0xcf, 0x6c, 0xc2, 0x77, 0x06, 0x1e, 0x38, 0x6a, 0xbf, ++ 0x6d, 0x99, 0xaf, 0x87, 0xf5, 0x64, 0x94, 0xf7, 0xfa, 0x5b, 0x82, 0x74, ++ 0xa3, 0x38, 0x24, 0xf7, 0x14, 0x9a, 0x78, 0xbf, 0x8b, 0x29, 0xb2, 0x5b, ++ 0x52, 0xf4, 0x7f, 0x5b, 0x8f, 0x69, 0x49, 0xbf, 0x96, 0x14, 0x61, 0x53, ++ 0x12, 0xe3, 0xb2, 0xf0, 0xfd, 0x88, 0x74, 0x2f, 0x54, 0xf7, 0x5b, 0xdf, ++ 0x6b, 0x7e, 0xdf, 0xbd, 0x78, 0xde, 0x24, 0xf6, 0xd4, 0xdb, 0x0f, 0x6b, ++ 0x4d, 0x5f, 0xef, 0x71, 0xf5, 0x39, 0xdb, 0xcb, 0xb7, 0x9a, 0xdb, 0x67, ++ 0x35, 0xfa, 0x34, 0xe8, 0x2a, 0xdd, 0x6b, 0x1f, 0xc4, 0x7a, 0x6d, 0x48, ++ 0x9b, 0x34, 0x1f, 0x84, 0x22, 0x8f, 0x61, 0x62, 0x58, 0xeb, 0x24, 0xeb, ++ 0xc4, 0xe4, 0xb8, 0x4c, 0x73, 0x64, 0x52, 0x9d, 0x0f, 0xc8, 0xc1, 0x1f, ++ 0x9e, 0x7f, 0x25, 0xcf, 0xd3, 0x4e, 0x98, 0xce, 0xcd, 0x21, 0xc5, 0x97, ++ 0x2d, 0xdf, 0x7f, 0x86, 0xf8, 0x3a, 0x39, 0x4d, 0x78, 0x02, 0x0e, 0x4b, ++ 0x4c, 0x54, 0xf5, 0x2d, 0x2e, 0x11, 0x52, 0x5e, 0x7d, 0x8b, 0x8a, 0xf2, ++ 0xd0, 0xae, 0xf3, 0xf4, 0x51, 0xff, 0x6e, 0x6c, 0xb5, 0x9f, 0x5e, 0x9d, ++ 0xc4, 0x7e, 0xea, 0x7a, 0x27, 0xe7, 0x46, 0x9b, 0xcf, 0x72, 0x8d, 0xf9, ++ 0xcc, 0xd5, 0x98, 0x6f, 0x5d, 0x2f, 0xae, 0xf2, 0xde, 0x45, 0x20, 0x1a, ++ 0x96, 0x1f, 0x24, 0x2b, 0x32, 0x21, 0xfb, 0x6b, 0x4c, 0xd2, 0x87, 0xd4, ++ 0x8a, 0x4e, 0x85, 0x24, 0x6f, 0xd6, 0x14, 0xf9, 0x45, 0xe8, 0x3c, 0xab, ++ 0xf0, 0xca, 0x84, 0xfa, 0xee, 0xfe, 0x03, 0x65, 0x6c, 0x9a, 0x59, 0x40, ++ 0x0c, 0x00, 0x00, 0x00 }; + + static u8 bnx2_rv2p_proc2[] = { +- /* Date: 02/03/2009 14:20 */ +- 0xad, 0x57, 0x4d, 0x68, 0x5c, 0x55, 0x14, 0x3e, 0xf3, 0xe6, 0xef, 0xcd, +- 0xcc, 0x9b, 0xcc, 0x34, 0x8d, 0x93, 0x31, 0x29, 0x26, 0x4d, 0x68, 0xea, +- 0xc8, 0x44, 0xf3, 0x47, 0x05, 0x5d, 0x18, 0x46, 0x48, 0x7f, 0x2c, 0x34, +- 0x8d, 0x2e, 0x8a, 0x9b, 0x36, 0x53, 0x3b, 0x3a, 0x6d, 0xed, 0xc2, 0xec, +- 0xdc, 0xf8, 0xb0, 0x35, 0x41, 0x98, 0x45, 0x53, 0x4c, 0x13, 0x44, 0xa8, +- 0xe8, 0xce, 0xdd, 0x88, 0x9a, 0xd6, 0x8d, 0x50, 0x68, 0x28, 0x76, 0x51, +- 0x04, 0x05, 0xed, 0x42, 0x10, 0xad, 0xa1, 0x15, 0x41, 0x51, 0xb3, 0x92, +- 0x8c, 0xf7, 0x9e, 0xef, 0xdc, 0x37, 0xef, 0x4d, 0xa6, 0xa4, 0x0b, 0x67, +- 0xf3, 0xe5, 0xdc, 0x77, 0xee, 0xb9, 0xe7, 0xe7, 0x3b, 0xe7, 0xde, 0x64, +- 0x89, 0x28, 0x42, 0x6e, 0xbd, 0x4f, 0x21, 0x85, 0xc2, 0x21, 0x5b, 0x41, +- 0x83, 0x28, 0x9a, 0xd7, 0x32, 0x59, 0x24, 0xbf, 0x27, 0xb2, 0x0c, 0xdf, +- 0xd6, 0x1d, 0xad, 0x46, 0x6e, 0x41, 0xeb, 0xd9, 0xf4, 0x92, 0x05, 0xbd, +- 0x08, 0x69, 0x54, 0x3a, 0xae, 0xc6, 0x1d, 0x82, 0xcf, 0x08, 0x46, 0x42, +- 0xc0, 0xb0, 0xa0, 0xd5, 0x82, 0x24, 0x7a, 0x5d, 0x22, 0x6f, 0x8a, 0xec, +- 0x08, 0xe6, 0x65, 0xfd, 0xb4, 0xe0, 0xab, 0xb2, 0x7e, 0x47, 0x70, 0x5d, +- 0xa1, 0xf1, 0x53, 0xcb, 0xbf, 0x35, 0x9a, 0xb2, 0x03, 0xf3, 0x05, 0xf8, +- 0xff, 0x62, 0x3f, 0xeb, 0x37, 0x82, 0xfa, 0x77, 0x1b, 0xc6, 0x0f, 0x13, +- 0xaf, 0x15, 0xd5, 0xfa, 0xbb, 0x27, 0x2e, 0x2f, 0x62, 0xdf, 0xf1, 0x7e, +- 0xac, 0x3f, 0x56, 0xd4, 0x71, 0xc7, 0xc8, 0x15, 0xa4, 0x61, 0x9b, 0xe3, +- 0x70, 0x87, 0x4d, 0xa2, 0xa0, 0xff, 0xe3, 0x22, 0xa4, 0xd9, 0x34, 0xec, +- 0x26, 0x03, 0x76, 0x73, 0x5b, 0xec, 0x7e, 0x9f, 0xf0, 0xdb, 0xff, 0x54, +- 0xec, 0x27, 0xb7, 0xb5, 0x5f, 0x4e, 0x03, 0x77, 0x16, 0xdb, 0x9d, 0x93, +- 0xd8, 0xc6, 0xff, 0xd3, 0xdb, 0xda, 0x7f, 0xd3, 0xf3, 0xdf, 0xac, 0x03, +- 0xfb, 0xf0, 0xf9, 0x13, 0xf7, 0x29, 0x93, 0x47, 0x13, 0xaf, 0xf8, 0x15, +- 0x06, 0x4e, 0x16, 0x19, 0x6a, 0x27, 0x25, 0xb1, 0x53, 0x43, 0xfa, 0xbc, +- 0x4e, 0x8a, 0x58, 0xda, 0xce, 0x5e, 0x3b, 0x76, 0x0d, 0xeb, 0xc7, 0x32, +- 0xc0, 0x57, 0x24, 0x80, 0xbb, 0x49, 0x9d, 0x90, 0x46, 0xa3, 0x92, 0x12, +- 0xfb, 0x28, 0x23, 0xb9, 0x29, 0xec, 0x5f, 0x73, 0xb4, 0x5f, 0xb7, 0x54, +- 0xdd, 0xb4, 0x1c, 0x26, 0x37, 0x13, 0xf4, 0xff, 0x0a, 0x41, 0x6f, 0xc7, +- 0x5e, 0xac, 0x5e, 0xac, 0x40, 0xee, 0xfd, 0x38, 0xcb, 0xfa, 0x2b, 0x75, +- 0x13, 0x87, 0x5e, 0x57, 0xfc, 0xcf, 0xc0, 0x0e, 0x0d, 0xd8, 0x7c, 0x18, +- 0xf2, 0xa3, 0x0e, 0x1d, 0x36, 0xf6, 0xf0, 0xbb, 0xbc, 0xc7, 0xf0, 0x09, +- 0x72, 0x25, 0xc6, 0x90, 0x9f, 0x9d, 0xd7, 0xfe, 0x66, 0xe8, 0x84, 0xa5, +- 0x1d, 0xb1, 0x24, 0xbe, 0xb0, 0xed, 0x7c, 0x01, 0xfd, 0xaf, 0xfa, 0x1c, +- 0xf6, 0xad, 0x32, 0x8e, 0x7d, 0x5d, 0x63, 0xc0, 0xa5, 0xb1, 0xa8, 0x86, +- 0x62, 0x65, 0x8e, 0xc5, 0x27, 0x7f, 0x1e, 0xb5, 0x59, 0xcf, 0x1d, 0x36, +- 0x7c, 0x35, 0x79, 0xd7, 0xf1, 0x5e, 0x6c, 0xf2, 0x76, 0x10, 0xf9, 0xf9, +- 0x75, 0x8f, 0xd6, 0x57, 0x49, 0x1a, 0xc0, 0x39, 0x33, 0xd5, 0x76, 0x7c, +- 0x7f, 0x57, 0xed, 0x7b, 0xb8, 0xfa, 0x4d, 0x72, 0xdc, 0x93, 0x12, 0x7f, +- 0xbf, 0xf0, 0x63, 0x57, 0x1b, 0x7e, 0x64, 0xf8, 0xef, 0xfb, 0xa5, 0x2c, +- 0xe7, 0xef, 0x08, 0xd6, 0x2f, 0x4d, 0xad, 0x22, 0xcf, 0x07, 0x39, 0x7e, +- 0x4a, 0x5e, 0xf8, 0x1c, 0xbb, 0x66, 0xd3, 0x5a, 0x7e, 0x79, 0xa2, 0xf2, +- 0x25, 0xe4, 0x72, 0x58, 0xcb, 0xc7, 0x9c, 0x93, 0x57, 0xa1, 0x1f, 0x3d, +- 0x9f, 0xe5, 0xbc, 0x1d, 0x91, 0x53, 0x0e, 0xaa, 0x51, 0xa1, 0x7e, 0xb5, +- 0xd8, 0x79, 0x16, 0x9d, 0x35, 0xfe, 0x9e, 0xa5, 0x85, 0x3a, 0xbe, 0x9f, +- 0x4b, 0xe9, 0xb8, 0xce, 0xa8, 0xb8, 0x58, 0xaf, 0xab, 0x1a, 0xc3, 0xfe, +- 0xda, 0xa2, 0xb6, 0x17, 0xa2, 0x7b, 0x9f, 0x69, 0xf9, 0x70, 0xf1, 0x1e, +- 0xf4, 0x8b, 0xd5, 0x79, 0x31, 0x6c, 0x21, 0x6f, 0xf7, 0x2d, 0xe8, 0x0b, +- 0xad, 0x92, 0x11, 0xae, 0x5b, 0x88, 0x9c, 0x29, 0xe0, 0x3b, 0xfc, 0xfd, +- 0xdf, 0x50, 0x8d, 0xf3, 0xf5, 0x7c, 0x47, 0x64, 0xd5, 0xe4, 0x47, 0x30, +- 0x63, 0xe2, 0x02, 0x3e, 0x2c, 0x6f, 0xe7, 0x1d, 0xc3, 0x57, 0xa9, 0x57, +- 0xe1, 0x41, 0x7c, 0x05, 0x4e, 0x0d, 0x01, 0x63, 0x83, 0x5a, 0x2f, 0xda, +- 0x86, 0xb7, 0xc1, 0xba, 0x48, 0x5d, 0x7d, 0xfc, 0x62, 0x50, 0xbc, 0x0a, +- 0xf0, 0x4c, 0xf1, 0x98, 0xe7, 0x90, 0xca, 0xa7, 0xe1, 0x8b, 0x36, 0x14, +- 0xa7, 0x33, 0x62, 0xaf, 0x2a, 0x71, 0x9d, 0x95, 0xb8, 0x7e, 0x4f, 0x9a, +- 0xbc, 0x9b, 0x78, 0x80, 0x0b, 0x5e, 0x3c, 0x86, 0x6f, 0xb8, 0x1f, 0x66, +- 0xaa, 0x01, 0x7f, 0x6a, 0x37, 0x06, 0xf0, 0x47, 0xef, 0x20, 0xd0, 0x8b, +- 0x73, 0x88, 0xfb, 0xa4, 0xa3, 0xfb, 0xaa, 0xf1, 0x43, 0xd7, 0x75, 0x43, +- 0xf8, 0x6a, 0xa9, 0x78, 0xfd, 0xfd, 0xd9, 0xd3, 0xa6, 0x3f, 0x83, 0xfd, +- 0x62, 0xe2, 0x3f, 0x97, 0xe6, 0x01, 0x34, 0x71, 0x7b, 0x3d, 0xd8, 0x0f, +- 0xe0, 0x7f, 0xdc, 0xe3, 0x51, 0xd7, 0x3e, 0xc9, 0x93, 0x60, 0xee, 0x69, +- 0x6d, 0x6f, 0x5a, 0xec, 0x8f, 0x88, 0x7d, 0xc7, 0xd7, 0x8f, 0xda, 0xbf, +- 0x3e, 0xaf, 0x0f, 0x4d, 0x7d, 0x9a, 0xfd, 0x68, 0xf2, 0xc4, 0xe7, 0x17, +- 0x6f, 0xaf, 0xeb, 0xfd, 0xbd, 0xdb, 0xf4, 0xe7, 0x23, 0x9e, 0xbd, 0xef, +- 0xbc, 0x7e, 0xd4, 0xdf, 0x53, 0xf4, 0x9c, 0x88, 0xc1, 0x39, 0xf3, 0x87, +- 0x9a, 0x33, 0x1c, 0x87, 0xed, 0xac, 0xca, 0x5c, 0x99, 0xd3, 0xe7, 0xe4, +- 0xc5, 0xef, 0xbc, 0x99, 0xeb, 0xca, 0x6f, 0x99, 0x3f, 0xc7, 0xfd, 0x73, +- 0x24, 0xde, 0xe6, 0x3c, 0xc0, 0x64, 0xb1, 0x35, 0x5f, 0xc8, 0x3b, 0xec, +- 0xaa, 0xfc, 0x9b, 0x39, 0x30, 0x6e, 0xec, 0x43, 0x74, 0x47, 0xfd, 0xfa, +- 0xad, 0xf5, 0x89, 0x3c, 0x60, 0x9e, 0x6d, 0x6c, 0xe2, 0xde, 0xfd, 0x67, +- 0xb3, 0x79, 0x1f, 0x07, 0xea, 0xe8, 0x12, 0xd7, 0x3d, 0xae, 0xea, 0xcf, +- 0xef, 0x03, 0xef, 0x9e, 0xb7, 0xa2, 0x7a, 0x5d, 0xe5, 0x42, 0x78, 0xf5, +- 0xfa, 0xe3, 0xb2, 0xbf, 0x80, 0xb9, 0xf4, 0xda, 0x29, 0xce, 0xff, 0x7b, +- 0x67, 0x37, 0x78, 0x3e, 0x7d, 0xf8, 0xc6, 0x35, 0x1d, 0xd7, 0xa3, 0xb4, +- 0x3e, 0xe7, 0xb0, 0x3f, 0xa5, 0xdd, 0x50, 0xdf, 0x78, 0xb6, 0xb5, 0x1e, +- 0x78, 0xd7, 0xa0, 0x5e, 0x4a, 0x6f, 0x36, 0x78, 0xaf, 0x36, 0xfd, 0x43, +- 0xbf, 0xec, 0xcf, 0x40, 0xdf, 0xf4, 0x73, 0xb0, 0xae, 0x77, 0x36, 0x9b, +- 0x73, 0xd7, 0xe4, 0x3b, 0xc8, 0xd3, 0xa3, 0xe3, 0x7e, 0xbb, 0x83, 0xb4, +- 0x56, 0x87, 0xdd, 0x69, 0xe9, 0xc3, 0x13, 0x72, 0xf0, 0x4f, 0xc9, 0x0c, +- 0x9f, 0x53, 0x7e, 0x81, 0x79, 0x46, 0xb9, 0x14, 0xe2, 0x2c, 0x1f, 0xc6, +- 0xf7, 0x72, 0x1a, 0xeb, 0x3d, 0x69, 0xdc, 0x6f, 0xd3, 0x71, 0x87, 0xf5, +- 0x7b, 0xd2, 0xc0, 0x9c, 0xf4, 0xeb, 0x9a, 0x37, 0x8f, 0x80, 0x2b, 0x31, +- 0x7f, 0xff, 0x46, 0xe8, 0x7a, 0x4c, 0x2b, 0xa8, 0xcb, 0xba, 0x80, 0xfe, +- 0x2b, 0x0d, 0x39, 0xfc, 0x7d, 0xa6, 0x80, 0xb9, 0x4a, 0x03, 0xc1, 0xfb, +- 0x50, 0xfa, 0xb9, 0xa7, 0x39, 0xb7, 0xfc, 0x73, 0x2d, 0x31, 0xb6, 0x5c, +- 0x0f, 0xde, 0x97, 0x2b, 0x31, 0xff, 0x9c, 0xd0, 0x76, 0x59, 0x54, 0xf3, +- 0xc1, 0x3f, 0xd7, 0xc2, 0x52, 0xef, 0xbf, 0x64, 0x0e, 0xec, 0xa4, 0x9b, +- 0x75, 0xc4, 0xb5, 0x56, 0x6f, 0xcd, 0xb3, 0x39, 0xcf, 0xd8, 0x83, 0xdf, +- 0x26, 0x8e, 0xa6, 0x7d, 0x9c, 0x7f, 0x4a, 0xfc, 0xfc, 0x85, 0xdf, 0x21, +- 0x39, 0x89, 0x47, 0xdb, 0xc5, 0xfa, 0x01, 0x99, 0xb3, 0xae, 0x27, 0x07, +- 0xe7, 0xe3, 0x34, 0xfb, 0xd5, 0x49, 0x78, 0x77, 0xe4, 0xbc, 0xbe, 0x36, +- 0xf1, 0x75, 0x8d, 0x00, 0x97, 0x46, 0x4c, 0x1d, 0x4c, 0xbd, 0x4c, 0x7d, +- 0x50, 0xc7, 0xdc, 0x28, 0xab, 0x4d, 0x94, 0x47, 0x99, 0xa7, 0x23, 0xe5, +- 0x3f, 0x83, 0xef, 0xb4, 0xa3, 0x45, 0xad, 0xff, 0x16, 0x7d, 0xc3, 0x7d, +- 0x44, 0xf4, 0x83, 0x60, 0x73, 0x1e, 0x49, 0x01, 0x02, 0xef, 0xb2, 0x30, +- 0x5d, 0x8f, 0xca, 0xf2, 0xb8, 0xe9, 0x9b, 0x60, 0xdf, 0x5d, 0xe1, 0x77, +- 0xfa, 0xc2, 0xe6, 0xd6, 0xfe, 0x37, 0xf1, 0x69, 0xbd, 0x61, 0xe1, 0xa1, +- 0x4d, 0xa5, 0xfd, 0x78, 0xd7, 0x74, 0xc4, 0xc1, 0xf3, 0x8e, 0xb8, 0xbf, +- 0x4e, 0x8a, 0x0f, 0x89, 0xb8, 0x16, 0x77, 0x75, 0x26, 0x38, 0x8e, 0x4b, +- 0x5f, 0xdf, 0xe2, 0xcf, 0x1f, 0x2d, 0xa7, 0xb0, 0xde, 0x5d, 0x82, 0xf9, +- 0x08, 0xf3, 0x35, 0x4c, 0x17, 0xc0, 0xe7, 0x0f, 0x96, 0x80, 0xef, 0xd3, +- 0x21, 0xd8, 0xe9, 0x7c, 0x9b, 0xef, 0x71, 0xbb, 0x1b, 0xe9, 0xac, 0x2d, +- 0x0b, 0x4f, 0xf3, 0x16, 0xff, 0x3f, 0xd2, 0xa0, 0xb4, 0xbc, 0x5b, 0xa5, +- 0xcf, 0xc0, 0xcf, 0x88, 0xaf, 0xce, 0xdb, 0xf1, 0x55, 0xa3, 0xa3, 0xf8, +- 0x88, 0xed, 0xc2, 0x5b, 0xbb, 0x95, 0xb7, 0xa6, 0x8e, 0x79, 0xab, 0x2d, +- 0x4f, 0xf7, 0x05, 0x79, 0x1a, 0x13, 0x9e, 0xfe, 0xed, 0xcd, 0xd3, 0xad, +- 0x76, 0x31, 0xc7, 0x6f, 0xfe, 0x6f, 0xbc, 0x05, 0x1e, 0x18, 0xd4, 0xe7, +- 0x77, 0xfb, 0xf8, 0x67, 0xfc, 0xf2, 0xcf, 0x9f, 0x43, 0x6a, 0xae, 0xfe, +- 0x07, 0x92, 0xe2, 0x88, 0x7c, 0xe0, 0x0d, 0x00, 0x00, 0x00 }; ++ /* Date: 05/13/2008 13:50 */ ++ 0xad, 0x58, 0x4d, 0x6c, 0x54, 0x55, 0x14, 0xbe, 0x7d, 0xf3, 0xdb, 0x99, ++ 0x37, 0x3f, 0xb4, 0xb5, 0xbf, 0x68, 0xa1, 0x95, 0xd2, 0x92, 0x29, 0x94, ++ 0x69, 0x01, 0x95, 0x44, 0x49, 0x31, 0x05, 0x94, 0x84, 0x52, 0x5d, 0x10, ++ 0x37, 0xd0, 0x22, 0xa5, 0x83, 0x2d, 0x69, 0x28, 0x61, 0xc1, 0xc6, 0x09, ++ 0xc5, 0xe2, 0x62, 0x12, 0x2d, 0xb1, 0x14, 0x8c, 0xc1, 0x46, 0x37, 0xc4, ++ 0xb8, 0x19, 0x83, 0x52, 0xd4, 0xc4, 0x84, 0x60, 0x43, 0x70, 0x01, 0x26, ++ 0x9a, 0xe0, 0x42, 0x13, 0xa2, 0x50, 0x0b, 0x36, 0x58, 0x7e, 0x46, 0x17, ++ 0xca, 0x78, 0xef, 0xf9, 0xce, 0x7d, 0x7d, 0x6f, 0x3a, 0xb5, 0x2c, 0xe8, ++ 0xe6, 0xeb, 0xbd, 0xef, 0xdc, 0x73, 0xcf, 0xcf, 0x77, 0xcf, 0x39, 0x6d, ++ 0x54, 0x08, 0xe1, 0x16, 0xc9, 0x74, 0xb5, 0x44, 0x11, 0x32, 0x0a, 0xfc, ++ 0x12, 0xb2, 0x42, 0x78, 0xca, 0xd5, 0x5a, 0x18, 0x82, 0x7f, 0x56, 0x44, ++ 0x09, 0x7e, 0x48, 0xab, 0xef, 0x3e, 0xf1, 0xaa, 0x81, 0xef, 0x6e, 0xa1, ++ 0x30, 0x22, 0x44, 0x52, 0x61, 0x94, 0x71, 0x3d, 0x63, 0x86, 0x31, 0x58, ++ 0x00, 0x6c, 0x66, 0x7c, 0xc0, 0xfb, 0x77, 0x78, 0x7d, 0x93, 0xf1, 0x6f, ++ 0xde, 0x37, 0x19, 0x6f, 0xf3, 0xfe, 0xf3, 0x06, 0x30, 0xc1, 0xfb, 0x3f, ++ 0x4b, 0xd4, 0x76, 0xa9, 0xf5, 0x74, 0x56, 0x24, 0xe5, 0x19, 0x21, 0xc5, ++ 0x1b, 0xf4, 0xbe, 0x49, 0x90, 0x6c, 0x80, 0xdd, 0xaf, 0x2c, 0x51, 0x72, ++ 0xbf, 0xe7, 0x91, 0x53, 0xfb, 0x37, 0xb2, 0xd0, 0x3b, 0xeb, 0xaf, 0xe1, ++ 0x51, 0xe7, 0x96, 0xb6, 0x9c, 0x18, 0xc6, 0xf9, 0x9d, 0x4b, 0xb0, 0xff, ++ 0x54, 0x4c, 0xf9, 0xef, 0x15, 0x49, 0x46, 0xd1, 0xa8, 0xd0, 0x28, 0x48, ++ 0x36, 0xea, 0x40, 0x41, 0xfe, 0x97, 0x61, 0xac, 0x3a, 0x43, 0xd0, 0x1b, ++ 0x70, 0xe8, 0x2d, 0x9d, 0xa3, 0xf7, 0x5a, 0xa1, 0x5d, 0xff, 0x67, 0xac, ++ 0x3f, 0xb0, 0xa0, 0xfe, 0xae, 0x10, 0xb0, 0x38, 0x96, 0xef, 0x9e, 0xc2, ++ 0x05, 0xec, 0xdf, 0xb7, 0xa0, 0xfe, 0xc3, 0x96, 0xfd, 0x3a, 0x6e, 0xfa, ++ 0x3b, 0xb0, 0x1a, 0x62, 0x9f, 0x24, 0x57, 0xe9, 0x78, 0x6a, 0xbf, 0xd9, ++ 0x3e, 0x17, 0x70, 0x43, 0x8c, 0x20, 0xb5, 0x9b, 0x03, 0xdc, 0x56, 0xa7, ++ 0xee, 0x2d, 0x12, 0x6e, 0x43, 0xe9, 0x59, 0xee, 0xf7, 0x9e, 0xc7, 0xfe, ++ 0x8e, 0x08, 0xf0, 0x75, 0x76, 0xe4, 0x46, 0x40, 0x05, 0x26, 0x9b, 0xed, ++ 0x0e, 0xb2, 0x7e, 0xa4, 0x55, 0x24, 0x83, 0x38, 0x3f, 0x61, 0x2a, 0xfb, ++ 0x2e, 0xcb, 0xfc, 0xa9, 0xb5, 0x4b, 0x24, 0x23, 0x4e, 0x3f, 0x3e, 0x14, ++ 0x90, 0x5b, 0xb4, 0x1c, 0xbb, 0xef, 0x76, 0x63, 0x5d, 0xf5, 0x71, 0x94, ++ 0xe4, 0x4f, 0xa6, 0xb5, 0x1f, 0x6a, 0x5f, 0xbe, 0x83, 0x08, 0xf4, 0x88, ++ 0x1a, 0x3f, 0x5d, 0x86, 0x38, 0xc9, 0x4b, 0x1b, 0xb5, 0x3e, 0xfc, 0x9c, ++ 0x58, 0xa6, 0xf9, 0x85, 0x75, 0xb7, 0x97, 0xa0, 0xbc, 0x73, 0x48, 0xd9, ++ 0x1b, 0x11, 0xbb, 0x0c, 0x65, 0x88, 0xc1, 0xfe, 0xb9, 0xfc, 0xe6, 0x17, ++ 0x90, 0xff, 0xa6, 0xda, 0x24, 0xdb, 0xba, 0x9b, 0x71, 0xae, 0x24, 0x0e, ++ 0x1c, 0x89, 0x7b, 0x14, 0xc4, 0xba, 0x07, 0x68, 0xb9, 0xf2, 0xd7, 0xd5, ++ 0x7e, 0x92, 0x4b, 0x36, 0x6a, 0xfe, 0xea, 0xb8, 0x2b, 0x7f, 0xdf, 0xc9, ++ 0x5a, 0xfc, 0xaf, 0x45, 0x7c, 0x6e, 0x2e, 0x53, 0xf2, 0x32, 0x48, 0x35, ++ 0xb8, 0xa7, 0x23, 0x91, 0x8f, 0xff, 0x6f, 0xdb, 0xf8, 0xff, 0x68, 0x79, ++ 0xdc, 0x40, 0xfe, 0x6f, 0xe0, 0x38, 0x2c, 0x61, 0xbe, 0x2c, 0xce, 0xc3, ++ 0x97, 0x08, 0xfd, 0x7e, 0xab, 0x35, 0x4a, 0x71, 0xdc, 0x86, 0xfd, 0xe3, ++ 0x6d, 0xe7, 0x10, 0xef, 0x2d, 0x14, 0x07, 0x11, 0x38, 0xfa, 0x39, 0x4e, ++ 0x75, 0x86, 0xd4, 0xfa, 0xb5, 0x96, 0xee, 0x2f, 0xb1, 0xee, 0x72, 0xa9, ++ 0xf5, 0x0e, 0x73, 0xf7, 0x38, 0xe4, 0x3d, 0x83, 0x51, 0x8a, 0xdf, 0x36, ++ 0xbe, 0x65, 0x8b, 0xab, 0x40, 0x41, 0xca, 0x3b, 0x48, 0x4b, 0x73, 0x82, ++ 0xbe, 0x47, 0xc5, 0xb1, 0x34, 0xbe, 0xef, 0x0f, 0x52, 0x7d, 0x90, 0xfe, ++ 0x91, 0x5c, 0x49, 0xc2, 0x8b, 0xf3, 0xa9, 0x61, 0x3f, 0xf9, 0x3b, 0x75, ++ 0x56, 0xad, 0xb7, 0xc6, 0xa6, 0x20, 0x1f, 0x4b, 0x0c, 0xb1, 0x62, 0x03, ++ 0xf1, 0xbb, 0x65, 0x40, 0x9e, 0xe9, 0x15, 0x70, 0x53, 0xfe, 0x0a, 0x84, ++ 0xd9, 0x06, 0x7c, 0x8b, 0xbe, 0xff, 0x53, 0x90, 0xa2, 0x78, 0x6d, 0x0c, ++ 0xbb, 0xcf, 0xe9, 0xf8, 0x30, 0x46, 0xb4, 0x5f, 0xc0, 0x47, 0xe5, 0xef, ++ 0x90, 0xa9, 0x79, 0xcb, 0x79, 0x6b, 0x98, 0x8f, 0xb7, 0xc0, 0xb6, 0x3a, ++ 0xa0, 0xb7, 0x56, 0xc9, 0x79, 0xf2, 0xf0, 0xd7, 0x99, 0x17, 0xce, 0xab, ++ 0x8d, 0x67, 0x04, 0x92, 0x5f, 0x0e, 0xbe, 0x49, 0x3e, 0x53, 0x5d, 0x92, ++ 0xf1, 0xd4, 0xbc, 0x51, 0x8a, 0x7c, 0xe2, 0x0d, 0xd6, 0x97, 0x60, 0xbf, ++ 0x7a, 0xd9, 0xaf, 0xe9, 0x80, 0x8e, 0xbb, 0xf6, 0x07, 0x78, 0xcc, 0x04, ++ 0xbf, 0x3a, 0x12, 0xda, 0x2f, 0x27, 0x7f, 0xd9, 0x9e, 0xd4, 0xb7, 0x35, ++ 0xf8, 0xa5, 0xaa, 0x16, 0x68, 0xf9, 0x59, 0x47, 0xef, 0x25, 0x5c, 0x36, ++ 0xae, 0xed, 0x50, 0x79, 0xfd, 0x4b, 0xe6, 0x15, 0xf9, 0x39, 0x99, 0xb6, ++ 0xbf, 0xd3, 0xca, 0x3c, 0xef, 0xd4, 0xf9, 0x6e, 0xb4, 0xff, 0xfb, 0x43, ++ 0x54, 0x88, 0x5a, 0xae, 0x4c, 0x3a, 0xdf, 0x05, 0xf8, 0xef, 0xb3, 0x78, ++ 0x54, 0xb2, 0x96, 0xe3, 0xc4, 0x58, 0xba, 0x4e, 0xe9, 0x6b, 0x67, 0xfd, ++ 0x4d, 0xac, 0xdf, 0xb4, 0xbd, 0x4b, 0x65, 0xdf, 0x93, 0xd6, 0x7b, 0xd4, ++ 0xf9, 0x99, 0x7d, 0x97, 0x3a, 0x4e, 0x74, 0x7f, 0xec, 0xca, 0xa4, 0x3a, ++ 0x5f, 0xb5, 0xc0, 0x3b, 0x2d, 0xb6, 0xf4, 0xfd, 0x68, 0xbd, 0x47, 0xf5, ++ 0x3d, 0x28, 0x5e, 0xe0, 0xa5, 0xb3, 0xde, 0xfc, 0x29, 0xeb, 0x0d, 0xf9, ++ 0xe1, 0x37, 0xcf, 0x71, 0x7d, 0x19, 0x50, 0xf7, 0x94, 0xb3, 0xdd, 0xe5, ++ 0xba, 0xce, 0x4b, 0xbb, 0xb9, 0x0e, 0xed, 0xb4, 0xd7, 0x13, 0x8f, 0xad, ++ 0x2e, 0xa8, 0xb5, 0x2b, 0x4f, 0x9f, 0x74, 0xc4, 0x33, 0x29, 0x22, 0x98, ++ 0x03, 0x92, 0x11, 0x25, 0x7f, 0x4f, 0xcc, 0xad, 0x2b, 0xb9, 0xf6, 0x23, ++ 0x1e, 0x9d, 0x46, 0x88, 0xe4, 0xae, 0xf7, 0xab, 0x73, 0xd7, 0xac, 0x3e, ++ 0x8e, 0x3a, 0x73, 0x91, 0xed, 0x5d, 0xcc, 0xf6, 0x4a, 0x7d, 0x8d, 0xc4, ++ 0x53, 0xff, 0xf5, 0x7e, 0xbb, 0xbd, 0x77, 0x1e, 0xce, 0x7f, 0x9f, 0x33, ++ 0xef, 0xfd, 0xdc, 0x6f, 0xb8, 0x4f, 0xfa, 0x77, 0x7f, 0xa5, 0xed, 0xe1, ++ 0x7b, 0x23, 0xfa, 0x7e, 0x93, 0xf2, 0x32, 0x39, 0xa0, 0xce, 0x87, 0x05, ++ 0xd3, 0x44, 0xf4, 0xd5, 0xa3, 0xae, 0x4d, 0xef, 0x81, 0xfd, 0x7d, 0x75, ++ 0xea, 0xfe, 0x16, 0x81, 0x7e, 0xe3, 0x96, 0x21, 0x45, 0x7d, 0xbf, 0x38, ++ 0x9c, 0x2f, 0x8f, 0x5f, 0xb3, 0xdc, 0x38, 0xfb, 0x15, 0x65, 0xbf, 0x36, ++ 0x4b, 0xbf, 0x28, 0xee, 0xfc, 0x3d, 0x9f, 0xdf, 0x6c, 0xa7, 0xd0, 0xfd, ++ 0x9b, 0xcf, 0x91, 0x5c, 0x0f, 0xcb, 0xb9, 0xe7, 0xed, 0xdb, 0x99, 0xe5, ++ 0x54, 0x87, 0x4f, 0x1f, 0xa6, 0x7a, 0x1a, 0xb2, 0xf8, 0xe6, 0xb4, 0x6f, ++ 0xe2, 0x31, 0xc4, 0x51, 0xc9, 0x2d, 0x12, 0x7b, 0xc3, 0xf3, 0xc5, 0xcb, ++ 0xad, 0xb6, 0xc7, 0x66, 0xc6, 0x75, 0xbc, 0x4d, 0xf2, 0x73, 0x72, 0x80, ++ 0xe6, 0xc2, 0x9c, 0x38, 0x1a, 0xb6, 0x38, 0x42, 0x1e, 0xf3, 0x4a, 0xbe, ++ 0xf8, 0xe5, 0xeb, 0x8b, 0x9f, 0x3e, 0xd4, 0x7c, 0x3a, 0xe2, 0xd5, 0xf6, ++ 0x2b, 0x5c, 0x65, 0xe5, 0xf3, 0x00, 0xcf, 0x23, 0x19, 0x93, 0x7e, 0x89, ++ 0x4f, 0xa7, 0x68, 0x69, 0x56, 0x9c, 0x51, 0x72, 0x2b, 0xe2, 0x07, 0xd8, ++ 0xce, 0xcb, 0x2e, 0xf8, 0xd1, 0xb3, 0x07, 0xeb, 0x2b, 0x5c, 0xdf, 0xee, ++ 0x72, 0x9d, 0xda, 0xee, 0x07, 0x4e, 0xd7, 0x93, 0x7f, 0xf1, 0x03, 0xe7, ++ 0xb5, 0x7e, 0xd2, 0x6b, 0x66, 0x38, 0x3e, 0x2f, 0xba, 0xd8, 0xee, 0x1a, ++ 0xca, 0x47, 0xfc, 0x0e, 0xbd, 0x4f, 0xb7, 0x68, 0x5d, 0xaa, 0xb0, 0x42, ++ 0xc6, 0x81, 0xed, 0x59, 0x0f, 0xec, 0xf0, 0x71, 0x5c, 0x1b, 0x72, 0xf3, ++ 0x85, 0x6d, 0x6f, 0x0d, 0x9f, 0xef, 0xc4, 0xda, 0xc7, 0xf5, 0x65, 0x94, ++ 0xed, 0x7a, 0xaf, 0x1e, 0x18, 0x6e, 0x40, 0x7f, 0x9c, 0x34, 0x15, 0x46, ++ 0xe2, 0x03, 0xe3, 0xf0, 0xa7, 0x77, 0x23, 0xfc, 0xbd, 0xc7, 0x71, 0x60, ++ 0x0c, 0x9f, 0x1a, 0xa4, 0xbe, 0x19, 0x1e, 0x42, 0x7f, 0x0d, 0x7b, 0x07, ++ 0xe1, 0x47, 0x6f, 0x06, 0xeb, 0x7b, 0xcf, 0x02, 0x1f, 0x3c, 0x87, 0x73, ++ 0x07, 0x0f, 0x73, 0x7c, 0x36, 0xe6, 0x3f, 0xd7, 0x73, 0x1f, 0x72, 0x7d, ++ 0xf5, 0xd4, 0xe7, 0xc7, 0xb8, 0xef, 0x8a, 0x04, 0xf7, 0xf9, 0x0c, 0xaf, ++ 0xf7, 0x71, 0x1f, 0xb9, 0xcd, 0x7d, 0xb2, 0x37, 0xa7, 0x4f, 0x4e, 0xa1, ++ 0x6e, 0x8e, 0x65, 0x52, 0x6a, 0x43, 0xd6, 0xaf, 0x42, 0xdd, 0x1f, 0x15, ++ 0x06, 0xe2, 0x65, 0x9c, 0xaf, 0x92, 0x35, 0xc0, 0x91, 0x35, 0xe8, 0x6b, ++ 0xbd, 0x87, 0x38, 0x2e, 0x2d, 0x94, 0x9f, 0x95, 0x33, 0xe3, 0x9a, 0x0f, ++ 0x34, 0x3f, 0x3d, 0xd4, 0xbc, 0x43, 0xfd, 0xca, 0x58, 0xf5, 0x76, 0x8a, ++ 0xec, 0xab, 0x1a, 0xcb, 0x90, 0x7c, 0xa5, 0x28, 0x26, 0x7e, 0x55, 0x84, ++ 0x67, 0x60, 0x6f, 0x7c, 0x94, 0xfd, 0xec, 0x7f, 0x06, 0x78, 0x88, 0xf3, ++ 0xac, 0xf3, 0x77, 0x75, 0x9d, 0x49, 0xe7, 0x26, 0x07, 0x60, 0xb7, 0xe6, ++ 0x7d, 0xee, 0x9c, 0xa7, 0xf3, 0x5e, 0xd1, 0x4c, 0x6b, 0xd1, 0x73, 0x50, ++ 0xdd, 0x13, 0x92, 0xf9, 0x52, 0x76, 0xc9, 0x58, 0x70, 0x7f, 0x74, 0xf2, ++ 0x41, 0xf1, 0x45, 0xf3, 0xd2, 0xce, 0x23, 0x3b, 0x4f, 0x9c, 0xfc, 0x08, ++ 0x53, 0x3d, 0x97, 0x8f, 0x97, 0xfa, 0xa7, 0x37, 0x3e, 0x3a, 0xfc, 0xff, ++ 0xf1, 0x3a, 0x85, 0x78, 0xc5, 0xd9, 0x6e, 0x33, 0x41, 0x73, 0xd6, 0x13, ++ 0x62, 0x88, 0xf3, 0x35, 0x55, 0xcf, 0xef, 0xb5, 0x06, 0xf9, 0xea, 0x7f, ++ 0x1a, 0xf6, 0xf4, 0xf3, 0x3b, 0xf9, 0x83, 0xfb, 0x39, 0xf2, 0xec, 0x33, ++ 0xbb, 0xc7, 0x39, 0xaf, 0xcc, 0xb7, 0x7d, 0x1c, 0x87, 0xdb, 0x88, 0x83, ++ 0xa9, 0xe3, 0x90, 0xb0, 0xe2, 0xa0, 0xeb, 0x83, 0x5d, 0x4f, 0x91, 0xe4, ++ 0x0b, 0xd5, 0x19, 0xf3, 0x2a, 0xcd, 0x27, 0x1e, 0xf6, 0x5b, 0xca, 0x35, ++ 0x2b, 0xff, 0xc2, 0xec, 0x5f, 0x48, 0xec, 0x5d, 0x69, 0x3f, 0x17, 0xe4, ++ 0x73, 0x01, 0x79, 0x0e, 0xfb, 0x78, 0x8f, 0xe6, 0x3c, 0xf1, 0x55, 0x71, ++ 0xd4, 0x7a, 0x73, 0xdf, 0x9d, 0x3d, 0x9e, 0x54, 0x51, 0xe9, 0x07, 0x75, ++ 0x46, 0xe6, 0x8d, 0xea, 0x91, 0x69, 0xd5, 0x99, 0xbb, 0x54, 0x7f, 0x03, ++ 0xa7, 0xfb, 0x50, 0x17, 0x4e, 0xf7, 0x9d, 0xe1, 0xfe, 0xc7, 0x71, 0x69, ++ 0xa7, 0xb9, 0x58, 0xc6, 0xae, 0xc6, 0x59, 0x67, 0x9c, 0x76, 0x54, 0xd9, ++ 0xec, 0xd0, 0xf7, 0xce, 0xd7, 0x97, 0x31, 0xaf, 0x6d, 0xa2, 0xbe, 0xec, ++ 0xb7, 0xe6, 0x49, 0x67, 0xbd, 0xf7, 0x3f, 0x72, 0xbd, 0xdf, 0xde, 0x6c, ++ 0xd7, 0x5f, 0x2b, 0x26, 0xd2, 0xd0, 0xdf, 0xce, 0xfd, 0x72, 0x17, 0xbf, ++ 0xdb, 0xeb, 0x81, 0x08, 0xdd, 0xd7, 0xf5, 0x32, 0xf9, 0x27, 0x4a, 0x83, ++ 0xf0, 0xa7, 0x6b, 0x2b, 0xbe, 0x77, 0x85, 0xb0, 0x5f, 0x19, 0xc2, 0xdf, ++ 0x5b, 0xed, 0x3e, 0x93, 0xe4, 0x2b, 0x43, 0xc0, 0x52, 0x7e, 0xef, 0x13, ++ 0xd6, 0x5c, 0x0c, 0x3c, 0xe9, 0xb5, 0xcf, 0x8f, 0x6e, 0x71, 0xc1, 0x8b, ++ 0xf7, 0x2f, 0x1a, 0x30, 0x07, 0xb6, 0xd6, 0x99, 0xf4, 0xbd, 0xa3, 0x01, ++ 0xfd, 0x12, 0xf5, 0x75, 0xf6, 0xef, 0x33, 0x9e, 0x2b, 0x2b, 0x67, 0xe7, ++ 0x67, 0xfb, 0x7c, 0x5d, 0x18, 0x1f, 0xb5, 0xe6, 0x5c, 0x7d, 0x9f, 0xfd, ++ 0xfd, 0x28, 0xbd, 0xb4, 0x94, 0x73, 0xaa, 0x7d, 0xbe, 0x76, 0xe9, 0x79, ++ 0x87, 0xe7, 0xd1, 0x62, 0x71, 0x29, 0x0d, 0xbf, 0x26, 0xd2, 0xf9, 0xde, ++ 0xa1, 0xba, 0x4f, 0xeb, 0x83, 0xdd, 0xda, 0x8f, 0x59, 0xfd, 0xb8, 0x7f, ++ 0x0f, 0xdb, 0xf9, 0x1b, 0xfd, 0x5d, 0x5c, 0xca, 0xfe, 0x28, 0xbd, 0xd8, ++ 0xdf, 0xcc, 0xf3, 0x7e, 0xd2, 0x5a, 0x3b, 0xe7, 0xf4, 0x76, 0xb2, 0xab, ++ 0x88, 0xfb, 0x69, 0xa9, 0xad, 0xdf, 0x43, 0xbe, 0xa4, 0x09, 0x38, 0xd2, ++ 0xa4, 0xf3, 0xa0, 0xf3, 0xa5, 0xf3, 0x83, 0x3c, 0x96, 0xae, 0x26, 0xb1, ++ 0x96, 0xae, 0xd5, 0xf4, 0x60, 0x9b, 0xba, 0x66, 0x9c, 0xff, 0x3f, 0xd8, ++ 0x1e, 0x53, 0xf2, 0x6f, 0x8a, 0xef, 0x63, 0x68, 0x80, 0x3f, 0x31, 0xce, ++ 0xce, 0xc5, 0x9c, 0x00, 0x6b, 0x1e, 0xc1, 0x7d, 0x17, 0x3c, 0xbc, 0xdd, ++ 0xac, 0xe7, 0x46, 0x67, 0xff, 0xfe, 0x90, 0xea, 0xf2, 0xd9, 0x7f, 0x73, ++ 0xe7, 0xce, 0xd9, 0xf9, 0x51, 0xfb, 0xa9, 0xe4, 0x1b, 0x99, 0x8f, 0x7e, ++ 0xd1, 0xba, 0x09, 0x7f, 0x6f, 0x87, 0x7d, 0xe0, 0x7d, 0xd8, 0x67, 0xcf, ++ 0x97, 0xe4, 0x45, 0x21, 0x3d, 0xf0, 0xc5, 0x45, 0x85, 0xe4, 0xcf, 0xf1, ++ 0xcb, 0xdf, 0xd1, 0xe7, 0x8f, 0x46, 0x83, 0xd8, 0x2f, 0x6b, 0x85, 0x7a, ++ 0x37, 0xf1, 0xd6, 0x25, 0x8e, 0x82, 0xd7, 0x1f, 0x8c, 0x00, 0xdf, 0x17, ++ 0x2f, 0x41, 0x4f, 0xd1, 0x11, 0xea, 0x73, 0xfe, 0x32, 0x84, 0x35, 0x35, ++ 0xca, 0x7c, 0x2d, 0x37, 0xe8, 0xff, 0x65, 0x59, 0x11, 0xe2, 0xff, 0xab, ++ 0xf0, 0xbb, 0x03, 0x4f, 0xdd, 0xb6, 0x7c, 0x2f, 0xc4, 0x5b, 0xaa, 0x1f, ++ 0x92, 0x97, 0x38, 0xce, 0xfc, 0xf5, 0xe7, 0xf2, 0x57, 0xc7, 0xa5, 0xdc, ++ 0xc8, 0xcb, 0xd7, 0xb5, 0x4e, 0xbe, 0x7a, 0x99, 0xaf, 0xf7, 0xad, 0xfe, ++ 0x36, 0x57, 0x2f, 0xfe, 0xae, 0xb8, 0xf4, 0xd8, 0xf8, 0x0b, 0xdc, 0x5c, ++ 0xab, 0xee, 0x2f, 0x9b, 0x33, 0x77, 0x56, 0x0b, 0x7b, 0x3d, 0x3a, 0x24, ++ 0xf3, 0xfd, 0x1f, 0xfe, 0xac, 0x5e, 0x92, 0x80, 0x14, 0x00, 0x00, 0x00 }; + + static u8 bnx2_TPAT_b06FwText[] = { +- 0xbd, 0x58, 0x6d, 0x70, 0x5c, 0xd5, 0x79, 0x7e, 0xce, 0xbd, 0x77, 0xb5, +- 0xd7, 0xd2, 0x4a, 0xba, 0xb2, 0xd6, 0x66, 0x5d, 0xdc, 0xfa, 0x1e, 0x74, +- 0x57, 0x52, 0x58, 0x01, 0x77, 0x6d, 0x01, 0xeb, 0xe6, 0xb6, 0xbe, 0xc8, +- 0xb2, 0xbc, 0xfe, 0x00, 0xe4, 0xc0, 0x4c, 0xe4, 0x96, 0x8e, 0x37, 0xc6, +- 0x18, 0xd9, 0x90, 0xa9, 0x28, 0xfc, 0x58, 0x37, 0x4c, 0xbd, 0x95, 0x65, +- 0x63, 0xc3, 0x4a, 0x6b, 0x0c, 0xb1, 0x4c, 0xda, 0x99, 0x78, 0x84, 0xb1, +- 0x4c, 0x22, 0x7b, 0x0d, 0xe4, 0x07, 0x49, 0xc3, 0xa0, 0xc1, 0x0e, 0x08, +- 0x06, 0xf3, 0x31, 0x6d, 0x67, 0x98, 0xe9, 0xa4, 0xf5, 0x18, 0xf3, 0x11, +- 0x92, 0x18, 0x87, 0x4e, 0x3a, 0xa2, 0x10, 0x9f, 0x3e, 0x67, 0x77, 0xc5, +- 0x57, 0x32, 0xd3, 0xfe, 0xaa, 0x66, 0x56, 0x7b, 0xf7, 0xec, 0xf9, 0x78, +- 0xcf, 0xfb, 0x3e, 0xef, 0xf3, 0x3e, 0xef, 0x5e, 0x21, 0x50, 0x8f, 0xda, +- 0x5f, 0x23, 0x5f, 0xdd, 0xdf, 0x1a, 0xba, 0x2f, 0x7d, 0xf5, 0x75, 0x57, +- 0xf3, 0xf1, 0x3a, 0xe1, 0xd4, 0x59, 0xf8, 0x7f, 0xfc, 0x33, 0x01, 0x67, +- 0xce, 0x0e, 0xfd, 0x82, 0x6d, 0x04, 0x85, 0xcb, 0x7b, 0x3c, 0xd8, 0x66, +- 0x10, 0x77, 0x6f, 0xf7, 0x80, 0x70, 0x2a, 0xe5, 0xae, 0xc4, 0xef, 0x54, +- 0x21, 0x6e, 0x41, 0x8f, 0xff, 0x71, 0xf0, 0xe9, 0x35, 0xcf, 0x5d, 0x2f, +- 0x2f, 0x1e, 0x36, 0x61, 0x3b, 0xc1, 0x5e, 0xcb, 0x69, 0x87, 0xbd, 0x98, +- 0x6b, 0xfe, 0xb1, 0xe3, 0x2f, 0x04, 0x9a, 0xe6, 0xf6, 0x52, 0x6a, 0xc4, +- 0x8f, 0x62, 0xd8, 0x4f, 0x60, 0x77, 0xc9, 0x40, 0xe8, 0x44, 0xb1, 0xcb, +- 0x9b, 0x55, 0x5b, 0x7c, 0xe9, 0xef, 0x86, 0x5a, 0x72, 0xda, 0x97, 0x89, +- 0x5e, 0x13, 0xe1, 0x77, 0xbc, 0xc5, 0xd8, 0x5d, 0x4e, 0x60, 0xa4, 0x6c, +- 0xe3, 0xac, 0x39, 0x82, 0xde, 0xf2, 0xdc, 0x3a, 0x97, 0xeb, 0x3a, 0xb1, +- 0xe7, 0xcb, 0x6b, 0xdd, 0xdd, 0x48, 0x25, 0xf6, 0xc0, 0x40, 0x2e, 0xee, +- 0x71, 0x5d, 0x9b, 0xbb, 0x07, 0xb2, 0x93, 0xfb, 0x14, 0xea, 0xba, 0x5d, +- 0xee, 0x51, 0xe0, 0x7a, 0xe9, 0x1e, 0x85, 0xde, 0x2b, 0xc3, 0xcf, 0x6f, +- 0xa9, 0xe7, 0x3a, 0x16, 0xe3, 0x19, 0xee, 0xff, 0x74, 0xd9, 0xc1, 0xc9, +- 0xb2, 0x87, 0xe7, 0xcb, 0x2e, 0x7e, 0x54, 0x8e, 0xe3, 0xa9, 0xb2, 0x9d, +- 0xb3, 0x03, 0xf4, 0xc7, 0x47, 0x77, 0xaa, 0x84, 0x87, 0xc2, 0x1f, 0x05, +- 0xde, 0xa1, 0x43, 0x46, 0x2c, 0xf3, 0x37, 0xd7, 0xa1, 0x7f, 0xfe, 0x71, +- 0x1b, 0x1b, 0x4a, 0x8b, 0x73, 0xd1, 0x00, 0x9c, 0x23, 0xe0, 0x5f, 0x67, +- 0xa3, 0x9f, 0x7b, 0x14, 0xb8, 0x7f, 0x58, 0x1e, 0xe1, 0xcb, 0xc6, 0xbb, +- 0x45, 0xdb, 0x6e, 0x1e, 0x5d, 0xa8, 0xe7, 0xe0, 0x57, 0xc5, 0x8b, 0xea, +- 0x42, 0xda, 0xc1, 0x2b, 0xcb, 0x95, 0x6a, 0x0c, 0x50, 0x68, 0xe8, 0x2e, +- 0xc0, 0x0c, 0x64, 0x76, 0x9d, 0x29, 0xd0, 0x7b, 0x95, 0xd7, 0x39, 0x2a, +- 0x6e, 0xb9, 0xc5, 0x08, 0x60, 0x8b, 0xc0, 0xb5, 0xda, 0xa6, 0x32, 0xd8, +- 0x57, 0xe6, 0xbd, 0x68, 0xcf, 0x48, 0x19, 0xe1, 0x5f, 0x76, 0x98, 0x98, +- 0x88, 0xe3, 0xfe, 0xb7, 0xbb, 0x2d, 0x7c, 0x5c, 0x94, 0x89, 0x4e, 0xf3, +- 0x7e, 0xec, 0x2c, 0xe6, 0x71, 0x47, 0x11, 0x05, 0x23, 0x18, 0xc2, 0x37, +- 0xba, 0x03, 0xde, 0x33, 0xc4, 0xf7, 0xcb, 0xb0, 0x5b, 0x83, 0xd3, 0x97, +- 0xdf, 0xdb, 0x2e, 0x0f, 0x87, 0x06, 0x90, 0x1d, 0x03, 0xfa, 0x4a, 0x02, +- 0xa7, 0x32, 0x02, 0x5b, 0xfc, 0xcb, 0x50, 0x70, 0xba, 0xb1, 0xb7, 0x2c, +- 0xb3, 0x05, 0x7e, 0x77, 0xd5, 0x28, 0xec, 0x45, 0xc1, 0x6d, 0xd6, 0xf2, +- 0x12, 0xec, 0x96, 0x60, 0xc0, 0x4a, 0x8f, 0xb5, 0xcd, 0x1e, 0x13, 0x32, +- 0xbf, 0xc2, 0x94, 0x21, 0x20, 0x33, 0x9d, 0x46, 0xaa, 0xa0, 0x84, 0x1c, +- 0xba, 0x08, 0x6d, 0xd3, 0x6d, 0xd6, 0x35, 0x53, 0xfa, 0x7d, 0xc0, 0xba, +- 0x7a, 0x0a, 0x58, 0xcf, 0x3d, 0x1f, 0x5a, 0x2e, 0xb0, 0x3d, 0xfd, 0x6b, +- 0x15, 0x2e, 0x90, 0xe1, 0x61, 0xd1, 0x8d, 0xd1, 0x32, 0x70, 0xd3, 0x18, +- 0xec, 0x18, 0xe7, 0x16, 0xb9, 0x77, 0x3d, 0xe7, 0xae, 0x1d, 0x6d, 0x1b, +- 0x9c, 0x11, 0x92, 0x77, 0x93, 0x03, 0x40, 0xca, 0x3f, 0x0e, 0xe9, 0xae, +- 0x13, 0xd2, 0xd9, 0x53, 0xdb, 0x33, 0x59, 0xdb, 0xf3, 0x8a, 0x29, 0x5b, +- 0xac, 0x2a, 0x41, 0xf4, 0x96, 0xe0, 0x3e, 0xe9, 0x83, 0x77, 0x89, 0xf1, +- 0xde, 0xf5, 0x70, 0x5b, 0xa4, 0x7f, 0x98, 0x73, 0xa3, 0x41, 0x97, 0xf5, +- 0x5e, 0x51, 0xe0, 0x43, 0x4f, 0xcf, 0xef, 0xd2, 0xb6, 0x84, 0x4e, 0x90, +- 0x11, 0xfd, 0xe5, 0xfd, 0x73, 0x39, 0x62, 0x9c, 0xf4, 0xe3, 0xc0, 0x42, +- 0x34, 0xb7, 0x78, 0xf3, 0xf1, 0xb0, 0x83, 0xc6, 0xa8, 0xb7, 0xcc, 0x78, +- 0xc0, 0xa9, 0xc3, 0x49, 0xff, 0xb7, 0x0a, 0xdf, 0xd0, 0xf3, 0x81, 0x6f, +- 0x3f, 0xe2, 0x20, 0xe6, 0x5d, 0xc4, 0xd1, 0xf4, 0x36, 0xe3, 0x55, 0x67, +- 0x08, 0x4d, 0xde, 0xcf, 0x8d, 0xd7, 0x9c, 0x38, 0x1e, 0xe2, 0x7d, 0xee, +- 0x4c, 0xc6, 0xf1, 0x40, 0xf9, 0xab, 0xfb, 0x5a, 0x22, 0x3b, 0xfe, 0x8e, +- 0x42, 0x4b, 0x65, 0x7d, 0xf8, 0xac, 0x3f, 0x01, 0x5c, 0xa6, 0xc7, 0xf3, +- 0x62, 0x63, 0xe9, 0x92, 0x72, 0xa3, 0x19, 0x3c, 0x50, 0xb2, 0x31, 0x8f, +- 0x76, 0x45, 0x3c, 0x1b, 0x6f, 0x17, 0xf3, 0x62, 0x55, 0x39, 0x14, 0x6b, +- 0x26, 0x7b, 0x44, 0x38, 0x69, 0x89, 0x9e, 0x71, 0x10, 0x9b, 0x4a, 0xad, +- 0xf1, 0x05, 0xfe, 0xc3, 0xff, 0x57, 0xe3, 0x6c, 0xab, 0x0c, 0x5d, 0x71, +- 0x49, 0x79, 0x49, 0x03, 0xf5, 0x5e, 0x9f, 0x58, 0x3b, 0xa9, 0xd4, 0x5e, +- 0x3f, 0x2b, 0x7a, 0x27, 0x61, 0x37, 0x04, 0x81, 0x75, 0xd7, 0xe8, 0x69, +- 0x23, 0xb7, 0x20, 0x86, 0x52, 0xc9, 0xc5, 0x29, 0x5f, 0xe3, 0x77, 0x1e, +- 0x2c, 0x4f, 0xf0, 0x85, 0xd8, 0x19, 0x1f, 0x56, 0x8c, 0xcf, 0x53, 0x1b, +- 0x2c, 0x8c, 0x74, 0xaf, 0xad, 0xac, 0x89, 0x10, 0x2b, 0x4f, 0x14, 0xb3, +- 0x30, 0x88, 0xbf, 0x45, 0x41, 0x72, 0x76, 0x82, 0x98, 0x7f, 0xcb, 0x4f, +- 0x76, 0x7e, 0x6c, 0x92, 0x1c, 0x5a, 0x65, 0x82, 0x86, 0x0a, 0x2b, 0x48, +- 0x76, 0x1e, 0x81, 0x80, 0xe9, 0x59, 0x78, 0xc5, 0x8f, 0x20, 0xdc, 0x60, +- 0x63, 0x17, 0x71, 0x55, 0xc7, 0xf1, 0xa3, 0x95, 0x71, 0xfd, 0x19, 0xce, +- 0xaa, 0xf2, 0x57, 0x73, 0x9e, 0xe3, 0xa5, 0x36, 0xe4, 0x2a, 0x79, 0x0f, +- 0x67, 0x1d, 0xef, 0xfb, 0xad, 0x88, 0x7e, 0xfc, 0x93, 0xcf, 0xc6, 0x6e, +- 0xa4, 0x9d, 0x66, 0xe0, 0xe5, 0x1e, 0x17, 0x8b, 0x50, 0x68, 0x01, 0xed, +- 0x36, 0x70, 0x21, 0xbd, 0x10, 0xd3, 0x2d, 0xfa, 0xeb, 0xb8, 0xd3, 0x3f, +- 0xde, 0xaa, 0x63, 0xa2, 0xf7, 0x72, 0x56, 0x8d, 0x2b, 0xf5, 0xbc, 0x5f, +- 0x87, 0xd9, 0x8e, 0xe1, 0x19, 0x66, 0x89, 0xbf, 0x88, 0x39, 0xf9, 0x12, +- 0xcf, 0x6f, 0x59, 0x66, 0xc2, 0x5c, 0xe6, 0x9a, 0xee, 0x7c, 0x60, 0xa2, +- 0xa8, 0x39, 0x41, 0xce, 0xbe, 0xc4, 0xff, 0xe7, 0xca, 0x1a, 0x9f, 0x3e, +- 0xf1, 0x29, 0xd0, 0xde, 0xa1, 0xe3, 0xee, 0x5b, 0xed, 0xc4, 0xde, 0x76, +- 0xfa, 0x33, 0xc2, 0x3c, 0x78, 0x90, 0xf6, 0x9e, 0x2b, 0x7e, 0xcf, 0x58, +- 0xe5, 0x48, 0x57, 0x9f, 0xf0, 0x4e, 0x11, 0xe2, 0x79, 0xff, 0xef, 0xb4, +- 0x8f, 0x5d, 0x6e, 0x4b, 0xcc, 0xdc, 0x47, 0xcc, 0x68, 0xee, 0x59, 0x6f, +- 0x39, 0x63, 0x72, 0xe0, 0x7d, 0x1a, 0x91, 0x08, 0x86, 0xac, 0x44, 0x29, +- 0xb5, 0x77, 0x90, 0xdf, 0xdb, 0x41, 0xd6, 0xb2, 0x47, 0x65, 0x9e, 0xe7, +- 0xe5, 0x2c, 0x43, 0x26, 0x9a, 0xcd, 0xd4, 0xd0, 0x88, 0x90, 0x83, 0xcd, +- 0x42, 0xf6, 0xdf, 0x03, 0xe9, 0x9c, 0x10, 0xfa, 0xcc, 0xf5, 0x56, 0x57, +- 0x05, 0xa3, 0x59, 0x62, 0x54, 0xbf, 0xdf, 0x67, 0xa5, 0x2a, 0xef, 0x43, +- 0xd6, 0x95, 0x53, 0x09, 0x8c, 0x96, 0xa4, 0xef, 0x8a, 0x28, 0xbe, 0x96, +- 0xb6, 0x71, 0x22, 0xa9, 0x96, 0xbc, 0x90, 0x96, 0xb9, 0x1e, 0x73, 0x31, +- 0x73, 0x21, 0x81, 0x61, 0x62, 0xe9, 0x1f, 0x92, 0x23, 0xe8, 0x29, 0x9b, +- 0xc4, 0xb1, 0x8b, 0xfd, 0xa5, 0x28, 0x66, 0xc8, 0x4f, 0x75, 0xe9, 0x4e, +- 0x8c, 0x94, 0x64, 0xe7, 0x1b, 0x48, 0xe5, 0x8f, 0x30, 0x5e, 0x67, 0x17, +- 0x78, 0xd8, 0x5f, 0x6e, 0x63, 0x8c, 0xa4, 0xbb, 0x8a, 0x1c, 0x65, 0x76, +- 0x4b, 0x67, 0x17, 0x7d, 0x5b, 0x17, 0x90, 0xdb, 0xca, 0x19, 0xee, 0x53, +- 0xc0, 0xaa, 0x72, 0x5e, 0xf4, 0x95, 0xe7, 0x70, 0xfa, 0x73, 0x62, 0x53, +- 0x63, 0xd5, 0xc6, 0xe6, 0x12, 0x70, 0x67, 0xc9, 0x47, 0x8b, 0x67, 0xbc, +- 0x18, 0xc5, 0x45, 0xfa, 0x71, 0x02, 0xf7, 0x38, 0x21, 0x16, 0x79, 0xeb, +- 0xd4, 0x8e, 0xb8, 0x9e, 0x9f, 0x17, 0x6b, 0x19, 0xb7, 0x30, 0x02, 0x63, +- 0xd2, 0x37, 0x71, 0x36, 0x3e, 0x3c, 0x3f, 0x52, 0xe1, 0x5d, 0xfd, 0x6e, +- 0xa2, 0xdf, 0xc7, 0x1a, 0x07, 0x72, 0xc8, 0x17, 0x85, 0xc1, 0x26, 0xfa, +- 0xe1, 0xa4, 0x28, 0x0c, 0xc4, 0x20, 0x0b, 0xf7, 0x0a, 0x3a, 0x6b, 0x8c, +- 0x24, 0xb1, 0x60, 0x8e, 0xa7, 0x2d, 0xfc, 0x75, 0xe9, 0x29, 0xe3, 0x5c, +- 0xa4, 0x0e, 0xe6, 0x81, 0x08, 0xa2, 0x07, 0x2c, 0x34, 0x1f, 0x10, 0xc4, +- 0x5d, 0xa1, 0x33, 0xaa, 0xd7, 0x21, 0x81, 0x7d, 0xa3, 0x36, 0xee, 0xe9, +- 0x88, 0xe0, 0x42, 0x52, 0x0e, 0x5e, 0x21, 0x86, 0xfd, 0x26, 0x8e, 0x8d, +- 0x1e, 0x97, 0xae, 0x6b, 0x14, 0x22, 0x68, 0x8a, 0x23, 0xd2, 0x5e, 0x87, +- 0x06, 0xae, 0xdb, 0x59, 0x52, 0x3b, 0xed, 0xa0, 0xe0, 0x36, 0x40, 0xfa, +- 0x0f, 0x73, 0xdf, 0x53, 0x45, 0xa5, 0xea, 0xaf, 0xf5, 0x66, 0x3e, 0x30, +- 0xe5, 0xf4, 0x0e, 0x7e, 0x7e, 0x6b, 0xaa, 0xba, 0xff, 0xbc, 0x03, 0x36, +- 0x1a, 0x0f, 0x56, 0xf6, 0x9f, 0x7d, 0x8a, 0x16, 0x7c, 0x58, 0xd2, 0xf9, +- 0xa4, 0x54, 0x34, 0xf0, 0xfa, 0xdf, 0x13, 0x4a, 0xdd, 0xe4, 0xcb, 0xdc, +- 0xcb, 0xa2, 0x6d, 0x60, 0x94, 0xcf, 0x83, 0xe9, 0xa4, 0x9b, 0xa5, 0xcd, +- 0xe7, 0xcb, 0x51, 0xda, 0xc7, 0x5c, 0xf0, 0xb6, 0x19, 0x3b, 0x1c, 0x13, +- 0x75, 0xde, 0x0e, 0x63, 0x6b, 0x05, 0xab, 0x0e, 0x16, 0x8d, 0xd5, 0x63, +- 0x89, 0x17, 0x8a, 0x4d, 0xcc, 0xcd, 0x8d, 0x93, 0x16, 0xe7, 0xe9, 0xdc, +- 0x14, 0x88, 0x7a, 0xbd, 0x62, 0xe5, 0x64, 0x5f, 0x25, 0x5f, 0x07, 0xc6, +- 0x0d, 0xbc, 0xe9, 0xdf, 0x80, 0x48, 0x90, 0x15, 0x03, 0x93, 0x3a, 0x7f, +- 0xd6, 0x8a, 0xd5, 0x93, 0x8c, 0xdf, 0x7c, 0x9d, 0x3b, 0x37, 0x88, 0x48, +- 0xa0, 0xf3, 0xe5, 0xf3, 0x1c, 0xb2, 0x99, 0x43, 0xc7, 0xfe, 0x97, 0x1c, +- 0x7a, 0xa8, 0x64, 0x21, 0xd7, 0x52, 0xcd, 0x97, 0x5e, 0xc6, 0xe2, 0xef, +- 0x6b, 0x75, 0x7b, 0x3b, 0xc7, 0xa3, 0x07, 0x74, 0x0e, 0xf7, 0x32, 0x87, +- 0x35, 0x9e, 0x2d, 0xb1, 0x69, 0x1c, 0x76, 0x73, 0x10, 0x5a, 0x1f, 0x8e, +- 0x2a, 0xbc, 0xed, 0x2b, 0xf5, 0xf1, 0x32, 0xed, 0x13, 0x39, 0xf8, 0x2c, +- 0xf1, 0x08, 0x12, 0xd2, 0xbb, 0x9e, 0x52, 0x33, 0x7e, 0x2a, 0xfb, 0x2c, +- 0x79, 0xf9, 0x9c, 0xd0, 0xf7, 0x8f, 0xc2, 0x49, 0x6b, 0x3c, 0xf6, 0x5a, +- 0x57, 0x55, 0x70, 0x19, 0x12, 0xaf, 0xac, 0xd5, 0xf3, 0x35, 0x36, 0xa3, +- 0x68, 0x48, 0xce, 0xd2, 0x37, 0x72, 0xa8, 0x51, 0xa8, 0x25, 0xaf, 0xa6, +- 0xab, 0xb8, 0x2c, 0xb2, 0x36, 0xad, 0xe7, 0x59, 0xbd, 0xe3, 0xb2, 0xb0, +- 0xde, 0xac, 0xd6, 0xd1, 0xbd, 0xc4, 0x86, 0xe6, 0xb8, 0xcb, 0xdb, 0xa3, +- 0xd8, 0x47, 0x8c, 0x7a, 0x69, 0x17, 0xc3, 0xac, 0xab, 0xbb, 0x4b, 0xd2, +- 0x1d, 0x26, 0x4e, 0x77, 0xd7, 0x70, 0x3a, 0xcc, 0x5a, 0xba, 0x1b, 0x72, +- 0xaf, 0xae, 0xa5, 0x11, 0xe2, 0x94, 0x34, 0x56, 0xc1, 0xe9, 0x48, 0x0d, +- 0xa7, 0xbd, 0x15, 0x9c, 0xee, 0x36, 0x34, 0x3e, 0x35, 0xf6, 0x36, 0xf1, +- 0xbe, 0x67, 0xa3, 0x30, 0x7e, 0xc0, 0xfd, 0xc3, 0x05, 0xc3, 0x3d, 0x35, +- 0xec, 0xf5, 0x68, 0xec, 0x19, 0x69, 0xdc, 0x63, 0xf0, 0x6e, 0x2f, 0x88, +- 0x42, 0xae, 0x11, 0x32, 0x3b, 0x2c, 0x0a, 0x9d, 0xf3, 0x88, 0xbd, 0x67, +- 0x38, 0xa3, 0x81, 0xd8, 0xab, 0xfa, 0x4c, 0xcf, 0x8f, 0x11, 0x7b, 0xff, +- 0x29, 0xce, 0x46, 0x34, 0xd7, 0xea, 0xd8, 0x02, 0x8b, 0x4e, 0x68, 0xae, +- 0x8d, 0x92, 0x30, 0x2c, 0xe4, 0x4b, 0xc6, 0xe2, 0x04, 0x14, 0xb6, 0x92, +- 0xdb, 0xde, 0xf4, 0x76, 0xf9, 0x2d, 0xb8, 0x01, 0xa7, 0xbb, 0x0c, 0x68, +- 0x1d, 0x62, 0x4e, 0x54, 0xb1, 0x7b, 0x17, 0x39, 0xa3, 0x29, 0x90, 0x9d, +- 0x67, 0xa9, 0x37, 0xb6, 0xa4, 0x1b, 0x50, 0xf2, 0x86, 0xc3, 0x66, 0x56, +- 0x43, 0x9b, 0xe7, 0xae, 0x86, 0xae, 0x85, 0x71, 0x58, 0xed, 0x36, 0x1a, +- 0x8e, 0x7a, 0xb9, 0x13, 0x42, 0xe3, 0x15, 0xe8, 0x3a, 0x6e, 0xd3, 0x7e, +- 0x38, 0xf5, 0x81, 0x97, 0xf9, 0xc0, 0x7c, 0x5c, 0x9c, 0x75, 0xaa, 0xf5, +- 0xa0, 0x6f, 0x5c, 0x63, 0xec, 0x57, 0xea, 0x4d, 0xcf, 0xc0, 0x1d, 0xdd, +- 0x4a, 0x79, 0x4b, 0xa3, 0x88, 0x4c, 0xd8, 0xa8, 0x3b, 0xd8, 0x8a, 0x97, +- 0xba, 0x22, 0x38, 0x7b, 0xab, 0xfe, 0x3e, 0x8a, 0x7a, 0xe2, 0x70, 0xd3, +- 0xb5, 0x51, 0x2c, 0x99, 0xa8, 0x62, 0xb2, 0xc1, 0xfb, 0x89, 0xb8, 0x8b, +- 0x98, 0x9c, 0xe7, 0x9d, 0x11, 0xdb, 0x9c, 0x0c, 0xf6, 0xd2, 0xa6, 0xd7, +- 0xc9, 0xf1, 0xe7, 0x93, 0xbb, 0x66, 0x2c, 0xda, 0xbf, 0x62, 0x59, 0xa1, +- 0x73, 0x09, 0x22, 0x58, 0x34, 0x21, 0x07, 0x8e, 0xe9, 0x0a, 0x33, 0x6a, +- 0x89, 0x0d, 0xc4, 0xbb, 0xe6, 0x57, 0x93, 0x71, 0xba, 0x62, 0x69, 0xdb, +- 0xd0, 0xcd, 0xb8, 0xa4, 0xce, 0x24, 0x93, 0xd9, 0x51, 0x62, 0x7d, 0xdb, +- 0xf1, 0x08, 0xea, 0x0e, 0xfc, 0x97, 0x32, 0x02, 0xe6, 0x42, 0xb7, 0x22, +- 0x3e, 0x0b, 0x99, 0x7a, 0x72, 0xc8, 0x45, 0xc4, 0xf1, 0xd8, 0xfe, 0x9d, +- 0x6a, 0x09, 0xc7, 0xdf, 0xbb, 0xbe, 0x19, 0x6d, 0xcb, 0x64, 0x7e, 0x2b, +- 0xf7, 0x9f, 0x4d, 0x17, 0x3a, 0x13, 0x8c, 0xdd, 0x49, 0xb8, 0xb8, 0x6a, +- 0x4c, 0xe6, 0x8e, 0xa1, 0x0e, 0xcd, 0x13, 0x5e, 0xf6, 0x84, 0x88, 0xa1, +- 0xf1, 0x44, 0x0c, 0xfb, 0x8e, 0xeb, 0xfc, 0x8c, 0xc1, 0x1a, 0xf3, 0x66, +- 0x3b, 0x44, 0xa1, 0x9f, 0xf9, 0x39, 0xd3, 0x2f, 0xda, 0xd1, 0x3e, 0x2e, +- 0xa7, 0xb3, 0xc2, 0x0b, 0x1f, 0x80, 0x87, 0x76, 0xd6, 0x65, 0xfb, 0x84, +- 0x8b, 0x15, 0xba, 0x7e, 0x94, 0x75, 0xfe, 0xe8, 0x7a, 0x6a, 0xf0, 0x4e, +- 0xa1, 0x58, 0x5f, 0xa9, 0x79, 0xbd, 0x7c, 0xf5, 0xb1, 0xfe, 0x59, 0x62, +- 0xdd, 0xb8, 0xce, 0x2d, 0x03, 0x33, 0xfe, 0x25, 0xb5, 0x3d, 0x99, 0x65, +- 0xad, 0x9b, 0xc7, 0xbc, 0xaa, 0xe6, 0x13, 0x5a, 0x74, 0x6e, 0xcd, 0xab, +- 0xe5, 0x93, 0x85, 0x33, 0x8c, 0xdd, 0xe1, 0xff, 0x73, 0x5d, 0xb2, 0x90, +- 0x38, 0x60, 0xa0, 0xa5, 0x23, 0x8a, 0x6b, 0x96, 0xb6, 0x39, 0xcd, 0x88, +- 0xe2, 0x26, 0xdf, 0x41, 0x13, 0x31, 0xb1, 0x9f, 0x39, 0x85, 0xf9, 0xd5, +- 0x5c, 0x5b, 0xa9, 0xeb, 0x55, 0x2d, 0xd7, 0xf2, 0xa5, 0x04, 0x6b, 0x93, +- 0xae, 0x05, 0xbd, 0xac, 0x05, 0x16, 0x0e, 0x95, 0xb5, 0x6f, 0x1d, 0xbc, +- 0x4b, 0xce, 0x7e, 0xc5, 0xd7, 0xbe, 0x5d, 0x8c, 0x12, 0x73, 0xe3, 0x41, +- 0xe6, 0xc6, 0xda, 0xf2, 0x25, 0xb5, 0xc6, 0xd3, 0xf5, 0x38, 0x64, 0x3d, +- 0xb6, 0xc4, 0x4d, 0xe3, 0x72, 0xd0, 0x15, 0xa7, 0xee, 0x24, 0x36, 0x3b, +- 0x1b, 0x0d, 0xa5, 0x5e, 0x4e, 0xa7, 0x42, 0xea, 0x98, 0xcc, 0xdd, 0x42, +- 0xba, 0xef, 0x93, 0x9b, 0xd6, 0x9a, 0x51, 0x2c, 0xaf, 0xe5, 0x60, 0xb2, +- 0x96, 0x83, 0x1e, 0x73, 0xd0, 0x6d, 0x45, 0xf8, 0x09, 0x6d, 0x6c, 0x63, +- 0x0e, 0x6e, 0xa3, 0x4e, 0xfd, 0x7e, 0xa9, 0xc2, 0xfb, 0x99, 0x15, 0x22, +- 0x35, 0x73, 0x9e, 0xf9, 0xe4, 0x5e, 0xe6, 0x51, 0xaf, 0xb5, 0x65, 0xce, +- 0x33, 0x66, 0xab, 0x6b, 0xf9, 0xb4, 0xbb, 0xc6, 0xfb, 0x0f, 0xd4, 0xf2, +- 0x69, 0xf5, 0x97, 0xf2, 0x49, 0xf3, 0xd3, 0x0b, 0xbf, 0x43, 0xab, 0xd6, +- 0x22, 0x79, 0xa1, 0xef, 0x97, 0xb3, 0x10, 0xfe, 0xd8, 0xd7, 0x67, 0xd9, +- 0xb0, 0x82, 0xc6, 0x0a, 0xdf, 0x58, 0x41, 0x28, 0x7a, 0x59, 0x3b, 0x6d, +- 0x2f, 0x2f, 0xb2, 0xf4, 0x9d, 0x5e, 0xb7, 0x96, 0xb1, 0xd8, 0x99, 0xfe, +- 0x05, 0xce, 0xb6, 0x2a, 0xd5, 0x97, 0xbe, 0xa4, 0xde, 0x60, 0x5c, 0x62, +- 0xd4, 0x1f, 0xeb, 0x27, 0xb3, 0xa2, 0x7f, 0x52, 0xfb, 0xa6, 0x11, 0x11, +- 0x6f, 0xad, 0x58, 0x35, 0x09, 0xdc, 0x43, 0x3d, 0x73, 0x8e, 0x7e, 0x59, +- 0xe3, 0xcb, 0xa1, 0x35, 0xbc, 0xdb, 0x19, 0xdf, 0xc2, 0xc3, 0xe5, 0xaa, +- 0x7f, 0xf6, 0x95, 0x65, 0x66, 0x1a, 0x23, 0x58, 0xc3, 0x9a, 0x76, 0x98, +- 0x7c, 0xf1, 0x6f, 0xc9, 0x28, 0x5e, 0x24, 0x5f, 0xbc, 0xc4, 0xfb, 0x1d, +- 0xaa, 0xde, 0xcf, 0x9f, 0x45, 0x2a, 0x73, 0x5a, 0xf3, 0x05, 0xb5, 0xf7, +- 0xa1, 0x72, 0x9b, 0x7f, 0x9a, 0x78, 0x7c, 0xb0, 0x24, 0x07, 0xfa, 0x78, +- 0x47, 0xbb, 0x5b, 0xce, 0x0e, 0x0a, 0x81, 0x8d, 0x49, 0x38, 0x66, 0xa0, +- 0xef, 0xe1, 0x52, 0xe3, 0x66, 0xe8, 0x87, 0x02, 0xfa, 0x78, 0xd7, 0x95, +- 0xac, 0x71, 0x8f, 0x95, 0xbf, 0xa4, 0xeb, 0xb0, 0xad, 0xa4, 0xb9, 0x4a, +- 0xa9, 0x8e, 0xb4, 0xd6, 0x4a, 0x79, 0x71, 0xb3, 0xe6, 0x94, 0x48, 0x14, +- 0xca, 0x6f, 0x4b, 0x2c, 0x61, 0xec, 0xf3, 0xc4, 0xd7, 0xbb, 0x5e, 0x3d, +- 0x79, 0x21, 0x24, 0xaf, 0xf7, 0x90, 0xb7, 0x7b, 0x45, 0x5f, 0x85, 0xcf, +- 0xb3, 0x22, 0x3b, 0x69, 0x8b, 0x1e, 0x6a, 0x94, 0x0d, 0xcc, 0x33, 0x77, +- 0xe1, 0x3c, 0x62, 0x4a, 0xe3, 0xca, 0xc0, 0x0f, 0xfc, 0xb5, 0xe4, 0xfc, +- 0x1b, 0xe8, 0x2b, 0xf2, 0x52, 0x05, 0x8b, 0x37, 0x50, 0x27, 0x55, 0xb1, +- 0xf8, 0x43, 0x62, 0x31, 0x57, 0xc3, 0x62, 0x24, 0x48, 0x92, 0xef, 0x3e, +- 0xc7, 0x62, 0xef, 0x1f, 0xe0, 0xf7, 0x2f, 0x62, 0x6e, 0xbd, 0xe6, 0xf7, +- 0xc8, 0x1c, 0xe6, 0x58, 0x9f, 0x3b, 0x02, 0xf2, 0xb0, 0xc6, 0x9b, 0x8d, +- 0xbe, 0x47, 0xeb, 0xb1, 0xe1, 0xd1, 0x18, 0x6e, 0x7e, 0x54, 0xa9, 0xd7, +- 0x7c, 0x78, 0x2d, 0xe4, 0xa2, 0x5f, 0xa4, 0x27, 0x70, 0xa6, 0x25, 0xe9, +- 0xee, 0x83, 0xee, 0xa3, 0x7a, 0xad, 0xdb, 0x8b, 0x5a, 0xa3, 0x84, 0xd4, +- 0x28, 0xb2, 0xff, 0x7d, 0xe6, 0xfa, 0xa6, 0xa4, 0xcc, 0xef, 0xac, 0x70, +- 0x7f, 0xca, 0xa7, 0x16, 0xdf, 0x6b, 0x98, 0x32, 0xdb, 0x6e, 0x54, 0xb1, +- 0x76, 0x4d, 0x0d, 0x6b, 0x5f, 0x9b, 0xb2, 0xf1, 0x4b, 0xd6, 0x85, 0xcd, +- 0xe9, 0x28, 0x56, 0xeb, 0x1a, 0xef, 0xe8, 0x5e, 0x2a, 0x8a, 0x7e, 0xc6, +- 0xc5, 0x58, 0xaa, 0xa8, 0x37, 0xa8, 0x3b, 0x18, 0xcb, 0x55, 0xec, 0xa7, +- 0xce, 0x50, 0x9f, 0xdc, 0x68, 0x56, 0x7b, 0xa9, 0xd1, 0x9a, 0x3e, 0xb9, +- 0xb1, 0xac, 0xf3, 0xd1, 0x25, 0x06, 0xa2, 0x38, 0xcd, 0x35, 0x7b, 0xfc, +- 0xaa, 0x3e, 0x79, 0x1d, 0xa9, 0xac, 0xd6, 0x27, 0x2e, 0x79, 0xbf, 0x54, +- 0xd1, 0x27, 0x5a, 0x8f, 0x68, 0x2d, 0xa2, 0xfb, 0x85, 0x6e, 0xf6, 0x0b, +- 0x72, 0x5a, 0xeb, 0x15, 0xa3, 0x5b, 0xfa, 0x86, 0x19, 0x61, 0x8d, 0xcc, +- 0x30, 0x96, 0x97, 0x61, 0xd7, 0x23, 0x4d, 0x8c, 0x45, 0x23, 0x76, 0x38, +- 0x2b, 0xac, 0x25, 0x9e, 0xe6, 0x4f, 0x6a, 0x90, 0xdf, 0xd3, 0x2e, 0x47, +- 0x35, 0xc7, 0x32, 0xfe, 0x73, 0xe3, 0xff, 0x5e, 0x1b, 0xd7, 0xf3, 0xb3, +- 0xac, 0xd1, 0x7a, 0xcd, 0x8f, 0xac, 0x2a, 0xee, 0xd1, 0xdc, 0xe4, 0xfd, +- 0x19, 0x2e, 0xd0, 0xc6, 0x37, 0xbf, 0x14, 0x47, 0x9b, 0x79, 0xa1, 0xe3, +- 0xf8, 0x09, 0xd7, 0xea, 0x78, 0xdb, 0x78, 0x87, 0x3e, 0x3e, 0x47, 0x1f, +- 0xff, 0xf2, 0xd1, 0x80, 0xdc, 0x84, 0x4f, 0x0d, 0xfa, 0x78, 0x3b, 0x71, +- 0xf3, 0x63, 0xff, 0x7a, 0xb4, 0xb7, 0x26, 0xdd, 0x0f, 0xcc, 0xb9, 0x7a, +- 0x0b, 0x7b, 0x09, 0x7d, 0xa7, 0xe8, 0x67, 0xdd, 0xeb, 0x1c, 0xa3, 0x7f, +- 0x99, 0xcb, 0x15, 0x0d, 0xd2, 0x6e, 0x56, 0xfd, 0xdb, 0x51, 0xf3, 0x6f, +- 0x66, 0x6a, 0x1b, 0xcf, 0xd1, 0xf5, 0x54, 0xeb, 0xd1, 0xfb, 0x2b, 0xfd, +- 0x92, 0x19, 0xdc, 0x5a, 0x89, 0x55, 0x5d, 0x90, 0xb7, 0x5e, 0x2c, 0xea, +- 0x9a, 0xdd, 0xcf, 0x9a, 0xcd, 0x9e, 0xc9, 0x94, 0x83, 0x83, 0x48, 0x4d, +- 0x73, 0xaf, 0xbd, 0xa7, 0x91, 0x0a, 0xd9, 0x4f, 0x0d, 0x9d, 0x67, 0xef, +- 0x93, 0x31, 0x64, 0x6e, 0xa6, 0xa2, 0x27, 0x6f, 0xad, 0xd5, 0xe9, 0xfe, +- 0x9a, 0xae, 0xbc, 0xbf, 0x76, 0x4e, 0x9e, 0xba, 0x72, 0xee, 0x1c, 0x7d, +- 0x97, 0xcb, 0x2d, 0xfd, 0xac, 0xfb, 0x80, 0x37, 0xfc, 0x9f, 0x29, 0x2c, +- 0x6c, 0xac, 0xe8, 0x8e, 0xcf, 0xef, 0x6c, 0x89, 0x8d, 0xe3, 0x17, 0x55, +- 0xa6, 0xe3, 0x2e, 0x13, 0xf5, 0x4a, 0x59, 0xcb, 0x42, 0x14, 0x4b, 0x33, +- 0xaa, 0x18, 0x97, 0x05, 0x0d, 0xca, 0x96, 0xe0, 0x6e, 0xc6, 0x07, 0xb6, +- 0x15, 0x0c, 0x5a, 0x23, 0x45, 0x39, 0xc4, 0x5e, 0x2e, 0xcf, 0x3e, 0x2c, +- 0xdc, 0x0f, 0xad, 0x6f, 0xf5, 0x79, 0x77, 0xeb, 0x3e, 0x8e, 0xef, 0x83, +- 0xb4, 0x67, 0xee, 0xdc, 0x10, 0x8f, 0x95, 0xfe, 0x4a, 0x3d, 0x16, 0x97, +- 0x39, 0xbd, 0x47, 0x84, 0x73, 0x9e, 0xa8, 0xe8, 0xe7, 0x41, 0xad, 0x9f, +- 0x5d, 0x8d, 0xc7, 0x31, 0x4f, 0xce, 0x9e, 0x40, 0x6a, 0xe0, 0x82, 0x29, +- 0xfb, 0x63, 0xd4, 0xcc, 0xeb, 0x6a, 0x7b, 0xad, 0xa8, 0xed, 0xd5, 0x36, +- 0xf5, 0x10, 0xed, 0xd6, 0x78, 0xac, 0xd6, 0x37, 0x23, 0x88, 0xa1, 0x69, +- 0xd4, 0x63, 0x8d, 0x4f, 0xe6, 0x8e, 0xb0, 0xce, 0xc4, 0x8e, 0xef, 0xa8, +- 0xd8, 0xfb, 0xba, 0xff, 0xa4, 0x59, 0xc9, 0xef, 0x13, 0xba, 0x4e, 0x58, +- 0xb0, 0x58, 0x77, 0xae, 0x1c, 0x93, 0xe1, 0x16, 0xf1, 0x91, 0x5a, 0x92, +- 0xf4, 0x12, 0xab, 0x85, 0xd6, 0x3e, 0x49, 0x6a, 0x9f, 0x18, 0x32, 0x27, +- 0xfe, 0x85, 0xf6, 0x69, 0xfd, 0xa6, 0x6b, 0xa1, 0x83, 0x96, 0x51, 0xaf, +- 0xb3, 0xcd, 0x48, 0x52, 0x3b, 0x3b, 0x68, 0xfe, 0x6c, 0x3f, 0x4b, 0xac, +- 0xe2, 0x3e, 0x75, 0x07, 0x1c, 0x5c, 0x33, 0x26, 0x9d, 0xa3, 0xb8, 0x40, +- 0x0e, 0xf7, 0x06, 0xb5, 0x4e, 0xbc, 0x3a, 0x9d, 0x64, 0x4d, 0x77, 0xd0, +- 0xf5, 0xd9, 0x3e, 0x31, 0xd4, 0x8d, 0xe9, 0xb3, 0x0b, 0xd3, 0x26, 0xe3, +- 0xe4, 0x98, 0x47, 0x39, 0xee, 0xa2, 0xfd, 0x44, 0x23, 0xfb, 0x2d, 0xa5, +- 0xfa, 0x59, 0x0f, 0x2c, 0xd6, 0xdc, 0x5e, 0xb4, 0x0f, 0x8e, 0x88, 0xd4, +- 0x40, 0x23, 0x52, 0xfd, 0x31, 0x78, 0xce, 0x3a, 0xa1, 0x7f, 0x63, 0x98, +- 0xd3, 0x24, 0xc0, 0xe3, 0xc5, 0x3f, 0xe7, 0xba, 0xa4, 0xb3, 0x85, 0x18, +- 0x6b, 0xf9, 0xd3, 0x54, 0xbe, 0x05, 0xa9, 0x21, 0x07, 0x9e, 0xfb, 0x3a, +- 0xe7, 0x15, 0xbe, 0x30, 0xef, 0xd9, 0xca, 0x3c, 0xfa, 0xe2, 0x7a, 0xad, +- 0xb5, 0x94, 0x7a, 0x82, 0x7a, 0xab, 0xe0, 0x68, 0xce, 0x11, 0x18, 0xf6, +- 0xf5, 0x9e, 0x3d, 0xae, 0x05, 0x99, 0xb8, 0x03, 0x9f, 0xa8, 0x42, 0x3c, +- 0xec, 0x8c, 0x54, 0x7e, 0x97, 0x90, 0x4e, 0x8e, 0xdc, 0x36, 0x5d, 0xed, +- 0xb3, 0xd8, 0x17, 0x29, 0xf5, 0x22, 0xb9, 0xe9, 0x09, 0x6a, 0x9f, 0xe1, +- 0xa9, 0x4f, 0xd4, 0x34, 0xb5, 0xcd, 0x88, 0xa7, 0xe7, 0x55, 0x39, 0xe8, +- 0xb0, 0xa3, 0xd4, 0xe3, 0xfc, 0x6e, 0xcf, 0xd4, 0x1c, 0x2f, 0xf1, 0x3c, +- 0x72, 0xc2, 0xed, 0xde, 0x7f, 0xab, 0xcd, 0x5f, 0x9a, 0xab, 0xd4, 0x18, +- 0x6d, 0x78, 0xcb, 0xc7, 0xfd, 0x11, 0x24, 0x73, 0xb3, 0xf4, 0xcf, 0x99, +- 0xe5, 0xb2, 0x7f, 0x8a, 0xf7, 0x5c, 0x2f, 0x64, 0x96, 0x77, 0xec, 0x9d, +- 0x07, 0xcd, 0xb5, 0x92, 0xf9, 0x60, 0x78, 0x75, 0x7c, 0xfe, 0x99, 0x2f, +- 0x13, 0x47, 0xf8, 0xbe, 0x39, 0xa3, 0xf7, 0x50, 0xaa, 0xc7, 0xd7, 0x3d, +- 0xfe, 0x08, 0x7b, 0xfc, 0x82, 0x6a, 0xf0, 0xde, 0x50, 0xcf, 0x75, 0xc8, +- 0xfe, 0x11, 0xe1, 0x71, 0xad, 0xcb, 0xba, 0xa0, 0xfb, 0xaa, 0x11, 0xf6, +- 0x55, 0x2e, 0x9e, 0x26, 0xc7, 0x9c, 0x2c, 0x77, 0xe2, 0xf9, 0xb2, 0x87, +- 0x67, 0x58, 0x3f, 0x9e, 0x2a, 0x5b, 0xd8, 0xfa, 0x88, 0xcc, 0x58, 0x62, +- 0x27, 0xce, 0xfb, 0xd2, 0xf9, 0x1e, 0xed, 0x36, 0x03, 0xb9, 0x7f, 0x25, +- 0x79, 0x85, 0x67, 0x14, 0x72, 0x66, 0x8b, 0xb0, 0x03, 0x1b, 0xdf, 0xe9, +- 0x30, 0x70, 0x38, 0x3e, 0x84, 0xbe, 0xf6, 0xbb, 0xf9, 0xb2, 0xd0, 0x7a, +- 0x40, 0xd7, 0x6a, 0xdd, 0x6f, 0x34, 0xe3, 0x4e, 0xf2, 0xd9, 0xd5, 0x4b, +- 0x43, 0xfc, 0x3a, 0xdd, 0xd6, 0xf9, 0x92, 0xa0, 0x66, 0x68, 0x91, 0x59, +- 0xe0, 0xa7, 0xd8, 0xc8, 0x7e, 0x21, 0xb3, 0x6c, 0x7f, 0xad, 0x37, 0xff, +- 0x29, 0x56, 0xea, 0x3e, 0xc3, 0x6f, 0x66, 0xbd, 0xab, 0xc6, 0xe1, 0x70, +- 0xc5, 0x8f, 0x06, 0x9a, 0x0e, 0x16, 0x54, 0xbd, 0x27, 0x73, 0x93, 0x15, +- 0x1d, 0xb5, 0xd0, 0xb9, 0x91, 0x7d, 0x40, 0xc3, 0x01, 0xcf, 0x5d, 0x27, +- 0x14, 0x63, 0xb1, 0x9b, 0xb1, 0x48, 0x86, 0x31, 0xb6, 0xdb, 0xcd, 0x41, +- 0x32, 0x6c, 0x16, 0x79, 0x71, 0x8b, 0xae, 0xb1, 0x75, 0xf5, 0xec, 0xbf, +- 0x59, 0x53, 0x27, 0x0d, 0xf6, 0x23, 0xba, 0x1f, 0x8f, 0x62, 0x2a, 0xdd, +- 0xc6, 0x3e, 0x29, 0x8a, 0xed, 0xe9, 0x1e, 0xea, 0x1a, 0x03, 0xc6, 0xc1, +- 0x4b, 0x6a, 0xe5, 0x17, 0xfa, 0x88, 0x4d, 0xe3, 0x9a, 0xc3, 0x6c, 0xb1, +- 0x91, 0xf9, 0x9b, 0x59, 0x46, 0xb1, 0x76, 0x8b, 0xee, 0xe1, 0xf5, 0x1d, +- 0x1c, 0xf6, 0xc7, 0x06, 0xa6, 0x17, 0x38, 0xd8, 0xd5, 0x2d, 0x13, 0x05, +- 0xe8, 0x5c, 0xfe, 0x6a, 0x4d, 0x81, 0x93, 0xfd, 0xbd, 0x3a, 0x03, 0x67, +- 0x03, 0x6d, 0x91, 0x75, 0x4a, 0xb5, 0xa6, 0x4d, 0xe4, 0x2a, 0xf5, 0x26, +- 0xe1, 0x64, 0xd9, 0xff, 0xcd, 0x4c, 0xb1, 0x27, 0x3b, 0xa8, 0xd4, 0x4e, +- 0x62, 0xe9, 0xe3, 0x8e, 0xe1, 0x43, 0xec, 0xc4, 0xf7, 0xb6, 0xb2, 0xb7, +- 0xfa, 0x3a, 0xdb, 0xb7, 0xb7, 0x8a, 0xdf, 0x24, 0x7f, 0x1b, 0xdd, 0x09, +- 0xe8, 0x7e, 0xa7, 0xa0, 0x22, 0x9e, 0x37, 0xfb, 0x38, 0xb5, 0xe0, 0x6f, +- 0x96, 0x75, 0xc1, 0x9d, 0x5f, 0xf5, 0xd5, 0x6a, 0x6a, 0xa9, 0x8f, 0xc8, +- 0xf9, 0x61, 0xe5, 0x73, 0xcc, 0x59, 0x37, 0x7e, 0x49, 0x6d, 0xa6, 0x6f, +- 0x7a, 0xaa, 0x76, 0x59, 0xf5, 0x01, 0x9b, 0xc4, 0x6b, 0xe1, 0xac, 0xf9, +- 0x03, 0x36, 0x7d, 0x5e, 0xef, 0x62, 0xce, 0x9a, 0xf1, 0xc5, 0xb4, 0x51, +- 0xba, 0xd3, 0x15, 0xfc, 0xf8, 0xf8, 0xc8, 0x1b, 0x4e, 0xcc, 0x47, 0xa1, +- 0x93, 0x39, 0x36, 0xfb, 0x4f, 0x1c, 0x6b, 0x5f, 0x0a, 0xfc, 0xa6, 0xfc, +- 0x5d, 0xf2, 0xbe, 0xd1, 0xd5, 0x82, 0xc2, 0x0c, 0x6d, 0x3c, 0xf4, 0x75, +- 0x62, 0x32, 0x3f, 0x86, 0xfb, 0xd8, 0x46, 0xe0, 0x59, 0xd6, 0xdb, 0x63, +- 0xe4, 0x8c, 0xe6, 0xb4, 0x83, 0x32, 0x9f, 0x8f, 0x94, 0x92, 0x83, 0xa7, +- 0x99, 0xb7, 0xc7, 0xf9, 0x7c, 0x94, 0xf7, 0xdc, 0x4a, 0x7d, 0x77, 0xef, +- 0x78, 0x3d, 0xbe, 0x3d, 0x1e, 0xc3, 0xd6, 0xf1, 0x80, 0x9a, 0x02, 0xb7, +- 0x35, 0x72, 0xdf, 0x57, 0x89, 0xe7, 0xcd, 0x4b, 0xaf, 0xc3, 0x5a, 0x27, +- 0xe9, 0xde, 0xcd, 0xdc, 0xab, 0x3b, 0x08, 0xc7, 0x21, 0x8e, 0xfe, 0xd9, +- 0x5b, 0x2e, 0xd0, 0x44, 0xbd, 0xbf, 0xd4, 0x12, 0xeb, 0xc7, 0x57, 0x57, +- 0x9e, 0x47, 0xd2, 0x79, 0x6a, 0x0b, 0x62, 0xb2, 0x44, 0x4c, 0x32, 0x36, +- 0x4f, 0x97, 0x88, 0x4b, 0x6a, 0xc3, 0x93, 0x25, 0x8d, 0x6d, 0x1f, 0xcf, +- 0x75, 0x0c, 0xa9, 0x2a, 0x56, 0x3e, 0x55, 0x4f, 0x78, 0xaf, 0x45, 0x50, +- 0x6f, 0xe9, 0xdf, 0x76, 0xf0, 0x66, 0x31, 0xe1, 0x6c, 0x28, 0x6b, 0x3c, +- 0xfc, 0x6d, 0x0d, 0x0f, 0x6f, 0x47, 0xaa, 0xfa, 0x44, 0xce, 0x4c, 0x42, +- 0x73, 0xdd, 0x62, 0xe7, 0xa6, 0xd2, 0xf0, 0x34, 0x7d, 0x9f, 0xa7, 0xc6, +- 0x76, 0xdf, 0x67, 0xc8, 0xc7, 0xa6, 0x8c, 0x2e, 0xf6, 0xd4, 0xf4, 0x87, +- 0xbe, 0x33, 0xf3, 0x37, 0x2d, 0x3b, 0x75, 0x4c, 0x8e, 0x17, 0x71, 0x2b, +- 0xfb, 0x1e, 0x3f, 0x44, 0xf5, 0x6e, 0x53, 0xbc, 0xf3, 0x43, 0xbc, 0xf3, +- 0x0f, 0xf9, 0x3c, 0x51, 0x4a, 0x66, 0x7b, 0x78, 0xe7, 0x27, 0xf9, 0x3c, +- 0x59, 0x6a, 0xad, 0xd3, 0x67, 0x4c, 0x4e, 0x85, 0xac, 0x03, 0x2f, 0xab, +- 0x52, 0xbc, 0x12, 0x0e, 0xf6, 0xc0, 0x06, 0x1a, 0x0e, 0xce, 0xf1, 0xb3, +- 0xfe, 0x6d, 0x49, 0xd7, 0x38, 0xcd, 0xf9, 0x83, 0xba, 0x26, 0x67, 0xae, +- 0x14, 0x97, 0xd4, 0x47, 0x9e, 0x0c, 0x9f, 0xc6, 0x29, 0x35, 0x1f, 0xa9, +- 0x99, 0xf9, 0x42, 0x4e, 0xaf, 0x30, 0xa4, 0xbb, 0xc8, 0xac, 0x72, 0x75, +- 0x67, 0x8d, 0xab, 0xbd, 0xa9, 0x1b, 0xeb, 0xaa, 0x77, 0x48, 0x39, 0x47, +- 0x30, 0x8f, 0xd8, 0xd7, 0x35, 0x55, 0xf3, 0x8f, 0xfe, 0x4c, 0x7d, 0x67, +- 0x85, 0x09, 0x93, 0x7e, 0x08, 0x6f, 0xd5, 0x63, 0xd1, 0xda, 0x6f, 0x3e, +- 0x29, 0x5f, 0xf7, 0x82, 0xd3, 0xf1, 0x1e, 0x7e, 0xa7, 0x7b, 0xc1, 0x4f, +- 0x54, 0x2e, 0xde, 0xf3, 0x19, 0x67, 0x15, 0xd0, 0x45, 0xed, 0xf1, 0x3e, +- 0x39, 0xa1, 0x83, 0x2a, 0x4a, 0xe0, 0x14, 0xfb, 0xb0, 0x23, 0x5d, 0x49, +- 0x67, 0x17, 0xf7, 0x0b, 0x1d, 0x87, 0x5c, 0xb0, 0x93, 0x3a, 0x93, 0x73, +- 0xca, 0x1d, 0x5c, 0xa3, 0xb9, 0xf0, 0x3e, 0xfa, 0xe6, 0xb7, 0xed, 0x96, +- 0xe7, 0x63, 0x57, 0xe9, 0x39, 0xc3, 0xf2, 0xb4, 0x5f, 0x52, 0x99, 0x5d, +- 0xb4, 0xe7, 0x2c, 0xed, 0x89, 0x78, 0x21, 0xb9, 0x31, 0x55, 0x59, 0x5f, +- 0xb0, 0xb4, 0x1d, 0x15, 0x7b, 0x38, 0xa6, 0x39, 0x4f, 0xf6, 0x9f, 0x62, +- 0x8d, 0xdd, 0x02, 0xfd, 0x3b, 0x85, 0xb6, 0xa1, 0x2d, 0xb1, 0x85, 0xf6, +- 0x1c, 0x8e, 0x57, 0xf8, 0x94, 0xdf, 0xf1, 0xbc, 0x92, 0xb1, 0xbe, 0x9e, +- 0x78, 0xbf, 0x22, 0x9d, 0x60, 0x6c, 0xbb, 0xa8, 0xef, 0xab, 0x71, 0xde, +- 0x57, 0xc1, 0xf2, 0xff, 0x00, 0xb0, 0x60, 0x72, 0xf9, 0x60, 0x17, 0x00, +- 0x00, 0x00 }; ++ 0xbd, 0x59, 0x6d, 0x70, 0x5b, 0x55, 0x7a, 0x7e, 0xae, 0x74, 0x25, 0x5d, ++ 0xdb, 0xb2, 0x75, 0x8d, 0x95, 0x20, 0xb7, 0x2e, 0xd6, 0x8d, 0xaf, 0x6c, ++ 0x11, 0xb9, 0xe1, 0x2a, 0x36, 0x45, 0x19, 0xee, 0x94, 0x1b, 0x7f, 0x21, ++ 0x92, 0x10, 0x94, 0x42, 0x5b, 0x67, 0x96, 0x19, 0x4c, 0xe2, 0x4d, 0x4c, ++ 0x08, 0x6c, 0xba, 0xcb, 0x4c, 0xdd, 0xd9, 0x4c, 0x23, 0xfc, 0x15, 0x93, ++ 0xc8, 0x16, 0x6b, 0x20, 0x26, 0x3b, 0x3b, 0x43, 0xc6, 0xf9, 0x70, 0x0a, ++ 0x72, 0x14, 0xda, 0x3f, 0x3b, 0xd3, 0x65, 0xf0, 0x6c, 0x12, 0x12, 0x58, ++ 0xd8, 0xb4, 0xd3, 0x3f, 0xc9, 0xf4, 0xc7, 0x7a, 0x21, 0xa1, 0x81, 0x42, ++ 0x36, 0xed, 0x0c, 0x9d, 0x50, 0x68, 0x4e, 0x9f, 0x73, 0x25, 0x07, 0x13, ++ 0xb2, 0xfd, 0xd9, 0xcc, 0x08, 0x4b, 0xe7, 0xde, 0x73, 0xce, 0x7b, 0xce, ++ 0xfb, 0x3c, 0xcf, 0xfb, 0x9c, 0xc3, 0x0a, 0x05, 0x95, 0x28, 0xff, 0xab, ++ 0xe6, 0xa7, 0xfd, 0xc9, 0x5d, 0xcf, 0xad, 0x5e, 0xd5, 0xbe, 0x8a, 0x5f, ++ 0x57, 0x2b, 0xcb, 0x55, 0x15, 0xff, 0x8f, 0xff, 0xbc, 0x80, 0xbe, 0x18, ++ 0x87, 0xfc, 0x40, 0xf3, 0xd8, 0xf3, 0x77, 0x75, 0x98, 0xd0, 0xbc, 0xf6, ++ 0x63, 0x4d, 0x5b, 0x4d, 0xc0, 0x29, 0x24, 0xa2, 0x9d, 0xf8, 0x1f, 0x91, ++ 0x0d, 0xab, 0x90, 0xed, 0x7f, 0x64, 0x7f, 0x7d, 0xcf, 0x5b, 0xf7, 0x19, ++ 0xd7, 0x0e, 0x79, 0xa1, 0xe9, 0xf6, 0xb8, 0xaa, 0x37, 0x43, 0x6b, 0x60, ++ 0x9f, 0x9f, 0xb5, 0xf4, 0xfb, 0x50, 0xb3, 0x38, 0x16, 0x70, 0x38, 0x67, ++ 0x58, 0xdb, 0x90, 0xd0, 0x4f, 0x41, 0x85, 0xc3, 0x39, 0x8e, 0x15, 0x80, ++ 0xbd, 0x39, 0x05, 0x97, 0x39, 0xe6, 0x68, 0x41, 0xc3, 0x82, 0xd7, 0x9d, ++ 0xae, 0xaf, 0xc2, 0x46, 0xc6, 0x9c, 0xd8, 0x23, 0x02, 0x26, 0xb2, 0x7f, ++ 0x60, 0x9b, 0xf1, 0xbd, 0x08, 0xa6, 0x66, 0xda, 0x91, 0x59, 0x31, 0xa7, ++ 0x61, 0x73, 0xbe, 0xa1, 0x4f, 0xb3, 0xc1, 0x77, 0x14, 0xa4, 0xee, 0xd3, ++ 0xd0, 0x5b, 0x8c, 0x23, 0x5b, 0xcc, 0xc2, 0x29, 0x8e, 0xf0, 0xa3, 0x21, ++ 0x30, 0xa1, 0x69, 0xf7, 0x4c, 0x2c, 0x97, 0xef, 0x20, 0x38, 0x71, 0x4d, ++ 0x5c, 0x4d, 0xea, 0x78, 0x6f, 0x8d, 0x10, 0xd5, 0x36, 0xb2, 0x55, 0xed, ++ 0x59, 0x78, 0x6d, 0xc3, 0x5a, 0xef, 0x55, 0xd0, 0xf5, 0xc7, 0x66, 0x7c, ++ 0x42, 0x79, 0xf4, 0x51, 0x8f, 0x0d, 0x4d, 0xb1, 0xa3, 0x6a, 0x53, 0xa1, ++ 0x01, 0x63, 0x45, 0x1d, 0x7b, 0x8b, 0x61, 0x8c, 0x14, 0xb1, 0xdb, 0x7b, ++ 0xaf, 0x1f, 0x33, 0x3a, 0x9c, 0xef, 0xb5, 0xec, 0xc6, 0x8e, 0xdc, 0x20, ++ 0xb6, 0xe6, 0x52, 0xd8, 0x57, 0x94, 0x31, 0x46, 0x31, 0x5c, 0x54, 0xe1, ++ 0x9f, 0x30, 0x22, 0xef, 0xe2, 0x76, 0xcf, 0x84, 0x18, 0xb1, 0x02, 0x18, ++ 0xb2, 0xe2, 0x18, 0xcd, 0x7b, 0xb8, 0xce, 0x00, 0x86, 0xcd, 0xeb, 0xa2, ++ 0xdf, 0x32, 0xac, 0x51, 0x88, 0xc6, 0xd3, 0x96, 0x11, 0xe9, 0xf2, 0xc2, ++ 0xf9, 0xb1, 0x19, 0xc1, 0x28, 0x63, 0x1f, 0x71, 0xfb, 0x8d, 0xa0, 0xeb, ++ 0x66, 0x3f, 0x87, 0xfd, 0x74, 0x8c, 0x7d, 0xbb, 0x6f, 0x74, 0x14, 0x89, ++ 0xc8, 0x18, 0x3c, 0xe8, 0x0b, 0xb7, 0xb2, 0x5f, 0x53, 0x74, 0x0c, 0x46, ++ 0x9c, 0xe3, 0x64, 0xfd, 0xed, 0x0e, 0xc7, 0xc8, 0xb2, 0xbf, 0x11, 0x3d, ++ 0x06, 0x39, 0x56, 0x03, 0x7f, 0xb7, 0xb3, 0xbf, 0x02, 0x8f, 0x1d, 0x8b, ++ 0x0e, 0xb1, 0xcf, 0x29, 0x4b, 0xc5, 0x19, 0x7e, 0xfa, 0x74, 0x43, 0x66, ++ 0x56, 0x09, 0xb0, 0x7d, 0x2f, 0xf8, 0xdc, 0xac, 0xc2, 0xa1, 0x8c, 0x85, ++ 0x21, 0xae, 0x5b, 0x63, 0xdb, 0x38, 0xdb, 0x7c, 0xa6, 0xc5, 0xf1, 0xa1, ++ 0x77, 0x15, 0x97, 0x62, 0x62, 0x31, 0x37, 0xbf, 0xaf, 0x9d, 0x63, 0xe4, ++ 0x4b, 0x39, 0x95, 0xef, 0x74, 0xe6, 0x6f, 0x88, 0x27, 0xd5, 0xa5, 0xcf, ++ 0x07, 0x95, 0x0e, 0xb6, 0x39, 0x6a, 0x03, 0xf6, 0xe6, 0xa1, 0xf9, 0x4d, ++ 0x8d, 0xf3, 0x68, 0xf8, 0x28, 0x37, 0xa8, 0xf4, 0x14, 0x1d, 0xa5, 0x7b, ++ 0xb6, 0x43, 0x71, 0x66, 0x55, 0xa5, 0x6b, 0x5a, 0xc6, 0x2d, 0xc4, 0x0b, ++ 0x96, 0xc2, 0x98, 0x7f, 0x22, 0xe3, 0x75, 0xa2, 0xca, 0x0d, 0xb1, 0x32, ++ 0xe6, 0x41, 0x95, 0xd9, 0xa3, 0xac, 0x9f, 0x15, 0x22, 0x9d, 0x4c, 0x2b, ++ 0xeb, 0x66, 0xa1, 0x05, 0x6d, 0x5b, 0xcd, 0x4d, 0xec, 0x43, 0x76, 0x99, ++ 0x89, 0x83, 0xf9, 0x28, 0x3e, 0xb0, 0x3c, 0x38, 0xb4, 0xac, 0x02, 0xaa, ++ 0xa9, 0xf0, 0x83, 0xe0, 0x79, 0x0b, 0x6a, 0x0d, 0xbf, 0x5f, 0xdd, 0xa4, ++ 0x62, 0xa4, 0x7d, 0x9d, 0xd2, 0xc5, 0x3e, 0x3e, 0xe6, 0xf9, 0x68, 0x2e, ++ 0x8d, 0x20, 0xb1, 0x53, 0x65, 0xc7, 0x22, 0x05, 0xee, 0xcd, 0x7b, 0x56, ++ 0x2c, 0xfe, 0xb4, 0xc4, 0x63, 0xad, 0x11, 0x91, 0x7b, 0x53, 0x6d, 0xc7, ++ 0xe2, 0x73, 0xdc, 0x07, 0xaf, 0xa9, 0xe2, 0xd7, 0x96, 0x0f, 0xf3, 0x9b, ++ 0x2c, 0xe6, 0x54, 0x87, 0x9f, 0xed, 0xc7, 0xdc, 0x76, 0xf9, 0x1b, 0x7a, ++ 0xf7, 0xb7, 0xf6, 0xa1, 0xb4, 0x07, 0xc3, 0xf9, 0x26, 0xc6, 0x5c, 0xda, ++ 0x83, 0x47, 0xb8, 0xde, 0xdf, 0xfa, 0xe4, 0xd7, 0xbb, 0x6e, 0xb6, 0x6d, ++ 0x66, 0x9c, 0x1e, 0xdb, 0x9c, 0x5f, 0xe1, 0xad, 0x07, 0xea, 0xda, 0xb1, ++ 0x8f, 0x39, 0xee, 0x4a, 0x2e, 0x47, 0xd6, 0x7d, 0x1e, 0xd6, 0xd7, 0x4f, ++ 0xd7, 0xa1, 0x6f, 0x99, 0xbb, 0x6f, 0xfa, 0xc6, 0x69, 0x21, 0xce, 0x24, ++ 0xfd, 0x98, 0x33, 0x87, 0x22, 0xd5, 0xc8, 0x5a, 0x5e, 0xe6, 0xfb, 0x2c, ++ 0xe7, 0x2f, 0x24, 0xbd, 0x38, 0x9c, 0x3c, 0x84, 0x6c, 0x2d, 0x30, 0x93, ++ 0x93, 0xbc, 0x32, 0xe6, 0xcf, 0xf2, 0xbf, 0x9e, 0xa2, 0x5c, 0x9f, 0xc5, ++ 0xf5, 0x29, 0x38, 0x66, 0x4a, 0x4c, 0x5b, 0x6a, 0x33, 0xf9, 0xb5, 0x83, ++ 0xfb, 0x59, 0xdf, 0x1e, 0x24, 0x3e, 0x81, 0x0f, 0x73, 0xfd, 0xd8, 0x5c, ++ 0x8a, 0x05, 0xd7, 0x73, 0x50, 0x7c, 0x6d, 0x69, 0x1c, 0x2a, 0xfd, 0x26, ++ 0xc7, 0xd3, 0x6a, 0x47, 0xce, 0xc8, 0xa4, 0x91, 0x38, 0xd7, 0xa1, 0xc8, ++ 0xfe, 0x69, 0x75, 0x65, 0xc1, 0x8f, 0x68, 0x5d, 0xe9, 0x79, 0x95, 0xbd, ++ 0x41, 0x7d, 0x7a, 0x42, 0xc1, 0xf6, 0x98, 0x7c, 0xb6, 0x41, 0x6d, 0x29, ++ 0x40, 0xab, 0xb6, 0x77, 0xa9, 0x73, 0x13, 0x46, 0xdf, 0x71, 0x25, 0x11, ++ 0x9d, 0x70, 0xfb, 0xec, 0x52, 0x5b, 0x0b, 0x01, 0xae, 0x27, 0xce, 0x9c, ++ 0x40, 0xab, 0xb1, 0x9f, 0x53, 0x7f, 0xcd, 0x07, 0xe7, 0xdc, 0x3e, 0xcf, ++ 0xa9, 0xf1, 0x82, 0x6c, 0x37, 0xac, 0xa8, 0x12, 0xc0, 0xdd, 0x49, 0x0d, ++ 0x2b, 0x5b, 0x44, 0x63, 0x77, 0xd2, 0x98, 0xef, 0xf6, 0x46, 0x70, 0x90, ++ 0x5c, 0x20, 0xee, 0x9c, 0x3f, 0x6c, 0x19, 0x41, 0x77, 0xd1, 0x8b, 0x68, ++ 0xad, 0x83, 0xfd, 0xf9, 0x00, 0x7e, 0x49, 0xfc, 0xf7, 0x58, 0x3a, 0x46, ++ 0xf2, 0x46, 0xfc, 0x57, 0x48, 0xa4, 0x8e, 0x30, 0x67, 0x0b, 0xe4, 0xc0, ++ 0xfe, 0x62, 0x53, 0xfc, 0x08, 0x8c, 0x81, 0x6e, 0x72, 0x40, 0x6b, 0x97, ++ 0x31, 0x40, 0x57, 0x6d, 0x72, 0xa7, 0xd8, 0x80, 0x1c, 0xf9, 0xd0, 0xed, ++ 0xf2, 0x6a, 0x50, 0xe9, 0x2a, 0xbe, 0x4f, 0x6d, 0xed, 0x21, 0xbe, 0x10, ++ 0x8a, 0x98, 0x7e, 0xa4, 0xea, 0xa2, 0x38, 0x4d, 0xac, 0x64, 0xc3, 0x15, ++ 0xcc, 0xa5, 0xcc, 0xe7, 0x45, 0x3e, 0x5f, 0xa7, 0x74, 0xce, 0x46, 0xf1, ++ 0x4b, 0xeb, 0x6b, 0xe1, 0x84, 0xab, 0xd9, 0xe6, 0x5b, 0xd2, 0xae, 0xe1, ++ 0xf2, 0xcb, 0x95, 0xf8, 0xf4, 0xe5, 0x20, 0xbe, 0x7c, 0x99, 0xfc, 0xce, ++ 0xa3, 0xbd, 0x12, 0x42, 0xa4, 0xda, 0x84, 0x28, 0x5a, 0xad, 0xf8, 0xa8, ++ 0x36, 0x16, 0xbd, 0x00, 0xa9, 0x8d, 0x8e, 0xba, 0x35, 0x67, 0xec, 0x1a, ++ 0x40, 0xc2, 0x39, 0xe5, 0xee, 0x85, 0xa3, 0xae, 0x2a, 0x9c, 0x16, 0xd8, ++ 0x54, 0xda, 0x0b, 0xbf, 0xdd, 0xa5, 0xbe, 0xc3, 0xdc, 0x9c, 0x77, 0x73, ++ 0xd3, 0xa5, 0xde, 0x53, 0xb8, 0xdf, 0x83, 0xca, 0xd2, 0x33, 0xd5, 0xce, ++ 0xa8, 0x23, 0x39, 0xa3, 0x77, 0x9c, 0xeb, 0xeb, 0x77, 0xfb, 0x66, 0xd4, ++ 0x04, 0xf7, 0x7e, 0xa1, 0x9c, 0x9b, 0x6a, 0xfb, 0x31, 0xee, 0x33, 0x73, ++ 0xef, 0xee, 0xe3, 0x63, 0xdc, 0x63, 0x39, 0xdf, 0xe0, 0x2d, 0xf3, 0x0d, ++ 0x72, 0xbe, 0xe3, 0x4b, 0xe6, 0xdb, 0xbd, 0x64, 0xbe, 0xdd, 0x4b, 0xe6, ++ 0x4b, 0x91, 0xab, 0xff, 0x22, 0x86, 0xc2, 0xa5, 0xb1, 0x55, 0x7b, 0xe0, ++ 0x96, 0xb9, 0x07, 0x38, 0xf7, 0x01, 0xb1, 0x90, 0x29, 0x8d, 0x53, 0x6d, ++ 0xef, 0x5c, 0x32, 0xf7, 0x4e, 0xce, 0xbd, 0x38, 0x8e, 0x4e, 0x2d, 0x12, ++ 0x62, 0xa3, 0x25, 0x84, 0x6a, 0x9b, 0x7a, 0x17, 0x9a, 0x33, 0x5d, 0xc4, ++ 0x4e, 0x25, 0x12, 0xf3, 0x1e, 0x98, 0x83, 0xf5, 0x5e, 0x1f, 0x16, 0x6a, ++ 0x17, 0xb9, 0x51, 0x5d, 0xfe, 0xfb, 0x9a, 0x02, 0x6a, 0xfd, 0x1b, 0xb9, ++ 0x10, 0xc7, 0x88, 0xe9, 0xfd, 0x8a, 0x10, 0xa7, 0xd6, 0x24, 0x06, 0xbc, ++ 0x48, 0xf4, 0xd5, 0xc0, 0x24, 0x86, 0x7c, 0x65, 0x2e, 0x2c, 0xed, 0x73, ++ 0xdc, 0xed, 0x53, 0x74, 0xfb, 0x08, 0xf1, 0xe1, 0xbd, 0x57, 0xc4, 0x5b, ++ 0x2d, 0x61, 0xbc, 0x4d, 0x4e, 0x9e, 0x2c, 0x2e, 0xea, 0x8a, 0xd4, 0x0d, ++ 0x78, 0x4e, 0x59, 0x7e, 0xc6, 0x34, 0xb4, 0xc3, 0xff, 0xad, 0xfe, 0x04, ++ 0x8c, 0x29, 0xdb, 0xbc, 0x78, 0x3d, 0x89, 0x27, 0x2b, 0x61, 0xf4, 0xee, ++ 0x53, 0xb2, 0xe9, 0x2a, 0x18, 0xce, 0x4a, 0x25, 0x9b, 0xd2, 0x20, 0x79, ++ 0xa3, 0x36, 0x1e, 0x35, 0x8d, 0xec, 0x65, 0xbe, 0xac, 0x4e, 0xde, 0x2e, ++ 0x06, 0x95, 0x63, 0x04, 0xf1, 0x6c, 0xfe, 0x7d, 0xcc, 0xfb, 0xa4, 0x86, ++ 0x49, 0xed, 0xe4, 0xc0, 0x27, 0xa4, 0x86, 0x05, 0x48, 0x44, 0x15, 0x7b, ++ 0xf2, 0x9e, 0xd3, 0x8d, 0x10, 0xf0, 0xb7, 0xf9, 0x70, 0xd1, 0x1c, 0xb6, ++ 0xea, 0xb1, 0x16, 0xe7, 0x5b, 0xb9, 0x07, 0xcb, 0x54, 0x44, 0x66, 0x96, ++ 0x8e, 0x15, 0xe1, 0x58, 0x11, 0x7c, 0x92, 0x13, 0xa2, 0xd2, 0x36, 0xe2, ++ 0x0b, 0x30, 0x19, 0x47, 0x04, 0x57, 0x0a, 0x5b, 0xfc, 0xa8, 0x09, 0x43, ++ 0x6d, 0x56, 0xb1, 0x3d, 0xaf, 0x29, 0xdd, 0x79, 0xe8, 0x5e, 0xdb, 0x8c, ++ 0x1e, 0xc6, 0x51, 0xc6, 0xc3, 0xba, 0x76, 0x4c, 0x55, 0x36, 0x4e, 0x07, ++ 0x50, 0x3d, 0xf5, 0x99, 0x78, 0x9f, 0x7a, 0xf8, 0xc6, 0xbd, 0xac, 0x17, ++ 0xc9, 0x00, 0xaa, 0xdc, 0xb9, 0x85, 0xf8, 0xb8, 0xad, 0x0e, 0x17, 0x39, ++ 0x5f, 0xf4, 0x2f, 0x03, 0xf0, 0x4e, 0x05, 0xe0, 0x9b, 0x52, 0x30, 0xd3, ++ 0x1e, 0x80, 0x67, 0x46, 0xfe, 0x56, 0x10, 0x30, 0xa7, 0xb1, 0x5d, 0x6f, ++ 0xc0, 0x78, 0x9e, 0x45, 0xda, 0xfc, 0x19, 0x06, 0xdc, 0xef, 0x2a, 0x9e, ++ 0xca, 0x6b, 0x08, 0x1d, 0x10, 0xa2, 0xd1, 0x16, 0x22, 0x96, 0xf4, 0x60, ++ 0xd6, 0x1c, 0x8e, 0x06, 0xb8, 0x8e, 0x61, 0x4b, 0x6a, 0x8e, 0x0f, 0xea, ++ 0x8c, 0x91, 0x39, 0xc7, 0xa8, 0x37, 0x4f, 0xa8, 0x4a, 0xef, 0xf4, 0x1e, ++ 0xc1, 0x98, 0xfa, 0x1e, 0xf0, 0x0a, 0x51, 0xd3, 0xd6, 0x34, 0x70, 0x9e, ++ 0xda, 0x3c, 0x13, 0x8b, 0xf5, 0x0e, 0x29, 0xc0, 0xfa, 0x39, 0x1f, 0xfc, ++ 0x53, 0xff, 0xc5, 0x3a, 0x2b, 0x44, 0xe1, 0x5e, 0x81, 0x77, 0xad, 0x6c, ++ 0xbc, 0x02, 0x46, 0xea, 0x24, 0xc2, 0xb8, 0xf4, 0xa2, 0x10, 0xdb, 0xdb, ++ 0x43, 0x78, 0xcd, 0x32, 0x76, 0x7d, 0xec, 0x15, 0xb8, 0x98, 0xcc, 0x0e, ++ 0xd6, 0x53, 0xb7, 0xae, 0x29, 0x51, 0x54, 0xe5, 0x8d, 0xcc, 0x15, 0x85, ++ 0x4b, 0x9f, 0x31, 0xf5, 0x9d, 0x4a, 0x10, 0x55, 0x27, 0x82, 0xe8, 0x98, ++ 0xf3, 0xa3, 0x62, 0x2a, 0x08, 0xef, 0xa4, 0x79, 0xfd, 0x41, 0xb8, 0xe3, ++ 0x58, 0x27, 0xd1, 0x8c, 0x8b, 0x2f, 0x1b, 0xf3, 0xc7, 0x89, 0x93, 0xed, ++ 0x88, 0xe2, 0x37, 0x05, 0x13, 0x17, 0x0b, 0x41, 0xa8, 0x27, 0x74, 0xd4, ++ 0xbb, 0xf5, 0x4e, 0x47, 0xb5, 0xe9, 0x61, 0x5e, 0x1c, 0xe5, 0x61, 0xb7, ++ 0x9e, 0x74, 0xf1, 0xd3, 0xa3, 0x74, 0xb0, 0xae, 0x6c, 0x98, 0x26, 0x95, ++ 0xf9, 0xec, 0x9c, 0x75, 0x43, 0xec, 0x8f, 0xa5, 0x59, 0x47, 0x2a, 0xe0, ++ 0xb3, 0xd7, 0xb1, 0x8e, 0xb0, 0x38, 0xb9, 0xba, 0x5f, 0xa1, 0xf8, 0xec, ++ 0xef, 0x6a, 0x7e, 0x88, 0x9a, 0x5f, 0xfc, 0x3f, 0x35, 0x5f, 0x85, 0x3a, ++ 0xe5, 0xc1, 0x98, 0x19, 0xc0, 0x6f, 0xac, 0xa6, 0x73, 0x8d, 0x08, 0x20, ++ 0xd5, 0xa6, 0x23, 0x72, 0xc2, 0xc2, 0x8b, 0xdc, 0x5b, 0xdc, 0x71, 0x6b, ++ 0x3d, 0x04, 0x76, 0x92, 0x53, 0x15, 0xd4, 0x86, 0xbb, 0x27, 0x82, 0xd4, ++ 0x29, 0x55, 0x59, 0x4f, 0x9d, 0xdf, 0x91, 0xbc, 0x21, 0xd2, 0x31, 0x23, ++ 0x1e, 0x57, 0x12, 0xa9, 0xbf, 0x43, 0x49, 0x3b, 0x62, 0xd4, 0xd1, 0x05, ++ 0x7d, 0x91, 0x83, 0x5d, 0x2e, 0x07, 0x67, 0x62, 0x25, 0xed, 0x58, 0x51, ++ 0x28, 0xf1, 0xef, 0x01, 0xea, 0xe7, 0xf5, 0xb6, 0x92, 0x76, 0xbe, 0x4a, ++ 0xff, 0xd3, 0xcb, 0xf1, 0x1e, 0x99, 0x36, 0xb2, 0xbd, 0xcc, 0xcf, 0x25, ++ 0x62, 0x63, 0x92, 0x19, 0x9c, 0xaf, 0xa5, 0xa6, 0x36, 0x07, 0x18, 0xe3, ++ 0x75, 0x71, 0x9a, 0xde, 0x62, 0x98, 0xfd, 0x46, 0xf3, 0x46, 0x74, 0x98, ++ 0x7c, 0x1f, 0x2d, 0x6b, 0xe9, 0x30, 0xfd, 0xc4, 0x28, 0xf3, 0xf4, 0x36, ++ 0x9f, 0x9d, 0xcc, 0x1b, 0xe9, 0x2e, 0x57, 0x53, 0xa5, 0xaf, 0x90, 0x31, ++ 0x49, 0x6f, 0x11, 0xc1, 0x5b, 0x2d, 0x52, 0x5f, 0x1b, 0xa8, 0xaf, 0x8b, ++ 0xba, 0x2a, 0xf1, 0x70, 0x4d, 0x84, 0x5a, 0x42, 0x5e, 0xc9, 0xcb, 0x4b, ++ 0x49, 0x21, 0xaa, 0xec, 0x20, 0x2a, 0x27, 0xcc, 0xf4, 0x7a, 0x25, 0x16, ++ 0x31, 0x95, 0xbb, 0xd8, 0xce, 0x1c, 0xce, 0x6d, 0xf2, 0xba, 0xde, 0xf6, ++ 0x84, 0x10, 0x21, 0x5b, 0x47, 0xcd, 0x84, 0x49, 0xdc, 0xc4, 0xfa, 0x8e, ++ 0xb8, 0xcf, 0x75, 0x04, 0xe7, 0x16, 0xc8, 0xe7, 0x08, 0xf9, 0x1c, 0xc6, ++ 0x9b, 0xb7, 0x70, 0x9a, 0x5a, 0xeb, 0xe9, 0x27, 0xa7, 0xb3, 0xe1, 0xa1, ++ 0x2d, 0xde, 0x6f, 0xf1, 0x71, 0xbf, 0xe4, 0x34, 0xdb, 0xbc, 0x78, 0x21, ++ 0x89, 0xcd, 0xc4, 0x47, 0xe6, 0x29, 0x25, 0xeb, 0x90, 0xdb, 0xa9, 0x0a, ++ 0x25, 0x4b, 0x17, 0xf5, 0x0d, 0xa7, 0xcf, 0xf0, 0x6d, 0x2f, 0x39, 0xdd, ++ 0x17, 0xbe, 0x95, 0xd3, 0x2c, 0xbe, 0xcc, 0xf7, 0x33, 0xf9, 0x83, 0x98, ++ 0xf1, 0xf9, 0x11, 0x99, 0xf2, 0x21, 0x30, 0xa5, 0x92, 0x5f, 0x0a, 0xfd, ++ 0x41, 0x36, 0x1e, 0x80, 0x91, 0x3e, 0x89, 0x08, 0x12, 0x13, 0x1a, 0xfe, ++ 0xaa, 0xc5, 0x87, 0x63, 0x31, 0x23, 0xb3, 0x93, 0x3c, 0x5d, 0x39, 0x37, ++ 0xc4, 0x88, 0x8c, 0x68, 0xd4, 0x53, 0xe2, 0xab, 0xaf, 0xd9, 0x0f, 0x6d, ++ 0xca, 0xe5, 0xe0, 0x1e, 0x8f, 0x9d, 0x8d, 0x6a, 0x30, 0x76, 0xfd, 0x84, ++ 0xb8, 0xb8, 0x30, 0x21, 0x44, 0x67, 0xbb, 0x79, 0xee, 0x23, 0xaf, 0x41, ++ 0x2d, 0x54, 0x71, 0x7e, 0xae, 0x34, 0x7e, 0xd5, 0x94, 0x06, 0xff, 0x01, ++ 0x77, 0xfc, 0xeb, 0x6f, 0x32, 0x8a, 0xcf, 0xf3, 0x12, 0x9f, 0x42, 0x04, ++ 0x6c, 0x33, 0x32, 0x4b, 0x3d, 0xdc, 0x97, 0x34, 0xb8, 0x7f, 0x4d, 0x4e, ++ 0x33, 0xbf, 0x7b, 0x92, 0xb1, 0xe8, 0x16, 0xbe, 0x73, 0xa9, 0x58, 0xe2, ++ 0x70, 0xbd, 0xb9, 0x15, 0x7f, 0xa3, 0x7b, 0x51, 0x63, 0xfe, 0x10, 0xcf, ++ 0xba, 0x1a, 0x45, 0xec, 0x4f, 0x56, 0xa2, 0x91, 0x98, 0x7f, 0x82, 0x98, ++ 0xdf, 0x3c, 0x4b, 0xad, 0x99, 0x6a, 0x67, 0x7e, 0x25, 0xdf, 0xbb, 0x94, ++ 0xde, 0xd9, 0x1e, 0xd7, 0x57, 0x3d, 0x32, 0xed, 0xc1, 0x9b, 0xd6, 0x5a, ++ 0x7a, 0x98, 0xb4, 0xf2, 0xc8, 0xac, 0xc4, 0xfb, 0x3a, 0xe5, 0x41, 0x62, ++ 0x3f, 0x7a, 0x87, 0x8a, 0x19, 0x6b, 0xad, 0xe2, 0x77, 0xb1, 0xef, 0x83, ++ 0x93, 0x29, 0xe1, 0xde, 0x6b, 0xc7, 0xac, 0x53, 0x4b, 0x70, 0xdf, 0x73, ++ 0x1b, 0xaf, 0x23, 0xb5, 0x03, 0x25, 0x7d, 0xd7, 0xbb, 0x98, 0xaf, 0xe7, ++ 0xcb, 0xf8, 0x7e, 0x96, 0xed, 0xbe, 0x29, 0x68, 0x95, 0xc4, 0xf0, 0x3a, ++ 0x62, 0x7c, 0x92, 0x38, 0x79, 0x78, 0x5a, 0xe0, 0x0d, 0xd6, 0x89, 0x42, ++ 0xd2, 0xb0, 0x76, 0x2a, 0x46, 0xba, 0x47, 0x49, 0x64, 0x57, 0x96, 0x6b, ++ 0xe4, 0xdd, 0xac, 0x73, 0xb8, 0x43, 0xe0, 0xe7, 0x16, 0xb4, 0x00, 0xb1, ++ 0xfd, 0x6f, 0xac, 0x59, 0xff, 0x51, 0xae, 0x91, 0xc9, 0x42, 0x25, 0x42, ++ 0x2d, 0xd4, 0x7c, 0x62, 0xb9, 0x9b, 0x58, 0x3e, 0x44, 0x3e, 0x8c, 0xd0, ++ 0x13, 0x6c, 0x26, 0x96, 0x57, 0xb4, 0x19, 0xd9, 0x2e, 0xfa, 0x69, 0xcf, ++ 0xea, 0x08, 0x71, 0x1a, 0xa7, 0x87, 0x1d, 0x41, 0x07, 0xe7, 0x4a, 0x4f, ++ 0x1b, 0x91, 0x0e, 0xe2, 0x5f, 0x65, 0x9f, 0xd7, 0xd8, 0x67, 0xa1, 0x4e, ++ 0x7a, 0xed, 0x00, 0x5e, 0x60, 0x1f, 0x33, 0xe9, 0xb8, 0x3a, 0x21, 0xf1, ++ 0x3f, 0x86, 0x44, 0x46, 0xe2, 0xdf, 0x59, 0xd6, 0x4a, 0xdf, 0x2f, 0xf1, ++ 0x4f, 0x0c, 0xe6, 0x89, 0xc1, 0x12, 0x07, 0x06, 0x24, 0x07, 0x6a, 0xe8, ++ 0x2b, 0x4e, 0xd0, 0x57, 0x54, 0xd9, 0x51, 0xe2, 0x5f, 0xf2, 0xa1, 0xe4, ++ 0x2d, 0xba, 0xca, 0x1c, 0x58, 0xef, 0xce, 0x27, 0x35, 0x20, 0x88, 0xa6, ++ 0x49, 0x43, 0x57, 0x95, 0xff, 0x14, 0x4f, 0x98, 0xe6, 0xfc, 0x76, 0xfa, ++ 0x83, 0x2f, 0xdb, 0x62, 0xcc, 0x7b, 0x10, 0xf7, 0x9c, 0x08, 0xa9, 0x12, ++ 0xe7, 0xf5, 0x93, 0x41, 0x84, 0x26, 0x25, 0x0f, 0xb2, 0xe3, 0x11, 0x62, ++ 0xc4, 0xf2, 0xfc, 0x96, 0xf8, 0x8f, 0x12, 0x17, 0xaa, 0xd2, 0xcd, 0x31, ++ 0x6a, 0xa6, 0x74, 0xb4, 0x4e, 0x1a, 0x03, 0x27, 0x70, 0x55, 0xbc, 0x11, ++ 0x33, 0x33, 0x7b, 0x99, 0xff, 0x6d, 0xc9, 0x18, 0xf7, 0x4a, 0xc7, 0xdd, ++ 0x37, 0xc7, 0x70, 0x39, 0xe1, 0x6c, 0xb1, 0x82, 0x65, 0xaf, 0xad, 0x61, ++ 0x4b, 0x1e, 0xd8, 0x96, 0xa7, 0xd9, 0x35, 0x3d, 0xab, 0xfc, 0xb8, 0x86, ++ 0xc3, 0x44, 0x7f, 0xbf, 0xee, 0x30, 0xff, 0x01, 0xea, 0x7d, 0xe9, 0x9d, ++ 0x92, 0x07, 0xff, 0x79, 0xf9, 0x8c, 0xf9, 0x2b, 0x4f, 0xe9, 0xef, 0xdb, ++ 0xde, 0xc5, 0x33, 0xe7, 0x16, 0x62, 0xb0, 0x93, 0x18, 0xec, 0x61, 0x8e, ++ 0xb6, 0x5b, 0xe4, 0x36, 0xf3, 0x99, 0x55, 0x03, 0xf4, 0xd4, 0x4d, 0x7d, ++ 0xd5, 0xd4, 0xb4, 0x7d, 0xd4, 0xa7, 0x77, 0xcd, 0x4a, 0x7a, 0x70, 0x87, ++ 0xda, 0xd9, 0x41, 0xdd, 0xec, 0x52, 0x1e, 0x72, 0xb1, 0x95, 0x26, 0x8e, ++ 0x34, 0x25, 0x4d, 0x5f, 0xeb, 0x63, 0xed, 0x38, 0x14, 0x5e, 0xf4, 0xdf, ++ 0x32, 0x4e, 0xe9, 0xb9, 0x8d, 0xb8, 0x2c, 0xbf, 0xcf, 0xba, 0x3a, 0xb4, ++ 0x16, 0xaa, 0xbd, 0x56, 0x51, 0x6d, 0x79, 0xc6, 0x50, 0xf1, 0x03, 0xea, ++ 0xec, 0xc2, 0x26, 0x79, 0xd6, 0xe0, 0xba, 0xd8, 0x16, 0x31, 0x63, 0xd1, ++ 0x83, 0xc4, 0xd5, 0xab, 0xdf, 0x39, 0x7b, 0x94, 0xf0, 0x36, 0x9c, 0x57, ++ 0x6f, 0xfa, 0x68, 0xa9, 0x0f, 0x6b, 0x6f, 0xe2, 0x4d, 0xc3, 0x33, 0x2d, ++ 0x51, 0xe2, 0x51, 0x62, 0x4d, 0x43, 0xe1, 0x95, 0x4a, 0xbc, 0xf1, 0x4a, ++ 0x10, 0xaf, 0xbf, 0x22, 0xc4, 0x68, 0x12, 0x3c, 0xe1, 0x08, 0xf1, 0x50, ++ 0x72, 0x0d, 0x8e, 0xeb, 0xb1, 0xe8, 0x0b, 0xae, 0x8f, 0x75, 0xe8, 0x63, ++ 0x8d, 0x81, 0xb3, 0xb8, 0x21, 0x0a, 0x2e, 0xa7, 0x13, 0xe4, 0x5b, 0x09, ++ 0x8b, 0xae, 0xdf, 0xad, 0xd5, 0x70, 0x81, 0xf8, 0x0b, 0x11, 0x7f, 0xbf, ++ 0xa3, 0xe6, 0x5e, 0x2d, 0x6b, 0xee, 0xaa, 0x02, 0xf9, 0xd8, 0x16, 0x40, ++ 0x8f, 0x5c, 0x0b, 0x71, 0x38, 0x7c, 0x13, 0x87, 0xac, 0xbd, 0xdc, 0xf3, ++ 0xb3, 0x96, 0x11, 0xef, 0x24, 0x1e, 0x67, 0x2c, 0xc3, 0xe9, 0xa0, 0x9f, ++ 0x1d, 0x76, 0x31, 0x49, 0xed, 0x8d, 0x49, 0x5c, 0x12, 0x87, 0xcc, 0xc9, ++ 0x3e, 0xf6, 0x39, 0xcd, 0x3e, 0x63, 0x65, 0x3f, 0xfb, 0x1e, 0x12, 0x69, ++ 0xe9, 0x67, 0xa3, 0xc4, 0xe0, 0x3e, 0xd7, 0xcf, 0x4a, 0xff, 0x2a, 0xbd, ++ 0xab, 0x8c, 0xb3, 0xdd, 0x8d, 0xb3, 0xfb, 0x26, 0x0e, 0xa9, 0x61, 0xb5, ++ 0x12, 0x7f, 0x0f, 0x60, 0xec, 0xa5, 0x1a, 0x84, 0xcc, 0x3b, 0x71, 0x3e, ++ 0xf3, 0x80, 0x1a, 0x31, 0xa1, 0xd7, 0xdb, 0x25, 0x3c, 0x6e, 0x2e, 0xa6, ++ 0x90, 0xcf, 0xbf, 0x23, 0xf2, 0x61, 0xc3, 0x39, 0xeb, 0x7a, 0xd2, 0x01, ++ 0x7a, 0xc4, 0x1b, 0xc2, 0x13, 0x33, 0xce, 0x6d, 0xa1, 0x2f, 0x6b, 0xf2, ++ 0x96, 0xfc, 0xdd, 0x9a, 0xc2, 0xfb, 0x02, 0x75, 0xa5, 0x75, 0xaa, 0xf4, ++ 0x74, 0x23, 0xe4, 0xdc, 0xa8, 0x59, 0xf2, 0x77, 0xb1, 0xc2, 0xa7, 0xaa, ++ 0xd4, 0x73, 0x4f, 0x9b, 0x1c, 0x37, 0x4d, 0x0d, 0x59, 0x1c, 0xfb, 0x1b, ++ 0x5d, 0x1e, 0x21, 0x06, 0x87, 0xa5, 0xd7, 0xa2, 0x2f, 0xe1, 0x59, 0x7d, ++ 0x89, 0xa6, 0xee, 0xf6, 0xc2, 0x94, 0x6d, 0x8e, 0xf2, 0x10, 0xd7, 0xa0, ++ 0x99, 0x83, 0x4a, 0x9a, 0xb5, 0x79, 0x2f, 0xf1, 0xd5, 0xc3, 0x1a, 0x7c, ++ 0xd9, 0x6a, 0x26, 0x87, 0x05, 0xeb, 0xd0, 0x0d, 0xb1, 0xcf, 0x5c, 0x3c, ++ 0xd3, 0xc9, 0xf3, 0x5c, 0x9c, 0x71, 0x57, 0xb3, 0x76, 0xaf, 0x63, 0xbd, ++ 0xe6, 0x69, 0x91, 0x39, 0xfd, 0x32, 0x26, 0x1a, 0x57, 0xb5, 0x19, 0x03, ++ 0x1b, 0xbd, 0x01, 0xe4, 0x88, 0xf7, 0x57, 0x59, 0x83, 0xf2, 0xdc, 0xd3, ++ 0xc9, 0xa2, 0x91, 0xca, 0x62, 0x04, 0x1b, 0xb9, 0xa7, 0x3c, 0x03, 0x39, ++ 0xff, 0x18, 0x2b, 0x9d, 0x91, 0xb7, 0xb3, 0xb6, 0x8d, 0x97, 0xb9, 0x7d, ++ 0x05, 0x09, 0x4b, 0x72, 0x7b, 0x9e, 0xb5, 0x6d, 0xdc, 0xe5, 0xb6, 0x91, ++ 0x92, 0x7c, 0xae, 0x28, 0xd7, 0xb4, 0x4f, 0x20, 0x39, 0x7c, 0x6b, 0x3d, ++ 0x93, 0x78, 0x5e, 0xeb, 0x93, 0xde, 0x36, 0x9f, 0x97, 0x35, 0x49, 0xd6, ++ 0xa2, 0xc5, 0xba, 0xa4, 0xc9, 0xfb, 0x84, 0x4c, 0xe3, 0xc4, 0x1e, 0xe1, ++ 0x29, 0xdd, 0x49, 0x9c, 0xfb, 0xd0, 0x1b, 0x4c, 0xa5, 0xee, 0x43, 0x26, ++ 0x32, 0xa7, 0x61, 0x53, 0xbe, 0xa1, 0x2f, 0x60, 0x83, 0xef, 0x28, 0xb0, ++ 0xfe, 0x44, 0x43, 0xe6, 0x96, 0x3b, 0x89, 0x8f, 0x73, 0x9a, 0x16, 0x9a, ++ 0x58, 0x2e, 0xdf, 0xc1, 0x67, 0xb9, 0xdb, 0xde, 0x49, 0xa4, 0x7f, 0xdf, ++ 0x9d, 0xc4, 0x0b, 0xe4, 0xc7, 0x58, 0xe9, 0x4e, 0xc2, 0xf9, 0x5e, 0x8b, ++ 0x17, 0x33, 0x61, 0xec, 0xfe, 0xa8, 0x5d, 0xc5, 0xe5, 0x9c, 0x11, 0x39, ++ 0x8e, 0xdd, 0xe8, 0x77, 0xef, 0x1f, 0x90, 0xf5, 0xdb, 0xbb, 0xf0, 0x4f, ++ 0xed, 0xf2, 0xfe, 0x21, 0x25, 0xd7, 0x38, 0xce, 0xe5, 0x43, 0xa3, 0xde, ++ 0xac, 0x67, 0x2d, 0xd8, 0xb1, 0x46, 0xc1, 0x43, 0xc9, 0x3b, 0x5d, 0x6c, ++ 0x8f, 0x17, 0x8d, 0x74, 0x94, 0xcf, 0xee, 0x99, 0x90, 0x35, 0xf2, 0x71, ++ 0x9e, 0x17, 0xa1, 0x35, 0xda, 0xbd, 0xaa, 0xc8, 0x37, 0x45, 0xae, 0x28, ++ 0x86, 0x73, 0x18, 0xf2, 0x8e, 0x20, 0x71, 0xce, 0xab, 0x18, 0xf3, 0x1f, ++ 0x7a, 0x8d, 0x54, 0xbd, 0x8b, 0x99, 0xc7, 0x79, 0x76, 0x93, 0x7f, 0x7b, ++ 0xe5, 0xb9, 0x0f, 0x1b, 0x39, 0xe6, 0x07, 0x6b, 0xe4, 0x59, 0xf4, 0x73, ++ 0x91, 0x5d, 0x66, 0x38, 0x0b, 0x8a, 0xc6, 0xdc, 0x80, 0xfa, 0x24, 0x35, ++ 0xfc, 0x71, 0x6a, 0xb8, 0xf4, 0x2c, 0xbd, 0xf4, 0x2c, 0x4d, 0xf3, 0x71, ++ 0xaf, 0x91, 0xb9, 0x4e, 0xbd, 0xe3, 0x98, 0x7d, 0xbd, 0x8a, 0xd1, 0x7b, ++ 0x82, 0xfa, 0xbf, 0x53, 0x29, 0x8d, 0xb9, 0xb2, 0x3c, 0xe6, 0xdd, 0x05, ++ 0x4d, 0xe9, 0xcc, 0x83, 0xba, 0x83, 0xe8, 0x36, 0x8b, 0xda, 0x51, 0xac, ++ 0x24, 0xc7, 0x4c, 0xb9, 0x66, 0xc6, 0xd6, 0xca, 0xd8, 0x14, 0x5c, 0x69, ++ 0x91, 0xef, 0xb6, 0xca, 0x38, 0x9c, 0x2a, 0x3b, 0x45, 0xed, 0x7d, 0xc5, ++ 0x57, 0xd6, 0x2f, 0xcf, 0x16, 0x6b, 0x19, 0x9c, 0x30, 0x42, 0x3e, 0xb3, ++ 0x0e, 0xa3, 0xb4, 0x81, 0x41, 0xb3, 0x19, 0x39, 0xdd, 0x8f, 0x2d, 0xd6, ++ 0x17, 0x82, 0x3a, 0xc9, 0xf7, 0x81, 0xa7, 0x5e, 0xe2, 0x19, 0xde, 0xbc, ++ 0x86, 0x58, 0xf2, 0x39, 0x1c, 0xd3, 0x77, 0xd1, 0x0f, 0x6e, 0xc5, 0xeb, ++ 0xae, 0x9e, 0xd8, 0xc4, 0xb3, 0x42, 0x0c, 0xd9, 0xb2, 0xd6, 0xdd, 0x32, ++ 0xb6, 0xbc, 0x93, 0xb8, 0x24, 0xb2, 0xa5, 0x31, 0x9c, 0x6d, 0x56, 0x86, ++ 0x71, 0x7d, 0xa3, 0xbb, 0x3b, 0xa8, 0xbb, 0x15, 0xa6, 0xe7, 0xae, 0x4a, ++ 0xea, 0xee, 0x56, 0xeb, 0xcf, 0xf1, 0x14, 0x39, 0x5e, 0x65, 0x7e, 0x26, ++ 0x9e, 0x0e, 0xcb, 0x31, 0xa9, 0xaf, 0x35, 0x4b, 0xc7, 0xff, 0x90, 0x63, ++ 0xca, 0x39, 0x64, 0x3d, 0x3c, 0x2f, 0x0e, 0xd5, 0xca, 0x31, 0x07, 0x95, ++ 0x8d, 0xe4, 0xd4, 0x3c, 0x4b, 0xef, 0x0f, 0xc8, 0xa7, 0x05, 0xe6, 0xa7, ++ 0xf1, 0x36, 0x7c, 0x6a, 0x24, 0x9f, 0x9e, 0x58, 0xc2, 0xa7, 0x83, 0x79, ++ 0xe9, 0xbd, 0x14, 0xb4, 0xb4, 0xfd, 0x29, 0x75, 0x45, 0x08, 0x7f, 0xdb, ++ 0x0d, 0x71, 0xc6, 0xf5, 0xbe, 0xd2, 0xef, 0xa6, 0x95, 0xee, 0x59, 0xa9, ++ 0x4f, 0xd5, 0x08, 0x92, 0x4f, 0x1b, 0xc8, 0xa7, 0x7e, 0xf2, 0xe9, 0x69, ++ 0x53, 0x34, 0xee, 0x48, 0x1a, 0xa9, 0x79, 0xfa, 0x9a, 0x75, 0xe4, 0xd4, ++ 0x3b, 0xe4, 0xd4, 0x48, 0xb1, 0xa4, 0x53, 0xfb, 0xb8, 0xee, 0xfb, 0xa9, ++ 0x53, 0xeb, 0x8a, 0x52, 0xdb, 0x1c, 0xe2, 0x3f, 0x80, 0xcf, 0xc9, 0xa9, ++ 0xd9, 0xa4, 0xab, 0x53, 0xd6, 0xef, 0x90, 0xd8, 0x75, 0x5a, 0xf2, 0x89, ++ 0x3a, 0x95, 0x2f, 0x36, 0x59, 0xa7, 0xb9, 0xa6, 0xf1, 0xbc, 0x71, 0xbd, ++ 0x87, 0x9c, 0xf2, 0xb5, 0x1b, 0xe7, 0x2e, 0x13, 0xbb, 0x81, 0x18, 0xf4, ++ 0x88, 0x2d, 0xd7, 0xc4, 0x1a, 0xcb, 0x3a, 0x79, 0x90, 0xf8, 0xef, 0xa1, ++ 0x66, 0xf4, 0x16, 0x6d, 0xec, 0x2d, 0x2e, 0xdd, 0x53, 0xd6, 0xa1, 0xdb, ++ 0xee, 0xcb, 0xb8, 0xff, 0xf6, 0xed, 0xac, 0x57, 0xb7, 0x6d, 0x97, 0x7c, ++ 0x5d, 0xe6, 0x97, 0x7c, 0x1d, 0xce, 0xbf, 0xa6, 0xde, 0xfe, 0x1d, 0x79, ++ 0xa7, 0x26, 0xc4, 0x51, 0x4b, 0xde, 0x49, 0x48, 0xdf, 0xa3, 0x60, 0xc8, ++ 0x92, 0xf7, 0x6a, 0x1d, 0x51, 0x15, 0x46, 0xe4, 0xfb, 0xf8, 0x4a, 0x64, ++ 0xc3, 0x4e, 0xdc, 0xe7, 0xd6, 0x48, 0x43, 0xef, 0x63, 0xad, 0x9b, 0x2f, ++ 0x9f, 0xfd, 0x66, 0x78, 0x3e, 0x7b, 0x87, 0x75, 0xea, 0x28, 0xcf, 0x79, ++ 0x43, 0x85, 0xaf, 0xc4, 0x7c, 0x58, 0xc5, 0x88, 0x79, 0xf3, 0x8e, 0xd2, ++ 0xd5, 0xb1, 0xc3, 0x7c, 0x36, 0x56, 0x58, 0xac, 0x51, 0xd4, 0x4c, 0x53, ++ 0x88, 0xad, 0xe6, 0x7f, 0x8b, 0x2d, 0xdf, 0x7a, 0x57, 0x88, 0x49, 0xc6, ++ 0x70, 0xc1, 0xc2, 0x6e, 0x1f, 0x62, 0x7d, 0xd7, 0x59, 0xd7, 0x3f, 0x58, ++ 0x63, 0x64, 0x0a, 0x4a, 0xa2, 0x77, 0x83, 0x22, 0xbd, 0x9e, 0xa7, 0xab, ++ 0x82, 0xef, 0xb4, 0xd0, 0x1b, 0x5d, 0x61, 0x06, 0xfd, 0xfc, 0x7e, 0xc6, ++ 0x32, 0x22, 0x47, 0xf8, 0x77, 0x4b, 0x4a, 0x8e, 0x21, 0x44, 0x87, 0x25, ++ 0xef, 0xbb, 0x46, 0xd4, 0xdc, 0x44, 0x56, 0x54, 0x99, 0x17, 0xa8, 0x4d, ++ 0x46, 0x66, 0x44, 0x91, 0x3e, 0x3b, 0x0a, 0x57, 0x67, 0xf9, 0x4c, 0x9b, ++ 0x88, 0xe0, 0xef, 0x5d, 0xff, 0x1c, 0xa5, 0x66, 0x35, 0xe0, 0x1f, 0x5c, ++ 0xdd, 0x52, 0xb1, 0xed, 0x25, 0x23, 0xa5, 0x2a, 0x7b, 0x70, 0xc9, 0x32, ++ 0xf4, 0x9f, 0x32, 0x6e, 0x6a, 0xcd, 0x8b, 0x9d, 0x3c, 0x3f, 0x71, 0x8e, ++ 0x6c, 0x9f, 0xb7, 0x56, 0xd1, 0x58, 0x3b, 0x7e, 0xdc, 0x22, 0x6b, 0xf7, ++ 0x2e, 0xf4, 0x34, 0xef, 0xe4, 0x47, 0x45, 0xdd, 0x94, 0xaa, 0x6c, 0xa2, ++ 0x27, 0x09, 0x4d, 0x85, 0xb0, 0x7d, 0xb5, 0x10, 0xab, 0x56, 0x3b, 0xf8, ++ 0x3c, 0xd9, 0x14, 0x3f, 0xcb, 0x1a, 0x74, 0xa8, 0xd6, 0x48, 0x03, 0xbf, ++ 0xc0, 0x66, 0x7a, 0xd9, 0x54, 0x5b, 0x0e, 0xb8, 0x53, 0xae, 0xf1, 0x17, ++ 0xe8, 0x94, 0x1e, 0xd8, 0x0a, 0x49, 0xbf, 0xe5, 0xe2, 0xb7, 0x74, 0xaf, ++ 0xc4, 0xd4, 0x1d, 0xc8, 0x8a, 0x4a, 0xd3, 0xe8, 0x9b, 0x65, 0xbd, 0xfd, ++ 0x20, 0xb6, 0x5c, 0x7f, 0x78, 0x56, 0x7a, 0x60, 0x33, 0xba, 0x5e, 0x11, ++ 0xcc, 0xc5, 0xf3, 0xcc, 0x45, 0xcc, 0x09, 0xd2, 0x32, 0xf0, 0xac, 0xe5, ++ 0x84, 0x94, 0x41, 0xe5, 0x51, 0xf2, 0xa1, 0xcf, 0x5f, 0x49, 0x0f, 0xe1, ++ 0xd0, 0x3f, 0x78, 0x50, 0x7d, 0x40, 0x7a, 0x8a, 0x00, 0xb5, 0xa6, 0xa9, ++ 0x37, 0xc8, 0xfc, 0xec, 0x48, 0x4a, 0xff, 0x41, 0xac, 0x1f, 0xb8, 0x21, ++ 0x3a, 0xe9, 0x71, 0x3b, 0xcb, 0x1e, 0xf7, 0x89, 0xe9, 0x34, 0x3d, 0xb0, ++ 0xa6, 0xc8, 0x3b, 0xb6, 0x54, 0x1b, 0x0f, 0xa4, 0x8f, 0x4a, 0x1f, 0x22, ++ 0xd7, 0xa0, 0xe3, 0x6a, 0x52, 0x62, 0x57, 0xc7, 0x70, 0xbb, 0x11, 0xc9, ++ 0x42, 0xde, 0xe9, 0xdc, 0xea, 0x2f, 0xa0, 0xa7, 0xbf, 0xe3, 0x39, 0xa0, ++ 0x6f, 0x62, 0x2c, 0x86, 0x5f, 0x88, 0xba, 0xa4, 0x17, 0x7d, 0xee, 0x59, ++ 0x2e, 0xa2, 0xa7, 0xc9, 0xfb, 0x73, 0xf4, 0x09, 0x5e, 0x9e, 0x99, 0xf7, ++ 0x10, 0x4b, 0x5f, 0xb6, 0x0c, 0xbd, 0x5a, 0x8f, 0xec, 0x78, 0x1d, 0xcf, ++ 0xa8, 0xf7, 0x53, 0x57, 0x2f, 0xe4, 0x1e, 0x65, 0x3d, 0xf7, 0xb4, 0x47, ++ 0x78, 0x06, 0x68, 0x9c, 0xca, 0x8a, 0x7a, 0xfa, 0x41, 0x9e, 0x97, 0x51, ++ 0xdb, 0x16, 0xa7, 0xdf, 0x5e, 0xdc, 0x2b, 0x0f, 0x7e, 0x68, 0x99, 0x70, ++ 0xdc, 0xdf, 0x41, 0xbd, 0x7b, 0x9a, 0xe7, 0x68, 0x73, 0xb9, 0xde, 0x51, ++ 0x8a, 0x4b, 0xad, 0xb0, 0x2d, 0xb4, 0xdc, 0x0b, 0xfd, 0xc1, 0xdb, 0xc4, ++ 0xb4, 0x4e, 0x7a, 0x1f, 0x5f, 0xa9, 0xdf, 0x9f, 0x4d, 0x37, 0xe8, 0x8f, ++ 0xb0, 0xde, 0xcd, 0x13, 0x2b, 0x4f, 0xac, 0xb6, 0x64, 0x2c, 0xf3, 0x32, ++ 0x16, 0xfa, 0x4b, 0xe7, 0x7e, 0x0f, 0x7d, 0x49, 0x12, 0x08, 0xcd, 0xfd, ++ 0x35, 0x79, 0xe5, 0x69, 0x0d, 0x21, 0xbb, 0x8b, 0x31, 0xbe, 0xfa, 0xaf, ++ 0xdc, 0x9a, 0xfe, 0x49, 0xf4, 0x7b, 0xd8, 0x67, 0xc2, 0x02, 0x9e, 0x39, ++ 0x01, 0x3c, 0x3d, 0x19, 0xa3, 0x2f, 0xa7, 0x8f, 0x3c, 0xa1, 0xe1, 0xfb, ++ 0xd3, 0x95, 0xf8, 0xd1, 0x74, 0x10, 0x3b, 0xa6, 0xdd, 0xbb, 0xae, 0x0d, ++ 0x75, 0x7c, 0xaf, 0x83, 0x67, 0xbb, 0x59, 0x6b, 0x35, 0x3e, 0xa2, 0x87, ++ 0x5a, 0xa1, 0x78, 0x10, 0x39, 0x00, 0x5d, 0x27, 0x6e, 0x6a, 0x5b, 0x7e, ++ 0x44, 0x2e, 0x0b, 0x61, 0xae, 0x96, 0x3a, 0xf9, 0xbc, 0xfb, 0x7d, 0x84, ++ 0xfe, 0x31, 0x23, 0x31, 0x98, 0x27, 0x06, 0xf3, 0xc4, 0xe4, 0x4d, 0x4f, ++ 0x2d, 0xb1, 0x1c, 0xa7, 0x8f, 0x7e, 0x4e, 0x94, 0xb0, 0xf1, 0xb5, 0x38, ++ 0x6a, 0x9e, 0x24, 0x7f, 0x55, 0x6a, 0x28, 0xf0, 0xcf, 0xb9, 0x88, 0xbe, ++ 0xa9, 0x28, 0xf3, 0xff, 0xb7, 0xe5, 0xfc, 0x9f, 0xf1, 0x97, 0xf4, 0xc2, ++ 0x70, 0x66, 0xd1, 0x80, 0xc9, 0x7c, 0x83, 0xbe, 0x21, 0x3f, 0x34, 0xa8, ++ 0x21, 0x1b, 0x0d, 0xc1, 0x18, 0x98, 0x84, 0xa7, 0x35, 0x08, 0xb9, 0x76, ++ 0xa0, 0xe0, 0xae, 0x51, 0x88, 0x31, 0xea, 0x9b, 0xcc, 0xc1, 0xbf, 0xe7, ++ 0xd0, 0xea, 0x61, 0x3e, 0x1c, 0xc8, 0xb3, 0x35, 0xf0, 0x69, 0x41, 0xde, ++ 0x7d, 0xc6, 0xd2, 0xdd, 0xf8, 0xc2, 0x1d, 0xf3, 0x93, 0x42, 0x0a, 0xfb, ++ 0xf3, 0x1f, 0x88, 0xfd, 0xe1, 0x92, 0xc6, 0xa7, 0x79, 0x3e, 0x0a, 0x1d, ++ 0x28, 0x7b, 0x21, 0x72, 0xb8, 0x9a, 0xeb, 0xbd, 0x9a, 0x74, 0xbd, 0x3f, ++ 0x6b, 0xe4, 0x80, 0x7a, 0xd4, 0x64, 0xb1, 0xab, 0xb9, 0x21, 0xc6, 0x62, ++ 0x89, 0x40, 0x29, 0xa6, 0x84, 0x7e, 0x04, 0x15, 0xc4, 0xae, 0x3c, 0x23, ++ 0x49, 0xfd, 0x90, 0xbf, 0x79, 0x3e, 0x51, 0x9d, 0x88, 0x97, 0xeb, 0x72, ++ 0x1e, 0x93, 0x6d, 0x81, 0xb2, 0x5f, 0x5d, 0xf4, 0x22, 0x1d, 0x7c, 0x26, ++ 0xbd, 0xc8, 0x57, 0xa2, 0x2f, 0xdc, 0x71, 0x53, 0x73, 0xb2, 0x7c, 0x63, ++ 0x34, 0x2f, 0xef, 0xb4, 0x5a, 0xe8, 0x88, 0x15, 0x9c, 0x62, 0xe4, 0x47, ++ 0x5a, 0x63, 0xfa, 0x30, 0xc7, 0x73, 0x74, 0x9d, 0x5c, 0xde, 0x43, 0xbf, ++ 0xcc, 0x77, 0x8a, 0x2d, 0xec, 0x23, 0xb5, 0xec, 0x2f, 0xb8, 0xd6, 0x2f, ++ 0x9a, 0x25, 0xb6, 0x87, 0xf3, 0x6f, 0x79, 0x54, 0x53, 0xae, 0x33, 0x91, ++ 0x1a, 0x66, 0x3c, 0x0b, 0xba, 0xf4, 0xd6, 0x0e, 0xb5, 0x2d, 0xe1, 0xf6, ++ 0xcf, 0xaa, 0x32, 0x0e, 0x37, 0x1e, 0xb6, 0x49, 0xcd, 0x32, 0x32, 0xa7, ++ 0x90, 0x70, 0xfa, 0xa5, 0x39, 0x58, 0x26, 0x63, 0x68, 0x8a, 0xf4, 0x33, ++ 0x9e, 0x43, 0x61, 0x57, 0x0f, 0xf9, 0x8c, 0xf3, 0xe5, 0x3d, 0x1b, 0x2a, ++ 0x21, 0xb0, 0x22, 0xe9, 0x9e, 0xf9, 0xcb, 0xff, 0x5f, 0x43, 0xa5, 0x0f, ++ 0x91, 0x58, 0xfc, 0x5f, 0x69, 0xd7, 0x8a, 0xc0, 0xa8, 0x1a, 0x00, 0x00, ++ 0x00 }; + + static const u32 bnx2_TPAT_b06FwData[(0x0/4) + 1] = { 0x0 }; + static const u32 bnx2_TPAT_b06FwRodata[(0x0/4) + 1] = { 0x0 }; + + static struct fw_info bnx2_tpat_fw_06 = { +- /* Firmware version: 4.6.16 */ ++ /* Firmware version: 4.4.22 */ + .ver_major = 0x4, +- .ver_minor = 0x6, +- .ver_fix = 0x10, ++ .ver_minor = 0x4, ++ .ver_fix = 0x16, + + .start_addr = 0x08000488, + + .text_addr = 0x08000400, +- .text_len = 0x175c, ++ .text_len = 0x1aa4, + .text_index = 0x0, + .gz_text = bnx2_TPAT_b06FwText, + .gz_text_len = sizeof(bnx2_TPAT_b06FwText), +@@ -3540,11 +3639,11 @@ + .data_index = 0x0, + .data = bnx2_TPAT_b06FwData, + +- .sbss_addr = 0x08001b80, ++ .sbss_addr = 0x08001ec0, + .sbss_len = 0x44, + .sbss_index = 0x0, + +- .bss_addr = 0x08001bc4, ++ .bss_addr = 0x08001f04, + .bss_len = 0x450, + .bss_index = 0x0, + +@@ -3571,858 +3670,862 @@ + }; + + static u8 bnx2_TXP_b06FwText[] = { +- 0xad, 0x7b, 0x0f, 0x70, 0x54, 0xe7, 0x75, 0xef, 0xef, 0xee, 0x1f, 0x69, +- 0x57, 0x5a, 0xad, 0x2e, 0x78, 0xc1, 0xab, 0x54, 0x29, 0x7b, 0xd9, 0xbb, +- 0xd2, 0x1a, 0x09, 0xb8, 0x0b, 0xc2, 0x88, 0xe8, 0xd6, 0x6c, 0x85, 0x00, +- 0x21, 0x64, 0x2c, 0x63, 0x25, 0x15, 0x7d, 0x9e, 0x5a, 0x0f, 0x64, 0x23, +- 0xdb, 0xd8, 0x16, 0x35, 0x6d, 0xe5, 0xd4, 0xad, 0xd6, 0x92, 0xc0, 0xc2, +- 0xac, 0xb8, 0x22, 0x0b, 0x11, 0xee, 0xf4, 0xbd, 0xc8, 0x96, 0xb0, 0xb0, +- 0xb3, 0x62, 0xed, 0xa4, 0xaf, 0xd3, 0xcc, 0x34, 0xe3, 0x7d, 0xfe, 0x83, +- 0x49, 0x1e, 0xb6, 0xd3, 0x4e, 0xe7, 0x3d, 0xa7, 0xf3, 0xde, 0x84, 0x17, +- 0x63, 0x62, 0xa7, 0x89, 0xed, 0xe6, 0xa5, 0xf3, 0x44, 0xea, 0xf8, 0xbe, +- 0xdf, 0xb9, 0x77, 0x17, 0x88, 0x9b, 0x4e, 0x67, 0x3a, 0x4f, 0x33, 0x9a, +- 0xd5, 0xde, 0x3f, 0xdf, 0x77, 0xce, 0xf9, 0xce, 0xf9, 0x9d, 0xdf, 0x39, +- 0xdf, 0xa7, 0x06, 0xa0, 0x0a, 0xa5, 0x9f, 0x1a, 0xfe, 0xb6, 0x0c, 0x0d, +- 0x1f, 0x4a, 0xad, 0xb9, 0x75, 0x0d, 0xff, 0xbc, 0x15, 0x6a, 0x85, 0x4f, +- 0x6e, 0xde, 0xaa, 0x00, 0xfd, 0x3f, 0xc6, 0xbf, 0xeb, 0xe7, 0xf3, 0xff, +- 0xbe, 0xd7, 0x9c, 0x1f, 0x2f, 0xa0, 0x96, 0xe5, 0x92, 0x5f, 0x04, 0x3c, +- 0xe6, 0xcc, 0x17, 0xda, 0x75, 0x04, 0xbc, 0x66, 0xaf, 0xb9, 0x4f, 0x07, +- 0xd2, 0xf9, 0xa6, 0xd8, 0x16, 0xfc, 0xd2, 0xce, 0x44, 0x7c, 0x90, 0xeb, +- 0x9f, 0x37, 0x3f, 0x19, 0xf9, 0xf6, 0x46, 0xed, 0xe3, 0x19, 0x2f, 0x02, +- 0xaa, 0x79, 0x1a, 0x6a, 0x03, 0x02, 0xf5, 0x7c, 0xe7, 0xcf, 0x1b, 0xfd, +- 0x5e, 0x84, 0xcb, 0x63, 0xb5, 0x62, 0xcc, 0x42, 0x26, 0x60, 0x0e, 0xa1, +- 0x72, 0x03, 0xf0, 0x5e, 0x36, 0x61, 0x8c, 0x01, 0x53, 0x1e, 0x33, 0x11, +- 0x7b, 0x05, 0x06, 0x0e, 0x17, 0x62, 0xe8, 0xe0, 0xef, 0x0e, 0xeb, 0x53, +- 0x3b, 0xe6, 0x47, 0xc6, 0xcb, 0xe7, 0xf6, 0xb6, 0x00, 0x5b, 0xb3, 0x06, +- 0x8e, 0x58, 0x08, 0xd4, 0x99, 0x8f, 0x63, 0x13, 0x3f, 0xc3, 0xe6, 0x30, +- 0xde, 0x9a, 0x8c, 0xc7, 0x9e, 0x83, 0xd6, 0xa7, 0x7b, 0xb5, 0x61, 0xa0, +- 0x69, 0x70, 0x40, 0xd1, 0xfa, 0xdf, 0x56, 0xb4, 0x9e, 0x49, 0x05, 0x01, +- 0x85, 0xcf, 0x35, 0xe5, 0xe5, 0x73, 0x18, 0xab, 0xf2, 0x01, 0x5c, 0xf2, +- 0xca, 0xfc, 0xbf, 0x45, 0x7b, 0x2b, 0xf0, 0xe9, 0xad, 0x18, 0xa7, 0x0c, +- 0x7e, 0x53, 0xc1, 0xb3, 0x2d, 0x89, 0xe8, 0x28, 0xe4, 0x7e, 0x0c, 0x5b, +- 0x0a, 0xf2, 0xa9, 0x51, 0x6b, 0xdb, 0x1e, 0x37, 0x6c, 0xfb, 0x8c, 0x51, +- 0x89, 0x8c, 0xaa, 0x45, 0x01, 0x05, 0xa3, 0x86, 0x07, 0x69, 0xb5, 0x3d, +- 0xe6, 0x83, 0x16, 0xbd, 0x17, 0xff, 0x4c, 0x9d, 0xd3, 0x49, 0x3f, 0xdc, +- 0xe7, 0xfb, 0x51, 0x89, 0xa2, 0xea, 0x5a, 0xed, 0xd9, 0xac, 0x6d, 0x9f, +- 0xd7, 0x7d, 0x38, 0x43, 0xfb, 0x8c, 0xe6, 0xff, 0xd9, 0x2e, 0xd2, 0x36, +- 0xe3, 0x7a, 0x79, 0xfe, 0x00, 0x66, 0x54, 0xdb, 0x9e, 0xe5, 0xbd, 0x23, +- 0xf9, 0xb2, 0x9d, 0x6d, 0xdb, 0xa3, 0xdb, 0xf6, 0x3e, 0xfd, 0x17, 0xf6, +- 0xde, 0x5f, 0x79, 0xd6, 0xb6, 0x9f, 0x32, 0x6e, 0xc2, 0xd9, 0x5c, 0x87, +- 0xd2, 0x35, 0xbf, 0x3c, 0xbc, 0x63, 0xda, 0xc6, 0x79, 0x03, 0xaa, 0xc7, +- 0xdc, 0xa6, 0xec, 0x98, 0xef, 0x54, 0xb6, 0x16, 0x76, 0x2b, 0xdb, 0x66, +- 0x7f, 0x57, 0xe9, 0x9c, 0xef, 0x57, 0xb6, 0x17, 0xa2, 0x98, 0xb3, 0x22, +- 0x98, 0xb5, 0xfa, 0x94, 0x8e, 0xf9, 0x5e, 0xc5, 0xd5, 0x63, 0x58, 0x69, +- 0x2f, 0x94, 0xc7, 0xba, 0x6e, 0xc7, 0x1d, 0x59, 0x13, 0x13, 0x56, 0x25, +- 0xe7, 0x59, 0xb4, 0xbf, 0xdd, 0xb8, 0x48, 0x3d, 0x0d, 0x1c, 0x2d, 0x3c, +- 0x85, 0xdb, 0xa7, 0x6d, 0x3b, 0x9f, 0x02, 0xf2, 0x05, 0xe0, 0xeb, 0x56, +- 0xbc, 0x67, 0x50, 0xb1, 0xed, 0xed, 0x09, 0x7b, 0xc5, 0x15, 0xa3, 0x29, +- 0xf9, 0x1a, 0xfe, 0xaf, 0x3d, 0x13, 0x41, 0x26, 0xc4, 0x31, 0x8e, 0x71, +- 0xcd, 0x1e, 0x98, 0x44, 0xa0, 0xd2, 0x1c, 0xc7, 0x8f, 0xb2, 0x08, 0x54, +- 0x98, 0x19, 0x9c, 0xcf, 0x8e, 0xaa, 0x01, 0xc4, 0xa3, 0x3b, 0x94, 0xcc, +- 0xb0, 0x07, 0xda, 0xd0, 0xbb, 0xd0, 0x62, 0x5c, 0x8f, 0x0b, 0xaf, 0x2a, +- 0x5a, 0xf1, 0x35, 0x68, 0xe9, 0x5f, 0x28, 0x5a, 0x67, 0x9d, 0x17, 0x69, +- 0x4f, 0x22, 0x80, 0x6f, 0x37, 0xca, 0x9a, 0x8c, 0x63, 0x8d, 0xb3, 0x36, +- 0x19, 0xdc, 0x72, 0x6d, 0x6d, 0x4c, 0x8c, 0x52, 0xae, 0x23, 0x94, 0xeb, +- 0x75, 0x43, 0x8b, 0x3e, 0x0b, 0x7b, 0xc5, 0x80, 0x21, 0xf7, 0x4c, 0x8c, +- 0x17, 0xec, 0x58, 0xd8, 0xbc, 0x44, 0x79, 0x91, 0xf9, 0x9c, 0x19, 0xc8, +- 0xd4, 0x9a, 0xbf, 0xb4, 0xdf, 0xdc, 0x10, 0xc5, 0xcb, 0x85, 0x08, 0x5e, +- 0x2a, 0xa8, 0x78, 0xb1, 0xd0, 0x01, 0xab, 0x80, 0xf0, 0xed, 0x85, 0x5f, +- 0xe7, 0xc7, 0x36, 0x42, 0x7c, 0x9e, 0x72, 0x87, 0x77, 0x16, 0x7c, 0xfd, +- 0x15, 0x26, 0x7a, 0xbe, 0x93, 0x1d, 0xb1, 0xab, 0x74, 0xf4, 0x2f, 0x31, +- 0xf5, 0xf4, 0x2a, 0x25, 0xd4, 0x4a, 0x3f, 0xec, 0x79, 0x23, 0xdf, 0xea, +- 0xd3, 0x8f, 0x07, 0xe1, 0xa7, 0xfd, 0xb7, 0x16, 0x6c, 0x7b, 0xcc, 0x38, +- 0xb8, 0x76, 0x6f, 0xeb, 0x37, 0x8b, 0x3d, 0x7a, 0x37, 0x32, 0x85, 0x01, +- 0x20, 0x6c, 0xf2, 0x93, 0xa1, 0xb8, 0xbb, 0xb9, 0x23, 0x76, 0xae, 0xdf, +- 0xe7, 0xfa, 0x33, 0x65, 0xa0, 0xdd, 0x5f, 0xb2, 0x28, 0x83, 0xf5, 0x47, +- 0x61, 0x54, 0xc5, 0xa8, 0xdf, 0xf7, 0x28, 0x67, 0x12, 0xdf, 0x28, 0xe8, +- 0x94, 0xad, 0x99, 0x32, 0xc6, 0x28, 0x5f, 0x00, 0x7b, 0x73, 0xda, 0x54, +- 0x06, 0xda, 0xc4, 0x0c, 0x56, 0x23, 0x1d, 0x51, 0xe9, 0x83, 0x7f, 0x06, +- 0x77, 0x8c, 0x6e, 0x1c, 0xb7, 0xb0, 0x4e, 0x35, 0xb9, 0xbe, 0x29, 0x3c, +- 0x5e, 0x81, 0x44, 0xff, 0xc7, 0x8a, 0x82, 0x37, 0x13, 0xdd, 0x98, 0xa4, +- 0x3e, 0xdd, 0xf9, 0x20, 0x1e, 0xcc, 0x55, 0xe1, 0xfe, 0x9c, 0x8d, 0x07, +- 0x52, 0x30, 0xab, 0xa8, 0x4f, 0x32, 0x95, 0x88, 0xbd, 0x0f, 0x1f, 0x3a, +- 0xf2, 0xdd, 0x8c, 0xa5, 0x2d, 0x48, 0x57, 0x04, 0xb0, 0x25, 0x1f, 0x62, +- 0x3c, 0xa6, 0x71, 0x7a, 0x3a, 0x00, 0xff, 0x7a, 0x0f, 0x66, 0x22, 0x15, +- 0x48, 0x36, 0x78, 0xf8, 0x1b, 0x09, 0xb7, 0x4f, 0xd7, 0x87, 0xb7, 0x5a, +- 0x3e, 0xec, 0xb7, 0x3c, 0x18, 0xc9, 0xd9, 0x76, 0x87, 0x61, 0xe3, 0xea, +- 0x7a, 0x15, 0xdf, 0xa2, 0xfd, 0x0e, 0x5a, 0x51, 0x9c, 0x2d, 0x3c, 0x49, +- 0x59, 0x22, 0xae, 0xbc, 0x16, 0x65, 0xb7, 0x28, 0xbb, 0x45, 0xb9, 0x2d, +- 0x91, 0xf3, 0x55, 0xc6, 0x8c, 0x41, 0xbd, 0x82, 0x94, 0xa1, 0x1a, 0x83, +- 0x94, 0x23, 0x9e, 0xb2, 0xe1, 0x49, 0x69, 0x99, 0xbd, 0x04, 0xaf, 0x15, +- 0x0d, 0xb6, 0xfd, 0xf1, 0x7a, 0xd1, 0x85, 0x6b, 0xee, 0xe9, 0x96, 0x18, +- 0xfd, 0xed, 0x1a, 0xc6, 0xd5, 0xf7, 0x69, 0xb7, 0xa7, 0x0b, 0x41, 0x0c, +- 0xe7, 0x1c, 0xbf, 0x3d, 0x54, 0x41, 0xb9, 0x45, 0xae, 0x82, 0x9e, 0x60, +- 0x8c, 0x26, 0xfa, 0x18, 0xa3, 0xd8, 0x49, 0x99, 0x1f, 0xb0, 0x22, 0xe1, +- 0x8e, 0xe9, 0x44, 0xeb, 0x6e, 0xc5, 0x87, 0xed, 0xf9, 0xeb, 0x72, 0x52, +- 0x5f, 0x89, 0x41, 0xea, 0xaa, 0x52, 0xbe, 0x08, 0xf6, 0x51, 0xce, 0x97, +- 0x4a, 0x72, 0xce, 0x16, 0x64, 0xae, 0xcf, 0xca, 0x5a, 0x96, 0x13, 0x99, +- 0xa5, 0x66, 0x44, 0x41, 0x55, 0x08, 0xbb, 0xf3, 0xef, 0x70, 0x2d, 0xea, +- 0xf1, 0x4d, 0xae, 0xc1, 0xcb, 0x8c, 0x91, 0x6f, 0x5c, 0xf3, 0x17, 0x59, +- 0x8f, 0x27, 0xb8, 0x0e, 0xda, 0xe9, 0x0c, 0x42, 0xe8, 0x2f, 0xa4, 0x71, +- 0x78, 0x1a, 0xe9, 0x39, 0xe3, 0x18, 0xe3, 0x7d, 0x39, 0xbc, 0x7a, 0x65, +- 0x5a, 0xd5, 0xab, 0xb0, 0x6f, 0x36, 0x82, 0xa1, 0x42, 0x3b, 0xac, 0x5c, +- 0x04, 0x07, 0xe8, 0x9b, 0x1f, 0xa6, 0xd2, 0x0f, 0x84, 0x21, 0xb2, 0x47, +- 0xf0, 0x20, 0xdf, 0x79, 0x6a, 0x3a, 0x82, 0x41, 0xda, 0x68, 0x47, 0x2a, +- 0xd1, 0x1a, 0xe4, 0xb5, 0xfd, 0xbc, 0x76, 0x84, 0xf6, 0x7f, 0xd5, 0x98, +- 0x44, 0x7f, 0x8f, 0x96, 0x04, 0x22, 0xb8, 0xcf, 0x82, 0x4a, 0x17, 0x7e, +- 0x82, 0xf8, 0x96, 0x7c, 0x95, 0xdf, 0xef, 0x2d, 0x54, 0x51, 0xdf, 0x30, +- 0xa2, 0xfa, 0x27, 0xb6, 0xbf, 0xc5, 0xb6, 0xbf, 0x66, 0x24, 0x2e, 0xfc, +- 0xd0, 0xeb, 0xc3, 0x63, 0x05, 0x0f, 0x86, 0x67, 0xab, 0xf0, 0xfb, 0x39, +- 0x1f, 0xee, 0x6c, 0xa8, 0xc2, 0xc1, 0xd9, 0x34, 0xc6, 0xa6, 0xab, 0x30, +- 0x90, 0xc3, 0x8a, 0xfb, 0x8c, 0xb1, 0x25, 0x15, 0xd0, 0x16, 0x3b, 0x90, +- 0xc4, 0x55, 0xae, 0xc3, 0x63, 0xb3, 0xa1, 0x70, 0xdf, 0xb4, 0x8a, 0xe1, +- 0xf9, 0x20, 0x9f, 0xf7, 0xf0, 0xf9, 0x4a, 0x18, 0xeb, 0xe2, 0xc3, 0x2a, +- 0x44, 0xc6, 0x6a, 0x3c, 0x3c, 0x1b, 0xc4, 0x43, 0x39, 0x15, 0x07, 0xa6, +- 0x5b, 0x30, 0x65, 0xa5, 0x71, 0x94, 0xd8, 0xf1, 0xf5, 0x94, 0xd6, 0x73, +- 0x40, 0xd1, 0xd2, 0x5b, 0x95, 0x34, 0x1a, 0x53, 0x7e, 0x5c, 0x22, 0x0e, +- 0xf9, 0x53, 0x4d, 0xad, 0x2f, 0x12, 0x1b, 0x2a, 0xcc, 0x08, 0xbf, 0x6b, +- 0x13, 0x8c, 0xd9, 0xb4, 0xdf, 0xb3, 0x1e, 0x58, 0x26, 0xf1, 0x1b, 0x09, +- 0x77, 0x59, 0x6a, 0xb8, 0xab, 0x50, 0x1f, 0xde, 0x61, 0x45, 0xc3, 0x3b, +- 0x18, 0x5f, 0x5b, 0xc5, 0x1f, 0xad, 0x00, 0x8e, 0xa5, 0x7e, 0x69, 0xf7, +- 0x2f, 0x71, 0xf0, 0x2c, 0x7c, 0xfb, 0xb4, 0x96, 0x99, 0x81, 0x66, 0x30, +- 0x1b, 0x60, 0x72, 0xde, 0xc7, 0xf5, 0x53, 0xb0, 0x44, 0x6f, 0x21, 0x8e, +- 0xab, 0x78, 0x98, 0x98, 0xf2, 0xb7, 0xc4, 0x94, 0x81, 0xe3, 0x71, 0x75, +- 0x0a, 0x41, 0xda, 0x1b, 0xd8, 0x7b, 0x2e, 0xc2, 0x35, 0xef, 0xc4, 0x93, +- 0x94, 0x6b, 0xc7, 0x86, 0x08, 0xee, 0x2f, 0xa8, 0xe1, 0x4e, 0xae, 0xdf, +- 0xfb, 0xf9, 0x68, 0x78, 0x0b, 0xd7, 0xf2, 0xdd, 0xbc, 0x16, 0x2b, 0xe2, +- 0x9f, 0xc4, 0x9f, 0x92, 0xf0, 0x00, 0xf7, 0x1d, 0xf7, 0xa3, 0x18, 0x91, +- 0xb9, 0x68, 0x73, 0xeb, 0x65, 0x3b, 0xa4, 0xeb, 0xa7, 0x0f, 0xd0, 0xd6, +- 0x8f, 0x16, 0x42, 0x78, 0xc8, 0xd2, 0x92, 0xdf, 0x50, 0x42, 0xb4, 0x69, +- 0x80, 0x76, 0x20, 0xc0, 0x2c, 0x97, 0xe7, 0x52, 0x88, 0x2d, 0x77, 0xb1, +- 0xf6, 0xe0, 0xac, 0xf8, 0x09, 0xd7, 0xde, 0xa2, 0x0f, 0xd0, 0x7f, 0xbe, +- 0x71, 0x2d, 0x56, 0x35, 0x35, 0xe3, 0x60, 0x77, 0x92, 0xfe, 0xe2, 0xda, +- 0xe8, 0xc4, 0xb4, 0xd8, 0x41, 0x9b, 0x82, 0x27, 0x8d, 0xb5, 0xeb, 0xfe, +- 0xd6, 0xbe, 0xb4, 0x4c, 0xec, 0xa1, 0x62, 0x84, 0x36, 0x3c, 0x6d, 0xd9, +- 0xf6, 0xd5, 0xf5, 0x3f, 0xb5, 0x5b, 0x6f, 0x16, 0xbb, 0x88, 0xae, 0xdf, +- 0x52, 0x24, 0x8f, 0x2c, 0xd1, 0xc3, 0xff, 0x1f, 0x7c, 0xe5, 0x0f, 0xed, +- 0x7e, 0x47, 0x3f, 0xf1, 0x17, 0x1f, 0x7d, 0xf1, 0x49, 0x8e, 0xed, 0x41, +- 0x3f, 0xc7, 0x7b, 0xc4, 0xb2, 0x3f, 0xaa, 0x33, 0x3f, 0xb5, 0x5b, 0x37, +- 0xea, 0x43, 0x8b, 0xca, 0xff, 0xe0, 0xf5, 0x08, 0x1e, 0x2e, 0xb4, 0xd2, +- 0x76, 0x1d, 0x78, 0xca, 0x12, 0x3c, 0xec, 0x64, 0xbc, 0x45, 0xe9, 0xcf, +- 0xf5, 0xf4, 0x6f, 0x9f, 0xb2, 0xd5, 0xca, 0x63, 0xc7, 0x64, 0x06, 0xdb, +- 0xe9, 0xef, 0x17, 0xb2, 0xf1, 0xd6, 0xe7, 0xa1, 0x65, 0xa8, 0x43, 0xb8, +- 0x93, 0x36, 0xee, 0xb0, 0xb4, 0x4e, 0x59, 0xd3, 0x0e, 0xe2, 0xd2, 0x2b, +- 0xd9, 0x68, 0xb8, 0xbd, 0x20, 0xf6, 0xae, 0x0f, 0x6f, 0x29, 0xdc, 0xca, +- 0xb5, 0x57, 0xb0, 0x69, 0x75, 0x80, 0x38, 0x73, 0x07, 0xdc, 0x75, 0x75, +- 0xd7, 0xee, 0xcd, 0x54, 0x53, 0xff, 0x4f, 0xd1, 0x85, 0xcc, 0x32, 0xf7, +- 0xda, 0x30, 0xaf, 0xd5, 0xae, 0x47, 0xf8, 0x0e, 0xfa, 0xc1, 0x3d, 0xf4, +- 0x83, 0xab, 0xeb, 0x7f, 0x69, 0xc7, 0x6e, 0x72, 0xfd, 0xa0, 0x7d, 0xda, +- 0x17, 0xde, 0x46, 0x3b, 0x6d, 0x35, 0x14, 0xcc, 0x1a, 0x4f, 0xa1, 0xff, +- 0x1a, 0x77, 0x48, 0xcf, 0x9c, 0x35, 0xd2, 0xc4, 0x91, 0x36, 0xf8, 0x96, +- 0x60, 0xe6, 0x79, 0xe3, 0x30, 0x62, 0xae, 0xef, 0xe0, 0x40, 0x2e, 0x88, +- 0xcc, 0x9d, 0x2a, 0xe6, 0x1a, 0x55, 0x3c, 0xc2, 0xb1, 0x3f, 0x4c, 0x35, +- 0x0d, 0xbe, 0x45, 0x1b, 0xcc, 0x2c, 0x91, 0x6b, 0x69, 0xfc, 0x95, 0xf1, +- 0x65, 0xe0, 0x26, 0x77, 0xee, 0x79, 0x89, 0xd1, 0xf9, 0x16, 0x1c, 0x29, +- 0xf4, 0x29, 0x2e, 0x6e, 0x6a, 0x9d, 0x69, 0x7c, 0xcf, 0x16, 0x2c, 0x9d, +- 0x27, 0x86, 0xb4, 0xd3, 0xa7, 0xc6, 0xe9, 0x47, 0xa3, 0xc4, 0x90, 0xed, +- 0xf4, 0xa3, 0x27, 0xf3, 0xa2, 0x53, 0xc2, 0x30, 0xbc, 0x37, 0x33, 0x37, +- 0xd3, 0x3e, 0x96, 0x93, 0xf3, 0x6b, 0x55, 0xfd, 0x30, 0xa6, 0x1c, 0xd9, +- 0x86, 0x95, 0x3b, 0xc8, 0x31, 0x2e, 0xf9, 0x51, 0x1b, 0xd5, 0x1f, 0xc1, +- 0x69, 0xe7, 0x5a, 0x84, 0xef, 0xa6, 0x3d, 0x1e, 0x1d, 0xaa, 0x6a, 0x76, +- 0x30, 0xaf, 0x8a, 0xef, 0x77, 0x2a, 0x3b, 0x98, 0x6b, 0xd3, 0xcc, 0xb5, +- 0x69, 0xe6, 0xda, 0x34, 0xe7, 0x4f, 0x33, 0xc7, 0xb6, 0x17, 0x86, 0x95, +- 0x1e, 0xb1, 0xbb, 0xd8, 0xdf, 0x72, 0xf9, 0x03, 0xb1, 0x27, 0xbc, 0xbd, +- 0xb0, 0xc6, 0xe3, 0x72, 0xba, 0x61, 0xa5, 0xc4, 0x61, 0x02, 0x55, 0x3a, +- 0x73, 0x98, 0x35, 0xac, 0x74, 0x31, 0xcf, 0xf6, 0x39, 0x36, 0x8c, 0x0f, +- 0x5d, 0x66, 0x7e, 0x7d, 0x93, 0xf9, 0x35, 0x9f, 0x62, 0x3c, 0xad, 0xbe, +- 0x6a, 0xf7, 0x2f, 0x73, 0x73, 0xc1, 0x18, 0xe5, 0xfc, 0x1a, 0xd7, 0xaa, +- 0xc8, 0x1c, 0xda, 0xe1, 0x55, 0x70, 0x9f, 0x8e, 0xda, 0x3a, 0x62, 0xe9, +- 0x91, 0x02, 0xf1, 0xdf, 0x88, 0xb7, 0x7e, 0x40, 0x83, 0x1e, 0xd1, 0xfd, +- 0xb8, 0x7a, 0x13, 0x49, 0x8e, 0xde, 0x8e, 0x63, 0xb9, 0x4a, 0x0c, 0xa6, +- 0xd2, 0x4b, 0x03, 0xe4, 0x28, 0x9d, 0x2d, 0x78, 0x9c, 0x53, 0x2b, 0x51, +- 0x33, 0x41, 0x7f, 0x41, 0xfa, 0x38, 0xf3, 0xc3, 0xa4, 0x75, 0x2b, 0xf2, +- 0xcc, 0xa3, 0x73, 0x86, 0x0f, 0x6f, 0xe6, 0xd7, 0x10, 0xdf, 0x12, 0x46, +- 0x48, 0xa9, 0x62, 0xdc, 0x9a, 0xc8, 0x5a, 0x82, 0x4b, 0xb6, 0x3d, 0x27, +- 0x32, 0x24, 0x12, 0xe9, 0x51, 0x08, 0x56, 0xd9, 0x2b, 0xee, 0x4d, 0x55, +- 0x60, 0x53, 0x22, 0x8c, 0x15, 0x7a, 0xbf, 0xd2, 0x59, 0x48, 0x18, 0xaf, +- 0xe2, 0x77, 0x95, 0x7b, 0xe6, 0x4d, 0xc6, 0x74, 0x9f, 0xb2, 0x67, 0xbe, +- 0x0a, 0x97, 0x22, 0x22, 0x23, 0x6a, 0xfd, 0xba, 0x07, 0xef, 0xdd, 0xa5, +- 0x40, 0xd5, 0xd3, 0x38, 0xdf, 0xa2, 0xd2, 0x9f, 0x3a, 0xc9, 0x2d, 0x62, +- 0xf0, 0x2e, 0x44, 0xc3, 0x3b, 0xb9, 0x06, 0xd5, 0x0b, 0xb2, 0x2e, 0x1d, +- 0xb4, 0x55, 0x3d, 0xfd, 0xaf, 0x53, 0xe9, 0xa0, 0x1d, 0xbb, 0x66, 0xa1, +- 0x56, 0x99, 0xbd, 0xca, 0xb6, 0x82, 0x46, 0x3b, 0x89, 0x4d, 0x86, 0xc9, +- 0x91, 0xc4, 0x47, 0xca, 0x6b, 0x28, 0x7e, 0x7a, 0xe3, 0x3a, 0xf6, 0x79, +- 0x24, 0xd6, 0x36, 0xad, 0x36, 0x19, 0x87, 0x1e, 0xca, 0x25, 0x32, 0x04, +- 0x50, 0xdb, 0x68, 0xaf, 0xf8, 0x30, 0xb5, 0xc0, 0x7b, 0x26, 0x8e, 0x17, +- 0xba, 0xb9, 0x2e, 0xcd, 0x25, 0xbf, 0x52, 0xe9, 0x87, 0x1d, 0x1c, 0x5f, +- 0xfc, 0x3b, 0x0d, 0x77, 0x2d, 0x3b, 0xc9, 0x89, 0xfe, 0xb5, 0x35, 0x3c, +- 0xc8, 0x31, 0x64, 0x1d, 0x2b, 0xca, 0x7e, 0x19, 0xbe, 0x67, 0x3a, 0x8d, +- 0xf7, 0x9c, 0x1c, 0x5a, 0xf6, 0xe1, 0x61, 0xa5, 0x93, 0x6b, 0x09, 0xbf, +- 0x3b, 0xfe, 0xae, 0x69, 0xf8, 0x6b, 0x4c, 0xc4, 0xbc, 0xe4, 0x6d, 0x17, +- 0x53, 0x09, 0x75, 0x52, 0xe9, 0xe6, 0x58, 0x8c, 0x2d, 0x62, 0x7d, 0x35, +- 0xfd, 0xa6, 0x83, 0xfa, 0x76, 0x51, 0xdf, 0x2e, 0x67, 0x4e, 0xf1, 0xbb, +- 0x5f, 0x9d, 0x77, 0x4b, 0xe1, 0x1e, 0x47, 0xf7, 0x9d, 0x7c, 0x67, 0x0f, +- 0x65, 0xdd, 0xc3, 0xe7, 0xb7, 0x58, 0xdf, 0xe7, 0x35, 0x91, 0x57, 0xe2, +- 0xfa, 0xc6, 0x5c, 0x25, 0xb1, 0xfd, 0xdd, 0x12, 0x57, 0x40, 0xc6, 0x63, +- 0x4a, 0xec, 0x0f, 0xa1, 0xa7, 0x05, 0x81, 0xa5, 0xe6, 0x50, 0xdb, 0xee, +- 0x06, 0xe2, 0x14, 0x71, 0x32, 0x70, 0x9c, 0x1c, 0x99, 0xd8, 0x3b, 0xd7, +- 0xaa, 0x60, 0xcc, 0xb8, 0x99, 0xf1, 0x67, 0x60, 0xa2, 0xa0, 0x75, 0xc6, +- 0x78, 0xaf, 0x79, 0x52, 0xb8, 0xfb, 0x01, 0xb4, 0x93, 0xaf, 0x45, 0xcd, +- 0x41, 0x44, 0xad, 0x78, 0x74, 0x42, 0xd1, 0x06, 0xb7, 0x40, 0xbb, 0x40, +- 0xcc, 0x1f, 0x9e, 0x55, 0xb4, 0xa1, 0x3a, 0xaf, 0x96, 0x7e, 0xdb, 0xe1, +- 0xcd, 0x07, 0xb0, 0xda, 0xe1, 0x66, 0x83, 0x48, 0x92, 0xa3, 0xee, 0xe4, +- 0x98, 0xfb, 0x37, 0x29, 0xb8, 0x62, 0xfc, 0x94, 0xeb, 0xa4, 0xa5, 0x33, +- 0x8a, 0x81, 0x2c, 0xe3, 0x3f, 0x7a, 0x5c, 0x38, 0xf8, 0x01, 0x72, 0x70, +- 0x04, 0x42, 0x7c, 0x36, 0x3b, 0x19, 0x1f, 0x0e, 0x78, 0xb5, 0x24, 0xf9, +- 0x77, 0x9a, 0x63, 0x1a, 0x05, 0xf2, 0x72, 0xce, 0x11, 0xbb, 0xaf, 0x34, +- 0x66, 0xa2, 0x34, 0xa6, 0x9e, 0x07, 0xe3, 0x62, 0x02, 0xdb, 0x13, 0xcc, +- 0x01, 0xc4, 0xb2, 0xa3, 0xc2, 0xf5, 0x39, 0x5e, 0xe5, 0x71, 0x83, 0xdf, +- 0x87, 0x95, 0x3d, 0x12, 0x33, 0x95, 0x2e, 0x73, 0xab, 0xe5, 0x1c, 0x35, +- 0xe6, 0x21, 0x2c, 0x38, 0x73, 0x0c, 0xc9, 0x1c, 0x43, 0x3f, 0x52, 0xb4, +- 0xe4, 0x39, 0x45, 0x30, 0xb8, 0xa9, 0xef, 0x1c, 0x63, 0xe4, 0x88, 0xa2, +- 0xb5, 0x1e, 0xa3, 0xfa, 0x41, 0x5d, 0xc6, 0x3f, 0x54, 0x9a, 0x67, 0x08, +- 0x8d, 0x79, 0xc6, 0x5f, 0x21, 0xa0, 0x6c, 0xc9, 0xb5, 0x63, 0x6c, 0xb6, +- 0x1d, 0xa3, 0x39, 0x05, 0xf7, 0x18, 0xcb, 0x70, 0xe9, 0x66, 0xa7, 0xfe, +- 0xa8, 0x59, 0xa1, 0xd7, 0x61, 0x44, 0x45, 0xad, 0x47, 0xff, 0x3c, 0xf6, +- 0x96, 0xb8, 0xfb, 0xf6, 0x13, 0x3d, 0xc4, 0x73, 0x1b, 0x1f, 0x30, 0x56, +- 0xe2, 0x4b, 0x90, 0xf6, 0x9b, 0xad, 0xe4, 0xd9, 0x4b, 0xbd, 0x6e, 0x3c, +- 0xff, 0x7d, 0xc0, 0x5d, 0x03, 0xb1, 0xff, 0x67, 0xef, 0xb5, 0xe3, 0xe9, +- 0x5c, 0x05, 0x5a, 0xd7, 0xe3, 0xce, 0x28, 0x6a, 0x3c, 0xcc, 0x5d, 0xef, +- 0xec, 0x56, 0x1e, 0xe6, 0x3d, 0xe7, 0xd9, 0xc0, 0x6f, 0x98, 0x1f, 0xb7, +- 0xfd, 0x71, 0xa3, 0x5c, 0x97, 0x67, 0x6f, 0xbc, 0xae, 0x9a, 0xff, 0xf2, +- 0xba, 0x82, 0x17, 0x08, 0x50, 0x5f, 0x67, 0xae, 0xc8, 0x67, 0x6d, 0x78, +- 0x4d, 0x1f, 0x06, 0x27, 0x63, 0x38, 0xb0, 0x10, 0xc1, 0x42, 0x56, 0xeb, +- 0xbf, 0xc4, 0xba, 0x60, 0x6f, 0x8b, 0x8e, 0x87, 0x16, 0xa2, 0x98, 0xcf, +- 0xc2, 0x0e, 0x9a, 0x7a, 0x31, 0xa8, 0x24, 0xb1, 0x7f, 0xa1, 0x1e, 0xe7, +- 0xb2, 0xfa, 0x85, 0x51, 0x25, 0x31, 0x5c, 0x47, 0x3e, 0xf1, 0xc8, 0x42, +- 0x33, 0x1e, 0x5e, 0x08, 0xf0, 0x1d, 0x1b, 0x5d, 0xa9, 0x7a, 0x3e, 0xef, +- 0xc1, 0xf3, 0x27, 0x6d, 0x5b, 0xf8, 0xd4, 0xe0, 0x02, 0x30, 0x3f, 0xc5, +- 0x1c, 0x73, 0x86, 0xf9, 0xe6, 0x19, 0x60, 0xff, 0x33, 0x1e, 0xcc, 0x4e, +- 0xd9, 0xd8, 0x6b, 0x8c, 0xd6, 0x79, 0xe8, 0xe4, 0xfd, 0xcc, 0x07, 0x7e, +- 0xe6, 0xb6, 0x7b, 0x55, 0x17, 0xa7, 0x2f, 0x11, 0x87, 0x1e, 0x78, 0x26, +- 0x89, 0x77, 0xb2, 0x19, 0x74, 0x91, 0x77, 0x0f, 0x53, 0x96, 0xb7, 0xb3, +- 0xcc, 0x4f, 0x0b, 0x06, 0xde, 0xca, 0x06, 0x38, 0x4f, 0x33, 0x5e, 0xcb, +- 0xca, 0x33, 0xf2, 0x6c, 0x08, 0x03, 0x94, 0xe5, 0xcd, 0x6c, 0x94, 0x73, +- 0x46, 0xf0, 0x1d, 0x3e, 0x77, 0xff, 0x82, 0xce, 0x7c, 0x14, 0xe0, 0xbc, +- 0x31, 0xbc, 0x91, 0x0d, 0x51, 0xd6, 0x08, 0x73, 0xd0, 0x00, 0xc6, 0xb2, +- 0x4d, 0x17, 0xb6, 0x90, 0xb3, 0xb8, 0x39, 0x44, 0xae, 0x5d, 0xb6, 0xbb, +- 0x9d, 0x98, 0x93, 0x79, 0xca, 0xf3, 0x0e, 0x60, 0x34, 0xfb, 0x9a, 0xb7, +- 0x5c, 0x27, 0xbf, 0x30, 0xb5, 0xe8, 0x70, 0xba, 0xe7, 0x2d, 0xfe, 0x3d, +- 0x0b, 0x9c, 0xb3, 0x32, 0x76, 0xad, 0x49, 0x0e, 0xcb, 0xdc, 0xf3, 0xc3, +- 0x0d, 0xcd, 0x9c, 0x57, 0xef, 0x7f, 0x45, 0x91, 0x3a, 0xc6, 0x87, 0xd8, +- 0x33, 0x62, 0x2f, 0xc6, 0xf1, 0x3c, 0xf0, 0x57, 0xe4, 0x95, 0x8d, 0x93, +- 0x9a, 0xf8, 0x7d, 0x1f, 0xf9, 0x4a, 0x4f, 0x11, 0x0d, 0xc9, 0x87, 0x30, +- 0x62, 0x57, 0x90, 0x77, 0xd7, 0x92, 0xaf, 0x2e, 0x34, 0x33, 0xff, 0x6c, +- 0xb0, 0xed, 0xef, 0xb7, 0xc0, 0xf6, 0x98, 0xba, 0x51, 0xe7, 0x2d, 0x7e, +- 0xbe, 0x06, 0xfa, 0x85, 0xb0, 0xa2, 0x17, 0x7f, 0x88, 0xc4, 0xd0, 0xab, +- 0x10, 0xbb, 0x02, 0x6b, 0x16, 0x7c, 0x58, 0x4b, 0x7d, 0xb6, 0x4e, 0x72, +- 0x6e, 0xf2, 0x8e, 0x04, 0x75, 0xba, 0x7d, 0x92, 0x5c, 0x4a, 0x0f, 0x61, +- 0x35, 0x6d, 0x3c, 0x78, 0xca, 0xb6, 0x2b, 0x69, 0xe3, 0x46, 0xae, 0xcf, +- 0x7d, 0x27, 0x6c, 0xbc, 0x62, 0xbc, 0x42, 0x9b, 0x2a, 0xe4, 0x83, 0x2d, +- 0x7c, 0x27, 0xc2, 0xe7, 0x03, 0xd8, 0x3f, 0x29, 0x75, 0x50, 0x3d, 0x9f, +- 0xb9, 0x88, 0x63, 0xd9, 0x24, 0x9a, 0x69, 0xbf, 0x18, 0xc7, 0x6c, 0xe2, +- 0x3b, 0xb1, 0x05, 0x37, 0x97, 0xc4, 0x16, 0x7e, 0x1d, 0x0e, 0x00, 0xa7, +- 0xa7, 0xb4, 0x89, 0x22, 0xb9, 0x74, 0x8d, 0x39, 0x02, 0xe6, 0x62, 0xbc, +- 0x3d, 0xa3, 0xe0, 0xf8, 0x14, 0x6b, 0xb7, 0x0d, 0xb0, 0xab, 0xa8, 0xc7, +- 0x5b, 0x33, 0xbf, 0x89, 0xe7, 0x4e, 0x52, 0xf7, 0x67, 0x23, 0xf8, 0x7a, +- 0xd6, 0x87, 0x5b, 0x8e, 0x0b, 0x3f, 0xd3, 0x93, 0x07, 0x14, 0xa9, 0x75, +- 0xa4, 0x06, 0x49, 0xc4, 0xfc, 0x8a, 0x07, 0x0d, 0xcf, 0xf9, 0xa0, 0x9f, +- 0x8b, 0xc1, 0xdf, 0x10, 0x80, 0xde, 0xf0, 0xfb, 0xc4, 0x17, 0x0f, 0x2a, +- 0x58, 0x97, 0x6e, 0xff, 0x4a, 0x92, 0xd7, 0x22, 0xbc, 0x86, 0xdf, 0xac, +- 0x84, 0x77, 0xb9, 0x97, 0xf9, 0xb8, 0x42, 0x27, 0xb7, 0xf2, 0xd9, 0xb6, +- 0x97, 0x78, 0xbf, 0xe7, 0xab, 0xb6, 0x1d, 0x5f, 0x2f, 0xcf, 0xab, 0x88, +- 0x9f, 0xd3, 0xf9, 0x9c, 0x9b, 0x03, 0xaf, 0x73, 0x2b, 0x2f, 0x7d, 0x47, +- 0xe2, 0xf3, 0x71, 0xb8, 0xf5, 0x90, 0xcb, 0xc1, 0x5f, 0x2a, 0x08, 0x4f, +- 0x89, 0x39, 0x3a, 0x9c, 0x9d, 0x52, 0x88, 0x73, 0x26, 0x9f, 0xdd, 0x0c, +- 0x6f, 0x4a, 0x9b, 0xc8, 0x70, 0xed, 0xf7, 0xaa, 0xad, 0x78, 0xc1, 0xf2, +- 0xa3, 0x5a, 0x5f, 0x8e, 0x07, 0x7b, 0x54, 0xbc, 0x40, 0x8e, 0xcf, 0x75, +- 0x4a, 0x16, 0x51, 0xc9, 0x5a, 0x8b, 0xe3, 0x79, 0xfe, 0x1a, 0xfa, 0x57, +- 0x3c, 0xc4, 0x36, 0xaf, 0x83, 0x6d, 0x15, 0x0d, 0x40, 0x31, 0xef, 0xc3, +- 0x79, 0xdd, 0xe5, 0x77, 0x2f, 0x39, 0x79, 0x58, 0x53, 0x8b, 0xd7, 0x78, +- 0x9d, 0xd6, 0x9a, 0x56, 0x0e, 0x7b, 0x45, 0xce, 0x17, 0x0b, 0x3b, 0x7d, +- 0xae, 0xff, 0x5c, 0xf4, 0x4a, 0xfd, 0x70, 0xfd, 0x7b, 0x15, 0x3c, 0xa6, +- 0x16, 0x6d, 0xf7, 0x22, 0xe0, 0x33, 0x03, 0x6d, 0xe3, 0xfa, 0xe7, 0x6e, +- 0x90, 0xbd, 0x19, 0x63, 0x85, 0xeb, 0x75, 0x73, 0x67, 0xd6, 0xf1, 0x9b, +- 0x4e, 0xb1, 0xfd, 0x53, 0x86, 0x60, 0xeb, 0xb0, 0xd2, 0x41, 0xac, 0xca, +- 0xf8, 0xdc, 0xba, 0xf8, 0x08, 0xeb, 0xe2, 0xd7, 0xb3, 0xd2, 0x1b, 0x39, +- 0x84, 0x7d, 0x0e, 0xce, 0x0e, 0x09, 0xce, 0xc6, 0xce, 0x42, 0x1b, 0x1c, +- 0x28, 0xe1, 0xec, 0x9c, 0x8b, 0xb3, 0xfd, 0x2e, 0xce, 0x1e, 0x2a, 0xe1, +- 0xec, 0x10, 0x9a, 0xf3, 0x11, 0x72, 0xe0, 0x0e, 0xe6, 0xda, 0x6e, 0x72, +- 0x0e, 0xc9, 0x91, 0x7d, 0xca, 0xce, 0xf9, 0x80, 0xb2, 0x2d, 0x17, 0xc0, +- 0xeb, 0xe4, 0x53, 0x33, 0xbd, 0x50, 0x6f, 0xd9, 0x80, 0xe0, 0xce, 0x5c, +- 0x0f, 0x2a, 0x75, 0xa9, 0x03, 0x2b, 0xb1, 0xdd, 0xc9, 0x55, 0x52, 0x2f, +- 0x49, 0x2f, 0xa0, 0x97, 0x58, 0x07, 0x35, 0x68, 0xba, 0x75, 0xbf, 0xe0, +- 0xde, 0xed, 0x7c, 0xf7, 0x2c, 0xfd, 0x10, 0x6e, 0x4e, 0x53, 0xee, 0x60, +- 0x3d, 0xf0, 0x61, 0x4a, 0x41, 0xf1, 0xce, 0x00, 0x38, 0x16, 0xf5, 0x3d, +- 0xd0, 0x36, 0x3e, 0xd5, 0xa3, 0x74, 0xcc, 0xce, 0x05, 0x99, 0xb7, 0x99, +- 0x93, 0x66, 0x82, 0x6e, 0xae, 0xfe, 0xec, 0x58, 0xd2, 0x73, 0x49, 0xb6, +- 0x6d, 0x22, 0xc7, 0x69, 0x5d, 0xff, 0x8f, 0x36, 0x7e, 0x47, 0xde, 0xff, +- 0xcf, 0x25, 0xfb, 0xa5, 0x29, 0x4f, 0x24, 0xb0, 0xbd, 0xa0, 0x06, 0xd2, +- 0x85, 0x0e, 0xbe, 0xdf, 0xc3, 0xb1, 0x7a, 0x83, 0x1d, 0xd6, 0xdd, 0xc1, +- 0xad, 0x56, 0x77, 0x70, 0x9b, 0xc5, 0xd8, 0x2d, 0xf4, 0xd2, 0x8e, 0x3d, +- 0xac, 0xe1, 0xef, 0x26, 0x7f, 0x90, 0x31, 0xfb, 0xc9, 0x65, 0x82, 0xd4, +- 0x6d, 0x84, 0xba, 0x15, 0xa3, 0x7e, 0xa4, 0x35, 0x3f, 0x34, 0x75, 0xcc, +- 0x59, 0xb7, 0x09, 0xa7, 0x8f, 0x54, 0x65, 0xae, 0x6e, 0xeb, 0x3a, 0x41, +- 0x4c, 0x37, 0x1b, 0xda, 0x6e, 0x39, 0x85, 0x25, 0x7e, 0x53, 0xea, 0x5e, +- 0xd6, 0xb2, 0x89, 0x84, 0xf1, 0x3e, 0x12, 0xd1, 0xd7, 0xf9, 0xec, 0x28, +- 0x7d, 0x75, 0xcc, 0xe9, 0x1d, 0x70, 0x01, 0xf2, 0xcd, 0xe8, 0xb2, 0x02, +- 0xc1, 0xdb, 0x59, 0x57, 0x85, 0x4d, 0xad, 0x75, 0x97, 0x57, 0x7a, 0x19, +- 0xc5, 0xdf, 0x0e, 0xa1, 0x19, 0x9d, 0x85, 0x40, 0x70, 0xcb, 0xf4, 0xe7, +- 0xf0, 0x0f, 0x27, 0x99, 0xbb, 0x20, 0x7e, 0x67, 0xdb, 0xf7, 0xb3, 0x26, +- 0x39, 0x9a, 0xaf, 0xc7, 0x15, 0x67, 0x4d, 0x7d, 0x38, 0x92, 0x8f, 0xe1, +- 0x32, 0xf1, 0xc9, 0xb7, 0x50, 0x87, 0x77, 0xa7, 0xbc, 0xd8, 0x67, 0xdc, +- 0x56, 0xca, 0x09, 0x1e, 0xdc, 0x9b, 0x3c, 0x48, 0x1e, 0xe0, 0x41, 0x2d, +- 0x39, 0xd8, 0x23, 0xce, 0x35, 0x2f, 0x6b, 0xb7, 0x2f, 0x62, 0xd8, 0xcd, +- 0x19, 0x94, 0xb1, 0x9e, 0x32, 0xb6, 0x04, 0xb7, 0xe4, 0xb4, 0xe0, 0x1d, +- 0x39, 0x04, 0xfc, 0xe6, 0xca, 0xb6, 0x33, 0x27, 0x6d, 0x0c, 0x18, 0xab, +- 0xf0, 0xe1, 0xc9, 0xd1, 0x41, 0x1f, 0xfd, 0xe5, 0x27, 0xa9, 0x3e, 0x58, +- 0xd3, 0x38, 0x4f, 0x26, 0x71, 0x31, 0x44, 0xfc, 0x6e, 0x24, 0x67, 0xa0, +- 0x1f, 0x18, 0xf3, 0x8c, 0xc5, 0x6d, 0xf4, 0x0f, 0xfa, 0x43, 0xda, 0x6b, +- 0x26, 0xfa, 0xc7, 0x48, 0x00, 0x6b, 0x28, 0x4f, 0x90, 0xf8, 0x1c, 0x5a, +- 0x88, 0x05, 0xf7, 0x30, 0xa7, 0x44, 0x59, 0x9b, 0x05, 0x13, 0xb8, 0xad, +- 0x0e, 0x89, 0xe4, 0x22, 0xf5, 0xf6, 0x2f, 0x34, 0x07, 0x77, 0x31, 0x47, +- 0x5c, 0x49, 0xd8, 0x23, 0xaf, 0x18, 0x21, 0x84, 0x17, 0x0c, 0xda, 0xbb, +- 0x0f, 0xa3, 0xf3, 0x2c, 0x97, 0x12, 0xac, 0xd7, 0x17, 0x5a, 0x83, 0xb7, +- 0x33, 0x16, 0x6b, 0x88, 0x53, 0x4d, 0x0b, 0xe9, 0xa0, 0xd4, 0x6b, 0xcd, +- 0x0b, 0x1b, 0x29, 0x9f, 0xac, 0x63, 0x73, 0xdb, 0x26, 0xfa, 0x41, 0x6c, +- 0x01, 0xdb, 0x09, 0x65, 0xaf, 0x71, 0xcc, 0xbe, 0x28, 0x79, 0xe8, 0xfe, +- 0x0d, 0x21, 0x62, 0x91, 0xd8, 0x92, 0x76, 0x2c, 0x94, 0x75, 0x92, 0xdc, +- 0xdb, 0xd0, 0xb6, 0x70, 0x4a, 0x72, 0x6f, 0xb4, 0x2d, 0x7b, 0x4a, 0xc7, +- 0x65, 0xe6, 0x8f, 0x35, 0x29, 0xcd, 0x38, 0xa7, 0xc4, 0xa3, 0x17, 0xa9, +- 0x8b, 0x0f, 0x3f, 0xb3, 0xf7, 0xea, 0x89, 0xe2, 0x4a, 0xc6, 0x4f, 0x2d, +- 0xf1, 0x2f, 0x4a, 0x5c, 0xaf, 0x5d, 0xa0, 0x61, 0x16, 0x7e, 0x46, 0xff, +- 0x88, 0x22, 0x90, 0xd0, 0xf1, 0xde, 0xc9, 0x24, 0xed, 0x70, 0x6d, 0xcc, +- 0x03, 0xa4, 0x50, 0x03, 0x4c, 0x77, 0x4f, 0x3c, 0x47, 0x1f, 0x1c, 0xe7, +- 0xbc, 0x15, 0x0b, 0x22, 0xb3, 0x3c, 0x1f, 0xe1, 0xf3, 0xd7, 0xe7, 0xae, +- 0xe5, 0xdc, 0x1f, 0x9d, 0x92, 0xfe, 0x52, 0xb4, 0xed, 0xfc, 0x49, 0x77, +- 0xee, 0x44, 0x2a, 0x89, 0x9f, 0x9e, 0xd4, 0x86, 0xde, 0x53, 0xe2, 0xfd, +- 0xe7, 0x15, 0x99, 0x1f, 0xf5, 0x35, 0xf8, 0xd0, 0x1e, 0x4d, 0x24, 0x86, +- 0xf7, 0x72, 0xcc, 0xd6, 0x8d, 0xb4, 0xbf, 0x23, 0x07, 0x13, 0x3b, 0xb1, +- 0xd4, 0x4f, 0x79, 0x5c, 0x59, 0xea, 0x39, 0xf6, 0xc9, 0x52, 0x9d, 0xc5, +- 0x1a, 0xf3, 0xba, 0x3c, 0x11, 0xda, 0x21, 0xb0, 0xa7, 0x25, 0x84, 0x3a, +- 0xe7, 0x39, 0x95, 0xcf, 0x89, 0x1d, 0x7e, 0xae, 0x78, 0xf4, 0xf7, 0x89, +- 0x5b, 0x82, 0x1d, 0x11, 0x62, 0xd6, 0xdd, 0x52, 0x8f, 0x66, 0x32, 0xf4, +- 0x77, 0x3f, 0xfd, 0x7d, 0xab, 0xf8, 0xb4, 0x45, 0x9f, 0xb6, 0xe8, 0xd3, +- 0x96, 0x16, 0x1d, 0x42, 0x5c, 0x1d, 0xe0, 0xba, 0xa5, 0xa3, 0xe2, 0xeb, +- 0xbd, 0xd8, 0xc7, 0xdf, 0xfb, 0x78, 0xff, 0x08, 0x6b, 0x54, 0x2c, 0x95, +- 0x39, 0x0f, 0xa1, 0xc3, 0x7a, 0x02, 0x83, 0x39, 0xfc, 0x22, 0xd8, 0x52, +- 0x89, 0xca, 0xd5, 0x52, 0x7f, 0x6b, 0xea, 0x51, 0x3c, 0xc1, 0x1a, 0xe8, +- 0xe7, 0x4a, 0xb5, 0xee, 0xeb, 0x39, 0xa6, 0x68, 0x6a, 0x07, 0x6b, 0xd9, +- 0xbd, 0x85, 0xbb, 0xb9, 0xbe, 0xf1, 0xc1, 0xd7, 0x15, 0xd6, 0x41, 0x75, +- 0x9c, 0x9b, 0xb1, 0x74, 0x07, 0xe7, 0xb1, 0x44, 0x0e, 0x07, 0x5f, 0x7f, +- 0x0f, 0x62, 0xdb, 0x6f, 0x37, 0x0e, 0x70, 0x7e, 0x57, 0x8e, 0x51, 0xd6, +- 0x83, 0x03, 0x8c, 0xb1, 0x7d, 0x4e, 0x7c, 0xf5, 0x72, 0x8c, 0xeb, 0xb8, +- 0xb5, 0x25, 0x2b, 0xf9, 0xd2, 0xc6, 0x93, 0x86, 0x8d, 0xe7, 0xf9, 0x7b, +- 0x81, 0xd8, 0x35, 0x76, 0x03, 0x76, 0x79, 0xf8, 0xdc, 0x1e, 0x3e, 0xd7, +- 0x4a, 0xdc, 0x9e, 0x9f, 0x95, 0xbe, 0xde, 0x21, 0xe9, 0xeb, 0x21, 0x6f, +- 0x89, 0xed, 0x87, 0x70, 0x3e, 0x1b, 0x1f, 0xf6, 0x7a, 0xed, 0x11, 0xc6, +- 0xd5, 0x85, 0x8f, 0xe8, 0xbb, 0x6f, 0x6e, 0xd0, 0x7a, 0x68, 0xc3, 0xe4, +- 0xa4, 0xa2, 0x45, 0xbf, 0x8b, 0xe2, 0xf6, 0x00, 0x9a, 0x62, 0x6b, 0xbd, +- 0x09, 0x95, 0x38, 0x57, 0x1c, 0xa0, 0xa6, 0xcf, 0x16, 0x5c, 0x6c, 0xdb, +- 0x54, 0xc2, 0xb6, 0xd6, 0x7c, 0x15, 0xb1, 0x87, 0x39, 0x78, 0xd6, 0xce, +- 0x84, 0x99, 0x9f, 0x0a, 0xb3, 0x32, 0xf6, 0x08, 0x9a, 0x52, 0x32, 0x96, +- 0xde, 0x39, 0xa9, 0xe0, 0x4b, 0xd5, 0x48, 0x30, 0x37, 0xc1, 0xa8, 0xd4, +- 0x33, 0x36, 0x73, 0x90, 0xea, 0x37, 0x25, 0x3f, 0x76, 0x13, 0x0f, 0x7b, +- 0x89, 0x87, 0xc2, 0x99, 0xa5, 0xd7, 0xe9, 0xe2, 0xd1, 0xd6, 0x82, 0xac, +- 0x8b, 0xac, 0x89, 0xac, 0xcd, 0x21, 0xdc, 0x6b, 0x49, 0xdd, 0x6e, 0x63, +- 0xca, 0x48, 0xc4, 0x9e, 0x83, 0xac, 0xd3, 0x21, 0xda, 0xc2, 0x8f, 0x7d, +- 0xc4, 0xbf, 0xbd, 0x2d, 0xb4, 0x55, 0xd8, 0x8f, 0xbd, 0x4e, 0x1f, 0xa0, +- 0x6c, 0x3f, 0x3f, 0xd7, 0x50, 0x61, 0x4e, 0xfb, 0xaa, 0xdf, 0xb5, 0xa3, +- 0xdb, 0x57, 0xf4, 0x9a, 0x32, 0x5e, 0xb9, 0xa7, 0xe8, 0xda, 0x6e, 0x7b, +- 0x56, 0xc6, 0xb5, 0x71, 0xd6, 0x70, 0xb9, 0x69, 0xd9, 0x66, 0x82, 0xed, +- 0x4b, 0x36, 0x02, 0x6b, 0x6f, 0xe0, 0xa7, 0x55, 0xbc, 0xd6, 0x75, 0x9d, +- 0x9f, 0xf6, 0x09, 0x07, 0x26, 0x3f, 0xed, 0xdc, 0x49, 0x7e, 0xda, 0xa0, +- 0x94, 0xb9, 0xa9, 0xf4, 0x14, 0xca, 0xfc, 0xb4, 0xb6, 0x84, 0xcd, 0x87, +- 0xb0, 0x97, 0xdc, 0xa5, 0xae, 0x61, 0x04, 0x81, 0x75, 0x9e, 0x4f, 0x3d, +- 0x18, 0x61, 0xed, 0x51, 0x01, 0x2c, 0xb3, 0xb1, 0x72, 0x7d, 0xc6, 0xae, +- 0xd4, 0x1b, 0x62, 0x95, 0x1e, 0xe9, 0x19, 0x27, 0x32, 0x63, 0xc4, 0x12, +- 0xcf, 0x3a, 0x2d, 0x93, 0x46, 0x40, 0x5d, 0xa2, 0xdf, 0x5d, 0xaa, 0x09, +- 0xa2, 0x81, 0x1d, 0xe4, 0x36, 0x89, 0xd4, 0x2f, 0xed, 0x99, 0xc8, 0x08, +- 0xa2, 0xeb, 0x8a, 0xc3, 0x51, 0xa4, 0x0f, 0x46, 0x1d, 0x5c, 0x99, 0x40, +- 0x3e, 0x11, 0x0d, 0x74, 0x17, 0x32, 0xc1, 0xae, 0xc6, 0x18, 0x76, 0x4e, +- 0x76, 0xb0, 0xe6, 0xd0, 0xb1, 0x6d, 0xb2, 0x93, 0xf5, 0x51, 0x8f, 0xd2, +- 0x33, 0x2b, 0xf6, 0x11, 0xfb, 0x6a, 0x6a, 0xcc, 0x73, 0x63, 0x2f, 0xb3, +- 0x5c, 0xcf, 0xbe, 0xef, 0xf8, 0xce, 0xb8, 0xa1, 0xd2, 0x2e, 0xff, 0xdb, +- 0x8f, 0xb0, 0x8d, 0x33, 0x86, 0xf8, 0x1c, 0xbf, 0xb3, 0xb6, 0xda, 0xda, +- 0x32, 0x65, 0xfb, 0x74, 0xe9, 0x49, 0x47, 0x9d, 0xf5, 0x92, 0x1a, 0xab, +- 0x63, 0xb6, 0x97, 0x6b, 0x54, 0xee, 0x3f, 0xdf, 0xb8, 0x56, 0x9b, 0x83, +- 0x5b, 0x89, 0x67, 0xac, 0xc7, 0x02, 0x01, 0x62, 0x64, 0xe0, 0x94, 0x8d, +- 0x59, 0xe3, 0x1d, 0xfb, 0x49, 0xdd, 0xc7, 0xf5, 0xb8, 0x95, 0x78, 0x2b, +- 0xfc, 0xc3, 0x0c, 0xee, 0x9a, 0xf6, 0x79, 0x58, 0x5b, 0xb5, 0x54, 0xc0, +- 0xa9, 0xad, 0x9c, 0x3e, 0xe1, 0xb1, 0xfc, 0x6d, 0xc1, 0xae, 0x1c, 0xeb, +- 0x04, 0xd6, 0xa9, 0x6e, 0x8d, 0x76, 0x6b, 0xf0, 0x9e, 0x9c, 0x57, 0xa9, +- 0x33, 0xe1, 0x6d, 0xdd, 0x68, 0xe3, 0xe3, 0xf5, 0x89, 0xe1, 0xa8, 0x87, +- 0xd8, 0xc8, 0xb1, 0xac, 0x7c, 0x4b, 0xb0, 0x8f, 0x58, 0x7c, 0x7b, 0x0e, +- 0x69, 0xe9, 0xa9, 0x86, 0xd7, 0x8f, 0xf6, 0x87, 0x21, 0xfd, 0x2f, 0x7c, +- 0x89, 0xd1, 0x18, 0xa1, 0xaf, 0x45, 0xdb, 0x95, 0xc4, 0xe2, 0x20, 0x12, +- 0x17, 0x3e, 0xf6, 0xbe, 0x63, 0x3f, 0x9d, 0xdf, 0xc8, 0xe7, 0x3b, 0x89, +- 0x93, 0x69, 0xe2, 0xe6, 0xe8, 0xb0, 0x1f, 0xf2, 0x8e, 0xd6, 0xf7, 0xb6, +- 0x12, 0xa7, 0x8f, 0xe3, 0x77, 0xf8, 0xbc, 0xba, 0x8d, 0x18, 0x39, 0x6b, +- 0x24, 0xd2, 0x5b, 0x90, 0xe9, 0xac, 0x85, 0x66, 0x34, 0x2a, 0xd2, 0xaf, +- 0x12, 0xfb, 0x27, 0xf1, 0x3d, 0xce, 0xe9, 0xd3, 0xc5, 0x8e, 0x9b, 0x31, +- 0x30, 0xab, 0xa9, 0xd7, 0xfd, 0x4c, 0x6c, 0x20, 0x76, 0xe9, 0xa8, 0x40, +- 0xd5, 0x52, 0xea, 0xf6, 0x3d, 0x07, 0x4f, 0x82, 0xba, 0x8e, 0xff, 0x42, +- 0x1e, 0xf4, 0x17, 0x05, 0xe9, 0x4b, 0x96, 0xb9, 0x9d, 0xf8, 0x44, 0x73, +- 0xdb, 0x2d, 0x33, 0xc9, 0x52, 0x9f, 0x32, 0x10, 0xec, 0x9c, 0xb6, 0x71, +- 0xd2, 0x08, 0x43, 0xea, 0xf3, 0xca, 0x54, 0x91, 0x19, 0xbf, 0x19, 0xdb, +- 0x78, 0xbd, 0x63, 0xba, 0x5a, 0xe9, 0xc8, 0xd9, 0xf8, 0xa6, 0xa1, 0x65, +- 0xda, 0xbd, 0x8c, 0x65, 0x43, 0x3b, 0x0b, 0x5c, 0x26, 0x27, 0x12, 0xdf, +- 0xf2, 0x21, 0xa4, 0xbb, 0x63, 0x35, 0xcf, 0xdc, 0x46, 0xbe, 0x20, 0xb1, +- 0xe5, 0x5d, 0x53, 0x85, 0x94, 0x32, 0xe3, 0x13, 0xbb, 0x75, 0x22, 0x5d, +- 0xa8, 0x56, 0x76, 0xd3, 0x96, 0x77, 0xac, 0xab, 0xc0, 0x25, 0xc7, 0x96, +- 0xb7, 0xd1, 0x96, 0x78, 0x6b, 0x05, 0xbc, 0xe7, 0xeb, 0xd0, 0xa9, 0xc0, +- 0xa9, 0xbd, 0xaa, 0x99, 0x9f, 0xd3, 0xe4, 0xae, 0xe4, 0x7d, 0x6a, 0x2f, +- 0xbe, 0x42, 0x9c, 0x79, 0x92, 0x3e, 0xfa, 0x33, 0xbd, 0x19, 0x55, 0x5f, +- 0x6d, 0xe1, 0x3a, 0x6e, 0x0c, 0xee, 0xc8, 0xf5, 0xe1, 0xa9, 0x79, 0x1b, +- 0xcf, 0x31, 0x3e, 0x1a, 0x53, 0x19, 0xb5, 0x92, 0xb5, 0x18, 0x73, 0xd9, +- 0xe2, 0x09, 0xc7, 0xbf, 0x57, 0xb6, 0x6d, 0x9e, 0x8b, 0xc2, 0xfb, 0x15, +- 0xf9, 0xbb, 0xbe, 0x2d, 0x36, 0x27, 0x9f, 0x51, 0x7e, 0xda, 0x18, 0x32, +- 0xb4, 0xf4, 0xc7, 0xde, 0x2a, 0x54, 0x27, 0x6c, 0x7b, 0x28, 0x25, 0xd7, +- 0xf5, 0xb6, 0xa4, 0x73, 0xbf, 0x81, 0x9f, 0xe5, 0x3e, 0xf2, 0xeb, 0xc2, +- 0xf9, 0x62, 0x69, 0xea, 0xbc, 0x93, 0x79, 0xbd, 0x8f, 0x79, 0xbd, 0xce, +- 0xd4, 0xd2, 0x7b, 0xbc, 0xd2, 0x3b, 0x29, 0x1e, 0xac, 0xe5, 0xf5, 0x5d, +- 0xa5, 0xbc, 0x5e, 0x73, 0x4a, 0xfa, 0x70, 0xe4, 0x7a, 0x70, 0xf7, 0x2f, +- 0xba, 0x99, 0xd7, 0xab, 0x26, 0x7d, 0xe8, 0x62, 0x4e, 0xf7, 0x93, 0x67, +- 0x6f, 0xcd, 0xd7, 0x21, 0x78, 0xc2, 0x8b, 0x78, 0xea, 0xdb, 0x38, 0x48, +- 0x1f, 0x3b, 0x98, 0xf4, 0x2a, 0xb1, 0xe5, 0x1e, 0xda, 0xe9, 0x9f, 0x70, +- 0x40, 0xf5, 0xa2, 0x46, 0xff, 0x2e, 0x1e, 0xfa, 0x35, 0xb9, 0xbc, 0x2f, +- 0x27, 0x31, 0xbd, 0xb2, 0xad, 0xeb, 0x94, 0x9b, 0xcb, 0x43, 0xa7, 0x46, +- 0x17, 0x25, 0x97, 0xd7, 0xad, 0xef, 0xc3, 0xe9, 0x69, 0xfc, 0xe1, 0x0a, +- 0x92, 0xc4, 0x3a, 0xce, 0xd9, 0x90, 0x4a, 0xb0, 0x6e, 0xd6, 0x06, 0xb7, +- 0x29, 0x89, 0x89, 0x1a, 0xc6, 0xfe, 0x69, 0xe6, 0xf2, 0x80, 0x99, 0x50, +- 0x93, 0x1e, 0x74, 0xfb, 0xb9, 0x1e, 0x1f, 0xb0, 0x86, 0xfe, 0x61, 0x3e, +- 0xc6, 0x31, 0x2b, 0xe0, 0x63, 0x2e, 0xff, 0x40, 0xc7, 0xa7, 0x5e, 0xfa, +- 0xde, 0x65, 0x6f, 0x00, 0x57, 0xf3, 0x6e, 0x2e, 0xaf, 0x6d, 0xb4, 0x47, +- 0xae, 0xa4, 0x42, 0xf8, 0x30, 0x6f, 0xd0, 0x07, 0xfb, 0x70, 0x84, 0xb9, +- 0xfc, 0x8a, 0xae, 0xe2, 0xa7, 0xf9, 0x56, 0xfa, 0x65, 0x04, 0x3f, 0x21, +- 0xcf, 0x5d, 0xc7, 0x5c, 0x7e, 0x27, 0x7d, 0x2a, 0xc5, 0x5c, 0xde, 0xee, +- 0xf0, 0x8c, 0xe6, 0xb6, 0x33, 0x53, 0x4e, 0x2e, 0x6f, 0x64, 0x89, 0x5f, +- 0xef, 0x47, 0x62, 0x91, 0xf8, 0x60, 0xff, 0x6c, 0x63, 0x88, 0xcf, 0xd2, +- 0x6e, 0x85, 0xf5, 0x98, 0x71, 0x72, 0xcf, 0xe6, 0xe0, 0x6e, 0xce, 0xbd, +- 0xcc, 0x89, 0x33, 0x1b, 0x3b, 0xd7, 0xbd, 0x89, 0x3f, 0x58, 0xe2, 0xa1, +- 0x1f, 0x9a, 0xc1, 0x3b, 0x18, 0x6b, 0x61, 0xfa, 0xd7, 0x4f, 0x53, 0x89, +- 0xfe, 0x73, 0xac, 0x21, 0x7f, 0xc2, 0x38, 0xbb, 0x93, 0xbe, 0xb1, 0x72, +- 0x5d, 0x80, 0xeb, 0xee, 0xc6, 0x59, 0x07, 0xe3, 0x2c, 0xca, 0x38, 0x5b, +- 0xc1, 0x38, 0x7b, 0xda, 0x48, 0x24, 0x37, 0x93, 0x6f, 0xbd, 0x9e, 0x97, +- 0x58, 0x6b, 0xe1, 0xb8, 0x1a, 0xf5, 0x1a, 0xed, 0x97, 0x98, 0xd9, 0xb9, +- 0x6e, 0xf4, 0x6c, 0x35, 0xc4, 0x56, 0xf8, 0x74, 0x19, 0xb9, 0x05, 0x11, +- 0xe9, 0xc2, 0xa2, 0x37, 0x31, 0xbc, 0xca, 0x9b, 0x18, 0x7a, 0x5f, 0x79, +- 0xc7, 0x7e, 0x8b, 0x71, 0x76, 0x3b, 0xe3, 0x6c, 0x37, 0xe3, 0xac, 0xdd, +- 0xb2, 0xf1, 0x52, 0x4a, 0xeb, 0x6b, 0xf6, 0xc4, 0x8d, 0x76, 0x0f, 0x56, +- 0x54, 0x33, 0x25, 0x04, 0x91, 0xe8, 0xfc, 0x03, 0xca, 0x7f, 0xc1, 0x48, +- 0xf4, 0x24, 0x15, 0x89, 0xad, 0x18, 0x7e, 0x4c, 0xbd, 0x2b, 0x4b, 0xb1, +- 0xb5, 0x7f, 0xf6, 0xd5, 0x92, 0x6f, 0x94, 0x75, 0xf7, 0xe2, 0x45, 0x83, +- 0x18, 0xba, 0x54, 0x8b, 0x65, 0x3c, 0xbd, 0x98, 0xa0, 0x1d, 0x83, 0x89, +- 0x5e, 0x1c, 0x65, 0x1e, 0xbc, 0x9f, 0xf9, 0xf7, 0x01, 0x2b, 0xde, 0xba, +- 0x83, 0x75, 0xce, 0xa5, 0xa8, 0x16, 0x8b, 0x29, 0xbd, 0x18, 0xa0, 0x0f, +- 0x0f, 0x30, 0x5f, 0xb4, 0x5b, 0x3f, 0x57, 0xb6, 0x91, 0x23, 0xdc, 0x57, +- 0x90, 0xf7, 0xb4, 0x64, 0xbf, 0x67, 0x10, 0xfd, 0xf3, 0x82, 0x6d, 0x50, +- 0x6f, 0x32, 0x7b, 0x71, 0xdc, 0xaa, 0x40, 0x6f, 0x4b, 0xb7, 0xb2, 0xab, +- 0x20, 0xbd, 0x33, 0xc6, 0xa3, 0xc5, 0x78, 0x75, 0xe4, 0x55, 0x88, 0xa5, +- 0xdd, 0xc8, 0x4a, 0x7c, 0x5a, 0xbb, 0x95, 0x3b, 0x67, 0x25, 0xc6, 0x7b, +- 0x95, 0x5e, 0x89, 0x61, 0x6b, 0x58, 0xb9, 0x4b, 0x62, 0xda, 0xe9, 0x33, +- 0x4b, 0xdc, 0xcb, 0x3e, 0xc4, 0x6d, 0xe4, 0x6f, 0x60, 0x4c, 0x79, 0xbf, +- 0x1a, 0x65, 0xdc, 0xb5, 0x57, 0x78, 0xe8, 0xa7, 0x71, 0xae, 0x9d, 0x07, +- 0x1d, 0xc6, 0x6f, 0xda, 0x19, 0xb5, 0x9f, 0x31, 0xd5, 0x8b, 0x23, 0xd6, +- 0x6f, 0xd8, 0x57, 0x1c, 0x5e, 0x52, 0xc6, 0xf3, 0xcd, 0xb8, 0x37, 0xb7, +- 0x1c, 0x01, 0x5d, 0xf2, 0x75, 0x08, 0xc9, 0x25, 0x01, 0x54, 0xe9, 0x92, +- 0x67, 0x9a, 0xdb, 0x16, 0x4e, 0x50, 0x86, 0x0d, 0xe5, 0xf8, 0xde, 0x8c, +- 0x07, 0x89, 0x03, 0xfb, 0x52, 0xf7, 0xe2, 0x01, 0xb5, 0x0a, 0x61, 0xda, +- 0xe9, 0x61, 0x35, 0x44, 0x7c, 0xfd, 0xbd, 0xd2, 0x38, 0xff, 0xa9, 0xa2, +- 0x54, 0x33, 0x5f, 0xe3, 0x54, 0x75, 0x8c, 0xb1, 0x4d, 0xd3, 0x52, 0x9b, +- 0x44, 0xdb, 0xa2, 0xd3, 0x3a, 0xc2, 0xac, 0x55, 0x37, 0xa7, 0xb4, 0xe1, +- 0xcd, 0xde, 0xf8, 0xe0, 0xa2, 0x82, 0x6c, 0x98, 0x7c, 0x2e, 0x9f, 0x48, +- 0xf4, 0x34, 0x8b, 0x8d, 0xf5, 0x28, 0xb6, 0xd3, 0x4e, 0x5d, 0xf9, 0x08, +- 0x63, 0xe8, 0xbd, 0x0a, 0xe1, 0x46, 0xe9, 0xfc, 0xf5, 0xb1, 0xa2, 0x1c, +- 0x2b, 0x3a, 0x2d, 0x3c, 0x2d, 0x4a, 0x9e, 0xa6, 0x33, 0x0e, 0x6d, 0x7b, +- 0x13, 0xf9, 0x59, 0xe8, 0x94, 0xd4, 0x38, 0xf1, 0x09, 0x72, 0xda, 0x66, +- 0xf2, 0xdd, 0x5e, 0x7a, 0xb5, 0xbd, 0xb2, 0x21, 0x61, 0xb4, 0x2b, 0x78, +- 0x62, 0xae, 0x85, 0xf5, 0x11, 0xc7, 0xbc, 0x9c, 0x57, 0x71, 0x25, 0x1f, +- 0xc5, 0xbb, 0x1c, 0xfb, 0x92, 0x33, 0x76, 0x3d, 0x7e, 0x54, 0xc2, 0xad, +- 0x14, 0x71, 0x6b, 0x4b, 0x4e, 0xa1, 0xbf, 0xc6, 0x30, 0x62, 0xfc, 0xdd, +- 0xa7, 0x97, 0x6e, 0x0e, 0xd0, 0x6e, 0xa2, 0x8b, 0x8f, 0x9f, 0xe3, 0x78, +- 0xd8, 0xc1, 0xe9, 0x37, 0x3f, 0x9d, 0x59, 0xc2, 0xb5, 0xa2, 0xed, 0x6b, +- 0x4b, 0xef, 0xad, 0x9d, 0xf9, 0xf3, 0x92, 0xbe, 0x3a, 0x3c, 0xa7, 0x92, +- 0xa8, 0x38, 0x75, 0x4d, 0x56, 0x5d, 0xe2, 0x83, 0x19, 0xf5, 0x89, 0xaf, +- 0x71, 0xfe, 0xc7, 0xc8, 0xf5, 0x6c, 0xce, 0x7f, 0xd5, 0x99, 0x37, 0xc2, +- 0x79, 0x95, 0x6b, 0xbc, 0x30, 0x7a, 0xed, 0x1d, 0x95, 0xba, 0xe3, 0xf1, +- 0x28, 0x6d, 0xf7, 0xe1, 0x06, 0x79, 0x2e, 0x84, 0x5d, 0xf9, 0x15, 0x95, +- 0x82, 0xe3, 0x41, 0xd6, 0x01, 0xae, 0x2f, 0x91, 0xe7, 0x59, 0xcf, 0xf1, +- 0x9e, 0xf0, 0xae, 0xcd, 0xe4, 0x18, 0x9f, 0xb5, 0x7b, 0x84, 0x6b, 0xf1, +- 0x7f, 0xf8, 0x8e, 0xdc, 0xfb, 0x75, 0x79, 0xf4, 0x4f, 0x31, 0xcc, 0x1a, +- 0xe8, 0xb1, 0x5c, 0x06, 0x0f, 0xe7, 0xbe, 0xec, 0xec, 0xab, 0xad, 0x5d, +- 0x8f, 0xfb, 0x38, 0xe7, 0x81, 0x5a, 0xc6, 0xd1, 0x7f, 0x4b, 0x25, 0x84, +- 0x1b, 0xed, 0xae, 0x86, 0xe4, 0xda, 0x44, 0xeb, 0x2a, 0xc5, 0x46, 0x45, +- 0x0a, 0x43, 0x1d, 0x2d, 0x89, 0xe4, 0x15, 0x3c, 0x61, 0x4b, 0x5f, 0xd3, +- 0x5b, 0xca, 0xbb, 0x52, 0xff, 0x49, 0x6f, 0xb5, 0xbd, 0xc4, 0x91, 0xb6, +- 0x14, 0xde, 0xf9, 0x4c, 0xef, 0x40, 0xea, 0x6e, 0xc9, 0x37, 0x41, 0xa5, +- 0x9d, 0xf3, 0x1c, 0x21, 0x66, 0xbf, 0x68, 0xbc, 0x12, 0x65, 0x36, 0x86, +- 0x6f, 0x9d, 0x82, 0x83, 0x86, 0x1f, 0x99, 0x88, 0x8d, 0xdd, 0xfc, 0xdc, +- 0x4f, 0xde, 0xf4, 0x9e, 0x51, 0x83, 0x19, 0x55, 0x25, 0x57, 0x24, 0x06, +- 0x7b, 0xde, 0xf4, 0xcb, 0x5e, 0x4c, 0xcc, 0x23, 0xfb, 0xe6, 0xff, 0xd6, +- 0x5e, 0xca, 0x3a, 0xf2, 0x16, 0xd1, 0x3d, 0xa8, 0x10, 0x43, 0x93, 0x20, +- 0x97, 0xd9, 0x6b, 0x14, 0x63, 0x1e, 0xa4, 0xaf, 0x7a, 0xa0, 0x9d, 0xbe, +- 0xcc, 0xfa, 0xee, 0xb1, 0x06, 0xed, 0x74, 0x9b, 0x57, 0xc7, 0xf0, 0xf1, +- 0x00, 0x1e, 0x39, 0xbe, 0x0d, 0xb5, 0x4e, 0xef, 0x67, 0x9c, 0x36, 0xf5, +- 0xb0, 0xae, 0x1a, 0xfd, 0xa5, 0x8f, 0xf5, 0xd5, 0xd5, 0xf5, 0x8f, 0xa3, +- 0xd5, 0xb9, 0x3e, 0x86, 0xfb, 0x72, 0x41, 0xa5, 0x2b, 0xe7, 0xc3, 0xb6, +- 0x3b, 0x1f, 0x87, 0x7f, 0x5d, 0x3f, 0xe5, 0x92, 0xeb, 0xf2, 0xf7, 0x5d, +- 0xac, 0xcb, 0x44, 0xbe, 0x0a, 0xc4, 0x96, 0x53, 0xb6, 0x75, 0x3a, 0x46, +- 0x8e, 0xfb, 0x94, 0x3d, 0xd6, 0x7f, 0xb7, 0xaf, 0x3a, 0xfb, 0x34, 0x72, +- 0xad, 0x4a, 0xf6, 0xef, 0xf9, 0x8c, 0x60, 0xce, 0x00, 0x72, 0x8c, 0xed, +- 0xbb, 0x9c, 0xf7, 0xff, 0xb8, 0xc2, 0xd5, 0x29, 0xcd, 0x7a, 0xb5, 0x83, +- 0xeb, 0x27, 0xcf, 0x24, 0x4b, 0xd7, 0x9a, 0x03, 0xee, 0x19, 0x01, 0xf1, +- 0x85, 0x01, 0xdc, 0xc2, 0x45, 0x68, 0x48, 0x88, 0x8f, 0x0d, 0xa0, 0x21, +- 0x4f, 0x40, 0x5d, 0xee, 0xca, 0xfb, 0x90, 0x55, 0x64, 0xad, 0xa9, 0x13, +- 0x37, 0x69, 0xbb, 0x65, 0xf2, 0xfe, 0x2f, 0x2a, 0x7f, 0xf5, 0x7d, 0xc1, +- 0x5b, 0x72, 0xcc, 0xb0, 0x70, 0xcd, 0x5f, 0x77, 0xff, 0xb7, 0x20, 0xf7, +- 0x7c, 0xfa, 0x9f, 0x30, 0x8e, 0x13, 0x3d, 0xd5, 0x1e, 0xf1, 0x9f, 0x3f, +- 0xc1, 0x03, 0xb3, 0x8f, 0xf0, 0xbe, 0x8c, 0x7f, 0x88, 0x35, 0x84, 0x4f, +- 0xe9, 0x24, 0xfe, 0xec, 0x3f, 0xee, 0xd9, 0x55, 0x81, 0xbf, 0xb4, 0x2b, +- 0x97, 0x8d, 0xa0, 0x21, 0x35, 0xc6, 0xe7, 0x15, 0x74, 0x90, 0x2f, 0x3e, +- 0x65, 0x6c, 0xc1, 0xb6, 0x25, 0x82, 0x01, 0x2f, 0xda, 0x03, 0xbd, 0x62, +- 0x43, 0x05, 0x5b, 0x79, 0xfd, 0x25, 0xae, 0xef, 0xb3, 0x86, 0x0f, 0x0d, +- 0x4b, 0xa5, 0x8f, 0xa7, 0x4d, 0xa5, 0xd1, 0x1e, 0x70, 0xf7, 0xab, 0x32, +- 0x76, 0xad, 0xae, 0x0f, 0xdd, 0xe1, 0x69, 0x98, 0x7a, 0x9b, 0xfe, 0xd4, +- 0xbe, 0xee, 0xc6, 0x7b, 0x65, 0x9b, 0x18, 0xe4, 0x90, 0x2f, 0xd8, 0xb8, +- 0x69, 0x14, 0xea, 0xba, 0x1b, 0xd7, 0xbf, 0x2c, 0xf7, 0x21, 0xc6, 0x20, +- 0x32, 0xb5, 0xa6, 0xf4, 0x79, 0x12, 0x1c, 0xe7, 0x10, 0x7e, 0xbf, 0x30, +- 0x86, 0x83, 0xb9, 0x12, 0xa7, 0xa6, 0x6f, 0xeb, 0xeb, 0xae, 0xeb, 0xf6, +- 0x50, 0x2e, 0xd1, 0x5f, 0x53, 0xd2, 0xed, 0x00, 0xeb, 0x8b, 0x6a, 0x62, +- 0xec, 0x83, 0xb4, 0xe9, 0x90, 0x63, 0xd3, 0x5e, 0x18, 0xf9, 0xeb, 0xe3, +- 0x0e, 0x72, 0xdc, 0xa0, 0x29, 0x76, 0x93, 0x3d, 0xb2, 0x43, 0xd8, 0xcf, +- 0x71, 0xf7, 0xdd, 0x30, 0xee, 0x80, 0x71, 0x7d, 0xdc, 0xbd, 0xb9, 0xc4, +- 0x69, 0x4f, 0x69, 0xdc, 0x47, 0x67, 0xcb, 0x63, 0x64, 0x70, 0xfb, 0xba, +- 0x0c, 0xf2, 0x9b, 0x0e, 0xd8, 0x07, 0x1c, 0x7b, 0x9c, 0x72, 0xae, 0x6f, +- 0x6d, 0x10, 0xee, 0xc5, 0x3f, 0x4d, 0xd9, 0x8f, 0x4f, 0x92, 0x7b, 0xe9, +- 0xce, 0x9e, 0xf0, 0x37, 0x0a, 0xe5, 0xbe, 0x94, 0xf6, 0x4e, 0x97, 0x37, +- 0xcd, 0xd8, 0x8e, 0x04, 0x76, 0x7c, 0xa6, 0x97, 0xb1, 0x8d, 0xf5, 0xd7, +- 0x76, 0xab, 0x3b, 0xd8, 0x69, 0x05, 0xc8, 0xbb, 0xaa, 0x95, 0xad, 0x39, +- 0xe9, 0x69, 0x48, 0x2c, 0x97, 0xb8, 0x70, 0x41, 0xea, 0xbc, 0xbb, 0x59, +- 0x1f, 0x2c, 0x0f, 0x20, 0xdc, 0x8f, 0x89, 0xc2, 0xef, 0x2a, 0xe9, 0x88, +- 0xec, 0x4d, 0x4b, 0x5e, 0x01, 0x73, 0x5e, 0x0f, 0xaa, 0xe9, 0x4b, 0x11, +- 0xd3, 0x30, 0x4f, 0x36, 0xd8, 0x20, 0x47, 0x09, 0x2c, 0x35, 0xd3, 0xe6, +- 0xee, 0x06, 0x2f, 0x8e, 0x39, 0xfc, 0x4b, 0x9b, 0xe1, 0xef, 0x94, 0xc4, +- 0xcc, 0x1d, 0x39, 0xc9, 0x63, 0xa4, 0x90, 0xfa, 0x08, 0xfe, 0x31, 0x55, +- 0x1c, 0x5a, 0x82, 0xf4, 0xfd, 0x4b, 0x20, 0xf5, 0xc4, 0x04, 0xfe, 0x4a, +- 0x8f, 0x06, 0xfa, 0x0a, 0x3e, 0xa5, 0xcb, 0x9a, 0x0b, 0xee, 0xb4, 0xc2, +- 0x08, 0xb1, 0x1e, 0xeb, 0xf6, 0xc6, 0x59, 0x5f, 0x88, 0x1d, 0x03, 0x6d, +- 0xb7, 0xe4, 0xfb, 0x82, 0x1d, 0x96, 0x8b, 0x85, 0x2b, 0x67, 0x02, 0xc1, +- 0x6d, 0xd3, 0xf1, 0xe8, 0x84, 0xc3, 0xc5, 0x42, 0x6d, 0xf1, 0xbc, 0x6d, +- 0xbf, 0x61, 0x14, 0xaf, 0x56, 0x3a, 0xdf, 0x8d, 0xb6, 0x64, 0xbe, 0x19, +- 0xf7, 0x90, 0x3f, 0xb5, 0x4f, 0x37, 0xc3, 0x98, 0x06, 0x4e, 0x1c, 0x8f, +- 0x62, 0x6d, 0x4e, 0x3b, 0x3d, 0xec, 0xed, 0xc3, 0xd4, 0x7c, 0x27, 0x72, +- 0x85, 0xe0, 0x62, 0xcc, 0x43, 0x5e, 0x9d, 0xf2, 0x60, 0x97, 0x71, 0x5c, +- 0x29, 0x2e, 0x53, 0x70, 0x17, 0x11, 0xbc, 0xdf, 0xe1, 0x13, 0x73, 0xac, +- 0x47, 0x15, 0xdc, 0xe4, 0xe0, 0x6e, 0x4b, 0xdb, 0x5a, 0xf2, 0xed, 0x3b, +- 0xc9, 0x07, 0x77, 0x11, 0x57, 0x12, 0xeb, 0x6c, 0xbc, 0x99, 0xca, 0xf4, +- 0xd7, 0x40, 0xeb, 0x39, 0xcc, 0x1a, 0xa8, 0x47, 0x71, 0xf9, 0x5d, 0xd3, +- 0x9c, 0xcb, 0x09, 0x57, 0xcd, 0xb5, 0x90, 0x37, 0xb2, 0xae, 0x49, 0x69, +- 0x31, 0x8f, 0x47, 0xc5, 0x94, 0x33, 0x46, 0xac, 0xcd, 0x98, 0xab, 0x60, +- 0xbe, 0xeb, 0xc5, 0xd3, 0x8e, 0xfc, 0x49, 0xca, 0x77, 0x37, 0xbe, 0x66, +- 0xf5, 0x05, 0xfb, 0x2c, 0xd9, 0xbf, 0x8c, 0x27, 0xaf, 0x7a, 0x4d, 0xf2, +- 0xd7, 0x78, 0xac, 0xce, 0xfb, 0x05, 0x25, 0xe3, 0x6b, 0x6a, 0x9d, 0x83, +- 0xa9, 0x5c, 0x2a, 0x71, 0x36, 0xd1, 0x2f, 0x41, 0x8e, 0xd5, 0x7e, 0x3c, +- 0xb8, 0x98, 0x86, 0xdb, 0xb3, 0xd9, 0x66, 0xfc, 0x2f, 0x14, 0x23, 0xda, +- 0x44, 0x9a, 0x18, 0xb0, 0x85, 0x98, 0xdb, 0xdf, 0xeb, 0xe3, 0x7d, 0xe9, +- 0x79, 0xa9, 0x6d, 0xe3, 0x59, 0x14, 0x83, 0x66, 0x22, 0x73, 0x94, 0x9e, +- 0xd3, 0x53, 0x90, 0xfd, 0x8d, 0x00, 0x1e, 0x60, 0xed, 0x94, 0x2e, 0xed, +- 0xfd, 0x6c, 0x9d, 0x76, 0xf7, 0xb3, 0x0e, 0xcf, 0xfb, 0xc2, 0xdd, 0x56, +- 0x0b, 0xf3, 0xbd, 0xef, 0x86, 0xb1, 0x13, 0x13, 0x2b, 0x3d, 0x1e, 0xac, +- 0x5e, 0xb7, 0x47, 0x99, 0x59, 0x56, 0xce, 0xad, 0x51, 0x27, 0x1f, 0x56, +- 0x50, 0xcf, 0xf3, 0x27, 0x65, 0x8e, 0xcf, 0xb5, 0x8d, 0x9f, 0x94, 0x5c, +- 0xab, 0xb6, 0x6d, 0xb2, 0xb4, 0x3e, 0xa9, 0xfd, 0xa2, 0xb4, 0x53, 0x94, +- 0xba, 0xad, 0x30, 0xd7, 0xb4, 0xd9, 0xd3, 0x5a, 0x74, 0x40, 0x49, 0x93, +- 0xf7, 0x69, 0xc9, 0x5b, 0xbc, 0x1e, 0x3c, 0xa2, 0x6b, 0x83, 0xd2, 0x13, +- 0x7c, 0x19, 0x2e, 0x07, 0x6e, 0x9a, 0x1b, 0x60, 0x5e, 0x73, 0x6d, 0xeb, +- 0xf6, 0x07, 0xeb, 0xdb, 0x9a, 0x1d, 0x5e, 0x6c, 0xdb, 0x97, 0x53, 0xdd, +- 0xe4, 0x0c, 0xc2, 0x8b, 0xe5, 0xfa, 0xea, 0xb6, 0xc6, 0x99, 0x00, 0x65, +- 0x53, 0xf0, 0x3e, 0x73, 0xd2, 0x44, 0xa1, 0x2c, 0xa3, 0xcb, 0x99, 0x77, +- 0x90, 0x33, 0x57, 0x99, 0x5a, 0x6b, 0x17, 0x39, 0xb3, 0x9e, 0x2a, 0xd6, +- 0xf9, 0xd0, 0x8b, 0xa7, 0xac, 0x66, 0x39, 0xe3, 0xe4, 0xf0, 0xe6, 0x2b, +- 0x27, 0xb5, 0xb4, 0x70, 0xe6, 0x1f, 0x18, 0xc0, 0x3d, 0xe4, 0xcc, 0x57, +- 0xb3, 0x3e, 0xec, 0x21, 0x67, 0x5e, 0xcc, 0x06, 0xd0, 0x47, 0xce, 0xfc, +- 0x11, 0xf9, 0xd5, 0xbb, 0xa9, 0x2b, 0x78, 0xb4, 0xd4, 0x07, 0xdb, 0x9b, +- 0xf4, 0xd0, 0xaf, 0x85, 0x37, 0xff, 0xbc, 0xc4, 0x9b, 0xe7, 0xff, 0x05, +- 0x6f, 0xde, 0x4a, 0x3e, 0xd8, 0x9d, 0x13, 0x4e, 0xb0, 0x92, 0x9c, 0xc0, +- 0xc6, 0xcb, 0xa5, 0x1e, 0xd8, 0x0a, 0xe6, 0xb3, 0xa7, 0x53, 0x7d, 0xc8, +- 0x4e, 0x63, 0x79, 0x8d, 0xd3, 0x77, 0x12, 0x99, 0x34, 0xe3, 0xb2, 0x92, +- 0xe8, 0xec, 0x43, 0x82, 0xf5, 0xb1, 0x96, 0xbc, 0xe8, 0xf6, 0xc0, 0x16, +- 0xdf, 0x85, 0xf4, 0x88, 0x7c, 0xa8, 0x59, 0x00, 0x56, 0xdc, 0xd0, 0x03, +- 0xab, 0x49, 0xe0, 0x4f, 0xeb, 0x20, 0xfb, 0x9a, 0x0c, 0xb3, 0x85, 0x66, +- 0xc6, 0xa7, 0x82, 0x23, 0x89, 0x10, 0xba, 0x8f, 0x93, 0xf3, 0x38, 0x3d, +- 0x30, 0x7b, 0xe4, 0x3b, 0x46, 0x1f, 0x8e, 0xce, 0xbb, 0x3d, 0xb0, 0xed, +- 0xe4, 0x6e, 0xbe, 0x44, 0x04, 0x95, 0x0b, 0x3e, 0xbc, 0x40, 0xee, 0xbc, +- 0x95, 0xeb, 0x7c, 0xa6, 0xd4, 0x07, 0x5b, 0xc1, 0x18, 0xb1, 0x73, 0x2a, +- 0x66, 0x16, 0xf0, 0x86, 0x17, 0xb8, 0xb8, 0xc2, 0xe9, 0xed, 0x4b, 0xff, +- 0x3f, 0x84, 0x73, 0x0e, 0x77, 0x0e, 0x2e, 0x66, 0x14, 0x57, 0xb7, 0x0a, +- 0xae, 0x89, 0xac, 0xab, 0x87, 0xeb, 0xda, 0x7e, 0x52, 0xeb, 0x7c, 0x85, +- 0xb6, 0x68, 0x4a, 0xbc, 0xea, 0xac, 0xc7, 0x40, 0x4a, 0x6a, 0xd9, 0x40, +- 0x5b, 0xc0, 0x39, 0x0f, 0xa5, 0xb6, 0xfd, 0x28, 0x1b, 0xef, 0xa9, 0x2c, +- 0xc5, 0xe3, 0xaa, 0x7c, 0x05, 0xd2, 0x25, 0x1f, 0x09, 0xd0, 0xa7, 0x03, +- 0x93, 0x69, 0x54, 0x6d, 0x70, 0xfd, 0x7b, 0x55, 0x7e, 0x9c, 0xbc, 0xb5, +- 0x53, 0xea, 0xe8, 0xf0, 0x76, 0xab, 0x13, 0x53, 0x56, 0x0c, 0x95, 0xe7, +- 0x4a, 0x7b, 0xa6, 0xe7, 0xe4, 0xec, 0x5c, 0x7d, 0x9b, 0xfa, 0xd5, 0x32, +- 0x1f, 0x4c, 0x93, 0xe3, 0x44, 0x02, 0x77, 0x14, 0x84, 0x2b, 0xf6, 0xe0, +- 0xa8, 0xa5, 0x45, 0xbf, 0x87, 0xf8, 0xd0, 0xfd, 0xb4, 0x51, 0xb1, 0xee, +- 0x7a, 0xbf, 0x69, 0x40, 0xfa, 0x51, 0x9f, 0xe9, 0x37, 0x0d, 0xe7, 0xf0, +- 0x8b, 0xba, 0x96, 0x4a, 0x78, 0xd6, 0xfa, 0xc9, 0xe7, 0xb5, 0xe8, 0xd3, +- 0x78, 0x02, 0x23, 0xb9, 0x9f, 0x2b, 0x21, 0xdd, 0x37, 0xf8, 0x13, 0xaf, +- 0x16, 0x9d, 0x53, 0x42, 0x7c, 0xf7, 0xee, 0x60, 0x97, 0x75, 0x37, 0x71, +- 0x27, 0x9e, 0xec, 0x54, 0xbc, 0x98, 0x89, 0x3a, 0x5c, 0x34, 0xd8, 0xc3, +- 0x6b, 0x53, 0x85, 0x32, 0xa7, 0x71, 0x6b, 0xfe, 0xed, 0xc7, 0x5d, 0xfc, +- 0x88, 0xe7, 0x83, 0x8b, 0x97, 0xe0, 0xea, 0x56, 0x4d, 0x5d, 0x1f, 0x9c, +- 0x54, 0xed, 0xfe, 0x65, 0x12, 0xc3, 0x3a, 0xf6, 0xd0, 0xf7, 0xee, 0x99, +- 0x1e, 0xa0, 0x9c, 0xc2, 0xa5, 0x57, 0x10, 0xa7, 0xfa, 0x30, 0x4e, 0x9c, +- 0xb1, 0x28, 0x5f, 0x8e, 0x35, 0xe4, 0xe2, 0xfa, 0x8c, 0x3d, 0xb9, 0x41, +- 0x37, 0x56, 0x7b, 0x8b, 0x4b, 0xa2, 0xe4, 0x36, 0xeb, 0x98, 0xb7, 0xdb, +- 0x0b, 0xcd, 0xb8, 0x7c, 0x46, 0x67, 0x7d, 0xdb, 0x41, 0xee, 0xde, 0x83, +- 0x87, 0xa9, 0xcf, 0xa3, 0x85, 0xc7, 0x91, 0xfe, 0x92, 0x0f, 0x87, 0x8f, +- 0xa7, 0xb1, 0x6a, 0x5d, 0x0a, 0xe9, 0x2f, 0x06, 0x88, 0x53, 0x21, 0x4c, +- 0x30, 0x16, 0xa1, 0xb8, 0x7e, 0x2e, 0xe7, 0x7f, 0xfe, 0x82, 0x36, 0xfb, +- 0x26, 0xed, 0xf7, 0x8d, 0x6b, 0x7b, 0x00, 0x65, 0xfe, 0x7d, 0x9d, 0xab, +- 0x7a, 0xb9, 0x86, 0xfb, 0x9c, 0xd8, 0x8c, 0x32, 0x36, 0x75, 0x5c, 0x2d, +- 0xf5, 0x12, 0x17, 0x4f, 0x6a, 0x8b, 0xf7, 0x22, 0x3e, 0x7c, 0xd9, 0x8b, +- 0x81, 0x3a, 0xfa, 0x5d, 0x94, 0x5c, 0xf5, 0xc3, 0x44, 0xc2, 0x38, 0x47, +- 0xae, 0x3a, 0xba, 0xc1, 0xe5, 0xaa, 0x9e, 0x05, 0x15, 0x15, 0x0b, 0xac, +- 0x65, 0x9d, 0x5e, 0xe2, 0x37, 0x83, 0x6e, 0x2f, 0x51, 0xf8, 0x4d, 0xab, +- 0x9c, 0x75, 0xba, 0x8d, 0xb5, 0x5c, 0xfa, 0x0a, 0x32, 0xe8, 0x2c, 0xcc, +- 0x04, 0xef, 0x21, 0x36, 0xf7, 0x49, 0x6f, 0xa4, 0x10, 0x09, 0xdf, 0x43, +- 0xde, 0xf5, 0x2d, 0xae, 0xaf, 0xec, 0xed, 0xf6, 0x15, 0x56, 0xf3, 0xbd, +- 0x28, 0x3f, 0x05, 0x57, 0x45, 0xf6, 0x1b, 0xf5, 0xe8, 0xa9, 0x92, 0xbd, +- 0x86, 0x97, 0xa9, 0x43, 0xff, 0xdc, 0x4a, 0x3c, 0x3a, 0xe7, 0xaf, 0x12, +- 0xc2, 0xff, 0x68, 0xde, 0xc5, 0xb6, 0x58, 0xfe, 0xae, 0xa0, 0xf0, 0xc9, +- 0xf6, 0xe3, 0xee, 0x77, 0xfd, 0x86, 0xef, 0x65, 0xfd, 0x56, 0x50, 0x3f, +- 0x7b, 0x5a, 0xea, 0xa2, 0x68, 0xdb, 0x19, 0xea, 0xb7, 0x78, 0xd2, 0x89, +- 0x2f, 0xd6, 0x98, 0xf1, 0xe1, 0x84, 0x57, 0xf4, 0xfa, 0x99, 0xe8, 0x45, +- 0xae, 0xc2, 0x78, 0xe1, 0xb8, 0x1e, 0x3d, 0xe2, 0xe8, 0xe5, 0xea, 0xe3, +- 0xf6, 0x69, 0xaf, 0x9c, 0x4c, 0xde, 0xd8, 0x17, 0xd5, 0xc9, 0x97, 0x3f, +- 0x61, 0x6c, 0x3c, 0x71, 0x98, 0x9c, 0xf9, 0x2a, 0x6b, 0x4a, 0x3f, 0x9f, +- 0xaf, 0x73, 0x9e, 0x97, 0x3e, 0xad, 0xe7, 0x1a, 0x67, 0x5e, 0xbc, 0xfe, +- 0x4e, 0x89, 0x2f, 0x4b, 0x4f, 0x5a, 0x9e, 0x53, 0x1d, 0x3b, 0xed, 0x76, +- 0x78, 0xa0, 0x70, 0x2b, 0x1b, 0x1d, 0xeb, 0xfe, 0xad, 0x35, 0x0b, 0x2e, +- 0xce, 0x38, 0x6e, 0xd5, 0x55, 0x25, 0x7b, 0xe1, 0xab, 0xd6, 0x3d, 0x68, +- 0xbb, 0xfe, 0x1c, 0x09, 0xef, 0x62, 0x9c, 0x7c, 0x85, 0xef, 0xec, 0x3a, +- 0x57, 0x1f, 0xbe, 0xcb, 0x6a, 0x71, 0x6c, 0x74, 0xd7, 0xb9, 0x28, 0x46, +- 0x2d, 0xe9, 0xeb, 0x43, 0xf1, 0x99, 0x87, 0xb1, 0x7d, 0x2a, 0x86, 0x77, +- 0x8d, 0x60, 0xe9, 0xec, 0x89, 0xc4, 0xa4, 0xc1, 0x98, 0x8c, 0xd0, 0x77, +- 0xe3, 0xb1, 0x77, 0xc9, 0x51, 0x33, 0x3e, 0xe0, 0x68, 0x8e, 0xb8, 0x46, +- 0xde, 0x08, 0xc5, 0x3d, 0xbb, 0xe9, 0xbe, 0x5b, 0xfe, 0xbb, 0x1a, 0xb1, +- 0x25, 0xf1, 0xd6, 0xfd, 0xa8, 0x47, 0x96, 0xd8, 0x1f, 0xd4, 0xff, 0x1a, +- 0xc7, 0x4e, 0x78, 0x98, 0x1f, 0x08, 0x4e, 0x77, 0x1a, 0xfc, 0xde, 0x34, +- 0xf8, 0x01, 0xfe, 0xd1, 0x9e, 0x91, 0xf3, 0x51, 0x8a, 0x9c, 0xc5, 0xf8, +- 0xc4, 0xae, 0xd3, 0xf5, 0xe2, 0xb7, 0xa0, 0x0f, 0x5f, 0x45, 0xd3, 0xd0, +- 0x22, 0x7e, 0x6c, 0x17, 0x79, 0xef, 0x7d, 0xc6, 0xd1, 0x2b, 0x46, 0x3c, +- 0xea, 0xa1, 0xf0, 0xc5, 0x88, 0x17, 0xf7, 0x1b, 0xb2, 0xa7, 0xa4, 0x0d, +- 0x3d, 0x0f, 0x6d, 0xf0, 0xbc, 0x22, 0x67, 0x6a, 0x2e, 0xd9, 0x99, 0x25, +- 0x32, 0xaf, 0x82, 0xb5, 0xab, 0x9b, 0x3a, 0x2b, 0xa0, 0xb5, 0xfa, 0x15, +- 0xdd, 0xf8, 0x40, 0xf9, 0x7b, 0xbb, 0x18, 0xf9, 0xc4, 0xbe, 0xac, 0x97, +- 0xc7, 0xd5, 0x62, 0x01, 0x6f, 0x59, 0xb6, 0x7a, 0x1c, 0xb3, 0x64, 0x2f, +- 0xee, 0xaf, 0xf1, 0xc0, 0x09, 0x1f, 0x3a, 0x52, 0x3f, 0xb1, 0x33, 0x11, +- 0x19, 0xf3, 0x13, 0xda, 0x42, 0xc6, 0x77, 0xfb, 0xd5, 0x2f, 0x17, 0xa0, +- 0x6c, 0xb3, 0x84, 0x33, 0x8b, 0x5f, 0x4c, 0xc1, 0xb6, 0xa4, 0x87, 0x68, +- 0xe3, 0x8e, 0xd4, 0x08, 0xde, 0x4f, 0xa5, 0xff, 0x63, 0x00, 0xda, 0x85, +- 0x2b, 0x5e, 0xad, 0xd8, 0xec, 0x8d, 0x29, 0xc1, 0x46, 0x7d, 0xa8, 0xd1, +- 0xdd, 0x9f, 0x67, 0xfd, 0x14, 0x0a, 0xec, 0x2a, 0x48, 0x9d, 0x39, 0x85, +- 0x85, 0xc9, 0x0c, 0x7c, 0xe4, 0x77, 0xa3, 0x2d, 0x5a, 0xdf, 0x73, 0x8a, +- 0x16, 0x3d, 0xa0, 0xc4, 0x94, 0x7b, 0xf5, 0x61, 0xbc, 0x60, 0x24, 0xd2, +- 0xed, 0x4a, 0x7d, 0xa0, 0xb3, 0x50, 0x1e, 0xbb, 0x83, 0xb8, 0xa1, 0x15, +- 0xaf, 0x78, 0x2b, 0x51, 0xb7, 0x5e, 0xef, 0xac, 0xf4, 0x6a, 0xc3, 0x5f, +- 0x60, 0x1d, 0xb0, 0xa3, 0x50, 0x0c, 0x7e, 0x90, 0xf0, 0x60, 0x8d, 0xb3, +- 0x87, 0x90, 0x2d, 0xf5, 0x47, 0xa7, 0xd0, 0x35, 0x69, 0x6f, 0xbe, 0x98, +- 0xd2, 0xa2, 0xcf, 0x29, 0x99, 0x3d, 0x21, 0xf2, 0x9a, 0x07, 0xa1, 0xc7, +- 0xe6, 0x19, 0xc7, 0x1d, 0x05, 0x0f, 0x56, 0x3a, 0x7e, 0x9c, 0xe5, 0x98, +- 0x87, 0x51, 0x79, 0xc2, 0xde, 0xbc, 0xc7, 0xd0, 0x86, 0xaf, 0x78, 0x33, +- 0xff, 0xb5, 0x8e, 0x76, 0xdb, 0xa6, 0x68, 0xac, 0x4f, 0x47, 0x70, 0x91, +- 0x3a, 0x7c, 0x3d, 0xa5, 0x25, 0xff, 0x4c, 0xd1, 0x7a, 0xbe, 0x4c, 0x5f, +- 0xf6, 0x9a, 0x61, 0xca, 0xa9, 0x25, 0x67, 0x21, 0xbd, 0xf3, 0x18, 0xae, +- 0x18, 0x99, 0xe0, 0xf6, 0xc6, 0x24, 0xf9, 0x59, 0x94, 0xf9, 0x30, 0x86, +- 0xa3, 0xe4, 0x77, 0x87, 0x0b, 0x15, 0x28, 0xaa, 0x3a, 0xf9, 0x59, 0x0f, +- 0x3c, 0x93, 0x21, 0x65, 0x2e, 0x1b, 0x37, 0x3a, 0xf0, 0x47, 0x28, 0x3a, +- 0x38, 0x77, 0x18, 0xa1, 0x13, 0x3f, 0xb0, 0x6b, 0x74, 0xbd, 0x75, 0x52, +- 0xe1, 0xbc, 0xcf, 0x44, 0x69, 0x63, 0xbe, 0x27, 0xe7, 0x4e, 0xac, 0x6e, +- 0xdc, 0x3b, 0x19, 0xe1, 0xfb, 0x35, 0x58, 0x7b, 0x22, 0x86, 0x0f, 0x53, +- 0x37, 0xa3, 0xe8, 0x70, 0x04, 0x85, 0x7e, 0x40, 0x3f, 0x62, 0xad, 0x95, +- 0x21, 0x8f, 0x94, 0x7d, 0xa3, 0xc3, 0x96, 0xd4, 0xe8, 0x3e, 0x7e, 0x0f, +- 0xf1, 0x57, 0xec, 0xf9, 0x39, 0x72, 0x1d, 0xf9, 0x5c, 0xd3, 0x16, 0x9b, +- 0xfb, 0x5e, 0x95, 0xb3, 0x7f, 0x89, 0x18, 0x9f, 0x53, 0x9d, 0xde, 0xe0, +- 0x28, 0xc7, 0x3c, 0x3b, 0x25, 0xb5, 0x5b, 0xfb, 0xa6, 0x40, 0x69, 0x7f, +- 0xfd, 0x87, 0x86, 0x07, 0x9b, 0x59, 0xdf, 0x47, 0x75, 0x39, 0x9b, 0x39, +- 0xaa, 0xd5, 0x61, 0x13, 0x4e, 0xab, 0x2c, 0xc4, 0xf5, 0xff, 0x80, 0x09, +- 0x35, 0x49, 0xac, 0xd1, 0xf1, 0x5e, 0xf6, 0x37, 0x58, 0xf3, 0xd4, 0xcb, +- 0xd9, 0x1b, 0xac, 0x3c, 0xe1, 0xe7, 0x9c, 0x9b, 0xc9, 0x75, 0xb6, 0xe3, +- 0xbb, 0xaa, 0x5b, 0x6f, 0x10, 0x8f, 0x30, 0x3e, 0x1b, 0x22, 0x1f, 0x0d, +- 0xf0, 0xf7, 0x46, 0xd9, 0x7e, 0x9d, 0x4c, 0xa2, 0xcb, 0xbf, 0x25, 0x53, +- 0x80, 0x7c, 0x80, 0x78, 0x99, 0x7d, 0x0d, 0x1f, 0x72, 0xec, 0xcc, 0xac, +- 0x3b, 0xe6, 0xf1, 0x82, 0x8c, 0x2b, 0xf3, 0xc5, 0x99, 0x37, 0x65, 0xfc, +- 0x90, 0x9c, 0xbf, 0xfd, 0x77, 0xce, 0x41, 0x86, 0x77, 0x82, 0x35, 0xb2, +- 0xd1, 0x88, 0x0e, 0x95, 0xeb, 0x65, 0xc9, 0x1c, 0x1a, 0xeb, 0x51, 0x79, +- 0x37, 0x8a, 0x35, 0x93, 0xf6, 0x48, 0xd4, 0x94, 0xeb, 0xb6, 0x5d, 0xbb, +- 0x51, 0x8f, 0xbe, 0xad, 0xf8, 0x98, 0xf3, 0x7c, 0xb4, 0xc1, 0x38, 0xce, +- 0x66, 0x9b, 0x2e, 0xbc, 0x4f, 0x0e, 0x15, 0x63, 0xbd, 0x77, 0xc9, 0x3b, +- 0x8e, 0xb9, 0xec, 0xb1, 0x6a, 0xe9, 0x13, 0x30, 0x0f, 0x2a, 0xb3, 0xd9, +- 0xfb, 0xab, 0x05, 0xab, 0xc6, 0xe8, 0x0b, 0xcd, 0x93, 0x22, 0xab, 0x3d, +- 0x52, 0xc3, 0x71, 0x8e, 0x72, 0x9c, 0xd9, 0x0d, 0x7a, 0xdf, 0x98, 0x22, +- 0x36, 0x0b, 0xe1, 0x58, 0xe1, 0xa2, 0xf4, 0xd0, 0x68, 0xb7, 0x69, 0x3e, +- 0x2f, 0x76, 0x8b, 0xe0, 0xbb, 0xa5, 0x71, 0x9e, 0x2a, 0x5c, 0xc0, 0x6c, +- 0xf6, 0x2d, 0xe7, 0xef, 0x31, 0xd6, 0x0d, 0xe3, 0xac, 0x21, 0xf3, 0xc4, +- 0x93, 0xc9, 0x6c, 0x53, 0xdf, 0x24, 0xe5, 0x70, 0xcf, 0xca, 0x0d, 0xe0, +- 0xd9, 0xd2, 0x33, 0xa3, 0x7c, 0x77, 0xf4, 0xda, 0xdf, 0x62, 0x23, 0x77, +- 0x0f, 0xdf, 0xdd, 0x53, 0xa8, 0xe4, 0xda, 0xb9, 0xb5, 0xf8, 0x11, 0xcb, +- 0x2f, 0x7d, 0x70, 0xbc, 0x36, 0xb5, 0x19, 0x63, 0xc6, 0x5f, 0x62, 0x2f, +- 0xf5, 0x1e, 0xa7, 0x3d, 0x4f, 0x58, 0xce, 0x5e, 0xbd, 0x9c, 0xcb, 0x22, +- 0x96, 0x87, 0xda, 0xce, 0x90, 0x93, 0x1d, 0x63, 0xcc, 0xdc, 0x97, 0x6a, +- 0xea, 0x79, 0x9d, 0x7e, 0x97, 0xfe, 0xa2, 0xec, 0x87, 0x03, 0x93, 0xb9, +- 0x47, 0x31, 0xb3, 0xa4, 0x69, 0xf1, 0x45, 0x62, 0xc2, 0x69, 0xe2, 0x94, +- 0x8f, 0x98, 0x50, 0x9b, 0xf3, 0x94, 0xf6, 0x77, 0x0d, 0x7e, 0x6f, 0xba, +- 0x30, 0x87, 0xbf, 0xa1, 0x5d, 0x44, 0xbe, 0x78, 0x72, 0x0e, 0xf2, 0xac, +- 0xdb, 0x83, 0xd5, 0xe7, 0x06, 0x71, 0xe9, 0x66, 0xb7, 0x8f, 0xe6, 0x65, +- 0xee, 0xde, 0x97, 0x6d, 0x52, 0xc7, 0x64, 0xec, 0x5e, 0x2d, 0x9a, 0xe1, +- 0x5a, 0x4d, 0x38, 0x1c, 0x5c, 0x65, 0x8e, 0x97, 0x73, 0x58, 0x35, 0xf0, +- 0xd1, 0xf7, 0xc7, 0x0c, 0x39, 0xbf, 0x10, 0x0d, 0xef, 0xe0, 0x1a, 0x8e, +- 0x59, 0x4d, 0xad, 0x71, 0x65, 0x0f, 0xca, 0xfc, 0xdb, 0xe5, 0xd4, 0x5a, +- 0xdf, 0x51, 0x34, 0xf5, 0x3c, 0x88, 0x2f, 0x21, 0xbd, 0xa4, 0xa9, 0x7f, +- 0x0a, 0x71, 0xe3, 0x7e, 0xc8, 0x39, 0x4e, 0x77, 0xac, 0x86, 0x3c, 0x33, +- 0xc9, 0xd2, 0x4f, 0xec, 0x15, 0xfa, 0x53, 0x98, 0x22, 0x77, 0x6c, 0x5c, +- 0xa7, 0x5f, 0xf8, 0x5a, 0xe9, 0x9e, 0xbb, 0x4f, 0x24, 0xfe, 0x12, 0xa0, +- 0x0d, 0x2a, 0xe1, 0x5b, 0x5a, 0xcf, 0x39, 0x68, 0x0b, 0xe7, 0x8c, 0xef, +- 0x45, 0x1c, 0xa4, 0xbf, 0x4d, 0x15, 0x14, 0x18, 0x0d, 0x17, 0x31, 0x24, +- 0xb9, 0x8b, 0xef, 0xb4, 0x67, 0x43, 0xe4, 0xb2, 0x51, 0x54, 0xea, 0xf1, +- 0xd8, 0x28, 0xf5, 0x6b, 0x27, 0x96, 0x8f, 0x13, 0x43, 0x32, 0x6a, 0xc8, +- 0x39, 0x77, 0x5a, 0xa9, 0x47, 0x9d, 0xff, 0x15, 0x90, 0x5a, 0xa8, 0x71, +- 0x46, 0xf6, 0xa8, 0x0f, 0xe3, 0xe2, 0x54, 0x11, 0xc7, 0x52, 0x69, 0xec, +- 0x5f, 0xa2, 0x62, 0xd2, 0x5a, 0xe6, 0xf4, 0x0e, 0xa4, 0xe6, 0xea, 0xca, +- 0x1d, 0x72, 0xfa, 0x91, 0x5b, 0x53, 0x9e, 0x06, 0x39, 0xa7, 0x31, 0xcb, +- 0xda, 0x6b, 0xca, 0x18, 0xc1, 0x41, 0xe3, 0xcb, 0x30, 0x96, 0x0a, 0x76, +- 0x8e, 0xe1, 0xd5, 0x19, 0xc9, 0x71, 0xc9, 0xb6, 0x5b, 0x26, 0xc5, 0x3e, +- 0x1e, 0x72, 0xdf, 0x00, 0x9a, 0x1d, 0x2e, 0xf7, 0x50, 0xdb, 0xea, 0x19, +- 0x97, 0xd3, 0x35, 0xe7, 0xe5, 0xac, 0x74, 0x0d, 0xc2, 0xb4, 0xd7, 0xf9, +- 0x94, 0x9f, 0x98, 0x23, 0xf6, 0x94, 0x33, 0x7a, 0xae, 0x9e, 0xc9, 0xbc, +- 0x82, 0xb1, 0x96, 0x1b, 0xf7, 0x58, 0xe4, 0xff, 0x06, 0xae, 0x9d, 0x1b, +- 0x2c, 0xf5, 0xc7, 0xff, 0xcc, 0xbe, 0x74, 0x93, 0xe8, 0xbd, 0x22, 0x44, +- 0x4c, 0x8f, 0xcd, 0x5c, 0xb3, 0xaf, 0xd8, 0xf4, 0x9c, 0xe4, 0x0c, 0xc7, +- 0xe6, 0x6e, 0xcf, 0x4d, 0x1b, 0xba, 0xac, 0x34, 0x31, 0x9f, 0xd0, 0xaf, +- 0x96, 0xd0, 0xdf, 0x9a, 0xd1, 0xbf, 0xc2, 0xf4, 0xf5, 0x5e, 0xb5, 0x36, +- 0xa3, 0x75, 0xfd, 0x7b, 0x36, 0x6e, 0x6e, 0x87, 0x57, 0x97, 0xeb, 0x33, +- 0x76, 0x5a, 0x95, 0xbf, 0xff, 0x24, 0x24, 0xb9, 0xfe, 0x65, 0xab, 0x68, +- 0xaf, 0x5e, 0xe6, 0x72, 0xc4, 0x1f, 0x64, 0x65, 0xdf, 0x2b, 0x63, 0xb3, +- 0xde, 0xbe, 0xf0, 0xae, 0xf7, 0x10, 0xbe, 0x9f, 0x3f, 0x8c, 0x77, 0xa6, +- 0x7c, 0x08, 0xeb, 0xa2, 0xcb, 0x66, 0xd4, 0xae, 0x4f, 0xa4, 0xdf, 0x23, +- 0x2e, 0x5e, 0x98, 0x29, 0xfb, 0xc5, 0x43, 0x6d, 0x6b, 0x66, 0x14, 0x8e, +- 0x55, 0x83, 0x0a, 0xea, 0xf9, 0x1d, 0xc3, 0x8b, 0x58, 0x89, 0xe3, 0x7a, +- 0x29, 0xa7, 0x9c, 0x7b, 0x10, 0xee, 0x1b, 0xcf, 0x1f, 0x0a, 0xb9, 0x3d, +- 0xb0, 0x10, 0x71, 0x74, 0x1c, 0x13, 0xd9, 0xa6, 0xe4, 0xfb, 0x72, 0x0e, +- 0x87, 0x35, 0xd9, 0x25, 0x8c, 0xe3, 0x44, 0xb6, 0x8c, 0xa1, 0x51, 0x39, +- 0x97, 0x9a, 0x8c, 0x79, 0x5c, 0x8c, 0x8c, 0x79, 0xb4, 0x4c, 0xcc, 0xe3, +- 0x0f, 0x09, 0x77, 0x18, 0x2d, 0xc4, 0xa3, 0x95, 0xf0, 0xe2, 0x3e, 0xc3, +- 0xf5, 0x8f, 0x86, 0x39, 0x3f, 0x62, 0x4b, 0x25, 0x2f, 0x4b, 0x4e, 0xf6, +- 0x31, 0x27, 0x2f, 0x23, 0xbf, 0xf6, 0xe1, 0x4d, 0x5d, 0xec, 0xb1, 0xa6, +- 0x6c, 0x0f, 0xe3, 0x1c, 0x1e, 0xb6, 0x8b, 0x3d, 0xe2, 0x4b, 0x7e, 0x1c, +- 0x6e, 0x9e, 0xb5, 0x67, 0x22, 0xa2, 0xbb, 0x17, 0xa7, 0x89, 0xaf, 0xb8, +- 0x39, 0x1e, 0x3d, 0xcd, 0x9c, 0x3d, 0xa6, 0x97, 0x7d, 0xfc, 0xb7, 0x4b, +- 0x72, 0xea, 0x7d, 0xf3, 0xb8, 0x9f, 0x7f, 0x37, 0x44, 0xf7, 0x2b, 0xee, +- 0x7c, 0xab, 0xe7, 0xfe, 0x26, 0x54, 0xee, 0x9f, 0xca, 0xb3, 0xb1, 0xfc, +- 0xe3, 0xfc, 0x2e, 0x63, 0x85, 0xe8, 0x9f, 0x95, 0xe8, 0x8f, 0xc8, 0xff, +- 0x89, 0x88, 0x5d, 0x64, 0x3f, 0x11, 0xb4, 0x87, 0x8d, 0xd7, 0x68, 0x8f, +- 0xc3, 0xd7, 0xce, 0x4c, 0xb9, 0xf8, 0x55, 0xc5, 0xeb, 0x3b, 0x52, 0xaf, +- 0x6c, 0x0a, 0xe2, 0x17, 0xf6, 0xa5, 0x48, 0x94, 0x98, 0x50, 0xe6, 0xa1, +- 0x62, 0x33, 0xc3, 0xb1, 0x99, 0x5b, 0x2b, 0x5e, 0xd3, 0xa3, 0x38, 0x40, +- 0xbe, 0xbd, 0x90, 0x2d, 0x9f, 0x15, 0x89, 0x13, 0x6b, 0x3e, 0x8f, 0xfe, +- 0x3a, 0x19, 0xaf, 0x9e, 0xfe, 0x95, 0xa4, 0x0d, 0xd4, 0xf0, 0xce, 0x69, +- 0xa9, 0xb5, 0xc9, 0x8f, 0x27, 0xe3, 0xc6, 0x43, 0xe4, 0x91, 0x13, 0x93, +- 0xb6, 0xfd, 0x96, 0x81, 0x3b, 0xc3, 0xcc, 0xef, 0x2f, 0x90, 0x4f, 0x90, +- 0x6f, 0xc4, 0x2a, 0x95, 0xa6, 0xe8, 0x2a, 0xe6, 0xfa, 0x31, 0xd6, 0x0a, +- 0x4f, 0x13, 0xe3, 0x4e, 0x2f, 0x54, 0xc1, 0x3a, 0x21, 0xfb, 0x82, 0x55, +- 0x98, 0x7c, 0x26, 0x49, 0xd9, 0x97, 0x72, 0x9c, 0x00, 0xaa, 0xcf, 0xb4, +- 0xa2, 0xea, 0x94, 0x82, 0x1d, 0x89, 0x56, 0x04, 0xcf, 0xd4, 0x30, 0xff, +- 0x06, 0x70, 0xa5, 0x85, 0x6b, 0xfc, 0x4c, 0x59, 0x0f, 0x67, 0x8f, 0x14, +- 0x4f, 0xe6, 0x62, 0xe4, 0xf1, 0x11, 0x2c, 0x58, 0xb2, 0x1f, 0x1c, 0x70, +- 0xb0, 0xf4, 0xc2, 0x86, 0x7a, 0x67, 0xcf, 0xea, 0xc5, 0x82, 0x1e, 0x3d, +- 0xab, 0xd4, 0xe0, 0xc7, 0x27, 0x8a, 0x37, 0x57, 0xc2, 0x7e, 0x79, 0x85, +- 0x99, 0xe8, 0xdb, 0x4b, 0xff, 0x5f, 0xb3, 0x3a, 0xc2, 0xfa, 0xc6, 0xb6, +- 0xaf, 0x6e, 0x94, 0x3a, 0xd8, 0x70, 0xea, 0x60, 0x77, 0x6f, 0x5f, 0x1f, +- 0x7c, 0x4c, 0xc9, 0x6c, 0x0f, 0xc3, 0xfe, 0xa8, 0xd2, 0xb4, 0x3f, 0xf6, +- 0x9b, 0x09, 0xbe, 0x2f, 0x7b, 0x7c, 0xb6, 0xfd, 0xc3, 0x16, 0xdb, 0xce, +- 0xb7, 0xc4, 0xfb, 0x54, 0xaf, 0x8a, 0x33, 0x8d, 0xb2, 0x2f, 0xe8, 0xc1, +- 0x8f, 0x13, 0x7a, 0x74, 0x2f, 0x64, 0x0f, 0x9e, 0x78, 0xbf, 0x4c, 0xce, +- 0x18, 0xd6, 0x87, 0x3b, 0xad, 0xa5, 0x78, 0x61, 0x7e, 0x23, 0xfa, 0xfd, +- 0x70, 0xce, 0xc5, 0xd8, 0x06, 0xde, 0x5e, 0x01, 0xc9, 0xe1, 0x89, 0xd6, +- 0xc7, 0x10, 0xc1, 0x7c, 0xe1, 0x30, 0x1e, 0x39, 0x21, 0xf5, 0xd7, 0xea, +- 0xb6, 0xc0, 0x09, 0xfb, 0x07, 0x51, 0xb3, 0x48, 0x8c, 0xb4, 0xed, 0xaa, +- 0x8d, 0x4d, 0x51, 0xa6, 0x26, 0xf2, 0x8d, 0x18, 0x79, 0xb3, 0x3e, 0xf8, +- 0x63, 0x2c, 0xc1, 0xd9, 0xd9, 0xf4, 0xcd, 0xe4, 0xf2, 0x9d, 0xcf, 0x2a, +- 0xc2, 0xdb, 0x23, 0x78, 0xbe, 0x20, 0x9c, 0x65, 0x6d, 0x5b, 0xd7, 0x89, +- 0xe5, 0x78, 0x79, 0x3e, 0x82, 0xb3, 0x96, 0x4e, 0xce, 0x04, 0xa5, 0xda, +- 0xb4, 0x6b, 0x6b, 0x29, 0x6b, 0xb5, 0xd7, 0x8b, 0xed, 0x29, 0xa9, 0x19, +- 0xf5, 0xc1, 0x90, 0x82, 0xe5, 0x95, 0xd0, 0x17, 0x1f, 0x06, 0x86, 0x82, +- 0x66, 0xe2, 0xc2, 0xb3, 0x4a, 0xa2, 0xef, 0x03, 0x6f, 0x04, 0xdf, 0x22, +- 0x16, 0x7d, 0xbd, 0x20, 0x67, 0xa5, 0x88, 0x37, 0xb3, 0x31, 0xae, 0x5b, +- 0x00, 0x9e, 0x86, 0x1a, 0x1c, 0x61, 0xec, 0xbc, 0x66, 0x54, 0x10, 0xaf, +- 0xe4, 0xec, 0x94, 0x60, 0x7d, 0xbd, 0x9c, 0x19, 0xb1, 0x5f, 0xd4, 0xdd, +- 0x7a, 0xdf, 0x98, 0xbb, 0xf1, 0x4c, 0xb1, 0x4a, 0x8c, 0x6f, 0xea, 0x89, +- 0x2a, 0x6f, 0xd8, 0xe9, 0x2f, 0x2a, 0xd4, 0xb3, 0xb7, 0x06, 0x55, 0x8e, +- 0xae, 0x18, 0xcd, 0x95, 0xf3, 0x4b, 0xad, 0xd4, 0x77, 0x3d, 0x99, 0x92, +- 0x3f, 0x56, 0x33, 0xee, 0x8f, 0x32, 0x5f, 0x57, 0x9e, 0x90, 0xbc, 0x42, +- 0xfe, 0xad, 0x6c, 0x26, 0x2f, 0x16, 0x0e, 0x11, 0xc0, 0x83, 0xaa, 0xf8, +- 0x86, 0x4a, 0xfd, 0x36, 0xf9, 0xe4, 0x2c, 0xd4, 0x0b, 0x05, 0xc9, 0xeb, +- 0x82, 0x0b, 0xe5, 0xf9, 0xa2, 0xa8, 0x9b, 0x94, 0x35, 0x52, 0xdb, 0x3e, +- 0x9a, 0x0c, 0xc9, 0xd9, 0xf7, 0x11, 0x0f, 0xeb, 0xef, 0x00, 0xfd, 0xeb, +- 0x9e, 0x16, 0x7d, 0x70, 0xb3, 0x57, 0x63, 0x0d, 0x1e, 0x67, 0x2d, 0xa1, +- 0xb5, 0x4e, 0x28, 0x37, 0x8e, 0xf3, 0x6c, 0x8d, 0xc4, 0x4b, 0x86, 0x7a, +- 0x3e, 0xe9, 0xe8, 0xb4, 0x86, 0x3a, 0x09, 0x5e, 0x27, 0x89, 0xd7, 0x35, +- 0xb8, 0x32, 0x05, 0x9d, 0x11, 0x8c, 0x57, 0x0d, 0x02, 0x95, 0x9a, 0x48, +- 0x77, 0x40, 0x62, 0x41, 0xeb, 0x17, 0x3e, 0x55, 0x4d, 0x7c, 0x9e, 0x9d, +- 0x92, 0x7c, 0xa3, 0x08, 0x57, 0xc9, 0xd4, 0x9a, 0x43, 0xf8, 0x70, 0x03, +- 0xf0, 0xc6, 0xa4, 0xbb, 0xef, 0xde, 0x27, 0x67, 0x6f, 0x2b, 0xdd, 0x33, +- 0x0d, 0x8f, 0x39, 0x67, 0x15, 0x64, 0xfc, 0x43, 0x38, 0x93, 0x15, 0x7e, +- 0x39, 0x44, 0x7e, 0x19, 0x1f, 0x26, 0xf7, 0x6c, 0x2d, 0x40, 0x62, 0xb2, +- 0xc9, 0xf8, 0x88, 0xbe, 0xff, 0x2c, 0x79, 0xeb, 0x11, 0xb8, 0xfb, 0xee, +- 0x8d, 0xa5, 0xb3, 0x08, 0xf1, 0x7c, 0xa7, 0xb2, 0xd3, 0x39, 0xcf, 0x64, +- 0x30, 0xde, 0x3a, 0x94, 0x1d, 0xf3, 0xdb, 0x94, 0xae, 0xf9, 0x6e, 0x65, +- 0x4f, 0x41, 0xea, 0xd8, 0xd5, 0x6d, 0x0f, 0x9e, 0xd8, 0xad, 0xec, 0x9c, +- 0xed, 0x55, 0xc8, 0x6f, 0xd5, 0x80, 0xd9, 0xa7, 0x74, 0xcf, 0xbb, 0xfd, +- 0xf4, 0x4e, 0xd6, 0x70, 0x3b, 0x2d, 0xf1, 0x07, 0xb5, 0xad, 0x6b, 0x52, +- 0xfe, 0x17, 0x2b, 0x22, 0xff, 0xf7, 0xd0, 0xbf, 0x55, 0xb1, 0xed, 0x55, +- 0xa9, 0xd7, 0x65, 0x3d, 0xec, 0xe7, 0x53, 0xcc, 0x93, 0x56, 0x0d, 0x06, +- 0x58, 0x83, 0x8c, 0x1a, 0xb7, 0x94, 0xf6, 0xcf, 0x44, 0x27, 0x39, 0x2f, +- 0x21, 0xfe, 0x8a, 0x4c, 0x25, 0x65, 0xf8, 0x07, 0xca, 0xbf, 0xbf, 0xa4, +- 0x57, 0xb7, 0x9c, 0x27, 0xf0, 0x23, 0x23, 0x3a, 0xe4, 0xa9, 0xef, 0xb1, +- 0xc9, 0xeb, 0x7a, 0xf9, 0x78, 0x6d, 0x9c, 0x5c, 0x75, 0xbf, 0xa2, 0x0d, +- 0x3f, 0xe7, 0xea, 0x75, 0xe1, 0x8a, 0xa2, 0x15, 0x47, 0x21, 0xb8, 0xe0, +- 0xea, 0xb5, 0xb6, 0xa4, 0xd7, 0x9a, 0x7c, 0xa7, 0x73, 0x4e, 0xab, 0x86, +- 0x7a, 0x2d, 0x4c, 0x76, 0x28, 0x9d, 0xf3, 0xd2, 0xcb, 0x14, 0xdd, 0x44, +- 0x8f, 0x13, 0x76, 0x95, 0xde, 0xad, 0xdc, 0xee, 0x9c, 0x2b, 0x93, 0xb3, +- 0x5d, 0xb2, 0xdf, 0x5f, 0xd6, 0x4b, 0x72, 0xfa, 0xd2, 0xf0, 0xb6, 0x69, +- 0x35, 0xbc, 0x75, 0xda, 0xb6, 0xbf, 0x6b, 0xfc, 0xb3, 0xa3, 0xcb, 0x59, +- 0x43, 0x74, 0x91, 0x73, 0x23, 0x65, 0x7d, 0xbe, 0x50, 0xd2, 0x47, 0xd6, +- 0xea, 0xfa, 0x3a, 0x95, 0xff, 0x87, 0xef, 0xdd, 0xac, 0x7b, 0xa6, 0xa4, +- 0xac, 0x4f, 0xd8, 0x2c, 0x9f, 0x2f, 0x1b, 0xc2, 0x1b, 0xbc, 0xff, 0x93, +- 0x6c, 0x59, 0x2f, 0x2f, 0xe6, 0x66, 0xc5, 0xfe, 0x43, 0xf2, 0x3f, 0x7c, +- 0xc4, 0x91, 0xb8, 0x31, 0x46, 0x3f, 0x72, 0xf5, 0xd3, 0x86, 0x57, 0x7a, +- 0x9b, 0x8a, 0x57, 0xa0, 0xf5, 0x2f, 0x2a, 0x89, 0x34, 0x6b, 0x70, 0x9c, +- 0x2d, 0xfc, 0xea, 0xfa, 0x35, 0xe7, 0xab, 0x94, 0x6d, 0x39, 0x19, 0xfb, +- 0x21, 0x8e, 0x2d, 0x67, 0x4a, 0x14, 0x3c, 0x37, 0x0b, 0xcc, 0x5a, 0x9c, +- 0xd6, 0x1c, 0xc1, 0xd3, 0x86, 0x6d, 0x3f, 0xdb, 0xa2, 0xcb, 0x59, 0xa0, +- 0xf3, 0x6e, 0xaf, 0x08, 0x46, 0x8d, 0x2e, 0x7b, 0x79, 0x72, 0x9e, 0xa4, +- 0x97, 0x36, 0x10, 0xdd, 0xc5, 0x07, 0xca, 0x6b, 0x2f, 0xe7, 0xdc, 0x32, +- 0xb4, 0x8f, 0xd8, 0xa6, 0x7c, 0xde, 0x4d, 0xfa, 0x30, 0x37, 0xda, 0x64, +- 0x6d, 0xd8, 0x59, 0x5f, 0x43, 0xfc, 0x95, 0xe8, 0x43, 0x5f, 0x9d, 0x23, +- 0x97, 0x18, 0x33, 0xfc, 0x0e, 0x6f, 0x3b, 0x42, 0xae, 0x32, 0xc1, 0xd8, +- 0x79, 0xd2, 0xba, 0x80, 0x0b, 0xf9, 0xd7, 0xf0, 0xc6, 0xb5, 0xff, 0x67, +- 0x13, 0x7f, 0xb9, 0xb8, 0xb1, 0xcb, 0x39, 0xd3, 0x74, 0xba, 0xf5, 0x96, +- 0x84, 0xe0, 0x50, 0x77, 0xb3, 0x9c, 0x71, 0xaa, 0x34, 0xf3, 0x9b, 0x64, +- 0xbf, 0xab, 0xc2, 0x34, 0x6f, 0x3d, 0xaf, 0x8b, 0x6d, 0xfe, 0x62, 0xfd, +- 0x19, 0x5d, 0xf4, 0xfa, 0x9f, 0x6b, 0xc7, 0x9d, 0xff, 0xaf, 0xfc, 0xbb, +- 0x5b, 0xf7, 0xe9, 0x12, 0x3b, 0x67, 0x5b, 0xda, 0x1d, 0x4c, 0x68, 0x35, +- 0x57, 0x39, 0x36, 0x68, 0x31, 0x6f, 0x71, 0x3e, 0x0d, 0x33, 0xe9, 0x7c, +- 0x9a, 0xa6, 0x6b, 0x9b, 0x6e, 0xb3, 0xc1, 0xf9, 0xec, 0x30, 0xdd, 0xf3, +- 0xcf, 0x69, 0x53, 0x77, 0x3e, 0x7b, 0xcc, 0xb8, 0xf3, 0xd9, 0x69, 0xae, +- 0xbc, 0x2e, 0x17, 0x7f, 0xfe, 0x1f, 0x9b, 0x97, 0x53, 0xd9, 0x78, 0x3a, ++ 0xad, 0x7b, 0x0d, 0x70, 0x94, 0xf7, 0x79, 0xe7, 0xef, 0xbf, 0x1f, 0xd2, ++ 0xae, 0xb4, 0x5a, 0xad, 0xf0, 0x82, 0x57, 0x89, 0x52, 0xf6, 0xf5, 0xbe, ++ 0x2b, 0x2d, 0x96, 0x80, 0x77, 0x41, 0x04, 0x11, 0x6d, 0xcd, 0x56, 0x08, ++ 0x21, 0x40, 0xd8, 0x32, 0x56, 0x92, 0x25, 0xc7, 0xd4, 0x2a, 0xc8, 0x20, ++ 0xdb, 0x18, 0x8b, 0x86, 0xe6, 0xe4, 0xd6, 0xad, 0xd6, 0x92, 0xc0, 0x60, ++ 0x56, 0xbc, 0x22, 0x82, 0x08, 0x77, 0xee, 0x26, 0xb2, 0x25, 0x2c, 0xec, ++ 0xac, 0x58, 0x3b, 0xbd, 0xeb, 0xc5, 0x33, 0xc9, 0x58, 0x67, 0x6c, 0x4c, ++ 0x72, 0xfe, 0xc8, 0x75, 0x3a, 0x3d, 0xf7, 0xe6, 0xee, 0xca, 0xf8, 0x83, ++ 0xd8, 0x6e, 0x8c, 0xdd, 0x4c, 0x3a, 0x27, 0x52, 0xdb, 0xef, 0xfd, 0x9e, ++ 0xf7, 0xdd, 0x05, 0xe2, 0xba, 0xd3, 0x99, 0xce, 0x69, 0x66, 0x67, 0xa5, ++ 0xf7, 0xe3, 0xf9, 0x3f, 0xdf, 0xcf, 0xef, 0x79, 0xfe, 0x7f, 0xd5, 0x03, ++ 0x15, 0x28, 0xfe, 0x54, 0xf1, 0xd3, 0x3c, 0x30, 0x78, 0x70, 0xd5, 0x8a, ++ 0xe6, 0x15, 0xf6, 0x05, 0x97, 0xc7, 0x23, 0x37, 0xbf, 0xaa, 0x80, 0xde, ++ 0x0f, 0xf0, 0x6f, 0xfa, 0xf9, 0xca, 0xbf, 0xed, 0x35, 0xfb, 0xc7, 0x0d, ++ 0x84, 0x4a, 0x7c, 0xc9, 0x07, 0x3e, 0x57, 0xea, 0xd2, 0xd7, 0xda, 0x74, ++ 0xf8, 0xdc, 0xa9, 0x93, 0xa9, 0xdd, 0x3a, 0x90, 0xce, 0x37, 0x46, 0x37, ++ 0xe0, 0x53, 0x2b, 0x1b, 0xf6, 0x40, 0xae, 0x7f, 0x25, 0xf5, 0xc9, 0xd0, ++ 0x4f, 0xd6, 0x6a, 0x1f, 0x4f, 0xb9, 0xe1, 0x0b, 0xa5, 0x4e, 0x23, 0x54, ++ 0x0f, 0x5f, 0x1d, 0xdf, 0xf9, 0x0f, 0x0d, 0xd5, 0x6e, 0x04, 0x4b, 0xb4, ++ 0x5a, 0x30, 0x62, 0x22, 0xeb, 0x4b, 0x0d, 0xa0, 0x7c, 0x0d, 0xf0, 0x6e, ++ 0x2e, 0x6e, 0x8c, 0x00, 0xe3, 0xae, 0x54, 0x3c, 0xfa, 0x22, 0x0c, 0x1c, ++ 0x2a, 0x44, 0xd1, 0xce, 0xcf, 0x66, 0xf3, 0x33, 0x2b, 0xea, 0x45, 0xd6, ++ 0xcd, 0xe7, 0x76, 0x35, 0x03, 0x1b, 0x73, 0x06, 0x0e, 0x9b, 0xf0, 0xd5, ++ 0xa6, 0x1e, 0xc6, 0x3a, 0x7e, 0x07, 0x53, 0x83, 0x78, 0x7d, 0x2c, 0x16, ++ 0x7d, 0x0a, 0x5a, 0x46, 0x77, 0x6b, 0x83, 0x40, 0x63, 0x7f, 0x9f, 0xd2, ++ 0x7a, 0xdf, 0x50, 0x5a, 0xf7, 0x98, 0x82, 0x4f, 0xf1, 0xb9, 0xc6, 0xbc, ++ 0x7c, 0x0f, 0xe2, 0xd6, 0xbc, 0x0f, 0x97, 0xdc, 0xb2, 0xfe, 0xef, 0x52, ++ 0xdf, 0x0a, 0x1e, 0xbd, 0x05, 0xa3, 0xe4, 0xc1, 0x9b, 0x52, 0x78, 0xb2, ++ 0x39, 0x1e, 0x19, 0x86, 0xdc, 0x8f, 0x62, 0x43, 0x41, 0xbe, 0x35, 0x4a, ++ 0x6d, 0x59, 0xa3, 0x86, 0x65, 0x9d, 0x31, 0xca, 0x91, 0x0d, 0x69, 0x11, ++ 0x40, 0x61, 0xd8, 0x70, 0x21, 0x1d, 0x6a, 0x8b, 0x7a, 0xa0, 0x45, 0xee, ++ 0xc1, 0x3f, 0x51, 0xe6, 0x74, 0xc2, 0x0b, 0xe7, 0xf9, 0x5e, 0x94, 0x63, ++ 0x3e, 0xe4, 0x68, 0xed, 0xc9, 0x9c, 0x65, 0x5d, 0xd0, 0x3d, 0x38, 0x43, ++ 0xfd, 0x0c, 0xe7, 0xff, 0xc9, 0x9a, 0xa7, 0x6e, 0x46, 0xf5, 0xd2, 0xfa, ++ 0x3e, 0x4c, 0x85, 0x2c, 0x6b, 0x9a, 0xf7, 0x0e, 0xe7, 0x4b, 0x7a, 0xb6, ++ 0x2c, 0x97, 0x6e, 0x59, 0xbb, 0xf5, 0xdf, 0x58, 0xbb, 0x7e, 0xeb, 0x59, ++ 0xcb, 0x7a, 0xcc, 0xb8, 0x09, 0x67, 0x27, 0xda, 0xd5, 0x96, 0xd9, 0x25, ++ 0xc1, 0xcd, 0x93, 0x16, 0x2e, 0x18, 0x08, 0xb9, 0x52, 0x1d, 0x6a, 0xf3, ++ 0x6c, 0xa7, 0xda, 0x58, 0xd8, 0xae, 0x3a, 0xa6, 0xbf, 0xa5, 0x3a, 0x67, ++ 0x7b, 0xd5, 0xa6, 0x42, 0x04, 0x33, 0x66, 0x18, 0xd3, 0x66, 0x46, 0xb5, ++ 0xcf, 0xf6, 0x28, 0x47, 0x8e, 0x41, 0xd5, 0x56, 0x28, 0xd1, 0xba, 0xae, ++ 0xc7, 0xcd, 0xb9, 0x14, 0x8e, 0x98, 0xe5, 0x5c, 0x67, 0xc1, 0xfa, 0x49, ++ 0xc3, 0x02, 0xe5, 0x34, 0x70, 0xb4, 0xf0, 0x18, 0xb6, 0x4d, 0x5a, 0x56, ++ 0x3e, 0x09, 0xe4, 0x0b, 0xc0, 0x0f, 0xcc, 0x58, 0x77, 0xbf, 0xb2, 0xac, ++ 0x4d, 0x71, 0x6b, 0xe9, 0x65, 0xa3, 0x31, 0xf1, 0x12, 0xfe, 0xaf, 0x35, ++ 0x15, 0x46, 0x36, 0x40, 0x1a, 0xc7, 0x68, 0xb3, 0xfb, 0xc6, 0xe0, 0x2b, ++ 0x4f, 0x8d, 0xe2, 0x17, 0x39, 0xf8, 0xca, 0x52, 0x59, 0x5c, 0xc8, 0x0d, ++ 0x87, 0x7c, 0x88, 0x45, 0x36, 0xab, 0xec, 0xa0, 0x0b, 0xda, 0xc0, 0xdb, ++ 0xd0, 0xa2, 0xb4, 0xc7, 0xc5, 0xf3, 0x4a, 0x9b, 0x7f, 0x09, 0x5a, 0xfa, ++ 0x37, 0x4a, 0xeb, 0xac, 0x75, 0x23, 0xed, 0x8a, 0xfb, 0xf0, 0x93, 0x06, ++ 0xb1, 0xc9, 0x28, 0x56, 0xd8, 0xb6, 0xc9, 0x62, 0xd9, 0x35, 0xdb, 0xa4, ++ 0x30, 0x4c, 0xbe, 0x0e, 0x93, 0xaf, 0x97, 0x0d, 0x2d, 0xf2, 0x24, 0xac, ++ 0xa5, 0x7d, 0x86, 0xdc, 0x4b, 0x61, 0xb4, 0x60, 0x45, 0x83, 0xa9, 0x4b, ++ 0xe4, 0x17, 0xd9, 0x2f, 0xa5, 0x7c, 0xd9, 0xea, 0xd4, 0xa7, 0xd6, 0x6b, ++ 0x6b, 0x22, 0x78, 0xa1, 0x10, 0xc6, 0x73, 0x85, 0x10, 0x9e, 0x2d, 0xb4, ++ 0xc3, 0x2c, 0x20, 0xb8, 0xad, 0xf0, 0x45, 0x7e, 0x6c, 0x21, 0xc0, 0xe7, ++ 0xc9, 0x77, 0x70, 0x6b, 0xc1, 0xd3, 0x5b, 0x96, 0x42, 0xf7, 0x4f, 0x73, ++ 0x43, 0x56, 0x85, 0x8e, 0xde, 0x9a, 0x94, 0x9e, 0xbe, 0x55, 0x05, 0x5a, ++ 0xe8, 0x87, 0xdd, 0xaf, 0xe4, 0x5b, 0x3c, 0xfa, 0x71, 0x3f, 0xbc, 0xd4, ++ 0xff, 0xc6, 0x82, 0x65, 0x8d, 0x18, 0x07, 0x56, 0xee, 0x6a, 0xf9, 0x8b, ++ 0xf9, 0x6e, 0xbd, 0x0b, 0xd9, 0x42, 0x1f, 0x10, 0x4c, 0xf1, 0x9b, 0xa1, ++ 0xb8, 0xbd, 0xa9, 0x3d, 0x7a, 0xee, 0x01, 0x8f, 0xe3, 0xcf, 0xe4, 0x81, ++ 0x7a, 0x7f, 0xce, 0x24, 0x0f, 0xe6, 0xe1, 0x20, 0x2a, 0xa2, 0x94, 0xef, ++ 0xe7, 0xe4, 0x33, 0x81, 0x1f, 0x16, 0x74, 0xf2, 0xd6, 0x44, 0x1e, 0xa3, ++ 0xe4, 0xcf, 0x87, 0x5d, 0x13, 0xda, 0x78, 0x16, 0xda, 0x91, 0x29, 0x2c, ++ 0x47, 0x3a, 0x1c, 0xa2, 0x0f, 0xfe, 0x39, 0x1c, 0x1a, 0x5d, 0x38, 0x6e, ++ 0x62, 0x55, 0x28, 0x45, 0xfb, 0x26, 0xf1, 0x70, 0x19, 0xe2, 0xbd, 0x1f, ++ 0x2b, 0x85, 0xd7, 0xe2, 0x5d, 0x18, 0xa3, 0x3c, 0x5d, 0x79, 0x3f, 0xee, ++ 0x9f, 0xa8, 0xc0, 0xbd, 0x13, 0x16, 0xee, 0x4b, 0x22, 0x55, 0x41, 0x79, ++ 0x12, 0xc9, 0x78, 0xf4, 0x3d, 0x78, 0xd0, 0x9e, 0xef, 0x62, 0x2c, 0x6d, ++ 0x40, 0xba, 0xcc, 0x87, 0x0d, 0xf9, 0x00, 0xe3, 0x31, 0x8d, 0xd3, 0x93, ++ 0x3e, 0x78, 0x57, 0xbb, 0x30, 0x15, 0x2e, 0x43, 0xa2, 0xde, 0xc5, 0x4f, ++ 0x38, 0xd8, 0x36, 0x59, 0x17, 0xdc, 0x68, 0x7a, 0xb0, 0xd7, 0x74, 0x61, ++ 0x68, 0xc2, 0xb2, 0xda, 0x0d, 0x0b, 0x57, 0x57, 0x87, 0xf0, 0x3c, 0xf5, ++ 0x77, 0xc0, 0x8c, 0xe0, 0x6c, 0xe1, 0x51, 0xf2, 0x12, 0x76, 0xf8, 0x35, ++ 0xc9, 0xbb, 0x49, 0xde, 0x4d, 0xf2, 0x6d, 0x0a, 0x9f, 0xe7, 0x19, 0x33, ++ 0x06, 0xe5, 0xf2, 0x93, 0x87, 0x4a, 0xf4, 0x93, 0x8f, 0x58, 0xd2, 0x82, ++ 0x2b, 0xa9, 0x65, 0x77, 0x31, 0x79, 0x2d, 0xad, 0xb7, 0xac, 0x8f, 0x57, ++ 0x8b, 0x2c, 0xb4, 0xb9, 0xab, 0x4b, 0x62, 0xf4, 0xf7, 0xaa, 0x18, 0x57, ++ 0x7f, 0x4b, 0xbd, 0x3d, 0x5e, 0xf0, 0x63, 0x70, 0xc2, 0xf6, 0xdb, 0x83, ++ 0x65, 0xe4, 0x5b, 0xf8, 0x2a, 0xe8, 0x71, 0xc6, 0x68, 0x3c, 0xc3, 0x18, ++ 0xc5, 0x56, 0xf2, 0x7c, 0x9f, 0x19, 0x6f, 0xd9, 0xae, 0x3c, 0xd8, 0x94, ++ 0x0f, 0x07, 0xdb, 0x6f, 0xe0, 0x93, 0xf2, 0x4a, 0x0c, 0x52, 0xd6, 0x10, ++ 0xf9, 0x0b, 0x63, 0x37, 0xf9, 0x7c, 0xae, 0xc8, 0xe7, 0x74, 0x41, 0xd6, ++ 0xfa, 0x3c, 0xaf, 0x25, 0x3e, 0x91, 0x5d, 0x94, 0x0a, 0x2b, 0x54, 0x04, ++ 0xb0, 0x3d, 0xff, 0x26, 0x6d, 0x51, 0x87, 0xbf, 0xa0, 0x0d, 0x5e, 0x60, ++ 0x8c, 0xfc, 0xf0, 0x9a, 0xbf, 0x88, 0x3d, 0x1e, 0xa1, 0x1d, 0xb4, 0xd3, ++ 0x59, 0x04, 0xd0, 0x5b, 0x48, 0xe3, 0xd0, 0x24, 0xd2, 0x33, 0xc6, 0x31, ++ 0xc6, 0xfb, 0x12, 0xb8, 0xf5, 0xf2, 0x74, 0x48, 0xaf, 0xc0, 0xee, 0xe9, ++ 0x30, 0x06, 0x0a, 0x6d, 0x30, 0x27, 0xc2, 0xd8, 0x47, 0xdf, 0xbc, 0x92, ++ 0x4c, 0xdf, 0x17, 0x84, 0xf0, 0x1e, 0xc6, 0xfd, 0x7c, 0xe7, 0xb1, 0xc9, ++ 0x30, 0xfa, 0xa9, 0xa3, 0xcd, 0xc9, 0x78, 0x8b, 0x9f, 0xd7, 0xf6, 0xf2, ++ 0xda, 0x61, 0xea, 0xff, 0xbc, 0x31, 0x86, 0xde, 0x6e, 0x2d, 0x01, 0x84, ++ 0xb1, 0xc7, 0x44, 0x88, 0x2e, 0xfc, 0x08, 0xf3, 0x5b, 0xe2, 0x3c, 0xff, ++ 0xbe, 0xa7, 0x50, 0x41, 0x39, 0x83, 0x88, 0xe8, 0x9f, 0x58, 0xde, 0x66, ++ 0xcb, 0xfa, 0xbe, 0x11, 0xbf, 0xf8, 0x96, 0xdb, 0x83, 0x87, 0x0a, 0x2e, ++ 0x0c, 0x4e, 0x57, 0xe0, 0x0f, 0x27, 0x3c, 0xb8, 0xb3, 0xbe, 0x02, 0x07, ++ 0xa6, 0xd3, 0x18, 0x99, 0xac, 0x40, 0xdf, 0x04, 0x96, 0xee, 0x31, 0x46, ++ 0x6a, 0xca, 0xa0, 0x2d, 0xb4, 0x23, 0x81, 0xab, 0xb4, 0xc3, 0x43, 0xd3, ++ 0x81, 0x60, 0x66, 0x32, 0x84, 0xc1, 0x59, 0x3f, 0x9f, 0x77, 0xf1, 0xf9, ++ 0x72, 0x18, 0xab, 0x62, 0x83, 0x21, 0x08, 0x8f, 0x95, 0xd8, 0x3f, 0xed, ++ 0xc7, 0x03, 0x13, 0x21, 0xec, 0x9b, 0x6c, 0xc6, 0xb8, 0x99, 0xc6, 0x51, ++ 0xe6, 0x8e, 0x1f, 0x24, 0xb5, 0xee, 0x7d, 0x4a, 0x4b, 0x6f, 0x54, 0x69, ++ 0x34, 0x24, 0xbd, 0xb8, 0xc4, 0x3c, 0xe4, 0x4d, 0x36, 0xb6, 0x3c, 0xcb, ++ 0xdc, 0x50, 0x96, 0x0a, 0xf3, 0x6f, 0xed, 0x08, 0x63, 0x36, 0xed, 0x75, ++ 0xad, 0x06, 0x16, 0x4b, 0xfc, 0x86, 0x83, 0x5b, 0xcc, 0x50, 0x70, 0x4b, ++ 0xa1, 0x2e, 0xb8, 0xd9, 0x8c, 0x04, 0x37, 0x33, 0xbe, 0x36, 0x8a, 0x3f, ++ 0x9a, 0x3e, 0x1c, 0x4b, 0x7e, 0x6a, 0xf5, 0xd6, 0xd8, 0xf9, 0x2c, 0xb8, ++ 0x6d, 0x52, 0xcb, 0x4e, 0x41, 0x33, 0x58, 0x0d, 0x30, 0x36, 0xeb, 0xa1, ++ 0xfd, 0x14, 0x6a, 0xf4, 0x66, 0xe6, 0xf1, 0x10, 0xf6, 0x33, 0xa7, 0xfc, ++ 0x15, 0x73, 0x4a, 0xdf, 0xf1, 0x58, 0x68, 0x1c, 0x7e, 0xea, 0x1b, 0xd8, ++ 0x75, 0x2e, 0x4c, 0x9b, 0x77, 0xe2, 0x51, 0xf2, 0xb5, 0x79, 0x4d, 0x18, ++ 0xf7, 0x16, 0x42, 0xc1, 0x4e, 0xda, 0xef, 0xbd, 0x7c, 0x24, 0xb8, 0x81, ++ 0xb6, 0x7c, 0x3b, 0xaf, 0x45, 0xe7, 0xf1, 0x8f, 0xe2, 0x4f, 0x09, 0xb8, ++ 0x80, 0x3d, 0xc7, 0xbd, 0x98, 0x0f, 0xcb, 0x5a, 0xd4, 0xb9, 0xf9, 0x82, ++ 0x15, 0xd0, 0xf5, 0xd3, 0xfb, 0xa8, 0xeb, 0x6f, 0x17, 0x02, 0x78, 0xc0, ++ 0xd4, 0x12, 0x3f, 0x54, 0x01, 0xea, 0xd4, 0x47, 0x3d, 0x30, 0xc1, 0x2c, ++ 0x91, 0xe7, 0x92, 0x88, 0x2e, 0x71, 0x72, 0xed, 0x81, 0x69, 0xf1, 0x13, ++ 0xda, 0xde, 0xa4, 0x0f, 0xd0, 0x7f, 0x7e, 0x78, 0x2d, 0x56, 0xb5, 0x50, ++ 0xd6, 0xce, 0xdd, 0x09, 0xfa, 0x8b, 0xa3, 0xa3, 0x13, 0x93, 0xa2, 0x07, ++ 0x6d, 0x1c, 0xae, 0x34, 0x56, 0xae, 0xfa, 0x2b, 0xeb, 0xd2, 0x62, 0xd1, ++ 0x47, 0x08, 0x43, 0xd4, 0xe1, 0x69, 0xd3, 0xb2, 0xae, 0xae, 0xfe, 0xd0, ++ 0x6a, 0xb9, 0x59, 0xf4, 0x22, 0xb2, 0x3e, 0xaf, 0xa4, 0x8e, 0xd4, 0xe8, ++ 0xc1, 0xff, 0x0f, 0xbe, 0xf2, 0x1d, 0xab, 0xd7, 0x96, 0x4f, 0xfc, 0xc5, ++ 0x43, 0x5f, 0x7c, 0x94, 0xb4, 0x5d, 0xe8, 0x25, 0xbd, 0x07, 0x4d, 0xeb, ++ 0xa3, 0xda, 0xd4, 0x67, 0x56, 0xcb, 0x5a, 0x7d, 0x60, 0x41, 0xfd, 0x0f, ++ 0x5e, 0x0f, 0x63, 0x7f, 0xa1, 0x85, 0xba, 0x6b, 0xc7, 0x63, 0xd4, 0xe1, ++ 0x61, 0x53, 0x72, 0x62, 0x84, 0xfe, 0x5c, 0x47, 0xff, 0xf6, 0xa8, 0x8d, ++ 0x66, 0x1e, 0x9b, 0xc7, 0xb2, 0xd8, 0x44, 0x7f, 0xbf, 0x98, 0x8b, 0xb5, ++ 0x3c, 0x0d, 0x2d, 0x4b, 0x19, 0x82, 0x9d, 0xd4, 0x71, 0xbb, 0xa9, 0x75, ++ 0x8a, 0x4d, 0xdb, 0x99, 0x97, 0x5e, 0xcc, 0x45, 0x82, 0x6d, 0x05, 0xd1, ++ 0x77, 0x5d, 0x70, 0x43, 0xe1, 0xab, 0xb4, 0xbd, 0xc2, 0xba, 0xe5, 0x3e, ++ 0xe6, 0x99, 0x3b, 0xe1, 0xd8, 0xd5, 0xb1, 0xdd, 0x6b, 0xc9, 0xc6, 0xde, ++ 0x0f, 0x99, 0x9f, 0xb2, 0x8b, 0x9d, 0x6b, 0x83, 0xbc, 0x56, 0xbd, 0x1a, ++ 0xc1, 0x3b, 0xe8, 0x07, 0x77, 0xd3, 0x0f, 0xae, 0xae, 0xfe, 0xd4, 0x8a, ++ 0xde, 0xe4, 0xf8, 0x41, 0xdb, 0xa4, 0x27, 0xd8, 0x41, 0x3d, 0x6d, 0x34, ++ 0x14, 0xa6, 0x8d, 0x1c, 0x7a, 0xaf, 0x61, 0x87, 0xf4, 0xd4, 0x59, 0x23, ++ 0xcd, 0x3c, 0xf2, 0xbb, 0xf0, 0xd4, 0x60, 0xea, 0x69, 0xe3, 0x51, 0x44, ++ 0x1d, 0xdf, 0xc1, 0xbe, 0x09, 0x3f, 0xb2, 0x77, 0x86, 0x30, 0xd3, 0x10, ++ 0xc2, 0x83, 0xa4, 0x7d, 0x25, 0xd9, 0xd8, 0xff, 0x3a, 0x75, 0x30, 0x55, ++ 0x23, 0xd7, 0xd2, 0xf8, 0x91, 0xf1, 0x30, 0x70, 0x93, 0xb3, 0xf6, 0xac, ++ 0xc4, 0xe8, 0x6c, 0x33, 0x0e, 0x17, 0x32, 0xca, 0xc9, 0x9b, 0x5a, 0x67, ++ 0x1a, 0x3f, 0xb7, 0x24, 0x97, 0xce, 0x9a, 0xcc, 0x71, 0xd4, 0xc7, 0x28, ++ 0xfd, 0x68, 0x38, 0x5f, 0x17, 0xdc, 0x44, 0x3f, 0x7a, 0x34, 0x2f, 0x32, ++ 0xc5, 0x0d, 0xc3, 0x5d, 0xcb, 0xda, 0x4c, 0xfd, 0x98, 0x76, 0xcd, 0xaf, ++ 0x0e, 0xe9, 0x47, 0x31, 0x6e, 0xf3, 0x36, 0xa8, 0x32, 0xc4, 0x18, 0x0c, ++ 0x99, 0xea, 0x72, 0xfd, 0x00, 0x1e, 0xb5, 0xaf, 0x85, 0x83, 0x3b, 0x26, ++ 0xd3, 0x2e, 0x97, 0x8e, 0x50, 0x65, 0xaa, 0x5d, 0xed, 0x60, 0xdd, 0xed, ++ 0x98, 0xec, 0x50, 0x1d, 0xb3, 0x12, 0x03, 0x9d, 0x6a, 0x33, 0x6b, 0x6e, ++ 0x9a, 0x35, 0x37, 0xcd, 0x9a, 0x9b, 0x26, 0x1f, 0x69, 0xd6, 0xda, 0xb6, ++ 0xc2, 0xa0, 0xda, 0x2a, 0xfa, 0xa7, 0x7f, 0x3d, 0x6b, 0x3a, 0x38, 0x82, ++ 0x39, 0x28, 0xb8, 0xa9, 0xb0, 0xc2, 0xe5, 0x60, 0xbb, 0x41, 0x55, 0xc4, ++ 0x32, 0xbe, 0x0a, 0x9d, 0xb5, 0xcc, 0x1c, 0x54, 0x5b, 0x58, 0x6f, 0x33, ++ 0xb6, 0x2e, 0x63, 0x03, 0xef, 0xb0, 0xce, 0xbe, 0xc6, 0x3a, 0x9b, 0x4f, ++ 0x32, 0xae, 0x96, 0x5f, 0xb5, 0x7a, 0x17, 0x3b, 0x35, 0x61, 0x84, 0xfc, ++ 0x7e, 0x9f, 0x36, 0x9b, 0x67, 0x2d, 0x6d, 0x77, 0x2b, 0xec, 0xd1, 0x51, ++ 0x5d, 0xcb, 0x9c, 0x7a, 0xb8, 0xc0, 0x3a, 0x60, 0xc4, 0x5a, 0xde, 0xa7, ++ 0x62, 0x0f, 0xeb, 0x5e, 0x5c, 0xbd, 0x89, 0x60, 0x47, 0x6f, 0xc3, 0xb1, ++ 0x89, 0x72, 0xf4, 0x27, 0xd3, 0x8b, 0x7c, 0xc4, 0x2a, 0x9d, 0xcd, 0x78, ++ 0x98, 0x4b, 0xab, 0x48, 0x2a, 0x4e, 0xbf, 0x41, 0xfa, 0x38, 0xeb, 0xc4, ++ 0x98, 0xf9, 0x55, 0xe4, 0x59, 0x4f, 0x67, 0x0c, 0x0f, 0x5e, 0xcb, 0xaf, ++ 0x60, 0x9e, 0x8b, 0x1b, 0x01, 0x55, 0xc1, 0xf8, 0x4d, 0x21, 0x67, 0x4a, ++ 0x7e, 0xb2, 0xac, 0x19, 0xe1, 0x21, 0x1e, 0x4f, 0x0f, 0x43, 0x72, 0x96, ++ 0xb5, 0xf4, 0x9e, 0x64, 0x19, 0xd6, 0xc5, 0x83, 0x58, 0xaa, 0xf7, 0xaa, ++ 0xce, 0x42, 0xdc, 0x38, 0x8f, 0x6f, 0xa9, 0xbb, 0x67, 0x53, 0x8c, 0xed, ++ 0x0c, 0x75, 0x53, 0x81, 0x4b, 0x61, 0xe1, 0x11, 0xd5, 0x5e, 0xdd, 0x85, ++ 0x77, 0xef, 0x52, 0x08, 0xe9, 0x69, 0x5c, 0x68, 0x0e, 0xd1, 0xaf, 0x3a, ++ 0x89, 0x31, 0xa2, 0x70, 0xcf, 0x45, 0x82, 0x5b, 0x69, 0x8b, 0xca, 0xb9, ++ 0x3a, 0xda, 0x87, 0xbe, 0x47, 0x1d, 0xb6, 0x51, 0x87, 0x5b, 0xa6, 0x11, ++ 0xaa, 0x48, 0xf5, 0xa8, 0x8e, 0x42, 0xbb, 0x6a, 0x2f, 0x68, 0xd4, 0x93, ++ 0xe8, 0xe4, 0x3b, 0xc4, 0x4a, 0xe2, 0x2b, 0x25, 0x5b, 0x8a, 0xbf, 0xde, ++ 0x68, 0xcf, 0x8c, 0x4b, 0x62, 0x6e, 0xdd, 0xf2, 0x14, 0xe3, 0xd1, 0x45, ++ 0xbe, 0x84, 0x07, 0x1f, 0xaa, 0x1b, 0xac, 0xa5, 0x57, 0x92, 0x4c, 0x9e, ++ 0x15, 0x29, 0x1c, 0x2f, 0x74, 0xd1, 0x2e, 0xab, 0x8b, 0xfe, 0x15, 0x0a, ++ 0x6e, 0x9c, 0x6c, 0x57, 0x1b, 0x67, 0x17, 0x05, 0xbb, 0x69, 0xc3, 0xee, ++ 0xd9, 0x88, 0xd0, 0xe5, 0xfa, 0x62, 0xdb, 0x34, 0x5c, 0xfa, 0xbf, 0x64, ++ 0xcb, 0x6f, 0x93, 0x96, 0xd8, 0xd3, 0x5f, 0xf2, 0xd3, 0xe0, 0xdd, 0x93, ++ 0x69, 0xbc, 0xbb, 0xda, 0xcb, 0x9a, 0x5a, 0xc2, 0x14, 0x55, 0xc5, 0xef, ++ 0xd3, 0x2e, 0xe8, 0x83, 0xaa, 0x53, 0xfc, 0xc8, 0xeb, 0xac, 0x79, 0xc7, ++ 0x24, 0xbc, 0x84, 0x0a, 0x51, 0x37, 0x31, 0xdd, 0x87, 0xc9, 0x78, 0xef, ++ 0x39, 0xd5, 0xa5, 0xba, 0x0a, 0x52, 0x83, 0x1d, 0x9f, 0x6a, 0xa3, 0x4f, ++ 0xb5, 0x93, 0x9f, 0x76, 0xfa, 0xd4, 0x16, 0xf2, 0xb3, 0xc5, 0xf6, 0x29, ++ 0xf1, 0xcd, 0xdf, 0xe6, 0x65, 0x43, 0xe1, 0x6e, 0x5b, 0x2f, 0x5b, 0xf9, ++ 0x6e, 0x27, 0xe5, 0xe8, 0xe4, 0x7b, 0x77, 0xf3, 0xbd, 0xbb, 0x67, 0xff, ++ 0x97, 0xf0, 0x47, 0x59, 0x9c, 0xd8, 0xbf, 0x5e, 0xd3, 0x24, 0x07, 0xfc, ++ 0xac, 0x88, 0x29, 0x90, 0x75, 0xa5, 0x24, 0x47, 0x0c, 0xa0, 0xbb, 0x19, ++ 0xbe, 0x45, 0xa9, 0x67, 0x5b, 0xb7, 0xd7, 0x33, 0x9f, 0x31, 0x9f, 0xfa, ++ 0x8e, 0x13, 0x4b, 0x33, 0x47, 0xcf, 0xb4, 0x28, 0x8c, 0x18, 0x37, 0x33, ++ 0x4e, 0x0d, 0x1c, 0x29, 0x68, 0x9d, 0x51, 0xde, 0x6b, 0x1a, 0x13, 0x8c, ++ 0xbf, 0x0f, 0x6d, 0xc4, 0x75, 0x91, 0x54, 0x3f, 0x22, 0x66, 0x2c, 0x72, ++ 0x44, 0x69, 0xfd, 0x1b, 0xa0, 0x5d, 0x64, 0x6d, 0x18, 0x9c, 0x56, 0xda, ++ 0x40, 0xad, 0x5b, 0x4b, 0xbf, 0x61, 0xe3, 0xeb, 0x7d, 0x58, 0x6e, 0x63, ++ 0xb8, 0x7e, 0x24, 0x88, 0x65, 0xb7, 0x92, 0xe6, 0xde, 0x75, 0x0a, 0x97, ++ 0x8d, 0x0f, 0x69, 0x47, 0x2d, 0x9d, 0x55, 0x06, 0x72, 0xcc, 0x13, 0x91, ++ 0xe3, 0x82, 0xd5, 0xf7, 0x11, 0xab, 0xc3, 0x17, 0xe0, 0xb3, 0xb9, 0xb1, ++ 0xd8, 0xa0, 0xcf, 0xad, 0x25, 0x88, 0xd3, 0xd3, 0xa4, 0x69, 0x14, 0x88, ++ 0xdf, 0xb9, 0x46, 0x74, 0x4f, 0x91, 0x66, 0xbc, 0x48, 0x53, 0xcf, 0x83, ++ 0x71, 0x73, 0x04, 0x9b, 0xe2, 0xac, 0x15, 0xcc, 0x79, 0x47, 0xa5, 0x27, ++ 0x20, 0xbd, 0xf2, 0xe3, 0x06, 0xff, 0x1e, 0x54, 0x3b, 0x24, 0xa6, 0xca, ++ 0x1d, 0x2b, 0x54, 0x73, 0x8d, 0xaa, 0xd4, 0x41, 0xcc, 0xd9, 0x6b, 0x0c, ++ 0xc8, 0x1a, 0x03, 0xbf, 0x50, 0x5a, 0xe2, 0x9c, 0x92, 0x5c, 0xdd, 0x98, ++ 0x39, 0xc7, 0x18, 0x3a, 0xac, 0xb4, 0x96, 0x63, 0x14, 0xdf, 0xaf, 0x0b, ++ 0xfd, 0x83, 0xc5, 0x75, 0x06, 0xd0, 0x90, 0x67, 0x7c, 0x16, 0x7c, 0x6a, ++ 0xc3, 0x44, 0x1b, 0x46, 0xa6, 0xdb, 0x30, 0x3c, 0xa1, 0x70, 0xb7, 0xb1, ++ 0x18, 0x97, 0x6e, 0xb6, 0xfb, 0x94, 0xaa, 0xa5, 0x7a, 0x2d, 0x86, 0x42, ++ 0xa8, 0x76, 0xe9, 0x5f, 0xc1, 0xae, 0x22, 0xc6, 0xdf, 0x74, 0xa2, 0x9b, ++ 0x79, 0xdf, 0xc2, 0xfb, 0x8c, 0xa5, 0x58, 0x0d, 0xd2, 0xde, 0x54, 0x0b, ++ 0xf1, 0x78, 0x9d, 0xdb, 0x89, 0xf7, 0x0f, 0x7d, 0x8e, 0x0d, 0x44, 0xff, ++ 0x9f, 0xbf, 0xd7, 0x86, 0xc7, 0x27, 0xca, 0xd0, 0xb2, 0x1a, 0x77, 0x46, ++ 0x50, 0xe5, 0x62, 0x8d, 0x7b, 0x73, 0xbb, 0x1a, 0xe4, 0x3d, 0xfb, 0x59, ++ 0xdf, 0x97, 0x53, 0x46, 0xea, 0x4f, 0x1a, 0xe4, 0xba, 0x9d, 0x37, 0x6e, ++ 0xb8, 0xde, 0xfd, 0x05, 0xd7, 0x15, 0x9e, 0x61, 0x22, 0xfb, 0x01, 0x6b, ++ 0x4a, 0x3e, 0x67, 0xc1, 0x9d, 0xf2, 0xa0, 0x7f, 0x2c, 0x8a, 0x7d, 0x73, ++ 0x61, 0xcc, 0xe5, 0xb4, 0xde, 0x4b, 0xec, 0x1f, 0x76, 0x35, 0xeb, 0x78, ++ 0x60, 0x2e, 0x82, 0xd9, 0x1c, 0x2c, 0x7f, 0x4a, 0x9f, 0xf7, 0xab, 0x04, ++ 0xf6, 0xce, 0xd5, 0xe1, 0x5c, 0x4e, 0xbf, 0x38, 0xac, 0xe2, 0x83, 0xb5, ++ 0xc4, 0x1d, 0x0f, 0xce, 0x35, 0x61, 0xff, 0x9c, 0x8f, 0xef, 0x58, 0xd8, ++ 0x92, 0xac, 0xe3, 0xf3, 0x2e, 0x3c, 0x7d, 0xd2, 0xb2, 0x04, 0x77, 0xf5, ++ 0xcf, 0x01, 0xb3, 0xe3, 0xac, 0x45, 0x67, 0x58, 0x97, 0x9e, 0x00, 0xf6, ++ 0x3e, 0xe1, 0xc2, 0xf4, 0xb8, 0x85, 0x5d, 0xc6, 0x70, 0xad, 0x8b, 0x0e, ++ 0xdf, 0xcb, 0xba, 0xe1, 0x65, 0x0d, 0xbc, 0x27, 0xe4, 0xe4, 0xf3, 0x4b, ++ 0xcc, 0x53, 0xf7, 0x3d, 0x91, 0xc0, 0x9b, 0xb9, 0x2c, 0xb6, 0x10, 0x9f, ++ 0x0f, 0x92, 0x97, 0x37, 0x72, 0xac, 0x63, 0x73, 0x06, 0x5e, 0xcf, 0xf9, ++ 0xb8, 0x4e, 0x13, 0x5e, 0xca, 0xc9, 0x33, 0xf2, 0x6c, 0x00, 0x7d, 0xe4, ++ 0xe5, 0xb5, 0x5c, 0x84, 0x6b, 0x86, 0xf1, 0x53, 0x3e, 0x77, 0xef, 0x9c, ++ 0xce, 0xba, 0xe5, 0xe3, 0xba, 0x51, 0xbc, 0x92, 0x0b, 0x90, 0xd7, 0x30, ++ 0x6b, 0x55, 0x1f, 0x46, 0x72, 0x8d, 0x17, 0x37, 0x30, 0x51, 0x3b, 0xb5, ++ 0x46, 0xae, 0xbd, 0x63, 0x75, 0xd9, 0xb1, 0x28, 0xeb, 0x94, 0xd6, 0xed, ++ 0xc3, 0x70, 0xee, 0x75, 0x77, 0xa9, 0x9f, 0x7e, 0x66, 0x7c, 0xc1, 0xc6, ++ 0x7e, 0x4f, 0x9b, 0xfc, 0x7d, 0x1a, 0x38, 0x67, 0x66, 0xad, 0xea, 0x14, ++ 0xb1, 0x2e, 0x6b, 0xd4, 0x5b, 0x6b, 0x9a, 0xb8, 0xae, 0xde, 0xfb, 0xa2, ++ 0x92, 0x7e, 0xc7, 0x83, 0xe8, 0x13, 0xa2, 0x2f, 0x62, 0xe6, 0x59, 0xe0, ++ 0x47, 0xc4, 0x9f, 0x0d, 0x63, 0x9a, 0xf8, 0x7d, 0x86, 0xb8, 0xa6, 0x7b, ++ 0x1e, 0xf5, 0x89, 0x07, 0x30, 0x64, 0x95, 0x11, 0x9f, 0x57, 0x13, 0xd7, ++ 0xce, 0x35, 0xb1, 0x4e, 0xad, 0xb1, 0xac, 0xbf, 0x6d, 0x86, 0xe5, 0x4a, ++ 0xe9, 0x46, 0xad, 0x7b, 0xfe, 0x2b, 0x55, 0xd0, 0x2f, 0x06, 0x95, 0x3e, ++ 0xff, 0x16, 0xe2, 0x03, 0xe7, 0x21, 0x7a, 0x05, 0x56, 0xcc, 0x79, 0xb0, ++ 0x92, 0xf2, 0x6c, 0x1c, 0xe3, 0xda, 0xc4, 0x27, 0x71, 0xca, 0xb4, 0x6d, ++ 0x8c, 0x98, 0x4b, 0x0f, 0x60, 0x39, 0x75, 0xdc, 0x7f, 0xca, 0xb2, 0xca, ++ 0xa9, 0xe3, 0x06, 0xda, 0x67, 0xcf, 0x09, 0x0b, 0x2f, 0x1a, 0x2f, 0x52, ++ 0xa7, 0x8a, 0xb8, 0xb1, 0x99, 0xef, 0x84, 0xf9, 0xbc, 0x0f, 0x7b, 0xc7, ++ 0xa4, 0x5f, 0xaa, 0xe3, 0x33, 0xaf, 0xe2, 0x58, 0x2e, 0x81, 0x26, 0xea, ++ 0x2f, 0x4a, 0x9a, 0x8d, 0x7c, 0x27, 0x4a, 0x7a, 0xd1, 0xb9, 0xaf, 0x61, ++ 0xf3, 0x29, 0x05, 0x3d, 0x2e, 0x3a, 0xf8, 0x1a, 0xda, 0xcf, 0x7c, 0x51, ++ 0x4e, 0x60, 0x96, 0x1a, 0xd7, 0x8e, 0xcc, 0x13, 0x7f, 0x57, 0xa5, 0x86, ++ 0xc0, 0xfa, 0x8d, 0x37, 0xa6, 0x14, 0x8e, 0x8f, 0xb3, 0xdf, 0x5b, 0x03, ++ 0xab, 0x82, 0x32, 0xbd, 0x3e, 0xf5, 0x3b, 0x78, 0xea, 0x24, 0xf5, 0xf0, ++ 0x64, 0x18, 0x3f, 0xc8, 0x79, 0xb0, 0xec, 0xb8, 0x60, 0x3a, 0x3d, 0xb1, ++ 0x4f, 0x49, 0x7f, 0x24, 0x7d, 0x4b, 0x3c, 0xea, 0x55, 0x2e, 0xd4, 0x3f, ++ 0xe5, 0x81, 0x7e, 0x2e, 0x0a, 0x6f, 0xbd, 0x0f, 0x7a, 0xfd, 0x1f, 0x32, ++ 0xd7, 0xb8, 0x50, 0xc6, 0x5e, 0x76, 0xd3, 0x77, 0x13, 0xbc, 0x16, 0xe6, ++ 0x35, 0xfc, 0x4e, 0x39, 0xdc, 0x4b, 0xdc, 0xac, 0xe1, 0x65, 0x3a, 0xf1, ++ 0x98, 0xc7, 0xb2, 0xdc, 0xac, 0x0d, 0x3b, 0xbe, 0x67, 0x59, 0xb1, 0xd5, ++ 0xf2, 0x7c, 0x08, 0xb1, 0x73, 0x3a, 0x9f, 0x73, 0xea, 0xe5, 0x75, 0x3c, ++ 0xe6, 0xa6, 0x1f, 0x49, 0xac, 0xb2, 0xde, 0xdb, 0x3d, 0x94, 0x83, 0xdb, ++ 0x9f, 0x2b, 0x08, 0xb6, 0x89, 0xda, 0x32, 0x9c, 0x1d, 0x57, 0xcc, 0xd9, ++ 0x29, 0x3e, 0xbb, 0x1e, 0xee, 0xa4, 0x76, 0x24, 0x4b, 0x3f, 0xd8, 0x15, ++ 0x6a, 0xc1, 0x33, 0xa6, 0x17, 0x95, 0xfa, 0x12, 0xdc, 0xdf, 0x1d, 0xc2, ++ 0x33, 0xec, 0x0b, 0x68, 0xb3, 0xc4, 0x3c, 0xd8, 0x48, 0x07, 0x49, 0xcf, ++ 0xf5, 0x63, 0xe8, 0xdf, 0x75, 0x31, 0xcf, 0xb9, 0xed, 0x3c, 0x57, 0x56, ++ 0x0f, 0xcc, 0xe7, 0x3d, 0xb8, 0xa0, 0x3b, 0x98, 0xf0, 0x39, 0xbb, 0x66, ++ 0x6b, 0xa1, 0xf9, 0x6b, 0x58, 0x50, 0x6b, 0x49, 0x2b, 0x32, 0x13, 0x14, ++ 0xdd, 0x65, 0x3c, 0x8e, 0x2f, 0xfd, 0x8d, 0x5b, 0x7a, 0x8e, 0xeb, 0x7f, ++ 0x57, 0xc0, 0x95, 0xd2, 0x22, 0x6d, 0x6e, 0xf8, 0x3c, 0xa9, 0xce, 0xd6, ++ 0x51, 0xfd, 0x4b, 0x37, 0xf0, 0xde, 0x84, 0x91, 0xc2, 0xf5, 0x5e, 0xbb, ++ 0x33, 0x67, 0xfb, 0x50, 0xa7, 0xe8, 0xfe, 0x31, 0x43, 0xf2, 0xec, 0xa0, ++ 0x6a, 0x67, 0xde, 0xca, 0x7a, 0x90, 0xad, 0xe2, 0x33, 0xd4, 0x3f, 0x0e, ++ 0x8f, 0x09, 0x9d, 0x83, 0x18, 0xcd, 0xc9, 0x6c, 0x63, 0x00, 0xeb, 0xcc, ++ 0x58, 0xe2, 0x22, 0x7b, 0xe8, 0x43, 0x90, 0x39, 0x44, 0xe3, 0xfc, 0xcb, ++ 0x4a, 0x1b, 0xbc, 0xc5, 0xad, 0xf5, 0x2f, 0x28, 0x27, 0x6f, 0xad, 0x28, ++ 0xe6, 0xad, 0xe5, 0xf9, 0x25, 0xc1, 0x2e, 0xd6, 0x83, 0xae, 0xd9, 0x52, ++ 0x7d, 0xe8, 0x52, 0x9b, 0xec, 0xda, 0x9a, 0x51, 0x5b, 0x67, 0x7d, 0xaa, ++ 0x63, 0xc2, 0x87, 0x97, 0x89, 0xc5, 0xa6, 0x7a, 0x10, 0x5a, 0xb6, 0x06, ++ 0xfe, 0xad, 0x13, 0xdd, 0x28, 0xd7, 0xa5, 0x87, 0x2c, 0xc7, 0x26, 0xbb, ++ 0xae, 0xd5, 0x05, 0xbb, 0x58, 0x7f, 0xba, 0x0a, 0x3d, 0xcc, 0x7f, 0x08, ++ 0xf9, 0x53, 0xce, 0xcc, 0x40, 0x72, 0xe1, 0xed, 0x7c, 0xf7, 0x62, 0x72, ++ 0x11, 0xe0, 0xd4, 0x3f, 0x95, 0x61, 0x2f, 0x51, 0xbd, 0x5a, 0xe1, 0xd2, ++ 0x9d, 0x3e, 0x90, 0x16, 0x7b, 0xfe, 0x7c, 0xeb, 0x85, 0xf1, 0x6e, 0xd5, ++ 0x31, 0x3d, 0xe3, 0xdf, 0x68, 0xca, 0x2c, 0x62, 0xca, 0xdf, 0x4e, 0x1e, ++ 0xda, 0x67, 0x9f, 0xf4, 0x6f, 0x20, 0x4f, 0x1b, 0x66, 0x3f, 0x4f, 0x53, ++ 0xea, 0x4a, 0x7f, 0x6b, 0x1b, 0x63, 0x7b, 0x87, 0xf1, 0x91, 0x15, 0xfd, ++ 0xa6, 0xd0, 0x99, 0x2b, 0xea, 0x33, 0x4d, 0xbe, 0xc2, 0xbe, 0x4d, 0x85, ++ 0x90, 0x2f, 0x5d, 0x68, 0xf7, 0xb7, 0x99, 0xdd, 0xfe, 0x0d, 0x66, 0x8f, ++ 0xbf, 0xdd, 0xdc, 0x49, 0xda, 0x5d, 0xfe, 0x0e, 0x93, 0x71, 0x5d, 0xe8, ++ 0xa1, 0x5e, 0xbb, 0x31, 0x5a, 0xd8, 0x49, 0xec, 0x21, 0x34, 0x7b, 0x89, ++ 0x83, 0xfc, 0x94, 0x71, 0x88, 0x32, 0xce, 0x47, 0xbc, 0x48, 0x6b, 0x5e, ++ 0xea, 0x6b, 0xc4, 0xb6, 0xe3, 0x11, 0x7b, 0x16, 0x55, 0x91, 0x7a, 0xa0, ++ 0x75, 0xcb, 0x09, 0xe6, 0xfb, 0xd4, 0x9e, 0xd6, 0x65, 0xa7, 0x50, 0xe3, ++ 0x4d, 0x49, 0xef, 0xcc, 0x7e, 0x38, 0x1e, 0x37, 0xde, 0x43, 0x3c, 0xf2, ++ 0x32, 0x9f, 0x1d, 0xa6, 0xef, 0x8e, 0xd8, 0xf3, 0x07, 0x1a, 0x24, 0xdf, ++ 0x84, 0x2d, 0xa6, 0xcf, 0xbf, 0x8d, 0xbd, 0x59, 0x30, 0xa5, 0xb5, 0xdc, ++ 0xee, 0x96, 0x79, 0xc8, 0xfc, 0xef, 0x05, 0xd0, 0x84, 0xce, 0x82, 0x8f, ++ 0x72, 0x7d, 0x09, 0x7f, 0x7f, 0x92, 0x75, 0x0d, 0xe2, 0x87, 0x96, 0x75, ++ 0x2f, 0xfb, 0x9a, 0xa3, 0xf9, 0x3a, 0x5c, 0xb6, 0x6d, 0xec, 0xc1, 0xe1, ++ 0x7c, 0x14, 0xef, 0x50, 0x3e, 0xcf, 0x5c, 0x2d, 0xde, 0x1e, 0x77, 0x63, ++ 0xb7, 0x71, 0x5b, 0xb1, 0x5e, 0xb8, 0x70, 0x4f, 0xe2, 0x00, 0xb1, 0x83, ++ 0x0b, 0xd5, 0xc4, 0x6f, 0x0f, 0xda, 0xd7, 0xdc, 0xec, 0xff, 0xbe, 0x8e, ++ 0x41, 0xa7, 0x9e, 0x90, 0xc7, 0x9d, 0xe4, 0xb1, 0xd9, 0xbf, 0x61, 0x42, ++ 0xf3, 0xdf, 0x31, 0x01, 0x9f, 0x37, 0xb5, 0xab, 0xf5, 0xcc, 0x49, 0x0b, ++ 0x7d, 0xc6, 0xad, 0xb8, 0x72, 0x72, 0xb8, 0xdf, 0x43, 0xff, 0xf9, 0x65, ++ 0x32, 0x03, 0x73, 0x12, 0x17, 0x88, 0x3c, 0x5e, 0x0d, 0x30, 0xb7, 0x37, ++ 0x24, 0xe3, 0x21, 0xd6, 0x62, 0x63, 0x96, 0xb1, 0xd9, 0x01, 0xad, 0x9f, ++ 0x35, 0x39, 0xed, 0x4e, 0xc5, 0x7b, 0x47, 0x08, 0x1e, 0xab, 0xc8, 0x8f, ++ 0x9f, 0xb9, 0x3b, 0x30, 0x17, 0xf5, 0xef, 0x60, 0xbd, 0x89, 0xb0, 0xbf, ++ 0xf3, 0xc7, 0x71, 0x5b, 0x2d, 0xe2, 0x89, 0x05, 0xca, 0xed, 0x9d, 0x6b, ++ 0xf2, 0xdf, 0xce, 0xfa, 0x71, 0x39, 0x6e, 0x0d, 0xbd, 0x68, 0x04, 0x10, ++ 0x9c, 0x33, 0xa8, 0xef, 0x0c, 0x86, 0x67, 0xd9, 0x72, 0xc5, 0xd9, 0xf3, ++ 0xcf, 0xb5, 0xf8, 0xb7, 0x31, 0x36, 0xab, 0x68, 0xa2, 0xc6, 0xb9, 0xb4, ++ 0x5f, 0x7a, 0xbe, 0xa6, 0xb9, 0xb5, 0xe4, 0x4f, 0x7c, 0x74, 0x5f, 0xeb, ++ 0x3a, 0xfa, 0x43, 0x74, 0x0e, 0x9b, 0x98, 0xe6, 0x5e, 0x22, 0xcd, 0x4c, ++ 0x84, 0x18, 0x76, 0xef, 0x9a, 0x00, 0xf3, 0x94, 0xe8, 0x92, 0x7a, 0x2c, ++ 0x94, 0x64, 0x92, 0xba, 0xbc, 0xa7, 0x75, 0xee, 0x94, 0xd4, 0xe5, 0x4c, ++ 0x6b, 0xee, 0x94, 0x8e, 0x77, 0x58, 0x5b, 0x56, 0x24, 0x35, 0xe3, 0x9c, ++ 0x8a, 0x45, 0x5e, 0xa5, 0x2c, 0x1e, 0xfc, 0xca, 0xda, 0xa5, 0xc7, 0xe7, ++ 0x6f, 0x61, 0x3c, 0x55, 0x33, 0x37, 0x46, 0x98, 0xf3, 0xab, 0xe7, 0xa8, ++ 0x98, 0x39, 0xb7, 0x17, 0x15, 0x11, 0xf8, 0xe2, 0x3a, 0xde, 0x3d, 0x99, ++ 0xa0, 0x1e, 0xae, 0xd1, 0xdc, 0x47, 0xa8, 0xd5, 0xc7, 0x52, 0xf8, 0xc8, ++ 0x53, 0xf4, 0xc5, 0x51, 0xae, 0x5b, 0x36, 0x27, 0x3c, 0xcb, 0xf3, 0x61, ++ 0x3e, 0x7f, 0x7d, 0xed, 0x6a, 0xae, 0xfd, 0xd1, 0x29, 0xf1, 0xd7, 0x4c, ++ 0xeb, 0x85, 0x93, 0xce, 0xda, 0xf1, 0x64, 0x02, 0x1f, 0x9e, 0xd4, 0x06, ++ 0xde, 0x55, 0xb1, 0xde, 0x0b, 0x4a, 0xd6, 0x47, 0x5d, 0x15, 0xae, 0x58, ++ 0xc3, 0xf1, 0xf8, 0xe0, 0x2e, 0xd2, 0x6c, 0x59, 0x4b, 0xfd, 0xdb, 0x7c, ++ 0xd0, 0xe7, 0x99, 0x67, 0xbd, 0xe4, 0xc7, 0xe1, 0xa5, 0x8e, 0xb4, 0x4f, ++ 0x16, 0x7b, 0x35, 0xf6, 0xa9, 0xd7, 0xf9, 0x09, 0x53, 0x0f, 0xbe, 0x1d, ++ 0xcd, 0x01, 0xd4, 0xda, 0xcf, 0x85, 0xf8, 0x9c, 0xe8, 0xe1, 0xd7, 0xca, ++ 0xa5, 0xbf, 0xc7, 0x3c, 0x26, 0xb9, 0x24, 0xcc, 0x1c, 0xb6, 0x53, 0x7a, ++ 0xda, 0x6c, 0x96, 0xfe, 0xee, 0xa5, 0xbf, 0x6f, 0x14, 0x9f, 0x36, 0xe9, ++ 0xd3, 0x26, 0x7d, 0xda, 0xd4, 0x22, 0x03, 0x88, 0x85, 0xfa, 0x68, 0xb7, ++ 0x74, 0x44, 0x7c, 0xbd, 0x07, 0xbb, 0xf9, 0xd9, 0xc3, 0xfb, 0x87, 0xd9, ++ 0xe7, 0x62, 0x91, 0xac, 0x79, 0x10, 0xed, 0xe6, 0x23, 0xe8, 0x9f, 0xc0, ++ 0x6f, 0xfc, 0xcd, 0xe5, 0x28, 0x5f, 0x2e, 0x3d, 0xbc, 0x16, 0x3a, 0x8a, ++ 0x47, 0xd8, 0x47, 0xfd, 0x5a, 0x55, 0xea, 0x9e, 0xee, 0x63, 0x4a, 0x0b, ++ 0xb5, 0xb3, 0x1f, 0xde, 0x55, 0xd8, 0x49, 0xfb, 0xc6, 0xfa, 0x5f, 0x56, ++ 0xec, 0xa5, 0x6a, 0xb9, 0x36, 0x63, 0xe9, 0x0e, 0xae, 0x63, 0x0a, 0x1f, ++ 0x76, 0xbe, 0xfd, 0x7d, 0x88, 0x6e, 0x7f, 0xd2, 0xd0, 0xc7, 0xf5, 0x1d, ++ 0x3e, 0x86, 0xd9, 0x53, 0xf6, 0x31, 0xc6, 0x76, 0xdb, 0xf1, 0xd5, 0x43, ++ 0x1a, 0xd7, 0xf3, 0xd8, 0x86, 0x9c, 0xd4, 0x52, 0x0b, 0x8f, 0x1a, 0x16, ++ 0x9e, 0xe6, 0xe7, 0x22, 0x73, 0xd9, 0xc8, 0x0d, 0xb9, 0xcc, 0xc5, 0xe7, ++ 0x76, 0xf0, 0xb9, 0x16, 0xa6, 0xce, 0xd9, 0x69, 0x99, 0x0d, 0x1e, 0x94, ++ 0xd9, 0x20, 0xf2, 0xa6, 0xe8, 0x7e, 0x00, 0x17, 0x72, 0xb1, 0x41, 0xb7, ++ 0xdb, 0x1a, 0x62, 0x5c, 0x5d, 0xfc, 0x88, 0xbe, 0xfb, 0xda, 0x1a, 0xad, ++ 0x9b, 0x3a, 0x4c, 0x8c, 0x29, 0x2d, 0xf2, 0x33, 0xcc, 0x6f, 0xf2, 0xa1, ++ 0x31, 0xba, 0xd2, 0x1d, 0x0f, 0x9d, 0x85, 0x36, 0xdf, 0x47, 0x49, 0x9f, ++ 0x2c, 0x38, 0xb9, 0x6e, 0x5d, 0x31, 0xd7, 0xb5, 0xe4, 0x2b, 0xd4, 0x1d, ++ 0x13, 0xac, 0xcf, 0xd3, 0x56, 0x36, 0xc8, 0x7a, 0x55, 0x98, 0x16, 0xda, ++ 0x43, 0x68, 0x4c, 0x0a, 0x2d, 0xbd, 0x73, 0x4c, 0xe1, 0x1b, 0x95, 0x88, ++ 0xb3, 0x56, 0xc1, 0x28, 0xd7, 0xb3, 0x16, 0x6b, 0x52, 0xc8, 0x9b, 0x92, ++ 0xda, 0xd9, 0xc5, 0xbe, 0xa5, 0x87, 0x79, 0x51, 0x30, 0xb5, 0xcc, 0x4b, ++ 0x9d, 0x7c, 0xb4, 0xb1, 0x20, 0x76, 0x11, 0x9b, 0x88, 0x6d, 0x0e, 0xe2, ++ 0x1e, 0x53, 0x7a, 0x7f, 0x0b, 0xe3, 0x46, 0x3c, 0xfa, 0x14, 0xc4, 0x4e, ++ 0x07, 0xa9, 0x0b, 0x2f, 0x76, 0x33, 0x0f, 0xee, 0x6a, 0xa6, 0xae, 0x82, ++ 0x5e, 0xec, 0xb2, 0x67, 0x09, 0x25, 0xfd, 0x79, 0x69, 0x43, 0xc5, 0x1a, ++ 0x37, 0xeb, 0x75, 0xf4, 0xe8, 0xcc, 0x26, 0xdd, 0x29, 0xa1, 0x57, 0x9a, ++ 0x4b, 0x3a, 0xba, 0xdb, 0x94, 0x13, 0xba, 0x16, 0xce, 0x1a, 0x0e, 0x6e, ++ 0x2d, 0xe9, 0x2c, 0x42, 0xb9, 0x6a, 0xd6, 0x02, 0x2b, 0x6f, 0xc0, 0xae, ++ 0x15, 0xbc, 0xb6, 0xe5, 0x3a, 0x76, 0xcd, 0x08, 0x3e, 0x26, 0x76, 0xed, ++ 0xdc, 0x4a, 0xec, 0x5a, 0xaf, 0x4a, 0xb8, 0x55, 0xe6, 0x12, 0x25, 0xec, ++ 0x5a, 0x5d, 0xcc, 0xd1, 0x07, 0xb1, 0x8b, 0xb8, 0xa6, 0xb6, 0x7e, 0x08, ++ 0xbe, 0x55, 0xae, 0xcf, 0x5c, 0x18, 0x62, 0xbf, 0x52, 0x06, 0x2c, 0xb6, ++ 0x70, 0xcb, 0xea, 0xac, 0x55, 0xae, 0xd7, 0x47, 0xcb, 0x5d, 0x32, 0x77, ++ 0x8e, 0x67, 0x47, 0x98, 0x4b, 0x5c, 0xab, 0xb4, 0x6c, 0x1a, 0xbe, 0x50, ++ 0x8d, 0xbe, 0xb3, 0xd8, 0x2f, 0x44, 0x7c, 0x9b, 0x89, 0x7b, 0xe2, 0xc9, ++ 0x4f, 0xad, 0xa9, 0xb0, 0xd0, 0x98, 0x9f, 0xf7, 0x21, 0xfd, 0x90, 0x8f, ++ 0x75, 0x68, 0x41, 0x1d, 0xc1, 0x6b, 0xf1, 0x88, 0x6f, 0x5b, 0x21, 0xeb, ++ 0xdf, 0xd2, 0x70, 0x0b, 0xba, 0x4e, 0x49, 0xcd, 0x89, 0x62, 0xeb, 0xa9, ++ 0x76, 0xd6, 0x19, 0x1d, 0x1d, 0x63, 0x9d, 0xec, 0xe3, 0xba, 0x55, 0xf7, ++ 0xb4, 0xe8, 0x49, 0xf4, 0xac, 0x85, 0xa2, 0xae, 0x1b, 0xe7, 0xa2, 0xa5, ++ 0x9e, 0xf8, 0x3d, 0xdb, 0x87, 0x46, 0x8d, 0x10, 0xf5, 0xf3, 0x2b, 0x2f, ++ 0x82, 0x16, 0xce, 0x18, 0xe2, 0x7b, 0xfc, 0xdb, 0x4c, 0x63, 0x63, 0xf3, ++ 0xb8, 0xe5, 0xd1, 0x65, 0xbe, 0x1d, 0xb1, 0xed, 0xb6, 0x81, 0xb5, 0xac, ++ 0x7d, 0xba, 0x87, 0xb6, 0x2a, 0xcd, 0xb2, 0x6f, 0xb4, 0xd9, 0x7a, 0xff, ++ 0x46, 0xe6, 0x35, 0xf6, 0xe9, 0x3e, 0x1f, 0x73, 0xa5, 0xef, 0x94, 0x85, ++ 0x69, 0xe3, 0x4d, 0xeb, 0x51, 0xdd, 0x43, 0xbb, 0x7c, 0x95, 0x79, 0x57, ++ 0x70, 0x49, 0xca, 0x7f, 0xfb, 0xa4, 0xc7, 0x55, 0x95, 0x42, 0x73, 0x19, ++ 0x7d, 0xee, 0xd5, 0xa4, 0x33, 0x73, 0x3c, 0x96, 0xbf, 0xcd, 0xbf, 0x65, ++ 0x82, 0xbd, 0x04, 0x7b, 0x5d, 0xa7, 0xbf, 0xfb, 0xaa, 0xff, 0xee, 0x09, ++ 0xb7, 0xaa, 0x4d, 0xc1, 0xdd, 0xb2, 0xd6, 0xc2, 0xc7, 0xab, 0xe3, 0x83, ++ 0x11, 0x17, 0x73, 0x24, 0x69, 0x99, 0xf9, 0x66, 0x7f, 0x86, 0x39, 0x79, ++ 0xdb, 0x04, 0xd2, 0x32, 0x9f, 0x0d, 0xae, 0x1e, 0xee, 0x0d, 0x42, 0x66, ++ 0x69, 0xf8, 0x06, 0xa3, 0x32, 0x4c, 0x9f, 0x8b, 0xb4, 0xa9, 0xf8, 0x42, ++ 0x3f, 0xe2, 0x17, 0x3f, 0x76, 0xbf, 0x69, 0x3d, 0x9e, 0x5f, 0xcb, 0xe7, ++ 0x3b, 0x99, 0x2f, 0xd3, 0xcc, 0x9f, 0xc3, 0x83, 0x5e, 0xc8, 0x3b, 0x5a, ++ 0xe6, 0x0d, 0x15, 0xa3, 0xaf, 0xe3, 0x9b, 0x7c, 0x3e, 0xd4, 0xc1, 0x5c, ++ 0x39, 0x6d, 0xc4, 0xd3, 0x1b, 0x90, 0xed, 0xac, 0x86, 0x66, 0x34, 0x28, ++ 0x99, 0x7d, 0x89, 0x1d, 0x12, 0xf8, 0x39, 0xd7, 0xf4, 0xe8, 0xa2, 0xc7, ++ 0xf5, 0xe8, 0x9b, 0x66, 0xfd, 0xbf, 0xe6, 0x6f, 0xa2, 0x03, 0xd1, 0xcb, ++ 0x37, 0xcb, 0x50, 0xb1, 0x88, 0xb2, 0xfd, 0xdc, 0xce, 0x2b, 0x7e, 0x5d, ++ 0xc7, 0x7f, 0x26, 0x3e, 0xfa, 0x4f, 0x05, 0x99, 0x71, 0x96, 0x30, 0x9f, ++ 0xdd, 0x47, 0xb5, 0x2e, 0x9b, 0x4a, 0x14, 0x67, 0x9e, 0x3e, 0x7f, 0xe7, ++ 0xa4, 0x85, 0x93, 0x46, 0x10, 0xd2, 0xe3, 0x97, 0x27, 0xe7, 0x89, 0x00, ++ 0x9a, 0xd0, 0xc1, 0xeb, 0xed, 0x93, 0x95, 0xaa, 0x7d, 0xc2, 0xc2, 0x5f, ++ 0x18, 0x5a, 0xb6, 0xcd, 0xcd, 0x98, 0x36, 0xb4, 0xb3, 0xc0, 0x3b, 0xc4, ++ 0x4a, 0xe2, 0x63, 0x1e, 0x04, 0x74, 0x87, 0x56, 0xd3, 0xd4, 0x6d, 0xc4, ++ 0x0f, 0x12, 0x63, 0xee, 0x15, 0x15, 0x48, 0xaa, 0x29, 0x8f, 0xe8, 0xad, ++ 0x13, 0xe9, 0x42, 0xa5, 0xda, 0x4e, 0x5d, 0xde, 0xb1, 0xaa, 0x0c, 0x97, ++ 0x6c, 0x5d, 0xde, 0x46, 0x5d, 0xe2, 0xf5, 0xa5, 0x70, 0x5f, 0xa8, 0x45, ++ 0xa7, 0x82, 0xdd, 0x9f, 0x55, 0xb2, 0x4e, 0xa7, 0x89, 0x6f, 0x89, 0x07, ++ 0x43, 0x3d, 0xf8, 0x2e, 0xf3, 0xcd, 0xa3, 0xf4, 0xd5, 0x5f, 0xe9, 0x4d, ++ 0xa8, 0xf8, 0x5e, 0x33, 0xed, 0xb8, 0xd6, 0xbf, 0x79, 0x22, 0x83, 0xc7, ++ 0x66, 0x2d, 0x3c, 0xc5, 0x38, 0x69, 0x48, 0x66, 0x43, 0xe5, 0xec, 0xd7, ++ 0x58, 0xd3, 0x16, 0x4e, 0xd8, 0x7e, 0xbe, 0xab, 0x75, 0xfd, 0x4c, 0x04, ++ 0xee, 0xef, 0xca, 0xef, 0x3b, 0x5b, 0xa3, 0x33, 0xf2, 0x9d, 0xe1, 0xb7, ++ 0x85, 0x01, 0x43, 0x4b, 0x7f, 0xec, 0xae, 0x40, 0x65, 0xdc, 0xb2, 0x06, ++ 0x92, 0x72, 0xbd, 0xaf, 0x35, 0x61, 0xdf, 0xdf, 0xc3, 0xef, 0xd2, 0x4c, ++ 0xfa, 0x6f, 0x04, 0x0b, 0x46, 0xd3, 0x94, 0x79, 0x2b, 0xeb, 0x7b, 0x86, ++ 0xf5, 0xbd, 0x36, 0xa5, 0xa5, 0x77, 0xb8, 0x65, 0xfe, 0x32, 0x7f, 0xa0, ++ 0x9a, 0xd7, 0x6f, 0x2f, 0xd6, 0xf7, 0xaa, 0x53, 0x32, 0xd3, 0x23, 0x06, ++ 0x84, 0xb3, 0x17, 0xd2, 0xc5, 0xfa, 0x5e, 0x31, 0xe6, 0xc1, 0x16, 0xd6, ++ 0x76, 0x2f, 0xb1, 0xf8, 0xc6, 0x7c, 0x2d, 0xfc, 0x27, 0xdc, 0x88, 0x25, ++ 0x7f, 0x82, 0x03, 0xf4, 0xb1, 0x03, 0x09, 0xb7, 0x8a, 0x2e, 0x71, 0x51, ++ 0x4f, 0xff, 0x88, 0x7d, 0x21, 0x37, 0xaa, 0xf4, 0x9f, 0xe1, 0x81, 0x2f, ++ 0xa8, 0xe9, 0x99, 0x09, 0x89, 0xed, 0x5d, 0xad, 0x5b, 0x4e, 0x39, 0x35, ++ 0x3d, 0x70, 0x6a, 0x78, 0x41, 0x6a, 0x7a, 0xed, 0xea, 0x0c, 0x4e, 0x4f, ++ 0xe2, 0x3b, 0x4b, 0x09, 0x1e, 0x6b, 0xb9, 0x66, 0x7d, 0x32, 0xce, 0xde, ++ 0x5a, 0xeb, 0xef, 0x50, 0xf1, 0x23, 0x55, 0xcc, 0x01, 0xa7, 0x59, 0xd3, ++ 0x7d, 0xa9, 0x78, 0x28, 0xe1, 0x42, 0x97, 0x97, 0xf6, 0x78, 0x9f, 0x7d, ++ 0xf6, 0x5b, 0xf9, 0x28, 0x69, 0x96, 0xc1, 0xc3, 0x9a, 0xfe, 0xbe, 0x8e, ++ 0xcf, 0xdc, 0xf4, 0xbd, 0x77, 0xdc, 0x3e, 0x5c, 0xcd, 0x3b, 0x35, 0xbd, ++ 0xba, 0xc1, 0x1a, 0xba, 0x9c, 0x0c, 0xe0, 0x4a, 0xde, 0xa0, 0x0f, 0x66, ++ 0x70, 0x98, 0x35, 0xfd, 0xb2, 0x1e, 0xc2, 0x87, 0xf9, 0x16, 0xfa, 0x65, ++ 0x18, 0xbf, 0x24, 0xfe, 0x5d, 0xc5, 0x9a, 0x7e, 0x27, 0x7d, 0x2a, 0xc9, ++ 0x9a, 0xde, 0x66, 0xe3, 0x8d, 0x7d, 0xad, 0x67, 0xc6, 0xed, 0x9a, 0xde, ++ 0xe0, 0x62, 0x3d, 0xf4, 0x22, 0xbe, 0xc0, 0x3c, 0x61, 0xfd, 0x6a, 0x6d, ++ 0x80, 0xcf, 0x52, 0x6f, 0x85, 0xd5, 0x98, 0xb2, 0x6b, 0xd0, 0x7a, 0xff, ++ 0x76, 0xae, 0xbd, 0xd8, 0x8e, 0x33, 0x0b, 0x5b, 0x57, 0xbd, 0x86, 0x3f, ++ 0xaa, 0x71, 0xd1, 0x0f, 0x53, 0xfe, 0x3b, 0x18, 0x6b, 0xc1, 0x54, 0x69, ++ 0xe6, 0x91, 0xe0, 0x3a, 0xb7, 0xf9, 0xef, 0xa4, 0x6f, 0xdc, 0xb2, 0x8a, ++ 0x99, 0x24, 0xe4, 0xc4, 0x59, 0x3b, 0xe3, 0x2c, 0xc2, 0x38, 0x5b, 0xca, ++ 0x38, 0x7b, 0xdc, 0x88, 0x27, 0xd6, 0x13, 0x77, 0xbd, 0x9c, 0x97, 0x58, ++ 0x6b, 0x26, 0x5d, 0x8d, 0x72, 0x0d, 0xf7, 0x4a, 0xcc, 0x6c, 0x5d, 0x35, ++ 0x7c, 0xb6, 0x12, 0xa2, 0x2b, 0x7c, 0xb6, 0x98, 0x18, 0x83, 0x99, 0xe9, ++ 0xe2, 0x82, 0x3b, 0x3e, 0x78, 0xab, 0x3b, 0x3e, 0xf0, 0x9e, 0x7a, 0xd3, ++ 0x7a, 0x9d, 0x71, 0xb6, 0x8d, 0x71, 0xb6, 0x9d, 0x71, 0xd6, 0x66, 0x5a, ++ 0x78, 0x2e, 0xa9, 0x65, 0x9a, 0x5c, 0x31, 0xa3, 0xcd, 0x85, 0xa5, 0x95, ++ 0x2c, 0x0d, 0x7e, 0xc4, 0x3b, 0xff, 0x88, 0xfc, 0x5f, 0x34, 0xe2, 0xdd, ++ 0x09, 0x25, 0xb1, 0x15, 0xc5, 0x07, 0x94, 0xbb, 0xbc, 0x18, 0x5b, 0x7b, ++ 0xa7, 0xcf, 0x17, 0x7d, 0xa3, 0x24, 0xbb, 0x1b, 0xcf, 0x1a, 0xcc, 0xa5, ++ 0x8b, 0xb4, 0x68, 0xd6, 0xd5, 0x83, 0x23, 0xd4, 0xa3, 0x3f, 0xde, 0x83, ++ 0xa3, 0xac, 0x87, 0xf7, 0xb2, 0x0e, 0xdf, 0x67, 0xc6, 0x5a, 0x36, 0xb3, ++ 0xff, 0xb9, 0x14, 0xd1, 0xa2, 0x51, 0xd5, 0x83, 0x3e, 0xfa, 0x70, 0x1f, ++ 0xeb, 0x46, 0x9b, 0xf9, 0x6b, 0xd5, 0x41, 0xac, 0xb0, 0xa7, 0x20, 0xef, ++ 0x69, 0x89, 0x5e, 0x57, 0x3f, 0x7a, 0x67, 0x25, 0xb7, 0x21, 0x74, 0x53, ++ 0xaa, 0x07, 0xc7, 0xcd, 0x32, 0xf4, 0x34, 0x77, 0xa9, 0xdb, 0x0b, 0x32, ++ 0x7f, 0x63, 0x3c, 0x9a, 0x8c, 0x57, 0x9b, 0x5f, 0x85, 0x7c, 0xbc, 0x0b, ++ 0x39, 0x89, 0x4f, 0x73, 0xbb, 0xba, 0x73, 0x5a, 0x62, 0xbc, 0x47, 0xf5, ++ 0x48, 0x0c, 0x9b, 0x83, 0xea, 0x2e, 0x89, 0x69, 0x7b, 0x66, 0x2d, 0x71, ++ 0x2f, 0x7b, 0x1a, 0xb7, 0x11, 0xc7, 0x81, 0x31, 0xe5, 0xfe, 0x5e, 0x84, ++ 0x71, 0xd7, 0x56, 0xe6, 0xa2, 0x9f, 0xc6, 0x68, 0x3b, 0x17, 0xda, 0x8d, ++ 0xdf, 0xb1, 0xb2, 0xa1, 0x5e, 0xc6, 0x54, 0x0f, 0x0e, 0x9b, 0x5f, 0xb6, ++ 0x2e, 0xdb, 0xf8, 0xa4, 0x94, 0xd7, 0xd7, 0xe3, 0x9e, 0x89, 0x25, 0xf0, ++ 0xe9, 0x52, 0xb7, 0x03, 0x48, 0xd4, 0xf8, 0x50, 0xa1, 0x4b, 0xbd, 0xd9, ++ 0xd7, 0x3a, 0x77, 0x42, 0x49, 0xff, 0x51, 0x8c, 0xef, 0xf5, 0xb8, 0x9f, ++ 0x79, 0x60, 0x77, 0xf2, 0x1e, 0xdc, 0x17, 0xaa, 0x40, 0x90, 0x7a, 0xda, ++ 0x1f, 0x0a, 0x30, 0xbf, 0xfe, 0x7e, 0x91, 0xce, 0xb3, 0x65, 0xc5, 0xbe, ++ 0xfa, 0x1a, 0xb6, 0xaa, 0x65, 0x8c, 0xad, 0x9b, 0x94, 0x39, 0x51, 0xa6, ++ 0x35, 0x32, 0xa9, 0x23, 0xc8, 0x7e, 0x76, 0x7d, 0x52, 0x1b, 0x5c, 0xef, ++ 0x8e, 0x49, 0xaf, 0x92, 0x0b, 0x12, 0xd7, 0xe5, 0xe3, 0xf1, 0xee, 0x26, ++ 0xd1, 0xb1, 0x1e, 0xc1, 0x26, 0xea, 0x69, 0x4b, 0x3e, 0xcc, 0x18, 0x5a, ++ 0x28, 0x13, 0x8c, 0x94, 0xce, 0x5f, 0xa7, 0x15, 0x21, 0xad, 0xc8, 0xa4, ++ 0xe0, 0xb5, 0x0c, 0xf1, 0x9a, 0xce, 0x38, 0xb4, 0xac, 0x75, 0xc4, 0x69, ++ 0x81, 0x53, 0x32, 0x6f, 0x8a, 0x1d, 0x21, 0xb6, 0x6d, 0x22, 0xee, 0xed, ++ 0xa1, 0x57, 0x5b, 0xb7, 0xd4, 0xc7, 0x8d, 0x36, 0x85, 0x47, 0x66, 0x9a, ++ 0xe1, 0x73, 0x93, 0xe6, 0x3b, 0xf9, 0x10, 0x2e, 0xe7, 0x23, 0x78, 0x9b, ++ 0xb4, 0x2f, 0xd9, 0xb4, 0xeb, 0xf0, 0x8b, 0x62, 0xde, 0x4a, 0x32, 0x6f, ++ 0x6d, 0x98, 0x50, 0xf4, 0xd7, 0x28, 0x86, 0x8c, 0xbf, 0xfe, 0xec, 0xd2, ++ 0xcd, 0x3e, 0xea, 0x4d, 0x64, 0xf1, 0xf0, 0x7b, 0x14, 0xfb, 0xed, 0x3c, ++ 0xfd, 0xda, 0x67, 0x53, 0x35, 0xb4, 0x15, 0x75, 0x5f, 0x5d, 0x7c, 0x6f, ++ 0xe5, 0x54, 0xa1, 0x28, 0xaf, 0x0e, 0xd7, 0xa9, 0x04, 0xca, 0x4e, 0x5d, ++ 0xe3, 0x55, 0x97, 0xf8, 0x60, 0x65, 0x7d, 0xe4, 0xfb, 0x5c, 0xff, 0x21, ++ 0x62, 0x3e, 0x8b, 0xeb, 0x5f, 0xb5, 0xd7, 0x0d, 0x73, 0x5d, 0x75, 0x0d, ++ 0x1f, 0x46, 0xae, 0xbd, 0x13, 0xa2, 0xec, 0x78, 0x38, 0x42, 0xdd, 0x5d, ++ 0x59, 0x23, 0xcf, 0x05, 0x70, 0x7b, 0x7e, 0x55, 0xb9, 0xe4, 0x71, 0x3f, ++ 0xfb, 0x01, 0xc7, 0x97, 0x88, 0xf7, 0xcc, 0xe7, 0x79, 0x4f, 0xf0, 0xd7, ++ 0x7a, 0x62, 0x8d, 0xcf, 0xeb, 0x3d, 0x4c, 0x5b, 0x94, 0xd1, 0x78, 0x72, ++ 0xef, 0x8b, 0xea, 0xe8, 0x9f, 0x61, 0x90, 0xbd, 0xd0, 0x43, 0x13, 0x59, ++ 0xec, 0x9f, 0xf8, 0x63, 0x7b, 0x8f, 0x6e, 0xe5, 0x6a, 0xec, 0xe1, 0x9a, ++ 0xfb, 0xaa, 0x19, 0x47, 0xff, 0x2d, 0x19, 0x17, 0x8c, 0xb4, 0xbd, 0x12, ++ 0x52, 0x6b, 0xe3, 0x2d, 0xb7, 0x2a, 0x0b, 0x65, 0x49, 0x0c, 0xb4, 0x37, ++ 0xc7, 0x13, 0x97, 0xf1, 0x88, 0x25, 0xf3, 0x6e, 0x77, 0xb1, 0xee, 0x12, ++ 0x97, 0xaa, 0x76, 0xd6, 0xde, 0xb6, 0x22, 0x56, 0xda, 0x50, 0x78, 0xf3, ++ 0x73, 0x33, 0x05, 0xe9, 0xc7, 0xa5, 0xde, 0xf8, 0x55, 0x1b, 0xd7, 0x39, ++ 0xcc, 0x9c, 0xfd, 0xac, 0xf1, 0x62, 0x84, 0xd5, 0x18, 0x9e, 0x55, 0x0a, ++ 0x07, 0x0c, 0x2f, 0xb2, 0x61, 0x0b, 0xdb, 0xf9, 0xbd, 0x97, 0xf8, 0xe9, ++ 0x5d, 0xa3, 0x0a, 0x53, 0xa1, 0x10, 0x31, 0x23, 0x73, 0xb0, 0xeb, 0xff, ++ 0x78, 0x65, 0x5f, 0x27, 0xea, 0x92, 0x3d, 0xf8, 0x7f, 0x6d, 0x5f, 0x66, ++ 0x15, 0xf1, 0x8b, 0xc8, 0xee, 0x57, 0xcc, 0xa1, 0x09, 0x10, 0xd3, 0xec, ++ 0x32, 0xe6, 0xa3, 0x2e, 0xa4, 0xaf, 0xba, 0xa0, 0x9d, 0x7e, 0x87, 0x7d, ++ 0xde, 0x43, 0xf5, 0xda, 0xe9, 0x56, 0xb7, 0x8e, 0xc1, 0xe3, 0x3e, 0x3c, ++ 0x78, 0xbc, 0x03, 0xd5, 0xf6, 0x7c, 0x68, 0x94, 0x3a, 0x75, 0xb1, 0xbf, ++ 0x1a, 0xfe, 0xd4, 0xc3, 0x3e, 0xeb, 0xea, 0xea, 0x87, 0xd1, 0x62, 0x5f, ++ 0x1f, 0xc1, 0x9e, 0x09, 0xbf, 0xda, 0x32, 0xe1, 0x41, 0xc7, 0x9d, 0x0f, ++ 0xc3, 0xbb, 0xaa, 0x97, 0x7c, 0xc9, 0x75, 0xf9, 0xfd, 0x2e, 0xf6, 0x67, ++ 0xc2, 0x5f, 0x19, 0xa2, 0x4b, 0xc8, 0xdb, 0x2a, 0x1d, 0x43, 0xc7, 0x3d, ++ 0x6a, 0x87, 0xf9, 0x37, 0xd6, 0x55, 0x7b, 0xcf, 0x47, 0xae, 0x55, 0xc8, ++ 0x59, 0x00, 0x3e, 0x23, 0x39, 0xa7, 0x0f, 0x13, 0x8c, 0xed, 0xbb, 0xec, ++ 0xf7, 0x8f, 0x97, 0x39, 0x32, 0xa5, 0xd9, 0xb7, 0xb6, 0xd3, 0x7e, 0xf2, ++ 0x4c, 0x6b, 0xf1, 0xda, 0x7a, 0x9f, 0x73, 0xde, 0x40, 0x7c, 0xa1, 0x0f, ++ 0xcb, 0x68, 0x84, 0xfa, 0xb8, 0x5d, 0xa7, 0x50, 0x9f, 0x67, 0x42, 0x5d, ++ 0xe2, 0xf0, 0xfb, 0x80, 0x39, 0xcf, 0x9e, 0x53, 0x67, 0xde, 0xa4, 0xee, ++ 0x16, 0xcb, 0xfb, 0x55, 0xbe, 0xdf, 0x7e, 0x5f, 0xf2, 0x2d, 0xb1, 0x66, ++ 0x50, 0x30, 0xe7, 0x17, 0xdd, 0xff, 0x5d, 0xc8, 0x3d, 0x8f, 0xfe, 0xa7, ++ 0x8c, 0xe3, 0x78, 0x77, 0xa5, 0x4b, 0xfc, 0xe7, 0x4f, 0x71, 0xdf, 0xf4, ++ 0x30, 0xef, 0x0b, 0xfd, 0x83, 0xec, 0x25, 0x3c, 0xaa, 0x93, 0xf9, 0x67, ++ 0xef, 0x71, 0xd7, 0xed, 0x65, 0xf8, 0x4b, 0xab, 0x7c, 0xf1, 0x10, 0xea, ++ 0x93, 0x23, 0x7c, 0x5e, 0xa1, 0x9d, 0xb8, 0xf1, 0x31, 0x63, 0x03, 0x3a, ++ 0x6a, 0x24, 0x07, 0x3c, 0x6b, 0xf5, 0xf5, 0x88, 0x0e, 0x15, 0x36, 0xf2, ++ 0xfa, 0x73, 0xb4, 0xef, 0x93, 0x86, 0x07, 0xf5, 0x8b, 0x64, 0xd6, 0xa7, ++ 0x8d, 0xa7, 0xf1, 0x75, 0x9f, 0xb3, 0xf7, 0x95, 0xb5, 0xaa, 0x75, 0x7d, ++ 0xe0, 0x0e, 0x57, 0xfd, 0xf8, 0x1b, 0xf4, 0xa7, 0xb6, 0x55, 0x37, 0xde, ++ 0x2b, 0xe9, 0xc4, 0x40, 0x64, 0xd5, 0x33, 0x16, 0x6e, 0x1a, 0x46, 0x68, ++ 0xd5, 0x8d, 0xf6, 0x2f, 0xf1, 0x7d, 0x90, 0x31, 0x88, 0x6c, 0x75, 0x4a, ++ 0xe6, 0x3f, 0x71, 0xd2, 0x39, 0x88, 0x3f, 0x2c, 0x8c, 0xe0, 0xc0, 0x44, ++ 0x11, 0x5b, 0xd3, 0xb7, 0xf5, 0x55, 0xd7, 0x65, 0x7b, 0x60, 0x22, 0xde, ++ 0x5b, 0x55, 0x94, 0x6d, 0x1f, 0xfb, 0x8c, 0x4a, 0xe6, 0xd8, 0xfb, 0xa9, ++ 0xd3, 0x01, 0x5b, 0xa7, 0x3d, 0x30, 0xf2, 0xd7, 0xe9, 0xf6, 0x93, 0xae, ++ 0x3f, 0x25, 0x7a, 0x93, 0xfd, 0xb6, 0x83, 0xd8, 0x4b, 0xba, 0xbb, 0x6f, ++ 0xa0, 0xdb, 0x67, 0x5c, 0xa7, 0xbb, 0x6b, 0x22, 0x7e, 0xda, 0x55, 0xa4, ++ 0xfb, 0xed, 0xe9, 0x12, 0x8d, 0x2c, 0xb6, 0xad, 0xca, 0x22, 0xbf, 0x6e, ++ 0x9f, 0xb5, 0xcf, 0xd6, 0xc7, 0x59, 0xfb, 0xfa, 0xc6, 0x7a, 0x89, 0x07, ++ 0xfe, 0x9a, 0xd2, 0xed, 0xbd, 0x7d, 0x07, 0x7b, 0xdd, 0x18, 0x1f, 0xda, ++ 0x9b, 0x5b, 0xdc, 0x69, 0xc6, 0x76, 0xd8, 0xb7, 0xf9, 0x73, 0x33, 0x8d, ++ 0x0e, 0xf6, 0x61, 0x9b, 0xcc, 0x2e, 0x7f, 0xa7, 0xe9, 0x23, 0xee, 0xaa, ++ 0x54, 0x1b, 0x27, 0x64, 0xb6, 0x21, 0xb1, 0x5c, 0xc4, 0xc2, 0x05, 0xe9, ++ 0xf7, 0x76, 0xb2, 0x4f, 0x58, 0x46, 0xfb, 0xf6, 0xe2, 0x48, 0xa1, 0x57, ++ 0xa5, 0xc3, 0x5c, 0xc7, 0x94, 0xba, 0x02, 0xd6, 0xbc, 0x6e, 0x54, 0xd2, ++ 0x97, 0xc2, 0xa9, 0x81, 0xd4, 0xc9, 0x7a, 0x0b, 0xc4, 0x28, 0xbe, 0x45, ++ 0xa9, 0x6c, 0x6a, 0x7b, 0xbd, 0x1b, 0xc7, 0x6c, 0xfc, 0xa5, 0x4d, 0xf1, ++ 0x33, 0x2e, 0x31, 0x73, 0xc7, 0x84, 0xd4, 0x31, 0x42, 0x48, 0x7d, 0x08, ++ 0xff, 0x90, 0x9c, 0x1f, 0xa8, 0x41, 0xfa, 0xde, 0x1a, 0x48, 0x5f, 0x71, ++ 0x04, 0x3f, 0xd2, 0x23, 0xbe, 0x4c, 0xc1, 0xa3, 0xb6, 0x98, 0x33, 0xfe, ++ 0xad, 0x66, 0x10, 0x01, 0xf6, 0x65, 0x5d, 0xee, 0x18, 0xfb, 0x0c, 0xd1, ++ 0x63, 0x67, 0xeb, 0xb2, 0x7c, 0xc6, 0xdf, 0x6e, 0x3a, 0xb9, 0xf0, 0x96, ++ 0x29, 0x9f, 0xbf, 0x63, 0x32, 0x16, 0x39, 0x62, 0x63, 0xb1, 0xae, 0xd6, ++ 0x58, 0xde, 0xb2, 0x5e, 0x31, 0xe6, 0xaf, 0x96, 0x3b, 0x3d, 0x48, 0x6b, ++ 0x22, 0xdf, 0x84, 0xbb, 0x89, 0x9f, 0xda, 0x26, 0x9b, 0x60, 0x4c, 0x02, ++ 0x27, 0x8e, 0x47, 0xb0, 0x72, 0x42, 0x3b, 0x3d, 0xe8, 0xce, 0x60, 0x7c, ++ 0xb6, 0x13, 0x13, 0x05, 0xff, 0x42, 0xd4, 0x45, 0x5c, 0x9d, 0x74, 0xe1, ++ 0x76, 0x63, 0xb5, 0x9a, 0xb7, 0x63, 0x5a, 0xe1, 0x2e, 0x63, 0xbb, 0xea, ++ 0xb5, 0x31, 0xc5, 0x0c, 0xb1, 0x88, 0xc2, 0x4d, 0xce, 0x5c, 0xbe, 0x35, ++ 0x49, 0xcc, 0x7d, 0xfb, 0x84, 0xd4, 0x77, 0x0b, 0xaf, 0x26, 0xa9, 0x97, ++ 0x64, 0x36, 0xe3, 0x65, 0x0f, 0xb4, 0x4f, 0x69, 0xdd, 0x86, 0x72, 0x30, ++ 0xde, 0xad, 0x33, 0x0e, 0x2e, 0x5c, 0x36, 0xd3, 0xec, 0x97, 0x1c, 0xd4, ++ 0x6e, 0x68, 0x11, 0x8f, 0x2b, 0x84, 0x01, 0x9b, 0x46, 0x6f, 0xab, 0x31, ++ 0x53, 0x86, 0xa5, 0x7a, 0x0f, 0x4e, 0xdb, 0x32, 0xf4, 0xb7, 0xae, 0x27, ++ 0xbe, 0x7e, 0xdc, 0xcc, 0xb0, 0x07, 0x96, 0xfd, 0xd0, 0x58, 0xa2, 0xc5, ++ 0xdd, 0x46, 0x0c, 0x1b, 0x8b, 0x2e, 0xa8, 0xb4, 0xca, 0x7a, 0x1a, 0xd3, ++ 0x33, 0x60, 0x45, 0xa9, 0x71, 0xea, 0x9b, 0xc8, 0x18, 0x27, 0xce, 0x6a, ++ 0x3b, 0xee, 0x5f, 0x48, 0xc3, 0x99, 0xdf, 0x6c, 0x32, 0xfe, 0x37, 0x2e, ++ 0x85, 0xb5, 0x23, 0x69, 0xf2, 0xdd, 0xc1, 0xbc, 0x3b, 0xdf, 0xe3, 0xe1, ++ 0x7d, 0x99, 0xdb, 0x75, 0xb7, 0x8e, 0xe6, 0x30, 0xef, 0x4e, 0x49, 0x5f, ++ 0x85, 0x60, 0x77, 0x01, 0x32, 0x43, 0x62, 0x6f, 0xf1, 0xa9, 0x55, 0xda, ++ 0x3b, 0xea, 0x9a, 0x74, 0xf6, 0xc5, 0x72, 0xb3, 0x9e, 0xe0, 0x56, 0xb3, ++ 0x19, 0xc7, 0x0a, 0x9e, 0x1b, 0x68, 0xc7, 0x8f, 0xdc, 0xe2, 0x72, 0x21, ++ 0xbe, 0xea, 0x2e, 0x55, 0xdc, 0x5b, 0x62, 0x9e, 0xc8, 0xd8, 0x35, 0xb1, ++ 0x8c, 0x72, 0x5e, 0x38, 0x29, 0x6b, 0x7c, 0xab, 0x75, 0xf4, 0xa4, 0xd4, ++ 0xc8, 0xee, 0xd6, 0x88, 0xa9, 0x75, 0x4b, 0x1f, 0x58, 0x4d, 0x3d, 0x7d, ++ 0x34, 0x26, 0x35, 0x78, 0x3f, 0x6b, 0xb0, 0xb6, 0xd0, 0xae, 0xa4, 0x8e, ++ 0x69, 0x09, 0xbf, 0xdb, 0x85, 0x2b, 0x0d, 0x5a, 0xe6, 0x79, 0x68, 0xbd, ++ 0xce, 0xbc, 0x70, 0x67, 0x6b, 0x63, 0x11, 0x0f, 0xdf, 0x3a, 0xd3, 0x27, ++ 0xe7, 0x49, 0x6c, 0x1d, 0x37, 0xe5, 0x05, 0x1b, 0x5b, 0xd6, 0x4b, 0xc9, ++ 0x2e, 0xe2, 0x06, 0xc1, 0xc6, 0x72, 0xfd, 0x81, 0xd6, 0x86, 0x29, 0x1f, ++ 0x79, 0x53, 0x78, 0x8f, 0x75, 0xe9, 0x48, 0xa1, 0xc4, 0xa3, 0x83, 0x9b, ++ 0x37, 0x13, 0x37, 0xbb, 0x53, 0x5a, 0xcb, 0x06, 0xe2, 0x66, 0x9d, 0x3d, ++ 0x84, 0x07, 0x3d, 0x78, 0xcc, 0x74, 0xfa, 0x08, 0xc1, 0xce, 0xd6, 0x49, ++ 0x2d, 0x2d, 0xb8, 0xf9, 0xea, 0x6a, 0x60, 0x07, 0x71, 0xf3, 0x42, 0xce, ++ 0x83, 0x0c, 0x71, 0xf3, 0x47, 0x39, 0x1f, 0xee, 0x20, 0x6e, 0xbe, 0x42, ++ 0x8c, 0x75, 0x3e, 0xf9, 0x4b, 0x7c, 0xbb, 0x38, 0x13, 0xdb, 0x95, 0xf0, ++ 0xd1, 0xb7, 0x05, 0x3b, 0xff, 0xa6, 0x88, 0x9d, 0xff, 0xcb, 0x3f, 0xc3, ++ 0xce, 0x77, 0x13, 0x13, 0x76, 0x4d, 0xc8, 0xfe, 0xd1, 0xae, 0xd6, 0xd7, ++ 0x4f, 0xc9, 0x99, 0x95, 0x5b, 0xf1, 0xee, 0xc9, 0xe1, 0x7e, 0x62, 0x65, ++ 0x8c, 0x24, 0x33, 0xc8, 0x4d, 0x62, 0x09, 0x71, 0xc1, 0x4b, 0x6e, 0xae, ++ 0xbb, 0x32, 0xa9, 0x19, 0x6f, 0xa8, 0x78, 0x67, 0x06, 0x71, 0xf6, 0xca, ++ 0xda, 0x02, 0x4d, 0x98, 0xf6, 0xa4, 0x88, 0x8d, 0x59, 0x03, 0x97, 0x12, ++ 0x3b, 0x57, 0xcd, 0x01, 0xb5, 0x73, 0x0e, 0x76, 0x96, 0x79, 0x58, 0x55, ++ 0x1c, 0x7f, 0x46, 0xec, 0xcc, 0xfe, 0x96, 0xa1, 0x36, 0xd7, 0xc4, 0x18, ++ 0x55, 0x38, 0x1c, 0x0f, 0xa0, 0xeb, 0x38, 0x71, 0x8f, 0x3d, 0x0f, 0xb3, ++ 0x86, 0x7e, 0x6a, 0x64, 0x70, 0x74, 0xd6, 0x99, 0x87, 0x6d, 0x22, 0x7e, ++ 0xf3, 0xc4, 0xc3, 0x28, 0x9f, 0xf3, 0xe0, 0x19, 0xe2, 0xe7, 0x8d, 0xb4, ++ 0xf3, 0x19, 0xe2, 0xe7, 0xbb, 0x6f, 0x98, 0x89, 0x4d, 0xcd, 0xe1, 0x15, ++ 0x62, 0xf9, 0xba, 0x5a, 0xc4, 0x65, 0xde, 0x61, 0x5d, 0x59, 0x13, 0xc0, ++ 0x39, 0x1b, 0x3f, 0xfb, 0x17, 0xb2, 0xca, 0x91, 0xad, 0x8c, 0xb6, 0x10, ++ 0xbb, 0xba, 0x68, 0xd7, 0xb6, 0x93, 0x5a, 0xe7, 0x8b, 0xd4, 0x45, 0x63, ++ 0xfc, 0xbc, 0x6d, 0x8f, 0xbe, 0xa4, 0xcc, 0x4e, 0x3a, 0x5b, 0xe5, 0x5c, ++ 0x55, 0x05, 0xed, 0xbd, 0x65, 0x2c, 0x96, 0xfe, 0x00, 0x4e, 0x4c, 0x26, ++ 0xf2, 0x65, 0xc5, 0x7a, 0x28, 0xf7, 0xfa, 0x79, 0x2f, 0x8d, 0xce, 0x35, ++ 0x8e, 0x7f, 0x27, 0xf2, 0xc7, 0x88, 0x5d, 0x65, 0xcf, 0x34, 0x14, 0xdc, ++ 0x64, 0x76, 0x62, 0xdc, 0x8c, 0xa2, 0xfc, 0x5c, 0x71, 0xef, 0xf5, 0x9c, ++ 0x9c, 0xc5, 0xdb, 0xd9, 0x1a, 0xfa, 0x5e, 0x09, 0x13, 0xa6, 0x89, 0xef, ++ 0xc2, 0xbe, 0xdb, 0x0b, 0x82, 0x17, 0xbb, 0x71, 0xd4, 0xd4, 0x22, 0x3f, ++ 0x67, 0x4c, 0xdc, 0x2b, 0xfb, 0xee, 0x37, 0xcc, 0x9e, 0x1e, 0xe4, 0x3d, ++ 0xf3, 0x73, 0xb3, 0xa7, 0xc1, 0x09, 0xfc, 0xc6, 0xdd, 0x5c, 0x0e, 0xd7, ++ 0x4a, 0x2f, 0x31, 0xbd, 0x16, 0x19, 0xc1, 0x23, 0xc4, 0x1c, 0xbf, 0x56, ++ 0x01, 0xdd, 0xd3, 0xdf, 0xe4, 0xd6, 0x22, 0x33, 0x2a, 0xc0, 0x77, 0x77, ++ 0x32, 0xbf, 0xed, 0xa4, 0x6f, 0xc4, 0x16, 0x2a, 0x94, 0x1b, 0x97, 0xbe, ++ 0x6c, 0xe3, 0x51, 0x7f, 0x37, 0xaf, 0x8d, 0x17, 0x4a, 0xb8, 0xa6, 0x47, ++ 0x78, 0xc5, 0xa6, 0xe3, 0x4e, 0x0e, 0xd1, 0xf3, 0xfe, 0x85, 0x4b, 0x70, ++ 0x64, 0xab, 0xa4, 0xac, 0xf7, 0x8f, 0x85, 0xac, 0xde, 0xc5, 0x12, 0xc3, ++ 0x3a, 0xb6, 0x99, 0xe2, 0x5f, 0x7d, 0xe4, 0xb3, 0x07, 0x87, 0xcc, 0xa5, ++ 0xec, 0xdd, 0x64, 0x0e, 0xda, 0x44, 0x6c, 0xdd, 0xcd, 0x1a, 0x6c, 0x59, ++ 0x83, 0x46, 0xd6, 0x6a, 0x5a, 0xab, 0x1b, 0x79, 0x35, 0x5f, 0x13, 0x21, ++ 0xbe, 0x59, 0xc5, 0xda, 0xdd, 0x56, 0x68, 0xc2, 0x1b, 0x67, 0x74, 0xfa, ++ 0x66, 0x3b, 0xf1, 0x7b, 0x37, 0xee, 0xa1, 0x3c, 0xdf, 0x2e, 0x7c, 0x07, ++ 0xe9, 0x6f, 0x78, 0x70, 0xe4, 0x78, 0x1a, 0xeb, 0x57, 0x0d, 0xe1, 0xd2, ++ 0x37, 0x7d, 0xcc, 0x55, 0x01, 0x3c, 0x7e, 0x5c, 0xf2, 0x6b, 0x09, 0x6f, ++ 0xdf, 0x88, 0x45, 0x7c, 0x88, 0xda, 0x38, 0xe4, 0x8b, 0xef, 0x39, 0x18, ++ 0xc5, 0xcf, 0xfe, 0xb7, 0xf4, 0x3e, 0xf3, 0xd0, 0xaa, 0x7f, 0x86, 0x67, ++ 0x88, 0x5b, 0x88, 0x05, 0x2a, 0x12, 0xf6, 0xb9, 0xb7, 0x12, 0xde, 0xf5, ++ 0xd0, 0x07, 0x24, 0xa6, 0x97, 0x32, 0xd6, 0x2d, 0x62, 0xe7, 0x85, 0xe2, ++ 0x5c, 0xf2, 0xed, 0x93, 0xda, 0xc5, 0x43, 0x88, 0x11, 0x43, 0xa3, 0x4f, ++ 0xb0, 0x9b, 0x9b, 0x78, 0xf7, 0x4a, 0x3c, 0x6e, 0x9c, 0x23, 0xde, 0x1d, ++ 0xa6, 0xad, 0x3d, 0xba, 0xf8, 0x66, 0x08, 0x65, 0x73, 0x11, 0xfa, 0xa4, ++ 0xcc, 0x25, 0x5f, 0xf1, 0x3b, 0x73, 0x49, 0x99, 0x85, 0xcb, 0xb9, 0x10, ++ 0x74, 0x94, 0xb1, 0x77, 0x2b, 0x57, 0x59, 0xe6, 0xe4, 0x29, 0xff, 0x0e, ++ 0xe6, 0xf7, 0x8c, 0x19, 0x0e, 0xee, 0x28, 0x84, 0xf8, 0xa9, 0x0b, 0x66, ++ 0x0a, 0xbf, 0xc7, 0xe7, 0x23, 0xfc, 0x8e, 0x62, 0x22, 0x5f, 0x5b, 0x21, ++ 0xcd, 0xc0, 0x44, 0xde, 0xc9, 0x79, 0xd1, 0xfc, 0x5e, 0xbf, 0x60, 0xcd, ++ 0xb6, 0xe3, 0xce, 0xdf, 0xfa, 0x0d, 0x7f, 0x7f, 0x1e, 0xf3, 0x7b, 0xc9, ++ 0xf7, 0x99, 0x93, 0x3a, 0x3e, 0x3a, 0x69, 0x63, 0xfe, 0x79, 0x62, 0xfe, ++ 0x01, 0xaf, 0x5b, 0xb0, 0xe6, 0xaf, 0xac, 0xf3, 0xf1, 0x78, 0xef, 0x34, ++ 0xfd, 0xa0, 0x8b, 0x74, 0x5d, 0x7a, 0xd8, 0xe6, 0xd7, 0xe1, 0xd3, 0x99, ++ 0xe5, 0x5e, 0x3e, 0x99, 0xc0, 0x3b, 0xd7, 0x67, 0xa7, 0x9f, 0x94, 0xd9, ++ 0x33, 0x60, 0x3c, 0xf2, 0xee, 0x5a, 0xf8, 0x5a, 0xd8, 0x6f, 0x7a, 0xf9, ++ 0x7c, 0xc4, 0x7e, 0x5e, 0x66, 0xb9, 0x9f, 0x7c, 0x56, 0xc2, 0xd3, 0x1f, ++ 0x5d, 0x7f, 0xe7, 0x20, 0x3b, 0x35, 0xdf, 0x79, 0xc6, 0x96, 0xdb, 0x7e, ++ 0x4e, 0xe6, 0xad, 0xfe, 0x05, 0xd8, 0xf1, 0xf5, 0xfb, 0x94, 0x49, 0xec, ++ 0x7b, 0xc0, 0x72, 0xfc, 0x36, 0x1c, 0xdc, 0xc6, 0x78, 0xf8, 0x2e, 0xed, ++ 0xb3, 0xed, 0x5c, 0x5d, 0xf0, 0x2e, 0xb3, 0xd3, 0x96, 0xf9, 0xae, 0x73, ++ 0x52, 0x93, 0xe4, 0xfe, 0x1f, 0x54, 0x08, 0x1e, 0x7f, 0x9c, 0x35, 0x6b, ++ 0xd8, 0x94, 0xd9, 0x3e, 0x94, 0x27, 0x75, 0x08, 0x9b, 0xc6, 0xa3, 0x78, ++ 0xdb, 0xf0, 0x17, 0xcf, 0xb0, 0x48, 0x4c, 0x0e, 0x30, 0x26, 0xc3, 0x18, ++ 0x31, 0x63, 0xd1, 0xb7, 0x89, 0x4f, 0xb3, 0x64, 0xf8, 0xe8, 0x84, 0x1b, ++ 0x6f, 0x13, 0x33, 0x42, 0x39, 0x67, 0x40, 0x9d, 0x77, 0x4b, 0xbf, 0x57, ++ 0x22, 0x5a, 0x13, 0x6b, 0xd9, 0x8b, 0x3a, 0xe4, 0x98, 0xf3, 0xfd, 0xfa, ++ 0x8f, 0x71, 0xec, 0x84, 0x0b, 0xf7, 0xb1, 0xef, 0x4b, 0xdf, 0x69, 0xf0, ++ 0xef, 0xc6, 0xfe, 0xf7, 0xf1, 0x0f, 0xd6, 0x94, 0x9c, 0xb3, 0x52, 0x72, ++ 0x96, 0xe3, 0x13, 0xab, 0x56, 0xd7, 0xe7, 0x9f, 0x87, 0x3e, 0x78, 0x15, ++ 0x8d, 0x03, 0x0b, 0xf8, 0xc0, 0x9a, 0xe7, 0xbd, 0xf7, 0x18, 0x3f, 0x2f, ++ 0x1a, 0xb1, 0x88, 0x8b, 0xc2, 0xcc, 0x87, 0xdd, 0xb8, 0xd7, 0x90, 0x7d, ++ 0x26, 0x6d, 0xe0, 0x69, 0x68, 0xfd, 0x17, 0x94, 0x9c, 0xcd, 0xb9, 0x64, ++ 0x65, 0x6b, 0x64, 0x5d, 0x85, 0x95, 0xcb, 0x1b, 0x3b, 0xcb, 0xa0, 0xb5, ++ 0x78, 0x95, 0x6e, 0xbc, 0xaf, 0xfe, 0xa7, 0x35, 0x1f, 0xfe, 0xc4, 0x7a, ++ 0x47, 0x2f, 0xd1, 0xd5, 0xa2, 0x3e, 0x77, 0x89, 0xb7, 0x3a, 0x1c, 0x33, ++ 0x65, 0x7f, 0xee, 0xc7, 0xb8, 0xef, 0x84, 0x07, 0xed, 0xc9, 0x5f, 0x5a, ++ 0xd9, 0xb0, 0xd0, 0x0c, 0x56, 0xa2, 0x42, 0xe8, 0x3b, 0x33, 0xeb, 0x17, ++ 0x0a, 0x50, 0x1d, 0xa6, 0xe0, 0x65, 0xf1, 0xd3, 0x71, 0x58, 0xa6, 0xcc, ++ 0x11, 0x2d, 0xdc, 0x91, 0x1c, 0xc2, 0x7b, 0xc9, 0xf4, 0x1f, 0xf8, 0xa0, ++ 0x5d, 0xbc, 0xec, 0xd6, 0xe6, 0x9b, 0xdc, 0x51, 0xe5, 0x6f, 0xd0, 0x07, ++ 0x1a, 0xec, 0x7a, 0x93, 0x67, 0xef, 0x14, 0x60, 0x6e, 0x91, 0x1e, 0x73, ++ 0x1c, 0x73, 0x63, 0x59, 0x78, 0x88, 0xed, 0x86, 0x9b, 0xb5, 0xcc, 0x53, ++ 0x4a, 0x8b, 0xec, 0x53, 0x51, 0x75, 0x8f, 0x3e, 0x88, 0x67, 0x8c, 0x78, ++ 0xba, 0x4d, 0xd5, 0xf9, 0x3a, 0x0b, 0x25, 0xda, 0xed, 0xc4, 0x2a, 0xda, ++ 0xfc, 0x65, 0x77, 0x39, 0x6a, 0x57, 0xeb, 0x9d, 0xe5, 0x6e, 0x6d, 0xf0, ++ 0x6b, 0x8c, 0xaf, 0xcd, 0x85, 0x79, 0xff, 0xfb, 0x71, 0x17, 0x56, 0xd8, ++ 0xfb, 0x08, 0xb9, 0xe2, 0x8c, 0x74, 0x1c, 0x5b, 0xc6, 0xac, 0xf5, 0xaf, ++ 0x26, 0xb5, 0xc8, 0x53, 0x2a, 0xbb, 0x23, 0x40, 0x4c, 0x73, 0x3f, 0xf4, ++ 0xe8, 0x2c, 0xeb, 0x54, 0x7b, 0xc1, 0x85, 0x5b, 0x4e, 0x09, 0xcd, 0x1c, ++ 0x69, 0x1e, 0x42, 0xf9, 0x09, 0x6b, 0xfd, 0x0e, 0x43, 0x1b, 0xbc, 0xec, ++ 0xce, 0xfe, 0xd7, 0x5a, 0xea, 0xad, 0x43, 0xc9, 0x3e, 0xda, 0x10, 0x71, ++ 0xc5, 0x90, 0x9c, 0x87, 0x4b, 0xfc, 0x39, 0x31, 0xc5, 0x1f, 0xd3, 0x57, ++ 0xdd, 0xa9, 0x20, 0xf9, 0xd4, 0x12, 0xd3, 0x90, 0xf9, 0x79, 0x14, 0x97, ++ 0x8d, 0xac, 0x7f, 0x53, 0x43, 0x82, 0xd8, 0x2c, 0xc2, 0x3a, 0x18, 0xc5, ++ 0x51, 0x62, 0xbc, 0x43, 0x6c, 0x09, 0xe7, 0x43, 0x3a, 0xb1, 0x59, 0x37, ++ 0x5c, 0x63, 0x01, 0x35, 0x93, 0x8b, 0x19, 0xed, 0xf8, 0xf7, 0x98, 0x8f, ++ 0x88, 0x8b, 0x1c, 0x42, 0xe0, 0xc4, 0xdf, 0x59, 0x55, 0xba, 0xde, 0x32, ++ 0xa6, 0xb8, 0xee, 0x13, 0x11, 0xea, 0x98, 0xef, 0xc9, 0xb9, 0x15, 0xb3, ++ 0x0b, 0xf7, 0x8c, 0x85, 0xf9, 0x7e, 0x15, 0x56, 0x9e, 0x88, 0xe2, 0x4a, ++ 0xf2, 0x66, 0xcc, 0xd7, 0x38, 0x18, 0xc8, 0xaf, 0xd3, 0x8f, 0xd8, 0x67, ++ 0x65, 0x0b, 0xba, 0xbd, 0x77, 0x74, 0xc8, 0x94, 0xfe, 0xdc, 0xc3, 0xbf, ++ 0x03, 0xfc, 0x88, 0x3e, 0xbf, 0x55, 0xc4, 0x3a, 0xfb, 0x5b, 0xa3, 0x33, ++ 0x6f, 0x55, 0xd8, 0x7b, 0x9a, 0x88, 0xf2, 0xb9, 0x90, 0x3d, 0x17, 0x1c, ++ 0x26, 0xcd, 0xb3, 0xe3, 0xd2, 0xb7, 0xb5, 0xad, 0xf3, 0x15, 0xf7, 0xdf, ++ 0xdf, 0x32, 0x5c, 0x58, 0xcf, 0xde, 0x3e, 0xa2, 0x4b, 0xbd, 0x1c, 0xd6, ++ 0x6a, 0xb1, 0x0e, 0xa7, 0x43, 0x6c, 0xc2, 0xf5, 0x7f, 0x87, 0x23, 0xa1, ++ 0x04, 0x73, 0xbe, 0x8e, 0x77, 0x73, 0x5f, 0x66, 0xbf, 0x53, 0x27, 0x67, ++ 0x77, 0x70, 0xcb, 0x09, 0x2f, 0xd7, 0x5c, 0x4f, 0x5c, 0xb3, 0x09, 0x3f, ++ 0x0b, 0x39, 0xbd, 0xc6, 0x61, 0x5e, 0x1f, 0x9d, 0x0e, 0x10, 0x8b, 0xfa, ++ 0xf8, 0xb9, 0x91, 0xb7, 0x2f, 0xe2, 0x49, 0x64, 0xf9, 0xd7, 0x78, 0xf2, ++ 0x11, 0x0f, 0xe8, 0xb8, 0x9a, 0x7b, 0x09, 0x57, 0x48, 0x3b, 0x3b, 0xed, ++ 0xd0, 0x3c, 0x5e, 0x10, 0xba, 0xb2, 0x5e, 0x6c, 0xb0, 0xd6, 0x2d, 0xf4, ++ 0x03, 0x72, 0x8e, 0xf7, 0xdf, 0xb8, 0x06, 0x91, 0xdd, 0x09, 0xf6, 0xc7, ++ 0x46, 0x03, 0xda, 0x43, 0xb4, 0x97, 0x29, 0x6b, 0x68, 0xec, 0x45, 0xe5, ++ 0xdd, 0x08, 0x56, 0x8c, 0x59, 0x43, 0x91, 0x94, 0x5c, 0xb7, 0xac, 0xea, ++ 0xb5, 0x7a, 0xe4, 0x0d, 0xe5, 0x61, 0xad, 0xf3, 0x50, 0x07, 0xa3, 0x38, ++ 0x9b, 0x6b, 0xbc, 0xf8, 0x1e, 0xb1, 0x53, 0x94, 0xbd, 0xde, 0x25, 0xf7, ++ 0x28, 0x66, 0x72, 0xff, 0xb1, 0x52, 0x66, 0x04, 0xa3, 0x85, 0x80, 0x9a, ++ 0xce, 0xfd, 0x49, 0xa5, 0xe4, 0xa2, 0x11, 0xfa, 0x42, 0xd3, 0x98, 0xf0, ++ 0x6a, 0x0d, 0x55, 0x91, 0xce, 0x51, 0xd2, 0x99, 0x5e, 0xa3, 0x67, 0x46, ++ 0x94, 0xe8, 0x2c, 0x40, 0x5c, 0xf7, 0xaa, 0xcc, 0xcf, 0xa8, 0xb7, 0xa7, ++ 0xf9, 0xbc, 0xe8, 0x2d, 0x8c, 0x9f, 0x15, 0xe9, 0x3c, 0x56, 0xb8, 0x88, ++ 0xe9, 0xdc, 0x25, 0xfb, 0xf7, 0x91, 0x42, 0x82, 0xb5, 0xaf, 0x0f, 0x79, ++ 0xe6, 0x93, 0xb1, 0x5c, 0x63, 0x66, 0x8c, 0x7c, 0x38, 0x67, 0xee, 0xfa, ++ 0xf0, 0x64, 0xf1, 0x99, 0x61, 0xbe, 0x3b, 0x7c, 0xed, 0x77, 0xd1, 0x91, ++ 0xb3, 0xaf, 0xef, 0xec, 0x2b, 0x94, 0xd3, 0x76, 0x4e, 0x1f, 0x7e, 0xd8, ++ 0xf4, 0xca, 0x0c, 0x1c, 0x2f, 0x8d, 0xaf, 0xc7, 0x88, 0xf1, 0x97, 0xd8, ++ 0x45, 0xb9, 0x47, 0xa9, 0xcf, 0x13, 0xa6, 0xbd, 0x7f, 0x2f, 0xe7, 0xba, ++ 0x98, 0xab, 0xbb, 0x5a, 0xcf, 0x10, 0x8b, 0x1d, 0x63, 0xcc, 0xec, 0x49, ++ 0x36, 0x76, 0xbf, 0x4c, 0xbf, 0x4b, 0x7f, 0x5d, 0xf6, 0xc8, 0x81, 0xb1, ++ 0x89, 0x6f, 0x63, 0xaa, 0xa6, 0x71, 0xe1, 0x59, 0xe6, 0x84, 0xd3, 0xcc, ++ 0x53, 0x1e, 0xe6, 0x84, 0xea, 0x09, 0x62, 0x48, 0xe6, 0xa9, 0x79, 0xe6, ++ 0x29, 0x8f, 0xde, 0x78, 0x71, 0x06, 0xff, 0x9d, 0x7a, 0x11, 0xfe, 0x62, ++ 0x89, 0x19, 0xc8, 0xb3, 0xce, 0xfc, 0x55, 0x9f, 0xe9, 0xc7, 0xa5, 0x9b, ++ 0x9d, 0x19, 0x9a, 0x9b, 0x35, 0x7b, 0x77, 0xae, 0x31, 0x34, 0x22, 0xb4, ++ 0x7b, 0xb4, 0x48, 0x96, 0xb6, 0x3a, 0x62, 0x63, 0xef, 0x6e, 0xf6, 0x0b, ++ 0x72, 0x8e, 0xab, 0x0a, 0x1e, 0xfa, 0xfe, 0x88, 0x21, 0xe7, 0x1b, 0x22, ++ 0xc1, 0xcd, 0xb4, 0xe1, 0x88, 0xd9, 0xd8, 0x12, 0x53, 0x3b, 0x70, 0xa9, ++ 0x98, 0x63, 0x1d, 0x2c, 0xad, 0x65, 0x8e, 0xa2, 0xb1, 0xfb, 0x7e, 0x7c, ++ 0x03, 0xe9, 0x9a, 0xc6, 0xde, 0x71, 0xc4, 0x8c, 0x7b, 0x21, 0xe7, 0x41, ++ 0x1d, 0x5a, 0xf5, 0x79, 0x37, 0xf1, 0xc8, 0x27, 0xd6, 0x52, 0xfd, 0x31, ++ 0x8c, 0x13, 0x33, 0x36, 0xac, 0xd2, 0x2f, 0x7e, 0xbf, 0x78, 0xcf, 0xd9, ++ 0x2b, 0x12, 0x7f, 0xf1, 0x51, 0x07, 0xe5, 0xf0, 0x2c, 0xaa, 0xe3, 0x1a, ++ 0xd4, 0x85, 0x7d, 0x56, 0xf8, 0x55, 0x1c, 0xa0, 0xbf, 0x8d, 0x17, 0x14, ++ 0x8c, 0xfa, 0x57, 0x31, 0x20, 0xb5, 0x89, 0xef, 0xb4, 0xe5, 0x02, 0xc4, ++ 0x29, 0x11, 0x94, 0xeb, 0xb1, 0xe8, 0x30, 0xe5, 0x6b, 0x63, 0x2e, 0x1f, ++ 0x65, 0x0e, 0xc9, 0x86, 0x02, 0xf6, 0xf9, 0xd5, 0x72, 0x3d, 0x62, 0xff, ++ 0xcf, 0x81, 0xf4, 0x41, 0x0d, 0x53, 0xb2, 0x4f, 0x7d, 0x08, 0xaf, 0x8e, ++ 0xcf, 0xe3, 0x58, 0x32, 0x8d, 0xbd, 0x35, 0x21, 0x8c, 0x99, 0x8b, 0xed, ++ 0xb9, 0x81, 0xf4, 0x5b, 0x5b, 0x26, 0x0e, 0xda, 0xb3, 0xc8, 0x8d, 0x49, ++ 0x57, 0xbd, 0x9c, 0xe3, 0x98, 0x66, 0xdf, 0x35, 0x6e, 0x0c, 0xe1, 0x80, ++ 0xf1, 0xc7, 0x30, 0x16, 0x49, 0xee, 0x1c, 0xc1, 0xf9, 0x29, 0xa9, 0x61, ++ 0xfd, 0xad, 0xcb, 0xc6, 0x44, 0x3f, 0x2e, 0x62, 0x5e, 0x1f, 0x9a, 0x6c, ++ 0x0c, 0x37, 0xd7, 0xba, 0x7c, 0xca, 0xc1, 0x72, 0x4d, 0x79, 0x39, 0x73, ++ 0x5d, 0x85, 0x20, 0xf5, 0x75, 0x21, 0xe9, 0x65, 0xce, 0x11, 0x7d, 0xca, ++ 0x19, 0x3f, 0x47, 0xce, 0x44, 0x5e, 0x61, 0xa4, 0xf9, 0xc6, 0xfd, 0x15, ++ 0xf9, 0xff, 0x83, 0x6b, 0xe7, 0x0e, 0x8b, 0xb3, 0xf1, 0x3f, 0xb7, 0x2e, ++ 0xdd, 0x24, 0x72, 0x27, 0x03, 0xcc, 0xe9, 0xd1, 0xa9, 0x6b, 0xfa, 0x15, ++ 0x9d, 0x9e, 0x93, 0x9a, 0x61, 0xeb, 0xdc, 0x99, 0xb7, 0x69, 0x03, 0xef, ++ 0xa8, 0x46, 0xd6, 0x13, 0xfa, 0x55, 0x0d, 0xfd, 0xad, 0x09, 0xbd, 0x4b, ++ 0x53, 0x9e, 0x9e, 0xab, 0xe6, 0x7a, 0xb4, 0xac, 0x7e, 0xd7, 0xc2, 0xcd, ++ 0x6d, 0x70, 0xeb, 0x72, 0x7d, 0xca, 0x4a, 0x87, 0xe4, 0x77, 0x33, 0x20, ++ 0xb5, 0xfc, 0x05, 0x73, 0xde, 0x5a, 0xbe, 0xd8, 0xc1, 0x86, 0x7f, 0x97, ++ 0x93, 0xbd, 0xaf, 0xac, 0xc5, 0x5e, 0xfb, 0xe2, 0xdb, 0xee, 0x83, 0xf8, ++ 0xdb, 0xfc, 0x21, 0xbc, 0x39, 0xee, 0x21, 0xce, 0x14, 0x59, 0xd6, 0xa3, ++ 0x7a, 0x75, 0x3c, 0xfd, 0x2e, 0xf3, 0xe2, 0xc5, 0xa9, 0x92, 0x5f, 0xcc, ++ 0xb5, 0xae, 0x98, 0x52, 0xa4, 0x55, 0x85, 0x32, 0xca, 0xf9, 0x53, 0xc3, ++ 0x8d, 0x68, 0x11, 0xdb, 0xba, 0xc9, 0xe7, 0xee, 0x9c, 0x83, 0x79, 0x63, ++ 0xf9, 0xc3, 0x01, 0x67, 0xfe, 0x15, 0x60, 0x1e, 0x1d, 0xc5, 0x91, 0x5c, ++ 0x63, 0xe2, 0x3d, 0x39, 0xa7, 0xc3, 0x5e, 0xec, 0x12, 0x46, 0x71, 0x22, ++ 0x57, 0xca, 0xa1, 0x11, 0x39, 0xdf, 0x9a, 0x88, 0xba, 0x9c, 0x1c, 0x19, ++ 0x75, 0x69, 0xd9, 0xa8, 0xeb, 0xe6, 0x80, 0x60, 0x83, 0xe1, 0x42, 0x2c, ++ 0x52, 0x0e, 0x37, 0xf6, 0x18, 0x8e, 0x7f, 0xd4, 0xcf, 0x78, 0x11, 0x5d, ++ 0x24, 0x75, 0x59, 0x6a, 0xb2, 0x87, 0x35, 0x79, 0x31, 0xd2, 0x8b, 0x3d, ++ 0x78, 0x4d, 0x17, 0x7d, 0xec, 0x2f, 0xe9, 0xc3, 0x38, 0x87, 0xfd, 0xd6, ++ 0x7c, 0xb7, 0xf8, 0x92, 0x17, 0x87, 0x9a, 0xa6, 0xad, 0xa9, 0xb0, 0xc8, ++ 0xee, 0xc6, 0x69, 0xe6, 0x57, 0xdc, 0x1c, 0x8b, 0x9c, 0x66, 0xcd, 0x1e, ++ 0xd1, 0x4b, 0x3e, 0x7e, 0x57, 0x91, 0x4f, 0x3d, 0x33, 0x8b, 0x3f, 0xe1, ++ 0xef, 0xf5, 0x91, 0xbd, 0xca, 0x59, 0x6f, 0xf9, 0xcc, 0xdb, 0x81, 0xd2, ++ 0xec, 0x54, 0x9e, 0x8d, 0xe6, 0x09, 0x3a, 0x2b, 0x84, 0x56, 0x80, 0xfe, ++ 0x59, 0x8e, 0xde, 0xb0, 0x9c, 0xf3, 0x10, 0xbd, 0xc8, 0x9e, 0x22, 0xa8, ++ 0x0f, 0x0b, 0x2f, 0x51, 0x1f, 0x87, 0xae, 0x9d, 0xa9, 0x72, 0xf2, 0x57, ++ 0x05, 0xaf, 0x6f, 0x4e, 0xbe, 0xb8, 0xce, 0x8f, 0xdf, 0x58, 0x97, 0xc2, ++ 0x11, 0xe6, 0x04, 0xb1, 0x69, 0xc6, 0xc6, 0x91, 0x6e, 0xe2, 0x93, 0xdd, ++ 0xf6, 0xf9, 0x11, 0xc6, 0x81, 0x79, 0x4d, 0x8e, 0xf9, 0x3e, 0xe2, 0xec, ++ 0xb9, 0x9c, 0x7d, 0x66, 0xaf, 0xf7, 0x0d, 0x15, 0x63, 0xae, 0xf9, 0x12, ++ 0x7a, 0x6b, 0x85, 0x5e, 0x28, 0xb8, 0x6d, 0x32, 0x41, 0x1d, 0xd4, 0x09, ++ 0x5d, 0xeb, 0x29, 0x76, 0x73, 0x87, 0xc6, 0x84, 0x3e, 0x30, 0x32, 0x16, ++ 0xeb, 0xff, 0x29, 0xb0, 0xae, 0x0a, 0xda, 0xe0, 0x6c, 0xf1, 0xff, 0x38, ++ 0x7e, 0xa1, 0x84, 0x96, 0xd0, 0xf1, 0xc0, 0x64, 0x8e, 0x3b, 0x3e, 0x57, ++ 0x41, 0xdd, 0x69, 0xdd, 0x3f, 0x50, 0x15, 0x78, 0xec, 0x89, 0x04, 0x79, ++ 0x5f, 0x14, 0xdc, 0x3c, 0xe9, 0x83, 0xff, 0x4c, 0x15, 0x6b, 0xae, 0x0f, ++ 0x97, 0x9b, 0x69, 0xd7, 0x27, 0x4a, 0xbc, 0xdb, 0x7b, 0xa3, 0x78, 0x74, ++ 0x22, 0x0a, 0x93, 0x3e, 0x3b, 0x67, 0xca, 0x3e, 0xb0, 0xcf, 0xce, 0x9f, ++ 0x17, 0xd7, 0xd4, 0xd9, 0x7b, 0x54, 0xcf, 0x16, 0xf4, 0xc8, 0x59, 0x55, ++ 0x85, 0x0f, 0x4e, 0xcc, 0xdf, 0x5c, 0x0e, 0xeb, 0x85, 0xa5, 0xa9, 0x78, ++ 0x66, 0x17, 0x7d, 0x7e, 0xc5, 0xf2, 0x30, 0x7b, 0x19, 0xf6, 0x94, 0x6b, ++ 0xa5, 0xff, 0x1d, 0x60, 0xff, 0x5b, 0xda, 0xd3, 0xd7, 0xfb, 0x1f, 0x52, ++ 0xd9, 0x4d, 0x41, 0x58, 0x1f, 0x95, 0xa7, 0xac, 0x8f, 0xbd, 0xa9, 0x38, ++ 0xdf, 0x97, 0x3d, 0x3d, 0xcb, 0x7a, 0xab, 0xd9, 0xb2, 0xf2, 0xcd, 0xb1, ++ 0x4c, 0xc8, 0x1d, 0xc2, 0x99, 0x06, 0xd9, 0x07, 0x74, 0xe1, 0x83, 0xb8, ++ 0x1e, 0xd9, 0x05, 0xd9, 0x7b, 0x67, 0x8e, 0x5f, 0x2c, 0xe7, 0x0e, 0xeb, ++ 0x82, 0x9d, 0xe6, 0x22, 0x3c, 0x33, 0xbb, 0x16, 0xbd, 0x5e, 0xd8, 0xe7, ++ 0x62, 0x2c, 0x03, 0x6f, 0x2c, 0x85, 0xd4, 0xed, 0x78, 0xcb, 0x43, 0x08, ++ 0x63, 0xb6, 0x70, 0x08, 0x0f, 0x9e, 0x90, 0xfd, 0xc5, 0x07, 0x5a, 0x7d, ++ 0x27, 0xac, 0xbf, 0x8b, 0xa4, 0xe6, 0x99, 0x17, 0x2d, 0xab, 0x62, 0x6d, ++ 0x63, 0x84, 0xe5, 0x88, 0x18, 0xa3, 0x57, 0xb0, 0x7b, 0xff, 0x07, 0xa8, ++ 0xc1, 0xd9, 0xe9, 0xf4, 0xcd, 0xec, 0x25, 0x3b, 0x9f, 0x54, 0x21, 0x3c, ++ 0x4f, 0x19, 0x9f, 0x2e, 0x08, 0x4e, 0x79, 0xb0, 0x75, 0xcb, 0x89, 0x25, ++ 0x78, 0x61, 0x36, 0x8c, 0xb3, 0xa6, 0x4e, 0x9c, 0x04, 0x55, 0x99, 0xb2, ++ 0xaa, 0xab, 0xc9, 0x6b, 0xa5, 0xdb, 0x8d, 0x4d, 0x49, 0xe9, 0x0f, 0xf5, ++ 0xfe, 0x80, 0xc2, 0x92, 0x72, 0xe8, 0x0b, 0xfb, 0x81, 0x01, 0x3f, 0xfb, ++ 0xd5, 0x27, 0x55, 0x3c, 0xf3, 0xbe, 0x3b, 0x8c, 0xe7, 0x99, 0x7f, 0x7e, ++ 0x50, 0x90, 0x33, 0x53, 0xcc, 0x31, 0xd3, 0x51, 0xda, 0xca, 0x07, 0x57, ++ 0x7d, 0x15, 0x0e, 0x33, 0x5e, 0x5e, 0x32, 0xca, 0x98, 0xa3, 0xe4, 0x0c, ++ 0x95, 0xe4, 0xf7, 0x9d, 0x72, 0x56, 0xc4, 0x7a, 0x56, 0x77, 0xfa, 0x7d, ++ 0x63, 0xe6, 0xc6, 0x73, 0xc8, 0x21, 0xe6, 0xf5, 0xc6, 0xee, 0x88, 0x7a, ++ 0xc5, 0x4a, 0x7f, 0x5d, 0x51, 0xce, 0xdd, 0x55, 0xa8, 0xb0, 0x65, 0xc5, ++ 0xf0, 0x44, 0xa9, 0xa6, 0x54, 0x4b, 0x2f, 0xd7, 0x9d, 0x2d, 0xfa, 0x60, ++ 0x25, 0x63, 0xfd, 0x28, 0x6b, 0x74, 0xf9, 0x09, 0xa9, 0x25, 0xec, 0x5f, ++ 0xd4, 0x7a, 0x62, 0x61, 0xc1, 0x0d, 0x3e, 0xdc, 0x1f, 0xd2, 0x5a, 0xe4, ++ 0x2c, 0xf6, 0xd3, 0x85, 0x0e, 0x8f, 0x9c, 0x89, 0x7a, 0xa6, 0x20, 0xb5, ++ 0x5c, 0x72, 0x41, 0x69, 0xbd, 0x08, 0x6a, 0xc7, 0xc4, 0x46, 0xdd, 0xad, ++ 0x1f, 0x8d, 0x05, 0xe4, 0xdc, 0xfc, 0x90, 0x8b, 0xbd, 0xb6, 0x6f, 0xcc, ++ 0xb2, 0xee, 0x6e, 0xd6, 0xfb, 0xd7, 0xbb, 0x65, 0x3f, 0x39, 0xd6, 0x7b, ++ 0x4e, 0x69, 0x2d, 0x47, 0xd4, 0x8d, 0x74, 0x9e, 0xab, 0x92, 0x18, 0xc9, ++ 0x52, 0xce, 0x47, 0x6d, 0x99, 0xf6, 0x53, 0xa6, 0xd2, 0x99, 0xa1, 0x2a, ++ 0x5c, 0x1e, 0x87, 0xce, 0xa8, 0xc5, 0x79, 0x83, 0xc9, 0x29, 0x14, 0x4f, ++ 0xb7, 0x43, 0xfc, 0x5f, 0xeb, 0x15, 0x0c, 0x55, 0xc9, 0x9c, 0x3c, 0x3d, ++ 0x2e, 0x35, 0x46, 0x09, 0x3e, 0xc9, 0x56, 0xa7, 0x06, 0x70, 0x65, 0x0d, ++ 0xf0, 0xca, 0x98, 0xb3, 0xdf, 0x5e, 0x3c, 0xe3, 0x6d, 0x9f, 0x65, 0x78, ++ 0xc8, 0x3e, 0xa3, 0x20, 0xf4, 0x0f, 0xe2, 0x4c, 0x4e, 0x30, 0xe5, 0x00, ++ 0x31, 0x65, 0x6c, 0x90, 0x78, 0xb3, 0xa5, 0xe0, 0x9c, 0xb7, 0x32, 0x3e, ++ 0xa2, 0xcf, 0x3f, 0x49, 0xac, 0x7a, 0x18, 0xce, 0x7e, 0x7b, 0x43, 0xf1, ++ 0x0c, 0x42, 0x2c, 0xdf, 0xa9, 0xb6, 0x16, 0xec, 0x33, 0x5a, 0x8c, 0xb1, ++ 0x76, 0xb5, 0x79, 0xb6, 0x43, 0x6d, 0x99, 0xed, 0x52, 0x3b, 0x0a, 0xd2, ++ 0xb3, 0x3e, 0xd0, 0x7a, 0xff, 0x89, 0xed, 0x6a, 0xeb, 0x74, 0x8f, 0x22, ++ 0xa6, 0x0d, 0xf9, 0x52, 0x19, 0xd5, 0x35, 0xeb, 0xcc, 0xcf, 0x3b, 0xd9, ++ 0x77, 0x6d, 0x35, 0x4b, 0xfd, 0xbc, 0xfc, 0x1f, 0x57, 0x58, 0xfe, 0x67, ++ 0xa2, 0x77, 0xa3, 0xb2, 0xac, 0x5b, 0x93, 0x7f, 0x2d, 0xf6, 0xb0, 0x9e, ++ 0x4e, 0xb2, 0x36, 0x9a, 0x55, 0xe8, 0x63, 0xdf, 0x31, 0x6c, 0x2c, 0x2b, ++ 0xee, 0x97, 0x89, 0x4c, 0x72, 0x4e, 0x42, 0xfc, 0x15, 0x59, 0xf6, 0x20, ++ 0xf8, 0x7b, 0xf2, 0xbf, 0xb7, 0x28, 0x57, 0x97, 0x9c, 0x23, 0xf0, 0x5e, ++ 0x3f, 0x47, 0x76, 0x6c, 0xec, 0xba, 0x5c, 0x1e, 0x5e, 0x1b, 0x25, 0x3e, ++ 0xdd, 0xab, 0xb4, 0xc1, 0xa7, 0x1c, 0xb9, 0x2e, 0x5e, 0x66, 0x0c, 0x0f, ++ 0xdb, 0x31, 0xec, 0xc8, 0xb5, 0xb2, 0x28, 0xd7, 0x8a, 0x7c, 0xa7, 0x7d, ++ 0x3e, 0x8b, 0x74, 0x5a, 0xe7, 0xc6, 0xe4, 0x1c, 0x99, 0xcc, 0x2e, 0x45, ++ 0x36, 0x91, 0xe3, 0x84, 0x55, 0xa1, 0x77, 0xa9, 0x6d, 0xf6, 0xb9, 0x32, ++ 0x39, 0xd3, 0x25, 0xfb, 0xfb, 0x25, 0xb9, 0xa4, 0x8e, 0x2f, 0x0a, 0x76, ++ 0x4c, 0xca, 0x39, 0x6b, 0xcb, 0xfa, 0x99, 0x51, 0x11, 0x14, 0x59, 0xce, ++ 0x1a, 0x22, 0x8b, 0x9c, 0x17, 0x29, 0xc9, 0xf3, 0xb5, 0xa2, 0x3c, 0x62, ++ 0xab, 0xeb, 0x76, 0x2a, 0xfd, 0xff, 0xdf, 0xdb, 0x39, 0xe7, 0x2c, 0x49, ++ 0x49, 0x9e, 0x60, 0x4a, 0xf8, 0xcf, 0xb7, 0x8e, 0x8e, 0x0f, 0xe0, 0x15, ++ 0xde, 0xff, 0x65, 0xae, 0x24, 0x97, 0x1b, 0x33, 0xd3, 0xa5, 0x33, 0x72, ++ 0x6c, 0x29, 0xcd, 0x98, 0x31, 0x42, 0x3f, 0x72, 0xe4, 0x93, 0x33, 0x72, ++ 0x8d, 0xf3, 0x97, 0xed, 0xb9, 0x57, 0x3c, 0xcd, 0x7e, 0x19, 0x67, 0x0b, ++ 0xbf, 0x6d, 0xbf, 0xa6, 0x7c, 0x05, 0x7b, 0x64, 0xa1, 0x3d, 0x47, 0xda, ++ 0x72, 0x96, 0x44, 0xe1, 0xa9, 0x69, 0x60, 0xda, 0xe4, 0xb2, 0xa9, 0x21, ++ 0x3c, 0x6e, 0x58, 0xd6, 0x93, 0xcd, 0xba, 0x9c, 0x01, 0xba, 0x50, 0x6b, ++ 0xcf, 0x85, 0x60, 0x54, 0xe9, 0xb2, 0x77, 0x27, 0xe7, 0x48, 0x7a, 0xa8, ++ 0x03, 0x91, 0x5d, 0x7c, 0xa0, 0x64, 0x7b, 0x39, 0xdf, 0x96, 0xa5, 0x7e, ++ 0x44, 0x37, 0xa5, 0x73, 0x6e, 0x32, 0x73, 0xb9, 0x51, 0x27, 0xb7, 0xd9, ++ 0x3a, 0x79, 0xda, 0x10, 0x7f, 0x65, 0xf6, 0xa1, 0xaf, 0xce, 0x10, 0x3f, ++ 0x8c, 0x18, 0x5e, 0x1b, 0xab, 0x1d, 0x26, 0x3e, 0x39, 0xc2, 0xd8, 0x79, ++ 0xd4, 0xbc, 0x88, 0x8b, 0xf9, 0x97, 0xf0, 0xca, 0xb5, 0xff, 0x85, 0x13, ++ 0x7f, 0xf1, 0xb5, 0x6c, 0xb1, 0xcf, 0x32, 0xfd, 0x75, 0xcb, 0xb2, 0xb8, ++ 0xe4, 0xa1, 0x93, 0x4d, 0x72, 0xb6, 0xa9, 0x3c, 0xf5, 0xde, 0x3a, 0xd9, ++ 0xdf, 0x2a, 0x4b, 0x0d, 0x7e, 0xf5, 0x82, 0x2e, 0xba, 0xf9, 0x64, 0xf5, ++ 0x19, 0x5d, 0xe4, 0xd2, 0x8d, 0x51, 0xfb, 0x7f, 0x33, 0x43, 0x6b, 0x77, ++ 0xeb, 0x12, 0x3b, 0xef, 0x34, 0xb7, 0xd9, 0x39, 0x61, 0x30, 0x75, 0xab, ++ 0xad, 0x83, 0x83, 0xa9, 0x65, 0x8e, 0x2e, 0x52, 0x09, 0xfb, 0xfb, 0xe1, ++ 0x94, 0xa3, 0x9b, 0x5c, 0xaa, 0xde, 0xfe, 0x1e, 0x4d, 0x39, 0x67, 0xa2, ++ 0xb3, 0x29, 0xdd, 0xfe, 0x1e, 0x4f, 0xc5, 0xec, 0xef, 0x23, 0xa9, 0x5b, ++ 0xae, 0xf3, 0xc5, 0x9f, 0xff, 0x07, 0xd8, 0xc4, 0xd3, 0xb4, 0xb4, 0x3a, + 0x00, 0x00, 0x00 }; + + static const u32 bnx2_TXP_b06FwData[(0x0/4) + 1] = { 0x0 }; + static const u32 bnx2_TXP_b06FwRodata[(0x0/4) + 1] = { 0x0 }; + + static struct fw_info bnx2_txp_fw_06 = { +- /* Firmware version: 4.6.16 */ ++ /* Firmware version: 4.4.2 */ + .ver_major = 0x4, +- .ver_minor = 0x6, +- .ver_fix = 0x10, ++ .ver_minor = 0x4, ++ .ver_fix = 0x2, + + .start_addr = 0x08000098, + + .text_addr = 0x08000000, +- .text_len = 0x3a74, ++ .text_len = 0x3ab0, + .text_index = 0x0, + .gz_text = bnx2_TXP_b06FwText, + .gz_text_len = sizeof(bnx2_TXP_b06FwText), +@@ -4432,11 +4535,11 @@ + .data_index = 0x0, + .data = bnx2_TXP_b06FwData, + +- .sbss_addr = 0x08003aa0, ++ .sbss_addr = 0x08003ae0, + .sbss_len = 0x68, + .sbss_index = 0x0, + +- .bss_addr = 0x08003b08, ++ .bss_addr = 0x08003b48, + .bss_len = 0x14c, + .bss_index = 0x0, + +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/drivers/net/bnx2.h linux-2.6.29-rc3.owrt/drivers/net/bnx2.h +--- linux-2.6.29.owrt/drivers/net/bnx2.h 2009-05-10 22:04:38.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/drivers/net/bnx2.h 2009-05-10 23:48:28.000000000 +0200 +@@ -1,6 +1,6 @@ + /* bnx2.h: Broadcom NX2 network driver. + * +- * Copyright (c) 2004-2009 Broadcom Corporation ++ * Copyright (c) 2004-2007 Broadcom Corporation + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/drivers/net/bnx2x.h linux-2.6.29-rc3.owrt/drivers/net/bnx2x.h +--- linux-2.6.29.owrt/drivers/net/bnx2x.h 2009-05-10 22:04:38.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/drivers/net/bnx2x.h 2009-05-10 23:48:28.000000000 +0200 +@@ -152,7 +152,7 @@ + #define PAGES_PER_SGE (1 << PAGES_PER_SGE_SHIFT) + #define SGE_PAGE_SIZE PAGE_SIZE + #define SGE_PAGE_SHIFT PAGE_SHIFT +-#define SGE_PAGE_ALIGN(addr) PAGE_ALIGN((typeof(PAGE_SIZE))addr) ++#define SGE_PAGE_ALIGN(addr) PAGE_ALIGN(addr) + + #define BCM_RX_ETH_PAYLOAD_ALIGN 64 + +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/drivers/net/bnx2x_init.h linux-2.6.29-rc3.owrt/drivers/net/bnx2x_init.h +--- linux-2.6.29.owrt/drivers/net/bnx2x_init.h 2009-05-10 22:04:38.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/drivers/net/bnx2x_init.h 2009-05-10 23:48:28.000000000 +0200 +@@ -150,6 +150,7 @@ + + static void bnx2x_write_big_buf(struct bnx2x *bp, u32 addr, u32 len) + { ++#ifdef USE_DMAE + int offset = 0; + + if (bp->dmae_ready) { +@@ -163,6 +164,9 @@ + addr + offset, len); + } else + bnx2x_init_str_wr(bp, addr, bp->gunzip_buf, len); ++#else ++ bnx2x_init_str_wr(bp, addr, bp->gunzip_buf, len); ++#endif + } + + static void bnx2x_init_fill(struct bnx2x *bp, u32 addr, int fill, u32 len) +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/drivers/net/bnx2x_main.c linux-2.6.29-rc3.owrt/drivers/net/bnx2x_main.c +--- linux-2.6.29.owrt/drivers/net/bnx2x_main.c 2009-05-10 22:04:38.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/drivers/net/bnx2x_main.c 2009-05-10 23:48:28.000000000 +0200 +@@ -57,7 +57,7 @@ + #include "bnx2x.h" + #include "bnx2x_init.h" + +-#define DRV_MODULE_VERSION "1.45.27" ++#define DRV_MODULE_VERSION "1.45.26" + #define DRV_MODULE_RELDATE "2009/01/26" + #define BNX2X_BC_VER 0x040200 + +@@ -4035,10 +4035,10 @@ + { + int port = BP_PORT(bp); + +- bnx2x_init_fill(bp, USTORM_INTMEM_ADDR + ++ bnx2x_init_fill(bp, BAR_USTRORM_INTMEM + + USTORM_SB_HOST_STATUS_BLOCK_OFFSET(port, sb_id), 0, + sizeof(struct ustorm_status_block)/4); +- bnx2x_init_fill(bp, CSTORM_INTMEM_ADDR + ++ bnx2x_init_fill(bp, BAR_CSTRORM_INTMEM + + CSTORM_SB_HOST_STATUS_BLOCK_OFFSET(port, sb_id), 0, + sizeof(struct cstorm_status_block)/4); + } +@@ -4092,18 +4092,18 @@ + { + int func = BP_FUNC(bp); + +- bnx2x_init_fill(bp, TSTORM_INTMEM_ADDR + +- TSTORM_DEF_SB_HOST_STATUS_BLOCK_OFFSET(func), 0, +- sizeof(struct tstorm_def_status_block)/4); +- bnx2x_init_fill(bp, USTORM_INTMEM_ADDR + ++ bnx2x_init_fill(bp, BAR_USTRORM_INTMEM + + USTORM_DEF_SB_HOST_STATUS_BLOCK_OFFSET(func), 0, + sizeof(struct ustorm_def_status_block)/4); +- bnx2x_init_fill(bp, CSTORM_INTMEM_ADDR + ++ bnx2x_init_fill(bp, BAR_CSTRORM_INTMEM + + CSTORM_DEF_SB_HOST_STATUS_BLOCK_OFFSET(func), 0, + sizeof(struct cstorm_def_status_block)/4); +- bnx2x_init_fill(bp, XSTORM_INTMEM_ADDR + ++ bnx2x_init_fill(bp, BAR_XSTRORM_INTMEM + + XSTORM_DEF_SB_HOST_STATUS_BLOCK_OFFSET(func), 0, + sizeof(struct xstorm_def_status_block)/4); ++ bnx2x_init_fill(bp, BAR_TSTRORM_INTMEM + ++ TSTORM_DEF_SB_HOST_STATUS_BLOCK_OFFSET(func), 0, ++ sizeof(struct tstorm_def_status_block)/4); + } + + static void bnx2x_init_def_sb(struct bnx2x *bp, +@@ -4518,8 +4518,7 @@ + (USTORM_ETH_ST_CONTEXT_CONFIG_ENABLE_TPA | + USTORM_ETH_ST_CONTEXT_CONFIG_ENABLE_SGE_RING); + context->ustorm_st_context.common.sge_buff_size = +- (u16)min((u32)SGE_PAGE_SIZE*PAGES_PER_SGE, +- (u32)0xffff); ++ (u16)(BCM_PAGE_SIZE*PAGES_PER_SGE); + context->ustorm_st_context.common.sge_page_base_hi = + U64_HI(fp->rx_sge_mapping); + context->ustorm_st_context.common.sge_page_base_lo = +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/drivers/net/bonding/bond_main.c linux-2.6.29-rc3.owrt/drivers/net/bonding/bond_main.c +--- linux-2.6.29.owrt/drivers/net/bonding/bond_main.c 2009-05-10 22:04:38.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/drivers/net/bonding/bond_main.c 2009-05-10 23:48:28.000000000 +0200 +@@ -3537,26 +3537,11 @@ + } + break; + case NETDEV_CHANGE: +- if (bond->params.mode == BOND_MODE_8023AD || bond_is_lb(bond)) { +- struct slave *slave; +- +- slave = bond_get_slave_by_dev(bond, slave_dev); +- if (slave) { +- u16 old_speed = slave->speed; +- u16 old_duplex = slave->duplex; +- +- bond_update_speed_duplex(slave); +- +- if (bond_is_lb(bond)) +- break; +- +- if (old_speed != slave->speed) +- bond_3ad_adapter_speed_changed(slave); +- if (old_duplex != slave->duplex) +- bond_3ad_adapter_duplex_changed(slave); +- } +- } +- ++ /* ++ * TODO: is this what we get if somebody ++ * sets up a hierarchical bond, then rmmod's ++ * one of the slave bonding devices? ++ */ + break; + case NETDEV_DOWN: + /* +@@ -4128,7 +4113,7 @@ + const struct net_device_ops *slave_ops + = slave->dev->netdev_ops; + if (slave_ops->ndo_neigh_setup) +- return slave_ops->ndo_neigh_setup(slave->dev, parms); ++ return slave_ops->ndo_neigh_setup(dev, parms); + } + return 0; + } +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/drivers/net/cassini.c linux-2.6.29-rc3.owrt/drivers/net/cassini.c +--- linux-2.6.29.owrt/drivers/net/cassini.c 2009-05-10 22:04:38.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/drivers/net/cassini.c 2009-05-10 23:48:28.000000000 +0200 +@@ -806,7 +806,7 @@ + + cas_phy_write(cp, MII_BMCR, BMCR_RESET); + udelay(100); +- while (--limit) { ++ while (limit--) { + val = cas_phy_read(cp, MII_BMCR); + if ((val & BMCR_RESET) == 0) + break; +@@ -979,7 +979,7 @@ + writel(val, cp->regs + REG_PCS_MII_CTRL); + + limit = STOP_TRIES; +- while (--limit > 0) { ++ while (limit-- > 0) { + udelay(10); + if ((readl(cp->regs + REG_PCS_MII_CTRL) & + PCS_MII_RESET) == 0) +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/drivers/net/cxgb3/cxgb3_main.c linux-2.6.29-rc3.owrt/drivers/net/cxgb3/cxgb3_main.c +--- linux-2.6.29.owrt/drivers/net/cxgb3/cxgb3_main.c 2009-05-10 22:04:38.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/drivers/net/cxgb3/cxgb3_main.c 2009-05-10 23:48:28.000000000 +0200 +@@ -90,7 +90,6 @@ + CH_DEVICE(0x30, 2), /* T3B10 */ + CH_DEVICE(0x31, 3), /* T3B20 */ + CH_DEVICE(0x32, 1), /* T3B02 */ +- CH_DEVICE(0x35, 6), /* T3C20-derived T3C10 */ + {0,} + }; + +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/drivers/net/cxgb3/sge.c linux-2.6.29-rc3.owrt/drivers/net/cxgb3/sge.c +--- linux-2.6.29.owrt/drivers/net/cxgb3/sge.c 2009-05-10 22:04:38.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/drivers/net/cxgb3/sge.c 2009-05-10 23:48:28.000000000 +0200 +@@ -2276,7 +2276,8 @@ + } else if ((len = ntohl(r->len_cq)) != 0) { + struct sge_fl *fl; + +- lro &= eth && is_eth_tcp(rss_hi); ++ if (eth) ++ lro = qs->lro_enabled && is_eth_tcp(rss_hi); + + fl = (len & F_RSPD_FLQ) ? &qs->fl[1] : &qs->fl[0]; + if (fl->use_pages) { +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/drivers/net/cxgb3/t3_hw.c linux-2.6.29-rc3.owrt/drivers/net/cxgb3/t3_hw.c +--- linux-2.6.29.owrt/drivers/net/cxgb3/t3_hw.c 2009-05-10 22:04:38.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/drivers/net/cxgb3/t3_hw.c 2009-05-10 23:48:28.000000000 +0200 +@@ -512,13 +512,6 @@ + F_GPIO5_OUT_VAL | F_GPIO6_OUT_VAL | F_GPIO10_OUT_VAL, + { S_GPIO9, S_GPIO3 }, SUPPORTED_10000baseT_Full | SUPPORTED_AUI, + &mi1_mdio_ext_ops, "Chelsio T320"}, +- {}, +- {}, +- {1, 0, +- F_GPIO1_OEN | F_GPIO2_OEN | F_GPIO4_OEN | F_GPIO6_OEN | F_GPIO7_OEN | +- F_GPIO10_OEN | F_GPIO1_OUT_VAL | F_GPIO6_OUT_VAL | F_GPIO10_OUT_VAL, +- { S_GPIO9 }, SUPPORTED_10000baseT_Full | SUPPORTED_AUI, +- &mi1_mdio_ext_ops, "Chelsio T310" }, + }; + + /* +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/drivers/net/dm9000.c linux-2.6.29-rc3.owrt/drivers/net/dm9000.c +--- linux-2.6.29.owrt/drivers/net/dm9000.c 2009-05-10 22:04:38.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/drivers/net/dm9000.c 2009-05-10 23:48:28.000000000 +0200 +@@ -930,15 +930,13 @@ + struct net_device *dev = dev_id; + board_info_t *db = netdev_priv(dev); + int int_status; +- unsigned long flags; + u8 reg_save; + + dm9000_dbg(db, 3, "entering %s\n", __func__); + + /* A real interrupt coming */ + +- /* holders of db->lock must always block IRQs */ +- spin_lock_irqsave(&db->lock, flags); ++ spin_lock(&db->lock); + + /* Save previous register address */ + reg_save = readb(db->io_addr); +@@ -974,7 +972,7 @@ + /* Restore previous register address */ + writeb(reg_save, db->io_addr); + +- spin_unlock_irqrestore(&db->lock, flags); ++ spin_unlock(&db->lock); + + return IRQ_HANDLED; + } +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/drivers/net/dnet.c linux-2.6.29-rc3.owrt/drivers/net/dnet.c +--- linux-2.6.29.owrt/drivers/net/dnet.c 2009-05-10 22:04:38.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/drivers/net/dnet.c 1970-01-01 01:00:00.000000000 +0100 +@@ -1,994 +0,0 @@ +-/* +- * Dave DNET Ethernet Controller driver +- * +- * Copyright (C) 2008 Dave S.r.l. <www.dave.eu> +- * Copyright (C) 2009 Ilya Yanok, Emcraft Systems Ltd, <yanok@emcraft.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/version.h> +-#include <linux/module.h> +-#include <linux/moduleparam.h> +-#include <linux/kernel.h> +-#include <linux/types.h> +-#include <linux/slab.h> +-#include <linux/delay.h> +-#include <linux/init.h> +-#include <linux/netdevice.h> +-#include <linux/etherdevice.h> +-#include <linux/dma-mapping.h> +-#include <linux/platform_device.h> +-#include <linux/phy.h> +-#include <linux/platform_device.h> +- +-#include "dnet.h" +- +-#undef DEBUG +- +-/* function for reading internal MAC register */ +-u16 dnet_readw_mac(struct dnet *bp, u16 reg) +-{ +- u16 data_read; +- +- /* issue a read */ +- dnet_writel(bp, reg, MACREG_ADDR); +- +- /* since a read/write op to the MAC is very slow, +- * we must wait before reading the data */ +- ndelay(500); +- +- /* read data read from the MAC register */ +- data_read = dnet_readl(bp, MACREG_DATA); +- +- /* all done */ +- return data_read; +-} +- +-/* function for writing internal MAC register */ +-void dnet_writew_mac(struct dnet *bp, u16 reg, u16 val) +-{ +- /* load data to write */ +- dnet_writel(bp, val, MACREG_DATA); +- +- /* issue a write */ +- dnet_writel(bp, reg | DNET_INTERNAL_WRITE, MACREG_ADDR); +- +- /* since a read/write op to the MAC is very slow, +- * we must wait before exiting */ +- ndelay(500); +-} +- +-static void __dnet_set_hwaddr(struct dnet *bp) +-{ +- u16 tmp; +- +- tmp = cpu_to_be16(*((u16 *) bp->dev->dev_addr)); +- dnet_writew_mac(bp, DNET_INTERNAL_MAC_ADDR_0_REG, tmp); +- tmp = cpu_to_be16(*((u16 *) (bp->dev->dev_addr + 2))); +- dnet_writew_mac(bp, DNET_INTERNAL_MAC_ADDR_1_REG, tmp); +- tmp = cpu_to_be16(*((u16 *) (bp->dev->dev_addr + 4))); +- dnet_writew_mac(bp, DNET_INTERNAL_MAC_ADDR_2_REG, tmp); +-} +- +-static void __devinit dnet_get_hwaddr(struct dnet *bp) +-{ +- u16 tmp; +- u8 addr[6]; +- +- /* +- * from MAC docs: +- * "Note that the MAC address is stored in the registers in Hexadecimal +- * form. For example, to set the MAC Address to: AC-DE-48-00-00-80 +- * would require writing 0xAC (octet 0) to address 0x0B (high byte of +- * Mac_addr[15:0]), 0xDE (octet 1) to address 0x0A (Low byte of +- * Mac_addr[15:0]), 0x48 (octet 2) to address 0x0D (high byte of +- * Mac_addr[15:0]), 0x00 (octet 3) to address 0x0C (Low byte of +- * Mac_addr[15:0]), 0x00 (octet 4) to address 0x0F (high byte of +- * Mac_addr[15:0]), and 0x80 (octet 5) to address * 0x0E (Low byte of +- * Mac_addr[15:0]). +- */ +- tmp = dnet_readw_mac(bp, DNET_INTERNAL_MAC_ADDR_0_REG); +- *((u16 *) addr) = be16_to_cpu(tmp); +- tmp = dnet_readw_mac(bp, DNET_INTERNAL_MAC_ADDR_1_REG); +- *((u16 *) (addr + 2)) = be16_to_cpu(tmp); +- tmp = dnet_readw_mac(bp, DNET_INTERNAL_MAC_ADDR_2_REG); +- *((u16 *) (addr + 4)) = be16_to_cpu(tmp); +- +- if (is_valid_ether_addr(addr)) +- memcpy(bp->dev->dev_addr, addr, sizeof(addr)); +-} +- +-static int dnet_mdio_read(struct mii_bus *bus, int mii_id, int regnum) +-{ +- struct dnet *bp = bus->priv; +- u16 value; +- +- while (!(dnet_readw_mac(bp, DNET_INTERNAL_GMII_MNG_CTL_REG) +- & DNET_INTERNAL_GMII_MNG_CMD_FIN)) +- cpu_relax(); +- +- /* only 5 bits allowed for phy-addr and reg_offset */ +- mii_id &= 0x1f; +- regnum &= 0x1f; +- +- /* prepare reg_value for a read */ +- value = (mii_id << 8); +- value |= regnum; +- +- /* write control word */ +- dnet_writew_mac(bp, DNET_INTERNAL_GMII_MNG_CTL_REG, value); +- +- /* wait for end of transfer */ +- while (!(dnet_readw_mac(bp, DNET_INTERNAL_GMII_MNG_CTL_REG) +- & DNET_INTERNAL_GMII_MNG_CMD_FIN)) +- cpu_relax(); +- +- value = dnet_readw_mac(bp, DNET_INTERNAL_GMII_MNG_DAT_REG); +- +- pr_debug("mdio_read %02x:%02x <- %04x\n", mii_id, regnum, value); +- +- return value; +-} +- +-static int dnet_mdio_write(struct mii_bus *bus, int mii_id, int regnum, +- u16 value) +-{ +- struct dnet *bp = bus->priv; +- u16 tmp; +- +- pr_debug("mdio_write %02x:%02x <- %04x\n", mii_id, regnum, value); +- +- while (!(dnet_readw_mac(bp, DNET_INTERNAL_GMII_MNG_CTL_REG) +- & DNET_INTERNAL_GMII_MNG_CMD_FIN)) +- cpu_relax(); +- +- /* prepare for a write operation */ +- tmp = (1 << 13); +- +- /* only 5 bits allowed for phy-addr and reg_offset */ +- mii_id &= 0x1f; +- regnum &= 0x1f; +- +- /* only 16 bits on data */ +- value &= 0xffff; +- +- /* prepare reg_value for a write */ +- tmp |= (mii_id << 8); +- tmp |= regnum; +- +- /* write data to write first */ +- dnet_writew_mac(bp, DNET_INTERNAL_GMII_MNG_DAT_REG, value); +- +- /* write control word */ +- dnet_writew_mac(bp, DNET_INTERNAL_GMII_MNG_CTL_REG, tmp); +- +- while (!(dnet_readw_mac(bp, DNET_INTERNAL_GMII_MNG_CTL_REG) +- & DNET_INTERNAL_GMII_MNG_CMD_FIN)) +- cpu_relax(); +- +- return 0; +-} +- +-static int dnet_mdio_reset(struct mii_bus *bus) +-{ +- return 0; +-} +- +-static void dnet_handle_link_change(struct net_device *dev) +-{ +- struct dnet *bp = netdev_priv(dev); +- struct phy_device *phydev = bp->phy_dev; +- unsigned long flags; +- u32 mode_reg, ctl_reg; +- +- int status_change = 0; +- +- spin_lock_irqsave(&bp->lock, flags); +- +- mode_reg = dnet_readw_mac(bp, DNET_INTERNAL_MODE_REG); +- ctl_reg = dnet_readw_mac(bp, DNET_INTERNAL_RXTX_CONTROL_REG); +- +- if (phydev->link) { +- if (bp->duplex != phydev->duplex) { +- if (phydev->duplex) +- ctl_reg &= +- ~(DNET_INTERNAL_RXTX_CONTROL_ENABLEHALFDUP); +- else +- ctl_reg |= +- DNET_INTERNAL_RXTX_CONTROL_ENABLEHALFDUP; +- +- bp->duplex = phydev->duplex; +- status_change = 1; +- } +- +- if (bp->speed != phydev->speed) { +- status_change = 1; +- switch (phydev->speed) { +- case 1000: +- mode_reg |= DNET_INTERNAL_MODE_GBITEN; +- break; +- case 100: +- case 10: +- mode_reg &= ~DNET_INTERNAL_MODE_GBITEN; +- break; +- default: +- printk(KERN_WARNING +- "%s: Ack! Speed (%d) is not " +- "10/100/1000!\n", dev->name, +- phydev->speed); +- break; +- } +- bp->speed = phydev->speed; +- } +- } +- +- if (phydev->link != bp->link) { +- if (phydev->link) { +- mode_reg |= +- (DNET_INTERNAL_MODE_RXEN | DNET_INTERNAL_MODE_TXEN); +- } else { +- mode_reg &= +- ~(DNET_INTERNAL_MODE_RXEN | +- DNET_INTERNAL_MODE_TXEN); +- bp->speed = 0; +- bp->duplex = -1; +- } +- bp->link = phydev->link; +- +- status_change = 1; +- } +- +- if (status_change) { +- dnet_writew_mac(bp, DNET_INTERNAL_RXTX_CONTROL_REG, ctl_reg); +- dnet_writew_mac(bp, DNET_INTERNAL_MODE_REG, mode_reg); +- } +- +- spin_unlock_irqrestore(&bp->lock, flags); +- +- if (status_change) { +- if (phydev->link) +- printk(KERN_INFO "%s: link up (%d/%s)\n", +- dev->name, phydev->speed, +- DUPLEX_FULL == phydev->duplex ? "Full" : "Half"); +- else +- printk(KERN_INFO "%s: link down\n", dev->name); +- } +-} +- +-static int dnet_mii_probe(struct net_device *dev) +-{ +- struct dnet *bp = netdev_priv(dev); +- struct phy_device *phydev = NULL; +- int phy_addr; +- +- /* find the first phy */ +- for (phy_addr = 0; phy_addr < PHY_MAX_ADDR; phy_addr++) { +- if (bp->mii_bus->phy_map[phy_addr]) { +- phydev = bp->mii_bus->phy_map[phy_addr]; +- break; +- } +- } +- +- if (!phydev) { +- printk(KERN_ERR "%s: no PHY found\n", dev->name); +- return -ENODEV; +- } +- +- /* TODO : add pin_irq */ +- +- /* attach the mac to the phy */ +- if (bp->capabilities & DNET_HAS_RMII) { +- phydev = phy_connect(dev, dev_name(&phydev->dev), +- &dnet_handle_link_change, 0, +- PHY_INTERFACE_MODE_RMII); +- } else { +- phydev = phy_connect(dev, dev_name(&phydev->dev), +- &dnet_handle_link_change, 0, +- PHY_INTERFACE_MODE_MII); +- } +- +- if (IS_ERR(phydev)) { +- printk(KERN_ERR "%s: Could not attach to PHY\n", dev->name); +- return PTR_ERR(phydev); +- } +- +- /* mask with MAC supported features */ +- if (bp->capabilities & DNET_HAS_GIGABIT) +- phydev->supported &= PHY_GBIT_FEATURES; +- else +- phydev->supported &= PHY_BASIC_FEATURES; +- +- phydev->supported |= SUPPORTED_Asym_Pause | SUPPORTED_Pause; +- +- phydev->advertising = phydev->supported; +- +- bp->link = 0; +- bp->speed = 0; +- bp->duplex = -1; +- bp->phy_dev = phydev; +- +- return 0; +-} +- +-static int dnet_mii_init(struct dnet *bp) +-{ +- int err, i; +- +- bp->mii_bus = mdiobus_alloc(); +- if (bp->mii_bus == NULL) +- return -ENOMEM; +- +- bp->mii_bus->name = "dnet_mii_bus"; +- bp->mii_bus->read = &dnet_mdio_read; +- bp->mii_bus->write = &dnet_mdio_write; +- bp->mii_bus->reset = &dnet_mdio_reset; +- +- snprintf(bp->mii_bus->id, MII_BUS_ID_SIZE, "%x", 0); +- +- bp->mii_bus->priv = bp; +- +- bp->mii_bus->irq = kmalloc(sizeof(int) * PHY_MAX_ADDR, GFP_KERNEL); +- if (!bp->mii_bus->irq) { +- err = -ENOMEM; +- goto err_out; +- } +- +- for (i = 0; i < PHY_MAX_ADDR; i++) +- bp->mii_bus->irq[i] = PHY_POLL; +- +- platform_set_drvdata(bp->dev, bp->mii_bus); +- +- if (mdiobus_register(bp->mii_bus)) { +- err = -ENXIO; +- goto err_out_free_mdio_irq; +- } +- +- if (dnet_mii_probe(bp->dev) != 0) { +- err = -ENXIO; +- goto err_out_unregister_bus; +- } +- +- return 0; +- +-err_out_unregister_bus: +- mdiobus_unregister(bp->mii_bus); +-err_out_free_mdio_irq: +- kfree(bp->mii_bus->irq); +-err_out: +- mdiobus_free(bp->mii_bus); +- return err; +-} +- +-/* For Neptune board: LINK1000 as Link LED and TX as activity LED */ +-int dnet_phy_marvell_fixup(struct phy_device *phydev) +-{ +- return phy_write(phydev, 0x18, 0x4148); +-} +- +-static void dnet_update_stats(struct dnet *bp) +-{ +- u32 __iomem *reg = bp->regs + DNET_RX_PKT_IGNR_CNT; +- u32 *p = &bp->hw_stats.rx_pkt_ignr; +- u32 *end = &bp->hw_stats.rx_byte + 1; +- +- WARN_ON((unsigned long)(end - p - 1) != +- (DNET_RX_BYTE_CNT - DNET_RX_PKT_IGNR_CNT) / 4); +- +- for (; p < end; p++, reg++) +- *p += readl(reg); +- +- reg = bp->regs + DNET_TX_UNICAST_CNT; +- p = &bp->hw_stats.tx_unicast; +- end = &bp->hw_stats.tx_byte + 1; +- +- WARN_ON((unsigned long)(end - p - 1) != +- (DNET_TX_BYTE_CNT - DNET_TX_UNICAST_CNT) / 4); +- +- for (; p < end; p++, reg++) +- *p += readl(reg); +-} +- +-static int dnet_poll(struct napi_struct *napi, int budget) +-{ +- struct dnet *bp = container_of(napi, struct dnet, napi); +- struct net_device *dev = bp->dev; +- int npackets = 0; +- unsigned int pkt_len; +- struct sk_buff *skb; +- unsigned int *data_ptr; +- u32 int_enable; +- u32 cmd_word; +- int i; +- +- while (npackets < budget) { +- /* +- * break out of while loop if there are no more +- * packets waiting +- */ +- if (!(dnet_readl(bp, RX_FIFO_WCNT) >> 16)) { +- napi_complete(napi); +- int_enable = dnet_readl(bp, INTR_ENB); +- int_enable |= DNET_INTR_SRC_RX_CMDFIFOAF; +- dnet_writel(bp, int_enable, INTR_ENB); +- return 0; +- } +- +- cmd_word = dnet_readl(bp, RX_LEN_FIFO); +- pkt_len = cmd_word & 0xFFFF; +- +- if (cmd_word & 0xDF180000) +- printk(KERN_ERR "%s packet receive error %x\n", +- __func__, cmd_word); +- +- skb = dev_alloc_skb(pkt_len + 5); +- if (skb != NULL) { +- /* Align IP on 16 byte boundaries */ +- skb_reserve(skb, 2); +- /* +- * 'skb_put()' points to the start of sk_buff +- * data area. +- */ +- data_ptr = (unsigned int *)skb_put(skb, pkt_len); +- for (i = 0; i < (pkt_len + 3) >> 2; i++) +- *data_ptr++ = dnet_readl(bp, RX_DATA_FIFO); +- skb->protocol = eth_type_trans(skb, dev); +- netif_receive_skb(skb); +- npackets++; +- } else +- printk(KERN_NOTICE +- "%s: No memory to allocate a sk_buff of " +- "size %u.\n", dev->name, pkt_len); +- } +- +- budget -= npackets; +- +- if (npackets < budget) { +- /* We processed all packets available. Tell NAPI it can +- * stop polling then re-enable rx interrupts */ +- napi_complete(napi); +- int_enable = dnet_readl(bp, INTR_ENB); +- int_enable |= DNET_INTR_SRC_RX_CMDFIFOAF; +- dnet_writel(bp, int_enable, INTR_ENB); +- return 0; +- } +- +- /* There are still packets waiting */ +- return 1; +-} +- +-static irqreturn_t dnet_interrupt(int irq, void *dev_id) +-{ +- struct net_device *dev = dev_id; +- struct dnet *bp = netdev_priv(dev); +- u32 int_src, int_enable, int_current; +- unsigned long flags; +- unsigned int handled = 0; +- +- spin_lock_irqsave(&bp->lock, flags); +- +- /* read and clear the DNET irq (clear on read) */ +- int_src = dnet_readl(bp, INTR_SRC); +- int_enable = dnet_readl(bp, INTR_ENB); +- int_current = int_src & int_enable; +- +- /* restart the queue if we had stopped it for TX fifo almost full */ +- if (int_current & DNET_INTR_SRC_TX_FIFOAE) { +- int_enable = dnet_readl(bp, INTR_ENB); +- int_enable &= ~DNET_INTR_ENB_TX_FIFOAE; +- dnet_writel(bp, int_enable, INTR_ENB); +- netif_wake_queue(dev); +- handled = 1; +- } +- +- /* RX FIFO error checking */ +- if (int_current & +- (DNET_INTR_SRC_RX_CMDFIFOFF | DNET_INTR_SRC_RX_DATAFIFOFF)) { +- printk(KERN_ERR "%s: RX fifo error %x, irq %x\n", __func__, +- dnet_readl(bp, RX_STATUS), int_current); +- /* we can only flush the RX FIFOs */ +- dnet_writel(bp, DNET_SYS_CTL_RXFIFOFLUSH, SYS_CTL); +- ndelay(500); +- dnet_writel(bp, 0, SYS_CTL); +- handled = 1; +- } +- +- /* TX FIFO error checking */ +- if (int_current & +- (DNET_INTR_SRC_TX_FIFOFULL | DNET_INTR_SRC_TX_DISCFRM)) { +- printk(KERN_ERR "%s: TX fifo error %x, irq %x\n", __func__, +- dnet_readl(bp, TX_STATUS), int_current); +- /* we can only flush the TX FIFOs */ +- dnet_writel(bp, DNET_SYS_CTL_TXFIFOFLUSH, SYS_CTL); +- ndelay(500); +- dnet_writel(bp, 0, SYS_CTL); +- handled = 1; +- } +- +- if (int_current & DNET_INTR_SRC_RX_CMDFIFOAF) { +- if (napi_schedule_prep(&bp->napi)) { +- /* +- * There's no point taking any more interrupts +- * until we have processed the buffers +- */ +- /* Disable Rx interrupts and schedule NAPI poll */ +- int_enable = dnet_readl(bp, INTR_ENB); +- int_enable &= ~DNET_INTR_SRC_RX_CMDFIFOAF; +- dnet_writel(bp, int_enable, INTR_ENB); +- __napi_schedule(&bp->napi); +- } +- handled = 1; +- } +- +- if (!handled) +- pr_debug("%s: irq %x remains\n", __func__, int_current); +- +- spin_unlock_irqrestore(&bp->lock, flags); +- +- return IRQ_RETVAL(handled); +-} +- +-#ifdef DEBUG +-static inline void dnet_print_skb(struct sk_buff *skb) +-{ +- int k; +- printk(KERN_DEBUG PFX "data:"); +- for (k = 0; k < skb->len; k++) +- printk(" %02x", (unsigned int)skb->data[k]); +- printk("\n"); +-} +-#else +-#define dnet_print_skb(skb) do {} while (0) +-#endif +- +-static int dnet_start_xmit(struct sk_buff *skb, struct net_device *dev) +-{ +- +- struct dnet *bp = netdev_priv(dev); +- u32 tx_status, irq_enable; +- unsigned int len, i, tx_cmd, wrsz; +- unsigned long flags; +- unsigned int *bufp; +- +- tx_status = dnet_readl(bp, TX_STATUS); +- +- pr_debug("start_xmit: len %u head %p data %p\n", +- skb->len, skb->head, skb->data); +- dnet_print_skb(skb); +- +- /* frame size (words) */ +- len = (skb->len + 3) >> 2; +- +- spin_lock_irqsave(&bp->lock, flags); +- +- tx_status = dnet_readl(bp, TX_STATUS); +- +- bufp = (unsigned int *)(((unsigned long) skb->data) & ~0x3UL); +- wrsz = (u32) skb->len + 3; +- wrsz += ((unsigned long) skb->data) & 0x3; +- wrsz >>= 2; +- tx_cmd = ((((unsigned long)(skb->data)) & 0x03) << 16) | (u32) skb->len; +- +- /* check if there is enough room for the current frame */ +- if (wrsz < (DNET_FIFO_SIZE - dnet_readl(bp, TX_FIFO_WCNT))) { +- for (i = 0; i < wrsz; i++) +- dnet_writel(bp, *bufp++, TX_DATA_FIFO); +- +- /* +- * inform MAC that a packet's written and ready to be +- * shipped out +- */ +- dnet_writel(bp, tx_cmd, TX_LEN_FIFO); +- } +- +- if (dnet_readl(bp, TX_FIFO_WCNT) > DNET_FIFO_TX_DATA_AF_TH) { +- netif_stop_queue(dev); +- tx_status = dnet_readl(bp, INTR_SRC); +- irq_enable = dnet_readl(bp, INTR_ENB); +- irq_enable |= DNET_INTR_ENB_TX_FIFOAE; +- dnet_writel(bp, irq_enable, INTR_ENB); +- } +- +- /* free the buffer */ +- dev_kfree_skb(skb); +- +- spin_unlock_irqrestore(&bp->lock, flags); +- +- dev->trans_start = jiffies; +- +- return 0; +-} +- +-static void dnet_reset_hw(struct dnet *bp) +-{ +- /* put ts_mac in IDLE state i.e. disable rx/tx */ +- dnet_writew_mac(bp, DNET_INTERNAL_MODE_REG, DNET_INTERNAL_MODE_FCEN); +- +- /* +- * RX FIFO almost full threshold: only cmd FIFO almost full is +- * implemented for RX side +- */ +- dnet_writel(bp, DNET_FIFO_RX_CMD_AF_TH, RX_FIFO_TH); +- /* +- * TX FIFO almost empty threshold: only data FIFO almost empty +- * is implemented for TX side +- */ +- dnet_writel(bp, DNET_FIFO_TX_DATA_AE_TH, TX_FIFO_TH); +- +- /* flush rx/tx fifos */ +- dnet_writel(bp, DNET_SYS_CTL_RXFIFOFLUSH | DNET_SYS_CTL_TXFIFOFLUSH, +- SYS_CTL); +- msleep(1); +- dnet_writel(bp, 0, SYS_CTL); +-} +- +-static void dnet_init_hw(struct dnet *bp) +-{ +- u32 config; +- +- dnet_reset_hw(bp); +- __dnet_set_hwaddr(bp); +- +- config = dnet_readw_mac(bp, DNET_INTERNAL_RXTX_CONTROL_REG); +- +- if (bp->dev->flags & IFF_PROMISC) +- /* Copy All Frames */ +- config |= DNET_INTERNAL_RXTX_CONTROL_ENPROMISC; +- if (!(bp->dev->flags & IFF_BROADCAST)) +- /* No BroadCast */ +- config |= DNET_INTERNAL_RXTX_CONTROL_RXMULTICAST; +- +- config |= DNET_INTERNAL_RXTX_CONTROL_RXPAUSE | +- DNET_INTERNAL_RXTX_CONTROL_RXBROADCAST | +- DNET_INTERNAL_RXTX_CONTROL_DROPCONTROL | +- DNET_INTERNAL_RXTX_CONTROL_DISCFXFCS; +- +- dnet_writew_mac(bp, DNET_INTERNAL_RXTX_CONTROL_REG, config); +- +- /* clear irq before enabling them */ +- config = dnet_readl(bp, INTR_SRC); +- +- /* enable RX/TX interrupt, recv packet ready interrupt */ +- dnet_writel(bp, DNET_INTR_ENB_GLOBAL_ENABLE | DNET_INTR_ENB_RX_SUMMARY | +- DNET_INTR_ENB_TX_SUMMARY | DNET_INTR_ENB_RX_FIFOERR | +- DNET_INTR_ENB_RX_ERROR | DNET_INTR_ENB_RX_FIFOFULL | +- DNET_INTR_ENB_TX_FIFOFULL | DNET_INTR_ENB_TX_DISCFRM | +- DNET_INTR_ENB_RX_PKTRDY, INTR_ENB); +-} +- +-static int dnet_open(struct net_device *dev) +-{ +- struct dnet *bp = netdev_priv(dev); +- +- /* if the phy is not yet register, retry later */ +- if (!bp->phy_dev) +- return -EAGAIN; +- +- if (!is_valid_ether_addr(dev->dev_addr)) +- return -EADDRNOTAVAIL; +- +- napi_enable(&bp->napi); +- dnet_init_hw(bp); +- +- phy_start_aneg(bp->phy_dev); +- +- /* schedule a link state check */ +- phy_start(bp->phy_dev); +- +- netif_start_queue(dev); +- +- return 0; +-} +- +-static int dnet_close(struct net_device *dev) +-{ +- struct dnet *bp = netdev_priv(dev); +- +- netif_stop_queue(dev); +- napi_disable(&bp->napi); +- +- if (bp->phy_dev) +- phy_stop(bp->phy_dev); +- +- dnet_reset_hw(bp); +- netif_carrier_off(dev); +- +- return 0; +-} +- +-static inline void dnet_print_pretty_hwstats(struct dnet_stats *hwstat) +-{ +- pr_debug("%s\n", __func__); +- pr_debug("----------------------------- RX statistics " +- "-------------------------------\n"); +- pr_debug("RX_PKT_IGNR_CNT %-8x\n", hwstat->rx_pkt_ignr); +- pr_debug("RX_LEN_CHK_ERR_CNT %-8x\n", hwstat->rx_len_chk_err); +- pr_debug("RX_LNG_FRM_CNT %-8x\n", hwstat->rx_lng_frm); +- pr_debug("RX_SHRT_FRM_CNT %-8x\n", hwstat->rx_shrt_frm); +- pr_debug("RX_IPG_VIOL_CNT %-8x\n", hwstat->rx_ipg_viol); +- pr_debug("RX_CRC_ERR_CNT %-8x\n", hwstat->rx_crc_err); +- pr_debug("RX_OK_PKT_CNT %-8x\n", hwstat->rx_ok_pkt); +- pr_debug("RX_CTL_FRM_CNT %-8x\n", hwstat->rx_ctl_frm); +- pr_debug("RX_PAUSE_FRM_CNT %-8x\n", hwstat->rx_pause_frm); +- pr_debug("RX_MULTICAST_CNT %-8x\n", hwstat->rx_multicast); +- pr_debug("RX_BROADCAST_CNT %-8x\n", hwstat->rx_broadcast); +- pr_debug("RX_VLAN_TAG_CNT %-8x\n", hwstat->rx_vlan_tag); +- pr_debug("RX_PRE_SHRINK_CNT %-8x\n", hwstat->rx_pre_shrink); +- pr_debug("RX_DRIB_NIB_CNT %-8x\n", hwstat->rx_drib_nib); +- pr_debug("RX_UNSUP_OPCD_CNT %-8x\n", hwstat->rx_unsup_opcd); +- pr_debug("RX_BYTE_CNT %-8x\n", hwstat->rx_byte); +- pr_debug("----------------------------- TX statistics " +- "-------------------------------\n"); +- pr_debug("TX_UNICAST_CNT %-8x\n", hwstat->tx_unicast); +- pr_debug("TX_PAUSE_FRM_CNT %-8x\n", hwstat->tx_pause_frm); +- pr_debug("TX_MULTICAST_CNT %-8x\n", hwstat->tx_multicast); +- pr_debug("TX_BRDCAST_CNT %-8x\n", hwstat->tx_brdcast); +- pr_debug("TX_VLAN_TAG_CNT %-8x\n", hwstat->tx_vlan_tag); +- pr_debug("TX_BAD_FCS_CNT %-8x\n", hwstat->tx_bad_fcs); +- pr_debug("TX_JUMBO_CNT %-8x\n", hwstat->tx_jumbo); +- pr_debug("TX_BYTE_CNT %-8x\n", hwstat->tx_byte); +-} +- +-static struct net_device_stats *dnet_get_stats(struct net_device *dev) +-{ +- +- struct dnet *bp = netdev_priv(dev); +- struct net_device_stats *nstat = &dev->stats; +- struct dnet_stats *hwstat = &bp->hw_stats; +- +- /* read stats from hardware */ +- dnet_update_stats(bp); +- +- /* Convert HW stats into netdevice stats */ +- nstat->rx_errors = (hwstat->rx_len_chk_err + +- hwstat->rx_lng_frm + hwstat->rx_shrt_frm + +- /* ignore IGP violation error +- hwstat->rx_ipg_viol + */ +- hwstat->rx_crc_err + +- hwstat->rx_pre_shrink + +- hwstat->rx_drib_nib + hwstat->rx_unsup_opcd); +- nstat->tx_errors = hwstat->tx_bad_fcs; +- nstat->rx_length_errors = (hwstat->rx_len_chk_err + +- hwstat->rx_lng_frm + +- hwstat->rx_shrt_frm + hwstat->rx_pre_shrink); +- nstat->rx_crc_errors = hwstat->rx_crc_err; +- nstat->rx_frame_errors = hwstat->rx_pre_shrink + hwstat->rx_drib_nib; +- nstat->rx_packets = hwstat->rx_ok_pkt; +- nstat->tx_packets = (hwstat->tx_unicast + +- hwstat->tx_multicast + hwstat->tx_brdcast); +- nstat->rx_bytes = hwstat->rx_byte; +- nstat->tx_bytes = hwstat->tx_byte; +- nstat->multicast = hwstat->rx_multicast; +- nstat->rx_missed_errors = hwstat->rx_pkt_ignr; +- +- dnet_print_pretty_hwstats(hwstat); +- +- return nstat; +-} +- +-static int dnet_get_settings(struct net_device *dev, struct ethtool_cmd *cmd) +-{ +- struct dnet *bp = netdev_priv(dev); +- struct phy_device *phydev = bp->phy_dev; +- +- if (!phydev) +- return -ENODEV; +- +- return phy_ethtool_gset(phydev, cmd); +-} +- +-static int dnet_set_settings(struct net_device *dev, struct ethtool_cmd *cmd) +-{ +- struct dnet *bp = netdev_priv(dev); +- struct phy_device *phydev = bp->phy_dev; +- +- if (!phydev) +- return -ENODEV; +- +- return phy_ethtool_sset(phydev, cmd); +-} +- +-static int dnet_ioctl(struct net_device *dev, struct ifreq *rq, int cmd) +-{ +- struct dnet *bp = netdev_priv(dev); +- struct phy_device *phydev = bp->phy_dev; +- +- if (!netif_running(dev)) +- return -EINVAL; +- +- if (!phydev) +- return -ENODEV; +- +- return phy_mii_ioctl(phydev, if_mii(rq), cmd); +-} +- +-static void dnet_get_drvinfo(struct net_device *dev, +- struct ethtool_drvinfo *info) +-{ +- strcpy(info->driver, DRV_NAME); +- strcpy(info->version, DRV_VERSION); +- strcpy(info->bus_info, "0"); +-} +- +-static const struct ethtool_ops dnet_ethtool_ops = { +- .get_settings = dnet_get_settings, +- .set_settings = dnet_set_settings, +- .get_drvinfo = dnet_get_drvinfo, +- .get_link = ethtool_op_get_link, +-}; +- +-static const struct net_device_ops dnet_netdev_ops = { +- .ndo_open = dnet_open, +- .ndo_stop = dnet_close, +- .ndo_get_stats = dnet_get_stats, +- .ndo_start_xmit = dnet_start_xmit, +- .ndo_do_ioctl = dnet_ioctl, +- .ndo_set_mac_address = eth_mac_addr, +- .ndo_validate_addr = eth_validate_addr, +- .ndo_change_mtu = eth_change_mtu, +-}; +- +-static int __devinit dnet_probe(struct platform_device *pdev) +-{ +- struct resource *res; +- struct net_device *dev; +- struct dnet *bp; +- struct phy_device *phydev; +- int err = -ENXIO; +- unsigned int mem_base, mem_size, irq; +- +- res = platform_get_resource(pdev, IORESOURCE_MEM, 0); +- if (!res) { +- dev_err(&pdev->dev, "no mmio resource defined\n"); +- goto err_out; +- } +- mem_base = res->start; +- mem_size = resource_size(res); +- irq = platform_get_irq(pdev, 0); +- +- if (!request_mem_region(mem_base, mem_size, DRV_NAME)) { +- dev_err(&pdev->dev, "no memory region available\n"); +- err = -EBUSY; +- goto err_out; +- } +- +- err = -ENOMEM; +- dev = alloc_etherdev(sizeof(*bp)); +- if (!dev) { +- dev_err(&pdev->dev, "etherdev alloc failed, aborting.\n"); +- goto err_out; +- } +- +- /* TODO: Actually, we have some interesting features... */ +- dev->features |= 0; +- +- bp = netdev_priv(dev); +- bp->dev = dev; +- +- SET_NETDEV_DEV(dev, &pdev->dev); +- +- spin_lock_init(&bp->lock); +- +- bp->regs = ioremap(mem_base, mem_size); +- if (!bp->regs) { +- dev_err(&pdev->dev, "failed to map registers, aborting.\n"); +- err = -ENOMEM; +- goto err_out_free_dev; +- } +- +- dev->irq = irq; +- err = request_irq(dev->irq, dnet_interrupt, 0, DRV_NAME, dev); +- if (err) { +- dev_err(&pdev->dev, "Unable to request IRQ %d (error %d)\n", +- irq, err); +- goto err_out_iounmap; +- } +- +- dev->netdev_ops = &dnet_netdev_ops; +- netif_napi_add(dev, &bp->napi, dnet_poll, 64); +- dev->ethtool_ops = &dnet_ethtool_ops; +- +- dev->base_addr = (unsigned long)bp->regs; +- +- bp->capabilities = dnet_readl(bp, VERCAPS) & DNET_CAPS_MASK; +- +- dnet_get_hwaddr(bp); +- +- if (!is_valid_ether_addr(dev->dev_addr)) { +- /* choose a random ethernet address */ +- random_ether_addr(dev->dev_addr); +- __dnet_set_hwaddr(bp); +- } +- +- err = register_netdev(dev); +- if (err) { +- dev_err(&pdev->dev, "Cannot register net device, aborting.\n"); +- goto err_out_free_irq; +- } +- +- /* register the PHY board fixup (for Marvell 88E1111) */ +- err = phy_register_fixup_for_uid(0x01410cc0, 0xfffffff0, +- dnet_phy_marvell_fixup); +- /* we can live without it, so just issue a warning */ +- if (err) +- dev_warn(&pdev->dev, "Cannot register PHY board fixup.\n"); +- +- if (dnet_mii_init(bp) != 0) +- goto err_out_unregister_netdev; +- +- dev_info(&pdev->dev, "Dave DNET at 0x%p (0x%08x) irq %d %pM\n", +- bp->regs, mem_base, dev->irq, dev->dev_addr); +- dev_info(&pdev->dev, "has %smdio, %sirq, %sgigabit, %sdma \n", +- (bp->capabilities & DNET_HAS_MDIO) ? "" : "no ", +- (bp->capabilities & DNET_HAS_IRQ) ? "" : "no ", +- (bp->capabilities & DNET_HAS_GIGABIT) ? "" : "no ", +- (bp->capabilities & DNET_HAS_DMA) ? "" : "no "); +- phydev = bp->phy_dev; +- dev_info(&pdev->dev, "attached PHY driver [%s] " +- "(mii_bus:phy_addr=%s, irq=%d)\n", +- phydev->drv->name, dev_name(&phydev->dev), phydev->irq); +- +- return 0; +- +-err_out_unregister_netdev: +- unregister_netdev(dev); +-err_out_free_irq: +- free_irq(dev->irq, dev); +-err_out_iounmap: +- iounmap(bp->regs); +-err_out_free_dev: +- free_netdev(dev); +-err_out: +- return err; +-} +- +-static int __devexit dnet_remove(struct platform_device *pdev) +-{ +- +- struct net_device *dev; +- struct dnet *bp; +- +- dev = platform_get_drvdata(pdev); +- +- if (dev) { +- bp = netdev_priv(dev); +- if (bp->phy_dev) +- phy_disconnect(bp->phy_dev); +- mdiobus_unregister(bp->mii_bus); +- kfree(bp->mii_bus->irq); +- mdiobus_free(bp->mii_bus); +- unregister_netdev(dev); +- free_irq(dev->irq, dev); +- iounmap(bp->regs); +- free_netdev(dev); +- } +- +- return 0; +-} +- +-static struct platform_driver dnet_driver = { +- .probe = dnet_probe, +- .remove = __devexit_p(dnet_remove), +- .driver = { +- .name = "dnet", +- }, +-}; +- +-static int __init dnet_init(void) +-{ +- return platform_driver_register(&dnet_driver); +-} +- +-static void __exit dnet_exit(void) +-{ +- platform_driver_unregister(&dnet_driver); +-} +- +-module_init(dnet_init); +-module_exit(dnet_exit); +- +-MODULE_LICENSE("GPL"); +-MODULE_DESCRIPTION("Dave DNET Ethernet driver"); +-MODULE_AUTHOR("Ilya Yanok <yanok@emcraft.com>, " +- "Matteo Vit <matteo.vit@dave.eu>"); +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/drivers/net/dnet.h linux-2.6.29-rc3.owrt/drivers/net/dnet.h +--- linux-2.6.29.owrt/drivers/net/dnet.h 2009-05-10 22:04:38.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/drivers/net/dnet.h 1970-01-01 01:00:00.000000000 +0100 +@@ -1,225 +0,0 @@ +-/* +- * Dave DNET Ethernet Controller driver +- * +- * Copyright (C) 2008 Dave S.r.l. <www.dave.eu> +- * +- * 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 _DNET_H +-#define _DNET_H +- +-#define DRV_NAME "dnet" +-#define DRV_VERSION "0.9.1" +-#define PFX DRV_NAME ": " +- +-/* Register access macros */ +-#define dnet_writel(port, value, reg) \ +- writel((value), (port)->regs + DNET_##reg) +-#define dnet_readl(port, reg) readl((port)->regs + DNET_##reg) +- +-/* ALL DNET FIFO REGISTERS */ +-#define DNET_RX_LEN_FIFO 0x000 /* RX_LEN_FIFO */ +-#define DNET_RX_DATA_FIFO 0x004 /* RX_DATA_FIFO */ +-#define DNET_TX_LEN_FIFO 0x008 /* TX_LEN_FIFO */ +-#define DNET_TX_DATA_FIFO 0x00C /* TX_DATA_FIFO */ +- +-/* ALL DNET CONTROL/STATUS REGISTERS OFFSETS */ +-#define DNET_VERCAPS 0x100 /* VERCAPS */ +-#define DNET_INTR_SRC 0x104 /* INTR_SRC */ +-#define DNET_INTR_ENB 0x108 /* INTR_ENB */ +-#define DNET_RX_STATUS 0x10C /* RX_STATUS */ +-#define DNET_TX_STATUS 0x110 /* TX_STATUS */ +-#define DNET_RX_FRAMES_CNT 0x114 /* RX_FRAMES_CNT */ +-#define DNET_TX_FRAMES_CNT 0x118 /* TX_FRAMES_CNT */ +-#define DNET_RX_FIFO_TH 0x11C /* RX_FIFO_TH */ +-#define DNET_TX_FIFO_TH 0x120 /* TX_FIFO_TH */ +-#define DNET_SYS_CTL 0x124 /* SYS_CTL */ +-#define DNET_PAUSE_TMR 0x128 /* PAUSE_TMR */ +-#define DNET_RX_FIFO_WCNT 0x12C /* RX_FIFO_WCNT */ +-#define DNET_TX_FIFO_WCNT 0x130 /* TX_FIFO_WCNT */ +- +-/* ALL DNET MAC REGISTERS */ +-#define DNET_MACREG_DATA 0x200 /* Mac-Reg Data */ +-#define DNET_MACREG_ADDR 0x204 /* Mac-Reg Addr */ +- +-/* ALL DNET RX STATISTICS COUNTERS */ +-#define DNET_RX_PKT_IGNR_CNT 0x300 +-#define DNET_RX_LEN_CHK_ERR_CNT 0x304 +-#define DNET_RX_LNG_FRM_CNT 0x308 +-#define DNET_RX_SHRT_FRM_CNT 0x30C +-#define DNET_RX_IPG_VIOL_CNT 0x310 +-#define DNET_RX_CRC_ERR_CNT 0x314 +-#define DNET_RX_OK_PKT_CNT 0x318 +-#define DNET_RX_CTL_FRM_CNT 0x31C +-#define DNET_RX_PAUSE_FRM_CNT 0x320 +-#define DNET_RX_MULTICAST_CNT 0x324 +-#define DNET_RX_BROADCAST_CNT 0x328 +-#define DNET_RX_VLAN_TAG_CNT 0x32C +-#define DNET_RX_PRE_SHRINK_CNT 0x330 +-#define DNET_RX_DRIB_NIB_CNT 0x334 +-#define DNET_RX_UNSUP_OPCD_CNT 0x338 +-#define DNET_RX_BYTE_CNT 0x33C +- +-/* DNET TX STATISTICS COUNTERS */ +-#define DNET_TX_UNICAST_CNT 0x400 +-#define DNET_TX_PAUSE_FRM_CNT 0x404 +-#define DNET_TX_MULTICAST_CNT 0x408 +-#define DNET_TX_BRDCAST_CNT 0x40C +-#define DNET_TX_VLAN_TAG_CNT 0x410 +-#define DNET_TX_BAD_FCS_CNT 0x414 +-#define DNET_TX_JUMBO_CNT 0x418 +-#define DNET_TX_BYTE_CNT 0x41C +- +-/* SOME INTERNAL MAC-CORE REGISTER */ +-#define DNET_INTERNAL_MODE_REG 0x0 +-#define DNET_INTERNAL_RXTX_CONTROL_REG 0x2 +-#define DNET_INTERNAL_MAX_PKT_SIZE_REG 0x4 +-#define DNET_INTERNAL_IGP_REG 0x8 +-#define DNET_INTERNAL_MAC_ADDR_0_REG 0xa +-#define DNET_INTERNAL_MAC_ADDR_1_REG 0xc +-#define DNET_INTERNAL_MAC_ADDR_2_REG 0xe +-#define DNET_INTERNAL_TX_RX_STS_REG 0x12 +-#define DNET_INTERNAL_GMII_MNG_CTL_REG 0x14 +-#define DNET_INTERNAL_GMII_MNG_DAT_REG 0x16 +- +-#define DNET_INTERNAL_GMII_MNG_CMD_FIN (1 << 14) +- +-#define DNET_INTERNAL_WRITE (1 << 31) +- +-/* MAC-CORE REGISTER FIELDS */ +- +-/* MAC-CORE MODE REGISTER FIELDS */ +-#define DNET_INTERNAL_MODE_GBITEN (1 << 0) +-#define DNET_INTERNAL_MODE_FCEN (1 << 1) +-#define DNET_INTERNAL_MODE_RXEN (1 << 2) +-#define DNET_INTERNAL_MODE_TXEN (1 << 3) +- +-/* MAC-CORE RXTX CONTROL REGISTER FIELDS */ +-#define DNET_INTERNAL_RXTX_CONTROL_RXSHORTFRAME (1 << 8) +-#define DNET_INTERNAL_RXTX_CONTROL_RXBROADCAST (1 << 7) +-#define DNET_INTERNAL_RXTX_CONTROL_RXMULTICAST (1 << 4) +-#define DNET_INTERNAL_RXTX_CONTROL_RXPAUSE (1 << 3) +-#define DNET_INTERNAL_RXTX_CONTROL_DISTXFCS (1 << 2) +-#define DNET_INTERNAL_RXTX_CONTROL_DISCFXFCS (1 << 1) +-#define DNET_INTERNAL_RXTX_CONTROL_ENPROMISC (1 << 0) +-#define DNET_INTERNAL_RXTX_CONTROL_DROPCONTROL (1 << 6) +-#define DNET_INTERNAL_RXTX_CONTROL_ENABLEHALFDUP (1 << 5) +- +-/* SYSTEM CONTROL REGISTER FIELDS */ +-#define DNET_SYS_CTL_IGNORENEXTPKT (1 << 0) +-#define DNET_SYS_CTL_SENDPAUSE (1 << 2) +-#define DNET_SYS_CTL_RXFIFOFLUSH (1 << 3) +-#define DNET_SYS_CTL_TXFIFOFLUSH (1 << 4) +- +-/* TX STATUS REGISTER FIELDS */ +-#define DNET_TX_STATUS_FIFO_ALMOST_EMPTY (1 << 2) +-#define DNET_TX_STATUS_FIFO_ALMOST_FULL (1 << 1) +- +-/* INTERRUPT SOURCE REGISTER FIELDS */ +-#define DNET_INTR_SRC_TX_PKTSENT (1 << 0) +-#define DNET_INTR_SRC_TX_FIFOAF (1 << 1) +-#define DNET_INTR_SRC_TX_FIFOAE (1 << 2) +-#define DNET_INTR_SRC_TX_DISCFRM (1 << 3) +-#define DNET_INTR_SRC_TX_FIFOFULL (1 << 4) +-#define DNET_INTR_SRC_RX_CMDFIFOAF (1 << 8) +-#define DNET_INTR_SRC_RX_CMDFIFOFF (1 << 9) +-#define DNET_INTR_SRC_RX_DATAFIFOFF (1 << 10) +-#define DNET_INTR_SRC_TX_SUMMARY (1 << 16) +-#define DNET_INTR_SRC_RX_SUMMARY (1 << 17) +-#define DNET_INTR_SRC_PHY (1 << 19) +- +-/* INTERRUPT ENABLE REGISTER FIELDS */ +-#define DNET_INTR_ENB_TX_PKTSENT (1 << 0) +-#define DNET_INTR_ENB_TX_FIFOAF (1 << 1) +-#define DNET_INTR_ENB_TX_FIFOAE (1 << 2) +-#define DNET_INTR_ENB_TX_DISCFRM (1 << 3) +-#define DNET_INTR_ENB_TX_FIFOFULL (1 << 4) +-#define DNET_INTR_ENB_RX_PKTRDY (1 << 8) +-#define DNET_INTR_ENB_RX_FIFOAF (1 << 9) +-#define DNET_INTR_ENB_RX_FIFOERR (1 << 10) +-#define DNET_INTR_ENB_RX_ERROR (1 << 11) +-#define DNET_INTR_ENB_RX_FIFOFULL (1 << 12) +-#define DNET_INTR_ENB_RX_FIFOAE (1 << 13) +-#define DNET_INTR_ENB_TX_SUMMARY (1 << 16) +-#define DNET_INTR_ENB_RX_SUMMARY (1 << 17) +-#define DNET_INTR_ENB_GLOBAL_ENABLE (1 << 18) +- +-/* default values: +- * almost empty = less than one full sized ethernet frame (no jumbo) inside +- * the fifo almost full = can write less than one full sized ethernet frame +- * (no jumbo) inside the fifo +- */ +-#define DNET_CFG_TX_FIFO_FULL_THRES 25 +-#define DNET_CFG_RX_FIFO_FULL_THRES 20 +- +-/* +- * Capabilities. Used by the driver to know the capabilities that the ethernet +- * controller inside the FPGA have. +- */ +- +-#define DNET_HAS_MDIO (1 << 0) +-#define DNET_HAS_IRQ (1 << 1) +-#define DNET_HAS_GIGABIT (1 << 2) +-#define DNET_HAS_DMA (1 << 3) +- +-#define DNET_HAS_MII (1 << 4) /* or GMII */ +-#define DNET_HAS_RMII (1 << 5) /* or RGMII */ +- +-#define DNET_CAPS_MASK 0xFFFF +- +-#define DNET_FIFO_SIZE 1024 /* 1K x 32 bit */ +-#define DNET_FIFO_TX_DATA_AF_TH (DNET_FIFO_SIZE - 384) /* 384 = 1536 / 4 */ +-#define DNET_FIFO_TX_DATA_AE_TH 384 +- +-#define DNET_FIFO_RX_CMD_AF_TH (1 << 16) /* just one frame inside the FIFO */ +- +-/* +- * Hardware-collected statistics. +- */ +-struct dnet_stats { +- u32 rx_pkt_ignr; +- u32 rx_len_chk_err; +- u32 rx_lng_frm; +- u32 rx_shrt_frm; +- u32 rx_ipg_viol; +- u32 rx_crc_err; +- u32 rx_ok_pkt; +- u32 rx_ctl_frm; +- u32 rx_pause_frm; +- u32 rx_multicast; +- u32 rx_broadcast; +- u32 rx_vlan_tag; +- u32 rx_pre_shrink; +- u32 rx_drib_nib; +- u32 rx_unsup_opcd; +- u32 rx_byte; +- u32 tx_unicast; +- u32 tx_pause_frm; +- u32 tx_multicast; +- u32 tx_brdcast; +- u32 tx_vlan_tag; +- u32 tx_bad_fcs; +- u32 tx_jumbo; +- u32 tx_byte; +-}; +- +-struct dnet { +- void __iomem *regs; +- spinlock_t lock; +- struct platform_device *pdev; +- struct net_device *dev; +- struct dnet_stats hw_stats; +- unsigned int capabilities; /* read from FPGA */ +- struct napi_struct napi; +- +- /* PHY stuff */ +- struct mii_bus *mii_bus; +- struct phy_device *phy_dev; +- unsigned int link; +- unsigned int speed; +- unsigned int duplex; +-}; +- +-#endif /* _DNET_H */ +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/drivers/net/e1000/e1000_main.c linux-2.6.29-rc3.owrt/drivers/net/e1000/e1000_main.c +--- linux-2.6.29.owrt/drivers/net/e1000/e1000_main.c 2009-05-10 22:04:38.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/drivers/net/e1000/e1000_main.c 2009-05-10 23:48:28.000000000 +0200 +@@ -31,7 +31,7 @@ + + char e1000_driver_name[] = "e1000"; + static char e1000_driver_string[] = "Intel(R) PRO/1000 Network Driver"; +-#define DRV_VERSION "7.3.21-k3-NAPI" ++#define DRV_VERSION "7.3.20-k3-NAPI" + const char e1000_driver_version[] = DRV_VERSION; + static const char e1000_copyright[] = "Copyright (c) 1999-2006 Intel Corporation."; + +@@ -940,7 +940,7 @@ + err = pci_enable_device(pdev); + } else { + bars = pci_select_bars(pdev, IORESOURCE_MEM); +- err = pci_enable_device_mem(pdev); ++ err = pci_enable_device(pdev); + } + if (err) + return err; +@@ -3712,7 +3712,7 @@ + struct e1000_hw *hw = &adapter->hw; + u32 rctl, icr = er32(ICR); + +- if (unlikely((!icr) || test_bit(__E1000_RESETTING, &adapter->flags))) ++ if (unlikely(!icr)) + return IRQ_NONE; /* Not our interrupt */ + + /* IMS will not auto-mask if INT_ASSERTED is not set, and if it is +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/drivers/net/forcedeth.c linux-2.6.29-rc3.owrt/drivers/net/forcedeth.c +--- linux-2.6.29.owrt/drivers/net/forcedeth.c 2009-05-10 22:04:38.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/drivers/net/forcedeth.c 2009-05-10 23:48:28.000000000 +0200 +@@ -6011,20 +6011,9 @@ + if (netif_running(dev)) + nv_close(dev); + +- /* +- * Restore the MAC so a kernel started by kexec won't get confused. +- * If we really go for poweroff, we must not restore the MAC, +- * otherwise the MAC for WOL will be reversed at least on some boards. +- */ +- if (system_state != SYSTEM_POWER_OFF) { +- nv_restore_mac_addr(pdev); +- } ++ nv_restore_mac_addr(pdev); + + pci_disable_device(pdev); +- /* +- * Apparently it is not possible to reinitialise from D3 hot, +- * only put the device into D3 if we really go for poweroff. +- */ + if (system_state == SYSTEM_POWER_OFF) { + if (pci_enable_wake(pdev, PCI_D3cold, np->wolenabled)) + pci_enable_wake(pdev, PCI_D3hot, np->wolenabled); +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/drivers/net/gianfar.c linux-2.6.29-rc3.owrt/drivers/net/gianfar.c +--- linux-2.6.29.owrt/drivers/net/gianfar.c 2009-05-10 22:04:38.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/drivers/net/gianfar.c 2009-05-10 23:48:28.000000000 +0200 +@@ -351,9 +351,6 @@ + /* Reset MAC layer */ + gfar_write(&priv->regs->maccfg1, MACCFG1_SOFT_RESET); + +- /* We need to delay at least 3 TX clocks */ +- udelay(2); +- + tempval = (MACCFG1_TX_FLOW | MACCFG1_RX_FLOW); + gfar_write(&priv->regs->maccfg1, tempval); + +@@ -1284,7 +1281,7 @@ + spin_lock_irqsave(&priv->txlock, flags); + + /* check if there is space to queue this packet */ +- if ((nr_frags+1) > priv->num_txbdfree) { ++ if (nr_frags > priv->num_txbdfree) { + /* no space, stop the queue */ + netif_stop_queue(dev); + dev->stats.tx_fifo_errors++; +@@ -1629,12 +1626,6 @@ + if (netif_rx_schedule_prep(&priv->napi)) { + gfar_write(&priv->regs->imask, IMASK_RTX_DISABLED); + __netif_rx_schedule(&priv->napi); +- } else { +- /* +- * Clear IEVENT, so interrupts aren't called again +- * because of the packets that have already arrived. +- */ +- gfar_write(&priv->regs->ievent, IEVENT_RTX_MASK); + } + + spin_unlock(&priv->rxlock); +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/drivers/net/gianfar.h linux-2.6.29-rc3.owrt/drivers/net/gianfar.h +--- linux-2.6.29.owrt/drivers/net/gianfar.h 2009-05-10 22:04:38.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/drivers/net/gianfar.h 2009-05-10 23:48:28.000000000 +0200 +@@ -312,7 +312,7 @@ + #define ATTRELI_EI(x) (x) + + #define BD_LFLAG(flags) ((flags) << 16) +-#define BD_LENGTH_MASK 0x0000ffff ++#define BD_LENGTH_MASK 0x00ff + + /* TxBD status field bits */ + #define TXBD_READY 0x8000 +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/drivers/net/gianfar_mii.c linux-2.6.29-rc3.owrt/drivers/net/gianfar_mii.c +--- linux-2.6.29.owrt/drivers/net/gianfar_mii.c 2009-05-10 22:04:38.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/drivers/net/gianfar_mii.c 2009-05-10 23:48:28.000000000 +0200 +@@ -234,8 +234,6 @@ + if (NULL == new_bus) + return -ENOMEM; + +- device_init_wakeup(&ofdev->dev, 1); +- + new_bus->name = "Gianfar MII Bus", + new_bus->read = &gfar_mdio_read, + new_bus->write = &gfar_mdio_write, +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/drivers/net/hp-plus.c linux-2.6.29-rc3.owrt/drivers/net/hp-plus.c +--- linux-2.6.29.owrt/drivers/net/hp-plus.c 2009-05-10 22:04:38.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/drivers/net/hp-plus.c 2009-05-10 23:48:28.000000000 +0200 +@@ -467,7 +467,7 @@ + if (this_dev != 0) break; /* only autoprobe 1st one */ + printk(KERN_NOTICE "hp-plus.c: Presently autoprobing (not recommended) for a single card.\n"); + } +- dev = alloc_eip_netdev(); ++ dev = alloc_ei_netdev(); + if (!dev) + break; + dev->irq = irq[this_dev]; +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/drivers/net/ibm_newemac/core.c linux-2.6.29-rc3.owrt/drivers/net/ibm_newemac/core.c +--- linux-2.6.29.owrt/drivers/net/ibm_newemac/core.c 2009-05-10 22:04:38.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/drivers/net/ibm_newemac/core.c 2009-05-10 23:48:28.000000000 +0200 +@@ -2594,9 +2594,6 @@ + if (of_device_is_compatible(np, "ibm,emac-460ex") || + of_device_is_compatible(np, "ibm,emac-460gt")) + dev->features |= EMAC_FTR_460EX_PHY_CLK_FIX; +- if (of_device_is_compatible(np, "ibm,emac-405ex") || +- of_device_is_compatible(np, "ibm,emac-405exr")) +- dev->features |= EMAC_FTR_440EP_PHY_CLK_FIX; + } else if (of_device_is_compatible(np, "ibm,emac4")) { + dev->features |= EMAC_FTR_EMAC4; + if (of_device_is_compatible(np, "ibm,emac-440gx")) +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/drivers/net/ibm_newemac/phy.c linux-2.6.29-rc3.owrt/drivers/net/ibm_newemac/phy.c +--- linux-2.6.29.owrt/drivers/net/ibm_newemac/phy.c 2009-05-10 22:04:38.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/drivers/net/ibm_newemac/phy.c 2009-05-10 23:48:28.000000000 +0200 +@@ -60,7 +60,7 @@ + + udelay(300); + +- while (--limit) { ++ while (limit--) { + val = phy_read(phy, MII_BMCR); + if (val >= 0 && (val & BMCR_RESET) == 0) + break; +@@ -84,7 +84,7 @@ + + udelay(300); + +- while (--limit) { ++ while (limit--) { + val = gpcs_phy_read(phy, MII_BMCR); + if (val >= 0 && (val & BMCR_RESET) == 0) + break; +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/drivers/net/igb/e1000_82575.c linux-2.6.29-rc3.owrt/drivers/net/igb/e1000_82575.c +--- linux-2.6.29.owrt/drivers/net/igb/e1000_82575.c 2009-05-10 22:04:38.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/drivers/net/igb/e1000_82575.c 2009-05-10 23:48:28.000000000 +0200 +@@ -699,18 +699,11 @@ + + /* SGMII link check is done through the PCS register. */ + if ((hw->phy.media_type != e1000_media_type_copper) || +- (igb_sgmii_active_82575(hw))) { ++ (igb_sgmii_active_82575(hw))) + ret_val = igb_get_pcs_speed_and_duplex_82575(hw, &speed, + &duplex); +- /* +- * Use this flag to determine if link needs to be checked or +- * not. If we have link clear the flag so that we do not +- * continue to check for link. +- */ +- hw->mac.get_link_status = !hw->mac.serdes_has_link; +- } else { ++ else + ret_val = igb_check_for_copper_link(hw); +- } + + return ret_val; + } +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/drivers/net/igb/igb.h linux-2.6.29-rc3.owrt/drivers/net/igb/igb.h +--- linux-2.6.29.owrt/drivers/net/igb/igb.h 2009-05-10 22:04:38.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/drivers/net/igb/igb.h 2009-05-10 23:48:28.000000000 +0200 +@@ -300,10 +300,11 @@ + + #define IGB_FLAG_HAS_MSI (1 << 0) + #define IGB_FLAG_MSI_ENABLE (1 << 1) +-#define IGB_FLAG_DCA_ENABLED (1 << 2) +-#define IGB_FLAG_IN_NETPOLL (1 << 3) +-#define IGB_FLAG_QUAD_PORT_A (1 << 4) +-#define IGB_FLAG_NEED_CTX_IDX (1 << 5) ++#define IGB_FLAG_HAS_DCA (1 << 2) ++#define IGB_FLAG_DCA_ENABLED (1 << 3) ++#define IGB_FLAG_IN_NETPOLL (1 << 5) ++#define IGB_FLAG_QUAD_PORT_A (1 << 6) ++#define IGB_FLAG_NEED_CTX_IDX (1 << 7) + + enum e1000_state_t { + __IGB_TESTING, +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/drivers/net/igb/igb_main.c linux-2.6.29-rc3.owrt/drivers/net/igb/igb_main.c +--- linux-2.6.29.owrt/drivers/net/igb/igb_main.c 2009-05-10 22:04:38.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/drivers/net/igb/igb_main.c 2009-05-10 23:48:28.000000000 +0200 +@@ -206,11 +206,10 @@ + + global_quad_port_a = 0; + ++ ret = pci_register_driver(&igb_driver); + #ifdef CONFIG_IGB_DCA + dca_register_notify(&dca_notifier); + #endif +- +- ret = pci_register_driver(&igb_driver); + return ret; + } + +@@ -1023,10 +1022,11 @@ + struct net_device *netdev; + struct igb_adapter *adapter; + struct e1000_hw *hw; ++ struct pci_dev *us_dev; + const struct e1000_info *ei = igb_info_tbl[ent->driver_data]; + unsigned long mmio_start, mmio_len; +- int i, err, pci_using_dac; +- u16 eeprom_data = 0; ++ int i, err, pci_using_dac, pos; ++ u16 eeprom_data = 0, state = 0; + u16 eeprom_apme_mask = IGB_EEPROM_APME; + u32 part_num; + int bars, need_ioport; +@@ -1061,6 +1061,27 @@ + } + } + ++ /* 82575 requires that the pci-e link partner disable the L0s state */ ++ switch (pdev->device) { ++ case E1000_DEV_ID_82575EB_COPPER: ++ case E1000_DEV_ID_82575EB_FIBER_SERDES: ++ case E1000_DEV_ID_82575GB_QUAD_COPPER: ++ us_dev = pdev->bus->self; ++ pos = pci_find_capability(us_dev, PCI_CAP_ID_EXP); ++ if (pos) { ++ pci_read_config_word(us_dev, pos + PCI_EXP_LNKCTL, ++ &state); ++ state &= ~PCIE_LINK_STATE_L0S; ++ pci_write_config_word(us_dev, pos + PCI_EXP_LNKCTL, ++ state); ++ dev_info(&pdev->dev, ++ "Disabling ASPM L0s upstream switch port %s\n", ++ pci_name(us_dev)); ++ } ++ default: ++ break; ++ } ++ + err = pci_request_selected_regions(pdev, bars, igb_driver_name); + if (err) + goto err_pci_reg; +@@ -1135,10 +1156,11 @@ + + /* set flags */ + switch (hw->mac.type) { ++ case e1000_82576: + case e1000_82575: ++ adapter->flags |= IGB_FLAG_HAS_DCA; + adapter->flags |= IGB_FLAG_NEED_CTX_IDX; + break; +- case e1000_82576: + default: + break; + } +@@ -1288,7 +1310,8 @@ + goto err_register; + + #ifdef CONFIG_IGB_DCA +- if (dca_add_requester(&pdev->dev) == 0) { ++ if ((adapter->flags & IGB_FLAG_HAS_DCA) && ++ (dca_add_requester(&pdev->dev) == 0)) { + adapter->flags |= IGB_FLAG_DCA_ENABLED; + dev_info(&pdev->dev, "DCA enabled\n"); + /* Always use CB2 mode, difference is masked +@@ -1812,11 +1835,11 @@ + rctl |= E1000_RCTL_SECRC; + + /* +- * disable store bad packets and clear size bits. ++ * disable store bad packets, long packet enable, and clear size bits. + */ +- rctl &= ~(E1000_RCTL_SBP | E1000_RCTL_SZ_256); ++ rctl &= ~(E1000_RCTL_SBP | E1000_RCTL_LPE | E1000_RCTL_SZ_256); + +- /* enable LPE when to prevent packets larger than max_frame_size */ ++ if (adapter->netdev->mtu > ETH_DATA_LEN) + rctl |= E1000_RCTL_LPE; + + /* Setup buffer sizes */ +@@ -1842,7 +1865,7 @@ + */ + /* allocations using alloc_page take too long for regular MTU + * so only enable packet split for jumbo frames */ +- if (adapter->netdev->mtu > ETH_DATA_LEN) { ++ if (rctl & E1000_RCTL_LPE) { + adapter->rx_ps_hdr_size = IGB_RXBUFFER_128; + srrctl |= adapter->rx_ps_hdr_size << + E1000_SRRCTL_BSIZEHDRSIZE_SHIFT; +@@ -3450,16 +3473,19 @@ + struct e1000_hw *hw = &adapter->hw; + unsigned long event = *(unsigned long *)data; + ++ if (!(adapter->flags & IGB_FLAG_HAS_DCA)) ++ goto out; ++ + switch (event) { + case DCA_PROVIDER_ADD: + /* if already enabled, don't do it again */ + if (adapter->flags & IGB_FLAG_DCA_ENABLED) + break; ++ adapter->flags |= IGB_FLAG_DCA_ENABLED; + /* Always use CB2 mode, difference is masked + * in the CB driver. */ + wr32(E1000_DCA_CTRL, 2); + if (dca_add_requester(dev) == 0) { +- adapter->flags |= IGB_FLAG_DCA_ENABLED; + dev_info(&adapter->pdev->dev, "DCA enabled\n"); + igb_setup_dca(adapter); + break; +@@ -3476,7 +3502,7 @@ + } + break; + } +- ++out: + return 0; + } + +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/drivers/net/irda/mcs7780.c linux-2.6.29-rc3.owrt/drivers/net/irda/mcs7780.c +--- linux-2.6.29.owrt/drivers/net/irda/mcs7780.c 2009-05-10 22:04:38.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/drivers/net/irda/mcs7780.c 2009-05-10 23:48:28.000000000 +0200 +@@ -585,7 +585,7 @@ + mcs_get_reg(mcs, MCS_RESV_REG, &rval); + } while(cnt++ < 100 && (rval & MCS_IRINTX)); + +- if (cnt > 100) { ++ if(cnt >= 100) { + IRDA_ERROR("unable to change speed\n"); + ret = -EIO; + goto error; +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/drivers/net/ixgbe/ixgbe_main.c linux-2.6.29-rc3.owrt/drivers/net/ixgbe/ixgbe_main.c +--- linux-2.6.29.owrt/drivers/net/ixgbe/ixgbe_main.c 2009-05-10 22:04:38.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/drivers/net/ixgbe/ixgbe_main.c 2009-05-10 23:48:28.000000000 +0200 +@@ -3973,7 +3973,6 @@ + .ndo_stop = ixgbe_close, + .ndo_start_xmit = ixgbe_xmit_frame, + .ndo_get_stats = ixgbe_get_stats, +- .ndo_set_rx_mode = ixgbe_set_rx_mode, + .ndo_set_multicast_list = ixgbe_set_rx_mode, + .ndo_validate_addr = eth_validate_addr, + .ndo_set_mac_address = ixgbe_set_mac, +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/drivers/net/jme.c linux-2.6.29-rc3.owrt/drivers/net/jme.c +--- linux-2.6.29.owrt/drivers/net/jme.c 2009-05-10 22:04:38.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/drivers/net/jme.c 2009-05-10 23:48:28.000000000 +0200 +@@ -957,14 +957,13 @@ + goto out_inc; + + i = atomic_read(&rxring->next_to_clean); +- while (limit > 0) { ++ while (limit-- > 0) { + rxdesc = rxring->desc; + rxdesc += i; + + if ((rxdesc->descwb.flags & cpu_to_le16(RXWBFLAG_OWN)) || + !(rxdesc->descwb.desccnt & RXWBDCNT_WBCPL)) + goto out; +- --limit; + + desccnt = rxdesc->descwb.desccnt & RXWBDCNT_DCNT; + +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/drivers/net/Kconfig linux-2.6.29-rc3.owrt/drivers/net/Kconfig +--- linux-2.6.29.owrt/drivers/net/Kconfig 2009-05-10 22:04:38.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/drivers/net/Kconfig 2009-05-10 23:48:28.000000000 +0200 +@@ -1163,17 +1163,6 @@ + To compile this driver as a module, choose M here. The module + will be called ni65. + +-config DNET +- tristate "Dave ethernet support (DNET)" +- depends on NET_ETHERNET && HAS_IOMEM +- select PHYLIB +- help +- The Dave ethernet interface (DNET) is found on Qong Board FPGA. +- Say Y to include support for the DNET chip. +- +- To compile this driver as a module, choose M here: the module +- will be called dnet. +- + source "drivers/net/tulip/Kconfig" + + config AT1700 +@@ -2476,17 +2465,6 @@ + To compile this driver as a module, choose M here. The module + will be called atl1e. + +-config ATL1C +- tristate "Atheros L1C Gigabit Ethernet support (EXPERIMENTAL)" +- depends on PCI && EXPERIMENTAL +- select CRC32 +- select MII +- help +- This driver supports the Atheros L1C gigabit ethernet adapter. +- +- To compile this driver as a module, choose M here. The module +- will be called atl1c. +- + config JME + tristate "JMicron(R) PCI-Express Gigabit Ethernet support" + depends on PCI +@@ -2753,8 +2731,6 @@ + + source "drivers/net/sfc/Kconfig" + +-source "drivers/net/benet/Kconfig" +- + endif # NETDEV_10000 + + source "drivers/net/tokenring/Kconfig" +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/drivers/net/Makefile linux-2.6.29-rc3.owrt/drivers/net/Makefile +--- linux-2.6.29.owrt/drivers/net/Makefile 2009-05-10 22:04:38.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/drivers/net/Makefile 2009-05-10 23:48:28.000000000 +0200 +@@ -17,12 +17,10 @@ + obj-$(CONFIG_ATL1) += atlx/ + obj-$(CONFIG_ATL2) += atlx/ + obj-$(CONFIG_ATL1E) += atl1e/ +-obj-$(CONFIG_ATL1C) += atl1c/ + obj-$(CONFIG_GIANFAR) += gianfar_driver.o + obj-$(CONFIG_TEHUTI) += tehuti.o + obj-$(CONFIG_ENIC) += enic/ + obj-$(CONFIG_JME) += jme.o +-obj-$(CONFIG_BE2NET) += benet/ + + gianfar_driver-objs := gianfar.o \ + gianfar_ethtool.o \ +@@ -233,7 +231,6 @@ + + obj-$(CONFIG_XTENSA_XT2000_SONIC) += xtsonic.o + +-obj-$(CONFIG_DNET) += dnet.o + obj-$(CONFIG_MACB) += macb.o + + obj-$(CONFIG_ARM) += arm/ +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/drivers/net/mv643xx_eth.c linux-2.6.29-rc3.owrt/drivers/net/mv643xx_eth.c +--- linux-2.6.29.owrt/drivers/net/mv643xx_eth.c 2009-05-10 22:04:38.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/drivers/net/mv643xx_eth.c 2009-05-10 23:48:28.000000000 +0200 +@@ -1175,7 +1175,7 @@ + { + struct mib_counters *p = &mp->mib_counters; + +- spin_lock_bh(&mp->mib_counters_lock); ++ spin_lock(&mp->mib_counters_lock); + p->good_octets_received += mib_read(mp, 0x00); + p->good_octets_received += (u64)mib_read(mp, 0x04) << 32; + p->bad_octets_received += mib_read(mp, 0x08); +@@ -1208,7 +1208,7 @@ + p->bad_crc_event += mib_read(mp, 0x74); + p->collision += mib_read(mp, 0x78); + p->late_collision += mib_read(mp, 0x7c); +- spin_unlock_bh(&mp->mib_counters_lock); ++ spin_unlock(&mp->mib_counters_lock); + + mod_timer(&mp->mib_counters_timer, jiffies + 30 * HZ); + } +@@ -1575,7 +1575,7 @@ + return; + } + +- mc_spec = kmalloc(0x200, GFP_ATOMIC); ++ mc_spec = kmalloc(0x200, GFP_KERNEL); + if (mc_spec == NULL) + goto oom; + mc_other = mc_spec + (0x100 >> 2); +@@ -2030,6 +2030,11 @@ + } + + /* ++ * Add configured unicast address to address filter table. ++ */ ++ mv643xx_eth_program_unicast_filter(mp->dev); ++ ++ /* + * Receive all unmatched unicast, TCP, UDP, BPDU and broadcast + * frames to RX queue #0, and include the pseudo-header when + * calculating receive checksums. +@@ -2042,11 +2047,6 @@ + wrlp(mp, PORT_CONFIG_EXT, 0x00000000); + + /* +- * Add configured unicast addresses to address filter table. +- */ +- mv643xx_eth_program_unicast_filter(mp->dev); +- +- /* + * Enable the receive queues. + */ + for (i = 0; i < mp->rxq_count; i++) { +@@ -2216,6 +2216,8 @@ + wrlp(mp, INT_MASK, 0x00000000); + rdlp(mp, INT_MASK); + ++ del_timer_sync(&mp->mib_counters_timer); ++ + napi_disable(&mp->napi); + + del_timer_sync(&mp->rx_oom); +@@ -2227,7 +2229,6 @@ + port_reset(mp); + mv643xx_eth_get_stats(dev); + mib_counters_update(mp); +- del_timer_sync(&mp->mib_counters_timer); + + skb_queue_purge(&mp->rx_recycle); + +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/drivers/net/netxen/netxen_nic.h linux-2.6.29-rc3.owrt/drivers/net/netxen/netxen_nic.h +--- linux-2.6.29.owrt/drivers/net/netxen/netxen_nic.h 2009-05-10 22:04:38.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/drivers/net/netxen/netxen_nic.h 2009-05-10 23:48:29.000000000 +0200 +@@ -210,7 +210,7 @@ + #define MAX_CMD_DESCRIPTORS_HOST 1024 + #define MAX_RCV_DESCRIPTORS_1G 2048 + #define MAX_RCV_DESCRIPTORS_10G 4096 +-#define MAX_JUMBO_RCV_DESCRIPTORS 1024 ++#define MAX_JUMBO_RCV_DESCRIPTORS 512 + #define MAX_LRO_RCV_DESCRIPTORS 8 + #define MAX_RCVSTATUS_DESCRIPTORS MAX_RCV_DESCRIPTORS + #define MAX_JUMBO_RCV_DESC MAX_JUMBO_RCV_DESCRIPTORS +@@ -1203,7 +1203,7 @@ + #define NETXEN_IS_MSI_FAMILY(adapter) \ + ((adapter)->flags & (NETXEN_NIC_MSI_ENABLED | NETXEN_NIC_MSIX_ENABLED)) + +-#define MSIX_ENTRIES_PER_ADAPTER 1 ++#define MSIX_ENTRIES_PER_ADAPTER 8 + #define NETXEN_MSIX_TBL_SPACE 8192 + #define NETXEN_PCI_REG_MSIX_TBL 0x44 + +@@ -1595,6 +1595,7 @@ + } + + ++int netxen_is_flash_supported(struct netxen_adapter *adapter); + int netxen_get_flash_mac_addr(struct netxen_adapter *adapter, __le64 *mac); + int netxen_p3_get_mac_addr(struct netxen_adapter *adapter, __le64 *mac); + extern void netxen_change_ringparam(struct netxen_adapter *adapter); +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/drivers/net/netxen/netxen_nic_hw.c linux-2.6.29-rc3.owrt/drivers/net/netxen/netxen_nic_hw.c +--- linux-2.6.29.owrt/drivers/net/netxen/netxen_nic_hw.c 2009-05-10 22:04:38.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/drivers/net/netxen/netxen_nic_hw.c 2009-05-10 23:48:29.000000000 +0200 +@@ -706,6 +706,28 @@ + return rc; + } + ++int netxen_is_flash_supported(struct netxen_adapter *adapter) ++{ ++ const int locs[] = { 0, 0x4, 0x100, 0x4000, 0x4128 }; ++ int addr, val01, val02, i, j; ++ ++ /* if the flash size less than 4Mb, make huge war cry and die */ ++ for (j = 1; j < 4; j++) { ++ addr = j * NETXEN_NIC_WINDOW_MARGIN; ++ for (i = 0; i < ARRAY_SIZE(locs); i++) { ++ if (netxen_rom_fast_read(adapter, locs[i], &val01) == 0 ++ && netxen_rom_fast_read(adapter, (addr + locs[i]), ++ &val02) == 0) { ++ if (val01 == val02) ++ return -1; ++ } else ++ return -1; ++ } ++ } ++ ++ return 0; ++} ++ + static int netxen_get_flash_block(struct netxen_adapter *adapter, int base, + int size, __le32 * buf) + { +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/drivers/net/netxen/netxen_nic_init.c linux-2.6.29-rc3.owrt/drivers/net/netxen/netxen_nic_init.c +--- linux-2.6.29.owrt/drivers/net/netxen/netxen_nic_init.c 2009-05-10 22:04:38.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/drivers/net/netxen/netxen_nic_init.c 2009-05-10 23:48:29.000000000 +0200 +@@ -947,10 +947,8 @@ + } + for (i = 0; i < n; i++) { + if (netxen_rom_fast_read(adapter, 8*i + 4*offset, &val) != 0 || +- netxen_rom_fast_read(adapter, 8*i + 4*offset + 4, &addr) != 0) { +- kfree(buf); ++ netxen_rom_fast_read(adapter, 8*i + 4*offset + 4, &addr) != 0) + return -EIO; +- } + + buf[i].addr = addr; + buf[i].data = val; +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/drivers/net/netxen/netxen_nic_main.c linux-2.6.29-rc3.owrt/drivers/net/netxen/netxen_nic_main.c +--- linux-2.6.29.owrt/drivers/net/netxen/netxen_nic_main.c 2009-05-10 22:04:38.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/drivers/net/netxen/netxen_nic_main.c 2009-05-10 23:48:29.000000000 +0200 +@@ -76,7 +76,6 @@ + #endif + static irqreturn_t netxen_intr(int irq, void *data); + static irqreturn_t netxen_msi_intr(int irq, void *data); +-static irqreturn_t netxen_msix_intr(int irq, void *data); + + /* PCI Device ID Table */ + #define ENTRY(device) \ +@@ -201,9 +200,9 @@ + adapter->pci_using_dac = 1; + return 0; + } +-set_32_bit_mask: + #endif /* CONFIG_IA64 */ + ++set_32_bit_mask: + err = pci_set_dma_mask(pdev, DMA_32BIT_MASK); + if (!err) + err = pci_set_consistent_dma_mask(pdev, DMA_32BIT_MASK); +@@ -372,6 +371,67 @@ + } + } + ++#define PCI_CAP_ID_GEN 0x10 ++ ++static void netxen_pcie_strap_init(struct netxen_adapter *adapter) ++{ ++ u32 pdevfuncsave; ++ u32 c8c9value = 0; ++ u32 chicken = 0; ++ u32 control = 0; ++ int i, pos; ++ struct pci_dev *pdev; ++ ++ pdev = adapter->pdev; ++ ++ adapter->hw_read_wx(adapter, ++ NETXEN_PCIE_REG(PCIE_CHICKEN3), &chicken, 4); ++ /* clear chicken3.25:24 */ ++ chicken &= 0xFCFFFFFF; ++ /* ++ * if gen1 and B0, set F1020 - if gen 2, do nothing ++ * if gen2 set to F1000 ++ */ ++ pos = pci_find_capability(pdev, PCI_CAP_ID_GEN); ++ if (pos == 0xC0) { ++ pci_read_config_dword(pdev, pos + 0x10, &control); ++ if ((control & 0x000F0000) != 0x00020000) { ++ /* set chicken3.24 if gen1 */ ++ chicken |= 0x01000000; ++ } ++ printk(KERN_INFO "%s Gen2 strapping detected\n", ++ netxen_nic_driver_name); ++ c8c9value = 0xF1000; ++ } else { ++ /* set chicken3.24 if gen1 */ ++ chicken |= 0x01000000; ++ printk(KERN_INFO "%s Gen1 strapping detected\n", ++ netxen_nic_driver_name); ++ if (adapter->ahw.revision_id == NX_P3_B0) ++ c8c9value = 0xF1020; ++ else ++ c8c9value = 0; ++ ++ } ++ adapter->hw_write_wx(adapter, ++ NETXEN_PCIE_REG(PCIE_CHICKEN3), &chicken, 4); ++ ++ if (!c8c9value) ++ return; ++ ++ pdevfuncsave = pdev->devfn; ++ if (pdevfuncsave & 0x07) ++ return; ++ ++ for (i = 0; i < 8; i++) { ++ pci_read_config_dword(pdev, pos + 8, &control); ++ pci_read_config_dword(pdev, pos + 8, &control); ++ pci_write_config_dword(pdev, pos + 8, c8c9value); ++ pdev->devfn++; ++ } ++ pdev->devfn = pdevfuncsave; ++} ++ + static void netxen_set_msix_bit(struct pci_dev *pdev, int enable) + { + u32 control; +@@ -405,6 +465,9 @@ + struct net_device *netdev = adapter->netdev; + struct pci_dev *pdev = adapter->pdev; + ++ if (netxen_is_flash_supported(adapter) != 0) ++ return -EIO; ++ + if (NX_IS_REVISION_P3(adapter->ahw.revision_id)) { + if (netxen_p3_get_mac_addr(adapter, &mac_addr) != 0) + return -EIO; +@@ -585,12 +648,7 @@ + adapter->pci_mem_read = netxen_nic_pci_mem_read_2M; + adapter->pci_mem_write = netxen_nic_pci_mem_write_2M; + +- mem_ptr0 = pci_ioremap_bar(pdev, 0); +- if (mem_ptr0 == NULL) { +- dev_err(&pdev->dev, "failed to map PCI bar 0\n"); +- return -EIO; +- } +- ++ mem_ptr0 = ioremap(mem_base, mem_len); + pci_len0 = mem_len; + first_page_group_start = 0; + first_page_group_end = 0; +@@ -753,6 +811,9 @@ + } + netxen_load_firmware(adapter); + ++ if (NX_IS_REVISION_P3(revision_id)) ++ netxen_pcie_strap_init(adapter); ++ + if (NX_IS_REVISION_P2(revision_id)) { + + /* Initialize multicast addr pool owners */ +@@ -797,12 +858,9 @@ + * See if the firmware gave us a virtual-physical port mapping. + */ + adapter->physical_port = adapter->portnum; +- if (adapter->fw_major < 4) { +- i = adapter->pci_read_normalize(adapter, +- CRB_V2P(adapter->portnum)); +- if (i != 0x55555555) +- adapter->physical_port = i; +- } ++ i = adapter->pci_read_normalize(adapter, CRB_V2P(adapter->portnum)); ++ if (i != 0x55555555) ++ adapter->physical_port = i; + + adapter->flags &= ~(NETXEN_NIC_MSI_ENABLED | NETXEN_NIC_MSIX_ENABLED); + +@@ -1026,9 +1084,7 @@ + for (ring = 0; ring < adapter->max_rds_rings; ring++) + netxen_post_rx_buffers(adapter, ctx, ring); + } +- if (adapter->flags & NETXEN_NIC_MSIX_ENABLED) +- handler = netxen_msix_intr; +- else if (adapter->flags & NETXEN_NIC_MSI_ENABLED) ++ if (NETXEN_IS_MSI_FAMILY(adapter)) + handler = netxen_msi_intr; + else { + flags |= IRQF_SHARED; +@@ -1556,14 +1612,6 @@ + return IRQ_HANDLED; + } + +-static irqreturn_t netxen_msix_intr(int irq, void *data) +-{ +- struct netxen_adapter *adapter = data; +- +- napi_schedule(&adapter->napi); +- return IRQ_HANDLED; +-} +- + static int netxen_nic_poll(struct napi_struct *napi, int budget) + { + struct netxen_adapter *adapter = container_of(napi, struct netxen_adapter, napi); +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/drivers/net/pcmcia/3c574_cs.c linux-2.6.29-rc3.owrt/drivers/net/pcmcia/3c574_cs.c +--- linux-2.6.29.owrt/drivers/net/pcmcia/3c574_cs.c 2009-05-10 22:04:38.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/drivers/net/pcmcia/3c574_cs.c 2009-05-10 23:48:29.000000000 +0200 +@@ -1035,8 +1035,7 @@ + DEBUG(3, "%s: in rx_packet(), status %4.4x, rx_status %4.4x.\n", + dev->name, inw(ioaddr+EL3_STATUS), inw(ioaddr+RxStatus)); + while (!((rx_status = inw(ioaddr + RxStatus)) & 0x8000) && +- worklimit > 0) { +- worklimit--; ++ (--worklimit >= 0)) { + if (rx_status & 0x4000) { /* Error, update stats. */ + short error = rx_status & 0x3800; + dev->stats.rx_errors++; +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/drivers/net/pcmcia/3c589_cs.c linux-2.6.29-rc3.owrt/drivers/net/pcmcia/3c589_cs.c +--- linux-2.6.29.owrt/drivers/net/pcmcia/3c589_cs.c 2009-05-10 22:04:38.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/drivers/net/pcmcia/3c589_cs.c 2009-05-10 23:48:29.000000000 +0200 +@@ -857,8 +857,7 @@ + DEBUG(3, "%s: in rx_packet(), status %4.4x, rx_status %4.4x.\n", + dev->name, inw(ioaddr+EL3_STATUS), inw(ioaddr+RX_STATUS)); + while (!((rx_status = inw(ioaddr + RX_STATUS)) & 0x8000) && +- worklimit > 0) { +- worklimit--; ++ (--worklimit >= 0)) { + if (rx_status & 0x4000) { /* Error, update stats. */ + short error = rx_status & 0x3800; + dev->stats.rx_errors++; +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/drivers/net/pcmcia/pcnet_cs.c linux-2.6.29-rc3.owrt/drivers/net/pcmcia/pcnet_cs.c +--- linux-2.6.29.owrt/drivers/net/pcmcia/pcnet_cs.c 2009-05-10 22:04:38.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/drivers/net/pcmcia/pcnet_cs.c 2009-05-10 23:48:29.000000000 +0200 +@@ -586,7 +586,7 @@ + } + + if ((link->conf.ConfigBase == 0x03c0) +- && (link->manf_id == 0x149) && (link->card_id == 0xc1ab)) { ++ && (link->manf_id == 0x149) && (link->card_id = 0xc1ab)) { + printk(KERN_INFO "pcnet_cs: this is an AX88190 card!\n"); + printk(KERN_INFO "pcnet_cs: use axnet_cs instead.\n"); + goto failed; +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/drivers/net/phy/mdio-gpio.c linux-2.6.29-rc3.owrt/drivers/net/phy/mdio-gpio.c +--- linux-2.6.29.owrt/drivers/net/phy/mdio-gpio.c 2009-05-10 22:04:38.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/drivers/net/phy/mdio-gpio.c 2009-05-10 23:48:29.000000000 +0200 +@@ -125,8 +125,6 @@ + if (gpio_request(bitbang->mdio, "mdio")) + goto out_free_mdc; + +- gpio_direction_output(bitbang->mdc, 0); +- + dev_set_drvdata(dev, new_bus); + + ret = mdiobus_register(new_bus); +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/drivers/net/ps3_gelic_wireless.c linux-2.6.29-rc3.owrt/drivers/net/ps3_gelic_wireless.c +--- linux-2.6.29.owrt/drivers/net/ps3_gelic_wireless.c 2009-05-10 22:04:38.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/drivers/net/ps3_gelic_wireless.c 2009-05-10 23:48:29.000000000 +0200 +@@ -2168,7 +2168,7 @@ + complete(&wl->assoc_done); + netif_carrier_on(port_to_netdev(wl_port(wl))); + } else +- pr_debug("%s: event %#llx under wpa\n", ++ pr_debug("%s: event %#lx under wpa\n", + __func__, event); + } + +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/drivers/net/qlge/qlge.h linux-2.6.29-rc3.owrt/drivers/net/qlge/qlge.h +--- linux-2.6.29.owrt/drivers/net/qlge/qlge.h 2009-05-10 22:04:38.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/drivers/net/qlge/qlge.h 2009-05-10 23:48:29.000000000 +0200 +@@ -787,12 +787,12 @@ + + struct flash_params { + u8 dev_id_str[4]; +- __le16 size; +- __le16 csum; +- __le16 ver; +- __le16 sub_dev_id; ++ u16 size; ++ u16 csum; ++ u16 ver; ++ u16 sub_dev_id; + u8 mac_addr[6]; +- __le16 res; ++ u16 res; + }; + + +@@ -927,7 +927,6 @@ + u8 flags1; + #define IB_MAC_IOCB_RSP_OI 0x01 /* Overide intr delay */ + #define IB_MAC_IOCB_RSP_I 0x02 /* Disble Intr Generation */ +-#define IB_MAC_CSUM_ERR_MASK 0x1c /* A mask to use for csum errs */ + #define IB_MAC_IOCB_RSP_TE 0x04 /* Checksum error */ + #define IB_MAC_IOCB_RSP_NU 0x08 /* No checksum rcvd */ + #define IB_MAC_IOCB_RSP_IE 0x10 /* IPv4 checksum error */ +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/drivers/net/qlge/qlge_main.c linux-2.6.29-rc3.owrt/drivers/net/qlge/qlge_main.c +--- linux-2.6.29.owrt/drivers/net/qlge/qlge_main.c 2009-05-10 22:04:38.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/drivers/net/qlge/qlge_main.c 2009-05-10 23:48:29.000000000 +0200 +@@ -641,7 +641,7 @@ + + } + +-static int ql_read_flash_word(struct ql_adapter *qdev, int offset, __le32 *data) ++static int ql_read_flash_word(struct ql_adapter *qdev, int offset, u32 *data) + { + int status = 0; + /* wait for reg to come ready */ +@@ -656,11 +656,8 @@ + FLASH_ADDR, FLASH_ADDR_RDY, FLASH_ADDR_ERR); + if (status) + goto exit; +- /* This data is stored on flash as an array of +- * __le32. Since ql_read32() returns cpu endian +- * we need to swap it back. +- */ +- *data = cpu_to_le32(ql_read32(qdev, FLASH_DATA)); ++ /* get the data */ ++ *data = ql_read32(qdev, FLASH_DATA); + exit: + return status; + } +@@ -669,20 +666,13 @@ + { + int i; + int status; +- __le32 *p = (__le32 *)&qdev->flash; +- u32 offset = 0; +- +- /* Second function's parameters follow the first +- * function's. +- */ +- if (qdev->func) +- offset = sizeof(qdev->flash) / sizeof(u32); ++ u32 *p = (u32 *)&qdev->flash; + + if (ql_sem_spinlock(qdev, SEM_FLASH_MASK)) + return -ETIMEDOUT; + + for (i = 0; i < sizeof(qdev->flash) / sizeof(u32); i++, p++) { +- status = ql_read_flash_word(qdev, i+offset, p); ++ status = ql_read_flash_word(qdev, i, p); + if (status) { + QPRINTK(qdev, IFUP, ERR, "Error reading flash.\n"); + goto exit; +@@ -898,7 +888,6 @@ + lbq_desc->index); + lbq_desc->p.lbq_page = alloc_page(GFP_ATOMIC); + if (lbq_desc->p.lbq_page == NULL) { +- rx_ring->lbq_clean_idx = clean_idx; + QPRINTK(qdev, RX_STATUS, ERR, + "Couldn't get a page.\n"); + return; +@@ -908,9 +897,6 @@ + 0, PAGE_SIZE, + PCI_DMA_FROMDEVICE); + if (pci_dma_mapping_error(qdev->pdev, map)) { +- rx_ring->lbq_clean_idx = clean_idx; +- put_page(lbq_desc->p.lbq_page); +- lbq_desc->p.lbq_page = NULL; + QPRINTK(qdev, RX_STATUS, ERR, + "PCI mapping failed.\n"); + return; +@@ -972,8 +958,6 @@ + if (pci_dma_mapping_error(qdev->pdev, map)) { + QPRINTK(qdev, IFUP, ERR, "PCI mapping failed.\n"); + rx_ring->sbq_clean_idx = clean_idx; +- dev_kfree_skb_any(sbq_desc->p.skb); +- sbq_desc->p.skb = NULL; + return; + } + pci_unmap_addr_set(sbq_desc, mapaddr, map); +@@ -1436,32 +1420,18 @@ + if (ib_mac_rsp->flags2 & IB_MAC_IOCB_RSP_P) { + QPRINTK(qdev, RX_STATUS, DEBUG, "Promiscuous Packet.\n"); + } +- +- skb->protocol = eth_type_trans(skb, ndev); +- skb->ip_summed = CHECKSUM_NONE; +- +- /* If rx checksum is on, and there are no +- * csum or frame errors. +- */ +- if (qdev->rx_csum && +- !(ib_mac_rsp->flags2 & IB_MAC_IOCB_RSP_ERR_MASK) && +- !(ib_mac_rsp->flags1 & IB_MAC_CSUM_ERR_MASK)) { +- /* TCP frame. */ +- if (ib_mac_rsp->flags2 & IB_MAC_IOCB_RSP_T) { +- QPRINTK(qdev, RX_STATUS, DEBUG, +- "TCP checksum done!\n"); +- skb->ip_summed = CHECKSUM_UNNECESSARY; +- } else if ((ib_mac_rsp->flags2 & IB_MAC_IOCB_RSP_U) && +- (ib_mac_rsp->flags3 & IB_MAC_IOCB_RSP_V4)) { +- /* Unfragmented ipv4 UDP frame. */ +- struct iphdr *iph = (struct iphdr *) skb->data; +- if (!(iph->frag_off & +- cpu_to_be16(IP_MF|IP_OFFSET))) { +- skb->ip_summed = CHECKSUM_UNNECESSARY; +- QPRINTK(qdev, RX_STATUS, DEBUG, +- "TCP checksum done!\n"); +- } +- } ++ if (ib_mac_rsp->flags1 & (IB_MAC_IOCB_RSP_IE | IB_MAC_IOCB_RSP_TE)) { ++ QPRINTK(qdev, RX_STATUS, ERR, ++ "Bad checksum for this %s packet.\n", ++ ((ib_mac_rsp-> ++ flags2 & IB_MAC_IOCB_RSP_T) ? "TCP" : "UDP")); ++ skb->ip_summed = CHECKSUM_NONE; ++ } else if (qdev->rx_csum && ++ ((ib_mac_rsp->flags2 & IB_MAC_IOCB_RSP_T) || ++ ((ib_mac_rsp->flags2 & IB_MAC_IOCB_RSP_U) && ++ !(ib_mac_rsp->flags1 & IB_MAC_IOCB_RSP_NU)))) { ++ QPRINTK(qdev, RX_STATUS, DEBUG, "RX checksum done!\n"); ++ skb->ip_summed = CHECKSUM_UNNECESSARY; + } + qdev->stats.rx_packets++; + qdev->stats.rx_bytes += skb->len; +@@ -1469,12 +1439,12 @@ + if (qdev->vlgrp && (ib_mac_rsp->flags2 & IB_MAC_IOCB_RSP_V)) { + QPRINTK(qdev, RX_STATUS, DEBUG, + "Passing a VLAN packet upstream.\n"); +- vlan_hwaccel_receive_skb(skb, qdev->vlgrp, ++ vlan_hwaccel_rx(skb, qdev->vlgrp, + le16_to_cpu(ib_mac_rsp->vlan_id)); + } else { + QPRINTK(qdev, RX_STATUS, DEBUG, + "Passing a normal packet upstream.\n"); +- netif_receive_skb(skb); ++ netif_rx(skb); + } + } + +@@ -1531,11 +1501,6 @@ + netif_stop_queue(qdev->ndev); + netif_carrier_off(qdev->ndev); + ql_disable_interrupts(qdev); +- /* Clear adapter up bit to signal the recovery +- * process that it shouldn't kill the reset worker +- * thread +- */ +- clear_bit(QL_ADAPTER_UP, &qdev->flags); + queue_delayed_work(qdev->workqueue, &qdev->asic_reset_work, 0); + } + +@@ -1941,9 +1906,6 @@ + + tx_ring = &qdev->tx_ring[tx_ring_idx]; + +- if (skb_padto(skb, ETH_ZLEN)) +- return NETDEV_TX_OK; +- + if (unlikely(atomic_read(&tx_ring->tx_count) < 2)) { + QPRINTK(qdev, TX_QUEUED, INFO, + "%s: shutting down tx queue %d du to lack of resources.\n", +@@ -1955,6 +1917,10 @@ + tx_ring_desc = &tx_ring->q[tx_ring->prod_idx]; + mac_iocb_ptr = tx_ring_desc->queue_entry; + memset((void *)mac_iocb_ptr, 0, sizeof(mac_iocb_ptr)); ++ if (ql_map_send(qdev, mac_iocb_ptr, skb, tx_ring_desc) != NETDEV_TX_OK) { ++ QPRINTK(qdev, TX_QUEUED, ERR, "Could not map the segments.\n"); ++ return NETDEV_TX_BUSY; ++ } + + mac_iocb_ptr->opcode = OPCODE_OB_MAC_IOCB; + mac_iocb_ptr->tid = tx_ring_desc->index; +@@ -1980,12 +1946,6 @@ + ql_hw_csum_setup(skb, + (struct ob_mac_tso_iocb_req *)mac_iocb_ptr); + } +- if (ql_map_send(qdev, mac_iocb_ptr, skb, tx_ring_desc) != +- NETDEV_TX_OK) { +- QPRINTK(qdev, TX_QUEUED, ERR, +- "Could not map the segments.\n"); +- return NETDEV_TX_BUSY; +- } + QL_DUMP_OB_MAC_IOCB(mac_iocb_ptr); + tx_ring->prod_idx++; + if (tx_ring->prod_idx == tx_ring->wq_len) +@@ -2903,8 +2863,8 @@ + /* + * Fill out the Indirection Table. + */ +- for (i = 0; i < 256; i++) +- hash_id[i] = i & (qdev->rss_ring_count - 1); ++ for (i = 0; i < 32; i++) ++ hash_id[i] = i & 1; + + /* + * Random values for the IPv6 and IPv4 Hash Keys. +@@ -2987,9 +2947,9 @@ + mask = value << 16; + ql_write32(qdev, SYS, mask | value); + +- /* Set the default queue, and VLAN behavior. */ +- value = NIC_RCV_CFG_DFQ | NIC_RCV_CFG_RV; +- mask = NIC_RCV_CFG_DFQ_MASK | (NIC_RCV_CFG_RV << 16); ++ /* Set the default queue. */ ++ value = NIC_RCV_CFG_DFQ; ++ mask = NIC_RCV_CFG_DFQ_MASK; + ql_write32(qdev, NIC_RCV_CFG, (mask | value)); + + /* Set the MPI interrupt to enabled. */ +@@ -3130,11 +3090,7 @@ + netif_stop_queue(ndev); + netif_carrier_off(ndev); + +- /* Don't kill the reset worker thread if we +- * are in the process of recovery. +- */ +- if (test_bit(QL_ADAPTER_UP, &qdev->flags)) +- cancel_delayed_work_sync(&qdev->asic_reset_work); ++ cancel_delayed_work_sync(&qdev->asic_reset_work); + cancel_delayed_work_sync(&qdev->mpi_reset_work); + cancel_delayed_work_sync(&qdev->mpi_work); + +@@ -3166,11 +3122,6 @@ + + ql_tx_ring_clean(qdev); + +- /* Call netif_napi_del() from common point. +- */ +- for (i = qdev->rss_ring_first_cq_id; i < qdev->rx_ring_count; i++) +- netif_napi_del(&qdev->rx_ring[i].napi); +- + spin_lock(&qdev->hw_lock); + status = ql_adapter_reset(qdev); + if (status) +@@ -3540,7 +3491,7 @@ + static void qlge_tx_timeout(struct net_device *ndev) + { + struct ql_adapter *qdev = (struct ql_adapter *)netdev_priv(ndev); +- ql_queue_asic_error(qdev); ++ queue_delayed_work(qdev->workqueue, &qdev->asic_reset_work, 0); + } + + static void ql_asic_reset_work(struct work_struct *work) +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/drivers/net/r6040.c linux-2.6.29-rc3.owrt/drivers/net/r6040.c +--- linux-2.6.29.owrt/drivers/net/r6040.c 2009-05-10 22:04:38.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/drivers/net/r6040.c 2009-05-10 23:48:29.000000000 +0200 +@@ -438,6 +438,7 @@ + { + struct r6040_private *lp = netdev_priv(dev); + void __iomem *ioaddr = lp->base; ++ struct pci_dev *pdev = lp->pdev; + int limit = 2048; + u16 *adrp; + u16 cmd; +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/drivers/net/r8169.c linux-2.6.29-rc3.owrt/drivers/net/r8169.c +--- linux-2.6.29.owrt/drivers/net/r8169.c 2009-05-10 22:04:38.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/drivers/net/r8169.c 2009-05-10 23:48:29.000000000 +0200 +@@ -437,22 +437,6 @@ + RTL_FEATURE_GMII = (1 << 2), + }; + +-struct rtl8169_counters { +- __le64 tx_packets; +- __le64 rx_packets; +- __le64 tx_errors; +- __le32 rx_errors; +- __le16 rx_missed; +- __le16 align_errors; +- __le32 tx_one_collision; +- __le32 tx_multi_collision; +- __le64 rx_unicast; +- __le64 rx_broadcast; +- __le32 rx_multicast; +- __le16 tx_aborted; +- __le16 tx_underun; +-}; +- + struct rtl8169_private { + void __iomem *mmio_addr; /* memory map physical address */ + struct pci_dev *pci_dev; /* Index of PCI device */ +@@ -496,7 +480,6 @@ + unsigned features; + + struct mii_if_info mii; +- struct rtl8169_counters counters; + }; + + MODULE_AUTHOR("Realtek and the Linux r8169 crew <netdev@vger.kernel.org>"); +@@ -1117,6 +1100,22 @@ + "tx_underrun", + }; + ++struct rtl8169_counters { ++ __le64 tx_packets; ++ __le64 rx_packets; ++ __le64 tx_errors; ++ __le32 rx_errors; ++ __le16 rx_missed; ++ __le16 align_errors; ++ __le32 tx_one_collision; ++ __le32 tx_multi_collision; ++ __le64 rx_unicast; ++ __le64 rx_broadcast; ++ __le32 rx_multicast; ++ __le16 tx_aborted; ++ __le16 tx_underun; ++}; ++ + static int rtl8169_get_sset_count(struct net_device *dev, int sset) + { + switch (sset) { +@@ -1127,21 +1126,16 @@ + } + } + +-static void rtl8169_update_counters(struct net_device *dev) ++static void rtl8169_get_ethtool_stats(struct net_device *dev, ++ struct ethtool_stats *stats, u64 *data) + { + struct rtl8169_private *tp = netdev_priv(dev); + void __iomem *ioaddr = tp->mmio_addr; + struct rtl8169_counters *counters; + dma_addr_t paddr; + u32 cmd; +- int wait = 1000; + +- /* +- * Some chips are unable to dump tally counters when the receiver +- * is disabled. +- */ +- if ((RTL_R8(ChipCmd) & CmdRxEnb) == 0) +- return; ++ ASSERT_RTNL(); + + counters = pci_alloc_consistent(tp->pci_dev, sizeof(*counters), &paddr); + if (!counters) +@@ -1152,43 +1146,29 @@ + RTL_W32(CounterAddrLow, cmd); + RTL_W32(CounterAddrLow, cmd | CounterDump); + +- while (wait--) { +- if ((RTL_R32(CounterAddrLow) & CounterDump) == 0) { +- /* copy updated counters */ +- memcpy(&tp->counters, counters, sizeof(*counters)); ++ while (RTL_R32(CounterAddrLow) & CounterDump) { ++ if (msleep_interruptible(1)) + break; +- } +- udelay(10); + } + + RTL_W32(CounterAddrLow, 0); + RTL_W32(CounterAddrHigh, 0); + +- pci_free_consistent(tp->pci_dev, sizeof(*counters), counters, paddr); +-} ++ data[0] = le64_to_cpu(counters->tx_packets); ++ data[1] = le64_to_cpu(counters->rx_packets); ++ data[2] = le64_to_cpu(counters->tx_errors); ++ data[3] = le32_to_cpu(counters->rx_errors); ++ data[4] = le16_to_cpu(counters->rx_missed); ++ data[5] = le16_to_cpu(counters->align_errors); ++ data[6] = le32_to_cpu(counters->tx_one_collision); ++ data[7] = le32_to_cpu(counters->tx_multi_collision); ++ data[8] = le64_to_cpu(counters->rx_unicast); ++ data[9] = le64_to_cpu(counters->rx_broadcast); ++ data[10] = le32_to_cpu(counters->rx_multicast); ++ data[11] = le16_to_cpu(counters->tx_aborted); ++ data[12] = le16_to_cpu(counters->tx_underun); + +-static void rtl8169_get_ethtool_stats(struct net_device *dev, +- struct ethtool_stats *stats, u64 *data) +-{ +- struct rtl8169_private *tp = netdev_priv(dev); +- +- ASSERT_RTNL(); +- +- rtl8169_update_counters(dev); +- +- data[0] = le64_to_cpu(tp->counters.tx_packets); +- data[1] = le64_to_cpu(tp->counters.rx_packets); +- data[2] = le64_to_cpu(tp->counters.tx_errors); +- data[3] = le32_to_cpu(tp->counters.rx_errors); +- data[4] = le16_to_cpu(tp->counters.rx_missed); +- data[5] = le16_to_cpu(tp->counters.align_errors); +- data[6] = le32_to_cpu(tp->counters.tx_one_collision); +- data[7] = le32_to_cpu(tp->counters.tx_multi_collision); +- data[8] = le64_to_cpu(tp->counters.rx_unicast); +- data[9] = le64_to_cpu(tp->counters.rx_broadcast); +- data[10] = le32_to_cpu(tp->counters.rx_multicast); +- data[11] = le16_to_cpu(tp->counters.tx_aborted); +- data[12] = le16_to_cpu(tp->counters.tx_underun); ++ pci_free_consistent(tp->pci_dev, sizeof(*counters), counters, paddr); + } + + static void rtl8169_get_strings(struct net_device *dev, u32 stringset, u8 *data) +@@ -3253,6 +3233,13 @@ + opts1 |= FirstFrag; + } else { + len = skb->len; ++ ++ if (unlikely(len < ETH_ZLEN)) { ++ if (skb_padto(skb, ETH_ZLEN)) ++ goto err_update_stats; ++ len = ETH_ZLEN; ++ } ++ + opts1 |= FirstFrag | LastFrag; + tp->tx_skb[entry].skb = skb; + } +@@ -3290,6 +3277,7 @@ + err_stop: + netif_stop_queue(dev); + ret = NETDEV_TX_BUSY; ++err_update_stats: + dev->stats.tx_dropped++; + goto out; + } +@@ -3696,9 +3684,6 @@ + struct rtl8169_private *tp = netdev_priv(dev); + struct pci_dev *pdev = tp->pci_dev; + +- /* update counters before going down */ +- rtl8169_update_counters(dev); +- + rtl8169_down(dev); + + free_irq(dev->irq, dev); +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/drivers/net/sfc/efx.c linux-2.6.29-rc3.owrt/drivers/net/sfc/efx.c +--- linux-2.6.29.owrt/drivers/net/sfc/efx.c 2009-05-10 22:04:38.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/drivers/net/sfc/efx.c 2009-05-10 23:48:29.000000000 +0200 +@@ -676,8 +676,9 @@ + rc = efx->phy_op->init(efx); + if (rc) + return rc; +- mutex_lock(&efx->mac_lock); + efx->phy_op->reconfigure(efx); ++ ++ mutex_lock(&efx->mac_lock); + rc = falcon_switch_mac(efx); + mutex_unlock(&efx->mac_lock); + if (rc) +@@ -685,7 +686,7 @@ + efx->mac_op->reconfigure(efx); + + efx->port_initialized = true; +- efx_stats_enable(efx); ++ efx->stats_enabled = true; + return 0; + + fail: +@@ -734,7 +735,6 @@ + if (!efx->port_initialized) + return; + +- efx_stats_disable(efx); + efx->phy_op->fini(efx); + efx->port_initialized = false; + +@@ -1361,20 +1361,6 @@ + return 0; + } + +-void efx_stats_disable(struct efx_nic *efx) +-{ +- spin_lock(&efx->stats_lock); +- ++efx->stats_disable_count; +- spin_unlock(&efx->stats_lock); +-} +- +-void efx_stats_enable(struct efx_nic *efx) +-{ +- spin_lock(&efx->stats_lock); +- --efx->stats_disable_count; +- spin_unlock(&efx->stats_lock); +-} +- + /* Context: process, dev_base_lock or RTNL held, non-blocking. */ + static struct net_device_stats *efx_net_stats(struct net_device *net_dev) + { +@@ -1383,12 +1369,12 @@ + struct net_device_stats *stats = &net_dev->stats; + + /* Update stats if possible, but do not wait if another thread +- * is updating them or if MAC stats fetches are temporarily +- * disabled; slightly stale stats are acceptable. ++ * is updating them (or resetting the NIC); slightly stale ++ * stats are acceptable. + */ + if (!spin_trylock(&efx->stats_lock)) + return stats; +- if (!efx->stats_disable_count) { ++ if (efx->stats_enabled) { + efx->mac_op->update_stats(efx); + falcon_update_nic_stats(efx); + } +@@ -1636,12 +1622,16 @@ + + /* Tears down the entire software state and most of the hardware state + * before reset. */ +-void efx_reset_down(struct efx_nic *efx, enum reset_type method, +- struct ethtool_cmd *ecmd) ++void efx_reset_down(struct efx_nic *efx, struct ethtool_cmd *ecmd) + { + EFX_ASSERT_RESET_SERIALISED(efx); + +- efx_stats_disable(efx); ++ /* The net_dev->get_stats handler is quite slow, and will fail ++ * if a fetch is pending over reset. Serialise against it. */ ++ spin_lock(&efx->stats_lock); ++ efx->stats_enabled = false; ++ spin_unlock(&efx->stats_lock); ++ + efx_stop_all(efx); + mutex_lock(&efx->mac_lock); + mutex_lock(&efx->spi_lock); +@@ -1649,8 +1639,6 @@ + efx->phy_op->get_settings(efx, ecmd); + + efx_fini_channels(efx); +- if (efx->port_initialized && method != RESET_TYPE_INVISIBLE) +- efx->phy_op->fini(efx); + } + + /* This function will always ensure that the locks acquired in +@@ -1658,8 +1646,7 @@ + * that we were unable to reinitialise the hardware, and the + * driver should be disabled. If ok is false, then the rx and tx + * engines are not restarted, pending a RESET_DISABLE. */ +-int efx_reset_up(struct efx_nic *efx, enum reset_type method, +- struct ethtool_cmd *ecmd, bool ok) ++int efx_reset_up(struct efx_nic *efx, struct ethtool_cmd *ecmd, bool ok) + { + int rc; + +@@ -1671,15 +1658,6 @@ + ok = false; + } + +- if (efx->port_initialized && method != RESET_TYPE_INVISIBLE) { +- if (ok) { +- rc = efx->phy_op->init(efx); +- if (rc) +- ok = false; +- } else +- efx->port_initialized = false; +- } +- + if (ok) { + efx_init_channels(efx); + +@@ -1692,7 +1670,7 @@ + + if (ok) { + efx_start_all(efx); +- efx_stats_enable(efx); ++ efx->stats_enabled = true; + } + return rc; + } +@@ -1724,7 +1702,7 @@ + + EFX_INFO(efx, "resetting (%d)\n", method); + +- efx_reset_down(efx, method, &ecmd); ++ efx_reset_down(efx, &ecmd); + + rc = falcon_reset_hw(efx, method); + if (rc) { +@@ -1743,10 +1721,10 @@ + + /* Leave device stopped if necessary */ + if (method == RESET_TYPE_DISABLE) { +- efx_reset_up(efx, method, &ecmd, false); ++ efx_reset_up(efx, &ecmd, false); + rc = -EIO; + } else { +- rc = efx_reset_up(efx, method, &ecmd, true); ++ rc = efx_reset_up(efx, &ecmd, true); + } + + out_disable: +@@ -1898,7 +1876,6 @@ + efx->rx_checksum_enabled = true; + spin_lock_init(&efx->netif_stop_lock); + spin_lock_init(&efx->stats_lock); +- efx->stats_disable_count = 1; + mutex_init(&efx->mac_lock); + efx->mac_op = &efx_dummy_mac_operations; + efx->phy_op = &efx_dummy_phy_operations; +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/drivers/net/sfc/efx.h linux-2.6.29-rc3.owrt/drivers/net/sfc/efx.h +--- linux-2.6.29.owrt/drivers/net/sfc/efx.h 2009-05-10 22:04:38.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/drivers/net/sfc/efx.h 2009-05-10 23:48:29.000000000 +0200 +@@ -36,16 +36,13 @@ + extern void efx_flush_queues(struct efx_nic *efx); + + /* Ports */ +-extern void efx_stats_disable(struct efx_nic *efx); +-extern void efx_stats_enable(struct efx_nic *efx); + extern void efx_reconfigure_port(struct efx_nic *efx); + extern void __efx_reconfigure_port(struct efx_nic *efx); + + /* Reset handling */ +-extern void efx_reset_down(struct efx_nic *efx, enum reset_type method, +- struct ethtool_cmd *ecmd); +-extern int efx_reset_up(struct efx_nic *efx, enum reset_type method, +- struct ethtool_cmd *ecmd, bool ok); ++extern void efx_reset_down(struct efx_nic *efx, struct ethtool_cmd *ecmd); ++extern int efx_reset_up(struct efx_nic *efx, struct ethtool_cmd *ecmd, ++ bool ok); + + /* Global */ + extern void efx_schedule_reset(struct efx_nic *efx, enum reset_type type); +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/drivers/net/sfc/ethtool.c linux-2.6.29-rc3.owrt/drivers/net/sfc/ethtool.c +--- linux-2.6.29.owrt/drivers/net/sfc/ethtool.c 2009-05-10 22:04:38.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/drivers/net/sfc/ethtool.c 2009-05-10 23:48:29.000000000 +0200 +@@ -219,6 +219,9 @@ + struct efx_nic *efx = netdev_priv(net_dev); + int rc; + ++ if (EFX_WORKAROUND_13963(efx) && !ecmd->autoneg) ++ return -EINVAL; ++ + /* Falcon GMAC does not support 1000Mbps HD */ + if (ecmd->speed == SPEED_1000 && ecmd->duplex != DUPLEX_FULL) { + EFX_LOG(efx, "rejecting unsupported 1000Mbps HD" +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/drivers/net/sfc/falcon.c linux-2.6.29-rc3.owrt/drivers/net/sfc/falcon.c +--- linux-2.6.29.owrt/drivers/net/sfc/falcon.c 2009-05-10 22:04:38.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/drivers/net/sfc/falcon.c 2009-05-10 23:48:29.000000000 +0200 +@@ -824,6 +824,10 @@ + rx_ev_pause_frm ? " [PAUSE]" : ""); + } + #endif ++ ++ if (unlikely(rx_ev_eth_crc_err && EFX_WORKAROUND_10750(efx) && ++ efx->phy_type == PHY_TYPE_SFX7101)) ++ tenxpress_crc_err(efx); + } + + /* Handle receive events that are not in-order. */ +@@ -1883,7 +1887,7 @@ + + /* MAC stats will fail whilst the TX fifo is draining. Serialise + * the drain sequence with the statistics fetch */ +- efx_stats_disable(efx); ++ spin_lock(&efx->stats_lock); + + falcon_read(efx, ®, MAC0_CTRL_REG_KER); + EFX_SET_OWORD_FIELD(reg, TXFIFO_DRAIN_EN_B0, 1); +@@ -1913,7 +1917,7 @@ + udelay(10); + } + +- efx_stats_enable(efx); ++ spin_unlock(&efx->stats_lock); + + /* If we've reset the EM block and the link is up, then + * we'll have to kick the XAUI link so the PHY can recover */ +@@ -2273,10 +2277,6 @@ + struct efx_mac_operations *old_mac_op = efx->mac_op; + efx_oword_t nic_stat; + unsigned strap_val; +- int rc = 0; +- +- /* Don't try to fetch MAC stats while we're switching MACs */ +- efx_stats_disable(efx); + + /* Internal loopbacks override the phy speed setting */ + if (efx->loopback_mode == LOOPBACK_GMAC) { +@@ -2287,12 +2287,16 @@ + efx->link_fd = true; + } + +- WARN_ON(!mutex_is_locked(&efx->mac_lock)); + efx->mac_op = (EFX_IS10G(efx) ? + &falcon_xmac_operations : &falcon_gmac_operations); ++ if (old_mac_op == efx->mac_op) ++ return 0; ++ ++ WARN_ON(!mutex_is_locked(&efx->mac_lock)); ++ ++ /* Not all macs support a mac-level link state */ ++ efx->mac_up = true; + +- /* Always push the NIC_STAT_REG setting even if the mac hasn't +- * changed, because this function is run post online reset */ + falcon_read(efx, &nic_stat, NIC_STAT_REG); + strap_val = EFX_IS10G(efx) ? 5 : 3; + if (falcon_rev(efx) >= FALCON_REV_B0) { +@@ -2305,17 +2309,9 @@ + BUG_ON(EFX_OWORD_FIELD(nic_stat, STRAP_PINS) != strap_val); + } + +- if (old_mac_op == efx->mac_op) +- goto out; + + EFX_LOG(efx, "selected %cMAC\n", EFX_IS10G(efx) ? 'X' : 'G'); +- /* Not all macs support a mac-level link state */ +- efx->mac_up = true; +- +- rc = falcon_reset_macs(efx); +-out: +- efx_stats_enable(efx); +- return rc; ++ return falcon_reset_macs(efx); + } + + /* This call is responsible for hooking in the MAC and PHY operations */ +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/drivers/net/sfc/mdio_10g.c linux-2.6.29-rc3.owrt/drivers/net/sfc/mdio_10g.c +--- linux-2.6.29.owrt/drivers/net/sfc/mdio_10g.c 2009-05-10 22:04:38.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/drivers/net/sfc/mdio_10g.c 2009-05-10 23:48:29.000000000 +0200 +@@ -15,7 +15,6 @@ + #include "net_driver.h" + #include "mdio_10g.h" + #include "boards.h" +-#include "workarounds.h" + + int mdio_clause45_reset_mmd(struct efx_nic *port, int mmd, + int spins, int spintime) +@@ -180,12 +179,17 @@ + return false; + else if (efx_phy_mode_disabled(efx->phy_mode)) + return false; +- else if (efx->loopback_mode == LOOPBACK_PHYXS) ++ else if (efx->loopback_mode == LOOPBACK_PHYXS) { + mmd_mask &= ~(MDIO_MMDREG_DEVS_PHYXS | + MDIO_MMDREG_DEVS_PCS | + MDIO_MMDREG_DEVS_PMAPMD | + MDIO_MMDREG_DEVS_AN); +- else if (efx->loopback_mode == LOOPBACK_PCS) ++ if (!mmd_mask) { ++ reg = mdio_clause45_read(efx, phy_id, MDIO_MMD_PHYXS, ++ MDIO_PHYXS_STATUS2); ++ return !(reg & (1 << MDIO_PHYXS_STATUS2_RX_FAULT_LBN)); ++ } ++ } else if (efx->loopback_mode == LOOPBACK_PCS) + mmd_mask &= ~(MDIO_MMDREG_DEVS_PCS | + MDIO_MMDREG_DEVS_PMAPMD | + MDIO_MMDREG_DEVS_AN); +@@ -193,13 +197,6 @@ + mmd_mask &= ~(MDIO_MMDREG_DEVS_PMAPMD | + MDIO_MMDREG_DEVS_AN); + +- if (!mmd_mask) { +- /* Use presence of XGMII faults in leui of link state */ +- reg = mdio_clause45_read(efx, phy_id, MDIO_MMD_PHYXS, +- MDIO_PHYXS_STATUS2); +- return !(reg & (1 << MDIO_PHYXS_STATUS2_RX_FAULT_LBN)); +- } +- + while (mmd_mask) { + if (mmd_mask & 1) { + /* Double reads because link state is latched, and a +@@ -266,7 +263,7 @@ + } + } + +-static u32 mdio_clause45_get_an(struct efx_nic *efx, u16 addr) ++static u32 mdio_clause45_get_an(struct efx_nic *efx, u16 addr, u32 xnp) + { + int phy_id = efx->mii.phy_id; + u32 result = 0; +@@ -281,6 +278,9 @@ + result |= ADVERTISED_100baseT_Half; + if (reg & ADVERTISE_100FULL) + result |= ADVERTISED_100baseT_Full; ++ if (reg & LPA_RESV) ++ result |= xnp; ++ + return result; + } + +@@ -310,7 +310,7 @@ + */ + void mdio_clause45_get_settings_ext(struct efx_nic *efx, + struct ethtool_cmd *ecmd, +- u32 npage_adv, u32 npage_lpa) ++ u32 xnp, u32 xnp_lpa) + { + int phy_id = efx->mii.phy_id; + int reg; +@@ -361,8 +361,8 @@ + ecmd->autoneg = AUTONEG_ENABLE; + ecmd->advertising |= + ADVERTISED_Autoneg | +- mdio_clause45_get_an(efx, MDIO_AN_ADVERTISE) | +- npage_adv; ++ mdio_clause45_get_an(efx, ++ MDIO_AN_ADVERTISE, xnp); + } else + ecmd->autoneg = AUTONEG_DISABLE; + } else +@@ -371,30 +371,27 @@ + if (ecmd->autoneg) { + /* If AN is complete, report best common mode, + * otherwise report best advertised mode. */ +- u32 modes = 0; ++ u32 common = ecmd->advertising; + if (mdio_clause45_read(efx, phy_id, MDIO_MMD_AN, + MDIO_MMDREG_STAT1) & +- (1 << MDIO_AN_STATUS_AN_DONE_LBN)) +- modes = (ecmd->advertising & +- (mdio_clause45_get_an(efx, MDIO_AN_LPA) | +- npage_lpa)); +- if (modes == 0) +- modes = ecmd->advertising; +- +- if (modes & ADVERTISED_10000baseT_Full) { ++ (1 << MDIO_AN_STATUS_AN_DONE_LBN)) { ++ common &= mdio_clause45_get_an(efx, MDIO_AN_LPA, ++ xnp_lpa); ++ } ++ if (common & ADVERTISED_10000baseT_Full) { + ecmd->speed = SPEED_10000; + ecmd->duplex = DUPLEX_FULL; +- } else if (modes & (ADVERTISED_1000baseT_Full | +- ADVERTISED_1000baseT_Half)) { ++ } else if (common & (ADVERTISED_1000baseT_Full | ++ ADVERTISED_1000baseT_Half)) { + ecmd->speed = SPEED_1000; +- ecmd->duplex = !!(modes & ADVERTISED_1000baseT_Full); +- } else if (modes & (ADVERTISED_100baseT_Full | +- ADVERTISED_100baseT_Half)) { ++ ecmd->duplex = !!(common & ADVERTISED_1000baseT_Full); ++ } else if (common & (ADVERTISED_100baseT_Full | ++ ADVERTISED_100baseT_Half)) { + ecmd->speed = SPEED_100; +- ecmd->duplex = !!(modes & ADVERTISED_100baseT_Full); ++ ecmd->duplex = !!(common & ADVERTISED_100baseT_Full); + } else { + ecmd->speed = SPEED_10; +- ecmd->duplex = !!(modes & ADVERTISED_10baseT_Full); ++ ecmd->duplex = !!(common & ADVERTISED_10baseT_Full); + } + } else { + /* Report forced settings */ +@@ -418,7 +415,7 @@ + int phy_id = efx->mii.phy_id; + struct ethtool_cmd prev; + u32 required; +- int reg; ++ int ctrl1_bits, reg; + + efx->phy_op->get_settings(efx, &prev); + +@@ -433,83 +430,99 @@ + if (prev.port != PORT_TP || ecmd->port != PORT_TP) + return -EINVAL; + +- /* Check that PHY supports these settings */ +- if (ecmd->autoneg) { +- required = SUPPORTED_Autoneg; +- } else if (ecmd->duplex) { ++ /* Check that PHY supports these settings and work out the ++ * basic control bits */ ++ if (ecmd->duplex) { + switch (ecmd->speed) { +- case SPEED_10: required = SUPPORTED_10baseT_Full; break; +- case SPEED_100: required = SUPPORTED_100baseT_Full; break; +- default: return -EINVAL; ++ case SPEED_10: ++ ctrl1_bits = BMCR_FULLDPLX; ++ required = SUPPORTED_10baseT_Full; ++ break; ++ case SPEED_100: ++ ctrl1_bits = BMCR_SPEED100 | BMCR_FULLDPLX; ++ required = SUPPORTED_100baseT_Full; ++ break; ++ case SPEED_1000: ++ ctrl1_bits = BMCR_SPEED1000 | BMCR_FULLDPLX; ++ required = SUPPORTED_1000baseT_Full; ++ break; ++ case SPEED_10000: ++ ctrl1_bits = (BMCR_SPEED1000 | BMCR_SPEED100 | ++ BMCR_FULLDPLX); ++ required = SUPPORTED_10000baseT_Full; ++ break; ++ default: ++ return -EINVAL; + } + } else { + switch (ecmd->speed) { +- case SPEED_10: required = SUPPORTED_10baseT_Half; break; +- case SPEED_100: required = SUPPORTED_100baseT_Half; break; +- default: return -EINVAL; ++ case SPEED_10: ++ ctrl1_bits = 0; ++ required = SUPPORTED_10baseT_Half; ++ break; ++ case SPEED_100: ++ ctrl1_bits = BMCR_SPEED100; ++ required = SUPPORTED_100baseT_Half; ++ break; ++ case SPEED_1000: ++ ctrl1_bits = BMCR_SPEED1000; ++ required = SUPPORTED_1000baseT_Half; ++ break; ++ default: ++ return -EINVAL; + } + } ++ if (ecmd->autoneg) ++ required |= SUPPORTED_Autoneg; + required |= ecmd->advertising; + if (required & ~prev.supported) + return -EINVAL; + +- if (ecmd->autoneg) { +- bool xnp = (ecmd->advertising & ADVERTISED_10000baseT_Full +- || EFX_WORKAROUND_13204(efx)); +- +- /* Set up the base page */ +- reg = ADVERTISE_CSMA; +- if (ecmd->advertising & ADVERTISED_10baseT_Half) +- reg |= ADVERTISE_10HALF; +- if (ecmd->advertising & ADVERTISED_10baseT_Full) +- reg |= ADVERTISE_10FULL; +- if (ecmd->advertising & ADVERTISED_100baseT_Half) +- reg |= ADVERTISE_100HALF; +- if (ecmd->advertising & ADVERTISED_100baseT_Full) +- reg |= ADVERTISE_100FULL; +- if (xnp) +- reg |= ADVERTISE_RESV; +- else if (ecmd->advertising & (ADVERTISED_1000baseT_Half | +- ADVERTISED_1000baseT_Full)) +- reg |= ADVERTISE_NPAGE; +- reg |= efx_fc_advertise(efx->wanted_fc); +- mdio_clause45_write(efx, phy_id, MDIO_MMD_AN, +- MDIO_AN_ADVERTISE, reg); +- +- /* Set up the (extended) next page if necessary */ +- if (efx->phy_op->set_npage_adv) +- efx->phy_op->set_npage_adv(efx, ecmd->advertising); ++ /* Set the basic control bits */ ++ reg = mdio_clause45_read(efx, phy_id, MDIO_MMD_PMAPMD, ++ MDIO_MMDREG_CTRL1); ++ reg &= ~(BMCR_SPEED1000 | BMCR_SPEED100 | BMCR_FULLDPLX | 0x003c); ++ reg |= ctrl1_bits; ++ mdio_clause45_write(efx, phy_id, MDIO_MMD_PMAPMD, MDIO_MMDREG_CTRL1, ++ reg); ++ ++ /* Set the AN registers */ ++ if (ecmd->autoneg != prev.autoneg || ++ ecmd->advertising != prev.advertising) { ++ bool xnp = false; ++ ++ if (efx->phy_op->set_xnp_advertise) ++ xnp = efx->phy_op->set_xnp_advertise(efx, ++ ecmd->advertising); ++ ++ if (ecmd->autoneg) { ++ reg = 0; ++ if (ecmd->advertising & ADVERTISED_10baseT_Half) ++ reg |= ADVERTISE_10HALF; ++ if (ecmd->advertising & ADVERTISED_10baseT_Full) ++ reg |= ADVERTISE_10FULL; ++ if (ecmd->advertising & ADVERTISED_100baseT_Half) ++ reg |= ADVERTISE_100HALF; ++ if (ecmd->advertising & ADVERTISED_100baseT_Full) ++ reg |= ADVERTISE_100FULL; ++ if (xnp) ++ reg |= ADVERTISE_RESV; ++ mdio_clause45_write(efx, phy_id, MDIO_MMD_AN, ++ MDIO_AN_ADVERTISE, reg); ++ } + +- /* Enable and restart AN */ + reg = mdio_clause45_read(efx, phy_id, MDIO_MMD_AN, + MDIO_MMDREG_CTRL1); +- reg |= BMCR_ANENABLE; +- if (!(EFX_WORKAROUND_15195(efx) && +- LOOPBACK_MASK(efx) & efx->phy_op->loopbacks)) +- reg |= BMCR_ANRESTART; ++ if (ecmd->autoneg) ++ reg |= BMCR_ANENABLE | BMCR_ANRESTART; ++ else ++ reg &= ~BMCR_ANENABLE; + if (xnp) + reg |= 1 << MDIO_AN_CTRL_XNP_LBN; + else + reg &= ~(1 << MDIO_AN_CTRL_XNP_LBN); + mdio_clause45_write(efx, phy_id, MDIO_MMD_AN, + MDIO_MMDREG_CTRL1, reg); +- } else { +- /* Disable AN */ +- mdio_clause45_set_flag(efx, phy_id, MDIO_MMD_AN, +- MDIO_MMDREG_CTRL1, +- __ffs(BMCR_ANENABLE), false); +- +- /* Set the basic control bits */ +- reg = mdio_clause45_read(efx, phy_id, MDIO_MMD_PMAPMD, +- MDIO_MMDREG_CTRL1); +- reg &= ~(BMCR_SPEED1000 | BMCR_SPEED100 | BMCR_FULLDPLX | +- 0x003c); +- if (ecmd->speed == SPEED_100) +- reg |= BMCR_SPEED100; +- if (ecmd->duplex) +- reg |= BMCR_FULLDPLX; +- mdio_clause45_write(efx, phy_id, MDIO_MMD_PMAPMD, +- MDIO_MMDREG_CTRL1, reg); + } + + return 0; +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/drivers/net/sfc/mdio_10g.h linux-2.6.29-rc3.owrt/drivers/net/sfc/mdio_10g.h +--- linux-2.6.29.owrt/drivers/net/sfc/mdio_10g.h 2009-05-10 22:04:38.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/drivers/net/sfc/mdio_10g.h 2009-05-10 23:48:29.000000000 +0200 +@@ -155,8 +155,7 @@ + #define MDIO_AN_XNP 22 + #define MDIO_AN_LPA_XNP 25 + +-#define MDIO_AN_10GBT_CTRL 32 +-#define MDIO_AN_10GBT_CTRL_ADV_10G_LBN 12 ++#define MDIO_AN_10GBT_ADVERTISE 32 + #define MDIO_AN_10GBT_STATUS (33) + #define MDIO_AN_10GBT_STATUS_MS_FLT_LBN (15) /* MASTER/SLAVE config fault */ + #define MDIO_AN_10GBT_STATUS_MS_LBN (14) /* MASTER/SLAVE config */ +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/drivers/net/sfc/net_driver.h linux-2.6.29-rc3.owrt/drivers/net/sfc/net_driver.h +--- linux-2.6.29.owrt/drivers/net/sfc/net_driver.h 2009-05-10 22:04:38.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/drivers/net/sfc/net_driver.h 2009-05-10 23:48:29.000000000 +0200 +@@ -566,7 +566,7 @@ + * @poll: Poll for hardware state. Serialised by the mac_lock. + * @get_settings: Get ethtool settings. Serialised by the mac_lock. + * @set_settings: Set ethtool settings. Serialised by the mac_lock. +- * @set_npage_adv: Set abilities advertised in (Extended) Next Page ++ * @set_xnp_advertise: Set abilities advertised in Extended Next Page + * (only needed where AN bit is set in mmds) + * @num_tests: Number of PHY-specific tests/results + * @test_names: Names of the tests/results +@@ -586,7 +586,7 @@ + struct ethtool_cmd *ecmd); + int (*set_settings) (struct efx_nic *efx, + struct ethtool_cmd *ecmd); +- void (*set_npage_adv) (struct efx_nic *efx, u32); ++ bool (*set_xnp_advertise) (struct efx_nic *efx, u32); + u32 num_tests; + const char *const *test_names; + int (*run_tests) (struct efx_nic *efx, int *results, unsigned flags); +@@ -754,7 +754,8 @@ + * &struct net_device_stats. + * @stats_buffer: DMA buffer for statistics + * @stats_lock: Statistics update lock. Serialises statistics fetches +- * @stats_disable_count: Nest count for disabling statistics fetches ++ * @stats_enabled: Temporarily disable statistics fetches. ++ * Serialised by @stats_lock + * @mac_op: MAC interface + * @mac_address: Permanent MAC address + * @phy_type: PHY type +@@ -836,7 +837,7 @@ + struct efx_mac_stats mac_stats; + struct efx_buffer stats_buffer; + spinlock_t stats_lock; +- unsigned int stats_disable_count; ++ bool stats_enabled; + + struct efx_mac_operations *mac_op; + unsigned char mac_address[ETH_ALEN]; +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/drivers/net/sfc/phy.h linux-2.6.29-rc3.owrt/drivers/net/sfc/phy.h +--- linux-2.6.29.owrt/drivers/net/sfc/phy.h 2009-05-10 22:04:38.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/drivers/net/sfc/phy.h 2009-05-10 23:48:29.000000000 +0200 +@@ -17,6 +17,7 @@ + extern struct efx_phy_operations falcon_sft9001_phy_ops; + + extern void tenxpress_phy_blink(struct efx_nic *efx, bool blink); ++extern void tenxpress_crc_err(struct efx_nic *efx); + + /**************************************************************************** + * Exported functions from the driver for XFP optical PHYs +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/drivers/net/sfc/selftest.c linux-2.6.29-rc3.owrt/drivers/net/sfc/selftest.c +--- linux-2.6.29.owrt/drivers/net/sfc/selftest.c 2009-05-10 22:04:38.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/drivers/net/sfc/selftest.c 2009-05-10 23:48:29.000000000 +0200 +@@ -665,7 +665,6 @@ + { + enum efx_loopback_mode loopback_mode = efx->loopback_mode; + int phy_mode = efx->phy_mode; +- enum reset_type reset_method = RESET_TYPE_INVISIBLE; + struct ethtool_cmd ecmd; + struct efx_channel *channel; + int rc_test = 0, rc_reset = 0, rc; +@@ -719,21 +718,21 @@ + mutex_unlock(&efx->mac_lock); + + /* free up all consumers of SRAM (including all the queues) */ +- efx_reset_down(efx, reset_method, &ecmd); ++ efx_reset_down(efx, &ecmd); + + rc = efx_test_chip(efx, tests); + if (rc && !rc_test) + rc_test = rc; + + /* reset the chip to recover from the register test */ +- rc_reset = falcon_reset_hw(efx, reset_method); ++ rc_reset = falcon_reset_hw(efx, RESET_TYPE_ALL); + + /* Ensure that the phy is powered and out of loopback + * for the bist and loopback tests */ + efx->phy_mode &= ~PHY_MODE_LOW_POWER; + efx->loopback_mode = LOOPBACK_NONE; + +- rc = efx_reset_up(efx, reset_method, &ecmd, rc_reset == 0); ++ rc = efx_reset_up(efx, &ecmd, rc_reset == 0); + if (rc && !rc_reset) + rc_reset = rc; + +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/drivers/net/sfc/sfe4001.c linux-2.6.29-rc3.owrt/drivers/net/sfc/sfe4001.c +--- linux-2.6.29.owrt/drivers/net/sfc/sfe4001.c 2009-05-10 22:04:38.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/drivers/net/sfc/sfe4001.c 2009-05-10 23:48:29.000000000 +0200 +@@ -186,22 +186,19 @@ + { + efx_oword_t reg; + +- /* GPIO 3 and the GPIO register are shared with I2C, so block that */ ++ /* GPIO pins are also used for I2C, so block that temporarily */ + mutex_lock(&efx->i2c_adap.bus_lock); + +- /* Pull RST_N (GPIO 2) low then let it up again, setting the +- * FLASH_CFG_1 strap (GPIO 3) appropriately. Only change the +- * output enables; the output levels should always be 0 (low) +- * and we rely on external pull-ups. */ + falcon_read(efx, ®, GPIO_CTL_REG_KER); + EFX_SET_OWORD_FIELD(reg, GPIO2_OEN, true); ++ EFX_SET_OWORD_FIELD(reg, GPIO2_OUT, false); + falcon_write(efx, ®, GPIO_CTL_REG_KER); + msleep(1000); +- EFX_SET_OWORD_FIELD(reg, GPIO2_OEN, false); +- EFX_SET_OWORD_FIELD(reg, GPIO3_OEN, +- !!(efx->phy_mode & PHY_MODE_SPECIAL)); ++ EFX_SET_OWORD_FIELD(reg, GPIO2_OUT, true); ++ EFX_SET_OWORD_FIELD(reg, GPIO3_OEN, true); ++ EFX_SET_OWORD_FIELD(reg, GPIO3_OUT, ++ !(efx->phy_mode & PHY_MODE_SPECIAL)); + falcon_write(efx, ®, GPIO_CTL_REG_KER); +- msleep(1); + + mutex_unlock(&efx->i2c_adap.bus_lock); + +@@ -235,18 +232,12 @@ + } else if (efx->state != STATE_RUNNING || netif_running(efx->net_dev)) { + err = -EBUSY; + } else { +- /* Reset the PHY, reconfigure the MAC and enable/disable +- * MAC stats accordingly. */ + efx->phy_mode = new_mode; +- if (new_mode & PHY_MODE_SPECIAL) +- efx_stats_disable(efx); + if (efx->board_info.type == EFX_BOARD_SFE4001) + err = sfe4001_poweron(efx); + else + err = sfn4111t_reset(efx); + efx_reconfigure_port(efx); +- if (!(new_mode & PHY_MODE_SPECIAL)) +- efx_stats_enable(efx); + } + rtnl_unlock(); + +@@ -335,11 +326,6 @@ + efx->board_info.monitor = sfe4001_check_hw; + efx->board_info.fini = sfe4001_fini; + +- if (efx->phy_mode & PHY_MODE_SPECIAL) { +- /* PHY won't generate a 156.25 MHz clock and MAC stats fetch +- * will fail. */ +- efx_stats_disable(efx); +- } + rc = sfe4001_poweron(efx); + if (rc) + goto fail_ioexp; +@@ -386,25 +372,17 @@ + i2c_unregister_device(efx->board_info.hwmon_client); + } + +-static struct i2c_board_info sfn4111t_a0_hwmon_info = { ++static struct i2c_board_info sfn4111t_hwmon_info = { + I2C_BOARD_INFO("max6647", 0x4e), + .irq = -1, + }; + +-static struct i2c_board_info sfn4111t_r5_hwmon_info = { +- I2C_BOARD_INFO("max6646", 0x4d), +- .irq = -1, +-}; +- + int sfn4111t_init(struct efx_nic *efx) + { + int rc; + + efx->board_info.hwmon_client = +- i2c_new_device(&efx->i2c_adap, +- (efx->board_info.minor < 5) ? +- &sfn4111t_a0_hwmon_info : +- &sfn4111t_r5_hwmon_info); ++ i2c_new_device(&efx->i2c_adap, &sfn4111t_hwmon_info); + if (!efx->board_info.hwmon_client) + return -EIO; + +@@ -416,10 +394,8 @@ + if (rc) + goto fail_hwmon; + +- if (efx->phy_mode & PHY_MODE_SPECIAL) { +- efx_stats_disable(efx); ++ if (efx->phy_mode & PHY_MODE_SPECIAL) + sfn4111t_reset(efx); +- } + + return 0; + +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/drivers/net/sfc/tenxpress.c linux-2.6.29-rc3.owrt/drivers/net/sfc/tenxpress.c +--- linux-2.6.29.owrt/drivers/net/sfc/tenxpress.c 2009-05-10 22:04:38.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/drivers/net/sfc/tenxpress.c 2009-05-10 23:48:29.000000000 +0200 +@@ -67,8 +67,6 @@ + #define PMA_PMD_EXT_CLK312_WIDTH 1 + #define PMA_PMD_EXT_LPOWER_LBN 12 + #define PMA_PMD_EXT_LPOWER_WIDTH 1 +-#define PMA_PMD_EXT_ROBUST_LBN 14 +-#define PMA_PMD_EXT_ROBUST_WIDTH 1 + #define PMA_PMD_EXT_SSR_LBN 15 + #define PMA_PMD_EXT_SSR_WIDTH 1 + +@@ -179,24 +177,35 @@ + #define C22EXT_STATUS_LINK_LBN 2 + #define C22EXT_STATUS_LINK_WIDTH 1 + +-#define C22EXT_MSTSLV_CTRL 49161 +-#define C22EXT_MSTSLV_CTRL_ADV_1000_HD_LBN 8 +-#define C22EXT_MSTSLV_CTRL_ADV_1000_FD_LBN 9 +- +-#define C22EXT_MSTSLV_STATUS 49162 +-#define C22EXT_MSTSLV_STATUS_LP_1000_HD_LBN 10 +-#define C22EXT_MSTSLV_STATUS_LP_1000_FD_LBN 11 ++#define C22EXT_MSTSLV_REG 49162 ++#define C22EXT_MSTSLV_1000_HD_LBN 10 ++#define C22EXT_MSTSLV_1000_HD_WIDTH 1 ++#define C22EXT_MSTSLV_1000_FD_LBN 11 ++#define C22EXT_MSTSLV_1000_FD_WIDTH 1 + + /* Time to wait between powering down the LNPGA and turning off the power + * rails */ + #define LNPGA_PDOWN_WAIT (HZ / 5) + ++static int crc_error_reset_threshold = 100; ++module_param(crc_error_reset_threshold, int, 0644); ++MODULE_PARM_DESC(crc_error_reset_threshold, ++ "Max number of CRC errors before XAUI reset"); ++ + struct tenxpress_phy_data { + enum efx_loopback_mode loopback_mode; ++ atomic_t bad_crc_count; + enum efx_phy_mode phy_mode; + int bad_lp_tries; + }; + ++void tenxpress_crc_err(struct efx_nic *efx) ++{ ++ struct tenxpress_phy_data *phy_data = efx->phy_data; ++ if (phy_data != NULL) ++ atomic_inc(&phy_data->bad_crc_count); ++} ++ + static ssize_t show_phy_short_reach(struct device *dev, + struct device_attribute *attr, char *buf) + { +@@ -275,9 +284,7 @@ + PMA_PMD_XCONTROL_REG); + reg |= ((1 << PMA_PMD_EXT_GMII_EN_LBN) | + (1 << PMA_PMD_EXT_CLK_OUT_LBN) | +- (1 << PMA_PMD_EXT_CLK312_LBN) | +- (1 << PMA_PMD_EXT_ROBUST_LBN)); +- ++ (1 << PMA_PMD_EXT_CLK312_LBN)); + mdio_clause45_write(efx, phy_id, MDIO_MMD_PMAPMD, + PMA_PMD_XCONTROL_REG, reg); + mdio_clause45_set_flag(efx, phy_id, MDIO_MMD_C22EXT, +@@ -339,7 +346,6 @@ + rc = tenxpress_init(efx); + if (rc < 0) + goto fail; +- mdio_clause45_set_pause(efx); + + if (efx->phy_type == PHY_TYPE_SFT9001B) { + rc = device_create_file(&efx->pci_dev->dev, +@@ -370,8 +376,8 @@ + + /* The XGMAC clock is driven from the SFC7101/SFT9001 312MHz clock, so + * a special software reset can glitch the XGMAC sufficiently for stats +- * requests to fail. */ +- efx_stats_disable(efx); ++ * requests to fail. Since we don't often special_reset, just lock. */ ++ spin_lock(&efx->stats_lock); + + /* Initiate reset */ + reg = mdio_clause45_read(efx, efx->mii.phy_id, +@@ -386,17 +392,17 @@ + rc = mdio_clause45_wait_reset_mmds(efx, + TENXPRESS_REQUIRED_DEVS); + if (rc < 0) +- goto out; ++ goto unlock; + + /* Try and reconfigure the device */ + rc = tenxpress_init(efx); + if (rc < 0) +- goto out; ++ goto unlock; + + /* Wait for the XGXS state machine to churn */ + mdelay(10); +-out: +- efx_stats_enable(efx); ++unlock: ++ spin_unlock(&efx->stats_lock); + return rc; + } + +@@ -514,7 +520,7 @@ + { + struct tenxpress_phy_data *phy_data = efx->phy_data; + struct ethtool_cmd ecmd; +- bool phy_mode_change, loop_reset; ++ bool phy_mode_change, loop_reset, loop_toggle, loopback; + + if (efx->phy_mode & (PHY_MODE_OFF | PHY_MODE_SPECIAL)) { + phy_data->phy_mode = efx->phy_mode; +@@ -525,10 +531,12 @@ + + phy_mode_change = (efx->phy_mode == PHY_MODE_NORMAL && + phy_data->phy_mode != PHY_MODE_NORMAL); ++ loopback = LOOPBACK_MASK(efx) & efx->phy_op->loopbacks; ++ loop_toggle = LOOPBACK_CHANGED(phy_data, efx, efx->phy_op->loopbacks); + loop_reset = (LOOPBACK_OUT_OF(phy_data, efx, efx->phy_op->loopbacks) || + LOOPBACK_CHANGED(phy_data, efx, 1 << LOOPBACK_GPHY)); + +- if (loop_reset || phy_mode_change) { ++ if (loop_reset || loop_toggle || loopback || phy_mode_change) { + int rc; + + efx->phy_op->get_settings(efx, &ecmd); +@@ -543,6 +551,20 @@ + falcon_reset_xaui(efx); + } + ++ if (efx->phy_type != PHY_TYPE_SFX7101) { ++ /* Only change autoneg once, on coming out or ++ * going into loopback */ ++ if (loop_toggle) ++ ecmd.autoneg = !loopback; ++ if (loopback) { ++ ecmd.duplex = DUPLEX_FULL; ++ if (efx->loopback_mode == LOOPBACK_GPHY) ++ ecmd.speed = SPEED_1000; ++ else ++ ecmd.speed = SPEED_10000; ++ } ++ } ++ + rc = efx->phy_op->set_settings(efx, &ecmd); + WARN_ON(rc); + } +@@ -601,6 +623,13 @@ + + if (phy_data->phy_mode != PHY_MODE_NORMAL) + return; ++ ++ if (EFX_WORKAROUND_10750(efx) && ++ atomic_read(&phy_data->bad_crc_count) > crc_error_reset_threshold) { ++ EFX_ERR(efx, "Resetting XAUI due to too many CRC errors\n"); ++ falcon_reset_xaui(efx); ++ atomic_set(&phy_data->bad_crc_count, 0); ++ } + } + + static void tenxpress_phy_fini(struct efx_nic *efx) +@@ -743,76 +772,107 @@ + return rc; + } + +-static void +-tenxpress_get_settings(struct efx_nic *efx, struct ethtool_cmd *ecmd) ++static u32 tenxpress_get_xnp_lpa(struct efx_nic *efx) + { +- int phy_id = efx->mii.phy_id; +- u32 adv = 0, lpa = 0; ++ int phy = efx->mii.phy_id; ++ u32 lpa = 0; + int reg; + + if (efx->phy_type != PHY_TYPE_SFX7101) { +- reg = mdio_clause45_read(efx, phy_id, MDIO_MMD_C22EXT, +- C22EXT_MSTSLV_CTRL); +- if (reg & (1 << C22EXT_MSTSLV_CTRL_ADV_1000_FD_LBN)) +- adv |= ADVERTISED_1000baseT_Full; +- reg = mdio_clause45_read(efx, phy_id, MDIO_MMD_C22EXT, +- C22EXT_MSTSLV_STATUS); +- if (reg & (1 << C22EXT_MSTSLV_STATUS_LP_1000_HD_LBN)) ++ reg = mdio_clause45_read(efx, phy, MDIO_MMD_C22EXT, ++ C22EXT_MSTSLV_REG); ++ if (reg & (1 << C22EXT_MSTSLV_1000_HD_LBN)) + lpa |= ADVERTISED_1000baseT_Half; +- if (reg & (1 << C22EXT_MSTSLV_STATUS_LP_1000_FD_LBN)) ++ if (reg & (1 << C22EXT_MSTSLV_1000_FD_LBN)) + lpa |= ADVERTISED_1000baseT_Full; + } +- reg = mdio_clause45_read(efx, phy_id, MDIO_MMD_AN, +- MDIO_AN_10GBT_CTRL); +- if (reg & (1 << MDIO_AN_10GBT_CTRL_ADV_10G_LBN)) +- adv |= ADVERTISED_10000baseT_Full; +- reg = mdio_clause45_read(efx, phy_id, MDIO_MMD_AN, +- MDIO_AN_10GBT_STATUS); ++ reg = mdio_clause45_read(efx, phy, MDIO_MMD_AN, MDIO_AN_10GBT_STATUS); + if (reg & (1 << MDIO_AN_10GBT_STATUS_LP_10G_LBN)) + lpa |= ADVERTISED_10000baseT_Full; +- +- mdio_clause45_get_settings_ext(efx, ecmd, adv, lpa); +- +- if (efx->phy_type != PHY_TYPE_SFX7101) +- ecmd->supported |= (SUPPORTED_100baseT_Full | +- SUPPORTED_1000baseT_Full); +- +- /* In loopback, the PHY automatically brings up the correct interface, +- * but doesn't advertise the correct speed. So override it */ +- if (efx->loopback_mode == LOOPBACK_GPHY) +- ecmd->speed = SPEED_1000; +- else if (LOOPBACK_MASK(efx) & efx->phy_op->loopbacks) +- ecmd->speed = SPEED_10000; ++ return lpa; + } + +-static int tenxpress_set_settings(struct efx_nic *efx, struct ethtool_cmd *ecmd) ++static void sfx7101_get_settings(struct efx_nic *efx, struct ethtool_cmd *ecmd) + { +- if (!ecmd->autoneg) +- return -EINVAL; +- +- return mdio_clause45_set_settings(efx, ecmd); ++ mdio_clause45_get_settings_ext(efx, ecmd, ADVERTISED_10000baseT_Full, ++ tenxpress_get_xnp_lpa(efx)); ++ ecmd->supported |= SUPPORTED_10000baseT_Full; ++ ecmd->advertising |= ADVERTISED_10000baseT_Full; + } + +-static void sfx7101_set_npage_adv(struct efx_nic *efx, u32 advertising) ++static void sft9001_get_settings(struct efx_nic *efx, struct ethtool_cmd *ecmd) + { +- mdio_clause45_set_flag(efx, efx->mii.phy_id, MDIO_MMD_AN, +- MDIO_AN_10GBT_CTRL, +- MDIO_AN_10GBT_CTRL_ADV_10G_LBN, +- advertising & ADVERTISED_10000baseT_Full); ++ int phy_id = efx->mii.phy_id; ++ u32 xnp_adv = 0; ++ int reg; ++ ++ reg = mdio_clause45_read(efx, phy_id, MDIO_MMD_PMAPMD, ++ PMA_PMD_SPEED_ENABLE_REG); ++ if (EFX_WORKAROUND_13204(efx) && (reg & (1 << PMA_PMD_100TX_ADV_LBN))) ++ xnp_adv |= ADVERTISED_100baseT_Full; ++ if (reg & (1 << PMA_PMD_1000T_ADV_LBN)) ++ xnp_adv |= ADVERTISED_1000baseT_Full; ++ if (reg & (1 << PMA_PMD_10000T_ADV_LBN)) ++ xnp_adv |= ADVERTISED_10000baseT_Full; ++ ++ mdio_clause45_get_settings_ext(efx, ecmd, xnp_adv, ++ tenxpress_get_xnp_lpa(efx)); ++ ++ ecmd->supported |= (SUPPORTED_100baseT_Half | ++ SUPPORTED_100baseT_Full | ++ SUPPORTED_1000baseT_Full); ++ ++ /* Use the vendor defined C22ext register for duplex settings */ ++ if (ecmd->speed != SPEED_10000 && !ecmd->autoneg) { ++ reg = mdio_clause45_read(efx, phy_id, MDIO_MMD_C22EXT, ++ GPHY_XCONTROL_REG); ++ ecmd->duplex = (reg & (1 << GPHY_DUPLEX_LBN) ? ++ DUPLEX_FULL : DUPLEX_HALF); ++ } + } + +-static void sft9001_set_npage_adv(struct efx_nic *efx, u32 advertising) ++static int sft9001_set_settings(struct efx_nic *efx, struct ethtool_cmd *ecmd) + { + int phy_id = efx->mii.phy_id; ++ int rc; + +- mdio_clause45_set_flag(efx, phy_id, MDIO_MMD_C22EXT, +- C22EXT_MSTSLV_CTRL, +- C22EXT_MSTSLV_CTRL_ADV_1000_FD_LBN, +- advertising & ADVERTISED_1000baseT_Full); +- mdio_clause45_set_flag(efx, phy_id, MDIO_MMD_AN, +- MDIO_AN_10GBT_CTRL, +- MDIO_AN_10GBT_CTRL_ADV_10G_LBN, +- advertising & ADVERTISED_10000baseT_Full); ++ rc = mdio_clause45_set_settings(efx, ecmd); ++ if (rc) ++ return rc; ++ ++ if (ecmd->speed != SPEED_10000 && !ecmd->autoneg) ++ mdio_clause45_set_flag(efx, phy_id, MDIO_MMD_C22EXT, ++ GPHY_XCONTROL_REG, GPHY_DUPLEX_LBN, ++ ecmd->duplex == DUPLEX_FULL); ++ ++ return rc; ++} ++ ++static bool sft9001_set_xnp_advertise(struct efx_nic *efx, u32 advertising) ++{ ++ int phy = efx->mii.phy_id; ++ int reg = mdio_clause45_read(efx, phy, MDIO_MMD_PMAPMD, ++ PMA_PMD_SPEED_ENABLE_REG); ++ bool enabled; ++ ++ reg &= ~((1 << 2) | (1 << 3)); ++ if (EFX_WORKAROUND_13204(efx) && ++ (advertising & ADVERTISED_100baseT_Full)) ++ reg |= 1 << PMA_PMD_100TX_ADV_LBN; ++ if (advertising & ADVERTISED_1000baseT_Full) ++ reg |= 1 << PMA_PMD_1000T_ADV_LBN; ++ if (advertising & ADVERTISED_10000baseT_Full) ++ reg |= 1 << PMA_PMD_10000T_ADV_LBN; ++ mdio_clause45_write(efx, phy, MDIO_MMD_PMAPMD, ++ PMA_PMD_SPEED_ENABLE_REG, reg); ++ ++ enabled = (advertising & ++ (ADVERTISED_1000baseT_Half | ++ ADVERTISED_1000baseT_Full | ++ ADVERTISED_10000baseT_Full)); ++ if (EFX_WORKAROUND_13204(efx)) ++ enabled |= (advertising & ADVERTISED_100baseT_Full); ++ return enabled; + } + + struct efx_phy_operations falcon_sfx7101_phy_ops = { +@@ -822,9 +882,8 @@ + .poll = tenxpress_phy_poll, + .fini = tenxpress_phy_fini, + .clear_interrupt = efx_port_dummy_op_void, +- .get_settings = tenxpress_get_settings, +- .set_settings = tenxpress_set_settings, +- .set_npage_adv = sfx7101_set_npage_adv, ++ .get_settings = sfx7101_get_settings, ++ .set_settings = mdio_clause45_set_settings, + .num_tests = ARRAY_SIZE(sfx7101_test_names), + .test_names = sfx7101_test_names, + .run_tests = sfx7101_run_tests, +@@ -839,9 +898,9 @@ + .poll = tenxpress_phy_poll, + .fini = tenxpress_phy_fini, + .clear_interrupt = efx_port_dummy_op_void, +- .get_settings = tenxpress_get_settings, +- .set_settings = tenxpress_set_settings, +- .set_npage_adv = sft9001_set_npage_adv, ++ .get_settings = sft9001_get_settings, ++ .set_settings = sft9001_set_settings, ++ .set_xnp_advertise = sft9001_set_xnp_advertise, + .num_tests = ARRAY_SIZE(sft9001_test_names), + .test_names = sft9001_test_names, + .run_tests = sft9001_run_tests, +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/drivers/net/sfc/workarounds.h linux-2.6.29-rc3.owrt/drivers/net/sfc/workarounds.h +--- linux-2.6.29.owrt/drivers/net/sfc/workarounds.h 2009-05-10 22:04:38.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/drivers/net/sfc/workarounds.h 2009-05-10 23:48:29.000000000 +0200 +@@ -18,8 +18,8 @@ + #define EFX_WORKAROUND_ALWAYS(efx) 1 + #define EFX_WORKAROUND_FALCON_A(efx) (falcon_rev(efx) <= FALCON_REV_A1) + #define EFX_WORKAROUND_10G(efx) EFX_IS10G(efx) +-#define EFX_WORKAROUND_SFT9001(efx) ((efx)->phy_type == PHY_TYPE_SFT9001A || \ +- (efx)->phy_type == PHY_TYPE_SFT9001B) ++#define EFX_WORKAROUND_SFX7101(efx) ((efx)->phy_type == PHY_TYPE_SFX7101) ++#define EFX_WORKAROUND_SFT9001A(efx) ((efx)->phy_type == PHY_TYPE_SFT9001A) + + /* XAUI resets if link not detected */ + #define EFX_WORKAROUND_5147 EFX_WORKAROUND_ALWAYS +@@ -29,6 +29,8 @@ + #define EFX_WORKAROUND_7884 EFX_WORKAROUND_10G + /* TX pkt parser problem with <= 16 byte TXes */ + #define EFX_WORKAROUND_9141 EFX_WORKAROUND_ALWAYS ++/* Low rate CRC errors require XAUI reset */ ++#define EFX_WORKAROUND_10750 EFX_WORKAROUND_SFX7101 + /* TX_EV_PKT_ERR can be caused by a dangling TX descriptor + * or a PCIe error (bug 11028) */ + #define EFX_WORKAROUND_10727 EFX_WORKAROUND_ALWAYS +@@ -53,8 +55,8 @@ + #define EFX_WORKAROUND_8071 EFX_WORKAROUND_FALCON_A + + /* Need to send XNP pages for 100BaseT */ +-#define EFX_WORKAROUND_13204 EFX_WORKAROUND_SFT9001 +-/* Don't restart AN in near-side loopback */ +-#define EFX_WORKAROUND_15195 EFX_WORKAROUND_SFT9001 ++#define EFX_WORKAROUND_13204 EFX_WORKAROUND_SFT9001A ++/* Need to keep AN enabled */ ++#define EFX_WORKAROUND_13963 EFX_WORKAROUND_SFT9001A + + #endif /* EFX_WORKAROUNDS_H */ +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/drivers/net/sh_eth.c linux-2.6.29-rc3.owrt/drivers/net/sh_eth.c +--- linux-2.6.29.owrt/drivers/net/sh_eth.c 2009-05-10 22:04:38.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/drivers/net/sh_eth.c 2009-05-10 23:48:29.000000000 +0200 +@@ -687,7 +687,6 @@ + { + struct net_device *ndev = netdev; + struct sh_eth_private *mdp = netdev_priv(ndev); +- irqreturn_t ret = IRQ_NONE; + u32 ioaddr, boguscnt = RX_RING_SIZE; + u32 intr_status = 0; + +@@ -697,13 +696,7 @@ + /* Get interrpt stat */ + intr_status = ctrl_inl(ioaddr + EESR); + /* Clear interrupt */ +- if (intr_status & (EESR_FRC | EESR_RMAF | EESR_RRF | +- EESR_RTLF | EESR_RTSF | EESR_PRE | EESR_CERF | +- TX_CHECK | EESR_ERR_CHECK)) { +- ctrl_outl(intr_status, ioaddr + EESR); +- ret = IRQ_HANDLED; +- } else +- goto other_irq; ++ ctrl_outl(intr_status, ioaddr + EESR); + + if (intr_status & (EESR_FRC | /* Frame recv*/ + EESR_RMAF | /* Multi cast address recv*/ +@@ -730,10 +723,9 @@ + ndev->name, intr_status); + } + +-other_irq: + spin_unlock(&mdp->lock); + +- return ret; ++ return IRQ_HANDLED; + } + + static void sh_eth_timer(unsigned long data) +@@ -852,13 +844,7 @@ + int ret = 0; + struct sh_eth_private *mdp = netdev_priv(ndev); + +- ret = request_irq(ndev->irq, &sh_eth_interrupt, +-#if defined(CONFIG_CPU_SUBTYPE_SH7763) || defined(CONFIG_CPU_SUBTYPE_SH7764) +- IRQF_SHARED, +-#else +- 0, +-#endif +- ndev->name, ndev); ++ ret = request_irq(ndev->irq, &sh_eth_interrupt, 0, ndev->name, ndev); + if (ret) { + printk(KERN_ERR "Can not assign IRQ number to %s\n", CARDNAME); + return ret; +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/drivers/net/sh_eth.h linux-2.6.29-rc3.owrt/drivers/net/sh_eth.h +--- linux-2.6.29.owrt/drivers/net/sh_eth.h 2009-05-10 22:04:38.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/drivers/net/sh_eth.h 2009-05-10 23:48:29.000000000 +0200 +@@ -43,8 +43,8 @@ + + #define SH7763_SKB_ALIGN 32 + /* Chip Base Address */ +-# define SH_TSU_ADDR 0xFEE01800 +-# define ARSTR SH_TSU_ADDR ++# define SH_TSU_ADDR 0xFFE01800 ++# define ARSTR 0xFFE01800 + + /* Chip Registers */ + /* E-DMAC */ +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/drivers/net/skfp/skfddi.c linux-2.6.29-rc3.owrt/drivers/net/skfp/skfddi.c +--- linux-2.6.29.owrt/drivers/net/skfp/skfddi.c 2009-05-10 22:04:38.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/drivers/net/skfp/skfddi.c 2009-05-10 23:48:29.000000000 +0200 +@@ -1003,9 +1003,9 @@ + break; + case SKFP_CLR_STATS: /* Zero out the driver statistics */ + if (!capable(CAP_NET_ADMIN)) { +- status = -EPERM; +- } else { + memset(&lp->MacStat, 0, sizeof(lp->MacStat)); ++ } else { ++ status = -EPERM; + } + break; + default: +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/drivers/net/sky2.c linux-2.6.29-rc3.owrt/drivers/net/sky2.c +--- linux-2.6.29.owrt/drivers/net/sky2.c 2009-05-10 22:04:38.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/drivers/net/sky2.c 2009-05-10 23:48:29.000000000 +0200 +@@ -1403,6 +1403,9 @@ + + } + ++ if (netif_msg_ifup(sky2)) ++ printk(KERN_INFO PFX "%s: enabling interface\n", dev->name); ++ + netif_carrier_off(dev); + + /* must be power of 2 */ +@@ -1481,9 +1484,6 @@ + sky2_write32(hw, B0_IMSK, imask); + + sky2_set_multicast(dev); +- +- if (netif_msg_ifup(sky2)) +- printk(KERN_INFO PFX "%s: enabling interface\n", dev->name); + return 0; + + err_out: +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/drivers/net/smc911x.c linux-2.6.29-rc3.owrt/drivers/net/smc911x.c +--- linux-2.6.29.owrt/drivers/net/smc911x.c 2009-05-10 22:04:38.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/drivers/net/smc911x.c 2009-05-10 23:48:29.000000000 +0200 +@@ -220,9 +220,9 @@ + + /* make sure EEPROM has finished loading before setting GPIO_CFG */ + timeout=1000; +- while (--timeout && (SMC_GET_E2P_CMD(lp) & E2P_CMD_EPC_BUSY_)) ++ while ( timeout-- && (SMC_GET_E2P_CMD(lp) & E2P_CMD_EPC_BUSY_)) { + udelay(10); +- ++ } + if (timeout == 0){ + PRINTK("%s: smc911x_reset timeout waiting for EEPROM busy\n", dev->name); + return; +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/drivers/net/smc911x.h linux-2.6.29-rc3.owrt/drivers/net/smc911x.h +--- linux-2.6.29.owrt/drivers/net/smc911x.h 2009-05-10 22:04:38.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/drivers/net/smc911x.h 2009-05-10 23:48:29.000000000 +0200 +@@ -42,16 +42,6 @@ + #define SMC_USE_16BIT 0 + #define SMC_USE_32BIT 1 + #define SMC_IRQ_SENSE IRQF_TRIGGER_LOW +-#elif defined(CONFIG_ARCH_OMAP34XX) +- #define SMC_USE_16BIT 0 +- #define SMC_USE_32BIT 1 +- #define SMC_IRQ_SENSE IRQF_TRIGGER_LOW +- #define SMC_MEM_RESERVED 1 +-#elif defined(CONFIG_ARCH_OMAP24XX) +- #define SMC_USE_16BIT 0 +- #define SMC_USE_32BIT 1 +- #define SMC_IRQ_SENSE IRQF_TRIGGER_LOW +- #define SMC_MEM_RESERVED 1 + #else + /* + * Default configuration +@@ -685,7 +675,6 @@ + #define CHIP_9116 0x0116 + #define CHIP_9117 0x0117 + #define CHIP_9118 0x0118 +-#define CHIP_9211 0x9211 + #define CHIP_9215 0x115A + #define CHIP_9217 0x117A + #define CHIP_9218 0x118A +@@ -700,7 +689,6 @@ + { CHIP_9116, "LAN9116" }, + { CHIP_9117, "LAN9117" }, + { CHIP_9118, "LAN9118" }, +- { CHIP_9211, "LAN9211" }, + { CHIP_9215, "LAN9215" }, + { CHIP_9217, "LAN9217" }, + { CHIP_9218, "LAN9218" }, +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/drivers/net/smsc911x.c linux-2.6.29-rc3.owrt/drivers/net/smsc911x.c +--- linux-2.6.29.owrt/drivers/net/smsc911x.c 2009-05-10 22:04:38.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/drivers/net/smsc911x.c 2009-05-10 23:48:29.000000000 +0200 +@@ -953,7 +953,7 @@ + do { + udelay(1); + val = smsc911x_reg_read(pdata, RX_DP_CTRL); +- } while (--timeout && (val & RX_DP_CTRL_RX_FFWD_)); ++ } while (timeout-- && (val & RX_DP_CTRL_RX_FFWD_)); + + if (unlikely(timeout == 0)) + SMSC_WARNING(HW, "Timed out waiting for " +@@ -1225,10 +1225,6 @@ + dev_info(&dev->dev, "SMSC911x/921x identified at %#08lx, IRQ: %d\n", + (unsigned long)pdata->ioaddr, dev->irq); + +- /* Reset the last known duplex and carrier */ +- pdata->last_duplex = -1; +- pdata->last_carrier = -1; +- + /* Bring the PHY up */ + phy_start(pdata->phy_dev); + +@@ -1628,7 +1624,7 @@ + do { + msleep(1); + e2cmd = smsc911x_reg_read(pdata, E2P_CMD); +- } while ((e2cmd & E2P_CMD_EPC_BUSY_) && (--timeout)); ++ } while ((e2cmd & E2P_CMD_EPC_BUSY_) && (timeout--)); + + if (!timeout) { + SMSC_TRACE(DRV, "TIMED OUT"); +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/drivers/net/smsc9420.c linux-2.6.29-rc3.owrt/drivers/net/smsc9420.c +--- linux-2.6.29.owrt/drivers/net/smsc9420.c 2009-05-10 22:04:38.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/drivers/net/smsc9420.c 2009-05-10 23:48:29.000000000 +0200 +@@ -341,7 +341,7 @@ + do { + msleep(1); + e2cmd = smsc9420_reg_read(pd, E2P_CMD); +- } while ((e2cmd & E2P_CMD_EPC_BUSY_) && (--timeout)); ++ } while ((e2cmd & E2P_CMD_EPC_BUSY_) && (timeout--)); + + if (!timeout) { + smsc_info(HW, "TIMED OUT"); +@@ -413,7 +413,6 @@ + } + + memcpy(data, &eeprom_data[eeprom->offset], len); +- eeprom->magic = SMSC9420_EEPROM_MAGIC; + eeprom->len = len; + return 0; + } +@@ -424,9 +423,6 @@ + struct smsc9420_pdata *pd = netdev_priv(dev); + int ret; + +- if (eeprom->magic != SMSC9420_EEPROM_MAGIC) +- return -EINVAL; +- + smsc9420_eeprom_enable_access(pd); + smsc9420_eeprom_send_cmd(pd, E2P_CMD_EPC_CMD_EWEN_); + ret = smsc9420_eeprom_write_location(pd, eeprom->offset, *data); +@@ -502,7 +498,7 @@ + static void smsc9420_stop_tx(struct smsc9420_pdata *pd) + { + u32 dmac_control, mac_cr, dma_intr_ena; +- int timeout = 1000; ++ int timeOut = 1000; + + /* disable TX DMAC */ + dmac_control = smsc9420_reg_read(pd, DMAC_CONTROL); +@@ -510,13 +506,13 @@ + smsc9420_reg_write(pd, DMAC_CONTROL, dmac_control); + + /* Wait max 10ms for transmit process to stop */ +- while (--timeout) { ++ while (timeOut--) { + if (smsc9420_reg_read(pd, DMAC_STATUS) & DMAC_STS_TS_) + break; + udelay(10); + } + +- if (!timeout) ++ if (!timeOut) + smsc_warn(IFDOWN, "TX DMAC failed to stop"); + + /* ACK Tx DMAC stop bit */ +@@ -600,7 +596,7 @@ + + static void smsc9420_stop_rx(struct smsc9420_pdata *pd) + { +- int timeout = 1000; ++ int timeOut = 1000; + u32 mac_cr, dmac_control, dma_intr_ena; + + /* mask RX DMAC interrupts */ +@@ -621,13 +617,13 @@ + smsc9420_pci_flush_write(pd); + + /* wait up to 10ms for receive to stop */ +- while (--timeout) { ++ while (timeOut--) { + if (smsc9420_reg_read(pd, DMAC_STATUS) & DMAC_STS_RS_) + break; + udelay(10); + } + +- if (!timeout) ++ if (!timeOut) + smsc_warn(IFDOWN, "RX DMAC did not stop! timeout."); + + /* ACK the Rx DMAC stop bit */ +@@ -1382,7 +1378,6 @@ + + /* test the IRQ connection to the ISR */ + smsc_dbg(IFUP, "Testing ISR using IRQ %d", dev->irq); +- pd->software_irq_signal = false; + + spin_lock_irqsave(&pd->int_lock, flags); + /* configure interrupt deassertion timer and enable interrupts */ +@@ -1398,6 +1393,8 @@ + smsc9420_pci_flush_write(pd); + + timeout = 1000; ++ pd->software_irq_signal = false; ++ smp_wmb(); + while (timeout--) { + if (pd->software_irq_signal) + break; +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/drivers/net/smsc9420.h linux-2.6.29-rc3.owrt/drivers/net/smsc9420.h +--- linux-2.6.29.owrt/drivers/net/smsc9420.h 2009-05-10 22:04:38.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/drivers/net/smsc9420.h 2009-05-10 23:48:29.000000000 +0200 +@@ -44,7 +44,6 @@ + #define LAN_REGISTER_EXTENT (0x400) + + #define SMSC9420_EEPROM_SIZE ((u32)11) +-#define SMSC9420_EEPROM_MAGIC (0x9420) + + #define PKT_BUF_SZ (VLAN_ETH_FRAME_LEN + NET_IP_ALIGN + 4) + +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/drivers/net/sun3lance.c linux-2.6.29-rc3.owrt/drivers/net/sun3lance.c +--- linux-2.6.29.owrt/drivers/net/sun3lance.c 2009-05-10 22:04:38.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/drivers/net/sun3lance.c 2009-05-10 23:48:29.000000000 +0200 +@@ -428,7 +428,7 @@ + while (--i > 0) + if (DREG & CSR0_IDON) + break; +- if (i <= 0 || (DREG & CSR0_ERR)) { ++ if (i < 0 || (DREG & CSR0_ERR)) { + DPRINTK( 2, ( "lance_open(): opening %s failed, i=%d, csr0=%04x\n", + dev->name, i, DREG )); + DREG = CSR0_STOP; +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/drivers/net/sundance.c linux-2.6.29-rc3.owrt/drivers/net/sundance.c +--- linux-2.6.29.owrt/drivers/net/sundance.c 2009-05-10 22:04:38.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/drivers/net/sundance.c 2009-05-10 23:48:29.000000000 +0200 +@@ -909,7 +909,7 @@ + printk(KERN_INFO "%s: Setting %s-duplex based on MII #%d " + "negotiated capability %4.4x.\n", dev->name, + duplex ? "full" : "half", np->phys[0], negotiated); +- iowrite16(ioread16(ioaddr + MACCtrl0) | (duplex ? 0x20 : 0), ioaddr + MACCtrl0); ++ iowrite16(ioread16(ioaddr + MACCtrl0) | duplex ? 0x20 : 0, ioaddr + MACCtrl0); + } + } + +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/drivers/net/sungem.c linux-2.6.29-rc3.owrt/drivers/net/sungem.c +--- linux-2.6.29.owrt/drivers/net/sungem.c 2009-05-10 22:04:38.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/drivers/net/sungem.c 2009-05-10 23:48:29.000000000 +0200 +@@ -148,7 +148,7 @@ + cmd |= (MIF_FRAME_TAMSB); + writel(cmd, gp->regs + MIF_FRAME); + +- while (--limit) { ++ while (limit--) { + cmd = readl(gp->regs + MIF_FRAME); + if (cmd & MIF_FRAME_TALSB) + break; +@@ -1157,7 +1157,7 @@ + if (limit-- <= 0) + break; + } +- if (limit < 0) ++ if (limit <= 0) + printk(KERN_WARNING "%s: PCS reset bit would not clear.\n", + gp->dev->name); + } +@@ -1229,7 +1229,7 @@ + break; + } while (val & (GREG_SWRST_TXRST | GREG_SWRST_RXRST)); + +- if (limit < 0) ++ if (limit <= 0) + printk(KERN_ERR "%s: SW reset is ghetto.\n", gp->dev->name); + + if (gp->phy_type == phy_serialink || gp->phy_type == phy_serdes) +@@ -2221,8 +2221,6 @@ + + gp->running = 1; + +- napi_enable(&gp->napi); +- + if (gp->lstate == link_up) { + netif_carrier_on(gp->dev); + gem_set_link_modes(gp); +@@ -2240,8 +2238,6 @@ + spin_lock_irqsave(&gp->lock, flags); + spin_lock(&gp->tx_lock); + +- napi_disable(&gp->napi); +- + gp->running = 0; + gem_reset(gp); + gem_clean_rings(gp); +@@ -2342,6 +2338,8 @@ + if (!gp->asleep) + rc = gem_do_start(dev); + gp->opened = (rc == 0); ++ if (gp->opened) ++ napi_enable(&gp->napi); + + mutex_unlock(&gp->pm_mutex); + +@@ -2478,6 +2476,8 @@ + + /* Re-attach net device */ + netif_device_attach(dev); ++ ++ napi_enable(&gp->napi); + } + + spin_lock_irqsave(&gp->lock, flags); +@@ -2998,11 +2998,8 @@ + .ndo_do_ioctl = gem_ioctl, + .ndo_tx_timeout = gem_tx_timeout, + .ndo_change_mtu = gem_change_mtu, ++ .ndo_set_mac_address = eth_mac_addr, + .ndo_validate_addr = eth_validate_addr, +- .ndo_set_mac_address = gem_set_mac_address, +-#ifdef CONFIG_NET_POLL_CONTROLLER +- .ndo_poll_controller = gem_poll_controller, +-#endif + }; + + static int __devinit gem_init_one(struct pci_dev *pdev, +@@ -3164,6 +3161,10 @@ + dev->watchdog_timeo = 5 * HZ; + dev->irq = pdev->irq; + dev->dma = 0; ++ dev->set_mac_address = gem_set_mac_address; ++#ifdef CONFIG_NET_POLL_CONTROLLER ++ dev->poll_controller = gem_poll_controller; ++#endif + + /* Set that now, in case PM kicks in now */ + pci_set_drvdata(pdev, dev); +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/drivers/net/sungem_phy.c linux-2.6.29-rc3.owrt/drivers/net/sungem_phy.c +--- linux-2.6.29.owrt/drivers/net/sungem_phy.c 2009-05-10 22:04:38.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/drivers/net/sungem_phy.c 2009-05-10 23:48:29.000000000 +0200 +@@ -79,7 +79,7 @@ + + udelay(100); + +- while (--limit) { ++ while (limit--) { + val = __phy_read(phy, phy_id, MII_BMCR); + if ((val & BMCR_RESET) == 0) + break; +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/drivers/net/sunhme.c linux-2.6.29-rc3.owrt/drivers/net/sunhme.c +--- linux-2.6.29.owrt/drivers/net/sunhme.c 2009-05-10 22:04:38.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/drivers/net/sunhme.c 2009-05-10 23:48:29.000000000 +0200 +@@ -2543,36 +2543,25 @@ + } + + /* After all quattro cards have been probed, we call these functions +- * to register the IRQ handlers for the cards that have been +- * successfully probed and skip the cards that failed to initialize ++ * to register the IRQ handlers. + */ +-static int __init quattro_sbus_register_irqs(void) ++static void __init quattro_sbus_register_irqs(void) + { + struct quattro *qp; + + for (qp = qfe_sbus_list; qp != NULL; qp = qp->next) { + struct of_device *op = qp->quattro_dev; +- int err, qfe_slot, skip = 0; +- +- for (qfe_slot = 0; qfe_slot < 4; qfe_slot++) { +- if (!qp->happy_meals[qfe_slot]) +- skip = 1; +- } +- if (skip) +- continue; ++ int err; + + err = request_irq(op->irqs[0], + quattro_sbus_interrupt, + IRQF_SHARED, "Quattro", + qp); + if (err != 0) { +- printk(KERN_ERR "Quattro HME: IRQ registration " +- "error %d.\n", err); +- return err; ++ printk(KERN_ERR "Quattro: Fatal IRQ registery error %d.\n", err); ++ panic("QFE request irq"); + } + } +- +- return 0; + } + + static void quattro_sbus_free_irqs(void) +@@ -2581,14 +2570,6 @@ + + for (qp = qfe_sbus_list; qp != NULL; qp = qp->next) { + struct of_device *op = qp->quattro_dev; +- int qfe_slot, skip = 0; +- +- for (qfe_slot = 0; qfe_slot < 4; qfe_slot++) { +- if (!qp->happy_meals[qfe_slot]) +- skip = 1; +- } +- if (skip) +- continue; + + free_irq(op->irqs[0], qp); + } +@@ -2648,12 +2629,6 @@ + int i, qfe_slot = -1; + int err = -ENODEV; + +- sbus_dp = to_of_device(op->dev.parent)->node; +- +- /* We can match PCI devices too, do not accept those here. */ +- if (strcmp(sbus_dp->name, "sbus")) +- return err; +- + if (is_qfe) { + qp = quattro_sbus_find(op); + if (qp == NULL) +@@ -2759,6 +2734,10 @@ + if (qp != NULL) + hp->happy_flags |= HFLAG_QUATTRO; + ++ sbus_dp = to_of_device(op->dev.parent)->node; ++ if (is_qfe) ++ sbus_dp = to_of_device(op->dev.parent->parent)->node; ++ + /* Get the supported DVMA burst sizes from our Happy SBUS. */ + hp->happy_bursts = of_getintprop_default(sbus_dp, + "burst-sizes", 0x00); +@@ -2845,9 +2824,6 @@ + if (hp->tcvregs) + of_iounmap(&op->resource[4], hp->tcvregs, TCVR_REG_SIZE); + +- if (qp) +- qp->happy_meals[qfe_slot] = NULL; +- + err_out_free_netdev: + free_netdev(dev); + +@@ -3305,7 +3281,7 @@ + + err = of_register_driver(&hme_sbus_driver, &of_bus_type); + if (!err) +- err = quattro_sbus_register_irqs(); ++ quattro_sbus_register_irqs(); + + return err; + } +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/drivers/net/sunlance.c linux-2.6.29-rc3.owrt/drivers/net/sunlance.c +--- linux-2.6.29.owrt/drivers/net/sunlance.c 2009-05-10 22:04:38.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/drivers/net/sunlance.c 2009-05-10 23:48:29.000000000 +0200 +@@ -343,7 +343,7 @@ + ib->phys_addr [5] = dev->dev_addr [4]; + + /* Setup the Tx ring entries */ +- for (i = 0; i < TX_RING_SIZE; i++) { ++ for (i = 0; i <= TX_RING_SIZE; i++) { + leptr = LANCE_ADDR(aib + libbuff_offset(tx_buf, i)); + ib->btx_ring [i].tmd0 = leptr; + ib->btx_ring [i].tmd1_hadr = leptr >> 16; +@@ -399,7 +399,7 @@ + sbus_writeb(dev->dev_addr[4], &ib->phys_addr[5]); + + /* Setup the Tx ring entries */ +- for (i = 0; i < TX_RING_SIZE; i++) { ++ for (i = 0; i <= TX_RING_SIZE; i++) { + leptr = libbuff_offset(tx_buf, i); + sbus_writew(leptr, &ib->btx_ring [i].tmd0); + sbus_writeb(leptr >> 16,&ib->btx_ring [i].tmd1_hadr); +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/drivers/net/sunqe.c linux-2.6.29-rc3.owrt/drivers/net/sunqe.c +--- linux-2.6.29.owrt/drivers/net/sunqe.c 2009-05-10 22:04:38.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/drivers/net/sunqe.c 2009-05-10 23:48:29.000000000 +0200 +@@ -227,7 +227,7 @@ + if (!(sbus_readb(mregs + MREGS_PHYCONFIG) & MREGS_PHYCONFIG_LTESTDIS)) { + int tries = 50; + +- while (--tries) { ++ while (tries--) { + u8 tmp; + + mdelay(5); +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/drivers/net/tg3.c linux-2.6.29-rc3.owrt/drivers/net/tg3.c +--- linux-2.6.29.owrt/drivers/net/tg3.c 2009-05-10 22:04:38.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/drivers/net/tg3.c 2009-05-10 23:48:29.000000000 +0200 +@@ -852,7 +852,7 @@ + } + udelay(10); + } +- if (limit < 0) ++ if (limit <= 0) + return -EBUSY; + + return 0; +@@ -1473,8 +1473,7 @@ + { + u32 reg; + +- if (!(tp->tg3_flags2 & TG3_FLG2_5705_PLUS) || +- GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5906) ++ if (!(tp->tg3_flags2 & TG3_FLG2_5705_PLUS)) + return; + + reg = MII_TG3_MISC_SHDW_WREN | +@@ -1604,7 +1603,7 @@ + break; + } + } +- if (limit < 0) ++ if (limit <= 0) + return -EBUSY; + + return 0; +@@ -2238,8 +2237,8 @@ + phyid = phydev->drv->phy_id & phydev->drv->phy_id_mask; + if (phyid != TG3_PHY_ID_BCMAC131) { + phyid &= TG3_PHY_OUI_MASK; +- if (phyid == TG3_PHY_OUI_1 || +- phyid == TG3_PHY_OUI_2 || ++ if (phyid == TG3_PHY_OUI_1 && ++ phyid == TG3_PHY_OUI_2 && + phyid == TG3_PHY_OUI_3) + do_low_power = true; + } +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/drivers/net/tokenring/tmspci.c linux-2.6.29-rc3.owrt/drivers/net/tokenring/tmspci.c +--- linux-2.6.29.owrt/drivers/net/tokenring/tmspci.c 2009-05-10 22:04:38.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/drivers/net/tokenring/tmspci.c 2009-05-10 23:48:29.000000000 +0200 +@@ -121,6 +121,11 @@ + goto err_out_trdev; + } + ++ ret = request_irq(pdev->irq, tms380tr_interrupt, IRQF_SHARED, ++ dev->name, dev); ++ if (ret) ++ goto err_out_region; ++ + dev->base_addr = pci_ioaddr; + dev->irq = pci_irq_line; + dev->dma = 0; +@@ -137,7 +142,7 @@ + ret = tmsdev_init(dev, &pdev->dev); + if (ret) { + printk("%s: unable to get memory for dev->priv.\n", dev->name); +- goto err_out_region; ++ goto err_out_irq; + } + + tp = netdev_priv(dev); +@@ -152,11 +157,6 @@ + + tp->tmspriv = cardinfo; + +- ret = request_irq(pdev->irq, tms380tr_interrupt, IRQF_SHARED, +- dev->name, dev); +- if (ret) +- goto err_out_tmsdev; +- + dev->open = tms380tr_open; + dev->stop = tms380tr_close; + pci_set_drvdata(pdev, dev); +@@ -164,15 +164,15 @@ + + ret = register_netdev(dev); + if (ret) +- goto err_out_irq; ++ goto err_out_tmsdev; + + return 0; + +-err_out_irq: +- free_irq(pdev->irq, dev); + err_out_tmsdev: + pci_set_drvdata(pdev, NULL); + tmsdev_term(dev); ++err_out_irq: ++ free_irq(pdev->irq, dev); + err_out_region: + release_region(pci_ioaddr, TMS_PCI_IO_EXTENT); + err_out_trdev: +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/drivers/net/tsi108_eth.c linux-2.6.29-rc3.owrt/drivers/net/tsi108_eth.c +--- linux-2.6.29.owrt/drivers/net/tsi108_eth.c 2009-05-10 22:04:38.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/drivers/net/tsi108_eth.c 2009-05-10 23:48:29.000000000 +0200 +@@ -1237,7 +1237,7 @@ + spin_lock_irqsave(&phy_lock, flags); + + tsi108_write_mii(data, MII_BMCR, BMCR_RESET); +- while (--i) { ++ while (i--){ + if(!(tsi108_read_mii(data, MII_BMCR) & BMCR_RESET)) + break; + udelay(10); +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/drivers/net/tulip/21142.c linux-2.6.29-rc3.owrt/drivers/net/tulip/21142.c +--- linux-2.6.29.owrt/drivers/net/tulip/21142.c 2009-05-10 22:04:38.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/drivers/net/tulip/21142.c 2009-05-10 23:48:29.000000000 +0200 +@@ -9,11 +9,6 @@ + + Please refer to Documentation/DocBook/tulip-user.{pdf,ps,html} + for more information on this driver. +- +- DC21143 manual "21143 PCI/CardBus 10/100Mb/s Ethernet LAN Controller +- Hardware Reference Manual" is currently available at : +- http://developer.intel.com/design/network/manuals/278074.htm +- + Please submit bugs to http://bugzilla.kernel.org/ . + */ + +@@ -37,11 +32,7 @@ + int csr12 = ioread32(ioaddr + CSR12); + int next_tick = 60*HZ; + int new_csr6 = 0; +- int csr14 = ioread32(ioaddr + CSR14); + +- /* CSR12[LS10,LS100] are not reliable during autonegotiation */ +- if ((csr14 & 0x80) && (csr12 & 0x7000) != 0x5000) +- csr12 |= 6; + if (tulip_debug > 2) + printk(KERN_INFO"%s: 21143 negotiation status %8.8x, %s.\n", + dev->name, csr12, medianame[dev->if_port]); +@@ -85,7 +76,7 @@ + new_csr6 = 0x83860000; + dev->if_port = 3; + iowrite32(0, ioaddr + CSR13); +- iowrite32(0x0003FFFF, ioaddr + CSR14); ++ iowrite32(0x0003FF7F, ioaddr + CSR14); + iowrite16(8, ioaddr + CSR15); + iowrite32(1, ioaddr + CSR13); + } +@@ -141,14 +132,10 @@ + struct tulip_private *tp = netdev_priv(dev); + void __iomem *ioaddr = tp->base_addr; + int csr12 = ioread32(ioaddr + CSR12); +- int csr14 = ioread32(ioaddr + CSR14); + +- /* CSR12[LS10,LS100] are not reliable during autonegotiation */ +- if ((csr14 & 0x80) && (csr12 & 0x7000) != 0x5000) +- csr12 |= 6; + if (tulip_debug > 1) + printk(KERN_INFO"%s: 21143 link status interrupt %8.8x, CSR5 %x, " +- "%8.8x.\n", dev->name, csr12, csr5, csr14); ++ "%8.8x.\n", dev->name, csr12, csr5, ioread32(ioaddr + CSR14)); + + /* If NWay finished and we have a negotiated partner capability. */ + if (tp->nway && !tp->nwayset && (csr12 & 0x7000) == 0x5000) { +@@ -156,9 +143,7 @@ + int negotiated = tp->sym_advertise & (csr12 >> 16); + tp->lpar = csr12 >> 16; + tp->nwayset = 1; +- /* If partner cannot negotiate, it is 10Mbps Half Duplex */ +- if (!(csr12 & 0x8000)) dev->if_port = 0; +- else if (negotiated & 0x0100) dev->if_port = 5; ++ if (negotiated & 0x0100) dev->if_port = 5; + else if (negotiated & 0x0080) dev->if_port = 3; + else if (negotiated & 0x0040) dev->if_port = 4; + else if (negotiated & 0x0020) dev->if_port = 0; +@@ -229,7 +214,7 @@ + tp->timer.expires = RUN_AT(3*HZ); + add_timer(&tp->timer); + } else if (dev->if_port == 5) +- iowrite32(csr14 & ~0x080, ioaddr + CSR14); ++ iowrite32(ioread32(ioaddr + CSR14) & ~0x080, ioaddr + CSR14); + } else if (dev->if_port == 0 || dev->if_port == 4) { + if ((csr12 & 4) == 0) + printk(KERN_INFO"%s: 21143 10baseT link beat good.\n", +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/drivers/net/tulip/de2104x.c linux-2.6.29-rc3.owrt/drivers/net/tulip/de2104x.c +--- linux-2.6.29.owrt/drivers/net/tulip/de2104x.c 2009-05-10 22:04:38.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/drivers/net/tulip/de2104x.c 2009-05-10 23:48:29.000000000 +0200 +@@ -392,7 +392,7 @@ + unsigned drop = 0; + int rc; + +- while (--rx_work) { ++ while (rx_work--) { + u32 status, len; + dma_addr_t mapping; + struct sk_buff *skb, *copy_skb; +@@ -464,14 +464,13 @@ + drop = 1; + + rx_next: ++ de->rx_ring[rx_tail].opts1 = cpu_to_le32(DescOwn); + if (rx_tail == (DE_RX_RING_SIZE - 1)) + de->rx_ring[rx_tail].opts2 = + cpu_to_le32(RingEnd | de->rx_buf_sz); + else + de->rx_ring[rx_tail].opts2 = cpu_to_le32(de->rx_buf_sz); + de->rx_ring[rx_tail].addr1 = cpu_to_le32(mapping); +- wmb(); +- de->rx_ring[rx_tail].opts1 = cpu_to_le32(DescOwn); + rx_tail = NEXT_RX(rx_tail); + } + +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/drivers/net/tulip/tulip_core.c linux-2.6.29-rc3.owrt/drivers/net/tulip/tulip_core.c +--- linux-2.6.29.owrt/drivers/net/tulip/tulip_core.c 2009-05-10 22:04:38.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/drivers/net/tulip/tulip_core.c 2009-05-10 23:48:29.000000000 +0200 +@@ -255,7 +255,6 @@ + + static void tulip_tx_timeout(struct net_device *dev); + static void tulip_init_ring(struct net_device *dev); +-static void tulip_free_ring(struct net_device *dev); + static int tulip_start_xmit(struct sk_buff *skb, struct net_device *dev); + static int tulip_open(struct net_device *dev); + static int tulip_close(struct net_device *dev); +@@ -503,21 +502,16 @@ + { + int retval; + +- tulip_init_ring (dev); ++ if ((retval = request_irq(dev->irq, &tulip_interrupt, IRQF_SHARED, dev->name, dev))) ++ return retval; + +- retval = request_irq(dev->irq, &tulip_interrupt, IRQF_SHARED, dev->name, dev); +- if (retval) +- goto free_ring; ++ tulip_init_ring (dev); + + tulip_up (dev); + + netif_start_queue (dev); + + return 0; +- +-free_ring: +- tulip_free_ring (dev); +- return retval; + } + + +@@ -774,11 +768,23 @@ + tulip_set_power_state (tp, 0, 1); + } + +-static void tulip_free_ring (struct net_device *dev) ++ ++static int tulip_close (struct net_device *dev) + { + struct tulip_private *tp = netdev_priv(dev); ++ void __iomem *ioaddr = tp->base_addr; + int i; + ++ netif_stop_queue (dev); ++ ++ tulip_down (dev); ++ ++ if (tulip_debug > 1) ++ printk (KERN_DEBUG "%s: Shutting down ethercard, status was %2.2x.\n", ++ dev->name, ioread32 (ioaddr + CSR5)); ++ ++ free_irq (dev->irq, dev); ++ + /* Free all the skbuffs in the Rx queue. */ + for (i = 0; i < RX_RING_SIZE; i++) { + struct sk_buff *skb = tp->rx_buffers[i].skb; +@@ -797,7 +803,6 @@ + dev_kfree_skb (skb); + } + } +- + for (i = 0; i < TX_RING_SIZE; i++) { + struct sk_buff *skb = tp->tx_buffers[i].skb; + +@@ -809,24 +814,6 @@ + tp->tx_buffers[i].skb = NULL; + tp->tx_buffers[i].mapping = 0; + } +-} +- +-static int tulip_close (struct net_device *dev) +-{ +- struct tulip_private *tp = netdev_priv(dev); +- void __iomem *ioaddr = tp->base_addr; +- +- netif_stop_queue (dev); +- +- tulip_down (dev); +- +- if (tulip_debug > 1) +- printk (KERN_DEBUG "%s: Shutting down ethercard, status was %2.2x.\n", +- dev->name, ioread32 (ioaddr + CSR5)); +- +- free_irq (dev->irq, dev); +- +- tulip_free_ring (dev); + + return 0; + } +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/drivers/net/tun.c linux-2.6.29-rc3.owrt/drivers/net/tun.c +--- linux-2.6.29.owrt/drivers/net/tun.c 2009-05-10 22:04:38.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/drivers/net/tun.c 2009-05-10 23:48:29.000000000 +0200 +@@ -157,16 +157,10 @@ + + nexact = n; + +- /* Remaining multicast addresses are hashed, +- * unicast will leave the filter disabled. */ ++ /* The rest is hashed */ + memset(filter->mask, 0, sizeof(filter->mask)); +- for (; n < uf.count; n++) { +- if (!is_multicast_ether_addr(addr[n].u)) { +- err = 0; /* no filter */ +- goto done; +- } ++ for (; n < uf.count; n++) + addr_hash_set(filter->mask, addr[n].u); +- } + + /* For ALLMULTI just set the mask to all ones. + * This overrides the mask populated above. */ +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/drivers/net/ucc_geth.c linux-2.6.29-rc3.owrt/drivers/net/ucc_geth.c +--- linux-2.6.29.owrt/drivers/net/ucc_geth.c 2009-05-10 22:04:38.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/drivers/net/ucc_geth.c 2009-05-10 23:48:29.000000000 +0200 +@@ -1536,15 +1536,17 @@ + static int init_phy(struct net_device *dev) + { + struct ucc_geth_private *priv = netdev_priv(dev); +- struct ucc_geth_info *ug_info = priv->ug_info; + struct phy_device *phydev; ++ char phy_id[BUS_ID_SIZE]; + + priv->oldlink = 0; + priv->oldspeed = 0; + priv->oldduplex = -1; + +- phydev = phy_connect(dev, ug_info->phy_bus_id, &adjust_link, 0, +- priv->phy_interface); ++ snprintf(phy_id, sizeof(phy_id), PHY_ID_FMT, priv->ug_info->mdio_bus, ++ priv->ug_info->phy_address); ++ ++ phydev = phy_connect(dev, phy_id, &adjust_link, 0, priv->phy_interface); + + if (IS_ERR(phydev)) { + printk("%s: Could not attach to PHY\n", dev->name); +@@ -3612,12 +3614,10 @@ + ug_info->uf_info.irq = irq_of_parse_and_map(np, 0); + fixed_link = of_get_property(np, "fixed-link", NULL); + if (fixed_link) { +- snprintf(ug_info->phy_bus_id, sizeof(ug_info->phy_bus_id), +- PHY_ID_FMT, "0", fixed_link[0]); ++ snprintf(ug_info->mdio_bus, MII_BUS_ID_SIZE, "0"); ++ ug_info->phy_address = fixed_link[0]; + phy = NULL; + } else { +- char bus_name[MII_BUS_ID_SIZE]; +- + ph = of_get_property(np, "phy-handle", NULL); + phy = of_find_node_by_phandle(*ph); + +@@ -3628,6 +3628,7 @@ + prop = of_get_property(phy, "reg", NULL); + if (prop == NULL) + return -1; ++ ug_info->phy_address = *prop; + + /* Set the bus id */ + mdio = of_get_parent(phy); +@@ -3641,9 +3642,7 @@ + if (err) + return -1; + +- uec_mdio_bus_name(bus_name, mdio); +- snprintf(ug_info->phy_bus_id, sizeof(ug_info->phy_bus_id), +- "%s:%02x", bus_name, *prop); ++ snprintf(ug_info->mdio_bus, MII_BUS_ID_SIZE, "%x", res.start); + } + + /* get the phy interface type, or default to MII */ +@@ -3749,7 +3748,6 @@ + + ugeth->ug_info = ug_info; + ugeth->dev = dev; +- ugeth->node = np; + + return 0; + } +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/drivers/net/ucc_geth.h linux-2.6.29-rc3.owrt/drivers/net/ucc_geth.h +--- linux-2.6.29.owrt/drivers/net/ucc_geth.h 2009-05-10 22:04:38.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/drivers/net/ucc_geth.h 2009-05-10 23:48:29.000000000 +0200 +@@ -1091,7 +1091,8 @@ + u32 eventRegMask; + u16 pausePeriod; + u16 extensionField; +- char phy_bus_id[BUS_ID_SIZE]; ++ u8 phy_address; ++ char mdio_bus[MII_BUS_ID_SIZE]; + u8 weightfactor[NUM_TX_QUEUES]; + u8 interruptcoalescingmaxvalue[NUM_RX_QUEUES]; + u8 l2qt[UCC_GETH_VLAN_PRIORITY_MAX]; +@@ -1185,8 +1186,6 @@ + int oldspeed; + int oldduplex; + int oldlink; +- +- struct device_node *node; + }; + + void uec_set_ethtool_ops(struct net_device *netdev); +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/drivers/net/ucc_geth_mii.c linux-2.6.29-rc3.owrt/drivers/net/ucc_geth_mii.c +--- linux-2.6.29.owrt/drivers/net/ucc_geth_mii.c 2009-05-10 22:04:38.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/drivers/net/ucc_geth_mii.c 2009-05-10 23:48:29.000000000 +0200 +@@ -107,7 +107,7 @@ + static int uec_mdio_reset(struct mii_bus *bus) + { + struct ucc_mii_mng __iomem *regs = (void __iomem *)bus->priv; +- int timeout = PHY_INIT_TIMEOUT; ++ unsigned int timeout = PHY_INIT_TIMEOUT; + + mutex_lock(&bus->mdio_lock); + +@@ -123,7 +123,7 @@ + + mutex_unlock(&bus->mdio_lock); + +- if (timeout < 0) { ++ if (timeout <= 0) { + printk(KERN_ERR "%s: The MII Bus is stuck!\n", bus->name); + return -EBUSY; + } +@@ -156,7 +156,7 @@ + if (err) + goto reg_map_fail; + +- uec_mdio_bus_name(new_bus->id, np); ++ snprintf(new_bus->id, MII_BUS_ID_SIZE, "%x", res.start); + + new_bus->irq = kmalloc(32 * sizeof(int), GFP_KERNEL); + +@@ -283,13 +283,3 @@ + { + of_unregister_platform_driver(&uec_mdio_driver); + } +- +-void uec_mdio_bus_name(char *name, struct device_node *np) +-{ +- const u32 *reg; +- +- reg = of_get_property(np, "reg", NULL); +- +- snprintf(name, MII_BUS_ID_SIZE, "%s@%x", np->name, reg ? *reg : 0); +-} +- +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/drivers/net/ucc_geth_mii.h linux-2.6.29-rc3.owrt/drivers/net/ucc_geth_mii.h +--- linux-2.6.29.owrt/drivers/net/ucc_geth_mii.h 2009-05-10 22:04:38.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/drivers/net/ucc_geth_mii.h 2009-05-10 23:48:29.000000000 +0200 +@@ -97,5 +97,4 @@ + int uec_mdio_write(struct mii_bus *bus, int mii_id, int regnum, u16 value); + int __init uec_mdio_init(void); + void uec_mdio_exit(void); +-void uec_mdio_bus_name(char *name, struct device_node *np); + #endif /* __UEC_MII_H */ +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/drivers/net/usb/asix.c linux-2.6.29-rc3.owrt/drivers/net/usb/asix.c +--- linux-2.6.29.owrt/drivers/net/usb/asix.c 2009-05-10 22:04:38.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/drivers/net/usb/asix.c 2009-05-10 23:48:29.000000000 +0200 +@@ -1451,14 +1451,6 @@ + // Cables-to-Go USB Ethernet Adapter + USB_DEVICE(0x0b95, 0x772a), + .driver_info = (unsigned long) &ax88772_info, +-}, { +- // ABOCOM for pci +- USB_DEVICE(0x14ea, 0xab11), +- .driver_info = (unsigned long) &ax88178_info, +-}, { +- // ASIX 88772a +- USB_DEVICE(0x0db0, 0xa877), +- .driver_info = (unsigned long) &ax88772_info, + }, + { }, // END + }; +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/drivers/net/usb/cdc_ether.c linux-2.6.29-rc3.owrt/drivers/net/usb/cdc_ether.c +--- linux-2.6.29.owrt/drivers/net/usb/cdc_ether.c 2009-05-10 22:04:38.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/drivers/net/usb/cdc_ether.c 2009-05-10 23:48:29.000000000 +0200 +@@ -559,11 +559,6 @@ + USB_INTERFACE_INFO(USB_CLASS_COMM, USB_CDC_SUBCLASS_ETHERNET, + USB_CDC_PROTO_NONE), + .driver_info = (unsigned long) &cdc_info, +-}, { +- /* Ericsson F3507g */ +- USB_DEVICE_AND_INTERFACE_INFO(0x0bdb, 0x1900, USB_CLASS_COMM, +- USB_CDC_SUBCLASS_MDLM, USB_CDC_PROTO_NONE), +- .driver_info = (unsigned long) &cdc_info, + }, + { }, // END + }; +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/drivers/net/usb/dm9601.c linux-2.6.29-rc3.owrt/drivers/net/usb/dm9601.c +--- linux-2.6.29.owrt/drivers/net/usb/dm9601.c 2009-05-10 22:04:38.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/drivers/net/usb/dm9601.c 2009-05-10 23:48:29.000000000 +0200 +@@ -635,10 +635,6 @@ + USB_DEVICE(0x0a47, 0x9601), /* Hirose USB-100 */ + .driver_info = (unsigned long)&dm9601_info, + }, +- { +- USB_DEVICE(0x0fe6, 0x8101), /* DM9601 USB to Fast Ethernet Adapter */ +- .driver_info = (unsigned long)&dm9601_info, +- }, + {}, // END + }; + +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/drivers/net/usb/hso.c linux-2.6.29-rc3.owrt/drivers/net/usb/hso.c +--- linux-2.6.29.owrt/drivers/net/usb/hso.c 2009-05-10 22:04:38.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/drivers/net/usb/hso.c 2009-05-10 23:48:29.000000000 +0200 +@@ -455,7 +455,6 @@ + {icon321_port_device(0x0af0, 0xd033)}, /* Icon-322 */ + {USB_DEVICE(0x0af0, 0x7301)}, /* GE40x */ + {USB_DEVICE(0x0af0, 0x7361)}, /* GE40x */ +- {USB_DEVICE(0x0af0, 0x7381)}, /* GE40x */ + {USB_DEVICE(0x0af0, 0x7401)}, /* GI 0401 */ + {USB_DEVICE(0x0af0, 0x7501)}, /* GTM 382 */ + {USB_DEVICE(0x0af0, 0x7601)}, /* GE40x */ +@@ -463,8 +462,7 @@ + {USB_DEVICE(0x0af0, 0x7801)}, + {USB_DEVICE(0x0af0, 0x7901)}, + {USB_DEVICE(0x0af0, 0x7361)}, +- {USB_DEVICE(0x0af0, 0xd057)}, +- {USB_DEVICE(0x0af0, 0xd055)}, ++ {icon321_port_device(0x0af0, 0xd051)}, + {} + }; + MODULE_DEVICE_TABLE(usb, hso_ids); +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/drivers/net/usb/usbnet.c linux-2.6.29-rc3.owrt/drivers/net/usb/usbnet.c +--- linux-2.6.29.owrt/drivers/net/usb/usbnet.c 2009-05-10 22:04:38.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/drivers/net/usb/usbnet.c 2009-05-10 23:48:29.000000000 +0200 +@@ -723,8 +723,8 @@ + if (dev->mii.mdio_read) + return mii_link_ok(&dev->mii); + +- /* Otherwise, dtrt for drivers calling netif_carrier_{on,off} */ +- return ethtool_op_get_link(net); ++ /* Otherwise, say we're up (to avoid breaking scripts) */ ++ return 1; + } + EXPORT_SYMBOL_GPL(usbnet_get_link); + +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/drivers/net/usb/zaurus.c linux-2.6.29-rc3.owrt/drivers/net/usb/zaurus.c +--- linux-2.6.29.owrt/drivers/net/usb/zaurus.c 2009-05-10 22:04:38.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/drivers/net/usb/zaurus.c 2009-05-10 23:48:29.000000000 +0200 +@@ -341,11 +341,6 @@ + USB_INTERFACE_INFO(USB_CLASS_COMM, USB_CDC_SUBCLASS_MDLM, + USB_CDC_PROTO_NONE), + .driver_info = (unsigned long) &bogus_mdlm_info, +-}, { +- /* Motorola MOTOMAGX phones */ +- USB_DEVICE_AND_INTERFACE_INFO(0x22b8, 0x6425, USB_CLASS_COMM, +- USB_CDC_SUBCLASS_MDLM, USB_CDC_PROTO_NONE), +- .driver_info = (unsigned long) &bogus_mdlm_info, + }, + + /* Olympus has some models with a Zaurus-compatible option. +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/drivers/net/veth.c linux-2.6.29-rc3.owrt/drivers/net/veth.c +--- linux-2.6.29.owrt/drivers/net/veth.c 2009-05-10 22:04:38.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/drivers/net/veth.c 2009-05-10 23:48:29.000000000 +0200 +@@ -239,16 +239,6 @@ + return 0; + } + +-static int veth_close(struct net_device *dev) +-{ +- struct veth_priv *priv = netdev_priv(dev); +- +- netif_carrier_off(dev); +- netif_carrier_off(priv->peer); +- +- return 0; +-} +- + static int veth_dev_init(struct net_device *dev) + { + struct veth_net_stats *stats; +@@ -273,12 +263,10 @@ + } + + static const struct net_device_ops veth_netdev_ops = { +- .ndo_init = veth_dev_init, +- .ndo_open = veth_open, +- .ndo_stop = veth_close, +- .ndo_start_xmit = veth_xmit, +- .ndo_get_stats = veth_get_stats, +- .ndo_set_mac_address = eth_mac_addr, ++ .ndo_init = veth_dev_init, ++ .ndo_open = veth_open, ++ .ndo_start_xmit = veth_xmit, ++ .ndo_get_stats = veth_get_stats, + }; + + static void veth_setup(struct net_device *dev) +@@ -291,6 +279,44 @@ + dev->destructor = veth_dev_free; + } + ++static void veth_change_state(struct net_device *dev) ++{ ++ struct net_device *peer; ++ struct veth_priv *priv; ++ ++ priv = netdev_priv(dev); ++ peer = priv->peer; ++ ++ if (netif_carrier_ok(peer)) { ++ if (!netif_carrier_ok(dev)) ++ netif_carrier_on(dev); ++ } else { ++ if (netif_carrier_ok(dev)) ++ netif_carrier_off(dev); ++ } ++} ++ ++static int veth_device_event(struct notifier_block *unused, ++ unsigned long event, void *ptr) ++{ ++ struct net_device *dev = ptr; ++ ++ if (dev->netdev_ops->ndo_open != veth_open) ++ goto out; ++ ++ switch (event) { ++ case NETDEV_CHANGE: ++ veth_change_state(dev); ++ break; ++ } ++out: ++ return NOTIFY_DONE; ++} ++ ++static struct notifier_block veth_notifier_block __read_mostly = { ++ .notifier_call = veth_device_event, ++}; ++ + /* + * netlink interface + */ +@@ -441,12 +467,14 @@ + + static __init int veth_init(void) + { ++ register_netdevice_notifier(&veth_notifier_block); + return rtnl_link_register(&veth_link_ops); + } + + static __exit void veth_exit(void) + { + rtnl_link_unregister(&veth_link_ops); ++ unregister_netdevice_notifier(&veth_notifier_block); + } + + module_init(veth_init); +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/drivers/net/via-velocity.c linux-2.6.29-rc3.owrt/drivers/net/via-velocity.c +--- linux-2.6.29.owrt/drivers/net/via-velocity.c 2009-05-10 22:04:38.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/drivers/net/via-velocity.c 2009-05-10 23:48:29.000000000 +0200 +@@ -1838,19 +1838,17 @@ + { + struct sk_buff *skb = tdinfo->skb; + int i; +- int pktlen; + + /* + * Don't unmap the pre-allocated tx_bufs + */ + if (tdinfo->skb_dma) { + +- pktlen = (skb->len > ETH_ZLEN ? : ETH_ZLEN); + for (i = 0; i < tdinfo->nskb_dma; i++) { + #ifdef VELOCITY_ZERO_COPY_SUPPORT + pci_unmap_single(vptr->pdev, tdinfo->skb_dma[i], le16_to_cpu(td->tdesc1.len), PCI_DMA_TODEVICE); + #else +- pci_unmap_single(vptr->pdev, tdinfo->skb_dma[i], pktlen, PCI_DMA_TODEVICE); ++ pci_unmap_single(vptr->pdev, tdinfo->skb_dma[i], skb->len, PCI_DMA_TODEVICE); + #endif + tdinfo->skb_dma[i] = 0; + } +@@ -2082,14 +2080,17 @@ + struct tx_desc *td_ptr; + struct velocity_td_info *tdinfo; + unsigned long flags; +- int pktlen; ++ int pktlen = skb->len; + __le16 len; + int index; + + +- if (skb_padto(skb, ETH_ZLEN)) +- goto out; +- pktlen = max_t(unsigned int, skb->len, ETH_ZLEN); ++ ++ if (skb->len < ETH_ZLEN) { ++ if (skb_padto(skb, ETH_ZLEN)) ++ goto out; ++ pktlen = ETH_ZLEN; ++ } + + len = cpu_to_le16(pktlen); + +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/drivers/net/virtio_net.c linux-2.6.29-rc3.owrt/drivers/net/virtio_net.c +--- linux-2.6.29.owrt/drivers/net/virtio_net.c 2009-05-10 22:04:38.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/drivers/net/virtio_net.c 2009-05-10 23:48:29.000000000 +0200 +@@ -287,7 +287,7 @@ + skb_put(skb, MAX_PACKET_LEN); + + hdr = skb_vnet_hdr(skb); +- sg_set_buf(sg, hdr, sizeof(*hdr)); ++ sg_init_one(sg, hdr, sizeof(*hdr)); + + if (vi->big_packets) { + for (i = 0; i < MAX_SKB_FRAGS; i++) { +@@ -488,9 +488,9 @@ + + /* Encode metadata header at front. */ + if (vi->mergeable_rx_bufs) +- sg_set_buf(sg, mhdr, sizeof(*mhdr)); ++ sg_init_one(sg, mhdr, sizeof(*mhdr)); + else +- sg_set_buf(sg, hdr, sizeof(*hdr)); ++ sg_init_one(sg, hdr, sizeof(*hdr)); + + num = skb_to_sgvec(skb, sg+1, 0, skb->len) + 1; + +@@ -612,7 +612,6 @@ + .set_tx_csum = virtnet_set_tx_csum, + .set_sg = ethtool_op_set_sg, + .set_tso = ethtool_op_set_tso, +- .get_link = ethtool_op_get_link, + }; + + #define MIN_MTU 68 +@@ -740,8 +739,6 @@ + goto unregister; + } + +- netif_carrier_on(dev); +- + pr_debug("virtnet: registered device %s\n", dev->name); + return 0; + +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/drivers/net/wimax/i2400m/debugfs.c linux-2.6.29-rc3.owrt/drivers/net/wimax/i2400m/debugfs.c +--- linux-2.6.29.owrt/drivers/net/wimax/i2400m/debugfs.c 2009-05-10 22:04:38.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/drivers/net/wimax/i2400m/debugfs.c 2009-05-10 23:48:29.000000000 +0200 +@@ -234,6 +234,20 @@ + &fops_i2400m_reset); + } + ++/* ++ * Debug levels control; see debug.h ++ */ ++struct d_level D_LEVEL[] = { ++ D_SUBMODULE_DEFINE(control), ++ D_SUBMODULE_DEFINE(driver), ++ D_SUBMODULE_DEFINE(debugfs), ++ D_SUBMODULE_DEFINE(fw), ++ D_SUBMODULE_DEFINE(netdev), ++ D_SUBMODULE_DEFINE(rfkill), ++ D_SUBMODULE_DEFINE(rx), ++ D_SUBMODULE_DEFINE(tx), ++}; ++size_t D_LEVEL_SIZE = ARRAY_SIZE(D_LEVEL); + + #define __debugfs_register(prefix, name, parent) \ + do { \ +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/drivers/net/wimax/i2400m/driver.c linux-2.6.29-rc3.owrt/drivers/net/wimax/i2400m/driver.c +--- linux-2.6.29.owrt/drivers/net/wimax/i2400m/driver.c 2009-05-10 22:04:38.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/drivers/net/wimax/i2400m/driver.c 2009-05-10 23:48:29.000000000 +0200 +@@ -707,22 +707,6 @@ + EXPORT_SYMBOL_GPL(i2400m_release); + + +-/* +- * Debug levels control; see debug.h +- */ +-struct d_level D_LEVEL[] = { +- D_SUBMODULE_DEFINE(control), +- D_SUBMODULE_DEFINE(driver), +- D_SUBMODULE_DEFINE(debugfs), +- D_SUBMODULE_DEFINE(fw), +- D_SUBMODULE_DEFINE(netdev), +- D_SUBMODULE_DEFINE(rfkill), +- D_SUBMODULE_DEFINE(rx), +- D_SUBMODULE_DEFINE(tx), +-}; +-size_t D_LEVEL_SIZE = ARRAY_SIZE(D_LEVEL); +- +- + static + int __init i2400m_driver_init(void) + { +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/drivers/net/wimax/i2400m/i2400m.h linux-2.6.29-rc3.owrt/drivers/net/wimax/i2400m/i2400m.h +--- linux-2.6.29.owrt/drivers/net/wimax/i2400m/i2400m.h 2009-05-10 22:04:38.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/drivers/net/wimax/i2400m/i2400m.h 2009-05-10 23:48:29.000000000 +0200 +@@ -157,7 +157,7 @@ + + + /* Firmware version we request when pulling the fw image file */ +-#define I2400M_FW_VERSION "1.4" ++#define I2400M_FW_VERSION "1.3" + + + /** +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/drivers/net/wireless/ath5k/base.c linux-2.6.29-rc3.owrt/drivers/net/wireless/ath5k/base.c +--- linux-2.6.29.owrt/drivers/net/wireless/ath5k/base.c 2009-05-10 22:04:38.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/drivers/net/wireless/ath5k/base.c 2009-05-10 23:48:29.000000000 +0200 +@@ -1028,8 +1028,6 @@ + * it's done by reseting the chip. To accomplish this we must + * first cleanup any pending DMA, then restart stuff after a la + * ath5k_init. +- * +- * Called with sc->lock. + */ + static int + ath5k_chan_set(struct ath5k_softc *sc, struct ieee80211_channel *chan) +@@ -1098,42 +1096,6 @@ + * Buffers setup * + \***************/ + +-static +-struct sk_buff *ath5k_rx_skb_alloc(struct ath5k_softc *sc, dma_addr_t *skb_addr) +-{ +- struct sk_buff *skb; +- unsigned int off; +- +- /* +- * Allocate buffer with headroom_needed space for the +- * fake physical layer header at the start. +- */ +- skb = dev_alloc_skb(sc->rxbufsize + sc->cachelsz - 1); +- +- if (!skb) { +- ATH5K_ERR(sc, "can't alloc skbuff of size %u\n", +- sc->rxbufsize + sc->cachelsz - 1); +- return NULL; +- } +- /* +- * Cache-line-align. This is important (for the +- * 5210 at least) as not doing so causes bogus data +- * in rx'd frames. +- */ +- off = ((unsigned long)skb->data) % sc->cachelsz; +- if (off != 0) +- skb_reserve(skb, sc->cachelsz - off); +- +- *skb_addr = pci_map_single(sc->pdev, +- skb->data, sc->rxbufsize, PCI_DMA_FROMDEVICE); +- if (unlikely(pci_dma_mapping_error(sc->pdev, *skb_addr))) { +- ATH5K_ERR(sc, "%s: DMA mapping failed\n", __func__); +- dev_kfree_skb(skb); +- return NULL; +- } +- return skb; +-} +- + static int + ath5k_rxbuf_setup(struct ath5k_softc *sc, struct ath5k_buf *bf) + { +@@ -1141,11 +1103,37 @@ + struct sk_buff *skb = bf->skb; + struct ath5k_desc *ds; + +- if (!skb) { +- skb = ath5k_rx_skb_alloc(sc, &bf->skbaddr); +- if (!skb) ++ if (likely(skb == NULL)) { ++ unsigned int off; ++ ++ /* ++ * Allocate buffer with headroom_needed space for the ++ * fake physical layer header at the start. ++ */ ++ skb = dev_alloc_skb(sc->rxbufsize + sc->cachelsz - 1); ++ if (unlikely(skb == NULL)) { ++ ATH5K_ERR(sc, "can't alloc skbuff of size %u\n", ++ sc->rxbufsize + sc->cachelsz - 1); + return -ENOMEM; ++ } ++ /* ++ * Cache-line-align. This is important (for the ++ * 5210 at least) as not doing so causes bogus data ++ * in rx'd frames. ++ */ ++ off = ((unsigned long)skb->data) % sc->cachelsz; ++ if (off != 0) ++ skb_reserve(skb, sc->cachelsz - off); ++ + bf->skb = skb; ++ bf->skbaddr = pci_map_single(sc->pdev, ++ skb->data, sc->rxbufsize, PCI_DMA_FROMDEVICE); ++ if (unlikely(pci_dma_mapping_error(sc->pdev, bf->skbaddr))) { ++ ATH5K_ERR(sc, "%s: DMA mapping failed\n", __func__); ++ dev_kfree_skb(skb); ++ bf->skb = NULL; ++ return -ENOMEM; ++ } + } + + /* +@@ -1674,8 +1662,7 @@ + { + struct ieee80211_rx_status rxs = {}; + struct ath5k_rx_status rs = {}; +- struct sk_buff *skb, *next_skb; +- dma_addr_t next_skb_addr; ++ struct sk_buff *skb; + struct ath5k_softc *sc = (void *)data; + struct ath5k_buf *bf, *bf_last; + struct ath5k_desc *ds; +@@ -1760,17 +1747,10 @@ + goto next; + } + accept: +- next_skb = ath5k_rx_skb_alloc(sc, &next_skb_addr); +- +- /* +- * If we can't replace bf->skb with a new skb under memory +- * pressure, just skip this packet +- */ +- if (!next_skb) +- goto next; +- + pci_unmap_single(sc->pdev, bf->skbaddr, sc->rxbufsize, + PCI_DMA_FROMDEVICE); ++ bf->skb = NULL; ++ + skb_put(skb, rs.rs_datalen); + + /* The MAC header is padded to have 32-bit boundary if the +@@ -1843,9 +1823,6 @@ + ath5k_check_ibss_tsf(sc, skb, &rxs); + + __ieee80211_rx(sc->hw, skb, &rxs); +- +- bf->skb = next_skb; +- bf->skbaddr = next_skb_addr; + next: + list_move_tail(&bf->list, &sc->rxbuf); + } while (ath5k_rxbuf_setup(sc, bf) == 0); +@@ -2837,17 +2814,11 @@ + { + struct ath5k_softc *sc = hw->priv; + struct ieee80211_conf *conf = &hw->conf; +- int ret; +- +- mutex_lock(&sc->lock); + + sc->bintval = conf->beacon_int; + sc->power_level = conf->power_level; + +- ret = ath5k_chan_set(sc, conf->channel); +- +- mutex_unlock(&sc->lock); +- return ret; ++ return ath5k_chan_set(sc, conf->channel); + } + + static int +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/drivers/net/wireless/ath9k/ath9k.h linux-2.6.29-rc3.owrt/drivers/net/wireless/ath9k/ath9k.h +--- linux-2.6.29.owrt/drivers/net/wireless/ath9k/ath9k.h 2009-05-10 22:04:38.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/drivers/net/wireless/ath9k/ath9k.h 2009-05-10 23:48:29.000000000 +0200 +@@ -587,8 +587,8 @@ + u8 iso[3]; + }; + +-#define REG_WRITE(_ah, _reg, _val) ath9k_iowrite32((_ah), (_reg), (_val)) +-#define REG_READ(_ah, _reg) ath9k_ioread32((_ah), (_reg)) ++#define REG_WRITE(_ah, _reg, _val) iowrite32(_val, _ah->ah_sh + _reg) ++#define REG_READ(_ah, _reg) ioread32(_ah->ah_sh + _reg) + + #define SM(_v, _f) (((_v) << _f##_S) & _f) + #define MS(_v, _f) (((_v) & _f) >> _f##_S) +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/drivers/net/wireless/ath9k/core.h linux-2.6.29-rc3.owrt/drivers/net/wireless/ath9k/core.h +--- linux-2.6.29.owrt/drivers/net/wireless/ath9k/core.h 2009-05-10 22:04:38.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/drivers/net/wireless/ath9k/core.h 2009-05-10 23:48:29.000000000 +0200 +@@ -701,7 +701,6 @@ + struct ath_hal *sc_ah; + void __iomem *mem; + spinlock_t sc_resetlock; +- spinlock_t sc_serial_rw; + struct mutex mutex; + + u8 sc_curbssid[ETH_ALEN]; +@@ -752,36 +751,4 @@ + int ath_get_mac80211_qnum(u32 queue, struct ath_softc *sc); + int ath_cabq_update(struct ath_softc *); + +-/* +- * Read and write, they both share the same lock. We do this to serialize +- * reads and writes on Atheros 802.11n PCI devices only. This is required +- * as the FIFO on these devices can only accept sanely 2 requests. After +- * that the device goes bananas. Serializing the reads/writes prevents this +- * from happening. +- */ +- +-static inline void ath9k_iowrite32(struct ath_hal *ah, u32 reg_offset, u32 val) +-{ +- if (ah->ah_config.serialize_regmode == SER_REG_MODE_ON) { +- unsigned long flags; +- spin_lock_irqsave(&ah->ah_sc->sc_serial_rw, flags); +- iowrite32(val, ah->ah_sc->mem + reg_offset); +- spin_unlock_irqrestore(&ah->ah_sc->sc_serial_rw, flags); +- } else +- iowrite32(val, ah->ah_sc->mem + reg_offset); +-} +- +-static inline unsigned int ath9k_ioread32(struct ath_hal *ah, u32 reg_offset) +-{ +- u32 val; +- if (ah->ah_config.serialize_regmode == SER_REG_MODE_ON) { +- unsigned long flags; +- spin_lock_irqsave(&ah->ah_sc->sc_serial_rw, flags); +- val = ioread32(ah->ah_sc->mem + reg_offset); +- spin_unlock_irqrestore(&ah->ah_sc->sc_serial_rw, flags); +- } else +- val = ioread32(ah->ah_sc->mem + reg_offset); +- return val; +-} +- + #endif /* CORE_H */ +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/drivers/net/wireless/ath9k/hw.c linux-2.6.29-rc3.owrt/drivers/net/wireless/ath9k/hw.c +--- linux-2.6.29.owrt/drivers/net/wireless/ath9k/hw.c 2009-05-10 22:04:38.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/drivers/net/wireless/ath9k/hw.c 2009-05-10 23:48:29.000000000 +0200 +@@ -437,25 +437,6 @@ + } + + ah->ah_config.intr_mitigation = 1; +- +- /* +- * We need this for PCI devices only (Cardbus, PCI, miniPCI) +- * _and_ if on non-uniprocessor systems (Multiprocessor/HT). +- * This means we use it for all AR5416 devices, and the few +- * minor PCI AR9280 devices out there. +- * +- * Serialization is required because these devices do not handle +- * well the case of two concurrent reads/writes due to the latency +- * involved. During one read/write another read/write can be issued +- * on another CPU while the previous read/write may still be working +- * on our hardware, if we hit this case the hardware poops in a loop. +- * We prevent this by serializing reads and writes. +- * +- * This issue is not present on PCI-Express devices or pre-AR5416 +- * devices (legacy, 802.11abg). +- */ +- if (num_possible_cpus() > 1) +- ah->ah_config.serialize_regmode = SER_REG_MODE_AUTO; + } + + static struct ath_hal_5416 *ath9k_hw_newstate(u16 devid, +@@ -687,8 +668,7 @@ + } + + if (ah->ah_config.serialize_regmode == SER_REG_MODE_AUTO) { +- if (ah->ah_macVersion == AR_SREV_VERSION_5416_PCI || +- (AR_SREV_9280(ah) && !ah->ah_isPciExpress)) { ++ if (ah->ah_macVersion == AR_SREV_VERSION_5416_PCI) { + ah->ah_config.serialize_regmode = + SER_REG_MODE_ON; + } else { +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/drivers/net/wireless/ath9k/main.c linux-2.6.29-rc3.owrt/drivers/net/wireless/ath9k/main.c +--- linux-2.6.29.owrt/drivers/net/wireless/ath9k/main.c 2009-05-10 22:04:38.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/drivers/net/wireless/ath9k/main.c 2009-05-10 23:48:29.000000000 +0200 +@@ -1336,7 +1336,6 @@ + printk(KERN_ERR "Unable to create debugfs files\n"); + + spin_lock_init(&sc->sc_resetlock); +- spin_lock_init(&sc->sc_serial_rw); + mutex_init(&sc->mutex); + tasklet_init(&sc->intr_tq, ath9k_tasklet, (unsigned long)sc); + tasklet_init(&sc->bcon_tasklet, ath9k_beacon_tasklet, +@@ -1539,7 +1538,6 @@ + bad: + if (ah) + ath9k_hw_detach(ah); +- ath9k_exit_debug(sc); + + return error; + } +@@ -1547,7 +1545,7 @@ + static int ath_attach(u16 devid, struct ath_softc *sc) + { + struct ieee80211_hw *hw = sc->hw; +- int error = 0, i; ++ int error = 0; + + DPRINTF(sc, ATH_DBG_CONFIG, "Attach ATH hw\n"); + +@@ -1591,11 +1589,11 @@ + /* initialize tx/rx engine */ + error = ath_tx_init(sc, ATH_TXBUF); + if (error != 0) +- goto error_attach; ++ goto detach; + + error = ath_rx_init(sc, ATH_RXBUF); + if (error != 0) +- goto error_attach; ++ goto detach; + + #if defined(CONFIG_RFKILL) || defined(CONFIG_RFKILL_MODULE) + /* Initialze h/w Rfkill */ +@@ -1603,9 +1601,8 @@ + INIT_DELAYED_WORK(&sc->rf_kill.rfkill_poll, ath_rfkill_poll); + + /* Initialize s/w rfkill */ +- error = ath_init_sw_rfkill(sc); +- if (error) +- goto error_attach; ++ if (ath_init_sw_rfkill(sc)) ++ goto detach; + #endif + + error = ieee80211_register_hw(hw); +@@ -1614,16 +1611,8 @@ + ath_init_leds(sc); + + return 0; +- +-error_attach: +- /* cleanup tx queues */ +- for (i = 0; i < ATH9K_NUM_TX_QUEUES; i++) +- if (ATH_TXQ_SETUP(sc, i)) +- ath_tx_cleanupq(sc, &sc->tx.txq[i]); +- +- ath9k_hw_detach(sc->sc_ah); +- ath9k_exit_debug(sc); +- ++detach: ++ ath_detach(sc); + return error; + } + +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/drivers/net/wireless/iwlwifi/iwl3945-base.c linux-2.6.29-rc3.owrt/drivers/net/wireless/iwlwifi/iwl3945-base.c +--- linux-2.6.29.owrt/drivers/net/wireless/iwlwifi/iwl3945-base.c 2009-05-10 22:04:38.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/drivers/net/wireless/iwlwifi/iwl3945-base.c 2009-05-10 23:48:29.000000000 +0200 +@@ -7911,7 +7911,7 @@ + CSR_GP_CNTRL_REG_FLAG_MAC_CLOCK_READY, 25000); + if (err < 0) { + IWL_DEBUG_INFO("Failed to init the card\n"); +- goto out_iounmap; ++ goto out_remove_sysfs; + } + + /*********************** +@@ -7921,7 +7921,7 @@ + err = iwl3945_eeprom_init(priv); + if (err) { + IWL_ERROR("Unable to init EEPROM\n"); +- goto out_iounmap; ++ goto out_remove_sysfs; + } + /* MAC Address location in EEPROM same for 3945/4965 */ + get_eeprom_mac(priv, priv->mac_addr); +@@ -7975,7 +7975,7 @@ + err = iwl3945_init_channel_map(priv); + if (err) { + IWL_ERROR("initializing regulatory failed: %d\n", err); +- goto out_unset_hw_setting; ++ goto out_release_irq; + } + + err = iwl3945_init_geos(priv); +@@ -8045,22 +8045,25 @@ + return 0; + + out_remove_sysfs: +- destroy_workqueue(priv->workqueue); +- priv->workqueue = NULL; + sysfs_remove_group(&pdev->dev.kobj, &iwl3945_attribute_group); + out_free_geos: + iwl3945_free_geos(priv); + out_free_channel_map: + iwl3945_free_channel_map(priv); +- out_unset_hw_setting: ++ ++ ++ out_release_irq: ++ destroy_workqueue(priv->workqueue); ++ priv->workqueue = NULL; + iwl3945_unset_hw_setting(priv); ++ + out_iounmap: + pci_iounmap(pdev, priv->hw_base); + out_pci_release_regions: + pci_release_regions(pdev); + out_pci_disable_device: +- pci_set_drvdata(pdev, NULL); + pci_disable_device(pdev); ++ pci_set_drvdata(pdev, NULL); + out_ieee80211_free_hw: + ieee80211_free_hw(priv->hw); + out: +@@ -8140,19 +8143,6 @@ + priv->is_open = 1; + } + +- /* pci driver assumes state will be saved in this function. +- * pci state is saved and device disabled when interface is +- * stopped, so at this time pci device will always be disabled - +- * whether interface was started or not. saving pci state now will +- * cause saved state be that of a disabled device, which will cause +- * problems during resume in that we will end up with a disabled device. +- * +- * indicate that the current saved state (from when interface was +- * stopped) is valid. if interface was never up at time of suspend +- * then the saved state will still be valid as it was saved during +- * .probe. */ +- pdev->state_saved = true; +- + pci_set_power_state(pdev, PCI_D3hot); + + return 0; +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/drivers/net/wireless/iwlwifi/iwl-agn.c linux-2.6.29-rc3.owrt/drivers/net/wireless/iwlwifi/iwl-agn.c +--- linux-2.6.29.owrt/drivers/net/wireless/iwlwifi/iwl-agn.c 2009-05-10 22:04:38.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/drivers/net/wireless/iwlwifi/iwl-agn.c 2009-05-10 23:48:29.000000000 +0200 +@@ -1719,10 +1719,6 @@ + priv->ucode_data_backup.len = data_size; + iwl_alloc_fw_desc(priv->pci_dev, &priv->ucode_data_backup); + +- if (!priv->ucode_code.v_addr || !priv->ucode_data.v_addr || +- !priv->ucode_data_backup.v_addr) +- goto err_pci_alloc; +- + /* Initialization instructions and data */ + if (init_size && init_data_size) { + priv->ucode_init.len = init_size; +@@ -3868,7 +3864,7 @@ + } + err = iwl_eeprom_check_version(priv); + if (err) +- goto out_free_eeprom; ++ goto out_iounmap; + + /* extract MAC Address */ + iwl_eeprom_get_mac(priv, priv->mac_addr); +@@ -3945,8 +3941,6 @@ + return 0; + + out_remove_sysfs: +- destroy_workqueue(priv->workqueue); +- priv->workqueue = NULL; + sysfs_remove_group(&pdev->dev.kobj, &iwl_attribute_group); + out_uninit_drv: + iwl_uninit_drv(priv); +@@ -3955,8 +3949,8 @@ + out_iounmap: + pci_iounmap(pdev, priv->hw_base); + out_pci_release_regions: +- pci_set_drvdata(pdev, NULL); + pci_release_regions(pdev); ++ pci_set_drvdata(pdev, NULL); + out_pci_disable_device: + pci_disable_device(pdev); + out_ieee80211_free_hw: +@@ -4044,19 +4038,6 @@ + priv->is_open = 1; + } + +- /* pci driver assumes state will be saved in this function. +- * pci state is saved and device disabled when interface is +- * stopped, so at this time pci device will always be disabled - +- * whether interface was started or not. saving pci state now will +- * cause saved state be that of a disabled device, which will cause +- * problems during resume in that we will end up with a disabled device. +- * +- * indicate that the current saved state (from when interface was +- * stopped) is valid. if interface was never up at time of suspend +- * then the saved state will still be valid as it was saved during +- * .probe. */ +- pdev->state_saved = true; +- + pci_set_power_state(pdev, PCI_D3hot); + + return 0; +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/drivers/net/wireless/iwlwifi/iwl-sta.c linux-2.6.29-rc3.owrt/drivers/net/wireless/iwlwifi/iwl-sta.c +--- linux-2.6.29.owrt/drivers/net/wireless/iwlwifi/iwl-sta.c 2009-05-10 22:04:38.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/drivers/net/wireless/iwlwifi/iwl-sta.c 2009-05-10 23:48:29.000000000 +0200 +@@ -480,9 +480,6 @@ + priv->num_stations = 0; + memset(priv->stations, 0, sizeof(priv->stations)); + +- /* clean ucode key table bit map */ +- priv->ucode_key_table = 0; +- + spin_unlock_irqrestore(&priv->sta_lock, flags); + } + EXPORT_SYMBOL(iwl_clear_stations_table); +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/drivers/net/wireless/iwlwifi/iwl-tx.c linux-2.6.29-rc3.owrt/drivers/net/wireless/iwlwifi/iwl-tx.c +--- linux-2.6.29.owrt/drivers/net/wireless/iwlwifi/iwl-tx.c 2009-05-10 22:04:38.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/drivers/net/wireless/iwlwifi/iwl-tx.c 2009-05-10 23:48:29.000000000 +0200 +@@ -148,7 +148,7 @@ + pci_unmap_single(dev, + pci_unmap_addr(&txq->cmd[index]->meta, mapping), + pci_unmap_len(&txq->cmd[index]->meta, len), +- PCI_DMA_BIDIRECTIONAL); ++ PCI_DMA_TODEVICE); + + /* Unmap chunks, if any. */ + for (i = 1; i < num_tbs; i++) { +@@ -964,7 +964,7 @@ + * within command buffer array. */ + txcmd_phys = pci_map_single(priv->pci_dev, + out_cmd, sizeof(struct iwl_cmd), +- PCI_DMA_BIDIRECTIONAL); ++ PCI_DMA_TODEVICE); + pci_unmap_addr_set(&out_cmd->meta, mapping, txcmd_phys); + pci_unmap_len_set(&out_cmd->meta, len, sizeof(struct iwl_cmd)); + /* Add buffer containing Tx command and MAC(!) header to TFD's +@@ -1115,7 +1115,7 @@ + IWL_MAX_SCAN_SIZE : sizeof(struct iwl_cmd); + + phys_addr = pci_map_single(priv->pci_dev, out_cmd, +- len, PCI_DMA_BIDIRECTIONAL); ++ len, PCI_DMA_TODEVICE); + pci_unmap_addr_set(&out_cmd->meta, mapping, phys_addr); + pci_unmap_len_set(&out_cmd->meta, len, len); + phys_addr += offsetof(struct iwl_cmd, hdr); +@@ -1212,7 +1212,7 @@ + pci_unmap_single(priv->pci_dev, + pci_unmap_addr(&txq->cmd[cmd_idx]->meta, mapping), + pci_unmap_len(&txq->cmd[cmd_idx]->meta, len), +- PCI_DMA_BIDIRECTIONAL); ++ PCI_DMA_TODEVICE); + + for (idx = iwl_queue_inc_wrap(idx, q->n_bd); q->read_ptr != idx; + q->read_ptr = iwl_queue_inc_wrap(q->read_ptr, q->n_bd)) { +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/drivers/net/wireless/libertas/ethtool.c linux-2.6.29-rc3.owrt/drivers/net/wireless/libertas/ethtool.c +--- linux-2.6.29.owrt/drivers/net/wireless/libertas/ethtool.c 2009-05-10 22:04:38.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/drivers/net/wireless/libertas/ethtool.c 2009-05-10 23:48:29.000000000 +0200 +@@ -23,7 +23,7 @@ + static void lbs_ethtool_get_drvinfo(struct net_device *dev, + struct ethtool_drvinfo *info) + { +- struct lbs_private *priv = dev->ml_priv; ++ struct lbs_private *priv = netdev_priv(dev); + + snprintf(info->fw_version, 32, "%u.%u.%u.p%u", + priv->fwrelease >> 24 & 0xff, +@@ -47,7 +47,7 @@ + static int lbs_ethtool_get_eeprom(struct net_device *dev, + struct ethtool_eeprom *eeprom, u8 * bytes) + { +- struct lbs_private *priv = dev->ml_priv; ++ struct lbs_private *priv = netdev_priv(dev); + struct cmd_ds_802_11_eeprom_access cmd; + int ret; + +@@ -76,7 +76,7 @@ + static void lbs_ethtool_get_stats(struct net_device *dev, + struct ethtool_stats *stats, uint64_t *data) + { +- struct lbs_private *priv = dev->ml_priv; ++ struct lbs_private *priv = netdev_priv(dev); + struct cmd_ds_mesh_access mesh_access; + int ret; + +@@ -113,7 +113,7 @@ + + static int lbs_ethtool_get_sset_count(struct net_device *dev, int sset) + { +- struct lbs_private *priv = dev->ml_priv; ++ struct lbs_private *priv = netdev_priv(dev); + + if (sset == ETH_SS_STATS && dev == priv->mesh_dev) + return MESH_STATS_NUM; +@@ -143,7 +143,7 @@ + static void lbs_ethtool_get_wol(struct net_device *dev, + struct ethtool_wolinfo *wol) + { +- struct lbs_private *priv = dev->ml_priv; ++ struct lbs_private *priv = netdev_priv(dev); + + if (priv->wol_criteria == 0xffffffff) { + /* Interface driver didn't configure wake */ +@@ -166,7 +166,7 @@ + static int lbs_ethtool_set_wol(struct net_device *dev, + struct ethtool_wolinfo *wol) + { +- struct lbs_private *priv = dev->ml_priv; ++ struct lbs_private *priv = netdev_priv(dev); + uint32_t criteria = 0; + + if (priv->wol_criteria == 0xffffffff && wol->wolopts) +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/drivers/net/wireless/libertas/if_usb.c linux-2.6.29-rc3.owrt/drivers/net/wireless/libertas/if_usb.c +--- linux-2.6.29.owrt/drivers/net/wireless/libertas/if_usb.c 2009-05-10 22:04:38.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/drivers/net/wireless/libertas/if_usb.c 2009-05-10 23:48:29.000000000 +0200 +@@ -59,7 +59,7 @@ + static ssize_t if_usb_firmware_set(struct device *dev, + struct device_attribute *attr, const char *buf, size_t count) + { +- struct lbs_private *priv = to_net_dev(dev)->ml_priv; ++ struct lbs_private *priv = netdev_priv(to_net_dev(dev)); + struct if_usb_card *cardp = priv->card; + char fwname[FIRMWARE_NAME_MAX]; + int ret; +@@ -86,7 +86,7 @@ + static ssize_t if_usb_boot2_set(struct device *dev, + struct device_attribute *attr, const char *buf, size_t count) + { +- struct lbs_private *priv = to_net_dev(dev)->ml_priv; ++ struct lbs_private *priv = netdev_priv(to_net_dev(dev)); + struct if_usb_card *cardp = priv->card; + char fwname[FIRMWARE_NAME_MAX]; + int ret; +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/drivers/net/wireless/libertas/main.c linux-2.6.29-rc3.owrt/drivers/net/wireless/libertas/main.c +--- linux-2.6.29.owrt/drivers/net/wireless/libertas/main.c 2009-05-10 22:04:38.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/drivers/net/wireless/libertas/main.c 2009-05-10 23:48:29.000000000 +0200 +@@ -222,7 +222,7 @@ + static ssize_t lbs_anycast_get(struct device *dev, + struct device_attribute *attr, char * buf) + { +- struct lbs_private *priv = to_net_dev(dev)->ml_priv; ++ struct lbs_private *priv = netdev_priv(to_net_dev(dev)); + struct cmd_ds_mesh_access mesh_access; + int ret; + +@@ -241,7 +241,7 @@ + static ssize_t lbs_anycast_set(struct device *dev, + struct device_attribute *attr, const char * buf, size_t count) + { +- struct lbs_private *priv = to_net_dev(dev)->ml_priv; ++ struct lbs_private *priv = netdev_priv(to_net_dev(dev)); + struct cmd_ds_mesh_access mesh_access; + uint32_t datum; + int ret; +@@ -263,7 +263,7 @@ + static ssize_t lbs_prb_rsp_limit_get(struct device *dev, + struct device_attribute *attr, char *buf) + { +- struct lbs_private *priv = to_net_dev(dev)->ml_priv; ++ struct lbs_private *priv = netdev_priv(to_net_dev(dev)); + struct cmd_ds_mesh_access mesh_access; + int ret; + u32 retry_limit; +@@ -286,7 +286,7 @@ + static ssize_t lbs_prb_rsp_limit_set(struct device *dev, + struct device_attribute *attr, const char *buf, size_t count) + { +- struct lbs_private *priv = to_net_dev(dev)->ml_priv; ++ struct lbs_private *priv = netdev_priv(to_net_dev(dev)); + struct cmd_ds_mesh_access mesh_access; + int ret; + unsigned long retry_limit; +@@ -321,7 +321,7 @@ + static ssize_t lbs_rtap_get(struct device *dev, + struct device_attribute *attr, char * buf) + { +- struct lbs_private *priv = to_net_dev(dev)->ml_priv; ++ struct lbs_private *priv = netdev_priv(to_net_dev(dev)); + return snprintf(buf, 5, "0x%X\n", priv->monitormode); + } + +@@ -332,7 +332,7 @@ + struct device_attribute *attr, const char * buf, size_t count) + { + int monitor_mode; +- struct lbs_private *priv = to_net_dev(dev)->ml_priv; ++ struct lbs_private *priv = netdev_priv(to_net_dev(dev)); + + sscanf(buf, "%x", &monitor_mode); + if (monitor_mode) { +@@ -383,7 +383,7 @@ + static ssize_t lbs_mesh_get(struct device *dev, + struct device_attribute *attr, char * buf) + { +- struct lbs_private *priv = to_net_dev(dev)->ml_priv; ++ struct lbs_private *priv = netdev_priv(to_net_dev(dev)); + return snprintf(buf, 5, "0x%X\n", !!priv->mesh_dev); + } + +@@ -393,7 +393,7 @@ + static ssize_t lbs_mesh_set(struct device *dev, + struct device_attribute *attr, const char * buf, size_t count) + { +- struct lbs_private *priv = to_net_dev(dev)->ml_priv; ++ struct lbs_private *priv = netdev_priv(to_net_dev(dev)); + int enable; + int ret, action = CMD_ACT_MESH_CONFIG_STOP; + +@@ -452,7 +452,7 @@ + */ + static int lbs_dev_open(struct net_device *dev) + { +- struct lbs_private *priv = dev->ml_priv; ++ struct lbs_private *priv = netdev_priv(dev) ; + int ret = 0; + + lbs_deb_enter(LBS_DEB_NET); +@@ -521,7 +521,7 @@ + */ + static int lbs_eth_stop(struct net_device *dev) + { +- struct lbs_private *priv = dev->ml_priv; ++ struct lbs_private *priv = netdev_priv(dev); + + lbs_deb_enter(LBS_DEB_NET); + +@@ -538,7 +538,7 @@ + + static void lbs_tx_timeout(struct net_device *dev) + { +- struct lbs_private *priv = dev->ml_priv; ++ struct lbs_private *priv = netdev_priv(dev); + + lbs_deb_enter(LBS_DEB_TX); + +@@ -590,7 +590,7 @@ + */ + static struct net_device_stats *lbs_get_stats(struct net_device *dev) + { +- struct lbs_private *priv = dev->ml_priv; ++ struct lbs_private *priv = netdev_priv(dev); + + lbs_deb_enter(LBS_DEB_NET); + return &priv->stats; +@@ -599,7 +599,7 @@ + static int lbs_set_mac_address(struct net_device *dev, void *addr) + { + int ret = 0; +- struct lbs_private *priv = dev->ml_priv; ++ struct lbs_private *priv = netdev_priv(dev); + struct sockaddr *phwaddr = addr; + struct cmd_ds_802_11_mac_address cmd; + +@@ -732,7 +732,7 @@ + + static void lbs_set_multicast_list(struct net_device *dev) + { +- struct lbs_private *priv = dev->ml_priv; ++ struct lbs_private *priv = netdev_priv(dev); + + schedule_work(&priv->mcast_work); + } +@@ -748,7 +748,7 @@ + static int lbs_thread(void *data) + { + struct net_device *dev = data; +- struct lbs_private *priv = dev->ml_priv; ++ struct lbs_private *priv = netdev_priv(dev); + wait_queue_t wait; + + lbs_deb_enter(LBS_DEB_THREAD); +@@ -1184,7 +1184,6 @@ + goto done; + } + priv = netdev_priv(dev); +- dev->ml_priv = priv; + + if (lbs_init_adapter(priv)) { + lbs_pr_err("failed to initialize adapter structure.\n"); +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/drivers/net/wireless/libertas/persistcfg.c linux-2.6.29-rc3.owrt/drivers/net/wireless/libertas/persistcfg.c +--- linux-2.6.29.owrt/drivers/net/wireless/libertas/persistcfg.c 2009-05-10 22:04:38.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/drivers/net/wireless/libertas/persistcfg.c 2009-05-10 23:48:29.000000000 +0200 +@@ -18,7 +18,7 @@ + static int mesh_get_default_parameters(struct device *dev, + struct mrvl_mesh_defaults *defs) + { +- struct lbs_private *priv = to_net_dev(dev)->ml_priv; ++ struct lbs_private *priv = netdev_priv(to_net_dev(dev)); + struct cmd_ds_mesh_config cmd; + int ret; + +@@ -57,7 +57,7 @@ + static ssize_t bootflag_set(struct device *dev, struct device_attribute *attr, + const char *buf, size_t count) + { +- struct lbs_private *priv = to_net_dev(dev)->ml_priv; ++ struct lbs_private *priv = netdev_priv(to_net_dev(dev)); + struct cmd_ds_mesh_config cmd; + uint32_t datum; + int ret; +@@ -100,7 +100,7 @@ + static ssize_t boottime_set(struct device *dev, + struct device_attribute *attr, const char *buf, size_t count) + { +- struct lbs_private *priv = to_net_dev(dev)->ml_priv; ++ struct lbs_private *priv = netdev_priv(to_net_dev(dev)); + struct cmd_ds_mesh_config cmd; + uint32_t datum; + int ret; +@@ -152,7 +152,7 @@ + static ssize_t channel_set(struct device *dev, struct device_attribute *attr, + const char *buf, size_t count) + { +- struct lbs_private *priv = to_net_dev(dev)->ml_priv; ++ struct lbs_private *priv = netdev_priv(to_net_dev(dev)); + struct cmd_ds_mesh_config cmd; + uint32_t datum; + int ret; +@@ -210,7 +210,7 @@ + struct cmd_ds_mesh_config cmd; + struct mrvl_mesh_defaults defs; + struct mrvl_meshie *ie; +- struct lbs_private *priv = to_net_dev(dev)->ml_priv; ++ struct lbs_private *priv = netdev_priv(to_net_dev(dev)); + int len; + int ret; + +@@ -269,7 +269,7 @@ + struct cmd_ds_mesh_config cmd; + struct mrvl_mesh_defaults defs; + struct mrvl_meshie *ie; +- struct lbs_private *priv = to_net_dev(dev)->ml_priv; ++ struct lbs_private *priv = netdev_priv(to_net_dev(dev)); + uint32_t datum; + int ret; + +@@ -323,7 +323,7 @@ + struct cmd_ds_mesh_config cmd; + struct mrvl_mesh_defaults defs; + struct mrvl_meshie *ie; +- struct lbs_private *priv = to_net_dev(dev)->ml_priv; ++ struct lbs_private *priv = netdev_priv(to_net_dev(dev)); + uint32_t datum; + int ret; + +@@ -377,7 +377,7 @@ + struct cmd_ds_mesh_config cmd; + struct mrvl_mesh_defaults defs; + struct mrvl_meshie *ie; +- struct lbs_private *priv = to_net_dev(dev)->ml_priv; ++ struct lbs_private *priv = netdev_priv(to_net_dev(dev)); + uint32_t datum; + int ret; + +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/drivers/net/wireless/libertas/scan.c linux-2.6.29-rc3.owrt/drivers/net/wireless/libertas/scan.c +--- linux-2.6.29.owrt/drivers/net/wireless/libertas/scan.c 2009-05-10 22:04:38.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/drivers/net/wireless/libertas/scan.c 2009-05-10 23:48:29.000000000 +0200 +@@ -945,7 +945,7 @@ + union iwreq_data *wrqu, char *extra) + { + DECLARE_SSID_BUF(ssid); +- struct lbs_private *priv = dev->ml_priv; ++ struct lbs_private *priv = netdev_priv(dev); + int ret = 0; + + lbs_deb_enter(LBS_DEB_WEXT); +@@ -1008,7 +1008,7 @@ + struct iw_point *dwrq, char *extra) + { + #define SCAN_ITEM_SIZE 128 +- struct lbs_private *priv = dev->ml_priv; ++ struct lbs_private *priv = netdev_priv(dev); + int err = 0; + char *ev = extra; + char *stop = ev + dwrq->length; +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/drivers/net/wireless/libertas/tx.c linux-2.6.29-rc3.owrt/drivers/net/wireless/libertas/tx.c +--- linux-2.6.29.owrt/drivers/net/wireless/libertas/tx.c 2009-05-10 22:04:38.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/drivers/net/wireless/libertas/tx.c 2009-05-10 23:48:29.000000000 +0200 +@@ -60,7 +60,7 @@ + int lbs_hard_start_xmit(struct sk_buff *skb, struct net_device *dev) + { + unsigned long flags; +- struct lbs_private *priv = dev->ml_priv; ++ struct lbs_private *priv = netdev_priv(dev); + struct txpd *txpd; + char *p802x_hdr; + uint16_t pkt_len; +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/drivers/net/wireless/libertas/wext.c linux-2.6.29-rc3.owrt/drivers/net/wireless/libertas/wext.c +--- linux-2.6.29.owrt/drivers/net/wireless/libertas/wext.c 2009-05-10 22:04:38.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/drivers/net/wireless/libertas/wext.c 2009-05-10 23:48:29.000000000 +0200 +@@ -163,7 +163,7 @@ + static int lbs_get_freq(struct net_device *dev, struct iw_request_info *info, + struct iw_freq *fwrq, char *extra) + { +- struct lbs_private *priv = dev->ml_priv; ++ struct lbs_private *priv = netdev_priv(dev); + struct chan_freq_power *cfp; + + lbs_deb_enter(LBS_DEB_WEXT); +@@ -189,7 +189,7 @@ + static int lbs_get_wap(struct net_device *dev, struct iw_request_info *info, + struct sockaddr *awrq, char *extra) + { +- struct lbs_private *priv = dev->ml_priv; ++ struct lbs_private *priv = netdev_priv(dev); + + lbs_deb_enter(LBS_DEB_WEXT); + +@@ -207,7 +207,7 @@ + static int lbs_set_nick(struct net_device *dev, struct iw_request_info *info, + struct iw_point *dwrq, char *extra) + { +- struct lbs_private *priv = dev->ml_priv; ++ struct lbs_private *priv = netdev_priv(dev); + + lbs_deb_enter(LBS_DEB_WEXT); + +@@ -231,7 +231,7 @@ + static int lbs_get_nick(struct net_device *dev, struct iw_request_info *info, + struct iw_point *dwrq, char *extra) + { +- struct lbs_private *priv = dev->ml_priv; ++ struct lbs_private *priv = netdev_priv(dev); + + lbs_deb_enter(LBS_DEB_WEXT); + +@@ -248,7 +248,7 @@ + static int mesh_get_nick(struct net_device *dev, struct iw_request_info *info, + struct iw_point *dwrq, char *extra) + { +- struct lbs_private *priv = dev->ml_priv; ++ struct lbs_private *priv = netdev_priv(dev); + + lbs_deb_enter(LBS_DEB_WEXT); + +@@ -273,7 +273,7 @@ + struct iw_param *vwrq, char *extra) + { + int ret = 0; +- struct lbs_private *priv = dev->ml_priv; ++ struct lbs_private *priv = netdev_priv(dev); + u32 val = vwrq->value; + + lbs_deb_enter(LBS_DEB_WEXT); +@@ -293,7 +293,7 @@ + static int lbs_get_rts(struct net_device *dev, struct iw_request_info *info, + struct iw_param *vwrq, char *extra) + { +- struct lbs_private *priv = dev->ml_priv; ++ struct lbs_private *priv = netdev_priv(dev); + int ret = 0; + u16 val = 0; + +@@ -315,7 +315,7 @@ + static int lbs_set_frag(struct net_device *dev, struct iw_request_info *info, + struct iw_param *vwrq, char *extra) + { +- struct lbs_private *priv = dev->ml_priv; ++ struct lbs_private *priv = netdev_priv(dev); + int ret = 0; + u32 val = vwrq->value; + +@@ -336,7 +336,7 @@ + static int lbs_get_frag(struct net_device *dev, struct iw_request_info *info, + struct iw_param *vwrq, char *extra) + { +- struct lbs_private *priv = dev->ml_priv; ++ struct lbs_private *priv = netdev_priv(dev); + int ret = 0; + u16 val = 0; + +@@ -359,7 +359,7 @@ + static int lbs_get_mode(struct net_device *dev, + struct iw_request_info *info, u32 * uwrq, char *extra) + { +- struct lbs_private *priv = dev->ml_priv; ++ struct lbs_private *priv = netdev_priv(dev); + + lbs_deb_enter(LBS_DEB_WEXT); + +@@ -385,7 +385,7 @@ + struct iw_request_info *info, + struct iw_param *vwrq, char *extra) + { +- struct lbs_private *priv = dev->ml_priv; ++ struct lbs_private *priv = netdev_priv(dev); + s16 curlevel = 0; + int ret = 0; + +@@ -418,7 +418,7 @@ + static int lbs_set_retry(struct net_device *dev, struct iw_request_info *info, + struct iw_param *vwrq, char *extra) + { +- struct lbs_private *priv = dev->ml_priv; ++ struct lbs_private *priv = netdev_priv(dev); + int ret = 0; + u16 slimit = 0, llimit = 0; + +@@ -466,7 +466,7 @@ + static int lbs_get_retry(struct net_device *dev, struct iw_request_info *info, + struct iw_param *vwrq, char *extra) + { +- struct lbs_private *priv = dev->ml_priv; ++ struct lbs_private *priv = netdev_priv(dev); + int ret = 0; + u16 val = 0; + +@@ -542,7 +542,7 @@ + struct iw_point *dwrq, char *extra) + { + int i, j; +- struct lbs_private *priv = dev->ml_priv; ++ struct lbs_private *priv = netdev_priv(dev); + struct iw_range *range = (struct iw_range *)extra; + struct chan_freq_power *cfp; + u8 rates[MAX_RATES + 1]; +@@ -708,7 +708,7 @@ + static int lbs_set_power(struct net_device *dev, struct iw_request_info *info, + struct iw_param *vwrq, char *extra) + { +- struct lbs_private *priv = dev->ml_priv; ++ struct lbs_private *priv = netdev_priv(dev); + + lbs_deb_enter(LBS_DEB_WEXT); + +@@ -758,7 +758,7 @@ + static int lbs_get_power(struct net_device *dev, struct iw_request_info *info, + struct iw_param *vwrq, char *extra) + { +- struct lbs_private *priv = dev->ml_priv; ++ struct lbs_private *priv = netdev_priv(dev); + + lbs_deb_enter(LBS_DEB_WEXT); + +@@ -781,7 +781,7 @@ + EXCELLENT = 95, + PERFECT = 100 + }; +- struct lbs_private *priv = dev->ml_priv; ++ struct lbs_private *priv = netdev_priv(dev); + u32 rssi_qual; + u32 tx_qual; + u32 quality = 0; +@@ -886,7 +886,7 @@ + struct iw_freq *fwrq, char *extra) + { + int ret = -EINVAL; +- struct lbs_private *priv = dev->ml_priv; ++ struct lbs_private *priv = netdev_priv(dev); + struct chan_freq_power *cfp; + struct assoc_request * assoc_req; + +@@ -943,7 +943,7 @@ + struct iw_request_info *info, + struct iw_freq *fwrq, char *extra) + { +- struct lbs_private *priv = dev->ml_priv; ++ struct lbs_private *priv = netdev_priv(dev); + struct chan_freq_power *cfp; + int ret = -EINVAL; + +@@ -994,7 +994,7 @@ + static int lbs_set_rate(struct net_device *dev, struct iw_request_info *info, + struct iw_param *vwrq, char *extra) + { +- struct lbs_private *priv = dev->ml_priv; ++ struct lbs_private *priv = netdev_priv(dev); + u8 new_rate = 0; + int ret = -EINVAL; + u8 rates[MAX_RATES + 1]; +@@ -1054,7 +1054,7 @@ + static int lbs_get_rate(struct net_device *dev, struct iw_request_info *info, + struct iw_param *vwrq, char *extra) + { +- struct lbs_private *priv = dev->ml_priv; ++ struct lbs_private *priv = netdev_priv(dev); + + lbs_deb_enter(LBS_DEB_WEXT); + +@@ -1079,7 +1079,7 @@ + struct iw_request_info *info, u32 * uwrq, char *extra) + { + int ret = 0; +- struct lbs_private *priv = dev->ml_priv; ++ struct lbs_private *priv = netdev_priv(dev); + struct assoc_request * assoc_req; + + lbs_deb_enter(LBS_DEB_WEXT); +@@ -1124,7 +1124,7 @@ + struct iw_request_info *info, + struct iw_point *dwrq, u8 * extra) + { +- struct lbs_private *priv = dev->ml_priv; ++ struct lbs_private *priv = netdev_priv(dev); + int index = (dwrq->flags & IW_ENCODE_INDEX) - 1; + + lbs_deb_enter(LBS_DEB_WEXT); +@@ -1319,7 +1319,7 @@ + struct iw_point *dwrq, char *extra) + { + int ret = 0; +- struct lbs_private *priv = dev->ml_priv; ++ struct lbs_private *priv = netdev_priv(dev); + struct assoc_request * assoc_req; + u16 is_default = 0, index = 0, set_tx_key = 0; + +@@ -1395,7 +1395,7 @@ + char *extra) + { + int ret = -EINVAL; +- struct lbs_private *priv = dev->ml_priv; ++ struct lbs_private *priv = netdev_priv(dev); + struct iw_encode_ext *ext = (struct iw_encode_ext *)extra; + int index, max_key_len; + +@@ -1501,7 +1501,7 @@ + char *extra) + { + int ret = 0; +- struct lbs_private *priv = dev->ml_priv; ++ struct lbs_private *priv = netdev_priv(dev); + struct iw_encode_ext *ext = (struct iw_encode_ext *)extra; + int alg = ext->alg; + struct assoc_request * assoc_req; +@@ -1639,7 +1639,7 @@ + struct iw_point *dwrq, + char *extra) + { +- struct lbs_private *priv = dev->ml_priv; ++ struct lbs_private *priv = netdev_priv(dev); + int ret = 0; + struct assoc_request * assoc_req; + +@@ -1685,7 +1685,7 @@ + char *extra) + { + int ret = 0; +- struct lbs_private *priv = dev->ml_priv; ++ struct lbs_private *priv = netdev_priv(dev); + + lbs_deb_enter(LBS_DEB_WEXT); + +@@ -1713,7 +1713,7 @@ + struct iw_param *dwrq, + char *extra) + { +- struct lbs_private *priv = dev->ml_priv; ++ struct lbs_private *priv = netdev_priv(dev); + struct assoc_request * assoc_req; + int ret = 0; + int updated = 0; +@@ -1816,7 +1816,7 @@ + char *extra) + { + int ret = 0; +- struct lbs_private *priv = dev->ml_priv; ++ struct lbs_private *priv = netdev_priv(dev); + + lbs_deb_enter(LBS_DEB_WEXT); + +@@ -1857,7 +1857,7 @@ + struct iw_param *vwrq, char *extra) + { + int ret = 0; +- struct lbs_private *priv = dev->ml_priv; ++ struct lbs_private *priv = netdev_priv(dev); + s16 dbm = (s16) vwrq->value; + + lbs_deb_enter(LBS_DEB_WEXT); +@@ -1936,7 +1936,7 @@ + static int lbs_get_essid(struct net_device *dev, struct iw_request_info *info, + struct iw_point *dwrq, char *extra) + { +- struct lbs_private *priv = dev->ml_priv; ++ struct lbs_private *priv = netdev_priv(dev); + + lbs_deb_enter(LBS_DEB_WEXT); + +@@ -1971,7 +1971,7 @@ + static int lbs_set_essid(struct net_device *dev, struct iw_request_info *info, + struct iw_point *dwrq, char *extra) + { +- struct lbs_private *priv = dev->ml_priv; ++ struct lbs_private *priv = netdev_priv(dev); + int ret = 0; + u8 ssid[IW_ESSID_MAX_SIZE]; + u8 ssid_len = 0; +@@ -2040,7 +2040,7 @@ + struct iw_request_info *info, + struct iw_point *dwrq, char *extra) + { +- struct lbs_private *priv = dev->ml_priv; ++ struct lbs_private *priv = netdev_priv(dev); + + lbs_deb_enter(LBS_DEB_WEXT); + +@@ -2058,7 +2058,7 @@ + struct iw_request_info *info, + struct iw_point *dwrq, char *extra) + { +- struct lbs_private *priv = dev->ml_priv; ++ struct lbs_private *priv = netdev_priv(dev); + int ret = 0; + + lbs_deb_enter(LBS_DEB_WEXT); +@@ -2102,7 +2102,7 @@ + static int lbs_set_wap(struct net_device *dev, struct iw_request_info *info, + struct sockaddr *awrq, char *extra) + { +- struct lbs_private *priv = dev->ml_priv; ++ struct lbs_private *priv = netdev_priv(dev); + struct assoc_request * assoc_req; + int ret = 0; + +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/drivers/net/wireless/orinoco/orinoco.c linux-2.6.29-rc3.owrt/drivers/net/wireless/orinoco/orinoco.c +--- linux-2.6.29.owrt/drivers/net/wireless/orinoco/orinoco.c 2009-05-10 22:04:38.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/drivers/net/wireless/orinoco/orinoco.c 2009-05-10 23:48:29.000000000 +0200 +@@ -3157,20 +3157,8 @@ + + return NOTIFY_DONE; + } +- +-static void orinoco_register_pm_notifier(struct orinoco_private *priv) +-{ +- priv->pm_notifier.notifier_call = orinoco_pm_notifier; +- register_pm_notifier(&priv->pm_notifier); +-} +- +-static void orinoco_unregister_pm_notifier(struct orinoco_private *priv) +-{ +- unregister_pm_notifier(&priv->pm_notifier); +-} + #else /* !PM_SLEEP || HERMES_CACHE_FW_ON_INIT */ +-#define orinoco_register_pm_notifier(priv) do { } while(0) +-#define orinoco_unregister_pm_notifier(priv) do { } while(0) ++#define orinoco_pm_notifier NULL + #endif + + /********************************************************************/ +@@ -3660,7 +3648,8 @@ + priv->cached_fw = NULL; + + /* Register PM notifiers */ +- orinoco_register_pm_notifier(priv); ++ priv->pm_notifier.notifier_call = orinoco_pm_notifier; ++ register_pm_notifier(&priv->pm_notifier); + + return dev; + } +@@ -3684,7 +3673,7 @@ + kfree(rx_data); + } + +- orinoco_unregister_pm_notifier(priv); ++ unregister_pm_notifier(&priv->pm_notifier); + orinoco_uncache_fw(priv); + + priv->wpa_ie_len = 0; +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/drivers/net/wireless/p54/p54common.c linux-2.6.29-rc3.owrt/drivers/net/wireless/p54/p54common.c +--- linux-2.6.29.owrt/drivers/net/wireless/p54/p54common.c 2009-05-10 22:04:38.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/drivers/net/wireless/p54/p54common.c 2009-05-10 23:48:29.000000000 +0200 +@@ -710,11 +710,10 @@ + __le32 req_id) + { + struct p54_common *priv = dev->priv; +- struct sk_buff *entry; ++ struct sk_buff *entry = priv->tx_queue.next; + unsigned long flags; + + spin_lock_irqsave(&priv->tx_queue.lock, flags); +- entry = priv->tx_queue.next; + while (entry != (struct sk_buff *)&priv->tx_queue) { + struct p54_hdr *hdr = (struct p54_hdr *) entry->data; + +@@ -733,7 +732,7 @@ + struct p54_common *priv = dev->priv; + struct p54_hdr *hdr = (struct p54_hdr *) skb->data; + struct p54_frame_sent *payload = (struct p54_frame_sent *) hdr->data; +- struct sk_buff *entry; ++ struct sk_buff *entry = (struct sk_buff *) priv->tx_queue.next; + u32 addr = le32_to_cpu(hdr->req_id) - priv->headroom; + struct memrecord *range = NULL; + u32 freed = 0; +@@ -742,7 +741,6 @@ + int count, idx; + + spin_lock_irqsave(&priv->tx_queue.lock, flags); +- entry = (struct sk_buff *) priv->tx_queue.next; + while (entry != (struct sk_buff *)&priv->tx_queue) { + struct ieee80211_tx_info *info = IEEE80211_SKB_CB(entry); + struct p54_hdr *entry_hdr; +@@ -978,7 +976,7 @@ + struct p54_hdr *data, u32 len) + { + struct p54_common *priv = dev->priv; +- struct sk_buff *entry; ++ struct sk_buff *entry = priv->tx_queue.next; + struct sk_buff *target_skb = NULL; + struct ieee80211_tx_info *info; + struct memrecord *range; +@@ -1016,7 +1014,6 @@ + } + } + +- entry = priv->tx_queue.next; + while (left--) { + u32 hole_size; + info = IEEE80211_SKB_CB(entry); +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/drivers/net/wireless/rt2x00/rt2500usb.c linux-2.6.29-rc3.owrt/drivers/net/wireless/rt2x00/rt2500usb.c +--- linux-2.6.29.owrt/drivers/net/wireless/rt2x00/rt2500usb.c 2009-05-10 22:04:38.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/drivers/net/wireless/rt2x00/rt2500usb.c 2009-05-10 23:48:29.000000000 +0200 +@@ -1952,8 +1952,6 @@ + { USB_DEVICE(0x13b1, 0x000d), USB_DEVICE_DATA(&rt2500usb_ops) }, + { USB_DEVICE(0x13b1, 0x0011), USB_DEVICE_DATA(&rt2500usb_ops) }, + { USB_DEVICE(0x13b1, 0x001a), USB_DEVICE_DATA(&rt2500usb_ops) }, +- /* CNet */ +- { USB_DEVICE(0x1371, 0x9022), USB_DEVICE_DATA(&rt2500usb_ops) }, + /* Conceptronic */ + { USB_DEVICE(0x14b2, 0x3c02), USB_DEVICE_DATA(&rt2500usb_ops) }, + /* D-LINK */ +@@ -1978,20 +1976,14 @@ + { USB_DEVICE(0x148f, 0x2570), USB_DEVICE_DATA(&rt2500usb_ops) }, + { USB_DEVICE(0x148f, 0x2573), USB_DEVICE_DATA(&rt2500usb_ops) }, + { USB_DEVICE(0x148f, 0x9020), USB_DEVICE_DATA(&rt2500usb_ops) }, +- /* Sagem */ +- { USB_DEVICE(0x079b, 0x004b), USB_DEVICE_DATA(&rt2500usb_ops) }, + /* Siemens */ + { USB_DEVICE(0x0681, 0x3c06), USB_DEVICE_DATA(&rt2500usb_ops) }, + /* SMC */ + { USB_DEVICE(0x0707, 0xee13), USB_DEVICE_DATA(&rt2500usb_ops) }, + /* Spairon */ + { USB_DEVICE(0x114b, 0x0110), USB_DEVICE_DATA(&rt2500usb_ops) }, +- /* SURECOM */ +- { USB_DEVICE(0x0769, 0x11f3), USB_DEVICE_DATA(&rt2500usb_ops) }, + /* Trust */ + { USB_DEVICE(0x0eb0, 0x9020), USB_DEVICE_DATA(&rt2500usb_ops) }, +- /* VTech */ +- { USB_DEVICE(0x0f88, 0x3012), USB_DEVICE_DATA(&rt2500usb_ops) }, + /* Zinwell */ + { USB_DEVICE(0x5a57, 0x0260), USB_DEVICE_DATA(&rt2500usb_ops) }, + { 0, } +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/drivers/net/wireless/rt2x00/rt73usb.c linux-2.6.29-rc3.owrt/drivers/net/wireless/rt2x00/rt73usb.c +--- linux-2.6.29.owrt/drivers/net/wireless/rt2x00/rt73usb.c 2009-05-10 22:04:38.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/drivers/net/wireless/rt2x00/rt73usb.c 2009-05-10 23:48:29.000000000 +0200 +@@ -2281,18 +2281,7 @@ + */ + static struct usb_device_id rt73usb_device_table[] = { + /* AboCom */ +- { USB_DEVICE(0x07b8, 0xb21b), USB_DEVICE_DATA(&rt73usb_ops) }, +- { USB_DEVICE(0x07b8, 0xb21c), USB_DEVICE_DATA(&rt73usb_ops) }, + { USB_DEVICE(0x07b8, 0xb21d), USB_DEVICE_DATA(&rt73usb_ops) }, +- { USB_DEVICE(0x07b8, 0xb21e), USB_DEVICE_DATA(&rt73usb_ops) }, +- { USB_DEVICE(0x07b8, 0xb21f), USB_DEVICE_DATA(&rt73usb_ops) }, +- /* AL */ +- { USB_DEVICE(0x14b2, 0x3c10), USB_DEVICE_DATA(&rt73usb_ops) }, +- /* Amigo */ +- { USB_DEVICE(0x148f, 0x9021), USB_DEVICE_DATA(&rt73usb_ops) }, +- { USB_DEVICE(0x0eb0, 0x9021), USB_DEVICE_DATA(&rt73usb_ops) }, +- /* AMIT */ +- { USB_DEVICE(0x18c5, 0x0002), USB_DEVICE_DATA(&rt73usb_ops) }, + /* Askey */ + { USB_DEVICE(0x1690, 0x0722), USB_DEVICE_DATA(&rt73usb_ops) }, + /* ASUS */ +@@ -2305,9 +2294,7 @@ + { USB_DEVICE(0x050d, 0x905c), USB_DEVICE_DATA(&rt73usb_ops) }, + /* Billionton */ + { USB_DEVICE(0x1631, 0xc019), USB_DEVICE_DATA(&rt73usb_ops) }, +- { USB_DEVICE(0x08dd, 0x0120), USB_DEVICE_DATA(&rt73usb_ops) }, + /* Buffalo */ +- { USB_DEVICE(0x0411, 0x00d8), USB_DEVICE_DATA(&rt73usb_ops) }, + { USB_DEVICE(0x0411, 0x00f4), USB_DEVICE_DATA(&rt73usb_ops) }, + /* CNet */ + { USB_DEVICE(0x1371, 0x9022), USB_DEVICE_DATA(&rt73usb_ops) }, +@@ -2321,11 +2308,6 @@ + { USB_DEVICE(0x07d1, 0x3c04), USB_DEVICE_DATA(&rt73usb_ops) }, + { USB_DEVICE(0x07d1, 0x3c06), USB_DEVICE_DATA(&rt73usb_ops) }, + { USB_DEVICE(0x07d1, 0x3c07), USB_DEVICE_DATA(&rt73usb_ops) }, +- /* Edimax */ +- { USB_DEVICE(0x7392, 0x7318), USB_DEVICE_DATA(&rt73usb_ops) }, +- { USB_DEVICE(0x7392, 0x7618), USB_DEVICE_DATA(&rt73usb_ops) }, +- /* EnGenius */ +- { USB_DEVICE(0x1740, 0x3701), USB_DEVICE_DATA(&rt73usb_ops) }, + /* Gemtek */ + { USB_DEVICE(0x15a9, 0x0004), USB_DEVICE_DATA(&rt73usb_ops) }, + /* Gigabyte */ +@@ -2346,34 +2328,22 @@ + { USB_DEVICE(0x0db0, 0xa861), USB_DEVICE_DATA(&rt73usb_ops) }, + { USB_DEVICE(0x0db0, 0xa874), USB_DEVICE_DATA(&rt73usb_ops) }, + /* Ralink */ +- { USB_DEVICE(0x04bb, 0x093d), USB_DEVICE_DATA(&rt73usb_ops) }, + { USB_DEVICE(0x148f, 0x2573), USB_DEVICE_DATA(&rt73usb_ops) }, + { USB_DEVICE(0x148f, 0x2671), USB_DEVICE_DATA(&rt73usb_ops) }, + /* Qcom */ + { USB_DEVICE(0x18e8, 0x6196), USB_DEVICE_DATA(&rt73usb_ops) }, + { USB_DEVICE(0x18e8, 0x6229), USB_DEVICE_DATA(&rt73usb_ops) }, + { USB_DEVICE(0x18e8, 0x6238), USB_DEVICE_DATA(&rt73usb_ops) }, +- /* Samsung */ +- { USB_DEVICE(0x04e8, 0x4471), USB_DEVICE_DATA(&rt73usb_ops) }, + /* Senao */ + { USB_DEVICE(0x1740, 0x7100), USB_DEVICE_DATA(&rt73usb_ops) }, + /* Sitecom */ +- { USB_DEVICE(0x0df6, 0x0024), USB_DEVICE_DATA(&rt73usb_ops) }, +- { USB_DEVICE(0x0df6, 0x0027), USB_DEVICE_DATA(&rt73usb_ops) }, +- { USB_DEVICE(0x0df6, 0x002f), USB_DEVICE_DATA(&rt73usb_ops) }, +- { USB_DEVICE(0x0df6, 0x90ac), USB_DEVICE_DATA(&rt73usb_ops) }, + { USB_DEVICE(0x0df6, 0x9712), USB_DEVICE_DATA(&rt73usb_ops) }, ++ { USB_DEVICE(0x0df6, 0x90ac), USB_DEVICE_DATA(&rt73usb_ops) }, + /* Surecom */ + { USB_DEVICE(0x0769, 0x31f3), USB_DEVICE_DATA(&rt73usb_ops) }, +- /* Philips */ +- { USB_DEVICE(0x0471, 0x200a), USB_DEVICE_DATA(&rt73usb_ops) }, + /* Planex */ + { USB_DEVICE(0x2019, 0xab01), USB_DEVICE_DATA(&rt73usb_ops) }, + { USB_DEVICE(0x2019, 0xab50), USB_DEVICE_DATA(&rt73usb_ops) }, +- /* Zcom */ +- { USB_DEVICE(0x0cde, 0x001c), USB_DEVICE_DATA(&rt73usb_ops) }, +- /* ZyXEL */ +- { USB_DEVICE(0x0586, 0x3415), USB_DEVICE_DATA(&rt73usb_ops) }, + { 0, } + }; + +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/drivers/net/wireless/rtl818x/rtl8187_dev.c linux-2.6.29-rc3.owrt/drivers/net/wireless/rtl818x/rtl8187_dev.c +--- linux-2.6.29.owrt/drivers/net/wireless/rtl818x/rtl8187_dev.c 2009-05-10 22:04:38.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/drivers/net/wireless/rtl818x/rtl8187_dev.c 2009-05-10 23:48:29.000000000 +0200 +@@ -48,10 +48,6 @@ + {USB_DEVICE(0x0bda, 0x8189), .driver_info = DEVICE_RTL8187B}, + {USB_DEVICE(0x0bda, 0x8197), .driver_info = DEVICE_RTL8187B}, + {USB_DEVICE(0x0bda, 0x8198), .driver_info = DEVICE_RTL8187B}, +- /* Surecom */ +- {USB_DEVICE(0x0769, 0x11F2), .driver_info = DEVICE_RTL8187}, +- /* Logitech */ +- {USB_DEVICE(0x0789, 0x010C), .driver_info = DEVICE_RTL8187}, + /* Netgear */ + {USB_DEVICE(0x0846, 0x6100), .driver_info = DEVICE_RTL8187}, + {USB_DEVICE(0x0846, 0x6a00), .driver_info = DEVICE_RTL8187}, +@@ -61,16 +57,8 @@ + /* Sitecom */ + {USB_DEVICE(0x0df6, 0x000d), .driver_info = DEVICE_RTL8187}, + {USB_DEVICE(0x0df6, 0x0028), .driver_info = DEVICE_RTL8187B}, +- /* Sphairon Access Systems GmbH */ +- {USB_DEVICE(0x114B, 0x0150), .driver_info = DEVICE_RTL8187}, +- /* Dick Smith Electronics */ +- {USB_DEVICE(0x1371, 0x9401), .driver_info = DEVICE_RTL8187}, + /* Abocom */ + {USB_DEVICE(0x13d1, 0xabe6), .driver_info = DEVICE_RTL8187}, +- /* Qcom */ +- {USB_DEVICE(0x18E8, 0x6232), .driver_info = DEVICE_RTL8187}, +- /* AirLive */ +- {USB_DEVICE(0x1b75, 0x8187), .driver_info = DEVICE_RTL8187}, + {} + }; + +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/drivers/net/wireless/rtl818x/rtl8187_rtl8225.c linux-2.6.29-rc3.owrt/drivers/net/wireless/rtl818x/rtl8187_rtl8225.c +--- linux-2.6.29.owrt/drivers/net/wireless/rtl818x/rtl8187_rtl8225.c 2009-05-10 22:04:38.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/drivers/net/wireless/rtl818x/rtl8187_rtl8225.c 2009-05-10 23:48:29.000000000 +0200 +@@ -285,10 +285,7 @@ + ofdm_power = priv->channels[channel - 1].hw_value >> 4; + + cck_power = min(cck_power, (u8)11); +- if (ofdm_power > (u8)15) +- ofdm_power = 25; +- else +- ofdm_power += 10; ++ ofdm_power = min(ofdm_power, (u8)35); + + rtl818x_iowrite8(priv, &priv->map->TX_GAIN_CCK, + rtl8225_tx_gain_cck_ofdm[cck_power / 6] >> 1); +@@ -539,10 +536,7 @@ + cck_power += priv->txpwr_base & 0xF; + cck_power = min(cck_power, (u8)35); + +- if (ofdm_power > (u8)15) +- ofdm_power = 25; +- else +- ofdm_power += 10; ++ ofdm_power = min(ofdm_power, (u8)15); + ofdm_power += priv->txpwr_base >> 4; + ofdm_power = min(ofdm_power, (u8)35); + +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/drivers/net/wireless/zd1211rw/zd_mac.c linux-2.6.29-rc3.owrt/drivers/net/wireless/zd1211rw/zd_mac.c +--- linux-2.6.29.owrt/drivers/net/wireless/zd1211rw/zd_mac.c 2009-05-10 22:04:38.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/drivers/net/wireless/zd1211rw/zd_mac.c 2009-05-10 23:48:29.000000000 +0200 +@@ -575,17 +575,13 @@ + + r = fill_ctrlset(mac, skb); + if (r) +- goto fail; ++ return r; + + info->rate_driver_data[0] = hw; + + r = zd_usb_tx(&mac->chip.usb, skb); + if (r) +- goto fail; +- return 0; +- +-fail: +- dev_kfree_skb(skb); ++ return r; + return 0; + } + +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/drivers/net/wireless/zd1211rw/zd_rf.c linux-2.6.29-rc3.owrt/drivers/net/wireless/zd1211rw/zd_rf.c +--- linux-2.6.29.owrt/drivers/net/wireless/zd1211rw/zd_rf.c 2009-05-10 22:04:38.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/drivers/net/wireless/zd1211rw/zd_rf.c 2009-05-10 23:48:29.000000000 +0200 +@@ -86,7 +86,6 @@ + case AL7230B_RF: + r = zd_rf_init_al7230b(rf); + break; +- case MAXIM_NEW_RF: + case UW2453_RF: + r = zd_rf_init_uw2453(rf); + break; +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/drivers/net/wireless/zd1211rw/zd_usb.c linux-2.6.29-rc3.owrt/drivers/net/wireless/zd1211rw/zd_usb.c +--- linux-2.6.29.owrt/drivers/net/wireless/zd1211rw/zd_usb.c 2009-05-10 22:04:38.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/drivers/net/wireless/zd1211rw/zd_usb.c 2009-05-10 23:48:29.000000000 +0200 +@@ -37,7 +37,6 @@ + static struct usb_device_id usb_ids[] = { + /* ZD1211 */ + { USB_DEVICE(0x0ace, 0x1211), .driver_info = DEVICE_ZD1211 }, +- { USB_DEVICE(0x0ace, 0xa211), .driver_info = DEVICE_ZD1211 }, + { USB_DEVICE(0x07b8, 0x6001), .driver_info = DEVICE_ZD1211 }, + { USB_DEVICE(0x126f, 0xa006), .driver_info = DEVICE_ZD1211 }, + { USB_DEVICE(0x6891, 0xa727), .driver_info = DEVICE_ZD1211 }, +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/drivers/parisc/dino.c linux-2.6.29-rc3.owrt/drivers/parisc/dino.c +--- linux-2.6.29.owrt/drivers/parisc/dino.c 2009-05-10 22:04:38.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/drivers/parisc/dino.c 2009-05-10 23:48:29.000000000 +0200 +@@ -479,7 +479,7 @@ + res = &dino_dev->hba.lmmio_space; + res->flags = IORESOURCE_MEM; + size = scnprintf(name, sizeof(name), "Dino LMMIO (%s)", +- dev_name(bus->bridge)); ++ bus->bridge->bus_id); + res->name = kmalloc(size+1, GFP_KERNEL); + if(res->name) + strcpy((char *)res->name, name); +@@ -493,7 +493,7 @@ + struct list_head *ln, *tmp_ln; + + printk(KERN_ERR "Dino: cannot attach bus %s\n", +- dev_name(bus->bridge)); ++ bus->bridge->bus_id); + /* kill the bus, we can't do anything with it */ + list_for_each_safe(ln, tmp_ln, &bus->devices) { + struct pci_dev *dev = pci_dev_b(ln); +@@ -587,7 +587,7 @@ + bus->resource[i+1] = &res[i]; + } + +- } else if (bus->parent) { ++ } else if(bus->self) { + int i; + + pci_read_bridge_bases(bus); +@@ -611,12 +611,12 @@ + } + + DBG("DEBUG %s assigning %d [0x%lx,0x%lx]\n", +- dev_name(&bus->self->dev), i, ++ bus->self->dev.bus_id, i, + bus->self->resource[i].start, + bus->self->resource[i].end); + pci_assign_resource(bus->self, i); + DBG("DEBUG %s after assign %d [0x%lx,0x%lx]\n", +- dev_name(&bus->self->dev), i, ++ bus->self->dev.bus_id, i, + bus->self->resource[i].start, + bus->self->resource[i].end); + } +@@ -1026,8 +1026,7 @@ + dino_current_bus = bus->subordinate + 1; + pci_bus_assign_resources(bus); + } else { +- printk(KERN_ERR "ERROR: failed to scan PCI bus on %s (probably duplicate bus number %d)\n", +- dev_name(&dev->dev), dino_current_bus); ++ printk(KERN_ERR "ERROR: failed to scan PCI bus on %s (probably duplicate bus number %d)\n", dev->dev.bus_id, dino_current_bus); + /* increment the bus number in case of duplicates */ + dino_current_bus++; + } +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/drivers/parisc/gsc.c linux-2.6.29-rc3.owrt/drivers/parisc/gsc.c +--- linux-2.6.29.owrt/drivers/parisc/gsc.c 2009-05-10 22:04:38.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/drivers/parisc/gsc.c 2009-05-10 23:48:29.000000000 +0200 +@@ -186,34 +186,29 @@ + *irqp = irq; + } + +-struct gsc_fixup_struct { +- void (*choose_irq)(struct parisc_device *, void *); +- void *ctrl; +-}; +- +-static int gsc_fixup_irqs_callback(struct device *dev, void *data) ++static struct device *next_device(struct klist_iter *i) + { +- struct parisc_device *padev = to_parisc_device(dev); +- struct gsc_fixup_struct *gf = data; +- +- /* work-around for 715/64 and others which have parent +- at path [5] and children at path [5/0/x] */ +- if (padev->id.hw_type == HPHW_FAULTY) +- gsc_fixup_irqs(padev, gf->ctrl, gf->choose_irq); +- gf->choose_irq(padev, gf->ctrl); +- +- return 0; ++ struct klist_node * n = klist_next(i); ++ return n ? container_of(n, struct device, knode_parent) : NULL; + } + + void gsc_fixup_irqs(struct parisc_device *parent, void *ctrl, + void (*choose_irq)(struct parisc_device *, void *)) + { +- struct gsc_fixup_struct data = { +- .choose_irq = choose_irq, +- .ctrl = ctrl, +- }; ++ struct device *dev; ++ struct klist_iter i; + +- device_for_each_child(&parent->dev, &data, gsc_fixup_irqs_callback); ++ klist_iter_init(&parent->dev.klist_children, &i); ++ while ((dev = next_device(&i))) { ++ struct parisc_device *padev = to_parisc_device(dev); ++ ++ /* work-around for 715/64 and others which have parent ++ at path [5] and children at path [5/0/x] */ ++ if (padev->id.hw_type == HPHW_FAULTY) ++ return gsc_fixup_irqs(padev, ctrl, choose_irq); ++ choose_irq(padev, ctrl); ++ } ++ klist_iter_exit(&i); + } + + int gsc_common_setup(struct parisc_device *parent, struct gsc_asic *gsc_asic) +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/drivers/parisc/iosapic.c linux-2.6.29-rc3.owrt/drivers/parisc/iosapic.c +--- linux-2.6.29.owrt/drivers/parisc/iosapic.c 2009-05-10 22:04:38.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/drivers/parisc/iosapic.c 2009-05-10 23:48:29.000000000 +0200 +@@ -487,7 +487,7 @@ + } + + /* Check if pcidev behind a PPB */ +- if (pcidev->bus->parent) { ++ if (NULL != pcidev->bus->self) { + /* Convert pcidev INTR_PIN into something we + ** can lookup in the IRT. + */ +@@ -523,9 +523,10 @@ + #endif /* PCI_BRIDGE_FUNCS */ + + /* +- * Locate the host slot of the PPB. +- */ +- while (p->parent->parent) ++ ** Locate the host slot the PPB nearest the Host bus ++ ** adapter. ++ */ ++ while (NULL != p->parent->self) + p = p->parent; + + intr_slot = PCI_SLOT(p->self->devfn); +@@ -708,14 +709,11 @@ + struct vector_info *vi = iosapic_get_vector(irq); + u32 d0, d1, dummy_d0; + unsigned long flags; +- int dest_cpu; + +- dest_cpu = cpu_check_affinity(irq, dest); +- if (dest_cpu < 0) ++ if (cpu_check_affinity(irq, dest)) + return; + +- irq_desc[irq].affinity = cpumask_of_cpu(dest_cpu); +- vi->txn_addr = txn_affinity_addr(irq, dest_cpu); ++ vi->txn_addr = txn_affinity_addr(irq, cpumask_first(dest)); + + spin_lock_irqsave(&iosapic_lock, flags); + /* d1 contains the destination CPU, so only want to set that +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/drivers/parisc/lba_pci.c linux-2.6.29-rc3.owrt/drivers/parisc/lba_pci.c +--- linux-2.6.29.owrt/drivers/parisc/lba_pci.c 2009-05-10 22:04:38.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/drivers/parisc/lba_pci.c 2009-05-10 23:48:29.000000000 +0200 +@@ -644,7 +644,7 @@ + ** Properly Setup MMIO resources for this bus. + ** pci_alloc_primary_bus() mangles this. + */ +- if (bus->parent) { ++ if (bus->self) { + int i; + /* PCI-PCI Bridge */ + pci_read_bridge_bases(bus); +@@ -802,7 +802,7 @@ + ** Can't fixup here anyway....garr... + */ + if (fbb_enable) { +- if (bus->parent) { ++ if (bus->self) { + u8 control; + /* enable on PPB */ + (void) pci_read_config_byte(bus->self, PCI_BRIDGE_CONTROL, &control); +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/drivers/parisc/sba_iommu.c linux-2.6.29-rc3.owrt/drivers/parisc/sba_iommu.c +--- linux-2.6.29.owrt/drivers/parisc/sba_iommu.c 2009-05-10 22:04:38.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/drivers/parisc/sba_iommu.c 2009-05-10 23:48:29.000000000 +0200 +@@ -668,7 +668,7 @@ + * @dev: instance of PCI owned by the driver that's asking + * @mask: number of address bits this PCI device can handle + * +- * See Documentation/PCI/PCI-DMA-mapping.txt ++ * See Documentation/DMA-mapping.txt + */ + static int sba_dma_supported( struct device *dev, u64 mask) + { +@@ -680,8 +680,8 @@ + return(0); + } + +- /* Documentation/PCI/PCI-DMA-mapping.txt tells drivers to try 64-bit +- * first, then fall back to 32-bit if that fails. ++ /* Documentation/DMA-mapping.txt tells drivers to try 64-bit first, ++ * then fall back to 32-bit if that fails. + * We are just "encouraging" 32-bit DMA masks here since we can + * never allow IOMMU bypass unless we add special support for ZX1. + */ +@@ -706,7 +706,7 @@ + * @size: number of bytes to map in driver buffer. + * @direction: R/W or both. + * +- * See Documentation/PCI/PCI-DMA-mapping.txt ++ * See Documentation/DMA-mapping.txt + */ + static dma_addr_t + sba_map_single(struct device *dev, void *addr, size_t size, +@@ -785,7 +785,7 @@ + * @size: number of bytes mapped in driver buffer. + * @direction: R/W or both. + * +- * See Documentation/PCI/PCI-DMA-mapping.txt ++ * See Documentation/DMA-mapping.txt + */ + static void + sba_unmap_single(struct device *dev, dma_addr_t iova, size_t size, +@@ -861,7 +861,7 @@ + * @size: number of bytes mapped in driver buffer. + * @dma_handle: IOVA of new buffer. + * +- * See Documentation/PCI/PCI-DMA-mapping.txt ++ * See Documentation/DMA-mapping.txt + */ + static void *sba_alloc_consistent(struct device *hwdev, size_t size, + dma_addr_t *dma_handle, gfp_t gfp) +@@ -892,7 +892,7 @@ + * @vaddr: virtual address IOVA of "consistent" buffer. + * @dma_handler: IO virtual address of "consistent" buffer. + * +- * See Documentation/PCI/PCI-DMA-mapping.txt ++ * See Documentation/DMA-mapping.txt + */ + static void + sba_free_consistent(struct device *hwdev, size_t size, void *vaddr, +@@ -927,7 +927,7 @@ + * @nents: number of entries in list + * @direction: R/W or both. + * +- * See Documentation/PCI/PCI-DMA-mapping.txt ++ * See Documentation/DMA-mapping.txt + */ + static int + sba_map_sg(struct device *dev, struct scatterlist *sglist, int nents, +@@ -1011,7 +1011,7 @@ + * @nents: number of entries in list + * @direction: R/W or both. + * +- * See Documentation/PCI/PCI-DMA-mapping.txt ++ * See Documentation/DMA-mapping.txt + */ + static void + sba_unmap_sg(struct device *dev, struct scatterlist *sglist, int nents, +@@ -1206,48 +1206,30 @@ + return (void *) pdir_base; + } + +-struct ibase_data_struct { +- struct ioc *ioc; +- int ioc_num; +-}; +- +-static int setup_ibase_imask_callback(struct device *dev, void *data) ++static struct device *next_device(struct klist_iter *i) + { +- /* lba_set_iregs() is in drivers/parisc/lba_pci.c */ +- extern void lba_set_iregs(struct parisc_device *, u32, u32); +- struct parisc_device *lba = to_parisc_device(dev); +- struct ibase_data_struct *ibd = data; +- int rope_num = (lba->hpa.start >> 13) & 0xf; +- if (rope_num >> 3 == ibd->ioc_num) +- lba_set_iregs(lba, ibd->ioc->ibase, ibd->ioc->imask); +- return 0; ++ struct klist_node * n = klist_next(i); ++ return n ? container_of(n, struct device, knode_parent) : NULL; + } + + /* setup Mercury or Elroy IBASE/IMASK registers. */ + static void + setup_ibase_imask(struct parisc_device *sba, struct ioc *ioc, int ioc_num) + { +- struct ibase_data_struct ibase_data = { +- .ioc = ioc, +- .ioc_num = ioc_num, +- }; +- +- device_for_each_child(&sba->dev, &ibase_data, +- setup_ibase_imask_callback); +-} +- +-#ifdef SBA_AGP_SUPPORT +-static int +-sba_ioc_find_quicksilver(struct device *dev, void *data) +-{ +- int *agp_found = data; +- struct parisc_device *lba = to_parisc_device(dev); ++ /* lba_set_iregs() is in drivers/parisc/lba_pci.c */ ++ extern void lba_set_iregs(struct parisc_device *, u32, u32); ++ struct device *dev; ++ struct klist_iter i; + +- if (IS_QUICKSILVER(lba)) +- *agp_found = 1; +- return 0; ++ klist_iter_init(&sba->dev.klist_children, &i); ++ while ((dev = next_device(&i))) { ++ struct parisc_device *lba = to_parisc_device(dev); ++ int rope_num = (lba->hpa.start >> 13) & 0xf; ++ if (rope_num >> 3 == ioc_num) ++ lba_set_iregs(lba, ioc->ibase, ioc->imask); ++ } ++ klist_iter_exit(&i); + } +-#endif + + static void + sba_ioc_init_pluto(struct parisc_device *sba, struct ioc *ioc, int ioc_num) +@@ -1350,6 +1332,9 @@ + WRITE_REG(ioc->ibase | 31, ioc->ioc_hpa + IOC_PCOM); + + #ifdef SBA_AGP_SUPPORT ++{ ++ struct klist_iter i; ++ struct device *dev = NULL; + + /* + ** If an AGP device is present, only use half of the IOV space +@@ -1359,7 +1344,13 @@ + ** We program the next pdir index after we stop w/ a key for + ** the GART code to handshake on. + */ +- device_for_each_child(&sba->dev, &agp_found, sba_ioc_find_quicksilver); ++ klist_iter_init(&sba->dev.klist_children, &i); ++ while ((dev = next_device(&i))) { ++ struct parisc_device *lba = to_parisc_device(dev); ++ if (IS_QUICKSILVER(lba)) ++ agp_found = 1; ++ } ++ klist_iter_exit(&i); + + if (agp_found && sba_reserve_agpgart) { + printk(KERN_INFO "%s: reserving %dMb of IOVA space for agpgart\n", +@@ -1367,7 +1358,9 @@ + ioc->pdir_size /= 2; + ioc->pdir_base[PDIR_INDEX(iova_space_size/2)] = SBA_AGPGART_COOKIE; + } ++} + #endif /*SBA_AGP_SUPPORT*/ ++ + } + + static void +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/drivers/parport/parport_atari.c linux-2.6.29-rc3.owrt/drivers/parport/parport_atari.c +--- linux-2.6.29.owrt/drivers/parport/parport_atari.c 2009-05-10 22:04:39.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/drivers/parport/parport_atari.c 2009-05-10 23:48:29.000000000 +0200 +@@ -84,7 +84,7 @@ + static unsigned char + parport_atari_read_status(struct parport *p) + { +- return ((st_mfp.par_dt_reg & 1 ? 0 : PARPORT_STATUS_BUSY) | ++ return ((mfp.par_dt_reg & 1 ? 0 : PARPORT_STATUS_BUSY) | + PARPORT_STATUS_SELECT | PARPORT_STATUS_ERROR); + } + +@@ -193,9 +193,9 @@ + sound_ym.wd_data = sound_ym.rd_data_reg_sel | (1 << 5); + local_irq_restore(flags); + /* MFP port I0 as input. */ +- st_mfp.data_dir &= ~1; ++ mfp.data_dir &= ~1; + /* MFP port I0 interrupt on high->low edge. */ +- st_mfp.active_edge &= ~1; ++ mfp.active_edge &= ~1; + p = parport_register_port((unsigned long)&sound_ym.wd_data, + IRQ_MFP_BUSY, PARPORT_DMA_NONE, + &parport_atari_ops); +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/drivers/parport/parport_serial.c linux-2.6.29-rc3.owrt/drivers/parport/parport_serial.c +--- linux-2.6.29.owrt/drivers/parport/parport_serial.c 2009-05-10 22:04:39.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/drivers/parport/parport_serial.c 2009-05-10 23:48:29.000000000 +0200 +@@ -64,11 +64,6 @@ + + static int __devinit netmos_parallel_init(struct pci_dev *dev, struct parport_pc_pci *card, int autoirq, int autodma) + { +- /* the rule described below doesn't hold for this device */ +- if (dev->device == PCI_DEVICE_ID_NETMOS_9835 && +- dev->subsystem_vendor == PCI_VENDOR_ID_IBM && +- dev->subsystem_device == 0x0299) +- return -ENODEV; + /* + * Netmos uses the subdevice ID to indicate the number of parallel + * and serial ports. The form is 0x00PS, where <P> is the number of +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/drivers/pci/dmar.c linux-2.6.29-rc3.owrt/drivers/pci/dmar.c +--- linux-2.6.29.owrt/drivers/pci/dmar.c 2009-05-10 22:04:39.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/drivers/pci/dmar.c 2009-05-10 23:48:29.000000000 +0200 +@@ -330,14 +330,6 @@ + entry_header = (struct acpi_dmar_header *)(dmar + 1); + while (((unsigned long)entry_header) < + (((unsigned long)dmar) + dmar_tbl->length)) { +- /* Avoid looping forever on bad ACPI tables */ +- if (entry_header->length == 0) { +- printk(KERN_WARNING PREFIX +- "Invalid 0-length structure\n"); +- ret = -EINVAL; +- break; +- } +- + dmar_table_print_dmar_entry(entry_header); + + switch (entry_header->type) { +@@ -499,7 +491,7 @@ + int map_size; + u32 ver; + static int iommu_allocated = 0; +- int agaw = 0; ++ int agaw; + + iommu = kzalloc(sizeof(*iommu), GFP_KERNEL); + if (!iommu) +@@ -515,7 +507,6 @@ + iommu->cap = dmar_readq(iommu->reg + DMAR_CAP_REG); + iommu->ecap = dmar_readq(iommu->reg + DMAR_ECAP_REG); + +-#ifdef CONFIG_DMAR + agaw = iommu_calculate_agaw(iommu); + if (agaw < 0) { + printk(KERN_ERR +@@ -523,7 +514,6 @@ + iommu->seq_id); + goto error; + } +-#endif + iommu->agaw = agaw; + + /* the registers might be more than one page */ +@@ -581,49 +571,19 @@ + } + } + +-static int qi_check_fault(struct intel_iommu *iommu, int index) +-{ +- u32 fault; +- int head; +- struct q_inval *qi = iommu->qi; +- int wait_index = (index + 1) % QI_LENGTH; +- +- fault = readl(iommu->reg + DMAR_FSTS_REG); +- +- /* +- * If IQE happens, the head points to the descriptor associated +- * with the error. No new descriptors are fetched until the IQE +- * is cleared. +- */ +- if (fault & DMA_FSTS_IQE) { +- head = readl(iommu->reg + DMAR_IQH_REG); +- if ((head >> 4) == index) { +- memcpy(&qi->desc[index], &qi->desc[wait_index], +- sizeof(struct qi_desc)); +- __iommu_flush_cache(iommu, &qi->desc[index], +- sizeof(struct qi_desc)); +- writel(DMA_FSTS_IQE, iommu->reg + DMAR_FSTS_REG); +- return -EINVAL; +- } +- } +- +- return 0; +-} +- + /* + * Submit the queued invalidation descriptor to the remapping + * hardware unit and wait for its completion. + */ +-int qi_submit_sync(struct qi_desc *desc, struct intel_iommu *iommu) ++void qi_submit_sync(struct qi_desc *desc, struct intel_iommu *iommu) + { +- int rc = 0; + struct q_inval *qi = iommu->qi; + struct qi_desc *hw, wait_desc; + int wait_index, index; + unsigned long flags; + + if (!qi) +- return 0; ++ return; + + hw = qi->desc; + +@@ -641,8 +601,7 @@ + + hw[index] = *desc; + +- wait_desc.low = QI_IWD_STATUS_DATA(QI_DONE) | +- QI_IWD_STATUS_WRITE | QI_IWD_TYPE; ++ wait_desc.low = QI_IWD_STATUS_DATA(2) | QI_IWD_STATUS_WRITE | QI_IWD_TYPE; + wait_desc.high = virt_to_phys(&qi->desc_status[wait_index]); + + hw[wait_index] = wait_desc; +@@ -653,11 +612,13 @@ + qi->free_head = (qi->free_head + 2) % QI_LENGTH; + qi->free_cnt -= 2; + ++ spin_lock(&iommu->register_lock); + /* + * update the HW tail register indicating the presence of + * new descriptors. + */ + writel(qi->free_head << 4, iommu->reg + DMAR_IQT_REG); ++ spin_unlock(&iommu->register_lock); + + while (qi->desc_status[wait_index] != QI_DONE) { + /* +@@ -667,21 +628,15 @@ + * a deadlock where the interrupt context can wait indefinitely + * for free slots in the queue. + */ +- rc = qi_check_fault(iommu, index); +- if (rc) +- goto out; +- + spin_unlock(&qi->q_lock); + cpu_relax(); + spin_lock(&qi->q_lock); + } +-out: +- qi->desc_status[index] = qi->desc_status[wait_index] = QI_DONE; ++ ++ qi->desc_status[index] = QI_DONE; + + reclaim_free_desc(qi); + spin_unlock_irqrestore(&qi->q_lock, flags); +- +- return rc; + } + + /* +@@ -694,13 +649,13 @@ + desc.low = QI_IEC_TYPE; + desc.high = 0; + +- /* should never fail */ + qi_submit_sync(&desc, iommu); + } + + int qi_flush_context(struct intel_iommu *iommu, u16 did, u16 sid, u8 fm, + u64 type, int non_present_entry_flush) + { ++ + struct qi_desc desc; + + if (non_present_entry_flush) { +@@ -714,7 +669,10 @@ + | QI_CC_GRAN(type) | QI_CC_TYPE; + desc.high = 0; + +- return qi_submit_sync(&desc, iommu); ++ qi_submit_sync(&desc, iommu); ++ ++ return 0; ++ + } + + int qi_flush_iotlb(struct intel_iommu *iommu, u16 did, u64 addr, +@@ -744,7 +702,10 @@ + desc.high = QI_IOTLB_ADDR(addr) | QI_IOTLB_IH(ih) + | QI_IOTLB_AM(size_order); + +- return qi_submit_sync(&desc, iommu); ++ qi_submit_sync(&desc, iommu); ++ ++ return 0; ++ + } + + /* +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/drivers/pci/hotplug/fakephp.c linux-2.6.29-rc3.owrt/drivers/pci/hotplug/fakephp.c +--- linux-2.6.29.owrt/drivers/pci/hotplug/fakephp.c 2009-05-10 22:04:39.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/drivers/pci/hotplug/fakephp.c 2009-05-10 23:48:29.000000000 +0200 +@@ -195,13 +195,13 @@ + * Tries hard not to re-enable already existing devices; + * also handles scanning of subfunctions. + */ +-static int pci_rescan_slot(struct pci_dev *temp) ++static void pci_rescan_slot(struct pci_dev *temp) + { + struct pci_bus *bus = temp->bus; + struct pci_dev *dev; + int func; ++ int retval; + u8 hdr_type; +- int count = 0; + + if (!pci_read_config_byte(temp, PCI_HEADER_TYPE, &hdr_type)) { + temp->hdr_type = hdr_type & 0x7f; +@@ -213,12 +213,17 @@ + dbg("New device on %s function %x:%x\n", + bus->name, temp->devfn >> 3, + temp->devfn & 7); +- count++; ++ retval = pci_bus_add_device(dev); ++ if (retval) ++ dev_err(&dev->dev, "error adding " ++ "device, continuing.\n"); ++ else ++ add_slot(dev); + } + } + /* multifunction device? */ + if (!(hdr_type & 0x80)) +- return count; ++ return; + + /* continue scanning for other functions */ + for (func = 1, temp->devfn++; func < 8; func++, temp->devfn++) { +@@ -234,13 +239,16 @@ + dbg("New device on %s function %x:%x\n", + bus->name, temp->devfn >> 3, + temp->devfn & 7); +- count++; ++ retval = pci_bus_add_device(dev); ++ if (retval) ++ dev_err(&dev->dev, "error adding " ++ "device, continuing.\n"); ++ else ++ add_slot(dev); + } + } + } + } +- +- return count; + } + + +@@ -254,8 +262,6 @@ + { + unsigned int devfn; + struct pci_dev *dev; +- int retval; +- int found = 0; + dev = alloc_pci_dev(); + if (!dev) + return; +@@ -264,23 +270,7 @@ + dev->sysdata = bus->sysdata; + for (devfn = 0; devfn < 0x100; devfn += 8) { + dev->devfn = devfn; +- found += pci_rescan_slot(dev); +- } +- +- if (found) { +- pci_bus_assign_resources(bus); +- list_for_each_entry(dev, &bus->devices, bus_list) { +- /* Skip already-added devices */ +- if (dev->is_added) +- continue; +- retval = pci_bus_add_device(dev); +- if (retval) +- dev_err(&dev->dev, +- "Error adding device, continuing\n"); +- else +- add_slot(dev); +- } +- pci_bus_add_devices(bus); ++ pci_rescan_slot(dev); + } + kfree(dev); + } +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/drivers/pci/hotplug/Kconfig linux-2.6.29-rc3.owrt/drivers/pci/hotplug/Kconfig +--- linux-2.6.29.owrt/drivers/pci/hotplug/Kconfig 2009-05-10 22:04:39.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/drivers/pci/hotplug/Kconfig 2009-05-10 23:48:29.000000000 +0200 +@@ -143,7 +143,7 @@ + + config HOTPLUG_PCI_RPA + tristate "RPA PCI Hotplug driver" +- depends on PPC_PSERIES && EEH && !HOTPLUG_PCI_FAKE ++ depends on PPC_PSERIES && PPC64 && !HOTPLUG_PCI_FAKE + help + Say Y here if you have a RPA system that supports PCI Hotplug. + +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/drivers/pci/hotplug/Makefile linux-2.6.29-rc3.owrt/drivers/pci/hotplug/Makefile +--- linux-2.6.29.owrt/drivers/pci/hotplug/Makefile 2009-05-10 22:04:39.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/drivers/pci/hotplug/Makefile 2009-05-10 23:48:29.000000000 +0200 +@@ -5,15 +5,11 @@ + obj-$(CONFIG_HOTPLUG_PCI) += pci_hotplug.o + obj-$(CONFIG_HOTPLUG_PCI_COMPAQ) += cpqphp.o + obj-$(CONFIG_HOTPLUG_PCI_IBM) += ibmphp.o +- +-# pciehp should be linked before acpiphp in order to allow the native driver +-# to attempt to bind first. We can then fall back to generic support. +- +-obj-$(CONFIG_HOTPLUG_PCI_PCIE) += pciehp.o + obj-$(CONFIG_HOTPLUG_PCI_ACPI) += acpiphp.o + obj-$(CONFIG_HOTPLUG_PCI_ACPI_IBM) += acpiphp_ibm.o + obj-$(CONFIG_HOTPLUG_PCI_CPCI_ZT5550) += cpcihp_zt5550.o + obj-$(CONFIG_HOTPLUG_PCI_CPCI_GENERIC) += cpcihp_generic.o ++obj-$(CONFIG_HOTPLUG_PCI_PCIE) += pciehp.o + obj-$(CONFIG_HOTPLUG_PCI_SHPC) += shpchp.o + obj-$(CONFIG_HOTPLUG_PCI_RPA) += rpaphp.o + obj-$(CONFIG_HOTPLUG_PCI_RPA_DLPAR) += rpadlpar_io.o +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/drivers/pci/hotplug/pciehp_core.c linux-2.6.29-rc3.owrt/drivers/pci/hotplug/pciehp_core.c +--- linux-2.6.29.owrt/drivers/pci/hotplug/pciehp_core.c 2009-05-10 22:04:39.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/drivers/pci/hotplug/pciehp_core.c 2009-05-10 23:48:29.000000000 +0200 +@@ -434,13 +434,6 @@ + goto err_out_release_ctlr; + } + +- /* Enable events after we have setup the data structures */ +- rc = pcie_init_notification(ctrl); +- if (rc) { +- ctrl_err(ctrl, "Notification initialization failed\n"); +- goto err_out_release_ctlr; +- } +- + /* Check if slot is occupied */ + t_slot = pciehp_find_slot(ctrl, ctrl->slot_device_offset); + t_slot->hpc_ops->get_adapter_status(t_slot, &value); +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/drivers/pci/hotplug/pciehp.h linux-2.6.29-rc3.owrt/drivers/pci/hotplug/pciehp.h +--- linux-2.6.29.owrt/drivers/pci/hotplug/pciehp.h 2009-05-10 22:04:39.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/drivers/pci/hotplug/pciehp.h 2009-05-10 23:48:29.000000000 +0200 +@@ -111,7 +111,6 @@ + int cmd_busy; + unsigned int no_cmd_complete:1; + unsigned int link_active_reporting:1; +- unsigned int notification_enabled:1; + }; + + #define INT_BUTTON_IGNORE 0 +@@ -171,7 +170,6 @@ + extern int pciehp_unconfigure_device(struct slot *p_slot); + extern void pciehp_queue_pushbutton_work(struct work_struct *work); + struct controller *pcie_init(struct pcie_device *dev); +-int pcie_init_notification(struct controller *ctrl); + int pciehp_enable_slot(struct slot *p_slot); + int pciehp_disable_slot(struct slot *p_slot); + int pcie_enable_notification(struct controller *ctrl); +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/drivers/pci/hotplug/pciehp_hpc.c linux-2.6.29-rc3.owrt/drivers/pci/hotplug/pciehp_hpc.c +--- linux-2.6.29.owrt/drivers/pci/hotplug/pciehp_hpc.c 2009-05-10 22:04:39.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/drivers/pci/hotplug/pciehp_hpc.c 2009-05-10 23:48:29.000000000 +0200 +@@ -934,7 +934,7 @@ + ctrl_warn(ctrl, "Cannot disable software notification\n"); + } + +-int pcie_init_notification(struct controller *ctrl) ++static int pcie_init_notification(struct controller *ctrl) + { + if (pciehp_request_irq(ctrl)) + return -1; +@@ -942,17 +942,13 @@ + pciehp_free_irq(ctrl); + return -1; + } +- ctrl->notification_enabled = 1; + return 0; + } + + static void pcie_shutdown_notification(struct controller *ctrl) + { +- if (ctrl->notification_enabled) { +- pcie_disable_notification(ctrl); +- pciehp_free_irq(ctrl); +- ctrl->notification_enabled = 0; +- } ++ pcie_disable_notification(ctrl); ++ pciehp_free_irq(ctrl); + } + + static int pcie_init_slot(struct controller *ctrl) +@@ -1114,8 +1110,13 @@ + if (pcie_init_slot(ctrl)) + goto abort_ctrl; + ++ if (pcie_init_notification(ctrl)) ++ goto abort_slot; ++ + return ctrl; + ++abort_slot: ++ pcie_cleanup_slot(ctrl); + abort_ctrl: + kfree(ctrl); + abort: +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/drivers/pci/intel-iommu.c linux-2.6.29-rc3.owrt/drivers/pci/intel-iommu.c +--- linux-2.6.29.owrt/drivers/pci/intel-iommu.c 2009-05-10 22:04:39.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/drivers/pci/intel-iommu.c 2009-05-10 23:48:29.000000000 +0200 +@@ -61,8 +61,6 @@ + /* global iommu list, set NULL for ignored DMAR units */ + static struct intel_iommu **g_iommus; + +-static int rwbf_quirk; +- + /* + * 0: Present + * 1-11: Reserved +@@ -270,12 +268,7 @@ + + static void domain_remove_dev_info(struct dmar_domain *domain); + +-#ifdef CONFIG_DMAR_DEFAULT_ON +-int dmar_disabled = 0; +-#else +-int dmar_disabled = 1; +-#endif /*CONFIG_DMAR_DEFAULT_ON*/ +- ++int dmar_disabled; + static int __initdata dmar_map_gfx = 1; + static int dmar_forcedac; + static int intel_iommu_strict; +@@ -291,12 +284,9 @@ + if (!str) + return -EINVAL; + while (*str) { +- if (!strncmp(str, "on", 2)) { +- dmar_disabled = 0; +- printk(KERN_INFO "Intel-IOMMU: enabled\n"); +- } else if (!strncmp(str, "off", 3)) { ++ if (!strncmp(str, "off", 3)) { + dmar_disabled = 1; +- printk(KERN_INFO "Intel-IOMMU: disabled\n"); ++ printk(KERN_INFO"Intel-IOMMU: disabled\n"); + } else if (!strncmp(str, "igfx_off", 8)) { + dmar_map_gfx = 0; + printk(KERN_INFO +@@ -787,7 +777,7 @@ + u32 val; + unsigned long flag; + +- if (!rwbf_quirk && !cap_rwbf(iommu->cap)) ++ if (!cap_rwbf(iommu->cap)) + return; + val = iommu->gcmd | DMA_GCMD_WBF; + +@@ -3139,15 +3129,3 @@ + .unmap = intel_iommu_unmap_range, + .iova_to_phys = intel_iommu_iova_to_phys, + }; +- +-static void __devinit quirk_iommu_rwbf(struct pci_dev *dev) +-{ +- /* +- * Mobile 4 Series Chipset neglects to set RWBF capability, +- * but needs it: +- */ +- printk(KERN_INFO "DMAR: Forcing write-buffer flush capability\n"); +- rwbf_quirk = 1; +-} +- +-DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, 0x2a40, quirk_iommu_rwbf); +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/drivers/pci/intr_remapping.c linux-2.6.29-rc3.owrt/drivers/pci/intr_remapping.c +--- linux-2.6.29.owrt/drivers/pci/intr_remapping.c 2009-05-10 22:04:39.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/drivers/pci/intr_remapping.c 2009-05-10 23:48:29.000000000 +0200 +@@ -207,7 +207,7 @@ + return index; + } + +-static int qi_flush_iec(struct intel_iommu *iommu, int index, int mask) ++static void qi_flush_iec(struct intel_iommu *iommu, int index, int mask) + { + struct qi_desc desc; + +@@ -215,7 +215,7 @@ + | QI_IEC_SELECTIVE; + desc.high = 0; + +- return qi_submit_sync(&desc, iommu); ++ qi_submit_sync(&desc, iommu); + } + + int map_irq_to_irte_handle(int irq, u16 *sub_handle) +@@ -283,7 +283,6 @@ + + int modify_irte(int irq, struct irte *irte_modified) + { +- int rc; + int index; + struct irte *irte; + struct intel_iommu *iommu; +@@ -304,15 +303,14 @@ + set_64bit((unsigned long *)irte, irte_modified->low | (1 << 1)); + __iommu_flush_cache(iommu, irte, sizeof(*irte)); + +- rc = qi_flush_iec(iommu, index, 0); +- spin_unlock(&irq_2_ir_lock); ++ qi_flush_iec(iommu, index, 0); + +- return rc; ++ spin_unlock(&irq_2_ir_lock); ++ return 0; + } + + int flush_irte(int irq) + { +- int rc; + int index; + struct intel_iommu *iommu; + struct irq_2_iommu *irq_iommu; +@@ -328,10 +326,10 @@ + + index = irq_iommu->irte_index + irq_iommu->sub_handle; + +- rc = qi_flush_iec(iommu, index, irq_iommu->irte_mask); ++ qi_flush_iec(iommu, index, irq_iommu->irte_mask); + spin_unlock(&irq_2_ir_lock); + +- return rc; ++ return 0; + } + + struct intel_iommu *map_ioapic_to_ir(int apic) +@@ -357,7 +355,6 @@ + + int free_irte(int irq) + { +- int rc = 0; + int index, i; + struct irte *irte; + struct intel_iommu *iommu; +@@ -378,7 +375,7 @@ + if (!irq_iommu->sub_handle) { + for (i = 0; i < (1 << irq_iommu->irte_mask); i++) + set_64bit((unsigned long *)irte, 0); +- rc = qi_flush_iec(iommu, index, irq_iommu->irte_mask); ++ qi_flush_iec(iommu, index, irq_iommu->irte_mask); + } + + irq_iommu->iommu = NULL; +@@ -388,7 +385,7 @@ + + spin_unlock(&irq_2_ir_lock); + +- return rc; ++ return 0; + } + + static void iommu_set_intr_remapping(struct intel_iommu *iommu, int mode) +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/drivers/pci/msi.c linux-2.6.29-rc3.owrt/drivers/pci/msi.c +--- linux-2.6.29.owrt/drivers/pci/msi.c 2009-05-10 22:04:39.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/drivers/pci/msi.c 2009-05-10 23:48:29.000000000 +0200 +@@ -103,14 +103,6 @@ + } + } + +-static inline __attribute_const__ u32 msi_mask(unsigned x) +-{ +- /* Don't shift by >= width of type */ +- if (x >= 5) +- return 0xffffffff; +- return (1 << (1 << x)) - 1; +-} +- + static void msix_flush_writes(struct irq_desc *desc) + { + struct msi_desc *entry; +@@ -415,7 +407,8 @@ + + /* All MSIs are unmasked by default, Mask them all */ + pci_read_config_dword(dev, base, &maskbits); +- temp = msi_mask((control & PCI_MSI_FLAGS_QMASK) >> 1); ++ temp = (1 << multi_msi_capable(control)); ++ temp = ((temp - 1) & ~temp); + maskbits |= temp; + pci_write_config_dword(dev, base, maskbits); + entry->msi_attrib.maskbits_mask = temp; +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/drivers/pci/pci.c linux-2.6.29-rc3.owrt/drivers/pci/pci.c +--- linux-2.6.29.owrt/drivers/pci/pci.c 2009-05-10 22:04:39.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/drivers/pci/pci.c 2009-05-10 23:48:29.000000000 +0200 +@@ -1393,35 +1393,35 @@ + pci_power_t prev_state; + int error; + ++ pci_restore_state(dev); + pci_update_current_state(dev, PCI_D0); + + prev_state = dev->current_state; + if (prev_state == PCI_D0) +- goto Restore; ++ return 0; + + error = pci_raw_set_power_state(dev, PCI_D0, false); + if (error) + return error; + +- /* +- * This assumes that we won't get a bus in B2 or B3 from the BIOS, but +- * we've made this assumption forever and it appears to be universally +- * satisfied. +- */ +- switch(prev_state) { +- case PCI_D3cold: +- case PCI_D3hot: +- mdelay(pci_pm_d3_delay); +- break; +- case PCI_D2: +- udelay(PCI_PM_D2_DELAY); +- break; ++ if (pci_is_bridge(dev)) { ++ if (prev_state > PCI_D1) ++ mdelay(PCI_PM_BUS_WAIT); ++ } else { ++ switch(prev_state) { ++ case PCI_D3cold: ++ case PCI_D3hot: ++ mdelay(pci_pm_d3_delay); ++ break; ++ case PCI_D2: ++ udelay(PCI_PM_D2_DELAY); ++ break; ++ } + } + +- pci_update_current_state(dev, PCI_D0); ++ dev->current_state = PCI_D0; + +- Restore: +- return dev->state_saved ? pci_restore_state(dev) : 0; ++ return 0; + } + + /** +@@ -1540,21 +1540,16 @@ + } + + /** +- * __pci_request_region - Reserved PCI I/O and memory resource ++ * pci_request_region - Reserved PCI I/O and memory resource + * @pdev: PCI device whose resources are to be reserved + * @bar: BAR to be reserved + * @res_name: Name to be associated with resource. +- * @exclusive: whether the region access is exclusive or not + * + * Mark the PCI region associated with PCI device @pdev BR @bar as + * being reserved by owner @res_name. Do not access any + * address inside the PCI regions unless this call returns + * successfully. + * +- * If @exclusive is set, then the region is marked so that userspace +- * is explicitly not allowed to map the resource via /dev/mem or +- * sysfs MMIO access. +- * + * Returns 0 on success, or %EBUSY on error. A warning + * message is also printed on failure. + */ +@@ -1593,12 +1588,12 @@ + } + + /** +- * pci_request_region - Reserve PCI I/O and memory resource ++ * pci_request_region - Reserved PCI I/O and memory resource + * @pdev: PCI device whose resources are to be reserved + * @bar: BAR to be reserved +- * @res_name: Name to be associated with resource ++ * @res_name: Name to be associated with resource. + * +- * Mark the PCI region associated with PCI device @pdev BAR @bar as ++ * Mark the PCI region associated with PCI device @pdev BR @bar as + * being reserved by owner @res_name. Do not access any + * address inside the PCI regions unless this call returns + * successfully. +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/drivers/pci/pci-driver.c linux-2.6.29-rc3.owrt/drivers/pci/pci-driver.c +--- linux-2.6.29.owrt/drivers/pci/pci-driver.c 2009-05-10 22:04:39.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/drivers/pci/pci-driver.c 2009-05-10 23:48:29.000000000 +0200 +@@ -355,8 +355,6 @@ + int i = 0; + + if (drv && drv->suspend) { +- pci_power_t prev = pci_dev->current_state; +- + pci_dev->state_saved = false; + + i = drv->suspend(pci_dev, state); +@@ -367,13 +365,8 @@ + if (pci_dev->state_saved) + goto Fixup; + +- if (pci_dev->current_state != PCI_D0 +- && pci_dev->current_state != PCI_UNKNOWN) { +- WARN_ONCE(pci_dev->current_state != prev, +- "PCI PM: Device state not saved by %pF\n", +- drv->suspend); ++ if (WARN_ON_ONCE(pci_dev->current_state != PCI_D0)) + goto Fixup; +- } + } + + pci_save_state(pci_dev); +@@ -426,24 +419,38 @@ + static void pci_pm_default_resume_noirq(struct pci_dev *pci_dev) + { + pci_restore_standard_config(pci_dev); +- pci_dev->state_saved = false; + pci_fixup_device(pci_fixup_resume_early, pci_dev); + } + +-static void pci_pm_default_resume(struct pci_dev *pci_dev) ++static int pci_pm_default_resume(struct pci_dev *pci_dev) + { + pci_fixup_device(pci_fixup_resume, pci_dev); + + if (!pci_is_bridge(pci_dev)) + pci_enable_wake(pci_dev, PCI_D0, false); ++ ++ return pci_pm_reenable_device(pci_dev); ++} ++ ++static void pci_pm_default_suspend_generic(struct pci_dev *pci_dev) ++{ ++ /* If device is enabled at this point, disable it */ ++ pci_disable_enabled_device(pci_dev); ++ /* ++ * Save state with interrupts enabled, because in principle the bus the ++ * device is on may be put into a low power state after this code runs. ++ */ ++ pci_save_state(pci_dev); + } + + static void pci_pm_default_suspend(struct pci_dev *pci_dev) + { +- /* Disable non-bridge devices without PM support */ ++ pci_pm_default_suspend_generic(pci_dev); ++ + if (!pci_is_bridge(pci_dev)) +- pci_disable_enabled_device(pci_dev); +- pci_save_state(pci_dev); ++ pci_prepare_to_sleep(pci_dev); ++ ++ pci_fixup_device(pci_fixup_suspend, pci_dev); + } + + static bool pci_has_legacy_pm_support(struct pci_dev *pci_dev) +@@ -488,49 +495,21 @@ + static int pci_pm_suspend(struct device *dev) + { + struct pci_dev *pci_dev = to_pci_dev(dev); +- struct dev_pm_ops *pm = dev->driver ? dev->driver->pm : NULL; ++ struct device_driver *drv = dev->driver; ++ int error = 0; + + if (pci_has_legacy_pm_support(pci_dev)) + return pci_legacy_suspend(dev, PMSG_SUSPEND); + +- if (!pm) { +- pci_pm_default_suspend(pci_dev); +- goto Fixup; +- } +- +- pci_dev->state_saved = false; +- +- if (pm->suspend) { +- pci_power_t prev = pci_dev->current_state; +- int error; +- +- error = pm->suspend(dev); +- suspend_report_result(pm->suspend, error); +- if (error) +- return error; +- +- if (pci_dev->state_saved) +- goto Fixup; +- +- if (pci_dev->current_state != PCI_D0 +- && pci_dev->current_state != PCI_UNKNOWN) { +- WARN_ONCE(pci_dev->current_state != prev, +- "PCI PM: State of device not saved by %pF\n", +- pm->suspend); +- goto Fixup; +- } +- } +- +- if (!pci_dev->state_saved) { +- pci_save_state(pci_dev); +- if (!pci_is_bridge(pci_dev)) +- pci_prepare_to_sleep(pci_dev); ++ if (drv && drv->pm && drv->pm->suspend) { ++ error = drv->pm->suspend(dev); ++ suspend_report_result(drv->pm->suspend, error); + } + +- Fixup: +- pci_fixup_device(pci_fixup_suspend, pci_dev); ++ if (!error) ++ pci_pm_default_suspend(pci_dev); + +- return 0; ++ return error; + } + + static int pci_pm_suspend_noirq(struct device *dev) +@@ -573,29 +552,18 @@ + static int pci_pm_resume(struct device *dev) + { + struct pci_dev *pci_dev = to_pci_dev(dev); +- struct dev_pm_ops *pm = dev->driver ? dev->driver->pm : NULL; ++ struct device_driver *drv = dev->driver; + int error = 0; + +- /* +- * This is necessary for the suspend error path in which resume is +- * called without restoring the standard config registers of the device. +- */ +- if (pci_dev->state_saved) +- pci_restore_standard_config(pci_dev); +- + if (pci_has_legacy_pm_support(pci_dev)) + return pci_legacy_resume(dev); + +- pci_pm_default_resume(pci_dev); ++ error = pci_pm_default_resume(pci_dev); + +- if (pm) { +- if (pm->resume) +- error = pm->resume(dev); +- } else { +- pci_pm_reenable_device(pci_dev); +- } ++ if (!error && drv && drv->pm && drv->pm->resume) ++ error = drv->pm->resume(dev); + +- return 0; ++ return error; + } + + #else /* !CONFIG_SUSPEND */ +@@ -612,31 +580,21 @@ + static int pci_pm_freeze(struct device *dev) + { + struct pci_dev *pci_dev = to_pci_dev(dev); +- struct dev_pm_ops *pm = dev->driver ? dev->driver->pm : NULL; ++ struct device_driver *drv = dev->driver; ++ int error = 0; + + if (pci_has_legacy_pm_support(pci_dev)) + return pci_legacy_suspend(dev, PMSG_FREEZE); + +- if (!pm) { +- pci_pm_default_suspend(pci_dev); +- return 0; ++ if (drv && drv->pm && drv->pm->freeze) { ++ error = drv->pm->freeze(dev); ++ suspend_report_result(drv->pm->freeze, error); + } + +- pci_dev->state_saved = false; +- +- if (pm->freeze) { +- int error; +- +- error = pm->freeze(dev); +- suspend_report_result(pm->freeze, error); +- if (error) +- return error; +- } +- +- if (!pci_dev->state_saved) +- pci_save_state(pci_dev); ++ if (!error) ++ pci_pm_default_suspend_generic(pci_dev); + +- return 0; ++ return error; + } + + static int pci_pm_freeze_noirq(struct device *dev) +@@ -679,18 +637,16 @@ + static int pci_pm_thaw(struct device *dev) + { + struct pci_dev *pci_dev = to_pci_dev(dev); +- struct dev_pm_ops *pm = dev->driver ? dev->driver->pm : NULL; ++ struct device_driver *drv = dev->driver; + int error = 0; + + if (pci_has_legacy_pm_support(pci_dev)) + return pci_legacy_resume(dev); + +- if (pm) { +- if (pm->thaw) +- error = pm->thaw(dev); +- } else { +- pci_pm_reenable_device(pci_dev); +- } ++ pci_pm_reenable_device(pci_dev); ++ ++ if (drv && drv->pm && drv->pm->thaw) ++ error = drv->pm->thaw(dev); + + return error; + } +@@ -698,29 +654,19 @@ + static int pci_pm_poweroff(struct device *dev) + { + struct pci_dev *pci_dev = to_pci_dev(dev); +- struct dev_pm_ops *pm = dev->driver ? dev->driver->pm : NULL; ++ struct device_driver *drv = dev->driver; + int error = 0; + + if (pci_has_legacy_pm_support(pci_dev)) + return pci_legacy_suspend(dev, PMSG_HIBERNATE); + +- if (!pm) { +- pci_pm_default_suspend(pci_dev); +- goto Fixup; ++ if (drv && drv->pm && drv->pm->poweroff) { ++ error = drv->pm->poweroff(dev); ++ suspend_report_result(drv->pm->poweroff, error); + } + +- pci_dev->state_saved = false; +- +- if (pm->poweroff) { +- error = pm->poweroff(dev); +- suspend_report_result(pm->poweroff, error); +- } +- +- if (!pci_dev->state_saved && !pci_is_bridge(pci_dev)) +- pci_prepare_to_sleep(pci_dev); +- +- Fixup: +- pci_fixup_device(pci_fixup_suspend, pci_dev); ++ if (!error) ++ pci_pm_default_suspend(pci_dev); + + return error; + } +@@ -761,27 +707,16 @@ + static int pci_pm_restore(struct device *dev) + { + struct pci_dev *pci_dev = to_pci_dev(dev); +- struct dev_pm_ops *pm = dev->driver ? dev->driver->pm : NULL; ++ struct device_driver *drv = dev->driver; + int error = 0; + +- /* +- * This is necessary for the hibernation error path in which restore is +- * called without restoring the standard config registers of the device. +- */ +- if (pci_dev->state_saved) +- pci_restore_standard_config(pci_dev); +- + if (pci_has_legacy_pm_support(pci_dev)) + return pci_legacy_resume(dev); + +- pci_pm_default_resume(pci_dev); ++ error = pci_pm_default_resume(pci_dev); + +- if (pm) { +- if (pm->restore) +- error = pm->restore(dev); +- } else { +- pci_pm_reenable_device(pci_dev); +- } ++ if (!error && drv && drv->pm && drv->pm->restore) ++ error = drv->pm->restore(dev); + + return error; + } +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/drivers/pci/pcie/aer/aerdrv_core.c linux-2.6.29-rc3.owrt/drivers/pci/pcie/aer/aerdrv_core.c +--- linux-2.6.29.owrt/drivers/pci/pcie/aer/aerdrv_core.c 2009-05-10 22:04:39.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/drivers/pci/pcie/aer/aerdrv_core.c 2009-05-10 23:48:29.000000000 +0200 +@@ -108,37 +108,6 @@ + } + #endif /* 0 */ + +- +-static void set_device_error_reporting(struct pci_dev *dev, void *data) +-{ +- bool enable = *((bool *)data); +- +- if (dev->pcie_type != PCIE_RC_PORT && +- dev->pcie_type != PCIE_SW_UPSTREAM_PORT && +- dev->pcie_type != PCIE_SW_DOWNSTREAM_PORT) +- return; +- +- if (enable) +- pci_enable_pcie_error_reporting(dev); +- else +- pci_disable_pcie_error_reporting(dev); +-} +- +-/** +- * set_downstream_devices_error_reporting - enable/disable the error reporting bits on the root port and its downstream ports. +- * @dev: pointer to root port's pci_dev data structure +- * @enable: true = enable error reporting, false = disable error reporting. +- */ +-static void set_downstream_devices_error_reporting(struct pci_dev *dev, +- bool enable) +-{ +- set_device_error_reporting(dev, &enable); +- +- if (!dev->subordinate) +- return; +- pci_walk_bus(dev->subordinate, set_device_error_reporting, &enable); +-} +- + static int find_device_iter(struct device *device, void *data) + { + struct pci_dev *dev; +@@ -556,11 +525,15 @@ + pci_read_config_dword(pdev, aer_pos + PCI_ERR_UNCOR_STATUS, ®32); + pci_write_config_dword(pdev, aer_pos + PCI_ERR_UNCOR_STATUS, reg32); + +- /* +- * Enable error reporting for the root port device and downstream port +- * devices. +- */ +- set_downstream_devices_error_reporting(pdev, true); ++ /* Enable Root Port device reporting error itself */ ++ pci_read_config_word(pdev, pos+PCI_EXP_DEVCTL, ®16); ++ reg16 = reg16 | ++ PCI_EXP_DEVCTL_CERE | ++ PCI_EXP_DEVCTL_NFERE | ++ PCI_EXP_DEVCTL_FERE | ++ PCI_EXP_DEVCTL_URRE; ++ pci_write_config_word(pdev, pos+PCI_EXP_DEVCTL, ++ reg16); + + /* Enable Root Port's interrupt in response to error messages */ + pci_write_config_dword(pdev, +@@ -580,12 +553,6 @@ + u32 reg32; + int pos; + +- /* +- * Disable error reporting for the root port device and downstream port +- * devices. +- */ +- set_downstream_devices_error_reporting(pdev, false); +- + pos = pci_find_ext_capability(pdev, PCI_EXT_CAP_ID_ERR); + /* Disable Root's interrupt in response to error messages */ + pci_write_config_dword(pdev, pos + PCI_ERR_ROOT_COMMAND, 0); +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/drivers/pci/pcie/aspm.c linux-2.6.29-rc3.owrt/drivers/pci/pcie/aspm.c +--- linux-2.6.29.owrt/drivers/pci/pcie/aspm.c 2009-05-10 22:04:39.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/drivers/pci/pcie/aspm.c 2009-05-10 23:48:29.000000000 +0200 +@@ -718,9 +718,9 @@ + + /* + * All PCIe functions are in one slot, remove one function will remove +- * the whole slot, so just wait until we are the last function left. ++ * the the whole slot, so just wait + */ +- if (!list_is_last(&pdev->bus_list, &parent->subordinate->devices)) ++ if (!list_empty(&parent->subordinate->devices)) + goto out; + + /* All functions are removed, so just disable ASPM for the link */ +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/drivers/pci/pcie/portdrv_pci.c linux-2.6.29-rc3.owrt/drivers/pci/pcie/portdrv_pci.c +--- linux-2.6.29.owrt/drivers/pci/pcie/portdrv_pci.c 2009-05-10 22:04:39.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/drivers/pci/pcie/portdrv_pci.c 2009-05-10 23:48:29.000000000 +0200 +@@ -55,13 +55,25 @@ + + } + ++static int pcie_portdrv_suspend_late(struct pci_dev *dev, pm_message_t state) ++{ ++ return pci_save_state(dev); ++} ++ ++static int pcie_portdrv_resume_early(struct pci_dev *dev) ++{ ++ return pci_restore_state(dev); ++} ++ + static int pcie_portdrv_resume(struct pci_dev *dev) + { +- pci_set_master(dev); ++ pcie_portdrv_restore_config(dev); + return pcie_port_device_resume(dev); + } + #else + #define pcie_portdrv_suspend NULL ++#define pcie_portdrv_suspend_late NULL ++#define pcie_portdrv_resume_early NULL + #define pcie_portdrv_resume NULL + #endif + +@@ -97,13 +109,14 @@ + + pcie_portdrv_save_config(dev); + ++ pci_enable_pcie_error_reporting(dev); ++ + return 0; + } + + static void pcie_portdrv_remove (struct pci_dev *dev) + { + pcie_port_device_remove(dev); +- pci_disable_device(dev); + kfree(pci_get_drvdata(dev)); + } + +@@ -279,6 +292,8 @@ + .remove = pcie_portdrv_remove, + + .suspend = pcie_portdrv_suspend, ++ .suspend_late = pcie_portdrv_suspend_late, ++ .resume_early = pcie_portdrv_resume_early, + .resume = pcie_portdrv_resume, + + .err_handler = &pcie_portdrv_err_handler, +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/drivers/pci/pci.h linux-2.6.29-rc3.owrt/drivers/pci/pci.h +--- linux-2.6.29.owrt/drivers/pci/pci.h 2009-05-10 22:04:39.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/drivers/pci/pci.h 2009-05-10 23:48:29.000000000 +0200 +@@ -16,21 +16,21 @@ + #endif + + /** +- * struct pci_platform_pm_ops - Firmware PM callbacks ++ * Firmware PM callbacks + * +- * @is_manageable: returns 'true' if given device is power manageable by the +- * platform firmware ++ * @is_manageable - returns 'true' if given device is power manageable by the ++ * platform firmware + * +- * @set_state: invokes the platform firmware to set the device's power state ++ * @set_state - invokes the platform firmware to set the device's power state + * +- * @choose_state: returns PCI power state of given device preferred by the +- * platform; to be used during system-wide transitions from a +- * sleeping state to the working state and vice versa ++ * @choose_state - returns PCI power state of given device preferred by the ++ * platform; to be used during system-wide transitions from a ++ * sleeping state to the working state and vice versa + * +- * @can_wakeup: returns 'true' if given device is capable of waking up the +- * system from a sleeping state ++ * @can_wakeup - returns 'true' if given device is capable of waking up the ++ * system from a sleeping state + * +- * @sleep_wake: enables/disables the system wake up capability of given device ++ * @sleep_wake - enables/disables the system wake up capability of given device + * + * If given platform is generally capable of power managing PCI devices, all of + * these callbacks are mandatory. +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/drivers/pci/pci-sysfs.c linux-2.6.29-rc3.owrt/drivers/pci/pci-sysfs.c +--- linux-2.6.29.owrt/drivers/pci/pci-sysfs.c 2009-05-10 22:04:39.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/drivers/pci/pci-sysfs.c 2009-05-10 23:48:29.000000000 +0200 +@@ -768,8 +768,8 @@ + return -EINVAL; + + rom = pci_map_rom(pdev, &size); /* size starts out as PCI window size */ +- if (!rom || !size) +- return -EIO; ++ if (!rom) ++ return 0; + + if (off >= size) + count = 0; +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/drivers/pci/quirks.c linux-2.6.29-rc3.owrt/drivers/pci/quirks.c +--- linux-2.6.29.owrt/drivers/pci/quirks.c 2009-05-10 22:04:39.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/drivers/pci/quirks.c 2009-05-10 23:48:29.000000000 +0200 +@@ -23,7 +23,6 @@ + #include <linux/acpi.h> + #include <linux/kallsyms.h> + #include <linux/dmi.h> +-#include <linux/pci-aspm.h> + #include "pci.h" + + int isa_dma_bridge_buggy; +@@ -1585,7 +1584,6 @@ + */ + #define AMD_813X_MISC 0x40 + #define AMD_813X_NOIOAMODE (1<<0) +-#define AMD_813X_REV_B2 0x13 + + static void quirk_disable_amd_813x_boot_interrupt(struct pci_dev *dev) + { +@@ -1593,8 +1591,6 @@ + + if (noioapicquirk) + return; +- if (dev->revision == AMD_813X_REV_B2) +- return; + + pci_read_config_dword(dev, AMD_813X_MISC, &pci_config_dword); + pci_config_dword &= ~AMD_813X_NOIOAMODE; +@@ -1750,30 +1746,6 @@ + } + DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_INTEL, PCI_ANY_ID, quirk_e100_interrupt); + +-/* +- * The 82575 and 82598 may experience data corruption issues when transitioning +- * out of L0S. To prevent this we need to disable L0S on the pci-e link +- */ +-static void __devinit quirk_disable_aspm_l0s(struct pci_dev *dev) +-{ +- dev_info(&dev->dev, "Disabling L0s\n"); +- pci_disable_link_state(dev, PCIE_LINK_STATE_L0S); +-} +-DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_INTEL, 0x10a7, quirk_disable_aspm_l0s); +-DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_INTEL, 0x10a9, quirk_disable_aspm_l0s); +-DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_INTEL, 0x10b6, quirk_disable_aspm_l0s); +-DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_INTEL, 0x10c6, quirk_disable_aspm_l0s); +-DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_INTEL, 0x10c7, quirk_disable_aspm_l0s); +-DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_INTEL, 0x10c8, quirk_disable_aspm_l0s); +-DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_INTEL, 0x10d6, quirk_disable_aspm_l0s); +-DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_INTEL, 0x10db, quirk_disable_aspm_l0s); +-DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_INTEL, 0x10dd, quirk_disable_aspm_l0s); +-DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_INTEL, 0x10e1, quirk_disable_aspm_l0s); +-DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_INTEL, 0x10ec, quirk_disable_aspm_l0s); +-DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_INTEL, 0x10f1, quirk_disable_aspm_l0s); +-DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_INTEL, 0x10f4, quirk_disable_aspm_l0s); +-DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_INTEL, 0x1508, quirk_disable_aspm_l0s); +- + static void __devinit fixup_rev1_53c810(struct pci_dev* dev) + { + /* rev 1 ncr53c810 chips don't set the class at all which means +@@ -2009,6 +1981,7 @@ + DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_SERVERWORKS, PCI_DEVICE_ID_SERVERWORKS_HT2000_PCIE, + quirk_msi_ht_cap); + ++ + /* The nVidia CK804 chipset may have 2 HT MSI mappings. + * MSI are supported if the MSI capability set in any of these mappings. + */ +@@ -2059,9 +2032,6 @@ + PCI_DEVICE_ID_SERVERWORKS_HT1000_PXB, + ht_enable_msi_mapping); + +-DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_AMD, PCI_DEVICE_ID_AMD_8132_BRIDGE, +- ht_enable_msi_mapping); +- + /* The P5N32-SLI Premium motherboard from Asus has a problem with msi + * for the MCP55 NIC. It is not yet determined whether the msi problem + * also affects other devices. As for now, turn off msi for this device. +@@ -2078,104 +2048,10 @@ + PCI_DEVICE_ID_NVIDIA_NVENET_15, + nvenet_msi_disable); + +-static void __devinit nv_ht_enable_msi_mapping(struct pci_dev *dev) +-{ +- struct pci_dev *host_bridge; +- int pos; +- int i, dev_no; +- int found = 0; +- +- dev_no = dev->devfn >> 3; +- for (i = dev_no; i >= 0; i--) { +- host_bridge = pci_get_slot(dev->bus, PCI_DEVFN(i, 0)); +- if (!host_bridge) +- continue; +- +- pos = pci_find_ht_capability(host_bridge, HT_CAPTYPE_SLAVE); +- if (pos != 0) { +- found = 1; +- break; +- } +- pci_dev_put(host_bridge); +- } +- +- if (!found) +- return; +- +- /* root did that ! */ +- if (msi_ht_cap_enabled(host_bridge)) +- goto out; +- +- ht_enable_msi_mapping(dev); +- +-out: +- pci_dev_put(host_bridge); +-} +- +-static void __devinit ht_disable_msi_mapping(struct pci_dev *dev) +-{ +- int pos, ttl = 48; +- +- pos = pci_find_ht_capability(dev, HT_CAPTYPE_MSI_MAPPING); +- while (pos && ttl--) { +- u8 flags; +- +- if (pci_read_config_byte(dev, pos + HT_MSI_FLAGS, +- &flags) == 0) { +- dev_info(&dev->dev, "Disabling HT MSI Mapping\n"); +- +- pci_write_config_byte(dev, pos + HT_MSI_FLAGS, +- flags & ~HT_MSI_FLAGS_ENABLE); +- } +- pos = pci_find_next_ht_capability(dev, pos, +- HT_CAPTYPE_MSI_MAPPING); +- } +-} +- +-static int __devinit ht_check_msi_mapping(struct pci_dev *dev) +-{ +- int pos, ttl = 48; +- int found = 0; +- +- /* check if there is HT MSI cap or enabled on this device */ +- pos = pci_find_ht_capability(dev, HT_CAPTYPE_MSI_MAPPING); +- while (pos && ttl--) { +- u8 flags; +- +- if (found < 1) +- found = 1; +- if (pci_read_config_byte(dev, pos + HT_MSI_FLAGS, +- &flags) == 0) { +- if (flags & HT_MSI_FLAGS_ENABLE) { +- if (found < 2) { +- found = 2; +- break; +- } +- } +- } +- pos = pci_find_next_ht_capability(dev, pos, +- HT_CAPTYPE_MSI_MAPPING); +- } +- +- return found; +-} +- + static void __devinit nv_msi_ht_cap_quirk(struct pci_dev *dev) + { + struct pci_dev *host_bridge; +- int pos; +- int found; +- +- /* Enabling HT MSI mapping on this device breaks MCP51 */ +- if (dev->device == 0x270) +- return; +- +- /* check if there is HT MSI cap or enabled on this device */ +- found = ht_check_msi_mapping(dev); +- +- /* no HT MSI CAP */ +- if (found == 0) +- return; ++ int pos, ttl = 48; + + /* + * HT MSI mapping should be disabled on devices that are below +@@ -2191,19 +2067,24 @@ + pos = pci_find_ht_capability(host_bridge, HT_CAPTYPE_SLAVE); + if (pos != 0) { + /* Host bridge is to HT */ +- if (found == 1) { +- /* it is not enabled, try to enable it */ +- nv_ht_enable_msi_mapping(dev); +- } ++ ht_enable_msi_mapping(dev); + return; + } + +- /* HT MSI is not enabled */ +- if (found == 1) +- return; +- + /* Host bridge is not to HT, disable HT MSI mapping on this device */ +- ht_disable_msi_mapping(dev); ++ pos = pci_find_ht_capability(dev, HT_CAPTYPE_MSI_MAPPING); ++ while (pos && ttl--) { ++ u8 flags; ++ ++ if (pci_read_config_byte(dev, pos + HT_MSI_FLAGS, ++ &flags) == 0) { ++ dev_info(&dev->dev, "Disabling HT MSI mapping"); ++ pci_write_config_byte(dev, pos + HT_MSI_FLAGS, ++ flags & ~HT_MSI_FLAGS_ENABLE); ++ } ++ pos = pci_find_next_ht_capability(dev, pos, ++ HT_CAPTYPE_MSI_MAPPING); ++ } + } + DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_NVIDIA, PCI_ANY_ID, nv_msi_ht_cap_quirk); + DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_AL, PCI_ANY_ID, nv_msi_ht_cap_quirk); +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/drivers/pci/rom.c linux-2.6.29-rc3.owrt/drivers/pci/rom.c +--- linux-2.6.29.owrt/drivers/pci/rom.c 2009-05-10 22:04:39.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/drivers/pci/rom.c 2009-05-10 23:48:29.000000000 +0200 +@@ -55,7 +55,6 @@ + + /** + * pci_get_rom_size - obtain the actual size of the ROM image +- * @pdev: target PCI device + * @rom: kernel virtual pointer to image of ROM + * @size: size of PCI window + * return: size of actual ROM image +@@ -64,7 +63,7 @@ + * The PCI window size could be much larger than the + * actual image size. + */ +-size_t pci_get_rom_size(struct pci_dev *pdev, void __iomem *rom, size_t size) ++size_t pci_get_rom_size(void __iomem *rom, size_t size) + { + void __iomem *image; + int last_image; +@@ -73,10 +72,8 @@ + do { + void __iomem *pds; + /* Standard PCI ROMs start out with these bytes 55 AA */ +- if (readb(image) != 0x55) { +- dev_err(&pdev->dev, "Invalid ROM contents\n"); ++ if (readb(image) != 0x55) + break; +- } + if (readb(image + 1) != 0xAA) + break; + /* get the PCI data structure and check its signature */ +@@ -162,7 +159,7 @@ + * size is much larger than the actual size of the ROM. + * True size is important if the ROM is going to be copied. + */ +- *size = pci_get_rom_size(pdev, rom, *size); ++ *size = pci_get_rom_size(rom, *size); + return rom; + } + +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/drivers/platform/x86/acer-wmi.c linux-2.6.29-rc3.owrt/drivers/platform/x86/acer-wmi.c +--- linux-2.6.29.owrt/drivers/platform/x86/acer-wmi.c 2009-05-10 22:04:39.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/drivers/platform/x86/acer-wmi.c 2009-05-10 23:48:29.000000000 +0200 +@@ -1026,7 +1026,7 @@ + kfree(wireless_rfkill->data); + rfkill_unregister(wireless_rfkill); + if (has_cap(ACER_CAP_BLUETOOTH)) { +- kfree(bluetooth_rfkill->data); ++ kfree(wireless_rfkill->data); + rfkill_unregister(bluetooth_rfkill); + } + return; +@@ -1297,7 +1297,7 @@ + + set_quirks(); + +- if (acpi_video_backlight_support() && has_cap(ACER_CAP_BRIGHTNESS)) { ++ if (!acpi_video_backlight_support() && has_cap(ACER_CAP_BRIGHTNESS)) { + interface->capability &= ~ACER_CAP_BRIGHTNESS; + printk(ACER_INFO "Brightness must be controlled by " + "generic video driver\n"); +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/drivers/platform/x86/asus_acpi.c linux-2.6.29-rc3.owrt/drivers/platform/x86/asus_acpi.c +--- linux-2.6.29.owrt/drivers/platform/x86/asus_acpi.c 2009-05-10 22:04:39.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/drivers/platform/x86/asus_acpi.c 2009-05-10 23:48:29.000000000 +0200 +@@ -143,7 +143,6 @@ + S1300N, S5200N*/ + A4S, /* Z81sp */ + F3Sa, /* (Centrino) */ +- R1F, + END_MODEL + } model; /* Models currently supported */ + u16 event_count[128]; /* Count for each event TODO make this better */ +@@ -421,18 +420,7 @@ + .display_get = "\\ADVG", + .display_set = "SDSP", + }, +- { +- .name = "R1F", +- .mt_bt_switch = "BLED", +- .mt_mled = "MLED", +- .mt_wled = "WLED", +- .mt_lcd_switch = "\\Q10", +- .lcd_status = "\\GP06", +- .brightness_set = "SPLV", +- .brightness_get = "GPLV", +- .display_set = "SDSP", +- .display_get = "\\INFB" +- } ++ + }; + + /* procdir we use */ +@@ -1177,8 +1165,6 @@ + return W3V; + else if (strncmp(model, "W5A", 3) == 0) + return W5A; +- else if (strncmp(model, "R1F", 3) == 0) +- return R1F; + else if (strncmp(model, "A4S", 3) == 0) + return A4S; + else if (strncmp(model, "F3Sa", 4) == 0) +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/drivers/platform/x86/asus-laptop.c linux-2.6.29-rc3.owrt/drivers/platform/x86/asus-laptop.c +--- linux-2.6.29.owrt/drivers/platform/x86/asus-laptop.c 2009-05-10 22:04:39.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/drivers/platform/x86/asus-laptop.c 2009-05-10 23:48:29.000000000 +0200 +@@ -46,7 +46,6 @@ + #include <acpi/acpi_drivers.h> + #include <acpi/acpi_bus.h> + #include <asm/uaccess.h> +-#include <linux/input.h> + + #define ASUS_LAPTOP_VERSION "0.42" + +@@ -182,8 +181,6 @@ + u8 light_level; //light sensor level + u8 light_switch; //light sensor switch value + u16 event_count[128]; //count for each event TODO make this better +- struct input_dev *inputdev; +- u16 *keycode_map; + }; + + /* +@@ -253,37 +250,6 @@ + ASUS_LED(pled, "phone"); + ASUS_LED(gled, "gaming"); + +-struct key_entry { +- char type; +- u8 code; +- u16 keycode; +-}; +- +-enum { KE_KEY, KE_END }; +- +-static struct key_entry asus_keymap[] = { +- {KE_KEY, 0x30, KEY_VOLUMEUP}, +- {KE_KEY, 0x31, KEY_VOLUMEDOWN}, +- {KE_KEY, 0x32, KEY_MUTE}, +- {KE_KEY, 0x33, KEY_SWITCHVIDEOMODE}, +- {KE_KEY, 0x34, KEY_SWITCHVIDEOMODE}, +- {KE_KEY, 0x40, KEY_PREVIOUSSONG}, +- {KE_KEY, 0x41, KEY_NEXTSONG}, +- {KE_KEY, 0x43, KEY_STOP}, +- {KE_KEY, 0x45, KEY_PLAYPAUSE}, +- {KE_KEY, 0x50, KEY_EMAIL}, +- {KE_KEY, 0x51, KEY_WWW}, +- {KE_KEY, 0x5C, BTN_EXTRA}, /* Performance */ +- {KE_KEY, 0x5D, KEY_WLAN}, +- {KE_KEY, 0x61, KEY_SWITCHVIDEOMODE}, +- {KE_KEY, 0x6B, BTN_TOUCH}, /* Lock Mouse */ +- {KE_KEY, 0x82, KEY_CAMERA}, +- {KE_KEY, 0x8A, KEY_TV}, +- {KE_KEY, 0x95, KEY_MEDIA}, +- {KE_KEY, 0x99, KEY_PHONE}, +- {KE_END, 0}, +-}; +- + /* + * This function evaluates an ACPI method, given an int as parameter, the + * method is searched within the scope of the handle, can be NULL. The output +@@ -754,69 +720,8 @@ + return store_status(buf, count, NULL, GPS_ON); + } + +-/* +- * Hotkey functions +- */ +-static struct key_entry *asus_get_entry_by_scancode(int code) +-{ +- struct key_entry *key; +- +- for (key = asus_keymap; key->type != KE_END; key++) +- if (code == key->code) +- return key; +- +- return NULL; +-} +- +-static struct key_entry *asus_get_entry_by_keycode(int code) +-{ +- struct key_entry *key; +- +- for (key = asus_keymap; key->type != KE_END; key++) +- if (code == key->keycode && key->type == KE_KEY) +- return key; +- +- return NULL; +-} +- +-static int asus_getkeycode(struct input_dev *dev, int scancode, int *keycode) +-{ +- struct key_entry *key = asus_get_entry_by_scancode(scancode); +- +- if (key && key->type == KE_KEY) { +- *keycode = key->keycode; +- return 0; +- } +- +- return -EINVAL; +-} +- +-static int asus_setkeycode(struct input_dev *dev, int scancode, int keycode) +-{ +- struct key_entry *key; +- int old_keycode; +- +- if (keycode < 0 || keycode > KEY_MAX) +- return -EINVAL; +- +- key = asus_get_entry_by_scancode(scancode); +- if (key && key->type == KE_KEY) { +- old_keycode = key->keycode; +- key->keycode = keycode; +- set_bit(keycode, dev->keybit); +- if (!asus_get_entry_by_keycode(old_keycode)) +- clear_bit(old_keycode, dev->keybit); +- return 0; +- } +- +- return -EINVAL; +-} +- + static void asus_hotk_notify(acpi_handle handle, u32 event, void *data) + { +- static struct key_entry *key; +- u16 count; +- + /* TODO Find a better way to handle events count. */ + if (!hotk) + return; +@@ -833,26 +738,10 @@ + lcd_blank(FB_BLANK_POWERDOWN); + } + +- count = hotk->event_count[event % 128]++; +- acpi_bus_generate_proc_event(hotk->device, event, count); +- acpi_bus_generate_netlink_event(hotk->device->pnp.device_class, +- dev_name(&hotk->device->dev), event, +- count); +- +- if (hotk->inputdev) { +- key = asus_get_entry_by_scancode(event); +- if (!key) +- return ; +- +- switch (key->type) { +- case KE_KEY: +- input_report_key(hotk->inputdev, key->keycode, 1); +- input_sync(hotk->inputdev); +- input_report_key(hotk->inputdev, key->keycode, 0); +- input_sync(hotk->inputdev); +- break; +- } +- } ++ acpi_bus_generate_proc_event(hotk->device, event, ++ hotk->event_count[event % 128]++); ++ ++ return; + } + + #define ASUS_CREATE_DEVICE_ATTR(_name) \ +@@ -1070,38 +959,6 @@ + return AE_OK; + } + +-static int asus_input_init(void) +-{ +- const struct key_entry *key; +- int result; +- +- hotk->inputdev = input_allocate_device(); +- if (!hotk->inputdev) { +- printk(ASUS_INFO "Unable to allocate input device\n"); +- return 0; +- } +- hotk->inputdev->name = "Asus Laptop extra buttons"; +- hotk->inputdev->phys = ASUS_HOTK_FILE "/input0"; +- hotk->inputdev->id.bustype = BUS_HOST; +- hotk->inputdev->getkeycode = asus_getkeycode; +- hotk->inputdev->setkeycode = asus_setkeycode; +- +- for (key = asus_keymap; key->type != KE_END; key++) { +- switch (key->type) { +- case KE_KEY: +- set_bit(EV_KEY, hotk->inputdev->evbit); +- set_bit(key->keycode, hotk->inputdev->keybit); +- break; +- } +- } +- result = input_register_device(hotk->inputdev); +- if (result) { +- printk(ASUS_INFO "Unable to register input device\n"); +- input_free_device(hotk->inputdev); +- } +- return result; +-} +- + static int asus_hotk_check(void) + { + int result = 0; +@@ -1187,7 +1044,7 @@ + /* GPS is on by default */ + write_status(NULL, 1, GPS_ON); + +-end: ++ end: + if (result) { + kfree(hotk->name); + kfree(hotk); +@@ -1234,17 +1091,10 @@ + ASUS_LED_UNREGISTER(gled); + } + +-static void asus_input_exit(void) +-{ +- if (hotk->inputdev) +- input_unregister_device(hotk->inputdev); +-} +- + static void __exit asus_laptop_exit(void) + { + asus_backlight_exit(); + asus_led_exit(); +- asus_input_exit(); + + acpi_bus_unregister_driver(&asus_hotk_driver); + sysfs_remove_group(&asuspf_device->dev.kobj, &asuspf_attribute_group); +@@ -1366,10 +1216,6 @@ + printk(ASUS_INFO "Brightness ignored, must be controlled by " + "ACPI video driver\n"); + +- result = asus_input_init(); +- if (result) +- goto fail_input; +- + result = asus_led_init(dev); + if (result) + goto fail_led; +@@ -1396,25 +1242,22 @@ + + return 0; + +-fail_sysfs: ++ fail_sysfs: + platform_device_del(asuspf_device); + +-fail_platform_device2: ++ fail_platform_device2: + platform_device_put(asuspf_device); + +-fail_platform_device1: ++ fail_platform_device1: + platform_driver_unregister(&asuspf_driver); + +-fail_platform_driver: ++ fail_platform_driver: + asus_led_exit(); + +-fail_led: +- asus_input_exit(); +- +-fail_input: ++ fail_led: + asus_backlight_exit(); + +-fail_backlight: ++ fail_backlight: + + return result; + } +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/drivers/platform/x86/eeepc-laptop.c linux-2.6.29-rc3.owrt/drivers/platform/x86/eeepc-laptop.c +--- linux-2.6.29.owrt/drivers/platform/x86/eeepc-laptop.c 2009-05-10 22:04:39.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/drivers/platform/x86/eeepc-laptop.c 2009-05-10 23:48:29.000000000 +0200 +@@ -30,7 +30,6 @@ + #include <linux/uaccess.h> + #include <linux/input.h> + #include <linux/rfkill.h> +-#include <linux/pci.h> + + #define EEEPC_LAPTOP_VERSION "0.1" + +@@ -162,10 +161,6 @@ + {KE_KEY, 0x13, KEY_MUTE }, + {KE_KEY, 0x14, KEY_VOLUMEDOWN }, + {KE_KEY, 0x15, KEY_VOLUMEUP }, +- {KE_KEY, 0x1a, KEY_COFFEE }, +- {KE_KEY, 0x1b, KEY_ZOOM }, +- {KE_KEY, 0x1c, KEY_PROG2 }, +- {KE_KEY, 0x1d, KEY_PROG3 }, + {KE_KEY, 0x30, KEY_SWITCHVIDEOMODE }, + {KE_KEY, 0x31, KEY_SWITCHVIDEOMODE }, + {KE_KEY, 0x32, KEY_SWITCHVIDEOMODE }, +@@ -515,59 +510,18 @@ + static void notify_brn(void) + { + struct backlight_device *bd = eeepc_backlight_device; +- if (bd) +- bd->props.brightness = read_brightness(bd); +-} +- +-static void eeepc_rfkill_notify(acpi_handle handle, u32 event, void *data) +-{ +- struct pci_dev *dev; +- struct pci_bus *bus = pci_find_bus(0, 1); +- +- if (event != ACPI_NOTIFY_BUS_CHECK) +- return; +- +- if (!bus) { +- printk(EEEPC_WARNING "Unable to find PCI bus 1?\n"); +- return; +- } +- +- if (get_acpi(CM_ASL_WLAN) == 1) { +- dev = pci_get_slot(bus, 0); +- if (dev) { +- /* Device already present */ +- pci_dev_put(dev); +- return; +- } +- dev = pci_scan_single_device(bus, 0); +- if (dev) { +- pci_bus_assign_resources(bus); +- if (pci_bus_add_device(dev)) +- printk(EEEPC_ERR "Unable to hotplug wifi\n"); +- } +- } else { +- dev = pci_get_slot(bus, 0); +- if (dev) { +- pci_remove_bus_device(dev); +- pci_dev_put(dev); +- } +- } ++ bd->props.brightness = read_brightness(bd); + } + + static void eeepc_hotk_notify(acpi_handle handle, u32 event, void *data) + { + static struct key_entry *key; +- u16 count; +- + if (!ehotk) + return; + if (event >= NOTIFY_BRN_MIN && event <= NOTIFY_BRN_MAX) + notify_brn(); +- count = ehotk->event_count[event % 128]++; +- acpi_bus_generate_proc_event(ehotk->device, event, count); +- acpi_bus_generate_netlink_event(ehotk->device->pnp.device_class, +- dev_name(&ehotk->device->dev), event, +- count); ++ acpi_bus_generate_proc_event(ehotk->device, event, ++ ehotk->event_count[event % 128]++); + if (ehotk->inputdev) { + key = eepc_get_entry_by_scancode(event); + if (key) { +@@ -585,45 +539,6 @@ + } + } + +-static int eeepc_register_rfkill_notifier(char *node) +-{ +- acpi_status status = AE_OK; +- acpi_handle handle; +- +- status = acpi_get_handle(NULL, node, &handle); +- +- if (ACPI_SUCCESS(status)) { +- status = acpi_install_notify_handler(handle, +- ACPI_SYSTEM_NOTIFY, +- eeepc_rfkill_notify, +- NULL); +- if (ACPI_FAILURE(status)) +- printk(EEEPC_WARNING +- "Failed to register notify on %s\n", node); +- } else +- return -ENODEV; +- +- return 0; +-} +- +-static void eeepc_unregister_rfkill_notifier(char *node) +-{ +- acpi_status status = AE_OK; +- acpi_handle handle; +- +- status = acpi_get_handle(NULL, node, &handle); +- +- if (ACPI_SUCCESS(status)) { +- status = acpi_remove_notify_handler(handle, +- ACPI_SYSTEM_NOTIFY, +- eeepc_rfkill_notify); +- if (ACPI_FAILURE(status)) +- printk(EEEPC_ERR +- "Error removing rfkill notify handler %s\n", +- node); +- } +-} +- + static int eeepc_hotk_add(struct acpi_device *device) + { + acpi_status status = AE_OK; +@@ -643,7 +558,7 @@ + ehotk->device = device; + result = eeepc_hotk_check(); + if (result) +- goto ehotk_fail; ++ goto end; + status = acpi_install_notify_handler(ehotk->handle, ACPI_SYSTEM_NOTIFY, + eeepc_hotk_notify, ehotk); + if (ACPI_FAILURE(status)) +@@ -654,25 +569,18 @@ + RFKILL_TYPE_WLAN); + + if (!ehotk->eeepc_wlan_rfkill) +- goto wlan_fail; ++ goto end; + + ehotk->eeepc_wlan_rfkill->name = "eeepc-wlan"; + ehotk->eeepc_wlan_rfkill->toggle_radio = eeepc_wlan_rfkill_set; + ehotk->eeepc_wlan_rfkill->get_state = eeepc_wlan_rfkill_state; +- if (get_acpi(CM_ASL_WLAN) == 1) { ++ if (get_acpi(CM_ASL_WLAN) == 1) + ehotk->eeepc_wlan_rfkill->state = + RFKILL_STATE_UNBLOCKED; +- rfkill_set_default(RFKILL_TYPE_WLAN, +- RFKILL_STATE_UNBLOCKED); +- } else { ++ else + ehotk->eeepc_wlan_rfkill->state = + RFKILL_STATE_SOFT_BLOCKED; +- rfkill_set_default(RFKILL_TYPE_WLAN, +- RFKILL_STATE_SOFT_BLOCKED); +- } +- result = rfkill_register(ehotk->eeepc_wlan_rfkill); +- if (result) +- goto wlan_fail; ++ rfkill_register(ehotk->eeepc_wlan_rfkill); + } + + if (get_acpi(CM_ASL_BLUETOOTH) != -1) { +@@ -680,47 +588,27 @@ + rfkill_allocate(&device->dev, RFKILL_TYPE_BLUETOOTH); + + if (!ehotk->eeepc_bluetooth_rfkill) +- goto bluetooth_fail; ++ goto end; + + ehotk->eeepc_bluetooth_rfkill->name = "eeepc-bluetooth"; + ehotk->eeepc_bluetooth_rfkill->toggle_radio = + eeepc_bluetooth_rfkill_set; + ehotk->eeepc_bluetooth_rfkill->get_state = + eeepc_bluetooth_rfkill_state; +- if (get_acpi(CM_ASL_BLUETOOTH) == 1) { ++ if (get_acpi(CM_ASL_BLUETOOTH) == 1) + ehotk->eeepc_bluetooth_rfkill->state = + RFKILL_STATE_UNBLOCKED; +- rfkill_set_default(RFKILL_TYPE_BLUETOOTH, +- RFKILL_STATE_UNBLOCKED); +- } else { ++ else + ehotk->eeepc_bluetooth_rfkill->state = + RFKILL_STATE_SOFT_BLOCKED; +- rfkill_set_default(RFKILL_TYPE_BLUETOOTH, +- RFKILL_STATE_SOFT_BLOCKED); +- } +- +- result = rfkill_register(ehotk->eeepc_bluetooth_rfkill); +- if (result) +- goto bluetooth_fail; ++ rfkill_register(ehotk->eeepc_bluetooth_rfkill); + } + +- eeepc_register_rfkill_notifier("\\_SB.PCI0.P0P6"); +- eeepc_register_rfkill_notifier("\\_SB.PCI0.P0P7"); +- +- return 0; +- +- bluetooth_fail: +- if (ehotk->eeepc_bluetooth_rfkill) +- rfkill_free(ehotk->eeepc_bluetooth_rfkill); +- rfkill_unregister(ehotk->eeepc_wlan_rfkill); +- ehotk->eeepc_wlan_rfkill = NULL; +- wlan_fail: +- if (ehotk->eeepc_wlan_rfkill) +- rfkill_free(ehotk->eeepc_wlan_rfkill); +- ehotk_fail: +- kfree(ehotk); +- ehotk = NULL; +- ++ end: ++ if (result) { ++ kfree(ehotk); ++ ehotk = NULL; ++ } + return result; + } + +@@ -734,10 +622,6 @@ + eeepc_hotk_notify); + if (ACPI_FAILURE(status)) + printk(EEEPC_ERR "Error removing notify handler\n"); +- +- eeepc_unregister_rfkill_notifier("\\_SB.PCI0.P0P6"); +- eeepc_unregister_rfkill_notifier("\\_SB.PCI0.P0P7"); +- + kfree(ehotk); + return 0; + } +@@ -853,21 +737,13 @@ + { + if (eeepc_backlight_device) + backlight_device_unregister(eeepc_backlight_device); +- eeepc_backlight_device = NULL; +-} +- +-static void eeepc_rfkill_exit(void) +-{ ++ if (ehotk->inputdev) ++ input_unregister_device(ehotk->inputdev); + if (ehotk->eeepc_wlan_rfkill) + rfkill_unregister(ehotk->eeepc_wlan_rfkill); + if (ehotk->eeepc_bluetooth_rfkill) + rfkill_unregister(ehotk->eeepc_bluetooth_rfkill); +-} +- +-static void eeepc_input_exit(void) +-{ +- if (ehotk->inputdev) +- input_unregister_device(ehotk->inputdev); ++ eeepc_backlight_device = NULL; + } + + static void eeepc_hwmon_exit(void) +@@ -886,8 +762,6 @@ + static void __exit eeepc_laptop_exit(void) + { + eeepc_backlight_exit(); +- eeepc_rfkill_exit(); +- eeepc_input_exit(); + eeepc_hwmon_exit(); + acpi_bus_unregister_driver(&eeepc_hotk_driver); + sysfs_remove_group(&platform_device->dev.kobj, +@@ -991,8 +865,6 @@ + fail_hwmon: + eeepc_backlight_exit(); + fail_backlight: +- eeepc_input_exit(); +- eeepc_rfkill_exit(); + return result; + } + +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/drivers/platform/x86/fujitsu-laptop.c linux-2.6.29-rc3.owrt/drivers/platform/x86/fujitsu-laptop.c +--- linux-2.6.29.owrt/drivers/platform/x86/fujitsu-laptop.c 2009-05-10 22:04:39.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/drivers/platform/x86/fujitsu-laptop.c 2009-05-10 23:48:29.000000000 +0200 +@@ -166,7 +166,6 @@ + struct platform_device *pf_device; + struct kfifo *fifo; + spinlock_t fifo_lock; +- int rfkill_supported; + int rfkill_state; + int logolamp_registered; + int kblamps_registered; +@@ -527,7 +526,7 @@ + show_lid_state(struct device *dev, + struct device_attribute *attr, char *buf) + { +- if (!(fujitsu_hotkey->rfkill_supported & 0x100)) ++ if (fujitsu_hotkey->rfkill_state == UNSUPPORTED_CMD) + return sprintf(buf, "unknown\n"); + if (fujitsu_hotkey->rfkill_state & 0x100) + return sprintf(buf, "open\n"); +@@ -539,7 +538,7 @@ + show_dock_state(struct device *dev, + struct device_attribute *attr, char *buf) + { +- if (!(fujitsu_hotkey->rfkill_supported & 0x200)) ++ if (fujitsu_hotkey->rfkill_state == UNSUPPORTED_CMD) + return sprintf(buf, "unknown\n"); + if (fujitsu_hotkey->rfkill_state & 0x200) + return sprintf(buf, "docked\n"); +@@ -551,7 +550,7 @@ + show_radios_state(struct device *dev, + struct device_attribute *attr, char *buf) + { +- if (!(fujitsu_hotkey->rfkill_supported & 0x20)) ++ if (fujitsu_hotkey->rfkill_state == UNSUPPORTED_CMD) + return sprintf(buf, "unknown\n"); + if (fujitsu_hotkey->rfkill_state & 0x20) + return sprintf(buf, "on\n"); +@@ -929,17 +928,8 @@ + ; /* No action, result is discarded */ + vdbg_printk(FUJLAPTOP_DBG_INFO, "Discarded %i ringbuffer entries\n", i); + +- fujitsu_hotkey->rfkill_supported = +- call_fext_func(FUNC_RFKILL, 0x0, 0x0, 0x0); +- +- /* Make sure our bitmask of supported functions is cleared if the +- RFKILL function block is not implemented, like on the S7020. */ +- if (fujitsu_hotkey->rfkill_supported == UNSUPPORTED_CMD) +- fujitsu_hotkey->rfkill_supported = 0; +- +- if (fujitsu_hotkey->rfkill_supported) +- fujitsu_hotkey->rfkill_state = +- call_fext_func(FUNC_RFKILL, 0x4, 0x0, 0x0); ++ fujitsu_hotkey->rfkill_state = ++ call_fext_func(FUNC_RFKILL, 0x4, 0x0, 0x0); + + /* Suspect this is a keymap of the application panel, print it */ + printk(KERN_INFO "fujitsu-laptop: BTNI: [0x%x]\n", +@@ -1015,9 +1005,8 @@ + + input = fujitsu_hotkey->input; + +- if (fujitsu_hotkey->rfkill_supported) +- fujitsu_hotkey->rfkill_state = +- call_fext_func(FUNC_RFKILL, 0x4, 0x0, 0x0); ++ fujitsu_hotkey->rfkill_state = ++ call_fext_func(FUNC_RFKILL, 0x4, 0x0, 0x0); + + switch (event) { + case ACPI_FUJITSU_NOTIFY_CODE1: +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/drivers/platform/x86/hp-wmi.c linux-2.6.29-rc3.owrt/drivers/platform/x86/hp-wmi.c +--- linux-2.6.29.owrt/drivers/platform/x86/hp-wmi.c 2009-05-10 22:04:39.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/drivers/platform/x86/hp-wmi.c 2009-05-10 23:48:29.000000000 +0200 +@@ -382,11 +382,6 @@ + case KE_SW: + set_bit(EV_SW, hp_wmi_input_dev->evbit); + set_bit(key->keycode, hp_wmi_input_dev->swbit); +- +- /* Set initial dock state */ +- input_report_switch(hp_wmi_input_dev, key->keycode, +- hp_wmi_dock_state()); +- input_sync(hp_wmi_input_dev); + break; + } + } +@@ -446,7 +441,6 @@ + bluetooth_rfkill->toggle_radio = hp_wmi_bluetooth_set; + bluetooth_rfkill->user_claim_unsupported = 1; + err = rfkill_register(bluetooth_rfkill); +- if (err) + goto register_bluetooth_error; + } + +@@ -463,11 +457,9 @@ + + return 0; + register_wwan_err: +- if (bluetooth_rfkill) +- rfkill_unregister(bluetooth_rfkill); ++ rfkill_unregister(bluetooth_rfkill); + register_bluetooth_error: +- if (wifi_rfkill) +- rfkill_unregister(wifi_rfkill); ++ rfkill_unregister(wifi_rfkill); + add_sysfs_error: + cleanup_sysfs(device); + return err; +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/drivers/platform/x86/Kconfig linux-2.6.29-rc3.owrt/drivers/platform/x86/Kconfig +--- linux-2.6.29.owrt/drivers/platform/x86/Kconfig 2009-05-10 22:04:39.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/drivers/platform/x86/Kconfig 2009-05-10 23:48:29.000000000 +0200 +@@ -15,7 +15,8 @@ + if X86_PLATFORM_DEVICES + + config ACER_WMI +- tristate "Acer WMI Laptop Extras" ++ tristate "Acer WMI Laptop Extras (EXPERIMENTAL)" ++ depends on EXPERIMENTAL + depends on ACPI + depends on LEDS_CLASS + depends on NEW_LEDS +@@ -38,10 +39,9 @@ + tristate "Asus Laptop Extras (EXPERIMENTAL)" + depends on ACPI + depends on EXPERIMENTAL && !ACPI_ASUS +- select LEDS_CLASS +- select NEW_LEDS +- select BACKLIGHT_CLASS_DEVICE +- depends on INPUT ++ depends on LEDS_CLASS ++ depends on NEW_LEDS ++ depends on BACKLIGHT_CLASS_DEVICE + ---help--- + This is the new Linux driver for Asus laptops. It may also support some + MEDION, JVC or VICTOR laptops. It makes all the extra buttons generate +@@ -61,7 +61,6 @@ + depends on EXPERIMENTAL + depends on BACKLIGHT_CLASS_DEVICE + depends on RFKILL +- depends on POWER_SUPPLY + default n + ---help--- + This driver adds support for rfkill and backlight control to Dell +@@ -184,11 +183,11 @@ + config THINKPAD_ACPI + tristate "ThinkPad ACPI Laptop Extras" + depends on ACPI +- depends on INPUT + select BACKLIGHT_LCD_SUPPORT + select BACKLIGHT_CLASS_DEVICE + select HWMON + select NVRAM ++ select INPUT + select NEW_LEDS + select LEDS_CLASS + select NET +@@ -301,7 +300,6 @@ + config EEEPC_LAPTOP + tristate "Eee PC Hotkey Driver (EXPERIMENTAL)" + depends on ACPI +- depends on INPUT + depends on EXPERIMENTAL + select BACKLIGHT_CLASS_DEVICE + select HWMON +@@ -314,8 +312,9 @@ + + + config ACPI_WMI +- tristate "WMI" ++ tristate "WMI (EXPERIMENTAL)" + depends on ACPI ++ depends on EXPERIMENTAL + help + This driver adds support for the ACPI-WMI (Windows Management + Instrumentation) mapper device (PNP0C14) found on some systems. +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/drivers/platform/x86/panasonic-laptop.c linux-2.6.29-rc3.owrt/drivers/platform/x86/panasonic-laptop.c +--- linux-2.6.29.owrt/drivers/platform/x86/panasonic-laptop.c 2009-05-10 22:04:39.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/drivers/platform/x86/panasonic-laptop.c 2009-05-10 23:48:29.000000000 +0200 +@@ -507,7 +507,7 @@ + + hkey_num = result & 0xf; + +- if (hkey_num < 0 || hkey_num >= ARRAY_SIZE(pcc->keymap)) { ++ if (hkey_num < 0 || hkey_num > ARRAY_SIZE(pcc->keymap)) { + ACPI_DEBUG_PRINT((ACPI_DB_ERROR, + "hotkey number out of range: %d\n", + hkey_num)); +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/drivers/platform/x86/thinkpad_acpi.c linux-2.6.29-rc3.owrt/drivers/platform/x86/thinkpad_acpi.c +--- linux-2.6.29.owrt/drivers/platform/x86/thinkpad_acpi.c 2009-05-10 22:04:39.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/drivers/platform/x86/thinkpad_acpi.c 2009-05-10 23:48:29.000000000 +0200 +@@ -7532,7 +7532,7 @@ + * if it is not there yet. + */ + #define IBM_BIOS_MODULE_ALIAS(__type) \ +- MODULE_ALIAS("dmi:bvnIBM:bvr" __type "ET??WW*") ++ MODULE_ALIAS("dmi:bvnIBM:bvr" __type "ET??WW") + + /* Non-ancient thinkpads */ + MODULE_ALIAS("dmi:bvnIBM:*:svnIBM:*:pvrThinkPad*:rvnIBM:*"); +@@ -7541,9 +7541,9 @@ + /* Ancient thinkpad BIOSes have to be identified by + * BIOS type or model number, and there are far less + * BIOS types than model numbers... */ +-IBM_BIOS_MODULE_ALIAS("I[BDHIMNOTWVYZ]"); +-IBM_BIOS_MODULE_ALIAS("1[0368A-GIKM-PST]"); +-IBM_BIOS_MODULE_ALIAS("K[UX-Z]"); ++IBM_BIOS_MODULE_ALIAS("I[B,D,H,I,M,N,O,T,W,V,Y,Z]"); ++IBM_BIOS_MODULE_ALIAS("1[0,3,6,8,A-G,I,K,M-P,S,T]"); ++IBM_BIOS_MODULE_ALIAS("K[U,X-Z]"); + + MODULE_AUTHOR("Borislav Deianov, Henrique de Moraes Holschuh"); + MODULE_DESCRIPTION(TPACPI_DESC); +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/drivers/platform/x86/wmi.c linux-2.6.29-rc3.owrt/drivers/platform/x86/wmi.c +--- linux-2.6.29.owrt/drivers/platform/x86/wmi.c 2009-05-10 22:04:39.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/drivers/platform/x86/wmi.c 2009-05-10 23:48:29.000000000 +0200 +@@ -708,7 +708,7 @@ + + static int __init acpi_wmi_init(void) + { +- int result; ++ acpi_status result; + + INIT_LIST_HEAD(&wmi_blocks.list); + +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/drivers/power/ds2760_battery.c linux-2.6.29-rc3.owrt/drivers/power/ds2760_battery.c +--- linux-2.6.29.owrt/drivers/power/ds2760_battery.c 2009-05-10 22:04:38.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/drivers/power/ds2760_battery.c 2009-05-10 23:48:29.000000000 +0200 +@@ -180,13 +180,10 @@ + di->empty_uAh = battery_interpolate(scale, di->temp_C / 10); + di->empty_uAh *= 1000; /* convert to µAh */ + +- if (di->full_active_uAh == di->empty_uAh) +- di->rem_capacity = 0; +- else +- /* From Maxim Application Note 131: remaining capacity = +- * ((ICA - Empty Value) / (Full Value - Empty Value)) x 100% */ +- di->rem_capacity = ((di->accum_current_uAh - di->empty_uAh) * 100L) / +- (di->full_active_uAh - di->empty_uAh); ++ /* From Maxim Application Note 131: remaining capacity = ++ * ((ICA - Empty Value) / (Full Value - Empty Value)) x 100% */ ++ di->rem_capacity = ((di->accum_current_uAh - di->empty_uAh) * 100L) / ++ (di->full_active_uAh - di->empty_uAh); + + if (di->rem_capacity < 0) + di->rem_capacity = 0; +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/drivers/power/pcf50633-charger.c linux-2.6.29-rc3.owrt/drivers/power/pcf50633-charger.c +--- linux-2.6.29.owrt/drivers/power/pcf50633-charger.c 2009-05-10 22:04:38.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/drivers/power/pcf50633-charger.c 2009-05-10 23:48:29.000000000 +0200 +@@ -199,8 +199,7 @@ + enum power_supply_property psp, + union power_supply_propval *val) + { +- struct pcf50633_mbc *mbc = container_of(psy, +- struct pcf50633_mbc, adapter); ++ struct pcf50633_mbc *mbc = container_of(psy, struct pcf50633_mbc, usb); + int ret = 0; + + switch (psp) { +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/drivers/regulator/bq24022.c linux-2.6.29-rc3.owrt/drivers/regulator/bq24022.c +--- linux-2.6.29.owrt/drivers/regulator/bq24022.c 2009-05-10 22:04:38.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/drivers/regulator/bq24022.c 2009-05-10 23:48:29.000000000 +0200 +@@ -152,7 +152,11 @@ + platform_driver_unregister(&bq24022_driver); + } + +-module_init(bq24022_init); ++/* ++ * make sure this is probed before gpio_vbus and pda_power, ++ * but after asic3 or other GPIO expander drivers. ++ */ ++subsys_initcall(bq24022_init); + module_exit(bq24022_exit); + + MODULE_AUTHOR("Philipp Zabel"); +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/drivers/regulator/wm8350-regulator.c linux-2.6.29-rc3.owrt/drivers/regulator/wm8350-regulator.c +--- linux-2.6.29.owrt/drivers/regulator/wm8350-regulator.c 2009-05-10 22:04:38.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/drivers/regulator/wm8350-regulator.c 2009-05-10 23:48:29.000000000 +0200 +@@ -1435,7 +1435,7 @@ + struct platform_device *pdev; + int ret; + +- if (lednum >= ARRAY_SIZE(wm8350->pmic.led) || lednum < 0) { ++ if (lednum > ARRAY_SIZE(wm8350->pmic.led) || lednum < 0) { + dev_err(wm8350->dev, "Invalid LED index %d\n", lednum); + return -ENODEV; + } +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/drivers/rtc/Kconfig linux-2.6.29-rc3.owrt/drivers/rtc/Kconfig +--- linux-2.6.29.owrt/drivers/rtc/Kconfig 2009-05-10 22:04:38.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/drivers/rtc/Kconfig 2009-05-10 23:48:29.000000000 +0200 +@@ -241,12 +241,6 @@ + If you say Y here you will get support for the + watchdog timer in the ST M41T60 and M41T80 RTC chips series. + +-config RTC_DRV_DM355EVM +- tristate "TI DaVinci DM355 EVM RTC" +- depends on MFD_DM355EVM_MSP +- help +- Supports the RTC firmware in the MSP430 on the DM355 EVM. +- + config RTC_DRV_TWL92330 + boolean "TI TWL92330/Menelaus" + depends on MENELAUS +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/drivers/rtc/Makefile linux-2.6.29-rc3.owrt/drivers/rtc/Makefile +--- linux-2.6.29.owrt/drivers/rtc/Makefile 2009-05-10 22:04:38.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/drivers/rtc/Makefile 2009-05-10 23:48:29.000000000 +0200 +@@ -23,7 +23,6 @@ + obj-$(CONFIG_RTC_DRV_AU1XXX) += rtc-au1xxx.o + obj-$(CONFIG_RTC_DRV_BFIN) += rtc-bfin.o + obj-$(CONFIG_RTC_DRV_CMOS) += rtc-cmos.o +-obj-$(CONFIG_RTC_DRV_DM355EVM) += rtc-dm355evm.o + obj-$(CONFIG_RTC_DRV_DS1216) += rtc-ds1216.o + obj-$(CONFIG_RTC_DRV_DS1286) += rtc-ds1286.o + obj-$(CONFIG_RTC_DRV_DS1302) += rtc-ds1302.o +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/drivers/rtc/rtc-au1xxx.c linux-2.6.29-rc3.owrt/drivers/rtc/rtc-au1xxx.c +--- linux-2.6.29.owrt/drivers/rtc/rtc-au1xxx.c 2009-05-10 22:04:38.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/drivers/rtc/rtc-au1xxx.c 2009-05-10 23:48:29.000000000 +0200 +@@ -81,7 +81,7 @@ + if (au_readl(SYS_TOYTRIM) != 32767) { + /* wait until hardware gives access to TRIM register */ + t = 0x00100000; +- while ((au_readl(SYS_COUNTER_CNTRL) & SYS_CNTRL_T0S) && --t) ++ while ((au_readl(SYS_COUNTER_CNTRL) & SYS_CNTRL_T0S) && t--) + msleep(1); + + if (!t) { +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/drivers/rtc/rtc-dm355evm.c linux-2.6.29-rc3.owrt/drivers/rtc/rtc-dm355evm.c +--- linux-2.6.29.owrt/drivers/rtc/rtc-dm355evm.c 2009-05-10 22:04:38.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/drivers/rtc/rtc-dm355evm.c 1970-01-01 01:00:00.000000000 +0100 +@@ -1,175 +0,0 @@ +-/* +- * rtc-dm355evm.c - access battery-backed counter in MSP430 firmware +- * +- * Copyright (c) 2008 by David Brownell +- * +- * 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. +- */ +-#include <linux/kernel.h> +-#include <linux/init.h> +-#include <linux/rtc.h> +-#include <linux/platform_device.h> +- +-#include <linux/i2c/dm355evm_msp.h> +- +- +-/* +- * The MSP430 firmware on the DM355 EVM uses a watch crystal to feed +- * a 1 Hz counter. When a backup battery is supplied, that makes a +- * reasonable RTC for applications where alarms and non-NTP drift +- * compensation aren't important. +- * +- * The only real glitch is the inability to read or write all four +- * counter bytes atomically: the count may increment in the middle +- * of an operation, causing trouble when the LSB rolls over. +- * +- * This driver was tested with firmware revision A4. +- */ +-union evm_time { +- u8 bytes[4]; +- u32 value; +-}; +- +-static int dm355evm_rtc_read_time(struct device *dev, struct rtc_time *tm) +-{ +- union evm_time time; +- int status; +- int tries = 0; +- +- do { +- /* +- * Read LSB(0) to MSB(3) bytes. Defend against the counter +- * rolling over by re-reading until the value is stable, +- * and assuming the four reads take at most a few seconds. +- */ +- status = dm355evm_msp_read(DM355EVM_MSP_RTC_0); +- if (status < 0) +- return status; +- if (tries && time.bytes[0] == status) +- break; +- time.bytes[0] = status; +- +- status = dm355evm_msp_read(DM355EVM_MSP_RTC_1); +- if (status < 0) +- return status; +- if (tries && time.bytes[1] == status) +- break; +- time.bytes[1] = status; +- +- status = dm355evm_msp_read(DM355EVM_MSP_RTC_2); +- if (status < 0) +- return status; +- if (tries && time.bytes[2] == status) +- break; +- time.bytes[2] = status; +- +- status = dm355evm_msp_read(DM355EVM_MSP_RTC_3); +- if (status < 0) +- return status; +- if (tries && time.bytes[3] == status) +- break; +- time.bytes[3] = status; +- +- } while (++tries < 5); +- +- dev_dbg(dev, "read timestamp %08x\n", time.value); +- +- rtc_time_to_tm(le32_to_cpu(time.value), tm); +- return 0; +-} +- +-static int dm355evm_rtc_set_time(struct device *dev, struct rtc_time *tm) +-{ +- union evm_time time; +- unsigned long value; +- int status; +- +- rtc_tm_to_time(tm, &value); +- time.value = cpu_to_le32(value); +- +- dev_dbg(dev, "write timestamp %08x\n", time.value); +- +- /* +- * REVISIT handle non-atomic writes ... maybe just retry until +- * byte[1] sticks (no rollover)? +- */ +- status = dm355evm_msp_write(time.bytes[0], DM355EVM_MSP_RTC_0); +- if (status < 0) +- return status; +- +- status = dm355evm_msp_write(time.bytes[1], DM355EVM_MSP_RTC_1); +- if (status < 0) +- return status; +- +- status = dm355evm_msp_write(time.bytes[2], DM355EVM_MSP_RTC_2); +- if (status < 0) +- return status; +- +- status = dm355evm_msp_write(time.bytes[3], DM355EVM_MSP_RTC_3); +- if (status < 0) +- return status; +- +- return 0; +-} +- +-static struct rtc_class_ops dm355evm_rtc_ops = { +- .read_time = dm355evm_rtc_read_time, +- .set_time = dm355evm_rtc_set_time, +-}; +- +-/*----------------------------------------------------------------------*/ +- +-static int __devinit dm355evm_rtc_probe(struct platform_device *pdev) +-{ +- struct rtc_device *rtc; +- +- rtc = rtc_device_register(pdev->name, +- &pdev->dev, &dm355evm_rtc_ops, THIS_MODULE); +- if (IS_ERR(rtc)) { +- dev_err(&pdev->dev, "can't register RTC device, err %ld\n", +- PTR_ERR(rtc)); +- return PTR_ERR(rtc); +- } +- platform_set_drvdata(pdev, rtc); +- +- return 0; +-} +- +-static int __devexit dm355evm_rtc_remove(struct platform_device *pdev) +-{ +- struct rtc_device *rtc = platform_get_drvdata(pdev); +- +- rtc_device_unregister(rtc); +- platform_set_drvdata(pdev, NULL); +- return 0; +-} +- +-/* +- * I2C is used to talk to the MSP430, but this platform device is +- * exposed by an MFD driver that manages I2C communications. +- */ +-static struct platform_driver rtc_dm355evm_driver = { +- .probe = dm355evm_rtc_probe, +- .remove = __devexit_p(dm355evm_rtc_remove), +- .driver = { +- .owner = THIS_MODULE, +- .name = "rtc-dm355evm", +- }, +-}; +- +-static int __init dm355evm_rtc_init(void) +-{ +- return platform_driver_register(&rtc_dm355evm_driver); +-} +-module_init(dm355evm_rtc_init); +- +-static void __exit dm355evm_rtc_exit(void) +-{ +- platform_driver_unregister(&rtc_dm355evm_driver); +-} +-module_exit(dm355evm_rtc_exit); +- +-MODULE_LICENSE("GPL"); +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/drivers/rtc/rtc-ds1390.c linux-2.6.29-rc3.owrt/drivers/rtc/rtc-ds1390.c +--- linux-2.6.29.owrt/drivers/rtc/rtc-ds1390.c 2009-05-10 22:04:38.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/drivers/rtc/rtc-ds1390.c 2009-05-10 23:48:29.000000000 +0200 +@@ -122,6 +122,7 @@ + + static int __devinit ds1390_probe(struct spi_device *spi) + { ++ struct rtc_device *rtc; + unsigned char tmp; + struct ds1390 *chip; + int res; +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/drivers/rtc/rtc-pxa.c linux-2.6.29-rc3.owrt/drivers/rtc/rtc-pxa.c +--- linux-2.6.29.owrt/drivers/rtc/rtc-pxa.c 2009-05-10 22:04:38.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/drivers/rtc/rtc-pxa.c 2009-05-10 23:48:29.000000000 +0200 +@@ -485,7 +485,7 @@ + module_init(pxa_rtc_init); + module_exit(pxa_rtc_exit); + +-MODULE_AUTHOR("Robert Jarzmik <robert.jarzmik@free.fr>"); ++MODULE_AUTHOR("Robert Jarzmik"); + MODULE_DESCRIPTION("PXA27x/PXA3xx Realtime Clock Driver (RTC)"); + MODULE_LICENSE("GPL"); + MODULE_ALIAS("platform:pxa-rtc"); +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/drivers/s390/block/dasd.c linux-2.6.29-rc3.owrt/drivers/s390/block/dasd.c +--- linux-2.6.29.owrt/drivers/s390/block/dasd.c 2009-05-10 22:04:38.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/drivers/s390/block/dasd.c 2009-05-10 23:48:29.000000000 +0200 +@@ -57,8 +57,6 @@ + static void dasd_block_tasklet(struct dasd_block *); + static void do_kick_device(struct work_struct *); + static void dasd_return_cqr_cb(struct dasd_ccw_req *, void *); +-static void dasd_device_timeout(unsigned long); +-static void dasd_block_timeout(unsigned long); + + /* + * SECTION: Operations on the device structure. +@@ -101,8 +99,6 @@ + (unsigned long) device); + INIT_LIST_HEAD(&device->ccw_queue); + init_timer(&device->timer); +- device->timer.function = dasd_device_timeout; +- device->timer.data = (unsigned long) device; + INIT_WORK(&device->kick_work, do_kick_device); + device->state = DASD_STATE_NEW; + device->target = DASD_STATE_NEW; +@@ -142,8 +138,6 @@ + INIT_LIST_HEAD(&block->ccw_queue); + spin_lock_init(&block->queue_lock); + init_timer(&block->timer); +- block->timer.function = dasd_block_timeout; +- block->timer.data = (unsigned long) block; + + return block; + } +@@ -921,10 +915,19 @@ + */ + void dasd_device_set_timer(struct dasd_device *device, int expires) + { +- if (expires == 0) +- del_timer(&device->timer); +- else +- mod_timer(&device->timer, jiffies + expires); ++ if (expires == 0) { ++ if (timer_pending(&device->timer)) ++ del_timer(&device->timer); ++ return; ++ } ++ if (timer_pending(&device->timer)) { ++ if (mod_timer(&device->timer, jiffies + expires)) ++ return; ++ } ++ device->timer.function = dasd_device_timeout; ++ device->timer.data = (unsigned long) device; ++ device->timer.expires = jiffies + expires; ++ add_timer(&device->timer); + } + + /* +@@ -932,7 +935,8 @@ + */ + void dasd_device_clear_timer(struct dasd_device *device) + { +- del_timer(&device->timer); ++ if (timer_pending(&device->timer)) ++ del_timer(&device->timer); + } + + static void dasd_handle_killed_request(struct ccw_device *cdev, +@@ -1582,10 +1586,19 @@ + */ + void dasd_block_set_timer(struct dasd_block *block, int expires) + { +- if (expires == 0) +- del_timer(&block->timer); +- else +- mod_timer(&block->timer, jiffies + expires); ++ if (expires == 0) { ++ if (timer_pending(&block->timer)) ++ del_timer(&block->timer); ++ return; ++ } ++ if (timer_pending(&block->timer)) { ++ if (mod_timer(&block->timer, jiffies + expires)) ++ return; ++ } ++ block->timer.function = dasd_block_timeout; ++ block->timer.data = (unsigned long) block; ++ block->timer.expires = jiffies + expires; ++ add_timer(&block->timer); + } + + /* +@@ -1593,7 +1606,8 @@ + */ + void dasd_block_clear_timer(struct dasd_block *block) + { +- del_timer(&block->timer); ++ if (timer_pending(&block->timer)) ++ del_timer(&block->timer); + } + + /* +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/drivers/s390/block/dasd_devmap.c linux-2.6.29-rc3.owrt/drivers/s390/block/dasd_devmap.c +--- linux-2.6.29.owrt/drivers/s390/block/dasd_devmap.c 2009-05-10 22:04:38.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/drivers/s390/block/dasd_devmap.c 2009-05-10 23:48:29.000000000 +0200 +@@ -677,7 +677,7 @@ + struct dasd_devmap *devmap; + int ff_flag; + +- devmap = dasd_find_busid(dev_name(dev)); ++ devmap = dasd_find_busid(dev->bus_id); + if (!IS_ERR(devmap)) + ff_flag = (devmap->features & DASD_FEATURE_FAILFAST) != 0; + else +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/drivers/s390/char/sclp.c linux-2.6.29-rc3.owrt/drivers/s390/char/sclp.c +--- linux-2.6.29.owrt/drivers/s390/char/sclp.c 2009-05-10 22:04:38.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/drivers/s390/char/sclp.c 2009-05-10 23:48:29.000000000 +0200 +@@ -280,11 +280,8 @@ + rc = 0; + for (offset = sizeof(struct sccb_header); offset < sccb->length; + offset += evbuf->length) { +- evbuf = (struct evbuf_header *) ((addr_t) sccb + offset); +- /* Check for malformed hardware response */ +- if (evbuf->length == 0) +- break; + /* Search for event handler */ ++ evbuf = (struct evbuf_header *) ((addr_t) sccb + offset); + reg = NULL; + list_for_each(l, &sclp_reg_list) { + reg = list_entry(l, struct sclp_register, list); +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/drivers/s390/char/sclp_cmd.c linux-2.6.29-rc3.owrt/drivers/s390/char/sclp_cmd.c +--- linux-2.6.29.owrt/drivers/s390/char/sclp_cmd.c 2009-05-10 22:04:38.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/drivers/s390/char/sclp_cmd.c 2009-05-10 23:48:29.000000000 +0200 +@@ -19,7 +19,6 @@ + #include <linux/memory.h> + #include <asm/chpid.h> + #include <asm/sclp.h> +-#include <asm/setup.h> + + #include "sclp.h" + +@@ -475,10 +474,6 @@ + goto skip_add; + if (start + size > VMEM_MAX_PHYS) + size = VMEM_MAX_PHYS - start; +- if (memory_end_set && (start >= memory_end)) +- goto skip_add; +- if (memory_end_set && (start + size > memory_end)) +- size = memory_end - start; + add_memory(0, start, size); + skip_add: + first_rn = rn; +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/drivers/sbus/char/bbc_i2c.c linux-2.6.29-rc3.owrt/drivers/sbus/char/bbc_i2c.c +--- linux-2.6.29.owrt/drivers/sbus/char/bbc_i2c.c 2009-05-10 22:04:38.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/drivers/sbus/char/bbc_i2c.c 2009-05-10 23:48:29.000000000 +0200 +@@ -129,7 +129,7 @@ + bp->waiting = 1; + add_wait_queue(&bp->wq, &wait); + while (limit-- > 0) { +- long val; ++ unsigned long val; + + val = wait_event_interruptible_timeout( + bp->wq, +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/drivers/sbus/char/jsflash.c linux-2.6.29-rc3.owrt/drivers/sbus/char/jsflash.c +--- linux-2.6.29.owrt/drivers/sbus/char/jsflash.c 2009-05-10 22:04:38.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/drivers/sbus/char/jsflash.c 2009-05-10 23:48:29.000000000 +0200 +@@ -38,6 +38,9 @@ + #include <linux/string.h> + #include <linux/genhd.h> + #include <linux/blkdev.h> ++ ++#define MAJOR_NR JSFD_MAJOR ++ + #include <asm/uaccess.h> + #include <asm/pgtable.h> + #include <asm/io.h> +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/drivers/sbus/char/openprom.c linux-2.6.29-rc3.owrt/drivers/sbus/char/openprom.c +--- linux-2.6.29.owrt/drivers/sbus/char/openprom.c 2009-05-10 22:04:38.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/drivers/sbus/char/openprom.c 2009-05-10 23:48:29.000000000 +0200 +@@ -51,7 +51,6 @@ + MODULE_DESCRIPTION("OPENPROM Configuration Driver"); + MODULE_LICENSE("GPL"); + MODULE_VERSION("1.0"); +-MODULE_ALIAS_MISCDEV(SUN_OPENPROM_MINOR); + + /* Private data kept by the driver for each descriptor. */ + typedef struct openprom_private_data +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/drivers/scsi/cxgb3i/cxgb3i_ddp.c linux-2.6.29-rc3.owrt/drivers/scsi/cxgb3i/cxgb3i_ddp.c +--- linux-2.6.29.owrt/drivers/scsi/cxgb3i/cxgb3i_ddp.c 2009-05-10 22:04:39.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/drivers/scsi/cxgb3i/cxgb3i_ddp.c 2009-05-10 23:48:29.000000000 +0200 +@@ -639,11 +639,10 @@ + write_unlock(&cxgb3i_ddp_rwlock); + + ddp_log_info("nppods %u (0x%x ~ 0x%x), bits %u, mask 0x%x,0x%x " +- "pkt %u/%u, %u/%u.\n", ++ "pkt %u,%u.\n", + ppmax, ddp->llimit, ddp->ulimit, ddp->idx_bits, + ddp->idx_mask, ddp->rsvd_tag_mask, +- ddp->max_txsz, uinfo.max_txsz, +- ddp->max_rxsz, uinfo.max_rxsz); ++ ddp->max_txsz, ddp->max_rxsz); + return 0; + + free_ddp_map: +@@ -655,8 +654,8 @@ + * cxgb3i_adapter_ddp_init - initialize the adapter's ddp resource + * @tdev: t3cdev adapter + * @tformat: tag format +- * @txsz: max tx pdu payload size, filled in by this func. +- * @rxsz: max rx pdu payload size, filled in by this func. ++ * @txsz: max tx pkt size, filled in by this func. ++ * @rxsz: max rx pkt size, filled in by this func. + * initialize the ddp pagepod manager for a given adapter if needed and + * setup the tag format for a given iscsi entity + */ +@@ -686,12 +685,10 @@ + tformat->sw_bits, tformat->rsvd_bits, + tformat->rsvd_shift, tformat->rsvd_mask); + +- *txsz = min_t(unsigned int, ULP2_MAX_PDU_PAYLOAD, +- ddp->max_txsz - ISCSI_PDU_NONPAYLOAD_LEN); +- *rxsz = min_t(unsigned int, ULP2_MAX_PDU_PAYLOAD, +- ddp->max_rxsz - ISCSI_PDU_NONPAYLOAD_LEN); +- ddp_log_info("max payload size: %u/%u, %u/%u.\n", +- *txsz, ddp->max_txsz, *rxsz, ddp->max_rxsz); ++ *txsz = ddp->max_txsz; ++ *rxsz = ddp->max_rxsz; ++ ddp_log_info("ddp max pkt size: %u, %u.\n", ++ ddp->max_txsz, ddp->max_rxsz); + return 0; + } + EXPORT_SYMBOL_GPL(cxgb3i_adapter_ddp_init); +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/drivers/scsi/cxgb3i/cxgb3i_ddp.h linux-2.6.29-rc3.owrt/drivers/scsi/cxgb3i/cxgb3i_ddp.h +--- linux-2.6.29.owrt/drivers/scsi/cxgb3i/cxgb3i_ddp.h 2009-05-10 22:04:39.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/drivers/scsi/cxgb3i/cxgb3i_ddp.h 2009-05-10 23:48:29.000000000 +0200 +@@ -13,8 +13,6 @@ + #ifndef __CXGB3I_ULP2_DDP_H__ + #define __CXGB3I_ULP2_DDP_H__ + +-#include <linux/vmalloc.h> +- + /** + * struct cxgb3i_tag_format - cxgb3i ulp tag format for an iscsi entity + * +@@ -87,9 +85,8 @@ + struct sk_buff **gl_skb; + }; + +-#define ISCSI_PDU_NONPAYLOAD_LEN 312 /* bhs(48) + ahs(256) + digest(8) */ + #define ULP2_MAX_PKT_SIZE 16224 +-#define ULP2_MAX_PDU_PAYLOAD (ULP2_MAX_PKT_SIZE - ISCSI_PDU_NONPAYLOAD_LEN) ++#define ULP2_MAX_PDU_PAYLOAD (ULP2_MAX_PKT_SIZE - ISCSI_PDU_NONPAYLOAD_MAX) + #define PPOD_PAGES_MAX 4 + #define PPOD_PAGES_SHIFT 2 /* 4 pages per pod */ + +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/drivers/scsi/cxgb3i/cxgb3i.h linux-2.6.29-rc3.owrt/drivers/scsi/cxgb3i/cxgb3i.h +--- linux-2.6.29.owrt/drivers/scsi/cxgb3i/cxgb3i.h 2009-05-10 22:04:39.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/drivers/scsi/cxgb3i/cxgb3i.h 2009-05-10 23:48:29.000000000 +0200 +@@ -20,7 +20,6 @@ + #include <linux/list.h> + #include <linux/netdevice.h> + #include <linux/scatterlist.h> +-#include <linux/skbuff.h> + #include <scsi/libiscsi_tcp.h> + + /* from cxgb3 LLD */ +@@ -114,26 +113,6 @@ + struct cxgb3i_conn *cconn; + }; + +-/** +- * struct cxgb3i_task_data - private iscsi task data +- * +- * @nr_frags: # of coalesced page frags (from scsi sgl) +- * @frags: coalesced page frags (from scsi sgl) +- * @skb: tx pdu skb +- * @offset: data offset for the next pdu +- * @count: max. possible pdu payload +- * @sgoffset: offset to the first sg entry for a given offset +- */ +-#define MAX_PDU_FRAGS ((ULP2_MAX_PDU_PAYLOAD + 512 - 1) / 512) +-struct cxgb3i_task_data { +- unsigned short nr_frags; +- skb_frag_t frags[MAX_PDU_FRAGS]; +- struct sk_buff *skb; +- unsigned int offset; +- unsigned int count; +- unsigned int sgoffset; +-}; +- + int cxgb3i_iscsi_init(void); + void cxgb3i_iscsi_cleanup(void); + +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/drivers/scsi/cxgb3i/cxgb3i_init.c linux-2.6.29-rc3.owrt/drivers/scsi/cxgb3i/cxgb3i_init.c +--- linux-2.6.29.owrt/drivers/scsi/cxgb3i/cxgb3i_init.c 2009-05-10 22:04:39.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/drivers/scsi/cxgb3i/cxgb3i_init.c 2009-05-10 23:48:29.000000000 +0200 +@@ -12,8 +12,8 @@ + #include "cxgb3i.h" + + #define DRV_MODULE_NAME "cxgb3i" +-#define DRV_MODULE_VERSION "1.0.1" +-#define DRV_MODULE_RELDATE "Jan. 2009" ++#define DRV_MODULE_VERSION "1.0.0" ++#define DRV_MODULE_RELDATE "Jun. 1, 2008" + + static char version[] = + "Chelsio S3xx iSCSI Driver " DRV_MODULE_NAME +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/drivers/scsi/cxgb3i/cxgb3i_iscsi.c linux-2.6.29-rc3.owrt/drivers/scsi/cxgb3i/cxgb3i_iscsi.c +--- linux-2.6.29.owrt/drivers/scsi/cxgb3i/cxgb3i_iscsi.c 2009-05-10 22:04:39.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/drivers/scsi/cxgb3i/cxgb3i_iscsi.c 2009-05-10 23:48:29.000000000 +0200 +@@ -364,8 +364,7 @@ + + cls_session = iscsi_session_setup(&cxgb3i_iscsi_transport, shost, + cmds_max, +- sizeof(struct iscsi_tcp_task) + +- sizeof(struct cxgb3i_task_data), ++ sizeof(struct iscsi_tcp_task), + initial_cmdsn, ISCSI_MAX_TARGET); + if (!cls_session) + return NULL; +@@ -403,15 +402,17 @@ + { + struct iscsi_tcp_conn *tcp_conn = conn->dd_data; + struct cxgb3i_conn *cconn = tcp_conn->dd_data; +- unsigned int max = max(512 * MAX_SKB_FRAGS, SKB_TX_HEADROOM); ++ unsigned int max = min_t(unsigned int, ULP2_MAX_PDU_PAYLOAD, ++ cconn->hba->snic->tx_max_size - ++ ISCSI_PDU_NONPAYLOAD_MAX); + +- max = min(cconn->hba->snic->tx_max_size, max); + if (conn->max_xmit_dlength) +- conn->max_xmit_dlength = min(conn->max_xmit_dlength, max); ++ conn->max_xmit_dlength = min_t(unsigned int, ++ conn->max_xmit_dlength, max); + else + conn->max_xmit_dlength = max; + align_pdu_size(conn->max_xmit_dlength); +- cxgb3i_api_debug("conn 0x%p, max xmit %u.\n", ++ cxgb3i_log_info("conn 0x%p, max xmit %u.\n", + conn, conn->max_xmit_dlength); + return 0; + } +@@ -426,7 +427,9 @@ + { + struct iscsi_tcp_conn *tcp_conn = conn->dd_data; + struct cxgb3i_conn *cconn = tcp_conn->dd_data; +- unsigned int max = cconn->hba->snic->rx_max_size; ++ unsigned int max = min_t(unsigned int, ULP2_MAX_PDU_PAYLOAD, ++ cconn->hba->snic->rx_max_size - ++ ISCSI_PDU_NONPAYLOAD_MAX); + + align_pdu_size(max); + if (conn->max_recv_dlength) { +@@ -436,7 +439,8 @@ + conn->max_recv_dlength, max); + return -EINVAL; + } +- conn->max_recv_dlength = min(conn->max_recv_dlength, max); ++ conn->max_recv_dlength = min_t(unsigned int, ++ conn->max_recv_dlength, max); + align_pdu_size(conn->max_recv_dlength); + } else + conn->max_recv_dlength = max; +@@ -840,7 +844,7 @@ + .proc_name = "cxgb3i", + .queuecommand = iscsi_queuecommand, + .change_queue_depth = iscsi_change_queue_depth, +- .can_queue = CXGB3I_SCSI_QDEPTH_DFLT - 1, ++ .can_queue = 128 * (ISCSI_DEF_XMIT_CMDS_MAX - 1), + .sg_tablesize = SG_ALL, + .max_sectors = 0xFFFF, + .cmd_per_lun = ISCSI_DEF_CMD_PER_LUN, +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/drivers/scsi/cxgb3i/cxgb3i_offload.c linux-2.6.29-rc3.owrt/drivers/scsi/cxgb3i/cxgb3i_offload.c +--- linux-2.6.29.owrt/drivers/scsi/cxgb3i/cxgb3i_offload.c 2009-05-10 22:04:39.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/drivers/scsi/cxgb3i/cxgb3i_offload.c 2009-05-10 23:48:29.000000000 +0200 +@@ -23,19 +23,19 @@ + #include "cxgb3i_ddp.h" + + #ifdef __DEBUG_C3CN_CONN__ +-#define c3cn_conn_debug cxgb3i_log_debug ++#define c3cn_conn_debug cxgb3i_log_info + #else + #define c3cn_conn_debug(fmt...) + #endif + + #ifdef __DEBUG_C3CN_TX__ +-#define c3cn_tx_debug cxgb3i_log_debug ++#define c3cn_tx_debug cxgb3i_log_debug + #else + #define c3cn_tx_debug(fmt...) + #endif + + #ifdef __DEBUG_C3CN_RX__ +-#define c3cn_rx_debug cxgb3i_log_debug ++#define c3cn_rx_debug cxgb3i_log_debug + #else + #define c3cn_rx_debug(fmt...) + #endif +@@ -47,9 +47,9 @@ + module_param(cxgb3_rcv_win, int, 0644); + MODULE_PARM_DESC(cxgb3_rcv_win, "TCP receive window in bytes (default=256KB)"); + +-static int cxgb3_snd_win = 128 * 1024; ++static int cxgb3_snd_win = 64 * 1024; + module_param(cxgb3_snd_win, int, 0644); +-MODULE_PARM_DESC(cxgb3_snd_win, "TCP send window in bytes (default=128KB)"); ++MODULE_PARM_DESC(cxgb3_snd_win, "TCP send window in bytes (default=64KB)"); + + static int cxgb3_rx_credit_thres = 10 * 1024; + module_param(cxgb3_rx_credit_thres, int, 0644); +@@ -301,8 +301,8 @@ + static void skb_entail(struct s3_conn *c3cn, struct sk_buff *skb, + int flags) + { +- skb_tcp_seq(skb) = c3cn->write_seq; +- skb_flags(skb) = flags; ++ CXGB3_SKB_CB(skb)->seq = c3cn->write_seq; ++ CXGB3_SKB_CB(skb)->flags = flags; + __skb_queue_tail(&c3cn->write_queue, skb); + } + +@@ -457,9 +457,12 @@ + * The number of WRs needed for an skb depends on the number of fragments + * in the skb and whether it has any payload in its main body. This maps the + * length of the gather list represented by an skb into the # of necessary WRs. +- * The extra two fragments are for iscsi bhs and payload padding. ++ * ++ * The max. length of an skb is controlled by the max pdu size which is ~16K. ++ * Also, assume the min. fragment length is the sector size (512), then add ++ * extra fragment counts for iscsi bhs and payload padding. + */ +-#define SKB_WR_LIST_SIZE (MAX_SKB_FRAGS + 2) ++#define SKB_WR_LIST_SIZE (16384/512 + 3) + static unsigned int skb_wrs[SKB_WR_LIST_SIZE] __read_mostly; + + static void s3_init_wr_tab(unsigned int wr_len) +@@ -482,7 +485,7 @@ + + static inline void reset_wr_list(struct s3_conn *c3cn) + { +- c3cn->wr_pending_head = c3cn->wr_pending_tail = NULL; ++ c3cn->wr_pending_head = NULL; + } + + /* +@@ -493,7 +496,7 @@ + static inline void enqueue_wr(struct s3_conn *c3cn, + struct sk_buff *skb) + { +- skb_tx_wr_next(skb) = NULL; ++ skb_wr_data(skb) = NULL; + + /* + * We want to take an extra reference since both us and the driver +@@ -506,22 +509,10 @@ + if (!c3cn->wr_pending_head) + c3cn->wr_pending_head = skb; + else +- skb_tx_wr_next(c3cn->wr_pending_tail) = skb; ++ skb_wr_data(skb) = skb; + c3cn->wr_pending_tail = skb; + } + +-static int count_pending_wrs(struct s3_conn *c3cn) +-{ +- int n = 0; +- const struct sk_buff *skb = c3cn->wr_pending_head; +- +- while (skb) { +- n += skb->csum; +- skb = skb_tx_wr_next(skb); +- } +- return n; +-} +- + static inline struct sk_buff *peek_wr(const struct s3_conn *c3cn) + { + return c3cn->wr_pending_head; +@@ -538,8 +529,8 @@ + + if (likely(skb)) { + /* Don't bother clearing the tail */ +- c3cn->wr_pending_head = skb_tx_wr_next(skb); +- skb_tx_wr_next(skb) = NULL; ++ c3cn->wr_pending_head = skb_wr_data(skb); ++ skb_wr_data(skb) = NULL; + } + return skb; + } +@@ -552,14 +543,13 @@ + } + + static inline void make_tx_data_wr(struct s3_conn *c3cn, struct sk_buff *skb, +- int len, int req_completion) ++ int len) + { + struct tx_data_wr *req; + + skb_reset_transport_header(skb); + req = (struct tx_data_wr *)__skb_push(skb, sizeof(*req)); +- req->wr_hi = htonl(V_WR_OP(FW_WROPCODE_OFLD_TX_DATA) | +- (req_completion ? F_WR_COMPL : 0)); ++ req->wr_hi = htonl(V_WR_OP(FW_WROPCODE_OFLD_TX_DATA)); + req->wr_lo = htonl(V_WR_TID(c3cn->tid)); + req->sndseq = htonl(c3cn->snd_nxt); + /* len includes the length of any HW ULP additions */ +@@ -602,7 +592,7 @@ + + if (unlikely(c3cn->state == C3CN_STATE_CONNECTING || + c3cn->state == C3CN_STATE_CLOSE_WAIT_1 || +- c3cn->state >= C3CN_STATE_ABORTING)) { ++ c3cn->state == C3CN_STATE_ABORTING)) { + c3cn_tx_debug("c3cn 0x%p, in closing state %u.\n", + c3cn, c3cn->state); + return 0; +@@ -625,7 +615,7 @@ + if (c3cn->wr_avail < wrs_needed) { + c3cn_tx_debug("c3cn 0x%p, skb len %u/%u, frag %u, " + "wr %d < %u.\n", +- c3cn, skb->len, skb->data_len, frags, ++ c3cn, skb->len, skb->datalen, frags, + wrs_needed, c3cn->wr_avail); + break; + } +@@ -637,24 +627,20 @@ + c3cn->wr_unacked += wrs_needed; + enqueue_wr(c3cn, skb); + +- c3cn_tx_debug("c3cn 0x%p, enqueue, skb len %u/%u, frag %u, " +- "wr %d, left %u, unack %u.\n", +- c3cn, skb->len, skb->data_len, frags, +- wrs_needed, c3cn->wr_avail, c3cn->wr_unacked); +- ++ if (likely(CXGB3_SKB_CB(skb)->flags & C3CB_FLAG_NEED_HDR)) { ++ len += ulp_extra_len(skb); ++ make_tx_data_wr(c3cn, skb, len); ++ c3cn->snd_nxt += len; ++ if ((req_completion ++ && c3cn->wr_unacked == wrs_needed) ++ || (CXGB3_SKB_CB(skb)->flags & C3CB_FLAG_COMPL) ++ || c3cn->wr_unacked >= c3cn->wr_max / 2) { ++ struct work_request_hdr *wr = cplhdr(skb); + +- if (likely(skb_flags(skb) & C3CB_FLAG_NEED_HDR)) { +- if ((req_completion && +- c3cn->wr_unacked == wrs_needed) || +- (skb_flags(skb) & C3CB_FLAG_COMPL) || +- c3cn->wr_unacked >= c3cn->wr_max / 2) { +- req_completion = 1; ++ wr->wr_hi |= htonl(F_WR_COMPL); + c3cn->wr_unacked = 0; + } +- len += ulp_extra_len(skb); +- make_tx_data_wr(c3cn, skb, len, req_completion); +- c3cn->snd_nxt += len; +- skb_flags(skb) &= ~C3CB_FLAG_NEED_HDR; ++ CXGB3_SKB_CB(skb)->flags &= ~C3CB_FLAG_NEED_HDR; + } + + total_size += skb->truesize; +@@ -749,11 +735,8 @@ + if (unlikely(c3cn_flag(c3cn, C3CN_ACTIVE_CLOSE_NEEDED))) + /* upper layer has requested closing */ + send_abort_req(c3cn); +- else { +- if (skb_queue_len(&c3cn->write_queue)) +- c3cn_push_tx_frames(c3cn, 1); ++ else if (c3cn_push_tx_frames(c3cn, 1)) + cxgb3i_conn_tx_open(c3cn); +- } + } + + static int do_act_establish(struct t3cdev *cdev, struct sk_buff *skb, +@@ -1099,8 +1082,8 @@ + return; + } + +- skb_tcp_seq(skb) = ntohl(hdr_cpl->seq); +- skb_flags(skb) = 0; ++ CXGB3_SKB_CB(skb)->seq = ntohl(hdr_cpl->seq); ++ CXGB3_SKB_CB(skb)->flags = 0; + + skb_reset_transport_header(skb); + __skb_pull(skb, sizeof(struct cpl_iscsi_hdr)); +@@ -1120,12 +1103,12 @@ + goto abort_conn; + + skb_ulp_mode(skb) = ULP2_FLAG_DATA_READY; +- skb_rx_pdulen(skb) = ntohs(ddp_cpl.len); +- skb_rx_ddigest(skb) = ntohl(ddp_cpl.ulp_crc); ++ skb_ulp_pdulen(skb) = ntohs(ddp_cpl.len); ++ skb_ulp_ddigest(skb) = ntohl(ddp_cpl.ulp_crc); + status = ntohl(ddp_cpl.ddp_status); + + c3cn_rx_debug("rx skb 0x%p, len %u, pdulen %u, ddp status 0x%x.\n", +- skb, skb->len, skb_rx_pdulen(skb), status); ++ skb, skb->len, skb_ulp_pdulen(skb), status); + + if (status & (1 << RX_DDP_STATUS_HCRC_SHIFT)) + skb_ulp_mode(skb) |= ULP2_FLAG_HCRC_ERROR; +@@ -1143,7 +1126,7 @@ + } else if (status & (1 << RX_DDP_STATUS_DDP_SHIFT)) + skb_ulp_mode(skb) |= ULP2_FLAG_DATA_DDPED; + +- c3cn->rcv_nxt = ntohl(ddp_cpl.seq) + skb_rx_pdulen(skb); ++ c3cn->rcv_nxt = ntohl(ddp_cpl.seq) + skb_ulp_pdulen(skb); + __pskb_trim(skb, len); + __skb_queue_tail(&c3cn->receive_queue, skb); + cxgb3i_conn_pdu_ready(c3cn); +@@ -1168,27 +1151,12 @@ + * Process an acknowledgment of WR completion. Advance snd_una and send the + * next batch of work requests from the write queue. + */ +-static void check_wr_invariants(struct s3_conn *c3cn) +-{ +- int pending = count_pending_wrs(c3cn); +- +- if (unlikely(c3cn->wr_avail + pending != c3cn->wr_max)) +- cxgb3i_log_error("TID %u: credit imbalance: avail %u, " +- "pending %u, total should be %u\n", +- c3cn->tid, c3cn->wr_avail, pending, +- c3cn->wr_max); +-} +- + static void process_wr_ack(struct s3_conn *c3cn, struct sk_buff *skb) + { + struct cpl_wr_ack *hdr = cplhdr(skb); + unsigned int credits = ntohs(hdr->credits); + u32 snd_una = ntohl(hdr->snd_una); + +- c3cn_tx_debug("%u WR credits, avail %u, unack %u, TID %u, state %u.\n", +- credits, c3cn->wr_avail, c3cn->wr_unacked, +- c3cn->tid, c3cn->state); +- + c3cn->wr_avail += credits; + if (c3cn->wr_unacked > c3cn->wr_max - c3cn->wr_avail) + c3cn->wr_unacked = c3cn->wr_max - c3cn->wr_avail; +@@ -1203,17 +1171,6 @@ + break; + } + if (unlikely(credits < p->csum)) { +- struct tx_data_wr *w = cplhdr(p); +- cxgb3i_log_error("TID %u got %u WR credits need %u, " +- "len %u, main body %u, frags %u, " +- "seq # %u, ACK una %u, ACK nxt %u, " +- "WR_AVAIL %u, WRs pending %u\n", +- c3cn->tid, credits, p->csum, p->len, +- p->len - p->data_len, +- skb_shinfo(p)->nr_frags, +- ntohl(w->sndseq), snd_una, +- ntohl(hdr->snd_nxt), c3cn->wr_avail, +- count_pending_wrs(c3cn) - credits); + p->csum -= credits; + break; + } else { +@@ -1223,24 +1180,15 @@ + } + } + +- check_wr_invariants(c3cn); +- +- if (unlikely(before(snd_una, c3cn->snd_una))) { +- cxgb3i_log_error("TID %u, unexpected sequence # %u in WR_ACK " +- "snd_una %u\n", +- c3cn->tid, snd_una, c3cn->snd_una); ++ if (unlikely(before(snd_una, c3cn->snd_una))) + goto out_free; +- } + + if (c3cn->snd_una != snd_una) { + c3cn->snd_una = snd_una; + dst_confirm(c3cn->dst_cache); + } + +- if (skb_queue_len(&c3cn->write_queue)) { +- if (c3cn_push_tx_frames(c3cn, 0)) +- cxgb3i_conn_tx_open(c3cn); +- } else ++ if (skb_queue_len(&c3cn->write_queue) && c3cn_push_tx_frames(c3cn, 0)) + cxgb3i_conn_tx_open(c3cn); + out_free: + __kfree_skb(skb); +@@ -1504,7 +1452,7 @@ + struct dst_entry *dst) + { + BUG_ON(c3cn->cdev != cdev); +- c3cn->wr_max = c3cn->wr_avail = T3C_DATA(cdev)->max_wrs - 1; ++ c3cn->wr_max = c3cn->wr_avail = T3C_DATA(cdev)->max_wrs; + c3cn->wr_unacked = 0; + c3cn->mss_idx = select_mss(c3cn, dst_mtu(dst)); + +@@ -1723,17 +1671,9 @@ + goto out_err; + } + ++ err = -EPIPE; + if (c3cn->err) { + c3cn_tx_debug("c3cn 0x%p, err %d.\n", c3cn, c3cn->err); +- err = -EPIPE; +- goto out_err; +- } +- +- if (c3cn->write_seq - c3cn->snd_una >= cxgb3_snd_win) { +- c3cn_tx_debug("c3cn 0x%p, snd %u - %u > %u.\n", +- c3cn, c3cn->write_seq, c3cn->snd_una, +- cxgb3_snd_win); +- err = -EAGAIN; + goto out_err; + } + +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/drivers/scsi/cxgb3i/cxgb3i_offload.h linux-2.6.29-rc3.owrt/drivers/scsi/cxgb3i/cxgb3i_offload.h +--- linux-2.6.29.owrt/drivers/scsi/cxgb3i/cxgb3i_offload.h 2009-05-10 22:04:39.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/drivers/scsi/cxgb3i/cxgb3i_offload.h 2009-05-10 23:48:29.000000000 +0200 +@@ -178,33 +178,25 @@ + * @flag: see C3CB_FLAG_* below + * @ulp_mode: ULP mode/submode of sk_buff + * @seq: tcp sequence number ++ * @ddigest: pdu data digest ++ * @pdulen: recovered pdu length ++ * @wr_data: scratch area for tx wr + */ +-struct cxgb3_skb_rx_cb { +- __u32 ddigest; /* data digest */ +- __u32 pdulen; /* recovered pdu length */ +-}; +- +-struct cxgb3_skb_tx_cb { +- struct sk_buff *wr_next; /* next wr */ +-}; +- + struct cxgb3_skb_cb { + __u8 flags; + __u8 ulp_mode; + __u32 seq; +- union { +- struct cxgb3_skb_rx_cb rx; +- struct cxgb3_skb_tx_cb tx; +- }; ++ __u32 ddigest; ++ __u32 pdulen; ++ struct sk_buff *wr_data; + }; + + #define CXGB3_SKB_CB(skb) ((struct cxgb3_skb_cb *)&((skb)->cb[0])) +-#define skb_flags(skb) (CXGB3_SKB_CB(skb)->flags) ++ + #define skb_ulp_mode(skb) (CXGB3_SKB_CB(skb)->ulp_mode) +-#define skb_tcp_seq(skb) (CXGB3_SKB_CB(skb)->seq) +-#define skb_rx_ddigest(skb) (CXGB3_SKB_CB(skb)->rx.ddigest) +-#define skb_rx_pdulen(skb) (CXGB3_SKB_CB(skb)->rx.pdulen) +-#define skb_tx_wr_next(skb) (CXGB3_SKB_CB(skb)->tx.wr_next) ++#define skb_ulp_ddigest(skb) (CXGB3_SKB_CB(skb)->ddigest) ++#define skb_ulp_pdulen(skb) (CXGB3_SKB_CB(skb)->pdulen) ++#define skb_wr_data(skb) (CXGB3_SKB_CB(skb)->wr_data) + + enum c3cb_flags { + C3CB_FLAG_NEED_HDR = 1 << 0, /* packet needs a TX_DATA_WR header */ +@@ -225,7 +217,6 @@ + /* for TX: a skb must have a headroom of at least TX_HEADER_LEN bytes */ + #define TX_HEADER_LEN \ + (sizeof(struct tx_data_wr) + sizeof(struct sge_opaque_hdr)) +-#define SKB_TX_HEADROOM SKB_MAX_HEAD(TX_HEADER_LEN) + + /* + * get and set private ip for iscsi traffic +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/drivers/scsi/cxgb3i/cxgb3i_pdu.c linux-2.6.29-rc3.owrt/drivers/scsi/cxgb3i/cxgb3i_pdu.c +--- linux-2.6.29.owrt/drivers/scsi/cxgb3i/cxgb3i_pdu.c 2009-05-10 22:04:39.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/drivers/scsi/cxgb3i/cxgb3i_pdu.c 2009-05-10 23:48:29.000000000 +0200 +@@ -32,10 +32,6 @@ + #define cxgb3i_tx_debug(fmt...) + #endif + +-/* always allocate rooms for AHS */ +-#define SKB_TX_PDU_HEADER_LEN \ +- (sizeof(struct iscsi_hdr) + ISCSI_MAX_AHS_SIZE) +-static unsigned int skb_extra_headroom; + static struct page *pad_page; + + /* +@@ -150,13 +146,12 @@ + + void cxgb3i_conn_cleanup_task(struct iscsi_task *task) + { +- struct cxgb3i_task_data *tdata = task->dd_data + +- sizeof(struct iscsi_tcp_task); ++ struct iscsi_tcp_task *tcp_task = task->dd_data; + + /* never reached the xmit task callout */ +- if (tdata->skb) +- __kfree_skb(tdata->skb); +- memset(tdata, 0, sizeof(struct cxgb3i_task_data)); ++ if (tcp_task->dd_data) ++ kfree_skb(tcp_task->dd_data); ++ tcp_task->dd_data = NULL; + + /* MNC - Do we need a check in case this is called but + * cxgb3i_conn_alloc_pdu has never been called on the task */ +@@ -164,102 +159,28 @@ + iscsi_tcp_cleanup_task(task); + } + +-static int sgl_seek_offset(struct scatterlist *sgl, unsigned int sgcnt, +- unsigned int offset, unsigned int *off, +- struct scatterlist **sgp) +-{ +- int i; +- struct scatterlist *sg; +- +- for_each_sg(sgl, sg, sgcnt, i) { +- if (offset < sg->length) { +- *off = offset; +- *sgp = sg; +- return 0; +- } +- offset -= sg->length; +- } +- return -EFAULT; +-} +- +-static int sgl_read_to_frags(struct scatterlist *sg, unsigned int sgoffset, +- unsigned int dlen, skb_frag_t *frags, +- int frag_max) +-{ +- unsigned int datalen = dlen; +- unsigned int sglen = sg->length - sgoffset; +- struct page *page = sg_page(sg); +- int i; +- +- i = 0; +- do { +- unsigned int copy; +- +- if (!sglen) { +- sg = sg_next(sg); +- if (!sg) { +- cxgb3i_log_error("%s, sg NULL, len %u/%u.\n", +- __func__, datalen, dlen); +- return -EINVAL; +- } +- sgoffset = 0; +- sglen = sg->length; +- page = sg_page(sg); +- +- } +- copy = min(datalen, sglen); +- if (i && page == frags[i - 1].page && +- sgoffset + sg->offset == +- frags[i - 1].page_offset + frags[i - 1].size) { +- frags[i - 1].size += copy; +- } else { +- if (i >= frag_max) { +- cxgb3i_log_error("%s, too many pages %u, " +- "dlen %u.\n", __func__, +- frag_max, dlen); +- return -EINVAL; +- } +- +- frags[i].page = page; +- frags[i].page_offset = sg->offset + sgoffset; +- frags[i].size = copy; +- i++; +- } +- datalen -= copy; +- sgoffset += copy; +- sglen -= copy; +- } while (datalen); +- +- return i; +-} +- ++/* ++ * We do not support ahs yet ++ */ + int cxgb3i_conn_alloc_pdu(struct iscsi_task *task, u8 opcode) + { +- struct iscsi_conn *conn = task->conn; + struct iscsi_tcp_task *tcp_task = task->dd_data; +- struct cxgb3i_task_data *tdata = task->dd_data + sizeof(*tcp_task); +- struct scsi_cmnd *sc = task->sc; +- int headroom = SKB_TX_PDU_HEADER_LEN; ++ struct sk_buff *skb; + +- tcp_task->dd_data = tdata; + task->hdr = NULL; +- +- /* write command, need to send data pdus */ +- if (skb_extra_headroom && (opcode == ISCSI_OP_SCSI_DATA_OUT || +- (opcode == ISCSI_OP_SCSI_CMD && +- (scsi_bidi_cmnd(sc) || sc->sc_data_direction == DMA_TO_DEVICE)))) +- headroom += min(skb_extra_headroom, conn->max_xmit_dlength); +- +- tdata->skb = alloc_skb(TX_HEADER_LEN + headroom, GFP_ATOMIC); +- if (!tdata->skb) ++ /* always allocate rooms for AHS */ ++ skb = alloc_skb(sizeof(struct iscsi_hdr) + ISCSI_MAX_AHS_SIZE + ++ TX_HEADER_LEN, GFP_ATOMIC); ++ if (!skb) + return -ENOMEM; +- skb_reserve(tdata->skb, TX_HEADER_LEN); + + cxgb3i_tx_debug("task 0x%p, opcode 0x%x, skb 0x%p.\n", +- task, opcode, tdata->skb); ++ task, opcode, skb); + +- task->hdr = (struct iscsi_hdr *)tdata->skb->data; +- task->hdr_max = SKB_TX_PDU_HEADER_LEN; ++ tcp_task->dd_data = skb; ++ skb_reserve(skb, TX_HEADER_LEN); ++ task->hdr = (struct iscsi_hdr *)skb->data; ++ task->hdr_max = sizeof(struct iscsi_hdr); + + /* data_out uses scsi_cmd's itt */ + if (opcode != ISCSI_OP_SCSI_DATA_OUT) +@@ -271,13 +192,13 @@ + int cxgb3i_conn_init_pdu(struct iscsi_task *task, unsigned int offset, + unsigned int count) + { +- struct iscsi_conn *conn = task->conn; + struct iscsi_tcp_task *tcp_task = task->dd_data; +- struct cxgb3i_task_data *tdata = tcp_task->dd_data; +- struct sk_buff *skb = tdata->skb; ++ struct sk_buff *skb = tcp_task->dd_data; ++ struct iscsi_conn *conn = task->conn; ++ struct page *pg; + unsigned int datalen = count; + int i, padlen = iscsi_padding(count); +- struct page *pg; ++ skb_frag_t *frag; + + cxgb3i_tx_debug("task 0x%p,0x%p, offset %u, count %u, skb 0x%p.\n", + task, task->sc, offset, count, skb); +@@ -288,94 +209,90 @@ + return 0; + + if (task->sc) { +- struct scsi_data_buffer *sdb = scsi_out(task->sc); +- struct scatterlist *sg = NULL; +- int err; +- +- tdata->offset = offset; +- tdata->count = count; +- err = sgl_seek_offset(sdb->table.sgl, sdb->table.nents, +- tdata->offset, &tdata->sgoffset, &sg); +- if (err < 0) { +- cxgb3i_log_warn("tpdu, sgl %u, bad offset %u/%u.\n", +- sdb->table.nents, tdata->offset, +- sdb->length); +- return err; ++ struct scatterlist *sg; ++ struct scsi_data_buffer *sdb; ++ unsigned int sgoffset = offset; ++ struct page *sgpg; ++ unsigned int sglen; ++ ++ sdb = scsi_out(task->sc); ++ sg = sdb->table.sgl; ++ ++ for_each_sg(sdb->table.sgl, sg, sdb->table.nents, i) { ++ cxgb3i_tx_debug("sg %d, page 0x%p, len %u offset %u\n", ++ i, sg_page(sg), sg->length, sg->offset); ++ ++ if (sgoffset < sg->length) ++ break; ++ sgoffset -= sg->length; + } +- err = sgl_read_to_frags(sg, tdata->sgoffset, tdata->count, +- tdata->frags, MAX_PDU_FRAGS); +- if (err < 0) { +- cxgb3i_log_warn("tpdu, sgl %u, bad offset %u + %u.\n", +- sdb->table.nents, tdata->offset, +- tdata->count); +- return err; +- } +- tdata->nr_frags = err; ++ sgpg = sg_page(sg); ++ sglen = sg->length - sgoffset; + +- if (tdata->nr_frags > MAX_SKB_FRAGS || +- (padlen && tdata->nr_frags == MAX_SKB_FRAGS)) { +- char *dst = skb->data + task->hdr_len; +- skb_frag_t *frag = tdata->frags; +- +- /* data fits in the skb's headroom */ +- for (i = 0; i < tdata->nr_frags; i++, frag++) { +- char *src = kmap_atomic(frag->page, +- KM_SOFTIRQ0); +- +- memcpy(dst, src+frag->page_offset, frag->size); +- dst += frag->size; +- kunmap_atomic(src, KM_SOFTIRQ0); ++ do { ++ int j = skb_shinfo(skb)->nr_frags; ++ unsigned int copy; ++ ++ if (!sglen) { ++ sg = sg_next(sg); ++ sgpg = sg_page(sg); ++ sgoffset = 0; ++ sglen = sg->length; ++ ++i; + } +- if (padlen) { +- memset(dst, 0, padlen); +- padlen = 0; ++ copy = min(sglen, datalen); ++ if (j && skb_can_coalesce(skb, j, sgpg, ++ sg->offset + sgoffset)) { ++ skb_shinfo(skb)->frags[j - 1].size += copy; ++ } else { ++ get_page(sgpg); ++ skb_fill_page_desc(skb, j, sgpg, ++ sg->offset + sgoffset, copy); + } +- skb_put(skb, count + padlen); +- } else { +- /* data fit into frag_list */ +- for (i = 0; i < tdata->nr_frags; i++) +- get_page(tdata->frags[i].page); +- +- memcpy(skb_shinfo(skb)->frags, tdata->frags, +- sizeof(skb_frag_t) * tdata->nr_frags); +- skb_shinfo(skb)->nr_frags = tdata->nr_frags; +- skb->len += count; +- skb->data_len += count; +- skb->truesize += count; +- } +- ++ sgoffset += copy; ++ sglen -= copy; ++ datalen -= copy; ++ } while (datalen); + } else { + pg = virt_to_page(task->data); + +- get_page(pg); +- skb_fill_page_desc(skb, 0, pg, offset_in_page(task->data), +- count); +- skb->len += count; +- skb->data_len += count; +- skb->truesize += count; ++ while (datalen) { ++ i = skb_shinfo(skb)->nr_frags; ++ frag = &skb_shinfo(skb)->frags[i]; ++ ++ get_page(pg); ++ frag->page = pg; ++ frag->page_offset = 0; ++ frag->size = min((unsigned int)PAGE_SIZE, datalen); ++ ++ skb_shinfo(skb)->nr_frags++; ++ datalen -= frag->size; ++ pg++; ++ } + } + + if (padlen) { + i = skb_shinfo(skb)->nr_frags; +- get_page(pad_page); +- skb_fill_page_desc(skb, skb_shinfo(skb)->nr_frags, pad_page, 0, +- padlen); +- +- skb->data_len += padlen; +- skb->truesize += padlen; +- skb->len += padlen; ++ frag = &skb_shinfo(skb)->frags[i]; ++ frag->page = pad_page; ++ frag->page_offset = 0; ++ frag->size = padlen; ++ skb_shinfo(skb)->nr_frags++; + } + ++ datalen = count + padlen; ++ skb->data_len += datalen; ++ skb->truesize += datalen; ++ skb->len += datalen; + return 0; + } + + int cxgb3i_conn_xmit_pdu(struct iscsi_task *task) + { ++ struct iscsi_tcp_task *tcp_task = task->dd_data; ++ struct sk_buff *skb = tcp_task->dd_data; + struct iscsi_tcp_conn *tcp_conn = task->conn->dd_data; + struct cxgb3i_conn *cconn = tcp_conn->dd_data; +- struct iscsi_tcp_task *tcp_task = task->dd_data; +- struct cxgb3i_task_data *tdata = tcp_task->dd_data; +- struct sk_buff *skb = tdata->skb; + unsigned int datalen; + int err; + +@@ -383,13 +300,12 @@ + return 0; + + datalen = skb->data_len; +- tdata->skb = NULL; ++ tcp_task->dd_data = NULL; + err = cxgb3i_c3cn_send_pdus(cconn->cep->c3cn, skb); +- if (err > 0) { +- int pdulen = err; +- + cxgb3i_tx_debug("task 0x%p, skb 0x%p, len %u/%u, rv %d.\n", + task, skb, skb->len, skb->data_len, err); ++ if (err > 0) { ++ int pdulen = err; + + if (task->conn->hdrdgst_en) + pdulen += ISCSI_DIGEST_SIZE; +@@ -409,14 +325,12 @@ + return err; + } + /* reset skb to send when we are called again */ +- tdata->skb = skb; ++ tcp_task->dd_data = skb; + return -EAGAIN; + } + + int cxgb3i_pdu_init(void) + { +- if (SKB_TX_HEADROOM > (512 * MAX_SKB_FRAGS)) +- skb_extra_headroom = SKB_TX_HEADROOM; + pad_page = alloc_page(GFP_KERNEL); + if (!pad_page) + return -ENOMEM; +@@ -452,9 +366,7 @@ + skb = skb_peek(&c3cn->receive_queue); + while (!err && skb) { + __skb_unlink(skb, &c3cn->receive_queue); +- read += skb_rx_pdulen(skb); +- cxgb3i_rx_debug("conn 0x%p, cn 0x%p, rx skb 0x%p, pdulen %u.\n", +- conn, c3cn, skb, skb_rx_pdulen(skb)); ++ read += skb_ulp_pdulen(skb); + err = cxgb3i_conn_read_pdu_skb(conn, skb); + __kfree_skb(skb); + skb = skb_peek(&c3cn->receive_queue); +@@ -465,11 +377,6 @@ + cxgb3i_c3cn_rx_credits(c3cn, read); + } + conn->rxdata_octets += read; +- +- if (err) { +- cxgb3i_log_info("conn 0x%p rx failed err %d.\n", conn, err); +- iscsi_conn_failure(conn, ISCSI_ERR_CONN_FAILED); +- } + } + + void cxgb3i_conn_tx_open(struct s3_conn *c3cn) +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/drivers/scsi/cxgb3i/cxgb3i_pdu.h linux-2.6.29-rc3.owrt/drivers/scsi/cxgb3i/cxgb3i_pdu.h +--- linux-2.6.29.owrt/drivers/scsi/cxgb3i/cxgb3i_pdu.h 2009-05-10 22:04:39.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/drivers/scsi/cxgb3i/cxgb3i_pdu.h 2009-05-10 23:48:29.000000000 +0200 +@@ -53,7 +53,7 @@ + #define ULP2_FLAG_DCRC_ERROR 0x20 + #define ULP2_FLAG_PAD_ERROR 0x40 + +-void cxgb3i_conn_closing(struct s3_conn *c3cn); ++void cxgb3i_conn_closing(struct s3_conn *); + void cxgb3i_conn_pdu_ready(struct s3_conn *c3cn); + void cxgb3i_conn_tx_open(struct s3_conn *c3cn); + #endif +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/drivers/scsi/fcoe/fcoe_sw.c linux-2.6.29-rc3.owrt/drivers/scsi/fcoe/fcoe_sw.c +--- linux-2.6.29.owrt/drivers/scsi/fcoe/fcoe_sw.c 2009-05-10 22:04:39.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/drivers/scsi/fcoe/fcoe_sw.c 2009-05-10 23:48:29.000000000 +0200 +@@ -104,19 +104,19 @@ + .max_sectors = 0xffff, + }; + +-/** +- * fcoe_sw_lport_config() - sets up the fc_lport ++/* ++ * fcoe_sw_lport_config - sets up the fc_lport + * @lp: ptr to the fc_lport + * @shost: ptr to the parent scsi host + * + * Returns: 0 for success ++ * + */ + static int fcoe_sw_lport_config(struct fc_lport *lp) + { + int i = 0; + +- lp->link_up = 0; +- lp->qfull = 0; ++ lp->link_status = 0; + lp->max_retry_count = 3; + lp->e_d_tov = 2 * 1000; /* FC-FS default */ + lp->r_a_tov = 2 * 2 * 1000; +@@ -136,14 +136,16 @@ + return 0; + } + +-/** +- * fcoe_sw_netdev_config() - Set up netdev for SW FCoE ++/* ++ * fcoe_sw_netdev_config - sets up fcoe_softc for lport and network ++ * related properties + * @lp : ptr to the fc_lport + * @netdev : ptr to the associated netdevice struct + * + * Must be called after fcoe_sw_lport_config() as it will use lport mutex + * + * Returns : 0 for success ++ * + */ + static int fcoe_sw_netdev_config(struct fc_lport *lp, struct net_device *netdev) + { +@@ -179,8 +181,9 @@ + if (fc_set_mfs(lp, mfs)) + return -EINVAL; + ++ lp->link_status = ~FC_PAUSE & ~FC_LINK_UP; + if (!fcoe_link_ok(lp)) +- lp->link_up = 1; ++ lp->link_status |= FC_LINK_UP; + + /* offload features support */ + if (fc->real_dev->features & NETIF_F_SG) +@@ -188,7 +191,6 @@ + + + skb_queue_head_init(&fc->fcoe_pending_queue); +- fc->fcoe_pending_queue_active = 0; + + /* setup Source Mac Address */ + memcpy(fc->ctl_src_addr, fc->real_dev->dev_addr, +@@ -222,15 +224,16 @@ + return 0; + } + +-/** +- * fcoe_sw_shost_config() - Sets up fc_lport->host ++/* ++ * fcoe_sw_shost_config - sets up fc_lport->host + * @lp : ptr to the fc_lport + * @shost : ptr to the associated scsi host + * @dev : device associated to scsi host + * +- * Must be called after fcoe_sw_lport_config() and fcoe_sw_netdev_config() ++ * Must be called after fcoe_sw_lport_config) and fcoe_sw_netdev_config() + * + * Returns : 0 for success ++ * + */ + static int fcoe_sw_shost_config(struct fc_lport *lp, struct Scsi_Host *shost, + struct device *dev) +@@ -258,8 +261,8 @@ + return 0; + } + +-/** +- * fcoe_sw_em_config() - allocates em for this lport ++/* ++ * fcoe_sw_em_config - allocates em for this lport + * @lp: the port that em is to allocated for + * + * Returns : 0 on success +@@ -276,8 +279,8 @@ + return 0; + } + +-/** +- * fcoe_sw_destroy() - FCoE software HBA tear-down function ++/* ++ * fcoe_sw_destroy - FCoE software HBA tear-down function + * @netdev: ptr to the associated net_device + * + * Returns: 0 if link is OK for use by FCoE. +@@ -298,7 +301,7 @@ + if (!lp) + return -ENODEV; + +- fc = lport_priv(lp); ++ fc = fcoe_softc(lp); + + /* Logout of the fabric */ + fc_fabric_logoff(lp); +@@ -350,8 +353,8 @@ + .frame_send = fcoe_xmit, + }; + +-/** +- * fcoe_sw_create() - this function creates the fcoe interface ++/* ++ * fcoe_sw_create - this function creates the fcoe interface + * @netdev: pointer the associated netdevice + * + * Creates fc_lport struct and scsi_host for lport, configures lport +@@ -437,8 +440,8 @@ + return rc; + } + +-/** +- * fcoe_sw_match() - The FCoE SW transport match function ++/* ++ * fcoe_sw_match - the fcoe sw transport match function + * + * Returns : false always + */ +@@ -458,8 +461,8 @@ + .device = 0xffff, + }; + +-/** +- * fcoe_sw_init() - Registers fcoe_sw_transport ++/* ++ * fcoe_sw_init - registers fcoe_sw_transport + * + * Returns : 0 on success + */ +@@ -468,22 +471,17 @@ + /* attach to scsi transport */ + scsi_transport_fcoe_sw = + fc_attach_transport(&fcoe_sw_transport_function); +- + if (!scsi_transport_fcoe_sw) { + printk(KERN_ERR "fcoe_sw_init:fc_attach_transport() failed\n"); + return -ENODEV; + } +- +- mutex_init(&fcoe_sw_transport.devlock); +- INIT_LIST_HEAD(&fcoe_sw_transport.devlist); +- + /* register sw transport */ + fcoe_transport_register(&fcoe_sw_transport); + return 0; + } + +-/** +- * fcoe_sw_exit() - Unregisters fcoe_sw_transport ++/* ++ * fcoe_sw_exit - unregisters fcoe_sw_transport + * + * Returns : 0 on success + */ +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/drivers/scsi/fcoe/fc_transport_fcoe.c linux-2.6.29-rc3.owrt/drivers/scsi/fcoe/fc_transport_fcoe.c +--- linux-2.6.29.owrt/drivers/scsi/fcoe/fc_transport_fcoe.c 2009-05-10 22:04:39.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/drivers/scsi/fcoe/fc_transport_fcoe.c 2009-05-10 23:48:29.000000000 +0200 +@@ -33,19 +33,19 @@ + static DEFINE_MUTEX(fcoe_transports_lock); + + /** +- * fcoe_transport_default() - Returns ptr to the default transport fcoe_sw +- */ ++ * fcoe_transport_default - returns ptr to the default transport fcoe_sw ++ **/ + struct fcoe_transport *fcoe_transport_default(void) + { + return &fcoe_sw_transport; + } + + /** +- * fcoe_transport_to_pcidev() - get the pci dev from a netdev ++ * fcoe_transport_to_pcidev - get the pci dev from a netdev + * @netdev: the netdev that pci dev will be retrived from + * + * Returns: NULL or the corrsponding pci_dev +- */ ++ **/ + struct pci_dev *fcoe_transport_pcidev(const struct net_device *netdev) + { + if (!netdev->dev.parent) +@@ -54,17 +54,18 @@ + } + + /** +- * fcoe_transport_device_lookup() - Lookup a transport ++ * fcoe_transport_device_lookup - find out netdev is managed by the ++ * transport ++ * assign a transport to a device + * @netdev: the netdev the transport to be attached to + * + * This will look for existing offload driver, if not found, it falls back to + * the default sw hba (fcoe_sw) as its fcoe transport. + * + * Returns: 0 for success +- */ +-static struct fcoe_transport_internal * +-fcoe_transport_device_lookup(struct fcoe_transport *t, +- struct net_device *netdev) ++ **/ ++static struct fcoe_transport_internal *fcoe_transport_device_lookup( ++ struct fcoe_transport *t, struct net_device *netdev) + { + struct fcoe_transport_internal *ti; + +@@ -80,14 +81,14 @@ + return NULL; + } + /** +- * fcoe_transport_device_add() - Assign a transport to a device ++ * fcoe_transport_device_add - assign a transport to a device + * @netdev: the netdev the transport to be attached to + * + * This will look for existing offload driver, if not found, it falls back to + * the default sw hba (fcoe_sw) as its fcoe transport. + * + * Returns: 0 for success +- */ ++ **/ + static int fcoe_transport_device_add(struct fcoe_transport *t, + struct net_device *netdev) + { +@@ -122,14 +123,14 @@ + } + + /** +- * fcoe_transport_device_remove() - Remove a device from its transport ++ * fcoe_transport_device_remove - remove a device from its transport + * @netdev: the netdev the transport to be attached to + * +- * This removes the device from the transport so the given transport will ++ * this removes the device from the transport so the given transport will + * not manage this device any more + * + * Returns: 0 for success +- */ ++ **/ + static int fcoe_transport_device_remove(struct fcoe_transport *t, + struct net_device *netdev) + { +@@ -154,13 +155,13 @@ + } + + /** +- * fcoe_transport_device_remove_all() - Remove all from transport devlist ++ * fcoe_transport_device_remove_all - remove all from transport devlist + * +- * This removes the device from the transport so the given transport will ++ * this removes the device from the transport so the given transport will + * not manage this device any more + * + * Returns: 0 for success +- */ ++ **/ + static void fcoe_transport_device_remove_all(struct fcoe_transport *t) + { + struct fcoe_transport_internal *ti, *tmp; +@@ -174,18 +175,18 @@ + } + + /** +- * fcoe_transport_match() - Use the bus device match function to match the hw +- * @t: The fcoe transport to check +- * @netdev: The netdev to match against ++ * fcoe_transport_match - use the bus device match function to match the hw ++ * @t: the fcoe transport ++ * @netdev: + * +- * This function is used to check if the given transport wants to manage the ++ * This function is used to check if the givne transport wants to manage the + * input netdev. if the transports implements the match function, it will be + * called, o.w. we just compare the pci vendor and device id. + * + * Returns: true for match up +- */ ++ **/ + static bool fcoe_transport_match(struct fcoe_transport *t, +- struct net_device *netdev) ++ struct net_device *netdev) + { + /* match transport by vendor and device id */ + struct pci_dev *pci; +@@ -209,17 +210,17 @@ + } + + /** +- * fcoe_transport_lookup() - Check if the transport is already registered ++ * fcoe_transport_lookup - check if the transport is already registered + * @t: the transport to be looked up + * + * This compares the parent device (pci) vendor and device id + * + * Returns: NULL if not found + * +- * TODO: return default sw transport if no other transport is found +- */ +-static struct fcoe_transport * +-fcoe_transport_lookup(struct net_device *netdev) ++ * TODO - return default sw transport if no other transport is found ++ **/ ++static struct fcoe_transport *fcoe_transport_lookup( ++ struct net_device *netdev) + { + struct fcoe_transport *t; + +@@ -238,11 +239,11 @@ + } + + /** +- * fcoe_transport_register() - Adds a fcoe transport to the fcoe transports list ++ * fcoe_transport_register - adds a fcoe transport to the fcoe transports list + * @t: ptr to the fcoe transport to be added + * + * Returns: 0 for success +- */ ++ **/ + int fcoe_transport_register(struct fcoe_transport *t) + { + struct fcoe_transport *tt; +@@ -258,6 +259,9 @@ + list_add_tail(&t->list, &fcoe_transports); + mutex_unlock(&fcoe_transports_lock); + ++ mutex_init(&t->devlock); ++ INIT_LIST_HEAD(&t->devlist); ++ + printk(KERN_DEBUG "fcoe_transport_register:%s\n", t->name); + + return 0; +@@ -265,11 +269,11 @@ + EXPORT_SYMBOL_GPL(fcoe_transport_register); + + /** +- * fcoe_transport_unregister() - Remove the tranport fro the fcoe transports list ++ * fcoe_transport_unregister - remove the tranport fro the fcoe transports list + * @t: ptr to the fcoe transport to be removed + * + * Returns: 0 for success +- */ ++ **/ + int fcoe_transport_unregister(struct fcoe_transport *t) + { + struct fcoe_transport *tt, *tmp; +@@ -290,8 +294,8 @@ + } + EXPORT_SYMBOL_GPL(fcoe_transport_unregister); + +-/** +- * fcoe_load_transport_driver() - Load an offload driver by alias name ++/* ++ * fcoe_load_transport_driver - load an offload driver by alias name + * @netdev: the target net device + * + * Requests for an offload driver module as the fcoe transport, if fails, it +@@ -303,7 +307,7 @@ + * 3. pure hw fcoe hba may not have netdev + * + * Returns: 0 for success +- */ ++ **/ + int fcoe_load_transport_driver(struct net_device *netdev) + { + struct pci_dev *pci; +@@ -331,14 +335,14 @@ + EXPORT_SYMBOL_GPL(fcoe_load_transport_driver); + + /** +- * fcoe_transport_attach() - Load transport to fcoe ++ * fcoe_transport_attach - load transport to fcoe + * @netdev: the netdev the transport to be attached to + * + * This will look for existing offload driver, if not found, it falls back to + * the default sw hba (fcoe_sw) as its fcoe transport. + * + * Returns: 0 for success +- */ ++ **/ + int fcoe_transport_attach(struct net_device *netdev) + { + struct fcoe_transport *t; +@@ -369,11 +373,11 @@ + EXPORT_SYMBOL_GPL(fcoe_transport_attach); + + /** +- * fcoe_transport_release() - Unload transport from fcoe ++ * fcoe_transport_release - unload transport from fcoe + * @netdev: the net device on which fcoe is to be released + * + * Returns: 0 for success +- */ ++ **/ + int fcoe_transport_release(struct net_device *netdev) + { + struct fcoe_transport *t; +@@ -406,12 +410,12 @@ + EXPORT_SYMBOL_GPL(fcoe_transport_release); + + /** +- * fcoe_transport_init() - Initializes fcoe transport layer ++ * fcoe_transport_init - initializes fcoe transport layer + * + * This prepares for the fcoe transport layer + * + * Returns: none +- */ ++ **/ + int __init fcoe_transport_init(void) + { + INIT_LIST_HEAD(&fcoe_transports); +@@ -420,13 +424,12 @@ + } + + /** +- * fcoe_transport_exit() - Cleans up the fcoe transport layer +- * ++ * fcoe_transport_exit - cleans up the fcoe transport layer + * This cleans up the fcoe transport layer. removing any transport on the list, + * note that the transport destroy func is not called here. + * + * Returns: none +- */ ++ **/ + int __exit fcoe_transport_exit(void) + { + struct fcoe_transport *t, *tmp; +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/drivers/scsi/fcoe/libfcoe.c linux-2.6.29-rc3.owrt/drivers/scsi/fcoe/libfcoe.c +--- linux-2.6.29.owrt/drivers/scsi/fcoe/libfcoe.c 2009-05-10 22:04:39.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/drivers/scsi/fcoe/libfcoe.c 2009-05-10 23:48:29.000000000 +0200 +@@ -49,7 +49,6 @@ + static int debug_fcoe; + + #define FCOE_MAX_QUEUE_DEPTH 256 +-#define FCOE_LOW_QUEUE_DEPTH 32 + + /* destination address mode */ + #define FCOE_GW_ADDR_MODE 0x00 +@@ -70,6 +69,8 @@ + + /* Function Prototyes */ + static int fcoe_check_wait_queue(struct fc_lport *); ++static void fcoe_insert_wait_queue_head(struct fc_lport *, struct sk_buff *); ++static void fcoe_insert_wait_queue(struct fc_lport *, struct sk_buff *); + static void fcoe_recv_flogi(struct fcoe_softc *, struct fc_frame *, u8 *); + #ifdef CONFIG_HOTPLUG_CPU + static int fcoe_cpu_callback(struct notifier_block *, ulong, void *); +@@ -90,13 +91,13 @@ + }; + + /** +- * fcoe_create_percpu_data() - creates the associated cpu data ++ * fcoe_create_percpu_data - creates the associated cpu data + * @cpu: index for the cpu where fcoe cpu data will be created + * + * create percpu stats block, from cpu add notifier + * + * Returns: none +- */ ++ **/ + static void fcoe_create_percpu_data(int cpu) + { + struct fc_lport *lp; +@@ -114,13 +115,13 @@ + } + + /** +- * fcoe_destroy_percpu_data() - destroys the associated cpu data ++ * fcoe_destroy_percpu_data - destroys the associated cpu data + * @cpu: index for the cpu where fcoe cpu data will destroyed + * + * destroy percpu stats block called by cpu add/remove notifier + * + * Retuns: none +- */ ++ **/ + static void fcoe_destroy_percpu_data(int cpu) + { + struct fc_lport *lp; +@@ -136,7 +137,7 @@ + } + + /** +- * fcoe_cpu_callback() - fcoe cpu hotplug event callback ++ * fcoe_cpu_callback - fcoe cpu hotplug event callback + * @nfb: callback data block + * @action: event triggering the callback + * @hcpu: index for the cpu of this event +@@ -144,7 +145,7 @@ + * this creates or destroys per cpu data for fcoe + * + * Returns NOTIFY_OK always. +- */ ++ **/ + static int fcoe_cpu_callback(struct notifier_block *nfb, unsigned long action, + void *hcpu) + { +@@ -165,7 +166,7 @@ + #endif /* CONFIG_HOTPLUG_CPU */ + + /** +- * fcoe_rcv() - this is the fcoe receive function called by NET_RX_SOFTIRQ ++ * fcoe_rcv - this is the fcoe receive function called by NET_RX_SOFTIRQ + * @skb: the receive skb + * @dev: associated net device + * @ptype: context +@@ -174,7 +175,7 @@ + * this function will receive the packet and build fc frame and pass it up + * + * Returns: 0 for success +- */ ++ **/ + int fcoe_rcv(struct sk_buff *skb, struct net_device *dev, + struct packet_type *ptype, struct net_device *olddev) + { +@@ -264,11 +265,11 @@ + EXPORT_SYMBOL_GPL(fcoe_rcv); + + /** +- * fcoe_start_io() - pass to netdev to start xmit for fcoe ++ * fcoe_start_io - pass to netdev to start xmit for fcoe + * @skb: the skb to be xmitted + * + * Returns: 0 for success +- */ ++ **/ + static inline int fcoe_start_io(struct sk_buff *skb) + { + int rc; +@@ -282,12 +283,12 @@ + } + + /** +- * fcoe_get_paged_crc_eof() - in case we need alloc a page for crc_eof ++ * fcoe_get_paged_crc_eof - in case we need alloc a page for crc_eof + * @skb: the skb to be xmitted + * @tlen: total len + * + * Returns: 0 for success +- */ ++ **/ + static int fcoe_get_paged_crc_eof(struct sk_buff *skb, int tlen) + { + struct fcoe_percpu_s *fps; +@@ -325,12 +326,13 @@ + } + + /** +- * fcoe_fc_crc() - calculates FC CRC in this fcoe skb ++ * fcoe_fc_crc - calculates FC CRC in this fcoe skb + * @fp: the fc_frame containg data to be checksummed + * + * This uses crc32() to calculate the crc for fc frame + * Return : 32 bit crc +- */ ++ * ++ **/ + u32 fcoe_fc_crc(struct fc_frame *fp) + { + struct sk_buff *skb = fp_skb(fp); +@@ -361,12 +363,13 @@ + EXPORT_SYMBOL_GPL(fcoe_fc_crc); + + /** +- * fcoe_xmit() - FCoE frame transmit function ++ * fcoe_xmit - FCoE frame transmit function + * @lp: the associated local port + * @fp: the fc_frame to be transmitted + * + * Return : 0 for success +- */ ++ * ++ **/ + int fcoe_xmit(struct fc_lport *lp, struct fc_frame *fp) + { + int wlen, rc = 0; +@@ -386,7 +389,7 @@ + + WARN_ON((fr_len(fp) % sizeof(u32)) != 0); + +- fc = lport_priv(lp); ++ fc = fcoe_softc(lp); + /* + * if it is a flogi then we need to learn gw-addr + * and my own fcid +@@ -436,7 +439,7 @@ + if (skb_is_nonlinear(skb)) { + skb_frag_t *frag; + if (fcoe_get_paged_crc_eof(skb, tlen)) { +- kfree_skb(skb); ++ kfree(skb); + return -ENOMEM; + } + frag = &skb_shinfo(skb)->frags[skb_shinfo(skb)->nr_frags - 1]; +@@ -499,22 +502,21 @@ + rc = fcoe_start_io(skb); + + if (rc) { +- spin_lock_bh(&fc->fcoe_pending_queue.lock); +- __skb_queue_tail(&fc->fcoe_pending_queue, skb); +- spin_unlock_bh(&fc->fcoe_pending_queue.lock); ++ fcoe_insert_wait_queue(lp, skb); + if (fc->fcoe_pending_queue.qlen > FCOE_MAX_QUEUE_DEPTH) +- lp->qfull = 1; ++ fc_pause(lp); + } + + return 0; + } + EXPORT_SYMBOL_GPL(fcoe_xmit); + +-/** +- * fcoe_percpu_receive_thread() - recv thread per cpu ++/* ++ * fcoe_percpu_receive_thread - recv thread per cpu + * @arg: ptr to the fcoe per cpu struct + * + * Return: 0 for success ++ * + */ + int fcoe_percpu_receive_thread(void *arg) + { +@@ -531,7 +533,7 @@ + struct fcoe_softc *fc; + struct fcoe_hdr *hp; + +- set_user_nice(current, -20); ++ set_user_nice(current, 19); + + while (!kthread_should_stop()) { + +@@ -656,7 +658,7 @@ + } + + /** +- * fcoe_recv_flogi() - flogi receive function ++ * fcoe_recv_flogi - flogi receive function + * @fc: associated fcoe_softc + * @fp: the recieved frame + * @sa: the source address of this flogi +@@ -665,7 +667,7 @@ + * mac address for the initiator, eitehr OUI based or GW based. + * + * Returns: none +- */ ++ **/ + static void fcoe_recv_flogi(struct fcoe_softc *fc, struct fc_frame *fp, u8 *sa) + { + struct fc_frame_header *fh; +@@ -713,23 +715,32 @@ + } + + /** +- * fcoe_watchdog() - fcoe timer callback ++ * fcoe_watchdog - fcoe timer callback + * @vp: + * +- * This checks the pending queue length for fcoe and set lport qfull ++ * This checks the pending queue length for fcoe and put fcoe to be paused state + * if the FCOE_MAX_QUEUE_DEPTH is reached. This is done for all fc_lport on the + * fcoe_hostlist. + * + * Returns: 0 for success +- */ ++ **/ + void fcoe_watchdog(ulong vp) + { ++ struct fc_lport *lp; + struct fcoe_softc *fc; ++ int paused = 0; + + read_lock(&fcoe_hostlist_lock); + list_for_each_entry(fc, &fcoe_hostlist, list) { +- if (fc->lp) +- fcoe_check_wait_queue(fc->lp); ++ lp = fc->lp; ++ if (lp) { ++ if (fc->fcoe_pending_queue.qlen > FCOE_MAX_QUEUE_DEPTH) ++ paused = 1; ++ if (fcoe_check_wait_queue(lp) < FCOE_MAX_QUEUE_DEPTH) { ++ if (paused) ++ fc_unpause(lp); ++ } ++ } + } + read_unlock(&fcoe_hostlist_lock); + +@@ -739,64 +750,96 @@ + + + /** +- * fcoe_check_wait_queue() - put the skb into fcoe pending xmit queue ++ * fcoe_check_wait_queue - put the skb into fcoe pending xmit queue + * @lp: the fc_port for this skb + * @skb: the associated skb to be xmitted + * + * This empties the wait_queue, dequeue the head of the wait_queue queue + * and calls fcoe_start_io() for each packet, if all skb have been +- * transmitted, return qlen or -1 if a error occurs, then restore +- * wait_queue and try again later. ++ * transmitted, return 0 if a error occurs, then restore wait_queue and ++ * try again later. + * + * The wait_queue is used when the skb transmit fails. skb will go + * in the wait_queue which will be emptied by the time function OR + * by the next skb transmit. + * + * Returns: 0 for success +- */ ++ **/ + static int fcoe_check_wait_queue(struct fc_lport *lp) + { +- struct fcoe_softc *fc = lport_priv(lp); ++ int rc, unpause = 0; ++ int paused = 0; + struct sk_buff *skb; +- int rc = -1; ++ struct fcoe_softc *fc; + ++ fc = fcoe_softc(lp); + spin_lock_bh(&fc->fcoe_pending_queue.lock); +- if (fc->fcoe_pending_queue_active) +- goto out; +- fc->fcoe_pending_queue_active = 1; +- +- while (fc->fcoe_pending_queue.qlen) { +- /* keep qlen > 0 until fcoe_start_io succeeds */ +- fc->fcoe_pending_queue.qlen++; +- skb = __skb_dequeue(&fc->fcoe_pending_queue); +- +- spin_unlock_bh(&fc->fcoe_pending_queue.lock); +- rc = fcoe_start_io(skb); +- spin_lock_bh(&fc->fcoe_pending_queue.lock); + +- if (rc) { +- __skb_queue_head(&fc->fcoe_pending_queue, skb); +- /* undo temporary increment above */ +- fc->fcoe_pending_queue.qlen--; +- break; ++ /* ++ * is this interface paused? ++ */ ++ if (fc->fcoe_pending_queue.qlen > FCOE_MAX_QUEUE_DEPTH) ++ paused = 1; ++ if (fc->fcoe_pending_queue.qlen) { ++ while ((skb = __skb_dequeue(&fc->fcoe_pending_queue)) != NULL) { ++ spin_unlock_bh(&fc->fcoe_pending_queue.lock); ++ rc = fcoe_start_io(skb); ++ if (rc) { ++ fcoe_insert_wait_queue_head(lp, skb); ++ return rc; ++ } ++ spin_lock_bh(&fc->fcoe_pending_queue.lock); + } +- /* undo temporary increment above */ +- fc->fcoe_pending_queue.qlen--; ++ if (fc->fcoe_pending_queue.qlen < FCOE_MAX_QUEUE_DEPTH) ++ unpause = 1; + } ++ spin_unlock_bh(&fc->fcoe_pending_queue.lock); ++ if ((unpause) && (paused)) ++ fc_unpause(lp); ++ return fc->fcoe_pending_queue.qlen; ++} + +- if (fc->fcoe_pending_queue.qlen < FCOE_LOW_QUEUE_DEPTH) +- lp->qfull = 0; +- fc->fcoe_pending_queue_active = 0; +- rc = fc->fcoe_pending_queue.qlen; +-out: ++/** ++ * fcoe_insert_wait_queue_head - puts skb to fcoe pending queue head ++ * @lp: the fc_port for this skb ++ * @skb: the associated skb to be xmitted ++ * ++ * Returns: none ++ **/ ++static void fcoe_insert_wait_queue_head(struct fc_lport *lp, ++ struct sk_buff *skb) ++{ ++ struct fcoe_softc *fc; ++ ++ fc = fcoe_softc(lp); ++ spin_lock_bh(&fc->fcoe_pending_queue.lock); ++ __skb_queue_head(&fc->fcoe_pending_queue, skb); + spin_unlock_bh(&fc->fcoe_pending_queue.lock); +- return rc; + } + + /** +- * fcoe_dev_setup() - setup link change notification interface +- */ +-static void fcoe_dev_setup() ++ * fcoe_insert_wait_queue - put the skb into fcoe pending queue tail ++ * @lp: the fc_port for this skb ++ * @skb: the associated skb to be xmitted ++ * ++ * Returns: none ++ **/ ++static void fcoe_insert_wait_queue(struct fc_lport *lp, ++ struct sk_buff *skb) ++{ ++ struct fcoe_softc *fc; ++ ++ fc = fcoe_softc(lp); ++ spin_lock_bh(&fc->fcoe_pending_queue.lock); ++ __skb_queue_tail(&fc->fcoe_pending_queue, skb); ++ spin_unlock_bh(&fc->fcoe_pending_queue.lock); ++} ++ ++/** ++ * fcoe_dev_setup - setup link change notification interface ++ * ++ **/ ++static void fcoe_dev_setup(void) + { + /* + * here setup a interface specific wd time to +@@ -806,15 +849,15 @@ + } + + /** +- * fcoe_dev_setup() - cleanup link change notification interface +- */ ++ * fcoe_dev_setup - cleanup link change notification interface ++ **/ + static void fcoe_dev_cleanup(void) + { + unregister_netdevice_notifier(&fcoe_notifier); + } + + /** +- * fcoe_device_notification() - netdev event notification callback ++ * fcoe_device_notification - netdev event notification callback + * @notifier: context of the notification + * @event: type of event + * @ptr: fixed array for output parsed ifname +@@ -822,7 +865,7 @@ + * This function is called by the ethernet driver in case of link change event + * + * Returns: 0 for success +- */ ++ **/ + static int fcoe_device_notification(struct notifier_block *notifier, + ulong event, void *ptr) + { +@@ -830,7 +873,7 @@ + struct net_device *real_dev = ptr; + struct fcoe_softc *fc; + struct fcoe_dev_stats *stats; +- u32 new_link_up; ++ u16 new_status; + u32 mfs; + int rc = NOTIFY_OK; + +@@ -847,15 +890,17 @@ + goto out; + } + +- new_link_up = lp->link_up; ++ new_status = lp->link_status; + switch (event) { + case NETDEV_DOWN: + case NETDEV_GOING_DOWN: +- new_link_up = 0; ++ new_status &= ~FC_LINK_UP; + break; + case NETDEV_UP: + case NETDEV_CHANGE: +- new_link_up = !fcoe_link_ok(lp); ++ new_status &= ~FC_LINK_UP; ++ if (!fcoe_link_ok(lp)) ++ new_status |= FC_LINK_UP; + break; + case NETDEV_CHANGEMTU: + mfs = fc->real_dev->mtu - +@@ -863,15 +908,17 @@ + sizeof(struct fcoe_crc_eof)); + if (mfs >= FC_MIN_MAX_FRAME) + fc_set_mfs(lp, mfs); +- new_link_up = !fcoe_link_ok(lp); ++ new_status &= ~FC_LINK_UP; ++ if (!fcoe_link_ok(lp)) ++ new_status |= FC_LINK_UP; + break; + case NETDEV_REGISTER: + break; + default: + FC_DBG("unknown event %ld call", event); + } +- if (lp->link_up != new_link_up) { +- if (new_link_up) ++ if (lp->link_status != new_status) { ++ if ((new_status & FC_LINK_UP) == FC_LINK_UP) + fc_linkup(lp); + else { + stats = lp->dev_stats[smp_processor_id()]; +@@ -886,12 +933,12 @@ + } + + /** +- * fcoe_if_to_netdev() - parse a name buffer to get netdev ++ * fcoe_if_to_netdev - parse a name buffer to get netdev + * @ifname: fixed array for output parsed ifname + * @buffer: incoming buffer to be copied + * + * Returns: NULL or ptr to netdeive +- */ ++ **/ + static struct net_device *fcoe_if_to_netdev(const char *buffer) + { + char *cp; +@@ -908,13 +955,13 @@ + } + + /** +- * fcoe_netdev_to_module_owner() - finds out the nic drive moddule of the netdev ++ * fcoe_netdev_to_module_owner - finds out the nic drive moddule of the netdev + * @netdev: the target netdev + * + * Returns: ptr to the struct module, NULL for failure +- */ +-static struct module * +-fcoe_netdev_to_module_owner(const struct net_device *netdev) ++ **/ ++static struct module *fcoe_netdev_to_module_owner( ++ const struct net_device *netdev) + { + struct device *dev; + +@@ -932,14 +979,12 @@ + } + + /** +- * fcoe_ethdrv_get() - Hold the Ethernet driver +- * @netdev: the target netdev +- * +- * Holds the Ethernet driver module by try_module_get() for ++ * fcoe_ethdrv_get - holds the nic driver module by try_module_get() for + * the corresponding netdev. ++ * @netdev: the target netdev + * + * Returns: 0 for succsss +- */ ++ **/ + static int fcoe_ethdrv_get(const struct net_device *netdev) + { + struct module *owner; +@@ -954,14 +999,12 @@ + } + + /** +- * fcoe_ethdrv_put() - Release the Ethernet driver +- * @netdev: the target netdev +- * +- * Releases the Ethernet driver module by module_put for ++ * fcoe_ethdrv_get - releases the nic driver module by module_put for + * the corresponding netdev. ++ * @netdev: the target netdev + * + * Returns: 0 for succsss +- */ ++ **/ + static int fcoe_ethdrv_put(const struct net_device *netdev) + { + struct module *owner; +@@ -977,12 +1020,12 @@ + } + + /** +- * fcoe_destroy() - handles the destroy from sysfs ++ * fcoe_destroy- handles the destroy from sysfs + * @buffer: expcted to be a eth if name + * @kp: associated kernel param + * + * Returns: 0 for success +- */ ++ **/ + static int fcoe_destroy(const char *buffer, struct kernel_param *kp) + { + int rc; +@@ -1015,12 +1058,12 @@ + } + + /** +- * fcoe_create() - Handles the create call from sysfs ++ * fcoe_create - handles the create call from sysfs + * @buffer: expcted to be a eth if name + * @kp: associated kernel param + * + * Returns: 0 for success +- */ ++ **/ + static int fcoe_create(const char *buffer, struct kernel_param *kp) + { + int rc; +@@ -1061,8 +1104,8 @@ + __MODULE_PARM_TYPE(destroy, "string"); + MODULE_PARM_DESC(destroy, "Destroy fcoe port"); + +-/** +- * fcoe_link_ok() - Check if link is ok for the fc_lport ++/* ++ * fcoe_link_ok - check if link is ok for the fc_lport + * @lp: ptr to the fc_lport + * + * Any permanently-disqualifying conditions have been previously checked. +@@ -1077,7 +1120,7 @@ + */ + int fcoe_link_ok(struct fc_lport *lp) + { +- struct fcoe_softc *fc = lport_priv(lp); ++ struct fcoe_softc *fc = fcoe_softc(lp); + struct net_device *dev = fc->real_dev; + struct ethtool_cmd ecmd = { ETHTOOL_GSET }; + int rc = 0; +@@ -1106,8 +1149,9 @@ + } + EXPORT_SYMBOL_GPL(fcoe_link_ok); + +-/** +- * fcoe_percpu_clean() - Clear the pending skbs for an lport ++/* ++ * fcoe_percpu_clean - frees skb of the corresponding lport from the per ++ * cpu queue. + * @lp: the fc_lport + */ + void fcoe_percpu_clean(struct fc_lport *lp) +@@ -1141,11 +1185,11 @@ + EXPORT_SYMBOL_GPL(fcoe_percpu_clean); + + /** +- * fcoe_clean_pending_queue() - Dequeue a skb and free it ++ * fcoe_clean_pending_queue - dequeue skb and free it + * @lp: the corresponding fc_lport + * + * Returns: none +- */ ++ **/ + void fcoe_clean_pending_queue(struct fc_lport *lp) + { + struct fcoe_softc *fc = lport_priv(lp); +@@ -1162,21 +1206,21 @@ + EXPORT_SYMBOL_GPL(fcoe_clean_pending_queue); + + /** +- * libfc_host_alloc() - Allocate a Scsi_Host with room for the fc_lport ++ * libfc_host_alloc - allocate a Scsi_Host with room for the fc_lport + * @sht: ptr to the scsi host templ + * @priv_size: size of private data after fc_lport + * + * Returns: ptr to Scsi_Host +- * TODO: to libfc? ++ * TODO - to libfc? + */ +-static inline struct Scsi_Host * +-libfc_host_alloc(struct scsi_host_template *sht, int priv_size) ++static inline struct Scsi_Host *libfc_host_alloc( ++ struct scsi_host_template *sht, int priv_size) + { + return scsi_host_alloc(sht, sizeof(struct fc_lport) + priv_size); + } + + /** +- * fcoe_host_alloc() - Allocate a Scsi_Host with room for the fcoe_softc ++ * fcoe_host_alloc - allocate a Scsi_Host with room for the fcoe_softc + * @sht: ptr to the scsi host templ + * @priv_size: size of private data after fc_lport + * +@@ -1188,8 +1232,8 @@ + } + EXPORT_SYMBOL_GPL(fcoe_host_alloc); + +-/** +- * fcoe_reset() - Resets the fcoe ++/* ++ * fcoe_reset - resets the fcoe + * @shost: shost the reset is from + * + * Returns: always 0 +@@ -1202,8 +1246,8 @@ + } + EXPORT_SYMBOL_GPL(fcoe_reset); + +-/** +- * fcoe_wwn_from_mac() - Converts 48-bit IEEE MAC address to 64-bit FC WWN. ++/* ++ * fcoe_wwn_from_mac - converts 48-bit IEEE MAC address to 64-bit FC WWN. + * @mac: mac address + * @scheme: check port + * @port: port indicator for converting +@@ -1242,15 +1286,14 @@ + return wwn; + } + EXPORT_SYMBOL_GPL(fcoe_wwn_from_mac); +- +-/** +- * fcoe_hostlist_lookup_softc() - find the corresponding lport by a given device ++/* ++ * fcoe_hostlist_lookup_softc - find the corresponding lport by a given device + * @device: this is currently ptr to net_device + * + * Returns: NULL or the located fcoe_softc + */ +-static struct fcoe_softc * +-fcoe_hostlist_lookup_softc(const struct net_device *dev) ++static struct fcoe_softc *fcoe_hostlist_lookup_softc( ++ const struct net_device *dev) + { + struct fcoe_softc *fc; + +@@ -1265,8 +1308,8 @@ + return NULL; + } + +-/** +- * fcoe_hostlist_lookup() - Find the corresponding lport by netdev ++/* ++ * fcoe_hostlist_lookup - find the corresponding lport by netdev + * @netdev: ptr to net_device + * + * Returns: 0 for success +@@ -1281,8 +1324,8 @@ + } + EXPORT_SYMBOL_GPL(fcoe_hostlist_lookup); + +-/** +- * fcoe_hostlist_add() - Add a lport to lports list ++/* ++ * fcoe_hostlist_add - add a lport to lports list + * @lp: ptr to the fc_lport to badded + * + * Returns: 0 for success +@@ -1293,7 +1336,7 @@ + + fc = fcoe_hostlist_lookup_softc(fcoe_netdev(lp)); + if (!fc) { +- fc = lport_priv(lp); ++ fc = fcoe_softc(lp); + write_lock_bh(&fcoe_hostlist_lock); + list_add_tail(&fc->list, &fcoe_hostlist); + write_unlock_bh(&fcoe_hostlist_lock); +@@ -1302,8 +1345,8 @@ + } + EXPORT_SYMBOL_GPL(fcoe_hostlist_add); + +-/** +- * fcoe_hostlist_remove() - remove a lport from lports list ++/* ++ * fcoe_hostlist_remove - remove a lport from lports list + * @lp: ptr to the fc_lport to badded + * + * Returns: 0 for success +@@ -1323,12 +1366,12 @@ + EXPORT_SYMBOL_GPL(fcoe_hostlist_remove); + + /** +- * fcoe_libfc_config() - sets up libfc related properties for lport ++ * fcoe_libfc_config - sets up libfc related properties for lport + * @lp: ptr to the fc_lport + * @tt: libfc function template + * + * Returns : 0 for success +- */ ++ **/ + int fcoe_libfc_config(struct fc_lport *lp, struct libfc_function_template *tt) + { + /* Set the function pointers set by the LLDD */ +@@ -1346,14 +1389,14 @@ + EXPORT_SYMBOL_GPL(fcoe_libfc_config); + + /** +- * fcoe_init() - fcoe module loading initialization ++ * fcoe_init - fcoe module loading initialization + * + * Initialization routine + * 1. Will create fc transport software structure + * 2. initialize the link list of port information structure + * + * Returns 0 on success, negative on failure +- */ ++ **/ + static int __init fcoe_init(void) + { + int cpu; +@@ -1390,6 +1433,7 @@ + } else { + fcoe_percpu[cpu] = NULL; + kfree(p); ++ + } + } + } +@@ -1399,9 +1443,11 @@ + */ + fcoe_dev_setup(); + +- setup_timer(&fcoe_timer, fcoe_watchdog, 0); +- +- mod_timer(&fcoe_timer, jiffies + (10 * HZ)); ++ init_timer(&fcoe_timer); ++ fcoe_timer.data = 0; ++ fcoe_timer.function = fcoe_watchdog; ++ fcoe_timer.expires = (jiffies + (10 * HZ)); ++ add_timer(&fcoe_timer); + + /* initiatlize the fcoe transport */ + fcoe_transport_init(); +@@ -1413,10 +1459,10 @@ + module_init(fcoe_init); + + /** +- * fcoe_exit() - fcoe module unloading cleanup ++ * fcoe_exit - fcoe module unloading cleanup + * + * Returns 0 on success, negative on failure +- */ ++ **/ + static void __exit fcoe_exit(void) + { + u32 idx; +@@ -1437,7 +1483,7 @@ + */ + del_timer_sync(&fcoe_timer); + +- /* releases the associated fcoe transport for each lport */ ++ /* releases the assocaited fcoe transport for each lport */ + list_for_each_entry_safe(fc, tmp, &fcoe_hostlist, list) + fcoe_transport_release(fc->real_dev); + +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/drivers/scsi/hptiop.c linux-2.6.29-rc3.owrt/drivers/scsi/hptiop.c +--- linux-2.6.29.owrt/drivers/scsi/hptiop.c 2009-05-10 22:04:39.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/drivers/scsi/hptiop.c 2009-05-10 23:48:29.000000000 +0200 +@@ -1251,7 +1251,6 @@ + { PCI_VDEVICE(TTI, 0x3530), (kernel_ulong_t)&hptiop_itl_ops }, + { PCI_VDEVICE(TTI, 0x3560), (kernel_ulong_t)&hptiop_itl_ops }, + { PCI_VDEVICE(TTI, 0x4322), (kernel_ulong_t)&hptiop_itl_ops }, +- { PCI_VDEVICE(TTI, 0x4321), (kernel_ulong_t)&hptiop_itl_ops }, + { PCI_VDEVICE(TTI, 0x4210), (kernel_ulong_t)&hptiop_itl_ops }, + { PCI_VDEVICE(TTI, 0x4211), (kernel_ulong_t)&hptiop_itl_ops }, + { PCI_VDEVICE(TTI, 0x4310), (kernel_ulong_t)&hptiop_itl_ops }, +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/drivers/scsi/ibmvscsi/ibmvfc.c linux-2.6.29-rc3.owrt/drivers/scsi/ibmvscsi/ibmvfc.c +--- linux-2.6.29.owrt/drivers/scsi/ibmvscsi/ibmvfc.c 2009-05-10 22:04:39.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/drivers/scsi/ibmvscsi/ibmvfc.c 2009-05-10 23:48:29.000000000 +0200 +@@ -1573,6 +1573,9 @@ + vfc_cmd->resp_len = sizeof(vfc_cmd->rsp); + vfc_cmd->cancel_key = (unsigned long)cmnd->device->hostdata; + vfc_cmd->tgt_scsi_id = rport->port_id; ++ if ((rport->supported_classes & FC_COS_CLASS3) && ++ (fc_host_supported_classes(vhost->host) & FC_COS_CLASS3)) ++ vfc_cmd->flags = IBMVFC_CLASS_3_ERR; + vfc_cmd->iu.xfer_len = scsi_bufflen(cmnd); + int_to_scsilun(cmnd->device->lun, &vfc_cmd->iu.lun); + memcpy(vfc_cmd->iu.cdb, cmnd->cmnd, cmnd->cmd_len); +@@ -3263,7 +3266,6 @@ + return -ENOMEM; + } + +- memset(tgt, 0, sizeof(*tgt)); + tgt->scsi_id = scsi_id; + tgt->new_scsi_id = scsi_id; + tgt->vhost = vhost; +@@ -3574,18 +3576,9 @@ + static void ibmvfc_tgt_add_rport(struct ibmvfc_target *tgt) + { + struct ibmvfc_host *vhost = tgt->vhost; +- struct fc_rport *rport = tgt->rport; ++ struct fc_rport *rport; + unsigned long flags; + +- if (rport) { +- tgt_dbg(tgt, "Setting rport roles\n"); +- fc_remote_port_rolechg(rport, tgt->ids.roles); +- spin_lock_irqsave(vhost->host->host_lock, flags); +- ibmvfc_set_tgt_action(tgt, IBMVFC_TGT_ACTION_NONE); +- spin_unlock_irqrestore(vhost->host->host_lock, flags); +- return; +- } +- + tgt_dbg(tgt, "Adding rport\n"); + rport = fc_remote_port_add(vhost->host, 0, &tgt->ids); + spin_lock_irqsave(vhost->host->host_lock, flags); +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/drivers/scsi/ibmvscsi/ibmvfc.h linux-2.6.29-rc3.owrt/drivers/scsi/ibmvscsi/ibmvfc.h +--- linux-2.6.29.owrt/drivers/scsi/ibmvscsi/ibmvfc.h 2009-05-10 22:04:39.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/drivers/scsi/ibmvscsi/ibmvfc.h 2009-05-10 23:48:29.000000000 +0200 +@@ -32,7 +32,7 @@ + #define IBMVFC_DRIVER_VERSION "1.0.4" + #define IBMVFC_DRIVER_DATE "(November 14, 2008)" + +-#define IBMVFC_DEFAULT_TIMEOUT 60 ++#define IBMVFC_DEFAULT_TIMEOUT 15 + #define IBMVFC_INIT_TIMEOUT 120 + #define IBMVFC_MAX_REQUESTS_DEFAULT 100 + +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/drivers/scsi/ibmvscsi/ibmvscsi.c linux-2.6.29-rc3.owrt/drivers/scsi/ibmvscsi/ibmvscsi.c +--- linux-2.6.29.owrt/drivers/scsi/ibmvscsi/ibmvscsi.c 2009-05-10 22:04:39.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/drivers/scsi/ibmvscsi/ibmvscsi.c 2009-05-10 23:48:29.000000000 +0200 +@@ -432,7 +432,6 @@ + sdev_printk(KERN_ERR, cmd->device, + "Can't allocate memory " + "for indirect table\n"); +- scsi_dma_unmap(cmd); + return 0; + } + } +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/drivers/scsi/lasi700.c linux-2.6.29-rc3.owrt/drivers/scsi/lasi700.c +--- linux-2.6.29.owrt/drivers/scsi/lasi700.c 2009-05-10 22:04:39.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/drivers/scsi/lasi700.c 2009-05-10 23:48:29.000000000 +0200 +@@ -103,7 +103,7 @@ + + hostdata = kzalloc(sizeof(*hostdata), GFP_KERNEL); + if (!hostdata) { +- dev_printk(KERN_ERR, &dev->dev, "Failed to allocate host data\n"); ++ dev_printk(KERN_ERR, dev, "Failed to allocate host data\n"); + return -ENOMEM; + } + +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/drivers/scsi/libfc/fc_disc.c linux-2.6.29-rc3.owrt/drivers/scsi/libfc/fc_disc.c +--- linux-2.6.29.owrt/drivers/scsi/libfc/fc_disc.c 2009-05-10 22:04:39.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/drivers/scsi/libfc/fc_disc.c 2009-05-10 23:48:29.000000000 +0200 +@@ -64,7 +64,7 @@ + static void fc_disc_restart(struct fc_disc *); + + /** +- * fc_disc_lookup_rport() - lookup a remote port by port_id ++ * fc_disc_lookup_rport - lookup a remote port by port_id + * @lport: Fibre Channel host port instance + * @port_id: remote port port_id to match + */ +@@ -92,7 +92,7 @@ + } + + /** +- * fc_disc_stop_rports() - delete all the remote ports associated with the lport ++ * fc_disc_stop_rports - delete all the remote ports associated with the lport + * @disc: The discovery job to stop rports on + * + * Locking Note: This function expects that the lport mutex is locked before +@@ -117,7 +117,7 @@ + } + + /** +- * fc_disc_rport_callback() - Event handler for rport events ++ * fc_disc_rport_callback - Event handler for rport events + * @lport: The lport which is receiving the event + * @rport: The rport which the event has occured on + * @event: The event that occured +@@ -151,7 +151,7 @@ + } + + /** +- * fc_disc_recv_rscn_req() - Handle Registered State Change Notification (RSCN) ++ * fc_disc_recv_rscn_req - Handle Registered State Change Notification (RSCN) + * @sp: Current sequence of the RSCN exchange + * @fp: RSCN Frame + * @lport: Fibre Channel host port instance +@@ -246,7 +246,7 @@ + list_del(&dp->peers); + rport = lport->tt.rport_lookup(lport, dp->ids.port_id); + if (rport) { +- rdata = rport->dd_data; ++ rdata = RPORT_TO_PRIV(rport); + list_del(&rdata->peers); + lport->tt.rport_logoff(rport); + } +@@ -265,7 +265,7 @@ + } + + /** +- * fc_disc_recv_req() - Handle incoming requests ++ * fc_disc_recv_req - Handle incoming requests + * @sp: Current sequence of the request exchange + * @fp: The frame + * @lport: The FC local port +@@ -294,7 +294,7 @@ + } + + /** +- * fc_disc_restart() - Restart discovery ++ * fc_disc_restart - Restart discovery + * @lport: FC discovery context + * + * Locking Note: This function expects that the disc mutex +@@ -322,7 +322,7 @@ + } + + /** +- * fc_disc_start() - Fibre Channel Target discovery ++ * fc_disc_start - Fibre Channel Target discovery + * @lport: FC local port + * + * Returns non-zero if discovery cannot be started. +@@ -383,7 +383,7 @@ + }; + + /** +- * fc_disc_new_target() - Handle new target found by discovery ++ * fc_disc_new_target - Handle new target found by discovery + * @lport: FC local port + * @rport: The previous FC remote port (NULL if new remote port) + * @ids: Identifiers for the new FC remote port +@@ -396,7 +396,7 @@ + struct fc_rport_identifiers *ids) + { + struct fc_lport *lport = disc->lport; +- struct fc_rport_libfc_priv *rdata; ++ struct fc_rport_libfc_priv *rp; + int error = 0; + + if (rport && ids->port_name) { +@@ -430,15 +430,15 @@ + dp.ids.port_name = ids->port_name; + dp.ids.node_name = ids->node_name; + dp.ids.roles = ids->roles; +- rport = lport->tt.rport_create(&dp); ++ rport = fc_rport_rogue_create(&dp); + } + if (!rport) + error = -ENOMEM; + } + if (rport) { +- rdata = rport->dd_data; +- rdata->ops = &fc_disc_rport_ops; +- rdata->rp_state = RPORT_ST_INIT; ++ rp = rport->dd_data; ++ rp->ops = &fc_disc_rport_ops; ++ rp->rp_state = RPORT_ST_INIT; + lport->tt.rport_login(rport); + } + } +@@ -446,20 +446,20 @@ + } + + /** +- * fc_disc_del_target() - Delete a target ++ * fc_disc_del_target - Delete a target + * @disc: FC discovery context + * @rport: The remote port to be removed + */ + static void fc_disc_del_target(struct fc_disc *disc, struct fc_rport *rport) + { + struct fc_lport *lport = disc->lport; +- struct fc_rport_libfc_priv *rdata = rport->dd_data; ++ struct fc_rport_libfc_priv *rdata = RPORT_TO_PRIV(rport); + list_del(&rdata->peers); + lport->tt.rport_logoff(rport); + } + + /** +- * fc_disc_done() - Discovery has been completed ++ * fc_disc_done - Discovery has been completed + * @disc: FC discovery context + */ + static void fc_disc_done(struct fc_disc *disc) +@@ -479,7 +479,7 @@ + } + + /** +- * fc_disc_error() - Handle error on dNS request ++ * fc_disc_error - Handle error on dNS request + * @disc: FC discovery context + * @fp: The frame pointer + */ +@@ -519,7 +519,7 @@ + } + + /** +- * fc_disc_gpn_ft_req() - Send Get Port Names by FC-4 type (GPN_FT) request ++ * fc_disc_gpn_ft_req - Send Get Port Names by FC-4 type (GPN_FT) request + * @lport: FC discovery context + * + * Locking Note: This function expects that the disc_mutex is locked +@@ -553,7 +553,7 @@ + } + + /** +- * fc_disc_gpn_ft_parse() - Parse the list of IDs and names resulting from a request ++ * fc_disc_gpn_ft_parse - Parse the list of IDs and names resulting from a request + * @lport: Fibre Channel host port instance + * @buf: GPN_FT response buffer + * @len: size of response buffer +@@ -617,7 +617,7 @@ + + if ((dp.ids.port_id != fc_host_port_id(lport->host)) && + (dp.ids.port_name != lport->wwpn)) { +- rport = lport->tt.rport_create(&dp); ++ rport = fc_rport_rogue_create(&dp); + if (rport) { + rdata = rport->dd_data; + rdata->ops = &fc_disc_rport_ops; +@@ -658,10 +658,7 @@ + return error; + } + +-/** +- * fc_disc_timeout() - Retry handler for the disc component +- * @work: Structure holding disc obj that needs retry discovery +- * ++/* + * Handle retry of memory allocation for remote ports. + */ + static void fc_disc_timeout(struct work_struct *work) +@@ -676,7 +673,7 @@ + } + + /** +- * fc_disc_gpn_ft_resp() - Handle a response frame from Get Port Names (GPN_FT) ++ * fc_disc_gpn_ft_resp - Handle a response frame from Get Port Names (GPN_FT) + * @sp: Current sequence of GPN_FT exchange + * @fp: response frame + * @lp_arg: Fibre Channel host port instance +@@ -715,7 +712,9 @@ + fr_len(fp)); + } else if (ntohs(cp->ct_cmd) == FC_FS_ACC) { + +- /* Accepted, parse the response. */ ++ /* ++ * Accepted. Parse response. ++ */ + buf = cp + 1; + len -= sizeof(*cp); + } else if (ntohs(cp->ct_cmd) == FC_FS_RJT) { +@@ -747,7 +746,7 @@ + } + + /** +- * fc_disc_single() - Discover the directory information for a single target ++ * fc_disc_single - Discover the directory information for a single target + * @lport: FC local port + * @dp: The port to rediscover + * +@@ -770,7 +769,7 @@ + if (rport) + fc_disc_del_target(disc, rport); + +- new_rport = lport->tt.rport_create(dp); ++ new_rport = fc_rport_rogue_create(dp); + if (new_rport) { + rdata = new_rport->dd_data; + rdata->ops = &fc_disc_rport_ops; +@@ -783,7 +782,7 @@ + } + + /** +- * fc_disc_stop() - Stop discovery for a given lport ++ * fc_disc_stop - Stop discovery for a given lport + * @lport: The lport that discovery should stop for + */ + void fc_disc_stop(struct fc_lport *lport) +@@ -797,7 +796,7 @@ + } + + /** +- * fc_disc_stop_final() - Stop discovery for a given lport ++ * fc_disc_stop_final - Stop discovery for a given lport + * @lport: The lport that discovery should stop for + * + * This function will block until discovery has been +@@ -810,7 +809,7 @@ + } + + /** +- * fc_disc_init() - Initialize the discovery block ++ * fc_disc_init - Initialize the discovery block + * @lport: FC local port + */ + int fc_disc_init(struct fc_lport *lport) +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/drivers/scsi/libfc/fc_exch.c linux-2.6.29-rc3.owrt/drivers/scsi/libfc/fc_exch.c +--- linux-2.6.29.owrt/drivers/scsi/libfc/fc_exch.c 2009-05-10 22:04:39.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/drivers/scsi/libfc/fc_exch.c 2009-05-10 23:48:29.000000000 +0200 +@@ -32,6 +32,8 @@ + #include <scsi/libfc.h> + #include <scsi/fc_encode.h> + ++#define FC_DEF_R_A_TOV (10 * 1000) /* resource allocation timeout */ ++ + /* + * fc_exch_debug can be set in debugger or at compile time to get more logs. + */ +@@ -625,6 +627,7 @@ + { + struct fc_exch *ep; + struct fc_frame_header *fh; ++ u16 rxid; + + ep = mp->lp->tt.exch_get(mp->lp, fp); + if (ep) { +@@ -651,6 +654,18 @@ + if ((ntoh24(fh->fh_f_ctl) & FC_FC_SEQ_INIT) == 0) + ep->esb_stat &= ~ESB_ST_SEQ_INIT; + ++ /* ++ * Set the responder ID in the frame header. ++ * The old one should've been 0xffff. ++ * If it isn't, don't assign one. ++ * Incoming basic link service frames may specify ++ * a referenced RX_ID. ++ */ ++ if (fh->fh_type != FC_TYPE_BLS) { ++ rxid = ntohs(fh->fh_rx_id); ++ WARN_ON(rxid != FC_XID_UNKNOWN); ++ fh->fh_rx_id = htons(ep->rxid); ++ } + fc_exch_hold(ep); /* hold for caller */ + spin_unlock_bh(&ep->ex_lock); /* lock from exch_get */ + } +@@ -662,8 +677,8 @@ + * If fc_pf_rjt_reason is FC_RJT_NONE then this function will have a hold + * on the ep that should be released by the caller. + */ +-static enum fc_pf_rjt_reason fc_seq_lookup_recip(struct fc_exch_mgr *mp, +- struct fc_frame *fp) ++static enum fc_pf_rjt_reason ++fc_seq_lookup_recip(struct fc_exch_mgr *mp, struct fc_frame *fp) + { + struct fc_frame_header *fh = fc_frame_header_get(fp); + struct fc_exch *ep = NULL; +@@ -981,9 +996,9 @@ + * Send BLS Reject. + * This is for rejecting BA_ABTS only. + */ +-static void fc_exch_send_ba_rjt(struct fc_frame *rx_fp, +- enum fc_ba_rjt_reason reason, +- enum fc_ba_rjt_explan explan) ++static void ++fc_exch_send_ba_rjt(struct fc_frame *rx_fp, enum fc_ba_rjt_reason reason, ++ enum fc_ba_rjt_explan explan) + { + struct fc_frame *fp; + struct fc_frame_header *rx_fh; +@@ -1081,7 +1096,7 @@ + ap->ba_high_seq_cnt = fh->fh_seq_cnt; + ap->ba_low_seq_cnt = htons(sp->cnt); + } +- sp = fc_seq_start_next_locked(sp); ++ sp = fc_seq_start_next(sp); + spin_unlock_bh(&ep->ex_lock); + fc_seq_send_last(sp, fp, FC_RCTL_BA_ACC, FC_TYPE_BLS); + fc_frame_free(rx_fp); +@@ -1465,11 +1480,10 @@ + * If sid is non-zero, reset only exchanges we source from that FID. + * If did is non-zero, reset only exchanges destined to that FID. + */ +-void fc_exch_mgr_reset(struct fc_lport *lp, u32 sid, u32 did) ++void fc_exch_mgr_reset(struct fc_exch_mgr *mp, u32 sid, u32 did) + { + struct fc_exch *ep; + struct fc_exch *next; +- struct fc_exch_mgr *mp = lp->emp; + + spin_lock_bh(&mp->em_lock); + restart: +@@ -1593,7 +1607,7 @@ + if (IS_ERR(fp)) { + int err = PTR_ERR(fp); + +- if (err == -FC_EX_CLOSED || err == -FC_EX_TIMEOUT) ++ if (err == -FC_EX_CLOSED) + goto cleanup; + FC_DBG("Cannot process RRQ, because of frame error %d\n", err); + return; +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/drivers/scsi/libfc/fc_fcp.c linux-2.6.29-rc3.owrt/drivers/scsi/libfc/fc_fcp.c +--- linux-2.6.29.owrt/drivers/scsi/libfc/fc_fcp.c 2009-05-10 22:04:39.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/drivers/scsi/libfc/fc_fcp.c 2009-05-10 23:48:29.000000000 +0200 +@@ -161,7 +161,7 @@ + } + + /** +- * fc_fcp_pkt_release() - release hold on scsi_pkt packet ++ * fc_fcp_pkt_release - release hold on scsi_pkt packet + * @fsp: fcp packet struct + * + * This is used by upper layer scsi driver. +@@ -183,7 +183,8 @@ + } + + /** +- * fc_fcp_pkt_destory() - release hold on scsi_pkt packet ++ * fc_fcp_pkt_destory - release hold on scsi_pkt packet ++ * + * @seq: exchange sequence + * @fsp: fcp packet struct + * +@@ -198,7 +199,7 @@ + } + + /** +- * fc_fcp_lock_pkt() - lock a packet and get a ref to it. ++ * fc_fcp_lock_pkt - lock a packet and get a ref to it. + * @fsp: fcp packet + * + * We should only return error if we return a command to scsi-ml before +@@ -290,7 +291,9 @@ + buf = fc_frame_payload_get(fp, 0); + + if (offset + len > fsp->data_len) { +- /* this should never happen */ ++ /* ++ * this should never happen ++ */ + if ((fr_flags(fp) & FCPHF_CRC_UNCHECKED) && + fc_frame_crc_check(fp)) + goto crc_err; +@@ -384,8 +387,8 @@ + fc_fcp_complete_locked(fsp); + } + +-/** +- * fc_fcp_send_data() - Send SCSI data to target. ++/* ++ * fc_fcp_send_data - Send SCSI data to target. + * @fsp: ptr to fc_fcp_pkt + * @sp: ptr to this sequence + * @offset: starting offset for this data request +@@ -607,8 +610,8 @@ + } + } + +-/** +- * fc_fcp_reduce_can_queue() - drop can_queue ++/* ++ * fc_fcp_reduce_can_queue - drop can_queue + * @lp: lport to drop queueing for + * + * If we are getting memory allocation failures, then we may +@@ -639,11 +642,9 @@ + spin_unlock_irqrestore(lp->host->host_lock, flags); + } + +-/** +- * fc_fcp_recv() - Reveive FCP frames +- * @seq: The sequence the frame is on +- * @fp: The FC frame +- * @arg: The related FCP packet ++/* ++ * exch mgr calls this routine to process scsi ++ * exchanges. + * + * Return : None + * Context : called from Soft IRQ context +@@ -831,7 +832,7 @@ + } + + /** +- * fc_fcp_complete_locked() - complete processing of a fcp packet ++ * fc_fcp_complete_locked - complete processing of a fcp packet + * @fsp: fcp packet + * + * This function may sleep if a timer is pending. The packet lock must be +@@ -899,7 +900,7 @@ + } + + /** +- * fc_fcp_cleanup_each_cmd() - Cleanup active commads ++ * fc_fcp_cleanup_each_cmd - run fn on each active command + * @lp: logical port + * @id: target id + * @lun: lun +@@ -951,7 +952,7 @@ + } + + /** +- * fc_fcp_pkt_send() - send a fcp packet to the lower level. ++ * fc_fcp_pkt_send - send a fcp packet to the lower level. + * @lp: fc lport + * @fsp: fc packet. + * +@@ -1620,7 +1621,7 @@ + static inline int fc_fcp_lport_queue_ready(struct fc_lport *lp) + { + /* lock ? */ +- return (lp->state == LPORT_ST_READY) && lp->link_up && !lp->qfull; ++ return (lp->state == LPORT_ST_READY) && (lp->link_status & FC_LINK_UP); + } + + /** +@@ -1726,7 +1727,7 @@ + EXPORT_SYMBOL(fc_queuecommand); + + /** +- * fc_io_compl() - Handle responses for completed commands ++ * fc_io_compl - Handle responses for completed commands + * @fsp: scsi packet + * + * Translates a error to a Linux SCSI error. +@@ -1809,12 +1810,12 @@ + sc_cmd->result = DID_ERROR << 16; + break; + case FC_DATA_UNDRUN: +- if ((fsp->cdb_status == 0) && !(fsp->req_flags & FC_SRB_READ)) { ++ if (fsp->cdb_status == 0) { + /* + * scsi status is good but transport level +- * underrun. ++ * underrun. for read it should be an error?? + */ +- sc_cmd->result = DID_OK << 16; ++ sc_cmd->result = (DID_OK << 16) | fsp->cdb_status; + } else { + /* + * scsi got underrun, this is an error +@@ -1856,7 +1857,7 @@ + } + + /** +- * fc_fcp_complete() - complete processing of a fcp packet ++ * fc_fcp_complete - complete processing of a fcp packet + * @fsp: fcp packet + * + * This function may sleep if a fsp timer is pending. +@@ -1873,10 +1874,9 @@ + EXPORT_SYMBOL(fc_fcp_complete); + + /** +- * fc_eh_abort() - Abort a command ++ * fc_eh_abort - Abort a command...from scsi host template + * @sc_cmd: scsi command to abort + * +- * From scsi host template. + * send ABTS to the target device and wait for the response + * sc_cmd is the pointer to the command to be aborted. + */ +@@ -1890,7 +1890,7 @@ + lp = shost_priv(sc_cmd->device->host); + if (lp->state != LPORT_ST_READY) + return rc; +- else if (!lp->link_up) ++ else if (!(lp->link_status & FC_LINK_UP)) + return rc; + + spin_lock_irqsave(lp->host->host_lock, flags); +@@ -1920,7 +1920,7 @@ + EXPORT_SYMBOL(fc_eh_abort); + + /** +- * fc_eh_device_reset() Reset a single LUN ++ * fc_eh_device_reset: Reset a single LUN + * @sc_cmd: scsi command + * + * Set from scsi host template to send tm cmd to the target and wait for the +@@ -1973,7 +1973,7 @@ + EXPORT_SYMBOL(fc_eh_device_reset); + + /** +- * fc_eh_host_reset() - The reset function will reset the ports on the host. ++ * fc_eh_host_reset - The reset function will reset the ports on the host. + * @sc_cmd: scsi command + */ + int fc_eh_host_reset(struct scsi_cmnd *sc_cmd) +@@ -1999,7 +1999,7 @@ + EXPORT_SYMBOL(fc_eh_host_reset); + + /** +- * fc_slave_alloc() - configure queue depth ++ * fc_slave_alloc - configure queue depth + * @sdev: scsi device + * + * Configures queue depth based on host's cmd_per_len. If not set +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/drivers/scsi/libfc/fc_lport.c linux-2.6.29-rc3.owrt/drivers/scsi/libfc/fc_lport.c +--- linux-2.6.29.owrt/drivers/scsi/libfc/fc_lport.c 2009-05-10 22:04:39.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/drivers/scsi/libfc/fc_lport.c 2009-05-10 23:48:29.000000000 +0200 +@@ -139,7 +139,7 @@ + } + + /** +- * fc_lport_rport_callback() - Event handler for rport events ++ * fc_lport_rport_callback - Event handler for rport events + * @lport: The lport which is receiving the event + * @rport: The rport which the event has occured on + * @event: The event that occured +@@ -195,7 +195,7 @@ + } + + /** +- * fc_lport_state() - Return a string which represents the lport's state ++ * fc_lport_state - Return a string which represents the lport's state + * @lport: The lport whose state is to converted to a string + */ + static const char *fc_lport_state(struct fc_lport *lport) +@@ -209,7 +209,7 @@ + } + + /** +- * fc_lport_ptp_setup() - Create an rport for point-to-point mode ++ * fc_lport_ptp_setup - Create an rport for point-to-point mode + * @lport: The lport to attach the ptp rport to + * @fid: The FID of the ptp rport + * @remote_wwpn: The WWPN of the ptp rport +@@ -232,7 +232,7 @@ + lport->ptp_rp = NULL; + } + +- lport->ptp_rp = lport->tt.rport_create(&dp); ++ lport->ptp_rp = fc_rport_rogue_create(&dp); + + lport->tt.rport_login(lport->ptp_rp); + +@@ -250,7 +250,7 @@ + { + struct fc_lport *lp = shost_priv(shost); + +- if (lp->link_up) ++ if ((lp->link_status & FC_LINK_UP) == FC_LINK_UP) + fc_host_port_state(shost) = FC_PORTSTATE_ONLINE; + else + fc_host_port_state(shost) = FC_PORTSTATE_OFFLINE; +@@ -351,7 +351,7 @@ + } + + /** +- * fc_lport_recv_rlir_req() - Handle received Registered Link Incident Report. ++ * fc_lport_recv_rlir_req - Handle received Registered Link Incident Report. + * @lport: Fibre Channel local port recieving the RLIR + * @sp: current sequence in the RLIR exchange + * @fp: RLIR request frame +@@ -370,7 +370,7 @@ + } + + /** +- * fc_lport_recv_echo_req() - Handle received ECHO request ++ * fc_lport_recv_echo_req - Handle received ECHO request + * @lport: Fibre Channel local port recieving the ECHO + * @sp: current sequence in the ECHO exchange + * @fp: ECHO request frame +@@ -412,7 +412,7 @@ + } + + /** +- * fc_lport_recv_echo_req() - Handle received Request Node ID data request ++ * fc_lport_recv_echo_req - Handle received Request Node ID data request + * @lport: Fibre Channel local port recieving the RNID + * @sp: current sequence in the RNID exchange + * @fp: RNID request frame +@@ -479,7 +479,7 @@ + } + + /** +- * fc_lport_recv_adisc_req() - Handle received Address Discovery Request ++ * fc_lport_recv_adisc_req - Handle received Address Discovery Request + * @lport: Fibre Channel local port recieving the ADISC + * @sp: current sequence in the ADISC exchange + * @fp: ADISC request frame +@@ -529,7 +529,7 @@ + } + + /** +- * fc_lport_recv_logo_req() - Handle received fabric LOGO request ++ * fc_lport_recv_logo_req - Handle received fabric LOGO request + * @lport: Fibre Channel local port recieving the LOGO + * @sp: current sequence in the LOGO exchange + * @fp: LOGO request frame +@@ -546,7 +546,7 @@ + } + + /** +- * fc_fabric_login() - Start the lport state machine ++ * fc_fabric_login - Start the lport state machine + * @lport: The lport that should log into the fabric + * + * Locking Note: This function should not be called +@@ -568,7 +568,7 @@ + EXPORT_SYMBOL(fc_fabric_login); + + /** +- * fc_linkup() - Handler for transport linkup events ++ * fc_linkup - Handler for transport linkup events + * @lport: The lport whose link is up + */ + void fc_linkup(struct fc_lport *lport) +@@ -577,8 +577,8 @@ + fc_host_port_id(lport->host)); + + mutex_lock(&lport->lp_mutex); +- if (!lport->link_up) { +- lport->link_up = 1; ++ if ((lport->link_status & FC_LINK_UP) != FC_LINK_UP) { ++ lport->link_status |= FC_LINK_UP; + + if (lport->state == LPORT_ST_RESET) + fc_lport_enter_flogi(lport); +@@ -588,7 +588,7 @@ + EXPORT_SYMBOL(fc_linkup); + + /** +- * fc_linkdown() - Handler for transport linkdown events ++ * fc_linkdown - Handler for transport linkdown events + * @lport: The lport whose link is down + */ + void fc_linkdown(struct fc_lport *lport) +@@ -597,8 +597,8 @@ + FC_DEBUG_LPORT("Link is down for port (%6x)\n", + fc_host_port_id(lport->host)); + +- if (lport->link_up) { +- lport->link_up = 0; ++ if ((lport->link_status & FC_LINK_UP) == FC_LINK_UP) { ++ lport->link_status &= ~(FC_LINK_UP); + fc_lport_enter_reset(lport); + lport->tt.fcp_cleanup(lport); + } +@@ -607,25 +607,48 @@ + EXPORT_SYMBOL(fc_linkdown); + + /** +- * fc_fabric_logoff() - Logout of the fabric ++ * fc_pause - Pause the flow of frames ++ * @lport: The lport to be paused ++ */ ++void fc_pause(struct fc_lport *lport) ++{ ++ mutex_lock(&lport->lp_mutex); ++ lport->link_status |= FC_PAUSE; ++ mutex_unlock(&lport->lp_mutex); ++} ++EXPORT_SYMBOL(fc_pause); ++ ++/** ++ * fc_unpause - Unpause the flow of frames ++ * @lport: The lport to be unpaused ++ */ ++void fc_unpause(struct fc_lport *lport) ++{ ++ mutex_lock(&lport->lp_mutex); ++ lport->link_status &= ~(FC_PAUSE); ++ mutex_unlock(&lport->lp_mutex); ++} ++EXPORT_SYMBOL(fc_unpause); ++ ++/** ++ * fc_fabric_logoff - Logout of the fabric + * @lport: fc_lport pointer to logoff the fabric + * + * Return value: + * 0 for success, -1 for failure +- */ ++ **/ + int fc_fabric_logoff(struct fc_lport *lport) + { + lport->tt.disc_stop_final(lport); + mutex_lock(&lport->lp_mutex); + fc_lport_enter_logo(lport); + mutex_unlock(&lport->lp_mutex); +- cancel_delayed_work_sync(&lport->retry_work); + return 0; + } + EXPORT_SYMBOL(fc_fabric_logoff); + + /** +- * fc_lport_destroy() - unregister a fc_lport ++ * fc_lport_destroy - unregister a fc_lport + * @lport: fc_lport pointer to unregister + * + * Return value: +@@ -635,25 +658,26 @@ + * clean-up all the allocated memory + * and free up other system resources. + * +- */ ++ **/ + int fc_lport_destroy(struct fc_lport *lport) + { + lport->tt.frame_send = fc_frame_drop; + lport->tt.fcp_abort_io(lport); +- lport->tt.exch_mgr_reset(lport, 0, 0); ++ lport->tt.exch_mgr_reset(lport->emp, 0, 0); + return 0; + } + EXPORT_SYMBOL(fc_lport_destroy); + + /** +- * fc_set_mfs() - sets up the mfs for the corresponding fc_lport ++ * fc_set_mfs - sets up the mfs for the corresponding fc_lport + * @lport: fc_lport pointer to unregister + * @mfs: the new mfs for fc_lport + * + * Set mfs for the given fc_lport to the new mfs. + * + * Return: 0 for success +- */ ++ * ++ **/ + int fc_set_mfs(struct fc_lport *lport, u32 mfs) + { + unsigned int old_mfs; +@@ -682,7 +706,7 @@ + EXPORT_SYMBOL(fc_set_mfs); + + /** +- * fc_lport_disc_callback() - Callback for discovery events ++ * fc_lport_disc_callback - Callback for discovery events + * @lport: FC local port + * @event: The discovery event + */ +@@ -707,7 +731,7 @@ + } + + /** +- * fc_rport_enter_ready() - Enter the ready state and start discovery ++ * fc_rport_enter_ready - Enter the ready state and start discovery + * @lport: Fibre Channel local port that is ready + * + * Locking Note: The lport lock is expected to be held before calling +@@ -724,7 +748,7 @@ + } + + /** +- * fc_lport_recv_flogi_req() - Receive a FLOGI request ++ * fc_lport_recv_flogi_req - Receive a FLOGI request + * @sp_in: The sequence the FLOGI is on + * @rx_fp: The frame the FLOGI is in + * @lport: The lport that recieved the request +@@ -814,7 +838,7 @@ + } + + /** +- * fc_lport_recv_req() - The generic lport request handler ++ * fc_lport_recv_req - The generic lport request handler + * @lport: The lport that received the request + * @sp: The sequence the request is on + * @fp: The frame the request is in +@@ -910,7 +934,7 @@ + } + + /** +- * fc_lport_reset() - Reset an lport ++ * fc_lport_reset - Reset an lport + * @lport: The lport which should be reset + * + * Locking Note: This functions should not be called with the +@@ -918,7 +942,6 @@ + */ + int fc_lport_reset(struct fc_lport *lport) + { +- cancel_delayed_work_sync(&lport->retry_work); + mutex_lock(&lport->lp_mutex); + fc_lport_enter_reset(lport); + mutex_unlock(&lport->lp_mutex); +@@ -927,7 +950,7 @@ + EXPORT_SYMBOL(fc_lport_reset); + + /** +- * fc_rport_enter_reset() - Reset the local port ++ * fc_rport_enter_reset - Reset the local port + * @lport: Fibre Channel local port to be reset + * + * Locking Note: The lport lock is expected to be held before calling +@@ -950,16 +973,16 @@ + + lport->tt.disc_stop(lport); + +- lport->tt.exch_mgr_reset(lport, 0, 0); ++ lport->tt.exch_mgr_reset(lport->emp, 0, 0); + fc_host_fabric_name(lport->host) = 0; + fc_host_port_id(lport->host) = 0; + +- if (lport->link_up) ++ if ((lport->link_status & FC_LINK_UP) == FC_LINK_UP) + fc_lport_enter_flogi(lport); + } + + /** +- * fc_lport_error() - Handler for any errors ++ * fc_lport_error - Handler for any errors + * @lport: The fc_lport object + * @fp: The frame pointer + * +@@ -1006,8 +1029,8 @@ + } + + /** +- * fc_lport_rft_id_resp() - Handle response to Register Fibre +- * Channel Types by ID (RPN_ID) request ++ * fc_lport_rft_id_resp - Handle response to Register Fibre ++ * Channel Types by ID (RPN_ID) request + * @sp: current sequence in RPN_ID exchange + * @fp: response frame + * @lp_arg: Fibre Channel host port instance +@@ -1030,17 +1053,17 @@ + + FC_DEBUG_LPORT("Received a RFT_ID response\n"); + +- if (IS_ERR(fp)) { +- fc_lport_error(lport, fp); +- goto err; +- } +- + if (lport->state != LPORT_ST_RFT_ID) { + FC_DBG("Received a RFT_ID response, but in state %s\n", + fc_lport_state(lport)); + goto out; + } + ++ if (IS_ERR(fp)) { ++ fc_lport_error(lport, fp); ++ goto err; ++ } ++ + fh = fc_frame_header_get(fp); + ct = fc_frame_payload_get(fp, sizeof(*ct)); + +@@ -1058,8 +1081,8 @@ + } + + /** +- * fc_lport_rpn_id_resp() - Handle response to Register Port +- * Name by ID (RPN_ID) request ++ * fc_lport_rpn_id_resp - Handle response to Register Port ++ * Name by ID (RPN_ID) request + * @sp: current sequence in RPN_ID exchange + * @fp: response frame + * @lp_arg: Fibre Channel host port instance +@@ -1082,17 +1105,17 @@ + + FC_DEBUG_LPORT("Received a RPN_ID response\n"); + +- if (IS_ERR(fp)) { +- fc_lport_error(lport, fp); +- goto err; +- } +- + if (lport->state != LPORT_ST_RPN_ID) { + FC_DBG("Received a RPN_ID response, but in state %s\n", + fc_lport_state(lport)); + goto out; + } + ++ if (IS_ERR(fp)) { ++ fc_lport_error(lport, fp); ++ goto err; ++ } ++ + fh = fc_frame_header_get(fp); + ct = fc_frame_payload_get(fp, sizeof(*ct)); + if (fh && ct && fh->fh_type == FC_TYPE_CT && +@@ -1110,7 +1133,7 @@ + } + + /** +- * fc_lport_scr_resp() - Handle response to State Change Register (SCR) request ++ * fc_lport_scr_resp - Handle response to State Change Register (SCR) request + * @sp: current sequence in SCR exchange + * @fp: response frame + * @lp_arg: Fibre Channel lport port instance that sent the registration request +@@ -1132,17 +1155,17 @@ + + FC_DEBUG_LPORT("Received a SCR response\n"); + +- if (IS_ERR(fp)) { +- fc_lport_error(lport, fp); +- goto err; +- } +- + if (lport->state != LPORT_ST_SCR) { + FC_DBG("Received a SCR response, but in state %s\n", + fc_lport_state(lport)); + goto out; + } + ++ if (IS_ERR(fp)) { ++ fc_lport_error(lport, fp); ++ goto err; ++ } ++ + op = fc_frame_payload_op(fp); + if (op == ELS_LS_ACC) + fc_lport_enter_ready(lport); +@@ -1156,7 +1179,7 @@ + } + + /** +- * fc_lport_enter_scr() - Send a State Change Register (SCR) request ++ * fc_lport_enter_scr - Send a State Change Register (SCR) request + * @lport: Fibre Channel local port to register for state changes + * + * Locking Note: The lport lock is expected to be held before calling +@@ -1183,7 +1206,7 @@ + } + + /** +- * fc_lport_enter_rft_id() - Register FC4-types with the name server ++ * fc_lport_enter_rft_id - Register FC4-types with the name server + * @lport: Fibre Channel local port to register + * + * Locking Note: The lport lock is expected to be held before calling +@@ -1225,7 +1248,7 @@ + } + + /** +- * fc_rport_enter_rft_id() - Register port name with the name server ++ * fc_rport_enter_rft_id - Register port name with the name server + * @lport: Fibre Channel local port to register + * + * Locking Note: The lport lock is expected to be held before calling +@@ -1258,7 +1281,7 @@ + }; + + /** +- * fc_rport_enter_dns() - Create a rport to the name server ++ * fc_rport_enter_dns - Create a rport to the name server + * @lport: Fibre Channel local port requesting a rport for the name server + * + * Locking Note: The lport lock is expected to be held before calling +@@ -1281,7 +1304,7 @@ + + fc_lport_state_enter(lport, LPORT_ST_DNS); + +- rport = lport->tt.rport_create(&dp); ++ rport = fc_rport_rogue_create(&dp); + if (!rport) + goto err; + +@@ -1295,7 +1318,7 @@ + } + + /** +- * fc_lport_timeout() - Handler for the retry_work timer. ++ * fc_lport_timeout - Handler for the retry_work timer. + * @work: The work struct of the fc_lport + */ + static void fc_lport_timeout(struct work_struct *work) +@@ -1336,7 +1359,7 @@ + } + + /** +- * fc_lport_logo_resp() - Handle response to LOGO request ++ * fc_lport_logo_resp - Handle response to LOGO request + * @sp: current sequence in LOGO exchange + * @fp: response frame + * @lp_arg: Fibre Channel lport port instance that sent the LOGO request +@@ -1358,17 +1381,17 @@ + + FC_DEBUG_LPORT("Received a LOGO response\n"); + +- if (IS_ERR(fp)) { +- fc_lport_error(lport, fp); +- goto err; +- } +- + if (lport->state != LPORT_ST_LOGO) { + FC_DBG("Received a LOGO response, but in state %s\n", + fc_lport_state(lport)); + goto out; + } + ++ if (IS_ERR(fp)) { ++ fc_lport_error(lport, fp); ++ goto err; ++ } ++ + op = fc_frame_payload_op(fp); + if (op == ELS_LS_ACC) + fc_lport_enter_reset(lport); +@@ -1382,7 +1405,7 @@ + } + + /** +- * fc_rport_enter_logo() - Logout of the fabric ++ * fc_rport_enter_logo - Logout of the fabric + * @lport: Fibre Channel local port to be logged out + * + * Locking Note: The lport lock is expected to be held before calling +@@ -1414,7 +1437,7 @@ + } + + /** +- * fc_lport_flogi_resp() - Handle response to FLOGI request ++ * fc_lport_flogi_resp - Handle response to FLOGI request + * @sp: current sequence in FLOGI exchange + * @fp: response frame + * @lp_arg: Fibre Channel lport port instance that sent the FLOGI request +@@ -1442,17 +1465,17 @@ + + FC_DEBUG_LPORT("Received a FLOGI response\n"); + +- if (IS_ERR(fp)) { +- fc_lport_error(lport, fp); +- goto err; +- } +- + if (lport->state != LPORT_ST_FLOGI) { + FC_DBG("Received a FLOGI response, but in state %s\n", + fc_lport_state(lport)); + goto out; + } + ++ if (IS_ERR(fp)) { ++ fc_lport_error(lport, fp); ++ goto err; ++ } ++ + fh = fc_frame_header_get(fp); + did = ntoh24(fh->fh_d_id); + if (fc_frame_payload_op(fp) == ELS_LS_ACC && did != 0) { +@@ -1509,7 +1532,7 @@ + } + + /** +- * fc_rport_enter_flogi() - Send a FLOGI request to the fabric manager ++ * fc_rport_enter_flogi - Send a FLOGI request to the fabric manager + * @lport: Fibre Channel local port to be logged in to the fabric + * + * Locking Note: The lport lock is expected to be held before calling +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/drivers/scsi/libfc/fc_rport.c linux-2.6.29-rc3.owrt/drivers/scsi/libfc/fc_rport.c +--- linux-2.6.29.owrt/drivers/scsi/libfc/fc_rport.c 2009-05-10 22:04:39.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/drivers/scsi/libfc/fc_rport.c 2009-05-10 23:48:29.000000000 +0200 +@@ -81,7 +81,6 @@ + struct fc_seq *, struct fc_frame *); + static void fc_rport_timeout(struct work_struct *); + static void fc_rport_error(struct fc_rport *, struct fc_frame *); +-static void fc_rport_error_retry(struct fc_rport *, struct fc_frame *); + static void fc_rport_work(struct work_struct *); + + static const char *fc_rport_state_names[] = { +@@ -146,7 +145,7 @@ + } + + /** +- * fc_rport_state() - return a string for the state the rport is in ++ * fc_rport_state - return a string for the state the rport is in + * @rport: The rport whose state we want to get a string for + */ + static const char *fc_rport_state(struct fc_rport *rport) +@@ -161,7 +160,7 @@ + } + + /** +- * fc_set_rport_loss_tmo() - Set the remote port loss timeout in seconds. ++ * fc_set_rport_loss_tmo - Set the remote port loss timeout in seconds. + * @rport: Pointer to Fibre Channel remote port structure + * @timeout: timeout in seconds + */ +@@ -175,12 +174,12 @@ + EXPORT_SYMBOL(fc_set_rport_loss_tmo); + + /** +- * fc_plogi_get_maxframe() - Get max payload from the common service parameters ++ * fc_plogi_get_maxframe - Get max payload from the common service parameters + * @flp: FLOGI payload structure + * @maxval: upper limit, may be less than what is in the service parameters + */ +-static unsigned int fc_plogi_get_maxframe(struct fc_els_flogi *flp, +- unsigned int maxval) ++static unsigned int ++fc_plogi_get_maxframe(struct fc_els_flogi *flp, unsigned int maxval) + { + unsigned int mfs; + +@@ -198,7 +197,7 @@ + } + + /** +- * fc_rport_state_enter() - Change the rport's state ++ * fc_rport_state_enter - Change the rport's state + * @rport: The rport whose state should change + * @new: The new state of the rport + * +@@ -215,7 +214,6 @@ + + static void fc_rport_work(struct work_struct *work) + { +- u32 port_id; + struct fc_rport_libfc_priv *rdata = + container_of(work, struct fc_rport_libfc_priv, event_work); + enum fc_rport_event event; +@@ -281,18 +279,14 @@ + rport_ops->event_callback(lport, rport, event); + if (trans_state == FC_PORTSTATE_ROGUE) + put_device(&rport->dev); +- else { +- port_id = rport->port_id; ++ else + fc_remote_port_delete(rport); +- lport->tt.exch_mgr_reset(lport, 0, port_id); +- lport->tt.exch_mgr_reset(lport, port_id, 0); +- } + } else + mutex_unlock(&rdata->rp_mutex); + } + + /** +- * fc_rport_login() - Start the remote port login state machine ++ * fc_rport_login - Start the remote port login state machine + * @rport: Fibre Channel remote port + * + * Locking Note: Called without the rport lock held. This +@@ -315,7 +309,7 @@ + } + + /** +- * fc_rport_logoff() - Logoff and remove an rport ++ * fc_rport_logoff - Logoff and remove an rport + * @rport: Fibre Channel remote port to be removed + * + * Locking Note: Called without the rport lock held. This +@@ -353,7 +347,7 @@ + } + + /** +- * fc_rport_enter_ready() - The rport is ready ++ * fc_rport_enter_ready - The rport is ready + * @rport: Fibre Channel remote port that is ready + * + * Locking Note: The rport lock is expected to be held before calling +@@ -372,7 +366,7 @@ + } + + /** +- * fc_rport_timeout() - Handler for the retry_work timer. ++ * fc_rport_timeout - Handler for the retry_work timer. + * @work: The work struct of the fc_rport_libfc_priv + * + * Locking Note: Called without the rport lock held. This +@@ -411,75 +405,59 @@ + } + + /** +- * fc_rport_error() - Error handler, called once retries have been exhausted ++ * fc_rport_error - Handler for any errors + * @rport: The fc_rport object + * @fp: The frame pointer + * ++ * If the error was caused by a resource allocation failure ++ * then wait for half a second and retry, otherwise retry ++ * immediately. ++ * + * Locking Note: The rport lock is expected to be held before + * calling this routine + */ + static void fc_rport_error(struct fc_rport *rport, struct fc_frame *fp) + { + struct fc_rport_libfc_priv *rdata = rport->dd_data; ++ unsigned long delay = 0; + + FC_DEBUG_RPORT("Error %ld in state %s, retries %d\n", + PTR_ERR(fp), fc_rport_state(rport), rdata->retries); + +- switch (rdata->rp_state) { +- case RPORT_ST_PLOGI: +- case RPORT_ST_PRLI: +- case RPORT_ST_LOGO: +- rdata->event = RPORT_EV_FAILED; +- queue_work(rport_event_queue, +- &rdata->event_work); +- break; +- case RPORT_ST_RTV: +- fc_rport_enter_ready(rport); +- break; +- case RPORT_ST_NONE: +- case RPORT_ST_READY: +- case RPORT_ST_INIT: +- break; +- } +-} +- +-/** +- * fc_rport_error_retry() - Error handler when retries are desired +- * @rport: The fc_rport object +- * @fp: The frame pointer +- * +- * If the error was an exchange timeout retry immediately, +- * otherwise wait for E_D_TOV. +- * +- * Locking Note: The rport lock is expected to be held before +- * calling this routine +- */ +-static void fc_rport_error_retry(struct fc_rport *rport, struct fc_frame *fp) +-{ +- struct fc_rport_libfc_priv *rdata = rport->dd_data; +- unsigned long delay = FC_DEF_E_D_TOV; +- +- /* make sure this isn't an FC_EX_CLOSED error, never retry those */ +- if (PTR_ERR(fp) == -FC_EX_CLOSED) +- return fc_rport_error(rport, fp); +- +- if (rdata->retries < rdata->local_port->max_retry_count) { +- FC_DEBUG_RPORT("Error %ld in state %s, retrying\n", +- PTR_ERR(fp), fc_rport_state(rport)); +- rdata->retries++; +- /* no additional delay on exchange timeouts */ +- if (PTR_ERR(fp) == -FC_EX_TIMEOUT) +- delay = 0; +- get_device(&rport->dev); +- schedule_delayed_work(&rdata->retry_work, delay); +- return; ++ if (!fp || PTR_ERR(fp) == -FC_EX_TIMEOUT) { ++ /* ++ * Memory allocation failure, or the exchange timed out. ++ * Retry after delay ++ */ ++ if (rdata->retries < rdata->local_port->max_retry_count) { ++ rdata->retries++; ++ if (!fp) ++ delay = msecs_to_jiffies(500); ++ get_device(&rport->dev); ++ schedule_delayed_work(&rdata->retry_work, delay); ++ } else { ++ switch (rdata->rp_state) { ++ case RPORT_ST_PLOGI: ++ case RPORT_ST_PRLI: ++ case RPORT_ST_LOGO: ++ rdata->event = RPORT_EV_FAILED; ++ queue_work(rport_event_queue, ++ &rdata->event_work); ++ break; ++ case RPORT_ST_RTV: ++ fc_rport_enter_ready(rport); ++ break; ++ case RPORT_ST_NONE: ++ case RPORT_ST_READY: ++ case RPORT_ST_INIT: ++ break; ++ } ++ } + } +- +- return fc_rport_error(rport, fp); + } + + /** +- * fc_rport_plogi_recv_resp() - Handle incoming ELS PLOGI response ++ * fc_rport_plogi_recv_resp - Handle incoming ELS PLOGI response + * @sp: current sequence in the PLOGI exchange + * @fp: response frame + * @rp_arg: Fibre Channel remote port +@@ -505,17 +483,17 @@ + FC_DEBUG_RPORT("Received a PLOGI response from port (%6x)\n", + rport->port_id); + +- if (IS_ERR(fp)) { +- fc_rport_error_retry(rport, fp); +- goto err; +- } +- + if (rdata->rp_state != RPORT_ST_PLOGI) { + FC_DBG("Received a PLOGI response, but in state %s\n", + fc_rport_state(rport)); + goto out; + } + ++ if (IS_ERR(fp)) { ++ fc_rport_error(rport, fp); ++ goto err; ++ } ++ + op = fc_frame_payload_op(fp); + if (op == ELS_LS_ACC && + (plp = fc_frame_payload_get(fp, sizeof(*plp))) != NULL) { +@@ -544,7 +522,7 @@ + else + fc_rport_enter_prli(rport); + } else +- fc_rport_error_retry(rport, fp); ++ fc_rport_error(rport, fp); + + out: + fc_frame_free(fp); +@@ -554,7 +532,7 @@ + } + + /** +- * fc_rport_enter_plogi() - Send Port Login (PLOGI) request to peer ++ * fc_rport_enter_plogi - Send Port Login (PLOGI) request to peer + * @rport: Fibre Channel remote port to send PLOGI to + * + * Locking Note: The rport lock is expected to be held before calling +@@ -574,20 +552,20 @@ + rport->maxframe_size = FC_MIN_MAX_PAYLOAD; + fp = fc_frame_alloc(lport, sizeof(struct fc_els_flogi)); + if (!fp) { +- fc_rport_error_retry(rport, fp); ++ fc_rport_error(rport, fp); + return; + } + rdata->e_d_tov = lport->e_d_tov; + + if (!lport->tt.elsct_send(lport, rport, fp, ELS_PLOGI, + fc_rport_plogi_resp, rport, lport->e_d_tov)) +- fc_rport_error_retry(rport, fp); ++ fc_rport_error(rport, fp); + else + get_device(&rport->dev); + } + + /** +- * fc_rport_prli_resp() - Process Login (PRLI) response handler ++ * fc_rport_prli_resp - Process Login (PRLI) response handler + * @sp: current sequence in the PRLI exchange + * @fp: response frame + * @rp_arg: Fibre Channel remote port +@@ -614,17 +592,17 @@ + FC_DEBUG_RPORT("Received a PRLI response from port (%6x)\n", + rport->port_id); + +- if (IS_ERR(fp)) { +- fc_rport_error_retry(rport, fp); +- goto err; +- } +- + if (rdata->rp_state != RPORT_ST_PRLI) { + FC_DBG("Received a PRLI response, but in state %s\n", + fc_rport_state(rport)); + goto out; + } + ++ if (IS_ERR(fp)) { ++ fc_rport_error(rport, fp); ++ goto err; ++ } ++ + op = fc_frame_payload_op(fp); + if (op == ELS_LS_ACC) { + pp = fc_frame_payload_get(fp, sizeof(*pp)); +@@ -657,7 +635,7 @@ + } + + /** +- * fc_rport_logo_resp() - Logout (LOGO) response handler ++ * fc_rport_logo_resp - Logout (LOGO) response handler + * @sp: current sequence in the LOGO exchange + * @fp: response frame + * @rp_arg: Fibre Channel remote port +@@ -679,7 +657,7 @@ + rport->port_id); + + if (IS_ERR(fp)) { +- fc_rport_error_retry(rport, fp); ++ fc_rport_error(rport, fp); + goto err; + } + +@@ -706,7 +684,7 @@ + } + + /** +- * fc_rport_enter_prli() - Send Process Login (PRLI) request to peer ++ * fc_rport_enter_prli - Send Process Login (PRLI) request to peer + * @rport: Fibre Channel remote port to send PRLI to + * + * Locking Note: The rport lock is expected to be held before calling +@@ -729,19 +707,19 @@ + + fp = fc_frame_alloc(lport, sizeof(*pp)); + if (!fp) { +- fc_rport_error_retry(rport, fp); ++ fc_rport_error(rport, fp); + return; + } + + if (!lport->tt.elsct_send(lport, rport, fp, ELS_PRLI, + fc_rport_prli_resp, rport, lport->e_d_tov)) +- fc_rport_error_retry(rport, fp); ++ fc_rport_error(rport, fp); + else + get_device(&rport->dev); + } + + /** +- * fc_rport_els_rtv_resp() - Request Timeout Value response handler ++ * fc_rport_els_rtv_resp - Request Timeout Value response handler + * @sp: current sequence in the RTV exchange + * @fp: response frame + * @rp_arg: Fibre Channel remote port +@@ -764,17 +742,17 @@ + FC_DEBUG_RPORT("Received a RTV response from port (%6x)\n", + rport->port_id); + +- if (IS_ERR(fp)) { +- fc_rport_error(rport, fp); +- goto err; +- } +- + if (rdata->rp_state != RPORT_ST_RTV) { + FC_DBG("Received a RTV response, but in state %s\n", + fc_rport_state(rport)); + goto out; + } + ++ if (IS_ERR(fp)) { ++ fc_rport_error(rport, fp); ++ goto err; ++ } ++ + op = fc_frame_payload_op(fp); + if (op == ELS_LS_ACC) { + struct fc_els_rtv_acc *rtv; +@@ -807,7 +785,7 @@ + } + + /** +- * fc_rport_enter_rtv() - Send Request Timeout Value (RTV) request to peer ++ * fc_rport_enter_rtv - Send Request Timeout Value (RTV) request to peer + * @rport: Fibre Channel remote port to send RTV to + * + * Locking Note: The rport lock is expected to be held before calling +@@ -826,19 +804,19 @@ + + fp = fc_frame_alloc(lport, sizeof(struct fc_els_rtv)); + if (!fp) { +- fc_rport_error_retry(rport, fp); ++ fc_rport_error(rport, fp); + return; + } + + if (!lport->tt.elsct_send(lport, rport, fp, ELS_RTV, + fc_rport_rtv_resp, rport, lport->e_d_tov)) +- fc_rport_error_retry(rport, fp); ++ fc_rport_error(rport, fp); + else + get_device(&rport->dev); + } + + /** +- * fc_rport_enter_logo() - Send Logout (LOGO) request to peer ++ * fc_rport_enter_logo - Send Logout (LOGO) request to peer + * @rport: Fibre Channel remote port to send LOGO to + * + * Locking Note: The rport lock is expected to be held before calling +@@ -857,20 +835,20 @@ + + fp = fc_frame_alloc(lport, sizeof(struct fc_els_logo)); + if (!fp) { +- fc_rport_error_retry(rport, fp); ++ fc_rport_error(rport, fp); + return; + } + + if (!lport->tt.elsct_send(lport, rport, fp, ELS_LOGO, + fc_rport_logo_resp, rport, lport->e_d_tov)) +- fc_rport_error_retry(rport, fp); ++ fc_rport_error(rport, fp); + else + get_device(&rport->dev); + } + + + /** +- * fc_rport_recv_req() - Receive a request from a rport ++ * fc_rport_recv_req - Receive a request from a rport + * @sp: current sequence in the PLOGI exchange + * @fp: response frame + * @rp_arg: Fibre Channel remote port +@@ -931,7 +909,7 @@ + } + + /** +- * fc_rport_recv_plogi_req() - Handle incoming Port Login (PLOGI) request ++ * fc_rport_recv_plogi_req - Handle incoming Port Login (PLOGI) request + * @rport: Fibre Channel remote port that initiated PLOGI + * @sp: current sequence in the PLOGI exchange + * @fp: PLOGI request frame +@@ -1053,7 +1031,7 @@ + } + + /** +- * fc_rport_recv_prli_req() - Handle incoming Process Login (PRLI) request ++ * fc_rport_recv_prli_req - Handle incoming Process Login (PRLI) request + * @rport: Fibre Channel remote port that initiated PRLI + * @sp: current sequence in the PRLI exchange + * @fp: PRLI request frame +@@ -1204,7 +1182,7 @@ + } + + /** +- * fc_rport_recv_prlo_req() - Handle incoming Process Logout (PRLO) request ++ * fc_rport_recv_prlo_req - Handle incoming Process Logout (PRLO) request + * @rport: Fibre Channel remote port that initiated PRLO + * @sp: current sequence in the PRLO exchange + * @fp: PRLO request frame +@@ -1235,7 +1213,7 @@ + } + + /** +- * fc_rport_recv_logo_req() - Handle incoming Logout (LOGO) request ++ * fc_rport_recv_logo_req - Handle incoming Logout (LOGO) request + * @rport: Fibre Channel remote port that initiated LOGO + * @sp: current sequence in the LOGO exchange + * @fp: LOGO request frame +@@ -1271,9 +1249,6 @@ + + int fc_rport_init(struct fc_lport *lport) + { +- if (!lport->tt.rport_create) +- lport->tt.rport_create = fc_rport_rogue_create; +- + if (!lport->tt.rport_login) + lport->tt.rport_login = fc_rport_login; + +@@ -1310,7 +1285,7 @@ + struct fc_rport_libfc_priv *rdata = rport->dd_data; + struct fc_lport *lport = rdata->local_port; + +- lport->tt.exch_mgr_reset(lport, 0, rport->port_id); +- lport->tt.exch_mgr_reset(lport, rport->port_id, 0); ++ lport->tt.exch_mgr_reset(lport->emp, 0, rport->port_id); ++ lport->tt.exch_mgr_reset(lport->emp, rport->port_id, 0); + } + EXPORT_SYMBOL(fc_rport_terminate_io); +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/drivers/scsi/libiscsi.c linux-2.6.29-rc3.owrt/drivers/scsi/libiscsi.c +--- linux-2.6.29.owrt/drivers/scsi/libiscsi.c 2009-05-10 22:04:39.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/drivers/scsi/libiscsi.c 2009-05-10 23:48:29.000000000 +0200 +@@ -1998,8 +1998,6 @@ + if (!shost->can_queue) + shost->can_queue = ISCSI_DEF_XMIT_CMDS_MAX; + +- if (!shost->transportt->eh_timed_out) +- shost->transportt->eh_timed_out = iscsi_eh_cmd_timed_out; + return scsi_add_host(shost, pdev); + } + EXPORT_SYMBOL_GPL(iscsi_host_add); +@@ -2022,6 +2020,7 @@ + shost = scsi_host_alloc(sht, sizeof(struct iscsi_host) + dd_data_size); + if (!shost) + return NULL; ++ shost->transportt->eh_timed_out = iscsi_eh_cmd_timed_out; + + if (qdepth > ISCSI_MAX_CMD_PER_LUN || qdepth < 1) { + if (qdepth != 0) +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/drivers/scsi/lpfc/lpfc_els.c linux-2.6.29-rc3.owrt/drivers/scsi/lpfc/lpfc_els.c +--- linux-2.6.29.owrt/drivers/scsi/lpfc/lpfc_els.c 2009-05-10 22:04:39.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/drivers/scsi/lpfc/lpfc_els.c 2009-05-10 23:48:29.000000000 +0200 +@@ -5258,7 +5258,6 @@ + sizeof(struct lpfc_name)); + break; + default: +- kfree(els_data); + return; + } + memcpy(els_data->wwpn, &ndlp->nlp_portname, sizeof(struct lpfc_name)); +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/drivers/scsi/qla2xxx/qla_attr.c linux-2.6.29-rc3.owrt/drivers/scsi/qla2xxx/qla_attr.c +--- linux-2.6.29.owrt/drivers/scsi/qla2xxx/qla_attr.c 2009-05-10 22:04:39.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/drivers/scsi/qla2xxx/qla_attr.c 2009-05-10 23:48:29.000000000 +0200 +@@ -244,6 +244,12 @@ + if (ha->optrom_state != QLA_SWAITING) + break; + ++ if (start & 0xfff) { ++ qla_printk(KERN_WARNING, ha, ++ "Invalid start region 0x%x/0x%x.\n", start, size); ++ return -EINVAL; ++ } ++ + ha->optrom_region_start = start; + ha->optrom_region_size = start + size > ha->optrom_size ? + ha->optrom_size - start : size; +@@ -297,7 +303,8 @@ + else if (start == (ha->flt_region_boot * 4) || + start == (ha->flt_region_fw * 4)) + valid = 1; +- else if (IS_QLA25XX(ha) || IS_QLA81XX(ha)) ++ else if ((IS_QLA25XX(ha) || IS_QLA81XX(ha)) && ++ start == (ha->flt_region_vpd_nvram * 4)) + valid = 1; + if (!valid) { + qla_printk(KERN_WARNING, ha, +@@ -1258,6 +1265,13 @@ + test_bit(FCPORT_UPDATE_NEEDED, &vha->dpc_flags)) + msleep(1000); + ++ if (ha->mqenable) { ++ if (qla25xx_delete_queues(vha, 0) != QLA_SUCCESS) ++ qla_printk(KERN_WARNING, ha, ++ "Queue delete failed.\n"); ++ vha->req_ques[0] = ha->req_q_map[0]->id; ++ } ++ + qla24xx_disable_vp(vha); + + fc_remove_host(vha->host); +@@ -1279,12 +1293,6 @@ + vha->host_no, vha->vp_idx, vha)); + } + +- if (ha->mqenable) { +- if (qla25xx_delete_queues(vha, 0) != QLA_SUCCESS) +- qla_printk(KERN_WARNING, ha, +- "Queue delete failed.\n"); +- } +- + scsi_host_put(vha->host); + qla_printk(KERN_INFO, ha, "vport %d deleted\n", id); + return 0; +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/drivers/scsi/qla2xxx/qla_def.h linux-2.6.29-rc3.owrt/drivers/scsi/qla2xxx/qla_def.h +--- linux-2.6.29.owrt/drivers/scsi/qla2xxx/qla_def.h 2009-05-10 22:04:39.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/drivers/scsi/qla2xxx/qla_def.h 2009-05-10 23:48:29.000000000 +0200 +@@ -2135,7 +2135,6 @@ + /* Work events. */ + enum qla_work_type { + QLA_EVT_AEN, +- QLA_EVT_IDC_ACK, + }; + + +@@ -2150,10 +2149,6 @@ + enum fc_host_event_code code; + u32 data; + } aen; +- struct { +-#define QLA_IDC_ACK_REGS 7 +- uint16_t mb[QLA_IDC_ACK_REGS]; +- } idc_ack; + } u; + }; + +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/drivers/scsi/qla2xxx/qla_devtbl.h linux-2.6.29-rc3.owrt/drivers/scsi/qla2xxx/qla_devtbl.h +--- linux-2.6.29.owrt/drivers/scsi/qla2xxx/qla_devtbl.h 2009-05-10 22:04:39.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/drivers/scsi/qla2xxx/qla_devtbl.h 2009-05-10 23:48:29.000000000 +0200 +@@ -72,7 +72,7 @@ + "QLA2462", "Sun PCI-X 2.0 to 4Gb FC, Dual Channel", /* 0x141 */ + "QLE2460", "Sun PCI-Express to 2Gb FC, Single Channel", /* 0x142 */ + "QLE2462", "Sun PCI-Express to 4Gb FC, Single Channel", /* 0x143 */ +- "QEM2462", "Server I/O Module 4Gb FC, Dual Channel", /* 0x144 */ ++ "QEM2462" "Server I/O Module 4Gb FC, Dual Channel", /* 0x144 */ + "QLE2440", "PCI-Express to 4Gb FC, Single Channel", /* 0x145 */ + "QLE2464", "PCI-Express to 4Gb FC, Quad Channel", /* 0x146 */ + "QLA2440", "PCI-X 2.0 to 4Gb FC, Single Channel", /* 0x147 */ +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/drivers/scsi/qla2xxx/qla_fw.h linux-2.6.29-rc3.owrt/drivers/scsi/qla2xxx/qla_fw.h +--- linux-2.6.29.owrt/drivers/scsi/qla2xxx/qla_fw.h 2009-05-10 22:04:39.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/drivers/scsi/qla2xxx/qla_fw.h 2009-05-10 23:48:29.000000000 +0200 +@@ -1402,8 +1402,6 @@ + #define MBA_IDC_NOTIFY 0x8101 + #define MBA_IDC_TIME_EXT 0x8102 + +-#define MBC_IDC_ACK 0x101 +- + struct nvram_81xx { + /* NVRAM header. */ + uint8_t id[4]; +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/drivers/scsi/qla2xxx/qla_gbl.h linux-2.6.29-rc3.owrt/drivers/scsi/qla2xxx/qla_gbl.h +--- linux-2.6.29.owrt/drivers/scsi/qla2xxx/qla_gbl.h 2009-05-10 22:04:39.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/drivers/scsi/qla2xxx/qla_gbl.h 2009-05-10 23:48:29.000000000 +0200 +@@ -72,7 +72,6 @@ + extern void qla2x00_abort_all_cmds(scsi_qla_host_t *, int); + extern int qla2x00_post_aen_work(struct scsi_qla_host *, enum + fc_host_event_code, u32); +-extern int qla2x00_post_idc_ack_work(struct scsi_qla_host *, uint16_t *); + + extern void qla2x00_abort_fcport_cmds(fc_port_t *); + extern struct scsi_qla_host *qla2x00_create_host(struct scsi_host_template *, +@@ -267,8 +266,6 @@ + + extern int qla84xx_verify_chip(struct scsi_qla_host *, uint16_t *); + +-extern int qla81xx_idc_ack(scsi_qla_host_t *, uint16_t *); +- + /* + * Global Function Prototypes in qla_isr.c source file. + */ +@@ -379,8 +376,10 @@ + + /* Globa function prototypes for multi-q */ + extern int qla25xx_request_irq(struct rsp_que *); +-extern int qla25xx_init_req_que(struct scsi_qla_host *, struct req_que *); +-extern int qla25xx_init_rsp_que(struct scsi_qla_host *, struct rsp_que *); ++extern int qla25xx_init_req_que(struct scsi_qla_host *, struct req_que *, ++ uint8_t); ++extern int qla25xx_init_rsp_que(struct scsi_qla_host *, struct rsp_que *, ++ uint8_t); + extern int qla25xx_create_req_que(struct qla_hw_data *, uint16_t, uint8_t, + uint16_t, uint8_t, uint8_t); + extern int qla25xx_create_rsp_que(struct qla_hw_data *, uint16_t, uint8_t, +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/drivers/scsi/qla2xxx/qla_init.c linux-2.6.29-rc3.owrt/drivers/scsi/qla2xxx/qla_init.c +--- linux-2.6.29.owrt/drivers/scsi/qla2xxx/qla_init.c 2009-05-10 22:04:39.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/drivers/scsi/qla2xxx/qla_init.c 2009-05-10 23:48:29.000000000 +0200 +@@ -1226,8 +1226,9 @@ + icb->firmware_options_2 |= + __constant_cpu_to_le32(BIT_18); + +- icb->firmware_options_2 &= __constant_cpu_to_le32(~BIT_22); ++ icb->firmware_options_2 |= __constant_cpu_to_le32(BIT_22); + icb->firmware_options_2 |= __constant_cpu_to_le32(BIT_23); ++ ha->rsp_q_map[0]->options = icb->firmware_options_2; + + WRT_REG_DWORD(®->isp25mq.req_q_in, 0); + WRT_REG_DWORD(®->isp25mq.req_q_out, 0); +@@ -1308,12 +1309,8 @@ + + DEBUG(printk("scsi(%ld): Issue init firmware.\n", vha->host_no)); + +- if (ha->flags.npiv_supported) { +- if (ha->operating_mode == LOOP) +- ha->max_npiv_vports = MIN_MULTI_ID_FABRIC - 1; ++ if (ha->flags.npiv_supported) + mid_init_cb->count = cpu_to_le16(ha->max_npiv_vports); +- } +- + + mid_init_cb->options = __constant_cpu_to_le16(BIT_1); + +@@ -2614,7 +2611,6 @@ + port_id_t wrap, nxt_d_id; + struct qla_hw_data *ha = vha->hw; + struct scsi_qla_host *vp, *base_vha = pci_get_drvdata(ha->pdev); +- struct scsi_qla_host *tvp; + + rval = QLA_SUCCESS; + +@@ -2714,7 +2710,7 @@ + /* Bypass virtual ports of the same host. */ + found = 0; + if (ha->num_vhosts) { +- list_for_each_entry_safe(vp, tvp, &ha->vp_list, list) { ++ list_for_each_entry(vp, &ha->vp_list, list) { + if (new_fcport->d_id.b24 == vp->d_id.b24) { + found = 1; + break; +@@ -2837,7 +2833,6 @@ + uint16_t first_loop_id; + struct qla_hw_data *ha = vha->hw; + struct scsi_qla_host *vp; +- struct scsi_qla_host *tvp; + + rval = QLA_SUCCESS; + +@@ -2862,7 +2857,7 @@ + /* Check for loop ID being already in use. */ + found = 0; + fcport = NULL; +- list_for_each_entry_safe(vp, tvp, &ha->vp_list, list) { ++ list_for_each_entry(vp, &ha->vp_list, list) { + list_for_each_entry(fcport, &vp->vp_fcports, list) { + if (fcport->loop_id == dev->loop_id && + fcport != dev) { +@@ -3297,7 +3292,6 @@ + uint8_t status = 0; + struct qla_hw_data *ha = vha->hw; + struct scsi_qla_host *vp; +- struct scsi_qla_host *tvp; + struct req_que *req = ha->req_q_map[0]; + + if (vha->flags.online) { +@@ -3313,7 +3307,7 @@ + if (atomic_read(&vha->loop_state) != LOOP_DOWN) { + atomic_set(&vha->loop_state, LOOP_DOWN); + qla2x00_mark_all_devices_lost(vha, 0); +- list_for_each_entry_safe(vp, tvp, &ha->vp_list, list) ++ list_for_each_entry(vp, &ha->vp_list, list) + qla2x00_mark_all_devices_lost(vp, 0); + } else { + if (!atomic_read(&vha->loop_down_timer)) +@@ -3410,7 +3404,7 @@ + DEBUG(printk(KERN_INFO + "qla2x00_abort_isp(%ld): succeeded.\n", + vha->host_no)); +- list_for_each_entry_safe(vp, tvp, &ha->vp_list, list) { ++ list_for_each_entry(vp, &ha->vp_list, list) { + if (vp->vp_idx) + qla2x00_vp_abort_isp(vp); + } +@@ -3435,7 +3429,7 @@ + static int + qla2x00_restart_isp(scsi_qla_host_t *vha) + { +- int status = 0; ++ uint8_t status = 0; + uint32_t wait_time; + struct qla_hw_data *ha = vha->hw; + struct req_que *req = ha->req_q_map[0]; +@@ -3499,7 +3493,7 @@ + rsp = ha->rsp_q_map[i]; + if (rsp) { + rsp->options &= ~BIT_0; +- ret = qla25xx_init_rsp_que(base_vha, rsp); ++ ret = qla25xx_init_rsp_que(base_vha, rsp, rsp->options); + if (ret != QLA_SUCCESS) + DEBUG2_17(printk(KERN_WARNING + "%s Rsp que:%d init failed\n", __func__, +@@ -3513,7 +3507,7 @@ + if (req) { + /* Clear outstanding commands array. */ + req->options &= ~BIT_0; +- ret = qla25xx_init_req_que(base_vha, req); ++ ret = qla25xx_init_req_que(base_vha, req, req->options); + if (ret != QLA_SUCCESS) + DEBUG2_17(printk(KERN_WARNING + "%s Req que:%d init failed\n", __func__, +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/drivers/scsi/qla2xxx/qla_isr.c linux-2.6.29-rc3.owrt/drivers/scsi/qla2xxx/qla_isr.c +--- linux-2.6.29.owrt/drivers/scsi/qla2xxx/qla_isr.c 2009-05-10 22:04:39.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/drivers/scsi/qla2xxx/qla_isr.c 2009-05-10 23:48:29.000000000 +0200 +@@ -266,40 +266,6 @@ + } + } + +-static void +-qla81xx_idc_event(scsi_qla_host_t *vha, uint16_t aen, uint16_t descr) +-{ +- static char *event[] = +- { "Complete", "Request Notification", "Time Extension" }; +- int rval; +- struct device_reg_24xx __iomem *reg24 = &vha->hw->iobase->isp24; +- uint16_t __iomem *wptr; +- uint16_t cnt, timeout, mb[QLA_IDC_ACK_REGS]; +- +- /* Seed data -- mailbox1 -> mailbox7. */ +- wptr = (uint16_t __iomem *)®24->mailbox1; +- for (cnt = 0; cnt < QLA_IDC_ACK_REGS; cnt++, wptr++) +- mb[cnt] = RD_REG_WORD(wptr); +- +- DEBUG2(printk("scsi(%ld): Inter-Driver Commucation %s -- " +- "%04x %04x %04x %04x %04x %04x %04x.\n", vha->host_no, +- event[aen & 0xff], +- mb[0], mb[1], mb[2], mb[3], mb[4], mb[5], mb[6])); +- +- /* Acknowledgement needed? [Notify && non-zero timeout]. */ +- timeout = (descr >> 8) & 0xf; +- if (aen != MBA_IDC_NOTIFY || !timeout) +- return; +- +- DEBUG2(printk("scsi(%ld): Inter-Driver Commucation %s -- " +- "ACK timeout=%d.\n", vha->host_no, event[aen & 0xff], timeout)); +- +- rval = qla2x00_post_idc_ack_work(vha, mb); +- if (rval != QLA_SUCCESS) +- qla_printk(KERN_WARNING, vha->hw, +- "IDC failed to post ACK.\n"); +-} +- + /** + * qla2x00_async_event() - Process aynchronous events. + * @ha: SCSI driver HA context +@@ -748,9 +714,21 @@ + "%04x %04x %04x\n", vha->host_no, mb[1], mb[2], mb[3])); + break; + case MBA_IDC_COMPLETE: ++ DEBUG2(printk("scsi(%ld): Inter-Driver Commucation " ++ "Complete -- %04x %04x %04x\n", vha->host_no, mb[1], mb[2], ++ mb[3])); ++ break; + case MBA_IDC_NOTIFY: ++ DEBUG2(printk("scsi(%ld): Inter-Driver Commucation " ++ "Request Notification -- %04x %04x %04x\n", vha->host_no, ++ mb[1], mb[2], mb[3])); ++ /**** Mailbox registers 4 - 7 valid!!! */ ++ break; + case MBA_IDC_TIME_EXT: +- qla81xx_idc_event(vha, mb[0], mb[1]); ++ DEBUG2(printk("scsi(%ld): Inter-Driver Commucation " ++ "Time Extension -- %04x %04x %04x\n", vha->host_no, mb[1], ++ mb[2], mb[3])); ++ /**** Mailbox registers 4 - 7 valid!!! */ + break; + } + +@@ -1729,6 +1707,7 @@ + struct qla_hw_data *ha; + struct rsp_que *rsp; + struct device_reg_24xx __iomem *reg; ++ uint16_t msix_disabled_hccr = 0; + + rsp = (struct rsp_que *) dev_id; + if (!rsp) { +@@ -1741,8 +1720,17 @@ + + spin_lock_irq(&ha->hardware_lock); + ++ msix_disabled_hccr = rsp->options; ++ if (!rsp->id) ++ msix_disabled_hccr &= __constant_cpu_to_le32(BIT_22); ++ else ++ msix_disabled_hccr &= __constant_cpu_to_le32(BIT_6); ++ + qla24xx_process_response_queue(rsp); + ++ if (!msix_disabled_hccr) ++ WRT_REG_DWORD(®->hccr, HCCRX_CLR_RISC_INT); ++ + spin_unlock_irq(&ha->hardware_lock); + + return IRQ_HANDLED; +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/drivers/scsi/qla2xxx/qla_mbx.c linux-2.6.29-rc3.owrt/drivers/scsi/qla2xxx/qla_mbx.c +--- linux-2.6.29.owrt/drivers/scsi/qla2xxx/qla_mbx.c 2009-05-10 22:04:39.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/drivers/scsi/qla2xxx/qla_mbx.c 2009-05-10 23:48:29.000000000 +0200 +@@ -2685,7 +2685,6 @@ + uint16_t stat = le16_to_cpu(rptid_entry->vp_idx); + struct qla_hw_data *ha = vha->hw; + scsi_qla_host_t *vp; +- scsi_qla_host_t *tvp; + + if (rptid_entry->entry_status != 0) + return; +@@ -2711,7 +2710,7 @@ + if (MSB(stat) == 1) + return; + +- list_for_each_entry_safe(vp, tvp, &ha->vp_list, list) ++ list_for_each_entry(vp, &ha->vp_list, list) + if (vp_idx == vp->vp_idx) + break; + if (!vp) +@@ -3091,7 +3090,8 @@ + } + + int +-qla25xx_init_req_que(struct scsi_qla_host *vha, struct req_que *req) ++qla25xx_init_req_que(struct scsi_qla_host *vha, struct req_que *req, ++ uint8_t options) + { + int rval; + unsigned long flags; +@@ -3101,7 +3101,7 @@ + struct qla_hw_data *ha = vha->hw; + + mcp->mb[0] = MBC_INITIALIZE_MULTIQ; +- mcp->mb[1] = req->options; ++ mcp->mb[1] = options; + mcp->mb[2] = MSW(LSD(req->dma)); + mcp->mb[3] = LSW(LSD(req->dma)); + mcp->mb[6] = MSW(MSD(req->dma)); +@@ -3128,7 +3128,7 @@ + mcp->tov = 60; + + spin_lock_irqsave(&ha->hardware_lock, flags); +- if (!(req->options & BIT_0)) { ++ if (!(options & BIT_0)) { + WRT_REG_DWORD(®->req_q_in, 0); + WRT_REG_DWORD(®->req_q_out, 0); + } +@@ -3142,7 +3142,8 @@ + } + + int +-qla25xx_init_rsp_que(struct scsi_qla_host *vha, struct rsp_que *rsp) ++qla25xx_init_rsp_que(struct scsi_qla_host *vha, struct rsp_que *rsp, ++ uint8_t options) + { + int rval; + unsigned long flags; +@@ -3152,7 +3153,7 @@ + struct qla_hw_data *ha = vha->hw; + + mcp->mb[0] = MBC_INITIALIZE_MULTIQ; +- mcp->mb[1] = rsp->options; ++ mcp->mb[1] = options; + mcp->mb[2] = MSW(LSD(rsp->dma)); + mcp->mb[3] = LSW(LSD(rsp->dma)); + mcp->mb[6] = MSW(MSD(rsp->dma)); +@@ -3177,7 +3178,7 @@ + mcp->tov = 60; + + spin_lock_irqsave(&ha->hardware_lock, flags); +- if (!(rsp->options & BIT_0)) { ++ if (!(options & BIT_0)) { + WRT_REG_DWORD(®->rsp_q_out, 0); + WRT_REG_DWORD(®->rsp_q_in, 0); + } +@@ -3192,29 +3193,3 @@ + return rval; + } + +-int +-qla81xx_idc_ack(scsi_qla_host_t *vha, uint16_t *mb) +-{ +- int rval; +- mbx_cmd_t mc; +- mbx_cmd_t *mcp = &mc; +- +- DEBUG11(printk("%s(%ld): entered.\n", __func__, vha->host_no)); +- +- mcp->mb[0] = MBC_IDC_ACK; +- memcpy(&mcp->mb[1], mb, QLA_IDC_ACK_REGS * sizeof(uint16_t)); +- mcp->out_mb = MBX_7|MBX_6|MBX_5|MBX_4|MBX_3|MBX_2|MBX_1|MBX_0; +- mcp->in_mb = MBX_0; +- mcp->tov = MBX_TOV_SECONDS; +- mcp->flags = 0; +- rval = qla2x00_mailbox_command(vha, mcp); +- +- if (rval != QLA_SUCCESS) { +- DEBUG2_3_11(printk("%s(%ld): failed=%x (%x).\n", __func__, +- vha->host_no, rval, mcp->mb[0])); +- } else { +- DEBUG11(printk("%s(%ld): done.\n", __func__, vha->host_no)); +- } +- +- return rval; +-} +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/drivers/scsi/qla2xxx/qla_mid.c linux-2.6.29-rc3.owrt/drivers/scsi/qla2xxx/qla_mid.c +--- linux-2.6.29.owrt/drivers/scsi/qla2xxx/qla_mid.c 2009-05-10 22:04:39.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/drivers/scsi/qla2xxx/qla_mid.c 2009-05-10 23:48:29.000000000 +0200 +@@ -69,10 +69,9 @@ + qla24xx_find_vhost_by_name(struct qla_hw_data *ha, uint8_t *port_name) + { + scsi_qla_host_t *vha; +- struct scsi_qla_host *tvha; + + /* Locate matching device in database. */ +- list_for_each_entry_safe(vha, tvha, &ha->vp_list, list) { ++ list_for_each_entry(vha, &ha->vp_list, list) { + if (!memcmp(port_name, vha->port_name, WWN_SIZE)) + return vha; + } +@@ -195,11 +194,11 @@ + void + qla2x00_alert_all_vps(struct rsp_que *rsp, uint16_t *mb) + { +- scsi_qla_host_t *vha, *tvha; ++ scsi_qla_host_t *vha; + struct qla_hw_data *ha = rsp->hw; + int i = 0; + +- list_for_each_entry_safe(vha, tvha, &ha->vp_list, list) { ++ list_for_each_entry(vha, &ha->vp_list, list) { + if (vha->vp_idx) { + switch (mb[0]) { + case MBA_LIP_OCCURRED: +@@ -301,7 +300,6 @@ + int ret; + struct qla_hw_data *ha = vha->hw; + scsi_qla_host_t *vp; +- struct scsi_qla_host *tvp; + + if (vha->vp_idx) + return; +@@ -310,7 +308,7 @@ + + clear_bit(VP_DPC_NEEDED, &vha->dpc_flags); + +- list_for_each_entry_safe(vp, tvp, &ha->vp_list, list) { ++ list_for_each_entry(vp, &ha->vp_list, list) { + if (vp->vp_idx) + ret = qla2x00_do_dpc_vp(vp); + } +@@ -398,7 +396,7 @@ + + qla2x00_start_timer(vha, qla2x00_timer, WATCH_INTERVAL); + +- memset(vha->req_ques, 0, sizeof(vha->req_ques)); ++ memset(vha->req_ques, 0, sizeof(vha->req_ques) * QLA_MAX_HOST_QUES); + vha->req_ques[0] = ha->req_q_map[0]->id; + host->can_queue = ha->req_q_map[0]->length + 128; + host->this_id = 255; +@@ -473,7 +471,7 @@ + + if (req) { + req->options |= BIT_0; +- ret = qla25xx_init_req_que(vha, req); ++ ret = qla25xx_init_req_que(vha, req, req->options); + } + if (ret == QLA_SUCCESS) + qla25xx_free_req_que(vha, req); +@@ -488,7 +486,7 @@ + + if (rsp) { + rsp->options |= BIT_0; +- ret = qla25xx_init_rsp_que(vha, rsp); ++ ret = qla25xx_init_rsp_que(vha, rsp, rsp->options); + } + if (ret == QLA_SUCCESS) + qla25xx_free_rsp_que(vha, rsp); +@@ -504,7 +502,7 @@ + + req->options |= BIT_3; + req->qos = qos; +- ret = qla25xx_init_req_que(vha, req); ++ ret = qla25xx_init_req_que(vha, req, req->options); + if (ret != QLA_SUCCESS) + DEBUG2_17(printk(KERN_WARNING "%s failed\n", __func__)); + /* restore options bit */ +@@ -634,7 +632,7 @@ + req->max_q_depth = ha->req_q_map[0]->max_q_depth; + mutex_unlock(&ha->vport_lock); + +- ret = qla25xx_init_req_que(base_vha, req); ++ ret = qla25xx_init_req_que(base_vha, req, options); + if (ret != QLA_SUCCESS) { + qla_printk(KERN_WARNING, ha, "%s failed\n", __func__); + mutex_lock(&ha->vport_lock); +@@ -712,7 +710,7 @@ + if (ret) + goto que_failed; + +- ret = qla25xx_init_rsp_que(base_vha, rsp); ++ ret = qla25xx_init_rsp_que(base_vha, rsp, options); + if (ret != QLA_SUCCESS) { + qla_printk(KERN_WARNING, ha, "%s failed\n", __func__); + mutex_lock(&ha->vport_lock); +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/drivers/scsi/qla2xxx/qla_os.c linux-2.6.29-rc3.owrt/drivers/scsi/qla2xxx/qla_os.c +--- linux-2.6.29.owrt/drivers/scsi/qla2xxx/qla_os.c 2009-05-10 22:04:39.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/drivers/scsi/qla2xxx/qla_os.c 2009-05-10 23:48:29.000000000 +0200 +@@ -2222,6 +2222,10 @@ + { + char name[16]; + ++ ha->init_cb_size = sizeof(init_cb_t); ++ if (IS_QLA2XXX_MIDTYPE(ha)) ++ ha->init_cb_size = sizeof(struct mid_init_cb_24xx); ++ + ha->init_cb = dma_alloc_coherent(&ha->pdev->dev, ha->init_cb_size, + &ha->init_cb_dma, GFP_KERNEL); + if (!ha->init_cb) +@@ -2518,19 +2522,6 @@ + return qla2x00_post_work(vha, e, 1); + } + +-int +-qla2x00_post_idc_ack_work(struct scsi_qla_host *vha, uint16_t *mb) +-{ +- struct qla_work_evt *e; +- +- e = qla2x00_alloc_work(vha, QLA_EVT_IDC_ACK, 1); +- if (!e) +- return QLA_FUNCTION_FAILED; +- +- memcpy(e->u.idc_ack.mb, mb, QLA_IDC_ACK_REGS * sizeof(uint16_t)); +- return qla2x00_post_work(vha, e, 1); +-} +- + static void + qla2x00_do_work(struct scsi_qla_host *vha) + { +@@ -2548,9 +2539,6 @@ + fc_host_post_event(vha->host, fc_get_event_number(), + e->u.aen.code, e->u.aen.data); + break; +- case QLA_EVT_IDC_ACK: +- qla81xx_idc_ack(vha, e->u.idc_ack.mb); +- break; + } + if (e->flags & QLA_EVT_FLAG_FREE) + kfree(e); +@@ -2564,7 +2552,7 @@ + void qla2x00_relogin(struct scsi_qla_host *vha) + { + fc_port_t *fcport; +- int status; ++ uint8_t status; + uint16_t next_loopid = 0; + struct qla_hw_data *ha = vha->hw; + +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/drivers/scsi/qla2xxx/qla_sup.c linux-2.6.29-rc3.owrt/drivers/scsi/qla2xxx/qla_sup.c +--- linux-2.6.29.owrt/drivers/scsi/qla2xxx/qla_sup.c 2009-05-10 22:04:39.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/drivers/scsi/qla2xxx/qla_sup.c 2009-05-10 23:48:29.000000000 +0200 +@@ -684,7 +684,7 @@ + "end=0x%x size=0x%x.\n", le32_to_cpu(region->code), start, + le32_to_cpu(region->end) >> 2, le32_to_cpu(region->size))); + +- switch (le32_to_cpu(region->code) & 0xff) { ++ switch (le32_to_cpu(region->code)) { + case FLT_REG_FW: + ha->flt_region_fw = start; + break; +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/drivers/scsi/qla2xxx/qla_version.h linux-2.6.29-rc3.owrt/drivers/scsi/qla2xxx/qla_version.h +--- linux-2.6.29.owrt/drivers/scsi/qla2xxx/qla_version.h 2009-05-10 22:04:39.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/drivers/scsi/qla2xxx/qla_version.h 2009-05-10 23:48:29.000000000 +0200 +@@ -7,7 +7,7 @@ + /* + * Driver version + */ +-#define QLA2XXX_VERSION "8.03.00-k4" ++#define QLA2XXX_VERSION "8.03.00-k2" + + #define QLA_DRIVER_MAJOR_VER 8 + #define QLA_DRIVER_MINOR_VER 3 +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/drivers/scsi/scsi_lib.c linux-2.6.29-rc3.owrt/drivers/scsi/scsi_lib.c +--- linux-2.6.29.owrt/drivers/scsi/scsi_lib.c 2009-05-10 22:04:39.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/drivers/scsi/scsi_lib.c 2009-05-10 23:48:29.000000000 +0200 +@@ -1040,11 +1040,12 @@ + action = ACTION_FAIL; + break; + case ABORTED_COMMAND: +- action = ACTION_FAIL; + if (sshdr.asc == 0x10) { /* DIF */ + description = "Target Data Integrity Failure"; ++ action = ACTION_FAIL; + error = -EILSEQ; +- } ++ } else ++ action = ACTION_RETRY; + break; + case NOT_READY: + /* If the device is in the process of becoming +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/drivers/scsi/scsi_scan.c linux-2.6.29-rc3.owrt/drivers/scsi/scsi_scan.c +--- linux-2.6.29.owrt/drivers/scsi/scsi_scan.c 2009-05-10 22:04:39.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/drivers/scsi/scsi_scan.c 2009-05-10 23:48:29.000000000 +0200 +@@ -317,7 +317,6 @@ + return sdev; + + out_device_destroy: +- scsi_device_set_state(sdev, SDEV_DEL); + transport_destroy_device(&sdev->sdev_gendev); + put_device(&sdev->sdev_gendev); + out: +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/drivers/scsi/sd.c linux-2.6.29-rc3.owrt/drivers/scsi/sd.c +--- linux-2.6.29.owrt/drivers/scsi/sd.c 2009-05-10 22:04:39.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/drivers/scsi/sd.c 2009-05-10 23:48:29.000000000 +0200 +@@ -107,7 +107,6 @@ + static void sd_print_sense_hdr(struct scsi_disk *, struct scsi_sense_hdr *); + static void sd_print_result(struct scsi_disk *, int); + +-static DEFINE_SPINLOCK(sd_index_lock); + static DEFINE_IDA(sd_index_ida); + + /* This semaphore is used to mediate the 0->1 reference get in the +@@ -1167,19 +1166,23 @@ + /* + * The device does not want the automatic start to be issued. + */ +- if (sdkp->device->no_start_on_add) ++ if (sdkp->device->no_start_on_add) { + break; ++ } + +- if (sense_valid && sshdr.sense_key == NOT_READY) { +- if (sshdr.asc == 4 && sshdr.ascq == 3) +- break; /* manual intervention required */ +- if (sshdr.asc == 4 && sshdr.ascq == 0xb) +- break; /* standby */ +- if (sshdr.asc == 4 && sshdr.ascq == 0xc) +- break; /* unavailable */ +- /* +- * Issue command to spin up drive when not ready +- */ ++ /* ++ * If manual intervention is required, or this is an ++ * absent USB storage device, a spinup is meaningless. ++ */ ++ if (sense_valid && ++ sshdr.sense_key == NOT_READY && ++ sshdr.asc == 4 && sshdr.ascq == 3) { ++ break; /* manual intervention required */ ++ ++ /* ++ * Issue command to spin up drive when not ready ++ */ ++ } else if (sense_valid && sshdr.sense_key == NOT_READY) { + if (!spintime) { + sd_printk(KERN_NOTICE, sdkp, "Spinning up disk..."); + cmd[0] = START_STOP; +@@ -1911,9 +1914,7 @@ + if (!ida_pre_get(&sd_index_ida, GFP_KERNEL)) + goto out_put; + +- spin_lock(&sd_index_lock); + error = ida_get_new(&sd_index_ida, &index); +- spin_unlock(&sd_index_lock); + } while (error == -EAGAIN); + + if (error) +@@ -1935,9 +1936,7 @@ + return 0; + + out_free_index: +- spin_lock(&sd_index_lock); + ida_remove(&sd_index_ida, index); +- spin_unlock(&sd_index_lock); + out_put: + put_disk(gd); + out_free: +@@ -1987,9 +1986,7 @@ + struct scsi_disk *sdkp = to_scsi_disk(dev); + struct gendisk *disk = sdkp->disk; + +- spin_lock(&sd_index_lock); + ida_remove(&sd_index_ida, sdkp->index); +- spin_unlock(&sd_index_lock); + + disk->private_data = NULL; + put_disk(disk); +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/drivers/scsi/sg.c linux-2.6.29-rc3.owrt/drivers/scsi/sg.c +--- linux-2.6.29.owrt/drivers/scsi/sg.c 2009-05-10 22:04:39.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/drivers/scsi/sg.c 2009-05-10 23:48:29.000000000 +0200 +@@ -1078,7 +1078,7 @@ + case BLKTRACESETUP: + return blk_trace_setup(sdp->device->request_queue, + sdp->disk->disk_name, +- MKDEV(SCSI_GENERIC_MAJOR, sdp->index), ++ sdp->device->sdev_gendev.devt, + (char *)arg); + case BLKTRACESTART: + return blk_trace_startstop(sdp->device->request_queue, 1); +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/drivers/scsi/zalon.c linux-2.6.29-rc3.owrt/drivers/scsi/zalon.c +--- linux-2.6.29.owrt/drivers/scsi/zalon.c 2009-05-10 22:04:39.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/drivers/scsi/zalon.c 2009-05-10 23:48:29.000000000 +0200 +@@ -137,7 +137,7 @@ + goto fail; + + if (request_irq(dev->irq, ncr53c8xx_intr, IRQF_SHARED, "zalon", host)) { +- dev_printk(KERN_ERR, &dev->dev, "irq problem with %d, detaching\n ", ++ dev_printk(KERN_ERR, dev, "irq problem with %d, detaching\n ", + dev->irq); + goto fail; + } +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/drivers/serial/8250.c linux-2.6.29-rc3.owrt/drivers/serial/8250.c +--- linux-2.6.29.owrt/drivers/serial/8250.c 2009-05-10 22:04:38.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/drivers/serial/8250.c 2009-05-10 23:48:29.000000000 +0200 +@@ -2083,20 +2083,6 @@ + + serial8250_set_mctrl(&up->port, up->port.mctrl); + +- /* Serial over Lan (SoL) hack: +- Intel 8257x Gigabit ethernet chips have a +- 16550 emulation, to be used for Serial Over Lan. +- Those chips take a longer time than a normal +- serial device to signalize that a transmission +- data was queued. Due to that, the above test generally +- fails. One solution would be to delay the reading of +- iir. However, this is not reliable, since the timeout +- is variable. So, let's just don't test if we receive +- TX irq. This way, we'll never enable UART_BUG_TXEN. +- */ +- if (up->port.flags & UPF_NO_TXEN_TEST) +- goto dont_test_tx_en; +- + /* + * Do a quick test to see if we receive an + * interrupt when we enable the TX irq. +@@ -2116,7 +2102,6 @@ + up->bugs &= ~UART_BUG_TXEN; + } + +-dont_test_tx_en: + spin_unlock_irqrestore(&up->port.lock, flags); + + /* +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/drivers/serial/8250_pci.c linux-2.6.29-rc3.owrt/drivers/serial/8250_pci.c +--- linux-2.6.29.owrt/drivers/serial/8250_pci.c 2009-05-10 22:04:38.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/drivers/serial/8250_pci.c 2009-05-10 23:48:29.000000000 +0200 +@@ -798,21 +798,6 @@ + return setup_port(priv, port, bar, offset, board->reg_shift); + } + +-static int skip_tx_en_setup(struct serial_private *priv, +- const struct pciserial_board *board, +- struct uart_port *port, int idx) +-{ +- port->flags |= UPF_NO_TXEN_TEST; +- printk(KERN_DEBUG "serial8250: skipping TxEn test for device " +- "[%04x:%04x] subsystem [%04x:%04x]\n", +- priv->dev->vendor, +- priv->dev->device, +- priv->dev->subsystem_vendor, +- priv->dev->subsystem_device); +- +- return pci_default_setup(priv, board, port, idx); +-} +- + /* This should be in linux/pci_ids.h */ + #define PCI_VENDOR_ID_SBSMODULARIO 0x124B + #define PCI_SUBVENDOR_ID_SBSMODULARIO 0x124B +@@ -879,27 +864,6 @@ + .init = pci_inteli960ni_init, + .setup = pci_default_setup, + }, +- { +- .vendor = PCI_VENDOR_ID_INTEL, +- .device = PCI_DEVICE_ID_INTEL_8257X_SOL, +- .subvendor = PCI_ANY_ID, +- .subdevice = PCI_ANY_ID, +- .setup = skip_tx_en_setup, +- }, +- { +- .vendor = PCI_VENDOR_ID_INTEL, +- .device = PCI_DEVICE_ID_INTEL_82573L_SOL, +- .subvendor = PCI_ANY_ID, +- .subdevice = PCI_ANY_ID, +- .setup = skip_tx_en_setup, +- }, +- { +- .vendor = PCI_VENDOR_ID_INTEL, +- .device = PCI_DEVICE_ID_INTEL_82573E_SOL, +- .subvendor = PCI_ANY_ID, +- .subdevice = PCI_ANY_ID, +- .setup = skip_tx_en_setup, +- }, + /* + * ITE + */ +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/drivers/serial/atmel_serial.c linux-2.6.29-rc3.owrt/drivers/serial/atmel_serial.c +--- linux-2.6.29.owrt/drivers/serial/atmel_serial.c 2009-05-10 22:04:38.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/drivers/serial/atmel_serial.c 2009-05-10 23:48:29.000000000 +0200 +@@ -877,10 +877,6 @@ + } + } + +- /* Save current CSR for comparison in atmel_tasklet_func() */ +- atmel_port->irq_status_prev = UART_GET_CSR(port); +- atmel_port->irq_status = atmel_port->irq_status_prev; +- + /* + * Finally, enable the serial port + */ +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/drivers/serial/jsm/jsm_driver.c linux-2.6.29-rc3.owrt/drivers/serial/jsm/jsm_driver.c +--- linux-2.6.29.owrt/drivers/serial/jsm/jsm_driver.c 2009-05-10 22:04:38.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/drivers/serial/jsm/jsm_driver.c 2009-05-10 23:48:29.000000000 +0200 +@@ -84,8 +84,6 @@ + brd->pci_dev = pdev; + if (pdev->device == PCIE_DEVICE_ID_NEO_4_IBM) + brd->maxports = 4; +- else if (pdev->device == PCI_DEVICE_ID_DIGI_NEO_8) +- brd->maxports = 8; + else + brd->maxports = 2; + +@@ -214,7 +212,6 @@ + { PCI_DEVICE(PCI_VENDOR_ID_DIGI, PCI_DEVICE_ID_NEO_2RJ45), 0, 0, 2 }, + { PCI_DEVICE(PCI_VENDOR_ID_DIGI, PCI_DEVICE_ID_NEO_2RJ45PRI), 0, 0, 3 }, + { PCI_DEVICE(PCI_VENDOR_ID_DIGI, PCIE_DEVICE_ID_NEO_4_IBM), 0, 0, 4 }, +- { PCI_DEVICE(PCI_VENDOR_ID_DIGI, PCI_DEVICE_ID_DIGI_NEO_8), 0, 0, 5 }, + { 0, } + }; + MODULE_DEVICE_TABLE(pci, jsm_pci_tbl); +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/drivers/serial/jsm/jsm_tty.c linux-2.6.29-rc3.owrt/drivers/serial/jsm/jsm_tty.c +--- linux-2.6.29.owrt/drivers/serial/jsm/jsm_tty.c 2009-05-10 22:04:38.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/drivers/serial/jsm/jsm_tty.c 2009-05-10 23:48:29.000000000 +0200 +@@ -161,11 +161,6 @@ + channel->ch_bd->bd_ops->disable_receiver(channel); + } + +-static void jsm_tty_enable_ms(struct uart_port *port) +-{ +- /* Nothing needed */ +-} +- + static void jsm_tty_break(struct uart_port *port, int break_state) + { + unsigned long lock_flags; +@@ -350,7 +345,6 @@ + .start_tx = jsm_tty_start_tx, + .send_xchar = jsm_tty_send_xchar, + .stop_rx = jsm_tty_stop_rx, +- .enable_ms = jsm_tty_enable_ms, + .break_ctl = jsm_tty_break, + .startup = jsm_tty_open, + .shutdown = jsm_tty_close, +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/drivers/serial/sh-sci.h linux-2.6.29-rc3.owrt/drivers/serial/sh-sci.h +--- linux-2.6.29.owrt/drivers/serial/sh-sci.h 2009-05-10 22:04:38.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/drivers/serial/sh-sci.h 2009-05-10 23:48:29.000000000 +0200 +@@ -133,7 +133,7 @@ + # define SCSPTR3 0xffed0024 /* 16 bit SCIF */ + # define SCSPTR4 0xffee0024 /* 16 bit SCIF */ + # define SCSPTR5 0xffef0024 /* 16 bit SCIF */ +-# define SCIF_ORER 0x0001 /* Overrun error bit */ ++# define SCIF_OPER 0x0001 /* Overrun error bit */ + # define SCSCR_INIT(port) 0x3a /* TIE=0,RIE=0,TE=1,RE=1,REIE=1 */ + #elif defined(CONFIG_CPU_SUBTYPE_SH7201) || \ + defined(CONFIG_CPU_SUBTYPE_SH7203) || \ +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/drivers/spi/spi_gpio.c linux-2.6.29-rc3.owrt/drivers/spi/spi_gpio.c +--- linux-2.6.29.owrt/drivers/spi/spi_gpio.c 2009-05-10 22:04:38.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/drivers/spi/spi_gpio.c 2009-05-10 23:48:29.000000000 +0200 +@@ -117,7 +117,7 @@ + + static inline int getmiso(const struct spi_device *spi) + { +- return !!gpio_get_value(SPI_MISO_GPIO); ++ return gpio_get_value(SPI_MISO_GPIO); + } + + #undef pdata +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/drivers/staging/agnx/agnx.h linux-2.6.29-rc3.owrt/drivers/staging/agnx/agnx.h +--- linux-2.6.29.owrt/drivers/staging/agnx/agnx.h 2009-05-10 22:04:38.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/drivers/staging/agnx/agnx.h 2009-05-10 23:48:29.000000000 +0200 +@@ -1,8 +1,6 @@ + #ifndef AGNX_H_ + #define AGNX_H_ + +-#include <linux/io.h> +- + #include "xmit.h" + + #define PFX KBUILD_MODNAME ": " +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/drivers/staging/altpciechdma/altpciechdma.c linux-2.6.29-rc3.owrt/drivers/staging/altpciechdma/altpciechdma.c +--- linux-2.6.29.owrt/drivers/staging/altpciechdma/altpciechdma.c 2009-05-10 22:04:38.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/drivers/staging/altpciechdma/altpciechdma.c 2009-05-10 23:48:29.000000000 +0200 +@@ -531,7 +531,7 @@ + goto fail; + + /* allocate and map coherently-cached memory for a DMA-able buffer */ +- /* @see Documentation/PCI/PCI-DMA-mapping.txt, near line 318 */ ++ /* @see 2.6.26.2/Documentation/DMA-mapping.txt line 318 */ + buffer_virt = (u8 *)pci_alloc_consistent(dev, PAGE_SIZE * 4, &buffer_bus); + if (!buffer_virt) { + printk(KERN_DEBUG "Could not allocate coherent DMA buffer.\n"); +@@ -846,7 +846,7 @@ + + #if 1 // @todo For now, disable 64-bit, because I do not understand the implications (DAC!) + /* query for DMA transfer */ +- /* @see Documentation/PCI/PCI-DMA-mapping.txt */ ++ /* @see Documentation/DMA-mapping.txt */ + if (!pci_set_dma_mask(dev, DMA_64BIT_MASK)) { + pci_set_consistent_dma_mask(dev, DMA_64BIT_MASK); + /* use 64-bit DMA */ +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/drivers/staging/android/binder.c linux-2.6.29-rc3.owrt/drivers/staging/android/binder.c +--- linux-2.6.29.owrt/drivers/staging/android/binder.c 2009-05-10 22:04:38.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/drivers/staging/android/binder.c 2009-05-10 23:48:29.000000000 +0200 +@@ -319,7 +319,6 @@ + int fd, error; + struct fdtable *fdt; + unsigned long rlim_cur; +- unsigned long irqs; + + if (files == NULL) + return -ESRCH; +@@ -336,11 +335,12 @@ + * N.B. For clone tasks sharing a files structure, this test + * will limit the total number of files that can be opened. + */ +- rlim_cur = 0; +- if (lock_task_sighand(tsk, &irqs)) { ++ rcu_read_lock(); ++ if (tsk->signal) + rlim_cur = tsk->signal->rlim[RLIMIT_NOFILE].rlim_cur; +- unlock_task_sighand(tsk, &irqs); +- } ++ else ++ rlim_cur = 0; ++ rcu_read_unlock(); + if (fd >= rlim_cur) + goto out; + +@@ -2649,14 +2649,14 @@ + { + struct binder_proc *proc = vma->vm_private_data; + if (binder_debug_mask & BINDER_DEBUG_OPEN_CLOSE) +- printk(KERN_INFO "binder: %d open vm area %lx-%lx (%ld K) vma %lx pagep %lx\n", proc->pid, vma->vm_start, vma->vm_end, (vma->vm_end - vma->vm_start) / SZ_1K, vma->vm_flags, pgprot_val(vma->vm_page_prot)); ++ printk(KERN_INFO "binder: %d open vm area %lx-%lx (%ld K) vma %lx pagep %lx\n", proc->pid, vma->vm_start, vma->vm_end, (vma->vm_end - vma->vm_start) / SZ_1K, vma->vm_flags, vma->vm_page_prot.pgprot); + dump_stack(); + } + static void binder_vma_close(struct vm_area_struct *vma) + { + struct binder_proc *proc = vma->vm_private_data; + if (binder_debug_mask & BINDER_DEBUG_OPEN_CLOSE) +- printk(KERN_INFO "binder: %d close vm area %lx-%lx (%ld K) vma %lx pagep %lx\n", proc->pid, vma->vm_start, vma->vm_end, (vma->vm_end - vma->vm_start) / SZ_1K, vma->vm_flags, pgprot_val(vma->vm_page_prot)); ++ printk(KERN_INFO "binder: %d close vm area %lx-%lx (%ld K) vma %lx pagep %lx\n", proc->pid, vma->vm_start, vma->vm_end, (vma->vm_end - vma->vm_start) / SZ_1K, vma->vm_flags, vma->vm_page_prot.pgprot); + proc->vma = NULL; + } + +@@ -2677,7 +2677,7 @@ + vma->vm_end = vma->vm_start + SZ_4M; + + if (binder_debug_mask & BINDER_DEBUG_OPEN_CLOSE) +- printk(KERN_INFO "binder_mmap: %d %lx-%lx (%ld K) vma %lx pagep %lx\n", proc->pid, vma->vm_start, vma->vm_end, (vma->vm_end - vma->vm_start) / SZ_1K, vma->vm_flags, pgprot_val(vma->vm_page_prot)); ++ printk(KERN_INFO "binder_mmap: %d %lx-%lx (%ld K) vma %lx pagep %lx\n", proc->pid, vma->vm_start, vma->vm_end, (vma->vm_end - vma->vm_start) / SZ_1K, vma->vm_flags, vma->vm_page_prot.pgprot); + + if (vma->vm_flags & FORBIDDEN_MMAP_FLAGS) { + ret = -EPERM; +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/drivers/staging/android/Kconfig linux-2.6.29-rc3.owrt/drivers/staging/android/Kconfig +--- linux-2.6.29.owrt/drivers/staging/android/Kconfig 2009-05-10 22:04:38.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/drivers/staging/android/Kconfig 2009-05-10 23:48:29.000000000 +0200 +@@ -27,7 +27,6 @@ + bool "Android RAM Console Enable error correction" + default n + depends on ANDROID_RAM_CONSOLE +- depends on !ANDROID_RAM_CONSOLE_EARLY_INIT + select REED_SOLOMON + select REED_SOLOMON_ENC8 + select REED_SOLOMON_DEC8 +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/drivers/staging/android/lowmemorykiller.txt linux-2.6.29-rc3.owrt/drivers/staging/android/lowmemorykiller.txt +--- linux-2.6.29.owrt/drivers/staging/android/lowmemorykiller.txt 2009-05-10 22:04:38.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/drivers/staging/android/lowmemorykiller.txt 1970-01-01 01:00:00.000000000 +0100 +@@ -1,16 +0,0 @@ +-The lowmemorykiller driver lets user-space specify a set of memory thresholds +-where processes with a range of oom_adj values will get killed. Specify the +-minimum oom_adj values in /sys/module/lowmemorykiller/parameters/adj and the +-number of free pages in /sys/module/lowmemorykiller/parameters/minfree. Both +-files take a comma separated list of numbers in ascending order. +- +-For example, write "0,8" to /sys/module/lowmemorykiller/parameters/adj and +-"1024,4096" to /sys/module/lowmemorykiller/parameters/minfree to kill processes +-with a oom_adj value of 8 or higher when the free memory drops below 4096 pages +-and kill processes with a oom_adj value of 0 or higher when the free memory +-drops below 1024 pages. +- +-The driver considers memory used for caches to be free, but if a large +-percentage of the cached memory is locked this can be very inaccurate +-and processes may not get killed until the normal oom killer is triggered. +- +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/drivers/staging/android/ram_console.c linux-2.6.29-rc3.owrt/drivers/staging/android/ram_console.c +--- linux-2.6.29.owrt/drivers/staging/android/ram_console.c 2009-05-10 22:04:38.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/drivers/staging/android/ram_console.c 2009-05-10 23:48:29.000000000 +0200 +@@ -224,23 +224,9 @@ + ram_console_buffer_size = + buffer_size - sizeof(struct ram_console_buffer); + +- if (ram_console_buffer_size > buffer_size) { +- pr_err("ram_console: buffer %p, invalid size %d, datasize %d\n", +- buffer, buffer_size, ram_console_buffer_size); +- return 0; +- } +- + #ifdef CONFIG_ANDROID_RAM_CONSOLE_ERROR_CORRECTION + ram_console_buffer_size -= (DIV_ROUND_UP(ram_console_buffer_size, + ECC_BLOCK_SIZE) + 1) * ECC_SIZE; +- +- if (ram_console_buffer_size > buffer_size) { +- pr_err("ram_console: buffer %p, invalid size %d, " +- "non-ecc datasize %d\n", +- buffer, buffer_size, ram_console_buffer_size); +- return 0; +- } +- + ram_console_par_buffer = buffer->data + ram_console_buffer_size; + + +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/drivers/staging/android/timed_gpio.c linux-2.6.29-rc3.owrt/drivers/staging/android/timed_gpio.c +--- linux-2.6.29.owrt/drivers/staging/android/timed_gpio.c 2009-05-10 22:04:38.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/drivers/staging/android/timed_gpio.c 2009-05-10 23:48:29.000000000 +0200 +@@ -18,7 +18,7 @@ + #include <linux/platform_device.h> + #include <linux/hrtimer.h> + #include <linux/err.h> +-#include <linux/gpio.h> ++#include <asm/arch/gpio.h> + + #include "timed_gpio.h" + +@@ -49,8 +49,7 @@ + + if (hrtimer_active(&gpio_data->timer)) { + ktime_t r = hrtimer_get_remaining(&gpio_data->timer); +- struct timeval t = ktime_to_timeval(r); +- remaining = t.tv_sec * 1000 + t.tv_usec / 1000; ++ remaining = r.tv.sec * 1000 + r.tv.nsec / 1000000; + } else + remaining = 0; + +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/drivers/staging/at76_usb/at76_usb.c linux-2.6.29-rc3.owrt/drivers/staging/at76_usb/at76_usb.c +--- linux-2.6.29.owrt/drivers/staging/at76_usb/at76_usb.c 2009-05-10 22:04:38.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/drivers/staging/at76_usb/at76_usb.c 2009-05-10 23:48:29.000000000 +0200 +@@ -6,6 +6,7 @@ + * Copyright (c) 2004 Nick Jones + * Copyright (c) 2004 Balint Seeber <n0_5p4m_p13453@hotmail.com> + * Copyright (c) 2007 Guido Guenther <agx@sigxcpu.org> ++ * Copyright (c) 2007 Kalle Valo <kalle.valo@iki.fi> + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as +@@ -16,6 +17,13 @@ + * Atmel AT76C503A/505/505A. + * + * Some iw_handler code was taken from airo.c, (C) 1999 Benjamin Reed ++ * ++ * TODO for the mac80211 port: ++ * o adhoc support ++ * o RTS/CTS support ++ * o Power Save Mode support ++ * o support for short/long preambles ++ * o export variables through debugfs/sysfs + */ + + #include <linux/init.h> +@@ -36,7 +44,7 @@ + #include <net/ieee80211_radiotap.h> + #include <linux/firmware.h> + #include <linux/leds.h> +-#include <net/ieee80211.h> ++#include <net/mac80211.h> + + #include "at76_usb.h" + +@@ -76,31 +84,43 @@ + #define DBG_WE_EVENTS 0x08000000 /* dump wireless events */ + #define DBG_FW 0x10000000 /* firmware download */ + #define DBG_DFU 0x20000000 /* device firmware upgrade */ ++#define DBG_CMD 0x40000000 ++#define DBG_MAC80211 0x80000000 + + #define DBG_DEFAULTS 0 + + /* Use our own dbg macro */ + #define at76_dbg(bits, format, arg...) \ +- do { \ +- if (at76_debug & (bits)) \ ++do { \ ++ if (at76_debug & (bits)) \ ++ printk(KERN_DEBUG DRIVER_NAME ": " format "\n" , ## arg); \ ++} while (0) ++ ++#define at76_dbg_dump(bits, buf, len, format, arg...) \ ++do { \ ++ if (at76_debug & (bits)) { \ + printk(KERN_DEBUG DRIVER_NAME ": " format "\n" , ## arg); \ +- } while (0) ++ print_hex_dump_bytes("", DUMP_PREFIX_OFFSET, buf, len); \ ++ } \ ++} while (0) + + static int at76_debug = DBG_DEFAULTS; + ++#define FIRMWARE_IS_WPA(ver) ((ver.major == 1) && (ver.minor == 103)) ++ + /* Protect against concurrent firmware loading and parsing */ + static struct mutex fw_mutex; + + static struct fwentry firmwares[] = { +- [0] = {""}, +- [BOARD_503_ISL3861] = {"atmel_at76c503-i3861.bin"}, +- [BOARD_503_ISL3863] = {"atmel_at76c503-i3863.bin"}, +- [BOARD_503] = {"atmel_at76c503-rfmd.bin"}, +- [BOARD_503_ACC] = {"atmel_at76c503-rfmd-acc.bin"}, +- [BOARD_505] = {"atmel_at76c505-rfmd.bin"}, +- [BOARD_505_2958] = {"atmel_at76c505-rfmd2958.bin"}, +- [BOARD_505A] = {"atmel_at76c505a-rfmd2958.bin"}, +- [BOARD_505AMX] = {"atmel_at76c505amx-rfmd.bin"}, ++ [0] = { "" }, ++ [BOARD_503_ISL3861] = { "atmel_at76c503-i3861.bin" }, ++ [BOARD_503_ISL3863] = { "atmel_at76c503-i3863.bin" }, ++ [BOARD_503] = { "atmel_at76c503-rfmd.bin" }, ++ [BOARD_503_ACC] = { "atmel_at76c503-rfmd-acc.bin" }, ++ [BOARD_505] = { "atmel_at76c505-rfmd.bin" }, ++ [BOARD_505_2958] = { "atmel_at76c505-rfmd2958.bin" }, ++ [BOARD_505A] = { "atmel_at76c505a-rfmd2958.bin" }, ++ [BOARD_505AMX] = { "atmel_at76c505amx-rfmd.bin" }, + }; + + #define USB_DEVICE_DATA(__ops) .driver_info = (kernel_ulong_t)(__ops) +@@ -110,135 +130,133 @@ + * at76c503-i3861 + */ + /* Generic AT76C503/3861 device */ +- {USB_DEVICE(0x03eb, 0x7603), USB_DEVICE_DATA(BOARD_503_ISL3861)}, ++ { USB_DEVICE(0x03eb, 0x7603), USB_DEVICE_DATA(BOARD_503_ISL3861) }, + /* Linksys WUSB11 v2.1/v2.6 */ +- {USB_DEVICE(0x066b, 0x2211), USB_DEVICE_DATA(BOARD_503_ISL3861)}, ++ { USB_DEVICE(0x066b, 0x2211), USB_DEVICE_DATA(BOARD_503_ISL3861) }, + /* Netgear MA101 rev. A */ +- {USB_DEVICE(0x0864, 0x4100), USB_DEVICE_DATA(BOARD_503_ISL3861)}, ++ { USB_DEVICE(0x0864, 0x4100), USB_DEVICE_DATA(BOARD_503_ISL3861) }, + /* Tekram U300C / Allnet ALL0193 */ +- {USB_DEVICE(0x0b3b, 0x1612), USB_DEVICE_DATA(BOARD_503_ISL3861)}, ++ { USB_DEVICE(0x0b3b, 0x1612), USB_DEVICE_DATA(BOARD_503_ISL3861) }, + /* HP HN210W J7801A */ +- {USB_DEVICE(0x03f0, 0x011c), USB_DEVICE_DATA(BOARD_503_ISL3861)}, ++ { USB_DEVICE(0x03f0, 0x011c), USB_DEVICE_DATA(BOARD_503_ISL3861) }, + /* Sitecom/Z-Com/Zyxel M4Y-750 */ +- {USB_DEVICE(0x0cde, 0x0001), USB_DEVICE_DATA(BOARD_503_ISL3861)}, ++ { USB_DEVICE(0x0cde, 0x0001), USB_DEVICE_DATA(BOARD_503_ISL3861) }, + /* Dynalink/Askey WLL013 (intersil) */ +- {USB_DEVICE(0x069a, 0x0320), USB_DEVICE_DATA(BOARD_503_ISL3861)}, ++ { USB_DEVICE(0x069a, 0x0320), USB_DEVICE_DATA(BOARD_503_ISL3861) }, + /* EZ connect 11Mpbs Wireless USB Adapter SMC2662W v1 */ +- {USB_DEVICE(0x0d5c, 0xa001), USB_DEVICE_DATA(BOARD_503_ISL3861)}, ++ { USB_DEVICE(0x0d5c, 0xa001), USB_DEVICE_DATA(BOARD_503_ISL3861) }, + /* BenQ AWL300 */ +- {USB_DEVICE(0x04a5, 0x9000), USB_DEVICE_DATA(BOARD_503_ISL3861)}, ++ { USB_DEVICE(0x04a5, 0x9000), USB_DEVICE_DATA(BOARD_503_ISL3861) }, + /* Addtron AWU-120, Compex WLU11 */ +- {USB_DEVICE(0x05dd, 0xff31), USB_DEVICE_DATA(BOARD_503_ISL3861)}, ++ { USB_DEVICE(0x05dd, 0xff31), USB_DEVICE_DATA(BOARD_503_ISL3861) }, + /* Intel AP310 AnyPoint II USB */ +- {USB_DEVICE(0x8086, 0x0200), USB_DEVICE_DATA(BOARD_503_ISL3861)}, ++ { USB_DEVICE(0x8086, 0x0200), USB_DEVICE_DATA(BOARD_503_ISL3861) }, + /* Dynalink L11U */ +- {USB_DEVICE(0x0d8e, 0x7100), USB_DEVICE_DATA(BOARD_503_ISL3861)}, ++ { USB_DEVICE(0x0d8e, 0x7100), USB_DEVICE_DATA(BOARD_503_ISL3861) }, + /* Arescom WL-210, FCC id 07J-GL2411USB */ +- {USB_DEVICE(0x0d8e, 0x7110), USB_DEVICE_DATA(BOARD_503_ISL3861)}, ++ { USB_DEVICE(0x0d8e, 0x7110), USB_DEVICE_DATA(BOARD_503_ISL3861) }, + /* I-O DATA WN-B11/USB */ +- {USB_DEVICE(0x04bb, 0x0919), USB_DEVICE_DATA(BOARD_503_ISL3861)}, ++ { USB_DEVICE(0x04bb, 0x0919), USB_DEVICE_DATA(BOARD_503_ISL3861) }, + /* BT Voyager 1010 */ +- {USB_DEVICE(0x069a, 0x0821), USB_DEVICE_DATA(BOARD_503_ISL3861)}, ++ { USB_DEVICE(0x069a, 0x0821), USB_DEVICE_DATA(BOARD_503_ISL3861) }, + /* + * at76c503-i3863 + */ + /* Generic AT76C503/3863 device */ +- {USB_DEVICE(0x03eb, 0x7604), USB_DEVICE_DATA(BOARD_503_ISL3863)}, ++ { USB_DEVICE(0x03eb, 0x7604), USB_DEVICE_DATA(BOARD_503_ISL3863) }, + /* Samsung SWL-2100U */ +- {USB_DEVICE(0x055d, 0xa000), USB_DEVICE_DATA(BOARD_503_ISL3863)}, ++ { USB_DEVICE(0x055d, 0xa000), USB_DEVICE_DATA(BOARD_503_ISL3863) }, + /* + * at76c503-rfmd + */ + /* Generic AT76C503/RFMD device */ +- {USB_DEVICE(0x03eb, 0x7605), USB_DEVICE_DATA(BOARD_503)}, ++ { USB_DEVICE(0x03eb, 0x7605), USB_DEVICE_DATA(BOARD_503) }, + /* Dynalink/Askey WLL013 (rfmd) */ +- {USB_DEVICE(0x069a, 0x0321), USB_DEVICE_DATA(BOARD_503)}, ++ { USB_DEVICE(0x069a, 0x0321), USB_DEVICE_DATA(BOARD_503) }, + /* Linksys WUSB11 v2.6 */ +- {USB_DEVICE(0x077b, 0x2219), USB_DEVICE_DATA(BOARD_503)}, ++ { USB_DEVICE(0x077b, 0x2219), USB_DEVICE_DATA(BOARD_503) }, + /* Network Everywhere NWU11B */ +- {USB_DEVICE(0x077b, 0x2227), USB_DEVICE_DATA(BOARD_503)}, ++ { USB_DEVICE(0x077b, 0x2227), USB_DEVICE_DATA(BOARD_503) }, + /* Netgear MA101 rev. B */ +- {USB_DEVICE(0x0864, 0x4102), USB_DEVICE_DATA(BOARD_503)}, ++ { USB_DEVICE(0x0864, 0x4102), USB_DEVICE_DATA(BOARD_503) }, + /* D-Link DWL-120 rev. E */ +- {USB_DEVICE(0x2001, 0x3200), USB_DEVICE_DATA(BOARD_503)}, ++ { USB_DEVICE(0x2001, 0x3200), USB_DEVICE_DATA(BOARD_503) }, + /* Actiontec 802UAT1, HWU01150-01UK */ +- {USB_DEVICE(0x1668, 0x7605), USB_DEVICE_DATA(BOARD_503)}, ++ { USB_DEVICE(0x1668, 0x7605), USB_DEVICE_DATA(BOARD_503) }, + /* AirVast W-Buddie WN210 */ +- {USB_DEVICE(0x03eb, 0x4102), USB_DEVICE_DATA(BOARD_503)}, ++ { USB_DEVICE(0x03eb, 0x4102), USB_DEVICE_DATA(BOARD_503) }, + /* Dick Smith Electronics XH1153 802.11b USB adapter */ +- {USB_DEVICE(0x1371, 0x5743), USB_DEVICE_DATA(BOARD_503)}, ++ { USB_DEVICE(0x1371, 0x5743), USB_DEVICE_DATA(BOARD_503) }, + /* CNet CNUSB611 */ +- {USB_DEVICE(0x1371, 0x0001), USB_DEVICE_DATA(BOARD_503)}, ++ { USB_DEVICE(0x1371, 0x0001), USB_DEVICE_DATA(BOARD_503) }, + /* FiberLine FL-WL200U */ +- {USB_DEVICE(0x1371, 0x0002), USB_DEVICE_DATA(BOARD_503)}, ++ { USB_DEVICE(0x1371, 0x0002), USB_DEVICE_DATA(BOARD_503) }, + /* BenQ AWL400 USB stick */ +- {USB_DEVICE(0x04a5, 0x9001), USB_DEVICE_DATA(BOARD_503)}, ++ { USB_DEVICE(0x04a5, 0x9001), USB_DEVICE_DATA(BOARD_503) }, + /* 3Com 3CRSHEW696 */ +- {USB_DEVICE(0x0506, 0x0a01), USB_DEVICE_DATA(BOARD_503)}, ++ { USB_DEVICE(0x0506, 0x0a01), USB_DEVICE_DATA(BOARD_503) }, + /* Siemens Santis ADSL WLAN USB adapter WLL 013 */ +- {USB_DEVICE(0x0681, 0x001b), USB_DEVICE_DATA(BOARD_503)}, ++ { USB_DEVICE(0x0681, 0x001b), USB_DEVICE_DATA(BOARD_503) }, + /* Belkin F5D6050, version 2 */ +- {USB_DEVICE(0x050d, 0x0050), USB_DEVICE_DATA(BOARD_503)}, ++ { USB_DEVICE(0x050d, 0x0050), USB_DEVICE_DATA(BOARD_503) }, + /* iBlitzz, BWU613 (not *B or *SB) */ +- {USB_DEVICE(0x07b8, 0xb000), USB_DEVICE_DATA(BOARD_503)}, ++ { USB_DEVICE(0x07b8, 0xb000), USB_DEVICE_DATA(BOARD_503) }, + /* Gigabyte GN-WLBM101 */ +- {USB_DEVICE(0x1044, 0x8003), USB_DEVICE_DATA(BOARD_503)}, ++ { USB_DEVICE(0x1044, 0x8003), USB_DEVICE_DATA(BOARD_503) }, + /* Planex GW-US11S */ +- {USB_DEVICE(0x2019, 0x3220), USB_DEVICE_DATA(BOARD_503)}, ++ { USB_DEVICE(0x2019, 0x3220), USB_DEVICE_DATA(BOARD_503) }, + /* Internal WLAN adapter in h5[4,5]xx series iPAQs */ +- {USB_DEVICE(0x049f, 0x0032), USB_DEVICE_DATA(BOARD_503)}, ++ { USB_DEVICE(0x049f, 0x0032), USB_DEVICE_DATA(BOARD_503) }, + /* Corega Wireless LAN USB-11 mini */ +- {USB_DEVICE(0x07aa, 0x0011), USB_DEVICE_DATA(BOARD_503)}, ++ { USB_DEVICE(0x07aa, 0x0011), USB_DEVICE_DATA(BOARD_503) }, + /* Corega Wireless LAN USB-11 mini2 */ +- {USB_DEVICE(0x07aa, 0x0018), USB_DEVICE_DATA(BOARD_503)}, ++ { USB_DEVICE(0x07aa, 0x0018), USB_DEVICE_DATA(BOARD_503) }, + /* Uniden PCW100 */ +- {USB_DEVICE(0x05dd, 0xff35), USB_DEVICE_DATA(BOARD_503)}, ++ { USB_DEVICE(0x05dd, 0xff35), USB_DEVICE_DATA(BOARD_503) }, + /* + * at76c503-rfmd-acc + */ + /* SMC2664W */ +- {USB_DEVICE(0x083a, 0x3501), USB_DEVICE_DATA(BOARD_503_ACC)}, ++ { USB_DEVICE(0x083a, 0x3501), USB_DEVICE_DATA(BOARD_503_ACC) }, + /* Belkin F5D6050, SMC2662W v2, SMC2662W-AR */ +- {USB_DEVICE(0x0d5c, 0xa002), USB_DEVICE_DATA(BOARD_503_ACC)}, ++ { USB_DEVICE(0x0d5c, 0xa002), USB_DEVICE_DATA(BOARD_503_ACC) }, + /* + * at76c505-rfmd + */ + /* Generic AT76C505/RFMD */ +- {USB_DEVICE(0x03eb, 0x7606), USB_DEVICE_DATA(BOARD_505)}, ++ { USB_DEVICE(0x03eb, 0x7606), USB_DEVICE_DATA(BOARD_505) }, + /* + * at76c505-rfmd2958 + */ + /* Generic AT76C505/RFMD, OvisLink WL-1130USB */ +- {USB_DEVICE(0x03eb, 0x7613), USB_DEVICE_DATA(BOARD_505_2958)}, ++ { USB_DEVICE(0x03eb, 0x7613), USB_DEVICE_DATA(BOARD_505_2958) }, + /* Fiberline FL-WL240U */ +- {USB_DEVICE(0x1371, 0x0014), USB_DEVICE_DATA(BOARD_505_2958)}, ++ { USB_DEVICE(0x1371, 0x0014), USB_DEVICE_DATA(BOARD_505_2958) }, + /* CNet CNUSB-611G */ +- {USB_DEVICE(0x1371, 0x0013), USB_DEVICE_DATA(BOARD_505_2958)}, ++ { USB_DEVICE(0x1371, 0x0013), USB_DEVICE_DATA(BOARD_505_2958) }, + /* Linksys WUSB11 v2.8 */ +- {USB_DEVICE(0x1915, 0x2233), USB_DEVICE_DATA(BOARD_505_2958)}, ++ { USB_DEVICE(0x1915, 0x2233), USB_DEVICE_DATA(BOARD_505_2958) }, + /* Xterasys XN-2122B, IBlitzz BWU613B/BWU613SB */ +- {USB_DEVICE(0x12fd, 0x1001), USB_DEVICE_DATA(BOARD_505_2958)}, ++ { USB_DEVICE(0x12fd, 0x1001), USB_DEVICE_DATA(BOARD_505_2958) }, + /* Corega WLAN USB Stick 11 */ +- {USB_DEVICE(0x07aa, 0x7613), USB_DEVICE_DATA(BOARD_505_2958)}, ++ { USB_DEVICE(0x07aa, 0x7613), USB_DEVICE_DATA(BOARD_505_2958) }, + /* Microstar MSI Box MS6978 */ +- {USB_DEVICE(0x0db0, 0x1020), USB_DEVICE_DATA(BOARD_505_2958)}, ++ { USB_DEVICE(0x0db0, 0x1020), USB_DEVICE_DATA(BOARD_505_2958) }, + /* + * at76c505a-rfmd2958 + */ + /* Generic AT76C505A device */ +- {USB_DEVICE(0x03eb, 0x7614), USB_DEVICE_DATA(BOARD_505A)}, ++ { USB_DEVICE(0x03eb, 0x7614), USB_DEVICE_DATA(BOARD_505A) }, + /* Generic AT76C505AS device */ +- {USB_DEVICE(0x03eb, 0x7617), USB_DEVICE_DATA(BOARD_505A)}, ++ { USB_DEVICE(0x03eb, 0x7617), USB_DEVICE_DATA(BOARD_505A) }, + /* Siemens Gigaset USB WLAN Adapter 11 */ +- {USB_DEVICE(0x1690, 0x0701), USB_DEVICE_DATA(BOARD_505A)}, +- /* OQO Model 01+ Internal Wi-Fi */ +- {USB_DEVICE(0x1557, 0x0002), USB_DEVICE_DATA(BOARD_505A)}, ++ { USB_DEVICE(0x1690, 0x0701), USB_DEVICE_DATA(BOARD_505A) }, + /* + * at76c505amx-rfmd + */ + /* Generic AT76C505AMX device */ +- {USB_DEVICE(0x03eb, 0x7615), USB_DEVICE_DATA(BOARD_505AMX)}, +- {} ++ { USB_DEVICE(0x03eb, 0x7615), USB_DEVICE_DATA(BOARD_505AMX) }, ++ { } + }; + + MODULE_DEVICE_TABLE(usb, dev_table); +@@ -246,26 +264,8 @@ + /* Supported rates of this hardware, bit 7 marks basic rates */ + static const u8 hw_rates[] = { 0x82, 0x84, 0x0b, 0x16 }; + +-/* Frequency of each channel in MHz */ +-static const long channel_frequency[] = { +- 2412, 2417, 2422, 2427, 2432, 2437, 2442, +- 2447, 2452, 2457, 2462, 2467, 2472, 2484 +-}; +- +-#define NUM_CHANNELS ARRAY_SIZE(channel_frequency) +- + static const char *const preambles[] = { "long", "short", "auto" }; + +-static const char *const mac_states[] = { +- [MAC_INIT] = "INIT", +- [MAC_SCANNING] = "SCANNING", +- [MAC_AUTH] = "AUTH", +- [MAC_ASSOC] = "ASSOC", +- [MAC_JOINING] = "JOINING", +- [MAC_CONNECTED] = "CONNECTED", +- [MAC_OWN_IBSS] = "OWN_IBSS" +-}; +- + /* Firmware download */ + /* DFU states */ + #define STATE_IDLE 0x00 +@@ -300,17 +300,30 @@ + + static inline int at76_is_intersil(enum board_type board) + { +- return (board == BOARD_503_ISL3861 || board == BOARD_503_ISL3863); ++ if (board == BOARD_503_ISL3861 || board == BOARD_503_ISL3863) ++ return 1; ++ return 0; + } + + static inline int at76_is_503rfmd(enum board_type board) + { +- return (board == BOARD_503 || board == BOARD_503_ACC); ++ if (board == BOARD_503 || board == BOARD_503_ACC) ++ return 1; ++ return 0; ++} ++ ++static inline int at76_is_505(enum board_type board) ++{ ++ if (board == BOARD_505 || board == BOARD_505_2958) ++ return 1; ++ return 0; + } + + static inline int at76_is_505a(enum board_type board) + { +- return (board == BOARD_505A || board == BOARD_505AMX); ++ if (board == BOARD_505A || board == BOARD_505AMX) ++ return 1; ++ return 0; + } + + /* Load a block of the first (internal) part of the firmware */ +@@ -491,41 +504,6 @@ + return ret; + } + +-/* Report that the scan results are ready */ +-static inline void at76_iwevent_scan_complete(struct net_device *netdev) +-{ +- union iwreq_data wrqu; +- wrqu.data.length = 0; +- wrqu.data.flags = 0; +- wireless_send_event(netdev, SIOCGIWSCAN, &wrqu, NULL); +- at76_dbg(DBG_WE_EVENTS, "%s: SIOCGIWSCAN sent", netdev->name); +-} +- +-static inline void at76_iwevent_bss_connect(struct net_device *netdev, +- u8 *bssid) +-{ +- union iwreq_data wrqu; +- wrqu.data.length = 0; +- wrqu.data.flags = 0; +- memcpy(wrqu.ap_addr.sa_data, bssid, ETH_ALEN); +- wrqu.ap_addr.sa_family = ARPHRD_ETHER; +- wireless_send_event(netdev, SIOCGIWAP, &wrqu, NULL); +- at76_dbg(DBG_WE_EVENTS, "%s: %s: SIOCGIWAP sent", netdev->name, +- __func__); +-} +- +-static inline void at76_iwevent_bss_disconnect(struct net_device *netdev) +-{ +- union iwreq_data wrqu; +- wrqu.data.length = 0; +- wrqu.data.flags = 0; +- memset(wrqu.ap_addr.sa_data, 0, ETH_ALEN); +- wrqu.ap_addr.sa_family = ARPHRD_ETHER; +- wireless_send_event(netdev, SIOCGIWAP, &wrqu, NULL); +- at76_dbg(DBG_WE_EVENTS, "%s: %s: SIOCGIWAP sent", netdev->name, +- __func__); +-} +- + #define HEX2STR_BUFFERS 4 + #define HEX2STR_MAX_LEN 64 + #define BIN2HEX(x) ((x) < 10 ? '0' + (x) : (x) + 'A' - 10) +@@ -597,37 +575,6 @@ + mod_timer(&ledtrig_tx_timer, jiffies + HZ / 4); + } + +-/* Check if the given ssid is hidden */ +-static inline int at76_is_hidden_ssid(u8 *ssid, int length) +-{ +- static const u8 zeros[32]; +- +- if (length == 0) +- return 1; +- +- if (length == 1 && ssid[0] == ' ') +- return 1; +- +- return (memcmp(ssid, zeros, length) == 0); +-} +- +-static inline void at76_free_bss_list(struct at76_priv *priv) +-{ +- struct list_head *next, *ptr; +- unsigned long flags; +- +- spin_lock_irqsave(&priv->bss_list_spinlock, flags); +- +- priv->curr_bss = NULL; +- +- list_for_each_safe(ptr, next, &priv->bss_list) { +- list_del(ptr); +- kfree(list_entry(ptr, struct bss_info, list)); +- } +- +- spin_unlock_irqrestore(&priv->bss_list_spinlock, flags); +-} +- + static int at76_remap(struct usb_device *udev) + { + int ret; +@@ -651,7 +598,7 @@ + return -ENOMEM; + ret = usb_control_msg(udev, usb_rcvctrlpipe(udev, 0), 0x33, + USB_TYPE_VENDOR | USB_DIR_IN | +- USB_RECIP_INTERFACE, 0x01, 0, op_mode, 1, ++ USB_RECIP_INTERFACE, 0x01, 0, &op_mode, 1, + USB_CTRL_GET_TIMEOUT); + saved = *op_mode; + kfree(op_mode); +@@ -729,7 +676,7 @@ + kfree(hwcfg); + if (ret < 0) + printk(KERN_ERR "%s: cannot get HW Config (error %d)\n", +- priv->netdev->name, ret); ++ wiphy_name(priv->hw->wiphy), ret); + + return ret; + } +@@ -738,15 +685,15 @@ + { + int i; + static struct reg_domain const fd_tab[] = { +- {0x10, "FCC (USA)", 0x7ff}, /* ch 1-11 */ +- {0x20, "IC (Canada)", 0x7ff}, /* ch 1-11 */ +- {0x30, "ETSI (most of Europe)", 0x1fff}, /* ch 1-13 */ +- {0x31, "Spain", 0x600}, /* ch 10-11 */ +- {0x32, "France", 0x1e00}, /* ch 10-13 */ +- {0x40, "MKK (Japan)", 0x2000}, /* ch 14 */ +- {0x41, "MKK1 (Japan)", 0x3fff}, /* ch 1-14 */ +- {0x50, "Israel", 0x3fc}, /* ch 3-9 */ +- {0x00, "<unknown>", 0xffffffff} /* ch 1-32 */ ++ { 0x10, "FCC (USA)", 0x7ff }, /* ch 1-11 */ ++ { 0x20, "IC (Canada)", 0x7ff }, /* ch 1-11 */ ++ { 0x30, "ETSI (most of Europe)", 0x1fff }, /* ch 1-13 */ ++ { 0x31, "Spain", 0x600 }, /* ch 10-11 */ ++ { 0x32, "France", 0x1e00 }, /* ch 10-13 */ ++ { 0x40, "MKK (Japan)", 0x2000 }, /* ch 14 */ ++ { 0x41, "MKK1 (Japan)", 0x3fff }, /* ch 1-14 */ ++ { 0x50, "Israel", 0x3fc }, /* ch 3-9 */ ++ { 0x00, "<unknown>", 0xffffffff } /* ch 1-32 */ + }; + + /* Last entry is fallback for unknown domain code */ +@@ -784,7 +731,7 @@ + ret = usb_control_msg(udev, usb_rcvctrlpipe(udev, 0), 0x22, + USB_TYPE_VENDOR | USB_DIR_IN | + USB_RECIP_INTERFACE, cmd, 0, stat_buf, +- 40, USB_CTRL_GET_TIMEOUT); ++ sizeof(stat_buf), USB_CTRL_GET_TIMEOUT); + if (ret >= 0) + ret = stat_buf[5]; + kfree(stat_buf); +@@ -792,6 +739,24 @@ + return ret; + } + ++#define MAKE_CMD_CASE(c) case (c): return #c ++ ++static const char *at76_get_cmd_string(u8 cmd_status) ++{ ++ switch (cmd_status) { ++ MAKE_CMD_CASE(CMD_SET_MIB); ++ MAKE_CMD_CASE(CMD_GET_MIB); ++ MAKE_CMD_CASE(CMD_SCAN); ++ MAKE_CMD_CASE(CMD_JOIN); ++ MAKE_CMD_CASE(CMD_START_IBSS); ++ MAKE_CMD_CASE(CMD_RADIO_ON); ++ MAKE_CMD_CASE(CMD_RADIO_OFF); ++ MAKE_CMD_CASE(CMD_STARTUP); ++ } ++ ++ return "UNKNOWN"; ++} ++ + static int at76_set_card_command(struct usb_device *udev, u8 cmd, void *buf, + int buf_size) + { +@@ -807,6 +772,10 @@ + cmd_buf->size = cpu_to_le16(buf_size); + memcpy(cmd_buf->data, buf, buf_size); + ++ at76_dbg_dump(DBG_CMD, cmd_buf, sizeof(struct at76_command) + buf_size, ++ "issuing command %s (0x%02x)", ++ at76_get_cmd_string(cmd), cmd); ++ + ret = usb_control_msg(udev, usb_sndctrlpipe(udev, 0), 0x0e, + USB_TYPE_VENDOR | USB_DIR_OUT | USB_RECIP_DEVICE, + 0, 0, cmd_buf, +@@ -844,13 +813,13 @@ + status = at76_get_cmd_status(priv->udev, cmd); + if (status < 0) { + printk(KERN_ERR "%s: at76_get_cmd_status failed: %d\n", +- priv->netdev->name, status); ++ wiphy_name(priv->hw->wiphy), status); + break; + } + + at76_dbg(DBG_WAIT_COMPLETE, + "%s: Waiting on cmd %d, status = %d (%s)", +- priv->netdev->name, cmd, status, ++ wiphy_name(priv->hw->wiphy), cmd, status, + at76_get_cmd_status_string(status)); + + if (status != CMD_STATUS_IN_PROGRESS +@@ -861,7 +830,7 @@ + if (time_after(jiffies, timeout)) { + printk(KERN_ERR + "%s: completion timeout for command %d\n", +- priv->netdev->name, cmd); ++ wiphy_name(priv->hw->wiphy), cmd); + status = -ETIMEDOUT; + break; + } +@@ -884,7 +853,7 @@ + if (ret != CMD_STATUS_COMPLETE) { + printk(KERN_INFO + "%s: set_mib: at76_wait_completion failed " +- "with %d\n", priv->netdev->name, ret); ++ "with %d\n", wiphy_name(priv->hw->wiphy), ret); + ret = -EIO; + } + +@@ -905,7 +874,7 @@ + ret = at76_set_card_command(priv->udev, cmd, NULL, 0); + if (ret < 0) + printk(KERN_ERR "%s: at76_set_card_command(%d) failed: %d\n", +- priv->netdev->name, cmd, ret); ++ wiphy_name(priv->hw->wiphy), cmd, ret); + else + ret = 1; + +@@ -926,44 +895,7 @@ + ret = at76_set_mib(priv, &priv->mib_buf); + if (ret < 0) + printk(KERN_ERR "%s: set_mib (pm_mode) failed: %d\n", +- priv->netdev->name, ret); +- +- return ret; +-} +- +-/* Set the association id for power save mode */ +-static int at76_set_associd(struct at76_priv *priv, u16 id) +-{ +- int ret = 0; +- +- priv->mib_buf.type = MIB_MAC_MGMT; +- priv->mib_buf.size = 2; +- priv->mib_buf.index = offsetof(struct mib_mac_mgmt, station_id); +- priv->mib_buf.data.word = cpu_to_le16(id); +- +- ret = at76_set_mib(priv, &priv->mib_buf); +- if (ret < 0) +- printk(KERN_ERR "%s: set_mib (associd) failed: %d\n", +- priv->netdev->name, ret); +- +- return ret; +-} +- +-/* Set the listen interval for power save mode */ +-static int at76_set_listen_interval(struct at76_priv *priv, u16 interval) +-{ +- int ret = 0; +- +- priv->mib_buf.type = MIB_MAC; +- priv->mib_buf.size = 2; +- priv->mib_buf.index = offsetof(struct mib_mac, listen_interval); +- priv->mib_buf.data.word = cpu_to_le16(interval); +- +- ret = at76_set_mib(priv, &priv->mib_buf); +- if (ret < 0) +- printk(KERN_ERR +- "%s: set_mib (listen_interval) failed: %d\n", +- priv->netdev->name, ret); ++ wiphy_name(priv->hw->wiphy), ret); + + return ret; + } +@@ -980,7 +912,7 @@ + ret = at76_set_mib(priv, &priv->mib_buf); + if (ret < 0) + printk(KERN_ERR "%s: set_mib (preamble) failed: %d\n", +- priv->netdev->name, ret); ++ wiphy_name(priv->hw->wiphy), ret); + + return ret; + } +@@ -997,7 +929,7 @@ + ret = at76_set_mib(priv, &priv->mib_buf); + if (ret < 0) + printk(KERN_ERR "%s: set_mib (frag threshold) failed: %d\n", +- priv->netdev->name, ret); ++ wiphy_name(priv->hw->wiphy), ret); + + return ret; + } +@@ -1014,7 +946,7 @@ + ret = at76_set_mib(priv, &priv->mib_buf); + if (ret < 0) + printk(KERN_ERR "%s: set_mib (rts) failed: %d\n", +- priv->netdev->name, ret); ++ wiphy_name(priv->hw->wiphy), ret); + + return ret; + } +@@ -1031,24 +963,41 @@ + ret = at76_set_mib(priv, &priv->mib_buf); + if (ret < 0) + printk(KERN_ERR "%s: set_mib (autorate fallback) failed: %d\n", +- priv->netdev->name, ret); ++ wiphy_name(priv->hw->wiphy), ret); + + return ret; + } + +-static int at76_add_mac_address(struct at76_priv *priv, void *addr) ++static int at76_set_tkip_bssid(struct at76_priv *priv, const void *addr) + { + int ret = 0; + +- priv->mib_buf.type = MIB_MAC_ADDR; ++ priv->mib_buf.type = MIB_MAC_ENCRYPTION; + priv->mib_buf.size = ETH_ALEN; +- priv->mib_buf.index = offsetof(struct mib_mac_addr, mac_addr); ++ priv->mib_buf.index = offsetof(struct mib_mac_encryption, tkip_bssid); + memcpy(priv->mib_buf.data.addr, addr, ETH_ALEN); + + ret = at76_set_mib(priv, &priv->mib_buf); + if (ret < 0) +- printk(KERN_ERR "%s: set_mib (MAC_ADDR, mac_addr) failed: %d\n", +- priv->netdev->name, ret); ++ printk(KERN_ERR "%s: set_mib (MAC_ENCRYPTION, tkip_bssid) failed: %d\n", ++ wiphy_name(priv->hw->wiphy), ret); ++ ++ return ret; ++} ++ ++static int at76_reset_rsc(struct at76_priv *priv) ++{ ++ int ret = 0; ++ ++ priv->mib_buf.type = MIB_MAC_ENCRYPTION; ++ priv->mib_buf.size = 4 * 8; ++ priv->mib_buf.index = offsetof(struct mib_mac_encryption, key_rsc); ++ memset(priv->mib_buf.data.data, 0 , priv->mib_buf.size); ++ ++ ret = at76_set_mib(priv, &priv->mib_buf); ++ if (ret < 0) ++ printk(KERN_ERR "%s: set_mib (MAC_ENCRYPTION, key_rsc) failed: %d\n", ++ wiphy_name(priv->hw->wiphy), ret); + + return ret; + } +@@ -1067,16 +1016,16 @@ + sizeof(struct mib_mac_addr)); + if (ret < 0) { + printk(KERN_ERR "%s: at76_get_mib (MAC_ADDR) failed: %d\n", +- priv->netdev->name, ret); ++ wiphy_name(priv->hw->wiphy), ret); + goto exit; + } + + at76_dbg(DBG_MIB, "%s: MIB MAC_ADDR: mac_addr %s res 0x%x 0x%x", +- priv->netdev->name, ++ wiphy_name(priv->hw->wiphy), + mac2str(m->mac_addr), m->res[0], m->res[1]); + for (i = 0; i < ARRAY_SIZE(m->group_addr); i++) + at76_dbg(DBG_MIB, "%s: MIB MAC_ADDR: group addr %d: %s, " +- "status %d", priv->netdev->name, i, ++ "status %d", wiphy_name(priv->hw->wiphy), i, + mac2str(m->group_addr[i]), m->group_addr_status[i]); + exit: + kfree(m); +@@ -1096,13 +1045,13 @@ + sizeof(struct mib_mac_wep)); + if (ret < 0) { + printk(KERN_ERR "%s: at76_get_mib (MAC_WEP) failed: %d\n", +- priv->netdev->name, ret); ++ wiphy_name(priv->hw->wiphy), ret); + goto exit; + } + + at76_dbg(DBG_MIB, "%s: MIB MAC_WEP: priv_invoked %u def_key_id %u " + "key_len %u excl_unencr %u wep_icv_err %u wep_excluded %u " +- "encr_level %u key %d", priv->netdev->name, ++ "encr_level %u key %d", wiphy_name(priv->hw->wiphy), + m->privacy_invoked, m->wep_default_key_id, + m->wep_key_mapping_len, m->exclude_unencrypted, + le32_to_cpu(m->wep_icv_error_count), +@@ -1114,12 +1063,55 @@ + + for (i = 0; i < WEP_KEYS; i++) + at76_dbg(DBG_MIB, "%s: MIB MAC_WEP: key %d: %s", +- priv->netdev->name, i, ++ wiphy_name(priv->hw->wiphy), i, + hex2str(m->wep_default_keyvalue[i], key_len)); + exit: + kfree(m); + } + ++static void at76_dump_mib_mac_encryption(struct at76_priv *priv) ++{ ++ int i; ++ int ret; ++ /*int key_len;*/ ++ struct mib_mac_encryption *m; ++ ++ m = kmalloc(sizeof(struct mib_mac_encryption), GFP_KERNEL); ++ if (!m) ++ return; ++ ++ ret = at76_get_mib(priv->udev, MIB_MAC_ENCRYPTION, m, ++ sizeof(struct mib_mac_encryption)); ++ if (ret < 0) { ++ dev_err(&priv->udev->dev, ++ "%s: at76_get_mib (MAC_ENCRYPTION) failed: %d\n", ++ wiphy_name(priv->hw->wiphy), ret); ++ goto exit; ++ } ++ ++ at76_dbg(DBG_MIB, ++ "%s: MIB MAC_ENCRYPTION: tkip_bssid %s priv_invoked %u " ++ "ciph_key_id %u grp_key_id %u excl_unencr %u " ++ "ckip_key_perm %u wep_icv_err %u wep_excluded %u", ++ wiphy_name(priv->hw->wiphy), mac2str(m->tkip_bssid), ++ m->privacy_invoked, m->cipher_default_key_id, ++ m->cipher_default_group_key_id, m->exclude_unencrypted, ++ m->ckip_key_permutation, ++ le32_to_cpu(m->wep_icv_error_count), ++ le32_to_cpu(m->wep_excluded_count)); ++ ++ /*key_len = (m->encryption_level == 1) ? ++ WEP_SMALL_KEY_LEN : WEP_LARGE_KEY_LEN;*/ ++ ++ for (i = 0; i < CIPHER_KEYS; i++) ++ at76_dbg(DBG_MIB, "%s: MIB MAC_ENCRYPTION: key %d: %s", ++ wiphy_name(priv->hw->wiphy), i, ++ hex2str(m->cipher_default_keyvalue[i], ++ CIPHER_KEY_LEN)); ++exit: ++ kfree(m); ++} ++ + static void at76_dump_mib_mac_mgmt(struct at76_priv *priv) + { + int ret; +@@ -1133,7 +1125,7 @@ + sizeof(struct mib_mac_mgmt)); + if (ret < 0) { + printk(KERN_ERR "%s: at76_get_mib (MAC_MGMT) failed: %d\n", +- priv->netdev->name, ret); ++ wiphy_name(priv->hw->wiphy), ret); + goto exit; + } + +@@ -1144,7 +1136,7 @@ + "pm_mode %d ibss_change %d res %d " + "multi_domain_capability_implemented %d " + "international_roaming %d country_string %.3s", +- priv->netdev->name, le16_to_cpu(m->beacon_period), ++ wiphy_name(priv->hw->wiphy), le16_to_cpu(m->beacon_period), + le16_to_cpu(m->CFP_max_duration), + le16_to_cpu(m->medium_occupancy_limit), + le16_to_cpu(m->station_id), le16_to_cpu(m->ATIM_window), +@@ -1169,7 +1161,7 @@ + ret = at76_get_mib(priv->udev, MIB_MAC, m, sizeof(struct mib_mac)); + if (ret < 0) { + printk(KERN_ERR "%s: at76_get_mib (MAC) failed: %d\n", +- priv->netdev->name, ret); ++ wiphy_name(priv->hw->wiphy), ret); + goto exit; + } + +@@ -1179,7 +1171,8 @@ + "scan_type %d scan_channel %d probe_delay %u " + "min_channel_time %d max_channel_time %d listen_int %d " + "desired_ssid %s desired_bssid %s desired_bsstype %d", +- priv->netdev->name, le32_to_cpu(m->max_tx_msdu_lifetime), ++ wiphy_name(priv->hw->wiphy), ++ le32_to_cpu(m->max_tx_msdu_lifetime), + le32_to_cpu(m->max_rx_lifetime), + le16_to_cpu(m->frag_threshold), le16_to_cpu(m->rts_threshold), + le16_to_cpu(m->cwmin), le16_to_cpu(m->cwmax), +@@ -1205,7 +1198,7 @@ + ret = at76_get_mib(priv->udev, MIB_PHY, m, sizeof(struct mib_phy)); + if (ret < 0) { + printk(KERN_ERR "%s: at76_get_mib (PHY) failed: %d\n", +- priv->netdev->name, ret); ++ wiphy_name(priv->hw->wiphy), ret); + goto exit; + } + +@@ -1214,7 +1207,7 @@ + "mpdu_max_length %d cca_mode_supported %d operation_rate_set " + "0x%x 0x%x 0x%x 0x%x channel_id %d current_cca_mode %d " + "phy_type %d current_reg_domain %d", +- priv->netdev->name, le32_to_cpu(m->ed_threshold), ++ wiphy_name(priv->hw->wiphy), le32_to_cpu(m->ed_threshold), + le16_to_cpu(m->slot_time), le16_to_cpu(m->sifs_time), + le16_to_cpu(m->preamble_length), + le16_to_cpu(m->plcp_header_length), +@@ -1238,13 +1231,14 @@ + ret = at76_get_mib(priv->udev, MIB_LOCAL, m, sizeof(struct mib_local)); + if (ret < 0) { + printk(KERN_ERR "%s: at76_get_mib (LOCAL) failed: %d\n", +- priv->netdev->name, ret); ++ wiphy_name(priv->hw->wiphy), ret); + goto exit; + } + + at76_dbg(DBG_MIB, "%s: MIB LOCAL: beacon_enable %d " + "txautorate_fallback %d ssid_size %d promiscuous_mode %d " +- "preamble_type %d", priv->netdev->name, m->beacon_enable, ++ "preamble_type %d", wiphy_name(priv->hw->wiphy), ++ m->beacon_enable, + m->txautorate_fallback, m->ssid_size, m->promiscuous_mode, + m->preamble_type); + exit: +@@ -1263,118 +1257,21 @@ + sizeof(struct mib_mdomain)); + if (ret < 0) { + printk(KERN_ERR "%s: at76_get_mib (MDOMAIN) failed: %d\n", +- priv->netdev->name, ret); ++ wiphy_name(priv->hw->wiphy), ret); + goto exit; + } + + at76_dbg(DBG_MIB, "%s: MIB MDOMAIN: channel_list %s", +- priv->netdev->name, ++ wiphy_name(priv->hw->wiphy), + hex2str(m->channel_list, sizeof(m->channel_list))); + + at76_dbg(DBG_MIB, "%s: MIB MDOMAIN: tx_powerlevel %s", +- priv->netdev->name, ++ wiphy_name(priv->hw->wiphy), + hex2str(m->tx_powerlevel, sizeof(m->tx_powerlevel))); + exit: + kfree(m); + } + +-static int at76_get_current_bssid(struct at76_priv *priv) +-{ +- int ret = 0; +- struct mib_mac_mgmt *mac_mgmt = +- kmalloc(sizeof(struct mib_mac_mgmt), GFP_KERNEL); +- +- if (!mac_mgmt) { +- ret = -ENOMEM; +- goto exit; +- } +- +- ret = at76_get_mib(priv->udev, MIB_MAC_MGMT, mac_mgmt, +- sizeof(struct mib_mac_mgmt)); +- if (ret < 0) { +- printk(KERN_ERR "%s: at76_get_mib failed: %d\n", +- priv->netdev->name, ret); +- goto error; +- } +- memcpy(priv->bssid, mac_mgmt->current_bssid, ETH_ALEN); +- printk(KERN_INFO "%s: using BSSID %s\n", priv->netdev->name, +- mac2str(priv->bssid)); +-error: +- kfree(mac_mgmt); +-exit: +- return ret; +-} +- +-static int at76_get_current_channel(struct at76_priv *priv) +-{ +- int ret = 0; +- struct mib_phy *phy = kmalloc(sizeof(struct mib_phy), GFP_KERNEL); +- +- if (!phy) { +- ret = -ENOMEM; +- goto exit; +- } +- ret = at76_get_mib(priv->udev, MIB_PHY, phy, sizeof(struct mib_phy)); +- if (ret < 0) { +- printk(KERN_ERR "%s: at76_get_mib(MIB_PHY) failed: %d\n", +- priv->netdev->name, ret); +- goto error; +- } +- priv->channel = phy->channel_id; +-error: +- kfree(phy); +-exit: +- return ret; +-} +- +-/** +- * at76_start_scan - start a scan +- * +- * @use_essid - use the configured ESSID in non passive mode +- */ +-static int at76_start_scan(struct at76_priv *priv, int use_essid) +-{ +- struct at76_req_scan scan; +- +- memset(&scan, 0, sizeof(struct at76_req_scan)); +- memset(scan.bssid, 0xff, ETH_ALEN); +- +- if (use_essid) { +- memcpy(scan.essid, priv->essid, IW_ESSID_MAX_SIZE); +- scan.essid_size = priv->essid_size; +- } else +- scan.essid_size = 0; +- +- /* jal: why should we start at a certain channel? we do scan the whole +- range allowed by reg domain. */ +- scan.channel = priv->channel; +- +- /* atmelwlandriver differs between scan type 0 and 1 (active/passive) +- For ad-hoc mode, it uses type 0 only. */ +- scan.scan_type = priv->scan_mode; +- +- /* INFO: For probe_delay, not multiplying by 1024 as this will be +- slightly less than min_channel_time +- (per spec: probe delay < min. channel time) */ +- scan.min_channel_time = cpu_to_le16(priv->scan_min_time); +- scan.max_channel_time = cpu_to_le16(priv->scan_max_time); +- scan.probe_delay = cpu_to_le16(priv->scan_min_time * 1000); +- scan.international_scan = 0; +- +- /* other values are set to 0 for type 0 */ +- +- at76_dbg(DBG_PROGRESS, "%s: start_scan (use_essid = %d, intl = %d, " +- "channel = %d, probe_delay = %d, scan_min_time = %d, " +- "scan_max_time = %d)", +- priv->netdev->name, use_essid, +- scan.international_scan, scan.channel, +- le16_to_cpu(scan.probe_delay), +- le16_to_cpu(scan.min_channel_time), +- le16_to_cpu(scan.max_channel_time)); +- +- return at76_set_card_command(priv->udev, CMD_SCAN, &scan, sizeof(scan)); +-} +- + /* Enable monitor mode */ + static int at76_start_monitor(struct at76_priv *priv) + { +@@ -1395,86 +1292,6 @@ + return ret; + } + +-static int at76_start_ibss(struct at76_priv *priv) +-{ +- struct at76_req_ibss bss; +- int ret; +- +- WARN_ON(priv->mac_state != MAC_OWN_IBSS); +- if (priv->mac_state != MAC_OWN_IBSS) +- return -EBUSY; +- +- memset(&bss, 0, sizeof(struct at76_req_ibss)); +- memset(bss.bssid, 0xff, ETH_ALEN); +- memcpy(bss.essid, priv->essid, IW_ESSID_MAX_SIZE); +- bss.essid_size = priv->essid_size; +- bss.bss_type = ADHOC_MODE; +- bss.channel = priv->channel; +- +- ret = at76_set_card_command(priv->udev, CMD_START_IBSS, &bss, +- sizeof(struct at76_req_ibss)); +- if (ret < 0) { +- printk(KERN_ERR "%s: start_ibss failed: %d\n", +- priv->netdev->name, ret); +- return ret; +- } +- +- ret = at76_wait_completion(priv, CMD_START_IBSS); +- if (ret != CMD_STATUS_COMPLETE) { +- printk(KERN_ERR "%s: start_ibss failed to complete, %d\n", +- priv->netdev->name, ret); +- return ret; +- } +- +- ret = at76_get_current_bssid(priv); +- if (ret < 0) +- return ret; +- +- ret = at76_get_current_channel(priv); +- if (ret < 0) +- return ret; +- +- /* not sure what this is good for ??? */ +- priv->mib_buf.type = MIB_MAC_MGMT; +- priv->mib_buf.size = 1; +- priv->mib_buf.index = offsetof(struct mib_mac_mgmt, ibss_change); +- priv->mib_buf.data.byte = 0; +- +- ret = at76_set_mib(priv, &priv->mib_buf); +- if (ret < 0) { +- printk(KERN_ERR "%s: set_mib (ibss change ok) failed: %d\n", +- priv->netdev->name, ret); +- return ret; +- } +- +- netif_carrier_on(priv->netdev); +- netif_start_queue(priv->netdev); +- return 0; +-} +- +-/* Request card to join BSS in managed or ad-hoc mode */ +-static int at76_join_bss(struct at76_priv *priv, struct bss_info *ptr) +-{ +- struct at76_req_join join; +- +- BUG_ON(!ptr); +- +- memset(&join, 0, sizeof(struct at76_req_join)); +- memcpy(join.bssid, ptr->bssid, ETH_ALEN); +- memcpy(join.essid, ptr->ssid, ptr->ssid_len); +- join.essid_size = ptr->ssid_len; +- join.bss_type = (priv->iw_mode == IW_MODE_ADHOC ? 1 : 2); +- join.channel = ptr->channel; +- join.timeout = cpu_to_le16(2000); +- +- at76_dbg(DBG_PROGRESS, +- "%s join addr %s ssid %s type %d ch %d timeout %d", +- priv->netdev->name, mac2str(join.bssid), join.essid, +- join.bss_type, join.channel, le16_to_cpu(join.timeout)); +- return at76_set_card_command(priv->udev, CMD_JOIN, &join, +- sizeof(struct at76_req_join)); +-} +- + /* Calculate padding from txbuf->wlength (which excludes the USB TX header), + likely to compensate a flaw in the AT76C503A USB part ... */ + static inline int at76_calc_padding(int wlen) +@@ -1493,14 +1310,6 @@ + return 0; + } + +-/* We are doing a lot of things here in an interrupt. Need +- a bh handler (Watching TV with a TV card is probably +- a good test: if you see flickers, we are doing too much. +- Currently I do see flickers... even with our tasklet :-( ) +- Maybe because the bttv driver and usb-uhci use the same interrupt +-*/ +-/* Or maybe because our BH handler is preempting bttv's BH handler.. BHs don't +- * solve everything.. (alex) */ + static void at76_rx_callback(struct urb *urb) + { + struct at76_priv *priv = urb->context; +@@ -1510,1914 +1319,70 @@ + return; + } + +-static void at76_tx_callback(struct urb *urb) ++static int at76_submit_rx_urb(struct at76_priv *priv) + { +- struct at76_priv *priv = urb->context; +- struct net_device_stats *stats = &priv->stats; +- unsigned long flags; +- struct at76_tx_buffer *mgmt_buf; + int ret; ++ int size; ++ struct sk_buff *skb = priv->rx_skb; + +- switch (urb->status) { +- case 0: +- stats->tx_packets++; +- break; +- case -ENOENT: +- case -ECONNRESET: +- /* urb has been unlinked */ +- return; +- default: +- at76_dbg(DBG_URB, "%s - nonzero tx status received: %d", +- __func__, urb->status); +- stats->tx_errors++; +- break; ++ if (!priv->rx_urb) { ++ printk(KERN_ERR "%s: %s: priv->rx_urb is NULL\n", ++ wiphy_name(priv->hw->wiphy), __func__); ++ return -EFAULT; + } + +- spin_lock_irqsave(&priv->mgmt_spinlock, flags); +- mgmt_buf = priv->next_mgmt_bulk; +- priv->next_mgmt_bulk = NULL; +- spin_unlock_irqrestore(&priv->mgmt_spinlock, flags); ++ if (!skb) { ++ skb = dev_alloc_skb(sizeof(struct at76_rx_buffer)); ++ if (!skb) { ++ printk(KERN_ERR "%s: cannot allocate rx skbuff\n", ++ wiphy_name(priv->hw->wiphy)); ++ ret = -ENOMEM; ++ goto exit; ++ } ++ priv->rx_skb = skb; ++ } else { ++ skb_push(skb, skb_headroom(skb)); ++ skb_trim(skb, 0); ++ } + +- if (!mgmt_buf) { +- netif_wake_queue(priv->netdev); +- return; ++ size = skb_tailroom(skb); ++ usb_fill_bulk_urb(priv->rx_urb, priv->udev, priv->rx_pipe, ++ skb_put(skb, size), size, at76_rx_callback, priv); ++ ret = usb_submit_urb(priv->rx_urb, GFP_ATOMIC); ++ if (ret < 0) { ++ if (ret == -ENODEV) ++ at76_dbg(DBG_DEVSTART, ++ "usb_submit_urb returned -ENODEV"); ++ else ++ printk(KERN_ERR "%s: rx, usb_submit_urb failed: %d\n", ++ wiphy_name(priv->hw->wiphy), ret); + } + +- /* we don't copy the padding bytes, but add them +- to the length */ +- memcpy(priv->bulk_out_buffer, mgmt_buf, +- le16_to_cpu(mgmt_buf->wlength) + AT76_TX_HDRLEN); +- usb_fill_bulk_urb(priv->tx_urb, priv->udev, priv->tx_pipe, +- priv->bulk_out_buffer, +- le16_to_cpu(mgmt_buf->wlength) + mgmt_buf->padding + +- AT76_TX_HDRLEN, at76_tx_callback, priv); +- ret = usb_submit_urb(priv->tx_urb, GFP_ATOMIC); +- if (ret) +- printk(KERN_ERR "%s: error in tx submit urb: %d\n", +- priv->netdev->name, ret); ++exit: ++ if (ret < 0 && ret != -ENODEV) ++ printk(KERN_ERR "%s: cannot submit rx urb - please unload the " ++ "driver and/or power cycle the device\n", ++ wiphy_name(priv->hw->wiphy)); + +- kfree(mgmt_buf); ++ return ret; + } + +-/* Send a management frame on bulk-out. txbuf->wlength must be set */ +-static int at76_tx_mgmt(struct at76_priv *priv, struct at76_tx_buffer *txbuf) ++/* Download external firmware */ ++static int at76_load_external_fw(struct usb_device *udev, struct fwentry *fwe) + { +- unsigned long flags; + int ret; +- int urb_status; +- void *oldbuf = NULL; +- +- netif_carrier_off(priv->netdev); /* stop netdev watchdog */ +- netif_stop_queue(priv->netdev); /* stop tx data packets */ ++ int op_mode; ++ int blockno = 0; ++ int bsize; ++ u8 *block; ++ u8 *buf = fwe->extfw; ++ int size = fwe->extfw_size; + +- spin_lock_irqsave(&priv->mgmt_spinlock, flags); ++ if (!buf || !size) ++ return -ENOENT; + +- urb_status = priv->tx_urb->status; +- if (urb_status == -EINPROGRESS) { +- /* cannot transmit now, put in the queue */ +- oldbuf = priv->next_mgmt_bulk; +- priv->next_mgmt_bulk = txbuf; +- } +- spin_unlock_irqrestore(&priv->mgmt_spinlock, flags); +- +- if (oldbuf) { +- /* a data/mgmt tx is already pending in the URB - +- if this is no error in some situations we must +- implement a queue or silently modify the old msg */ +- printk(KERN_ERR "%s: removed pending mgmt buffer %s\n", +- priv->netdev->name, hex2str(oldbuf, 64)); +- kfree(oldbuf); +- return 0; +- } +- +- txbuf->tx_rate = TX_RATE_1MBIT; +- txbuf->padding = at76_calc_padding(le16_to_cpu(txbuf->wlength)); +- memset(txbuf->reserved, 0, sizeof(txbuf->reserved)); +- +- if (priv->next_mgmt_bulk) +- printk(KERN_ERR "%s: URB status %d, but mgmt is pending\n", +- priv->netdev->name, urb_status); +- +- at76_dbg(DBG_TX_MGMT, +- "%s: tx mgmt: wlen %d tx_rate %d pad %d %s", +- priv->netdev->name, le16_to_cpu(txbuf->wlength), +- txbuf->tx_rate, txbuf->padding, +- hex2str(txbuf->packet, le16_to_cpu(txbuf->wlength))); +- +- /* txbuf was not consumed above -> send mgmt msg immediately */ +- memcpy(priv->bulk_out_buffer, txbuf, +- le16_to_cpu(txbuf->wlength) + AT76_TX_HDRLEN); +- usb_fill_bulk_urb(priv->tx_urb, priv->udev, priv->tx_pipe, +- priv->bulk_out_buffer, +- le16_to_cpu(txbuf->wlength) + txbuf->padding + +- AT76_TX_HDRLEN, at76_tx_callback, priv); +- ret = usb_submit_urb(priv->tx_urb, GFP_ATOMIC); +- if (ret) +- printk(KERN_ERR "%s: error in tx submit urb: %d\n", +- priv->netdev->name, ret); +- +- kfree(txbuf); +- +- return ret; +-} +- +-/* Go to the next information element */ +-static inline void next_ie(struct ieee80211_info_element **ie) +-{ +- *ie = (struct ieee80211_info_element *)(&(*ie)->data[(*ie)->len]); +-} +- +-/* Challenge is the challenge string (in TLV format) +- we got with seq_nr 2 for shared secret authentication only and +- send in seq_nr 3 WEP encrypted to prove we have the correct WEP key; +- otherwise it is NULL */ +-static int at76_auth_req(struct at76_priv *priv, struct bss_info *bss, +- int seq_nr, struct ieee80211_info_element *challenge) +-{ +- struct at76_tx_buffer *tx_buffer; +- struct ieee80211_hdr_3addr *mgmt; +- struct ieee80211_auth *req; +- int buf_len = (seq_nr != 3 ? AUTH_FRAME_SIZE : +- AUTH_FRAME_SIZE + 1 + 1 + challenge->len); +- +- BUG_ON(!bss); +- BUG_ON(seq_nr == 3 && !challenge); +- tx_buffer = kmalloc(buf_len + MAX_PADDING_SIZE, GFP_ATOMIC); +- if (!tx_buffer) +- return -ENOMEM; +- +- req = (struct ieee80211_auth *)tx_buffer->packet; +- mgmt = &req->header; +- +- /* make wireless header */ +- /* first auth msg is not encrypted, only the second (seq_nr == 3) */ +- mgmt->frame_ctl = +- cpu_to_le16(IEEE80211_FTYPE_MGMT | IEEE80211_STYPE_AUTH | +- (seq_nr == 3 ? IEEE80211_FCTL_PROTECTED : 0)); +- +- mgmt->duration_id = cpu_to_le16(0x8000); +- memcpy(mgmt->addr1, bss->bssid, ETH_ALEN); +- memcpy(mgmt->addr2, priv->netdev->dev_addr, ETH_ALEN); +- memcpy(mgmt->addr3, bss->bssid, ETH_ALEN); +- mgmt->seq_ctl = cpu_to_le16(0); +- +- req->algorithm = cpu_to_le16(priv->auth_mode); +- req->transaction = cpu_to_le16(seq_nr); +- req->status = cpu_to_le16(0); +- +- if (seq_nr == 3) +- memcpy(req->info_element, challenge, 1 + 1 + challenge->len); +- +- /* init. at76_priv tx header */ +- tx_buffer->wlength = cpu_to_le16(buf_len - AT76_TX_HDRLEN); +- at76_dbg(DBG_TX_MGMT, "%s: AuthReq bssid %s alg %d seq_nr %d", +- priv->netdev->name, mac2str(mgmt->addr3), +- le16_to_cpu(req->algorithm), le16_to_cpu(req->transaction)); +- if (seq_nr == 3) +- at76_dbg(DBG_TX_MGMT, "%s: AuthReq challenge: %s ...", +- priv->netdev->name, hex2str(req->info_element, 18)); +- +- /* either send immediately (if no data tx is pending +- or put it in pending list */ +- return at76_tx_mgmt(priv, tx_buffer); +-} +- +-static int at76_assoc_req(struct at76_priv *priv, struct bss_info *bss) +-{ +- struct at76_tx_buffer *tx_buffer; +- struct ieee80211_hdr_3addr *mgmt; +- struct ieee80211_assoc_request *req; +- struct ieee80211_info_element *ie; +- char *essid; +- int essid_len; +- u16 capa; +- +- BUG_ON(!bss); +- +- tx_buffer = kmalloc(ASSOCREQ_MAX_SIZE + MAX_PADDING_SIZE, GFP_ATOMIC); +- if (!tx_buffer) +- return -ENOMEM; +- +- req = (struct ieee80211_assoc_request *)tx_buffer->packet; +- mgmt = &req->header; +- ie = req->info_element; +- +- /* make wireless header */ +- mgmt->frame_ctl = cpu_to_le16(IEEE80211_FTYPE_MGMT | +- IEEE80211_STYPE_ASSOC_REQ); +- +- mgmt->duration_id = cpu_to_le16(0x8000); +- memcpy(mgmt->addr1, bss->bssid, ETH_ALEN); +- memcpy(mgmt->addr2, priv->netdev->dev_addr, ETH_ALEN); +- memcpy(mgmt->addr3, bss->bssid, ETH_ALEN); +- mgmt->seq_ctl = cpu_to_le16(0); +- +- /* we must set the Privacy bit in the capabilities to assure an +- Agere-based AP with optional WEP transmits encrypted frames +- to us. AP only set the Privacy bit in their capabilities +- if WEP is mandatory in the BSS! */ +- capa = bss->capa; +- if (priv->wep_enabled) +- capa |= WLAN_CAPABILITY_PRIVACY; +- if (priv->preamble_type != PREAMBLE_TYPE_LONG) +- capa |= WLAN_CAPABILITY_SHORT_PREAMBLE; +- req->capability = cpu_to_le16(capa); +- +- req->listen_interval = cpu_to_le16(2 * bss->beacon_interval); +- +- /* write TLV data elements */ +- +- ie->id = MFIE_TYPE_SSID; +- ie->len = bss->ssid_len; +- memcpy(ie->data, bss->ssid, bss->ssid_len); +- next_ie(&ie); +- +- ie->id = MFIE_TYPE_RATES; +- ie->len = sizeof(hw_rates); +- memcpy(ie->data, hw_rates, sizeof(hw_rates)); +- next_ie(&ie); /* ie points behind the supp_rates field */ +- +- /* init. at76_priv tx header */ +- tx_buffer->wlength = cpu_to_le16((u8 *)ie - (u8 *)mgmt); +- +- ie = req->info_element; +- essid = ie->data; +- essid_len = min_t(int, IW_ESSID_MAX_SIZE, ie->len); +- +- next_ie(&ie); /* points to IE of rates now */ +- at76_dbg(DBG_TX_MGMT, +- "%s: AssocReq bssid %s capa 0x%04x ssid %.*s rates %s", +- priv->netdev->name, mac2str(mgmt->addr3), +- le16_to_cpu(req->capability), essid_len, essid, +- hex2str(ie->data, ie->len)); +- +- /* either send immediately (if no data tx is pending +- or put it in pending list */ +- return at76_tx_mgmt(priv, tx_buffer); +-} +- +-/* We got to check the bss_list for old entries */ +-static void at76_bss_list_timeout(unsigned long par) +-{ +- struct at76_priv *priv = (struct at76_priv *)par; +- unsigned long flags; +- struct list_head *lptr, *nptr; +- struct bss_info *ptr; +- +- spin_lock_irqsave(&priv->bss_list_spinlock, flags); +- +- list_for_each_safe(lptr, nptr, &priv->bss_list) { +- +- ptr = list_entry(lptr, struct bss_info, list); +- +- if (ptr != priv->curr_bss +- && time_after(jiffies, ptr->last_rx + BSS_LIST_TIMEOUT)) { +- at76_dbg(DBG_BSS_TABLE_RM, +- "%s: bss_list: removing old BSS %s ch %d", +- priv->netdev->name, mac2str(ptr->bssid), +- ptr->channel); +- list_del(&ptr->list); +- kfree(ptr); +- } +- } +- spin_unlock_irqrestore(&priv->bss_list_spinlock, flags); +- /* restart the timer */ +- mod_timer(&priv->bss_list_timer, jiffies + BSS_LIST_TIMEOUT); +-} +- +-static inline void at76_set_mac_state(struct at76_priv *priv, +- enum mac_state mac_state) +-{ +- at76_dbg(DBG_MAC_STATE, "%s state: %s", priv->netdev->name, +- mac_states[mac_state]); +- priv->mac_state = mac_state; +-} +- +-static void at76_dump_bss_table(struct at76_priv *priv) +-{ +- struct bss_info *ptr; +- unsigned long flags; +- struct list_head *lptr; +- +- spin_lock_irqsave(&priv->bss_list_spinlock, flags); +- +- at76_dbg(DBG_BSS_TABLE, "%s BSS table (curr=%p):", priv->netdev->name, +- priv->curr_bss); +- +- list_for_each(lptr, &priv->bss_list) { +- ptr = list_entry(lptr, struct bss_info, list); +- at76_dbg(DBG_BSS_TABLE, "0x%p: bssid %s channel %d ssid %.*s " +- "(%s) capa 0x%04x rates %s rssi %d link %d noise %d", +- ptr, mac2str(ptr->bssid), ptr->channel, ptr->ssid_len, +- ptr->ssid, hex2str(ptr->ssid, ptr->ssid_len), +- ptr->capa, hex2str(ptr->rates, ptr->rates_len), +- ptr->rssi, ptr->link_qual, ptr->noise_level); +- } +- spin_unlock_irqrestore(&priv->bss_list_spinlock, flags); +-} +- +-/* Called upon successful association to mark interface as connected */ +-static void at76_work_assoc_done(struct work_struct *work) +-{ +- struct at76_priv *priv = container_of(work, struct at76_priv, +- work_assoc_done); +- +- mutex_lock(&priv->mtx); +- +- WARN_ON(priv->mac_state != MAC_ASSOC); +- WARN_ON(!priv->curr_bss); +- if (priv->mac_state != MAC_ASSOC || !priv->curr_bss) +- goto exit; +- +- if (priv->iw_mode == IW_MODE_INFRA) { +- if (priv->pm_mode != AT76_PM_OFF) { +- /* calculate the listen interval in units of +- beacon intervals of the curr_bss */ +- u32 pm_period_beacon = (priv->pm_period >> 10) / +- priv->curr_bss->beacon_interval; +- +- pm_period_beacon = max(pm_period_beacon, 2u); +- pm_period_beacon = min(pm_period_beacon, 0xffffu); +- +- at76_dbg(DBG_PM, +- "%s: pm_mode %d assoc id 0x%x listen int %d", +- priv->netdev->name, priv->pm_mode, +- priv->assoc_id, pm_period_beacon); +- +- at76_set_associd(priv, priv->assoc_id); +- at76_set_listen_interval(priv, (u16)pm_period_beacon); +- } +- schedule_delayed_work(&priv->dwork_beacon, BEACON_TIMEOUT); +- } +- at76_set_pm_mode(priv); +- +- netif_carrier_on(priv->netdev); +- netif_wake_queue(priv->netdev); +- at76_set_mac_state(priv, MAC_CONNECTED); +- at76_iwevent_bss_connect(priv->netdev, priv->curr_bss->bssid); +- at76_dbg(DBG_PROGRESS, "%s: connected to BSSID %s", +- priv->netdev->name, mac2str(priv->curr_bss->bssid)); +- +-exit: +- mutex_unlock(&priv->mtx); +-} +- +-/* We only store the new mac address in netdev struct, +- it gets set when the netdev is opened. */ +-static int at76_set_mac_address(struct net_device *netdev, void *addr) +-{ +- struct sockaddr *mac = addr; +- memcpy(netdev->dev_addr, mac->sa_data, ETH_ALEN); +- return 1; +-} +- +-static struct net_device_stats *at76_get_stats(struct net_device *netdev) +-{ +- struct at76_priv *priv = netdev_priv(netdev); +- return &priv->stats; +-} +- +-static struct iw_statistics *at76_get_wireless_stats(struct net_device *netdev) +-{ +- struct at76_priv *priv = netdev_priv(netdev); +- +- at76_dbg(DBG_IOCTL, "RETURN qual %d level %d noise %d updated %d", +- priv->wstats.qual.qual, priv->wstats.qual.level, +- priv->wstats.qual.noise, priv->wstats.qual.updated); +- +- return &priv->wstats; +-} +- +-static void at76_set_multicast(struct net_device *netdev) +-{ +- struct at76_priv *priv = netdev_priv(netdev); +- int promisc; +- +- promisc = ((netdev->flags & IFF_PROMISC) != 0); +- if (promisc != priv->promisc) { +- /* This gets called in interrupt, must reschedule */ +- priv->promisc = promisc; +- schedule_work(&priv->work_set_promisc); +- } +-} +- +-/* Stop all network activity, flush all pending tasks */ +-static void at76_quiesce(struct at76_priv *priv) +-{ +- unsigned long flags; +- +- netif_stop_queue(priv->netdev); +- netif_carrier_off(priv->netdev); +- +- at76_set_mac_state(priv, MAC_INIT); +- +- cancel_delayed_work(&priv->dwork_get_scan); +- cancel_delayed_work(&priv->dwork_beacon); +- cancel_delayed_work(&priv->dwork_auth); +- cancel_delayed_work(&priv->dwork_assoc); +- cancel_delayed_work(&priv->dwork_restart); +- +- spin_lock_irqsave(&priv->mgmt_spinlock, flags); +- kfree(priv->next_mgmt_bulk); +- priv->next_mgmt_bulk = NULL; +- spin_unlock_irqrestore(&priv->mgmt_spinlock, flags); +-} +- +-/******************************************************************************* +- * at76_priv implementations of iw_handler functions: +- */ +-static int at76_iw_handler_commit(struct net_device *netdev, +- struct iw_request_info *info, +- void *null, char *extra) +-{ +- struct at76_priv *priv = netdev_priv(netdev); +- +- at76_dbg(DBG_IOCTL, "%s %s: restarting the device", netdev->name, +- __func__); +- +- if (priv->mac_state != MAC_INIT) +- at76_quiesce(priv); +- +- /* Wait half second before the restart to process subsequent +- * requests from the same iwconfig in a single restart */ +- schedule_delayed_work(&priv->dwork_restart, HZ / 2); +- +- return 0; +-} +- +-static int at76_iw_handler_get_name(struct net_device *netdev, +- struct iw_request_info *info, +- char *name, char *extra) +-{ +- strcpy(name, "IEEE 802.11b"); +- at76_dbg(DBG_IOCTL, "%s: SIOCGIWNAME - name %s", netdev->name, name); +- return 0; +-} +- +-static int at76_iw_handler_set_freq(struct net_device *netdev, +- struct iw_request_info *info, +- struct iw_freq *freq, char *extra) +-{ +- struct at76_priv *priv = netdev_priv(netdev); +- int chan = -1; +- int ret = -EIWCOMMIT; +- at76_dbg(DBG_IOCTL, "%s: SIOCSIWFREQ - freq.m %d freq.e %d", +- netdev->name, freq->m, freq->e); +- +- if ((freq->e == 0) && (freq->m <= 1000)) +- /* Setting by channel number */ +- chan = freq->m; +- else { +- /* Setting by frequency - search the table */ +- int mult = 1; +- int i; +- +- for (i = 0; i < (6 - freq->e); i++) +- mult *= 10; +- +- for (i = 0; i < NUM_CHANNELS; i++) { +- if (freq->m == (channel_frequency[i] * mult)) +- chan = i + 1; +- } +- } +- +- if (chan < 1 || !priv->domain) +- /* non-positive channels are invalid +- * we need a domain info to set the channel +- * either that or an invalid frequency was +- * provided by the user */ +- ret = -EINVAL; +- else if (!(priv->domain->channel_map & (1 << (chan - 1)))) { +- printk(KERN_INFO "%s: channel %d not allowed for domain %s\n", +- priv->netdev->name, chan, priv->domain->name); +- ret = -EINVAL; +- } +- +- if (ret == -EIWCOMMIT) { +- priv->channel = chan; +- at76_dbg(DBG_IOCTL, "%s: SIOCSIWFREQ - ch %d", netdev->name, +- chan); +- } +- +- return ret; +-} +- +-static int at76_iw_handler_get_freq(struct net_device *netdev, +- struct iw_request_info *info, +- struct iw_freq *freq, char *extra) +-{ +- struct at76_priv *priv = netdev_priv(netdev); +- +- freq->m = priv->channel; +- freq->e = 0; +- +- if (priv->channel) +- at76_dbg(DBG_IOCTL, "%s: SIOCGIWFREQ - freq %ld x 10e%d", +- netdev->name, channel_frequency[priv->channel - 1], 6); +- +- at76_dbg(DBG_IOCTL, "%s: SIOCGIWFREQ - ch %d", netdev->name, +- priv->channel); +- +- return 0; +-} +- +-static int at76_iw_handler_set_mode(struct net_device *netdev, +- struct iw_request_info *info, +- __u32 *mode, char *extra) +-{ +- struct at76_priv *priv = netdev_priv(netdev); +- +- at76_dbg(DBG_IOCTL, "%s: SIOCSIWMODE - %d", netdev->name, *mode); +- +- if ((*mode != IW_MODE_ADHOC) && (*mode != IW_MODE_INFRA) && +- (*mode != IW_MODE_MONITOR)) +- return -EINVAL; +- +- priv->iw_mode = *mode; +- if (priv->iw_mode != IW_MODE_INFRA) +- priv->pm_mode = AT76_PM_OFF; +- +- return -EIWCOMMIT; +-} +- +-static int at76_iw_handler_get_mode(struct net_device *netdev, +- struct iw_request_info *info, +- __u32 *mode, char *extra) +-{ +- struct at76_priv *priv = netdev_priv(netdev); +- +- *mode = priv->iw_mode; +- +- at76_dbg(DBG_IOCTL, "%s: SIOCGIWMODE - %d", netdev->name, *mode); +- +- return 0; +-} +- +-static int at76_iw_handler_get_range(struct net_device *netdev, +- struct iw_request_info *info, +- struct iw_point *data, char *extra) +-{ +- /* inspired by atmel.c */ +- struct at76_priv *priv = netdev_priv(netdev); +- struct iw_range *range = (struct iw_range *)extra; +- int i; +- +- data->length = sizeof(struct iw_range); +- memset(range, 0, sizeof(struct iw_range)); +- +- /* TODO: range->throughput = xxxxxx; */ +- +- range->min_nwid = 0x0000; +- range->max_nwid = 0x0000; +- +- /* this driver doesn't maintain sensitivity information */ +- range->sensitivity = 0; +- +- range->max_qual.qual = 100; +- range->max_qual.level = 100; +- range->max_qual.noise = 0; +- range->max_qual.updated = IW_QUAL_NOISE_INVALID; +- +- range->avg_qual.qual = 50; +- range->avg_qual.level = 50; +- range->avg_qual.noise = 0; +- range->avg_qual.updated = IW_QUAL_NOISE_INVALID; +- +- range->bitrate[0] = 1000000; +- range->bitrate[1] = 2000000; +- range->bitrate[2] = 5500000; +- range->bitrate[3] = 11000000; +- range->num_bitrates = 4; +- +- range->min_rts = 0; +- range->max_rts = MAX_RTS_THRESHOLD; +- +- range->min_frag = MIN_FRAG_THRESHOLD; +- range->max_frag = MAX_FRAG_THRESHOLD; +- +- range->pmp_flags = IW_POWER_PERIOD; +- range->pmt_flags = IW_POWER_ON; +- range->pm_capa = IW_POWER_PERIOD | IW_POWER_ALL_R; +- +- range->encoding_size[0] = WEP_SMALL_KEY_LEN; +- range->encoding_size[1] = WEP_LARGE_KEY_LEN; +- range->num_encoding_sizes = 2; +- range->max_encoding_tokens = WEP_KEYS; +- +- /* both WL-240U and Linksys WUSB11 v2.6 specify 15 dBm as output power +- - take this for all (ignore antenna gains) */ +- range->txpower[0] = 15; +- range->num_txpower = 1; +- range->txpower_capa = IW_TXPOW_DBM; +- +- range->we_version_source = WIRELESS_EXT; +- range->we_version_compiled = WIRELESS_EXT; +- +- /* same as the values used in atmel.c */ +- range->retry_capa = IW_RETRY_LIMIT; +- range->retry_flags = IW_RETRY_LIMIT; +- range->r_time_flags = 0; +- range->min_retry = 1; +- range->max_retry = 255; +- +- range->num_channels = NUM_CHANNELS; +- range->num_frequency = 0; +- +- for (i = 0; i < NUM_CHANNELS; i++) { +- /* test if channel map bit is raised */ +- if (priv->domain->channel_map & (0x1 << i)) { +- range->num_frequency += 1; +- +- range->freq[i].i = i + 1; +- range->freq[i].m = channel_frequency[i] * 100000; +- range->freq[i].e = 1; /* freq * 10^1 */ +- } +- } +- +- at76_dbg(DBG_IOCTL, "%s: SIOCGIWRANGE", netdev->name); +- +- return 0; +-} +- +-static int at76_iw_handler_set_spy(struct net_device *netdev, +- struct iw_request_info *info, +- struct iw_point *data, char *extra) +-{ +- struct at76_priv *priv = netdev_priv(netdev); +- int ret = 0; +- +- at76_dbg(DBG_IOCTL, "%s: SIOCSIWSPY - number of addresses %d", +- netdev->name, data->length); +- +- spin_lock_bh(&priv->spy_spinlock); +- ret = iw_handler_set_spy(priv->netdev, info, (union iwreq_data *)data, +- extra); +- spin_unlock_bh(&priv->spy_spinlock); +- +- return ret; +-} +- +-static int at76_iw_handler_get_spy(struct net_device *netdev, +- struct iw_request_info *info, +- struct iw_point *data, char *extra) +-{ +- +- struct at76_priv *priv = netdev_priv(netdev); +- int ret = 0; +- +- spin_lock_bh(&priv->spy_spinlock); +- ret = iw_handler_get_spy(priv->netdev, info, +- (union iwreq_data *)data, extra); +- spin_unlock_bh(&priv->spy_spinlock); +- +- at76_dbg(DBG_IOCTL, "%s: SIOCGIWSPY - number of addresses %d", +- netdev->name, data->length); +- +- return ret; +-} +- +-static int at76_iw_handler_set_thrspy(struct net_device *netdev, +- struct iw_request_info *info, +- struct iw_point *data, char *extra) +-{ +- struct at76_priv *priv = netdev_priv(netdev); +- int ret; +- +- at76_dbg(DBG_IOCTL, "%s: SIOCSIWTHRSPY - number of addresses %d)", +- netdev->name, data->length); +- +- spin_lock_bh(&priv->spy_spinlock); +- ret = iw_handler_set_thrspy(netdev, info, (union iwreq_data *)data, +- extra); +- spin_unlock_bh(&priv->spy_spinlock); +- +- return ret; +-} +- +-static int at76_iw_handler_get_thrspy(struct net_device *netdev, +- struct iw_request_info *info, +- struct iw_point *data, char *extra) +-{ +- struct at76_priv *priv = netdev_priv(netdev); +- int ret; +- +- spin_lock_bh(&priv->spy_spinlock); +- ret = iw_handler_get_thrspy(netdev, info, (union iwreq_data *)data, +- extra); +- spin_unlock_bh(&priv->spy_spinlock); +- +- at76_dbg(DBG_IOCTL, "%s: SIOCGIWTHRSPY - number of addresses %d)", +- netdev->name, data->length); +- +- return ret; +-} +- +-static int at76_iw_handler_set_wap(struct net_device *netdev, +- struct iw_request_info *info, +- struct sockaddr *ap_addr, char *extra) +-{ +- struct at76_priv *priv = netdev_priv(netdev); +- +- at76_dbg(DBG_IOCTL, "%s: SIOCSIWAP - wap/bssid %s", netdev->name, +- mac2str(ap_addr->sa_data)); +- +- /* if the incoming address == ff:ff:ff:ff:ff:ff, the user has +- chosen any or auto AP preference */ +- if (is_broadcast_ether_addr(ap_addr->sa_data) +- || is_zero_ether_addr(ap_addr->sa_data)) +- priv->wanted_bssid_valid = 0; +- else { +- /* user wants to set a preferred AP address */ +- priv->wanted_bssid_valid = 1; +- memcpy(priv->wanted_bssid, ap_addr->sa_data, ETH_ALEN); +- } +- +- return -EIWCOMMIT; +-} +- +-static int at76_iw_handler_get_wap(struct net_device *netdev, +- struct iw_request_info *info, +- struct sockaddr *ap_addr, char *extra) +-{ +- struct at76_priv *priv = netdev_priv(netdev); +- +- ap_addr->sa_family = ARPHRD_ETHER; +- memcpy(ap_addr->sa_data, priv->bssid, ETH_ALEN); +- +- at76_dbg(DBG_IOCTL, "%s: SIOCGIWAP - wap/bssid %s", netdev->name, +- mac2str(ap_addr->sa_data)); +- +- return 0; +-} +- +-static int at76_iw_handler_set_scan(struct net_device *netdev, +- struct iw_request_info *info, +- union iwreq_data *wrqu, char *extra) +-{ +- struct at76_priv *priv = netdev_priv(netdev); +- int ret = 0; +- +- at76_dbg(DBG_IOCTL, "%s: SIOCSIWSCAN", netdev->name); +- +- if (mutex_lock_interruptible(&priv->mtx)) +- return -EINTR; +- +- if (!netif_running(netdev)) { +- ret = -ENETDOWN; +- goto exit; +- } +- +- /* jal: we don't allow "iwlist ethX scan" while we are +- in monitor mode */ +- if (priv->iw_mode == IW_MODE_MONITOR) { +- ret = -EBUSY; +- goto exit; +- } +- +- /* Discard old scan results */ +- if ((jiffies - priv->last_scan) > (20 * HZ)) +- priv->scan_state = SCAN_IDLE; +- priv->last_scan = jiffies; +- +- /* Initiate a scan command */ +- if (priv->scan_state == SCAN_IN_PROGRESS) { +- ret = -EBUSY; +- goto exit; +- } +- +- priv->scan_state = SCAN_IN_PROGRESS; +- +- at76_quiesce(priv); +- +- /* Try to do passive or active scan if WE asks as. */ +- if (wrqu->data.length +- && wrqu->data.length == sizeof(struct iw_scan_req)) { +- struct iw_scan_req *req = (struct iw_scan_req *)extra; +- +- if (req->scan_type == IW_SCAN_TYPE_PASSIVE) +- priv->scan_mode = SCAN_TYPE_PASSIVE; +- else if (req->scan_type == IW_SCAN_TYPE_ACTIVE) +- priv->scan_mode = SCAN_TYPE_ACTIVE; +- +- /* Sanity check values? */ +- if (req->min_channel_time > 0) +- priv->scan_min_time = req->min_channel_time; +- +- if (req->max_channel_time > 0) +- priv->scan_max_time = req->max_channel_time; +- } +- +- /* change to scanning state */ +- at76_set_mac_state(priv, MAC_SCANNING); +- schedule_work(&priv->work_start_scan); +- +-exit: +- mutex_unlock(&priv->mtx); +- return ret; +-} +- +-static int at76_iw_handler_get_scan(struct net_device *netdev, +- struct iw_request_info *info, +- struct iw_point *data, char *extra) +-{ +- struct at76_priv *priv = netdev_priv(netdev); +- unsigned long flags; +- struct list_head *lptr, *nptr; +- struct bss_info *curr_bss; +- struct iw_event *iwe = kmalloc(sizeof(struct iw_event), GFP_KERNEL); +- char *curr_val, *curr_pos = extra; +- int i; +- +- at76_dbg(DBG_IOCTL, "%s: SIOCGIWSCAN", netdev->name); +- +- if (!iwe) +- return -ENOMEM; +- +- if (priv->scan_state != SCAN_COMPLETED) { +- /* scan not yet finished */ +- kfree(iwe); +- return -EAGAIN; +- } +- +- spin_lock_irqsave(&priv->bss_list_spinlock, flags); +- +- list_for_each_safe(lptr, nptr, &priv->bss_list) { +- curr_bss = list_entry(lptr, struct bss_info, list); +- +- iwe->cmd = SIOCGIWAP; +- iwe->u.ap_addr.sa_family = ARPHRD_ETHER; +- memcpy(iwe->u.ap_addr.sa_data, curr_bss->bssid, 6); +- curr_pos = iwe_stream_add_event(info, curr_pos, +- extra + IW_SCAN_MAX_DATA, iwe, +- IW_EV_ADDR_LEN); +- +- iwe->u.data.length = curr_bss->ssid_len; +- iwe->cmd = SIOCGIWESSID; +- iwe->u.data.flags = 1; +- +- curr_pos = iwe_stream_add_point(info, curr_pos, +- extra + IW_SCAN_MAX_DATA, iwe, +- curr_bss->ssid); +- +- iwe->cmd = SIOCGIWMODE; +- iwe->u.mode = (curr_bss->capa & WLAN_CAPABILITY_IBSS) ? +- IW_MODE_ADHOC : +- (curr_bss->capa & WLAN_CAPABILITY_ESS) ? +- IW_MODE_MASTER : IW_MODE_AUTO; +- /* IW_MODE_AUTO = 0 which I thought is +- * the most logical value to return in this case */ +- curr_pos = iwe_stream_add_event(info, curr_pos, +- extra + IW_SCAN_MAX_DATA, iwe, +- IW_EV_UINT_LEN); +- +- iwe->cmd = SIOCGIWFREQ; +- iwe->u.freq.m = curr_bss->channel; +- iwe->u.freq.e = 0; +- curr_pos = iwe_stream_add_event(info, curr_pos, +- extra + IW_SCAN_MAX_DATA, iwe, +- IW_EV_FREQ_LEN); +- +- iwe->cmd = SIOCGIWENCODE; +- if (curr_bss->capa & WLAN_CAPABILITY_PRIVACY) +- iwe->u.data.flags = IW_ENCODE_ENABLED | IW_ENCODE_NOKEY; +- else +- iwe->u.data.flags = IW_ENCODE_DISABLED; +- +- iwe->u.data.length = 0; +- curr_pos = iwe_stream_add_point(info, curr_pos, +- extra + IW_SCAN_MAX_DATA, iwe, +- NULL); +- +- /* Add quality statistics */ +- iwe->cmd = IWEVQUAL; +- iwe->u.qual.noise = 0; +- iwe->u.qual.updated = +- IW_QUAL_NOISE_INVALID | IW_QUAL_LEVEL_UPDATED; +- iwe->u.qual.level = (curr_bss->rssi * 100 / 42); +- if (iwe->u.qual.level > 100) +- iwe->u.qual.level = 100; +- if (at76_is_intersil(priv->board_type)) +- iwe->u.qual.qual = curr_bss->link_qual; +- else { +- iwe->u.qual.qual = 0; +- iwe->u.qual.updated |= IW_QUAL_QUAL_INVALID; +- } +- /* Add new value to event */ +- curr_pos = iwe_stream_add_event(info, curr_pos, +- extra + IW_SCAN_MAX_DATA, iwe, +- IW_EV_QUAL_LEN); +- +- /* Rate: stuffing multiple values in a single event requires +- * a bit more of magic - Jean II */ +- curr_val = curr_pos + IW_EV_LCP_LEN; +- +- iwe->cmd = SIOCGIWRATE; +- /* Those two flags are ignored... */ +- iwe->u.bitrate.fixed = 0; +- iwe->u.bitrate.disabled = 0; +- /* Max 8 values */ +- for (i = 0; i < curr_bss->rates_len; i++) { +- /* Bit rate given in 500 kb/s units (+ 0x80) */ +- iwe->u.bitrate.value = +- ((curr_bss->rates[i] & 0x7f) * 500000); +- /* Add new value to event */ +- curr_val = iwe_stream_add_value(info, curr_pos, +- curr_val, +- extra + +- IW_SCAN_MAX_DATA, iwe, +- IW_EV_PARAM_LEN); +- } +- +- /* Check if we added any event */ +- if ((curr_val - curr_pos) > IW_EV_LCP_LEN) +- curr_pos = curr_val; +- +- /* more information may be sent back using IWECUSTOM */ +- +- } +- +- spin_unlock_irqrestore(&priv->bss_list_spinlock, flags); +- +- data->length = (curr_pos - extra); +- data->flags = 0; +- +- kfree(iwe); +- return 0; +-} +- +-static int at76_iw_handler_set_essid(struct net_device *netdev, +- struct iw_request_info *info, +- struct iw_point *data, char *extra) +-{ +- struct at76_priv *priv = netdev_priv(netdev); +- +- at76_dbg(DBG_IOCTL, "%s: SIOCSIWESSID - %s", netdev->name, extra); +- +- if (data->flags) { +- memcpy(priv->essid, extra, data->length); +- priv->essid_size = data->length; +- } else +- priv->essid_size = 0; /* Use any SSID */ +- +- return -EIWCOMMIT; +-} +- +-static int at76_iw_handler_get_essid(struct net_device *netdev, +- struct iw_request_info *info, +- struct iw_point *data, char *extra) +-{ +- struct at76_priv *priv = netdev_priv(netdev); +- +- if (priv->essid_size) { +- /* not the ANY ssid in priv->essid */ +- data->flags = 1; +- data->length = priv->essid_size; +- memcpy(extra, priv->essid, data->length); +- } else { +- /* the ANY ssid was specified */ +- if (priv->mac_state == MAC_CONNECTED && priv->curr_bss) { +- /* report the SSID we have found */ +- data->flags = 1; +- data->length = priv->curr_bss->ssid_len; +- memcpy(extra, priv->curr_bss->ssid, data->length); +- } else { +- /* report ANY back */ +- data->flags = 0; +- data->length = 0; +- } +- } +- +- at76_dbg(DBG_IOCTL, "%s: SIOCGIWESSID - %.*s", netdev->name, +- data->length, extra); +- +- return 0; +-} +- +-static int at76_iw_handler_set_rate(struct net_device *netdev, +- struct iw_request_info *info, +- struct iw_param *bitrate, char *extra) +-{ +- struct at76_priv *priv = netdev_priv(netdev); +- int ret = -EIWCOMMIT; +- +- at76_dbg(DBG_IOCTL, "%s: SIOCSIWRATE - %d", netdev->name, +- bitrate->value); +- +- switch (bitrate->value) { +- case -1: +- priv->txrate = TX_RATE_AUTO; +- break; /* auto rate */ +- case 1000000: +- priv->txrate = TX_RATE_1MBIT; +- break; +- case 2000000: +- priv->txrate = TX_RATE_2MBIT; +- break; +- case 5500000: +- priv->txrate = TX_RATE_5_5MBIT; +- break; +- case 11000000: +- priv->txrate = TX_RATE_11MBIT; +- break; +- default: +- ret = -EINVAL; +- } +- +- return ret; +-} +- +-static int at76_iw_handler_get_rate(struct net_device *netdev, +- struct iw_request_info *info, +- struct iw_param *bitrate, char *extra) +-{ +- struct at76_priv *priv = netdev_priv(netdev); +- int ret = 0; +- +- switch (priv->txrate) { +- /* return max rate if RATE_AUTO */ +- case TX_RATE_AUTO: +- bitrate->value = 11000000; +- break; +- case TX_RATE_1MBIT: +- bitrate->value = 1000000; +- break; +- case TX_RATE_2MBIT: +- bitrate->value = 2000000; +- break; +- case TX_RATE_5_5MBIT: +- bitrate->value = 5500000; +- break; +- case TX_RATE_11MBIT: +- bitrate->value = 11000000; +- break; +- default: +- ret = -EINVAL; +- } +- +- bitrate->fixed = (priv->txrate != TX_RATE_AUTO); +- bitrate->disabled = 0; +- +- at76_dbg(DBG_IOCTL, "%s: SIOCGIWRATE - %d", netdev->name, +- bitrate->value); +- +- return ret; +-} +- +-static int at76_iw_handler_set_rts(struct net_device *netdev, +- struct iw_request_info *info, +- struct iw_param *rts, char *extra) +-{ +- struct at76_priv *priv = netdev_priv(netdev); +- int ret = -EIWCOMMIT; +- int rthr = rts->value; +- +- at76_dbg(DBG_IOCTL, "%s: SIOCSIWRTS - value %d disabled %s", +- netdev->name, rts->value, (rts->disabled) ? "true" : "false"); +- +- if (rts->disabled) +- rthr = MAX_RTS_THRESHOLD; +- +- if ((rthr < 0) || (rthr > MAX_RTS_THRESHOLD)) +- ret = -EINVAL; +- else +- priv->rts_threshold = rthr; +- +- return ret; +-} +- +-static int at76_iw_handler_get_rts(struct net_device *netdev, +- struct iw_request_info *info, +- struct iw_param *rts, char *extra) +-{ +- struct at76_priv *priv = netdev_priv(netdev); +- +- rts->value = priv->rts_threshold; +- rts->disabled = (rts->value >= MAX_RTS_THRESHOLD); +- rts->fixed = 1; +- +- at76_dbg(DBG_IOCTL, "%s: SIOCGIWRTS - value %d disabled %s", +- netdev->name, rts->value, (rts->disabled) ? "true" : "false"); +- +- return 0; +-} +- +-static int at76_iw_handler_set_frag(struct net_device *netdev, +- struct iw_request_info *info, +- struct iw_param *frag, char *extra) +-{ +- struct at76_priv *priv = netdev_priv(netdev); +- int ret = -EIWCOMMIT; +- int fthr = frag->value; +- +- at76_dbg(DBG_IOCTL, "%s: SIOCSIWFRAG - value %d, disabled %s", +- netdev->name, frag->value, +- (frag->disabled) ? "true" : "false"); +- +- if (frag->disabled) +- fthr = MAX_FRAG_THRESHOLD; +- +- if ((fthr < MIN_FRAG_THRESHOLD) || (fthr > MAX_FRAG_THRESHOLD)) +- ret = -EINVAL; +- else +- priv->frag_threshold = fthr & ~0x1; /* get an even value */ +- +- return ret; +-} +- +-static int at76_iw_handler_get_frag(struct net_device *netdev, +- struct iw_request_info *info, +- struct iw_param *frag, char *extra) +-{ +- struct at76_priv *priv = netdev_priv(netdev); +- +- frag->value = priv->frag_threshold; +- frag->disabled = (frag->value >= MAX_FRAG_THRESHOLD); +- frag->fixed = 1; +- +- at76_dbg(DBG_IOCTL, "%s: SIOCGIWFRAG - value %d, disabled %s", +- netdev->name, frag->value, +- (frag->disabled) ? "true" : "false"); +- +- return 0; +-} +- +-static int at76_iw_handler_get_txpow(struct net_device *netdev, +- struct iw_request_info *info, +- struct iw_param *power, char *extra) +-{ +- power->value = 15; +- power->fixed = 1; /* No power control */ +- power->disabled = 0; +- power->flags = IW_TXPOW_DBM; +- +- at76_dbg(DBG_IOCTL, "%s: SIOCGIWTXPOW - txpow %d dBm", netdev->name, +- power->value); +- +- return 0; +-} +- +-/* jal: short retry is handled by the firmware (at least 0.90.x), +- while long retry is not (?) */ +-static int at76_iw_handler_set_retry(struct net_device *netdev, +- struct iw_request_info *info, +- struct iw_param *retry, char *extra) +-{ +- struct at76_priv *priv = netdev_priv(netdev); +- int ret = -EIWCOMMIT; +- +- at76_dbg(DBG_IOCTL, "%s: SIOCSIWRETRY disabled %d flags 0x%x val %d", +- netdev->name, retry->disabled, retry->flags, retry->value); +- +- if (!retry->disabled && (retry->flags & IW_RETRY_LIMIT)) { +- if ((retry->flags & IW_RETRY_MIN) || +- !(retry->flags & IW_RETRY_MAX)) +- priv->short_retry_limit = retry->value; +- else +- ret = -EINVAL; +- } else +- ret = -EINVAL; +- +- return ret; +-} +- +-/* Adapted (ripped) from atmel.c */ +-static int at76_iw_handler_get_retry(struct net_device *netdev, +- struct iw_request_info *info, +- struct iw_param *retry, char *extra) +-{ +- struct at76_priv *priv = netdev_priv(netdev); +- +- at76_dbg(DBG_IOCTL, "%s: SIOCGIWRETRY", netdev->name); +- +- retry->disabled = 0; /* Can't be disabled */ +- retry->flags = IW_RETRY_LIMIT; +- retry->value = priv->short_retry_limit; +- +- return 0; +-} +- +-static int at76_iw_handler_set_encode(struct net_device *netdev, +- struct iw_request_info *info, +- struct iw_point *encoding, char *extra) +-{ +- struct at76_priv *priv = netdev_priv(netdev); +- int index = (encoding->flags & IW_ENCODE_INDEX) - 1; +- int len = encoding->length; +- +- at76_dbg(DBG_IOCTL, "%s: SIOCSIWENCODE - enc.flags %08x " +- "pointer %p len %d", netdev->name, encoding->flags, +- encoding->pointer, encoding->length); +- at76_dbg(DBG_IOCTL, +- "%s: SIOCSIWENCODE - old wepstate: enabled %s key_id %d " +- "auth_mode %s", netdev->name, +- (priv->wep_enabled) ? "true" : "false", priv->wep_key_id, +- (priv->auth_mode == +- WLAN_AUTH_SHARED_KEY) ? "restricted" : "open"); +- +- /* take the old default key if index is invalid */ +- if ((index < 0) || (index >= WEP_KEYS)) +- index = priv->wep_key_id; +- +- if (len > 0) { +- if (len > WEP_LARGE_KEY_LEN) +- len = WEP_LARGE_KEY_LEN; +- +- memset(priv->wep_keys[index], 0, WEP_KEY_LEN); +- memcpy(priv->wep_keys[index], extra, len); +- priv->wep_keys_len[index] = (len <= WEP_SMALL_KEY_LEN) ? +- WEP_SMALL_KEY_LEN : WEP_LARGE_KEY_LEN; +- priv->wep_enabled = 1; +- } +- +- priv->wep_key_id = index; +- priv->wep_enabled = ((encoding->flags & IW_ENCODE_DISABLED) == 0); +- +- if (encoding->flags & IW_ENCODE_RESTRICTED) +- priv->auth_mode = WLAN_AUTH_SHARED_KEY; +- if (encoding->flags & IW_ENCODE_OPEN) +- priv->auth_mode = WLAN_AUTH_OPEN; +- +- at76_dbg(DBG_IOCTL, +- "%s: SIOCSIWENCODE - new wepstate: enabled %s key_id %d " +- "key_len %d auth_mode %s", netdev->name, +- (priv->wep_enabled) ? "true" : "false", priv->wep_key_id + 1, +- priv->wep_keys_len[priv->wep_key_id], +- (priv->auth_mode == +- WLAN_AUTH_SHARED_KEY) ? "restricted" : "open"); +- +- return -EIWCOMMIT; +-} +- +-static int at76_iw_handler_get_encode(struct net_device *netdev, +- struct iw_request_info *info, +- struct iw_point *encoding, char *extra) +-{ +- struct at76_priv *priv = netdev_priv(netdev); +- int index = (encoding->flags & IW_ENCODE_INDEX) - 1; +- +- if ((index < 0) || (index >= WEP_KEYS)) +- index = priv->wep_key_id; +- +- encoding->flags = +- (priv->auth_mode == WLAN_AUTH_SHARED_KEY) ? +- IW_ENCODE_RESTRICTED : IW_ENCODE_OPEN; +- +- if (!priv->wep_enabled) +- encoding->flags |= IW_ENCODE_DISABLED; +- +- if (encoding->pointer) { +- encoding->length = priv->wep_keys_len[index]; +- +- memcpy(extra, priv->wep_keys[index], priv->wep_keys_len[index]); +- +- encoding->flags |= (index + 1); +- } +- +- at76_dbg(DBG_IOCTL, "%s: SIOCGIWENCODE - enc.flags %08x " +- "pointer %p len %d", netdev->name, encoding->flags, +- encoding->pointer, encoding->length); +- at76_dbg(DBG_IOCTL, +- "%s: SIOCGIWENCODE - wepstate: enabled %s key_id %d " +- "key_len %d auth_mode %s", netdev->name, +- (priv->wep_enabled) ? "true" : "false", priv->wep_key_id + 1, +- priv->wep_keys_len[priv->wep_key_id], +- (priv->auth_mode == +- WLAN_AUTH_SHARED_KEY) ? "restricted" : "open"); +- +- return 0; +-} +- +-static int at76_iw_handler_set_power(struct net_device *netdev, +- struct iw_request_info *info, +- struct iw_param *prq, char *extra) +-{ +- int err = -EIWCOMMIT; +- struct at76_priv *priv = netdev_priv(netdev); +- +- at76_dbg(DBG_IOCTL, +- "%s: SIOCSIWPOWER - disabled %s flags 0x%x value 0x%x", +- netdev->name, (prq->disabled) ? "true" : "false", prq->flags, +- prq->value); +- +- if (prq->disabled) +- priv->pm_mode = AT76_PM_OFF; +- else { +- switch (prq->flags & IW_POWER_MODE) { +- case IW_POWER_ALL_R: +- case IW_POWER_ON: +- break; +- default: +- err = -EINVAL; +- goto exit; +- } +- if (prq->flags & IW_POWER_PERIOD) +- priv->pm_period = prq->value; +- +- if (prq->flags & IW_POWER_TIMEOUT) { +- err = -EINVAL; +- goto exit; +- } +- priv->pm_mode = AT76_PM_ON; +- } +-exit: +- return err; +-} +- +-static int at76_iw_handler_get_power(struct net_device *netdev, +- struct iw_request_info *info, +- struct iw_param *power, char *extra) +-{ +- struct at76_priv *priv = netdev_priv(netdev); +- +- power->disabled = (priv->pm_mode == AT76_PM_OFF); +- if (!power->disabled) { +- power->flags = IW_POWER_PERIOD | IW_POWER_ALL_R; +- power->value = priv->pm_period; +- } +- +- at76_dbg(DBG_IOCTL, "%s: SIOCGIWPOWER - %s flags 0x%x value 0x%x", +- netdev->name, power->disabled ? "disabled" : "enabled", +- power->flags, power->value); +- +- return 0; +-} +- +-/******************************************************************************* +- * Private IOCTLS +- */ +-static int at76_iw_set_short_preamble(struct net_device *netdev, +- struct iw_request_info *info, char *name, +- char *extra) +-{ +- struct at76_priv *priv = netdev_priv(netdev); +- int val = *((int *)name); +- int ret = -EIWCOMMIT; +- +- at76_dbg(DBG_IOCTL, "%s: AT76_SET_SHORT_PREAMBLE, %d", +- netdev->name, val); +- +- if (val < PREAMBLE_TYPE_LONG || val > PREAMBLE_TYPE_AUTO) +- ret = -EINVAL; +- else +- priv->preamble_type = val; +- +- return ret; +-} +- +-static int at76_iw_get_short_preamble(struct net_device *netdev, +- struct iw_request_info *info, +- union iwreq_data *wrqu, char *extra) +-{ +- struct at76_priv *priv = netdev_priv(netdev); +- +- snprintf(wrqu->name, sizeof(wrqu->name), "%s (%d)", +- preambles[priv->preamble_type], priv->preamble_type); +- return 0; +-} +- +-static int at76_iw_set_debug(struct net_device *netdev, +- struct iw_request_info *info, +- struct iw_point *data, char *extra) +-{ +- char *ptr; +- u32 val; +- +- if (data->length > 0) { +- val = simple_strtol(extra, &ptr, 0); +- +- if (ptr == extra) +- val = DBG_DEFAULTS; +- +- at76_dbg(DBG_IOCTL, "%s: AT76_SET_DEBUG input %d: %s -> 0x%x", +- netdev->name, data->length, extra, val); +- } else +- val = DBG_DEFAULTS; +- +- at76_dbg(DBG_IOCTL, "%s: AT76_SET_DEBUG, old 0x%x, new 0x%x", +- netdev->name, at76_debug, val); +- +- /* jal: some more output to pin down lockups */ +- at76_dbg(DBG_IOCTL, "%s: netif running %d queue_stopped %d " +- "carrier_ok %d", netdev->name, netif_running(netdev), +- netif_queue_stopped(netdev), netif_carrier_ok(netdev)); +- +- at76_debug = val; +- +- return 0; +-} +- +-static int at76_iw_get_debug(struct net_device *netdev, +- struct iw_request_info *info, +- union iwreq_data *wrqu, char *extra) +-{ +- snprintf(wrqu->name, sizeof(wrqu->name), "0x%08x", at76_debug); +- return 0; +-} +- +-static int at76_iw_set_powersave_mode(struct net_device *netdev, +- struct iw_request_info *info, char *name, +- char *extra) +-{ +- struct at76_priv *priv = netdev_priv(netdev); +- int val = *((int *)name); +- int ret = -EIWCOMMIT; +- +- at76_dbg(DBG_IOCTL, "%s: AT76_SET_POWERSAVE_MODE, %d (%s)", +- netdev->name, val, +- val == AT76_PM_OFF ? "active" : val == AT76_PM_ON ? "save" : +- val == AT76_PM_SMART ? "smart save" : "<invalid>"); +- if (val < AT76_PM_OFF || val > AT76_PM_SMART) +- ret = -EINVAL; +- else +- priv->pm_mode = val; +- +- return ret; +-} +- +-static int at76_iw_get_powersave_mode(struct net_device *netdev, +- struct iw_request_info *info, +- union iwreq_data *wrqu, char *extra) +-{ +- struct at76_priv *priv = netdev_priv(netdev); +- int *param = (int *)extra; +- +- param[0] = priv->pm_mode; +- return 0; +-} +- +-static int at76_iw_set_scan_times(struct net_device *netdev, +- struct iw_request_info *info, char *name, +- char *extra) +-{ +- struct at76_priv *priv = netdev_priv(netdev); +- int mint = *((int *)name); +- int maxt = *((int *)name + 1); +- int ret = -EIWCOMMIT; +- +- at76_dbg(DBG_IOCTL, "%s: AT76_SET_SCAN_TIMES - min %d max %d", +- netdev->name, mint, maxt); +- if (mint <= 0 || maxt <= 0 || mint > maxt) +- ret = -EINVAL; +- else { +- priv->scan_min_time = mint; +- priv->scan_max_time = maxt; +- } +- +- return ret; +-} +- +-static int at76_iw_get_scan_times(struct net_device *netdev, +- struct iw_request_info *info, +- union iwreq_data *wrqu, char *extra) +-{ +- struct at76_priv *priv = netdev_priv(netdev); +- int *param = (int *)extra; +- +- param[0] = priv->scan_min_time; +- param[1] = priv->scan_max_time; +- return 0; +-} +- +-static int at76_iw_set_scan_mode(struct net_device *netdev, +- struct iw_request_info *info, char *name, +- char *extra) +-{ +- struct at76_priv *priv = netdev_priv(netdev); +- int val = *((int *)name); +- int ret = -EIWCOMMIT; +- +- at76_dbg(DBG_IOCTL, "%s: AT76_SET_SCAN_MODE - mode %s", +- netdev->name, (val = SCAN_TYPE_ACTIVE) ? "active" : +- (val = SCAN_TYPE_PASSIVE) ? "passive" : "<invalid>"); +- +- if (val != SCAN_TYPE_ACTIVE && val != SCAN_TYPE_PASSIVE) +- ret = -EINVAL; +- else +- priv->scan_mode = val; +- +- return ret; +-} +- +-static int at76_iw_get_scan_mode(struct net_device *netdev, +- struct iw_request_info *info, +- union iwreq_data *wrqu, char *extra) +-{ +- struct at76_priv *priv = netdev_priv(netdev); +- int *param = (int *)extra; +- +- param[0] = priv->scan_mode; +- return 0; +-} +- +-#define AT76_SET_HANDLER(h, f) [h - SIOCIWFIRST] = (iw_handler) f +- +-/* Standard wireless handlers */ +-static const iw_handler at76_handlers[] = { +- AT76_SET_HANDLER(SIOCSIWCOMMIT, at76_iw_handler_commit), +- AT76_SET_HANDLER(SIOCGIWNAME, at76_iw_handler_get_name), +- AT76_SET_HANDLER(SIOCSIWFREQ, at76_iw_handler_set_freq), +- AT76_SET_HANDLER(SIOCGIWFREQ, at76_iw_handler_get_freq), +- AT76_SET_HANDLER(SIOCSIWMODE, at76_iw_handler_set_mode), +- AT76_SET_HANDLER(SIOCGIWMODE, at76_iw_handler_get_mode), +- AT76_SET_HANDLER(SIOCGIWRANGE, at76_iw_handler_get_range), +- AT76_SET_HANDLER(SIOCSIWSPY, at76_iw_handler_set_spy), +- AT76_SET_HANDLER(SIOCGIWSPY, at76_iw_handler_get_spy), +- AT76_SET_HANDLER(SIOCSIWTHRSPY, at76_iw_handler_set_thrspy), +- AT76_SET_HANDLER(SIOCGIWTHRSPY, at76_iw_handler_get_thrspy), +- AT76_SET_HANDLER(SIOCSIWAP, at76_iw_handler_set_wap), +- AT76_SET_HANDLER(SIOCGIWAP, at76_iw_handler_get_wap), +- AT76_SET_HANDLER(SIOCSIWSCAN, at76_iw_handler_set_scan), +- AT76_SET_HANDLER(SIOCGIWSCAN, at76_iw_handler_get_scan), +- AT76_SET_HANDLER(SIOCSIWESSID, at76_iw_handler_set_essid), +- AT76_SET_HANDLER(SIOCGIWESSID, at76_iw_handler_get_essid), +- AT76_SET_HANDLER(SIOCSIWRATE, at76_iw_handler_set_rate), +- AT76_SET_HANDLER(SIOCGIWRATE, at76_iw_handler_get_rate), +- AT76_SET_HANDLER(SIOCSIWRTS, at76_iw_handler_set_rts), +- AT76_SET_HANDLER(SIOCGIWRTS, at76_iw_handler_get_rts), +- AT76_SET_HANDLER(SIOCSIWFRAG, at76_iw_handler_set_frag), +- AT76_SET_HANDLER(SIOCGIWFRAG, at76_iw_handler_get_frag), +- AT76_SET_HANDLER(SIOCGIWTXPOW, at76_iw_handler_get_txpow), +- AT76_SET_HANDLER(SIOCSIWRETRY, at76_iw_handler_set_retry), +- AT76_SET_HANDLER(SIOCGIWRETRY, at76_iw_handler_get_retry), +- AT76_SET_HANDLER(SIOCSIWENCODE, at76_iw_handler_set_encode), +- AT76_SET_HANDLER(SIOCGIWENCODE, at76_iw_handler_get_encode), +- AT76_SET_HANDLER(SIOCSIWPOWER, at76_iw_handler_set_power), +- AT76_SET_HANDLER(SIOCGIWPOWER, at76_iw_handler_get_power) +-}; +- +-#define AT76_SET_PRIV(h, f) [h - SIOCIWFIRSTPRIV] = (iw_handler) f +- +-/* Private wireless handlers */ +-static const iw_handler at76_priv_handlers[] = { +- AT76_SET_PRIV(AT76_SET_SHORT_PREAMBLE, at76_iw_set_short_preamble), +- AT76_SET_PRIV(AT76_GET_SHORT_PREAMBLE, at76_iw_get_short_preamble), +- AT76_SET_PRIV(AT76_SET_DEBUG, at76_iw_set_debug), +- AT76_SET_PRIV(AT76_GET_DEBUG, at76_iw_get_debug), +- AT76_SET_PRIV(AT76_SET_POWERSAVE_MODE, at76_iw_set_powersave_mode), +- AT76_SET_PRIV(AT76_GET_POWERSAVE_MODE, at76_iw_get_powersave_mode), +- AT76_SET_PRIV(AT76_SET_SCAN_TIMES, at76_iw_set_scan_times), +- AT76_SET_PRIV(AT76_GET_SCAN_TIMES, at76_iw_get_scan_times), +- AT76_SET_PRIV(AT76_SET_SCAN_MODE, at76_iw_set_scan_mode), +- AT76_SET_PRIV(AT76_GET_SCAN_MODE, at76_iw_get_scan_mode), +-}; +- +-/* Names and arguments of private wireless handlers */ +-static const struct iw_priv_args at76_priv_args[] = { +- /* 0 - long, 1 - short */ +- {AT76_SET_SHORT_PREAMBLE, +- IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, 0, "set_preamble"}, +- +- {AT76_GET_SHORT_PREAMBLE, +- 0, IW_PRIV_TYPE_CHAR | IW_PRIV_SIZE_FIXED | 10, "get_preamble"}, +- +- /* we must pass the new debug mask as a string, because iwpriv cannot +- * parse hex numbers starting with 0x :-( */ +- {AT76_SET_DEBUG, +- IW_PRIV_TYPE_CHAR | 10, 0, "set_debug"}, +- +- {AT76_GET_DEBUG, +- 0, IW_PRIV_TYPE_CHAR | IW_PRIV_SIZE_FIXED | 10, "get_debug"}, +- +- /* 1 - active, 2 - power save, 3 - smart power save */ +- {AT76_SET_POWERSAVE_MODE, +- IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, 0, "set_powersave"}, +- +- {AT76_GET_POWERSAVE_MODE, +- 0, IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, "get_powersave"}, +- +- /* min_channel_time, max_channel_time */ +- {AT76_SET_SCAN_TIMES, +- IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 2, 0, "set_scan_times"}, +- +- {AT76_GET_SCAN_TIMES, +- 0, IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 2, "get_scan_times"}, +- +- /* 0 - active, 1 - passive scan */ +- {AT76_SET_SCAN_MODE, +- IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, 0, "set_scan_mode"}, +- +- {AT76_GET_SCAN_MODE, +- 0, IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, "get_scan_mode"}, +-}; +- +-static const struct iw_handler_def at76_handler_def = { +- .num_standard = ARRAY_SIZE(at76_handlers), +- .num_private = ARRAY_SIZE(at76_priv_handlers), +- .num_private_args = ARRAY_SIZE(at76_priv_args), +- .standard = at76_handlers, +- .private = at76_priv_handlers, +- .private_args = at76_priv_args, +- .get_wireless_stats = at76_get_wireless_stats, +-}; +- +-static const u8 snapsig[] = { 0xaa, 0xaa, 0x03 }; +- +-/* RFC 1042 encapsulates Ethernet frames in 802.2 SNAP (0xaa, 0xaa, 0x03) with +- * a SNAP OID of 0 (0x00, 0x00, 0x00) */ +-static const u8 rfc1042sig[] = { 0xaa, 0xaa, 0x03, 0x00, 0x00, 0x00 }; +- +-static int at76_tx(struct sk_buff *skb, struct net_device *netdev) +-{ +- struct at76_priv *priv = netdev_priv(netdev); +- struct net_device_stats *stats = &priv->stats; +- int ret = 0; +- int wlen; +- int submit_len; +- struct at76_tx_buffer *tx_buffer = priv->bulk_out_buffer; +- struct ieee80211_hdr_3addr *i802_11_hdr = +- (struct ieee80211_hdr_3addr *)tx_buffer->packet; +- u8 *payload = i802_11_hdr->payload; +- struct ethhdr *eh = (struct ethhdr *)skb->data; +- +- if (netif_queue_stopped(netdev)) { +- printk(KERN_ERR "%s: %s called while netdev is stopped\n", +- netdev->name, __func__); +- /* skip this packet */ +- dev_kfree_skb(skb); +- return 0; +- } +- +- if (priv->tx_urb->status == -EINPROGRESS) { +- printk(KERN_ERR "%s: %s called while tx urb is pending\n", +- netdev->name, __func__); +- /* skip this packet */ +- dev_kfree_skb(skb); +- return 0; +- } +- +- if (skb->len < ETH_HLEN) { +- printk(KERN_ERR "%s: %s: skb too short (%d)\n", +- netdev->name, __func__, skb->len); +- dev_kfree_skb(skb); +- return 0; +- } +- +- at76_ledtrig_tx_activity(); /* tell ledtrigger we send a packet */ +- +- /* we can get rid of memcpy if we set netdev->hard_header_len to +- reserve enough space, but we would need to keep the skb around */ +- +- if (ntohs(eh->h_proto) <= ETH_DATA_LEN) { +- /* this is a 802.3 packet */ +- if (skb->len >= ETH_HLEN + sizeof(rfc1042sig) +- && skb->data[ETH_HLEN] == rfc1042sig[0] +- && skb->data[ETH_HLEN + 1] == rfc1042sig[1]) { +- /* higher layer delivered SNAP header - keep it */ +- memcpy(payload, skb->data + ETH_HLEN, +- skb->len - ETH_HLEN); +- wlen = IEEE80211_3ADDR_LEN + skb->len - ETH_HLEN; +- } else { +- printk(KERN_ERR "%s: dropping non-SNAP 802.2 packet " +- "(DSAP 0x%02x SSAP 0x%02x cntrl 0x%02x)\n", +- priv->netdev->name, skb->data[ETH_HLEN], +- skb->data[ETH_HLEN + 1], +- skb->data[ETH_HLEN + 2]); +- dev_kfree_skb(skb); +- return 0; +- } +- } else { +- /* add RFC 1042 header in front */ +- memcpy(payload, rfc1042sig, sizeof(rfc1042sig)); +- memcpy(payload + sizeof(rfc1042sig), &eh->h_proto, +- skb->len - offsetof(struct ethhdr, h_proto)); +- wlen = IEEE80211_3ADDR_LEN + sizeof(rfc1042sig) + skb->len - +- offsetof(struct ethhdr, h_proto); +- } +- +- /* make wireless header */ +- i802_11_hdr->frame_ctl = +- cpu_to_le16(IEEE80211_FTYPE_DATA | +- (priv->wep_enabled ? IEEE80211_FCTL_PROTECTED : 0) | +- (priv->iw_mode == +- IW_MODE_INFRA ? IEEE80211_FCTL_TODS : 0)); +- +- if (priv->iw_mode == IW_MODE_ADHOC) { +- memcpy(i802_11_hdr->addr1, eh->h_dest, ETH_ALEN); +- memcpy(i802_11_hdr->addr2, eh->h_source, ETH_ALEN); +- memcpy(i802_11_hdr->addr3, priv->bssid, ETH_ALEN); +- } else if (priv->iw_mode == IW_MODE_INFRA) { +- memcpy(i802_11_hdr->addr1, priv->bssid, ETH_ALEN); +- memcpy(i802_11_hdr->addr2, eh->h_source, ETH_ALEN); +- memcpy(i802_11_hdr->addr3, eh->h_dest, ETH_ALEN); +- } +- +- i802_11_hdr->duration_id = cpu_to_le16(0); +- i802_11_hdr->seq_ctl = cpu_to_le16(0); +- +- /* setup 'Atmel' header */ +- tx_buffer->wlength = cpu_to_le16(wlen); +- tx_buffer->tx_rate = priv->txrate; +- /* for broadcast destination addresses, the firmware 0.100.x +- seems to choose the highest rate set with CMD_STARTUP in +- basic_rate_set replacing this value */ +- +- memset(tx_buffer->reserved, 0, sizeof(tx_buffer->reserved)); +- +- tx_buffer->padding = at76_calc_padding(wlen); +- submit_len = wlen + AT76_TX_HDRLEN + tx_buffer->padding; +- +- at76_dbg(DBG_TX_DATA_CONTENT, "%s skb->data %s", priv->netdev->name, +- hex2str(skb->data, 32)); +- at76_dbg(DBG_TX_DATA, "%s tx: wlen 0x%x pad 0x%x rate %d hdr %s", +- priv->netdev->name, +- le16_to_cpu(tx_buffer->wlength), +- tx_buffer->padding, tx_buffer->tx_rate, +- hex2str(i802_11_hdr, sizeof(*i802_11_hdr))); +- at76_dbg(DBG_TX_DATA_CONTENT, "%s payload %s", priv->netdev->name, +- hex2str(payload, 48)); +- +- /* send stuff */ +- netif_stop_queue(netdev); +- netdev->trans_start = jiffies; +- +- usb_fill_bulk_urb(priv->tx_urb, priv->udev, priv->tx_pipe, tx_buffer, +- submit_len, at76_tx_callback, priv); +- ret = usb_submit_urb(priv->tx_urb, GFP_ATOMIC); +- if (ret) { +- stats->tx_errors++; +- printk(KERN_ERR "%s: error in tx submit urb: %d\n", +- netdev->name, ret); +- if (ret == -EINVAL) +- printk(KERN_ERR +- "%s: -EINVAL: tx urb %p hcpriv %p complete %p\n", +- priv->netdev->name, priv->tx_urb, +- priv->tx_urb->hcpriv, priv->tx_urb->complete); +- } else { +- stats->tx_bytes += skb->len; +- dev_kfree_skb(skb); +- } +- +- return ret; +-} +- +-static void at76_tx_timeout(struct net_device *netdev) +-{ +- struct at76_priv *priv = netdev_priv(netdev); +- +- if (!priv) +- return; +- dev_warn(&netdev->dev, "tx timeout."); +- +- usb_unlink_urb(priv->tx_urb); +- priv->stats.tx_errors++; +-} +- +-static int at76_submit_rx_urb(struct at76_priv *priv) +-{ +- int ret; +- int size; +- struct sk_buff *skb = priv->rx_skb; +- +- if (!priv->rx_urb) { +- printk(KERN_ERR "%s: %s: priv->rx_urb is NULL\n", +- priv->netdev->name, __func__); +- return -EFAULT; +- } +- +- if (!skb) { +- skb = dev_alloc_skb(sizeof(struct at76_rx_buffer)); +- if (!skb) { +- printk(KERN_ERR "%s: cannot allocate rx skbuff\n", +- priv->netdev->name); +- ret = -ENOMEM; +- goto exit; +- } +- priv->rx_skb = skb; +- } else { +- skb_push(skb, skb_headroom(skb)); +- skb_trim(skb, 0); +- } +- +- size = skb_tailroom(skb); +- usb_fill_bulk_urb(priv->rx_urb, priv->udev, priv->rx_pipe, +- skb_put(skb, size), size, at76_rx_callback, priv); +- ret = usb_submit_urb(priv->rx_urb, GFP_ATOMIC); +- if (ret < 0) { +- if (ret == -ENODEV) +- at76_dbg(DBG_DEVSTART, +- "usb_submit_urb returned -ENODEV"); +- else +- printk(KERN_ERR "%s: rx, usb_submit_urb failed: %d\n", +- priv->netdev->name, ret); +- } +- +-exit: +- if (ret < 0 && ret != -ENODEV) +- printk(KERN_ERR "%s: cannot submit rx urb - please unload the " +- "driver and/or power cycle the device\n", +- priv->netdev->name); +- +- return ret; +-} +- +-static int at76_open(struct net_device *netdev) +-{ +- struct at76_priv *priv = netdev_priv(netdev); +- int ret = 0; +- +- at76_dbg(DBG_PROC_ENTRY, "%s(): entry", __func__); +- +- if (mutex_lock_interruptible(&priv->mtx)) +- return -EINTR; +- +- /* if netdev->dev_addr != priv->mac_addr we must +- set the mac address in the device ! */ +- if (compare_ether_addr(netdev->dev_addr, priv->mac_addr)) { +- if (at76_add_mac_address(priv, netdev->dev_addr) >= 0) +- at76_dbg(DBG_PROGRESS, "%s: set new MAC addr %s", +- netdev->name, mac2str(netdev->dev_addr)); +- } +- +- priv->scan_state = SCAN_IDLE; +- priv->last_scan = jiffies; +- +- ret = at76_submit_rx_urb(priv); +- if (ret < 0) { +- printk(KERN_ERR "%s: open: submit_rx_urb failed: %d\n", +- netdev->name, ret); +- goto error; +- } +- +- schedule_delayed_work(&priv->dwork_restart, 0); +- +- at76_dbg(DBG_PROC_ENTRY, "%s(): end", __func__); +-error: +- mutex_unlock(&priv->mtx); +- return ret < 0 ? ret : 0; +-} +- +-static int at76_stop(struct net_device *netdev) +-{ +- struct at76_priv *priv = netdev_priv(netdev); +- +- at76_dbg(DBG_DEVSTART, "%s: ENTER", __func__); +- +- if (mutex_lock_interruptible(&priv->mtx)) +- return -EINTR; +- +- at76_quiesce(priv); +- +- if (!priv->device_unplugged) { +- /* We are called by "ifconfig ethX down", not because the +- * device is not available anymore. */ +- at76_set_radio(priv, 0); +- +- /* We unlink rx_urb because at76_open() re-submits it. +- * If unplugged, at76_delete_device() takes care of it. */ +- usb_kill_urb(priv->rx_urb); +- } +- +- /* free the bss_list */ +- at76_free_bss_list(priv); +- +- mutex_unlock(&priv->mtx); +- at76_dbg(DBG_DEVSTART, "%s: EXIT", __func__); +- +- return 0; +-} +- +-static void at76_ethtool_get_drvinfo(struct net_device *netdev, +- struct ethtool_drvinfo *info) +-{ +- struct at76_priv *priv = netdev_priv(netdev); +- +- strncpy(info->driver, DRIVER_NAME, sizeof(info->driver)); +- strncpy(info->version, DRIVER_VERSION, sizeof(info->version)); +- +- usb_make_path(priv->udev, info->bus_info, sizeof(info->bus_info)); +- +- snprintf(info->fw_version, sizeof(info->fw_version), "%d.%d.%d-%d", +- priv->fw_version.major, priv->fw_version.minor, +- priv->fw_version.patch, priv->fw_version.build); +-} +- +-static u32 at76_ethtool_get_link(struct net_device *netdev) +-{ +- struct at76_priv *priv = netdev_priv(netdev); +- return priv->mac_state == MAC_CONNECTED; +-} +- +-static struct ethtool_ops at76_ethtool_ops = { +- .get_drvinfo = at76_ethtool_get_drvinfo, +- .get_link = at76_ethtool_get_link, +-}; +- +-/* Download external firmware */ +-static int at76_load_external_fw(struct usb_device *udev, struct fwentry *fwe) +-{ +- int ret; +- int op_mode; +- int blockno = 0; +- int bsize; +- u8 *block; +- u8 *buf = fwe->extfw; +- int size = fwe->extfw_size; +- +- if (!buf || !size) +- return -ENOENT; +- +- op_mode = at76_get_op_mode(udev); +- at76_dbg(DBG_DEVSTART, "opmode %d", op_mode); ++ op_mode = at76_get_op_mode(udev); ++ at76_dbg(DBG_DEVSTART, "opmode %d", op_mode); + + if (op_mode != OPMODE_NORMAL_NIC_WITHOUT_FLASH) { + dev_printk(KERN_ERR, &udev->dev, "unexpected opmode %d\n", +@@ -3458,444 +1423,44 @@ + exit: + kfree(block); + if (ret < 0) +- dev_printk(KERN_ERR, &udev->dev, +- "downloading external firmware failed: %d\n", ret); +- return ret; +-} +- +-/* Download internal firmware */ +-static int at76_load_internal_fw(struct usb_device *udev, struct fwentry *fwe) +-{ +- int ret; +- int need_remap = !at76_is_505a(fwe->board_type); +- +- ret = at76_usbdfu_download(udev, fwe->intfw, fwe->intfw_size, +- need_remap ? 0 : 2 * HZ); +- +- if (ret < 0) { +- dev_printk(KERN_ERR, &udev->dev, +- "downloading internal fw failed with %d\n", ret); +- goto exit; +- } +- +- at76_dbg(DBG_DEVSTART, "sending REMAP"); +- +- /* no REMAP for 505A (see SF driver) */ +- if (need_remap) { +- ret = at76_remap(udev); +- if (ret < 0) { +- dev_printk(KERN_ERR, &udev->dev, +- "sending REMAP failed with %d\n", ret); +- goto exit; +- } +- } +- +- at76_dbg(DBG_DEVSTART, "sleeping for 2 seconds"); +- schedule_timeout_interruptible(2 * HZ + 1); +- usb_reset_device(udev); +- +-exit: +- return ret; +-} +- +-static int at76_match_essid(struct at76_priv *priv, struct bss_info *ptr) +-{ +- /* common criteria for both modi */ +- +- int ret = (priv->essid_size == 0 /* ANY ssid */ || +- (priv->essid_size == ptr->ssid_len && +- !memcmp(priv->essid, ptr->ssid, ptr->ssid_len))); +- if (!ret) +- at76_dbg(DBG_BSS_MATCH, +- "%s bss table entry %p: essid didn't match", +- priv->netdev->name, ptr); +- return ret; +-} +- +-static inline int at76_match_mode(struct at76_priv *priv, struct bss_info *ptr) +-{ +- int ret; +- +- if (priv->iw_mode == IW_MODE_ADHOC) +- ret = ptr->capa & WLAN_CAPABILITY_IBSS; +- else +- ret = ptr->capa & WLAN_CAPABILITY_ESS; +- if (!ret) +- at76_dbg(DBG_BSS_MATCH, +- "%s bss table entry %p: mode didn't match", +- priv->netdev->name, ptr); +- return ret; +-} +- +-static int at76_match_rates(struct at76_priv *priv, struct bss_info *ptr) +-{ +- int i; +- +- for (i = 0; i < ptr->rates_len; i++) { +- u8 rate = ptr->rates[i]; +- +- if (!(rate & 0x80)) +- continue; +- +- /* this is a basic rate we have to support +- (see IEEE802.11, ch. 7.3.2.2) */ +- if (rate != (0x80 | hw_rates[0]) +- && rate != (0x80 | hw_rates[1]) +- && rate != (0x80 | hw_rates[2]) +- && rate != (0x80 | hw_rates[3])) { +- at76_dbg(DBG_BSS_MATCH, +- "%s: bss table entry %p: basic rate %02x not " +- "supported", priv->netdev->name, ptr, rate); +- return 0; +- } +- } +- +- /* if we use short preamble, the bss must support it */ +- if (priv->preamble_type == PREAMBLE_TYPE_SHORT && +- !(ptr->capa & WLAN_CAPABILITY_SHORT_PREAMBLE)) { +- at76_dbg(DBG_BSS_MATCH, +- "%s: %p does not support short preamble", +- priv->netdev->name, ptr); +- return 0; +- } else +- return 1; +-} +- +-static inline int at76_match_wep(struct at76_priv *priv, struct bss_info *ptr) +-{ +- if (!priv->wep_enabled && ptr->capa & WLAN_CAPABILITY_PRIVACY) { +- /* we have disabled WEP, but the BSS signals privacy */ +- at76_dbg(DBG_BSS_MATCH, +- "%s: bss table entry %p: requires encryption", +- priv->netdev->name, ptr); +- return 0; +- } +- /* otherwise if the BSS does not signal privacy it may well +- accept encrypted packets from us ... */ +- return 1; +-} +- +-static inline int at76_match_bssid(struct at76_priv *priv, struct bss_info *ptr) +-{ +- if (!priv->wanted_bssid_valid || +- !compare_ether_addr(ptr->bssid, priv->wanted_bssid)) +- return 1; +- +- at76_dbg(DBG_BSS_MATCH, +- "%s: requested bssid - %s does not match", +- priv->netdev->name, mac2str(priv->wanted_bssid)); +- at76_dbg(DBG_BSS_MATCH, +- " AP bssid - %s of bss table entry %p", +- mac2str(ptr->bssid), ptr); +- return 0; +-} +- +-/** +- * at76_match_bss - try to find a matching bss in priv->bss +- * +- * last - last bss tried +- * +- * last == NULL signals a new round starting with priv->bss_list.next +- * this function must be called inside an acquired priv->bss_list_spinlock +- * otherwise the timeout on bss may remove the newly chosen entry +- */ +-static struct bss_info *at76_match_bss(struct at76_priv *priv, +- struct bss_info *last) +-{ +- struct bss_info *ptr = NULL; +- struct list_head *curr; +- +- curr = last ? last->list.next : priv->bss_list.next; +- while (curr != &priv->bss_list) { +- ptr = list_entry(curr, struct bss_info, list); +- if (at76_match_essid(priv, ptr) && at76_match_mode(priv, ptr) +- && at76_match_wep(priv, ptr) && at76_match_rates(priv, ptr) +- && at76_match_bssid(priv, ptr)) +- break; +- curr = curr->next; +- } +- +- if (curr == &priv->bss_list) +- ptr = NULL; +- /* otherwise ptr points to the struct bss_info we have chosen */ +- +- at76_dbg(DBG_BSS_TABLE, "%s %s: returned %p", priv->netdev->name, +- __func__, ptr); +- return ptr; +-} +- +-/* Start joining a matching BSS, or create own IBSS */ +-static void at76_work_join(struct work_struct *work) +-{ +- struct at76_priv *priv = container_of(work, struct at76_priv, +- work_join); +- int ret; +- unsigned long flags; +- +- mutex_lock(&priv->mtx); +- +- WARN_ON(priv->mac_state != MAC_JOINING); +- if (priv->mac_state != MAC_JOINING) +- goto exit; +- +- /* secure the access to priv->curr_bss ! */ +- spin_lock_irqsave(&priv->bss_list_spinlock, flags); +- priv->curr_bss = at76_match_bss(priv, priv->curr_bss); +- spin_unlock_irqrestore(&priv->bss_list_spinlock, flags); +- +- if (!priv->curr_bss) { +- /* here we haven't found a matching (i)bss ... */ +- if (priv->iw_mode == IW_MODE_ADHOC) { +- at76_set_mac_state(priv, MAC_OWN_IBSS); +- at76_start_ibss(priv); +- goto exit; +- } +- /* haven't found a matching BSS in infra mode - try again */ +- at76_set_mac_state(priv, MAC_SCANNING); +- schedule_work(&priv->work_start_scan); +- goto exit; +- } +- +- ret = at76_join_bss(priv, priv->curr_bss); +- if (ret < 0) { +- printk(KERN_ERR "%s: join_bss failed with %d\n", +- priv->netdev->name, ret); +- goto exit; +- } +- +- ret = at76_wait_completion(priv, CMD_JOIN); +- if (ret != CMD_STATUS_COMPLETE) { +- if (ret != CMD_STATUS_TIME_OUT) +- printk(KERN_ERR "%s: join_bss completed with %d\n", +- priv->netdev->name, ret); +- else +- printk(KERN_INFO "%s: join_bss ssid %s timed out\n", +- priv->netdev->name, +- mac2str(priv->curr_bss->bssid)); +- +- /* retry next BSS immediately */ +- schedule_work(&priv->work_join); +- goto exit; +- } +- +- /* here we have joined the (I)BSS */ +- if (priv->iw_mode == IW_MODE_ADHOC) { +- struct bss_info *bptr = priv->curr_bss; +- at76_set_mac_state(priv, MAC_CONNECTED); +- /* get ESSID, BSSID and channel for priv->curr_bss */ +- priv->essid_size = bptr->ssid_len; +- memcpy(priv->essid, bptr->ssid, bptr->ssid_len); +- memcpy(priv->bssid, bptr->bssid, ETH_ALEN); +- priv->channel = bptr->channel; +- at76_iwevent_bss_connect(priv->netdev, bptr->bssid); +- netif_carrier_on(priv->netdev); +- netif_start_queue(priv->netdev); +- /* just to be sure */ +- cancel_delayed_work(&priv->dwork_get_scan); +- cancel_delayed_work(&priv->dwork_auth); +- cancel_delayed_work(&priv->dwork_assoc); +- } else { +- /* send auth req */ +- priv->retries = AUTH_RETRIES; +- at76_set_mac_state(priv, MAC_AUTH); +- at76_auth_req(priv, priv->curr_bss, 1, NULL); +- at76_dbg(DBG_MGMT_TIMER, +- "%s:%d: starting mgmt_timer + HZ", __func__, __LINE__); +- schedule_delayed_work(&priv->dwork_auth, AUTH_TIMEOUT); +- } +- +-exit: +- mutex_unlock(&priv->mtx); +-} +- +-/* Reap scan results */ +-static void at76_dwork_get_scan(struct work_struct *work) +-{ +- int status; +- int ret; +- struct at76_priv *priv = container_of(work, struct at76_priv, +- dwork_get_scan.work); +- +- mutex_lock(&priv->mtx); +- WARN_ON(priv->mac_state != MAC_SCANNING); +- if (priv->mac_state != MAC_SCANNING) +- goto exit; +- +- status = at76_get_cmd_status(priv->udev, CMD_SCAN); +- if (status < 0) { +- printk(KERN_ERR "%s: %s: at76_get_cmd_status failed with %d\n", +- priv->netdev->name, __func__, status); +- status = CMD_STATUS_IN_PROGRESS; +- /* INFO: Hope it was a one off error - if not, scanning +- further down the line and stop this cycle */ +- } +- at76_dbg(DBG_PROGRESS, +- "%s %s: got cmd_status %d (state %s, need_any %d)", +- priv->netdev->name, __func__, status, +- mac_states[priv->mac_state], priv->scan_need_any); +- +- if (status != CMD_STATUS_COMPLETE) { +- if ((status != CMD_STATUS_IN_PROGRESS) && +- (status != CMD_STATUS_IDLE)) +- printk(KERN_ERR "%s: %s: Bad scan status: %s\n", +- priv->netdev->name, __func__, +- at76_get_cmd_status_string(status)); +- +- /* the first cmd status after scan start is always a IDLE -> +- start the timer to poll again until COMPLETED */ +- at76_dbg(DBG_MGMT_TIMER, +- "%s:%d: starting mgmt_timer for %d ticks", +- __func__, __LINE__, SCAN_POLL_INTERVAL); +- schedule_delayed_work(&priv->dwork_get_scan, +- SCAN_POLL_INTERVAL); +- goto exit; +- } +- +- if (at76_debug & DBG_BSS_TABLE) +- at76_dump_bss_table(priv); +- +- if (priv->scan_need_any) { +- ret = at76_start_scan(priv, 0); +- if (ret < 0) +- printk(KERN_ERR +- "%s: %s: start_scan (ANY) failed with %d\n", +- priv->netdev->name, __func__, ret); +- at76_dbg(DBG_MGMT_TIMER, +- "%s:%d: starting mgmt_timer for %d ticks", __func__, +- __LINE__, SCAN_POLL_INTERVAL); +- schedule_delayed_work(&priv->dwork_get_scan, +- SCAN_POLL_INTERVAL); +- priv->scan_need_any = 0; +- } else { +- priv->scan_state = SCAN_COMPLETED; +- /* report the end of scan to user space */ +- at76_iwevent_scan_complete(priv->netdev); +- at76_set_mac_state(priv, MAC_JOINING); +- schedule_work(&priv->work_join); +- } +- +-exit: +- mutex_unlock(&priv->mtx); +-} +- +-/* Handle loss of beacons from the AP */ +-static void at76_dwork_beacon(struct work_struct *work) +-{ +- struct at76_priv *priv = container_of(work, struct at76_priv, +- dwork_beacon.work); +- +- mutex_lock(&priv->mtx); +- if (priv->mac_state != MAC_CONNECTED || priv->iw_mode != IW_MODE_INFRA) +- goto exit; +- +- /* We haven't received any beacons from out AP for BEACON_TIMEOUT */ +- printk(KERN_INFO "%s: lost beacon bssid %s\n", +- priv->netdev->name, mac2str(priv->curr_bss->bssid)); +- +- netif_carrier_off(priv->netdev); +- netif_stop_queue(priv->netdev); +- at76_iwevent_bss_disconnect(priv->netdev); +- at76_set_mac_state(priv, MAC_SCANNING); +- schedule_work(&priv->work_start_scan); +- +-exit: +- mutex_unlock(&priv->mtx); +-} +- +-/* Handle authentication response timeout */ +-static void at76_dwork_auth(struct work_struct *work) +-{ +- struct at76_priv *priv = container_of(work, struct at76_priv, +- dwork_auth.work); +- +- mutex_lock(&priv->mtx); +- WARN_ON(priv->mac_state != MAC_AUTH); +- if (priv->mac_state != MAC_AUTH) +- goto exit; +- +- at76_dbg(DBG_PROGRESS, "%s: authentication response timeout", +- priv->netdev->name); +- +- if (priv->retries-- >= 0) { +- at76_auth_req(priv, priv->curr_bss, 1, NULL); +- at76_dbg(DBG_MGMT_TIMER, "%s:%d: starting mgmt_timer + HZ", +- __func__, __LINE__); +- schedule_delayed_work(&priv->dwork_auth, AUTH_TIMEOUT); +- } else { +- /* try to get next matching BSS */ +- at76_set_mac_state(priv, MAC_JOINING); +- schedule_work(&priv->work_join); +- } +- +-exit: +- mutex_unlock(&priv->mtx); +-} +- +-/* Handle association response timeout */ +-static void at76_dwork_assoc(struct work_struct *work) +-{ +- struct at76_priv *priv = container_of(work, struct at76_priv, +- dwork_assoc.work); +- +- mutex_lock(&priv->mtx); +- WARN_ON(priv->mac_state != MAC_ASSOC); +- if (priv->mac_state != MAC_ASSOC) +- goto exit; +- +- at76_dbg(DBG_PROGRESS, "%s: association response timeout", +- priv->netdev->name); +- +- if (priv->retries-- >= 0) { +- at76_assoc_req(priv, priv->curr_bss); +- at76_dbg(DBG_MGMT_TIMER, "%s:%d: starting mgmt_timer + HZ", +- __func__, __LINE__); +- schedule_delayed_work(&priv->dwork_assoc, ASSOC_TIMEOUT); +- } else { +- /* try to get next matching BSS */ +- at76_set_mac_state(priv, MAC_JOINING); +- schedule_work(&priv->work_join); +- } +- +-exit: +- mutex_unlock(&priv->mtx); ++ dev_printk(KERN_ERR, &udev->dev, ++ "downloading external firmware failed: %d\n", ret); ++ return ret; + } + +-/* Read new bssid in ad-hoc mode */ +-static void at76_work_new_bss(struct work_struct *work) ++/* Download internal firmware */ ++static int at76_load_internal_fw(struct usb_device *udev, struct fwentry *fwe) + { +- struct at76_priv *priv = container_of(work, struct at76_priv, +- work_new_bss); + int ret; +- struct mib_mac_mgmt mac_mgmt; ++ int need_remap = !at76_is_505a(fwe->board_type); + +- mutex_lock(&priv->mtx); ++ ret = at76_usbdfu_download(udev, fwe->intfw, fwe->intfw_size, ++ need_remap ? 0 : 2 * HZ); + +- ret = at76_get_mib(priv->udev, MIB_MAC_MGMT, &mac_mgmt, +- sizeof(struct mib_mac_mgmt)); + if (ret < 0) { +- printk(KERN_ERR "%s: at76_get_mib failed: %d\n", +- priv->netdev->name, ret); ++ dev_printk(KERN_ERR, &udev->dev, ++ "downloading internal fw failed with %d\n", ret); + goto exit; + } + +- at76_dbg(DBG_PROGRESS, "ibss_change = 0x%2x", mac_mgmt.ibss_change); +- memcpy(priv->bssid, mac_mgmt.current_bssid, ETH_ALEN); +- at76_dbg(DBG_PROGRESS, "using BSSID %s", mac2str(priv->bssid)); +- +- at76_iwevent_bss_connect(priv->netdev, priv->bssid); ++ at76_dbg(DBG_DEVSTART, "sending REMAP"); + +- priv->mib_buf.type = MIB_MAC_MGMT; +- priv->mib_buf.size = 1; +- priv->mib_buf.index = offsetof(struct mib_mac_mgmt, ibss_change); +- priv->mib_buf.data.byte = 0; ++ /* no REMAP for 505A (see SF driver) */ ++ if (need_remap) { ++ ret = at76_remap(udev); ++ if (ret < 0) { ++ dev_printk(KERN_ERR, &udev->dev, ++ "sending REMAP failed with %d\n", ret); ++ goto exit; ++ } ++ } + +- ret = at76_set_mib(priv, &priv->mib_buf); +- if (ret < 0) +- printk(KERN_ERR "%s: set_mib (ibss change ok) failed: %d\n", +- priv->netdev->name, ret); ++ at76_dbg(DBG_DEVSTART, "sleeping for 2 seconds"); ++ schedule_timeout_interruptible(2 * HZ + 1); ++ usb_reset_device(udev); + + exit: +- mutex_unlock(&priv->mtx); ++ return ret; + } + + static int at76_startup_device(struct at76_priv *priv) +@@ -3905,14 +1470,14 @@ + + at76_dbg(DBG_PARAMS, + "%s param: ssid %.*s (%s) mode %s ch %d wep %s key %d " +- "keylen %d", priv->netdev->name, priv->essid_size, priv->essid, +- hex2str(priv->essid, IW_ESSID_MAX_SIZE), ++ "keylen %d", wiphy_name(priv->hw->wiphy), priv->essid_size, ++ priv->essid, hex2str(priv->essid, IW_ESSID_MAX_SIZE), + priv->iw_mode == IW_MODE_ADHOC ? "adhoc" : "infra", + priv->channel, priv->wep_enabled ? "enabled" : "disabled", + priv->wep_key_id, priv->wep_keys_len[priv->wep_key_id]); + at76_dbg(DBG_PARAMS, + "%s param: preamble %s rts %d retry %d frag %d " +- "txrate %s auth_mode %d", priv->netdev->name, ++ "txrate %s auth_mode %d", wiphy_name(priv->hw->wiphy), + preambles[priv->preamble_type], priv->rts_threshold, + priv->short_retry_limit, priv->frag_threshold, + priv->txrate == TX_RATE_1MBIT ? "1MBit" : priv->txrate == +@@ -3923,7 +1488,7 @@ + at76_dbg(DBG_PARAMS, + "%s param: pm_mode %d pm_period %d auth_mode %s " + "scan_times %d %d scan_mode %s", +- priv->netdev->name, priv->pm_mode, priv->pm_period, ++ wiphy_name(priv->hw->wiphy), priv->pm_mode, priv->pm_period, + priv->auth_mode == WLAN_AUTH_OPEN ? "open" : "shared_secret", + priv->scan_min_time, priv->scan_max_time, + priv->scan_mode == SCAN_TYPE_ACTIVE ? "active" : "passive"); +@@ -3957,7 +1522,8 @@ + ccfg->ssid_len = priv->essid_size; + + ccfg->wep_default_key_id = priv->wep_key_id; +- memcpy(ccfg->wep_default_key_value, priv->wep_keys, 4 * WEP_KEY_LEN); ++ memcpy(ccfg->wep_default_key_value, priv->wep_keys, ++ sizeof(priv->wep_keys)); + + ccfg->short_preamble = priv->preamble_type; + ccfg->beacon_period = cpu_to_le16(priv->beacon_period); +@@ -3966,7 +1532,7 @@ + sizeof(struct at76_card_config)); + if (ret < 0) { + printk(KERN_ERR "%s: at76_set_card_command failed: %d\n", +- priv->netdev->name, ret); ++ wiphy_name(priv->hw->wiphy), ret); + return ret; + } + +@@ -4012,69 +1578,6 @@ + return 0; + } + +-/* Restart the interface */ +-static void at76_dwork_restart(struct work_struct *work) +-{ +- struct at76_priv *priv = container_of(work, struct at76_priv, +- dwork_restart.work); +- +- mutex_lock(&priv->mtx); +- +- netif_carrier_off(priv->netdev); /* stop netdev watchdog */ +- netif_stop_queue(priv->netdev); /* stop tx data packets */ +- +- at76_startup_device(priv); +- +- if (priv->iw_mode != IW_MODE_MONITOR) { +- priv->netdev->type = ARPHRD_ETHER; +- at76_set_mac_state(priv, MAC_SCANNING); +- schedule_work(&priv->work_start_scan); +- } else { +- priv->netdev->type = ARPHRD_IEEE80211_RADIOTAP; +- at76_start_monitor(priv); +- } +- +- mutex_unlock(&priv->mtx); +-} +- +-/* Initiate scanning */ +-static void at76_work_start_scan(struct work_struct *work) +-{ +- struct at76_priv *priv = container_of(work, struct at76_priv, +- work_start_scan); +- int ret; +- +- mutex_lock(&priv->mtx); +- +- WARN_ON(priv->mac_state != MAC_SCANNING); +- if (priv->mac_state != MAC_SCANNING) +- goto exit; +- +- /* only clear the bss list when a scan is actively initiated, +- * otherwise simply rely on at76_bss_list_timeout */ +- if (priv->scan_state == SCAN_IN_PROGRESS) { +- at76_free_bss_list(priv); +- priv->scan_need_any = 1; +- } else +- priv->scan_need_any = 0; +- +- ret = at76_start_scan(priv, 1); +- +- if (ret < 0) +- printk(KERN_ERR "%s: %s: start_scan failed with %d\n", +- priv->netdev->name, __func__, ret); +- else { +- at76_dbg(DBG_MGMT_TIMER, +- "%s:%d: starting mgmt_timer for %d ticks", +- __func__, __LINE__, SCAN_POLL_INTERVAL); +- schedule_delayed_work(&priv->dwork_get_scan, +- SCAN_POLL_INTERVAL); +- } +- +-exit: +- mutex_unlock(&priv->mtx); +-} +- + /* Enable or disable promiscuous mode */ + static void at76_work_set_promisc(struct work_struct *work) + { +@@ -4092,7 +1595,7 @@ + ret = at76_set_mib(priv, &priv->mib_buf); + if (ret < 0) + printk(KERN_ERR "%s: set_mib (promiscuous_mode) failed: %d\n", +- priv->netdev->name, ret); ++ wiphy_name(priv->hw->wiphy), ret); + + mutex_unlock(&priv->mtx); + } +@@ -4108,1088 +1611,759 @@ + mutex_unlock(&priv->mtx); + } + +-/* We got an association response */ +-static void at76_rx_mgmt_assoc(struct at76_priv *priv, +- struct at76_rx_buffer *buf) +-{ +- struct ieee80211_assoc_response *resp = +- (struct ieee80211_assoc_response *)buf->packet; +- u16 assoc_id = le16_to_cpu(resp->aid); +- u16 status = le16_to_cpu(resp->status); +- +- at76_dbg(DBG_RX_MGMT, "%s: rx AssocResp bssid %s capa 0x%04x status " +- "0x%04x assoc_id 0x%04x rates %s", priv->netdev->name, +- mac2str(resp->header.addr3), le16_to_cpu(resp->capability), +- status, assoc_id, hex2str(resp->info_element->data, +- resp->info_element->len)); +- +- if (priv->mac_state != MAC_ASSOC) { +- printk(KERN_INFO "%s: AssocResp in state %s ignored\n", +- priv->netdev->name, mac_states[priv->mac_state]); ++static void at76_rx_tasklet(unsigned long param) ++{ ++ struct urb *urb = (struct urb *)param; ++ struct at76_priv *priv = urb->context; ++ struct at76_rx_buffer *buf; ++ struct ieee80211_rx_status rx_status = { 0 }; ++ ++ if (priv->device_unplugged) { ++ at76_dbg(DBG_DEVSTART, "device unplugged"); ++ if (urb) ++ at76_dbg(DBG_DEVSTART, "urb status %d", urb->status); + return; + } + +- BUG_ON(!priv->curr_bss); ++ if (!priv->rx_skb || !priv->rx_skb->data) ++ return; + +- cancel_delayed_work(&priv->dwork_assoc); +- if (status == WLAN_STATUS_SUCCESS) { +- struct bss_info *ptr = priv->curr_bss; +- priv->assoc_id = assoc_id & 0x3fff; +- /* update iwconfig params */ +- memcpy(priv->bssid, ptr->bssid, ETH_ALEN); +- memcpy(priv->essid, ptr->ssid, ptr->ssid_len); +- priv->essid_size = ptr->ssid_len; +- priv->channel = ptr->channel; +- schedule_work(&priv->work_assoc_done); +- } else { +- at76_set_mac_state(priv, MAC_JOINING); +- schedule_work(&priv->work_join); ++ buf = (struct at76_rx_buffer *)priv->rx_skb->data; ++ ++ if (urb->status != 0) { ++ if (urb->status != -ENOENT && urb->status != -ECONNRESET) ++ at76_dbg(DBG_URB, ++ "%s %s: - nonzero Rx bulk status received: %d", ++ __func__, wiphy_name(priv->hw->wiphy), ++ urb->status); ++ return; + } ++ ++ at76_dbg(DBG_RX_ATMEL_HDR, ++ "%s: rx frame: rate %d rssi %d noise %d link %d", ++ wiphy_name(priv->hw->wiphy), buf->rx_rate, buf->rssi, ++ buf->noise_level, buf->link_quality); ++ ++ skb_trim(priv->rx_skb, le16_to_cpu(buf->wlength) + AT76_RX_HDRLEN); ++ at76_dbg_dump(DBG_RX_DATA, &priv->rx_skb->data[AT76_RX_HDRLEN], ++ priv->rx_skb->len, "RX: len=%d", ++ (int)(priv->rx_skb->len - AT76_RX_HDRLEN)); ++ ++ rx_status.signal = buf->rssi; ++ /* FIXME: is rate_idx still present in structure? */ ++ rx_status.rate_idx = buf->rx_rate; ++ rx_status.flag |= RX_FLAG_DECRYPTED; ++ rx_status.flag |= RX_FLAG_IV_STRIPPED; ++ ++ skb_pull(priv->rx_skb, AT76_RX_HDRLEN); ++ at76_dbg(DBG_MAC80211, "calling ieee80211_rx_irqsafe(): %d/%d", ++ priv->rx_skb->len, priv->rx_skb->data_len); ++ ieee80211_rx_irqsafe(priv->hw, priv->rx_skb, &rx_status); ++ ++ /* Use a new skb for the next receive */ ++ priv->rx_skb = NULL; ++ ++ at76_submit_rx_urb(priv); + } + +-/* Process disassociation request from the AP */ +-static void at76_rx_mgmt_disassoc(struct at76_priv *priv, +- struct at76_rx_buffer *buf) ++/* Load firmware into kernel memory and parse it */ ++static struct fwentry *at76_load_firmware(struct usb_device *udev, ++ enum board_type board_type) + { +- struct ieee80211_disassoc *resp = +- (struct ieee80211_disassoc *)buf->packet; +- struct ieee80211_hdr_3addr *mgmt = &resp->header; ++ int ret; ++ char *str; ++ struct at76_fw_header *fwh; ++ struct fwentry *fwe = &firmwares[board_type]; + +- at76_dbg(DBG_RX_MGMT, +- "%s: rx DisAssoc bssid %s reason 0x%04x destination %s", +- priv->netdev->name, mac2str(mgmt->addr3), +- le16_to_cpu(resp->reason), mac2str(mgmt->addr1)); ++ mutex_lock(&fw_mutex); + +- /* We are not connected, ignore */ +- if (priv->mac_state == MAC_SCANNING || priv->mac_state == MAC_INIT +- || !priv->curr_bss) +- return; ++ if (fwe->loaded) { ++ at76_dbg(DBG_FW, "re-using previously loaded fw"); ++ goto exit; ++ } + +- /* Not our BSSID, ignore */ +- if (compare_ether_addr(mgmt->addr3, priv->curr_bss->bssid)) +- return; ++ at76_dbg(DBG_FW, "downloading firmware %s", fwe->fwname); ++ ret = request_firmware(&fwe->fw, fwe->fwname, &udev->dev); ++ if (ret < 0) { ++ dev_printk(KERN_ERR, &udev->dev, "firmware %s not found!\n", ++ fwe->fwname); ++ dev_printk(KERN_ERR, &udev->dev, ++ "you may need to download the firmware from " ++ "http://developer.berlios.de/projects/at76c503a/\n"); ++ goto exit; ++ } + +- /* Not for our STA and not broadcast, ignore */ +- if (compare_ether_addr(priv->netdev->dev_addr, mgmt->addr1) +- && !is_broadcast_ether_addr(mgmt->addr1)) +- return; ++ at76_dbg(DBG_FW, "got it."); ++ fwh = (struct at76_fw_header *)(fwe->fw->data); + +- if (priv->mac_state != MAC_ASSOC && priv->mac_state != MAC_CONNECTED +- && priv->mac_state != MAC_JOINING) { +- printk(KERN_INFO "%s: DisAssoc in state %s ignored\n", +- priv->netdev->name, mac_states[priv->mac_state]); +- return; ++ if (fwe->fw->size <= sizeof(*fwh)) { ++ dev_printk(KERN_ERR, &udev->dev, ++ "firmware is too short (0x%zx)\n", fwe->fw->size); ++ goto exit; + } + +- if (priv->mac_state == MAC_CONNECTED) { +- netif_carrier_off(priv->netdev); +- netif_stop_queue(priv->netdev); +- at76_iwevent_bss_disconnect(priv->netdev); +- } +- cancel_delayed_work(&priv->dwork_get_scan); +- cancel_delayed_work(&priv->dwork_beacon); +- cancel_delayed_work(&priv->dwork_auth); +- cancel_delayed_work(&priv->dwork_assoc); +- at76_set_mac_state(priv, MAC_JOINING); +- schedule_work(&priv->work_join); +-} +- +-static void at76_rx_mgmt_auth(struct at76_priv *priv, +- struct at76_rx_buffer *buf) +-{ +- struct ieee80211_auth *resp = (struct ieee80211_auth *)buf->packet; +- struct ieee80211_hdr_3addr *mgmt = &resp->header; +- int seq_nr = le16_to_cpu(resp->transaction); +- int alg = le16_to_cpu(resp->algorithm); +- int status = le16_to_cpu(resp->status); +- +- at76_dbg(DBG_RX_MGMT, +- "%s: rx AuthFrame bssid %s alg %d seq_nr %d status %d " +- "destination %s", priv->netdev->name, mac2str(mgmt->addr3), +- alg, seq_nr, status, mac2str(mgmt->addr1)); +- +- if (alg == WLAN_AUTH_SHARED_KEY && seq_nr == 2) +- at76_dbg(DBG_RX_MGMT, "%s: AuthFrame challenge %s ...", +- priv->netdev->name, hex2str(resp->info_element, 18)); +- +- if (priv->mac_state != MAC_AUTH) { +- printk(KERN_INFO "%s: ignored AuthFrame in state %s\n", +- priv->netdev->name, mac_states[priv->mac_state]); +- return; +- } +- if (priv->auth_mode != alg) { +- printk(KERN_INFO "%s: ignored AuthFrame for alg %d\n", +- priv->netdev->name, alg); +- return; ++ /* CRC currently not checked */ ++ fwe->board_type = le32_to_cpu(fwh->board_type); ++ if (fwe->board_type != board_type) { ++ dev_printk(KERN_ERR, &udev->dev, ++ "board type mismatch, requested %u, got %u\n", ++ board_type, fwe->board_type); ++ goto exit; + } + +- BUG_ON(!priv->curr_bss); ++ fwe->fw_version.major = fwh->major; ++ fwe->fw_version.minor = fwh->minor; ++ fwe->fw_version.patch = fwh->patch; ++ fwe->fw_version.build = fwh->build; + +- /* Not our BSSID or not for our STA, ignore */ +- if (compare_ether_addr(mgmt->addr3, priv->curr_bss->bssid) +- || compare_ether_addr(priv->netdev->dev_addr, mgmt->addr1)) +- return; ++ str = (char *)fwh + le32_to_cpu(fwh->str_offset); ++ fwe->intfw = (u8 *)fwh + le32_to_cpu(fwh->int_fw_offset); ++ fwe->intfw_size = le32_to_cpu(fwh->int_fw_len); ++ fwe->extfw = (u8 *)fwh + le32_to_cpu(fwh->ext_fw_offset); ++ fwe->extfw_size = le32_to_cpu(fwh->ext_fw_len); + +- cancel_delayed_work(&priv->dwork_auth); +- if (status != WLAN_STATUS_SUCCESS) { +- /* try to join next bss */ +- at76_set_mac_state(priv, MAC_JOINING); +- schedule_work(&priv->work_join); +- return; +- } ++ fwe->loaded = 1; + +- if (priv->auth_mode == WLAN_AUTH_OPEN || seq_nr == 4) { +- priv->retries = ASSOC_RETRIES; +- at76_set_mac_state(priv, MAC_ASSOC); +- at76_assoc_req(priv, priv->curr_bss); +- at76_dbg(DBG_MGMT_TIMER, +- "%s:%d: starting mgmt_timer + HZ", __func__, __LINE__); +- schedule_delayed_work(&priv->dwork_assoc, ASSOC_TIMEOUT); +- return; +- } ++ dev_printk(KERN_DEBUG, &udev->dev, ++ "using firmware %s (version %d.%d.%d-%d)\n", ++ fwe->fwname, fwh->major, fwh->minor, fwh->patch, fwh->build); + +- WARN_ON(seq_nr != 2); +- at76_auth_req(priv, priv->curr_bss, seq_nr + 1, resp->info_element); +- at76_dbg(DBG_MGMT_TIMER, "%s:%d: starting mgmt_timer + HZ", __func__, +- __LINE__); +- schedule_delayed_work(&priv->dwork_auth, AUTH_TIMEOUT); +-} +- +-static void at76_rx_mgmt_deauth(struct at76_priv *priv, +- struct at76_rx_buffer *buf) +-{ +- struct ieee80211_disassoc *resp = +- (struct ieee80211_disassoc *)buf->packet; +- struct ieee80211_hdr_3addr *mgmt = &resp->header; +- +- at76_dbg(DBG_RX_MGMT | DBG_PROGRESS, +- "%s: rx DeAuth bssid %s reason 0x%04x destination %s", +- priv->netdev->name, mac2str(mgmt->addr3), +- le16_to_cpu(resp->reason), mac2str(mgmt->addr1)); +- +- if (priv->mac_state != MAC_AUTH && priv->mac_state != MAC_ASSOC +- && priv->mac_state != MAC_CONNECTED) { +- printk(KERN_INFO "%s: DeAuth in state %s ignored\n", +- priv->netdev->name, mac_states[priv->mac_state]); +- return; +- } ++ at76_dbg(DBG_DEVSTART, "board %u, int %d:%d, ext %d:%d", board_type, ++ le32_to_cpu(fwh->int_fw_offset), le32_to_cpu(fwh->int_fw_len), ++ le32_to_cpu(fwh->ext_fw_offset), le32_to_cpu(fwh->ext_fw_len)); ++ at76_dbg(DBG_DEVSTART, "firmware id %s", str); + +- BUG_ON(!priv->curr_bss); ++exit: ++ mutex_unlock(&fw_mutex); + +- /* Not our BSSID, ignore */ +- if (compare_ether_addr(mgmt->addr3, priv->curr_bss->bssid)) +- return; ++ if (fwe->loaded) ++ return fwe; ++ else ++ return NULL; ++} + +- /* Not for our STA and not broadcast, ignore */ +- if (compare_ether_addr(priv->netdev->dev_addr, mgmt->addr1) +- && !is_broadcast_ether_addr(mgmt->addr1)) +- return; ++static void at76_mac80211_tx_callback(struct urb *urb) ++{ ++ struct at76_priv *priv = urb->context; ++ struct ieee80211_tx_info *info = IEEE80211_SKB_CB(priv->tx_skb); + +- if (priv->mac_state == MAC_CONNECTED) +- at76_iwevent_bss_disconnect(priv->netdev); ++ at76_dbg(DBG_MAC80211, "%s()", __func__); + +- at76_set_mac_state(priv, MAC_JOINING); +- schedule_work(&priv->work_join); +- cancel_delayed_work(&priv->dwork_get_scan); +- cancel_delayed_work(&priv->dwork_beacon); +- cancel_delayed_work(&priv->dwork_auth); +- cancel_delayed_work(&priv->dwork_assoc); +-} +- +-static void at76_rx_mgmt_beacon(struct at76_priv *priv, +- struct at76_rx_buffer *buf) +-{ +- int varpar_len; +- /* beacon content */ +- struct ieee80211_beacon *bdata = (struct ieee80211_beacon *)buf->packet; +- struct ieee80211_hdr_3addr *mgmt = &bdata->header; +- +- struct list_head *lptr; +- struct bss_info *match; /* entry matching addr3 with its bssid */ +- int new_entry = 0; +- int len; +- struct ieee80211_info_element *ie; +- int have_ssid = 0; +- int have_rates = 0; +- int have_channel = 0; +- int keep_going = 1; +- unsigned long flags; +- +- spin_lock_irqsave(&priv->bss_list_spinlock, flags); +- if (priv->mac_state == MAC_CONNECTED) { +- /* in state MAC_CONNECTED we use the mgmt_timer to control +- the beacon of the BSS */ +- BUG_ON(!priv->curr_bss); +- +- if (!compare_ether_addr(priv->curr_bss->bssid, mgmt->addr3)) { +- /* We got our AP's beacon, defer the timeout handler. +- Kill pending work first, as schedule_delayed_work() +- won't do it. */ +- cancel_delayed_work(&priv->dwork_beacon); +- schedule_delayed_work(&priv->dwork_beacon, +- BEACON_TIMEOUT); +- priv->curr_bss->rssi = buf->rssi; +- priv->beacons_received++; +- goto exit; +- } ++ switch (urb->status) { ++ case 0: ++ /* success */ ++ /* FIXME: ++ * is the frame really ACKed when tx_callback is called ? */ ++ info->flags |= IEEE80211_TX_STAT_ACK; ++ break; ++ case -ENOENT: ++ case -ECONNRESET: ++ /* fail, urb has been unlinked */ ++ /* FIXME: add error message */ ++ break; ++ default: ++ at76_dbg(DBG_URB, "%s - nonzero tx status received: %d", ++ __func__, urb->status); ++ break; + } + +- /* look if we have this BSS already in the list */ +- match = NULL; ++ memset(&info->status, 0, sizeof(info->status)); + +- if (!list_empty(&priv->bss_list)) { +- list_for_each(lptr, &priv->bss_list) { +- struct bss_info *bss_ptr = +- list_entry(lptr, struct bss_info, list); +- if (!compare_ether_addr(bss_ptr->bssid, mgmt->addr3)) { +- match = bss_ptr; +- break; +- } +- } ++ ieee80211_tx_status_irqsafe(priv->hw, priv->tx_skb); ++ ++ priv->tx_skb = NULL; ++ ++ ieee80211_wake_queues(priv->hw); ++} ++ ++static int at76_mac80211_tx(struct ieee80211_hw *hw, struct sk_buff *skb) ++{ ++ struct at76_priv *priv = hw->priv; ++ struct at76_tx_buffer *tx_buffer = priv->bulk_out_buffer; ++ struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb); ++ int padding, submit_len, ret; ++ ++ at76_dbg(DBG_MAC80211, "%s()", __func__); ++ ++ if (priv->tx_urb->status == -EINPROGRESS) { ++ printk(KERN_ERR "%s: %s called while tx urb is pending\n", ++ wiphy_name(priv->hw->wiphy), __func__); ++ return NETDEV_TX_BUSY; + } + +- if (!match) { +- /* BSS not in the list - append it */ +- match = kzalloc(sizeof(struct bss_info), GFP_ATOMIC); +- if (!match) { +- at76_dbg(DBG_BSS_TABLE, +- "%s: cannot kmalloc new bss info (%zd byte)", +- priv->netdev->name, sizeof(struct bss_info)); +- goto exit; +- } +- new_entry = 1; +- list_add_tail(&match->list, &priv->bss_list); ++ ieee80211_stop_queues(hw); ++ ++ at76_ledtrig_tx_activity(); /* tell ledtrigger we send a packet */ ++ ++ WARN_ON(priv->tx_skb != NULL); ++ ++ priv->tx_skb = skb; ++ padding = at76_calc_padding(skb->len); ++ submit_len = AT76_TX_HDRLEN + skb->len + padding; ++ ++ /* setup 'Atmel' header */ ++ memset(tx_buffer, 0, sizeof(*tx_buffer)); ++ tx_buffer->padding = padding; ++ tx_buffer->wlength = cpu_to_le16(skb->len); ++ tx_buffer->tx_rate = ieee80211_get_tx_rate(hw, info)->hw_value; ++ if (FIRMWARE_IS_WPA(priv->fw_version) && info->control.hw_key) { ++ tx_buffer->key_id = (info->control.hw_key->keyidx); ++ tx_buffer->cipher_type = ++ priv->keys[info->control.hw_key->keyidx].cipher; ++ tx_buffer->cipher_length = ++ priv->keys[info->control.hw_key->keyidx].keylen; ++ tx_buffer->reserved = 0; ++ } else { ++ tx_buffer->key_id = 0; ++ tx_buffer->cipher_type = 0; ++ tx_buffer->cipher_length = 0; ++ tx_buffer->reserved = 0; ++ }; ++ /* memset(tx_buffer->reserved, 0, sizeof(tx_buffer->reserved)); */ ++ memcpy(tx_buffer->packet, skb->data, skb->len); ++ ++ at76_dbg(DBG_TX_DATA, "%s tx: wlen 0x%x pad 0x%x rate %d hdr", ++ wiphy_name(priv->hw->wiphy), le16_to_cpu(tx_buffer->wlength), ++ tx_buffer->padding, tx_buffer->tx_rate); ++ ++ /* send stuff */ ++ at76_dbg_dump(DBG_TX_DATA_CONTENT, tx_buffer, submit_len, ++ "%s(): tx_buffer %d bytes:", __func__, submit_len); ++ usb_fill_bulk_urb(priv->tx_urb, priv->udev, priv->tx_pipe, tx_buffer, ++ submit_len, at76_mac80211_tx_callback, priv); ++ ret = usb_submit_urb(priv->tx_urb, GFP_ATOMIC); ++ if (ret) { ++ printk(KERN_ERR "%s: error in tx submit urb: %d\n", ++ wiphy_name(priv->hw->wiphy), ret); ++ if (ret == -EINVAL) ++ printk(KERN_ERR ++ "%s: -EINVAL: tx urb %p hcpriv %p complete %p\n", ++ wiphy_name(priv->hw->wiphy), priv->tx_urb, ++ priv->tx_urb->hcpriv, priv->tx_urb->complete); + } + +- match->capa = le16_to_cpu(bdata->capability); +- match->beacon_interval = le16_to_cpu(bdata->beacon_interval); +- match->rssi = buf->rssi; +- match->link_qual = buf->link_quality; +- match->noise_level = buf->noise_level; +- memcpy(match->bssid, mgmt->addr3, ETH_ALEN); +- at76_dbg(DBG_RX_BEACON, "%s: bssid %s", priv->netdev->name, +- mac2str(match->bssid)); +- +- ie = bdata->info_element; +- +- /* length of var length beacon parameters */ +- varpar_len = min_t(int, le16_to_cpu(buf->wlength) - +- sizeof(struct ieee80211_beacon), +- BEACON_MAX_DATA_LENGTH); +- +- /* This routine steps through the bdata->data array to get +- * some useful information about the access point. +- * Currently, this implementation supports receipt of: SSID, +- * supported transfer rates and channel, in any order, with some +- * tolerance for intermittent unknown codes (although this +- * functionality may not be necessary as the useful information will +- * usually arrive in consecutively, but there have been some +- * reports of some of the useful information fields arriving in a +- * different order). +- * It does not support any more IE types although MFIE_TYPE_TIM may +- * be supported (on my AP at least). +- * The bdata->data array is about 1500 bytes long but only ~36 of those +- * bytes are useful, hence the have_ssid etc optimizations. */ +- +- while (keep_going && +- ((&ie->data[ie->len] - (u8 *)bdata->info_element) <= +- varpar_len)) { ++ return 0; ++} + +- switch (ie->id) { ++static int at76_mac80211_start(struct ieee80211_hw *hw) ++{ ++ struct at76_priv *priv = hw->priv; ++ int ret; + +- case MFIE_TYPE_SSID: +- if (have_ssid) +- break; ++ at76_dbg(DBG_MAC80211, "%s()", __func__); + +- len = min_t(int, IW_ESSID_MAX_SIZE, ie->len); ++ mutex_lock(&priv->mtx); + +- /* we copy only if this is a new entry, +- or the incoming SSID is not a hidden SSID. This +- will protect us from overwriting a real SSID read +- in a ProbeResponse with a hidden one from a +- following beacon. */ +- if (!new_entry && at76_is_hidden_ssid(ie->data, len)) { +- have_ssid = 1; +- break; +- } ++ ret = at76_submit_rx_urb(priv); ++ if (ret < 0) { ++ printk(KERN_ERR "%s: open: submit_rx_urb failed: %d\n", ++ wiphy_name(priv->hw->wiphy), ret); ++ goto error; ++ } + +- match->ssid_len = len; +- memcpy(match->ssid, ie->data, len); +- at76_dbg(DBG_RX_BEACON, "%s: SSID - %.*s", +- priv->netdev->name, len, match->ssid); +- have_ssid = 1; +- break; ++ at76_startup_device(priv); + +- case MFIE_TYPE_RATES: +- if (have_rates) +- break; ++ at76_start_monitor(priv); + +- match->rates_len = +- min_t(int, sizeof(match->rates), ie->len); +- memcpy(match->rates, ie->data, match->rates_len); +- have_rates = 1; +- at76_dbg(DBG_RX_BEACON, "%s: SUPPORTED RATES %s", +- priv->netdev->name, +- hex2str(ie->data, ie->len)); +- break; ++error: ++ mutex_unlock(&priv->mtx); + +- case MFIE_TYPE_DS_SET: +- if (have_channel) +- break; ++ return 0; ++} + +- match->channel = ie->data[0]; +- have_channel = 1; +- at76_dbg(DBG_RX_BEACON, "%s: CHANNEL - %d", +- priv->netdev->name, match->channel); +- break; ++static void at76_mac80211_stop(struct ieee80211_hw *hw) ++{ ++ struct at76_priv *priv = hw->priv; + +- case MFIE_TYPE_CF_SET: +- case MFIE_TYPE_TIM: +- case MFIE_TYPE_IBSS_SET: +- default: +- at76_dbg(DBG_RX_BEACON, "%s: beacon IE id %d len %d %s", +- priv->netdev->name, ie->id, ie->len, +- hex2str(ie->data, ie->len)); +- break; +- } ++ at76_dbg(DBG_MAC80211, "%s()", __func__); + +- /* advance to the next informational element */ +- next_ie(&ie); ++ mutex_lock(&priv->mtx); ++ ++ if (!priv->device_unplugged) { ++ /* We are called by "ifconfig ethX down", not because the ++ * device is not available anymore. */ ++ if (at76_set_radio(priv, 0) == 1) ++ at76_wait_completion(priv, CMD_RADIO_ON); ++ ++ /* We unlink rx_urb because at76_open() re-submits it. ++ * If unplugged, at76_delete_device() takes care of it. */ ++ usb_kill_urb(priv->rx_urb); ++ } ++ ++ mutex_unlock(&priv->mtx); ++} ++ ++static int at76_add_interface(struct ieee80211_hw *hw, ++ struct ieee80211_if_init_conf *conf) ++{ ++ struct at76_priv *priv = hw->priv; ++ int ret = 0; + +- /* Optimization: after all, the bdata->data array is +- * varpar_len bytes long, whereas we get all of the useful +- * information after only ~36 bytes, this saves us a lot of +- * time (and trouble as the remaining portion of the array +- * could be full of junk) +- * Comment this out if you want to see what other information +- * comes from the AP - although little of it may be useful */ +- } ++ at76_dbg(DBG_MAC80211, "%s()", __func__); + +- at76_dbg(DBG_RX_BEACON, "%s: Finished processing beacon data", +- priv->netdev->name); ++ mutex_lock(&priv->mtx); + +- match->last_rx = jiffies; /* record last rx of beacon */ ++ switch (conf->type) { ++ case NL80211_IFTYPE_STATION: ++ priv->iw_mode = IW_MODE_INFRA; ++ break; ++ default: ++ ret = -EOPNOTSUPP; ++ goto exit; ++ } + + exit: +- spin_unlock_irqrestore(&priv->bss_list_spinlock, flags); ++ mutex_unlock(&priv->mtx); ++ ++ return ret; + } + +-/* Calculate the link level from a given rx_buffer */ +-static void at76_calc_level(struct at76_priv *priv, struct at76_rx_buffer *buf, +- struct iw_quality *qual) ++static void at76_remove_interface(struct ieee80211_hw *hw, ++ struct ieee80211_if_init_conf *conf) + { +- /* just a guess for now, might be different for other chips */ +- int max_rssi = 42; +- +- qual->level = (buf->rssi * 100 / max_rssi); +- if (qual->level > 100) +- qual->level = 100; +- qual->updated |= IW_QUAL_LEVEL_UPDATED; ++ at76_dbg(DBG_MAC80211, "%s()", __func__); + } + +-/* Calculate the link quality from a given rx_buffer */ +-static void at76_calc_qual(struct at76_priv *priv, struct at76_rx_buffer *buf, +- struct iw_quality *qual) ++static int at76_join(struct at76_priv *priv) + { +- if (at76_is_intersil(priv->board_type)) +- qual->qual = buf->link_quality; +- else { +- unsigned long elapsed; ++ struct at76_req_join join; ++ int ret; + +- /* Update qual at most once a second */ +- elapsed = jiffies - priv->beacons_last_qual; +- if (elapsed < 1 * HZ) +- return; ++ memset(&join, 0, sizeof(struct at76_req_join)); ++ memcpy(join.essid, priv->essid, priv->essid_size); ++ join.essid_size = priv->essid_size; ++ memcpy(join.bssid, priv->bssid, ETH_ALEN); ++ join.bss_type = INFRASTRUCTURE_MODE; ++ join.channel = priv->channel; ++ join.timeout = cpu_to_le16(2000); + +- qual->qual = qual->level * priv->beacons_received * +- msecs_to_jiffies(priv->beacon_period) / elapsed; ++ at76_dbg(DBG_MAC80211, "%s: sending CMD_JOIN", __func__); ++ ret = at76_set_card_command(priv->udev, CMD_JOIN, &join, ++ sizeof(struct at76_req_join)); + +- priv->beacons_last_qual = jiffies; +- priv->beacons_received = 0; ++ if (ret < 0) { ++ printk(KERN_ERR "%s: at76_set_card_command failed: %d\n", ++ wiphy_name(priv->hw->wiphy), ret); ++ return 0; + } +- qual->qual = (qual->qual > 100) ? 100 : qual->qual; +- qual->updated |= IW_QUAL_QUAL_UPDATED; +-} + +-/* Calculate the noise quality from a given rx_buffer */ +-static void at76_calc_noise(struct at76_priv *priv, struct at76_rx_buffer *buf, +- struct iw_quality *qual) +-{ +- qual->noise = 0; +- qual->updated |= IW_QUAL_NOISE_INVALID; +-} ++ ret = at76_wait_completion(priv, CMD_JOIN); ++ at76_dbg(DBG_MAC80211, "%s: CMD_JOIN returned: 0x%02x", __func__, ret); ++ if (ret != CMD_STATUS_COMPLETE) { ++ printk(KERN_ERR "%s: at76_wait_completion failed: %d\n", ++ wiphy_name(priv->hw->wiphy), ret); ++ return 0; ++ } + +-static void at76_update_wstats(struct at76_priv *priv, +- struct at76_rx_buffer *buf) +-{ +- struct iw_quality *qual = &priv->wstats.qual; ++ at76_set_tkip_bssid(priv, priv->bssid); ++ at76_set_pm_mode(priv); + +- if (buf->rssi && priv->mac_state == MAC_CONNECTED) { +- qual->updated = 0; +- at76_calc_level(priv, buf, qual); +- at76_calc_qual(priv, buf, qual); +- at76_calc_noise(priv, buf, qual); +- } else { +- qual->qual = 0; +- qual->level = 0; +- qual->noise = 0; +- qual->updated = IW_QUAL_ALL_INVALID; +- } ++ return 0; + } + +-static void at76_rx_mgmt(struct at76_priv *priv, struct at76_rx_buffer *buf) +-{ +- struct ieee80211_hdr_3addr *mgmt = +- (struct ieee80211_hdr_3addr *)buf->packet; +- u16 framectl = le16_to_cpu(mgmt->frame_ctl); +- +- /* update wstats */ +- if (priv->mac_state != MAC_INIT && priv->mac_state != MAC_SCANNING) { +- /* jal: this is a dirty hack needed by Tim in ad-hoc mode */ +- /* Data packets always seem to have a 0 link level, so we +- only read link quality info from management packets. +- Atmel driver actually averages the present, and previous +- values, we just present the raw value at the moment - TJS */ +- if (priv->iw_mode == IW_MODE_ADHOC +- || (priv->curr_bss +- && !compare_ether_addr(mgmt->addr3, +- priv->curr_bss->bssid))) +- at76_update_wstats(priv, buf); +- } +- +- at76_dbg(DBG_RX_MGMT_CONTENT, "%s rx mgmt framectl 0x%x %s", +- priv->netdev->name, framectl, +- hex2str(mgmt, le16_to_cpu(buf->wlength))); +- +- switch (framectl & IEEE80211_FCTL_STYPE) { +- case IEEE80211_STYPE_BEACON: +- case IEEE80211_STYPE_PROBE_RESP: +- at76_rx_mgmt_beacon(priv, buf); +- break; ++static void at76_dwork_hw_scan(struct work_struct *work) ++{ ++ struct at76_priv *priv = container_of(work, struct at76_priv, ++ dwork_hw_scan.work); ++ int ret; + +- case IEEE80211_STYPE_ASSOC_RESP: +- at76_rx_mgmt_assoc(priv, buf); +- break; ++ ret = at76_get_cmd_status(priv->udev, CMD_SCAN); ++ at76_dbg(DBG_MAC80211, "%s: CMD_SCAN status 0x%02x", __func__, ret); + +- case IEEE80211_STYPE_DISASSOC: +- at76_rx_mgmt_disassoc(priv, buf); +- break; ++ /* FIXME: add maximum time for scan to complete */ + +- case IEEE80211_STYPE_AUTH: +- at76_rx_mgmt_auth(priv, buf); +- break; ++ if (ret != CMD_STATUS_COMPLETE) { ++ queue_delayed_work(priv->hw->workqueue, &priv->dwork_hw_scan, ++ SCAN_POLL_INTERVAL); ++ goto exit; ++ } + +- case IEEE80211_STYPE_DEAUTH: +- at76_rx_mgmt_deauth(priv, buf); +- break; ++ ieee80211_scan_completed(priv->hw); + +- default: +- printk(KERN_DEBUG "%s: ignoring frame with framectl 0x%04x\n", +- priv->netdev->name, framectl); ++ if (is_valid_ether_addr(priv->bssid)) { ++ ieee80211_wake_queues(priv->hw); ++ at76_join(priv); + } + ++ ieee80211_wake_queues(priv->hw); ++ ++exit: + return; + } + +-/* Convert the 802.11 header into an ethernet-style header, make skb +- * ready for consumption by netif_rx() */ +-static void at76_ieee80211_to_eth(struct sk_buff *skb, int iw_mode) +-{ +- struct ieee80211_hdr_3addr *i802_11_hdr; +- struct ethhdr *eth_hdr_p; +- u8 *src_addr; +- u8 *dest_addr; +- +- i802_11_hdr = (struct ieee80211_hdr_3addr *)skb->data; +- +- /* That would be the ethernet header if the hardware converted +- * the frame for us. Make sure the source and the destination +- * match the 802.11 header. Which hardware does it? */ +- eth_hdr_p = (struct ethhdr *)skb_pull(skb, IEEE80211_3ADDR_LEN); +- +- dest_addr = i802_11_hdr->addr1; +- if (iw_mode == IW_MODE_ADHOC) +- src_addr = i802_11_hdr->addr2; +- else +- src_addr = i802_11_hdr->addr3; +- +- if (!compare_ether_addr(eth_hdr_p->h_source, src_addr) && +- !compare_ether_addr(eth_hdr_p->h_dest, dest_addr)) +- /* Yes, we already have an ethernet header */ +- skb_reset_mac_header(skb); +- else { +- u16 len; +- +- /* Need to build an ethernet header */ +- if (!memcmp(skb->data, snapsig, sizeof(snapsig))) { +- /* SNAP frame - decapsulate, keep proto */ +- skb_push(skb, offsetof(struct ethhdr, h_proto) - +- sizeof(rfc1042sig)); +- len = 0; +- } else { +- /* 802.3 frame, proto is length */ +- len = skb->len; +- skb_push(skb, ETH_HLEN); +- } +- +- skb_reset_mac_header(skb); +- eth_hdr_p = eth_hdr(skb); +- /* This needs to be done in this order (eth_hdr_p->h_dest may +- * overlap src_addr) */ +- memcpy(eth_hdr_p->h_source, src_addr, ETH_ALEN); +- memcpy(eth_hdr_p->h_dest, dest_addr, ETH_ALEN); +- if (len) +- eth_hdr_p->h_proto = htons(len); +- } +- +- skb->protocol = eth_type_trans(skb, skb->dev); +-} +- +-/* Check for fragmented data in priv->rx_skb. If the packet was no fragment +- or it was the last of a fragment set a skb containing the whole packet +- is returned for further processing. Otherwise we get NULL and are +- done and the packet is either stored inside the fragment buffer +- or thrown away. Every returned skb starts with the ieee802_11 header +- and contains _no_ FCS at the end */ +-static struct sk_buff *at76_check_for_rx_frags(struct at76_priv *priv) ++static int at76_hw_scan(struct ieee80211_hw *hw, u8 *ssid, size_t len) + { +- struct sk_buff *skb = priv->rx_skb; +- struct at76_rx_buffer *buf = (struct at76_rx_buffer *)skb->data; +- struct ieee80211_hdr_3addr *i802_11_hdr = +- (struct ieee80211_hdr_3addr *)buf->packet; +- /* seq_ctrl, fragment_number, sequence number of new packet */ +- u16 sctl = le16_to_cpu(i802_11_hdr->seq_ctl); +- u16 fragnr = sctl & 0xf; +- u16 seqnr = sctl >> 4; +- u16 frame_ctl = le16_to_cpu(i802_11_hdr->frame_ctl); +- +- /* Length including the IEEE802.11 header, but without the trailing +- * FCS and without the Atmel Rx header */ +- int length = le16_to_cpu(buf->wlength) - IEEE80211_FCS_LEN; +- +- /* where does the data payload start in skb->data ? */ +- u8 *data = i802_11_hdr->payload; +- +- /* length of payload, excl. the trailing FCS */ +- int data_len = length - IEEE80211_3ADDR_LEN; +- +- int i; +- struct rx_data_buf *bptr, *optr; +- unsigned long oldest = ~0UL; +- +- at76_dbg(DBG_RX_FRAGS, +- "%s: rx data frame_ctl %04x addr2 %s seq/frag %d/%d " +- "length %d data %d: %s ...", priv->netdev->name, frame_ctl, +- mac2str(i802_11_hdr->addr2), seqnr, fragnr, length, data_len, +- hex2str(data, 32)); +- +- at76_dbg(DBG_RX_FRAGS_SKB, "%s: incoming skb: head %p data %p " +- "tail %p end %p len %d", priv->netdev->name, skb->head, +- skb->data, skb_tail_pointer(skb), skb_end_pointer(skb), +- skb->len); +- +- if (data_len < 0) { +- /* make sure data starts in the buffer */ +- printk(KERN_INFO "%s: data frame too short\n", +- priv->netdev->name); +- return NULL; +- } +- +- WARN_ON(length <= AT76_RX_HDRLEN); +- if (length <= AT76_RX_HDRLEN) +- return NULL; ++ struct at76_priv *priv = hw->priv; ++ struct at76_req_scan scan; ++ int ret; + +- /* remove the at76_rx_buffer header - we don't need it anymore */ +- /* we need the IEEE802.11 header (for the addresses) if this packet +- is the first of a chain */ +- skb_pull(skb, AT76_RX_HDRLEN); +- +- /* remove FCS at end */ +- skb_trim(skb, length); +- +- at76_dbg(DBG_RX_FRAGS_SKB, "%s: trimmed skb: head %p data %p tail %p " +- "end %p len %d data %p data_len %d", priv->netdev->name, +- skb->head, skb->data, skb_tail_pointer(skb), +- skb_end_pointer(skb), skb->len, data, data_len); +- +- if (fragnr == 0 && !(frame_ctl & IEEE80211_FCTL_MOREFRAGS)) { +- /* unfragmented packet received */ +- /* Use a new skb for the next receive */ +- priv->rx_skb = NULL; +- at76_dbg(DBG_RX_FRAGS, "%s: unfragmented", priv->netdev->name); +- return skb; +- } +- +- /* look if we've got a chain for the sender address. +- afterwards optr points to first free or the oldest entry, +- or, if i < NR_RX_DATA_BUF, bptr points to the entry for the +- sender address */ +- /* determining the oldest entry doesn't cope with jiffies wrapping +- but I don't care to delete a young entry at these rare moments ... */ +- +- bptr = priv->rx_data; +- optr = NULL; +- for (i = 0; i < NR_RX_DATA_BUF; i++, bptr++) { +- if (!bptr->skb) { +- optr = bptr; +- oldest = 0UL; +- continue; +- } ++ at76_dbg(DBG_MAC80211, "%s():", __func__); ++ at76_dbg_dump(DBG_MAC80211, ssid, len, "ssid %zd bytes:", len); + +- if (!compare_ether_addr(i802_11_hdr->addr2, bptr->sender)) +- break; ++ mutex_lock(&priv->mtx); + +- if (!optr) { +- optr = bptr; +- oldest = bptr->last_rx; +- } else if (bptr->last_rx < oldest) +- optr = bptr; +- } +- +- if (i < NR_RX_DATA_BUF) { +- +- at76_dbg(DBG_RX_FRAGS, "%s: %d. cacheentry (seq/frag = %d/%d) " +- "matched sender addr", +- priv->netdev->name, i, bptr->seqnr, bptr->fragnr); +- +- /* bptr points to an entry for the sender address */ +- if (bptr->seqnr == seqnr) { +- int left; +- /* the fragment has the current sequence number */ +- if (((bptr->fragnr + 1) & 0xf) != fragnr) { +- /* wrong fragment number -> ignore it */ +- /* is & 0xf necessary above ??? */ +- at76_dbg(DBG_RX_FRAGS, +- "%s: frag nr mismatch: %d + 1 != %d", +- priv->netdev->name, bptr->fragnr, +- fragnr); +- return NULL; +- } +- bptr->last_rx = jiffies; +- /* the next following fragment number -> +- add the data at the end */ +- +- /* for test only ??? */ +- left = skb_tailroom(bptr->skb); +- if (left < data_len) +- printk(KERN_INFO +- "%s: only %d byte free (need %d)\n", +- priv->netdev->name, left, data_len); +- else +- memcpy(skb_put(bptr->skb, data_len), data, +- data_len); +- +- bptr->fragnr = fragnr; +- if (frame_ctl & IEEE80211_FCTL_MOREFRAGS) +- return NULL; +- +- /* this was the last fragment - send it */ +- skb = bptr->skb; +- bptr->skb = NULL; /* free the entry */ +- at76_dbg(DBG_RX_FRAGS, "%s: last frag of seq %d", +- priv->netdev->name, seqnr); +- return skb; +- } ++ ieee80211_stop_queues(hw); + +- /* got another sequence number */ +- if (fragnr == 0) { +- /* it's the start of a new chain - replace the +- old one by this */ +- /* bptr->sender has the correct value already */ +- at76_dbg(DBG_RX_FRAGS, +- "%s: start of new seq %d, removing old seq %d", +- priv->netdev->name, seqnr, bptr->seqnr); +- bptr->seqnr = seqnr; +- bptr->fragnr = 0; +- bptr->last_rx = jiffies; +- /* swap bptr->skb and priv->rx_skb */ +- skb = bptr->skb; +- bptr->skb = priv->rx_skb; +- priv->rx_skb = skb; +- } else { +- /* it from the middle of a new chain -> +- delete the old entry and skip the new one */ +- at76_dbg(DBG_RX_FRAGS, +- "%s: middle of new seq %d (%d) " +- "removing old seq %d", +- priv->netdev->name, seqnr, fragnr, +- bptr->seqnr); +- dev_kfree_skb(bptr->skb); +- bptr->skb = NULL; +- } +- return NULL; ++ memset(&scan, 0, sizeof(struct at76_req_scan)); ++ memset(scan.bssid, 0xFF, ETH_ALEN); ++ scan.scan_type = SCAN_TYPE_ACTIVE; ++ if (priv->essid_size > 0) { ++ memcpy(scan.essid, ssid, len); ++ scan.essid_size = len; + } ++ scan.min_channel_time = cpu_to_le16(priv->scan_min_time); ++ scan.max_channel_time = cpu_to_le16(priv->scan_max_time); ++ scan.probe_delay = cpu_to_le16(priv->scan_min_time * 1000); ++ scan.international_scan = 0; + +- /* if we didn't find a chain for the sender address, optr +- points either to the first free or the oldest entry */ ++ at76_dbg(DBG_MAC80211, "%s: sending CMD_SCAN", __func__); ++ ret = at76_set_card_command(priv->udev, CMD_SCAN, &scan, sizeof(scan)); + +- if (fragnr != 0) { +- /* this is not the begin of a fragment chain ... */ +- at76_dbg(DBG_RX_FRAGS, +- "%s: no chain for non-first fragment (%d)", +- priv->netdev->name, fragnr); +- return NULL; ++ if (ret < 0) { ++ err("CMD_SCAN failed: %d", ret); ++ goto exit; + } + +- BUG_ON(!optr); +- if (optr->skb) { +- /* swap the skb's */ +- skb = optr->skb; +- optr->skb = priv->rx_skb; +- priv->rx_skb = skb; +- +- at76_dbg(DBG_RX_FRAGS, +- "%s: free old contents: sender %s seq/frag %d/%d", +- priv->netdev->name, mac2str(optr->sender), +- optr->seqnr, optr->fragnr); ++ queue_delayed_work(priv->hw->workqueue, &priv->dwork_hw_scan, ++ SCAN_POLL_INTERVAL); + +- } else { +- /* take the skb from priv->rx_skb */ +- optr->skb = priv->rx_skb; +- /* let at76_submit_rx_urb() allocate a new skb */ +- priv->rx_skb = NULL; +- +- at76_dbg(DBG_RX_FRAGS, "%s: use a free entry", +- priv->netdev->name); +- } +- memcpy(optr->sender, i802_11_hdr->addr2, ETH_ALEN); +- optr->seqnr = seqnr; +- optr->fragnr = 0; +- optr->last_rx = jiffies; ++exit: ++ mutex_unlock(&priv->mtx); + +- return NULL; ++ return 0; + } + +-/* Rx interrupt: we expect the complete data buffer in priv->rx_skb */ +-static void at76_rx_data(struct at76_priv *priv) ++static int at76_config(struct ieee80211_hw *hw, u32 changed) + { +- struct net_device *netdev = priv->netdev; +- struct net_device_stats *stats = &priv->stats; +- struct sk_buff *skb = priv->rx_skb; +- struct at76_rx_buffer *buf = (struct at76_rx_buffer *)skb->data; +- struct ieee80211_hdr_3addr *i802_11_hdr; +- int length = le16_to_cpu(buf->wlength); +- +- at76_dbg(DBG_RX_DATA, "%s received data packet: %s", netdev->name, +- hex2str(skb->data, AT76_RX_HDRLEN)); ++ struct at76_priv *priv = hw->priv; ++ struct ieee80211_conf *conf = &hw->conf; + +- at76_dbg(DBG_RX_DATA_CONTENT, "rx packet: %s", +- hex2str(skb->data + AT76_RX_HDRLEN, length)); ++ at76_dbg(DBG_MAC80211, "%s(): channel %d radio %d", ++ __func__, conf->channel->hw_value, conf->radio_enabled); ++ at76_dbg_dump(DBG_MAC80211, priv->essid, priv->essid_size, "ssid:"); ++ at76_dbg_dump(DBG_MAC80211, priv->bssid, ETH_ALEN, "bssid:"); + +- skb = at76_check_for_rx_frags(priv); +- if (!skb) +- return; ++ mutex_lock(&priv->mtx); + +- /* Atmel header and the FCS are already removed */ +- i802_11_hdr = (struct ieee80211_hdr_3addr *)skb->data; ++ priv->channel = conf->channel->hw_value; + +- skb->dev = netdev; +- skb->ip_summed = CHECKSUM_NONE; /* TODO: should check CRC */ ++ if (is_valid_ether_addr(priv->bssid)) { ++ at76_join(priv); ++ ieee80211_wake_queues(priv->hw); ++ } else { ++ ieee80211_stop_queues(priv->hw); ++ at76_start_monitor(priv); ++ }; + +- if (is_broadcast_ether_addr(i802_11_hdr->addr1)) { +- if (!compare_ether_addr(i802_11_hdr->addr1, netdev->broadcast)) +- skb->pkt_type = PACKET_BROADCAST; +- else +- skb->pkt_type = PACKET_MULTICAST; +- } else if (compare_ether_addr(i802_11_hdr->addr1, netdev->dev_addr)) +- skb->pkt_type = PACKET_OTHERHOST; +- +- at76_ieee80211_to_eth(skb, priv->iw_mode); +- +- netdev->last_rx = jiffies; +- netif_rx(skb); +- stats->rx_packets++; +- stats->rx_bytes += length; ++ mutex_unlock(&priv->mtx); + +- return; ++ return 0; + } + +-static void at76_rx_monitor_mode(struct at76_priv *priv) ++static int at76_config_interface(struct ieee80211_hw *hw, ++ struct ieee80211_vif *vif, ++ struct ieee80211_if_conf *conf) + { +- struct at76_rx_radiotap *rt; +- u8 *payload; +- int skblen; +- struct net_device *netdev = priv->netdev; +- struct at76_rx_buffer *buf = +- (struct at76_rx_buffer *)priv->rx_skb->data; +- /* length including the IEEE802.11 header and the trailing FCS, +- but not at76_rx_buffer */ +- int length = le16_to_cpu(buf->wlength); +- struct sk_buff *skb = priv->rx_skb; +- struct net_device_stats *stats = &priv->stats; +- +- if (length < IEEE80211_FCS_LEN) { +- /* buffer contains no data */ +- at76_dbg(DBG_MONITOR_MODE, +- "%s: MONITOR MODE: rx skb without data", +- priv->netdev->name); +- return; +- } +- +- skblen = sizeof(struct at76_rx_radiotap) + length; ++ struct at76_priv *priv = hw->priv; + +- skb = dev_alloc_skb(skblen); +- if (!skb) { +- printk(KERN_ERR "%s: MONITOR MODE: dev_alloc_skb for radiotap " +- "header returned NULL\n", priv->netdev->name); +- return; +- } ++ at76_dbg_dump(DBG_MAC80211, conf->bssid, ETH_ALEN, "bssid:"); + +- skb_put(skb, skblen); ++ mutex_lock(&priv->mtx); + +- rt = (struct at76_rx_radiotap *)skb->data; +- payload = skb->data + sizeof(struct at76_rx_radiotap); ++ memcpy(priv->bssid, conf->bssid, ETH_ALEN); ++// memcpy(priv->essid, conf->ssid, conf->ssid_len); ++// priv->essid_size = conf->ssid_len; ++ ++ if (is_valid_ether_addr(priv->bssid)) { ++ /* mac80211 is joining a bss */ ++ ieee80211_wake_queues(priv->hw); ++ at76_join(priv); ++ } else ++ ieee80211_stop_queues(priv->hw); + +- rt->rt_hdr.it_version = 0; +- rt->rt_hdr.it_pad = 0; +- rt->rt_hdr.it_len = cpu_to_le16(sizeof(struct at76_rx_radiotap)); +- rt->rt_hdr.it_present = cpu_to_le32(AT76_RX_RADIOTAP_PRESENT); +- +- rt->rt_tsft = cpu_to_le64(le32_to_cpu(buf->rx_time)); +- rt->rt_rate = hw_rates[buf->rx_rate] & (~0x80); +- rt->rt_signal = buf->rssi; +- rt->rt_noise = buf->noise_level; +- rt->rt_flags = IEEE80211_RADIOTAP_F_FCS; +- if (buf->fragmentation) +- rt->rt_flags |= IEEE80211_RADIOTAP_F_FRAG; +- +- memcpy(payload, buf->packet, length); +- skb->dev = netdev; +- skb->ip_summed = CHECKSUM_NONE; +- skb_reset_mac_header(skb); +- skb->pkt_type = PACKET_OTHERHOST; +- skb->protocol = htons(ETH_P_802_2); +- +- netdev->last_rx = jiffies; +- netif_rx(skb); +- stats->rx_packets++; +- stats->rx_bytes += length; +-} +- +-/* Check if we spy on the sender address in buf and update stats */ +-static void at76_iwspy_update(struct at76_priv *priv, +- struct at76_rx_buffer *buf) +-{ +- struct ieee80211_hdr_3addr *hdr = +- (struct ieee80211_hdr_3addr *)buf->packet; +- struct iw_quality qual; +- +- /* We can only set the level here */ +- qual.updated = IW_QUAL_QUAL_INVALID | IW_QUAL_NOISE_INVALID; +- qual.level = 0; +- qual.noise = 0; +- at76_calc_level(priv, buf, &qual); ++ mutex_unlock(&priv->mtx); + +- spin_lock_bh(&priv->spy_spinlock); ++ return 0; ++} + +- if (priv->spy_data.spy_number > 0) +- wireless_spy_update(priv->netdev, hdr->addr2, &qual); ++/* must be atomic */ ++static void at76_configure_filter(struct ieee80211_hw *hw, ++ unsigned int changed_flags, ++ unsigned int *total_flags, int mc_count, ++ struct dev_addr_list *mc_list) ++{ ++ struct at76_priv *priv = hw->priv; ++ int flags; ++ ++ at76_dbg(DBG_MAC80211, "%s(): changed_flags=0x%08x " ++ "total_flags=0x%08x mc_count=%d", ++ __func__, changed_flags, *total_flags, mc_count); ++ ++ flags = changed_flags & AT76_SUPPORTED_FILTERS; ++ *total_flags = AT76_SUPPORTED_FILTERS; ++ ++ /* FIXME: access to priv->promisc should be protected with ++ * priv->mtx, but it's impossible because this function needs to be ++ * atomic */ ++ ++ if (flags && !priv->promisc) { ++ /* mac80211 wants us to enable promiscuous mode */ ++ priv->promisc = 1; ++ } else if (!flags && priv->promisc) { ++ /* we need to disable promiscuous mode */ ++ priv->promisc = 0; ++ } else ++ return; + +- spin_unlock_bh(&priv->spy_spinlock); ++ queue_work(hw->workqueue, &priv->work_set_promisc); + } + +-static void at76_rx_tasklet(unsigned long param) ++static int at76_set_key_oldfw(struct ieee80211_hw *hw, enum set_key_cmd cmd, ++ const u8 *local_address, const u8 *address, ++ struct ieee80211_key_conf *key) + { +- struct urb *urb = (struct urb *)param; +- struct at76_priv *priv = urb->context; +- struct net_device *netdev = priv->netdev; +- struct at76_rx_buffer *buf; +- struct ieee80211_hdr_3addr *i802_11_hdr; +- u16 frame_ctl; +- +- if (priv->device_unplugged) { +- at76_dbg(DBG_DEVSTART, "device unplugged"); +- if (urb) +- at76_dbg(DBG_DEVSTART, "urb status %d", urb->status); +- return; +- } ++ struct at76_priv *priv = hw->priv; + +- if (!priv->rx_skb || !netdev || !priv->rx_skb->data) +- return; ++ int i; + +- buf = (struct at76_rx_buffer *)priv->rx_skb->data; ++ at76_dbg(DBG_MAC80211, "%s(): cmd %d key->alg %d key->keyidx %d " ++ "key->keylen %d", ++ __func__, cmd, key->alg, key->keyidx, key->keylen); + +- i802_11_hdr = (struct ieee80211_hdr_3addr *)buf->packet; ++ if (key->alg != ALG_WEP) ++ return -EOPNOTSUPP; + +- frame_ctl = le16_to_cpu(i802_11_hdr->frame_ctl); ++ key->hw_key_idx = key->keyidx; + +- if (urb->status != 0) { +- if (urb->status != -ENOENT && urb->status != -ECONNRESET) +- at76_dbg(DBG_URB, +- "%s %s: - nonzero Rx bulk status received: %d", +- __func__, netdev->name, urb->status); +- return; +- } ++ mutex_lock(&priv->mtx); + +- at76_dbg(DBG_RX_ATMEL_HDR, +- "%s: rx frame: rate %d rssi %d noise %d link %d %s", +- priv->netdev->name, buf->rx_rate, buf->rssi, buf->noise_level, +- buf->link_quality, hex2str(i802_11_hdr, 48)); +- if (priv->iw_mode == IW_MODE_MONITOR) { +- at76_rx_monitor_mode(priv); +- goto exit; +- } ++ switch (cmd) { ++ case SET_KEY: ++ memcpy(priv->wep_keys[key->keyidx], key->key, key->keylen); ++ priv->wep_keys_len[key->keyidx] = key->keylen; + +- /* there is a new bssid around, accept it: */ +- if (buf->newbss && priv->iw_mode == IW_MODE_ADHOC) { +- at76_dbg(DBG_PROGRESS, "%s: rx newbss", netdev->name); +- schedule_work(&priv->work_new_bss); +- } ++ /* FIXME: find out how to do this properly */ ++ priv->wep_key_id = key->keyidx; + +- switch (frame_ctl & IEEE80211_FCTL_FTYPE) { +- case IEEE80211_FTYPE_DATA: +- at76_rx_data(priv); + break; ++ case DISABLE_KEY: ++ default: ++ priv->wep_keys_len[key->keyidx] = 0; ++ break; ++ } + +- case IEEE80211_FTYPE_MGMT: +- /* jal: TODO: find out if we can update iwspy also on +- other frames than management (might depend on the +- radio chip / firmware version !) */ ++ priv->wep_enabled = 0; + +- at76_iwspy_update(priv, buf); ++ for (i = 0; i < WEP_KEYS; i++) { ++ if (priv->wep_keys_len[i] != 0) ++ priv->wep_enabled = 1; ++ } + +- at76_rx_mgmt(priv, buf); +- break; ++ at76_startup_device(priv); + +- case IEEE80211_FTYPE_CTL: +- at76_dbg(DBG_RX_CTRL, "%s: ignored ctrl frame: %04x", +- priv->netdev->name, frame_ctl); +- break; ++ mutex_unlock(&priv->mtx); + +- default: +- printk(KERN_DEBUG "%s: ignoring frame with framectl 0x%04x\n", +- priv->netdev->name, frame_ctl); +- } +-exit: +- at76_submit_rx_urb(priv); ++ return 0; + } + +-/* Load firmware into kernel memory and parse it */ +-static struct fwentry *at76_load_firmware(struct usb_device *udev, +- enum board_type board_type) +-{ +- int ret; +- char *str; +- struct at76_fw_header *fwh; +- struct fwentry *fwe = &firmwares[board_type]; ++static int at76_set_key_newfw(struct ieee80211_hw *hw, enum set_key_cmd cmd, ++ const u8 *local_address, const u8 *address, ++ struct ieee80211_key_conf *key) ++{ ++ struct at76_priv *priv = hw->priv; ++ int ret = -EOPNOTSUPP; ++ ++ at76_dbg(DBG_MAC80211, "%s(): cmd %d key->alg %d key->keyidx %d " ++ "key->keylen %d", ++ __func__, cmd, key->alg, key->keyidx, key->keylen); + +- mutex_lock(&fw_mutex); ++ mutex_lock(&priv->mtx); + +- if (fwe->loaded) { +- at76_dbg(DBG_FW, "re-using previously loaded fw"); +- goto exit; +- } ++ priv->mib_buf.type = MIB_MAC_ENCRYPTION; + +- at76_dbg(DBG_FW, "downloading firmware %s", fwe->fwname); +- ret = request_firmware(&fwe->fw, fwe->fwname, &udev->dev); +- if (ret < 0) { +- dev_printk(KERN_ERR, &udev->dev, "firmware %s not found!\n", +- fwe->fwname); +- dev_printk(KERN_ERR, &udev->dev, +- "you may need to download the firmware from " +- "http://developer.berlios.de/projects/at76c503a/"); ++ if (cmd == DISABLE_KEY) { ++ priv->mib_buf.size = CIPHER_KEY_LEN; ++ priv->mib_buf.index = offsetof(struct mib_mac_encryption, ++ cipher_default_keyvalue[key->keyidx]); ++ memset(priv->mib_buf.data.data, 0, CIPHER_KEY_LEN); ++ if (at76_set_mib(priv, &priv->mib_buf) != CMD_STATUS_COMPLETE) ++ ret = -EOPNOTSUPP; /* -EIO would be probably better */ ++ else { ++ ++ priv->keys[key->keyidx].cipher = CIPHER_NONE; ++ priv->keys[key->keyidx].keylen = 0; ++ }; ++ if (priv->default_group_key == key->keyidx) ++ priv->default_group_key = 0xff; ++ ++ if (priv->default_pairwise_key == key->keyidx) ++ priv->default_pairwise_key = 0xff; ++ /* If default pairwise key is removed, fall back to ++ * group key? */ ++ ret = 0; + goto exit; +- } ++ }; + +- at76_dbg(DBG_FW, "got it."); +- fwh = (struct at76_fw_header *)(fwe->fw->data); ++ if (cmd == SET_KEY) { ++ /* store key into MIB */ ++ priv->mib_buf.size = CIPHER_KEY_LEN; ++ priv->mib_buf.index = offsetof(struct mib_mac_encryption, ++ cipher_default_keyvalue[key->keyidx]); ++ memset(priv->mib_buf.data.data, 0, CIPHER_KEY_LEN); ++ memcpy(priv->mib_buf.data.data, key->key, key->keylen); ++ ++ switch (key->alg) { ++ case ALG_WEP: ++ if (key->keylen == 5) { ++ priv->keys[key->keyidx].cipher = ++ CIPHER_WEP64; ++ priv->keys[key->keyidx].keylen = 8; ++ } else if (key->keylen == 13) { ++ priv->keys[key->keyidx].cipher = ++ CIPHER_WEP128; ++ /* Firmware needs this */ ++ priv->keys[key->keyidx].keylen = 8; ++ } else { ++ ret = -EOPNOTSUPP; ++ goto exit; ++ }; ++ break; ++ case ALG_TKIP: ++ key->flags |= IEEE80211_KEY_FLAG_GENERATE_MMIC; ++ priv->keys[key->keyidx].cipher = CIPHER_TKIP; ++ priv->keys[key->keyidx].keylen = 12; ++ break; + +- if (fwe->fw->size <= sizeof(*fwh)) { +- dev_printk(KERN_ERR, &udev->dev, +- "firmware is too short (0x%zx)\n", fwe->fw->size); +- goto exit; +- } ++ case ALG_CCMP: ++ if (!at76_is_505a(priv->board_type)) { ++ ret = -EOPNOTSUPP; ++ goto exit; ++ }; ++ key->flags |= IEEE80211_KEY_FLAG_GENERATE_MMIC; ++ priv->keys[key->keyidx].cipher = CIPHER_CCMP; ++ priv->keys[key->keyidx].keylen = 16; ++ break; + +- /* CRC currently not checked */ +- fwe->board_type = le32_to_cpu(fwh->board_type); +- if (fwe->board_type != board_type) { +- dev_printk(KERN_ERR, &udev->dev, +- "board type mismatch, requested %u, got %u\n", +- board_type, fwe->board_type); +- goto exit; +- } ++ default: ++ ret = -EOPNOTSUPP; ++ goto exit; ++ }; + +- fwe->fw_version.major = fwh->major; +- fwe->fw_version.minor = fwh->minor; +- fwe->fw_version.patch = fwh->patch; +- fwe->fw_version.build = fwh->build; ++ priv->mib_buf.data.data[38] = priv->keys[key->keyidx].cipher; ++ priv->mib_buf.data.data[39] = 1; /* Taken from atmelwlandriver, ++ not documented */ ++ ++ if (is_valid_ether_addr(address)) ++ /* Pairwise key */ ++ priv->mib_buf.data.data[39] |= (KEY_PAIRWISE | KEY_TX); ++ else if (is_broadcast_ether_addr(address)) ++ /* Group key */ ++ priv->mib_buf.data.data[39] |= (KEY_TX); ++ else /* Key used only for transmission ??? */ ++ priv->mib_buf.data.data[39] |= (KEY_TX); ++ ++ if (at76_set_mib(priv, &priv->mib_buf) != ++ CMD_STATUS_COMPLETE) { ++ ret = -EOPNOTSUPP; /* -EIO would be probably better */ ++ goto exit; ++ }; + +- str = (char *)fwh + le32_to_cpu(fwh->str_offset); +- fwe->intfw = (u8 *)fwh + le32_to_cpu(fwh->int_fw_offset); +- fwe->intfw_size = le32_to_cpu(fwh->int_fw_len); +- fwe->extfw = (u8 *)fwh + le32_to_cpu(fwh->ext_fw_offset); +- fwe->extfw_size = le32_to_cpu(fwh->ext_fw_len); ++ if ((key->alg == ALG_TKIP) || (key->alg == ALG_CCMP)) ++ at76_reset_rsc(priv); + +- fwe->loaded = 1; ++ key->hw_key_idx = key->keyidx; + +- dev_printk(KERN_DEBUG, &udev->dev, +- "using firmware %s (version %d.%d.%d-%d)\n", +- fwe->fwname, fwh->major, fwh->minor, fwh->patch, fwh->build); ++ /* Set up default keys */ ++ if (is_broadcast_ether_addr(address)) ++ priv->default_group_key = key->keyidx; ++ if (is_valid_ether_addr(address)) ++ priv->default_pairwise_key = key->keyidx; ++ ++ /* Set up encryption MIBs */ ++ ++ /* first block of settings */ ++ priv->mib_buf.size = 3; ++ priv->mib_buf.index = offsetof(struct mib_mac_encryption, ++ privacy_invoked); ++ priv->mib_buf.data.data[0] = 1; /* privacy_invoked */ ++ priv->mib_buf.data.data[1] = priv->default_pairwise_key; ++ priv->mib_buf.data.data[2] = priv->default_group_key; + +- at76_dbg(DBG_DEVSTART, "board %u, int %d:%d, ext %d:%d", board_type, +- le32_to_cpu(fwh->int_fw_offset), le32_to_cpu(fwh->int_fw_len), +- le32_to_cpu(fwh->ext_fw_offset), le32_to_cpu(fwh->ext_fw_len)); +- at76_dbg(DBG_DEVSTART, "firmware id %s", str); ++ ret = at76_set_mib(priv, &priv->mib_buf); ++ if (ret != CMD_STATUS_COMPLETE) ++ goto exit; ++ ++ /* second block of settings */ ++ priv->mib_buf.size = 3; ++ priv->mib_buf.index = offsetof(struct mib_mac_encryption, ++ exclude_unencrypted); ++ priv->mib_buf.data.data[0] = 1; /* exclude_unencrypted */ ++ priv->mib_buf.data.data[1] = 0; /* wep_encryption_type */ ++ priv->mib_buf.data.data[2] = 0; /* ckip_key_permutation */ + ++ ret = at76_set_mib(priv, &priv->mib_buf); ++ if (ret != CMD_STATUS_COMPLETE) ++ goto exit; ++ ret = 0; ++ }; + exit: +- mutex_unlock(&fw_mutex); ++ at76_dump_mib_mac_encryption(priv); ++ mutex_unlock(&priv->mtx); ++ return ret; ++} + +- if (fwe->loaded) +- return fwe; ++static int at76_set_key(struct ieee80211_hw *hw, enum set_key_cmd cmd, ++ const u8 *local_address, const u8 *address, ++ struct ieee80211_key_conf *key) ++{ ++ struct at76_priv *priv = hw->priv; ++ ++ at76_dbg(DBG_MAC80211, "%s(): cmd %d key->alg %d key->keyidx %d " ++ "key->keylen %d", ++ __func__, cmd, key->alg, key->keyidx, key->keylen); ++ ++ if (FIRMWARE_IS_WPA(priv->fw_version)) ++ return at76_set_key_newfw(hw, cmd, local_address, address, key); + else +- return NULL; ++ return at76_set_key_oldfw(hw, cmd, local_address, address, key); ++ + } + ++static const struct ieee80211_ops at76_ops = { ++ .tx = at76_mac80211_tx, ++ .add_interface = at76_add_interface, ++ .remove_interface = at76_remove_interface, ++ .config = at76_config, ++ .config_interface = at76_config_interface, ++ .configure_filter = at76_configure_filter, ++ .start = at76_mac80211_start, ++ .stop = at76_mac80211_stop, ++ .hw_scan = at76_hw_scan, ++ .set_key = at76_set_key, ++}; ++ + /* Allocate network device and initialize private data */ + static struct at76_priv *at76_alloc_new_device(struct usb_device *udev) + { +- struct net_device *netdev; ++ struct ieee80211_hw *hw; + struct at76_priv *priv; +- int i; + +- /* allocate memory for our device state and initialize it */ +- netdev = alloc_etherdev(sizeof(struct at76_priv)); +- if (!netdev) { +- dev_printk(KERN_ERR, &udev->dev, "out of memory\n"); ++ hw = ieee80211_alloc_hw(sizeof(struct at76_priv), &at76_ops); ++ if (!hw) { ++ printk(KERN_ERR DRIVER_NAME ": could not register" ++ " ieee80211_hw\n"); + return NULL; + } + +- priv = netdev_priv(netdev); ++ priv = hw->priv; ++ priv->hw = hw; + + priv->udev = udev; +- priv->netdev = netdev; + + mutex_init(&priv->mtx); +- INIT_WORK(&priv->work_assoc_done, at76_work_assoc_done); +- INIT_WORK(&priv->work_join, at76_work_join); +- INIT_WORK(&priv->work_new_bss, at76_work_new_bss); +- INIT_WORK(&priv->work_start_scan, at76_work_start_scan); + INIT_WORK(&priv->work_set_promisc, at76_work_set_promisc); + INIT_WORK(&priv->work_submit_rx, at76_work_submit_rx); +- INIT_DELAYED_WORK(&priv->dwork_restart, at76_dwork_restart); +- INIT_DELAYED_WORK(&priv->dwork_get_scan, at76_dwork_get_scan); +- INIT_DELAYED_WORK(&priv->dwork_beacon, at76_dwork_beacon); +- INIT_DELAYED_WORK(&priv->dwork_auth, at76_dwork_auth); +- INIT_DELAYED_WORK(&priv->dwork_assoc, at76_dwork_assoc); +- +- spin_lock_init(&priv->mgmt_spinlock); +- priv->next_mgmt_bulk = NULL; +- priv->mac_state = MAC_INIT; +- +- /* initialize empty BSS list */ +- priv->curr_bss = NULL; +- INIT_LIST_HEAD(&priv->bss_list); +- spin_lock_init(&priv->bss_list_spinlock); +- +- init_timer(&priv->bss_list_timer); +- priv->bss_list_timer.data = (unsigned long)priv; +- priv->bss_list_timer.function = at76_bss_list_timeout; +- +- spin_lock_init(&priv->spy_spinlock); +- +- /* mark all rx data entries as unused */ +- for (i = 0; i < NR_RX_DATA_BUF; i++) +- priv->rx_data[i].skb = NULL; ++ INIT_DELAYED_WORK(&priv->dwork_hw_scan, at76_dwork_hw_scan); + + priv->rx_tasklet.func = at76_rx_tasklet; + priv->rx_tasklet.data = 0; +@@ -5197,6 +2371,9 @@ + priv->pm_mode = AT76_PM_OFF; + priv->pm_period = 0; + ++ /* unit us */ ++ priv->hw->channel_change_time = 100000; ++ + return priv; + } + +@@ -5259,11 +2436,42 @@ + return 0; + } + ++static struct ieee80211_rate at76_rates[] = { ++ { .bitrate = 10, .hw_value = TX_RATE_1MBIT, }, ++ { .bitrate = 20, .hw_value = TX_RATE_2MBIT, }, ++ { .bitrate = 55, .hw_value = TX_RATE_5_5MBIT, }, ++ { .bitrate = 110, .hw_value = TX_RATE_11MBIT, }, ++}; ++ ++static struct ieee80211_channel at76_channels[] = { ++ { .center_freq = 2412, .hw_value = 1 }, ++ { .center_freq = 2417, .hw_value = 2 }, ++ { .center_freq = 2422, .hw_value = 3 }, ++ { .center_freq = 2427, .hw_value = 4 }, ++ { .center_freq = 2432, .hw_value = 5 }, ++ { .center_freq = 2437, .hw_value = 6 }, ++ { .center_freq = 2442, .hw_value = 7 }, ++ { .center_freq = 2447, .hw_value = 8 }, ++ { .center_freq = 2452, .hw_value = 9 }, ++ { .center_freq = 2457, .hw_value = 10 }, ++ { .center_freq = 2462, .hw_value = 11 }, ++ { .center_freq = 2467, .hw_value = 12 }, ++ { .center_freq = 2472, .hw_value = 13 }, ++ { .center_freq = 2484, .hw_value = 14 } ++}; ++ ++static struct ieee80211_supported_band at76_supported_band = { ++ .channels = at76_channels, ++ .n_channels = ARRAY_SIZE(at76_channels), ++ .bitrates = at76_rates, ++ .n_bitrates = ARRAY_SIZE(at76_rates), ++}; ++ + /* Register network device and initialize the hardware */ + static int at76_init_new_device(struct at76_priv *priv, + struct usb_interface *interface) + { +- struct net_device *netdev = priv->netdev; ++ struct device *dev = &interface->dev; + int ret; + + /* set up the endpoint information */ +@@ -5279,14 +2487,11 @@ + /* MAC address */ + ret = at76_get_hw_config(priv); + if (ret < 0) { +- dev_printk(KERN_ERR, &interface->dev, +- "cannot get MAC address\n"); ++ dev_err(dev, "cannot get MAC address\n"); + goto exit; + } + + priv->domain = at76_get_reg_domain(priv->regulatory_domain); +- /* init. netdev->dev_addr */ +- memcpy(netdev->dev_addr, priv->mac_addr, ETH_ALEN); + + priv->channel = DEF_CHANNEL; + priv->iw_mode = IW_MODE_INFRA; +@@ -5296,47 +2501,54 @@ + priv->txrate = TX_RATE_AUTO; + priv->preamble_type = PREAMBLE_TYPE_LONG; + priv->beacon_period = 100; +- priv->beacons_last_qual = jiffies; + priv->auth_mode = WLAN_AUTH_OPEN; + priv->scan_min_time = DEF_SCAN_MIN_TIME; + priv->scan_max_time = DEF_SCAN_MAX_TIME; + priv->scan_mode = SCAN_TYPE_ACTIVE; ++ priv->default_pairwise_key = 0xff; ++ priv->default_group_key = 0xff; ++ ++ /* mac80211 initialisation */ ++ priv->hw->wiphy->bands[IEEE80211_BAND_2GHZ] = &at76_supported_band; ++ ++ if (FIRMWARE_IS_WPA(priv->fw_version) && ++ (at76_is_503rfmd(priv->board_type) || ++ at76_is_505(priv->board_type))) ++ priv->hw->flags = IEEE80211_HW_SIGNAL_UNSPEC; ++ else ++ priv->hw->flags = IEEE80211_HW_RX_INCLUDES_FCS | ++ IEEE80211_HW_SIGNAL_UNSPEC; + +- netdev->flags &= ~IFF_MULTICAST; /* not yet or never */ +- netdev->open = at76_open; +- netdev->stop = at76_stop; +- netdev->get_stats = at76_get_stats; +- netdev->ethtool_ops = &at76_ethtool_ops; +- +- /* Add pointers to enable iwspy support. */ +- priv->wireless_data.spy_data = &priv->spy_data; +- netdev->wireless_data = &priv->wireless_data; +- +- netdev->hard_start_xmit = at76_tx; +- netdev->tx_timeout = at76_tx_timeout; +- netdev->watchdog_timeo = 2 * HZ; +- netdev->wireless_handlers = &at76_handler_def; +- netdev->set_multicast_list = at76_set_multicast; +- netdev->set_mac_address = at76_set_mac_address; +- dev_alloc_name(netdev, "wlan%d"); ++ priv->hw->wiphy->interface_modes = BIT(NL80211_IFTYPE_STATION); + +- ret = register_netdev(priv->netdev); ++ SET_IEEE80211_DEV(priv->hw, &interface->dev); ++ SET_IEEE80211_PERM_ADDR(priv->hw, priv->mac_addr); ++ ++ ret = ieee80211_register_hw(priv->hw); + if (ret) { +- dev_printk(KERN_ERR, &interface->dev, +- "cannot register netdevice (status %d)!\n", ret); ++ dev_err(dev, "cannot register mac80211 hw (status %d)!\n", ret); + goto exit; + } +- priv->netdev_registered = 1; + +- printk(KERN_INFO "%s: USB %s, MAC %s, firmware %d.%d.%d-%d\n", +- netdev->name, dev_name(&interface->dev), mac2str(priv->mac_addr), +- priv->fw_version.major, priv->fw_version.minor, +- priv->fw_version.patch, priv->fw_version.build); +- printk(KERN_INFO "%s: regulatory domain 0x%02x: %s\n", netdev->name, +- priv->regulatory_domain, priv->domain->name); ++ priv->mac80211_registered = 1; + +- /* we let this timer run the whole time this driver instance lives */ +- mod_timer(&priv->bss_list_timer, jiffies + BSS_LIST_TIMEOUT); ++ dev_info(dev, "%s: USB %s, MAC %s, firmware %d.%d.%d-%d\n", ++ wiphy_name(priv->hw->wiphy), ++ dev_name(&interface->dev), mac2str(priv->mac_addr), ++ priv->fw_version.major, priv->fw_version.minor, ++ priv->fw_version.patch, priv->fw_version.build); ++ dev_info(dev, "%s: regulatory domain 0x%02x: %s\n", ++ wiphy_name(priv->hw->wiphy), ++ priv->regulatory_domain, priv->domain->name); ++ dev_info(dev, "%s: WPA support: ", wiphy_name(priv->hw->wiphy)); ++ if (!FIRMWARE_IS_WPA(priv->fw_version)) ++ printk("none\n"); ++ else { ++ if (!at76_is_505a(priv->board_type)) ++ printk("TKIP\n"); ++ else ++ printk("TKIP, AES/CCMP\n"); ++ }; + + exit: + return ret; +@@ -5344,15 +2556,13 @@ + + static void at76_delete_device(struct at76_priv *priv) + { +- int i; +- + at76_dbg(DBG_PROC_ENTRY, "%s: ENTER", __func__); + + /* The device is gone, don't bother turning it off */ + priv->device_unplugged = 1; + +- if (priv->netdev_registered) +- unregister_netdev(priv->netdev); ++ if (priv->mac80211_registered) ++ ieee80211_unregister_hw(priv->hw); + + /* assuming we used keventd, it must quiesce too */ + flush_scheduled_work(); +@@ -5373,25 +2583,11 @@ + if (priv->rx_skb) + kfree_skb(priv->rx_skb); + +- at76_free_bss_list(priv); +- del_timer_sync(&priv->bss_list_timer); +- cancel_delayed_work(&priv->dwork_get_scan); +- cancel_delayed_work(&priv->dwork_beacon); +- cancel_delayed_work(&priv->dwork_auth); +- cancel_delayed_work(&priv->dwork_assoc); +- +- if (priv->mac_state == MAC_CONNECTED) +- at76_iwevent_bss_disconnect(priv->netdev); +- +- for (i = 0; i < NR_RX_DATA_BUF; i++) +- if (priv->rx_data[i].skb) { +- dev_kfree_skb(priv->rx_data[i].skb); +- priv->rx_data[i].skb = NULL; +- } + usb_put_dev(priv->udev); + +- at76_dbg(DBG_PROC_ENTRY, "%s: before freeing priv/netdev", __func__); +- free_netdev(priv->netdev); /* priv is in netdev */ ++ at76_dbg(DBG_PROC_ENTRY, "%s: before freeing priv/ieee80211_hw", ++ __func__); ++ ieee80211_free_hw(priv->hw); + + at76_dbg(DBG_PROC_ENTRY, "%s: EXIT", __func__); + } +@@ -5425,8 +2621,8 @@ + we get 204 with 2.4.23, Fiberline FL-WL240u (505A+RFMD2958) ??? */ + + if (op_mode == OPMODE_HW_CONFIG_MODE) { +- dev_printk(KERN_ERR, &interface->dev, +- "cannot handle a device in HW_CONFIG_MODE\n"); ++ dev_err(&interface->dev, ++ "cannot handle a device in HW_CONFIG_MODE\n"); + ret = -EBUSY; + goto error; + } +@@ -5434,13 +2630,12 @@ + if (op_mode != OPMODE_NORMAL_NIC_WITH_FLASH + && op_mode != OPMODE_NORMAL_NIC_WITHOUT_FLASH) { + /* download internal firmware part */ +- dev_printk(KERN_DEBUG, &interface->dev, +- "downloading internal firmware\n"); ++ dev_dbg(&interface->dev, "downloading internal firmware\n"); + ret = at76_load_internal_fw(udev, fwe); + if (ret < 0) { +- dev_printk(KERN_ERR, &interface->dev, +- "error %d downloading internal firmware\n", +- ret); ++ dev_err(&interface->dev, ++ "error %d downloading internal firmware\n", ++ ret); + goto error; + } + usb_put_dev(udev); +@@ -5465,8 +2660,7 @@ + need_ext_fw = 1; + + if (need_ext_fw) { +- dev_printk(KERN_DEBUG, &interface->dev, +- "downloading external firmware\n"); ++ dev_dbg(&interface->dev, "downloading external firmware\n"); + + ret = at76_load_external_fw(udev, fwe); + if (ret) +@@ -5475,8 +2669,8 @@ + /* Re-check firmware version */ + ret = at76_get_mib(udev, MIB_FW_VERSION, &fwv, sizeof(fwv)); + if (ret < 0) { +- dev_printk(KERN_ERR, &interface->dev, +- "error %d getting firmware version\n", ret); ++ dev_err(&interface->dev, ++ "error %d getting firmware version\n", ret); + goto error; + } + } +@@ -5487,7 +2681,6 @@ + goto error; + } + +- SET_NETDEV_DEV(priv->netdev, &interface->dev); + usb_set_intfdata(interface, priv); + + memcpy(&priv->fw_version, &fwv, sizeof(struct mib_fw_version)); +@@ -5515,7 +2708,7 @@ + if (!priv) + return; + +- printk(KERN_INFO "%s: disconnecting\n", priv->netdev->name); ++ printk(KERN_INFO "%s: disconnecting\n", wiphy_name(priv->hw->wiphy)); + at76_delete_device(priv); + dev_printk(KERN_INFO, &interface->dev, "disconnected\n"); + } +@@ -5571,5 +2764,8 @@ + MODULE_AUTHOR("Nick Jones"); + MODULE_AUTHOR("Balint Seeber <n0_5p4m_p13453@hotmail.com>"); + MODULE_AUTHOR("Pavel Roskin <proski@gnu.org>"); ++MODULE_AUTHOR("Guido Guenther <agx@sigxcpu.org>"); ++MODULE_AUTHOR("Kalle Valo <kalle.valo@iki.fi>"); ++MODULE_AUTHOR("Milan Plzik <milan.plzik@gmail.com>"); + MODULE_DESCRIPTION(DRIVER_DESC); + MODULE_LICENSE("GPL"); +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/drivers/staging/at76_usb/at76_usb.h linux-2.6.29-rc3.owrt/drivers/staging/at76_usb/at76_usb.h +--- linux-2.6.29.owrt/drivers/staging/at76_usb/at76_usb.h 2009-05-10 22:04:38.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/drivers/staging/at76_usb/at76_usb.h 2009-05-10 23:48:29.000000000 +0200 +@@ -34,23 +34,6 @@ + BOARD_505AMX = 8 + }; + +-/* our private ioctl's */ +-/* preamble length (0 - long, 1 - short, 2 - auto) */ +-#define AT76_SET_SHORT_PREAMBLE (SIOCIWFIRSTPRIV + 0) +-#define AT76_GET_SHORT_PREAMBLE (SIOCIWFIRSTPRIV + 1) +-/* which debug channels are enabled */ +-#define AT76_SET_DEBUG (SIOCIWFIRSTPRIV + 2) +-#define AT76_GET_DEBUG (SIOCIWFIRSTPRIV + 3) +-/* power save mode (incl. the Atmel proprietary smart save mode) */ +-#define AT76_SET_POWERSAVE_MODE (SIOCIWFIRSTPRIV + 4) +-#define AT76_GET_POWERSAVE_MODE (SIOCIWFIRSTPRIV + 5) +-/* min and max channel times for scan */ +-#define AT76_SET_SCAN_TIMES (SIOCIWFIRSTPRIV + 6) +-#define AT76_GET_SCAN_TIMES (SIOCIWFIRSTPRIV + 7) +-/* scan mode (0 - active, 1 - passive) */ +-#define AT76_SET_SCAN_MODE (SIOCIWFIRSTPRIV + 8) +-#define AT76_GET_SCAN_MODE (SIOCIWFIRSTPRIV + 9) +- + #define CMD_STATUS_IDLE 0x00 + #define CMD_STATUS_COMPLETE 0x01 + #define CMD_STATUS_UNKNOWN 0x02 +@@ -82,6 +65,7 @@ + #define MIB_MAC 0x03 + #define MIB_MAC_MGMT 0x05 + #define MIB_MAC_WEP 0x06 ++#define MIB_MAC_ENCRYPTION 0x06 + #define MIB_PHY 0x07 + #define MIB_FW_VERSION 0x08 + #define MIB_MDOMAIN 0x09 +@@ -106,6 +90,26 @@ + #define AT76_PM_ON 2 + #define AT76_PM_SMART 3 + ++/* cipher values for encryption keys */ ++#define CIPHER_NONE 0 /* this value is only guessed */ ++#define CIPHER_WEP64 1 ++#define CIPHER_TKIP 2 ++#define CIPHER_CCMP 3 ++#define CIPHER_CCX 4 /* for consistency sake only */ ++#define CIPHER_WEP128 5 ++ ++/* bit flags key types for encryption keys */ ++#define KEY_PAIRWISE 2 ++#define KEY_TX 4 ++ ++#define CIPHER_KEYS (4) ++#define CIPHER_KEY_LEN (40) ++ ++struct key_config { ++ u8 cipher; ++ u8 keylen; ++}; ++ + struct hwcfg_r505 { + u8 cr39_values[14]; + u8 reserved1[14]; +@@ -147,6 +151,9 @@ + + #define WEP_SMALL_KEY_LEN (40 / 8) + #define WEP_LARGE_KEY_LEN (104 / 8) ++#define WEP_KEYS (4) ++ ++ + + struct at76_card_config { + u8 exclude_unencrypted; +@@ -161,7 +168,7 @@ + u8 privacy_invoked; + u8 wep_default_key_id; /* 0..3 */ + u8 current_ssid[32]; +- u8 wep_default_key_value[4][WEP_KEY_LEN]; ++ u8 wep_default_key_value[4][WEP_LARGE_KEY_LEN]; + u8 ssid_len; + u8 short_preamble; + __le16 beacon_period; +@@ -186,7 +193,7 @@ + u8 link_quality; + u8 noise_level; + __le32 rx_time; +- u8 packet[IEEE80211_FRAME_LEN + IEEE80211_FCS_LEN]; ++ u8 packet[IEEE80211_MAX_FRAG_THRESHOLD]; + } __attribute__((packed)); + + /* Length of Atmel-specific Tx header before 802.11 frame */ +@@ -196,8 +203,11 @@ + __le16 wlength; + u8 tx_rate; + u8 padding; +- u8 reserved[4]; +- u8 packet[IEEE80211_FRAME_LEN + IEEE80211_FCS_LEN]; ++ u8 key_id; ++ u8 cipher_type; ++ u8 cipher_length; ++ u8 reserved; ++ u8 packet[IEEE80211_MAX_FRAG_THRESHOLD]; + } __attribute__((packed)); + + /* defines for scan_type below */ +@@ -244,6 +254,7 @@ + u8 byte; + __le16 word; + u8 addr[ETH_ALEN]; ++ u8 data[256]; /* we need more space for mib_mac_encryption */ + } data; + } __attribute__((packed)); + +@@ -317,10 +328,24 @@ + u8 exclude_unencrypted; + __le32 wep_icv_error_count; + __le32 wep_excluded_count; +- u8 wep_default_keyvalue[WEP_KEYS][WEP_KEY_LEN]; ++ u8 wep_default_keyvalue[WEP_KEYS][WEP_LARGE_KEY_LEN]; + u8 encryption_level; /* 1 for 40bit, 2 for 104bit encryption */ + } __attribute__((packed)); + ++struct mib_mac_encryption { ++ u8 cipher_default_keyvalue[CIPHER_KEYS][CIPHER_KEY_LEN]; ++ u8 tkip_bssid[6]; ++ u8 privacy_invoked; ++ u8 cipher_default_key_id; ++ u8 cipher_default_group_key_id; ++ u8 exclude_unencrypted; ++ u8 wep_encryption_type; ++ u8 ckip_key_permutation; /* bool */ ++ __le32 wep_icv_error_count; ++ __le32 wep_excluded_count; ++ u8 key_rsc[CIPHER_KEYS][8]; ++} __attribute__((packed)); ++ + struct mib_phy { + __le32 ed_threshold; + +@@ -364,16 +389,6 @@ + __le32 ext_fw_len; /* external firmware image length */ + } __attribute__((packed)); + +-enum mac_state { +- MAC_INIT, +- MAC_SCANNING, +- MAC_AUTH, +- MAC_ASSOC, +- MAC_JOINING, +- MAC_CONNECTED, +- MAC_OWN_IBSS +-}; +- + /* a description of a regulatory domain and the allowed channels */ + struct reg_domain { + u16 code; +@@ -381,47 +396,6 @@ + u32 channel_map; /* if bit N is set, channel (N+1) is allowed */ + }; + +-/* how long do we keep a (I)BSS in the bss_list in jiffies +- this should be long enough for the user to retrieve the table +- (by iwlist ?) after the device started, because all entries from +- other channels than the one the device locks on get removed, too */ +-#define BSS_LIST_TIMEOUT (120 * HZ) +-/* struct to store BSS info found during scan */ +-#define BSS_LIST_MAX_RATE_LEN 32 /* 32 rates should be enough ... */ +- +-struct bss_info { +- struct list_head list; +- +- u8 bssid[ETH_ALEN]; /* bssid */ +- u8 ssid[IW_ESSID_MAX_SIZE]; /* essid */ +- u8 ssid_len; /* length of ssid above */ +- u8 channel; +- u16 capa; /* BSS capabilities */ +- u16 beacon_interval; /* beacon interval, Kus (1024 microseconds) */ +- u8 rates[BSS_LIST_MAX_RATE_LEN]; /* supported rates in units of +- 500 kbps, ORed with 0x80 for +- basic rates */ +- u8 rates_len; +- +- /* quality of received beacon */ +- u8 rssi; +- u8 link_qual; +- u8 noise_level; +- +- unsigned long last_rx; /* time (jiffies) of last beacon received */ +-}; +- +-/* a rx data buffer to collect rx fragments */ +-struct rx_data_buf { +- u8 sender[ETH_ALEN]; /* sender address */ +- u16 seqnr; /* sequence number */ +- u16 fragnr; /* last fragment received */ +- unsigned long last_rx; /* jiffies of last rx */ +- struct sk_buff *skb; /* == NULL if entry is free */ +-}; +- +-#define NR_RX_DATA_BUF 8 +- + /* Data for one loaded firmware file */ + struct fwentry { + const char *const fwname; +@@ -438,11 +412,9 @@ + + struct at76_priv { + struct usb_device *udev; /* USB device pointer */ +- struct net_device *netdev; /* net device pointer */ +- struct net_device_stats stats; /* net device stats */ +- struct iw_statistics wstats; /* wireless stats */ + + struct sk_buff *rx_skb; /* skbuff for receiving data */ ++ struct sk_buff *tx_skb; /* skbuff for transmitting data */ + void *bulk_out_buffer; /* buffer for sending data */ + + struct urb *tx_urb; /* URB for sending data */ +@@ -454,26 +426,17 @@ + struct mutex mtx; /* locks this structure */ + + /* work queues */ +- struct work_struct work_assoc_done; +- struct work_struct work_join; +- struct work_struct work_new_bss; +- struct work_struct work_start_scan; + struct work_struct work_set_promisc; + struct work_struct work_submit_rx; +- struct delayed_work dwork_restart; +- struct delayed_work dwork_get_scan; +- struct delayed_work dwork_beacon; +- struct delayed_work dwork_auth; +- struct delayed_work dwork_assoc; ++ struct delayed_work dwork_hw_scan; + + struct tasklet_struct rx_tasklet; + + /* the WEP stuff */ + int wep_enabled; /* 1 if WEP is enabled */ + int wep_key_id; /* key id to be used */ +- u8 wep_keys[WEP_KEYS][WEP_KEY_LEN]; /* the four WEP keys, +- 5 or 13 bytes are used */ +- u8 wep_keys_len[WEP_KEYS]; /* the length of the above keys */ ++ u8 wep_keys[WEP_KEYS][WEP_LARGE_KEY_LEN]; /* WEP keys */ ++ u8 wep_keys_len[WEP_KEYS]; /* length of WEP keys */ + + int channel; + int iw_mode; +@@ -495,44 +458,13 @@ + int scan_mode; /* SCAN_TYPE_ACTIVE, SCAN_TYPE_PASSIVE */ + int scan_need_any; /* if set, need to scan for any ESSID */ + +- /* the list we got from scanning */ +- spinlock_t bss_list_spinlock; /* protects bss_list operations */ +- struct list_head bss_list; /* list of BSS we got beacons from */ +- struct timer_list bss_list_timer; /* timer to purge old entries +- from bss_list */ +- struct bss_info *curr_bss; /* current BSS */ + u16 assoc_id; /* current association ID, if associated */ + +- u8 wanted_bssid[ETH_ALEN]; +- int wanted_bssid_valid; /* != 0 if wanted_bssid is to be used */ +- +- /* some data for infrastructure mode only */ +- spinlock_t mgmt_spinlock; /* this spinlock protects access to +- next_mgmt_bulk */ +- +- struct at76_tx_buffer *next_mgmt_bulk; /* pending management msg to +- send via bulk out */ +- enum mac_state mac_state; +- enum { +- SCAN_IDLE, +- SCAN_IN_PROGRESS, +- SCAN_COMPLETED +- } scan_state; +- time_t last_scan; +- +- int retries; /* remaining retries in case of timeout when +- * sending AuthReq or AssocReq */ + u8 pm_mode; /* power management mode */ + u32 pm_period; /* power management period in microseconds */ + + struct reg_domain const *domain; /* reg domain description */ + +- /* iwspy support */ +- spinlock_t spy_spinlock; +- struct iw_spy_data spy_data; +- +- struct iw_public_data wireless_data; +- + /* These fields contain HW config provided by the device (not all of + * these fields are used by all board types) */ + u8 mac_addr[ETH_ALEN]; +@@ -540,9 +472,6 @@ + + struct at76_card_config card_config; + +- /* store rx fragments until complete */ +- struct rx_data_buf rx_data[NR_RX_DATA_BUF]; +- + enum board_type board_type; + struct mib_fw_version fw_version; + +@@ -550,58 +479,20 @@ + unsigned int netdev_registered:1; + struct set_mib_buffer mib_buf; /* global buffer for set_mib calls */ + +- /* beacon counting */ + int beacon_period; /* period of mgmt beacons, Kus */ +- int beacons_received; +- unsigned long beacons_last_qual; /* time we restarted counting +- beacons */ +-}; + +-struct at76_rx_radiotap { +- struct ieee80211_radiotap_header rt_hdr; +- __le64 rt_tsft; +- u8 rt_flags; +- u8 rt_rate; +- s8 rt_signal; +- s8 rt_noise; +-}; +- +-#define AT76_RX_RADIOTAP_PRESENT \ +- ((1 << IEEE80211_RADIOTAP_TSFT) | \ +- (1 << IEEE80211_RADIOTAP_FLAGS) | \ +- (1 << IEEE80211_RADIOTAP_RATE) | \ +- (1 << IEEE80211_RADIOTAP_DB_ANTSIGNAL) | \ +- (1 << IEEE80211_RADIOTAP_DB_ANTNOISE)) +- +-#define BEACON_MAX_DATA_LENGTH 1500 +- +-/* the maximum size of an AssocReq packet */ +-#define ASSOCREQ_MAX_SIZE \ +- (AT76_TX_HDRLEN + sizeof(struct ieee80211_assoc_request) + \ +- 1 + 1 + IW_ESSID_MAX_SIZE + 1 + 1 + 4) +- +-/* for shared secret auth, add the challenge text size */ +-#define AUTH_FRAME_SIZE (AT76_TX_HDRLEN + sizeof(struct ieee80211_auth)) ++ struct ieee80211_hw *hw; ++ int mac80211_registered; + +-/* Maximal number of AuthReq retries */ +-#define AUTH_RETRIES 3 +- +-/* Maximal number of AssocReq retries */ +-#define ASSOC_RETRIES 3 +- +-/* Beacon timeout in managed mode when we are connected */ +-#define BEACON_TIMEOUT (10 * HZ) +- +-/* Timeout for authentication response */ +-#define AUTH_TIMEOUT (1 * HZ) ++ struct key_config keys[4]; /* installed key types */ ++ u8 default_pairwise_key; ++ u8 default_group_key; ++}; + +-/* Timeout for association response */ +-#define ASSOC_TIMEOUT (1 * HZ) ++#define AT76_SUPPORTED_FILTERS FIF_PROMISC_IN_BSS + +-/* Polling interval when scan is running */ + #define SCAN_POLL_INTERVAL (HZ / 4) + +-/* Command completion timeout */ + #define CMD_COMPLETION_TIMEOUT (5 * HZ) + + #define DEF_RTS_THRESHOLD 1536 +@@ -611,8 +502,6 @@ + #define DEF_SCAN_MIN_TIME 10 + #define DEF_SCAN_MAX_TIME 120 + +-#define MAX_RTS_THRESHOLD (MAX_FRAG_THRESHOLD + 1) +- + /* the max padding size for tx in bytes (see calc_padding) */ + #define MAX_PADDING_SIZE 53 + +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/drivers/staging/at76_usb/Kconfig linux-2.6.29-rc3.owrt/drivers/staging/at76_usb/Kconfig +--- linux-2.6.29.owrt/drivers/staging/at76_usb/Kconfig 2009-05-10 22:04:38.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/drivers/staging/at76_usb/Kconfig 2009-05-10 23:48:29.000000000 +0200 +@@ -1,6 +1,6 @@ + config USB_ATMEL + tristate "Atmel at76c503/at76c505/at76c505a USB cards" +- depends on WLAN_80211 && USB ++ depends on MAC80211 && WLAN_80211 && USB + default N + select FW_LOADER + ---help--- +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/drivers/staging/benet/asyncmesg.h linux-2.6.29-rc3.owrt/drivers/staging/benet/asyncmesg.h +--- linux-2.6.29.owrt/drivers/staging/benet/asyncmesg.h 1970-01-01 01:00:00.000000000 +0100 ++++ linux-2.6.29-rc3.owrt/drivers/staging/benet/asyncmesg.h 2009-05-10 23:48:29.000000000 +0200 +@@ -0,0 +1,82 @@ ++/* ++ * Copyright (C) 2005 - 2008 ServerEngines ++ * All rights reserved. ++ * ++ * 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. The full GNU General ++ * Public License is included in this distribution in the file called COPYING. ++ * ++ * Contact Information: ++ * linux-drivers@serverengines.com ++ * ++ * ServerEngines ++ * 209 N. Fair Oaks Ave ++ * Sunnyvale, CA 94085 ++ */ ++/* ++ * Autogenerated by srcgen version: 0127 ++ */ ++#ifndef __asyncmesg_amap_h__ ++#define __asyncmesg_amap_h__ ++#include "fwcmd_common.h" ++ ++/* --- ASYNC_EVENT_CODES --- */ ++#define ASYNC_EVENT_CODE_LINK_STATE (1) ++#define ASYNC_EVENT_CODE_ISCSI (2) ++ ++/* --- ASYNC_LINK_STATES --- */ ++#define ASYNC_EVENT_LINK_DOWN (0) /* Link Down on a port */ ++#define ASYNC_EVENT_LINK_UP (1) /* Link Up on a port */ ++ ++/* ++ * The last 4 bytes of the async events have this common format. It allows ++ * the driver to distinguish [link]MCC_CQ_ENTRY[/link] structs from ++ * asynchronous events. Both arrive on the same completion queue. This ++ * structure also contains the common fields used to decode the async event. ++ */ ++struct BE_ASYNC_EVENT_TRAILER_AMAP { ++ u8 rsvd0[8]; /* DWORD 0 */ ++ u8 event_code[8]; /* DWORD 0 */ ++ u8 event_type[8]; /* DWORD 0 */ ++ u8 rsvd1[6]; /* DWORD 0 */ ++ u8 async_event; /* DWORD 0 */ ++ u8 valid; /* DWORD 0 */ ++} __packed; ++struct ASYNC_EVENT_TRAILER_AMAP { ++ u32 dw[1]; ++}; ++ ++/* ++ * Applicable in Initiator, Target and NIC modes. ++ * A link state async event is seen by all device drivers as soon they ++ * create an MCC ring. Thereafter, anytime the link status changes the ++ * drivers will receive a link state async event. Notifications continue to ++ * be sent until a driver destroys its MCC ring. A link down event is ++ * reported when either port loses link. A link up event is reported ++ * when either port regains link. When BE's failover mechanism is enabled, a ++ * link down on the active port causes traffic to be diverted to the standby ++ * port by the BE's ARM firmware (assuming the standby port has link). In ++ * this case, the standy port assumes the active status. Note: when link is ++ * restored on the failed port, traffic continues on the currently active ++ * port. The ARM firmware does not attempt to 'fail back' traffic to ++ * the restored port. ++ */ ++struct BE_ASYNC_EVENT_LINK_STATE_AMAP { ++ u8 port0_link_status[8]; ++ u8 port1_link_status[8]; ++ u8 active_port[8]; ++ u8 rsvd0[8]; /* DWORD 0 */ ++ u8 port0_duplex[8]; ++ u8 port0_speed[8]; ++ u8 port1_duplex[8]; ++ u8 port1_speed[8]; ++ u8 port0_fault[8]; ++ u8 port1_fault[8]; ++ u8 rsvd1[2][8]; /* DWORD 2 */ ++ struct BE_ASYNC_EVENT_TRAILER_AMAP trailer; ++} __packed; ++struct ASYNC_EVENT_LINK_STATE_AMAP { ++ u32 dw[4]; ++}; ++#endif /* __asyncmesg_amap_h__ */ +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/drivers/staging/benet/be_cm.h linux-2.6.29-rc3.owrt/drivers/staging/benet/be_cm.h +--- linux-2.6.29.owrt/drivers/staging/benet/be_cm.h 1970-01-01 01:00:00.000000000 +0100 ++++ linux-2.6.29-rc3.owrt/drivers/staging/benet/be_cm.h 2009-05-10 23:48:29.000000000 +0200 +@@ -0,0 +1,134 @@ ++/* ++ * Copyright (C) 2005 - 2008 ServerEngines ++ * All rights reserved. ++ * ++ * 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. The full GNU General ++ * Public License is included in this distribution in the file called COPYING. ++ * ++ * Contact Information: ++ * linux-drivers@serverengines.com ++ * ++ * ServerEngines ++ * 209 N. Fair Oaks Ave ++ * Sunnyvale, CA 94085 ++ */ ++/* ++ * Autogenerated by srcgen version: 0127 ++ */ ++#ifndef __be_cm_amap_h__ ++#define __be_cm_amap_h__ ++#include "be_common.h" ++#include "etx_context.h" ++#include "mpu_context.h" ++ ++/* ++ * --- CEV_WATERMARK_ENUM --- ++ * CQ/EQ Watermark Encodings. Encoded as number of free entries in ++ * Queue when Watermark is reached. ++ */ ++#define CEV_WMARK_0 (0) /* Watermark when Queue full */ ++#define CEV_WMARK_16 (1) /* Watermark at 16 free entries */ ++#define CEV_WMARK_32 (2) /* Watermark at 32 free entries */ ++#define CEV_WMARK_48 (3) /* Watermark at 48 free entries */ ++#define CEV_WMARK_64 (4) /* Watermark at 64 free entries */ ++#define CEV_WMARK_80 (5) /* Watermark at 80 free entries */ ++#define CEV_WMARK_96 (6) /* Watermark at 96 free entries */ ++#define CEV_WMARK_112 (7) /* Watermark at 112 free entries */ ++#define CEV_WMARK_128 (8) /* Watermark at 128 free entries */ ++#define CEV_WMARK_144 (9) /* Watermark at 144 free entries */ ++#define CEV_WMARK_160 (10) /* Watermark at 160 free entries */ ++#define CEV_WMARK_176 (11) /* Watermark at 176 free entries */ ++#define CEV_WMARK_192 (12) /* Watermark at 192 free entries */ ++#define CEV_WMARK_208 (13) /* Watermark at 208 free entries */ ++#define CEV_WMARK_224 (14) /* Watermark at 224 free entries */ ++#define CEV_WMARK_240 (15) /* Watermark at 240 free entries */ ++ ++/* ++ * --- CQ_CNT_ENUM --- ++ * Completion Queue Count Encodings. ++ */ ++#define CEV_CQ_CNT_256 (0) /* CQ has 256 entries */ ++#define CEV_CQ_CNT_512 (1) /* CQ has 512 entries */ ++#define CEV_CQ_CNT_1024 (2) /* CQ has 1024 entries */ ++ ++/* ++ * --- EQ_CNT_ENUM --- ++ * Event Queue Count Encodings. ++ */ ++#define CEV_EQ_CNT_256 (0) /* EQ has 256 entries (16-byte EQEs only) */ ++#define CEV_EQ_CNT_512 (1) /* EQ has 512 entries (16-byte EQEs only) */ ++#define CEV_EQ_CNT_1024 (2) /* EQ has 1024 entries (4-byte or */ ++ /* 16-byte EQEs only) */ ++#define CEV_EQ_CNT_2048 (3) /* EQ has 2048 entries (4-byte or */ ++ /* 16-byte EQEs only) */ ++#define CEV_EQ_CNT_4096 (4) /* EQ has 4096 entries (4-byte EQEs only) */ ++ ++/* ++ * --- EQ_SIZE_ENUM --- ++ * Event Queue Entry Size Encoding. ++ */ ++#define CEV_EQ_SIZE_4 (0) /* EQE is 4 bytes */ ++#define CEV_EQ_SIZE_16 (1) /* EQE is 16 bytes */ ++ ++/* ++ * Completion Queue Context Table Entry. Contains the state of a CQ. ++ * Located in RAM within the CEV block. ++ */ ++struct BE_CQ_CONTEXT_AMAP { ++ u8 Cidx[11]; /* DWORD 0 */ ++ u8 Watermark[4]; /* DWORD 0 */ ++ u8 NoDelay; /* DWORD 0 */ ++ u8 EPIdx[11]; /* DWORD 0 */ ++ u8 Count[2]; /* DWORD 0 */ ++ u8 valid; /* DWORD 0 */ ++ u8 SolEvent; /* DWORD 0 */ ++ u8 Eventable; /* DWORD 0 */ ++ u8 Pidx[11]; /* DWORD 1 */ ++ u8 PD[10]; /* DWORD 1 */ ++ u8 EQID[7]; /* DWORD 1 */ ++ u8 Func; /* DWORD 1 */ ++ u8 WME; /* DWORD 1 */ ++ u8 Stalled; /* DWORD 1 */ ++ u8 Armed; /* DWORD 1 */ ++} __packed; ++struct CQ_CONTEXT_AMAP { ++ u32 dw[2]; ++}; ++ ++/* ++ * Event Queue Context Table Entry. Contains the state of an EQ. ++ * Located in RAM in the CEV block. ++ */ ++struct BE_EQ_CONTEXT_AMAP { ++ u8 Cidx[13]; /* DWORD 0 */ ++ u8 rsvd0[2]; /* DWORD 0 */ ++ u8 Func; /* DWORD 0 */ ++ u8 EPIdx[13]; /* DWORD 0 */ ++ u8 valid; /* DWORD 0 */ ++ u8 rsvd1; /* DWORD 0 */ ++ u8 Size; /* DWORD 0 */ ++ u8 Pidx[13]; /* DWORD 1 */ ++ u8 rsvd2[3]; /* DWORD 1 */ ++ u8 PD[10]; /* DWORD 1 */ ++ u8 Count[3]; /* DWORD 1 */ ++ u8 SolEvent; /* DWORD 1 */ ++ u8 Stalled; /* DWORD 1 */ ++ u8 Armed; /* DWORD 1 */ ++ u8 Watermark[4]; /* DWORD 2 */ ++ u8 WME; /* DWORD 2 */ ++ u8 rsvd3[3]; /* DWORD 2 */ ++ u8 EventVect[6]; /* DWORD 2 */ ++ u8 rsvd4[2]; /* DWORD 2 */ ++ u8 Delay[8]; /* DWORD 2 */ ++ u8 rsvd5[6]; /* DWORD 2 */ ++ u8 TMR; /* DWORD 2 */ ++ u8 rsvd6; /* DWORD 2 */ ++ u8 rsvd7[32]; /* DWORD 3 */ ++} __packed; ++struct EQ_CONTEXT_AMAP { ++ u32 dw[4]; ++}; ++ ++#endif /* __be_cm_amap_h__ */ +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/drivers/staging/benet/be_common.h linux-2.6.29-rc3.owrt/drivers/staging/benet/be_common.h +--- linux-2.6.29.owrt/drivers/staging/benet/be_common.h 1970-01-01 01:00:00.000000000 +0100 ++++ linux-2.6.29-rc3.owrt/drivers/staging/benet/be_common.h 2009-05-10 23:48:29.000000000 +0200 +@@ -0,0 +1,53 @@ ++/* ++ * Copyright (C) 2005 - 2008 ServerEngines ++ * All rights reserved. ++ * ++ * 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. The full GNU General ++ * Public License is included in this distribution in the file called COPYING. ++ * ++ * Contact Information: ++ * linux-drivers@serverengines.com ++ * ++ * ServerEngines ++ * 209 N. Fair Oaks Ave ++ * Sunnyvale, CA 94085 ++ */ ++/* ++ * Autogenerated by srcgen version: 0127 ++ */ ++#ifndef __be_common_amap_h__ ++#define __be_common_amap_h__ ++ ++/* Physical Address. */ ++struct BE_PHYS_ADDR_AMAP { ++ u8 lo[32]; /* DWORD 0 */ ++ u8 hi[32]; /* DWORD 1 */ ++} __packed; ++struct PHYS_ADDR_AMAP { ++ u32 dw[2]; ++}; ++ ++/* Virtual Address. */ ++struct BE_VIRT_ADDR_AMAP { ++ u8 lo[32]; /* DWORD 0 */ ++ u8 hi[32]; /* DWORD 1 */ ++} __packed; ++struct VIRT_ADDR_AMAP { ++ u32 dw[2]; ++}; ++ ++/* Scatter gather element. */ ++struct BE_SGE_AMAP { ++ u8 addr_hi[32]; /* DWORD 0 */ ++ u8 addr_lo[32]; /* DWORD 1 */ ++ u8 rsvd0[32]; /* DWORD 2 */ ++ u8 len[16]; /* DWORD 3 */ ++ u8 rsvd1[16]; /* DWORD 3 */ ++} __packed; ++struct SGE_AMAP { ++ u32 dw[4]; ++}; ++ ++#endif /* __be_common_amap_h__ */ +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/drivers/staging/benet/be_ethtool.c linux-2.6.29-rc3.owrt/drivers/staging/benet/be_ethtool.c +--- linux-2.6.29.owrt/drivers/staging/benet/be_ethtool.c 1970-01-01 01:00:00.000000000 +0100 ++++ linux-2.6.29-rc3.owrt/drivers/staging/benet/be_ethtool.c 2009-05-10 23:48:29.000000000 +0200 +@@ -0,0 +1,348 @@ ++/* ++ * Copyright (C) 2005 - 2008 ServerEngines ++ * All rights reserved. ++ * ++ * 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. The full GNU General ++ * Public License is included in this distribution in the file called COPYING. ++ * ++ * Contact Information: ++ * linux-drivers@serverengines.com ++ * ++ * ServerEngines ++ * 209 N. Fair Oaks Ave ++ * Sunnyvale, CA 94085 ++ */ ++/* ++ * be_ethtool.c ++ * ++ * This file contains various functions that ethtool can use ++ * to talk to the driver and the BE H/W. ++ */ ++ ++#include "benet.h" ++ ++#include <linux/ethtool.h> ++ ++static const char benet_gstrings_stats[][ETH_GSTRING_LEN] = { ++/* net_device_stats */ ++ "rx_packets", ++ "tx_packets", ++ "rx_bytes", ++ "tx_bytes", ++ "rx_errors", ++ "tx_errors", ++ "rx_dropped", ++ "tx_dropped", ++ "multicast", ++ "collisions", ++ "rx_length_errors", ++ "rx_over_errors", ++ "rx_crc_errors", ++ "rx_frame_errors", ++ "rx_fifo_errors", ++ "rx_missed_errors", ++ "tx_aborted_errors", ++ "tx_carrier_errors", ++ "tx_fifo_errors", ++ "tx_heartbeat_errors", ++ "tx_window_errors", ++ "rx_compressed", ++ "tc_compressed", ++/* BE driver Stats */ ++ "bes_tx_reqs", ++ "bes_tx_fails", ++ "bes_fwd_reqs", ++ "bes_tx_wrbs", ++ "bes_interrupts", ++ "bes_events", ++ "bes_tx_events", ++ "bes_rx_events", ++ "bes_tx_compl", ++ "bes_rx_compl", ++ "bes_ethrx_post_fail", ++ "bes_802_3_dropped_frames", ++ "bes_802_3_malformed_frames", ++ "bes_rx_misc_pkts", ++ "bes_eth_tx_rate", ++ "bes_eth_rx_rate", ++ "Num Packets collected", ++ "Num Times Flushed", ++}; ++ ++#define NET_DEV_STATS_LEN \ ++ (sizeof(struct net_device_stats)/sizeof(unsigned long)) ++ ++#define BENET_STATS_LEN ARRAY_SIZE(benet_gstrings_stats) ++ ++static void ++be_get_drvinfo(struct net_device *netdev, struct ethtool_drvinfo *drvinfo) ++{ ++ struct be_net_object *pnob = netdev_priv(netdev); ++ struct be_adapter *adapter = pnob->adapter; ++ ++ strncpy(drvinfo->driver, be_driver_name, 32); ++ strncpy(drvinfo->version, be_drvr_ver, 32); ++ strncpy(drvinfo->fw_version, be_fw_ver, 32); ++ strcpy(drvinfo->bus_info, pci_name(adapter->pdev)); ++ drvinfo->testinfo_len = 0; ++ drvinfo->regdump_len = 0; ++ drvinfo->eedump_len = 0; ++} ++ ++static int ++be_get_coalesce(struct net_device *netdev, struct ethtool_coalesce *coalesce) ++{ ++ struct be_net_object *pnob = netdev_priv(netdev); ++ struct be_adapter *adapter = pnob->adapter; ++ ++ coalesce->rx_max_coalesced_frames = adapter->max_rx_coal; ++ ++ coalesce->rx_coalesce_usecs = adapter->cur_eqd; ++ coalesce->rx_coalesce_usecs_high = adapter->max_eqd; ++ coalesce->rx_coalesce_usecs_low = adapter->min_eqd; ++ ++ coalesce->tx_coalesce_usecs = adapter->cur_eqd; ++ coalesce->tx_coalesce_usecs_high = adapter->max_eqd; ++ coalesce->tx_coalesce_usecs_low = adapter->min_eqd; ++ ++ coalesce->use_adaptive_rx_coalesce = adapter->enable_aic; ++ coalesce->use_adaptive_tx_coalesce = adapter->enable_aic; ++ ++ return 0; ++} ++ ++/* ++ * This routine is used to set interrup coalescing delay *as well as* ++ * the number of pkts to coalesce for LRO. ++ */ ++static int ++be_set_coalesce(struct net_device *netdev, struct ethtool_coalesce *coalesce) ++{ ++ struct be_net_object *pnob = netdev_priv(netdev); ++ struct be_adapter *adapter = pnob->adapter; ++ struct be_eq_object *eq_objectp; ++ u32 max, min, cur; ++ int status; ++ ++ adapter->max_rx_coal = coalesce->rx_max_coalesced_frames; ++ if (adapter->max_rx_coal >= BE_LRO_MAX_PKTS) ++ adapter->max_rx_coal = BE_LRO_MAX_PKTS; ++ ++ if (adapter->enable_aic == 0 && ++ coalesce->use_adaptive_rx_coalesce == 1) { ++ /* if AIC is being turned on now, start with an EQD of 0 */ ++ adapter->cur_eqd = 0; ++ } ++ adapter->enable_aic = coalesce->use_adaptive_rx_coalesce; ++ ++ /* round off to nearest multiple of 8 */ ++ max = (((coalesce->rx_coalesce_usecs_high + 4) >> 3) << 3); ++ min = (((coalesce->rx_coalesce_usecs_low + 4) >> 3) << 3); ++ cur = (((coalesce->rx_coalesce_usecs + 4) >> 3) << 3); ++ ++ if (adapter->enable_aic) { ++ /* accept low and high if AIC is enabled */ ++ if (max > MAX_EQD) ++ max = MAX_EQD; ++ if (min > max) ++ min = max; ++ adapter->max_eqd = max; ++ adapter->min_eqd = min; ++ if (adapter->cur_eqd > max) ++ adapter->cur_eqd = max; ++ if (adapter->cur_eqd < min) ++ adapter->cur_eqd = min; ++ } else { ++ /* accept specified coalesce_usecs only if AIC is disabled */ ++ if (cur > MAX_EQD) ++ cur = MAX_EQD; ++ eq_objectp = &pnob->event_q_obj; ++ status = ++ be_eq_modify_delay(&pnob->fn_obj, 1, &eq_objectp, &cur, ++ NULL, NULL, NULL); ++ if (status == BE_SUCCESS) ++ adapter->cur_eqd = cur; ++ } ++ return 0; ++} ++ ++static u32 be_get_rx_csum(struct net_device *netdev) ++{ ++ struct be_net_object *pnob = netdev_priv(netdev); ++ struct be_adapter *adapter = pnob->adapter; ++ return adapter->rx_csum; ++} ++ ++static int be_set_rx_csum(struct net_device *netdev, uint32_t data) ++{ ++ struct be_net_object *pnob = netdev_priv(netdev); ++ struct be_adapter *adapter = pnob->adapter; ++ ++ if (data) ++ adapter->rx_csum = 1; ++ else ++ adapter->rx_csum = 0; ++ ++ return 0; ++} ++ ++static void ++be_get_strings(struct net_device *netdev, uint32_t stringset, uint8_t *data) ++{ ++ switch (stringset) { ++ case ETH_SS_STATS: ++ memcpy(data, *benet_gstrings_stats, ++ sizeof(benet_gstrings_stats)); ++ break; ++ } ++} ++ ++static int be_get_stats_count(struct net_device *netdev) ++{ ++ return BENET_STATS_LEN; ++} ++ ++static void ++be_get_ethtool_stats(struct net_device *netdev, ++ struct ethtool_stats *stats, uint64_t *data) ++{ ++ struct be_net_object *pnob = netdev_priv(netdev); ++ struct be_adapter *adapter = pnob->adapter; ++ int i; ++ ++ benet_get_stats(netdev); ++ ++ for (i = 0; i <= NET_DEV_STATS_LEN; i++) ++ data[i] = ((unsigned long *)&adapter->benet_stats)[i]; ++ ++ data[i] = adapter->be_stat.bes_tx_reqs; ++ data[i++] = adapter->be_stat.bes_tx_fails; ++ data[i++] = adapter->be_stat.bes_fwd_reqs; ++ data[i++] = adapter->be_stat.bes_tx_wrbs; ++ ++ data[i++] = adapter->be_stat.bes_ints; ++ data[i++] = adapter->be_stat.bes_events; ++ data[i++] = adapter->be_stat.bes_tx_events; ++ data[i++] = adapter->be_stat.bes_rx_events; ++ data[i++] = adapter->be_stat.bes_tx_compl; ++ data[i++] = adapter->be_stat.bes_rx_compl; ++ data[i++] = adapter->be_stat.bes_ethrx_post_fail; ++ data[i++] = adapter->be_stat.bes_802_3_dropped_frames; ++ data[i++] = adapter->be_stat.bes_802_3_malformed_frames; ++ data[i++] = adapter->be_stat.bes_rx_misc_pkts; ++ data[i++] = adapter->be_stat.bes_eth_tx_rate; ++ data[i++] = adapter->be_stat.bes_eth_rx_rate; ++ data[i++] = adapter->be_stat.bes_rx_coal; ++ data[i++] = adapter->be_stat.bes_rx_flush; ++ ++} ++ ++static int be_get_settings(struct net_device *netdev, struct ethtool_cmd *ecmd) ++{ ++ ecmd->speed = SPEED_10000; ++ ecmd->duplex = DUPLEX_FULL; ++ ecmd->autoneg = AUTONEG_DISABLE; ++ return 0; ++} ++ ++/* Get the Ring parameters from the pnob */ ++static void ++be_get_ringparam(struct net_device *netdev, struct ethtool_ringparam *ring) ++{ ++ struct be_net_object *pnob = netdev_priv(netdev); ++ ++ /* Pre Set Maxims */ ++ ring->rx_max_pending = pnob->rx_q_len; ++ ring->rx_mini_max_pending = ring->rx_mini_max_pending; ++ ring->rx_jumbo_max_pending = ring->rx_jumbo_max_pending; ++ ring->tx_max_pending = pnob->tx_q_len; ++ ++ /* Current hardware Settings */ ++ ring->rx_pending = atomic_read(&pnob->rx_q_posted); ++ ring->rx_mini_pending = ring->rx_mini_pending; ++ ring->rx_jumbo_pending = ring->rx_jumbo_pending; ++ ring->tx_pending = atomic_read(&pnob->tx_q_used); ++ ++} ++ ++static void ++be_get_pauseparam(struct net_device *netdev, struct ethtool_pauseparam *ecmd) ++{ ++ struct be_net_object *pnob = netdev_priv(netdev); ++ bool rxfc, txfc; ++ int status; ++ ++ status = be_eth_get_flow_control(&pnob->fn_obj, &txfc, &rxfc); ++ if (status != BE_SUCCESS) { ++ dev_info(&netdev->dev, "Unable to get pause frame settings\n"); ++ /* return defaults */ ++ ecmd->rx_pause = 1; ++ ecmd->tx_pause = 0; ++ ecmd->autoneg = AUTONEG_ENABLE; ++ return; ++ } ++ ++ if (txfc == true) ++ ecmd->tx_pause = 1; ++ else ++ ecmd->tx_pause = 0; ++ ++ if (rxfc == true) ++ ecmd->rx_pause = 1; ++ else ++ ecmd->rx_pause = 0; ++ ++ ecmd->autoneg = AUTONEG_ENABLE; ++} ++ ++static int ++be_set_pauseparam(struct net_device *netdev, struct ethtool_pauseparam *ecmd) ++{ ++ struct be_net_object *pnob = netdev_priv(netdev); ++ bool txfc, rxfc; ++ int status; ++ ++ if (ecmd->autoneg != AUTONEG_ENABLE) ++ return -EINVAL; ++ ++ if (ecmd->tx_pause) ++ txfc = true; ++ else ++ txfc = false; ++ ++ if (ecmd->rx_pause) ++ rxfc = true; ++ else ++ rxfc = false; ++ ++ status = be_eth_set_flow_control(&pnob->fn_obj, txfc, rxfc); ++ if (status != BE_SUCCESS) { ++ dev_info(&netdev->dev, "Unable to set pause frame settings\n"); ++ return -1; ++ } ++ return 0; ++} ++ ++struct ethtool_ops be_ethtool_ops = { ++ .get_settings = be_get_settings, ++ .get_drvinfo = be_get_drvinfo, ++ .get_link = ethtool_op_get_link, ++ .get_coalesce = be_get_coalesce, ++ .set_coalesce = be_set_coalesce, ++ .get_ringparam = be_get_ringparam, ++ .get_pauseparam = be_get_pauseparam, ++ .set_pauseparam = be_set_pauseparam, ++ .get_rx_csum = be_get_rx_csum, ++ .set_rx_csum = be_set_rx_csum, ++ .get_tx_csum = ethtool_op_get_tx_csum, ++ .set_tx_csum = ethtool_op_set_tx_csum, ++ .get_sg = ethtool_op_get_sg, ++ .set_sg = ethtool_op_set_sg, ++ .get_tso = ethtool_op_get_tso, ++ .set_tso = ethtool_op_set_tso, ++ .get_strings = be_get_strings, ++ .get_stats_count = be_get_stats_count, ++ .get_ethtool_stats = be_get_ethtool_stats, ++}; +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/drivers/staging/benet/be_init.c linux-2.6.29-rc3.owrt/drivers/staging/benet/be_init.c +--- linux-2.6.29.owrt/drivers/staging/benet/be_init.c 1970-01-01 01:00:00.000000000 +0100 ++++ linux-2.6.29-rc3.owrt/drivers/staging/benet/be_init.c 2009-05-10 23:48:29.000000000 +0200 +@@ -0,0 +1,1382 @@ ++/* ++ * Copyright (C) 2005 - 2008 ServerEngines ++ * All rights reserved. ++ * ++ * 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. The full GNU General ++ * Public License is included in this distribution in the file called COPYING. ++ * ++ * Contact Information: ++ * linux-drivers@serverengines.com ++ * ++ * ServerEngines ++ * 209 N. Fair Oaks Ave ++ * Sunnyvale, CA 94085 ++ */ ++#include <linux/etherdevice.h> ++#include "benet.h" ++ ++#define DRVR_VERSION "1.0.728" ++ ++static const struct pci_device_id be_device_id_table[] = { ++ {PCI_DEVICE(0x19a2, 0x0201)}, ++ {0} ++}; ++ ++MODULE_DEVICE_TABLE(pci, be_device_id_table); ++ ++MODULE_VERSION(DRVR_VERSION); ++ ++#define DRV_DESCRIPTION "ServerEngines BladeEngine Network Driver Version " ++ ++MODULE_DESCRIPTION(DRV_DESCRIPTION DRVR_VERSION); ++MODULE_AUTHOR("ServerEngines"); ++MODULE_LICENSE("GPL"); ++ ++static unsigned int msix = 1; ++module_param(msix, uint, S_IRUGO); ++MODULE_PARM_DESC(msix, "Use MSI-x interrupts"); ++ ++static unsigned int rxbuf_size = 2048; /* Default RX frag size */ ++module_param(rxbuf_size, uint, S_IRUGO); ++MODULE_PARM_DESC(rxbuf_size, "Size of buffers to hold Rx data"); ++ ++const char be_drvr_ver[] = DRVR_VERSION; ++char be_fw_ver[32]; /* F/W version filled in by be_probe */ ++char be_driver_name[] = "benet"; ++ ++/* ++ * Number of entries in each queue. ++ */ ++#define EVENT_Q_LEN 1024 ++#define ETH_TXQ_LEN 2048 ++#define ETH_TXCQ_LEN 1024 ++#define ETH_RXQ_LEN 1024 /* Does not support any other value */ ++#define ETH_UC_RXCQ_LEN 1024 ++#define ETH_BC_RXCQ_LEN 256 ++#define MCC_Q_LEN 64 /* total size not to exceed 8 pages */ ++#define MCC_CQ_LEN 256 ++ ++/* Bit mask describing events of interest to be traced */ ++unsigned int trace_level; ++ ++static int ++init_pci_be_function(struct be_adapter *adapter, struct pci_dev *pdev) ++{ ++ u64 pa; ++ ++ /* CSR */ ++ pa = pci_resource_start(pdev, 2); ++ adapter->csr_va = ioremap_nocache(pa, pci_resource_len(pdev, 2)); ++ if (adapter->csr_va == NULL) ++ return -ENOMEM; ++ ++ /* Door Bell */ ++ pa = pci_resource_start(pdev, 4); ++ adapter->db_va = ioremap_nocache(pa, (128 * 1024)); ++ if (adapter->db_va == NULL) { ++ iounmap(adapter->csr_va); ++ return -ENOMEM; ++ } ++ ++ /* PCI */ ++ pa = pci_resource_start(pdev, 1); ++ adapter->pci_va = ioremap_nocache(pa, pci_resource_len(pdev, 1)); ++ if (adapter->pci_va == NULL) { ++ iounmap(adapter->csr_va); ++ iounmap(adapter->db_va); ++ return -ENOMEM; ++ } ++ return 0; ++} ++ ++/* ++ This function enables the interrupt corresponding to the Event ++ queue ID for the given NetObject ++*/ ++void be_enable_eq_intr(struct be_net_object *pnob) ++{ ++ struct CQ_DB_AMAP cqdb; ++ cqdb.dw[0] = 0; ++ AMAP_SET_BITS_PTR(CQ_DB, event, &cqdb, 1); ++ AMAP_SET_BITS_PTR(CQ_DB, rearm, &cqdb, 1); ++ AMAP_SET_BITS_PTR(CQ_DB, num_popped, &cqdb, 0); ++ AMAP_SET_BITS_PTR(CQ_DB, qid, &cqdb, pnob->event_q_id); ++ PD_WRITE(&pnob->fn_obj, cq_db, cqdb.dw[0]); ++} ++ ++/* ++ This function disables the interrupt corresponding to the Event ++ queue ID for the given NetObject ++*/ ++void be_disable_eq_intr(struct be_net_object *pnob) ++{ ++ struct CQ_DB_AMAP cqdb; ++ cqdb.dw[0] = 0; ++ AMAP_SET_BITS_PTR(CQ_DB, event, &cqdb, 1); ++ AMAP_SET_BITS_PTR(CQ_DB, rearm, &cqdb, 0); ++ AMAP_SET_BITS_PTR(CQ_DB, num_popped, &cqdb, 0); ++ AMAP_SET_BITS_PTR(CQ_DB, qid, &cqdb, pnob->event_q_id); ++ PD_WRITE(&pnob->fn_obj, cq_db, cqdb.dw[0]); ++} ++ ++/* ++ This function enables the interrupt from the network function ++ of the BladeEngine. Use the function be_disable_eq_intr() ++ to enable the interrupt from the event queue of only one specific ++ NetObject ++*/ ++void be_enable_intr(struct be_net_object *pnob) ++{ ++ struct PCICFG_HOST_TIMER_INT_CTRL_CSR_AMAP ctrl; ++ u32 host_intr; ++ ++ ctrl.dw[0] = PCICFG1_READ(&pnob->fn_obj, host_timer_int_ctrl); ++ host_intr = AMAP_GET_BITS_PTR(PCICFG_HOST_TIMER_INT_CTRL_CSR, ++ hostintr, ctrl.dw); ++ if (!host_intr) { ++ AMAP_SET_BITS_PTR(PCICFG_HOST_TIMER_INT_CTRL_CSR, ++ hostintr, ctrl.dw, 1); ++ PCICFG1_WRITE(&pnob->fn_obj, host_timer_int_ctrl, ++ ctrl.dw[0]); ++ } ++} ++ ++/* ++ This function disables the interrupt from the network function of ++ the BladeEngine. Use the function be_disable_eq_intr() to ++ disable the interrupt from the event queue of only one specific NetObject ++*/ ++void be_disable_intr(struct be_net_object *pnob) ++{ ++ ++ struct PCICFG_HOST_TIMER_INT_CTRL_CSR_AMAP ctrl; ++ u32 host_intr; ++ ctrl.dw[0] = PCICFG1_READ(&pnob->fn_obj, host_timer_int_ctrl); ++ host_intr = AMAP_GET_BITS_PTR(PCICFG_HOST_TIMER_INT_CTRL_CSR, ++ hostintr, ctrl.dw); ++ if (host_intr) { ++ AMAP_SET_BITS_PTR(PCICFG_HOST_TIMER_INT_CTRL_CSR, hostintr, ++ ctrl.dw, 0); ++ PCICFG1_WRITE(&pnob->fn_obj, host_timer_int_ctrl, ++ ctrl.dw[0]); ++ } ++} ++ ++static int be_enable_msix(struct be_adapter *adapter) ++{ ++ int i, ret; ++ ++ if (!msix) ++ return -1; ++ ++ for (i = 0; i < BE_MAX_REQ_MSIX_VECTORS; i++) ++ adapter->msix_entries[i].entry = i; ++ ++ ret = pci_enable_msix(adapter->pdev, adapter->msix_entries, ++ BE_MAX_REQ_MSIX_VECTORS); ++ ++ if (ret == 0) ++ adapter->msix_enabled = 1; ++ return ret; ++} ++ ++static int be_register_isr(struct be_adapter *adapter, ++ struct be_net_object *pnob) ++{ ++ struct net_device *netdev = pnob->netdev; ++ int intx = 0, r; ++ ++ netdev->irq = adapter->pdev->irq; ++ r = be_enable_msix(adapter); ++ ++ if (r == 0) { ++ r = request_irq(adapter->msix_entries[0].vector, ++ be_int, IRQF_SHARED, netdev->name, netdev); ++ if (r) { ++ printk(KERN_WARNING ++ "MSIX Request IRQ failed - Errno %d\n", r); ++ intx = 1; ++ pci_disable_msix(adapter->pdev); ++ adapter->msix_enabled = 0; ++ } ++ } else { ++ intx = 1; ++ } ++ ++ if (intx) { ++ r = request_irq(netdev->irq, be_int, IRQF_SHARED, ++ netdev->name, netdev); ++ if (r) { ++ printk(KERN_WARNING ++ "INTx Request IRQ failed - Errno %d\n", r); ++ return -1; ++ } ++ } ++ adapter->isr_registered = 1; ++ return 0; ++} ++ ++static void be_unregister_isr(struct be_adapter *adapter) ++{ ++ struct net_device *netdev = adapter->netdevp; ++ if (adapter->isr_registered) { ++ if (adapter->msix_enabled) { ++ free_irq(adapter->msix_entries[0].vector, netdev); ++ pci_disable_msix(adapter->pdev); ++ adapter->msix_enabled = 0; ++ } else { ++ free_irq(netdev->irq, netdev); ++ } ++ adapter->isr_registered = 0; ++ } ++} ++ ++/* ++ This function processes the Flush Completions that are issued by the ++ ARM F/W, when a Recv Ring is destroyed. A flush completion is ++ identified when a Rx COmpl descriptor has the tcpcksum and udpcksum ++ set and the pktsize is 32. These completions are received on the ++ Rx Completion Queue. ++*/ ++static u32 be_process_rx_flush_cmpl(struct be_net_object *pnob) ++{ ++ struct ETH_RX_COMPL_AMAP *rxcp; ++ unsigned int i = 0; ++ while ((rxcp = be_get_rx_cmpl(pnob)) != NULL) { ++ be_notify_cmpl(pnob, 1, pnob->rx_cq_id, 1); ++ i++; ++ } ++ return i; ++} ++ ++static void be_tx_q_clean(struct be_net_object *pnob) ++{ ++ while (atomic_read(&pnob->tx_q_used)) ++ process_one_tx_compl(pnob, tx_compl_lastwrb_idx_get(pnob)); ++} ++ ++static void be_rx_q_clean(struct be_net_object *pnob) ++{ ++ if (pnob->rx_ctxt) { ++ int i; ++ struct be_rx_page_info *rx_page_info; ++ for (i = 0; i < pnob->rx_q_len; i++) { ++ rx_page_info = &(pnob->rx_page_info[i]); ++ if (!pnob->rx_pg_shared || rx_page_info->page_offset) { ++ pci_unmap_page(pnob->adapter->pdev, ++ pci_unmap_addr(rx_page_info, bus), ++ pnob->rx_buf_size, ++ PCI_DMA_FROMDEVICE); ++ } ++ if (rx_page_info->page) ++ put_page(rx_page_info->page); ++ memset(rx_page_info, 0, sizeof(struct be_rx_page_info)); ++ } ++ pnob->rx_pg_info_hd = 0; ++ } ++} ++ ++static void be_destroy_netobj(struct be_net_object *pnob) ++{ ++ int status; ++ ++ if (pnob->tx_q_created) { ++ status = be_eth_sq_destroy(&pnob->tx_q_obj); ++ pnob->tx_q_created = 0; ++ } ++ ++ if (pnob->rx_q_created) { ++ status = be_eth_rq_destroy(&pnob->rx_q_obj); ++ if (status != 0) { ++ status = be_eth_rq_destroy_options(&pnob->rx_q_obj, 0, ++ NULL, NULL); ++ BUG_ON(status); ++ } ++ pnob->rx_q_created = 0; ++ } ++ ++ be_process_rx_flush_cmpl(pnob); ++ ++ if (pnob->tx_cq_created) { ++ status = be_cq_destroy(&pnob->tx_cq_obj); ++ pnob->tx_cq_created = 0; ++ } ++ ++ if (pnob->rx_cq_created) { ++ status = be_cq_destroy(&pnob->rx_cq_obj); ++ pnob->rx_cq_created = 0; ++ } ++ ++ if (pnob->mcc_q_created) { ++ status = be_mcc_ring_destroy(&pnob->mcc_q_obj); ++ pnob->mcc_q_created = 0; ++ } ++ if (pnob->mcc_cq_created) { ++ status = be_cq_destroy(&pnob->mcc_cq_obj); ++ pnob->mcc_cq_created = 0; ++ } ++ ++ if (pnob->event_q_created) { ++ status = be_eq_destroy(&pnob->event_q_obj); ++ pnob->event_q_created = 0; ++ } ++ be_function_cleanup(&pnob->fn_obj); ++} ++ ++/* ++ * free all resources associated with a pnob ++ * Called at the time of module cleanup as well a any error during ++ * module init. Some resources may be partially allocated in a NetObj. ++ */ ++static void netobject_cleanup(struct be_adapter *adapter, ++ struct be_net_object *pnob) ++{ ++ struct net_device *netdev = adapter->netdevp; ++ ++ if (netif_running(netdev)) { ++ netif_stop_queue(netdev); ++ be_wait_nic_tx_cmplx_cmpl(pnob); ++ be_disable_eq_intr(pnob); ++ } ++ ++ be_unregister_isr(adapter); ++ ++ if (adapter->tasklet_started) { ++ tasklet_kill(&(adapter->sts_handler)); ++ adapter->tasklet_started = 0; ++ } ++ if (pnob->fn_obj_created) ++ be_disable_intr(pnob); ++ ++ if (adapter->dev_state != BE_DEV_STATE_NONE) ++ unregister_netdev(netdev); ++ ++ if (pnob->fn_obj_created) ++ be_destroy_netobj(pnob); ++ ++ adapter->net_obj = NULL; ++ adapter->netdevp = NULL; ++ ++ be_rx_q_clean(pnob); ++ if (pnob->rx_ctxt) { ++ kfree(pnob->rx_page_info); ++ kfree(pnob->rx_ctxt); ++ } ++ ++ be_tx_q_clean(pnob); ++ kfree(pnob->tx_ctxt); ++ ++ if (pnob->mcc_q) ++ pci_free_consistent(adapter->pdev, pnob->mcc_q_size, ++ pnob->mcc_q, pnob->mcc_q_bus); ++ ++ if (pnob->mcc_wrb_ctxt) ++ free_pages((unsigned long)pnob->mcc_wrb_ctxt, ++ get_order(pnob->mcc_wrb_ctxt_size)); ++ ++ if (pnob->mcc_cq) ++ pci_free_consistent(adapter->pdev, pnob->mcc_cq_size, ++ pnob->mcc_cq, pnob->mcc_cq_bus); ++ ++ if (pnob->event_q) ++ pci_free_consistent(adapter->pdev, pnob->event_q_size, ++ pnob->event_q, pnob->event_q_bus); ++ ++ if (pnob->tx_cq) ++ pci_free_consistent(adapter->pdev, pnob->tx_cq_size, ++ pnob->tx_cq, pnob->tx_cq_bus); ++ ++ if (pnob->tx_q) ++ pci_free_consistent(adapter->pdev, pnob->tx_q_size, ++ pnob->tx_q, pnob->tx_q_bus); ++ ++ if (pnob->rx_q) ++ pci_free_consistent(adapter->pdev, pnob->rx_q_size, ++ pnob->rx_q, pnob->rx_q_bus); ++ ++ if (pnob->rx_cq) ++ pci_free_consistent(adapter->pdev, pnob->rx_cq_size, ++ pnob->rx_cq, pnob->rx_cq_bus); ++ ++ ++ if (pnob->mb_ptr) ++ pci_free_consistent(adapter->pdev, pnob->mb_size, pnob->mb_ptr, ++ pnob->mb_bus); ++ ++ free_netdev(netdev); ++} ++ ++ ++static int be_nob_ring_alloc(struct be_adapter *adapter, ++ struct be_net_object *pnob) ++{ ++ u32 size; ++ ++ /* Mail box rd; mailbox pointer needs to be 16 byte aligned */ ++ pnob->mb_size = sizeof(struct MCC_MAILBOX_AMAP) + 16; ++ pnob->mb_ptr = pci_alloc_consistent(adapter->pdev, pnob->mb_size, ++ &pnob->mb_bus); ++ if (!pnob->mb_bus) ++ return -1; ++ memset(pnob->mb_ptr, 0, pnob->mb_size); ++ pnob->mb_rd.va = PTR_ALIGN(pnob->mb_ptr, 16); ++ pnob->mb_rd.pa = PTR_ALIGN(pnob->mb_bus, 16); ++ pnob->mb_rd.length = sizeof(struct MCC_MAILBOX_AMAP); ++ /* ++ * Event queue ++ */ ++ pnob->event_q_len = EVENT_Q_LEN; ++ pnob->event_q_size = pnob->event_q_len * sizeof(struct EQ_ENTRY_AMAP); ++ pnob->event_q = pci_alloc_consistent(adapter->pdev, pnob->event_q_size, ++ &pnob->event_q_bus); ++ if (!pnob->event_q_bus) ++ return -1; ++ memset(pnob->event_q, 0, pnob->event_q_size); ++ /* ++ * Eth TX queue ++ */ ++ pnob->tx_q_len = ETH_TXQ_LEN; ++ pnob->tx_q_port = 0; ++ pnob->tx_q_size = pnob->tx_q_len * sizeof(struct ETH_WRB_AMAP); ++ pnob->tx_q = pci_alloc_consistent(adapter->pdev, pnob->tx_q_size, ++ &pnob->tx_q_bus); ++ if (!pnob->tx_q_bus) ++ return -1; ++ memset(pnob->tx_q, 0, pnob->tx_q_size); ++ /* ++ * Eth TX Compl queue ++ */ ++ pnob->txcq_len = ETH_TXCQ_LEN; ++ pnob->tx_cq_size = pnob->txcq_len * sizeof(struct ETH_TX_COMPL_AMAP); ++ pnob->tx_cq = pci_alloc_consistent(adapter->pdev, pnob->tx_cq_size, ++ &pnob->tx_cq_bus); ++ if (!pnob->tx_cq_bus) ++ return -1; ++ memset(pnob->tx_cq, 0, pnob->tx_cq_size); ++ /* ++ * Eth RX queue ++ */ ++ pnob->rx_q_len = ETH_RXQ_LEN; ++ pnob->rx_q_size = pnob->rx_q_len * sizeof(struct ETH_RX_D_AMAP); ++ pnob->rx_q = pci_alloc_consistent(adapter->pdev, pnob->rx_q_size, ++ &pnob->rx_q_bus); ++ if (!pnob->rx_q_bus) ++ return -1; ++ memset(pnob->rx_q, 0, pnob->rx_q_size); ++ /* ++ * Eth Unicast RX Compl queue ++ */ ++ pnob->rx_cq_len = ETH_UC_RXCQ_LEN; ++ pnob->rx_cq_size = pnob->rx_cq_len * ++ sizeof(struct ETH_RX_COMPL_AMAP); ++ pnob->rx_cq = pci_alloc_consistent(adapter->pdev, pnob->rx_cq_size, ++ &pnob->rx_cq_bus); ++ if (!pnob->rx_cq_bus) ++ return -1; ++ memset(pnob->rx_cq, 0, pnob->rx_cq_size); ++ ++ /* TX resources */ ++ size = pnob->tx_q_len * sizeof(void **); ++ pnob->tx_ctxt = kzalloc(size, GFP_KERNEL); ++ if (pnob->tx_ctxt == NULL) ++ return -1; ++ ++ /* RX resources */ ++ size = pnob->rx_q_len * sizeof(void *); ++ pnob->rx_ctxt = kzalloc(size, GFP_KERNEL); ++ if (pnob->rx_ctxt == NULL) ++ return -1; ++ ++ size = (pnob->rx_q_len * sizeof(struct be_rx_page_info)); ++ pnob->rx_page_info = kzalloc(size, GFP_KERNEL); ++ if (pnob->rx_page_info == NULL) ++ return -1; ++ ++ adapter->eth_statsp = kzalloc(sizeof(struct FWCMD_ETH_GET_STATISTICS), ++ GFP_KERNEL); ++ if (adapter->eth_statsp == NULL) ++ return -1; ++ pnob->rx_buf_size = rxbuf_size; ++ return 0; ++} ++ ++/* ++ This function initializes the be_net_object for subsequent ++ network operations. ++ ++ Before calling this function, the driver must have allocated ++ space for the NetObject structure, initialized the structure, ++ allocated DMAable memory for all the network queues that form ++ part of the NetObject and populated the start address (virtual) ++ and number of entries allocated for each queue in the NetObject structure. ++ ++ The driver must also have allocated memory to hold the ++ mailbox structure (MCC_MAILBOX) and post the physical address, ++ virtual addresses and the size of the mailbox memory in the ++ NetObj.mb_rd. This structure is used by BECLIB for ++ initial communication with the embedded MCC processor. BECLIB ++ uses the mailbox until MCC rings are created for more efficient ++ communication with the MCC processor. ++ ++ If the driver wants to create multiple network interface for more ++ than one protection domain, it can call be_create_netobj() ++ multiple times once for each protection domain. A Maximum of ++ 32 protection domains are supported. ++ ++*/ ++static int ++be_create_netobj(struct be_net_object *pnob, u8 __iomem *csr_va, ++ u8 __iomem *db_va, u8 __iomem *pci_va) ++{ ++ int status = 0; ++ bool eventable = false, tx_no_delay = false, rx_no_delay = false; ++ struct be_eq_object *eq_objectp = NULL; ++ struct be_function_object *pfob = &pnob->fn_obj; ++ struct ring_desc rd; ++ u32 set_rxbuf_size; ++ u32 tx_cmpl_wm = CEV_WMARK_96; /* 0xffffffff to disable */ ++ u32 rx_cmpl_wm = CEV_WMARK_160; /* 0xffffffff to disable */ ++ u32 eq_delay = 0; /* delay in 8usec units. 0xffffffff to disable */ ++ ++ memset(&rd, 0, sizeof(struct ring_desc)); ++ ++ status = be_function_object_create(csr_va, db_va, pci_va, ++ BE_FUNCTION_TYPE_NETWORK, &pnob->mb_rd, pfob); ++ if (status != BE_SUCCESS) ++ return status; ++ pnob->fn_obj_created = true; ++ ++ if (tx_cmpl_wm == 0xffffffff) ++ tx_no_delay = true; ++ if (rx_cmpl_wm == 0xffffffff) ++ rx_no_delay = true; ++ /* ++ * now create the necessary rings ++ * Event Queue first. ++ */ ++ if (pnob->event_q_len) { ++ rd.va = pnob->event_q; ++ rd.pa = pnob->event_q_bus; ++ rd.length = pnob->event_q_size; ++ ++ status = be_eq_create(pfob, &rd, 4, pnob->event_q_len, ++ (u32) -1, /* CEV_WMARK_* or -1 */ ++ eq_delay, /* in 8us units, or -1 */ ++ &pnob->event_q_obj); ++ if (status != BE_SUCCESS) ++ goto error_ret; ++ pnob->event_q_id = pnob->event_q_obj.eq_id; ++ pnob->event_q_created = 1; ++ eventable = true; ++ eq_objectp = &pnob->event_q_obj; ++ } ++ /* ++ * Now Eth Tx Compl. queue. ++ */ ++ if (pnob->txcq_len) { ++ rd.va = pnob->tx_cq; ++ rd.pa = pnob->tx_cq_bus; ++ rd.length = pnob->tx_cq_size; ++ ++ status = be_cq_create(pfob, &rd, ++ pnob->txcq_len * sizeof(struct ETH_TX_COMPL_AMAP), ++ false, /* solicted events, */ ++ tx_no_delay, /* nodelay */ ++ tx_cmpl_wm, /* Watermark encodings */ ++ eq_objectp, &pnob->tx_cq_obj); ++ if (status != BE_SUCCESS) ++ goto error_ret; ++ ++ pnob->tx_cq_id = pnob->tx_cq_obj.cq_id; ++ pnob->tx_cq_created = 1; ++ } ++ /* ++ * Eth Tx queue ++ */ ++ if (pnob->tx_q_len) { ++ struct be_eth_sq_parameters ex_params = { 0 }; ++ u32 type; ++ ++ if (pnob->tx_q_port) { ++ /* TXQ to be bound to a specific port */ ++ type = BE_ETH_TX_RING_TYPE_BOUND; ++ ex_params.port = pnob->tx_q_port - 1; ++ } else ++ type = BE_ETH_TX_RING_TYPE_STANDARD; ++ ++ rd.va = pnob->tx_q; ++ rd.pa = pnob->tx_q_bus; ++ rd.length = pnob->tx_q_size; ++ ++ status = be_eth_sq_create_ex(pfob, &rd, ++ pnob->tx_q_len * sizeof(struct ETH_WRB_AMAP), ++ type, 2, &pnob->tx_cq_obj, ++ &ex_params, &pnob->tx_q_obj); ++ ++ if (status != BE_SUCCESS) ++ goto error_ret; ++ ++ pnob->tx_q_id = pnob->tx_q_obj.bid; ++ pnob->tx_q_created = 1; ++ } ++ /* ++ * Now Eth Rx compl. queue. Always needed. ++ */ ++ rd.va = pnob->rx_cq; ++ rd.pa = pnob->rx_cq_bus; ++ rd.length = pnob->rx_cq_size; ++ ++ status = be_cq_create(pfob, &rd, ++ pnob->rx_cq_len * sizeof(struct ETH_RX_COMPL_AMAP), ++ false, /* solicted events, */ ++ rx_no_delay, /* nodelay */ ++ rx_cmpl_wm, /* Watermark encodings */ ++ eq_objectp, &pnob->rx_cq_obj); ++ if (status != BE_SUCCESS) ++ goto error_ret; ++ ++ pnob->rx_cq_id = pnob->rx_cq_obj.cq_id; ++ pnob->rx_cq_created = 1; ++ ++ status = be_eth_rq_set_frag_size(pfob, pnob->rx_buf_size, ++ (u32 *) &set_rxbuf_size); ++ if (status != BE_SUCCESS) { ++ be_eth_rq_get_frag_size(pfob, (u32 *) &pnob->rx_buf_size); ++ if ((pnob->rx_buf_size != 2048) && (pnob->rx_buf_size != 4096) ++ && (pnob->rx_buf_size != 8192)) ++ goto error_ret; ++ } else { ++ if (pnob->rx_buf_size != set_rxbuf_size) ++ pnob->rx_buf_size = set_rxbuf_size; ++ } ++ /* ++ * Eth RX queue. be_eth_rq_create() always assumes 2 pages size ++ */ ++ rd.va = pnob->rx_q; ++ rd.pa = pnob->rx_q_bus; ++ rd.length = pnob->rx_q_size; ++ ++ status = be_eth_rq_create(pfob, &rd, &pnob->rx_cq_obj, ++ &pnob->rx_cq_obj, &pnob->rx_q_obj); ++ ++ if (status != BE_SUCCESS) ++ goto error_ret; ++ ++ pnob->rx_q_id = pnob->rx_q_obj.rid; ++ pnob->rx_q_created = 1; ++ ++ return BE_SUCCESS; /* All required queues created. */ ++ ++error_ret: ++ be_destroy_netobj(pnob); ++ return status; ++} ++ ++static int be_nob_ring_init(struct be_adapter *adapter, ++ struct be_net_object *pnob) ++{ ++ int status; ++ ++ pnob->event_q_tl = 0; ++ ++ pnob->tx_q_hd = 0; ++ pnob->tx_q_tl = 0; ++ ++ pnob->tx_cq_tl = 0; ++ ++ pnob->rx_cq_tl = 0; ++ ++ memset(pnob->event_q, 0, pnob->event_q_size); ++ memset(pnob->tx_cq, 0, pnob->tx_cq_size); ++ memset(pnob->tx_ctxt, 0, pnob->tx_q_len * sizeof(void **)); ++ memset(pnob->rx_ctxt, 0, pnob->rx_q_len * sizeof(void *)); ++ pnob->rx_pg_info_hd = 0; ++ pnob->rx_q_hd = 0; ++ atomic_set(&pnob->rx_q_posted, 0); ++ ++ status = be_create_netobj(pnob, adapter->csr_va, adapter->db_va, ++ adapter->pci_va); ++ if (status != BE_SUCCESS) ++ return -1; ++ ++ be_post_eth_rx_buffs(pnob); ++ return 0; ++} ++ ++/* This function handles async callback for link status */ ++static void ++be_link_status_async_callback(void *context, u32 event_code, void *event) ++{ ++ struct ASYNC_EVENT_LINK_STATE_AMAP *link_status = event; ++ struct be_adapter *adapter = context; ++ bool link_enable = false; ++ struct be_net_object *pnob; ++ struct ASYNC_EVENT_TRAILER_AMAP *async_trailer; ++ struct net_device *netdev; ++ u32 async_event_code, async_event_type, active_port; ++ u32 port0_link_status, port1_link_status, port0_duplex, port1_duplex; ++ u32 port0_speed, port1_speed; ++ ++ if (event_code != ASYNC_EVENT_CODE_LINK_STATE) { ++ /* Not our event to handle */ ++ return; ++ } ++ async_trailer = (struct ASYNC_EVENT_TRAILER_AMAP *) ++ ((u8 *) event + sizeof(struct MCC_CQ_ENTRY_AMAP) - ++ sizeof(struct ASYNC_EVENT_TRAILER_AMAP)); ++ ++ async_event_code = AMAP_GET_BITS_PTR(ASYNC_EVENT_TRAILER, event_code, ++ async_trailer); ++ BUG_ON(async_event_code != ASYNC_EVENT_CODE_LINK_STATE); ++ ++ pnob = adapter->net_obj; ++ netdev = pnob->netdev; ++ ++ /* Determine if this event is a switch VLD or a physical link event */ ++ async_event_type = AMAP_GET_BITS_PTR(ASYNC_EVENT_TRAILER, event_type, ++ async_trailer); ++ active_port = AMAP_GET_BITS_PTR(ASYNC_EVENT_LINK_STATE, ++ active_port, link_status); ++ port0_link_status = AMAP_GET_BITS_PTR(ASYNC_EVENT_LINK_STATE, ++ port0_link_status, link_status); ++ port1_link_status = AMAP_GET_BITS_PTR(ASYNC_EVENT_LINK_STATE, ++ port1_link_status, link_status); ++ port0_duplex = AMAP_GET_BITS_PTR(ASYNC_EVENT_LINK_STATE, ++ port0_duplex, link_status); ++ port1_duplex = AMAP_GET_BITS_PTR(ASYNC_EVENT_LINK_STATE, ++ port1_duplex, link_status); ++ port0_speed = AMAP_GET_BITS_PTR(ASYNC_EVENT_LINK_STATE, ++ port0_speed, link_status); ++ port1_speed = AMAP_GET_BITS_PTR(ASYNC_EVENT_LINK_STATE, ++ port1_speed, link_status); ++ if (async_event_type == NTWK_LINK_TYPE_VIRTUAL) { ++ adapter->be_stat.bes_link_change_virtual++; ++ if (adapter->be_link_sts->active_port != active_port) { ++ dev_notice(&netdev->dev, ++ "Active port changed due to VLD on switch\n"); ++ } else { ++ dev_notice(&netdev->dev, "Link status update\n"); ++ } ++ ++ } else { ++ adapter->be_stat.bes_link_change_physical++; ++ if (adapter->be_link_sts->active_port != active_port) { ++ dev_notice(&netdev->dev, ++ "Active port changed due to port link" ++ " status change\n"); ++ } else { ++ dev_notice(&netdev->dev, "Link status update\n"); ++ } ++ } ++ ++ memset(adapter->be_link_sts, 0, sizeof(adapter->be_link_sts)); ++ ++ if ((port0_link_status == ASYNC_EVENT_LINK_UP) || ++ (port1_link_status == ASYNC_EVENT_LINK_UP)) { ++ if ((adapter->port0_link_sts == BE_PORT_LINK_DOWN) && ++ (adapter->port1_link_sts == BE_PORT_LINK_DOWN)) { ++ /* Earlier both the ports are down So link is up */ ++ link_enable = true; ++ } ++ ++ if (port0_link_status == ASYNC_EVENT_LINK_UP) { ++ adapter->port0_link_sts = BE_PORT_LINK_UP; ++ adapter->be_link_sts->mac0_duplex = port0_duplex; ++ adapter->be_link_sts->mac0_speed = port0_speed; ++ if (active_port == NTWK_PORT_A) ++ adapter->be_link_sts->active_port = 0; ++ } else ++ adapter->port0_link_sts = BE_PORT_LINK_DOWN; ++ ++ if (port1_link_status == ASYNC_EVENT_LINK_UP) { ++ adapter->port1_link_sts = BE_PORT_LINK_UP; ++ adapter->be_link_sts->mac1_duplex = port1_duplex; ++ adapter->be_link_sts->mac1_speed = port1_speed; ++ if (active_port == NTWK_PORT_B) ++ adapter->be_link_sts->active_port = 1; ++ } else ++ adapter->port1_link_sts = BE_PORT_LINK_DOWN; ++ ++ printk(KERN_INFO "Link Properties for %s:\n", netdev->name); ++ dev_info(&netdev->dev, "Link Properties:\n"); ++ be_print_link_info(adapter->be_link_sts); ++ ++ if (!link_enable) ++ return; ++ /* ++ * Both ports were down previously, but atleast one of ++ * them has come up if this netdevice's carrier is not up, ++ * then indicate to stack ++ */ ++ if (!netif_carrier_ok(netdev)) { ++ netif_start_queue(netdev); ++ netif_carrier_on(netdev); ++ } ++ return; ++ } ++ ++ /* Now both the ports are down. Tell the stack about it */ ++ dev_info(&netdev->dev, "Both ports are down\n"); ++ adapter->port0_link_sts = BE_PORT_LINK_DOWN; ++ adapter->port1_link_sts = BE_PORT_LINK_DOWN; ++ if (netif_carrier_ok(netdev)) { ++ netif_carrier_off(netdev); ++ netif_stop_queue(netdev); ++ } ++ return; ++} ++ ++static int be_mcc_create(struct be_adapter *adapter) ++{ ++ struct be_net_object *pnob; ++ ++ pnob = adapter->net_obj; ++ /* ++ * Create the MCC ring so that all further communication with ++ * MCC can go thru the ring. we do this at the end since ++ * we do not want to be dealing with interrupts until the ++ * initialization is complete. ++ */ ++ pnob->mcc_q_len = MCC_Q_LEN; ++ pnob->mcc_q_size = pnob->mcc_q_len * sizeof(struct MCC_WRB_AMAP); ++ pnob->mcc_q = pci_alloc_consistent(adapter->pdev, pnob->mcc_q_size, ++ &pnob->mcc_q_bus); ++ if (!pnob->mcc_q_bus) ++ return -1; ++ /* ++ * space for MCC WRB context ++ */ ++ pnob->mcc_wrb_ctxtLen = MCC_Q_LEN; ++ pnob->mcc_wrb_ctxt_size = pnob->mcc_wrb_ctxtLen * ++ sizeof(struct be_mcc_wrb_context); ++ pnob->mcc_wrb_ctxt = (void *)__get_free_pages(GFP_KERNEL, ++ get_order(pnob->mcc_wrb_ctxt_size)); ++ if (pnob->mcc_wrb_ctxt == NULL) ++ return -1; ++ /* ++ * Space for MCC compl. ring ++ */ ++ pnob->mcc_cq_len = MCC_CQ_LEN; ++ pnob->mcc_cq_size = pnob->mcc_cq_len * sizeof(struct MCC_CQ_ENTRY_AMAP); ++ pnob->mcc_cq = pci_alloc_consistent(adapter->pdev, pnob->mcc_cq_size, ++ &pnob->mcc_cq_bus); ++ if (!pnob->mcc_cq_bus) ++ return -1; ++ return 0; ++} ++ ++/* ++ This function creates the MCC request and completion ring required ++ for communicating with the ARM processor. The caller must have ++ allocated required amount of memory for the MCC ring and MCC ++ completion ring and posted the virtual address and number of ++ entries in the corresponding members (mcc_q and mcc_cq) in the ++ NetObject struture. ++ ++ When this call is completed, all further communication with ++ ARM will switch from mailbox to this ring. ++ ++ pnob - Pointer to the NetObject structure. This NetObject should ++ have been created using a previous call to be_create_netobj() ++*/ ++int be_create_mcc_rings(struct be_net_object *pnob) ++{ ++ int status = 0; ++ struct ring_desc rd; ++ struct be_function_object *pfob = &pnob->fn_obj; ++ ++ memset(&rd, 0, sizeof(struct ring_desc)); ++ if (pnob->mcc_cq_len) { ++ rd.va = pnob->mcc_cq; ++ rd.pa = pnob->mcc_cq_bus; ++ rd.length = pnob->mcc_cq_size; ++ ++ status = be_cq_create(pfob, &rd, ++ pnob->mcc_cq_len * sizeof(struct MCC_CQ_ENTRY_AMAP), ++ false, /* solicted events, */ ++ true, /* nodelay */ ++ 0, /* 0 Watermark since Nodelay is true */ ++ &pnob->event_q_obj, ++ &pnob->mcc_cq_obj); ++ ++ if (status != BE_SUCCESS) ++ return status; ++ ++ pnob->mcc_cq_id = pnob->mcc_cq_obj.cq_id; ++ pnob->mcc_cq_created = 1; ++ } ++ if (pnob->mcc_q_len) { ++ rd.va = pnob->mcc_q; ++ rd.pa = pnob->mcc_q_bus; ++ rd.length = pnob->mcc_q_size; ++ ++ status = be_mcc_ring_create(pfob, &rd, ++ pnob->mcc_q_len * sizeof(struct MCC_WRB_AMAP), ++ pnob->mcc_wrb_ctxt, pnob->mcc_wrb_ctxtLen, ++ &pnob->mcc_cq_obj, &pnob->mcc_q_obj); ++ ++ if (status != BE_SUCCESS) ++ return status; ++ ++ pnob->mcc_q_created = 1; ++ } ++ return BE_SUCCESS; ++} ++ ++static int be_mcc_init(struct be_adapter *adapter) ++{ ++ u32 r; ++ struct be_net_object *pnob; ++ ++ pnob = adapter->net_obj; ++ memset(pnob->mcc_q, 0, pnob->mcc_q_size); ++ pnob->mcc_q_hd = 0; ++ ++ memset(pnob->mcc_wrb_ctxt, 0, pnob->mcc_wrb_ctxt_size); ++ ++ memset(pnob->mcc_cq, 0, pnob->mcc_cq_size); ++ pnob->mcc_cq_tl = 0; ++ ++ r = be_create_mcc_rings(adapter->net_obj); ++ if (r != BE_SUCCESS) ++ return -1; ++ ++ return 0; ++} ++ ++static void be_remove(struct pci_dev *pdev) ++{ ++ struct be_net_object *pnob; ++ struct be_adapter *adapter; ++ ++ adapter = pci_get_drvdata(pdev); ++ if (!adapter) ++ return; ++ ++ pci_set_drvdata(pdev, NULL); ++ pnob = (struct be_net_object *)adapter->net_obj; ++ ++ flush_scheduled_work(); ++ ++ if (pnob) { ++ /* Unregister async callback function for link status updates */ ++ if (pnob->mcc_q_created) ++ be_mcc_add_async_event_callback(&pnob->mcc_q_obj, ++ NULL, NULL); ++ netobject_cleanup(adapter, pnob); ++ } ++ ++ if (adapter->csr_va) ++ iounmap(adapter->csr_va); ++ if (adapter->db_va) ++ iounmap(adapter->db_va); ++ if (adapter->pci_va) ++ iounmap(adapter->pci_va); ++ ++ pci_release_regions(adapter->pdev); ++ pci_disable_device(adapter->pdev); ++ ++ kfree(adapter->be_link_sts); ++ kfree(adapter->eth_statsp); ++ ++ if (adapter->timer_ctxt.get_stats_timer.function) ++ del_timer_sync(&adapter->timer_ctxt.get_stats_timer); ++ kfree(adapter); ++} ++ ++/* ++ * This function is called by the PCI sub-system when it finds a PCI ++ * device with dev/vendor IDs that match with one of our devices. ++ * All of the driver initialization is done in this function. ++ */ ++static int be_probe(struct pci_dev *pdev, const struct pci_device_id *pdev_id) ++{ ++ int status = 0; ++ struct be_adapter *adapter; ++ struct FWCMD_COMMON_GET_FW_VERSION_RESPONSE_PAYLOAD get_fwv; ++ struct be_net_object *pnob; ++ struct net_device *netdev; ++ ++ status = pci_enable_device(pdev); ++ if (status) ++ goto error; ++ ++ status = pci_request_regions(pdev, be_driver_name); ++ if (status) ++ goto error_pci_req; ++ ++ pci_set_master(pdev); ++ adapter = kzalloc(sizeof(struct be_adapter), GFP_KERNEL); ++ if (adapter == NULL) { ++ status = -ENOMEM; ++ goto error_adapter; ++ } ++ adapter->dev_state = BE_DEV_STATE_NONE; ++ adapter->pdev = pdev; ++ pci_set_drvdata(pdev, adapter); ++ ++ adapter->enable_aic = 1; ++ adapter->max_eqd = MAX_EQD; ++ adapter->min_eqd = 0; ++ adapter->cur_eqd = 0; ++ ++ status = pci_set_dma_mask(pdev, DMA_64BIT_MASK); ++ if (!status) { ++ adapter->dma_64bit_cap = true; ++ } else { ++ adapter->dma_64bit_cap = false; ++ status = pci_set_dma_mask(pdev, DMA_32BIT_MASK); ++ if (status != 0) { ++ printk(KERN_ERR "Could not set PCI DMA Mask\n"); ++ goto cleanup; ++ } ++ } ++ ++ status = init_pci_be_function(adapter, pdev); ++ if (status != 0) { ++ printk(KERN_ERR "Failed to map PCI BARS\n"); ++ status = -ENOMEM; ++ goto cleanup; ++ } ++ ++ be_trace_set_level(DL_ALWAYS | DL_ERR); ++ ++ adapter->be_link_sts = kmalloc(sizeof(struct BE_LINK_STATUS), ++ GFP_KERNEL); ++ if (adapter->be_link_sts == NULL) { ++ printk(KERN_ERR "Memory allocation for link status " ++ "buffer failed\n"); ++ goto cleanup; ++ } ++ spin_lock_init(&adapter->txq_lock); ++ ++ netdev = alloc_etherdev(sizeof(struct be_net_object)); ++ if (netdev == NULL) { ++ status = -ENOMEM; ++ goto cleanup; ++ } ++ pnob = netdev_priv(netdev); ++ adapter->net_obj = pnob; ++ adapter->netdevp = netdev; ++ pnob->adapter = adapter; ++ pnob->netdev = netdev; ++ ++ status = be_nob_ring_alloc(adapter, pnob); ++ if (status != 0) ++ goto cleanup; ++ ++ status = be_nob_ring_init(adapter, pnob); ++ if (status != 0) ++ goto cleanup; ++ ++ be_rxf_mac_address_read_write(&pnob->fn_obj, false, false, false, ++ false, false, netdev->dev_addr, NULL, NULL); ++ ++ netdev->init = &benet_init; ++ netif_carrier_off(netdev); ++ netif_stop_queue(netdev); ++ ++ SET_NETDEV_DEV(netdev, &(adapter->pdev->dev)); ++ ++ netif_napi_add(netdev, &pnob->napi, be_poll, 64); ++ ++ /* if the rx_frag size if 2K, one page is shared as two RX frags */ ++ pnob->rx_pg_shared = ++ (pnob->rx_buf_size <= PAGE_SIZE / 2) ? true : false; ++ if (pnob->rx_buf_size != rxbuf_size) { ++ printk(KERN_WARNING ++ "Could not set Rx buffer size to %d. Using %d\n", ++ rxbuf_size, pnob->rx_buf_size); ++ rxbuf_size = pnob->rx_buf_size; ++ } ++ ++ tasklet_init(&(adapter->sts_handler), be_process_intr, ++ (unsigned long)adapter); ++ adapter->tasklet_started = 1; ++ spin_lock_init(&(adapter->int_lock)); ++ ++ status = be_register_isr(adapter, pnob); ++ if (status != 0) ++ goto cleanup; ++ ++ adapter->rx_csum = 1; ++ adapter->max_rx_coal = BE_LRO_MAX_PKTS; ++ ++ memset(&get_fwv, 0, ++ sizeof(struct FWCMD_COMMON_GET_FW_VERSION_RESPONSE_PAYLOAD)); ++ printk(KERN_INFO "BladeEngine Driver version:%s. " ++ "Copyright ServerEngines, Corporation 2005 - 2008\n", ++ be_drvr_ver); ++ status = be_function_get_fw_version(&pnob->fn_obj, &get_fwv, NULL, ++ NULL); ++ if (status == BE_SUCCESS) { ++ strncpy(be_fw_ver, get_fwv.firmware_version_string, 32); ++ printk(KERN_INFO "BladeEngine Firmware Version:%s\n", ++ get_fwv.firmware_version_string); ++ } else { ++ printk(KERN_WARNING "Unable to get BE Firmware Version\n"); ++ } ++ ++ sema_init(&adapter->get_eth_stat_sem, 0); ++ init_timer(&adapter->timer_ctxt.get_stats_timer); ++ atomic_set(&adapter->timer_ctxt.get_stat_flag, 0); ++ adapter->timer_ctxt.get_stats_timer.function = ++ &be_get_stats_timer_handler; ++ ++ status = be_mcc_create(adapter); ++ if (status < 0) ++ goto cleanup; ++ status = be_mcc_init(adapter); ++ if (status < 0) ++ goto cleanup; ++ ++ ++ status = be_mcc_add_async_event_callback(&adapter->net_obj->mcc_q_obj, ++ be_link_status_async_callback, (void *)adapter); ++ if (status != BE_SUCCESS) { ++ printk(KERN_WARNING "add_async_event_callback failed"); ++ printk(KERN_WARNING ++ "Link status changes may not be reflected\n"); ++ } ++ ++ status = register_netdev(netdev); ++ if (status != 0) ++ goto cleanup; ++ be_update_link_status(adapter); ++ adapter->dev_state = BE_DEV_STATE_INIT; ++ return 0; ++ ++cleanup: ++ be_remove(pdev); ++ return status; ++error_adapter: ++ pci_release_regions(pdev); ++error_pci_req: ++ pci_disable_device(pdev); ++error: ++ printk(KERN_ERR "BladeEngine initalization failed\n"); ++ return status; ++} ++ ++/* ++ * Get the current link status and print the status on console ++ */ ++void be_update_link_status(struct be_adapter *adapter) ++{ ++ int status; ++ struct be_net_object *pnob = adapter->net_obj; ++ ++ status = be_rxf_link_status(&pnob->fn_obj, adapter->be_link_sts, NULL, ++ NULL, NULL); ++ if (status == BE_SUCCESS) { ++ if (adapter->be_link_sts->mac0_speed && ++ adapter->be_link_sts->mac0_duplex) ++ adapter->port0_link_sts = BE_PORT_LINK_UP; ++ else ++ adapter->port0_link_sts = BE_PORT_LINK_DOWN; ++ ++ if (adapter->be_link_sts->mac1_speed && ++ adapter->be_link_sts->mac1_duplex) ++ adapter->port1_link_sts = BE_PORT_LINK_UP; ++ else ++ adapter->port1_link_sts = BE_PORT_LINK_DOWN; ++ ++ dev_info(&pnob->netdev->dev, "Link Properties:\n"); ++ be_print_link_info(adapter->be_link_sts); ++ return; ++ } ++ dev_info(&pnob->netdev->dev, "Could not get link status\n"); ++ return; ++} ++ ++ ++#ifdef CONFIG_PM ++static void ++be_pm_cleanup(struct be_adapter *adapter, ++ struct be_net_object *pnob, struct net_device *netdev) ++{ ++ netif_carrier_off(netdev); ++ netif_stop_queue(netdev); ++ ++ be_wait_nic_tx_cmplx_cmpl(pnob); ++ be_disable_eq_intr(pnob); ++ ++ if (adapter->tasklet_started) { ++ tasklet_kill(&adapter->sts_handler); ++ adapter->tasklet_started = 0; ++ } ++ ++ be_unregister_isr(adapter); ++ be_disable_intr(pnob); ++ ++ be_tx_q_clean(pnob); ++ be_rx_q_clean(pnob); ++ ++ be_destroy_netobj(pnob); ++} ++ ++static int be_suspend(struct pci_dev *pdev, pm_message_t state) ++{ ++ struct be_adapter *adapter = pci_get_drvdata(pdev); ++ struct net_device *netdev = adapter->netdevp; ++ struct be_net_object *pnob = netdev_priv(netdev); ++ ++ adapter->dev_pm_state = adapter->dev_state; ++ adapter->dev_state = BE_DEV_STATE_SUSPEND; ++ ++ netif_device_detach(netdev); ++ if (netif_running(netdev)) ++ be_pm_cleanup(adapter, pnob, netdev); ++ ++ pci_enable_wake(pdev, 3, 1); ++ pci_enable_wake(pdev, 4, 1); /* D3 Cold = 4 */ ++ pci_save_state(pdev); ++ pci_disable_device(pdev); ++ pci_set_power_state(pdev, pci_choose_state(pdev, state)); ++ return 0; ++} ++ ++static void be_up(struct be_adapter *adapter) ++{ ++ struct be_net_object *pnob = adapter->net_obj; ++ ++ if (pnob->num_vlans != 0) ++ be_rxf_vlan_config(&pnob->fn_obj, false, pnob->num_vlans, ++ pnob->vlan_tag, NULL, NULL, NULL); ++ ++} ++ ++static int be_resume(struct pci_dev *pdev) ++{ ++ int status = 0; ++ struct be_adapter *adapter = pci_get_drvdata(pdev); ++ struct net_device *netdev = adapter->netdevp; ++ struct be_net_object *pnob = netdev_priv(netdev); ++ ++ netif_device_detach(netdev); ++ ++ status = pci_enable_device(pdev); ++ if (status) ++ return status; ++ ++ pci_set_power_state(pdev, 0); ++ pci_restore_state(pdev); ++ pci_enable_wake(pdev, 3, 0); ++ pci_enable_wake(pdev, 4, 0); /* 4 is D3 cold */ ++ ++ netif_carrier_on(netdev); ++ netif_start_queue(netdev); ++ ++ if (netif_running(netdev)) { ++ be_rxf_mac_address_read_write(&pnob->fn_obj, false, false, ++ false, true, false, netdev->dev_addr, NULL, NULL); ++ ++ status = be_nob_ring_init(adapter, pnob); ++ if (status < 0) ++ return status; ++ ++ tasklet_init(&(adapter->sts_handler), be_process_intr, ++ (unsigned long)adapter); ++ adapter->tasklet_started = 1; ++ ++ if (be_register_isr(adapter, pnob) != 0) { ++ printk(KERN_ERR "be_register_isr failed\n"); ++ return status; ++ } ++ ++ ++ status = be_mcc_init(adapter); ++ if (status < 0) { ++ printk(KERN_ERR "be_mcc_init failed\n"); ++ return status; ++ } ++ be_update_link_status(adapter); ++ /* ++ * Register async call back function to handle link ++ * status updates ++ */ ++ status = be_mcc_add_async_event_callback( ++ &adapter->net_obj->mcc_q_obj, ++ be_link_status_async_callback, (void *)adapter); ++ if (status != BE_SUCCESS) { ++ printk(KERN_WARNING "add_async_event_callback failed"); ++ printk(KERN_WARNING ++ "Link status changes may not be reflected\n"); ++ } ++ be_enable_intr(pnob); ++ be_enable_eq_intr(pnob); ++ be_up(adapter); ++ } ++ netif_device_attach(netdev); ++ adapter->dev_state = adapter->dev_pm_state; ++ return 0; ++ ++} ++ ++#endif ++ ++/* Wait until no more pending transmits */ ++void be_wait_nic_tx_cmplx_cmpl(struct be_net_object *pnob) ++{ ++ int i; ++ ++ /* Wait for 20us * 50000 (= 1s) and no more */ ++ i = 0; ++ while ((pnob->tx_q_tl != pnob->tx_q_hd) && (i < 50000)) { ++ ++i; ++ udelay(20); ++ } ++ ++ /* Check for no more pending transmits */ ++ if (i >= 50000) { ++ printk(KERN_WARNING ++ "Did not receive completions for all TX requests\n"); ++ } ++} ++ ++static struct pci_driver be_driver = { ++ .name = be_driver_name, ++ .id_table = be_device_id_table, ++ .probe = be_probe, ++#ifdef CONFIG_PM ++ .suspend = be_suspend, ++ .resume = be_resume, ++#endif ++ .remove = be_remove ++}; ++ ++/* ++ * Module init entry point. Registers our our device and return. ++ * Our probe will be called if the device is found. ++ */ ++static int __init be_init_module(void) ++{ ++ int ret; ++ ++ if (rxbuf_size != 8192 && rxbuf_size != 4096 && rxbuf_size != 2048) { ++ printk(KERN_WARNING ++ "Unsupported receive buffer size (%d) requested\n", ++ rxbuf_size); ++ printk(KERN_WARNING ++ "Must be 2048, 4096 or 8192. Defaulting to 2048\n"); ++ rxbuf_size = 2048; ++ } ++ ++ ret = pci_register_driver(&be_driver); ++ ++ return ret; ++} ++ ++module_init(be_init_module); ++ ++/* ++ * be_exit_module - Driver Exit Cleanup Routine ++ */ ++static void __exit be_exit_module(void) ++{ ++ pci_unregister_driver(&be_driver); ++} ++ ++module_exit(be_exit_module); +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/drivers/staging/benet/be_int.c linux-2.6.29-rc3.owrt/drivers/staging/benet/be_int.c +--- linux-2.6.29.owrt/drivers/staging/benet/be_int.c 1970-01-01 01:00:00.000000000 +0100 ++++ linux-2.6.29-rc3.owrt/drivers/staging/benet/be_int.c 2009-05-10 23:48:29.000000000 +0200 +@@ -0,0 +1,863 @@ ++/* ++ * Copyright (C) 2005 - 2008 ServerEngines ++ * All rights reserved. ++ * ++ * 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. The full GNU General ++ * Public License is included in this distribution in the file called COPYING. ++ * ++ * Contact Information: ++ * linux-drivers@serverengines.com ++ * ++ * ServerEngines ++ * 209 N. Fair Oaks Ave ++ * Sunnyvale, CA 94085 ++ */ ++#include <linux/if_vlan.h> ++#include <linux/inet_lro.h> ++ ++#include "benet.h" ++ ++/* number of bytes of RX frame that are copied to skb->data */ ++#define BE_HDR_LEN 64 ++ ++#define NETIF_RX(skb) netif_receive_skb(skb) ++#define VLAN_ACCEL_RX(skb, pnob, vt) \ ++ vlan_hwaccel_rx(skb, pnob->vlan_grp, vt) ++ ++/* ++ This function notifies BladeEngine of the number of completion ++ entries processed from the specified completion queue by writing ++ the number of popped entries to the door bell. ++ ++ pnob - Pointer to the NetObject structure ++ n - Number of completion entries processed ++ cq_id - Queue ID of the completion queue for which notification ++ is being done. ++ re_arm - 1 - rearm the completion ring to generate an event. ++ - 0 - dont rearm the completion ring to generate an event ++*/ ++void be_notify_cmpl(struct be_net_object *pnob, int n, int cq_id, int re_arm) ++{ ++ struct CQ_DB_AMAP cqdb; ++ ++ cqdb.dw[0] = 0; ++ AMAP_SET_BITS_PTR(CQ_DB, qid, &cqdb, cq_id); ++ AMAP_SET_BITS_PTR(CQ_DB, rearm, &cqdb, re_arm); ++ AMAP_SET_BITS_PTR(CQ_DB, num_popped, &cqdb, n); ++ PD_WRITE(&pnob->fn_obj, cq_db, cqdb.dw[0]); ++} ++ ++/* ++ * adds additional receive frags indicated by BE starting from given ++ * frag index (fi) to specified skb's frag list ++ */ ++static void ++add_skb_frags(struct be_net_object *pnob, struct sk_buff *skb, ++ u32 nresid, u32 fi) ++{ ++ struct be_adapter *adapter = pnob->adapter; ++ u32 sk_frag_idx, n; ++ struct be_rx_page_info *rx_page_info; ++ u32 frag_sz = pnob->rx_buf_size; ++ ++ sk_frag_idx = skb_shinfo(skb)->nr_frags; ++ while (nresid) { ++ index_inc(&fi, pnob->rx_q_len); ++ ++ rx_page_info = (struct be_rx_page_info *)pnob->rx_ctxt[fi]; ++ pnob->rx_ctxt[fi] = NULL; ++ if ((rx_page_info->page_offset) || ++ (pnob->rx_pg_shared == false)) { ++ pci_unmap_page(adapter->pdev, ++ pci_unmap_addr(rx_page_info, bus), ++ frag_sz, PCI_DMA_FROMDEVICE); ++ } ++ ++ n = min(nresid, frag_sz); ++ skb_shinfo(skb)->frags[sk_frag_idx].page = rx_page_info->page; ++ skb_shinfo(skb)->frags[sk_frag_idx].page_offset ++ = rx_page_info->page_offset; ++ skb_shinfo(skb)->frags[sk_frag_idx].size = n; ++ ++ sk_frag_idx++; ++ skb->len += n; ++ skb->data_len += n; ++ skb_shinfo(skb)->nr_frags++; ++ nresid -= n; ++ ++ memset(rx_page_info, 0, sizeof(struct be_rx_page_info)); ++ atomic_dec(&pnob->rx_q_posted); ++ } ++} ++ ++/* ++ * This function processes incoming nic packets over various Rx queues. ++ * This function takes the adapter, the current Rx status descriptor ++ * entry and the Rx completion queue ID as argument. ++ */ ++static inline int process_nic_rx_completion(struct be_net_object *pnob, ++ struct ETH_RX_COMPL_AMAP *rxcp) ++{ ++ struct be_adapter *adapter = pnob->adapter; ++ struct sk_buff *skb; ++ int udpcksm, tcpcksm; ++ int n; ++ u32 nresid, fi; ++ u32 frag_sz = pnob->rx_buf_size; ++ u8 *va; ++ struct be_rx_page_info *rx_page_info; ++ u32 numfrags, vtp, vtm, vlan_tag, pktsize; ++ ++ fi = AMAP_GET_BITS_PTR(ETH_RX_COMPL, fragndx, rxcp); ++ BUG_ON(fi >= (int)pnob->rx_q_len); ++ BUG_ON(fi < 0); ++ ++ rx_page_info = (struct be_rx_page_info *)pnob->rx_ctxt[fi]; ++ BUG_ON(!rx_page_info->page); ++ pnob->rx_ctxt[fi] = NULL; ++ ++ /* ++ * If one page is used per fragment or if this is the second half of ++ * of the page, unmap the page here ++ */ ++ if ((rx_page_info->page_offset) || (pnob->rx_pg_shared == false)) { ++ pci_unmap_page(adapter->pdev, ++ pci_unmap_addr(rx_page_info, bus), frag_sz, ++ PCI_DMA_FROMDEVICE); ++ } ++ ++ atomic_dec(&pnob->rx_q_posted); ++ udpcksm = AMAP_GET_BITS_PTR(ETH_RX_COMPL, udpcksm, rxcp); ++ tcpcksm = AMAP_GET_BITS_PTR(ETH_RX_COMPL, tcpcksm, rxcp); ++ pktsize = AMAP_GET_BITS_PTR(ETH_RX_COMPL, pktsize, rxcp); ++ /* ++ * get rid of RX flush completions first. ++ */ ++ if ((tcpcksm) && (udpcksm) && (pktsize == 32)) { ++ put_page(rx_page_info->page); ++ memset(rx_page_info, 0, sizeof(struct be_rx_page_info)); ++ return 0; ++ } ++ skb = netdev_alloc_skb(pnob->netdev, BE_HDR_LEN + NET_IP_ALIGN); ++ if (skb == NULL) { ++ dev_info(&pnob->netdev->dev, "alloc_skb() failed\n"); ++ put_page(rx_page_info->page); ++ memset(rx_page_info, 0, sizeof(struct be_rx_page_info)); ++ goto free_frags; ++ } ++ skb_reserve(skb, NET_IP_ALIGN); ++ ++ skb->dev = pnob->netdev; ++ ++ n = min(pktsize, frag_sz); ++ ++ va = page_address(rx_page_info->page) + rx_page_info->page_offset; ++ prefetch(va); ++ ++ skb->len = n; ++ skb->data_len = n; ++ if (n <= BE_HDR_LEN) { ++ memcpy(skb->data, va, n); ++ put_page(rx_page_info->page); ++ skb->data_len -= n; ++ skb->tail += n; ++ } else { ++ ++ /* Setup the SKB with page buffer information */ ++ skb_shinfo(skb)->frags[0].page = rx_page_info->page; ++ skb_shinfo(skb)->nr_frags++; ++ ++ /* Copy the header into the skb_data */ ++ memcpy(skb->data, va, BE_HDR_LEN); ++ skb_shinfo(skb)->frags[0].page_offset = ++ rx_page_info->page_offset + BE_HDR_LEN; ++ skb_shinfo(skb)->frags[0].size = n - BE_HDR_LEN; ++ skb->data_len -= BE_HDR_LEN; ++ skb->tail += BE_HDR_LEN; ++ } ++ memset(rx_page_info, 0, sizeof(struct be_rx_page_info)); ++ nresid = pktsize - n; ++ ++ skb->protocol = eth_type_trans(skb, pnob->netdev); ++ ++ if ((tcpcksm || udpcksm) && adapter->rx_csum) ++ skb->ip_summed = CHECKSUM_UNNECESSARY; ++ else ++ skb->ip_summed = CHECKSUM_NONE; ++ /* ++ * if we have more bytes left, the frame has been ++ * given to us in multiple fragments. This happens ++ * with Jumbo frames. Add the remaining fragments to ++ * skb->frags[] array. ++ */ ++ if (nresid) ++ add_skb_frags(pnob, skb, nresid, fi); ++ ++ /* update the the true size of the skb. */ ++ skb->truesize = skb->len + sizeof(struct sk_buff); ++ ++ /* ++ * If a 802.3 frame or 802.2 LLC frame ++ * (i.e) contains length field in MAC Hdr ++ * and frame len is greater than 64 bytes ++ */ ++ if (((skb->protocol == ntohs(ETH_P_802_2)) || ++ (skb->protocol == ntohs(ETH_P_802_3))) ++ && (pktsize > BE_HDR_LEN)) { ++ /* ++ * If the length given in Mac Hdr is less than frame size ++ * Erraneous frame, Drop it ++ */ ++ if ((ntohs(*(u16 *) (va + 12)) + ETH_HLEN) < pktsize) { ++ /* Increment Non Ether type II frames dropped */ ++ adapter->be_stat.bes_802_3_dropped_frames++; ++ ++ kfree_skb(skb); ++ return 0; ++ } ++ /* ++ * else if the length given in Mac Hdr is greater than ++ * frame size, should not be seeing this sort of frames ++ * dump the pkt and pass to stack ++ */ ++ else if ((ntohs(*(u16 *) (va + 12)) + ETH_HLEN) > pktsize) { ++ /* Increment Non Ether type II frames malformed */ ++ adapter->be_stat.bes_802_3_malformed_frames++; ++ } ++ } ++ ++ vtp = AMAP_GET_BITS_PTR(ETH_RX_COMPL, vtp, rxcp); ++ vtm = AMAP_GET_BITS_PTR(ETH_RX_COMPL, vtm, rxcp); ++ if (vtp && vtm) { ++ /* Vlan tag present in pkt and BE found ++ * that the tag matched an entry in VLAN table ++ */ ++ if (!pnob->vlan_grp || pnob->num_vlans == 0) { ++ /* But we have no VLANs configured. ++ * This should never happen. Drop the packet. ++ */ ++ dev_info(&pnob->netdev->dev, ++ "BladeEngine: Unexpected vlan tagged packet\n"); ++ kfree_skb(skb); ++ return 0; ++ } ++ /* pass the VLAN packet to stack */ ++ vlan_tag = AMAP_GET_BITS_PTR(ETH_RX_COMPL, vlan_tag, rxcp); ++ VLAN_ACCEL_RX(skb, pnob, be16_to_cpu(vlan_tag)); ++ ++ } else { ++ NETIF_RX(skb); ++ } ++ return 0; ++ ++free_frags: ++ /* free all frags associated with the current rxcp */ ++ numfrags = AMAP_GET_BITS_PTR(ETH_RX_COMPL, numfrags, rxcp); ++ while (numfrags-- > 1) { ++ index_inc(&fi, pnob->rx_q_len); ++ ++ rx_page_info = (struct be_rx_page_info *) ++ pnob->rx_ctxt[fi]; ++ pnob->rx_ctxt[fi] = (void *)NULL; ++ if (rx_page_info->page_offset || !pnob->rx_pg_shared) { ++ pci_unmap_page(adapter->pdev, ++ pci_unmap_addr(rx_page_info, bus), ++ frag_sz, PCI_DMA_FROMDEVICE); ++ } ++ ++ put_page(rx_page_info->page); ++ memset(rx_page_info, 0, sizeof(struct be_rx_page_info)); ++ atomic_dec(&pnob->rx_q_posted); ++ } ++ return -ENOMEM; ++} ++ ++static void process_nic_rx_completion_lro(struct be_net_object *pnob, ++ struct ETH_RX_COMPL_AMAP *rxcp) ++{ ++ struct be_adapter *adapter = pnob->adapter; ++ struct skb_frag_struct rx_frags[BE_MAX_FRAGS_PER_FRAME]; ++ unsigned int udpcksm, tcpcksm; ++ u32 numfrags, vlanf, vtm, vlan_tag, nresid; ++ u16 vlant; ++ unsigned int fi, idx, n; ++ struct be_rx_page_info *rx_page_info; ++ u32 frag_sz = pnob->rx_buf_size, pktsize; ++ bool rx_coal = (adapter->max_rx_coal <= 1) ? 0 : 1; ++ u8 err, *va; ++ __wsum csum = 0; ++ ++ if (AMAP_GET_BITS_PTR(ETH_RX_COMPL, ipsec, rxcp)) { ++ /* Drop the pkt and move to the next completion. */ ++ adapter->be_stat.bes_rx_misc_pkts++; ++ return; ++ } ++ err = AMAP_GET_BITS_PTR(ETH_RX_COMPL, err, rxcp); ++ if (err || !rx_coal) { ++ /* We won't coalesce Rx pkts if the err bit set. ++ * take the path of normal completion processing */ ++ process_nic_rx_completion(pnob, rxcp); ++ return; ++ } ++ ++ fi = AMAP_GET_BITS_PTR(ETH_RX_COMPL, fragndx, rxcp); ++ BUG_ON(fi >= (int)pnob->rx_q_len); ++ BUG_ON(fi < 0); ++ rx_page_info = (struct be_rx_page_info *)pnob->rx_ctxt[fi]; ++ BUG_ON(!rx_page_info->page); ++ pnob->rx_ctxt[fi] = (void *)NULL; ++ /* If one page is used per fragment or if this is the ++ * second half of the page, unmap the page here ++ */ ++ if (rx_page_info->page_offset || !pnob->rx_pg_shared) { ++ pci_unmap_page(adapter->pdev, ++ pci_unmap_addr(rx_page_info, bus), ++ frag_sz, PCI_DMA_FROMDEVICE); ++ } ++ ++ numfrags = AMAP_GET_BITS_PTR(ETH_RX_COMPL, numfrags, rxcp); ++ udpcksm = AMAP_GET_BITS_PTR(ETH_RX_COMPL, udpcksm, rxcp); ++ tcpcksm = AMAP_GET_BITS_PTR(ETH_RX_COMPL, tcpcksm, rxcp); ++ vlan_tag = AMAP_GET_BITS_PTR(ETH_RX_COMPL, vlan_tag, rxcp); ++ vlant = be16_to_cpu(vlan_tag); ++ vlanf = AMAP_GET_BITS_PTR(ETH_RX_COMPL, vtp, rxcp); ++ vtm = AMAP_GET_BITS_PTR(ETH_RX_COMPL, vtm, rxcp); ++ pktsize = AMAP_GET_BITS_PTR(ETH_RX_COMPL, pktsize, rxcp); ++ ++ atomic_dec(&pnob->rx_q_posted); ++ ++ if (tcpcksm && udpcksm && pktsize == 32) { ++ /* flush completion entries */ ++ put_page(rx_page_info->page); ++ memset(rx_page_info, 0, sizeof(struct be_rx_page_info)); ++ return; ++ } ++ /* Only one of udpcksum and tcpcksum can be set */ ++ BUG_ON(udpcksm && tcpcksm); ++ ++ /* jumbo frames could come in multiple fragments */ ++ BUG_ON(numfrags != ((pktsize + (frag_sz - 1)) / frag_sz)); ++ n = min(pktsize, frag_sz); ++ nresid = pktsize - n; /* will be useful for jumbo pkts */ ++ idx = 0; ++ ++ va = page_address(rx_page_info->page) + rx_page_info->page_offset; ++ prefetch(va); ++ rx_frags[idx].page = rx_page_info->page; ++ rx_frags[idx].page_offset = (rx_page_info->page_offset); ++ rx_frags[idx].size = n; ++ memset(rx_page_info, 0, sizeof(struct be_rx_page_info)); ++ ++ /* If we got multiple fragments, we have more data. */ ++ while (nresid) { ++ idx++; ++ index_inc(&fi, pnob->rx_q_len); ++ ++ rx_page_info = (struct be_rx_page_info *)pnob->rx_ctxt[fi]; ++ pnob->rx_ctxt[fi] = (void *)NULL; ++ if (rx_page_info->page_offset || !pnob->rx_pg_shared) { ++ pci_unmap_page(adapter->pdev, ++ pci_unmap_addr(rx_page_info, bus), ++ frag_sz, PCI_DMA_FROMDEVICE); ++ } ++ ++ n = min(nresid, frag_sz); ++ rx_frags[idx].page = rx_page_info->page; ++ rx_frags[idx].page_offset = (rx_page_info->page_offset); ++ rx_frags[idx].size = n; ++ ++ nresid -= n; ++ memset(rx_page_info, 0, sizeof(struct be_rx_page_info)); ++ atomic_dec(&pnob->rx_q_posted); ++ } ++ ++ if (likely(!(vlanf && vtm))) { ++ lro_receive_frags(&pnob->lro_mgr, rx_frags, ++ pktsize, pktsize, ++ (void *)(unsigned long)csum, csum); ++ } else { ++ /* Vlan tag present in pkt and BE found ++ * that the tag matched an entry in VLAN table ++ */ ++ if (unlikely(!pnob->vlan_grp || pnob->num_vlans == 0)) { ++ /* But we have no VLANs configured. ++ * This should never happen. Drop the packet. ++ */ ++ dev_info(&pnob->netdev->dev, ++ "BladeEngine: Unexpected vlan tagged packet\n"); ++ return; ++ } ++ /* pass the VLAN packet to stack */ ++ lro_vlan_hwaccel_receive_frags(&pnob->lro_mgr, ++ rx_frags, pktsize, pktsize, ++ pnob->vlan_grp, vlant, ++ (void *)(unsigned long)csum, ++ csum); ++ } ++ ++ adapter->be_stat.bes_rx_coal++; ++} ++ ++struct ETH_RX_COMPL_AMAP *be_get_rx_cmpl(struct be_net_object *pnob) ++{ ++ struct ETH_RX_COMPL_AMAP *rxcp = &pnob->rx_cq[pnob->rx_cq_tl]; ++ u32 valid, ct; ++ ++ valid = AMAP_GET_BITS_PTR(ETH_RX_COMPL, valid, rxcp); ++ if (valid == 0) ++ return NULL; ++ ++ ct = AMAP_GET_BITS_PTR(ETH_RX_COMPL, ct, rxcp); ++ if (ct != 0) { ++ /* Invalid chute #. treat as error */ ++ AMAP_SET_BITS_PTR(ETH_RX_COMPL, err, rxcp, 1); ++ } ++ ++ be_adv_rxcq_tl(pnob); ++ AMAP_SET_BITS_PTR(ETH_RX_COMPL, valid, rxcp, 0); ++ return rxcp; ++} ++ ++static void update_rx_rate(struct be_adapter *adapter) ++{ ++ /* update the rate once in two seconds */ ++ if ((jiffies - adapter->eth_rx_jiffies) > 2 * (HZ)) { ++ u32 r; ++ r = adapter->eth_rx_bytes / ++ ((jiffies - adapter->eth_rx_jiffies) / (HZ)); ++ r = (r / 1000000); /* MB/Sec */ ++ ++ /* Mega Bits/Sec */ ++ adapter->be_stat.bes_eth_rx_rate = (r * 8); ++ adapter->eth_rx_jiffies = jiffies; ++ adapter->eth_rx_bytes = 0; ++ } ++} ++ ++static int process_rx_completions(struct be_net_object *pnob, int max_work) ++{ ++ struct be_adapter *adapter = pnob->adapter; ++ struct ETH_RX_COMPL_AMAP *rxcp; ++ u32 nc = 0; ++ unsigned int pktsize; ++ ++ while (max_work && (rxcp = be_get_rx_cmpl(pnob))) { ++ prefetch(rxcp); ++ pktsize = AMAP_GET_BITS_PTR(ETH_RX_COMPL, pktsize, rxcp); ++ process_nic_rx_completion_lro(pnob, rxcp); ++ adapter->eth_rx_bytes += pktsize; ++ update_rx_rate(adapter); ++ nc++; ++ max_work--; ++ adapter->be_stat.bes_rx_compl++; ++ } ++ if (likely(adapter->max_rx_coal > 1)) { ++ adapter->be_stat.bes_rx_flush++; ++ lro_flush_all(&pnob->lro_mgr); ++ } ++ ++ /* Refill the queue */ ++ if (atomic_read(&pnob->rx_q_posted) < 900) ++ be_post_eth_rx_buffs(pnob); ++ ++ return nc; ++} ++ ++static struct ETH_TX_COMPL_AMAP *be_get_tx_cmpl(struct be_net_object *pnob) ++{ ++ struct ETH_TX_COMPL_AMAP *txcp = &pnob->tx_cq[pnob->tx_cq_tl]; ++ u32 valid; ++ ++ valid = AMAP_GET_BITS_PTR(ETH_TX_COMPL, valid, txcp); ++ if (valid == 0) ++ return NULL; ++ ++ AMAP_SET_BITS_PTR(ETH_TX_COMPL, valid, txcp, 0); ++ be_adv_txcq_tl(pnob); ++ return txcp; ++ ++} ++ ++void process_one_tx_compl(struct be_net_object *pnob, u32 end_idx) ++{ ++ struct be_adapter *adapter = pnob->adapter; ++ int cur_index, tx_wrbs_completed = 0; ++ struct sk_buff *skb; ++ u64 busaddr, pa, pa_lo, pa_hi; ++ struct ETH_WRB_AMAP *wrb; ++ u32 frag_len, last_index, j; ++ ++ last_index = tx_compl_lastwrb_idx_get(pnob); ++ BUG_ON(last_index != end_idx); ++ pnob->tx_ctxt[pnob->tx_q_tl] = NULL; ++ do { ++ cur_index = pnob->tx_q_tl; ++ wrb = &pnob->tx_q[cur_index]; ++ pa_hi = AMAP_GET_BITS_PTR(ETH_WRB, frag_pa_hi, wrb); ++ pa_lo = AMAP_GET_BITS_PTR(ETH_WRB, frag_pa_lo, wrb); ++ frag_len = AMAP_GET_BITS_PTR(ETH_WRB, frag_len, wrb); ++ busaddr = (pa_hi << 32) | pa_lo; ++ if (busaddr != 0) { ++ pa = le64_to_cpu(busaddr); ++ pci_unmap_single(adapter->pdev, pa, ++ frag_len, PCI_DMA_TODEVICE); ++ } ++ if (cur_index == last_index) { ++ skb = (struct sk_buff *)pnob->tx_ctxt[cur_index]; ++ BUG_ON(!skb); ++ for (j = 0; j < skb_shinfo(skb)->nr_frags; j++) { ++ struct skb_frag_struct *frag; ++ frag = &skb_shinfo(skb)->frags[j]; ++ pci_unmap_page(adapter->pdev, ++ (ulong) frag->page, frag->size, ++ PCI_DMA_TODEVICE); ++ } ++ kfree_skb(skb); ++ pnob->tx_ctxt[cur_index] = NULL; ++ } else { ++ BUG_ON(pnob->tx_ctxt[cur_index]); ++ } ++ tx_wrbs_completed++; ++ be_adv_txq_tl(pnob); ++ } while (cur_index != last_index); ++ atomic_sub(tx_wrbs_completed, &pnob->tx_q_used); ++} ++ ++/* there is no need to take an SMP lock here since currently ++ * we have only one instance of the tasklet that does completion ++ * processing. ++ */ ++static void process_nic_tx_completions(struct be_net_object *pnob) ++{ ++ struct be_adapter *adapter = pnob->adapter; ++ struct ETH_TX_COMPL_AMAP *txcp; ++ struct net_device *netdev = pnob->netdev; ++ u32 end_idx, num_processed = 0; ++ ++ adapter->be_stat.bes_tx_events++; ++ ++ while ((txcp = be_get_tx_cmpl(pnob))) { ++ end_idx = AMAP_GET_BITS_PTR(ETH_TX_COMPL, wrb_index, txcp); ++ process_one_tx_compl(pnob, end_idx); ++ num_processed++; ++ adapter->be_stat.bes_tx_compl++; ++ } ++ be_notify_cmpl(pnob, num_processed, pnob->tx_cq_id, 1); ++ /* ++ * We got Tx completions and have usable WRBs. ++ * If the netdev's queue has been stopped ++ * because we had run out of WRBs, wake it now. ++ */ ++ spin_lock(&adapter->txq_lock); ++ if (netif_queue_stopped(netdev) ++ && atomic_read(&pnob->tx_q_used) < pnob->tx_q_len / 2) { ++ netif_wake_queue(netdev); ++ } ++ spin_unlock(&adapter->txq_lock); ++} ++ ++static u32 post_rx_buffs(struct be_net_object *pnob, struct list_head *rxbl) ++{ ++ u32 nposted = 0; ++ struct ETH_RX_D_AMAP *rxd = NULL; ++ struct be_recv_buffer *rxbp; ++ void **rx_ctxp; ++ struct RQ_DB_AMAP rqdb; ++ ++ rx_ctxp = pnob->rx_ctxt; ++ ++ while (!list_empty(rxbl) && ++ (rx_ctxp[pnob->rx_q_hd] == NULL) && nposted < 255) { ++ ++ rxbp = list_first_entry(rxbl, struct be_recv_buffer, rxb_list); ++ list_del(&rxbp->rxb_list); ++ rxd = pnob->rx_q + pnob->rx_q_hd; ++ AMAP_SET_BITS_PTR(ETH_RX_D, fragpa_lo, rxd, rxbp->rxb_pa_lo); ++ AMAP_SET_BITS_PTR(ETH_RX_D, fragpa_hi, rxd, rxbp->rxb_pa_hi); ++ ++ rx_ctxp[pnob->rx_q_hd] = rxbp->rxb_ctxt; ++ be_adv_rxq_hd(pnob); ++ nposted++; ++ } ++ ++ if (nposted) { ++ /* Now press the door bell to notify BladeEngine. */ ++ rqdb.dw[0] = 0; ++ AMAP_SET_BITS_PTR(RQ_DB, numPosted, &rqdb, nposted); ++ AMAP_SET_BITS_PTR(RQ_DB, rq, &rqdb, pnob->rx_q_id); ++ PD_WRITE(&pnob->fn_obj, erx_rq_db, rqdb.dw[0]); ++ } ++ atomic_add(nposted, &pnob->rx_q_posted); ++ return nposted; ++} ++ ++void be_post_eth_rx_buffs(struct be_net_object *pnob) ++{ ++ struct be_adapter *adapter = pnob->adapter; ++ u32 num_bufs, r; ++ u64 busaddr = 0, tmp_pa; ++ u32 max_bufs, pg_hd; ++ u32 frag_size; ++ struct be_recv_buffer *rxbp; ++ struct list_head rxbl; ++ struct be_rx_page_info *rx_page_info; ++ struct page *page = NULL; ++ u32 page_order = 0; ++ gfp_t alloc_flags = GFP_ATOMIC; ++ ++ BUG_ON(!adapter); ++ ++ max_bufs = 64; /* should be even # <= 255. */ ++ ++ frag_size = pnob->rx_buf_size; ++ page_order = get_order(frag_size); ++ ++ if (frag_size == 8192) ++ alloc_flags |= (gfp_t) __GFP_COMP; ++ /* ++ * Form a linked list of RECV_BUFFFER structure to be be posted. ++ * We will post even number of buffer so that pages can be ++ * shared. ++ */ ++ INIT_LIST_HEAD(&rxbl); ++ ++ for (num_bufs = 0; num_bufs < max_bufs && ++ !pnob->rx_page_info[pnob->rx_pg_info_hd].page; ++num_bufs) { ++ ++ rxbp = &pnob->eth_rx_bufs[num_bufs]; ++ pg_hd = pnob->rx_pg_info_hd; ++ rx_page_info = &pnob->rx_page_info[pg_hd]; ++ ++ if (!page) { ++ page = alloc_pages(alloc_flags, page_order); ++ if (unlikely(page == NULL)) { ++ adapter->be_stat.bes_ethrx_post_fail++; ++ pnob->rxbuf_post_fail++; ++ break; ++ } ++ pnob->rxbuf_post_fail = 0; ++ busaddr = pci_map_page(adapter->pdev, page, 0, ++ frag_size, PCI_DMA_FROMDEVICE); ++ rx_page_info->page_offset = 0; ++ rx_page_info->page = page; ++ /* ++ * If we are sharing a page among two skbs, ++ * alloc a new one on the next iteration ++ */ ++ if (pnob->rx_pg_shared == false) ++ page = NULL; ++ } else { ++ get_page(page); ++ rx_page_info->page_offset += frag_size; ++ rx_page_info->page = page; ++ /* ++ * We are finished with the alloced page, ++ * Alloc a new one on the next iteration ++ */ ++ page = NULL; ++ } ++ rxbp->rxb_ctxt = (void *)rx_page_info; ++ index_inc(&pnob->rx_pg_info_hd, pnob->rx_q_len); ++ ++ pci_unmap_addr_set(rx_page_info, bus, busaddr); ++ tmp_pa = busaddr + rx_page_info->page_offset; ++ rxbp->rxb_pa_lo = (tmp_pa & 0xFFFFFFFF); ++ rxbp->rxb_pa_hi = (tmp_pa >> 32); ++ rxbp->rxb_len = frag_size; ++ list_add_tail(&rxbp->rxb_list, &rxbl); ++ } /* End of for */ ++ ++ r = post_rx_buffs(pnob, &rxbl); ++ BUG_ON(r != num_bufs); ++ return; ++} ++ ++/* ++ * Interrupt service for network function. We just schedule the ++ * tasklet which does all completion processing. ++ */ ++irqreturn_t be_int(int irq, void *dev) ++{ ++ struct net_device *netdev = dev; ++ struct be_net_object *pnob = netdev_priv(netdev); ++ struct be_adapter *adapter = pnob->adapter; ++ u32 isr; ++ ++ isr = CSR_READ(&pnob->fn_obj, cev.isr1); ++ if (unlikely(!isr)) ++ return IRQ_NONE; ++ ++ spin_lock(&adapter->int_lock); ++ adapter->isr |= isr; ++ spin_unlock(&adapter->int_lock); ++ ++ adapter->be_stat.bes_ints++; ++ ++ tasklet_schedule(&adapter->sts_handler); ++ return IRQ_HANDLED; ++} ++ ++/* ++ * Poll function called by NAPI with a work budget. ++ * We process as many UC. BC and MC receive completions ++ * as the budget allows and return the actual number of ++ * RX ststutses processed. ++ */ ++int be_poll(struct napi_struct *napi, int budget) ++{ ++ struct be_net_object *pnob = ++ container_of(napi, struct be_net_object, napi); ++ u32 work_done; ++ ++ pnob->adapter->be_stat.bes_polls++; ++ work_done = process_rx_completions(pnob, budget); ++ BUG_ON(work_done > budget); ++ ++ /* All consumed */ ++ if (work_done < budget) { ++ netif_rx_complete(napi); ++ /* enable intr */ ++ be_notify_cmpl(pnob, work_done, pnob->rx_cq_id, 1); ++ } else { ++ /* More to be consumed; continue with interrupts disabled */ ++ be_notify_cmpl(pnob, work_done, pnob->rx_cq_id, 0); ++ } ++ return work_done; ++} ++ ++static struct EQ_ENTRY_AMAP *get_event(struct be_net_object *pnob) ++{ ++ struct EQ_ENTRY_AMAP *eqp = &(pnob->event_q[pnob->event_q_tl]); ++ if (!AMAP_GET_BITS_PTR(EQ_ENTRY, Valid, eqp)) ++ return NULL; ++ be_adv_eq_tl(pnob); ++ return eqp; ++} ++ ++/* ++ * Processes all valid events in the event ring associated with given ++ * NetObject. Also, notifies BE the number of events processed. ++ */ ++static inline u32 process_events(struct be_net_object *pnob) ++{ ++ struct be_adapter *adapter = pnob->adapter; ++ struct EQ_ENTRY_AMAP *eqp; ++ u32 rid, num_events = 0; ++ struct net_device *netdev = pnob->netdev; ++ ++ while ((eqp = get_event(pnob)) != NULL) { ++ adapter->be_stat.bes_events++; ++ rid = AMAP_GET_BITS_PTR(EQ_ENTRY, ResourceID, eqp); ++ if (rid == pnob->rx_cq_id) { ++ adapter->be_stat.bes_rx_events++; ++ netif_rx_schedule(&pnob->napi); ++ } else if (rid == pnob->tx_cq_id) { ++ process_nic_tx_completions(pnob); ++ } else if (rid == pnob->mcc_cq_id) { ++ be_mcc_process_cq(&pnob->mcc_q_obj, 1); ++ } else { ++ dev_info(&netdev->dev, ++ "Invalid EQ ResourceID %d\n", rid); ++ } ++ AMAP_SET_BITS_PTR(EQ_ENTRY, Valid, eqp, 0); ++ AMAP_SET_BITS_PTR(EQ_ENTRY, ResourceID, eqp, 0); ++ num_events++; ++ } ++ return num_events; ++} ++ ++static void update_eqd(struct be_adapter *adapter, struct be_net_object *pnob) ++{ ++ int status; ++ struct be_eq_object *eq_objectp; ++ ++ /* update once a second */ ++ if ((jiffies - adapter->ips_jiffies) > 1 * (HZ)) { ++ /* One second elapsed since last update */ ++ u32 r, new_eqd = -1; ++ r = adapter->be_stat.bes_ints - adapter->be_stat.bes_prev_ints; ++ r = r / ((jiffies - adapter->ips_jiffies) / (HZ)); ++ adapter->be_stat.bes_ips = r; ++ adapter->ips_jiffies = jiffies; ++ adapter->be_stat.bes_prev_ints = adapter->be_stat.bes_ints; ++ if (r > IPS_HI_WM && adapter->cur_eqd < adapter->max_eqd) ++ new_eqd = (adapter->cur_eqd + 8); ++ if (r < IPS_LO_WM && adapter->cur_eqd > adapter->min_eqd) ++ new_eqd = (adapter->cur_eqd - 8); ++ if (adapter->enable_aic && new_eqd != -1) { ++ eq_objectp = &pnob->event_q_obj; ++ status = be_eq_modify_delay(&pnob->fn_obj, 1, ++ &eq_objectp, &new_eqd, NULL, ++ NULL, NULL); ++ if (status == BE_SUCCESS) ++ adapter->cur_eqd = new_eqd; ++ } ++ } ++} ++ ++/* ++ This function notifies BladeEngine of how many events were processed ++ from the event queue by ringing the corresponding door bell and ++ optionally re-arms the event queue. ++ n - number of events processed ++ re_arm - 1 - re-arm the EQ, 0 - do not re-arm the EQ ++ ++*/ ++static void be_notify_event(struct be_net_object *pnob, int n, int re_arm) ++{ ++ struct CQ_DB_AMAP eqdb; ++ eqdb.dw[0] = 0; ++ ++ AMAP_SET_BITS_PTR(CQ_DB, qid, &eqdb, pnob->event_q_id); ++ AMAP_SET_BITS_PTR(CQ_DB, rearm, &eqdb, re_arm); ++ AMAP_SET_BITS_PTR(CQ_DB, event, &eqdb, 1); ++ AMAP_SET_BITS_PTR(CQ_DB, num_popped, &eqdb, n); ++ /* ++ * Under some situations we see an interrupt and no valid ++ * EQ entry. To keep going, we need to ring the DB even if ++ * numPOsted is 0. ++ */ ++ PD_WRITE(&pnob->fn_obj, cq_db, eqdb.dw[0]); ++ return; ++} ++ ++/* ++ * Called from the tasklet scheduled by ISR. All real interrupt processing ++ * is done here. ++ */ ++void be_process_intr(unsigned long context) ++{ ++ struct be_adapter *adapter = (struct be_adapter *)context; ++ struct be_net_object *pnob = adapter->net_obj; ++ u32 isr, n; ++ ulong flags = 0; ++ ++ isr = adapter->isr; ++ ++ /* ++ * we create only one NIC event queue in Linux. Event is ++ * expected only in the first event queue ++ */ ++ BUG_ON(isr & 0xfffffffe); ++ if ((isr & 1) == 0) ++ return; /* not our interrupt */ ++ n = process_events(pnob); ++ /* ++ * Clear the event bit. adapter->isr is set by ++ * hard interrupt. Prevent race with lock. ++ */ ++ spin_lock_irqsave(&adapter->int_lock, flags); ++ adapter->isr &= ~1; ++ spin_unlock_irqrestore(&adapter->int_lock, flags); ++ be_notify_event(pnob, n, 1); ++ /* ++ * If previous allocation attempts had failed and ++ * BE has used up all posted buffers, post RX buffers here ++ */ ++ if (pnob->rxbuf_post_fail && atomic_read(&pnob->rx_q_posted) == 0) ++ be_post_eth_rx_buffs(pnob); ++ update_eqd(adapter, pnob); ++ return; ++} +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/drivers/staging/benet/benet.h linux-2.6.29-rc3.owrt/drivers/staging/benet/benet.h +--- linux-2.6.29.owrt/drivers/staging/benet/benet.h 1970-01-01 01:00:00.000000000 +0100 ++++ linux-2.6.29-rc3.owrt/drivers/staging/benet/benet.h 2009-05-10 23:48:29.000000000 +0200 +@@ -0,0 +1,429 @@ ++/* ++ * Copyright (C) 2005 - 2008 ServerEngines ++ * All rights reserved. ++ * ++ * 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. The full GNU General ++ * Public License is included in this distribution in the file called COPYING. ++ * ++ * Contact Information: ++ * linux-drivers@serverengines.com ++ * ++ * ServerEngines ++ * 209 N. Fair Oaks Ave ++ * Sunnyvale, CA 94085 ++ */ ++#ifndef _BENET_H_ ++#define _BENET_H_ ++ ++#include <linux/pci.h> ++#include <linux/netdevice.h> ++#include <linux/inet_lro.h> ++#include "hwlib.h" ++ ++#define _SA_MODULE_NAME "net-driver" ++ ++#define VLAN_VALID_BIT 0x8000 ++#define BE_NUM_VLAN_SUPPORTED 32 ++#define BE_PORT_LINK_DOWN 0000 ++#define BE_PORT_LINK_UP 0001 ++#define BE_MAX_TX_FRAG_COUNT (30) ++ ++/* Flag bits for send operation */ ++#define IPCS (1 << 0) /* Enable IP checksum offload */ ++#define UDPCS (1 << 1) /* Enable UDP checksum offload */ ++#define TCPCS (1 << 2) /* Enable TCP checksum offload */ ++#define LSO (1 << 3) /* Enable Large Segment offload */ ++#define ETHVLAN (1 << 4) /* Enable VLAN insert */ ++#define ETHEVENT (1 << 5) /* Generate event on completion */ ++#define ETHCOMPLETE (1 << 6) /* Generate completion when done */ ++#define IPSEC (1 << 7) /* Enable IPSEC */ ++#define FORWARD (1 << 8) /* Send the packet in forwarding path */ ++#define FIN (1 << 9) /* Issue FIN segment */ ++ ++#define BE_MAX_MTU 8974 ++ ++#define BE_MAX_LRO_DESCRIPTORS 8 ++#define BE_LRO_MAX_PKTS 64 ++#define BE_MAX_FRAGS_PER_FRAME 6 ++ ++extern const char be_drvr_ver[]; ++extern char be_fw_ver[]; ++extern char be_driver_name[]; ++ ++extern struct ethtool_ops be_ethtool_ops; ++ ++#define BE_DEV_STATE_NONE 0 ++#define BE_DEV_STATE_INIT 1 ++#define BE_DEV_STATE_OPEN 2 ++#define BE_DEV_STATE_SUSPEND 3 ++ ++/* This structure is used to describe physical fragments to use ++ * for DMAing data from NIC. ++ */ ++struct be_recv_buffer { ++ struct list_head rxb_list; /* for maintaining a linked list */ ++ void *rxb_va; /* buffer virtual address */ ++ u32 rxb_pa_lo; /* low part of physical address */ ++ u32 rxb_pa_hi; /* high part of physical address */ ++ u32 rxb_len; /* length of recv buffer */ ++ void *rxb_ctxt; /* context for OSM driver to use */ ++}; ++ ++/* ++ * fragment list to describe scattered data. ++ */ ++struct be_tx_frag_list { ++ u32 txb_len; /* Size of this fragment */ ++ u32 txb_pa_lo; /* Lower 32 bits of 64 bit physical addr */ ++ u32 txb_pa_hi; /* Higher 32 bits of 64 bit physical addr */ ++}; ++ ++struct be_rx_page_info { ++ struct page *page; ++ dma_addr_t bus; ++ u16 page_offset; ++}; ++ ++/* ++ * This structure is the main tracking structure for a NIC interface. ++ */ ++struct be_net_object { ++ /* MCC Ring - used to send fwcmds to embedded ARM processor */ ++ struct MCC_WRB_AMAP *mcc_q; /* VA of the start of the ring */ ++ u32 mcc_q_len; /* # of WRB entries in this ring */ ++ u32 mcc_q_size; ++ u32 mcc_q_hd; /* MCC ring head */ ++ u8 mcc_q_created; /* flag to help cleanup */ ++ struct be_mcc_object mcc_q_obj; /* BECLIB's MCC ring Object */ ++ dma_addr_t mcc_q_bus; /* DMA'ble bus address */ ++ ++ /* MCC Completion Ring - FW responses to fwcmds sent from MCC ring */ ++ struct MCC_CQ_ENTRY_AMAP *mcc_cq; /* VA of the start of the ring */ ++ u32 mcc_cq_len; /* # of compl. entries in this ring */ ++ u32 mcc_cq_size; ++ u32 mcc_cq_tl; /* compl. ring tail */ ++ u8 mcc_cq_created; /* flag to help cleanup */ ++ struct be_cq_object mcc_cq_obj; /* BECLIB's MCC compl. ring object */ ++ u32 mcc_cq_id; /* MCC ring ID */ ++ dma_addr_t mcc_cq_bus; /* DMA'ble bus address */ ++ ++ struct ring_desc mb_rd; /* RD for MCC_MAIL_BOX */ ++ void *mb_ptr; /* mailbox ptr to be freed */ ++ dma_addr_t mb_bus; /* DMA'ble bus address */ ++ u32 mb_size; ++ ++ /* BEClib uses an array of context objects to track outstanding ++ * requests to the MCC. We need allocate the same number of ++ * conext entries as the number of entries in the MCC WRB ring ++ */ ++ u32 mcc_wrb_ctxt_size; ++ void *mcc_wrb_ctxt; /* pointer to the context area */ ++ u32 mcc_wrb_ctxtLen; /* Number of entries in the context */ ++ /* ++ * NIC send request ring - used for xmitting raw ether frames. ++ */ ++ struct ETH_WRB_AMAP *tx_q; /* VA of the start of the ring */ ++ u32 tx_q_len; /* # if entries in the send ring */ ++ u32 tx_q_size; ++ u32 tx_q_hd; /* Head index. Next req. goes here */ ++ u32 tx_q_tl; /* Tail indx. oldest outstanding req. */ ++ u8 tx_q_created; /* flag to help cleanup */ ++ struct be_ethsq_object tx_q_obj;/* BECLIB's send Q handle */ ++ dma_addr_t tx_q_bus; /* DMA'ble bus address */ ++ u32 tx_q_id; /* send queue ring ID */ ++ u32 tx_q_port; /* 0 no binding, 1 port A, 2 port B */ ++ atomic_t tx_q_used; /* # of WRBs used */ ++ /* ptr to an array in which we store context info for each send req. */ ++ void **tx_ctxt; ++ /* ++ * NIC Send compl. ring - completion status for all NIC frames xmitted. ++ */ ++ struct ETH_TX_COMPL_AMAP *tx_cq;/* VA of start of the ring */ ++ u32 txcq_len; /* # of entries in the ring */ ++ u32 tx_cq_size; ++ /* ++ * index into compl ring where the host expects next completion entry ++ */ ++ u32 tx_cq_tl; ++ u32 tx_cq_id; /* completion queue id */ ++ u8 tx_cq_created; /* flag to help cleanup */ ++ struct be_cq_object tx_cq_obj; ++ dma_addr_t tx_cq_bus; /* DMA'ble bus address */ ++ /* ++ * Event Queue - all completion entries post events here. ++ */ ++ struct EQ_ENTRY_AMAP *event_q; /* VA of start of event queue */ ++ u32 event_q_len; /* # of entries */ ++ u32 event_q_size; ++ u32 event_q_tl; /* Tail of the event queue */ ++ u32 event_q_id; /* Event queue ID */ ++ u8 event_q_created; /* flag to help cleanup */ ++ struct be_eq_object event_q_obj; /* Queue handle */ ++ dma_addr_t event_q_bus; /* DMA'ble bus address */ ++ /* ++ * NIC receive queue - Data buffers to be used for receiving unicast, ++ * broadcast and multi-cast frames are posted here. ++ */ ++ struct ETH_RX_D_AMAP *rx_q; /* VA of start of the queue */ ++ u32 rx_q_len; /* # of entries */ ++ u32 rx_q_size; ++ u32 rx_q_hd; /* Head of the queue */ ++ atomic_t rx_q_posted; /* number of posted buffers */ ++ u32 rx_q_id; /* queue ID */ ++ u8 rx_q_created; /* flag to help cleanup */ ++ struct be_ethrq_object rx_q_obj; /* NIC RX queue handle */ ++ dma_addr_t rx_q_bus; /* DMA'ble bus address */ ++ /* ++ * Pointer to an array of opaque context object for use by OSM driver ++ */ ++ void **rx_ctxt; ++ /* ++ * NIC unicast RX completion queue - all unicast ether frame completion ++ * statuses from BE come here. ++ */ ++ struct ETH_RX_COMPL_AMAP *rx_cq; /* VA of start of the queue */ ++ u32 rx_cq_len; /* # of entries */ ++ u32 rx_cq_size; ++ u32 rx_cq_tl; /* Tail of the queue */ ++ u32 rx_cq_id; /* queue ID */ ++ u8 rx_cq_created; /* flag to help cleanup */ ++ struct be_cq_object rx_cq_obj; /* queue handle */ ++ dma_addr_t rx_cq_bus; /* DMA'ble bus address */ ++ struct be_function_object fn_obj; /* function object */ ++ bool fn_obj_created; ++ u32 rx_buf_size; /* Size of the RX buffers */ ++ ++ struct net_device *netdev; ++ struct be_recv_buffer eth_rx_bufs[256]; /* to pass Rx buffer ++ addresses */ ++ struct be_adapter *adapter; /* Pointer to OSM adapter */ ++ u32 devno; /* OSM, network dev no. */ ++ u32 use_port; /* Current active port */ ++ struct be_rx_page_info *rx_page_info; /* Array of Rx buf pages */ ++ u32 rx_pg_info_hd; /* Head of queue */ ++ int rxbuf_post_fail; /* RxBuff posting fail count */ ++ bool rx_pg_shared; /* Is an allocsted page shared as two frags ? */ ++ struct vlan_group *vlan_grp; ++ u32 num_vlans; /* Number of vlans in BE's filter */ ++ u16 vlan_tag[BE_NUM_VLAN_SUPPORTED]; /* vlans currently configured */ ++ struct napi_struct napi; ++ struct net_lro_mgr lro_mgr; ++ struct net_lro_desc lro_desc[BE_MAX_LRO_DESCRIPTORS]; ++}; ++ ++#define NET_FH(np) (&(np)->fn_obj) ++ ++/* ++ * BE driver statistics. ++ */ ++struct be_drvr_stat { ++ u32 bes_tx_reqs; /* number of TX requests initiated */ ++ u32 bes_tx_fails; /* number of TX requests that failed */ ++ u32 bes_fwd_reqs; /* number of send reqs through forwarding i/f */ ++ u32 bes_tx_wrbs; /* number of tx WRBs used */ ++ ++ u32 bes_ints; /* number of interrupts */ ++ u32 bes_polls; /* number of times NAPI called poll function */ ++ u32 bes_events; /* total evet entries processed */ ++ u32 bes_tx_events; /* number of tx completion events */ ++ u32 bes_rx_events; /* number of ucast rx completion events */ ++ u32 bes_tx_compl; /* number of tx completion entries processed */ ++ u32 bes_rx_compl; /* number of rx completion entries ++ processed */ ++ u32 bes_ethrx_post_fail; /* number of ethrx buffer alloc ++ failures */ ++ /* ++ * number of non ether type II frames dropped where ++ * frame len > length field of Mac Hdr ++ */ ++ u32 bes_802_3_dropped_frames; ++ /* ++ * number of non ether type II frames malformed where ++ * in frame len < length field of Mac Hdr ++ */ ++ u32 bes_802_3_malformed_frames; ++ u32 bes_ips; /* interrupts / sec */ ++ u32 bes_prev_ints; /* bes_ints at last IPS calculation */ ++ u16 bes_eth_tx_rate; /* ETH TX rate - Mb/sec */ ++ u16 bes_eth_rx_rate; /* ETH RX rate - Mb/sec */ ++ u32 bes_rx_coal; /* Num pkts coalasced */ ++ u32 bes_rx_flush; /* Num times coalasced */ ++ u32 bes_link_change_physical; /*Num of times physical link changed */ ++ u32 bes_link_change_virtual; /*Num of times virtual link changed */ ++ u32 bes_rx_misc_pkts; /* Misc pkts received */ ++}; ++ ++/* Maximum interrupt delay (in microseconds) allowed */ ++#define MAX_EQD 120 ++ ++/* ++ * timer to prevent system shutdown hang for ever if h/w stops responding ++ */ ++struct be_timer_ctxt { ++ atomic_t get_stat_flag; ++ struct timer_list get_stats_timer; ++ unsigned long get_stat_sem_addr; ++} ; ++ ++/* This structure is the main BladeEngine driver context. */ ++struct be_adapter { ++ struct net_device *netdevp; ++ struct be_drvr_stat be_stat; ++ struct net_device_stats benet_stats; ++ ++ /* PCI BAR mapped addresses */ ++ u8 __iomem *csr_va; /* CSR */ ++ u8 __iomem *db_va; /* Door Bell */ ++ u8 __iomem *pci_va; /* PCI Config */ ++ ++ struct tasklet_struct sts_handler; ++ struct timer_list cq_timer; ++ spinlock_t int_lock; /* to protect the isr field in adapter */ ++ ++ struct FWCMD_ETH_GET_STATISTICS *eth_statsp; ++ /* ++ * This will enable the use of ethtool to enable or disable ++ * Checksum on Rx pkts to be obeyed or disobeyed. ++ * If this is true = 1, then whatever is the checksum on the ++ * Received pkt as per BE, it will be given to the stack. ++ * Else the stack will re calculate it. ++ */ ++ bool rx_csum; ++ /* ++ * This will enable the use of ethtool to enable or disable ++ * Coalese on Rx pkts to be obeyed or disobeyed. ++ * If this is grater than 0 and less than 16 then coalascing ++ * is enabled else it is disabled ++ */ ++ u32 max_rx_coal; ++ struct pci_dev *pdev; /* Pointer to OS's PCI dvice */ ++ ++ spinlock_t txq_lock; /* to stop/wake queue based on tx_q_used */ ++ ++ u32 isr; /* copy of Intr status reg. */ ++ ++ u32 port0_link_sts; /* Port 0 link status */ ++ u32 port1_link_sts; /* port 1 list status */ ++ struct BE_LINK_STATUS *be_link_sts; ++ ++ /* pointer to the first netobject of this adapter */ ++ struct be_net_object *net_obj; ++ ++ /* Flags to indicate what to clean up */ ++ bool tasklet_started; ++ bool isr_registered; ++ /* ++ * adaptive interrupt coalescing (AIC) related ++ */ ++ bool enable_aic; /* 1 if AIC is enabled */ ++ u16 min_eqd; /* minimum EQ delay in usec */ ++ u16 max_eqd; /* minimum EQ delay in usec */ ++ u16 cur_eqd; /* current EQ delay in usec */ ++ /* ++ * book keeping for interrupt / sec and TX/RX rate calculation ++ */ ++ ulong ips_jiffies; /* jiffies at last IPS calc */ ++ u32 eth_tx_bytes; ++ ulong eth_tx_jiffies; ++ u32 eth_rx_bytes; ++ ulong eth_rx_jiffies; ++ ++ struct semaphore get_eth_stat_sem; ++ ++ /* timer ctxt to prevent shutdown hanging due to un-responsive BE */ ++ struct be_timer_ctxt timer_ctxt; ++ ++#define BE_MAX_MSIX_VECTORS 32 ++#define BE_MAX_REQ_MSIX_VECTORS 1 /* only one EQ in Linux driver */ ++ struct msix_entry msix_entries[BE_MAX_MSIX_VECTORS]; ++ bool msix_enabled; ++ bool dma_64bit_cap; /* the Device DAC capable or not */ ++ u8 dev_state; /* The current state of the device */ ++ u8 dev_pm_state; /* The State of device before going to suspend */ ++}; ++ ++/* ++ * Every second we look at the ints/sec and adjust eq_delay ++ * between adapter->min_eqd and adapter->max_eqd to keep the ints/sec between ++ * IPS_HI_WM and IPS_LO_WM. ++ */ ++#define IPS_HI_WM 18000 ++#define IPS_LO_WM 8000 ++ ++ ++static inline void index_adv(u32 *index, u32 val, u32 limit) ++{ ++ BUG_ON(limit & (limit-1)); ++ *index = (*index + val) & (limit - 1); ++} ++ ++static inline void index_inc(u32 *index, u32 limit) ++{ ++ BUG_ON(limit & (limit-1)); ++ *index = (*index + 1) & (limit - 1); ++} ++ ++static inline void be_adv_eq_tl(struct be_net_object *pnob) ++{ ++ index_inc(&pnob->event_q_tl, pnob->event_q_len); ++} ++ ++static inline void be_adv_txq_hd(struct be_net_object *pnob) ++{ ++ index_inc(&pnob->tx_q_hd, pnob->tx_q_len); ++} ++ ++static inline void be_adv_txq_tl(struct be_net_object *pnob) ++{ ++ index_inc(&pnob->tx_q_tl, pnob->tx_q_len); ++} ++ ++static inline void be_adv_txcq_tl(struct be_net_object *pnob) ++{ ++ index_inc(&pnob->tx_cq_tl, pnob->txcq_len); ++} ++ ++static inline void be_adv_rxq_hd(struct be_net_object *pnob) ++{ ++ index_inc(&pnob->rx_q_hd, pnob->rx_q_len); ++} ++ ++static inline void be_adv_rxcq_tl(struct be_net_object *pnob) ++{ ++ index_inc(&pnob->rx_cq_tl, pnob->rx_cq_len); ++} ++ ++static inline u32 tx_compl_lastwrb_idx_get(struct be_net_object *pnob) ++{ ++ return (pnob->tx_q_tl + *(u32 *)&pnob->tx_ctxt[pnob->tx_q_tl] - 1) ++ & (pnob->tx_q_len - 1); ++} ++ ++int benet_init(struct net_device *); ++int be_ethtool_ioctl(struct net_device *, struct ifreq *); ++struct net_device_stats *benet_get_stats(struct net_device *); ++void be_process_intr(unsigned long context); ++irqreturn_t be_int(int irq, void *dev); ++void be_post_eth_rx_buffs(struct be_net_object *); ++void be_get_stat_cb(void *, int, struct MCC_WRB_AMAP *); ++void be_get_stats_timer_handler(unsigned long); ++void be_wait_nic_tx_cmplx_cmpl(struct be_net_object *); ++void be_print_link_info(struct BE_LINK_STATUS *); ++void be_update_link_status(struct be_adapter *); ++void be_init_procfs(struct be_adapter *); ++void be_cleanup_procfs(struct be_adapter *); ++int be_poll(struct napi_struct *, int); ++struct ETH_RX_COMPL_AMAP *be_get_rx_cmpl(struct be_net_object *); ++void be_notify_cmpl(struct be_net_object *, int, int, int); ++void be_enable_intr(struct be_net_object *); ++void be_enable_eq_intr(struct be_net_object *); ++void be_disable_intr(struct be_net_object *); ++void be_disable_eq_intr(struct be_net_object *); ++int be_set_uc_mac_adr(struct be_net_object *, u8, u8, u8, ++ u8 *, mcc_wrb_cqe_callback, void *); ++int be_get_flow_ctl(struct be_function_object *pFnObj, bool *, bool *); ++void process_one_tx_compl(struct be_net_object *pnob, u32 end_idx); ++ ++#endif /* _BENET_H_ */ +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/drivers/staging/benet/be_netif.c linux-2.6.29-rc3.owrt/drivers/staging/benet/be_netif.c +--- linux-2.6.29.owrt/drivers/staging/benet/be_netif.c 1970-01-01 01:00:00.000000000 +0100 ++++ linux-2.6.29-rc3.owrt/drivers/staging/benet/be_netif.c 2009-05-10 23:48:29.000000000 +0200 +@@ -0,0 +1,705 @@ ++/* ++ * Copyright (C) 2005 - 2008 ServerEngines ++ * All rights reserved. ++ * ++ * 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. The full GNU General ++ * Public License is included in this distribution in the file called COPYING. ++ * ++ * Contact Information: ++ * linux-drivers@serverengines.com ++ * ++ * ServerEngines ++ * 209 N. Fair Oaks Ave ++ * Sunnyvale, CA 94085 ++ */ ++/* ++ * be_netif.c ++ * ++ * This file contains various entry points of drivers seen by tcp/ip stack. ++ */ ++ ++#include <linux/if_vlan.h> ++#include <linux/in.h> ++#include "benet.h" ++#include <linux/ip.h> ++#include <linux/inet_lro.h> ++ ++/* Strings to print Link properties */ ++static const char *link_speed[] = { ++ "Invalid link Speed Value", ++ "10 Mbps", ++ "100 Mbps", ++ "1 Gbps", ++ "10 Gbps" ++}; ++ ++static const char *link_duplex[] = { ++ "Invalid Duplex Value", ++ "Half Duplex", ++ "Full Duplex" ++}; ++ ++static const char *link_state[] = { ++ "", ++ "(active)" ++}; ++ ++void be_print_link_info(struct BE_LINK_STATUS *lnk_status) ++{ ++ u16 si, di, ai; ++ ++ /* Port 0 */ ++ if (lnk_status->mac0_speed && lnk_status->mac0_duplex) { ++ /* Port is up and running */ ++ si = (lnk_status->mac0_speed < 5) ? lnk_status->mac0_speed : 0; ++ di = (lnk_status->mac0_duplex < 3) ? ++ lnk_status->mac0_duplex : 0; ++ ai = (lnk_status->active_port == 0) ? 1 : 0; ++ printk(KERN_INFO "PortNo. 0: Speed - %s %s %s\n", ++ link_speed[si], link_duplex[di], link_state[ai]); ++ } else ++ printk(KERN_INFO "PortNo. 0: Down\n"); ++ ++ /* Port 1 */ ++ if (lnk_status->mac1_speed && lnk_status->mac1_duplex) { ++ /* Port is up and running */ ++ si = (lnk_status->mac1_speed < 5) ? lnk_status->mac1_speed : 0; ++ di = (lnk_status->mac1_duplex < 3) ? ++ lnk_status->mac1_duplex : 0; ++ ai = (lnk_status->active_port == 0) ? 1 : 0; ++ printk(KERN_INFO "PortNo. 1: Speed - %s %s %s\n", ++ link_speed[si], link_duplex[di], link_state[ai]); ++ } else ++ printk(KERN_INFO "PortNo. 1: Down\n"); ++ ++ return; ++} ++ ++static int ++be_get_frag_header(struct skb_frag_struct *frag, void **mac_hdr, ++ void **ip_hdr, void **tcpudp_hdr, ++ u64 *hdr_flags, void *priv) ++{ ++ struct ethhdr *eh; ++ struct vlan_ethhdr *veh; ++ struct iphdr *iph; ++ u8 *va = page_address(frag->page) + frag->page_offset; ++ unsigned long ll_hlen; ++ ++ /* find the mac header, abort if not IPv4 */ ++ ++ prefetch(va); ++ eh = (struct ethhdr *)va; ++ *mac_hdr = eh; ++ ll_hlen = ETH_HLEN; ++ if (eh->h_proto != htons(ETH_P_IP)) { ++ if (eh->h_proto == htons(ETH_P_8021Q)) { ++ veh = (struct vlan_ethhdr *)va; ++ if (veh->h_vlan_encapsulated_proto != htons(ETH_P_IP)) ++ return -1; ++ ++ ll_hlen += VLAN_HLEN; ++ ++ } else { ++ return -1; ++ } ++ } ++ *hdr_flags = LRO_IPV4; ++ ++ iph = (struct iphdr *)(va + ll_hlen); ++ *ip_hdr = iph; ++ if (iph->protocol != IPPROTO_TCP) ++ return -1; ++ *hdr_flags |= LRO_TCP; ++ *tcpudp_hdr = (u8 *) (*ip_hdr) + (iph->ihl << 2); ++ ++ return 0; ++} ++ ++static int benet_open(struct net_device *netdev) ++{ ++ struct be_net_object *pnob = netdev_priv(netdev); ++ struct be_adapter *adapter = pnob->adapter; ++ struct net_lro_mgr *lro_mgr; ++ ++ if (adapter->dev_state < BE_DEV_STATE_INIT) ++ return -EAGAIN; ++ ++ lro_mgr = &pnob->lro_mgr; ++ lro_mgr->dev = netdev; ++ ++ lro_mgr->features = LRO_F_NAPI; ++ lro_mgr->ip_summed = CHECKSUM_UNNECESSARY; ++ lro_mgr->ip_summed_aggr = CHECKSUM_UNNECESSARY; ++ lro_mgr->max_desc = BE_MAX_LRO_DESCRIPTORS; ++ lro_mgr->lro_arr = pnob->lro_desc; ++ lro_mgr->get_frag_header = be_get_frag_header; ++ lro_mgr->max_aggr = adapter->max_rx_coal; ++ lro_mgr->frag_align_pad = 2; ++ if (lro_mgr->max_aggr > MAX_SKB_FRAGS) ++ lro_mgr->max_aggr = MAX_SKB_FRAGS; ++ ++ adapter->max_rx_coal = BE_LRO_MAX_PKTS; ++ ++ be_update_link_status(adapter); ++ ++ /* ++ * Set carrier on only if Physical Link up ++ * Either of the port link status up signifies this ++ */ ++ if ((adapter->port0_link_sts == BE_PORT_LINK_UP) || ++ (adapter->port1_link_sts == BE_PORT_LINK_UP)) { ++ netif_start_queue(netdev); ++ netif_carrier_on(netdev); ++ } ++ ++ adapter->dev_state = BE_DEV_STATE_OPEN; ++ napi_enable(&pnob->napi); ++ be_enable_intr(pnob); ++ be_enable_eq_intr(pnob); ++ /* ++ * RX completion queue may be in dis-armed state. Arm it. ++ */ ++ be_notify_cmpl(pnob, 0, pnob->rx_cq_id, 1); ++ ++ return 0; ++} ++ ++static int benet_close(struct net_device *netdev) ++{ ++ struct be_net_object *pnob = netdev_priv(netdev); ++ struct be_adapter *adapter = pnob->adapter; ++ ++ netif_stop_queue(netdev); ++ synchronize_irq(netdev->irq); ++ ++ be_wait_nic_tx_cmplx_cmpl(pnob); ++ adapter->dev_state = BE_DEV_STATE_INIT; ++ netif_carrier_off(netdev); ++ ++ adapter->port0_link_sts = BE_PORT_LINK_DOWN; ++ adapter->port1_link_sts = BE_PORT_LINK_DOWN; ++ be_disable_intr(pnob); ++ be_disable_eq_intr(pnob); ++ napi_disable(&pnob->napi); ++ ++ return 0; ++} ++ ++/* ++ * Setting a Mac Address for BE ++ * Takes netdev and a void pointer as arguments. ++ * The pointer holds the new addres to be used. ++ */ ++static int benet_set_mac_addr(struct net_device *netdev, void *p) ++{ ++ struct sockaddr *addr = p; ++ struct be_net_object *pnob = netdev_priv(netdev); ++ ++ memcpy(netdev->dev_addr, addr->sa_data, netdev->addr_len); ++ be_rxf_mac_address_read_write(&pnob->fn_obj, 0, 0, false, true, false, ++ netdev->dev_addr, NULL, NULL); ++ /* ++ * Since we are doing Active-Passive failover, both ++ * ports should have matching MAC addresses everytime. ++ */ ++ be_rxf_mac_address_read_write(&pnob->fn_obj, 1, 0, false, true, false, ++ netdev->dev_addr, NULL, NULL); ++ ++ return 0; ++} ++ ++void be_get_stats_timer_handler(unsigned long context) ++{ ++ struct be_timer_ctxt *ctxt = (struct be_timer_ctxt *)context; ++ ++ if (atomic_read(&ctxt->get_stat_flag)) { ++ atomic_dec(&ctxt->get_stat_flag); ++ up((void *)ctxt->get_stat_sem_addr); ++ } ++ del_timer(&ctxt->get_stats_timer); ++ return; ++} ++ ++void be_get_stat_cb(void *context, int status, ++ struct MCC_WRB_AMAP *optional_wrb) ++{ ++ struct be_timer_ctxt *ctxt = (struct be_timer_ctxt *)context; ++ /* ++ * just up the semaphore if the get_stat_flag ++ * reads 1. so that the waiter can continue. ++ * If it is 0, then it was handled by the timer handler. ++ */ ++ del_timer(&ctxt->get_stats_timer); ++ if (atomic_read(&ctxt->get_stat_flag)) { ++ atomic_dec(&ctxt->get_stat_flag); ++ up((void *)ctxt->get_stat_sem_addr); ++ } ++} ++ ++struct net_device_stats *benet_get_stats(struct net_device *dev) ++{ ++ struct be_net_object *pnob = netdev_priv(dev); ++ struct be_adapter *adapter = pnob->adapter; ++ u64 pa; ++ struct be_timer_ctxt *ctxt = &adapter->timer_ctxt; ++ ++ if (adapter->dev_state != BE_DEV_STATE_OPEN) { ++ /* Return previously read stats */ ++ return &(adapter->benet_stats); ++ } ++ /* Get Physical Addr */ ++ pa = pci_map_single(adapter->pdev, adapter->eth_statsp, ++ sizeof(struct FWCMD_ETH_GET_STATISTICS), ++ PCI_DMA_FROMDEVICE); ++ ctxt->get_stat_sem_addr = (unsigned long)&adapter->get_eth_stat_sem; ++ atomic_inc(&ctxt->get_stat_flag); ++ ++ be_rxf_query_eth_statistics(&pnob->fn_obj, adapter->eth_statsp, ++ cpu_to_le64(pa), be_get_stat_cb, ctxt, ++ NULL); ++ ++ ctxt->get_stats_timer.data = (unsigned long)ctxt; ++ mod_timer(&ctxt->get_stats_timer, (jiffies + (HZ * 2))); ++ down((void *)ctxt->get_stat_sem_addr); /* callback will unblock us */ ++ ++ /* Adding port0 and port1 stats. */ ++ adapter->benet_stats.rx_packets = ++ adapter->eth_statsp->params.response.p0recvdtotalframes + ++ adapter->eth_statsp->params.response.p1recvdtotalframes; ++ adapter->benet_stats.tx_packets = ++ adapter->eth_statsp->params.response.p0xmitunicastframes + ++ adapter->eth_statsp->params.response.p1xmitunicastframes; ++ adapter->benet_stats.tx_bytes = ++ adapter->eth_statsp->params.response.p0xmitbyteslsd + ++ adapter->eth_statsp->params.response.p1xmitbyteslsd; ++ adapter->benet_stats.rx_errors = ++ adapter->eth_statsp->params.response.p0crcerrors + ++ adapter->eth_statsp->params.response.p1crcerrors; ++ adapter->benet_stats.rx_errors += ++ adapter->eth_statsp->params.response.p0alignmentsymerrs + ++ adapter->eth_statsp->params.response.p1alignmentsymerrs; ++ adapter->benet_stats.rx_errors += ++ adapter->eth_statsp->params.response.p0inrangelenerrors + ++ adapter->eth_statsp->params.response.p1inrangelenerrors; ++ adapter->benet_stats.rx_bytes = ++ adapter->eth_statsp->params.response.p0recvdtotalbytesLSD + ++ adapter->eth_statsp->params.response.p1recvdtotalbytesLSD; ++ adapter->benet_stats.rx_crc_errors = ++ adapter->eth_statsp->params.response.p0crcerrors + ++ adapter->eth_statsp->params.response.p1crcerrors; ++ ++ adapter->benet_stats.tx_packets += ++ adapter->eth_statsp->params.response.p0xmitmulticastframes + ++ adapter->eth_statsp->params.response.p1xmitmulticastframes; ++ adapter->benet_stats.tx_packets += ++ adapter->eth_statsp->params.response.p0xmitbroadcastframes + ++ adapter->eth_statsp->params.response.p1xmitbroadcastframes; ++ adapter->benet_stats.tx_errors = 0; ++ ++ adapter->benet_stats.multicast = ++ adapter->eth_statsp->params.response.p0xmitmulticastframes + ++ adapter->eth_statsp->params.response.p1xmitmulticastframes; ++ ++ adapter->benet_stats.rx_fifo_errors = ++ adapter->eth_statsp->params.response.p0rxfifooverflowdropped + ++ adapter->eth_statsp->params.response.p1rxfifooverflowdropped; ++ adapter->benet_stats.rx_frame_errors = ++ adapter->eth_statsp->params.response.p0alignmentsymerrs + ++ adapter->eth_statsp->params.response.p1alignmentsymerrs; ++ adapter->benet_stats.rx_length_errors = ++ adapter->eth_statsp->params.response.p0inrangelenerrors + ++ adapter->eth_statsp->params.response.p1inrangelenerrors; ++ adapter->benet_stats.rx_length_errors += ++ adapter->eth_statsp->params.response.p0outrangeerrors + ++ adapter->eth_statsp->params.response.p1outrangeerrors; ++ adapter->benet_stats.rx_length_errors += ++ adapter->eth_statsp->params.response.p0frametoolongerrors + ++ adapter->eth_statsp->params.response.p1frametoolongerrors; ++ ++ pci_unmap_single(adapter->pdev, (ulong) adapter->eth_statsp, ++ sizeof(struct FWCMD_ETH_GET_STATISTICS), ++ PCI_DMA_FROMDEVICE); ++ return &(adapter->benet_stats); ++ ++} ++ ++static void be_start_tx(struct be_net_object *pnob, u32 nposted) ++{ ++#define CSR_ETH_MAX_SQPOSTS 255 ++ struct SQ_DB_AMAP sqdb; ++ ++ sqdb.dw[0] = 0; ++ ++ AMAP_SET_BITS_PTR(SQ_DB, cid, &sqdb, pnob->tx_q_id); ++ while (nposted) { ++ if (nposted > CSR_ETH_MAX_SQPOSTS) { ++ AMAP_SET_BITS_PTR(SQ_DB, numPosted, &sqdb, ++ CSR_ETH_MAX_SQPOSTS); ++ nposted -= CSR_ETH_MAX_SQPOSTS; ++ } else { ++ AMAP_SET_BITS_PTR(SQ_DB, numPosted, &sqdb, nposted); ++ nposted = 0; ++ } ++ PD_WRITE(&pnob->fn_obj, etx_sq_db, sqdb.dw[0]); ++ } ++ ++ return; ++} ++ ++static void update_tx_rate(struct be_adapter *adapter) ++{ ++ /* update the rate once in two seconds */ ++ if ((jiffies - adapter->eth_tx_jiffies) > 2 * (HZ)) { ++ u32 r; ++ r = adapter->eth_tx_bytes / ++ ((jiffies - adapter->eth_tx_jiffies) / (HZ)); ++ r = (r / 1000000); /* M bytes/s */ ++ adapter->be_stat.bes_eth_tx_rate = (r * 8); /* M bits/s */ ++ adapter->eth_tx_jiffies = jiffies; ++ adapter->eth_tx_bytes = 0; ++ } ++} ++ ++static int wrb_cnt_in_skb(struct sk_buff *skb) ++{ ++ int cnt = 0; ++ while (skb) { ++ if (skb->len > skb->data_len) ++ cnt++; ++ cnt += skb_shinfo(skb)->nr_frags; ++ skb = skb_shinfo(skb)->frag_list; ++ } ++ BUG_ON(cnt > BE_MAX_TX_FRAG_COUNT); ++ return cnt; ++} ++ ++static void wrb_fill(struct ETH_WRB_AMAP *wrb, u64 addr, int len) ++{ ++ AMAP_SET_BITS_PTR(ETH_WRB, frag_pa_hi, wrb, addr >> 32); ++ AMAP_SET_BITS_PTR(ETH_WRB, frag_pa_lo, wrb, addr & 0xFFFFFFFF); ++ AMAP_SET_BITS_PTR(ETH_WRB, frag_len, wrb, len); ++} ++ ++static void wrb_fill_extra(struct ETH_WRB_AMAP *wrb, struct sk_buff *skb, ++ struct be_net_object *pnob) ++{ ++ wrb->dw[2] = 0; ++ wrb->dw[3] = 0; ++ AMAP_SET_BITS_PTR(ETH_WRB, crc, wrb, 1); ++ if (skb_shinfo(skb)->gso_segs > 1 && skb_shinfo(skb)->gso_size) { ++ AMAP_SET_BITS_PTR(ETH_WRB, lso, wrb, 1); ++ AMAP_SET_BITS_PTR(ETH_WRB, lso_mss, wrb, ++ skb_shinfo(skb)->gso_size); ++ } else if (skb->ip_summed == CHECKSUM_PARTIAL) { ++ u8 proto = ((struct iphdr *)ip_hdr(skb))->protocol; ++ if (proto == IPPROTO_TCP) ++ AMAP_SET_BITS_PTR(ETH_WRB, tcpcs, wrb, 1); ++ else if (proto == IPPROTO_UDP) ++ AMAP_SET_BITS_PTR(ETH_WRB, udpcs, wrb, 1); ++ } ++ if (pnob->vlan_grp && vlan_tx_tag_present(skb)) { ++ AMAP_SET_BITS_PTR(ETH_WRB, vlan, wrb, 1); ++ AMAP_SET_BITS_PTR(ETH_WRB, vlan_tag, wrb, vlan_tx_tag_get(skb)); ++ } ++} ++ ++static inline void wrb_copy_extra(struct ETH_WRB_AMAP *to, ++ struct ETH_WRB_AMAP *from) ++{ ++ ++ to->dw[2] = from->dw[2]; ++ to->dw[3] = from->dw[3]; ++} ++ ++/* Returns the actual count of wrbs used including a possible dummy */ ++static int copy_skb_to_txq(struct be_net_object *pnob, struct sk_buff *skb, ++ u32 wrb_cnt, u32 *copied) ++{ ++ u64 busaddr; ++ struct ETH_WRB_AMAP *wrb = NULL, *first = NULL; ++ u32 i; ++ bool dummy = true; ++ struct pci_dev *pdev = pnob->adapter->pdev; ++ ++ if (wrb_cnt & 1) ++ wrb_cnt++; ++ else ++ dummy = false; ++ ++ atomic_add(wrb_cnt, &pnob->tx_q_used); ++ ++ while (skb) { ++ if (skb->len > skb->data_len) { ++ int len = skb->len - skb->data_len; ++ busaddr = pci_map_single(pdev, skb->data, len, ++ PCI_DMA_TODEVICE); ++ busaddr = cpu_to_le64(busaddr); ++ wrb = &pnob->tx_q[pnob->tx_q_hd]; ++ if (first == NULL) { ++ wrb_fill_extra(wrb, skb, pnob); ++ first = wrb; ++ } else { ++ wrb_copy_extra(wrb, first); ++ } ++ wrb_fill(wrb, busaddr, len); ++ be_adv_txq_hd(pnob); ++ *copied += len; ++ } ++ ++ for (i = 0; i < skb_shinfo(skb)->nr_frags; i++) { ++ struct skb_frag_struct *frag = ++ &skb_shinfo(skb)->frags[i]; ++ busaddr = pci_map_page(pdev, frag->page, ++ frag->page_offset, frag->size, ++ PCI_DMA_TODEVICE); ++ busaddr = cpu_to_le64(busaddr); ++ wrb = &pnob->tx_q[pnob->tx_q_hd]; ++ if (first == NULL) { ++ wrb_fill_extra(wrb, skb, pnob); ++ first = wrb; ++ } else { ++ wrb_copy_extra(wrb, first); ++ } ++ wrb_fill(wrb, busaddr, frag->size); ++ be_adv_txq_hd(pnob); ++ *copied += frag->size; ++ } ++ skb = skb_shinfo(skb)->frag_list; ++ } ++ ++ if (dummy) { ++ wrb = &pnob->tx_q[pnob->tx_q_hd]; ++ BUG_ON(first == NULL); ++ wrb_copy_extra(wrb, first); ++ wrb_fill(wrb, 0, 0); ++ be_adv_txq_hd(pnob); ++ } ++ AMAP_SET_BITS_PTR(ETH_WRB, complete, wrb, 1); ++ AMAP_SET_BITS_PTR(ETH_WRB, last, wrb, 1); ++ return wrb_cnt; ++} ++ ++/* For each skb transmitted, tx_ctxt stores the num of wrbs in the ++ * start index and skb pointer in the end index ++ */ ++static inline void be_tx_wrb_info_remember(struct be_net_object *pnob, ++ struct sk_buff *skb, int wrb_cnt, ++ u32 start) ++{ ++ *(u32 *) (&pnob->tx_ctxt[start]) = wrb_cnt; ++ index_adv(&start, wrb_cnt - 1, pnob->tx_q_len); ++ pnob->tx_ctxt[start] = skb; ++} ++ ++static int benet_xmit(struct sk_buff *skb, struct net_device *netdev) ++{ ++ struct be_net_object *pnob = netdev_priv(netdev); ++ struct be_adapter *adapter = pnob->adapter; ++ u32 wrb_cnt, copied = 0; ++ u32 start = pnob->tx_q_hd; ++ ++ adapter->be_stat.bes_tx_reqs++; ++ ++ wrb_cnt = wrb_cnt_in_skb(skb); ++ spin_lock_bh(&adapter->txq_lock); ++ if ((pnob->tx_q_len - 2 - atomic_read(&pnob->tx_q_used)) <= wrb_cnt) { ++ netif_stop_queue(pnob->netdev); ++ spin_unlock_bh(&adapter->txq_lock); ++ adapter->be_stat.bes_tx_fails++; ++ return NETDEV_TX_BUSY; ++ } ++ spin_unlock_bh(&adapter->txq_lock); ++ ++ wrb_cnt = copy_skb_to_txq(pnob, skb, wrb_cnt, &copied); ++ be_tx_wrb_info_remember(pnob, skb, wrb_cnt, start); ++ ++ be_start_tx(pnob, wrb_cnt); ++ ++ adapter->eth_tx_bytes += copied; ++ adapter->be_stat.bes_tx_wrbs += wrb_cnt; ++ update_tx_rate(adapter); ++ netdev->trans_start = jiffies; ++ ++ return NETDEV_TX_OK; ++} ++ ++/* ++ * This is the driver entry point to change the mtu of the device ++ * Returns 0 for success and errno for failure. ++ */ ++static int benet_change_mtu(struct net_device *netdev, int new_mtu) ++{ ++ /* ++ * BE supports jumbo frame size upto 9000 bytes including the link layer ++ * header. Considering the different variants of frame formats possible ++ * like VLAN, SNAP/LLC, the maximum possible value for MTU is 8974 bytes ++ */ ++ ++ if (new_mtu < (ETH_ZLEN + ETH_FCS_LEN) || (new_mtu > BE_MAX_MTU)) { ++ dev_info(&netdev->dev, "Invalid MTU requested. " ++ "Must be between %d and %d bytes\n", ++ (ETH_ZLEN + ETH_FCS_LEN), BE_MAX_MTU); ++ return -EINVAL; ++ } ++ dev_info(&netdev->dev, "MTU changed from %d to %d\n", ++ netdev->mtu, new_mtu); ++ netdev->mtu = new_mtu; ++ return 0; ++} ++ ++/* ++ * This is the driver entry point to register a vlan with the device ++ */ ++static void benet_vlan_register(struct net_device *netdev, ++ struct vlan_group *grp) ++{ ++ struct be_net_object *pnob = netdev_priv(netdev); ++ ++ be_disable_eq_intr(pnob); ++ pnob->vlan_grp = grp; ++ pnob->num_vlans = 0; ++ be_enable_eq_intr(pnob); ++} ++ ++/* ++ * This is the driver entry point to add a vlan vlan_id ++ * with the device netdev ++ */ ++static void benet_vlan_add_vid(struct net_device *netdev, u16 vlan_id) ++{ ++ struct be_net_object *pnob = netdev_priv(netdev); ++ ++ if (pnob->num_vlans == (BE_NUM_VLAN_SUPPORTED - 1)) { ++ /* no way to return an error */ ++ dev_info(&netdev->dev, ++ "BladeEngine: Cannot configure more than %d Vlans\n", ++ BE_NUM_VLAN_SUPPORTED); ++ return; ++ } ++ /* The new vlan tag will be in the slot indicated by num_vlans. */ ++ pnob->vlan_tag[pnob->num_vlans++] = vlan_id; ++ be_rxf_vlan_config(&pnob->fn_obj, false, pnob->num_vlans, ++ pnob->vlan_tag, NULL, NULL, NULL); ++} ++ ++/* ++ * This is the driver entry point to remove a vlan vlan_id ++ * with the device netdev ++ */ ++static void benet_vlan_rem_vid(struct net_device *netdev, u16 vlan_id) ++{ ++ struct be_net_object *pnob = netdev_priv(netdev); ++ ++ u32 i, value; ++ ++ /* ++ * In Blade Engine, we support 32 vlan tag filters across both ports. ++ * To program a vlan tag, the RXF_RTPR_CSR register is used. ++ * Each 32-bit value of RXF_RTDR_CSR can address 2 vlan tag entries. ++ * The Vlan table is of depth 16. thus we support 32 tags. ++ */ ++ ++ value = vlan_id | VLAN_VALID_BIT; ++ for (i = 0; i < BE_NUM_VLAN_SUPPORTED; i++) { ++ if (pnob->vlan_tag[i] == vlan_id) ++ break; ++ } ++ ++ if (i == BE_NUM_VLAN_SUPPORTED) ++ return; ++ /* Now compact the vlan tag array by removing hole created. */ ++ while ((i + 1) < BE_NUM_VLAN_SUPPORTED) { ++ pnob->vlan_tag[i] = pnob->vlan_tag[i + 1]; ++ i++; ++ } ++ if ((i + 1) == BE_NUM_VLAN_SUPPORTED) ++ pnob->vlan_tag[i] = (u16) 0x0; ++ pnob->num_vlans--; ++ be_rxf_vlan_config(&pnob->fn_obj, false, pnob->num_vlans, ++ pnob->vlan_tag, NULL, NULL, NULL); ++} ++ ++/* ++ * This function is called to program multicast ++ * address in the multicast filter of the ASIC. ++ */ ++static void be_set_multicast_filter(struct net_device *netdev) ++{ ++ struct be_net_object *pnob = netdev_priv(netdev); ++ struct dev_mc_list *mc_ptr; ++ u8 mac_addr[32][ETH_ALEN]; ++ int i; ++ ++ if (netdev->flags & IFF_ALLMULTI) { ++ /* set BE in Multicast promiscuous */ ++ be_rxf_multicast_config(&pnob->fn_obj, true, 0, NULL, NULL, ++ NULL, NULL); ++ return; ++ } ++ ++ for (mc_ptr = netdev->mc_list, i = 0; mc_ptr; ++ mc_ptr = mc_ptr->next, i++) { ++ memcpy(&mac_addr[i][0], mc_ptr->dmi_addr, ETH_ALEN); ++ } ++ ++ /* reset the promiscuous mode also. */ ++ be_rxf_multicast_config(&pnob->fn_obj, false, i, ++ &mac_addr[0][0], NULL, NULL, NULL); ++} ++ ++/* ++ * This is the driver entry point to set multicast list ++ * with the device netdev. This function will be used to ++ * set promiscuous mode or multicast promiscuous mode ++ * or multicast mode.... ++ */ ++static void benet_set_multicast_list(struct net_device *netdev) ++{ ++ struct be_net_object *pnob = netdev_priv(netdev); ++ ++ if (netdev->flags & IFF_PROMISC) { ++ be_rxf_promiscuous(&pnob->fn_obj, 1, 1, NULL, NULL, NULL); ++ } else { ++ be_rxf_promiscuous(&pnob->fn_obj, 0, 0, NULL, NULL, NULL); ++ be_set_multicast_filter(netdev); ++ } ++} ++ ++int benet_init(struct net_device *netdev) ++{ ++ struct be_net_object *pnob = netdev_priv(netdev); ++ struct be_adapter *adapter = pnob->adapter; ++ ++ ether_setup(netdev); ++ ++ netdev->open = &benet_open; ++ netdev->stop = &benet_close; ++ netdev->hard_start_xmit = &benet_xmit; ++ ++ netdev->get_stats = &benet_get_stats; ++ ++ netdev->set_multicast_list = &benet_set_multicast_list; ++ ++ netdev->change_mtu = &benet_change_mtu; ++ netdev->set_mac_address = &benet_set_mac_addr; ++ ++ netdev->vlan_rx_register = benet_vlan_register; ++ netdev->vlan_rx_add_vid = benet_vlan_add_vid; ++ netdev->vlan_rx_kill_vid = benet_vlan_rem_vid; ++ ++ netdev->features = ++ NETIF_F_SG | NETIF_F_HIGHDMA | NETIF_F_HW_VLAN_RX | NETIF_F_TSO | ++ NETIF_F_HW_VLAN_TX | NETIF_F_HW_VLAN_FILTER | NETIF_F_IP_CSUM; ++ ++ netdev->flags |= IFF_MULTICAST; ++ ++ /* If device is DAC Capable, set the HIGHDMA flag for netdevice. */ ++ if (adapter->dma_64bit_cap) ++ netdev->features |= NETIF_F_HIGHDMA; ++ ++ SET_ETHTOOL_OPS(netdev, &be_ethtool_ops); ++ return 0; ++} +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/drivers/staging/benet/bestatus.h linux-2.6.29-rc3.owrt/drivers/staging/benet/bestatus.h +--- linux-2.6.29.owrt/drivers/staging/benet/bestatus.h 1970-01-01 01:00:00.000000000 +0100 ++++ linux-2.6.29-rc3.owrt/drivers/staging/benet/bestatus.h 2009-05-10 23:48:29.000000000 +0200 +@@ -0,0 +1,103 @@ ++/* ++ * Copyright (C) 2005 - 2008 ServerEngines ++ * All rights reserved. ++ * ++ * 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. The full GNU General ++ * Public License is included in this distribution in the file called COPYING. ++ * ++ * Contact Information: ++ * linux-drivers@serverengines.com ++ * ++ * ServerEngines ++ * 209 N. Fair Oaks Ave ++ * Sunnyvale, CA 94085 ++ */ ++#ifndef _BESTATUS_H_ ++#define _BESTATUS_H_ ++ ++#define BE_SUCCESS (0x00000000L) ++/* ++ * MessageId: BE_PENDING ++ * The BladeEngine Driver call succeeded, and pended operation. ++ */ ++#define BE_PENDING (0x20070001L) ++#define BE_STATUS_PENDING (BE_PENDING) ++/* ++ * MessageId: BE_NOT_OK ++ * An error occurred. ++ */ ++#define BE_NOT_OK (0xE0070002L) ++/* ++ * MessageId: BE_STATUS_SYSTEM_RESOURCES ++ * Insufficient host system resources exist to complete the API. ++ */ ++#define BE_STATUS_SYSTEM_RESOURCES (0xE0070003L) ++/* ++ * MessageId: BE_STATUS_CHIP_RESOURCES ++ * Insufficient chip resources exist to complete the API. ++ */ ++#define BE_STATUS_CHIP_RESOURCES (0xE0070004L) ++/* ++ * MessageId: BE_STATUS_NO_RESOURCE ++ * Insufficient resources to complete request. ++ */ ++#define BE_STATUS_NO_RESOURCE (0xE0070005L) ++/* ++ * MessageId: BE_STATUS_BUSY ++ * Resource is currently busy. ++ */ ++#define BE_STATUS_BUSY (0xE0070006L) ++/* ++ * MessageId: BE_STATUS_INVALID_PARAMETER ++ * Invalid Parameter in request. ++ */ ++#define BE_STATUS_INVALID_PARAMETER (0xE0000007L) ++/* ++ * MessageId: BE_STATUS_NOT_SUPPORTED ++ * Requested operation is not supported. ++ */ ++#define BE_STATUS_NOT_SUPPORTED (0xE000000DL) ++ ++/* ++ * *************************************************************************** ++ * E T H E R N E T S T A T U S ++ * *************************************************************************** ++ */ ++ ++/* ++ * MessageId: BE_ETH_TX_ERROR ++ * The Ethernet device driver failed to transmit a packet. ++ */ ++#define BE_ETH_TX_ERROR (0xE0070101L) ++ ++/* ++ * *************************************************************************** ++ * S H A R E D S T A T U S ++ * *************************************************************************** ++ */ ++ ++/* ++ * MessageId: BE_STATUS_VBD_INVALID_VERSION ++ * The device driver is not compatible with this version of the VBD. ++ */ ++#define BE_STATUS_INVALID_VERSION (0xE0070402L) ++/* ++ * MessageId: BE_STATUS_DOMAIN_DENIED ++ * The operation failed to complete due to insufficient access ++ * rights for the requesting domain. ++ */ ++#define BE_STATUS_DOMAIN_DENIED (0xE0070403L) ++/* ++ * MessageId: BE_STATUS_TCP_NOT_STARTED ++ * The embedded TCP/IP stack has not been started. ++ */ ++#define BE_STATUS_TCP_NOT_STARTED (0xE0070409L) ++/* ++ * MessageId: BE_STATUS_NO_MCC_WRB ++ * No free MCC WRB are available for posting the request. ++ */ ++#define BE_STATUS_NO_MCC_WRB (0xE0070414L) ++ ++#endif /* _BESTATUS_ */ +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/drivers/staging/benet/cev.h linux-2.6.29-rc3.owrt/drivers/staging/benet/cev.h +--- linux-2.6.29.owrt/drivers/staging/benet/cev.h 1970-01-01 01:00:00.000000000 +0100 ++++ linux-2.6.29-rc3.owrt/drivers/staging/benet/cev.h 2009-05-10 23:48:29.000000000 +0200 +@@ -0,0 +1,243 @@ ++/* ++ * Copyright (C) 2005 - 2008 ServerEngines ++ * All rights reserved. ++ * ++ * 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. The full GNU General ++ * Public License is included in this distribution in the file called COPYING. ++ * ++ * Contact Information: ++ * linux-drivers@serverengines.com ++ * ++ * ServerEngines ++ * 209 N. Fair Oaks Ave ++ * Sunnyvale, CA 94085 ++ */ ++/* ++ * Autogenerated by srcgen version: 0127 ++ */ ++#ifndef __cev_amap_h__ ++#define __cev_amap_h__ ++#include "ep.h" ++ ++/* ++ * Host Interrupt Status Register 0. The first of four application ++ * interrupt status registers. This register contains the interrupts ++ * for Event Queues EQ0 through EQ31. ++ */ ++struct BE_CEV_ISR0_CSR_AMAP { ++ u8 interrupt0; /* DWORD 0 */ ++ u8 interrupt1; /* DWORD 0 */ ++ u8 interrupt2; /* DWORD 0 */ ++ u8 interrupt3; /* DWORD 0 */ ++ u8 interrupt4; /* DWORD 0 */ ++ u8 interrupt5; /* DWORD 0 */ ++ u8 interrupt6; /* DWORD 0 */ ++ u8 interrupt7; /* DWORD 0 */ ++ u8 interrupt8; /* DWORD 0 */ ++ u8 interrupt9; /* DWORD 0 */ ++ u8 interrupt10; /* DWORD 0 */ ++ u8 interrupt11; /* DWORD 0 */ ++ u8 interrupt12; /* DWORD 0 */ ++ u8 interrupt13; /* DWORD 0 */ ++ u8 interrupt14; /* DWORD 0 */ ++ u8 interrupt15; /* DWORD 0 */ ++ u8 interrupt16; /* DWORD 0 */ ++ u8 interrupt17; /* DWORD 0 */ ++ u8 interrupt18; /* DWORD 0 */ ++ u8 interrupt19; /* DWORD 0 */ ++ u8 interrupt20; /* DWORD 0 */ ++ u8 interrupt21; /* DWORD 0 */ ++ u8 interrupt22; /* DWORD 0 */ ++ u8 interrupt23; /* DWORD 0 */ ++ u8 interrupt24; /* DWORD 0 */ ++ u8 interrupt25; /* DWORD 0 */ ++ u8 interrupt26; /* DWORD 0 */ ++ u8 interrupt27; /* DWORD 0 */ ++ u8 interrupt28; /* DWORD 0 */ ++ u8 interrupt29; /* DWORD 0 */ ++ u8 interrupt30; /* DWORD 0 */ ++ u8 interrupt31; /* DWORD 0 */ ++} __packed; ++struct CEV_ISR0_CSR_AMAP { ++ u32 dw[1]; ++}; ++ ++/* ++ * Host Interrupt Status Register 1. The second of four application ++ * interrupt status registers. This register contains the interrupts ++ * for Event Queues EQ32 through EQ63. ++ */ ++struct BE_CEV_ISR1_CSR_AMAP { ++ u8 interrupt32; /* DWORD 0 */ ++ u8 interrupt33; /* DWORD 0 */ ++ u8 interrupt34; /* DWORD 0 */ ++ u8 interrupt35; /* DWORD 0 */ ++ u8 interrupt36; /* DWORD 0 */ ++ u8 interrupt37; /* DWORD 0 */ ++ u8 interrupt38; /* DWORD 0 */ ++ u8 interrupt39; /* DWORD 0 */ ++ u8 interrupt40; /* DWORD 0 */ ++ u8 interrupt41; /* DWORD 0 */ ++ u8 interrupt42; /* DWORD 0 */ ++ u8 interrupt43; /* DWORD 0 */ ++ u8 interrupt44; /* DWORD 0 */ ++ u8 interrupt45; /* DWORD 0 */ ++ u8 interrupt46; /* DWORD 0 */ ++ u8 interrupt47; /* DWORD 0 */ ++ u8 interrupt48; /* DWORD 0 */ ++ u8 interrupt49; /* DWORD 0 */ ++ u8 interrupt50; /* DWORD 0 */ ++ u8 interrupt51; /* DWORD 0 */ ++ u8 interrupt52; /* DWORD 0 */ ++ u8 interrupt53; /* DWORD 0 */ ++ u8 interrupt54; /* DWORD 0 */ ++ u8 interrupt55; /* DWORD 0 */ ++ u8 interrupt56; /* DWORD 0 */ ++ u8 interrupt57; /* DWORD 0 */ ++ u8 interrupt58; /* DWORD 0 */ ++ u8 interrupt59; /* DWORD 0 */ ++ u8 interrupt60; /* DWORD 0 */ ++ u8 interrupt61; /* DWORD 0 */ ++ u8 interrupt62; /* DWORD 0 */ ++ u8 interrupt63; /* DWORD 0 */ ++} __packed; ++struct CEV_ISR1_CSR_AMAP { ++ u32 dw[1]; ++}; ++/* ++ * Host Interrupt Status Register 2. The third of four application ++ * interrupt status registers. This register contains the interrupts ++ * for Event Queues EQ64 through EQ95. ++ */ ++struct BE_CEV_ISR2_CSR_AMAP { ++ u8 interrupt64; /* DWORD 0 */ ++ u8 interrupt65; /* DWORD 0 */ ++ u8 interrupt66; /* DWORD 0 */ ++ u8 interrupt67; /* DWORD 0 */ ++ u8 interrupt68; /* DWORD 0 */ ++ u8 interrupt69; /* DWORD 0 */ ++ u8 interrupt70; /* DWORD 0 */ ++ u8 interrupt71; /* DWORD 0 */ ++ u8 interrupt72; /* DWORD 0 */ ++ u8 interrupt73; /* DWORD 0 */ ++ u8 interrupt74; /* DWORD 0 */ ++ u8 interrupt75; /* DWORD 0 */ ++ u8 interrupt76; /* DWORD 0 */ ++ u8 interrupt77; /* DWORD 0 */ ++ u8 interrupt78; /* DWORD 0 */ ++ u8 interrupt79; /* DWORD 0 */ ++ u8 interrupt80; /* DWORD 0 */ ++ u8 interrupt81; /* DWORD 0 */ ++ u8 interrupt82; /* DWORD 0 */ ++ u8 interrupt83; /* DWORD 0 */ ++ u8 interrupt84; /* DWORD 0 */ ++ u8 interrupt85; /* DWORD 0 */ ++ u8 interrupt86; /* DWORD 0 */ ++ u8 interrupt87; /* DWORD 0 */ ++ u8 interrupt88; /* DWORD 0 */ ++ u8 interrupt89; /* DWORD 0 */ ++ u8 interrupt90; /* DWORD 0 */ ++ u8 interrupt91; /* DWORD 0 */ ++ u8 interrupt92; /* DWORD 0 */ ++ u8 interrupt93; /* DWORD 0 */ ++ u8 interrupt94; /* DWORD 0 */ ++ u8 interrupt95; /* DWORD 0 */ ++} __packed; ++struct CEV_ISR2_CSR_AMAP { ++ u32 dw[1]; ++}; ++ ++/* ++ * Host Interrupt Status Register 3. The fourth of four application ++ * interrupt status registers. This register contains the interrupts ++ * for Event Queues EQ96 through EQ127. ++ */ ++struct BE_CEV_ISR3_CSR_AMAP { ++ u8 interrupt96; /* DWORD 0 */ ++ u8 interrupt97; /* DWORD 0 */ ++ u8 interrupt98; /* DWORD 0 */ ++ u8 interrupt99; /* DWORD 0 */ ++ u8 interrupt100; /* DWORD 0 */ ++ u8 interrupt101; /* DWORD 0 */ ++ u8 interrupt102; /* DWORD 0 */ ++ u8 interrupt103; /* DWORD 0 */ ++ u8 interrupt104; /* DWORD 0 */ ++ u8 interrupt105; /* DWORD 0 */ ++ u8 interrupt106; /* DWORD 0 */ ++ u8 interrupt107; /* DWORD 0 */ ++ u8 interrupt108; /* DWORD 0 */ ++ u8 interrupt109; /* DWORD 0 */ ++ u8 interrupt110; /* DWORD 0 */ ++ u8 interrupt111; /* DWORD 0 */ ++ u8 interrupt112; /* DWORD 0 */ ++ u8 interrupt113; /* DWORD 0 */ ++ u8 interrupt114; /* DWORD 0 */ ++ u8 interrupt115; /* DWORD 0 */ ++ u8 interrupt116; /* DWORD 0 */ ++ u8 interrupt117; /* DWORD 0 */ ++ u8 interrupt118; /* DWORD 0 */ ++ u8 interrupt119; /* DWORD 0 */ ++ u8 interrupt120; /* DWORD 0 */ ++ u8 interrupt121; /* DWORD 0 */ ++ u8 interrupt122; /* DWORD 0 */ ++ u8 interrupt123; /* DWORD 0 */ ++ u8 interrupt124; /* DWORD 0 */ ++ u8 interrupt125; /* DWORD 0 */ ++ u8 interrupt126; /* DWORD 0 */ ++ u8 interrupt127; /* DWORD 0 */ ++} __packed; ++struct CEV_ISR3_CSR_AMAP { ++ u32 dw[1]; ++}; ++ ++/* Completions and Events block Registers. */ ++struct BE_CEV_CSRMAP_AMAP { ++ u8 rsvd0[32]; /* DWORD 0 */ ++ u8 rsvd1[32]; /* DWORD 1 */ ++ u8 rsvd2[32]; /* DWORD 2 */ ++ u8 rsvd3[32]; /* DWORD 3 */ ++ struct BE_CEV_ISR0_CSR_AMAP isr0; ++ struct BE_CEV_ISR1_CSR_AMAP isr1; ++ struct BE_CEV_ISR2_CSR_AMAP isr2; ++ struct BE_CEV_ISR3_CSR_AMAP isr3; ++ u8 rsvd4[32]; /* DWORD 8 */ ++ u8 rsvd5[32]; /* DWORD 9 */ ++ u8 rsvd6[32]; /* DWORD 10 */ ++ u8 rsvd7[32]; /* DWORD 11 */ ++ u8 rsvd8[32]; /* DWORD 12 */ ++ u8 rsvd9[32]; /* DWORD 13 */ ++ u8 rsvd10[32]; /* DWORD 14 */ ++ u8 rsvd11[32]; /* DWORD 15 */ ++ u8 rsvd12[32]; /* DWORD 16 */ ++ u8 rsvd13[32]; /* DWORD 17 */ ++ u8 rsvd14[32]; /* DWORD 18 */ ++ u8 rsvd15[32]; /* DWORD 19 */ ++ u8 rsvd16[32]; /* DWORD 20 */ ++ u8 rsvd17[32]; /* DWORD 21 */ ++ u8 rsvd18[32]; /* DWORD 22 */ ++ u8 rsvd19[32]; /* DWORD 23 */ ++ u8 rsvd20[32]; /* DWORD 24 */ ++ u8 rsvd21[32]; /* DWORD 25 */ ++ u8 rsvd22[32]; /* DWORD 26 */ ++ u8 rsvd23[32]; /* DWORD 27 */ ++ u8 rsvd24[32]; /* DWORD 28 */ ++ u8 rsvd25[32]; /* DWORD 29 */ ++ u8 rsvd26[32]; /* DWORD 30 */ ++ u8 rsvd27[32]; /* DWORD 31 */ ++ u8 rsvd28[32]; /* DWORD 32 */ ++ u8 rsvd29[32]; /* DWORD 33 */ ++ u8 rsvd30[192]; /* DWORD 34 */ ++ u8 rsvd31[192]; /* DWORD 40 */ ++ u8 rsvd32[160]; /* DWORD 46 */ ++ u8 rsvd33[160]; /* DWORD 51 */ ++ u8 rsvd34[160]; /* DWORD 56 */ ++ u8 rsvd35[96]; /* DWORD 61 */ ++ u8 rsvd36[192][32]; /* DWORD 64 */ ++} __packed; ++struct CEV_CSRMAP_AMAP { ++ u32 dw[256]; ++}; ++ ++#endif /* __cev_amap_h__ */ +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/drivers/staging/benet/cq.c linux-2.6.29-rc3.owrt/drivers/staging/benet/cq.c +--- linux-2.6.29.owrt/drivers/staging/benet/cq.c 1970-01-01 01:00:00.000000000 +0100 ++++ linux-2.6.29-rc3.owrt/drivers/staging/benet/cq.c 2009-05-10 23:48:29.000000000 +0200 +@@ -0,0 +1,211 @@ ++/* ++ * Copyright (C) 2005 - 2008 ServerEngines ++ * All rights reserved. ++ * ++ * 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. The full GNU General ++ * Public License is included in this distribution in the file called COPYING. ++ * ++ * Contact Information: ++ * linux-drivers@serverengines.com ++ * ++ * ServerEngines ++ * 209 N. Fair Oaks Ave ++ * Sunnyvale, CA 94085 ++ */ ++#include "hwlib.h" ++#include "bestatus.h" ++ ++/* ++ * Completion Queue Objects ++ */ ++/* ++ *============================================================================ ++ * P U B L I C R O U T I N E S ++ *============================================================================ ++ */ ++ ++/* ++ This routine creates a completion queue based on the client completion ++ queue configuration information. ++ ++ ++ FunctionObject - Handle to a function object ++ CqBaseVa - Base VA for a the CQ ring ++ NumEntries - CEV_CQ_CNT_* values ++ solEventEnable - 0 = All CQEs can generate Events if CQ is eventable ++ 1 = only CQEs with solicited bit set are eventable ++ eventable - Eventable CQ, generates interrupts. ++ nodelay - 1 = Force interrupt, relevent if CQ eventable. ++ Interrupt is asserted immediately after EQE ++ write is confirmed, regardless of EQ Timer ++ or watermark settings. ++ wme - Enable watermark based coalescing ++ wmThresh - High watermark(CQ fullness at which event ++ or interrupt should be asserted). These are the ++ CEV_WATERMARK encoded values. ++ EqObject - EQ Handle to assign to this CQ ++ ppCqObject - Internal CQ Handle returned. ++ ++ Returns BE_SUCCESS if successfull, otherwise a useful error code is ++ returned. ++ ++ IRQL < DISPATCH_LEVEL ++ ++*/ ++int be_cq_create(struct be_function_object *pfob, ++ struct ring_desc *rd, u32 length, bool solicited_eventable, ++ bool no_delay, u32 wm_thresh, ++ struct be_eq_object *eq_object, struct be_cq_object *cq_object) ++{ ++ int status = BE_SUCCESS; ++ u32 num_entries_encoding; ++ u32 num_entries = length / sizeof(struct MCC_CQ_ENTRY_AMAP); ++ struct FWCMD_COMMON_CQ_CREATE *fwcmd = NULL; ++ struct MCC_WRB_AMAP *wrb = NULL; ++ u32 n; ++ unsigned long irql; ++ ++ ASSERT(rd); ++ ASSERT(cq_object); ++ ASSERT(length % sizeof(struct MCC_CQ_ENTRY_AMAP) == 0); ++ ++ switch (num_entries) { ++ case 256: ++ num_entries_encoding = CEV_CQ_CNT_256; ++ break; ++ case 512: ++ num_entries_encoding = CEV_CQ_CNT_512; ++ break; ++ case 1024: ++ num_entries_encoding = CEV_CQ_CNT_1024; ++ break; ++ default: ++ ASSERT(0); ++ return BE_STATUS_INVALID_PARAMETER; ++ } ++ ++ /* ++ * All cq entries all the same size. Use iSCSI version ++ * as a test for the proper rd length. ++ */ ++ memset(cq_object, 0, sizeof(*cq_object)); ++ ++ atomic_set(&cq_object->ref_count, 0); ++ cq_object->parent_function = pfob; ++ cq_object->eq_object = eq_object; ++ cq_object->num_entries = num_entries; ++ /* save for MCC cq processing */ ++ cq_object->va = rd->va; ++ ++ /* map into UT. */ ++ length = num_entries * sizeof(struct MCC_CQ_ENTRY_AMAP); ++ ++ spin_lock_irqsave(&pfob->post_lock, irql); ++ ++ wrb = be_function_peek_mcc_wrb(pfob); ++ if (!wrb) { ++ ASSERT(wrb); ++ TRACE(DL_ERR, "No free MCC WRBs in create EQ."); ++ status = BE_STATUS_NO_MCC_WRB; ++ goto Error; ++ } ++ /* Prepares an embedded fwcmd, including request/response sizes. */ ++ fwcmd = BE_PREPARE_EMBEDDED_FWCMD(pfob, wrb, COMMON_CQ_CREATE); ++ ++ fwcmd->params.request.num_pages = PAGES_SPANNED(OFFSET_IN_PAGE(rd->va), ++ length); ++ ++ AMAP_SET_BITS_PTR(CQ_CONTEXT, valid, &fwcmd->params.request.context, 1); ++ n = pfob->pci_function_number; ++ AMAP_SET_BITS_PTR(CQ_CONTEXT, Func, &fwcmd->params.request.context, n); ++ ++ n = (eq_object != NULL); ++ AMAP_SET_BITS_PTR(CQ_CONTEXT, Eventable, ++ &fwcmd->params.request.context, n); ++ AMAP_SET_BITS_PTR(CQ_CONTEXT, Armed, &fwcmd->params.request.context, 1); ++ ++ n = eq_object ? eq_object->eq_id : 0; ++ AMAP_SET_BITS_PTR(CQ_CONTEXT, EQID, &fwcmd->params.request.context, n); ++ AMAP_SET_BITS_PTR(CQ_CONTEXT, Count, ++ &fwcmd->params.request.context, num_entries_encoding); ++ ++ n = 0; /* Protection Domain is always 0 in Linux driver */ ++ AMAP_SET_BITS_PTR(CQ_CONTEXT, PD, &fwcmd->params.request.context, n); ++ AMAP_SET_BITS_PTR(CQ_CONTEXT, NoDelay, ++ &fwcmd->params.request.context, no_delay); ++ AMAP_SET_BITS_PTR(CQ_CONTEXT, SolEvent, ++ &fwcmd->params.request.context, solicited_eventable); ++ ++ n = (wm_thresh != 0xFFFFFFFF); ++ AMAP_SET_BITS_PTR(CQ_CONTEXT, WME, &fwcmd->params.request.context, n); ++ ++ n = (n ? wm_thresh : 0); ++ AMAP_SET_BITS_PTR(CQ_CONTEXT, Watermark, ++ &fwcmd->params.request.context, n); ++ /* Create a page list for the FWCMD. */ ++ be_rd_to_pa_list(rd, fwcmd->params.request.pages, ++ ARRAY_SIZE(fwcmd->params.request.pages)); ++ ++ /* Post the f/w command */ ++ status = be_function_post_mcc_wrb(pfob, wrb, NULL, NULL, NULL, ++ NULL, NULL, fwcmd, NULL); ++ if (status != BE_SUCCESS) { ++ TRACE(DL_ERR, "MCC to create CQ failed."); ++ goto Error; ++ } ++ /* Remember the CQ id. */ ++ cq_object->cq_id = fwcmd->params.response.cq_id; ++ ++ /* insert this cq into eq_object reference */ ++ if (eq_object) { ++ atomic_inc(&eq_object->ref_count); ++ list_add_tail(&cq_object->cqlist_for_eq, ++ &eq_object->cq_list_head); ++ } ++ ++Error: ++ spin_unlock_irqrestore(&pfob->post_lock, irql); ++ ++ if (pfob->pend_queue_driving && pfob->mcc) { ++ pfob->pend_queue_driving = 0; ++ be_drive_mcc_wrb_queue(pfob->mcc); ++ } ++ return status; ++} ++ ++/* ++ ++ Deferences the given object. Once the object's reference count drops to ++ zero, the object is destroyed and all resources that are held by this object ++ are released. The on-chip context is also destroyed along with the queue ++ ID, and any mappings made into the UT. ++ ++ cq_object - CQ handle returned from cq_object_create. ++ ++ returns the current reference count on the object ++ ++ IRQL: IRQL < DISPATCH_LEVEL ++*/ ++int be_cq_destroy(struct be_cq_object *cq_object) ++{ ++ int status = 0; ++ ++ /* Nothing should reference this CQ at this point. */ ++ ASSERT(atomic_read(&cq_object->ref_count) == 0); ++ ++ /* Send fwcmd to destroy the CQ. */ ++ status = be_function_ring_destroy(cq_object->parent_function, ++ cq_object->cq_id, FWCMD_RING_TYPE_CQ, ++ NULL, NULL, NULL, NULL); ++ ASSERT(status == 0); ++ ++ /* Remove reference if this is an eventable CQ. */ ++ if (cq_object->eq_object) { ++ atomic_dec(&cq_object->eq_object->ref_count); ++ list_del(&cq_object->cqlist_for_eq); ++ } ++ return BE_SUCCESS; ++} ++ +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/drivers/staging/benet/descriptors.h linux-2.6.29-rc3.owrt/drivers/staging/benet/descriptors.h +--- linux-2.6.29.owrt/drivers/staging/benet/descriptors.h 1970-01-01 01:00:00.000000000 +0100 ++++ linux-2.6.29-rc3.owrt/drivers/staging/benet/descriptors.h 2009-05-10 23:48:29.000000000 +0200 +@@ -0,0 +1,71 @@ ++/* ++ * Copyright (C) 2005 - 2008 ServerEngines ++ * All rights reserved. ++ * ++ * 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. The full GNU General ++ * Public License is included in this distribution in the file called COPYING. ++ * ++ * Contact Information: ++ * linux-drivers@serverengines.com ++ * ++ * ServerEngines ++ * 209 N. Fair Oaks Ave ++ * Sunnyvale, CA 94085 ++ */ ++/* ++ * Autogenerated by srcgen version: 0127 ++ */ ++#ifndef __descriptors_amap_h__ ++#define __descriptors_amap_h__ ++ ++/* ++ * --- IPC_NODE_ID_ENUM --- ++ * IPC processor id values ++ */ ++#define TPOST_NODE_ID (0) /* TPOST ID */ ++#define TPRE_NODE_ID (1) /* TPRE ID */ ++#define TXULP0_NODE_ID (2) /* TXULP0 ID */ ++#define TXULP1_NODE_ID (3) /* TXULP1 ID */ ++#define TXULP2_NODE_ID (4) /* TXULP2 ID */ ++#define RXULP0_NODE_ID (5) /* RXULP0 ID */ ++#define RXULP1_NODE_ID (6) /* RXULP1 ID */ ++#define RXULP2_NODE_ID (7) /* RXULP2 ID */ ++#define MPU_NODE_ID (15) /* MPU ID */ ++ ++/* ++ * --- MAC_ID_ENUM --- ++ * Meaning of the mac_id field in rxpp_eth_d ++ */ ++#define PORT0_HOST_MAC0 (0) /* PD 0, Port 0, host networking, MAC 0. */ ++#define PORT0_HOST_MAC1 (1) /* PD 0, Port 0, host networking, MAC 1. */ ++#define PORT0_STORAGE_MAC0 (2) /* PD 0, Port 0, host storage, MAC 0. */ ++#define PORT0_STORAGE_MAC1 (3) /* PD 0, Port 0, host storage, MAC 1. */ ++#define PORT1_HOST_MAC0 (4) /* PD 0, Port 1 host networking, MAC 0. */ ++#define PORT1_HOST_MAC1 (5) /* PD 0, Port 1 host networking, MAC 1. */ ++#define PORT1_STORAGE_MAC0 (6) /* PD 0, Port 1 host storage, MAC 0. */ ++#define PORT1_STORAGE_MAC1 (7) /* PD 0, Port 1 host storage, MAC 1. */ ++#define FIRST_VM_MAC (8) /* PD 1 MAC. Protection domains have IDs */ ++ /* from 0x8-0x26, one per PD. */ ++#define LAST_VM_MAC (38) /* PD 31 MAC. */ ++#define MGMT_MAC (39) /* Management port MAC. */ ++#define MARBLE_MAC0 (59) /* Used for flushing function 0 receive */ ++ /* ++ * queues before re-using a torn-down ++ * receive ring. the DA = ++ * 00-00-00-00-00-00, and the MSB of the ++ * SA = 00 ++ */ ++#define MARBLE_MAC1 (60) /* Used for flushing function 1 receive */ ++ /* ++ * queues before re-using a torn-down ++ * receive ring. the DA = ++ * 00-00-00-00-00-00, and the MSB of the ++ * SA != 00 ++ */ ++#define NULL_MAC (61) /* Promiscuous mode, indicates no match */ ++#define MCAST_MAC (62) /* Multicast match. */ ++#define BCAST_MATCH (63) /* Broadcast match. */ ++ ++#endif /* __descriptors_amap_h__ */ +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/drivers/staging/benet/doorbells.h linux-2.6.29-rc3.owrt/drivers/staging/benet/doorbells.h +--- linux-2.6.29.owrt/drivers/staging/benet/doorbells.h 1970-01-01 01:00:00.000000000 +0100 ++++ linux-2.6.29-rc3.owrt/drivers/staging/benet/doorbells.h 2009-05-10 23:48:29.000000000 +0200 +@@ -0,0 +1,179 @@ ++/* ++ * Copyright (C) 2005 - 2008 ServerEngines ++ * All rights reserved. ++ * ++ * 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. The full GNU General ++ * Public License is included in this distribution in the file called COPYING. ++ * ++ * Contact Information: ++ * linux-drivers@serverengines.com ++ * ++ * ServerEngines ++ * 209 N. Fair Oaks Ave ++ * Sunnyvale, CA 94085 ++ */ ++/* ++ * Autogenerated by srcgen version: 0127 ++ */ ++#ifndef __doorbells_amap_h__ ++#define __doorbells_amap_h__ ++ ++/* The TX/RDMA send queue doorbell. */ ++struct BE_SQ_DB_AMAP { ++ u8 cid[11]; /* DWORD 0 */ ++ u8 rsvd0[5]; /* DWORD 0 */ ++ u8 numPosted[14]; /* DWORD 0 */ ++ u8 rsvd1[2]; /* DWORD 0 */ ++} __packed; ++struct SQ_DB_AMAP { ++ u32 dw[1]; ++}; ++ ++/* The receive queue doorbell. */ ++struct BE_RQ_DB_AMAP { ++ u8 rq[10]; /* DWORD 0 */ ++ u8 rsvd0[13]; /* DWORD 0 */ ++ u8 Invalidate; /* DWORD 0 */ ++ u8 numPosted[8]; /* DWORD 0 */ ++} __packed; ++struct RQ_DB_AMAP { ++ u32 dw[1]; ++}; ++ ++/* ++ * The CQ/EQ doorbell. Software MUST set reserved fields in this ++ * descriptor to zero, otherwise (CEV) hardware will not execute the ++ * doorbell (flagging a bad_db_qid error instead). ++ */ ++struct BE_CQ_DB_AMAP { ++ u8 qid[10]; /* DWORD 0 */ ++ u8 rsvd0[4]; /* DWORD 0 */ ++ u8 rearm; /* DWORD 0 */ ++ u8 event; /* DWORD 0 */ ++ u8 num_popped[13]; /* DWORD 0 */ ++ u8 rsvd1[3]; /* DWORD 0 */ ++} __packed; ++struct CQ_DB_AMAP { ++ u32 dw[1]; ++}; ++ ++struct BE_TPM_RQ_DB_AMAP { ++ u8 qid[10]; /* DWORD 0 */ ++ u8 rsvd0[6]; /* DWORD 0 */ ++ u8 numPosted[11]; /* DWORD 0 */ ++ u8 mss_cnt[5]; /* DWORD 0 */ ++} __packed; ++struct TPM_RQ_DB_AMAP { ++ u32 dw[1]; ++}; ++ ++/* ++ * Post WRB Queue Doorbell Register used by the host Storage stack ++ * to notify the controller of a posted Work Request Block ++ */ ++struct BE_WRB_POST_DB_AMAP { ++ u8 wrb_cid[10]; /* DWORD 0 */ ++ u8 rsvd0[6]; /* DWORD 0 */ ++ u8 wrb_index[8]; /* DWORD 0 */ ++ u8 numberPosted[8]; /* DWORD 0 */ ++} __packed; ++struct WRB_POST_DB_AMAP { ++ u32 dw[1]; ++}; ++ ++/* ++ * Update Default PDU Queue Doorbell Register used to communicate ++ * to the controller that the driver has stopped processing the queue ++ * and where in the queue it stopped, this is ++ * a CQ Entry Type. Used by storage driver. ++ */ ++struct BE_DEFAULT_PDU_DB_AMAP { ++ u8 qid[10]; /* DWORD 0 */ ++ u8 rsvd0[4]; /* DWORD 0 */ ++ u8 rearm; /* DWORD 0 */ ++ u8 event; /* DWORD 0 */ ++ u8 cqproc[14]; /* DWORD 0 */ ++ u8 rsvd1[2]; /* DWORD 0 */ ++} __packed; ++struct DEFAULT_PDU_DB_AMAP { ++ u32 dw[1]; ++}; ++ ++/* Management Command and Controller default fragment ring */ ++struct BE_MCC_DB_AMAP { ++ u8 rid[11]; /* DWORD 0 */ ++ u8 rsvd0[5]; /* DWORD 0 */ ++ u8 numPosted[14]; /* DWORD 0 */ ++ u8 rsvd1[2]; /* DWORD 0 */ ++} __packed; ++struct MCC_DB_AMAP { ++ u32 dw[1]; ++}; ++ ++/* ++ * Used for bootstrapping the Host interface. This register is ++ * used for driver communication with the MPU when no MCC Rings exist. ++ * The software must write this register twice to post any MCC ++ * command. First, it writes the register with hi=1 and the upper bits of ++ * the physical address for the MCC_MAILBOX structure. Software must poll ++ * the ready bit until this is acknowledged. Then, sotware writes the ++ * register with hi=0 with the lower bits in the address. It must ++ * poll the ready bit until the MCC command is complete. Upon completion, ++ * the MCC_MAILBOX will contain a valid completion queue entry. ++ */ ++struct BE_MPU_MAILBOX_DB_AMAP { ++ u8 ready; /* DWORD 0 */ ++ u8 hi; /* DWORD 0 */ ++ u8 address[30]; /* DWORD 0 */ ++} __packed; ++struct MPU_MAILBOX_DB_AMAP { ++ u32 dw[1]; ++}; ++ ++/* ++ * This is the protection domain doorbell register map. Note that ++ * while this map shows doorbells for all Blade Engine supported ++ * protocols, not all of these may be valid in a given function or ++ * protection domain. It is the responsibility of the application ++ * accessing the doorbells to know which are valid. Each doorbell ++ * occupies 32 bytes of space, but unless otherwise specified, ++ * only the first 4 bytes should be written. There are 32 instances ++ * of these doorbells for the host and 31 virtual machines respectively. ++ * The host and VMs will only map the doorbell pages belonging to its ++ * protection domain. It will not be able to touch the doorbells for ++ * another VM. The doorbells are the only registers directly accessible ++ * by a virtual machine. Similarly, there are 511 additional ++ * doorbells for RDMA protection domains. PD 0 for RDMA shares ++ * the same physical protection domain doorbell page as ETH/iSCSI. ++ * ++ */ ++struct BE_PROTECTION_DOMAIN_DBMAP_AMAP { ++ u8 rsvd0[512]; /* DWORD 0 */ ++ struct BE_SQ_DB_AMAP rdma_sq_db; ++ u8 rsvd1[7][32]; /* DWORD 17 */ ++ struct BE_WRB_POST_DB_AMAP iscsi_wrb_post_db; ++ u8 rsvd2[7][32]; /* DWORD 25 */ ++ struct BE_SQ_DB_AMAP etx_sq_db; ++ u8 rsvd3[7][32]; /* DWORD 33 */ ++ struct BE_RQ_DB_AMAP rdma_rq_db; ++ u8 rsvd4[7][32]; /* DWORD 41 */ ++ struct BE_DEFAULT_PDU_DB_AMAP iscsi_default_pdu_db; ++ u8 rsvd5[7][32]; /* DWORD 49 */ ++ struct BE_TPM_RQ_DB_AMAP tpm_rq_db; ++ u8 rsvd6[7][32]; /* DWORD 57 */ ++ struct BE_RQ_DB_AMAP erx_rq_db; ++ u8 rsvd7[7][32]; /* DWORD 65 */ ++ struct BE_CQ_DB_AMAP cq_db; ++ u8 rsvd8[7][32]; /* DWORD 73 */ ++ struct BE_MCC_DB_AMAP mpu_mcc_db; ++ u8 rsvd9[7][32]; /* DWORD 81 */ ++ struct BE_MPU_MAILBOX_DB_AMAP mcc_bootstrap_db; ++ u8 rsvd10[935][32]; /* DWORD 89 */ ++} __packed; ++struct PROTECTION_DOMAIN_DBMAP_AMAP { ++ u32 dw[1024]; ++}; ++ ++#endif /* __doorbells_amap_h__ */ +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/drivers/staging/benet/ep.h linux-2.6.29-rc3.owrt/drivers/staging/benet/ep.h +--- linux-2.6.29.owrt/drivers/staging/benet/ep.h 1970-01-01 01:00:00.000000000 +0100 ++++ linux-2.6.29-rc3.owrt/drivers/staging/benet/ep.h 2009-05-10 23:48:29.000000000 +0200 +@@ -0,0 +1,66 @@ ++/* ++ * Copyright (C) 2005 - 2008 ServerEngines ++ * All rights reserved. ++ * ++ * 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. The full GNU General ++ * Public License is included in this distribution in the file called COPYING. ++ * ++ * Contact Information: ++ * linux-drivers@serverengines.com ++ * ++ * ServerEngines ++ * 209 N. Fair Oaks Ave ++ * Sunnyvale, CA 94085 ++ */ ++/* ++ * Autogenerated by srcgen version: 0127 ++ */ ++#ifndef __ep_amap_h__ ++#define __ep_amap_h__ ++ ++/* General Control and Status Register. */ ++struct BE_EP_CONTROL_CSR_AMAP { ++ u8 m0_RxPbuf; /* DWORD 0 */ ++ u8 m1_RxPbuf; /* DWORD 0 */ ++ u8 m2_RxPbuf; /* DWORD 0 */ ++ u8 ff_en; /* DWORD 0 */ ++ u8 rsvd0[27]; /* DWORD 0 */ ++ u8 CPU_reset; /* DWORD 0 */ ++} __packed; ++struct EP_CONTROL_CSR_AMAP { ++ u32 dw[1]; ++}; ++ ++/* Semaphore Register. */ ++struct BE_EP_SEMAPHORE_CSR_AMAP { ++ u8 value[32]; /* DWORD 0 */ ++} __packed; ++struct EP_SEMAPHORE_CSR_AMAP { ++ u32 dw[1]; ++}; ++ ++/* Embedded Processor Specific Registers. */ ++struct BE_EP_CSRMAP_AMAP { ++ struct BE_EP_CONTROL_CSR_AMAP ep_control; ++ u8 rsvd0[32]; /* DWORD 1 */ ++ u8 rsvd1[32]; /* DWORD 2 */ ++ u8 rsvd2[32]; /* DWORD 3 */ ++ u8 rsvd3[32]; /* DWORD 4 */ ++ u8 rsvd4[32]; /* DWORD 5 */ ++ u8 rsvd5[8][128]; /* DWORD 6 */ ++ u8 rsvd6[32]; /* DWORD 38 */ ++ u8 rsvd7[32]; /* DWORD 39 */ ++ u8 rsvd8[32]; /* DWORD 40 */ ++ u8 rsvd9[32]; /* DWORD 41 */ ++ u8 rsvd10[32]; /* DWORD 42 */ ++ struct BE_EP_SEMAPHORE_CSR_AMAP ep_semaphore; ++ u8 rsvd11[32]; /* DWORD 44 */ ++ u8 rsvd12[19][32]; /* DWORD 45 */ ++} __packed; ++struct EP_CSRMAP_AMAP { ++ u32 dw[64]; ++}; ++ ++#endif /* __ep_amap_h__ */ +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/drivers/staging/benet/eq.c linux-2.6.29-rc3.owrt/drivers/staging/benet/eq.c +--- linux-2.6.29.owrt/drivers/staging/benet/eq.c 1970-01-01 01:00:00.000000000 +0100 ++++ linux-2.6.29-rc3.owrt/drivers/staging/benet/eq.c 2009-05-10 23:48:29.000000000 +0200 +@@ -0,0 +1,299 @@ ++/* ++ * Copyright (C) 2005 - 2008 ServerEngines ++ * All rights reserved. ++ * ++ * 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. The full GNU General ++ * Public License is included in this distribution in the file called COPYING. ++ * ++ * Contact Information: ++ * linux-drivers@serverengines.com ++ * ++ * ServerEngines ++ * 209 N. Fair Oaks Ave ++ * Sunnyvale, CA 94085 ++ */ ++#include "hwlib.h" ++#include "bestatus.h" ++/* ++ This routine creates an event queue based on the client completion ++ queue configuration information. ++ ++ FunctionObject - Handle to a function object ++ EqBaseVa - Base VA for a the EQ ring ++ SizeEncoding - The encoded size for the EQ entries. This value is ++ either CEV_EQ_SIZE_4 or CEV_EQ_SIZE_16 ++ NumEntries - CEV_CQ_CNT_* values. ++ Watermark - Enables watermark based coalescing. This parameter ++ must be of the type CEV_WMARK_* if watermarks ++ are enabled. If watermarks to to be disabled ++ this value should be-1. ++ TimerDelay - If a timer delay is enabled this value should be the ++ time of the delay in 8 microsecond units. If ++ delays are not used this parameter should be ++ set to -1. ++ ppEqObject - Internal EQ Handle returned. ++ ++ Returns BE_SUCCESS if successfull,, otherwise a useful error code ++ is returned. ++ ++ IRQL < DISPATCH_LEVEL ++*/ ++int ++be_eq_create(struct be_function_object *pfob, ++ struct ring_desc *rd, u32 eqe_size, u32 num_entries, ++ u32 watermark, /* CEV_WMARK_* or -1 */ ++ u32 timer_delay, /* in 8us units, or -1 */ ++ struct be_eq_object *eq_object) ++{ ++ int status = BE_SUCCESS; ++ u32 num_entries_encoding, eqe_size_encoding, length; ++ struct FWCMD_COMMON_EQ_CREATE *fwcmd = NULL; ++ struct MCC_WRB_AMAP *wrb = NULL; ++ u32 n; ++ unsigned long irql; ++ ++ ASSERT(rd); ++ ASSERT(eq_object); ++ ++ switch (num_entries) { ++ case 256: ++ num_entries_encoding = CEV_EQ_CNT_256; ++ break; ++ case 512: ++ num_entries_encoding = CEV_EQ_CNT_512; ++ break; ++ case 1024: ++ num_entries_encoding = CEV_EQ_CNT_1024; ++ break; ++ case 2048: ++ num_entries_encoding = CEV_EQ_CNT_2048; ++ break; ++ case 4096: ++ num_entries_encoding = CEV_EQ_CNT_4096; ++ break; ++ default: ++ ASSERT(0); ++ return BE_STATUS_INVALID_PARAMETER; ++ } ++ ++ switch (eqe_size) { ++ case 4: ++ eqe_size_encoding = CEV_EQ_SIZE_4; ++ break; ++ case 16: ++ eqe_size_encoding = CEV_EQ_SIZE_16; ++ break; ++ default: ++ ASSERT(0); ++ return BE_STATUS_INVALID_PARAMETER; ++ } ++ ++ if ((eqe_size == 4 && num_entries < 1024) || ++ (eqe_size == 16 && num_entries == 4096)) { ++ TRACE(DL_ERR, "Bad EQ size. eqe_size:%d num_entries:%d", ++ eqe_size, num_entries); ++ ASSERT(0); ++ return BE_STATUS_INVALID_PARAMETER; ++ } ++ ++ memset(eq_object, 0, sizeof(*eq_object)); ++ ++ atomic_set(&eq_object->ref_count, 0); ++ eq_object->parent_function = pfob; ++ eq_object->eq_id = 0xFFFFFFFF; ++ ++ INIT_LIST_HEAD(&eq_object->cq_list_head); ++ ++ length = num_entries * eqe_size; ++ ++ spin_lock_irqsave(&pfob->post_lock, irql); ++ ++ wrb = be_function_peek_mcc_wrb(pfob); ++ if (!wrb) { ++ ASSERT(wrb); ++ TRACE(DL_ERR, "No free MCC WRBs in create EQ."); ++ status = BE_STATUS_NO_MCC_WRB; ++ goto Error; ++ } ++ /* Prepares an embedded fwcmd, including request/response sizes. */ ++ fwcmd = BE_PREPARE_EMBEDDED_FWCMD(pfob, wrb, COMMON_EQ_CREATE); ++ ++ fwcmd->params.request.num_pages = PAGES_SPANNED(OFFSET_IN_PAGE(rd->va), ++ length); ++ n = pfob->pci_function_number; ++ AMAP_SET_BITS_PTR(EQ_CONTEXT, Func, &fwcmd->params.request.context, n); ++ ++ AMAP_SET_BITS_PTR(EQ_CONTEXT, valid, &fwcmd->params.request.context, 1); ++ ++ AMAP_SET_BITS_PTR(EQ_CONTEXT, Size, ++ &fwcmd->params.request.context, eqe_size_encoding); ++ ++ n = 0; /* Protection Domain is always 0 in Linux driver */ ++ AMAP_SET_BITS_PTR(EQ_CONTEXT, PD, &fwcmd->params.request.context, n); ++ ++ /* Let the caller ARM the EQ with the doorbell. */ ++ AMAP_SET_BITS_PTR(EQ_CONTEXT, Armed, &fwcmd->params.request.context, 0); ++ ++ AMAP_SET_BITS_PTR(EQ_CONTEXT, Count, &fwcmd->params.request.context, ++ num_entries_encoding); ++ ++ n = pfob->pci_function_number * 32; ++ AMAP_SET_BITS_PTR(EQ_CONTEXT, EventVect, ++ &fwcmd->params.request.context, n); ++ if (watermark != -1) { ++ AMAP_SET_BITS_PTR(EQ_CONTEXT, WME, ++ &fwcmd->params.request.context, 1); ++ AMAP_SET_BITS_PTR(EQ_CONTEXT, Watermark, ++ &fwcmd->params.request.context, watermark); ++ ASSERT(watermark <= CEV_WMARK_240); ++ } else ++ AMAP_SET_BITS_PTR(EQ_CONTEXT, WME, ++ &fwcmd->params.request.context, 0); ++ if (timer_delay != -1) { ++ AMAP_SET_BITS_PTR(EQ_CONTEXT, TMR, ++ &fwcmd->params.request.context, 1); ++ ++ ASSERT(timer_delay <= 250); /* max value according to EAS */ ++ timer_delay = min(timer_delay, (u32)250); ++ ++ AMAP_SET_BITS_PTR(EQ_CONTEXT, Delay, ++ &fwcmd->params.request.context, timer_delay); ++ } else { ++ AMAP_SET_BITS_PTR(EQ_CONTEXT, TMR, ++ &fwcmd->params.request.context, 0); ++ } ++ /* Create a page list for the FWCMD. */ ++ be_rd_to_pa_list(rd, fwcmd->params.request.pages, ++ ARRAY_SIZE(fwcmd->params.request.pages)); ++ ++ status = be_function_post_mcc_wrb(pfob, wrb, NULL, NULL, NULL, ++ NULL, NULL, fwcmd, NULL); ++ if (status != BE_SUCCESS) { ++ TRACE(DL_ERR, "MCC to create EQ failed."); ++ goto Error; ++ } ++ /* Get the EQ id. The MPU allocates the IDs. */ ++ eq_object->eq_id = fwcmd->params.response.eq_id; ++ ++Error: ++ spin_unlock_irqrestore(&pfob->post_lock, irql); ++ ++ if (pfob->pend_queue_driving && pfob->mcc) { ++ pfob->pend_queue_driving = 0; ++ be_drive_mcc_wrb_queue(pfob->mcc); ++ } ++ return status; ++} ++ ++/* ++ Deferences the given object. Once the object's reference count drops to ++ zero, the object is destroyed and all resources that are held by this ++ object are released. The on-chip context is also destroyed along with ++ the queue ID, and any mappings made into the UT. ++ ++ eq_object - EQ handle returned from eq_object_create. ++ ++ Returns BE_SUCCESS if successfull, otherwise a useful error code ++ is returned. ++ ++ IRQL: IRQL < DISPATCH_LEVEL ++*/ ++int be_eq_destroy(struct be_eq_object *eq_object) ++{ ++ int status = 0; ++ ++ ASSERT(atomic_read(&eq_object->ref_count) == 0); ++ /* no CQs should reference this EQ now */ ++ ASSERT(list_empty(&eq_object->cq_list_head)); ++ ++ /* Send fwcmd to destroy the EQ. */ ++ status = be_function_ring_destroy(eq_object->parent_function, ++ eq_object->eq_id, FWCMD_RING_TYPE_EQ, ++ NULL, NULL, NULL, NULL); ++ ASSERT(status == 0); ++ ++ return BE_SUCCESS; ++} ++/* ++ *--------------------------------------------------------------------------- ++ * Function: be_eq_modify_delay ++ * Changes the EQ delay for a group of EQs. ++ * num_eq - The number of EQs in the eq_array to adjust. ++ * This also is the number of delay values in ++ * the eq_delay_array. ++ * eq_array - Array of struct be_eq_object pointers to adjust. ++ * eq_delay_array - Array of "num_eq" timer delays in units ++ * of microseconds. The be_eq_query_delay_range ++ * fwcmd returns the resolution and range of ++ * legal EQ delays. ++ * cb - ++ * cb_context - ++ * q_ctxt - Optional. Pointer to a previously allocated ++ * struct. If the MCC WRB ring is full, this ++ * structure is used to queue the operation. It ++ * will be posted to the MCC ring when space ++ * becomes available. All queued commands will ++ * be posted to the ring in the order they are ++ * received. It is always valid to pass a pointer to ++ * a generic be_generic_q_cntxt. However, ++ * the specific context structs ++ * are generally smaller than the generic struct. ++ * return pend_status - BE_SUCCESS (0) on success. ++ * BE_PENDING (postive value) if the FWCMD ++ * completion is pending. Negative error code on failure. ++ *------------------------------------------------------------------------- ++ */ ++int ++be_eq_modify_delay(struct be_function_object *pfob, ++ u32 num_eq, struct be_eq_object **eq_array, ++ u32 *eq_delay_array, mcc_wrb_cqe_callback cb, ++ void *cb_context, struct be_eq_modify_delay_q_ctxt *q_ctxt) ++{ ++ struct FWCMD_COMMON_MODIFY_EQ_DELAY *fwcmd = NULL; ++ struct MCC_WRB_AMAP *wrb = NULL; ++ int status = 0; ++ struct be_generic_q_ctxt *gen_ctxt = NULL; ++ u32 i; ++ unsigned long irql; ++ ++ spin_lock_irqsave(&pfob->post_lock, irql); ++ ++ wrb = be_function_peek_mcc_wrb(pfob); ++ if (!wrb) { ++ if (q_ctxt && cb) { ++ wrb = (struct MCC_WRB_AMAP *) &q_ctxt->wrb_header; ++ gen_ctxt = (struct be_generic_q_ctxt *) q_ctxt; ++ gen_ctxt->context.bytes = sizeof(*q_ctxt); ++ } else { ++ status = BE_STATUS_NO_MCC_WRB; ++ goto Error; ++ } ++ } ++ /* Prepares an embedded fwcmd, including request/response sizes. */ ++ fwcmd = BE_PREPARE_EMBEDDED_FWCMD(pfob, wrb, COMMON_MODIFY_EQ_DELAY); ++ ++ ASSERT(num_eq > 0); ++ ASSERT(num_eq <= ARRAY_SIZE(fwcmd->params.request.delay)); ++ fwcmd->params.request.num_eq = num_eq; ++ for (i = 0; i < num_eq; i++) { ++ fwcmd->params.request.delay[i].eq_id = eq_array[i]->eq_id; ++ fwcmd->params.request.delay[i].delay_in_microseconds = ++ eq_delay_array[i]; ++ } ++ ++ /* Post the f/w command */ ++ status = be_function_post_mcc_wrb(pfob, wrb, gen_ctxt, ++ cb, cb_context, NULL, NULL, fwcmd, NULL); ++ ++Error: ++ spin_unlock_irqrestore(&pfob->post_lock, irql); ++ ++ if (pfob->pend_queue_driving && pfob->mcc) { ++ pfob->pend_queue_driving = 0; ++ be_drive_mcc_wrb_queue(pfob->mcc); ++ } ++ return status; ++} ++ +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/drivers/staging/benet/eth.c linux-2.6.29-rc3.owrt/drivers/staging/benet/eth.c +--- linux-2.6.29.owrt/drivers/staging/benet/eth.c 1970-01-01 01:00:00.000000000 +0100 ++++ linux-2.6.29-rc3.owrt/drivers/staging/benet/eth.c 2009-05-10 23:48:29.000000000 +0200 +@@ -0,0 +1,1273 @@ ++/* ++ * Copyright (C) 2005 - 2008 ServerEngines ++ * All rights reserved. ++ * ++ * 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. The full GNU General ++ * Public License is included in this distribution in the file called COPYING. ++ * ++ * Contact Information: ++ * linux-drivers@serverengines.com ++ * ++ * ServerEngines ++ * 209 N. Fair Oaks Ave ++ * Sunnyvale, CA 94085 ++ */ ++#include <linux/if_ether.h> ++#include "hwlib.h" ++#include "bestatus.h" ++ ++/* ++ *--------------------------------------------------------- ++ * Function: be_eth_sq_create_ex ++ * Creates an ethernet send ring - extended version with ++ * additional parameters. ++ * pfob - ++ * rd - ring address ++ * length_in_bytes - ++ * type - The type of ring to create. ++ * ulp - The requested ULP number for the ring. ++ * This should be zero based, i.e. 0,1,2. This must ++ * be valid NIC ULP based on the firmware config. ++ * All doorbells for this ring must be sent to ++ * this ULP. The first network ring allocated for ++ * each ULP are higher performance than subsequent rings. ++ * cq_object - cq object for completions ++ * ex_parameters - Additional parameters (that may increase in ++ * future revisions). These parameters are only used ++ * for certain ring types -- see ++ * struct be_eth_sq_parameters for details. ++ * eth_sq - ++ * return status - BE_SUCCESS (0) on success. Negative error code on failure. ++ *--------------------------------------------------------- ++ */ ++int ++be_eth_sq_create_ex(struct be_function_object *pfob, struct ring_desc *rd, ++ u32 length, u32 type, u32 ulp, struct be_cq_object *cq_object, ++ struct be_eth_sq_parameters *ex_parameters, ++ struct be_ethsq_object *eth_sq) ++{ ++ struct FWCMD_COMMON_ETH_TX_CREATE *fwcmd = NULL; ++ struct MCC_WRB_AMAP *wrb = NULL; ++ int status = 0; ++ u32 n; ++ unsigned long irql; ++ ++ ASSERT(rd); ++ ASSERT(eth_sq); ++ ASSERT(ex_parameters); ++ ++ spin_lock_irqsave(&pfob->post_lock, irql); ++ ++ memset(eth_sq, 0, sizeof(*eth_sq)); ++ ++ eth_sq->parent_function = pfob; ++ eth_sq->bid = 0xFFFFFFFF; ++ eth_sq->cq_object = cq_object; ++ ++ /* Translate hwlib interface to arm interface. */ ++ switch (type) { ++ case BE_ETH_TX_RING_TYPE_FORWARDING: ++ type = ETH_TX_RING_TYPE_FORWARDING; ++ break; ++ case BE_ETH_TX_RING_TYPE_STANDARD: ++ type = ETH_TX_RING_TYPE_STANDARD; ++ break; ++ case BE_ETH_TX_RING_TYPE_BOUND: ++ ASSERT(ex_parameters->port < 2); ++ type = ETH_TX_RING_TYPE_BOUND; ++ break; ++ default: ++ TRACE(DL_ERR, "Invalid eth tx ring type:%d", type); ++ return BE_NOT_OK; ++ break; ++ } ++ ++ wrb = be_function_peek_mcc_wrb(pfob); ++ if (!wrb) { ++ ASSERT(wrb); ++ TRACE(DL_ERR, "No free MCC WRBs in create EQ."); ++ status = BE_STATUS_NO_MCC_WRB; ++ goto Error; ++ } ++ /* NIC must be supported by the current config. */ ++ ASSERT(pfob->fw_config.nic_ulp_mask); ++ ++ /* ++ * The ulp parameter must select a valid NIC ULP ++ * for the current config. ++ */ ++ ASSERT((1 << ulp) & pfob->fw_config.nic_ulp_mask); ++ ++ /* Prepares an embedded fwcmd, including request/response sizes. */ ++ fwcmd = BE_PREPARE_EMBEDDED_FWCMD(pfob, wrb, COMMON_ETH_TX_CREATE); ++ fwcmd->header.request.port_number = ex_parameters->port; ++ ++ AMAP_SET_BITS_PTR(ETX_CONTEXT, pd_id, ++ &fwcmd->params.request.context, 0); ++ ++ n = be_ring_length_to_encoding(length, sizeof(struct ETH_WRB_AMAP)); ++ AMAP_SET_BITS_PTR(ETX_CONTEXT, tx_ring_size, ++ &fwcmd->params.request.context, n); ++ ++ AMAP_SET_BITS_PTR(ETX_CONTEXT, cq_id_send, ++ &fwcmd->params.request.context, cq_object->cq_id); ++ ++ n = pfob->pci_function_number; ++ AMAP_SET_BITS_PTR(ETX_CONTEXT, func, &fwcmd->params.request.context, n); ++ ++ fwcmd->params.request.type = type; ++ fwcmd->params.request.ulp_num = (1 << ulp); ++ fwcmd->params.request.num_pages = DIV_ROUND_UP(length, PAGE_SIZE); ++ ASSERT(PAGES_SPANNED(rd->va, rd->length) >= ++ fwcmd->params.request.num_pages); ++ ++ /* Create a page list for the FWCMD. */ ++ be_rd_to_pa_list(rd, fwcmd->params.request.pages, ++ ARRAY_SIZE(fwcmd->params.request.pages)); ++ ++ status = be_function_post_mcc_wrb(pfob, wrb, NULL, NULL, NULL, ++ NULL, NULL, fwcmd, NULL); ++ if (status != BE_SUCCESS) { ++ TRACE(DL_ERR, "MCC to create etx queue failed."); ++ goto Error; ++ } ++ /* save the butler ID */ ++ eth_sq->bid = fwcmd->params.response.cid; ++ ++ /* add a reference to the corresponding CQ */ ++ atomic_inc(&cq_object->ref_count); ++ ++Error: ++ spin_unlock_irqrestore(&pfob->post_lock, irql); ++ ++ if (pfob->pend_queue_driving && pfob->mcc) { ++ pfob->pend_queue_driving = 0; ++ be_drive_mcc_wrb_queue(pfob->mcc); ++ } ++ return status; ++} ++ ++ ++/* ++ This routine destroys an ethernet send queue ++ ++ EthSq - EthSq Handle returned from EthSqCreate ++ ++ This function always return BE_SUCCESS. ++ ++ This function frees memory allocated by EthSqCreate for the EthSq Object. ++ ++*/ ++int be_eth_sq_destroy(struct be_ethsq_object *eth_sq) ++{ ++ int status = 0; ++ ++ /* Send fwcmd to destroy the queue. */ ++ status = be_function_ring_destroy(eth_sq->parent_function, eth_sq->bid, ++ FWCMD_RING_TYPE_ETH_TX, NULL, NULL, NULL, NULL); ++ ASSERT(status == 0); ++ ++ /* Derefence any associated CQs. */ ++ atomic_dec(ð_sq->cq_object->ref_count); ++ return status; ++} ++/* ++ This routine attempts to set the transmit flow control parameters. ++ ++ FunctionObject - Handle to a function object ++ ++ txfc_enable - transmit flow control enable - true for ++ enable, false for disable ++ ++ rxfc_enable - receive flow control enable - true for ++ enable, false for disable ++ ++ Returns BE_SUCCESS if successfull, otherwise a useful int error ++ code is returned. ++ ++ IRQL: < DISPATCH_LEVEL ++ ++ This function always fails in non-privileged machine context. ++*/ ++int ++be_eth_set_flow_control(struct be_function_object *pfob, ++ bool txfc_enable, bool rxfc_enable) ++{ ++ struct FWCMD_COMMON_SET_FLOW_CONTROL *fwcmd = NULL; ++ struct MCC_WRB_AMAP *wrb = NULL; ++ int status = 0; ++ unsigned long irql; ++ ++ spin_lock_irqsave(&pfob->post_lock, irql); ++ ++ wrb = be_function_peek_mcc_wrb(pfob); ++ if (!wrb) { ++ TRACE(DL_ERR, "MCC wrb peek failed."); ++ status = BE_STATUS_NO_MCC_WRB; ++ goto error; ++ } ++ /* Prepares an embedded fwcmd, including request/response sizes. */ ++ fwcmd = BE_PREPARE_EMBEDDED_FWCMD(pfob, wrb, COMMON_SET_FLOW_CONTROL); ++ ++ fwcmd->params.request.rx_flow_control = rxfc_enable; ++ fwcmd->params.request.tx_flow_control = txfc_enable; ++ ++ /* Post the f/w command */ ++ status = be_function_post_mcc_wrb(pfob, wrb, NULL, NULL, NULL, ++ NULL, NULL, fwcmd, NULL); ++ ++ if (status != 0) { ++ TRACE(DL_ERR, "set flow control fwcmd failed."); ++ goto error; ++ } ++ ++error: ++ spin_unlock_irqrestore(&pfob->post_lock, irql); ++ ++ if (pfob->pend_queue_driving && pfob->mcc) { ++ pfob->pend_queue_driving = 0; ++ be_drive_mcc_wrb_queue(pfob->mcc); ++ } ++ return status; ++} ++ ++/* ++ This routine attempts to get the transmit flow control parameters. ++ ++ pfob - Handle to a function object ++ ++ txfc_enable - transmit flow control enable - true for ++ enable, false for disable ++ ++ rxfc_enable - receive flow control enable - true for enable, ++ false for disable ++ ++ Returns BE_SUCCESS if successfull, otherwise a useful int error code ++ is returned. ++ ++ IRQL: < DISPATCH_LEVEL ++ ++ This function always fails in non-privileged machine context. ++*/ ++int ++be_eth_get_flow_control(struct be_function_object *pfob, ++ bool *txfc_enable, bool *rxfc_enable) ++{ ++ struct FWCMD_COMMON_GET_FLOW_CONTROL *fwcmd = NULL; ++ struct MCC_WRB_AMAP *wrb = NULL; ++ int status = 0; ++ unsigned long irql; ++ ++ spin_lock_irqsave(&pfob->post_lock, irql); ++ ++ wrb = be_function_peek_mcc_wrb(pfob); ++ if (!wrb) { ++ TRACE(DL_ERR, "MCC wrb peek failed."); ++ status = BE_STATUS_NO_MCC_WRB; ++ goto error; ++ } ++ /* Prepares an embedded fwcmd, including request/response sizes. */ ++ fwcmd = BE_PREPARE_EMBEDDED_FWCMD(pfob, wrb, COMMON_GET_FLOW_CONTROL); ++ ++ /* Post the f/w command */ ++ status = be_function_post_mcc_wrb(pfob, wrb, NULL, NULL, NULL, ++ NULL, NULL, fwcmd, NULL); ++ ++ if (status != 0) { ++ TRACE(DL_ERR, "get flow control fwcmd failed."); ++ goto error; ++ } ++ ++ *txfc_enable = fwcmd->params.response.tx_flow_control; ++ *rxfc_enable = fwcmd->params.response.rx_flow_control; ++ ++error: ++ spin_unlock_irqrestore(&pfob->post_lock, irql); ++ ++ if (pfob->pend_queue_driving && pfob->mcc) { ++ pfob->pend_queue_driving = 0; ++ be_drive_mcc_wrb_queue(pfob->mcc); ++ } ++ return status; ++} ++ ++/* ++ *--------------------------------------------------------- ++ * Function: be_eth_set_qos ++ * This function sets the ethernet transmit Quality of Service (QoS) ++ * characteristics of BladeEngine for the domain. All ethernet ++ * transmit rings of the domain will evenly share the bandwidth. ++ * The exeception to sharing is the host primary (super) ethernet ++ * transmit ring as well as the host ethernet forwarding ring ++ * for missed offload data. ++ * pfob - ++ * max_bps - the maximum bits per second in units of ++ * 10 Mbps (valid 0-100) ++ * max_pps - the maximum packets per second in units ++ * of 1 Kpps (0 indicates no limit) ++ * return status - BE_SUCCESS (0) on success. Negative error code on failure. ++ *--------------------------------------------------------- ++ */ ++int ++be_eth_set_qos(struct be_function_object *pfob, u32 max_bps, u32 max_pps) ++{ ++ struct FWCMD_COMMON_SET_QOS *fwcmd = NULL; ++ struct MCC_WRB_AMAP *wrb = NULL; ++ int status = 0; ++ unsigned long irql; ++ ++ spin_lock_irqsave(&pfob->post_lock, irql); ++ ++ wrb = be_function_peek_mcc_wrb(pfob); ++ if (!wrb) { ++ TRACE(DL_ERR, "MCC wrb peek failed."); ++ status = BE_STATUS_NO_MCC_WRB; ++ goto error; ++ } ++ /* Prepares an embedded fwcmd, including request/response sizes. */ ++ fwcmd = BE_PREPARE_EMBEDDED_FWCMD(pfob, wrb, COMMON_SET_QOS); ++ ++ /* Set fields in fwcmd */ ++ fwcmd->params.request.max_bits_per_second_NIC = max_bps; ++ fwcmd->params.request.max_packets_per_second_NIC = max_pps; ++ fwcmd->params.request.valid_flags = QOS_BITS_NIC | QOS_PKTS_NIC; ++ ++ /* Post the f/w command */ ++ status = be_function_post_mcc_wrb(pfob, wrb, NULL, NULL, NULL, ++ NULL, NULL, fwcmd, NULL); ++ ++ if (status != 0) ++ TRACE(DL_ERR, "network set qos fwcmd failed."); ++ ++error: ++ spin_unlock_irqrestore(&pfob->post_lock, irql); ++ if (pfob->pend_queue_driving && pfob->mcc) { ++ pfob->pend_queue_driving = 0; ++ be_drive_mcc_wrb_queue(pfob->mcc); ++ } ++ return status; ++} ++ ++/* ++ *--------------------------------------------------------- ++ * Function: be_eth_get_qos ++ * This function retrieves the ethernet transmit Quality of Service (QoS) ++ * characteristics for the domain. ++ * max_bps - the maximum bits per second in units of ++ * 10 Mbps (valid 0-100) ++ * max_pps - the maximum packets per second in units of ++ * 1 Kpps (0 indicates no limit) ++ * return status - BE_SUCCESS (0) on success. Negative error code on failure. ++ *--------------------------------------------------------- ++ */ ++int ++be_eth_get_qos(struct be_function_object *pfob, u32 *max_bps, u32 *max_pps) ++{ ++ struct FWCMD_COMMON_GET_QOS *fwcmd = NULL; ++ struct MCC_WRB_AMAP *wrb = NULL; ++ int status = 0; ++ unsigned long irql; ++ ++ spin_lock_irqsave(&pfob->post_lock, irql); ++ ++ wrb = be_function_peek_mcc_wrb(pfob); ++ if (!wrb) { ++ TRACE(DL_ERR, "MCC wrb peek failed."); ++ status = BE_STATUS_NO_MCC_WRB; ++ goto error; ++ } ++ /* Prepares an embedded fwcmd, including request/response sizes. */ ++ fwcmd = BE_PREPARE_EMBEDDED_FWCMD(pfob, wrb, COMMON_GET_QOS); ++ ++ /* Post the f/w command */ ++ status = be_function_post_mcc_wrb(pfob, wrb, NULL, NULL, NULL, ++ NULL, NULL, fwcmd, NULL); ++ ++ if (status != 0) { ++ TRACE(DL_ERR, "network get qos fwcmd failed."); ++ goto error; ++ } ++ ++ *max_bps = fwcmd->params.response.max_bits_per_second_NIC; ++ *max_pps = fwcmd->params.response.max_packets_per_second_NIC; ++ ++error: ++ spin_unlock_irqrestore(&pfob->post_lock, irql); ++ if (pfob->pend_queue_driving && pfob->mcc) { ++ pfob->pend_queue_driving = 0; ++ be_drive_mcc_wrb_queue(pfob->mcc); ++ } ++ return status; ++} ++ ++/* ++ *--------------------------------------------------------- ++ * Function: be_eth_set_frame_size ++ * This function sets the ethernet maximum frame size. The previous ++ * values are returned. ++ * pfob - ++ * tx_frame_size - maximum transmit frame size in bytes ++ * rx_frame_size - maximum receive frame size in bytes ++ * return status - BE_SUCCESS (0) on success. Negative error code on failure. ++ *--------------------------------------------------------- ++ */ ++int ++be_eth_set_frame_size(struct be_function_object *pfob, ++ u32 *tx_frame_size, u32 *rx_frame_size) ++{ ++ struct FWCMD_COMMON_SET_FRAME_SIZE *fwcmd = NULL; ++ struct MCC_WRB_AMAP *wrb = NULL; ++ int status = 0; ++ unsigned long irql; ++ ++ spin_lock_irqsave(&pfob->post_lock, irql); ++ ++ wrb = be_function_peek_mcc_wrb(pfob); ++ if (!wrb) { ++ TRACE(DL_ERR, "MCC wrb peek failed."); ++ status = BE_STATUS_NO_MCC_WRB; ++ goto error; ++ } ++ /* Prepares an embedded fwcmd, including request/response sizes. */ ++ fwcmd = BE_PREPARE_EMBEDDED_FWCMD(pfob, wrb, COMMON_SET_FRAME_SIZE); ++ fwcmd->params.request.max_tx_frame_size = *tx_frame_size; ++ fwcmd->params.request.max_rx_frame_size = *rx_frame_size; ++ ++ /* Post the f/w command */ ++ status = be_function_post_mcc_wrb(pfob, wrb, NULL, NULL, NULL, ++ NULL, NULL, fwcmd, NULL); ++ ++ if (status != 0) { ++ TRACE(DL_ERR, "network set frame size fwcmd failed."); ++ goto error; ++ } ++ ++ *tx_frame_size = fwcmd->params.response.chip_max_tx_frame_size; ++ *rx_frame_size = fwcmd->params.response.chip_max_rx_frame_size; ++ ++error: ++ spin_unlock_irqrestore(&pfob->post_lock, irql); ++ if (pfob->pend_queue_driving && pfob->mcc) { ++ pfob->pend_queue_driving = 0; ++ be_drive_mcc_wrb_queue(pfob->mcc); ++ } ++ return status; ++} ++ ++ ++/* ++ This routine creates a Ethernet receive ring. ++ ++ pfob - handle to a function object ++ rq_base_va - base VA for the default receive ring. this must be ++ exactly 8K in length and continguous physical memory. ++ cq_object - handle to a previously created CQ to be associated ++ with the RQ. ++ pp_eth_rq - pointer to an opqaue handle where an eth ++ receive object is returned. ++ Returns BE_SUCCESS if successfull, , otherwise a useful ++ int error code is returned. ++ ++ IRQL: < DISPATCH_LEVEL ++ this function allocates a struct be_ethrq_object *object. ++ there must be no more than 1 of these per function object, unless the ++ function object supports RSS (is networking and on the host). ++ the rq_base_va must point to a buffer of exactly 8K. ++ the erx::host_cqid (or host_stor_cqid) register and erx::ring_page registers ++ will be updated as appropriate on return ++*/ ++int ++be_eth_rq_create(struct be_function_object *pfob, ++ struct ring_desc *rd, struct be_cq_object *cq_object, ++ struct be_cq_object *bcmc_cq_object, ++ struct be_ethrq_object *eth_rq) ++{ ++ int status = 0; ++ struct MCC_WRB_AMAP *wrb = NULL; ++ struct FWCMD_COMMON_ETH_RX_CREATE *fwcmd = NULL; ++ unsigned long irql; ++ ++ /* MPU will set the */ ++ ASSERT(rd); ++ ASSERT(eth_rq); ++ ++ spin_lock_irqsave(&pfob->post_lock, irql); ++ ++ eth_rq->parent_function = pfob; ++ eth_rq->cq_object = cq_object; ++ ++ wrb = be_function_peek_mcc_wrb(pfob); ++ if (!wrb) { ++ TRACE(DL_ERR, "MCC wrb peek failed."); ++ status = BE_STATUS_NO_MCC_WRB; ++ goto Error; ++ } ++ /* Prepares an embedded fwcmd, including request/response sizes. */ ++ fwcmd = BE_PREPARE_EMBEDDED_FWCMD(pfob, wrb, COMMON_ETH_RX_CREATE); ++ ++ fwcmd->params.request.num_pages = 2; /* required length */ ++ fwcmd->params.request.cq_id = cq_object->cq_id; ++ ++ if (bcmc_cq_object) ++ fwcmd->params.request.bcmc_cq_id = bcmc_cq_object->cq_id; ++ else ++ fwcmd->params.request.bcmc_cq_id = 0xFFFF; ++ ++ /* Create a page list for the FWCMD. */ ++ be_rd_to_pa_list(rd, fwcmd->params.request.pages, ++ ARRAY_SIZE(fwcmd->params.request.pages)); ++ ++ /* Post the f/w command */ ++ status = be_function_post_mcc_wrb(pfob, wrb, NULL, NULL, NULL, ++ NULL, NULL, fwcmd, NULL); ++ if (status != BE_SUCCESS) { ++ TRACE(DL_ERR, "fwcmd to map eth rxq frags failed."); ++ goto Error; ++ } ++ /* Save the ring ID for cleanup. */ ++ eth_rq->rid = fwcmd->params.response.id; ++ ++ atomic_inc(&cq_object->ref_count); ++ ++Error: ++ spin_unlock_irqrestore(&pfob->post_lock, irql); ++ ++ if (pfob->pend_queue_driving && pfob->mcc) { ++ pfob->pend_queue_driving = 0; ++ be_drive_mcc_wrb_queue(pfob->mcc); ++ } ++ return status; ++} ++ ++/* ++ This routine destroys an Ethernet receive queue ++ ++ eth_rq - ethernet receive queue handle returned from eth_rq_create ++ ++ Returns BE_SUCCESS on success and an appropriate int on failure. ++ ++ This function frees resourcs allocated by EthRqCreate. ++ The erx::host_cqid (or host_stor_cqid) register and erx::ring_page ++ registers will be updated as appropriate on return ++ IRQL: < DISPATCH_LEVEL ++*/ ++ ++static void be_eth_rq_destroy_internal_cb(void *context, int status, ++ struct MCC_WRB_AMAP *wrb) ++{ ++ struct be_ethrq_object *eth_rq = (struct be_ethrq_object *) context; ++ ++ if (status != BE_SUCCESS) { ++ TRACE(DL_ERR, "Destroy eth rq failed in internal callback.\n"); ++ } else { ++ /* Dereference any CQs associated with this queue. */ ++ atomic_dec(ð_rq->cq_object->ref_count); ++ } ++ ++ return; ++} ++ ++int be_eth_rq_destroy(struct be_ethrq_object *eth_rq) ++{ ++ int status = BE_SUCCESS; ++ ++ /* Send fwcmd to destroy the RQ. */ ++ status = be_function_ring_destroy(eth_rq->parent_function, ++ eth_rq->rid, FWCMD_RING_TYPE_ETH_RX, NULL, NULL, ++ be_eth_rq_destroy_internal_cb, eth_rq); ++ ++ return status; ++} ++ ++/* ++ *--------------------------------------------------------------------------- ++ * Function: be_eth_rq_destroy_options ++ * Destroys an ethernet receive ring with finer granularity options ++ * than the standard be_eth_rq_destroy() API function. ++ * eth_rq - ++ * flush - Set to 1 to flush the ring, set to 0 to bypass the flush ++ * cb - Callback function on completion ++ * cb_context - Callback context ++ * return status - BE_SUCCESS (0) on success. Negative error code on failure. ++ *---------------------------------------------------------------------------- ++ */ ++int ++be_eth_rq_destroy_options(struct be_ethrq_object *eth_rq, bool flush, ++ mcc_wrb_cqe_callback cb, void *cb_context) ++{ ++ struct FWCMD_COMMON_RING_DESTROY *fwcmd = NULL; ++ struct MCC_WRB_AMAP *wrb = NULL; ++ int status = BE_SUCCESS; ++ struct be_function_object *pfob = NULL; ++ unsigned long irql; ++ ++ pfob = eth_rq->parent_function; ++ ++ spin_lock_irqsave(&pfob->post_lock, irql); ++ ++ TRACE(DL_INFO, "Destroy eth_rq ring id:%d, flush:%d", eth_rq->rid, ++ flush); ++ ++ wrb = be_function_peek_mcc_wrb(pfob); ++ if (!wrb) { ++ ASSERT(wrb); ++ TRACE(DL_ERR, "No free MCC WRBs in destroy eth_rq ring."); ++ status = BE_STATUS_NO_MCC_WRB; ++ goto Error; ++ } ++ /* Prepares an embedded fwcmd, including request/response sizes. */ ++ fwcmd = BE_PREPARE_EMBEDDED_FWCMD(pfob, wrb, COMMON_RING_DESTROY); ++ ++ fwcmd->params.request.id = eth_rq->rid; ++ fwcmd->params.request.ring_type = FWCMD_RING_TYPE_ETH_RX; ++ fwcmd->params.request.bypass_flush = ((0 == flush) ? 1 : 0); ++ ++ /* Post the f/w command */ ++ status = be_function_post_mcc_wrb(pfob, wrb, NULL, cb, cb_context, ++ be_eth_rq_destroy_internal_cb, eth_rq, fwcmd, NULL); ++ ++ if (status != BE_SUCCESS && status != BE_PENDING) { ++ TRACE(DL_ERR, "eth_rq ring destroy failed. id:%d, flush:%d", ++ eth_rq->rid, flush); ++ goto Error; ++ } ++ ++Error: ++ spin_unlock_irqrestore(&pfob->post_lock, irql); ++ ++ if (pfob->pend_queue_driving && pfob->mcc) { ++ pfob->pend_queue_driving = 0; ++ be_drive_mcc_wrb_queue(pfob->mcc); ++ } ++ return status; ++} ++ ++/* ++ This routine queries the frag size for erx. ++ ++ pfob - handle to a function object ++ ++ frag_size_bytes - erx frag size in bytes that is/was set. ++ ++ Returns BE_SUCCESS if successfull, otherwise a useful int error ++ code is returned. ++ ++ IRQL: < DISPATCH_LEVEL ++ ++*/ ++int ++be_eth_rq_get_frag_size(struct be_function_object *pfob, u32 *frag_size_bytes) ++{ ++ struct FWCMD_ETH_GET_RX_FRAG_SIZE *fwcmd = NULL; ++ struct MCC_WRB_AMAP *wrb = NULL; ++ int status = 0; ++ unsigned long irql; ++ ++ ASSERT(frag_size_bytes); ++ ++ spin_lock_irqsave(&pfob->post_lock, irql); ++ ++ wrb = be_function_peek_mcc_wrb(pfob); ++ if (!wrb) { ++ TRACE(DL_ERR, "MCC wrb peek failed."); ++ return BE_STATUS_NO_MCC_WRB; ++ } ++ /* Prepares an embedded fwcmd, including request/response sizes. */ ++ fwcmd = BE_PREPARE_EMBEDDED_FWCMD(pfob, wrb, ETH_GET_RX_FRAG_SIZE); ++ ++ /* Post the f/w command */ ++ status = be_function_post_mcc_wrb(pfob, wrb, NULL, NULL, NULL, ++ NULL, NULL, fwcmd, NULL); ++ ++ if (status != 0) { ++ TRACE(DL_ERR, "get frag size fwcmd failed."); ++ goto error; ++ } ++ ++ *frag_size_bytes = 1 << fwcmd->params.response.actual_fragsize_log2; ++ ++error: ++ spin_unlock_irqrestore(&pfob->post_lock, irql); ++ ++ if (pfob->pend_queue_driving && pfob->mcc) { ++ pfob->pend_queue_driving = 0; ++ be_drive_mcc_wrb_queue(pfob->mcc); ++ } ++ return status; ++} ++ ++/* ++ This routine attempts to set the frag size for erx. If the frag size is ++ already set, the attempt fails and the current frag size is returned. ++ ++ pfob - Handle to a function object ++ ++ frag_size - Erx frag size in bytes that is/was set. ++ ++ current_frag_size_bytes - Pointer to location where currrent frag ++ is to be rturned ++ ++ Returns BE_SUCCESS if successfull, otherwise a useful int error ++ code is returned. ++ ++ IRQL: < DISPATCH_LEVEL ++ ++ This function always fails in non-privileged machine context. ++*/ ++int ++be_eth_rq_set_frag_size(struct be_function_object *pfob, ++ u32 frag_size, u32 *frag_size_bytes) ++{ ++ struct FWCMD_ETH_SET_RX_FRAG_SIZE *fwcmd = NULL; ++ struct MCC_WRB_AMAP *wrb = NULL; ++ int status = 0; ++ unsigned long irql; ++ ++ ASSERT(frag_size_bytes); ++ ++ spin_lock_irqsave(&pfob->post_lock, irql); ++ ++ wrb = be_function_peek_mcc_wrb(pfob); ++ if (!wrb) { ++ TRACE(DL_ERR, "MCC wrb peek failed."); ++ status = BE_STATUS_NO_MCC_WRB; ++ goto error; ++ } ++ /* Prepares an embedded fwcmd, including request/response sizes. */ ++ fwcmd = BE_PREPARE_EMBEDDED_FWCMD(pfob, wrb, ETH_SET_RX_FRAG_SIZE); ++ ++ ASSERT(frag_size >= 128 && frag_size <= 16 * 1024); ++ ++ /* This is the log2 of the fragsize. This is not the exact ++ * ERX encoding. */ ++ fwcmd->params.request.new_fragsize_log2 = __ilog2_u32(frag_size); ++ ++ /* Post the f/w command */ ++ status = be_function_post_mcc_wrb(pfob, wrb, NULL, NULL, NULL, ++ NULL, NULL, fwcmd, NULL); ++ ++ if (status != 0) { ++ TRACE(DL_ERR, "set frag size fwcmd failed."); ++ goto error; ++ } ++ ++ *frag_size_bytes = 1 << fwcmd->params.response.actual_fragsize_log2; ++error: ++ spin_unlock_irqrestore(&pfob->post_lock, irql); ++ ++ if (pfob->pend_queue_driving && pfob->mcc) { ++ pfob->pend_queue_driving = 0; ++ be_drive_mcc_wrb_queue(pfob->mcc); ++ } ++ return status; ++} ++ ++ ++/* ++ This routine gets or sets a mac address for a domain ++ given the port and mac. ++ ++ FunctionObject - Function object handle. ++ port1 - Set to TRUE if this function will set/get the Port 1 ++ address. Only the host may set this to TRUE. ++ mac1 - Set to TRUE if this function will set/get the ++ MAC 1 address. Only the host may set this to TRUE. ++ write - Set to TRUE if this function should write the mac address. ++ mac_address - Buffer of the mac address to read or write. ++ ++ Returns BE_SUCCESS if successfull, otherwise a useful int is returned. ++ ++ IRQL: < DISPATCH_LEVEL ++*/ ++int be_rxf_mac_address_read_write(struct be_function_object *pfob, ++ bool port1, /* VM must always set to false */ ++ bool mac1, /* VM must always set to false */ ++ bool mgmt, bool write, ++ bool permanent, u8 *mac_address, ++ mcc_wrb_cqe_callback cb, /* optional */ ++ void *cb_context) /* optional */ ++{ ++ int status = BE_SUCCESS; ++ union { ++ struct FWCMD_COMMON_NTWK_MAC_QUERY *query; ++ struct FWCMD_COMMON_NTWK_MAC_SET *set; ++ } fwcmd = {NULL}; ++ struct MCC_WRB_AMAP *wrb = NULL; ++ u32 type = 0; ++ unsigned long irql; ++ struct be_mcc_wrb_response_copy rc; ++ ++ spin_lock_irqsave(&pfob->post_lock, irql); ++ ++ ASSERT(mac_address); ++ ++ ASSERT(port1 == false); ++ ASSERT(mac1 == false); ++ ++ wrb = be_function_peek_mcc_wrb(pfob); ++ if (!wrb) { ++ TRACE(DL_ERR, "MCC wrb peek failed."); ++ status = BE_STATUS_NO_MCC_WRB; ++ goto Error; ++ } ++ ++ if (mgmt) { ++ type = MAC_ADDRESS_TYPE_MANAGEMENT; ++ } else { ++ if (pfob->type == BE_FUNCTION_TYPE_NETWORK) ++ type = MAC_ADDRESS_TYPE_NETWORK; ++ else ++ type = MAC_ADDRESS_TYPE_STORAGE; ++ } ++ ++ if (write) { ++ /* Prepares an embedded fwcmd, including ++ * request/response sizes. ++ */ ++ fwcmd.set = BE_PREPARE_EMBEDDED_FWCMD(pfob, ++ wrb, COMMON_NTWK_MAC_SET); ++ ++ fwcmd.set->params.request.invalidate = 0; ++ fwcmd.set->params.request.mac1 = (mac1 ? 1 : 0); ++ fwcmd.set->params.request.port = (port1 ? 1 : 0); ++ fwcmd.set->params.request.type = type; ++ ++ /* Copy the mac address to set. */ ++ fwcmd.set->params.request.mac.SizeOfStructure = ++ sizeof(fwcmd.set->params.request.mac); ++ memcpy(fwcmd.set->params.request.mac.MACAddress, ++ mac_address, ETH_ALEN); ++ ++ /* Post the f/w command */ ++ status = be_function_post_mcc_wrb(pfob, wrb, NULL, ++ cb, cb_context, NULL, NULL, fwcmd.set, NULL); ++ ++ } else { ++ ++ /* ++ * Prepares an embedded fwcmd, including ++ * request/response sizes. ++ */ ++ fwcmd.query = BE_PREPARE_EMBEDDED_FWCMD(pfob, ++ wrb, COMMON_NTWK_MAC_QUERY); ++ ++ fwcmd.query->params.request.mac1 = (mac1 ? 1 : 0); ++ fwcmd.query->params.request.port = (port1 ? 1 : 0); ++ fwcmd.query->params.request.type = type; ++ fwcmd.query->params.request.permanent = permanent; ++ ++ rc.length = FIELD_SIZEOF(struct FWCMD_COMMON_NTWK_MAC_QUERY, ++ params.response.mac.MACAddress); ++ rc.fwcmd_offset = offsetof(struct FWCMD_COMMON_NTWK_MAC_QUERY, ++ params.response.mac.MACAddress); ++ rc.va = mac_address; ++ /* Post the f/w command (with a copy for the response) */ ++ status = be_function_post_mcc_wrb(pfob, wrb, NULL, cb, ++ cb_context, NULL, NULL, fwcmd.query, &rc); ++ } ++ ++ if (status < 0) { ++ TRACE(DL_ERR, "mac set/query failed."); ++ goto Error; ++ } ++ ++Error: ++ spin_unlock_irqrestore(&pfob->post_lock, irql); ++ if (pfob->pend_queue_driving && pfob->mcc) { ++ pfob->pend_queue_driving = 0; ++ be_drive_mcc_wrb_queue(pfob->mcc); ++ } ++ return status; ++} ++ ++/* ++ This routine writes data to context memory. ++ ++ pfob - Function object handle. ++ mac_table - Set to the 128-bit multicast address hash table. ++ ++ Returns BE_SUCCESS if successfull, otherwise a useful int is returned. ++ ++ IRQL: < DISPATCH_LEVEL ++*/ ++ ++int be_rxf_multicast_config(struct be_function_object *pfob, ++ bool promiscuous, u32 num, u8 *mac_table, ++ mcc_wrb_cqe_callback cb, /* optional */ ++ void *cb_context, ++ struct be_multicast_q_ctxt *q_ctxt) ++{ ++ int status = BE_SUCCESS; ++ struct FWCMD_COMMON_NTWK_MULTICAST_SET *fwcmd = NULL; ++ struct MCC_WRB_AMAP *wrb = NULL; ++ struct be_generic_q_ctxt *generic_ctxt = NULL; ++ unsigned long irql; ++ ++ ASSERT(num <= ARRAY_SIZE(fwcmd->params.request.mac)); ++ ++ if (num > ARRAY_SIZE(fwcmd->params.request.mac)) { ++ TRACE(DL_ERR, "Too many multicast addresses. BE supports %d.", ++ (int) ARRAY_SIZE(fwcmd->params.request.mac)); ++ return BE_NOT_OK; ++ } ++ ++ spin_lock_irqsave(&pfob->post_lock, irql); ++ ++ wrb = be_function_peek_mcc_wrb(pfob); ++ if (!wrb) { ++ if (q_ctxt && cb) { ++ wrb = (struct MCC_WRB_AMAP *) &q_ctxt->wrb_header; ++ generic_ctxt = (struct be_generic_q_ctxt *) q_ctxt; ++ generic_ctxt->context.bytes = sizeof(*q_ctxt); ++ } else { ++ status = BE_STATUS_NO_MCC_WRB; ++ goto Error; ++ } ++ } ++ /* Prepares an embedded fwcmd, including request/response sizes. */ ++ fwcmd = BE_PREPARE_EMBEDDED_FWCMD(pfob, wrb, COMMON_NTWK_MULTICAST_SET); ++ ++ fwcmd->params.request.promiscuous = promiscuous; ++ if (!promiscuous) { ++ fwcmd->params.request.num_mac = num; ++ if (num > 0) { ++ ASSERT(mac_table); ++ memcpy(fwcmd->params.request.mac, ++ mac_table, ETH_ALEN * num); ++ } ++ } ++ ++ /* Post the f/w command */ ++ status = be_function_post_mcc_wrb(pfob, wrb, generic_ctxt, ++ cb, cb_context, NULL, NULL, fwcmd, NULL); ++ if (status < 0) { ++ TRACE(DL_ERR, "multicast fwcmd failed."); ++ goto Error; ++ } ++ ++Error: ++ spin_unlock_irqrestore(&pfob->post_lock, irql); ++ if (pfob->pend_queue_driving && pfob->mcc) { ++ pfob->pend_queue_driving = 0; ++ be_drive_mcc_wrb_queue(pfob->mcc); ++ } ++ return status; ++} ++ ++/* ++ This routine adds or removes a vlan tag from the rxf table. ++ ++ FunctionObject - Function object handle. ++ VLanTag - VLan tag to add or remove. ++ Add - Set to TRUE if this will add a vlan tag ++ ++ Returns BE_SUCCESS if successfull, otherwise a useful int is returned. ++ ++ IRQL: < DISPATCH_LEVEL ++*/ ++int be_rxf_vlan_config(struct be_function_object *pfob, ++ bool promiscuous, u32 num, u16 *vlan_tag_array, ++ mcc_wrb_cqe_callback cb, /* optional */ ++ void *cb_context, ++ struct be_vlan_q_ctxt *q_ctxt) /* optional */ ++{ ++ int status = BE_SUCCESS; ++ struct FWCMD_COMMON_NTWK_VLAN_CONFIG *fwcmd = NULL; ++ struct MCC_WRB_AMAP *wrb = NULL; ++ struct be_generic_q_ctxt *generic_ctxt = NULL; ++ unsigned long irql; ++ ++ if (num > ARRAY_SIZE(fwcmd->params.request.vlan_tag)) { ++ TRACE(DL_ERR, "Too many VLAN tags."); ++ return BE_NOT_OK; ++ } ++ ++ spin_lock_irqsave(&pfob->post_lock, irql); ++ ++ wrb = be_function_peek_mcc_wrb(pfob); ++ if (!wrb) { ++ if (q_ctxt && cb) { ++ wrb = (struct MCC_WRB_AMAP *) &q_ctxt->wrb_header; ++ generic_ctxt = (struct be_generic_q_ctxt *) q_ctxt; ++ generic_ctxt->context.bytes = sizeof(*q_ctxt); ++ } else { ++ status = BE_STATUS_NO_MCC_WRB; ++ goto Error; ++ } ++ } ++ /* Prepares an embedded fwcmd, including request/response sizes. */ ++ fwcmd = BE_PREPARE_EMBEDDED_FWCMD(pfob, wrb, COMMON_NTWK_VLAN_CONFIG); ++ ++ fwcmd->params.request.promiscuous = promiscuous; ++ if (!promiscuous) { ++ fwcmd->params.request.num_vlan = num; ++ ++ if (num > 0) { ++ ASSERT(vlan_tag_array); ++ memcpy(fwcmd->params.request.vlan_tag, vlan_tag_array, ++ num * sizeof(vlan_tag_array[0])); ++ } ++ } ++ ++ /* Post the commadn */ ++ status = be_function_post_mcc_wrb(pfob, wrb, generic_ctxt, ++ cb, cb_context, NULL, NULL, fwcmd, NULL); ++ if (status < 0) { ++ TRACE(DL_ERR, "vlan fwcmd failed."); ++ goto Error; ++ } ++ ++Error: ++ spin_unlock_irqrestore(&pfob->post_lock, irql); ++ if (pfob->pend_queue_driving && pfob->mcc) { ++ pfob->pend_queue_driving = 0; ++ be_drive_mcc_wrb_queue(pfob->mcc); ++ } ++ return status; ++} ++ ++ ++int be_rxf_link_status(struct be_function_object *pfob, ++ struct BE_LINK_STATUS *link_status, ++ mcc_wrb_cqe_callback cb, ++ void *cb_context, ++ struct be_link_status_q_ctxt *q_ctxt) ++{ ++ struct FWCMD_COMMON_NTWK_LINK_STATUS_QUERY *fwcmd = NULL; ++ struct MCC_WRB_AMAP *wrb = NULL; ++ int status = 0; ++ struct be_generic_q_ctxt *generic_ctxt = NULL; ++ unsigned long irql; ++ struct be_mcc_wrb_response_copy rc; ++ ++ ASSERT(link_status); ++ ++ spin_lock_irqsave(&pfob->post_lock, irql); ++ ++ wrb = be_function_peek_mcc_wrb(pfob); ++ ++ if (!wrb) { ++ if (q_ctxt && cb) { ++ wrb = (struct MCC_WRB_AMAP *) &q_ctxt->wrb_header; ++ generic_ctxt = (struct be_generic_q_ctxt *) q_ctxt; ++ generic_ctxt->context.bytes = sizeof(*q_ctxt); ++ } else { ++ status = BE_STATUS_NO_MCC_WRB; ++ goto Error; ++ } ++ } ++ /* Prepares an embedded fwcmd, including request/response sizes. */ ++ fwcmd = BE_PREPARE_EMBEDDED_FWCMD(pfob, wrb, ++ COMMON_NTWK_LINK_STATUS_QUERY); ++ ++ rc.length = FIELD_SIZEOF(struct FWCMD_COMMON_NTWK_LINK_STATUS_QUERY, ++ params.response); ++ rc.fwcmd_offset = offsetof(struct FWCMD_COMMON_NTWK_LINK_STATUS_QUERY, ++ params.response); ++ rc.va = link_status; ++ /* Post or queue the f/w command */ ++ status = be_function_post_mcc_wrb(pfob, wrb, generic_ctxt, ++ cb, cb_context, NULL, NULL, fwcmd, &rc); ++ ++ if (status < 0) { ++ TRACE(DL_ERR, "link status fwcmd failed."); ++ goto Error; ++ } ++ ++Error: ++ spin_unlock_irqrestore(&pfob->post_lock, irql); ++ if (pfob->pend_queue_driving && pfob->mcc) { ++ pfob->pend_queue_driving = 0; ++ be_drive_mcc_wrb_queue(pfob->mcc); ++ } ++ return status; ++} ++ ++int ++be_rxf_query_eth_statistics(struct be_function_object *pfob, ++ struct FWCMD_ETH_GET_STATISTICS *va_for_fwcmd, ++ u64 pa_for_fwcmd, mcc_wrb_cqe_callback cb, ++ void *cb_context, ++ struct be_nonembedded_q_ctxt *q_ctxt) ++{ ++ struct MCC_WRB_AMAP *wrb = NULL; ++ int status = 0; ++ struct be_generic_q_ctxt *generic_ctxt = NULL; ++ unsigned long irql; ++ ++ ASSERT(va_for_fwcmd); ++ ASSERT(pa_for_fwcmd); ++ ++ spin_lock_irqsave(&pfob->post_lock, irql); ++ ++ wrb = be_function_peek_mcc_wrb(pfob); ++ ++ if (!wrb) { ++ if (q_ctxt && cb) { ++ wrb = (struct MCC_WRB_AMAP *) &q_ctxt->wrb_header; ++ generic_ctxt = (struct be_generic_q_ctxt *) q_ctxt; ++ generic_ctxt->context.bytes = sizeof(*q_ctxt); ++ } else { ++ status = BE_STATUS_NO_MCC_WRB; ++ goto Error; ++ } ++ } ++ ++ TRACE(DL_INFO, "Query eth stats. fwcmd va:%p pa:0x%08x_%08x", ++ va_for_fwcmd, upper_32_bits(pa_for_fwcmd), (u32)pa_for_fwcmd); ++ ++ /* Prepares an embedded fwcmd, including request/response sizes. */ ++ va_for_fwcmd = BE_PREPARE_NONEMBEDDED_FWCMD(pfob, wrb, ++ va_for_fwcmd, pa_for_fwcmd, ETH_GET_STATISTICS); ++ ++ /* Post the f/w command */ ++ status = be_function_post_mcc_wrb(pfob, wrb, generic_ctxt, ++ cb, cb_context, NULL, NULL, va_for_fwcmd, NULL); ++ if (status < 0) { ++ TRACE(DL_ERR, "eth stats fwcmd failed."); ++ goto Error; ++ } ++ ++Error: ++ spin_unlock_irqrestore(&pfob->post_lock, irql); ++ if (pfob->pend_queue_driving && pfob->mcc) { ++ pfob->pend_queue_driving = 0; ++ be_drive_mcc_wrb_queue(pfob->mcc); ++ } ++ return status; ++} ++ ++int ++be_rxf_promiscuous(struct be_function_object *pfob, ++ bool enable_port0, bool enable_port1, ++ mcc_wrb_cqe_callback cb, void *cb_context, ++ struct be_promiscuous_q_ctxt *q_ctxt) ++{ ++ struct FWCMD_ETH_PROMISCUOUS *fwcmd = NULL; ++ struct MCC_WRB_AMAP *wrb = NULL; ++ int status = 0; ++ struct be_generic_q_ctxt *generic_ctxt = NULL; ++ unsigned long irql; ++ ++ ++ spin_lock_irqsave(&pfob->post_lock, irql); ++ ++ wrb = be_function_peek_mcc_wrb(pfob); ++ ++ if (!wrb) { ++ if (q_ctxt && cb) { ++ wrb = (struct MCC_WRB_AMAP *) &q_ctxt->wrb_header; ++ generic_ctxt = (struct be_generic_q_ctxt *) q_ctxt; ++ generic_ctxt->context.bytes = sizeof(*q_ctxt); ++ } else { ++ status = BE_STATUS_NO_MCC_WRB; ++ goto Error; ++ } ++ } ++ /* Prepares an embedded fwcmd, including request/response sizes. */ ++ fwcmd = BE_PREPARE_EMBEDDED_FWCMD(pfob, wrb, ETH_PROMISCUOUS); ++ ++ fwcmd->params.request.port0_promiscuous = enable_port0; ++ fwcmd->params.request.port1_promiscuous = enable_port1; ++ ++ /* Post the f/w command */ ++ status = be_function_post_mcc_wrb(pfob, wrb, generic_ctxt, ++ cb, cb_context, NULL, NULL, fwcmd, NULL); ++ ++ if (status < 0) { ++ TRACE(DL_ERR, "promiscuous fwcmd failed."); ++ goto Error; ++ } ++ ++Error: ++ spin_unlock_irqrestore(&pfob->post_lock, irql); ++ if (pfob->pend_queue_driving && pfob->mcc) { ++ pfob->pend_queue_driving = 0; ++ be_drive_mcc_wrb_queue(pfob->mcc); ++ } ++ return status; ++} ++ ++ ++/* ++ *------------------------------------------------------------------------- ++ * Function: be_rxf_filter_config ++ * Configures BladeEngine ethernet receive filter settings. ++ * pfob - ++ * settings - Pointer to the requested filter settings. ++ * The response from BladeEngine will be placed back ++ * in this structure. ++ * cb - optional ++ * cb_context - optional ++ * q_ctxt - Optional. Pointer to a previously allocated struct. ++ * If the MCC WRB ring is full, this structure is ++ * used to queue the operation. It will be posted ++ * to the MCC ring when space becomes available. All ++ * queued commands will be posted to the ring in ++ * the order they are received. It is always valid ++ * to pass a pointer to a generic ++ * be_generic_q_ctxt. However, the specific ++ * context structs are generally smaller than ++ * the generic struct. ++ * return pend_status - BE_SUCCESS (0) on success. ++ * BE_PENDING (postive value) if the FWCMD ++ * completion is pending. Negative error code on failure. ++ *--------------------------------------------------------------------------- ++ */ ++int ++be_rxf_filter_config(struct be_function_object *pfob, ++ struct NTWK_RX_FILTER_SETTINGS *settings, ++ mcc_wrb_cqe_callback cb, void *cb_context, ++ struct be_rxf_filter_q_ctxt *q_ctxt) ++{ ++ struct FWCMD_COMMON_NTWK_RX_FILTER *fwcmd = NULL; ++ struct MCC_WRB_AMAP *wrb = NULL; ++ int status = 0; ++ struct be_generic_q_ctxt *generic_ctxt = NULL; ++ unsigned long irql; ++ struct be_mcc_wrb_response_copy rc; ++ ++ ASSERT(settings); ++ ++ spin_lock_irqsave(&pfob->post_lock, irql); ++ ++ wrb = be_function_peek_mcc_wrb(pfob); ++ ++ if (!wrb) { ++ if (q_ctxt && cb) { ++ wrb = (struct MCC_WRB_AMAP *) &q_ctxt->wrb_header; ++ generic_ctxt = (struct be_generic_q_ctxt *) q_ctxt; ++ generic_ctxt->context.bytes = sizeof(*q_ctxt); ++ } else { ++ status = BE_STATUS_NO_MCC_WRB; ++ goto Error; ++ } ++ } ++ /* Prepares an embedded fwcmd, including request/response sizes. */ ++ fwcmd = BE_PREPARE_EMBEDDED_FWCMD(pfob, wrb, COMMON_NTWK_RX_FILTER); ++ memcpy(&fwcmd->params.request, settings, sizeof(*settings)); ++ ++ rc.length = FIELD_SIZEOF(struct FWCMD_COMMON_NTWK_RX_FILTER, ++ params.response); ++ rc.fwcmd_offset = offsetof(struct FWCMD_COMMON_NTWK_RX_FILTER, ++ params.response); ++ rc.va = settings; ++ /* Post or queue the f/w command */ ++ status = be_function_post_mcc_wrb(pfob, wrb, generic_ctxt, ++ cb, cb_context, NULL, NULL, fwcmd, &rc); ++ ++ if (status < 0) { ++ TRACE(DL_ERR, "RXF/ERX filter config fwcmd failed."); ++ goto Error; ++ } ++ ++Error: ++ spin_unlock_irqrestore(&pfob->post_lock, irql); ++ if (pfob->pend_queue_driving && pfob->mcc) { ++ pfob->pend_queue_driving = 0; ++ be_drive_mcc_wrb_queue(pfob->mcc); ++ } ++ return status; ++} +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/drivers/staging/benet/etx_context.h linux-2.6.29-rc3.owrt/drivers/staging/benet/etx_context.h +--- linux-2.6.29.owrt/drivers/staging/benet/etx_context.h 1970-01-01 01:00:00.000000000 +0100 ++++ linux-2.6.29-rc3.owrt/drivers/staging/benet/etx_context.h 2009-05-10 23:48:29.000000000 +0200 +@@ -0,0 +1,55 @@ ++/* ++ * Copyright (C) 2005 - 2008 ServerEngines ++ * All rights reserved. ++ * ++ * 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. The full GNU General ++ * Public License is included in this distribution in the file called COPYING. ++ * ++ * Contact Information: ++ * linux-drivers@serverengines.com ++ * ++ * ServerEngines ++ * 209 N. Fair Oaks Ave ++ * Sunnyvale, CA 94085 ++ */ ++/* ++ * Autogenerated by srcgen version: 0127 ++ */ ++#ifndef __etx_context_amap_h__ ++#define __etx_context_amap_h__ ++ ++/* ETX ring context structure. */ ++struct BE_ETX_CONTEXT_AMAP { ++ u8 tx_cidx[11]; /* DWORD 0 */ ++ u8 rsvd0[5]; /* DWORD 0 */ ++ u8 rsvd1[16]; /* DWORD 0 */ ++ u8 tx_pidx[11]; /* DWORD 1 */ ++ u8 rsvd2; /* DWORD 1 */ ++ u8 tx_ring_size[4]; /* DWORD 1 */ ++ u8 pd_id[5]; /* DWORD 1 */ ++ u8 pd_id_not_valid; /* DWORD 1 */ ++ u8 cq_id_send[10]; /* DWORD 1 */ ++ u8 rsvd3[32]; /* DWORD 2 */ ++ u8 rsvd4[32]; /* DWORD 3 */ ++ u8 cur_bytes[32]; /* DWORD 4 */ ++ u8 max_bytes[32]; /* DWORD 5 */ ++ u8 time_stamp[32]; /* DWORD 6 */ ++ u8 rsvd5[11]; /* DWORD 7 */ ++ u8 func; /* DWORD 7 */ ++ u8 rsvd6[20]; /* DWORD 7 */ ++ u8 cur_txd_count[32]; /* DWORD 8 */ ++ u8 max_txd_count[32]; /* DWORD 9 */ ++ u8 rsvd7[32]; /* DWORD 10 */ ++ u8 rsvd8[32]; /* DWORD 11 */ ++ u8 rsvd9[32]; /* DWORD 12 */ ++ u8 rsvd10[32]; /* DWORD 13 */ ++ u8 rsvd11[32]; /* DWORD 14 */ ++ u8 rsvd12[32]; /* DWORD 15 */ ++} __packed; ++struct ETX_CONTEXT_AMAP { ++ u32 dw[16]; ++}; ++ ++#endif /* __etx_context_amap_h__ */ +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/drivers/staging/benet/funcobj.c linux-2.6.29-rc3.owrt/drivers/staging/benet/funcobj.c +--- linux-2.6.29.owrt/drivers/staging/benet/funcobj.c 1970-01-01 01:00:00.000000000 +0100 ++++ linux-2.6.29-rc3.owrt/drivers/staging/benet/funcobj.c 2009-05-10 23:48:29.000000000 +0200 +@@ -0,0 +1,565 @@ ++/* ++ * Copyright (C) 2005 - 2008 ServerEngines ++ * All rights reserved. ++ * ++ * 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. The full GNU General ++ * Public License is included in this distribution in the file called COPYING. ++ * ++ * Contact Information: ++ * linux-drivers@serverengines.com ++ * ++ * ServerEngines ++ * 209 N. Fair Oaks Ave ++ * Sunnyvale, CA 94085 ++ */ ++#include "hwlib.h" ++#include "bestatus.h" ++ ++ ++int ++be_function_internal_query_firmware_config(struct be_function_object *pfob, ++ struct BE_FIRMWARE_CONFIG *config) ++{ ++ struct FWCMD_COMMON_FIRMWARE_CONFIG *fwcmd = NULL; ++ struct MCC_WRB_AMAP *wrb = NULL; ++ int status = 0; ++ unsigned long irql; ++ struct be_mcc_wrb_response_copy rc; ++ ++ spin_lock_irqsave(&pfob->post_lock, irql); ++ ++ wrb = be_function_peek_mcc_wrb(pfob); ++ if (!wrb) { ++ TRACE(DL_ERR, "MCC wrb peek failed."); ++ status = BE_STATUS_NO_MCC_WRB; ++ goto error; ++ } ++ /* Prepares an embedded fwcmd, including request/response sizes. */ ++ fwcmd = BE_PREPARE_EMBEDDED_FWCMD(pfob, wrb, COMMON_FIRMWARE_CONFIG); ++ ++ rc.length = FIELD_SIZEOF(struct FWCMD_COMMON_FIRMWARE_CONFIG, ++ params.response); ++ rc.fwcmd_offset = offsetof(struct FWCMD_COMMON_FIRMWARE_CONFIG, ++ params.response); ++ rc.va = config; ++ ++ /* Post the f/w command */ ++ status = be_function_post_mcc_wrb(pfob, wrb, NULL, NULL, ++ NULL, NULL, NULL, fwcmd, &rc); ++error: ++ spin_unlock_irqrestore(&pfob->post_lock, irql); ++ if (pfob->pend_queue_driving && pfob->mcc) { ++ pfob->pend_queue_driving = 0; ++ be_drive_mcc_wrb_queue(pfob->mcc); ++ } ++ return status; ++} ++ ++/* ++ This allocates and initializes a function object based on the information ++ provided by upper layer drivers. ++ ++ Returns BE_SUCCESS on success and an appropriate int on failure. ++ ++ A function object represents a single BladeEngine (logical) PCI function. ++ That is a function object either represents ++ the networking side of BladeEngine or the iSCSI side of BladeEngine. ++ ++ This routine will also detect and create an appropriate PD object for the ++ PCI function as needed. ++*/ ++int ++be_function_object_create(u8 __iomem *csr_va, u8 __iomem *db_va, ++ u8 __iomem *pci_va, u32 function_type, ++ struct ring_desc *mailbox, struct be_function_object *pfob) ++{ ++ int status; ++ ++ ASSERT(pfob); /* not a magic assert */ ++ ASSERT(function_type <= 2); ++ ++ TRACE(DL_INFO, "Create function object. type:%s object:0x%p", ++ (function_type == BE_FUNCTION_TYPE_ISCSI ? "iSCSI" : ++ (function_type == BE_FUNCTION_TYPE_NETWORK ? "Network" : ++ "Arm")), pfob); ++ ++ memset(pfob, 0, sizeof(*pfob)); ++ ++ pfob->type = function_type; ++ pfob->csr_va = csr_va; ++ pfob->db_va = db_va; ++ pfob->pci_va = pci_va; ++ ++ spin_lock_init(&pfob->cq_lock); ++ spin_lock_init(&pfob->post_lock); ++ spin_lock_init(&pfob->mcc_context_lock); ++ ++ ++ pfob->pci_function_number = 1; ++ ++ ++ pfob->emulate = false; ++ TRACE(DL_NOTE, "Non-emulation mode"); ++ status = be_drive_POST(pfob); ++ if (status != BE_SUCCESS) { ++ TRACE(DL_ERR, "BladeEngine POST failed."); ++ goto error; ++ } ++ ++ /* Initialize the mailbox */ ++ status = be_mpu_init_mailbox(pfob, mailbox); ++ if (status != BE_SUCCESS) { ++ TRACE(DL_ERR, "Failed to initialize mailbox."); ++ goto error; ++ } ++ /* ++ * Cache the firmware config for ASSERTs in hwclib and later ++ * driver queries. ++ */ ++ status = be_function_internal_query_firmware_config(pfob, ++ &pfob->fw_config); ++ if (status != BE_SUCCESS) { ++ TRACE(DL_ERR, "Failed to query firmware config."); ++ goto error; ++ } ++ ++error: ++ if (status != BE_SUCCESS) { ++ /* No cleanup necessary */ ++ TRACE(DL_ERR, "Failed to create function."); ++ memset(pfob, 0, sizeof(*pfob)); ++ } ++ return status; ++} ++ ++/* ++ This routine drops the reference count on a given function object. Once ++ the reference count falls to zero, the function object is destroyed and all ++ resources held are freed. ++ ++ FunctionObject - The function object to drop the reference to. ++*/ ++int be_function_object_destroy(struct be_function_object *pfob) ++{ ++ TRACE(DL_INFO, "Destroy pfob. Object:0x%p", ++ pfob); ++ ++ ++ ASSERT(pfob->mcc == NULL); ++ ++ return BE_SUCCESS; ++} ++ ++int be_function_cleanup(struct be_function_object *pfob) ++{ ++ int status = 0; ++ u32 isr; ++ u32 host_intr; ++ struct PCICFG_HOST_TIMER_INT_CTRL_CSR_AMAP ctrl; ++ ++ ++ if (pfob->type == BE_FUNCTION_TYPE_NETWORK) { ++ status = be_rxf_multicast_config(pfob, false, 0, ++ NULL, NULL, NULL, NULL); ++ ASSERT(status == BE_SUCCESS); ++ } ++ /* VLAN */ ++ status = be_rxf_vlan_config(pfob, false, 0, NULL, NULL, NULL, NULL); ++ ASSERT(status == BE_SUCCESS); ++ /* ++ * MCC Queue -- Switches to mailbox mode. May want to destroy ++ * all but the MCC CQ before this call if polling CQ is much better ++ * performance than polling mailbox register. ++ */ ++ if (pfob->mcc) ++ status = be_mcc_ring_destroy(pfob->mcc); ++ /* ++ * If interrupts are disabled, clear any CEV interrupt assertions that ++ * fired after we stopped processing EQs. ++ */ ++ ctrl.dw[0] = PCICFG1_READ(pfob, host_timer_int_ctrl); ++ host_intr = AMAP_GET_BITS_PTR(PCICFG_HOST_TIMER_INT_CTRL_CSR, ++ hostintr, ctrl.dw); ++ if (!host_intr) ++ if (pfob->type == BE_FUNCTION_TYPE_NETWORK) ++ isr = CSR_READ(pfob, cev.isr1); ++ else ++ isr = CSR_READ(pfob, cev.isr0); ++ else ++ /* This should never happen... */ ++ TRACE(DL_ERR, "function_cleanup called with interrupt enabled"); ++ /* Function object destroy */ ++ status = be_function_object_destroy(pfob); ++ ASSERT(status == BE_SUCCESS); ++ ++ return status; ++} ++ ++ ++void * ++be_function_prepare_embedded_fwcmd(struct be_function_object *pfob, ++ struct MCC_WRB_AMAP *wrb, u32 payld_len, u32 request_length, ++ u32 response_length, u32 opcode, u32 subsystem) ++{ ++ struct FWCMD_REQUEST_HEADER *header = NULL; ++ u32 n; ++ ++ ASSERT(wrb); ++ ++ n = offsetof(struct BE_MCC_WRB_AMAP, payload)/8; ++ AMAP_SET_BITS_PTR(MCC_WRB, embedded, wrb, 1); ++ AMAP_SET_BITS_PTR(MCC_WRB, payload_length, wrb, min(payld_len, n)); ++ header = (struct FWCMD_REQUEST_HEADER *)((u8 *)wrb + n); ++ ++ header->timeout = 0; ++ header->domain = 0; ++ header->request_length = max(request_length, response_length); ++ header->opcode = opcode; ++ header->subsystem = subsystem; ++ ++ return header; ++} ++ ++void * ++be_function_prepare_nonembedded_fwcmd(struct be_function_object *pfob, ++ struct MCC_WRB_AMAP *wrb, ++ void *fwcmd_va, u64 fwcmd_pa, ++ u32 payld_len, ++ u32 request_length, ++ u32 response_length, ++ u32 opcode, u32 subsystem) ++{ ++ struct FWCMD_REQUEST_HEADER *header = NULL; ++ u32 n; ++ struct MCC_WRB_PAYLOAD_AMAP *plp; ++ ++ ASSERT(wrb); ++ ASSERT(fwcmd_va); ++ ++ header = (struct FWCMD_REQUEST_HEADER *) fwcmd_va; ++ ++ AMAP_SET_BITS_PTR(MCC_WRB, embedded, wrb, 0); ++ AMAP_SET_BITS_PTR(MCC_WRB, payload_length, wrb, payld_len); ++ ++ /* ++ * Assume one fragment. The caller may override the SGL by ++ * rewriting the 0th length and adding more entries. They ++ * will also need to update the sge_count. ++ */ ++ AMAP_SET_BITS_PTR(MCC_WRB, sge_count, wrb, 1); ++ ++ n = offsetof(struct BE_MCC_WRB_AMAP, payload)/8; ++ plp = (struct MCC_WRB_PAYLOAD_AMAP *)((u8 *)wrb + n); ++ AMAP_SET_BITS_PTR(MCC_WRB_PAYLOAD, sgl[0].length, plp, payld_len); ++ AMAP_SET_BITS_PTR(MCC_WRB_PAYLOAD, sgl[0].pa_lo, plp, (u32)fwcmd_pa); ++ AMAP_SET_BITS_PTR(MCC_WRB_PAYLOAD, sgl[0].pa_hi, plp, ++ upper_32_bits(fwcmd_pa)); ++ ++ header->timeout = 0; ++ header->domain = 0; ++ header->request_length = max(request_length, response_length); ++ header->opcode = opcode; ++ header->subsystem = subsystem; ++ ++ return header; ++} ++ ++struct MCC_WRB_AMAP * ++be_function_peek_mcc_wrb(struct be_function_object *pfob) ++{ ++ struct MCC_WRB_AMAP *wrb = NULL; ++ u32 offset; ++ ++ if (pfob->mcc) ++ wrb = _be_mpu_peek_ring_wrb(pfob->mcc, false); ++ else { ++ offset = offsetof(struct BE_MCC_MAILBOX_AMAP, wrb)/8; ++ wrb = (struct MCC_WRB_AMAP *) ((u8 *) pfob->mailbox.va + ++ offset); ++ } ++ ++ if (wrb) ++ memset(wrb, 0, sizeof(struct MCC_WRB_AMAP)); ++ ++ return wrb; ++} ++ ++#if defined(BE_DEBUG) ++void be_function_debug_print_wrb(struct be_function_object *pfob, ++ struct MCC_WRB_AMAP *wrb, void *optional_fwcmd_va, ++ struct be_mcc_wrb_context *wrb_context) ++{ ++ ++ struct FWCMD_REQUEST_HEADER *header = NULL; ++ u8 embedded; ++ u32 n; ++ ++ embedded = AMAP_GET_BITS_PTR(MCC_WRB, embedded, wrb); ++ ++ if (embedded) { ++ n = offsetof(struct BE_MCC_WRB_AMAP, payload)/8; ++ header = (struct FWCMD_REQUEST_HEADER *)((u8 *)wrb + n); ++ } else { ++ header = (struct FWCMD_REQUEST_HEADER *) optional_fwcmd_va; ++ } ++ ++ /* Save the completed count before posting for a debug assert. */ ++ ++ if (header) { ++ wrb_context->opcode = header->opcode; ++ wrb_context->subsystem = header->subsystem; ++ ++ } else { ++ wrb_context->opcode = 0; ++ wrb_context->subsystem = 0; ++ } ++} ++#else ++#define be_function_debug_print_wrb(a_, b_, c_, d_) ++#endif ++ ++int ++be_function_post_mcc_wrb(struct be_function_object *pfob, ++ struct MCC_WRB_AMAP *wrb, ++ struct be_generic_q_ctxt *q_ctxt, ++ mcc_wrb_cqe_callback cb, void *cb_context, ++ mcc_wrb_cqe_callback internal_cb, ++ void *internal_cb_context, void *optional_fwcmd_va, ++ struct be_mcc_wrb_response_copy *rc) ++{ ++ int status; ++ struct be_mcc_wrb_context *wrb_context = NULL; ++ u64 *p; ++ ++ if (q_ctxt) { ++ /* Initialize context. */ ++ q_ctxt->context.internal_cb = internal_cb; ++ q_ctxt->context.internal_cb_context = internal_cb_context; ++ q_ctxt->context.cb = cb; ++ q_ctxt->context.cb_context = cb_context; ++ if (rc) { ++ q_ctxt->context.copy.length = rc->length; ++ q_ctxt->context.copy.fwcmd_offset = rc->fwcmd_offset; ++ q_ctxt->context.copy.va = rc->va; ++ } else ++ q_ctxt->context.copy.length = 0; ++ ++ q_ctxt->context.optional_fwcmd_va = optional_fwcmd_va; ++ ++ /* Queue this request */ ++ status = be_function_queue_mcc_wrb(pfob, q_ctxt); ++ ++ goto Error; ++ } ++ /* ++ * Allocate a WRB context struct to hold the callback pointers, ++ * status, etc. This is required if commands complete out of order. ++ */ ++ wrb_context = _be_mcc_allocate_wrb_context(pfob); ++ if (!wrb_context) { ++ TRACE(DL_WARN, "Failed to allocate MCC WRB context."); ++ status = BE_STATUS_SYSTEM_RESOURCES; ++ goto Error; ++ } ++ /* Initialize context. */ ++ memset(wrb_context, 0, sizeof(*wrb_context)); ++ wrb_context->internal_cb = internal_cb; ++ wrb_context->internal_cb_context = internal_cb_context; ++ wrb_context->cb = cb; ++ wrb_context->cb_context = cb_context; ++ if (rc) { ++ wrb_context->copy.length = rc->length; ++ wrb_context->copy.fwcmd_offset = rc->fwcmd_offset; ++ wrb_context->copy.va = rc->va; ++ } else ++ wrb_context->copy.length = 0; ++ wrb_context->wrb = wrb; ++ ++ /* ++ * Copy the context pointer into the WRB opaque tag field. ++ * Verify assumption of 64-bit tag with a compile time assert. ++ */ ++ p = (u64 *) ((u8 *)wrb + offsetof(struct BE_MCC_WRB_AMAP, tag)/8); ++ *p = (u64)(size_t)wrb_context; ++ ++ /* Print info about this FWCMD for debug builds. */ ++ be_function_debug_print_wrb(pfob, wrb, optional_fwcmd_va, wrb_context); ++ ++ /* ++ * issue the WRB to the MPU as appropriate ++ */ ++ if (pfob->mcc) { ++ /* ++ * we're in WRB mode, pass to the mcc layer ++ */ ++ status = _be_mpu_post_wrb_ring(pfob->mcc, wrb, wrb_context); ++ } else { ++ /* ++ * we're in mailbox mode ++ */ ++ status = _be_mpu_post_wrb_mailbox(pfob, wrb, wrb_context); ++ ++ /* mailbox mode always completes synchronously */ ++ ASSERT(status != BE_STATUS_PENDING); ++ } ++ ++Error: ++ ++ return status; ++} ++ ++int ++be_function_ring_destroy(struct be_function_object *pfob, ++ u32 id, u32 ring_type, mcc_wrb_cqe_callback cb, ++ void *cb_context, mcc_wrb_cqe_callback internal_cb, ++ void *internal_cb_context) ++{ ++ ++ struct FWCMD_COMMON_RING_DESTROY *fwcmd = NULL; ++ struct MCC_WRB_AMAP *wrb = NULL; ++ int status = 0; ++ unsigned long irql; ++ ++ spin_lock_irqsave(&pfob->post_lock, irql); ++ ++ TRACE(DL_INFO, "Destroy ring id:%d type:%d", id, ring_type); ++ ++ wrb = be_function_peek_mcc_wrb(pfob); ++ if (!wrb) { ++ ASSERT(wrb); ++ TRACE(DL_ERR, "No free MCC WRBs in destroy ring."); ++ status = BE_STATUS_NO_MCC_WRB; ++ goto Error; ++ } ++ /* Prepares an embedded fwcmd, including request/response sizes. */ ++ fwcmd = BE_PREPARE_EMBEDDED_FWCMD(pfob, wrb, COMMON_RING_DESTROY); ++ ++ fwcmd->params.request.id = id; ++ fwcmd->params.request.ring_type = ring_type; ++ ++ /* Post the f/w command */ ++ status = be_function_post_mcc_wrb(pfob, wrb, NULL, cb, cb_context, ++ internal_cb, internal_cb_context, fwcmd, NULL); ++ if (status != BE_SUCCESS && status != BE_PENDING) { ++ TRACE(DL_ERR, "Ring destroy fwcmd failed. id:%d ring_type:%d", ++ id, ring_type); ++ goto Error; ++ } ++ ++Error: ++ spin_unlock_irqrestore(&pfob->post_lock, irql); ++ if (pfob->pend_queue_driving && pfob->mcc) { ++ pfob->pend_queue_driving = 0; ++ be_drive_mcc_wrb_queue(pfob->mcc); ++ } ++ return status; ++} ++ ++void ++be_rd_to_pa_list(struct ring_desc *rd, struct PHYS_ADDR *pa_list, u32 max_num) ++{ ++ u32 num_pages = PAGES_SPANNED(rd->va, rd->length); ++ u32 i = 0; ++ u64 pa = rd->pa; ++ __le64 lepa; ++ ++ ASSERT(pa_list); ++ ASSERT(pa); ++ ++ for (i = 0; i < min(num_pages, max_num); i++) { ++ lepa = cpu_to_le64(pa); ++ pa_list[i].lo = (u32)lepa; ++ pa_list[i].hi = upper_32_bits(lepa); ++ pa += PAGE_SIZE; ++ } ++} ++ ++ ++ ++/*----------------------------------------------------------------------------- ++ * Function: be_function_get_fw_version ++ * Retrieves the firmware version on the adpater. If the callback is ++ * NULL this call executes synchronously. If the callback is not NULL, ++ * the returned status will be BE_PENDING if the command was issued ++ * successfully. ++ * pfob - ++ * fwv - Pointer to response buffer if callback is NULL. ++ * cb - Callback function invoked when the FWCMD completes. ++ * cb_context - Passed to the callback function. ++ * return pend_status - BE_SUCCESS (0) on success. ++ * BE_PENDING (postive value) if the FWCMD ++ * completion is pending. Negative error code on failure. ++ *--------------------------------------------------------------------------- ++ */ ++int ++be_function_get_fw_version(struct be_function_object *pfob, ++ struct FWCMD_COMMON_GET_FW_VERSION_RESPONSE_PAYLOAD *fwv, ++ mcc_wrb_cqe_callback cb, void *cb_context) ++{ ++ int status = BE_SUCCESS; ++ struct MCC_WRB_AMAP *wrb = NULL; ++ struct FWCMD_COMMON_GET_FW_VERSION *fwcmd = NULL; ++ unsigned long irql; ++ struct be_mcc_wrb_response_copy rc; ++ ++ spin_lock_irqsave(&pfob->post_lock, irql); ++ ++ wrb = be_function_peek_mcc_wrb(pfob); ++ if (!wrb) { ++ TRACE(DL_ERR, "MCC wrb peek failed."); ++ status = BE_STATUS_NO_MCC_WRB; ++ goto Error; ++ } ++ ++ if (!cb && !fwv) { ++ TRACE(DL_ERR, "callback and response buffer NULL!"); ++ status = BE_NOT_OK; ++ goto Error; ++ } ++ /* Prepares an embedded fwcmd, including request/response sizes. */ ++ fwcmd = BE_PREPARE_EMBEDDED_FWCMD(pfob, wrb, COMMON_GET_FW_VERSION); ++ ++ rc.length = FIELD_SIZEOF(struct FWCMD_COMMON_GET_FW_VERSION, ++ params.response); ++ rc.fwcmd_offset = offsetof(struct FWCMD_COMMON_GET_FW_VERSION, ++ params.response); ++ rc.va = fwv; ++ ++ /* Post the f/w command */ ++ status = be_function_post_mcc_wrb(pfob, wrb, NULL, cb, ++ cb_context, NULL, NULL, fwcmd, &rc); ++ ++Error: ++ spin_unlock_irqrestore(&pfob->post_lock, irql); ++ if (pfob->pend_queue_driving && pfob->mcc) { ++ pfob->pend_queue_driving = 0; ++ be_drive_mcc_wrb_queue(pfob->mcc); ++ } ++ return status; ++} ++ ++int ++be_function_queue_mcc_wrb(struct be_function_object *pfob, ++ struct be_generic_q_ctxt *q_ctxt) ++{ ++ int status; ++ ++ ASSERT(q_ctxt); ++ ++ /* ++ * issue the WRB to the MPU as appropriate ++ */ ++ if (pfob->mcc) { ++ ++ /* We're in ring mode. Queue this item. */ ++ pfob->mcc->backlog_length++; ++ list_add_tail(&q_ctxt->context.list, &pfob->mcc->backlog); ++ status = BE_PENDING; ++ } else { ++ status = BE_NOT_OK; ++ } ++ return status; ++} ++ +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/drivers/staging/benet/fwcmd_common_bmap.h linux-2.6.29-rc3.owrt/drivers/staging/benet/fwcmd_common_bmap.h +--- linux-2.6.29.owrt/drivers/staging/benet/fwcmd_common_bmap.h 1970-01-01 01:00:00.000000000 +0100 ++++ linux-2.6.29-rc3.owrt/drivers/staging/benet/fwcmd_common_bmap.h 2009-05-10 23:48:29.000000000 +0200 +@@ -0,0 +1,717 @@ ++/* ++ * Copyright (C) 2005 - 2008 ServerEngines ++ * All rights reserved. ++ * ++ * 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. The full GNU General ++ * Public License is included in this distribution in the file called COPYING. ++ * ++ * Contact Information: ++ * linux-drivers@serverengines.com ++ * ++ * ServerEngines ++ * 209 N. Fair Oaks Ave ++ * Sunnyvale, CA 94085 ++ */ ++/* ++ * Autogenerated by srcgen version: 0127 ++ */ ++#ifndef __fwcmd_common_bmap_h__ ++#define __fwcmd_common_bmap_h__ ++#include "fwcmd_types_bmap.h" ++#include "fwcmd_hdr_bmap.h" ++ ++#if defined(__BIG_ENDIAN) ++ /* Physical Address. */ ++struct PHYS_ADDR { ++ union { ++ struct { ++ u32 lo; /* DWORD 0 */ ++ u32 hi; /* DWORD 1 */ ++ } __packed; /* unnamed struct */ ++ u32 dw[2]; /* dword union */ ++ }; /* unnamed union */ ++} __packed ; ++ ++ ++#else ++ /* Physical Address. */ ++struct PHYS_ADDR { ++ union { ++ struct { ++ u32 lo; /* DWORD 0 */ ++ u32 hi; /* DWORD 1 */ ++ } __packed; /* unnamed struct */ ++ u32 dw[2]; /* dword union */ ++ }; /* unnamed union */ ++} __packed ; ++ ++struct BE_LINK_STATUS { ++ u8 mac0_duplex; ++ u8 mac0_speed; ++ u8 mac1_duplex; ++ u8 mac1_speed; ++ u8 mgmt_mac_duplex; ++ u8 mgmt_mac_speed; ++ u8 active_port; ++ u8 rsvd0; ++ u8 mac0_fault; ++ u8 mac1_fault; ++ u16 rsvd1; ++} __packed; ++#endif ++ ++struct FWCMD_COMMON_ANON_170_REQUEST { ++ u32 rsvd0; ++} __packed; ++ ++union LINK_STATUS_QUERY_PARAMS { ++ struct BE_LINK_STATUS response; ++ struct FWCMD_COMMON_ANON_170_REQUEST request; ++} __packed; ++ ++/* ++ * Queries the the link status for all ports. The valid values below ++ * DO NOT indicate that a particular duplex or speed is supported by ++ * BladeEngine. These enumerations simply list all possible duplexes ++ * and speeds for any port. Consult BladeEngine product documentation ++ * for the supported parameters. ++ */ ++struct FWCMD_COMMON_NTWK_LINK_STATUS_QUERY { ++ union FWCMD_HEADER header; ++ union LINK_STATUS_QUERY_PARAMS params; ++} __packed; ++ ++struct FWCMD_COMMON_ANON_171_REQUEST { ++ u8 type; ++ u8 port; ++ u8 mac1; ++ u8 permanent; ++} __packed; ++ ++struct FWCMD_COMMON_ANON_172_RESPONSE { ++ struct MAC_ADDRESS_FORMAT mac; ++} __packed; ++ ++union NTWK_MAC_QUERY_PARAMS { ++ struct FWCMD_COMMON_ANON_171_REQUEST request; ++ struct FWCMD_COMMON_ANON_172_RESPONSE response; ++} __packed; ++ ++/* Queries one MAC address. */ ++struct FWCMD_COMMON_NTWK_MAC_QUERY { ++ union FWCMD_HEADER header; ++ union NTWK_MAC_QUERY_PARAMS params; ++} __packed; ++ ++struct MAC_SET_PARAMS_IN { ++ u8 type; ++ u8 port; ++ u8 mac1; ++ u8 invalidate; ++ struct MAC_ADDRESS_FORMAT mac; ++} __packed; ++ ++struct MAC_SET_PARAMS_OUT { ++ u32 rsvd0; ++} __packed; ++ ++union MAC_SET_PARAMS { ++ struct MAC_SET_PARAMS_IN request; ++ struct MAC_SET_PARAMS_OUT response; ++} __packed; ++ ++/* Sets a MAC address. */ ++struct FWCMD_COMMON_NTWK_MAC_SET { ++ union FWCMD_HEADER header; ++ union MAC_SET_PARAMS params; ++} __packed; ++ ++/* MAC address list. */ ++struct NTWK_MULTICAST_MAC_LIST { ++ u8 byte[6]; ++} __packed; ++ ++struct FWCMD_COMMON_NTWK_MULTICAST_SET_REQUEST_PAYLOAD { ++ u16 num_mac; ++ u8 promiscuous; ++ u8 rsvd0; ++ struct NTWK_MULTICAST_MAC_LIST mac[32]; ++} __packed; ++ ++struct FWCMD_COMMON_ANON_174_RESPONSE { ++ u32 rsvd0; ++} __packed; ++ ++union FWCMD_COMMON_ANON_173_PARAMS { ++ struct FWCMD_COMMON_NTWK_MULTICAST_SET_REQUEST_PAYLOAD request; ++ struct FWCMD_COMMON_ANON_174_RESPONSE response; ++} __packed; ++ ++/* ++ * Sets multicast address hash. The MPU will merge the MAC address lists ++ * from all clients, including the networking and storage functions. ++ * This command may fail if the final merged list of MAC addresses exceeds ++ * 32 entries. ++ */ ++struct FWCMD_COMMON_NTWK_MULTICAST_SET { ++ union FWCMD_HEADER header; ++ union FWCMD_COMMON_ANON_173_PARAMS params; ++} __packed; ++ ++struct FWCMD_COMMON_NTWK_VLAN_CONFIG_REQUEST_PAYLOAD { ++ u16 num_vlan; ++ u8 promiscuous; ++ u8 rsvd0; ++ u16 vlan_tag[32]; ++} __packed; ++ ++struct FWCMD_COMMON_ANON_176_RESPONSE { ++ u32 rsvd0; ++} __packed; ++ ++union FWCMD_COMMON_ANON_175_PARAMS { ++ struct FWCMD_COMMON_NTWK_VLAN_CONFIG_REQUEST_PAYLOAD request; ++ struct FWCMD_COMMON_ANON_176_RESPONSE response; ++} __packed; ++ ++/* ++ * Sets VLAN tag filter. The MPU will merge the VLAN tag list from all ++ * clients, including the networking and storage functions. This command ++ * may fail if the final vlan_tag array (from all functions) is longer ++ * than 32 entries. ++ */ ++struct FWCMD_COMMON_NTWK_VLAN_CONFIG { ++ union FWCMD_HEADER header; ++ union FWCMD_COMMON_ANON_175_PARAMS params; ++} __packed; ++ ++struct RING_DESTROY_REQUEST { ++ u16 ring_type; ++ u16 id; ++ u8 bypass_flush; ++ u8 rsvd0; ++ u16 rsvd1; ++} __packed; ++ ++struct FWCMD_COMMON_ANON_190_RESPONSE { ++ u32 rsvd0; ++} __packed; ++ ++union FWCMD_COMMON_ANON_189_PARAMS { ++ struct RING_DESTROY_REQUEST request; ++ struct FWCMD_COMMON_ANON_190_RESPONSE response; ++} __packed; ++/* ++ * Command for destroying any ring. The connection(s) using the ring should ++ * be quiesced before destroying the ring. ++ */ ++struct FWCMD_COMMON_RING_DESTROY { ++ union FWCMD_HEADER header; ++ union FWCMD_COMMON_ANON_189_PARAMS params; ++} __packed; ++ ++struct FWCMD_COMMON_ANON_192_REQUEST { ++ u16 num_pages; ++ u16 rsvd0; ++ struct CQ_CONTEXT_AMAP context; ++ struct PHYS_ADDR pages[4]; ++} __packed ; ++ ++struct FWCMD_COMMON_ANON_193_RESPONSE { ++ u16 cq_id; ++} __packed ; ++ ++union FWCMD_COMMON_ANON_191_PARAMS { ++ struct FWCMD_COMMON_ANON_192_REQUEST request; ++ struct FWCMD_COMMON_ANON_193_RESPONSE response; ++} __packed ; ++ ++/* ++ * Command for creating a completion queue. A Completion Queue must span ++ * at least 1 page and at most 4 pages. Each completion queue entry ++ * is 16 bytes regardless of CQ entry format. Thus the ring must be ++ * at least 256 entries deep (corresponding to 1 page) and can be at ++ * most 1024 entries deep (corresponding to 4 pages). The number of ++ * pages posted must contain the CQ ring size as encoded in the context. ++ * ++ */ ++struct FWCMD_COMMON_CQ_CREATE { ++ union FWCMD_HEADER header; ++ union FWCMD_COMMON_ANON_191_PARAMS params; ++} __packed ; ++ ++struct FWCMD_COMMON_ANON_198_REQUEST { ++ u16 num_pages; ++ u16 rsvd0; ++ struct EQ_CONTEXT_AMAP context; ++ struct PHYS_ADDR pages[8]; ++} __packed ; ++ ++struct FWCMD_COMMON_ANON_199_RESPONSE { ++ u16 eq_id; ++} __packed ; ++ ++union FWCMD_COMMON_ANON_197_PARAMS { ++ struct FWCMD_COMMON_ANON_198_REQUEST request; ++ struct FWCMD_COMMON_ANON_199_RESPONSE response; ++} __packed ; ++ ++/* ++ * Command for creating a event queue. An Event Queue must span at least ++ * 1 page and at most 8 pages. The number of pages posted must contain ++ * the EQ ring. The ring is defined by the size of the EQ entries (encoded ++ * in the context) and the number of EQ entries (also encoded in the ++ * context). ++ */ ++struct FWCMD_COMMON_EQ_CREATE { ++ union FWCMD_HEADER header; ++ union FWCMD_COMMON_ANON_197_PARAMS params; ++} __packed ; ++ ++struct FWCMD_COMMON_ANON_201_REQUEST { ++ u16 cq_id; ++ u16 bcmc_cq_id; ++ u16 num_pages; ++ u16 rsvd0; ++ struct PHYS_ADDR pages[2]; ++} __packed; ++ ++struct FWCMD_COMMON_ANON_202_RESPONSE { ++ u16 id; ++} __packed; ++ ++union FWCMD_COMMON_ANON_200_PARAMS { ++ struct FWCMD_COMMON_ANON_201_REQUEST request; ++ struct FWCMD_COMMON_ANON_202_RESPONSE response; ++} __packed; ++ ++/* ++ * Command for creating Ethernet receive ring. An ERX ring contains ETH_RX_D ++ * entries (8 bytes each). An ERX ring must be 1024 entries deep ++ * (corresponding to 2 pages). ++ */ ++struct FWCMD_COMMON_ETH_RX_CREATE { ++ union FWCMD_HEADER header; ++ union FWCMD_COMMON_ANON_200_PARAMS params; ++} __packed; ++ ++struct FWCMD_COMMON_ANON_204_REQUEST { ++ u16 num_pages; ++ u8 ulp_num; ++ u8 type; ++ struct ETX_CONTEXT_AMAP context; ++ struct PHYS_ADDR pages[8]; ++} __packed ; ++ ++struct FWCMD_COMMON_ANON_205_RESPONSE { ++ u16 cid; ++ u8 ulp_num; ++ u8 rsvd0; ++} __packed ; ++ ++union FWCMD_COMMON_ANON_203_PARAMS { ++ struct FWCMD_COMMON_ANON_204_REQUEST request; ++ struct FWCMD_COMMON_ANON_205_RESPONSE response; ++} __packed ; ++ ++/* ++ * Command for creating an Ethernet transmit ring. An ETX ring contains ++ * ETH_WRB entries (16 bytes each). An ETX ring must be at least 256 ++ * entries deep (corresponding to 1 page) and at most 2k entries deep ++ * (corresponding to 8 pages). ++ */ ++struct FWCMD_COMMON_ETH_TX_CREATE { ++ union FWCMD_HEADER header; ++ union FWCMD_COMMON_ANON_203_PARAMS params; ++} __packed ; ++ ++struct FWCMD_COMMON_ANON_222_REQUEST { ++ u16 num_pages; ++ u16 rsvd0; ++ struct MCC_RING_CONTEXT_AMAP context; ++ struct PHYS_ADDR pages[8]; ++} __packed ; ++ ++struct FWCMD_COMMON_ANON_223_RESPONSE { ++ u16 id; ++} __packed ; ++ ++union FWCMD_COMMON_ANON_221_PARAMS { ++ struct FWCMD_COMMON_ANON_222_REQUEST request; ++ struct FWCMD_COMMON_ANON_223_RESPONSE response; ++} __packed ; ++ ++/* ++ * Command for creating the MCC ring. An MCC ring must be at least 16 ++ * entries deep (corresponding to 1 page) and at most 128 entries deep ++ * (corresponding to 8 pages). ++ */ ++struct FWCMD_COMMON_MCC_CREATE { ++ union FWCMD_HEADER header; ++ union FWCMD_COMMON_ANON_221_PARAMS params; ++} __packed ; ++ ++struct GET_QOS_IN { ++ u32 qos_params_rsvd; ++} __packed; ++ ++struct GET_QOS_OUT { ++ u32 max_bits_per_second_NIC; ++ u32 max_packets_per_second_NIC; ++ u32 max_ios_per_second_iSCSI; ++ u32 max_bytes_per_second_iSCSI; ++ u16 domain_VLAN_tag; ++ u16 fabric_domain_ID; ++ u32 qos_params_oem[4]; ++} __packed; ++ ++union GET_QOS_PARAMS { ++ struct GET_QOS_IN request; ++ struct GET_QOS_OUT response; ++} __packed; ++ ++/* QOS/Bandwidth settings per domain. Applicable only in VMs. */ ++struct FWCMD_COMMON_GET_QOS { ++ union FWCMD_HEADER header; ++ union GET_QOS_PARAMS params; ++} __packed; ++ ++struct SET_QOS_IN { ++ u32 valid_flags; ++ u32 max_bits_per_second_NIC; ++ u32 max_packets_per_second_NIC; ++ u32 max_ios_per_second_iSCSI; ++ u32 max_bytes_per_second_iSCSI; ++ u16 domain_VLAN_tag; ++ u16 fabric_domain_ID; ++ u32 qos_params_oem[4]; ++} __packed; ++ ++struct SET_QOS_OUT { ++ u32 qos_params_rsvd; ++} __packed; ++ ++union SET_QOS_PARAMS { ++ struct SET_QOS_IN request; ++ struct SET_QOS_OUT response; ++} __packed; ++ ++/* QOS/Bandwidth settings per domain. Applicable only in VMs. */ ++struct FWCMD_COMMON_SET_QOS { ++ union FWCMD_HEADER header; ++ union SET_QOS_PARAMS params; ++} __packed; ++ ++struct SET_FRAME_SIZE_IN { ++ u32 max_tx_frame_size; ++ u32 max_rx_frame_size; ++} __packed; ++ ++struct SET_FRAME_SIZE_OUT { ++ u32 chip_max_tx_frame_size; ++ u32 chip_max_rx_frame_size; ++} __packed; ++ ++union SET_FRAME_SIZE_PARAMS { ++ struct SET_FRAME_SIZE_IN request; ++ struct SET_FRAME_SIZE_OUT response; ++} __packed; ++ ++/* Set frame size command. Only host domain may issue this command. */ ++struct FWCMD_COMMON_SET_FRAME_SIZE { ++ union FWCMD_HEADER header; ++ union SET_FRAME_SIZE_PARAMS params; ++} __packed; ++ ++struct FORCE_FAILOVER_IN { ++ u32 move_to_port; ++ u32 failover_config; ++} __packed; ++ ++struct FWCMD_COMMON_ANON_231_RESPONSE { ++ u32 rsvd0; ++} __packed; ++ ++union FWCMD_COMMON_ANON_230_PARAMS { ++ struct FORCE_FAILOVER_IN request; ++ struct FWCMD_COMMON_ANON_231_RESPONSE response; ++} __packed; ++ ++/* ++ * Use this command to control failover in BladeEngine. It may be used ++ * to failback to a restored port or to forcibly move traffic from ++ * one port to another. It may also be used to enable or disable the ++ * automatic failover feature. This command can only be issued by domain ++ * 0. ++ */ ++struct FWCMD_COMMON_FORCE_FAILOVER { ++ union FWCMD_HEADER header; ++ union FWCMD_COMMON_ANON_230_PARAMS params; ++} __packed; ++ ++struct FWCMD_COMMON_ANON_240_REQUEST { ++ u64 context; ++} __packed; ++ ++struct FWCMD_COMMON_ANON_241_RESPONSE { ++ u64 context; ++} __packed; ++ ++union FWCMD_COMMON_ANON_239_PARAMS { ++ struct FWCMD_COMMON_ANON_240_REQUEST request; ++ struct FWCMD_COMMON_ANON_241_RESPONSE response; ++} __packed; ++ ++/* ++ * This command can be used by clients as a no-operation request. Typical ++ * uses for drivers are as a heartbeat mechanism, or deferred processing ++ * catalyst. The ARM will always complete this command with a good completion. ++ * The 64-bit parameter is not touched by the ARM processor. ++ */ ++struct FWCMD_COMMON_NOP { ++ union FWCMD_HEADER header; ++ union FWCMD_COMMON_ANON_239_PARAMS params; ++} __packed; ++ ++struct NTWK_RX_FILTER_SETTINGS { ++ u8 promiscuous; ++ u8 ip_cksum; ++ u8 tcp_cksum; ++ u8 udp_cksum; ++ u8 pass_err; ++ u8 pass_ckerr; ++ u8 strip_crc; ++ u8 mcast_en; ++ u8 bcast_en; ++ u8 mcast_promiscuous_en; ++ u8 unicast_en; ++ u8 vlan_promiscuous; ++} __packed; ++ ++union FWCMD_COMMON_ANON_242_PARAMS { ++ struct NTWK_RX_FILTER_SETTINGS request; ++ struct NTWK_RX_FILTER_SETTINGS response; ++} __packed; ++ ++/* ++ * This command is used to modify the ethernet receive filter configuration. ++ * Only domain 0 network function drivers may issue this command. The ++ * applied configuration is returned in the response payload. Note: ++ * Some receive packet filter settings are global on BladeEngine and ++ * can affect both the storage and network function clients that the ++ * BladeEngine hardware and firmware serve. Additionaly, depending ++ * on the revision of BladeEngine, some ethernet receive filter settings ++ * are dependent on others. If a dependency exists between settings ++ * for the BladeEngine revision, and the command request settings do ++ * not meet the dependency requirement, the invalid settings will not ++ * be applied despite the comand succeeding. For example: a driver may ++ * request to enable broadcast packets, but not enable multicast packets. ++ * On early revisions of BladeEngine, there may be no distinction between ++ * broadcast and multicast filters, so broadcast could not be enabled ++ * without enabling multicast. In this scenario, the comand would still ++ * succeed, but the response payload would indicate the previously ++ * configured broadcast and multicast setting. ++ */ ++struct FWCMD_COMMON_NTWK_RX_FILTER { ++ union FWCMD_HEADER header; ++ union FWCMD_COMMON_ANON_242_PARAMS params; ++} __packed; ++ ++ ++struct FWCMD_COMMON_ANON_244_REQUEST { ++ u32 rsvd0; ++} __packed; ++ ++struct FWCMD_COMMON_GET_FW_VERSION_RESPONSE_PAYLOAD { ++ u8 firmware_version_string[32]; ++ u8 fw_on_flash_version_string[32]; ++} __packed; ++ ++union FWCMD_COMMON_ANON_243_PARAMS { ++ struct FWCMD_COMMON_ANON_244_REQUEST request; ++ struct FWCMD_COMMON_GET_FW_VERSION_RESPONSE_PAYLOAD response; ++} __packed; ++ ++/* This comand retrieves the firmware version. */ ++struct FWCMD_COMMON_GET_FW_VERSION { ++ union FWCMD_HEADER header; ++ union FWCMD_COMMON_ANON_243_PARAMS params; ++} __packed; ++ ++struct FWCMD_COMMON_ANON_246_REQUEST { ++ u16 tx_flow_control; ++ u16 rx_flow_control; ++} __packed; ++ ++struct FWCMD_COMMON_ANON_247_RESPONSE { ++ u32 rsvd0; ++} __packed; ++ ++union FWCMD_COMMON_ANON_245_PARAMS { ++ struct FWCMD_COMMON_ANON_246_REQUEST request; ++ struct FWCMD_COMMON_ANON_247_RESPONSE response; ++} __packed; ++ ++/* ++ * This comand is used to program BladeEngine flow control behavior. ++ * Only the host networking driver is allowed to use this comand. ++ */ ++struct FWCMD_COMMON_SET_FLOW_CONTROL { ++ union FWCMD_HEADER header; ++ union FWCMD_COMMON_ANON_245_PARAMS params; ++} __packed; ++ ++struct FWCMD_COMMON_ANON_249_REQUEST { ++ u32 rsvd0; ++} __packed; ++ ++struct FWCMD_COMMON_ANON_250_RESPONSE { ++ u16 tx_flow_control; ++ u16 rx_flow_control; ++} __packed; ++ ++union FWCMD_COMMON_ANON_248_PARAMS { ++ struct FWCMD_COMMON_ANON_249_REQUEST request; ++ struct FWCMD_COMMON_ANON_250_RESPONSE response; ++} __packed; ++ ++/* This comand is used to read BladeEngine flow control settings. */ ++struct FWCMD_COMMON_GET_FLOW_CONTROL { ++ union FWCMD_HEADER header; ++ union FWCMD_COMMON_ANON_248_PARAMS params; ++} __packed; ++ ++struct EQ_DELAY_PARAMS { ++ u32 eq_id; ++ u32 delay_in_microseconds; ++} __packed; ++ ++struct FWCMD_COMMON_ANON_257_REQUEST { ++ u32 num_eq; ++ u32 rsvd0; ++ struct EQ_DELAY_PARAMS delay[16]; ++} __packed; ++ ++struct FWCMD_COMMON_ANON_258_RESPONSE { ++ u32 delay_resolution_in_microseconds; ++ u32 delay_max_in_microseconds; ++} __packed; ++ ++union MODIFY_EQ_DELAY_PARAMS { ++ struct FWCMD_COMMON_ANON_257_REQUEST request; ++ struct FWCMD_COMMON_ANON_258_RESPONSE response; ++} __packed; ++ ++/* This comand changes the EQ delay for a given set of EQs. */ ++struct FWCMD_COMMON_MODIFY_EQ_DELAY { ++ union FWCMD_HEADER header; ++ union MODIFY_EQ_DELAY_PARAMS params; ++} __packed; ++ ++struct FWCMD_COMMON_ANON_260_REQUEST { ++ u32 rsvd0; ++} __packed; ++ ++struct BE_FIRMWARE_CONFIG { ++ u16 be_config_number; ++ u16 asic_revision; ++ u32 nic_ulp_mask; ++ u32 tulp_mask; ++ u32 iscsi_ulp_mask; ++ u32 rdma_ulp_mask; ++ u32 rsvd0[4]; ++ u32 eth_tx_id_start; ++ u32 eth_tx_id_count; ++ u32 eth_rx_id_start; ++ u32 eth_rx_id_count; ++ u32 tpm_wrbq_id_start; ++ u32 tpm_wrbq_id_count; ++ u32 tpm_defq_id_start; ++ u32 tpm_defq_id_count; ++ u32 iscsi_wrbq_id_start; ++ u32 iscsi_wrbq_id_count; ++ u32 iscsi_defq_id_start; ++ u32 iscsi_defq_id_count; ++ u32 rdma_qp_id_start; ++ u32 rdma_qp_id_count; ++ u32 rsvd1[8]; ++} __packed; ++ ++union FWCMD_COMMON_ANON_259_PARAMS { ++ struct FWCMD_COMMON_ANON_260_REQUEST request; ++ struct BE_FIRMWARE_CONFIG response; ++} __packed; ++ ++/* ++ * This comand queries the current firmware configuration parameters. ++ * The static configuration type is defined by be_config_number. This ++ * differentiates different BladeEngine builds, such as iSCSI Initiator ++ * versus iSCSI Target. For a given static configuration, the Upper ++ * Layer Protocol (ULP) processors may be reconfigured to support different ++ * protocols. Each ULP processor supports one or more protocols. The ++ * masks indicate which processors are configured for each protocol. ++ * For a given static configuration, the number of TCP connections ++ * supported for each protocol may vary. The *_id_start and *_id_count ++ * variables define a linear range of IDs that are available for each ++ * supported protocol. The *_id_count may be used by the driver to allocate ++ * the appropriate number of connection resources. The *_id_start may ++ * be used to map the arbitrary range of IDs to a zero-based range ++ * of indices. ++ */ ++struct FWCMD_COMMON_FIRMWARE_CONFIG { ++ union FWCMD_HEADER header; ++ union FWCMD_COMMON_ANON_259_PARAMS params; ++} __packed; ++ ++struct FWCMD_COMMON_PORT_EQUALIZATION_PARAMS { ++ u32 emph_lev_sel_port0; ++ u32 emph_lev_sel_port1; ++ u8 xaui_vo_sel; ++ u8 xaui_state; ++ u16 rsvd0; ++ u32 xaui_eq_vector; ++} __packed; ++ ++struct FWCMD_COMMON_ANON_262_REQUEST { ++ u32 rsvd0; ++} __packed; ++ ++union FWCMD_COMMON_ANON_261_PARAMS { ++ struct FWCMD_COMMON_ANON_262_REQUEST request; ++ struct FWCMD_COMMON_PORT_EQUALIZATION_PARAMS response; ++} __packed; ++ ++/* ++ * This comand can be used to read XAUI equalization parameters. The ++ * ARM firmware applies default equalization parameters during initialization. ++ * These parameters may be customer-specific when derived from the ++ * SEEPROM. See SEEPROM_DATA for equalization specific fields. ++ */ ++struct FWCMD_COMMON_GET_PORT_EQUALIZATION { ++ union FWCMD_HEADER header; ++ union FWCMD_COMMON_ANON_261_PARAMS params; ++} __packed; ++ ++struct FWCMD_COMMON_ANON_264_RESPONSE { ++ u32 rsvd0; ++} __packed; ++ ++union FWCMD_COMMON_ANON_263_PARAMS { ++ struct FWCMD_COMMON_PORT_EQUALIZATION_PARAMS request; ++ struct FWCMD_COMMON_ANON_264_RESPONSE response; ++} __packed; ++ ++/* ++ * This comand can be used to set XAUI equalization parameters. The ARM ++ * firmware applies default equalization parameters during initialization. ++ * These parameters may be customer-specific when derived from the ++ * SEEPROM. See SEEPROM_DATA for equalization specific fields. ++ */ ++struct FWCMD_COMMON_SET_PORT_EQUALIZATION { ++ union FWCMD_HEADER header; ++ union FWCMD_COMMON_ANON_263_PARAMS params; ++} __packed; ++ ++#endif /* __fwcmd_common_bmap_h__ */ +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/drivers/staging/benet/fwcmd_common.h linux-2.6.29-rc3.owrt/drivers/staging/benet/fwcmd_common.h +--- linux-2.6.29.owrt/drivers/staging/benet/fwcmd_common.h 1970-01-01 01:00:00.000000000 +0100 ++++ linux-2.6.29-rc3.owrt/drivers/staging/benet/fwcmd_common.h 2009-05-10 23:48:29.000000000 +0200 +@@ -0,0 +1,222 @@ ++/* ++ * Copyright (C) 2005 - 2008 ServerEngines ++ * All rights reserved. ++ * ++ * 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. The full GNU General ++ * Public License is included in this distribution in the file called COPYING. ++ * ++ * Contact Information: ++ * linux-drivers@serverengines.com ++ * ++ * ServerEngines ++ * 209 N. Fair Oaks Ave ++ * Sunnyvale, CA 94085 ++ */ ++/* ++ * Autogenerated by srcgen version: 0127 ++ */ ++#ifndef __fwcmd_common_amap_h__ ++#define __fwcmd_common_amap_h__ ++#include "host_struct.h" ++ ++/* --- PHY_LINK_DUPLEX_ENUM --- */ ++#define PHY_LINK_DUPLEX_NONE (0) ++#define PHY_LINK_DUPLEX_HALF (1) ++#define PHY_LINK_DUPLEX_FULL (2) ++ ++/* --- PHY_LINK_SPEED_ENUM --- */ ++#define PHY_LINK_SPEED_ZERO (0) /* No link. */ ++#define PHY_LINK_SPEED_10MBPS (1) /* 10 Mbps */ ++#define PHY_LINK_SPEED_100MBPS (2) /* 100 Mbps */ ++#define PHY_LINK_SPEED_1GBPS (3) /* 1 Gbps */ ++#define PHY_LINK_SPEED_10GBPS (4) /* 10 Gbps */ ++ ++/* --- PHY_LINK_FAULT_ENUM --- */ ++#define PHY_LINK_FAULT_NONE (0) /* No fault status ++ available or detected */ ++#define PHY_LINK_FAULT_LOCAL (1) /* Local fault detected */ ++#define PHY_LINK_FAULT_REMOTE (2) /* Remote fault detected */ ++ ++/* --- BE_ULP_MASK --- */ ++#define BE_ULP0_MASK (1) ++#define BE_ULP1_MASK (2) ++#define BE_ULP2_MASK (4) ++ ++/* --- NTWK_ACTIVE_PORT --- */ ++#define NTWK_PORT_A (0) /* Port A is currently active */ ++#define NTWK_PORT_B (1) /* Port B is currently active */ ++#define NTWK_NO_ACTIVE_PORT (15) /* Both ports have lost link */ ++ ++/* --- NTWK_LINK_TYPE --- */ ++#define NTWK_LINK_TYPE_PHYSICAL (0) /* link up/down event ++ applies to BladeEngine's ++ Physical Ports ++ */ ++#define NTWK_LINK_TYPE_VIRTUAL (1) /* Virtual link up/down event ++ reported by BladeExchange. ++ This applies only when the ++ VLD feature is enabled ++ */ ++ ++/* ++ * --- FWCMD_MAC_TYPE_ENUM --- ++ * This enum defines the types of MAC addresses in the RXF MAC Address Table. ++ */ ++#define MAC_ADDRESS_TYPE_STORAGE (0) /* Storage MAC Address */ ++#define MAC_ADDRESS_TYPE_NETWORK (1) /* Network MAC Address */ ++#define MAC_ADDRESS_TYPE_PD (2) /* Protection Domain MAC Addr */ ++#define MAC_ADDRESS_TYPE_MANAGEMENT (3) /* Managment MAC Address */ ++ ++ ++/* --- FWCMD_RING_TYPE_ENUM --- */ ++#define FWCMD_RING_TYPE_ETH_RX (1) /* Ring created with */ ++ /* FWCMD_COMMON_ETH_RX_CREATE. */ ++#define FWCMD_RING_TYPE_ETH_TX (2) /* Ring created with */ ++ /* FWCMD_COMMON_ETH_TX_CREATE. */ ++#define FWCMD_RING_TYPE_ISCSI_WRBQ (3) /* Ring created with */ ++ /* FWCMD_COMMON_ISCSI_WRBQ_CREATE. */ ++#define FWCMD_RING_TYPE_ISCSI_DEFQ (4) /* Ring created with */ ++ /* FWCMD_COMMON_ISCSI_DEFQ_CREATE. */ ++#define FWCMD_RING_TYPE_TPM_WRBQ (5) /* Ring created with */ ++ /* FWCMD_COMMON_TPM_WRBQ_CREATE. */ ++#define FWCMD_RING_TYPE_TPM_DEFQ (6) /* Ring created with */ ++ /* FWCMD_COMMONTPM_TDEFQ_CREATE. */ ++#define FWCMD_RING_TYPE_TPM_RQ (7) /* Ring created with */ ++ /* FWCMD_COMMON_TPM_RQ_CREATE. */ ++#define FWCMD_RING_TYPE_MCC (8) /* Ring created with */ ++ /* FWCMD_COMMON_MCC_CREATE. */ ++#define FWCMD_RING_TYPE_CQ (9) /* Ring created with */ ++ /* FWCMD_COMMON_CQ_CREATE. */ ++#define FWCMD_RING_TYPE_EQ (10) /* Ring created with */ ++ /* FWCMD_COMMON_EQ_CREATE. */ ++#define FWCMD_RING_TYPE_QP (11) /* Ring created with */ ++ /* FWCMD_RDMA_QP_CREATE. */ ++ ++ ++/* --- ETH_TX_RING_TYPE_ENUM --- */ ++#define ETH_TX_RING_TYPE_FORWARDING (1) /* Ethernet ring for ++ forwarding packets */ ++#define ETH_TX_RING_TYPE_STANDARD (2) /* Ethernet ring for sending ++ network packets. */ ++#define ETH_TX_RING_TYPE_BOUND (3) /* Ethernet ring bound to the ++ port specified in the command ++ header.port_number field. ++ Rings of this type are ++ NOT subject to the ++ failover logic implemented ++ in the BladeEngine. ++ */ ++ ++/* --- FWCMD_COMMON_QOS_TYPE_ENUM --- */ ++#define QOS_BITS_NIC (1) /* max_bits_per_second_NIC */ ++ /* field is valid. */ ++#define QOS_PKTS_NIC (2) /* max_packets_per_second_NIC */ ++ /* field is valid. */ ++#define QOS_IOPS_ISCSI (4) /* max_ios_per_second_iSCSI */ ++ /*field is valid. */ ++#define QOS_VLAN_TAG (8) /* domain_VLAN_tag field ++ is valid. */ ++#define QOS_FABRIC_ID (16) /* fabric_domain_ID field ++ is valid. */ ++#define QOS_OEM_PARAMS (32) /* qos_params_oem field ++ is valid. */ ++#define QOS_TPUT_ISCSI (64) /* max_bytes_per_second_iSCSI ++ field is valid. */ ++ ++ ++/* ++ * --- FAILOVER_CONFIG_ENUM --- ++ * Failover configuration setting used in FWCMD_COMMON_FORCE_FAILOVER ++ */ ++#define FAILOVER_CONFIG_NO_CHANGE (0) /* No change to automatic */ ++ /* port failover setting. */ ++#define FAILOVER_CONFIG_ON (1) /* Automatic port failover ++ on link down is enabled. */ ++#define FAILOVER_CONFIG_OFF (2) /* Automatic port failover ++ on link down is disabled. */ ++ ++/* ++ * --- FAILOVER_PORT_ENUM --- ++ * Failover port setting used in FWCMD_COMMON_FORCE_FAILOVER ++ */ ++#define FAILOVER_PORT_A (0) /* Selects port A. */ ++#define FAILOVER_PORT_B (1) /* Selects port B. */ ++#define FAILOVER_PORT_NONE (15) /* No port change requested. */ ++ ++ ++/* ++ * --- MGMT_FLASHROM_OPCODE --- ++ * Flash ROM operation code ++ */ ++#define MGMT_FLASHROM_OPCODE_FLASH (1) /* Commit downloaded data ++ to Flash ROM */ ++#define MGMT_FLASHROM_OPCODE_SAVE (2) /* Save downloaded data to ++ ARM's DDR - do not flash */ ++#define MGMT_FLASHROM_OPCODE_CLEAR (3) /* Erase specified component ++ from FlashROM */ ++#define MGMT_FLASHROM_OPCODE_REPORT (4) /* Read specified component ++ from Flash ROM */ ++#define MGMT_FLASHROM_OPCODE_IMAGE_INFO (5) /* Returns size of a ++ component */ ++ ++/* ++ * --- MGMT_FLASHROM_OPTYPE --- ++ * Flash ROM operation type ++ */ ++#define MGMT_FLASHROM_OPTYPE_CODE_FIRMWARE (0) /* Includes ARM firmware, ++ IPSec (optional) and EP ++ firmware */ ++#define MGMT_FLASHROM_OPTYPE_CODE_REDBOOT (1) ++#define MGMT_FLASHROM_OPTYPE_CODE_BIOS (2) ++#define MGMT_FLASHROM_OPTYPE_CODE_PXE_BIOS (3) ++#define MGMT_FLASHROM_OPTYPE_CODE_CTRLS (4) ++#define MGMT_FLASHROM_OPTYPE_CFG_IPSEC (5) ++#define MGMT_FLASHROM_OPTYPE_CFG_INI (6) ++#define MGMT_FLASHROM_OPTYPE_ROM_OFFSET_SPECIFIED (7) ++ ++/* ++ * --- FLASHROM_TYPE --- ++ * Flash ROM manufacturers supported in the f/w ++ */ ++#define INTEL (0) ++#define SPANSION (1) ++#define MICRON (2) ++ ++/* --- DDR_CAS_TYPE --- */ ++#define CAS_3 (0) ++#define CAS_4 (1) ++#define CAS_5 (2) ++ ++/* --- DDR_SIZE_TYPE --- */ ++#define SIZE_256MB (0) ++#define SIZE_512MB (1) ++ ++/* --- DDR_MODE_TYPE --- */ ++#define DDR_NO_ECC (0) ++#define DDR_ECC (1) ++ ++/* --- INTERFACE_10GB_TYPE --- */ ++#define CX4_TYPE (0) ++#define XFP_TYPE (1) ++ ++/* --- BE_CHIP_MAX_MTU --- */ ++#define CHIP_MAX_MTU (9000) ++ ++/* --- XAUI_STATE_ENUM --- */ ++#define XAUI_STATE_ENABLE (0) /* This MUST be the default ++ value for all requests ++ which set/change ++ equalization parameter. */ ++#define XAUI_STATE_DISABLE (255) /* The XAUI for both ports ++ may be disabled for EMI ++ tests. There is no ++ provision for turning off ++ individual ports. ++ */ ++/* --- BE_ASIC_REVISION --- */ ++#define BE_ASIC_REV_A0 (1) ++#define BE_ASIC_REV_A1 (2) ++ ++#endif /* __fwcmd_common_amap_h__ */ +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/drivers/staging/benet/fwcmd_eth_bmap.h linux-2.6.29-rc3.owrt/drivers/staging/benet/fwcmd_eth_bmap.h +--- linux-2.6.29.owrt/drivers/staging/benet/fwcmd_eth_bmap.h 1970-01-01 01:00:00.000000000 +0100 ++++ linux-2.6.29-rc3.owrt/drivers/staging/benet/fwcmd_eth_bmap.h 2009-05-10 23:48:29.000000000 +0200 +@@ -0,0 +1,280 @@ ++/* ++ * Copyright (C) 2005 - 2008 ServerEngines ++ * All rights reserved. ++ * ++ * 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. The full GNU General ++ * Public License is included in this distribution in the file called COPYING. ++ * ++ * Contact Information: ++ * linux-drivers@serverengines.com ++ * ++ * ServerEngines ++ * 209 N. Fair Oaks Ave ++ * Sunnyvale, CA 94085 ++ */ ++/* ++ * Autogenerated by srcgen version: 0127 ++ */ ++#ifndef __fwcmd_eth_bmap_h__ ++#define __fwcmd_eth_bmap_h__ ++#include "fwcmd_hdr_bmap.h" ++#include "fwcmd_types_bmap.h" ++ ++struct MIB_ETH_STATISTICS_PARAMS_IN { ++ u32 rsvd0; ++} __packed; ++ ++struct BE_RXF_STATS { ++ u32 p0recvdtotalbytesLSD; /* DWORD 0 */ ++ u32 p0recvdtotalbytesMSD; /* DWORD 1 */ ++ u32 p0recvdtotalframes; /* DWORD 2 */ ++ u32 p0recvdunicastframes; /* DWORD 3 */ ++ u32 p0recvdmulticastframes; /* DWORD 4 */ ++ u32 p0recvdbroadcastframes; /* DWORD 5 */ ++ u32 p0crcerrors; /* DWORD 6 */ ++ u32 p0alignmentsymerrs; /* DWORD 7 */ ++ u32 p0pauseframesrecvd; /* DWORD 8 */ ++ u32 p0controlframesrecvd; /* DWORD 9 */ ++ u32 p0inrangelenerrors; /* DWORD 10 */ ++ u32 p0outrangeerrors; /* DWORD 11 */ ++ u32 p0frametoolongerrors; /* DWORD 12 */ ++ u32 p0droppedaddressmatch; /* DWORD 13 */ ++ u32 p0droppedvlanmismatch; /* DWORD 14 */ ++ u32 p0ipdroppedtoosmall; /* DWORD 15 */ ++ u32 p0ipdroppedtooshort; /* DWORD 16 */ ++ u32 p0ipdroppedhdrtoosmall; /* DWORD 17 */ ++ u32 p0tcpdroppedlen; /* DWORD 18 */ ++ u32 p0droppedrunt; /* DWORD 19 */ ++ u32 p0recvd64; /* DWORD 20 */ ++ u32 p0recvd65_127; /* DWORD 21 */ ++ u32 p0recvd128_256; /* DWORD 22 */ ++ u32 p0recvd256_511; /* DWORD 23 */ ++ u32 p0recvd512_1023; /* DWORD 24 */ ++ u32 p0recvd1518_1522; /* DWORD 25 */ ++ u32 p0recvd1522_2047; /* DWORD 26 */ ++ u32 p0recvd2048_4095; /* DWORD 27 */ ++ u32 p0recvd4096_8191; /* DWORD 28 */ ++ u32 p0recvd8192_9216; /* DWORD 29 */ ++ u32 p0rcvdipcksmerrs; /* DWORD 30 */ ++ u32 p0recvdtcpcksmerrs; /* DWORD 31 */ ++ u32 p0recvdudpcksmerrs; /* DWORD 32 */ ++ u32 p0recvdnonrsspackets; /* DWORD 33 */ ++ u32 p0recvdippackets; /* DWORD 34 */ ++ u32 p0recvdchute1packets; /* DWORD 35 */ ++ u32 p0recvdchute2packets; /* DWORD 36 */ ++ u32 p0recvdchute3packets; /* DWORD 37 */ ++ u32 p0recvdipsecpackets; /* DWORD 38 */ ++ u32 p0recvdmanagementpackets; /* DWORD 39 */ ++ u32 p0xmitbyteslsd; /* DWORD 40 */ ++ u32 p0xmitbytesmsd; /* DWORD 41 */ ++ u32 p0xmitunicastframes; /* DWORD 42 */ ++ u32 p0xmitmulticastframes; /* DWORD 43 */ ++ u32 p0xmitbroadcastframes; /* DWORD 44 */ ++ u32 p0xmitpauseframes; /* DWORD 45 */ ++ u32 p0xmitcontrolframes; /* DWORD 46 */ ++ u32 p0xmit64; /* DWORD 47 */ ++ u32 p0xmit65_127; /* DWORD 48 */ ++ u32 p0xmit128_256; /* DWORD 49 */ ++ u32 p0xmit256_511; /* DWORD 50 */ ++ u32 p0xmit512_1023; /* DWORD 51 */ ++ u32 p0xmit1518_1522; /* DWORD 52 */ ++ u32 p0xmit1522_2047; /* DWORD 53 */ ++ u32 p0xmit2048_4095; /* DWORD 54 */ ++ u32 p0xmit4096_8191; /* DWORD 55 */ ++ u32 p0xmit8192_9216; /* DWORD 56 */ ++ u32 p0rxfifooverflowdropped; /* DWORD 57 */ ++ u32 p0ipseclookupfaileddropped; /* DWORD 58 */ ++ u32 p1recvdtotalbytesLSD; /* DWORD 59 */ ++ u32 p1recvdtotalbytesMSD; /* DWORD 60 */ ++ u32 p1recvdtotalframes; /* DWORD 61 */ ++ u32 p1recvdunicastframes; /* DWORD 62 */ ++ u32 p1recvdmulticastframes; /* DWORD 63 */ ++ u32 p1recvdbroadcastframes; /* DWORD 64 */ ++ u32 p1crcerrors; /* DWORD 65 */ ++ u32 p1alignmentsymerrs; /* DWORD 66 */ ++ u32 p1pauseframesrecvd; /* DWORD 67 */ ++ u32 p1controlframesrecvd; /* DWORD 68 */ ++ u32 p1inrangelenerrors; /* DWORD 69 */ ++ u32 p1outrangeerrors; /* DWORD 70 */ ++ u32 p1frametoolongerrors; /* DWORD 71 */ ++ u32 p1droppedaddressmatch; /* DWORD 72 */ ++ u32 p1droppedvlanmismatch; /* DWORD 73 */ ++ u32 p1ipdroppedtoosmall; /* DWORD 74 */ ++ u32 p1ipdroppedtooshort; /* DWORD 75 */ ++ u32 p1ipdroppedhdrtoosmall; /* DWORD 76 */ ++ u32 p1tcpdroppedlen; /* DWORD 77 */ ++ u32 p1droppedrunt; /* DWORD 78 */ ++ u32 p1recvd64; /* DWORD 79 */ ++ u32 p1recvd65_127; /* DWORD 80 */ ++ u32 p1recvd128_256; /* DWORD 81 */ ++ u32 p1recvd256_511; /* DWORD 82 */ ++ u32 p1recvd512_1023; /* DWORD 83 */ ++ u32 p1recvd1518_1522; /* DWORD 84 */ ++ u32 p1recvd1522_2047; /* DWORD 85 */ ++ u32 p1recvd2048_4095; /* DWORD 86 */ ++ u32 p1recvd4096_8191; /* DWORD 87 */ ++ u32 p1recvd8192_9216; /* DWORD 88 */ ++ u32 p1rcvdipcksmerrs; /* DWORD 89 */ ++ u32 p1recvdtcpcksmerrs; /* DWORD 90 */ ++ u32 p1recvdudpcksmerrs; /* DWORD 91 */ ++ u32 p1recvdnonrsspackets; /* DWORD 92 */ ++ u32 p1recvdippackets; /* DWORD 93 */ ++ u32 p1recvdchute1packets; /* DWORD 94 */ ++ u32 p1recvdchute2packets; /* DWORD 95 */ ++ u32 p1recvdchute3packets; /* DWORD 96 */ ++ u32 p1recvdipsecpackets; /* DWORD 97 */ ++ u32 p1recvdmanagementpackets; /* DWORD 98 */ ++ u32 p1xmitbyteslsd; /* DWORD 99 */ ++ u32 p1xmitbytesmsd; /* DWORD 100 */ ++ u32 p1xmitunicastframes; /* DWORD 101 */ ++ u32 p1xmitmulticastframes; /* DWORD 102 */ ++ u32 p1xmitbroadcastframes; /* DWORD 103 */ ++ u32 p1xmitpauseframes; /* DWORD 104 */ ++ u32 p1xmitcontrolframes; /* DWORD 105 */ ++ u32 p1xmit64; /* DWORD 106 */ ++ u32 p1xmit65_127; /* DWORD 107 */ ++ u32 p1xmit128_256; /* DWORD 108 */ ++ u32 p1xmit256_511; /* DWORD 109 */ ++ u32 p1xmit512_1023; /* DWORD 110 */ ++ u32 p1xmit1518_1522; /* DWORD 111 */ ++ u32 p1xmit1522_2047; /* DWORD 112 */ ++ u32 p1xmit2048_4095; /* DWORD 113 */ ++ u32 p1xmit4096_8191; /* DWORD 114 */ ++ u32 p1xmit8192_9216; /* DWORD 115 */ ++ u32 p1rxfifooverflowdropped; /* DWORD 116 */ ++ u32 p1ipseclookupfaileddropped; /* DWORD 117 */ ++ u32 pxdroppednopbuf; /* DWORD 118 */ ++ u32 pxdroppednotxpb; /* DWORD 119 */ ++ u32 pxdroppednoipsecbuf; /* DWORD 120 */ ++ u32 pxdroppednoerxdescr; /* DWORD 121 */ ++ u32 pxdroppednotpredescr; /* DWORD 122 */ ++ u32 pxrecvdmanagementportpackets; /* DWORD 123 */ ++ u32 pxrecvdmanagementportbytes; /* DWORD 124 */ ++ u32 pxrecvdmanagementportpauseframes; /* DWORD 125 */ ++ u32 pxrecvdmanagementporterrors; /* DWORD 126 */ ++ u32 pxxmitmanagementportpackets; /* DWORD 127 */ ++ u32 pxxmitmanagementportbytes; /* DWORD 128 */ ++ u32 pxxmitmanagementportpause; /* DWORD 129 */ ++ u32 pxxmitmanagementportrxfifooverflow; /* DWORD 130 */ ++ u32 pxrecvdipsecipcksmerrs; /* DWORD 131 */ ++ u32 pxrecvdtcpsecipcksmerrs; /* DWORD 132 */ ++ u32 pxrecvdudpsecipcksmerrs; /* DWORD 133 */ ++ u32 pxipsecrunt; /* DWORD 134 */ ++ u32 pxipsecaddressmismatchdropped; /* DWORD 135 */ ++ u32 pxipsecrxfifooverflowdropped; /* DWORD 136 */ ++ u32 pxipsecframestoolong; /* DWORD 137 */ ++ u32 pxipsectotalipframes; /* DWORD 138 */ ++ u32 pxipseciptoosmall; /* DWORD 139 */ ++ u32 pxipseciptooshort; /* DWORD 140 */ ++ u32 pxipseciphdrtoosmall; /* DWORD 141 */ ++ u32 pxipsectcphdrbad; /* DWORD 142 */ ++ u32 pxrecvdipsecchute1; /* DWORD 143 */ ++ u32 pxrecvdipsecchute2; /* DWORD 144 */ ++ u32 pxrecvdipsecchute3; /* DWORD 145 */ ++ u32 pxdropped7frags; /* DWORD 146 */ ++ u32 pxdroppedfrags; /* DWORD 147 */ ++ u32 pxdroppedinvalidfragring; /* DWORD 148 */ ++ u32 pxnumforwardedpackets; /* DWORD 149 */ ++} __packed; ++ ++union MIB_ETH_STATISTICS_PARAMS { ++ struct MIB_ETH_STATISTICS_PARAMS_IN request; ++ struct BE_RXF_STATS response; ++} __packed; ++ ++/* ++ * Query ethernet statistics. All domains may issue this command. The ++ * host domain drivers may optionally reset internal statistic counters ++ * with a query. ++ */ ++struct FWCMD_ETH_GET_STATISTICS { ++ union FWCMD_HEADER header; ++ union MIB_ETH_STATISTICS_PARAMS params; ++} __packed; ++ ++ ++struct FWCMD_ETH_ANON_175_REQUEST { ++ u8 port0_promiscuous; ++ u8 port1_promiscuous; ++ u16 rsvd0; ++} __packed; ++ ++struct FWCMD_ETH_ANON_176_RESPONSE { ++ u32 rsvd0; ++} __packed; ++ ++union FWCMD_ETH_ANON_174_PARAMS { ++ struct FWCMD_ETH_ANON_175_REQUEST request; ++ struct FWCMD_ETH_ANON_176_RESPONSE response; ++} __packed; ++ ++/* Enables/Disables promiscuous ethernet receive mode. */ ++struct FWCMD_ETH_PROMISCUOUS { ++ union FWCMD_HEADER header; ++ union FWCMD_ETH_ANON_174_PARAMS params; ++} __packed; ++ ++struct FWCMD_ETH_ANON_178_REQUEST { ++ u32 new_fragsize_log2; ++} __packed; ++ ++struct FWCMD_ETH_ANON_179_RESPONSE { ++ u32 actual_fragsize_log2; ++} __packed; ++ ++union FWCMD_ETH_ANON_177_PARAMS { ++ struct FWCMD_ETH_ANON_178_REQUEST request; ++ struct FWCMD_ETH_ANON_179_RESPONSE response; ++} __packed; ++ ++/* ++ * Sets the Ethernet RX fragment size. Only host (domain 0) networking ++ * drivers may issue this command. This call will fail for non-host ++ * protection domains. In this situation the MCC CQ status will indicate ++ * a failure due to insufficient priviledges. The response should be ++ * ignored, and the driver should use the FWCMD_ETH_GET_FRAG_SIZE to ++ * query the existing ethernet receive fragment size. It must use this ++ * fragment size for all fragments in the ethernet receive ring. If ++ * the command succeeds, the driver must use the frag size indicated ++ * in the command response since the requested frag size may not be applied ++ * until the next reboot. When the requested fragsize matches the response ++ * fragsize, this indicates the request was applied immediately. ++ */ ++struct FWCMD_ETH_SET_RX_FRAG_SIZE { ++ union FWCMD_HEADER header; ++ union FWCMD_ETH_ANON_177_PARAMS params; ++} __packed; ++ ++struct FWCMD_ETH_ANON_181_REQUEST { ++ u32 rsvd0; ++} __packed; ++ ++struct FWCMD_ETH_ANON_182_RESPONSE { ++ u32 actual_fragsize_log2; ++} __packed; ++ ++union FWCMD_ETH_ANON_180_PARAMS { ++ struct FWCMD_ETH_ANON_181_REQUEST request; ++ struct FWCMD_ETH_ANON_182_RESPONSE response; ++} __packed; ++ ++/* ++ * Queries the Ethernet RX fragment size. All domains may issue this ++ * command. The driver should call this command to determine the minimum ++ * required fragment size for the ethernet RX ring buffers. Drivers ++ * may choose to use a larger size for each fragment buffer, but BladeEngine ++ * will use up to the configured minimum required fragsize in each ethernet ++ * receive fragment buffer. For example, if the ethernet receive fragment ++ * size is configured to 4kB, and a driver uses 8kB fragments, a 6kB ++ * ethernet packet received by BladeEngine will be split accross two ++ * of the driver's receive framgents (4kB in one fragment buffer, and ++ * 2kB in the subsequent fragment buffer). ++ */ ++struct FWCMD_ETH_GET_RX_FRAG_SIZE { ++ union FWCMD_HEADER header; ++ union FWCMD_ETH_ANON_180_PARAMS params; ++} __packed; ++ ++#endif /* __fwcmd_eth_bmap_h__ */ +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/drivers/staging/benet/fwcmd_hdr_bmap.h linux-2.6.29-rc3.owrt/drivers/staging/benet/fwcmd_hdr_bmap.h +--- linux-2.6.29.owrt/drivers/staging/benet/fwcmd_hdr_bmap.h 1970-01-01 01:00:00.000000000 +0100 ++++ linux-2.6.29-rc3.owrt/drivers/staging/benet/fwcmd_hdr_bmap.h 2009-05-10 23:48:29.000000000 +0200 +@@ -0,0 +1,54 @@ ++/* ++ * Copyright (C) 2005 - 2008 ServerEngines ++ * All rights reserved. ++ * ++ * 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. The full GNU General ++ * Public License is included in this distribution in the file called COPYING. ++ * ++ * Contact Information: ++ * linux-drivers@serverengines.com ++ * ++ * ServerEngines ++ * 209 N. Fair Oaks Ave ++ * Sunnyvale, CA 94085 ++ */ ++/* ++ * Autogenerated by srcgen version: 0127 ++ */ ++#ifndef __fwcmd_hdr_bmap_h__ ++#define __fwcmd_hdr_bmap_h__ ++ ++struct FWCMD_REQUEST_HEADER { ++ u8 opcode; ++ u8 subsystem; ++ u8 port_number; ++ u8 domain; ++ u32 timeout; ++ u32 request_length; ++ u32 rsvd0; ++} __packed; ++ ++struct FWCMD_RESPONSE_HEADER { ++ u8 opcode; ++ u8 subsystem; ++ u8 rsvd0; ++ u8 domain; ++ u8 status; ++ u8 additional_status; ++ u16 rsvd1; ++ u32 response_length; ++ u32 actual_response_length; ++} __packed; ++ ++/* ++ * The firmware/driver overwrites the input FWCMD_REQUEST_HEADER with ++ * the output FWCMD_RESPONSE_HEADER. ++ */ ++union FWCMD_HEADER { ++ struct FWCMD_REQUEST_HEADER request; ++ struct FWCMD_RESPONSE_HEADER response; ++} __packed; ++ ++#endif /* __fwcmd_hdr_bmap_h__ */ +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/drivers/staging/benet/fwcmd_mcc.h linux-2.6.29-rc3.owrt/drivers/staging/benet/fwcmd_mcc.h +--- linux-2.6.29.owrt/drivers/staging/benet/fwcmd_mcc.h 1970-01-01 01:00:00.000000000 +0100 ++++ linux-2.6.29-rc3.owrt/drivers/staging/benet/fwcmd_mcc.h 2009-05-10 23:48:29.000000000 +0200 +@@ -0,0 +1,94 @@ ++/* ++ * Copyright (C) 2005 - 2008 ServerEngines ++ * All rights reserved. ++ * ++ * 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. The full GNU General ++ * Public License is included in this distribution in the file called COPYING. ++ * ++ * Contact Information: ++ * linux-drivers@serverengines.com ++ * ++ * ServerEngines ++ * 209 N. Fair Oaks Ave ++ * Sunnyvale, CA 94085 ++ */ ++/* ++ * Autogenerated by srcgen version: 0127 ++ */ ++#ifndef __fwcmd_mcc_amap_h__ ++#define __fwcmd_mcc_amap_h__ ++#include "fwcmd_opcodes.h" ++/* ++ * Where applicable, a WRB, may contain a list of Scatter-gather elements. ++ * Each element supports a 64 bit address and a 32bit length field. ++ */ ++struct BE_MCC_SGE_AMAP { ++ u8 pa_lo[32]; /* DWORD 0 */ ++ u8 pa_hi[32]; /* DWORD 1 */ ++ u8 length[32]; /* DWORD 2 */ ++} __packed; ++struct MCC_SGE_AMAP { ++ u32 dw[3]; ++}; ++/* ++ * The design of an MCC_SGE allows up to 19 elements to be embedded ++ * in a WRB, supporting 64KB data transfers (assuming a 4KB page size). ++ */ ++struct BE_MCC_WRB_PAYLOAD_AMAP { ++ union { ++ struct BE_MCC_SGE_AMAP sgl[19]; ++ u8 embedded[59][32]; /* DWORD 0 */ ++ }; ++} __packed; ++struct MCC_WRB_PAYLOAD_AMAP { ++ u32 dw[59]; ++}; ++ ++/* ++ * This is the structure of the MCC Command WRB for commands ++ * sent to the Management Processing Unit (MPU). See section ++ * for usage in embedded and non-embedded modes. ++ */ ++struct BE_MCC_WRB_AMAP { ++ u8 embedded; /* DWORD 0 */ ++ u8 rsvd0[2]; /* DWORD 0 */ ++ u8 sge_count[5]; /* DWORD 0 */ ++ u8 rsvd1[16]; /* DWORD 0 */ ++ u8 special[8]; /* DWORD 0 */ ++ u8 payload_length[32]; /* DWORD 1 */ ++ u8 tag[2][32]; /* DWORD 2 */ ++ u8 rsvd2[32]; /* DWORD 4 */ ++ struct BE_MCC_WRB_PAYLOAD_AMAP payload; ++} __packed; ++struct MCC_WRB_AMAP { ++ u32 dw[64]; ++}; ++ ++/* This is the structure of the MCC Completion queue entry */ ++struct BE_MCC_CQ_ENTRY_AMAP { ++ u8 completion_status[16]; /* DWORD 0 */ ++ u8 extended_status[16]; /* DWORD 0 */ ++ u8 mcc_tag[2][32]; /* DWORD 1 */ ++ u8 rsvd0[27]; /* DWORD 3 */ ++ u8 consumed; /* DWORD 3 */ ++ u8 completed; /* DWORD 3 */ ++ u8 hpi_buffer_completion; /* DWORD 3 */ ++ u8 async_event; /* DWORD 3 */ ++ u8 valid; /* DWORD 3 */ ++} __packed; ++struct MCC_CQ_ENTRY_AMAP { ++ u32 dw[4]; ++}; ++ ++/* Mailbox structures used by the MPU during bootstrap */ ++struct BE_MCC_MAILBOX_AMAP { ++ struct BE_MCC_WRB_AMAP wrb; ++ struct BE_MCC_CQ_ENTRY_AMAP cq; ++} __packed; ++struct MCC_MAILBOX_AMAP { ++ u32 dw[68]; ++}; ++ ++#endif /* __fwcmd_mcc_amap_h__ */ +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/drivers/staging/benet/fwcmd_opcodes.h linux-2.6.29-rc3.owrt/drivers/staging/benet/fwcmd_opcodes.h +--- linux-2.6.29.owrt/drivers/staging/benet/fwcmd_opcodes.h 1970-01-01 01:00:00.000000000 +0100 ++++ linux-2.6.29-rc3.owrt/drivers/staging/benet/fwcmd_opcodes.h 2009-05-10 23:48:29.000000000 +0200 +@@ -0,0 +1,244 @@ ++/* ++ * Copyright (C) 2005 - 2008 ServerEngines ++ * All rights reserved. ++ * ++ * 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. The full GNU General ++ * Public License is included in this distribution in the file called COPYING. ++ * ++ * Contact Information: ++ * linux-drivers@serverengines.com ++ * ++ * ServerEngines ++ * 209 N. Fair Oaks Ave ++ * Sunnyvale, CA 94085 ++ */ ++/* ++ * Autogenerated by srcgen version: 0127 ++ */ ++#ifndef __fwcmd_opcodes_amap_h__ ++#define __fwcmd_opcodes_amap_h__ ++ ++/* ++ * --- FWCMD_SUBSYSTEMS --- ++ * The commands are grouped into the following subsystems. The subsystem ++ * code along with the opcode uniquely identify a particular fwcmd. ++ */ ++#define FWCMD_SUBSYSTEM_RSVD (0) /* This subsystem is reserved. It is */ ++ /* never used. */ ++#define FWCMD_SUBSYSTEM_COMMON (1) /* CMDs in this group are common to ++ * all subsystems. See ++ * COMMON_SUBSYSTEM_OPCODES for opcodes ++ * and Common Host Configuration CMDs ++ * for the FWCMD descriptions. ++ */ ++#define FWCMD_SUBSYSTEM_COMMON_ISCSI (2) /* CMDs in this group are */ ++ /* ++ * common to Initiator and Target. See ++ * COMMON_ISCSI_SUBSYSTEM_OPCODES and ++ * Common iSCSI Initiator and Target ++ * CMDs for the command descriptions. ++ */ ++#define FWCMD_SUBSYSTEM_ETH (3) /* This subsystem is used to ++ execute Ethernet commands. */ ++ ++#define FWCMD_SUBSYSTEM_TPM (4) /* This subsystem is used ++ to execute TPM commands. */ ++#define FWCMD_SUBSYSTEM_PXE_UNDI (5) /* This subsystem is used ++ * to execute PXE ++ * and UNDI specific commands. ++ */ ++ ++#define FWCMD_SUBSYSTEM_ISCSI_INI (6) /* This subsystem is used to ++ execute ISCSI Initiator ++ specific commands. ++ */ ++#define FWCMD_SUBSYSTEM_ISCSI_TGT (7) /* This subsystem is used ++ to execute iSCSI Target ++ specific commands.between ++ PTL and ARM firmware. ++ */ ++#define FWCMD_SUBSYSTEM_MILI_PTL (8) /* This subsystem is used to ++ execute iSCSI Target specific ++ commands.between MILI ++ and PTL. */ ++#define FWCMD_SUBSYSTEM_MILI_TMD (9) /* This subsystem is used to ++ execute iSCSI Target specific ++ commands between MILI ++ and TMD. */ ++#define FWCMD_SUBSYSTEM_PROXY (11) /* This subsystem is used ++ to execute proxied commands ++ within the host at the ++ explicit request of a ++ non priviledged domain. ++ This 'subsystem' is entirely ++ virtual from the controller ++ and firmware perspective as ++ it is implemented in host ++ drivers. ++ */ ++ ++/* ++ * --- COMMON_SUBSYSTEM_OPCODES --- ++ * These opcodes are common to both networking and storage PCI ++ * functions. They are used to reserve resources and configure ++ * BladeEngine. These opcodes all use the FWCMD_SUBSYSTEM_COMMON ++ * subsystem code. ++ */ ++#define OPCODE_COMMON_NTWK_MAC_QUERY (1) ++#define SUBSYSTEM_COMMON_NTWK_MAC_QUERY (1) ++#define SUBSYSTEM_COMMON_NTWK_MAC_SET (1) ++#define SUBSYSTEM_COMMON_NTWK_MULTICAST_SET (1) ++#define SUBSYSTEM_COMMON_NTWK_VLAN_CONFIG (1) ++#define SUBSYSTEM_COMMON_NTWK_LINK_STATUS_QUERY (1) ++#define SUBSYSTEM_COMMON_READ_FLASHROM (1) ++#define SUBSYSTEM_COMMON_WRITE_FLASHROM (1) ++#define SUBSYSTEM_COMMON_QUERY_MAX_FWCMD_BUFFER_SIZE (1) ++#define SUBSYSTEM_COMMON_ADD_PAGE_TABLES (1) ++#define SUBSYSTEM_COMMON_REMOVE_PAGE_TABLES (1) ++#define SUBSYSTEM_COMMON_RING_DESTROY (1) ++#define SUBSYSTEM_COMMON_CQ_CREATE (1) ++#define SUBSYSTEM_COMMON_EQ_CREATE (1) ++#define SUBSYSTEM_COMMON_ETH_RX_CREATE (1) ++#define SUBSYSTEM_COMMON_ETH_TX_CREATE (1) ++#define SUBSYSTEM_COMMON_ISCSI_DEFQ_CREATE (1) ++#define SUBSYSTEM_COMMON_ISCSI_WRBQ_CREATE (1) ++#define SUBSYSTEM_COMMON_MCC_CREATE (1) ++#define SUBSYSTEM_COMMON_JELL_CONFIG (1) ++#define SUBSYSTEM_COMMON_FORCE_FAILOVER (1) ++#define SUBSYSTEM_COMMON_ADD_TEMPLATE_HEADER_BUFFERS (1) ++#define SUBSYSTEM_COMMON_REMOVE_TEMPLATE_HEADER_BUFFERS (1) ++#define SUBSYSTEM_COMMON_POST_ZERO_BUFFER (1) ++#define SUBSYSTEM_COMMON_GET_QOS (1) ++#define SUBSYSTEM_COMMON_SET_QOS (1) ++#define SUBSYSTEM_COMMON_TCP_GET_STATISTICS (1) ++#define SUBSYSTEM_COMMON_SEEPROM_READ (1) ++#define SUBSYSTEM_COMMON_TCP_STATE_QUERY (1) ++#define SUBSYSTEM_COMMON_GET_CNTL_ATTRIBUTES (1) ++#define SUBSYSTEM_COMMON_NOP (1) ++#define SUBSYSTEM_COMMON_NTWK_RX_FILTER (1) ++#define SUBSYSTEM_COMMON_GET_FW_VERSION (1) ++#define SUBSYSTEM_COMMON_SET_FLOW_CONTROL (1) ++#define SUBSYSTEM_COMMON_GET_FLOW_CONTROL (1) ++#define SUBSYSTEM_COMMON_SET_TCP_PARAMETERS (1) ++#define SUBSYSTEM_COMMON_SET_FRAME_SIZE (1) ++#define SUBSYSTEM_COMMON_GET_FAT (1) ++#define SUBSYSTEM_COMMON_MODIFY_EQ_DELAY (1) ++#define SUBSYSTEM_COMMON_FIRMWARE_CONFIG (1) ++#define SUBSYSTEM_COMMON_ENABLE_DISABLE_DOMAINS (1) ++#define SUBSYSTEM_COMMON_GET_DOMAIN_CONFIG (1) ++#define SUBSYSTEM_COMMON_SET_VLD_CONFIG (1) ++#define SUBSYSTEM_COMMON_GET_VLD_CONFIG (1) ++#define SUBSYSTEM_COMMON_GET_PORT_EQUALIZATION (1) ++#define SUBSYSTEM_COMMON_SET_PORT_EQUALIZATION (1) ++#define SUBSYSTEM_COMMON_RED_CONFIG (1) ++#define OPCODE_COMMON_NTWK_MAC_SET (2) ++#define OPCODE_COMMON_NTWK_MULTICAST_SET (3) ++#define OPCODE_COMMON_NTWK_VLAN_CONFIG (4) ++#define OPCODE_COMMON_NTWK_LINK_STATUS_QUERY (5) ++#define OPCODE_COMMON_READ_FLASHROM (6) ++#define OPCODE_COMMON_WRITE_FLASHROM (7) ++#define OPCODE_COMMON_QUERY_MAX_FWCMD_BUFFER_SIZE (8) ++#define OPCODE_COMMON_ADD_PAGE_TABLES (9) ++#define OPCODE_COMMON_REMOVE_PAGE_TABLES (10) ++#define OPCODE_COMMON_RING_DESTROY (11) ++#define OPCODE_COMMON_CQ_CREATE (12) ++#define OPCODE_COMMON_EQ_CREATE (13) ++#define OPCODE_COMMON_ETH_RX_CREATE (14) ++#define OPCODE_COMMON_ETH_TX_CREATE (15) ++#define OPCODE_COMMON_NET_RESERVED0 (16) /* Reserved */ ++#define OPCODE_COMMON_NET_RESERVED1 (17) /* Reserved */ ++#define OPCODE_COMMON_NET_RESERVED2 (18) /* Reserved */ ++#define OPCODE_COMMON_ISCSI_DEFQ_CREATE (19) ++#define OPCODE_COMMON_ISCSI_WRBQ_CREATE (20) ++#define OPCODE_COMMON_MCC_CREATE (21) ++#define OPCODE_COMMON_JELL_CONFIG (22) ++#define OPCODE_COMMON_FORCE_FAILOVER (23) ++#define OPCODE_COMMON_ADD_TEMPLATE_HEADER_BUFFERS (24) ++#define OPCODE_COMMON_REMOVE_TEMPLATE_HEADER_BUFFERS (25) ++#define OPCODE_COMMON_POST_ZERO_BUFFER (26) ++#define OPCODE_COMMON_GET_QOS (27) ++#define OPCODE_COMMON_SET_QOS (28) ++#define OPCODE_COMMON_TCP_GET_STATISTICS (29) ++#define OPCODE_COMMON_SEEPROM_READ (30) ++#define OPCODE_COMMON_TCP_STATE_QUERY (31) ++#define OPCODE_COMMON_GET_CNTL_ATTRIBUTES (32) ++#define OPCODE_COMMON_NOP (33) ++#define OPCODE_COMMON_NTWK_RX_FILTER (34) ++#define OPCODE_COMMON_GET_FW_VERSION (35) ++#define OPCODE_COMMON_SET_FLOW_CONTROL (36) ++#define OPCODE_COMMON_GET_FLOW_CONTROL (37) ++#define OPCODE_COMMON_SET_TCP_PARAMETERS (38) ++#define OPCODE_COMMON_SET_FRAME_SIZE (39) ++#define OPCODE_COMMON_GET_FAT (40) ++#define OPCODE_COMMON_MODIFY_EQ_DELAY (41) ++#define OPCODE_COMMON_FIRMWARE_CONFIG (42) ++#define OPCODE_COMMON_ENABLE_DISABLE_DOMAINS (43) ++#define OPCODE_COMMON_GET_DOMAIN_CONFIG (44) ++#define OPCODE_COMMON_SET_VLD_CONFIG (45) ++#define OPCODE_COMMON_GET_VLD_CONFIG (46) ++#define OPCODE_COMMON_GET_PORT_EQUALIZATION (47) ++#define OPCODE_COMMON_SET_PORT_EQUALIZATION (48) ++#define OPCODE_COMMON_RED_CONFIG (49) ++ ++ ++ ++/* ++ * --- ETH_SUBSYSTEM_OPCODES --- ++ * These opcodes are used for configuring the Ethernet interfaces. These ++ * opcodes all use the FWCMD_SUBSYSTEM_ETH subsystem code. ++ */ ++#define OPCODE_ETH_RSS_CONFIG (1) ++#define OPCODE_ETH_ACPI_CONFIG (2) ++#define SUBSYSTEM_ETH_RSS_CONFIG (3) ++#define SUBSYSTEM_ETH_ACPI_CONFIG (3) ++#define OPCODE_ETH_PROMISCUOUS (3) ++#define SUBSYSTEM_ETH_PROMISCUOUS (3) ++#define SUBSYSTEM_ETH_GET_STATISTICS (3) ++#define SUBSYSTEM_ETH_GET_RX_FRAG_SIZE (3) ++#define SUBSYSTEM_ETH_SET_RX_FRAG_SIZE (3) ++#define OPCODE_ETH_GET_STATISTICS (4) ++#define OPCODE_ETH_GET_RX_FRAG_SIZE (5) ++#define OPCODE_ETH_SET_RX_FRAG_SIZE (6) ++ ++ ++ ++ ++ ++/* ++ * --- MCC_STATUS_CODE --- ++ * These are the global status codes used by all subsystems ++ */ ++#define MCC_STATUS_SUCCESS (0) /* Indicates a successful ++ completion of the command */ ++#define MCC_STATUS_INSUFFICIENT_PRIVILEGES (1) /* The client does not have ++ sufficient privileges to ++ execute the command */ ++#define MCC_STATUS_INVALID_PARAMETER (2) /* A parameter in the command ++ was invalid. The extended ++ status contains the index ++ of the parameter */ ++#define MCC_STATUS_INSUFFICIENT_RESOURCES (3) /* There are insufficient ++ chip resources to execute ++ the command */ ++#define MCC_STATUS_QUEUE_FLUSHING (4) /* The command is completing ++ because the queue was ++ getting flushed */ ++#define MCC_STATUS_DMA_FAILED (5) /* The command is completing ++ with a DMA error */ ++ ++/* ++ * --- MGMT_ERROR_CODES --- ++ * Error Codes returned in the status field of the FWCMD response header ++ */ ++#define MGMT_STATUS_SUCCESS (0) /* The FWCMD completed ++ without errors */ ++#define MGMT_STATUS_FAILED (1) /* Error status in the Status ++ field of the ++ struct FWCMD_RESPONSE_HEADER */ ++#define MGMT_STATUS_ILLEGAL_REQUEST (2) /* Invalid FWCMD opcode */ ++#define MGMT_STATUS_ILLEGAL_FIELD (3) /* Invalid parameter in ++ the FWCMD payload */ ++ ++#endif /* __fwcmd_opcodes_amap_h__ */ +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/drivers/staging/benet/fwcmd_types_bmap.h linux-2.6.29-rc3.owrt/drivers/staging/benet/fwcmd_types_bmap.h +--- linux-2.6.29.owrt/drivers/staging/benet/fwcmd_types_bmap.h 1970-01-01 01:00:00.000000000 +0100 ++++ linux-2.6.29-rc3.owrt/drivers/staging/benet/fwcmd_types_bmap.h 2009-05-10 23:48:29.000000000 +0200 +@@ -0,0 +1,29 @@ ++/* ++ * Copyright (C) 2005 - 2008 ServerEngines ++ * All rights reserved. ++ * ++ * 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. The full GNU General ++ * Public License is included in this distribution in the file called COPYING. ++ * ++ * Contact Information: ++ * linux-drivers@serverengines.com ++ * ++ * ServerEngines ++ * 209 N. Fair Oaks Ave ++ * Sunnyvale, CA 94085 ++ */ ++/* ++ * Autogenerated by srcgen version: 0127 ++ */ ++#ifndef __fwcmd_types_bmap_h__ ++#define __fwcmd_types_bmap_h__ ++ ++/* MAC address format */ ++struct MAC_ADDRESS_FORMAT { ++ u16 SizeOfStructure; ++ u8 MACAddress[6]; ++} __packed; ++ ++#endif /* __fwcmd_types_bmap_h__ */ +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/drivers/staging/benet/host_struct.h linux-2.6.29-rc3.owrt/drivers/staging/benet/host_struct.h +--- linux-2.6.29.owrt/drivers/staging/benet/host_struct.h 1970-01-01 01:00:00.000000000 +0100 ++++ linux-2.6.29-rc3.owrt/drivers/staging/benet/host_struct.h 2009-05-10 23:48:29.000000000 +0200 +@@ -0,0 +1,182 @@ ++/* ++ * Copyright (C) 2005 - 2008 ServerEngines ++ * All rights reserved. ++ * ++ * 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. The full GNU General ++ * Public License is included in this distribution in the file called COPYING. ++ * ++ * Contact Information: ++ * linux-drivers@serverengines.com ++ * ++ * ServerEngines ++ * 209 N. Fair Oaks Ave ++ * Sunnyvale, CA 94085 ++ */ ++/* ++ * Autogenerated by srcgen version: 0127 ++ */ ++#ifndef __host_struct_amap_h__ ++#define __host_struct_amap_h__ ++#include "be_cm.h" ++#include "be_common.h" ++#include "descriptors.h" ++ ++/* --- EQ_COMPLETION_MAJOR_CODE_ENUM --- */ ++#define EQ_MAJOR_CODE_COMPLETION (0) /* Completion event on a */ ++ /* qcompletion ueue. */ ++#define EQ_MAJOR_CODE_ETH (1) /* Affiliated Ethernet Event. */ ++#define EQ_MAJOR_CODE_RESERVED (2) /* Reserved */ ++#define EQ_MAJOR_CODE_RDMA (3) /* Affiliated RDMA Event. */ ++#define EQ_MAJOR_CODE_ISCSI (4) /* Affiliated ISCSI Event */ ++#define EQ_MAJOR_CODE_UNAFFILIATED (5) /* Unaffiliated Event */ ++ ++/* --- EQ_COMPLETION_MINOR_CODE_ENUM --- */ ++#define EQ_MINOR_CODE_COMPLETION (0) /* Completion event on a */ ++ /* completion queue. */ ++#define EQ_MINOR_CODE_OTHER (1) /* Other Event (TBD). */ ++ ++/* Queue Entry Definition for all 4 byte event queue types. */ ++struct BE_EQ_ENTRY_AMAP { ++ u8 Valid; /* DWORD 0 */ ++ u8 MajorCode[3]; /* DWORD 0 */ ++ u8 MinorCode[12]; /* DWORD 0 */ ++ u8 ResourceID[16]; /* DWORD 0 */ ++} __packed; ++struct EQ_ENTRY_AMAP { ++ u32 dw[1]; ++}; ++ ++/* ++ * --- ETH_EVENT_CODE --- ++ * These codes are returned by the MPU when one of these events has occurred, ++ * and the event is configured to report to an Event Queue when an event ++ * is detected. ++ */ ++#define ETH_EQ_LINK_STATUS (0) /* Link status change event */ ++ /* detected. */ ++#define ETH_EQ_WATERMARK (1) /* watermark event detected. */ ++#define ETH_EQ_MAGIC_PKT (2) /* magic pkt event detected. */ ++#define ETH_EQ_ACPI_PKT0 (3) /* ACPI interesting packet */ ++ /* detected. */ ++#define ETH_EQ_ACPI_PKT1 (3) /* ACPI interesting packet */ ++ /* detected. */ ++#define ETH_EQ_ACPI_PKT2 (3) /* ACPI interesting packet */ ++ /* detected. */ ++#define ETH_EQ_ACPI_PKT3 (3) /* ACPI interesting packet */ ++ /* detected. */ ++ ++/* ++ * --- ETH_TX_COMPL_STATUS_ENUM --- ++ * Status codes contained in Ethernet TX completion descriptors. ++ */ ++#define ETH_COMP_VALID (0) ++#define ETH_COMP_ERROR (1) ++#define ETH_COMP_INVALID (15) ++ ++/* ++ * --- ETH_TX_COMPL_PORT_ENUM --- ++ * Port indicator contained in Ethernet TX completion descriptors. ++ */ ++#define ETH_COMP_PORT0 (0) ++#define ETH_COMP_PORT1 (1) ++#define ETH_COMP_MGMT (2) ++ ++/* ++ * --- ETH_TX_COMPL_CT_ENUM --- ++ * Completion type indicator contained in Ethernet TX completion descriptors. ++ */ ++#define ETH_COMP_ETH (0) ++ ++/* ++ * Work request block that the driver issues to the chip for ++ * Ethernet transmissions. All control fields must be valid in each WRB for ++ * a message. The controller, as specified by the flags, optionally writes ++ * an entry to the Completion Ring and generate an event. ++ */ ++struct BE_ETH_WRB_AMAP { ++ u8 frag_pa_hi[32]; /* DWORD 0 */ ++ u8 frag_pa_lo[32]; /* DWORD 1 */ ++ u8 complete; /* DWORD 2 */ ++ u8 event; /* DWORD 2 */ ++ u8 crc; /* DWORD 2 */ ++ u8 forward; /* DWORD 2 */ ++ u8 ipsec; /* DWORD 2 */ ++ u8 mgmt; /* DWORD 2 */ ++ u8 ipcs; /* DWORD 2 */ ++ u8 udpcs; /* DWORD 2 */ ++ u8 tcpcs; /* DWORD 2 */ ++ u8 lso; /* DWORD 2 */ ++ u8 last; /* DWORD 2 */ ++ u8 vlan; /* DWORD 2 */ ++ u8 dbg[3]; /* DWORD 2 */ ++ u8 hash_val[3]; /* DWORD 2 */ ++ u8 lso_mss[14]; /* DWORD 2 */ ++ u8 frag_len[16]; /* DWORD 3 */ ++ u8 vlan_tag[16]; /* DWORD 3 */ ++} __packed; ++struct ETH_WRB_AMAP { ++ u32 dw[4]; ++}; ++ ++/* This is an Ethernet transmit completion descriptor */ ++struct BE_ETH_TX_COMPL_AMAP { ++ u8 user_bytes[16]; /* DWORD 0 */ ++ u8 nwh_bytes[8]; /* DWORD 0 */ ++ u8 lso; /* DWORD 0 */ ++ u8 rsvd0[7]; /* DWORD 0 */ ++ u8 wrb_index[16]; /* DWORD 1 */ ++ u8 ct[2]; /* DWORD 1 */ ++ u8 port[2]; /* DWORD 1 */ ++ u8 rsvd1[8]; /* DWORD 1 */ ++ u8 status[4]; /* DWORD 1 */ ++ u8 rsvd2[16]; /* DWORD 2 */ ++ u8 ringid[11]; /* DWORD 2 */ ++ u8 hash_val[4]; /* DWORD 2 */ ++ u8 valid; /* DWORD 2 */ ++ u8 rsvd3[32]; /* DWORD 3 */ ++} __packed; ++struct ETH_TX_COMPL_AMAP { ++ u32 dw[4]; ++}; ++ ++/* Ethernet Receive Buffer descriptor */ ++struct BE_ETH_RX_D_AMAP { ++ u8 fragpa_hi[32]; /* DWORD 0 */ ++ u8 fragpa_lo[32]; /* DWORD 1 */ ++} __packed; ++struct ETH_RX_D_AMAP { ++ u32 dw[2]; ++}; ++ ++/* This is an Ethernet Receive Completion Descriptor */ ++struct BE_ETH_RX_COMPL_AMAP { ++ u8 vlan_tag[16]; /* DWORD 0 */ ++ u8 pktsize[14]; /* DWORD 0 */ ++ u8 port; /* DWORD 0 */ ++ u8 rsvd0; /* DWORD 0 */ ++ u8 err; /* DWORD 1 */ ++ u8 rsshp; /* DWORD 1 */ ++ u8 ipf; /* DWORD 1 */ ++ u8 tcpf; /* DWORD 1 */ ++ u8 udpf; /* DWORD 1 */ ++ u8 ipcksm; /* DWORD 1 */ ++ u8 tcpcksm; /* DWORD 1 */ ++ u8 udpcksm; /* DWORD 1 */ ++ u8 macdst[6]; /* DWORD 1 */ ++ u8 vtp; /* DWORD 1 */ ++ u8 vtm; /* DWORD 1 */ ++ u8 fragndx[10]; /* DWORD 1 */ ++ u8 ct[2]; /* DWORD 1 */ ++ u8 ipsec; /* DWORD 1 */ ++ u8 numfrags[3]; /* DWORD 1 */ ++ u8 rsvd1[31]; /* DWORD 2 */ ++ u8 valid; /* DWORD 2 */ ++ u8 rsshash[32]; /* DWORD 3 */ ++} __packed; ++struct ETH_RX_COMPL_AMAP { ++ u32 dw[4]; ++}; ++ ++#endif /* __host_struct_amap_h__ */ +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/drivers/staging/benet/hwlib.h linux-2.6.29-rc3.owrt/drivers/staging/benet/hwlib.h +--- linux-2.6.29.owrt/drivers/staging/benet/hwlib.h 1970-01-01 01:00:00.000000000 +0100 ++++ linux-2.6.29-rc3.owrt/drivers/staging/benet/hwlib.h 2009-05-10 23:48:29.000000000 +0200 +@@ -0,0 +1,830 @@ ++/* ++ * Copyright (C) 2005 - 2008 ServerEngines ++ * All rights reserved. ++ * ++ * 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. The full GNU General ++ * Public License is included in this distribution in the file called COPYING. ++ * ++ * Contact Information: ++ * linux-drivers@serverengines.com ++ * ++ * ServerEngines ++ * 209 N. Fair Oaks Ave ++ * Sunnyvale, CA 94085 ++ */ ++#ifndef __hwlib_h__ ++#define __hwlib_h__ ++ ++#include <linux/module.h> ++#include <linux/io.h> ++#include <linux/list.h> ++#include <linux/spinlock.h> ++ ++#include "regmap.h" /* srcgen array map output */ ++ ++#include "asyncmesg.h" ++#include "fwcmd_opcodes.h" ++#include "post_codes.h" ++#include "fwcmd_mcc.h" ++ ++#include "fwcmd_types_bmap.h" ++#include "fwcmd_common_bmap.h" ++#include "fwcmd_eth_bmap.h" ++#include "bestatus.h" ++/* ++ * ++ * Macros for reading/writing a protection domain or CSR registers ++ * in BladeEngine. ++ */ ++#define PD_READ(fo, field) ioread32((fo)->db_va + \ ++ offsetof(struct BE_PROTECTION_DOMAIN_DBMAP_AMAP, field)/8) ++ ++#define PD_WRITE(fo, field, val) iowrite32(val, (fo)->db_va + \ ++ offsetof(struct BE_PROTECTION_DOMAIN_DBMAP_AMAP, field)/8) ++ ++#define CSR_READ(fo, field) ioread32((fo)->csr_va + \ ++ offsetof(struct BE_BLADE_ENGINE_CSRMAP_AMAP, field)/8) ++ ++#define CSR_WRITE(fo, field, val) iowrite32(val, (fo)->csr_va + \ ++ offsetof(struct BE_BLADE_ENGINE_CSRMAP_AMAP, field)/8) ++ ++#define PCICFG0_READ(fo, field) ioread32((fo)->pci_va + \ ++ offsetof(struct BE_PCICFG0_CSRMAP_AMAP, field)/8) ++ ++#define PCICFG0_WRITE(fo, field, val) iowrite32(val, (fo)->pci_va + \ ++ offsetof(struct BE_PCICFG0_CSRMAP_AMAP, field)/8) ++ ++#define PCICFG1_READ(fo, field) ioread32((fo)->pci_va + \ ++ offsetof(struct BE_PCICFG1_CSRMAP_AMAP, field)/8) ++ ++#define PCICFG1_WRITE(fo, field, val) iowrite32(val, (fo)->pci_va + \ ++ offsetof(struct BE_PCICFG1_CSRMAP_AMAP, field)/8) ++ ++#ifdef BE_DEBUG ++#define ASSERT(c) BUG_ON(!(c)); ++#else ++#define ASSERT(c) ++#endif ++ ++/* debug levels */ ++enum BE_DEBUG_LEVELS { ++ DL_ALWAYS = 0, /* cannot be masked */ ++ DL_ERR = 0x1, /* errors that should never happen */ ++ DL_WARN = 0x2, /* something questionable. ++ recoverable errors */ ++ DL_NOTE = 0x4, /* infrequent, important debug info */ ++ DL_INFO = 0x8, /* debug information */ ++ DL_VERBOSE = 0x10, /* detailed info, such as buffer traces */ ++ BE_DL_MIN_VALUE = 0x1, /* this is the min value used */ ++ BE_DL_MAX_VALUE = 0x80 /* this is the higheset value used */ ++} ; ++ ++extern unsigned int trace_level; ++ ++#define TRACE(lm, fmt, args...) { \ ++ if (trace_level & lm) { \ ++ printk(KERN_NOTICE "BE: %s:%d \n" fmt, \ ++ __FILE__ , __LINE__ , ## args); \ ++ } \ ++ } ++ ++static inline unsigned int be_trace_set_level(unsigned int level) ++{ ++ unsigned int old_level = trace_level; ++ trace_level = level; ++ return old_level; ++} ++ ++#define be_trace_get_level() trace_level ++/* ++ * Returns number of pages spanned by the size of data ++ * starting at the given address. ++ */ ++#define PAGES_SPANNED(_address, _size) \ ++ ((u32)((((size_t)(_address) & (PAGE_SIZE - 1)) + \ ++ (_size) + (PAGE_SIZE - 1)) >> PAGE_SHIFT)) ++/* Byte offset into the page corresponding to given address */ ++#define OFFSET_IN_PAGE(_addr_) ((size_t)(_addr_) & (PAGE_SIZE-1)) ++ ++/* ++ * circular subtract. ++ * Returns a - b assuming a circular number system, where a and b are ++ * in range (0, maxValue-1). If a==b, zero is returned so the ++ * highest value possible with this subtraction is maxValue-1. ++ */ ++static inline u32 be_subc(u32 a, u32 b, u32 max) ++{ ++ ASSERT(a <= max && b <= max); ++ ASSERT(max > 0); ++ return a >= b ? (a - b) : (max - b + a); ++} ++ ++static inline u32 be_addc(u32 a, u32 b, u32 max) ++{ ++ ASSERT(a < max); ++ ASSERT(max > 0); ++ return (max - a > b) ? (a + b) : (b + a - max); ++} ++ ++/* descriptor for a physically contiguous memory used for ring */ ++struct ring_desc { ++ u32 length; /* length in bytes */ ++ void *va; /* virtual address */ ++ u64 pa; /* bus address */ ++} ; ++ ++/* ++ * This structure stores information about a ring shared between hardware ++ * and software. Each ring is allocated by the driver in the uncached ++ * extension and mapped into BladeEngine's unified table. ++ */ ++struct mp_ring { ++ u32 pages; /* queue size in pages */ ++ u32 id; /* queue id assigned by beklib */ ++ u32 num; /* number of elements in queue */ ++ u32 cidx; /* consumer index */ ++ u32 pidx; /* producer index -- not used by most rings */ ++ u32 itemSize; /* size in bytes of one object */ ++ ++ void *va; /* The virtual address of the ring. ++ This should be last to allow 32 & 64 ++ bit debugger extensions to work. */ ++} ; ++ ++/*----------- amap bit filed get / set macros and functions -----*/ ++/* ++ * Structures defined in the map header files (under fw/amap/) with names ++ * in the format BE_<name>_AMAP are pseudo structures with members ++ * of type u8. These structures are templates that are used in ++ * conjuntion with the structures with names in the format ++ * <name>_AMAP to calculate the bit masks and bit offsets to get or set ++ * bit fields in structures. The structures <name>_AMAP are arrays ++ * of 32 bits words and have the correct size. The following macros ++ * provide convenient ways to get and set the various members ++ * in the structures without using strucctures with bit fields. ++ * Always use the macros AMAP_GET_BITS_PTR and AMAP_SET_BITS_PTR ++ * macros to extract and set various members. ++ */ ++ ++/* ++ * Returns the a bit mask for the register that is NOT shifted into location. ++ * That means return values always look like: 0x1, 0xFF, 0x7FF, etc... ++ */ ++static inline u32 amap_mask(u32 bit_size) ++{ ++ return bit_size == 32 ? 0xFFFFFFFF : (1 << bit_size) - 1; ++} ++ ++#define AMAP_BIT_MASK(_struct_, field) \ ++ amap_mask(AMAP_BIT_SIZE(_struct_, field)) ++ ++/* ++ * non-optimized set bits function. First clears the bits and then assigns them. ++ * This does not require knowledge of the particular DWORD you are setting. ++ * e.g. AMAP_SET_BITS_PTR (struct, field1, &contextMemory, 123); ++ */ ++static inline void ++amap_set(void *ptr, u32 dw_offset, u32 mask, u32 offset, u32 value) ++{ ++ u32 *dw = (u32 *)ptr; ++ *(dw + dw_offset) &= ~(mask << offset); ++ *(dw + dw_offset) |= (mask & value) << offset; ++} ++ ++#define AMAP_SET_BITS_PTR(_struct_, field, _structPtr_, val) \ ++ amap_set(_structPtr_, AMAP_WORD_OFFSET(_struct_, field),\ ++ AMAP_BIT_MASK(_struct_, field), \ ++ AMAP_BIT_OFFSET(_struct_, field), val) ++/* ++ * Non-optimized routine that gets the bits without knowing the correct DWORD. ++ * e.g. fieldValue = AMAP_GET_BITS_PTR (struct, field1, &contextMemory); ++ */ ++static inline u32 ++amap_get(void *ptr, u32 dw_offset, u32 mask, u32 offset) ++{ ++ u32 *dw = (u32 *)ptr; ++ return mask & (*(dw + dw_offset) >> offset); ++} ++#define AMAP_GET_BITS_PTR(_struct_, field, _structPtr_) \ ++ amap_get(_structPtr_, AMAP_WORD_OFFSET(_struct_, field), \ ++ AMAP_BIT_MASK(_struct_, field), \ ++ AMAP_BIT_OFFSET(_struct_, field)) ++ ++/* Returns 0-31 representing bit offset within a DWORD of a bitfield. */ ++#define AMAP_BIT_OFFSET(_struct_, field) \ ++ (offsetof(struct BE_ ## _struct_ ## _AMAP, field) % 32) ++ ++/* Returns 0-n representing DWORD offset of bitfield within the structure. */ ++#define AMAP_WORD_OFFSET(_struct_, field) \ ++ (offsetof(struct BE_ ## _struct_ ## _AMAP, field)/32) ++ ++/* Returns size of bitfield in bits. */ ++#define AMAP_BIT_SIZE(_struct_, field) \ ++ sizeof(((struct BE_ ## _struct_ ## _AMAP*)0)->field) ++ ++struct be_mcc_wrb_response_copy { ++ u16 length; /* bytes in response */ ++ u16 fwcmd_offset; /* offset within the wrb of the response */ ++ void *va; /* user's va to copy response into */ ++ ++} ; ++typedef void (*mcc_wrb_cqe_callback) (void *context, int status, ++ struct MCC_WRB_AMAP *optional_wrb); ++struct be_mcc_wrb_context { ++ ++ mcc_wrb_cqe_callback internal_cb; /* Function to call on ++ completion */ ++ void *internal_cb_context; /* Parameter to pass ++ to completion function */ ++ ++ mcc_wrb_cqe_callback cb; /* Function to call on completion */ ++ void *cb_context; /* Parameter to pass to completion function */ ++ ++ int *users_final_status; /* pointer to a local ++ variable for synchronous ++ commands */ ++ struct MCC_WRB_AMAP *wrb; /* pointer to original wrb for embedded ++ commands only */ ++ struct list_head next; /* links context structs together in ++ free list */ ++ ++ struct be_mcc_wrb_response_copy copy; /* Optional parameters to copy ++ embedded response to user's va */ ++ ++#if defined(BE_DEBUG) ++ u16 subsystem, opcode; /* Track this FWCMD for debug builds. */ ++ struct MCC_WRB_AMAP *ring_wrb; ++ u32 consumed_count; ++#endif ++} ; ++ ++/* ++ Represents a function object for network or storage. This ++ is used to manage per-function resources like MCC CQs, etc. ++*/ ++struct be_function_object { ++ ++ u32 magic; /*!< magic for detecting memory corruption. */ ++ ++ /* PCI BAR mapped addresses */ ++ u8 __iomem *csr_va; /* CSR */ ++ u8 __iomem *db_va; /* Door Bell */ ++ u8 __iomem *pci_va; /* PCI config space */ ++ u32 emulate; /* if set, MPU is not available. ++ Emulate everything. */ ++ u32 pend_queue_driving; /* if set, drive the queued WRBs ++ after releasing the WRB lock */ ++ ++ spinlock_t post_lock; /* lock for verifying one thread posting wrbs */ ++ spinlock_t cq_lock; /* lock for verifying one thread ++ processing cq */ ++ spinlock_t mcc_context_lock; /* lock for protecting mcc ++ context free list */ ++ unsigned long post_irq; ++ unsigned long cq_irq; ++ ++ u32 type; ++ u32 pci_function_number; ++ ++ struct be_mcc_object *mcc; /* mcc rings. */ ++ ++ struct { ++ struct MCC_MAILBOX_AMAP *va; /* VA to the mailbox */ ++ u64 pa; /* PA to the mailbox */ ++ u32 length; /* byte length of mailbox */ ++ ++ /* One default context struct used for posting at ++ * least one MCC_WRB ++ */ ++ struct be_mcc_wrb_context default_context; ++ bool default_context_allocated; ++ } mailbox; ++ ++ struct { ++ ++ /* Wake on lans configured. */ ++ u32 wol_bitmask; /* bits 0,1,2,3 are set if ++ corresponding index is enabled */ ++ } config; ++ ++ ++ struct BE_FIRMWARE_CONFIG fw_config; ++} ; ++ ++/* ++ Represents an Event Queue ++*/ ++struct be_eq_object { ++ u32 magic; ++ atomic_t ref_count; ++ ++ struct be_function_object *parent_function; ++ ++ struct list_head eq_list; ++ struct list_head cq_list_head; ++ ++ u32 eq_id; ++ void *cb_context; ++ ++} ; ++ ++/* ++ Manages a completion queue ++*/ ++struct be_cq_object { ++ u32 magic; ++ atomic_t ref_count; ++ ++ struct be_function_object *parent_function; ++ struct be_eq_object *eq_object; ++ ++ struct list_head cq_list; ++ struct list_head cqlist_for_eq; ++ ++ void *va; ++ u32 num_entries; ++ ++ void *cb_context; ++ ++ u32 cq_id; ++ ++} ; ++ ++/* ++ Manages an ethernet send queue ++*/ ++struct be_ethsq_object { ++ u32 magic; ++ ++ struct list_head list; ++ ++ struct be_function_object *parent_function; ++ struct be_cq_object *cq_object; ++ u32 bid; ++ ++} ; ++ ++/* ++@brief ++ Manages an ethernet receive queue ++*/ ++struct be_ethrq_object { ++ u32 magic; ++ struct list_head list; ++ struct be_function_object *parent_function; ++ u32 rid; ++ struct be_cq_object *cq_object; ++ struct be_cq_object *rss_cq_object[4]; ++ ++} ; ++ ++/* ++ Manages an MCC ++*/ ++typedef void (*mcc_async_event_callback) (void *context, u32 event_code, ++ void *event); ++struct be_mcc_object { ++ u32 magic; ++ ++ struct be_function_object *parent_function; ++ struct list_head mcc_list; ++ ++ struct be_cq_object *cq_object; ++ ++ /* Async event callback for MCC CQ. */ ++ mcc_async_event_callback async_cb; ++ void *async_context; ++ ++ struct { ++ struct be_mcc_wrb_context *base; ++ u32 num; ++ struct list_head list_head; ++ } wrb_context; ++ ++ struct { ++ struct ring_desc *rd; ++ struct mp_ring ring; ++ } sq; ++ ++ struct { ++ struct mp_ring ring; ++ } cq; ++ ++ u32 processing; /* flag indicating that one thread ++ is processing CQ */ ++ u32 rearm; /* doorbell rearm setting to make ++ sure the active processing thread */ ++ /* rearms the CQ if any of the threads requested it. */ ++ ++ struct list_head backlog; ++ u32 backlog_length; ++ u32 driving_backlog; ++ u32 consumed_index; ++ ++} ; ++ ++ ++/* Queue context header -- the required software information for ++ * queueing a WRB. ++ */ ++struct be_queue_driver_context { ++ mcc_wrb_cqe_callback internal_cb; /* Function to call on ++ completion */ ++ void *internal_cb_context; /* Parameter to pass ++ to completion function */ ++ ++ mcc_wrb_cqe_callback cb; /* Function to call on completion */ ++ void *cb_context; /* Parameter to pass to completion function */ ++ ++ struct be_mcc_wrb_response_copy copy; /* Optional parameters to copy ++ embedded response to user's va */ ++ void *optional_fwcmd_va; ++ struct list_head list; ++ u32 bytes; ++} ; ++ ++/* ++ * Common MCC WRB header that all commands require. ++ */ ++struct be_mcc_wrb_header { ++ u8 rsvd[offsetof(struct BE_MCC_WRB_AMAP, payload)/8]; ++} ; ++ ++/* ++ * All non embedded commands supported by hwlib functions only allow ++ * 1 SGE. This queue context handles them all. ++ */ ++struct be_nonembedded_q_ctxt { ++ struct be_queue_driver_context context; ++ struct be_mcc_wrb_header wrb_header; ++ struct MCC_SGE_AMAP sge[1]; ++} ; ++ ++/* ++ * ------------------------------------------------------------------------ ++ * This section contains the specific queue struct for each command. ++ * The user could always provide a be_generic_q_ctxt but this is a ++ * rather large struct. By using the specific struct, memory consumption ++ * can be reduced. ++ * ------------------------------------------------------------------------ ++ */ ++ ++struct be_link_status_q_ctxt { ++ struct be_queue_driver_context context; ++ struct be_mcc_wrb_header wrb_header; ++ struct FWCMD_COMMON_NTWK_LINK_STATUS_QUERY fwcmd; ++} ; ++ ++struct be_multicast_q_ctxt { ++ struct be_queue_driver_context context; ++ struct be_mcc_wrb_header wrb_header; ++ struct FWCMD_COMMON_NTWK_MULTICAST_SET fwcmd; ++} ; ++ ++ ++struct be_vlan_q_ctxt { ++ struct be_queue_driver_context context; ++ struct be_mcc_wrb_header wrb_header; ++ struct FWCMD_COMMON_NTWK_VLAN_CONFIG fwcmd; ++} ; ++ ++struct be_promiscuous_q_ctxt { ++ struct be_queue_driver_context context; ++ struct be_mcc_wrb_header wrb_header; ++ struct FWCMD_ETH_PROMISCUOUS fwcmd; ++} ; ++ ++struct be_force_failover_q_ctxt { ++ struct be_queue_driver_context context; ++ struct be_mcc_wrb_header wrb_header; ++ struct FWCMD_COMMON_FORCE_FAILOVER fwcmd; ++} ; ++ ++ ++struct be_rxf_filter_q_ctxt { ++ struct be_queue_driver_context context; ++ struct be_mcc_wrb_header wrb_header; ++ struct FWCMD_COMMON_NTWK_RX_FILTER fwcmd; ++} ; ++ ++struct be_eq_modify_delay_q_ctxt { ++ struct be_queue_driver_context context; ++ struct be_mcc_wrb_header wrb_header; ++ struct FWCMD_COMMON_MODIFY_EQ_DELAY fwcmd; ++} ; ++ ++/* ++ * The generic context is the largest size that would be required. ++ * It is the software context plus an entire WRB. ++ */ ++struct be_generic_q_ctxt { ++ struct be_queue_driver_context context; ++ struct be_mcc_wrb_header wrb_header; ++ struct MCC_WRB_PAYLOAD_AMAP payload; ++} ; ++ ++/* ++ * Types for the BE_QUEUE_CONTEXT object. ++ */ ++#define BE_QUEUE_INVALID (0) ++#define BE_QUEUE_LINK_STATUS (0xA006) ++#define BE_QUEUE_ETH_STATS (0xA007) ++#define BE_QUEUE_TPM_STATS (0xA008) ++#define BE_QUEUE_TCP_STATS (0xA009) ++#define BE_QUEUE_MULTICAST (0xA00A) ++#define BE_QUEUE_VLAN (0xA00B) ++#define BE_QUEUE_RSS (0xA00C) ++#define BE_QUEUE_FORCE_FAILOVER (0xA00D) ++#define BE_QUEUE_PROMISCUOUS (0xA00E) ++#define BE_QUEUE_WAKE_ON_LAN (0xA00F) ++#define BE_QUEUE_NOP (0xA010) ++ ++/* --- BE_FUNCTION_ENUM --- */ ++#define BE_FUNCTION_TYPE_ISCSI (0) ++#define BE_FUNCTION_TYPE_NETWORK (1) ++#define BE_FUNCTION_TYPE_ARM (2) ++ ++/* --- BE_ETH_TX_RING_TYPE_ENUM --- */ ++#define BE_ETH_TX_RING_TYPE_FORWARDING (1) /* Ether ring for forwarding */ ++#define BE_ETH_TX_RING_TYPE_STANDARD (2) /* Ether ring for sending */ ++ /* network packets. */ ++#define BE_ETH_TX_RING_TYPE_BOUND (3) /* Ethernet ring for sending */ ++ /* network packets, bound */ ++ /* to a physical port. */ ++/* ++ * ---------------------------------------------------------------------- ++ * API MACROS ++ * ---------------------------------------------------------------------- ++ */ ++#define BE_FWCMD_NAME(_short_name_) struct FWCMD_##_short_name_ ++#define BE_OPCODE_NAME(_short_name_) OPCODE_##_short_name_ ++#define BE_SUBSYSTEM_NAME(_short_name_) SUBSYSTEM_##_short_name_ ++ ++ ++#define BE_PREPARE_EMBEDDED_FWCMD(_pfob_, _wrb_, _short_name_) \ ++ ((BE_FWCMD_NAME(_short_name_) *) \ ++ be_function_prepare_embedded_fwcmd(_pfob_, _wrb_, \ ++ sizeof(BE_FWCMD_NAME(_short_name_)), \ ++ FIELD_SIZEOF(BE_FWCMD_NAME(_short_name_), params.request), \ ++ FIELD_SIZEOF(BE_FWCMD_NAME(_short_name_), params.response), \ ++ BE_OPCODE_NAME(_short_name_), \ ++ BE_SUBSYSTEM_NAME(_short_name_))); ++ ++#define BE_PREPARE_NONEMBEDDED_FWCMD(_pfob_, _wrb_, _iva_, _ipa_, _short_name_)\ ++ ((BE_FWCMD_NAME(_short_name_) *) \ ++ be_function_prepare_nonembedded_fwcmd(_pfob_, _wrb_, (_iva_), (_ipa_), \ ++ sizeof(BE_FWCMD_NAME(_short_name_)), \ ++ FIELD_SIZEOF(BE_FWCMD_NAME(_short_name_), params.request), \ ++ FIELD_SIZEOF(BE_FWCMD_NAME(_short_name_), params.response), \ ++ BE_OPCODE_NAME(_short_name_), \ ++ BE_SUBSYSTEM_NAME(_short_name_))); ++ ++int be_function_object_create(u8 __iomem *csr_va, u8 __iomem *db_va, ++ u8 __iomem *pci_va, u32 function_type, struct ring_desc *mailbox_rd, ++ struct be_function_object *pfob); ++ ++int be_function_object_destroy(struct be_function_object *pfob); ++int be_function_cleanup(struct be_function_object *pfob); ++ ++ ++int be_function_get_fw_version(struct be_function_object *pfob, ++ struct FWCMD_COMMON_GET_FW_VERSION_RESPONSE_PAYLOAD *fw_version, ++ mcc_wrb_cqe_callback cb, void *cb_context); ++ ++ ++int be_eq_modify_delay(struct be_function_object *pfob, ++ u32 num_eq, struct be_eq_object **eq_array, ++ u32 *eq_delay_array, mcc_wrb_cqe_callback cb, ++ void *cb_context, ++ struct be_eq_modify_delay_q_ctxt *q_ctxt); ++ ++ ++ ++int be_eq_create(struct be_function_object *pfob, ++ struct ring_desc *rd, u32 eqe_size, u32 num_entries, ++ u32 watermark, u32 timer_delay, struct be_eq_object *eq_object); ++ ++int be_eq_destroy(struct be_eq_object *eq); ++ ++int be_cq_create(struct be_function_object *pfob, ++ struct ring_desc *rd, u32 length, ++ bool solicited_eventable, bool no_delay, ++ u32 wm_thresh, struct be_eq_object *eq_object, ++ struct be_cq_object *cq_object); ++ ++int be_cq_destroy(struct be_cq_object *cq); ++ ++int be_mcc_ring_create(struct be_function_object *pfob, ++ struct ring_desc *rd, u32 length, ++ struct be_mcc_wrb_context *context_array, ++ u32 num_context_entries, ++ struct be_cq_object *cq, struct be_mcc_object *mcc); ++int be_mcc_ring_destroy(struct be_mcc_object *mcc_object); ++ ++int be_mcc_process_cq(struct be_mcc_object *mcc_object, bool rearm); ++ ++int be_mcc_add_async_event_callback(struct be_mcc_object *mcc_object, ++ mcc_async_event_callback cb, void *cb_context); ++ ++int be_pci_soft_reset(struct be_function_object *pfob); ++ ++ ++int be_drive_POST(struct be_function_object *pfob); ++ ++ ++int be_eth_sq_create(struct be_function_object *pfob, ++ struct ring_desc *rd, u32 length_in_bytes, ++ u32 type, u32 ulp, struct be_cq_object *cq_object, ++ struct be_ethsq_object *eth_sq); ++ ++struct be_eth_sq_parameters { ++ u32 port; ++ u32 rsvd0[2]; ++} ; ++ ++int be_eth_sq_create_ex(struct be_function_object *pfob, ++ struct ring_desc *rd, u32 length_in_bytes, ++ u32 type, u32 ulp, struct be_cq_object *cq_object, ++ struct be_eth_sq_parameters *ex_parameters, ++ struct be_ethsq_object *eth_sq); ++int be_eth_sq_destroy(struct be_ethsq_object *eth_sq); ++ ++int be_eth_set_flow_control(struct be_function_object *pfob, ++ bool txfc_enable, bool rxfc_enable); ++ ++int be_eth_get_flow_control(struct be_function_object *pfob, ++ bool *txfc_enable, bool *rxfc_enable); ++int be_eth_set_qos(struct be_function_object *pfob, u32 max_bps, u32 max_pps); ++ ++int be_eth_get_qos(struct be_function_object *pfob, u32 *max_bps, u32 *max_pps); ++ ++int be_eth_set_frame_size(struct be_function_object *pfob, ++ u32 *tx_frame_size, u32 *rx_frame_size); ++ ++int be_eth_rq_create(struct be_function_object *pfob, ++ struct ring_desc *rd, struct be_cq_object *cq_object, ++ struct be_cq_object *bcmc_cq_object, ++ struct be_ethrq_object *eth_rq); ++ ++int be_eth_rq_destroy(struct be_ethrq_object *eth_rq); ++ ++int be_eth_rq_destroy_options(struct be_ethrq_object *eth_rq, bool flush, ++ mcc_wrb_cqe_callback cb, void *cb_context); ++int be_eth_rq_set_frag_size(struct be_function_object *pfob, ++ u32 new_frag_size_bytes, u32 *actual_frag_size_bytes); ++int be_eth_rq_get_frag_size(struct be_function_object *pfob, ++ u32 *frag_size_bytes); ++ ++void *be_function_prepare_embedded_fwcmd(struct be_function_object *pfob, ++ struct MCC_WRB_AMAP *wrb, ++ u32 payload_length, u32 request_length, ++ u32 response_length, u32 opcode, u32 subsystem); ++void *be_function_prepare_nonembedded_fwcmd(struct be_function_object *pfob, ++ struct MCC_WRB_AMAP *wrb, void *fwcmd_header_va, u64 fwcmd_header_pa, ++ u32 payload_length, u32 request_length, u32 response_length, ++ u32 opcode, u32 subsystem); ++ ++ ++struct MCC_WRB_AMAP * ++be_function_peek_mcc_wrb(struct be_function_object *pfob); ++ ++int be_rxf_mac_address_read_write(struct be_function_object *pfob, ++ bool port1, bool mac1, bool mgmt, ++ bool write, bool permanent, u8 *mac_address, ++ mcc_wrb_cqe_callback cb, ++ void *cb_context); ++ ++int be_rxf_multicast_config(struct be_function_object *pfob, ++ bool promiscuous, u32 num, u8 *mac_table, ++ mcc_wrb_cqe_callback cb, ++ void *cb_context, ++ struct be_multicast_q_ctxt *q_ctxt); ++ ++int be_rxf_vlan_config(struct be_function_object *pfob, ++ bool promiscuous, u32 num, u16 *vlan_tag_array, ++ mcc_wrb_cqe_callback cb, void *cb_context, ++ struct be_vlan_q_ctxt *q_ctxt); ++ ++ ++int be_rxf_link_status(struct be_function_object *pfob, ++ struct BE_LINK_STATUS *link_status, ++ mcc_wrb_cqe_callback cb, ++ void *cb_context, ++ struct be_link_status_q_ctxt *q_ctxt); ++ ++ ++int be_rxf_query_eth_statistics(struct be_function_object *pfob, ++ struct FWCMD_ETH_GET_STATISTICS *va_for_fwcmd, ++ u64 pa_for_fwcmd, mcc_wrb_cqe_callback cb, ++ void *cb_context, ++ struct be_nonembedded_q_ctxt *q_ctxt); ++ ++int be_rxf_promiscuous(struct be_function_object *pfob, ++ bool enable_port0, bool enable_port1, ++ mcc_wrb_cqe_callback cb, void *cb_context, ++ struct be_promiscuous_q_ctxt *q_ctxt); ++ ++ ++int be_rxf_filter_config(struct be_function_object *pfob, ++ struct NTWK_RX_FILTER_SETTINGS *settings, ++ mcc_wrb_cqe_callback cb, ++ void *cb_context, ++ struct be_rxf_filter_q_ctxt *q_ctxt); ++ ++/* ++ * ------------------------------------------------------ ++ * internal functions used by hwlib ++ * ------------------------------------------------------ ++ */ ++ ++ ++int be_function_ring_destroy(struct be_function_object *pfob, ++ u32 id, u32 ring_type, mcc_wrb_cqe_callback cb, ++ void *cb_context, ++ mcc_wrb_cqe_callback internal_cb, ++ void *internal_callback_context); ++ ++int be_function_post_mcc_wrb(struct be_function_object *pfob, ++ struct MCC_WRB_AMAP *wrb, ++ struct be_generic_q_ctxt *q_ctxt, ++ mcc_wrb_cqe_callback cb, void *cb_context, ++ mcc_wrb_cqe_callback internal_cb, ++ void *internal_cb_context, void *optional_fwcmd_va, ++ struct be_mcc_wrb_response_copy *response_copy); ++ ++int be_function_queue_mcc_wrb(struct be_function_object *pfob, ++ struct be_generic_q_ctxt *q_ctxt); ++ ++/* ++ * ------------------------------------------------------ ++ * MCC QUEUE ++ * ------------------------------------------------------ ++ */ ++ ++int be_mpu_init_mailbox(struct be_function_object *pfob, struct ring_desc *rd); ++ ++ ++struct MCC_WRB_AMAP * ++_be_mpu_peek_ring_wrb(struct be_mcc_object *mcc, bool driving_queue); ++ ++struct be_mcc_wrb_context * ++_be_mcc_allocate_wrb_context(struct be_function_object *pfob); ++ ++void _be_mcc_free_wrb_context(struct be_function_object *pfob, ++ struct be_mcc_wrb_context *context); ++ ++int _be_mpu_post_wrb_mailbox(struct be_function_object *pfob, ++ struct MCC_WRB_AMAP *wrb, struct be_mcc_wrb_context *wrb_context); ++ ++int _be_mpu_post_wrb_ring(struct be_mcc_object *mcc, ++ struct MCC_WRB_AMAP *wrb, struct be_mcc_wrb_context *wrb_context); ++ ++void be_drive_mcc_wrb_queue(struct be_mcc_object *mcc); ++ ++ ++/* ++ * ------------------------------------------------------ ++ * Ring Sizes ++ * ------------------------------------------------------ ++ */ ++static inline u32 be_ring_encoding_to_length(u32 encoding, u32 object_size) ++{ ++ ++ ASSERT(encoding != 1); /* 1 is rsvd */ ++ ASSERT(encoding < 16); ++ ASSERT(object_size > 0); ++ ++ if (encoding == 0) /* 32k deep */ ++ encoding = 16; ++ ++ return (1 << (encoding - 1)) * object_size; ++} ++ ++static inline ++u32 be_ring_length_to_encoding(u32 length_in_bytes, u32 object_size) ++{ ++ ++ u32 count, encoding; ++ ++ ASSERT(object_size > 0); ++ ASSERT(length_in_bytes % object_size == 0); ++ ++ count = length_in_bytes / object_size; ++ ++ ASSERT(count > 1); ++ ASSERT(count <= 32 * 1024); ++ ASSERT(length_in_bytes <= 8 * PAGE_SIZE); /* max ring size in UT */ ++ ++ encoding = __ilog2_u32(count) + 1; ++ ++ if (encoding == 16) ++ encoding = 0; /* 32k deep */ ++ ++ return encoding; ++} ++ ++void be_rd_to_pa_list(struct ring_desc *rd, struct PHYS_ADDR *pa_list, ++ u32 max_num); ++#endif /* __hwlib_h__ */ +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/drivers/staging/benet/Kconfig linux-2.6.29-rc3.owrt/drivers/staging/benet/Kconfig +--- linux-2.6.29.owrt/drivers/staging/benet/Kconfig 1970-01-01 01:00:00.000000000 +0100 ++++ linux-2.6.29-rc3.owrt/drivers/staging/benet/Kconfig 2009-05-10 23:48:29.000000000 +0200 +@@ -0,0 +1,7 @@ ++config BENET ++ tristate "ServerEngines 10Gb NIC - BladeEngine" ++ depends on PCI && INET ++ select INET_LRO ++ help ++ This driver implements the NIC functionality for ServerEngines ++ 10Gb network adapter BladeEngine (EC 3210). +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/drivers/staging/benet/MAINTAINERS linux-2.6.29-rc3.owrt/drivers/staging/benet/MAINTAINERS +--- linux-2.6.29.owrt/drivers/staging/benet/MAINTAINERS 1970-01-01 01:00:00.000000000 +0100 ++++ linux-2.6.29-rc3.owrt/drivers/staging/benet/MAINTAINERS 2009-05-10 23:48:29.000000000 +0200 +@@ -0,0 +1,6 @@ ++SERVER ENGINES 10Gbe NIC - BLADE-ENGINE ++P: Subbu Seetharaman ++M: subbus@serverengines.com ++L: netdev@vger.kernel.org ++W: http://www.serverengines.com ++S: Supported +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/drivers/staging/benet/Makefile linux-2.6.29-rc3.owrt/drivers/staging/benet/Makefile +--- linux-2.6.29.owrt/drivers/staging/benet/Makefile 1970-01-01 01:00:00.000000000 +0100 ++++ linux-2.6.29-rc3.owrt/drivers/staging/benet/Makefile 2009-05-10 23:48:29.000000000 +0200 +@@ -0,0 +1,14 @@ ++# ++# Makefile to build the network driver for ServerEngine's BladeEngine ++# ++obj-$(CONFIG_BENET) += benet.o ++ ++benet-y := be_init.o \ ++ be_int.o \ ++ be_netif.o \ ++ be_ethtool.o \ ++ funcobj.o \ ++ cq.o \ ++ eq.o \ ++ mpu.o \ ++ eth.o +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/drivers/staging/benet/mpu.c linux-2.6.29-rc3.owrt/drivers/staging/benet/mpu.c +--- linux-2.6.29.owrt/drivers/staging/benet/mpu.c 1970-01-01 01:00:00.000000000 +0100 ++++ linux-2.6.29-rc3.owrt/drivers/staging/benet/mpu.c 2009-05-10 23:48:29.000000000 +0200 +@@ -0,0 +1,1364 @@ ++/* ++ * Copyright (C) 2005 - 2008 ServerEngines ++ * All rights reserved. ++ * ++ * 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. The full GNU General ++ * Public License is included in this distribution in the file called COPYING. ++ * ++ * Contact Information: ++ * linux-drivers@serverengines.com ++ * ++ * ServerEngines ++ * 209 N. Fair Oaks Ave ++ * Sunnyvale, CA 94085 ++ */ ++#include <linux/delay.h> ++#include "hwlib.h" ++#include "bestatus.h" ++ ++static ++inline void mp_ring_create(struct mp_ring *ring, u32 num, u32 size, void *va) ++{ ++ ASSERT(ring); ++ memset(ring, 0, sizeof(struct mp_ring)); ++ ring->num = num; ++ ring->pages = DIV_ROUND_UP(num * size, PAGE_SIZE); ++ ring->itemSize = size; ++ ring->va = va; ++} ++ ++/* ++ * ----------------------------------------------------------------------- ++ * Interface for 2 index rings. i.e. consumer/producer rings ++ * -------------------------------------------------------------------------- ++ */ ++ ++/* Returns number items pending on ring. */ ++static inline u32 mp_ring_num_pending(struct mp_ring *ring) ++{ ++ ASSERT(ring); ++ if (ring->num == 0) ++ return 0; ++ return be_subc(ring->pidx, ring->cidx, ring->num); ++} ++ ++/* Returns number items free on ring. */ ++static inline u32 mp_ring_num_empty(struct mp_ring *ring) ++{ ++ ASSERT(ring); ++ return ring->num - 1 - mp_ring_num_pending(ring); ++} ++ ++/* Consume 1 item */ ++static inline void mp_ring_consume(struct mp_ring *ring) ++{ ++ ASSERT(ring); ++ ASSERT(ring->pidx != ring->cidx); ++ ++ ring->cidx = be_addc(ring->cidx, 1, ring->num); ++} ++ ++/* Produce 1 item */ ++static inline void mp_ring_produce(struct mp_ring *ring) ++{ ++ ASSERT(ring); ++ ring->pidx = be_addc(ring->pidx, 1, ring->num); ++} ++ ++/* Consume count items */ ++static inline void mp_ring_consume_multiple(struct mp_ring *ring, u32 count) ++{ ++ ASSERT(ring); ++ ASSERT(mp_ring_num_pending(ring) >= count); ++ ring->cidx = be_addc(ring->cidx, count, ring->num); ++} ++ ++static inline void *mp_ring_item(struct mp_ring *ring, u32 index) ++{ ++ ASSERT(ring); ++ ASSERT(index < ring->num); ++ ASSERT(ring->itemSize > 0); ++ return (u8 *) ring->va + index * ring->itemSize; ++} ++ ++/* Ptr to produce item */ ++static inline void *mp_ring_producer_ptr(struct mp_ring *ring) ++{ ++ ASSERT(ring); ++ return mp_ring_item(ring, ring->pidx); ++} ++ ++/* ++ * Returns a pointer to the current location in the ring. ++ * This is used for rings with 1 index. ++ */ ++static inline void *mp_ring_current(struct mp_ring *ring) ++{ ++ ASSERT(ring); ++ ASSERT(ring->pidx == 0); /* not used */ ++ ++ return mp_ring_item(ring, ring->cidx); ++} ++ ++/* ++ * Increment index for rings with only 1 index. ++ * This is used for rings with 1 index. ++ */ ++static inline void *mp_ring_next(struct mp_ring *ring) ++{ ++ ASSERT(ring); ++ ASSERT(ring->num > 0); ++ ASSERT(ring->pidx == 0); /* not used */ ++ ++ ring->cidx = be_addc(ring->cidx, 1, ring->num); ++ return mp_ring_current(ring); ++} ++ ++/* ++ This routine waits for a previously posted mailbox WRB to be completed. ++ Specifically it waits for the mailbox to say that it's ready to accept ++ more data by setting the LSB of the mailbox pd register to 1. ++ ++ pcontroller - The function object to post this data to ++ ++ IRQL < DISPATCH_LEVEL ++*/ ++static void be_mcc_mailbox_wait(struct be_function_object *pfob) ++{ ++ struct MPU_MAILBOX_DB_AMAP mailbox_db; ++ u32 i = 0; ++ u32 ready; ++ ++ if (pfob->emulate) { ++ /* No waiting for mailbox in emulated mode. */ ++ return; ++ } ++ ++ mailbox_db.dw[0] = PD_READ(pfob, mcc_bootstrap_db); ++ ready = AMAP_GET_BITS_PTR(MPU_MAILBOX_DB, ready, &mailbox_db); ++ ++ while (ready == false) { ++ if ((++i & 0x3FFFF) == 0) { ++ TRACE(DL_WARN, "Waiting for mailbox ready - %dk polls", ++ i / 1000); ++ } ++ udelay(1); ++ mailbox_db.dw[0] = PD_READ(pfob, mcc_bootstrap_db); ++ ready = AMAP_GET_BITS_PTR(MPU_MAILBOX_DB, ready, &mailbox_db); ++ } ++} ++ ++/* ++ This routine tells the MCC mailbox that there is data to processed ++ in the mailbox. It does this by setting the physical address for the ++ mailbox location and clearing the LSB. This routine returns immediately ++ and does not wait for the WRB to be processed. ++ ++ pcontroller - The function object to post this data to ++ ++ IRQL < DISPATCH_LEVEL ++ ++*/ ++static void be_mcc_mailbox_notify(struct be_function_object *pfob) ++{ ++ struct MPU_MAILBOX_DB_AMAP mailbox_db; ++ u32 pa; ++ ++ ASSERT(pfob->mailbox.pa); ++ ASSERT(pfob->mailbox.va); ++ ++ /* If emulated, do not ring the mailbox */ ++ if (pfob->emulate) { ++ TRACE(DL_WARN, "MPU disabled. Skipping mailbox notify."); ++ return; ++ } ++ ++ /* form the higher bits in the address */ ++ mailbox_db.dw[0] = 0; /* init */ ++ AMAP_SET_BITS_PTR(MPU_MAILBOX_DB, hi, &mailbox_db, 1); ++ AMAP_SET_BITS_PTR(MPU_MAILBOX_DB, ready, &mailbox_db, 0); ++ ++ /* bits 34 to 63 */ ++ pa = (u32) (pfob->mailbox.pa >> 34); ++ AMAP_SET_BITS_PTR(MPU_MAILBOX_DB, address, &mailbox_db, pa); ++ ++ /* Wait for the MPU to be ready */ ++ be_mcc_mailbox_wait(pfob); ++ ++ /* Ring doorbell 1st time */ ++ PD_WRITE(pfob, mcc_bootstrap_db, mailbox_db.dw[0]); ++ ++ /* Wait for 1st write to be acknowledged. */ ++ be_mcc_mailbox_wait(pfob); ++ ++ /* lower bits 30 bits from 4th bit (bits 4 to 33)*/ ++ pa = (u32) (pfob->mailbox.pa >> 4) & 0x3FFFFFFF; ++ ++ AMAP_SET_BITS_PTR(MPU_MAILBOX_DB, hi, &mailbox_db, 0); ++ AMAP_SET_BITS_PTR(MPU_MAILBOX_DB, ready, &mailbox_db, 0); ++ AMAP_SET_BITS_PTR(MPU_MAILBOX_DB, address, &mailbox_db, pa); ++ ++ /* Ring doorbell 2nd time */ ++ PD_WRITE(pfob, mcc_bootstrap_db, mailbox_db.dw[0]); ++} ++ ++/* ++ This routine tells the MCC mailbox that there is data to processed ++ in the mailbox. It does this by setting the physical address for the ++ mailbox location and clearing the LSB. This routine spins until the ++ MPU writes a 1 into the LSB indicating that the data has been received ++ and is ready to be processed. ++ ++ pcontroller - The function object to post this data to ++ ++ IRQL < DISPATCH_LEVEL ++*/ ++static void ++be_mcc_mailbox_notify_and_wait(struct be_function_object *pfob) ++{ ++ /* ++ * Notify it ++ */ ++ be_mcc_mailbox_notify(pfob); ++ /* ++ * Now wait for completion of WRB ++ */ ++ be_mcc_mailbox_wait(pfob); ++} ++ ++void ++be_mcc_process_cqe(struct be_function_object *pfob, ++ struct MCC_CQ_ENTRY_AMAP *cqe) ++{ ++ struct be_mcc_wrb_context *wrb_context = NULL; ++ u32 offset, status; ++ u8 *p; ++ ++ ASSERT(cqe); ++ /* ++ * A command completed. Commands complete out-of-order. ++ * Determine which command completed from the TAG. ++ */ ++ offset = offsetof(struct BE_MCC_CQ_ENTRY_AMAP, mcc_tag)/8; ++ p = (u8 *) cqe + offset; ++ wrb_context = (struct be_mcc_wrb_context *)(void *)(size_t)(*(u64 *)p); ++ ASSERT(wrb_context); ++ ++ /* ++ * Perform a response copy if requested. ++ * Only copy data if the FWCMD is successful. ++ */ ++ status = AMAP_GET_BITS_PTR(MCC_CQ_ENTRY, completion_status, cqe); ++ if (status == MGMT_STATUS_SUCCESS && wrb_context->copy.length > 0) { ++ ASSERT(wrb_context->wrb); ++ ASSERT(wrb_context->copy.va); ++ p = (u8 *)wrb_context->wrb + ++ offsetof(struct BE_MCC_WRB_AMAP, payload)/8; ++ memcpy(wrb_context->copy.va, ++ (u8 *)p + wrb_context->copy.fwcmd_offset, ++ wrb_context->copy.length); ++ } ++ ++ if (status) ++ status = BE_NOT_OK; ++ /* internal callback */ ++ if (wrb_context->internal_cb) { ++ wrb_context->internal_cb(wrb_context->internal_cb_context, ++ status, wrb_context->wrb); ++ } ++ ++ /* callback */ ++ if (wrb_context->cb) { ++ wrb_context->cb(wrb_context->cb_context, ++ status, wrb_context->wrb); ++ } ++ /* Free the context structure */ ++ _be_mcc_free_wrb_context(pfob, wrb_context); ++} ++ ++void be_drive_mcc_wrb_queue(struct be_mcc_object *mcc) ++{ ++ struct be_function_object *pfob = NULL; ++ int status = BE_PENDING; ++ struct be_generic_q_ctxt *q_ctxt; ++ struct MCC_WRB_AMAP *wrb; ++ struct MCC_WRB_AMAP *queue_wrb; ++ u32 length, payload_length, sge_count, embedded; ++ unsigned long irql; ++ ++ BUILD_BUG_ON((sizeof(struct be_generic_q_ctxt) < ++ sizeof(struct be_queue_driver_context) + ++ sizeof(struct MCC_WRB_AMAP))); ++ pfob = mcc->parent_function; ++ ++ spin_lock_irqsave(&pfob->post_lock, irql); ++ ++ if (mcc->driving_backlog) { ++ spin_unlock_irqrestore(&pfob->post_lock, irql); ++ if (pfob->pend_queue_driving && pfob->mcc) { ++ pfob->pend_queue_driving = 0; ++ be_drive_mcc_wrb_queue(pfob->mcc); ++ } ++ return; ++ } ++ /* Acquire the flag to limit 1 thread to redrive posts. */ ++ mcc->driving_backlog = 1; ++ ++ while (!list_empty(&mcc->backlog)) { ++ wrb = _be_mpu_peek_ring_wrb(mcc, true); /* Driving the queue */ ++ if (!wrb) ++ break; /* No space in the ring yet. */ ++ /* Get the next queued entry to process. */ ++ q_ctxt = list_first_entry(&mcc->backlog, ++ struct be_generic_q_ctxt, context.list); ++ list_del(&q_ctxt->context.list); ++ pfob->mcc->backlog_length--; ++ /* ++ * Compute the required length of the WRB. ++ * Since the queue element may be smaller than ++ * the complete WRB, copy only the required number of bytes. ++ */ ++ queue_wrb = (struct MCC_WRB_AMAP *) &q_ctxt->wrb_header; ++ embedded = AMAP_GET_BITS_PTR(MCC_WRB, embedded, queue_wrb); ++ if (embedded) { ++ payload_length = AMAP_GET_BITS_PTR(MCC_WRB, ++ payload_length, queue_wrb); ++ length = sizeof(struct be_mcc_wrb_header) + ++ payload_length; ++ } else { ++ sge_count = AMAP_GET_BITS_PTR(MCC_WRB, sge_count, ++ queue_wrb); ++ ASSERT(sge_count == 1); /* only 1 frag. */ ++ length = sizeof(struct be_mcc_wrb_header) + ++ sge_count * sizeof(struct MCC_SGE_AMAP); ++ } ++ ++ /* ++ * Truncate the length based on the size of the ++ * queue element. Some elements that have output parameters ++ * can be smaller than the payload_length field would ++ * indicate. We really only need to copy the request ++ * parameters, not the response. ++ */ ++ length = min(length, (u32) (q_ctxt->context.bytes - ++ offsetof(struct be_generic_q_ctxt, wrb_header))); ++ ++ /* Copy the queue element WRB into the ring. */ ++ memcpy(wrb, &q_ctxt->wrb_header, length); ++ ++ /* Post the wrb. This should not fail assuming we have ++ * enough context structs. */ ++ status = be_function_post_mcc_wrb(pfob, wrb, NULL, ++ q_ctxt->context.cb, q_ctxt->context.cb_context, ++ q_ctxt->context.internal_cb, ++ q_ctxt->context.internal_cb_context, ++ q_ctxt->context.optional_fwcmd_va, ++ &q_ctxt->context.copy); ++ ++ if (status == BE_SUCCESS) { ++ /* ++ * Synchronous completion. Since it was queued, ++ * we will invoke the callback. ++ * To the user, this is an asynchronous request. ++ */ ++ spin_unlock_irqrestore(&pfob->post_lock, irql); ++ if (pfob->pend_queue_driving && pfob->mcc) { ++ pfob->pend_queue_driving = 0; ++ be_drive_mcc_wrb_queue(pfob->mcc); ++ } ++ ++ ASSERT(q_ctxt->context.cb); ++ ++ q_ctxt->context.cb( ++ q_ctxt->context.cb_context, ++ BE_SUCCESS, NULL); ++ ++ spin_lock_irqsave(&pfob->post_lock, irql); ++ ++ } else if (status != BE_PENDING) { ++ /* ++ * Another resource failed. Should never happen ++ * if we have sufficient MCC_WRB_CONTEXT structs. ++ * Return to head of the queue. ++ */ ++ TRACE(DL_WARN, "Failed to post a queued WRB. 0x%x", ++ status); ++ list_add(&q_ctxt->context.list, &mcc->backlog); ++ pfob->mcc->backlog_length++; ++ break; ++ } ++ } ++ ++ /* Free the flag to limit 1 thread to redrive posts. */ ++ mcc->driving_backlog = 0; ++ spin_unlock_irqrestore(&pfob->post_lock, irql); ++} ++ ++/* This function asserts that the WRB was consumed in order. */ ++#ifdef BE_DEBUG ++u32 be_mcc_wrb_consumed_in_order(struct be_mcc_object *mcc, ++ struct MCC_CQ_ENTRY_AMAP *cqe) ++{ ++ struct be_mcc_wrb_context *wrb_context = NULL; ++ u32 wrb_index; ++ u32 wrb_consumed_in_order; ++ u32 offset; ++ u8 *p; ++ ++ ASSERT(cqe); ++ /* ++ * A command completed. Commands complete out-of-order. ++ * Determine which command completed from the TAG. ++ */ ++ offset = offsetof(struct BE_MCC_CQ_ENTRY_AMAP, mcc_tag)/8; ++ p = (u8 *) cqe + offset; ++ wrb_context = (struct be_mcc_wrb_context *)(void *)(size_t)(*(u64 *)p); ++ ++ ASSERT(wrb_context); ++ ++ wrb_index = (u32) (((u64)(size_t)wrb_context->ring_wrb - ++ (u64)(size_t)mcc->sq.ring.va) / sizeof(struct MCC_WRB_AMAP)); ++ ++ ASSERT(wrb_index < mcc->sq.ring.num); ++ ++ wrb_consumed_in_order = (u32) (wrb_index == mcc->consumed_index); ++ mcc->consumed_index = be_addc(mcc->consumed_index, 1, mcc->sq.ring.num); ++ return wrb_consumed_in_order; ++} ++#endif ++ ++int be_mcc_process_cq(struct be_mcc_object *mcc, bool rearm) ++{ ++ struct be_function_object *pfob = NULL; ++ struct MCC_CQ_ENTRY_AMAP *cqe; ++ struct CQ_DB_AMAP db; ++ struct mp_ring *cq_ring = &mcc->cq.ring; ++ struct mp_ring *mp_ring = &mcc->sq.ring; ++ u32 num_processed = 0; ++ u32 consumed = 0, valid, completed, cqe_consumed, async_event; ++ ++ pfob = mcc->parent_function; ++ ++ spin_lock_irqsave(&pfob->cq_lock, pfob->cq_irq); ++ ++ /* ++ * Verify that only one thread is processing the CQ at once. ++ * We cannot hold the lock while processing the CQ due to ++ * the callbacks into the OS. Therefore, this flag is used ++ * to control it. If any of the threads want to ++ * rearm the CQ, we need to honor that. ++ */ ++ if (mcc->processing != 0) { ++ mcc->rearm = mcc->rearm || rearm; ++ goto Error; ++ } else { ++ mcc->processing = 1; /* lock processing for this thread. */ ++ mcc->rearm = rearm; /* set our rearm setting */ ++ } ++ ++ spin_unlock_irqrestore(&pfob->cq_lock, pfob->cq_irq); ++ ++ cqe = mp_ring_current(cq_ring); ++ valid = AMAP_GET_BITS_PTR(MCC_CQ_ENTRY, valid, cqe); ++ while (valid) { ++ ++ if (num_processed >= 8) { ++ /* coalesce doorbells, but free space in cq ++ * ring while processing. */ ++ db.dw[0] = 0; /* clear */ ++ AMAP_SET_BITS_PTR(CQ_DB, qid, &db, cq_ring->id); ++ AMAP_SET_BITS_PTR(CQ_DB, rearm, &db, false); ++ AMAP_SET_BITS_PTR(CQ_DB, event, &db, false); ++ AMAP_SET_BITS_PTR(CQ_DB, num_popped, &db, ++ num_processed); ++ num_processed = 0; ++ ++ PD_WRITE(pfob, cq_db, db.dw[0]); ++ } ++ ++ async_event = AMAP_GET_BITS_PTR(MCC_CQ_ENTRY, async_event, cqe); ++ if (async_event) { ++ /* This is an asynchronous event. */ ++ struct ASYNC_EVENT_TRAILER_AMAP *async_trailer = ++ (struct ASYNC_EVENT_TRAILER_AMAP *) ++ ((u8 *) cqe + sizeof(struct MCC_CQ_ENTRY_AMAP) - ++ sizeof(struct ASYNC_EVENT_TRAILER_AMAP)); ++ u32 event_code; ++ async_event = AMAP_GET_BITS_PTR(ASYNC_EVENT_TRAILER, ++ async_event, async_trailer); ++ ASSERT(async_event == 1); ++ ++ ++ valid = AMAP_GET_BITS_PTR(ASYNC_EVENT_TRAILER, ++ valid, async_trailer); ++ ASSERT(valid == 1); ++ ++ /* Call the async event handler if it is installed. */ ++ if (mcc->async_cb) { ++ event_code = ++ AMAP_GET_BITS_PTR(ASYNC_EVENT_TRAILER, ++ event_code, async_trailer); ++ mcc->async_cb(mcc->async_context, ++ (u32) event_code, (void *) cqe); ++ } ++ ++ } else { ++ /* This is a completion entry. */ ++ ++ /* No vm forwarding in this driver. */ ++ ++ cqe_consumed = AMAP_GET_BITS_PTR(MCC_CQ_ENTRY, ++ consumed, cqe); ++ if (cqe_consumed) { ++ /* ++ * A command on the MCC ring was consumed. ++ * Update the consumer index. ++ * These occur in order. ++ */ ++ ASSERT(be_mcc_wrb_consumed_in_order(mcc, cqe)); ++ consumed++; ++ } ++ ++ completed = AMAP_GET_BITS_PTR(MCC_CQ_ENTRY, ++ completed, cqe); ++ if (completed) { ++ /* A command completed. Use tag to ++ * determine which command. */ ++ be_mcc_process_cqe(pfob, cqe); ++ } ++ } ++ ++ /* Reset the CQE */ ++ AMAP_SET_BITS_PTR(MCC_CQ_ENTRY, valid, cqe, false); ++ num_processed++; ++ ++ /* Update our tracking for the CQ ring. */ ++ cqe = mp_ring_next(cq_ring); ++ valid = AMAP_GET_BITS_PTR(MCC_CQ_ENTRY, valid, cqe); ++ } ++ ++ TRACE(DL_INFO, "num_processed:0x%x, and consumed:0x%x", ++ num_processed, consumed); ++ /* ++ * Grab the CQ lock to synchronize the "rearm" setting for ++ * the doorbell, and for clearing the "processing" flag. ++ */ ++ spin_lock_irqsave(&pfob->cq_lock, pfob->cq_irq); ++ ++ /* ++ * Rearm the cq. This is done based on the global mcc->rearm ++ * flag which combines the rearm parameter from the current ++ * call to process_cq and any other threads ++ * that tried to process the CQ while this one was active. ++ * This handles the situation where a sync. fwcmd was processing ++ * the CQ while the interrupt/dpc tries to process it. ++ * The sync process gets to continue -- but it is now ++ * responsible for the rearming. ++ */ ++ if (num_processed > 0 || mcc->rearm == true) { ++ db.dw[0] = 0; /* clear */ ++ AMAP_SET_BITS_PTR(CQ_DB, qid, &db, cq_ring->id); ++ AMAP_SET_BITS_PTR(CQ_DB, rearm, &db, mcc->rearm); ++ AMAP_SET_BITS_PTR(CQ_DB, event, &db, false); ++ AMAP_SET_BITS_PTR(CQ_DB, num_popped, &db, num_processed); ++ ++ PD_WRITE(pfob, cq_db, db.dw[0]); ++ } ++ /* ++ * Update the consumer index after ringing the CQ doorbell. ++ * We don't want another thread to post more WRBs before we ++ * have CQ space available. ++ */ ++ mp_ring_consume_multiple(mp_ring, consumed); ++ ++ /* Clear the processing flag. */ ++ mcc->processing = 0; ++ ++Error: ++ spin_unlock_irqrestore(&pfob->cq_lock, pfob->cq_irq); ++ /* ++ * Use the local variable to detect if the current thread ++ * holds the WRB post lock. If rearm is false, this is ++ * either a synchronous command, or the upper layer driver is polling ++ * from a thread. We do not drive the queue from that ++ * context since the driver may hold the ++ * wrb post lock already. ++ */ ++ if (rearm) ++ be_drive_mcc_wrb_queue(mcc); ++ else ++ pfob->pend_queue_driving = 1; ++ ++ return BE_SUCCESS; ++} ++ ++/* ++ *============================================================================ ++ * P U B L I C R O U T I N E S ++ *============================================================================ ++ */ ++ ++/* ++ This routine creates an MCC object. This object contains an MCC send queue ++ and a CQ private to the MCC. ++ ++ pcontroller - Handle to a function object ++ ++ EqObject - EQ object that will be used to dispatch this MCC ++ ++ ppMccObject - Pointer to an internal Mcc Object returned. ++ ++ Returns BE_SUCCESS if successfull,, otherwise a useful error code ++ is returned. ++ ++ IRQL < DISPATCH_LEVEL ++ ++*/ ++int ++be_mcc_ring_create(struct be_function_object *pfob, ++ struct ring_desc *rd, u32 length, ++ struct be_mcc_wrb_context *context_array, ++ u32 num_context_entries, ++ struct be_cq_object *cq, struct be_mcc_object *mcc) ++{ ++ int status = 0; ++ ++ struct FWCMD_COMMON_MCC_CREATE *fwcmd = NULL; ++ struct MCC_WRB_AMAP *wrb = NULL; ++ u32 num_entries_encoded, n, i; ++ void *va = NULL; ++ unsigned long irql; ++ ++ if (length < sizeof(struct MCC_WRB_AMAP) * 2) { ++ TRACE(DL_ERR, "Invalid MCC ring length:%d", length); ++ return BE_NOT_OK; ++ } ++ /* ++ * Reduce the actual ring size to be less than the number ++ * of context entries. This ensures that we run out of ++ * ring WRBs first so the queuing works correctly. We never ++ * queue based on context structs. ++ */ ++ if (num_context_entries + 1 < ++ length / sizeof(struct MCC_WRB_AMAP) - 1) { ++ ++ u32 max_length = ++ (num_context_entries + 2) * sizeof(struct MCC_WRB_AMAP); ++ ++ if (is_power_of_2(max_length)) ++ length = __roundup_pow_of_two(max_length+1) / 2; ++ else ++ length = __roundup_pow_of_two(max_length) / 2; ++ ++ ASSERT(length <= max_length); ++ ++ TRACE(DL_WARN, ++ "MCC ring length reduced based on context entries." ++ " length:%d wrbs:%d context_entries:%d", length, ++ (int) (length / sizeof(struct MCC_WRB_AMAP)), ++ num_context_entries); ++ } ++ ++ spin_lock_irqsave(&pfob->post_lock, irql); ++ ++ num_entries_encoded = ++ be_ring_length_to_encoding(length, sizeof(struct MCC_WRB_AMAP)); ++ ++ /* Init MCC object. */ ++ memset(mcc, 0, sizeof(*mcc)); ++ mcc->parent_function = pfob; ++ mcc->cq_object = cq; ++ ++ INIT_LIST_HEAD(&mcc->backlog); ++ ++ wrb = be_function_peek_mcc_wrb(pfob); ++ if (!wrb) { ++ ASSERT(wrb); ++ TRACE(DL_ERR, "No free MCC WRBs in create EQ."); ++ status = BE_STATUS_NO_MCC_WRB; ++ goto error; ++ } ++ /* Prepares an embedded fwcmd, including request/response sizes. */ ++ fwcmd = BE_PREPARE_EMBEDDED_FWCMD(pfob, wrb, COMMON_MCC_CREATE); ++ ++ fwcmd->params.request.num_pages = DIV_ROUND_UP(length, PAGE_SIZE); ++ /* ++ * Program MCC ring context ++ */ ++ AMAP_SET_BITS_PTR(MCC_RING_CONTEXT, pdid, ++ &fwcmd->params.request.context, 0); ++ AMAP_SET_BITS_PTR(MCC_RING_CONTEXT, invalid, ++ &fwcmd->params.request.context, false); ++ AMAP_SET_BITS_PTR(MCC_RING_CONTEXT, ring_size, ++ &fwcmd->params.request.context, num_entries_encoded); ++ ++ n = cq->cq_id; ++ AMAP_SET_BITS_PTR(MCC_RING_CONTEXT, ++ cq_id, &fwcmd->params.request.context, n); ++ be_rd_to_pa_list(rd, fwcmd->params.request.pages, ++ ARRAY_SIZE(fwcmd->params.request.pages)); ++ /* Post the f/w command */ ++ status = be_function_post_mcc_wrb(pfob, wrb, NULL, NULL, NULL, ++ NULL, NULL, fwcmd, NULL); ++ if (status != BE_SUCCESS) { ++ TRACE(DL_ERR, "MCC to create CQ failed."); ++ goto error; ++ } ++ /* ++ * Create a linked list of context structures ++ */ ++ mcc->wrb_context.base = context_array; ++ mcc->wrb_context.num = num_context_entries; ++ INIT_LIST_HEAD(&mcc->wrb_context.list_head); ++ memset(context_array, 0, ++ sizeof(struct be_mcc_wrb_context) * num_context_entries); ++ for (i = 0; i < mcc->wrb_context.num; i++) { ++ list_add_tail(&context_array[i].next, ++ &mcc->wrb_context.list_head); ++ } ++ ++ /* ++ * ++ * Create an mcc_ring for tracking WRB hw ring ++ */ ++ va = rd->va; ++ ASSERT(va); ++ mp_ring_create(&mcc->sq.ring, length / sizeof(struct MCC_WRB_AMAP), ++ sizeof(struct MCC_WRB_AMAP), va); ++ mcc->sq.ring.id = fwcmd->params.response.id; ++ /* ++ * Init a mcc_ring for tracking the MCC CQ. ++ */ ++ ASSERT(cq->va); ++ mp_ring_create(&mcc->cq.ring, cq->num_entries, ++ sizeof(struct MCC_CQ_ENTRY_AMAP), cq->va); ++ mcc->cq.ring.id = cq->cq_id; ++ ++ /* Force zeroing of CQ. */ ++ memset(cq->va, 0, cq->num_entries * sizeof(struct MCC_CQ_ENTRY_AMAP)); ++ ++ /* Initialize debug index. */ ++ mcc->consumed_index = 0; ++ ++ atomic_inc(&cq->ref_count); ++ pfob->mcc = mcc; ++ ++ TRACE(DL_INFO, "MCC ring created. id:%d bytes:%d cq_id:%d cq_entries:%d" ++ " num_context:%d", mcc->sq.ring.id, length, ++ cq->cq_id, cq->num_entries, num_context_entries); ++ ++error: ++ spin_unlock_irqrestore(&pfob->post_lock, irql); ++ if (pfob->pend_queue_driving && pfob->mcc) { ++ pfob->pend_queue_driving = 0; ++ be_drive_mcc_wrb_queue(pfob->mcc); ++ } ++ return status; ++} ++ ++/* ++ This routine destroys an MCC send queue ++ ++ MccObject - Internal Mcc Object to be destroyed. ++ ++ Returns BE_SUCCESS if successfull, otherwise an error code is returned. ++ ++ IRQL < DISPATCH_LEVEL ++ ++ The caller of this routine must ensure that no other WRB may be posted ++ until this routine returns. ++ ++*/ ++int be_mcc_ring_destroy(struct be_mcc_object *mcc) ++{ ++ int status = 0; ++ struct be_function_object *pfob = mcc->parent_function; ++ ++ ++ ASSERT(mcc->processing == 0); ++ ++ /* ++ * Remove the ring from the function object. ++ * This transitions back to mailbox mode. ++ */ ++ pfob->mcc = NULL; ++ ++ /* Send fwcmd to destroy the queue. (Using the mailbox.) */ ++ status = be_function_ring_destroy(mcc->parent_function, mcc->sq.ring.id, ++ FWCMD_RING_TYPE_MCC, NULL, NULL, NULL, NULL); ++ ASSERT(status == 0); ++ ++ /* Release the SQ reference to the CQ */ ++ atomic_dec(&mcc->cq_object->ref_count); ++ ++ return status; ++} ++ ++static void ++mcc_wrb_sync_cb(void *context, int staus, struct MCC_WRB_AMAP *wrb) ++{ ++ struct be_mcc_wrb_context *wrb_context = ++ (struct be_mcc_wrb_context *) context; ++ ASSERT(wrb_context); ++ *wrb_context->users_final_status = staus; ++} ++ ++/* ++ This routine posts a command to the MCC send queue ++ ++ mcc - Internal Mcc Object to be destroyed. ++ ++ wrb - wrb to post. ++ ++ Returns BE_SUCCESS if successfull, otherwise an error code is returned. ++ ++ IRQL < DISPATCH_LEVEL if CompletionCallback is not NULL ++ IRQL <=DISPATCH_LEVEL if CompletionCallback is NULL ++ ++ If this routine is called with CompletionCallback != NULL the ++ call is considered to be asynchronous and will return as soon ++ as the WRB is posted to the MCC with BE_PENDING. ++ ++ If CompletionCallback is NULL, then this routine will not return until ++ a completion for this MCC command has been processed. ++ If called at DISPATCH_LEVEL the CompletionCallback must be NULL. ++ ++ This routine should only be called if the MPU has been boostraped past ++ mailbox mode. ++ ++ ++*/ ++int ++_be_mpu_post_wrb_ring(struct be_mcc_object *mcc, struct MCC_WRB_AMAP *wrb, ++ struct be_mcc_wrb_context *wrb_context) ++{ ++ ++ struct MCC_WRB_AMAP *ring_wrb = NULL; ++ int status = BE_PENDING; ++ int final_status = BE_PENDING; ++ mcc_wrb_cqe_callback cb = NULL; ++ struct MCC_DB_AMAP mcc_db; ++ u32 embedded; ++ ++ ASSERT(mp_ring_num_empty(&mcc->sq.ring) > 0); ++ /* ++ * Input wrb is most likely the next wrb in the ring, since the client ++ * can peek at the address. ++ */ ++ ring_wrb = mp_ring_producer_ptr(&mcc->sq.ring); ++ if (wrb != ring_wrb) { ++ /* If not equal, copy it into the ring. */ ++ memcpy(ring_wrb, wrb, sizeof(struct MCC_WRB_AMAP)); ++ } ++#ifdef BE_DEBUG ++ wrb_context->ring_wrb = ring_wrb; ++#endif ++ embedded = AMAP_GET_BITS_PTR(MCC_WRB, embedded, ring_wrb); ++ if (embedded) { ++ /* embedded commands will have the response within the WRB. */ ++ wrb_context->wrb = ring_wrb; ++ } else { ++ /* ++ * non-embedded commands will not have the response ++ * within the WRB, and they may complete out-of-order. ++ * The WRB will not be valid to inspect ++ * during the completion. ++ */ ++ wrb_context->wrb = NULL; ++ } ++ cb = wrb_context->cb; ++ ++ if (cb == NULL) { ++ /* Assign our internal callback if this is a ++ * synchronous call. */ ++ wrb_context->cb = mcc_wrb_sync_cb; ++ wrb_context->cb_context = wrb_context; ++ wrb_context->users_final_status = &final_status; ++ } ++ /* Increment producer index */ ++ ++ mcc_db.dw[0] = 0; /* initialize */ ++ AMAP_SET_BITS_PTR(MCC_DB, rid, &mcc_db, mcc->sq.ring.id); ++ AMAP_SET_BITS_PTR(MCC_DB, numPosted, &mcc_db, 1); ++ ++ mp_ring_produce(&mcc->sq.ring); ++ PD_WRITE(mcc->parent_function, mpu_mcc_db, mcc_db.dw[0]); ++ TRACE(DL_INFO, "pidx: %x and cidx: %x.", mcc->sq.ring.pidx, ++ mcc->sq.ring.cidx); ++ ++ if (cb == NULL) { ++ int polls = 0; /* At >= 1 us per poll */ ++ /* Wait until this command completes, polling the CQ. */ ++ do { ++ TRACE(DL_INFO, "FWCMD submitted in the poll mode."); ++ /* Do not rearm CQ in this context. */ ++ be_mcc_process_cq(mcc, false); ++ ++ if (final_status == BE_PENDING) { ++ if ((++polls & 0x7FFFF) == 0) { ++ TRACE(DL_WARN, ++ "Warning : polling MCC CQ for %d" ++ "ms.", polls / 1000); ++ } ++ ++ udelay(1); ++ } ++ ++ /* final_status changed when the command completes */ ++ } while (final_status == BE_PENDING); ++ ++ status = final_status; ++ } ++ ++ return status; ++} ++ ++struct MCC_WRB_AMAP * ++_be_mpu_peek_ring_wrb(struct be_mcc_object *mcc, bool driving_queue) ++{ ++ /* If we have queued items, do not allow a post to bypass the queue. */ ++ if (!driving_queue && !list_empty(&mcc->backlog)) ++ return NULL; ++ ++ if (mp_ring_num_empty(&mcc->sq.ring) <= 0) ++ return NULL; ++ return (struct MCC_WRB_AMAP *) mp_ring_producer_ptr(&mcc->sq.ring); ++} ++ ++int ++be_mpu_init_mailbox(struct be_function_object *pfob, struct ring_desc *mailbox) ++{ ++ ASSERT(mailbox); ++ pfob->mailbox.va = mailbox->va; ++ pfob->mailbox.pa = cpu_to_le64(mailbox->pa); ++ pfob->mailbox.length = mailbox->length; ++ ++ ASSERT(((u32)(size_t)pfob->mailbox.va & 0xf) == 0); ++ ASSERT(((u32)(size_t)pfob->mailbox.pa & 0xf) == 0); ++ /* ++ * Issue the WRB to set MPU endianness ++ */ ++ { ++ u64 *endian_check = (u64 *) (pfob->mailbox.va + ++ offsetof(struct BE_MCC_MAILBOX_AMAP, wrb)/8); ++ *endian_check = 0xFF1234FFFF5678FFULL; ++ } ++ ++ be_mcc_mailbox_notify_and_wait(pfob); ++ ++ return BE_SUCCESS; ++} ++ ++ ++/* ++ This routine posts a command to the MCC mailbox. ++ ++ FuncObj - Function Object to post the WRB on behalf of. ++ wrb - wrb to post. ++ CompletionCallback - Address of a callback routine to invoke once the WRB ++ is completed. ++ CompletionCallbackContext - Opaque context to be passed during the call to ++ the CompletionCallback. ++ Returns BE_SUCCESS if successfull, otherwise an error code is returned. ++ ++ IRQL <=DISPATCH_LEVEL if CompletionCallback is NULL ++ ++ This routine will block until a completion for this MCC command has been ++ processed. If called at DISPATCH_LEVEL the CompletionCallback must be NULL. ++ ++ This routine should only be called if the MPU has not been boostraped past ++ mailbox mode. ++*/ ++int ++_be_mpu_post_wrb_mailbox(struct be_function_object *pfob, ++ struct MCC_WRB_AMAP *wrb, struct be_mcc_wrb_context *wrb_context) ++{ ++ struct MCC_MAILBOX_AMAP *mailbox = NULL; ++ struct MCC_WRB_AMAP *mb_wrb; ++ struct MCC_CQ_ENTRY_AMAP *mb_cq; ++ u32 offset, status; ++ ++ ASSERT(pfob->mcc == NULL); ++ mailbox = pfob->mailbox.va; ++ ASSERT(mailbox); ++ ++ offset = offsetof(struct BE_MCC_MAILBOX_AMAP, wrb)/8; ++ mb_wrb = (struct MCC_WRB_AMAP *) (u8 *)mailbox + offset; ++ if (mb_wrb != wrb) { ++ memset(mailbox, 0, sizeof(*mailbox)); ++ memcpy(mb_wrb, wrb, sizeof(struct MCC_WRB_AMAP)); ++ } ++ /* The callback can inspect the final WRB to get output parameters. */ ++ wrb_context->wrb = mb_wrb; ++ ++ be_mcc_mailbox_notify_and_wait(pfob); ++ ++ /* A command completed. Use tag to determine which command. */ ++ offset = offsetof(struct BE_MCC_MAILBOX_AMAP, cq)/8; ++ mb_cq = (struct MCC_CQ_ENTRY_AMAP *) ((u8 *)mailbox + offset); ++ be_mcc_process_cqe(pfob, mb_cq); ++ ++ status = AMAP_GET_BITS_PTR(MCC_CQ_ENTRY, completion_status, mb_cq); ++ if (status) ++ status = BE_NOT_OK; ++ return status; ++} ++ ++struct be_mcc_wrb_context * ++_be_mcc_allocate_wrb_context(struct be_function_object *pfob) ++{ ++ struct be_mcc_wrb_context *context = NULL; ++ unsigned long irq; ++ ++ spin_lock_irqsave(&pfob->mcc_context_lock, irq); ++ ++ if (!pfob->mailbox.default_context_allocated) { ++ /* Use the single default context that we ++ * always have allocated. */ ++ pfob->mailbox.default_context_allocated = true; ++ context = &pfob->mailbox.default_context; ++ } else if (pfob->mcc) { ++ /* Get a context from the free list. If any are available. */ ++ if (!list_empty(&pfob->mcc->wrb_context.list_head)) { ++ context = list_first_entry( ++ &pfob->mcc->wrb_context.list_head, ++ struct be_mcc_wrb_context, next); ++ } ++ } ++ ++ spin_unlock_irqrestore(&pfob->mcc_context_lock, irq); ++ ++ return context; ++} ++ ++void ++_be_mcc_free_wrb_context(struct be_function_object *pfob, ++ struct be_mcc_wrb_context *context) ++{ ++ unsigned long irq; ++ ++ ASSERT(context); ++ /* ++ * Zero during free to try and catch any bugs where the context ++ * is accessed after a free. ++ */ ++ memset(context, 0, sizeof(context)); ++ ++ spin_lock_irqsave(&pfob->mcc_context_lock, irq); ++ ++ if (context == &pfob->mailbox.default_context) { ++ /* Free the default context. */ ++ ASSERT(pfob->mailbox.default_context_allocated); ++ pfob->mailbox.default_context_allocated = false; ++ } else { ++ /* Add to free list. */ ++ ASSERT(pfob->mcc); ++ list_add_tail(&context->next, ++ &pfob->mcc->wrb_context.list_head); ++ } ++ ++ spin_unlock_irqrestore(&pfob->mcc_context_lock, irq); ++} ++ ++int ++be_mcc_add_async_event_callback(struct be_mcc_object *mcc_object, ++ mcc_async_event_callback cb, void *cb_context) ++{ ++ /* Lock against anyone trying to change the callback/context pointers ++ * while being used. */ ++ spin_lock_irqsave(&mcc_object->parent_function->cq_lock, ++ mcc_object->parent_function->cq_irq); ++ ++ /* Assign the async callback. */ ++ mcc_object->async_context = cb_context; ++ mcc_object->async_cb = cb; ++ ++ spin_unlock_irqrestore(&mcc_object->parent_function->cq_lock, ++ mcc_object->parent_function->cq_irq); ++ ++ return BE_SUCCESS; ++} ++ ++#define MPU_EP_CONTROL 0 ++#define MPU_EP_SEMAPHORE 0xac ++ ++/* ++ *------------------------------------------------------------------- ++ * Function: be_wait_for_POST_complete ++ * Waits until the BladeEngine POST completes (either in error or success). ++ * pfob - ++ * return status - BE_SUCCESS (0) on success. Negative error code on failure. ++ *------------------------------------------------------------------- ++ */ ++static int be_wait_for_POST_complete(struct be_function_object *pfob) ++{ ++ struct MGMT_HBA_POST_STATUS_STRUCT_AMAP status; ++ int s; ++ u32 post_error, post_stage; ++ ++ const u32 us_per_loop = 1000; /* 1000us */ ++ const u32 print_frequency_loops = 1000000 / us_per_loop; ++ const u32 max_loops = 60 * print_frequency_loops; ++ u32 loops = 0; ++ ++ /* ++ * Wait for arm fw indicating it is done or a fatal error happened. ++ * Note: POST can take some time to complete depending on configuration ++ * settings (consider ARM attempts to acquire an IP address ++ * over DHCP!!!). ++ * ++ */ ++ do { ++ status.dw[0] = ioread32(pfob->csr_va + MPU_EP_SEMAPHORE); ++ post_error = AMAP_GET_BITS_PTR(MGMT_HBA_POST_STATUS_STRUCT, ++ error, &status); ++ post_stage = AMAP_GET_BITS_PTR(MGMT_HBA_POST_STATUS_STRUCT, ++ stage, &status); ++ if (0 == (loops % print_frequency_loops)) { ++ /* Print current status */ ++ TRACE(DL_INFO, "POST status = 0x%x (stage = 0x%x)", ++ status.dw[0], post_stage); ++ } ++ udelay(us_per_loop); ++ } while ((post_error != 1) && ++ (post_stage != POST_STAGE_ARMFW_READY) && ++ (++loops < max_loops)); ++ ++ if (post_error == 1) { ++ TRACE(DL_ERR, "POST error! Status = 0x%x (stage = 0x%x)", ++ status.dw[0], post_stage); ++ s = BE_NOT_OK; ++ } else if (post_stage != POST_STAGE_ARMFW_READY) { ++ TRACE(DL_ERR, "POST time-out! Status = 0x%x (stage = 0x%x)", ++ status.dw[0], post_stage); ++ s = BE_NOT_OK; ++ } else { ++ s = BE_SUCCESS; ++ } ++ return s; ++} ++ ++/* ++ *------------------------------------------------------------------- ++ * Function: be_kickoff_and_wait_for_POST ++ * Interacts with the BladeEngine management processor to initiate POST, and ++ * subsequently waits until POST completes (either in error or success). ++ * The caller must acquire the reset semaphore before initiating POST ++ * to prevent multiple drivers interacting with the management processor. ++ * Once POST is complete the caller must release the reset semaphore. ++ * Callers who only want to wait for POST complete may call ++ * be_wait_for_POST_complete. ++ * pfob - ++ * return status - BE_SUCCESS (0) on success. Negative error code on failure. ++ *------------------------------------------------------------------- ++ */ ++static int ++be_kickoff_and_wait_for_POST(struct be_function_object *pfob) ++{ ++ struct MGMT_HBA_POST_STATUS_STRUCT_AMAP status; ++ int s; ++ ++ const u32 us_per_loop = 1000; /* 1000us */ ++ const u32 print_frequency_loops = 1000000 / us_per_loop; ++ const u32 max_loops = 5 * print_frequency_loops; ++ u32 loops = 0; ++ u32 post_error, post_stage; ++ ++ /* Wait for arm fw awaiting host ready or a fatal error happened. */ ++ TRACE(DL_INFO, "Wait for BladeEngine ready to POST"); ++ do { ++ status.dw[0] = ioread32(pfob->csr_va + MPU_EP_SEMAPHORE); ++ post_error = AMAP_GET_BITS_PTR(MGMT_HBA_POST_STATUS_STRUCT, ++ error, &status); ++ post_stage = AMAP_GET_BITS_PTR(MGMT_HBA_POST_STATUS_STRUCT, ++ stage, &status); ++ if (0 == (loops % print_frequency_loops)) { ++ /* Print current status */ ++ TRACE(DL_INFO, "POST status = 0x%x (stage = 0x%x)", ++ status.dw[0], post_stage); ++ } ++ udelay(us_per_loop); ++ } while ((post_error != 1) && ++ (post_stage < POST_STAGE_AWAITING_HOST_RDY) && ++ (++loops < max_loops)); ++ ++ if (post_error == 1) { ++ TRACE(DL_ERR, "Pre-POST error! Status = 0x%x (stage = 0x%x)", ++ status.dw[0], post_stage); ++ s = BE_NOT_OK; ++ } else if (post_stage == POST_STAGE_AWAITING_HOST_RDY) { ++ iowrite32(POST_STAGE_HOST_RDY, pfob->csr_va + MPU_EP_SEMAPHORE); ++ ++ /* Wait for POST to complete */ ++ s = be_wait_for_POST_complete(pfob); ++ } else { ++ /* ++ * Either a timeout waiting for host ready signal or POST has ++ * moved ahead without requiring a host ready signal. ++ * Might as well give POST a chance to complete ++ * (or timeout again). ++ */ ++ s = be_wait_for_POST_complete(pfob); ++ } ++ return s; ++} ++ ++/* ++ *------------------------------------------------------------------- ++ * Function: be_pci_soft_reset ++ * This function is called to issue a BladeEngine soft reset. ++ * Callers should acquire the soft reset semaphore before calling this ++ * function. Additionaly, callers should ensure they cannot be pre-empted ++ * while the routine executes. Upon completion of this routine, callers ++ * should release the reset semaphore. This routine implicitly waits ++ * for BladeEngine POST to complete. ++ * pfob - ++ * return status - BE_SUCCESS (0) on success. Negative error code on failure. ++ *------------------------------------------------------------------- ++ */ ++int be_pci_soft_reset(struct be_function_object *pfob) ++{ ++ struct PCICFG_SOFT_RESET_CSR_AMAP soft_reset; ++ struct PCICFG_ONLINE0_CSR_AMAP pciOnline0; ++ struct PCICFG_ONLINE1_CSR_AMAP pciOnline1; ++ struct EP_CONTROL_CSR_AMAP epControlCsr; ++ int status = BE_SUCCESS; ++ u32 i, soft_reset_bit; ++ ++ TRACE(DL_NOTE, "PCI reset..."); ++ ++ /* Issue soft reset #1 to get BladeEngine into a known state. */ ++ soft_reset.dw[0] = PCICFG0_READ(pfob, soft_reset); ++ AMAP_SET_BITS_PTR(PCICFG_SOFT_RESET_CSR, softreset, soft_reset.dw, 1); ++ PCICFG0_WRITE(pfob, host_timer_int_ctrl, soft_reset.dw[0]); ++ /* ++ * wait til soft reset is deasserted - hardware ++ * deasserts after some time. ++ */ ++ i = 0; ++ do { ++ udelay(50); ++ soft_reset.dw[0] = PCICFG0_READ(pfob, soft_reset); ++ soft_reset_bit = AMAP_GET_BITS_PTR(PCICFG_SOFT_RESET_CSR, ++ softreset, soft_reset.dw); ++ } while (soft_reset_bit && (i++ < 1024)); ++ if (soft_reset_bit != 0) { ++ TRACE(DL_ERR, "Soft-reset #1 did not deassert as expected."); ++ status = BE_NOT_OK; ++ goto Error_label; ++ } ++ /* Mask everything */ ++ PCICFG0_WRITE(pfob, ue_status_low_mask, 0xFFFFFFFF); ++ PCICFG0_WRITE(pfob, ue_status_hi_mask, 0xFFFFFFFF); ++ /* ++ * Set everything offline except MPU IRAM (it is offline with ++ * the soft-reset, but soft-reset does not reset the PCICFG registers!) ++ */ ++ pciOnline0.dw[0] = 0; ++ pciOnline1.dw[0] = 0; ++ AMAP_SET_BITS_PTR(PCICFG_ONLINE1_CSR, mpu_iram_online, ++ pciOnline1.dw, 1); ++ PCICFG0_WRITE(pfob, online0, pciOnline0.dw[0]); ++ PCICFG0_WRITE(pfob, online1, pciOnline1.dw[0]); ++ ++ udelay(20000); ++ ++ /* Issue soft reset #2. */ ++ AMAP_SET_BITS_PTR(PCICFG_SOFT_RESET_CSR, softreset, soft_reset.dw, 1); ++ PCICFG0_WRITE(pfob, host_timer_int_ctrl, soft_reset.dw[0]); ++ /* ++ * wait til soft reset is deasserted - hardware ++ * deasserts after some time. ++ */ ++ i = 0; ++ do { ++ udelay(50); ++ soft_reset.dw[0] = PCICFG0_READ(pfob, soft_reset); ++ soft_reset_bit = AMAP_GET_BITS_PTR(PCICFG_SOFT_RESET_CSR, ++ softreset, soft_reset.dw); ++ } while (soft_reset_bit && (i++ < 1024)); ++ if (soft_reset_bit != 0) { ++ TRACE(DL_ERR, "Soft-reset #1 did not deassert as expected."); ++ status = BE_NOT_OK; ++ goto Error_label; ++ } ++ ++ ++ udelay(20000); ++ ++ /* Take MPU out of reset. */ ++ ++ epControlCsr.dw[0] = ioread32(pfob->csr_va + MPU_EP_CONTROL); ++ AMAP_SET_BITS_PTR(EP_CONTROL_CSR, CPU_reset, &epControlCsr, 0); ++ iowrite32((u32)epControlCsr.dw[0], pfob->csr_va + MPU_EP_CONTROL); ++ ++ /* Kickoff BE POST and wait for completion */ ++ status = be_kickoff_and_wait_for_POST(pfob); ++ ++Error_label: ++ return status; ++} ++ ++ ++/* ++ *------------------------------------------------------------------- ++ * Function: be_pci_reset_required ++ * This private function is called to detect if a host entity is ++ * required to issue a PCI soft reset and subsequently drive ++ * BladeEngine POST. Scenarios where this is required: ++ * 1) BIOS-less configuration ++ * 2) Hot-swap/plug/power-on ++ * pfob - ++ * return true if a reset is required, false otherwise ++ *------------------------------------------------------------------- ++ */ ++static bool be_pci_reset_required(struct be_function_object *pfob) ++{ ++ struct MGMT_HBA_POST_STATUS_STRUCT_AMAP status; ++ bool do_reset = false; ++ u32 post_error, post_stage; ++ ++ /* ++ * Read the POST status register ++ */ ++ status.dw[0] = ioread32(pfob->csr_va + MPU_EP_SEMAPHORE); ++ post_error = AMAP_GET_BITS_PTR(MGMT_HBA_POST_STATUS_STRUCT, error, ++ &status); ++ post_stage = AMAP_GET_BITS_PTR(MGMT_HBA_POST_STATUS_STRUCT, stage, ++ &status); ++ if (post_stage <= POST_STAGE_AWAITING_HOST_RDY) { ++ /* ++ * If BladeEngine is waiting for host ready indication, ++ * we want to do a PCI reset. ++ */ ++ do_reset = true; ++ } ++ ++ return do_reset; ++} ++ ++/* ++ *------------------------------------------------------------------- ++ * Function: be_drive_POST ++ * This function is called to drive BladeEngine POST. The ++ * caller should ensure they cannot be pre-empted while this routine executes. ++ * pfob - ++ * return status - BE_SUCCESS (0) on success. Negative error code on failure. ++ *------------------------------------------------------------------- ++ */ ++int be_drive_POST(struct be_function_object *pfob) ++{ ++ int status; ++ ++ if (false != be_pci_reset_required(pfob)) { ++ /* PCI reset is needed (implicitly starts and waits for POST) */ ++ status = be_pci_soft_reset(pfob); ++ } else { ++ /* No PCI reset is needed, start POST */ ++ status = be_kickoff_and_wait_for_POST(pfob); ++ } ++ ++ return status; ++} +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/drivers/staging/benet/mpu_context.h linux-2.6.29-rc3.owrt/drivers/staging/benet/mpu_context.h +--- linux-2.6.29.owrt/drivers/staging/benet/mpu_context.h 1970-01-01 01:00:00.000000000 +0100 ++++ linux-2.6.29-rc3.owrt/drivers/staging/benet/mpu_context.h 2009-05-10 23:48:29.000000000 +0200 +@@ -0,0 +1,46 @@ ++/* ++ * Copyright (C) 2005 - 2008 ServerEngines ++ * All rights reserved. ++ * ++ * 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. The full GNU General ++ * Public License is included in this distribution in the file called COPYING. ++ * ++ * Contact Information: ++ * linux-drivers@serverengines.com ++ * ++ * ServerEngines ++ * 209 N. Fair Oaks Ave ++ * Sunnyvale, CA 94085 ++ */ ++/* ++ * Autogenerated by srcgen version: 0127 ++ */ ++#ifndef __mpu_context_amap_h__ ++#define __mpu_context_amap_h__ ++ ++/* ++ * Management command and control ring context. The MPUs BTLR_CTRL1 CSR ++ * controls the writeback behavior of the producer and consumer index values. ++ */ ++struct BE_MCC_RING_CONTEXT_AMAP { ++ u8 con_index[16]; /* DWORD 0 */ ++ u8 ring_size[4]; /* DWORD 0 */ ++ u8 cq_id[11]; /* DWORD 0 */ ++ u8 rsvd0; /* DWORD 0 */ ++ u8 prod_index[16]; /* DWORD 1 */ ++ u8 pdid[15]; /* DWORD 1 */ ++ u8 invalid; /* DWORD 1 */ ++ u8 cmd_pending_current[7]; /* DWORD 2 */ ++ u8 rsvd1[25]; /* DWORD 2 */ ++ u8 hpi_port_cq_id[11]; /* DWORD 3 */ ++ u8 rsvd2[5]; /* DWORD 3 */ ++ u8 cmd_pending_max[7]; /* DWORD 3 */ ++ u8 rsvd3[9]; /* DWORD 3 */ ++} __packed; ++struct MCC_RING_CONTEXT_AMAP { ++ u32 dw[4]; ++}; ++ ++#endif /* __mpu_context_amap_h__ */ +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/drivers/staging/benet/mpu.h linux-2.6.29-rc3.owrt/drivers/staging/benet/mpu.h +--- linux-2.6.29.owrt/drivers/staging/benet/mpu.h 1970-01-01 01:00:00.000000000 +0100 ++++ linux-2.6.29-rc3.owrt/drivers/staging/benet/mpu.h 2009-05-10 23:48:29.000000000 +0200 +@@ -0,0 +1,74 @@ ++/* ++ * Copyright (C) 2005 - 2008 ServerEngines ++ * All rights reserved. ++ * ++ * 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. The full GNU General ++ * Public License is included in this distribution in the file called COPYING. ++ * ++ * Contact Information: ++ * linux-drivers@serverengines.com ++ * ++ * ServerEngines ++ * 209 N. Fair Oaks Ave ++ * Sunnyvale, CA 94085 ++ */ ++/* ++ * Autogenerated by srcgen version: 0127 ++ */ ++#ifndef __mpu_amap_h__ ++#define __mpu_amap_h__ ++#include "ep.h" ++ ++/* Provide control parameters for the Managment Processor Unit. */ ++struct BE_MPU_CSRMAP_AMAP { ++ struct BE_EP_CSRMAP_AMAP ep; ++ u8 rsvd0[128]; /* DWORD 64 */ ++ u8 rsvd1[32]; /* DWORD 68 */ ++ u8 rsvd2[192]; /* DWORD 69 */ ++ u8 rsvd3[192]; /* DWORD 75 */ ++ u8 rsvd4[32]; /* DWORD 81 */ ++ u8 rsvd5[32]; /* DWORD 82 */ ++ u8 rsvd6[32]; /* DWORD 83 */ ++ u8 rsvd7[32]; /* DWORD 84 */ ++ u8 rsvd8[32]; /* DWORD 85 */ ++ u8 rsvd9[32]; /* DWORD 86 */ ++ u8 rsvd10[32]; /* DWORD 87 */ ++ u8 rsvd11[32]; /* DWORD 88 */ ++ u8 rsvd12[32]; /* DWORD 89 */ ++ u8 rsvd13[32]; /* DWORD 90 */ ++ u8 rsvd14[32]; /* DWORD 91 */ ++ u8 rsvd15[32]; /* DWORD 92 */ ++ u8 rsvd16[32]; /* DWORD 93 */ ++ u8 rsvd17[32]; /* DWORD 94 */ ++ u8 rsvd18[32]; /* DWORD 95 */ ++ u8 rsvd19[32]; /* DWORD 96 */ ++ u8 rsvd20[32]; /* DWORD 97 */ ++ u8 rsvd21[32]; /* DWORD 98 */ ++ u8 rsvd22[32]; /* DWORD 99 */ ++ u8 rsvd23[32]; /* DWORD 100 */ ++ u8 rsvd24[32]; /* DWORD 101 */ ++ u8 rsvd25[32]; /* DWORD 102 */ ++ u8 rsvd26[32]; /* DWORD 103 */ ++ u8 rsvd27[32]; /* DWORD 104 */ ++ u8 rsvd28[96]; /* DWORD 105 */ ++ u8 rsvd29[32]; /* DWORD 108 */ ++ u8 rsvd30[32]; /* DWORD 109 */ ++ u8 rsvd31[32]; /* DWORD 110 */ ++ u8 rsvd32[32]; /* DWORD 111 */ ++ u8 rsvd33[32]; /* DWORD 112 */ ++ u8 rsvd34[96]; /* DWORD 113 */ ++ u8 rsvd35[32]; /* DWORD 116 */ ++ u8 rsvd36[32]; /* DWORD 117 */ ++ u8 rsvd37[32]; /* DWORD 118 */ ++ u8 rsvd38[32]; /* DWORD 119 */ ++ u8 rsvd39[32]; /* DWORD 120 */ ++ u8 rsvd40[32]; /* DWORD 121 */ ++ u8 rsvd41[134][32]; /* DWORD 122 */ ++} __packed; ++struct MPU_CSRMAP_AMAP { ++ u32 dw[256]; ++}; ++ ++#endif /* __mpu_amap_h__ */ +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/drivers/staging/benet/pcicfg.h linux-2.6.29-rc3.owrt/drivers/staging/benet/pcicfg.h +--- linux-2.6.29.owrt/drivers/staging/benet/pcicfg.h 1970-01-01 01:00:00.000000000 +0100 ++++ linux-2.6.29-rc3.owrt/drivers/staging/benet/pcicfg.h 2009-05-10 23:48:29.000000000 +0200 +@@ -0,0 +1,825 @@ ++/* ++ * Copyright (C) 2005 - 2008 ServerEngines ++ * All rights reserved. ++ * ++ * 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. The full GNU General ++ * Public License is included in this distribution in the file called COPYING. ++ * ++ * Contact Information: ++ * linux-drivers@serverengines.com ++ * ++ * ServerEngines ++ * 209 N. Fair Oaks Ave ++ * Sunnyvale, CA 94085 ++ */ ++/* ++ * Autogenerated by srcgen version: 0127 ++ */ ++#ifndef __pcicfg_amap_h__ ++#define __pcicfg_amap_h__ ++ ++/* Vendor and Device ID Register. */ ++struct BE_PCICFG_ID_CSR_AMAP { ++ u8 vendorid[16]; /* DWORD 0 */ ++ u8 deviceid[16]; /* DWORD 0 */ ++} __packed; ++struct PCICFG_ID_CSR_AMAP { ++ u32 dw[1]; ++}; ++ ++/* IO Bar Register. */ ++struct BE_PCICFG_IOBAR_CSR_AMAP { ++ u8 iospace; /* DWORD 0 */ ++ u8 rsvd0[7]; /* DWORD 0 */ ++ u8 iobar[24]; /* DWORD 0 */ ++} __packed; ++struct PCICFG_IOBAR_CSR_AMAP { ++ u32 dw[1]; ++}; ++ ++/* Memory BAR 0 Register. */ ++struct BE_PCICFG_MEMBAR0_CSR_AMAP { ++ u8 memspace; /* DWORD 0 */ ++ u8 type[2]; /* DWORD 0 */ ++ u8 pf; /* DWORD 0 */ ++ u8 rsvd0[10]; /* DWORD 0 */ ++ u8 membar0[18]; /* DWORD 0 */ ++} __packed; ++struct PCICFG_MEMBAR0_CSR_AMAP { ++ u32 dw[1]; ++}; ++ ++/* Memory BAR 1 - Low Address Register. */ ++struct BE_PCICFG_MEMBAR1_LO_CSR_AMAP { ++ u8 memspace; /* DWORD 0 */ ++ u8 type[2]; /* DWORD 0 */ ++ u8 pf; /* DWORD 0 */ ++ u8 rsvd0[13]; /* DWORD 0 */ ++ u8 membar1lo[15]; /* DWORD 0 */ ++} __packed; ++struct PCICFG_MEMBAR1_LO_CSR_AMAP { ++ u32 dw[1]; ++}; ++ ++/* Memory BAR 1 - High Address Register. */ ++struct BE_PCICFG_MEMBAR1_HI_CSR_AMAP { ++ u8 membar1hi[32]; /* DWORD 0 */ ++} __packed; ++struct PCICFG_MEMBAR1_HI_CSR_AMAP { ++ u32 dw[1]; ++}; ++ ++/* Memory BAR 2 - Low Address Register. */ ++struct BE_PCICFG_MEMBAR2_LO_CSR_AMAP { ++ u8 memspace; /* DWORD 0 */ ++ u8 type[2]; /* DWORD 0 */ ++ u8 pf; /* DWORD 0 */ ++ u8 rsvd0[17]; /* DWORD 0 */ ++ u8 membar2lo[11]; /* DWORD 0 */ ++} __packed; ++struct PCICFG_MEMBAR2_LO_CSR_AMAP { ++ u32 dw[1]; ++}; ++ ++/* Memory BAR 2 - High Address Register. */ ++struct BE_PCICFG_MEMBAR2_HI_CSR_AMAP { ++ u8 membar2hi[32]; /* DWORD 0 */ ++} __packed; ++struct PCICFG_MEMBAR2_HI_CSR_AMAP { ++ u32 dw[1]; ++}; ++ ++/* Subsystem Vendor and ID (Function 0) Register. */ ++struct BE_PCICFG_SUBSYSTEM_ID_F0_CSR_AMAP { ++ u8 subsys_vendor_id[16]; /* DWORD 0 */ ++ u8 subsys_id[16]; /* DWORD 0 */ ++} __packed; ++struct PCICFG_SUBSYSTEM_ID_F0_CSR_AMAP { ++ u32 dw[1]; ++}; ++ ++/* Subsystem Vendor and ID (Function 1) Register. */ ++struct BE_PCICFG_SUBSYSTEM_ID_F1_CSR_AMAP { ++ u8 subsys_vendor_id[16]; /* DWORD 0 */ ++ u8 subsys_id[16]; /* DWORD 0 */ ++} __packed; ++struct PCICFG_SUBSYSTEM_ID_F1_CSR_AMAP { ++ u32 dw[1]; ++}; ++ ++/* Semaphore Register. */ ++struct BE_PCICFG_SEMAPHORE_CSR_AMAP { ++ u8 locked; /* DWORD 0 */ ++ u8 rsvd0[31]; /* DWORD 0 */ ++} __packed; ++struct PCICFG_SEMAPHORE_CSR_AMAP { ++ u32 dw[1]; ++}; ++ ++/* Soft Reset Register. */ ++struct BE_PCICFG_SOFT_RESET_CSR_AMAP { ++ u8 rsvd0[7]; /* DWORD 0 */ ++ u8 softreset; /* DWORD 0 */ ++ u8 rsvd1[16]; /* DWORD 0 */ ++ u8 nec_ll_rcvdetect_i[8]; /* DWORD 0 */ ++} __packed; ++struct PCICFG_SOFT_RESET_CSR_AMAP { ++ u32 dw[1]; ++}; ++ ++/* Unrecoverable Error Status (Low) Register. Each bit corresponds to ++ * an internal Unrecoverable Error. These are set by hardware and may be ++ * cleared by writing a one to the respective bit(s) to be cleared. Any ++ * bit being set that is also unmasked will result in Unrecoverable Error ++ * interrupt notification to the host CPU and/or Server Management chip ++ * and the transitioning of BladeEngine to an Offline state. ++ */ ++struct BE_PCICFG_UE_STATUS_LOW_CSR_AMAP { ++ u8 cev_ue_status; /* DWORD 0 */ ++ u8 ctx_ue_status; /* DWORD 0 */ ++ u8 dbuf_ue_status; /* DWORD 0 */ ++ u8 erx_ue_status; /* DWORD 0 */ ++ u8 host_ue_status; /* DWORD 0 */ ++ u8 mpu_ue_status; /* DWORD 0 */ ++ u8 ndma_ue_status; /* DWORD 0 */ ++ u8 ptc_ue_status; /* DWORD 0 */ ++ u8 rdma_ue_status; /* DWORD 0 */ ++ u8 rxf_ue_status; /* DWORD 0 */ ++ u8 rxips_ue_status; /* DWORD 0 */ ++ u8 rxulp0_ue_status; /* DWORD 0 */ ++ u8 rxulp1_ue_status; /* DWORD 0 */ ++ u8 rxulp2_ue_status; /* DWORD 0 */ ++ u8 tim_ue_status; /* DWORD 0 */ ++ u8 tpost_ue_status; /* DWORD 0 */ ++ u8 tpre_ue_status; /* DWORD 0 */ ++ u8 txips_ue_status; /* DWORD 0 */ ++ u8 txulp0_ue_status; /* DWORD 0 */ ++ u8 txulp1_ue_status; /* DWORD 0 */ ++ u8 uc_ue_status; /* DWORD 0 */ ++ u8 wdma_ue_status; /* DWORD 0 */ ++ u8 txulp2_ue_status; /* DWORD 0 */ ++ u8 host1_ue_status; /* DWORD 0 */ ++ u8 p0_ob_link_ue_status; /* DWORD 0 */ ++ u8 p1_ob_link_ue_status; /* DWORD 0 */ ++ u8 host_gpio_ue_status; /* DWORD 0 */ ++ u8 mbox_netw_ue_status; /* DWORD 0 */ ++ u8 mbox_stor_ue_status; /* DWORD 0 */ ++ u8 axgmac0_ue_status; /* DWORD 0 */ ++ u8 axgmac1_ue_status; /* DWORD 0 */ ++ u8 mpu_intpend_ue_status; /* DWORD 0 */ ++} __packed; ++struct PCICFG_UE_STATUS_LOW_CSR_AMAP { ++ u32 dw[1]; ++}; ++ ++/* Unrecoverable Error Status (High) Register. Each bit corresponds to ++ * an internal Unrecoverable Error. These are set by hardware and may be ++ * cleared by writing a one to the respective bit(s) to be cleared. Any ++ * bit being set that is also unmasked will result in Unrecoverable Error ++ * interrupt notification to the host CPU and/or Server Management chip; ++ * and the transitioning of BladeEngine to an Offline state. ++ */ ++struct BE_PCICFG_UE_STATUS_HI_CSR_AMAP { ++ u8 jtag_ue_status; /* DWORD 0 */ ++ u8 lpcmemhost_ue_status; /* DWORD 0 */ ++ u8 mgmt_mac_ue_status; /* DWORD 0 */ ++ u8 mpu_iram_ue_status; /* DWORD 0 */ ++ u8 pcs0online_ue_status; /* DWORD 0 */ ++ u8 pcs1online_ue_status; /* DWORD 0 */ ++ u8 pctl0_ue_status; /* DWORD 0 */ ++ u8 pctl1_ue_status; /* DWORD 0 */ ++ u8 pmem_ue_status; /* DWORD 0 */ ++ u8 rr_ue_status; /* DWORD 0 */ ++ u8 rxpp_ue_status; /* DWORD 0 */ ++ u8 txpb_ue_status; /* DWORD 0 */ ++ u8 txp_ue_status; /* DWORD 0 */ ++ u8 xaui_ue_status; /* DWORD 0 */ ++ u8 arm_ue_status; /* DWORD 0 */ ++ u8 ipc_ue_status; /* DWORD 0 */ ++ u8 rsvd0[16]; /* DWORD 0 */ ++} __packed; ++struct PCICFG_UE_STATUS_HI_CSR_AMAP { ++ u32 dw[1]; ++}; ++ ++/* Unrecoverable Error Mask (Low) Register. Each bit, when set to one, ++ * will mask the associated Unrecoverable Error status bit from notification ++ * of Unrecoverable Error to the host CPU and/or Server Managment chip and the ++ * transitioning of all BladeEngine units to an Offline state. ++ */ ++struct BE_PCICFG_UE_STATUS_LOW_MASK_CSR_AMAP { ++ u8 cev_ue_mask; /* DWORD 0 */ ++ u8 ctx_ue_mask; /* DWORD 0 */ ++ u8 dbuf_ue_mask; /* DWORD 0 */ ++ u8 erx_ue_mask; /* DWORD 0 */ ++ u8 host_ue_mask; /* DWORD 0 */ ++ u8 mpu_ue_mask; /* DWORD 0 */ ++ u8 ndma_ue_mask; /* DWORD 0 */ ++ u8 ptc_ue_mask; /* DWORD 0 */ ++ u8 rdma_ue_mask; /* DWORD 0 */ ++ u8 rxf_ue_mask; /* DWORD 0 */ ++ u8 rxips_ue_mask; /* DWORD 0 */ ++ u8 rxulp0_ue_mask; /* DWORD 0 */ ++ u8 rxulp1_ue_mask; /* DWORD 0 */ ++ u8 rxulp2_ue_mask; /* DWORD 0 */ ++ u8 tim_ue_mask; /* DWORD 0 */ ++ u8 tpost_ue_mask; /* DWORD 0 */ ++ u8 tpre_ue_mask; /* DWORD 0 */ ++ u8 txips_ue_mask; /* DWORD 0 */ ++ u8 txulp0_ue_mask; /* DWORD 0 */ ++ u8 txulp1_ue_mask; /* DWORD 0 */ ++ u8 uc_ue_mask; /* DWORD 0 */ ++ u8 wdma_ue_mask; /* DWORD 0 */ ++ u8 txulp2_ue_mask; /* DWORD 0 */ ++ u8 host1_ue_mask; /* DWORD 0 */ ++ u8 p0_ob_link_ue_mask; /* DWORD 0 */ ++ u8 p1_ob_link_ue_mask; /* DWORD 0 */ ++ u8 host_gpio_ue_mask; /* DWORD 0 */ ++ u8 mbox_netw_ue_mask; /* DWORD 0 */ ++ u8 mbox_stor_ue_mask; /* DWORD 0 */ ++ u8 axgmac0_ue_mask; /* DWORD 0 */ ++ u8 axgmac1_ue_mask; /* DWORD 0 */ ++ u8 mpu_intpend_ue_mask; /* DWORD 0 */ ++} __packed; ++struct PCICFG_UE_STATUS_LOW_MASK_CSR_AMAP { ++ u32 dw[1]; ++}; ++ ++/* Unrecoverable Error Mask (High) Register. Each bit, when set to one, ++ * will mask the associated Unrecoverable Error status bit from notification ++ * of Unrecoverable Error to the host CPU and/or Server Managment chip and the ++ * transitioning of all BladeEngine units to an Offline state. ++ */ ++struct BE_PCICFG_UE_STATUS_HI_MASK_CSR_AMAP { ++ u8 jtag_ue_mask; /* DWORD 0 */ ++ u8 lpcmemhost_ue_mask; /* DWORD 0 */ ++ u8 mgmt_mac_ue_mask; /* DWORD 0 */ ++ u8 mpu_iram_ue_mask; /* DWORD 0 */ ++ u8 pcs0online_ue_mask; /* DWORD 0 */ ++ u8 pcs1online_ue_mask; /* DWORD 0 */ ++ u8 pctl0_ue_mask; /* DWORD 0 */ ++ u8 pctl1_ue_mask; /* DWORD 0 */ ++ u8 pmem_ue_mask; /* DWORD 0 */ ++ u8 rr_ue_mask; /* DWORD 0 */ ++ u8 rxpp_ue_mask; /* DWORD 0 */ ++ u8 txpb_ue_mask; /* DWORD 0 */ ++ u8 txp_ue_mask; /* DWORD 0 */ ++ u8 xaui_ue_mask; /* DWORD 0 */ ++ u8 arm_ue_mask; /* DWORD 0 */ ++ u8 ipc_ue_mask; /* DWORD 0 */ ++ u8 rsvd0[16]; /* DWORD 0 */ ++} __packed; ++struct PCICFG_UE_STATUS_HI_MASK_CSR_AMAP { ++ u32 dw[1]; ++}; ++ ++/* Online Control Register 0. This register controls various units within ++ * BladeEngine being in an Online or Offline state. ++ */ ++struct BE_PCICFG_ONLINE0_CSR_AMAP { ++ u8 cev_online; /* DWORD 0 */ ++ u8 ctx_online; /* DWORD 0 */ ++ u8 dbuf_online; /* DWORD 0 */ ++ u8 erx_online; /* DWORD 0 */ ++ u8 host_online; /* DWORD 0 */ ++ u8 mpu_online; /* DWORD 0 */ ++ u8 ndma_online; /* DWORD 0 */ ++ u8 ptc_online; /* DWORD 0 */ ++ u8 rdma_online; /* DWORD 0 */ ++ u8 rxf_online; /* DWORD 0 */ ++ u8 rxips_online; /* DWORD 0 */ ++ u8 rxulp0_online; /* DWORD 0 */ ++ u8 rxulp1_online; /* DWORD 0 */ ++ u8 rxulp2_online; /* DWORD 0 */ ++ u8 tim_online; /* DWORD 0 */ ++ u8 tpost_online; /* DWORD 0 */ ++ u8 tpre_online; /* DWORD 0 */ ++ u8 txips_online; /* DWORD 0 */ ++ u8 txulp0_online; /* DWORD 0 */ ++ u8 txulp1_online; /* DWORD 0 */ ++ u8 uc_online; /* DWORD 0 */ ++ u8 wdma_online; /* DWORD 0 */ ++ u8 txulp2_online; /* DWORD 0 */ ++ u8 host1_online; /* DWORD 0 */ ++ u8 p0_ob_link_online; /* DWORD 0 */ ++ u8 p1_ob_link_online; /* DWORD 0 */ ++ u8 host_gpio_online; /* DWORD 0 */ ++ u8 mbox_netw_online; /* DWORD 0 */ ++ u8 mbox_stor_online; /* DWORD 0 */ ++ u8 axgmac0_online; /* DWORD 0 */ ++ u8 axgmac1_online; /* DWORD 0 */ ++ u8 mpu_intpend_online; /* DWORD 0 */ ++} __packed; ++struct PCICFG_ONLINE0_CSR_AMAP { ++ u32 dw[1]; ++}; ++ ++/* Online Control Register 1. This register controls various units within ++ * BladeEngine being in an Online or Offline state. ++ */ ++struct BE_PCICFG_ONLINE1_CSR_AMAP { ++ u8 jtag_online; /* DWORD 0 */ ++ u8 lpcmemhost_online; /* DWORD 0 */ ++ u8 mgmt_mac_online; /* DWORD 0 */ ++ u8 mpu_iram_online; /* DWORD 0 */ ++ u8 pcs0online_online; /* DWORD 0 */ ++ u8 pcs1online_online; /* DWORD 0 */ ++ u8 pctl0_online; /* DWORD 0 */ ++ u8 pctl1_online; /* DWORD 0 */ ++ u8 pmem_online; /* DWORD 0 */ ++ u8 rr_online; /* DWORD 0 */ ++ u8 rxpp_online; /* DWORD 0 */ ++ u8 txpb_online; /* DWORD 0 */ ++ u8 txp_online; /* DWORD 0 */ ++ u8 xaui_online; /* DWORD 0 */ ++ u8 arm_online; /* DWORD 0 */ ++ u8 ipc_online; /* DWORD 0 */ ++ u8 rsvd0[16]; /* DWORD 0 */ ++} __packed; ++struct PCICFG_ONLINE1_CSR_AMAP { ++ u32 dw[1]; ++}; ++ ++/* Host Timer Register. */ ++struct BE_PCICFG_HOST_TIMER_INT_CTRL_CSR_AMAP { ++ u8 hosttimer[24]; /* DWORD 0 */ ++ u8 hostintr; /* DWORD 0 */ ++ u8 rsvd0[7]; /* DWORD 0 */ ++} __packed; ++struct PCICFG_HOST_TIMER_INT_CTRL_CSR_AMAP { ++ u32 dw[1]; ++}; ++ ++/* Scratchpad Register (for software use). */ ++struct BE_PCICFG_SCRATCHPAD_CSR_AMAP { ++ u8 scratchpad[32]; /* DWORD 0 */ ++} __packed; ++struct PCICFG_SCRATCHPAD_CSR_AMAP { ++ u32 dw[1]; ++}; ++ ++/* PCI Express Capabilities Register. */ ++struct BE_PCICFG_PCIE_CAP_CSR_AMAP { ++ u8 capid[8]; /* DWORD 0 */ ++ u8 nextcap[8]; /* DWORD 0 */ ++ u8 capver[4]; /* DWORD 0 */ ++ u8 devport[4]; /* DWORD 0 */ ++ u8 rsvd0[6]; /* DWORD 0 */ ++ u8 rsvd1[2]; /* DWORD 0 */ ++} __packed; ++struct PCICFG_PCIE_CAP_CSR_AMAP { ++ u32 dw[1]; ++}; ++ ++/* PCI Express Device Capabilities Register. */ ++struct BE_PCICFG_PCIE_DEVCAP_CSR_AMAP { ++ u8 payload[3]; /* DWORD 0 */ ++ u8 rsvd0[3]; /* DWORD 0 */ ++ u8 lo_lat[3]; /* DWORD 0 */ ++ u8 l1_lat[3]; /* DWORD 0 */ ++ u8 rsvd1[3]; /* DWORD 0 */ ++ u8 rsvd2[3]; /* DWORD 0 */ ++ u8 pwr_value[8]; /* DWORD 0 */ ++ u8 pwr_scale[2]; /* DWORD 0 */ ++ u8 rsvd3[4]; /* DWORD 0 */ ++} __packed; ++struct PCICFG_PCIE_DEVCAP_CSR_AMAP { ++ u32 dw[1]; ++}; ++ ++/* PCI Express Device Control/Status Registers. */ ++struct BE_PCICFG_PCIE_CONTROL_STATUS_CSR_AMAP { ++ u8 CorrErrReportEn; /* DWORD 0 */ ++ u8 NonFatalErrReportEn; /* DWORD 0 */ ++ u8 FatalErrReportEn; /* DWORD 0 */ ++ u8 UnsuppReqReportEn; /* DWORD 0 */ ++ u8 EnableRelaxOrder; /* DWORD 0 */ ++ u8 Max_Payload_Size[3]; /* DWORD 0 */ ++ u8 ExtendTagFieldEnable; /* DWORD 0 */ ++ u8 PhantomFnEnable; /* DWORD 0 */ ++ u8 AuxPwrPMEnable; /* DWORD 0 */ ++ u8 EnableNoSnoop; /* DWORD 0 */ ++ u8 Max_Read_Req_Size[3]; /* DWORD 0 */ ++ u8 rsvd0; /* DWORD 0 */ ++ u8 CorrErrDetect; /* DWORD 0 */ ++ u8 NonFatalErrDetect; /* DWORD 0 */ ++ u8 FatalErrDetect; /* DWORD 0 */ ++ u8 UnsuppReqDetect; /* DWORD 0 */ ++ u8 AuxPwrDetect; /* DWORD 0 */ ++ u8 TransPending; /* DWORD 0 */ ++ u8 rsvd1[10]; /* DWORD 0 */ ++} __packed; ++struct PCICFG_PCIE_CONTROL_STATUS_CSR_AMAP { ++ u32 dw[1]; ++}; ++ ++/* PCI Express Link Capabilities Register. */ ++struct BE_PCICFG_PCIE_LINK_CAP_CSR_AMAP { ++ u8 MaxLinkSpeed[4]; /* DWORD 0 */ ++ u8 MaxLinkWidth[6]; /* DWORD 0 */ ++ u8 ASPMSupport[2]; /* DWORD 0 */ ++ u8 L0sExitLat[3]; /* DWORD 0 */ ++ u8 L1ExitLat[3]; /* DWORD 0 */ ++ u8 rsvd0[6]; /* DWORD 0 */ ++ u8 PortNum[8]; /* DWORD 0 */ ++} __packed; ++struct PCICFG_PCIE_LINK_CAP_CSR_AMAP { ++ u32 dw[1]; ++}; ++ ++/* PCI Express Link Status Register. */ ++struct BE_PCICFG_PCIE_LINK_STATUS_CSR_AMAP { ++ u8 ASPMCtl[2]; /* DWORD 0 */ ++ u8 rsvd0; /* DWORD 0 */ ++ u8 ReadCmplBndry; /* DWORD 0 */ ++ u8 LinkDisable; /* DWORD 0 */ ++ u8 RetrainLink; /* DWORD 0 */ ++ u8 CommonClkConfig; /* DWORD 0 */ ++ u8 ExtendSync; /* DWORD 0 */ ++ u8 rsvd1[8]; /* DWORD 0 */ ++ u8 LinkSpeed[4]; /* DWORD 0 */ ++ u8 NegLinkWidth[6]; /* DWORD 0 */ ++ u8 LinkTrainErr; /* DWORD 0 */ ++ u8 LinkTrain; /* DWORD 0 */ ++ u8 SlotClkConfig; /* DWORD 0 */ ++ u8 rsvd2[3]; /* DWORD 0 */ ++} __packed; ++struct PCICFG_PCIE_LINK_STATUS_CSR_AMAP { ++ u32 dw[1]; ++}; ++ ++/* PCI Express MSI Configuration Register. */ ++struct BE_PCICFG_MSI_CSR_AMAP { ++ u8 capid[8]; /* DWORD 0 */ ++ u8 nextptr[8]; /* DWORD 0 */ ++ u8 tablesize[11]; /* DWORD 0 */ ++ u8 rsvd0[3]; /* DWORD 0 */ ++ u8 funcmask; /* DWORD 0 */ ++ u8 en; /* DWORD 0 */ ++} __packed; ++struct PCICFG_MSI_CSR_AMAP { ++ u32 dw[1]; ++}; ++ ++/* MSI-X Table Offset Register. */ ++struct BE_PCICFG_MSIX_TABLE_CSR_AMAP { ++ u8 tablebir[3]; /* DWORD 0 */ ++ u8 offset[29]; /* DWORD 0 */ ++} __packed; ++struct PCICFG_MSIX_TABLE_CSR_AMAP { ++ u32 dw[1]; ++}; ++ ++/* MSI-X PBA Offset Register. */ ++struct BE_PCICFG_MSIX_PBA_CSR_AMAP { ++ u8 pbabir[3]; /* DWORD 0 */ ++ u8 offset[29]; /* DWORD 0 */ ++} __packed; ++struct PCICFG_MSIX_PBA_CSR_AMAP { ++ u32 dw[1]; ++}; ++ ++/* PCI Express MSI-X Message Vector Control Register. */ ++struct BE_PCICFG_MSIX_VECTOR_CONTROL_CSR_AMAP { ++ u8 vector_control; /* DWORD 0 */ ++ u8 rsvd0[31]; /* DWORD 0 */ ++} __packed; ++struct PCICFG_MSIX_VECTOR_CONTROL_CSR_AMAP { ++ u32 dw[1]; ++}; ++ ++/* PCI Express MSI-X Message Data Register. */ ++struct BE_PCICFG_MSIX_MSG_DATA_CSR_AMAP { ++ u8 data[16]; /* DWORD 0 */ ++ u8 rsvd0[16]; /* DWORD 0 */ ++} __packed; ++struct PCICFG_MSIX_MSG_DATA_CSR_AMAP { ++ u32 dw[1]; ++}; ++ ++/* PCI Express MSI-X Message Address Register - High Part. */ ++struct BE_PCICFG_MSIX_MSG_ADDR_HI_CSR_AMAP { ++ u8 addr[32]; /* DWORD 0 */ ++} __packed; ++struct PCICFG_MSIX_MSG_ADDR_HI_CSR_AMAP { ++ u32 dw[1]; ++}; ++ ++/* PCI Express MSI-X Message Address Register - Low Part. */ ++struct BE_PCICFG_MSIX_MSG_ADDR_LO_CSR_AMAP { ++ u8 rsvd0[2]; /* DWORD 0 */ ++ u8 addr[30]; /* DWORD 0 */ ++} __packed; ++struct PCICFG_MSIX_MSG_ADDR_LO_CSR_AMAP { ++ u32 dw[1]; ++}; ++ ++struct BE_PCICFG_ANON_18_RSVD_AMAP { ++ u8 rsvd0[32]; /* DWORD 0 */ ++} __packed; ++struct PCICFG_ANON_18_RSVD_AMAP { ++ u32 dw[1]; ++}; ++ ++struct BE_PCICFG_ANON_19_RSVD_AMAP { ++ u8 rsvd0[32]; /* DWORD 0 */ ++} __packed; ++struct PCICFG_ANON_19_RSVD_AMAP { ++ u32 dw[1]; ++}; ++ ++struct BE_PCICFG_ANON_20_RSVD_AMAP { ++ u8 rsvd0[32]; /* DWORD 0 */ ++ u8 rsvd1[25][32]; /* DWORD 1 */ ++} __packed; ++struct PCICFG_ANON_20_RSVD_AMAP { ++ u32 dw[26]; ++}; ++ ++struct BE_PCICFG_ANON_21_RSVD_AMAP { ++ u8 rsvd0[32]; /* DWORD 0 */ ++ u8 rsvd1[1919][32]; /* DWORD 1 */ ++} __packed; ++struct PCICFG_ANON_21_RSVD_AMAP { ++ u32 dw[1920]; ++}; ++ ++struct BE_PCICFG_ANON_22_MESSAGE_AMAP { ++ struct BE_PCICFG_MSIX_VECTOR_CONTROL_CSR_AMAP vec_ctrl; ++ struct BE_PCICFG_MSIX_MSG_DATA_CSR_AMAP msg_data; ++ struct BE_PCICFG_MSIX_MSG_ADDR_HI_CSR_AMAP addr_hi; ++ struct BE_PCICFG_MSIX_MSG_ADDR_LO_CSR_AMAP addr_low; ++} __packed; ++struct PCICFG_ANON_22_MESSAGE_AMAP { ++ u32 dw[4]; ++}; ++ ++struct BE_PCICFG_ANON_23_RSVD_AMAP { ++ u8 rsvd0[32]; /* DWORD 0 */ ++ u8 rsvd1[895][32]; /* DWORD 1 */ ++} __packed; ++struct PCICFG_ANON_23_RSVD_AMAP { ++ u32 dw[896]; ++}; ++ ++/* These PCI Configuration Space registers are for the Storage Function of ++ * BladeEngine (Function 0). In the memory map of the registers below their ++ * table, ++ */ ++struct BE_PCICFG0_CSRMAP_AMAP { ++ struct BE_PCICFG_ID_CSR_AMAP id; ++ u8 rsvd0[32]; /* DWORD 1 */ ++ u8 rsvd1[32]; /* DWORD 2 */ ++ u8 rsvd2[32]; /* DWORD 3 */ ++ struct BE_PCICFG_IOBAR_CSR_AMAP iobar; ++ struct BE_PCICFG_MEMBAR0_CSR_AMAP membar0; ++ struct BE_PCICFG_MEMBAR1_LO_CSR_AMAP membar1_lo; ++ struct BE_PCICFG_MEMBAR1_HI_CSR_AMAP membar1_hi; ++ struct BE_PCICFG_MEMBAR2_LO_CSR_AMAP membar2_lo; ++ struct BE_PCICFG_MEMBAR2_HI_CSR_AMAP membar2_hi; ++ u8 rsvd3[32]; /* DWORD 10 */ ++ struct BE_PCICFG_SUBSYSTEM_ID_F0_CSR_AMAP subsystem_id; ++ u8 rsvd4[32]; /* DWORD 12 */ ++ u8 rsvd5[32]; /* DWORD 13 */ ++ u8 rsvd6[32]; /* DWORD 14 */ ++ u8 rsvd7[32]; /* DWORD 15 */ ++ struct BE_PCICFG_SEMAPHORE_CSR_AMAP semaphore[4]; ++ struct BE_PCICFG_SOFT_RESET_CSR_AMAP soft_reset; ++ u8 rsvd8[32]; /* DWORD 21 */ ++ struct BE_PCICFG_SCRATCHPAD_CSR_AMAP scratchpad; ++ u8 rsvd9[32]; /* DWORD 23 */ ++ u8 rsvd10[32]; /* DWORD 24 */ ++ u8 rsvd11[32]; /* DWORD 25 */ ++ u8 rsvd12[32]; /* DWORD 26 */ ++ u8 rsvd13[32]; /* DWORD 27 */ ++ u8 rsvd14[2][32]; /* DWORD 28 */ ++ u8 rsvd15[32]; /* DWORD 30 */ ++ u8 rsvd16[32]; /* DWORD 31 */ ++ u8 rsvd17[8][32]; /* DWORD 32 */ ++ struct BE_PCICFG_UE_STATUS_LOW_CSR_AMAP ue_status_low; ++ struct BE_PCICFG_UE_STATUS_HI_CSR_AMAP ue_status_hi; ++ struct BE_PCICFG_UE_STATUS_LOW_MASK_CSR_AMAP ue_status_low_mask; ++ struct BE_PCICFG_UE_STATUS_HI_MASK_CSR_AMAP ue_status_hi_mask; ++ struct BE_PCICFG_ONLINE0_CSR_AMAP online0; ++ struct BE_PCICFG_ONLINE1_CSR_AMAP online1; ++ u8 rsvd18[32]; /* DWORD 46 */ ++ u8 rsvd19[32]; /* DWORD 47 */ ++ u8 rsvd20[32]; /* DWORD 48 */ ++ u8 rsvd21[32]; /* DWORD 49 */ ++ struct BE_PCICFG_HOST_TIMER_INT_CTRL_CSR_AMAP host_timer_int_ctrl; ++ u8 rsvd22[32]; /* DWORD 51 */ ++ struct BE_PCICFG_PCIE_CAP_CSR_AMAP pcie_cap; ++ struct BE_PCICFG_PCIE_DEVCAP_CSR_AMAP pcie_devcap; ++ struct BE_PCICFG_PCIE_CONTROL_STATUS_CSR_AMAP pcie_control_status; ++ struct BE_PCICFG_PCIE_LINK_CAP_CSR_AMAP pcie_link_cap; ++ struct BE_PCICFG_PCIE_LINK_STATUS_CSR_AMAP pcie_link_status; ++ struct BE_PCICFG_MSI_CSR_AMAP msi; ++ struct BE_PCICFG_MSIX_TABLE_CSR_AMAP msix_table_offset; ++ struct BE_PCICFG_MSIX_PBA_CSR_AMAP msix_pba_offset; ++ u8 rsvd23[32]; /* DWORD 60 */ ++ u8 rsvd24[32]; /* DWORD 61 */ ++ u8 rsvd25[32]; /* DWORD 62 */ ++ u8 rsvd26[32]; /* DWORD 63 */ ++ u8 rsvd27[32]; /* DWORD 64 */ ++ u8 rsvd28[32]; /* DWORD 65 */ ++ u8 rsvd29[32]; /* DWORD 66 */ ++ u8 rsvd30[32]; /* DWORD 67 */ ++ u8 rsvd31[32]; /* DWORD 68 */ ++ u8 rsvd32[32]; /* DWORD 69 */ ++ u8 rsvd33[32]; /* DWORD 70 */ ++ u8 rsvd34[32]; /* DWORD 71 */ ++ u8 rsvd35[32]; /* DWORD 72 */ ++ u8 rsvd36[32]; /* DWORD 73 */ ++ u8 rsvd37[32]; /* DWORD 74 */ ++ u8 rsvd38[32]; /* DWORD 75 */ ++ u8 rsvd39[32]; /* DWORD 76 */ ++ u8 rsvd40[32]; /* DWORD 77 */ ++ u8 rsvd41[32]; /* DWORD 78 */ ++ u8 rsvd42[32]; /* DWORD 79 */ ++ u8 rsvd43[32]; /* DWORD 80 */ ++ u8 rsvd44[32]; /* DWORD 81 */ ++ u8 rsvd45[32]; /* DWORD 82 */ ++ u8 rsvd46[32]; /* DWORD 83 */ ++ u8 rsvd47[32]; /* DWORD 84 */ ++ u8 rsvd48[32]; /* DWORD 85 */ ++ u8 rsvd49[32]; /* DWORD 86 */ ++ u8 rsvd50[32]; /* DWORD 87 */ ++ u8 rsvd51[32]; /* DWORD 88 */ ++ u8 rsvd52[32]; /* DWORD 89 */ ++ u8 rsvd53[32]; /* DWORD 90 */ ++ u8 rsvd54[32]; /* DWORD 91 */ ++ u8 rsvd55[32]; /* DWORD 92 */ ++ u8 rsvd56[832]; /* DWORD 93 */ ++ u8 rsvd57[32]; /* DWORD 119 */ ++ u8 rsvd58[32]; /* DWORD 120 */ ++ u8 rsvd59[32]; /* DWORD 121 */ ++ u8 rsvd60[32]; /* DWORD 122 */ ++ u8 rsvd61[32]; /* DWORD 123 */ ++ u8 rsvd62[32]; /* DWORD 124 */ ++ u8 rsvd63[32]; /* DWORD 125 */ ++ u8 rsvd64[32]; /* DWORD 126 */ ++ u8 rsvd65[32]; /* DWORD 127 */ ++ u8 rsvd66[61440]; /* DWORD 128 */ ++ struct BE_PCICFG_ANON_22_MESSAGE_AMAP message[32]; ++ u8 rsvd67[28672]; /* DWORD 2176 */ ++ u8 rsvd68[32]; /* DWORD 3072 */ ++ u8 rsvd69[1023][32]; /* DWORD 3073 */ ++} __packed; ++struct PCICFG0_CSRMAP_AMAP { ++ u32 dw[4096]; ++}; ++ ++struct BE_PCICFG_ANON_24_RSVD_AMAP { ++ u8 rsvd0[32]; /* DWORD 0 */ ++} __packed; ++struct PCICFG_ANON_24_RSVD_AMAP { ++ u32 dw[1]; ++}; ++ ++struct BE_PCICFG_ANON_25_RSVD_AMAP { ++ u8 rsvd0[32]; /* DWORD 0 */ ++} __packed; ++struct PCICFG_ANON_25_RSVD_AMAP { ++ u32 dw[1]; ++}; ++ ++struct BE_PCICFG_ANON_26_RSVD_AMAP { ++ u8 rsvd0[32]; /* DWORD 0 */ ++} __packed; ++struct PCICFG_ANON_26_RSVD_AMAP { ++ u32 dw[1]; ++}; ++ ++struct BE_PCICFG_ANON_27_RSVD_AMAP { ++ u8 rsvd0[32]; /* DWORD 0 */ ++ u8 rsvd1[32]; /* DWORD 1 */ ++} __packed; ++struct PCICFG_ANON_27_RSVD_AMAP { ++ u32 dw[2]; ++}; ++ ++struct BE_PCICFG_ANON_28_RSVD_AMAP { ++ u8 rsvd0[32]; /* DWORD 0 */ ++ u8 rsvd1[3][32]; /* DWORD 1 */ ++} __packed; ++struct PCICFG_ANON_28_RSVD_AMAP { ++ u32 dw[4]; ++}; ++ ++struct BE_PCICFG_ANON_29_RSVD_AMAP { ++ u8 rsvd0[32]; /* DWORD 0 */ ++ u8 rsvd1[36][32]; /* DWORD 1 */ ++} __packed; ++struct PCICFG_ANON_29_RSVD_AMAP { ++ u32 dw[37]; ++}; ++ ++struct BE_PCICFG_ANON_30_RSVD_AMAP { ++ u8 rsvd0[32]; /* DWORD 0 */ ++ u8 rsvd1[1930][32]; /* DWORD 1 */ ++} __packed; ++struct PCICFG_ANON_30_RSVD_AMAP { ++ u32 dw[1931]; ++}; ++ ++struct BE_PCICFG_ANON_31_MESSAGE_AMAP { ++ struct BE_PCICFG_MSIX_VECTOR_CONTROL_CSR_AMAP vec_ctrl; ++ struct BE_PCICFG_MSIX_MSG_DATA_CSR_AMAP msg_data; ++ struct BE_PCICFG_MSIX_MSG_ADDR_HI_CSR_AMAP addr_hi; ++ struct BE_PCICFG_MSIX_MSG_ADDR_LO_CSR_AMAP addr_low; ++} __packed; ++struct PCICFG_ANON_31_MESSAGE_AMAP { ++ u32 dw[4]; ++}; ++ ++struct BE_PCICFG_ANON_32_RSVD_AMAP { ++ u8 rsvd0[32]; /* DWORD 0 */ ++ u8 rsvd1[895][32]; /* DWORD 1 */ ++} __packed; ++struct PCICFG_ANON_32_RSVD_AMAP { ++ u32 dw[896]; ++}; ++ ++/* This PCI configuration space register map is for the Networking Function of ++ * BladeEngine (Function 1). ++ */ ++struct BE_PCICFG1_CSRMAP_AMAP { ++ struct BE_PCICFG_ID_CSR_AMAP id; ++ u8 rsvd0[32]; /* DWORD 1 */ ++ u8 rsvd1[32]; /* DWORD 2 */ ++ u8 rsvd2[32]; /* DWORD 3 */ ++ struct BE_PCICFG_IOBAR_CSR_AMAP iobar; ++ struct BE_PCICFG_MEMBAR0_CSR_AMAP membar0; ++ struct BE_PCICFG_MEMBAR1_LO_CSR_AMAP membar1_lo; ++ struct BE_PCICFG_MEMBAR1_HI_CSR_AMAP membar1_hi; ++ struct BE_PCICFG_MEMBAR2_LO_CSR_AMAP membar2_lo; ++ struct BE_PCICFG_MEMBAR2_HI_CSR_AMAP membar2_hi; ++ u8 rsvd3[32]; /* DWORD 10 */ ++ struct BE_PCICFG_SUBSYSTEM_ID_F1_CSR_AMAP subsystem_id; ++ u8 rsvd4[32]; /* DWORD 12 */ ++ u8 rsvd5[32]; /* DWORD 13 */ ++ u8 rsvd6[32]; /* DWORD 14 */ ++ u8 rsvd7[32]; /* DWORD 15 */ ++ struct BE_PCICFG_SEMAPHORE_CSR_AMAP semaphore[4]; ++ struct BE_PCICFG_SOFT_RESET_CSR_AMAP soft_reset; ++ u8 rsvd8[32]; /* DWORD 21 */ ++ struct BE_PCICFG_SCRATCHPAD_CSR_AMAP scratchpad; ++ u8 rsvd9[32]; /* DWORD 23 */ ++ u8 rsvd10[32]; /* DWORD 24 */ ++ u8 rsvd11[32]; /* DWORD 25 */ ++ u8 rsvd12[32]; /* DWORD 26 */ ++ u8 rsvd13[32]; /* DWORD 27 */ ++ u8 rsvd14[2][32]; /* DWORD 28 */ ++ u8 rsvd15[32]; /* DWORD 30 */ ++ u8 rsvd16[32]; /* DWORD 31 */ ++ u8 rsvd17[8][32]; /* DWORD 32 */ ++ struct BE_PCICFG_UE_STATUS_LOW_CSR_AMAP ue_status_low; ++ struct BE_PCICFG_UE_STATUS_HI_CSR_AMAP ue_status_hi; ++ struct BE_PCICFG_UE_STATUS_LOW_MASK_CSR_AMAP ue_status_low_mask; ++ struct BE_PCICFG_UE_STATUS_HI_MASK_CSR_AMAP ue_status_hi_mask; ++ struct BE_PCICFG_ONLINE0_CSR_AMAP online0; ++ struct BE_PCICFG_ONLINE1_CSR_AMAP online1; ++ u8 rsvd18[32]; /* DWORD 46 */ ++ u8 rsvd19[32]; /* DWORD 47 */ ++ u8 rsvd20[32]; /* DWORD 48 */ ++ u8 rsvd21[32]; /* DWORD 49 */ ++ struct BE_PCICFG_HOST_TIMER_INT_CTRL_CSR_AMAP host_timer_int_ctrl; ++ u8 rsvd22[32]; /* DWORD 51 */ ++ struct BE_PCICFG_PCIE_CAP_CSR_AMAP pcie_cap; ++ struct BE_PCICFG_PCIE_DEVCAP_CSR_AMAP pcie_devcap; ++ struct BE_PCICFG_PCIE_CONTROL_STATUS_CSR_AMAP pcie_control_status; ++ struct BE_PCICFG_PCIE_LINK_CAP_CSR_AMAP pcie_link_cap; ++ struct BE_PCICFG_PCIE_LINK_STATUS_CSR_AMAP pcie_link_status; ++ struct BE_PCICFG_MSI_CSR_AMAP msi; ++ struct BE_PCICFG_MSIX_TABLE_CSR_AMAP msix_table_offset; ++ struct BE_PCICFG_MSIX_PBA_CSR_AMAP msix_pba_offset; ++ u8 rsvd23[64]; /* DWORD 60 */ ++ u8 rsvd24[32]; /* DWORD 62 */ ++ u8 rsvd25[32]; /* DWORD 63 */ ++ u8 rsvd26[32]; /* DWORD 64 */ ++ u8 rsvd27[32]; /* DWORD 65 */ ++ u8 rsvd28[32]; /* DWORD 66 */ ++ u8 rsvd29[32]; /* DWORD 67 */ ++ u8 rsvd30[32]; /* DWORD 68 */ ++ u8 rsvd31[32]; /* DWORD 69 */ ++ u8 rsvd32[32]; /* DWORD 70 */ ++ u8 rsvd33[32]; /* DWORD 71 */ ++ u8 rsvd34[32]; /* DWORD 72 */ ++ u8 rsvd35[32]; /* DWORD 73 */ ++ u8 rsvd36[32]; /* DWORD 74 */ ++ u8 rsvd37[128]; /* DWORD 75 */ ++ u8 rsvd38[32]; /* DWORD 79 */ ++ u8 rsvd39[1184]; /* DWORD 80 */ ++ u8 rsvd40[61792]; /* DWORD 117 */ ++ struct BE_PCICFG_ANON_31_MESSAGE_AMAP message[32]; ++ u8 rsvd41[28672]; /* DWORD 2176 */ ++ u8 rsvd42[32]; /* DWORD 3072 */ ++ u8 rsvd43[1023][32]; /* DWORD 3073 */ ++} __packed; ++struct PCICFG1_CSRMAP_AMAP { ++ u32 dw[4096]; ++}; ++ ++#endif /* __pcicfg_amap_h__ */ +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/drivers/staging/benet/post_codes.h linux-2.6.29-rc3.owrt/drivers/staging/benet/post_codes.h +--- linux-2.6.29.owrt/drivers/staging/benet/post_codes.h 1970-01-01 01:00:00.000000000 +0100 ++++ linux-2.6.29-rc3.owrt/drivers/staging/benet/post_codes.h 2009-05-10 23:48:29.000000000 +0200 +@@ -0,0 +1,111 @@ ++/* ++ * Copyright (C) 2005 - 2008 ServerEngines ++ * All rights reserved. ++ * ++ * 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. The full GNU General ++ * Public License is included in this distribution in the file called COPYING. ++ * ++ * Contact Information: ++ * linux-drivers@serverengines.com ++ * ++ * ServerEngines ++ * 209 N. Fair Oaks Ave ++ * Sunnyvale, CA 94085 ++ */ ++/* ++ * Autogenerated by srcgen version: 0127 ++ */ ++#ifndef __post_codes_amap_h__ ++#define __post_codes_amap_h__ ++ ++/* --- MGMT_HBA_POST_STAGE_ENUM --- */ ++#define POST_STAGE_POWER_ON_RESET (0) /* State after a cold or warm boot. */ ++#define POST_STAGE_AWAITING_HOST_RDY (1) /* ARM boot code awaiting a ++ go-ahed from the host. */ ++#define POST_STAGE_HOST_RDY (2) /* Host has given go-ahed to ARM. */ ++#define POST_STAGE_BE_RESET (3) /* Host wants to reset chip, this is a chip ++ workaround */ ++#define POST_STAGE_SEEPROM_CS_START (256) /* SEEPROM checksum ++ test start. */ ++#define POST_STAGE_SEEPROM_CS_DONE (257) /* SEEPROM checksum test ++ done. */ ++#define POST_STAGE_DDR_CONFIG_START (512) /* DDR configuration start. */ ++#define POST_STAGE_DDR_CONFIG_DONE (513) /* DDR configuration done. */ ++#define POST_STAGE_DDR_CALIBRATE_START (768) /* DDR calibration start. */ ++#define POST_STAGE_DDR_CALIBRATE_DONE (769) /* DDR calibration done. */ ++#define POST_STAGE_DDR_TEST_START (1024) /* DDR memory test start. */ ++#define POST_STAGE_DDR_TEST_DONE (1025) /* DDR memory test done. */ ++#define POST_STAGE_REDBOOT_INIT_START (1536) /* Redboot starts execution. */ ++#define POST_STAGE_REDBOOT_INIT_DONE (1537) /* Redboot done execution. */ ++#define POST_STAGE_FW_IMAGE_LOAD_START (1792) /* Firmware image load to ++ DDR start. */ ++#define POST_STAGE_FW_IMAGE_LOAD_DONE (1793) /* Firmware image load ++ to DDR done. */ ++#define POST_STAGE_ARMFW_START (2048) /* ARMfw runtime code ++ starts execution. */ ++#define POST_STAGE_DHCP_QUERY_START (2304) /* DHCP server query start. */ ++#define POST_STAGE_DHCP_QUERY_DONE (2305) /* DHCP server query done. */ ++#define POST_STAGE_BOOT_TARGET_DISCOVERY_START (2560) /* Boot Target ++ Discovery Start. */ ++#define POST_STAGE_BOOT_TARGET_DISCOVERY_DONE (2561) /* Boot Target ++ Discovery Done. */ ++#define POST_STAGE_RC_OPTION_SET (2816) /* Remote configuration ++ option is set in SEEPROM */ ++#define POST_STAGE_SWITCH_LINK (2817) /* Wait for link up on switch */ ++#define POST_STAGE_SEND_ICDS_MESSAGE (2818) /* Send the ICDS message ++ to switch */ ++#define POST_STAGE_PERFROM_TFTP (2819) /* Download xml using TFTP */ ++#define POST_STAGE_PARSE_XML (2820) /* Parse XML file */ ++#define POST_STAGE_DOWNLOAD_IMAGE (2821) /* Download IMAGE from ++ TFTP server */ ++#define POST_STAGE_FLASH_IMAGE (2822) /* Flash the IMAGE */ ++#define POST_STAGE_RC_DONE (2823) /* Remote configuration ++ complete */ ++#define POST_STAGE_REBOOT_SYSTEM (2824) /* Upgrade IMAGE done, ++ reboot required */ ++#define POST_STAGE_MAC_ADDRESS (3072) /* MAC Address Check */ ++#define POST_STAGE_ARMFW_READY (49152) /* ARMfw is done with POST ++ and ready. */ ++#define POST_STAGE_ARMFW_UE (61440) /* ARMfw has asserted an ++ unrecoverable error. The ++ lower 3 hex digits of the ++ stage code identify the ++ unique error code. ++ */ ++ ++/* This structure defines the format of the MPU semaphore ++ * register when used for POST. ++ */ ++struct BE_MGMT_HBA_POST_STATUS_STRUCT_AMAP { ++ u8 stage[16]; /* DWORD 0 */ ++ u8 rsvd0[10]; /* DWORD 0 */ ++ u8 iscsi_driver_loaded; /* DWORD 0 */ ++ u8 option_rom_installed; /* DWORD 0 */ ++ u8 iscsi_ip_conflict; /* DWORD 0 */ ++ u8 iscsi_no_ip; /* DWORD 0 */ ++ u8 backup_fw; /* DWORD 0 */ ++ u8 error; /* DWORD 0 */ ++} __packed; ++struct MGMT_HBA_POST_STATUS_STRUCT_AMAP { ++ u32 dw[1]; ++}; ++ ++/* --- MGMT_HBA_POST_DUMMY_BITS_ENUM --- */ ++#define POST_BIT_ISCSI_LOADED (26) ++#define POST_BIT_OPTROM_INST (27) ++#define POST_BIT_BAD_IP_ADDR (28) ++#define POST_BIT_NO_IP_ADDR (29) ++#define POST_BIT_BACKUP_FW (30) ++#define POST_BIT_ERROR (31) ++ ++/* --- MGMT_HBA_POST_DUMMY_VALUES_ENUM --- */ ++#define POST_ISCSI_DRIVER_LOADED (67108864) ++#define POST_OPTROM_INSTALLED (134217728) ++#define POST_ISCSI_IP_ADDRESS_CONFLICT (268435456) ++#define POST_ISCSI_NO_IP_ADDRESS (536870912) ++#define POST_BACKUP_FW_LOADED (1073741824) ++#define POST_FATAL_ERROR (2147483648) ++ ++#endif /* __post_codes_amap_h__ */ +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/drivers/staging/benet/regmap.h linux-2.6.29-rc3.owrt/drivers/staging/benet/regmap.h +--- linux-2.6.29.owrt/drivers/staging/benet/regmap.h 1970-01-01 01:00:00.000000000 +0100 ++++ linux-2.6.29-rc3.owrt/drivers/staging/benet/regmap.h 2009-05-10 23:48:29.000000000 +0200 +@@ -0,0 +1,68 @@ ++/* ++ * Copyright (C) 2005 - 2008 ServerEngines ++ * All rights reserved. ++ * ++ * 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. The full GNU General ++ * Public License is included in this distribution in the file called COPYING. ++ * ++ * Contact Information: ++ * linux-drivers@serverengines.com ++ * ++ * ServerEngines ++ * 209 N. Fair Oaks Ave ++ * Sunnyvale, CA 94085 ++ */ ++/* ++ * Autogenerated by srcgen version: 0127 ++ */ ++#ifndef __regmap_amap_h__ ++#define __regmap_amap_h__ ++#include "pcicfg.h" ++#include "ep.h" ++#include "cev.h" ++#include "mpu.h" ++#include "doorbells.h" ++ ++/* ++ * This is the control and status register map for BladeEngine, showing ++ * the relative size and offset of each sub-module. The CSR registers ++ * are identical for the network and storage PCI functions. The ++ * CSR map is shown below, followed by details of each block, ++ * in sub-sections. The sub-sections begin with a description ++ * of CSRs that are instantiated in multiple blocks. ++ */ ++struct BE_BLADE_ENGINE_CSRMAP_AMAP { ++ struct BE_MPU_CSRMAP_AMAP mpu; ++ u8 rsvd0[8192]; /* DWORD 256 */ ++ u8 rsvd1[8192]; /* DWORD 512 */ ++ struct BE_CEV_CSRMAP_AMAP cev; ++ u8 rsvd2[8192]; /* DWORD 1024 */ ++ u8 rsvd3[8192]; /* DWORD 1280 */ ++ u8 rsvd4[8192]; /* DWORD 1536 */ ++ u8 rsvd5[8192]; /* DWORD 1792 */ ++ u8 rsvd6[8192]; /* DWORD 2048 */ ++ u8 rsvd7[8192]; /* DWORD 2304 */ ++ u8 rsvd8[8192]; /* DWORD 2560 */ ++ u8 rsvd9[8192]; /* DWORD 2816 */ ++ u8 rsvd10[8192]; /* DWORD 3072 */ ++ u8 rsvd11[8192]; /* DWORD 3328 */ ++ u8 rsvd12[8192]; /* DWORD 3584 */ ++ u8 rsvd13[8192]; /* DWORD 3840 */ ++ u8 rsvd14[8192]; /* DWORD 4096 */ ++ u8 rsvd15[8192]; /* DWORD 4352 */ ++ u8 rsvd16[8192]; /* DWORD 4608 */ ++ u8 rsvd17[8192]; /* DWORD 4864 */ ++ u8 rsvd18[8192]; /* DWORD 5120 */ ++ u8 rsvd19[8192]; /* DWORD 5376 */ ++ u8 rsvd20[8192]; /* DWORD 5632 */ ++ u8 rsvd21[8192]; /* DWORD 5888 */ ++ u8 rsvd22[8192]; /* DWORD 6144 */ ++ u8 rsvd23[17152][32]; /* DWORD 6400 */ ++} __packed; ++struct BLADE_ENGINE_CSRMAP_AMAP { ++ u32 dw[23552]; ++}; ++ ++#endif /* __regmap_amap_h__ */ +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/drivers/staging/benet/TODO linux-2.6.29-rc3.owrt/drivers/staging/benet/TODO +--- linux-2.6.29.owrt/drivers/staging/benet/TODO 1970-01-01 01:00:00.000000000 +0100 ++++ linux-2.6.29-rc3.owrt/drivers/staging/benet/TODO 2009-05-10 23:48:29.000000000 +0200 +@@ -0,0 +1,6 @@ ++TODO: ++ - remove wrappers around common iowrite functions ++ - full netdev audit of common problems/issues ++ ++Please send all patches and questions to Subbu Seetharaman ++<subbus@serverengines.com> and Greg Kroah-Hartman <greg@kroah.com> +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/drivers/staging/comedi/Kconfig linux-2.6.29-rc3.owrt/drivers/staging/comedi/Kconfig +--- linux-2.6.29.owrt/drivers/staging/comedi/Kconfig 2009-05-10 22:04:38.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/drivers/staging/comedi/Kconfig 2009-05-10 23:48:29.000000000 +0200 +@@ -1,7 +1,6 @@ + config COMEDI + tristate "Data Acquision support (comedi)" + default N +- depends on m + ---help--- + Enable support a wide range of data acquision devices + for Linux. +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/drivers/staging/Kconfig linux-2.6.29-rc3.owrt/drivers/staging/Kconfig +--- linux-2.6.29.owrt/drivers/staging/Kconfig 2009-05-10 22:04:38.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/drivers/staging/Kconfig 2009-05-10 23:48:29.000000000 +0200 +@@ -73,6 +73,8 @@ + + source "drivers/staging/rt2870/Kconfig" + ++source "drivers/staging/benet/Kconfig" ++ + source "drivers/staging/comedi/Kconfig" + + source "drivers/staging/asus_oled/Kconfig" +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/drivers/staging/Makefile linux-2.6.29-rc3.owrt/drivers/staging/Makefile +--- linux-2.6.29.owrt/drivers/staging/Makefile 2009-05-10 22:04:38.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/drivers/staging/Makefile 2009-05-10 23:48:29.000000000 +0200 +@@ -19,6 +19,7 @@ + obj-$(CONFIG_OTUS) += otus/ + obj-$(CONFIG_RT2860) += rt2860/ + obj-$(CONFIG_RT2870) += rt2870/ ++obj-$(CONFIG_BENET) += benet/ + obj-$(CONFIG_COMEDI) += comedi/ + obj-$(CONFIG_ASUS_OLED) += asus_oled/ + obj-$(CONFIG_PANEL) += panel/ +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/drivers/staging/meilhaus/Kconfig linux-2.6.29-rc3.owrt/drivers/staging/meilhaus/Kconfig +--- linux-2.6.29.owrt/drivers/staging/meilhaus/Kconfig 2009-05-10 22:04:38.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/drivers/staging/meilhaus/Kconfig 2009-05-10 23:48:29.000000000 +0200 +@@ -4,7 +4,6 @@ + + menuconfig MEILHAUS + tristate "Meilhaus support" +- depends on m + ---help--- + If you have a Meilhaus card, say Y (or M) here. + +@@ -19,7 +18,7 @@ + config ME0600 + tristate "Meilhaus ME-600 support" + default n +- depends on PCI && m ++ depends on PCI + help + This driver supports the Meilhaus ME-600 family of boards + that do data collection and multipurpose I/O. +@@ -30,7 +29,7 @@ + config ME0900 + tristate "Meilhaus ME-900 support" + default n +- depends on PCI && m ++ depends on PCI + help + This driver supports the Meilhaus ME-900 family of boards + that do data collection and multipurpose I/O. +@@ -41,7 +40,7 @@ + config ME1000 + tristate "Meilhaus ME-1000 support" + default n +- depends on PCI && m ++ depends on PCI + help + This driver supports the Meilhaus ME-1000 family of boards + that do data collection and multipurpose I/O. +@@ -52,7 +51,7 @@ + config ME1400 + tristate "Meilhaus ME-1400 support" + default n +- depends on PCI && m ++ depends on PCI + help + This driver supports the Meilhaus ME-1400 family of boards + that do data collection and multipurpose I/O. +@@ -63,7 +62,7 @@ + config ME1600 + tristate "Meilhaus ME-1600 support" + default n +- depends on PCI && m ++ depends on PCI + help + This driver supports the Meilhaus ME-1600 family of boards + that do data collection and multipurpose I/O. +@@ -74,7 +73,7 @@ + config ME4600 + tristate "Meilhaus ME-4600 support" + default n +- depends on PCI && m ++ depends on PCI + help + This driver supports the Meilhaus ME-4600 family of boards + that do data collection and multipurpose I/O. +@@ -85,7 +84,7 @@ + config ME6000 + tristate "Meilhaus ME-6000 support" + default n +- depends on PCI && m ++ depends on PCI + help + This driver supports the Meilhaus ME-6000 family of boards + that do data collection and multipurpose I/O. +@@ -96,7 +95,7 @@ + config ME8100 + tristate "Meilhaus ME-8100 support" + default n +- depends on PCI && m ++ depends on PCI + help + This driver supports the Meilhaus ME-8100 family of boards + that do data collection and multipurpose I/O. +@@ -107,7 +106,7 @@ + config ME8200 + tristate "Meilhaus ME-8200 support" + default n +- depends on PCI && m ++ depends on PCI + help + This driver supports the Meilhaus ME-8200 family of boards + that do data collection and multipurpose I/O. +@@ -118,7 +117,7 @@ + config MEDUMMY + tristate "Meilhaus dummy driver" + default n +- depends on PCI && m ++ depends on PCI + help + This provides a dummy driver for the Meilhaus driver package + +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/drivers/staging/panel/panel.c linux-2.6.29-rc3.owrt/drivers/staging/panel/panel.c +--- linux-2.6.29.owrt/drivers/staging/panel/panel.c 2009-05-10 22:04:38.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/drivers/staging/panel/panel.c 2009-05-10 23:48:29.000000000 +0200 +@@ -622,7 +622,7 @@ + } + + /* sets ctrl & data port bits according to current signals values */ +-static void panel_set_bits(void) ++static void set_bits(void) + { + set_data_bits(); + set_ctrl_bits(); +@@ -707,12 +707,12 @@ + */ + for (bit = 0; bit < 8; bit++) { + bits.cl = BIT_CLR; /* CLK low */ +- panel_set_bits(); ++ set_bits(); + bits.da = byte & 1; +- panel_set_bits(); ++ set_bits(); + udelay(2); /* maintain the data during 2 us before CLK up */ + bits.cl = BIT_SET; /* CLK high */ +- panel_set_bits(); ++ set_bits(); + udelay(1); /* maintain the strobe during 1 us */ + byte >>= 1; + } +@@ -727,7 +727,7 @@ + /* The backlight is activated by seting the AUTOFEED line to +5V */ + spin_lock(&pprt_lock); + bits.bl = on; +- panel_set_bits(); ++ set_bits(); + spin_unlock(&pprt_lock); + } + +@@ -2164,20 +2164,19 @@ + if (scan_timer.function != NULL) + del_timer(&scan_timer); + +- if (pprt != NULL) { +- if (keypad_enabled) +- misc_deregister(&keypad_dev); +- +- if (lcd_enabled) { +- panel_lcd_print("\x0cLCD driver " PANEL_VERSION +- "\nunloaded.\x1b[Lc\x1b[Lb\x1b[L-"); +- misc_deregister(&lcd_dev); +- } ++ if (keypad_enabled) ++ misc_deregister(&keypad_dev); + +- /* TODO: free all input signals */ +- parport_release(pprt); +- parport_unregister_device(pprt); ++ if (lcd_enabled) { ++ panel_lcd_print("\x0cLCD driver " PANEL_VERSION ++ "\nunloaded.\x1b[Lc\x1b[Lb\x1b[L-"); ++ misc_deregister(&lcd_dev); + } ++ ++ /* TODO: free all input signals */ ++ ++ parport_release(pprt); ++ parport_unregister_device(pprt); + parport_unregister_driver(&panel_driver); + } + +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/drivers/staging/poch/poch.c linux-2.6.29-rc3.owrt/drivers/staging/poch/poch.c +--- linux-2.6.29.owrt/drivers/staging/poch/poch.c 2009-05-10 22:04:38.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/drivers/staging/poch/poch.c 2009-05-10 23:48:29.000000000 +0200 +@@ -1026,7 +1026,7 @@ + } + break; + case POCH_IOC_GET_COUNTERS: +- if (!access_ok(VERIFY_WRITE, argp, sizeof(struct poch_counters))) ++ if (access_ok(VERIFY_WRITE, argp, sizeof(struct poch_counters))) + return -EFAULT; + + spin_lock_irq(&channel->counters_lock); +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/drivers/staging/rtl8187se/ieee80211/ieee80211_crypt.c linux-2.6.29-rc3.owrt/drivers/staging/rtl8187se/ieee80211/ieee80211_crypt.c +--- linux-2.6.29.owrt/drivers/staging/rtl8187se/ieee80211/ieee80211_crypt.c 2009-05-10 22:04:38.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/drivers/staging/rtl8187se/ieee80211/ieee80211_crypt.c 2009-05-10 23:48:29.000000000 +0200 +@@ -234,21 +234,20 @@ + void ieee80211_crypto_deinit(void) + { + struct list_head *ptr, *n; +- struct ieee80211_crypto_alg *alg = NULL; + + if (hcrypt == NULL) + return; + +- list_for_each_safe(ptr, n, &hcrypt->algs) { +- alg = list_entry(ptr, struct ieee80211_crypto_alg, list); +- if (alg) { +- list_del(ptr); +- printk(KERN_DEBUG +- "ieee80211_crypt: unregistered algorithm '%s' (deinit)\n", +- alg->ops->name); +- kfree(alg); +- } ++ for (ptr = hcrypt->algs.next, n = ptr->next; ptr != &hcrypt->algs; ++ ptr = n, n = ptr->next) { ++ struct ieee80211_crypto_alg *alg = ++ (struct ieee80211_crypto_alg *) ptr; ++ list_del(ptr); ++ printk(KERN_DEBUG "ieee80211_crypt: unregistered algorithm " ++ "'%s' (deinit)\n", alg->ops->name); ++ kfree(alg); + } ++ + kfree(hcrypt); + } + +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/drivers/staging/rtl8187se/Kconfig linux-2.6.29-rc3.owrt/drivers/staging/rtl8187se/Kconfig +--- linux-2.6.29.owrt/drivers/staging/rtl8187se/Kconfig 2009-05-10 22:04:38.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/drivers/staging/rtl8187se/Kconfig 2009-05-10 23:48:29.000000000 +0200 +@@ -1,6 +1,5 @@ + config RTL8187SE + tristate "RealTek RTL8187SE Wireless LAN NIC driver" + depends on PCI +- depends on WIRELESS_EXT && COMPAT_NET_DEV_OPS + default N + ---help--- +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/drivers/staging/rtl8187se/r8180_core.c linux-2.6.29-rc3.owrt/drivers/staging/rtl8187se/r8180_core.c +--- linux-2.6.29.owrt/drivers/staging/rtl8187se/r8180_core.c 2009-05-10 22:04:38.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/drivers/staging/rtl8187se/r8180_core.c 2009-05-10 23:48:29.000000000 +0200 +@@ -6161,10 +6161,10 @@ + { + pci_unregister_driver (&rtl8180_pci_driver); + rtl8180_proc_module_remove(); ++ ieee80211_crypto_deinit(); + ieee80211_crypto_tkip_exit(); + ieee80211_crypto_ccmp_exit(); + ieee80211_crypto_wep_exit(); +- ieee80211_crypto_deinit(); + DMESG("Exiting"); + } + +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/drivers/staging/usbip/usbip_common.c linux-2.6.29-rc3.owrt/drivers/staging/usbip/usbip_common.c +--- linux-2.6.29.owrt/drivers/staging/usbip/usbip_common.c 2009-05-10 22:04:38.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/drivers/staging/usbip/usbip_common.c 2009-05-10 23:48:29.000000000 +0200 +@@ -406,20 +406,8 @@ + /* + * threads are invoked per one device (per one connection). + */ +- int retval; +- +- retval = kernel_thread(usbip_thread, (void *)&ud->tcp_rx, 0); +- if (retval < 0) { +- printk(KERN_ERR "Creating tcp_rx thread for ud %p failed.\n", +- ud); +- return; +- } +- retval = kernel_thread(usbip_thread, (void *)&ud->tcp_tx, 0); +- if (retval < 0) { +- printk(KERN_ERR "Creating tcp_tx thread for ud %p failed.\n", +- ud); +- return; +- } ++ kernel_thread(usbip_thread, (void *)&ud->tcp_rx, 0); ++ kernel_thread(usbip_thread, (void *)&ud->tcp_tx, 0); + + /* confirm threads are starting */ + wait_for_completion(&ud->tcp_rx.thread_done); +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/drivers/staging/winbond/wbusb.c linux-2.6.29-rc3.owrt/drivers/staging/winbond/wbusb.c +--- linux-2.6.29.owrt/drivers/staging/winbond/wbusb.c 2009-05-10 22:04:38.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/drivers/staging/winbond/wbusb.c 2009-05-10 23:48:29.000000000 +0200 +@@ -319,18 +319,16 @@ + struct usb_device *udev = interface_to_usbdev(intf); + struct wbsoft_priv *priv; + struct ieee80211_hw *dev; +- int nr, err; ++ int err; + + usb_get_dev(udev); + + // 20060630.2 Check the device if it already be opened +- nr = usb_control_msg(udev, usb_rcvctrlpipe( udev, 0 ), +- 0x01, USB_TYPE_VENDOR|USB_RECIP_DEVICE|USB_DIR_IN, +- 0x0, 0x400, <mp, 4, HZ*100 ); +- if (nr < 0) { +- err = nr; ++ err = usb_control_msg(udev, usb_rcvctrlpipe( udev, 0 ), ++ 0x01, USB_TYPE_VENDOR|USB_RECIP_DEVICE|USB_DIR_IN, ++ 0x0, 0x400, <mp, 4, HZ*100 ); ++ if (err) + goto error; +- } + + ltmp = cpu_to_le32(ltmp); + if (ltmp) { // Is already initialized? +@@ -339,10 +337,8 @@ + } + + dev = ieee80211_alloc_hw(sizeof(*priv), &wbsoft_ops); +- if (!dev) { +- err = -ENOMEM; ++ if (!dev) + goto error; +- } + + priv = dev->priv; + +@@ -373,11 +369,9 @@ + } + + dev->extra_tx_headroom = 12; /* FIXME */ +- dev->flags = IEEE80211_HW_SIGNAL_UNSPEC; +- dev->wiphy->interface_modes = BIT(NL80211_IFTYPE_STATION); ++ dev->flags = 0; + + dev->channel_change_time = 1000; +- dev->max_signal = 100; + dev->queues = 1; + + dev->wiphy->bands[IEEE80211_BAND_2GHZ] = &wbsoft_band_2GHz; +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/drivers/usb/atm/cxacru.c linux-2.6.29-rc3.owrt/drivers/usb/atm/cxacru.c +--- linux-2.6.29.owrt/drivers/usb/atm/cxacru.c 2009-05-10 22:04:38.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/drivers/usb/atm/cxacru.c 2009-05-10 23:48:29.000000000 +0200 +@@ -485,7 +485,7 @@ + usb_err(instance->usbatm, "requested transfer size too large (%d, %d)\n", + wbuflen, rbuflen); + ret = -ENOMEM; +- goto err; ++ goto fail; + } + + mutex_lock(&instance->cm_serialize); +@@ -565,7 +565,6 @@ + dbg("cm %#x", cm); + fail: + mutex_unlock(&instance->cm_serialize); +-err: + return ret; + } + +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/drivers/usb/class/cdc-acm.c linux-2.6.29-rc3.owrt/drivers/usb/class/cdc-acm.c +--- linux-2.6.29.owrt/drivers/usb/class/cdc-acm.c 2009-05-10 22:04:38.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/drivers/usb/class/cdc-acm.c 2009-05-10 23:48:29.000000000 +0200 +@@ -1349,6 +1349,9 @@ + { USB_DEVICE(0x0e8d, 0x0003), /* FIREFLY, MediaTek Inc; andrey.arapov@gmail.com */ + .driver_info = NO_UNION_NORMAL, /* has no union descriptor */ + }, ++ { USB_DEVICE(0x0e8d, 0x3329), /* i-blue 747, Qstarz BT-Q1000, Holux M-241 */ ++ .driver_info = NO_UNION_NORMAL, /* has no union descriptor */ ++ }, + { USB_DEVICE(0x0e8d, 0x3329), /* MediaTek Inc GPS */ + .driver_info = NO_UNION_NORMAL, /* has no union descriptor */ + }, +@@ -1376,15 +1379,6 @@ + { USB_DEVICE(0x0572, 0x1324), /* Conexant USB MODEM RD02-D400 */ + .driver_info = NO_UNION_NORMAL, /* has no union descriptor */ + }, +- { USB_DEVICE(0x22b8, 0x6425), /* Motorola MOTOMAGX phones */ +- }, +- { USB_DEVICE(0x0572, 0x1329), /* Hummingbird huc56s (Conexant) */ +- .driver_info = NO_UNION_NORMAL, /* union descriptor misplaced on +- data interface instead of +- communications interface. +- Maybe we should define a new +- quirk for this. */ +- }, + + /* control interfaces with various AT-command sets */ + { USB_INTERFACE_INFO(USB_CLASS_COMM, USB_CDC_SUBCLASS_ACM, +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/drivers/usb/class/usbtmc.c linux-2.6.29-rc3.owrt/drivers/usb/class/usbtmc.c +--- linux-2.6.29.owrt/drivers/usb/class/usbtmc.c 2009-05-10 22:04:38.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/drivers/usb/class/usbtmc.c 2009-05-10 23:48:29.000000000 +0200 +@@ -50,7 +50,6 @@ + + static struct usb_device_id usbtmc_devices[] = { + { USB_INTERFACE_INFO(USB_CLASS_APP_SPEC, 3, 0), }, +- { USB_INTERFACE_INFO(USB_CLASS_APP_SPEC, 3, 1), }, + { 0, } /* terminating entry */ + }; + MODULE_DEVICE_TABLE(usb, usbtmc_devices); +@@ -107,13 +106,12 @@ + { + struct usb_interface *intf; + struct usbtmc_device_data *data; +- int retval = 0; ++ int retval = -ENODEV; + + intf = usb_find_interface(&usbtmc_driver, iminor(inode)); + if (!intf) { + printk(KERN_ERR KBUILD_MODNAME + ": can not find device for minor %d", iminor(inode)); +- retval = -ENODEV; + goto exit; + } + +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/drivers/usb/core/devio.c linux-2.6.29-rc3.owrt/drivers/usb/core/devio.c +--- linux-2.6.29.owrt/drivers/usb/core/devio.c 2009-05-10 22:04:38.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/drivers/usb/core/devio.c 2009-05-10 23:48:29.000000000 +0200 +@@ -359,6 +359,11 @@ + spin_lock_irqsave(&ps->lock, flags); + } + spin_unlock_irqrestore(&ps->lock, flags); ++ as = async_getcompleted(ps); ++ while (as) { ++ free_async(as); ++ as = async_getcompleted(ps); ++ } + } + + static void destroy_async_on_interface(struct dev_state *ps, +@@ -638,7 +643,6 @@ + struct dev_state *ps = file->private_data; + struct usb_device *dev = ps->dev; + unsigned int ifnum; +- struct async *as; + + usb_lock_device(dev); + +@@ -657,12 +661,6 @@ + usb_unlock_device(dev); + usb_put_dev(dev); + put_pid(ps->disc_pid); +- +- as = async_getcompleted(ps); +- while (as) { +- free_async(as); +- as = async_getcompleted(ps); +- } + kfree(ps); + return 0; + } +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/drivers/usb/core/hcd.h linux-2.6.29-rc3.owrt/drivers/usb/core/hcd.h +--- linux-2.6.29.owrt/drivers/usb/core/hcd.h 2009-05-10 22:04:38.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/drivers/usb/core/hcd.h 2009-05-10 23:48:29.000000000 +0200 +@@ -257,6 +257,7 @@ + + #ifdef CONFIG_PM + extern int usb_hcd_pci_suspend(struct pci_dev *dev, pm_message_t msg); ++extern int usb_hcd_pci_resume_early(struct pci_dev *dev); + extern int usb_hcd_pci_resume(struct pci_dev *dev); + #endif /* CONFIG_PM */ + +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/drivers/usb/core/hcd-pci.c linux-2.6.29-rc3.owrt/drivers/usb/core/hcd-pci.c +--- linux-2.6.29.owrt/drivers/usb/core/hcd-pci.c 2009-05-10 22:04:38.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/drivers/usb/core/hcd-pci.c 2009-05-10 23:48:29.000000000 +0200 +@@ -298,6 +298,19 @@ + EXPORT_SYMBOL_GPL(usb_hcd_pci_suspend); + + /** ++ * usb_hcd_pci_resume_early - resume a PCI-based HCD before IRQs are enabled ++ * @dev: USB Host Controller being resumed ++ * ++ * Store this function in the HCD's struct pci_driver as .resume_early. ++ */ ++int usb_hcd_pci_resume_early(struct pci_dev *dev) ++{ ++ pci_restore_state(dev); ++ return 0; ++} ++EXPORT_SYMBOL_GPL(usb_hcd_pci_resume_early); ++ ++/** + * usb_hcd_pci_resume - power management resume of a PCI-based HCD + * @dev: USB Host Controller being resumed + * +@@ -320,8 +333,6 @@ + } + #endif + +- pci_restore_state(dev); +- + hcd = pci_get_drvdata(dev); + if (hcd->state != HC_STATE_SUSPENDED) { + dev_dbg(hcd->self.controller, +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/drivers/usb/core/message.c linux-2.6.29-rc3.owrt/drivers/usb/core/message.c +--- linux-2.6.29.owrt/drivers/usb/core/message.c 2009-05-10 22:04:38.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/drivers/usb/core/message.c 2009-05-10 23:48:29.000000000 +0200 +@@ -653,7 +653,7 @@ + if (result <= 0 && result != -ETIMEDOUT) + continue; + if (result > 1 && ((u8 *)buf)[1] != type) { +- result = -ENODATA; ++ result = -EPROTO; + continue; + } + break; +@@ -696,13 +696,8 @@ + USB_REQ_GET_DESCRIPTOR, USB_DIR_IN, + (USB_DT_STRING << 8) + index, langid, buf, size, + USB_CTRL_GET_TIMEOUT); +- if (result == 0 || result == -EPIPE) +- continue; +- if (result > 1 && ((u8 *) buf)[1] != USB_DT_STRING) { +- result = -ENODATA; +- continue; +- } +- break; ++ if (!(result == 0 || result == -EPIPE)) ++ break; + } + return result; + } +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/drivers/usb/gadget/file_storage.c linux-2.6.29-rc3.owrt/drivers/usb/gadget/file_storage.c +--- linux-2.6.29.owrt/drivers/usb/gadget/file_storage.c 2009-05-10 22:04:38.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/drivers/usb/gadget/file_storage.c 2009-05-10 23:48:29.000000000 +0200 +@@ -3879,11 +3879,7 @@ + mod_data.protocol_type = USB_SC_SCSI; + mod_data.protocol_name = "Transparent SCSI"; + +- /* Some peripheral controllers are known not to be able to +- * halt bulk endpoints correctly. If one of them is present, +- * disable stalls. +- */ +- if (gadget_is_sh(fsg->gadget) || gadget_is_at91(fsg->gadget)) ++ if (gadget_is_sh(fsg->gadget)) + mod_data.can_stall = 0; + + if (mod_data.release == 0xffff) { // Parameter wasn't set +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/drivers/usb/gadget/f_obex.c linux-2.6.29-rc3.owrt/drivers/usb/gadget/f_obex.c +--- linux-2.6.29.owrt/drivers/usb/gadget/f_obex.c 2009-05-10 22:04:38.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/drivers/usb/gadget/f_obex.c 2009-05-10 23:48:29.000000000 +0200 +@@ -366,9 +366,9 @@ + f->hs_descriptors = usb_copy_descriptors(hs_function); + + obex->hs.obex_in = usb_find_endpoint(hs_function, +- f->hs_descriptors, &obex_hs_ep_in_desc); ++ f->descriptors, &obex_hs_ep_in_desc); + obex->hs.obex_out = usb_find_endpoint(hs_function, +- f->hs_descriptors, &obex_hs_ep_out_desc); ++ f->descriptors, &obex_hs_ep_out_desc); + } + + /* Avoid letting this gadget enumerate until the userspace +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/drivers/usb/gadget/fsl_qe_udc.c linux-2.6.29-rc3.owrt/drivers/usb/gadget/fsl_qe_udc.c +--- linux-2.6.29.owrt/drivers/usb/gadget/fsl_qe_udc.c 2009-05-10 22:04:38.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/drivers/usb/gadget/fsl_qe_udc.c 2009-05-10 23:48:29.000000000 +0200 +@@ -1622,8 +1622,6 @@ + nuke(ep, -ESHUTDOWN); + ep->desc = NULL; + ep->stopped = 1; +- ep->tx_req = NULL; +- qe_ep_reset(udc, ep->epnum); + spin_unlock_irqrestore(&udc->lock, flags); + + cpm_muram_free(cpm_muram_offset(ep->rxbase)); +@@ -1683,11 +1681,14 @@ + kfree(req); + } + +-static int __qe_ep_queue(struct usb_ep *_ep, struct usb_request *_req) ++/* queues (submits) an I/O request to an endpoint */ ++static int qe_ep_queue(struct usb_ep *_ep, struct usb_request *_req, ++ gfp_t gfp_flags) + { + struct qe_ep *ep = container_of(_ep, struct qe_ep, ep); + struct qe_req *req = container_of(_req, struct qe_req, req); + struct qe_udc *udc; ++ unsigned long flags; + int reval; + + udc = ep->udc; +@@ -1731,7 +1732,7 @@ + list_add_tail(&req->queue, &ep->queue); + dev_vdbg(udc->dev, "gadget have request in %s! %d\n", + ep->name, req->req.length); +- ++ spin_lock_irqsave(&udc->lock, flags); + /* push the request to device */ + if (ep_is_in(ep)) + reval = ep_req_send(ep, req); +@@ -1747,22 +1748,9 @@ + if (ep->dir == USB_DIR_OUT) + reval = ep_req_receive(ep, req); + +- return 0; +-} +- +-/* queues (submits) an I/O request to an endpoint */ +-static int qe_ep_queue(struct usb_ep *_ep, struct usb_request *_req, +- gfp_t gfp_flags) +-{ +- struct qe_ep *ep = container_of(_ep, struct qe_ep, ep); +- struct qe_udc *udc = ep->udc; +- unsigned long flags; +- int ret; +- +- spin_lock_irqsave(&udc->lock, flags); +- ret = __qe_ep_queue(_ep, _req); + spin_unlock_irqrestore(&udc->lock, flags); +- return ret; ++ ++ return 0; + } + + /* dequeues (cancels, unlinks) an I/O request from an endpoint */ +@@ -2020,7 +2008,7 @@ + udc->ep0_dir = USB_DIR_IN; + + /* data phase */ +- status = __qe_ep_queue(&ep->ep, &req->req); ++ status = qe_ep_queue(&ep->ep, &req->req, GFP_ATOMIC); + + if (status == 0) + return; +@@ -2163,9 +2151,6 @@ + { + unsigned char i; + +- if (udc->usb_state == USB_STATE_DEFAULT) +- return 0; +- + qe_usb_disable(); + out_8(&udc->usb_regs->usb_usadr, 0); + +@@ -2457,12 +2442,8 @@ + struct usb_ctlr __iomem *qe_usbregs; + qe_usbregs = udc->usb_regs; + +- /* Spec says that we must enable the USB controller to change mode. */ ++ /* Init the usb register */ + out_8(&qe_usbregs->usb_usmod, 0x01); +- /* Mode changed, now disable it, since muram isn't initialized yet. */ +- out_8(&qe_usbregs->usb_usmod, 0x00); +- +- /* Initialize the rest. */ + out_be16(&qe_usbregs->usb_usbmr, 0); + out_8(&qe_usbregs->usb_uscom, 0); + out_be16(&qe_usbregs->usb_usber, USBER_ALL_CLEAR); +@@ -2623,10 +2604,6 @@ + (unsigned long)udc_controller); + /* request irq and disable DR */ + udc_controller->usb_irq = irq_of_parse_and_map(np, 0); +- if (!udc_controller->usb_irq) { +- ret = -EINVAL; +- goto err_noirq; +- } + + ret = request_irq(udc_controller->usb_irq, qe_udc_irq, 0, + driver_name, udc_controller); +@@ -2648,8 +2625,6 @@ + err6: + free_irq(udc_controller->usb_irq, udc_controller); + err5: +- irq_dispose_mapping(udc_controller->usb_irq); +-err_noirq: + if (udc_controller->nullmap) { + dma_unmap_single(udc_controller->gadget.dev.parent, + udc_controller->nullp, 256, +@@ -2673,7 +2648,7 @@ + iounmap(udc_controller->usb_regs); + err1: + kfree(udc_controller); +- udc_controller = NULL; ++ + return ret; + } + +@@ -2735,7 +2710,6 @@ + kfree(ep->txframe); + + free_irq(udc_controller->usb_irq, udc_controller); +- irq_dispose_mapping(udc_controller->usb_irq); + + tasklet_kill(&udc_controller->rx_tasklet); + +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/drivers/usb/gadget/fsl_usb2_udc.c linux-2.6.29-rc3.owrt/drivers/usb/gadget/fsl_usb2_udc.c +--- linux-2.6.29.owrt/drivers/usb/gadget/fsl_usb2_udc.c 2009-05-10 22:04:38.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/drivers/usb/gadget/fsl_usb2_udc.c 2009-05-10 23:48:29.000000000 +0200 +@@ -404,10 +404,7 @@ + } + if (zlt) + tmp |= EP_QUEUE_HEAD_ZLT_SEL; +- + p_QH->max_pkt_length = cpu_to_le32(tmp); +- p_QH->next_dtd_ptr = 1; +- p_QH->size_ioc_int_sts = 0; + + return; + } +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/drivers/usb/gadget/Kconfig linux-2.6.29-rc3.owrt/drivers/usb/gadget/Kconfig +--- linux-2.6.29.owrt/drivers/usb/gadget/Kconfig 2009-05-10 22:04:38.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/drivers/usb/gadget/Kconfig 2009-05-10 23:48:29.000000000 +0200 +@@ -191,7 +191,6 @@ + boolean "OMAP USB Device Controller" + depends on ARCH_OMAP + select ISP1301_OMAP if MACH_OMAP_H2 || MACH_OMAP_H3 || MACH_OMAP_H4_OTG +- select USB_OTG_UTILS if ARCH_OMAP + help + Many Texas Instruments OMAP processors have flexible full + speed USB device controllers, with support for up to 30 +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/drivers/usb/gadget/pxa25x_udc.c linux-2.6.29-rc3.owrt/drivers/usb/gadget/pxa25x_udc.c +--- linux-2.6.29.owrt/drivers/usb/gadget/pxa25x_udc.c 2009-05-10 22:04:38.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/drivers/usb/gadget/pxa25x_udc.c 2009-05-10 23:48:29.000000000 +0200 +@@ -904,8 +904,8 @@ + + /* most IN status is the same, but ISO can't stall */ + *ep->reg_udccs = UDCCS_BI_TPC|UDCCS_BI_FTF|UDCCS_BI_TUR +- | (ep->bmAttributes == USB_ENDPOINT_XFER_ISOC +- ? 0 : UDCCS_BI_SST); ++ | (ep->bmAttributes == USB_ENDPOINT_XFER_ISOC) ++ ? 0 : UDCCS_BI_SST; + } + + +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/drivers/usb/host/ehci.h linux-2.6.29-rc3.owrt/drivers/usb/host/ehci.h +--- linux-2.6.29.owrt/drivers/usb/host/ehci.h 2009-05-10 22:04:38.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/drivers/usb/host/ehci.h 2009-05-10 23:48:29.000000000 +0200 +@@ -87,10 +87,6 @@ + int next_uframe; /* scan periodic, start here */ + unsigned periodic_sched; /* periodic activity count */ + +- /* list of itds completed while clock_frame was still active */ +- struct list_head cached_itd_list; +- unsigned clock_frame; +- + /* per root hub port */ + unsigned long reset_done [EHCI_MAX_ROOT_PORTS]; + +@@ -224,8 +220,6 @@ + } + } + +-static void free_cached_itd_list(struct ehci_hcd *ehci); +- + /*-------------------------------------------------------------------------*/ + + #include <linux/usb/ehci_def.h> +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/drivers/usb/host/ehci-hcd.c linux-2.6.29-rc3.owrt/drivers/usb/host/ehci-hcd.c +--- linux-2.6.29.owrt/drivers/usb/host/ehci-hcd.c 2009-05-10 22:04:38.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/drivers/usb/host/ehci-hcd.c 2009-05-10 23:48:29.000000000 +0200 +@@ -485,7 +485,6 @@ + * periodic_size can shrink by USBCMD update if hcc_params allows. + */ + ehci->periodic_size = DEFAULT_I_TDPS; +- INIT_LIST_HEAD(&ehci->cached_itd_list); + if ((retval = ehci_mem_init(ehci, GFP_KERNEL)) < 0) + return retval; + +@@ -498,7 +497,6 @@ + + ehci->reclaim = NULL; + ehci->next_uframe = -1; +- ehci->clock_frame = -1; + + /* + * dedicate a qh for the async ring head, since we couldn't unlink +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/drivers/usb/host/ehci-mem.c linux-2.6.29-rc3.owrt/drivers/usb/host/ehci-mem.c +--- linux-2.6.29.owrt/drivers/usb/host/ehci-mem.c 2009-05-10 22:04:38.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/drivers/usb/host/ehci-mem.c 2009-05-10 23:48:29.000000000 +0200 +@@ -128,7 +128,6 @@ + + static void ehci_mem_cleanup (struct ehci_hcd *ehci) + { +- free_cached_itd_list(ehci); + if (ehci->async) + qh_put (ehci->async); + ehci->async = NULL; +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/drivers/usb/host/ehci-pci.c linux-2.6.29-rc3.owrt/drivers/usb/host/ehci-pci.c +--- linux-2.6.29.owrt/drivers/usb/host/ehci-pci.c 2009-05-10 22:04:38.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/drivers/usb/host/ehci-pci.c 2009-05-10 23:48:29.000000000 +0200 +@@ -432,6 +432,7 @@ + + #ifdef CONFIG_PM + .suspend = usb_hcd_pci_suspend, ++ .resume_early = usb_hcd_pci_resume_early, + .resume = usb_hcd_pci_resume, + #endif + .shutdown = usb_hcd_pci_shutdown, +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/drivers/usb/host/ehci-q.c linux-2.6.29-rc3.owrt/drivers/usb/host/ehci-q.c +--- linux-2.6.29.owrt/drivers/usb/host/ehci-q.c 2009-05-10 22:04:38.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/drivers/usb/host/ehci-q.c 2009-05-10 23:48:29.000000000 +0200 +@@ -1095,8 +1095,7 @@ + prev->qh_next = qh->qh_next; + wmb (); + +- /* If the controller isn't running, we don't have to wait for it */ +- if (unlikely(!HC_IS_RUNNING(ehci_to_hcd(ehci)->state))) { ++ if (unlikely (ehci_to_hcd(ehci)->state == HC_STATE_HALT)) { + /* if (unlikely (qh->reclaim != 0)) + * this will recurse, probably not much + */ +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/drivers/usb/host/ehci-sched.c linux-2.6.29-rc3.owrt/drivers/usb/host/ehci-sched.c +--- linux-2.6.29.owrt/drivers/usb/host/ehci-sched.c 2009-05-10 22:04:38.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/drivers/usb/host/ehci-sched.c 2009-05-10 23:48:29.000000000 +0200 +@@ -1004,8 +1004,7 @@ + + is_in = (stream->bEndpointAddress & USB_DIR_IN) ? 0x10 : 0; + stream->bEndpointAddress &= 0x0f; +- if (stream->ep) +- stream->ep->hcpriv = NULL; ++ stream->ep->hcpriv = NULL; + + if (stream->rescheduled) { + ehci_info (ehci, "ep%d%s-iso rescheduled " +@@ -1536,7 +1535,7 @@ + struct ehci_itd, itd_list); + list_move_tail (&itd->itd_list, &stream->td_list); + itd->stream = iso_stream_get (stream); +- itd->urb = urb; ++ itd->urb = usb_get_urb (urb); + itd_init (ehci, stream, itd); + } + +@@ -1645,7 +1644,7 @@ + (void) disable_periodic(ehci); + ehci_to_hcd(ehci)->self.bandwidth_isoc_reqs--; + +- if (unlikely(list_is_singular(&stream->td_list))) { ++ if (unlikely (list_empty (&stream->td_list))) { + ehci_to_hcd(ehci)->self.bandwidth_allocated + -= stream->bandwidth; + ehci_vdbg (ehci, +@@ -1654,27 +1653,14 @@ + (stream->bEndpointAddress & USB_DIR_IN) ? "in" : "out"); + } + iso_stream_put (ehci, stream); +- ++ /* OK to recycle this ITD now that its completion callback ran. */ + done: ++ usb_put_urb(urb); + itd->urb = NULL; +- if (ehci->clock_frame != itd->frame || itd->index[7] != -1) { +- /* OK to recycle this ITD now. */ +- itd->stream = NULL; +- list_move(&itd->itd_list, &stream->free_list); +- iso_stream_put(ehci, stream); +- } else { +- /* HW might remember this ITD, so we can't recycle it yet. +- * Move it to a safe place until a new frame starts. +- */ +- list_move(&itd->itd_list, &ehci->cached_itd_list); +- if (stream->refcount == 2) { +- /* If iso_stream_put() were called here, stream +- * would be freed. Instead, just prevent reuse. +- */ +- stream->ep->hcpriv = NULL; +- stream->ep = NULL; +- } +- } ++ itd->stream = NULL; ++ list_move(&itd->itd_list, &stream->free_list); ++ iso_stream_put(ehci, stream); ++ + return retval; + } + +@@ -1948,7 +1934,7 @@ + struct ehci_sitd, sitd_list); + list_move_tail (&sitd->sitd_list, &stream->td_list); + sitd->stream = iso_stream_get (stream); +- sitd->urb = urb; ++ sitd->urb = usb_get_urb (urb); + + sitd_patch(ehci, stream, sitd, sched, packet); + sitd_link (ehci, (next_uframe >> 3) % ehci->periodic_size, +@@ -2033,7 +2019,7 @@ + (void) disable_periodic(ehci); + ehci_to_hcd(ehci)->self.bandwidth_isoc_reqs--; + +- if (list_is_singular(&stream->td_list)) { ++ if (list_empty (&stream->td_list)) { + ehci_to_hcd(ehci)->self.bandwidth_allocated + -= stream->bandwidth; + ehci_vdbg (ehci, +@@ -2044,6 +2030,7 @@ + iso_stream_put (ehci, stream); + /* OK to recycle this SITD now that its completion callback ran. */ + done: ++ usb_put_urb(urb); + sitd->urb = NULL; + sitd->stream = NULL; + list_move(&sitd->sitd_list, &stream->free_list); +@@ -2114,20 +2101,6 @@ + + /*-------------------------------------------------------------------------*/ + +-static void free_cached_itd_list(struct ehci_hcd *ehci) +-{ +- struct ehci_itd *itd, *n; +- +- list_for_each_entry_safe(itd, n, &ehci->cached_itd_list, itd_list) { +- struct ehci_iso_stream *stream = itd->stream; +- itd->stream = NULL; +- list_move(&itd->itd_list, &stream->free_list); +- iso_stream_put(ehci, stream); +- } +-} +- +-/*-------------------------------------------------------------------------*/ +- + static void + scan_periodic (struct ehci_hcd *ehci) + { +@@ -2142,17 +2115,10 @@ + * Touches as few pages as possible: cache-friendly. + */ + now_uframe = ehci->next_uframe; +- if (HC_IS_RUNNING(ehci_to_hcd(ehci)->state)) { ++ if (HC_IS_RUNNING (ehci_to_hcd(ehci)->state)) + clock = ehci_readl(ehci, &ehci->regs->frame_index); +- clock_frame = (clock >> 3) % ehci->periodic_size; +- } else { ++ else + clock = now_uframe + mod - 1; +- clock_frame = -1; +- } +- if (ehci->clock_frame != clock_frame) { +- free_cached_itd_list(ehci); +- ehci->clock_frame = clock_frame; +- } + clock %= mod; + clock_frame = clock >> 3; + +@@ -2311,10 +2277,6 @@ + /* rescan the rest of this frame, then ... */ + clock = now; + clock_frame = clock >> 3; +- if (ehci->clock_frame != clock_frame) { +- free_cached_itd_list(ehci); +- ehci->clock_frame = clock_frame; +- } + } else { + now_uframe++; + now_uframe %= mod; +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/drivers/usb/host/ohci-pci.c linux-2.6.29-rc3.owrt/drivers/usb/host/ohci-pci.c +--- linux-2.6.29.owrt/drivers/usb/host/ohci-pci.c 2009-05-10 22:04:38.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/drivers/usb/host/ohci-pci.c 2009-05-10 23:48:29.000000000 +0200 +@@ -487,6 +487,7 @@ + + #ifdef CONFIG_PM + .suspend = usb_hcd_pci_suspend, ++ .resume_early = usb_hcd_pci_resume_early, + .resume = usb_hcd_pci_resume, + #endif + +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/drivers/usb/host/uhci-hcd.c linux-2.6.29-rc3.owrt/drivers/usb/host/uhci-hcd.c +--- linux-2.6.29.owrt/drivers/usb/host/uhci-hcd.c 2009-05-10 22:04:38.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/drivers/usb/host/uhci-hcd.c 2009-05-10 23:48:29.000000000 +0200 +@@ -942,6 +942,7 @@ + + #ifdef CONFIG_PM + .suspend = usb_hcd_pci_suspend, ++ .resume_early = usb_hcd_pci_resume_early, + .resume = usb_hcd_pci_resume, + #endif /* PM */ + }; +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/drivers/usb/host/whci/asl.c linux-2.6.29-rc3.owrt/drivers/usb/host/whci/asl.c +--- linux-2.6.29.owrt/drivers/usb/host/whci/asl.c 2009-05-10 22:04:38.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/drivers/usb/host/whci/asl.c 2009-05-10 23:48:29.000000000 +0200 +@@ -170,17 +170,12 @@ + void asl_update(struct whc *whc, uint32_t wusbcmd) + { + struct wusbhc *wusbhc = &whc->wusbhc; +- long t; + + mutex_lock(&wusbhc->mutex); + if (wusbhc->active) { + whc_write_wusbcmd(whc, wusbcmd, wusbcmd); +- t = wait_event_timeout( +- whc->async_list_wq, +- (le_readl(whc->base + WUSBCMD) & WUSBCMD_ASYNC_UPDATED) == 0, +- msecs_to_jiffies(1000)); +- if (t == 0) +- whc_hw_error(whc, "ASL update timeout"); ++ wait_event(whc->async_list_wq, ++ (le_readl(whc->base + WUSBCMD) & WUSBCMD_ASYNC_UPDATED) == 0); + } + mutex_unlock(&wusbhc->mutex); + } +@@ -227,13 +222,13 @@ + * Now that the ASL is updated, complete the removal of any + * removed qsets. + */ +- spin_lock_irq(&whc->lock); ++ spin_lock(&whc->lock); + + list_for_each_entry_safe(qset, t, &whc->async_removed_list, list_node) { + qset_remove_complete(whc, qset); + } + +- spin_unlock_irq(&whc->lock); ++ spin_unlock(&whc->lock); + } + + /** +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/drivers/usb/host/whci/hw.c linux-2.6.29-rc3.owrt/drivers/usb/host/whci/hw.c +--- linux-2.6.29.owrt/drivers/usb/host/whci/hw.c 2009-05-10 22:04:38.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/drivers/usb/host/whci/hw.c 2009-05-10 23:48:29.000000000 +0200 +@@ -87,18 +87,3 @@ + + return ret; + } +- +-/** +- * whc_hw_error - recover from a hardware error +- * @whc: the WHCI HC that broke. +- * @reason: a description of the failure. +- * +- * Recover from broken hardware with a full reset. +- */ +-void whc_hw_error(struct whc *whc, const char *reason) +-{ +- struct wusbhc *wusbhc = &whc->wusbhc; +- +- dev_err(&whc->umc->dev, "hardware error: %s\n", reason); +- wusbhc_reset_all(wusbhc); +-} +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/drivers/usb/host/whci/pzl.c linux-2.6.29-rc3.owrt/drivers/usb/host/whci/pzl.c +--- linux-2.6.29.owrt/drivers/usb/host/whci/pzl.c 2009-05-10 22:04:38.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/drivers/usb/host/whci/pzl.c 2009-05-10 23:48:29.000000000 +0200 +@@ -183,17 +183,12 @@ + void pzl_update(struct whc *whc, uint32_t wusbcmd) + { + struct wusbhc *wusbhc = &whc->wusbhc; +- long t; + + mutex_lock(&wusbhc->mutex); + if (wusbhc->active) { + whc_write_wusbcmd(whc, wusbcmd, wusbcmd); +- t = wait_event_timeout( +- whc->periodic_list_wq, +- (le_readl(whc->base + WUSBCMD) & WUSBCMD_PERIODIC_UPDATED) == 0, +- msecs_to_jiffies(1000)); +- if (t == 0) +- whc_hw_error(whc, "PZL update timeout"); ++ wait_event(whc->periodic_list_wq, ++ (le_readl(whc->base + WUSBCMD) & WUSBCMD_PERIODIC_UPDATED) == 0); + } + mutex_unlock(&wusbhc->mutex); + } +@@ -255,13 +250,13 @@ + * Now that the PZL is updated, complete the removal of any + * removed qsets. + */ +- spin_lock_irq(&whc->lock); ++ spin_lock(&whc->lock); + + list_for_each_entry_safe(qset, t, &whc->periodic_removed_list, list_node) { + qset_remove_complete(whc, qset); + } + +- spin_unlock_irq(&whc->lock); ++ spin_unlock(&whc->lock); + } + + /** +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/drivers/usb/host/whci/whcd.h linux-2.6.29-rc3.owrt/drivers/usb/host/whci/whcd.h +--- linux-2.6.29.owrt/drivers/usb/host/whci/whcd.h 2009-05-10 22:04:38.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/drivers/usb/host/whci/whcd.h 2009-05-10 23:48:29.000000000 +0200 +@@ -137,7 +137,6 @@ + /* hw.c */ + void whc_write_wusbcmd(struct whc *whc, u32 mask, u32 val); + int whc_do_gencmd(struct whc *whc, u32 cmd, u32 params, void *addr, size_t len); +-void whc_hw_error(struct whc *whc, const char *reason); + + /* wusb.c */ + int whc_wusbhc_start(struct wusbhc *wusbhc); +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/drivers/usb/image/mdc800.c linux-2.6.29-rc3.owrt/drivers/usb/image/mdc800.c +--- linux-2.6.29.owrt/drivers/usb/image/mdc800.c 2009-05-10 22:04:38.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/drivers/usb/image/mdc800.c 2009-05-10 23:48:29.000000000 +0200 +@@ -499,7 +499,6 @@ + retval = usb_register_dev(intf, &mdc800_class); + if (retval) { + dev_err(&intf->dev, "Not able to get a minor for this device.\n"); +- mutex_unlock(&mdc800->io_lock); + return -ENODEV; + } + +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/drivers/usb/Makefile linux-2.6.29-rc3.owrt/drivers/usb/Makefile +--- linux-2.6.29.owrt/drivers/usb/Makefile 2009-05-10 22:04:38.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/drivers/usb/Makefile 2009-05-10 23:48:29.000000000 +0200 +@@ -11,7 +11,6 @@ + obj-$(CONFIG_PCI) += host/ + obj-$(CONFIG_USB_EHCI_HCD) += host/ + obj-$(CONFIG_USB_ISP116X_HCD) += host/ +-obj-$(CONFIG_USB_ISP1760_HCD) += host/ + obj-$(CONFIG_USB_OHCI_HCD) += host/ + obj-$(CONFIG_USB_UHCI_HCD) += host/ + obj-$(CONFIG_USB_FHCI_HCD) += host/ +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/drivers/usb/misc/adutux.c linux-2.6.29-rc3.owrt/drivers/usb/misc/adutux.c +--- linux-2.6.29.owrt/drivers/usb/misc/adutux.c 2009-05-10 22:04:38.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/drivers/usb/misc/adutux.c 2009-05-10 23:48:29.000000000 +0200 +@@ -376,7 +376,7 @@ + if (dev->open_count <= 0) { + dbg(1," %s : device not opened", __func__); + retval = -ENODEV; +- goto unlock; ++ goto exit; + } + + adu_release_internal(dev); +@@ -385,9 +385,9 @@ + if (!dev->open_count) /* ... and we're the last user */ + adu_delete(dev); + } +-unlock: +- mutex_unlock(&adutux_mutex); ++ + exit: ++ mutex_unlock(&adutux_mutex); + dbg(2," %s : leave, return value %d", __func__, retval); + return retval; + } +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/drivers/usb/misc/vstusb.c linux-2.6.29-rc3.owrt/drivers/usb/misc/vstusb.c +--- linux-2.6.29.owrt/drivers/usb/misc/vstusb.c 2009-05-10 22:04:38.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/drivers/usb/misc/vstusb.c 2009-05-10 23:48:29.000000000 +0200 +@@ -401,7 +401,6 @@ + } + + if (copy_from_user(buf, buffer, count)) { +- mutex_unlock(&vstdev->lock); + dev_err(&dev->dev, "%s: can't copy_from_user\n", __func__); + retval = -EFAULT; + goto exit; +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/drivers/usb/musb/davinci.c linux-2.6.29-rc3.owrt/drivers/usb/musb/davinci.c +--- linux-2.6.29.owrt/drivers/usb/musb/davinci.c 2009-05-10 22:04:38.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/drivers/usb/musb/davinci.c 2009-05-10 23:48:29.000000000 +0200 +@@ -377,8 +377,18 @@ + u32 revision; + + musb->mregs += DAVINCI_BASE_OFFSET; ++#if 0 ++ /* REVISIT there's something odd about clocking, this ++ * didn't appear do the job ... ++ */ ++ musb->clock = clk_get(pDevice, "usb"); ++ if (IS_ERR(musb->clock)) ++ return PTR_ERR(musb->clock); + +- clk_enable(musb->clock); ++ status = clk_enable(musb->clock); ++ if (status < 0) ++ return -ENODEV; ++#endif + + /* returns zero if e.g. not clocked */ + revision = musb_readl(tibase, DAVINCI_USB_VERSION_REG); +@@ -443,8 +453,5 @@ + } + + phy_off(); +- +- clk_disable(musb->clock); +- + return 0; + } +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/drivers/usb/musb/musb_core.c linux-2.6.29-rc3.owrt/drivers/usb/musb/musb_core.c +--- linux-2.6.29.owrt/drivers/usb/musb/musb_core.c 2009-05-10 22:04:38.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/drivers/usb/musb/musb_core.c 2009-05-10 23:48:29.000000000 +0200 +@@ -115,7 +115,7 @@ + + + unsigned musb_debug; +-module_param_named(debug, musb_debug, uint, S_IRUGO | S_IWUSR); ++module_param(musb_debug, uint, S_IRUGO | S_IWUSR); + MODULE_PARM_DESC(debug, "Debug message level. Default = 0"); + + #define DRIVER_AUTHOR "Mentor Graphics, Texas Instruments, Nokia" +@@ -767,7 +767,6 @@ + #ifdef CONFIG_USB_MUSB_HDRC_HCD + case OTG_STATE_A_HOST: + case OTG_STATE_A_SUSPEND: +- usb_hcd_resume_root_hub(musb_to_hcd(musb)); + musb_root_disconnect(musb); + if (musb->a_wait_bcon != 0) + musb_platform_try_idle(musb, jiffies +@@ -1816,7 +1815,7 @@ + #ifdef CONFIG_SYSFS + device_remove_file(musb->controller, &dev_attr_mode); + device_remove_file(musb->controller, &dev_attr_vbus); +-#ifdef CONFIG_USB_GADGET_MUSB_HDRC ++#ifdef CONFIG_USB_MUSB_OTG + device_remove_file(musb->controller, &dev_attr_srp); + #endif + #endif +@@ -2064,7 +2063,7 @@ + #ifdef CONFIG_SYSFS + device_remove_file(musb->controller, &dev_attr_mode); + device_remove_file(musb->controller, &dev_attr_vbus); +-#ifdef CONFIG_USB_GADGET_MUSB_HDRC ++#ifdef CONFIG_USB_MUSB_OTG + device_remove_file(musb->controller, &dev_attr_srp); + #endif + #endif +@@ -2244,10 +2243,10 @@ + return platform_driver_probe(&musb_driver, musb_probe); + } + +-/* make us init after usbcore and i2c (transceivers, regulators, etc) +- * and before usb gadget and host-side drivers start to register ++/* make us init after usbcore and before usb ++ * gadget and host-side drivers start to register + */ +-fs_initcall(musb_init); ++subsys_initcall(musb_init); + + static void __exit musb_cleanup(void) + { +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/drivers/usb/musb/musb_gadget.c linux-2.6.29-rc3.owrt/drivers/usb/musb/musb_gadget.c +--- linux-2.6.29.owrt/drivers/usb/musb/musb_gadget.c 2009-05-10 22:04:38.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/drivers/usb/musb/musb_gadget.c 2009-05-10 23:48:29.000000000 +0200 +@@ -575,7 +575,7 @@ + struct usb_request *request = &req->request; + struct musb_ep *musb_ep = &musb->endpoints[epnum].ep_out; + void __iomem *epio = musb->endpoints[epnum].regs; +- unsigned fifo_count = 0; ++ u16 fifo_count = 0; + u16 len = musb_ep->packet_sz; + + csr = musb_readw(epio, MUSB_RXCSR); +@@ -687,7 +687,7 @@ + len, fifo_count, + musb_ep->packet_sz); + +- fifo_count = min_t(unsigned, len, fifo_count); ++ fifo_count = min(len, fifo_count); + + #ifdef CONFIG_USB_TUSB_OMAP_DMA + if (tusb_dma_omap() && musb_ep->dma) { +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/drivers/usb/musb/musb_host.c linux-2.6.29-rc3.owrt/drivers/usb/musb/musb_host.c +--- linux-2.6.29.owrt/drivers/usb/musb/musb_host.c 2009-05-10 22:04:38.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/drivers/usb/musb/musb_host.c 2009-05-10 23:48:29.000000000 +0200 +@@ -335,11 +335,16 @@ + static struct musb_qh * + musb_giveback(struct musb_qh *qh, struct urb *urb, int status) + { ++ int is_in; + struct musb_hw_ep *ep = qh->hw_ep; + struct musb *musb = ep->musb; +- int is_in = usb_pipein(urb->pipe); + int ready = qh->is_ready; + ++ if (ep->is_shared_fifo) ++ is_in = 1; ++ else ++ is_in = usb_pipein(urb->pipe); ++ + /* save toggle eagerly, for paranoia */ + switch (qh->type) { + case USB_ENDPOINT_XFER_BULK: +@@ -427,7 +432,7 @@ + else + qh = musb_giveback(qh, urb, urb->status); + +- if (qh != NULL && qh->is_ready) { ++ if (qh && qh->is_ready && !list_empty(&qh->hep->urb_list)) { + DBG(4, "... next ep%d %cX urb %p\n", + hw_ep->epnum, is_in ? 'R' : 'T', + next_urb(qh)); +@@ -937,8 +942,8 @@ + switch (musb->ep0_stage) { + case MUSB_EP0_IN: + fifo_dest = urb->transfer_buffer + urb->actual_length; +- fifo_count = min_t(size_t, len, urb->transfer_buffer_length - +- urb->actual_length); ++ fifo_count = min(len, ((u16) (urb->transfer_buffer_length ++ - urb->actual_length))); + if (fifo_count < len) + urb->status = -EOVERFLOW; + +@@ -971,9 +976,10 @@ + } + /* FALLTHROUGH */ + case MUSB_EP0_OUT: +- fifo_count = min_t(size_t, qh->maxpacket, +- urb->transfer_buffer_length - +- urb->actual_length); ++ fifo_count = min(qh->maxpacket, ((u16) ++ (urb->transfer_buffer_length ++ - urb->actual_length))); ++ + if (fifo_count) { + fifo_dest = (u8 *) (urb->transfer_buffer + + urb->actual_length); +@@ -1155,8 +1161,7 @@ + struct urb *urb; + struct musb_hw_ep *hw_ep = musb->endpoints + epnum; + void __iomem *epio = hw_ep->regs; +- struct musb_qh *qh = hw_ep->is_shared_fifo ? hw_ep->in_qh +- : hw_ep->out_qh; ++ struct musb_qh *qh = hw_ep->out_qh; + u32 status = 0; + void __iomem *mbase = musb->mregs; + struct dma_channel *dma; +@@ -1303,8 +1308,7 @@ + * packets before updating TXCSR ... other docs disagree ... + */ + /* PIO: start next packet in this URB */ +- if (wLength > qh->maxpacket) +- wLength = qh->maxpacket; ++ wLength = min(qh->maxpacket, (u16) wLength); + musb_write_fifo(hw_ep, wLength, buf); + qh->segsize = wLength; + +@@ -1863,21 +1867,19 @@ + } + qh->type_reg = type_reg; + +- /* Precompute RXINTERVAL/TXINTERVAL register */ ++ /* precompute rxinterval/txinterval register */ ++ interval = min((u8)16, epd->bInterval); /* log encoding */ + switch (qh->type) { + case USB_ENDPOINT_XFER_INT: +- /* +- * Full/low speeds use the linear encoding, +- * high speed uses the logarithmic encoding. +- */ +- if (urb->dev->speed <= USB_SPEED_FULL) { +- interval = max_t(u8, epd->bInterval, 1); +- break; ++ /* fullspeed uses linear encoding */ ++ if (USB_SPEED_FULL == urb->dev->speed) { ++ interval = epd->bInterval; ++ if (!interval) ++ interval = 1; + } + /* FALLTHROUGH */ + case USB_ENDPOINT_XFER_ISOC: +- /* ISO always uses logarithmic encoding */ +- interval = min_t(u8, epd->bInterval, 16); ++ /* iso always uses log encoding */ + break; + default: + /* REVISIT we actually want to use NAK limits, hinting to the +@@ -2035,9 +2037,9 @@ + goto done; + + /* Any URB not actively programmed into endpoint hardware can be +- * immediately given back; that's any URB not at the head of an ++ * immediately given back. Such an URB must be at the head of its + * endpoint queue, unless someday we get real DMA queues. And even +- * if it's at the head, it might not be known to the hardware... ++ * then, it might not be known to the hardware... + * + * Otherwise abort current transfer, pending dma, etc.; urb->status + * has already been updated. This is a synchronous abort; it'd be +@@ -2076,15 +2078,6 @@ + qh->is_ready = 0; + __musb_giveback(musb, urb, 0); + qh->is_ready = ready; +- +- /* If nothing else (usually musb_giveback) is using it +- * and its URB list has emptied, recycle this qh. +- */ +- if (ready && list_empty(&qh->hep->urb_list)) { +- qh->hep->hcpriv = NULL; +- list_del(&qh->ring); +- kfree(qh); +- } + } else + ret = musb_cleanup_urb(urb, qh, urb->pipe & USB_DIR_IN); + done: +@@ -2100,15 +2093,14 @@ + unsigned long flags; + struct musb *musb = hcd_to_musb(hcd); + u8 is_in = epnum & USB_DIR_IN; +- struct musb_qh *qh; +- struct urb *urb; ++ struct musb_qh *qh = hep->hcpriv; ++ struct urb *urb, *tmp; + struct list_head *sched; + +- spin_lock_irqsave(&musb->lock, flags); ++ if (!qh) ++ return; + +- qh = hep->hcpriv; +- if (qh == NULL) +- goto exit; ++ spin_lock_irqsave(&musb->lock, flags); + + switch (qh->type) { + case USB_ENDPOINT_XFER_CONTROL: +@@ -2143,28 +2135,13 @@ + + /* cleanup */ + musb_cleanup_urb(urb, qh, urb->pipe & USB_DIR_IN); ++ } else ++ urb = NULL; + +- /* Then nuke all the others ... and advance the +- * queue on hw_ep (e.g. bulk ring) when we're done. +- */ +- while (!list_empty(&hep->urb_list)) { +- urb = next_urb(qh); +- urb->status = -ESHUTDOWN; +- musb_advance_schedule(musb, urb, qh->hw_ep, is_in); +- } +- } else { +- /* Just empty the queue; the hardware is busy with +- * other transfers, and since !qh->is_ready nothing +- * will activate any of these as it advances. +- */ +- while (!list_empty(&hep->urb_list)) +- __musb_giveback(musb, next_urb(qh), -ESHUTDOWN); ++ /* then just nuke all the others */ ++ list_for_each_entry_safe_from(urb, tmp, &hep->urb_list, urb_list) ++ musb_giveback(qh, urb, -ESHUTDOWN); + +- hep->hcpriv = NULL; +- list_del(&qh->ring); +- kfree(qh); +- } +-exit: + spin_unlock_irqrestore(&musb->lock, flags); + } + +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/drivers/usb/serial/aircable.c linux-2.6.29-rc3.owrt/drivers/usb/serial/aircable.c +--- linux-2.6.29.owrt/drivers/usb/serial/aircable.c 2009-05-10 22:04:38.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/drivers/usb/serial/aircable.c 2009-05-10 23:48:29.000000000 +0200 +@@ -621,9 +621,9 @@ + goto failed_usb_register; + return 0; + +-failed_usb_register: +- usb_serial_deregister(&aircable_device); + failed_serial_register: ++ usb_serial_deregister(&aircable_device); ++failed_usb_register: + return retval; + } + +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/drivers/usb/serial/cp2101.c linux-2.6.29-rc3.owrt/drivers/usb/serial/cp2101.c +--- linux-2.6.29.owrt/drivers/usb/serial/cp2101.c 2009-05-10 22:04:38.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/drivers/usb/serial/cp2101.c 2009-05-10 23:48:29.000000000 +0200 +@@ -79,7 +79,6 @@ + { USB_DEVICE(0x10C4, 0x814A) }, /* West Mountain Radio RIGblaster P&P */ + { USB_DEVICE(0x10C4, 0x814B) }, /* West Mountain Radio RIGtalk */ + { USB_DEVICE(0x10C4, 0x815E) }, /* Helicomm IP-Link 1220-DVM */ +- { USB_DEVICE(0x10C4, 0x819F) }, /* MJS USB Toslink Switcher */ + { USB_DEVICE(0x10C4, 0x81A6) }, /* ThinkOptics WavIt */ + { USB_DEVICE(0x10C4, 0x81AC) }, /* MSD Dash Hawk */ + { USB_DEVICE(0x10C4, 0x81C8) }, /* Lipowsky Industrie Elektronik GmbH, Baby-JTAG */ +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/drivers/usb/serial/ftdi_sio.c linux-2.6.29-rc3.owrt/drivers/usb/serial/ftdi_sio.c +--- linux-2.6.29.owrt/drivers/usb/serial/ftdi_sio.c 2009-05-10 22:04:38.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/drivers/usb/serial/ftdi_sio.c 2009-05-10 23:48:29.000000000 +0200 +@@ -662,12 +662,6 @@ + { USB_DEVICE(FTDI_VID, FTDI_DOMINTELL_DUSB_PID) }, + { USB_DEVICE(ALTI2_VID, ALTI2_N3_PID) }, + { USB_DEVICE(FTDI_VID, DIEBOLD_BCS_SE923_PID) }, +- { USB_DEVICE(FTDI_VID, FTDI_NDI_HUC_PID) }, +- { USB_DEVICE(ATMEL_VID, STK541_PID) }, +- { USB_DEVICE(DE_VID, STB_PID) }, +- { USB_DEVICE(DE_VID, WHT_PID) }, +- { USB_DEVICE(ADI_VID, ADI_GNICE_PID), +- .driver_info = (kernel_ulong_t)&ftdi_jtag_quirk }, + { }, /* Optional parameter entry */ + { } /* Terminating entry */ + }; +@@ -1070,10 +1064,8 @@ + + if (!capable(CAP_SYS_ADMIN)) { + if (((new_serial.flags & ~ASYNC_USR_MASK) != +- (priv->flags & ~ASYNC_USR_MASK))) { +- unlock_kernel(); ++ (priv->flags & ~ASYNC_USR_MASK))) + return -EPERM; +- } + priv->flags = ((priv->flags & ~ASYNC_USR_MASK) | + (new_serial.flags & ASYNC_USR_MASK)); + priv->custom_divisor = new_serial.custom_divisor; +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/drivers/usb/serial/ftdi_sio.h linux-2.6.29-rc3.owrt/drivers/usb/serial/ftdi_sio.h +--- linux-2.6.29.owrt/drivers/usb/serial/ftdi_sio.h 2009-05-10 22:04:38.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/drivers/usb/serial/ftdi_sio.h 2009-05-10 23:48:29.000000000 +0200 +@@ -844,9 +844,6 @@ + #define TML_VID 0x1B91 /* Vendor ID */ + #define TML_USB_SERIAL_PID 0x0064 /* USB - Serial Converter */ + +-/* NDI Polaris System */ +-#define FTDI_NDI_HUC_PID 0xDA70 +- + /* Propox devices */ + #define FTDI_PROPOX_JTAGCABLEII_PID 0xD738 + +@@ -893,26 +890,6 @@ + #define DIEBOLD_BCS_SE923_PID 0xfb99 + + /* +- * Atmel STK541 +- */ +-#define ATMEL_VID 0x03eb /* Vendor ID */ +-#define STK541_PID 0x2109 /* Zigbee Controller */ +- +-/* +- * Dresden Elektronic Sensor Terminal Board +- */ +-#define DE_VID 0x1cf1 /* Vendor ID */ +-#define STB_PID 0x0001 /* Sensor Terminal Board */ +-#define WHT_PID 0x0004 /* Wireless Handheld Terminal */ +- +-/* +- * Blackfin gnICE JTAG +- * http://docs.blackfin.uclinux.org/doku.php?id=hw:jtag:gnice +- */ +-#define ADI_VID 0x0456 +-#define ADI_GNICE_PID 0xF000 +- +-/* + * BmRequestType: 1100 0000b + * bRequest: FTDI_E2_READ + * wValue: 0 +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/drivers/usb/serial/option.c linux-2.6.29-rc3.owrt/drivers/usb/serial/option.c +--- linux-2.6.29.owrt/drivers/usb/serial/option.c 2009-05-10 22:04:38.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/drivers/usb/serial/option.c 2009-05-10 23:48:29.000000000 +0200 +@@ -89,7 +89,6 @@ + #define OPTION_PRODUCT_ETNA_MODEM_GT 0x7041 + #define OPTION_PRODUCT_ETNA_MODEM_EX 0x7061 + #define OPTION_PRODUCT_ETNA_KOI_MODEM 0x7100 +-#define OPTION_PRODUCT_GTM380_MODEM 0x7201 + + #define HUAWEI_VENDOR_ID 0x12D1 + #define HUAWEI_PRODUCT_E600 0x1001 +@@ -198,18 +197,16 @@ + /* OVATION PRODUCTS */ + #define NOVATELWIRELESS_PRODUCT_MC727 0x4100 + #define NOVATELWIRELESS_PRODUCT_MC950D 0x4400 +-#define NOVATELWIRELESS_PRODUCT_U727 0x5010 + + /* FUTURE NOVATEL PRODUCTS */ +-#define NOVATELWIRELESS_PRODUCT_EVDO_FULLSPEED 0X6000 +-#define NOVATELWIRELESS_PRODUCT_EVDO_HIGHSPEED 0X6001 +-#define NOVATELWIRELESS_PRODUCT_HSPA_FULLSPEED 0X7000 +-#define NOVATELWIRELESS_PRODUCT_HSPA_HIGHSPEED 0X7001 +-#define NOVATELWIRELESS_PRODUCT_EVDO_EMBEDDED_FULLSPEED 0X8000 +-#define NOVATELWIRELESS_PRODUCT_EVDO_EMBEDDED_HIGHSPEED 0X8001 +-#define NOVATELWIRELESS_PRODUCT_HSPA_EMBEDDED_FULLSPEED 0X9000 +-#define NOVATELWIRELESS_PRODUCT_HSPA_EMBEDDED_HIGHSPEED 0X9001 +-#define NOVATELWIRELESS_PRODUCT_GLOBAL 0XA001 ++#define NOVATELWIRELESS_PRODUCT_EVDO_1 0x6000 ++#define NOVATELWIRELESS_PRODUCT_HSPA_1 0x7000 ++#define NOVATELWIRELESS_PRODUCT_EMBEDDED_1 0x8000 ++#define NOVATELWIRELESS_PRODUCT_GLOBAL_1 0x9000 ++#define NOVATELWIRELESS_PRODUCT_EVDO_2 0x6001 ++#define NOVATELWIRELESS_PRODUCT_HSPA_2 0x7001 ++#define NOVATELWIRELESS_PRODUCT_EMBEDDED_2 0x8001 ++#define NOVATELWIRELESS_PRODUCT_GLOBAL_2 0x9001 + + /* AMOI PRODUCTS */ + #define AMOI_VENDOR_ID 0x1614 +@@ -219,27 +216,6 @@ + + #define DELL_VENDOR_ID 0x413C + +-/* Dell modems */ +-#define DELL_PRODUCT_5700_MINICARD 0x8114 +-#define DELL_PRODUCT_5500_MINICARD 0x8115 +-#define DELL_PRODUCT_5505_MINICARD 0x8116 +-#define DELL_PRODUCT_5700_EXPRESSCARD 0x8117 +-#define DELL_PRODUCT_5510_EXPRESSCARD 0x8118 +- +-#define DELL_PRODUCT_5700_MINICARD_SPRINT 0x8128 +-#define DELL_PRODUCT_5700_MINICARD_TELUS 0x8129 +- +-#define DELL_PRODUCT_5720_MINICARD_VZW 0x8133 +-#define DELL_PRODUCT_5720_MINICARD_SPRINT 0x8134 +-#define DELL_PRODUCT_5720_MINICARD_TELUS 0x8135 +-#define DELL_PRODUCT_5520_MINICARD_CINGULAR 0x8136 +-#define DELL_PRODUCT_5520_MINICARD_GENERIC_L 0x8137 +-#define DELL_PRODUCT_5520_MINICARD_GENERIC_I 0x8138 +- +-#define DELL_PRODUCT_5730_MINICARD_SPRINT 0x8180 +-#define DELL_PRODUCT_5730_MINICARD_TELUS 0x8181 +-#define DELL_PRODUCT_5730_MINICARD_VZW 0x8182 +- + #define KYOCERA_VENDOR_ID 0x0c88 + #define KYOCERA_PRODUCT_KPC650 0x17da + #define KYOCERA_PRODUCT_KPC680 0x180a +@@ -290,13 +266,19 @@ + + /* ZTE PRODUCTS */ + #define ZTE_VENDOR_ID 0x19d2 +-#define ZTE_PRODUCT_MF622 0x0001 + #define ZTE_PRODUCT_MF628 0x0015 + #define ZTE_PRODUCT_MF626 0x0031 + #define ZTE_PRODUCT_CDMA_TECH 0xfffe + +-#define BENQ_VENDOR_ID 0x04a5 +-#define BENQ_PRODUCT_H10 0x4068 ++/* Ericsson products */ ++#define ERICSSON_VENDOR_ID 0x0bdb ++#define ERICSSON_PRODUCT_F3507G 0x1900 ++ ++/* Pantech products */ ++#define PANTECH_VENDOR_ID 0x106c ++#define PANTECH_PRODUCT_PC5740 0x3701 ++#define PANTECH_PRODUCT_PC5750 0x3702 /* PX-500 */ ++#define PANTECH_PRODUCT_UM150 0x3711 + + static struct usb_device_id option_ids[] = { + { USB_DEVICE(OPTION_VENDOR_ID, OPTION_PRODUCT_COLT) }, +@@ -323,7 +305,6 @@ + { USB_DEVICE(OPTION_VENDOR_ID, OPTION_PRODUCT_ETNA_MODEM_GT) }, + { USB_DEVICE(OPTION_VENDOR_ID, OPTION_PRODUCT_ETNA_MODEM_EX) }, + { USB_DEVICE(OPTION_VENDOR_ID, OPTION_PRODUCT_ETNA_KOI_MODEM) }, +- { USB_DEVICE(OPTION_VENDOR_ID, OPTION_PRODUCT_GTM380_MODEM) }, + { USB_DEVICE(QUANTA_VENDOR_ID, QUANTA_PRODUCT_Q101) }, + { USB_DEVICE(QUANTA_VENDOR_ID, QUANTA_PRODUCT_Q111) }, + { USB_DEVICE(QUANTA_VENDOR_ID, QUANTA_PRODUCT_GLX) }, +@@ -414,37 +395,31 @@ + { USB_DEVICE(NOVATELWIRELESS_VENDOR_ID, NOVATELWIRELESS_PRODUCT_EU870D) }, /* Novatel EU850D/EU860D/EU870D */ + { USB_DEVICE(NOVATELWIRELESS_VENDOR_ID, NOVATELWIRELESS_PRODUCT_MC950D) }, /* Novatel MC930D/MC950D */ + { USB_DEVICE(NOVATELWIRELESS_VENDOR_ID, NOVATELWIRELESS_PRODUCT_MC727) }, /* Novatel MC727/U727/USB727 */ +- { USB_DEVICE(NOVATELWIRELESS_VENDOR_ID, NOVATELWIRELESS_PRODUCT_U727) }, /* Novatel MC727/U727/USB727 */ +- { USB_DEVICE(NOVATELWIRELESS_VENDOR_ID, NOVATELWIRELESS_PRODUCT_EVDO_FULLSPEED) }, /* Novatel EVDO product */ +- { USB_DEVICE(NOVATELWIRELESS_VENDOR_ID, NOVATELWIRELESS_PRODUCT_HSPA_FULLSPEED) }, /* Novatel HSPA product */ +- { USB_DEVICE(NOVATELWIRELESS_VENDOR_ID, NOVATELWIRELESS_PRODUCT_EVDO_EMBEDDED_FULLSPEED) }, /* Novatel EVDO Embedded product */ +- { USB_DEVICE(NOVATELWIRELESS_VENDOR_ID, NOVATELWIRELESS_PRODUCT_HSPA_EMBEDDED_FULLSPEED) }, /* Novatel HSPA Embedded product */ +- { USB_DEVICE(NOVATELWIRELESS_VENDOR_ID, NOVATELWIRELESS_PRODUCT_EVDO_HIGHSPEED) }, /* Novatel EVDO product */ +- { USB_DEVICE(NOVATELWIRELESS_VENDOR_ID, NOVATELWIRELESS_PRODUCT_HSPA_HIGHSPEED) }, /* Novatel HSPA product */ +- { USB_DEVICE(NOVATELWIRELESS_VENDOR_ID, NOVATELWIRELESS_PRODUCT_EVDO_EMBEDDED_HIGHSPEED) }, /* Novatel EVDO Embedded product */ +- { USB_DEVICE(NOVATELWIRELESS_VENDOR_ID, NOVATELWIRELESS_PRODUCT_HSPA_EMBEDDED_HIGHSPEED) }, /* Novatel HSPA Embedded product */ +- { USB_DEVICE(NOVATELWIRELESS_VENDOR_ID, NOVATELWIRELESS_PRODUCT_GLOBAL) }, /* Novatel Global product */ ++ { USB_DEVICE(NOVATELWIRELESS_VENDOR_ID, NOVATELWIRELESS_PRODUCT_EVDO_1) }, /* Novatel EVDO product */ ++ { USB_DEVICE(NOVATELWIRELESS_VENDOR_ID, NOVATELWIRELESS_PRODUCT_HSPA_1) }, /* Novatel HSPA product */ ++ { USB_DEVICE(NOVATELWIRELESS_VENDOR_ID, NOVATELWIRELESS_PRODUCT_EMBEDDED_1) }, /* Novatel Embedded product */ ++ { USB_DEVICE(NOVATELWIRELESS_VENDOR_ID, NOVATELWIRELESS_PRODUCT_GLOBAL_1) }, /* Novatel Global product */ ++ { USB_DEVICE(NOVATELWIRELESS_VENDOR_ID, NOVATELWIRELESS_PRODUCT_EVDO_2) }, /* Novatel EVDO product */ ++ { USB_DEVICE(NOVATELWIRELESS_VENDOR_ID, NOVATELWIRELESS_PRODUCT_HSPA_2) }, /* Novatel HSPA product */ ++ { USB_DEVICE(NOVATELWIRELESS_VENDOR_ID, NOVATELWIRELESS_PRODUCT_EMBEDDED_2) }, /* Novatel Embedded product */ ++ { USB_DEVICE(NOVATELWIRELESS_VENDOR_ID, NOVATELWIRELESS_PRODUCT_GLOBAL_2) }, /* Novatel Global product */ + + { USB_DEVICE(AMOI_VENDOR_ID, AMOI_PRODUCT_H01) }, + { USB_DEVICE(AMOI_VENDOR_ID, AMOI_PRODUCT_H01A) }, + { USB_DEVICE(AMOI_VENDOR_ID, AMOI_PRODUCT_H02) }, + +- { USB_DEVICE(DELL_VENDOR_ID, DELL_PRODUCT_5700_MINICARD) }, /* Dell Wireless 5700 Mobile Broadband CDMA/EVDO Mini-Card == Novatel Expedite EV620 CDMA/EV-DO */ +- { USB_DEVICE(DELL_VENDOR_ID, DELL_PRODUCT_5500_MINICARD) }, /* Dell Wireless 5500 Mobile Broadband HSDPA Mini-Card == Novatel Expedite EU740 HSDPA/3G */ +- { USB_DEVICE(DELL_VENDOR_ID, DELL_PRODUCT_5505_MINICARD) }, /* Dell Wireless 5505 Mobile Broadband HSDPA Mini-Card == Novatel Expedite EU740 HSDPA/3G */ +- { USB_DEVICE(DELL_VENDOR_ID, DELL_PRODUCT_5700_EXPRESSCARD) }, /* Dell Wireless 5700 Mobile Broadband CDMA/EVDO ExpressCard == Novatel Merlin XV620 CDMA/EV-DO */ +- { USB_DEVICE(DELL_VENDOR_ID, DELL_PRODUCT_5510_EXPRESSCARD) }, /* Dell Wireless 5510 Mobile Broadband HSDPA ExpressCard == Novatel Merlin XU870 HSDPA/3G */ +- { USB_DEVICE(DELL_VENDOR_ID, DELL_PRODUCT_5700_MINICARD_SPRINT) }, /* Dell Wireless 5700 Mobile Broadband CDMA/EVDO Mini-Card == Novatel Expedite E720 CDMA/EV-DO */ +- { USB_DEVICE(DELL_VENDOR_ID, DELL_PRODUCT_5700_MINICARD_TELUS) }, /* Dell Wireless 5700 Mobile Broadband CDMA/EVDO Mini-Card == Novatel Expedite ET620 CDMA/EV-DO */ +- { USB_DEVICE(DELL_VENDOR_ID, DELL_PRODUCT_5720_MINICARD_VZW) }, /* Dell Wireless 5720 == Novatel EV620 CDMA/EV-DO */ +- { USB_DEVICE(DELL_VENDOR_ID, DELL_PRODUCT_5720_MINICARD_SPRINT) }, /* Dell Wireless 5720 == Novatel EV620 CDMA/EV-DO */ +- { USB_DEVICE(DELL_VENDOR_ID, DELL_PRODUCT_5720_MINICARD_TELUS) }, /* Dell Wireless 5720 == Novatel EV620 CDMA/EV-DO */ +- { USB_DEVICE(DELL_VENDOR_ID, DELL_PRODUCT_5520_MINICARD_CINGULAR) }, /* Dell Wireless HSDPA 5520 == Novatel Expedite EU860D */ +- { USB_DEVICE(DELL_VENDOR_ID, DELL_PRODUCT_5520_MINICARD_GENERIC_L) }, /* Dell Wireless HSDPA 5520 */ +- { USB_DEVICE(DELL_VENDOR_ID, DELL_PRODUCT_5520_MINICARD_GENERIC_I) }, /* Dell Wireless 5520 Voda I Mobile Broadband (3G HSDPA) Minicard */ +- { USB_DEVICE(DELL_VENDOR_ID, DELL_PRODUCT_5730_MINICARD_SPRINT) }, /* Dell Wireless 5730 Mobile Broadband EVDO/HSPA Mini-Card */ +- { USB_DEVICE(DELL_VENDOR_ID, DELL_PRODUCT_5730_MINICARD_TELUS) }, /* Dell Wireless 5730 Mobile Broadband EVDO/HSPA Mini-Card */ +- { USB_DEVICE(DELL_VENDOR_ID, DELL_PRODUCT_5730_MINICARD_VZW) }, /* Dell Wireless 5730 Mobile Broadband EVDO/HSPA Mini-Card */ ++ { USB_DEVICE(DELL_VENDOR_ID, 0x8114) }, /* Dell Wireless 5700 Mobile Broadband CDMA/EVDO Mini-Card == Novatel Expedite EV620 CDMA/EV-DO */ ++ { USB_DEVICE(DELL_VENDOR_ID, 0x8115) }, /* Dell Wireless 5500 Mobile Broadband HSDPA Mini-Card == Novatel Expedite EU740 HSDPA/3G */ ++ { USB_DEVICE(DELL_VENDOR_ID, 0x8116) }, /* Dell Wireless 5505 Mobile Broadband HSDPA Mini-Card == Novatel Expedite EU740 HSDPA/3G */ ++ { USB_DEVICE(DELL_VENDOR_ID, 0x8117) }, /* Dell Wireless 5700 Mobile Broadband CDMA/EVDO ExpressCard == Novatel Merlin XV620 CDMA/EV-DO */ ++ { USB_DEVICE(DELL_VENDOR_ID, 0x8118) }, /* Dell Wireless 5510 Mobile Broadband HSDPA ExpressCard == Novatel Merlin XU870 HSDPA/3G */ ++ { USB_DEVICE(DELL_VENDOR_ID, 0x8128) }, /* Dell Wireless 5700 Mobile Broadband CDMA/EVDO Mini-Card == Novatel Expedite E720 CDMA/EV-DO */ ++ { USB_DEVICE(DELL_VENDOR_ID, 0x8129) }, /* Dell Wireless 5700 Mobile Broadband CDMA/EVDO Mini-Card == Novatel Expedite ET620 CDMA/EV-DO */ ++ { USB_DEVICE(DELL_VENDOR_ID, 0x8133) }, /* Dell Wireless 5720 == Novatel EV620 CDMA/EV-DO */ ++ { USB_DEVICE(DELL_VENDOR_ID, 0x8136) }, /* Dell Wireless HSDPA 5520 == Novatel Expedite EU860D */ ++ { USB_DEVICE(DELL_VENDOR_ID, 0x8137) }, /* Dell Wireless HSDPA 5520 */ ++ { USB_DEVICE(DELL_VENDOR_ID, 0x8138) }, /* Dell Wireless 5520 Voda I Mobile Broadband (3G HSDPA) Minicard */ ++ { USB_DEVICE(DELL_VENDOR_ID, 0x8147) }, /* Dell Wireless 5530 Mobile Broadband (3G HSPA) Mini-Card */ + { USB_DEVICE(ANYDATA_VENDOR_ID, ANYDATA_PRODUCT_ADU_E100A) }, /* ADU-E100, ADU-310 */ + { USB_DEVICE(ANYDATA_VENDOR_ID, ANYDATA_PRODUCT_ADU_500A) }, + { USB_DEVICE(ANYDATA_VENDOR_ID, ANYDATA_PRODUCT_ADU_620UW) }, +@@ -509,12 +484,13 @@ + { USB_DEVICE(QUALCOMM_VENDOR_ID, 0x6613)}, /* Onda H600/ZTE MF330 */ + { USB_DEVICE(MAXON_VENDOR_ID, 0x6280) }, /* BP3-USB & BP3-EXT HSDPA */ + { USB_DEVICE(TELIT_VENDOR_ID, TELIT_PRODUCT_UC864E) }, +- { USB_DEVICE(ZTE_VENDOR_ID, ZTE_PRODUCT_MF622) }, + { USB_DEVICE(ZTE_VENDOR_ID, ZTE_PRODUCT_MF626) }, + { USB_DEVICE(ZTE_VENDOR_ID, ZTE_PRODUCT_MF628) }, + { USB_DEVICE(ZTE_VENDOR_ID, ZTE_PRODUCT_CDMA_TECH) }, +- { USB_DEVICE(BENQ_VENDOR_ID, BENQ_PRODUCT_H10) }, +- { USB_DEVICE(0x1da5, 0x4515) }, /* BenQ H20 */ ++ { USB_DEVICE(ERICSSON_VENDOR_ID, ERICSSON_PRODUCT_F3507G) }, ++ { USB_DEVICE(PANTECH_VENDOR_ID, PANTECH_PRODUCT_PC5740) }, ++ { USB_DEVICE(PANTECH_VENDOR_ID, PANTECH_PRODUCT_PC5750) }, ++ { USB_DEVICE(PANTECH_VENDOR_ID, PANTECH_PRODUCT_UM150) }, + { } /* Terminating entry */ + }; + MODULE_DEVICE_TABLE(usb, option_ids); +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/drivers/usb/serial/ti_usb_3410_5052.c linux-2.6.29-rc3.owrt/drivers/usb/serial/ti_usb_3410_5052.c +--- linux-2.6.29.owrt/drivers/usb/serial/ti_usb_3410_5052.c 2009-05-10 22:04:38.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/drivers/usb/serial/ti_usb_3410_5052.c 2009-05-10 23:48:29.000000000 +0200 +@@ -176,7 +176,7 @@ + /* the array dimension is the number of default entries plus */ + /* TI_EXTRA_VID_PID_COUNT user defined entries plus 1 terminating */ + /* null entry */ +-static struct usb_device_id ti_id_table_3410[10+TI_EXTRA_VID_PID_COUNT+1] = { ++static struct usb_device_id ti_id_table_3410[7+TI_EXTRA_VID_PID_COUNT+1] = { + { USB_DEVICE(TI_VENDOR_ID, TI_3410_PRODUCT_ID) }, + { USB_DEVICE(TI_VENDOR_ID, TI_3410_EZ430_ID) }, + { USB_DEVICE(MTS_VENDOR_ID, MTS_GSM_NO_FW_PRODUCT_ID) }, +@@ -185,11 +185,9 @@ + { USB_DEVICE(MTS_VENDOR_ID, MTS_GSM_PRODUCT_ID) }, + { USB_DEVICE(MTS_VENDOR_ID, MTS_EDGE_PRODUCT_ID) }, + { USB_DEVICE(IBM_VENDOR_ID, IBM_4543_PRODUCT_ID) }, +- { USB_DEVICE(IBM_VENDOR_ID, IBM_454B_PRODUCT_ID) }, +- { USB_DEVICE(IBM_VENDOR_ID, IBM_454C_PRODUCT_ID) }, + }; + +-static struct usb_device_id ti_id_table_5052[5+TI_EXTRA_VID_PID_COUNT+1] = { ++static struct usb_device_id ti_id_table_5052[4+TI_EXTRA_VID_PID_COUNT+1] = { + { USB_DEVICE(TI_VENDOR_ID, TI_5052_BOOT_PRODUCT_ID) }, + { USB_DEVICE(TI_VENDOR_ID, TI_5152_BOOT_PRODUCT_ID) }, + { USB_DEVICE(TI_VENDOR_ID, TI_5052_EEPROM_PRODUCT_ID) }, +@@ -197,7 +195,7 @@ + { USB_DEVICE(IBM_VENDOR_ID, IBM_4543_PRODUCT_ID) }, + }; + +-static struct usb_device_id ti_id_table_combined[14+2*TI_EXTRA_VID_PID_COUNT+1] = { ++static struct usb_device_id ti_id_table_combined[6+2*TI_EXTRA_VID_PID_COUNT+1] = { + { USB_DEVICE(TI_VENDOR_ID, TI_3410_PRODUCT_ID) }, + { USB_DEVICE(TI_VENDOR_ID, TI_3410_EZ430_ID) }, + { USB_DEVICE(MTS_VENDOR_ID, MTS_GSM_NO_FW_PRODUCT_ID) }, +@@ -210,8 +208,6 @@ + { USB_DEVICE(TI_VENDOR_ID, TI_5052_EEPROM_PRODUCT_ID) }, + { USB_DEVICE(TI_VENDOR_ID, TI_5052_FIRMWARE_PRODUCT_ID) }, + { USB_DEVICE(IBM_VENDOR_ID, IBM_4543_PRODUCT_ID) }, +- { USB_DEVICE(IBM_VENDOR_ID, IBM_454B_PRODUCT_ID) }, +- { USB_DEVICE(IBM_VENDOR_ID, IBM_454C_PRODUCT_ID) }, + { } + }; + +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/drivers/usb/serial/ti_usb_3410_5052.h linux-2.6.29-rc3.owrt/drivers/usb/serial/ti_usb_3410_5052.h +--- linux-2.6.29.owrt/drivers/usb/serial/ti_usb_3410_5052.h 2009-05-10 22:04:38.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/drivers/usb/serial/ti_usb_3410_5052.h 2009-05-10 23:48:29.000000000 +0200 +@@ -30,8 +30,6 @@ + #define IBM_VENDOR_ID 0x04b3 + #define TI_3410_PRODUCT_ID 0x3410 + #define IBM_4543_PRODUCT_ID 0x4543 +-#define IBM_454B_PRODUCT_ID 0x454b +-#define IBM_454C_PRODUCT_ID 0x454c + #define TI_3410_EZ430_ID 0xF430 /* TI ez430 development tool */ + #define TI_5052_BOOT_PRODUCT_ID 0x5052 /* no EEPROM, no firmware */ + #define TI_5152_BOOT_PRODUCT_ID 0x5152 /* no EEPROM, no firmware */ +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/drivers/usb/storage/scsiglue.c linux-2.6.29-rc3.owrt/drivers/usb/storage/scsiglue.c +--- linux-2.6.29.owrt/drivers/usb/storage/scsiglue.c 2009-05-10 22:04:38.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/drivers/usb/storage/scsiglue.c 2009-05-10 23:48:29.000000000 +0200 +@@ -64,7 +64,6 @@ + */ + #define VENDOR_ID_NOKIA 0x0421 + #define VENDOR_ID_NIKON 0x04b0 +-#define VENDOR_ID_PENTAX 0x0a17 + #define VENDOR_ID_MOTOROLA 0x22b8 + + /*********************************************************************** +@@ -159,7 +158,6 @@ + switch (le16_to_cpu(us->pusb_dev->descriptor.idVendor)) { + case VENDOR_ID_NOKIA: + case VENDOR_ID_NIKON: +- case VENDOR_ID_PENTAX: + case VENDOR_ID_MOTOROLA: + if (!(us->fflags & (US_FL_FIX_CAPACITY | + US_FL_CAPACITY_OK))) +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/drivers/usb/storage/transport.c linux-2.6.29-rc3.owrt/drivers/usb/storage/transport.c +--- linux-2.6.29.owrt/drivers/usb/storage/transport.c 2009-05-10 22:04:38.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/drivers/usb/storage/transport.c 2009-05-10 23:48:29.000000000 +0200 +@@ -558,10 +558,32 @@ + + if (srb->result == SAM_STAT_GOOD && scsi_get_resid(srb) == 0) { + +- /* The command succeeded. We know this device doesn't +- * have the last-sector bug, so stop checking it. ++ /* The command succeeded. If the capacity is odd ++ * (i.e., if the sector number is even) then the ++ * "always-even" heuristic would be wrong for this ++ * device. Issue a WARN() so that the kerneloops.org ++ * project will be notified and we will then know to ++ * mark the device with a CAPACITY_OK flag. Hopefully ++ * this will occur for only a few devices. ++ * ++ * Use the sign of us->last_sector_hacks to tell whether ++ * the warning has already been issued; we don't need ++ * more than one warning per device. + */ +- us->use_last_sector_hacks = 0; ++ if (!(sector & 1) && us->use_last_sector_hacks > 0) { ++ unsigned vid = le16_to_cpu( ++ us->pusb_dev->descriptor.idVendor); ++ unsigned pid = le16_to_cpu( ++ us->pusb_dev->descriptor.idProduct); ++ unsigned rev = le16_to_cpu( ++ us->pusb_dev->descriptor.bcdDevice); ++ ++ WARN(1, "%s: Successful last sector success at %u, " ++ "device %04x:%04x:%04x\n", ++ sdkp->disk->disk_name, sector, ++ vid, pid, rev); ++ us->use_last_sector_hacks = -1; ++ } + + } else { + /* The command failed. Allow up to 3 retries in case this +@@ -577,6 +599,14 @@ + srb->result = SAM_STAT_CHECK_CONDITION; + memcpy(srb->sense_buffer, record_not_found, + sizeof(record_not_found)); ++ ++ /* In theory we might want to issue a WARN() here if the ++ * capacity is even, since it could indicate the device ++ * has the READ CAPACITY bug _and_ the real capacity is ++ * odd. But it could also indicate that the device ++ * simply can't access its last sector, a failure mode ++ * which is surprisingly common. So no warning. ++ */ + } + + done: +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/drivers/usb/storage/unusual_devs.h linux-2.6.29-rc3.owrt/drivers/usb/storage/unusual_devs.h +--- linux-2.6.29.owrt/drivers/usb/storage/unusual_devs.h 2009-05-10 22:04:38.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/drivers/usb/storage/unusual_devs.h 2009-05-10 23:48:29.000000000 +0200 +@@ -226,7 +226,7 @@ + US_FL_MAX_SECTORS_64 ), + + /* Reported by Manuel Osdoba <manuel.osdoba@tu-ilmenau.de> */ +-UNUSUAL_DEV( 0x0421, 0x0492, 0x0452, 0x9999, ++UNUSUAL_DEV( 0x0421, 0x0492, 0x0452, 0x0452, + "Nokia", + "Nokia 6233", + US_SC_DEVICE, US_PR_DEVICE, NULL, +@@ -907,13 +907,13 @@ + "Genesys Logic", + "USB to IDE Optical", + US_SC_DEVICE, US_PR_DEVICE, NULL, +- US_FL_GO_SLOW | US_FL_MAX_SECTORS_64 | US_FL_IGNORE_RESIDUE ), ++ US_FL_GO_SLOW | US_FL_MAX_SECTORS_64 ), + + UNUSUAL_DEV( 0x05e3, 0x0702, 0x0000, 0xffff, + "Genesys Logic", + "USB to IDE Disk", + US_SC_DEVICE, US_PR_DEVICE, NULL, +- US_FL_GO_SLOW | US_FL_MAX_SECTORS_64 | US_FL_IGNORE_RESIDUE ), ++ US_FL_GO_SLOW | US_FL_MAX_SECTORS_64 ), + + /* Reported by Ben Efros <ben@pc-doctor.com> */ + UNUSUAL_DEV( 0x05e3, 0x0723, 0x9451, 0x9451, +@@ -951,9 +951,7 @@ + US_FL_FIX_CAPACITY ), + + /* Reported by Richard -=[]=- <micro_flyer@hotmail.com> */ +-/* Change to bcdDeviceMin (0x0100 to 0x0001) reported by +- * Thomas Bartosik <tbartdev@gmx-topmail.de> */ +-UNUSUAL_DEV( 0x067b, 0x2507, 0x0001, 0x0100, ++UNUSUAL_DEV( 0x067b, 0x2507, 0x0100, 0x0100, + "Prolific Technology Inc.", + "Mass Storage Device", + US_SC_DEVICE, US_PR_DEVICE, NULL, +@@ -1216,7 +1214,7 @@ + "Datafab", + "KECF-USB", + US_SC_DEVICE, US_PR_DEVICE, NULL, +- US_FL_FIX_INQUIRY | US_FL_FIX_CAPACITY ), ++ US_FL_FIX_INQUIRY ), + + /* Reported by Rauch Wolke <rauchwolke@gmx.net> */ + UNUSUAL_DEV( 0x07c4, 0xa4a5, 0x0000, 0xffff, +@@ -1356,6 +1354,21 @@ + US_SC_DEVICE, US_PR_DEVICE, NULL, + US_FL_FIX_INQUIRY ), + ++ ++/* Submitted by Per Winkvist <per.winkvist@uk.com> */ ++UNUSUAL_DEV( 0x0a17, 0x006, 0x0000, 0xffff, ++ "Pentax", ++ "Optio S/S4", ++ US_SC_DEVICE, US_PR_DEVICE, NULL, ++ US_FL_FIX_INQUIRY ), ++ ++/* Reported by Jaak Ristioja <Ristioja@gmail.com> */ ++UNUSUAL_DEV( 0x0a17, 0x006e, 0x0100, 0x0100, ++ "Pentax", ++ "K10D", ++ US_SC_DEVICE, US_PR_DEVICE, NULL, ++ US_FL_FIX_CAPACITY ), ++ + /* These are virtual windows driver CDs, which the zd1211rw driver + * automatically converts into WLAN devices. */ + UNUSUAL_DEV( 0x0ace, 0x2011, 0x0101, 0x0101, +@@ -1392,16 +1405,6 @@ + US_SC_DEVICE, US_PR_DEVICE, NULL, + 0 ), + +-/* Reported by Jan Dumon <j.dumon@option.com> +- * This device (wrongly) has a vendor-specific device descriptor. +- * The entry is needed so usb-storage can bind to it's mass-storage +- * interface as an interface driver */ +-UNUSUAL_DEV( 0x0af0, 0x7501, 0x0000, 0x0000, +- "Option", +- "GI 0431 SD-Card", +- US_SC_DEVICE, US_PR_DEVICE, NULL, +- 0 ), +- + /* Reported by Ben Efros <ben@pc-doctor.com> */ + UNUSUAL_DEV( 0x0bc2, 0x3010, 0x0000, 0x0000, + "Seagate", +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/drivers/usb/wusbcore/devconnect.c linux-2.6.29-rc3.owrt/drivers/usb/wusbcore/devconnect.c +--- linux-2.6.29.owrt/drivers/usb/wusbcore/devconnect.c 2009-05-10 22:04:38.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/drivers/usb/wusbcore/devconnect.c 2009-05-10 23:48:29.000000000 +0200 +@@ -386,7 +386,6 @@ + | USB_PORT_STAT_LOW_SPEED | USB_PORT_STAT_HIGH_SPEED); + port->change |= USB_PORT_STAT_C_CONNECTION | USB_PORT_STAT_C_ENABLE; + if (wusb_dev) { +- dev_dbg(wusbhc->dev, "disconnecting device from port %d\n", wusb_dev->port_idx); + if (!list_empty(&wusb_dev->cack_node)) + list_del_init(&wusb_dev->cack_node); + /* For the one in cack_add() */ +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/drivers/usb/wusbcore/rh.c linux-2.6.29-rc3.owrt/drivers/usb/wusbcore/rh.c +--- linux-2.6.29.owrt/drivers/usb/wusbcore/rh.c 2009-05-10 22:04:38.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/drivers/usb/wusbcore/rh.c 2009-05-10 23:48:29.000000000 +0200 +@@ -100,9 +100,6 @@ + struct wusb_port *port = wusb_port_by_idx(wusbhc, port_idx); + struct wusb_dev *wusb_dev = port->wusb_dev; + +- if (wusb_dev == NULL) +- return -ENOTCONN; +- + port->status |= USB_PORT_STAT_RESET; + port->change |= USB_PORT_STAT_C_RESET; + +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/drivers/usb/wusbcore/wa-xfer.c linux-2.6.29-rc3.owrt/drivers/usb/wusbcore/wa-xfer.c +--- linux-2.6.29.owrt/drivers/usb/wusbcore/wa-xfer.c 2009-05-10 22:04:38.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/drivers/usb/wusbcore/wa-xfer.c 2009-05-10 23:48:29.000000000 +0200 +@@ -921,10 +921,8 @@ + result = -ENODEV; + /* FIXME: segmentation broken -- kills DWA */ + mutex_lock(&wusbhc->mutex); /* get a WUSB dev */ +- if (urb->dev == NULL) { +- mutex_unlock(&wusbhc->mutex); ++ if (urb->dev == NULL) + goto error_dev_gone; +- } + wusb_dev = __wusb_dev_get_by_usb_dev(wusbhc, urb->dev); + if (wusb_dev == NULL) { + mutex_unlock(&wusbhc->mutex); +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/drivers/uwb/allocator.c linux-2.6.29-rc3.owrt/drivers/uwb/allocator.c +--- linux-2.6.29.owrt/drivers/uwb/allocator.c 2009-05-10 22:04:38.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/drivers/uwb/allocator.c 2009-05-10 23:48:29.000000000 +0200 +@@ -15,6 +15,7 @@ + * You should have received a copy of the GNU General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. + */ ++#include <linux/version.h> + #include <linux/kernel.h> + #include <linux/uwb.h> + +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/drivers/uwb/drp.c linux-2.6.29-rc3.owrt/drivers/uwb/drp.c +--- linux-2.6.29.owrt/drivers/uwb/drp.c 2009-05-10 22:04:38.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/drivers/uwb/drp.c 2009-05-10 23:48:29.000000000 +0200 +@@ -66,14 +66,14 @@ + } else + dev_err(&rc->uwb_dev.dev, "SET-DRP-IE: timeout\n"); + +- spin_lock_bh(&rc->rsvs_lock); ++ spin_lock(&rc->rsvs_lock); + if (rc->set_drp_ie_pending > 1) { + rc->set_drp_ie_pending = 0; + uwb_rsv_queue_update(rc); + } else { + rc->set_drp_ie_pending = 0; + } +- spin_unlock_bh(&rc->rsvs_lock); ++ spin_unlock(&rc->rsvs_lock); + } + + /** +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/drivers/uwb/rsv.c linux-2.6.29-rc3.owrt/drivers/uwb/rsv.c +--- linux-2.6.29.owrt/drivers/uwb/rsv.c 2009-05-10 22:04:38.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/drivers/uwb/rsv.c 2009-05-10 23:48:29.000000000 +0200 +@@ -114,8 +114,7 @@ + devaddr = rsv->target.devaddr; + uwb_dev_addr_print(target, sizeof(target), &devaddr); + +- dev_dbg(dev, "rsv %s %s -> %s: %s\n", +- text, owner, target, uwb_rsv_state_str(rsv->state)); ++ dev_dbg(dev, "rsv %s -> %s: %s\n", owner, target, uwb_rsv_state_str(rsv->state)); + } + + static void uwb_rsv_release(struct kref *kref) +@@ -512,7 +511,8 @@ + + if (uwb_rsv_is_owner(rsv)) + uwb_rsv_put_stream(rsv); +- ++ ++ del_timer_sync(&rsv->timer); + uwb_dev_put(rsv->owner); + if (rsv->target.type == UWB_RSV_TARGET_DEV) + uwb_dev_put(rsv->target.dev); +@@ -870,7 +870,7 @@ + */ + void uwb_rsv_sched_update(struct uwb_rc *rc) + { +- spin_lock_bh(&rc->rsvs_lock); ++ spin_lock(&rc->rsvs_lock); + if (!delayed_work_pending(&rc->rsv_update_work)) { + if (rc->set_drp_ie_pending > 0) { + rc->set_drp_ie_pending++; +@@ -879,7 +879,7 @@ + uwb_rsv_queue_update(rc); + } + unlock: +- spin_unlock_bh(&rc->rsvs_lock); ++ spin_unlock(&rc->rsvs_lock); + } + + /* +@@ -943,22 +943,13 @@ + + mutex_lock(&rc->rsvs_mutex); + list_for_each_entry_safe(rsv, t, &rc->reservations, rc_node) { +- if (rsv->state != UWB_RSV_STATE_NONE) +- uwb_rsv_set_state(rsv, UWB_RSV_STATE_NONE); +- del_timer_sync(&rsv->timer); ++ uwb_rsv_remove(rsv); + } + /* Cancel any postponed update. */ + rc->set_drp_ie_pending = 0; + mutex_unlock(&rc->rsvs_mutex); + + cancel_delayed_work_sync(&rc->rsv_update_work); +- flush_workqueue(rc->rsv_workq); +- +- mutex_lock(&rc->rsvs_mutex); +- list_for_each_entry_safe(rsv, t, &rc->reservations, rc_node) { +- uwb_rsv_remove(rsv); +- } +- mutex_unlock(&rc->rsvs_mutex); + } + + void uwb_rsv_init(struct uwb_rc *rc) +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/drivers/video/atafb.c linux-2.6.29-rc3.owrt/drivers/video/atafb.c +--- linux-2.6.29.owrt/drivers/video/atafb.c 2009-05-10 22:04:38.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/drivers/video/atafb.c 2009-05-10 23:48:29.000000000 +0200 +@@ -841,7 +841,7 @@ + tt_dmasnd.ctrl = DMASND_CTRL_OFF; + udelay(20); /* wait a while for things to settle down */ + } +- mono_moni = (st_mfp.par_dt_reg & 0x80) == 0; ++ mono_moni = (mfp.par_dt_reg & 0x80) == 0; + + tt_get_par(&par); + tt_encode_var(&atafb_predefined[0], &par); +@@ -2035,7 +2035,7 @@ + tt_dmasnd.ctrl = DMASND_CTRL_OFF; + udelay(20); /* wait a while for things to settle down */ + } +- mono_moni = (st_mfp.par_dt_reg & 0x80) == 0; ++ mono_moni = (mfp.par_dt_reg & 0x80) == 0; + + stste_get_par(&par); + stste_encode_var(&atafb_predefined[0], &par); +@@ -2086,20 +2086,20 @@ + return; + local_irq_save(flags); + +- st_mfp.tim_ct_b = 0x10; +- st_mfp.active_edge |= 8; +- st_mfp.tim_ct_b = 0; +- st_mfp.tim_dt_b = 0xf0; +- st_mfp.tim_ct_b = 8; +- while (st_mfp.tim_dt_b > 1) /* TOS does it this way, don't ask why */ ++ mfp.tim_ct_b = 0x10; ++ mfp.active_edge |= 8; ++ mfp.tim_ct_b = 0; ++ mfp.tim_dt_b = 0xf0; ++ mfp.tim_ct_b = 8; ++ while (mfp.tim_dt_b > 1) /* TOS does it this way, don't ask why */ + ; +- new = st_mfp.tim_dt_b; ++ new = mfp.tim_dt_b; + do { + udelay(LINE_DELAY); + old = new; +- new = st_mfp.tim_dt_b; ++ new = mfp.tim_dt_b; + } while (old != new); +- st_mfp.tim_ct_b = 0x10; ++ mfp.tim_ct_b = 0x10; + udelay(SYNC_DELAY); + + if (atari_switches & ATARI_SWITCH_OVSC_IKBD) +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/drivers/video/aty/aty128fb.c linux-2.6.29-rc3.owrt/drivers/video/aty/aty128fb.c +--- linux-2.6.29.owrt/drivers/video/aty/aty128fb.c 2009-05-10 22:04:38.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/drivers/video/aty/aty128fb.c 2009-05-10 23:48:29.000000000 +0200 +@@ -1475,7 +1475,7 @@ + aty128_set_pll(&par->pll, par); + aty128_set_fifo(&par->fifo_reg, par); + +- config = aty_ld_le32(CNFG_CNTL) & ~3; ++ config = aty_ld_le32(CONFIG_CNTL) & ~3; + + #if defined(__BIG_ENDIAN) + if (par->crtc.bpp == 32) +@@ -1484,7 +1484,7 @@ + config |= 1; /* make aperture do 16 bit swapping */ + #endif + +- aty_st_le32(CNFG_CNTL, config); ++ aty_st_le32(CONFIG_CNTL, config); + aty_st_8(CRTC_EXT_CNTL + 1, 0); /* turn the video back on */ + + info->fix.line_length = (par->crtc.vxres * par->crtc.bpp) >> 3; +@@ -1853,14 +1853,13 @@ + * Initialisation + */ + +-#ifdef CONFIG_PPC_PMAC__disabled ++#ifdef CONFIG_PPC_PMAC + static void aty128_early_resume(void *data) + { + struct aty128fb_par *par = data; + + if (try_acquire_console_sem()) + return; +- pci_restore_state(par->pdev); + aty128_do_resume(par->pdev); + release_console_sem(); + } +@@ -1876,7 +1875,7 @@ + u32 dac; + + /* Get the chip revision */ +- chip_rev = (aty_ld_le32(CNFG_CNTL) >> 16) & 0x1F; ++ chip_rev = (aty_ld_le32(CONFIG_CNTL) >> 16) & 0x1F; + + strcpy(video_card, "Rage128 XX "); + video_card[8] = ent->device >> 8; +@@ -1908,14 +1907,7 @@ + /* Indicate sleep capability */ + if (par->chip_gen == rage_M3) { + pmac_call_feature(PMAC_FTR_DEVICE_CAN_WAKE, NULL, 0, 1); +-#if 0 /* Disable the early video resume hack for now as it's causing problems, among +- * others we now rely on the PCI core restoring the config space for us, which +- * isn't the case with that hack, and that code path causes various things to +- * be called with interrupts off while they shouldn't. I'm leaving the code in +- * as it can be useful for debugging purposes +- */ + pmac_set_early_video_resume(aty128_early_resume, par); +-#endif + } + + /* Find default mode */ +@@ -2065,7 +2057,7 @@ + + /* Grab memory size from the card */ + // How does this relate to the resource length from the PCI hardware? +- par->vram_size = aty_ld_le32(CNFG_MEMSIZE) & 0x03FFFFFF; ++ par->vram_size = aty_ld_le32(CONFIG_MEMSIZE) & 0x03FFFFFF; + + /* Virtualize the framebuffer */ + info->screen_base = ioremap(fb_addr, par->vram_size); +@@ -2373,6 +2365,7 @@ + static void aty128_set_suspend(struct aty128fb_par *par, int suspend) + { + u32 pmgt; ++ u16 pwr_command; + struct pci_dev *pdev = par->pdev; + + if (!par->pm_reg) +@@ -2381,8 +2374,6 @@ + /* Set the chip into the appropriate suspend mode (we use D2, + * D3 would require a complete re-initialisation of the chip, + * including PCI config registers, clocks, AGP configuration, ...) +- * +- * For resume, the core will have already brought us back to D0 + */ + if (suspend) { + /* Make sure CRTC2 is reset. Remove that the day we decide to +@@ -2400,9 +2391,17 @@ + aty_st_le32(BUS_CNTL1, 0x00000010); + aty_st_le32(MEM_POWER_MISC, 0x0c830000); + mdelay(100); +- ++ pci_read_config_word(pdev, par->pm_reg+PCI_PM_CTRL, &pwr_command); + /* Switch PCI power management to D2 */ +- pci_set_power_state(pdev, PCI_D2); ++ pci_write_config_word(pdev, par->pm_reg+PCI_PM_CTRL, ++ (pwr_command & ~PCI_PM_CTRL_STATE_MASK) | 2); ++ pci_read_config_word(pdev, par->pm_reg+PCI_PM_CTRL, &pwr_command); ++ } else { ++ /* Switch back PCI power management to D0 */ ++ mdelay(100); ++ pci_write_config_word(pdev, par->pm_reg+PCI_PM_CTRL, 0); ++ pci_read_config_word(pdev, par->pm_reg+PCI_PM_CTRL, &pwr_command); ++ mdelay(100); + } + } + +@@ -2411,12 +2410,6 @@ + struct fb_info *info = pci_get_drvdata(pdev); + struct aty128fb_par *par = info->par; + +- /* Because we may change PCI D state ourselves, we need to +- * first save the config space content so the core can +- * restore it properly on resume. +- */ +- pci_save_state(pdev); +- + /* We don't do anything but D2, for now we return 0, but + * we may want to change that. How do we know if the BIOS + * can properly take care of D3 ? Also, with swsusp, we +@@ -2483,11 +2476,6 @@ + if (pdev->dev.power.power_state.event == PM_EVENT_ON) + return 0; + +- /* PCI state will have been restored by the core, so +- * we should be in D0 now with our config space fully +- * restored +- */ +- + /* Wakeup chip */ + aty128_set_suspend(par, 0); + par->asleep = 0; +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/drivers/video/aty/atyfb_base.c linux-2.6.29-rc3.owrt/drivers/video/aty/atyfb_base.c +--- linux-2.6.29.owrt/drivers/video/aty/atyfb_base.c 2009-05-10 22:04:38.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/drivers/video/aty/atyfb_base.c 2009-05-10 23:48:29.000000000 +0200 +@@ -135,7 +135,7 @@ + #if defined(CONFIG_PM) || defined(CONFIG_PMAC_BACKLIGHT) || \ + defined (CONFIG_FB_ATY_GENERIC_LCD) || defined(CONFIG_FB_ATY_BACKLIGHT) + static const u32 lt_lcd_regs[] = { +- CNFG_PANEL_LG, ++ CONFIG_PANEL_LG, + LCD_GEN_CNTL_LG, + DSTN_CONTROL_LG, + HFB_PITCH_ADDR_LG, +@@ -446,7 +446,7 @@ + par->pll_limits.ecp_max = aty_chips[i].ecp_max; + par->features = aty_chips[i].features; + +- chip_id = aty_ld_le32(CNFG_CHIP_ID, par); ++ chip_id = aty_ld_le32(CONFIG_CHIP_ID, par); + type = chip_id & CFG_CHIP_TYPE; + rev = (chip_id & CFG_CHIP_REV) >> 24; + +@@ -629,7 +629,7 @@ + crtc->lcd_index = aty_ld_le32(LCD_INDEX, par); + aty_st_le32(LCD_INDEX, crtc->lcd_index, par); + } +- crtc->lcd_config_panel = aty_ld_lcd(CNFG_PANEL, par); ++ crtc->lcd_config_panel = aty_ld_lcd(CONFIG_PANEL, par); + crtc->lcd_gen_cntl = aty_ld_lcd(LCD_GEN_CNTL, par); + + +@@ -676,7 +676,7 @@ + aty_st_le32(CRTC_GEN_CNTL, crtc->gen_cntl & ~(CRTC_EXT_DISP_EN | CRTC_EN), par); + + /* update non-shadow registers first */ +- aty_st_lcd(CNFG_PANEL, crtc->lcd_config_panel, par); ++ aty_st_lcd(CONFIG_PANEL, crtc->lcd_config_panel, par); + aty_st_lcd(LCD_GEN_CNTL, crtc->lcd_gen_cntl & + ~(CRTC_RW_SELECT | SHADOW_EN | SHADOW_RW_EN), par); + +@@ -858,7 +858,7 @@ + if (!M64_HAS(MOBIL_BUS)) + crtc->lcd_index |= CRTC2_DISPLAY_DIS; + +- crtc->lcd_config_panel = aty_ld_lcd(CNFG_PANEL, par) | 0x4000; ++ crtc->lcd_config_panel = aty_ld_lcd(CONFIG_PANEL, par) | 0x4000; + crtc->lcd_gen_cntl = aty_ld_lcd(LCD_GEN_CNTL, par) & ~CRTC_RW_SELECT; + + crtc->lcd_gen_cntl &= +@@ -1978,7 +1978,7 @@ + + return timeout ? 0 : -EIO; + } +-#endif /* CONFIG_PPC_PMAC */ ++#endif + + static int atyfb_pci_suspend(struct pci_dev *pdev, pm_message_t state) + { +@@ -2002,15 +2002,9 @@ + par->asleep = 1; + par->lock_blank = 1; + +- /* Because we may change PCI D state ourselves, we need to +- * first save the config space content so the core can +- * restore it properly on resume. +- */ +- pci_save_state(pdev); +- + #ifdef CONFIG_PPC_PMAC + /* Set chip to "suspend" mode */ +- if (machine_is(powermac) && aty_power_mgmt(1, par)) { ++ if (aty_power_mgmt(1, par)) { + par->asleep = 0; + par->lock_blank = 0; + atyfb_blank(FB_BLANK_UNBLANK, info); +@@ -2053,15 +2047,11 @@ + + acquire_console_sem(); + +- /* PCI state will have been restored by the core, so +- * we should be in D0 now with our config space fully +- * restored +- */ +- + #ifdef CONFIG_PPC_PMAC +- if (machine_is(powermac) && +- pdev->dev.power.power_state.event == PM_EVENT_SUSPEND) ++ if (pdev->dev.power.power_state.event == 2) + aty_power_mgmt(0, par); ++#else ++ pci_set_power_state(pdev, PCI_D0); + #endif + + aty_resume_chip(info); +@@ -2264,7 +2254,7 @@ + if (!M64_HAS(INTEGRATED)) { + u32 stat0; + u8 dac_type, dac_subtype, clk_type; +- stat0 = aty_ld_le32(CNFG_STAT0, par); ++ stat0 = aty_ld_le32(CONFIG_STAT0, par); + par->bus_type = (stat0 >> 0) & 0x07; + par->ram_type = (stat0 >> 3) & 0x07; + ramname = aty_gx_ram[par->ram_type]; +@@ -2334,7 +2324,7 @@ + par->dac_ops = &aty_dac_ct; + par->pll_ops = &aty_pll_ct; + par->bus_type = PCI; +- par->ram_type = (aty_ld_le32(CNFG_STAT0, par) & 0x07); ++ par->ram_type = (aty_ld_le32(CONFIG_STAT0, par) & 0x07); + ramname = aty_ct_ram[par->ram_type]; + /* for many chips, the mclk is 67 MHz for SDRAM, 63 MHz otherwise */ + if (par->pll_limits.mclk == 67 && par->ram_type < SDRAM) +@@ -2443,7 +2433,7 @@ + } + + if (M64_HAS(MAGIC_VRAM_SIZE)) { +- if (aty_ld_le32(CNFG_STAT1, par) & 0x40000000) ++ if (aty_ld_le32(CONFIG_STAT1, par) & 0x40000000) + info->fix.smem_len += 0x400000; + } + +@@ -2956,7 +2946,7 @@ + * Fix PROMs idea of MEM_CNTL settings... + */ + mem = aty_ld_le32(MEM_CNTL, par); +- chip_id = aty_ld_le32(CNFG_CHIP_ID, par); ++ chip_id = aty_ld_le32(CONFIG_CHIP_ID, par); + if (((chip_id & CFG_CHIP_TYPE) == VT_CHIP_ID) && !((chip_id >> 24) & 1)) { + switch (mem & 0x0f) { + case 3: +@@ -2974,7 +2964,7 @@ + default: + break; + } +- if ((aty_ld_le32(CNFG_STAT0, par) & 7) >= SDRAM) ++ if ((aty_ld_le32(CONFIG_STAT0, par) & 7) >= SDRAM) + mem &= ~(0x00700000); + } + mem &= ~(0xcf80e000); /* Turn off all undocumented bits. */ +@@ -3582,7 +3572,7 @@ + } + + /* Fake pci_id for correct_chipset() */ +- switch (aty_ld_le32(CNFG_CHIP_ID, par) & CFG_CHIP_TYPE) { ++ switch (aty_ld_le32(CONFIG_CHIP_ID, par) & CFG_CHIP_TYPE) { + case 0x00d7: + par->pci_id = PCI_CHIP_MACH64GX; + break; +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/drivers/video/aty/mach64_ct.c linux-2.6.29-rc3.owrt/drivers/video/aty/mach64_ct.c +--- linux-2.6.29.owrt/drivers/video/aty/mach64_ct.c 2009-05-10 22:04:38.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/drivers/video/aty/mach64_ct.c 2009-05-10 23:48:29.000000000 +0200 +@@ -8,9 +8,6 @@ + #include <asm/io.h> + #include <video/mach64.h> + #include "atyfb.h" +-#ifdef CONFIG_PPC +-#include <asm/machdep.h> +-#endif + + #undef DEBUG + +@@ -539,14 +536,6 @@ + pll->ct.xclk_post_div_real = postdividers[xpost_div]; + pll->ct.mclk_fb_div = q * pll->ct.xclk_post_div_real / 8; + +-#ifdef CONFIG_PPC +- if (machine_is(powermac)) { +- /* Override PLL_EXT_CNTL & 0x07. */ +- pll->ct.xclk_post_div = xpost_div; +- pll->ct.xclk_ref_div = 1; +- } +-#endif +- + #ifdef DEBUG + pllmclk = (1000000 * pll->ct.mclk_fb_mult * pll->ct.mclk_fb_div) / + (par->ref_clk_per * pll->ct.pll_ref_div); +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/drivers/video/aty/radeon_base.c linux-2.6.29-rc3.owrt/drivers/video/aty/radeon_base.c +--- linux-2.6.29.owrt/drivers/video/aty/radeon_base.c 2009-05-10 22:04:38.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/drivers/video/aty/radeon_base.c 2009-05-10 23:48:29.000000000 +0200 +@@ -1936,8 +1936,8 @@ + OUTREG(CRTC_GEN_CNTL, save_crtc_gen_cntl | CRTC_DISP_REQ_EN_B); + mdelay(100); + +- aper_base = INREG(CNFG_APER_0_BASE); +- aper_size = INREG(CNFG_APER_SIZE); ++ aper_base = INREG(CONFIG_APER_0_BASE); ++ aper_size = INREG(CONFIG_APER_SIZE); + + #ifdef SET_MC_FB_FROM_APERTURE + /* Set framebuffer to be at the same address as set in PCI BAR */ +@@ -2024,11 +2024,11 @@ + ~CRTC_H_CUTOFF_ACTIVE_EN); + } + } else { +- tmp = INREG(CNFG_MEMSIZE); ++ tmp = INREG(CONFIG_MEMSIZE); + } + + /* mem size is bits [28:0], mask off the rest */ +- rinfo->video_ram = tmp & CNFG_MEMSIZE_MASK; ++ rinfo->video_ram = tmp & CONFIG_MEMSIZE_MASK; + + /* + * Hack to get around some busted production M6's +@@ -2228,7 +2228,7 @@ + */ + rinfo->errata = 0; + if (rinfo->family == CHIP_FAMILY_R300 && +- (INREG(CNFG_CNTL) & CFG_ATI_REV_ID_MASK) ++ (INREG(CONFIG_CNTL) & CFG_ATI_REV_ID_MASK) + == CFG_ATI_REV_A11) + rinfo->errata |= CHIP_ERRATA_R300_CG; + +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/drivers/video/aty/radeonfb.h linux-2.6.29-rc3.owrt/drivers/video/aty/radeonfb.h +--- linux-2.6.29.owrt/drivers/video/aty/radeonfb.h 2009-05-10 22:04:38.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/drivers/video/aty/radeonfb.h 2009-05-10 23:48:29.000000000 +0200 +@@ -361,6 +361,8 @@ + #ifdef CONFIG_FB_RADEON_I2C + struct radeon_i2c_chan i2c[4]; + #endif ++ ++ u32 cfg_save[64]; + }; + + +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/drivers/video/aty/radeon_pm.c linux-2.6.29-rc3.owrt/drivers/video/aty/radeon_pm.c +--- linux-2.6.29.owrt/drivers/video/aty/radeon_pm.c 2009-05-10 22:04:38.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/drivers/video/aty/radeon_pm.c 2009-05-10 23:48:29.000000000 +0200 +@@ -333,7 +333,7 @@ + if (!rinfo->has_CRTC2) { + tmp = INPLL(pllSCLK_CNTL); + +- if ((INREG(CNFG_CNTL) & CFG_ATI_REV_ID_MASK) > CFG_ATI_REV_A13) ++ if ((INREG(CONFIG_CNTL) & CFG_ATI_REV_ID_MASK) > CFG_ATI_REV_A13) + tmp &= ~(SCLK_CNTL__FORCE_CP | SCLK_CNTL__FORCE_RB); + tmp &= ~(SCLK_CNTL__FORCE_HDP | SCLK_CNTL__FORCE_DISP1 | + SCLK_CNTL__FORCE_TOP | SCLK_CNTL__FORCE_SE | +@@ -468,9 +468,9 @@ + + /*RAGE_6::A11 A12 A12N1 A13, RV250::A11 A12, R300*/ + if ((rinfo->family == CHIP_FAMILY_RV250 && +- ((INREG(CNFG_CNTL) & CFG_ATI_REV_ID_MASK) < CFG_ATI_REV_A13)) || ++ ((INREG(CONFIG_CNTL) & CFG_ATI_REV_ID_MASK) < CFG_ATI_REV_A13)) || + ((rinfo->family == CHIP_FAMILY_RV100) && +- ((INREG(CNFG_CNTL) & CFG_ATI_REV_ID_MASK) <= CFG_ATI_REV_A13))) { ++ ((INREG(CONFIG_CNTL) & CFG_ATI_REV_ID_MASK) <= CFG_ATI_REV_A13))) { + tmp |= SCLK_CNTL__FORCE_CP; + tmp |= SCLK_CNTL__FORCE_VIP; + } +@@ -486,7 +486,7 @@ + /* RV200::A11 A12 RV250::A11 A12 */ + if (((rinfo->family == CHIP_FAMILY_RV200) || + (rinfo->family == CHIP_FAMILY_RV250)) && +- ((INREG(CNFG_CNTL) & CFG_ATI_REV_ID_MASK) < CFG_ATI_REV_A13)) ++ ((INREG(CONFIG_CNTL) & CFG_ATI_REV_ID_MASK) < CFG_ATI_REV_A13)) + tmp |= SCLK_MORE_CNTL__FORCEON; + + OUTPLL(pllSCLK_MORE_CNTL, tmp); +@@ -497,7 +497,7 @@ + /* RV200::A11 A12, RV250::A11 A12 */ + if (((rinfo->family == CHIP_FAMILY_RV200) || + (rinfo->family == CHIP_FAMILY_RV250)) && +- ((INREG(CNFG_CNTL) & CFG_ATI_REV_ID_MASK) < CFG_ATI_REV_A13)) { ++ ((INREG(CONFIG_CNTL) & CFG_ATI_REV_ID_MASK) < CFG_ATI_REV_A13)) { + tmp = INPLL(pllPLL_PWRMGT_CNTL); + tmp |= PLL_PWRMGT_CNTL__TCL_BYPASS_DISABLE; + OUTPLL(pllPLL_PWRMGT_CNTL, tmp); +@@ -702,7 +702,7 @@ + OUTREG(DISPLAY_BASE_ADDR, rinfo->save_regs[31]); + OUTREG(MC_AGP_LOCATION, rinfo->save_regs[32]); + OUTREG(CRTC2_DISPLAY_BASE_ADDR, rinfo->save_regs[33]); +- OUTREG(CNFG_MEMSIZE, rinfo->video_ram); ++ OUTREG(CONFIG_MEMSIZE, rinfo->video_ram); + + OUTREG(DISP_MISC_CNTL, rinfo->save_regs[9]); + OUTREG(DISP_PWR_MAN, rinfo->save_regs[10]); +@@ -1723,7 +1723,7 @@ + OUTREG(CRTC2_DISPLAY_BASE_ADDR, rinfo->save_regs[33]); + OUTREG(MC_FB_LOCATION, rinfo->save_regs[30]); + OUTREG(OV0_BASE_ADDR, rinfo->save_regs[80]); +- OUTREG(CNFG_MEMSIZE, rinfo->video_ram); ++ OUTREG(CONFIG_MEMSIZE, rinfo->video_ram); + OUTREG(BUS_CNTL, rinfo->save_regs[36]); + OUTREG(BUS_CNTL1, rinfo->save_regs[14]); + OUTREG(MPP_TB_CONFIG, rinfo->save_regs[37]); +@@ -1961,7 +1961,7 @@ + OUTMC(rinfo, ixMC_CHP_IO_CNTL_B1, rinfo->save_regs[68] /*0x141555ff*/); + OUTMC(rinfo, ixMC_IMP_CNTL_0, rinfo->save_regs[71] /*0x00009249*/); + OUTREG(MC_IND_INDEX, 0); +- OUTREG(CNFG_MEMSIZE, rinfo->video_ram); ++ OUTREG(CONFIG_MEMSIZE, rinfo->video_ram); + + mdelay(20); + } +@@ -2361,7 +2361,7 @@ + OUTMC(rinfo, ixMC_IMP_CNTL_0, 0x00009249); + OUTREG(MC_IND_INDEX, 0); + +- OUTREG(CNFG_MEMSIZE, rinfo->video_ram); ++ OUTREG(CONFIG_MEMSIZE, rinfo->video_ram); + + radeon_pm_full_reset_sdram(rinfo); + +@@ -2507,28 +2507,11 @@ + + #endif /* CONFIG_PPC_OF */ + +-static void radeonfb_whack_power_state(struct radeonfb_info *rinfo, pci_power_t state) +-{ +- u16 pwr_cmd; +- +- for (;;) { +- pci_read_config_word(rinfo->pdev, +- rinfo->pm_reg+PCI_PM_CTRL, +- &pwr_cmd); +- if (pwr_cmd & 2) +- break; +- pwr_cmd = (pwr_cmd & ~PCI_PM_CTRL_STATE_MASK) | 2; +- pci_write_config_word(rinfo->pdev, +- rinfo->pm_reg+PCI_PM_CTRL, +- pwr_cmd); +- msleep(500); +- } +- rinfo->pdev->current_state = state; +-} +- + static void radeon_set_suspend(struct radeonfb_info *rinfo, int suspend) + { ++ u16 pwr_cmd; + u32 tmp; ++ int i; + + if (!rinfo->pm_reg) + return; +@@ -2574,19 +2557,32 @@ + } + } + ++ for (i = 0; i < 64; ++i) ++ pci_read_config_dword(rinfo->pdev, i * 4, ++ &rinfo->cfg_save[i]); ++ + /* Switch PCI power management to D2. */ + pci_disable_device(rinfo->pdev); +- pci_save_state(rinfo->pdev); +- /* The chip seems to need us to whack the PM register +- * repeatedly until it sticks. We do that -prior- to +- * calling pci_set_power_state() +- */ +- radeonfb_whack_power_state(rinfo, PCI_D2); +- pci_set_power_state(rinfo->pdev, PCI_D2); ++ for (;;) { ++ pci_read_config_word( ++ rinfo->pdev, rinfo->pm_reg+PCI_PM_CTRL, ++ &pwr_cmd); ++ if (pwr_cmd & 2) ++ break; ++ pci_write_config_word( ++ rinfo->pdev, rinfo->pm_reg+PCI_PM_CTRL, ++ (pwr_cmd & ~PCI_PM_CTRL_STATE_MASK) | 2); ++ mdelay(500); ++ } + } else { + printk(KERN_DEBUG "radeonfb (%s): switching to D0 state...\n", + pci_name(rinfo->pdev)); + ++ /* Switch back PCI powermanagment to D0 */ ++ mdelay(200); ++ pci_write_config_word(rinfo->pdev, rinfo->pm_reg+PCI_PM_CTRL, 0); ++ mdelay(500); ++ + if (rinfo->family <= CHIP_FAMILY_RV250) { + /* Reset the SDRAM controller */ + radeon_pm_full_reset_sdram(rinfo); +@@ -2602,10 +2598,37 @@ + } + } + ++static int radeon_restore_pci_cfg(struct radeonfb_info *rinfo) ++{ ++ int i; ++ static u32 radeon_cfg_after_resume[64]; ++ ++ for (i = 0; i < 64; ++i) ++ pci_read_config_dword(rinfo->pdev, i * 4, ++ &radeon_cfg_after_resume[i]); ++ ++ if (radeon_cfg_after_resume[PCI_BASE_ADDRESS_0/4] ++ == rinfo->cfg_save[PCI_BASE_ADDRESS_0/4]) ++ return 0; /* assume everything is ok */ ++ ++ for (i = PCI_BASE_ADDRESS_0/4; i < 64; ++i) { ++ if (radeon_cfg_after_resume[i] != rinfo->cfg_save[i]) ++ pci_write_config_dword(rinfo->pdev, i * 4, ++ rinfo->cfg_save[i]); ++ } ++ pci_write_config_word(rinfo->pdev, PCI_CACHE_LINE_SIZE, ++ rinfo->cfg_save[PCI_CACHE_LINE_SIZE/4]); ++ pci_write_config_word(rinfo->pdev, PCI_COMMAND, ++ rinfo->cfg_save[PCI_COMMAND/4]); ++ return 1; ++} ++ ++ + int radeonfb_pci_suspend(struct pci_dev *pdev, pm_message_t mesg) + { + struct fb_info *info = pci_get_drvdata(pdev); + struct radeonfb_info *rinfo = info->par; ++ int i; + + if (mesg.event == pdev->dev.power.power_state.event) + return 0; +@@ -2651,11 +2674,6 @@ + pmac_suspend_agp_for_card(pdev); + #endif /* CONFIG_PPC_PMAC */ + +- /* It's unclear whether or when the generic code will do that, so let's +- * do it ourselves. We save state before we do any power management +- */ +- pci_save_state(pdev); +- + /* If we support wakeup from poweroff, we save all regs we can including cfg + * space + */ +@@ -2680,6 +2698,9 @@ + mdelay(20); + OUTREG(LVDS_GEN_CNTL, INREG(LVDS_GEN_CNTL) & ~(LVDS_DIGON)); + } ++ // FIXME: Use PCI layer ++ for (i = 0; i < 64; ++i) ++ pci_read_config_dword(pdev, i * 4, &rinfo->cfg_save[i]); + pci_disable_device(pdev); + } + /* If we support D2, we go to it (should be fixed later with a flag forcing +@@ -2696,13 +2717,6 @@ + return 0; + } + +-static int radeon_check_power_loss(struct radeonfb_info *rinfo) +-{ +- return rinfo->save_regs[4] != INPLL(CLK_PIN_CNTL) || +- rinfo->save_regs[2] != INPLL(MCLK_CNTL) || +- rinfo->save_regs[3] != INPLL(SCLK_CNTL); +-} +- + int radeonfb_pci_resume(struct pci_dev *pdev) + { + struct fb_info *info = pci_get_drvdata(pdev); +@@ -2721,13 +2735,20 @@ + printk(KERN_DEBUG "radeonfb (%s): resuming from state: %d...\n", + pci_name(pdev), pdev->dev.power.power_state.event); + +- /* PCI state will have been restored by the core, so +- * we should be in D0 now with our config space fully +- * restored +- */ ++ ++ if (pci_enable_device(pdev)) { ++ rc = -ENODEV; ++ printk(KERN_ERR "radeonfb (%s): can't enable PCI device !\n", ++ pci_name(pdev)); ++ goto bail; ++ } ++ pci_set_master(pdev); ++ + if (pdev->dev.power.power_state.event == PM_EVENT_SUSPEND) { +- /* Wakeup chip */ +- if ((rinfo->pm_mode & radeon_pm_off) && radeon_check_power_loss(rinfo)) { ++ /* Wakeup chip. Check from config space if we were powered off ++ * (todo: additionally, check CLK_PIN_CNTL too) ++ */ ++ if ((rinfo->pm_mode & radeon_pm_off) && radeon_restore_pci_cfg(rinfo)) { + if (rinfo->reinit_func != NULL) + rinfo->reinit_func(rinfo); + else { +@@ -2786,13 +2807,12 @@ + return rc; + } + +-#ifdef CONFIG_PPC_OF__disabled ++#ifdef CONFIG_PPC_OF + static void radeonfb_early_resume(void *data) + { + struct radeonfb_info *rinfo = data; + + rinfo->no_schedule = 1; +- pci_restore_state(rinfo->pdev); + radeonfb_pci_resume(rinfo->pdev); + rinfo->no_schedule = 0; + } +@@ -2859,14 +2879,7 @@ + */ + if (rinfo->pm_mode != radeon_pm_none) { + pmac_call_feature(PMAC_FTR_DEVICE_CAN_WAKE, rinfo->of_node, 0, 1); +-#if 0 /* Disable the early video resume hack for now as it's causing problems, among +- * others we now rely on the PCI core restoring the config space for us, which +- * isn't the case with that hack, and that code path causes various things to +- * be called with interrupts off while they shouldn't. I'm leaving the code in +- * as it can be useful for debugging purposes +- */ + pmac_set_early_video_resume(radeonfb_early_resume, rinfo); +-#endif + } + + #if 0 +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/drivers/video/backlight/da903x_bl.c linux-2.6.29-rc3.owrt/drivers/video/backlight/da903x_bl.c +--- linux-2.6.29.owrt/drivers/video/backlight/da903x_bl.c 2009-05-10 22:04:38.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/drivers/video/backlight/da903x_bl.c 1970-01-01 01:00:00.000000000 +0100 +@@ -1,203 +0,0 @@ +-/* +- * Backlight driver for Dialog Semiconductor DA9030/DA9034 +- * +- * Copyright (C) 2008 Compulab, Ltd. +- * Mike Rapoport <mike@compulab.co.il> +- * +- * Copyright (C) 2006-2008 Marvell International Ltd. +- * Eric Miao <eric.miao@marvell.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/init.h> +-#include <linux/platform_device.h> +-#include <linux/fb.h> +-#include <linux/backlight.h> +-#include <linux/mfd/da903x.h> +- +-#define DA9030_WLED_CONTROL 0x25 +-#define DA9030_WLED_CP_EN (1 << 6) +-#define DA9030_WLED_TRIM(x) ((x) & 0x7) +- +-#define DA9034_WLED_CONTROL1 0x3C +-#define DA9034_WLED_CONTROL2 0x3D +- +-#define DA9034_WLED_BOOST_EN (1 << 5) +- +-#define DA9030_MAX_BRIGHTNESS 7 +-#define DA9034_MAX_BRIGHTNESS 0x7f +- +-struct da903x_backlight_data { +- struct device *da903x_dev; +- int id; +- int current_brightness; +-}; +- +-static int da903x_backlight_set(struct backlight_device *bl, int brightness) +-{ +- struct da903x_backlight_data *data = bl_get_data(bl); +- struct device *dev = data->da903x_dev; +- uint8_t val; +- int ret = 0; +- +- switch (data->id) { +- case DA9034_ID_WLED: +- ret = da903x_update(dev, DA9034_WLED_CONTROL1, +- brightness, 0x7f); +- if (ret) +- return ret; +- +- if (data->current_brightness && brightness == 0) +- ret = da903x_clr_bits(dev, +- DA9034_WLED_CONTROL2, +- DA9034_WLED_BOOST_EN); +- +- if (data->current_brightness == 0 && brightness) +- ret = da903x_set_bits(dev, +- DA9034_WLED_CONTROL2, +- DA9034_WLED_BOOST_EN); +- break; +- case DA9030_ID_WLED: +- val = DA9030_WLED_TRIM(brightness); +- val |= brightness ? DA9030_WLED_CP_EN : 0; +- ret = da903x_write(dev, DA9030_WLED_CONTROL, val); +- break; +- } +- +- if (ret) +- return ret; +- +- data->current_brightness = brightness; +- return 0; +-} +- +-static int da903x_backlight_update_status(struct backlight_device *bl) +-{ +- int brightness = bl->props.brightness; +- +- if (bl->props.power != FB_BLANK_UNBLANK) +- brightness = 0; +- +- if (bl->props.fb_blank != FB_BLANK_UNBLANK) +- brightness = 0; +- +- return da903x_backlight_set(bl, brightness); +-} +- +-static int da903x_backlight_get_brightness(struct backlight_device *bl) +-{ +- struct da903x_backlight_data *data = bl_get_data(bl); +- return data->current_brightness; +-} +- +-static struct backlight_ops da903x_backlight_ops = { +- .update_status = da903x_backlight_update_status, +- .get_brightness = da903x_backlight_get_brightness, +-}; +- +-static int da903x_backlight_probe(struct platform_device *pdev) +-{ +- struct da903x_backlight_data *data; +- struct backlight_device *bl; +- int max_brightness; +- +- data = kzalloc(sizeof(*data), GFP_KERNEL); +- if (data == NULL) +- return -ENOMEM; +- +- switch (pdev->id) { +- case DA9030_ID_WLED: +- max_brightness = DA9030_MAX_BRIGHTNESS; +- break; +- case DA9034_ID_WLED: +- max_brightness = DA9034_MAX_BRIGHTNESS; +- break; +- default: +- dev_err(&pdev->dev, "invalid backlight device ID(%d)\n", +- pdev->id); +- kfree(data); +- return -EINVAL; +- } +- +- data->id = pdev->id; +- data->da903x_dev = pdev->dev.parent; +- data->current_brightness = 0; +- +- bl = backlight_device_register(pdev->name, data->da903x_dev, +- data, &da903x_backlight_ops); +- if (IS_ERR(bl)) { +- dev_err(&pdev->dev, "failed to register backlight\n"); +- kfree(data); +- return PTR_ERR(bl); +- } +- +- bl->props.max_brightness = max_brightness; +- bl->props.brightness = max_brightness; +- +- platform_set_drvdata(pdev, bl); +- backlight_update_status(bl); +- return 0; +-} +- +-static int da903x_backlight_remove(struct platform_device *pdev) +-{ +- struct backlight_device *bl = platform_get_drvdata(pdev); +- struct da903x_backlight_data *data = bl_get_data(bl); +- +- backlight_device_unregister(bl); +- kfree(data); +- return 0; +-} +- +-#ifdef CONFIG_PM +-static int da903x_backlight_suspend(struct platform_device *pdev, +- pm_message_t state) +-{ +- struct backlight_device *bl = platform_get_drvdata(pdev); +- return da903x_backlight_set(bl, 0); +-} +- +-static int da903x_backlight_resume(struct platform_device *pdev) +-{ +- struct backlight_device *bl = platform_get_drvdata(pdev); +- +- backlight_update_status(bl); +- return 0; +-} +-#else +-#define da903x_backlight_suspend NULL +-#define da903x_backlight_resume NULL +-#endif +- +-static struct platform_driver da903x_backlight_driver = { +- .driver = { +- .name = "da903x-backlight", +- .owner = THIS_MODULE, +- }, +- .probe = da903x_backlight_probe, +- .remove = da903x_backlight_remove, +- .suspend = da903x_backlight_suspend, +- .resume = da903x_backlight_resume, +-}; +- +-static int __init da903x_backlight_init(void) +-{ +- return platform_driver_register(&da903x_backlight_driver); +-} +-module_init(da903x_backlight_init); +- +-static void __exit da903x_backlight_exit(void) +-{ +- platform_driver_unregister(&da903x_backlight_driver); +-} +-module_exit(da903x_backlight_exit); +- +-MODULE_DESCRIPTION("Backlight Driver for Dialog Semiconductor DA9030/DA9034"); +-MODULE_AUTHOR("Eric Miao <eric.miao@marvell.com>" +- "Mike Rapoport <mike@compulab.co.il>"); +-MODULE_LICENSE("GPL"); +-MODULE_ALIAS("platform:da903x-backlight"); +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/drivers/video/backlight/da903x.c linux-2.6.29-rc3.owrt/drivers/video/backlight/da903x.c +--- linux-2.6.29.owrt/drivers/video/backlight/da903x.c 1970-01-01 01:00:00.000000000 +0100 ++++ linux-2.6.29-rc3.owrt/drivers/video/backlight/da903x.c 2009-05-10 23:48:29.000000000 +0200 +@@ -0,0 +1,203 @@ ++/* ++ * Backlight driver for Dialog Semiconductor DA9030/DA9034 ++ * ++ * Copyright (C) 2008 Compulab, Ltd. ++ * Mike Rapoport <mike@compulab.co.il> ++ * ++ * Copyright (C) 2006-2008 Marvell International Ltd. ++ * Eric Miao <eric.miao@marvell.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/init.h> ++#include <linux/platform_device.h> ++#include <linux/fb.h> ++#include <linux/backlight.h> ++#include <linux/mfd/da903x.h> ++ ++#define DA9030_WLED_CONTROL 0x25 ++#define DA9030_WLED_CP_EN (1 << 6) ++#define DA9030_WLED_TRIM(x) ((x) & 0x7) ++ ++#define DA9034_WLED_CONTROL1 0x3C ++#define DA9034_WLED_CONTROL2 0x3D ++ ++#define DA9034_WLED_BOOST_EN (1 << 5) ++ ++#define DA9030_MAX_BRIGHTNESS 7 ++#define DA9034_MAX_BRIGHTNESS 0x7f ++ ++struct da903x_backlight_data { ++ struct device *da903x_dev; ++ int id; ++ int current_brightness; ++}; ++ ++static int da903x_backlight_set(struct backlight_device *bl, int brightness) ++{ ++ struct da903x_backlight_data *data = bl_get_data(bl); ++ struct device *dev = data->da903x_dev; ++ uint8_t val; ++ int ret = 0; ++ ++ switch (data->id) { ++ case DA9034_ID_WLED: ++ ret = da903x_update(dev, DA9034_WLED_CONTROL1, ++ brightness, 0x7f); ++ if (ret) ++ return ret; ++ ++ if (data->current_brightness && brightness == 0) ++ ret = da903x_clr_bits(dev, ++ DA9034_WLED_CONTROL2, ++ DA9034_WLED_BOOST_EN); ++ ++ if (data->current_brightness == 0 && brightness) ++ ret = da903x_set_bits(dev, ++ DA9034_WLED_CONTROL2, ++ DA9034_WLED_BOOST_EN); ++ break; ++ case DA9030_ID_WLED: ++ val = DA9030_WLED_TRIM(brightness); ++ val |= brightness ? DA9030_WLED_CP_EN : 0; ++ ret = da903x_write(dev, DA9030_WLED_CONTROL, val); ++ break; ++ } ++ ++ if (ret) ++ return ret; ++ ++ data->current_brightness = brightness; ++ return 0; ++} ++ ++static int da903x_backlight_update_status(struct backlight_device *bl) ++{ ++ int brightness = bl->props.brightness; ++ ++ if (bl->props.power != FB_BLANK_UNBLANK) ++ brightness = 0; ++ ++ if (bl->props.fb_blank != FB_BLANK_UNBLANK) ++ brightness = 0; ++ ++ return da903x_backlight_set(bl, brightness); ++} ++ ++static int da903x_backlight_get_brightness(struct backlight_device *bl) ++{ ++ struct da903x_backlight_data *data = bl_get_data(bl); ++ return data->current_brightness; ++} ++ ++static struct backlight_ops da903x_backlight_ops = { ++ .update_status = da903x_backlight_update_status, ++ .get_brightness = da903x_backlight_get_brightness, ++}; ++ ++static int da903x_backlight_probe(struct platform_device *pdev) ++{ ++ struct da903x_backlight_data *data; ++ struct backlight_device *bl; ++ int max_brightness; ++ ++ data = kzalloc(sizeof(*data), GFP_KERNEL); ++ if (data == NULL) ++ return -ENOMEM; ++ ++ switch (pdev->id) { ++ case DA9030_ID_WLED: ++ max_brightness = DA9030_MAX_BRIGHTNESS; ++ break; ++ case DA9034_ID_WLED: ++ max_brightness = DA9034_MAX_BRIGHTNESS; ++ break; ++ default: ++ dev_err(&pdev->dev, "invalid backlight device ID(%d)\n", ++ pdev->id); ++ kfree(data); ++ return -EINVAL; ++ } ++ ++ data->id = pdev->id; ++ data->da903x_dev = pdev->dev.parent; ++ data->current_brightness = 0; ++ ++ bl = backlight_device_register(pdev->name, data->da903x_dev, ++ data, &da903x_backlight_ops); ++ if (IS_ERR(bl)) { ++ dev_err(&pdev->dev, "failed to register backlight\n"); ++ kfree(data); ++ return PTR_ERR(bl); ++ } ++ ++ bl->props.max_brightness = max_brightness; ++ bl->props.brightness = max_brightness; ++ ++ platform_set_drvdata(pdev, bl); ++ backlight_update_status(bl); ++ return 0; ++} ++ ++static int da903x_backlight_remove(struct platform_device *pdev) ++{ ++ struct backlight_device *bl = platform_get_drvdata(pdev); ++ struct da903x_backlight_data *data = bl_get_data(bl); ++ ++ backlight_device_unregister(bl); ++ kfree(data); ++ return 0; ++} ++ ++#ifdef CONFIG_PM ++static int da903x_backlight_suspend(struct platform_device *pdev, ++ pm_message_t state) ++{ ++ struct backlight_device *bl = platform_get_drvdata(pdev); ++ return da903x_backlight_set(bl, 0); ++} ++ ++static int da903x_backlight_resume(struct platform_device *pdev) ++{ ++ struct backlight_device *bl = platform_get_drvdata(pdev); ++ ++ backlight_update_status(bl); ++ return 0; ++} ++#else ++#define da903x_backlight_suspend NULL ++#define da903x_backlight_resume NULL ++#endif ++ ++static struct platform_driver da903x_backlight_driver = { ++ .driver = { ++ .name = "da903x-backlight", ++ .owner = THIS_MODULE, ++ }, ++ .probe = da903x_backlight_probe, ++ .remove = da903x_backlight_remove, ++ .suspend = da903x_backlight_suspend, ++ .resume = da903x_backlight_resume, ++}; ++ ++static int __init da903x_backlight_init(void) ++{ ++ return platform_driver_register(&da903x_backlight_driver); ++} ++module_init(da903x_backlight_init); ++ ++static void __exit da903x_backlight_exit(void) ++{ ++ platform_driver_unregister(&da903x_backlight_driver); ++} ++module_exit(da903x_backlight_exit); ++ ++MODULE_DESCRIPTION("Backlight Driver for Dialog Semiconductor DA9030/DA9034"); ++MODULE_AUTHOR("Eric Miao <eric.miao@marvell.com>" ++ "Mike Rapoport <mike@compulab.co.il>"); ++MODULE_LICENSE("GPL"); ++MODULE_ALIAS("platform:da903x-backlight"); +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/drivers/video/backlight/Makefile linux-2.6.29-rc3.owrt/drivers/video/backlight/Makefile +--- linux-2.6.29.owrt/drivers/video/backlight/Makefile 2009-05-10 22:04:38.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/drivers/video/backlight/Makefile 2009-05-10 23:48:29.000000000 +0200 +@@ -18,7 +18,7 @@ + obj-$(CONFIG_BACKLIGHT_PROGEAR) += progear_bl.o + obj-$(CONFIG_BACKLIGHT_CARILLO_RANCH) += cr_bllcd.o + obj-$(CONFIG_BACKLIGHT_PWM) += pwm_bl.o +-obj-$(CONFIG_BACKLIGHT_DA903X) += da903x_bl.o ++obj-$(CONFIG_BACKLIGHT_DA903X) += da903x.o + obj-$(CONFIG_BACKLIGHT_MBP_NVIDIA) += mbp_nvidia_bl.o + obj-$(CONFIG_BACKLIGHT_TOSA) += tosa_bl.o + obj-$(CONFIG_BACKLIGHT_SAHARA) += kb3886_bl.o +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/drivers/video/bfin-t350mcqb-fb.c linux-2.6.29-rc3.owrt/drivers/video/bfin-t350mcqb-fb.c +--- linux-2.6.29.owrt/drivers/video/bfin-t350mcqb-fb.c 2009-05-10 22:04:38.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/drivers/video/bfin-t350mcqb-fb.c 2009-05-10 23:48:29.000000000 +0200 +@@ -447,7 +447,7 @@ + return IRQ_HANDLED; + } + +-static int __devinit bfin_t350mcqb_probe(struct platform_device *pdev) ++static int __init bfin_t350mcqb_probe(struct platform_device *pdev) + { + struct bfin_t350mcqbfb_info *info; + struct fb_info *fbinfo; +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/drivers/video/fbcmap.c linux-2.6.29-rc3.owrt/drivers/video/fbcmap.c +--- linux-2.6.29.owrt/drivers/video/fbcmap.c 2009-05-10 22:04:38.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/drivers/video/fbcmap.c 2009-05-10 23:48:29.000000000 +0200 +@@ -250,6 +250,10 @@ + int rc, size = cmap->len * sizeof(u16); + struct fb_cmap umap; + ++ if (cmap->start < 0 || (!info->fbops->fb_setcolreg && ++ !info->fbops->fb_setcmap)) ++ return -EINVAL; ++ + memset(&umap, 0, sizeof(struct fb_cmap)); + rc = fb_alloc_cmap(&umap, cmap->len, cmap->transp != NULL); + if (rc) +@@ -258,23 +262,11 @@ + copy_from_user(umap.green, cmap->green, size) || + copy_from_user(umap.blue, cmap->blue, size) || + (cmap->transp && copy_from_user(umap.transp, cmap->transp, size))) { +- rc = -EFAULT; +- goto out; ++ fb_dealloc_cmap(&umap); ++ return -EFAULT; + } + umap.start = cmap->start; +- if (!lock_fb_info(info)) { +- rc = -ENODEV; +- goto out; +- } +- if (cmap->start < 0 || (!info->fbops->fb_setcolreg && +- !info->fbops->fb_setcmap)) { +- rc = -EINVAL; +- goto out1; +- } + rc = fb_set_cmap(&umap, info); +-out1: +- unlock_fb_info(info); +-out: + fb_dealloc_cmap(&umap); + return rc; + } +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/drivers/video/fbmem.c linux-2.6.29-rc3.owrt/drivers/video/fbmem.c +--- linux-2.6.29.owrt/drivers/video/fbmem.c 2009-05-10 22:04:38.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/drivers/video/fbmem.c 2009-05-10 23:48:29.000000000 +0200 +@@ -1013,139 +1013,132 @@ + struct fb_var_screeninfo var; + struct fb_fix_screeninfo fix; + struct fb_con2fbmap con2fb; +- struct fb_cmap cmap_from; + struct fb_cmap_user cmap; + struct fb_event event; + void __user *argp = (void __user *)arg; + long ret = 0; + ++ fb = info->fbops; ++ if (!fb) ++ return -ENODEV; ++ + switch (cmd) { + case FBIOGET_VSCREENINFO: +- if (!lock_fb_info(info)) +- return -ENODEV; +- var = info->var; +- unlock_fb_info(info); +- +- ret = copy_to_user(argp, &var, sizeof(var)) ? -EFAULT : 0; ++ ret = copy_to_user(argp, &info->var, ++ sizeof(var)) ? -EFAULT : 0; + break; + case FBIOPUT_VSCREENINFO: +- if (copy_from_user(&var, argp, sizeof(var))) +- return -EFAULT; +- if (!lock_fb_info(info)) +- return -ENODEV; ++ if (copy_from_user(&var, argp, sizeof(var))) { ++ ret = -EFAULT; ++ break; ++ } + acquire_console_sem(); + info->flags |= FBINFO_MISC_USEREVENT; + ret = fb_set_var(info, &var); + info->flags &= ~FBINFO_MISC_USEREVENT; + release_console_sem(); +- unlock_fb_info(info); +- if (!ret && copy_to_user(argp, &var, sizeof(var))) ++ if (ret == 0 && copy_to_user(argp, &var, sizeof(var))) + ret = -EFAULT; + break; + case FBIOGET_FSCREENINFO: +- if (!lock_fb_info(info)) +- return -ENODEV; +- fix = info->fix; +- unlock_fb_info(info); +- +- ret = copy_to_user(argp, &fix, sizeof(fix)) ? -EFAULT : 0; ++ ret = copy_to_user(argp, &info->fix, ++ sizeof(fix)) ? -EFAULT : 0; + break; + case FBIOPUTCMAP: + if (copy_from_user(&cmap, argp, sizeof(cmap))) +- return -EFAULT; +- ret = fb_set_user_cmap(&cmap, info); ++ ret = -EFAULT; ++ else ++ ret = fb_set_user_cmap(&cmap, info); + break; + case FBIOGETCMAP: + if (copy_from_user(&cmap, argp, sizeof(cmap))) +- return -EFAULT; +- if (!lock_fb_info(info)) +- return -ENODEV; +- cmap_from = info->cmap; +- unlock_fb_info(info); +- ret = fb_cmap_to_user(&cmap_from, &cmap); ++ ret = -EFAULT; ++ else ++ ret = fb_cmap_to_user(&info->cmap, &cmap); + break; + case FBIOPAN_DISPLAY: +- if (copy_from_user(&var, argp, sizeof(var))) +- return -EFAULT; +- if (!lock_fb_info(info)) +- return -ENODEV; ++ if (copy_from_user(&var, argp, sizeof(var))) { ++ ret = -EFAULT; ++ break; ++ } + acquire_console_sem(); + ret = fb_pan_display(info, &var); + release_console_sem(); +- unlock_fb_info(info); + if (ret == 0 && copy_to_user(argp, &var, sizeof(var))) +- return -EFAULT; ++ ret = -EFAULT; + break; + case FBIO_CURSOR: + ret = -EINVAL; + break; + case FBIOGET_CON2FBMAP: + if (copy_from_user(&con2fb, argp, sizeof(con2fb))) +- return -EFAULT; +- if (con2fb.console < 1 || con2fb.console > MAX_NR_CONSOLES) +- return -EINVAL; +- con2fb.framebuffer = -1; +- event.data = &con2fb; +- +- if (!lock_fb_info(info)) +- return -ENODEV; +- event.info = info; +- fb_notifier_call_chain(FB_EVENT_GET_CONSOLE_MAP, &event); +- unlock_fb_info(info); +- +- ret = copy_to_user(argp, &con2fb, sizeof(con2fb)) ? -EFAULT : 0; ++ ret = -EFAULT; ++ else if (con2fb.console < 1 || con2fb.console > MAX_NR_CONSOLES) ++ ret = -EINVAL; ++ else { ++ con2fb.framebuffer = -1; ++ event.info = info; ++ event.data = &con2fb; ++ fb_notifier_call_chain(FB_EVENT_GET_CONSOLE_MAP, ++ &event); ++ ret = copy_to_user(argp, &con2fb, ++ sizeof(con2fb)) ? -EFAULT : 0; ++ } + break; + case FBIOPUT_CON2FBMAP: +- if (copy_from_user(&con2fb, argp, sizeof(con2fb))) +- return -EFAULT; +- if (con2fb.console < 1 || con2fb.console > MAX_NR_CONSOLES) +- return -EINVAL; +- if (con2fb.framebuffer < 0 || con2fb.framebuffer >= FB_MAX) +- return -EINVAL; ++ if (copy_from_user(&con2fb, argp, sizeof(con2fb))) { ++ ret = -EFAULT; ++ break; ++ } ++ if (con2fb.console < 1 || con2fb.console > MAX_NR_CONSOLES) { ++ ret = -EINVAL; ++ break; ++ } ++ if (con2fb.framebuffer < 0 || con2fb.framebuffer >= FB_MAX) { ++ ret = -EINVAL; ++ break; ++ } + if (!registered_fb[con2fb.framebuffer]) + request_module("fb%d", con2fb.framebuffer); + if (!registered_fb[con2fb.framebuffer]) { + ret = -EINVAL; + break; + } +- event.data = &con2fb; +- if (!lock_fb_info(info)) +- return -ENODEV; + event.info = info; ++ event.data = &con2fb; + ret = fb_notifier_call_chain(FB_EVENT_SET_CONSOLE_MAP, + &event); +- unlock_fb_info(info); + break; + case FBIOBLANK: +- if (!lock_fb_info(info)) +- return -ENODEV; + acquire_console_sem(); + info->flags |= FBINFO_MISC_USEREVENT; + ret = fb_blank(info, arg); + info->flags &= ~FBINFO_MISC_USEREVENT; + release_console_sem(); +- unlock_fb_info(info); +- break; ++ break;; + default: +- if (!lock_fb_info(info)) +- return -ENODEV; +- fb = info->fbops; +- if (fb->fb_ioctl) +- ret = fb->fb_ioctl(info, cmd, arg); +- else ++ if (fb->fb_ioctl == NULL) + ret = -ENOTTY; +- unlock_fb_info(info); ++ else ++ ret = fb->fb_ioctl(info, cmd, arg); + } + return ret; + } + + static long fb_ioctl(struct file *file, unsigned int cmd, unsigned long arg) ++__acquires(&info->lock) ++__releases(&info->lock) + { + struct inode *inode = file->f_path.dentry->d_inode; + int fbidx = iminor(inode); +- struct fb_info *info = registered_fb[fbidx]; ++ struct fb_info *info; ++ long ret; + +- return do_fb_ioctl(info, cmd, arg); ++ info = registered_fb[fbidx]; ++ mutex_lock(&info->lock); ++ ret = do_fb_ioctl(info, cmd, arg); ++ mutex_unlock(&info->lock); ++ return ret; + } + + #ifdef CONFIG_COMPAT +@@ -1264,6 +1257,8 @@ + + static long fb_compat_ioctl(struct file *file, unsigned int cmd, + unsigned long arg) ++__acquires(&info->lock) ++__releases(&info->lock) + { + struct inode *inode = file->f_path.dentry->d_inode; + int fbidx = iminor(inode); +@@ -1271,6 +1266,7 @@ + struct fb_ops *fb = info->fbops; + long ret = -ENOIOCTLCMD; + ++ mutex_lock(&info->lock); + switch(cmd) { + case FBIOGET_VSCREENINFO: + case FBIOPUT_VSCREENINFO: +@@ -1296,6 +1292,7 @@ + ret = fb->fb_compat_ioctl(info, cmd, arg); + break; + } ++ mutex_unlock(&info->lock); + return ret; + } + #endif +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/drivers/video/geode/gx1fb_core.c linux-2.6.29-rc3.owrt/drivers/video/geode/gx1fb_core.c +--- linux-2.6.29.owrt/drivers/video/geode/gx1fb_core.c 2009-05-10 22:04:38.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/drivers/video/geode/gx1fb_core.c 2009-05-10 23:48:29.000000000 +0200 +@@ -136,10 +136,13 @@ + { + struct geodefb_par *par = info->par; + +- if (info->var.bits_per_pixel == 16) ++ if (info->var.bits_per_pixel == 16) { + info->fix.visual = FB_VISUAL_TRUECOLOR; +- else ++ fb_dealloc_cmap(&info->cmap); ++ } else { + info->fix.visual = FB_VISUAL_PSEUDOCOLOR; ++ fb_alloc_cmap(&info->cmap, 1<<info->var.bits_per_pixel, 0); ++ } + + info->fix.line_length = gx1_line_delta(info->var.xres, info->var.bits_per_pixel); + +@@ -312,10 +315,6 @@ + if (!par->panel_x) + par->enable_crt = 1; /* fall back to CRT if no panel is specified */ + +- if (fb_alloc_cmap(&info->cmap, 256, 0) < 0) { +- framebuffer_release(info); +- return NULL; +- } + return info; + } + +@@ -375,11 +374,8 @@ + release_mem_region(gx1_gx_base() + 0x8300, 0x100); + } + +- if (info) { +- fb_dealloc_cmap(&info->cmap); ++ if (info) + framebuffer_release(info); +- } +- + return ret; + } + +@@ -399,7 +395,6 @@ + iounmap(par->dc_regs); + release_mem_region(gx1_gx_base() + 0x8300, 0x100); + +- fb_dealloc_cmap(&info->cmap); + pci_set_drvdata(pdev, NULL); + + framebuffer_release(info); +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/drivers/video/geode/gxfb_core.c linux-2.6.29-rc3.owrt/drivers/video/geode/gxfb_core.c +--- linux-2.6.29.owrt/drivers/video/geode/gxfb_core.c 2009-05-10 22:04:38.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/drivers/video/geode/gxfb_core.c 2009-05-10 23:48:29.000000000 +0200 +@@ -171,10 +171,13 @@ + + static int gxfb_set_par(struct fb_info *info) + { +- if (info->var.bits_per_pixel > 8) ++ if (info->var.bits_per_pixel > 8) { + info->fix.visual = FB_VISUAL_TRUECOLOR; +- else ++ fb_dealloc_cmap(&info->cmap); ++ } else { + info->fix.visual = FB_VISUAL_PSEUDOCOLOR; ++ fb_alloc_cmap(&info->cmap, 1<<info->var.bits_per_pixel, 0); ++ } + + info->fix.line_length = gx_line_delta(info->var.xres, info->var.bits_per_pixel); + +@@ -328,11 +331,6 @@ + + info->var.grayscale = 0; + +- if (fb_alloc_cmap(&info->cmap, 256, 0) < 0) { +- framebuffer_release(info); +- return NULL; +- } +- + return info; + } + +@@ -445,10 +443,8 @@ + pci_release_region(pdev, 1); + } + +- if (info) { +- fb_dealloc_cmap(&info->cmap); ++ if (info) + framebuffer_release(info); +- } + return ret; + } + +@@ -471,7 +467,6 @@ + iounmap(par->gp_regs); + pci_release_region(pdev, 1); + +- fb_dealloc_cmap(&info->cmap); + pci_set_drvdata(pdev, NULL); + + framebuffer_release(info); +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/drivers/video/geode/lxfb_core.c linux-2.6.29-rc3.owrt/drivers/video/geode/lxfb_core.c +--- linux-2.6.29.owrt/drivers/video/geode/lxfb_core.c 2009-05-10 22:04:38.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/drivers/video/geode/lxfb_core.c 2009-05-10 23:48:29.000000000 +0200 +@@ -278,10 +278,13 @@ + + static int lxfb_set_par(struct fb_info *info) + { +- if (info->var.bits_per_pixel > 8) ++ if (info->var.bits_per_pixel > 8) { + info->fix.visual = FB_VISUAL_TRUECOLOR; +- else ++ fb_dealloc_cmap(&info->cmap); ++ } else { + info->fix.visual = FB_VISUAL_PSEUDOCOLOR; ++ fb_alloc_cmap(&info->cmap, 1<<info->var.bits_per_pixel, 0); ++ } + + info->fix.line_length = lx_get_pitch(info->var.xres, + info->var.bits_per_pixel); +@@ -448,11 +451,6 @@ + + info->pseudo_palette = (void *)par + sizeof(struct lxfb_par); + +- if (fb_alloc_cmap(&info->cmap, 256, 0) < 0) { +- framebuffer_release(info); +- return NULL; +- } +- + info->var.grayscale = 0; + + return info; +@@ -581,10 +579,8 @@ + pci_release_region(pdev, 3); + } + +- if (info) { +- fb_dealloc_cmap(&info->cmap); ++ if (info) + framebuffer_release(info); +- } + + return ret; + } +@@ -608,7 +604,6 @@ + iounmap(par->vp_regs); + pci_release_region(pdev, 3); + +- fb_dealloc_cmap(&info->cmap); + pci_set_drvdata(pdev, NULL); + framebuffer_release(info); + } +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/drivers/video/i810/i810_main.c linux-2.6.29-rc3.owrt/drivers/video/i810/i810_main.c +--- linux-2.6.29.owrt/drivers/video/i810/i810_main.c 2009-05-10 22:04:38.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/drivers/video/i810/i810_main.c 2009-05-10 23:48:29.000000000 +0200 +@@ -993,7 +993,6 @@ + struct i810fb_par *par = info->par; + int line_length, vidmem, mode_valid = 0, retval = 0; + u32 vyres = var->yres_virtual, vxres = var->xres_virtual; +- + /* + * Memory limit + */ +@@ -1003,12 +1002,12 @@ + if (vidmem > par->fb.size) { + vyres = par->fb.size/line_length; + if (vyres < var->yres) { +- vyres = info->var.yres; ++ vyres = yres; + vxres = par->fb.size/vyres; + vxres /= var->bits_per_pixel >> 3; + line_length = get_line_length(par, vxres, + var->bits_per_pixel); +- vidmem = line_length * info->var.yres; ++ vidmem = line_length * yres; + if (vxres < var->xres) { + printk("i810fb: required video memory, " + "%d bytes, for %dx%d-%d (virtual) " +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/drivers/video/Kconfig linux-2.6.29-rc3.owrt/drivers/video/Kconfig +--- linux-2.6.29.owrt/drivers/video/Kconfig 2009-05-10 22:04:38.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/drivers/video/Kconfig 2009-05-10 23:48:29.000000000 +0200 +@@ -41,7 +41,7 @@ + You need an utility program called fbset to make full use of frame + buffer devices. Please read <file:Documentation/fb/framebuffer.txt> + and the Framebuffer-HOWTO at +- <http://www.munted.org.uk/programming/Framebuffer-HOWTO-1.2.html> for more ++ <http://www.tahallah.demon.co.uk/programming/prog.html> for more + information. + + Say Y here and to the driver for your graphics board below if you +@@ -1054,7 +1054,9 @@ + + config FB_I810 + tristate "Intel 810/815 support (EXPERIMENTAL)" +- depends on EXPERIMENTAL && FB && PCI && X86_32 && AGP_INTEL ++ depends on FB && EXPERIMENTAL && PCI && X86_32 ++ select AGP ++ select AGP_INTEL + select FB_MODE_HELPERS + select FB_CFB_FILLRECT + select FB_CFB_COPYAREA +@@ -1117,7 +1119,9 @@ + + config FB_INTEL + tristate "Intel 830M/845G/852GM/855GM/865G/915G/945G/945GM/965G/965GM support (EXPERIMENTAL)" +- depends on EXPERIMENTAL && FB && PCI && X86 && AGP_INTEL ++ depends on FB && EXPERIMENTAL && PCI && X86 ++ select AGP ++ select AGP_INTEL + select FB_MODE_HELPERS + select FB_CFB_FILLRECT + select FB_CFB_COPYAREA +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/drivers/video/logo/logo_linux_clut224.ppm linux-2.6.29-rc3.owrt/drivers/video/logo/logo_linux_clut224.ppm +--- linux-2.6.29.owrt/drivers/video/logo/logo_linux_clut224.ppm 2009-05-10 22:04:38.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/drivers/video/logo/logo_linux_clut224.ppm 2009-05-10 23:48:29.000000000 +0200 +@@ -1,2828 +1,1604 @@ + P3 +-145 113 ++# Standard 224-color Linux logo ++80 80 + 255 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 3 4 4 6 7 7 +-8 10 10 8 10 10 6 8 8 6 7 7 3 4 4 2 2 2 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 4 5 5 17 18 17 +-27 29 28 35 37 36 40 43 41 43 45 43 40 43 41 37 39 37 +-32 34 33 27 30 29 23 25 24 17 21 21 15 18 18 12 15 15 +-11 13 13 8 10 10 6 7 7 3 4 4 1 1 1 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 13 13 13 32 34 33 49 51 48 60 60 56 58 59 55 +-55 57 54 55 56 53 49 51 48 43 45 43 39 40 39 33 37 35 +-28 31 30 23 27 26 20 23 23 17 20 20 14 17 17 13 16 16 +-11 14 14 10 13 13 10 12 12 9 11 11 8 10 10 6 7 7 +-2 3 3 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 6 7 7 12 15 15 +-12 15 15 8 9 9 2 3 3 0 0 0 1 1 1 25 27 26 +-55 56 53 68 70 65 65 66 61 65 66 61 63 64 60 63 64 60 +-58 59 55 51 52 50 47 48 46 41 42 42 35 37 36 30 32 31 +-26 28 27 20 24 24 18 22 22 16 19 19 14 17 17 13 16 16 +-12 15 15 11 14 14 10 13 13 10 12 12 9 11 11 8 10 10 +-8 9 9 6 8 8 3 3 3 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 6 7 7 20 24 24 23 27 26 +-23 27 26 18 22 22 11 13 13 23 24 24 61 63 57 72 73 67 +-72 73 67 68 70 65 68 70 65 68 70 65 63 64 60 58 59 55 +-55 56 53 47 48 46 41 42 42 35 37 36 30 32 31 26 28 27 +-20 24 24 18 22 22 16 20 20 15 19 19 14 17 17 13 16 16 +-12 15 15 12 15 15 11 14 14 10 13 13 10 12 12 9 11 11 +-8 10 10 8 9 9 7 9 9 6 7 7 1 2 2 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 1 1 1 4 5 5 5 6 5 4 5 5 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 15 19 19 40 41 39 53 55 47 +-33 36 34 27 30 29 51 52 50 72 73 67 72 73 67 72 73 67 +-72 73 67 68 70 65 68 70 65 63 64 60 58 59 55 51 52 50 +-47 48 46 40 43 41 33 37 35 30 32 31 26 28 27 20 24 24 +-18 22 22 17 21 21 16 19 19 14 18 18 14 17 17 13 17 17 +-13 16 16 12 15 15 12 15 15 11 14 14 10 13 13 10 12 12 +-9 11 11 8 10 10 8 9 9 7 9 9 6 8 8 3 4 4 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-2 2 2 6 8 8 10 12 12 10 12 12 10 12 12 10 12 12 +-6 8 8 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 20 23 23 71 71 57 131 127 93 +-115 113 82 63 64 60 72 73 67 72 73 67 72 73 67 72 73 67 +-68 70 65 65 66 61 61 63 57 55 57 54 49 51 48 43 45 43 +-39 40 39 33 36 34 28 31 30 23 27 26 20 24 24 20 23 23 +-17 21 21 16 20 20 15 19 19 15 18 18 14 18 18 14 17 17 +-13 17 17 13 16 16 12 15 15 12 15 15 11 14 14 10 13 13 +-10 12 12 9 11 11 8 10 10 7 9 9 7 9 9 6 8 8 +-4 5 5 0 0 0 0 0 0 0 0 0 1 1 1 6 7 7 +-10 12 12 10 12 12 10 12 12 10 12 12 10 12 12 10 12 12 +-10 12 12 3 4 4 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 18 22 22 71 71 57 144 139 99 +-84 83 72 68 70 65 72 73 67 72 73 67 68 70 65 65 66 61 +-63 64 60 55 57 54 51 52 50 47 48 46 40 43 41 35 37 36 +-30 32 31 27 29 28 23 27 26 20 24 24 18 22 22 17 21 21 +-16 20 20 15 19 19 15 19 19 15 19 19 15 18 18 14 18 18 +-14 17 17 13 17 17 13 16 16 12 15 15 12 15 15 11 14 14 +-10 13 13 9 12 12 9 11 11 8 10 10 7 9 9 6 8 8 +-6 8 8 3 4 4 0 0 0 2 2 2 8 10 10 10 12 12 +-10 12 12 10 12 12 11 13 13 36 38 35 61 61 53 48 49 45 +-10 12 12 7 9 9 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 15 19 19 61 61 53 84 83 72 +-68 70 65 72 73 67 68 70 65 68 70 65 63 64 60 58 59 55 +-51 52 50 47 48 46 41 42 42 37 39 37 32 35 33 28 31 30 +-23 27 26 20 24 24 20 23 23 18 22 22 17 21 21 17 21 21 +-17 21 21 17 21 21 17 20 20 16 20 20 16 20 20 16 19 19 +-15 18 18 14 18 18 13 17 17 13 16 16 12 15 15 12 15 15 +-11 14 14 10 13 13 9 12 12 9 11 11 8 10 10 7 9 9 +-6 8 8 6 8 8 5 6 5 9 11 11 10 12 12 10 12 12 +-19 20 18 82 81 62 149 145 103 160 154 106 142 137 94 96 95 69 +-10 12 12 10 12 12 1 1 1 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 10 12 12 44 46 43 68 70 65 +-72 73 67 68 70 65 68 70 65 63 64 60 55 57 54 49 51 48 +-43 45 43 39 40 39 33 37 35 30 32 31 26 28 27 23 27 26 +-20 24 24 18 22 22 18 22 22 18 22 22 18 22 22 20 23 23 +-20 24 24 23 25 24 23 25 24 22 24 23 20 23 23 18 22 22 +-17 20 20 15 19 19 15 18 18 14 17 17 13 16 16 12 15 15 +-11 14 14 11 13 13 10 12 12 9 11 11 8 10 10 8 9 9 +-7 9 9 7 9 9 10 12 12 10 12 12 10 12 12 71 71 57 +-164 159 111 186 182 128 186 182 128 171 165 117 151 147 98 96 95 69 +-10 12 12 10 12 12 3 3 3 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 8 10 10 63 64 60 68 70 65 +-72 73 67 68 70 65 63 64 60 55 57 54 47 48 46 40 43 41 +-33 37 35 30 32 31 27 29 28 23 27 26 20 24 24 20 23 23 +-18 22 22 18 22 22 20 23 22 21 25 23 23 27 26 27 29 28 +-28 31 30 31 33 31 31 33 31 31 33 31 28 31 30 26 28 27 +-23 25 24 20 23 22 16 20 20 15 18 18 14 17 17 13 16 16 +-12 15 15 11 14 14 10 13 13 10 12 12 9 11 11 8 10 10 +-10 12 12 10 13 13 10 12 12 12 14 14 96 95 69 165 161 109 +-186 182 128 192 187 134 192 187 134 176 171 126 160 154 106 103 101 77 +-10 12 12 10 12 12 5 6 5 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 35 37 36 68 70 65 72 73 67 +-68 70 65 65 66 61 58 59 55 49 51 48 40 43 41 33 37 35 +-28 31 30 23 27 26 20 24 24 20 23 23 18 22 22 18 22 22 +-18 22 22 20 23 23 23 27 26 27 30 29 32 35 33 37 39 37 +-40 43 41 44 46 43 46 47 43 44 46 43 40 43 41 36 38 35 +-31 33 31 27 29 28 22 24 23 17 21 21 15 18 18 14 17 17 +-13 16 16 12 15 15 11 14 14 11 14 14 11 13 13 13 16 16 +-13 16 16 11 14 14 10 12 12 79 78 62 142 137 94 164 159 111 +-178 174 128 192 187 134 192 187 134 176 171 126 160 154 106 96 95 69 +-10 12 12 10 12 12 6 7 7 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 55 57 54 68 70 65 72 73 67 +-68 70 65 63 64 60 55 56 53 43 45 43 35 37 36 28 31 30 +-23 27 26 20 24 24 18 22 22 17 21 21 17 21 21 17 21 21 +-20 24 24 25 27 26 31 33 31 38 39 37 46 47 43 53 55 47 +-61 61 53 66 65 55 66 65 55 66 65 55 61 61 53 53 55 47 +-46 47 43 37 39 37 30 33 30 24 26 24 17 21 21 15 18 18 +-13 17 17 12 15 15 12 15 15 13 16 16 14 18 18 14 18 18 +-14 17 17 12 15 15 30 31 28 118 116 76 134 131 96 160 154 106 +-174 170 121 178 174 128 178 174 128 171 165 117 151 147 98 96 95 69 +-10 12 12 10 12 12 6 8 8 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 63 64 60 68 70 65 68 70 65 +-65 66 61 58 59 55 49 51 48 39 40 39 30 32 31 23 27 26 +-20 24 24 18 22 22 17 21 21 16 20 20 17 21 21 20 23 23 +-25 27 26 32 35 33 43 44 41 53 55 47 66 65 55 75 75 61 +-82 81 62 84 83 72 87 86 72 87 86 72 82 81 62 75 75 61 +-66 65 55 53 55 47 40 41 39 31 33 31 23 25 24 17 20 20 +-14 18 18 13 16 16 12 15 15 12 15 15 13 17 17 14 18 18 +-14 18 18 13 16 16 46 47 43 96 95 69 125 122 87 142 137 94 +-160 154 106 165 161 109 164 159 111 155 149 109 142 137 94 75 75 61 +-10 12 12 10 12 12 6 8 8 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 60 60 56 68 70 65 68 70 65 +-63 64 60 55 57 54 46 47 45 35 37 36 27 30 29 23 25 24 +-18 22 22 17 21 21 16 20 20 17 21 21 18 22 22 23 27 26 +-31 33 31 43 44 41 55 56 53 71 71 57 84 83 72 92 91 72 +-103 101 77 92 91 72 82 81 62 82 81 62 87 86 72 92 91 72 +-84 83 72 71 71 57 55 56 53 43 44 41 30 33 30 22 24 23 +-16 19 19 14 17 17 12 15 15 12 15 15 13 16 16 14 18 18 +-14 18 18 14 17 17 43 44 41 82 81 62 118 116 76 125 122 87 +-142 137 94 144 139 99 144 139 99 134 131 96 118 116 76 53 55 47 +-10 12 12 10 12 12 6 8 8 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 47 48 46 63 64 60 63 64 60 +-55 57 54 49 51 48 40 43 41 32 34 33 26 28 27 20 24 24 +-18 22 22 16 20 20 16 20 20 17 21 21 20 24 24 28 31 30 +-40 41 39 53 55 47 75 75 61 90 89 73 87 86 72 48 49 45 +-14 14 13 2 2 2 1 2 2 1 1 1 1 1 1 2 2 2 +-19 20 18 43 44 41 66 65 55 53 55 47 38 39 37 26 28 27 +-18 22 22 14 18 18 13 16 16 12 15 15 12 15 15 13 17 17 +-14 18 18 14 18 18 30 31 28 66 65 55 96 95 69 103 101 77 +-118 116 76 118 116 76 118 116 76 118 116 76 103 101 77 36 38 35 +-10 12 12 10 12 12 6 7 7 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 28 31 30 55 57 54 51 52 50 +-49 51 48 41 42 42 35 37 36 28 31 30 23 27 26 20 23 23 +-17 21 21 16 20 20 16 20 20 18 22 22 23 27 26 33 36 34 +-48 49 45 71 71 57 82 81 62 43 44 41 8 9 9 6 7 7 +-6 7 7 6 7 7 6 7 7 5 6 5 4 5 5 3 4 4 +-2 3 3 1 2 2 4 5 4 36 38 35 48 49 45 32 35 33 +-21 25 23 16 19 19 13 17 17 12 15 15 12 15 15 13 16 16 +-14 18 18 14 18 18 16 18 16 36 38 35 61 61 53 82 81 62 +-96 95 69 96 95 69 96 95 69 96 95 69 79 78 62 19 20 18 +-10 12 12 10 12 12 4 5 5 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 13 13 13 46 47 45 43 45 43 +-40 43 41 35 37 36 30 32 31 23 27 26 20 24 24 18 22 22 +-17 21 21 16 20 20 17 21 21 20 23 23 27 30 29 40 41 39 +-61 61 53 53 55 47 16 17 16 9 11 11 10 12 12 10 12 12 +-10 12 12 10 12 12 10 12 12 9 11 11 8 10 10 8 9 9 +-6 8 8 5 6 5 4 5 5 2 3 3 19 20 18 38 39 37 +-26 28 27 17 21 21 14 17 17 13 16 16 12 15 15 12 15 15 +-13 17 17 14 18 18 12 15 15 13 12 7 30 31 28 46 47 43 +-53 55 47 66 65 55 66 65 55 53 55 47 36 38 35 10 12 12 +-10 12 12 10 12 12 2 3 3 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 1 1 1 33 37 35 35 37 36 +-32 35 33 28 31 30 23 27 26 20 24 24 18 22 22 17 21 21 +-16 20 20 16 20 20 17 21 21 21 25 23 31 33 31 44 46 43 +-31 33 31 11 13 13 12 14 14 12 15 15 13 16 16 14 17 17 +-14 17 17 14 17 17 14 17 17 13 16 16 12 15 15 12 14 14 +-11 13 13 9 11 11 8 10 10 6 8 8 4 5 5 17 18 17 +-30 33 30 20 23 22 15 18 18 13 16 16 12 15 15 12 14 14 +-13 16 16 14 17 17 14 18 18 11 12 11 7 7 5 16 17 12 +-21 22 20 30 31 28 25 27 25 21 22 20 14 14 13 10 12 12 +-10 12 12 9 11 11 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 18 22 22 27 30 29 +-27 29 28 40 41 39 53 55 47 53 55 47 53 55 47 46 47 43 +-25 27 25 16 20 20 17 21 21 23 25 24 31 33 31 20 20 20 +-12 15 15 14 17 17 15 19 19 16 20 20 17 21 21 18 22 22 +-18 22 22 18 22 22 18 22 22 17 21 21 17 21 21 16 19 19 +-15 18 18 13 16 16 12 15 15 10 12 12 8 10 10 6 8 8 +-21 22 21 22 24 23 15 19 19 13 17 17 13 16 16 12 15 15 +-12 15 15 13 17 17 14 18 18 14 18 18 13 15 14 10 9 6 +-7 7 5 7 7 5 7 7 5 9 11 11 10 12 12 10 12 12 +-10 12 12 6 7 7 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 16 17 12 82 81 62 +-118 116 76 118 116 76 161 156 96 161 156 96 161 156 96 118 116 76 +-118 116 76 96 95 69 53 55 47 22 24 23 14 17 17 13 16 16 +-15 19 19 17 21 21 18 22 22 20 24 24 20 24 24 23 27 26 +-23 27 26 23 27 26 23 27 26 23 27 26 23 27 26 20 24 24 +-20 23 23 17 21 21 16 19 19 14 17 17 12 15 15 10 12 12 +-9 11 11 20 23 22 16 19 19 14 17 17 13 16 16 12 15 15 +-11 14 14 13 16 16 14 17 17 14 18 18 14 17 17 12 15 15 +-10 12 12 10 12 12 10 12 12 10 12 12 10 12 12 10 12 12 +-9 11 11 1 1 1 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 53 55 47 161 156 96 +-161 156 96 230 229 82 230 229 82 230 229 82 230 229 82 230 229 82 +-230 229 82 161 156 96 118 116 76 96 95 69 21 22 20 16 19 19 +-18 22 22 20 24 24 23 27 26 23 27 26 26 28 27 27 30 29 +-27 30 29 18 22 22 12 14 14 8 10 10 9 11 11 17 21 21 +-23 27 26 23 27 26 20 24 24 18 22 22 16 20 20 14 17 17 +-12 14 14 14 17 17 16 20 20 14 17 17 13 17 17 13 16 16 +-12 15 15 12 15 15 13 17 17 14 18 18 14 17 17 13 16 16 +-11 13 13 10 12 12 10 12 12 10 12 12 10 12 12 10 12 12 +-4 5 5 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 13 12 7 118 116 76 230 229 82 +-230 229 82 230 229 82 230 229 82 230 229 82 230 229 82 230 229 82 +-230 229 82 230 229 82 230 229 82 161 156 96 118 116 76 30 31 28 +-20 24 24 23 27 26 27 30 29 28 31 30 30 32 31 23 27 26 +-16 19 19 17 21 21 12 15 15 9 11 11 10 12 12 9 11 11 +-20 24 24 28 31 30 26 28 27 23 27 26 20 24 24 17 21 21 +-15 19 19 13 16 16 16 19 19 14 18 18 14 17 17 13 16 16 +-12 15 15 11 14 14 13 16 16 14 17 17 14 18 18 14 17 17 +-12 15 15 10 12 12 10 12 12 10 12 12 10 12 12 8 9 9 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 82 81 62 161 156 96 230 229 82 +-230 229 82 233 233 100 230 229 82 230 229 82 230 229 82 230 229 82 +-230 229 82 230 229 82 230 229 82 230 229 82 161 156 96 118 116 76 +-27 29 28 27 30 29 30 32 31 30 32 31 23 27 26 20 24 24 +-26 28 27 17 21 21 6 7 7 72 73 67 145 141 105 15 15 15 +-14 17 17 33 37 35 30 32 31 28 31 30 26 28 27 23 27 26 +-20 23 23 16 20 20 15 19 19 14 18 18 14 17 17 13 16 16 +-12 15 15 11 14 14 12 15 15 13 17 17 14 18 18 14 17 17 +-13 16 16 11 13 13 10 12 12 10 12 12 9 11 11 1 1 1 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 16 17 12 161 156 96 230 229 82 230 229 82 +-243 242 120 235 234 117 230 229 82 230 229 82 230 229 82 230 229 82 +-230 229 82 230 229 82 230 229 82 230 229 82 230 229 82 161 156 96 +-82 81 62 28 31 30 28 31 30 27 30 29 28 31 30 30 32 31 +-33 37 35 13 16 16 3 3 3 105 104 92 210 208 158 12 14 14 +-17 21 21 33 37 35 33 37 35 32 35 33 30 32 31 27 30 29 +-23 27 26 20 23 23 17 20 20 15 18 18 14 18 18 13 17 17 +-13 16 16 12 15 15 11 14 14 13 16 16 14 17 17 14 18 18 +-13 17 17 12 15 15 10 12 12 10 12 12 3 4 4 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 96 95 69 230 229 82 230 229 82 244 244 132 +-241 241 143 243 242 120 230 229 82 230 229 82 230 229 82 230 229 82 +-230 229 82 230 229 82 230 229 82 230 229 82 230 229 82 230 229 82 +-161 156 96 46 47 43 32 35 33 33 37 35 33 37 35 33 37 35 +-40 43 41 23 27 26 1 1 1 2 2 2 24 26 24 14 17 17 +-23 27 26 33 37 35 33 37 35 33 37 35 33 37 35 30 32 31 +-27 30 29 23 27 26 20 23 23 15 18 18 14 18 18 14 17 17 +-13 16 16 12 15 15 11 14 14 12 15 15 13 17 17 14 17 17 +-14 17 17 13 16 16 11 13 13 6 8 8 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 16 17 12 161 156 96 230 229 82 235 234 117 239 239 170 +-239 239 170 236 236 101 230 229 82 230 229 82 230 229 82 230 229 82 +-230 229 82 230 229 82 230 229 82 230 229 82 230 229 82 230 229 82 +-230 229 82 118 116 76 33 37 35 33 37 35 37 39 37 37 39 37 +-43 45 43 49 51 48 20 24 24 8 10 10 17 20 20 35 37 36 +-33 37 35 40 43 41 37 39 37 35 37 36 33 37 35 33 37 35 +-30 32 31 27 30 29 23 27 26 15 19 19 14 18 18 14 17 17 +-13 17 17 13 16 16 12 15 15 11 14 14 13 16 16 14 17 17 +-14 17 17 13 17 17 11 14 14 4 5 5 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 96 95 69 230 229 82 230 229 82 239 239 170 251 251 187 +-241 241 143 230 229 82 230 229 82 230 229 82 230 229 82 230 229 82 +-230 229 82 230 229 82 230 229 82 230 229 82 230 229 82 230 229 82 +-230 229 82 161 156 96 36 38 35 33 37 35 33 37 35 33 37 35 +-37 39 37 47 48 46 55 57 54 55 57 54 49 51 48 43 45 43 +-43 45 43 43 45 43 40 43 41 40 43 41 37 39 37 33 37 35 +-33 37 35 28 31 30 26 28 27 16 20 20 15 18 18 14 18 18 +-14 17 17 13 16 16 12 15 15 11 14 14 12 15 15 13 17 17 +-14 17 17 14 17 17 8 10 10 5 7 7 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-16 17 12 230 229 82 230 229 82 243 242 120 251 251 187 251 251 187 +-246 246 123 230 229 82 230 229 82 230 229 82 230 229 82 230 229 82 +-230 229 82 230 229 82 230 229 82 230 229 82 230 229 82 230 229 82 +-230 229 82 230 229 82 66 65 55 30 32 31 32 35 33 33 37 35 +-33 37 35 37 39 37 40 43 41 47 48 46 49 51 48 51 52 50 +-55 57 54 55 57 54 51 52 50 47 48 46 43 45 43 39 40 39 +-33 37 35 30 32 31 26 28 27 17 21 21 15 19 19 14 18 18 +-14 17 17 13 16 16 12 15 15 12 14 14 11 14 14 13 16 16 +-14 17 17 12 15 15 7 9 9 6 8 8 1 1 1 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-96 95 69 230 229 82 230 229 82 239 239 170 251 251 187 239 239 170 +-230 229 82 230 229 82 230 229 82 230 229 82 230 229 82 230 229 82 +-230 229 82 230 229 82 230 229 82 230 229 82 230 229 82 230 229 82 +-230 229 82 230 229 82 96 95 69 27 30 29 28 31 30 30 32 31 +-33 37 35 40 43 41 46 47 45 55 57 54 63 64 60 72 73 67 +-72 73 67 72 73 67 72 73 67 65 66 61 55 57 54 47 48 46 +-39 40 39 32 35 33 27 30 29 17 21 21 15 19 19 15 18 18 +-14 18 18 13 17 17 13 16 16 12 15 15 11 14 14 12 14 14 +-13 16 16 9 11 11 7 9 9 9 11 11 66 65 55 115 113 82 +-21 22 20 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 13 12 7 +-230 229 82 230 229 82 236 236 101 251 251 187 251 251 187 246 246 123 +-230 229 82 230 229 82 230 229 82 230 229 82 230 229 82 230 229 82 +-230 229 82 230 229 82 230 229 82 230 229 82 230 229 82 230 229 82 +-230 229 82 230 229 82 118 116 76 23 27 26 26 28 27 32 35 33 +-51 52 50 90 89 73 110 109 94 145 141 105 168 163 120 177 172 135 +-177 172 135 188 184 146 188 184 146 181 176 137 194 191 148 188 184 146 +-184 179 149 188 184 146 188 184 146 156 151 111 177 172 135 181 176 137 +-177 172 135 168 163 120 168 163 120 158 153 112 156 151 111 158 153 112 +-156 151 111 158 153 112 177 172 135 188 184 146 188 184 146 194 189 146 +-36 38 35 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 82 81 62 +-230 229 82 230 229 82 244 244 132 251 251 187 244 244 132 230 229 82 +-230 229 82 230 229 82 230 229 82 230 229 82 230 229 82 230 229 82 +-230 229 82 230 229 82 230 229 82 230 229 82 161 156 96 82 81 62 +-96 95 69 230 229 82 181 178 103 110 109 94 156 151 111 188 184 146 +-188 184 146 197 193 154 188 184 146 184 181 136 188 184 146 168 163 120 +-168 163 120 178 174 128 156 151 111 158 153 112 174 170 121 156 151 111 +-156 151 111 158 153 112 156 151 111 168 163 120 178 174 128 181 176 137 +-176 171 126 178 174 128 184 181 136 176 171 126 178 174 128 184 181 136 +-176 171 126 178 174 128 184 181 136 164 159 111 155 149 109 96 95 69 +-1 1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 2 2 1 161 156 96 +-230 229 82 230 229 82 244 244 132 244 244 132 236 236 101 230 229 82 +-230 229 82 230 229 82 230 229 82 230 229 82 230 229 82 230 229 82 +-230 229 82 230 229 82 230 229 82 230 229 82 46 47 43 82 81 62 +-158 153 112 197 193 154 194 189 146 184 181 136 188 184 146 168 163 120 +-156 151 111 137 133 100 131 127 93 137 133 100 137 133 100 158 153 112 +-121 119 87 137 133 100 156 151 111 145 141 105 99 98 80 84 83 72 +-63 64 60 52 53 49 40 43 41 33 36 34 36 38 35 36 38 35 +-38 39 37 43 44 41 43 44 41 46 47 43 48 49 45 48 49 45 +-46 47 43 36 38 35 30 31 28 19 20 18 6 7 7 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 36 38 35 230 229 82 +-230 229 82 230 229 82 246 246 123 236 236 101 230 229 82 230 229 82 +-230 229 82 230 229 82 230 229 82 230 229 82 230 229 82 230 229 82 +-230 229 82 230 229 82 230 229 82 230 229 82 53 55 47 121 119 87 +-176 171 126 171 165 117 161 156 96 82 81 62 53 55 47 33 37 35 +-39 40 39 63 64 60 99 98 80 121 119 87 137 133 100 177 172 135 +-176 171 126 184 181 136 131 127 93 131 127 93 110 109 94 84 83 72 +-51 52 50 39 40 39 27 29 28 18 22 22 16 19 19 15 19 19 +-15 19 19 14 18 18 14 17 17 13 16 16 12 15 15 11 14 14 +-10 13 13 9 12 12 9 11 11 8 9 9 7 9 9 1 1 1 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 118 116 76 230 229 82 +-230 229 82 230 229 82 236 236 101 230 229 82 230 229 82 230 229 82 +-230 229 82 230 229 82 230 229 82 230 229 82 230 229 82 230 229 82 +-230 229 82 230 229 82 230 229 82 230 229 82 96 95 69 71 71 57 +-36 38 35 118 116 76 118 116 76 12 15 15 15 18 18 20 24 24 +-33 37 35 55 56 53 84 83 72 110 109 94 145 141 105 110 109 94 +-168 163 120 121 119 87 156 151 111 131 127 93 87 86 72 61 63 57 +-47 48 46 28 31 30 18 22 22 15 19 19 15 18 18 15 19 19 +-15 19 19 14 18 18 14 17 17 13 17 17 13 16 16 12 15 15 +-11 13 13 10 12 12 9 11 11 8 10 10 7 9 9 3 3 3 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 1 1 0 230 229 82 230 229 82 +-230 229 82 230 229 82 230 229 82 230 229 82 230 229 82 230 229 82 +-230 229 82 230 229 82 230 229 82 230 229 82 230 229 82 230 229 82 +-230 229 82 230 229 82 230 229 82 230 229 82 230 229 82 161 156 96 +-161 156 96 230 229 82 118 116 76 11 14 14 14 17 17 18 22 22 +-27 30 29 40 43 41 60 60 56 84 83 72 105 104 92 110 109 94 +-110 109 94 110 109 94 99 98 80 90 89 73 68 70 65 47 48 46 +-32 34 33 23 25 24 20 23 23 17 21 21 15 19 19 14 17 17 +-15 19 19 15 18 18 14 18 18 13 17 17 13 16 16 12 15 15 +-11 14 14 10 12 12 9 11 11 8 10 10 7 9 9 4 5 5 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 16 17 12 230 229 82 230 229 82 +-230 229 82 230 229 82 230 229 82 230 229 82 230 229 82 230 229 82 +-230 229 82 230 229 82 230 229 82 230 229 82 230 229 82 230 229 82 +-230 229 82 230 229 82 230 229 82 230 229 82 230 229 82 230 229 82 +-230 229 82 161 156 96 118 116 76 11 13 13 13 16 16 15 19 19 +-20 24 24 30 32 31 40 43 41 51 52 50 63 64 60 72 73 67 +-65 66 61 65 66 61 65 66 61 55 57 54 46 47 45 33 37 35 +-27 29 28 20 24 24 17 21 21 16 20 20 16 20 20 15 19 19 +-15 19 19 15 19 19 14 18 18 14 17 17 13 16 16 12 15 15 +-11 14 14 10 13 13 9 12 12 8 10 10 7 9 9 6 7 7 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 53 55 47 230 229 82 230 229 82 +-230 229 82 230 229 82 230 229 82 230 229 82 230 229 82 230 229 82 +-230 229 82 230 229 82 230 229 82 230 229 82 230 229 82 230 229 82 +-230 229 82 230 229 82 230 229 82 230 229 82 230 229 82 230 229 82 +-161 156 96 118 116 76 53 55 47 10 13 13 12 15 15 14 17 17 +-17 20 20 20 24 24 27 29 28 32 34 33 37 39 37 40 43 41 +-43 45 43 41 42 42 35 37 36 30 32 31 28 31 30 23 27 26 +-20 23 23 17 21 21 16 20 20 16 20 20 16 20 20 16 19 19 +-15 19 19 15 19 19 14 18 18 14 17 17 13 16 16 12 15 15 +-11 14 14 10 13 13 9 12 12 9 11 11 8 10 10 10 12 12 +-1 1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 82 81 62 230 229 82 230 229 82 +-230 229 82 230 229 82 230 229 82 230 229 82 230 229 82 230 229 82 +-230 229 82 230 229 82 230 229 82 230 229 82 230 229 82 230 229 82 +-230 229 82 230 229 82 230 229 82 230 229 82 161 156 96 161 156 96 +-118 116 76 82 81 62 13 14 12 10 13 13 12 15 15 13 17 17 +-15 19 19 16 20 20 20 23 23 20 24 24 23 27 26 26 28 27 +-26 28 27 26 28 27 23 27 26 18 22 22 20 23 23 17 21 21 +-17 21 21 16 20 20 16 20 20 16 20 20 16 20 20 16 19 19 +-15 19 19 15 19 19 15 18 18 14 17 17 13 17 17 13 16 16 +-12 15 15 12 14 14 12 14 14 12 14 14 12 14 14 23 24 24 +-6 8 8 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 118 116 76 230 229 82 230 229 82 +-230 229 82 230 229 82 230 229 82 230 229 82 230 229 82 230 229 82 +-230 229 82 230 229 82 230 229 82 230 229 82 230 229 82 230 229 82 +-230 229 82 230 229 82 230 229 82 161 156 96 161 156 96 118 116 76 +-71 71 57 13 14 12 9 12 12 10 13 13 12 15 15 13 17 17 +-15 18 18 15 19 19 16 20 20 17 21 21 17 21 21 18 22 22 +-18 22 22 18 22 22 17 21 21 16 19 19 15 18 18 14 18 18 +-16 19 19 16 20 20 16 20 20 16 20 20 16 20 20 16 20 20 +-15 19 19 15 19 19 15 18 18 14 18 18 16 20 20 23 25 24 +-17 21 21 25 27 26 47 48 46 47 48 46 51 52 50 72 73 67 +-33 36 34 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 118 116 76 230 229 82 230 229 82 +-230 229 82 230 229 82 230 229 82 230 229 82 230 229 82 230 229 82 +-230 229 82 230 229 82 230 229 82 230 229 82 230 229 82 230 229 82 +-230 229 82 230 229 82 161 156 96 118 116 76 118 116 76 46 47 43 +-9 11 11 9 11 11 10 12 12 11 13 13 12 15 15 14 17 17 +-15 18 18 15 19 19 16 20 20 16 20 20 16 20 20 16 20 20 +-16 20 20 16 20 20 16 20 20 16 20 20 16 20 20 16 20 20 +-15 19 19 16 20 20 16 20 20 16 20 20 16 20 20 16 20 20 +-15 19 19 16 20 20 20 24 24 55 56 53 32 34 33 84 83 72 +-90 89 73 110 109 94 110 109 94 105 104 92 110 109 94 110 109 94 +-72 73 67 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 96 95 69 230 229 82 230 229 82 +-230 229 82 230 229 82 230 229 82 230 229 82 230 229 82 230 229 82 +-230 229 82 230 229 82 230 229 82 230 229 82 230 229 82 230 229 82 +-230 229 82 161 156 96 118 116 76 82 81 62 16 17 12 9 11 11 +-9 11 11 9 12 12 10 13 13 12 14 14 13 16 16 14 18 18 +-15 19 19 16 20 20 16 20 20 16 20 20 16 20 20 16 20 20 +-16 20 20 16 20 20 16 20 20 16 20 20 16 20 20 16 20 20 +-16 20 20 16 20 20 16 20 20 16 20 20 16 20 20 16 20 20 +-16 19 19 33 36 34 99 98 80 156 151 111 145 141 105 184 179 149 +-168 163 120 184 179 149 177 172 135 156 151 111 145 141 105 110 109 94 +-90 89 73 2 2 2 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 71 71 57 230 229 82 230 229 82 +-230 229 82 230 229 82 230 229 82 230 229 82 230 229 82 230 229 82 +-230 229 82 161 156 96 230 229 82 230 229 82 230 229 82 161 156 96 +-118 116 76 82 81 62 30 31 28 9 11 11 9 11 11 9 11 11 +-10 12 12 10 13 13 11 14 14 13 16 16 14 17 17 15 18 18 +-15 19 19 16 20 20 16 20 20 16 20 20 16 20 20 16 20 20 +-16 20 20 16 20 20 16 20 20 16 20 20 16 20 20 16 20 20 +-16 20 20 16 20 20 16 20 20 16 20 20 16 20 20 16 20 20 +-18 22 22 58 59 55 137 133 100 197 193 154 214 212 158 210 208 158 +-197 193 154 184 179 149 184 179 149 137 133 100 110 109 94 99 98 80 +-84 83 72 10 10 9 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 16 17 12 230 229 82 230 229 82 +-230 229 82 230 229 82 230 229 82 230 229 82 230 229 82 161 156 96 +-161 156 96 161 156 96 161 156 96 161 156 96 118 116 76 71 71 57 +-21 22 20 12 14 14 11 13 13 10 12 12 10 12 12 10 13 13 +-11 13 13 12 15 15 13 16 16 14 17 17 14 18 18 15 19 19 +-16 20 20 16 20 20 16 20 20 16 20 20 16 20 20 16 20 20 +-16 20 20 16 20 20 16 20 20 16 20 20 16 20 20 16 20 20 +-16 20 20 16 20 20 16 20 20 16 20 20 16 20 20 17 21 21 +-23 27 26 84 83 72 184 179 149 251 251 187 210 208 158 184 179 149 +-184 179 149 156 151 111 110 109 94 84 83 72 63 64 60 51 52 50 +-18 22 22 6 8 8 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 118 116 76 230 229 82 +-230 229 82 230 229 82 230 229 82 230 229 82 161 156 96 161 156 96 +-161 156 96 161 156 96 118 116 76 53 55 47 20 23 22 16 19 19 +-13 16 16 12 15 15 12 14 14 11 14 14 11 14 14 11 14 14 +-12 15 15 13 16 16 14 17 17 15 19 19 16 20 20 17 21 21 +-23 27 26 18 22 22 20 24 24 23 27 26 30 32 31 17 21 21 +-16 20 20 16 20 20 16 20 20 16 20 20 16 20 20 16 20 20 +-16 20 20 16 20 20 16 20 20 16 20 20 16 20 20 16 20 20 +-23 27 26 33 37 35 137 133 100 156 151 111 158 153 112 105 104 92 +-105 104 92 68 70 65 39 40 39 18 22 22 12 14 14 12 15 15 +-9 11 11 4 5 5 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 16 17 12 230 229 82 +-230 229 82 230 229 82 230 229 82 161 156 96 118 116 76 118 116 76 +-118 116 76 66 65 55 43 45 43 32 34 33 25 27 26 20 23 22 +-17 20 20 15 18 18 14 17 17 15 18 18 13 16 16 14 17 17 +-14 18 18 16 20 20 32 34 33 55 57 54 58 59 55 72 73 67 +-105 104 92 55 57 54 65 66 61 63 64 60 40 43 41 33 37 35 +-41 42 42 20 24 24 16 20 20 16 20 20 16 20 20 16 20 20 +-16 20 20 16 20 20 16 20 20 16 20 20 16 20 20 16 20 20 +-17 21 21 26 28 27 30 32 31 35 37 36 68 70 65 39 40 39 +-23 27 26 15 18 18 13 16 16 11 14 14 9 12 12 8 10 10 +-7 9 9 6 7 7 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 36 38 35 +-230 229 82 230 229 82 230 229 82 96 95 69 30 31 28 49 51 48 +-90 89 73 68 70 65 55 57 54 47 48 46 47 48 46 43 45 43 +-32 34 33 43 45 43 43 45 43 23 27 26 25 27 26 40 43 41 +-40 43 41 90 89 73 110 109 94 145 141 105 156 151 111 156 151 111 +-184 179 149 184 179 149 177 172 135 184 179 149 137 133 100 84 83 72 +-105 104 92 63 64 60 49 51 48 47 48 46 28 31 30 18 22 22 +-16 20 20 16 20 20 16 20 20 16 20 20 16 20 20 16 20 20 +-16 20 20 15 19 19 15 19 19 15 19 19 18 22 22 15 19 19 +-13 16 16 12 15 15 11 14 14 10 13 13 9 12 12 9 11 11 +-8 10 10 6 8 8 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-30 31 28 230 229 82 71 71 57 2 2 1 0 0 0 58 59 55 +-105 104 92 84 83 72 65 66 61 84 83 72 110 109 94 110 109 94 +-145 141 105 105 104 92 110 109 94 110 109 94 84 83 72 110 109 94 +-158 153 112 197 193 154 197 193 154 239 239 170 251 251 187 251 251 187 +-251 251 187 251 251 187 251 251 187 251 251 187 210 208 158 197 193 154 +-197 193 154 184 179 149 145 141 105 137 133 100 105 104 92 47 48 46 +-20 23 23 16 20 20 16 20 20 16 20 20 16 20 20 16 20 20 +-16 20 20 16 19 19 15 19 19 15 19 19 14 18 18 14 17 17 +-13 17 17 13 16 16 12 14 14 12 14 14 13 13 13 13 13 13 +-13 13 13 12 12 12 10 10 9 6 7 7 2 2 2 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 1 1 0 0 0 0 0 0 0 65 66 61 +-105 104 92 84 83 72 84 83 72 110 109 94 184 179 149 210 208 158 +-210 208 158 210 208 158 214 212 158 197 193 154 214 212 158 210 208 158 +-251 251 187 251 251 187 251 251 187 251 251 187 251 251 187 251 251 187 +-251 251 187 251 251 187 251 251 187 251 251 187 251 251 187 251 251 187 +-251 251 187 251 251 187 239 239 170 251 251 187 184 179 149 84 83 72 +-26 28 27 16 20 20 16 20 20 16 20 20 16 20 20 16 20 20 +-16 20 20 16 20 20 15 19 19 15 19 19 15 18 18 14 18 18 +-13 17 17 13 16 16 15 15 15 14 14 13 14 14 13 14 14 13 +-13 13 13 13 13 13 12 12 12 12 12 12 12 12 12 3 4 4 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 72 73 67 +-105 104 92 99 98 80 84 83 72 99 98 80 177 172 135 197 193 154 +-251 251 187 251 251 187 251 251 187 251 251 187 251 251 187 251 251 187 +-251 251 187 251 251 187 251 251 187 251 251 187 251 251 187 251 251 187 +-251 251 187 251 251 187 251 251 187 251 251 187 251 251 187 251 251 187 +-251 251 187 251 251 187 251 251 187 214 212 158 197 193 154 99 98 80 +-23 27 26 16 20 20 16 20 20 16 20 20 16 20 20 16 20 20 +-16 20 20 16 20 20 15 19 19 15 19 19 15 18 18 14 18 18 +-14 17 17 16 16 16 16 16 16 16 16 16 15 15 15 14 14 13 +-14 14 13 13 13 13 13 13 13 12 12 12 12 12 12 12 12 12 +-3 3 3 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 84 83 72 +-110 109 94 99 98 80 72 73 67 63 64 60 99 98 80 177 172 135 +-184 179 149 210 208 158 251 251 187 251 251 187 251 251 187 251 251 187 +-251 251 187 251 251 187 251 251 187 251 251 187 251 251 187 251 251 187 +-251 251 187 251 251 187 251 251 187 251 251 187 251 251 187 251 251 187 +-251 251 187 210 208 158 184 179 149 177 172 135 110 109 94 33 37 35 +-17 21 21 16 20 20 16 20 20 16 20 20 16 20 20 16 20 20 +-16 20 20 16 20 20 15 19 19 15 19 19 15 19 19 14 18 18 +-15 18 18 18 19 18 18 19 18 17 17 17 16 16 16 15 15 15 +-14 14 13 13 13 13 13 13 13 12 12 12 12 12 12 12 12 12 +-10 10 9 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 2 2 2 105 104 92 +-108 107 93 99 98 80 72 73 67 63 64 60 51 52 50 87 86 72 +-105 104 92 110 109 94 108 107 93 156 151 111 184 179 149 184 179 149 +-197 193 154 197 193 154 197 193 154 184 179 149 184 179 149 177 172 135 +-197 193 154 156 151 111 177 172 135 184 179 149 168 163 120 137 133 100 +-145 141 105 110 109 94 99 98 80 47 48 46 55 57 54 15 19 19 +-16 19 19 16 20 20 16 20 20 16 20 20 16 20 20 16 20 20 +-17 20 20 17 21 21 16 20 20 16 19 19 15 19 19 16 19 19 +-20 20 20 21 22 21 20 20 20 19 20 19 18 19 18 16 16 16 +-15 15 15 14 14 13 13 13 13 13 13 13 12 12 12 12 12 12 +-12 12 12 4 5 5 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 58 59 55 110 109 94 +-105 104 92 90 89 73 72 73 67 55 57 54 43 45 43 39 40 39 +-43 45 43 46 47 45 43 45 43 68 70 65 65 66 61 63 64 60 +-108 107 93 72 73 67 105 104 92 90 89 73 72 73 67 40 43 41 +-72 73 67 68 70 65 68 70 65 58 59 55 63 64 60 49 51 48 +-43 45 43 33 36 34 27 30 29 20 24 24 16 20 20 15 19 19 +-15 19 19 15 19 19 15 19 19 16 19 19 16 20 20 16 20 20 +-17 21 21 20 24 24 20 23 22 17 21 21 17 20 20 20 20 20 +-21 22 21 21 22 21 21 22 21 21 22 21 20 20 20 18 19 18 +-16 16 16 15 15 15 13 13 13 13 13 13 12 12 12 12 12 12 +-12 12 12 10 10 9 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 21 22 21 110 109 94 110 109 94 +-105 104 92 84 83 72 68 70 65 51 52 50 41 42 42 33 37 35 +-28 31 30 23 27 26 20 23 23 18 22 22 17 20 20 25 27 26 +-26 28 27 27 30 29 25 27 26 20 23 23 23 27 26 30 32 31 +-20 24 24 17 21 21 18 22 22 15 19 19 26 28 27 20 23 23 +-14 18 18 15 19 19 15 18 18 15 19 19 15 19 19 15 19 19 +-15 19 19 15 19 19 15 19 19 15 19 19 15 19 19 16 19 19 +-16 20 20 22 24 23 24 26 24 22 24 23 20 23 22 22 24 23 +-24 26 24 24 26 24 23 24 24 22 24 23 21 22 21 19 20 19 +-17 17 17 15 15 15 14 14 13 13 13 13 12 12 12 12 12 12 +-12 12 12 12 12 12 2 2 2 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 2 2 2 99 98 80 110 109 94 108 107 93 +-105 104 92 84 83 72 63 64 60 49 51 48 39 40 39 32 34 33 +-27 30 29 23 25 24 20 23 23 17 20 20 15 19 19 14 18 18 +-14 17 17 13 17 17 13 17 17 13 17 17 13 17 17 13 17 17 +-14 17 17 14 17 17 14 17 17 14 17 17 14 17 17 14 17 17 +-14 18 18 14 18 18 14 18 18 14 18 18 15 18 18 15 19 19 +-15 19 19 15 19 19 15 19 19 15 19 19 15 19 19 15 19 19 +-15 19 19 17 21 21 27 29 28 26 28 27 25 27 26 25 27 26 +-27 29 28 27 29 28 26 28 27 24 26 24 21 22 21 20 20 20 +-18 19 18 16 16 16 14 14 13 13 13 13 12 12 12 12 12 12 +-12 12 12 12 12 12 4 5 5 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 51 52 50 110 109 94 110 109 94 105 104 92 +-90 89 73 72 73 67 55 57 54 43 45 43 35 37 36 30 32 31 +-26 28 27 20 24 24 17 21 21 16 19 19 15 18 18 14 17 17 +-13 16 16 13 16 16 13 16 16 13 16 16 13 16 16 13 16 16 +-13 16 16 13 16 16 13 16 16 13 17 17 13 17 17 14 17 17 +-14 17 17 14 17 17 14 17 17 14 18 18 14 18 18 14 18 18 +-15 18 18 15 18 18 15 19 19 15 19 19 15 19 19 15 19 19 +-15 19 19 15 19 19 27 29 28 32 34 33 28 31 30 27 29 28 +-30 32 31 30 32 31 30 31 28 26 28 27 23 24 24 21 22 21 +-19 20 19 16 16 16 14 14 13 13 13 13 12 12 12 12 12 12 +-12 12 12 12 12 12 6 7 7 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 3 3 3 0 0 0 0 0 0 +-0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 10 10 9 108 107 93 110 109 94 108 107 93 99 98 80 +-84 83 72 63 64 60 49 51 48 40 43 41 33 36 34 27 30 29 +-23 27 26 18 22 22 17 20 20 15 18 18 14 17 17 13 16 16 +-13 16 16 13 16 16 12 15 15 12 15 15 12 15 15 12 15 15 +-13 16 16 13 16 16 13 16 16 13 16 16 13 16 16 13 16 16 +-13 17 17 13 17 17 14 17 17 14 17 17 14 17 17 14 18 18 +-14 18 18 14 18 18 15 18 18 15 18 18 15 19 19 15 19 19 +-15 19 19 15 19 19 17 21 21 33 36 34 32 34 33 31 33 31 +-33 36 34 33 36 34 31 33 31 27 29 28 25 27 26 21 22 21 +-19 20 19 17 17 17 15 15 15 13 13 13 12 12 12 12 12 12 +-12 12 12 12 12 12 8 8 7 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 63 64 60 137 133 100 43 45 43 0 0 0 +-0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 68 70 65 110 109 94 110 109 94 105 104 92 84 83 72 +-68 70 65 55 57 54 43 45 43 35 37 36 30 32 31 26 28 27 +-20 24 24 17 21 21 16 19 19 14 17 17 13 16 16 12 15 15 +-12 15 15 12 15 15 12 15 15 12 15 15 12 15 15 12 15 15 +-12 15 15 12 15 15 12 15 15 12 15 15 12 15 15 13 16 16 +-13 16 16 13 16 16 13 16 16 13 17 17 13 17 17 14 17 17 +-14 17 17 14 17 17 14 18 18 14 18 18 14 18 18 15 18 18 +-15 19 19 15 19 19 15 19 19 20 24 24 32 34 33 35 37 36 +-37 39 37 35 37 36 33 36 34 30 32 31 26 28 27 22 24 23 +-20 20 20 17 17 17 15 15 15 13 13 13 12 12 12 12 12 12 +-12 12 12 12 12 12 8 8 7 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-1 1 1 99 98 80 184 179 149 184 179 149 68 70 65 0 0 0 +-0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-15 15 15 110 109 94 110 109 94 108 107 93 99 98 80 72 73 67 +-61 63 57 49 51 48 39 40 39 33 36 34 27 30 29 23 25 24 +-18 22 22 16 19 19 14 17 17 13 16 16 12 15 15 12 15 15 +-11 14 14 11 14 14 11 14 14 11 14 14 11 14 14 11 14 14 +-11 14 14 11 14 14 12 14 14 12 15 15 12 15 15 12 15 15 +-12 15 15 13 16 16 13 16 16 13 16 16 13 16 16 13 16 16 +-13 17 17 14 17 17 14 17 17 14 17 17 14 18 18 14 18 18 +-14 18 18 15 18 18 15 19 19 15 19 19 30 32 31 38 39 37 +-39 40 39 39 40 39 35 37 36 31 33 31 27 29 28 22 24 23 +-20 20 20 17 17 17 15 15 15 13 13 13 12 12 12 12 12 12 +-12 12 12 12 12 12 8 8 7 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 3 3 3 +-110 109 94 197 193 154 210 208 158 184 179 149 68 70 65 0 0 0 +-0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-68 70 65 110 109 94 110 109 94 105 104 92 84 83 72 65 66 61 +-51 52 50 43 45 43 35 37 36 30 32 31 25 27 26 20 23 23 +-17 20 20 15 18 18 13 16 16 12 15 15 12 15 15 11 14 14 +-11 14 14 11 14 14 11 13 13 11 13 13 11 13 13 11 13 13 +-11 14 14 11 14 14 11 14 14 11 14 14 11 14 14 11 14 14 +-12 15 15 12 15 15 12 15 15 12 15 15 13 16 16 13 16 16 +-13 16 16 13 16 16 13 17 17 13 17 17 14 17 17 14 17 17 +-14 18 18 14 18 18 14 18 18 16 19 19 37 39 37 41 42 42 +-41 42 42 41 42 42 38 39 37 32 34 33 27 29 28 23 24 24 +-21 22 21 17 17 17 15 15 15 13 13 13 12 12 12 12 12 12 +-12 12 12 12 12 12 8 8 7 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 11 11 11 137 133 100 +-197 193 154 251 251 187 239 239 170 184 179 149 31 33 31 0 0 0 +-0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 12 12 12 +-110 109 94 110 109 94 105 104 92 90 89 73 72 73 67 58 59 55 +-46 47 45 37 39 37 31 33 31 26 28 27 20 24 24 17 21 21 +-15 18 18 13 16 16 12 15 15 12 14 14 11 13 13 11 13 13 +-10 13 13 10 13 13 10 13 13 10 13 13 10 13 13 10 13 13 +-10 13 13 10 13 13 11 13 13 11 13 13 11 14 14 11 14 14 +-11 14 14 11 14 14 12 14 14 12 15 15 12 15 15 12 15 15 +-13 16 16 13 16 16 13 16 16 13 16 16 13 17 17 13 17 17 +-14 17 17 14 17 17 14 18 18 23 27 26 41 42 42 41 42 42 +-43 45 43 41 42 42 39 40 39 33 36 34 27 29 28 23 24 24 +-21 22 21 17 17 17 15 15 15 13 13 13 12 12 12 12 12 12 +-12 12 12 12 12 12 6 7 7 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 27 29 28 168 163 120 210 208 158 +-251 251 187 251 251 187 210 208 158 137 133 100 1 1 1 0 0 0 +-0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 60 60 56 +-110 109 94 105 104 92 105 104 92 84 83 72 65 66 61 51 52 50 +-40 43 41 33 36 34 27 30 29 23 25 24 18 22 22 16 19 19 +-14 17 17 12 15 15 11 14 14 11 14 14 10 13 13 10 13 13 +-10 13 13 10 12 12 10 12 12 10 12 12 10 12 12 10 12 12 +-10 12 12 10 12 12 10 13 13 10 13 13 10 13 13 11 13 13 +-11 13 13 11 14 14 11 14 14 11 14 14 11 14 14 12 15 15 +-12 15 15 12 15 15 12 15 15 13 16 16 13 16 16 13 16 16 +-13 17 17 13 17 17 14 17 17 32 34 33 43 45 43 43 45 43 +-43 45 43 43 45 43 39 40 39 33 36 34 27 29 28 23 24 24 +-21 22 21 17 17 17 15 15 15 13 13 13 12 12 12 12 12 12 +-12 12 12 12 12 12 6 7 7 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 1 1 1 68 70 65 184 179 149 210 208 158 251 251 187 +-251 251 187 214 212 158 184 179 149 37 39 37 0 0 0 0 0 0 +-0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 6 7 7 105 104 92 +-105 104 92 105 104 92 99 98 80 72 73 67 58 59 55 46 47 45 +-35 37 36 30 32 31 25 27 26 20 23 23 16 19 19 14 17 17 +-12 15 15 12 14 14 11 13 13 10 13 13 10 12 12 10 12 12 +-10 12 12 10 12 12 9 12 12 9 12 12 9 12 12 9 12 12 +-10 12 12 10 12 12 10 12 12 10 12 12 10 12 12 10 13 13 +-10 13 13 10 13 13 11 13 13 11 13 13 11 14 14 11 14 14 +-11 14 14 12 15 15 12 15 15 12 15 15 12 15 15 13 16 16 +-13 16 16 13 16 16 17 20 20 41 42 42 46 47 45 46 47 45 +-46 47 45 43 45 43 40 41 39 33 36 34 27 29 28 23 24 24 +-20 20 20 17 17 17 15 15 15 13 13 13 12 12 12 12 12 12 +-12 12 12 12 12 12 4 5 5 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-15 15 15 110 109 94 197 193 154 214 212 158 251 251 187 251 251 187 +-239 239 170 184 179 149 84 83 72 0 0 0 0 0 0 0 0 0 +-0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 47 48 46 105 104 92 +-105 104 92 99 98 80 84 83 72 68 70 65 51 52 50 40 43 41 +-32 34 33 27 29 28 22 24 23 17 21 21 15 18 18 13 16 16 +-12 15 15 11 13 13 10 13 13 10 12 12 9 12 12 9 12 12 +-9 12 12 9 12 12 9 11 11 9 11 11 9 11 11 9 11 11 +-9 12 12 9 12 12 9 12 12 9 12 12 10 12 12 10 12 12 +-10 12 12 10 12 12 10 13 13 10 13 13 10 13 13 11 13 13 +-11 14 14 11 14 14 11 14 14 12 14 14 12 15 15 12 15 15 +-12 15 15 13 16 16 28 31 30 43 45 43 47 48 46 47 48 46 +-47 48 46 43 45 43 40 41 39 33 36 34 27 29 28 22 24 23 +-20 20 20 17 17 17 15 15 15 13 13 13 12 12 12 12 12 12 +-12 12 12 12 12 12 3 4 4 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 1 1 1 60 60 56 +-177 172 135 197 193 154 251 251 187 251 251 187 251 251 187 251 251 187 +-184 179 149 110 109 94 3 4 4 0 0 0 0 0 0 0 0 0 +-0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 1 1 1 99 98 80 105 104 92 +-99 98 80 87 86 72 84 83 72 63 64 60 46 47 45 35 37 36 +-30 32 31 25 27 26 18 22 22 16 19 19 14 17 17 12 15 15 +-11 14 14 10 13 13 9 12 12 9 12 12 9 11 11 9 11 11 +-9 11 11 9 11 11 9 11 11 9 11 11 9 11 11 9 11 11 +-9 11 11 9 11 11 9 11 11 9 11 11 9 12 12 9 12 12 +-9 12 12 10 12 12 10 12 12 10 12 12 10 13 13 10 13 13 +-10 13 13 11 13 13 11 14 14 11 14 14 11 14 14 12 15 15 +-12 15 15 14 17 17 41 42 42 47 48 46 49 51 48 51 52 50 +-47 48 46 43 45 43 40 41 39 33 36 34 27 29 28 22 24 23 +-19 20 19 16 16 16 14 14 13 13 13 13 12 12 12 12 12 12 +-12 12 12 12 12 12 2 2 2 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 23 24 24 137 133 100 184 179 149 +-210 208 158 251 251 187 251 251 187 251 251 187 251 251 187 184 179 149 +-110 109 94 13 13 13 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 30 32 31 105 104 92 99 98 80 +-84 83 72 84 83 72 72 73 67 55 57 54 41 42 42 32 34 33 +-27 29 28 20 24 24 17 20 20 14 17 17 13 16 16 12 14 14 +-10 13 13 10 12 12 9 11 11 9 11 11 9 11 11 9 11 11 +-9 11 11 9 11 11 9 11 11 9 11 11 9 11 11 9 11 11 +-9 11 11 9 11 11 9 11 11 9 11 11 9 11 11 9 11 11 +-9 11 11 9 12 12 9 12 12 10 12 12 10 12 12 10 12 12 +-10 13 13 10 13 13 10 13 13 11 13 13 11 14 14 11 14 14 +-11 14 14 27 29 28 55 56 53 72 73 67 51 52 50 51 52 50 +-49 51 48 43 45 43 39 40 39 32 34 33 26 28 27 21 22 21 +-19 20 19 16 16 16 18 19 17 13 13 13 12 12 12 12 12 12 +-12 12 12 12 12 12 1 1 1 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 8 8 7 84 83 72 184 179 149 197 193 154 251 251 187 +-251 251 187 251 251 187 251 251 187 251 251 187 184 179 149 145 141 105 +-19 20 19 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 14 14 13 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 72 73 67 105 104 92 84 83 72 +-72 73 67 84 83 72 68 70 65 49 51 48 39 40 39 30 32 31 +-25 27 26 18 22 22 15 18 18 13 16 16 12 15 15 11 13 13 +-10 12 12 9 11 11 9 11 11 9 11 11 9 11 11 9 11 11 +-9 11 11 9 11 11 9 11 11 9 11 11 9 11 11 9 11 11 +-9 11 11 9 11 11 9 11 11 9 11 11 9 11 11 9 11 11 +-9 11 11 9 11 11 9 11 11 9 12 12 9 12 12 9 12 12 +-10 12 12 10 12 12 10 12 12 10 13 13 10 13 13 11 13 13 +-13 16 16 41 42 42 99 98 80 158 153 112 65 66 61 51 52 50 +-49 51 48 43 45 43 39 40 39 31 33 31 25 27 26 21 22 21 +-21 22 21 68 70 65 55 56 53 13 13 13 12 12 12 12 12 12 +-12 12 12 11 11 11 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 3 3 3 +-63 64 60 158 153 112 184 179 149 210 208 158 251 251 187 251 251 187 +-251 251 187 251 251 187 251 251 187 184 179 149 137 133 100 27 29 28 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-21 22 21 110 109 94 5 6 5 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 13 13 13 105 104 92 90 89 73 72 73 67 +-68 70 65 84 83 72 63 64 60 46 47 45 35 37 36 27 29 28 +-22 24 23 17 20 20 14 17 17 12 15 15 11 14 14 10 12 12 +-10 12 12 9 11 11 9 11 11 9 11 11 9 11 11 9 11 11 +-9 11 11 8 10 10 8 10 10 8 10 10 8 10 10 8 10 10 +-8 10 10 9 11 11 9 11 11 9 11 11 9 11 11 9 11 11 +-9 11 11 9 11 11 9 11 11 9 11 11 9 11 11 9 11 11 +-9 12 12 9 12 12 10 12 12 10 12 12 10 13 13 10 13 13 +-30 32 31 47 48 46 177 172 135 210 208 158 137 133 100 55 56 53 +-49 51 48 43 45 43 38 39 37 31 33 31 25 27 26 22 24 23 +-110 109 94 184 179 149 63 64 60 13 13 13 12 12 12 12 12 12 +-12 12 12 8 9 9 0 0 0 1 1 1 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 21 22 21 105 104 92 +-184 179 149 210 208 158 251 251 187 251 251 187 251 251 187 251 251 187 +-251 251 187 251 251 187 184 179 149 145 141 105 23 24 24 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-68 70 65 184 179 149 105 104 92 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 51 52 50 99 98 80 84 83 72 63 64 60 +-68 70 65 72 73 67 55 57 54 41 42 42 32 34 33 25 27 26 +-20 23 23 16 19 19 13 16 16 12 14 14 10 13 13 10 12 12 +-9 11 11 9 11 11 9 11 11 9 11 11 9 11 11 8 10 10 +-8 10 10 8 10 10 8 10 10 8 10 10 8 10 10 8 10 10 +-8 10 10 8 10 10 8 10 10 8 10 10 9 11 11 9 11 11 +-9 11 11 9 11 11 9 11 11 9 11 11 9 11 11 9 11 11 +-9 11 11 9 11 11 9 12 12 9 12 12 10 12 12 17 20 20 +-46 47 45 72 73 67 210 208 158 251 251 187 210 208 158 63 64 60 +-49 51 48 43 45 43 37 39 37 30 32 31 24 26 24 105 104 92 +-210 208 158 197 193 154 47 48 46 13 13 13 12 12 12 12 12 12 +-12 12 12 6 7 7 33 36 34 48 49 45 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 8 8 7 23 24 24 55 56 53 110 109 94 +-210 208 158 251 251 187 251 251 187 251 251 187 251 251 187 251 251 187 +-251 251 187 184 179 149 110 109 94 20 20 20 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-110 109 94 251 251 187 210 208 158 47 48 46 0 0 0 0 0 0 +-0 0 0 1 1 1 90 89 73 90 89 73 72 73 67 55 56 53 +-72 73 67 68 70 65 51 52 50 37 39 37 28 31 30 23 25 24 +-17 21 21 15 18 18 12 15 15 11 14 14 10 13 13 9 12 12 +-9 11 11 9 11 11 9 11 11 8 10 10 8 10 10 8 10 10 +-8 10 10 8 10 10 8 10 10 8 10 10 8 10 10 8 10 10 +-8 10 10 8 10 10 8 10 10 8 10 10 8 10 10 8 10 10 +-8 10 10 9 11 11 9 11 11 9 11 11 9 11 11 9 11 11 +-9 11 11 9 11 11 9 11 11 9 12 12 13 16 16 41 42 42 +-49 51 48 110 109 94 251 251 187 251 251 187 251 251 187 105 104 92 +-49 51 48 43 45 43 35 37 36 30 31 28 47 48 46 197 193 154 +-251 251 187 197 193 154 31 33 31 12 12 12 12 12 12 12 12 12 +-12 12 12 51 52 50 184 179 149 72 73 67 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 2 2 2 +-11 11 11 21 22 21 30 32 31 40 41 39 60 60 56 145 141 105 +-251 251 187 251 251 187 251 251 187 251 251 187 251 251 187 214 212 158 +-184 179 149 110 109 94 13 13 13 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 4 5 4 61 61 53 48 49 45 3 4 3 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-156 151 111 251 251 187 251 251 187 184 179 149 11 11 11 0 0 0 +-0 0 0 26 28 27 99 98 80 84 83 72 60 60 56 43 45 43 +-72 73 67 65 66 61 49 51 48 35 37 36 27 29 28 20 24 24 +-17 20 20 14 17 17 12 15 15 11 13 13 10 12 12 9 11 11 +-9 11 11 9 11 11 8 10 10 8 10 10 8 10 10 8 10 10 +-8 10 10 8 10 10 8 10 10 8 10 10 8 10 10 8 10 10 +-8 10 10 8 10 10 8 10 10 8 10 10 8 10 10 8 10 10 +-8 10 10 8 10 10 8 10 10 8 10 10 9 11 11 9 11 11 +-9 11 11 9 11 11 9 11 11 11 13 13 37 39 37 47 48 46 +-51 52 50 184 179 149 251 251 187 251 251 187 251 251 187 145 141 105 +-47 48 46 41 42 42 35 37 36 27 29 28 137 133 100 251 251 187 +-251 251 187 197 193 154 19 20 19 12 12 12 12 12 12 12 12 12 +-27 29 28 184 179 149 214 212 158 63 64 60 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 1 1 1 6 7 7 16 16 16 24 26 24 +-30 32 31 38 39 37 47 48 46 55 57 54 68 70 65 110 109 94 +-197 193 154 251 251 187 251 251 187 251 251 187 210 208 158 184 179 149 +-105 104 92 8 8 7 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 65 66 61 184 179 149 156 151 111 +-30 32 31 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-168 163 120 251 251 187 251 251 187 251 251 187 110 109 94 0 0 0 +-0 0 0 60 60 56 84 83 72 68 70 65 51 52 50 38 39 37 +-84 83 72 63 64 60 43 45 43 33 36 34 25 27 26 20 23 22 +-15 18 18 13 16 16 12 14 14 10 13 13 9 12 12 9 11 11 +-9 11 11 8 10 10 8 10 10 8 10 10 8 10 10 8 10 10 +-8 10 10 8 10 10 8 10 10 8 10 10 8 10 10 8 10 10 +-8 10 10 8 10 10 8 10 10 8 10 10 8 10 10 8 10 10 +-8 10 10 8 10 10 8 10 10 8 10 10 8 10 10 8 10 10 +-9 11 11 9 11 11 10 12 12 33 36 34 46 47 45 51 52 50 +-72 73 67 210 208 158 251 251 187 251 251 187 251 251 187 177 172 135 +-47 48 46 41 42 42 35 37 36 37 39 37 184 179 149 251 251 187 +-251 251 187 197 193 154 13 13 13 12 12 12 12 12 12 12 12 12 +-110 109 94 251 251 187 251 251 187 37 39 37 0 0 0 0 0 0 +-0 0 0 21 22 20 2 2 1 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-4 5 5 12 12 12 21 22 21 25 27 26 30 32 31 38 39 37 +-46 47 45 55 56 53 60 60 56 65 66 61 68 70 65 105 104 92 +-110 109 94 197 193 154 210 208 158 197 193 154 184 179 149 84 83 72 +-2 2 2 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 13 13 13 184 179 149 251 251 187 +-197 193 154 43 44 41 0 0 0 0 0 0 0 0 0 0 0 0 +-145 141 105 251 251 187 251 251 187 251 251 187 214 212 158 43 45 43 +-2 2 2 84 83 72 72 73 67 58 59 55 41 42 42 38 39 37 +-72 73 67 58 59 55 41 42 42 31 33 31 25 27 26 18 22 22 +-14 17 17 12 15 15 12 14 14 10 12 12 9 12 12 9 11 11 +-9 11 11 8 10 10 8 10 10 8 10 10 8 10 10 8 10 10 +-8 10 10 8 10 10 8 10 10 8 10 10 8 10 10 8 10 10 +-8 10 10 8 10 10 8 10 10 8 10 10 8 10 10 8 10 10 +-8 10 10 8 10 10 8 10 10 8 10 10 8 10 10 8 10 10 +-8 10 10 9 12 12 31 33 31 43 45 43 49 51 48 55 56 53 +-110 109 94 251 251 187 251 251 187 251 251 187 251 251 187 168 163 120 +-47 48 46 41 42 42 33 36 34 63 64 60 197 193 154 251 251 187 +-251 251 187 184 179 149 13 13 13 12 12 12 12 12 12 16 16 16 +-197 193 154 251 251 187 239 239 170 20 20 20 0 0 0 2 2 1 +-108 107 93 110 109 94 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 1 1 1 4 5 5 11 11 11 18 19 18 +-22 24 23 26 28 27 32 34 33 39 40 39 46 47 45 51 52 50 +-55 57 54 60 60 56 63 64 60 63 64 60 63 64 60 58 59 55 +-63 64 60 99 98 80 145 141 105 137 133 100 43 45 43 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 +-0 0 0 0 0 0 0 0 0 3 4 3 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 110 109 94 251 251 187 +-251 251 187 184 179 149 25 27 26 0 0 0 0 0 0 0 0 0 +-99 98 80 251 251 187 251 251 187 251 251 187 251 251 187 156 151 111 +-25 27 26 84 83 72 65 66 61 47 48 46 32 34 33 39 40 39 +-72 73 67 55 57 54 40 41 39 30 32 31 23 25 24 18 22 22 +-14 17 17 12 15 15 11 13 13 10 12 12 9 11 11 9 11 11 +-9 11 11 8 10 10 8 10 10 8 10 10 8 10 10 8 10 10 +-8 10 10 8 10 10 8 10 10 8 10 10 8 10 10 8 10 10 +-8 10 10 8 10 10 8 10 10 8 10 10 8 10 10 8 10 10 +-8 10 10 8 10 10 8 10 10 8 10 10 8 10 10 8 10 10 +-9 11 11 28 31 30 41 42 42 47 48 46 55 56 53 58 59 55 +-137 133 100 251 251 187 251 251 187 251 251 187 210 208 158 137 133 100 +-47 48 46 40 41 39 32 34 33 75 75 61 184 179 149 239 239 170 +-251 251 187 177 172 135 13 13 13 12 12 12 12 12 12 43 44 41 +-197 193 154 251 251 187 210 208 158 10 10 9 0 0 0 84 83 72 +-251 251 187 84 83 72 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 1 +-6 7 7 11 11 11 17 17 17 20 20 20 23 24 24 27 29 28 +-32 34 33 38 39 37 43 45 43 47 48 46 51 52 50 55 56 53 +-58 59 55 58 59 55 55 57 54 55 56 53 47 48 46 41 42 42 +-35 37 36 31 33 31 47 48 46 14 14 13 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 +-0 0 0 0 0 0 0 0 0 66 65 55 99 98 80 20 20 20 +-0 0 0 0 0 0 0 0 0 0 0 0 43 45 43 214 212 158 +-251 251 187 251 251 187 145 141 105 3 3 3 0 0 0 0 0 0 +-48 49 45 184 179 149 239 239 170 251 251 187 239 239 170 177 172 135 +-84 83 72 72 73 67 55 56 53 39 40 39 26 28 27 39 40 39 +-68 70 65 51 52 50 39 40 39 28 31 30 22 24 23 17 20 20 +-14 17 17 12 14 14 10 13 13 9 11 11 9 11 11 9 11 11 +-8 10 10 8 10 10 8 10 10 8 10 10 8 10 10 8 10 10 +-8 10 10 8 10 10 8 10 10 8 10 10 8 10 10 8 10 10 +-8 10 10 8 10 10 8 10 10 8 10 10 8 10 10 8 10 10 +-8 10 10 8 10 10 8 10 10 8 10 10 8 10 10 8 10 10 +-27 29 28 40 41 39 46 47 45 51 52 50 55 57 54 63 64 60 +-131 127 93 197 193 154 210 208 158 197 193 154 168 163 120 96 95 69 +-47 48 46 40 41 39 32 34 33 71 71 57 145 141 105 184 179 149 +-184 179 149 131 127 93 13 13 13 12 12 12 12 12 12 48 49 45 +-168 163 120 184 179 149 156 151 111 6 7 7 14 14 13 177 172 135 +-239 239 170 40 41 39 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 3 3 3 6 7 7 11 11 11 16 16 16 +-18 19 18 21 22 21 23 24 24 27 29 28 32 34 33 37 39 37 +-41 42 42 43 45 43 47 48 46 51 52 50 51 52 50 51 52 50 +-51 52 50 49 51 48 46 47 45 40 41 39 32 34 33 25 27 26 +-20 20 20 14 14 13 2 2 2 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 +-0 0 0 0 0 0 0 0 0 33 36 34 197 193 154 184 179 149 +-41 42 42 0 0 0 0 0 0 0 0 0 3 3 3 184 179 149 +-251 251 187 251 251 187 184 179 149 48 49 45 0 0 0 0 0 0 +-16 17 12 121 119 87 177 172 135 194 189 146 188 184 146 145 141 105 +-82 81 62 63 64 60 46 47 45 31 33 31 21 22 21 35 37 36 +-68 70 65 51 52 50 37 39 37 27 30 29 22 24 23 17 20 20 +-13 16 16 12 14 14 10 13 13 9 11 11 8 10 10 8 10 10 +-8 10 10 8 10 10 8 10 10 8 10 10 8 10 10 8 10 10 +-8 10 10 8 10 10 8 10 10 8 10 10 8 10 10 8 10 10 +-8 10 10 8 10 10 8 10 10 8 10 10 8 10 10 8 10 10 +-8 10 10 8 10 10 8 10 10 8 10 10 8 10 10 25 27 26 +-38 39 37 43 45 43 51 52 50 55 56 53 60 60 56 63 64 60 +-92 91 72 158 153 112 176 171 126 171 165 117 149 143 98 82 81 62 +-44 46 43 38 39 37 30 32 31 71 71 57 131 127 93 160 154 106 +-149 143 98 82 81 62 13 13 13 12 12 12 12 12 12 46 47 43 +-121 119 87 134 131 96 96 95 69 7 7 6 38 39 37 131 127 93 +-145 141 105 12 13 12 0 0 0 1 1 1 3 3 3 6 7 7 +-10 10 9 12 12 12 14 14 13 16 16 16 18 19 18 21 22 21 +-22 24 23 26 28 27 30 31 28 33 36 34 37 39 37 40 41 39 +-41 42 42 43 45 43 46 47 45 46 47 45 46 47 45 43 45 43 +-41 42 42 37 39 37 31 33 31 26 28 27 21 22 21 16 16 16 +-6 7 7 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 177 172 135 251 251 187 +-197 193 154 27 29 28 0 0 0 0 0 0 0 0 0 110 109 94 +-239 239 170 239 239 170 184 179 149 87 86 72 2 2 1 0 0 0 +-1 1 1 82 81 62 142 137 94 165 161 109 165 161 109 131 127 93 +-75 75 61 55 56 53 37 39 37 25 27 26 19 20 19 32 34 33 +-65 66 61 49 51 48 35 37 36 27 29 28 20 23 23 16 19 19 +-13 16 16 13 13 13 10 12 12 9 11 11 8 10 10 8 10 10 +-8 9 9 8 10 10 8 10 10 8 10 10 8 10 10 8 10 10 +-8 10 10 8 10 10 8 10 10 8 10 10 8 10 10 8 10 10 +-8 10 10 8 10 10 8 10 10 8 10 10 8 10 10 8 10 10 +-8 10 10 8 10 10 8 10 10 8 10 10 22 24 23 35 37 36 +-41 42 42 47 48 46 55 56 53 58 59 55 63 64 60 65 66 61 +-71 71 57 131 127 93 160 154 106 160 154 106 142 137 94 82 81 62 +-46 47 43 40 41 39 33 36 34 66 65 55 125 122 87 149 143 98 +-142 137 94 82 81 62 17 17 17 18 19 17 14 14 13 46 47 43 +-118 116 76 125 122 87 96 95 69 16 17 12 71 71 57 103 101 77 +-82 81 62 11 11 11 11 11 11 13 13 13 14 14 13 14 14 13 +-15 15 15 16 16 16 17 17 17 19 20 19 21 22 21 23 24 24 +-26 28 27 27 29 28 31 33 31 33 36 34 35 37 36 38 39 37 +-39 40 39 39 40 39 38 39 37 37 39 37 35 37 36 31 33 31 +-27 29 28 24 26 24 21 22 21 17 17 17 12 12 12 2 2 2 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 68 70 65 251 251 187 +-251 251 187 156 151 111 2 2 1 0 0 0 0 0 0 43 44 41 +-177 172 135 184 179 149 158 153 112 103 101 77 19 20 18 0 0 0 +-0 0 0 46 47 43 131 127 93 160 154 106 160 154 106 131 127 93 +-71 71 57 43 45 43 30 32 31 21 22 21 16 16 16 26 28 27 +-63 64 60 47 48 46 35 37 36 26 28 27 20 23 23 16 19 19 +-13 16 16 13 13 13 10 12 12 9 11 11 8 10 10 8 10 10 +-7 9 9 7 9 9 8 9 9 8 10 10 8 10 10 8 10 10 +-8 10 10 8 10 10 8 10 10 8 10 10 8 10 10 8 10 10 +-8 10 10 8 10 10 8 10 10 8 10 10 8 10 10 8 10 10 +-8 10 10 8 10 10 8 10 10 20 20 20 33 36 34 40 41 39 +-46 47 45 51 52 50 55 57 54 60 60 56 63 64 60 65 66 61 +-66 65 55 118 116 76 151 147 98 165 161 109 151 147 98 121 119 87 +-96 95 69 96 95 69 96 95 69 103 101 77 142 137 94 151 147 98 +-142 137 94 103 101 77 82 81 62 82 81 62 82 81 62 96 95 69 +-131 127 93 142 137 94 103 101 77 46 47 43 96 95 69 118 116 76 +-71 71 57 14 14 13 14 14 13 15 15 15 15 15 15 16 16 16 +-16 16 16 17 17 17 18 19 18 20 20 20 21 22 21 23 24 24 +-25 27 26 27 29 28 30 31 28 30 32 31 31 33 31 31 33 31 +-31 33 31 31 33 31 30 31 28 27 29 28 25 27 26 22 24 23 +-20 20 20 16 16 16 13 13 13 6 7 7 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 +-58 59 55 68 70 65 8 8 7 0 0 0 10 10 9 210 208 158 +-251 251 187 184 179 149 38 39 37 0 0 0 0 0 0 8 8 7 +-103 101 77 149 143 98 149 143 98 118 116 76 40 41 39 25 27 25 +-53 55 47 82 81 62 144 139 99 165 161 109 165 161 109 142 137 94 +-71 71 57 35 37 36 24 26 24 18 19 18 15 15 15 22 24 23 +-63 64 60 46 47 45 33 36 34 26 28 27 20 23 22 17 18 17 +-12 15 15 11 13 13 10 12 12 9 11 11 8 10 10 8 10 10 +-7 9 9 7 9 9 7 9 9 7 9 9 8 9 9 8 10 10 +-8 10 10 8 10 10 8 10 10 8 10 10 8 10 10 8 10 10 +-8 10 10 8 10 10 8 10 10 8 10 10 8 10 10 8 10 10 +-8 10 10 8 10 10 16 16 16 30 31 28 35 37 36 41 42 42 +-47 48 46 55 56 53 58 59 55 63 64 60 65 66 61 65 66 61 +-61 61 53 103 101 77 151 147 98 171 165 117 171 165 117 168 163 120 +-158 153 112 158 153 112 155 149 109 151 147 98 151 147 98 160 154 106 +-151 147 98 149 143 98 142 137 94 149 143 98 149 143 98 149 143 98 +-155 149 109 151 147 98 131 127 93 103 101 77 125 122 87 118 116 76 +-71 71 57 16 16 16 16 16 16 16 16 16 17 17 17 17 17 17 +-17 17 17 17 17 17 18 19 18 19 20 19 20 20 20 21 22 21 +-23 24 24 24 26 24 25 27 26 26 28 27 26 28 27 26 28 27 +-25 27 26 24 26 24 22 24 23 21 22 21 19 20 19 16 16 16 +-14 14 13 8 8 7 1 1 1 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 +-20 20 20 184 179 149 168 163 120 21 22 21 0 0 0 105 104 92 +-177 172 135 145 141 105 71 71 57 0 0 0 0 0 0 0 0 0 +-66 65 55 131 127 93 151 147 98 142 137 94 118 116 76 121 119 87 +-145 141 105 158 153 112 176 171 126 178 174 128 176 171 126 149 145 103 +-96 95 69 31 33 31 21 22 21 16 16 16 14 14 13 18 19 18 +-60 60 56 46 47 45 33 36 34 25 27 26 21 22 21 15 18 18 +-12 15 15 11 13 13 9 11 11 8 10 10 8 10 10 8 9 9 +-7 9 9 7 9 9 7 9 9 7 9 9 7 9 9 8 9 9 +-8 9 9 8 10 10 8 10 10 8 10 10 8 10 10 8 10 10 +-8 10 10 8 10 10 8 10 10 8 10 10 8 10 10 8 10 10 +-8 10 10 10 12 12 26 28 27 31 33 31 38 39 37 43 45 43 +-51 52 50 55 56 53 60 60 56 63 64 60 65 66 61 68 70 65 +-63 64 60 96 95 69 158 153 112 178 174 128 188 184 146 194 189 146 +-194 189 146 188 184 146 184 181 136 176 171 126 171 165 117 173 167 111 +-173 167 111 165 161 109 171 165 117 174 170 121 176 171 126 178 174 128 +-178 174 128 174 170 121 160 154 106 149 143 98 149 143 98 125 122 87 +-71 71 57 16 16 16 16 16 16 17 17 17 17 17 17 17 17 17 +-17 17 17 17 17 17 17 17 17 18 19 18 19 20 19 20 20 20 +-21 22 21 21 22 21 21 22 21 22 24 23 21 22 21 21 22 21 +-21 22 21 19 20 19 18 19 18 16 16 16 14 14 13 11 11 11 +-3 3 3 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 +-0 0 0 105 104 92 197 193 154 110 109 94 9 9 8 36 38 35 +-121 119 87 131 127 93 96 95 69 18 19 17 30 31 28 66 65 55 +-96 95 69 142 137 94 160 154 106 160 154 106 160 154 106 168 163 120 +-184 181 136 194 191 148 197 193 154 197 193 154 194 189 146 168 163 120 +-125 122 87 46 47 43 18 19 18 15 15 15 13 13 13 14 14 13 +-55 57 54 43 45 43 32 34 33 25 27 26 18 22 22 17 17 17 +-12 14 14 10 12 12 9 11 11 8 10 10 8 9 9 7 9 9 +-6 8 8 7 9 9 7 9 9 7 9 9 7 9 9 7 9 9 +-7 9 9 8 9 9 8 9 9 8 10 10 8 10 10 8 10 10 +-8 10 10 8 10 10 8 10 10 8 10 10 8 10 10 8 10 10 +-8 10 10 32 34 33 41 42 42 35 37 36 39 40 39 37 39 37 +-35 37 36 55 57 54 60 60 56 63 64 60 65 66 61 65 66 61 +-61 63 57 115 113 82 168 163 120 194 191 148 204 201 155 210 208 158 +-210 208 158 210 208 158 197 193 154 194 189 146 186 182 128 176 171 126 +-174 170 121 176 171 126 186 182 128 190 186 136 194 191 148 197 193 154 +-197 193 154 188 184 146 181 176 137 174 170 121 165 161 109 142 137 94 +-82 81 62 24 26 24 16 16 16 16 16 16 16 16 16 16 16 16 +-17 17 17 17 17 17 17 17 17 17 17 17 18 19 18 19 20 19 +-19 20 19 19 20 19 20 20 20 19 20 19 19 20 19 18 19 18 +-17 17 17 15 15 15 13 13 13 12 12 12 6 7 7 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 +-0 0 0 17 18 17 137 133 100 115 113 82 53 55 47 19 20 18 +-103 101 77 144 139 99 137 133 100 115 113 82 137 133 100 156 151 111 +-158 153 112 164 159 111 171 165 117 174 170 121 178 174 128 194 189 146 +-204 201 155 214 212 158 214 212 158 214 212 158 210 208 158 188 184 146 +-158 153 112 87 86 72 17 17 17 13 13 13 13 13 13 15 15 15 +-55 56 53 43 45 43 32 34 33 24 26 24 17 20 20 16 16 16 +-12 14 14 10 12 12 8 10 10 8 10 10 7 9 9 6 8 8 +-6 8 8 6 8 8 6 8 8 7 9 9 7 9 9 7 9 9 +-7 9 9 7 9 9 7 9 9 7 9 9 8 9 9 8 10 10 +-8 10 10 8 10 10 8 10 10 8 10 10 8 10 10 8 10 10 +-8 10 10 110 109 94 84 83 72 49 51 48 26 28 27 8 10 10 +-8 9 9 51 52 50 58 59 55 63 64 60 63 64 60 63 64 60 +-66 65 55 134 131 96 181 176 137 210 208 158 214 212 158 239 239 170 +-239 239 170 224 223 159 210 208 158 204 201 155 194 189 146 186 182 128 +-186 182 128 184 181 136 194 189 146 204 201 155 210 208 158 210 208 158 +-210 208 158 210 208 158 197 193 154 190 186 136 176 171 126 155 149 109 +-118 116 76 36 38 35 15 15 15 16 16 16 16 16 16 16 16 16 +-16 16 16 16 16 16 16 16 16 16 16 16 16 16 16 17 17 17 +-17 17 17 17 17 17 17 17 17 16 16 16 16 16 16 15 15 15 +-13 13 13 12 12 12 8 8 7 2 2 2 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 +-0 0 0 0 0 0 53 55 47 103 101 77 96 95 69 53 55 47 +-103 101 77 158 153 112 177 172 135 184 179 149 188 184 146 197 193 154 +-194 189 146 190 186 136 184 181 136 184 181 136 194 189 146 210 208 158 +-214 212 158 239 239 170 251 251 187 251 251 187 224 223 159 204 201 155 +-177 172 135 121 119 87 30 31 28 13 13 13 12 12 12 39 40 39 +-60 60 56 43 45 43 32 34 33 23 25 24 18 19 18 13 16 16 +-13 13 13 9 11 11 8 10 10 8 9 9 6 8 8 6 8 8 +-6 8 8 6 8 8 6 8 8 6 8 8 6 8 8 7 9 9 +-7 9 9 7 9 9 7 9 9 7 9 9 7 9 9 7 9 9 +-7 9 9 8 9 9 8 9 9 8 10 10 8 10 10 8 10 10 +-14 17 17 197 193 154 158 153 112 55 57 54 7 9 9 7 9 9 +-8 10 10 51 52 50 58 59 55 60 60 56 63 64 60 63 64 60 +-71 71 57 155 149 109 194 191 148 214 212 158 251 251 187 251 251 187 +-251 251 187 251 251 187 239 239 170 210 208 158 197 193 154 190 186 136 +-190 186 136 194 189 146 204 201 155 210 208 158 224 223 159 239 239 170 +-239 239 170 224 223 159 210 208 158 204 201 155 190 186 136 164 159 111 +-125 122 87 40 41 39 15 15 15 15 15 15 15 15 15 15 15 15 +-16 16 16 16 16 16 16 16 16 16 16 16 16 16 16 16 16 16 +-16 16 16 16 16 16 15 15 15 14 14 13 13 13 13 12 12 12 +-8 9 9 3 3 3 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 +-0 0 0 0 0 0 21 22 20 96 95 69 125 122 87 121 119 87 +-144 139 99 177 172 135 197 193 154 210 208 158 214 212 158 214 212 158 +-210 208 158 204 201 155 194 191 148 194 189 146 204 201 155 214 212 158 +-239 239 170 251 251 187 251 251 187 251 251 187 251 251 187 214 212 158 +-188 184 146 145 141 105 53 55 47 12 12 12 15 15 15 63 64 60 +-63 64 60 41 42 42 31 33 31 23 24 24 17 18 17 12 15 15 +-11 13 13 9 11 11 8 9 9 7 9 9 6 8 8 6 8 8 +-6 7 7 6 7 7 6 8 8 6 8 8 6 8 8 6 8 8 +-6 8 8 7 9 9 7 9 9 7 9 9 7 9 9 7 9 9 +-7 9 9 7 9 9 7 9 9 7 9 9 7 9 9 8 8 7 +-43 45 43 251 251 187 156 151 111 8 10 10 7 9 9 7 9 9 +-21 22 21 51 52 50 55 56 53 55 57 54 58 59 55 58 59 55 +-75 75 61 158 153 112 197 193 154 224 223 159 251 251 187 251 251 187 +-251 251 187 251 251 187 251 251 187 214 212 158 204 201 155 194 189 146 +-190 186 136 197 193 154 210 208 158 224 223 159 251 251 187 251 251 187 +-251 251 187 251 251 187 239 239 170 210 208 158 197 193 154 176 171 126 +-125 122 87 36 38 35 14 14 13 14 14 13 15 15 15 15 15 15 +-15 15 15 15 15 15 15 15 15 15 15 15 15 15 15 15 15 15 +-15 15 15 14 14 13 13 13 13 12 12 12 10 10 9 3 4 4 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 +-0 0 0 0 0 0 7 7 5 71 71 57 131 127 93 158 153 112 +-177 172 135 197 193 154 214 212 158 239 239 170 251 251 187 251 251 187 +-238 237 168 210 208 158 204 201 155 197 193 154 204 201 155 214 212 158 +-251 251 187 251 251 187 251 251 187 251 251 187 251 251 187 214 212 158 +-197 193 154 156 151 111 66 65 55 12 12 12 37 39 37 58 59 55 +-58 59 55 41 42 42 31 33 31 22 24 23 17 17 17 12 14 14 +-10 12 12 8 10 10 6 8 8 6 8 8 6 7 7 6 7 7 +-6 7 7 5 7 7 6 7 7 6 7 7 6 8 8 6 8 8 +-6 8 8 6 8 8 6 8 8 7 9 9 7 9 9 7 9 9 +-7 9 9 6 8 8 6 8 8 6 8 8 6 8 8 6 8 8 +-61 63 57 197 193 154 16 19 19 6 8 8 6 8 8 8 9 9 +-41 42 42 47 48 46 51 52 50 51 52 50 55 56 53 55 56 53 +-71 71 57 158 153 112 197 193 154 224 223 159 251 251 187 251 251 187 +-251 251 187 251 251 187 239 239 170 214 212 158 204 201 155 194 189 146 +-190 186 136 197 193 154 210 208 158 239 239 170 251 251 187 251 251 187 +-251 251 187 251 251 187 251 251 187 224 223 159 204 201 155 177 172 135 +-121 119 87 30 31 28 13 13 13 14 14 13 14 14 13 14 14 13 +-14 14 13 14 14 13 15 15 15 15 15 15 14 14 13 13 13 13 +-12 12 12 12 12 12 10 10 9 4 5 5 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 +-0 0 0 0 0 0 0 0 0 48 49 45 131 127 93 174 170 121 +-194 189 146 210 208 158 239 239 170 251 251 187 251 251 187 251 251 187 +-251 251 187 214 212 158 204 201 155 197 193 154 204 201 155 210 208 158 +-239 239 170 251 251 187 251 251 187 251 251 187 239 239 170 214 212 158 +-194 191 148 156 151 111 71 71 57 19 20 19 51 52 50 51 52 50 +-51 52 50 41 42 42 30 32 31 21 22 21 17 17 17 13 13 13 +-9 11 11 8 9 9 6 8 8 6 7 7 6 7 7 5 7 7 +-5 6 5 5 6 5 5 7 7 5 7 7 6 7 7 6 7 7 +-6 8 8 6 8 8 6 8 8 6 7 7 6 7 7 6 7 7 +-6 7 7 6 8 8 6 8 8 6 8 8 6 8 8 6 8 8 +-55 56 53 43 45 43 6 8 8 6 8 8 6 8 8 47 48 46 +-60 60 56 47 48 46 46 47 45 47 48 46 38 39 37 10 12 12 +-66 65 55 145 141 105 197 193 154 214 212 158 251 251 187 251 251 187 +-251 251 187 251 251 187 224 223 159 210 208 158 194 191 148 184 181 136 +-184 181 136 194 189 146 204 201 155 224 223 159 251 251 187 251 251 187 +-251 251 187 251 251 187 251 251 187 239 239 170 210 208 158 181 176 137 +-115 113 82 21 22 20 13 13 13 13 13 13 13 13 13 13 13 13 +-14 14 13 13 13 13 13 13 13 13 13 13 12 12 12 11 11 11 +-10 10 9 6 7 7 1 1 1 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 +-0 0 0 0 0 0 2 2 1 66 65 55 144 139 99 178 174 128 +-204 201 155 214 212 158 251 251 187 251 251 187 251 251 187 251 251 187 +-251 251 187 214 212 158 204 201 155 194 191 148 197 193 154 204 201 155 +-214 212 158 239 239 170 239 239 170 239 239 170 214 212 158 210 208 158 +-184 181 136 149 145 103 66 65 55 41 42 42 47 48 46 46 47 45 +-43 45 43 39 40 39 28 31 30 21 22 21 16 16 16 10 12 12 +-8 10 10 6 8 8 6 7 7 6 7 7 5 6 5 5 6 5 +-5 6 5 5 6 5 5 6 5 5 6 5 5 7 7 5 7 7 +-6 7 7 6 7 7 6 7 7 5 7 7 5 7 7 5 7 7 +-5 7 7 6 7 7 6 7 7 6 7 7 6 7 7 6 8 8 +-6 8 8 6 8 8 6 7 7 6 7 7 46 47 45 156 151 111 +-105 104 92 58 59 55 43 45 43 32 34 33 6 8 8 6 8 8 +-49 51 48 125 122 87 181 176 137 204 201 155 214 212 158 239 239 170 +-239 239 170 214 212 158 210 208 158 197 193 154 181 176 137 176 171 126 +-176 171 126 184 181 136 197 193 154 210 208 158 239 239 170 251 251 187 +-251 251 187 251 251 187 251 251 187 251 251 187 210 208 158 177 172 135 +-99 98 80 13 13 13 12 12 12 12 12 12 13 13 13 12 12 12 +-12 12 12 12 12 12 11 11 11 11 11 11 8 9 9 4 5 5 +-1 1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 +-0 0 0 0 0 0 1 1 0 61 61 53 142 137 94 181 176 137 +-204 201 155 224 223 159 251 251 187 251 251 187 251 251 187 251 251 187 +-251 251 187 214 212 158 197 193 154 190 186 136 184 181 136 188 184 146 +-197 193 154 204 201 155 210 208 158 210 208 158 204 201 155 194 189 146 +-176 171 126 134 131 96 66 65 55 43 45 43 41 42 42 39 40 39 +-35 37 36 33 36 34 27 29 28 20 20 20 15 15 15 9 11 11 +-8 9 9 6 7 7 5 6 5 5 6 5 4 5 5 4 5 5 +-4 5 5 4 5 5 4 5 5 4 5 5 5 6 5 4 5 5 +-4 5 5 5 6 5 4 5 5 5 6 5 5 6 5 5 6 5 +-5 7 7 5 7 7 5 7 7 5 7 7 5 7 7 5 7 7 +-6 7 7 6 7 7 6 7 7 28 31 30 184 179 149 184 179 149 +-145 141 105 84 83 72 27 29 28 5 7 7 5 6 5 16 16 16 +-43 44 41 96 95 69 158 153 112 188 184 146 204 201 155 210 208 158 +-204 201 155 197 193 154 184 179 149 177 172 135 168 163 120 164 159 111 +-164 159 111 174 170 121 184 181 136 197 193 154 214 212 158 251 251 187 +-251 251 187 251 251 187 251 251 187 251 251 187 210 208 158 177 172 135 +-71 71 57 11 11 11 12 12 12 11 11 11 11 11 11 11 11 11 +-10 10 9 10 10 9 8 8 7 3 4 4 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 +-0 0 0 0 0 0 0 0 0 31 33 31 121 119 87 176 171 126 +-197 193 154 214 212 158 251 251 187 251 251 187 251 251 187 251 251 187 +-239 239 170 210 208 158 194 189 146 178 174 128 174 170 121 176 171 126 +-177 172 135 181 176 137 184 179 149 184 179 149 181 176 137 178 174 128 +-158 153 112 121 119 87 53 55 47 37 39 37 33 36 34 30 32 31 +-27 29 28 25 27 26 24 26 24 19 20 19 13 13 13 8 10 10 +-6 8 8 6 7 7 5 6 5 4 5 5 4 5 5 4 5 5 +-4 5 5 4 5 5 4 5 5 3 4 4 3 4 4 4 5 5 +-4 5 5 4 5 5 4 5 5 4 5 5 4 5 5 4 5 5 +-5 6 5 5 6 5 5 6 5 5 6 5 5 6 5 5 6 5 +-5 6 5 5 6 5 12 14 14 145 141 105 184 179 149 177 172 135 +-90 89 73 21 22 21 5 6 5 5 6 5 4 5 5 37 39 37 +-38 39 37 61 61 53 134 131 96 168 163 120 184 181 136 188 184 146 +-184 179 149 177 172 135 168 163 120 164 159 111 155 149 109 151 147 98 +-151 147 98 164 159 111 176 171 126 184 179 149 210 208 158 239 239 170 +-251 251 187 251 251 187 251 251 187 239 239 170 210 208 158 158 153 112 +-46 47 43 10 10 9 10 10 9 10 10 9 8 9 9 8 9 9 +-6 7 7 3 3 3 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 +-0 0 0 0 0 0 0 0 0 13 12 7 82 81 62 158 153 112 +-188 184 146 210 208 158 239 239 170 251 251 187 251 251 187 251 251 187 +-224 223 159 204 201 155 184 181 136 171 165 117 164 159 111 160 154 106 +-158 153 112 164 159 111 168 163 120 168 163 120 168 163 120 164 159 111 +-142 137 94 96 95 69 43 44 41 27 29 28 26 28 27 23 24 24 +-21 22 21 18 19 18 17 17 17 18 19 18 13 13 13 8 8 7 +-6 7 7 5 6 5 4 5 5 3 4 4 3 4 4 3 4 4 +-3 4 4 3 4 4 3 3 3 3 3 3 3 4 4 3 4 4 +-3 4 4 3 4 4 4 5 5 4 5 5 4 5 5 4 5 5 +-4 5 5 4 5 5 4 5 5 4 5 5 4 5 5 4 5 5 +-4 5 5 4 5 5 4 5 5 4 5 5 4 5 5 4 5 5 +-4 5 5 4 5 5 4 5 5 4 5 5 31 33 31 65 66 61 +-37 39 37 38 39 37 96 95 69 144 139 99 168 163 120 174 170 121 +-168 163 120 164 159 111 155 149 109 149 145 103 149 143 98 142 137 94 +-149 143 98 151 147 98 164 159 111 177 172 135 197 193 154 210 208 158 +-251 251 187 251 251 187 251 251 187 239 239 170 197 193 154 137 133 100 +-24 26 24 8 9 9 8 9 9 8 8 7 6 7 7 2 2 2 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 46 47 43 125 122 87 +-176 171 126 197 193 154 210 208 158 239 239 170 251 251 187 239 239 170 +-214 212 158 197 193 154 181 176 137 164 159 111 151 147 98 149 143 98 +-149 143 98 149 143 98 149 145 103 155 149 109 160 154 106 149 143 98 +-118 116 76 82 81 62 30 31 28 21 22 21 19 20 19 17 17 17 +-14 14 13 12 12 12 10 10 9 12 12 12 10 12 12 6 8 8 +-4 5 5 3 4 4 3 4 4 3 4 4 3 3 3 3 3 3 +-3 3 3 3 3 3 3 3 3 3 3 3 2 3 3 2 3 3 +-3 4 4 3 4 4 3 4 4 3 4 4 3 4 4 4 5 5 +-4 5 5 3 4 4 3 4 4 3 4 4 3 4 4 3 4 4 +-4 5 5 4 5 5 4 5 5 4 5 5 4 5 5 4 5 5 +-4 5 5 3 4 4 3 4 4 23 24 24 110 109 94 72 73 67 +-39 40 39 22 24 23 46 47 43 103 101 77 142 137 94 155 149 109 +-160 154 106 155 149 109 149 143 98 142 137 94 142 137 94 142 137 94 +-142 137 94 149 143 98 155 149 109 176 171 126 184 179 149 210 208 158 +-239 239 170 251 251 187 251 251 187 214 212 158 184 179 149 105 104 92 +-10 10 9 6 7 7 3 4 4 1 1 1 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 12 12 9 82 81 62 +-149 145 103 181 176 137 197 193 154 210 208 158 214 212 158 214 212 158 +-210 208 158 197 193 154 177 172 135 158 153 112 149 143 98 142 137 94 +-142 137 94 142 137 94 149 143 98 151 147 98 151 147 98 131 127 93 +-103 101 77 71 71 57 22 24 23 15 15 15 13 13 13 11 11 11 +-8 9 9 6 7 7 6 7 7 4 5 5 8 9 9 6 7 7 +-4 5 5 3 3 3 3 3 3 3 3 3 3 3 3 2 2 2 +-2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 3 3 +-2 3 3 2 3 3 2 3 3 3 4 4 3 4 4 3 4 4 +-3 4 4 3 4 4 3 3 3 3 4 4 3 4 4 3 4 4 +-3 4 4 3 4 4 3 4 4 3 4 4 3 4 4 3 4 4 +-3 4 4 3 4 4 21 22 21 145 141 105 145 141 105 72 73 67 +-17 18 17 3 4 4 21 22 20 66 65 55 118 116 76 142 137 94 +-149 143 98 151 147 98 149 143 98 142 137 94 142 137 94 142 137 94 +-142 137 94 149 143 98 155 149 109 168 163 120 184 179 149 210 208 158 +-239 239 170 251 251 187 251 251 187 210 208 158 177 172 135 71 71 57 +-3 3 3 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 36 38 35 +-115 113 82 158 153 112 181 176 137 197 193 154 204 201 155 210 208 158 +-204 201 155 188 184 146 177 172 135 164 159 111 149 145 103 142 137 94 +-142 137 94 142 137 94 149 143 98 151 147 98 149 143 98 125 122 87 +-96 95 69 61 61 53 16 17 12 8 9 9 8 8 7 6 7 7 +-4 5 5 3 4 4 3 3 3 3 3 3 3 3 3 5 6 5 +-3 4 4 2 3 3 2 2 2 2 2 2 2 2 2 2 2 2 +-2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 1 2 2 +-2 2 2 2 2 2 2 3 3 2 3 3 2 3 3 2 3 3 +-3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 +-3 3 3 2 3 3 2 3 3 3 4 4 3 4 4 3 4 4 +-3 4 4 3 4 4 3 4 4 8 9 9 8 8 7 3 3 3 +-3 3 3 3 3 3 9 9 8 36 38 35 82 81 62 118 116 76 +-142 137 94 151 147 98 151 147 98 151 147 98 149 143 98 149 143 98 +-149 143 98 151 147 98 160 154 106 176 171 126 188 184 146 210 208 158 +-239 239 170 251 251 187 239 239 170 210 208 158 156 151 111 31 33 31 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 7 7 5 +-66 65 55 125 122 87 158 153 112 181 176 137 194 189 146 197 193 154 +-197 193 154 184 179 149 177 172 135 168 163 120 156 151 111 151 147 98 +-151 147 98 151 147 98 151 147 98 161 156 96 149 143 98 118 116 76 +-82 81 62 53 55 47 12 12 9 4 5 5 3 4 4 3 3 3 +-3 3 3 3 3 3 2 2 2 2 2 2 1 1 1 1 2 2 +-3 3 3 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 +-1 1 1 1 1 1 1 1 1 1 1 1 1 2 2 1 2 2 +-1 2 2 1 2 2 1 2 2 2 2 2 2 2 2 2 3 3 +-2 3 3 2 3 3 2 3 3 2 3 3 2 2 2 2 2 2 +-2 3 3 2 3 3 2 3 3 2 3 3 2 3 3 2 3 3 +-2 3 3 2 3 3 2 3 3 2 3 3 2 3 3 3 3 3 +-3 3 3 3 3 3 72 73 67 61 61 53 53 55 47 96 95 69 +-131 127 93 151 147 98 161 156 96 161 156 96 151 147 98 151 147 98 +-161 156 96 160 154 106 164 159 111 177 172 135 197 193 154 210 208 158 +-239 239 170 251 251 187 224 223 159 197 193 154 131 127 93 9 9 8 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-24 26 24 82 81 62 131 127 93 164 159 111 178 174 128 188 184 146 +-188 184 146 188 184 146 181 176 137 176 171 126 168 163 120 164 159 111 +-160 154 106 160 154 106 160 154 106 160 154 106 151 147 98 125 122 87 +-82 81 62 61 61 53 12 12 9 3 3 3 3 3 3 2 2 2 +-2 2 2 1 1 1 1 1 1 1 1 1 0 0 0 0 0 0 +-0 0 0 2 2 2 1 1 1 1 1 1 1 1 1 1 1 1 +-1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 +-1 1 1 1 1 1 1 2 2 1 2 2 1 2 2 1 2 2 +-1 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 +-2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 +-2 3 3 2 3 3 2 3 3 2 3 3 2 3 3 2 3 3 +-2 3 3 30 32 31 72 73 67 31 33 31 36 38 35 82 81 62 +-118 116 76 149 143 98 161 156 96 161 156 96 161 156 96 160 154 106 +-165 161 109 165 161 109 176 171 126 188 184 146 204 201 155 214 212 158 +-239 239 170 239 239 170 214 212 158 184 179 149 82 81 62 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-2 2 2 43 44 41 96 95 69 131 127 93 160 154 106 176 171 126 +-184 181 136 184 181 136 184 181 136 181 176 137 178 174 128 174 170 121 +-171 165 117 173 167 111 173 167 111 173 167 111 160 154 106 131 127 93 +-96 95 69 66 65 55 16 17 12 2 2 2 1 1 1 1 1 1 +-1 1 1 1 1 1 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 1 1 1 1 1 1 1 1 1 1 1 1 +-1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 +-1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 +-1 2 2 1 2 2 1 2 2 1 2 2 1 2 2 2 2 2 +-2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 +-2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 +-2 2 2 2 2 2 2 2 2 10 9 6 30 31 28 71 71 57 +-118 116 76 149 143 98 165 161 109 165 161 109 165 161 109 173 167 111 +-173 167 111 176 171 126 184 181 136 197 193 154 210 208 158 224 223 159 +-251 251 187 239 239 170 210 208 158 168 163 120 40 41 39 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 13 12 7 61 61 53 96 95 69 131 127 93 160 154 106 +-176 171 126 184 181 136 184 181 136 188 184 146 184 181 136 184 181 136 +-184 181 136 186 182 128 186 182 128 178 174 128 174 170 121 149 145 103 +-118 116 76 82 81 62 21 22 20 1 1 1 1 1 1 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 1 1 1 1 1 1 +-1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 +-1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 +-1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 2 2 +-1 2 2 1 2 2 1 2 2 1 2 2 1 2 2 2 2 2 +-2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 +-2 2 2 2 2 2 2 2 2 3 3 3 30 31 28 66 65 55 +-118 116 76 149 143 98 165 161 109 173 167 111 173 167 111 174 170 121 +-186 182 128 190 186 136 197 193 154 210 208 158 224 223 159 251 251 187 +-251 251 187 239 239 170 197 193 154 137 133 100 12 12 9 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 30 31 28 71 71 57 103 101 77 134 131 96 +-164 159 111 176 171 126 184 181 136 188 184 146 194 189 146 197 193 154 +-197 193 154 197 193 154 194 191 148 194 189 146 190 186 136 176 171 126 +-145 141 105 103 101 77 40 41 39 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 +-1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 +-1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 +-1 1 1 1 1 1 1 1 1 1 1 1 1 2 2 1 2 2 +-1 2 2 1 2 2 1 2 2 1 2 2 1 2 2 1 2 2 +-1 2 2 1 2 2 1 2 2 1 2 2 30 31 28 71 71 57 +-118 116 76 160 154 106 173 167 111 178 174 128 186 182 128 190 186 136 +-194 191 148 204 201 155 210 208 158 224 223 159 251 251 187 251 251 187 +-251 251 187 214 212 158 184 179 149 84 83 72 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 5 5 3 43 44 41 82 81 62 103 101 77 +-142 137 94 165 161 109 178 174 128 190 186 136 197 193 154 204 201 155 +-210 208 158 210 208 158 210 208 158 210 208 158 210 208 158 197 193 154 +-177 172 135 145 141 105 79 78 62 5 4 3 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 1 1 1 1 1 1 1 1 1 1 1 1 +-1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 +-1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 +-1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 +-1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 +-1 1 1 1 1 1 1 2 2 1 2 2 30 31 28 82 81 62 +-142 137 94 165 161 109 178 174 128 190 186 136 194 191 148 204 201 155 +-210 208 158 214 212 158 239 239 170 251 251 187 251 251 187 251 251 187 +-251 251 187 210 208 158 168 163 120 36 38 35 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 16 17 12 53 55 47 82 81 62 +-118 116 76 151 147 98 171 165 117 184 181 136 194 191 148 210 208 158 +-214 212 158 224 223 159 239 239 170 239 239 170 224 223 159 214 212 158 +-197 193 154 176 171 126 115 113 82 24 26 24 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 1 1 1 1 1 1 +-1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 +-1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 +-1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 +-1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 +-1 1 1 1 1 1 1 1 1 1 1 1 40 41 39 103 101 77 +-151 147 98 176 171 126 190 186 136 197 193 154 210 208 158 214 212 158 +-239 239 170 251 251 187 251 251 187 251 251 187 251 251 187 251 251 187 +-239 239 170 197 193 154 110 109 94 3 4 3 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 30 31 28 66 65 55 +-96 95 69 125 122 87 160 154 106 178 174 128 194 189 146 204 201 155 +-214 212 158 239 239 170 251 251 187 251 251 187 251 251 187 239 239 170 +-210 208 158 188 184 146 149 145 103 61 61 53 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 +-1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 +-1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 +-1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 +-1 1 1 1 1 1 1 1 1 1 1 1 61 61 53 131 127 93 +-164 159 111 184 181 136 197 193 154 210 208 158 224 223 159 251 251 187 +-251 251 187 251 251 187 251 251 187 251 251 187 251 251 187 251 251 187 +-210 208 158 168 163 120 43 44 41 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 4 3 2 36 38 35 +-71 71 57 96 95 69 142 137 94 165 161 109 184 181 136 197 193 154 +-210 208 158 239 239 170 251 251 187 251 251 187 251 251 187 251 251 187 +-214 212 158 197 193 154 168 163 120 103 101 77 7 7 5 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 1 +-1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 +-1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 +-1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 +-1 1 1 0 0 0 0 0 0 0 0 0 82 81 62 142 137 94 +-174 170 121 194 189 146 210 208 158 224 223 159 251 251 187 251 251 187 +-251 251 187 251 251 187 251 251 187 251 251 187 251 251 187 224 223 159 +-184 179 149 99 98 80 3 3 3 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 7 7 5 +-43 44 41 82 81 62 118 116 76 142 137 94 171 165 117 190 186 136 +-204 201 155 224 223 159 251 251 187 251 251 187 251 251 187 251 251 187 +-214 212 158 197 193 154 174 170 121 125 122 87 30 31 28 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 1 +-1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 3 4 3 82 81 62 149 143 98 +-176 171 126 194 191 148 210 208 158 239 239 170 251 251 187 251 251 187 +-251 251 187 251 251 187 251 251 187 251 251 187 239 239 170 204 201 155 +-145 141 105 30 31 28 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-10 9 6 46 47 43 82 81 62 118 116 76 149 143 98 174 170 121 +-194 189 146 210 208 158 224 223 159 251 251 187 251 251 187 224 223 159 +-210 208 158 194 191 148 174 170 121 134 131 96 53 55 47 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 7 7 5 96 95 69 149 143 98 +-176 171 126 194 191 148 210 208 158 239 239 170 251 251 187 251 251 187 +-251 251 187 251 251 187 251 251 187 239 239 170 210 208 158 177 172 135 +-75 75 61 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 10 9 6 46 47 43 82 81 62 118 116 76 149 143 98 +-176 171 126 194 191 148 210 208 158 214 212 158 214 212 158 210 208 158 +-197 193 154 184 181 136 164 159 111 131 127 93 53 55 47 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 7 7 5 96 95 69 149 143 98 +-174 170 121 194 189 146 204 201 155 214 212 158 239 239 170 251 251 187 +-251 251 187 251 251 187 239 239 170 210 208 158 184 179 149 110 109 94 +-12 12 9 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 10 9 6 43 44 41 82 81 62 115 113 82 +-144 139 99 168 163 120 188 184 146 197 193 154 197 193 154 194 189 146 +-184 181 136 174 170 121 151 147 98 118 116 76 36 38 35 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 4 3 2 82 81 62 142 137 94 +-171 165 117 186 182 128 194 191 148 210 208 158 214 212 158 224 223 159 +-239 239 170 224 223 159 210 208 158 184 179 149 137 133 100 36 38 35 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 7 7 5 36 38 35 71 71 57 +-103 101 77 131 127 93 155 149 109 168 163 120 168 163 120 168 163 120 +-164 159 111 149 143 98 125 122 87 82 81 62 13 12 7 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 61 61 53 125 122 87 +-160 154 106 174 170 121 184 181 136 194 189 146 204 201 155 210 208 158 +-210 208 158 204 201 155 184 179 149 145 141 105 61 61 53 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 3 3 2 30 31 28 +-61 61 53 82 81 62 103 101 77 121 119 87 125 122 87 125 122 87 +-118 116 76 103 101 77 79 78 62 24 26 24 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 25 27 25 96 95 69 +-142 137 94 160 154 106 171 165 117 178 174 128 184 181 136 184 181 136 +-181 176 137 177 172 135 145 141 105 75 75 61 5 5 3 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-16 17 12 40 41 39 61 61 53 71 71 57 71 71 57 71 71 57 +-66 65 55 43 44 41 12 12 9 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 1 1 1 46 47 43 +-96 95 69 125 122 87 142 137 94 149 145 103 155 149 109 155 149 109 +-145 141 105 121 119 87 66 65 55 7 7 5 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 1 1 1 16 17 12 24 26 24 25 27 25 19 20 18 +-7 7 5 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 2 2 1 +-25 27 25 61 61 53 82 81 62 96 95 69 96 95 69 82 81 62 +-61 61 53 25 27 25 2 2 1 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 5 6 5 13 12 7 10 9 6 3 4 3 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 ++ 0 0 0 0 0 0 0 0 0 0 0 0 ++ 0 0 0 0 0 0 0 0 0 0 0 0 ++ 0 0 0 0 0 0 0 0 0 0 0 0 ++ 0 0 0 0 0 0 0 0 0 0 0 0 ++ 0 0 0 0 0 0 0 0 0 0 0 0 ++ 0 0 0 0 0 0 0 0 0 0 0 0 ++ 0 0 0 0 0 0 0 0 0 0 0 0 ++ 0 0 0 0 0 0 0 0 0 0 0 0 ++ 0 0 0 0 0 0 0 0 0 0 0 0 ++ 6 6 6 6 6 6 10 10 10 10 10 10 ++ 10 10 10 6 6 6 6 6 6 6 6 6 ++ 0 0 0 0 0 0 0 0 0 0 0 0 ++ 0 0 0 0 0 0 0 0 0 0 0 0 ++ 0 0 0 0 0 0 0 0 0 0 0 0 ++ 0 0 0 0 0 0 0 0 0 0 0 0 ++ 0 0 0 0 0 0 0 0 0 0 0 0 ++ 0 0 0 0 0 0 0 0 0 0 0 0 ++ 0 0 0 0 0 0 0 0 0 0 0 0 ++ 0 0 0 0 0 0 0 0 0 0 0 0 ++ 0 0 0 0 0 0 0 0 0 0 0 0 ++ 0 0 0 0 0 0 0 0 0 0 0 0 ++ 0 0 0 0 0 0 0 0 0 0 0 0 ++ 0 0 0 0 0 0 0 0 0 0 0 0 ++ 0 0 0 0 0 0 0 0 0 0 0 0 ++ 0 0 0 0 0 0 0 0 0 0 0 0 ++ 0 0 0 0 0 0 0 0 0 0 0 0 ++ 0 0 0 0 0 0 0 0 0 0 0 0 ++ 0 0 0 0 0 0 0 0 0 0 0 0 ++ 0 0 0 6 6 6 10 10 10 14 14 14 ++ 22 22 22 26 26 26 30 30 30 34 34 34 ++ 30 30 30 30 30 30 26 26 26 18 18 18 ++ 14 14 14 10 10 10 6 6 6 0 0 0 ++ 0 0 0 0 0 0 0 0 0 0 0 0 ++ 0 0 0 0 0 0 0 0 0 0 0 0 ++ 0 0 0 0 0 0 0 0 0 0 0 0 ++ 0 0 0 0 0 0 0 0 0 0 0 0 ++ 0 0 0 0 0 0 0 0 0 0 0 0 ++ 0 0 0 0 0 0 0 0 0 0 0 0 ++ 0 0 0 0 0 0 0 0 0 0 0 0 ++ 0 0 0 0 0 0 0 0 0 0 0 0 ++ 0 0 0 0 0 0 0 0 0 0 0 0 ++ 0 0 0 0 0 1 0 0 1 0 0 0 ++ 0 0 0 0 0 0 0 0 0 0 0 0 ++ 0 0 0 0 0 0 0 0 0 0 0 0 ++ 0 0 0 0 0 0 0 0 0 0 0 0 ++ 0 0 0 0 0 0 0 0 0 0 0 0 ++ 0 0 0 0 0 0 0 0 0 0 0 0 ++ 0 0 0 0 0 0 0 0 0 0 0 0 ++ 6 6 6 14 14 14 26 26 26 42 42 42 ++ 54 54 54 66 66 66 78 78 78 78 78 78 ++ 78 78 78 74 74 74 66 66 66 54 54 54 ++ 42 42 42 26 26 26 18 18 18 10 10 10 ++ 6 6 6 0 0 0 0 0 0 0 0 0 ++ 0 0 0 0 0 0 0 0 0 0 0 0 ++ 0 0 0 0 0 0 0 0 0 0 0 0 ++ 0 0 0 0 0 0 0 0 0 0 0 0 ++ 0 0 0 0 0 0 0 0 0 0 0 0 ++ 0 0 0 0 0 0 0 0 0 0 0 0 ++ 0 0 0 0 0 0 0 0 0 0 0 0 ++ 0 0 0 0 0 0 0 0 0 0 0 0 ++ 0 0 0 0 0 0 0 0 0 0 0 0 ++ 0 0 1 0 0 0 0 0 0 0 0 0 ++ 0 0 0 0 0 0 0 0 0 0 0 0 ++ 0 0 0 0 0 0 0 0 0 0 0 0 ++ 0 0 0 0 0 0 0 0 0 0 0 0 ++ 0 0 0 0 0 0 0 0 0 0 0 0 ++ 0 0 0 0 0 0 0 0 0 0 0 0 ++ 0 0 0 0 0 0 0 0 0 10 10 10 ++ 22 22 22 42 42 42 66 66 66 86 86 86 ++ 66 66 66 38 38 38 38 38 38 22 22 22 ++ 26 26 26 34 34 34 54 54 54 66 66 66 ++ 86 86 86 70 70 70 46 46 46 26 26 26 ++ 14 14 14 6 6 6 0 0 0 0 0 0 ++ 0 0 0 0 0 0 0 0 0 0 0 0 ++ 0 0 0 0 0 0 0 0 0 0 0 0 ++ 0 0 0 0 0 0 0 0 0 0 0 0 ++ 0 0 0 0 0 0 0 0 0 0 0 0 ++ 0 0 0 0 0 0 0 0 0 0 0 0 ++ 0 0 0 0 0 0 0 0 0 0 0 0 ++ 0 0 0 0 0 0 0 0 0 0 0 0 ++ 0 0 0 0 0 0 0 0 0 0 0 0 ++ 0 0 1 0 0 1 0 0 1 0 0 0 ++ 0 0 0 0 0 0 0 0 0 0 0 0 ++ 0 0 0 0 0 0 0 0 0 0 0 0 ++ 0 0 0 0 0 0 0 0 0 0 0 0 ++ 0 0 0 0 0 0 0 0 0 0 0 0 ++ 0 0 0 0 0 0 0 0 0 0 0 0 ++ 0 0 0 0 0 0 10 10 10 26 26 26 ++ 50 50 50 82 82 82 58 58 58 6 6 6 ++ 2 2 6 2 2 6 2 2 6 2 2 6 ++ 2 2 6 2 2 6 2 2 6 2 2 6 ++ 6 6 6 54 54 54 86 86 86 66 66 66 ++ 38 38 38 18 18 18 6 6 6 0 0 0 ++ 0 0 0 0 0 0 0 0 0 0 0 0 ++ 0 0 0 0 0 0 0 0 0 0 0 0 ++ 0 0 0 0 0 0 0 0 0 0 0 0 ++ 0 0 0 0 0 0 0 0 0 0 0 0 ++ 0 0 0 0 0 0 0 0 0 0 0 0 ++ 0 0 0 0 0 0 0 0 0 0 0 0 ++ 0 0 0 0 0 0 0 0 0 0 0 0 ++ 0 0 0 0 0 0 0 0 0 0 0 0 ++ 0 0 0 0 0 0 0 0 0 0 0 0 ++ 0 0 0 0 0 0 0 0 0 0 0 0 ++ 0 0 0 0 0 0 0 0 0 0 0 0 ++ 0 0 0 0 0 0 0 0 0 0 0 0 ++ 0 0 0 0 0 0 0 0 0 0 0 0 ++ 0 0 0 0 0 0 0 0 0 0 0 0 ++ 0 0 0 6 6 6 22 22 22 50 50 50 ++ 78 78 78 34 34 34 2 2 6 2 2 6 ++ 2 2 6 2 2 6 2 2 6 2 2 6 ++ 2 2 6 2 2 6 2 2 6 2 2 6 ++ 2 2 6 2 2 6 6 6 6 70 70 70 ++ 78 78 78 46 46 46 22 22 22 6 6 6 ++ 0 0 0 0 0 0 0 0 0 0 0 0 ++ 0 0 0 0 0 0 0 0 0 0 0 0 ++ 0 0 0 0 0 0 0 0 0 0 0 0 ++ 0 0 0 0 0 0 0 0 0 0 0 0 ++ 0 0 0 0 0 0 0 0 0 0 0 0 ++ 0 0 0 0 0 0 0 0 0 0 0 0 ++ 0 0 0 0 0 0 0 0 0 0 0 0 ++ 0 0 0 0 0 0 0 0 0 0 0 0 ++ 0 0 1 0 0 1 0 0 1 0 0 0 ++ 0 0 0 0 0 0 0 0 0 0 0 0 ++ 0 0 0 0 0 0 0 0 0 0 0 0 ++ 0 0 0 0 0 0 0 0 0 0 0 0 ++ 0 0 0 0 0 0 0 0 0 0 0 0 ++ 0 0 0 0 0 0 0 0 0 0 0 0 ++ 6 6 6 18 18 18 42 42 42 82 82 82 ++ 26 26 26 2 2 6 2 2 6 2 2 6 ++ 2 2 6 2 2 6 2 2 6 2 2 6 ++ 2 2 6 2 2 6 2 2 6 14 14 14 ++ 46 46 46 34 34 34 6 6 6 2 2 6 ++ 42 42 42 78 78 78 42 42 42 18 18 18 ++ 6 6 6 0 0 0 0 0 0 0 0 0 ++ 0 0 0 0 0 0 0 0 0 0 0 0 ++ 0 0 0 0 0 0 0 0 0 0 0 0 ++ 0 0 0 0 0 0 0 0 0 0 0 0 ++ 0 0 0 0 0 0 0 0 0 0 0 0 ++ 0 0 0 0 0 0 0 0 0 0 0 0 ++ 0 0 0 0 0 0 0 0 0 0 0 0 ++ 0 0 0 0 0 0 0 0 0 0 0 0 ++ 0 0 1 0 0 0 0 0 1 0 0 0 ++ 0 0 0 0 0 0 0 0 0 0 0 0 ++ 0 0 0 0 0 0 0 0 0 0 0 0 ++ 0 0 0 0 0 0 0 0 0 0 0 0 ++ 0 0 0 0 0 0 0 0 0 0 0 0 ++ 0 0 0 0 0 0 0 0 0 0 0 0 ++ 10 10 10 30 30 30 66 66 66 58 58 58 ++ 2 2 6 2 2 6 2 2 6 2 2 6 ++ 2 2 6 2 2 6 2 2 6 2 2 6 ++ 2 2 6 2 2 6 2 2 6 26 26 26 ++ 86 86 86 101 101 101 46 46 46 10 10 10 ++ 2 2 6 58 58 58 70 70 70 34 34 34 ++ 10 10 10 0 0 0 0 0 0 0 0 0 ++ 0 0 0 0 0 0 0 0 0 0 0 0 ++ 0 0 0 0 0 0 0 0 0 0 0 0 ++ 0 0 0 0 0 0 0 0 0 0 0 0 ++ 0 0 0 0 0 0 0 0 0 0 0 0 ++ 0 0 0 0 0 0 0 0 0 0 0 0 ++ 0 0 0 0 0 0 0 0 0 0 0 0 ++ 0 0 0 0 0 0 0 0 0 0 0 0 ++ 0 0 1 0 0 1 0 0 1 0 0 0 ++ 0 0 0 0 0 0 0 0 0 0 0 0 ++ 0 0 0 0 0 0 0 0 0 0 0 0 ++ 0 0 0 0 0 0 0 0 0 0 0 0 ++ 0 0 0 0 0 0 0 0 0 0 0 0 ++ 0 0 0 0 0 0 0 0 0 0 0 0 ++ 14 14 14 42 42 42 86 86 86 10 10 10 ++ 2 2 6 2 2 6 2 2 6 2 2 6 ++ 2 2 6 2 2 6 2 2 6 2 2 6 ++ 2 2 6 2 2 6 2 2 6 30 30 30 ++ 94 94 94 94 94 94 58 58 58 26 26 26 ++ 2 2 6 6 6 6 78 78 78 54 54 54 ++ 22 22 22 6 6 6 0 0 0 0 0 0 ++ 0 0 0 0 0 0 0 0 0 0 0 0 ++ 0 0 0 0 0 0 0 0 0 0 0 0 ++ 0 0 0 0 0 0 0 0 0 0 0 0 ++ 0 0 0 0 0 0 0 0 0 0 0 0 ++ 0 0 0 0 0 0 0 0 0 0 0 0 ++ 0 0 0 0 0 0 0 0 0 0 0 0 ++ 0 0 0 0 0 0 0 0 0 0 0 0 ++ 0 0 0 0 0 0 0 0 0 0 0 0 ++ 0 0 0 0 0 0 0 0 0 0 0 0 ++ 0 0 0 0 0 0 0 0 0 0 0 0 ++ 0 0 0 0 0 0 0 0 0 0 0 0 ++ 0 0 0 0 0 0 0 0 0 0 0 0 ++ 0 0 0 0 0 0 0 0 0 6 6 6 ++ 22 22 22 62 62 62 62 62 62 2 2 6 ++ 2 2 6 2 2 6 2 2 6 2 2 6 ++ 2 2 6 2 2 6 2 2 6 2 2 6 ++ 2 2 6 2 2 6 2 2 6 26 26 26 ++ 54 54 54 38 38 38 18 18 18 10 10 10 ++ 2 2 6 2 2 6 34 34 34 82 82 82 ++ 38 38 38 14 14 14 0 0 0 0 0 0 ++ 0 0 0 0 0 0 0 0 0 0 0 0 ++ 0 0 0 0 0 0 0 0 0 0 0 0 ++ 0 0 0 0 0 0 0 0 0 0 0 0 ++ 0 0 0 0 0 0 0 0 0 0 0 0 ++ 0 0 0 0 0 0 0 0 0 0 0 0 ++ 0 0 0 0 0 0 0 0 0 0 0 0 ++ 0 0 0 0 0 0 0 0 0 0 0 0 ++ 0 0 0 0 0 1 0 0 1 0 0 0 ++ 0 0 0 0 0 0 0 0 0 0 0 0 ++ 0 0 0 0 0 0 0 0 0 0 0 0 ++ 0 0 0 0 0 0 0 0 0 0 0 0 ++ 0 0 0 0 0 0 0 0 0 0 0 0 ++ 0 0 0 0 0 0 0 0 0 6 6 6 ++ 30 30 30 78 78 78 30 30 30 2 2 6 ++ 2 2 6 2 2 6 2 2 6 2 2 6 ++ 2 2 6 2 2 6 2 2 6 2 2 6 ++ 2 2 6 2 2 6 2 2 6 10 10 10 ++ 10 10 10 2 2 6 2 2 6 2 2 6 ++ 2 2 6 2 2 6 2 2 6 78 78 78 ++ 50 50 50 18 18 18 6 6 6 0 0 0 ++ 0 0 0 0 0 0 0 0 0 0 0 0 ++ 0 0 0 0 0 0 0 0 0 0 0 0 ++ 0 0 0 0 0 0 0 0 0 0 0 0 ++ 0 0 0 0 0 0 0 0 0 0 0 0 ++ 0 0 0 0 0 0 0 0 0 0 0 0 ++ 0 0 0 0 0 0 0 0 0 0 0 0 ++ 0 0 0 0 0 0 0 0 0 0 0 0 ++ 0 0 1 0 0 0 0 0 0 0 0 0 ++ 0 0 0 0 0 0 0 0 0 0 0 0 ++ 0 0 0 0 0 0 0 0 0 0 0 0 ++ 0 0 0 0 0 0 0 0 0 0 0 0 ++ 0 0 0 0 0 0 0 0 0 0 0 0 ++ 0 0 0 0 0 0 0 0 0 10 10 10 ++ 38 38 38 86 86 86 14 14 14 2 2 6 ++ 2 2 6 2 2 6 2 2 6 2 2 6 ++ 2 2 6 2 2 6 2 2 6 2 2 6 ++ 2 2 6 2 2 6 2 2 6 2 2 6 ++ 2 2 6 2 2 6 2 2 6 2 2 6 ++ 2 2 6 2 2 6 2 2 6 54 54 54 ++ 66 66 66 26 26 26 6 6 6 0 0 0 ++ 0 0 0 0 0 0 0 0 0 0 0 0 ++ 0 0 0 0 0 0 0 0 0 0 0 0 ++ 0 0 0 0 0 0 0 0 0 0 0 0 ++ 0 0 0 0 0 0 0 0 0 0 0 0 ++ 0 0 0 0 0 0 0 0 0 0 0 0 ++ 0 0 0 0 0 0 0 0 0 0 0 0 ++ 0 0 0 0 0 0 0 0 0 0 0 0 ++ 0 0 0 0 0 1 0 0 1 0 0 0 ++ 0 0 0 0 0 0 0 0 0 0 0 0 ++ 0 0 0 0 0 0 0 0 0 0 0 0 ++ 0 0 0 0 0 0 0 0 0 0 0 0 ++ 0 0 0 0 0 0 0 0 0 0 0 0 ++ 0 0 0 0 0 0 0 0 0 14 14 14 ++ 42 42 42 82 82 82 2 2 6 2 2 6 ++ 2 2 6 6 6 6 10 10 10 2 2 6 ++ 2 2 6 2 2 6 2 2 6 2 2 6 ++ 2 2 6 2 2 6 2 2 6 6 6 6 ++ 14 14 14 10 10 10 2 2 6 2 2 6 ++ 2 2 6 2 2 6 2 2 6 18 18 18 ++ 82 82 82 34 34 34 10 10 10 0 0 0 ++ 0 0 0 0 0 0 0 0 0 0 0 0 ++ 0 0 0 0 0 0 0 0 0 0 0 0 ++ 0 0 0 0 0 0 0 0 0 0 0 0 ++ 0 0 0 0 0 0 0 0 0 0 0 0 ++ 0 0 0 0 0 0 0 0 0 0 0 0 ++ 0 0 0 0 0 0 0 0 0 0 0 0 ++ 0 0 0 0 0 0 0 0 0 0 0 0 ++ 0 0 1 0 0 0 0 0 0 0 0 0 ++ 0 0 0 0 0 0 0 0 0 0 0 0 ++ 0 0 0 0 0 0 0 0 0 0 0 0 ++ 0 0 0 0 0 0 0 0 0 0 0 0 ++ 0 0 0 0 0 0 0 0 0 0 0 0 ++ 0 0 0 0 0 0 0 0 0 14 14 14 ++ 46 46 46 86 86 86 2 2 6 2 2 6 ++ 6 6 6 6 6 6 22 22 22 34 34 34 ++ 6 6 6 2 2 6 2 2 6 2 2 6 ++ 2 2 6 2 2 6 18 18 18 34 34 34 ++ 10 10 10 50 50 50 22 22 22 2 2 6 ++ 2 2 6 2 2 6 2 2 6 10 10 10 ++ 86 86 86 42 42 42 14 14 14 0 0 0 ++ 0 0 0 0 0 0 0 0 0 0 0 0 ++ 0 0 0 0 0 0 0 0 0 0 0 0 ++ 0 0 0 0 0 0 0 0 0 0 0 0 ++ 0 0 0 0 0 0 0 0 0 0 0 0 ++ 0 0 0 0 0 0 0 0 0 0 0 0 ++ 0 0 0 0 0 0 0 0 0 0 0 0 ++ 0 0 0 0 0 0 0 0 0 0 0 0 ++ 0 0 1 0 0 1 0 0 1 0 0 0 ++ 0 0 0 0 0 0 0 0 0 0 0 0 ++ 0 0 0 0 0 0 0 0 0 0 0 0 ++ 0 0 0 0 0 0 0 0 0 0 0 0 ++ 0 0 0 0 0 0 0 0 0 0 0 0 ++ 0 0 0 0 0 0 0 0 0 14 14 14 ++ 46 46 46 86 86 86 2 2 6 2 2 6 ++ 38 38 38 116 116 116 94 94 94 22 22 22 ++ 22 22 22 2 2 6 2 2 6 2 2 6 ++ 14 14 14 86 86 86 138 138 138 162 162 162 ++154 154 154 38 38 38 26 26 26 6 6 6 ++ 2 2 6 2 2 6 2 2 6 2 2 6 ++ 86 86 86 46 46 46 14 14 14 0 0 0 ++ 0 0 0 0 0 0 0 0 0 0 0 0 ++ 0 0 0 0 0 0 0 0 0 0 0 0 ++ 0 0 0 0 0 0 0 0 0 0 0 0 ++ 0 0 0 0 0 0 0 0 0 0 0 0 ++ 0 0 0 0 0 0 0 0 0 0 0 0 ++ 0 0 0 0 0 0 0 0 0 0 0 0 ++ 0 0 0 0 0 0 0 0 0 0 0 0 ++ 0 0 0 0 0 0 0 0 0 0 0 0 ++ 0 0 0 0 0 0 0 0 0 0 0 0 ++ 0 0 0 0 0 0 0 0 0 0 0 0 ++ 0 0 0 0 0 0 0 0 0 0 0 0 ++ 0 0 0 0 0 0 0 0 0 0 0 0 ++ 0 0 0 0 0 0 0 0 0 14 14 14 ++ 46 46 46 86 86 86 2 2 6 14 14 14 ++134 134 134 198 198 198 195 195 195 116 116 116 ++ 10 10 10 2 2 6 2 2 6 6 6 6 ++101 98 89 187 187 187 210 210 210 218 218 218 ++214 214 214 134 134 134 14 14 14 6 6 6 ++ 2 2 6 2 2 6 2 2 6 2 2 6 ++ 86 86 86 50 50 50 18 18 18 6 6 6 ++ 0 0 0 0 0 0 0 0 0 0 0 0 ++ 0 0 0 0 0 0 0 0 0 0 0 0 ++ 0 0 0 0 0 0 0 0 0 0 0 0 ++ 0 0 0 0 0 0 0 0 0 0 0 0 ++ 0 0 0 0 0 0 0 0 0 0 0 0 ++ 0 0 0 0 0 0 0 0 0 0 0 0 ++ 0 0 0 0 0 0 0 0 1 0 0 0 ++ 0 0 1 0 0 1 0 0 1 0 0 0 ++ 0 0 0 0 0 0 0 0 0 0 0 0 ++ 0 0 0 0 0 0 0 0 0 0 0 0 ++ 0 0 0 0 0 0 0 0 0 0 0 0 ++ 0 0 0 0 0 0 0 0 0 0 0 0 ++ 0 0 0 0 0 0 0 0 0 14 14 14 ++ 46 46 46 86 86 86 2 2 6 54 54 54 ++218 218 218 195 195 195 226 226 226 246 246 246 ++ 58 58 58 2 2 6 2 2 6 30 30 30 ++210 210 210 253 253 253 174 174 174 123 123 123 ++221 221 221 234 234 234 74 74 74 2 2 6 ++ 2 2 6 2 2 6 2 2 6 2 2 6 ++ 70 70 70 58 58 58 22 22 22 6 6 6 ++ 0 0 0 0 0 0 0 0 0 0 0 0 ++ 0 0 0 0 0 0 0 0 0 0 0 0 ++ 0 0 0 0 0 0 0 0 0 0 0 0 ++ 0 0 0 0 0 0 0 0 0 0 0 0 ++ 0 0 0 0 0 0 0 0 0 0 0 0 ++ 0 0 0 0 0 0 0 0 0 0 0 0 ++ 0 0 0 0 0 0 0 0 0 0 0 0 ++ 0 0 0 0 0 0 0 0 0 0 0 0 ++ 0 0 0 0 0 0 0 0 0 0 0 0 ++ 0 0 0 0 0 0 0 0 0 0 0 0 ++ 0 0 0 0 0 0 0 0 0 0 0 0 ++ 0 0 0 0 0 0 0 0 0 0 0 0 ++ 0 0 0 0 0 0 0 0 0 14 14 14 ++ 46 46 46 82 82 82 2 2 6 106 106 106 ++170 170 170 26 26 26 86 86 86 226 226 226 ++123 123 123 10 10 10 14 14 14 46 46 46 ++231 231 231 190 190 190 6 6 6 70 70 70 ++ 90 90 90 238 238 238 158 158 158 2 2 6 ++ 2 2 6 2 2 6 2 2 6 2 2 6 ++ 70 70 70 58 58 58 22 22 22 6 6 6 ++ 0 0 0 0 0 0 0 0 0 0 0 0 ++ 0 0 0 0 0 0 0 0 0 0 0 0 ++ 0 0 0 0 0 0 0 0 0 0 0 0 ++ 0 0 0 0 0 0 0 0 0 0 0 0 ++ 0 0 0 0 0 0 0 0 0 0 0 0 ++ 0 0 0 0 0 0 0 0 0 0 0 0 ++ 0 0 0 0 0 0 0 0 1 0 0 0 ++ 0 0 1 0 0 1 0 0 1 0 0 0 ++ 0 0 0 0 0 0 0 0 0 0 0 0 ++ 0 0 0 0 0 0 0 0 0 0 0 0 ++ 0 0 0 0 0 0 0 0 0 0 0 0 ++ 0 0 0 0 0 0 0 0 0 0 0 0 ++ 0 0 0 0 0 0 0 0 0 14 14 14 ++ 42 42 42 86 86 86 6 6 6 116 116 116 ++106 106 106 6 6 6 70 70 70 149 149 149 ++128 128 128 18 18 18 38 38 38 54 54 54 ++221 221 221 106 106 106 2 2 6 14 14 14 ++ 46 46 46 190 190 190 198 198 198 2 2 6 ++ 2 2 6 2 2 6 2 2 6 2 2 6 ++ 74 74 74 62 62 62 22 22 22 6 6 6 ++ 0 0 0 0 0 0 0 0 0 0 0 0 ++ 0 0 0 0 0 0 0 0 0 0 0 0 ++ 0 0 0 0 0 0 0 0 0 0 0 0 ++ 0 0 0 0 0 0 0 0 0 0 0 0 ++ 0 0 0 0 0 0 0 0 0 0 0 0 ++ 0 0 0 0 0 0 0 0 0 0 0 0 ++ 0 0 0 0 0 0 0 0 1 0 0 0 ++ 0 0 1 0 0 0 0 0 1 0 0 0 ++ 0 0 0 0 0 0 0 0 0 0 0 0 ++ 0 0 0 0 0 0 0 0 0 0 0 0 ++ 0 0 0 0 0 0 0 0 0 0 0 0 ++ 0 0 0 0 0 0 0 0 0 0 0 0 ++ 0 0 0 0 0 0 0 0 0 14 14 14 ++ 42 42 42 94 94 94 14 14 14 101 101 101 ++128 128 128 2 2 6 18 18 18 116 116 116 ++118 98 46 121 92 8 121 92 8 98 78 10 ++162 162 162 106 106 106 2 2 6 2 2 6 ++ 2 2 6 195 195 195 195 195 195 6 6 6 ++ 2 2 6 2 2 6 2 2 6 2 2 6 ++ 74 74 74 62 62 62 22 22 22 6 6 6 ++ 0 0 0 0 0 0 0 0 0 0 0 0 ++ 0 0 0 0 0 0 0 0 0 0 0 0 ++ 0 0 0 0 0 0 0 0 0 0 0 0 ++ 0 0 0 0 0 0 0 0 0 0 0 0 ++ 0 0 0 0 0 0 0 0 0 0 0 0 ++ 0 0 0 0 0 0 0 0 0 0 0 0 ++ 0 0 0 0 0 0 0 0 1 0 0 1 ++ 0 0 1 0 0 0 0 0 1 0 0 0 ++ 0 0 0 0 0 0 0 0 0 0 0 0 ++ 0 0 0 0 0 0 0 0 0 0 0 0 ++ 0 0 0 0 0 0 0 0 0 0 0 0 ++ 0 0 0 0 0 0 0 0 0 0 0 0 ++ 0 0 0 0 0 0 0 0 0 10 10 10 ++ 38 38 38 90 90 90 14 14 14 58 58 58 ++210 210 210 26 26 26 54 38 6 154 114 10 ++226 170 11 236 186 11 225 175 15 184 144 12 ++215 174 15 175 146 61 37 26 9 2 2 6 ++ 70 70 70 246 246 246 138 138 138 2 2 6 ++ 2 2 6 2 2 6 2 2 6 2 2 6 ++ 70 70 70 66 66 66 26 26 26 6 6 6 ++ 0 0 0 0 0 0 0 0 0 0 0 0 ++ 0 0 0 0 0 0 0 0 0 0 0 0 ++ 0 0 0 0 0 0 0 0 0 0 0 0 ++ 0 0 0 0 0 0 0 0 0 0 0 0 ++ 0 0 0 0 0 0 0 0 0 0 0 0 ++ 0 0 0 0 0 0 0 0 0 0 0 0 ++ 0 0 0 0 0 0 0 0 0 0 0 0 ++ 0 0 0 0 0 0 0 0 0 0 0 0 ++ 0 0 0 0 0 0 0 0 0 0 0 0 ++ 0 0 0 0 0 0 0 0 0 0 0 0 ++ 0 0 0 0 0 0 0 0 0 0 0 0 ++ 0 0 0 0 0 0 0 0 0 0 0 0 ++ 0 0 0 0 0 0 0 0 0 10 10 10 ++ 38 38 38 86 86 86 14 14 14 10 10 10 ++195 195 195 188 164 115 192 133 9 225 175 15 ++239 182 13 234 190 10 232 195 16 232 200 30 ++245 207 45 241 208 19 232 195 16 184 144 12 ++218 194 134 211 206 186 42 42 42 2 2 6 ++ 2 2 6 2 2 6 2 2 6 2 2 6 ++ 50 50 50 74 74 74 30 30 30 6 6 6 ++ 0 0 0 0 0 0 0 0 0 0 0 0 ++ 0 0 0 0 0 0 0 0 0 0 0 0 ++ 0 0 0 0 0 0 0 0 0 0 0 0 ++ 0 0 0 0 0 0 0 0 0 0 0 0 ++ 0 0 0 0 0 0 0 0 0 0 0 0 ++ 0 0 0 0 0 0 0 0 0 0 0 0 ++ 0 0 0 0 0 0 0 0 0 0 0 0 ++ 0 0 0 0 0 0 0 0 0 0 0 0 ++ 0 0 0 0 0 0 0 0 0 0 0 0 ++ 0 0 0 0 0 0 0 0 0 0 0 0 ++ 0 0 0 0 0 0 0 0 0 0 0 0 ++ 0 0 0 0 0 0 0 0 0 0 0 0 ++ 0 0 0 0 0 0 0 0 0 10 10 10 ++ 34 34 34 86 86 86 14 14 14 2 2 6 ++121 87 25 192 133 9 219 162 10 239 182 13 ++236 186 11 232 195 16 241 208 19 244 214 54 ++246 218 60 246 218 38 246 215 20 241 208 19 ++241 208 19 226 184 13 121 87 25 2 2 6 ++ 2 2 6 2 2 6 2 2 6 2 2 6 ++ 50 50 50 82 82 82 34 34 34 10 10 10 ++ 0 0 0 0 0 0 0 0 0 0 0 0 ++ 0 0 0 0 0 0 0 0 0 0 0 0 ++ 0 0 0 0 0 0 0 0 0 0 0 0 ++ 0 0 0 0 0 0 0 0 0 0 0 0 ++ 0 0 0 0 0 0 0 0 0 0 0 0 ++ 0 0 0 0 0 0 0 0 0 0 0 0 ++ 0 0 0 0 0 0 0 0 0 0 0 0 ++ 0 0 0 0 0 0 0 0 0 0 0 0 ++ 0 0 0 0 0 0 0 0 0 0 0 0 ++ 0 0 0 0 0 0 0 0 0 0 0 0 ++ 0 0 0 0 0 0 0 0 0 0 0 0 ++ 0 0 0 0 0 0 0 0 0 0 0 0 ++ 0 0 0 0 0 0 0 0 0 10 10 10 ++ 34 34 34 82 82 82 30 30 30 61 42 6 ++180 123 7 206 145 10 230 174 11 239 182 13 ++234 190 10 238 202 15 241 208 19 246 218 74 ++246 218 38 246 215 20 246 215 20 246 215 20 ++226 184 13 215 174 15 184 144 12 6 6 6 ++ 2 2 6 2 2 6 2 2 6 2 2 6 ++ 26 26 26 94 94 94 42 42 42 14 14 14 ++ 0 0 0 0 0 0 0 0 0 0 0 0 ++ 0 0 0 0 0 0 0 0 0 0 0 0 ++ 0 0 0 0 0 0 0 0 0 0 0 0 ++ 0 0 0 0 0 0 0 0 0 0 0 0 ++ 0 0 0 0 0 0 0 0 0 0 0 0 ++ 0 0 0 0 0 0 0 0 0 0 0 0 ++ 0 0 0 0 0 0 0 0 0 0 0 0 ++ 0 0 0 0 0 0 0 0 0 0 0 0 ++ 0 0 0 0 0 0 0 0 0 0 0 0 ++ 0 0 0 0 0 0 0 0 0 0 0 0 ++ 0 0 0 0 0 0 0 0 0 0 0 0 ++ 0 0 0 0 0 0 0 0 0 0 0 0 ++ 0 0 0 0 0 0 0 0 0 10 10 10 ++ 30 30 30 78 78 78 50 50 50 104 69 6 ++192 133 9 216 158 10 236 178 12 236 186 11 ++232 195 16 241 208 19 244 214 54 245 215 43 ++246 215 20 246 215 20 241 208 19 198 155 10 ++200 144 11 216 158 10 156 118 10 2 2 6 ++ 2 2 6 2 2 6 2 2 6 2 2 6 ++ 6 6 6 90 90 90 54 54 54 18 18 18 ++ 6 6 6 0 0 0 0 0 0 0 0 0 ++ 0 0 0 0 0 0 0 0 0 0 0 0 ++ 0 0 0 0 0 0 0 0 0 0 0 0 ++ 0 0 0 0 0 0 0 0 0 0 0 0 ++ 0 0 0 0 0 0 0 0 0 0 0 0 ++ 0 0 0 0 0 0 0 0 0 0 0 0 ++ 0 0 0 0 0 0 0 0 0 0 0 0 ++ 0 0 0 0 0 0 0 0 0 0 0 0 ++ 0 0 0 0 0 0 0 0 0 0 0 0 ++ 0 0 0 0 0 0 0 0 0 0 0 0 ++ 0 0 0 0 0 0 0 0 0 0 0 0 ++ 0 0 0 0 0 0 0 0 0 0 0 0 ++ 0 0 0 0 0 0 0 0 0 10 10 10 ++ 30 30 30 78 78 78 46 46 46 22 22 22 ++137 92 6 210 162 10 239 182 13 238 190 10 ++238 202 15 241 208 19 246 215 20 246 215 20 ++241 208 19 203 166 17 185 133 11 210 150 10 ++216 158 10 210 150 10 102 78 10 2 2 6 ++ 6 6 6 54 54 54 14 14 14 2 2 6 ++ 2 2 6 62 62 62 74 74 74 30 30 30 ++ 10 10 10 0 0 0 0 0 0 0 0 0 ++ 0 0 0 0 0 0 0 0 0 0 0 0 ++ 0 0 0 0 0 0 0 0 0 0 0 0 ++ 0 0 0 0 0 0 0 0 0 0 0 0 ++ 0 0 0 0 0 0 0 0 0 0 0 0 ++ 0 0 0 0 0 0 0 0 0 0 0 0 ++ 0 0 0 0 0 0 0 0 0 0 0 0 ++ 0 0 0 0 0 0 0 0 0 0 0 0 ++ 0 0 0 0 0 0 0 0 0 0 0 0 ++ 0 0 0 0 0 0 0 0 0 0 0 0 ++ 0 0 0 0 0 0 0 0 0 0 0 0 ++ 0 0 0 0 0 0 0 0 0 0 0 0 ++ 0 0 0 0 0 0 0 0 0 10 10 10 ++ 34 34 34 78 78 78 50 50 50 6 6 6 ++ 94 70 30 139 102 15 190 146 13 226 184 13 ++232 200 30 232 195 16 215 174 15 190 146 13 ++168 122 10 192 133 9 210 150 10 213 154 11 ++202 150 34 182 157 106 101 98 89 2 2 6 ++ 2 2 6 78 78 78 116 116 116 58 58 58 ++ 2 2 6 22 22 22 90 90 90 46 46 46 ++ 18 18 18 6 6 6 0 0 0 0 0 0 ++ 0 0 0 0 0 0 0 0 0 0 0 0 ++ 0 0 0 0 0 0 0 0 0 0 0 0 ++ 0 0 0 0 0 0 0 0 0 0 0 0 ++ 0 0 0 0 0 0 0 0 0 0 0 0 ++ 0 0 0 0 0 0 0 0 0 0 0 0 ++ 0 0 0 0 0 0 0 0 0 0 0 0 ++ 0 0 0 0 0 0 0 0 0 0 0 0 ++ 0 0 0 0 0 0 0 0 0 0 0 0 ++ 0 0 0 0 0 0 0 0 0 0 0 0 ++ 0 0 0 0 0 0 0 0 0 0 0 0 ++ 0 0 0 0 0 0 0 0 0 0 0 0 ++ 0 0 0 0 0 0 0 0 0 10 10 10 ++ 38 38 38 86 86 86 50 50 50 6 6 6 ++128 128 128 174 154 114 156 107 11 168 122 10 ++198 155 10 184 144 12 197 138 11 200 144 11 ++206 145 10 206 145 10 197 138 11 188 164 115 ++195 195 195 198 198 198 174 174 174 14 14 14 ++ 2 2 6 22 22 22 116 116 116 116 116 116 ++ 22 22 22 2 2 6 74 74 74 70 70 70 ++ 30 30 30 10 10 10 0 0 0 0 0 0 ++ 0 0 0 0 0 0 0 0 0 0 0 0 ++ 0 0 0 0 0 0 0 0 0 0 0 0 ++ 0 0 0 0 0 0 0 0 0 0 0 0 ++ 0 0 0 0 0 0 0 0 0 0 0 0 ++ 0 0 0 0 0 0 0 0 0 0 0 0 ++ 0 0 0 0 0 0 0 0 0 0 0 0 ++ 0 0 0 0 0 0 0 0 0 0 0 0 ++ 0 0 0 0 0 0 0 0 0 0 0 0 ++ 0 0 0 0 0 0 0 0 0 0 0 0 ++ 0 0 0 0 0 0 0 0 0 0 0 0 ++ 0 0 0 0 0 0 0 0 0 0 0 0 ++ 0 0 0 0 0 0 6 6 6 18 18 18 ++ 50 50 50 101 101 101 26 26 26 10 10 10 ++138 138 138 190 190 190 174 154 114 156 107 11 ++197 138 11 200 144 11 197 138 11 192 133 9 ++180 123 7 190 142 34 190 178 144 187 187 187 ++202 202 202 221 221 221 214 214 214 66 66 66 ++ 2 2 6 2 2 6 50 50 50 62 62 62 ++ 6 6 6 2 2 6 10 10 10 90 90 90 ++ 50 50 50 18 18 18 6 6 6 0 0 0 ++ 0 0 0 0 0 0 0 0 0 0 0 0 ++ 0 0 0 0 0 0 0 0 0 0 0 0 ++ 0 0 0 0 0 0 0 0 0 0 0 0 ++ 0 0 0 0 0 0 0 0 0 0 0 0 ++ 0 0 0 0 0 0 0 0 0 0 0 0 ++ 0 0 0 0 0 0 0 0 0 0 0 0 ++ 0 0 0 0 0 0 0 0 0 0 0 0 ++ 0 0 0 0 0 0 0 0 0 0 0 0 ++ 0 0 0 0 0 0 0 0 0 0 0 0 ++ 0 0 0 0 0 0 0 0 0 0 0 0 ++ 0 0 0 0 0 0 0 0 0 0 0 0 ++ 0 0 0 0 0 0 10 10 10 34 34 34 ++ 74 74 74 74 74 74 2 2 6 6 6 6 ++144 144 144 198 198 198 190 190 190 178 166 146 ++154 121 60 156 107 11 156 107 11 168 124 44 ++174 154 114 187 187 187 190 190 190 210 210 210 ++246 246 246 253 253 253 253 253 253 182 182 182 ++ 6 6 6 2 2 6 2 2 6 2 2 6 ++ 2 2 6 2 2 6 2 2 6 62 62 62 ++ 74 74 74 34 34 34 14 14 14 0 0 0 ++ 0 0 0 0 0 0 0 0 0 0 0 0 ++ 0 0 0 0 0 0 0 0 0 0 0 0 ++ 0 0 0 0 0 0 0 0 0 0 0 0 ++ 0 0 0 0 0 0 0 0 0 0 0 0 ++ 0 0 0 0 0 0 0 0 0 0 0 0 ++ 0 0 0 0 0 0 0 0 0 0 0 0 ++ 0 0 0 0 0 0 0 0 0 0 0 0 ++ 0 0 0 0 0 0 0 0 0 0 0 0 ++ 0 0 0 0 0 0 0 0 0 0 0 0 ++ 0 0 0 0 0 0 0 0 0 0 0 0 ++ 0 0 0 0 0 0 0 0 0 0 0 0 ++ 0 0 0 10 10 10 22 22 22 54 54 54 ++ 94 94 94 18 18 18 2 2 6 46 46 46 ++234 234 234 221 221 221 190 190 190 190 190 190 ++190 190 190 187 187 187 187 187 187 190 190 190 ++190 190 190 195 195 195 214 214 214 242 242 242 ++253 253 253 253 253 253 253 253 253 253 253 253 ++ 82 82 82 2 2 6 2 2 6 2 2 6 ++ 2 2 6 2 2 6 2 2 6 14 14 14 ++ 86 86 86 54 54 54 22 22 22 6 6 6 ++ 0 0 0 0 0 0 0 0 0 0 0 0 ++ 0 0 0 0 0 0 0 0 0 0 0 0 ++ 0 0 0 0 0 0 0 0 0 0 0 0 ++ 0 0 0 0 0 0 0 0 0 0 0 0 ++ 0 0 0 0 0 0 0 0 0 0 0 0 ++ 0 0 0 0 0 0 0 0 0 0 0 0 ++ 0 0 0 0 0 0 0 0 0 0 0 0 ++ 0 0 0 0 0 0 0 0 0 0 0 0 ++ 0 0 0 0 0 0 0 0 0 0 0 0 ++ 0 0 0 0 0 0 0 0 0 0 0 0 ++ 0 0 0 0 0 0 0 0 0 0 0 0 ++ 6 6 6 18 18 18 46 46 46 90 90 90 ++ 46 46 46 18 18 18 6 6 6 182 182 182 ++253 253 253 246 246 246 206 206 206 190 190 190 ++190 190 190 190 190 190 190 190 190 190 190 190 ++206 206 206 231 231 231 250 250 250 253 253 253 ++253 253 253 253 253 253 253 253 253 253 253 253 ++202 202 202 14 14 14 2 2 6 2 2 6 ++ 2 2 6 2 2 6 2 2 6 2 2 6 ++ 42 42 42 86 86 86 42 42 42 18 18 18 ++ 6 6 6 0 0 0 0 0 0 0 0 0 ++ 0 0 0 0 0 0 0 0 0 0 0 0 ++ 0 0 0 0 0 0 0 0 0 0 0 0 ++ 0 0 0 0 0 0 0 0 0 0 0 0 ++ 0 0 0 0 0 0 0 0 0 0 0 0 ++ 0 0 0 0 0 0 0 0 0 0 0 0 ++ 0 0 0 0 0 0 0 0 0 0 0 0 ++ 0 0 0 0 0 0 0 0 0 0 0 0 ++ 0 0 0 0 0 0 0 0 0 0 0 0 ++ 0 0 0 0 0 0 0 0 0 0 0 0 ++ 0 0 0 0 0 0 0 0 0 6 6 6 ++ 14 14 14 38 38 38 74 74 74 66 66 66 ++ 2 2 6 6 6 6 90 90 90 250 250 250 ++253 253 253 253 253 253 238 238 238 198 198 198 ++190 190 190 190 190 190 195 195 195 221 221 221 ++246 246 246 253 253 253 253 253 253 253 253 253 ++253 253 253 253 253 253 253 253 253 253 253 253 ++253 253 253 82 82 82 2 2 6 2 2 6 ++ 2 2 6 2 2 6 2 2 6 2 2 6 ++ 2 2 6 78 78 78 70 70 70 34 34 34 ++ 14 14 14 6 6 6 0 0 0 0 0 0 ++ 0 0 0 0 0 0 0 0 0 0 0 0 ++ 0 0 0 0 0 0 0 0 0 0 0 0 ++ 0 0 0 0 0 0 0 0 0 0 0 0 ++ 0 0 0 0 0 0 0 0 0 0 0 0 ++ 0 0 0 0 0 0 0 0 0 0 0 0 ++ 0 0 0 0 0 0 0 0 0 0 0 0 ++ 0 0 0 0 0 0 0 0 0 0 0 0 ++ 0 0 0 0 0 0 0 0 0 0 0 0 ++ 0 0 0 0 0 0 0 0 0 0 0 0 ++ 0 0 0 0 0 0 0 0 0 14 14 14 ++ 34 34 34 66 66 66 78 78 78 6 6 6 ++ 2 2 6 18 18 18 218 218 218 253 253 253 ++253 253 253 253 253 253 253 253 253 246 246 246 ++226 226 226 231 231 231 246 246 246 253 253 253 ++253 253 253 253 253 253 253 253 253 253 253 253 ++253 253 253 253 253 253 253 253 253 253 253 253 ++253 253 253 178 178 178 2 2 6 2 2 6 ++ 2 2 6 2 2 6 2 2 6 2 2 6 ++ 2 2 6 18 18 18 90 90 90 62 62 62 ++ 30 30 30 10 10 10 0 0 0 0 0 0 ++ 0 0 0 0 0 0 0 0 0 0 0 0 ++ 0 0 0 0 0 0 0 0 0 0 0 0 ++ 0 0 0 0 0 0 0 0 0 0 0 0 ++ 0 0 0 0 0 0 0 0 0 0 0 0 ++ 0 0 0 0 0 0 0 0 0 0 0 0 ++ 0 0 0 0 0 0 0 0 0 0 0 0 ++ 0 0 0 0 0 0 0 0 0 0 0 0 ++ 0 0 0 0 0 0 0 0 0 0 0 0 ++ 0 0 0 0 0 0 0 0 0 0 0 0 ++ 0 0 0 0 0 0 10 10 10 26 26 26 ++ 58 58 58 90 90 90 18 18 18 2 2 6 ++ 2 2 6 110 110 110 253 253 253 253 253 253 ++253 253 253 253 253 253 253 253 253 253 253 253 ++250 250 250 253 253 253 253 253 253 253 253 253 ++253 253 253 253 253 253 253 253 253 253 253 253 ++253 253 253 253 253 253 253 253 253 253 253 253 ++253 253 253 231 231 231 18 18 18 2 2 6 ++ 2 2 6 2 2 6 2 2 6 2 2 6 ++ 2 2 6 2 2 6 18 18 18 94 94 94 ++ 54 54 54 26 26 26 10 10 10 0 0 0 ++ 0 0 0 0 0 0 0 0 0 0 0 0 ++ 0 0 0 0 0 0 0 0 0 0 0 0 ++ 0 0 0 0 0 0 0 0 0 0 0 0 ++ 0 0 0 0 0 0 0 0 0 0 0 0 ++ 0 0 0 0 0 0 0 0 0 0 0 0 ++ 0 0 0 0 0 0 0 0 0 0 0 0 ++ 0 0 0 0 0 0 0 0 0 0 0 0 ++ 0 0 0 0 0 0 0 0 0 0 0 0 ++ 0 0 0 0 0 0 0 0 0 0 0 0 ++ 0 0 0 6 6 6 22 22 22 50 50 50 ++ 90 90 90 26 26 26 2 2 6 2 2 6 ++ 14 14 14 195 195 195 250 250 250 253 253 253 ++253 253 253 253 253 253 253 253 253 253 253 253 ++253 253 253 253 253 253 253 253 253 253 253 253 ++253 253 253 253 253 253 253 253 253 253 253 253 ++253 253 253 253 253 253 253 253 253 253 253 253 ++250 250 250 242 242 242 54 54 54 2 2 6 ++ 2 2 6 2 2 6 2 2 6 2 2 6 ++ 2 2 6 2 2 6 2 2 6 38 38 38 ++ 86 86 86 50 50 50 22 22 22 6 6 6 ++ 0 0 0 0 0 0 0 0 0 0 0 0 ++ 0 0 0 0 0 0 0 0 0 0 0 0 ++ 0 0 0 0 0 0 0 0 0 0 0 0 ++ 0 0 0 0 0 0 0 0 0 0 0 0 ++ 0 0 0 0 0 0 0 0 0 0 0 0 ++ 0 0 0 0 0 0 0 0 0 0 0 0 ++ 0 0 0 0 0 0 0 0 0 0 0 0 ++ 0 0 0 0 0 0 0 0 0 0 0 0 ++ 0 0 0 0 0 0 0 0 0 0 0 0 ++ 6 6 6 14 14 14 38 38 38 82 82 82 ++ 34 34 34 2 2 6 2 2 6 2 2 6 ++ 42 42 42 195 195 195 246 246 246 253 253 253 ++253 253 253 253 253 253 253 253 253 250 250 250 ++242 242 242 242 242 242 250 250 250 253 253 253 ++253 253 253 253 253 253 253 253 253 253 253 253 ++253 253 253 250 250 250 246 246 246 238 238 238 ++226 226 226 231 231 231 101 101 101 6 6 6 ++ 2 2 6 2 2 6 2 2 6 2 2 6 ++ 2 2 6 2 2 6 2 2 6 2 2 6 ++ 38 38 38 82 82 82 42 42 42 14 14 14 ++ 6 6 6 0 0 0 0 0 0 0 0 0 ++ 0 0 0 0 0 0 0 0 0 0 0 0 ++ 0 0 0 0 0 0 0 0 0 0 0 0 ++ 0 0 0 0 0 0 0 0 0 0 0 0 ++ 0 0 0 0 0 0 0 0 0 0 0 0 ++ 0 0 0 0 0 0 0 0 0 0 0 0 ++ 0 0 0 0 0 0 0 0 0 0 0 0 ++ 0 0 0 0 0 0 0 0 0 0 0 0 ++ 0 0 0 0 0 0 0 0 0 0 0 0 ++ 10 10 10 26 26 26 62 62 62 66 66 66 ++ 2 2 6 2 2 6 2 2 6 6 6 6 ++ 70 70 70 170 170 170 206 206 206 234 234 234 ++246 246 246 250 250 250 250 250 250 238 238 238 ++226 226 226 231 231 231 238 238 238 250 250 250 ++250 250 250 250 250 250 246 246 246 231 231 231 ++214 214 214 206 206 206 202 202 202 202 202 202 ++198 198 198 202 202 202 182 182 182 18 18 18 ++ 2 2 6 2 2 6 2 2 6 2 2 6 ++ 2 2 6 2 2 6 2 2 6 2 2 6 ++ 2 2 6 62 62 62 66 66 66 30 30 30 ++ 10 10 10 0 0 0 0 0 0 0 0 0 ++ 0 0 0 0 0 0 0 0 0 0 0 0 ++ 0 0 0 0 0 0 0 0 0 0 0 0 ++ 0 0 0 0 0 0 0 0 0 0 0 0 ++ 0 0 0 0 0 0 0 0 0 0 0 0 ++ 0 0 0 0 0 0 0 0 0 0 0 0 ++ 0 0 0 0 0 0 0 0 0 0 0 0 ++ 0 0 0 0 0 0 0 0 0 0 0 0 ++ 0 0 0 0 0 0 0 0 0 0 0 0 ++ 14 14 14 42 42 42 82 82 82 18 18 18 ++ 2 2 6 2 2 6 2 2 6 10 10 10 ++ 94 94 94 182 182 182 218 218 218 242 242 242 ++250 250 250 253 253 253 253 253 253 250 250 250 ++234 234 234 253 253 253 253 253 253 253 253 253 ++253 253 253 253 253 253 253 253 253 246 246 246 ++238 238 238 226 226 226 210 210 210 202 202 202 ++195 195 195 195 195 195 210 210 210 158 158 158 ++ 6 6 6 14 14 14 50 50 50 14 14 14 ++ 2 2 6 2 2 6 2 2 6 2 2 6 ++ 2 2 6 6 6 6 86 86 86 46 46 46 ++ 18 18 18 6 6 6 0 0 0 0 0 0 ++ 0 0 0 0 0 0 0 0 0 0 0 0 ++ 0 0 0 0 0 0 0 0 0 0 0 0 ++ 0 0 0 0 0 0 0 0 0 0 0 0 ++ 0 0 0 0 0 0 0 0 0 0 0 0 ++ 0 0 0 0 0 0 0 0 0 0 0 0 ++ 0 0 0 0 0 0 0 0 0 0 0 0 ++ 0 0 0 0 0 0 0 0 0 0 0 0 ++ 0 0 0 0 0 0 0 0 0 6 6 6 ++ 22 22 22 54 54 54 70 70 70 2 2 6 ++ 2 2 6 10 10 10 2 2 6 22 22 22 ++166 166 166 231 231 231 250 250 250 253 253 253 ++253 253 253 253 253 253 253 253 253 250 250 250 ++242 242 242 253 253 253 253 253 253 253 253 253 ++253 253 253 253 253 253 253 253 253 253 253 253 ++253 253 253 253 253 253 253 253 253 246 246 246 ++231 231 231 206 206 206 198 198 198 226 226 226 ++ 94 94 94 2 2 6 6 6 6 38 38 38 ++ 30 30 30 2 2 6 2 2 6 2 2 6 ++ 2 2 6 2 2 6 62 62 62 66 66 66 ++ 26 26 26 10 10 10 0 0 0 0 0 0 ++ 0 0 0 0 0 0 0 0 0 0 0 0 ++ 0 0 0 0 0 0 0 0 0 0 0 0 ++ 0 0 0 0 0 0 0 0 0 0 0 0 ++ 0 0 0 0 0 0 0 0 0 0 0 0 ++ 0 0 0 0 0 0 0 0 0 0 0 0 ++ 0 0 0 0 0 0 0 0 0 0 0 0 ++ 0 0 0 0 0 0 0 0 0 0 0 0 ++ 0 0 0 0 0 0 0 0 0 10 10 10 ++ 30 30 30 74 74 74 50 50 50 2 2 6 ++ 26 26 26 26 26 26 2 2 6 106 106 106 ++238 238 238 253 253 253 253 253 253 253 253 253 ++253 253 253 253 253 253 253 253 253 253 253 253 ++253 253 253 253 253 253 253 253 253 253 253 253 ++253 253 253 253 253 253 253 253 253 253 253 253 ++253 253 253 253 253 253 253 253 253 253 253 253 ++253 253 253 246 246 246 218 218 218 202 202 202 ++210 210 210 14 14 14 2 2 6 2 2 6 ++ 30 30 30 22 22 22 2 2 6 2 2 6 ++ 2 2 6 2 2 6 18 18 18 86 86 86 ++ 42 42 42 14 14 14 0 0 0 0 0 0 ++ 0 0 0 0 0 0 0 0 0 0 0 0 ++ 0 0 0 0 0 0 0 0 0 0 0 0 ++ 0 0 0 0 0 0 0 0 0 0 0 0 ++ 0 0 0 0 0 0 0 0 0 0 0 0 ++ 0 0 0 0 0 0 0 0 0 0 0 0 ++ 0 0 0 0 0 0 0 0 0 0 0 0 ++ 0 0 0 0 0 0 0 0 0 0 0 0 ++ 0 0 0 0 0 0 0 0 0 14 14 14 ++ 42 42 42 90 90 90 22 22 22 2 2 6 ++ 42 42 42 2 2 6 18 18 18 218 218 218 ++253 253 253 253 253 253 253 253 253 253 253 253 ++253 253 253 253 253 253 253 253 253 253 253 253 ++253 253 253 253 253 253 253 253 253 253 253 253 ++253 253 253 253 253 253 253 253 253 253 253 253 ++253 253 253 253 253 253 253 253 253 253 253 253 ++253 253 253 253 253 253 250 250 250 221 221 221 ++218 218 218 101 101 101 2 2 6 14 14 14 ++ 18 18 18 38 38 38 10 10 10 2 2 6 ++ 2 2 6 2 2 6 2 2 6 78 78 78 ++ 58 58 58 22 22 22 6 6 6 0 0 0 ++ 0 0 0 0 0 0 0 0 0 0 0 0 ++ 0 0 0 0 0 0 0 0 0 0 0 0 ++ 0 0 0 0 0 0 0 0 0 0 0 0 ++ 0 0 0 0 0 0 0 0 0 0 0 0 ++ 0 0 0 0 0 0 0 0 0 0 0 0 ++ 0 0 0 0 0 0 0 0 0 0 0 0 ++ 0 0 0 0 0 0 0 0 0 0 0 0 ++ 0 0 0 0 0 0 6 6 6 18 18 18 ++ 54 54 54 82 82 82 2 2 6 26 26 26 ++ 22 22 22 2 2 6 123 123 123 253 253 253 ++253 253 253 253 253 253 253 253 253 253 253 253 ++253 253 253 253 253 253 253 253 253 253 253 253 ++253 253 253 253 253 253 253 253 253 253 253 253 ++253 253 253 253 253 253 253 253 253 253 253 253 ++253 253 253 253 253 253 253 253 253 253 253 253 ++253 253 253 253 253 253 253 253 253 250 250 250 ++238 238 238 198 198 198 6 6 6 38 38 38 ++ 58 58 58 26 26 26 38 38 38 2 2 6 ++ 2 2 6 2 2 6 2 2 6 46 46 46 ++ 78 78 78 30 30 30 10 10 10 0 0 0 ++ 0 0 0 0 0 0 0 0 0 0 0 0 ++ 0 0 0 0 0 0 0 0 0 0 0 0 ++ 0 0 0 0 0 0 0 0 0 0 0 0 ++ 0 0 0 0 0 0 0 0 0 0 0 0 ++ 0 0 0 0 0 0 0 0 0 0 0 0 ++ 0 0 0 0 0 0 0 0 0 0 0 0 ++ 0 0 0 0 0 0 0 0 0 0 0 0 ++ 0 0 0 0 0 0 10 10 10 30 30 30 ++ 74 74 74 58 58 58 2 2 6 42 42 42 ++ 2 2 6 22 22 22 231 231 231 253 253 253 ++253 253 253 253 253 253 253 253 253 253 253 253 ++253 253 253 253 253 253 253 253 253 250 250 250 ++253 253 253 253 253 253 253 253 253 253 253 253 ++253 253 253 253 253 253 253 253 253 253 253 253 ++253 253 253 253 253 253 253 253 253 253 253 253 ++253 253 253 253 253 253 253 253 253 253 253 253 ++253 253 253 246 246 246 46 46 46 38 38 38 ++ 42 42 42 14 14 14 38 38 38 14 14 14 ++ 2 2 6 2 2 6 2 2 6 6 6 6 ++ 86 86 86 46 46 46 14 14 14 0 0 0 ++ 0 0 0 0 0 0 0 0 0 0 0 0 ++ 0 0 0 0 0 0 0 0 0 0 0 0 ++ 0 0 0 0 0 0 0 0 0 0 0 0 ++ 0 0 0 0 0 0 0 0 0 0 0 0 ++ 0 0 0 0 0 0 0 0 0 0 0 0 ++ 0 0 0 0 0 0 0 0 0 0 0 0 ++ 0 0 0 0 0 0 0 0 0 0 0 0 ++ 0 0 0 6 6 6 14 14 14 42 42 42 ++ 90 90 90 18 18 18 18 18 18 26 26 26 ++ 2 2 6 116 116 116 253 253 253 253 253 253 ++253 253 253 253 253 253 253 253 253 253 253 253 ++253 253 253 253 253 253 250 250 250 238 238 238 ++253 253 253 253 253 253 253 253 253 253 253 253 ++253 253 253 253 253 253 253 253 253 253 253 253 ++253 253 253 253 253 253 253 253 253 253 253 253 ++253 253 253 253 253 253 253 253 253 253 253 253 ++253 253 253 253 253 253 94 94 94 6 6 6 ++ 2 2 6 2 2 6 10 10 10 34 34 34 ++ 2 2 6 2 2 6 2 2 6 2 2 6 ++ 74 74 74 58 58 58 22 22 22 6 6 6 ++ 0 0 0 0 0 0 0 0 0 0 0 0 ++ 0 0 0 0 0 0 0 0 0 0 0 0 ++ 0 0 0 0 0 0 0 0 0 0 0 0 ++ 0 0 0 0 0 0 0 0 0 0 0 0 ++ 0 0 0 0 0 0 0 0 0 0 0 0 ++ 0 0 0 0 0 0 0 0 0 0 0 0 ++ 0 0 0 0 0 0 0 0 0 0 0 0 ++ 0 0 0 10 10 10 26 26 26 66 66 66 ++ 82 82 82 2 2 6 38 38 38 6 6 6 ++ 14 14 14 210 210 210 253 253 253 253 253 253 ++253 253 253 253 253 253 253 253 253 253 253 253 ++253 253 253 253 253 253 246 246 246 242 242 242 ++253 253 253 253 253 253 253 253 253 253 253 253 ++253 253 253 253 253 253 253 253 253 253 253 253 ++253 253 253 253 253 253 253 253 253 253 253 253 ++253 253 253 253 253 253 253 253 253 253 253 253 ++253 253 253 253 253 253 144 144 144 2 2 6 ++ 2 2 6 2 2 6 2 2 6 46 46 46 ++ 2 2 6 2 2 6 2 2 6 2 2 6 ++ 42 42 42 74 74 74 30 30 30 10 10 10 ++ 0 0 0 0 0 0 0 0 0 0 0 0 ++ 0 0 0 0 0 0 0 0 0 0 0 0 ++ 0 0 0 0 0 0 0 0 0 0 0 0 ++ 0 0 0 0 0 0 0 0 0 0 0 0 ++ 0 0 0 0 0 0 0 0 0 0 0 0 ++ 0 0 0 0 0 0 0 0 0 0 0 0 ++ 0 0 0 0 0 0 0 0 0 0 0 0 ++ 6 6 6 14 14 14 42 42 42 90 90 90 ++ 26 26 26 6 6 6 42 42 42 2 2 6 ++ 74 74 74 250 250 250 253 253 253 253 253 253 ++253 253 253 253 253 253 253 253 253 253 253 253 ++253 253 253 253 253 253 242 242 242 242 242 242 ++253 253 253 253 253 253 253 253 253 253 253 253 ++253 253 253 253 253 253 253 253 253 253 253 253 ++253 253 253 253 253 253 253 253 253 253 253 253 ++253 253 253 253 253 253 253 253 253 253 253 253 ++253 253 253 253 253 253 182 182 182 2 2 6 ++ 2 2 6 2 2 6 2 2 6 46 46 46 ++ 2 2 6 2 2 6 2 2 6 2 2 6 ++ 10 10 10 86 86 86 38 38 38 10 10 10 ++ 0 0 0 0 0 0 0 0 0 0 0 0 ++ 0 0 0 0 0 0 0 0 0 0 0 0 ++ 0 0 0 0 0 0 0 0 0 0 0 0 ++ 0 0 0 0 0 0 0 0 0 0 0 0 ++ 0 0 0 0 0 0 0 0 0 0 0 0 ++ 0 0 0 0 0 0 0 0 0 0 0 0 ++ 0 0 0 0 0 0 0 0 0 0 0 0 ++ 10 10 10 26 26 26 66 66 66 82 82 82 ++ 2 2 6 22 22 22 18 18 18 2 2 6 ++149 149 149 253 253 253 253 253 253 253 253 253 ++253 253 253 253 253 253 253 253 253 253 253 253 ++253 253 253 253 253 253 234 234 234 242 242 242 ++253 253 253 253 253 253 253 253 253 253 253 253 ++253 253 253 253 253 253 253 253 253 253 253 253 ++253 253 253 253 253 253 253 253 253 253 253 253 ++253 253 253 253 253 253 253 253 253 253 253 253 ++253 253 253 253 253 253 206 206 206 2 2 6 ++ 2 2 6 2 2 6 2 2 6 38 38 38 ++ 2 2 6 2 2 6 2 2 6 2 2 6 ++ 6 6 6 86 86 86 46 46 46 14 14 14 ++ 0 0 0 0 0 0 0 0 0 0 0 0 ++ 0 0 0 0 0 0 0 0 0 0 0 0 ++ 0 0 0 0 0 0 0 0 0 0 0 0 ++ 0 0 0 0 0 0 0 0 0 0 0 0 ++ 0 0 0 0 0 0 0 0 0 0 0 0 ++ 0 0 0 0 0 0 0 0 0 0 0 0 ++ 0 0 0 0 0 0 0 0 0 6 6 6 ++ 18 18 18 46 46 46 86 86 86 18 18 18 ++ 2 2 6 34 34 34 10 10 10 6 6 6 ++210 210 210 253 253 253 253 253 253 253 253 253 ++253 253 253 253 253 253 253 253 253 253 253 253 ++253 253 253 253 253 253 234 234 234 242 242 242 ++253 253 253 253 253 253 253 253 253 253 253 253 ++253 253 253 253 253 253 253 253 253 253 253 253 ++253 253 253 253 253 253 253 253 253 253 253 253 ++253 253 253 253 253 253 253 253 253 253 253 253 ++253 253 253 253 253 253 221 221 221 6 6 6 ++ 2 2 6 2 2 6 6 6 6 30 30 30 ++ 2 2 6 2 2 6 2 2 6 2 2 6 ++ 2 2 6 82 82 82 54 54 54 18 18 18 ++ 6 6 6 0 0 0 0 0 0 0 0 0 ++ 0 0 0 0 0 0 0 0 0 0 0 0 ++ 0 0 0 0 0 0 0 0 0 0 0 0 ++ 0 0 0 0 0 0 0 0 0 0 0 0 ++ 0 0 0 0 0 0 0 0 0 0 0 0 ++ 0 0 0 0 0 0 0 0 0 0 0 0 ++ 0 0 0 0 0 0 0 0 0 10 10 10 ++ 26 26 26 66 66 66 62 62 62 2 2 6 ++ 2 2 6 38 38 38 10 10 10 26 26 26 ++238 238 238 253 253 253 253 253 253 253 253 253 ++253 253 253 253 253 253 253 253 253 253 253 253 ++253 253 253 253 253 253 231 231 231 238 238 238 ++253 253 253 253 253 253 253 253 253 253 253 253 ++253 253 253 253 253 253 253 253 253 253 253 253 ++253 253 253 253 253 253 253 253 253 253 253 253 ++253 253 253 253 253 253 253 253 253 253 253 253 ++253 253 253 253 253 253 231 231 231 6 6 6 ++ 2 2 6 2 2 6 10 10 10 30 30 30 ++ 2 2 6 2 2 6 2 2 6 2 2 6 ++ 2 2 6 66 66 66 58 58 58 22 22 22 ++ 6 6 6 0 0 0 0 0 0 0 0 0 ++ 0 0 0 0 0 0 0 0 0 0 0 0 ++ 0 0 0 0 0 0 0 0 0 0 0 0 ++ 0 0 0 0 0 0 0 0 0 0 0 0 ++ 0 0 0 0 0 0 0 0 0 0 0 0 ++ 0 0 0 0 0 0 0 0 0 0 0 0 ++ 0 0 0 0 0 0 0 0 0 10 10 10 ++ 38 38 38 78 78 78 6 6 6 2 2 6 ++ 2 2 6 46 46 46 14 14 14 42 42 42 ++246 246 246 253 253 253 253 253 253 253 253 253 ++253 253 253 253 253 253 253 253 253 253 253 253 ++253 253 253 253 253 253 231 231 231 242 242 242 ++253 253 253 253 253 253 253 253 253 253 253 253 ++253 253 253 253 253 253 253 253 253 253 253 253 ++253 253 253 253 253 253 253 253 253 253 253 253 ++253 253 253 253 253 253 253 253 253 253 253 253 ++253 253 253 253 253 253 234 234 234 10 10 10 ++ 2 2 6 2 2 6 22 22 22 14 14 14 ++ 2 2 6 2 2 6 2 2 6 2 2 6 ++ 2 2 6 66 66 66 62 62 62 22 22 22 ++ 6 6 6 0 0 0 0 0 0 0 0 0 ++ 0 0 0 0 0 0 0 0 0 0 0 0 ++ 0 0 0 0 0 0 0 0 0 0 0 0 ++ 0 0 0 0 0 0 0 0 0 0 0 0 ++ 0 0 0 0 0 0 0 0 0 0 0 0 ++ 0 0 0 0 0 0 0 0 0 0 0 0 ++ 0 0 0 0 0 0 6 6 6 18 18 18 ++ 50 50 50 74 74 74 2 2 6 2 2 6 ++ 14 14 14 70 70 70 34 34 34 62 62 62 ++250 250 250 253 253 253 253 253 253 253 253 253 ++253 253 253 253 253 253 253 253 253 253 253 253 ++253 253 253 253 253 253 231 231 231 246 246 246 ++253 253 253 253 253 253 253 253 253 253 253 253 ++253 253 253 253 253 253 253 253 253 253 253 253 ++253 253 253 253 253 253 253 253 253 253 253 253 ++253 253 253 253 253 253 253 253 253 253 253 253 ++253 253 253 253 253 253 234 234 234 14 14 14 ++ 2 2 6 2 2 6 30 30 30 2 2 6 ++ 2 2 6 2 2 6 2 2 6 2 2 6 ++ 2 2 6 66 66 66 62 62 62 22 22 22 ++ 6 6 6 0 0 0 0 0 0 0 0 0 ++ 0 0 0 0 0 0 0 0 0 0 0 0 ++ 0 0 0 0 0 0 0 0 0 0 0 0 ++ 0 0 0 0 0 0 0 0 0 0 0 0 ++ 0 0 0 0 0 0 0 0 0 0 0 0 ++ 0 0 0 0 0 0 0 0 0 0 0 0 ++ 0 0 0 0 0 0 6 6 6 18 18 18 ++ 54 54 54 62 62 62 2 2 6 2 2 6 ++ 2 2 6 30 30 30 46 46 46 70 70 70 ++250 250 250 253 253 253 253 253 253 253 253 253 ++253 253 253 253 253 253 253 253 253 253 253 253 ++253 253 253 253 253 253 231 231 231 246 246 246 ++253 253 253 253 253 253 253 253 253 253 253 253 ++253 253 253 253 253 253 253 253 253 253 253 253 ++253 253 253 253 253 253 253 253 253 253 253 253 ++253 253 253 253 253 253 253 253 253 253 253 253 ++253 253 253 253 253 253 226 226 226 10 10 10 ++ 2 2 6 6 6 6 30 30 30 2 2 6 ++ 2 2 6 2 2 6 2 2 6 2 2 6 ++ 2 2 6 66 66 66 58 58 58 22 22 22 ++ 6 6 6 0 0 0 0 0 0 0 0 0 ++ 0 0 0 0 0 0 0 0 0 0 0 0 ++ 0 0 0 0 0 0 0 0 0 0 0 0 ++ 0 0 0 0 0 0 0 0 0 0 0 0 ++ 0 0 0 0 0 0 0 0 0 0 0 0 ++ 0 0 0 0 0 0 0 0 0 0 0 0 ++ 0 0 0 0 0 0 6 6 6 22 22 22 ++ 58 58 58 62 62 62 2 2 6 2 2 6 ++ 2 2 6 2 2 6 30 30 30 78 78 78 ++250 250 250 253 253 253 253 253 253 253 253 253 ++253 253 253 253 253 253 253 253 253 253 253 253 ++253 253 253 253 253 253 231 231 231 246 246 246 ++253 253 253 253 253 253 253 253 253 253 253 253 ++253 253 253 253 253 253 253 253 253 253 253 253 ++253 253 253 253 253 253 253 253 253 253 253 253 ++253 253 253 253 253 253 253 253 253 253 253 253 ++253 253 253 253 253 253 206 206 206 2 2 6 ++ 22 22 22 34 34 34 18 14 6 22 22 22 ++ 26 26 26 18 18 18 6 6 6 2 2 6 ++ 2 2 6 82 82 82 54 54 54 18 18 18 ++ 6 6 6 0 0 0 0 0 0 0 0 0 ++ 0 0 0 0 0 0 0 0 0 0 0 0 ++ 0 0 0 0 0 0 0 0 0 0 0 0 ++ 0 0 0 0 0 0 0 0 0 0 0 0 ++ 0 0 0 0 0 0 0 0 0 0 0 0 ++ 0 0 0 0 0 0 0 0 0 0 0 0 ++ 0 0 0 0 0 0 6 6 6 26 26 26 ++ 62 62 62 106 106 106 74 54 14 185 133 11 ++210 162 10 121 92 8 6 6 6 62 62 62 ++238 238 238 253 253 253 253 253 253 253 253 253 ++253 253 253 253 253 253 253 253 253 253 253 253 ++253 253 253 253 253 253 231 231 231 246 246 246 ++253 253 253 253 253 253 253 253 253 253 253 253 ++253 253 253 253 253 253 253 253 253 253 253 253 ++253 253 253 253 253 253 253 253 253 253 253 253 ++253 253 253 253 253 253 253 253 253 253 253 253 ++253 253 253 253 253 253 158 158 158 18 18 18 ++ 14 14 14 2 2 6 2 2 6 2 2 6 ++ 6 6 6 18 18 18 66 66 66 38 38 38 ++ 6 6 6 94 94 94 50 50 50 18 18 18 ++ 6 6 6 0 0 0 0 0 0 0 0 0 ++ 0 0 0 0 0 0 0 0 0 0 0 0 ++ 0 0 0 0 0 0 0 0 0 0 0 0 ++ 0 0 0 0 0 0 0 0 0 0 0 0 ++ 0 0 0 0 0 0 0 0 0 0 0 0 ++ 0 0 0 0 0 0 0 0 0 6 6 6 ++ 10 10 10 10 10 10 18 18 18 38 38 38 ++ 78 78 78 142 134 106 216 158 10 242 186 14 ++246 190 14 246 190 14 156 118 10 10 10 10 ++ 90 90 90 238 238 238 253 253 253 253 253 253 ++253 253 253 253 253 253 253 253 253 253 253 253 ++253 253 253 253 253 253 231 231 231 250 250 250 ++253 253 253 253 253 253 253 253 253 253 253 253 ++253 253 253 253 253 253 253 253 253 253 253 253 ++253 253 253 253 253 253 253 253 253 253 253 253 ++253 253 253 253 253 253 253 253 253 246 230 190 ++238 204 91 238 204 91 181 142 44 37 26 9 ++ 2 2 6 2 2 6 2 2 6 2 2 6 ++ 2 2 6 2 2 6 38 38 38 46 46 46 ++ 26 26 26 106 106 106 54 54 54 18 18 18 ++ 6 6 6 0 0 0 0 0 0 0 0 0 ++ 0 0 0 0 0 0 0 0 0 0 0 0 ++ 0 0 0 0 0 0 0 0 0 0 0 0 ++ 0 0 0 0 0 0 0 0 0 0 0 0 ++ 0 0 0 0 0 0 0 0 0 0 0 0 ++ 0 0 0 6 6 6 14 14 14 22 22 22 ++ 30 30 30 38 38 38 50 50 50 70 70 70 ++106 106 106 190 142 34 226 170 11 242 186 14 ++246 190 14 246 190 14 246 190 14 154 114 10 ++ 6 6 6 74 74 74 226 226 226 253 253 253 ++253 253 253 253 253 253 253 253 253 253 253 253 ++253 253 253 253 253 253 231 231 231 250 250 250 ++253 253 253 253 253 253 253 253 253 253 253 253 ++253 253 253 253 253 253 253 253 253 253 253 253 ++253 253 253 253 253 253 253 253 253 253 253 253 ++253 253 253 253 253 253 253 253 253 228 184 62 ++241 196 14 241 208 19 232 195 16 38 30 10 ++ 2 2 6 2 2 6 2 2 6 2 2 6 ++ 2 2 6 6 6 6 30 30 30 26 26 26 ++203 166 17 154 142 90 66 66 66 26 26 26 ++ 6 6 6 0 0 0 0 0 0 0 0 0 ++ 0 0 0 0 0 0 0 0 0 0 0 0 ++ 0 0 0 0 0 0 0 0 0 0 0 0 ++ 0 0 0 0 0 0 0 0 0 0 0 0 ++ 0 0 0 0 0 0 0 0 0 0 0 0 ++ 6 6 6 18 18 18 38 38 38 58 58 58 ++ 78 78 78 86 86 86 101 101 101 123 123 123 ++175 146 61 210 150 10 234 174 13 246 186 14 ++246 190 14 246 190 14 246 190 14 238 190 10 ++102 78 10 2 2 6 46 46 46 198 198 198 ++253 253 253 253 253 253 253 253 253 253 253 253 ++253 253 253 253 253 253 234 234 234 242 242 242 ++253 253 253 253 253 253 253 253 253 253 253 253 ++253 253 253 253 253 253 253 253 253 253 253 253 ++253 253 253 253 253 253 253 253 253 253 253 253 ++253 253 253 253 253 253 253 253 253 224 178 62 ++242 186 14 241 196 14 210 166 10 22 18 6 ++ 2 2 6 2 2 6 2 2 6 2 2 6 ++ 2 2 6 2 2 6 6 6 6 121 92 8 ++238 202 15 232 195 16 82 82 82 34 34 34 ++ 10 10 10 0 0 0 0 0 0 0 0 0 ++ 0 0 0 0 0 0 0 0 0 0 0 0 ++ 0 0 0 0 0 0 0 0 0 0 0 0 ++ 0 0 0 0 0 0 0 0 0 0 0 0 ++ 0 0 0 0 0 0 0 0 0 0 0 0 ++ 14 14 14 38 38 38 70 70 70 154 122 46 ++190 142 34 200 144 11 197 138 11 197 138 11 ++213 154 11 226 170 11 242 186 14 246 190 14 ++246 190 14 246 190 14 246 190 14 246 190 14 ++225 175 15 46 32 6 2 2 6 22 22 22 ++158 158 158 250 250 250 253 253 253 253 253 253 ++253 253 253 253 253 253 253 253 253 253 253 253 ++253 253 253 253 253 253 253 253 253 253 253 253 ++253 253 253 253 253 253 253 253 253 253 253 253 ++253 253 253 253 253 253 253 253 253 253 253 253 ++253 253 253 250 250 250 242 242 242 224 178 62 ++239 182 13 236 186 11 213 154 11 46 32 6 ++ 2 2 6 2 2 6 2 2 6 2 2 6 ++ 2 2 6 2 2 6 61 42 6 225 175 15 ++238 190 10 236 186 11 112 100 78 42 42 42 ++ 14 14 14 0 0 0 0 0 0 0 0 0 ++ 0 0 0 0 0 0 0 0 0 0 0 0 ++ 0 0 0 0 0 0 0 0 0 0 0 0 ++ 0 0 0 0 0 0 0 0 0 0 0 0 ++ 0 0 0 0 0 0 0 0 0 6 6 6 ++ 22 22 22 54 54 54 154 122 46 213 154 11 ++226 170 11 230 174 11 226 170 11 226 170 11 ++236 178 12 242 186 14 246 190 14 246 190 14 ++246 190 14 246 190 14 246 190 14 246 190 14 ++241 196 14 184 144 12 10 10 10 2 2 6 ++ 6 6 6 116 116 116 242 242 242 253 253 253 ++253 253 253 253 253 253 253 253 253 253 253 253 ++253 253 253 253 253 253 253 253 253 253 253 253 ++253 253 253 253 253 253 253 253 253 253 253 253 ++253 253 253 253 253 253 253 253 253 253 253 253 ++253 253 253 231 231 231 198 198 198 214 170 54 ++236 178 12 236 178 12 210 150 10 137 92 6 ++ 18 14 6 2 2 6 2 2 6 2 2 6 ++ 6 6 6 70 47 6 200 144 11 236 178 12 ++239 182 13 239 182 13 124 112 88 58 58 58 ++ 22 22 22 6 6 6 0 0 0 0 0 0 ++ 0 0 0 0 0 0 0 0 0 0 0 0 ++ 0 0 0 0 0 0 0 0 0 0 0 0 ++ 0 0 0 0 0 0 0 0 0 0 0 0 ++ 0 0 0 0 0 0 0 0 0 10 10 10 ++ 30 30 30 70 70 70 180 133 36 226 170 11 ++239 182 13 242 186 14 242 186 14 246 186 14 ++246 190 14 246 190 14 246 190 14 246 190 14 ++246 190 14 246 190 14 246 190 14 246 190 14 ++246 190 14 232 195 16 98 70 6 2 2 6 ++ 2 2 6 2 2 6 66 66 66 221 221 221 ++253 253 253 253 253 253 253 253 253 253 253 253 ++253 253 253 253 253 253 253 253 253 253 253 253 ++253 253 253 253 253 253 253 253 253 253 253 253 ++253 253 253 253 253 253 253 253 253 253 253 253 ++253 253 253 206 206 206 198 198 198 214 166 58 ++230 174 11 230 174 11 216 158 10 192 133 9 ++163 110 8 116 81 8 102 78 10 116 81 8 ++167 114 7 197 138 11 226 170 11 239 182 13 ++242 186 14 242 186 14 162 146 94 78 78 78 ++ 34 34 34 14 14 14 6 6 6 0 0 0 ++ 0 0 0 0 0 0 0 0 0 0 0 0 ++ 0 0 0 0 0 0 0 0 0 0 0 0 ++ 0 0 0 0 0 0 0 0 0 0 0 0 ++ 0 0 0 0 0 0 0 0 0 6 6 6 ++ 30 30 30 78 78 78 190 142 34 226 170 11 ++239 182 13 246 190 14 246 190 14 246 190 14 ++246 190 14 246 190 14 246 190 14 246 190 14 ++246 190 14 246 190 14 246 190 14 246 190 14 ++246 190 14 241 196 14 203 166 17 22 18 6 ++ 2 2 6 2 2 6 2 2 6 38 38 38 ++218 218 218 253 253 253 253 253 253 253 253 253 ++253 253 253 253 253 253 253 253 253 253 253 253 ++253 253 253 253 253 253 253 253 253 253 253 253 ++253 253 253 253 253 253 253 253 253 253 253 253 ++250 250 250 206 206 206 198 198 198 202 162 69 ++226 170 11 236 178 12 224 166 10 210 150 10 ++200 144 11 197 138 11 192 133 9 197 138 11 ++210 150 10 226 170 11 242 186 14 246 190 14 ++246 190 14 246 186 14 225 175 15 124 112 88 ++ 62 62 62 30 30 30 14 14 14 6 6 6 ++ 0 0 0 0 0 0 0 0 0 0 0 0 ++ 0 0 0 0 0 0 0 0 0 0 0 0 ++ 0 0 0 0 0 0 0 0 0 0 0 0 ++ 0 0 0 0 0 0 0 0 0 10 10 10 ++ 30 30 30 78 78 78 174 135 50 224 166 10 ++239 182 13 246 190 14 246 190 14 246 190 14 ++246 190 14 246 190 14 246 190 14 246 190 14 ++246 190 14 246 190 14 246 190 14 246 190 14 ++246 190 14 246 190 14 241 196 14 139 102 15 ++ 2 2 6 2 2 6 2 2 6 2 2 6 ++ 78 78 78 250 250 250 253 253 253 253 253 253 ++253 253 253 253 253 253 253 253 253 253 253 253 ++253 253 253 253 253 253 253 253 253 253 253 253 ++253 253 253 253 253 253 253 253 253 253 253 253 ++250 250 250 214 214 214 198 198 198 190 150 46 ++219 162 10 236 178 12 234 174 13 224 166 10 ++216 158 10 213 154 11 213 154 11 216 158 10 ++226 170 11 239 182 13 246 190 14 246 190 14 ++246 190 14 246 190 14 242 186 14 206 162 42 ++101 101 101 58 58 58 30 30 30 14 14 14 ++ 6 6 6 0 0 0 0 0 0 0 0 0 ++ 0 0 0 0 0 0 0 0 0 0 0 0 ++ 0 0 0 0 0 0 0 0 0 0 0 0 ++ 0 0 0 0 0 0 0 0 0 10 10 10 ++ 30 30 30 74 74 74 174 135 50 216 158 10 ++236 178 12 246 190 14 246 190 14 246 190 14 ++246 190 14 246 190 14 246 190 14 246 190 14 ++246 190 14 246 190 14 246 190 14 246 190 14 ++246 190 14 246 190 14 241 196 14 226 184 13 ++ 61 42 6 2 2 6 2 2 6 2 2 6 ++ 22 22 22 238 238 238 253 253 253 253 253 253 ++253 253 253 253 253 253 253 253 253 253 253 253 ++253 253 253 253 253 253 253 253 253 253 253 253 ++253 253 253 253 253 253 253 253 253 253 253 253 ++253 253 253 226 226 226 187 187 187 180 133 36 ++216 158 10 236 178 12 239 182 13 236 178 12 ++230 174 11 226 170 11 226 170 11 230 174 11 ++236 178 12 242 186 14 246 190 14 246 190 14 ++246 190 14 246 190 14 246 186 14 239 182 13 ++206 162 42 106 106 106 66 66 66 34 34 34 ++ 14 14 14 6 6 6 0 0 0 0 0 0 ++ 0 0 0 0 0 0 0 0 0 0 0 0 ++ 0 0 0 0 0 0 0 0 0 0 0 0 ++ 0 0 0 0 0 0 0 0 0 6 6 6 ++ 26 26 26 70 70 70 163 133 67 213 154 11 ++236 178 12 246 190 14 246 190 14 246 190 14 ++246 190 14 246 190 14 246 190 14 246 190 14 ++246 190 14 246 190 14 246 190 14 246 190 14 ++246 190 14 246 190 14 246 190 14 241 196 14 ++190 146 13 18 14 6 2 2 6 2 2 6 ++ 46 46 46 246 246 246 253 253 253 253 253 253 ++253 253 253 253 253 253 253 253 253 253 253 253 ++253 253 253 253 253 253 253 253 253 253 253 253 ++253 253 253 253 253 253 253 253 253 253 253 253 ++253 253 253 221 221 221 86 86 86 156 107 11 ++216 158 10 236 178 12 242 186 14 246 186 14 ++242 186 14 239 182 13 239 182 13 242 186 14 ++242 186 14 246 186 14 246 190 14 246 190 14 ++246 190 14 246 190 14 246 190 14 246 190 14 ++242 186 14 225 175 15 142 122 72 66 66 66 ++ 30 30 30 10 10 10 0 0 0 0 0 0 ++ 0 0 0 0 0 0 0 0 0 0 0 0 ++ 0 0 0 0 0 0 0 0 0 0 0 0 ++ 0 0 0 0 0 0 0 0 0 6 6 6 ++ 26 26 26 70 70 70 163 133 67 210 150 10 ++236 178 12 246 190 14 246 190 14 246 190 14 ++246 190 14 246 190 14 246 190 14 246 190 14 ++246 190 14 246 190 14 246 190 14 246 190 14 ++246 190 14 246 190 14 246 190 14 246 190 14 ++232 195 16 121 92 8 34 34 34 106 106 106 ++221 221 221 253 253 253 253 253 253 253 253 253 ++253 253 253 253 253 253 253 253 253 253 253 253 ++253 253 253 253 253 253 253 253 253 253 253 253 ++253 253 253 253 253 253 253 253 253 253 253 253 ++242 242 242 82 82 82 18 14 6 163 110 8 ++216 158 10 236 178 12 242 186 14 246 190 14 ++246 190 14 246 190 14 246 190 14 246 190 14 ++246 190 14 246 190 14 246 190 14 246 190 14 ++246 190 14 246 190 14 246 190 14 246 190 14 ++246 190 14 246 190 14 242 186 14 163 133 67 ++ 46 46 46 18 18 18 6 6 6 0 0 0 ++ 0 0 0 0 0 0 0 0 0 0 0 0 ++ 0 0 0 0 0 0 0 0 0 0 0 0 ++ 0 0 0 0 0 0 0 0 0 10 10 10 ++ 30 30 30 78 78 78 163 133 67 210 150 10 ++236 178 12 246 186 14 246 190 14 246 190 14 ++246 190 14 246 190 14 246 190 14 246 190 14 ++246 190 14 246 190 14 246 190 14 246 190 14 ++246 190 14 246 190 14 246 190 14 246 190 14 ++241 196 14 215 174 15 190 178 144 253 253 253 ++253 253 253 253 253 253 253 253 253 253 253 253 ++253 253 253 253 253 253 253 253 253 253 253 253 ++253 253 253 253 253 253 253 253 253 253 253 253 ++253 253 253 253 253 253 253 253 253 218 218 218 ++ 58 58 58 2 2 6 22 18 6 167 114 7 ++216 158 10 236 178 12 246 186 14 246 190 14 ++246 190 14 246 190 14 246 190 14 246 190 14 ++246 190 14 246 190 14 246 190 14 246 190 14 ++246 190 14 246 190 14 246 190 14 246 190 14 ++246 190 14 246 186 14 242 186 14 190 150 46 ++ 54 54 54 22 22 22 6 6 6 0 0 0 ++ 0 0 0 0 0 0 0 0 0 0 0 0 ++ 0 0 0 0 0 0 0 0 0 0 0 0 ++ 0 0 0 0 0 0 0 0 0 14 14 14 ++ 38 38 38 86 86 86 180 133 36 213 154 11 ++236 178 12 246 186 14 246 190 14 246 190 14 ++246 190 14 246 190 14 246 190 14 246 190 14 ++246 190 14 246 190 14 246 190 14 246 190 14 ++246 190 14 246 190 14 246 190 14 246 190 14 ++246 190 14 232 195 16 190 146 13 214 214 214 ++253 253 253 253 253 253 253 253 253 253 253 253 ++253 253 253 253 253 253 253 253 253 253 253 253 ++253 253 253 253 253 253 253 253 253 253 253 253 ++253 253 253 250 250 250 170 170 170 26 26 26 ++ 2 2 6 2 2 6 37 26 9 163 110 8 ++219 162 10 239 182 13 246 186 14 246 190 14 ++246 190 14 246 190 14 246 190 14 246 190 14 ++246 190 14 246 190 14 246 190 14 246 190 14 ++246 190 14 246 190 14 246 190 14 246 190 14 ++246 186 14 236 178 12 224 166 10 142 122 72 ++ 46 46 46 18 18 18 6 6 6 0 0 0 ++ 0 0 0 0 0 0 0 0 0 0 0 0 ++ 0 0 0 0 0 0 0 0 0 0 0 0 ++ 0 0 0 0 0 0 6 6 6 18 18 18 ++ 50 50 50 109 106 95 192 133 9 224 166 10 ++242 186 14 246 190 14 246 190 14 246 190 14 ++246 190 14 246 190 14 246 190 14 246 190 14 ++246 190 14 246 190 14 246 190 14 246 190 14 ++246 190 14 246 190 14 246 190 14 246 190 14 ++242 186 14 226 184 13 210 162 10 142 110 46 ++226 226 226 253 253 253 253 253 253 253 253 253 ++253 253 253 253 253 253 253 253 253 253 253 253 ++253 253 253 253 253 253 253 253 253 253 253 253 ++198 198 198 66 66 66 2 2 6 2 2 6 ++ 2 2 6 2 2 6 50 34 6 156 107 11 ++219 162 10 239 182 13 246 186 14 246 190 14 ++246 190 14 246 190 14 246 190 14 246 190 14 ++246 190 14 246 190 14 246 190 14 246 190 14 ++246 190 14 246 190 14 246 190 14 242 186 14 ++234 174 13 213 154 11 154 122 46 66 66 66 ++ 30 30 30 10 10 10 0 0 0 0 0 0 ++ 0 0 0 0 0 0 0 0 0 0 0 0 ++ 0 0 0 0 0 0 0 0 0 0 0 0 ++ 0 0 0 0 0 0 6 6 6 22 22 22 ++ 58 58 58 154 121 60 206 145 10 234 174 13 ++242 186 14 246 186 14 246 190 14 246 190 14 ++246 190 14 246 190 14 246 190 14 246 190 14 ++246 190 14 246 190 14 246 190 14 246 190 14 ++246 190 14 246 190 14 246 190 14 246 190 14 ++246 186 14 236 178 12 210 162 10 163 110 8 ++ 61 42 6 138 138 138 218 218 218 250 250 250 ++253 253 253 253 253 253 253 253 253 250 250 250 ++242 242 242 210 210 210 144 144 144 66 66 66 ++ 6 6 6 2 2 6 2 2 6 2 2 6 ++ 2 2 6 2 2 6 61 42 6 163 110 8 ++216 158 10 236 178 12 246 190 14 246 190 14 ++246 190 14 246 190 14 246 190 14 246 190 14 ++246 190 14 246 190 14 246 190 14 246 190 14 ++246 190 14 239 182 13 230 174 11 216 158 10 ++190 142 34 124 112 88 70 70 70 38 38 38 ++ 18 18 18 6 6 6 0 0 0 0 0 0 ++ 0 0 0 0 0 0 0 0 0 0 0 0 ++ 0 0 0 0 0 0 0 0 0 0 0 0 ++ 0 0 0 0 0 0 6 6 6 22 22 22 ++ 62 62 62 168 124 44 206 145 10 224 166 10 ++236 178 12 239 182 13 242 186 14 242 186 14 ++246 186 14 246 190 14 246 190 14 246 190 14 ++246 190 14 246 190 14 246 190 14 246 190 14 ++246 190 14 246 190 14 246 190 14 246 190 14 ++246 190 14 236 178 12 216 158 10 175 118 6 ++ 80 54 7 2 2 6 6 6 6 30 30 30 ++ 54 54 54 62 62 62 50 50 50 38 38 38 ++ 14 14 14 2 2 6 2 2 6 2 2 6 ++ 2 2 6 2 2 6 2 2 6 2 2 6 ++ 2 2 6 6 6 6 80 54 7 167 114 7 ++213 154 11 236 178 12 246 190 14 246 190 14 ++246 190 14 246 190 14 246 190 14 246 190 14 ++246 190 14 242 186 14 239 182 13 239 182 13 ++230 174 11 210 150 10 174 135 50 124 112 88 ++ 82 82 82 54 54 54 34 34 34 18 18 18 ++ 6 6 6 0 0 0 0 0 0 0 0 0 ++ 0 0 0 0 0 0 0 0 0 0 0 0 ++ 0 0 0 0 0 0 0 0 0 0 0 0 ++ 0 0 0 0 0 0 6 6 6 18 18 18 ++ 50 50 50 158 118 36 192 133 9 200 144 11 ++216 158 10 219 162 10 224 166 10 226 170 11 ++230 174 11 236 178 12 239 182 13 239 182 13 ++242 186 14 246 186 14 246 190 14 246 190 14 ++246 190 14 246 190 14 246 190 14 246 190 14 ++246 186 14 230 174 11 210 150 10 163 110 8 ++104 69 6 10 10 10 2 2 6 2 2 6 ++ 2 2 6 2 2 6 2 2 6 2 2 6 ++ 2 2 6 2 2 6 2 2 6 2 2 6 ++ 2 2 6 2 2 6 2 2 6 2 2 6 ++ 2 2 6 6 6 6 91 60 6 167 114 7 ++206 145 10 230 174 11 242 186 14 246 190 14 ++246 190 14 246 190 14 246 186 14 242 186 14 ++239 182 13 230 174 11 224 166 10 213 154 11 ++180 133 36 124 112 88 86 86 86 58 58 58 ++ 38 38 38 22 22 22 10 10 10 6 6 6 ++ 0 0 0 0 0 0 0 0 0 0 0 0 ++ 0 0 0 0 0 0 0 0 0 0 0 0 ++ 0 0 0 0 0 0 0 0 0 0 0 0 ++ 0 0 0 0 0 0 0 0 0 14 14 14 ++ 34 34 34 70 70 70 138 110 50 158 118 36 ++167 114 7 180 123 7 192 133 9 197 138 11 ++200 144 11 206 145 10 213 154 11 219 162 10 ++224 166 10 230 174 11 239 182 13 242 186 14 ++246 186 14 246 186 14 246 186 14 246 186 14 ++239 182 13 216 158 10 185 133 11 152 99 6 ++104 69 6 18 14 6 2 2 6 2 2 6 ++ 2 2 6 2 2 6 2 2 6 2 2 6 ++ 2 2 6 2 2 6 2 2 6 2 2 6 ++ 2 2 6 2 2 6 2 2 6 2 2 6 ++ 2 2 6 6 6 6 80 54 7 152 99 6 ++192 133 9 219 162 10 236 178 12 239 182 13 ++246 186 14 242 186 14 239 182 13 236 178 12 ++224 166 10 206 145 10 192 133 9 154 121 60 ++ 94 94 94 62 62 62 42 42 42 22 22 22 ++ 14 14 14 6 6 6 0 0 0 0 0 0 ++ 0 0 0 0 0 0 0 0 0 0 0 0 ++ 0 0 0 0 0 0 0 0 0 0 0 0 ++ 0 0 0 0 0 0 0 0 0 0 0 0 ++ 0 0 0 0 0 0 0 0 0 6 6 6 ++ 18 18 18 34 34 34 58 58 58 78 78 78 ++101 98 89 124 112 88 142 110 46 156 107 11 ++163 110 8 167 114 7 175 118 6 180 123 7 ++185 133 11 197 138 11 210 150 10 219 162 10 ++226 170 11 236 178 12 236 178 12 234 174 13 ++219 162 10 197 138 11 163 110 8 130 83 6 ++ 91 60 6 10 10 10 2 2 6 2 2 6 ++ 18 18 18 38 38 38 38 38 38 38 38 38 ++ 38 38 38 38 38 38 38 38 38 38 38 38 ++ 38 38 38 38 38 38 26 26 26 2 2 6 ++ 2 2 6 6 6 6 70 47 6 137 92 6 ++175 118 6 200 144 11 219 162 10 230 174 11 ++234 174 13 230 174 11 219 162 10 210 150 10 ++192 133 9 163 110 8 124 112 88 82 82 82 ++ 50 50 50 30 30 30 14 14 14 6 6 6 ++ 0 0 0 0 0 0 0 0 0 0 0 0 ++ 0 0 0 0 0 0 0 0 0 0 0 0 ++ 0 0 0 0 0 0 0 0 0 0 0 0 ++ 0 0 0 0 0 0 0 0 0 0 0 0 ++ 0 0 0 0 0 0 0 0 0 0 0 0 ++ 6 6 6 14 14 14 22 22 22 34 34 34 ++ 42 42 42 58 58 58 74 74 74 86 86 86 ++101 98 89 122 102 70 130 98 46 121 87 25 ++137 92 6 152 99 6 163 110 8 180 123 7 ++185 133 11 197 138 11 206 145 10 200 144 11 ++180 123 7 156 107 11 130 83 6 104 69 6 ++ 50 34 6 54 54 54 110 110 110 101 98 89 ++ 86 86 86 82 82 82 78 78 78 78 78 78 ++ 78 78 78 78 78 78 78 78 78 78 78 78 ++ 78 78 78 82 82 82 86 86 86 94 94 94 ++106 106 106 101 101 101 86 66 34 124 80 6 ++156 107 11 180 123 7 192 133 9 200 144 11 ++206 145 10 200 144 11 192 133 9 175 118 6 ++139 102 15 109 106 95 70 70 70 42 42 42 ++ 22 22 22 10 10 10 0 0 0 0 0 0 ++ 0 0 0 0 0 0 0 0 0 0 0 0 ++ 0 0 0 0 0 0 0 0 0 0 0 0 ++ 0 0 0 0 0 0 0 0 0 0 0 0 ++ 0 0 0 0 0 0 0 0 0 0 0 0 ++ 0 0 0 0 0 0 0 0 0 0 0 0 ++ 0 0 0 0 0 0 6 6 6 10 10 10 ++ 14 14 14 22 22 22 30 30 30 38 38 38 ++ 50 50 50 62 62 62 74 74 74 90 90 90 ++101 98 89 112 100 78 121 87 25 124 80 6 ++137 92 6 152 99 6 152 99 6 152 99 6 ++138 86 6 124 80 6 98 70 6 86 66 30 ++101 98 89 82 82 82 58 58 58 46 46 46 ++ 38 38 38 34 34 34 34 34 34 34 34 34 ++ 34 34 34 34 34 34 34 34 34 34 34 34 ++ 34 34 34 34 34 34 38 38 38 42 42 42 ++ 54 54 54 82 82 82 94 86 76 91 60 6 ++134 86 6 156 107 11 167 114 7 175 118 6 ++175 118 6 167 114 7 152 99 6 121 87 25 ++101 98 89 62 62 62 34 34 34 18 18 18 ++ 6 6 6 0 0 0 0 0 0 0 0 0 ++ 0 0 0 0 0 0 0 0 0 0 0 0 ++ 0 0 0 0 0 0 0 0 0 0 0 0 ++ 0 0 0 0 0 0 0 0 0 0 0 0 ++ 0 0 0 0 0 0 0 0 0 0 0 0 ++ 0 0 0 0 0 0 0 0 0 0 0 0 ++ 0 0 0 0 0 0 0 0 0 0 0 0 ++ 0 0 0 6 6 6 6 6 6 10 10 10 ++ 18 18 18 22 22 22 30 30 30 42 42 42 ++ 50 50 50 66 66 66 86 86 86 101 98 89 ++106 86 58 98 70 6 104 69 6 104 69 6 ++104 69 6 91 60 6 82 62 34 90 90 90 ++ 62 62 62 38 38 38 22 22 22 14 14 14 ++ 10 10 10 10 10 10 10 10 10 10 10 10 ++ 10 10 10 10 10 10 6 6 6 10 10 10 ++ 10 10 10 10 10 10 10 10 10 14 14 14 ++ 22 22 22 42 42 42 70 70 70 89 81 66 ++ 80 54 7 104 69 6 124 80 6 137 92 6 ++134 86 6 116 81 8 100 82 52 86 86 86 ++ 58 58 58 30 30 30 14 14 14 6 6 6 ++ 0 0 0 0 0 0 0 0 0 0 0 0 ++ 0 0 0 0 0 0 0 0 0 0 0 0 ++ 0 0 0 0 0 0 0 0 0 0 0 0 ++ 0 0 0 0 0 0 0 0 0 0 0 0 ++ 0 0 0 0 0 0 0 0 0 0 0 0 ++ 0 0 0 0 0 0 0 0 0 0 0 0 ++ 0 0 0 0 0 0 0 0 0 0 0 0 ++ 0 0 0 0 0 0 0 0 0 0 0 0 ++ 0 0 0 6 6 6 10 10 10 14 14 14 ++ 18 18 18 26 26 26 38 38 38 54 54 54 ++ 70 70 70 86 86 86 94 86 76 89 81 66 ++ 89 81 66 86 86 86 74 74 74 50 50 50 ++ 30 30 30 14 14 14 6 6 6 0 0 0 ++ 0 0 0 0 0 0 0 0 0 0 0 0 ++ 0 0 0 0 0 0 0 0 0 0 0 0 ++ 0 0 0 0 0 0 0 0 0 0 0 0 ++ 6 6 6 18 18 18 34 34 34 58 58 58 ++ 82 82 82 89 81 66 89 81 66 89 81 66 ++ 94 86 66 94 86 76 74 74 74 50 50 50 ++ 26 26 26 14 14 14 6 6 6 0 0 0 ++ 0 0 0 0 0 0 0 0 0 0 0 0 ++ 0 0 0 0 0 0 0 0 0 0 0 0 ++ 0 0 0 0 0 0 0 0 0 0 0 0 ++ 0 0 0 0 0 0 0 0 0 0 0 0 ++ 0 0 0 0 0 0 0 0 0 0 0 0 ++ 0 0 0 0 0 0 0 0 0 0 0 0 ++ 0 0 0 0 0 0 0 0 0 0 0 0 ++ 0 0 0 0 0 0 0 0 0 0 0 0 ++ 0 0 0 0 0 0 0 0 0 0 0 0 ++ 6 6 6 6 6 6 14 14 14 18 18 18 ++ 30 30 30 38 38 38 46 46 46 54 54 54 ++ 50 50 50 42 42 42 30 30 30 18 18 18 ++ 10 10 10 0 0 0 0 0 0 0 0 0 ++ 0 0 0 0 0 0 0 0 0 0 0 0 ++ 0 0 0 0 0 0 0 0 0 0 0 0 ++ 0 0 0 0 0 0 0 0 0 0 0 0 ++ 0 0 0 6 6 6 14 14 14 26 26 26 ++ 38 38 38 50 50 50 58 58 58 58 58 58 ++ 54 54 54 42 42 42 30 30 30 18 18 18 ++ 10 10 10 0 0 0 0 0 0 0 0 0 ++ 0 0 0 0 0 0 0 0 0 0 0 0 ++ 0 0 0 0 0 0 0 0 0 0 0 0 ++ 0 0 0 0 0 0 0 0 0 0 0 0 ++ 0 0 0 0 0 0 0 0 0 0 0 0 ++ 0 0 0 0 0 0 0 0 0 0 0 0 ++ 0 0 0 0 0 0 0 0 0 0 0 0 ++ 0 0 0 0 0 0 0 0 0 0 0 0 ++ 0 0 0 0 0 0 0 0 0 0 0 0 ++ 0 0 0 0 0 0 0 0 0 0 0 0 ++ 0 0 0 0 0 0 0 0 0 6 6 6 ++ 6 6 6 10 10 10 14 14 14 18 18 18 ++ 18 18 18 14 14 14 10 10 10 6 6 6 ++ 0 0 0 0 0 0 0 0 0 0 0 0 ++ 0 0 0 0 0 0 0 0 0 0 0 0 ++ 0 0 0 0 0 0 0 0 0 0 0 0 ++ 0 0 0 0 0 0 0 0 0 0 0 0 ++ 0 0 0 0 0 0 0 0 0 6 6 6 ++ 14 14 14 18 18 18 22 22 22 22 22 22 ++ 18 18 18 14 14 14 10 10 10 6 6 6 ++ 0 0 0 0 0 0 0 0 0 0 0 0 ++ 0 0 0 0 0 0 0 0 0 0 0 0 ++ 0 0 0 0 0 0 0 0 0 0 0 0 ++ 0 0 0 0 0 0 0 0 0 0 0 0 ++ 0 0 0 0 0 0 0 0 0 0 0 0 +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/drivers/video/logo/logo_linux_vga16.ppm linux-2.6.29-rc3.owrt/drivers/video/logo/logo_linux_vga16.ppm +--- linux-2.6.29.owrt/drivers/video/logo/logo_linux_vga16.ppm 2009-05-10 22:04:38.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/drivers/video/logo/logo_linux_vga16.ppm 2009-05-10 23:48:29.000000000 +0200 +@@ -1,2739 +1,1604 @@ + P3 +-142 114 ++# Standard 16-color Linux logo ++80 80 + 255 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 85 85 85 0 0 0 85 85 85 0 0 0 +-85 85 85 0 0 0 85 85 85 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 85 85 85 85 85 85 85 85 85 +-85 85 85 85 85 85 0 0 0 85 85 85 0 0 0 85 85 85 +-0 0 0 0 0 0 0 0 0 0 0 0 85 85 85 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-85 85 85 85 85 85 85 85 85 0 0 0 85 85 85 85 85 85 +-0 0 0 85 85 85 0 0 0 85 85 85 0 0 0 0 0 0 +-85 85 85 0 0 0 85 85 85 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 85 85 85 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 85 85 85 +-0 0 0 0 0 0 0 0 0 0 0 0 85 85 85 85 85 85 +-85 85 85 85 85 85 85 85 85 85 85 85 85 85 85 0 0 0 +-85 85 85 85 85 85 0 0 0 85 85 85 0 0 0 85 85 85 +-0 0 0 0 0 0 0 0 0 0 0 0 85 85 85 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 85 85 85 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 85 85 85 0 0 0 +-85 85 85 0 0 0 85 85 85 85 85 85 85 85 85 85 85 85 +-0 0 0 85 85 85 85 85 85 0 0 0 85 85 85 85 85 85 +-0 0 0 85 85 85 0 0 0 85 85 85 0 0 0 0 0 0 +-0 0 0 0 0 0 85 85 85 0 0 0 0 0 0 0 0 0 +-85 85 85 0 0 0 85 85 85 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 85 85 85 85 85 85 +-85 85 85 85 85 85 85 85 85 85 85 85 85 85 85 85 85 85 +-85 85 85 85 85 85 0 0 0 85 85 85 0 0 0 85 85 85 +-0 0 0 0 0 0 0 0 0 0 0 0 85 85 85 0 0 0 +-0 0 0 85 85 85 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 85 85 85 170 170 170 +-85 85 85 85 85 85 85 85 85 85 85 85 0 0 0 85 85 85 +-0 0 0 85 85 85 85 85 85 0 0 0 85 85 85 0 0 0 +-85 85 85 0 0 0 85 85 85 0 0 0 0 0 0 85 85 85 +-0 0 0 0 0 0 0 0 0 0 0 0 85 85 85 0 0 0 +-85 85 85 0 0 0 0 0 0 0 0 0 85 85 85 0 0 0 +-85 85 85 0 0 0 0 0 0 85 85 85 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 85 85 85 85 85 85 85 85 85 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 85 85 85 85 85 85 +-85 85 85 0 0 0 85 85 85 85 85 85 85 85 85 85 85 85 +-0 0 0 85 85 85 0 0 0 85 85 85 0 0 0 0 0 0 +-0 0 0 85 85 85 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 85 85 85 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 85 85 85 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 85 85 85 +-0 0 0 85 85 85 170 170 170 170 85 0 170 170 170 85 85 85 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 85 85 85 0 0 0 +-85 85 85 85 85 85 85 85 85 85 85 85 0 0 0 85 85 85 +-0 0 0 85 85 85 0 0 0 0 0 0 85 85 85 0 0 0 +-85 85 85 0 0 0 0 0 0 0 0 0 85 85 85 0 0 0 +-85 85 85 0 0 0 0 0 0 0 0 0 85 85 85 0 0 0 +-85 85 85 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 85 85 85 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 85 85 85 0 0 0 0 0 0 0 0 0 +-170 170 170 255 255 85 170 170 170 170 170 170 170 170 170 85 85 85 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 85 85 85 85 85 85 +-85 85 85 0 0 0 85 85 85 0 0 0 85 85 85 0 0 0 +-85 85 85 0 0 0 85 85 85 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 85 85 85 0 0 0 0 0 0 0 0 0 +-0 0 0 85 85 85 0 0 0 85 85 85 0 0 0 0 0 0 +-0 0 0 0 0 0 85 85 85 0 0 0 85 85 85 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 85 85 85 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 85 85 85 170 170 170 +-255 255 85 170 170 170 170 170 170 170 85 0 85 255 85 170 85 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 85 85 85 0 0 0 85 85 85 +-85 85 85 85 85 85 85 85 85 85 85 85 0 0 0 85 85 85 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 85 85 85 +-0 0 0 85 85 85 0 0 0 0 0 0 85 85 85 85 85 85 +-0 0 0 85 85 85 0 0 0 85 85 85 0 0 0 85 85 85 +-0 0 0 85 85 85 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 85 85 85 0 0 0 0 0 0 0 0 0 0 0 0 +-85 85 85 0 0 0 0 0 0 85 85 85 170 170 170 170 85 0 +-170 170 170 170 170 170 255 255 85 170 170 170 170 170 170 85 85 85 +-0 0 0 85 85 85 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 85 85 85 85 85 85 85 85 85 +-0 0 0 85 85 85 0 0 0 85 85 85 0 0 0 0 0 0 +-85 85 85 0 0 0 85 85 85 0 0 0 85 85 85 0 0 0 +-0 0 0 0 0 0 85 85 85 0 0 0 85 85 85 0 0 0 +-85 85 85 85 85 85 85 85 85 85 85 85 85 85 85 0 0 0 +-85 85 85 0 0 0 85 85 85 0 0 0 85 85 85 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 85 85 85 85 85 85 170 85 0 170 170 170 +-170 170 170 170 85 0 170 170 170 170 170 170 170 85 0 85 85 85 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 85 85 85 0 0 0 85 85 85 +-85 85 85 85 85 85 0 0 0 85 85 85 0 0 0 85 85 85 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-85 85 85 0 0 0 85 85 85 0 0 0 85 85 85 85 85 85 +-85 85 85 85 85 85 85 85 85 85 85 85 85 85 85 85 85 85 +-85 85 85 0 0 0 85 85 85 0 0 0 0 0 0 0 0 0 +-85 85 85 0 0 0 0 0 0 85 85 85 0 0 0 85 85 85 +-0 0 0 0 0 0 85 85 85 85 85 85 85 85 85 85 255 85 +-255 85 85 85 255 85 170 170 170 170 85 0 170 170 170 85 85 85 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 85 85 85 85 85 85 85 85 85 +-0 0 0 85 85 85 0 0 0 85 85 85 0 0 0 0 0 0 +-0 0 0 85 85 85 0 0 0 85 85 85 0 0 0 0 0 0 +-0 0 0 85 85 85 85 85 85 85 85 85 85 85 85 85 85 85 +-85 85 85 85 85 85 85 85 85 85 85 85 85 85 85 85 85 85 +-85 85 85 85 85 85 85 85 85 0 0 0 85 85 85 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 85 85 85 170 85 0 85 85 85 85 85 85 +-170 170 170 170 85 0 170 170 170 85 85 85 170 85 0 85 85 85 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 85 85 85 0 0 0 85 85 85 +-85 85 85 0 0 0 85 85 85 0 0 0 0 0 0 85 85 85 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 85 85 85 +-0 0 0 85 85 85 0 0 0 85 85 85 85 85 85 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 85 85 85 85 85 85 0 0 0 85 85 85 +-0 0 0 0 0 0 85 85 85 0 0 0 0 0 0 0 0 0 +-85 85 85 0 0 0 0 0 0 85 85 85 85 85 85 170 85 0 +-85 85 85 85 85 85 170 85 0 85 255 85 85 85 85 85 85 85 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 85 85 85 0 0 0 +-85 85 85 85 85 85 0 0 0 85 85 85 0 0 0 0 0 0 +-0 0 0 85 85 85 0 0 0 85 85 85 0 0 0 85 85 85 +-0 0 0 85 85 85 85 85 85 85 85 85 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 85 85 85 0 0 0 +-0 0 0 85 85 85 0 0 0 0 0 0 85 85 85 0 0 0 +-0 0 0 0 0 0 0 0 0 85 85 85 0 0 0 85 85 85 +-85 85 85 85 85 85 85 85 85 85 85 85 170 85 0 0 0 0 +-0 0 0 85 85 85 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 85 85 85 +-0 0 0 85 85 85 0 0 0 0 0 0 0 0 0 85 85 85 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-85 85 85 85 85 85 0 0 0 0 0 0 0 0 0 85 85 85 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-85 85 85 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 85 85 85 0 0 0 0 0 0 0 0 0 85 85 85 +-85 85 85 85 85 85 85 85 85 85 85 85 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 85 85 85 0 0 0 +-0 0 0 0 0 0 85 85 85 0 0 0 85 85 85 0 0 0 +-0 0 0 85 85 85 0 0 0 85 85 85 0 0 0 85 85 85 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 85 85 85 0 0 0 85 85 85 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 85 85 85 +-0 0 0 0 0 0 85 85 85 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 85 85 85 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 85 85 85 +-0 0 0 85 85 85 0 0 0 0 170 0 85 85 85 0 0 0 +-85 85 85 0 0 0 0 0 0 0 0 0 85 85 85 0 0 0 +-0 0 0 0 0 0 85 85 85 0 0 0 0 0 0 85 85 85 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 85 85 85 +-0 0 0 85 85 85 0 0 0 85 85 85 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 85 85 85 +-0 0 0 0 0 0 85 85 85 0 0 0 85 85 85 0 0 0 +-0 0 0 0 0 0 85 85 85 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 85 85 85 +-170 85 0 85 255 85 170 85 0 170 85 0 170 85 0 85 255 85 +-170 85 0 170 85 0 0 170 0 0 0 0 0 0 0 0 0 0 +-85 85 85 0 0 0 0 0 0 0 0 0 85 85 85 0 0 0 +-0 0 0 85 85 85 0 0 0 85 85 85 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-85 85 85 0 0 0 0 0 0 85 85 85 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-85 85 85 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 170 0 170 85 0 +-255 255 85 170 85 0 255 255 85 255 255 85 255 255 85 170 85 0 +-255 255 85 85 255 85 170 85 0 170 85 0 85 85 85 0 0 0 +-0 0 0 0 0 0 0 0 0 85 85 85 0 0 0 0 0 0 +-85 85 85 0 0 0 0 0 0 0 0 0 0 0 0 85 85 85 +-0 0 0 85 85 85 0 0 0 85 85 85 0 0 0 0 0 0 +-0 0 0 85 85 85 0 0 0 0 0 0 0 0 0 0 0 0 +-85 85 85 0 0 0 0 0 0 85 85 85 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 85 85 85 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 170 85 0 255 255 85 +-85 255 85 255 255 85 255 255 85 170 85 0 255 255 85 255 255 85 +-255 255 85 170 85 0 255 255 85 85 255 85 170 85 0 0 0 0 +-85 85 85 0 0 0 85 85 85 0 0 0 0 0 0 85 85 85 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 85 85 85 0 0 0 +-0 0 0 0 0 0 0 0 0 85 85 85 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 85 85 85 +-0 0 0 0 0 0 0 0 0 85 85 85 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 85 85 85 255 255 85 170 85 0 +-255 255 85 255 255 85 255 255 85 255 255 85 255 255 85 170 85 0 +-255 255 85 255 255 85 255 255 85 255 255 85 170 85 0 85 255 85 +-0 0 0 0 0 0 0 0 0 85 85 85 0 0 0 0 0 0 +-0 0 0 85 85 85 0 0 0 85 85 85 170 170 170 0 0 0 +-0 0 0 85 85 85 0 0 0 85 85 85 0 0 0 0 0 0 +-85 85 85 0 0 0 0 0 0 0 0 0 0 0 0 85 85 85 +-0 0 0 0 0 0 0 0 0 85 85 85 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 170 85 0 255 255 85 255 255 85 +-255 255 85 255 255 85 170 85 0 255 255 85 85 255 85 255 255 85 +-255 255 85 170 85 0 255 255 85 170 85 0 255 255 85 170 85 0 +-170 85 0 85 85 85 0 0 0 0 0 0 85 85 85 0 0 0 +-85 85 85 0 0 0 0 0 0 85 85 85 170 170 170 0 0 0 +-85 85 85 0 0 0 85 85 85 0 0 0 85 85 85 0 0 0 +-0 0 0 85 85 85 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 85 85 85 0 0 0 0 0 0 0 0 0 85 85 85 +-0 0 0 85 85 85 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 170 85 0 255 255 85 85 255 85 255 255 85 +-170 170 170 255 255 85 255 255 85 255 255 85 255 255 85 255 255 85 +-255 255 85 255 255 85 85 255 85 255 255 85 255 255 85 255 255 85 +-85 255 85 0 0 0 85 85 85 0 0 0 85 85 85 0 0 0 +-85 85 85 0 0 0 0 0 0 0 0 0 85 85 85 0 0 0 +-0 0 0 85 85 85 0 0 0 85 85 85 0 0 0 0 0 0 +-85 85 85 0 0 0 0 0 0 85 85 85 0 0 0 85 85 85 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 170 85 0 255 255 85 255 255 85 255 255 85 +-255 255 255 255 255 85 255 255 85 170 85 0 255 255 85 170 85 0 +-255 255 85 255 255 85 255 255 85 255 255 85 170 85 0 255 255 85 +-170 85 0 170 85 0 0 170 0 0 0 0 85 85 85 0 0 0 +-85 85 85 0 0 0 85 85 85 0 0 0 0 0 0 85 85 85 +-0 0 0 85 85 85 0 0 0 0 0 0 85 85 85 0 0 0 +-0 0 0 85 85 85 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 85 85 85 0 0 0 0 0 0 85 85 85 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 170 85 0 85 255 85 255 255 85 170 170 170 255 255 255 +-255 255 85 255 255 85 255 255 85 255 255 85 255 255 85 255 255 85 +-255 255 85 255 255 85 170 85 0 255 255 85 85 255 85 255 255 85 +-255 255 85 85 255 85 0 0 0 85 85 85 0 0 0 85 85 85 +-0 0 0 85 85 85 0 0 0 85 85 85 85 85 85 0 0 0 +-85 85 85 0 0 0 85 85 85 0 0 0 85 85 85 0 0 0 +-85 85 85 0 0 0 0 0 0 85 85 85 0 0 0 0 0 0 +-85 85 85 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 85 85 85 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 255 255 85 255 255 85 255 255 85 255 255 255 255 255 85 +-255 255 85 255 255 85 85 255 85 255 255 85 255 255 85 85 255 85 +-255 255 85 255 255 85 255 255 85 255 255 85 255 255 85 170 85 0 +-255 255 85 170 85 0 85 85 85 0 0 0 0 0 0 85 85 85 +-0 0 0 85 85 85 0 0 0 85 85 85 0 0 0 85 85 85 +-85 85 85 0 0 0 85 85 85 85 85 85 0 0 0 85 85 85 +-0 0 0 85 85 85 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 85 85 85 0 0 0 0 0 0 +-85 85 85 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-170 85 0 170 85 0 255 255 85 255 255 85 255 255 255 170 170 170 +-255 255 85 255 255 85 255 255 85 255 255 85 255 255 85 255 255 85 +-170 85 0 255 255 85 255 255 85 170 85 0 255 255 85 255 255 85 +-255 255 85 85 255 85 170 85 0 85 85 85 0 0 0 0 0 0 +-85 85 85 0 0 0 85 85 85 0 0 0 85 85 85 85 85 85 +-85 85 85 85 85 85 85 85 85 85 85 85 85 85 85 0 0 0 +-85 85 85 0 0 0 0 0 0 85 85 85 0 0 0 85 85 85 +-0 0 0 85 85 85 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 85 85 85 85 85 85 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-255 255 85 85 255 85 255 255 85 170 170 170 255 255 255 255 255 85 +-255 255 85 255 255 85 170 85 0 255 255 85 255 255 85 255 255 85 +-255 255 85 255 255 85 255 255 85 255 255 85 85 255 85 170 85 0 +-255 255 85 170 85 0 170 85 0 0 0 0 85 85 85 0 0 0 +-85 85 85 85 85 85 85 85 85 170 170 170 170 170 170 170 170 170 +-85 255 85 170 170 170 170 170 170 170 170 170 170 170 170 170 170 170 +-170 170 170 170 170 170 170 170 170 170 170 170 170 170 170 170 170 170 +-170 170 170 170 170 170 170 170 170 170 170 170 170 170 170 170 170 170 +-170 170 170 170 170 170 170 170 170 170 170 170 255 255 85 170 170 170 +-85 85 85 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 170 0 +-170 85 0 255 255 85 255 255 85 255 255 85 255 255 85 255 255 85 +-255 255 85 255 255 85 255 255 85 255 255 85 255 255 85 255 255 85 +-255 255 85 255 255 85 85 255 85 255 255 85 170 85 0 170 85 0 +-170 85 0 85 255 85 255 255 85 85 85 85 170 170 170 170 170 170 +-170 170 170 170 170 170 170 170 170 85 255 85 170 170 170 170 170 170 +-85 85 85 170 170 170 170 170 170 170 85 0 170 170 170 170 170 170 +-85 255 85 170 170 170 170 85 0 170 170 170 85 255 85 255 85 85 +-85 255 85 170 170 170 255 255 85 85 85 85 255 255 85 170 170 170 +-85 255 85 170 170 170 255 255 85 170 170 170 170 170 170 85 85 85 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 255 255 85 +-255 255 85 255 255 85 255 255 85 255 255 255 255 255 85 255 255 85 +-255 255 85 255 255 85 255 255 85 255 255 85 255 255 85 170 85 0 +-255 255 85 255 255 85 255 255 85 170 85 0 0 170 0 85 85 85 +-170 170 170 170 170 170 255 255 85 170 170 170 170 170 170 85 255 85 +-255 85 85 85 255 85 85 85 85 255 85 85 85 85 85 170 170 170 +-170 85 0 170 170 170 85 85 85 85 255 85 85 85 85 85 85 85 +-85 85 85 0 0 0 85 85 85 0 0 0 85 85 85 0 0 0 +-0 0 0 0 0 0 85 85 85 0 0 0 85 85 85 0 0 0 +-170 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 255 255 85 +-170 85 0 255 255 85 255 255 85 255 255 85 255 255 85 255 255 85 +-255 255 85 255 255 85 255 255 85 255 255 85 255 255 85 255 255 85 +-255 255 85 255 255 85 170 85 0 255 255 85 85 85 85 85 85 85 +-255 255 85 170 170 170 85 85 85 85 85 85 0 0 0 85 85 85 +-0 0 0 85 85 85 85 85 85 170 170 170 170 85 0 170 170 170 +-170 170 170 255 255 85 170 170 170 85 85 85 85 85 85 85 85 85 +-0 0 0 85 85 85 0 0 0 0 0 0 0 0 0 0 0 0 +-85 85 85 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 170 85 0 255 255 85 +-255 255 85 255 255 85 255 255 85 255 255 85 255 255 85 255 255 85 +-255 255 85 255 255 85 255 255 85 255 255 85 255 255 85 255 255 85 +-255 255 85 255 255 85 255 255 85 170 85 0 170 85 0 0 170 0 +-0 0 0 170 85 0 170 85 0 0 170 0 0 0 0 0 0 0 +-85 85 85 0 0 0 85 85 85 85 85 85 170 170 170 85 85 85 +-170 170 170 85 85 85 85 85 85 170 170 170 170 85 0 85 85 85 +-85 85 85 0 0 0 0 0 0 85 85 85 0 0 0 0 0 0 +-0 0 0 0 0 0 85 85 85 0 0 0 0 0 0 0 0 0 +-85 85 85 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 255 255 85 170 85 0 +-255 255 85 255 255 85 255 255 85 255 255 85 255 255 85 170 85 0 +-255 255 85 255 255 85 255 255 85 170 85 0 255 255 85 255 255 85 +-170 85 0 255 255 85 85 255 85 255 255 85 255 255 85 170 85 0 +-170 85 0 255 255 85 170 85 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 85 85 85 85 85 85 85 85 85 85 85 85 +-85 85 85 85 85 85 85 85 85 85 85 85 85 85 85 0 0 0 +-0 0 0 85 85 85 0 0 0 0 0 0 0 0 0 0 0 0 +-85 85 85 0 0 0 0 0 0 0 0 0 85 85 85 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 255 255 85 255 255 85 +-255 255 85 255 255 85 170 85 0 255 255 85 255 255 85 255 255 85 +-255 255 85 255 255 85 255 255 85 255 255 85 255 255 85 255 255 85 +-255 255 85 255 255 85 255 255 85 170 85 0 255 255 85 255 255 85 +-85 255 85 170 85 0 0 170 0 85 85 85 0 0 0 85 85 85 +-0 0 0 85 85 85 0 0 0 85 85 85 85 85 85 85 85 85 +-85 85 85 85 85 85 85 85 85 85 85 85 0 0 0 85 85 85 +-0 0 0 0 0 0 0 0 0 85 85 85 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 85 85 85 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 170 0 170 85 0 255 255 85 +-85 255 85 255 255 85 255 255 85 255 255 85 255 255 85 255 255 85 +-255 255 85 255 255 85 255 255 85 255 255 85 255 255 85 255 255 85 +-170 85 0 255 255 85 85 255 85 255 255 85 255 255 85 170 85 0 +-85 255 85 170 85 0 170 85 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 85 85 85 0 0 0 0 0 0 85 85 85 +-0 0 0 85 85 85 0 0 0 0 0 0 85 85 85 0 0 0 +-0 0 0 85 85 85 0 0 0 0 0 0 0 0 0 85 85 85 +-0 0 0 0 0 0 85 85 85 0 0 0 85 85 85 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 85 85 85 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 170 85 0 255 255 85 255 255 85 +-255 255 85 255 255 85 255 255 85 255 255 85 255 255 85 255 255 85 +-255 255 85 170 85 0 255 255 85 85 255 85 255 255 85 170 85 0 +-255 255 85 255 255 85 170 85 0 255 255 85 170 85 0 85 255 85 +-170 85 0 170 85 0 0 0 0 0 0 0 0 0 0 85 85 85 +-0 0 0 0 0 0 0 0 0 0 0 0 85 85 85 0 0 0 +-0 0 0 0 0 0 0 0 0 85 85 85 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 85 85 85 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-85 85 85 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 85 85 85 255 255 85 170 85 0 +-255 255 85 170 85 0 255 255 85 170 85 0 255 255 85 85 255 85 +-255 255 85 255 255 85 255 255 85 255 255 85 255 255 85 255 255 85 +-255 255 85 170 85 0 255 255 85 85 255 85 170 85 0 170 85 0 +-0 170 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 85 85 85 0 0 0 0 0 0 0 0 0 +-0 0 0 85 85 85 0 0 0 0 0 0 0 0 0 85 85 85 +-0 0 0 85 85 85 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 85 85 85 0 0 0 0 0 0 85 85 85 0 0 0 +-0 0 0 0 0 0 85 85 85 85 85 85 85 85 85 85 85 85 +-85 85 85 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 170 85 0 255 255 85 255 255 85 +-255 255 85 255 255 85 255 255 85 255 255 85 255 255 85 255 255 85 +-255 255 85 255 255 85 170 85 0 255 255 85 170 85 0 85 255 85 +-255 255 85 85 255 85 170 85 0 170 85 0 85 255 85 170 85 0 +-0 0 0 0 0 0 85 85 85 0 0 0 0 0 0 85 85 85 +-0 0 0 0 0 0 0 0 0 0 0 0 85 85 85 0 0 0 +-85 85 85 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 85 85 85 0 0 0 85 85 85 +-0 0 0 0 0 0 0 0 0 85 85 85 0 0 0 85 85 85 +-85 85 85 85 85 85 85 85 85 85 85 85 85 85 85 85 85 85 +-85 85 85 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 85 85 85 255 255 85 85 255 85 +-255 255 85 255 255 85 85 255 85 255 255 85 255 255 85 255 255 85 +-255 255 85 170 85 0 255 255 85 85 255 85 255 255 85 255 255 85 +-170 85 0 170 85 0 85 255 85 170 85 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 85 85 85 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 85 85 85 0 0 0 85 85 85 +-0 0 0 85 85 85 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 85 85 85 85 85 85 170 170 170 170 170 170 170 170 170 +-170 170 170 170 170 170 170 170 170 170 170 170 170 170 170 85 85 85 +-85 85 85 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 85 85 85 255 255 85 255 255 85 +-170 85 0 255 255 85 255 255 85 170 85 0 255 255 85 170 85 0 +-255 255 85 85 255 85 170 85 0 255 255 85 170 85 0 85 255 85 +-170 85 0 170 85 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 85 85 85 0 0 0 0 0 0 85 85 85 0 0 0 +-85 85 85 0 0 0 0 0 0 0 0 0 85 85 85 0 0 0 +-0 0 0 85 85 85 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 85 85 85 0 0 0 0 0 0 +-85 85 85 0 0 0 170 170 170 170 170 170 170 170 170 170 170 170 +-170 170 170 170 170 170 170 170 170 85 85 85 85 85 85 85 85 85 +-85 85 85 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 170 85 0 255 255 85 +-255 255 85 255 255 85 255 255 85 255 255 85 255 255 85 85 255 85 +-170 85 0 255 255 85 170 85 0 85 255 85 170 85 0 170 85 0 +-0 170 0 0 0 0 0 0 0 0 0 0 85 85 85 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 85 85 85 0 0 0 0 0 0 85 85 85 +-0 0 0 0 0 0 0 0 0 0 0 0 85 85 85 0 0 0 +-0 0 0 85 85 85 0 0 0 0 0 0 85 85 85 0 0 0 +-0 0 0 85 85 85 170 170 170 170 170 170 255 255 255 170 170 170 +-170 170 170 170 170 170 85 85 85 85 85 85 85 85 85 85 85 85 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 85 255 85 255 255 85 +-170 85 0 255 255 85 255 255 85 170 85 0 85 255 85 170 85 0 +-255 255 85 170 85 0 0 170 0 170 85 0 0 0 0 0 0 0 +-0 0 0 0 0 0 85 85 85 0 0 0 0 0 0 0 0 0 +-0 0 0 85 85 85 0 0 0 85 85 85 0 0 0 0 0 0 +-85 85 85 0 0 0 0 0 0 0 0 0 85 85 85 0 0 0 +-0 0 0 85 85 85 0 0 0 0 0 0 0 0 0 0 0 0 +-85 85 85 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-85 85 85 0 0 0 170 170 170 170 170 170 170 170 170 85 85 85 +-85 85 85 85 85 85 85 85 85 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 255 255 85 +-255 255 85 255 255 85 255 255 85 255 255 85 170 85 0 170 85 0 +-0 170 0 85 85 85 85 85 85 0 0 0 0 0 0 85 85 85 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 85 85 85 +-0 0 0 0 0 0 85 85 85 0 0 0 85 85 85 85 85 85 +-85 85 85 85 85 85 85 85 85 85 85 85 85 85 85 0 0 0 +-85 85 85 0 0 0 0 0 0 0 0 0 85 85 85 0 0 0 +-0 0 0 0 0 0 85 85 85 0 0 0 85 85 85 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 85 85 85 0 0 0 +-85 85 85 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-255 255 85 255 255 85 170 85 0 0 170 0 85 85 85 85 85 85 +-85 85 85 85 85 85 0 0 0 85 85 85 85 85 85 0 0 0 +-85 85 85 85 85 85 0 0 0 85 85 85 0 0 0 0 0 0 +-85 85 85 85 85 85 85 85 85 170 170 170 170 170 170 85 85 85 +-170 170 170 170 170 170 170 170 170 170 170 170 85 85 85 85 85 85 +-85 85 85 85 85 85 85 85 85 85 85 85 0 0 0 0 0 0 +-85 85 85 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-85 85 85 0 0 0 85 85 85 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 85 85 85 0 0 0 0 0 0 +-85 85 85 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 170 85 0 85 85 85 0 0 0 0 0 0 0 0 0 +-85 85 85 85 85 85 85 85 85 85 85 85 170 170 170 85 85 85 +-85 85 85 85 85 85 85 85 85 85 85 85 85 85 85 85 85 85 +-170 170 170 170 170 170 170 170 170 170 170 170 255 255 255 255 255 255 +-255 255 255 255 255 255 255 255 255 170 170 170 255 255 255 170 170 170 +-170 170 170 170 170 170 170 170 170 85 85 85 85 85 85 85 85 85 +-0 0 0 0 0 0 0 0 0 0 0 0 85 85 85 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 85 85 85 0 0 0 +-0 0 0 85 85 85 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 85 85 85 +-85 85 85 85 85 85 85 85 85 85 85 85 170 170 170 170 170 170 +-255 255 255 255 255 255 255 255 255 170 170 170 255 255 255 170 170 170 +-255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 +-255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 +-255 255 255 255 255 255 170 170 170 255 255 255 170 170 170 85 85 85 +-0 0 0 85 85 85 0 0 0 0 0 0 0 0 0 0 0 0 +-85 85 85 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-85 85 85 0 0 0 0 0 0 0 0 0 85 85 85 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 85 85 85 +-85 85 85 85 85 85 85 85 85 85 85 85 170 170 170 170 170 170 +-255 255 255 170 170 170 255 255 255 255 255 255 255 255 255 255 255 255 +-255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 170 170 170 +-255 255 255 255 255 255 170 170 170 255 255 255 255 255 255 255 255 255 +-255 255 255 255 255 255 255 255 255 255 255 255 170 170 170 85 85 85 +-0 0 0 0 0 0 85 85 85 0 0 0 85 85 85 0 0 0 +-0 0 0 0 0 0 85 85 85 0 0 0 85 85 85 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-85 85 85 0 0 0 0 0 0 85 85 85 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 85 85 85 +-85 85 85 85 85 85 85 85 85 85 85 85 85 85 85 170 170 170 +-170 170 170 170 170 170 255 255 255 170 170 170 255 255 255 170 170 170 +-255 255 255 170 170 170 255 255 255 170 170 170 255 255 255 255 255 255 +-255 255 255 170 170 170 255 255 255 170 170 170 255 255 255 170 170 170 +-170 170 170 170 170 170 170 170 170 170 170 170 85 85 85 85 85 85 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-85 85 85 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-85 85 85 0 0 0 85 85 85 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 85 85 85 +-85 85 85 85 85 85 85 85 85 0 0 0 85 85 85 85 85 85 +-85 85 85 85 85 85 85 85 85 170 170 170 170 170 170 170 170 170 +-170 170 170 170 170 170 170 170 170 170 170 170 170 170 170 170 170 170 +-170 170 170 170 170 170 170 170 170 170 170 170 85 85 85 170 170 170 +-170 170 170 170 170 170 85 85 85 0 0 0 85 85 85 0 0 0 +-0 0 0 0 0 0 85 85 85 0 0 0 85 85 85 0 0 0 +-0 0 0 85 85 85 0 0 0 0 0 0 85 85 85 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 85 85 85 +-0 0 0 0 0 0 85 85 85 0 0 0 0 0 0 85 85 85 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 85 85 85 85 85 85 +-170 170 170 85 85 85 85 85 85 85 85 85 0 0 0 85 85 85 +-0 0 0 85 85 85 85 85 85 85 85 85 85 85 85 85 85 85 +-85 85 85 85 85 85 85 85 85 85 85 85 85 85 85 0 0 0 +-85 85 85 85 85 85 85 85 85 85 85 85 85 85 85 0 0 0 +-0 0 0 0 0 0 85 85 85 0 0 0 0 0 0 0 0 0 +-85 85 85 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 85 85 85 0 0 0 0 0 0 +-85 85 85 0 0 0 85 85 85 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 170 170 170 85 85 85 +-85 85 85 85 85 85 85 85 85 0 0 0 85 85 85 0 0 0 +-85 85 85 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-85 85 85 0 0 0 85 85 85 0 0 0 0 0 0 85 85 85 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-85 85 85 0 0 0 0 0 0 0 0 0 85 85 85 0 0 0 +-0 0 0 0 0 0 85 85 85 0 0 0 0 0 0 85 85 85 +-0 0 0 85 85 85 0 0 0 0 0 0 85 85 85 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 85 85 85 0 0 0 +-85 85 85 0 0 0 0 0 0 85 85 85 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 85 85 85 85 85 85 85 85 85 +-85 85 85 85 85 85 85 85 85 85 85 85 0 0 0 0 0 0 +-0 0 0 85 85 85 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 85 85 85 0 0 0 0 0 0 +-0 0 0 0 0 0 85 85 85 0 0 0 0 0 0 0 0 0 +-85 85 85 0 0 0 0 0 0 0 0 0 85 85 85 0 0 0 +-0 0 0 0 0 0 85 85 85 0 0 0 0 0 0 0 0 0 +-85 85 85 0 0 0 85 85 85 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 85 85 85 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 85 85 85 85 85 85 170 170 170 85 85 85 +-85 85 85 85 85 85 85 85 85 0 0 0 85 85 85 0 0 0 +-85 85 85 0 0 0 0 0 0 0 0 0 85 85 85 0 0 0 +-0 0 0 85 85 85 0 0 0 0 0 0 85 85 85 0 0 0 +-0 0 0 85 85 85 0 0 0 0 0 0 0 0 0 0 0 0 +-85 85 85 0 0 0 0 0 0 0 0 0 85 85 85 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-85 85 85 0 0 0 0 0 0 0 0 0 85 85 85 0 0 0 +-85 85 85 0 0 0 0 0 0 85 85 85 0 0 0 85 85 85 +-0 0 0 0 0 0 85 85 85 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 85 85 85 85 85 85 85 85 85 85 85 85 +-85 85 85 85 85 85 0 0 0 85 85 85 0 0 0 85 85 85 +-0 0 0 0 0 0 85 85 85 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 85 85 85 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-85 85 85 0 0 0 85 85 85 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 85 85 85 0 0 0 85 85 85 0 0 0 +-0 0 0 85 85 85 0 0 0 0 0 0 0 0 0 0 0 0 +-85 85 85 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-85 85 85 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 85 85 85 85 85 85 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 85 85 85 85 85 85 170 170 170 85 85 85 85 85 85 +-85 85 85 85 85 85 0 0 0 85 85 85 0 0 0 0 0 0 +-85 85 85 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-85 85 85 0 0 0 0 0 0 85 85 85 0 0 0 0 0 0 +-85 85 85 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-85 85 85 0 0 0 0 0 0 85 85 85 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 85 85 85 0 0 0 +-85 85 85 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-85 85 85 0 0 0 85 85 85 0 0 0 85 85 85 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 85 85 85 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 85 85 85 170 170 170 170 170 170 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 85 85 85 170 170 170 85 85 85 85 85 85 85 85 85 +-85 85 85 0 0 0 85 85 85 0 0 0 0 0 0 85 85 85 +-0 0 0 0 0 0 85 85 85 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 85 85 85 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 85 85 85 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 85 85 85 0 0 0 85 85 85 85 85 85 +-0 0 0 85 85 85 0 0 0 85 85 85 0 0 0 0 0 0 +-85 85 85 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-85 85 85 170 170 170 255 255 255 170 170 170 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-85 85 85 85 85 85 85 85 85 85 85 85 85 85 85 85 85 85 +-85 85 85 0 0 0 85 85 85 0 0 0 85 85 85 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 85 85 85 +-0 0 0 0 0 0 85 85 85 0 0 0 0 0 0 85 85 85 +-0 0 0 0 0 0 0 0 0 0 0 0 85 85 85 0 0 0 +-0 0 0 85 85 85 0 0 0 85 85 85 0 0 0 0 0 0 +-0 0 0 85 85 85 0 0 0 85 85 85 0 0 0 0 0 0 +-85 85 85 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-85 85 85 0 0 0 85 85 85 0 0 0 0 0 0 85 85 85 +-0 0 0 0 0 0 0 0 0 85 85 85 0 0 0 0 0 0 +-0 0 0 85 85 85 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 170 170 170 +-170 170 170 255 255 255 170 170 170 170 170 170 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-85 85 85 170 170 170 85 85 85 85 85 85 85 85 85 0 0 0 +-85 85 85 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-85 85 85 0 0 0 0 0 0 85 85 85 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 85 85 85 0 0 0 85 85 85 85 85 85 +-0 0 0 85 85 85 0 0 0 85 85 85 0 0 0 0 0 0 +-0 0 0 85 85 85 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 170 170 170 170 170 170 +-255 255 255 255 255 255 170 170 170 170 170 170 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 85 85 85 +-85 85 85 85 85 85 85 85 85 85 85 85 85 85 85 0 0 0 +-85 85 85 0 0 0 85 85 85 0 0 0 85 85 85 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-85 85 85 0 0 0 0 0 0 0 0 0 85 85 85 0 0 0 +-0 0 0 0 0 0 85 85 85 0 0 0 0 0 0 0 0 0 +-85 85 85 0 0 0 0 0 0 0 0 0 0 0 0 85 85 85 +-0 0 0 0 0 0 85 85 85 0 0 0 0 0 0 85 85 85 +-0 0 0 0 0 0 0 0 0 85 85 85 0 0 0 0 0 0 +-85 85 85 0 0 0 85 85 85 0 0 0 0 0 0 85 85 85 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-85 85 85 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 85 85 85 170 170 170 170 170 170 255 255 255 +-255 255 255 170 170 170 170 170 170 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 85 85 85 +-170 170 170 85 85 85 85 85 85 85 85 85 85 85 85 85 85 85 +-0 0 0 85 85 85 0 0 0 0 0 0 0 0 0 0 0 0 +-85 85 85 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-85 85 85 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 85 85 85 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 85 85 85 0 0 0 0 0 0 85 85 85 85 85 85 +-0 0 0 85 85 85 0 0 0 85 85 85 0 0 0 0 0 0 +-85 85 85 0 0 0 0 0 0 85 85 85 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 85 85 85 170 170 170 255 255 255 255 255 255 255 255 255 +-170 170 170 170 170 170 85 85 85 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 85 85 85 85 85 85 +-85 85 85 85 85 85 85 85 85 85 85 85 0 0 0 85 85 85 +-0 0 0 0 0 0 85 85 85 0 0 0 85 85 85 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 85 85 85 0 0 0 +-0 0 0 0 0 0 85 85 85 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 85 85 85 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 85 85 85 0 0 0 0 0 0 85 85 85 0 0 0 +-0 0 0 0 0 0 85 85 85 0 0 0 85 85 85 0 0 0 +-85 85 85 0 0 0 85 85 85 0 0 0 85 85 85 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 85 85 85 +-170 170 170 170 170 170 255 255 255 255 255 255 255 255 255 170 170 170 +-170 170 170 170 170 170 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 85 85 85 85 85 85 +-85 85 85 85 85 85 85 85 85 85 85 85 0 0 0 85 85 85 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 85 85 85 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 85 85 85 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 85 85 85 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 85 85 85 0 0 0 85 85 85 0 0 0 +-85 85 85 0 0 0 85 85 85 0 0 0 0 0 0 85 85 85 +-0 0 0 85 85 85 0 0 0 0 0 0 85 85 85 0 0 0 +-0 0 0 85 85 85 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 170 170 170 170 170 170 +-170 170 170 255 255 255 255 255 255 255 255 255 170 170 170 170 170 170 +-170 170 170 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 85 85 85 85 85 85 85 85 85 +-85 85 85 85 85 85 85 85 85 0 0 0 85 85 85 0 0 0 +-85 85 85 0 0 0 85 85 85 0 0 0 0 0 0 85 85 85 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-85 85 85 0 0 0 0 0 0 85 85 85 0 0 0 0 0 0 +-85 85 85 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-85 85 85 0 0 0 0 0 0 0 0 0 0 0 0 85 85 85 +-0 0 0 0 0 0 85 85 85 0 0 0 0 0 0 85 85 85 +-0 0 0 0 0 0 85 85 85 85 85 85 85 85 85 85 85 85 +-0 0 0 85 85 85 0 0 0 85 85 85 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 85 85 85 170 170 170 170 170 170 170 170 170 +-255 255 255 255 255 255 255 255 255 255 255 255 170 170 170 170 170 170 +-0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 85 85 85 85 85 85 85 85 85 +-85 85 85 85 85 85 85 85 85 85 85 85 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 85 85 85 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 85 85 85 85 85 85 85 85 85 85 85 85 0 0 0 +-85 85 85 0 0 0 85 85 85 0 0 0 85 85 85 0 0 0 +-85 85 85 85 85 85 85 85 85 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-85 85 85 170 170 170 170 170 170 255 255 255 255 255 255 255 255 255 +-255 255 255 255 255 255 170 170 170 170 170 170 85 85 85 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 85 85 85 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 85 85 85 85 85 85 85 85 85 +-85 85 85 85 85 85 85 85 85 0 0 0 85 85 85 0 0 0 +-85 85 85 0 0 0 85 85 85 0 0 0 85 85 85 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 85 85 85 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 85 85 85 0 0 0 +-0 0 0 0 0 0 85 85 85 0 0 0 0 0 0 0 0 0 +-85 85 85 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-85 85 85 0 0 0 170 170 170 255 255 255 85 85 85 85 85 85 +-85 85 85 0 0 0 85 85 85 0 0 0 0 0 0 0 0 0 +-85 85 85 170 170 170 85 85 85 0 0 0 0 0 0 0 0 0 +-85 85 85 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 85 85 85 +-170 170 170 170 170 170 255 255 255 170 170 170 255 255 255 255 255 255 +-255 255 255 255 255 255 170 170 170 170 170 170 85 85 85 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-85 85 85 170 170 170 85 85 85 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 85 85 85 85 85 85 85 85 85 85 85 85 +-85 85 85 85 85 85 0 0 0 85 85 85 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 85 85 85 0 0 0 0 0 0 85 85 85 0 0 0 +-0 0 0 85 85 85 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 85 85 85 0 0 0 0 0 0 85 85 85 +-0 0 0 85 85 85 170 170 170 255 255 255 170 170 170 85 85 85 +-0 0 0 85 85 85 0 0 0 85 85 85 0 0 0 85 85 85 +-255 255 255 170 170 170 85 85 85 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 85 85 85 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 85 85 85 85 85 85 +-255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 +-170 170 170 170 170 170 85 85 85 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-85 85 85 255 255 255 170 170 170 85 85 85 0 0 0 0 0 0 +-0 0 0 0 0 0 85 85 85 85 85 85 85 85 85 0 0 0 +-85 85 85 85 85 85 0 0 0 85 85 85 0 0 0 85 85 85 +-0 0 0 85 85 85 0 0 0 0 0 0 0 0 0 85 85 85 +-0 0 0 0 0 0 85 85 85 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-85 85 85 0 0 0 0 0 0 0 0 0 85 85 85 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-85 85 85 85 85 85 255 255 255 255 255 255 255 255 255 85 85 85 +-85 85 85 0 0 0 85 85 85 0 0 0 85 85 85 170 170 170 +-255 255 255 170 170 170 0 0 0 0 0 0 85 85 85 0 0 0 +-0 0 0 85 85 85 170 170 170 85 85 85 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 85 85 85 0 0 0 85 85 85 170 170 170 +-170 170 170 255 255 255 255 255 255 255 255 255 255 255 255 170 170 170 +-170 170 170 170 170 170 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 85 85 85 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-170 170 170 255 255 255 255 255 255 170 170 170 0 0 0 0 0 0 +-0 0 0 0 0 0 85 85 85 85 85 85 85 85 85 0 0 0 +-85 85 85 85 85 85 85 85 85 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 85 85 85 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 85 85 85 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 85 85 85 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 85 85 85 0 0 0 85 85 85 +-85 85 85 170 170 170 255 255 255 255 255 255 255 255 255 85 85 85 +-85 85 85 0 0 0 85 85 85 0 0 0 85 85 85 255 255 255 +-255 255 255 170 170 170 0 0 0 0 0 0 0 0 0 0 0 0 +-85 85 85 170 170 170 170 170 170 85 85 85 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-85 85 85 0 0 0 85 85 85 85 85 85 85 85 85 85 85 85 +-170 170 170 255 255 255 255 255 255 255 255 255 170 170 170 170 170 170 +-85 85 85 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 85 85 85 170 170 170 170 170 170 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-170 170 170 255 255 255 255 255 255 255 255 255 85 85 85 0 0 0 +-0 0 0 85 85 85 85 85 85 85 85 85 85 85 85 0 0 0 +-85 85 85 85 85 85 0 0 0 85 85 85 0 0 0 85 85 85 +-0 0 0 85 85 85 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 85 85 85 0 0 0 0 0 0 +-85 85 85 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 85 85 85 0 0 0 0 0 0 0 0 0 +-0 0 0 85 85 85 0 0 0 0 0 0 85 85 85 0 0 0 +-85 85 85 170 170 170 255 255 255 255 255 255 255 255 255 170 170 170 +-0 0 0 85 85 85 0 0 0 85 85 85 170 170 170 255 255 255 +-255 255 255 170 170 170 85 85 85 0 0 0 0 0 0 0 0 0 +-85 85 85 255 255 255 255 255 255 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 85 85 85 0 0 0 85 85 85 +-0 0 0 85 85 85 85 85 85 0 0 0 85 85 85 85 85 85 +-170 170 170 170 170 170 170 170 170 170 170 170 170 170 170 85 85 85 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 170 170 170 255 255 255 +-170 170 170 85 85 85 0 0 0 0 0 0 0 0 0 0 0 0 +-85 85 85 255 255 255 255 255 255 255 255 255 255 255 255 0 0 0 +-0 0 0 85 85 85 85 85 85 0 0 0 85 85 85 0 0 0 +-85 85 85 85 85 85 0 0 0 0 0 0 85 85 85 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 85 85 85 +-0 0 0 0 0 0 85 85 85 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 85 85 85 +-0 0 0 0 0 0 0 0 0 85 85 85 85 85 85 85 85 85 +-85 85 85 255 255 255 255 255 255 255 255 255 170 170 170 170 170 170 +-85 85 85 0 0 0 0 0 0 85 85 85 170 170 170 255 255 255 +-255 255 255 170 170 170 0 0 0 0 0 0 0 0 0 0 0 0 +-170 170 170 255 255 255 170 170 170 0 0 0 0 0 0 0 0 0 +-85 85 85 170 170 170 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 85 85 85 0 0 0 0 0 0 85 85 85 0 0 0 +-85 85 85 85 85 85 0 0 0 85 85 85 85 85 85 0 0 0 +-85 85 85 85 85 85 170 170 170 85 85 85 85 85 85 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 85 85 85 170 170 170 +-255 255 255 170 170 170 0 0 0 0 0 0 0 0 0 0 0 0 +-85 85 85 170 170 170 255 255 255 255 255 255 255 255 255 170 170 170 +-0 0 0 85 85 85 85 85 85 85 85 85 0 0 0 0 0 0 +-85 85 85 85 85 85 0 0 0 85 85 85 0 0 0 0 0 0 +-0 0 0 85 85 85 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 85 85 85 +-0 0 0 0 0 0 85 85 85 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 85 85 85 0 0 0 0 0 0 +-85 85 85 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 85 85 85 0 0 0 85 85 85 0 0 0 +-170 170 170 170 170 170 255 255 255 170 170 170 255 255 255 85 85 85 +-0 0 0 85 85 85 0 0 0 85 85 85 170 170 170 255 255 255 +-170 170 170 170 170 170 0 0 0 0 0 0 0 0 0 85 85 85 +-170 170 170 255 255 255 255 255 255 0 0 0 0 0 0 85 85 85 +-255 255 255 85 85 85 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 85 85 85 0 0 0 +-85 85 85 0 0 0 85 85 85 0 0 0 85 85 85 85 85 85 +-85 85 85 0 0 0 85 85 85 85 85 85 0 0 0 85 85 85 +-0 0 0 0 0 0 85 85 85 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 85 85 85 85 85 85 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 85 85 85 255 255 255 +-255 255 255 255 255 255 170 170 170 0 0 0 0 0 0 0 0 0 +-85 85 85 170 170 170 255 255 255 170 170 170 170 170 170 170 170 170 +-85 85 85 85 85 85 0 0 0 85 85 85 0 0 0 85 85 85 +-85 85 85 0 0 0 85 85 85 0 0 0 0 0 0 85 85 85 +-0 0 0 0 0 0 0 0 0 0 0 0 85 85 85 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 85 85 85 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 85 85 85 0 0 0 0 0 0 +-85 85 85 0 0 0 85 85 85 0 0 0 85 85 85 85 85 85 +-85 85 85 170 170 170 255 255 255 170 170 170 170 170 170 85 85 85 +-85 85 85 0 0 0 85 85 85 85 85 85 85 85 85 170 170 170 +-170 170 170 85 85 85 85 85 85 0 0 0 0 0 0 85 85 85 +-170 170 170 170 170 170 85 85 85 0 0 0 0 0 0 170 170 170 +-170 170 170 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 85 85 85 0 0 0 0 0 0 0 0 0 85 85 85 +-0 0 0 85 85 85 0 0 0 85 85 85 0 0 0 85 85 85 +-0 0 0 85 85 85 0 0 0 85 85 85 0 0 0 0 0 0 +-85 85 85 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 170 170 170 170 170 170 +-85 85 85 0 0 0 0 0 0 0 0 0 0 0 0 170 170 170 +-255 255 255 170 170 170 170 170 170 85 85 85 0 0 0 0 0 0 +-0 0 0 85 85 85 170 170 170 170 170 170 255 255 85 85 85 85 +-85 85 85 85 85 85 85 85 85 0 0 0 0 0 0 0 0 0 +-85 85 85 85 85 85 0 0 0 85 85 85 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 85 85 85 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 85 85 85 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-85 85 85 0 0 0 85 85 85 85 85 85 0 0 0 85 85 85 +-85 85 85 170 170 170 170 170 170 170 170 170 170 85 0 85 85 85 +-0 0 0 85 85 85 0 0 0 85 85 85 170 170 170 170 85 0 +-170 170 170 85 85 85 0 0 0 0 0 0 0 0 0 0 0 0 +-170 85 0 170 170 170 85 85 85 0 0 0 85 85 85 85 85 85 +-170 170 170 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 85 85 85 +-0 0 0 0 0 0 85 85 85 0 0 0 85 85 85 0 0 0 +-85 85 85 0 0 0 85 85 85 0 0 0 85 85 85 0 0 0 +-85 85 85 0 0 0 85 85 85 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 170 170 170 255 255 255 +-170 170 170 0 0 0 0 0 0 0 0 0 0 0 0 85 85 85 +-255 255 255 170 170 170 170 170 170 85 85 85 0 0 0 0 0 0 +-0 0 0 85 85 85 170 85 0 170 170 170 170 170 170 85 85 85 +-85 85 85 0 0 0 85 85 85 0 0 0 85 85 85 0 0 0 +-85 85 85 0 0 0 85 85 85 0 0 0 0 0 0 85 85 85 +-0 0 0 0 0 0 85 85 85 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 85 85 85 +-0 0 0 0 0 0 85 85 85 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 85 85 85 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 85 85 85 0 0 0 +-85 85 85 0 0 0 85 85 85 0 0 0 85 85 85 85 85 85 +-85 85 85 170 85 0 85 255 85 170 85 0 170 170 170 85 85 85 +-85 85 85 0 0 0 0 0 0 85 85 85 170 85 0 85 255 85 +-170 85 0 85 85 85 0 0 0 85 85 85 0 0 0 85 85 85 +-85 85 85 85 85 85 170 85 0 0 0 0 85 85 85 85 85 85 +-85 85 85 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 85 85 85 0 0 0 0 0 0 85 85 85 0 0 0 +-0 0 0 85 85 85 0 0 0 85 85 85 0 0 0 85 85 85 +-0 0 0 85 85 85 0 0 0 85 85 85 0 0 0 85 85 85 +-0 0 0 0 0 0 0 0 0 0 0 0 85 85 85 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 85 85 85 255 255 255 +-255 255 255 170 170 170 0 0 0 0 0 0 0 0 0 0 0 0 +-170 170 170 170 170 170 170 170 170 85 85 85 0 0 0 0 0 0 +-0 0 0 0 0 0 170 170 170 170 85 0 170 170 170 170 85 0 +-85 85 85 85 85 85 0 0 0 0 0 0 0 0 0 0 0 0 +-85 85 85 85 85 85 0 0 0 0 0 0 85 85 85 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-85 85 85 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-85 85 85 0 0 0 0 0 0 85 85 85 0 0 0 0 0 0 +-85 85 85 0 0 0 85 85 85 85 85 85 85 85 85 0 0 0 +-85 85 85 85 85 85 255 85 85 170 170 170 85 255 85 170 85 0 +-85 85 85 85 85 85 170 85 0 85 85 85 170 170 170 85 85 85 +-170 170 170 170 85 0 85 85 85 85 85 85 85 85 85 85 85 85 +-170 85 0 85 255 85 85 85 85 85 85 85 85 85 85 170 85 0 +-85 85 85 0 0 0 85 85 85 0 0 0 0 0 0 85 85 85 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-85 85 85 0 0 0 0 0 0 0 0 0 85 85 85 0 0 0 +-0 0 0 0 0 0 85 85 85 0 0 0 0 0 0 0 0 0 +-0 0 0 85 85 85 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 +-85 85 85 85 85 85 0 0 0 0 0 0 0 0 0 170 170 170 +-255 255 255 170 170 170 0 0 0 0 0 0 0 0 0 0 0 0 +-85 85 85 170 85 0 170 170 170 170 85 0 85 85 85 0 0 0 +-85 85 85 85 85 85 85 255 85 170 170 170 170 170 170 170 85 0 +-85 85 85 0 0 0 85 85 85 0 0 0 0 0 0 0 0 0 +-85 85 85 0 0 0 85 85 85 0 0 0 0 0 0 0 0 0 +-85 85 85 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 85 85 85 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 85 85 85 0 0 0 +-0 0 0 85 85 85 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 85 85 85 85 85 85 +-0 0 0 85 85 85 85 85 85 0 0 0 85 85 85 85 85 85 +-85 85 85 85 85 85 85 255 85 255 85 85 170 170 170 170 170 170 +-170 170 170 85 255 85 170 170 170 170 85 0 170 170 170 170 85 0 +-170 170 170 85 85 85 85 255 85 170 85 0 170 170 170 170 85 0 +-170 170 170 170 170 170 170 85 0 85 85 85 85 85 85 85 255 85 +-85 85 85 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 85 85 85 0 0 0 85 85 85 0 0 0 0 0 0 +-0 0 0 0 0 0 85 85 85 0 0 0 0 0 0 85 85 85 +-0 0 0 85 85 85 0 0 0 0 0 0 85 85 85 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 170 170 170 170 170 170 0 0 0 0 0 0 85 85 85 +-170 170 170 170 170 170 85 85 85 0 0 0 0 0 0 0 0 0 +-85 85 85 85 85 85 255 255 85 85 85 85 85 85 85 85 85 85 +-85 255 85 255 85 85 170 170 170 170 85 0 170 170 170 85 255 85 +-85 85 85 85 85 85 0 0 0 0 0 0 0 0 0 0 0 0 +-85 85 85 85 85 85 0 0 0 0 0 0 85 85 85 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 85 85 85 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 85 85 85 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 85 85 85 0 0 0 0 0 0 +-85 85 85 0 0 0 85 85 85 85 85 85 85 85 85 0 0 0 +-85 85 85 85 85 85 170 85 0 170 170 170 170 170 170 255 255 85 +-170 170 170 255 85 85 170 170 170 170 170 170 255 255 85 170 170 170 +-85 255 85 170 170 170 255 85 85 170 170 170 170 170 170 170 170 170 +-170 170 170 170 170 170 170 170 170 170 85 0 170 170 170 170 85 0 +-85 85 85 0 0 0 0 0 0 85 85 85 0 0 0 85 85 85 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-85 85 85 0 0 0 0 0 0 85 85 85 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 85 85 85 170 170 170 85 85 85 0 0 0 85 85 85 +-85 85 85 170 85 0 85 85 85 0 0 0 85 85 85 85 85 85 +-85 85 85 170 85 0 170 170 170 170 170 170 255 255 85 170 170 170 +-170 170 170 170 170 170 255 255 85 170 170 170 170 170 170 255 85 85 +-85 85 85 0 0 0 0 0 0 85 85 85 0 0 0 0 0 0 +-85 85 85 0 0 0 85 85 85 0 0 0 0 0 0 0 0 0 +-85 85 85 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 85 85 85 0 0 0 0 0 0 +-85 85 85 0 0 0 85 85 85 0 0 0 85 85 85 0 0 0 +-85 85 85 85 85 85 0 0 0 85 85 85 85 85 85 85 85 85 +-85 85 85 85 85 85 170 170 170 255 255 85 170 170 170 170 170 170 +-170 170 170 255 255 85 170 170 170 170 170 170 170 170 170 170 85 0 +-170 170 170 255 255 85 170 170 170 255 255 85 170 170 170 255 255 85 +-170 170 170 255 255 85 170 170 170 170 170 170 85 255 85 170 85 0 +-85 85 85 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 85 85 85 0 0 0 0 0 0 85 85 85 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 85 85 85 +-0 0 0 0 0 0 85 85 85 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 170 170 170 85 85 85 85 85 85 0 0 0 +-85 85 85 85 85 85 170 170 170 85 85 85 170 170 170 170 85 0 +-170 170 170 85 255 85 170 170 170 170 85 0 170 170 170 170 170 170 +-255 255 85 170 170 170 170 170 170 255 255 255 255 255 85 170 170 170 +-255 255 85 85 85 85 0 0 0 0 0 0 0 0 0 0 0 0 +-85 85 85 85 85 85 0 0 0 0 0 0 85 85 85 0 0 0 +-0 0 0 0 0 0 85 85 85 0 0 0 0 0 0 0 0 0 +-0 0 0 85 85 85 0 0 0 0 0 0 85 85 85 0 0 0 +-0 0 0 0 0 0 0 0 0 85 85 85 0 0 0 0 0 0 +-85 85 85 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 85 85 85 85 85 85 85 85 85 0 0 0 0 0 0 +-0 0 0 0 0 0 85 85 85 0 0 0 85 85 85 0 0 0 +-85 85 85 170 85 0 170 170 170 170 170 170 170 170 170 255 255 255 +-170 170 170 255 255 255 255 255 85 170 170 170 255 255 85 170 170 170 +-255 255 85 170 170 170 170 170 170 170 170 170 170 170 170 170 170 170 +-170 170 170 170 170 170 170 170 170 255 85 85 170 170 170 170 170 170 +-85 85 85 85 85 85 0 0 0 0 0 0 85 85 85 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 85 85 85 0 0 0 85 85 85 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 85 85 85 85 85 85 170 85 0 85 85 85 +-85 85 85 255 255 85 170 170 170 170 170 170 170 170 170 170 170 170 +-255 255 85 170 170 170 170 170 170 255 255 85 170 170 170 170 170 170 +-170 170 170 255 255 255 255 255 255 170 170 170 255 255 255 170 170 170 +-170 170 170 85 85 85 85 85 85 0 0 0 0 0 0 85 85 85 +-0 0 0 85 85 85 0 0 0 85 85 85 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-85 85 85 170 170 170 170 170 170 85 85 85 0 0 0 0 0 0 +-0 0 0 85 85 85 85 85 85 85 85 85 85 85 85 85 85 85 +-85 85 85 85 255 85 170 170 170 255 255 85 255 255 255 255 255 255 +-255 255 255 170 170 170 255 255 255 170 170 170 170 170 170 170 170 170 +-170 170 170 170 170 170 255 255 85 170 170 170 255 255 85 255 255 255 +-255 255 85 255 255 255 255 255 85 170 170 170 170 170 170 170 85 0 +-170 170 170 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-85 85 85 0 0 0 0 0 0 85 85 85 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 85 85 85 85 85 85 85 85 85 +-85 85 85 170 170 170 255 255 85 170 170 170 255 255 85 170 170 170 +-170 170 170 255 255 85 170 170 170 170 170 170 170 170 170 255 255 85 +-255 255 255 255 255 255 255 255 85 255 255 255 255 255 255 170 170 170 +-255 255 85 85 85 85 85 85 85 0 0 0 0 0 0 85 85 85 +-85 85 85 85 85 85 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 85 85 85 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 85 85 85 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 85 85 85 0 0 0 0 0 0 0 0 0 +-85 85 85 170 170 170 170 170 170 0 0 0 0 0 0 0 0 0 +-85 85 85 0 0 0 85 85 85 0 0 0 85 85 85 0 0 0 +-85 85 85 170 170 170 170 170 170 170 170 170 255 255 255 170 170 170 +-255 255 255 255 255 255 255 255 255 170 170 170 170 170 170 255 255 85 +-170 170 170 255 255 85 170 170 170 255 255 255 170 170 170 255 255 255 +-255 255 255 255 255 255 170 170 170 255 255 85 170 170 170 255 255 85 +-85 85 85 85 85 85 0 0 0 0 0 0 85 85 85 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 85 85 85 0 0 0 +-0 0 0 85 85 85 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 85 85 85 170 85 0 170 170 170 +-255 255 85 170 170 170 170 170 170 255 255 255 255 255 255 255 255 255 +-170 170 170 170 170 170 170 170 170 255 255 85 170 170 170 170 170 170 +-255 255 255 170 170 170 255 255 255 255 255 255 170 170 170 255 255 255 +-170 170 170 170 170 170 85 85 85 0 0 0 85 85 85 0 0 0 +-85 85 85 0 0 0 85 85 85 0 0 0 85 85 85 0 0 0 +-0 0 0 85 85 85 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 85 85 85 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-85 85 85 170 170 170 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 85 85 85 0 0 0 85 85 85 85 85 85 0 0 0 +-85 85 85 170 85 0 255 255 255 170 170 170 255 255 255 255 255 255 +-255 255 85 255 255 255 170 170 170 255 255 85 170 170 170 170 170 170 +-170 170 170 170 170 170 170 170 170 255 255 85 255 255 255 255 255 255 +-170 170 170 255 255 255 255 255 255 170 170 170 170 170 170 170 170 170 +-85 85 85 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 85 85 85 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 85 85 85 85 255 85 170 170 170 +-170 170 170 255 255 85 170 170 170 255 255 255 170 170 170 255 255 255 +-255 255 255 255 255 255 255 255 85 170 170 170 170 170 170 255 255 255 +-170 170 170 255 255 255 255 255 255 170 170 170 255 255 255 255 255 85 +-170 170 170 170 85 0 85 85 85 0 0 0 0 0 0 85 85 85 +-0 0 0 85 85 85 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 85 85 85 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-85 85 85 85 85 85 0 0 0 0 0 0 0 0 0 85 85 85 +-85 85 85 85 85 85 0 0 0 85 85 85 0 0 0 0 0 0 +-85 85 85 170 170 170 170 170 170 255 255 85 170 170 170 255 255 255 +-255 255 255 170 170 170 255 255 255 170 170 170 170 170 170 255 255 85 +-170 170 170 255 255 85 170 170 170 255 255 255 170 170 170 255 255 255 +-255 255 255 255 255 255 255 255 255 255 255 255 170 170 170 255 255 85 +-85 85 85 85 85 85 0 0 0 0 0 0 85 85 85 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 85 85 85 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 85 85 85 170 85 0 170 170 170 +-170 170 170 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 +-170 170 170 170 170 170 170 170 170 170 170 170 255 255 85 170 170 170 +-255 255 85 255 255 255 170 170 170 255 255 255 170 170 170 170 170 170 +-170 170 170 170 170 170 85 85 85 0 0 0 85 85 85 85 85 85 +-0 0 0 85 85 85 0 0 0 85 85 85 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-85 85 85 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 85 85 85 85 85 85 +-85 85 85 85 85 85 0 0 0 85 85 85 0 0 0 0 0 0 +-85 85 85 85 85 85 170 170 170 170 170 170 255 255 255 170 170 170 +-255 255 255 170 170 170 255 255 85 170 170 170 170 170 170 170 170 170 +-255 85 85 170 170 170 170 170 170 170 170 170 255 255 255 255 255 255 +-170 170 170 255 255 255 255 255 255 170 170 170 255 255 255 170 170 170 +-85 85 85 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 85 85 85 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 85 85 85 85 85 85 170 170 170 +-255 255 85 170 170 170 255 255 255 170 170 170 255 255 255 255 255 255 +-255 255 85 255 255 255 170 170 170 255 255 85 170 170 170 170 170 170 +-170 170 170 170 170 170 255 255 85 170 170 170 170 170 170 255 255 85 +-170 170 170 170 85 0 85 85 85 0 0 0 85 85 85 0 0 0 +-0 0 0 85 85 85 0 0 0 0 0 0 0 0 0 0 0 0 +-85 85 85 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 85 85 85 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 85 85 85 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 170 170 170 170 170 170 +-170 170 170 85 85 85 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 85 85 85 170 170 170 255 255 85 170 170 170 170 170 170 +-255 255 85 170 170 170 170 170 170 170 170 170 170 170 170 255 85 85 +-85 255 85 170 170 170 170 170 170 170 170 170 255 255 85 170 170 170 +-255 255 255 255 255 255 255 255 255 255 255 85 170 170 170 170 170 170 +-85 85 85 0 0 0 0 0 0 85 85 85 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 85 85 85 255 255 85 +-170 170 170 170 170 170 255 255 255 255 255 255 255 255 255 170 170 170 +-255 255 255 170 170 170 170 170 170 170 170 170 170 170 170 255 85 85 +-170 170 170 170 170 170 170 170 170 170 170 170 170 170 170 170 170 170 +-170 170 170 85 85 85 85 85 85 0 0 0 85 85 85 0 0 0 +-85 85 85 0 0 0 0 0 0 85 85 85 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-85 85 85 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 170 170 170 170 170 170 170 170 170 +-85 85 85 0 0 0 0 0 0 0 0 0 0 0 0 85 85 85 +-0 0 0 85 85 85 170 85 0 170 170 170 170 170 170 170 170 170 +-170 170 170 170 170 170 170 170 170 170 85 0 170 170 170 85 255 85 +-255 85 85 170 170 170 255 255 85 170 170 170 170 170 170 255 255 255 +-255 255 255 170 170 170 255 255 255 255 255 255 170 170 170 170 170 170 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 85 85 85 170 170 170 +-170 170 170 255 255 85 170 170 170 255 255 85 255 255 255 255 255 255 +-170 170 170 170 170 170 255 255 85 170 170 170 255 85 85 85 255 85 +-170 170 170 170 85 0 170 170 170 170 170 170 255 255 85 170 170 170 +-170 85 0 85 85 85 0 0 0 85 85 85 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 85 85 85 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 85 85 85 +-0 0 0 85 85 85 85 85 85 85 85 85 170 170 170 255 255 85 +-170 170 170 170 85 0 170 170 170 170 170 170 170 85 0 85 85 85 +-170 170 170 170 85 0 85 85 85 170 170 170 170 170 170 170 170 170 +-170 170 170 255 255 255 255 255 255 255 255 85 170 170 170 170 170 170 +-0 0 0 85 85 85 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 85 85 85 170 85 0 +-170 170 170 170 170 170 255 255 255 170 170 170 255 255 255 170 170 170 +-255 255 255 170 170 170 170 170 170 170 85 0 170 170 170 85 85 85 +-170 170 170 170 170 170 170 85 0 170 170 170 170 85 0 85 85 85 +-85 255 85 85 85 85 0 0 0 0 0 0 0 0 0 85 85 85 +-0 0 0 0 0 0 85 85 85 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-85 85 85 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 85 85 85 85 85 85 85 85 85 +-85 85 85 0 0 0 85 85 85 170 85 0 85 85 85 170 170 170 +-170 85 0 170 170 170 85 255 85 170 85 0 170 170 170 85 85 85 +-170 85 0 170 170 170 170 170 170 255 255 85 170 170 170 255 255 255 +-255 255 85 255 255 255 170 170 170 170 170 170 170 170 170 170 85 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 85 85 85 +-170 170 170 170 170 170 170 170 170 170 170 170 170 170 170 255 255 85 +-170 170 170 255 255 85 170 170 170 170 170 170 85 255 85 170 170 170 +-170 85 0 170 85 0 170 170 170 85 255 85 85 85 85 170 170 170 +-170 85 0 85 85 85 0 0 0 85 85 85 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 85 85 85 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 85 85 85 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 85 85 85 170 170 170 85 85 85 +-0 0 0 0 0 0 0 0 0 85 85 85 170 85 0 85 85 85 +-170 170 170 170 85 0 170 170 170 85 85 85 170 170 170 170 85 0 +-170 170 170 85 255 85 170 85 0 170 170 170 170 170 170 170 170 170 +-255 255 255 170 170 170 255 255 255 255 255 255 170 170 170 85 85 85 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-170 85 0 170 170 170 255 255 85 170 170 170 255 255 255 170 170 170 +-170 170 170 170 170 170 170 170 170 170 85 0 170 170 170 170 85 0 +-170 170 170 85 255 85 170 85 0 170 170 170 170 85 0 85 85 85 +-85 85 85 85 85 85 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 85 85 85 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 85 85 85 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 85 85 85 85 85 85 85 85 85 +-85 255 85 170 170 170 170 85 0 170 170 170 170 85 0 85 255 85 +-170 170 170 170 85 0 170 170 170 170 170 170 170 170 170 255 255 85 +-170 170 170 255 255 255 170 170 170 170 170 170 170 170 170 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-85 85 85 170 85 0 85 85 85 170 170 170 255 255 85 170 170 170 +-170 170 170 255 255 85 170 170 170 170 170 170 170 170 170 170 85 0 +-170 170 170 85 85 85 170 170 170 170 85 0 170 170 170 85 85 85 +-170 85 0 85 85 85 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 85 85 85 0 0 0 85 85 85 170 85 0 +-85 85 85 255 85 85 85 255 85 170 85 0 170 170 170 170 170 170 +-170 85 0 170 170 170 85 85 85 255 255 85 170 170 170 170 170 170 +-255 255 255 170 170 170 255 255 255 255 255 85 85 85 85 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 85 85 85 170 170 170 170 85 0 170 170 170 170 170 170 +-170 170 170 170 170 170 170 170 170 255 255 85 85 85 85 170 170 170 +-85 255 85 255 85 85 170 170 170 85 255 85 255 85 85 85 255 85 +-85 85 85 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 85 85 85 85 85 85 0 0 0 85 85 85 +-85 85 85 85 255 85 255 85 85 170 170 170 85 255 85 170 85 0 +-170 170 170 170 170 170 255 255 85 170 170 170 170 170 170 255 255 255 +-170 170 170 255 255 255 170 170 170 170 170 170 85 85 85 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 85 85 85 170 170 170 85 85 85 255 255 85 +-170 170 170 255 255 85 170 170 170 170 170 170 170 170 170 255 255 85 +-85 85 85 255 255 85 170 170 170 170 85 0 170 170 170 85 85 85 +-170 85 0 85 85 85 85 85 85 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 85 85 85 +-170 170 170 170 85 0 170 170 170 170 85 0 170 170 170 170 170 170 +-170 85 0 170 170 170 170 170 170 170 170 170 255 255 85 170 170 170 +-255 255 85 255 255 255 170 170 170 170 170 170 85 85 85 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 85 85 85 170 85 0 85 85 85 170 170 170 +-170 85 0 170 170 170 170 170 170 255 255 85 170 170 170 170 170 170 +-170 170 170 170 170 170 170 170 170 255 255 85 170 170 170 170 85 0 +-85 85 85 85 85 85 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 85 85 85 85 85 85 +-170 85 0 85 255 85 170 170 170 170 170 170 255 255 85 170 170 170 +-255 255 85 170 170 170 170 170 170 170 170 170 255 255 255 255 255 255 +-255 255 255 170 170 170 255 255 85 85 85 85 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 85 85 85 85 85 85 170 85 0 +-170 170 170 170 170 170 170 170 170 170 170 170 170 170 170 255 255 85 +-170 170 170 255 255 85 170 170 170 170 170 170 170 170 170 170 170 170 +-170 170 170 85 85 85 85 85 85 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 85 85 85 +-85 85 85 170 85 0 170 170 170 170 85 0 170 170 170 170 170 170 +-170 170 170 255 255 85 170 170 170 255 255 85 170 170 170 255 255 255 +-170 170 170 255 255 255 170 170 170 85 85 85 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 85 85 85 85 85 85 85 85 85 +-170 85 0 170 170 170 170 85 0 255 255 85 170 170 170 170 170 170 +-170 170 170 170 170 170 255 255 85 170 170 170 255 255 85 170 170 170 +-255 255 85 85 85 85 85 85 85 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 85 85 85 85 85 85 +-85 85 85 170 170 170 255 255 85 170 170 170 255 255 85 170 170 170 +-170 170 170 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 +-170 170 170 170 170 170 170 170 170 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 170 0 85 85 85 +-170 85 0 85 255 85 170 170 170 170 170 170 170 170 170 255 255 85 +-255 255 255 170 170 170 255 255 255 170 170 170 255 255 255 170 170 170 +-170 170 170 255 255 85 85 85 85 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 85 85 85 +-170 85 0 170 170 170 170 170 170 170 170 170 170 170 170 255 255 85 +-170 170 170 255 255 255 170 170 170 255 255 255 170 170 170 255 255 255 +-255 255 255 255 255 85 85 85 85 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 85 85 85 +-85 85 85 170 85 0 170 170 170 170 170 170 255 255 85 170 170 170 +-170 170 170 255 255 255 255 255 255 255 255 255 170 170 170 255 255 255 +-170 170 170 170 170 170 170 170 170 85 85 85 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 85 85 85 85 255 85 +-170 170 170 255 255 85 170 170 170 255 255 85 255 255 255 255 255 255 +-255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 170 170 170 +-170 170 170 170 170 170 85 85 85 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-85 85 85 85 85 85 85 85 85 170 85 0 170 170 170 170 170 170 +-255 255 85 170 170 170 255 255 255 255 255 85 255 255 255 255 255 255 +-170 170 170 255 255 85 170 170 170 85 85 85 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 85 85 85 170 85 0 +-170 170 170 170 170 170 170 170 170 255 255 255 170 170 170 255 255 255 +-170 170 170 255 255 255 170 170 170 255 255 255 255 255 85 255 255 255 +-170 170 170 85 85 85 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-85 85 85 170 85 0 85 85 85 170 170 170 170 170 170 170 170 170 +-170 170 170 255 255 255 170 170 170 255 255 255 255 255 255 170 170 170 +-255 255 85 170 170 170 170 170 170 170 85 0 85 85 85 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 85 85 85 170 170 170 +-255 255 85 170 170 170 255 255 85 170 170 170 255 255 255 255 255 255 +-255 255 255 255 255 255 255 255 255 255 255 255 170 170 170 170 170 170 +-170 170 170 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 85 85 85 85 85 85 85 85 85 170 85 0 170 170 170 +-255 255 85 170 170 170 255 255 85 255 255 255 170 170 170 255 255 255 +-170 170 170 170 170 170 170 170 170 170 170 170 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 85 85 85 170 170 170 +-170 85 0 170 170 170 255 255 255 170 170 170 255 255 255 170 170 170 +-255 255 255 255 255 255 170 170 170 255 255 255 255 255 85 170 170 170 +-85 85 85 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 85 85 85 170 85 0 85 85 85 170 170 170 +-170 170 170 170 170 170 170 170 170 170 170 170 255 255 85 170 170 170 +-255 255 85 170 170 170 170 85 0 85 255 85 85 85 85 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 85 85 85 170 85 0 +-170 170 170 170 170 170 255 255 85 170 170 170 255 255 255 255 255 255 +-255 255 85 255 255 255 170 170 170 255 255 255 170 170 170 85 85 85 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 85 85 85 85 85 85 +-170 85 0 170 170 170 170 170 170 255 255 85 170 170 170 170 170 170 +-170 170 170 170 170 170 170 170 170 170 85 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 85 85 85 85 85 85 +-255 255 85 170 170 170 170 170 170 170 170 170 255 255 85 170 170 170 +-255 255 255 170 170 170 255 255 85 170 170 170 85 85 85 85 85 85 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 85 85 85 85 85 85 +-85 85 85 170 85 0 170 170 170 170 170 170 170 170 170 170 170 170 +-170 85 0 170 170 170 170 85 0 85 85 85 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 85 85 85 85 85 85 +-170 170 170 170 170 170 255 255 85 170 170 170 170 170 170 170 170 170 +-170 170 170 255 255 255 170 170 170 170 170 170 85 85 85 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-85 85 85 85 85 85 85 85 85 170 85 0 85 85 85 170 85 0 +-85 85 85 85 85 85 85 85 85 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 170 85 0 +-85 85 85 170 85 0 170 170 170 170 170 170 170 170 170 255 255 85 +-170 170 170 170 170 170 170 85 0 85 85 85 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 85 85 85 85 85 85 85 85 85 85 85 85 85 85 85 +-85 85 85 85 85 85 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 85 85 85 +-85 85 85 85 255 85 170 85 0 170 170 170 170 85 0 170 170 170 +-85 85 85 85 85 85 85 85 85 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 85 85 85 85 85 85 85 85 85 85 85 85 85 85 85 +-85 85 85 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-0 0 0 0 0 0 0 0 0 0 0 0 ++ 0 0 0 0 0 0 0 0 0 0 0 0 ++ 0 0 0 0 0 0 0 0 0 0 0 0 ++ 0 0 0 0 0 0 0 0 0 0 0 0 ++ 0 0 0 0 0 0 0 0 0 0 0 0 ++ 0 0 0 0 0 0 0 0 0 0 0 0 ++ 0 0 0 0 0 0 0 0 0 0 0 0 ++ 0 0 0 0 0 0 0 0 0 0 0 0 ++ 0 0 0 0 0 0 0 0 0 0 0 0 ++ 0 0 0 0 0 0 0 0 0 0 0 0 ++ 0 0 0 0 0 0 0 0 0 0 0 0 ++ 0 0 0 0 0 0 0 0 0 0 0 0 ++ 0 0 0 0 0 0 0 0 0 0 0 0 ++ 0 0 0 0 0 0 0 0 0 0 0 0 ++ 0 0 0 0 0 0 0 0 0 0 0 0 ++ 0 0 0 0 0 0 0 0 0 0 0 0 ++ 0 0 0 0 0 0 0 0 0 0 0 0 ++ 0 0 0 0 0 0 0 0 0 0 0 0 ++ 0 0 0 0 0 0 0 0 0 0 0 0 ++ 0 0 0 0 0 0 0 0 0 0 0 0 ++ 0 0 0 0 0 0 0 0 0 0 0 0 ++ 0 0 0 0 0 0 0 0 0 0 0 0 ++ 0 0 0 0 0 0 0 0 0 0 0 0 ++ 0 0 0 0 0 0 0 0 0 0 0 0 ++ 0 0 0 0 0 0 0 0 0 0 0 0 ++ 0 0 0 0 0 0 0 0 0 0 0 0 ++ 0 0 0 0 0 0 0 0 0 0 0 0 ++ 0 0 0 0 0 0 0 0 0 0 0 0 ++ 0 0 0 0 0 0 0 0 0 0 0 0 ++ 0 0 0 0 0 0 0 0 0 0 0 0 ++ 0 0 0 0 0 0 0 0 0 0 0 0 ++ 0 0 0 0 0 0 0 0 0 0 0 0 ++ 0 0 0 0 0 0 0 0 0 0 0 0 ++ 0 0 0 0 0 0 0 0 0 0 0 0 ++ 0 0 0 0 0 0 0 0 0 0 0 0 ++ 0 0 0 0 0 0 0 0 0 0 0 0 ++ 0 0 0 0 0 0 0 0 0 0 0 0 ++ 0 0 0 0 0 0 0 0 0 0 0 0 ++ 0 0 0 0 0 0 0 0 0 0 0 0 ++ 0 0 0 0 0 0 0 0 0 0 0 0 ++ 0 0 0 0 0 0 0 0 0 0 0 0 ++ 0 0 0 0 0 0 0 0 0 0 0 0 ++ 0 0 0 0 0 0 0 0 0 0 0 0 ++ 0 0 0 0 0 0 0 0 0 0 0 0 ++ 0 0 0 0 0 0 0 0 0 0 0 0 ++ 0 0 0 0 0 0 0 0 0 0 0 0 ++ 0 0 0 0 0 0 0 0 0 0 0 0 ++ 0 0 0 0 0 0 0 0 0 0 0 0 ++ 0 0 0 0 0 0 0 0 0 0 0 0 ++ 0 0 0 0 0 0 0 0 0 0 0 0 ++ 85 85 85 85 85 85 85 85 85 85 85 85 ++ 85 85 85 85 85 85 85 85 85 0 0 0 ++ 0 0 0 0 0 0 0 0 0 0 0 0 ++ 0 0 0 0 0 0 0 0 0 0 0 0 ++ 0 0 0 0 0 0 0 0 0 0 0 0 ++ 0 0 0 0 0 0 0 0 0 0 0 0 ++ 0 0 0 0 0 0 0 0 0 0 0 0 ++ 0 0 0 0 0 0 0 0 0 0 0 0 ++ 0 0 0 0 0 0 0 0 0 0 0 0 ++ 0 0 0 0 0 0 0 0 0 0 0 0 ++ 0 0 0 0 0 0 0 0 0 0 0 0 ++ 0 0 0 0 0 0 0 0 0 0 0 0 ++ 0 0 0 0 0 0 0 0 0 0 0 0 ++ 0 0 0 0 0 0 0 0 0 0 0 0 ++ 0 0 0 0 0 0 0 0 0 0 0 0 ++ 0 0 0 0 0 0 0 0 0 0 0 0 ++ 0 0 0 0 0 0 0 0 0 0 0 0 ++ 0 0 0 0 0 0 0 0 0 0 0 0 ++ 0 0 0 0 0 0 0 0 0 0 0 0 ++ 0 0 0 0 0 0 85 85 85 85 85 85 ++ 85 85 85 0 0 0 0 0 0 0 0 0 ++ 0 0 0 0 0 0 0 0 0 85 85 85 ++ 85 85 85 85 85 85 0 0 0 0 0 0 ++ 0 0 0 0 0 0 0 0 0 0 0 0 ++ 0 0 0 0 0 0 0 0 0 0 0 0 ++ 0 0 0 0 0 0 0 0 0 0 0 0 ++ 0 0 0 0 0 0 0 0 0 0 0 0 ++ 0 0 0 0 0 0 0 0 0 0 0 0 ++ 0 0 0 0 0 0 0 0 0 0 0 0 ++ 0 0 0 0 0 0 0 0 0 0 0 0 ++ 0 0 0 0 0 0 0 0 0 0 0 0 ++ 0 0 0 0 0 0 0 0 0 0 0 0 ++ 0 0 0 0 0 0 0 0 0 0 0 0 ++ 0 0 0 0 0 0 0 0 0 0 0 0 ++ 0 0 0 0 0 0 0 0 0 0 0 0 ++ 0 0 0 0 0 0 0 0 0 0 0 0 ++ 0 0 0 0 0 0 0 0 0 0 0 0 ++ 0 0 0 0 0 0 0 0 0 0 0 0 ++ 0 0 0 0 0 0 0 0 0 0 0 0 ++ 0 0 0 85 85 85 0 0 0 0 0 0 ++ 0 0 0 0 0 0 0 0 0 0 0 0 ++ 0 0 0 0 0 0 0 0 0 0 0 0 ++ 0 0 0 0 0 0 85 85 85 85 85 85 ++ 0 0 0 0 0 0 0 0 0 0 0 0 ++ 0 0 0 0 0 0 0 0 0 0 0 0 ++ 0 0 0 0 0 0 0 0 0 0 0 0 ++ 0 0 0 0 0 0 0 0 0 0 0 0 ++ 0 0 0 0 0 0 0 0 0 0 0 0 ++ 0 0 0 0 0 0 0 0 0 0 0 0 ++ 0 0 0 0 0 0 0 0 0 0 0 0 ++ 0 0 0 0 0 0 0 0 0 0 0 0 ++ 0 0 0 0 0 0 0 0 0 0 0 0 ++ 0 0 0 0 0 0 0 0 0 0 0 0 ++ 0 0 0 0 0 0 0 0 0 0 0 0 ++ 0 0 0 0 0 0 0 0 0 0 0 0 ++ 0 0 0 0 0 0 0 0 0 0 0 0 ++ 0 0 0 0 0 0 0 0 0 0 0 0 ++ 0 0 0 0 0 0 0 0 0 0 0 0 ++ 0 0 0 0 0 0 0 0 0 0 0 0 ++ 85 85 85 0 0 0 0 0 0 0 0 0 ++ 0 0 0 0 0 0 0 0 0 0 0 0 ++ 0 0 0 0 0 0 0 0 0 0 0 0 ++ 0 0 0 0 0 0 0 0 0 85 85 85 ++ 85 85 85 0 0 0 0 0 0 0 0 0 ++ 0 0 0 0 0 0 0 0 0 0 0 0 ++ 0 0 0 0 0 0 0 0 0 0 0 0 ++ 0 0 0 0 0 0 0 0 0 0 0 0 ++ 0 0 0 0 0 0 0 0 0 0 0 0 ++ 0 0 0 0 0 0 0 0 0 0 0 0 ++ 0 0 0 0 0 0 0 0 0 0 0 0 ++ 0 0 0 0 0 0 0 0 0 0 0 0 ++ 0 0 0 0 0 0 0 0 0 0 0 0 ++ 0 0 0 0 0 0 0 0 0 0 0 0 ++ 0 0 0 0 0 0 0 0 0 0 0 0 ++ 0 0 0 0 0 0 0 0 0 0 0 0 ++ 0 0 0 0 0 0 0 0 0 0 0 0 ++ 0 0 0 0 0 0 0 0 0 0 0 0 ++ 0 0 0 0 0 0 0 0 0 0 0 0 ++ 0 0 0 0 0 0 0 0 0 85 85 85 ++ 0 0 0 0 0 0 0 0 0 0 0 0 ++ 0 0 0 0 0 0 0 0 0 0 0 0 ++ 0 0 0 0 0 0 0 0 0 0 0 0 ++ 0 0 0 0 0 0 0 0 0 0 0 0 ++ 85 85 85 85 85 85 0 0 0 0 0 0 ++ 0 0 0 0 0 0 0 0 0 0 0 0 ++ 0 0 0 0 0 0 0 0 0 0 0 0 ++ 0 0 0 0 0 0 0 0 0 0 0 0 ++ 0 0 0 0 0 0 0 0 0 0 0 0 ++ 0 0 0 0 0 0 0 0 0 0 0 0 ++ 0 0 0 0 0 0 0 0 0 0 0 0 ++ 0 0 0 0 0 0 0 0 0 0 0 0 ++ 0 0 0 0 0 0 0 0 0 0 0 0 ++ 0 0 0 0 0 0 0 0 0 0 0 0 ++ 0 0 0 0 0 0 0 0 0 0 0 0 ++ 0 0 0 0 0 0 0 0 0 0 0 0 ++ 0 0 0 0 0 0 0 0 0 0 0 0 ++ 0 0 0 0 0 0 0 0 0 0 0 0 ++ 0 0 0 0 0 0 0 0 0 0 0 0 ++ 0 0 0 0 0 0 0 0 0 85 85 85 ++ 0 0 0 0 0 0 0 0 0 0 0 0 ++ 0 0 0 0 0 0 0 0 0 0 0 0 ++ 0 0 0 0 0 0 0 0 0 0 0 0 ++ 85 85 85 170 170 170 0 0 0 0 0 0 ++ 0 0 0 85 85 85 0 0 0 0 0 0 ++ 0 0 0 0 0 0 0 0 0 0 0 0 ++ 0 0 0 0 0 0 0 0 0 0 0 0 ++ 0 0 0 0 0 0 0 0 0 0 0 0 ++ 0 0 0 0 0 0 0 0 0 0 0 0 ++ 0 0 0 0 0 0 0 0 0 0 0 0 ++ 0 0 0 0 0 0 0 0 0 0 0 0 ++ 0 0 0 0 0 0 0 0 0 0 0 0 ++ 0 0 0 0 0 0 0 0 0 0 0 0 ++ 0 0 0 0 0 0 0 0 0 0 0 0 ++ 0 0 0 0 0 0 0 0 0 0 0 0 ++ 0 0 0 0 0 0 0 0 0 0 0 0 ++ 0 0 0 0 0 0 0 0 0 0 0 0 ++ 0 0 0 0 0 0 0 0 0 0 0 0 ++ 0 0 0 0 0 0 0 0 0 0 0 0 ++ 0 0 0 0 0 0 85 85 85 0 0 0 ++ 0 0 0 0 0 0 0 0 0 0 0 0 ++ 0 0 0 0 0 0 0 0 0 0 0 0 ++ 0 0 0 0 0 0 0 0 0 0 0 0 ++170 170 170 170 170 170 85 85 85 0 0 0 ++ 0 0 0 0 0 0 85 85 85 0 0 0 ++ 0 0 0 0 0 0 0 0 0 0 0 0 ++ 0 0 0 0 0 0 0 0 0 0 0 0 ++ 0 0 0 0 0 0 0 0 0 0 0 0 ++ 0 0 0 0 0 0 0 0 0 0 0 0 ++ 0 0 0 0 0 0 0 0 0 0 0 0 ++ 0 0 0 0 0 0 0 0 0 0 0 0 ++ 0 0 0 0 0 0 0 0 0 0 0 0 ++ 0 0 0 0 0 0 0 0 0 0 0 0 ++ 0 0 0 0 0 0 0 0 0 0 0 0 ++ 0 0 0 0 0 0 0 0 0 0 0 0 ++ 0 0 0 0 0 0 0 0 0 0 0 0 ++ 0 0 0 0 0 0 0 0 0 0 0 0 ++ 0 0 0 0 0 0 0 0 0 0 0 0 ++ 0 0 0 0 0 0 0 0 0 0 0 0 ++ 0 0 0 0 0 0 85 85 85 0 0 0 ++ 0 0 0 0 0 0 0 0 0 0 0 0 ++ 0 0 0 0 0 0 0 0 0 0 0 0 ++ 0 0 0 0 0 0 0 0 0 0 0 0 ++ 0 0 0 85 85 85 0 0 0 0 0 0 ++ 0 0 0 0 0 0 0 0 0 85 85 85 ++ 0 0 0 0 0 0 0 0 0 0 0 0 ++ 0 0 0 0 0 0 0 0 0 0 0 0 ++ 0 0 0 0 0 0 0 0 0 0 0 0 ++ 0 0 0 0 0 0 0 0 0 0 0 0 ++ 0 0 0 0 0 0 0 0 0 0 0 0 ++ 0 0 0 0 0 0 0 0 0 0 0 0 ++ 0 0 0 0 0 0 0 0 0 0 0 0 ++ 0 0 0 0 0 0 0 0 0 0 0 0 ++ 0 0 0 0 0 0 0 0 0 0 0 0 ++ 0 0 0 0 0 0 0 0 0 0 0 0 ++ 0 0 0 0 0 0 0 0 0 0 0 0 ++ 0 0 0 0 0 0 0 0 0 0 0 0 ++ 0 0 0 0 0 0 0 0 0 0 0 0 ++ 0 0 0 0 0 0 0 0 0 0 0 0 ++ 0 0 0 0 0 0 85 85 85 0 0 0 ++ 0 0 0 0 0 0 0 0 0 0 0 0 ++ 0 0 0 0 0 0 0 0 0 0 0 0 ++ 0 0 0 0 0 0 0 0 0 0 0 0 ++ 0 0 0 0 0 0 0 0 0 0 0 0 ++ 0 0 0 0 0 0 0 0 0 85 85 85 ++ 0 0 0 0 0 0 0 0 0 0 0 0 ++ 0 0 0 0 0 0 0 0 0 0 0 0 ++ 0 0 0 0 0 0 0 0 0 0 0 0 ++ 0 0 0 0 0 0 0 0 0 0 0 0 ++ 0 0 0 0 0 0 0 0 0 0 0 0 ++ 0 0 0 0 0 0 0 0 0 0 0 0 ++ 0 0 0 0 0 0 0 0 0 0 0 0 ++ 0 0 0 0 0 0 0 0 0 0 0 0 ++ 0 0 0 0 0 0 0 0 0 0 0 0 ++ 0 0 0 0 0 0 0 0 0 0 0 0 ++ 0 0 0 0 0 0 0 0 0 0 0 0 ++ 0 0 0 0 0 0 0 0 0 0 0 0 ++ 0 0 0 0 0 0 0 0 0 0 0 0 ++ 0 0 0 0 0 0 0 0 0 0 0 0 ++ 0 0 0 85 85 85 0 0 0 0 0 0 ++ 0 0 0 0 0 0 0 0 0 0 0 0 ++ 0 0 0 0 0 0 0 0 0 0 0 0 ++ 0 0 0 0 0 0 0 0 0 0 0 0 ++ 0 0 0 0 0 0 0 0 0 0 0 0 ++ 0 0 0 0 0 0 0 0 0 85 85 85 ++ 0 0 0 0 0 0 0 0 0 0 0 0 ++ 0 0 0 0 0 0 0 0 0 0 0 0 ++ 0 0 0 0 0 0 0 0 0 0 0 0 ++ 0 0 0 0 0 0 0 0 0 0 0 0 ++ 0 0 0 0 0 0 0 0 0 0 0 0 ++ 0 0 0 0 0 0 0 0 0 0 0 0 ++ 0 0 0 0 0 0 0 0 0 0 0 0 ++ 0 0 0 0 0 0 0 0 0 0 0 0 ++ 0 0 0 0 0 0 0 0 0 0 0 0 ++ 0 0 0 0 0 0 0 0 0 0 0 0 ++ 0 0 0 0 0 0 0 0 0 0 0 0 ++ 0 0 0 0 0 0 0 0 0 0 0 0 ++ 0 0 0 0 0 0 0 0 0 0 0 0 ++ 0 0 0 0 0 0 0 0 0 0 0 0 ++ 0 0 0 85 85 85 0 0 0 0 0 0 ++ 0 0 0 0 0 0 0 0 0 0 0 0 ++ 0 0 0 0 0 0 0 0 0 0 0 0 ++ 0 0 0 0 0 0 0 0 0 0 0 0 ++ 0 0 0 0 0 0 0 0 0 0 0 0 ++ 0 0 0 0 0 0 0 0 0 0 0 0 ++ 85 85 85 0 0 0 0 0 0 0 0 0 ++ 0 0 0 0 0 0 0 0 0 0 0 0 ++ 0 0 0 0 0 0 0 0 0 0 0 0 ++ 0 0 0 0 0 0 0 0 0 0 0 0 ++ 0 0 0 0 0 0 0 0 0 0 0 0 ++ 0 0 0 0 0 0 0 0 0 0 0 0 ++ 0 0 0 0 0 0 0 0 0 0 0 0 ++ 0 0 0 0 0 0 0 0 0 0 0 0 ++ 0 0 0 0 0 0 0 0 0 0 0 0 ++ 0 0 0 0 0 0 0 0 0 0 0 0 ++ 0 0 0 0 0 0 0 0 0 0 0 0 ++ 0 0 0 0 0 0 0 0 0 0 0 0 ++ 0 0 0 0 0 0 0 0 0 0 0 0 ++ 0 0 0 0 0 0 0 0 0 0 0 0 ++ 0 0 0 85 85 85 0 0 0 0 0 0 ++ 0 0 0 0 0 0 0 0 0 0 0 0 ++ 0 0 0 0 0 0 0 0 0 0 0 0 ++ 0 0 0 0 0 0 0 0 0 0 0 0 ++ 0 0 0 0 0 0 0 0 0 0 0 0 ++ 0 0 0 0 0 0 0 0 0 0 0 0 ++ 85 85 85 0 0 0 0 0 0 0 0 0 ++ 0 0 0 0 0 0 0 0 0 0 0 0 ++ 0 0 0 0 0 0 0 0 0 0 0 0 ++ 0 0 0 0 0 0 0 0 0 0 0 0 ++ 0 0 0 0 0 0 0 0 0 0 0 0 ++ 0 0 0 0 0 0 0 0 0 0 0 0 ++ 0 0 0 0 0 0 0 0 0 0 0 0 ++ 0 0 0 0 0 0 0 0 0 0 0 0 ++ 0 0 0 0 0 0 0 0 0 0 0 0 ++ 0 0 0 0 0 0 0 0 0 0 0 0 ++ 0 0 0 0 0 0 0 0 0 0 0 0 ++ 0 0 0 0 0 0 0 0 0 0 0 0 ++ 0 0 0 0 0 0 0 0 0 0 0 0 ++ 0 0 0 0 0 0 0 0 0 0 0 0 ++ 0 0 0 85 85 85 0 0 0 0 0 0 ++ 0 0 0 85 85 85 170 170 170 0 0 0 ++ 0 0 0 0 0 0 0 0 0 0 0 0 ++ 0 0 0 0 0 0 170 170 170 170 170 170 ++170 170 170 0 0 0 0 0 0 0 0 0 ++ 0 0 0 0 0 0 0 0 0 0 0 0 ++ 85 85 85 0 0 0 0 0 0 0 0 0 ++ 0 0 0 0 0 0 0 0 0 0 0 0 ++ 0 0 0 0 0 0 0 0 0 0 0 0 ++ 0 0 0 0 0 0 0 0 0 0 0 0 ++ 0 0 0 0 0 0 0 0 0 0 0 0 ++ 0 0 0 0 0 0 0 0 0 0 0 0 ++ 0 0 0 0 0 0 0 0 0 0 0 0 ++ 0 0 0 0 0 0 0 0 0 0 0 0 ++ 0 0 0 0 0 0 0 0 0 0 0 0 ++ 0 0 0 0 0 0 0 0 0 0 0 0 ++ 0 0 0 0 0 0 0 0 0 0 0 0 ++ 0 0 0 0 0 0 0 0 0 0 0 0 ++ 0 0 0 0 0 0 0 0 0 0 0 0 ++ 0 0 0 0 0 0 0 0 0 0 0 0 ++ 0 0 0 85 85 85 0 0 0 0 0 0 ++ 85 85 85 170 170 170 170 170 170 170 170 170 ++ 0 0 0 0 0 0 0 0 0 0 0 0 ++ 0 0 0 170 170 170 255 255 255 255 255 255 ++255 255 255 170 170 170 0 0 0 0 0 0 ++ 0 0 0 0 0 0 0 0 0 0 0 0 ++ 85 85 85 0 0 0 0 0 0 0 0 0 ++ 0 0 0 0 0 0 0 0 0 0 0 0 ++ 0 0 0 0 0 0 0 0 0 0 0 0 ++ 0 0 0 0 0 0 0 0 0 0 0 0 ++ 0 0 0 0 0 0 0 0 0 0 0 0 ++ 0 0 0 0 0 0 0 0 0 0 0 0 ++ 0 0 0 0 0 0 0 0 0 0 0 0 ++ 0 0 0 0 0 0 0 0 0 0 0 0 ++ 0 0 0 0 0 0 0 0 0 0 0 0 ++ 0 0 0 0 0 0 0 0 0 0 0 0 ++ 0 0 0 0 0 0 0 0 0 0 0 0 ++ 0 0 0 0 0 0 0 0 0 0 0 0 ++ 0 0 0 0 0 0 0 0 0 0 0 0 ++ 0 0 0 0 0 0 0 0 0 0 0 0 ++ 0 0 0 85 85 85 0 0 0 85 85 85 ++170 170 170 170 170 170 255 255 255 255 255 255 ++ 0 0 0 0 0 0 0 0 0 0 0 0 ++170 170 170 255 255 255 170 170 170 170 170 170 ++255 255 255 170 170 170 0 0 0 0 0 0 ++ 0 0 0 0 0 0 0 0 0 0 0 0 ++ 85 85 85 0 0 0 0 0 0 0 0 0 ++ 0 0 0 0 0 0 0 0 0 0 0 0 ++ 0 0 0 0 0 0 0 0 0 0 0 0 ++ 0 0 0 0 0 0 0 0 0 0 0 0 ++ 0 0 0 0 0 0 0 0 0 0 0 0 ++ 0 0 0 0 0 0 0 0 0 0 0 0 ++ 0 0 0 0 0 0 0 0 0 0 0 0 ++ 0 0 0 0 0 0 0 0 0 0 0 0 ++ 0 0 0 0 0 0 0 0 0 0 0 0 ++ 0 0 0 0 0 0 0 0 0 0 0 0 ++ 0 0 0 0 0 0 0 0 0 0 0 0 ++ 0 0 0 0 0 0 0 0 0 0 0 0 ++ 0 0 0 0 0 0 0 0 0 0 0 0 ++ 0 0 0 0 0 0 0 0 0 0 0 0 ++ 0 0 0 85 85 85 0 0 0 85 85 85 ++170 170 170 0 0 0 0 0 0 255 255 255 ++ 85 85 85 0 0 0 0 0 0 0 0 0 ++255 255 255 170 170 170 0 0 0 85 85 85 ++170 170 170 255 255 255 170 170 170 0 0 0 ++ 0 0 0 0 0 0 0 0 0 0 0 0 ++ 85 85 85 0 0 0 0 0 0 0 0 0 ++ 0 0 0 0 0 0 0 0 0 0 0 0 ++ 0 0 0 0 0 0 0 0 0 0 0 0 ++ 0 0 0 0 0 0 0 0 0 0 0 0 ++ 0 0 0 0 0 0 0 0 0 0 0 0 ++ 0 0 0 0 0 0 0 0 0 0 0 0 ++ 0 0 0 0 0 0 0 0 0 0 0 0 ++ 0 0 0 0 0 0 0 0 0 0 0 0 ++ 0 0 0 0 0 0 0 0 0 0 0 0 ++ 0 0 0 0 0 0 0 0 0 0 0 0 ++ 0 0 0 0 0 0 0 0 0 0 0 0 ++ 0 0 0 0 0 0 0 0 0 0 0 0 ++ 0 0 0 0 0 0 0 0 0 0 0 0 ++ 0 0 0 0 0 0 0 0 0 0 0 0 ++ 0 0 0 85 85 85 0 0 0 85 85 85 ++ 85 85 85 0 0 0 0 0 0 170 170 170 ++ 85 85 85 0 0 0 0 0 0 0 0 0 ++255 255 255 85 85 85 0 0 0 0 0 0 ++ 85 85 85 255 255 255 170 170 170 0 0 0 ++ 0 0 0 0 0 0 0 0 0 0 0 0 ++ 85 85 85 0 0 0 0 0 0 0 0 0 ++ 0 0 0 0 0 0 0 0 0 0 0 0 ++ 0 0 0 0 0 0 0 0 0 0 0 0 ++ 0 0 0 0 0 0 0 0 0 0 0 0 ++ 0 0 0 0 0 0 0 0 0 0 0 0 ++ 0 0 0 0 0 0 0 0 0 0 0 0 ++ 0 0 0 0 0 0 0 0 0 0 0 0 ++ 0 0 0 0 0 0 0 0 0 0 0 0 ++ 0 0 0 0 0 0 0 0 0 0 0 0 ++ 0 0 0 0 0 0 0 0 0 0 0 0 ++ 0 0 0 0 0 0 0 0 0 0 0 0 ++ 0 0 0 0 0 0 0 0 0 0 0 0 ++ 0 0 0 0 0 0 0 0 0 0 0 0 ++ 0 0 0 0 0 0 0 0 0 0 0 0 ++ 0 0 0 85 85 85 0 0 0 85 85 85 ++170 170 170 0 0 0 0 0 0 170 170 170 ++ 85 85 85 85 85 85 85 85 85 85 85 85 ++255 255 255 85 85 85 0 0 0 0 0 0 ++ 85 85 85 255 255 255 170 170 170 0 0 0 ++ 0 0 0 0 0 0 0 0 0 0 0 0 ++ 85 85 85 0 0 0 0 0 0 0 0 0 ++ 0 0 0 0 0 0 0 0 0 0 0 0 ++ 0 0 0 0 0 0 0 0 0 0 0 0 ++ 0 0 0 0 0 0 0 0 0 0 0 0 ++ 0 0 0 0 0 0 0 0 0 0 0 0 ++ 0 0 0 0 0 0 0 0 0 0 0 0 ++ 0 0 0 0 0 0 0 0 0 0 0 0 ++ 0 0 0 0 0 0 0 0 0 0 0 0 ++ 0 0 0 0 0 0 0 0 0 0 0 0 ++ 0 0 0 0 0 0 0 0 0 0 0 0 ++ 0 0 0 0 0 0 0 0 0 0 0 0 ++ 0 0 0 0 0 0 0 0 0 0 0 0 ++ 0 0 0 0 0 0 0 0 0 0 0 0 ++ 0 0 0 0 0 0 0 0 0 0 0 0 ++ 0 0 0 85 85 85 0 0 0 0 0 0 ++255 255 255 0 0 0 0 0 0 170 85 0 ++255 255 85 170 85 0 255 255 85 170 85 0 ++255 255 85 170 85 0 0 0 0 0 0 0 ++ 85 85 85 255 255 255 0 0 0 0 0 0 ++ 0 0 0 0 0 0 0 0 0 0 0 0 ++ 85 85 85 0 0 0 0 0 0 0 0 0 ++ 0 0 0 0 0 0 0 0 0 0 0 0 ++ 0 0 0 0 0 0 0 0 0 0 0 0 ++ 0 0 0 0 0 0 0 0 0 0 0 0 ++ 0 0 0 0 0 0 0 0 0 0 0 0 ++ 0 0 0 0 0 0 0 0 0 0 0 0 ++ 0 0 0 0 0 0 0 0 0 0 0 0 ++ 0 0 0 0 0 0 0 0 0 0 0 0 ++ 0 0 0 0 0 0 0 0 0 0 0 0 ++ 0 0 0 0 0 0 0 0 0 0 0 0 ++ 0 0 0 0 0 0 0 0 0 0 0 0 ++ 0 0 0 0 0 0 0 0 0 0 0 0 ++ 0 0 0 0 0 0 0 0 0 0 0 0 ++ 0 0 0 0 0 0 0 0 0 0 0 0 ++ 0 0 0 85 85 85 0 0 0 0 0 0 ++170 170 170 170 170 170 170 85 0 255 255 85 ++170 85 0 255 255 85 170 85 0 255 255 85 ++170 85 0 255 255 85 170 85 0 255 255 85 ++170 170 170 170 170 170 0 0 0 0 0 0 ++ 0 0 0 0 0 0 0 0 0 0 0 0 ++ 85 85 85 0 0 0 0 0 0 0 0 0 ++ 0 0 0 0 0 0 0 0 0 0 0 0 ++ 0 0 0 0 0 0 0 0 0 0 0 0 ++ 0 0 0 0 0 0 0 0 0 0 0 0 ++ 0 0 0 0 0 0 0 0 0 0 0 0 ++ 0 0 0 0 0 0 0 0 0 0 0 0 ++ 0 0 0 0 0 0 0 0 0 0 0 0 ++ 0 0 0 0 0 0 0 0 0 0 0 0 ++ 0 0 0 0 0 0 0 0 0 0 0 0 ++ 0 0 0 0 0 0 0 0 0 0 0 0 ++ 0 0 0 0 0 0 0 0 0 0 0 0 ++ 0 0 0 0 0 0 0 0 0 0 0 0 ++ 0 0 0 0 0 0 0 0 0 0 0 0 ++ 0 0 0 0 0 0 0 0 0 0 0 0 ++ 0 0 0 85 85 85 0 0 0 0 0 0 ++ 0 0 0 170 85 0 255 255 85 170 85 0 ++255 255 85 170 85 0 255 255 85 170 85 0 ++255 255 85 170 85 0 255 255 85 170 85 0 ++255 255 85 170 85 0 0 0 0 0 0 0 ++ 0 0 0 0 0 0 0 0 0 0 0 0 ++ 85 85 85 0 0 0 0 0 0 0 0 0 ++ 0 0 0 0 0 0 0 0 0 0 0 0 ++ 0 0 0 0 0 0 0 0 0 0 0 0 ++ 0 0 0 0 0 0 0 0 0 0 0 0 ++ 0 0 0 0 0 0 0 0 0 0 0 0 ++ 0 0 0 0 0 0 0 0 0 0 0 0 ++ 0 0 0 0 0 0 0 0 0 0 0 0 ++ 0 0 0 0 0 0 0 0 0 0 0 0 ++ 0 0 0 0 0 0 0 0 0 0 0 0 ++ 0 0 0 0 0 0 0 0 0 0 0 0 ++ 0 0 0 0 0 0 0 0 0 0 0 0 ++ 0 0 0 0 0 0 0 0 0 0 0 0 ++ 0 0 0 0 0 0 0 0 0 0 0 0 ++ 0 0 0 0 0 0 0 0 0 0 0 0 ++ 0 0 0 85 85 85 0 0 0 0 0 0 ++170 85 0 255 255 85 170 85 0 255 255 85 ++170 85 0 255 255 85 170 85 0 255 255 85 ++170 85 0 255 255 85 170 85 0 255 255 85 ++170 85 0 255 255 85 170 85 0 0 0 0 ++ 0 0 0 0 0 0 0 0 0 0 0 0 ++ 0 0 0 85 85 85 0 0 0 0 0 0 ++ 0 0 0 0 0 0 0 0 0 0 0 0 ++ 0 0 0 0 0 0 0 0 0 0 0 0 ++ 0 0 0 0 0 0 0 0 0 0 0 0 ++ 0 0 0 0 0 0 0 0 0 0 0 0 ++ 0 0 0 0 0 0 0 0 0 0 0 0 ++ 0 0 0 0 0 0 0 0 0 0 0 0 ++ 0 0 0 0 0 0 0 0 0 0 0 0 ++ 0 0 0 0 0 0 0 0 0 0 0 0 ++ 0 0 0 0 0 0 0 0 0 0 0 0 ++ 0 0 0 0 0 0 0 0 0 0 0 0 ++ 0 0 0 0 0 0 0 0 0 0 0 0 ++ 0 0 0 0 0 0 0 0 0 0 0 0 ++ 0 0 0 0 0 0 0 0 0 0 0 0 ++ 0 0 0 85 85 85 85 85 85 0 0 0 ++255 255 85 170 85 0 255 255 85 170 85 0 ++255 255 85 170 85 0 255 255 85 170 85 0 ++255 255 85 170 85 0 255 255 85 170 85 0 ++255 255 85 170 85 0 170 85 0 0 0 0 ++ 0 0 0 0 0 0 0 0 0 0 0 0 ++ 0 0 0 85 85 85 0 0 0 0 0 0 ++ 0 0 0 0 0 0 0 0 0 0 0 0 ++ 0 0 0 0 0 0 0 0 0 0 0 0 ++ 0 0 0 0 0 0 0 0 0 0 0 0 ++ 0 0 0 0 0 0 0 0 0 0 0 0 ++ 0 0 0 0 0 0 0 0 0 0 0 0 ++ 0 0 0 0 0 0 0 0 0 0 0 0 ++ 0 0 0 0 0 0 0 0 0 0 0 0 ++ 0 0 0 0 0 0 0 0 0 0 0 0 ++ 0 0 0 0 0 0 0 0 0 0 0 0 ++ 0 0 0 0 0 0 0 0 0 0 0 0 ++ 0 0 0 0 0 0 0 0 0 0 0 0 ++ 0 0 0 0 0 0 0 0 0 0 0 0 ++ 0 0 0 0 0 0 0 0 0 0 0 0 ++ 0 0 0 85 85 85 85 85 85 0 0 0 ++170 85 0 255 255 85 170 85 0 255 255 85 ++170 85 0 255 255 85 170 85 0 255 255 85 ++170 85 0 255 255 85 170 85 0 170 85 0 ++170 85 0 170 85 0 85 85 85 0 0 0 ++ 0 0 0 85 85 85 0 0 0 0 0 0 ++ 0 0 0 0 0 0 85 85 85 0 0 0 ++ 0 0 0 0 0 0 0 0 0 0 0 0 ++ 0 0 0 0 0 0 0 0 0 0 0 0 ++ 0 0 0 0 0 0 0 0 0 0 0 0 ++ 0 0 0 0 0 0 0 0 0 0 0 0 ++ 0 0 0 0 0 0 0 0 0 0 0 0 ++ 0 0 0 0 0 0 0 0 0 0 0 0 ++ 0 0 0 0 0 0 0 0 0 0 0 0 ++ 0 0 0 0 0 0 0 0 0 0 0 0 ++ 0 0 0 0 0 0 0 0 0 0 0 0 ++ 0 0 0 0 0 0 0 0 0 0 0 0 ++ 0 0 0 0 0 0 0 0 0 0 0 0 ++ 0 0 0 0 0 0 0 0 0 0 0 0 ++ 0 0 0 0 0 0 0 0 0 0 0 0 ++ 0 0 0 85 85 85 85 85 85 0 0 0 ++ 85 85 85 170 85 0 255 255 85 170 85 0 ++255 255 85 170 85 0 255 255 85 170 85 0 ++170 85 0 170 85 0 170 85 0 170 85 0 ++170 85 0 170 85 0 85 85 85 0 0 0 ++ 0 0 0 85 85 85 170 170 170 85 85 85 ++ 0 0 0 0 0 0 85 85 85 0 0 0 ++ 0 0 0 0 0 0 0 0 0 0 0 0 ++ 0 0 0 0 0 0 0 0 0 0 0 0 ++ 0 0 0 0 0 0 0 0 0 0 0 0 ++ 0 0 0 0 0 0 0 0 0 0 0 0 ++ 0 0 0 0 0 0 0 0 0 0 0 0 ++ 0 0 0 0 0 0 0 0 0 0 0 0 ++ 0 0 0 0 0 0 0 0 0 0 0 0 ++ 0 0 0 0 0 0 0 0 0 0 0 0 ++ 0 0 0 0 0 0 0 0 0 0 0 0 ++ 0 0 0 0 0 0 0 0 0 0 0 0 ++ 0 0 0 0 0 0 0 0 0 0 0 0 ++ 0 0 0 0 0 0 0 0 0 0 0 0 ++ 0 0 0 0 0 0 0 0 0 0 0 0 ++ 0 0 0 85 85 85 85 85 85 0 0 0 ++ 85 85 85 170 85 0 170 85 0 170 85 0 ++170 85 0 170 85 0 170 85 0 170 85 0 ++170 85 0 170 85 0 170 85 0 170 85 0 ++170 170 170 170 170 170 170 170 170 0 0 0 ++ 0 0 0 0 0 0 170 170 170 170 170 170 ++ 0 0 0 0 0 0 0 0 0 85 85 85 ++ 0 0 0 0 0 0 0 0 0 0 0 0 ++ 0 0 0 0 0 0 0 0 0 0 0 0 ++ 0 0 0 0 0 0 0 0 0 0 0 0 ++ 0 0 0 0 0 0 0 0 0 0 0 0 ++ 0 0 0 0 0 0 0 0 0 0 0 0 ++ 0 0 0 0 0 0 0 0 0 0 0 0 ++ 0 0 0 0 0 0 0 0 0 0 0 0 ++ 0 0 0 0 0 0 0 0 0 0 0 0 ++ 0 0 0 0 0 0 0 0 0 0 0 0 ++ 0 0 0 0 0 0 0 0 0 0 0 0 ++ 0 0 0 0 0 0 0 0 0 0 0 0 ++ 0 0 0 0 0 0 0 0 0 0 0 0 ++ 0 0 0 0 0 0 0 0 0 0 0 0 ++ 0 0 0 85 85 85 0 0 0 0 0 0 ++ 85 85 85 170 170 170 170 85 0 170 85 0 ++170 85 0 170 85 0 170 85 0 170 85 0 ++170 85 0 170 85 0 170 170 170 170 170 170 ++170 170 170 170 170 170 170 170 170 85 85 85 ++ 0 0 0 0 0 0 85 85 85 85 85 85 ++ 0 0 0 0 0 0 0 0 0 85 85 85 ++ 0 0 0 0 0 0 0 0 0 0 0 0 ++ 0 0 0 0 0 0 0 0 0 0 0 0 ++ 0 0 0 0 0 0 0 0 0 0 0 0 ++ 0 0 0 0 0 0 0 0 0 0 0 0 ++ 0 0 0 0 0 0 0 0 0 0 0 0 ++ 0 0 0 0 0 0 0 0 0 0 0 0 ++ 0 0 0 0 0 0 0 0 0 0 0 0 ++ 0 0 0 0 0 0 0 0 0 0 0 0 ++ 0 0 0 0 0 0 0 0 0 0 0 0 ++ 0 0 0 0 0 0 0 0 0 0 0 0 ++ 0 0 0 0 0 0 0 0 0 0 0 0 ++ 0 0 0 0 0 0 0 0 0 0 0 0 ++ 0 0 0 0 0 0 0 0 0 0 0 0 ++ 0 0 0 85 85 85 0 0 0 0 0 0 ++ 85 85 85 170 170 170 170 170 170 170 85 0 ++170 85 0 170 85 0 170 85 0 170 85 0 ++170 170 170 170 170 170 170 170 170 170 170 170 ++255 255 255 255 255 255 255 255 255 170 170 170 ++ 0 0 0 0 0 0 0 0 0 0 0 0 ++ 0 0 0 0 0 0 0 0 0 85 85 85 ++ 0 0 0 0 0 0 0 0 0 0 0 0 ++ 0 0 0 0 0 0 0 0 0 0 0 0 ++ 0 0 0 0 0 0 0 0 0 0 0 0 ++ 0 0 0 0 0 0 0 0 0 0 0 0 ++ 0 0 0 0 0 0 0 0 0 0 0 0 ++ 0 0 0 0 0 0 0 0 0 0 0 0 ++ 0 0 0 0 0 0 0 0 0 0 0 0 ++ 0 0 0 0 0 0 0 0 0 0 0 0 ++ 0 0 0 0 0 0 0 0 0 0 0 0 ++ 0 0 0 0 0 0 0 0 0 0 0 0 ++ 0 0 0 0 0 0 0 0 0 0 0 0 ++ 0 0 0 0 0 0 0 0 0 0 0 0 ++ 0 0 0 0 0 0 0 0 0 0 0 0 ++ 85 85 85 0 0 0 0 0 0 85 85 85 ++255 255 255 255 255 255 170 170 170 170 170 170 ++170 170 170 170 170 170 170 170 170 170 170 170 ++170 170 170 170 170 170 255 255 255 255 255 255 ++255 255 255 255 255 255 255 255 255 255 255 255 ++ 85 85 85 0 0 0 0 0 0 0 0 0 ++ 0 0 0 0 0 0 0 0 0 0 0 0 ++ 85 85 85 0 0 0 0 0 0 0 0 0 ++ 0 0 0 0 0 0 0 0 0 0 0 0 ++ 0 0 0 0 0 0 0 0 0 0 0 0 ++ 0 0 0 0 0 0 0 0 0 0 0 0 ++ 0 0 0 0 0 0 0 0 0 0 0 0 ++ 0 0 0 0 0 0 0 0 0 0 0 0 ++ 0 0 0 0 0 0 0 0 0 0 0 0 ++ 0 0 0 0 0 0 0 0 0 0 0 0 ++ 0 0 0 0 0 0 0 0 0 0 0 0 ++ 0 0 0 0 0 0 0 0 0 0 0 0 ++ 0 0 0 0 0 0 0 0 0 0 0 0 ++ 0 0 0 0 0 0 0 0 0 0 0 0 ++ 0 0 0 0 0 0 0 0 0 0 0 0 ++ 85 85 85 0 0 0 0 0 0 170 170 170 ++255 255 255 255 255 255 170 170 170 170 170 170 ++170 170 170 170 170 170 170 170 170 170 170 170 ++170 170 170 255 255 255 255 255 255 255 255 255 ++255 255 255 255 255 255 255 255 255 255 255 255 ++170 170 170 0 0 0 0 0 0 0 0 0 ++ 0 0 0 0 0 0 0 0 0 0 0 0 ++ 85 85 85 0 0 0 0 0 0 0 0 0 ++ 0 0 0 0 0 0 0 0 0 0 0 0 ++ 0 0 0 0 0 0 0 0 0 0 0 0 ++ 0 0 0 0 0 0 0 0 0 0 0 0 ++ 0 0 0 0 0 0 0 0 0 0 0 0 ++ 0 0 0 0 0 0 0 0 0 0 0 0 ++ 0 0 0 0 0 0 0 0 0 0 0 0 ++ 0 0 0 0 0 0 0 0 0 0 0 0 ++ 0 0 0 0 0 0 0 0 0 0 0 0 ++ 0 0 0 0 0 0 0 0 0 0 0 0 ++ 0 0 0 0 0 0 0 0 0 0 0 0 ++ 0 0 0 0 0 0 0 0 0 0 0 0 ++ 0 0 0 0 0 0 0 0 0 85 85 85 ++ 0 0 0 0 0 0 85 85 85 255 255 255 ++255 255 255 255 255 255 255 255 255 170 170 170 ++170 170 170 170 170 170 170 170 170 170 170 170 ++255 255 255 255 255 255 255 255 255 255 255 255 ++255 255 255 255 255 255 255 255 255 255 255 255 ++255 255 255 0 0 0 0 0 0 0 0 0 ++ 0 0 0 0 0 0 0 0 0 0 0 0 ++ 0 0 0 85 85 85 0 0 0 0 0 0 ++ 0 0 0 0 0 0 0 0 0 0 0 0 ++ 0 0 0 0 0 0 0 0 0 0 0 0 ++ 0 0 0 0 0 0 0 0 0 0 0 0 ++ 0 0 0 0 0 0 0 0 0 0 0 0 ++ 0 0 0 0 0 0 0 0 0 0 0 0 ++ 0 0 0 0 0 0 0 0 0 0 0 0 ++ 0 0 0 0 0 0 0 0 0 0 0 0 ++ 0 0 0 0 0 0 0 0 0 0 0 0 ++ 0 0 0 0 0 0 0 0 0 0 0 0 ++ 0 0 0 0 0 0 0 0 0 0 0 0 ++ 0 0 0 0 0 0 0 0 0 0 0 0 ++ 0 0 0 0 0 0 85 85 85 0 0 0 ++ 0 0 0 85 85 85 170 170 170 255 255 255 ++255 255 255 255 255 255 255 255 255 255 255 255 ++255 255 255 255 255 255 255 255 255 255 255 255 ++255 255 255 255 255 255 255 255 255 255 255 255 ++255 255 255 255 255 255 255 255 255 255 255 255 ++255 255 255 85 85 85 0 0 0 0 0 0 ++ 0 0 0 0 0 0 0 0 0 0 0 0 ++ 0 0 0 0 0 0 85 85 85 0 0 0 ++ 0 0 0 0 0 0 0 0 0 0 0 0 ++ 0 0 0 0 0 0 0 0 0 0 0 0 ++ 0 0 0 0 0 0 0 0 0 0 0 0 ++ 0 0 0 0 0 0 0 0 0 0 0 0 ++ 0 0 0 0 0 0 0 0 0 0 0 0 ++ 0 0 0 0 0 0 0 0 0 0 0 0 ++ 0 0 0 0 0 0 0 0 0 0 0 0 ++ 0 0 0 0 0 0 0 0 0 0 0 0 ++ 0 0 0 0 0 0 0 0 0 0 0 0 ++ 0 0 0 0 0 0 0 0 0 0 0 0 ++ 0 0 0 0 0 0 0 0 0 0 0 0 ++ 0 0 0 85 85 85 0 0 0 0 0 0 ++ 0 0 0 85 85 85 255 255 255 255 255 255 ++255 255 255 255 255 255 255 255 255 255 255 255 ++255 255 255 255 255 255 255 255 255 255 255 255 ++255 255 255 255 255 255 255 255 255 255 255 255 ++255 255 255 255 255 255 255 255 255 255 255 255 ++255 255 255 170 170 170 0 0 0 0 0 0 ++ 0 0 0 0 0 0 0 0 0 0 0 0 ++ 0 0 0 0 0 0 0 0 0 85 85 85 ++ 0 0 0 0 0 0 0 0 0 0 0 0 ++ 0 0 0 0 0 0 0 0 0 0 0 0 ++ 0 0 0 0 0 0 0 0 0 0 0 0 ++ 0 0 0 0 0 0 0 0 0 0 0 0 ++ 0 0 0 0 0 0 0 0 0 0 0 0 ++ 0 0 0 0 0 0 0 0 0 0 0 0 ++ 0 0 0 0 0 0 0 0 0 0 0 0 ++ 0 0 0 0 0 0 0 0 0 0 0 0 ++ 0 0 0 0 0 0 0 0 0 0 0 0 ++ 0 0 0 0 0 0 0 0 0 0 0 0 ++ 0 0 0 0 0 0 0 0 0 0 0 0 ++ 0 0 0 85 85 85 0 0 0 0 0 0 ++ 0 0 0 85 85 85 255 255 255 255 255 255 ++255 255 255 255 255 255 255 255 255 255 255 255 ++255 255 255 255 255 255 255 255 255 255 255 255 ++255 255 255 255 255 255 255 255 255 255 255 255 ++255 255 255 255 255 255 255 255 255 255 255 255 ++255 255 255 255 255 255 0 0 0 0 0 0 ++ 0 0 0 0 0 0 0 0 0 0 0 0 ++ 0 0 0 0 0 0 0 0 0 0 0 0 ++ 85 85 85 0 0 0 0 0 0 0 0 0 ++ 0 0 0 0 0 0 0 0 0 0 0 0 ++ 0 0 0 0 0 0 0 0 0 0 0 0 ++ 0 0 0 0 0 0 0 0 0 0 0 0 ++ 0 0 0 0 0 0 0 0 0 0 0 0 ++ 0 0 0 0 0 0 0 0 0 0 0 0 ++ 0 0 0 0 0 0 0 0 0 0 0 0 ++ 0 0 0 0 0 0 0 0 0 0 0 0 ++ 0 0 0 0 0 0 0 0 0 0 0 0 ++ 0 0 0 0 0 0 0 0 0 0 0 0 ++ 0 0 0 0 0 0 0 0 0 0 0 0 ++ 85 85 85 0 0 0 0 0 0 0 0 0 ++ 85 85 85 170 170 170 255 255 255 255 255 255 ++255 255 255 255 255 255 255 255 255 255 255 255 ++255 255 255 255 255 255 255 255 255 255 255 255 ++255 255 255 255 255 255 255 255 255 255 255 255 ++255 255 255 255 255 255 255 255 255 255 255 255 ++255 255 255 255 255 255 85 85 85 0 0 0 ++ 0 0 0 0 0 0 0 0 0 0 0 0 ++ 0 0 0 0 0 0 0 0 0 0 0 0 ++ 0 0 0 85 85 85 0 0 0 0 0 0 ++ 0 0 0 0 0 0 0 0 0 0 0 0 ++ 0 0 0 0 0 0 0 0 0 0 0 0 ++ 0 0 0 0 0 0 0 0 0 0 0 0 ++ 0 0 0 0 0 0 0 0 0 0 0 0 ++ 0 0 0 0 0 0 0 0 0 0 0 0 ++ 0 0 0 0 0 0 0 0 0 0 0 0 ++ 0 0 0 0 0 0 0 0 0 0 0 0 ++ 0 0 0 0 0 0 0 0 0 0 0 0 ++ 0 0 0 0 0 0 0 0 0 0 0 0 ++ 0 0 0 0 0 0 0 0 0 85 85 85 ++ 0 0 0 0 0 0 0 0 0 0 0 0 ++ 85 85 85 170 170 170 170 170 170 170 170 170 ++255 255 255 255 255 255 255 255 255 170 170 170 ++170 170 170 170 170 170 255 255 255 255 255 255 ++255 255 255 255 255 255 255 255 255 255 255 255 ++170 170 170 170 170 170 170 170 170 170 170 170 ++170 170 170 170 170 170 170 170 170 85 85 85 ++ 0 0 0 0 0 0 0 0 0 0 0 0 ++ 0 0 0 0 0 0 0 0 0 0 0 0 ++ 0 0 0 85 85 85 0 0 0 0 0 0 ++ 0 0 0 0 0 0 0 0 0 0 0 0 ++ 0 0 0 0 0 0 0 0 0 0 0 0 ++ 0 0 0 0 0 0 0 0 0 0 0 0 ++ 0 0 0 0 0 0 0 0 0 0 0 0 ++ 0 0 0 0 0 0 0 0 0 0 0 0 ++ 0 0 0 0 0 0 0 0 0 0 0 0 ++ 0 0 0 0 0 0 0 0 0 0 0 0 ++ 0 0 0 0 0 0 0 0 0 0 0 0 ++ 0 0 0 0 0 0 0 0 0 0 0 0 ++ 0 0 0 0 0 0 0 0 0 85 85 85 ++ 0 0 0 0 0 0 0 0 0 0 0 0 ++170 170 170 170 170 170 170 170 170 255 255 255 ++255 255 255 255 255 255 255 255 255 255 255 255 ++170 170 170 255 255 255 255 255 255 255 255 255 ++255 255 255 255 255 255 255 255 255 255 255 255 ++255 255 255 255 255 255 170 170 170 170 170 170 ++170 170 170 170 170 170 170 170 170 85 85 85 ++ 0 0 0 0 0 0 85 85 85 0 0 0 ++ 0 0 0 0 0 0 0 0 0 0 0 0 ++ 0 0 0 0 0 0 85 85 85 0 0 0 ++ 0 0 0 0 0 0 0 0 0 0 0 0 ++ 0 0 0 0 0 0 0 0 0 0 0 0 ++ 0 0 0 0 0 0 0 0 0 0 0 0 ++ 0 0 0 0 0 0 0 0 0 0 0 0 ++ 0 0 0 0 0 0 0 0 0 0 0 0 ++ 0 0 0 0 0 0 0 0 0 0 0 0 ++ 0 0 0 0 0 0 0 0 0 0 0 0 ++ 0 0 0 0 0 0 0 0 0 0 0 0 ++ 0 0 0 0 0 0 0 0 0 0 0 0 ++ 0 0 0 0 0 0 85 85 85 0 0 0 ++ 0 0 0 0 0 0 0 0 0 0 0 0 ++170 170 170 255 255 255 255 255 255 255 255 255 ++255 255 255 255 255 255 255 255 255 255 255 255 ++255 255 255 255 255 255 255 255 255 255 255 255 ++255 255 255 255 255 255 255 255 255 255 255 255 ++255 255 255 255 255 255 255 255 255 255 255 255 ++255 255 255 170 170 170 170 170 170 170 170 170 ++ 0 0 0 0 0 0 0 0 0 85 85 85 ++ 85 85 85 0 0 0 0 0 0 0 0 0 ++ 0 0 0 0 0 0 85 85 85 0 0 0 ++ 0 0 0 0 0 0 0 0 0 0 0 0 ++ 0 0 0 0 0 0 0 0 0 0 0 0 ++ 0 0 0 0 0 0 0 0 0 0 0 0 ++ 0 0 0 0 0 0 0 0 0 0 0 0 ++ 0 0 0 0 0 0 0 0 0 0 0 0 ++ 0 0 0 0 0 0 0 0 0 0 0 0 ++ 0 0 0 0 0 0 0 0 0 0 0 0 ++ 0 0 0 0 0 0 0 0 0 0 0 0 ++ 0 0 0 0 0 0 0 0 0 0 0 0 ++ 0 0 0 0 0 0 85 85 85 0 0 0 ++ 85 85 85 0 0 0 0 0 0 85 85 85 ++255 255 255 255 255 255 255 255 255 255 255 255 ++255 255 255 255 255 255 255 255 255 255 255 255 ++255 255 255 255 255 255 255 255 255 255 255 255 ++255 255 255 255 255 255 255 255 255 255 255 255 ++255 255 255 255 255 255 255 255 255 255 255 255 ++255 255 255 255 255 255 170 170 170 170 170 170 ++ 85 85 85 0 0 0 0 0 0 0 0 0 ++ 0 0 0 85 85 85 0 0 0 0 0 0 ++ 0 0 0 0 0 0 0 0 0 85 85 85 ++ 0 0 0 0 0 0 0 0 0 0 0 0 ++ 0 0 0 0 0 0 0 0 0 0 0 0 ++ 0 0 0 0 0 0 0 0 0 0 0 0 ++ 0 0 0 0 0 0 0 0 0 0 0 0 ++ 0 0 0 0 0 0 0 0 0 0 0 0 ++ 0 0 0 0 0 0 0 0 0 0 0 0 ++ 0 0 0 0 0 0 0 0 0 0 0 0 ++ 0 0 0 0 0 0 0 0 0 0 0 0 ++ 0 0 0 0 0 0 0 0 0 0 0 0 ++ 0 0 0 85 85 85 0 0 0 0 0 0 ++ 85 85 85 0 0 0 0 0 0 170 170 170 ++255 255 255 255 255 255 255 255 255 255 255 255 ++255 255 255 255 255 255 255 255 255 255 255 255 ++255 255 255 255 255 255 255 255 255 255 255 255 ++255 255 255 255 255 255 255 255 255 255 255 255 ++255 255 255 255 255 255 255 255 255 255 255 255 ++255 255 255 255 255 255 255 255 255 255 255 255 ++170 170 170 85 85 85 0 0 0 0 0 0 ++ 0 0 0 85 85 85 85 85 85 0 0 0 ++ 0 0 0 0 0 0 0 0 0 85 85 85 ++ 0 0 0 0 0 0 0 0 0 0 0 0 ++ 0 0 0 0 0 0 0 0 0 0 0 0 ++ 0 0 0 0 0 0 0 0 0 0 0 0 ++ 0 0 0 0 0 0 0 0 0 0 0 0 ++ 0 0 0 0 0 0 0 0 0 0 0 0 ++ 0 0 0 0 0 0 0 0 0 0 0 0 ++ 0 0 0 0 0 0 0 0 0 0 0 0 ++ 0 0 0 0 0 0 0 0 0 0 0 0 ++ 0 0 0 0 0 0 0 0 0 0 0 0 ++ 0 0 0 85 85 85 0 0 0 85 85 85 ++ 0 0 0 0 0 0 85 85 85 255 255 255 ++255 255 255 255 255 255 255 255 255 255 255 255 ++255 255 255 255 255 255 255 255 255 255 255 255 ++255 255 255 255 255 255 255 255 255 255 255 255 ++255 255 255 255 255 255 255 255 255 255 255 255 ++255 255 255 255 255 255 255 255 255 255 255 255 ++255 255 255 255 255 255 255 255 255 255 255 255 ++255 255 255 170 170 170 0 0 0 85 85 85 ++ 85 85 85 0 0 0 85 85 85 0 0 0 ++ 0 0 0 0 0 0 0 0 0 85 85 85 ++ 0 0 0 0 0 0 0 0 0 0 0 0 ++ 0 0 0 0 0 0 0 0 0 0 0 0 ++ 0 0 0 0 0 0 0 0 0 0 0 0 ++ 0 0 0 0 0 0 0 0 0 0 0 0 ++ 0 0 0 0 0 0 0 0 0 0 0 0 ++ 0 0 0 0 0 0 0 0 0 0 0 0 ++ 0 0 0 0 0 0 0 0 0 0 0 0 ++ 0 0 0 0 0 0 0 0 0 0 0 0 ++ 0 0 0 0 0 0 0 0 0 0 0 0 ++ 0 0 0 85 85 85 0 0 0 85 85 85 ++ 0 0 0 85 85 85 170 170 170 255 255 255 ++255 255 255 255 255 255 255 255 255 255 255 255 ++255 255 255 255 255 255 255 255 255 255 255 255 ++255 255 255 255 255 255 255 255 255 255 255 255 ++255 255 255 255 255 255 255 255 255 255 255 255 ++255 255 255 255 255 255 255 255 255 255 255 255 ++255 255 255 255 255 255 255 255 255 255 255 255 ++255 255 255 170 170 170 0 0 0 85 85 85 ++ 85 85 85 0 0 0 85 85 85 0 0 0 ++ 0 0 0 0 0 0 0 0 0 0 0 0 ++ 85 85 85 0 0 0 0 0 0 0 0 0 ++ 0 0 0 0 0 0 0 0 0 0 0 0 ++ 0 0 0 0 0 0 0 0 0 0 0 0 ++ 0 0 0 0 0 0 0 0 0 0 0 0 ++ 0 0 0 0 0 0 0 0 0 0 0 0 ++ 0 0 0 0 0 0 0 0 0 0 0 0 ++ 0 0 0 0 0 0 0 0 0 0 0 0 ++ 0 0 0 0 0 0 0 0 0 0 0 0 ++ 0 0 0 0 0 0 0 0 0 0 0 0 ++ 85 85 85 0 0 0 0 0 0 85 85 85 ++ 0 0 0 170 170 170 255 255 255 255 255 255 ++255 255 255 255 255 255 255 255 255 255 255 255 ++255 255 255 255 255 255 255 255 255 255 255 255 ++255 255 255 255 255 255 255 255 255 255 255 255 ++255 255 255 255 255 255 255 255 255 255 255 255 ++255 255 255 255 255 255 255 255 255 255 255 255 ++255 255 255 255 255 255 255 255 255 255 255 255 ++255 255 255 255 255 255 85 85 85 0 0 0 ++ 0 0 0 0 0 0 0 0 0 85 85 85 ++ 0 0 0 0 0 0 0 0 0 0 0 0 ++ 85 85 85 0 0 0 0 0 0 0 0 0 ++ 0 0 0 0 0 0 0 0 0 0 0 0 ++ 0 0 0 0 0 0 0 0 0 0 0 0 ++ 0 0 0 0 0 0 0 0 0 0 0 0 ++ 0 0 0 0 0 0 0 0 0 0 0 0 ++ 0 0 0 0 0 0 0 0 0 0 0 0 ++ 0 0 0 0 0 0 0 0 0 0 0 0 ++ 0 0 0 0 0 0 0 0 0 0 0 0 ++ 0 0 0 0 0 0 0 0 0 0 0 0 ++ 85 85 85 0 0 0 85 85 85 0 0 0 ++ 0 0 0 255 255 255 255 255 255 255 255 255 ++255 255 255 255 255 255 255 255 255 255 255 255 ++255 255 255 255 255 255 255 255 255 255 255 255 ++255 255 255 255 255 255 255 255 255 255 255 255 ++255 255 255 255 255 255 255 255 255 255 255 255 ++255 255 255 255 255 255 255 255 255 255 255 255 ++255 255 255 255 255 255 255 255 255 255 255 255 ++255 255 255 255 255 255 170 170 170 0 0 0 ++ 0 0 0 0 0 0 0 0 0 85 85 85 ++ 0 0 0 0 0 0 0 0 0 0 0 0 ++ 85 85 85 0 0 0 0 0 0 0 0 0 ++ 0 0 0 0 0 0 0 0 0 0 0 0 ++ 0 0 0 0 0 0 0 0 0 0 0 0 ++ 0 0 0 0 0 0 0 0 0 0 0 0 ++ 0 0 0 0 0 0 0 0 0 0 0 0 ++ 0 0 0 0 0 0 0 0 0 0 0 0 ++ 0 0 0 0 0 0 0 0 0 0 0 0 ++ 0 0 0 0 0 0 0 0 0 0 0 0 ++ 0 0 0 0 0 0 0 0 0 85 85 85 ++ 0 0 0 0 0 0 85 85 85 0 0 0 ++ 85 85 85 255 255 255 255 255 255 255 255 255 ++255 255 255 255 255 255 255 255 255 255 255 255 ++255 255 255 255 255 255 255 255 255 255 255 255 ++255 255 255 255 255 255 255 255 255 255 255 255 ++255 255 255 255 255 255 255 255 255 255 255 255 ++255 255 255 255 255 255 255 255 255 255 255 255 ++255 255 255 255 255 255 255 255 255 255 255 255 ++255 255 255 255 255 255 170 170 170 0 0 0 ++ 0 0 0 0 0 0 0 0 0 85 85 85 ++ 0 0 0 0 0 0 0 0 0 0 0 0 ++ 85 85 85 0 0 0 0 0 0 0 0 0 ++ 0 0 0 0 0 0 0 0 0 0 0 0 ++ 0 0 0 0 0 0 0 0 0 0 0 0 ++ 0 0 0 0 0 0 0 0 0 0 0 0 ++ 0 0 0 0 0 0 0 0 0 0 0 0 ++ 0 0 0 0 0 0 0 0 0 0 0 0 ++ 0 0 0 0 0 0 0 0 0 0 0 0 ++ 0 0 0 0 0 0 0 0 0 0 0 0 ++ 0 0 0 0 0 0 0 0 0 85 85 85 ++ 0 0 0 85 85 85 0 0 0 0 0 0 ++170 170 170 255 255 255 255 255 255 255 255 255 ++255 255 255 255 255 255 255 255 255 255 255 255 ++255 255 255 255 255 255 255 255 255 255 255 255 ++255 255 255 255 255 255 255 255 255 255 255 255 ++255 255 255 255 255 255 255 255 255 255 255 255 ++255 255 255 255 255 255 255 255 255 255 255 255 ++255 255 255 255 255 255 255 255 255 255 255 255 ++255 255 255 255 255 255 170 170 170 0 0 0 ++ 0 0 0 0 0 0 0 0 0 85 85 85 ++ 0 0 0 0 0 0 0 0 0 0 0 0 ++ 0 0 0 85 85 85 0 0 0 0 0 0 ++ 0 0 0 0 0 0 0 0 0 0 0 0 ++ 0 0 0 0 0 0 0 0 0 0 0 0 ++ 0 0 0 0 0 0 0 0 0 0 0 0 ++ 0 0 0 0 0 0 0 0 0 0 0 0 ++ 0 0 0 0 0 0 0 0 0 0 0 0 ++ 0 0 0 0 0 0 0 0 0 0 0 0 ++ 0 0 0 0 0 0 0 0 0 0 0 0 ++ 0 0 0 0 0 0 85 85 85 0 0 0 ++ 0 0 0 85 85 85 0 0 0 0 0 0 ++255 255 255 255 255 255 255 255 255 255 255 255 ++255 255 255 255 255 255 255 255 255 255 255 255 ++255 255 255 255 255 255 170 170 170 255 255 255 ++255 255 255 255 255 255 255 255 255 255 255 255 ++255 255 255 255 255 255 255 255 255 255 255 255 ++255 255 255 255 255 255 255 255 255 255 255 255 ++255 255 255 255 255 255 255 255 255 255 255 255 ++255 255 255 255 255 255 255 255 255 0 0 0 ++ 0 0 0 0 0 0 0 0 0 85 85 85 ++ 0 0 0 0 0 0 0 0 0 0 0 0 ++ 0 0 0 85 85 85 0 0 0 0 0 0 ++ 0 0 0 0 0 0 0 0 0 0 0 0 ++ 0 0 0 0 0 0 0 0 0 0 0 0 ++ 0 0 0 0 0 0 0 0 0 0 0 0 ++ 0 0 0 0 0 0 0 0 0 0 0 0 ++ 0 0 0 0 0 0 0 0 0 0 0 0 ++ 0 0 0 0 0 0 0 0 0 0 0 0 ++ 0 0 0 0 0 0 0 0 0 0 0 0 ++ 0 0 0 85 85 85 0 0 0 0 0 0 ++ 0 0 0 85 85 85 0 0 0 0 0 0 ++255 255 255 255 255 255 255 255 255 255 255 255 ++255 255 255 255 255 255 255 255 255 255 255 255 ++255 255 255 255 255 255 170 170 170 255 255 255 ++255 255 255 255 255 255 255 255 255 255 255 255 ++255 255 255 255 255 255 255 255 255 255 255 255 ++255 255 255 255 255 255 255 255 255 255 255 255 ++255 255 255 255 255 255 255 255 255 255 255 255 ++255 255 255 255 255 255 255 255 255 0 0 0 ++ 0 0 0 0 0 0 0 0 0 85 85 85 ++ 0 0 0 0 0 0 0 0 0 0 0 0 ++ 0 0 0 85 85 85 0 0 0 0 0 0 ++ 0 0 0 0 0 0 0 0 0 0 0 0 ++ 0 0 0 0 0 0 0 0 0 0 0 0 ++ 0 0 0 0 0 0 0 0 0 0 0 0 ++ 0 0 0 0 0 0 0 0 0 0 0 0 ++ 0 0 0 0 0 0 0 0 0 0 0 0 ++ 0 0 0 0 0 0 0 0 0 0 0 0 ++ 0 0 0 0 0 0 0 0 0 0 0 0 ++ 0 0 0 85 85 85 0 0 0 0 0 0 ++ 0 0 0 85 85 85 0 0 0 85 85 85 ++255 255 255 255 255 255 255 255 255 255 255 255 ++255 255 255 255 255 255 255 255 255 255 255 255 ++255 255 255 255 255 255 170 170 170 255 255 255 ++255 255 255 255 255 255 255 255 255 255 255 255 ++255 255 255 255 255 255 255 255 255 255 255 255 ++255 255 255 255 255 255 255 255 255 255 255 255 ++255 255 255 255 255 255 255 255 255 255 255 255 ++255 255 255 255 255 255 255 255 255 0 0 0 ++ 0 0 0 0 0 0 0 0 0 85 85 85 ++ 0 0 0 0 0 0 0 0 0 0 0 0 ++ 0 0 0 85 85 85 0 0 0 0 0 0 ++ 0 0 0 0 0 0 0 0 0 0 0 0 ++ 0 0 0 0 0 0 0 0 0 0 0 0 ++ 0 0 0 0 0 0 0 0 0 0 0 0 ++ 0 0 0 0 0 0 0 0 0 0 0 0 ++ 0 0 0 0 0 0 0 0 0 0 0 0 ++ 0 0 0 0 0 0 0 0 0 0 0 0 ++ 0 0 0 0 0 0 0 0 0 0 0 0 ++ 0 0 0 85 85 85 0 0 0 0 0 0 ++ 0 0 0 85 85 85 0 0 0 85 85 85 ++255 255 255 255 255 255 255 255 255 255 255 255 ++255 255 255 255 255 255 255 255 255 255 255 255 ++255 255 255 255 255 255 170 170 170 255 255 255 ++255 255 255 255 255 255 255 255 255 255 255 255 ++255 255 255 255 255 255 255 255 255 255 255 255 ++255 255 255 255 255 255 255 255 255 255 255 255 ++255 255 255 255 255 255 255 255 255 255 255 255 ++255 255 255 255 255 255 255 255 255 0 0 0 ++ 0 0 0 0 0 0 0 0 0 85 85 85 ++ 0 0 0 0 0 0 0 0 0 0 0 0 ++ 0 0 0 85 85 85 0 0 0 0 0 0 ++ 0 0 0 0 0 0 0 0 0 0 0 0 ++ 0 0 0 0 0 0 0 0 0 0 0 0 ++ 0 0 0 0 0 0 0 0 0 0 0 0 ++ 0 0 0 0 0 0 0 0 0 0 0 0 ++ 0 0 0 0 0 0 0 0 0 0 0 0 ++ 0 0 0 0 0 0 0 0 0 0 0 0 ++ 0 0 0 0 0 0 0 0 0 0 0 0 ++ 0 0 0 85 85 85 0 0 0 0 0 0 ++ 0 0 0 0 0 0 85 85 85 85 85 85 ++255 255 255 255 255 255 255 255 255 255 255 255 ++255 255 255 255 255 255 255 255 255 255 255 255 ++255 255 255 255 255 255 170 170 170 255 255 255 ++255 255 255 255 255 255 255 255 255 255 255 255 ++255 255 255 255 255 255 255 255 255 255 255 255 ++255 255 255 255 255 255 255 255 255 255 255 255 ++255 255 255 255 255 255 255 255 255 255 255 255 ++255 255 255 255 255 255 255 255 255 0 0 0 ++ 0 0 0 0 0 0 0 0 0 85 85 85 ++ 0 0 0 0 0 0 0 0 0 0 0 0 ++ 0 0 0 85 85 85 0 0 0 0 0 0 ++ 0 0 0 0 0 0 0 0 0 0 0 0 ++ 0 0 0 0 0 0 0 0 0 0 0 0 ++ 0 0 0 0 0 0 0 0 0 0 0 0 ++ 0 0 0 0 0 0 0 0 0 0 0 0 ++ 0 0 0 0 0 0 0 0 0 0 0 0 ++ 0 0 0 0 0 0 0 0 0 0 0 0 ++ 0 0 0 0 0 0 0 0 0 0 0 0 ++ 0 0 0 85 85 85 0 0 0 0 0 0 ++ 0 0 0 0 0 0 0 0 0 85 85 85 ++255 255 255 255 255 255 255 255 255 255 255 255 ++255 255 255 255 255 255 255 255 255 255 255 255 ++255 255 255 255 255 255 170 170 170 255 255 255 ++255 255 255 255 255 255 255 255 255 255 255 255 ++255 255 255 255 255 255 255 255 255 255 255 255 ++255 255 255 255 255 255 255 255 255 255 255 255 ++255 255 255 255 255 255 255 255 255 255 255 255 ++255 255 255 255 255 255 255 255 255 0 0 0 ++ 85 85 85 85 85 85 85 85 85 85 85 85 ++ 85 85 85 0 0 0 0 0 0 0 0 0 ++ 0 0 0 85 85 85 0 0 0 0 0 0 ++ 0 0 0 0 0 0 0 0 0 0 0 0 ++ 0 0 0 0 0 0 0 0 0 0 0 0 ++ 0 0 0 0 0 0 0 0 0 0 0 0 ++ 0 0 0 0 0 0 0 0 0 0 0 0 ++ 0 0 0 0 0 0 0 0 0 0 0 0 ++ 0 0 0 0 0 0 0 0 0 0 0 0 ++ 0 0 0 0 0 0 0 0 0 0 0 0 ++ 0 0 0 85 85 85 0 0 0 170 85 0 ++255 255 85 170 85 0 0 0 0 0 0 0 ++ 85 85 85 255 255 255 255 255 255 255 255 255 ++255 255 255 255 255 255 255 255 255 255 255 255 ++255 255 255 255 255 255 170 170 170 255 255 255 ++255 255 255 255 255 255 255 255 255 255 255 255 ++255 255 255 255 255 255 255 255 255 255 255 255 ++255 255 255 255 255 255 255 255 255 255 255 255 ++255 255 255 255 255 255 255 255 255 255 255 255 ++255 255 255 255 255 255 255 255 255 85 85 85 ++ 0 0 0 0 0 0 0 0 0 0 0 0 ++ 0 0 0 85 85 85 85 85 85 0 0 0 ++ 0 0 0 85 85 85 0 0 0 0 0 0 ++ 0 0 0 0 0 0 0 0 0 0 0 0 ++ 0 0 0 0 0 0 0 0 0 0 0 0 ++ 0 0 0 0 0 0 0 0 0 0 0 0 ++ 0 0 0 0 0 0 0 0 0 0 0 0 ++ 0 0 0 0 0 0 0 0 0 0 0 0 ++ 0 0 0 0 0 0 0 0 0 0 0 0 ++ 0 0 0 0 0 0 0 0 0 0 0 0 ++ 0 0 0 0 0 0 170 85 0 255 255 85 ++170 85 0 255 255 85 170 85 0 0 0 0 ++ 0 0 0 85 85 85 255 255 255 255 255 255 ++255 255 255 255 255 255 255 255 255 255 255 255 ++255 255 255 255 255 255 170 170 170 255 255 255 ++255 255 255 255 255 255 255 255 255 255 255 255 ++255 255 255 255 255 255 255 255 255 255 255 255 ++255 255 255 255 255 255 255 255 255 255 255 255 ++255 255 255 255 255 255 255 255 255 255 255 255 ++255 255 85 170 85 0 255 255 85 0 0 0 ++ 0 0 0 0 0 0 0 0 0 0 0 0 ++ 0 0 0 0 0 0 85 85 85 85 85 85 ++ 85 85 85 0 0 0 0 0 0 0 0 0 ++ 0 0 0 0 0 0 0 0 0 0 0 0 ++ 0 0 0 0 0 0 0 0 0 0 0 0 ++ 0 0 0 0 0 0 0 0 0 0 0 0 ++ 0 0 0 0 0 0 0 0 0 0 0 0 ++ 0 0 0 0 0 0 0 0 0 0 0 0 ++ 0 0 0 0 0 0 0 0 0 0 0 0 ++ 0 0 0 0 0 0 0 0 0 0 0 0 ++ 0 0 0 170 85 0 255 255 85 170 85 0 ++255 255 85 170 85 0 255 255 85 170 85 0 ++ 0 0 0 0 0 0 85 85 85 255 255 255 ++255 255 255 255 255 255 255 255 255 255 255 255 ++255 255 255 255 255 255 255 255 255 255 255 255 ++255 255 255 255 255 255 255 255 255 255 255 255 ++255 255 255 255 255 255 255 255 255 255 255 255 ++255 255 255 255 255 255 255 255 255 255 255 255 ++255 255 255 255 255 255 255 255 255 255 255 85 ++170 85 0 255 255 85 170 85 0 0 0 0 ++ 0 0 0 0 0 0 0 0 0 0 0 0 ++ 0 0 0 0 0 0 0 0 0 0 0 0 ++170 85 0 0 0 0 0 0 0 0 0 0 ++ 0 0 0 0 0 0 0 0 0 0 0 0 ++ 0 0 0 0 0 0 0 0 0 0 0 0 ++ 0 0 0 0 0 0 0 0 0 0 0 0 ++ 0 0 0 0 0 0 0 0 0 0 0 0 ++ 0 0 0 0 0 0 0 0 0 0 0 0 ++ 0 0 0 0 0 0 0 0 0 0 0 0 ++ 0 0 0 0 0 0 0 0 0 0 0 0 ++170 85 0 255 255 85 170 85 0 255 255 85 ++170 85 0 255 255 85 170 85 0 255 255 85 ++170 85 0 0 0 0 0 0 0 85 85 85 ++255 255 255 255 255 255 255 255 255 255 255 255 ++255 255 255 255 255 255 255 255 255 255 255 255 ++255 255 255 255 255 255 255 255 255 255 255 255 ++255 255 255 255 255 255 255 255 255 255 255 255 ++255 255 255 255 255 255 255 255 255 255 255 255 ++255 255 255 255 255 255 255 255 255 170 85 0 ++255 255 85 170 85 0 255 255 85 0 0 0 ++ 0 0 0 0 0 0 0 0 0 0 0 0 ++ 0 0 0 0 0 0 0 0 0 170 85 0 ++255 255 85 170 85 0 0 0 0 0 0 0 ++ 0 0 0 0 0 0 0 0 0 0 0 0 ++ 0 0 0 0 0 0 0 0 0 0 0 0 ++ 0 0 0 0 0 0 0 0 0 0 0 0 ++ 0 0 0 0 0 0 0 0 0 0 0 0 ++ 0 0 0 0 0 0 0 0 0 0 0 0 ++ 0 0 0 0 0 0 0 0 0 170 85 0 ++255 255 85 170 85 0 255 255 85 170 85 0 ++255 255 85 170 85 0 255 255 85 170 85 0 ++255 255 85 170 85 0 255 255 85 170 85 0 ++255 255 85 0 0 0 0 0 0 0 0 0 ++ 85 85 85 255 255 255 255 255 255 255 255 255 ++255 255 255 255 255 255 255 255 255 255 255 255 ++255 255 255 255 255 255 255 255 255 255 255 255 ++255 255 255 255 255 255 255 255 255 255 255 255 ++255 255 255 255 255 255 255 255 255 255 255 255 ++255 255 255 255 255 255 255 255 255 255 255 85 ++170 85 0 255 255 85 170 85 0 0 0 0 ++ 0 0 0 0 0 0 0 0 0 0 0 0 ++ 0 0 0 0 0 0 0 0 0 255 255 85 ++170 85 0 255 255 85 0 0 0 0 0 0 ++ 0 0 0 0 0 0 0 0 0 0 0 0 ++ 0 0 0 0 0 0 0 0 0 0 0 0 ++ 0 0 0 0 0 0 0 0 0 0 0 0 ++ 0 0 0 0 0 0 0 0 0 0 0 0 ++ 0 0 0 0 0 0 0 0 0 0 0 0 ++ 0 0 0 0 0 0 170 85 0 255 255 85 ++170 85 0 255 255 85 170 85 0 255 255 85 ++170 85 0 255 255 85 170 85 0 255 255 85 ++170 85 0 255 255 85 170 85 0 255 255 85 ++170 85 0 255 255 85 0 0 0 0 0 0 ++ 0 0 0 85 85 85 255 255 255 255 255 255 ++255 255 255 255 255 255 255 255 255 255 255 255 ++255 255 255 255 255 255 255 255 255 255 255 255 ++255 255 255 255 255 255 255 255 255 255 255 255 ++255 255 255 255 255 255 255 255 255 255 255 255 ++255 255 255 255 255 255 170 170 170 170 85 0 ++255 255 85 170 85 0 255 255 85 170 85 0 ++ 0 0 0 0 0 0 0 0 0 0 0 0 ++ 0 0 0 0 0 0 255 255 85 170 85 0 ++255 255 85 170 85 0 0 0 0 0 0 0 ++ 0 0 0 0 0 0 0 0 0 0 0 0 ++ 0 0 0 0 0 0 0 0 0 0 0 0 ++ 0 0 0 0 0 0 0 0 0 0 0 0 ++ 0 0 0 0 0 0 0 0 0 0 0 0 ++ 0 0 0 0 0 0 0 0 0 0 0 0 ++ 0 0 0 0 0 0 255 255 85 170 85 0 ++255 255 85 170 85 0 255 255 85 170 85 0 ++255 255 85 170 85 0 255 255 85 170 85 0 ++255 255 85 170 85 0 255 255 85 170 85 0 ++255 255 85 170 85 0 255 255 85 0 0 0 ++ 0 0 0 0 0 0 85 85 85 255 255 255 ++255 255 255 255 255 255 255 255 255 255 255 255 ++255 255 255 255 255 255 255 255 255 255 255 255 ++255 255 255 255 255 255 255 255 255 255 255 255 ++255 255 255 255 255 255 255 255 255 255 255 255 ++255 255 255 170 170 170 170 170 170 255 255 85 ++170 85 0 255 255 85 170 85 0 255 255 85 ++170 85 0 255 255 85 170 85 0 255 255 85 ++170 85 0 255 255 85 170 85 0 255 255 85 ++170 85 0 255 255 85 0 0 0 0 0 0 ++ 0 0 0 0 0 0 0 0 0 0 0 0 ++ 0 0 0 0 0 0 0 0 0 0 0 0 ++ 0 0 0 0 0 0 0 0 0 0 0 0 ++ 0 0 0 0 0 0 0 0 0 0 0 0 ++ 0 0 0 0 0 0 0 0 0 0 0 0 ++ 0 0 0 0 0 0 170 85 0 255 255 85 ++170 85 0 255 255 85 170 85 0 255 255 85 ++170 85 0 255 255 85 170 85 0 255 255 85 ++170 85 0 255 255 85 170 85 0 255 255 85 ++170 85 0 255 255 85 170 85 0 0 0 0 ++ 0 0 0 0 0 0 0 0 0 85 85 85 ++255 255 255 255 255 255 255 255 255 255 255 255 ++255 255 255 255 255 255 255 255 255 255 255 255 ++255 255 255 255 255 255 255 255 255 255 255 255 ++255 255 255 255 255 255 255 255 255 255 255 255 ++255 255 255 170 170 170 170 170 170 170 85 0 ++255 255 85 170 85 0 255 255 85 170 85 0 ++255 255 85 170 85 0 255 255 85 170 85 0 ++255 255 85 170 85 0 255 255 85 170 85 0 ++255 255 85 170 85 0 255 255 85 0 0 0 ++ 0 0 0 0 0 0 0 0 0 0 0 0 ++ 0 0 0 0 0 0 0 0 0 0 0 0 ++ 0 0 0 0 0 0 0 0 0 0 0 0 ++ 0 0 0 0 0 0 0 0 0 0 0 0 ++ 0 0 0 0 0 0 0 0 0 0 0 0 ++ 0 0 0 0 0 0 255 255 85 170 85 0 ++255 255 85 170 85 0 255 255 85 170 85 0 ++255 255 85 170 85 0 255 255 85 170 85 0 ++255 255 85 170 85 0 255 255 85 170 85 0 ++255 255 85 170 85 0 255 255 85 170 85 0 ++ 0 0 0 0 0 0 0 0 0 0 0 0 ++ 0 0 0 255 255 255 255 255 255 255 255 255 ++255 255 255 255 255 255 255 255 255 255 255 255 ++255 255 255 255 255 255 255 255 255 255 255 255 ++255 255 255 255 255 255 255 255 255 255 255 255 ++255 255 255 170 170 170 170 170 170 255 255 85 ++170 85 0 255 255 85 170 85 0 255 255 85 ++170 85 0 255 255 85 170 85 0 255 255 85 ++170 85 0 255 255 85 170 85 0 255 255 85 ++170 85 0 255 255 85 170 85 0 255 255 85 ++ 0 0 0 0 0 0 0 0 0 0 0 0 ++ 0 0 0 0 0 0 0 0 0 0 0 0 ++ 0 0 0 0 0 0 0 0 0 0 0 0 ++ 0 0 0 0 0 0 0 0 0 0 0 0 ++ 0 0 0 0 0 0 0 0 0 0 0 0 ++ 0 0 0 0 0 0 170 85 0 255 255 85 ++170 85 0 255 255 85 170 85 0 255 255 85 ++170 85 0 255 255 85 170 85 0 255 255 85 ++170 85 0 255 255 85 170 85 0 255 255 85 ++170 85 0 255 255 85 170 85 0 255 255 85 ++170 85 0 0 0 0 0 0 0 0 0 0 ++ 0 0 0 255 255 255 255 255 255 255 255 255 ++255 255 255 255 255 255 255 255 255 255 255 255 ++255 255 255 255 255 255 255 255 255 255 255 255 ++255 255 255 255 255 255 255 255 255 255 255 255 ++255 255 255 170 170 170 170 170 170 170 85 0 ++255 255 85 170 85 0 255 255 85 170 85 0 ++255 255 85 170 85 0 255 255 85 170 85 0 ++255 255 85 170 85 0 255 255 85 170 85 0 ++255 255 85 170 85 0 255 255 85 170 85 0 ++255 255 85 0 0 0 0 0 0 0 0 0 ++ 0 0 0 0 0 0 0 0 0 0 0 0 ++ 0 0 0 0 0 0 0 0 0 0 0 0 ++ 0 0 0 0 0 0 0 0 0 0 0 0 ++ 0 0 0 0 0 0 0 0 0 0 0 0 ++ 0 0 0 0 0 0 255 255 85 170 85 0 ++255 255 85 170 85 0 255 255 85 170 85 0 ++255 255 85 170 85 0 255 255 85 170 85 0 ++255 255 85 170 85 0 255 255 85 170 85 0 ++255 255 85 170 85 0 255 255 85 170 85 0 ++255 255 85 0 0 0 0 0 0 0 0 0 ++ 85 85 85 255 255 255 255 255 255 255 255 255 ++255 255 255 255 255 255 255 255 255 255 255 255 ++255 255 255 255 255 255 255 255 255 255 255 255 ++255 255 255 255 255 255 255 255 255 255 255 255 ++255 255 255 170 170 170 85 85 85 255 255 85 ++170 85 0 255 255 85 170 85 0 255 255 85 ++170 85 0 255 255 85 170 85 0 255 255 85 ++170 85 0 255 255 85 170 85 0 255 255 85 ++170 85 0 255 255 85 170 85 0 255 255 85 ++170 85 0 255 255 85 0 0 0 0 0 0 ++ 0 0 0 0 0 0 0 0 0 0 0 0 ++ 0 0 0 0 0 0 0 0 0 0 0 0 ++ 0 0 0 0 0 0 0 0 0 0 0 0 ++ 0 0 0 0 0 0 0 0 0 0 0 0 ++ 0 0 0 0 0 0 170 85 0 255 255 85 ++170 85 0 255 255 85 170 85 0 255 255 85 ++170 85 0 255 255 85 170 85 0 255 255 85 ++170 85 0 255 255 85 170 85 0 255 255 85 ++170 85 0 255 255 85 170 85 0 255 255 85 ++170 85 0 255 255 85 85 85 85 85 85 85 ++255 255 255 255 255 255 255 255 255 255 255 255 ++255 255 255 255 255 255 255 255 255 255 255 255 ++255 255 255 255 255 255 255 255 255 255 255 255 ++255 255 255 255 255 255 255 255 255 255 255 255 ++170 170 170 85 85 85 85 85 85 170 85 0 ++255 255 85 170 85 0 255 255 85 170 85 0 ++255 255 85 170 85 0 255 255 85 170 85 0 ++255 255 85 170 85 0 255 255 85 170 85 0 ++255 255 85 170 85 0 255 255 85 170 85 0 ++255 255 85 170 85 0 255 255 85 170 85 0 ++ 0 0 0 0 0 0 0 0 0 0 0 0 ++ 0 0 0 0 0 0 0 0 0 0 0 0 ++ 0 0 0 0 0 0 0 0 0 0 0 0 ++ 0 0 0 0 0 0 0 0 0 0 0 0 ++ 0 0 0 0 0 0 255 255 85 170 85 0 ++255 255 85 170 85 0 255 255 85 170 85 0 ++255 255 85 170 85 0 255 255 85 170 85 0 ++255 255 85 170 85 0 255 255 85 170 85 0 ++255 255 85 170 85 0 255 255 85 170 85 0 ++255 255 85 170 85 0 255 255 85 255 255 255 ++255 255 255 255 255 255 255 255 255 255 255 255 ++255 255 255 255 255 255 255 255 255 255 255 255 ++255 255 255 255 255 255 255 255 255 255 255 255 ++255 255 255 255 255 255 255 255 255 170 170 170 ++ 85 85 85 0 0 0 0 0 0 170 85 0 ++170 85 0 255 255 85 170 85 0 255 255 85 ++170 85 0 255 255 85 170 85 0 255 255 85 ++170 85 0 255 255 85 170 85 0 255 255 85 ++170 85 0 255 255 85 170 85 0 255 255 85 ++170 85 0 255 255 85 170 85 0 255 255 85 ++ 0 0 0 0 0 0 0 0 0 0 0 0 ++ 0 0 0 0 0 0 0 0 0 0 0 0 ++ 0 0 0 0 0 0 0 0 0 0 0 0 ++ 0 0 0 0 0 0 0 0 0 0 0 0 ++ 0 0 0 0 0 0 170 85 0 255 255 85 ++170 85 0 255 255 85 170 85 0 255 255 85 ++170 85 0 255 255 85 170 85 0 255 255 85 ++170 85 0 255 255 85 170 85 0 255 255 85 ++170 85 0 255 255 85 170 85 0 255 255 85 ++170 85 0 255 255 85 170 85 0 255 255 85 ++255 255 255 255 255 255 255 255 255 255 255 255 ++255 255 255 255 255 255 255 255 255 255 255 255 ++255 255 255 255 255 255 255 255 255 255 255 255 ++255 255 255 255 255 255 170 170 170 85 85 85 ++ 0 0 0 0 0 0 0 0 0 170 85 0 ++255 255 85 170 85 0 255 255 85 170 85 0 ++255 255 85 170 85 0 255 255 85 170 85 0 ++255 255 85 170 85 0 255 255 85 170 85 0 ++255 255 85 170 85 0 255 255 85 170 85 0 ++255 255 85 170 85 0 255 255 85 0 0 0 ++ 0 0 0 0 0 0 0 0 0 0 0 0 ++ 0 0 0 0 0 0 0 0 0 0 0 0 ++ 0 0 0 0 0 0 0 0 0 0 0 0 ++ 0 0 0 0 0 0 0 0 0 0 0 0 ++ 0 0 0 0 0 0 255 255 85 170 85 0 ++255 255 85 170 85 0 255 255 85 170 85 0 ++255 255 85 170 85 0 255 255 85 170 85 0 ++255 255 85 170 85 0 255 255 85 170 85 0 ++255 255 85 170 85 0 255 255 85 170 85 0 ++255 255 85 170 85 0 255 255 85 170 85 0 ++170 170 170 255 255 255 255 255 255 255 255 255 ++255 255 255 255 255 255 255 255 255 255 255 255 ++255 255 255 255 255 255 255 255 255 255 255 255 ++170 170 170 85 85 85 85 85 85 0 0 0 ++ 0 0 0 0 0 0 0 0 0 170 85 0 ++170 85 0 255 255 85 170 85 0 255 255 85 ++170 85 0 255 255 85 170 85 0 255 255 85 ++170 85 0 255 255 85 170 85 0 255 255 85 ++170 85 0 255 255 85 170 85 0 255 255 85 ++170 85 0 255 255 85 0 0 0 0 0 0 ++ 0 0 0 0 0 0 0 0 0 0 0 0 ++ 0 0 0 0 0 0 0 0 0 0 0 0 ++ 0 0 0 0 0 0 0 0 0 0 0 0 ++ 0 0 0 0 0 0 0 0 0 0 0 0 ++ 0 0 0 255 255 85 170 85 0 255 255 85 ++170 85 0 255 255 85 170 85 0 255 255 85 ++170 85 0 255 255 85 170 85 0 255 255 85 ++170 85 0 255 255 85 170 85 0 255 255 85 ++170 85 0 255 255 85 170 85 0 255 255 85 ++170 85 0 255 255 85 170 85 0 170 85 0 ++170 85 0 170 170 170 255 255 255 255 255 255 ++255 255 255 255 255 255 255 255 255 255 255 255 ++255 255 255 255 255 255 170 170 170 85 85 85 ++ 85 85 85 0 0 0 0 0 0 0 0 0 ++ 0 0 0 0 0 0 85 85 85 170 85 0 ++255 255 85 170 85 0 255 255 85 170 85 0 ++255 255 85 170 85 0 255 255 85 170 85 0 ++255 255 85 170 85 0 255 255 85 170 85 0 ++255 255 85 170 85 0 255 255 85 170 85 0 ++255 255 85 0 0 0 0 0 0 0 0 0 ++ 0 0 0 0 0 0 0 0 0 0 0 0 ++ 0 0 0 0 0 0 0 0 0 0 0 0 ++ 0 0 0 0 0 0 0 0 0 0 0 0 ++ 0 0 0 0 0 0 0 0 0 0 0 0 ++ 0 0 0 170 85 0 255 255 85 170 85 0 ++255 255 85 170 85 0 255 255 85 170 85 0 ++255 255 85 170 85 0 255 255 85 170 85 0 ++255 255 85 170 85 0 255 255 85 170 85 0 ++255 255 85 170 85 0 255 255 85 170 85 0 ++255 255 85 170 85 0 255 255 85 170 85 0 ++170 85 0 0 0 0 0 0 0 0 0 0 ++ 0 0 0 0 0 0 0 0 0 0 0 0 ++ 0 0 0 0 0 0 0 0 0 0 0 0 ++ 0 0 0 0 0 0 0 0 0 0 0 0 ++ 0 0 0 0 0 0 85 85 85 170 85 0 ++170 85 0 255 255 85 170 85 0 255 255 85 ++170 85 0 255 255 85 170 85 0 255 255 85 ++170 85 0 255 255 85 170 85 0 255 255 85 ++170 85 0 170 85 0 170 85 0 0 0 0 ++ 0 0 0 0 0 0 0 0 0 0 0 0 ++ 0 0 0 0 0 0 0 0 0 0 0 0 ++ 0 0 0 0 0 0 0 0 0 0 0 0 ++ 0 0 0 0 0 0 0 0 0 0 0 0 ++ 0 0 0 0 0 0 0 0 0 0 0 0 ++ 0 0 0 255 255 85 170 85 0 255 255 85 ++170 85 0 255 255 85 170 85 0 255 255 85 ++170 85 0 255 255 85 170 85 0 255 255 85 ++170 85 0 255 255 85 170 85 0 255 255 85 ++170 85 0 255 255 85 170 85 0 255 255 85 ++170 85 0 255 255 85 170 85 0 170 85 0 ++170 85 0 0 0 0 0 0 0 0 0 0 ++ 0 0 0 0 0 0 0 0 0 0 0 0 ++ 0 0 0 0 0 0 0 0 0 0 0 0 ++ 0 0 0 0 0 0 0 0 0 0 0 0 ++ 0 0 0 0 0 0 85 85 85 170 85 0 ++255 255 85 170 85 0 255 255 85 170 85 0 ++255 255 85 170 85 0 255 255 85 170 85 0 ++255 255 85 170 85 0 255 255 85 170 85 0 ++170 85 0 0 0 0 0 0 0 0 0 0 ++ 0 0 0 0 0 0 0 0 0 0 0 0 ++ 0 0 0 0 0 0 0 0 0 0 0 0 ++ 0 0 0 0 0 0 0 0 0 0 0 0 ++ 0 0 0 0 0 0 0 0 0 0 0 0 ++ 0 0 0 0 0 0 0 0 0 0 0 0 ++ 0 0 0 0 0 0 255 255 85 170 85 0 ++255 255 85 170 85 0 255 255 85 170 85 0 ++255 255 85 170 85 0 255 255 85 170 85 0 ++255 255 85 170 85 0 255 255 85 170 85 0 ++255 255 85 170 85 0 255 255 85 170 85 0 ++255 255 85 170 85 0 255 255 85 170 85 0 ++170 85 0 0 0 0 0 0 0 0 0 0 ++ 0 0 0 0 0 0 0 0 0 0 0 0 ++ 0 0 0 0 0 0 0 0 0 0 0 0 ++ 0 0 0 0 0 0 0 0 0 0 0 0 ++ 0 0 0 0 0 0 85 85 85 170 85 0 ++170 85 0 255 255 85 170 85 0 255 255 85 ++170 85 0 255 255 85 170 85 0 255 255 85 ++170 85 0 170 85 0 170 85 0 170 85 0 ++ 0 0 0 0 0 0 0 0 0 0 0 0 ++ 0 0 0 0 0 0 0 0 0 0 0 0 ++ 0 0 0 0 0 0 0 0 0 0 0 0 ++ 0 0 0 0 0 0 0 0 0 0 0 0 ++ 0 0 0 0 0 0 0 0 0 0 0 0 ++ 0 0 0 0 0 0 0 0 0 0 0 0 ++ 0 0 0 0 0 0 0 0 0 0 0 0 ++ 0 0 0 0 0 0 170 85 0 170 85 0 ++170 85 0 170 85 0 170 85 0 170 85 0 ++170 85 0 255 255 85 170 85 0 255 255 85 ++170 85 0 255 255 85 170 85 0 255 255 85 ++170 85 0 255 255 85 170 85 0 170 85 0 ++170 85 0 0 0 0 0 0 0 0 0 0 ++ 85 85 85 85 85 85 85 85 85 85 85 85 ++ 85 85 85 85 85 85 85 85 85 85 85 85 ++ 85 85 85 85 85 85 85 85 85 0 0 0 ++ 0 0 0 0 0 0 0 0 0 170 85 0 ++170 85 0 170 85 0 255 255 85 170 85 0 ++255 255 85 170 85 0 255 255 85 170 85 0 ++170 85 0 170 85 0 0 0 0 0 0 0 ++ 0 0 0 0 0 0 0 0 0 0 0 0 ++ 0 0 0 0 0 0 0 0 0 0 0 0 ++ 0 0 0 0 0 0 0 0 0 0 0 0 ++ 0 0 0 0 0 0 0 0 0 0 0 0 ++ 0 0 0 0 0 0 0 0 0 0 0 0 ++ 0 0 0 0 0 0 0 0 0 0 0 0 ++ 0 0 0 0 0 0 0 0 0 0 0 0 ++ 0 0 0 0 0 0 0 0 0 0 0 0 ++ 0 0 0 0 0 0 170 85 0 170 85 0 ++170 85 0 170 85 0 170 85 0 170 85 0 ++170 85 0 170 85 0 255 255 85 170 85 0 ++255 255 85 170 85 0 170 85 0 170 85 0 ++ 85 85 85 85 85 85 85 85 85 85 85 85 ++ 0 0 0 0 0 0 0 0 0 0 0 0 ++ 0 0 0 0 0 0 0 0 0 0 0 0 ++ 0 0 0 0 0 0 0 0 0 85 85 85 ++ 85 85 85 85 85 85 85 85 85 170 85 0 ++170 85 0 170 85 0 170 85 0 255 255 85 ++170 85 0 255 255 85 170 85 0 170 85 0 ++170 85 0 0 0 0 0 0 0 0 0 0 ++ 0 0 0 0 0 0 0 0 0 0 0 0 ++ 0 0 0 0 0 0 0 0 0 0 0 0 ++ 0 0 0 0 0 0 0 0 0 0 0 0 ++ 0 0 0 0 0 0 0 0 0 0 0 0 ++ 0 0 0 0 0 0 0 0 0 0 0 0 ++ 0 0 0 0 0 0 0 0 0 0 0 0 ++ 0 0 0 0 0 0 0 0 0 0 0 0 ++ 0 0 0 0 0 0 0 0 0 0 0 0 ++ 0 0 0 0 0 0 0 0 0 0 0 0 ++ 0 0 0 0 0 0 0 0 0 170 85 0 ++170 85 0 170 85 0 170 85 0 170 85 0 ++170 85 0 170 85 0 170 85 0 170 85 0 ++ 0 0 0 0 0 0 0 0 0 0 0 0 ++ 0 0 0 0 0 0 0 0 0 0 0 0 ++ 0 0 0 0 0 0 0 0 0 0 0 0 ++ 0 0 0 0 0 0 0 0 0 0 0 0 ++ 0 0 0 0 0 0 0 0 0 170 85 0 ++170 85 0 170 85 0 170 85 0 170 85 0 ++170 85 0 170 85 0 170 85 0 170 85 0 ++ 0 0 0 0 0 0 0 0 0 0 0 0 ++ 0 0 0 0 0 0 0 0 0 0 0 0 ++ 0 0 0 0 0 0 0 0 0 0 0 0 ++ 0 0 0 0 0 0 0 0 0 0 0 0 ++ 0 0 0 0 0 0 0 0 0 0 0 0 ++ 0 0 0 0 0 0 0 0 0 0 0 0 ++ 0 0 0 0 0 0 0 0 0 0 0 0 ++ 0 0 0 0 0 0 0 0 0 0 0 0 ++ 0 0 0 0 0 0 0 0 0 0 0 0 ++ 0 0 0 0 0 0 0 0 0 0 0 0 ++ 0 0 0 0 0 0 0 0 0 0 0 0 ++ 0 0 0 170 85 0 170 85 0 170 85 0 ++170 85 0 170 85 0 170 85 0 0 0 0 ++ 0 0 0 0 0 0 0 0 0 0 0 0 ++ 0 0 0 0 0 0 0 0 0 0 0 0 ++ 0 0 0 0 0 0 0 0 0 0 0 0 ++ 0 0 0 0 0 0 0 0 0 0 0 0 ++ 0 0 0 0 0 0 0 0 0 0 0 0 ++170 85 0 170 85 0 170 85 0 170 85 0 ++170 85 0 170 85 0 170 85 0 0 0 0 ++ 0 0 0 0 0 0 0 0 0 0 0 0 ++ 0 0 0 0 0 0 0 0 0 0 0 0 ++ 0 0 0 0 0 0 0 0 0 0 0 0 ++ 0 0 0 0 0 0 0 0 0 0 0 0 ++ 0 0 0 0 0 0 0 0 0 0 0 0 ++ 0 0 0 0 0 0 0 0 0 0 0 0 ++ 0 0 0 0 0 0 0 0 0 0 0 0 ++ 0 0 0 0 0 0 0 0 0 0 0 0 ++ 0 0 0 0 0 0 0 0 0 0 0 0 ++ 0 0 0 0 0 0 0 0 0 0 0 0 ++ 0 0 0 0 0 0 0 0 0 0 0 0 ++ 0 0 0 0 0 0 0 0 0 0 0 0 ++ 0 0 0 0 0 0 0 0 0 0 0 0 ++ 0 0 0 0 0 0 0 0 0 0 0 0 ++ 0 0 0 0 0 0 0 0 0 0 0 0 ++ 0 0 0 0 0 0 0 0 0 0 0 0 ++ 0 0 0 0 0 0 0 0 0 0 0 0 ++ 0 0 0 0 0 0 0 0 0 0 0 0 ++ 0 0 0 0 0 0 0 0 0 0 0 0 ++ 0 0 0 0 0 0 0 0 0 0 0 0 ++ 0 0 0 0 0 0 0 0 0 0 0 0 ++ 0 0 0 0 0 0 0 0 0 0 0 0 ++ 0 0 0 0 0 0 0 0 0 0 0 0 ++ 0 0 0 0 0 0 0 0 0 0 0 0 ++ 0 0 0 0 0 0 0 0 0 0 0 0 ++ 0 0 0 0 0 0 0 0 0 0 0 0 ++ 0 0 0 0 0 0 0 0 0 0 0 0 ++ 0 0 0 0 0 0 0 0 0 0 0 0 ++ 0 0 0 0 0 0 0 0 0 0 0 0 ++ 0 0 0 0 0 0 0 0 0 0 0 0 ++ 0 0 0 0 0 0 0 0 0 0 0 0 ++ 0 0 0 0 0 0 0 0 0 0 0 0 ++ 0 0 0 0 0 0 0 0 0 0 0 0 ++ 0 0 0 0 0 0 0 0 0 0 0 0 ++ 0 0 0 0 0 0 0 0 0 0 0 0 ++ 0 0 0 0 0 0 0 0 0 0 0 0 ++ 0 0 0 0 0 0 0 0 0 0 0 0 ++ 0 0 0 0 0 0 0 0 0 0 0 0 ++ 0 0 0 0 0 0 0 0 0 0 0 0 ++ 0 0 0 0 0 0 0 0 0 0 0 0 ++ 0 0 0 0 0 0 0 0 0 0 0 0 ++ 0 0 0 0 0 0 0 0 0 0 0 0 ++ 0 0 0 0 0 0 0 0 0 0 0 0 ++ 0 0 0 0 0 0 0 0 0 0 0 0 ++ 0 0 0 0 0 0 0 0 0 0 0 0 ++ 0 0 0 0 0 0 0 0 0 0 0 0 ++ 0 0 0 0 0 0 0 0 0 0 0 0 ++ 0 0 0 0 0 0 0 0 0 0 0 0 ++ 0 0 0 0 0 0 0 0 0 0 0 0 ++ 0 0 0 0 0 0 0 0 0 0 0 0 ++ 0 0 0 0 0 0 0 0 0 0 0 0 ++ 0 0 0 0 0 0 0 0 0 0 0 0 ++ 0 0 0 0 0 0 0 0 0 0 0 0 ++ 0 0 0 0 0 0 0 0 0 0 0 0 ++ 0 0 0 0 0 0 0 0 0 0 0 0 ++ 0 0 0 0 0 0 0 0 0 0 0 0 ++ 0 0 0 0 0 0 0 0 0 0 0 0 ++ 0 0 0 0 0 0 0 0 0 0 0 0 ++ 0 0 0 0 0 0 0 0 0 0 0 0 ++ 0 0 0 0 0 0 0 0 0 0 0 0 ++ 0 0 0 0 0 0 0 0 0 0 0 0 ++ 0 0 0 0 0 0 0 0 0 0 0 0 ++ 0 0 0 0 0 0 0 0 0 0 0 0 ++ 0 0 0 0 0 0 0 0 0 0 0 0 ++ 0 0 0 0 0 0 0 0 0 0 0 0 +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/drivers/video/pxafb.c linux-2.6.29-rc3.owrt/drivers/video/pxafb.c +--- linux-2.6.29.owrt/drivers/video/pxafb.c 2009-05-10 22:04:38.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/drivers/video/pxafb.c 2009-05-10 23:48:29.000000000 +0200 +@@ -2230,7 +2230,7 @@ + + static struct platform_driver pxafb_driver = { + .probe = pxafb_probe, +- .remove = __devexit_p(pxafb_remove), ++ .remove = pxafb_remove, + .suspend = pxafb_suspend, + .resume = pxafb_resume, + .driver = { +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/drivers/video/sh_mobile_lcdcfb.c linux-2.6.29-rc3.owrt/drivers/video/sh_mobile_lcdcfb.c +--- linux-2.6.29.owrt/drivers/video/sh_mobile_lcdcfb.c 2009-05-10 22:04:38.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/drivers/video/sh_mobile_lcdcfb.c 2009-05-10 23:48:29.000000000 +0200 +@@ -446,6 +446,7 @@ + { + struct sh_mobile_lcdc_chan *ch; + struct sh_mobile_lcdc_board_cfg *board_cfg; ++ unsigned long tmp; + int k; + + /* tell the board code to disable the panel */ +@@ -455,8 +456,9 @@ + if (board_cfg->display_off) + board_cfg->display_off(board_cfg->board_data); + +- /* cleanup deferred io if enabled */ +- if (ch->info.fbdefio) { ++ /* cleanup deferred io if SYS bus */ ++ tmp = ch->cfg.sys_bus_cfg.deferred_io_msec; ++ if (ch->ldmt1r_value & (1 << 12) && tmp) { + fb_deferred_io_cleanup(&ch->info); + ch->info.fbdefio = NULL; + } +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/drivers/virtio/virtio_pci.c linux-2.6.29-rc3.owrt/drivers/virtio/virtio_pci.c +--- linux-2.6.29.owrt/drivers/virtio/virtio_pci.c 2009-05-10 22:04:38.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/drivers/virtio/virtio_pci.c 2009-05-10 23:48:29.000000000 +0200 +@@ -192,7 +192,7 @@ + drv = container_of(vp_dev->vdev.dev.driver, + struct virtio_driver, driver); + +- if (drv && drv->config_changed) ++ if (drv->config_changed) + drv->config_changed(&vp_dev->vdev); + } + +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/drivers/w1/masters/w1-gpio.c linux-2.6.29-rc3.owrt/drivers/w1/masters/w1-gpio.c +--- linux-2.6.29.owrt/drivers/w1/masters/w1-gpio.c 2009-05-10 22:04:39.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/drivers/w1/masters/w1-gpio.c 2009-05-10 23:48:29.000000000 +0200 +@@ -39,7 +39,7 @@ + { + struct w1_gpio_platform_data *pdata = data; + +- return gpio_get_value(pdata->pin) ? 1 : 0; ++ return gpio_get_value(pdata->pin); + } + + static int __init w1_gpio_probe(struct platform_device *pdev) +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/drivers/w1/slaves/Kconfig linux-2.6.29-rc3.owrt/drivers/w1/slaves/Kconfig +--- linux-2.6.29.owrt/drivers/w1/slaves/Kconfig 2009-05-10 22:04:39.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/drivers/w1/slaves/Kconfig 2009-05-10 23:48:29.000000000 +0200 +@@ -16,12 +16,6 @@ + Say Y here if you want to connect 1-wire + simple 64bit memory rom(ds2401/ds2411/ds1990*) to your wire. + +-config W1_SLAVE_DS2431 +- tristate "1kb EEPROM family support (DS2431)" +- help +- Say Y here if you want to use a 1-wire +- 1kb EEPROM family device (DS2431) +- + config W1_SLAVE_DS2433 + tristate "4kb EEPROM family support (DS2433)" + help +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/drivers/w1/slaves/Makefile linux-2.6.29-rc3.owrt/drivers/w1/slaves/Makefile +--- linux-2.6.29.owrt/drivers/w1/slaves/Makefile 2009-05-10 22:04:39.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/drivers/w1/slaves/Makefile 2009-05-10 23:48:29.000000000 +0200 +@@ -4,7 +4,6 @@ + + obj-$(CONFIG_W1_SLAVE_THERM) += w1_therm.o + obj-$(CONFIG_W1_SLAVE_SMEM) += w1_smem.o +-obj-$(CONFIG_W1_SLAVE_DS2431) += w1_ds2431.o + obj-$(CONFIG_W1_SLAVE_DS2433) += w1_ds2433.o + obj-$(CONFIG_W1_SLAVE_DS2760) += w1_ds2760.o + obj-$(CONFIG_W1_SLAVE_BQ27000) += w1_bq27000.o +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/drivers/w1/slaves/w1_ds2433.c linux-2.6.29-rc3.owrt/drivers/w1/slaves/w1_ds2433.c +--- linux-2.6.29.owrt/drivers/w1/slaves/w1_ds2433.c 2009-05-10 22:04:39.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/drivers/w1/slaves/w1_ds2433.c 2009-05-10 23:48:29.000000000 +0200 +@@ -156,9 +156,6 @@ + */ + static int w1_f23_write(struct w1_slave *sl, int addr, int len, const u8 *data) + { +-#ifdef CONFIG_W1_SLAVE_DS2433_CRC +- struct w1_f23_data *f23 = sl->family_data; +-#endif + u8 wrbuf[4]; + u8 rdbuf[W1_PAGE_SIZE + 3]; + u8 es = (addr + len - 1) & 0x1f; +@@ -199,9 +196,7 @@ + + /* Reset the bus to wake up the EEPROM (this may not be needed) */ + w1_reset_bus(sl->master); +-#ifdef CONFIG_W1_SLAVE_DS2433_CRC +- f23->validcrc &= ~(1 << (addr >> W1_PAGE_BITS)); +-#endif ++ + return 0; + } + +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/drivers/w1/slaves/w1_therm.c linux-2.6.29-rc3.owrt/drivers/w1/slaves/w1_therm.c +--- linux-2.6.29.owrt/drivers/w1/slaves/w1_therm.c 2009-05-10 22:04:39.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/drivers/w1/slaves/w1_therm.c 2009-05-10 23:48:29.000000000 +0200 +@@ -115,7 +115,7 @@ + + static inline int w1_DS18B20_convert_temp(u8 rom[9]) + { +- int t = ((s16)rom[1] << 8) | rom[0]; ++ s16 t = (rom[1] << 8) | rom[0]; + t = t*1000/16; + return t; + } +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/drivers/watchdog/at91rm9200_wdt.c linux-2.6.29-rc3.owrt/drivers/watchdog/at91rm9200_wdt.c +--- linux-2.6.29.owrt/drivers/watchdog/at91rm9200_wdt.c 2009-05-10 22:04:38.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/drivers/watchdog/at91rm9200_wdt.c 2009-05-10 23:48:29.000000000 +0200 +@@ -107,10 +107,10 @@ + static int at91_wdt_settimeout(int new_time) + { + /* +- * All counting occurs at SLOW_CLOCK / 128 = 256 Hz ++ * All counting occurs at SLOW_CLOCK / 128 = 0.256 Hz + * + * Since WDV is a 16-bit counter, the maximum period is +- * 65536 / 256 = 256 seconds. ++ * 65536 / 0.256 = 256 seconds. + */ + if ((new_time <= 0) || (new_time > WDT_MAX_TIME)) + return -EINVAL; +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/drivers/watchdog/at91sam9_wdt.c linux-2.6.29-rc3.owrt/drivers/watchdog/at91sam9_wdt.c +--- linux-2.6.29.owrt/drivers/watchdog/at91sam9_wdt.c 2009-05-10 22:04:38.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/drivers/watchdog/at91sam9_wdt.c 2009-05-10 23:48:29.000000000 +0200 +@@ -18,7 +18,6 @@ + #include <linux/errno.h> + #include <linux/fs.h> + #include <linux/init.h> +-#include <linux/io.h> + #include <linux/kernel.h> + #include <linux/miscdevice.h> + #include <linux/module.h> +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/drivers/watchdog/gef_wdt.c linux-2.6.29-rc3.owrt/drivers/watchdog/gef_wdt.c +--- linux-2.6.29.owrt/drivers/watchdog/gef_wdt.c 2009-05-10 22:04:38.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/drivers/watchdog/gef_wdt.c 2009-05-10 23:48:29.000000000 +0200 +@@ -269,7 +269,7 @@ + bus_clk = 133; /* in MHz */ + + freq = fsl_get_sys_freq(); +- if (freq != -1) ++ if (freq > 0) + bus_clk = freq; + + /* Map devices registers into memory */ +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/drivers/watchdog/iTCO_vendor_support.c linux-2.6.29-rc3.owrt/drivers/watchdog/iTCO_vendor_support.c +--- linux-2.6.29.owrt/drivers/watchdog/iTCO_vendor_support.c 2009-05-10 22:04:38.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/drivers/watchdog/iTCO_vendor_support.c 2009-05-10 23:48:29.000000000 +0200 +@@ -1,7 +1,7 @@ + /* + * intel TCO vendor specific watchdog driver support + * +- * (c) Copyright 2006-2009 Wim Van Sebroeck <wim@iguana.be>. ++ * (c) Copyright 2006-2008 Wim Van Sebroeck <wim@iguana.be>. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License +@@ -19,7 +19,7 @@ + + /* Module and version information */ + #define DRV_NAME "iTCO_vendor_support" +-#define DRV_VERSION "1.03" ++#define DRV_VERSION "1.02" + #define PFX DRV_NAME ": " + + /* Includes */ +@@ -77,26 +77,6 @@ + * 20.6 seconds. + */ + +-static void supermicro_old_pre_start(unsigned long acpibase) +-{ +- unsigned long val32; +- +- /* Bit 13: TCO_EN -> 0 = Disables TCO logic generating an SMI# */ +- val32 = inl(SMI_EN); +- val32 &= 0xffffdfff; /* Turn off SMI clearing watchdog */ +- outl(val32, SMI_EN); /* Needed to activate watchdog */ +-} +- +-static void supermicro_old_pre_stop(unsigned long acpibase) +-{ +- unsigned long val32; +- +- /* Bit 13: TCO_EN -> 1 = Enables the TCO logic to generate SMI# */ +- val32 = inl(SMI_EN); +- val32 |= 0x00002000; /* Turn on SMI clearing watchdog */ +- outl(val32, SMI_EN); /* Needed to deactivate watchdog */ +-} +- + static void supermicro_old_pre_keepalive(unsigned long acpibase) + { + /* Reload TCO Timer (done in iTCO_wdt_keepalive) + */ +@@ -248,18 +228,14 @@ + void iTCO_vendor_pre_start(unsigned long acpibase, + unsigned int heartbeat) + { +- if (vendorsupport == SUPERMICRO_OLD_BOARD) +- supermicro_old_pre_start(acpibase); +- else if (vendorsupport == SUPERMICRO_NEW_BOARD) ++ if (vendorsupport == SUPERMICRO_NEW_BOARD) + supermicro_new_pre_start(heartbeat); + } + EXPORT_SYMBOL(iTCO_vendor_pre_start); + + void iTCO_vendor_pre_stop(unsigned long acpibase) + { +- if (vendorsupport == SUPERMICRO_OLD_BOARD) +- supermicro_old_pre_stop(acpibase); +- else if (vendorsupport == SUPERMICRO_NEW_BOARD) ++ if (vendorsupport == SUPERMICRO_NEW_BOARD) + supermicro_new_pre_stop(); + } + EXPORT_SYMBOL(iTCO_vendor_pre_stop); +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/drivers/watchdog/iTCO_wdt.c linux-2.6.29-rc3.owrt/drivers/watchdog/iTCO_wdt.c +--- linux-2.6.29.owrt/drivers/watchdog/iTCO_wdt.c 2009-05-10 22:04:38.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/drivers/watchdog/iTCO_wdt.c 2009-05-10 23:48:29.000000000 +0200 +@@ -1,7 +1,7 @@ + /* +- * intel TCO Watchdog Driver (Used in i82801 and i63xxESB chipsets) ++ * intel TCO Watchdog Driver (Used in i82801 and i6300ESB chipsets) + * +- * (c) Copyright 2006-2009 Wim Van Sebroeck <wim@iguana.be>. ++ * (c) Copyright 2006-2008 Wim Van Sebroeck <wim@iguana.be>. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License +@@ -63,7 +63,7 @@ + + /* Module and version information */ + #define DRV_NAME "iTCO_wdt" +-#define DRV_VERSION "1.05" ++#define DRV_VERSION "1.04" + #define PFX DRV_NAME ": " + + /* Includes */ +@@ -236,16 +236,16 @@ + + /* Address definitions for the TCO */ + /* TCO base address */ +-#define TCOBASE iTCO_wdt_private.ACPIBASE + 0x60 ++#define TCOBASE iTCO_wdt_private.ACPIBASE + 0x60 + /* SMI Control and Enable Register */ +-#define SMI_EN iTCO_wdt_private.ACPIBASE + 0x30 ++#define SMI_EN iTCO_wdt_private.ACPIBASE + 0x30 + + #define TCO_RLD TCOBASE + 0x00 /* TCO Timer Reload and Curr. Value */ + #define TCOv1_TMR TCOBASE + 0x01 /* TCOv1 Timer Initial Value */ +-#define TCO_DAT_IN TCOBASE + 0x02 /* TCO Data In Register */ +-#define TCO_DAT_OUT TCOBASE + 0x03 /* TCO Data Out Register */ +-#define TCO1_STS TCOBASE + 0x04 /* TCO1 Status Register */ +-#define TCO2_STS TCOBASE + 0x06 /* TCO2 Status Register */ ++#define TCO_DAT_IN TCOBASE + 0x02 /* TCO Data In Register */ ++#define TCO_DAT_OUT TCOBASE + 0x03 /* TCO Data Out Register */ ++#define TCO1_STS TCOBASE + 0x04 /* TCO1 Status Register */ ++#define TCO2_STS TCOBASE + 0x06 /* TCO2 Status Register */ + #define TCO1_CNT TCOBASE + 0x08 /* TCO1 Control Register */ + #define TCO2_CNT TCOBASE + 0x0a /* TCO2 Control Register */ + #define TCOv2_TMR TCOBASE + 0x12 /* TCOv2 Timer Initial Value */ +@@ -338,6 +338,7 @@ + static int iTCO_wdt_start(void) + { + unsigned int val; ++ unsigned long val32; + + spin_lock(&iTCO_wdt_private.io_lock); + +@@ -350,6 +351,11 @@ + return -EIO; + } + ++ /* Bit 13: TCO_EN -> 0 = Disables TCO logic generating an SMI# */ ++ val32 = inl(SMI_EN); ++ val32 &= 0xffffdfff; /* Turn off SMI clearing watchdog */ ++ outl(val32, SMI_EN); ++ + /* Force the timer to its reload value by writing to the TCO_RLD + register */ + if (iTCO_wdt_private.iTCO_version == 2) +@@ -372,6 +378,7 @@ + static int iTCO_wdt_stop(void) + { + unsigned int val; ++ unsigned long val32; + + spin_lock(&iTCO_wdt_private.io_lock); + +@@ -383,6 +390,11 @@ + outw(val, TCO1_CNT); + val = inw(TCO1_CNT); + ++ /* Bit 13: TCO_EN -> 1 = Enables the TCO logic to generate SMI# */ ++ val32 = inl(SMI_EN); ++ val32 |= 0x00002000; ++ outl(val32, SMI_EN); ++ + /* Set the NO_REBOOT bit to prevent later reboots, just for sure */ + iTCO_wdt_set_NO_REBOOT_bit(); + +@@ -637,7 +649,6 @@ + int ret; + u32 base_address; + unsigned long RCBA; +- unsigned long val32; + + /* + * Find the ACPI/PM base I/O address which is the base +@@ -684,10 +695,6 @@ + ret = -EIO; + goto out; + } +- /* Bit 13: TCO_EN -> 0 = Disables TCO logic generating an SMI# */ +- val32 = inl(SMI_EN); +- val32 &= 0xffffdfff; /* Turn off SMI clearing watchdog */ +- outl(val32, SMI_EN); + + /* The TCO I/O registers reside in a 32-byte range pointed to + by the TCOBASE value */ +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/drivers/watchdog/Kconfig linux-2.6.29-rc3.owrt/drivers/watchdog/Kconfig +--- linux-2.6.29.owrt/drivers/watchdog/Kconfig 2009-05-10 22:04:38.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/drivers/watchdog/Kconfig 2009-05-10 23:48:29.000000000 +0200 +@@ -406,7 +406,7 @@ + ---help--- + Hardware driver for the intel TCO timer based watchdog devices. + These drivers are included in the Intel 82801 I/O Controller +- Hub family (from ICH0 up to ICH10) and in the Intel 63xxESB ++ Hub family (from ICH0 up to ICH8) and in the Intel 6300ESB + controller hub. + + The TCO (Total Cost of Ownership) timer is a watchdog timer +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/drivers/watchdog/ks8695_wdt.c linux-2.6.29-rc3.owrt/drivers/watchdog/ks8695_wdt.c +--- linux-2.6.29.owrt/drivers/watchdog/ks8695_wdt.c 2009-05-10 22:04:38.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/drivers/watchdog/ks8695_wdt.c 2009-05-10 23:48:29.000000000 +0200 +@@ -21,7 +21,6 @@ + #include <linux/watchdog.h> + #include <linux/io.h> + #include <linux/uaccess.h> +-#include <mach/timex.h> + #include <mach/regs-timer.h> + + #define WDT_DEFAULT_TIME 5 /* seconds */ +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/drivers/watchdog/orion5x_wdt.c linux-2.6.29-rc3.owrt/drivers/watchdog/orion5x_wdt.c +--- linux-2.6.29.owrt/drivers/watchdog/orion5x_wdt.c 2009-05-10 22:04:38.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/drivers/watchdog/orion5x_wdt.c 2009-05-10 23:48:29.000000000 +0200 +@@ -29,7 +29,6 @@ + #define WDT_EN 0x0010 + #define WDT_VAL (TIMER_VIRT_BASE + 0x0024) + +-#define ORION5X_TCLK 166666667 + #define WDT_MAX_DURATION (0xffffffff / ORION5X_TCLK) + #define WDT_IN_USE 0 + #define WDT_OK_TO_CLOSE 1 +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/drivers/watchdog/rc32434_wdt.c linux-2.6.29-rc3.owrt/drivers/watchdog/rc32434_wdt.c +--- linux-2.6.29.owrt/drivers/watchdog/rc32434_wdt.c 2009-05-10 22:04:38.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/drivers/watchdog/rc32434_wdt.c 2009-05-10 23:48:29.000000000 +0200 +@@ -34,89 +34,104 @@ + #include <asm/time.h> + #include <asm/mach-rc32434/integ.h> + +-#define VERSION "0.4" ++#define MAX_TIMEOUT 20 ++#define RC32434_WDT_INTERVAL (15 * HZ) ++ ++#define VERSION "0.2" + + static struct { ++ struct completion stop; ++ int running; ++ struct timer_list timer; ++ int queue; ++ int default_ticks; + unsigned long inuse; + } rc32434_wdt_device; + + static struct integ __iomem *wdt_reg; ++static int ticks = 100 * HZ; + + static int expect_close; +- +-/* Board internal clock speed in Hz, +- * the watchdog timer ticks at. */ +-extern unsigned int idt_cpu_freq; +- +-/* translate wtcompare value to seconds and vice versa */ +-#define WTCOMP2SEC(x) (x / idt_cpu_freq) +-#define SEC2WTCOMP(x) (x * idt_cpu_freq) +- +-/* Use a default timeout of 20s. This should be +- * safe for CPU clock speeds up to 400MHz, as +- * ((2 ^ 32) - 1) / (400MHz / 2) = 21s. */ +-#define WATCHDOG_TIMEOUT 20 +- +-static int timeout = WATCHDOG_TIMEOUT; ++static int timeout; + + static int nowayout = WATCHDOG_NOWAYOUT; + module_param(nowayout, int, 0); + MODULE_PARM_DESC(nowayout, "Watchdog cannot be stopped once started (default=" + __MODULE_STRING(WATCHDOG_NOWAYOUT) ")"); + +-/* apply or and nand masks to data read from addr and write back */ +-#define SET_BITS(addr, or, nand) \ +- writel((readl(&addr) | or) & ~nand, &addr) + + static void rc32434_wdt_start(void) + { +- u32 or, nand; +- +- /* zero the counter before enabling */ +- writel(0, &wdt_reg->wtcount); +- +- /* don't generate a non-maskable interrupt, +- * do a warm reset instead */ +- nand = 1 << RC32434_ERR_WNE; +- or = 1 << RC32434_ERR_WRE; ++ u32 val; + +- /* reset the ERRCS timeout bit in case it's set */ +- nand |= 1 << RC32434_ERR_WTO; ++ if (!rc32434_wdt_device.inuse) { ++ writel(0, &wdt_reg->wtcount); + +- SET_BITS(wdt_reg->errcs, or, nand); ++ val = RC32434_ERR_WRE; ++ writel(readl(&wdt_reg->errcs) | val, &wdt_reg->errcs); + +- /* reset WTC timeout bit and enable WDT */ +- nand = 1 << RC32434_WTC_TO; +- or = 1 << RC32434_WTC_EN; +- +- SET_BITS(wdt_reg->wtc, or, nand); ++ val = RC32434_WTC_EN; ++ writel(readl(&wdt_reg->wtc) | val, &wdt_reg->wtc); ++ } ++ rc32434_wdt_device.running++; + } + + static void rc32434_wdt_stop(void) + { +- /* Disable WDT */ +- SET_BITS(wdt_reg->wtc, 0, 1 << RC32434_WTC_EN); ++ u32 val; ++ ++ if (rc32434_wdt_device.running) { ++ ++ val = ~RC32434_WTC_EN; ++ writel(readl(&wdt_reg->wtc) & val, &wdt_reg->wtc); ++ ++ val = ~RC32434_ERR_WRE; ++ writel(readl(&wdt_reg->errcs) & val, &wdt_reg->errcs); ++ ++ rc32434_wdt_device.running = 0; ++ } + } + +-static int rc32434_wdt_set(int new_timeout) ++static void rc32434_wdt_set(int new_timeout) + { +- int max_to = WTCOMP2SEC((u32)-1); ++ u32 cmp = new_timeout * HZ; ++ u32 state, val; + +- if (new_timeout < 0 || new_timeout > max_to) { +- printk(KERN_ERR KBUILD_MODNAME +- ": timeout value must be between 0 and %d", +- max_to); +- return -EINVAL; +- } + timeout = new_timeout; +- writel(SEC2WTCOMP(timeout), &wdt_reg->wtcompare); ++ /* ++ * store and disable WTC ++ */ ++ state = (u32)(readl(&wdt_reg->wtc) & RC32434_WTC_EN); ++ val = ~RC32434_WTC_EN; ++ writel(readl(&wdt_reg->wtc) & val, &wdt_reg->wtc); + +- return 0; ++ writel(0, &wdt_reg->wtcount); ++ writel(cmp, &wdt_reg->wtcompare); ++ ++ /* ++ * restore WTC ++ */ ++ ++ writel(readl(&wdt_reg->wtc) | state, &wdt_reg); + } + +-static void rc32434_wdt_ping(void) ++static void rc32434_wdt_reset(void) + { ++ ticks = rc32434_wdt_device.default_ticks; ++} ++ ++static void rc32434_wdt_update(unsigned long unused) ++{ ++ if (rc32434_wdt_device.running) ++ ticks--; ++ + writel(0, &wdt_reg->wtcount); ++ ++ if (rc32434_wdt_device.queue && ticks) ++ mod_timer(&rc32434_wdt_device.timer, ++ jiffies + RC32434_WDT_INTERVAL); ++ else ++ complete(&rc32434_wdt_device.stop); + } + + static int rc32434_wdt_open(struct inode *inode, struct file *file) +@@ -127,23 +142,19 @@ + if (nowayout) + __module_get(THIS_MODULE); + +- rc32434_wdt_start(); +- rc32434_wdt_ping(); +- + return nonseekable_open(inode, file); + } + + static int rc32434_wdt_release(struct inode *inode, struct file *file) + { +- if (expect_close == 42) { ++ if (expect_close && nowayout == 0) { + rc32434_wdt_stop(); + printk(KERN_INFO KBUILD_MODNAME ": disabling watchdog timer\n"); + module_put(THIS_MODULE); +- } else { ++ } else + printk(KERN_CRIT KBUILD_MODNAME + ": device closed unexpectedly. WDT will not stop !\n"); +- rc32434_wdt_ping(); +- } ++ + clear_bit(0, &rc32434_wdt_device.inuse); + return 0; + } +@@ -163,10 +174,10 @@ + if (get_user(c, data + i)) + return -EFAULT; + if (c == 'V') +- expect_close = 42; ++ expect_close = 1; + } + } +- rc32434_wdt_ping(); ++ rc32434_wdt_update(0); + return len; + } + return 0; +@@ -186,11 +197,11 @@ + }; + switch (cmd) { + case WDIOC_KEEPALIVE: +- rc32434_wdt_ping(); ++ rc32434_wdt_reset(); + break; + case WDIOC_GETSTATUS: + case WDIOC_GETBOOTSTATUS: +- value = 0; ++ value = readl(&wdt_reg->wtcount); + if (copy_to_user(argp, &value, sizeof(int))) + return -EFAULT; + break; +@@ -207,7 +218,6 @@ + break; + case WDIOS_DISABLECARD: + rc32434_wdt_stop(); +- break; + default: + return -EINVAL; + } +@@ -215,9 +225,11 @@ + case WDIOC_SETTIMEOUT: + if (copy_from_user(&new_timeout, argp, sizeof(int))) + return -EFAULT; +- if (rc32434_wdt_set(new_timeout)) ++ if (new_timeout < 1) + return -EINVAL; +- /* Fall through */ ++ if (new_timeout > MAX_TIMEOUT) ++ return -EINVAL; ++ rc32434_wdt_set(new_timeout); + case WDIOC_GETTIMEOUT: + return copy_to_user(argp, &timeout, sizeof(int)); + default: +@@ -242,15 +254,15 @@ + .fops = &rc32434_wdt_fops, + }; + +-static char banner[] __devinitdata = KERN_INFO KBUILD_MODNAME ++static char banner[] = KERN_INFO KBUILD_MODNAME + ": Watchdog Timer version " VERSION ", timer margin: %d sec\n"; + +-static int __devinit rc32434_wdt_probe(struct platform_device *pdev) ++static int rc32434_wdt_probe(struct platform_device *pdev) + { + int ret; + struct resource *r; + +- r = platform_get_resource_byname(pdev, IORESOURCE_MEM, "rb532_wdt_res"); ++ r = platform_get_resource_byname(pdev, IORESOURCE_MEM, "rb500_wdt_res"); + if (!r) { + printk(KERN_ERR KBUILD_MODNAME + "failed to retrieve resources\n"); +@@ -265,12 +277,24 @@ + } + + ret = misc_register(&rc32434_wdt_miscdev); ++ + if (ret < 0) { + printk(KERN_ERR KBUILD_MODNAME + "failed to register watchdog device\n"); + goto unmap; + } + ++ init_completion(&rc32434_wdt_device.stop); ++ rc32434_wdt_device.queue = 0; ++ ++ clear_bit(0, &rc32434_wdt_device.inuse); ++ ++ setup_timer(&rc32434_wdt_device.timer, rc32434_wdt_update, 0L); ++ ++ rc32434_wdt_device.default_ticks = ticks; ++ ++ rc32434_wdt_start(); ++ + printk(banner, timeout); + + return 0; +@@ -280,17 +304,23 @@ + return ret; + } + +-static int __devexit rc32434_wdt_remove(struct platform_device *pdev) ++static int rc32434_wdt_remove(struct platform_device *pdev) + { ++ if (rc32434_wdt_device.queue) { ++ rc32434_wdt_device.queue = 0; ++ wait_for_completion(&rc32434_wdt_device.stop); ++ } + misc_deregister(&rc32434_wdt_miscdev); ++ + iounmap(wdt_reg); ++ + return 0; + } + + static struct platform_driver rc32434_wdt = { + .probe = rc32434_wdt_probe, +- .remove = __devexit_p(rc32434_wdt_remove), +- .driver = { ++ .remove = rc32434_wdt_remove, ++ .driver = { + .name = "rc32434_wdt", + } + }; +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/drivers/xen/balloon.c linux-2.6.29-rc3.owrt/drivers/xen/balloon.c +--- linux-2.6.29.owrt/drivers/xen/balloon.c 2009-05-10 22:04:39.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/drivers/xen/balloon.c 2009-05-10 23:48:29.000000000 +0200 +@@ -498,7 +498,7 @@ + if (!capable(CAP_SYS_ADMIN)) + return -EPERM; + +- target_bytes = simple_strtoull(buf, &endchar, 0) * 1024; ++ target_bytes = memparse(buf, &endchar); + + balloon_set_new_target(target_bytes >> PAGE_SHIFT); + +@@ -508,39 +508,8 @@ + static SYSDEV_ATTR(target_kb, S_IRUGO | S_IWUSR, + show_target_kb, store_target_kb); + +- +-static ssize_t show_target(struct sys_device *dev, struct sysdev_attribute *attr, +- char *buf) +-{ +- return sprintf(buf, "%llu\n", +- (u64)balloon_stats.target_pages << PAGE_SHIFT); +-} +- +-static ssize_t store_target(struct sys_device *dev, +- struct sysdev_attribute *attr, +- const char *buf, +- size_t count) +-{ +- char *endchar; +- unsigned long long target_bytes; +- +- if (!capable(CAP_SYS_ADMIN)) +- return -EPERM; +- +- target_bytes = memparse(buf, &endchar); +- +- balloon_set_new_target(target_bytes >> PAGE_SHIFT); +- +- return count; +-} +- +-static SYSDEV_ATTR(target, S_IRUGO | S_IWUSR, +- show_target, store_target); +- +- + static struct sysdev_attribute *balloon_attrs[] = { + &attr_target_kb, +- &attr_target, + }; + + static struct attribute *balloon_info_attrs[] = { +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/drivers/xen/manage.c linux-2.6.29-rc3.owrt/drivers/xen/manage.c +--- linux-2.6.29.owrt/drivers/xen/manage.c 2009-05-10 22:04:39.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/drivers/xen/manage.c 2009-05-10 23:48:29.000000000 +0200 +@@ -45,13 +45,6 @@ + err); + return err; + } +- err = sysdev_suspend(PMSG_SUSPEND); +- if (err) { +- printk(KERN_ERR "xen_suspend: sysdev_suspend failed: %d\n", +- err); +- device_power_up(PMSG_RESUME); +- return err; +- } + + xen_mm_pin_all(); + gnttab_suspend(); +@@ -68,7 +61,6 @@ + gnttab_resume(); + xen_mm_unpin_all(); + +- sysdev_resume(); + device_power_up(PMSG_RESUME); + + if (!*cancelled) { +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/fs/aio.c linux-2.6.29-rc3.owrt/fs/aio.c +--- linux-2.6.29.owrt/fs/aio.c 2009-05-10 22:04:39.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/fs/aio.c 2009-05-10 23:48:29.000000000 +0200 +@@ -443,7 +443,7 @@ + req->private = NULL; + req->ki_iovec = NULL; + INIT_LIST_HEAD(&req->ki_run_list); +- req->ki_eventfd = NULL; ++ req->ki_eventfd = ERR_PTR(-EINVAL); + + /* Check if the completion queue has enough free space to + * accept an event from this io. +@@ -485,6 +485,8 @@ + { + assert_spin_locked(&ctx->ctx_lock); + ++ if (!IS_ERR(req->ki_eventfd)) ++ fput(req->ki_eventfd); + if (req->ki_dtor) + req->ki_dtor(req); + if (req->ki_iovec != &req->ki_inline_vec) +@@ -506,11 +508,8 @@ + list_del(&req->ki_list); + spin_unlock_irq(&fput_lock); + +- /* Complete the fput(s) */ +- if (req->ki_filp != NULL) +- __fput(req->ki_filp); +- if (req->ki_eventfd != NULL) +- __fput(req->ki_eventfd); ++ /* Complete the fput */ ++ __fput(req->ki_filp); + + /* Link the iocb into the context's free list */ + spin_lock_irq(&ctx->ctx_lock); +@@ -528,14 +527,12 @@ + */ + static int __aio_put_req(struct kioctx *ctx, struct kiocb *req) + { +- int schedule_putreq = 0; +- + dprintk(KERN_DEBUG "aio_put(%p): f_count=%ld\n", + req, atomic_long_read(&req->ki_filp->f_count)); + + assert_spin_locked(&ctx->ctx_lock); + +- req->ki_users--; ++ req->ki_users --; + BUG_ON(req->ki_users < 0); + if (likely(req->ki_users)) + return 0; +@@ -543,23 +540,10 @@ + req->ki_cancel = NULL; + req->ki_retry = NULL; + +- /* +- * Try to optimize the aio and eventfd file* puts, by avoiding to +- * schedule work in case it is not __fput() time. In normal cases, +- * we would not be holding the last reference to the file*, so +- * this function will be executed w/out any aio kthread wakeup. ++ /* Must be done under the lock to serialise against cancellation. ++ * Call this aio_fput as it duplicates fput via the fput_work. + */ +- if (unlikely(atomic_long_dec_and_test(&req->ki_filp->f_count))) +- schedule_putreq++; +- else +- req->ki_filp = NULL; +- if (req->ki_eventfd != NULL) { +- if (unlikely(atomic_long_dec_and_test(&req->ki_eventfd->f_count))) +- schedule_putreq++; +- else +- req->ki_eventfd = NULL; +- } +- if (unlikely(schedule_putreq)) { ++ if (unlikely(atomic_long_dec_and_test(&req->ki_filp->f_count))) { + get_ioctx(ctx); + spin_lock(&fput_lock); + list_add(&req->ki_list, &fput_head); +@@ -587,7 +571,7 @@ + static struct kioctx *lookup_ioctx(unsigned long ctx_id) + { + struct mm_struct *mm = current->mm; +- struct kioctx *ctx, *ret = NULL; ++ struct kioctx *ctx = NULL; + struct hlist_node *n; + + rcu_read_lock(); +@@ -595,13 +579,12 @@ + hlist_for_each_entry_rcu(ctx, n, &mm->ioctx_list, list) { + if (ctx->user_id == ctx_id && !ctx->dead) { + get_ioctx(ctx); +- ret = ctx; + break; + } + } + + rcu_read_unlock(); +- return ret; ++ return ctx; + } + + /* +@@ -1026,7 +1009,7 @@ + * eventfd. The eventfd_signal() function is safe to be called + * from IRQ context. + */ +- if (iocb->ki_eventfd != NULL) ++ if (!IS_ERR(iocb->ki_eventfd)) + eventfd_signal(iocb->ki_eventfd, 1); + + put_rq: +@@ -1625,7 +1608,6 @@ + req->ki_eventfd = eventfd_fget((int) iocb->aio_resfd); + if (IS_ERR(req->ki_eventfd)) { + ret = PTR_ERR(req->ki_eventfd); +- req->ki_eventfd = NULL; + goto out_put_req; + } + } +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/fs/binfmt_elf.c linux-2.6.29-rc3.owrt/fs/binfmt_elf.c +--- linux-2.6.29.owrt/fs/binfmt_elf.c 2009-05-10 22:04:39.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/fs/binfmt_elf.c 2009-05-10 23:48:29.000000000 +0200 +@@ -1225,15 +1225,7 @@ + magic.elfmag[EI_MAG1] = ELFMAG1; + magic.elfmag[EI_MAG2] = ELFMAG2; + magic.elfmag[EI_MAG3] = ELFMAG3; +- /* +- * Switch to the user "segment" for get_user(), +- * then put back what elf_core_dump() had in place. +- */ +- set_fs(USER_DS); +- if (unlikely(get_user(word, header))) +- word = 0; +- set_fs(fs); +- if (word == magic.cmp) ++ if (get_user(word, header) == 0 && word == magic.cmp) + return PAGE_SIZE; + } + +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/fs/bio.c linux-2.6.29-rc3.owrt/fs/bio.c +--- linux-2.6.29.owrt/fs/bio.c 2009-05-10 22:04:39.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/fs/bio.c 2009-05-10 23:48:29.000000000 +0200 +@@ -302,10 +302,9 @@ + struct bio *bio_alloc_bioset(gfp_t gfp_mask, int nr_iovecs, struct bio_set *bs) + { + struct bio *bio = NULL; +- void *uninitialized_var(p); + + if (bs) { +- p = mempool_alloc(bs->bio_pool, gfp_mask); ++ void *p = mempool_alloc(bs->bio_pool, gfp_mask); + + if (p) + bio = p + bs->front_pad; +@@ -330,7 +329,7 @@ + } + if (unlikely(!bvl)) { + if (bs) +- mempool_free(p, bs->bio_pool); ++ mempool_free(bio, bs->bio_pool); + else + kfree(bio); + bio = NULL; +@@ -463,12 +462,10 @@ + if (bio_integrity(bio)) { + int ret; + +- ret = bio_integrity_clone(b, bio, gfp_mask, fs_bio_set); ++ ret = bio_integrity_clone(b, bio, fs_bio_set); + +- if (ret < 0) { +- bio_put(b); ++ if (ret < 0) + return NULL; +- } + } + + return b; +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/fs/bio-integrity.c linux-2.6.29-rc3.owrt/fs/bio-integrity.c +--- linux-2.6.29.owrt/fs/bio-integrity.c 2009-05-10 22:04:39.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/fs/bio-integrity.c 2009-05-10 23:48:29.000000000 +0200 +@@ -140,6 +140,7 @@ + + iv = bip_vec_idx(bip, bip->bip_vcnt); + BUG_ON(iv == NULL); ++ BUG_ON(iv->bv_page != NULL); + + iv->bv_page = page; + iv->bv_len = len; +@@ -464,7 +465,7 @@ + + if (ret) { + kunmap_atomic(kaddr, KM_USER0); +- return ret; ++ break; + } + + sectors = bv->bv_len / bi->sector_size; +@@ -492,13 +493,18 @@ + struct bio_integrity_payload *bip = + container_of(work, struct bio_integrity_payload, bip_work); + struct bio *bio = bip->bip_bio; +- int error; ++ int error = bip->bip_error; + +- error = bio_integrity_verify(bio); ++ if (bio_integrity_verify(bio)) { ++ clear_bit(BIO_UPTODATE, &bio->bi_flags); ++ error = -EIO; ++ } + + /* Restore original bio completion handler */ + bio->bi_end_io = bip->bip_end_io; +- bio_endio(bio, error); ++ ++ if (bio->bi_end_io) ++ bio->bi_end_io(bio, error); + } + + /** +@@ -519,17 +525,7 @@ + + BUG_ON(bip->bip_bio != bio); + +- /* In case of an I/O error there is no point in verifying the +- * integrity metadata. Restore original bio end_io handler +- * and run it. +- */ +- if (error) { +- bio->bi_end_io = bip->bip_end_io; +- bio_endio(bio, error); +- +- return; +- } +- ++ bip->bip_error = error; + INIT_WORK(&bip->bip_work, bio_integrity_verify_fn); + queue_work(kintegrityd_wq, &bip->bip_work); + } +@@ -685,20 +681,19 @@ + * bio_integrity_clone - Callback for cloning bios with integrity metadata + * @bio: New bio + * @bio_src: Original bio +- * @gfp_mask: Memory allocation mask + * @bs: bio_set to allocate bip from + * + * Description: Called to allocate a bip when cloning a bio + */ + int bio_integrity_clone(struct bio *bio, struct bio *bio_src, +- gfp_t gfp_mask, struct bio_set *bs) ++ struct bio_set *bs) + { + struct bio_integrity_payload *bip_src = bio_src->bi_integrity; + struct bio_integrity_payload *bip; + + BUG_ON(bip_src == NULL); + +- bip = bio_integrity_alloc_bioset(bio, gfp_mask, bip_src->bip_vcnt, bs); ++ bip = bio_integrity_alloc_bioset(bio, GFP_NOIO, bip_src->bip_vcnt, bs); + + if (bip == NULL) + return -EIO; +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/fs/btrfs/async-thread.c linux-2.6.29-rc3.owrt/fs/btrfs/async-thread.c +--- linux-2.6.29.owrt/fs/btrfs/async-thread.c 2009-05-10 22:04:39.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/fs/btrfs/async-thread.c 2009-05-10 23:48:29.000000000 +0200 +@@ -16,11 +16,11 @@ + * Boston, MA 021110-1307, USA. + */ + ++#include <linux/version.h> + #include <linux/kthread.h> + #include <linux/list.h> + #include <linux/spinlock.h> +-#include <linux/freezer.h> +-#include <linux/ftrace.h> ++# include <linux/freezer.h> + #include "async-thread.h" + + #define WORK_QUEUED_BIT 0 +@@ -143,7 +143,6 @@ + struct btrfs_work *work; + do { + spin_lock_irq(&worker->lock); +-again_locked: + while (!list_empty(&worker->pending)) { + cur = worker->pending.next; + work = list_entry(cur, struct btrfs_work, list); +@@ -166,50 +165,14 @@ + check_idle_worker(worker); + + } ++ worker->working = 0; + if (freezing(current)) { +- worker->working = 0; +- spin_unlock_irq(&worker->lock); + refrigerator(); + } else { ++ set_current_state(TASK_INTERRUPTIBLE); + spin_unlock_irq(&worker->lock); +- if (!kthread_should_stop()) { +- cpu_relax(); +- /* +- * we've dropped the lock, did someone else +- * jump_in? +- */ +- smp_mb(); +- if (!list_empty(&worker->pending)) +- continue; +- +- /* +- * this short schedule allows more work to +- * come in without the queue functions +- * needing to go through wake_up_process() +- * +- * worker->working is still 1, so nobody +- * is going to try and wake us up +- */ +- schedule_timeout(1); +- smp_mb(); +- if (!list_empty(&worker->pending)) +- continue; +- +- /* still no more work?, sleep for real */ +- spin_lock_irq(&worker->lock); +- set_current_state(TASK_INTERRUPTIBLE); +- if (!list_empty(&worker->pending)) +- goto again_locked; +- +- /* +- * this makes sure we get a wakeup when someone +- * adds something new to the queue +- */ +- worker->working = 0; +- spin_unlock_irq(&worker->lock); +- ++ if (!kthread_should_stop()) + schedule(); +- } + __set_current_state(TASK_RUNNING); + } + } while (!kthread_should_stop()); +@@ -387,14 +350,13 @@ + { + struct btrfs_worker_thread *worker = work->worker; + unsigned long flags; +- int wake = 0; + + if (test_and_set_bit(WORK_QUEUED_BIT, &work->flags)) + goto out; + + spin_lock_irqsave(&worker->lock, flags); +- list_add_tail(&work->list, &worker->pending); + atomic_inc(&worker->num_pending); ++ list_add_tail(&work->list, &worker->pending); + + /* by definition we're busy, take ourselves off the idle + * list +@@ -406,16 +368,10 @@ + &worker->workers->worker_list); + spin_unlock_irqrestore(&worker->workers->lock, flags); + } +- if (!worker->working) { +- wake = 1; +- worker->working = 1; +- } + + spin_unlock_irqrestore(&worker->lock, flags); +- if (wake) +- wake_up_process(worker->task); +-out: + ++out: + return 0; + } + +@@ -442,10 +398,9 @@ + } + + spin_lock_irqsave(&worker->lock, flags); +- +- list_add_tail(&work->list, &worker->pending); + atomic_inc(&worker->num_pending); + check_busy_worker(worker); ++ list_add_tail(&work->list, &worker->pending); + + /* + * avoid calling into wake_up_process if this thread has already +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/fs/btrfs/btrfs_inode.h linux-2.6.29-rc3.owrt/fs/btrfs/btrfs_inode.h +--- linux-2.6.29.owrt/fs/btrfs/btrfs_inode.h 2009-05-10 22:04:39.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/fs/btrfs/btrfs_inode.h 2009-05-10 23:48:29.000000000 +0200 +@@ -66,9 +66,6 @@ + */ + struct list_head delalloc_inodes; + +- /* the space_info for where this inode's data allocations are done */ +- struct btrfs_space_info *space_info; +- + /* full 64 bit generation number, struct vfs_inode doesn't have a big + * enough field for this. + */ +@@ -97,11 +94,6 @@ + */ + u64 delalloc_bytes; + +- /* total number of bytes that may be used for this inode for +- * delalloc +- */ +- u64 reserved_bytes; +- + /* + * the size of the file stored in the metadata on disk. data=ordered + * means the in-memory i_size might be larger than the size on disk +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/fs/btrfs/compression.c linux-2.6.29-rc3.owrt/fs/btrfs/compression.c +--- linux-2.6.29.owrt/fs/btrfs/compression.c 2009-05-10 22:04:39.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/fs/btrfs/compression.c 2009-05-10 23:48:29.000000000 +0200 +@@ -32,6 +32,7 @@ + #include <linux/swap.h> + #include <linux/writeback.h> + #include <linux/bit_spinlock.h> ++#include <linux/version.h> + #include <linux/pagevec.h> + #include "compat.h" + #include "ctree.h" +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/fs/btrfs/ctree.c linux-2.6.29-rc3.owrt/fs/btrfs/ctree.c +--- linux-2.6.29.owrt/fs/btrfs/ctree.c 2009-05-10 22:04:39.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/fs/btrfs/ctree.c 2009-05-10 23:48:29.000000000 +0200 +@@ -38,62 +38,20 @@ + static int del_ptr(struct btrfs_trans_handle *trans, struct btrfs_root *root, + struct btrfs_path *path, int level, int slot); + +-struct btrfs_path *btrfs_alloc_path(void) ++inline void btrfs_init_path(struct btrfs_path *p) + { +- struct btrfs_path *path; +- path = kmem_cache_zalloc(btrfs_path_cachep, GFP_NOFS); +- if (path) +- path->reada = 1; +- return path; ++ memset(p, 0, sizeof(*p)); + } + +-/* +- * set all locked nodes in the path to blocking locks. This should +- * be done before scheduling +- */ +-noinline void btrfs_set_path_blocking(struct btrfs_path *p) +-{ +- int i; +- for (i = 0; i < BTRFS_MAX_LEVEL; i++) { +- if (p->nodes[i] && p->locks[i]) +- btrfs_set_lock_blocking(p->nodes[i]); +- } +-} +- +-/* +- * reset all the locked nodes in the patch to spinning locks. +- * +- * held is used to keep lockdep happy, when lockdep is enabled +- * we set held to a blocking lock before we go around and +- * retake all the spinlocks in the path. You can safely use NULL +- * for held +- */ +-noinline void btrfs_clear_path_blocking(struct btrfs_path *p, +- struct extent_buffer *held) ++struct btrfs_path *btrfs_alloc_path(void) + { +- int i; +- +-#ifdef CONFIG_DEBUG_LOCK_ALLOC +- /* lockdep really cares that we take all of these spinlocks +- * in the right order. If any of the locks in the path are not +- * currently blocking, it is going to complain. So, make really +- * really sure by forcing the path to blocking before we clear +- * the path blocking. +- */ +- if (held) +- btrfs_set_lock_blocking(held); +- btrfs_set_path_blocking(p); +-#endif +- +- for (i = BTRFS_MAX_LEVEL - 1; i >= 0; i--) { +- if (p->nodes[i] && p->locks[i]) +- btrfs_clear_lock_blocking(p->nodes[i]); ++ struct btrfs_path *path; ++ path = kmem_cache_alloc(btrfs_path_cachep, GFP_NOFS); ++ if (path) { ++ btrfs_init_path(path); ++ path->reada = 1; + } +- +-#ifdef CONFIG_DEBUG_LOCK_ALLOC +- if (held) +- btrfs_clear_lock_blocking(held); +-#endif ++ return path; + } + + /* this also releases the path */ +@@ -277,7 +235,7 @@ + if (*cow_ret == buf) + unlock_orig = 1; + +- btrfs_assert_tree_locked(buf); ++ WARN_ON(!btrfs_tree_locked(buf)); + + if (parent) + parent_start = parent->start; +@@ -303,7 +261,7 @@ + trans->transid, level, &ins); + BUG_ON(ret); + cow = btrfs_init_new_buffer(trans, root, prealloc_dest, +- buf->len, level); ++ buf->len); + } else { + cow = btrfs_alloc_free_block(trans, root, buf->len, + parent_start, +@@ -314,8 +272,6 @@ + if (IS_ERR(cow)) + return PTR_ERR(cow); + +- /* cow is set to blocking by btrfs_init_new_buffer */ +- + copy_extent_buffer(cow, buf, 0, 0, cow->len); + btrfs_set_header_bytenr(cow, cow->start); + btrfs_set_header_generation(cow, trans->transid); +@@ -432,20 +388,17 @@ + WARN_ON(1); + } + ++ spin_lock(&root->fs_info->hash_lock); + if (btrfs_header_generation(buf) == trans->transid && + btrfs_header_owner(buf) == root->root_key.objectid && + !btrfs_header_flag(buf, BTRFS_HEADER_FLAG_WRITTEN)) { + *cow_ret = buf; ++ spin_unlock(&root->fs_info->hash_lock); + WARN_ON(prealloc_dest); + return 0; + } +- ++ spin_unlock(&root->fs_info->hash_lock); + search_start = buf->start & ~((u64)(1024 * 1024 * 1024) - 1); +- +- if (parent) +- btrfs_set_lock_blocking(parent); +- btrfs_set_lock_blocking(buf); +- + ret = __btrfs_cow_block(trans, root, buf, parent, + parent_slot, cow_ret, search_start, 0, + prealloc_dest); +@@ -551,8 +504,6 @@ + if (parent_nritems == 1) + return 0; + +- btrfs_set_lock_blocking(parent); +- + for (i = start_slot; i < end_slot; i++) { + int close = 1; + +@@ -613,7 +564,6 @@ + search_start = last_block; + + btrfs_tree_lock(cur); +- btrfs_set_lock_blocking(cur); + err = __btrfs_cow_block(trans, root, cur, parent, i, + &cur, search_start, + min(16 * blocksize, +@@ -912,7 +862,6 @@ + return 0; + + mid = path->nodes[level]; +- + WARN_ON(!path->locks[level]); + WARN_ON(btrfs_header_generation(mid) != trans->transid); + +@@ -934,9 +883,8 @@ + + /* promote the child to a root */ + child = read_node_slot(root, mid, 0); +- BUG_ON(!child); + btrfs_tree_lock(child); +- btrfs_set_lock_blocking(child); ++ BUG_ON(!child); + ret = btrfs_cow_block(trans, root, child, mid, 0, &child, 0); + BUG_ON(ret); + +@@ -952,7 +900,6 @@ + + add_root_to_dirty_list(root); + btrfs_tree_unlock(child); +- + path->locks[level] = 0; + path->nodes[level] = NULL; + clean_tree_block(trans, root, mid); +@@ -977,7 +924,6 @@ + left = read_node_slot(root, parent, pslot - 1); + if (left) { + btrfs_tree_lock(left); +- btrfs_set_lock_blocking(left); + wret = btrfs_cow_block(trans, root, left, + parent, pslot - 1, &left, 0); + if (wret) { +@@ -988,7 +934,6 @@ + right = read_node_slot(root, parent, pslot + 1); + if (right) { + btrfs_tree_lock(right); +- btrfs_set_lock_blocking(right); + wret = btrfs_cow_block(trans, root, right, + parent, pslot + 1, &right, 0); + if (wret) { +@@ -1164,8 +1109,6 @@ + u32 left_nr; + + btrfs_tree_lock(left); +- btrfs_set_lock_blocking(left); +- + left_nr = btrfs_header_nritems(left); + if (left_nr >= BTRFS_NODEPTRS_PER_BLOCK(root) - 1) { + wret = 1; +@@ -1212,10 +1155,7 @@ + */ + if (right) { + u32 right_nr; +- + btrfs_tree_lock(right); +- btrfs_set_lock_blocking(right); +- + right_nr = btrfs_header_nritems(right); + if (right_nr >= BTRFS_NODEPTRS_PER_BLOCK(root) - 1) { + wret = 1; +@@ -1270,7 +1210,8 @@ + struct btrfs_disk_key disk_key; + u32 nritems; + u64 search; +- u64 target; ++ u64 lowest_read; ++ u64 highest_read; + u64 nread = 0; + int direction = path->reada; + struct extent_buffer *eb; +@@ -1294,7 +1235,8 @@ + return; + } + +- target = search; ++ highest_read = search; ++ lowest_read = search; + + nritems = btrfs_header_nritems(node); + nr = slot; +@@ -1314,80 +1256,27 @@ + break; + } + search = btrfs_node_blockptr(node, nr); +- if ((search <= target && target - search <= 65536) || +- (search > target && search - target <= 65536)) { ++ if ((search >= lowest_read && search <= highest_read) || ++ (search < lowest_read && lowest_read - search <= 16384) || ++ (search > highest_read && search - highest_read <= 16384)) { + readahead_tree_block(root, search, blocksize, + btrfs_node_ptr_generation(node, nr)); + nread += blocksize; + } + nscan++; +- if ((nread > 65536 || nscan > 32)) ++ if (path->reada < 2 && (nread > (64 * 1024) || nscan > 32)) + break; +- } +-} +- +-/* +- * returns -EAGAIN if it had to drop the path, or zero if everything was in +- * cache +- */ +-static noinline int reada_for_balance(struct btrfs_root *root, +- struct btrfs_path *path, int level) +-{ +- int slot; +- int nritems; +- struct extent_buffer *parent; +- struct extent_buffer *eb; +- u64 gen; +- u64 block1 = 0; +- u64 block2 = 0; +- int ret = 0; +- int blocksize; + +- parent = path->nodes[level - 1]; +- if (!parent) +- return 0; +- +- nritems = btrfs_header_nritems(parent); +- slot = path->slots[level]; +- blocksize = btrfs_level_size(root, level); +- +- if (slot > 0) { +- block1 = btrfs_node_blockptr(parent, slot - 1); +- gen = btrfs_node_ptr_generation(parent, slot - 1); +- eb = btrfs_find_tree_block(root, block1, blocksize); +- if (eb && btrfs_buffer_uptodate(eb, gen)) +- block1 = 0; +- free_extent_buffer(eb); +- } +- if (slot < nritems) { +- block2 = btrfs_node_blockptr(parent, slot + 1); +- gen = btrfs_node_ptr_generation(parent, slot + 1); +- eb = btrfs_find_tree_block(root, block2, blocksize); +- if (eb && btrfs_buffer_uptodate(eb, gen)) +- block2 = 0; +- free_extent_buffer(eb); +- } +- if (block1 || block2) { +- ret = -EAGAIN; +- btrfs_release_path(root, path); +- if (block1) +- readahead_tree_block(root, block1, blocksize, 0); +- if (block2) +- readahead_tree_block(root, block2, blocksize, 0); ++ if (nread > (256 * 1024) || nscan > 128) ++ break; + +- if (block1) { +- eb = read_tree_block(root, block1, blocksize, 0); +- free_extent_buffer(eb); +- } +- if (block1) { +- eb = read_tree_block(root, block2, blocksize, 0); +- free_extent_buffer(eb); +- } ++ if (search < lowest_read) ++ lowest_read = search; ++ if (search > highest_read) ++ highest_read = search; + } +- return ret; + } + +- + /* + * when we walk down the tree, it is usually safe to unlock the higher layers + * in the tree. The exceptions are when our path goes through slot 0, because +@@ -1439,32 +1328,6 @@ + } + + /* +- * This releases any locks held in the path starting at level and +- * going all the way up to the root. +- * +- * btrfs_search_slot will keep the lock held on higher nodes in a few +- * corner cases, such as COW of the block at slot zero in the node. This +- * ignores those rules, and it should only be called when there are no +- * more updates to be done higher up in the tree. +- */ +-noinline void btrfs_unlock_up_safe(struct btrfs_path *path, int level) +-{ +- int i; +- +- if (path->keep_locks || path->lowest_level) +- return; +- +- for (i = level; i < BTRFS_MAX_LEVEL; i++) { +- if (!path->nodes[i]) +- continue; +- if (!path->locks[i]) +- continue; +- btrfs_tree_unlock(path->nodes[i]); +- path->locks[i] = 0; +- } +-} +- +-/* + * look for key in the tree. path is filled in with nodes along the way + * if key is found, we return zero and you can find the item in the leaf + * level of the path (level 0) +@@ -1524,30 +1387,32 @@ + int wret; + + /* is a cow on this block not required */ ++ spin_lock(&root->fs_info->hash_lock); + if (btrfs_header_generation(b) == trans->transid && + btrfs_header_owner(b) == root->root_key.objectid && + !btrfs_header_flag(b, BTRFS_HEADER_FLAG_WRITTEN)) { ++ spin_unlock(&root->fs_info->hash_lock); + goto cow_done; + } ++ spin_unlock(&root->fs_info->hash_lock); + + /* ok, we have to cow, is our old prealloc the right + * size? + */ + if (prealloc_block.objectid && + prealloc_block.offset != b->len) { +- btrfs_release_path(root, p); + btrfs_free_reserved_extent(root, + prealloc_block.objectid, + prealloc_block.offset); + prealloc_block.objectid = 0; +- goto again; + } + + /* + * for higher level blocks, try not to allocate blocks + * with the block and the parent locks held. + */ +- if (level > 0 && !prealloc_block.objectid) { ++ if (level > 1 && !prealloc_block.objectid && ++ btrfs_path_lock_waiting(p, level)) { + u32 size = b->len; + u64 hint = b->start; + +@@ -1560,8 +1425,6 @@ + goto again; + } + +- btrfs_set_path_blocking(p); +- + wret = btrfs_cow_block(trans, root, b, + p->nodes[level + 1], + p->slots[level + 1], +@@ -1583,22 +1446,6 @@ + if (!p->skip_locking) + p->locks[level] = 1; + +- btrfs_clear_path_blocking(p, NULL); +- +- /* +- * we have a lock on b and as long as we aren't changing +- * the tree, there is no way to for the items in b to change. +- * It is safe to drop the lock on our parent before we +- * go through the expensive btree search on b. +- * +- * If cow is true, then we might be changing slot zero, +- * which may require changing the parent. So, we can't +- * drop the lock until after we know which slot we're +- * operating on. +- */ +- if (!cow) +- btrfs_unlock_up_safe(p, level + 1); +- + ret = check_block(root, p, level); + if (ret) { + ret = -1; +@@ -1606,7 +1453,6 @@ + } + + ret = bin_search(b, key, level, &slot); +- + if (level != 0) { + if (ret && slot > 0) + slot -= 1; +@@ -1614,16 +1460,7 @@ + if ((p->search_for_split || ins_len > 0) && + btrfs_header_nritems(b) >= + BTRFS_NODEPTRS_PER_BLOCK(root) - 3) { +- int sret; +- +- sret = reada_for_balance(root, p, level); +- if (sret) +- goto again; +- +- btrfs_set_path_blocking(p); +- sret = split_node(trans, root, p, level); +- btrfs_clear_path_blocking(p, NULL); +- ++ int sret = split_node(trans, root, p, level); + BUG_ON(sret > 0); + if (sret) { + ret = sret; +@@ -1631,19 +1468,9 @@ + } + b = p->nodes[level]; + slot = p->slots[level]; +- } else if (ins_len < 0 && +- btrfs_header_nritems(b) < +- BTRFS_NODEPTRS_PER_BLOCK(root) / 4) { +- int sret; +- +- sret = reada_for_balance(root, p, level); +- if (sret) +- goto again; +- +- btrfs_set_path_blocking(p); +- sret = balance_level(trans, root, p, level); +- btrfs_clear_path_blocking(p, NULL); +- ++ } else if (ins_len < 0) { ++ int sret = balance_level(trans, root, p, ++ level); + if (sret) { + ret = sret; + goto done; +@@ -1677,7 +1504,7 @@ + * of the btree by dropping locks before + * we read. + */ +- if (level > 0) { ++ if (level > 1) { + btrfs_release_path(NULL, p); + if (tmp) + free_extent_buffer(tmp); +@@ -1692,7 +1519,6 @@ + free_extent_buffer(tmp); + goto again; + } else { +- btrfs_set_path_blocking(p); + if (tmp) + free_extent_buffer(tmp); + if (should_reada) +@@ -1702,29 +1528,14 @@ + b = read_node_slot(root, b, slot); + } + } +- if (!p->skip_locking) { +- int lret; +- +- btrfs_clear_path_blocking(p, NULL); +- lret = btrfs_try_spin_lock(b); +- +- if (!lret) { +- btrfs_set_path_blocking(p); +- btrfs_tree_lock(b); +- btrfs_clear_path_blocking(p, b); +- } +- } ++ if (!p->skip_locking) ++ btrfs_tree_lock(b); + } else { + p->slots[level] = slot; + if (ins_len > 0 && + btrfs_leaf_free_space(root, b) < ins_len) { +- int sret; +- +- btrfs_set_path_blocking(p); +- sret = split_leaf(trans, root, key, ++ int sret = split_leaf(trans, root, key, + p, ins_len, ret == 0); +- btrfs_clear_path_blocking(p, NULL); +- + BUG_ON(sret > 0); + if (sret) { + ret = sret; +@@ -1738,16 +1549,12 @@ + } + ret = 1; + done: +- /* +- * we don't really know what they plan on doing with the path +- * from here on, so for now just mark it as blocking +- */ +- btrfs_set_path_blocking(p); + if (prealloc_block.objectid) { + btrfs_free_reserved_extent(root, + prealloc_block.objectid, + prealloc_block.offset); + } ++ + return ret; + } + +@@ -1771,8 +1578,6 @@ + ret = btrfs_cow_block(trans, root, eb, NULL, 0, &eb, 0); + BUG_ON(ret); + +- btrfs_set_lock_blocking(eb); +- + parent = eb; + while (1) { + level = btrfs_header_level(parent); +@@ -1797,7 +1602,6 @@ + eb = read_tree_block(root, bytenr, blocksize, + generation); + btrfs_tree_lock(eb); +- btrfs_set_lock_blocking(eb); + } + + /* +@@ -1822,7 +1626,6 @@ + eb = read_tree_block(root, bytenr, blocksize, + generation); + btrfs_tree_lock(eb); +- btrfs_set_lock_blocking(eb); + } + + ret = btrfs_cow_block(trans, root, eb, parent, slot, +@@ -2365,12 +2168,10 @@ + if (slot >= btrfs_header_nritems(upper) - 1) + return 1; + +- btrfs_assert_tree_locked(path->nodes[1]); ++ WARN_ON(!btrfs_tree_locked(path->nodes[1])); + + right = read_node_slot(root, upper, slot + 1); + btrfs_tree_lock(right); +- btrfs_set_lock_blocking(right); +- + free_space = btrfs_leaf_free_space(root, right); + if (free_space < data_size) + goto out_unlock; +@@ -2562,12 +2363,10 @@ + if (right_nritems == 0) + return 1; + +- btrfs_assert_tree_locked(path->nodes[1]); ++ WARN_ON(!btrfs_tree_locked(path->nodes[1])); + + left = read_node_slot(root, path->nodes[1], slot - 1); + btrfs_tree_lock(left); +- btrfs_set_lock_blocking(left); +- + free_space = btrfs_leaf_free_space(root, left); + if (free_space < data_size) { + ret = 1; +@@ -3026,12 +2825,6 @@ + path->keep_locks = 0; + BUG_ON(ret); + +- /* +- * make sure any changes to the path from split_leaf leave it +- * in a blocking state +- */ +- btrfs_set_path_blocking(path); +- + leaf = path->nodes[0]; + BUG_ON(btrfs_leaf_free_space(root, leaf) < sizeof(struct btrfs_item)); + +@@ -3561,7 +3354,6 @@ + BUG(); + } + out: +- btrfs_unlock_up_safe(path, 1); + return ret; + } + +@@ -3649,22 +3441,15 @@ + { + int ret; + u64 root_gen = btrfs_header_generation(path->nodes[1]); +- u64 parent_start = path->nodes[1]->start; +- u64 parent_owner = btrfs_header_owner(path->nodes[1]); + + ret = del_ptr(trans, root, path, 1, path->slots[1]); + if (ret) + return ret; + +- /* +- * btrfs_free_extent is expensive, we want to make sure we +- * aren't holding any locks when we call it +- */ +- btrfs_unlock_up_safe(path, 0); +- + ret = btrfs_free_extent(trans, root, bytenr, + btrfs_level_size(root, 0), +- parent_start, parent_owner, ++ path->nodes[1]->start, ++ btrfs_header_owner(path->nodes[1]), + root_gen, 0, 1); + return ret; + } +@@ -3936,7 +3721,6 @@ + */ + if (slot >= nritems) { + path->slots[level] = slot; +- btrfs_set_path_blocking(path); + sret = btrfs_find_next_key(root, path, min_key, level, + cache_only, min_trans); + if (sret == 0) { +@@ -3954,20 +3738,16 @@ + unlock_up(path, level, 1); + goto out; + } +- btrfs_set_path_blocking(path); + cur = read_node_slot(root, cur, slot); + + btrfs_tree_lock(cur); +- + path->locks[level - 1] = 1; + path->nodes[level - 1] = cur; + unlock_up(path, level, 1); +- btrfs_clear_path_blocking(path, NULL); + } + out: + if (ret == 0) + memcpy(min_key, &found_key, sizeof(found_key)); +- btrfs_set_path_blocking(path); + return ret; + } + +@@ -4063,7 +3843,6 @@ + if (ret < 0) + return ret; + +- btrfs_set_path_blocking(path); + nritems = btrfs_header_nritems(path->nodes[0]); + /* + * by releasing the path above we dropped all our locks. A balance +@@ -4094,16 +3873,14 @@ + free_extent_buffer(next); + } + +- /* the path was set to blocking above */ + if (level == 1 && (path->locks[1] || path->skip_locking) && + path->reada) + reada_for_search(root, path, level, slot, 0); + + next = read_node_slot(root, c, slot); + if (!path->skip_locking) { +- btrfs_assert_tree_locked(c); ++ WARN_ON(!btrfs_tree_locked(c)); + btrfs_tree_lock(next); +- btrfs_set_lock_blocking(next); + } + break; + } +@@ -4120,15 +3897,12 @@ + path->locks[level] = 1; + if (!level) + break; +- +- btrfs_set_path_blocking(path); + if (level == 1 && path->locks[1] && path->reada) + reada_for_search(root, path, level, slot, 0); + next = read_node_slot(root, next, 0); + if (!path->skip_locking) { +- btrfs_assert_tree_locked(path->nodes[level]); ++ WARN_ON(!btrfs_tree_locked(path->nodes[level])); + btrfs_tree_lock(next); +- btrfs_set_lock_blocking(next); + } + } + done: +@@ -4153,7 +3927,6 @@ + + while (1) { + if (path->slots[0] == 0) { +- btrfs_set_path_blocking(path); + ret = btrfs_prev_leaf(root, path); + if (ret != 0) + return ret; +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/fs/btrfs/ctree.h linux-2.6.29-rc3.owrt/fs/btrfs/ctree.h +--- linux-2.6.29.owrt/fs/btrfs/ctree.h 2009-05-10 22:04:39.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/fs/btrfs/ctree.h 2009-05-10 23:48:29.000000000 +0200 +@@ -43,7 +43,11 @@ + + #define BTRFS_ACL_NOT_CACHED ((void *)-1) + +-#define BTRFS_MAX_LEVEL 8 ++#ifdef CONFIG_LOCKDEP ++# define BTRFS_MAX_LEVEL 7 ++#else ++# define BTRFS_MAX_LEVEL 8 ++#endif + + /* holds pointers to all of the tree roots */ + #define BTRFS_ROOT_TREE_OBJECTID 1ULL +@@ -450,11 +454,17 @@ + __le32 nsec; + } __attribute__ ((__packed__)); + +-enum btrfs_compression_type { ++typedef enum { + BTRFS_COMPRESS_NONE = 0, + BTRFS_COMPRESS_ZLIB = 1, + BTRFS_COMPRESS_LAST = 2, +-}; ++} btrfs_compression_type; ++ ++/* we don't understand any encryption methods right now */ ++typedef enum { ++ BTRFS_ENCRYPTION_NONE = 0, ++ BTRFS_ENCRYPTION_LAST = 1, ++} btrfs_encryption_type; + + struct btrfs_inode_item { + /* nfs style generation number */ +@@ -596,27 +606,13 @@ + + struct btrfs_space_info { + u64 flags; +- +- u64 total_bytes; /* total bytes in the space */ +- u64 bytes_used; /* total bytes used on disk */ +- u64 bytes_pinned; /* total bytes pinned, will be freed when the +- transaction finishes */ +- u64 bytes_reserved; /* total bytes the allocator has reserved for +- current allocations */ +- u64 bytes_readonly; /* total bytes that are read only */ +- +- /* delalloc accounting */ +- u64 bytes_delalloc; /* number of bytes reserved for allocation, +- this space is not necessarily reserved yet +- by the allocator */ +- u64 bytes_may_use; /* number of bytes that may be used for +- delalloc */ +- +- int full; /* indicates that we cannot allocate any more +- chunks for this space */ +- int force_alloc; /* set if we need to force a chunk alloc for +- this space */ +- ++ u64 total_bytes; ++ u64 bytes_used; ++ u64 bytes_pinned; ++ u64 bytes_reserved; ++ u64 bytes_readonly; ++ int full; ++ int force_alloc; + struct list_head list; + + /* for block groups in our same type */ +@@ -705,7 +701,9 @@ + struct btrfs_transaction *running_transaction; + wait_queue_head_t transaction_throttle; + wait_queue_head_t transaction_wait; ++ + wait_queue_head_t async_submit_wait; ++ wait_queue_head_t tree_log_wait; + + struct btrfs_super_block super_copy; + struct btrfs_super_block super_for_commit; +@@ -713,6 +711,7 @@ + struct super_block *sb; + struct inode *btree_inode; + struct backing_dev_info bdi; ++ spinlock_t hash_lock; + struct mutex trans_mutex; + struct mutex tree_log_mutex; + struct mutex transaction_kthread_mutex; +@@ -731,6 +730,10 @@ + atomic_t async_submit_draining; + atomic_t nr_async_bios; + atomic_t async_delalloc_pages; ++ atomic_t tree_log_writers; ++ atomic_t tree_log_commit; ++ unsigned long tree_log_batch; ++ u64 tree_log_transid; + + /* + * this is used by the balancing code to wait for all the pending +@@ -784,14 +787,7 @@ + struct list_head dirty_cowonly_roots; + + struct btrfs_fs_devices *fs_devices; +- +- /* +- * the space_info list is almost entirely read only. It only changes +- * when we add a new raid type to the FS, and that happens +- * very rarely. RCU is used to protect it. +- */ + struct list_head space_info; +- + spinlock_t delalloc_lock; + spinlock_t new_trans_lock; + u64 delalloc_bytes; +@@ -837,14 +833,7 @@ + struct kobject root_kobj; + struct completion kobj_unregister; + struct mutex objectid_mutex; +- + struct mutex log_mutex; +- wait_queue_head_t log_writer_wait; +- wait_queue_head_t log_commit_wait[2]; +- atomic_t log_writers; +- atomic_t log_commit[2]; +- unsigned long log_transid; +- unsigned long log_batch; + + u64 objectid; + u64 last_trans; +@@ -1732,8 +1721,7 @@ + u64 empty_size); + struct extent_buffer *btrfs_init_new_buffer(struct btrfs_trans_handle *trans, + struct btrfs_root *root, +- u64 bytenr, u32 blocksize, +- int level); ++ u64 bytenr, u32 blocksize); + int btrfs_alloc_extent(struct btrfs_trans_handle *trans, + struct btrfs_root *root, + u64 num_bytes, u64 parent, u64 min_bytes, +@@ -1803,18 +1791,6 @@ + int btrfs_cleanup_reloc_trees(struct btrfs_root *root); + int btrfs_reloc_clone_csums(struct inode *inode, u64 file_pos, u64 len); + u64 btrfs_reduce_alloc_profile(struct btrfs_root *root, u64 flags); +-void btrfs_set_inode_space_info(struct btrfs_root *root, struct inode *ionde); +-void btrfs_clear_space_info_full(struct btrfs_fs_info *info); +- +-int btrfs_check_metadata_free_space(struct btrfs_root *root); +-int btrfs_check_data_free_space(struct btrfs_root *root, struct inode *inode, +- u64 bytes); +-void btrfs_free_reserved_data_space(struct btrfs_root *root, +- struct inode *inode, u64 bytes); +-void btrfs_delalloc_reserve_space(struct btrfs_root *root, struct inode *inode, +- u64 bytes); +-void btrfs_delalloc_free_space(struct btrfs_root *root, struct inode *inode, +- u64 bytes); + /* ctree.c */ + int btrfs_previous_item(struct btrfs_root *root, + struct btrfs_path *path, u64 min_objectid, +@@ -1864,9 +1840,7 @@ + void btrfs_release_path(struct btrfs_root *root, struct btrfs_path *p); + struct btrfs_path *btrfs_alloc_path(void); + void btrfs_free_path(struct btrfs_path *p); +-void btrfs_set_path_blocking(struct btrfs_path *p); +-void btrfs_unlock_up_safe(struct btrfs_path *p, int level); +- ++void btrfs_init_path(struct btrfs_path *p); + int btrfs_del_items(struct btrfs_trans_handle *trans, struct btrfs_root *root, + struct btrfs_path *path, int slot, int nr); + int btrfs_del_leaf(struct btrfs_trans_handle *trans, +@@ -2060,6 +2034,8 @@ + unsigned long btrfs_force_ra(struct address_space *mapping, + struct file_ra_state *ra, struct file *file, + pgoff_t offset, pgoff_t last_index); ++int btrfs_check_free_space(struct btrfs_root *root, u64 num_required, ++ int for_del); + int btrfs_page_mkwrite(struct vm_area_struct *vma, struct page *page); + int btrfs_readpage(struct file *file, struct page *page); + void btrfs_delete_inode(struct inode *inode); +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/fs/btrfs/disk-io.c linux-2.6.29-rc3.owrt/fs/btrfs/disk-io.c +--- linux-2.6.29.owrt/fs/btrfs/disk-io.c 2009-05-10 22:04:39.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/fs/btrfs/disk-io.c 2009-05-10 23:48:29.000000000 +0200 +@@ -16,6 +16,7 @@ + * Boston, MA 021110-1307, USA. + */ + ++#include <linux/version.h> + #include <linux/fs.h> + #include <linux/blkdev.h> + #include <linux/scatterlist.h> +@@ -75,40 +76,6 @@ + struct btrfs_work work; + }; + +-/* These are used to set the lockdep class on the extent buffer locks. +- * The class is set by the readpage_end_io_hook after the buffer has +- * passed csum validation but before the pages are unlocked. +- * +- * The lockdep class is also set by btrfs_init_new_buffer on freshly +- * allocated blocks. +- * +- * The class is based on the level in the tree block, which allows lockdep +- * to know that lower nodes nest inside the locks of higher nodes. +- * +- * We also add a check to make sure the highest level of the tree is +- * the same as our lockdep setup here. If BTRFS_MAX_LEVEL changes, this +- * code needs update as well. +- */ +-#ifdef CONFIG_DEBUG_LOCK_ALLOC +-# if BTRFS_MAX_LEVEL != 8 +-# error +-# endif +-static struct lock_class_key btrfs_eb_class[BTRFS_MAX_LEVEL + 1]; +-static const char *btrfs_eb_name[BTRFS_MAX_LEVEL + 1] = { +- /* leaf */ +- "btrfs-extent-00", +- "btrfs-extent-01", +- "btrfs-extent-02", +- "btrfs-extent-03", +- "btrfs-extent-04", +- "btrfs-extent-05", +- "btrfs-extent-06", +- "btrfs-extent-07", +- /* highest possible level */ +- "btrfs-extent-08", +-}; +-#endif +- + /* + * extents on the btree inode are pretty simple, there's one extent + * that covers the entire device +@@ -381,15 +348,6 @@ + return ret; + } + +-#ifdef CONFIG_DEBUG_LOCK_ALLOC +-void btrfs_set_buffer_lockdep_class(struct extent_buffer *eb, int level) +-{ +- lockdep_set_class_and_name(&eb->lock, +- &btrfs_eb_class[level], +- btrfs_eb_name[level]); +-} +-#endif +- + static int btree_readpage_end_io_hook(struct page *page, u64 start, u64 end, + struct extent_state *state) + { +@@ -435,8 +393,6 @@ + } + found_level = btrfs_header_level(eb); + +- btrfs_set_buffer_lockdep_class(eb, found_level); +- + ret = csum_tree_block(root, eb, 1); + if (ret) + ret = -EIO; +@@ -844,7 +800,7 @@ + ret = btree_read_extent_buffer_pages(root, buf, 0, parent_transid); + + if (ret == 0) +- set_bit(EXTENT_BUFFER_UPTODATE, &buf->bflags); ++ buf->flags |= EXTENT_UPTODATE; + else + WARN_ON(1); + return buf; +@@ -857,11 +813,7 @@ + struct inode *btree_inode = root->fs_info->btree_inode; + if (btrfs_header_generation(buf) == + root->fs_info->running_transaction->transid) { +- btrfs_assert_tree_locked(buf); +- +- /* ugh, clear_extent_buffer_dirty can be expensive */ +- btrfs_set_lock_blocking(buf); +- ++ WARN_ON(!btrfs_tree_locked(buf)); + clear_extent_buffer_dirty(&BTRFS_I(btree_inode)->io_tree, + buf); + } +@@ -898,14 +850,6 @@ + spin_lock_init(&root->list_lock); + mutex_init(&root->objectid_mutex); + mutex_init(&root->log_mutex); +- init_waitqueue_head(&root->log_writer_wait); +- init_waitqueue_head(&root->log_commit_wait[0]); +- init_waitqueue_head(&root->log_commit_wait[1]); +- atomic_set(&root->log_commit[0], 0); +- atomic_set(&root->log_commit[1], 0); +- atomic_set(&root->log_writers, 0); +- root->log_batch = 0; +- root->log_transid = 0; + extent_io_tree_init(&root->dirty_log_pages, + fs_info->btree_inode->i_mapping, GFP_NOFS); + +@@ -990,16 +934,15 @@ + return 0; + } + +-static struct btrfs_root *alloc_log_tree(struct btrfs_trans_handle *trans, +- struct btrfs_fs_info *fs_info) ++int btrfs_init_log_root_tree(struct btrfs_trans_handle *trans, ++ struct btrfs_fs_info *fs_info) + { + struct btrfs_root *root; + struct btrfs_root *tree_root = fs_info->tree_root; +- struct extent_buffer *leaf; + + root = kzalloc(sizeof(*root), GFP_NOFS); + if (!root) +- return ERR_PTR(-ENOMEM); ++ return -ENOMEM; + + __setup_root(tree_root->nodesize, tree_root->leafsize, + tree_root->sectorsize, tree_root->stripesize, +@@ -1008,23 +951,12 @@ + root->root_key.objectid = BTRFS_TREE_LOG_OBJECTID; + root->root_key.type = BTRFS_ROOT_ITEM_KEY; + root->root_key.offset = BTRFS_TREE_LOG_OBJECTID; +- /* +- * log trees do not get reference counted because they go away +- * before a real commit is actually done. They do store pointers +- * to file data extents, and those reference counts still get +- * updated (along with back refs to the log tree). +- */ + root->ref_cows = 0; + +- leaf = btrfs_alloc_free_block(trans, root, root->leafsize, +- 0, BTRFS_TREE_LOG_OBJECTID, +- trans->transid, 0, 0, 0); +- if (IS_ERR(leaf)) { +- kfree(root); +- return ERR_CAST(leaf); +- } ++ root->node = btrfs_alloc_free_block(trans, root, root->leafsize, ++ 0, BTRFS_TREE_LOG_OBJECTID, ++ trans->transid, 0, 0, 0); + +- root->node = leaf; + btrfs_set_header_nritems(root->node, 0); + btrfs_set_header_level(root->node, 0); + btrfs_set_header_bytenr(root->node, root->node->start); +@@ -1036,48 +968,7 @@ + BTRFS_FSID_SIZE); + btrfs_mark_buffer_dirty(root->node); + btrfs_tree_unlock(root->node); +- return root; +-} +- +-int btrfs_init_log_root_tree(struct btrfs_trans_handle *trans, +- struct btrfs_fs_info *fs_info) +-{ +- struct btrfs_root *log_root; +- +- log_root = alloc_log_tree(trans, fs_info); +- if (IS_ERR(log_root)) +- return PTR_ERR(log_root); +- WARN_ON(fs_info->log_root_tree); +- fs_info->log_root_tree = log_root; +- return 0; +-} +- +-int btrfs_add_log_tree(struct btrfs_trans_handle *trans, +- struct btrfs_root *root) +-{ +- struct btrfs_root *log_root; +- struct btrfs_inode_item *inode_item; +- +- log_root = alloc_log_tree(trans, root->fs_info); +- if (IS_ERR(log_root)) +- return PTR_ERR(log_root); +- +- log_root->last_trans = trans->transid; +- log_root->root_key.offset = root->root_key.objectid; +- +- inode_item = &log_root->root_item.inode; +- inode_item->generation = cpu_to_le64(1); +- inode_item->size = cpu_to_le64(3); +- inode_item->nlink = cpu_to_le32(1); +- inode_item->nbytes = cpu_to_le64(root->leafsize); +- inode_item->mode = cpu_to_le32(S_IFDIR | 0755); +- +- btrfs_set_root_bytenr(&log_root->root_item, log_root->node->start); +- btrfs_set_root_generation(&log_root->root_item, trans->transid); +- +- WARN_ON(root->log_root); +- root->log_root = log_root; +- root->log_transid = 0; ++ fs_info->log_root_tree = root; + return 0; + } + +@@ -1245,6 +1136,7 @@ + { + struct btrfs_fs_info *info = (struct btrfs_fs_info *)congested_data; + int ret = 0; ++ struct list_head *cur; + struct btrfs_device *device; + struct backing_dev_info *bdi; + #if 0 +@@ -1252,7 +1144,8 @@ + btrfs_congested_async(info, 0)) + return 1; + #endif +- list_for_each_entry(device, &info->fs_devices->devices, dev_list) { ++ list_for_each(cur, &info->fs_devices->devices) { ++ device = list_entry(cur, struct btrfs_device, dev_list); + if (!device->bdev) + continue; + bdi = blk_get_backing_dev_info(device->bdev); +@@ -1270,11 +1163,13 @@ + */ + static void __unplug_io_fn(struct backing_dev_info *bdi, struct page *page) + { ++ struct list_head *cur; + struct btrfs_device *device; + struct btrfs_fs_info *info; + + info = (struct btrfs_fs_info *)bdi->unplug_io_data; +- list_for_each_entry(device, &info->fs_devices->devices, dev_list) { ++ list_for_each(cur, &info->fs_devices->devices) { ++ device = list_entry(cur, struct btrfs_device, dev_list); + if (!device->bdev) + continue; + +@@ -1552,6 +1447,7 @@ + INIT_LIST_HEAD(&fs_info->dead_roots); + INIT_LIST_HEAD(&fs_info->hashers); + INIT_LIST_HEAD(&fs_info->delalloc_inodes); ++ spin_lock_init(&fs_info->hash_lock); + spin_lock_init(&fs_info->delalloc_lock); + spin_lock_init(&fs_info->new_trans_lock); + spin_lock_init(&fs_info->ref_cache_lock); +@@ -1639,6 +1535,10 @@ + init_waitqueue_head(&fs_info->transaction_throttle); + init_waitqueue_head(&fs_info->transaction_wait); + init_waitqueue_head(&fs_info->async_submit_wait); ++ init_waitqueue_head(&fs_info->tree_log_wait); ++ atomic_set(&fs_info->tree_log_commit, 0); ++ atomic_set(&fs_info->tree_log_writers, 0); ++ fs_info->tree_log_transid = 0; + + __setup_root(4096, 4096, 4096, 4096, tree_root, + fs_info, BTRFS_ROOT_TREE_OBJECTID); +@@ -1727,8 +1627,6 @@ + * low idle thresh + */ + fs_info->endio_workers.idle_thresh = 4; +- fs_info->endio_meta_workers.idle_thresh = 4; +- + fs_info->endio_write_workers.idle_thresh = 64; + fs_info->endio_meta_write_workers.idle_thresh = 64; + +@@ -1822,6 +1720,7 @@ + ret = find_and_setup_root(tree_root, fs_info, + BTRFS_DEV_TREE_OBJECTID, dev_root); + dev_root->track_dirty = 1; ++ + if (ret) + goto fail_extent_root; + +@@ -1841,13 +1740,13 @@ + fs_info->system_alloc_profile = fs_info->metadata_alloc_profile; + fs_info->cleaner_kthread = kthread_run(cleaner_kthread, tree_root, + "btrfs-cleaner"); +- if (IS_ERR(fs_info->cleaner_kthread)) ++ if (!fs_info->cleaner_kthread) + goto fail_csum_root; + + fs_info->transaction_kthread = kthread_run(transaction_kthread, + tree_root, + "btrfs-transaction"); +- if (IS_ERR(fs_info->transaction_kthread)) ++ if (!fs_info->transaction_kthread) + goto fail_cleaner; + + if (btrfs_super_log_root(disk_super) != 0) { +@@ -1929,14 +1828,13 @@ + fail_iput: + invalidate_inode_pages2(fs_info->btree_inode->i_mapping); + iput(fs_info->btree_inode); +- ++fail: + btrfs_close_devices(fs_info->fs_devices); + btrfs_mapping_tree_free(&fs_info->mapping_tree); +- bdi_destroy(&fs_info->bdi); + +-fail: + kfree(extent_root); + kfree(tree_root); ++ bdi_destroy(&fs_info->bdi); + kfree(fs_info); + kfree(chunk_root); + kfree(dev_root); +@@ -2097,6 +1995,7 @@ + + int write_all_supers(struct btrfs_root *root, int max_mirrors) + { ++ struct list_head *cur; + struct list_head *head = &root->fs_info->fs_devices->devices; + struct btrfs_device *dev; + struct btrfs_super_block *sb; +@@ -2112,7 +2011,8 @@ + + sb = &root->fs_info->super_for_commit; + dev_item = &sb->dev_item; +- list_for_each_entry(dev, head, dev_list) { ++ list_for_each(cur, head) { ++ dev = list_entry(cur, struct btrfs_device, dev_list); + if (!dev->bdev) { + total_errors++; + continue; +@@ -2145,7 +2045,8 @@ + } + + total_errors = 0; +- list_for_each_entry(dev, head, dev_list) { ++ list_for_each(cur, head) { ++ dev = list_entry(cur, struct btrfs_device, dev_list); + if (!dev->bdev) + continue; + if (!dev->in_fs_metadata || !dev->writeable) +@@ -2359,9 +2260,7 @@ + u64 transid = btrfs_header_generation(buf); + struct inode *btree_inode = root->fs_info->btree_inode; + +- btrfs_set_lock_blocking(buf); +- +- btrfs_assert_tree_locked(buf); ++ WARN_ON(!btrfs_tree_locked(buf)); + if (transid != root->fs_info->generation) { + printk(KERN_CRIT "btrfs transid mismatch buffer %llu, " + "found %llu running %llu\n", +@@ -2403,13 +2302,14 @@ + int ret; + ret = btree_read_extent_buffer_pages(root, buf, 0, parent_transid); + if (ret == 0) +- set_bit(EXTENT_BUFFER_UPTODATE, &buf->bflags); ++ buf->flags |= EXTENT_UPTODATE; + return ret; + } + + int btree_lock_page_hook(struct page *page) + { + struct inode *inode = page->mapping->host; ++ struct btrfs_root *root = BTRFS_I(inode)->root; + struct extent_io_tree *io_tree = &BTRFS_I(inode)->io_tree; + struct extent_buffer *eb; + unsigned long len; +@@ -2424,7 +2324,9 @@ + goto out; + + btrfs_tree_lock(eb); ++ spin_lock(&root->fs_info->hash_lock); + btrfs_set_header_flag(eb, BTRFS_HEADER_FLAG_WRITTEN); ++ spin_unlock(&root->fs_info->hash_lock); + btrfs_tree_unlock(eb); + free_extent_buffer(eb); + out: +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/fs/btrfs/disk-io.h linux-2.6.29-rc3.owrt/fs/btrfs/disk-io.h +--- linux-2.6.29.owrt/fs/btrfs/disk-io.h 2009-05-10 22:04:39.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/fs/btrfs/disk-io.h 2009-05-10 23:48:29.000000000 +0200 +@@ -98,17 +98,5 @@ + struct btrfs_fs_info *fs_info); + int btrfs_init_log_root_tree(struct btrfs_trans_handle *trans, + struct btrfs_fs_info *fs_info); +-int btrfs_add_log_tree(struct btrfs_trans_handle *trans, +- struct btrfs_root *root); + int btree_lock_page_hook(struct page *page); +- +- +-#ifdef CONFIG_DEBUG_LOCK_ALLOC +-void btrfs_set_buffer_lockdep_class(struct extent_buffer *eb, int level); +-#else +-static inline void btrfs_set_buffer_lockdep_class(struct extent_buffer *eb, +- int level) +-{ +-} +-#endif + #endif +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/fs/btrfs/extent_io.c linux-2.6.29-rc3.owrt/fs/btrfs/extent_io.c +--- linux-2.6.29.owrt/fs/btrfs/extent_io.c 2009-05-10 22:04:39.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/fs/btrfs/extent_io.c 2009-05-10 23:48:29.000000000 +0200 +@@ -9,6 +9,7 @@ + #include <linux/spinlock.h> + #include <linux/blkdev.h> + #include <linux/swap.h> ++#include <linux/version.h> + #include <linux/writeback.h> + #include <linux/pagevec.h> + #include "extent_io.h" +@@ -30,7 +31,7 @@ + static LIST_HEAD(states); + + #define LEAK_DEBUG 0 +-#if LEAK_DEBUG ++#ifdef LEAK_DEBUG + static DEFINE_SPINLOCK(leak_lock); + #endif + +@@ -119,7 +120,7 @@ + static struct extent_state *alloc_extent_state(gfp_t mask) + { + struct extent_state *state; +-#if LEAK_DEBUG ++#ifdef LEAK_DEBUG + unsigned long flags; + #endif + +@@ -129,7 +130,7 @@ + state->state = 0; + state->private = 0; + state->tree = NULL; +-#if LEAK_DEBUG ++#ifdef LEAK_DEBUG + spin_lock_irqsave(&leak_lock, flags); + list_add(&state->leak_list, &states); + spin_unlock_irqrestore(&leak_lock, flags); +@@ -144,11 +145,11 @@ + if (!state) + return; + if (atomic_dec_and_test(&state->refs)) { +-#if LEAK_DEBUG ++#ifdef LEAK_DEBUG + unsigned long flags; + #endif + WARN_ON(state->tree); +-#if LEAK_DEBUG ++#ifdef LEAK_DEBUG + spin_lock_irqsave(&leak_lock, flags); + list_del(&state->leak_list); + spin_unlock_irqrestore(&leak_lock, flags); +@@ -415,6 +416,8 @@ + + node = tree_insert(&tree->state, prealloc->end, &prealloc->rb_node); + if (node) { ++ struct extent_state *found; ++ found = rb_entry(node, struct extent_state, rb_node); + free_extent_state(prealloc); + return -EEXIST; + } +@@ -2375,6 +2378,11 @@ + int scanned = 0; + int range_whole = 0; + ++ if (wbc->nonblocking && bdi_write_congested(bdi)) { ++ wbc->encountered_congestion = 1; ++ return 0; ++ } ++ + pagevec_init(&pvec, 0); + if (wbc->range_cyclic) { + index = mapping->writeback_index; /* Start from prev offset */ +@@ -2847,98 +2855,6 @@ + return sector; + } + +-int extent_fiemap(struct inode *inode, struct fiemap_extent_info *fieinfo, +- __u64 start, __u64 len, get_extent_t *get_extent) +-{ +- int ret; +- u64 off = start; +- u64 max = start + len; +- u32 flags = 0; +- u64 disko = 0; +- struct extent_map *em = NULL; +- int end = 0; +- u64 em_start = 0, em_len = 0; +- unsigned long emflags; +- ret = 0; +- +- if (len == 0) +- return -EINVAL; +- +- lock_extent(&BTRFS_I(inode)->io_tree, start, start + len, +- GFP_NOFS); +- em = get_extent(inode, NULL, 0, off, max - off, 0); +- if (!em) +- goto out; +- if (IS_ERR(em)) { +- ret = PTR_ERR(em); +- goto out; +- } +- while (!end) { +- off = em->start + em->len; +- if (off >= max) +- end = 1; +- +- em_start = em->start; +- em_len = em->len; +- +- disko = 0; +- flags = 0; +- +- switch (em->block_start) { +- case EXTENT_MAP_LAST_BYTE: +- end = 1; +- flags |= FIEMAP_EXTENT_LAST; +- break; +- case EXTENT_MAP_HOLE: +- flags |= FIEMAP_EXTENT_UNWRITTEN; +- break; +- case EXTENT_MAP_INLINE: +- flags |= (FIEMAP_EXTENT_DATA_INLINE | +- FIEMAP_EXTENT_NOT_ALIGNED); +- break; +- case EXTENT_MAP_DELALLOC: +- flags |= (FIEMAP_EXTENT_DELALLOC | +- FIEMAP_EXTENT_UNKNOWN); +- break; +- default: +- disko = em->block_start; +- break; +- } +- if (test_bit(EXTENT_FLAG_COMPRESSED, &em->flags)) +- flags |= FIEMAP_EXTENT_ENCODED; +- +- emflags = em->flags; +- free_extent_map(em); +- em = NULL; +- +- if (!end) { +- em = get_extent(inode, NULL, 0, off, max - off, 0); +- if (!em) +- goto out; +- if (IS_ERR(em)) { +- ret = PTR_ERR(em); +- goto out; +- } +- emflags = em->flags; +- } +- if (test_bit(EXTENT_FLAG_VACANCY, &emflags)) { +- flags |= FIEMAP_EXTENT_LAST; +- end = 1; +- } +- +- ret = fiemap_fill_next_extent(fieinfo, em_start, disko, +- em_len, flags); +- if (ret) +- goto out_free; +- } +-out_free: +- free_extent_map(em); +-out: +- unlock_extent(&BTRFS_I(inode)->io_tree, start, start + len, +- GFP_NOFS); +- return ret; +-} +- + static inline struct page *extent_buffer_page(struct extent_buffer *eb, + unsigned long i) + { +@@ -2976,17 +2892,15 @@ + gfp_t mask) + { + struct extent_buffer *eb = NULL; +-#if LEAK_DEBUG ++#ifdef LEAK_DEBUG + unsigned long flags; + #endif + + eb = kmem_cache_zalloc(extent_buffer_cache, mask); + eb->start = start; + eb->len = len; +- spin_lock_init(&eb->lock); +- init_waitqueue_head(&eb->lock_wq); +- +-#if LEAK_DEBUG ++ mutex_init(&eb->mutex); ++#ifdef LEAK_DEBUG + spin_lock_irqsave(&leak_lock, flags); + list_add(&eb->leak_list, &buffers); + spin_unlock_irqrestore(&leak_lock, flags); +@@ -2998,7 +2912,7 @@ + + static void __free_extent_buffer(struct extent_buffer *eb) + { +-#if LEAK_DEBUG ++#ifdef LEAK_DEBUG + unsigned long flags; + spin_lock_irqsave(&leak_lock, flags); + list_del(&eb->leak_list); +@@ -3066,7 +2980,8 @@ + unlock_page(p); + } + if (uptodate) +- set_bit(EXTENT_BUFFER_UPTODATE, &eb->bflags); ++ eb->flags |= EXTENT_UPTODATE; ++ eb->flags |= EXTENT_BUFFER_FILLED; + + spin_lock(&tree->buffer_lock); + exists = buffer_tree_insert(tree, start, &eb->rb_node); +@@ -3220,7 +3135,7 @@ + unsigned long num_pages; + + num_pages = num_extent_pages(eb->start, eb->len); +- clear_bit(EXTENT_BUFFER_UPTODATE, &eb->bflags); ++ eb->flags &= ~EXTENT_UPTODATE; + + clear_extent_uptodate(tree, eb->start, eb->start + eb->len - 1, + GFP_NOFS); +@@ -3291,7 +3206,7 @@ + struct page *page; + int pg_uptodate = 1; + +- if (test_bit(EXTENT_BUFFER_UPTODATE, &eb->bflags)) ++ if (eb->flags & EXTENT_UPTODATE) + return 1; + + ret = test_range_bit(tree, eb->start, eb->start + eb->len - 1, +@@ -3327,7 +3242,7 @@ + struct bio *bio = NULL; + unsigned long bio_flags = 0; + +- if (test_bit(EXTENT_BUFFER_UPTODATE, &eb->bflags)) ++ if (eb->flags & EXTENT_UPTODATE) + return 0; + + if (test_range_bit(tree, eb->start, eb->start + eb->len - 1, +@@ -3358,7 +3273,7 @@ + } + if (all_uptodate) { + if (start_i == 0) +- set_bit(EXTENT_BUFFER_UPTODATE, &eb->bflags); ++ eb->flags |= EXTENT_UPTODATE; + goto unlock_exit; + } + +@@ -3394,7 +3309,7 @@ + } + + if (!ret) +- set_bit(EXTENT_BUFFER_UPTODATE, &eb->bflags); ++ eb->flags |= EXTENT_UPTODATE; + return ret; + + unlock_exit: +@@ -3491,6 +3406,7 @@ + unmap_extent_buffer(eb, eb->map_token, km); + eb->map_token = NULL; + save = 1; ++ WARN_ON(!mutex_is_locked(&eb->mutex)); + } + err = map_private_extent_buffer(eb, start, min_len, token, map, + map_start, map_len, km); +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/fs/btrfs/extent_io.h linux-2.6.29-rc3.owrt/fs/btrfs/extent_io.h +--- linux-2.6.29.owrt/fs/btrfs/extent_io.h 2009-05-10 22:04:39.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/fs/btrfs/extent_io.h 2009-05-10 23:48:29.000000000 +0200 +@@ -22,10 +22,6 @@ + /* flags for bio submission */ + #define EXTENT_BIO_COMPRESSED 1 + +-/* these are bit numbers for test/set bit */ +-#define EXTENT_BUFFER_UPTODATE 0 +-#define EXTENT_BUFFER_BLOCKING 1 +- + /* + * page->private values. Every page that is controlled by the extent + * map has page->private set to one. +@@ -99,19 +95,11 @@ + unsigned long map_start; + unsigned long map_len; + struct page *first_page; +- unsigned long bflags; + atomic_t refs; ++ int flags; + struct list_head leak_list; + struct rb_node rb_node; +- +- /* the spinlock is used to protect most operations */ +- spinlock_t lock; +- +- /* +- * when we keep the lock held while blocking, waiters go onto +- * the wq +- */ +- wait_queue_head_t lock_wq; ++ struct mutex mutex; + }; + + struct extent_map_tree; +@@ -205,8 +193,6 @@ + unsigned from, unsigned to); + sector_t extent_bmap(struct address_space *mapping, sector_t iblock, + get_extent_t *get_extent); +-int extent_fiemap(struct inode *inode, struct fiemap_extent_info *fieinfo, +- __u64 start, __u64 len, get_extent_t *get_extent); + int set_range_dirty(struct extent_io_tree *tree, u64 start, u64 end); + int set_state_private(struct extent_io_tree *tree, u64 start, u64 private); + int get_state_private(struct extent_io_tree *tree, u64 start, u64 *private); +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/fs/btrfs/extent_map.c linux-2.6.29-rc3.owrt/fs/btrfs/extent_map.c +--- linux-2.6.29.owrt/fs/btrfs/extent_map.c 2009-05-10 22:04:39.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/fs/btrfs/extent_map.c 2009-05-10 23:48:29.000000000 +0200 +@@ -3,6 +3,7 @@ + #include <linux/slab.h> + #include <linux/module.h> + #include <linux/spinlock.h> ++#include <linux/version.h> + #include <linux/hardirq.h> + #include "extent_map.h" + +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/fs/btrfs/extent-tree.c linux-2.6.29-rc3.owrt/fs/btrfs/extent-tree.c +--- linux-2.6.29.owrt/fs/btrfs/extent-tree.c 2009-05-10 22:04:39.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/fs/btrfs/extent-tree.c 2009-05-10 23:48:29.000000000 +0200 +@@ -19,8 +19,7 @@ + #include <linux/pagemap.h> + #include <linux/writeback.h> + #include <linux/blkdev.h> +-#include <linux/sort.h> +-#include <linux/rcupdate.h> ++#include <linux/version.h> + #include "compat.h" + #include "hash.h" + #include "crc32c.h" +@@ -31,6 +30,7 @@ + #include "volumes.h" + #include "locking.h" + #include "ref-cache.h" ++#include "compat.h" + + #define PENDING_EXTENT_INSERT 0 + #define PENDING_EXTENT_DELETE 1 +@@ -61,10 +61,6 @@ + u64 bytenr, u64 num_bytes, int alloc, + int mark_free); + +-static int do_chunk_alloc(struct btrfs_trans_handle *trans, +- struct btrfs_root *extent_root, u64 alloc_bytes, +- u64 flags, int force); +- + static int block_group_bits(struct btrfs_block_group_cache *cache, u64 bits) + { + return (cache->flags & bits) == bits; +@@ -330,34 +326,16 @@ + u64 flags) + { + struct list_head *head = &info->space_info; ++ struct list_head *cur; + struct btrfs_space_info *found; +- +- rcu_read_lock(); +- list_for_each_entry_rcu(found, head, list) { +- if (found->flags == flags) { +- rcu_read_unlock(); ++ list_for_each(cur, head) { ++ found = list_entry(cur, struct btrfs_space_info, list); ++ if (found->flags == flags) + return found; +- } + } +- rcu_read_unlock(); + return NULL; + } + +-/* +- * after adding space to the filesystem, we need to clear the full flags +- * on all the space infos. +- */ +-void btrfs_clear_space_info_full(struct btrfs_fs_info *info) +-{ +- struct list_head *head = &info->space_info; +- struct btrfs_space_info *found; +- +- rcu_read_lock(); +- list_for_each_entry_rcu(found, head, list) +- found->full = 0; +- rcu_read_unlock(); +-} +- + static u64 div_factor(u64 num, int factor) + { + if (factor == 10) +@@ -1348,25 +1326,8 @@ + int btrfs_extent_post_op(struct btrfs_trans_handle *trans, + struct btrfs_root *root) + { +- u64 start; +- u64 end; +- int ret; +- +- while(1) { +- finish_current_insert(trans, root->fs_info->extent_root, 1); +- del_pending_extents(trans, root->fs_info->extent_root, 1); +- +- /* is there more work to do? */ +- ret = find_first_extent_bit(&root->fs_info->pending_del, +- 0, &start, &end, EXTENT_WRITEBACK); +- if (!ret) +- continue; +- ret = find_first_extent_bit(&root->fs_info->extent_ins, +- 0, &start, &end, EXTENT_WRITEBACK); +- if (!ret) +- continue; +- break; +- } ++ finish_current_insert(trans, root->fs_info->extent_root, 1); ++ del_pending_extents(trans, root->fs_info->extent_root, 1); + return 0; + } + +@@ -1564,55 +1525,15 @@ + return ret; + } + +-/* when a block goes through cow, we update the reference counts of +- * everything that block points to. The internal pointers of the block +- * can be in just about any order, and it is likely to have clusters of +- * things that are close together and clusters of things that are not. +- * +- * To help reduce the seeks that come with updating all of these reference +- * counts, sort them by byte number before actual updates are done. +- * +- * struct refsort is used to match byte number to slot in the btree block. +- * we sort based on the byte number and then use the slot to actually +- * find the item. +- * +- * struct refsort is smaller than strcut btrfs_item and smaller than +- * struct btrfs_key_ptr. Since we're currently limited to the page size +- * for a btree block, there's no way for a kmalloc of refsorts for a +- * single node to be bigger than a page. +- */ +-struct refsort { +- u64 bytenr; +- u32 slot; +-}; +- +-/* +- * for passing into sort() +- */ +-static int refsort_cmp(const void *a_void, const void *b_void) +-{ +- const struct refsort *a = a_void; +- const struct refsort *b = b_void; +- +- if (a->bytenr < b->bytenr) +- return -1; +- if (a->bytenr > b->bytenr) +- return 1; +- return 0; +-} +- +- +-noinline int btrfs_inc_ref(struct btrfs_trans_handle *trans, +- struct btrfs_root *root, +- struct extent_buffer *orig_buf, +- struct extent_buffer *buf, u32 *nr_extents) ++int btrfs_inc_ref(struct btrfs_trans_handle *trans, struct btrfs_root *root, ++ struct extent_buffer *orig_buf, struct extent_buffer *buf, ++ u32 *nr_extents) + { + u64 bytenr; + u64 ref_root; + u64 orig_root; + u64 ref_generation; + u64 orig_generation; +- struct refsort *sorted; + u32 nritems; + u32 nr_file_extents = 0; + struct btrfs_key key; +@@ -1621,8 +1542,6 @@ + int level; + int ret = 0; + int faili = 0; +- int refi = 0; +- int slot; + int (*process_func)(struct btrfs_trans_handle *, struct btrfs_root *, + u64, u64, u64, u64, u64, u64, u64, u64); + +@@ -1634,9 +1553,6 @@ + nritems = btrfs_header_nritems(buf); + level = btrfs_header_level(buf); + +- sorted = kmalloc(sizeof(struct refsort) * nritems, GFP_NOFS); +- BUG_ON(!sorted); +- + if (root->ref_cows) { + process_func = __btrfs_inc_extent_ref; + } else { +@@ -1649,11 +1565,6 @@ + process_func = __btrfs_update_extent_ref; + } + +- /* +- * we make two passes through the items. In the first pass we +- * only record the byte number and slot. Then we sort based on +- * byte number and do the actual work based on the sorted results +- */ + for (i = 0; i < nritems; i++) { + cond_resched(); + if (level == 0) { +@@ -1670,32 +1581,6 @@ + continue; + + nr_file_extents++; +- sorted[refi].bytenr = bytenr; +- sorted[refi].slot = i; +- refi++; +- } else { +- bytenr = btrfs_node_blockptr(buf, i); +- sorted[refi].bytenr = bytenr; +- sorted[refi].slot = i; +- refi++; +- } +- } +- /* +- * if refi == 0, we didn't actually put anything into the sorted +- * array and we're done +- */ +- if (refi == 0) +- goto out; +- +- sort(sorted, refi, sizeof(struct refsort), refsort_cmp, NULL); +- +- for (i = 0; i < refi; i++) { +- cond_resched(); +- slot = sorted[i].slot; +- bytenr = sorted[i].bytenr; +- +- if (level == 0) { +- btrfs_item_key_to_cpu(buf, &key, slot); + + ret = process_func(trans, root, bytenr, + orig_buf->start, buf->start, +@@ -1704,25 +1589,25 @@ + key.objectid); + + if (ret) { +- faili = slot; ++ faili = i; + WARN_ON(1); + goto fail; + } + } else { ++ bytenr = btrfs_node_blockptr(buf, i); + ret = process_func(trans, root, bytenr, + orig_buf->start, buf->start, + orig_root, ref_root, + orig_generation, ref_generation, + level - 1); + if (ret) { +- faili = slot; ++ faili = i; + WARN_ON(1); + goto fail; + } + } + } + out: +- kfree(sorted); + if (nr_extents) { + if (level == 0) + *nr_extents = nr_file_extents; +@@ -1731,7 +1616,6 @@ + } + return 0; + fail: +- kfree(sorted); + WARN_ON(1); + return ret; + } +@@ -1924,6 +1808,7 @@ + if (!found) + return -ENOMEM; + ++ list_add(&found->list, &info->space_info); + INIT_LIST_HEAD(&found->block_groups); + init_rwsem(&found->groups_sem); + spin_lock_init(&found->lock); +@@ -1933,11 +1818,9 @@ + found->bytes_pinned = 0; + found->bytes_reserved = 0; + found->bytes_readonly = 0; +- found->bytes_delalloc = 0; + found->full = 0; + found->force_alloc = 0; + *space_info = found; +- list_add_rcu(&found->list, &info->space_info); + return 0; + } + +@@ -1998,233 +1881,6 @@ + return flags; + } + +-static u64 btrfs_get_alloc_profile(struct btrfs_root *root, u64 data) +-{ +- struct btrfs_fs_info *info = root->fs_info; +- u64 alloc_profile; +- +- if (data) { +- alloc_profile = info->avail_data_alloc_bits & +- info->data_alloc_profile; +- data = BTRFS_BLOCK_GROUP_DATA | alloc_profile; +- } else if (root == root->fs_info->chunk_root) { +- alloc_profile = info->avail_system_alloc_bits & +- info->system_alloc_profile; +- data = BTRFS_BLOCK_GROUP_SYSTEM | alloc_profile; +- } else { +- alloc_profile = info->avail_metadata_alloc_bits & +- info->metadata_alloc_profile; +- data = BTRFS_BLOCK_GROUP_METADATA | alloc_profile; +- } +- +- return btrfs_reduce_alloc_profile(root, data); +-} +- +-void btrfs_set_inode_space_info(struct btrfs_root *root, struct inode *inode) +-{ +- u64 alloc_target; +- +- alloc_target = btrfs_get_alloc_profile(root, 1); +- BTRFS_I(inode)->space_info = __find_space_info(root->fs_info, +- alloc_target); +-} +- +-/* +- * for now this just makes sure we have at least 5% of our metadata space free +- * for use. +- */ +-int btrfs_check_metadata_free_space(struct btrfs_root *root) +-{ +- struct btrfs_fs_info *info = root->fs_info; +- struct btrfs_space_info *meta_sinfo; +- u64 alloc_target, thresh; +- int committed = 0, ret; +- +- /* get the space info for where the metadata will live */ +- alloc_target = btrfs_get_alloc_profile(root, 0); +- meta_sinfo = __find_space_info(info, alloc_target); +- +-again: +- spin_lock(&meta_sinfo->lock); +- if (!meta_sinfo->full) +- thresh = meta_sinfo->total_bytes * 80; +- else +- thresh = meta_sinfo->total_bytes * 95; +- +- do_div(thresh, 100); +- +- if (meta_sinfo->bytes_used + meta_sinfo->bytes_reserved + +- meta_sinfo->bytes_pinned + meta_sinfo->bytes_readonly > thresh) { +- struct btrfs_trans_handle *trans; +- if (!meta_sinfo->full) { +- meta_sinfo->force_alloc = 1; +- spin_unlock(&meta_sinfo->lock); +- +- trans = btrfs_start_transaction(root, 1); +- if (!trans) +- return -ENOMEM; +- +- ret = do_chunk_alloc(trans, root->fs_info->extent_root, +- 2 * 1024 * 1024, alloc_target, 0); +- btrfs_end_transaction(trans, root); +- goto again; +- } +- spin_unlock(&meta_sinfo->lock); +- +- if (!committed) { +- committed = 1; +- trans = btrfs_join_transaction(root, 1); +- if (!trans) +- return -ENOMEM; +- ret = btrfs_commit_transaction(trans, root); +- if (ret) +- return ret; +- goto again; +- } +- return -ENOSPC; +- } +- spin_unlock(&meta_sinfo->lock); +- +- return 0; +-} +- +-/* +- * This will check the space that the inode allocates from to make sure we have +- * enough space for bytes. +- */ +-int btrfs_check_data_free_space(struct btrfs_root *root, struct inode *inode, +- u64 bytes) +-{ +- struct btrfs_space_info *data_sinfo; +- int ret = 0, committed = 0; +- +- /* make sure bytes are sectorsize aligned */ +- bytes = (bytes + root->sectorsize - 1) & ~((u64)root->sectorsize - 1); +- +- data_sinfo = BTRFS_I(inode)->space_info; +-again: +- /* make sure we have enough space to handle the data first */ +- spin_lock(&data_sinfo->lock); +- if (data_sinfo->total_bytes - data_sinfo->bytes_used - +- data_sinfo->bytes_delalloc - data_sinfo->bytes_reserved - +- data_sinfo->bytes_pinned - data_sinfo->bytes_readonly - +- data_sinfo->bytes_may_use < bytes) { +- struct btrfs_trans_handle *trans; +- +- /* +- * if we don't have enough free bytes in this space then we need +- * to alloc a new chunk. +- */ +- if (!data_sinfo->full) { +- u64 alloc_target; +- +- data_sinfo->force_alloc = 1; +- spin_unlock(&data_sinfo->lock); +- +- alloc_target = btrfs_get_alloc_profile(root, 1); +- trans = btrfs_start_transaction(root, 1); +- if (!trans) +- return -ENOMEM; +- +- ret = do_chunk_alloc(trans, root->fs_info->extent_root, +- bytes + 2 * 1024 * 1024, +- alloc_target, 0); +- btrfs_end_transaction(trans, root); +- if (ret) +- return ret; +- goto again; +- } +- spin_unlock(&data_sinfo->lock); +- +- /* commit the current transaction and try again */ +- if (!committed) { +- committed = 1; +- trans = btrfs_join_transaction(root, 1); +- if (!trans) +- return -ENOMEM; +- ret = btrfs_commit_transaction(trans, root); +- if (ret) +- return ret; +- goto again; +- } +- +- printk(KERN_ERR "no space left, need %llu, %llu delalloc bytes" +- ", %llu bytes_used, %llu bytes_reserved, " +- "%llu bytes_pinned, %llu bytes_readonly, %llu may use" +- "%llu total\n", bytes, data_sinfo->bytes_delalloc, +- data_sinfo->bytes_used, data_sinfo->bytes_reserved, +- data_sinfo->bytes_pinned, data_sinfo->bytes_readonly, +- data_sinfo->bytes_may_use, data_sinfo->total_bytes); +- return -ENOSPC; +- } +- data_sinfo->bytes_may_use += bytes; +- BTRFS_I(inode)->reserved_bytes += bytes; +- spin_unlock(&data_sinfo->lock); +- +- return btrfs_check_metadata_free_space(root); +-} +- +-/* +- * if there was an error for whatever reason after calling +- * btrfs_check_data_free_space, call this so we can cleanup the counters. +- */ +-void btrfs_free_reserved_data_space(struct btrfs_root *root, +- struct inode *inode, u64 bytes) +-{ +- struct btrfs_space_info *data_sinfo; +- +- /* make sure bytes are sectorsize aligned */ +- bytes = (bytes + root->sectorsize - 1) & ~((u64)root->sectorsize - 1); +- +- data_sinfo = BTRFS_I(inode)->space_info; +- spin_lock(&data_sinfo->lock); +- data_sinfo->bytes_may_use -= bytes; +- BTRFS_I(inode)->reserved_bytes -= bytes; +- spin_unlock(&data_sinfo->lock); +-} +- +-/* called when we are adding a delalloc extent to the inode's io_tree */ +-void btrfs_delalloc_reserve_space(struct btrfs_root *root, struct inode *inode, +- u64 bytes) +-{ +- struct btrfs_space_info *data_sinfo; +- +- /* get the space info for where this inode will be storing its data */ +- data_sinfo = BTRFS_I(inode)->space_info; +- +- /* make sure we have enough space to handle the data first */ +- spin_lock(&data_sinfo->lock); +- data_sinfo->bytes_delalloc += bytes; +- +- /* +- * we are adding a delalloc extent without calling +- * btrfs_check_data_free_space first. This happens on a weird +- * writepage condition, but shouldn't hurt our accounting +- */ +- if (unlikely(bytes > BTRFS_I(inode)->reserved_bytes)) { +- data_sinfo->bytes_may_use -= BTRFS_I(inode)->reserved_bytes; +- BTRFS_I(inode)->reserved_bytes = 0; +- } else { +- data_sinfo->bytes_may_use -= bytes; +- BTRFS_I(inode)->reserved_bytes -= bytes; +- } +- +- spin_unlock(&data_sinfo->lock); +-} +- +-/* called when we are clearing an delalloc extent from the inode's io_tree */ +-void btrfs_delalloc_free_space(struct btrfs_root *root, struct inode *inode, +- u64 bytes) +-{ +- struct btrfs_space_info *info; +- +- info = BTRFS_I(inode)->space_info; +- +- spin_lock(&info->lock); +- info->bytes_delalloc -= bytes; +- spin_unlock(&info->lock); +-} +- + static int do_chunk_alloc(struct btrfs_trans_handle *trans, + struct btrfs_root *extent_root, u64 alloc_bytes, + u64 flags, int force) +@@ -2481,12 +2137,13 @@ + u64 end; + u64 priv; + u64 search = 0; ++ u64 skipped = 0; + struct btrfs_fs_info *info = extent_root->fs_info; + struct btrfs_path *path; + struct pending_extent_op *extent_op, *tmp; + struct list_head insert_list, update_list; + int ret; +- int num_inserts = 0, max_inserts, restart = 0; ++ int num_inserts = 0, max_inserts; + + path = btrfs_alloc_path(); + INIT_LIST_HEAD(&insert_list); +@@ -2502,19 +2159,18 @@ + ret = find_first_extent_bit(&info->extent_ins, search, &start, + &end, EXTENT_WRITEBACK); + if (ret) { +- if (restart && !num_inserts && +- list_empty(&update_list)) { +- restart = 0; ++ if (skipped && all && !num_inserts) { ++ skipped = 0; + search = 0; + continue; + } ++ mutex_unlock(&info->extent_ins_mutex); + break; + } + + ret = try_lock_extent(&info->extent_ins, start, end, GFP_NOFS); + if (!ret) { +- if (all) +- restart = 1; ++ skipped = 1; + search = end + 1; + if (need_resched()) { + mutex_unlock(&info->extent_ins_mutex); +@@ -2533,7 +2189,7 @@ + list_add_tail(&extent_op->list, &insert_list); + search = end + 1; + if (num_inserts == max_inserts) { +- restart = 1; ++ mutex_unlock(&info->extent_ins_mutex); + break; + } + } else if (extent_op->type == PENDING_BACKREF_UPDATE) { +@@ -2549,6 +2205,7 @@ + * somebody marked this thing for deletion then just unlock it and be + * done, the free_extents will handle it + */ ++ mutex_lock(&info->extent_ins_mutex); + list_for_each_entry_safe(extent_op, tmp, &update_list, list) { + clear_extent_bits(&info->extent_ins, extent_op->bytenr, + extent_op->bytenr + extent_op->num_bytes - 1, +@@ -2570,10 +2227,6 @@ + if (!list_empty(&update_list)) { + ret = update_backrefs(trans, extent_root, path, &update_list); + BUG_ON(ret); +- +- /* we may have COW'ed new blocks, so lets start over */ +- if (all) +- restart = 1; + } + + /* +@@ -2581,9 +2234,9 @@ + * need to make sure everything is cleaned then reset everything and + * go back to the beginning + */ +- if (!num_inserts && restart) { ++ if (!num_inserts && all && skipped) { + search = 0; +- restart = 0; ++ skipped = 0; + INIT_LIST_HEAD(&update_list); + INIT_LIST_HEAD(&insert_list); + goto again; +@@ -2640,19 +2293,27 @@ + BUG_ON(ret); + + /* +- * if restart is set for whatever reason we need to go back and start +- * searching through the pending list again. +- * +- * We just inserted some extents, which could have resulted in new +- * blocks being allocated, which would result in new blocks needing +- * updates, so if all is set we _must_ restart to get the updated +- * blocks. ++ * if we broke out of the loop in order to insert stuff because we hit ++ * the maximum number of inserts at a time we can handle, then loop ++ * back and pick up where we left off + */ +- if (restart || all) { ++ if (num_inserts == max_inserts) { ++ INIT_LIST_HEAD(&insert_list); ++ INIT_LIST_HEAD(&update_list); ++ num_inserts = 0; ++ goto again; ++ } ++ ++ /* ++ * again, if we need to make absolutely sure there are no more pending ++ * extent operations left and we know that we skipped some, go back to ++ * the beginning and do it all again ++ */ ++ if (all && skipped) { + INIT_LIST_HEAD(&insert_list); + INIT_LIST_HEAD(&update_list); + search = 0; +- restart = 0; ++ skipped = 0; + num_inserts = 0; + goto again; + } +@@ -2886,7 +2547,6 @@ + if (ret) { + if (all && skipped && !nr) { + search = 0; +- skipped = 0; + continue; + } + mutex_unlock(&info->extent_ins_mutex); +@@ -2973,8 +2633,6 @@ + goto again; + } + +- if (!err) +- finish_current_insert(trans, extent_root, 0); + return err; + } + +@@ -3042,9 +2700,13 @@ + /* if metadata always pin */ + if (owner_objectid < BTRFS_FIRST_FREE_OBJECTID) { + if (root->root_key.objectid == BTRFS_TREE_LOG_OBJECTID) { +- mutex_lock(&root->fs_info->pinned_mutex); +- btrfs_update_pinned_extents(root, bytenr, num_bytes, 1); +- mutex_unlock(&root->fs_info->pinned_mutex); ++ struct btrfs_block_group_cache *cache; ++ ++ /* btrfs_free_reserved_extent */ ++ cache = btrfs_lookup_block_group(root->fs_info, bytenr); ++ BUG_ON(!cache); ++ btrfs_add_free_space(cache, bytenr, num_bytes); ++ put_block_group(cache); + update_reserved_extents(root, bytenr, num_bytes, 0); + return 0; + } +@@ -3125,8 +2787,7 @@ + + if (data & BTRFS_BLOCK_GROUP_METADATA) { + last_ptr = &root->fs_info->last_alloc; +- if (!btrfs_test_opt(root, SSD)) +- empty_cluster = 64 * 1024; ++ empty_cluster = 64 * 1024; + } + + if ((data & BTRFS_BLOCK_GROUP_DATA) && btrfs_test_opt(root, SSD)) +@@ -3353,18 +3014,16 @@ + static void dump_space_info(struct btrfs_space_info *info, u64 bytes) + { + struct btrfs_block_group_cache *cache; ++ struct list_head *l; + + printk(KERN_INFO "space_info has %llu free, is %sfull\n", + (unsigned long long)(info->total_bytes - info->bytes_used - + info->bytes_pinned - info->bytes_reserved), + (info->full) ? "" : "not "); +- printk(KERN_INFO "space_info total=%llu, pinned=%llu, delalloc=%llu," +- " may_use=%llu, used=%llu\n", info->total_bytes, +- info->bytes_pinned, info->bytes_delalloc, info->bytes_may_use, +- info->bytes_used); + + down_read(&info->groups_sem); +- list_for_each_entry(cache, &info->block_groups, list) { ++ list_for_each(l, &info->block_groups) { ++ cache = list_entry(l, struct btrfs_block_group_cache, list); + spin_lock(&cache->lock); + printk(KERN_INFO "block group %llu has %llu bytes, %llu used " + "%llu pinned %llu reserved\n", +@@ -3388,10 +3047,24 @@ + { + int ret; + u64 search_start = 0; ++ u64 alloc_profile; + struct btrfs_fs_info *info = root->fs_info; + +- data = btrfs_get_alloc_profile(root, data); ++ if (data) { ++ alloc_profile = info->avail_data_alloc_bits & ++ info->data_alloc_profile; ++ data = BTRFS_BLOCK_GROUP_DATA | alloc_profile; ++ } else if (root == root->fs_info->chunk_root) { ++ alloc_profile = info->avail_system_alloc_bits & ++ info->system_alloc_profile; ++ data = BTRFS_BLOCK_GROUP_SYSTEM | alloc_profile; ++ } else { ++ alloc_profile = info->avail_metadata_alloc_bits & ++ info->metadata_alloc_profile; ++ data = BTRFS_BLOCK_GROUP_METADATA | alloc_profile; ++ } + again: ++ data = btrfs_reduce_alloc_profile(root, data); + /* + * the only place that sets empty_size is btrfs_realloc_node, which + * is not called recursively on allocations +@@ -3659,8 +3332,7 @@ + + struct extent_buffer *btrfs_init_new_buffer(struct btrfs_trans_handle *trans, + struct btrfs_root *root, +- u64 bytenr, u32 blocksize, +- int level) ++ u64 bytenr, u32 blocksize) + { + struct extent_buffer *buf; + +@@ -3668,13 +3340,9 @@ + if (!buf) + return ERR_PTR(-ENOMEM); + btrfs_set_header_generation(buf, trans->transid); +- btrfs_set_buffer_lockdep_class(buf, level); + btrfs_tree_lock(buf); + clean_tree_block(trans, root, buf); +- +- btrfs_set_lock_blocking(buf); + btrfs_set_buffer_uptodate(buf); +- + if (root->root_key.objectid == BTRFS_TREE_LOG_OBJECTID) { + set_extent_dirty(&root->dirty_log_pages, buf->start, + buf->start + buf->len - 1, GFP_NOFS); +@@ -3683,7 +3351,6 @@ + buf->start + buf->len - 1, GFP_NOFS); + } + trans->blocks_used++; +- /* this returns a buffer locked for blocking */ + return buf; + } + +@@ -3712,8 +3379,7 @@ + return ERR_PTR(ret); + } + +- buf = btrfs_init_new_buffer(trans, root, ins.objectid, +- blocksize, level); ++ buf = btrfs_init_new_buffer(trans, root, ins.objectid, blocksize); + return buf; + } + +@@ -3722,73 +3388,36 @@ + { + u64 leaf_owner; + u64 leaf_generation; +- struct refsort *sorted; + struct btrfs_key key; + struct btrfs_file_extent_item *fi; + int i; + int nritems; + int ret; +- int refi = 0; +- int slot; + + BUG_ON(!btrfs_is_leaf(leaf)); + nritems = btrfs_header_nritems(leaf); + leaf_owner = btrfs_header_owner(leaf); + leaf_generation = btrfs_header_generation(leaf); + +- sorted = kmalloc(sizeof(*sorted) * nritems, GFP_NOFS); +- /* we do this loop twice. The first time we build a list +- * of the extents we have a reference on, then we sort the list +- * by bytenr. The second time around we actually do the +- * extent freeing. +- */ + for (i = 0; i < nritems; i++) { + u64 disk_bytenr; + cond_resched(); + + btrfs_item_key_to_cpu(leaf, &key, i); +- +- /* only extents have references, skip everything else */ + if (btrfs_key_type(&key) != BTRFS_EXTENT_DATA_KEY) + continue; +- + fi = btrfs_item_ptr(leaf, i, struct btrfs_file_extent_item); +- +- /* inline extents live in the btree, they don't have refs */ + if (btrfs_file_extent_type(leaf, fi) == + BTRFS_FILE_EXTENT_INLINE) + continue; +- ++ /* ++ * FIXME make sure to insert a trans record that ++ * repeats the snapshot del on crash ++ */ + disk_bytenr = btrfs_file_extent_disk_bytenr(leaf, fi); +- +- /* holes don't have refs */ + if (disk_bytenr == 0) + continue; + +- sorted[refi].bytenr = disk_bytenr; +- sorted[refi].slot = i; +- refi++; +- } +- +- if (refi == 0) +- goto out; +- +- sort(sorted, refi, sizeof(struct refsort), refsort_cmp, NULL); +- +- for (i = 0; i < refi; i++) { +- u64 disk_bytenr; +- +- disk_bytenr = sorted[i].bytenr; +- slot = sorted[i].slot; +- +- cond_resched(); +- +- btrfs_item_key_to_cpu(leaf, &key, slot); +- if (btrfs_key_type(&key) != BTRFS_EXTENT_DATA_KEY) +- continue; +- +- fi = btrfs_item_ptr(leaf, slot, struct btrfs_file_extent_item); +- + ret = __btrfs_free_extent(trans, root, disk_bytenr, + btrfs_file_extent_disk_num_bytes(leaf, fi), + leaf->start, leaf_owner, leaf_generation, +@@ -3799,8 +3428,6 @@ + wake_up(&root->fs_info->transaction_throttle); + cond_resched(); + } +-out: +- kfree(sorted); + return 0; + } + +@@ -3810,25 +3437,9 @@ + { + int i; + int ret; +- struct btrfs_extent_info *info; +- struct refsort *sorted; +- +- if (ref->nritems == 0) +- return 0; ++ struct btrfs_extent_info *info = ref->extents; + +- sorted = kmalloc(sizeof(*sorted) * ref->nritems, GFP_NOFS); + for (i = 0; i < ref->nritems; i++) { +- sorted[i].bytenr = ref->extents[i].bytenr; +- sorted[i].slot = i; +- } +- sort(sorted, ref->nritems, sizeof(struct refsort), refsort_cmp, NULL); +- +- /* +- * the items in the ref were sorted when the ref was inserted +- * into the ref cache, so this is already in order +- */ +- for (i = 0; i < ref->nritems; i++) { +- info = ref->extents + sorted[i].slot; + ret = __btrfs_free_extent(trans, root, info->bytenr, + info->num_bytes, ref->bytenr, + ref->owner, ref->generation, +@@ -3842,7 +3453,6 @@ + info++; + } + +- kfree(sorted); + return 0; + } + +@@ -3887,152 +3497,6 @@ + } + + /* +- * this is used while deleting old snapshots, and it drops the refs +- * on a whole subtree starting from a level 1 node. +- * +- * The idea is to sort all the leaf pointers, and then drop the +- * ref on all the leaves in order. Most of the time the leaves +- * will have ref cache entries, so no leaf IOs will be required to +- * find the extents they have references on. +- * +- * For each leaf, any references it has are also dropped in order +- * +- * This ends up dropping the references in something close to optimal +- * order for reading and modifying the extent allocation tree. +- */ +-static noinline int drop_level_one_refs(struct btrfs_trans_handle *trans, +- struct btrfs_root *root, +- struct btrfs_path *path) +-{ +- u64 bytenr; +- u64 root_owner; +- u64 root_gen; +- struct extent_buffer *eb = path->nodes[1]; +- struct extent_buffer *leaf; +- struct btrfs_leaf_ref *ref; +- struct refsort *sorted = NULL; +- int nritems = btrfs_header_nritems(eb); +- int ret; +- int i; +- int refi = 0; +- int slot = path->slots[1]; +- u32 blocksize = btrfs_level_size(root, 0); +- u32 refs; +- +- if (nritems == 0) +- goto out; +- +- root_owner = btrfs_header_owner(eb); +- root_gen = btrfs_header_generation(eb); +- sorted = kmalloc(sizeof(*sorted) * nritems, GFP_NOFS); +- +- /* +- * step one, sort all the leaf pointers so we don't scribble +- * randomly into the extent allocation tree +- */ +- for (i = slot; i < nritems; i++) { +- sorted[refi].bytenr = btrfs_node_blockptr(eb, i); +- sorted[refi].slot = i; +- refi++; +- } +- +- /* +- * nritems won't be zero, but if we're picking up drop_snapshot +- * after a crash, slot might be > 0, so double check things +- * just in case. +- */ +- if (refi == 0) +- goto out; +- +- sort(sorted, refi, sizeof(struct refsort), refsort_cmp, NULL); +- +- /* +- * the first loop frees everything the leaves point to +- */ +- for (i = 0; i < refi; i++) { +- u64 ptr_gen; +- +- bytenr = sorted[i].bytenr; +- +- /* +- * check the reference count on this leaf. If it is > 1 +- * we just decrement it below and don't update any +- * of the refs the leaf points to. +- */ +- ret = drop_snap_lookup_refcount(root, bytenr, blocksize, &refs); +- BUG_ON(ret); +- if (refs != 1) +- continue; +- +- ptr_gen = btrfs_node_ptr_generation(eb, sorted[i].slot); +- +- /* +- * the leaf only had one reference, which means the +- * only thing pointing to this leaf is the snapshot +- * we're deleting. It isn't possible for the reference +- * count to increase again later +- * +- * The reference cache is checked for the leaf, +- * and if found we'll be able to drop any refs held by +- * the leaf without needing to read it in. +- */ +- ref = btrfs_lookup_leaf_ref(root, bytenr); +- if (ref && ref->generation != ptr_gen) { +- btrfs_free_leaf_ref(root, ref); +- ref = NULL; +- } +- if (ref) { +- ret = cache_drop_leaf_ref(trans, root, ref); +- BUG_ON(ret); +- btrfs_remove_leaf_ref(root, ref); +- btrfs_free_leaf_ref(root, ref); +- } else { +- /* +- * the leaf wasn't in the reference cache, so +- * we have to read it. +- */ +- leaf = read_tree_block(root, bytenr, blocksize, +- ptr_gen); +- ret = btrfs_drop_leaf_ref(trans, root, leaf); +- BUG_ON(ret); +- free_extent_buffer(leaf); +- } +- atomic_inc(&root->fs_info->throttle_gen); +- wake_up(&root->fs_info->transaction_throttle); +- cond_resched(); +- } +- +- /* +- * run through the loop again to free the refs on the leaves. +- * This is faster than doing it in the loop above because +- * the leaves are likely to be clustered together. We end up +- * working in nice chunks on the extent allocation tree. +- */ +- for (i = 0; i < refi; i++) { +- bytenr = sorted[i].bytenr; +- ret = __btrfs_free_extent(trans, root, bytenr, +- blocksize, eb->start, +- root_owner, root_gen, 0, 1); +- BUG_ON(ret); +- +- atomic_inc(&root->fs_info->throttle_gen); +- wake_up(&root->fs_info->transaction_throttle); +- cond_resched(); +- } +-out: +- kfree(sorted); +- +- /* +- * update the path to show we've processed the entire level 1 +- * node. This will get saved into the root's drop_snapshot_progress +- * field so these drops are not repeated again if this transaction +- * commits. +- */ +- path->slots[1] = nritems; +- return 0; +-} +- +-/* + * helper function for drop_snapshot, this walks down the tree dropping ref + * counts as it goes. + */ +@@ -4047,6 +3511,7 @@ + struct extent_buffer *next; + struct extent_buffer *cur; + struct extent_buffer *parent; ++ struct btrfs_leaf_ref *ref; + u32 blocksize; + int ret; + u32 refs; +@@ -4073,46 +3538,17 @@ + if (path->slots[*level] >= + btrfs_header_nritems(cur)) + break; +- +- /* the new code goes down to level 1 and does all the +- * leaves pointed to that node in bulk. So, this check +- * for level 0 will always be false. +- * +- * But, the disk format allows the drop_snapshot_progress +- * field in the root to leave things in a state where +- * a leaf will need cleaning up here. If someone crashes +- * with the old code and then boots with the new code, +- * we might find a leaf here. +- */ + if (*level == 0) { + ret = btrfs_drop_leaf_ref(trans, root, cur); + BUG_ON(ret); + break; + } +- +- /* +- * once we get to level one, process the whole node +- * at once, including everything below it. +- */ +- if (*level == 1) { +- ret = drop_level_one_refs(trans, root, path); +- BUG_ON(ret); +- break; +- } +- + bytenr = btrfs_node_blockptr(cur, path->slots[*level]); + ptr_gen = btrfs_node_ptr_generation(cur, path->slots[*level]); + blocksize = btrfs_level_size(root, *level - 1); + + ret = drop_snap_lookup_refcount(root, bytenr, blocksize, &refs); + BUG_ON(ret); +- +- /* +- * if there is more than one reference, we don't need +- * to read that node to drop any references it has. We +- * just drop the ref we hold on that node and move on to the +- * next slot in this level. +- */ + if (refs != 1) { + parent = path->nodes[*level]; + root_owner = btrfs_header_owner(parent); +@@ -4131,12 +3567,46 @@ + + continue; + } +- + /* +- * we need to keep freeing things in the next level down. +- * read the block and loop around to process it ++ * at this point, we have a single ref, and since the ++ * only place referencing this extent is a dead root ++ * the reference count should never go higher. ++ * So, we don't need to check it again + */ +- next = read_tree_block(root, bytenr, blocksize, ptr_gen); ++ if (*level == 1) { ++ ref = btrfs_lookup_leaf_ref(root, bytenr); ++ if (ref && ref->generation != ptr_gen) { ++ btrfs_free_leaf_ref(root, ref); ++ ref = NULL; ++ } ++ if (ref) { ++ ret = cache_drop_leaf_ref(trans, root, ref); ++ BUG_ON(ret); ++ btrfs_remove_leaf_ref(root, ref); ++ btrfs_free_leaf_ref(root, ref); ++ *level = 0; ++ break; ++ } ++ } ++ next = btrfs_find_tree_block(root, bytenr, blocksize); ++ if (!next || !btrfs_buffer_uptodate(next, ptr_gen)) { ++ free_extent_buffer(next); ++ ++ next = read_tree_block(root, bytenr, blocksize, ++ ptr_gen); ++ cond_resched(); ++#if 0 ++ /* ++ * this is a debugging check and can go away ++ * the ref should never go all the way down to 1 ++ * at this point ++ */ ++ ret = lookup_extent_ref(NULL, root, bytenr, blocksize, ++ &refs); ++ BUG_ON(ret); ++ WARN_ON(refs != 1); ++#endif ++ } + WARN_ON(*level <= 0); + if (path->nodes[*level-1]) + free_extent_buffer(path->nodes[*level-1]); +@@ -4161,16 +3631,11 @@ + root_owner = btrfs_header_owner(parent); + root_gen = btrfs_header_generation(parent); + +- /* +- * cleanup and free the reference on the last node +- * we processed +- */ + ret = __btrfs_free_extent(trans, root, bytenr, blocksize, + parent->start, root_owner, root_gen, + *level, 1); + free_extent_buffer(path->nodes[*level]); + path->nodes[*level] = NULL; +- + *level += 1; + BUG_ON(ret); + +@@ -4222,7 +3687,6 @@ + + next = read_tree_block(root, bytenr, blocksize, ptr_gen); + btrfs_tree_lock(next); +- btrfs_set_lock_blocking(next); + + ret = btrfs_lookup_extent_ref(trans, root, bytenr, blocksize, + &refs); +@@ -4290,13 +3754,6 @@ + if (slot < btrfs_header_nritems(path->nodes[i]) - 1) { + struct extent_buffer *node; + struct btrfs_disk_key disk_key; +- +- /* +- * there is more work to do in this level. +- * Update the drop_progress marker to reflect +- * the work we've done so far, and then bump +- * the slot number +- */ + node = path->nodes[i]; + path->slots[i]++; + *level = i; +@@ -4308,11 +3765,6 @@ + return 0; + } else { + struct extent_buffer *parent; +- +- /* +- * this whole node is done, free our reference +- * on it and go up one level +- */ + if (path->nodes[*level] == root->node) + parent = path->nodes[*level]; + else +@@ -4439,13 +3891,13 @@ + path = btrfs_alloc_path(); + BUG_ON(!path); + +- btrfs_assert_tree_locked(parent); ++ BUG_ON(!btrfs_tree_locked(parent)); + parent_level = btrfs_header_level(parent); + extent_buffer_get(parent); + path->nodes[parent_level] = parent; + path->slots[parent_level] = btrfs_header_nritems(parent); + +- btrfs_assert_tree_locked(node); ++ BUG_ON(!btrfs_tree_locked(node)); + level = btrfs_header_level(node); + extent_buffer_get(node); + path->nodes[level] = node; +@@ -4992,7 +4444,7 @@ + u64 lock_end = 0; + u64 num_bytes; + u64 ext_offset; +- u64 search_end = (u64)-1; ++ u64 first_pos; + u32 nritems; + int nr_scaned = 0; + int extent_locked = 0; +@@ -5000,6 +4452,7 @@ + int ret; + + memcpy(&key, leaf_key, sizeof(key)); ++ first_pos = INT_LIMIT(loff_t) - extent_key->offset; + if (ref_path->owner_objectid != BTRFS_MULTIPLE_OBJECTIDS) { + if (key.objectid < ref_path->owner_objectid || + (key.objectid == ref_path->owner_objectid && +@@ -5048,7 +4501,7 @@ + if ((key.objectid > ref_path->owner_objectid) || + (key.objectid == ref_path->owner_objectid && + key.type > BTRFS_EXTENT_DATA_KEY) || +- key.offset >= search_end) ++ (key.offset >= first_pos + extent_key->offset)) + break; + } + +@@ -5081,10 +4534,8 @@ + num_bytes = btrfs_file_extent_num_bytes(leaf, fi); + ext_offset = btrfs_file_extent_offset(leaf, fi); + +- if (search_end == (u64)-1) { +- search_end = key.offset - ext_offset + +- btrfs_file_extent_ram_bytes(leaf, fi); +- } ++ if (first_pos > key.offset - ext_offset) ++ first_pos = key.offset - ext_offset; + + if (!extent_locked) { + lock_start = key.offset; +@@ -5273,7 +4724,7 @@ + } + skip: + if (ref_path->owner_objectid != BTRFS_MULTIPLE_OBJECTIDS && +- key.offset >= search_end) ++ key.offset >= first_pos + extent_key->offset) + break; + + cond_resched(); +@@ -5327,7 +4778,6 @@ + ref->bytenr = buf->start; + ref->owner = btrfs_header_owner(buf); + ref->generation = btrfs_header_generation(buf); +- + ret = btrfs_add_leaf_ref(root, ref, 0); + WARN_ON(ret); + btrfs_free_leaf_ref(root, ref); +@@ -5901,9 +5351,7 @@ + prev_block = block_start; + } + +- mutex_lock(&extent_root->fs_info->trans_mutex); + btrfs_record_root_in_trans(found_root); +- mutex_unlock(&extent_root->fs_info->trans_mutex); + if (ref_path->owner_objectid >= BTRFS_FIRST_FREE_OBJECTID) { + /* + * try to update data extent references while +@@ -6341,7 +5789,6 @@ + int btrfs_free_block_groups(struct btrfs_fs_info *info) + { + struct btrfs_block_group_cache *block_group; +- struct btrfs_space_info *space_info; + struct rb_node *n; + + spin_lock(&info->block_group_cache_lock); +@@ -6363,23 +5810,6 @@ + spin_lock(&info->block_group_cache_lock); + } + spin_unlock(&info->block_group_cache_lock); +- +- /* now that all the block groups are freed, go through and +- * free all the space_info structs. This is only called during +- * the final stages of unmount, and so we know nobody is +- * using them. We call synchronize_rcu() once before we start, +- * just to be on the safe side. +- */ +- synchronize_rcu(); +- +- while(!list_empty(&info->space_info)) { +- space_info = list_entry(info->space_info.next, +- struct btrfs_space_info, +- list); +- +- list_del(&space_info->list); +- kfree(space_info); +- } + return 0; + } + +@@ -6527,11 +5957,9 @@ + path = btrfs_alloc_path(); + BUG_ON(!path); + +- spin_lock(&root->fs_info->block_group_cache_lock); ++ btrfs_remove_free_space_cache(block_group); + rb_erase(&block_group->cache_node, + &root->fs_info->block_group_cache_tree); +- spin_unlock(&root->fs_info->block_group_cache_lock); +- btrfs_remove_free_space_cache(block_group); + down_write(&block_group->space_info->groups_sem); + list_del(&block_group->list); + up_write(&block_group->space_info->groups_sem); +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/fs/btrfs/file.c linux-2.6.29-rc3.owrt/fs/btrfs/file.c +--- linux-2.6.29.owrt/fs/btrfs/file.c 2009-05-10 22:04:39.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/fs/btrfs/file.c 2009-05-10 23:48:29.000000000 +0200 +@@ -29,6 +29,7 @@ + #include <linux/writeback.h> + #include <linux/statfs.h> + #include <linux/compat.h> ++#include <linux/version.h> + #include "ctree.h" + #include "disk-io.h" + #include "transaction.h" +@@ -1091,24 +1092,19 @@ + WARN_ON(num_pages > nrptrs); + memset(pages, 0, sizeof(struct page *) * nrptrs); + +- ret = btrfs_check_data_free_space(root, inode, write_bytes); ++ ret = btrfs_check_free_space(root, write_bytes, 0); + if (ret) + goto out; + + ret = prepare_pages(root, file, pages, num_pages, + pos, first_index, last_index, + write_bytes); +- if (ret) { +- btrfs_free_reserved_data_space(root, inode, +- write_bytes); ++ if (ret) + goto out; +- } + + ret = btrfs_copy_from_user(pos, num_pages, + write_bytes, pages, buf); + if (ret) { +- btrfs_free_reserved_data_space(root, inode, +- write_bytes); + btrfs_drop_pages(pages, num_pages); + goto out; + } +@@ -1116,11 +1112,8 @@ + ret = dirty_and_release_pages(NULL, root, file, pages, + num_pages, pos, write_bytes); + btrfs_drop_pages(pages, num_pages); +- if (ret) { +- btrfs_free_reserved_data_space(root, inode, +- write_bytes); ++ if (ret) + goto out; +- } + + if (will_write) { + btrfs_fdatawrite_range(inode->i_mapping, pos, +@@ -1144,8 +1137,6 @@ + } + out: + mutex_unlock(&inode->i_mutex); +- if (ret) +- err = ret; + + out_nolock: + kfree(pages); +@@ -1224,15 +1215,15 @@ + } + mutex_unlock(&root->fs_info->trans_mutex); + +- root->log_batch++; ++ root->fs_info->tree_log_batch++; + filemap_fdatawrite(inode->i_mapping); + btrfs_wait_ordered_range(inode, 0, (u64)-1); +- root->log_batch++; ++ root->fs_info->tree_log_batch++; + + /* + * ok we haven't committed the transaction yet, lets do a commit + */ +- if (file && file->private_data) ++ if (file->private_data) + btrfs_ioctl_trans_end(file); + + trans = btrfs_start_transaction(root, 1); +@@ -1241,7 +1232,7 @@ + goto out; + } + +- ret = btrfs_log_dentry_safe(trans, root, dentry); ++ ret = btrfs_log_dentry_safe(trans, root, file->f_dentry); + if (ret < 0) + goto out; + +@@ -1255,7 +1246,7 @@ + * file again, but that will end up using the synchronization + * inside btrfs_sync_log to keep things safe. + */ +- mutex_unlock(&dentry->d_inode->i_mutex); ++ mutex_unlock(&file->f_dentry->d_inode->i_mutex); + + if (ret > 0) { + ret = btrfs_commit_transaction(trans, root); +@@ -1263,7 +1254,7 @@ + btrfs_sync_log(trans, root); + ret = btrfs_end_transaction(trans, root); + } +- mutex_lock(&dentry->d_inode->i_mutex); ++ mutex_lock(&file->f_dentry->d_inode->i_mutex); + out: + return ret > 0 ? EIO : ret; + } +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/fs/btrfs/inode.c linux-2.6.29-rc3.owrt/fs/btrfs/inode.c +--- linux-2.6.29.owrt/fs/btrfs/inode.c 2009-05-10 22:04:39.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/fs/btrfs/inode.c 2009-05-10 23:48:29.000000000 +0200 +@@ -34,6 +34,7 @@ + #include <linux/statfs.h> + #include <linux/compat.h> + #include <linux/bit_spinlock.h> ++#include <linux/version.h> + #include <linux/xattr.h> + #include <linux/posix_acl.h> + #include <linux/falloc.h> +@@ -50,7 +51,6 @@ + #include "tree-log.h" + #include "ref-cache.h" + #include "compression.h" +-#include "locking.h" + + struct btrfs_iget_args { + u64 ino; +@@ -91,14 +91,32 @@ + u64 start, u64 end, int *page_started, + unsigned long *nr_written, int unlock); + +-static int btrfs_init_inode_security(struct inode *inode, struct inode *dir) ++/* ++ * a very lame attempt at stopping writes when the FS is 85% full. There ++ * are countless ways this is incorrect, but it is better than nothing. ++ */ ++int btrfs_check_free_space(struct btrfs_root *root, u64 num_required, ++ int for_del) + { +- int err; ++ u64 total; ++ u64 used; ++ u64 thresh; ++ int ret = 0; + +- err = btrfs_init_acl(inode, dir); +- if (!err) +- err = btrfs_xattr_security_init(inode, dir); +- return err; ++ spin_lock(&root->fs_info->delalloc_lock); ++ total = btrfs_super_total_bytes(&root->fs_info->super_copy); ++ used = btrfs_super_bytes_used(&root->fs_info->super_copy); ++ if (for_del) ++ thresh = total * 90; ++ else ++ thresh = total * 85; ++ ++ do_div(thresh, 100); ++ ++ if (used + root->fs_info->delalloc_bytes + num_required > thresh) ++ ret = -ENOSPC; ++ spin_unlock(&root->fs_info->delalloc_lock); ++ return ret; + } + + /* +@@ -332,19 +350,6 @@ + nr_pages = (end >> PAGE_CACHE_SHIFT) - (start >> PAGE_CACHE_SHIFT) + 1; + nr_pages = min(nr_pages, (128 * 1024UL) / PAGE_CACHE_SIZE); + +- /* +- * we don't want to send crud past the end of i_size through +- * compression, that's just a waste of CPU time. So, if the +- * end of the file is before the start of our current +- * requested range of bytes, we bail out to the uncompressed +- * cleanup code that can deal with all of this. +- * +- * It isn't really the fastest way to fix things, but this is a +- * very uncommon corner. +- */ +- if (actual_end <= start) +- goto cleanup_and_bail_uncompressed; +- + total_compressed = actual_end - start; + + /* we want to make sure that amount of ram required to uncompress +@@ -489,7 +494,6 @@ + goto again; + } + } else { +-cleanup_and_bail_uncompressed: + /* + * No compression, but we still need to write the pages in + * the file we've been given so far. redirty the locked +@@ -1162,7 +1166,6 @@ + */ + if (!(old & EXTENT_DELALLOC) && (bits & EXTENT_DELALLOC)) { + struct btrfs_root *root = BTRFS_I(inode)->root; +- btrfs_delalloc_reserve_space(root, inode, end - start + 1); + spin_lock(&root->fs_info->delalloc_lock); + BTRFS_I(inode)->delalloc_bytes += end - start + 1; + root->fs_info->delalloc_bytes += end - start + 1; +@@ -1196,12 +1199,9 @@ + (unsigned long long)end - start + 1, + (unsigned long long) + root->fs_info->delalloc_bytes); +- btrfs_delalloc_free_space(root, inode, (u64)-1); + root->fs_info->delalloc_bytes = 0; + BTRFS_I(inode)->delalloc_bytes = 0; + } else { +- btrfs_delalloc_free_space(root, inode, +- end - start + 1); + root->fs_info->delalloc_bytes -= end - start + 1; + BTRFS_I(inode)->delalloc_bytes -= end - start + 1; + } +@@ -1324,11 +1324,12 @@ + struct inode *inode, u64 file_offset, + struct list_head *list) + { ++ struct list_head *cur; + struct btrfs_ordered_sum *sum; + + btrfs_set_trans_block_group(trans, inode); +- +- list_for_each_entry(sum, list, list) { ++ list_for_each(cur, list) { ++ sum = list_entry(cur, struct btrfs_ordered_sum, list); + btrfs_csum_file_blocks(trans, + BTRFS_I(inode)->root->fs_info->csum_root, sum); + } +@@ -2012,7 +2013,6 @@ + BTRFS_I(inode)->flags = btrfs_inode_flags(leaf, inode_item); + + alloc_group_block = btrfs_inode_block_group(leaf, inode_item); +- + BTRFS_I(inode)->block_group = btrfs_find_block_group(root, 0, + alloc_group_block, 0); + btrfs_free_path(path); +@@ -2039,7 +2039,6 @@ + inode->i_mapping->backing_dev_info = &root->fs_info->bdi; + break; + default: +- inode->i_op = &btrfs_special_inode_operations; + init_special_inode(inode, inode->i_mode, rdev); + break; + } +@@ -2109,7 +2108,6 @@ + goto failed; + } + +- btrfs_unlock_up_safe(path, 1); + leaf = path->nodes[0]; + inode_item = btrfs_item_ptr(leaf, path->slots[0], + struct btrfs_inode_item); +@@ -2221,6 +2219,10 @@ + + root = BTRFS_I(dir)->root; + ++ ret = btrfs_check_free_space(root, 1, 1); ++ if (ret) ++ goto fail; ++ + trans = btrfs_start_transaction(root, 1); + + btrfs_set_trans_block_group(trans, dir); +@@ -2233,6 +2235,7 @@ + nr = trans->blocks_used; + + btrfs_end_transaction_throttle(trans, root); ++fail: + btrfs_btree_balance_dirty(root, nr); + return ret; + } +@@ -2255,6 +2258,10 @@ + return -ENOTEMPTY; + } + ++ ret = btrfs_check_free_space(root, 1, 1); ++ if (ret) ++ goto fail; ++ + trans = btrfs_start_transaction(root, 1); + btrfs_set_trans_block_group(trans, dir); + +@@ -2271,6 +2278,7 @@ + fail_trans: + nr = trans->blocks_used; + ret = btrfs_end_transaction_throttle(trans, root); ++fail: + btrfs_btree_balance_dirty(root, nr); + + if (ret && !err) +@@ -2421,8 +2429,6 @@ + ref->generation = leaf_gen; + ref->nritems = 0; + +- btrfs_sort_leaf_ref(ref); +- + ret = btrfs_add_leaf_ref(root, ref, 0); + WARN_ON(ret); + btrfs_free_leaf_ref(root, ref); +@@ -2470,7 +2476,7 @@ + struct btrfs_path *path; + struct btrfs_key key; + struct btrfs_key found_key; +- u32 found_type = (u8)-1; ++ u32 found_type; + struct extent_buffer *leaf; + struct btrfs_file_extent_item *fi; + u64 extent_start = 0; +@@ -2497,6 +2503,8 @@ + key.offset = (u64)-1; + key.type = (u8)-1; + ++ btrfs_init_path(path); ++ + search_again: + ret = btrfs_search_slot(trans, root, &key, path, -1, 1); + if (ret < 0) +@@ -2655,8 +2663,6 @@ + if (pending_del_nr) + goto del_pending; + btrfs_release_path(root, path); +- if (found_type == BTRFS_INODE_ITEM_KEY) +- break; + goto search_again; + } + +@@ -2673,8 +2679,6 @@ + BUG_ON(ret); + pending_del_nr = 0; + btrfs_release_path(root, path); +- if (found_type == BTRFS_INODE_ITEM_KEY) +- break; + goto search_again; + } + } +@@ -2784,7 +2788,7 @@ + if (size <= hole_start) + return 0; + +- err = btrfs_check_metadata_free_space(root); ++ err = btrfs_check_free_space(root, 1, 0); + if (err) + return err; + +@@ -2980,7 +2984,6 @@ + bi->last_trans = 0; + bi->logged_trans = 0; + bi->delalloc_bytes = 0; +- bi->reserved_bytes = 0; + bi->disk_i_size = 0; + bi->flags = 0; + bi->index_cnt = (u64)-1; +@@ -3002,7 +3005,6 @@ + inode->i_ino = args->ino; + init_btrfs_i(inode); + BTRFS_I(inode)->root = args->root; +- btrfs_set_inode_space_info(args->root, inode); + return 0; + } + +@@ -3263,7 +3265,7 @@ + + /* Reached end of directory/root. Bump pos past the last item. */ + if (key_type == BTRFS_DIR_INDEX_KEY) +- filp->f_pos = INT_LIMIT(off_t); ++ filp->f_pos = INT_LIMIT(typeof(filp->f_pos)); + else + filp->f_pos++; + nopos: +@@ -3423,7 +3425,6 @@ + BTRFS_I(inode)->index_cnt = 2; + BTRFS_I(inode)->root = root; + BTRFS_I(inode)->generation = trans->transid; +- btrfs_set_inode_space_info(root, inode); + + if (mode & S_IFDIR) + owner = 0; +@@ -3457,14 +3458,7 @@ + root->highest_inode = objectid; + + inode->i_uid = current_fsuid(); +- +- if (dir && (dir->i_mode & S_ISGID)) { +- inode->i_gid = dir->i_gid; +- if (S_ISDIR(mode)) +- mode |= S_ISGID; +- } else +- inode->i_gid = current_fsgid(); +- ++ inode->i_gid = current_fsgid(); + inode->i_mode = mode; + inode->i_ino = objectid; + inode_set_bytes(inode, 0); +@@ -3571,7 +3565,7 @@ + if (!new_valid_dev(rdev)) + return -EINVAL; + +- err = btrfs_check_metadata_free_space(root); ++ err = btrfs_check_free_space(root, 1, 0); + if (err) + goto fail; + +@@ -3592,7 +3586,7 @@ + if (IS_ERR(inode)) + goto out_unlock; + +- err = btrfs_init_inode_security(inode, dir); ++ err = btrfs_init_acl(inode, dir); + if (err) { + drop_inode = 1; + goto out_unlock; +@@ -3634,7 +3628,7 @@ + u64 objectid; + u64 index = 0; + +- err = btrfs_check_metadata_free_space(root); ++ err = btrfs_check_free_space(root, 1, 0); + if (err) + goto fail; + trans = btrfs_start_transaction(root, 1); +@@ -3655,7 +3649,7 @@ + if (IS_ERR(inode)) + goto out_unlock; + +- err = btrfs_init_inode_security(inode, dir); ++ err = btrfs_init_acl(inode, dir); + if (err) { + drop_inode = 1; + goto out_unlock; +@@ -3702,7 +3696,7 @@ + return -ENOENT; + + btrfs_inc_nlink(inode); +- err = btrfs_check_metadata_free_space(root); ++ err = btrfs_check_free_space(root, 1, 0); + if (err) + goto fail; + err = btrfs_set_inode_index(dir, &index); +@@ -3748,7 +3742,7 @@ + u64 index = 0; + unsigned long nr = 1; + +- err = btrfs_check_metadata_free_space(root); ++ err = btrfs_check_free_space(root, 1, 0); + if (err) + goto out_unlock; + +@@ -3778,7 +3772,7 @@ + + drop_on_err = 1; + +- err = btrfs_init_inode_security(inode, dir); ++ err = btrfs_init_acl(inode, dir); + if (err) + goto out_fail; + +@@ -4164,10 +4158,9 @@ + return -EINVAL; + } + +-static int btrfs_fiemap(struct inode *inode, struct fiemap_extent_info *fieinfo, +- __u64 start, __u64 len) ++static sector_t btrfs_bmap(struct address_space *mapping, sector_t iblock) + { +- return extent_fiemap(inode, fieinfo, start, len, btrfs_get_extent); ++ return extent_bmap(mapping, iblock, btrfs_get_extent); + } + + int btrfs_readpage(struct file *file, struct page *page) +@@ -4230,7 +4223,7 @@ + { + if (PageWriteback(page) || PageDirty(page)) + return 0; +- return __btrfs_releasepage(page, gfp_flags & GFP_NOFS); ++ return __btrfs_releasepage(page, gfp_flags); + } + + static void btrfs_invalidatepage(struct page *page, unsigned long offset) +@@ -4305,7 +4298,7 @@ + u64 page_start; + u64 page_end; + +- ret = btrfs_check_data_free_space(root, inode, PAGE_CACHE_SIZE); ++ ret = btrfs_check_free_space(root, PAGE_CACHE_SIZE, 0); + if (ret) + goto out; + +@@ -4318,7 +4311,6 @@ + + if ((page->mapping != inode->i_mapping) || + (page_start >= size)) { +- btrfs_free_reserved_data_space(root, inode, PAGE_CACHE_SIZE); + /* page got truncated out from underneath us */ + goto out_unlock; + } +@@ -4601,7 +4593,7 @@ + if (old_inode->i_ino == BTRFS_FIRST_FREE_OBJECTID) + return -EXDEV; + +- ret = btrfs_check_metadata_free_space(root); ++ ret = btrfs_check_free_space(root, 1, 0); + if (ret) + goto out_unlock; + +@@ -4719,7 +4711,7 @@ + if (name_len > BTRFS_MAX_INLINE_DATA_SIZE(root)) + return -ENAMETOOLONG; + +- err = btrfs_check_metadata_free_space(root); ++ err = btrfs_check_free_space(root, 1, 0); + if (err) + goto out_fail; + +@@ -4741,7 +4733,7 @@ + if (IS_ERR(inode)) + goto out_unlock; + +- err = btrfs_init_inode_security(inode, dir); ++ err = btrfs_init_acl(inode, dir); + if (err) { + drop_inode = 1; + goto out_unlock; +@@ -4995,24 +4987,13 @@ + .clear_bit_hook = btrfs_clear_bit_hook, + }; + +-/* +- * btrfs doesn't support the bmap operation because swapfiles +- * use bmap to make a mapping of extents in the file. They assume +- * these extents won't change over the life of the file and they +- * use the bmap result to do IO directly to the drive. +- * +- * the btrfs bmap call would return logical addresses that aren't +- * suitable for IO and they also will change frequently as COW +- * operations happen. So, swapfile + btrfs == corruption. +- * +- * For now we're avoiding this by dropping bmap. +- */ + static struct address_space_operations btrfs_aops = { + .readpage = btrfs_readpage, + .writepage = btrfs_writepage, + .writepages = btrfs_writepages, + .readpages = btrfs_readpages, + .sync_page = block_sync_page, ++ .bmap = btrfs_bmap, + .direct_IO = btrfs_direct_IO, + .invalidatepage = btrfs_invalidatepage, + .releasepage = btrfs_releasepage, +@@ -5036,7 +5017,6 @@ + .removexattr = btrfs_removexattr, + .permission = btrfs_permission, + .fallocate = btrfs_fallocate, +- .fiemap = btrfs_fiemap, + }; + static struct inode_operations btrfs_special_inode_operations = { + .getattr = btrfs_getattr, +@@ -5052,8 +5032,4 @@ + .follow_link = page_follow_link_light, + .put_link = page_put_link, + .permission = btrfs_permission, +- .setxattr = btrfs_setxattr, +- .getxattr = btrfs_getxattr, +- .listxattr = btrfs_listxattr, +- .removexattr = btrfs_removexattr, + }; +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/fs/btrfs/inode-map.c linux-2.6.29-rc3.owrt/fs/btrfs/inode-map.c +--- linux-2.6.29.owrt/fs/btrfs/inode-map.c 2009-05-10 22:04:39.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/fs/btrfs/inode-map.c 2009-05-10 23:48:29.000000000 +0200 +@@ -84,6 +84,7 @@ + search_key.type = 0; + search_key.offset = 0; + ++ btrfs_init_path(path); + start_found = 0; + ret = btrfs_search_slot(trans, root, &search_key, path, 0, 0); + if (ret < 0) +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/fs/btrfs/ioctl.c linux-2.6.29-rc3.owrt/fs/btrfs/ioctl.c +--- linux-2.6.29.owrt/fs/btrfs/ioctl.c 2009-05-10 22:04:39.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/fs/btrfs/ioctl.c 2009-05-10 23:48:29.000000000 +0200 +@@ -38,6 +38,7 @@ + #include <linux/compat.h> + #include <linux/bit_spinlock.h> + #include <linux/security.h> ++#include <linux/version.h> + #include <linux/xattr.h> + #include <linux/vmalloc.h> + #include "compat.h" +@@ -70,7 +71,7 @@ + u64 index = 0; + unsigned long nr = 1; + +- ret = btrfs_check_metadata_free_space(root); ++ ret = btrfs_check_free_space(root, 1, 0); + if (ret) + goto fail_commit; + +@@ -203,7 +204,7 @@ + if (!root->ref_cows) + return -EINVAL; + +- ret = btrfs_check_metadata_free_space(root); ++ ret = btrfs_check_free_space(root, 1, 0); + if (ret) + goto fail_unlock; + +@@ -374,7 +375,7 @@ + unsigned long i; + int ret; + +- ret = btrfs_check_data_free_space(root, inode, inode->i_size); ++ ret = btrfs_check_free_space(root, inode->i_size, 0); + if (ret) + return -ENOSPC; + +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/fs/btrfs/Kconfig linux-2.6.29-rc3.owrt/fs/btrfs/Kconfig +--- linux-2.6.29.owrt/fs/btrfs/Kconfig 2009-05-10 22:04:39.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/fs/btrfs/Kconfig 2009-05-10 23:48:29.000000000 +0200 +@@ -16,16 +16,3 @@ + module will be called btrfs. + + If unsure, say N. +- +-config BTRFS_FS_POSIX_ACL +- bool "Btrfs POSIX Access Control Lists" +- depends on BTRFS_FS +- select FS_POSIX_ACL +- help +- POSIX Access Control Lists (ACLs) support permissions for users and +- groups beyond the owner/group/world scheme. +- +- To learn more about Access Control Lists, visit the POSIX ACLs for +- Linux website <http://acl.bestbits.at/>. +- +- If you don't know what Access Control Lists are, say N +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/fs/btrfs/locking.c linux-2.6.29-rc3.owrt/fs/btrfs/locking.c +--- linux-2.6.29.owrt/fs/btrfs/locking.c 2009-05-10 22:04:39.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/fs/btrfs/locking.c 2009-05-10 23:48:29.000000000 +0200 +@@ -25,203 +25,64 @@ + #include "extent_io.h" + #include "locking.h" + +-static inline void spin_nested(struct extent_buffer *eb) +-{ +- spin_lock(&eb->lock); +-} +- +-/* +- * Setting a lock to blocking will drop the spinlock and set the +- * flag that forces other procs who want the lock to wait. After +- * this you can safely schedule with the lock held. +- */ +-void btrfs_set_lock_blocking(struct extent_buffer *eb) +-{ +- if (!test_bit(EXTENT_BUFFER_BLOCKING, &eb->bflags)) { +- set_bit(EXTENT_BUFFER_BLOCKING, &eb->bflags); +- spin_unlock(&eb->lock); +- } +- /* exit with the spin lock released and the bit set */ +-} +- + /* +- * clearing the blocking flag will take the spinlock again. +- * After this you can't safely schedule +- */ +-void btrfs_clear_lock_blocking(struct extent_buffer *eb) +-{ +- if (test_bit(EXTENT_BUFFER_BLOCKING, &eb->bflags)) { +- spin_nested(eb); +- clear_bit(EXTENT_BUFFER_BLOCKING, &eb->bflags); +- smp_mb__after_clear_bit(); +- } +- /* exit with the spin lock held */ +-} +- +-/* +- * unfortunately, many of the places that currently set a lock to blocking +- * don't end up blocking for every long, and often they don't block +- * at all. For a dbench 50 run, if we don't spin one the blocking bit +- * at all, the context switch rate can jump up to 400,000/sec or more. ++ * locks the per buffer mutex in an extent buffer. This uses adaptive locks ++ * and the spin is not tuned very extensively. The spinning does make a big ++ * difference in almost every workload, but spinning for the right amount of ++ * time needs some help. + * +- * So, we're still stuck with this crummy spin on the blocking bit, +- * at least until the most common causes of the short blocks +- * can be dealt with. ++ * In general, we want to spin as long as the lock holder is doing btree ++ * searches, and we should give up if they are in more expensive code. + */ +-static int btrfs_spin_on_block(struct extent_buffer *eb) ++ ++int btrfs_tree_lock(struct extent_buffer *eb) + { + int i; ++ ++ if (mutex_trylock(&eb->mutex)) ++ return 0; + for (i = 0; i < 512; i++) { + cpu_relax(); +- if (!test_bit(EXTENT_BUFFER_BLOCKING, &eb->bflags)) +- return 1; +- if (need_resched()) +- break; ++ if (mutex_trylock(&eb->mutex)) ++ return 0; + } ++ cpu_relax(); ++ mutex_lock_nested(&eb->mutex, BTRFS_MAX_LEVEL - btrfs_header_level(eb)); + return 0; + } + +-/* +- * This is somewhat different from trylock. It will take the +- * spinlock but if it finds the lock is set to blocking, it will +- * return without the lock held. +- * +- * returns 1 if it was able to take the lock and zero otherwise +- * +- * After this call, scheduling is not safe without first calling +- * btrfs_set_lock_blocking() +- */ +-int btrfs_try_spin_lock(struct extent_buffer *eb) ++int btrfs_try_tree_lock(struct extent_buffer *eb) + { +- int i; +- +- spin_nested(eb); +- if (!test_bit(EXTENT_BUFFER_BLOCKING, &eb->bflags)) +- return 1; +- spin_unlock(&eb->lock); +- +- /* spin for a bit on the BLOCKING flag */ +- for (i = 0; i < 2; i++) { +- if (!btrfs_spin_on_block(eb)) +- break; +- +- spin_nested(eb); +- if (!test_bit(EXTENT_BUFFER_BLOCKING, &eb->bflags)) +- return 1; +- spin_unlock(&eb->lock); +- } +- return 0; ++ return mutex_trylock(&eb->mutex); + } + +-/* +- * the autoremove wake function will return 0 if it tried to wake up +- * a process that was already awake, which means that process won't +- * count as an exclusive wakeup. The waitq code will continue waking +- * procs until it finds one that was actually sleeping. +- * +- * For btrfs, this isn't quite what we want. We want a single proc +- * to be notified that the lock is ready for taking. If that proc +- * already happen to be awake, great, it will loop around and try for +- * the lock. +- * +- * So, btrfs_wake_function always returns 1, even when the proc that we +- * tried to wake up was already awake. +- */ +-static int btrfs_wake_function(wait_queue_t *wait, unsigned mode, +- int sync, void *key) ++int btrfs_tree_unlock(struct extent_buffer *eb) + { +- autoremove_wake_function(wait, mode, sync, key); +- return 1; ++ mutex_unlock(&eb->mutex); ++ return 0; + } + +-/* +- * returns with the extent buffer spinlocked. +- * +- * This will spin and/or wait as required to take the lock, and then +- * return with the spinlock held. +- * +- * After this call, scheduling is not safe without first calling +- * btrfs_set_lock_blocking() +- */ +-int btrfs_tree_lock(struct extent_buffer *eb) ++int btrfs_tree_locked(struct extent_buffer *eb) + { +- DEFINE_WAIT(wait); +- wait.func = btrfs_wake_function; +- +- while(1) { +- spin_nested(eb); +- +- /* nobody is blocking, exit with the spinlock held */ +- if (!test_bit(EXTENT_BUFFER_BLOCKING, &eb->bflags)) +- return 0; +- +- /* +- * we have the spinlock, but the real owner is blocking. +- * wait for them +- */ +- spin_unlock(&eb->lock); +- +- /* +- * spin for a bit, and if the blocking flag goes away, +- * loop around +- */ +- if (btrfs_spin_on_block(eb)) +- continue; +- +- prepare_to_wait_exclusive(&eb->lock_wq, &wait, +- TASK_UNINTERRUPTIBLE); +- +- if (test_bit(EXTENT_BUFFER_BLOCKING, &eb->bflags)) +- schedule(); +- +- finish_wait(&eb->lock_wq, &wait); +- } +- return 0; ++ return mutex_is_locked(&eb->mutex); + } + + /* +- * Very quick trylock, this does not spin or schedule. It returns +- * 1 with the spinlock held if it was able to take the lock, or it +- * returns zero if it was unable to take the lock. +- * +- * After this call, scheduling is not safe without first calling +- * btrfs_set_lock_blocking() ++ * btrfs_search_slot uses this to decide if it should drop its locks ++ * before doing something expensive like allocating free blocks for cow. + */ +-int btrfs_try_tree_lock(struct extent_buffer *eb) ++int btrfs_path_lock_waiting(struct btrfs_path *path, int level) + { +- if (spin_trylock(&eb->lock)) { +- if (test_bit(EXTENT_BUFFER_BLOCKING, &eb->bflags)) { +- /* +- * we've got the spinlock, but the real owner is +- * blocking. Drop the spinlock and return failure +- */ +- spin_unlock(&eb->lock); +- return 0; +- } +- return 1; ++ int i; ++ struct extent_buffer *eb; ++ for (i = level; i <= level + 1 && i < BTRFS_MAX_LEVEL; i++) { ++ eb = path->nodes[i]; ++ if (!eb) ++ break; ++ smp_mb(); ++ if (!list_empty(&eb->mutex.wait_list)) ++ return 1; + } +- /* someone else has the spinlock giveup */ + return 0; + } + +-int btrfs_tree_unlock(struct extent_buffer *eb) +-{ +- /* +- * if we were a blocking owner, we don't have the spinlock held +- * just clear the bit and look for waiters +- */ +- if (test_and_clear_bit(EXTENT_BUFFER_BLOCKING, &eb->bflags)) +- smp_mb__after_clear_bit(); +- else +- spin_unlock(&eb->lock); +- +- if (waitqueue_active(&eb->lock_wq)) +- wake_up(&eb->lock_wq); +- return 0; +-} +- +-void btrfs_assert_tree_locked(struct extent_buffer *eb) +-{ +- if (!test_bit(EXTENT_BUFFER_BLOCKING, &eb->bflags)) +- assert_spin_locked(&eb->lock); +-} +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/fs/btrfs/locking.h linux-2.6.29-rc3.owrt/fs/btrfs/locking.h +--- linux-2.6.29.owrt/fs/btrfs/locking.h 2009-05-10 22:04:39.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/fs/btrfs/locking.h 2009-05-10 23:48:29.000000000 +0200 +@@ -21,11 +21,7 @@ + + int btrfs_tree_lock(struct extent_buffer *eb); + int btrfs_tree_unlock(struct extent_buffer *eb); +- ++int btrfs_tree_locked(struct extent_buffer *eb); + int btrfs_try_tree_lock(struct extent_buffer *eb); +-int btrfs_try_spin_lock(struct extent_buffer *eb); +- +-void btrfs_set_lock_blocking(struct extent_buffer *eb); +-void btrfs_clear_lock_blocking(struct extent_buffer *eb); +-void btrfs_assert_tree_locked(struct extent_buffer *eb); ++int btrfs_path_lock_waiting(struct btrfs_path *path, int level); + #endif +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/fs/btrfs/ordered-data.c linux-2.6.29-rc3.owrt/fs/btrfs/ordered-data.c +--- linux-2.6.29.owrt/fs/btrfs/ordered-data.c 2009-05-10 22:04:39.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/fs/btrfs/ordered-data.c 2009-05-10 23:48:29.000000000 +0200 +@@ -613,6 +613,7 @@ + struct btrfs_sector_sum *sector_sums; + struct btrfs_ordered_extent *ordered; + struct btrfs_ordered_inode_tree *tree = &BTRFS_I(inode)->ordered_tree; ++ struct list_head *cur; + unsigned long num_sectors; + unsigned long i; + u32 sectorsize = BTRFS_I(inode)->root->sectorsize; +@@ -623,7 +624,8 @@ + return 1; + + mutex_lock(&tree->mutex); +- list_for_each_entry_reverse(ordered_sum, &ordered->list, list) { ++ list_for_each_prev(cur, &ordered->list) { ++ ordered_sum = list_entry(cur, struct btrfs_ordered_sum, list); + if (disk_bytenr >= ordered_sum->bytenr) { + num_sectors = ordered_sum->len / sectorsize; + sector_sums = ordered_sum->sums; +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/fs/btrfs/ref-cache.c linux-2.6.29-rc3.owrt/fs/btrfs/ref-cache.c +--- linux-2.6.29.owrt/fs/btrfs/ref-cache.c 2009-05-10 22:04:39.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/fs/btrfs/ref-cache.c 2009-05-10 23:48:29.000000000 +0200 +@@ -17,7 +17,6 @@ + */ + + #include <linux/sched.h> +-#include <linux/sort.h> + #include "ctree.h" + #include "ref-cache.h" + #include "transaction.h" +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/fs/btrfs/ref-cache.h linux-2.6.29-rc3.owrt/fs/btrfs/ref-cache.h +--- linux-2.6.29.owrt/fs/btrfs/ref-cache.h 2009-05-10 22:04:39.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/fs/btrfs/ref-cache.h 2009-05-10 23:48:29.000000000 +0200 +@@ -73,4 +73,5 @@ + int btrfs_remove_leaf_refs(struct btrfs_root *root, u64 max_root_gen, + int shared); + int btrfs_remove_leaf_ref(struct btrfs_root *root, struct btrfs_leaf_ref *ref); ++ + #endif +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/fs/btrfs/super.c linux-2.6.29-rc3.owrt/fs/btrfs/super.c +--- linux-2.6.29.owrt/fs/btrfs/super.c 2009-05-10 22:04:39.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/fs/btrfs/super.c 2009-05-10 23:48:29.000000000 +0200 +@@ -37,6 +37,7 @@ + #include <linux/ctype.h> + #include <linux/namei.h> + #include <linux/miscdevice.h> ++#include <linux/version.h> + #include <linux/magic.h> + #include "compat.h" + #include "ctree.h" +@@ -379,6 +380,7 @@ + btrfs_start_delalloc_inodes(root); + btrfs_wait_ordered_extents(root, 0); + ++ btrfs_clean_old_snapshots(root); + trans = btrfs_start_transaction(root, 1); + ret = btrfs_commit_transaction(trans, root); + sb->s_dirt = 0; +@@ -510,10 +512,6 @@ + struct btrfs_root *root = btrfs_sb(sb); + int ret; + +- ret = btrfs_parse_options(root, data); +- if (ret) +- return -EINVAL; +- + if ((*flags & MS_RDONLY) == (sb->s_flags & MS_RDONLY)) + return 0; + +@@ -585,18 +583,17 @@ + struct btrfs_ioctl_vol_args *vol; + struct btrfs_fs_devices *fs_devices; + int ret = -ENOTTY; ++ int len; + + if (!capable(CAP_SYS_ADMIN)) + return -EPERM; + + vol = kmalloc(sizeof(*vol), GFP_KERNEL); +- if (!vol) +- return -ENOMEM; +- + if (copy_from_user(vol, (void __user *)arg, sizeof(*vol))) { + ret = -EFAULT; + goto out; + } ++ len = strnlen(vol->name, BTRFS_PATH_NAME_MAX); + + switch (cmd) { + case BTRFS_IOC_SCAN_DEV: +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/fs/btrfs/transaction.c linux-2.6.29-rc3.owrt/fs/btrfs/transaction.c +--- linux-2.6.29.owrt/fs/btrfs/transaction.c 2009-05-10 22:04:39.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/fs/btrfs/transaction.c 2009-05-10 23:48:29.000000000 +0200 +@@ -688,9 +688,7 @@ + num_bytes -= btrfs_root_used(&dirty->root->root_item); + bytes_used = btrfs_root_used(&root->root_item); + if (num_bytes) { +- mutex_lock(&root->fs_info->trans_mutex); + btrfs_record_root_in_trans(root); +- mutex_unlock(&root->fs_info->trans_mutex); + btrfs_set_root_used(&root->root_item, + bytes_used - num_bytes); + } +@@ -854,9 +852,11 @@ + { + struct btrfs_pending_snapshot *pending; + struct list_head *head = &trans->transaction->pending_snapshots; ++ struct list_head *cur; + int ret; + +- list_for_each_entry(pending, head, list) { ++ list_for_each(cur, head) { ++ pending = list_entry(cur, struct btrfs_pending_snapshot, list); + ret = create_pending_snapshot(trans, fs_info, pending); + BUG_ON(ret); + } +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/fs/btrfs/tree-defrag.c linux-2.6.29-rc3.owrt/fs/btrfs/tree-defrag.c +--- linux-2.6.29.owrt/fs/btrfs/tree-defrag.c 2009-05-10 22:04:39.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/fs/btrfs/tree-defrag.c 2009-05-10 23:48:29.000000000 +0200 +@@ -74,7 +74,6 @@ + u32 nritems; + + root_node = btrfs_lock_root_node(root); +- btrfs_set_lock_blocking(root_node); + nritems = btrfs_header_nritems(root_node); + root->defrag_max.objectid = 0; + /* from above we know this is not a leaf */ +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/fs/btrfs/tree-log.c linux-2.6.29-rc3.owrt/fs/btrfs/tree-log.c +--- linux-2.6.29.owrt/fs/btrfs/tree-log.c 2009-05-10 22:04:39.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/fs/btrfs/tree-log.c 2009-05-10 23:48:29.000000000 +0200 +@@ -78,6 +78,104 @@ + */ + + /* ++ * btrfs_add_log_tree adds a new per-subvolume log tree into the ++ * tree of log tree roots. This must be called with a tree log transaction ++ * running (see start_log_trans). ++ */ ++static int btrfs_add_log_tree(struct btrfs_trans_handle *trans, ++ struct btrfs_root *root) ++{ ++ struct btrfs_key key; ++ struct btrfs_root_item root_item; ++ struct btrfs_inode_item *inode_item; ++ struct extent_buffer *leaf; ++ struct btrfs_root *new_root = root; ++ int ret; ++ u64 objectid = root->root_key.objectid; ++ ++ leaf = btrfs_alloc_free_block(trans, root, root->leafsize, 0, ++ BTRFS_TREE_LOG_OBJECTID, ++ trans->transid, 0, 0, 0); ++ if (IS_ERR(leaf)) { ++ ret = PTR_ERR(leaf); ++ return ret; ++ } ++ ++ btrfs_set_header_nritems(leaf, 0); ++ btrfs_set_header_level(leaf, 0); ++ btrfs_set_header_bytenr(leaf, leaf->start); ++ btrfs_set_header_generation(leaf, trans->transid); ++ btrfs_set_header_owner(leaf, BTRFS_TREE_LOG_OBJECTID); ++ ++ write_extent_buffer(leaf, root->fs_info->fsid, ++ (unsigned long)btrfs_header_fsid(leaf), ++ BTRFS_FSID_SIZE); ++ btrfs_mark_buffer_dirty(leaf); ++ ++ inode_item = &root_item.inode; ++ memset(inode_item, 0, sizeof(*inode_item)); ++ inode_item->generation = cpu_to_le64(1); ++ inode_item->size = cpu_to_le64(3); ++ inode_item->nlink = cpu_to_le32(1); ++ inode_item->nbytes = cpu_to_le64(root->leafsize); ++ inode_item->mode = cpu_to_le32(S_IFDIR | 0755); ++ ++ btrfs_set_root_bytenr(&root_item, leaf->start); ++ btrfs_set_root_generation(&root_item, trans->transid); ++ btrfs_set_root_level(&root_item, 0); ++ btrfs_set_root_refs(&root_item, 0); ++ btrfs_set_root_used(&root_item, 0); ++ ++ memset(&root_item.drop_progress, 0, sizeof(root_item.drop_progress)); ++ root_item.drop_level = 0; ++ ++ btrfs_tree_unlock(leaf); ++ free_extent_buffer(leaf); ++ leaf = NULL; ++ ++ btrfs_set_root_dirid(&root_item, 0); ++ ++ key.objectid = BTRFS_TREE_LOG_OBJECTID; ++ key.offset = objectid; ++ btrfs_set_key_type(&key, BTRFS_ROOT_ITEM_KEY); ++ ret = btrfs_insert_root(trans, root->fs_info->log_root_tree, &key, ++ &root_item); ++ if (ret) ++ goto fail; ++ ++ new_root = btrfs_read_fs_root_no_radix(root->fs_info->log_root_tree, ++ &key); ++ BUG_ON(!new_root); ++ ++ WARN_ON(root->log_root); ++ root->log_root = new_root; ++ ++ /* ++ * log trees do not get reference counted because they go away ++ * before a real commit is actually done. They do store pointers ++ * to file data extents, and those reference counts still get ++ * updated (along with back refs to the log tree). ++ */ ++ new_root->ref_cows = 0; ++ new_root->last_trans = trans->transid; ++ ++ /* ++ * we need to make sure the root block for this new tree ++ * is marked as dirty in the dirty_log_pages tree. This ++ * is how it gets flushed down to disk at tree log commit time. ++ * ++ * the tree logging mutex keeps others from coming in and changing ++ * the new_root->node, so we can safely access it here ++ */ ++ set_extent_dirty(&new_root->dirty_log_pages, new_root->node->start, ++ new_root->node->start + new_root->node->len - 1, ++ GFP_NOFS); ++ ++fail: ++ return ret; ++} ++ ++/* + * start a sub transaction and setup the log tree + * this increments the log tree writer count to make the people + * syncing the tree wait for us to finish +@@ -86,14 +184,6 @@ + struct btrfs_root *root) + { + int ret; +- +- mutex_lock(&root->log_mutex); +- if (root->log_root) { +- root->log_batch++; +- atomic_inc(&root->log_writers); +- mutex_unlock(&root->log_mutex); +- return 0; +- } + mutex_lock(&root->fs_info->tree_log_mutex); + if (!root->fs_info->log_root_tree) { + ret = btrfs_init_log_root_tree(trans, root->fs_info); +@@ -103,10 +193,9 @@ + ret = btrfs_add_log_tree(trans, root); + BUG_ON(ret); + } ++ atomic_inc(&root->fs_info->tree_log_writers); ++ root->fs_info->tree_log_batch++; + mutex_unlock(&root->fs_info->tree_log_mutex); +- root->log_batch++; +- atomic_inc(&root->log_writers); +- mutex_unlock(&root->log_mutex); + return 0; + } + +@@ -123,12 +212,13 @@ + if (!root->log_root) + return -ENOENT; + +- mutex_lock(&root->log_mutex); ++ mutex_lock(&root->fs_info->tree_log_mutex); + if (root->log_root) { + ret = 0; +- atomic_inc(&root->log_writers); ++ atomic_inc(&root->fs_info->tree_log_writers); ++ root->fs_info->tree_log_batch++; + } +- mutex_unlock(&root->log_mutex); ++ mutex_unlock(&root->fs_info->tree_log_mutex); + return ret; + } + +@@ -138,11 +228,10 @@ + */ + static int end_log_trans(struct btrfs_root *root) + { +- if (atomic_dec_and_test(&root->log_writers)) { +- smp_mb(); +- if (waitqueue_active(&root->log_writer_wait)) +- wake_up(&root->log_writer_wait); +- } ++ atomic_dec(&root->fs_info->tree_log_writers); ++ smp_mb(); ++ if (waitqueue_active(&root->fs_info->tree_log_wait)) ++ wake_up(&root->fs_info->tree_log_wait); + return 0; + } + +@@ -1615,7 +1704,6 @@ + + btrfs_tree_lock(next); + clean_tree_block(trans, root, next); +- btrfs_set_lock_blocking(next); + btrfs_wait_tree_block_writeback(next); + btrfs_tree_unlock(next); + +@@ -1662,7 +1750,6 @@ + next = path->nodes[*level]; + btrfs_tree_lock(next); + clean_tree_block(trans, root, next); +- btrfs_set_lock_blocking(next); + btrfs_wait_tree_block_writeback(next); + btrfs_tree_unlock(next); + +@@ -1720,7 +1807,6 @@ + + btrfs_tree_lock(next); + clean_tree_block(trans, root, next); +- btrfs_set_lock_blocking(next); + btrfs_wait_tree_block_writeback(next); + btrfs_tree_unlock(next); + +@@ -1793,7 +1879,6 @@ + + btrfs_tree_lock(next); + clean_tree_block(trans, log, next); +- btrfs_set_lock_blocking(next); + btrfs_wait_tree_block_writeback(next); + btrfs_tree_unlock(next); + +@@ -1817,65 +1902,26 @@ + } + } + btrfs_free_path(path); ++ if (wc->free) ++ free_extent_buffer(log->node); + return ret; + } + +-/* +- * helper function to update the item for a given subvolumes log root +- * in the tree of log roots +- */ +-static int update_log_root(struct btrfs_trans_handle *trans, +- struct btrfs_root *log) +-{ +- int ret; +- +- if (log->log_transid == 1) { +- /* insert root item on the first sync */ +- ret = btrfs_insert_root(trans, log->fs_info->log_root_tree, +- &log->root_key, &log->root_item); +- } else { +- ret = btrfs_update_root(trans, log->fs_info->log_root_tree, +- &log->root_key, &log->root_item); +- } +- return ret; +-} +- +-static int wait_log_commit(struct btrfs_root *root, unsigned long transid) ++static int wait_log_commit(struct btrfs_root *log) + { + DEFINE_WAIT(wait); +- int index = transid % 2; ++ u64 transid = log->fs_info->tree_log_transid; + +- /* +- * we only allow two pending log transactions at a time, +- * so we know that if ours is more than 2 older than the +- * current transaction, we're done +- */ + do { +- prepare_to_wait(&root->log_commit_wait[index], +- &wait, TASK_UNINTERRUPTIBLE); +- mutex_unlock(&root->log_mutex); +- if (root->log_transid < transid + 2 && +- atomic_read(&root->log_commit[index])) ++ prepare_to_wait(&log->fs_info->tree_log_wait, &wait, ++ TASK_UNINTERRUPTIBLE); ++ mutex_unlock(&log->fs_info->tree_log_mutex); ++ if (atomic_read(&log->fs_info->tree_log_commit)) + schedule(); +- finish_wait(&root->log_commit_wait[index], &wait); +- mutex_lock(&root->log_mutex); +- } while (root->log_transid < transid + 2 && +- atomic_read(&root->log_commit[index])); +- return 0; +-} +- +-static int wait_for_writer(struct btrfs_root *root) +-{ +- DEFINE_WAIT(wait); +- while (atomic_read(&root->log_writers)) { +- prepare_to_wait(&root->log_writer_wait, +- &wait, TASK_UNINTERRUPTIBLE); +- mutex_unlock(&root->log_mutex); +- if (atomic_read(&root->log_writers)) +- schedule(); +- mutex_lock(&root->log_mutex); +- finish_wait(&root->log_writer_wait, &wait); +- } ++ finish_wait(&log->fs_info->tree_log_wait, &wait); ++ mutex_lock(&log->fs_info->tree_log_mutex); ++ } while (transid == log->fs_info->tree_log_transid && ++ atomic_read(&log->fs_info->tree_log_commit)); + return 0; + } + +@@ -1887,114 +1933,57 @@ + int btrfs_sync_log(struct btrfs_trans_handle *trans, + struct btrfs_root *root) + { +- int index1; +- int index2; + int ret; ++ unsigned long batch; + struct btrfs_root *log = root->log_root; +- struct btrfs_root *log_root_tree = root->fs_info->log_root_tree; + +- mutex_lock(&root->log_mutex); +- index1 = root->log_transid % 2; +- if (atomic_read(&root->log_commit[index1])) { +- wait_log_commit(root, root->log_transid); +- mutex_unlock(&root->log_mutex); +- return 0; ++ mutex_lock(&log->fs_info->tree_log_mutex); ++ if (atomic_read(&log->fs_info->tree_log_commit)) { ++ wait_log_commit(log); ++ goto out; + } +- atomic_set(&root->log_commit[index1], 1); +- +- /* wait for previous tree log sync to complete */ +- if (atomic_read(&root->log_commit[(index1 + 1) % 2])) +- wait_log_commit(root, root->log_transid - 1); ++ atomic_set(&log->fs_info->tree_log_commit, 1); + + while (1) { +- unsigned long batch = root->log_batch; +- mutex_unlock(&root->log_mutex); ++ batch = log->fs_info->tree_log_batch; ++ mutex_unlock(&log->fs_info->tree_log_mutex); + schedule_timeout_uninterruptible(1); +- mutex_lock(&root->log_mutex); +- wait_for_writer(root); +- if (batch == root->log_batch) ++ mutex_lock(&log->fs_info->tree_log_mutex); ++ ++ while (atomic_read(&log->fs_info->tree_log_writers)) { ++ DEFINE_WAIT(wait); ++ prepare_to_wait(&log->fs_info->tree_log_wait, &wait, ++ TASK_UNINTERRUPTIBLE); ++ mutex_unlock(&log->fs_info->tree_log_mutex); ++ if (atomic_read(&log->fs_info->tree_log_writers)) ++ schedule(); ++ mutex_lock(&log->fs_info->tree_log_mutex); ++ finish_wait(&log->fs_info->tree_log_wait, &wait); ++ } ++ if (batch == log->fs_info->tree_log_batch) + break; + } + + ret = btrfs_write_and_wait_marked_extents(log, &log->dirty_log_pages); + BUG_ON(ret); +- +- btrfs_set_root_bytenr(&log->root_item, log->node->start); +- btrfs_set_root_generation(&log->root_item, trans->transid); +- btrfs_set_root_level(&log->root_item, btrfs_header_level(log->node)); +- +- root->log_batch = 0; +- root->log_transid++; +- log->log_transid = root->log_transid; +- smp_mb(); +- /* +- * log tree has been flushed to disk, new modifications of +- * the log will be written to new positions. so it's safe to +- * allow log writers to go in. +- */ +- mutex_unlock(&root->log_mutex); +- +- mutex_lock(&log_root_tree->log_mutex); +- log_root_tree->log_batch++; +- atomic_inc(&log_root_tree->log_writers); +- mutex_unlock(&log_root_tree->log_mutex); +- +- ret = update_log_root(trans, log); +- BUG_ON(ret); +- +- mutex_lock(&log_root_tree->log_mutex); +- if (atomic_dec_and_test(&log_root_tree->log_writers)) { +- smp_mb(); +- if (waitqueue_active(&log_root_tree->log_writer_wait)) +- wake_up(&log_root_tree->log_writer_wait); +- } +- +- index2 = log_root_tree->log_transid % 2; +- if (atomic_read(&log_root_tree->log_commit[index2])) { +- wait_log_commit(log_root_tree, log_root_tree->log_transid); +- mutex_unlock(&log_root_tree->log_mutex); +- goto out; +- } +- atomic_set(&log_root_tree->log_commit[index2], 1); +- +- if (atomic_read(&log_root_tree->log_commit[(index2 + 1) % 2])) +- wait_log_commit(log_root_tree, log_root_tree->log_transid - 1); +- +- wait_for_writer(log_root_tree); +- +- ret = btrfs_write_and_wait_marked_extents(log_root_tree, +- &log_root_tree->dirty_log_pages); ++ ret = btrfs_write_and_wait_marked_extents(root->fs_info->log_root_tree, ++ &root->fs_info->log_root_tree->dirty_log_pages); + BUG_ON(ret); + + btrfs_set_super_log_root(&root->fs_info->super_for_commit, +- log_root_tree->node->start); ++ log->fs_info->log_root_tree->node->start); + btrfs_set_super_log_root_level(&root->fs_info->super_for_commit, +- btrfs_header_level(log_root_tree->node)); +- +- log_root_tree->log_batch = 0; +- log_root_tree->log_transid++; +- smp_mb(); +- +- mutex_unlock(&log_root_tree->log_mutex); +- +- /* +- * nobody else is going to jump in and write the the ctree +- * super here because the log_commit atomic below is protecting +- * us. We must be called with a transaction handle pinning +- * the running transaction open, so a full commit can't hop +- * in and cause problems either. +- */ +- write_ctree_super(trans, root->fs_info->tree_root, 2); ++ btrfs_header_level(log->fs_info->log_root_tree->node)); + +- atomic_set(&log_root_tree->log_commit[index2], 0); ++ write_ctree_super(trans, log->fs_info->tree_root, 2); ++ log->fs_info->tree_log_transid++; ++ log->fs_info->tree_log_batch = 0; ++ atomic_set(&log->fs_info->tree_log_commit, 0); + smp_mb(); +- if (waitqueue_active(&log_root_tree->log_commit_wait[index2])) +- wake_up(&log_root_tree->log_commit_wait[index2]); ++ if (waitqueue_active(&log->fs_info->tree_log_wait)) ++ wake_up(&log->fs_info->tree_log_wait); + out: +- atomic_set(&root->log_commit[index1], 0); +- smp_mb(); +- if (waitqueue_active(&root->log_commit_wait[index1])) +- wake_up(&root->log_commit_wait[index1]); ++ mutex_unlock(&log->fs_info->tree_log_mutex); + return 0; + } + +@@ -2030,18 +2019,38 @@ + start, end, GFP_NOFS); + } + +- if (log->log_transid > 0) { +- ret = btrfs_del_root(trans, root->fs_info->log_root_tree, +- &log->root_key); +- BUG_ON(ret); +- } ++ log = root->log_root; ++ ret = btrfs_del_root(trans, root->fs_info->log_root_tree, ++ &log->root_key); ++ BUG_ON(ret); + root->log_root = NULL; +- free_extent_buffer(log->node); +- kfree(log); ++ kfree(root->log_root); + return 0; + } + + /* ++ * helper function to update the item for a given subvolumes log root ++ * in the tree of log roots ++ */ ++static int update_log_root(struct btrfs_trans_handle *trans, ++ struct btrfs_root *log) ++{ ++ u64 bytenr = btrfs_root_bytenr(&log->root_item); ++ int ret; ++ ++ if (log->node->start == bytenr) ++ return 0; ++ ++ btrfs_set_root_bytenr(&log->root_item, log->node->start); ++ btrfs_set_root_generation(&log->root_item, trans->transid); ++ btrfs_set_root_level(&log->root_item, btrfs_header_level(log->node)); ++ ret = btrfs_update_root(trans, log->fs_info->log_root_tree, ++ &log->root_key, &log->root_item); ++ BUG_ON(ret); ++ return ret; ++} ++ ++/* + * If both a file and directory are logged, and unlinks or renames are + * mixed in, we have a few interesting corners: + * +@@ -2702,6 +2711,11 @@ + + btrfs_free_path(path); + btrfs_free_path(dst_path); ++ ++ mutex_lock(&root->fs_info->tree_log_mutex); ++ ret = update_log_root(trans, log); ++ BUG_ON(ret); ++ mutex_unlock(&root->fs_info->tree_log_mutex); + out: + return 0; + } +@@ -2832,9 +2846,7 @@ + BUG_ON(!wc.replay_dest); + + wc.replay_dest->log_root = log; +- mutex_lock(&fs_info->trans_mutex); + btrfs_record_root_in_trans(wc.replay_dest); +- mutex_unlock(&fs_info->trans_mutex); + ret = walk_log_tree(trans, log, &wc); + BUG_ON(ret); + +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/fs/btrfs/volumes.c linux-2.6.29-rc3.owrt/fs/btrfs/volumes.c +--- linux-2.6.29.owrt/fs/btrfs/volumes.c 2009-05-10 22:04:39.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/fs/btrfs/volumes.c 2009-05-10 23:48:29.000000000 +0200 +@@ -20,6 +20,7 @@ + #include <linux/buffer_head.h> + #include <linux/blkdev.h> + #include <linux/random.h> ++#include <linux/version.h> + #include <asm/div64.h> + #include "compat.h" + #include "ctree.h" +@@ -103,8 +104,10 @@ + u64 devid, u8 *uuid) + { + struct btrfs_device *dev; ++ struct list_head *cur; + +- list_for_each_entry(dev, head, dev_list) { ++ list_for_each(cur, head) { ++ dev = list_entry(cur, struct btrfs_device, dev_list); + if (dev->devid == devid && + (!uuid || !memcmp(dev->uuid, uuid, BTRFS_UUID_SIZE))) { + return dev; +@@ -115,9 +118,11 @@ + + static noinline struct btrfs_fs_devices *find_fsid(u8 *fsid) + { ++ struct list_head *cur; + struct btrfs_fs_devices *fs_devices; + +- list_for_each_entry(fs_devices, &fs_uuids, list) { ++ list_for_each(cur, &fs_uuids) { ++ fs_devices = list_entry(cur, struct btrfs_fs_devices, list); + if (memcmp(fsid, fs_devices->fsid, BTRFS_FSID_SIZE) == 0) + return fs_devices; + } +@@ -154,7 +159,6 @@ + loop: + spin_lock(&device->io_lock); + +-loop_lock: + /* take all the bios off the list at once and process them + * later on (without the lock held). But, remember the + * tail and other pointers so the bios can be properly reinserted +@@ -204,7 +208,7 @@ + * is now congested. Back off and let other work structs + * run instead + */ +- if (pending && bdi_write_congested(bdi) && num_run > 16 && ++ if (pending && bdi_write_congested(bdi) && + fs_info->fs_devices->open_devices > 1) { + struct bio *old_head; + +@@ -216,8 +220,7 @@ + tail->bi_next = old_head; + else + device->pending_bio_tail = tail; +- +- device->running_pending = 1; ++ device->running_pending = 0; + + spin_unlock(&device->io_lock); + btrfs_requeue_work(&device->work); +@@ -226,11 +229,6 @@ + } + if (again) + goto loop; +- +- spin_lock(&device->io_lock); +- if (device->pending_bios) +- goto loop_lock; +- spin_unlock(&device->io_lock); + done: + return 0; + } +@@ -347,11 +345,14 @@ + + int btrfs_close_extra_devices(struct btrfs_fs_devices *fs_devices) + { +- struct btrfs_device *device, *next; ++ struct list_head *tmp; ++ struct list_head *cur; ++ struct btrfs_device *device; + + mutex_lock(&uuid_mutex); + again: +- list_for_each_entry_safe(device, next, &fs_devices->devices, dev_list) { ++ list_for_each_safe(cur, tmp, &fs_devices->devices) { ++ device = list_entry(cur, struct btrfs_device, dev_list); + if (device->in_fs_metadata) + continue; + +@@ -382,12 +383,14 @@ + + static int __btrfs_close_devices(struct btrfs_fs_devices *fs_devices) + { ++ struct list_head *cur; + struct btrfs_device *device; + + if (--fs_devices->opened > 0) + return 0; + +- list_for_each_entry(device, &fs_devices->devices, dev_list) { ++ list_for_each(cur, &fs_devices->devices) { ++ device = list_entry(cur, struct btrfs_device, dev_list); + if (device->bdev) { + close_bdev_exclusive(device->bdev, device->mode); + fs_devices->open_devices--; +@@ -436,6 +439,7 @@ + { + struct block_device *bdev; + struct list_head *head = &fs_devices->devices; ++ struct list_head *cur; + struct btrfs_device *device; + struct block_device *latest_bdev = NULL; + struct buffer_head *bh; +@@ -446,7 +450,8 @@ + int seeding = 1; + int ret = 0; + +- list_for_each_entry(device, head, dev_list) { ++ list_for_each(cur, head) { ++ device = list_entry(cur, struct btrfs_device, dev_list); + if (device->bdev) + continue; + if (!device->name) +@@ -573,7 +578,7 @@ + *(unsigned long long *)disk_super->fsid, + *(unsigned long long *)(disk_super->fsid + 8)); + } +- printk(KERN_CONT "devid %llu transid %llu %s\n", ++ printk(KERN_INFO "devid %llu transid %llu %s\n", + (unsigned long long)devid, (unsigned long long)transid, path); + ret = device_list_add(path, disk_super, devid, fs_devices_ret); + +@@ -1012,12 +1017,14 @@ + } + + if (strcmp(device_path, "missing") == 0) { ++ struct list_head *cur; + struct list_head *devices; + struct btrfs_device *tmp; + + device = NULL; + devices = &root->fs_info->fs_devices->devices; +- list_for_each_entry(tmp, devices, dev_list) { ++ list_for_each(cur, devices) { ++ tmp = list_entry(cur, struct btrfs_device, dev_list); + if (tmp->in_fs_metadata && !tmp->bdev) { + device = tmp; + break; +@@ -1273,6 +1280,7 @@ + struct btrfs_trans_handle *trans; + struct btrfs_device *device; + struct block_device *bdev; ++ struct list_head *cur; + struct list_head *devices; + struct super_block *sb = root->fs_info->sb; + u64 total_bytes; +@@ -1296,7 +1304,8 @@ + mutex_lock(&root->fs_info->volume_mutex); + + devices = &root->fs_info->fs_devices->devices; +- list_for_each_entry(device, devices, dev_list) { ++ list_for_each(cur, devices) { ++ device = list_entry(cur, struct btrfs_device, dev_list); + if (device->bdev == bdev) { + ret = -EEXIST; + goto error; +@@ -1374,12 +1383,6 @@ + ret = btrfs_add_device(trans, root, device); + } + +- /* +- * we've got more storage, clear any full flags on the space +- * infos +- */ +- btrfs_clear_space_info_full(root->fs_info); +- + unlock_chunks(root); + btrfs_commit_transaction(trans, root); + +@@ -1465,8 +1468,6 @@ + device->fs_devices->total_rw_bytes += diff; + + device->total_bytes = new_size; +- btrfs_clear_space_info_full(device->dev_root->fs_info); +- + return btrfs_update_device(trans, device); + } + +@@ -1703,6 +1704,7 @@ + int btrfs_balance(struct btrfs_root *dev_root) + { + int ret; ++ struct list_head *cur; + struct list_head *devices = &dev_root->fs_info->fs_devices->devices; + struct btrfs_device *device; + u64 old_size; +@@ -1721,7 +1723,8 @@ + dev_root = dev_root->fs_info->dev_root; + + /* step one make some room on all the devices */ +- list_for_each_entry(device, devices, dev_list) { ++ list_for_each(cur, devices) { ++ device = list_entry(cur, struct btrfs_device, dev_list); + old_size = device->total_bytes; + size_to_free = div_factor(old_size, 1); + size_to_free = min(size_to_free, (u64)1 * 1024 * 1024); +@@ -2902,6 +2905,10 @@ + free_extent_map(em); + } + ++ map = kzalloc(sizeof(*map), GFP_NOFS); ++ if (!map) ++ return -ENOMEM; ++ + em = alloc_extent_map(GFP_NOFS); + if (!em) + return -ENOMEM; +@@ -3110,8 +3117,6 @@ + if (!sb) + return -ENOMEM; + btrfs_set_buffer_uptodate(sb); +- btrfs_set_buffer_lockdep_class(sb, 0); +- + write_extent_buffer(sb, super_copy, 0, BTRFS_SUPER_INFO_SIZE); + array_size = btrfs_super_sys_array_size(super_copy); + +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/fs/btrfs/xattr.c linux-2.6.29-rc3.owrt/fs/btrfs/xattr.c +--- linux-2.6.29.owrt/fs/btrfs/xattr.c 2009-05-10 22:04:39.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/fs/btrfs/xattr.c 2009-05-10 23:48:29.000000000 +0200 +@@ -21,7 +21,6 @@ + #include <linux/slab.h> + #include <linux/rwsem.h> + #include <linux/xattr.h> +-#include <linux/security.h> + #include "ctree.h" + #include "btrfs_inode.h" + #include "transaction.h" +@@ -46,12 +45,9 @@ + /* lookup the xattr by name */ + di = btrfs_lookup_xattr(NULL, root, path, inode->i_ino, name, + strlen(name), 0); +- if (!di) { ++ if (!di || IS_ERR(di)) { + ret = -ENODATA; + goto out; +- } else if (IS_ERR(di)) { +- ret = PTR_ERR(di); +- goto out; + } + + leaf = path->nodes[0]; +@@ -66,14 +62,6 @@ + ret = -ERANGE; + goto out; + } +- +- /* +- * The way things are packed into the leaf is like this +- * |struct btrfs_dir_item|name|data| +- * where name is the xattr name, so security.foo, and data is the +- * content of the xattr. data_ptr points to the location in memory +- * where the data starts in the in memory leaf +- */ + data_ptr = (unsigned long)((char *)(di + 1) + + btrfs_dir_name_len(leaf, di)); + read_extent_buffer(leaf, buffer, data_ptr, +@@ -98,7 +86,7 @@ + if (!path) + return -ENOMEM; + +- trans = btrfs_join_transaction(root, 1); ++ trans = btrfs_start_transaction(root, 1); + btrfs_set_trans_block_group(trans, inode); + + /* first lets see if we already have this xattr */ +@@ -188,6 +176,7 @@ + ret = btrfs_search_slot(NULL, root, &key, path, 0, 0); + if (ret < 0) + goto err; ++ ret = 0; + advance = 0; + while (1) { + leaf = path->nodes[0]; +@@ -331,34 +320,3 @@ + return -EOPNOTSUPP; + return __btrfs_setxattr(dentry->d_inode, name, NULL, 0, XATTR_REPLACE); + } +- +-int btrfs_xattr_security_init(struct inode *inode, struct inode *dir) +-{ +- int err; +- size_t len; +- void *value; +- char *suffix; +- char *name; +- +- err = security_inode_init_security(inode, dir, &suffix, &value, &len); +- if (err) { +- if (err == -EOPNOTSUPP) +- return 0; +- return err; +- } +- +- name = kmalloc(XATTR_SECURITY_PREFIX_LEN + strlen(suffix) + 1, +- GFP_NOFS); +- if (!name) { +- err = -ENOMEM; +- } else { +- strcpy(name, XATTR_SECURITY_PREFIX); +- strcpy(name + XATTR_SECURITY_PREFIX_LEN, suffix); +- err = __btrfs_setxattr(inode, name, value, len, 0); +- kfree(name); +- } +- +- kfree(suffix); +- kfree(value); +- return err; +-} +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/fs/btrfs/xattr.h linux-2.6.29-rc3.owrt/fs/btrfs/xattr.h +--- linux-2.6.29.owrt/fs/btrfs/xattr.h 2009-05-10 22:04:39.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/fs/btrfs/xattr.h 2009-05-10 23:48:29.000000000 +0200 +@@ -36,6 +36,4 @@ + const void *value, size_t size, int flags); + extern int btrfs_removexattr(struct dentry *dentry, const char *name); + +-extern int btrfs_xattr_security_init(struct inode *inode, struct inode *dir); +- + #endif /* __XATTR__ */ +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/fs/buffer.c linux-2.6.29-rc3.owrt/fs/buffer.c +--- linux-2.6.29.owrt/fs/buffer.c 2009-05-10 22:04:39.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/fs/buffer.c 2009-05-10 23:48:29.000000000 +0200 +@@ -760,9 +760,15 @@ + * If warn is true, then emit a warning if the page is not uptodate and has + * not been truncated. + */ +-static void __set_page_dirty(struct page *page, ++static int __set_page_dirty(struct page *page, + struct address_space *mapping, int warn) + { ++ if (unlikely(!mapping)) ++ return !TestSetPageDirty(page); ++ ++ if (TestSetPageDirty(page)) ++ return 0; ++ + spin_lock_irq(&mapping->tree_lock); + if (page->mapping) { /* Race with truncate? */ + WARN_ON_ONCE(warn && !PageUptodate(page)); +@@ -771,7 +777,6 @@ + __inc_zone_page_state(page, NR_FILE_DIRTY); + __inc_bdi_stat(mapping->backing_dev_info, + BDI_RECLAIMABLE); +- task_dirty_inc(current); + task_io_account_write(PAGE_CACHE_SIZE); + } + radix_tree_tag_set(&mapping->page_tree, +@@ -779,6 +784,8 @@ + } + spin_unlock_irq(&mapping->tree_lock); + __mark_inode_dirty(mapping->host, I_DIRTY_PAGES); ++ ++ return 1; + } + + /* +@@ -808,7 +815,6 @@ + */ + int __set_page_dirty_buffers(struct page *page) + { +- int newly_dirty; + struct address_space *mapping = page_mapping(page); + + if (unlikely(!mapping)) +@@ -824,12 +830,9 @@ + bh = bh->b_this_page; + } while (bh != head); + } +- newly_dirty = !TestSetPageDirty(page); + spin_unlock(&mapping->private_lock); + +- if (newly_dirty) +- __set_page_dirty(page, mapping, 1); +- return newly_dirty; ++ return __set_page_dirty(page, mapping, 1); + } + EXPORT_SYMBOL(__set_page_dirty_buffers); + +@@ -1258,11 +1261,8 @@ + return; + } + +- if (!test_set_buffer_dirty(bh)) { +- struct page *page = bh->b_page; +- if (!TestSetPageDirty(page)) +- __set_page_dirty(page, page_mapping(page), 0); +- } ++ if (!test_set_buffer_dirty(bh)) ++ __set_page_dirty(bh->b_page, page_mapping(bh->b_page), 0); + } + + /* +@@ -2688,7 +2688,7 @@ + struct buffer_head *bh; + BUG_ON(fsdata != NULL && page_has_buffers(page)); + +- if (unlikely(copied < len) && head) ++ if (unlikely(copied < len) && !page_has_buffers(page)) + attach_nobh_buffers(page, head); + if (page_has_buffers(page)) + return generic_write_end(file, mapping, pos, len, +@@ -3108,7 +3108,7 @@ + if (test_clear_buffer_dirty(bh)) { + get_bh(bh); + bh->b_end_io = end_buffer_write_sync; +- ret = submit_bh(WRITE, bh); ++ ret = submit_bh(WRITE_SYNC, bh); + wait_on_buffer(bh); + if (buffer_eopnotsupp(bh)) { + clear_buffer_eopnotsupp(bh); +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/fs/cifs/CHANGES linux-2.6.29-rc3.owrt/fs/cifs/CHANGES +--- linux-2.6.29.owrt/fs/cifs/CHANGES 2009-05-10 22:04:39.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/fs/cifs/CHANGES 2009-05-10 23:48:29.000000000 +0200 +@@ -1,13 +1,3 @@ +-Version 1.57 +------------- +-Improve support for multiple security contexts to the same server. We +-used to use the same "vcnumber" for all connections which could cause +-the server to treat subsequent connections, especially those that +-are authenticated as guest, as reconnections, invalidating the earlier +-user's smb session. This fix allows cifs to mount multiple times to the +-same server with different userids without risking invalidating earlier +-established security contexts. +- + Version 1.56 + ------------ + Add "forcemandatorylock" mount option to allow user to use mandatory +@@ -15,12 +5,7 @@ + support posix byte range locks. Fix query of root inode when prefixpath + specified and user does not have access to query information about the + top of the share. Fix problem in 2.6.28 resolving DFS paths to +-Samba servers (worked to Windows). Fix rmdir so that pending search +-(readdir) requests do not get invalid results which include the now +-removed directory. Fix oops in cifs_dfs_ref.c when prefixpath is not reachable +-when using DFS. Add better file create support to servers which support +-the CIFS POSIX protocol extensions (this adds support for new flags +-on create, and improves semantics for write of locked ranges). ++Samba servers (worked to Windows). + + Version 1.55 + ------------ +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/fs/cifs/cifsencrypt.c linux-2.6.29-rc3.owrt/fs/cifs/cifsencrypt.c +--- linux-2.6.29.owrt/fs/cifs/cifsencrypt.c 2009-05-10 22:04:39.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/fs/cifs/cifsencrypt.c 2009-05-10 23:48:29.000000000 +0200 +@@ -48,11 +48,11 @@ + if ((cifs_pdu == NULL) || (signature == NULL) || (key == NULL)) + return -EINVAL; + +- cifs_MD5_init(&context); +- cifs_MD5_update(&context, (char *)&key->data, key->len); +- cifs_MD5_update(&context, cifs_pdu->Protocol, cifs_pdu->smb_buf_length); ++ MD5Init(&context); ++ MD5Update(&context, (char *)&key->data, key->len); ++ MD5Update(&context, cifs_pdu->Protocol, cifs_pdu->smb_buf_length); + +- cifs_MD5_final(signature, &context); ++ MD5Final(signature, &context); + return 0; + } + +@@ -96,8 +96,8 @@ + if ((iov == NULL) || (signature == NULL) || (key == NULL)) + return -EINVAL; + +- cifs_MD5_init(&context); +- cifs_MD5_update(&context, (char *)&key->data, key->len); ++ MD5Init(&context); ++ MD5Update(&context, (char *)&key->data, key->len); + for (i = 0; i < n_vec; i++) { + if (iov[i].iov_len == 0) + continue; +@@ -110,13 +110,13 @@ + if (i == 0) { + if (iov[0].iov_len <= 8) /* cmd field at offset 9 */ + break; /* nothing to sign or corrupt header */ +- cifs_MD5_update(&context, iov[0].iov_base+4, ++ MD5Update(&context, iov[0].iov_base+4, + iov[0].iov_len-4); + } else +- cifs_MD5_update(&context, iov[i].iov_base, iov[i].iov_len); ++ MD5Update(&context, iov[i].iov_base, iov[i].iov_len); + } + +- cifs_MD5_final(signature, &context); ++ MD5Final(signature, &context); + + return 0; + } +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/fs/cifs/cifsfs.h linux-2.6.29-rc3.owrt/fs/cifs/cifsfs.h +--- linux-2.6.29.owrt/fs/cifs/cifsfs.h 2009-05-10 22:04:39.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/fs/cifs/cifsfs.h 2009-05-10 23:48:29.000000000 +0200 +@@ -100,5 +100,5 @@ + extern const struct export_operations cifs_export_ops; + #endif /* EXPERIMENTAL */ + +-#define CIFS_VERSION "1.57" ++#define CIFS_VERSION "1.56" + #endif /* _CIFSFS_H */ +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/fs/cifs/cifsglob.h linux-2.6.29-rc3.owrt/fs/cifs/cifsglob.h +--- linux-2.6.29.owrt/fs/cifs/cifsglob.h 2009-05-10 22:04:39.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/fs/cifs/cifsglob.h 2009-05-10 23:48:29.000000000 +0200 +@@ -164,12 +164,9 @@ + /* multiplexed reads or writes */ + unsigned int maxBuf; /* maxBuf specifies the maximum */ + /* message size the server can send or receive for non-raw SMBs */ +- unsigned int max_rw; /* maxRw specifies the maximum */ ++ unsigned int maxRw; /* maxRw specifies the maximum */ + /* message size the server can send or receive for */ + /* SMB_COM_WRITE_RAW or SMB_COM_READ_RAW. */ +- unsigned int max_vcs; /* maximum number of smb sessions, at least +- those that can be specified uniquely with +- vcnumbers */ + char sessid[4]; /* unique token id for this session */ + /* (returned on Negotiate */ + int capabilities; /* allow selective disabling of caps by smb sess */ +@@ -213,7 +210,6 @@ + unsigned overrideSecFlg; /* if non-zero override global sec flags */ + __u16 ipc_tid; /* special tid for connection to IPC share */ + __u16 flags; +- __u16 vcnum; + char *serverOS; /* name of operating system underlying server */ + char *serverNOS; /* name of network operating system of server */ + char *serverDomain; /* security realm of server */ +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/fs/cifs/cifsproto.h linux-2.6.29-rc3.owrt/fs/cifs/cifsproto.h +--- linux-2.6.29.owrt/fs/cifs/cifsproto.h 2009-05-10 22:04:39.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/fs/cifs/cifsproto.h 2009-05-10 23:48:29.000000000 +0200 +@@ -35,14 +35,13 @@ + extern void cifs_buf_release(void *); + extern struct smb_hdr *cifs_small_buf_get(void); + extern void cifs_small_buf_release(void *); +-extern int smb_send(struct TCP_Server_Info *, struct smb_hdr *, +- unsigned int /* length */); ++extern int smb_send(struct socket *, struct smb_hdr *, ++ unsigned int /* length */ , struct sockaddr *, bool); + extern unsigned int _GetXid(void); + extern void _FreeXid(unsigned int); + #define GetXid() (int)_GetXid(); cFYI(1,("CIFS VFS: in %s as Xid: %d with uid: %d",__func__, xid,current_fsuid())); + #define FreeXid(curr_xid) {_FreeXid(curr_xid); cFYI(1,("CIFS VFS: leaving %s (xid = %d) rc = %d",__func__,curr_xid,(int)rc));} + extern char *build_path_from_dentry(struct dentry *); +-extern char *cifs_build_path_to_root(struct cifs_sb_info *cifs_sb); + extern char *build_wildcard_path_from_dentry(struct dentry *direntry); + /* extern void renew_parental_timestamps(struct dentry *direntry);*/ + extern int SendReceive(const unsigned int /* xid */ , struct cifsSesInfo *, +@@ -92,9 +91,6 @@ + extern __le64 cnvrtDosCifsTm(__u16 date, __u16 time); + extern struct timespec cnvrtDosUnixTm(__u16 date, __u16 time); + +-extern void posix_fill_in_inode(struct inode *tmp_inode, +- FILE_UNIX_BASIC_INFO *pData, int isNewInode); +-extern struct inode *cifs_new_inode(struct super_block *sb, __u64 *inum); + extern int cifs_get_inode_info(struct inode **pinode, + const unsigned char *search_path, + FILE_ALL_INFO *pfile_info, +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/fs/cifs/cifssmb.c linux-2.6.29-rc3.owrt/fs/cifs/cifssmb.c +--- linux-2.6.29.owrt/fs/cifs/cifssmb.c 2009-05-10 22:04:39.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/fs/cifs/cifssmb.c 2009-05-10 23:48:29.000000000 +0200 +@@ -528,15 +528,14 @@ + server->maxReq = le16_to_cpu(rsp->MaxMpxCount); + server->maxBuf = min((__u32)le16_to_cpu(rsp->MaxBufSize), + (__u32)CIFSMaxBufSize + MAX_CIFS_HDR_SIZE); +- server->max_vcs = le16_to_cpu(rsp->MaxNumberVcs); + GETU32(server->sessid) = le32_to_cpu(rsp->SessionKey); + /* even though we do not use raw we might as well set this + accurately, in case we ever find a need for it */ + if ((le16_to_cpu(rsp->RawMode) & RAW_ENABLE) == RAW_ENABLE) { +- server->max_rw = 0xFF00; ++ server->maxRw = 0xFF00; + server->capabilities = CAP_MPX_MODE | CAP_RAW_MODE; + } else { +- server->max_rw = 0;/* do not need to use raw anyway */ ++ server->maxRw = 0;/* we do not need to use raw anyway */ + server->capabilities = CAP_MPX_MODE; + } + tmp = (__s16)le16_to_cpu(rsp->ServerTimeZone); +@@ -639,7 +638,7 @@ + /* probably no need to store and check maxvcs */ + server->maxBuf = min(le32_to_cpu(pSMBr->MaxBufferSize), + (__u32) CIFSMaxBufSize + MAX_CIFS_HDR_SIZE); +- server->max_rw = le32_to_cpu(pSMBr->MaxRawSize); ++ server->maxRw = le32_to_cpu(pSMBr->MaxRawSize); + cFYI(DBG2, ("Max buf = %d", ses->server->maxBuf)); + GETU32(ses->server->sessid) = le32_to_cpu(pSMBr->SessionKey); + server->capabilities = le32_to_cpu(pSMBr->Capabilities); +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/fs/cifs/connect.c linux-2.6.29-rc3.owrt/fs/cifs/connect.c +--- linux-2.6.29.owrt/fs/cifs/connect.c 2009-05-10 22:04:39.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/fs/cifs/connect.c 2009-05-10 23:48:29.000000000 +0200 +@@ -23,6 +23,7 @@ + #include <linux/string.h> + #include <linux/list.h> + #include <linux/wait.h> ++#include <linux/ipv6.h> + #include <linux/pagemap.h> + #include <linux/ctype.h> + #include <linux/utsname.h> +@@ -34,7 +35,6 @@ + #include <linux/freezer.h> + #include <asm/uaccess.h> + #include <asm/processor.h> +-#include <net/ipv6.h> + #include "cifspdu.h" + #include "cifsglob.h" + #include "cifsproto.h" +@@ -1354,7 +1354,7 @@ + } + + static struct TCP_Server_Info * +-cifs_find_tcp_session(struct sockaddr_storage *addr) ++cifs_find_tcp_session(struct sockaddr *addr) + { + struct list_head *tmp; + struct TCP_Server_Info *server; +@@ -1374,13 +1374,13 @@ + if (server->tcpStatus == CifsNew) + continue; + +- if (addr->ss_family == AF_INET && ++ if (addr->sa_family == AF_INET && + (addr4->sin_addr.s_addr != + server->addr.sockAddr.sin_addr.s_addr)) + continue; +- else if (addr->ss_family == AF_INET6 && +- !ipv6_addr_equal(&server->addr.sockAddr6.sin6_addr, +- &addr6->sin6_addr)) ++ else if (addr->sa_family == AF_INET6 && ++ memcmp(&server->addr.sockAddr6.sin6_addr, ++ &addr6->sin6_addr, sizeof(addr6->sin6_addr))) + continue; + + ++server->srv_count; +@@ -1419,12 +1419,12 @@ + cifs_get_tcp_session(struct smb_vol *volume_info) + { + struct TCP_Server_Info *tcp_ses = NULL; +- struct sockaddr_storage addr; ++ struct sockaddr addr; + struct sockaddr_in *sin_server = (struct sockaddr_in *) &addr; + struct sockaddr_in6 *sin_server6 = (struct sockaddr_in6 *) &addr; + int rc; + +- memset(&addr, 0, sizeof(struct sockaddr_storage)); ++ memset(&addr, 0, sizeof(struct sockaddr)); + + if (volume_info->UNCip && volume_info->UNC) { + rc = cifs_inet_pton(AF_INET, volume_info->UNCip, +@@ -1435,9 +1435,9 @@ + rc = cifs_inet_pton(AF_INET6, volume_info->UNCip, + &sin_server6->sin6_addr.in6_u); + if (rc > 0) +- addr.ss_family = AF_INET6; ++ addr.sa_family = AF_INET6; + } else { +- addr.ss_family = AF_INET; ++ addr.sa_family = AF_INET; + } + + if (rc <= 0) { +@@ -1502,7 +1502,7 @@ + tcp_ses->tcpStatus = CifsNew; + ++tcp_ses->srv_count; + +- if (addr.ss_family == AF_INET6) { ++ if (addr.sa_family == AF_INET6) { + cFYI(1, ("attempting ipv6 connect")); + /* BB should we allow ipv6 on port 139? */ + /* other OS never observed in Wild doing 139 with v6 */ +@@ -1802,7 +1802,7 @@ + * user space buffer + */ + socket->sk->sk_rcvtimeo = 7 * HZ; +- socket->sk->sk_sndtimeo = 5 * HZ; ++ socket->sk->sk_sndtimeo = 3 * HZ; + + /* make the bufsizes depend on wsize/rsize and max requests */ + if (server->noautotune) { +@@ -1860,7 +1860,9 @@ + smb_buf = (struct smb_hdr *)ses_init_buf; + /* sizeof RFC1002_SESSION_REQUEST with no scope */ + smb_buf->smb_buf_length = 0x81000044; +- rc = smb_send(server, smb_buf, 0x44); ++ rc = smb_send(socket, smb_buf, 0x44, ++ (struct sockaddr *) &server->addr.sockAddr, ++ server->noblocksnd); + kfree(ses_init_buf); + msleep(1); /* RFC1001 layer in at least one server + requires very short break before negprot +@@ -1953,7 +1955,7 @@ + * user space buffer + */ + socket->sk->sk_rcvtimeo = 7 * HZ; +- socket->sk->sk_sndtimeo = 5 * HZ; ++ socket->sk->sk_sndtimeo = 3 * HZ; + server->ssocket = socket; + + return rc; +@@ -2180,33 +2182,6 @@ + "mount option supported")); + } + +-static int +-is_path_accessible(int xid, struct cifsTconInfo *tcon, +- struct cifs_sb_info *cifs_sb, const char *full_path) +-{ +- int rc; +- __u64 inode_num; +- FILE_ALL_INFO *pfile_info; +- +- rc = CIFSGetSrvInodeNumber(xid, tcon, full_path, &inode_num, +- cifs_sb->local_nls, +- cifs_sb->mnt_cifs_flags & +- CIFS_MOUNT_MAP_SPECIAL_CHR); +- if (rc != -EOPNOTSUPP) +- return rc; +- +- pfile_info = kmalloc(sizeof(FILE_ALL_INFO), GFP_KERNEL); +- if (pfile_info == NULL) +- return -ENOMEM; +- +- rc = CIFSSMBQPathInfo(xid, tcon, full_path, pfile_info, +- 0 /* not legacy */, cifs_sb->local_nls, +- cifs_sb->mnt_cifs_flags & +- CIFS_MOUNT_MAP_SPECIAL_CHR); +- kfree(pfile_info); +- return rc; +-} +- + int + cifs_mount(struct super_block *sb, struct cifs_sb_info *cifs_sb, + char *mount_data, const char *devname) +@@ -2217,7 +2192,6 @@ + struct cifsSesInfo *pSesInfo = NULL; + struct cifsTconInfo *tcon = NULL; + struct TCP_Server_Info *srvTcp = NULL; +- char *full_path; + + xid = GetXid(); + +@@ -2454,23 +2428,6 @@ + cifs_sb->rsize = min(cifs_sb->rsize, + (tcon->ses->server->maxBuf - MAX_CIFS_HDR_SIZE)); + +- if (!rc && cifs_sb->prepathlen) { +- /* build_path_to_root works only when we have a valid tcon */ +- full_path = cifs_build_path_to_root(cifs_sb); +- if (full_path == NULL) { +- rc = -ENOMEM; +- goto mount_fail_check; +- } +- rc = is_path_accessible(xid, tcon, cifs_sb, full_path); +- if (rc) { +- cERROR(1, ("Path %s in not accessible: %d", +- full_path, rc)); +- kfree(full_path); +- goto mount_fail_check; +- } +- kfree(full_path); +- } +- + /* volume_info->password is freed above when existing session found + (in which case it is not needed anymore) but when new sesion is created + the password ptr is put in the new session structure (in which case the +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/fs/cifs/dir.c linux-2.6.29-rc3.owrt/fs/cifs/dir.c +--- linux-2.6.29.owrt/fs/cifs/dir.c 2009-05-10 22:04:39.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/fs/cifs/dir.c 2009-05-10 23:48:29.000000000 +0200 +@@ -3,7 +3,7 @@ + * + * vfs operations that deal with dentries + * +- * Copyright (C) International Business Machines Corp., 2002,2009 ++ * Copyright (C) International Business Machines Corp., 2002,2008 + * Author(s): Steve French (sfrench@us.ibm.com) + * + * This library is free software; you can redistribute it and/or modify +@@ -129,89 +129,6 @@ + return full_path; + } + +-static int cifs_posix_open(char *full_path, struct inode **pinode, +- struct super_block *sb, int mode, int oflags, +- int *poplock, __u16 *pnetfid, int xid) +-{ +- int rc; +- __u32 oplock; +- FILE_UNIX_BASIC_INFO *presp_data; +- __u32 posix_flags = 0; +- struct cifs_sb_info *cifs_sb = CIFS_SB(sb); +- +- cFYI(1, ("posix open %s", full_path)); +- +- presp_data = kzalloc(sizeof(FILE_UNIX_BASIC_INFO), GFP_KERNEL); +- if (presp_data == NULL) +- return -ENOMEM; +- +-/* So far cifs posix extensions can only map the following flags. +- There are other valid fmode oflags such as FMODE_LSEEK, FMODE_PREAD, but +- so far we do not seem to need them, and we can treat them as local only */ +- if ((oflags & (FMODE_READ | FMODE_WRITE)) == +- (FMODE_READ | FMODE_WRITE)) +- posix_flags = SMB_O_RDWR; +- else if (oflags & FMODE_READ) +- posix_flags = SMB_O_RDONLY; +- else if (oflags & FMODE_WRITE) +- posix_flags = SMB_O_WRONLY; +- if (oflags & O_CREAT) +- posix_flags |= SMB_O_CREAT; +- if (oflags & O_EXCL) +- posix_flags |= SMB_O_EXCL; +- if (oflags & O_TRUNC) +- posix_flags |= SMB_O_TRUNC; +- if (oflags & O_APPEND) +- posix_flags |= SMB_O_APPEND; +- if (oflags & O_SYNC) +- posix_flags |= SMB_O_SYNC; +- if (oflags & O_DIRECTORY) +- posix_flags |= SMB_O_DIRECTORY; +- if (oflags & O_NOFOLLOW) +- posix_flags |= SMB_O_NOFOLLOW; +- if (oflags & O_DIRECT) +- posix_flags |= SMB_O_DIRECT; +- +- +- rc = CIFSPOSIXCreate(xid, cifs_sb->tcon, posix_flags, mode, +- pnetfid, presp_data, &oplock, full_path, +- cifs_sb->local_nls, cifs_sb->mnt_cifs_flags & +- CIFS_MOUNT_MAP_SPECIAL_CHR); +- if (rc) +- goto posix_open_ret; +- +- if (presp_data->Type == cpu_to_le32(-1)) +- goto posix_open_ret; /* open ok, caller does qpathinfo */ +- +- /* get new inode and set it up */ +- if (!pinode) +- goto posix_open_ret; /* caller does not need info */ +- +- *pinode = cifs_new_inode(sb, &presp_data->UniqueId); +- +- /* We do not need to close the file if new_inode fails since +- the caller will retry qpathinfo as long as inode is null */ +- if (*pinode == NULL) +- goto posix_open_ret; +- +- posix_fill_in_inode(*pinode, presp_data, 1); +- +-posix_open_ret: +- kfree(presp_data); +- return rc; +-} +- +-static void setup_cifs_dentry(struct cifsTconInfo *tcon, +- struct dentry *direntry, +- struct inode *newinode) +-{ +- if (tcon->nocase) +- direntry->d_op = &cifs_ci_dentry_ops; +- else +- direntry->d_op = &cifs_dentry_ops; +- d_instantiate(direntry, newinode); +-} +- + /* Inode operations in similar order to how they appear in Linux file fs.h */ + + int +@@ -222,21 +139,14 @@ + int xid; + int create_options = CREATE_NOT_DIR; + int oplock = 0; +- int oflags; +- /* +- * BB below access is probably too much for mknod to request +- * but we have to do query and setpathinfo so requesting +- * less could fail (unless we want to request getatr and setatr +- * permissions (only). At least for POSIX we do not have to +- * request so much. +- */ + int desiredAccess = GENERIC_READ | GENERIC_WRITE; + __u16 fileHandle; + struct cifs_sb_info *cifs_sb; +- struct cifsTconInfo *tcon; ++ struct cifsTconInfo *pTcon; + char *full_path = NULL; + FILE_ALL_INFO *buf = NULL; + struct inode *newinode = NULL; ++ struct cifsFileInfo *pCifsFile = NULL; + struct cifsInodeInfo *pCifsInode; + int disposition = FILE_OVERWRITE_IF; + bool write_only = false; +@@ -244,7 +154,7 @@ + xid = GetXid(); + + cifs_sb = CIFS_SB(inode->i_sb); +- tcon = cifs_sb->tcon; ++ pTcon = cifs_sb->tcon; + + full_path = build_path_from_dentry(direntry); + if (full_path == NULL) { +@@ -252,44 +162,12 @@ + return -ENOMEM; + } + +- mode &= ~current->fs->umask; +- if (oplockEnabled) +- oplock = REQ_OPLOCK; +- +- if (nd && (nd->flags & LOOKUP_OPEN)) +- oflags = nd->intent.open.flags; +- else +- oflags = FMODE_READ; +- +- if (tcon->unix_ext && (tcon->ses->capabilities & CAP_UNIX) && +- (CIFS_UNIX_POSIX_PATH_OPS_CAP & +- le64_to_cpu(tcon->fsUnixInfo.Capability))) { +- rc = cifs_posix_open(full_path, &newinode, inode->i_sb, +- mode, oflags, &oplock, &fileHandle, xid); +- /* EIO could indicate that (posix open) operation is not +- supported, despite what server claimed in capability +- negotation. EREMOTE indicates DFS junction, which is not +- handled in posix open */ +- +- if ((rc == 0) && (newinode == NULL)) +- goto cifs_create_get_file_info; /* query inode info */ +- else if (rc == 0) /* success, no need to query */ +- goto cifs_create_set_dentry; +- else if ((rc != -EIO) && (rc != -EREMOTE) && +- (rc != -EOPNOTSUPP)) /* path not found or net err */ +- goto cifs_create_out; +- /* else fallthrough to retry, using older open call, this is +- case where server does not support this SMB level, and +- falsely claims capability (also get here for DFS case +- which should be rare for path not covered on files) */ +- } +- + if (nd && (nd->flags & LOOKUP_OPEN)) { +- /* if the file is going to stay open, then we +- need to set the desired access properly */ ++ int oflags = nd->intent.open.flags; ++ + desiredAccess = 0; + if (oflags & FMODE_READ) +- desiredAccess |= GENERIC_READ; /* is this too little? */ ++ desiredAccess |= GENERIC_READ; + if (oflags & FMODE_WRITE) { + desiredAccess |= GENERIC_WRITE; + if (!(oflags & FMODE_READ)) +@@ -308,6 +186,8 @@ + + /* BB add processing to set equivalent of mode - e.g. via CreateX with + ACLs */ ++ if (oplockEnabled) ++ oplock = REQ_OPLOCK; + + buf = kmalloc(sizeof(FILE_ALL_INFO), GFP_KERNEL); + if (buf == NULL) { +@@ -316,15 +196,17 @@ + return -ENOMEM; + } + ++ mode &= ~current->fs->umask; ++ + /* + * if we're not using unix extensions, see if we need to set + * ATTR_READONLY on the create call + */ +- if (!tcon->unix_ext && (mode & S_IWUGO) == 0) ++ if (!pTcon->unix_ext && (mode & S_IWUGO) == 0) + create_options |= CREATE_OPTION_READONLY; + + if (cifs_sb->tcon->ses->capabilities & CAP_NT_SMBS) +- rc = CIFSSMBOpen(xid, tcon, full_path, disposition, ++ rc = CIFSSMBOpen(xid, pTcon, full_path, disposition, + desiredAccess, create_options, + &fileHandle, &oplock, buf, cifs_sb->local_nls, + cifs_sb->mnt_cifs_flags & CIFS_MOUNT_MAP_SPECIAL_CHR); +@@ -333,119 +215,128 @@ + + if (rc == -EIO) { + /* old server, retry the open legacy style */ +- rc = SMBLegacyOpen(xid, tcon, full_path, disposition, ++ rc = SMBLegacyOpen(xid, pTcon, full_path, disposition, + desiredAccess, create_options, + &fileHandle, &oplock, buf, cifs_sb->local_nls, + cifs_sb->mnt_cifs_flags & CIFS_MOUNT_MAP_SPECIAL_CHR); + } + if (rc) { + cFYI(1, ("cifs_create returned 0x%x", rc)); +- goto cifs_create_out; +- } +- +- /* If Open reported that we actually created a file +- then we now have to set the mode if possible */ +- if ((tcon->unix_ext) && (oplock & CIFS_CREATE_ACTION)) { +- struct cifs_unix_set_info_args args = { ++ } else { ++ /* If Open reported that we actually created a file ++ then we now have to set the mode if possible */ ++ if ((pTcon->unix_ext) && (oplock & CIFS_CREATE_ACTION)) { ++ struct cifs_unix_set_info_args args = { + .mode = mode, + .ctime = NO_CHANGE_64, + .atime = NO_CHANGE_64, + .mtime = NO_CHANGE_64, + .device = 0, +- }; ++ }; + +- if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_SET_UID) { +- args.uid = (__u64) current_fsuid(); +- if (inode->i_mode & S_ISGID) +- args.gid = (__u64) inode->i_gid; +- else +- args.gid = (__u64) current_fsgid(); +- } else { +- args.uid = NO_CHANGE_64; +- args.gid = NO_CHANGE_64; +- } +- CIFSSMBUnixSetInfo(xid, tcon, full_path, &args, +- cifs_sb->local_nls, +- cifs_sb->mnt_cifs_flags & CIFS_MOUNT_MAP_SPECIAL_CHR); +- } else { +- /* BB implement mode setting via Windows security +- descriptors e.g. */ +- /* CIFSSMBWinSetPerms(xid,tcon,path,mode,-1,-1,nls);*/ +- +- /* Could set r/o dos attribute if mode & 0222 == 0 */ +- } +- +-cifs_create_get_file_info: +- /* server might mask mode so we have to query for it */ +- if (tcon->unix_ext) +- rc = cifs_get_inode_info_unix(&newinode, full_path, +- inode->i_sb, xid); +- else { +- rc = cifs_get_inode_info(&newinode, full_path, buf, +- inode->i_sb, xid, &fileHandle); +- if (newinode) { +- if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_DYNPERM) +- newinode->i_mode = mode; +- if ((oplock & CIFS_CREATE_ACTION) && +- (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_SET_UID)) { +- newinode->i_uid = current_fsuid(); ++ if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_SET_UID) { ++ args.uid = (__u64) current_fsuid(); + if (inode->i_mode & S_ISGID) +- newinode->i_gid = inode->i_gid; ++ args.gid = (__u64) inode->i_gid; + else +- newinode->i_gid = current_fsgid(); ++ args.gid = (__u64) current_fsgid(); ++ } else { ++ args.uid = NO_CHANGE_64; ++ args.gid = NO_CHANGE_64; + } ++ CIFSSMBUnixSetInfo(xid, pTcon, full_path, &args, ++ cifs_sb->local_nls, ++ cifs_sb->mnt_cifs_flags & ++ CIFS_MOUNT_MAP_SPECIAL_CHR); ++ } else { ++ /* BB implement mode setting via Windows security ++ descriptors e.g. */ ++ /* CIFSSMBWinSetPerms(xid,pTcon,path,mode,-1,-1,nls);*/ ++ ++ /* Could set r/o dos attribute if mode & 0222 == 0 */ + } +- } + +-cifs_create_set_dentry: +- if (rc == 0) +- setup_cifs_dentry(tcon, direntry, newinode); +- else +- cFYI(1, ("Create worked, get_inode_info failed rc = %d", rc)); ++ /* server might mask mode so we have to query for it */ ++ if (pTcon->unix_ext) ++ rc = cifs_get_inode_info_unix(&newinode, full_path, ++ inode->i_sb, xid); ++ else { ++ rc = cifs_get_inode_info(&newinode, full_path, ++ buf, inode->i_sb, xid, ++ &fileHandle); ++ if (newinode) { ++ if (cifs_sb->mnt_cifs_flags & ++ CIFS_MOUNT_DYNPERM) ++ newinode->i_mode = mode; ++ if ((oplock & CIFS_CREATE_ACTION) && ++ (cifs_sb->mnt_cifs_flags & ++ CIFS_MOUNT_SET_UID)) { ++ newinode->i_uid = current_fsuid(); ++ if (inode->i_mode & S_ISGID) ++ newinode->i_gid = ++ inode->i_gid; ++ else ++ newinode->i_gid = ++ current_fsgid(); ++ } ++ } ++ } + +- /* nfsd case - nfs srv does not set nd */ +- if ((nd == NULL) || (!(nd->flags & LOOKUP_OPEN))) { +- /* mknod case - do not leave file open */ +- CIFSSMBClose(xid, tcon, fileHandle); +- } else if (newinode) { +- struct cifsFileInfo *pCifsFile = +- kzalloc(sizeof(struct cifsFileInfo), GFP_KERNEL); +- +- if (pCifsFile == NULL) +- goto cifs_create_out; +- pCifsFile->netfid = fileHandle; +- pCifsFile->pid = current->tgid; +- pCifsFile->pInode = newinode; +- pCifsFile->invalidHandle = false; +- pCifsFile->closePend = false; +- init_MUTEX(&pCifsFile->fh_sem); +- mutex_init(&pCifsFile->lock_mutex); +- INIT_LIST_HEAD(&pCifsFile->llist); +- atomic_set(&pCifsFile->wrtPending, 0); ++ if (rc != 0) { ++ cFYI(1, ++ ("Create worked but get_inode_info failed rc = %d", ++ rc)); ++ } else { ++ if (pTcon->nocase) ++ direntry->d_op = &cifs_ci_dentry_ops; ++ else ++ direntry->d_op = &cifs_dentry_ops; ++ d_instantiate(direntry, newinode); ++ } ++ if ((nd == NULL /* nfsd case - nfs srv does not set nd */) || ++ (!(nd->flags & LOOKUP_OPEN))) { ++ /* mknod case - do not leave file open */ ++ CIFSSMBClose(xid, pTcon, fileHandle); ++ } else if (newinode) { ++ pCifsFile = ++ kzalloc(sizeof(struct cifsFileInfo), GFP_KERNEL); ++ ++ if (pCifsFile == NULL) ++ goto cifs_create_out; ++ pCifsFile->netfid = fileHandle; ++ pCifsFile->pid = current->tgid; ++ pCifsFile->pInode = newinode; ++ pCifsFile->invalidHandle = false; ++ pCifsFile->closePend = false; ++ init_MUTEX(&pCifsFile->fh_sem); ++ mutex_init(&pCifsFile->lock_mutex); ++ INIT_LIST_HEAD(&pCifsFile->llist); ++ atomic_set(&pCifsFile->wrtPending, 0); + +- /* set the following in open now ++ /* set the following in open now + pCifsFile->pfile = file; */ +- write_lock(&GlobalSMBSeslock); +- list_add(&pCifsFile->tlist, &tcon->openFileList); +- pCifsInode = CIFS_I(newinode); +- if (pCifsInode) { +- /* if readable file instance put first in list*/ +- if (write_only) { +- list_add_tail(&pCifsFile->flist, +- &pCifsInode->openFileList); +- } else { +- list_add(&pCifsFile->flist, +- &pCifsInode->openFileList); ++ write_lock(&GlobalSMBSeslock); ++ list_add(&pCifsFile->tlist, &pTcon->openFileList); ++ pCifsInode = CIFS_I(newinode); ++ if (pCifsInode) { ++ /* if readable file instance put first in list*/ ++ if (write_only) { ++ list_add_tail(&pCifsFile->flist, ++ &pCifsInode->openFileList); ++ } else { ++ list_add(&pCifsFile->flist, ++ &pCifsInode->openFileList); ++ } ++ if ((oplock & 0xF) == OPLOCK_EXCLUSIVE) { ++ pCifsInode->clientCanCacheAll = true; ++ pCifsInode->clientCanCacheRead = true; ++ cFYI(1, ("Exclusive Oplock inode %p", ++ newinode)); ++ } else if ((oplock & 0xF) == OPLOCK_READ) ++ pCifsInode->clientCanCacheRead = true; + } +- if ((oplock & 0xF) == OPLOCK_EXCLUSIVE) { +- pCifsInode->clientCanCacheAll = true; +- pCifsInode->clientCanCacheRead = true; +- cFYI(1, ("Exclusive Oplock inode %p", +- newinode)); +- } else if ((oplock & 0xF) == OPLOCK_READ) +- pCifsInode->clientCanCacheRead = true; ++ write_unlock(&GlobalSMBSeslock); + } +- write_unlock(&GlobalSMBSeslock); + } + cifs_create_out: + kfree(buf); +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/fs/cifs/inode.c linux-2.6.29-rc3.owrt/fs/cifs/inode.c +--- linux-2.6.29.owrt/fs/cifs/inode.c 2009-05-10 22:04:39.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/fs/cifs/inode.c 2009-05-10 23:48:29.000000000 +0200 +@@ -199,49 +199,6 @@ + pfnd_dat->Gid = cpu_to_le64(pinode->i_gid); + } + +-/** +- * cifs_new inode - create new inode, initialize, and hash it +- * @sb - pointer to superblock +- * @inum - if valid pointer and serverino is enabled, replace i_ino with val +- * +- * Create a new inode, initialize it for CIFS and hash it. Returns the new +- * inode or NULL if one couldn't be allocated. +- * +- * If the share isn't mounted with "serverino" or inum is a NULL pointer then +- * we'll just use the inode number assigned by new_inode(). Note that this can +- * mean i_ino collisions since the i_ino assigned by new_inode is not +- * guaranteed to be unique. +- */ +-struct inode * +-cifs_new_inode(struct super_block *sb, __u64 *inum) +-{ +- struct inode *inode; +- +- inode = new_inode(sb); +- if (inode == NULL) +- return NULL; +- +- /* +- * BB: Is i_ino == 0 legal? Here, we assume that it is. If it isn't we +- * stop passing inum as ptr. Are there sanity checks we can use to +- * ensure that the server is really filling in that field? Also, +- * if serverino is disabled, perhaps we should be using iunique()? +- */ +- if (inum && (CIFS_SB(sb)->mnt_cifs_flags & CIFS_MOUNT_SERVER_INUM)) +- inode->i_ino = (unsigned long) *inum; +- +- /* +- * must set this here instead of cifs_alloc_inode since VFS will +- * clobber i_flags +- */ +- if (sb->s_flags & MS_NOATIME) +- inode->i_flags |= S_NOATIME | S_NOCMTIME; +- +- insert_inode_hash(inode); +- +- return inode; +-} +- + int cifs_get_inode_info_unix(struct inode **pinode, + const unsigned char *full_path, struct super_block *sb, int xid) + { +@@ -276,11 +233,22 @@ + + /* get new inode */ + if (*pinode == NULL) { +- *pinode = cifs_new_inode(sb, &find_data.UniqueId); ++ *pinode = new_inode(sb); + if (*pinode == NULL) { + rc = -ENOMEM; + goto cgiiu_exit; + } ++ /* Is an i_ino of zero legal? */ ++ /* note ino incremented to unique num in new_inode */ ++ /* Are there sanity checks we can use to ensure that ++ the server is really filling in that field? */ ++ if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_SERVER_INUM) ++ (*pinode)->i_ino = (unsigned long)find_data.UniqueId; ++ ++ if (sb->s_flags & MS_NOATIME) ++ (*pinode)->i_flags |= S_NOATIME | S_NOCMTIME; ++ ++ insert_inode_hash(*pinode); + } + + inode = *pinode; +@@ -497,9 +465,11 @@ + + /* get new inode */ + if (*pinode == NULL) { +- __u64 inode_num; +- __u64 *pinum = &inode_num; +- ++ *pinode = new_inode(sb); ++ if (*pinode == NULL) { ++ rc = -ENOMEM; ++ goto cgii_exit; ++ } + /* Is an i_ino of zero legal? Can we use that to check + if the server supports returning inode numbers? Are + there other sanity checks we can use to ensure that +@@ -516,26 +486,22 @@ + + if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_SERVER_INUM) { + int rc1 = 0; ++ __u64 inode_num; + + rc1 = CIFSGetSrvInodeNumber(xid, pTcon, +- full_path, pinum, ++ full_path, &inode_num, + cifs_sb->local_nls, + cifs_sb->mnt_cifs_flags & + CIFS_MOUNT_MAP_SPECIAL_CHR); + if (rc1) { + cFYI(1, ("GetSrvInodeNum rc %d", rc1)); +- pinum = NULL; + /* BB EOPNOSUPP disable SERVER_INUM? */ +- } +- } else { +- pinum = NULL; +- } +- +- *pinode = cifs_new_inode(sb, pinum); +- if (*pinode == NULL) { +- rc = -ENOMEM; +- goto cgii_exit; +- } ++ } else /* do we need cast or hash to ino? */ ++ (*pinode)->i_ino = inode_num; ++ } /* else ino incremented to unique num in new_inode*/ ++ if (sb->s_flags & MS_NOATIME) ++ (*pinode)->i_flags |= S_NOATIME | S_NOCMTIME; ++ insert_inode_hash(*pinode); + } + inode = *pinode; + cifsInfo = CIFS_I(inode); +@@ -655,7 +621,7 @@ + .lookup = cifs_lookup, + }; + +-char *cifs_build_path_to_root(struct cifs_sb_info *cifs_sb) ++static char *build_path_to_root(struct cifs_sb_info *cifs_sb) + { + int pplen = cifs_sb->prepathlen; + int dfsplen; +@@ -712,7 +678,7 @@ + return inode; + + cifs_sb = CIFS_SB(inode->i_sb); +- full_path = cifs_build_path_to_root(cifs_sb); ++ full_path = build_path_to_root(cifs_sb); + if (full_path == NULL) + return ERR_PTR(-ENOMEM); + +@@ -1051,7 +1017,7 @@ + return rc; + } + +-void posix_fill_in_inode(struct inode *tmp_inode, ++static void posix_fill_in_inode(struct inode *tmp_inode, + FILE_UNIX_BASIC_INFO *pData, int isNewInode) + { + struct cifsInodeInfo *cifsInfo = CIFS_I(tmp_inode); +@@ -1148,14 +1114,24 @@ + else + direntry->d_op = &cifs_dentry_ops; + +- newinode = cifs_new_inode(inode->i_sb, +- &pInfo->UniqueId); ++ newinode = new_inode(inode->i_sb); + if (newinode == NULL) { + kfree(pInfo); + goto mkdir_get_info; + } + ++ /* Is an i_ino of zero legal? */ ++ /* Are there sanity checks we can use to ensure that ++ the server is really filling in that field? */ ++ if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_SERVER_INUM) { ++ newinode->i_ino = ++ (unsigned long)pInfo->UniqueId; ++ } /* note ino incremented to unique num in new_inode */ ++ if (inode->i_sb->s_flags & MS_NOATIME) ++ newinode->i_flags |= S_NOATIME | S_NOCMTIME; + newinode->i_nlink = 2; ++ ++ insert_inode_hash(newinode); + d_instantiate(direntry, newinode); + + /* we already checked in POSIXCreate whether +@@ -1309,11 +1285,6 @@ + cifsInode = CIFS_I(direntry->d_inode); + cifsInode->time = 0; /* force revalidate to go get info when + needed */ +- +- cifsInode = CIFS_I(inode); +- cifsInode->time = 0; /* force revalidate to get parent dir info +- since cached search results now invalid */ +- + direntry->d_inode->i_ctime = inode->i_ctime = inode->i_mtime = + current_fs_time(inode->i_sb); + +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/fs/cifs/md5.c linux-2.6.29-rc3.owrt/fs/cifs/md5.c +--- linux-2.6.29.owrt/fs/cifs/md5.c 2009-05-10 22:04:39.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/fs/cifs/md5.c 2009-05-10 23:48:29.000000000 +0200 +@@ -10,8 +10,8 @@ + * with every copy. + * + * To compute the message digest of a chunk of bytes, declare an +- * MD5Context structure, pass it to cifs_MD5_init, call cifs_MD5_update as +- * needed on buffers full of bytes, and then call cifs_MD5_final, which ++ * MD5Context structure, pass it to MD5Init, call MD5Update as ++ * needed on buffers full of bytes, and then call MD5Final, which + * will fill a supplied 16-byte array with the digest. + */ + +@@ -45,7 +45,7 @@ + * initialization constants. + */ + void +-cifs_MD5_init(struct MD5Context *ctx) ++MD5Init(struct MD5Context *ctx) + { + ctx->buf[0] = 0x67452301; + ctx->buf[1] = 0xefcdab89; +@@ -61,7 +61,7 @@ + * of bytes. + */ + void +-cifs_MD5_update(struct MD5Context *ctx, unsigned char const *buf, unsigned len) ++MD5Update(struct MD5Context *ctx, unsigned char const *buf, unsigned len) + { + register __u32 t; + +@@ -110,7 +110,7 @@ + * 1 0* (64-bit count of bits processed, MSB-first) + */ + void +-cifs_MD5_final(unsigned char digest[16], struct MD5Context *ctx) ++MD5Final(unsigned char digest[16], struct MD5Context *ctx) + { + unsigned int count; + unsigned char *p; +@@ -165,7 +165,7 @@ + + /* + * The core of the MD5 algorithm, this alters an existing MD5 hash to +- * reflect the addition of 16 longwords of new data. cifs_MD5_update blocks ++ * reflect the addition of 16 longwords of new data. MD5Update blocks + * the data and converts bytes into longwords for this routine. + */ + static void +@@ -267,9 +267,9 @@ + unsigned char tk[16]; + struct MD5Context tctx; + +- cifs_MD5_init(&tctx); +- cifs_MD5_update(&tctx, key, key_len); +- cifs_MD5_final(tk, &tctx); ++ MD5Init(&tctx); ++ MD5Update(&tctx, key, key_len); ++ MD5Final(tk, &tctx); + + key = tk; + key_len = 16; +@@ -287,8 +287,8 @@ + ctx->k_opad[i] ^= 0x5c; + } + +- cifs_MD5_init(&ctx->ctx); +- cifs_MD5_update(&ctx->ctx, ctx->k_ipad, 64); ++ MD5Init(&ctx->ctx); ++ MD5Update(&ctx->ctx, ctx->k_ipad, 64); + } + #endif + +@@ -317,8 +317,8 @@ + ctx->k_opad[i] ^= 0x5c; + } + +- cifs_MD5_init(&ctx->ctx); +- cifs_MD5_update(&ctx->ctx, ctx->k_ipad, 64); ++ MD5Init(&ctx->ctx); ++ MD5Update(&ctx->ctx, ctx->k_ipad, 64); + } + + /*********************************************************************** +@@ -328,7 +328,7 @@ + hmac_md5_update(const unsigned char *text, int text_len, + struct HMACMD5Context *ctx) + { +- cifs_MD5_update(&ctx->ctx, text, text_len); /* then text of datagram */ ++ MD5Update(&ctx->ctx, text, text_len); /* then text of datagram */ + } + + /*********************************************************************** +@@ -339,12 +339,12 @@ + { + struct MD5Context ctx_o; + +- cifs_MD5_final(digest, &ctx->ctx); ++ MD5Final(digest, &ctx->ctx); + +- cifs_MD5_init(&ctx_o); +- cifs_MD5_update(&ctx_o, ctx->k_opad, 64); +- cifs_MD5_update(&ctx_o, digest, 16); +- cifs_MD5_final(digest, &ctx_o); ++ MD5Init(&ctx_o); ++ MD5Update(&ctx_o, ctx->k_opad, 64); ++ MD5Update(&ctx_o, digest, 16); ++ MD5Final(digest, &ctx_o); + } + + /*********************************************************** +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/fs/cifs/md5.h linux-2.6.29-rc3.owrt/fs/cifs/md5.h +--- linux-2.6.29.owrt/fs/cifs/md5.h 2009-05-10 22:04:39.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/fs/cifs/md5.h 2009-05-10 23:48:29.000000000 +0200 +@@ -20,10 +20,10 @@ + }; + #endif /* _HMAC_MD5_H */ + +-void cifs_MD5_init(struct MD5Context *context); +-void cifs_MD5_update(struct MD5Context *context, unsigned char const *buf, ++void MD5Init(struct MD5Context *context); ++void MD5Update(struct MD5Context *context, unsigned char const *buf, + unsigned len); +-void cifs_MD5_final(unsigned char digest[16], struct MD5Context *context); ++void MD5Final(unsigned char digest[16], struct MD5Context *context); + + /* The following definitions come from lib/hmacmd5.c */ + +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/fs/cifs/readdir.c linux-2.6.29-rc3.owrt/fs/cifs/readdir.c +--- linux-2.6.29.owrt/fs/cifs/readdir.c 2009-05-10 22:04:39.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/fs/cifs/readdir.c 2009-05-10 23:48:29.000000000 +0200 +@@ -56,34 +56,35 @@ + } + #endif /* DEBUG2 */ + +-/* Returns 1 if new inode created, 2 if both dentry and inode were */ ++/* Returns one if new inode created (which therefore needs to be hashed) */ + /* Might check in the future if inode number changed so we can rehash inode */ +-static int +-construct_dentry(struct qstr *qstring, struct file *file, +- struct inode **ptmp_inode, struct dentry **pnew_dentry, +- __u64 *inum) ++static int construct_dentry(struct qstr *qstring, struct file *file, ++ struct inode **ptmp_inode, struct dentry **pnew_dentry) + { +- struct dentry *tmp_dentry = NULL; +- struct super_block *sb = file->f_path.dentry->d_sb; ++ struct dentry *tmp_dentry; ++ struct cifs_sb_info *cifs_sb; ++ struct cifsTconInfo *pTcon; + int rc = 0; + + cFYI(1, ("For %s", qstring->name)); ++ cifs_sb = CIFS_SB(file->f_path.dentry->d_sb); ++ pTcon = cifs_sb->tcon; + + qstring->hash = full_name_hash(qstring->name, qstring->len); + tmp_dentry = d_lookup(file->f_path.dentry, qstring); + if (tmp_dentry) { +- /* BB: overwrite old name? i.e. tmp_dentry->d_name and +- * tmp_dentry->d_name.len?? +- */ + cFYI(0, ("existing dentry with inode 0x%p", + tmp_dentry->d_inode)); + *ptmp_inode = tmp_dentry->d_inode; ++/* BB overwrite old name? i.e. tmp_dentry->d_name and tmp_dentry->d_name.len??*/ + if (*ptmp_inode == NULL) { +- *ptmp_inode = cifs_new_inode(sb, inum); ++ *ptmp_inode = new_inode(file->f_path.dentry->d_sb); + if (*ptmp_inode == NULL) + return rc; + rc = 1; + } ++ if (file->f_path.dentry->d_sb->s_flags & MS_NOATIME) ++ (*ptmp_inode)->i_flags |= S_NOATIME | S_NOCMTIME; + } else { + tmp_dentry = d_alloc(file->f_path.dentry, qstring); + if (tmp_dentry == NULL) { +@@ -92,14 +93,15 @@ + return rc; + } + +- if (CIFS_SB(sb)->tcon->nocase) ++ *ptmp_inode = new_inode(file->f_path.dentry->d_sb); ++ if (pTcon->nocase) + tmp_dentry->d_op = &cifs_ci_dentry_ops; + else + tmp_dentry->d_op = &cifs_dentry_ops; +- +- *ptmp_inode = cifs_new_inode(sb, inum); + if (*ptmp_inode == NULL) + return rc; ++ if (file->f_path.dentry->d_sb->s_flags & MS_NOATIME) ++ (*ptmp_inode)->i_flags |= S_NOATIME | S_NOCMTIME; + rc = 2; + } + +@@ -820,7 +822,7 @@ + /* inode num, inode type and filename returned */ + static int cifs_get_name_from_search_buf(struct qstr *pqst, + char *current_entry, __u16 level, unsigned int unicode, +- struct cifs_sb_info *cifs_sb, int max_len, __u64 *pinum) ++ struct cifs_sb_info *cifs_sb, int max_len, ino_t *pinum) + { + int rc = 0; + unsigned int len = 0; +@@ -840,7 +842,9 @@ + len = strnlen(filename, PATH_MAX); + } + +- *pinum = pFindData->UniqueId; ++ /* BB fixme - hash low and high 32 bits if not 64 bit arch BB */ ++ if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_SERVER_INUM) ++ *pinum = pFindData->UniqueId; + } else if (level == SMB_FIND_FILE_DIRECTORY_INFO) { + FILE_DIRECTORY_INFO *pFindData = + (FILE_DIRECTORY_INFO *)current_entry; +@@ -903,7 +907,7 @@ + struct qstr qstring; + struct cifsFileInfo *pCifsF; + unsigned int obj_type; +- __u64 inum; ++ ino_t inum; + struct cifs_sb_info *cifs_sb; + struct inode *tmp_inode; + struct dentry *tmp_dentry; +@@ -936,18 +940,20 @@ + if (rc) + return rc; + +- /* only these two infolevels return valid inode numbers */ +- if (pCifsF->srch_inf.info_level == SMB_FIND_FILE_UNIX || +- pCifsF->srch_inf.info_level == SMB_FIND_FILE_ID_FULL_DIR_INFO) +- rc = construct_dentry(&qstring, file, &tmp_inode, &tmp_dentry, +- &inum); +- else +- rc = construct_dentry(&qstring, file, &tmp_inode, &tmp_dentry, +- NULL); +- ++ rc = construct_dentry(&qstring, file, &tmp_inode, &tmp_dentry); + if ((tmp_inode == NULL) || (tmp_dentry == NULL)) + return -ENOMEM; + ++ if (rc) { ++ /* inode created, we need to hash it with right inode number */ ++ if (inum != 0) { ++ /* BB fixme - hash the 2 32 quantities bits together if ++ * necessary BB */ ++ tmp_inode->i_ino = inum; ++ } ++ insert_inode_hash(tmp_inode); ++ } ++ + /* we pass in rc below, indicating whether it is a new inode, + so we can figure out whether to invalidate the inode cached + data if the file has changed */ +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/fs/cifs/sess.c linux-2.6.29-rc3.owrt/fs/cifs/sess.c +--- linux-2.6.29.owrt/fs/cifs/sess.c 2009-05-10 22:04:39.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/fs/cifs/sess.c 2009-05-10 23:48:29.000000000 +0200 +@@ -34,99 +34,15 @@ + extern void SMBNTencrypt(unsigned char *passwd, unsigned char *c8, + unsigned char *p24); + +-/* Checks if this is the first smb session to be reconnected after +- the socket has been reestablished (so we know whether to use vc 0). +- Called while holding the cifs_tcp_ses_lock, so do not block */ +-static bool is_first_ses_reconnect(struct cifsSesInfo *ses) +-{ +- struct list_head *tmp; +- struct cifsSesInfo *tmp_ses; +- +- list_for_each(tmp, &ses->server->smb_ses_list) { +- tmp_ses = list_entry(tmp, struct cifsSesInfo, +- smb_ses_list); +- if (tmp_ses->need_reconnect == false) +- return false; +- } +- /* could not find a session that was already connected, +- this must be the first one we are reconnecting */ +- return true; +-} +- +-/* +- * vc number 0 is treated specially by some servers, and should be the +- * first one we request. After that we can use vcnumbers up to maxvcs, +- * one for each smb session (some Windows versions set maxvcs incorrectly +- * so maxvc=1 can be ignored). If we have too many vcs, we can reuse +- * any vc but zero (some servers reset the connection on vcnum zero) +- * +- */ +-static __le16 get_next_vcnum(struct cifsSesInfo *ses) +-{ +- __u16 vcnum = 0; +- struct list_head *tmp; +- struct cifsSesInfo *tmp_ses; +- __u16 max_vcs = ses->server->max_vcs; +- __u16 i; +- int free_vc_found = 0; +- +- /* Quoting the MS-SMB specification: "Windows-based SMB servers set this +- field to one but do not enforce this limit, which allows an SMB client +- to establish more virtual circuits than allowed by this value ... but +- other server implementations can enforce this limit." */ +- if (max_vcs < 2) +- max_vcs = 0xFFFF; +- +- write_lock(&cifs_tcp_ses_lock); +- if ((ses->need_reconnect) && is_first_ses_reconnect(ses)) +- goto get_vc_num_exit; /* vcnum will be zero */ +- for (i = ses->server->srv_count - 1; i < max_vcs; i++) { +- if (i == 0) /* this is the only connection, use vc 0 */ +- break; +- +- free_vc_found = 1; +- +- list_for_each(tmp, &ses->server->smb_ses_list) { +- tmp_ses = list_entry(tmp, struct cifsSesInfo, +- smb_ses_list); +- if (tmp_ses->vcnum == i) { +- free_vc_found = 0; +- break; /* found duplicate, try next vcnum */ +- } +- } +- if (free_vc_found) +- break; /* we found a vcnumber that will work - use it */ +- } +- +- if (i == 0) +- vcnum = 0; /* for most common case, ie if one smb session, use +- vc zero. Also for case when no free vcnum, zero +- is safest to send (some clients only send zero) */ +- else if (free_vc_found == 0) +- vcnum = 1; /* we can not reuse vc=0 safely, since some servers +- reset all uids on that, but 1 is ok. */ +- else +- vcnum = i; +- ses->vcnum = vcnum; +-get_vc_num_exit: +- write_unlock(&cifs_tcp_ses_lock); +- +- return le16_to_cpu(vcnum); +-} +- + static __u32 cifs_ssetup_hdr(struct cifsSesInfo *ses, SESSION_SETUP_ANDX *pSMB) + { + __u32 capabilities = 0; + + /* init fields common to all four types of SessSetup */ +- /* Note that offsets for first seven fields in req struct are same */ +- /* in CIFS Specs so does not matter which of 3 forms of struct */ +- /* that we use in next few lines */ +- /* Note that header is initialized to zero in header_assemble */ ++ /* note that header is initialized to zero in header_assemble */ + pSMB->req.AndXCommand = 0xFF; + pSMB->req.MaxBufferSize = cpu_to_le16(ses->server->maxBuf); + pSMB->req.MaxMpxCount = cpu_to_le16(ses->server->maxReq); +- pSMB->req.VcNumber = get_next_vcnum(ses); + + /* Now no need to set SMBFLG_CASELESS or obsolete CANONICAL PATH */ + +@@ -155,6 +71,7 @@ + if (ses->capabilities & CAP_UNIX) + capabilities |= CAP_UNIX; + ++ /* BB check whether to init vcnum BB */ + return capabilities; + } + +@@ -311,7 +228,7 @@ + + kfree(ses->serverOS); + /* UTF-8 string will not grow more than four times as big as UCS-16 */ +- ses->serverOS = kzalloc((4 * len) + 2 /* trailing null */, GFP_KERNEL); ++ ses->serverOS = kzalloc(4 * len, GFP_KERNEL); + if (ses->serverOS != NULL) + cifs_strfromUCS_le(ses->serverOS, (__le16 *)data, len, nls_cp); + data += 2 * (len + 1); +@@ -324,7 +241,7 @@ + return rc; + + kfree(ses->serverNOS); +- ses->serverNOS = kzalloc((4 * len) + 2 /* trailing null */, GFP_KERNEL); ++ ses->serverNOS = kzalloc(4 * len, GFP_KERNEL); /* BB this is wrong length FIXME BB */ + if (ses->serverNOS != NULL) { + cifs_strfromUCS_le(ses->serverNOS, (__le16 *)data, len, + nls_cp); +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/fs/cifs/transport.c linux-2.6.29-rc3.owrt/fs/cifs/transport.c +--- linux-2.6.29.owrt/fs/cifs/transport.c 2009-05-10 22:04:39.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/fs/cifs/transport.c 2009-05-10 23:48:29.000000000 +0200 +@@ -154,8 +154,81 @@ + spin_unlock(&GlobalMid_Lock); + } + ++int ++smb_send(struct socket *ssocket, struct smb_hdr *smb_buffer, ++ unsigned int smb_buf_length, struct sockaddr *sin, bool noblocksnd) ++{ ++ int rc = 0; ++ int i = 0; ++ struct msghdr smb_msg; ++ struct kvec iov; ++ unsigned len = smb_buf_length + 4; ++ ++ if (ssocket == NULL) ++ return -ENOTSOCK; /* BB eventually add reconnect code here */ ++ iov.iov_base = smb_buffer; ++ iov.iov_len = len; ++ ++ smb_msg.msg_name = sin; ++ smb_msg.msg_namelen = sizeof(struct sockaddr); ++ smb_msg.msg_control = NULL; ++ smb_msg.msg_controllen = 0; ++ if (noblocksnd) ++ smb_msg.msg_flags = MSG_DONTWAIT + MSG_NOSIGNAL; ++ else ++ smb_msg.msg_flags = MSG_NOSIGNAL; ++ ++ /* smb header is converted in header_assemble. bcc and rest of SMB word ++ area, and byte area if necessary, is converted to littleendian in ++ cifssmb.c and RFC1001 len is converted to bigendian in smb_send ++ Flags2 is converted in SendReceive */ ++ ++ smb_buffer->smb_buf_length = cpu_to_be32(smb_buffer->smb_buf_length); ++ cFYI(1, ("Sending smb of length %d", smb_buf_length)); ++ dump_smb(smb_buffer, len); ++ ++ while (len > 0) { ++ rc = kernel_sendmsg(ssocket, &smb_msg, &iov, 1, len); ++ if ((rc == -ENOSPC) || (rc == -EAGAIN)) { ++ i++; ++ /* smaller timeout here than send2 since smaller size */ ++ /* Although it may not be required, this also is smaller ++ oplock break time */ ++ if (i > 12) { ++ cERROR(1, ++ ("sends on sock %p stuck for 7 seconds", ++ ssocket)); ++ rc = -EAGAIN; ++ break; ++ } ++ msleep(1 << i); ++ continue; ++ } ++ if (rc < 0) ++ break; ++ else ++ i = 0; /* reset i after each successful send */ ++ iov.iov_base += rc; ++ iov.iov_len -= rc; ++ len -= rc; ++ } ++ ++ if (rc < 0) { ++ cERROR(1, ("Error %d sending data on socket to server", rc)); ++ } else { ++ rc = 0; ++ } ++ ++ /* Don't want to modify the buffer as a ++ side effect of this call. */ ++ smb_buffer->smb_buf_length = smb_buf_length; ++ ++ return rc; ++} ++ + static int +-smb_sendv(struct TCP_Server_Info *server, struct kvec *iov, int n_vec) ++smb_send2(struct TCP_Server_Info *server, struct kvec *iov, int n_vec, ++ struct sockaddr *sin, bool noblocksnd) + { + int rc = 0; + int i = 0; +@@ -170,11 +243,11 @@ + if (ssocket == NULL) + return -ENOTSOCK; /* BB eventually add reconnect code here */ + +- smb_msg.msg_name = (struct sockaddr *) &server->addr.sockAddr; ++ smb_msg.msg_name = sin; + smb_msg.msg_namelen = sizeof(struct sockaddr); + smb_msg.msg_control = NULL; + smb_msg.msg_controllen = 0; +- if (server->noblocksnd) ++ if (noblocksnd) + smb_msg.msg_flags = MSG_DONTWAIT + MSG_NOSIGNAL; + else + smb_msg.msg_flags = MSG_NOSIGNAL; +@@ -199,25 +272,7 @@ + n_vec - first_vec, total_len); + if ((rc == -ENOSPC) || (rc == -EAGAIN)) { + i++; +- /* if blocking send we try 3 times, since each can block +- for 5 seconds. For nonblocking we have to try more +- but wait increasing amounts of time allowing time for +- socket to clear. The overall time we wait in either +- case to send on the socket is about 15 seconds. +- Similarly we wait for 15 seconds for +- a response from the server in SendReceive[2] +- for the server to send a response back for +- most types of requests (except SMB Write +- past end of file which can be slow, and +- blocking lock operations). NFS waits slightly longer +- than CIFS, but this can make it take longer for +- nonresponsive servers to be detected and 15 seconds +- is more than enough time for modern networks to +- send a packet. In most cases if we fail to send +- after the retries we will kill the socket and +- reconnect which may clear the network problem. +- */ +- if ((i >= 14) || (!server->noblocksnd && (i > 2))) { ++ if (i >= 14) { + cERROR(1, + ("sends on sock %p stuck for 15 seconds", + ssocket)); +@@ -284,18 +339,6 @@ + return rc; + } + +-int +-smb_send(struct TCP_Server_Info *server, struct smb_hdr *smb_buffer, +- unsigned int smb_buf_length) +-{ +- struct kvec iov; +- +- iov.iov_base = smb_buffer; +- iov.iov_len = smb_buf_length + 4; +- +- return smb_sendv(server, &iov, 1); +-} +- + static int wait_for_free_request(struct cifsSesInfo *ses, const int long_op) + { + if (long_op == CIFS_ASYNC_OP) { +@@ -497,7 +540,9 @@ + #ifdef CONFIG_CIFS_STATS2 + atomic_inc(&ses->server->inSend); + #endif +- rc = smb_sendv(ses->server, iov, n_vec); ++ rc = smb_send2(ses->server, iov, n_vec, ++ (struct sockaddr *) &(ses->server->addr.sockAddr), ++ ses->server->noblocksnd); + #ifdef CONFIG_CIFS_STATS2 + atomic_dec(&ses->server->inSend); + midQ->when_sent = jiffies; +@@ -691,7 +736,9 @@ + #ifdef CONFIG_CIFS_STATS2 + atomic_inc(&ses->server->inSend); + #endif +- rc = smb_send(ses->server, in_buf, in_buf->smb_buf_length); ++ rc = smb_send(ses->server->ssocket, in_buf, in_buf->smb_buf_length, ++ (struct sockaddr *) &(ses->server->addr.sockAddr), ++ ses->server->noblocksnd); + #ifdef CONFIG_CIFS_STATS2 + atomic_dec(&ses->server->inSend); + midQ->when_sent = jiffies; +@@ -832,7 +879,9 @@ + mutex_unlock(&ses->server->srv_mutex); + return rc; + } +- rc = smb_send(ses->server, in_buf, in_buf->smb_buf_length); ++ rc = smb_send(ses->server->ssocket, in_buf, in_buf->smb_buf_length, ++ (struct sockaddr *) &(ses->server->addr.sockAddr), ++ ses->server->noblocksnd); + mutex_unlock(&ses->server->srv_mutex); + return rc; + } +@@ -924,7 +973,9 @@ + #ifdef CONFIG_CIFS_STATS2 + atomic_inc(&ses->server->inSend); + #endif +- rc = smb_send(ses->server, in_buf, in_buf->smb_buf_length); ++ rc = smb_send(ses->server->ssocket, in_buf, in_buf->smb_buf_length, ++ (struct sockaddr *) &(ses->server->addr.sockAddr), ++ ses->server->noblocksnd); + #ifdef CONFIG_CIFS_STATS2 + atomic_dec(&ses->server->inSend); + midQ->when_sent = jiffies; +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/fs/compat.c linux-2.6.29-rc3.owrt/fs/compat.c +--- linux-2.6.29.owrt/fs/compat.c 2009-05-10 22:04:39.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/fs/compat.c 2009-05-10 23:48:29.000000000 +0200 +@@ -1407,7 +1407,7 @@ + bprm->cred = prepare_exec_creds(); + if (!bprm->cred) + goto out_unlock; +- check_unsafe_exec(bprm, current->files); ++ check_unsafe_exec(bprm); + + file = open_exec(filename); + retval = PTR_ERR(file); +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/fs/compat_ioctl.c linux-2.6.29-rc3.owrt/fs/compat_ioctl.c +--- linux-2.6.29.owrt/fs/compat_ioctl.c 2009-05-10 22:04:39.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/fs/compat_ioctl.c 2009-05-10 23:48:29.000000000 +0200 +@@ -538,7 +538,6 @@ + * cannot be fixed without breaking all existing apps. + */ + case TUNSETIFF: +- case TUNGETIFF: + case SIOCGIFFLAGS: + case SIOCGIFMETRIC: + case SIOCGIFMTU: +@@ -785,7 +784,7 @@ + + if (copy_in_user(&sgio->status, &sgio32->status, + (4 * sizeof(unsigned char)) + +- (2 * sizeof(unsigned short)) + ++ (2 * sizeof(unsigned (short))) + + (3 * sizeof(int)))) + return -EFAULT; + +@@ -1913,9 +1912,6 @@ + /* 0x00 */ + COMPATIBLE_IOCTL(FIBMAP) + COMPATIBLE_IOCTL(FIGETBSZ) +-/* 'X' - originally XFS but some now in the VFS */ +-COMPATIBLE_IOCTL(FIFREEZE) +-COMPATIBLE_IOCTL(FITHAW) + /* RAID */ + COMPATIBLE_IOCTL(RAID_VERSION) + COMPATIBLE_IOCTL(GET_ARRAY_INFO) +@@ -1941,8 +1937,6 @@ + /* Big K */ + COMPATIBLE_IOCTL(PIO_FONT) + COMPATIBLE_IOCTL(GIO_FONT) +-COMPATIBLE_IOCTL(PIO_CMAP) +-COMPATIBLE_IOCTL(GIO_CMAP) + ULONG_IOCTL(KDSIGACCEPT) + COMPATIBLE_IOCTL(KDGETKEYCODE) + COMPATIBLE_IOCTL(KDSETKEYCODE) +@@ -1988,11 +1982,6 @@ + COMPATIBLE_IOCTL(TUNSETDEBUG) + COMPATIBLE_IOCTL(TUNSETPERSIST) + COMPATIBLE_IOCTL(TUNSETOWNER) +-COMPATIBLE_IOCTL(TUNSETLINK) +-COMPATIBLE_IOCTL(TUNSETGROUP) +-COMPATIBLE_IOCTL(TUNGETFEATURES) +-COMPATIBLE_IOCTL(TUNSETOFFLOAD) +-COMPATIBLE_IOCTL(TUNSETTXFILTER) + /* Big V */ + COMPATIBLE_IOCTL(VT_SETMODE) + COMPATIBLE_IOCTL(VT_GETMODE) +@@ -2584,7 +2573,6 @@ + HANDLE_IOCTL(SIOCGIFTXQLEN, dev_ifsioc) + HANDLE_IOCTL(SIOCSIFTXQLEN, dev_ifsioc) + HANDLE_IOCTL(TUNSETIFF, dev_ifsioc) +-HANDLE_IOCTL(TUNGETIFF, dev_ifsioc) + HANDLE_IOCTL(SIOCETHTOOL, ethtool_ioctl) + HANDLE_IOCTL(SIOCBONDENSLAVE, bond_ioctl) + HANDLE_IOCTL(SIOCBONDRELEASE, bond_ioctl) +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/fs/dcache.c linux-2.6.29-rc3.owrt/fs/dcache.c +--- linux-2.6.29.owrt/fs/dcache.c 2009-05-10 22:04:39.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/fs/dcache.c 2009-05-10 23:48:29.000000000 +0200 +@@ -1180,7 +1180,7 @@ + iput(inode); + return res; + } +-EXPORT_SYMBOL(d_obtain_alias); ++EXPORT_SYMBOL_GPL(d_obtain_alias); + + /** + * d_splice_alias - splice a disconnected dentry into the tree if one exists +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/fs/devpts/inode.c linux-2.6.29-rc3.owrt/fs/devpts/inode.c +--- linux-2.6.29.owrt/fs/devpts/inode.c 2009-05-10 22:04:39.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/fs/devpts/inode.c 2009-05-10 23:48:29.000000000 +0200 +@@ -198,6 +198,9 @@ + + fsi->ptmx_dentry = dentry; + rc = 0; ++ ++ printk(KERN_DEBUG "Created ptmx node in devpts ino %lu\n", ++ inode->i_ino); + out: + mutex_unlock(&root->d_inode->i_mutex); + return rc; +@@ -366,6 +369,8 @@ + struct pts_fs_info *fsi; + struct pts_mount_opts *opts; + ++ printk(KERN_NOTICE "devpts: newinstance mount\n"); ++ + err = get_sb_nodev(fs_type, flags, data, devpts_fill_super, mnt); + if (err) + return err; +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/fs/ecryptfs/crypto.c linux-2.6.29-rc3.owrt/fs/ecryptfs/crypto.c +--- linux-2.6.29.owrt/fs/ecryptfs/crypto.c 2009-05-10 22:04:39.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/fs/ecryptfs/crypto.c 2009-05-10 23:48:29.000000000 +0200 +@@ -946,8 +946,6 @@ + list_for_each_entry(global_auth_tok, + &mount_crypt_stat->global_auth_tok_list, + mount_crypt_stat_list) { +- if (global_auth_tok->flags & ECRYPTFS_AUTH_TOK_FNEK) +- continue; + rc = ecryptfs_add_keysig(crypt_stat, global_auth_tok->sig); + if (rc) { + printk(KERN_ERR "Error adding keysig; rc = [%d]\n", rc); +@@ -1324,13 +1322,14 @@ + } + + static int +-ecryptfs_write_metadata_to_contents(struct dentry *ecryptfs_dentry, +- char *virt, size_t virt_len) ++ecryptfs_write_metadata_to_contents(struct ecryptfs_crypt_stat *crypt_stat, ++ struct dentry *ecryptfs_dentry, ++ char *virt) + { + int rc; + + rc = ecryptfs_write_lower(ecryptfs_dentry->d_inode, virt, +- 0, virt_len); ++ 0, crypt_stat->num_header_bytes_at_front); + if (rc) + printk(KERN_ERR "%s: Error attempting to write header " + "information to lower file; rc = [%d]\n", __func__, +@@ -1340,6 +1339,7 @@ + + static int + ecryptfs_write_metadata_to_xattr(struct dentry *ecryptfs_dentry, ++ struct ecryptfs_crypt_stat *crypt_stat, + char *page_virt, size_t size) + { + int rc; +@@ -1349,17 +1349,6 @@ + return rc; + } + +-static unsigned long ecryptfs_get_zeroed_pages(gfp_t gfp_mask, +- unsigned int order) +-{ +- struct page *page; +- +- page = alloc_pages(gfp_mask | __GFP_ZERO, order); +- if (page) +- return (unsigned long) page_address(page); +- return 0; +-} +- + /** + * ecryptfs_write_metadata + * @ecryptfs_dentry: The eCryptfs dentry +@@ -1376,9 +1365,7 @@ + { + struct ecryptfs_crypt_stat *crypt_stat = + &ecryptfs_inode_to_private(ecryptfs_dentry->d_inode)->crypt_stat; +- unsigned int order; + char *virt; +- size_t virt_len; + size_t size = 0; + int rc = 0; + +@@ -1394,35 +1381,33 @@ + rc = -EINVAL; + goto out; + } +- virt_len = crypt_stat->num_header_bytes_at_front; +- order = get_order(virt_len); + /* Released in this function */ +- virt = (char *)ecryptfs_get_zeroed_pages(GFP_KERNEL, order); ++ virt = (char *)get_zeroed_page(GFP_KERNEL); + if (!virt) { + printk(KERN_ERR "%s: Out of memory\n", __func__); + rc = -ENOMEM; + goto out; + } +- rc = ecryptfs_write_headers_virt(virt, virt_len, &size, crypt_stat, +- ecryptfs_dentry); ++ rc = ecryptfs_write_headers_virt(virt, PAGE_CACHE_SIZE, &size, ++ crypt_stat, ecryptfs_dentry); + if (unlikely(rc)) { + printk(KERN_ERR "%s: Error whilst writing headers; rc = [%d]\n", + __func__, rc); + goto out_free; + } + if (crypt_stat->flags & ECRYPTFS_METADATA_IN_XATTR) +- rc = ecryptfs_write_metadata_to_xattr(ecryptfs_dentry, virt, +- size); ++ rc = ecryptfs_write_metadata_to_xattr(ecryptfs_dentry, ++ crypt_stat, virt, size); + else +- rc = ecryptfs_write_metadata_to_contents(ecryptfs_dentry, virt, +- virt_len); ++ rc = ecryptfs_write_metadata_to_contents(crypt_stat, ++ ecryptfs_dentry, virt); + if (rc) { + printk(KERN_ERR "%s: Error writing metadata out to lower file; " + "rc = [%d]\n", __func__, rc); + goto out_free; + } + out_free: +- free_pages((unsigned long)virt, order); ++ free_page((unsigned long)virt); + out: + return rc; + } +@@ -1731,7 +1716,7 @@ + { + int rc = 0; + +- (*copied_name) = kmalloc((name_size + 1), GFP_KERNEL); ++ (*copied_name) = kmalloc((name_size + 2), GFP_KERNEL); + if (!(*copied_name)) { + rc = -ENOMEM; + goto out; +@@ -1741,7 +1726,7 @@ + * in printing out the + * string in debug + * messages */ +- (*copied_name_size) = name_size; ++ (*copied_name_size) = (name_size + 1); + out: + return rc; + } +@@ -2221,19 +2206,17 @@ + struct dentry *ecryptfs_dir_dentry, + const char *name, size_t name_size) + { +- struct ecryptfs_mount_crypt_stat *mount_crypt_stat = +- &ecryptfs_superblock_to_private( +- ecryptfs_dir_dentry->d_sb)->mount_crypt_stat; + char *decoded_name; + size_t decoded_name_size; + size_t packet_size; + int rc = 0; + +- if ((mount_crypt_stat->flags & ECRYPTFS_GLOBAL_ENCRYPT_FILENAMES) +- && !(mount_crypt_stat->flags & ECRYPTFS_ENCRYPTED_VIEW_ENABLED) +- && (name_size > ECRYPTFS_FNEK_ENCRYPTED_FILENAME_PREFIX_SIZE) ++ if ((name_size > ECRYPTFS_FNEK_ENCRYPTED_FILENAME_PREFIX_SIZE) + && (strncmp(name, ECRYPTFS_FNEK_ENCRYPTED_FILENAME_PREFIX, + ECRYPTFS_FNEK_ENCRYPTED_FILENAME_PREFIX_SIZE) == 0)) { ++ struct ecryptfs_mount_crypt_stat *mount_crypt_stat = ++ &ecryptfs_superblock_to_private( ++ ecryptfs_dir_dentry->d_sb)->mount_crypt_stat; + const char *orig_name = name; + size_t orig_name_size = name_size; + +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/fs/ecryptfs/ecryptfs_kernel.h linux-2.6.29-rc3.owrt/fs/ecryptfs/ecryptfs_kernel.h +--- linux-2.6.29.owrt/fs/ecryptfs/ecryptfs_kernel.h 2009-05-10 22:04:39.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/fs/ecryptfs/ecryptfs_kernel.h 2009-05-10 23:48:29.000000000 +0200 +@@ -328,7 +328,6 @@ + */ + struct ecryptfs_global_auth_tok { + #define ECRYPTFS_AUTH_TOK_INVALID 0x00000001 +-#define ECRYPTFS_AUTH_TOK_FNEK 0x00000002 + u32 flags; + struct list_head mount_crypt_stat_list; + struct key *global_auth_tok_key; +@@ -620,6 +619,7 @@ + u32 flags); + int ecryptfs_lookup_and_interpose_lower(struct dentry *ecryptfs_dentry, + struct dentry *lower_dentry, ++ struct ecryptfs_crypt_stat *crypt_stat, + struct inode *ecryptfs_dir_inode, + struct nameidata *ecryptfs_nd); + int ecryptfs_decode_and_decrypt_filename(char **decrypted_name, +@@ -696,7 +696,7 @@ + int ecryptfs_add_keysig(struct ecryptfs_crypt_stat *crypt_stat, char *sig); + int + ecryptfs_add_global_auth_tok(struct ecryptfs_mount_crypt_stat *mount_crypt_stat, +- char *sig, u32 global_auth_tok_flags); ++ char *sig); + int ecryptfs_get_global_auth_tok_for_sig( + struct ecryptfs_global_auth_tok **global_auth_tok, + struct ecryptfs_mount_crypt_stat *mount_crypt_stat, char *sig); +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/fs/ecryptfs/inode.c linux-2.6.29-rc3.owrt/fs/ecryptfs/inode.c +--- linux-2.6.29.owrt/fs/ecryptfs/inode.c 2009-05-10 22:04:39.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/fs/ecryptfs/inode.c 2009-05-10 23:48:29.000000000 +0200 +@@ -246,6 +246,7 @@ + */ + int ecryptfs_lookup_and_interpose_lower(struct dentry *ecryptfs_dentry, + struct dentry *lower_dentry, ++ struct ecryptfs_crypt_stat *crypt_stat, + struct inode *ecryptfs_dir_inode, + struct nameidata *ecryptfs_nd) + { +@@ -253,7 +254,6 @@ + struct vfsmount *lower_mnt; + struct inode *lower_inode; + struct ecryptfs_mount_crypt_stat *mount_crypt_stat; +- struct ecryptfs_crypt_stat *crypt_stat; + char *page_virt = NULL; + u64 file_size; + int rc = 0; +@@ -314,11 +314,6 @@ + goto out_free_kmem; + } + } +- crypt_stat = &ecryptfs_inode_to_private( +- ecryptfs_dentry->d_inode)->crypt_stat; +- /* TODO: lock for crypt_stat comparison */ +- if (!(crypt_stat->flags & ECRYPTFS_POLICY_APPLIED)) +- ecryptfs_set_default_sizes(crypt_stat); + rc = ecryptfs_read_and_validate_header_region(page_virt, + ecryptfs_dentry->d_inode); + if (rc) { +@@ -367,7 +362,9 @@ + { + char *encrypted_and_encoded_name = NULL; + size_t encrypted_and_encoded_name_size; ++ struct ecryptfs_crypt_stat *crypt_stat = NULL; + struct ecryptfs_mount_crypt_stat *mount_crypt_stat = NULL; ++ struct ecryptfs_inode_info *inode_info; + struct dentry *lower_dir_dentry, *lower_dentry; + int rc = 0; + +@@ -391,15 +388,26 @@ + } + if (lower_dentry->d_inode) + goto lookup_and_interpose; +- mount_crypt_stat = &ecryptfs_superblock_to_private( +- ecryptfs_dentry->d_sb)->mount_crypt_stat; +- if (!(mount_crypt_stat +- && (mount_crypt_stat->flags & ECRYPTFS_GLOBAL_ENCRYPT_FILENAMES))) ++ inode_info = ecryptfs_inode_to_private(ecryptfs_dentry->d_inode); ++ if (inode_info) { ++ crypt_stat = &inode_info->crypt_stat; ++ /* TODO: lock for crypt_stat comparison */ ++ if (!(crypt_stat->flags & ECRYPTFS_POLICY_APPLIED)) ++ ecryptfs_set_default_sizes(crypt_stat); ++ } ++ if (crypt_stat) ++ mount_crypt_stat = crypt_stat->mount_crypt_stat; ++ else ++ mount_crypt_stat = &ecryptfs_superblock_to_private( ++ ecryptfs_dentry->d_sb)->mount_crypt_stat; ++ if (!(crypt_stat && (crypt_stat->flags & ECRYPTFS_ENCRYPT_FILENAMES)) ++ && !(mount_crypt_stat && (mount_crypt_stat->flags ++ & ECRYPTFS_GLOBAL_ENCRYPT_FILENAMES))) + goto lookup_and_interpose; + dput(lower_dentry); + rc = ecryptfs_encrypt_and_encode_filename( + &encrypted_and_encoded_name, &encrypted_and_encoded_name_size, +- NULL, mount_crypt_stat, ecryptfs_dentry->d_name.name, ++ crypt_stat, mount_crypt_stat, ecryptfs_dentry->d_name.name, + ecryptfs_dentry->d_name.len); + if (rc) { + printk(KERN_ERR "%s: Error attempting to encrypt and encode " +@@ -418,7 +426,7 @@ + } + lookup_and_interpose: + rc = ecryptfs_lookup_and_interpose_lower(ecryptfs_dentry, lower_dentry, +- ecryptfs_dir_inode, ++ crypt_stat, ecryptfs_dir_inode, + ecryptfs_nd); + goto out; + out_d_drop: +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/fs/ecryptfs/keystore.c linux-2.6.29-rc3.owrt/fs/ecryptfs/keystore.c +--- linux-2.6.29.owrt/fs/ecryptfs/keystore.c 2009-05-10 22:04:39.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/fs/ecryptfs/keystore.c 2009-05-10 23:48:29.000000000 +0200 +@@ -2375,7 +2375,7 @@ + + int + ecryptfs_add_global_auth_tok(struct ecryptfs_mount_crypt_stat *mount_crypt_stat, +- char *sig, u32 global_auth_tok_flags) ++ char *sig) + { + struct ecryptfs_global_auth_tok *new_auth_tok; + int rc = 0; +@@ -2389,7 +2389,6 @@ + goto out; + } + memcpy(new_auth_tok->sig, sig, ECRYPTFS_SIG_SIZE_HEX); +- new_auth_tok->flags = global_auth_tok_flags; + new_auth_tok->sig[ECRYPTFS_SIG_SIZE_HEX] = '\0'; + mutex_lock(&mount_crypt_stat->global_auth_tok_list_mutex); + list_add(&new_auth_tok->mount_crypt_stat_list, +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/fs/ecryptfs/main.c linux-2.6.29-rc3.owrt/fs/ecryptfs/main.c +--- linux-2.6.29.owrt/fs/ecryptfs/main.c 2009-05-10 22:04:39.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/fs/ecryptfs/main.c 2009-05-10 23:48:29.000000000 +0200 +@@ -319,7 +319,7 @@ + case ecryptfs_opt_ecryptfs_sig: + sig_src = args[0].from; + rc = ecryptfs_add_global_auth_tok(mount_crypt_stat, +- sig_src, 0); ++ sig_src); + if (rc) { + printk(KERN_ERR "Error attempting to register " + "global sig; rc = [%d]\n", rc); +@@ -370,8 +370,7 @@ + ECRYPTFS_SIG_SIZE_HEX] = '\0'; + rc = ecryptfs_add_global_auth_tok( + mount_crypt_stat, +- mount_crypt_stat->global_default_fnek_sig, +- ECRYPTFS_AUTH_TOK_FNEK); ++ mount_crypt_stat->global_default_fnek_sig); + if (rc) { + printk(KERN_ERR "Error attempting to register " + "global fnek sig [%s]; rc = [%d]\n", +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/fs/eventpoll.c linux-2.6.29-rc3.owrt/fs/eventpoll.c +--- linux-2.6.29.owrt/fs/eventpoll.c 2009-05-10 22:04:39.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/fs/eventpoll.c 2009-05-10 23:48:29.000000000 +0200 +@@ -234,6 +234,8 @@ + /* + * Configuration options available inside /proc/sys/fs/epoll/ + */ ++/* Maximum number of epoll devices, per user */ ++static int max_user_instances __read_mostly; + /* Maximum number of epoll watched descriptors, per user */ + static int max_user_watches __read_mostly; + +@@ -259,6 +261,14 @@ + + ctl_table epoll_table[] = { + { ++ .procname = "max_user_instances", ++ .data = &max_user_instances, ++ .maxlen = sizeof(int), ++ .mode = 0644, ++ .proc_handler = &proc_dointvec_minmax, ++ .extra1 = &zero, ++ }, ++ { + .procname = "max_user_watches", + .data = &max_user_watches, + .maxlen = sizeof(int), +@@ -481,6 +491,7 @@ + + mutex_unlock(&epmutex); + mutex_destroy(&ep->mtx); ++ atomic_dec(&ep->user->epoll_devs); + free_uid(ep->user); + kfree(ep); + } +@@ -570,6 +581,10 @@ + struct eventpoll *ep; + + user = get_current_user(); ++ error = -EMFILE; ++ if (unlikely(atomic_read(&user->epoll_devs) >= ++ max_user_instances)) ++ goto free_uid; + error = -ENOMEM; + ep = kzalloc(sizeof(*ep), GFP_KERNEL); + if (unlikely(!ep)) +@@ -1126,6 +1141,7 @@ + flags & O_CLOEXEC); + if (fd < 0) + ep_free(ep); ++ atomic_inc(&ep->user->epoll_devs); + + error_return: + DNPRINTK(3, (KERN_INFO "[%p] eventpoll: sys_epoll_create(%d) = %d\n", +@@ -1350,10 +1366,8 @@ + struct sysinfo si; + + si_meminfo(&si); +- /* +- * Allows top 4% of lomem to be allocated for epoll watches (per user). +- */ +- max_user_watches = (((si.totalram - si.totalhigh) / 25) << PAGE_SHIFT) / ++ max_user_instances = 128; ++ max_user_watches = (((si.totalram - si.totalhigh) / 32) << PAGE_SHIFT) / + EP_ITEM_COST; + + /* Initialize the structure used to perform safe poll wait head wake ups */ +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/fs/exec.c linux-2.6.29-rc3.owrt/fs/exec.c +--- linux-2.6.29.owrt/fs/exec.c 2009-05-10 22:04:39.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/fs/exec.c 2009-05-10 23:48:29.000000000 +0200 +@@ -1049,32 +1049,16 @@ + * - the caller must hold current->cred_exec_mutex to protect against + * PTRACE_ATTACH + */ +-void check_unsafe_exec(struct linux_binprm *bprm, struct files_struct *files) ++void check_unsafe_exec(struct linux_binprm *bprm) + { +- struct task_struct *p = current, *t; +- unsigned long flags; +- unsigned n_fs, n_files, n_sighand; ++ struct task_struct *p = current; + + bprm->unsafe = tracehook_unsafe_exec(p); + +- n_fs = 1; +- n_files = 1; +- n_sighand = 1; +- lock_task_sighand(p, &flags); +- for (t = next_thread(p); t != p; t = next_thread(t)) { +- if (t->fs == p->fs) +- n_fs++; +- if (t->files == files) +- n_files++; +- n_sighand++; +- } +- +- if (atomic_read(&p->fs->count) > n_fs || +- atomic_read(&p->files->count) > n_files || +- atomic_read(&p->sighand->count) > n_sighand) ++ if (atomic_read(&p->fs->count) > 1 || ++ atomic_read(&p->files->count) > 1 || ++ atomic_read(&p->sighand->count) > 1) + bprm->unsafe |= LSM_UNSAFE_SHARE; +- +- unlock_task_sighand(p, &flags); + } + + /* +@@ -1289,7 +1273,7 @@ + bprm->cred = prepare_exec_creds(); + if (!bprm->cred) + goto out_unlock; +- check_unsafe_exec(bprm, displaced); ++ check_unsafe_exec(bprm); + + file = open_exec(filename); + retval = PTR_ERR(file); +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/fs/ext2/super.c linux-2.6.29-rc3.owrt/fs/ext2/super.c +--- linux-2.6.29.owrt/fs/ext2/super.c 2009-05-10 22:04:39.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/fs/ext2/super.c 2009-05-10 23:48:29.000000000 +0200 +@@ -1185,12 +1185,9 @@ + es = sbi->s_es; + if (((sbi->s_mount_opt & EXT2_MOUNT_XIP) != + (old_mount_opt & EXT2_MOUNT_XIP)) && +- invalidate_inodes(sb)) { +- ext2_warning(sb, __func__, "refusing change of xip flag " +- "with busy inodes while remounting"); +- sbi->s_mount_opt &= ~EXT2_MOUNT_XIP; +- sbi->s_mount_opt |= old_mount_opt & EXT2_MOUNT_XIP; +- } ++ invalidate_inodes(sb)) ++ ext2_warning(sb, __func__, "busy inodes while remounting "\ ++ "xip remain in cache (no functional problem)"); + if ((*flags & MS_RDONLY) == (sb->s_flags & MS_RDONLY)) + return 0; + if (*flags & MS_RDONLY) { +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/fs/ext3/namei.c linux-2.6.29-rc3.owrt/fs/ext3/namei.c +--- linux-2.6.29.owrt/fs/ext3/namei.c 2009-05-10 22:04:39.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/fs/ext3/namei.c 2009-05-10 23:48:29.000000000 +0200 +@@ -1358,7 +1358,7 @@ + struct fake_dirent *fde; + + blocksize = dir->i_sb->s_blocksize; +- dxtrace(printk(KERN_DEBUG "Creating index: inode %lu\n", dir->i_ino)); ++ dxtrace(printk("Creating index\n")); + retval = ext3_journal_get_write_access(handle, bh); + if (retval) { + ext3_std_error(dir->i_sb, retval); +@@ -1367,19 +1367,6 @@ + } + root = (struct dx_root *) bh->b_data; + +- /* The 0th block becomes the root, move the dirents out */ +- fde = &root->dotdot; +- de = (struct ext3_dir_entry_2 *)((char *)fde + +- ext3_rec_len_from_disk(fde->rec_len)); +- if ((char *) de >= (((char *) root) + blocksize)) { +- ext3_error(dir->i_sb, __func__, +- "invalid rec_len for '..' in inode %lu", +- dir->i_ino); +- brelse(bh); +- return -EIO; +- } +- len = ((char *) root) + blocksize - (char *) de; +- + bh2 = ext3_append (handle, dir, &block, &retval); + if (!(bh2)) { + brelse(bh); +@@ -1388,6 +1375,11 @@ + EXT3_I(dir)->i_flags |= EXT3_INDEX_FL; + data1 = bh2->b_data; + ++ /* The 0th block becomes the root, move the dirents out */ ++ fde = &root->dotdot; ++ de = (struct ext3_dir_entry_2 *)((char *)fde + ++ ext3_rec_len_from_disk(fde->rec_len)); ++ len = ((char *) root) + blocksize - (char *) de; + memcpy (data1, de, len); + de = (struct ext3_dir_entry_2 *) data1; + top = data1 + len; +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/fs/ext3/super.c linux-2.6.29-rc3.owrt/fs/ext3/super.c +--- linux-2.6.29.owrt/fs/ext3/super.c 2009-05-10 22:04:39.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/fs/ext3/super.c 2009-05-10 23:48:29.000000000 +0200 +@@ -2428,13 +2428,12 @@ + + static int ext3_sync_fs(struct super_block *sb, int wait) + { +- tid_t target; +- + sb->s_dirt = 0; +- if (journal_start_commit(EXT3_SB(sb)->s_journal, &target)) { +- if (wait) +- log_wait_commit(EXT3_SB(sb)->s_journal, target); +- } ++ if (wait) ++ ext3_force_commit(sb); ++ else ++ journal_start_commit(EXT3_SB(sb)->s_journal, NULL); ++ + return 0; + } + +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/fs/ext4/balloc.c linux-2.6.29-rc3.owrt/fs/ext4/balloc.c +--- linux-2.6.29.owrt/fs/ext4/balloc.c 2009-05-10 22:04:39.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/fs/ext4/balloc.c 2009-05-10 23:48:29.000000000 +0200 +@@ -609,9 +609,7 @@ + */ + int ext4_should_retry_alloc(struct super_block *sb, int *retries) + { +- if (!ext4_has_free_blocks(EXT4_SB(sb), 1) || +- (*retries)++ > 3 || +- !EXT4_SB(sb)->s_journal) ++ if (!ext4_has_free_blocks(EXT4_SB(sb), 1) || (*retries)++ > 3) + return 0; + + jbd_debug(1, "%s: retrying operation after ENOSPC\n", sb->s_id); +@@ -686,15 +684,15 @@ + gdp = ext4_get_group_desc(sb, i, NULL); + if (!gdp) + continue; +- desc_count += ext4_free_blks_count(sb, gdp); ++ desc_count += le16_to_cpu(gdp->bg_free_blocks_count); + brelse(bitmap_bh); + bitmap_bh = ext4_read_block_bitmap(sb, i); + if (bitmap_bh == NULL) + continue; + + x = ext4_count_free(bitmap_bh, sb->s_blocksize); +- printk(KERN_DEBUG "group %u: stored = %d, counted = %u\n", +- i, ext4_free_blks_count(sb, gdp), x); ++ printk(KERN_DEBUG "group %lu: stored = %d, counted = %u\n", ++ i, le16_to_cpu(gdp->bg_free_blocks_count), x); + bitmap_count += x; + } + brelse(bitmap_bh); +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/fs/ext4/ext4.h linux-2.6.29-rc3.owrt/fs/ext4/ext4.h +--- linux-2.6.29.owrt/fs/ext4/ext4.h 2009-05-10 22:04:39.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/fs/ext4/ext4.h 2009-05-10 23:48:29.000000000 +0200 +@@ -868,7 +868,7 @@ + { + unsigned len = le16_to_cpu(dlen); + +- if (len == EXT4_MAX_REC_LEN || len == 0) ++ if (len == EXT4_MAX_REC_LEN) + return 1 << 16; + return len; + } +@@ -1206,11 +1206,8 @@ + + static inline loff_t ext4_isize(struct ext4_inode *raw_inode) + { +- if (S_ISREG(le16_to_cpu(raw_inode->i_mode))) +- return ((loff_t)le32_to_cpu(raw_inode->i_size_high) << 32) | +- le32_to_cpu(raw_inode->i_size_lo); +- else +- return (loff_t) le32_to_cpu(raw_inode->i_size_lo); ++ return ((loff_t)le32_to_cpu(raw_inode->i_size_high) << 32) | ++ le32_to_cpu(raw_inode->i_size_lo); + } + + static inline void ext4_isize_set(struct ext4_inode *raw_inode, loff_t i_size) +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/fs/ext4/extents.c linux-2.6.29-rc3.owrt/fs/ext4/extents.c +--- linux-2.6.29.owrt/fs/ext4/extents.c 2009-05-10 22:04:39.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/fs/ext4/extents.c 2009-05-10 23:48:29.000000000 +0200 +@@ -1122,8 +1122,7 @@ + struct ext4_extent_idx *ix; + struct ext4_extent *ex; + ext4_fsblk_t block; +- int depth; /* Note, NOT eh_depth; depth from top of tree */ +- int ee_len; ++ int depth, ee_len; + + BUG_ON(path == NULL); + depth = path->p_depth; +@@ -1180,8 +1179,7 @@ + if (bh == NULL) + return -EIO; + eh = ext_block_hdr(bh); +- /* subtract from p_depth to get proper eh_depth */ +- if (ext4_ext_check_header(inode, eh, path->p_depth - depth)) { ++ if (ext4_ext_check_header(inode, eh, depth)) { + put_bh(bh); + return -EIO; + } +@@ -3050,7 +3048,7 @@ + WARN_ON(ret <= 0); + printk(KERN_ERR "%s: ext4_ext_get_blocks " + "returned error inode#%lu, block=%u, " +- "max_blocks=%u", __func__, ++ "max_blocks=%lu", __func__, + inode->i_ino, block, max_blocks); + #endif + ext4_mark_inode_dirty(handle, inode); +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/fs/ext4/ialloc.c linux-2.6.29-rc3.owrt/fs/ext4/ialloc.c +--- linux-2.6.29.owrt/fs/ext4/ialloc.c 2009-05-10 22:04:39.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/fs/ext4/ialloc.c 2009-05-10 23:48:29.000000000 +0200 +@@ -188,7 +188,7 @@ + struct ext4_group_desc *gdp; + struct ext4_super_block *es; + struct ext4_sb_info *sbi; +- int fatal = 0, err, count, cleared; ++ int fatal = 0, err, count; + ext4_group_t flex_group; + + if (atomic_read(&inode->i_count) > 1) { +@@ -248,10 +248,8 @@ + goto error_return; + + /* Ok, now we can actually update the inode bitmaps.. */ +- spin_lock(sb_bgl_lock(sbi, block_group)); +- cleared = ext4_clear_bit(bit, bitmap_bh->b_data); +- spin_unlock(sb_bgl_lock(sbi, block_group)); +- if (!cleared) ++ if (!ext4_clear_bit_atomic(sb_bgl_lock(sbi, block_group), ++ bit, bitmap_bh->b_data)) + ext4_error(sb, "ext4_free_inode", + "bit already cleared for inode %lu", ino); + else { +@@ -698,7 +696,6 @@ + struct inode *ret; + ext4_group_t i; + int free = 0; +- static int once = 1; + ext4_group_t flex_group; + + /* Cannot create files in a deleted directory */ +@@ -718,14 +715,6 @@ + + if (sbi->s_log_groups_per_flex) { + ret2 = find_group_flex(sb, dir, &group); +- if (ret2 == -1) { +- ret2 = find_group_other(sb, dir, &group); +- if (ret2 == 0 && once) +- once = 0; +- printk(KERN_NOTICE "ext4: find_group_flex " +- "failed, fallback succeeded dir %lu\n", +- dir->i_ino); +- } + goto got_group; + } + +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/fs/ext4/inode.c linux-2.6.29-rc3.owrt/fs/ext4/inode.c +--- linux-2.6.29.owrt/fs/ext4/inode.c 2009-05-10 22:04:39.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/fs/ext4/inode.c 2009-05-10 23:48:29.000000000 +0200 +@@ -47,10 +47,8 @@ + static inline int ext4_begin_ordered_truncate(struct inode *inode, + loff_t new_size) + { +- return jbd2_journal_begin_ordered_truncate( +- EXT4_SB(inode->i_sb)->s_journal, +- &EXT4_I(inode)->jinode, +- new_size); ++ return jbd2_journal_begin_ordered_truncate(&EXT4_I(inode)->jinode, ++ new_size); + } + + static void ext4_invalidatepage(struct page *page, unsigned long offset); +@@ -362,9 +360,9 @@ + final = ptrs; + } else { + ext4_warning(inode->i_sb, "ext4_block_to_path", +- "block %lu > max in inode %lu", ++ "block %lu > max", + i_block + direct_blocks + +- indirect_blocks + double_blocks, inode->i_ino); ++ indirect_blocks + double_blocks); + } + if (boundary) + *boundary = final - 1 - (i_block & (ptrs - 1)); +@@ -1368,10 +1366,6 @@ + goto out; + } + +- /* We cannot recurse into the filesystem as the transaction is already +- * started */ +- flags |= AOP_FLAG_NOFS; +- + page = grab_cache_page_write_begin(mapping, index, flags); + if (!page) { + ext4_journal_stop(handle); +@@ -1381,7 +1375,7 @@ + *pagep = page; + + ret = block_write_begin(file, mapping, pos, len, flags, pagep, fsdata, +- ext4_get_block); ++ ext4_get_block); + + if (!ret && ext4_should_journal_data(inode)) { + ret = walk_page_buffers(handle, page_buffers(page), +@@ -2443,7 +2437,6 @@ + int no_nrwrite_index_update; + int pages_written = 0; + long pages_skipped; +- int range_cyclic, cycled = 1, io_done = 0; + int needed_blocks, ret = 0, nr_to_writebump = 0; + struct ext4_sb_info *sbi = EXT4_SB(mapping->host->i_sb); + +@@ -2495,15 +2488,9 @@ + if (wbc->range_start == 0 && wbc->range_end == LLONG_MAX) + range_whole = 1; + +- range_cyclic = wbc->range_cyclic; +- if (wbc->range_cyclic) { ++ if (wbc->range_cyclic) + index = mapping->writeback_index; +- if (index) +- cycled = 0; +- wbc->range_start = index << PAGE_CACHE_SHIFT; +- wbc->range_end = LLONG_MAX; +- wbc->range_cyclic = 0; +- } else ++ else + index = wbc->range_start >> PAGE_CACHE_SHIFT; + + mpd.wbc = wbc; +@@ -2517,7 +2504,6 @@ + wbc->no_nrwrite_index_update = 1; + pages_skipped = wbc->pages_skipped; + +-retry: + while (!ret && wbc->nr_to_write > 0) { + + /* +@@ -2544,7 +2530,7 @@ + + ext4_journal_stop(handle); + +- if ((mpd.retval == -ENOSPC) && sbi->s_journal) { ++ if (mpd.retval == -ENOSPC) { + /* commit the transaction which would + * free blocks released in the transaction + * and try again +@@ -2560,7 +2546,6 @@ + pages_written += mpd.pages_written; + wbc->pages_skipped = pages_skipped; + ret = 0; +- io_done = 1; + } else if (wbc->nr_to_write) + /* + * There is no more writeout needed +@@ -2569,13 +2554,6 @@ + */ + break; + } +- if (!io_done && !cycled) { +- cycled = 1; +- index = 0; +- wbc->range_start = index << PAGE_CACHE_SHIFT; +- wbc->range_end = mapping->writeback_index - 1; +- goto retry; +- } + if (pages_skipped != wbc->pages_skipped) + printk(KERN_EMERG "This should not happen leaving %s " + "with nr_to_write = %ld ret = %d\n", +@@ -2583,7 +2561,6 @@ + + /* Update index */ + index += pages_written; +- wbc->range_cyclic = range_cyclic; + if (wbc->range_cyclic || (range_whole && wbc->nr_to_write > 0)) + /* + * set the writeback_index so that range_cyclic +@@ -2671,9 +2648,6 @@ + ret = PTR_ERR(handle); + goto out; + } +- /* We cannot recurse into the filesystem as the transaction is already +- * started */ +- flags |= AOP_FLAG_NOFS; + + page = grab_cache_page_write_begin(mapping, index, flags); + if (!page) { +@@ -2847,6 +2821,9 @@ + filemap_write_and_wait(mapping); + } + ++ BUG_ON(!EXT4_JOURNAL(inode) && ++ EXT4_I(inode)->i_state & EXT4_STATE_JDATA); ++ + if (EXT4_JOURNAL(inode) && EXT4_I(inode)->i_state & EXT4_STATE_JDATA) { + /* + * This is a REALLY heavyweight approach, but the use of +@@ -3645,7 +3622,7 @@ + * block pointed to itself, it would have been detached when + * the block was cleared. Check for this instead of OOPSing. + */ +- if ((EXT4_JOURNAL(inode) == NULL) || bh2jh(this_bh)) ++ if (bh2jh(this_bh)) + ext4_handle_dirty_metadata(handle, inode, this_bh); + else + ext4_error(inode->i_sb, __func__, +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/fs/ext4/mballoc.c linux-2.6.29-rc3.owrt/fs/ext4/mballoc.c +--- linux-2.6.29.owrt/fs/ext4/mballoc.c 2009-05-10 22:04:39.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/fs/ext4/mballoc.c 2009-05-10 23:48:29.000000000 +0200 +@@ -1447,7 +1447,7 @@ + struct ext4_free_extent *gex = &ac->ac_g_ex; + + BUG_ON(ex->fe_len <= 0); +- BUG_ON(ex->fe_len > EXT4_BLOCKS_PER_GROUP(ac->ac_sb)); ++ BUG_ON(ex->fe_len >= EXT4_BLOCKS_PER_GROUP(ac->ac_sb)); + BUG_ON(ex->fe_start >= EXT4_BLOCKS_PER_GROUP(ac->ac_sb)); + BUG_ON(ac->ac_status != AC_STATUS_CONTINUE); + +@@ -3025,7 +3025,7 @@ + goto out_err; + + ext4_debug("using block group %u(%d)\n", ac->ac_b_ex.fe_group, +- ext4_free_blks_count(sb, gdp)); ++ gdp->bg_free_blocks_count); + + err = ext4_journal_get_write_access(handle, gdp_bh); + if (err) +@@ -3292,7 +3292,7 @@ + } + BUG_ON(start + size <= ac->ac_o_ex.fe_logical && + start > ac->ac_o_ex.fe_logical); +- BUG_ON(size <= 0 || size > EXT4_BLOCKS_PER_GROUP(ac->ac_sb)); ++ BUG_ON(size <= 0 || size >= EXT4_BLOCKS_PER_GROUP(ac->ac_sb)); + + /* now prepare goal request */ + +@@ -3589,7 +3589,6 @@ + struct super_block *sb, struct ext4_prealloc_space *pa) + { + ext4_group_t grp; +- ext4_fsblk_t grp_blk; + + if (!atomic_dec_and_test(&pa->pa_count) || pa->pa_free != 0) + return; +@@ -3604,12 +3603,8 @@ + pa->pa_deleted = 1; + spin_unlock(&pa->pa_lock); + +- grp_blk = pa->pa_pstart; +- /* If linear, pa_pstart may be in the next group when pa is used up */ +- if (pa->pa_linear) +- grp_blk--; +- +- ext4_get_group_no_and_offset(sb, grp_blk, &grp, NULL); ++ /* -1 is to protect from crossing allocation group */ ++ ext4_get_group_no_and_offset(sb, pa->pa_pstart - 1, &grp, NULL); + + /* + * possible race: +@@ -3698,8 +3693,6 @@ + pa->pa_free = pa->pa_len; + atomic_set(&pa->pa_count, 1); + spin_lock_init(&pa->pa_lock); +- INIT_LIST_HEAD(&pa->pa_inode_list); +- INIT_LIST_HEAD(&pa->pa_group_list); + pa->pa_deleted = 0; + pa->pa_linear = 0; + +@@ -3762,7 +3755,6 @@ + atomic_set(&pa->pa_count, 1); + spin_lock_init(&pa->pa_lock); + INIT_LIST_HEAD(&pa->pa_inode_list); +- INIT_LIST_HEAD(&pa->pa_group_list); + pa->pa_deleted = 0; + pa->pa_linear = 1; + +@@ -4484,26 +4476,23 @@ + pa->pa_free -= ac->ac_b_ex.fe_len; + pa->pa_len -= ac->ac_b_ex.fe_len; + spin_unlock(&pa->pa_lock); ++ /* ++ * We want to add the pa to the right bucket. ++ * Remove it from the list and while adding ++ * make sure the list to which we are adding ++ * doesn't grow big. ++ */ ++ if (likely(pa->pa_free)) { ++ spin_lock(pa->pa_obj_lock); ++ list_del_rcu(&pa->pa_inode_list); ++ spin_unlock(pa->pa_obj_lock); ++ ext4_mb_add_n_trim(ac); ++ } + } ++ ext4_mb_put_pa(ac, ac->ac_sb, pa); + } + if (ac->alloc_semp) + up_read(ac->alloc_semp); +- if (pa) { +- /* +- * We want to add the pa to the right bucket. +- * Remove it from the list and while adding +- * make sure the list to which we are adding +- * doesn't grow big. We need to release +- * alloc_semp before calling ext4_mb_add_n_trim() +- */ +- if (pa->pa_linear && likely(pa->pa_free)) { +- spin_lock(pa->pa_obj_lock); +- list_del_rcu(&pa->pa_inode_list); +- spin_unlock(pa->pa_obj_lock); +- ext4_mb_add_n_trim(ac); +- } +- ext4_mb_put_pa(ac, ac->ac_sb, pa); +- } + if (ac->ac_bitmap_page) + page_cache_release(ac->ac_bitmap_page); + if (ac->ac_buddy_page) +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/fs/ext4/migrate.c linux-2.6.29-rc3.owrt/fs/ext4/migrate.c +--- linux-2.6.29.owrt/fs/ext4/migrate.c 2009-05-10 22:04:39.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/fs/ext4/migrate.c 2009-05-10 23:48:29.000000000 +0200 +@@ -481,7 +481,7 @@ + + 1); + if (IS_ERR(handle)) { + retval = PTR_ERR(handle); +- return retval; ++ goto err_out; + } + tmp_inode = ext4_new_inode(handle, + inode->i_sb->s_root->d_inode, +@@ -489,7 +489,8 @@ + if (IS_ERR(tmp_inode)) { + retval = -ENOMEM; + ext4_journal_stop(handle); +- return retval; ++ tmp_inode = NULL; ++ goto err_out; + } + i_size_write(tmp_inode, i_size_read(inode)); + /* +@@ -617,7 +618,8 @@ + + ext4_journal_stop(handle); + +- iput(tmp_inode); ++ if (tmp_inode) ++ iput(tmp_inode); + + return retval; + } +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/fs/ext4/namei.c linux-2.6.29-rc3.owrt/fs/ext4/namei.c +--- linux-2.6.29.owrt/fs/ext4/namei.c 2009-05-10 22:04:39.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/fs/ext4/namei.c 2009-05-10 23:48:29.000000000 +0200 +@@ -1368,7 +1368,7 @@ + struct fake_dirent *fde; + + blocksize = dir->i_sb->s_blocksize; +- dxtrace(printk(KERN_DEBUG "Creating index: inode %lu\n", dir->i_ino)); ++ dxtrace(printk(KERN_DEBUG "Creating index\n")); + retval = ext4_journal_get_write_access(handle, bh); + if (retval) { + ext4_std_error(dir->i_sb, retval); +@@ -1377,20 +1377,6 @@ + } + root = (struct dx_root *) bh->b_data; + +- /* The 0th block becomes the root, move the dirents out */ +- fde = &root->dotdot; +- de = (struct ext4_dir_entry_2 *)((char *)fde + +- ext4_rec_len_from_disk(fde->rec_len)); +- if ((char *) de >= (((char *) root) + blocksize)) { +- ext4_error(dir->i_sb, __func__, +- "invalid rec_len for '..' in inode %lu", +- dir->i_ino); +- brelse(bh); +- return -EIO; +- } +- len = ((char *) root) + blocksize - (char *) de; +- +- /* Allocate new block for the 0th block's dirents */ + bh2 = ext4_append(handle, dir, &block, &retval); + if (!(bh2)) { + brelse(bh); +@@ -1399,6 +1385,11 @@ + EXT4_I(dir)->i_flags |= EXT4_INDEX_FL; + data1 = bh2->b_data; + ++ /* The 0th block becomes the root, move the dirents out */ ++ fde = &root->dotdot; ++ de = (struct ext4_dir_entry_2 *)((char *)fde + ++ ext4_rec_len_from_disk(fde->rec_len)); ++ len = ((char *) root) + blocksize - (char *) de; + memcpy (data1, de, len); + de = (struct ext4_dir_entry_2 *) data1; + top = data1 + len; +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/fs/ext4/resize.c linux-2.6.29-rc3.owrt/fs/ext4/resize.c +--- linux-2.6.29.owrt/fs/ext4/resize.c 2009-05-10 22:04:39.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/fs/ext4/resize.c 2009-05-10 23:48:29.000000000 +0200 +@@ -861,13 +861,12 @@ + gdp = (struct ext4_group_desc *)((char *)primary->b_data + + gdb_off * EXT4_DESC_SIZE(sb)); + +- memset(gdp, 0, EXT4_DESC_SIZE(sb)); + ext4_block_bitmap_set(sb, gdp, input->block_bitmap); /* LV FIXME */ + ext4_inode_bitmap_set(sb, gdp, input->inode_bitmap); /* LV FIXME */ + ext4_inode_table_set(sb, gdp, input->inode_table); /* LV FIXME */ + ext4_free_blks_set(sb, gdp, input->free_blocks_count); + ext4_free_inodes_set(sb, gdp, EXT4_INODES_PER_GROUP(sb)); +- gdp->bg_flags = cpu_to_le16(EXT4_BG_INODE_ZEROED); ++ gdp->bg_flags |= cpu_to_le16(EXT4_BG_INODE_ZEROED); + gdp->bg_checksum = ext4_group_desc_csum(sbi, input->group, gdp); + + /* +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/fs/ext4/super.c linux-2.6.29-rc3.owrt/fs/ext4/super.c +--- linux-2.6.29.owrt/fs/ext4/super.c 2009-05-10 22:04:39.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/fs/ext4/super.c 2009-05-10 23:48:29.000000000 +0200 +@@ -3046,17 +3046,14 @@ + static int ext4_sync_fs(struct super_block *sb, int wait) + { + int ret = 0; +- tid_t target; + + trace_mark(ext4_sync_fs, "dev %s wait %d", sb->s_id, wait); + sb->s_dirt = 0; + if (EXT4_SB(sb)->s_journal) { +- if (jbd2_journal_start_commit(EXT4_SB(sb)->s_journal, +- &target)) { +- if (wait) +- jbd2_log_wait_commit(EXT4_SB(sb)->s_journal, +- target); +- } ++ if (wait) ++ ret = ext4_force_commit(sb); ++ else ++ jbd2_journal_start_commit(EXT4_SB(sb)->s_journal, NULL); + } else { + ext4_commit_super(sb, EXT4_SB(sb)->s_es, wait); + } +@@ -3091,6 +3088,7 @@ + + /* Journal blocked and flushed, clear needs_recovery flag. */ + EXT4_CLEAR_INCOMPAT_FEATURE(sb, EXT4_FEATURE_INCOMPAT_RECOVER); ++ ext4_commit_super(sb, EXT4_SB(sb)->s_es, 1); + error = ext4_commit_super(sb, EXT4_SB(sb)->s_es, 1); + if (error) + goto out; +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/fs/fat/inode.c linux-2.6.29-rc3.owrt/fs/fat/inode.c +--- linux-2.6.29.owrt/fs/fat/inode.c 2009-05-10 22:04:39.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/fs/fat/inode.c 2009-05-10 23:48:29.000000000 +0200 +@@ -202,9 +202,9 @@ + sector_t blocknr; + + /* fat_get_cluster() assumes the requested blocknr isn't truncated. */ +- down_read(&mapping->host->i_alloc_sem); ++ mutex_lock(&mapping->host->i_mutex); + blocknr = generic_block_bmap(mapping, block, fat_get_block); +- up_read(&mapping->host->i_alloc_sem); ++ mutex_unlock(&mapping->host->i_mutex); + + return blocknr; + } +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/fs/fs-writeback.c linux-2.6.29-rc3.owrt/fs/fs-writeback.c +--- linux-2.6.29.owrt/fs/fs-writeback.c 2009-05-10 22:04:39.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/fs/fs-writeback.c 2009-05-10 23:48:29.000000000 +0200 +@@ -274,7 +274,6 @@ + int ret; + + BUG_ON(inode->i_state & I_SYNC); +- WARN_ON(inode->i_state & I_NEW); + + /* Set I_SYNC, reset I_DIRTY */ + dirty = inode->i_state & I_DIRTY; +@@ -299,7 +298,6 @@ + } + + spin_lock(&inode_lock); +- WARN_ON(inode->i_state & I_NEW); + inode->i_state &= ~I_SYNC; + if (!(inode->i_state & I_FREEING)) { + if (!(inode->i_state & I_DIRTY) && +@@ -472,11 +470,6 @@ + break; + } + +- if (inode->i_state & I_NEW) { +- requeue_io(inode); +- continue; +- } +- + if (wbc->nonblocking && bdi_write_congested(bdi)) { + wbc->encountered_congestion = 1; + if (!sb_is_blkdev_sb(sb)) +@@ -538,7 +531,7 @@ + list_for_each_entry(inode, &sb->s_inodes, i_sb_list) { + struct address_space *mapping; + +- if (inode->i_state & (I_FREEING|I_WILL_FREE|I_NEW)) ++ if (inode->i_state & (I_FREEING|I_WILL_FREE)) + continue; + mapping = inode->i_mapping; + if (mapping->nrpages == 0) +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/fs/hugetlbfs/inode.c linux-2.6.29-rc3.owrt/fs/hugetlbfs/inode.c +--- linux-2.6.29.owrt/fs/hugetlbfs/inode.c 2009-05-10 22:04:39.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/fs/hugetlbfs/inode.c 2009-05-10 23:48:29.000000000 +0200 +@@ -108,8 +108,7 @@ + + if (hugetlb_reserve_pages(inode, + vma->vm_pgoff >> huge_page_order(h), +- len >> huge_page_shift(h), vma, +- vma->vm_flags)) ++ len >> huge_page_shift(h), vma)) + goto out; + + ret = 0; +@@ -948,7 +947,7 @@ + can_do_mlock()); + } + +-struct file *hugetlb_file_setup(const char *name, size_t size, int acctflag) ++struct file *hugetlb_file_setup(const char *name, size_t size) + { + int error = -ENOMEM; + struct file *file; +@@ -982,8 +981,7 @@ + + error = -ENOMEM; + if (hugetlb_reserve_pages(inode, 0, +- size >> huge_page_shift(hstate_inode(inode)), NULL, +- acctflag)) ++ size >> huge_page_shift(hstate_inode(inode)), NULL)) + goto out_inode; + + d_instantiate(dentry, inode); +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/fs/inode.c linux-2.6.29-rc3.owrt/fs/inode.c +--- linux-2.6.29.owrt/fs/inode.c 2009-05-10 22:04:39.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/fs/inode.c 2009-05-10 23:48:29.000000000 +0200 +@@ -359,7 +359,6 @@ + invalidate_inode_buffers(inode); + if (!atomic_read(&inode->i_count)) { + list_move(&inode->i_list, dispose); +- WARN_ON(inode->i_state & I_NEW); + inode->i_state |= I_FREEING; + count++; + continue; +@@ -461,7 +460,6 @@ + continue; + } + list_move(&inode->i_list, &freeable); +- WARN_ON(inode->i_state & I_NEW); + inode->i_state |= I_FREEING; + nr_pruned++; + } +@@ -658,7 +656,6 @@ + * just created it (so there can be no old holders + * that haven't tested I_LOCK). + */ +- WARN_ON((inode->i_state & (I_LOCK|I_NEW)) != (I_LOCK|I_NEW)); + inode->i_state &= ~(I_LOCK|I_NEW); + wake_up_inode(inode); + } +@@ -1148,7 +1145,6 @@ + + list_del_init(&inode->i_list); + list_del_init(&inode->i_sb_list); +- WARN_ON(inode->i_state & I_NEW); + inode->i_state |= I_FREEING; + inodes_stat.nr_inodes--; + spin_unlock(&inode_lock); +@@ -1190,19 +1186,16 @@ + spin_unlock(&inode_lock); + return; + } +- WARN_ON(inode->i_state & I_NEW); + inode->i_state |= I_WILL_FREE; + spin_unlock(&inode_lock); + write_inode_now(inode, 1); + spin_lock(&inode_lock); +- WARN_ON(inode->i_state & I_NEW); + inode->i_state &= ~I_WILL_FREE; + inodes_stat.nr_unused--; + hlist_del_init(&inode->i_hash); + } + list_del_init(&inode->i_list); + list_del_init(&inode->i_sb_list); +- WARN_ON(inode->i_state & I_NEW); + inode->i_state |= I_FREEING; + inodes_stat.nr_inodes--; + spin_unlock(&inode_lock); +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/fs/internal.h linux-2.6.29-rc3.owrt/fs/internal.h +--- linux-2.6.29.owrt/fs/internal.h 2009-05-10 22:04:39.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/fs/internal.h 2009-05-10 23:48:29.000000000 +0200 +@@ -43,7 +43,7 @@ + /* + * exec.c + */ +-extern void check_unsafe_exec(struct linux_binprm *, struct files_struct *); ++extern void check_unsafe_exec(struct linux_binprm *); + + /* + * namespace.c +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/fs/jbd/journal.c linux-2.6.29-rc3.owrt/fs/jbd/journal.c +--- linux-2.6.29.owrt/fs/jbd/journal.c 2009-05-10 22:04:39.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/fs/jbd/journal.c 2009-05-10 23:48:29.000000000 +0200 +@@ -427,7 +427,7 @@ + } + + /* +- * Called under j_state_lock. Returns true if a transaction commit was started. ++ * Called under j_state_lock. Returns true if a transaction was started. + */ + int __log_start_commit(journal_t *journal, tid_t target) + { +@@ -495,8 +495,7 @@ + + /* + * Start a commit of the current running transaction (if any). Returns true +- * if a transaction is going to be committed (or is currently already +- * committing), and fills its tid in at *ptid ++ * if a transaction was started, and fills its tid in at *ptid + */ + int journal_start_commit(journal_t *journal, tid_t *ptid) + { +@@ -506,19 +505,15 @@ + if (journal->j_running_transaction) { + tid_t tid = journal->j_running_transaction->t_tid; + +- __log_start_commit(journal, tid); +- /* There's a running transaction and we've just made sure +- * it's commit has been scheduled. */ +- if (ptid) ++ ret = __log_start_commit(journal, tid); ++ if (ret && ptid) + *ptid = tid; +- ret = 1; +- } else if (journal->j_committing_transaction) { ++ } else if (journal->j_committing_transaction && ptid) { + /* + * If ext3_write_super() recently started a commit, then we + * have to wait for completion of that transaction + */ +- if (ptid) +- *ptid = journal->j_committing_transaction->t_tid; ++ *ptid = journal->j_committing_transaction->t_tid; + ret = 1; + } + spin_unlock(&journal->j_state_lock); +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/fs/jbd2/journal.c linux-2.6.29-rc3.owrt/fs/jbd2/journal.c +--- linux-2.6.29.owrt/fs/jbd2/journal.c 2009-05-10 22:04:39.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/fs/jbd2/journal.c 2009-05-10 23:48:29.000000000 +0200 +@@ -37,10 +37,10 @@ + #include <linux/proc_fs.h> + #include <linux/debugfs.h> + #include <linux/seq_file.h> +-#include <linux/math64.h> + + #include <asm/uaccess.h> + #include <asm/page.h> ++#include <asm/div64.h> + + EXPORT_SYMBOL(jbd2_journal_start); + EXPORT_SYMBOL(jbd2_journal_restart); +@@ -450,7 +450,7 @@ + } + + /* +- * Called under j_state_lock. Returns true if a transaction commit was started. ++ * Called under j_state_lock. Returns true if a transaction was started. + */ + int __jbd2_log_start_commit(journal_t *journal, tid_t target) + { +@@ -518,8 +518,7 @@ + + /* + * Start a commit of the current running transaction (if any). Returns true +- * if a transaction is going to be committed (or is currently already +- * committing), and fills its tid in at *ptid ++ * if a transaction was started, and fills its tid in at *ptid + */ + int jbd2_journal_start_commit(journal_t *journal, tid_t *ptid) + { +@@ -529,19 +528,15 @@ + if (journal->j_running_transaction) { + tid_t tid = journal->j_running_transaction->t_tid; + +- __jbd2_log_start_commit(journal, tid); +- /* There's a running transaction and we've just made sure +- * it's commit has been scheduled. */ +- if (ptid) ++ ret = __jbd2_log_start_commit(journal, tid); ++ if (ret && ptid) + *ptid = tid; +- ret = 1; +- } else if (journal->j_committing_transaction) { ++ } else if (journal->j_committing_transaction && ptid) { + /* + * If ext3_write_super() recently started a commit, then we + * have to wait for completion of that transaction + */ +- if (ptid) +- *ptid = journal->j_committing_transaction->t_tid; ++ *ptid = journal->j_committing_transaction->t_tid; + ret = 1; + } + spin_unlock(&journal->j_state_lock); +@@ -851,8 +846,8 @@ + jiffies_to_msecs(s->stats->u.run.rs_flushing / s->stats->ts_tid)); + seq_printf(seq, " %ums logging transaction\n", + jiffies_to_msecs(s->stats->u.run.rs_logging / s->stats->ts_tid)); +- seq_printf(seq, " %lluus average transaction commit time\n", +- div_u64(s->journal->j_average_commit_time, 1000)); ++ seq_printf(seq, " %luus average transaction commit time\n", ++ do_div(s->journal->j_average_commit_time, 1000)); + seq_printf(seq, " %lu handles per transaction\n", + s->stats->u.run.rs_handle_count / s->stats->ts_tid); + seq_printf(seq, " %lu blocks per transaction\n", +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/fs/jbd2/transaction.c linux-2.6.29-rc3.owrt/fs/jbd2/transaction.c +--- linux-2.6.29.owrt/fs/jbd2/transaction.c 2009-05-10 22:04:39.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/fs/jbd2/transaction.c 2009-05-10 23:48:29.000000000 +0200 +@@ -2129,46 +2129,26 @@ + } + + /* +- * File truncate and transaction commit interact with each other in a +- * non-trivial way. If a transaction writing data block A is +- * committing, we cannot discard the data by truncate until we have +- * written them. Otherwise if we crashed after the transaction with +- * write has committed but before the transaction with truncate has +- * committed, we could see stale data in block A. This function is a +- * helper to solve this problem. It starts writeout of the truncated +- * part in case it is in the committing transaction. +- * +- * Filesystem code must call this function when inode is journaled in +- * ordered mode before truncation happens and after the inode has been +- * placed on orphan list with the new inode size. The second condition +- * avoids the race that someone writes new data and we start +- * committing the transaction after this function has been called but +- * before a transaction for truncate is started (and furthermore it +- * allows us to optimize the case where the addition to orphan list +- * happens in the same transaction as write --- we don't have to write +- * any data in such case). ++ * This function must be called when inode is journaled in ordered mode ++ * before truncation happens. It starts writeout of truncated part in ++ * case it is in the committing transaction so that we stand to ordered ++ * mode consistency guarantees. + */ +-int jbd2_journal_begin_ordered_truncate(journal_t *journal, +- struct jbd2_inode *jinode, ++int jbd2_journal_begin_ordered_truncate(struct jbd2_inode *inode, + loff_t new_size) + { +- transaction_t *inode_trans, *commit_trans; ++ journal_t *journal; ++ transaction_t *commit_trans; + int ret = 0; + +- /* This is a quick check to avoid locking if not necessary */ +- if (!jinode->i_transaction) ++ if (!inode->i_transaction && !inode->i_next_transaction) + goto out; +- /* Locks are here just to force reading of recent values, it is +- * enough that the transaction was not committing before we started +- * a transaction adding the inode to orphan list */ ++ journal = inode->i_transaction->t_journal; + spin_lock(&journal->j_state_lock); + commit_trans = journal->j_committing_transaction; + spin_unlock(&journal->j_state_lock); +- spin_lock(&journal->j_list_lock); +- inode_trans = jinode->i_transaction; +- spin_unlock(&journal->j_list_lock); +- if (inode_trans == commit_trans) { +- ret = filemap_fdatawrite_range(jinode->i_vfs_inode->i_mapping, ++ if (inode->i_transaction == commit_trans) { ++ ret = filemap_fdatawrite_range(inode->i_vfs_inode->i_mapping, + new_size, LLONG_MAX); + if (ret) + jbd2_journal_abort(journal, ret); +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/fs/jffs2/background.c linux-2.6.29-rc3.owrt/fs/jffs2/background.c +--- linux-2.6.29.owrt/fs/jffs2/background.c 2009-05-10 22:04:39.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/fs/jffs2/background.c 2009-05-10 23:48:29.000000000 +0200 +@@ -95,17 +95,13 @@ + spin_unlock(&c->erase_completion_lock); + + +- /* Problem - immediately after bootup, the GCD spends a lot +- * of time in places like jffs2_kill_fragtree(); so much so +- * that userspace processes (like gdm and X) are starved +- * despite plenty of cond_resched()s and renicing. Yield() +- * doesn't help, either (presumably because userspace and GCD +- * are generally competing for a higher latency resource - +- * disk). +- * This forces the GCD to slow the hell down. Pulling an +- * inode in with read_inode() is much preferable to having +- * the GC thread get there first. */ +- schedule_timeout_interruptible(msecs_to_jiffies(50)); ++ /* This thread is purely an optimisation. But if it runs when ++ other things could be running, it actually makes things a ++ lot worse. Use yield() and put it at the back of the runqueue ++ every time. Especially during boot, pulling an inode in ++ with read_inode() is much preferable to having the GC thread ++ get there first. */ ++ yield(); + + /* Put_super will send a SIGKILL and then wait on the sem. + */ +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/fs/jffs2/readinode.c linux-2.6.29-rc3.owrt/fs/jffs2/readinode.c +--- linux-2.6.29.owrt/fs/jffs2/readinode.c 2009-05-10 22:04:39.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/fs/jffs2/readinode.c 2009-05-10 23:48:29.000000000 +0200 +@@ -220,7 +220,7 @@ + struct jffs2_tmp_dnode_info *tn) + { + uint32_t fn_end = tn->fn->ofs + tn->fn->size; +- struct jffs2_tmp_dnode_info *this, *ptn; ++ struct jffs2_tmp_dnode_info *this; + + dbg_readinode("insert fragment %#04x-%#04x, ver %u at %08x\n", tn->fn->ofs, fn_end, tn->version, ref_offset(tn->fn->raw)); + +@@ -251,18 +251,11 @@ + if (this) { + /* If the node is coincident with another at a lower address, + back up until the other node is found. It may be relevant */ +- while (this->overlapped) { +- ptn = tn_prev(this); +- if (!ptn) { +- /* +- * We killed a node which set the overlapped +- * flags during the scan. Fix it up. +- */ +- this->overlapped = 0; +- break; +- } +- this = ptn; +- } ++ while (this->overlapped) ++ this = tn_prev(this); ++ ++ /* First node should never be marked overlapped */ ++ BUG_ON(!this); + dbg_readinode("'this' found %#04x-%#04x (%s)\n", this->fn->ofs, this->fn->ofs + this->fn->size, this->fn ? "data" : "hole"); + } + +@@ -367,17 +360,7 @@ + } + if (!this->overlapped) + break; +- +- ptn = tn_prev(this); +- if (!ptn) { +- /* +- * We killed a node which set the overlapped +- * flags during the scan. Fix it up. +- */ +- this->overlapped = 0; +- break; +- } +- this = ptn; ++ this = tn_prev(this); + } + } + +@@ -473,15 +456,8 @@ + eat_last(&rii->tn_root, &last->rb); + ver_insert(&ver_root, last); + +- if (unlikely(last->overlapped)) { +- if (pen) +- continue; +- /* +- * We killed a node which set the overlapped +- * flags during the scan. Fix it up. +- */ +- last->overlapped = 0; +- } ++ if (unlikely(last->overlapped)) ++ continue; + + /* Now we have a bunch of nodes in reverse version + order, in the tree at ver_root. Most of the time, +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/fs/lockd/clntlock.c linux-2.6.29-rc3.owrt/fs/lockd/clntlock.c +--- linux-2.6.29.owrt/fs/lockd/clntlock.c 2009-05-10 22:04:39.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/fs/lockd/clntlock.c 2009-05-10 23:48:29.000000000 +0200 +@@ -139,55 +139,6 @@ + return 0; + } + +-#if defined(CONFIG_IPV6) || defined(CONFIG_IPV6_MODULE) +-static const struct in6_addr *nlmclnt_map_v4addr(const struct sockaddr *sap, +- struct in6_addr *addr_mapped) +-{ +- const struct sockaddr_in *sin = (const struct sockaddr_in *)sap; +- +- switch (sap->sa_family) { +- case AF_INET6: +- return &((const struct sockaddr_in6 *)sap)->sin6_addr; +- case AF_INET: +- ipv6_addr_set_v4mapped(sin->sin_addr.s_addr, addr_mapped); +- return addr_mapped; +- } +- +- return NULL; +-} +- +-/* +- * If lockd is using a PF_INET6 listener, all incoming requests appear +- * to come from AF_INET6 remotes. The address of AF_INET remotes are +- * mapped to AF_INET6 automatically by the network layer. In case the +- * user passed an AF_INET server address at mount time, ensure both +- * addresses are AF_INET6 before comparing them. +- */ +-static int nlmclnt_cmp_addr(const struct nlm_host *host, +- const struct sockaddr *sap) +-{ +- const struct in6_addr *addr1; +- const struct in6_addr *addr2; +- struct in6_addr addr1_mapped; +- struct in6_addr addr2_mapped; +- +- addr1 = nlmclnt_map_v4addr(nlm_addr(host), &addr1_mapped); +- if (likely(addr1 != NULL)) { +- addr2 = nlmclnt_map_v4addr(sap, &addr2_mapped); +- if (likely(addr2 != NULL)) +- return ipv6_addr_equal(addr1, addr2); +- } +- +- return 0; +-} +-#else /* !(CONFIG_IPV6 || CONFIG_IPV6_MODULE) */ +-static int nlmclnt_cmp_addr(const struct nlm_host *host, +- const struct sockaddr *sap) +-{ +- return nlm_cmp_addr(nlm_addr(host), sap); +-} +-#endif /* !(CONFIG_IPV6 || CONFIG_IPV6_MODULE) */ +- + /* + * The server lockd has called us back to tell us the lock was granted + */ +@@ -215,7 +166,7 @@ + */ + if (fl_blocked->fl_u.nfs_fl.owner->pid != lock->svid) + continue; +- if (!nlmclnt_cmp_addr(block->b_host, addr)) ++ if (!nlm_cmp_addr(nlm_addr(block->b_host), addr)) + continue; + if (nfs_compare_fh(NFS_FH(fl_blocked->fl_file->f_path.dentry->d_inode) ,fh) != 0) + continue; +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/fs/lockd/svclock.c linux-2.6.29-rc3.owrt/fs/lockd/svclock.c +--- linux-2.6.29.owrt/fs/lockd/svclock.c 2009-05-10 22:04:39.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/fs/lockd/svclock.c 2009-05-10 23:48:29.000000000 +0200 +@@ -427,7 +427,7 @@ + goto out; + case -EAGAIN: + ret = nlm_lck_denied; +- break; ++ goto out; + case FILE_LOCK_DEFERRED: + if (wait) + break; +@@ -443,10 +443,6 @@ + goto out; + } + +- ret = nlm_lck_denied; +- if (!wait) +- goto out; +- + ret = nlm_lck_blocked; + + /* Append to list of blocked */ +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/fs/Makefile linux-2.6.29-rc3.owrt/fs/Makefile +--- linux-2.6.29.owrt/fs/Makefile 2009-05-10 22:04:39.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/fs/Makefile 2009-05-10 23:48:29.000000000 +0200 +@@ -69,12 +69,10 @@ + # Do not add any filesystems before this line + obj-$(CONFIG_REISERFS_FS) += reiserfs/ + obj-$(CONFIG_EXT3_FS) += ext3/ # Before ext2 so root fs can be ext3 +-obj-$(CONFIG_EXT2_FS) += ext2/ +-# We place ext4 after ext2 so plain ext2 root fs's are mounted using ext2 +-# unless explicitly requested by rootfstype +-obj-$(CONFIG_EXT4_FS) += ext4/ ++obj-$(CONFIG_EXT4_FS) += ext4/ # Before ext2 so root fs can be ext4 + obj-$(CONFIG_JBD) += jbd/ + obj-$(CONFIG_JBD2) += jbd2/ ++obj-$(CONFIG_EXT2_FS) += ext2/ + obj-$(CONFIG_CRAMFS) += cramfs/ + obj-$(CONFIG_SQUASHFS) += squashfs/ + obj-y += ramfs/ +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/fs/minix/inode.c linux-2.6.29-rc3.owrt/fs/minix/inode.c +--- linux-2.6.29.owrt/fs/minix/inode.c 2009-05-10 22:04:39.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/fs/minix/inode.c 2009-05-10 23:48:29.000000000 +0200 +@@ -3,7 +3,7 @@ + * + * Copyright (C) 1991, 1992 Linus Torvalds + * +- * Copyright (C) 1996 Gertjan van Wingerde ++ * Copyright (C) 1996 Gertjan van Wingerde (gertjan@cs.vu.nl) + * Minix V2 fs support. + * + * Modified for 680x0 by Andreas Schwab +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/fs/namespace.c linux-2.6.29-rc3.owrt/fs/namespace.c +--- linux-2.6.29.owrt/fs/namespace.c 2009-05-10 22:04:39.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/fs/namespace.c 2009-05-10 23:48:29.000000000 +0200 +@@ -614,11 +614,9 @@ + */ + for_each_possible_cpu(cpu) { + struct mnt_writer *cpu_writer = &per_cpu(mnt_writers, cpu); +- spin_lock(&cpu_writer->lock); +- if (cpu_writer->mnt != mnt) { +- spin_unlock(&cpu_writer->lock); ++ if (cpu_writer->mnt != mnt) + continue; +- } ++ spin_lock(&cpu_writer->lock); + atomic_add(cpu_writer->count, &mnt->__mnt_writers); + cpu_writer->count = 0; + /* +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/fs/nfs/client.c linux-2.6.29-rc3.owrt/fs/nfs/client.c +--- linux-2.6.29.owrt/fs/nfs/client.c 2009-05-10 22:04:39.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/fs/nfs/client.c 2009-05-10 23:48:29.000000000 +0200 +@@ -255,32 +255,6 @@ + } + return 0; + } +- +-/* +- * Test if two ip6 socket addresses refer to the same socket by +- * comparing relevant fields. The padding bytes specifically, are not +- * compared. sin6_flowinfo is not compared because it only affects QoS +- * and sin6_scope_id is only compared if the address is "link local" +- * because "link local" addresses need only be unique to a specific +- * link. Conversely, ordinary unicast addresses might have different +- * sin6_scope_id. +- * +- * The caller should ensure both socket addresses are AF_INET6. +- */ +-static int nfs_sockaddr_cmp_ip6(const struct sockaddr *sa1, +- const struct sockaddr *sa2) +-{ +- const struct sockaddr_in6 *saddr1 = (const struct sockaddr_in6 *)sa1; +- const struct sockaddr_in6 *saddr2 = (const struct sockaddr_in6 *)sa2; +- +- if (!ipv6_addr_equal(&saddr1->sin6_addr, +- &saddr1->sin6_addr)) +- return 0; +- if (ipv6_addr_scope(&saddr1->sin6_addr) == IPV6_ADDR_SCOPE_LINKLOCAL && +- saddr1->sin6_scope_id != saddr2->sin6_scope_id) +- return 0; +- return saddr1->sin6_port == saddr2->sin6_port; +-} + #else + static int nfs_sockaddr_match_ipaddr4(const struct sockaddr_in *sa1, + const struct sockaddr_in *sa2) +@@ -296,52 +270,9 @@ + return nfs_sockaddr_match_ipaddr4((const struct sockaddr_in *)sa1, + (const struct sockaddr_in *)sa2); + } +- +-static int nfs_sockaddr_cmp_ip6(const struct sockaddr * sa1, +- const struct sockaddr * sa2) +-{ +- return 0; +-} + #endif + + /* +- * Test if two ip4 socket addresses refer to the same socket, by +- * comparing relevant fields. The padding bytes specifically, are +- * not compared. +- * +- * The caller should ensure both socket addresses are AF_INET. +- */ +-static int nfs_sockaddr_cmp_ip4(const struct sockaddr *sa1, +- const struct sockaddr *sa2) +-{ +- const struct sockaddr_in *saddr1 = (const struct sockaddr_in *)sa1; +- const struct sockaddr_in *saddr2 = (const struct sockaddr_in *)sa2; +- +- if (saddr1->sin_addr.s_addr != saddr2->sin_addr.s_addr) +- return 0; +- return saddr1->sin_port == saddr2->sin_port; +-} +- +-/* +- * Test if two socket addresses represent the same actual socket, +- * by comparing (only) relevant fields. +- */ +-static int nfs_sockaddr_cmp(const struct sockaddr *sa1, +- const struct sockaddr *sa2) +-{ +- if (sa1->sa_family != sa2->sa_family) +- return 0; +- +- switch (sa1->sa_family) { +- case AF_INET: +- return nfs_sockaddr_cmp_ip4(sa1, sa2); +- case AF_INET6: +- return nfs_sockaddr_cmp_ip6(sa1, sa2); +- } +- return 0; +-} +- +-/* + * Find a client by IP address and protocol version + * - returns NULL if no such client + */ +@@ -413,10 +344,8 @@ + static struct nfs_client *nfs_match_client(const struct nfs_client_initdata *data) + { + struct nfs_client *clp; +- const struct sockaddr *sap = data->addr; + + list_for_each_entry(clp, &nfs_client_list, cl_share_link) { +- const struct sockaddr *clap = (struct sockaddr *)&clp->cl_addr; + /* Don't match clients that failed to initialise properly */ + if (clp->cl_cons_state < 0) + continue; +@@ -429,7 +358,7 @@ + continue; + + /* Match the full socket address */ +- if (!nfs_sockaddr_cmp(sap, clap)) ++ if (memcmp(&clp->cl_addr, data->addr, sizeof(clp->cl_addr)) != 0) + continue; + + atomic_inc(&clp->cl_count); +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/fs/nfs/dir.c linux-2.6.29-rc3.owrt/fs/nfs/dir.c +--- linux-2.6.29.owrt/fs/nfs/dir.c 2009-05-10 22:04:39.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/fs/nfs/dir.c 2009-05-10 23:48:29.000000000 +0200 +@@ -1892,14 +1892,8 @@ + cache.cred = cred; + cache.jiffies = jiffies; + status = NFS_PROTO(inode)->access(inode, &cache); +- if (status != 0) { +- if (status == -ESTALE) { +- nfs_zap_caches(inode); +- if (!S_ISDIR(inode->i_mode)) +- set_bit(NFS_INO_STALE, &NFS_I(inode)->flags); +- } ++ if (status != 0) + return status; +- } + nfs_access_add_cache(inode, &cache); + out: + if ((mask & ~cache.mask & (MAY_READ | MAY_WRITE | MAY_EXEC)) == 0) +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/fs/nfs/nfs3acl.c linux-2.6.29-rc3.owrt/fs/nfs/nfs3acl.c +--- linux-2.6.29.owrt/fs/nfs/nfs3acl.c 2009-05-10 22:04:39.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/fs/nfs/nfs3acl.c 2009-05-10 23:48:29.000000000 +0200 +@@ -292,7 +292,7 @@ + { + struct nfs_server *server = NFS_SERVER(inode); + struct nfs_fattr fattr; +- struct page *pages[NFSACL_MAXPAGES]; ++ struct page *pages[NFSACL_MAXPAGES] = { }; + struct nfs3_setaclargs args = { + .inode = inode, + .mask = NFS_ACL, +@@ -303,7 +303,7 @@ + .rpc_argp = &args, + .rpc_resp = &fattr, + }; +- int status; ++ int status, count; + + status = -EOPNOTSUPP; + if (!nfs_server_capable(inode, NFS_CAP_ACLS)) +@@ -319,20 +319,6 @@ + if (S_ISDIR(inode->i_mode)) { + args.mask |= NFS_DFACL; + args.acl_default = dfacl; +- args.len = nfsacl_size(acl, dfacl); +- } else +- args.len = nfsacl_size(acl, NULL); +- +- if (args.len > NFS_ACL_INLINE_BUFSIZE) { +- unsigned int npages = 1 + ((args.len - 1) >> PAGE_SHIFT); +- +- status = -ENOMEM; +- do { +- args.pages[args.npages] = alloc_page(GFP_KERNEL); +- if (args.pages[args.npages] == NULL) +- goto out_freepages; +- args.npages++; +- } while (args.npages < npages); + } + + dprintk("NFS call setacl\n"); +@@ -343,6 +329,10 @@ + nfs_zap_acl_cache(inode); + dprintk("NFS reply setacl: %d\n", status); + ++ /* pages may have been allocated at the xdr layer. */ ++ for (count = 0; count < NFSACL_MAXPAGES && args.pages[count]; count++) ++ __free_page(args.pages[count]); ++ + switch (status) { + case 0: + status = nfs_refresh_inode(inode, &fattr); +@@ -356,11 +346,6 @@ + case -ENOTSUPP: + status = -EOPNOTSUPP; + } +-out_freepages: +- while (args.npages != 0) { +- args.npages--; +- __free_page(args.pages[args.npages]); +- } + out: + return status; + } +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/fs/nfs/nfs3xdr.c linux-2.6.29-rc3.owrt/fs/nfs/nfs3xdr.c +--- linux-2.6.29.owrt/fs/nfs/nfs3xdr.c 2009-05-10 22:04:39.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/fs/nfs/nfs3xdr.c 2009-05-10 23:48:29.000000000 +0200 +@@ -82,10 +82,8 @@ + #define NFS3_commitres_sz (1+NFS3_wcc_data_sz+2) + + #define ACL3_getaclargs_sz (NFS3_fh_sz+1) +-#define ACL3_setaclargs_sz (NFS3_fh_sz+1+ \ +- XDR_QUADLEN(NFS_ACL_INLINE_BUFSIZE)) +-#define ACL3_getaclres_sz (1+NFS3_post_op_attr_sz+1+ \ +- XDR_QUADLEN(NFS_ACL_INLINE_BUFSIZE)) ++#define ACL3_setaclargs_sz (NFS3_fh_sz+1+2*(2+5*3)) ++#define ACL3_getaclres_sz (1+NFS3_post_op_attr_sz+1+2*(2+5*3)) + #define ACL3_setaclres_sz (1+NFS3_post_op_attr_sz) + + /* +@@ -705,18 +703,28 @@ + struct nfs3_setaclargs *args) + { + struct xdr_buf *buf = &req->rq_snd_buf; +- unsigned int base; +- int err; ++ unsigned int base, len_in_head, len = nfsacl_size( ++ (args->mask & NFS_ACL) ? args->acl_access : NULL, ++ (args->mask & NFS_DFACL) ? args->acl_default : NULL); ++ int count, err; + + p = xdr_encode_fhandle(p, NFS_FH(args->inode)); + *p++ = htonl(args->mask); +- req->rq_slen = xdr_adjust_iovec(req->rq_svec, p); +- base = req->rq_slen; +- +- if (args->npages != 0) +- xdr_encode_pages(buf, args->pages, 0, args->len); +- else +- req->rq_slen += args->len; ++ base = (char *)p - (char *)buf->head->iov_base; ++ /* put as much of the acls into head as possible. */ ++ len_in_head = min_t(unsigned int, buf->head->iov_len - base, len); ++ len -= len_in_head; ++ req->rq_slen = xdr_adjust_iovec(req->rq_svec, p + (len_in_head >> 2)); ++ ++ for (count = 0; (count << PAGE_SHIFT) < len; count++) { ++ args->pages[count] = alloc_page(GFP_KERNEL); ++ if (!args->pages[count]) { ++ while (count) ++ __free_page(args->pages[--count]); ++ return -ENOMEM; ++ } ++ } ++ xdr_encode_pages(buf, args->pages, 0, len); + + err = nfsacl_encode(buf, base, args->inode, + (args->mask & NFS_ACL) ? +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/fs/nfs/nfs4namespace.c linux-2.6.29-rc3.owrt/fs/nfs/nfs4namespace.c +--- linux-2.6.29.owrt/fs/nfs/nfs4namespace.c 2009-05-10 22:04:39.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/fs/nfs/nfs4namespace.c 2009-05-10 23:48:29.000000000 +0200 +@@ -21,9 +21,7 @@ + #define NFSDBG_FACILITY NFSDBG_VFS + + /* +- * Convert the NFSv4 pathname components into a standard posix path. +- * +- * Note that the resulting string will be placed at the end of the buffer ++ * Check if fs_root is valid + */ + static inline char *nfs4_pathname_string(const struct nfs4_pathname *pathname, + char *buffer, ssize_t buflen) +@@ -101,20 +99,21 @@ + { + struct vfsmount *mnt = ERR_PTR(-ENOENT); + char *mnt_path; +- unsigned int maxbuflen; ++ int page2len; + unsigned int s; + + mnt_path = nfs4_pathname_string(&location->rootpath, page2, PAGE_SIZE); + if (IS_ERR(mnt_path)) + return mnt; + mountdata->mnt_path = mnt_path; +- maxbuflen = mnt_path - 1 - page2; ++ page2 += strlen(mnt_path) + 1; ++ page2len = PAGE_SIZE - strlen(mnt_path) - 1; + + for (s = 0; s < location->nservers; s++) { + const struct nfs4_string *buf = &location->servers[s]; + struct sockaddr_storage addr; + +- if (buf->len <= 0 || buf->len >= maxbuflen) ++ if (buf->len <= 0 || buf->len >= PAGE_SIZE) + continue; + + mountdata->addr = (struct sockaddr *)&addr; +@@ -127,8 +126,8 @@ + continue; + nfs_set_port(mountdata->addr, NFS_PORT); + +- memcpy(page2, buf->data, buf->len); +- page2[buf->len] = '\0'; ++ strncpy(page2, buf->data, page2len); ++ page2[page2len] = '\0'; + mountdata->hostname = page2; + + snprintf(page, PAGE_SIZE, "%s:%s", +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/fs/nfsd/nfs4xdr.c linux-2.6.29-rc3.owrt/fs/nfsd/nfs4xdr.c +--- linux-2.6.29.owrt/fs/nfsd/nfs4xdr.c 2009-05-10 22:04:39.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/fs/nfsd/nfs4xdr.c 2009-05-10 23:48:29.000000000 +0200 +@@ -2596,7 +2596,6 @@ + [OP_LOOKUPP] = (nfsd4_enc)nfsd4_encode_noop, + [OP_NVERIFY] = (nfsd4_enc)nfsd4_encode_noop, + [OP_OPEN] = (nfsd4_enc)nfsd4_encode_open, +- [OP_OPENATTR] = (nfsd4_enc)nfsd4_encode_noop, + [OP_OPEN_CONFIRM] = (nfsd4_enc)nfsd4_encode_open_confirm, + [OP_OPEN_DOWNGRADE] = (nfsd4_enc)nfsd4_encode_open_downgrade, + [OP_PUTFH] = (nfsd4_enc)nfsd4_encode_noop, +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/fs/notify/inotify/inotify.c linux-2.6.29-rc3.owrt/fs/notify/inotify/inotify.c +--- linux-2.6.29.owrt/fs/notify/inotify/inotify.c 2009-05-10 22:04:39.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/fs/notify/inotify/inotify.c 2009-05-10 23:48:29.000000000 +0200 +@@ -156,7 +156,7 @@ + int ret; + + do { +- if (unlikely(!idr_pre_get(&ih->idr, GFP_NOFS))) ++ if (unlikely(!idr_pre_get(&ih->idr, GFP_KERNEL))) + return -ENOSPC; + ret = idr_get_new_above(&ih->idr, watch, ih->last_wd+1, &watch->wd); + } while (ret == -EAGAIN); +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/fs/ocfs2/alloc.c linux-2.6.29-rc3.owrt/fs/ocfs2/alloc.c +--- linux-2.6.29.owrt/fs/ocfs2/alloc.c 2009-05-10 22:04:39.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/fs/ocfs2/alloc.c 2009-05-10 23:48:29.000000000 +0200 +@@ -176,8 +176,7 @@ + + BUG_ON(OCFS2_I(inode)->ip_dyn_features & OCFS2_INLINE_DATA_FL); + mlog_bug_on_msg(!ocfs2_sparse_alloc(osb) && +- (OCFS2_I(inode)->ip_clusters != +- le32_to_cpu(rec->e_cpos)), ++ (OCFS2_I(inode)->ip_clusters != rec->e_cpos), + "Device %s, asking for sparse allocation: inode %llu, " + "cpos %u, clusters %u\n", + osb->dev_str, +@@ -4797,29 +4796,6 @@ + return ret; + } + +-static int ocfs2_replace_extent_rec(struct inode *inode, +- handle_t *handle, +- struct ocfs2_path *path, +- struct ocfs2_extent_list *el, +- int split_index, +- struct ocfs2_extent_rec *split_rec) +-{ +- int ret; +- +- ret = ocfs2_path_bh_journal_access(handle, inode, path, +- path_num_items(path) - 1); +- if (ret) { +- mlog_errno(ret); +- goto out; +- } +- +- el->l_recs[split_index] = *split_rec; +- +- ocfs2_journal_dirty(handle, path_leaf_bh(path)); +-out: +- return ret; +-} +- + /* + * Mark part or all of the extent record at split_index in the leaf + * pointed to by path as written. This removes the unwritten +@@ -4909,9 +4885,7 @@ + + if (ctxt.c_contig_type == CONTIG_NONE) { + if (ctxt.c_split_covers_rec) +- ret = ocfs2_replace_extent_rec(inode, handle, +- path, el, +- split_index, split_rec); ++ el->l_recs[split_index] = *split_rec; + else + ret = ocfs2_split_and_insert(inode, handle, path, et, + &last_eb_bh, split_index, +@@ -5416,9 +5390,6 @@ + goto out; + } + +- vfs_dq_free_space_nodirty(inode, +- ocfs2_clusters_to_bytes(inode->i_sb, len)); +- + ret = ocfs2_remove_extent(inode, et, cpos, len, handle, meta_ac, + dealloc); + if (ret) { +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/fs/ocfs2/aops.c linux-2.6.29-rc3.owrt/fs/ocfs2/aops.c +--- linux-2.6.29.owrt/fs/ocfs2/aops.c 2009-05-10 22:04:39.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/fs/ocfs2/aops.c 2009-05-10 23:48:29.000000000 +0200 +@@ -227,7 +227,7 @@ + size = i_size_read(inode); + + if (size > PAGE_CACHE_SIZE || +- size > ocfs2_max_inline_data_with_xattr(inode->i_sb, di)) { ++ size > ocfs2_max_inline_data(inode->i_sb)) { + ocfs2_error(inode->i_sb, + "Inode %llu has with inline data has bad size: %Lu", + (unsigned long long)OCFS2_I(inode)->ip_blkno, +@@ -1555,7 +1555,6 @@ + int ret, written = 0; + loff_t end = pos + len; + struct ocfs2_inode_info *oi = OCFS2_I(inode); +- struct ocfs2_dinode *di = NULL; + + mlog(0, "Inode %llu, write of %u bytes at off %llu. features: 0x%x\n", + (unsigned long long)oi->ip_blkno, len, (unsigned long long)pos, +@@ -1588,9 +1587,7 @@ + /* + * Check whether the write can fit. + */ +- di = (struct ocfs2_dinode *)wc->w_di_bh->b_data; +- if (mmap_page || +- end > ocfs2_max_inline_data_with_xattr(inode->i_sb, di)) ++ if (mmap_page || end > ocfs2_max_inline_data(inode->i_sb)) + return 0; + + do_inline_write: +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/fs/ocfs2/dcache.c linux-2.6.29-rc3.owrt/fs/ocfs2/dcache.c +--- linux-2.6.29.owrt/fs/ocfs2/dcache.c 2009-05-10 22:04:39.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/fs/ocfs2/dcache.c 2009-05-10 23:48:29.000000000 +0200 +@@ -38,7 +38,6 @@ + #include "dlmglue.h" + #include "file.h" + #include "inode.h" +-#include "super.h" + + + static int ocfs2_dentry_revalidate(struct dentry *dentry, +@@ -295,34 +294,6 @@ + return ret; + } + +-static DEFINE_SPINLOCK(dentry_list_lock); +- +-/* We limit the number of dentry locks to drop in one go. We have +- * this limit so that we don't starve other users of ocfs2_wq. */ +-#define DL_INODE_DROP_COUNT 64 +- +-/* Drop inode references from dentry locks */ +-void ocfs2_drop_dl_inodes(struct work_struct *work) +-{ +- struct ocfs2_super *osb = container_of(work, struct ocfs2_super, +- dentry_lock_work); +- struct ocfs2_dentry_lock *dl; +- int drop_count = DL_INODE_DROP_COUNT; +- +- spin_lock(&dentry_list_lock); +- while (osb->dentry_lock_list && drop_count--) { +- dl = osb->dentry_lock_list; +- osb->dentry_lock_list = dl->dl_next; +- spin_unlock(&dentry_list_lock); +- iput(dl->dl_inode); +- kfree(dl); +- spin_lock(&dentry_list_lock); +- } +- if (osb->dentry_lock_list) +- queue_work(ocfs2_wq, &osb->dentry_lock_work); +- spin_unlock(&dentry_list_lock); +-} +- + /* + * ocfs2_dentry_iput() and friends. + * +@@ -347,23 +318,16 @@ + static void ocfs2_drop_dentry_lock(struct ocfs2_super *osb, + struct ocfs2_dentry_lock *dl) + { ++ iput(dl->dl_inode); + ocfs2_simple_drop_lockres(osb, &dl->dl_lockres); + ocfs2_lock_res_free(&dl->dl_lockres); +- +- /* We leave dropping of inode reference to ocfs2_wq as that can +- * possibly lead to inode deletion which gets tricky */ +- spin_lock(&dentry_list_lock); +- if (!osb->dentry_lock_list) +- queue_work(ocfs2_wq, &osb->dentry_lock_work); +- dl->dl_next = osb->dentry_lock_list; +- osb->dentry_lock_list = dl; +- spin_unlock(&dentry_list_lock); ++ kfree(dl); + } + + void ocfs2_dentry_lock_put(struct ocfs2_super *osb, + struct ocfs2_dentry_lock *dl) + { +- int unlock; ++ int unlock = 0; + + BUG_ON(dl->dl_count == 0); + +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/fs/ocfs2/dcache.h linux-2.6.29-rc3.owrt/fs/ocfs2/dcache.h +--- linux-2.6.29.owrt/fs/ocfs2/dcache.h 2009-05-10 22:04:39.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/fs/ocfs2/dcache.h 2009-05-10 23:48:29.000000000 +0200 +@@ -29,13 +29,8 @@ + extern struct dentry_operations ocfs2_dentry_ops; + + struct ocfs2_dentry_lock { +- /* Use count of dentry lock */ + unsigned int dl_count; +- union { +- /* Linked list of dentry locks to release */ +- struct ocfs2_dentry_lock *dl_next; +- u64 dl_parent_blkno; +- }; ++ u64 dl_parent_blkno; + + /* + * The ocfs2_dentry_lock keeps an inode reference until +@@ -52,8 +47,6 @@ + void ocfs2_dentry_lock_put(struct ocfs2_super *osb, + struct ocfs2_dentry_lock *dl); + +-void ocfs2_drop_dl_inodes(struct work_struct *work); +- + struct dentry *ocfs2_find_local_alias(struct inode *inode, u64 parent_blkno, + int skip_unhashed); + +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/fs/ocfs2/dlm/dlmmaster.c linux-2.6.29-rc3.owrt/fs/ocfs2/dlm/dlmmaster.c +--- linux-2.6.29.owrt/fs/ocfs2/dlm/dlmmaster.c 2009-05-10 22:04:39.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/fs/ocfs2/dlm/dlmmaster.c 2009-05-10 23:48:29.000000000 +0200 +@@ -1849,12 +1849,12 @@ + if (!mle) { + if (res->owner != DLM_LOCK_RES_OWNER_UNKNOWN && + res->owner != assert->node_idx) { +- mlog(ML_ERROR, "DIE! Mastery assert from %u, " +- "but current owner is %u! (%.*s)\n", +- assert->node_idx, res->owner, namelen, +- name); +- __dlm_print_one_lock_resource(res); +- BUG(); ++ mlog(ML_ERROR, "assert_master from " ++ "%u, but current owner is " ++ "%u! (%.*s)\n", ++ assert->node_idx, res->owner, ++ namelen, name); ++ goto kill; + } + } else if (mle->type != DLM_MLE_MIGRATION) { + if (res->owner != DLM_LOCK_RES_OWNER_UNKNOWN) { +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/fs/ocfs2/dlm/dlmthread.c linux-2.6.29-rc3.owrt/fs/ocfs2/dlm/dlmthread.c +--- linux-2.6.29.owrt/fs/ocfs2/dlm/dlmthread.c 2009-05-10 22:04:39.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/fs/ocfs2/dlm/dlmthread.c 2009-05-10 23:48:29.000000000 +0200 +@@ -181,7 +181,8 @@ + + spin_lock(&res->spinlock); + /* This ensures that clear refmap is sent after the set */ +- __dlm_wait_on_lockres_flags(res, DLM_LOCK_RES_SETREF_INPROG); ++ __dlm_wait_on_lockres_flags(res, (DLM_LOCK_RES_SETREF_INPROG | ++ DLM_LOCK_RES_MIGRATING)); + spin_unlock(&res->spinlock); + + /* clear our bit from the master's refmap, ignore errors */ +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/fs/ocfs2/dlm/dlmunlock.c linux-2.6.29-rc3.owrt/fs/ocfs2/dlm/dlmunlock.c +--- linux-2.6.29.owrt/fs/ocfs2/dlm/dlmunlock.c 2009-05-10 22:04:39.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/fs/ocfs2/dlm/dlmunlock.c 2009-05-10 23:48:29.000000000 +0200 +@@ -117,11 +117,11 @@ + else + BUG_ON(res->owner == dlm->node_num); + +- spin_lock(&dlm->ast_lock); ++ spin_lock(&dlm->spinlock); + /* We want to be sure that we're not freeing a lock + * that still has AST's pending... */ + in_use = !list_empty(&lock->ast_list); +- spin_unlock(&dlm->ast_lock); ++ spin_unlock(&dlm->spinlock); + if (in_use) { + mlog(ML_ERROR, "lockres %.*s: Someone is calling dlmunlock " + "while waiting for an ast!", res->lockname.len, +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/fs/ocfs2/dlmglue.c linux-2.6.29-rc3.owrt/fs/ocfs2/dlmglue.c +--- linux-2.6.29.owrt/fs/ocfs2/dlmglue.c 2009-05-10 22:04:39.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/fs/ocfs2/dlmglue.c 2009-05-10 23:48:29.000000000 +0200 +@@ -320,14 +320,9 @@ + struct ocfs2_lock_res *lockres); + static inline void ocfs2_recover_from_dlm_error(struct ocfs2_lock_res *lockres, + int convert); +-#define ocfs2_log_dlm_error(_func, _err, _lockres) do { \ +- if ((_lockres)->l_type != OCFS2_LOCK_TYPE_DENTRY) \ +- mlog(ML_ERROR, "DLM error %d while calling %s on resource %s\n", \ +- _err, _func, _lockres->l_name); \ +- else \ +- mlog(ML_ERROR, "DLM error %d while calling %s on resource %.*s%08x\n", \ +- _err, _func, OCFS2_DENTRY_LOCK_INO_START - 1, (_lockres)->l_name, \ +- (unsigned int)ocfs2_get_dentry_lock_ino(_lockres)); \ ++#define ocfs2_log_dlm_error(_func, _err, _lockres) do { \ ++ mlog(ML_ERROR, "DLM error %d while calling %s on resource %s\n", \ ++ _err, _func, _lockres->l_name); \ + } while (0) + static int ocfs2_downconvert_thread(void *arg); + static void ocfs2_downconvert_on_unlock(struct ocfs2_super *osb, +@@ -2865,10 +2860,6 @@ + case OCFS2_UNLOCK_CANCEL_CONVERT: + mlog(0, "Cancel convert success for %s\n", lockres->l_name); + lockres->l_action = OCFS2_AST_INVALID; +- /* Downconvert thread may have requeued this lock, we +- * need to wake it. */ +- if (lockres->l_flags & OCFS2_LOCK_BLOCKED) +- ocfs2_wake_downconvert_thread(ocfs2_get_lockres_osb(lockres)); + break; + case OCFS2_UNLOCK_DROP_LOCK: + lockres->l_level = DLM_LOCK_IV; +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/fs/ocfs2/journal.h linux-2.6.29-rc3.owrt/fs/ocfs2/journal.h +--- linux-2.6.29.owrt/fs/ocfs2/journal.h 2009-05-10 22:04:39.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/fs/ocfs2/journal.h 2009-05-10 23:48:29.000000000 +0200 +@@ -513,10 +513,8 @@ + static inline int ocfs2_begin_ordered_truncate(struct inode *inode, + loff_t new_size) + { +- return jbd2_journal_begin_ordered_truncate( +- OCFS2_SB(inode->i_sb)->journal->j_journal, +- &OCFS2_I(inode)->ip_jinode, +- new_size); ++ return jbd2_journal_begin_ordered_truncate(&OCFS2_I(inode)->ip_jinode, ++ new_size); + } + + #endif /* OCFS2_JOURNAL_H */ +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/fs/ocfs2/namei.c linux-2.6.29-rc3.owrt/fs/ocfs2/namei.c +--- linux-2.6.29.owrt/fs/ocfs2/namei.c 2009-05-10 22:04:39.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/fs/ocfs2/namei.c 2009-05-10 23:48:29.000000000 +0200 +@@ -532,8 +532,7 @@ + + fe->i_dyn_features = cpu_to_le16(feat | OCFS2_INLINE_DATA_FL); + +- fe->id2.i_data.id_count = cpu_to_le16( +- ocfs2_max_inline_data_with_xattr(osb->sb, fe)); ++ fe->id2.i_data.id_count = cpu_to_le16(ocfs2_max_inline_data(osb->sb)); + } else { + fel = &fe->id2.i_list; + fel->l_tree_depth = 0; +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/fs/ocfs2/ocfs2_fs.h linux-2.6.29-rc3.owrt/fs/ocfs2/ocfs2_fs.h +--- linux-2.6.29.owrt/fs/ocfs2/ocfs2_fs.h 2009-05-10 22:04:39.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/fs/ocfs2/ocfs2_fs.h 2009-05-10 23:48:29.000000000 +0200 +@@ -1070,6 +1070,12 @@ + offsetof(struct ocfs2_dinode, id2.i_symlink); + } + ++static inline int ocfs2_max_inline_data(struct super_block *sb) ++{ ++ return sb->s_blocksize - ++ offsetof(struct ocfs2_dinode, id2.i_data.id_data); ++} ++ + static inline int ocfs2_max_inline_data_with_xattr(struct super_block *sb, + struct ocfs2_dinode *di) + { +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/fs/ocfs2/ocfs2.h linux-2.6.29-rc3.owrt/fs/ocfs2/ocfs2.h +--- linux-2.6.29.owrt/fs/ocfs2/ocfs2.h 2009-05-10 22:04:39.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/fs/ocfs2/ocfs2.h 2009-05-10 23:48:29.000000000 +0200 +@@ -210,7 +210,6 @@ + struct ocfs2_slot_info; + struct ocfs2_recovery_map; + struct ocfs2_quota_recovery; +-struct ocfs2_dentry_lock; + struct ocfs2_super + { + struct task_struct *commit_task; +@@ -326,11 +325,6 @@ + struct list_head blocked_lock_list; + unsigned long blocked_lock_count; + +- /* List of dentry locks to release. Anyone can add locks to +- * the list, ocfs2_wq processes the list */ +- struct ocfs2_dentry_lock *dentry_lock_list; +- struct work_struct dentry_lock_work; +- + wait_queue_head_t osb_mount_event; + + /* Truncate log info */ +@@ -341,9 +335,6 @@ + struct ocfs2_node_map osb_recovering_orphan_dirs; + unsigned int *osb_orphan_wipes; + wait_queue_head_t osb_wipe_event; +- +- /* used to protect metaecc calculation check of xattr. */ +- spinlock_t osb_xattr_lock; + }; + + #define OCFS2_SB(sb) ((struct ocfs2_super *)(sb)->s_fs_info) +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/fs/ocfs2/quota_global.c linux-2.6.29-rc3.owrt/fs/ocfs2/quota_global.c +--- linux-2.6.29.owrt/fs/ocfs2/quota_global.c 2009-05-10 22:04:39.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/fs/ocfs2/quota_global.c 2009-05-10 23:48:29.000000000 +0200 +@@ -754,9 +754,7 @@ + if (dquot->dq_flags & mask) + sync = 1; + spin_unlock(&dq_data_lock); +- /* This is a slight hack but we can't afford getting global quota +- * lock if we already have a transaction started. */ +- if (!sync || journal_current_handle()) { ++ if (!sync) { + status = ocfs2_write_dquot(dquot); + goto out; + } +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/fs/ocfs2/super.c linux-2.6.29-rc3.owrt/fs/ocfs2/super.c +--- linux-2.6.29.owrt/fs/ocfs2/super.c 2009-05-10 22:04:39.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/fs/ocfs2/super.c 2009-05-10 23:48:29.000000000 +0200 +@@ -1537,13 +1537,6 @@ + unlock_buffer(*bh); + ll_rw_block(READ, 1, bh); + wait_on_buffer(*bh); +- if (!buffer_uptodate(*bh)) { +- mlog_errno(-EIO); +- brelse(*bh); +- *bh = NULL; +- return -EIO; +- } +- + return 0; + } + +@@ -1754,7 +1747,6 @@ + INIT_LIST_HEAD(&osb->blocked_lock_list); + osb->blocked_lock_count = 0; + spin_lock_init(&osb->osb_lock); +- spin_lock_init(&osb->osb_xattr_lock); + ocfs2_init_inode_steal_slot(osb); + + atomic_set(&osb->alloc_stats.moves, 0); +@@ -1895,9 +1887,6 @@ + INIT_WORK(&journal->j_recovery_work, ocfs2_complete_recovery); + journal->j_state = OCFS2_JOURNAL_FREE; + +- INIT_WORK(&osb->dentry_lock_work, ocfs2_drop_dl_inodes); +- osb->dentry_lock_list = NULL; +- + /* get some pseudo constants for clustersize bits */ + osb->s_clustersize_bits = + le32_to_cpu(di->id2.i_super.s_clustersize_bits); +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/fs/ocfs2/xattr.c linux-2.6.29-rc3.owrt/fs/ocfs2/xattr.c +--- linux-2.6.29.owrt/fs/ocfs2/xattr.c 2009-05-10 22:04:39.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/fs/ocfs2/xattr.c 2009-05-10 23:48:29.000000000 +0200 +@@ -82,14 +82,13 @@ + + #define OCFS2_XATTR_ROOT_SIZE (sizeof(struct ocfs2_xattr_def_value_root)) + #define OCFS2_XATTR_INLINE_SIZE 80 +-#define OCFS2_XATTR_HEADER_GAP 4 + #define OCFS2_XATTR_FREE_IN_IBODY (OCFS2_MIN_XATTR_INLINE_SIZE \ + - sizeof(struct ocfs2_xattr_header) \ +- - OCFS2_XATTR_HEADER_GAP) ++ - sizeof(__u32)) + #define OCFS2_XATTR_FREE_IN_BLOCK(ptr) ((ptr)->i_sb->s_blocksize \ + - sizeof(struct ocfs2_xattr_block) \ + - sizeof(struct ocfs2_xattr_header) \ +- - OCFS2_XATTR_HEADER_GAP) ++ - sizeof(__u32)) + + static struct ocfs2_xattr_def_value_root def_xv = { + .xv.xr_list.l_count = cpu_to_le16(1), +@@ -275,12 +274,10 @@ + bucket->bu_blocks, bucket->bu_bhs, 0, + NULL); + if (!rc) { +- spin_lock(&OCFS2_SB(bucket->bu_inode->i_sb)->osb_xattr_lock); + rc = ocfs2_validate_meta_ecc_bhs(bucket->bu_inode->i_sb, + bucket->bu_bhs, + bucket->bu_blocks, + &bucket_xh(bucket)->xh_check); +- spin_unlock(&OCFS2_SB(bucket->bu_inode->i_sb)->osb_xattr_lock); + if (rc) + mlog_errno(rc); + } +@@ -313,11 +310,9 @@ + { + int i; + +- spin_lock(&OCFS2_SB(bucket->bu_inode->i_sb)->osb_xattr_lock); + ocfs2_compute_meta_ecc_bhs(bucket->bu_inode->i_sb, + bucket->bu_bhs, bucket->bu_blocks, + &bucket_xh(bucket)->xh_check); +- spin_unlock(&OCFS2_SB(bucket->bu_inode->i_sb)->osb_xattr_lock); + + for (i = 0; i < bucket->bu_blocks; i++) + ocfs2_journal_dirty(handle, bucket->bu_bhs[i]); +@@ -547,12 +542,8 @@ + * when blocksize = 512, may reserve one more cluser for + * xattr bucket, otherwise reserve one metadata block + * for them is ok. +- * If this is a new directory with inline data, +- * we choose to reserve the entire inline area for +- * directory contents and force an external xattr block. + */ + if (dir->i_sb->s_blocksize == OCFS2_MIN_BLOCKSIZE || +- (S_ISDIR(mode) && ocfs2_supports_inline_data(osb)) || + (s_size + a_size) > OCFS2_XATTR_FREE_IN_IBODY) { + ret = ocfs2_reserve_new_metadata_blocks(osb, 1, xattr_ac); + if (ret) { +@@ -1516,7 +1507,7 @@ + last += 1; + } + +- free = min_offs - ((void *)last - xs->base) - OCFS2_XATTR_HEADER_GAP; ++ free = min_offs - ((void *)last - xs->base) - sizeof(__u32); + if (free < 0) + return -EIO; + +@@ -2199,7 +2190,7 @@ + last += 1; + } + +- free = min_offs - ((void *)last - xs->base) - OCFS2_XATTR_HEADER_GAP; ++ free = min_offs - ((void *)last - xs->base) - sizeof(__u32); + if (free < 0) + return 0; + +@@ -2601,9 +2592,8 @@ + + if (!ret) { + /* Update inode ctime. */ +- ret = ocfs2_journal_access_di(ctxt->handle, inode, +- xis->inode_bh, +- OCFS2_JOURNAL_ACCESS_WRITE); ++ ret = ocfs2_journal_access(ctxt->handle, inode, xis->inode_bh, ++ OCFS2_JOURNAL_ACCESS_WRITE); + if (ret) { + mlog_errno(ret); + goto out; +@@ -4739,6 +4729,13 @@ + vb.vb_xv = (struct ocfs2_xattr_value_root *) + (vb.vb_bh->b_data + offset % blocksize); + ++ ret = ocfs2_xattr_bucket_journal_access(ctxt->handle, bucket, ++ OCFS2_JOURNAL_ACCESS_WRITE); ++ if (ret) { ++ mlog_errno(ret); ++ goto out; ++ } ++ + /* + * From here on out we have to dirty the bucket. The generic + * value calls only modify one of the bucket's bhs, but we need +@@ -4751,18 +4748,12 @@ + ret = ocfs2_xattr_value_truncate(inode, &vb, len, ctxt); + if (ret) { + mlog_errno(ret); +- goto out; +- } +- +- ret = ocfs2_xattr_bucket_journal_access(ctxt->handle, bucket, +- OCFS2_JOURNAL_ACCESS_WRITE); +- if (ret) { +- mlog_errno(ret); +- goto out; ++ goto out_dirty; + } + + xe->xe_value_size = cpu_to_le64(len); + ++out_dirty: + ocfs2_xattr_bucket_journal_dirty(ctxt->handle, bucket); + + out: +@@ -4795,33 +4786,19 @@ + char *val, + int value_len) + { +- int ret, offset, block_off; ++ int offset; + struct ocfs2_xattr_value_root *xv; + struct ocfs2_xattr_entry *xe = xs->here; +- struct ocfs2_xattr_header *xh = bucket_xh(xs->bucket); +- void *base; + + BUG_ON(!xs->base || !xe || ocfs2_xattr_is_local(xe)); + +- ret = ocfs2_xattr_bucket_get_name_value(inode, xh, +- xe - xh->xh_entries, +- &block_off, +- &offset); +- if (ret) { +- mlog_errno(ret); +- goto out; +- } ++ offset = le16_to_cpu(xe->xe_name_offset) + ++ OCFS2_XATTR_SIZE(xe->xe_name_len); + +- base = bucket_block(xs->bucket, block_off); +- xv = (struct ocfs2_xattr_value_root *)(base + offset + +- OCFS2_XATTR_SIZE(xe->xe_name_len)); ++ xv = (struct ocfs2_xattr_value_root *)(xs->base + offset); + +- ret = __ocfs2_xattr_set_value_outside(inode, handle, +- xv, val, value_len); +- if (ret) +- mlog_errno(ret); +-out: +- return ret; ++ return __ocfs2_xattr_set_value_outside(inode, handle, ++ xv, val, value_len); + } + + static int ocfs2_rm_xattr_cluster(struct inode *inode, +@@ -5084,8 +5061,8 @@ + xh_free_start = le16_to_cpu(xh->xh_free_start); + header_size = sizeof(struct ocfs2_xattr_header) + + count * sizeof(struct ocfs2_xattr_entry); +- max_free = OCFS2_XATTR_BUCKET_SIZE - header_size - +- le16_to_cpu(xh->xh_name_value_len) - OCFS2_XATTR_HEADER_GAP; ++ max_free = OCFS2_XATTR_BUCKET_SIZE - ++ le16_to_cpu(xh->xh_name_value_len) - header_size; + + mlog_bug_on_msg(header_size > blocksize, "bucket %llu has header size " + "of %u which exceed block size\n", +@@ -5118,7 +5095,7 @@ + need = 0; + } + +- free = xh_free_start - header_size - OCFS2_XATTR_HEADER_GAP; ++ free = xh_free_start - header_size; + /* + * We need to make sure the new name/value pair + * can exist in the same block. +@@ -5151,8 +5128,7 @@ + } + + xh_free_start = le16_to_cpu(xh->xh_free_start); +- free = xh_free_start - header_size +- - OCFS2_XATTR_HEADER_GAP; ++ free = xh_free_start - header_size; + if (xh_free_start % blocksize < need) + free -= xh_free_start % blocksize; + +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/fs/pipe.c linux-2.6.29-rc3.owrt/fs/pipe.c +--- linux-2.6.29.owrt/fs/pipe.c 2009-05-10 22:04:39.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/fs/pipe.c 2009-05-10 23:48:29.000000000 +0200 +@@ -699,12 +699,12 @@ + int retval; + + mutex_lock(&inode->i_mutex); ++ + retval = fasync_helper(fd, filp, on, &pipe->fasync_readers); +- if (retval >= 0) { ++ ++ if (retval >= 0) + retval = fasync_helper(fd, filp, on, &pipe->fasync_writers); +- if (retval < 0) /* this can happen only if on == T */ +- fasync_helper(-1, filp, 0, &pipe->fasync_readers); +- } ++ + mutex_unlock(&inode->i_mutex); + + if (retval < 0) +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/fs/proc/base.c linux-2.6.29-rc3.owrt/fs/proc/base.c +--- linux-2.6.29.owrt/fs/proc/base.c 2009-05-10 22:04:39.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/fs/proc/base.c 2009-05-10 23:48:29.000000000 +0200 +@@ -3066,6 +3066,7 @@ + int retval = -ENOENT; + ino_t ino; + int tid; ++ unsigned long pos = filp->f_pos; /* avoiding "long long" filp->f_pos */ + struct pid_namespace *ns; + + task = get_proc_task(inode); +@@ -3082,18 +3083,18 @@ + goto out_no_task; + retval = 0; + +- switch ((unsigned long)filp->f_pos) { ++ switch (pos) { + case 0: + ino = inode->i_ino; +- if (filldir(dirent, ".", 1, filp->f_pos, ino, DT_DIR) < 0) ++ if (filldir(dirent, ".", 1, pos, ino, DT_DIR) < 0) + goto out; +- filp->f_pos++; ++ pos++; + /* fall through */ + case 1: + ino = parent_ino(dentry); +- if (filldir(dirent, "..", 2, filp->f_pos, ino, DT_DIR) < 0) ++ if (filldir(dirent, "..", 2, pos, ino, DT_DIR) < 0) + goto out; +- filp->f_pos++; ++ pos++; + /* fall through */ + } + +@@ -3103,9 +3104,9 @@ + ns = filp->f_dentry->d_sb->s_fs_info; + tid = (int)filp->f_version; + filp->f_version = 0; +- for (task = first_tid(leader, tid, filp->f_pos - 2, ns); ++ for (task = first_tid(leader, tid, pos - 2, ns); + task; +- task = next_tid(task), filp->f_pos++) { ++ task = next_tid(task), pos++) { + tid = task_pid_nr_ns(task, ns); + if (proc_task_fill_cache(filp, dirent, filldir, task, tid) < 0) { + /* returning this tgid failed, save it as the first +@@ -3116,6 +3117,7 @@ + } + } + out: ++ filp->f_pos = pos; + put_task_struct(leader); + out_no_task: + return retval; +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/fs/proc/inode.c linux-2.6.29-rc3.owrt/fs/proc/inode.c +--- linux-2.6.29.owrt/fs/proc/inode.c 2009-05-10 22:04:39.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/fs/proc/inode.c 2009-05-10 23:48:29.000000000 +0200 +@@ -485,10 +485,8 @@ + } + } + unlock_new_inode(inode); +- } else { ++ } else + module_put(de->owner); +- de_put(de); +- } + return inode; + + out_ino: +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/fs/proc/page.c linux-2.6.29-rc3.owrt/fs/proc/page.c +--- linux-2.6.29.owrt/fs/proc/page.c 2009-05-10 22:04:39.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/fs/proc/page.c 2009-05-10 23:48:29.000000000 +0200 +@@ -80,7 +80,7 @@ + #define KPF_RECLAIM 9 + #define KPF_BUDDY 10 + +-#define kpf_copy_bit(flags, dstpos, srcpos) (((flags >> srcpos) & 1) << dstpos) ++#define kpf_copy_bit(flags, srcpos, dstpos) (((flags >> srcpos) & 1) << dstpos) + + static ssize_t kpageflags_read(struct file *file, char __user *buf, + size_t count, loff_t *ppos) +@@ -107,7 +107,7 @@ + else + kflags = ppage->flags; + +- uflags = kpf_copy_bit(kflags, KPF_LOCKED, PG_locked) | ++ uflags = kpf_copy_bit(KPF_LOCKED, PG_locked, kflags) | + kpf_copy_bit(kflags, KPF_ERROR, PG_error) | + kpf_copy_bit(kflags, KPF_REFERENCED, PG_referenced) | + kpf_copy_bit(kflags, KPF_UPTODATE, PG_uptodate) | +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/fs/ramfs/file-nommu.c linux-2.6.29-rc3.owrt/fs/ramfs/file-nommu.c +--- linux-2.6.29.owrt/fs/ramfs/file-nommu.c 2009-05-10 22:04:39.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/fs/ramfs/file-nommu.c 2009-05-10 23:48:29.000000000 +0200 +@@ -114,9 +114,6 @@ + if (!pagevec_add(&lru_pvec, page)) + __pagevec_lru_add_file(&lru_pvec); + +- /* prevent the page from being discarded on memory pressure */ +- SetPageDirty(page); +- + unlock_page(page); + } + +@@ -129,7 +126,6 @@ + return -EFBIG; + + add_error: +- pagevec_lru_add_file(&lru_pvec); + page_cache_release(pages + loop); + for (loop++; loop < npages; loop++) + __free_page(pages + loop); +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/fs/seq_file.c linux-2.6.29-rc3.owrt/fs/seq_file.c +--- linux-2.6.29.owrt/fs/seq_file.c 2009-05-10 22:04:39.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/fs/seq_file.c 2009-05-10 23:48:29.000000000 +0200 +@@ -48,78 +48,12 @@ + */ + file->f_version = 0; + +- /* +- * seq_files support lseek() and pread(). They do not implement +- * write() at all, but we clear FMODE_PWRITE here for historical +- * reasons. +- * +- * If a client of seq_files a) implements file.write() and b) wishes to +- * support pwrite() then that client will need to implement its own +- * file.open() which calls seq_open() and then sets FMODE_PWRITE. +- */ +- file->f_mode &= ~FMODE_PWRITE; ++ /* SEQ files support lseek, but not pread/pwrite */ ++ file->f_mode &= ~(FMODE_PREAD | FMODE_PWRITE); + return 0; + } + EXPORT_SYMBOL(seq_open); + +-static int traverse(struct seq_file *m, loff_t offset) +-{ +- loff_t pos = 0, index; +- int error = 0; +- void *p; +- +- m->version = 0; +- index = 0; +- m->count = m->from = 0; +- if (!offset) { +- m->index = index; +- return 0; +- } +- if (!m->buf) { +- m->buf = kmalloc(m->size = PAGE_SIZE, GFP_KERNEL); +- if (!m->buf) +- return -ENOMEM; +- } +- p = m->op->start(m, &index); +- while (p) { +- error = PTR_ERR(p); +- if (IS_ERR(p)) +- break; +- error = m->op->show(m, p); +- if (error < 0) +- break; +- if (unlikely(error)) { +- error = 0; +- m->count = 0; +- } +- if (m->count == m->size) +- goto Eoverflow; +- if (pos + m->count > offset) { +- m->from = offset - pos; +- m->count -= m->from; +- m->index = index; +- break; +- } +- pos += m->count; +- m->count = 0; +- if (pos == offset) { +- index++; +- m->index = index; +- break; +- } +- p = m->op->next(m, p, &index); +- } +- m->op->stop(m, p); +- m->index = index; +- return error; +- +-Eoverflow: +- m->op->stop(m, p); +- kfree(m->buf); +- m->buf = kmalloc(m->size <<= 1, GFP_KERNEL); +- return !m->buf ? -ENOMEM : -EAGAIN; +-} +- + /** + * seq_read - ->read() method for sequential files. + * @file: the file to read from +@@ -139,22 +73,6 @@ + int err = 0; + + mutex_lock(&m->lock); +- +- /* Don't assume *ppos is where we left it */ +- if (unlikely(*ppos != m->read_pos)) { +- m->read_pos = *ppos; +- while ((err = traverse(m, *ppos)) == -EAGAIN) +- ; +- if (err) { +- /* With prejudice... */ +- m->read_pos = 0; +- m->version = 0; +- m->index = 0; +- m->count = 0; +- goto Done; +- } +- } +- + /* + * seq_file->op->..m_start/m_stop/m_next may do special actions + * or optimisations based on the file->f_version, so we want to +@@ -254,10 +172,8 @@ + Done: + if (!copied) + copied = err; +- else { ++ else + *ppos += copied; +- m->read_pos += copied; +- } + file->f_version = m->version; + mutex_unlock(&m->lock); + return copied; +@@ -270,6 +186,63 @@ + } + EXPORT_SYMBOL(seq_read); + ++static int traverse(struct seq_file *m, loff_t offset) ++{ ++ loff_t pos = 0, index; ++ int error = 0; ++ void *p; ++ ++ m->version = 0; ++ index = 0; ++ m->count = m->from = 0; ++ if (!offset) { ++ m->index = index; ++ return 0; ++ } ++ if (!m->buf) { ++ m->buf = kmalloc(m->size = PAGE_SIZE, GFP_KERNEL); ++ if (!m->buf) ++ return -ENOMEM; ++ } ++ p = m->op->start(m, &index); ++ while (p) { ++ error = PTR_ERR(p); ++ if (IS_ERR(p)) ++ break; ++ error = m->op->show(m, p); ++ if (error < 0) ++ break; ++ if (unlikely(error)) { ++ error = 0; ++ m->count = 0; ++ } ++ if (m->count == m->size) ++ goto Eoverflow; ++ if (pos + m->count > offset) { ++ m->from = offset - pos; ++ m->count -= m->from; ++ m->index = index; ++ break; ++ } ++ pos += m->count; ++ m->count = 0; ++ if (pos == offset) { ++ index++; ++ m->index = index; ++ break; ++ } ++ p = m->op->next(m, p, &index); ++ } ++ m->op->stop(m, p); ++ return error; ++ ++Eoverflow: ++ m->op->stop(m, p); ++ kfree(m->buf); ++ m->buf = kmalloc(m->size <<= 1, GFP_KERNEL); ++ return !m->buf ? -ENOMEM : -EAGAIN; ++} ++ + /** + * seq_lseek - ->llseek() method for sequential files. + * @file: the file in question +@@ -292,18 +265,16 @@ + if (offset < 0) + break; + retval = offset; +- if (offset != m->read_pos) { ++ if (offset != file->f_pos) { + while ((retval=traverse(m, offset)) == -EAGAIN) + ; + if (retval) { + /* with extreme prejudice... */ + file->f_pos = 0; +- m->read_pos = 0; + m->version = 0; + m->index = 0; + m->count = 0; + } else { +- m->read_pos = offset; + retval = file->f_pos = offset; + } + } +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/fs/squashfs/block.c linux-2.6.29-rc3.owrt/fs/squashfs/block.c +--- linux-2.6.29.owrt/fs/squashfs/block.c 2009-05-10 22:04:39.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/fs/squashfs/block.c 2009-05-10 23:48:29.000000000 +0200 +@@ -80,7 +80,7 @@ + * generated a larger block - this does occasionally happen with zlib). + */ + int squashfs_read_data(struct super_block *sb, void **buffer, u64 index, +- int length, u64 *next_index, int srclength, int pages) ++ int length, u64 *next_index, int srclength) + { + struct squashfs_sb_info *msblk = sb->s_fs_info; + struct buffer_head **bh; +@@ -184,7 +184,7 @@ + offset = 0; + } + +- if (msblk->stream.avail_out == 0 && page < pages) { ++ if (msblk->stream.avail_out == 0) { + msblk->stream.next_out = buffer[page++]; + msblk->stream.avail_out = PAGE_CACHE_SIZE; + } +@@ -201,20 +201,25 @@ + zlib_init = 1; + } + +- zlib_err = zlib_inflate(&msblk->stream, Z_SYNC_FLUSH); ++ zlib_err = zlib_inflate(&msblk->stream, Z_NO_FLUSH); + + if (msblk->stream.avail_in == 0 && k < b) + put_bh(bh[k++]); + } while (zlib_err == Z_OK); + + if (zlib_err != Z_STREAM_END) { +- ERROR("zlib_inflate error, data probably corrupt\n"); ++ ERROR("zlib_inflate returned unexpected result" ++ " 0x%x, srclength %d, avail_in %d," ++ " avail_out %d\n", zlib_err, srclength, ++ msblk->stream.avail_in, ++ msblk->stream.avail_out); + goto release_mutex; + } + + zlib_err = zlib_inflateEnd(&msblk->stream); + if (zlib_err != Z_OK) { +- ERROR("zlib_inflate error, data probably corrupt\n"); ++ ERROR("zlib_inflateEnd returned unexpected result 0x%x," ++ " srclength %d\n", zlib_err, srclength); + goto release_mutex; + } + length = msblk->stream.total_out; +@@ -263,8 +268,7 @@ + put_bh(bh[k]); + + read_failure: +- ERROR("squashfs_read_data failed to read block 0x%llx\n", +- (unsigned long long) index); ++ ERROR("sb_bread failed reading block 0x%llx\n", cur_index); + kfree(bh); + return -EIO; + } +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/fs/squashfs/cache.c linux-2.6.29-rc3.owrt/fs/squashfs/cache.c +--- linux-2.6.29.owrt/fs/squashfs/cache.c 2009-05-10 22:04:39.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/fs/squashfs/cache.c 2009-05-10 23:48:29.000000000 +0200 +@@ -119,7 +119,7 @@ + + entry->length = squashfs_read_data(sb, entry->data, + block, length, &entry->next_index, +- cache->block_size, cache->pages); ++ cache->block_size); + + spin_lock(&cache->lock); + +@@ -406,7 +406,7 @@ + for (i = 0; i < pages; i++, buffer += PAGE_CACHE_SIZE) + data[i] = buffer; + res = squashfs_read_data(sb, data, block, length | +- SQUASHFS_COMPRESSED_BIT_BLOCK, NULL, length, pages); ++ SQUASHFS_COMPRESSED_BIT_BLOCK, NULL, length); + kfree(data); + return res; + } +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/fs/squashfs/inode.c linux-2.6.29-rc3.owrt/fs/squashfs/inode.c +--- linux-2.6.29.owrt/fs/squashfs/inode.c 2009-05-10 22:04:39.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/fs/squashfs/inode.c 2009-05-10 23:48:29.000000000 +0200 +@@ -133,8 +133,7 @@ + type = le16_to_cpu(sqshb_ino->inode_type); + switch (type) { + case SQUASHFS_REG_TYPE: { +- unsigned int frag_offset, frag; +- int frag_size; ++ unsigned int frag_offset, frag_size, frag; + u64 frag_blk; + struct squashfs_reg_inode *sqsh_ino = &squashfs_ino.reg; + +@@ -176,8 +175,7 @@ + break; + } + case SQUASHFS_LREG_TYPE: { +- unsigned int frag_offset, frag; +- int frag_size; ++ unsigned int frag_offset, frag_size, frag; + u64 frag_blk; + struct squashfs_lreg_inode *sqsh_ino = &squashfs_ino.lreg; + +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/fs/squashfs/squashfs.h linux-2.6.29-rc3.owrt/fs/squashfs/squashfs.h +--- linux-2.6.29.owrt/fs/squashfs/squashfs.h 2009-05-10 22:04:39.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/fs/squashfs/squashfs.h 2009-05-10 23:48:29.000000000 +0200 +@@ -34,7 +34,7 @@ + + /* block.c */ + extern int squashfs_read_data(struct super_block *, void **, u64, int, u64 *, +- int, int); ++ int); + + /* cache.c */ + extern struct squashfs_cache *squashfs_cache_init(char *, int, int); +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/fs/squashfs/super.c linux-2.6.29-rc3.owrt/fs/squashfs/super.c +--- linux-2.6.29.owrt/fs/squashfs/super.c 2009-05-10 22:04:39.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/fs/squashfs/super.c 2009-05-10 23:48:29.000000000 +0200 +@@ -389,7 +389,7 @@ + return err; + } + +- printk(KERN_INFO "squashfs: version 4.0 (2009/01/31) " ++ printk(KERN_INFO "squashfs: version 4.0 (2009/01/03) " + "Phillip Lougher\n"); + + return 0; +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/fs/super.c linux-2.6.29-rc3.owrt/fs/super.c +--- linux-2.6.29.owrt/fs/super.c 2009-05-10 22:04:39.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/fs/super.c 2009-05-10 23:48:29.000000000 +0200 +@@ -82,22 +82,7 @@ + * lock ordering than usbfs: + */ + lockdep_set_class(&s->s_lock, &type->s_lock_key); +- /* +- * sget() can have s_umount recursion. +- * +- * When it cannot find a suitable sb, it allocates a new +- * one (this one), and tries again to find a suitable old +- * one. +- * +- * In case that succeeds, it will acquire the s_umount +- * lock of the old one. Since these are clearly distrinct +- * locks, and this object isn't exposed yet, there's no +- * risk of deadlocks. +- * +- * Annotate this by putting this lock in a different +- * subclass. +- */ +- down_write_nested(&s->s_umount, SINGLE_DEPTH_NESTING); ++ down_write(&s->s_umount); + s->s_count = S_BIAS; + atomic_set(&s->s_active, 1); + mutex_init(&s->s_vfs_rename_mutex); +@@ -316,7 +301,7 @@ + /* + * wait for asynchronous fs operations to finish before going further + */ +- async_synchronize_full_domain(&sb->s_async_list); ++ async_synchronize_full_special(&sb->s_async_list); + + /* bad name - it should be evict_inodes() */ + invalidate_inodes(sb); +@@ -371,10 +356,8 @@ + continue; + if (!grab_super(old)) + goto retry; +- if (s) { +- up_write(&s->s_umount); ++ if (s) + destroy_super(s); +- } + return old; + } + } +@@ -389,7 +372,6 @@ + err = set(s, data); + if (err) { + spin_unlock(&sb_lock); +- up_write(&s->s_umount); + destroy_super(s); + return ERR_PTR(err); + } +@@ -488,7 +470,7 @@ + sb->s_count++; + spin_unlock(&sb_lock); + down_read(&sb->s_umount); +- async_synchronize_full_domain(&sb->s_async_list); ++ async_synchronize_full_special(&sb->s_async_list); + if (sb->s_root && (wait || sb->s_dirt)) + sb->s_op->sync_fs(sb, wait); + up_read(&sb->s_umount); +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/fs/timerfd.c linux-2.6.29-rc3.owrt/fs/timerfd.c +--- linux-2.6.29.owrt/fs/timerfd.c 2009-05-10 22:04:39.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/fs/timerfd.c 2009-05-10 23:48:29.000000000 +0200 +@@ -186,9 +186,10 @@ + BUILD_BUG_ON(TFD_CLOEXEC != O_CLOEXEC); + BUILD_BUG_ON(TFD_NONBLOCK != O_NONBLOCK); + +- if ((flags & ~TFD_CREATE_FLAGS) || +- (clockid != CLOCK_MONOTONIC && +- clockid != CLOCK_REALTIME)) ++ if (flags & ~(TFD_CLOEXEC | TFD_NONBLOCK)) ++ return -EINVAL; ++ if (clockid != CLOCK_MONOTONIC && ++ clockid != CLOCK_REALTIME) + return -EINVAL; + + ctx = kzalloc(sizeof(*ctx), GFP_KERNEL); +@@ -200,7 +201,7 @@ + hrtimer_init(&ctx->tmr, clockid, HRTIMER_MODE_ABS); + + ufd = anon_inode_getfd("[timerfd]", &timerfd_fops, ctx, +- flags & TFD_SHARED_FCNTL_FLAGS); ++ flags & (O_CLOEXEC | O_NONBLOCK)); + if (ufd < 0) + kfree(ctx); + +@@ -218,8 +219,7 @@ + if (copy_from_user(&ktmr, utmr, sizeof(ktmr))) + return -EFAULT; + +- if ((flags & ~TFD_SETTIME_FLAGS) || +- !timespec_valid(&ktmr.it_value) || ++ if (!timespec_valid(&ktmr.it_value) || + !timespec_valid(&ktmr.it_interval)) + return -EINVAL; + +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/fs/ubifs/budget.c linux-2.6.29-rc3.owrt/fs/ubifs/budget.c +--- linux-2.6.29.owrt/fs/ubifs/budget.c 2009-05-10 22:04:39.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/fs/ubifs/budget.c 2009-05-10 23:48:29.000000000 +0200 +@@ -689,7 +689,7 @@ + } + + /** +- * ubifs_get_free_space_nolock - return amount of free space. ++ * ubifs_get_free_space - return amount of free space. + * @c: UBIFS file-system description object + * + * This function calculates amount of free space to report to user-space. +@@ -704,14 +704,16 @@ + * traditional file-systems, because they have way less overhead than UBIFS. + * So, to keep users happy, UBIFS tries to take the overhead into account. + */ +-long long ubifs_get_free_space_nolock(struct ubifs_info *c) ++long long ubifs_get_free_space(struct ubifs_info *c) + { +- int rsvd_idx_lebs, lebs; ++ int min_idx_lebs, rsvd_idx_lebs, lebs; + long long available, outstanding, free; + +- ubifs_assert(c->min_idx_lebs == ubifs_calc_min_idx_lebs(c)); ++ spin_lock(&c->space_lock); ++ min_idx_lebs = c->min_idx_lebs; ++ ubifs_assert(min_idx_lebs == ubifs_calc_min_idx_lebs(c)); + outstanding = c->budg_data_growth + c->budg_dd_growth; +- available = ubifs_calc_available(c, c->min_idx_lebs); ++ available = ubifs_calc_available(c, min_idx_lebs); + + /* + * When reporting free space to user-space, UBIFS guarantees that it is +@@ -724,14 +726,15 @@ + * Note, the calculations below are similar to what we have in + * 'do_budget_space()', so refer there for comments. + */ +- if (c->min_idx_lebs > c->lst.idx_lebs) +- rsvd_idx_lebs = c->min_idx_lebs - c->lst.idx_lebs; ++ if (min_idx_lebs > c->lst.idx_lebs) ++ rsvd_idx_lebs = min_idx_lebs - c->lst.idx_lebs; + else + rsvd_idx_lebs = 0; + lebs = c->lst.empty_lebs + c->freeable_cnt + c->idx_gc_cnt - + c->lst.taken_empty_lebs; + lebs -= rsvd_idx_lebs; + available += lebs * (c->dark_wm - c->leb_overhead); ++ spin_unlock(&c->space_lock); + + if (available > outstanding) + free = ubifs_reported_space(c, available - outstanding); +@@ -739,21 +742,3 @@ + free = 0; + return free; + } +- +-/** +- * ubifs_get_free_space - return amount of free space. +- * @c: UBIFS file-system description object +- * +- * This function calculates and retuns amount of free space to report to +- * user-space. +- */ +-long long ubifs_get_free_space(struct ubifs_info *c) +-{ +- long long free; +- +- spin_lock(&c->space_lock); +- free = ubifs_get_free_space_nolock(c); +- spin_unlock(&c->space_lock); +- +- return free; +-} +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/fs/ubifs/debug.c linux-2.6.29-rc3.owrt/fs/ubifs/debug.c +--- linux-2.6.29.owrt/fs/ubifs/debug.c 2009-05-10 22:04:39.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/fs/ubifs/debug.c 2009-05-10 23:48:29.000000000 +0200 +@@ -620,11 +620,9 @@ + c->dark_wm, c->dead_wm, c->max_idx_node_sz); + printk(KERN_DEBUG "\tgc_lnum %d, ihead_lnum %d\n", + c->gc_lnum, c->ihead_lnum); +- /* If we are in R/O mode, journal heads do not exist */ +- if (c->jheads) +- for (i = 0; i < c->jhead_cnt; i++) +- printk(KERN_DEBUG "\tjhead %d\t LEB %d\n", +- c->jheads[i].wbuf.jhead, c->jheads[i].wbuf.lnum); ++ for (i = 0; i < c->jhead_cnt; i++) ++ printk(KERN_DEBUG "\tjhead %d\t LEB %d\n", ++ c->jheads[i].wbuf.jhead, c->jheads[i].wbuf.lnum); + for (rb = rb_first(&c->buds); rb; rb = rb_next(rb)) { + bud = rb_entry(rb, struct ubifs_bud, rb); + printk(KERN_DEBUG "\tbud LEB %d\n", bud->lnum); +@@ -639,7 +637,10 @@ + /* Print budgeting predictions */ + available = ubifs_calc_available(c, c->min_idx_lebs); + outstanding = c->budg_data_growth + c->budg_dd_growth; +- free = ubifs_get_free_space_nolock(c); ++ if (available > outstanding) ++ free = ubifs_reported_space(c, available - outstanding); ++ else ++ free = 0; + printk(KERN_DEBUG "Budgeting predictions:\n"); + printk(KERN_DEBUG "\tavailable: %lld, outstanding %lld, free %lld\n", + available, outstanding, free); +@@ -860,65 +861,6 @@ + } + + /** +- * dbg_save_space_info - save information about flash space. +- * @c: UBIFS file-system description object +- * +- * This function saves information about UBIFS free space, dirty space, etc, in +- * order to check it later. +- */ +-void dbg_save_space_info(struct ubifs_info *c) +-{ +- struct ubifs_debug_info *d = c->dbg; +- +- ubifs_get_lp_stats(c, &d->saved_lst); +- +- spin_lock(&c->space_lock); +- d->saved_free = ubifs_get_free_space_nolock(c); +- spin_unlock(&c->space_lock); +-} +- +-/** +- * dbg_check_space_info - check flash space information. +- * @c: UBIFS file-system description object +- * +- * This function compares current flash space information with the information +- * which was saved when the 'dbg_save_space_info()' function was called. +- * Returns zero if the information has not changed, and %-EINVAL it it has +- * changed. +- */ +-int dbg_check_space_info(struct ubifs_info *c) +-{ +- struct ubifs_debug_info *d = c->dbg; +- struct ubifs_lp_stats lst; +- long long avail, free; +- +- spin_lock(&c->space_lock); +- avail = ubifs_calc_available(c, c->min_idx_lebs); +- spin_unlock(&c->space_lock); +- free = ubifs_get_free_space(c); +- +- if (free != d->saved_free) { +- ubifs_err("free space changed from %lld to %lld", +- d->saved_free, free); +- goto out; +- } +- +- return 0; +- +-out: +- ubifs_msg("saved lprops statistics dump"); +- dbg_dump_lstats(&d->saved_lst); +- ubifs_get_lp_stats(c, &lst); +- ubifs_msg("current lprops statistics dump"); +- dbg_dump_lstats(&d->saved_lst); +- spin_lock(&c->space_lock); +- dbg_dump_budg(c); +- spin_unlock(&c->space_lock); +- dump_stack(); +- return -EINVAL; +-} +- +-/** + * dbg_check_synced_i_size - check synchronized inode size. + * @inode: inode to check + * +@@ -1407,7 +1349,7 @@ + * @c: UBIFS file-system description object + * @leaf_cb: called for each leaf node + * @znode_cb: called for each indexing node +- * @priv: private data which is passed to callbacks ++ * @priv: private date which is passed to callbacks + * + * This function walks the UBIFS index and calls the @leaf_cb for each leaf + * node and @znode_cb for each indexing node. Returns zero in case of success +@@ -2467,7 +2409,7 @@ + * Root directory for UBIFS stuff in debugfs. Contains sub-directories which + * contain the stuff specific to particular file-system mounts. + */ +-static struct dentry *dfs_rootdir; ++static struct dentry *debugfs_rootdir; + + /** + * dbg_debugfs_init - initialize debugfs file-system. +@@ -2479,9 +2421,9 @@ + */ + int dbg_debugfs_init(void) + { +- dfs_rootdir = debugfs_create_dir("ubifs", NULL); +- if (IS_ERR(dfs_rootdir)) { +- int err = PTR_ERR(dfs_rootdir); ++ debugfs_rootdir = debugfs_create_dir("ubifs", NULL); ++ if (IS_ERR(debugfs_rootdir)) { ++ int err = PTR_ERR(debugfs_rootdir); + ubifs_err("cannot create \"ubifs\" debugfs directory, " + "error %d\n", err); + return err; +@@ -2495,7 +2437,7 @@ + */ + void dbg_debugfs_exit(void) + { +- debugfs_remove(dfs_rootdir); ++ debugfs_remove(debugfs_rootdir); + } + + static int open_debugfs_file(struct inode *inode, struct file *file) +@@ -2510,13 +2452,13 @@ + struct ubifs_info *c = file->private_data; + struct ubifs_debug_info *d = c->dbg; + +- if (file->f_path.dentry == d->dfs_dump_lprops) ++ if (file->f_path.dentry == d->dump_lprops) + dbg_dump_lprops(c); +- else if (file->f_path.dentry == d->dfs_dump_budg) { ++ else if (file->f_path.dentry == d->dump_budg) { + spin_lock(&c->space_lock); + dbg_dump_budg(c); + spin_unlock(&c->space_lock); +- } else if (file->f_path.dentry == d->dfs_dump_tnc) { ++ } else if (file->f_path.dentry == d->dump_tnc) { + mutex_lock(&c->tnc_mutex); + dbg_dump_tnc(c); + mutex_unlock(&c->tnc_mutex); +@@ -2527,7 +2469,7 @@ + return count; + } + +-static const struct file_operations dfs_fops = { ++static const struct file_operations debugfs_fops = { + .open = open_debugfs_file, + .write = write_debugfs_file, + .owner = THIS_MODULE, +@@ -2552,32 +2494,36 @@ + struct dentry *dent; + struct ubifs_debug_info *d = c->dbg; + +- sprintf(d->dfs_dir_name, "ubi%d_%d", c->vi.ubi_num, c->vi.vol_id); +- d->dfs_dir = debugfs_create_dir(d->dfs_dir_name, dfs_rootdir); +- if (IS_ERR(d->dfs_dir)) { +- err = PTR_ERR(d->dfs_dir); ++ sprintf(d->debugfs_dir_name, "ubi%d_%d", c->vi.ubi_num, c->vi.vol_id); ++ d->debugfs_dir = debugfs_create_dir(d->debugfs_dir_name, ++ debugfs_rootdir); ++ if (IS_ERR(d->debugfs_dir)) { ++ err = PTR_ERR(d->debugfs_dir); + ubifs_err("cannot create \"%s\" debugfs directory, error %d\n", +- d->dfs_dir_name, err); ++ d->debugfs_dir_name, err); + goto out; + } + + fname = "dump_lprops"; +- dent = debugfs_create_file(fname, S_IWUGO, d->dfs_dir, c, &dfs_fops); ++ dent = debugfs_create_file(fname, S_IWUGO, d->debugfs_dir, c, ++ &debugfs_fops); + if (IS_ERR(dent)) + goto out_remove; +- d->dfs_dump_lprops = dent; ++ d->dump_lprops = dent; + + fname = "dump_budg"; +- dent = debugfs_create_file(fname, S_IWUGO, d->dfs_dir, c, &dfs_fops); ++ dent = debugfs_create_file(fname, S_IWUGO, d->debugfs_dir, c, ++ &debugfs_fops); + if (IS_ERR(dent)) + goto out_remove; +- d->dfs_dump_budg = dent; ++ d->dump_budg = dent; + + fname = "dump_tnc"; +- dent = debugfs_create_file(fname, S_IWUGO, d->dfs_dir, c, &dfs_fops); ++ dent = debugfs_create_file(fname, S_IWUGO, d->debugfs_dir, c, ++ &debugfs_fops); + if (IS_ERR(dent)) + goto out_remove; +- d->dfs_dump_tnc = dent; ++ d->dump_tnc = dent; + + return 0; + +@@ -2585,7 +2531,7 @@ + err = PTR_ERR(dent); + ubifs_err("cannot create \"%s\" debugfs directory, error %d\n", + fname, err); +- debugfs_remove_recursive(d->dfs_dir); ++ debugfs_remove_recursive(d->debugfs_dir); + out: + return err; + } +@@ -2596,7 +2542,7 @@ + */ + void dbg_debugfs_exit_fs(struct ubifs_info *c) + { +- debugfs_remove_recursive(c->dbg->dfs_dir); ++ debugfs_remove_recursive(c->dbg->debugfs_dir); + } + + #endif /* CONFIG_UBIFS_FS_DEBUG */ +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/fs/ubifs/debug.h linux-2.6.29-rc3.owrt/fs/ubifs/debug.h +--- linux-2.6.29.owrt/fs/ubifs/debug.h 2009-05-10 22:04:39.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/fs/ubifs/debug.h 2009-05-10 23:48:29.000000000 +0200 +@@ -41,17 +41,15 @@ + * @chk_lpt_wastage: used by LPT tree size checker + * @chk_lpt_lebs: used by LPT tree size checker + * @new_nhead_offs: used by LPT tree size checker +- * @new_ihead_lnum: used by debugging to check @c->ihead_lnum +- * @new_ihead_offs: used by debugging to check @c->ihead_offs ++ * @new_ihead_lnum: used by debugging to check ihead_lnum ++ * @new_ihead_offs: used by debugging to check ihead_offs + * +- * @saved_lst: saved lprops statistics (used by 'dbg_save_space_info()') +- * @saved_free: saved free space (used by 'dbg_save_space_info()') +- * +- * dfs_dir_name: name of debugfs directory containing this file-system's files +- * dfs_dir: direntry object of the file-system debugfs directory +- * dfs_dump_lprops: "dump lprops" debugfs knob +- * dfs_dump_budg: "dump budgeting information" debugfs knob +- * dfs_dump_tnc: "dump TNC" debugfs knob ++ * debugfs_dir_name: name of debugfs directory containing this file-system's ++ * files ++ * debugfs_dir: direntry object of the file-system debugfs directory ++ * dump_lprops: "dump lprops" debugfs knob ++ * dump_budg: "dump budgeting information" debugfs knob ++ * dump_tnc: "dump TNC" debugfs knob + */ + struct ubifs_debug_info { + void *buf; +@@ -71,14 +69,11 @@ + int new_ihead_lnum; + int new_ihead_offs; + +- struct ubifs_lp_stats saved_lst; +- long long saved_free; +- +- char dfs_dir_name[100]; +- struct dentry *dfs_dir; +- struct dentry *dfs_dump_lprops; +- struct dentry *dfs_dump_budg; +- struct dentry *dfs_dump_tnc; ++ char debugfs_dir_name[100]; ++ struct dentry *debugfs_dir; ++ struct dentry *dump_lprops; ++ struct dentry *dump_budg; ++ struct dentry *dump_tnc; + }; + + #define ubifs_assert(expr) do { \ +@@ -302,8 +297,7 @@ + dbg_znode_callback znode_cb, void *priv); + + /* Checking functions */ +-void dbg_save_space_info(struct ubifs_info *c); +-int dbg_check_space_info(struct ubifs_info *c); ++ + int dbg_check_lprops(struct ubifs_info *c); + int dbg_old_index_check_init(struct ubifs_info *c, struct ubifs_zbranch *zroot); + int dbg_check_old_index(struct ubifs_info *c, struct ubifs_zbranch *zroot); +@@ -445,8 +439,6 @@ + + #define dbg_walk_index(c, leaf_cb, znode_cb, priv) 0 + #define dbg_old_index_check_init(c, zroot) 0 +-#define dbg_save_space_info(c) ({}) +-#define dbg_check_space_info(c) 0 + #define dbg_check_old_index(c, zroot) 0 + #define dbg_check_cats(c) 0 + #define dbg_check_ltab(c) 0 +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/fs/ubifs/dir.c linux-2.6.29-rc3.owrt/fs/ubifs/dir.c +--- linux-2.6.29.owrt/fs/ubifs/dir.c 2009-05-10 22:04:39.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/fs/ubifs/dir.c 2009-05-10 23:48:29.000000000 +0200 +@@ -482,29 +482,30 @@ + } + + /** +- * lock_2_inodes - a wrapper for locking two UBIFS inodes. ++ * lock_2_inodes - lock two UBIFS inodes. + * @inode1: first inode + * @inode2: second inode +- * +- * We do not implement any tricks to guarantee strict lock ordering, because +- * VFS has already done it for us on the @i_mutex. So this is just a simple +- * wrapper function. + */ + static void lock_2_inodes(struct inode *inode1, struct inode *inode2) + { +- mutex_lock_nested(&ubifs_inode(inode1)->ui_mutex, WB_MUTEX_1); +- mutex_lock_nested(&ubifs_inode(inode2)->ui_mutex, WB_MUTEX_2); ++ if (inode1->i_ino < inode2->i_ino) { ++ mutex_lock_nested(&ubifs_inode(inode1)->ui_mutex, WB_MUTEX_2); ++ mutex_lock_nested(&ubifs_inode(inode2)->ui_mutex, WB_MUTEX_3); ++ } else { ++ mutex_lock_nested(&ubifs_inode(inode2)->ui_mutex, WB_MUTEX_2); ++ mutex_lock_nested(&ubifs_inode(inode1)->ui_mutex, WB_MUTEX_3); ++ } + } + + /** +- * unlock_2_inodes - a wrapper for unlocking two UBIFS inodes. ++ * unlock_2_inodes - unlock two UBIFS inodes inodes. + * @inode1: first inode + * @inode2: second inode + */ + static void unlock_2_inodes(struct inode *inode1, struct inode *inode2) + { +- mutex_unlock(&ubifs_inode(inode2)->ui_mutex); + mutex_unlock(&ubifs_inode(inode1)->ui_mutex); ++ mutex_unlock(&ubifs_inode(inode2)->ui_mutex); + } + + static int ubifs_link(struct dentry *old_dentry, struct inode *dir, +@@ -526,8 +527,6 @@ + dbg_gen("dent '%.*s' to ino %lu (nlink %d) in dir ino %lu", + dentry->d_name.len, dentry->d_name.name, inode->i_ino, + inode->i_nlink, dir->i_ino); +- ubifs_assert(mutex_is_locked(&dir->i_mutex)); +- ubifs_assert(mutex_is_locked(&inode->i_mutex)); + err = dbg_check_synced_i_size(inode); + if (err) + return err; +@@ -581,8 +580,6 @@ + dbg_gen("dent '%.*s' from ino %lu (nlink %d) in dir ino %lu", + dentry->d_name.len, dentry->d_name.name, inode->i_ino, + inode->i_nlink, dir->i_ino); +- ubifs_assert(mutex_is_locked(&dir->i_mutex)); +- ubifs_assert(mutex_is_locked(&inode->i_mutex)); + err = dbg_check_synced_i_size(inode); + if (err) + return err; +@@ -670,8 +667,7 @@ + + dbg_gen("directory '%.*s', ino %lu in dir ino %lu", dentry->d_name.len, + dentry->d_name.name, inode->i_ino, dir->i_ino); +- ubifs_assert(mutex_is_locked(&dir->i_mutex)); +- ubifs_assert(mutex_is_locked(&inode->i_mutex)); ++ + err = check_dir_empty(c, dentry->d_inode); + if (err) + return err; +@@ -926,30 +922,59 @@ + } + + /** +- * lock_3_inodes - a wrapper for locking three UBIFS inodes. ++ * lock_3_inodes - lock three UBIFS inodes for rename. + * @inode1: first inode + * @inode2: second inode + * @inode3: third inode + * +- * This function is used for 'ubifs_rename()' and @inode1 may be the same as +- * @inode2 whereas @inode3 may be %NULL. +- * +- * We do not implement any tricks to guarantee strict lock ordering, because +- * VFS has already done it for us on the @i_mutex. So this is just a simple +- * wrapper function. ++ * For 'ubifs_rename()', @inode1 may be the same as @inode2 whereas @inode3 may ++ * be null. + */ + static void lock_3_inodes(struct inode *inode1, struct inode *inode2, + struct inode *inode3) + { +- mutex_lock_nested(&ubifs_inode(inode1)->ui_mutex, WB_MUTEX_1); +- if (inode2 != inode1) +- mutex_lock_nested(&ubifs_inode(inode2)->ui_mutex, WB_MUTEX_2); +- if (inode3) +- mutex_lock_nested(&ubifs_inode(inode3)->ui_mutex, WB_MUTEX_3); ++ struct inode *i1, *i2, *i3; ++ ++ if (!inode3) { ++ if (inode1 != inode2) { ++ lock_2_inodes(inode1, inode2); ++ return; ++ } ++ mutex_lock_nested(&ubifs_inode(inode1)->ui_mutex, WB_MUTEX_1); ++ return; ++ } ++ ++ if (inode1 == inode2) { ++ lock_2_inodes(inode1, inode3); ++ return; ++ } ++ ++ /* 3 different inodes */ ++ if (inode1 < inode2) { ++ i3 = inode2; ++ if (inode1 < inode3) { ++ i1 = inode1; ++ i2 = inode3; ++ } else { ++ i1 = inode3; ++ i2 = inode1; ++ } ++ } else { ++ i3 = inode1; ++ if (inode2 < inode3) { ++ i1 = inode2; ++ i2 = inode3; ++ } else { ++ i1 = inode3; ++ i2 = inode2; ++ } ++ } ++ mutex_lock_nested(&ubifs_inode(i1)->ui_mutex, WB_MUTEX_1); ++ lock_2_inodes(i2, i3); + } + + /** +- * unlock_3_inodes - a wrapper for unlocking three UBIFS inodes for rename. ++ * unlock_3_inodes - unlock three UBIFS inodes for rename. + * @inode1: first inode + * @inode2: second inode + * @inode3: third inode +@@ -957,11 +982,11 @@ + static void unlock_3_inodes(struct inode *inode1, struct inode *inode2, + struct inode *inode3) + { +- if (inode3) +- mutex_unlock(&ubifs_inode(inode3)->ui_mutex); ++ mutex_unlock(&ubifs_inode(inode1)->ui_mutex); + if (inode1 != inode2) + mutex_unlock(&ubifs_inode(inode2)->ui_mutex); +- mutex_unlock(&ubifs_inode(inode1)->ui_mutex); ++ if (inode3) ++ mutex_unlock(&ubifs_inode(inode3)->ui_mutex); + } + + static int ubifs_rename(struct inode *old_dir, struct dentry *old_dentry, +@@ -995,11 +1020,6 @@ + "dir ino %lu", old_dentry->d_name.len, old_dentry->d_name.name, + old_inode->i_ino, old_dir->i_ino, new_dentry->d_name.len, + new_dentry->d_name.name, new_dir->i_ino); +- ubifs_assert(mutex_is_locked(&old_dir->i_mutex)); +- ubifs_assert(mutex_is_locked(&new_dir->i_mutex)); +- if (unlink) +- ubifs_assert(mutex_is_locked(&new_inode->i_mutex)); +- + + if (unlink && is_dir) { + err = check_dir_empty(c, new_inode); +@@ -1179,7 +1199,7 @@ + return 0; + } + +-const struct inode_operations ubifs_dir_inode_operations = { ++struct inode_operations ubifs_dir_inode_operations = { + .lookup = ubifs_lookup, + .create = ubifs_create, + .link = ubifs_link, +@@ -1199,7 +1219,7 @@ + #endif + }; + +-const struct file_operations ubifs_dir_operations = { ++struct file_operations ubifs_dir_operations = { + .llseek = ubifs_dir_llseek, + .release = ubifs_dir_release, + .read = generic_read_dir, +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/fs/ubifs/file.c linux-2.6.29-rc3.owrt/fs/ubifs/file.c +--- linux-2.6.29.owrt/fs/ubifs/file.c 2009-05-10 22:04:39.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/fs/ubifs/file.c 2009-05-10 23:48:29.000000000 +0200 +@@ -432,6 +432,7 @@ + int uninitialized_var(err), appending = !!(pos + len > inode->i_size); + struct page *page; + ++ + ubifs_assert(ubifs_inode(inode)->ui_size == inode->i_size); + + if (unlikely(c->ro_media)) +@@ -1540,7 +1541,7 @@ + return 0; + } + +-const struct address_space_operations ubifs_file_address_operations = { ++struct address_space_operations ubifs_file_address_operations = { + .readpage = ubifs_readpage, + .writepage = ubifs_writepage, + .write_begin = ubifs_write_begin, +@@ -1550,7 +1551,7 @@ + .releasepage = ubifs_releasepage, + }; + +-const struct inode_operations ubifs_file_inode_operations = { ++struct inode_operations ubifs_file_inode_operations = { + .setattr = ubifs_setattr, + .getattr = ubifs_getattr, + #ifdef CONFIG_UBIFS_FS_XATTR +@@ -1561,14 +1562,14 @@ + #endif + }; + +-const struct inode_operations ubifs_symlink_inode_operations = { ++struct inode_operations ubifs_symlink_inode_operations = { + .readlink = generic_readlink, + .follow_link = ubifs_follow_link, + .setattr = ubifs_setattr, + .getattr = ubifs_getattr, + }; + +-const struct file_operations ubifs_file_operations = { ++struct file_operations ubifs_file_operations = { + .llseek = generic_file_llseek, + .read = do_sync_read, + .write = do_sync_write, +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/fs/ubifs/gc.c linux-2.6.29-rc3.owrt/fs/ubifs/gc.c +--- linux-2.6.29.owrt/fs/ubifs/gc.c 2009-05-10 22:04:39.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/fs/ubifs/gc.c 2009-05-10 23:48:29.000000000 +0200 +@@ -31,26 +31,6 @@ + * to be reused. Garbage collection will cause the number of dirty index nodes + * to grow, however sufficient space is reserved for the index to ensure the + * commit will never run out of space. +- * +- * Notes about dead watermark. At current UBIFS implementation we assume that +- * LEBs which have less than @c->dead_wm bytes of free + dirty space are full +- * and not worth garbage-collecting. The dead watermark is one min. I/O unit +- * size, or min. UBIFS node size, depending on what is greater. Indeed, UBIFS +- * Garbage Collector has to synchronize the GC head's write buffer before +- * returning, so this is about wasting one min. I/O unit. However, UBIFS GC can +- * actually reclaim even very small pieces of dirty space by garbage collecting +- * enough dirty LEBs, but we do not bother doing this at this implementation. +- * +- * Notes about dark watermark. The results of GC work depends on how big are +- * the UBIFS nodes GC deals with. Large nodes make GC waste more space. Indeed, +- * if GC move data from LEB A to LEB B and nodes in LEB A are large, GC would +- * have to waste large pieces of free space at the end of LEB B, because nodes +- * from LEB A would not fit. And the worst situation is when all nodes are of +- * maximum size. So dark watermark is the amount of free + dirty space in LEB +- * which are guaranteed to be reclaimable. If LEB has less space, the GC migh +- * be unable to reclaim it. So, LEBs with free + dirty greater than dark +- * watermark are "good" LEBs from GC's point of few. The other LEBs are not so +- * good, and GC takes extra care when moving them. + */ + + #include <linux/pagemap.h> +@@ -401,7 +381,7 @@ + + /* + * Don't release the LEB until after the next commit, because +- * it may contain data which is needed for recovery. So ++ * it may contain date which is needed for recovery. So + * although we freed this LEB, it will become usable only after + * the commit. + */ +@@ -830,9 +810,8 @@ + * ubifs_destroy_idx_gc - destroy idx_gc list. + * @c: UBIFS file-system description object + * +- * This function destroys the @c->idx_gc list. It is called when unmounting +- * so locks are not needed. Returns zero in case of success and a negative +- * error code in case of failure. ++ * This function destroys the idx_gc list. It is called when unmounting or ++ * remounting read-only so locks are not needed. + */ + void ubifs_destroy_idx_gc(struct ubifs_info *c) + { +@@ -845,6 +824,7 @@ + list_del(&idx_gc->list); + kfree(idx_gc); + } ++ + } + + /** +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/fs/ubifs/io.c linux-2.6.29-rc3.owrt/fs/ubifs/io.c +--- linux-2.6.29.owrt/fs/ubifs/io.c 2009-05-10 22:04:39.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/fs/ubifs/io.c 2009-05-10 23:48:29.000000000 +0200 +@@ -29,7 +29,7 @@ + * would have been wasted for padding to the nearest minimal I/O unit boundary. + * Instead, data first goes to the write-buffer and is flushed when the + * buffer is full or when it is not used for some time (by timer). This is +- * similar to the mechanism is used by JFFS2. ++ * similarto the mechanism is used by JFFS2. + * + * Write-buffers are defined by 'struct ubifs_wbuf' objects and protected by + * mutexes defined inside these objects. Since sometimes upper-level code +@@ -75,7 +75,7 @@ + * @lnum: logical eraseblock number + * @offs: offset within the logical eraseblock + * @quiet: print no messages +- * @must_chk_crc: indicates whether to always check the CRC ++ * @chk_crc: indicates whether to always check the CRC + * + * This function checks node magic number and CRC checksum. This function also + * validates node length to prevent UBIFS from becoming crazy when an attacker +@@ -83,17 +83,11 @@ + * node length in the common header could cause UBIFS to read memory outside of + * allocated buffer when checking the CRC checksum. + * +- * This function may skip data nodes CRC checking if @c->no_chk_data_crc is +- * true, which is controlled by corresponding UBIFS mount option. However, if +- * @must_chk_crc is true, then @c->no_chk_data_crc is ignored and CRC is +- * checked. Similarly, if @c->always_chk_crc is true, @c->no_chk_data_crc is +- * ignored and CRC is checked. +- * +- * This function returns zero in case of success and %-EUCLEAN in case of bad +- * CRC or magic. ++ * This function returns zero in case of success %-EUCLEAN in case of bad CRC ++ * or magic. + */ + int ubifs_check_node(const struct ubifs_info *c, const void *buf, int lnum, +- int offs, int quiet, int must_chk_crc) ++ int offs, int quiet, int chk_crc) + { + int err = -EINVAL, type, node_len; + uint32_t crc, node_crc, magic; +@@ -129,9 +123,9 @@ + node_len > c->ranges[type].max_len) + goto out_len; + +- if (!must_chk_crc && type == UBIFS_DATA_NODE && !c->always_chk_crc && +- c->no_chk_data_crc) +- return 0; ++ if (!chk_crc && type == UBIFS_DATA_NODE && !c->always_chk_crc) ++ if (c->no_chk_data_crc) ++ return 0; + + crc = crc32(UBIFS_CRC32_INIT, buf + 8, node_len - 8); + node_crc = le32_to_cpu(ch->crc); +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/fs/ubifs/journal.c linux-2.6.29-rc3.owrt/fs/ubifs/journal.c +--- linux-2.6.29.owrt/fs/ubifs/journal.c 2009-05-10 22:04:39.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/fs/ubifs/journal.c 2009-05-10 23:48:29.000000000 +0200 +@@ -208,7 +208,7 @@ + offs = 0; + + out: +- err = ubifs_wbuf_seek_nolock(wbuf, lnum, offs, wbuf->dtype); ++ err = ubifs_wbuf_seek_nolock(wbuf, lnum, offs, UBI_SHORTTERM); + if (err) + goto out_unlock; + +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/fs/ubifs/lprops.c linux-2.6.29-rc3.owrt/fs/ubifs/lprops.c +--- linux-2.6.29.owrt/fs/ubifs/lprops.c 2009-05-10 22:04:39.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/fs/ubifs/lprops.c 2009-05-10 23:48:29.000000000 +0200 +@@ -635,10 +635,10 @@ + * @c: UBIFS file-system description object + * @st: return statistics + */ +-void ubifs_get_lp_stats(struct ubifs_info *c, struct ubifs_lp_stats *lst) ++void ubifs_get_lp_stats(struct ubifs_info *c, struct ubifs_lp_stats *st) + { + spin_lock(&c->space_lock); +- memcpy(lst, &c->lst, sizeof(struct ubifs_lp_stats)); ++ memcpy(st, &c->lst, sizeof(struct ubifs_lp_stats)); + spin_unlock(&c->space_lock); + } + +@@ -678,9 +678,6 @@ + + out: + ubifs_release_lprops(c); +- if (err) +- ubifs_err("cannot change properties of LEB %d, error %d", +- lnum, err); + return err; + } + +@@ -717,9 +714,6 @@ + + out: + ubifs_release_lprops(c); +- if (err) +- ubifs_err("cannot update properties of LEB %d, error %d", +- lnum, err); + return err; + } + +@@ -743,8 +737,6 @@ + lpp = ubifs_lpt_lookup(c, lnum); + if (IS_ERR(lpp)) { + err = PTR_ERR(lpp); +- ubifs_err("cannot read properties of LEB %d, error %d", +- lnum, err); + goto out; + } + +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/fs/ubifs/lpt_commit.c linux-2.6.29-rc3.owrt/fs/ubifs/lpt_commit.c +--- linux-2.6.29.owrt/fs/ubifs/lpt_commit.c 2009-05-10 22:04:39.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/fs/ubifs/lpt_commit.c 2009-05-10 23:48:29.000000000 +0200 +@@ -556,23 +556,23 @@ + } + + /** +- * next_pnode_to_dirty - find next pnode to dirty. ++ * next_pnode - find next pnode. + * @c: UBIFS file-system description object + * @pnode: pnode + * +- * This function returns the next pnode to dirty or %NULL if there are no more +- * pnodes. Note that pnodes that have never been written (lnum == 0) are +- * skipped. ++ * This function returns the next pnode or %NULL if there are no more pnodes. + */ +-static struct ubifs_pnode *next_pnode_to_dirty(struct ubifs_info *c, +- struct ubifs_pnode *pnode) ++static struct ubifs_pnode *next_pnode(struct ubifs_info *c, ++ struct ubifs_pnode *pnode) + { + struct ubifs_nnode *nnode; + int iip; + + /* Try to go right */ + nnode = pnode->parent; +- for (iip = pnode->iip + 1; iip < UBIFS_LPT_FANOUT; iip++) { ++ iip = pnode->iip + 1; ++ if (iip < UBIFS_LPT_FANOUT) { ++ /* We assume here that LEB zero is never an LPT LEB */ + if (nnode->nbranch[iip].lnum) + return ubifs_get_pnode(c, nnode, iip); + } +@@ -583,11 +583,8 @@ + nnode = nnode->parent; + if (!nnode) + return NULL; +- for (; iip < UBIFS_LPT_FANOUT; iip++) { +- if (nnode->nbranch[iip].lnum) +- break; +- } +- } while (iip >= UBIFS_LPT_FANOUT); ++ /* We assume here that LEB zero is never an LPT LEB */ ++ } while (iip >= UBIFS_LPT_FANOUT || !nnode->nbranch[iip].lnum); + + /* Go right */ + nnode = ubifs_get_nnode(c, nnode, iip); +@@ -596,29 +593,12 @@ + + /* Go down to level 1 */ + while (nnode->level > 1) { +- for (iip = 0; iip < UBIFS_LPT_FANOUT; iip++) { +- if (nnode->nbranch[iip].lnum) +- break; +- } +- if (iip >= UBIFS_LPT_FANOUT) { +- /* +- * Should not happen, but we need to keep going +- * if it does. +- */ +- iip = 0; +- } +- nnode = ubifs_get_nnode(c, nnode, iip); ++ nnode = ubifs_get_nnode(c, nnode, 0); + if (IS_ERR(nnode)) + return (void *)nnode; + } + +- for (iip = 0; iip < UBIFS_LPT_FANOUT; iip++) +- if (nnode->nbranch[iip].lnum) +- break; +- if (iip >= UBIFS_LPT_FANOUT) +- /* Should not happen, but we need to keep going if it does */ +- iip = 0; +- return ubifs_get_pnode(c, nnode, iip); ++ return ubifs_get_pnode(c, nnode, 0); + } + + /** +@@ -708,7 +688,7 @@ + pnode = pnode_lookup(c, 0); + while (pnode) { + do_make_pnode_dirty(c, pnode); +- pnode = next_pnode_to_dirty(c, pnode); ++ pnode = next_pnode(c, pnode); + if (IS_ERR(pnode)) + return PTR_ERR(pnode); + } +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/fs/ubifs/master.c linux-2.6.29-rc3.owrt/fs/ubifs/master.c +--- linux-2.6.29.owrt/fs/ubifs/master.c 2009-05-10 22:04:39.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/fs/ubifs/master.c 2009-05-10 23:48:29.000000000 +0200 +@@ -354,7 +354,7 @@ + int err, lnum, offs, len; + + if (c->ro_media) +- return -EROFS; ++ return -EINVAL; + + lnum = UBIFS_MST_LNUM; + offs = c->mst_offs + c->mst_node_alsz; +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/fs/ubifs/orphan.c linux-2.6.29-rc3.owrt/fs/ubifs/orphan.c +--- linux-2.6.29.owrt/fs/ubifs/orphan.c 2009-05-10 22:04:39.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/fs/ubifs/orphan.c 2009-05-10 23:48:29.000000000 +0200 +@@ -46,7 +46,7 @@ + * Orphans are accumulated in a rb-tree. When an inode's link count drops to + * zero, the inode number is added to the rb-tree. It is removed from the tree + * when the inode is deleted. Any new orphans that are in the orphan tree when +- * the commit is run, are written to the orphan area in 1 or more orphan nodes. ++ * the commit is run, are written to the orphan area in 1 or more orph nodes. + * If the orphan area is full, it is consolidated to make space. There is + * always enough space because validation prevents the user from creating more + * than the maximum number of orphans allowed. +@@ -231,7 +231,7 @@ + } + + /** +- * do_write_orph_node - write a node to the orphan head. ++ * do_write_orph_node - write a node + * @c: UBIFS file-system description object + * @len: length of node + * @atomic: write atomically +@@ -264,11 +264,11 @@ + } + + /** +- * write_orph_node - write an orphan node. ++ * write_orph_node - write an orph node + * @c: UBIFS file-system description object + * @atomic: write atomically + * +- * This function builds an orphan node from the cnext list and writes it to the ++ * This function builds an orph node from the cnext list and writes it to the + * orphan head. On success, %0 is returned, otherwise a negative error code + * is returned. + */ +@@ -326,11 +326,11 @@ + } + + /** +- * write_orph_nodes - write orphan nodes until there are no more to commit. ++ * write_orph_nodes - write orph nodes until there are no more to commit + * @c: UBIFS file-system description object + * @atomic: write atomically + * +- * This function writes orphan nodes for all the orphans to commit. On success, ++ * This function writes orph nodes for all the orphans to commit. On success, + * %0 is returned, otherwise a negative error code is returned. + */ + static int write_orph_nodes(struct ubifs_info *c, int atomic) +@@ -478,14 +478,14 @@ + } + + /** +- * ubifs_clear_orphans - erase all LEBs used for orphans. ++ * clear_orphans - erase all LEBs used for orphans. + * @c: UBIFS file-system description object + * + * If recovery is not required, then the orphans from the previous session + * are not needed. This function locates the LEBs used to record + * orphans, and un-maps them. + */ +-int ubifs_clear_orphans(struct ubifs_info *c) ++static int clear_orphans(struct ubifs_info *c) + { + int lnum, err; + +@@ -547,9 +547,9 @@ + * do_kill_orphans - remove orphan inodes from the index. + * @c: UBIFS file-system description object + * @sleb: scanned LEB +- * @last_cmt_no: cmt_no of last orphan node read is passed and returned here ++ * @last_cmt_no: cmt_no of last orph node read is passed and returned here + * @outofdate: whether the LEB is out of date is returned here +- * @last_flagged: whether the end orphan node is encountered ++ * @last_flagged: whether the end orph node is encountered + * + * This function is a helper to the 'kill_orphans()' function. It goes through + * every orphan node in a LEB and for every inode number recorded, removes +@@ -580,8 +580,8 @@ + /* + * The commit number on the master node may be less, because + * of a failed commit. If there are several failed commits in a +- * row, the commit number written on orphan nodes will continue +- * to increase (because the commit number is adjusted here) even ++ * row, the commit number written on orph nodes will continue to ++ * increase (because the commit number is adjusted here) even + * though the commit number on the master node stays the same + * because the master node has not been re-written. + */ +@@ -589,9 +589,9 @@ + c->cmt_no = cmt_no; + if (cmt_no < *last_cmt_no && *last_flagged) { + /* +- * The last orphan node had a higher commit number and +- * was flagged as the last written for that commit +- * number. That makes this orphan node, out of date. ++ * The last orph node had a higher commit number and was ++ * flagged as the last written for that commit number. ++ * That makes this orph node, out of date. + */ + if (!first) { + ubifs_err("out of order commit number %llu in " +@@ -658,10 +658,10 @@ + /* + * Orph nodes always start at c->orph_first and are written to each + * successive LEB in turn. Generally unused LEBs will have been unmapped +- * but may contain out of date orphan nodes if the unmap didn't go +- * through. In addition, the last orphan node written for each commit is ++ * but may contain out of date orph nodes if the unmap didn't go ++ * through. In addition, the last orph node written for each commit is + * marked (top bit of orph->cmt_no is set to 1). It is possible that +- * there are orphan nodes from the next commit (i.e. the commit did not ++ * there are orph nodes from the next commit (i.e. the commit did not + * complete successfully). In that case, no orphans will have been lost + * due to the way that orphans are written, and any orphans added will + * be valid orphans anyway and so can be deleted. +@@ -718,7 +718,7 @@ + if (unclean) + err = kill_orphans(c); + else if (!read_only) +- err = ubifs_clear_orphans(c); ++ err = clear_orphans(c); + + return err; + } +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/fs/ubifs/super.c linux-2.6.29-rc3.owrt/fs/ubifs/super.c +--- linux-2.6.29.owrt/fs/ubifs/super.c 2009-05-10 22:04:39.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/fs/ubifs/super.c 2009-05-10 23:48:29.000000000 +0200 +@@ -397,7 +397,6 @@ + buf->f_namelen = UBIFS_MAX_NLEN; + buf->f_fsid.val[0] = le32_to_cpu(uuid[0]) ^ le32_to_cpu(uuid[2]); + buf->f_fsid.val[1] = le32_to_cpu(uuid[1]) ^ le32_to_cpu(uuid[3]); +- ubifs_assert(buf->f_bfree <= c->block_cnt); + return 0; + } + +@@ -433,24 +432,33 @@ + int i, err; + struct ubifs_info *c = sb->s_fs_info; + struct writeback_control wbc = { +- .sync_mode = WB_SYNC_ALL, ++ .sync_mode = wait ? WB_SYNC_ALL : WB_SYNC_NONE, + .range_start = 0, + .range_end = LLONG_MAX, + .nr_to_write = LONG_MAX, + }; + + /* +- * Zero @wait is just an advisory thing to help the file system shove +- * lots of data into the queues, and there will be the second ++ * Note by akpm about WB_SYNC_NONE used above: zero @wait is just an ++ * advisory thing to help the file system shove lots of data into the ++ * queues. If some gets missed then it'll be picked up on the second + * '->sync_fs()' call, with non-zero @wait. + */ +- if (!wait) +- return 0; + + if (sb->s_flags & MS_RDONLY) + return 0; + + /* ++ * Synchronize write buffers, because 'ubifs_run_commit()' does not ++ * do this if it waits for an already running commit. ++ */ ++ for (i = 0; i < c->jhead_cnt; i++) { ++ err = ubifs_wbuf_sync(&c->jheads[i].wbuf); ++ if (err) ++ return err; ++ } ++ ++ /* + * VFS calls '->sync_fs()' before synchronizing all dirty inodes and + * pages, so synchronize them first, then commit the journal. Strictly + * speaking, it is not necessary to commit the journal here, +@@ -461,16 +469,6 @@ + */ + generic_sync_sb_inodes(sb, &wbc); + +- /* +- * Synchronize write buffers, because 'ubifs_run_commit()' does not +- * do this if it waits for an already running commit. +- */ +- for (i = 0; i < c->jhead_cnt; i++) { +- err = ubifs_wbuf_sync(&c->jheads[i].wbuf); +- if (err) +- return err; +- } +- + err = ubifs_run_commit(c); + if (err) + return err; +@@ -574,8 +572,15 @@ + c->ranges[UBIFS_IDX_NODE].max_len = INT_MAX; + + /* +- * Initialize dead and dark LEB space watermarks. See gc.c for comments +- * about these values. ++ * Initialize dead and dark LEB space watermarks. ++ * ++ * Dead space is the space which cannot be used. Its watermark is ++ * equivalent to min. I/O unit or minimum node size if it is greater ++ * then min. I/O unit. ++ * ++ * Dark space is the space which might be used, or might not, depending ++ * on which node should be written to the LEB. Its watermark is ++ * equivalent to maximum UBIFS node size. + */ + c->dead_wm = ALIGN(MIN_WRITE_SZ, c->min_io_size); + c->dark_wm = ALIGN(UBIFS_MAX_NODE_SZ, c->min_io_size); +@@ -736,12 +741,12 @@ + * take_gc_lnum - reserve GC LEB. + * @c: UBIFS file-system description object + * +- * This function ensures that the LEB reserved for garbage collection is marked +- * as "taken" in lprops. We also have to set free space to LEB size and dirty +- * space to zero, because lprops may contain out-of-date information if the +- * file-system was un-mounted before it has been committed. This function +- * returns zero in case of success and a negative error code in case of +- * failure. ++ * This function ensures that the LEB reserved for garbage collection is ++ * unmapped and is marked as "taken" in lprops. We also have to set free space ++ * to LEB size and dirty space to zero, because lprops may contain out-of-date ++ * information if the file-system was un-mounted before it has been committed. ++ * This function returns zero in case of success and a negative error code in ++ * case of failure. + */ + static int take_gc_lnum(struct ubifs_info *c) + { +@@ -752,6 +757,10 @@ + return -EINVAL; + } + ++ err = ubifs_leb_unmap(c, c->gc_lnum); ++ if (err) ++ return err; ++ + /* And we have to tell lprops that this LEB is taken */ + err = ubifs_change_one_lp(c, c->gc_lnum, c->leb_size, 0, + LPROPS_TAKEN, 0, 0); +@@ -957,16 +966,13 @@ + + token = match_token(p, tokens, args); + switch (token) { +- /* +- * %Opt_fast_unmount and %Opt_norm_unmount options are ignored. +- * We accepte them in order to be backware-compatible. But this +- * should be removed at some point. +- */ + case Opt_fast_unmount: + c->mount_opts.unmount_mode = 2; ++ c->fast_unmount = 1; + break; + case Opt_norm_unmount: + c->mount_opts.unmount_mode = 1; ++ c->fast_unmount = 0; + break; + case Opt_bulk_read: + c->mount_opts.bulk_read = 2; +@@ -1088,7 +1094,12 @@ + ubifs_err("insufficient free space to mount in read/write mode"); + dbg_dump_budg(c); + dbg_dump_lprops(c); +- return -ENOSPC; ++ /* ++ * We return %-EINVAL instead of %-ENOSPC because it seems to ++ * be the closest error code mentioned in the mount function ++ * documentation. ++ */ ++ return -EINVAL; + } + return 0; + } +@@ -1275,19 +1286,10 @@ + if (err) + goto out_orphans; + err = ubifs_rcvry_gc_commit(c); +- } else { ++ } else + err = take_gc_lnum(c); +- if (err) +- goto out_orphans; +- +- /* +- * GC LEB may contain garbage if there was an unclean +- * reboot, and it should be un-mapped. +- */ +- err = ubifs_leb_unmap(c, c->gc_lnum); +- if (err) +- return err; +- } ++ if (err) ++ goto out_orphans; + + err = dbg_check_lprops(c); + if (err) +@@ -1296,16 +1298,6 @@ + err = ubifs_recover_size(c); + if (err) + goto out_orphans; +- } else { +- /* +- * Even if we mount read-only, we have to set space in GC LEB +- * to proper value because this affects UBIFS free space +- * reporting. We do not want to have a situation when +- * re-mounting from R/O to R/W changes amount of free space. +- */ +- err = take_gc_lnum(c); +- if (err) +- goto out_orphans; + } + + spin_lock(&ubifs_infos_lock); +@@ -1318,17 +1310,14 @@ + else { + c->need_recovery = 0; + ubifs_msg("recovery completed"); +- /* GC LEB has to be empty and taken at this point */ +- ubifs_assert(c->lst.taken_empty_lebs == 1); + } +- } else +- ubifs_assert(c->lst.taken_empty_lebs == 1); ++ } + +- err = dbg_check_filesystem(c); ++ err = dbg_debugfs_init_fs(c); + if (err) + goto out_infos; + +- err = dbg_debugfs_init_fs(c); ++ err = dbg_check_filesystem(c); + if (err) + goto out_infos; + +@@ -1362,6 +1351,7 @@ + c->uuid[4], c->uuid[5], c->uuid[6], c->uuid[7], + c->uuid[8], c->uuid[9], c->uuid[10], c->uuid[11], + c->uuid[12], c->uuid[13], c->uuid[14], c->uuid[15]); ++ dbg_msg("fast unmount: %d", c->fast_unmount); + dbg_msg("big_lpt %d", c->big_lpt); + dbg_msg("log LEBs: %d (%d - %d)", + c->log_lebs, UBIFS_LOG_LNUM, c->log_last); +@@ -1485,8 +1475,10 @@ + { + int err, lnum; + ++ if (c->ro_media) ++ return -EINVAL; ++ + mutex_lock(&c->umount_mutex); +- dbg_save_space_info(c); + c->remounting_rw = 1; + c->always_chk_crc = 1; + +@@ -1522,12 +1514,6 @@ + err = ubifs_recover_inl_heads(c, c->sbuf); + if (err) + goto out; +- } else { +- /* A readonly mount is not allowed to have orphans */ +- ubifs_assert(c->tot_orphans == 0); +- err = ubifs_clear_orphans(c); +- if (err) +- goto out; + } + + if (!(c->mst_node->flags & cpu_to_le32(UBIFS_MST_DIRTY))) { +@@ -1583,7 +1569,7 @@ + if (c->need_recovery) + err = ubifs_rcvry_gc_commit(c); + else +- err = ubifs_leb_unmap(c, c->gc_lnum); ++ err = take_gc_lnum(c); + if (err) + goto out; + +@@ -1596,9 +1582,8 @@ + c->vfs_sb->s_flags &= ~MS_RDONLY; + c->remounting_rw = 0; + c->always_chk_crc = 0; +- err = dbg_check_space_info(c); + mutex_unlock(&c->umount_mutex); +- return err; ++ return 0; + + out: + vfree(c->orph_buf); +@@ -1618,18 +1603,43 @@ + } + + /** ++ * commit_on_unmount - commit the journal when un-mounting. ++ * @c: UBIFS file-system description object ++ * ++ * This function is called during un-mounting and re-mounting, and it commits ++ * the journal unless the "fast unmount" mode is enabled. ++ */ ++static void commit_on_unmount(struct ubifs_info *c) ++{ ++ struct super_block *sb = c->vfs_sb; ++ long long bud_bytes; ++ ++ /* ++ * This function is called before the background thread is stopped, so ++ * we may race with ongoing commit, which means we have to take ++ * @c->bud_lock to access @c->bud_bytes. ++ */ ++ spin_lock(&c->buds_lock); ++ bud_bytes = c->bud_bytes; ++ spin_unlock(&c->buds_lock); ++ ++ if (!c->fast_unmount && !(sb->s_flags & MS_RDONLY) && bud_bytes) ++ ubifs_run_commit(c); ++} ++ ++/** + * ubifs_remount_ro - re-mount in read-only mode. + * @c: UBIFS file-system description object + * +- * We assume VFS has stopped writing. Possibly the background thread could be +- * running a commit, however kthread_stop will wait in that case. ++ * We rely on VFS to have stopped writing. Possibly the background thread could ++ * be running a commit, however kthread_stop will wait in that case. + */ + static void ubifs_remount_ro(struct ubifs_info *c) + { + int i, err; + + ubifs_assert(!c->need_recovery); +- ubifs_assert(!(c->vfs_sb->s_flags & MS_RDONLY)); ++ commit_on_unmount(c); + + mutex_lock(&c->umount_mutex); + if (c->bgt) { +@@ -1637,29 +1647,27 @@ + c->bgt = NULL; + } + +- dbg_save_space_info(c); +- + for (i = 0; i < c->jhead_cnt; i++) { + ubifs_wbuf_sync(&c->jheads[i].wbuf); + del_timer_sync(&c->jheads[i].wbuf.timer); + } + +- c->mst_node->flags &= ~cpu_to_le32(UBIFS_MST_DIRTY); +- c->mst_node->flags |= cpu_to_le32(UBIFS_MST_NO_ORPHS); +- c->mst_node->gc_lnum = cpu_to_le32(c->gc_lnum); +- err = ubifs_write_master(c); +- if (err) +- ubifs_ro_mode(c, err); ++ if (!c->ro_media) { ++ c->mst_node->flags &= ~cpu_to_le32(UBIFS_MST_DIRTY); ++ c->mst_node->flags |= cpu_to_le32(UBIFS_MST_NO_ORPHS); ++ c->mst_node->gc_lnum = cpu_to_le32(c->gc_lnum); ++ err = ubifs_write_master(c); ++ if (err) ++ ubifs_ro_mode(c, err); ++ } + ++ ubifs_destroy_idx_gc(c); + free_wbufs(c); + vfree(c->orph_buf); + c->orph_buf = NULL; + vfree(c->ileb_buf); + c->ileb_buf = NULL; + ubifs_lpt_free(c, 1); +- err = dbg_check_space_info(c); +- if (err) +- ubifs_ro_mode(c, err); + mutex_unlock(&c->umount_mutex); + } + +@@ -1752,20 +1760,11 @@ + } + + if ((sb->s_flags & MS_RDONLY) && !(*flags & MS_RDONLY)) { +- if (c->ro_media) { +- ubifs_msg("cannot re-mount due to prior errors"); +- return -EROFS; +- } + err = ubifs_remount_rw(c); + if (err) + return err; +- } else if (!(sb->s_flags & MS_RDONLY) && (*flags & MS_RDONLY)) { +- if (c->ro_media) { +- ubifs_msg("cannot re-mount due to prior errors"); +- return -EROFS; +- } ++ } else if (!(sb->s_flags & MS_RDONLY) && (*flags & MS_RDONLY)) + ubifs_remount_ro(c); +- } + + if (c->bulk_read == 1) + bu_init(c); +@@ -1775,11 +1774,10 @@ + c->bu.buf = NULL; + } + +- ubifs_assert(c->lst.taken_empty_lebs == 1); + return 0; + } + +-const struct super_operations ubifs_super_operations = { ++struct super_operations ubifs_super_operations = { + .alloc_inode = ubifs_alloc_inode, + .destroy_inode = ubifs_destroy_inode, + .put_super = ubifs_put_super, +@@ -2046,6 +2044,15 @@ + + static void ubifs_kill_sb(struct super_block *sb) + { ++ struct ubifs_info *c = sb->s_fs_info; ++ ++ /* ++ * We do 'commit_on_unmount()' here instead of 'ubifs_put_super()' ++ * in order to be outside BKL. ++ */ ++ if (sb->s_root) ++ commit_on_unmount(c); ++ /* The un-mount routine is actually done in put_super() */ + generic_shutdown_super(sb); + } + +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/fs/ubifs/tnc.c linux-2.6.29-rc3.owrt/fs/ubifs/tnc.c +--- linux-2.6.29.owrt/fs/ubifs/tnc.c 2009-05-10 22:04:39.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/fs/ubifs/tnc.c 2009-05-10 23:48:29.000000000 +0200 +@@ -443,11 +443,6 @@ + * This function performs that same function as ubifs_read_node except that + * it does not require that there is actually a node present and instead + * the return code indicates if a node was read. +- * +- * Note, this function does not check CRC of data nodes if @c->no_chk_data_crc +- * is true (it is controlled by corresponding mount option). However, if +- * @c->always_chk_crc is true, @c->no_chk_data_crc is ignored and CRC is always +- * checked. + */ + static int try_read_node(const struct ubifs_info *c, void *buf, int type, + int len, int lnum, int offs) +@@ -475,8 +470,9 @@ + if (node_len != len) + return 0; + +- if (type == UBIFS_DATA_NODE && !c->always_chk_crc && c->no_chk_data_crc) +- return 1; ++ if (type == UBIFS_DATA_NODE && !c->always_chk_crc) ++ if (c->no_chk_data_crc) ++ return 0; + + crc = crc32(UBIFS_CRC32_INIT, buf + 8, node_len - 8); + node_crc = le32_to_cpu(ch->crc); +@@ -1510,7 +1506,7 @@ + * + * Note, if the bulk-read buffer length (@bu->buf_len) is known, this function + * makes sure bulk-read nodes fit the buffer. Otherwise, this function prepares +- * maximum possible amount of nodes for bulk-read. ++ * maxumum possible amount of nodes for bulk-read. + */ + int ubifs_tnc_get_bu_keys(struct ubifs_info *c, struct bu_info *bu) + { +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/fs/ubifs/ubifs.h linux-2.6.29-rc3.owrt/fs/ubifs/ubifs.h +--- linux-2.6.29.owrt/fs/ubifs/ubifs.h 2009-05-10 22:04:39.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/fs/ubifs/ubifs.h 2009-05-10 23:48:29.000000000 +0200 +@@ -426,9 +426,9 @@ + * LEB properties flags. + * + * LPROPS_UNCAT: not categorized +- * LPROPS_DIRTY: dirty > free, dirty >= @c->dead_wm, not index ++ * LPROPS_DIRTY: dirty > 0, not index + * LPROPS_DIRTY_IDX: dirty + free > @c->min_idx_node_sze and index +- * LPROPS_FREE: free > 0, dirty < @c->dead_wm, not empty, not index ++ * LPROPS_FREE: free > 0, not empty, not index + * LPROPS_HEAP_CNT: number of heaps used for storing categorized LEBs + * LPROPS_EMPTY: LEB is empty, not taken + * LPROPS_FREEABLE: free + dirty == leb_size, not index, not taken +@@ -961,6 +961,7 @@ + * @cs_lock: commit state lock + * @cmt_wq: wait queue to sleep on if the log is full and a commit is running + * ++ * @fast_unmount: do not run journal commit before un-mounting + * @big_lpt: flag that LPT is too big to write whole during commit + * @no_chk_data_crc: do not check CRCs when reading data nodes (except during + * recovery) +@@ -1201,6 +1202,7 @@ + spinlock_t cs_lock; + wait_queue_head_t cmt_wq; + ++ unsigned int fast_unmount:1; + unsigned int big_lpt:1; + unsigned int no_chk_data_crc:1; + unsigned int bulk_read:1; +@@ -1403,13 +1405,13 @@ + extern spinlock_t ubifs_infos_lock; + extern atomic_long_t ubifs_clean_zn_cnt; + extern struct kmem_cache *ubifs_inode_slab; +-extern const struct super_operations ubifs_super_operations; +-extern const struct address_space_operations ubifs_file_address_operations; +-extern const struct file_operations ubifs_file_operations; +-extern const struct inode_operations ubifs_file_inode_operations; +-extern const struct file_operations ubifs_dir_operations; +-extern const struct inode_operations ubifs_dir_inode_operations; +-extern const struct inode_operations ubifs_symlink_inode_operations; ++extern struct super_operations ubifs_super_operations; ++extern struct address_space_operations ubifs_file_address_operations; ++extern struct file_operations ubifs_file_operations; ++extern struct inode_operations ubifs_file_inode_operations; ++extern struct file_operations ubifs_dir_operations; ++extern struct inode_operations ubifs_dir_inode_operations; ++extern struct inode_operations ubifs_symlink_inode_operations; + extern struct backing_dev_info ubifs_backing_dev_info; + extern struct ubifs_compressor *ubifs_compressors[UBIFS_COMPR_TYPES_CNT]; + +@@ -1426,7 +1428,7 @@ + int ubifs_write_node(struct ubifs_info *c, void *node, int len, int lnum, + int offs, int dtype); + int ubifs_check_node(const struct ubifs_info *c, const void *buf, int lnum, +- int offs, int quiet, int must_chk_crc); ++ int offs, int quiet, int chk_crc); + void ubifs_prepare_node(struct ubifs_info *c, void *buf, int len, int pad); + void ubifs_prep_grp_node(struct ubifs_info *c, void *node, int len, int last); + int ubifs_io_init(struct ubifs_info *c); +@@ -1493,7 +1495,6 @@ + void ubifs_cancel_ino_op(struct ubifs_info *c, struct inode *inode, + struct ubifs_budget_req *req); + long long ubifs_get_free_space(struct ubifs_info *c); +-long long ubifs_get_free_space_nolock(struct ubifs_info *c); + int ubifs_calc_min_idx_lebs(struct ubifs_info *c); + void ubifs_convert_page_budget(struct ubifs_info *c); + long long ubifs_reported_space(const struct ubifs_info *c, long long free); +@@ -1602,7 +1603,6 @@ + int ubifs_orphan_start_commit(struct ubifs_info *c); + int ubifs_orphan_end_commit(struct ubifs_info *c); + int ubifs_mount_orphans(struct ubifs_info *c, int unclean, int read_only); +-int ubifs_clear_orphans(struct ubifs_info *c); + + /* lpt.c */ + int ubifs_calc_lpt_geom(struct ubifs_info *c); +@@ -1646,7 +1646,7 @@ + const struct ubifs_lprops *lp, + int free, int dirty, int flags, + int idx_gc_cnt); +-void ubifs_get_lp_stats(struct ubifs_info *c, struct ubifs_lp_stats *lst); ++void ubifs_get_lp_stats(struct ubifs_info *c, struct ubifs_lp_stats *stats); + void ubifs_add_to_cat(struct ubifs_info *c, struct ubifs_lprops *lprops, + int cat); + void ubifs_replace_cat(struct ubifs_info *c, struct ubifs_lprops *old_lprops, +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/fs/ufs/super.c linux-2.6.29-rc3.owrt/fs/ufs/super.c +--- linux-2.6.29.owrt/fs/ufs/super.c 2009-05-10 22:04:39.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/fs/ufs/super.c 2009-05-10 23:48:29.000000000 +0200 +@@ -41,7 +41,7 @@ + * Stefan Reinauer <stepan@home.culture.mipt.ru> + * + * Module usage counts added on 96/04/29 by +- * Gertjan van Wingerde <gwingerde@gmail.com> ++ * Gertjan van Wingerde <gertjan@cs.vu.nl> + * + * Clean swab support on 19970406 by + * Francois-Rene Rideau <fare@tunes.org> +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/fs/xfs/linux-2.6/xfs_buf.c linux-2.6.29-rc3.owrt/fs/xfs/linux-2.6/xfs_buf.c +--- linux-2.6.29.owrt/fs/xfs/linux-2.6/xfs_buf.c 2009-05-10 22:04:39.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/fs/xfs/linux-2.6/xfs_buf.c 2009-05-10 23:48:29.000000000 +0200 +@@ -34,12 +34,6 @@ + #include <linux/backing-dev.h> + #include <linux/freezer.h> + +-#include "xfs_sb.h" +-#include "xfs_inum.h" +-#include "xfs_ag.h" +-#include "xfs_dmapi.h" +-#include "xfs_mount.h" +- + static kmem_zone_t *xfs_buf_zone; + STATIC int xfsbufd(void *); + STATIC int xfsbufd_wakeup(int, gfp_t); +@@ -172,75 +166,6 @@ + } + + /* +- * Mapping of multi-page buffers into contiguous virtual space +- */ +- +-typedef struct a_list { +- void *vm_addr; +- struct a_list *next; +-} a_list_t; +- +-static a_list_t *as_free_head; +-static int as_list_len; +-static DEFINE_SPINLOCK(as_lock); +- +-/* +- * Try to batch vunmaps because they are costly. +- */ +-STATIC void +-free_address( +- void *addr) +-{ +- a_list_t *aentry; +- +-#ifdef CONFIG_XEN +- /* +- * Xen needs to be able to make sure it can get an exclusive +- * RO mapping of pages it wants to turn into a pagetable. If +- * a newly allocated page is also still being vmap()ed by xfs, +- * it will cause pagetable construction to fail. This is a +- * quick workaround to always eagerly unmap pages so that Xen +- * is happy. +- */ +- vunmap(addr); +- return; +-#endif +- +- aentry = kmalloc(sizeof(a_list_t), GFP_NOWAIT); +- if (likely(aentry)) { +- spin_lock(&as_lock); +- aentry->next = as_free_head; +- aentry->vm_addr = addr; +- as_free_head = aentry; +- as_list_len++; +- spin_unlock(&as_lock); +- } else { +- vunmap(addr); +- } +-} +- +-STATIC void +-purge_addresses(void) +-{ +- a_list_t *aentry, *old; +- +- if (as_free_head == NULL) +- return; +- +- spin_lock(&as_lock); +- aentry = as_free_head; +- as_free_head = NULL; +- as_list_len = 0; +- spin_unlock(&as_lock); +- +- while ((old = aentry) != NULL) { +- vunmap(aentry->vm_addr); +- aentry = aentry->next; +- kfree(old); +- } +-} +- +-/* + * Internal xfs_buf_t object manipulation + */ + +@@ -339,7 +264,7 @@ + uint i; + + if ((bp->b_flags & XBF_MAPPED) && (bp->b_page_count > 1)) +- free_address(bp->b_addr - bp->b_offset); ++ vm_unmap_ram(bp->b_addr - bp->b_offset, bp->b_page_count); + + for (i = 0; i < bp->b_page_count; i++) { + struct page *page = bp->b_pages[i]; +@@ -461,10 +386,8 @@ + bp->b_addr = page_address(bp->b_pages[0]) + bp->b_offset; + bp->b_flags |= XBF_MAPPED; + } else if (flags & XBF_MAPPED) { +- if (as_list_len > 64) +- purge_addresses(); +- bp->b_addr = vmap(bp->b_pages, bp->b_page_count, +- VM_MAP, PAGE_KERNEL); ++ bp->b_addr = vm_map_ram(bp->b_pages, bp->b_page_count, ++ -1, PAGE_KERNEL); + if (unlikely(bp->b_addr == NULL)) + return -ENOMEM; + bp->b_addr += bp->b_offset; +@@ -1441,12 +1364,10 @@ + + void + xfs_free_buftarg( +- struct xfs_mount *mp, +- struct xfs_buftarg *btp) ++ xfs_buftarg_t *btp) + { + xfs_flush_buftarg(btp, 1); +- if (mp->m_flags & XFS_MOUNT_BARRIER) +- xfs_blkdev_issue_flush(btp); ++ xfs_blkdev_issue_flush(btp); + xfs_free_bufhash(btp); + iput(btp->bt_mapping->host); + +@@ -1751,8 +1672,6 @@ + count++; + } + +- if (as_list_len > 0) +- purge_addresses(); + if (count) + blk_run_address_space(target->bt_mapping); + +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/fs/xfs/linux-2.6/xfs_buf.h linux-2.6.29-rc3.owrt/fs/xfs/linux-2.6/xfs_buf.h +--- linux-2.6.29.owrt/fs/xfs/linux-2.6/xfs_buf.h 2009-05-10 22:04:39.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/fs/xfs/linux-2.6/xfs_buf.h 2009-05-10 23:48:29.000000000 +0200 +@@ -413,7 +413,7 @@ + * Handling of buftargs. + */ + extern xfs_buftarg_t *xfs_alloc_buftarg(struct block_device *, int); +-extern void xfs_free_buftarg(struct xfs_mount *, struct xfs_buftarg *); ++extern void xfs_free_buftarg(xfs_buftarg_t *); + extern void xfs_wait_buftarg(xfs_buftarg_t *); + extern int xfs_setsize_buftarg(xfs_buftarg_t *, unsigned int, unsigned int); + extern int xfs_flush_buftarg(xfs_buftarg_t *, int); +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/fs/xfs/linux-2.6/xfs_super.c linux-2.6.29-rc3.owrt/fs/xfs/linux-2.6/xfs_super.c +--- linux-2.6.29.owrt/fs/xfs/linux-2.6/xfs_super.c 2009-05-10 22:04:39.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/fs/xfs/linux-2.6/xfs_super.c 2009-05-10 23:48:29.000000000 +0200 +@@ -734,15 +734,15 @@ + { + if (mp->m_logdev_targp && mp->m_logdev_targp != mp->m_ddev_targp) { + struct block_device *logdev = mp->m_logdev_targp->bt_bdev; +- xfs_free_buftarg(mp, mp->m_logdev_targp); ++ xfs_free_buftarg(mp->m_logdev_targp); + xfs_blkdev_put(logdev); + } + if (mp->m_rtdev_targp) { + struct block_device *rtdev = mp->m_rtdev_targp->bt_bdev; +- xfs_free_buftarg(mp, mp->m_rtdev_targp); ++ xfs_free_buftarg(mp->m_rtdev_targp); + xfs_blkdev_put(rtdev); + } +- xfs_free_buftarg(mp, mp->m_ddev_targp); ++ xfs_free_buftarg(mp->m_ddev_targp); + } + + /* +@@ -811,9 +811,9 @@ + + out_free_rtdev_targ: + if (mp->m_rtdev_targp) +- xfs_free_buftarg(mp, mp->m_rtdev_targp); ++ xfs_free_buftarg(mp->m_rtdev_targp); + out_free_ddev_targ: +- xfs_free_buftarg(mp, mp->m_ddev_targp); ++ xfs_free_buftarg(mp->m_ddev_targp); + out_close_rtdev: + if (rtdev) + xfs_blkdev_put(rtdev); +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/fs/xfs/linux-2.6/xfs_sync.c linux-2.6.29-rc3.owrt/fs/xfs/linux-2.6/xfs_sync.c +--- linux-2.6.29.owrt/fs/xfs/linux-2.6/xfs_sync.c 2009-05-10 22:04:39.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/fs/xfs/linux-2.6/xfs_sync.c 2009-05-10 23:48:29.000000000 +0200 +@@ -371,11 +371,7 @@ + /* flush inodes and push all remaining buffers out to disk */ + xfs_quiesce_fs(mp); + +- /* +- * Just warn here till VFS can correctly support +- * read-only remount without racing. +- */ +- WARN_ON(atomic_read(&mp->m_active_trans) != 0); ++ ASSERT_ALWAYS(atomic_read(&mp->m_active_trans) == 0); + + /* Push the superblock and write an unmount record */ + error = xfs_log_sbcount(mp, 1); +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/fs/xfs/xfs_dfrag.c linux-2.6.29-rc3.owrt/fs/xfs/xfs_dfrag.c +--- linux-2.6.29.owrt/fs/xfs/xfs_dfrag.c 2009-05-10 22:04:39.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/fs/xfs/xfs_dfrag.c 2009-05-10 23:48:29.000000000 +0200 +@@ -55,11 +55,17 @@ + struct file *file, *target_file; + int error = 0; + ++ sxp = kmem_alloc(sizeof(xfs_swapext_t), KM_MAYFAIL); ++ if (!sxp) { ++ error = XFS_ERROR(ENOMEM); ++ goto out; ++ } ++ + /* Pull information for the target fd */ + file = fget((int)sxp->sx_fdtarget); + if (!file) { + error = XFS_ERROR(EINVAL); +- goto out; ++ goto out_free_sxp; + } + + if (!(file->f_mode & FMODE_WRITE) || (file->f_flags & O_APPEND)) { +@@ -103,6 +109,8 @@ + fput(target_file); + out_put_file: + fput(file); ++ out_free_sxp: ++ kmem_free(sxp); + out: + return error; + } +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/fs/xfs/xfs_iget.c linux-2.6.29-rc3.owrt/fs/xfs/xfs_iget.c +--- linux-2.6.29.owrt/fs/xfs/xfs_iget.c 2009-05-10 22:04:39.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/fs/xfs/xfs_iget.c 2009-05-10 23:48:29.000000000 +0200 +@@ -246,6 +246,9 @@ + goto out_destroy; + } + ++ if (lock_flags) ++ xfs_ilock(ip, lock_flags); ++ + /* + * Preload the radix tree so we can insert safely under the + * write spinlock. Note that we cannot sleep inside the preload +@@ -253,16 +256,7 @@ + */ + if (radix_tree_preload(GFP_KERNEL)) { + error = EAGAIN; +- goto out_destroy; +- } +- +- /* +- * Because the inode hasn't been added to the radix-tree yet it can't +- * be found by another thread, so we can do the non-sleeping lock here. +- */ +- if (lock_flags) { +- if (!xfs_ilock_nowait(ip, lock_flags)) +- BUG(); ++ goto out_unlock; + } + + mask = ~(((XFS_INODE_CLUSTER_SIZE(mp) >> mp->m_sb.sb_inodelog)) - 1); +@@ -290,6 +284,7 @@ + out_preload_end: + write_unlock(&pag->pag_ici_lock); + radix_tree_preload_end(); ++out_unlock: + if (lock_flags) + xfs_iunlock(ip, lock_flags); + out_destroy: +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/fs/xfs/xfs_log_recover.c linux-2.6.29-rc3.owrt/fs/xfs/xfs_log_recover.c +--- linux-2.6.29.owrt/fs/xfs/xfs_log_recover.c 2009-05-10 22:04:39.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/fs/xfs/xfs_log_recover.c 2009-05-10 23:48:29.000000000 +0200 +@@ -70,21 +70,16 @@ + xfs_buf_t * + xlog_get_bp( + xlog_t *log, +- int nbblks) ++ int num_bblks) + { +- if (nbblks <= 0 || nbblks > log->l_logBBsize) { +- xlog_warn("XFS: Invalid block length (0x%x) given for buffer", nbblks); +- XFS_ERROR_REPORT("xlog_get_bp(1)", +- XFS_ERRLEVEL_HIGH, log->l_mp); +- return NULL; +- } ++ ASSERT(num_bblks > 0); + + if (log->l_sectbb_log) { +- if (nbblks > 1) +- nbblks += XLOG_SECTOR_ROUNDUP_BBCOUNT(log, 1); +- nbblks = XLOG_SECTOR_ROUNDUP_BBCOUNT(log, nbblks); ++ if (num_bblks > 1) ++ num_bblks += XLOG_SECTOR_ROUNDUP_BBCOUNT(log, 1); ++ num_bblks = XLOG_SECTOR_ROUNDUP_BBCOUNT(log, num_bblks); + } +- return xfs_buf_get_noaddr(BBTOB(nbblks), log->l_mp->m_logdev_targp); ++ return xfs_buf_get_noaddr(BBTOB(num_bblks), log->l_mp->m_logdev_targp); + } + + void +@@ -107,13 +102,6 @@ + { + int error; + +- if (nbblks <= 0 || nbblks > log->l_logBBsize) { +- xlog_warn("XFS: Invalid block length (0x%x) given for buffer", nbblks); +- XFS_ERROR_REPORT("xlog_bread(1)", +- XFS_ERRLEVEL_HIGH, log->l_mp); +- return EFSCORRUPTED; +- } +- + if (log->l_sectbb_log) { + blk_no = XLOG_SECTOR_ROUNDDOWN_BLKNO(log, blk_no); + nbblks = XLOG_SECTOR_ROUNDUP_BBCOUNT(log, nbblks); +@@ -151,13 +139,6 @@ + { + int error; + +- if (nbblks <= 0 || nbblks > log->l_logBBsize) { +- xlog_warn("XFS: Invalid block length (0x%x) given for buffer", nbblks); +- XFS_ERROR_REPORT("xlog_bwrite(1)", +- XFS_ERRLEVEL_HIGH, log->l_mp); +- return EFSCORRUPTED; +- } +- + if (log->l_sectbb_log) { + blk_no = XLOG_SECTOR_ROUNDDOWN_BLKNO(log, blk_no); + nbblks = XLOG_SECTOR_ROUNDUP_BBCOUNT(log, nbblks); +@@ -1455,19 +1436,10 @@ + item = item->ri_prev; + + if (item->ri_total == 0) { /* first region to be added */ +- if (in_f->ilf_size == 0 || +- in_f->ilf_size > XLOG_MAX_REGIONS_IN_ITEM) { +- xlog_warn( +- "XFS: bad number of regions (%d) in inode log format", +- in_f->ilf_size); +- ASSERT(0); +- return XFS_ERROR(EIO); +- } +- +- item->ri_total = in_f->ilf_size; +- item->ri_buf = +- kmem_zalloc(item->ri_total * sizeof(xfs_log_iovec_t), +- KM_SLEEP); ++ item->ri_total = in_f->ilf_size; ++ ASSERT(item->ri_total <= XLOG_MAX_REGIONS_IN_ITEM); ++ item->ri_buf = kmem_zalloc((item->ri_total * ++ sizeof(xfs_log_iovec_t)), KM_SLEEP); + } + ASSERT(item->ri_total > item->ri_cnt); + /* Description region is ri_buf[0] */ +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/include/acpi/pdc_intel.h linux-2.6.29-rc3.owrt/include/acpi/pdc_intel.h +--- linux-2.6.29.owrt/include/acpi/pdc_intel.h 2009-05-10 22:04:37.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/include/acpi/pdc_intel.h 2009-05-10 23:48:29.000000000 +0200 +@@ -14,7 +14,6 @@ + #define ACPI_PDC_SMP_T_SWCOORD (0x0080) + #define ACPI_PDC_C_C1_FFH (0x0100) + #define ACPI_PDC_C_C2C3_FFH (0x0200) +-#define ACPI_PDC_SMP_P_HWCOORD (0x0800) + + #define ACPI_PDC_EST_CAPABILITY_SMP (ACPI_PDC_SMP_C1PT | \ + ACPI_PDC_C_C1_HALT | \ +@@ -23,7 +22,6 @@ + #define ACPI_PDC_EST_CAPABILITY_SWSMP (ACPI_PDC_SMP_C1PT | \ + ACPI_PDC_C_C1_HALT | \ + ACPI_PDC_SMP_P_SWCOORD | \ +- ACPI_PDC_SMP_P_HWCOORD | \ + ACPI_PDC_P_FFH) + + #define ACPI_PDC_C_CAPABILITY_SMP (ACPI_PDC_SMP_C2C3 | \ +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/include/asm-frv/pgtable.h linux-2.6.29-rc3.owrt/include/asm-frv/pgtable.h +--- linux-2.6.29.owrt/include/asm-frv/pgtable.h 2009-05-10 22:04:37.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/include/asm-frv/pgtable.h 2009-05-10 23:48:29.000000000 +0200 +@@ -478,7 +478,7 @@ + #define __swp_type(x) (((x).val >> 2) & 0x1f) + #define __swp_offset(x) ((x).val >> 8) + #define __swp_entry(type, offset) ((swp_entry_t) { ((type) << 2) | ((offset) << 8) }) +-#define __pte_to_swp_entry(_pte) ((swp_entry_t) { (_pte).pte }) ++#define __pte_to_swp_entry(pte) ((swp_entry_t) { (pte).pte }) + #define __swp_entry_to_pte(x) ((pte_t) { (x).val }) + + static inline int pte_file(pte_t pte) +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/include/crypto/hash.h linux-2.6.29-rc3.owrt/include/crypto/hash.h +--- linux-2.6.29.owrt/include/crypto/hash.h 2009-05-10 22:04:38.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/include/crypto/hash.h 2009-05-10 23:48:29.000000000 +0200 +@@ -222,7 +222,7 @@ + + static inline void crypto_free_shash(struct crypto_shash *tfm) + { +- crypto_destroy_tfm(tfm, crypto_shash_tfm(tfm)); ++ crypto_free_tfm(crypto_shash_tfm(tfm)); + } + + static inline unsigned int crypto_shash_alignmask( +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/include/drm/drm_crtc.h linux-2.6.29-rc3.owrt/include/drm/drm_crtc.h +--- linux-2.6.29.owrt/include/drm/drm_crtc.h 2009-05-10 22:04:38.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/include/drm/drm_crtc.h 2009-05-10 23:48:29.000000000 +0200 +@@ -609,7 +609,7 @@ + extern char *drm_get_dvi_i_select_name(int val); + extern char *drm_get_tv_subconnector_name(int val); + extern char *drm_get_tv_select_name(int val); +-extern void drm_fb_release(struct drm_file *file_priv); ++extern void drm_fb_release(struct file *filp); + extern int drm_mode_group_init_legacy_group(struct drm_device *dev, struct drm_mode_group *group); + extern struct edid *drm_get_edid(struct drm_connector *connector, + struct i2c_adapter *adapter); +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/include/drm/drm_crtc_helper.h linux-2.6.29-rc3.owrt/include/drm/drm_crtc_helper.h +--- linux-2.6.29.owrt/include/drm/drm_crtc_helper.h 2009-05-10 22:04:38.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/include/drm/drm_crtc_helper.h 2009-05-10 23:48:29.000000000 +0200 +@@ -54,13 +54,13 @@ + struct drm_display_mode *mode, + struct drm_display_mode *adjusted_mode); + /* Actually set the mode */ +- int (*mode_set)(struct drm_crtc *crtc, struct drm_display_mode *mode, +- struct drm_display_mode *adjusted_mode, int x, int y, +- struct drm_framebuffer *old_fb); ++ void (*mode_set)(struct drm_crtc *crtc, struct drm_display_mode *mode, ++ struct drm_display_mode *adjusted_mode, int x, int y, ++ struct drm_framebuffer *old_fb); + + /* Move the crtc on the current fb to the given position *optional* */ +- int (*mode_set_base)(struct drm_crtc *crtc, int x, int y, +- struct drm_framebuffer *old_fb); ++ void (*mode_set_base)(struct drm_crtc *crtc, int x, int y, ++ struct drm_framebuffer *old_fb); + }; + + struct drm_encoder_helper_funcs { +@@ -76,7 +76,6 @@ + void (*mode_set)(struct drm_encoder *encoder, + struct drm_display_mode *mode, + struct drm_display_mode *adjusted_mode); +- struct drm_crtc *(*get_crtc)(struct drm_encoder *encoder); + /* detect for DAC style encoders */ + enum drm_connector_status (*detect)(struct drm_encoder *encoder, + struct drm_connector *connector); +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/include/drm/drm_edid.h linux-2.6.29-rc3.owrt/include/drm/drm_edid.h +--- linux-2.6.29.owrt/include/drm/drm_edid.h 2009-05-10 22:04:38.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/include/drm/drm_edid.h 2009-05-10 23:48:29.000000000 +0200 +@@ -58,10 +58,10 @@ + u8 hsync_pulse_width_lo; + u8 vsync_pulse_width_lo:4; + u8 vsync_offset_lo:4; +- u8 vsync_pulse_width_hi:2; +- u8 vsync_offset_hi:2; + u8 hsync_pulse_width_hi:2; + u8 hsync_offset_hi:2; ++ u8 vsync_pulse_width_hi:2; ++ u8 vsync_offset_hi:2; + u8 width_mm_lo; + u8 height_mm_lo; + u8 height_mm_hi:4; +@@ -69,8 +69,8 @@ + u8 hborder; + u8 vborder; + u8 unknown0:1; +- u8 hsync_positive:1; + u8 vsync_positive:1; ++ u8 hsync_positive:1; + u8 separate_sync:2; + u8 stereo:1; + u8 unknown6:1; +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/include/drm/drmP.h linux-2.6.29-rc3.owrt/include/drm/drmP.h +--- linux-2.6.29.owrt/include/drm/drmP.h 2009-05-10 22:04:38.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/include/drm/drmP.h 2009-05-10 23:48:29.000000000 +0200 +@@ -1321,8 +1321,6 @@ + struct drm_gem_object *drm_gem_object_alloc(struct drm_device *dev, + size_t size); + void drm_gem_object_handle_free(struct kref *kref); +-void drm_gem_vm_open(struct vm_area_struct *vma); +-void drm_gem_vm_close(struct vm_area_struct *vma); + int drm_gem_mmap(struct file *filp, struct vm_area_struct *vma); + + static inline void +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/include/drm/i915_drm.h linux-2.6.29-rc3.owrt/include/drm/i915_drm.h +--- linux-2.6.29.owrt/include/drm/i915_drm.h 2009-05-10 22:04:38.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/include/drm/i915_drm.h 2009-05-10 23:48:29.000000000 +0200 +@@ -261,7 +261,6 @@ + #define I915_PARAM_LAST_DISPATCH 3 + #define I915_PARAM_CHIPSET_ID 4 + #define I915_PARAM_HAS_GEM 5 +-#define I915_PARAM_NUM_FENCES_AVAIL 6 + + typedef struct drm_i915_getparam { + int param; +@@ -273,7 +272,6 @@ + #define I915_SETPARAM_USE_MI_BATCHBUFFER_START 1 + #define I915_SETPARAM_TEX_LRU_LOG_GRANULARITY 2 + #define I915_SETPARAM_ALLOW_BATCHBUFFER 3 +-#define I915_SETPARAM_NUM_USED_FENCES 4 + + typedef struct drm_i915_setparam { + int param; +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/include/linux/aio_abi.h linux-2.6.29-rc3.owrt/include/linux/aio_abi.h +--- linux-2.6.29.owrt/include/linux/aio_abi.h 2009-05-10 22:04:37.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/include/linux/aio_abi.h 2009-05-10 23:48:29.000000000 +0200 +@@ -27,7 +27,6 @@ + #ifndef __LINUX__AIO_ABI_H + #define __LINUX__AIO_ABI_H + +-#include <linux/types.h> + #include <asm/byteorder.h> + + typedef unsigned long aio_context_t; +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/include/linux/async.h linux-2.6.29-rc3.owrt/include/linux/async.h +--- linux-2.6.29.owrt/include/linux/async.h 2009-05-10 22:04:37.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/include/linux/async.h 2009-05-10 23:48:29.000000000 +0200 +@@ -17,11 +17,9 @@ + typedef void (async_func_ptr) (void *data, async_cookie_t cookie); + + extern async_cookie_t async_schedule(async_func_ptr *ptr, void *data); +-extern async_cookie_t async_schedule_domain(async_func_ptr *ptr, void *data, +- struct list_head *list); ++extern async_cookie_t async_schedule_special(async_func_ptr *ptr, void *data, struct list_head *list); + extern void async_synchronize_full(void); +-extern void async_synchronize_full_domain(struct list_head *list); ++extern void async_synchronize_full_special(struct list_head *list); + extern void async_synchronize_cookie(async_cookie_t cookie); +-extern void async_synchronize_cookie_domain(async_cookie_t cookie, +- struct list_head *list); ++extern void async_synchronize_cookie_special(async_cookie_t cookie, struct list_head *list); + +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/include/linux/ata.h linux-2.6.29-rc3.owrt/include/linux/ata.h +--- linux-2.6.29.owrt/include/linux/ata.h 2009-05-10 22:04:37.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/include/linux/ata.h 2009-05-10 23:48:29.000000000 +0200 +@@ -89,8 +89,6 @@ + ATA_ID_DLF = 128, + ATA_ID_CSFO = 129, + ATA_ID_CFA_POWER = 160, +- ATA_ID_CFA_KEY_MGMT = 162, +- ATA_ID_CFA_MODES = 163, + ATA_ID_ROT_SPEED = 217, + ATA_ID_PIO4 = (1 << 1), + +@@ -733,17 +731,12 @@ + + static inline int ata_id_is_cfa(const u16 *id) + { +- if (id[ATA_ID_CONFIG] == 0x848A) /* Traditional CF */ ++ if (id[ATA_ID_CONFIG] == 0x848A) /* Standard CF */ + return 1; +- /* +- * CF specs don't require specific value in the word 0 anymore and yet +- * they forbid to report the ATA version in the word 80 and require the +- * CFA feature set support to be indicated in the word 83 in this case. +- * Unfortunately, some cards only follow either of this requirements, +- * and while those that don't indicate CFA feature support need some +- * sort of quirk list, it seems impractical for the ones that do... +- */ +- if ((id[ATA_ID_COMMAND_SET_2] & 0xC004) == 0x4004) ++ /* Could be CF hiding as standard ATA */ ++ if (ata_id_major_version(id) >= 3 && ++ id[ATA_ID_COMMAND_SET_1] != 0xFFFF && ++ (id[ATA_ID_COMMAND_SET_1] & (1 << 2))) + return 1; + return 0; + } +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/include/linux/atalk.h linux-2.6.29-rc3.owrt/include/linux/atalk.h +--- linux-2.6.29.owrt/include/linux/atalk.h 2009-05-10 22:04:37.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/include/linux/atalk.h 2009-05-10 23:48:29.000000000 +0200 +@@ -1,7 +1,6 @@ + #ifndef __LINUX_ATALK_H__ + #define __LINUX_ATALK_H__ + +-#include <linux/types.h> + #include <asm/byteorder.h> + + /* +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/include/linux/atmbr2684.h linux-2.6.29-rc3.owrt/include/linux/atmbr2684.h +--- linux-2.6.29.owrt/include/linux/atmbr2684.h 2009-05-10 22:04:37.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/include/linux/atmbr2684.h 2009-05-10 23:48:29.000000000 +0200 +@@ -1,7 +1,6 @@ + #ifndef _LINUX_ATMBR2684_H + #define _LINUX_ATMBR2684_H + +-#include <linux/types.h> + #include <linux/atm.h> + #include <linux/if.h> /* For IFNAMSIZ */ + +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/include/linux/auto_fs4.h linux-2.6.29-rc3.owrt/include/linux/auto_fs4.h +--- linux-2.6.29.owrt/include/linux/auto_fs4.h 2009-05-10 22:04:37.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/include/linux/auto_fs4.h 2009-05-10 23:48:29.000000000 +0200 +@@ -12,7 +12,6 @@ + #define _LINUX_AUTO_FS4_H + + /* Include common v3 definitions */ +-#include <linux/types.h> + #include <linux/auto_fs.h> + + /* autofs v4 definitions */ +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/include/linux/bfs_fs.h linux-2.6.29-rc3.owrt/include/linux/bfs_fs.h +--- linux-2.6.29.owrt/include/linux/bfs_fs.h 2009-05-10 22:04:37.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/include/linux/bfs_fs.h 2009-05-10 23:48:29.000000000 +0200 +@@ -6,8 +6,6 @@ + #ifndef _LINUX_BFS_FS_H + #define _LINUX_BFS_FS_H + +-#include <linux/types.h> +- + #define BFS_BSIZE_BITS 9 + #define BFS_BSIZE (1<<BFS_BSIZE_BITS) + +@@ -19,6 +17,7 @@ + #define BFS_VDIR 2L + #define BFS_VREG 1L + ++ + /* BFS inode layout on disk */ + struct bfs_inode { + __le16 i_ino; +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/include/linux/bio.h linux-2.6.29-rc3.owrt/include/linux/bio.h +--- linux-2.6.29.owrt/include/linux/bio.h 2009-05-10 22:04:37.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/include/linux/bio.h 2009-05-10 23:48:29.000000000 +0200 +@@ -144,7 +144,7 @@ + * bit 1 -- rw-ahead when set + * bit 2 -- barrier + * Insert a serialization point in the IO queue, forcing previously +- * submitted IO to be completed before this one is issued. ++ * submitted IO to be completed before this oen is issued. + * bit 3 -- synchronous I/O hint: the block layer will unplug immediately + * Note that this does NOT indicate that the IO itself is sync, just + * that the block layer will not postpone issue of this IO by plugging. +@@ -163,31 +163,12 @@ + #define BIO_RW 0 /* Must match RW in req flags (blkdev.h) */ + #define BIO_RW_AHEAD 1 /* Must match FAILFAST in req flags */ + #define BIO_RW_BARRIER 2 +-#define BIO_RW_SYNCIO 3 +-#define BIO_RW_UNPLUG 4 +-#define BIO_RW_META 5 +-#define BIO_RW_DISCARD 6 +-#define BIO_RW_FAILFAST_DEV 7 +-#define BIO_RW_FAILFAST_TRANSPORT 8 +-#define BIO_RW_FAILFAST_DRIVER 9 +- +-#define bio_rw_flagged(bio, flag) ((bio)->bi_rw & (1 << (flag))) +- +-/* +- * Old defines, these should eventually be replaced by direct usage of +- * bio_rw_flagged() +- */ +-#define bio_barrier(bio) bio_rw_flagged(bio, BIO_RW_BARRIER) +-#define bio_sync(bio) bio_rw_flagged(bio, BIO_RW_SYNCIO) +-#define bio_unplug(bio) bio_rw_flagged(bio, BIO_RW_UNPLUG) +-#define bio_failfast_dev(bio) bio_rw_flagged(bio, BIO_RW_FAILFAST_DEV) +-#define bio_failfast_transport(bio) \ +- bio_rw_flagged(bio, BIO_RW_FAILFAST_TRANSPORT) +-#define bio_failfast_driver(bio) \ +- bio_rw_flagged(bio, BIO_RW_FAILFAST_DRIVER) +-#define bio_rw_ahead(bio) bio_rw_flagged(bio, BIO_RW_AHEAD) +-#define bio_rw_meta(bio) bio_rw_flagged(bio, BIO_RW_META) +-#define bio_discard(bio) bio_rw_flagged(bio, BIO_RW_DISCARD) ++#define BIO_RW_SYNC 3 ++#define BIO_RW_META 4 ++#define BIO_RW_DISCARD 5 ++#define BIO_RW_FAILFAST_DEV 6 ++#define BIO_RW_FAILFAST_TRANSPORT 7 ++#define BIO_RW_FAILFAST_DRIVER 8 + + /* + * upper 16 bits of bi_rw define the io priority of this bio +@@ -212,6 +193,15 @@ + #define bio_offset(bio) bio_iovec((bio))->bv_offset + #define bio_segments(bio) ((bio)->bi_vcnt - (bio)->bi_idx) + #define bio_sectors(bio) ((bio)->bi_size >> 9) ++#define bio_barrier(bio) ((bio)->bi_rw & (1 << BIO_RW_BARRIER)) ++#define bio_sync(bio) ((bio)->bi_rw & (1 << BIO_RW_SYNC)) ++#define bio_failfast_dev(bio) ((bio)->bi_rw & (1 << BIO_RW_FAILFAST_DEV)) ++#define bio_failfast_transport(bio) \ ++ ((bio)->bi_rw & (1 << BIO_RW_FAILFAST_TRANSPORT)) ++#define bio_failfast_driver(bio) ((bio)->bi_rw & (1 << BIO_RW_FAILFAST_DRIVER)) ++#define bio_rw_ahead(bio) ((bio)->bi_rw & (1 << BIO_RW_AHEAD)) ++#define bio_rw_meta(bio) ((bio)->bi_rw & (1 << BIO_RW_META)) ++#define bio_discard(bio) ((bio)->bi_rw & (1 << BIO_RW_DISCARD)) + #define bio_empty_barrier(bio) (bio_barrier(bio) && !bio_has_data(bio) && !bio_discard(bio)) + + static inline unsigned int bio_cur_sectors(struct bio *bio) +@@ -322,6 +312,7 @@ + void *bip_buf; /* generated integrity data */ + bio_end_io_t *bip_end_io; /* saved I/O completion fn */ + ++ int bip_error; /* saved I/O error */ + unsigned int bip_size; + + unsigned short bip_pool; /* pool the ivec came from */ +@@ -449,13 +440,12 @@ + + #ifdef CONFIG_HIGHMEM + /* +- * remember never ever reenable interrupts between a bvec_kmap_irq and +- * bvec_kunmap_irq! ++ * remember to add offset! and never ever reenable interrupts between a ++ * bvec_kmap_irq and bvec_kunmap_irq!! + * + * This function MUST be inlined - it plays with the CPU interrupt flags. + */ +-static __always_inline char *bvec_kmap_irq(struct bio_vec *bvec, +- unsigned long *flags) ++static inline char *bvec_kmap_irq(struct bio_vec *bvec, unsigned long *flags) + { + unsigned long addr; + +@@ -471,8 +461,7 @@ + return (char *) addr + bvec->bv_offset; + } + +-static __always_inline void bvec_kunmap_irq(char *buffer, +- unsigned long *flags) ++static inline void bvec_kunmap_irq(char *buffer, unsigned long *flags) + { + unsigned long ptr = (unsigned long) buffer & PAGE_MASK; + +@@ -531,7 +520,7 @@ + extern void bio_integrity_advance(struct bio *, unsigned int); + extern void bio_integrity_trim(struct bio *, unsigned int, unsigned int); + extern void bio_integrity_split(struct bio *, struct bio_pair *, int); +-extern int bio_integrity_clone(struct bio *, struct bio *, gfp_t, struct bio_set *); ++extern int bio_integrity_clone(struct bio *, struct bio *, struct bio_set *); + extern int bioset_integrity_create(struct bio_set *, int); + extern void bioset_integrity_free(struct bio_set *); + extern void bio_integrity_init_slab(void); +@@ -542,7 +531,7 @@ + #define bioset_integrity_create(a, b) (0) + #define bio_integrity_prep(a) (0) + #define bio_integrity_enabled(a) (0) +-#define bio_integrity_clone(a, b, c,d ) (0) ++#define bio_integrity_clone(a, b, c) (0) + #define bioset_integrity_free(a) do { } while (0) + #define bio_integrity_free(a, b) do { } while (0) + #define bio_integrity_endio(a, b) do { } while (0) +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/include/linux/blkdev.h linux-2.6.29-rc3.owrt/include/linux/blkdev.h +--- linux-2.6.29.owrt/include/linux/blkdev.h 2009-05-10 22:04:37.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/include/linux/blkdev.h 2009-05-10 23:48:29.000000000 +0200 +@@ -108,7 +108,6 @@ + __REQ_RW_META, /* metadata io request */ + __REQ_COPY_USER, /* contains copies of user pages */ + __REQ_INTEGRITY, /* integrity metadata has been remapped */ +- __REQ_UNPLUG, /* unplug queue on submission */ + __REQ_NR_BITS, /* stops here */ + }; + +@@ -135,7 +134,6 @@ + #define REQ_RW_META (1 << __REQ_RW_META) + #define REQ_COPY_USER (1 << __REQ_COPY_USER) + #define REQ_INTEGRITY (1 << __REQ_INTEGRITY) +-#define REQ_UNPLUG (1 << __REQ_UNPLUG) + + #define BLK_MAX_CDB 16 + +@@ -451,11 +449,6 @@ + #define QUEUE_FLAG_STACKABLE 13 /* supports request stacking */ + #define QUEUE_FLAG_NONROT 14 /* non-rotational device (SSD) */ + #define QUEUE_FLAG_VIRT QUEUE_FLAG_NONROT /* paravirt device */ +-#define QUEUE_FLAG_IO_STAT 15 /* do IO stats */ +- +-#define QUEUE_FLAG_DEFAULT ((1 << QUEUE_FLAG_IO_STAT) | \ +- (1 << QUEUE_FLAG_CLUSTER) | \ +- (1 << QUEUE_FLAG_STACKABLE)) + + static inline int queue_is_locked(struct request_queue *q) + { +@@ -572,7 +565,6 @@ + #define blk_queue_stopped(q) test_bit(QUEUE_FLAG_STOPPED, &(q)->queue_flags) + #define blk_queue_nomerges(q) test_bit(QUEUE_FLAG_NOMERGES, &(q)->queue_flags) + #define blk_queue_nonrot(q) test_bit(QUEUE_FLAG_NONROT, &(q)->queue_flags) +-#define blk_queue_io_stat(q) test_bit(QUEUE_FLAG_IO_STAT, &(q)->queue_flags) + #define blk_queue_flushing(q) ((q)->ordseq) + #define blk_queue_stackable(q) \ + test_bit(QUEUE_FLAG_STACKABLE, &(q)->queue_flags) +@@ -708,8 +700,6 @@ + }; + + /* This should not be used directly - use rq_for_each_segment */ +-#define for_each_bio(_bio) \ +- for (; _bio; _bio = _bio->bi_next) + #define __rq_for_each_bio(_bio, rq) \ + if ((rq->bio)) \ + for (_bio = (rq)->bio; _bio; _bio = _bio->bi_next) +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/include/linux/blktrace_api.h linux-2.6.29-rc3.owrt/include/linux/blktrace_api.h +--- linux-2.6.29.owrt/include/linux/blktrace_api.h 2009-05-10 22:04:37.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/include/linux/blktrace_api.h 2009-05-10 23:48:29.000000000 +0200 +@@ -1,7 +1,6 @@ + #ifndef BLKTRACE_H + #define BLKTRACE_H + +-#include <linux/types.h> + #ifdef __KERNEL__ + #include <linux/blkdev.h> + #include <linux/relay.h> +@@ -15,7 +14,6 @@ + BLK_TC_WRITE = 1 << 1, /* writes */ + BLK_TC_BARRIER = 1 << 2, /* barrier */ + BLK_TC_SYNC = 1 << 3, /* sync IO */ +- BLK_TC_SYNCIO = BLK_TC_SYNC, + BLK_TC_QUEUE = 1 << 4, /* queueing/merging */ + BLK_TC_REQUEUE = 1 << 5, /* requeueing */ + BLK_TC_ISSUE = 1 << 6, /* issue */ +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/include/linux/can/bcm.h linux-2.6.29-rc3.owrt/include/linux/can/bcm.h +--- linux-2.6.29.owrt/include/linux/can/bcm.h 2009-05-10 22:04:37.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/include/linux/can/bcm.h 2009-05-10 23:48:29.000000000 +0200 +@@ -14,8 +14,6 @@ + #ifndef CAN_BCM_H + #define CAN_BCM_H + +-#include <linux/types.h> +- + /** + * struct bcm_msg_head - head of messages to/from the broadcast manager + * @opcode: opcode, see enum below. +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/include/linux/capability.h linux-2.6.29-rc3.owrt/include/linux/capability.h +--- linux-2.6.29.owrt/include/linux/capability.h 2009-05-10 22:04:37.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/include/linux/capability.h 2009-05-10 23:48:29.000000000 +0200 +@@ -69,6 +69,10 @@ + #define VFS_CAP_U32 VFS_CAP_U32_2 + #define VFS_CAP_REVISION VFS_CAP_REVISION_2 + ++#ifdef CONFIG_SECURITY_FILE_CAPABILITIES ++extern int file_caps_enabled; ++#endif ++ + struct vfs_cap_data { + __le32 magic_etc; /* Little endian */ + struct { +@@ -92,10 +96,6 @@ + #define _KERNEL_CAPABILITY_VERSION _LINUX_CAPABILITY_VERSION_3 + #define _KERNEL_CAPABILITY_U32S _LINUX_CAPABILITY_U32S_3 + +-#ifdef CONFIG_SECURITY_FILE_CAPABILITIES +-extern int file_caps_enabled; +-#endif +- + typedef struct kernel_cap_struct { + __u32 cap[_KERNEL_CAPABILITY_U32S]; + } kernel_cap_t; +@@ -393,10 +393,8 @@ + # define CAP_FULL_SET ((kernel_cap_t){{ ~0, ~0 }}) + # define CAP_INIT_EFF_SET ((kernel_cap_t){{ ~CAP_TO_MASK(CAP_SETPCAP), ~0 }}) + # define CAP_FS_SET ((kernel_cap_t){{ CAP_FS_MASK_B0, CAP_FS_MASK_B1 } }) +-# define CAP_NFSD_SET ((kernel_cap_t){{ CAP_FS_MASK_B0 \ +- | CAP_TO_MASK(CAP_SYS_RESOURCE) \ +- | CAP_TO_MASK(CAP_MKNOD), \ +- CAP_FS_MASK_B1 } }) ++# define CAP_NFSD_SET ((kernel_cap_t){{ CAP_FS_MASK_B0|CAP_TO_MASK(CAP_SYS_RESOURCE), \ ++ CAP_FS_MASK_B1 } }) + + #endif /* _KERNEL_CAPABILITY_U32S != 2 */ + +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/include/linux/cdrom.h linux-2.6.29-rc3.owrt/include/linux/cdrom.h +--- linux-2.6.29.owrt/include/linux/cdrom.h 2009-05-10 22:04:37.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/include/linux/cdrom.h 2009-05-10 23:48:29.000000000 +0200 +@@ -11,7 +11,6 @@ + #ifndef _LINUX_CDROM_H + #define _LINUX_CDROM_H + +-#include <linux/types.h> + #include <asm/byteorder.h> + + /******************************************************* +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/include/linux/cgroup.h linux-2.6.29-rc3.owrt/include/linux/cgroup.h +--- linux-2.6.29.owrt/include/linux/cgroup.h 2009-05-10 22:04:37.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/include/linux/cgroup.h 2009-05-10 23:48:29.000000000 +0200 +@@ -99,7 +99,6 @@ + while (!atomic_inc_not_zero(&css->refcnt)) { + if (test_bit(CSS_REMOVED, &css->flags)) + return false; +- cpu_relax(); + } + return true; + } +@@ -378,7 +377,6 @@ + * - initiating hotplug events + */ + struct mutex hierarchy_mutex; +- struct lock_class_key subsys_key; + + /* + * Link to parent, and list entry in parent's children. +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/include/linux/cgroupstats.h linux-2.6.29-rc3.owrt/include/linux/cgroupstats.h +--- linux-2.6.29.owrt/include/linux/cgroupstats.h 2009-05-10 22:04:37.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/include/linux/cgroupstats.h 2009-05-10 23:48:29.000000000 +0200 +@@ -15,7 +15,6 @@ + #ifndef _LINUX_CGROUPSTATS_H + #define _LINUX_CGROUPSTATS_H + +-#include <linux/types.h> + #include <linux/taskstats.h> + + /* +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/include/linux/clockchips.h linux-2.6.29-rc3.owrt/include/linux/clockchips.h +--- linux-2.6.29.owrt/include/linux/clockchips.h 2009-05-10 22:04:37.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/include/linux/clockchips.h 2009-05-10 23:48:29.000000000 +0200 +@@ -36,7 +36,6 @@ + CLOCK_EVT_NOTIFY_BROADCAST_EXIT, + CLOCK_EVT_NOTIFY_SUSPEND, + CLOCK_EVT_NOTIFY_RESUME, +- CLOCK_EVT_NOTIFY_CPU_DYING, + CLOCK_EVT_NOTIFY_CPU_DEAD, + }; + +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/include/linux/compiler-gcc.h linux-2.6.29-rc3.owrt/include/linux/compiler-gcc.h +--- linux-2.6.29.owrt/include/linux/compiler-gcc.h 2009-05-10 22:04:37.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/include/linux/compiler-gcc.h 2009-05-10 23:48:29.000000000 +0200 +@@ -52,15 +52,7 @@ + #define __deprecated __attribute__((deprecated)) + #define __packed __attribute__((packed)) + #define __weak __attribute__((weak)) +- +-/* +- * it doesn't make sense on ARM (currently the only user of __naked) to trace +- * naked functions because then mcount is called without stack and frame pointer +- * being set up and there is no chance to restore the lr register to the value +- * before mcount was called. +- */ +-#define __naked __attribute__((naked)) notrace +- ++#define __naked __attribute__((naked)) + #define __noreturn __attribute__((noreturn)) + + /* +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/include/linux/cpufreq.h linux-2.6.29-rc3.owrt/include/linux/cpufreq.h +--- linux-2.6.29.owrt/include/linux/cpufreq.h 2009-05-10 22:04:37.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/include/linux/cpufreq.h 2009-05-10 23:48:29.000000000 +0200 +@@ -234,6 +234,7 @@ + int (*suspend) (struct cpufreq_policy *policy, pm_message_t pmsg); + int (*resume) (struct cpufreq_policy *policy); + struct freq_attr **attr; ++ bool hide_interface; + }; + + /* flags */ +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/include/linux/crypto.h linux-2.6.29-rc3.owrt/include/linux/crypto.h +--- linux-2.6.29.owrt/include/linux/crypto.h 2009-05-10 22:04:37.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/include/linux/crypto.h 2009-05-10 23:48:29.000000000 +0200 +@@ -552,12 +552,7 @@ + const struct crypto_type *frontend, + u32 type, u32 mask); + struct crypto_tfm *crypto_alloc_base(const char *alg_name, u32 type, u32 mask); +-void crypto_destroy_tfm(void *mem, struct crypto_tfm *tfm); +- +-static inline void crypto_free_tfm(struct crypto_tfm *tfm) +-{ +- return crypto_destroy_tfm(tfm, tfm); +-} ++void crypto_free_tfm(struct crypto_tfm *tfm); + + int alg_test(const char *driver, const char *alg, u32 type, u32 mask); + +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/include/linux/dca.h linux-2.6.29-rc3.owrt/include/linux/dca.h +--- linux-2.6.29.owrt/include/linux/dca.h 2009-05-10 22:04:37.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/include/linux/dca.h 2009-05-10 23:48:29.000000000 +0200 +@@ -1,23 +1,3 @@ +-/* +- * Copyright(c) 2007 - 2009 Intel Corporation. All rights reserved. +- * +- * 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, MA 02111-1307, USA. +- * +- * The full GNU General Public License is included in this distribution in the +- * file called COPYING. +- */ + #ifndef DCA_H + #define DCA_H + /* DCA Provider API */ +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/include/linux/dcbnl.h linux-2.6.29-rc3.owrt/include/linux/dcbnl.h +--- linux-2.6.29.owrt/include/linux/dcbnl.h 2009-05-10 22:04:37.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/include/linux/dcbnl.h 2009-05-10 23:48:29.000000000 +0200 +@@ -20,12 +20,10 @@ + #ifndef __LINUX_DCBNL_H__ + #define __LINUX_DCBNL_H__ + +-#include <linux/types.h> +- + #define DCB_PROTO_VERSION 1 + + struct dcbmsg { +- __u8 dcb_family; ++ unsigned char dcb_family; + __u8 cmd; + __u16 dcb_pad; + }; +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/include/linux/device.h linux-2.6.29-rc3.owrt/include/linux/device.h +--- linux-2.6.29.owrt/include/linux/device.h 2009-05-10 22:04:37.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/include/linux/device.h 2009-05-10 23:48:29.000000000 +0200 +@@ -147,8 +147,6 @@ + extern struct device_driver *driver_find(const char *name, + struct bus_type *bus); + extern int driver_probe_done(void); +-extern int wait_for_device_probe(void); +- + + /* sysfs interface for exporting driver attributes */ + +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/include/linux/dlm_plock.h linux-2.6.29-rc3.owrt/include/linux/dlm_plock.h +--- linux-2.6.29.owrt/include/linux/dlm_plock.h 2009-05-10 22:04:37.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/include/linux/dlm_plock.h 2009-05-10 23:48:29.000000000 +0200 +@@ -9,8 +9,6 @@ + #ifndef __DLM_PLOCK_DOT_H__ + #define __DLM_PLOCK_DOT_H__ + +-#include <linux/types.h> +- + #define DLM_PLOCK_MISC_NAME "dlm_plock" + + #define DLM_PLOCK_VERSION_MAJOR 1 +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/include/linux/dmaengine.h linux-2.6.29-rc3.owrt/include/linux/dmaengine.h +--- linux-2.6.29.owrt/include/linux/dmaengine.h 2009-05-10 22:04:37.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/include/linux/dmaengine.h 2009-05-10 23:48:29.000000000 +0200 +@@ -97,6 +97,7 @@ + + /** + * struct dma_chan_percpu - the per-CPU part of struct dma_chan ++ * @refcount: local_t used for open-coded "bigref" counting + * @memcpy_count: transaction counter + * @bytes_transferred: byte counter + */ +@@ -113,11 +114,13 @@ + * @cookie: last cookie value returned to client + * @chan_id: channel ID for sysfs + * @dev: class device for sysfs ++ * @refcount: kref, used in "bigref" slow-mode ++ * @slow_ref: indicates that the DMA channel is free ++ * @rcu: the DMA channel's RCU head + * @device_node: used to add this to the device chan list + * @local: per-cpu pointer to a struct dma_chan_percpu + * @client-count: how many clients are using this channel + * @table_count: number of appearances in the mem-to-mem allocation table +- * @private: private data for certain client-channel associations + */ + struct dma_chan { + struct dma_device *device; +@@ -131,7 +134,6 @@ + struct dma_chan_percpu *local; + int client_count; + int table_count; +- void *private; + }; + + /** +@@ -209,6 +211,8 @@ + * @global_node: list_head for global dma_device_list + * @cap_mask: one or more dma_capability flags + * @max_xor: maximum number of xor sources, 0 if no capability ++ * @refcount: reference count ++ * @done: IO completion struct + * @dev_id: unique device ID + * @dev: struct device reference for dma mapping api + * @device_alloc_chan_resources: allocate resources and return the +@@ -221,7 +225,6 @@ + * @device_prep_dma_interrupt: prepares an end of chain interrupt operation + * @device_prep_slave_sg: prepares a slave dma operation + * @device_terminate_all: terminate all pending operations +- * @device_is_tx_complete: poll for transaction completion + * @device_issue_pending: push pending transactions to hardware + */ + struct dma_device { +@@ -279,18 +282,6 @@ + } + #endif + +-#ifdef CONFIG_NET_DMA +-#define net_dmaengine_get() dmaengine_get() +-#define net_dmaengine_put() dmaengine_put() +-#else +-static inline void net_dmaengine_get(void) +-{ +-} +-static inline void net_dmaengine_put(void) +-{ +-} +-#endif +- + dma_cookie_t dma_async_memcpy_buf_to_buf(struct dma_chan *chan, + void *dest, void *src, size_t len); + dma_cookie_t dma_async_memcpy_buf_to_pg(struct dma_chan *chan, +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/include/linux/dn.h linux-2.6.29-rc3.owrt/include/linux/dn.h +--- linux-2.6.29.owrt/include/linux/dn.h 2009-05-10 22:04:37.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/include/linux/dn.h 2009-05-10 23:48:29.000000000 +0200 +@@ -1,8 +1,6 @@ + #ifndef _LINUX_DN_H + #define _LINUX_DN_H + +-#include <linux/types.h> +- + /* + + DECnet Data Structures and Constants +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/include/linux/dvb/audio.h linux-2.6.29-rc3.owrt/include/linux/dvb/audio.h +--- linux-2.6.29.owrt/include/linux/dvb/audio.h 2009-05-10 22:04:37.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/include/linux/dvb/audio.h 2009-05-10 23:48:29.000000000 +0200 +@@ -24,7 +24,12 @@ + #ifndef _DVBAUDIO_H_ + #define _DVBAUDIO_H_ + ++#ifdef __KERNEL__ + #include <linux/types.h> ++#else ++#include <stdint.h> ++#endif ++ + + typedef enum { + AUDIO_SOURCE_DEMUX, /* Select the demux as the main source */ +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/include/linux/dvb/dmx.h linux-2.6.29-rc3.owrt/include/linux/dvb/dmx.h +--- linux-2.6.29.owrt/include/linux/dvb/dmx.h 2009-05-10 22:04:37.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/include/linux/dvb/dmx.h 2009-05-10 23:48:29.000000000 +0200 +@@ -24,7 +24,7 @@ + #ifndef _DVBDMX_H_ + #define _DVBDMX_H_ + +-#include <linux/types.h> ++#include <asm/types.h> + #ifdef __KERNEL__ + #include <linux/time.h> + #else +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/include/linux/dvb/frontend.h linux-2.6.29-rc3.owrt/include/linux/dvb/frontend.h +--- linux-2.6.29.owrt/include/linux/dvb/frontend.h 2009-05-10 22:04:37.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/include/linux/dvb/frontend.h 2009-05-10 23:48:29.000000000 +0200 +@@ -26,7 +26,8 @@ + #ifndef _DVBFRONTEND_H_ + #define _DVBFRONTEND_H_ + +-#include <linux/types.h> ++#include <asm/types.h> ++ + + typedef enum fe_type { + FE_QPSK, +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/include/linux/dvb/net.h linux-2.6.29-rc3.owrt/include/linux/dvb/net.h +--- linux-2.6.29.owrt/include/linux/dvb/net.h 2009-05-10 22:04:37.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/include/linux/dvb/net.h 2009-05-10 23:48:29.000000000 +0200 +@@ -24,7 +24,8 @@ + #ifndef _DVBNET_H_ + #define _DVBNET_H_ + +-#include <linux/types.h> ++#include <asm/types.h> ++ + + struct dvb_net_if { + __u16 pid; +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/include/linux/dvb/video.h linux-2.6.29-rc3.owrt/include/linux/dvb/video.h +--- linux-2.6.29.owrt/include/linux/dvb/video.h 2009-05-10 22:04:37.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/include/linux/dvb/video.h 2009-05-10 23:48:29.000000000 +0200 +@@ -24,14 +24,17 @@ + #ifndef _DVBVIDEO_H_ + #define _DVBVIDEO_H_ + +-#include <linux/types.h> +-#ifdef __KERNEL__ + #include <linux/compiler.h> ++ ++#ifdef __KERNEL__ ++#include <linux/types.h> + #else ++#include <asm/types.h> + #include <stdint.h> + #include <time.h> + #endif + ++ + typedef enum { + VIDEO_FORMAT_4_3, /* Select 4:3 format */ + VIDEO_FORMAT_16_9, /* Select 16:9 format. */ +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/include/linux/edd.h linux-2.6.29-rc3.owrt/include/linux/edd.h +--- linux-2.6.29.owrt/include/linux/edd.h 2009-05-10 22:04:37.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/include/linux/edd.h 2009-05-10 23:48:29.000000000 +0200 +@@ -30,8 +30,6 @@ + #ifndef _LINUX_EDD_H + #define _LINUX_EDD_H + +-#include <linux/types.h> +- + #define EDDNR 0x1e9 /* addr of number of edd_info structs at EDDBUF + in boot_params - treat this as 1 byte */ + #define EDDBUF 0xd00 /* addr of edd_info structs in boot_params */ +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/include/linux/efs_fs_sb.h linux-2.6.29-rc3.owrt/include/linux/efs_fs_sb.h +--- linux-2.6.29.owrt/include/linux/efs_fs_sb.h 2009-05-10 22:04:37.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/include/linux/efs_fs_sb.h 2009-05-10 23:48:29.000000000 +0200 +@@ -9,7 +9,6 @@ + #ifndef __EFS_FS_SB_H__ + #define __EFS_FS_SB_H__ + +-#include <linux/types.h> + #include <linux/magic.h> + + /* EFS superblock magic numbers */ +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/include/linux/elf-fdpic.h linux-2.6.29-rc3.owrt/include/linux/elf-fdpic.h +--- linux-2.6.29.owrt/include/linux/elf-fdpic.h 2009-05-10 22:04:37.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/include/linux/elf-fdpic.h 2009-05-10 23:48:29.000000000 +0200 +@@ -58,13 +58,11 @@ + #define ELF_FDPIC_FLAG_PRESENT 0x80000000 /* T if this object is present */ + }; + +-#ifdef __KERNEL__ + #ifdef CONFIG_MMU + extern void elf_fdpic_arch_lay_out_mm(struct elf_fdpic_params *exec_params, + struct elf_fdpic_params *interp_params, + unsigned long *start_stack, + unsigned long *start_brk); + #endif +-#endif /* __KERNEL__ */ + + #endif /* _LINUX_ELF_FDPIC_H */ +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/include/linux/elf.h linux-2.6.29-rc3.owrt/include/linux/elf.h +--- linux-2.6.29.owrt/include/linux/elf.h 2009-05-10 22:04:37.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/include/linux/elf.h 2009-05-10 23:48:29.000000000 +0200 +@@ -377,7 +377,6 @@ + Elf64_Word n_type; /* Content type */ + } Elf64_Nhdr; + +-#ifdef __KERNEL__ + #if ELF_CLASS == ELFCLASS32 + + extern Elf32_Dyn _DYNAMIC []; +@@ -405,5 +404,5 @@ + extern int elf_coredump_extra_notes_size(void); + extern int elf_coredump_extra_notes_write(struct file *file, loff_t *foffset); + #endif +-#endif /* __KERNEL__ */ ++ + #endif /* _LINUX_ELF_H */ +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/include/linux/errqueue.h linux-2.6.29-rc3.owrt/include/linux/errqueue.h +--- linux-2.6.29.owrt/include/linux/errqueue.h 2009-05-10 22:04:37.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/include/linux/errqueue.h 2009-05-10 23:48:29.000000000 +0200 +@@ -1,8 +1,6 @@ + #ifndef _LINUX_ERRQUEUE_H + #define _LINUX_ERRQUEUE_H 1 + +-#include <linux/types.h> +- + struct sock_extended_err + { + __u32 ee_errno; +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/include/linux/fb.h linux-2.6.29-rc3.owrt/include/linux/fb.h +--- linux-2.6.29.owrt/include/linux/fb.h 2009-05-10 22:04:37.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/include/linux/fb.h 2009-05-10 23:48:29.000000000 +0200 +@@ -960,21 +960,6 @@ + extern int num_registered_fb; + extern struct class *fb_class; + +-static inline int lock_fb_info(struct fb_info *info) +-{ +- mutex_lock(&info->lock); +- if (!info->fbops) { +- mutex_unlock(&info->lock); +- return 0; +- } +- return 1; +-} +- +-static inline void unlock_fb_info(struct fb_info *info) +-{ +- mutex_unlock(&info->lock); +-} +- + static inline void __fb_pad_aligned_buffer(u8 *dst, u32 d_pitch, + u8 *src, u32 s_pitch, u32 height) + { +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/include/linux/firmware-map.h linux-2.6.29-rc3.owrt/include/linux/firmware-map.h +--- linux-2.6.29.owrt/include/linux/firmware-map.h 2009-05-10 22:04:37.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/include/linux/firmware-map.h 2009-05-10 23:48:29.000000000 +0200 +@@ -1,7 +1,7 @@ + /* + * include/linux/firmware-map.h: + * Copyright (C) 2008 SUSE LINUX Products GmbH +- * by Bernhard Walle <bernhard.walle@gmx.de> ++ * by Bernhard Walle <bwalle@suse.de> + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License v2.0 as published by +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/include/linux/fs.h linux-2.6.29-rc3.owrt/include/linux/fs.h +--- linux-2.6.29.owrt/include/linux/fs.h 2009-05-10 22:04:37.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/include/linux/fs.h 2009-05-10 23:48:29.000000000 +0200 +@@ -54,30 +54,24 @@ + #define MAY_ACCESS 16 + #define MAY_OPEN 32 + +-/* +- * flags in file.f_mode. Note that FMODE_READ and FMODE_WRITE must correspond +- * to O_WRONLY and O_RDWR via the strange trick in __dentry_open() +- */ +- + /* file is open for reading */ + #define FMODE_READ ((__force fmode_t)1) + /* file is open for writing */ + #define FMODE_WRITE ((__force fmode_t)2) + /* file is seekable */ + #define FMODE_LSEEK ((__force fmode_t)4) +-/* file can be accessed using pread */ ++/* file can be accessed using pread/pwrite */ + #define FMODE_PREAD ((__force fmode_t)8) +-/* file can be accessed using pwrite */ +-#define FMODE_PWRITE ((__force fmode_t)16) ++#define FMODE_PWRITE FMODE_PREAD /* These go hand in hand */ + /* File is opened for execution with sys_execve / sys_uselib */ +-#define FMODE_EXEC ((__force fmode_t)32) ++#define FMODE_EXEC ((__force fmode_t)16) + /* File is opened with O_NDELAY (only set for block devices) */ +-#define FMODE_NDELAY ((__force fmode_t)64) ++#define FMODE_NDELAY ((__force fmode_t)32) + /* File is opened with O_EXCL (only set for block devices) */ +-#define FMODE_EXCL ((__force fmode_t)128) ++#define FMODE_EXCL ((__force fmode_t)64) + /* File is opened using open(.., 3, ..) and is writeable only for ioctls + (specialy hack for floppy.c) */ +-#define FMODE_WRITE_IOCTL ((__force fmode_t)256) ++#define FMODE_WRITE_IOCTL ((__force fmode_t)128) + + /* + * Don't update ctime and mtime. +@@ -93,10 +87,10 @@ + #define WRITE 1 + #define READA 2 /* read-ahead - don't block if no resources */ + #define SWRITE 3 /* for ll_rw_block() - wait for buffer lock */ +-#define READ_SYNC (READ | (1 << BIO_RW_SYNCIO) | (1 << BIO_RW_UNPLUG)) ++#define READ_SYNC (READ | (1 << BIO_RW_SYNC)) + #define READ_META (READ | (1 << BIO_RW_META)) +-#define WRITE_SYNC (WRITE | (1 << BIO_RW_SYNCIO) | (1 << BIO_RW_UNPLUG)) +-#define SWRITE_SYNC (SWRITE | (1 << BIO_RW_SYNCIO) | (1 << BIO_RW_UNPLUG)) ++#define WRITE_SYNC (WRITE | (1 << BIO_RW_SYNC)) ++#define SWRITE_SYNC (SWRITE | (1 << BIO_RW_SYNC)) + #define WRITE_BARRIER (WRITE | (1 << BIO_RW_BARRIER)) + #define DISCARD_NOBARRIER (1 << BIO_RW_DISCARD) + #define DISCARD_BARRIER ((1 << BIO_RW_DISCARD) | (1 << BIO_RW_BARRIER)) +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/include/linux/genetlink.h linux-2.6.29-rc3.owrt/include/linux/genetlink.h +--- linux-2.6.29.owrt/include/linux/genetlink.h 2009-05-10 22:04:37.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/include/linux/genetlink.h 2009-05-10 23:48:29.000000000 +0200 +@@ -1,7 +1,6 @@ + #ifndef __LINUX_GENERIC_NETLINK_H + #define __LINUX_GENERIC_NETLINK_H + +-#include <linux/types.h> + #include <linux/netlink.h> + + #define GENL_NAMSIZ 16 /* length of family name */ +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/include/linux/gfs2_ondisk.h linux-2.6.29-rc3.owrt/include/linux/gfs2_ondisk.h +--- linux-2.6.29.owrt/include/linux/gfs2_ondisk.h 2009-05-10 22:04:37.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/include/linux/gfs2_ondisk.h 2009-05-10 23:48:29.000000000 +0200 +@@ -10,8 +10,6 @@ + #ifndef __GFS2_ONDISK_DOT_H__ + #define __GFS2_ONDISK_DOT_H__ + +-#include <linux/types.h> +- + #define GFS2_MAGIC 0x01161970 + #define GFS2_BASIC_BLOCK 512 + #define GFS2_BASIC_BLOCK_SHIFT 9 +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/include/linux/hdreg.h linux-2.6.29-rc3.owrt/include/linux/hdreg.h +--- linux-2.6.29.owrt/include/linux/hdreg.h 2009-05-10 22:04:37.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/include/linux/hdreg.h 2009-05-10 23:48:29.000000000 +0200 +@@ -511,6 +511,7 @@ + unsigned short words69_70[2]; /* reserved words 69-70 + * future command overlap and queuing + */ ++ /* HDIO_GET_IDENTITY currently returns only words 0 through 70 */ + unsigned short words71_74[4]; /* reserved words 71-74 + * for IDENTIFY PACKET DEVICE command + */ +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/include/linux/hiddev.h linux-2.6.29-rc3.owrt/include/linux/hiddev.h +--- linux-2.6.29.owrt/include/linux/hiddev.h 2009-05-10 22:04:37.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/include/linux/hiddev.h 2009-05-10 23:48:29.000000000 +0200 +@@ -27,8 +27,6 @@ + * Vojtech Pavlik, Ucitelska 1576, Prague 8, 182 00 Czech Republic + */ + +-#include <linux/types.h> +- + /* + * The event structure itself + */ +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/include/linux/hid.h linux-2.6.29-rc3.owrt/include/linux/hid.h +--- linux-2.6.29.owrt/include/linux/hid.h 2009-05-10 22:04:37.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/include/linux/hid.h 2009-05-10 23:48:29.000000000 +0200 +@@ -791,7 +791,6 @@ + __FILE__ , ## arg) + #endif /* HID_FF */ + +-#ifdef __KERNEL__ + #ifdef CONFIG_HID_COMPAT + #define HID_COMPAT_LOAD_DRIVER(name) \ + /* prototype to avoid sparse warning */ \ +@@ -805,7 +804,6 @@ + extern void hid_compat_##name(void); \ + hid_compat_##name(); \ + } while (0) +-#endif /* __KERNEL__ */ + + #endif + +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/include/linux/hugetlb.h linux-2.6.29-rc3.owrt/include/linux/hugetlb.h +--- linux-2.6.29.owrt/include/linux/hugetlb.h 2009-05-10 22:04:37.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/include/linux/hugetlb.h 2009-05-10 23:48:29.000000000 +0200 +@@ -33,8 +33,7 @@ + int hugetlb_fault(struct mm_struct *mm, struct vm_area_struct *vma, + unsigned long address, int write_access); + int hugetlb_reserve_pages(struct inode *inode, long from, long to, +- struct vm_area_struct *vma, +- int acctflags); ++ struct vm_area_struct *vma); + void hugetlb_unreserve_pages(struct inode *inode, long offset, long freed); + + extern unsigned long hugepages_treat_as_movable; +@@ -139,7 +138,7 @@ + + extern const struct file_operations hugetlbfs_file_operations; + extern struct vm_operations_struct hugetlb_vm_ops; +-struct file *hugetlb_file_setup(const char *name, size_t, int); ++struct file *hugetlb_file_setup(const char *name, size_t); + int hugetlb_get_quota(struct address_space *mapping, long delta); + void hugetlb_put_quota(struct address_space *mapping, long delta); + +@@ -159,9 +158,9 @@ + } + #else /* !CONFIG_HUGETLBFS */ + +-#define is_file_hugepages(file) 0 +-#define set_file_hugepages(file) BUG() +-#define hugetlb_file_setup(name,size,acctflag) ERR_PTR(-ENOSYS) ++#define is_file_hugepages(file) 0 ++#define set_file_hugepages(file) BUG() ++#define hugetlb_file_setup(name,size) ERR_PTR(-ENOSYS) + + #endif /* !CONFIG_HUGETLBFS */ + +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/include/linux/i2c-dev.h linux-2.6.29-rc3.owrt/include/linux/i2c-dev.h +--- linux-2.6.29.owrt/include/linux/i2c-dev.h 2009-05-10 22:04:37.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/include/linux/i2c-dev.h 2009-05-10 23:48:29.000000000 +0200 +@@ -33,7 +33,7 @@ + */ + #define I2C_RETRIES 0x0701 /* number of times a device address should + be polled when not acknowledging */ +-#define I2C_TIMEOUT 0x0702 /* set timeout in units of 10 ms */ ++#define I2C_TIMEOUT 0x0702 /* set timeout in jiffies - call with int */ + + /* NOTE: Slave address is 7 or 10 bits, but 10-bit addresses + * are NOT supported! (due to code brokenness) +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/include/linux/i2c.h linux-2.6.29-rc3.owrt/include/linux/i2c.h +--- linux-2.6.29.owrt/include/linux/i2c.h 2009-05-10 22:04:37.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/include/linux/i2c.h 2009-05-10 23:48:29.000000000 +0200 +@@ -361,7 +361,7 @@ + struct mutex bus_lock; + struct mutex clist_lock; + +- int timeout; /* in jiffies */ ++ int timeout; + int retries; + struct device dev; /* the adapter device */ + +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/include/linux/icmpv6.h linux-2.6.29-rc3.owrt/include/linux/icmpv6.h +--- linux-2.6.29.owrt/include/linux/icmpv6.h 2009-05-10 22:04:37.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/include/linux/icmpv6.h 2009-05-10 23:48:29.000000000 +0200 +@@ -1,7 +1,6 @@ + #ifndef _LINUX_ICMPV6_H + #define _LINUX_ICMPV6_H + +-#include <linux/types.h> + #include <asm/byteorder.h> + + struct icmp6hdr { +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/include/linux/ide.h linux-2.6.29-rc3.owrt/include/linux/ide.h +--- linux-2.6.29.owrt/include/linux/ide.h 2009-05-10 22:04:37.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/include/linux/ide.h 2009-05-10 23:48:29.000000000 +0200 +@@ -663,7 +663,7 @@ + #define to_ide_device(dev) container_of(dev, ide_drive_t, gendev) + + #define to_ide_drv(obj, cont_type) \ +- container_of(obj, struct cont_type, dev) ++ container_of(obj, struct cont_type, kref) + + #define ide_drv_g(disk, cont_type) \ + container_of((disk)->private_data, struct cont_type, driver) +@@ -797,7 +797,6 @@ + struct scatterlist *sg_table; + int sg_max_nents; /* Maximum number of entries in it */ + int sg_nents; /* Current number of entries in it */ +- int orig_sg_nents; + int sg_dma_direction; /* dma transfer direction */ + + /* data phase of the active command (currently only valid for PIO/DMA) */ +@@ -867,7 +866,6 @@ + unsigned int n_ports; + struct device *dev[2]; + unsigned int (*init_chipset)(struct pci_dev *); +- irq_handler_t irq_handler; + unsigned long host_flags; + void *host_priv; + ide_hwif_t *cur_port; /* for hosts requiring serialization */ +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/include/linux/if_addr.h linux-2.6.29-rc3.owrt/include/linux/if_addr.h +--- linux-2.6.29.owrt/include/linux/if_addr.h 2009-05-10 22:04:37.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/include/linux/if_addr.h 2009-05-10 23:48:29.000000000 +0200 +@@ -1,7 +1,6 @@ + #ifndef __LINUX_IF_ADDR_H + #define __LINUX_IF_ADDR_H + +-#include <linux/types.h> + #include <linux/netlink.h> + + struct ifaddrmsg +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/include/linux/if_addrlabel.h linux-2.6.29-rc3.owrt/include/linux/if_addrlabel.h +--- linux-2.6.29.owrt/include/linux/if_addrlabel.h 2009-05-10 22:04:37.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/include/linux/if_addrlabel.h 2009-05-10 23:48:29.000000000 +0200 +@@ -10,8 +10,6 @@ + #ifndef __LINUX_IF_ADDRLABEL_H + #define __LINUX_IF_ADDRLABEL_H + +-#include <linux/types.h> +- + struct ifaddrlblmsg + { + __u8 ifal_family; /* Address family */ +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/include/linux/if_fc.h linux-2.6.29-rc3.owrt/include/linux/if_fc.h +--- linux-2.6.29.owrt/include/linux/if_fc.h 2009-05-10 22:04:37.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/include/linux/if_fc.h 2009-05-10 23:48:29.000000000 +0200 +@@ -20,7 +20,6 @@ + #ifndef _LINUX_IF_FC_H + #define _LINUX_IF_FC_H + +-#include <linux/types.h> + + #define FC_ALEN 6 /* Octets in one ethernet addr */ + #define FC_HLEN (sizeof(struct fch_hdr)+sizeof(struct fcllc)) +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/include/linux/if_hippi.h linux-2.6.29-rc3.owrt/include/linux/if_hippi.h +--- linux-2.6.29.owrt/include/linux/if_hippi.h 2009-05-10 22:04:37.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/include/linux/if_hippi.h 2009-05-10 23:48:29.000000000 +0200 +@@ -22,7 +22,6 @@ + #ifndef _LINUX_IF_HIPPI_H + #define _LINUX_IF_HIPPI_H + +-#include <linux/types.h> + #include <asm/byteorder.h> + + /* +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/include/linux/if_link.h linux-2.6.29-rc3.owrt/include/linux/if_link.h +--- linux-2.6.29.owrt/include/linux/if_link.h 2009-05-10 22:04:37.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/include/linux/if_link.h 2009-05-10 23:48:29.000000000 +0200 +@@ -1,7 +1,6 @@ + #ifndef _LINUX_IF_LINK_H + #define _LINUX_IF_LINK_H + +-#include <linux/types.h> + #include <linux/netlink.h> + + /* The struct should be in sync with struct net_device_stats */ +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/include/linux/if_ppp.h linux-2.6.29-rc3.owrt/include/linux/if_ppp.h +--- linux-2.6.29.owrt/include/linux/if_ppp.h 2009-05-10 22:04:37.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/include/linux/if_ppp.h 2009-05-10 23:48:29.000000000 +0200 +@@ -33,7 +33,6 @@ + #ifndef _IF_PPP_H_ + #define _IF_PPP_H_ + +-#include <linux/types.h> + #include <linux/compiler.h> + + /* +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/include/linux/if_strip.h linux-2.6.29-rc3.owrt/include/linux/if_strip.h +--- linux-2.6.29.owrt/include/linux/if_strip.h 2009-05-10 22:04:37.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/include/linux/if_strip.h 2009-05-10 23:48:29.000000000 +0200 +@@ -18,8 +18,6 @@ + #ifndef __LINUX_STRIP_H + #define __LINUX_STRIP_H + +-#include <linux/types.h> +- + typedef struct { + __u8 c[6]; + } MetricomAddress; +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/include/linux/if_tr.h linux-2.6.29-rc3.owrt/include/linux/if_tr.h +--- linux-2.6.29.owrt/include/linux/if_tr.h 2009-05-10 22:04:37.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/include/linux/if_tr.h 2009-05-10 23:48:29.000000000 +0200 +@@ -19,7 +19,6 @@ + #ifndef _LINUX_IF_TR_H + #define _LINUX_IF_TR_H + +-#include <linux/types.h> + #include <asm/byteorder.h> /* For __be16 */ + + /* IEEE 802.5 Token-Ring magic constants. The frame sizes omit the preamble +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/include/linux/if_tunnel.h linux-2.6.29-rc3.owrt/include/linux/if_tunnel.h +--- linux-2.6.29.owrt/include/linux/if_tunnel.h 2009-05-10 22:04:37.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/include/linux/if_tunnel.h 2009-05-10 23:48:29.000000000 +0200 +@@ -2,10 +2,7 @@ + #define _IF_TUNNEL_H_ + + #include <linux/types.h> +- +-#ifdef __KERNEL__ + #include <linux/ip.h> +-#endif + + #define SIOCGETTUNNEL (SIOCDEVPRIVATE + 0) + #define SIOCADDTUNNEL (SIOCDEVPRIVATE + 1) +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/include/linux/if_vlan.h linux-2.6.29-rc3.owrt/include/linux/if_vlan.h +--- linux-2.6.29.owrt/include/linux/if_vlan.h 2009-05-10 22:04:37.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/include/linux/if_vlan.h 2009-05-10 23:48:29.000000000 +0200 +@@ -210,7 +210,6 @@ + + /* Move the mac addresses to the beginning of the new header. */ + memmove(skb->data, skb->data + VLAN_HLEN, 2 * VLAN_ETH_ALEN); +- skb->mac_header -= VLAN_HLEN; + + /* first, the ethernet type */ + veth->h_vlan_proto = htons(ETH_P_8021Q); +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/include/linux/igmp.h linux-2.6.29-rc3.owrt/include/linux/igmp.h +--- linux-2.6.29.owrt/include/linux/igmp.h 2009-05-10 22:04:37.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/include/linux/igmp.h 2009-05-10 23:48:29.000000000 +0200 +@@ -16,7 +16,6 @@ + #ifndef _LINUX_IGMP_H + #define _LINUX_IGMP_H + +-#include <linux/types.h> + #include <asm/byteorder.h> + + /* +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/include/linux/inet_diag.h linux-2.6.29-rc3.owrt/include/linux/inet_diag.h +--- linux-2.6.29.owrt/include/linux/inet_diag.h 2009-05-10 22:04:37.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/include/linux/inet_diag.h 2009-05-10 23:48:29.000000000 +0200 +@@ -1,8 +1,6 @@ + #ifndef _INET_DIAG_H_ + #define _INET_DIAG_H_ 1 + +-#include <linux/types.h> +- + /* Just some random number */ + #define TCPDIAG_GETSOCK 18 + #define DCCPDIAG_GETSOCK 19 +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/include/linux/init_task.h linux-2.6.29-rc3.owrt/include/linux/init_task.h +--- linux-2.6.29.owrt/include/linux/init_task.h 2009-05-10 22:04:37.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/include/linux/init_task.h 2009-05-10 23:48:29.000000000 +0200 +@@ -48,11 +48,12 @@ + .posix_timers = LIST_HEAD_INIT(sig.posix_timers), \ + .cpu_timers = INIT_CPU_TIMERS(sig.cpu_timers), \ + .rlim = INIT_RLIMITS, \ +- .cputimer = { \ +- .cputime = INIT_CPUTIME, \ +- .running = 0, \ +- .lock = __SPIN_LOCK_UNLOCKED(sig.cputimer.lock), \ +- }, \ ++ .cputime = { .totals = { \ ++ .utime = cputime_zero, \ ++ .stime = cputime_zero, \ ++ .sum_exec_runtime = 0, \ ++ .lock = __SPIN_LOCK_UNLOCKED(sig.cputime.totals.lock), \ ++ }, }, \ + } + + extern struct nsproxy init_nsproxy; +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/include/linux/intel-iommu.h linux-2.6.29-rc3.owrt/include/linux/intel-iommu.h +--- linux-2.6.29.owrt/include/linux/intel-iommu.h 2009-05-10 22:04:37.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/include/linux/intel-iommu.h 2009-05-10 23:48:29.000000000 +0200 +@@ -194,7 +194,6 @@ + /* FSTS_REG */ + #define DMA_FSTS_PPF ((u32)2) + #define DMA_FSTS_PFO ((u32)1) +-#define DMA_FSTS_IQE (1 << 4) + #define dma_fsts_fault_record_index(s) (((s) >> 8) & 0xff) + + /* FRCD_REG, 32 bits access */ +@@ -329,7 +328,7 @@ + unsigned int size_order, u64 type, + int non_present_entry_flush); + +-extern int qi_submit_sync(struct qi_desc *desc, struct intel_iommu *iommu); ++extern void qi_submit_sync(struct qi_desc *desc, struct intel_iommu *iommu); + + extern void *intel_alloc_coherent(struct device *, size_t, dma_addr_t *, gfp_t); + extern void intel_free_coherent(struct device *, size_t, void *, dma_addr_t); +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/include/linux/io-mapping.h linux-2.6.29-rc3.owrt/include/linux/io-mapping.h +--- linux-2.6.29.owrt/include/linux/io-mapping.h 2009-05-10 22:04:37.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/include/linux/io-mapping.h 2009-05-10 23:48:29.000000000 +0200 +@@ -30,13 +30,10 @@ + * See Documentation/io_mapping.txt + */ + +-#ifdef CONFIG_HAVE_ATOMIC_IOMAP ++/* this struct isn't actually defined anywhere */ ++struct io_mapping; + +-struct io_mapping { +- resource_size_t base; +- unsigned long size; +- pgprot_t prot; +-}; ++#ifdef CONFIG_HAVE_ATOMIC_IOMAP + + /* + * For small address space machines, mapping large objects +@@ -46,40 +43,23 @@ + */ + + static inline struct io_mapping * +-io_mapping_create_wc(resource_size_t base, unsigned long size) ++io_mapping_create_wc(unsigned long base, unsigned long size) + { +- struct io_mapping *iomap; +- +- if (!is_io_mapping_possible(base, size)) +- return NULL; +- +- iomap = kmalloc(sizeof(*iomap), GFP_KERNEL); +- if (!iomap) +- return NULL; +- +- iomap->base = base; +- iomap->size = size; +- iomap->prot = pgprot_writecombine(__pgprot(__PAGE_KERNEL)); +- return iomap; ++ return (struct io_mapping *) base; + } + + static inline void + io_mapping_free(struct io_mapping *mapping) + { +- kfree(mapping); + } + + /* Atomic map/unmap */ + static inline void * + io_mapping_map_atomic_wc(struct io_mapping *mapping, unsigned long offset) + { +- resource_size_t phys_addr; +- unsigned long pfn; +- +- BUG_ON(offset >= mapping->size); +- phys_addr = mapping->base + offset; +- pfn = (unsigned long) (phys_addr >> PAGE_SHIFT); +- return iomap_atomic_prot_pfn(pfn, KM_USER0, mapping->prot); ++ offset += (unsigned long) mapping; ++ return iomap_atomic_prot_pfn(offset >> PAGE_SHIFT, KM_USER0, ++ __pgprot(__PAGE_KERNEL_WC)); + } + + static inline void +@@ -91,12 +71,8 @@ + static inline void * + io_mapping_map_wc(struct io_mapping *mapping, unsigned long offset) + { +- resource_size_t phys_addr; +- +- BUG_ON(offset >= mapping->size); +- phys_addr = mapping->base + offset; +- +- return ioremap_wc(phys_addr, PAGE_SIZE); ++ offset += (unsigned long) mapping; ++ return ioremap_wc(offset, PAGE_SIZE); + } + + static inline void +@@ -107,12 +83,9 @@ + + #else + +-/* this struct isn't actually defined anywhere */ +-struct io_mapping; +- + /* Create the io_mapping object*/ + static inline struct io_mapping * +-io_mapping_create_wc(resource_size_t base, unsigned long size) ++io_mapping_create_wc(unsigned long base, unsigned long size) + { + return (struct io_mapping *) ioremap_wc(base, size); + } +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/include/linux/ip6_tunnel.h linux-2.6.29-rc3.owrt/include/linux/ip6_tunnel.h +--- linux-2.6.29.owrt/include/linux/ip6_tunnel.h 2009-05-10 22:04:37.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/include/linux/ip6_tunnel.h 2009-05-10 23:48:29.000000000 +0200 +@@ -1,8 +1,6 @@ + #ifndef _IP6_TUNNEL_H + #define _IP6_TUNNEL_H + +-#include <linux/types.h> +- + #define IPV6_TLV_TNL_ENCAP_LIMIT 4 + #define IPV6_DEFAULT_TNL_ENCAP_LIMIT 4 + +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/include/linux/ipv6.h linux-2.6.29-rc3.owrt/include/linux/ipv6.h +--- linux-2.6.29.owrt/include/linux/ipv6.h 2009-05-10 22:04:37.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/include/linux/ipv6.h 2009-05-10 23:48:29.000000000 +0200 +@@ -1,7 +1,6 @@ + #ifndef _IPV6_H + #define _IPV6_H + +-#include <linux/types.h> + #include <linux/in6.h> + #include <asm/byteorder.h> + +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/include/linux/ipv6_route.h linux-2.6.29-rc3.owrt/include/linux/ipv6_route.h +--- linux-2.6.29.owrt/include/linux/ipv6_route.h 2009-05-10 22:04:37.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/include/linux/ipv6_route.h 2009-05-10 23:48:29.000000000 +0200 +@@ -13,8 +13,6 @@ + #ifndef _LINUX_IPV6_ROUTE_H + #define _LINUX_IPV6_ROUTE_H + +-#include <linux/types.h> +- + #define RTF_DEFAULT 0x00010000 /* default - learned via ND */ + #define RTF_ALLONLINK 0x00020000 /* (deprecated and will be removed) + fallback, no routers on link */ +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/include/linux/ipx.h linux-2.6.29-rc3.owrt/include/linux/ipx.h +--- linux-2.6.29.owrt/include/linux/ipx.h 2009-05-10 22:04:37.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/include/linux/ipx.h 2009-05-10 23:48:29.000000000 +0200 +@@ -1,6 +1,5 @@ + #ifndef _IPX_H_ + #define _IPX_H_ +-#include <linux/types.h> + #include <linux/sockios.h> + #include <linux/socket.h> + #define IPX_NODE_LEN 6 +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/include/linux/irda.h linux-2.6.29-rc3.owrt/include/linux/irda.h +--- linux-2.6.29.owrt/include/linux/irda.h 2009-05-10 22:04:37.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/include/linux/irda.h 2009-05-10 23:48:29.000000000 +0200 +@@ -25,8 +25,6 @@ + #ifndef KERNEL_IRDA_H + #define KERNEL_IRDA_H + +-#include <linux/types.h> +- + /* Please do *not* add any #include in this file, this file is + * included as-is in user space. + * Please fix the calling file to properly included needed files before +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/include/linux/jbd2.h linux-2.6.29-rc3.owrt/include/linux/jbd2.h +--- linux-2.6.29.owrt/include/linux/jbd2.h 2009-05-10 22:04:37.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/include/linux/jbd2.h 2009-05-10 23:48:29.000000000 +0200 +@@ -308,8 +308,7 @@ + int val = (expr); \ + if (!val) { \ + printk(KERN_ERR \ +- "JBD2 unexpected failure: %s: %s;\n", \ +- __func__, #expr); \ ++ "EXT3-fs unexpected failure: %s;\n",# expr); \ + printk(KERN_ERR why "\n"); \ + } \ + val; \ +@@ -1150,8 +1149,7 @@ + extern int jbd2_journal_bmap(journal_t *, unsigned long, unsigned long long *); + extern int jbd2_journal_force_commit(journal_t *); + extern int jbd2_journal_file_inode(handle_t *handle, struct jbd2_inode *inode); +-extern int jbd2_journal_begin_ordered_truncate(journal_t *journal, +- struct jbd2_inode *inode, loff_t new_size); ++extern int jbd2_journal_begin_ordered_truncate(struct jbd2_inode *inode, loff_t new_size); + extern void jbd2_journal_init_jbd_inode(struct jbd2_inode *jinode, struct inode *inode); + extern void jbd2_journal_release_jbd_inode(journal_t *journal, struct jbd2_inode *jinode); + +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/include/linux/Kbuild linux-2.6.29-rc3.owrt/include/linux/Kbuild +--- linux-2.6.29.owrt/include/linux/Kbuild 2009-05-10 22:04:37.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/include/linux/Kbuild 2009-05-10 23:48:29.000000000 +0200 +@@ -41,7 +41,6 @@ + header-y += bfs_fs.h + header-y += blkpg.h + header-y += bpqether.h +-header-y += bsg.h + header-y += can.h + header-y += cdk.h + header-y += chio.h +@@ -52,7 +51,6 @@ + header-y += cgroupstats.h + header-y += cramfs_fs.h + header-y += cycx_cfm.h +-header-y += dcbnl.h + header-y += dlmconstants.h + header-y += dlm_device.h + header-y += dlm_netlink.h +@@ -91,6 +89,7 @@ + header-y += if_slip.h + header-y += if_strip.h + header-y += if_tun.h ++header-y += if_tunnel.h + header-y += in_route.h + header-y += ioctl.h + header-y += ip6_tunnel.h +@@ -236,7 +235,6 @@ + unifdef-y += if_pppol2tp.h + unifdef-y += if_pppox.h + unifdef-y += if_tr.h +-unifdef-y += if_tunnel.h + unifdef-y += if_vlan.h + unifdef-y += igmp.h + unifdef-y += inet_diag.h +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/include/linux/kernel.h linux-2.6.29-rc3.owrt/include/linux/kernel.h +--- linux-2.6.29.owrt/include/linux/kernel.h 2009-05-10 22:04:37.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/include/linux/kernel.h 2009-05-10 23:48:29.000000000 +0200 +@@ -480,8 +480,7 @@ + /* + * swap - swap value of @a and @b + */ +-#define swap(a, b) \ +- do { typeof(a) __tmp = (a); (a) = (b); (b) = __tmp; } while (0) ++#define swap(a, b) ({ typeof(a) __tmp = (a); (a) = (b); (b) = __tmp; }) + + /** + * container_of - cast a member of a structure out to the containing structure +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/include/linux/kprobes.h linux-2.6.29-rc3.owrt/include/linux/kprobes.h +--- linux-2.6.29.owrt/include/linux/kprobes.h 2009-05-10 22:04:37.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/include/linux/kprobes.h 2009-05-10 23:48:29.000000000 +0200 +@@ -49,13 +49,6 @@ + + /* Attach to insert probes on any functions which should be ignored*/ + #define __kprobes __attribute__((__section__(".kprobes.text"))) notrace +-#else /* CONFIG_KPROBES */ +-typedef int kprobe_opcode_t; +-struct arch_specific_insn { +- int dummy; +-}; +-#define __kprobes notrace +-#endif /* CONFIG_KPROBES */ + + struct kprobe; + struct pt_regs; +@@ -138,6 +131,23 @@ + /* For backward compatibility with old code using JPROBE_ENTRY() */ + #define JPROBE_ENTRY(handler) (handler) + ++DECLARE_PER_CPU(struct kprobe *, current_kprobe); ++DECLARE_PER_CPU(struct kprobe_ctlblk, kprobe_ctlblk); ++ ++#ifdef CONFIG_KRETPROBES ++extern void arch_prepare_kretprobe(struct kretprobe_instance *ri, ++ struct pt_regs *regs); ++extern int arch_trampoline_kprobe(struct kprobe *p); ++#else /* CONFIG_KRETPROBES */ ++static inline void arch_prepare_kretprobe(struct kretprobe *rp, ++ struct pt_regs *regs) ++{ ++} ++static inline int arch_trampoline_kprobe(struct kprobe *p) ++{ ++ return 0; ++} ++#endif /* CONFIG_KRETPROBES */ + /* + * Function-return probe - + * Note: +@@ -178,25 +188,6 @@ + unsigned long range; + }; + +-#ifdef CONFIG_KPROBES +-DECLARE_PER_CPU(struct kprobe *, current_kprobe); +-DECLARE_PER_CPU(struct kprobe_ctlblk, kprobe_ctlblk); +- +-#ifdef CONFIG_KRETPROBES +-extern void arch_prepare_kretprobe(struct kretprobe_instance *ri, +- struct pt_regs *regs); +-extern int arch_trampoline_kprobe(struct kprobe *p); +-#else /* CONFIG_KRETPROBES */ +-static inline void arch_prepare_kretprobe(struct kretprobe *rp, +- struct pt_regs *regs) +-{ +-} +-static inline int arch_trampoline_kprobe(struct kprobe *p) +-{ +- return 0; +-} +-#endif /* CONFIG_KRETPROBES */ +- + extern struct kretprobe_blackpoint kretprobe_blacklist[]; + + static inline void kretprobe_assert(struct kretprobe_instance *ri, +@@ -273,6 +264,10 @@ + + #else /* CONFIG_KPROBES */ + ++#define __kprobes notrace ++struct jprobe; ++struct kretprobe; ++ + static inline struct kprobe *get_kprobe(void *addr) + { + return NULL; +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/include/linux/kvm.h linux-2.6.29-rc3.owrt/include/linux/kvm.h +--- linux-2.6.29.owrt/include/linux/kvm.h 2009-05-10 22:04:37.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/include/linux/kvm.h 2009-05-10 23:48:29.000000000 +0200 +@@ -58,10 +58,10 @@ + __u32 pad; + union { + char dummy[512]; /* reserving space */ +-#ifdef __KVM_HAVE_PIT ++#ifdef CONFIG_X86 + struct kvm_pic_state pic; + #endif +-#ifdef __KVM_HAVE_IOAPIC ++#if defined(CONFIG_X86) || defined(CONFIG_IA64) + struct kvm_ioapic_state ioapic; + #endif + } chip; +@@ -384,16 +384,16 @@ + #define KVM_CAP_MP_STATE 14 + #define KVM_CAP_COALESCED_MMIO 15 + #define KVM_CAP_SYNC_MMU 16 /* Changes to host mmap are reflected in guest */ +-#ifdef __KVM_HAVE_DEVICE_ASSIGNMENT ++#if defined(CONFIG_X86)||defined(CONFIG_IA64) + #define KVM_CAP_DEVICE_ASSIGNMENT 17 + #endif + #define KVM_CAP_IOMMU 18 +-#ifdef __KVM_HAVE_MSI ++#if defined(CONFIG_X86) + #define KVM_CAP_DEVICE_MSI 20 + #endif + /* Bug in KVM_SET_USER_MEMORY_REGION fixed: */ + #define KVM_CAP_DESTROY_MEMORY_REGION_WORKS 21 +-#ifdef __KVM_HAVE_USER_NMI ++#if defined(CONFIG_X86) + #define KVM_CAP_USER_NMI 22 + #endif + +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/include/linux/kvm_host.h linux-2.6.29-rc3.owrt/include/linux/kvm_host.h +--- linux-2.6.29.owrt/include/linux/kvm_host.h 2009-05-10 22:04:37.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/include/linux/kvm_host.h 2009-05-10 23:48:29.000000000 +0200 +@@ -285,7 +285,6 @@ + struct kvm *kvm_arch_create_vm(void); + void kvm_arch_destroy_vm(struct kvm *kvm); + void kvm_free_all_assigned_devices(struct kvm *kvm); +-void kvm_arch_sync_events(struct kvm *kvm); + + int kvm_cpu_get_interrupt(struct kvm_vcpu *v); + int kvm_cpu_has_interrupt(struct kvm_vcpu *v); +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/include/linux/libata.h linux-2.6.29-rc3.owrt/include/linux/libata.h +--- linux-2.6.29.owrt/include/linux/libata.h 2009-05-10 22:04:37.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/include/linux/libata.h 2009-05-10 23:48:29.000000000 +0200 +@@ -275,7 +275,7 @@ + * advised to wait only for the following duration before + * doing SRST. + */ +- ATA_TMOUT_PMP_SRST_WAIT = 5000, ++ ATA_TMOUT_PMP_SRST_WAIT = 1000, + + /* ATA bus states */ + BUS_UNKNOWN = 0, +@@ -380,7 +380,6 @@ + ATA_HORKAGE_ATAPI_MOD16_DMA = (1 << 11), /* use ATAPI DMA for commands + not multiple of 16 bytes */ + ATA_HORKAGE_FIRMWARE_WARN = (1 << 12), /* firwmare update warning */ +- ATA_HORKAGE_1_5_GBPS = (1 << 13), /* force 1.5 Gbps */ + + /* DMA mask for user DMA control: User visible values; DO NOT + renumber */ +@@ -530,7 +529,6 @@ + unsigned long flags; /* ATA_QCFLAG_xxx */ + unsigned int tag; + unsigned int n_elem; +- unsigned int orig_n_elem; + + int dma_dir; + +@@ -582,7 +580,7 @@ + acpi_handle acpi_handle; + union acpi_object *gtf_cache; + #endif +- /* n_sector is CLEAR_BEGIN, read comment above CLEAR_BEGIN */ ++ /* n_sector is used as CLEAR_OFFSET, read comment above CLEAR_OFFSET */ + u64 n_sectors; /* size of device, if ATA */ + unsigned int class; /* ATA_DEV_xxx */ + unsigned long unpark_deadline; +@@ -607,22 +605,20 @@ + u16 heads; /* Number of heads */ + u16 sectors; /* Number of sectors per track */ + ++ /* error history */ ++ int spdn_cnt; ++ struct ata_ering ering; ++ + union { + u16 id[ATA_ID_WORDS]; /* IDENTIFY xxx DEVICE data */ + u32 gscr[SATA_PMP_GSCR_DWORDS]; /* PMP GSCR block */ + }; +- +- /* error history */ +- int spdn_cnt; +- /* ering is CLEAR_END, read comment above CLEAR_END */ +- struct ata_ering ering; + }; + +-/* Fields between ATA_DEVICE_CLEAR_BEGIN and ATA_DEVICE_CLEAR_END are +- * cleared to zero on ata_dev_init(). ++/* Offset into struct ata_device. Fields above it are maintained ++ * acress device init. Fields below are zeroed. + */ +-#define ATA_DEVICE_CLEAR_BEGIN offsetof(struct ata_device, n_sectors) +-#define ATA_DEVICE_CLEAR_END offsetof(struct ata_device, ering) ++#define ATA_DEVICE_CLEAR_OFFSET offsetof(struct ata_device, n_sectors) + + struct ata_eh_info { + struct ata_device *dev; /* offending device */ +@@ -751,8 +747,7 @@ + acpi_handle acpi_handle; + struct ata_acpi_gtm __acpi_init_gtm; /* use ata_acpi_init_gtm() */ + #endif +- /* owned by EH */ +- u8 sector_buf[ATA_SECT_SIZE] ____cacheline_aligned; ++ u8 sector_buf[ATA_SECT_SIZE]; /* owned by EH */ + }; + + /* The following initializer overrides a method to NULL whether one of +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/include/linux/lockd/lockd.h linux-2.6.29-rc3.owrt/include/linux/lockd/lockd.h +--- linux-2.6.29.owrt/include/linux/lockd/lockd.h 2009-05-10 22:04:37.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/include/linux/lockd/lockd.h 2009-05-10 23:48:29.000000000 +0200 +@@ -346,7 +346,6 @@ + return sin1->sin_addr.s_addr == sin2->sin_addr.s_addr; + } + +-#if defined(CONFIG_IPV6) || defined(CONFIG_IPV6_MODULE) + static inline int __nlm_cmp_addr6(const struct sockaddr *sap1, + const struct sockaddr *sap2) + { +@@ -354,13 +353,6 @@ + const struct sockaddr_in6 *sin2 = (const struct sockaddr_in6 *)sap2; + return ipv6_addr_equal(&sin1->sin6_addr, &sin2->sin6_addr); + } +-#else /* !(CONFIG_IPV6 || CONFIG_IPV6_MODULE) */ +-static inline int __nlm_cmp_addr6(const struct sockaddr *sap1, +- const struct sockaddr *sap2) +-{ +- return 0; +-} +-#endif /* !(CONFIG_IPV6 || CONFIG_IPV6_MODULE) */ + + /* + * Compare two host addresses +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/include/linux/minix_fs.h linux-2.6.29-rc3.owrt/include/linux/minix_fs.h +--- linux-2.6.29.owrt/include/linux/minix_fs.h 2009-05-10 22:04:37.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/include/linux/minix_fs.h 2009-05-10 23:48:29.000000000 +0200 +@@ -1,7 +1,6 @@ + #ifndef _LINUX_MINIX_FS_H + #define _LINUX_MINIX_FS_H + +-#include <linux/types.h> + #include <linux/magic.h> + + /* +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/include/linux/mm.h linux-2.6.29-rc3.owrt/include/linux/mm.h +--- linux-2.6.29.owrt/include/linux/mm.h 2009-05-10 22:04:37.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/include/linux/mm.h 2009-05-10 23:48:29.000000000 +0200 +@@ -1041,23 +1041,10 @@ + typedef int (*work_fn_t)(unsigned long, unsigned long, void *); + extern void work_with_active_regions(int nid, work_fn_t work_fn, void *data); + extern void sparse_memory_present_with_active_regions(int nid); +-#endif /* CONFIG_ARCH_POPULATES_NODE_MAP */ +- +-#if !defined(CONFIG_ARCH_POPULATES_NODE_MAP) && \ +- !defined(CONFIG_HAVE_ARCH_EARLY_PFN_TO_NID) +-static inline int __early_pfn_to_nid(unsigned long pfn) +-{ +- return 0; +-} +-#else +-/* please see mm/page_alloc.c */ +-extern int __meminit early_pfn_to_nid(unsigned long pfn); +-#ifdef CONFIG_HAVE_ARCH_EARLY_PFN_TO_NID +-/* there is a per-arch backend function. */ +-extern int __meminit __early_pfn_to_nid(unsigned long pfn); ++#ifndef CONFIG_HAVE_ARCH_EARLY_PFN_TO_NID ++extern int early_pfn_to_nid(unsigned long pfn); + #endif /* CONFIG_HAVE_ARCH_EARLY_PFN_TO_NID */ +-#endif +- ++#endif /* CONFIG_ARCH_POPULATES_NODE_MAP */ + extern void set_dma_reserve(unsigned long new_dma_reserve); + extern void memmap_init_zone(unsigned long, int, unsigned long, + unsigned long, enum memmap_context); +@@ -1142,7 +1129,8 @@ + unsigned long flag, unsigned long pgoff); + extern unsigned long mmap_region(struct file *file, unsigned long addr, + unsigned long len, unsigned long flags, +- unsigned int vm_flags, unsigned long pgoff); ++ unsigned int vm_flags, unsigned long pgoff, ++ int accountable); + + static inline unsigned long do_mmap(struct file *file, unsigned long addr, + unsigned long len, unsigned long prot, +@@ -1172,7 +1160,6 @@ + + /* mm/page-writeback.c */ + int write_one_page(struct page *page, int wait); +-void task_dirty_inc(struct task_struct *tsk); + + /* readahead.c */ + #define VM_MAX_READAHEAD 128 /* kbytes */ +@@ -1318,6 +1305,5 @@ + + extern void *alloc_locked_buffer(size_t size); + extern void free_locked_buffer(void *buffer, size_t size); +-extern void release_locked_buffer(void *buffer, size_t size); + #endif /* __KERNEL__ */ + #endif /* _LINUX_MM_H */ +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/include/linux/mm_types.h linux-2.6.29-rc3.owrt/include/linux/mm_types.h +--- linux-2.6.29.owrt/include/linux/mm_types.h 2009-05-10 22:04:37.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/include/linux/mm_types.h 2009-05-10 23:48:29.000000000 +0200 +@@ -276,7 +276,4 @@ + #endif + }; + +-/* Future-safe accessor for struct mm_struct's cpu_vm_mask. */ +-#define mm_cpumask(mm) (&(mm)->cpu_vm_mask) +- + #endif /* _LINUX_MM_TYPES_H */ +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/include/linux/mmzone.h linux-2.6.29-rc3.owrt/include/linux/mmzone.h +--- linux-2.6.29.owrt/include/linux/mmzone.h 2009-05-10 22:04:37.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/include/linux/mmzone.h 2009-05-10 23:48:29.000000000 +0200 +@@ -1071,7 +1071,7 @@ + #endif /* CONFIG_SPARSEMEM */ + + #ifdef CONFIG_NODES_SPAN_OTHER_NODES +-bool early_pfn_in_nid(unsigned long pfn, int nid); ++#define early_pfn_in_nid(pfn, nid) (early_pfn_to_nid(pfn) == (nid)) + #else + #define early_pfn_in_nid(pfn, nid) (1) + #endif +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/include/linux/module.h linux-2.6.29-rc3.owrt/include/linux/module.h +--- linux-2.6.29.owrt/include/linux/module.h 2009-05-10 22:04:37.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/include/linux/module.h 2009-05-10 23:48:29.000000000 +0200 +@@ -219,6 +219,11 @@ + + #endif + ++struct module_ref ++{ ++ local_t count; ++} ____cacheline_aligned; ++ + enum module_state + { + MODULE_STATE_LIVE, +@@ -339,11 +344,8 @@ + /* Destruction function. */ + void (*exit)(void); + +-#ifdef CONFIG_SMP +- char *refptr; +-#else +- local_t ref; +-#endif ++ /* Reference counts */ ++ struct module_ref ref[NR_CPUS]; + #endif + }; + #ifndef MODULE_ARCH_INIT +@@ -393,21 +395,13 @@ + #define symbol_put(x) __symbol_put(MODULE_SYMBOL_PREFIX #x) + void symbol_put_addr(void *addr); + +-static inline local_t *__module_ref_addr(struct module *mod, int cpu) +-{ +-#ifdef CONFIG_SMP +- return (local_t *) (mod->refptr + per_cpu_offset(cpu)); +-#else +- return &mod->ref; +-#endif +-} +- + /* Sometimes we know we already have a refcount, and it's easier not + to handle the error case (which only happens with rmmod --wait). */ + static inline void __module_get(struct module *module) + { + if (module) { +- local_inc(__module_ref_addr(module, get_cpu())); ++ BUG_ON(module_refcount(module) == 0); ++ local_inc(&module->ref[get_cpu()].count); + put_cpu(); + } + } +@@ -419,7 +413,7 @@ + if (module) { + unsigned int cpu = get_cpu(); + if (likely(module_is_live(module))) +- local_inc(__module_ref_addr(module, cpu)); ++ local_inc(&module->ref[cpu].count); + else + ret = 0; + put_cpu(); +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/include/linux/msdos_fs.h linux-2.6.29-rc3.owrt/include/linux/msdos_fs.h +--- linux-2.6.29.owrt/include/linux/msdos_fs.h 2009-05-10 22:04:37.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/include/linux/msdos_fs.h 2009-05-10 23:48:29.000000000 +0200 +@@ -1,7 +1,6 @@ + #ifndef _LINUX_MSDOS_FS_H + #define _LINUX_MSDOS_FS_H + +-#include <linux/types.h> + #include <linux/magic.h> + #include <asm/byteorder.h> + +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/include/linux/neighbour.h linux-2.6.29-rc3.owrt/include/linux/neighbour.h +--- linux-2.6.29.owrt/include/linux/neighbour.h 2009-05-10 22:04:37.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/include/linux/neighbour.h 2009-05-10 23:48:29.000000000 +0200 +@@ -1,7 +1,6 @@ + #ifndef __LINUX_NEIGHBOUR_H + #define __LINUX_NEIGHBOUR_H + +-#include <linux/types.h> + #include <linux/netlink.h> + + struct ndmsg +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/include/linux/netdevice.h linux-2.6.29-rc3.owrt/include/linux/netdevice.h +--- linux-2.6.29.owrt/include/linux/netdevice.h 2009-05-10 22:04:37.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/include/linux/netdevice.h 2009-05-10 23:48:29.000000000 +0200 +@@ -1081,7 +1081,6 @@ + extern int register_netdevice_notifier(struct notifier_block *nb); + extern int unregister_netdevice_notifier(struct notifier_block *nb); + extern int init_dummy_netdev(struct net_device *dev); +-extern void netdev_resync_ops(struct net_device *dev); + + extern int call_netdevice_notifiers(unsigned long val, struct net_device *dev); + extern struct net_device *dev_get_by_index(struct net *net, int ifindex); +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/include/linux/netfilter/xt_conntrack.h linux-2.6.29-rc3.owrt/include/linux/netfilter/xt_conntrack.h +--- linux-2.6.29.owrt/include/linux/netfilter/xt_conntrack.h 2009-05-10 22:04:37.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/include/linux/netfilter/xt_conntrack.h 2009-05-10 23:48:29.000000000 +0200 +@@ -5,7 +5,6 @@ + #ifndef _XT_CONNTRACK_H + #define _XT_CONNTRACK_H + +-#include <linux/types.h> + #include <linux/netfilter/nf_conntrack_tuple_common.h> + + #define XT_CONNTRACK_STATE_BIT(ctinfo) (1 << ((ctinfo)%IP_CT_IS_REPLY+1)) +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/include/linux/netfilter/xt_NFLOG.h linux-2.6.29-rc3.owrt/include/linux/netfilter/xt_NFLOG.h +--- linux-2.6.29.owrt/include/linux/netfilter/xt_NFLOG.h 2009-05-10 22:04:37.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/include/linux/netfilter/xt_NFLOG.h 2009-05-10 23:48:29.000000000 +0200 +@@ -2,7 +2,7 @@ + #define _XT_NFLOG_TARGET + + #define XT_NFLOG_DEFAULT_GROUP 0x1 +-#define XT_NFLOG_DEFAULT_THRESHOLD 0 ++#define XT_NFLOG_DEFAULT_THRESHOLD 1 + + #define XT_NFLOG_MASK 0x0 + +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/include/linux/nfsacl.h linux-2.6.29-rc3.owrt/include/linux/nfsacl.h +--- linux-2.6.29.owrt/include/linux/nfsacl.h 2009-05-10 22:04:37.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/include/linux/nfsacl.h 2009-05-10 23:48:29.000000000 +0200 +@@ -37,9 +37,6 @@ + #define NFSACL_MAXPAGES ((2*(8+12*NFS_ACL_MAX_ENTRIES) + PAGE_SIZE-1) \ + >> PAGE_SHIFT) + +-#define NFS_ACL_MAX_ENTRIES_INLINE (5) +-#define NFS_ACL_INLINE_BUFSIZE ((2*(2+3*NFS_ACL_MAX_ENTRIES_INLINE)) << 2) +- + static inline unsigned int + nfsacl_size(struct posix_acl *acl_access, struct posix_acl *acl_default) + { +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/include/linux/nfsd/export.h linux-2.6.29-rc3.owrt/include/linux/nfsd/export.h +--- linux-2.6.29.owrt/include/linux/nfsd/export.h 2009-05-10 22:04:37.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/include/linux/nfsd/export.h 2009-05-10 23:48:29.000000000 +0200 +@@ -10,8 +10,9 @@ + #ifndef NFSD_EXPORT_H + #define NFSD_EXPORT_H + +-# include <linux/types.h> ++#include <asm/types.h> + #ifdef __KERNEL__ ++# include <linux/types.h> + # include <linux/in.h> + #endif + +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/include/linux/nfsd/nfsfh.h linux-2.6.29-rc3.owrt/include/linux/nfsd/nfsfh.h +--- linux-2.6.29.owrt/include/linux/nfsd/nfsfh.h 2009-05-10 22:04:37.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/include/linux/nfsd/nfsfh.h 2009-05-10 23:48:29.000000000 +0200 +@@ -14,8 +14,9 @@ + #ifndef _LINUX_NFSD_FH_H + #define _LINUX_NFSD_FH_H + +-# include <linux/types.h> ++#include <asm/types.h> + #ifdef __KERNEL__ ++# include <linux/types.h> + # include <linux/string.h> + # include <linux/fs.h> + #endif +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/include/linux/nfsd/syscall.h linux-2.6.29-rc3.owrt/include/linux/nfsd/syscall.h +--- linux-2.6.29.owrt/include/linux/nfsd/syscall.h 2009-05-10 22:04:37.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/include/linux/nfsd/syscall.h 2009-05-10 23:48:29.000000000 +0200 +@@ -9,8 +9,9 @@ + #ifndef NFSD_SYSCALL_H + #define NFSD_SYSCALL_H + +-# include <linux/types.h> ++#include <asm/types.h> + #ifdef __KERNEL__ ++# include <linux/types.h> + # include <linux/in.h> + #endif + #include <linux/posix_types.h> +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/include/linux/nfs_idmap.h linux-2.6.29-rc3.owrt/include/linux/nfs_idmap.h +--- linux-2.6.29.owrt/include/linux/nfs_idmap.h 2009-05-10 22:04:37.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/include/linux/nfs_idmap.h 2009-05-10 23:48:29.000000000 +0200 +@@ -37,8 +37,6 @@ + #ifndef NFS_IDMAP_H + #define NFS_IDMAP_H + +-#include <linux/types.h> +- + /* XXX from bits/utmp.h */ + #define IDMAP_NAMESZ 128 + +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/include/linux/nfs_xdr.h linux-2.6.29-rc3.owrt/include/linux/nfs_xdr.h +--- linux-2.6.29.owrt/include/linux/nfs_xdr.h 2009-05-10 22:04:37.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/include/linux/nfs_xdr.h 2009-05-10 23:48:29.000000000 +0200 +@@ -406,8 +406,6 @@ + int mask; + struct posix_acl * acl_access; + struct posix_acl * acl_default; +- size_t len; +- unsigned int npages; + struct page ** pages; + }; + +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/include/linux/nubus.h linux-2.6.29-rc3.owrt/include/linux/nubus.h +--- linux-2.6.29.owrt/include/linux/nubus.h 2009-05-10 22:04:37.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/include/linux/nubus.h 2009-05-10 23:48:29.000000000 +0200 +@@ -12,7 +12,6 @@ + #ifndef LINUX_NUBUS_H + #define LINUX_NUBUS_H + +-#include <linux/types.h> + #ifdef __KERNEL__ + #include <asm/nubus.h> + #endif +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/include/linux/pci.h linux-2.6.29-rc3.owrt/include/linux/pci.h +--- linux-2.6.29.owrt/include/linux/pci.h 2009-05-10 22:04:37.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/include/linux/pci.h 2009-05-10 23:48:29.000000000 +0200 +@@ -684,7 +684,7 @@ + void pci_disable_rom(struct pci_dev *pdev); + void __iomem __must_check *pci_map_rom(struct pci_dev *pdev, size_t *size); + void pci_unmap_rom(struct pci_dev *pdev, void __iomem *rom); +-size_t pci_get_rom_size(struct pci_dev *pdev, void __iomem *rom, size_t size); ++size_t pci_get_rom_size(void __iomem *rom, size_t size); + + /* Power management related routines */ + int pci_save_state(struct pci_dev *dev); +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/include/linux/pci_ids.h linux-2.6.29-rc3.owrt/include/linux/pci_ids.h +--- linux-2.6.29.owrt/include/linux/pci_ids.h 2009-05-10 22:04:37.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/include/linux/pci_ids.h 2009-05-10 23:48:29.000000000 +0200 +@@ -1312,7 +1312,6 @@ + #define PCI_DEVICE_ID_VIA_VT3351 0x0351 + #define PCI_DEVICE_ID_VIA_VT3364 0x0364 + #define PCI_DEVICE_ID_VIA_8371_0 0x0391 +-#define PCI_DEVICE_ID_VIA_6415 0x0415 + #define PCI_DEVICE_ID_VIA_8501_0 0x0501 + #define PCI_DEVICE_ID_VIA_82C561 0x0561 + #define PCI_DEVICE_ID_VIA_82C586_1 0x0571 +@@ -1445,7 +1444,6 @@ + #define PCI_DEVICE_ID_DIGI_DF_M_E 0x0071 + #define PCI_DEVICE_ID_DIGI_DF_M_IOM2_A 0x0072 + #define PCI_DEVICE_ID_DIGI_DF_M_A 0x0073 +-#define PCI_DEVICE_ID_DIGI_NEO_8 0x00B1 + #define PCI_DEVICE_ID_NEO_2DB9 0x00C8 + #define PCI_DEVICE_ID_NEO_2DB9PRI 0x00C9 + #define PCI_DEVICE_ID_NEO_2RJ45 0x00CA +@@ -2323,9 +2321,6 @@ + #define PCI_DEVICE_ID_INTEL_82378 0x0484 + #define PCI_DEVICE_ID_INTEL_I960 0x0960 + #define PCI_DEVICE_ID_INTEL_I960RM 0x0962 +-#define PCI_DEVICE_ID_INTEL_8257X_SOL 0x1062 +-#define PCI_DEVICE_ID_INTEL_82573E_SOL 0x1085 +-#define PCI_DEVICE_ID_INTEL_82573L_SOL 0x108F + #define PCI_DEVICE_ID_INTEL_82815_MC 0x1130 + #define PCI_DEVICE_ID_INTEL_82815_CGC 0x1132 + #define PCI_DEVICE_ID_INTEL_82092AA_0 0x1221 +@@ -2430,7 +2425,6 @@ + #define PCI_DEVICE_ID_INTEL_ICH7_0 0x27b8 + #define PCI_DEVICE_ID_INTEL_ICH7_1 0x27b9 + #define PCI_DEVICE_ID_INTEL_ICH7_30 0x27b0 +-#define PCI_DEVICE_ID_INTEL_TGP_LPC 0x27bc + #define PCI_DEVICE_ID_INTEL_ICH7_31 0x27bd + #define PCI_DEVICE_ID_INTEL_ICH7_17 0x27da + #define PCI_DEVICE_ID_INTEL_ICH7_19 0x27dd +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/include/linux/phonet.h linux-2.6.29-rc3.owrt/include/linux/phonet.h +--- linux-2.6.29.owrt/include/linux/phonet.h 2009-05-10 22:04:37.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/include/linux/phonet.h 2009-05-10 23:48:29.000000000 +0200 +@@ -23,8 +23,6 @@ + #ifndef LINUX_PHONET_H + #define LINUX_PHONET_H + +-#include <linux/types.h> +- + /* Automatic protocol selection */ + #define PN_PROTO_TRANSPORT 0 + /* Phonet datagram socket */ +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/include/linux/pkt_cls.h linux-2.6.29-rc3.owrt/include/linux/pkt_cls.h +--- linux-2.6.29.owrt/include/linux/pkt_cls.h 2009-05-10 22:04:37.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/include/linux/pkt_cls.h 2009-05-10 23:48:29.000000000 +0200 +@@ -1,7 +1,6 @@ + #ifndef __LINUX_PKT_CLS_H + #define __LINUX_PKT_CLS_H + +-#include <linux/types.h> + #include <linux/pkt_sched.h> + + /* I think i could have done better macros ; for now this is stolen from +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/include/linux/pkt_sched.h linux-2.6.29-rc3.owrt/include/linux/pkt_sched.h +--- linux-2.6.29.owrt/include/linux/pkt_sched.h 2009-05-10 22:04:37.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/include/linux/pkt_sched.h 2009-05-10 23:48:29.000000000 +0200 +@@ -1,8 +1,6 @@ + #ifndef __LINUX_PKT_SCHED_H + #define __LINUX_PKT_SCHED_H + +-#include <linux/types.h> +- + /* Logical priority bands not depending on specific packet scheduler. + Every scheduler will map them to real traffic classes, if it has + no more precise mechanism to classify packets. +@@ -544,7 +542,7 @@ + + struct tc_drr_stats + { +- __u32 deficit; ++ u32 deficit; + }; + + #endif +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/include/linux/pm.h linux-2.6.29-rc3.owrt/include/linux/pm.h +--- linux-2.6.29.owrt/include/linux/pm.h 2009-05-10 22:04:37.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/include/linux/pm.h 2009-05-10 23:48:29.000000000 +0200 +@@ -381,12 +381,10 @@ + + #ifdef CONFIG_PM_SLEEP + extern void device_pm_lock(void); +-extern int sysdev_resume(void); + extern void device_power_up(pm_message_t state); + extern void device_resume(pm_message_t state); + + extern void device_pm_unlock(void); +-extern int sysdev_suspend(pm_message_t state); + extern int device_power_down(pm_message_t state); + extern int device_suspend(pm_message_t state); + extern int device_prepare_suspend(pm_message_t state); +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/include/linux/ppp_defs.h linux-2.6.29-rc3.owrt/include/linux/ppp_defs.h +--- linux-2.6.29.owrt/include/linux/ppp_defs.h 2009-05-10 22:04:37.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/include/linux/ppp_defs.h 2009-05-10 23:48:29.000000000 +0200 +@@ -25,8 +25,6 @@ + * OR MODIFICATIONS. + */ + +-#include <linux/types.h> +- + /* + * ==FILEVERSION 20000114== + * +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/include/linux/raid/md_p.h linux-2.6.29-rc3.owrt/include/linux/raid/md_p.h +--- linux-2.6.29.owrt/include/linux/raid/md_p.h 2009-05-10 22:04:37.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/include/linux/raid/md_p.h 2009-05-10 23:48:29.000000000 +0200 +@@ -15,8 +15,6 @@ + #ifndef _MD_P_H + #define _MD_P_H + +-#include <linux/types.h> +- + /* + * RAID superblock. + * +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/include/linux/random.h linux-2.6.29-rc3.owrt/include/linux/random.h +--- linux-2.6.29.owrt/include/linux/random.h 2009-05-10 22:04:37.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/include/linux/random.h 2009-05-10 23:48:29.000000000 +0200 +@@ -7,7 +7,6 @@ + #ifndef _LINUX_RANDOM_H + #define _LINUX_RANDOM_H + +-#include <linux/types.h> + #include <linux/ioctl.h> + #include <linux/irqnr.h> + +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/include/linux/rcuclassic.h linux-2.6.29-rc3.owrt/include/linux/rcuclassic.h +--- linux-2.6.29.owrt/include/linux/rcuclassic.h 2009-05-10 22:04:37.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/include/linux/rcuclassic.h 2009-05-10 23:48:29.000000000 +0200 +@@ -181,10 +181,4 @@ + #define rcu_enter_nohz() do { } while (0) + #define rcu_exit_nohz() do { } while (0) + +-/* A context switch is a grace period for rcuclassic. */ +-static inline int rcu_blocking_is_gp(void) +-{ +- return num_online_cpus() == 1; +-} +- + #endif /* __LINUX_RCUCLASSIC_H */ +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/include/linux/rcupdate.h linux-2.6.29-rc3.owrt/include/linux/rcupdate.h +--- linux-2.6.29.owrt/include/linux/rcupdate.h 2009-05-10 22:04:37.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/include/linux/rcupdate.h 2009-05-10 23:48:29.000000000 +0200 +@@ -52,9 +52,6 @@ + void (*func)(struct rcu_head *head); + }; + +-/* Internal to kernel, but needed by rcupreempt.h. */ +-extern int rcu_scheduler_active; +- + #if defined(CONFIG_CLASSIC_RCU) + #include <linux/rcuclassic.h> + #elif defined(CONFIG_TREE_RCU) +@@ -268,7 +265,6 @@ + + /* Internal to kernel */ + extern void rcu_init(void); +-extern void rcu_scheduler_starting(void); + extern int rcu_needs_cpu(int cpu); + + #endif /* __LINUX_RCUPDATE_H */ +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/include/linux/rcupreempt.h linux-2.6.29-rc3.owrt/include/linux/rcupreempt.h +--- linux-2.6.29.owrt/include/linux/rcupreempt.h 2009-05-10 22:04:37.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/include/linux/rcupreempt.h 2009-05-10 23:48:29.000000000 +0200 +@@ -142,19 +142,4 @@ + #define rcu_exit_nohz() do { } while (0) + #endif /* CONFIG_NO_HZ */ + +-/* +- * A context switch is a grace period for rcupreempt synchronize_rcu() +- * only during early boot, before the scheduler has been initialized. +- * So, how the heck do we get a context switch? Well, if the caller +- * invokes synchronize_rcu(), they are willing to accept a context +- * switch, so we simply pretend that one happened. +- * +- * After boot, there might be a blocked or preempted task in an RCU +- * read-side critical section, so we cannot then take the fastpath. +- */ +-static inline int rcu_blocking_is_gp(void) +-{ +- return num_online_cpus() == 1 && !rcu_scheduler_active; +-} +- + #endif /* __LINUX_RCUPREEMPT_H */ +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/include/linux/rcutree.h linux-2.6.29-rc3.owrt/include/linux/rcutree.h +--- linux-2.6.29.owrt/include/linux/rcutree.h 2009-05-10 22:04:37.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/include/linux/rcutree.h 2009-05-10 23:48:29.000000000 +0200 +@@ -326,10 +326,4 @@ + } + #endif /* CONFIG_NO_HZ */ + +-/* A context switch is a grace period for rcutree. */ +-static inline int rcu_blocking_is_gp(void) +-{ +- return num_online_cpus() == 1; +-} +- + #endif /* __LINUX_RCUTREE_H */ +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/include/linux/rtnetlink.h linux-2.6.29-rc3.owrt/include/linux/rtnetlink.h +--- linux-2.6.29.owrt/include/linux/rtnetlink.h 2009-05-10 22:04:37.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/include/linux/rtnetlink.h 2009-05-10 23:48:29.000000000 +0200 +@@ -1,7 +1,6 @@ + #ifndef __LINUX_RTNETLINK_H + #define __LINUX_RTNETLINK_H + +-#include <linux/types.h> + #include <linux/netlink.h> + #include <linux/if_link.h> + #include <linux/if_addr.h> +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/include/linux/sched.h linux-2.6.29-rc3.owrt/include/linux/sched.h +--- linux-2.6.29.owrt/include/linux/sched.h 2009-05-10 22:04:37.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/include/linux/sched.h 2009-05-10 23:48:29.000000000 +0200 +@@ -453,33 +453,23 @@ + cputime_t utime; + cputime_t stime; + unsigned long long sum_exec_runtime; ++ spinlock_t lock; + }; + /* Alternate field names when used to cache expirations. */ + #define prof_exp stime + #define virt_exp utime + #define sched_exp sum_exec_runtime + +-#define INIT_CPUTIME \ +- (struct task_cputime) { \ +- .utime = cputime_zero, \ +- .stime = cputime_zero, \ +- .sum_exec_runtime = 0, \ +- } +- + /** +- * struct thread_group_cputimer - thread group interval timer counts +- * @cputime: thread group interval timers. +- * @running: non-zero when there are timers running and +- * @cputime receives updates. +- * @lock: lock for fields in this struct. ++ * struct thread_group_cputime - thread group interval timer counts ++ * @totals: thread group interval timers; substructure for ++ * uniprocessor kernel, per-cpu for SMP kernel. + * + * This structure contains the version of task_cputime, above, that is +- * used for thread group CPU timer calculations. ++ * used for thread group CPU clock calculations. + */ +-struct thread_group_cputimer { +- struct task_cputime cputime; +- int running; +- spinlock_t lock; ++struct thread_group_cputime { ++ struct task_cputime totals; + }; + + /* +@@ -528,10 +518,10 @@ + cputime_t it_prof_incr, it_virt_incr; + + /* +- * Thread group totals for process CPU timers. +- * See thread_group_cputimer(), et al, for details. ++ * Thread group totals for process CPU clocks. ++ * See thread_group_cputime(), et al, for details. + */ +- struct thread_group_cputimer cputimer; ++ struct thread_group_cputime cputime; + + /* Earliest-expiration cache. */ + struct task_cputime cputime_expires; +@@ -568,7 +558,7 @@ + * Live threads maintain their own counters and add to these + * in __exit_signal, except for the group leader. + */ +- cputime_t utime, stime, cutime, cstime; ++ cputime_t cutime, cstime; + cputime_t gtime; + cputime_t cgtime; + unsigned long nvcsw, nivcsw, cnvcsw, cnivcsw; +@@ -577,14 +567,6 @@ + struct task_io_accounting ioac; + + /* +- * Cumulative ns of schedule CPU time fo dead threads in the +- * group, not including a zombie group leader, (This only differs +- * from jiffies_to_ns(utime + stime) if sched_clock uses something +- * other than jiffies.) +- */ +- unsigned long long sum_sched_runtime; +- +- /* + * We don't bother to synchronize most readers of this at all, + * because there is no reader checking a limit that actually needs + * to get both rlim_cur and rlim_max atomically, and either one +@@ -648,6 +630,7 @@ + atomic_t inotify_devs; /* How many inotify devs does this user have opened? */ + #endif + #ifdef CONFIG_EPOLL ++ atomic_t epoll_devs; /* The number of epoll descriptors currently open */ + atomic_t epoll_watches; /* The number of file descriptors currently watched */ + #endif + #ifdef CONFIG_POSIX_MQUEUE +@@ -1419,9 +1402,6 @@ + #endif + }; + +-/* Future-safe accessor for struct task_struct's cpus_allowed. */ +-#define tsk_cpumask(tsk) (&(tsk)->cpus_allowed) +- + /* + * Priority of a process goes from 0..MAX_PRIO-1, valid RT + * priority is 0..MAX_RT_PRIO-1, and SCHED_NORMAL/SCHED_BATCH +@@ -2203,14 +2183,27 @@ + /* + * Thread group CPU time accounting. + */ +-void thread_group_cputime(struct task_struct *tsk, struct task_cputime *times); +-void thread_group_cputimer(struct task_struct *tsk, struct task_cputime *times); ++ ++static inline ++void thread_group_cputime(struct task_struct *tsk, struct task_cputime *times) ++{ ++ struct task_cputime *totals = &tsk->signal->cputime.totals; ++ unsigned long flags; ++ ++ spin_lock_irqsave(&totals->lock, flags); ++ *times = *totals; ++ spin_unlock_irqrestore(&totals->lock, flags); ++} + + static inline void thread_group_cputime_init(struct signal_struct *sig) + { +- sig->cputimer.cputime = INIT_CPUTIME; +- spin_lock_init(&sig->cputimer.lock); +- sig->cputimer.running = 0; ++ sig->cputime.totals = (struct task_cputime){ ++ .utime = cputime_zero, ++ .stime = cputime_zero, ++ .sum_exec_runtime = 0, ++ }; ++ ++ spin_lock_init(&sig->cputime.totals.lock); + } + + static inline void thread_group_cputime_free(struct signal_struct *sig) +@@ -2294,13 +2287,9 @@ + extern int sched_group_set_rt_period(struct task_group *tg, + long rt_period_us); + extern long sched_group_rt_period(struct task_group *tg); +-extern int sched_rt_can_attach(struct task_group *tg, struct task_struct *tsk); + #endif + #endif + +-extern int task_can_switch_user(struct user_struct *up, +- struct task_struct *tsk); +- + #ifdef CONFIG_TASK_XACCT + static inline void add_rchar(struct task_struct *tsk, ssize_t amt) + { +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/include/linux/seq_file.h linux-2.6.29-rc3.owrt/include/linux/seq_file.h +--- linux-2.6.29.owrt/include/linux/seq_file.h 2009-05-10 22:04:37.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/include/linux/seq_file.h 2009-05-10 23:48:29.000000000 +0200 +@@ -19,7 +19,6 @@ + size_t from; + size_t count; + loff_t index; +- loff_t read_pos; + u64 version; + struct mutex lock; + const struct seq_operations *op; +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/include/linux/serial_core.h linux-2.6.29-rc3.owrt/include/linux/serial_core.h +--- linux-2.6.29.owrt/include/linux/serial_core.h 2009-05-10 22:04:37.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/include/linux/serial_core.h 2009-05-10 23:48:29.000000000 +0200 +@@ -296,7 +296,6 @@ + #define UPF_HARDPPS_CD ((__force upf_t) (1 << 11)) + #define UPF_LOW_LATENCY ((__force upf_t) (1 << 13)) + #define UPF_BUGGY_UART ((__force upf_t) (1 << 14)) +-#define UPF_NO_TXEN_TEST ((__force upf_t) (1 << 15)) + #define UPF_MAGIC_MULTIPLIER ((__force upf_t) (1 << 16)) + #define UPF_CONS_FLOW ((__force upf_t) (1 << 23)) + #define UPF_SHARE_IRQ ((__force upf_t) (1 << 24)) +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/include/linux/serio.h linux-2.6.29-rc3.owrt/include/linux/serio.h +--- linux-2.6.29.owrt/include/linux/serio.h 2009-05-10 22:04:37.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/include/linux/serio.h 2009-05-10 23:48:29.000000000 +0200 +@@ -212,7 +212,7 @@ + #define SERIO_FUJITSU 0x35 + #define SERIO_ZHENHUA 0x36 + #define SERIO_INEXIO 0x37 +-#define SERIO_TOUCHIT213 0x38 ++#define SERIO_TOUCHIT213 0x37 + #define SERIO_W8001 0x39 + + #endif +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/include/linux/signalfd.h linux-2.6.29-rc3.owrt/include/linux/signalfd.h +--- linux-2.6.29.owrt/include/linux/signalfd.h 2009-05-10 22:04:37.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/include/linux/signalfd.h 2009-05-10 23:48:29.000000000 +0200 +@@ -8,7 +8,6 @@ + #ifndef _LINUX_SIGNALFD_H + #define _LINUX_SIGNALFD_H + +-#include <linux/types.h> + /* For O_CLOEXEC and O_NONBLOCK */ + #include <linux/fcntl.h> + +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/include/linux/skbuff.h linux-2.6.29-rc3.owrt/include/linux/skbuff.h +--- linux-2.6.29.owrt/include/linux/skbuff.h 2009-05-10 22:04:37.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/include/linux/skbuff.h 2009-05-10 23:48:29.000000000 +0200 +@@ -434,6 +434,15 @@ + void *here); + extern void skb_under_panic(struct sk_buff *skb, int len, + void *here); ++extern void skb_truesize_bug(struct sk_buff *skb); ++ ++static inline void skb_truesize_check(struct sk_buff *skb) ++{ ++ int len = sizeof(struct sk_buff) + skb->len; ++ ++ if (unlikely((int)skb->truesize < len)) ++ skb_truesize_bug(skb); ++} + + extern int skb_append_datato_frags(struct sock *sk, struct sk_buff *skb, + int getfrag(void *from, char *to, int offset, +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/include/linux/slab_def.h linux-2.6.29-rc3.owrt/include/linux/slab_def.h +--- linux-2.6.29.owrt/include/linux/slab_def.h 2009-05-10 22:04:37.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/include/linux/slab_def.h 2009-05-10 23:48:29.000000000 +0200 +@@ -43,7 +43,10 @@ + i++; + #include <linux/kmalloc_sizes.h> + #undef CACHE +- return NULL; ++ { ++ extern void __you_cannot_kmalloc_that_much(void); ++ __you_cannot_kmalloc_that_much(); ++ } + found: + #ifdef CONFIG_ZONE_DMA + if (flags & GFP_DMA) +@@ -74,7 +77,10 @@ + i++; + #include <linux/kmalloc_sizes.h> + #undef CACHE +- return NULL; ++ { ++ extern void __you_cannot_kmalloc_that_much(void); ++ __you_cannot_kmalloc_that_much(); ++ } + found: + #ifdef CONFIG_ZONE_DMA + if (flags & GFP_DMA) +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/include/linux/slab.h linux-2.6.29-rc3.owrt/include/linux/slab.h +--- linux-2.6.29.owrt/include/linux/slab.h 2009-05-10 22:04:37.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/include/linux/slab.h 2009-05-10 23:48:29.000000000 +0200 +@@ -127,7 +127,6 @@ + void * __must_check __krealloc(const void *, size_t, gfp_t); + void * __must_check krealloc(const void *, size_t, gfp_t); + void kfree(const void *); +-void kzfree(const void *); + size_t ksize(const void *); + + /* +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/include/linux/soundcard.h linux-2.6.29-rc3.owrt/include/linux/soundcard.h +--- linux-2.6.29.owrt/include/linux/soundcard.h 2009-05-10 22:04:37.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/include/linux/soundcard.h 2009-05-10 23:48:29.000000000 +0200 +@@ -1045,36 +1045,50 @@ + */ + #define LOCL_STARTAUDIO 1 + +-#if !defined(__KERNEL__) || defined(USE_SEQ_MACROS) ++#if (!defined(__KERNEL__) && !defined(KERNEL) && !defined(INKERNEL) && !defined(_KERNEL)) || defined(USE_SEQ_MACROS) + /* + * Some convenience macros to simplify programming of the + * /dev/sequencer interface + * +- * This is a legacy interface for applications written against +- * the OSSlib-3.8 style interface. It is no longer possible +- * to actually link against OSSlib with this header, but we +- * still provide these macros for programs using them. +- * +- * If you want to use OSSlib, it is recommended that you get +- * the GPL version of OSS-4.x and build against that version +- * of the header. +- * +- * We redefine the extern keyword so that make headers_check +- * does not complain about SEQ_USE_EXTBUF. ++ * These macros define the API which should be used when possible. + */ + #define SEQ_DECLAREBUF() SEQ_USE_EXTBUF() + + void seqbuf_dump(void); /* This function must be provided by programs */ + +-#define SEQ_PM_DEFINES int __foo_bar___ +- +-#define SEQ_LOAD_GMINSTR(dev, instr) +-#define SEQ_LOAD_GMDRUM(dev, drum) ++extern int OSS_init(int seqfd, int buflen); ++extern void OSS_seqbuf_dump(int fd, unsigned char *buf, int buflen); ++extern void OSS_seq_advbuf(int len, int fd, unsigned char *buf, int buflen); ++extern void OSS_seq_needbuf(int len, int fd, unsigned char *buf, int buflen); ++extern void OSS_patch_caching(int dev, int chn, int patch, ++ int fd, unsigned char *buf, int buflen); ++extern void OSS_drum_caching(int dev, int chn, int patch, ++ int fd, unsigned char *buf, int buflen); ++extern void OSS_write_patch(int fd, unsigned char *buf, int len); ++extern int OSS_write_patch2(int fd, unsigned char *buf, int len); + +-#define _SEQ_EXTERN extern +-#define SEQ_USE_EXTBUF() \ +- _SEQ_EXTERN unsigned char _seqbuf[]; \ +- _SEQ_EXTERN int _seqbuflen; _SEQ_EXTERN int _seqbufptr ++#define SEQ_PM_DEFINES int __foo_bar___ ++#ifdef OSSLIB ++# define SEQ_USE_EXTBUF() \ ++ extern unsigned char *_seqbuf; \ ++ extern int _seqbuflen;extern int _seqbufptr ++# define SEQ_DEFINEBUF(len) SEQ_USE_EXTBUF();static int _requested_seqbuflen=len ++# define _SEQ_ADVBUF(len) OSS_seq_advbuf(len, seqfd, _seqbuf, _seqbuflen) ++# define _SEQ_NEEDBUF(len) OSS_seq_needbuf(len, seqfd, _seqbuf, _seqbuflen) ++# define SEQ_DUMPBUF() OSS_seqbuf_dump(seqfd, _seqbuf, _seqbuflen) ++ ++# define SEQ_LOAD_GMINSTR(dev, instr) \ ++ OSS_patch_caching(dev, -1, instr, seqfd, _seqbuf, _seqbuflen) ++# define SEQ_LOAD_GMDRUM(dev, drum) \ ++ OSS_drum_caching(dev, -1, drum, seqfd, _seqbuf, _seqbuflen) ++#else /* !OSSLIB */ ++ ++# define SEQ_LOAD_GMINSTR(dev, instr) ++# define SEQ_LOAD_GMDRUM(dev, drum) ++ ++# define SEQ_USE_EXTBUF() \ ++ extern unsigned char _seqbuf[]; \ ++ extern int _seqbuflen;extern int _seqbufptr + + #ifndef USE_SIMPLE_MACROS + /* Sample seqbuf_dump() implementation: +@@ -1117,6 +1131,7 @@ + */ + #define _SEQ_NEEDBUF(len) /* empty */ + #endif ++#endif /* !OSSLIB */ + + #define SEQ_VOLUME_MODE(dev, mode) {_SEQ_NEEDBUF(8);\ + _seqbuf[_seqbufptr] = SEQ_EXTENDED;\ +@@ -1200,8 +1215,14 @@ + _CHN_COMMON(dev, MIDI_CHN_PRESSURE, chn, pressure, 0, 0) + + #define SEQ_SET_PATCH SEQ_PGM_CHANGE +-#define SEQ_PGM_CHANGE(dev, chn, patch) \ ++#ifdef OSSLIB ++# define SEQ_PGM_CHANGE(dev, chn, patch) \ ++ {OSS_patch_caching(dev, chn, patch, seqfd, _seqbuf, _seqbuflen); \ ++ _CHN_COMMON(dev, MIDI_PGM_CHANGE, chn, patch, 0, 0);} ++#else ++# define SEQ_PGM_CHANGE(dev, chn, patch) \ + _CHN_COMMON(dev, MIDI_PGM_CHANGE, chn, patch, 0, 0) ++#endif + + #define SEQ_CONTROL(dev, chn, controller, value) \ + _CHN_COMMON(dev, MIDI_CTL_CHANGE, chn, controller, 0, value) +@@ -1279,12 +1300,19 @@ + /* + * Patch loading. + */ +-#define SEQ_WRPATCH(patchx, len) \ ++#ifdef OSSLIB ++# define SEQ_WRPATCH(patchx, len) \ ++ OSS_write_patch(seqfd, (char*)(patchx), len) ++# define SEQ_WRPATCH2(patchx, len) \ ++ OSS_write_patch2(seqfd, (char*)(patchx), len) ++#else ++# define SEQ_WRPATCH(patchx, len) \ + {if (_seqbufptr) SEQ_DUMPBUF();\ + if (write(seqfd, (char*)(patchx), len)==-1) \ + perror("Write patch: /dev/sequencer");} +-#define SEQ_WRPATCH2(patchx, len) \ ++# define SEQ_WRPATCH2(patchx, len) \ + (SEQ_DUMPBUF(), write(seqfd, (char*)(patchx), len)) ++#endif + + #endif + #endif +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/include/linux/sound.h linux-2.6.29-rc3.owrt/include/linux/sound.h +--- linux-2.6.29.owrt/include/linux/sound.h 2009-05-10 22:04:37.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/include/linux/sound.h 2009-05-10 23:48:29.000000000 +0200 +@@ -25,7 +25,6 @@ + #define SND_DEV_AMIDI 13 /* Like /dev/midi (obsolete) */ + #define SND_DEV_ADMMIDI 14 /* Like /dev/dmmidi (onsolete) */ + +-#ifdef __KERNEL__ + /* + * Sound core interface functions + */ +@@ -41,4 +40,3 @@ + extern void unregister_sound_mixer(int unit); + extern void unregister_sound_midi(int unit); + extern void unregister_sound_dsp(int unit); +-#endif /* __KERNEL__ */ +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/include/linux/spi/spi_bitbang.h linux-2.6.29-rc3.owrt/include/linux/spi/spi_bitbang.h +--- linux-2.6.29.owrt/include/linux/spi/spi_bitbang.h 2009-05-10 22:04:37.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/include/linux/spi/spi_bitbang.h 2009-05-10 23:48:29.000000000 +0200 +@@ -83,13 +83,6 @@ + * int getmiso(struct spi_device *); + * void spidelay(unsigned); + * +- * setsck()'s is_on parameter is a zero/nonzero boolean. +- * +- * setmosi()'s is_on parameter is a zero/nonzero boolean. +- * +- * getmiso() is required to return 0 or 1 only. Any other value is invalid +- * and will result in improper operation. +- * + * A non-inlined routine would call bitbang_txrx_*() routines. The + * main loop could easily compile down to a handful of instructions, + * especially if the delay is a NOP (to run at peak speed). +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/include/linux/spi/spidev.h linux-2.6.29-rc3.owrt/include/linux/spi/spidev.h +--- linux-2.6.29.owrt/include/linux/spi/spidev.h 2009-05-10 22:04:37.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/include/linux/spi/spidev.h 2009-05-10 23:48:29.000000000 +0200 +@@ -22,7 +22,6 @@ + #ifndef SPIDEV_H + #define SPIDEV_H + +-#include <linux/types.h> + + /* User space versions of kernel symbols for SPI clocking modes, + * matching <linux/spi/spi.h> +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/include/linux/spinlock.h linux-2.6.29-rc3.owrt/include/linux/spinlock.h +--- linux-2.6.29.owrt/include/linux/spinlock.h 2009-05-10 22:04:37.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/include/linux/spinlock.h 2009-05-10 23:48:29.000000000 +0200 +@@ -124,12 +124,7 @@ + #ifdef CONFIG_GENERIC_LOCKBREAK + #define spin_is_contended(lock) ((lock)->break_lock) + #else +- +-#ifdef __raw_spin_is_contended + #define spin_is_contended(lock) __raw_spin_is_contended(&(lock)->raw_lock) +-#else +-#define spin_is_contended(lock) (((void)(lock), 0)) +-#endif /*__raw_spin_is_contended*/ + #endif + + /** +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/include/linux/synclink.h linux-2.6.29-rc3.owrt/include/linux/synclink.h +--- linux-2.6.29.owrt/include/linux/synclink.h 2009-05-10 22:04:37.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/include/linux/synclink.h 2009-05-10 23:48:29.000000000 +0200 +@@ -13,8 +13,6 @@ + #define _SYNCLINK_H_ + #define SYNCLINK_H_VERSION 3.6 + +-#include <linux/types.h> +- + #define BIT0 0x0001 + #define BIT1 0x0002 + #define BIT2 0x0004 +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/include/linux/syscalls.h linux-2.6.29-rc3.owrt/include/linux/syscalls.h +--- linux-2.6.29.owrt/include/linux/syscalls.h 2009-05-10 22:04:37.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/include/linux/syscalls.h 2009-05-10 23:48:29.000000000 +0200 +@@ -95,47 +95,42 @@ + #define __SC_TEST5(t5, a5, ...) __SC_TEST(t5); __SC_TEST4(__VA_ARGS__) + #define __SC_TEST6(t6, a6, ...) __SC_TEST(t6); __SC_TEST5(__VA_ARGS__) + +-#define SYSCALL_DEFINE0(name) asmlinkage long sys_##name(void) +-#define SYSCALL_DEFINE1(name, ...) SYSCALL_DEFINEx(1, _##name, __VA_ARGS__) +-#define SYSCALL_DEFINE2(name, ...) SYSCALL_DEFINEx(2, _##name, __VA_ARGS__) +-#define SYSCALL_DEFINE3(name, ...) SYSCALL_DEFINEx(3, _##name, __VA_ARGS__) +-#define SYSCALL_DEFINE4(name, ...) SYSCALL_DEFINEx(4, _##name, __VA_ARGS__) +-#define SYSCALL_DEFINE5(name, ...) SYSCALL_DEFINEx(5, _##name, __VA_ARGS__) +-#define SYSCALL_DEFINE6(name, ...) SYSCALL_DEFINEx(6, _##name, __VA_ARGS__) ++#define SYSCALL_DEFINE0(name) asmlinkage long sys_##name(void) ++#define SYSCALL_DEFINE1(...) SYSCALL_DEFINEx(1, __VA_ARGS__) ++#define SYSCALL_DEFINE2(...) SYSCALL_DEFINEx(2, __VA_ARGS__) ++#define SYSCALL_DEFINE3(...) SYSCALL_DEFINEx(3, __VA_ARGS__) ++#define SYSCALL_DEFINE4(...) SYSCALL_DEFINEx(4, __VA_ARGS__) ++#define SYSCALL_DEFINE5(...) SYSCALL_DEFINEx(5, __VA_ARGS__) ++#define SYSCALL_DEFINE6(...) SYSCALL_DEFINEx(6, __VA_ARGS__) + + #ifdef CONFIG_PPC64 + #define SYSCALL_ALIAS(alias, name) \ + asm ("\t.globl " #alias "\n\t.set " #alias ", " #name "\n" \ + "\t.globl ." #alias "\n\t.set ." #alias ", ." #name) + #else +-#ifdef CONFIG_ALPHA +-#define SYSCALL_ALIAS(alias, name) \ +- asm ( #alias " = " #name "\n\t.globl " #alias) +-#else + #define SYSCALL_ALIAS(alias, name) \ + asm ("\t.globl " #alias "\n\t.set " #alias ", " #name) + #endif +-#endif + + #ifdef CONFIG_HAVE_SYSCALL_WRAPPERS + + #define SYSCALL_DEFINE(name) static inline long SYSC_##name + #define SYSCALL_DEFINEx(x, name, ...) \ +- asmlinkage long sys##name(__SC_DECL##x(__VA_ARGS__)); \ +- static inline long SYSC##name(__SC_DECL##x(__VA_ARGS__)); \ +- asmlinkage long SyS##name(__SC_LONG##x(__VA_ARGS__)) \ ++ asmlinkage long sys_##name(__SC_DECL##x(__VA_ARGS__)); \ ++ static inline long SYSC_##name(__SC_DECL##x(__VA_ARGS__)); \ ++ asmlinkage long SyS_##name(__SC_LONG##x(__VA_ARGS__)) \ + { \ + __SC_TEST##x(__VA_ARGS__); \ +- return (long) SYSC##name(__SC_CAST##x(__VA_ARGS__)); \ ++ return (long) SYSC_##name(__SC_CAST##x(__VA_ARGS__)); \ + } \ +- SYSCALL_ALIAS(sys##name, SyS##name); \ +- static inline long SYSC##name(__SC_DECL##x(__VA_ARGS__)) ++ SYSCALL_ALIAS(sys_##name, SyS_##name); \ ++ static inline long SYSC_##name(__SC_DECL##x(__VA_ARGS__)) + + #else /* CONFIG_HAVE_SYSCALL_WRAPPERS */ + + #define SYSCALL_DEFINE(name) asmlinkage long sys_##name + #define SYSCALL_DEFINEx(x, name, ...) \ +- asmlinkage long sys##name(__SC_DECL##x(__VA_ARGS__)) ++ asmlinkage long sys_##name(__SC_DECL##x(__VA_ARGS__)) + + #endif /* CONFIG_HAVE_SYSCALL_WRAPPERS */ + +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/include/linux/taskstats.h linux-2.6.29-rc3.owrt/include/linux/taskstats.h +--- linux-2.6.29.owrt/include/linux/taskstats.h 2009-05-10 22:04:37.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/include/linux/taskstats.h 2009-05-10 23:48:29.000000000 +0200 +@@ -16,8 +16,6 @@ + #ifndef _LINUX_TASKSTATS_H + #define _LINUX_TASKSTATS_H + +-#include <linux/types.h> +- + /* Format for per-task data returned to userland when + * - a task exits + * - listener requests stats for a task +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/include/linux/tc_act/tc_gact.h linux-2.6.29-rc3.owrt/include/linux/tc_act/tc_gact.h +--- linux-2.6.29.owrt/include/linux/tc_act/tc_gact.h 2009-05-10 22:04:37.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/include/linux/tc_act/tc_gact.h 2009-05-10 23:48:29.000000000 +0200 +@@ -1,7 +1,6 @@ + #ifndef __LINUX_TC_GACT_H + #define __LINUX_TC_GACT_H + +-#include <linux/types.h> + #include <linux/pkt_cls.h> + + #define TCA_ACT_GACT 5 +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/include/linux/tc_act/tc_mirred.h linux-2.6.29-rc3.owrt/include/linux/tc_act/tc_mirred.h +--- linux-2.6.29.owrt/include/linux/tc_act/tc_mirred.h 2009-05-10 22:04:37.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/include/linux/tc_act/tc_mirred.h 2009-05-10 23:48:29.000000000 +0200 +@@ -1,7 +1,6 @@ + #ifndef __LINUX_TC_MIR_H + #define __LINUX_TC_MIR_H + +-#include <linux/types.h> + #include <linux/pkt_cls.h> + + #define TCA_ACT_MIRRED 8 +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/include/linux/tc_act/tc_pedit.h linux-2.6.29-rc3.owrt/include/linux/tc_act/tc_pedit.h +--- linux-2.6.29.owrt/include/linux/tc_act/tc_pedit.h 2009-05-10 22:04:37.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/include/linux/tc_act/tc_pedit.h 2009-05-10 23:48:29.000000000 +0200 +@@ -1,7 +1,6 @@ + #ifndef __LINUX_TC_PED_H + #define __LINUX_TC_PED_H + +-#include <linux/types.h> + #include <linux/pkt_cls.h> + + #define TCA_ACT_PEDIT 7 +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/include/linux/tc_ematch/tc_em_cmp.h linux-2.6.29-rc3.owrt/include/linux/tc_ematch/tc_em_cmp.h +--- linux-2.6.29.owrt/include/linux/tc_ematch/tc_em_cmp.h 2009-05-10 22:04:37.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/include/linux/tc_ematch/tc_em_cmp.h 2009-05-10 23:48:29.000000000 +0200 +@@ -1,7 +1,6 @@ + #ifndef __LINUX_TC_EM_CMP_H + #define __LINUX_TC_EM_CMP_H + +-#include <linux/types.h> + #include <linux/pkt_cls.h> + + struct tcf_em_cmp +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/include/linux/tc_ematch/tc_em_meta.h linux-2.6.29-rc3.owrt/include/linux/tc_ematch/tc_em_meta.h +--- linux-2.6.29.owrt/include/linux/tc_ematch/tc_em_meta.h 2009-05-10 22:04:37.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/include/linux/tc_ematch/tc_em_meta.h 2009-05-10 23:48:29.000000000 +0200 +@@ -1,7 +1,6 @@ + #ifndef __LINUX_TC_EM_META_H + #define __LINUX_TC_EM_META_H + +-#include <linux/types.h> + #include <linux/pkt_cls.h> + + enum +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/include/linux/tc_ematch/tc_em_nbyte.h linux-2.6.29-rc3.owrt/include/linux/tc_ematch/tc_em_nbyte.h +--- linux-2.6.29.owrt/include/linux/tc_ematch/tc_em_nbyte.h 2009-05-10 22:04:37.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/include/linux/tc_ematch/tc_em_nbyte.h 2009-05-10 23:48:29.000000000 +0200 +@@ -1,7 +1,6 @@ + #ifndef __LINUX_TC_EM_NBYTE_H + #define __LINUX_TC_EM_NBYTE_H + +-#include <linux/types.h> + #include <linux/pkt_cls.h> + + struct tcf_em_nbyte +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/include/linux/tc_ematch/tc_em_text.h linux-2.6.29-rc3.owrt/include/linux/tc_ematch/tc_em_text.h +--- linux-2.6.29.owrt/include/linux/tc_ematch/tc_em_text.h 2009-05-10 22:04:37.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/include/linux/tc_ematch/tc_em_text.h 2009-05-10 23:48:29.000000000 +0200 +@@ -1,7 +1,6 @@ + #ifndef __LINUX_TC_EM_TEXT_H + #define __LINUX_TC_EM_TEXT_H + +-#include <linux/types.h> + #include <linux/pkt_cls.h> + + #define TC_EM_TEXT_ALGOSIZ 16 +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/include/linux/timerfd.h linux-2.6.29-rc3.owrt/include/linux/timerfd.h +--- linux-2.6.29.owrt/include/linux/timerfd.h 2009-05-10 22:04:37.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/include/linux/timerfd.h 2009-05-10 23:48:29.000000000 +0200 +@@ -11,21 +11,13 @@ + /* For O_CLOEXEC and O_NONBLOCK */ + #include <linux/fcntl.h> + +-/* +- * CAREFUL: Check include/asm-generic/fcntl.h when defining +- * new flags, since they might collide with O_* ones. We want +- * to re-use O_* flags that couldn't possibly have a meaning +- * from eventfd, in order to leave a free define-space for +- * shared O_* flags. +- */ ++/* Flags for timerfd_settime. */ + #define TFD_TIMER_ABSTIME (1 << 0) ++ ++/* Flags for timerfd_create. */ + #define TFD_CLOEXEC O_CLOEXEC + #define TFD_NONBLOCK O_NONBLOCK + +-#define TFD_SHARED_FCNTL_FLAGS (TFD_CLOEXEC | TFD_NONBLOCK) +-/* Flags for timerfd_create. */ +-#define TFD_CREATE_FLAGS TFD_SHARED_FCNTL_FLAGS +-/* Flags for timerfd_settime. */ +-#define TFD_SETTIME_FLAGS TFD_TIMER_ABSTIME + + #endif /* _LINUX_TIMERFD_H */ ++ +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/include/linux/usb/cdc.h linux-2.6.29-rc3.owrt/include/linux/usb/cdc.h +--- linux-2.6.29.owrt/include/linux/usb/cdc.h 2009-05-10 22:04:37.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/include/linux/usb/cdc.h 2009-05-10 23:48:29.000000000 +0200 +@@ -9,8 +9,6 @@ + #ifndef __LINUX_USB_CDC_H + #define __LINUX_USB_CDC_H + +-#include <linux/types.h> +- + #define USB_CDC_SUBCLASS_ACM 0x02 + #define USB_CDC_SUBCLASS_ETHERNET 0x06 + #define USB_CDC_SUBCLASS_WHCM 0x08 +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/include/linux/usb/gadgetfs.h linux-2.6.29-rc3.owrt/include/linux/usb/gadgetfs.h +--- linux-2.6.29.owrt/include/linux/usb/gadgetfs.h 2009-05-10 22:04:37.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/include/linux/usb/gadgetfs.h 2009-05-10 23:48:29.000000000 +0200 +@@ -18,7 +18,7 @@ + #ifndef __LINUX_USB_GADGETFS_H + #define __LINUX_USB_GADGETFS_H + +-#include <linux/types.h> ++#include <asm/types.h> + #include <asm/ioctl.h> + + #include <linux/usb/ch9.h> +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/include/linux/user_namespace.h linux-2.6.29-rc3.owrt/include/linux/user_namespace.h +--- linux-2.6.29.owrt/include/linux/user_namespace.h 2009-05-10 22:04:37.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/include/linux/user_namespace.h 2009-05-10 23:48:29.000000000 +0200 +@@ -13,7 +13,6 @@ + struct kref kref; + struct hlist_head uidhash_table[UIDHASH_SZ]; + struct user_struct *creator; +- struct work_struct destroyer; + }; + + extern struct user_namespace init_user_ns; +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/include/linux/video_decoder.h linux-2.6.29-rc3.owrt/include/linux/video_decoder.h +--- linux-2.6.29.owrt/include/linux/video_decoder.h 2009-05-10 22:04:37.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/include/linux/video_decoder.h 2009-05-10 23:48:29.000000000 +0200 +@@ -1,8 +1,6 @@ + #ifndef _LINUX_VIDEO_DECODER_H + #define _LINUX_VIDEO_DECODER_H + +-#include <linux/types.h> +- + #define HAVE_VIDEO_DECODER 1 + + struct video_decoder_capability { /* this name is too long */ +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/include/linux/videodev.h linux-2.6.29-rc3.owrt/include/linux/videodev.h +--- linux-2.6.29.owrt/include/linux/videodev.h 2009-05-10 22:04:37.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/include/linux/videodev.h 2009-05-10 23:48:29.000000000 +0200 +@@ -12,7 +12,6 @@ + #ifndef __LINUX_VIDEODEV_H + #define __LINUX_VIDEODEV_H + +-#include <linux/types.h> + #include <linux/ioctl.h> + #include <linux/videodev2.h> + +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/include/linux/video_encoder.h linux-2.6.29-rc3.owrt/include/linux/video_encoder.h +--- linux-2.6.29.owrt/include/linux/video_encoder.h 2009-05-10 22:04:37.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/include/linux/video_encoder.h 2009-05-10 23:48:29.000000000 +0200 +@@ -1,8 +1,6 @@ + #ifndef _LINUX_VIDEO_ENCODER_H + #define _LINUX_VIDEO_ENCODER_H + +-#include <linux/types.h> +- + struct video_encoder_capability { /* this name is too long */ + __u32 flags; + #define VIDEO_ENCODER_PAL 1 /* can encode PAL signal */ +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/include/linux/virtio_blk.h linux-2.6.29-rc3.owrt/include/linux/virtio_blk.h +--- linux-2.6.29.owrt/include/linux/virtio_blk.h 2009-05-10 22:04:37.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/include/linux/virtio_blk.h 2009-05-10 23:48:29.000000000 +0200 +@@ -2,7 +2,6 @@ + #define _LINUX_VIRTIO_BLK_H + /* This header is BSD licensed so anyone can use the definitions to implement + * compatible drivers/servers. */ +-#include <linux/types.h> + #include <linux/virtio_config.h> + + /* The ID for virtio_block */ +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/include/linux/virtio_console.h linux-2.6.29-rc3.owrt/include/linux/virtio_console.h +--- linux-2.6.29.owrt/include/linux/virtio_console.h 2009-05-10 22:04:37.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/include/linux/virtio_console.h 2009-05-10 23:48:29.000000000 +0200 +@@ -1,6 +1,5 @@ + #ifndef _LINUX_VIRTIO_CONSOLE_H + #define _LINUX_VIRTIO_CONSOLE_H +-#include <linux/types.h> + #include <linux/virtio_config.h> + /* This header, excluding the #ifdef __KERNEL__ part, is BSD licensed so + * anyone can use the definitions to implement compatible drivers/servers. */ +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/include/linux/virtio_net.h linux-2.6.29-rc3.owrt/include/linux/virtio_net.h +--- linux-2.6.29.owrt/include/linux/virtio_net.h 2009-05-10 22:04:37.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/include/linux/virtio_net.h 2009-05-10 23:48:29.000000000 +0200 +@@ -2,7 +2,6 @@ + #define _LINUX_VIRTIO_NET_H + /* This header is BSD licensed so anyone can use the definitions to implement + * compatible drivers/servers. */ +-#include <linux/types.h> + #include <linux/virtio_config.h> + + /* The ID for virtio_net */ +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/include/linux/vmalloc.h linux-2.6.29-rc3.owrt/include/linux/vmalloc.h +--- linux-2.6.29.owrt/include/linux/vmalloc.h 2009-05-10 22:04:37.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/include/linux/vmalloc.h 2009-05-10 23:48:29.000000000 +0200 +@@ -84,10 +84,6 @@ + unsigned long flags, void *caller); + extern struct vm_struct *__get_vm_area(unsigned long size, unsigned long flags, + unsigned long start, unsigned long end); +-extern struct vm_struct *__get_vm_area_caller(unsigned long size, +- unsigned long flags, +- unsigned long start, unsigned long end, +- void *caller); + extern struct vm_struct *get_vm_area_node(unsigned long size, + unsigned long flags, int node, + gfp_t gfp_mask); +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/include/linux/wait.h linux-2.6.29-rc3.owrt/include/linux/wait.h +--- linux-2.6.29.owrt/include/linux/wait.h 2009-05-10 22:04:37.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/include/linux/wait.h 2009-05-10 23:48:29.000000000 +0200 +@@ -132,8 +132,6 @@ + list_del(&old->task_list); + } + +-void __wake_up_common(wait_queue_head_t *q, unsigned int mode, +- int nr_exclusive, int sync, void *key); + void __wake_up(wait_queue_head_t *q, unsigned int mode, int nr, void *key); + extern void __wake_up_locked(wait_queue_head_t *q, unsigned int mode); + extern void __wake_up_sync(wait_queue_head_t *q, unsigned int mode, int nr); +@@ -335,19 +333,16 @@ + for (;;) { \ + prepare_to_wait_exclusive(&wq, &__wait, \ + TASK_INTERRUPTIBLE); \ +- if (condition) { \ +- finish_wait(&wq, &__wait); \ ++ if (condition) \ + break; \ +- } \ + if (!signal_pending(current)) { \ + schedule(); \ + continue; \ + } \ + ret = -ERESTARTSYS; \ +- abort_exclusive_wait(&wq, &__wait, \ +- TASK_INTERRUPTIBLE, NULL); \ + break; \ + } \ ++ finish_wait(&wq, &__wait); \ + } while (0) + + #define wait_event_interruptible_exclusive(wq, condition) \ +@@ -436,8 +431,6 @@ + void prepare_to_wait(wait_queue_head_t *q, wait_queue_t *wait, int state); + void prepare_to_wait_exclusive(wait_queue_head_t *q, wait_queue_t *wait, int state); + void finish_wait(wait_queue_head_t *q, wait_queue_t *wait); +-void abort_exclusive_wait(wait_queue_head_t *q, wait_queue_t *wait, +- unsigned int mode, void *key); + int autoremove_wake_function(wait_queue_t *wait, unsigned mode, int sync, void *key); + int wake_bit_function(wait_queue_t *wait, unsigned mode, int sync, void *key); + +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/include/media/v4l2-device.h linux-2.6.29-rc3.owrt/include/media/v4l2-device.h +--- linux-2.6.29.owrt/include/media/v4l2-device.h 2009-05-10 22:04:38.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/include/media/v4l2-device.h 2009-05-10 23:48:29.000000000 +0200 +@@ -94,16 +94,16 @@ + /* Call the specified callback for all subdevs matching grp_id (if 0, then + match them all). Ignore any errors. Note that you cannot add or delete + a subdev while walking the subdevs list. */ +-#define v4l2_device_call_all(dev, grpid, o, f, args...) \ ++#define v4l2_device_call_all(dev, grp_id, o, f, args...) \ + __v4l2_device_call_subdevs(dev, \ +- !(grpid) || sd->grp_id == (grpid), o, f , ##args) ++ !(grp_id) || sd->grp_id == (grp_id), o, f , ##args) + + /* Call the specified callback for all subdevs matching grp_id (if 0, then + match them all). If the callback returns an error other than 0 or + -ENOIOCTLCMD, then return with that error code. Note that you cannot + add or delete a subdev while walking the subdevs list. */ +-#define v4l2_device_call_until_err(dev, grpid, o, f, args...) \ ++#define v4l2_device_call_until_err(dev, grp_id, o, f, args...) \ + __v4l2_device_call_subdevs_until_err(dev, \ +- !(grpid) || sd->grp_id == (grpid), o, f , ##args) ++ !(grp_id) || sd->grp_id == (grp_id), o, f , ##args) + + #endif +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/include/media/videobuf-dma-sg.h linux-2.6.29-rc3.owrt/include/media/videobuf-dma-sg.h +--- linux-2.6.29.owrt/include/media/videobuf-dma-sg.h 2009-05-10 22:04:38.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/include/media/videobuf-dma-sg.h 2009-05-10 23:48:29.000000000 +0200 +@@ -49,7 +49,7 @@ + * does memory allocation too using vmalloc_32(). + * + * videobuf_dma_*() +- * see Documentation/PCI/PCI-DMA-mapping.txt, these functions to ++ * see Documentation/DMA-mapping.txt, these functions to + * basically the same. The map function does also build a + * scatterlist for the buffer (and unmap frees it ...) + * +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/include/mtd/inftl-user.h linux-2.6.29-rc3.owrt/include/mtd/inftl-user.h +--- linux-2.6.29.owrt/include/mtd/inftl-user.h 2009-05-10 22:04:38.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/include/mtd/inftl-user.h 2009-05-10 23:48:29.000000000 +0200 +@@ -6,8 +6,6 @@ + #ifndef __MTD_INFTL_USER_H__ + #define __MTD_INFTL_USER_H__ + +-#include <linux/types.h> +- + #define OSAK_VERSION 0x5120 + #define PERCENTUSED 98 + +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/include/mtd/ubi-user.h linux-2.6.29-rc3.owrt/include/mtd/ubi-user.h +--- linux-2.6.29.owrt/include/mtd/ubi-user.h 2009-05-10 22:04:38.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/include/mtd/ubi-user.h 2009-05-10 23:48:29.000000000 +0200 +@@ -40,37 +40,37 @@ + * UBI volume creation + * ~~~~~~~~~~~~~~~~~~~ + * +- * UBI volumes are created via the %UBI_IOCMKVOL ioctl command of UBI character ++ * UBI volumes are created via the %UBI_IOCMKVOL IOCTL command of UBI character + * device. A &struct ubi_mkvol_req object has to be properly filled and a +- * pointer to it has to be passed to the ioctl. ++ * pointer to it has to be passed to the IOCTL. + * + * UBI volume deletion + * ~~~~~~~~~~~~~~~~~~~ + * +- * To delete a volume, the %UBI_IOCRMVOL ioctl command of the UBI character ++ * To delete a volume, the %UBI_IOCRMVOL IOCTL command of the UBI character + * device should be used. A pointer to the 32-bit volume ID hast to be passed +- * to the ioctl. ++ * to the IOCTL. + * + * UBI volume re-size + * ~~~~~~~~~~~~~~~~~~ + * +- * To re-size a volume, the %UBI_IOCRSVOL ioctl command of the UBI character ++ * To re-size a volume, the %UBI_IOCRSVOL IOCTL command of the UBI character + * device should be used. A &struct ubi_rsvol_req object has to be properly +- * filled and a pointer to it has to be passed to the ioctl. ++ * filled and a pointer to it has to be passed to the IOCTL. + * + * UBI volumes re-name + * ~~~~~~~~~~~~~~~~~~~ + * + * To re-name several volumes atomically at one go, the %UBI_IOCRNVOL command + * of the UBI character device should be used. A &struct ubi_rnvol_req object +- * has to be properly filled and a pointer to it has to be passed to the ioctl. ++ * has to be properly filled and a pointer to it has to be passed to the IOCTL. + * + * UBI volume update + * ~~~~~~~~~~~~~~~~~ + * +- * Volume update should be done via the %UBI_IOCVOLUP ioctl command of the ++ * Volume update should be done via the %UBI_IOCVOLUP IOCTL command of the + * corresponding UBI volume character device. A pointer to a 64-bit update +- * size should be passed to the ioctl. After this, UBI expects user to write ++ * size should be passed to the IOCTL. After this, UBI expects user to write + * this number of bytes to the volume character device. The update is finished + * when the claimed number of bytes is passed. So, the volume update sequence + * is something like: +@@ -80,58 +80,14 @@ + * write(fd, buf, image_size); + * close(fd); + * +- * Logical eraseblock erase ++ * Atomic eraseblock change + * ~~~~~~~~~~~~~~~~~~~~~~~~ + * +- * To erase a logical eraseblock, the %UBI_IOCEBER ioctl command of the +- * corresponding UBI volume character device should be used. This command +- * unmaps the requested logical eraseblock, makes sure the corresponding +- * physical eraseblock is successfully erased, and returns. +- * +- * Atomic logical eraseblock change +- * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +- * +- * Atomic logical eraseblock change operation is called using the %UBI_IOCEBCH +- * ioctl command of the corresponding UBI volume character device. A pointer to +- * a &struct ubi_leb_change_req object has to be passed to the ioctl. Then the +- * user is expected to write the requested amount of bytes (similarly to what +- * should be done in case of the "volume update" ioctl). +- * +- * Logical eraseblock map +- * ~~~~~~~~~~~~~~~~~~~~~ +- * +- * To map a logical eraseblock to a physical eraseblock, the %UBI_IOCEBMAP +- * ioctl command should be used. A pointer to a &struct ubi_map_req object is +- * expected to be passed. The ioctl maps the requested logical eraseblock to +- * a physical eraseblock and returns. Only non-mapped logical eraseblocks can +- * be mapped. If the logical eraseblock specified in the request is already +- * mapped to a physical eraseblock, the ioctl fails and returns error. +- * +- * Logical eraseblock unmap +- * ~~~~~~~~~~~~~~~~~~~~~~~~ +- * +- * To unmap a logical eraseblock to a physical eraseblock, the %UBI_IOCEBUNMAP +- * ioctl command should be used. The ioctl unmaps the logical eraseblocks, +- * schedules corresponding physical eraseblock for erasure, and returns. Unlike +- * the "LEB erase" command, it does not wait for the physical eraseblock being +- * erased. Note, the side effect of this is that if an unclean reboot happens +- * after the unmap ioctl returns, you may find the LEB mapped again to the same +- * physical eraseblock after the UBI is run again. +- * +- * Check if logical eraseblock is mapped +- * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +- * +- * To check if a logical eraseblock is mapped to a physical eraseblock, the +- * %UBI_IOCEBISMAP ioctl command should be used. It returns %0 if the LEB is +- * not mapped, and %1 if it is mapped. +- * +- * Set an UBI volume property +- * ~~~~~~~~~~~~~~~~~~~~~~~~~ +- * +- * To set an UBI volume property the %UBI_IOCSETPROP ioctl command should be +- * used. A pointer to a &struct ubi_set_prop_req object is expected to be +- * passed. The object describes which property should be set, and to which value +- * it should be set. ++ * Atomic eraseblock change operation is done via the %UBI_IOCEBCH IOCTL ++ * command of the corresponding UBI volume character device. A pointer to ++ * &struct ubi_leb_change_req has to be passed to the IOCTL. Then the user is ++ * expected to write the requested amount of bytes. This is similar to the ++ * "volume update" IOCTL. + */ + + /* +@@ -145,7 +101,7 @@ + /* Maximum volume name length */ + #define UBI_MAX_VOLUME_NAME 127 + +-/* ioctl commands of UBI character devices */ ++/* IOCTL commands of UBI character devices */ + + #define UBI_IOC_MAGIC 'o' + +@@ -158,7 +114,7 @@ + /* Re-name volumes */ + #define UBI_IOCRNVOL _IOW(UBI_IOC_MAGIC, 3, struct ubi_rnvol_req) + +-/* ioctl commands of the UBI control character device */ ++/* IOCTL commands of the UBI control character device */ + + #define UBI_CTRL_IOC_MAGIC 'o' + +@@ -167,24 +123,16 @@ + /* Detach an MTD device */ + #define UBI_IOCDET _IOW(UBI_CTRL_IOC_MAGIC, 65, int32_t) + +-/* ioctl commands of UBI volume character devices */ ++/* IOCTL commands of UBI volume character devices */ + + #define UBI_VOL_IOC_MAGIC 'O' + + /* Start UBI volume update */ + #define UBI_IOCVOLUP _IOW(UBI_VOL_IOC_MAGIC, 0, int64_t) +-/* LEB erasure command, used for debugging, disabled by default */ ++/* An eraseblock erasure command, used for debugging, disabled by default */ + #define UBI_IOCEBER _IOW(UBI_VOL_IOC_MAGIC, 1, int32_t) +-/* Atomic LEB change command */ ++/* An atomic eraseblock change command */ + #define UBI_IOCEBCH _IOW(UBI_VOL_IOC_MAGIC, 2, int32_t) +-/* Map LEB command */ +-#define UBI_IOCEBMAP _IOW(UBI_VOL_IOC_MAGIC, 3, struct ubi_map_req) +-/* Unmap LEB command */ +-#define UBI_IOCEBUNMAP _IOW(UBI_VOL_IOC_MAGIC, 4, int32_t) +-/* Check if LEB is mapped command */ +-#define UBI_IOCEBISMAP _IOR(UBI_VOL_IOC_MAGIC, 5, int32_t) +-/* Set an UBI volume property */ +-#define UBI_IOCSETPROP _IOW(UBI_VOL_IOC_MAGIC, 6, struct ubi_set_prop_req) + + /* Maximum MTD device name length supported by UBI */ + #define MAX_UBI_MTD_NAME_LEN 127 +@@ -220,16 +168,6 @@ + UBI_STATIC_VOLUME = 4, + }; + +-/* +- * UBI set property ioctl constants +- * +- * @UBI_PROP_DIRECT_WRITE: allow / disallow user to directly write and +- * erase individual eraseblocks on dynamic volumes +- */ +-enum { +- UBI_PROP_DIRECT_WRITE = 1, +-}; +- + /** + * struct ubi_attach_req - attach MTD device request. + * @ubi_num: UBI device number to create +@@ -367,8 +305,8 @@ + } __attribute__ ((packed)); + + /** +- * struct ubi_leb_change_req - a data structure used in atomic LEB change +- * requests. ++ * struct ubi_leb_change_req - a data structure used in atomic logical ++ * eraseblock change requests. + * @lnum: logical eraseblock number to change + * @bytes: how many bytes will be written to the logical eraseblock + * @dtype: data type (%UBI_LONGTERM, %UBI_SHORTTERM, %UBI_UNKNOWN) +@@ -381,30 +319,4 @@ + int8_t padding[7]; + } __attribute__ ((packed)); + +-/** +- * struct ubi_map_req - a data structure used in map LEB requests. +- * @lnum: logical eraseblock number to unmap +- * @dtype: data type (%UBI_LONGTERM, %UBI_SHORTTERM, %UBI_UNKNOWN) +- * @padding: reserved for future, not used, has to be zeroed +- */ +-struct ubi_map_req { +- int32_t lnum; +- int8_t dtype; +- int8_t padding[3]; +-} __attribute__ ((packed)); +- +- +-/** +- * struct ubi_set_prop_req - a data structure used to set an ubi volume +- * property. +- * @property: property to set (%UBI_PROP_DIRECT_WRITE) +- * @padding: reserved for future, not used, has to be zeroed +- * @value: value to set +- */ +-struct ubi_set_prop_req { +- uint8_t property; +- uint8_t padding[7]; +- uint64_t value; +-} __attribute__ ((packed)); +- + #endif /* __UBI_USER_H__ */ +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/include/net/inet_hashtables.h linux-2.6.29-rc3.owrt/include/net/inet_hashtables.h +--- linux-2.6.29.owrt/include/net/inet_hashtables.h 2009-05-10 22:04:38.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/include/net/inet_hashtables.h 2009-05-10 23:48:29.000000000 +0200 +@@ -182,7 +182,7 @@ + size = 2048; + if (nr_pcpus >= 32) + size = 4096; +- if (sizeof(spinlock_t) != 0) { ++ if (sizeof(rwlock_t) != 0) { + #ifdef CONFIG_NUMA + if (size * sizeof(spinlock_t) > PAGE_SIZE) + hashinfo->ehash_locks = vmalloc(size * sizeof(spinlock_t)); +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/include/net/netfilter/nf_conntrack_core.h linux-2.6.29-rc3.owrt/include/net/netfilter/nf_conntrack_core.h +--- linux-2.6.29.owrt/include/net/netfilter/nf_conntrack_core.h 2009-05-10 22:04:38.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/include/net/netfilter/nf_conntrack_core.h 2009-05-10 23:48:29.000000000 +0200 +@@ -59,11 +59,10 @@ + struct nf_conn *ct = (struct nf_conn *)skb->nfct; + int ret = NF_ACCEPT; + +- if (ct && ct != &nf_conntrack_untracked) { ++ if (ct) { + if (!nf_ct_is_confirmed(ct) && !nf_ct_is_dying(ct)) + ret = __nf_conntrack_confirm(skb); +- if (likely(ret == NF_ACCEPT)) +- nf_ct_deliver_cached_events(ct); ++ nf_ct_deliver_cached_events(ct); + } + return ret; + } +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/include/net/net_namespace.h linux-2.6.29-rc3.owrt/include/net/net_namespace.h +--- linux-2.6.29.owrt/include/net/net_namespace.h 2009-05-10 22:04:38.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/include/net/net_namespace.h 2009-05-10 23:48:29.000000000 +0200 +@@ -109,6 +109,11 @@ + #ifdef CONFIG_NET_NS + extern void __put_net(struct net *net); + ++static inline int net_alive(struct net *net) ++{ ++ return net && atomic_read(&net->count); ++} ++ + static inline struct net *get_net(struct net *net) + { + atomic_inc(&net->count); +@@ -140,6 +145,11 @@ + } + #else + ++static inline int net_alive(struct net *net) ++{ ++ return 1; ++} ++ + static inline struct net *get_net(struct net *net) + { + return net; +@@ -224,23 +234,6 @@ + void (*exit)(struct net *net); + }; + +-/* +- * Use these carefully. If you implement a network device and it +- * needs per network namespace operations use device pernet operations, +- * otherwise use pernet subsys operations. +- * +- * This is critically important. Most of the network code cleanup +- * runs with the assumption that dev_remove_pack has been called so no +- * new packets will arrive during and after the cleanup functions have +- * been called. dev_remove_pack is not per namespace so instead the +- * guarantee of no more packets arriving in a network namespace is +- * provided by ensuring that all network devices and all sockets have +- * left the network namespace before the cleanup methods are called. +- * +- * For the longest time the ipv4 icmp code was registered as a pernet +- * device which caused kernel oops, and panics during network +- * namespace cleanup. So please don't get this wrong. +- */ + extern int register_pernet_subsys(struct pernet_operations *); + extern void unregister_pernet_subsys(struct pernet_operations *); + extern int register_pernet_gen_subsys(int *id, struct pernet_operations *); +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/include/net/sock.h linux-2.6.29-rc3.owrt/include/net/sock.h +--- linux-2.6.29.owrt/include/net/sock.h 2009-05-10 22:04:37.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/include/net/sock.h 2009-05-10 23:48:29.000000000 +0200 +@@ -860,6 +860,7 @@ + + static inline void sk_wmem_free_skb(struct sock *sk, struct sk_buff *skb) + { ++ skb_truesize_check(skb); + sock_set_flag(sk, SOCK_QUEUE_SHRUNK); + sk->sk_wmem_queued -= skb->truesize; + sk_mem_uncharge(sk, skb->truesize); +@@ -1307,7 +1308,7 @@ + + static inline gfp_t gfp_any(void) + { +- return in_softirq() ? GFP_ATOMIC : GFP_KERNEL; ++ return in_atomic() ? GFP_ATOMIC : GFP_KERNEL; + } + + static inline long sock_rcvtimeo(const struct sock *sk, int noblock) +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/include/scsi/fc/fc_fcoe.h linux-2.6.29-rc3.owrt/include/scsi/fc/fc_fcoe.h +--- linux-2.6.29.owrt/include/scsi/fc/fc_fcoe.h 2009-05-10 22:04:38.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/include/scsi/fc/fc_fcoe.h 2009-05-10 23:48:29.000000000 +0200 +@@ -31,6 +31,10 @@ + #define ETH_P_FCOE 0x8906 /* FCOE ether type */ + #endif + ++#ifndef ETH_P_8021Q ++#define ETH_P_8021Q 0x8100 ++#endif ++ + /* + * FC_FCOE_OUI hasn't been standardized yet. XXX TBD. + */ +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/include/scsi/fc/fc_fs.h linux-2.6.29-rc3.owrt/include/scsi/fc/fc_fs.h +--- linux-2.6.29.owrt/include/scsi/fc/fc_fs.h 2009-05-10 22:04:38.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/include/scsi/fc/fc_fs.h 2009-05-10 23:48:29.000000000 +0200 +@@ -337,9 +337,4 @@ + FC_RJT_VENDOR = 0xff, /* vendor specific reject */ + }; + +-/* default timeout values */ +- +-#define FC_DEF_E_D_TOV 2000UL +-#define FC_DEF_R_A_TOV 10000UL +- + #endif /* _FC_FS_H_ */ +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/include/scsi/libfc.h linux-2.6.29-rc3.owrt/include/scsi/libfc.h +--- linux-2.6.29.owrt/include/scsi/libfc.h 2009-05-10 22:04:38.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/include/scsi/libfc.h 2009-05-10 23:48:29.000000000 +0200 +@@ -68,6 +68,9 @@ + /* + * FC HBA status + */ ++#define FC_PAUSE (1 << 1) ++#define FC_LINK_UP (1 << 0) ++ + enum fc_lport_state { + LPORT_ST_NONE = 0, + LPORT_ST_FLOGI, +@@ -336,17 +339,31 @@ + + struct libfc_function_template { + ++ /** ++ * Mandatory Fields ++ * ++ * These handlers must be implemented by the LLD. ++ */ ++ + /* + * Interface to send a FC frame +- * +- * STATUS: REQUIRED + */ + int (*frame_send)(struct fc_lport *lp, struct fc_frame *fp); + +- /* +- * Interface to send ELS/CT frames ++ /** ++ * Optional Fields + * +- * STATUS: OPTIONAL ++ * The LLD may choose to implement any of the following handlers. ++ * If LLD doesn't specify hander and leaves its pointer NULL then ++ * the default libfc function will be used for that handler. ++ */ ++ ++ /** ++ * ELS/CT interfaces ++ */ ++ ++ /* ++ * elsct_send - sends ELS/CT frame + */ + struct fc_seq *(*elsct_send)(struct fc_lport *lport, + struct fc_rport *rport, +@@ -356,6 +373,9 @@ + struct fc_frame *fp, + void *arg), + void *arg, u32 timer_msec); ++ /** ++ * Exhance Manager interfaces ++ */ + + /* + * Send the FC frame payload using a new exchange and sequence. +@@ -387,8 +407,6 @@ + * timer_msec argument is specified. The timer is canceled when + * it fires or when the exchange is done. The exchange timeout handler + * is registered by EM layer. +- * +- * STATUS: OPTIONAL + */ + struct fc_seq *(*exch_seq_send)(struct fc_lport *lp, + struct fc_frame *fp, +@@ -400,18 +418,14 @@ + void *arg, unsigned int timer_msec); + + /* +- * Send a frame using an existing sequence and exchange. +- * +- * STATUS: OPTIONAL ++ * send a frame using existing sequence and exchange. + */ + int (*seq_send)(struct fc_lport *lp, struct fc_seq *sp, + struct fc_frame *fp); + + /* +- * Send an ELS response using infomation from a previous +- * exchange and sequence. +- * +- * STATUS: OPTIONAL ++ * Send ELS response using mainly infomation ++ * in exchange and sequence in EM layer. + */ + void (*seq_els_rsp_send)(struct fc_seq *sp, enum fc_els_cmd els_cmd, + struct fc_seq_els_data *els_data); +@@ -423,8 +437,6 @@ + * A timer_msec can be specified for abort timeout, if non-zero + * timer_msec value is specified then exchange resp handler + * will be called with timeout error if no response to abort. +- * +- * STATUS: OPTIONAL + */ + int (*seq_exch_abort)(const struct fc_seq *req_sp, + unsigned int timer_msec); +@@ -432,8 +444,6 @@ + /* + * Indicate that an exchange/sequence tuple is complete and the memory + * allocated for the related objects may be freed. +- * +- * STATUS: OPTIONAL + */ + void (*exch_done)(struct fc_seq *sp); + +@@ -441,8 +451,6 @@ + * Assigns a EM and a free XID for an new exchange and then + * allocates a new exchange and sequence pair. + * The fp can be used to determine free XID. +- * +- * STATUS: OPTIONAL + */ + struct fc_exch *(*exch_get)(struct fc_lport *lp, struct fc_frame *fp); + +@@ -450,16 +458,12 @@ + * Release previously assigned XID by exch_get API. + * The LLD may implement this if XID is assigned by LLD + * in exch_get(). +- * +- * STATUS: OPTIONAL + */ + void (*exch_put)(struct fc_lport *lp, struct fc_exch_mgr *mp, + u16 ex_id); + + /* + * Start a new sequence on the same exchange/sequence tuple. +- * +- * STATUS: OPTIONAL + */ + struct fc_seq *(*seq_start_next)(struct fc_seq *sp); + +@@ -467,38 +471,26 @@ + * Reset an exchange manager, completing all sequences and exchanges. + * If s_id is non-zero, reset only exchanges originating from that FID. + * If d_id is non-zero, reset only exchanges sending to that FID. +- * +- * STATUS: OPTIONAL + */ +- void (*exch_mgr_reset)(struct fc_lport *, ++ void (*exch_mgr_reset)(struct fc_exch_mgr *, + u32 s_id, u32 d_id); + +- /* +- * Flush the rport work queue. Generally used before shutdown. +- * +- * STATUS: OPTIONAL +- */ + void (*rport_flush_queue)(void); ++ /** ++ * Local Port interfaces ++ */ + + /* +- * Receive a frame for a local port. +- * +- * STATUS: OPTIONAL ++ * Receive a frame to a local port. + */ + void (*lport_recv)(struct fc_lport *lp, struct fc_seq *sp, + struct fc_frame *fp); + +- /* +- * Reset the local port. +- * +- * STATUS: OPTIONAL +- */ + int (*lport_reset)(struct fc_lport *); + +- /* +- * Create a remote port ++ /** ++ * Remote Port interfaces + */ +- struct fc_rport *(*rport_create)(struct fc_disc_port *); + + /* + * Initiates the RP state machine. It is called from the LP module. +@@ -508,72 +500,57 @@ + * - PLOGI + * - PRLI + * - RTV +- * +- * STATUS: OPTIONAL + */ + int (*rport_login)(struct fc_rport *rport); + + /* + * Logoff, and remove the rport from the transport if + * it had been added. This will send a LOGO to the target. +- * +- * STATUS: OPTIONAL + */ + int (*rport_logoff)(struct fc_rport *rport); + + /* + * Recieve a request from a remote port. +- * +- * STATUS: OPTIONAL + */ + void (*rport_recv_req)(struct fc_seq *, struct fc_frame *, + struct fc_rport *); + +- /* +- * lookup an rport by it's port ID. +- * +- * STATUS: OPTIONAL +- */ + struct fc_rport *(*rport_lookup)(const struct fc_lport *, u32); + ++ /** ++ * FCP interfaces ++ */ ++ + /* + * Send a fcp cmd from fsp pkt. + * Called with the SCSI host lock unlocked and irqs disabled. + * + * The resp handler is called when FCP_RSP received. + * +- * STATUS: OPTIONAL + */ + int (*fcp_cmd_send)(struct fc_lport *lp, struct fc_fcp_pkt *fsp, + void (*resp)(struct fc_seq *, struct fc_frame *fp, + void *arg)); + + /* +- * Cleanup the FCP layer, used durring link down and reset +- * +- * STATUS: OPTIONAL ++ * Used at least durring linkdown and reset + */ + void (*fcp_cleanup)(struct fc_lport *lp); + + /* + * Abort all I/O on a local port +- * +- * STATUS: OPTIONAL + */ + void (*fcp_abort_io)(struct fc_lport *lp); + +- /* +- * Receive a request for the discovery layer. +- * +- * STATUS: OPTIONAL ++ /** ++ * Discovery interfaces + */ ++ + void (*disc_recv_req)(struct fc_seq *, + struct fc_frame *, struct fc_lport *); + + /* + * Start discovery for a local port. +- * +- * STATUS: OPTIONAL + */ + void (*disc_start)(void (*disc_callback)(struct fc_lport *, + enum fc_disc_event), +@@ -582,8 +559,6 @@ + /* + * Stop discovery for a given lport. This will remove + * all discovered rports +- * +- * STATUS: OPTIONAL + */ + void (*disc_stop) (struct fc_lport *); + +@@ -591,8 +566,6 @@ + * Stop discovery for a given lport. This will block + * until all discovered rports are deleted from the + * FC transport class +- * +- * STATUS: OPTIONAL + */ + void (*disc_stop_final) (struct fc_lport *); + }; +@@ -630,8 +603,7 @@ + + /* Operational Information */ + struct libfc_function_template tt; +- u8 link_up; +- u8 qfull; ++ u16 link_status; + enum fc_lport_state state; + unsigned long boot_time; + +@@ -665,7 +637,7 @@ + struct delayed_work disc_work; + }; + +-/* ++/** + * FC_LPORT HELPER FUNCTIONS + *****************************/ + static inline void *lport_priv(const struct fc_lport *lp) +@@ -697,7 +669,7 @@ + } + + +-/* ++/** + * LOCAL PORT LAYER + *****************************/ + int fc_lport_init(struct fc_lport *lp); +@@ -732,6 +704,12 @@ + void fc_linkdown(struct fc_lport *); + + /* ++ * Pause and unpause traffic. ++ */ ++void fc_pause(struct fc_lport *); ++void fc_unpause(struct fc_lport *); ++ ++/* + * Configure the local port. + */ + int fc_lport_config(struct fc_lport *); +@@ -747,19 +725,19 @@ + int fc_set_mfs(struct fc_lport *lp, u32 mfs); + + +-/* ++/** + * REMOTE PORT LAYER + *****************************/ + int fc_rport_init(struct fc_lport *lp); + void fc_rport_terminate_io(struct fc_rport *rp); + +-/* ++/** + * DISCOVERY LAYER + *****************************/ + int fc_disc_init(struct fc_lport *lp); + + +-/* ++/** + * SCSI LAYER + *****************************/ + /* +@@ -820,7 +798,7 @@ + */ + void fc_fcp_destroy(struct fc_lport *); + +-/* ++/** + * ELS/CT interface + *****************************/ + /* +@@ -829,7 +807,7 @@ + int fc_elsct_init(struct fc_lport *lp); + + +-/* ++/** + * EXCHANGE MANAGER LAYER + *****************************/ + /* +@@ -938,7 +916,7 @@ + * If s_id is non-zero, reset only exchanges originating from that FID. + * If d_id is non-zero, reset only exchanges sending to that FID. + */ +-void fc_exch_mgr_reset(struct fc_lport *, u32 s_id, u32 d_id); ++void fc_exch_mgr_reset(struct fc_exch_mgr *, u32 s_id, u32 d_id); + + /* + * Functions for fc_functions_template +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/include/scsi/libfcoe.h linux-2.6.29-rc3.owrt/include/scsi/libfcoe.h +--- linux-2.6.29.owrt/include/scsi/libfcoe.h 2009-05-10 22:04:38.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/include/scsi/libfcoe.h 2009-05-10 23:48:29.000000000 +0200 +@@ -46,7 +46,6 @@ + struct net_device *phys_dev; /* device with ethtool_ops */ + struct packet_type fcoe_packet_type; + struct sk_buff_head fcoe_pending_queue; +- u8 fcoe_pending_queue_active; + + u8 dest_addr[ETH_ALEN]; + u8 ctl_src_addr[ETH_ALEN]; +@@ -59,10 +58,16 @@ + u8 address_mode; + }; + ++static inline struct fcoe_softc *fcoe_softc( ++ const struct fc_lport *lp) ++{ ++ return (struct fcoe_softc *)lport_priv(lp); ++} ++ + static inline struct net_device *fcoe_netdev( + const struct fc_lport *lp) + { +- return ((struct fcoe_softc *)lport_priv(lp))->real_dev; ++ return fcoe_softc(lp)->real_dev; + } + + static inline struct fcoe_hdr *skb_fcoe_header(const struct sk_buff *skb) +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/include/sound/hdsp.h linux-2.6.29-rc3.owrt/include/sound/hdsp.h +--- linux-2.6.29.owrt/include/sound/hdsp.h 2009-05-10 22:04:38.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/include/sound/hdsp.h 2009-05-10 23:48:29.000000000 +0200 +@@ -19,8 +19,6 @@ + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + */ + +-#include <linux/types.h> +- + #define HDSP_MATRIX_MIXER_SIZE 2048 + + enum HDSP_IO_Type { +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/include/video/aty128.h linux-2.6.29-rc3.owrt/include/video/aty128.h +--- linux-2.6.29.owrt/include/video/aty128.h 2009-05-10 22:04:37.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/include/video/aty128.h 2009-05-10 23:48:29.000000000 +0200 +@@ -21,9 +21,9 @@ + #define I2C_CNTL_1 0x0094 + #define PALETTE_INDEX 0x00b0 + #define PALETTE_DATA 0x00b4 +-#define CNFG_CNTL 0x00e0 ++#define CONFIG_CNTL 0x00e0 + #define GEN_RESET_CNTL 0x00f0 +-#define CNFG_MEMSIZE 0x00f8 ++#define CONFIG_MEMSIZE 0x00f8 + #define MEM_CNTL 0x0140 + #define MEM_POWER_MISC 0x015c + #define AGP_BASE 0x0170 +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/include/video/mach64.h linux-2.6.29-rc3.owrt/include/video/mach64.h +--- linux-2.6.29.owrt/include/video/mach64.h 2009-05-10 22:04:37.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/include/video/mach64.h 2009-05-10 23:48:29.000000000 +0200 +@@ -103,7 +103,7 @@ + #define CUR_HORZ_VERT_OFF 0x0070 /* Dword offset 0_1C */ + #define CUR2_HORZ_VERT_OFF 0x0070 /* Dword offset 0_1C */ + +-#define CNFG_PANEL_LG 0x0074 /* Dword offset 0_1D (LG) */ ++#define CONFIG_PANEL_LG 0x0074 /* Dword offset 0_1D (LG) */ + + /* General I/O Control */ + #define GP_IO 0x0078 /* Dword offset 0_1E */ +@@ -146,8 +146,8 @@ + #define CLOCK_SEL_CNTL 0x0090 /* Dword offset 0_24 */ + + /* Configuration */ +-#define CNFG_STAT1 0x0094 /* Dword offset 0_25 */ +-#define CNFG_STAT2 0x0098 /* Dword offset 0_26 */ ++#define CONFIG_STAT1 0x0094 /* Dword offset 0_25 */ ++#define CONFIG_STAT2 0x0098 /* Dword offset 0_26 */ + + /* Bus Control */ + #define BUS_CNTL 0x00A0 /* Dword offset 0_28 */ +@@ -190,9 +190,9 @@ + #define POWER_MANAGEMENT_LG 0x00D8 /* Dword offset 0_36 (LG) */ + + /* Configuration */ +-#define CNFG_CNTL 0x00DC /* Dword offset 0_37 (CT, ET, VT) */ +-#define CNFG_CHIP_ID 0x00E0 /* Dword offset 0_38 */ +-#define CNFG_STAT0 0x00E4 /* Dword offset 0_39 */ ++#define CONFIG_CNTL 0x00DC /* Dword offset 0_37 (CT, ET, VT) */ ++#define CONFIG_CHIP_ID 0x00E0 /* Dword offset 0_38 */ ++#define CONFIG_STAT0 0x00E4 /* Dword offset 0_39 */ + + /* Test and Debug */ + #define CRC_SIG 0x00E8 /* Dword offset 0_3A */ +@@ -851,17 +851,17 @@ + #define PLL_YCLK_CNTL 0x29 + #define PM_DYN_CLK_CNTL 0x2A + +-/* CNFG_CNTL register constants */ ++/* CONFIG_CNTL register constants */ + #define APERTURE_4M_ENABLE 1 + #define APERTURE_8M_ENABLE 2 + #define VGA_APERTURE_ENABLE 4 + +-/* CNFG_STAT0 register constants (GX, CX) */ ++/* CONFIG_STAT0 register constants (GX, CX) */ + #define CFG_BUS_TYPE 0x00000007 + #define CFG_MEM_TYPE 0x00000038 + #define CFG_INIT_DAC_TYPE 0x00000e00 + +-/* CNFG_STAT0 register constants (CT, ET, VT) */ ++/* CONFIG_STAT0 register constants (CT, ET, VT) */ + #define CFG_MEM_TYPE_xT 0x00000007 + + #define ISA 0 +@@ -942,7 +942,7 @@ + #define PCI_ATI_VENDOR_ID 0x1002 + + +-/* CNFG_CHIP_ID register constants */ ++/* CONFIG_CHIP_ID register constants */ + #define CFG_CHIP_TYPE 0x0000FFFF + #define CFG_CHIP_CLASS 0x00FF0000 + #define CFG_CHIP_REV 0xFF000000 +@@ -951,7 +951,7 @@ + #define CFG_CHIP_MINOR 0xC0000000 + + +-/* Chip IDs read from CNFG_CHIP_ID */ ++/* Chip IDs read from CONFIG_CHIP_ID */ + + /* mach64GX family */ + #define GX_CHIP_ID 0xD7 /* mach64GX (ATI888GX00) */ +@@ -1254,7 +1254,7 @@ + #define CRTC2_DISPLAY_DIS 0x00000400 + + /* LCD register indices */ +-#define CNFG_PANEL 0x00 ++#define CONFIG_PANEL 0x00 + #define LCD_GEN_CNTL 0x01 + #define DSTN_CONTROL 0x02 + #define HFB_PITCH_ADDR 0x03 +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/include/video/radeon.h linux-2.6.29-rc3.owrt/include/video/radeon.h +--- linux-2.6.29.owrt/include/video/radeon.h 2009-05-10 22:04:37.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/include/video/radeon.h 2009-05-10 23:48:29.000000000 +0200 +@@ -11,13 +11,13 @@ + #define HI_STAT 0x004C + #define BUS_CNTL1 0x0034 + #define I2C_CNTL_1 0x0094 +-#define CNFG_CNTL 0x00E0 +-#define CNFG_MEMSIZE 0x00F8 +-#define CNFG_APER_0_BASE 0x0100 +-#define CNFG_APER_1_BASE 0x0104 +-#define CNFG_APER_SIZE 0x0108 +-#define CNFG_REG_1_BASE 0x010C +-#define CNFG_REG_APER_SIZE 0x0110 ++#define CONFIG_CNTL 0x00E0 ++#define CONFIG_MEMSIZE 0x00F8 ++#define CONFIG_APER_0_BASE 0x0100 ++#define CONFIG_APER_1_BASE 0x0104 ++#define CONFIG_APER_SIZE 0x0108 ++#define CONFIG_REG_1_BASE 0x010C ++#define CONFIG_REG_APER_SIZE 0x0110 + #define PAD_AGPINPUT_DELAY 0x0164 + #define PAD_CTLR_STRENGTH 0x0168 + #define PAD_CTLR_UPDATE 0x016C +@@ -509,7 +509,7 @@ + /* CLOCK_CNTL_INDEX bit constants */ + #define PLL_WR_EN 0x00000080 + +-/* CNFG_CNTL bit constants */ ++/* CONFIG_CNTL bit constants */ + #define CFG_VGA_RAM_EN 0x00000100 + #define CFG_ATI_REV_ID_MASK (0xf << 16) + #define CFG_ATI_REV_A11 (0 << 16) +@@ -980,7 +980,7 @@ + + /* masks */ + +-#define CNFG_MEMSIZE_MASK 0x1f000000 ++#define CONFIG_MEMSIZE_MASK 0x1f000000 + #define MEM_CFG_TYPE 0x40000000 + #define DST_OFFSET_MASK 0x003fffff + #define DST_PITCH_MASK 0x3fc00000 +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/include/video/sisfb.h linux-2.6.29-rc3.owrt/include/video/sisfb.h +--- linux-2.6.29.owrt/include/video/sisfb.h 2009-05-10 22:04:37.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/include/video/sisfb.h 2009-05-10 23:48:29.000000000 +0200 +@@ -21,8 +21,8 @@ + #ifndef _LINUX_SISFB_H_ + #define _LINUX_SISFB_H_ + +-#include <linux/types.h> + #include <asm/ioctl.h> ++#include <asm/types.h> + + /**********************************************/ + /* PUBLIC */ +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/include/video/uvesafb.h linux-2.6.29-rc3.owrt/include/video/uvesafb.h +--- linux-2.6.29.owrt/include/video/uvesafb.h 2009-05-10 22:04:37.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/include/video/uvesafb.h 2009-05-10 23:48:29.000000000 +0200 +@@ -1,8 +1,6 @@ + #ifndef _UVESAFB_H + #define _UVESAFB_H + +-#include <linux/types.h> +- + struct v86_regs { + __u32 ebx; + __u32 ecx; +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/init/do_mounts.c linux-2.6.29-rc3.owrt/init/do_mounts.c +--- linux-2.6.29.owrt/init/do_mounts.c 2009-05-10 22:04:39.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/init/do_mounts.c 2009-05-10 23:48:29.000000000 +0200 +@@ -370,14 +370,10 @@ + ssleep(root_delay); + } + +- /* +- * wait for the known devices to complete their probing +- * +- * Note: this is a potential source of long boot delays. +- * For example, it is not atypical to wait 5 seconds here +- * for the touchpad of a laptop to initialize. +- */ +- wait_for_device_probe(); ++ /* wait for the known devices to complete their probing */ ++ while (driver_probe_done() != 0) ++ msleep(100); ++ async_synchronize_full(); + + md_run_setup(); + +@@ -403,7 +399,6 @@ + while (driver_probe_done() != 0 || + (ROOT_DEV = name_to_dev_t(saved_root_name)) == 0) + msleep(100); +- async_synchronize_full(); + } + + is_floppy = MAJOR(ROOT_DEV) == FLOPPY_MAJOR; +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/init/do_mounts_md.c linux-2.6.29-rc3.owrt/init/do_mounts_md.c +--- linux-2.6.29.owrt/init/do_mounts_md.c 2009-05-10 22:04:39.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/init/do_mounts_md.c 2009-05-10 23:48:29.000000000 +0200 +@@ -281,9 +281,8 @@ + */ + printk(KERN_INFO "md: Waiting for all devices to be available before autodetect\n"); + printk(KERN_INFO "md: If you don't use raid, use raid=noautodetect\n"); +- +- wait_for_device_probe(); +- ++ while (driver_probe_done() < 0) ++ msleep(100); + fd = sys_open("/dev/md0", 0, 0); + if (fd >= 0) { + sys_ioctl(fd, RAID_AUTORUN, raid_autopart); +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/init/Kconfig linux-2.6.29-rc3.owrt/init/Kconfig +--- linux-2.6.29.owrt/init/Kconfig 2009-05-10 22:04:39.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/init/Kconfig 2009-05-10 23:48:29.000000000 +0200 +@@ -675,9 +675,6 @@ + config SYSCTL + bool + +-config ANON_INODES +- bool +- + menuconfig EMBEDDED + bool "Configure standard kernel features (for small systems)" + help +@@ -783,6 +780,18 @@ + This option allows to disable the internal PC-Speaker + support, saving some memory. + ++config COMPAT_BRK ++ bool "Disable heap randomization" ++ default y ++ help ++ Randomizing heap placement makes heap exploits harder, but it ++ also breaks ancient binaries (including anything libc5 based). ++ This option changes the bootup default to heap randomization ++ disabled, and can be overriden runtime by setting ++ /proc/sys/kernel/randomize_va_space to 2. ++ ++ On non-ancient distros (post-2000 ones) N is usually a safe choice. ++ + config BASE_FULL + default y + bool "Enable full-sized data structures for core" if EMBEDDED +@@ -800,6 +809,9 @@ + support for "fast userspace mutexes". The resulting kernel may not + run glibc-based applications correctly. + ++config ANON_INODES ++ bool ++ + config EPOLL + bool "Enable eventpoll support" if EMBEDDED + default y +@@ -885,18 +897,6 @@ + SLUB sysfs support. /sys/slab will not exist and there will be + no support for cache validation etc. + +-config COMPAT_BRK +- bool "Disable heap randomization" +- default y +- help +- Randomizing heap placement makes heap exploits harder, but it +- also breaks ancient binaries (including anything libc5 based). +- This option changes the bootup default to heap randomization +- disabled, and can be overriden runtime by setting +- /proc/sys/kernel/randomize_va_space to 2. +- +- On non-ancient distros (post-2000 ones) N is usually a safe choice. +- + choice + prompt "Choose SLAB allocator" + default SLUB +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/init/main.c linux-2.6.29-rc3.owrt/init/main.c +--- linux-2.6.29.owrt/init/main.c 2009-05-10 22:04:39.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/init/main.c 2009-05-10 23:48:29.000000000 +0200 +@@ -97,7 +97,7 @@ + extern void tc_init(void); + #endif + +-enum system_states system_state __read_mostly; ++enum system_states system_state; + EXPORT_SYMBOL(system_state); + + /* +@@ -463,7 +463,6 @@ + * at least once to get things moving: + */ + init_idle_bootup_task(current); +- rcu_scheduler_starting(); + preempt_enable_no_resched(); + schedule(); + preempt_disable(); +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/ipc/shm.c linux-2.6.29-rc3.owrt/ipc/shm.c +--- linux-2.6.29.owrt/ipc/shm.c 2009-05-10 22:04:39.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/ipc/shm.c 2009-05-10 23:48:29.000000000 +0200 +@@ -340,7 +340,6 @@ + struct file * file; + char name[13]; + int id; +- int acctflag = 0; + + if (size < SHMMIN || size > ns->shm_ctlmax) + return -EINVAL; +@@ -365,19 +364,18 @@ + + sprintf (name, "SYSV%08x", key); + if (shmflg & SHM_HUGETLB) { +- /* hugetlb_file_setup applies strict accounting */ +- if (shmflg & SHM_NORESERVE) +- acctflag = VM_NORESERVE; +- file = hugetlb_file_setup(name, size, acctflag); ++ /* hugetlb_file_setup takes care of mlock user accounting */ ++ file = hugetlb_file_setup(name, size); + shp->mlock_user = current_user(); + } else { ++ int acctflag = VM_ACCOUNT; + /* + * Do not allow no accounting for OVERCOMMIT_NEVER, even + * if it's asked for. + */ + if ((shmflg & SHM_NORESERVE) && + sysctl_overcommit_memory != OVERCOMMIT_NEVER) +- acctflag = VM_NORESERVE; ++ acctflag = 0; + file = shmem_file_setup(name, size, acctflag); + } + error = PTR_ERR(file); +@@ -567,15 +565,11 @@ + struct hstate *h = hstate_file(shp->shm_file); + *rss += pages_per_huge_page(h) * mapping->nrpages; + } else { +-#ifdef CONFIG_SHMEM + struct shmem_inode_info *info = SHMEM_I(inode); + spin_lock(&info->lock); + *rss += inode->i_mapping->nrpages; + *swp += info->swapped; + spin_unlock(&info->lock); +-#else +- *rss += inode->i_mapping->nrpages; +-#endif + } + + total++; +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/kernel/async.c linux-2.6.29-rc3.owrt/kernel/async.c +--- linux-2.6.29.owrt/kernel/async.c 2009-05-10 22:04:41.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/kernel/async.c 2009-05-10 23:48:29.000000000 +0200 +@@ -54,7 +54,6 @@ + #include <linux/sched.h> + #include <linux/init.h> + #include <linux/kthread.h> +-#include <linux/delay.h> + #include <asm/atomic.h> + + static async_cookie_t next_cookie = 1; +@@ -133,23 +132,21 @@ + entry = list_first_entry(&async_pending, struct async_entry, list); + + /* 2) move it to the running queue */ +- list_move_tail(&entry->list, entry->running); ++ list_del(&entry->list); ++ list_add_tail(&entry->list, &async_running); + spin_unlock_irqrestore(&async_lock, flags); + + /* 3) run it (and print duration)*/ + if (initcall_debug && system_state == SYSTEM_BOOTING) { +- printk("calling %lli_%pF @ %i\n", (long long)entry->cookie, +- entry->func, task_pid_nr(current)); ++ printk("calling %lli_%pF @ %i\n", entry->cookie, entry->func, task_pid_nr(current)); + calltime = ktime_get(); + } + entry->func(entry->data, entry->cookie); + if (initcall_debug && system_state == SYSTEM_BOOTING) { + rettime = ktime_get(); + delta = ktime_sub(rettime, calltime); +- printk("initcall %lli_%pF returned 0 after %lld usecs\n", +- (long long)entry->cookie, +- entry->func, +- (long long)ktime_to_ns(delta) >> 10); ++ printk("initcall %lli_%pF returned 0 after %lld usecs\n", entry->cookie, ++ entry->func, ktime_to_ns(delta) >> 10); + } + + /* 4) remove it from the running queue */ +@@ -208,44 +205,18 @@ + return newcookie; + } + +-/** +- * async_schedule - schedule a function for asynchronous execution +- * @ptr: function to execute asynchronously +- * @data: data pointer to pass to the function +- * +- * Returns an async_cookie_t that may be used for checkpointing later. +- * Note: This function may be called from atomic or non-atomic contexts. +- */ + async_cookie_t async_schedule(async_func_ptr *ptr, void *data) + { +- return __async_schedule(ptr, data, &async_running); ++ return __async_schedule(ptr, data, &async_pending); + } + EXPORT_SYMBOL_GPL(async_schedule); + +-/** +- * async_schedule_domain - schedule a function for asynchronous execution within a certain domain +- * @ptr: function to execute asynchronously +- * @data: data pointer to pass to the function +- * @running: running list for the domain +- * +- * Returns an async_cookie_t that may be used for checkpointing later. +- * @running may be used in the async_synchronize_*_domain() functions +- * to wait within a certain synchronization domain rather than globally. +- * A synchronization domain is specified via the running queue @running to use. +- * Note: This function may be called from atomic or non-atomic contexts. +- */ +-async_cookie_t async_schedule_domain(async_func_ptr *ptr, void *data, +- struct list_head *running) ++async_cookie_t async_schedule_special(async_func_ptr *ptr, void *data, struct list_head *running) + { + return __async_schedule(ptr, data, running); + } +-EXPORT_SYMBOL_GPL(async_schedule_domain); ++EXPORT_SYMBOL_GPL(async_schedule_special); + +-/** +- * async_synchronize_full - synchronize all asynchronous function calls +- * +- * This function waits until all asynchronous function calls have been done. +- */ + void async_synchronize_full(void) + { + do { +@@ -254,30 +225,13 @@ + } + EXPORT_SYMBOL_GPL(async_synchronize_full); + +-/** +- * async_synchronize_full_domain - synchronize all asynchronous function within a certain domain +- * @list: running list to synchronize on +- * +- * This function waits until all asynchronous function calls for the +- * synchronization domain specified by the running list @list have been done. +- */ +-void async_synchronize_full_domain(struct list_head *list) ++void async_synchronize_full_special(struct list_head *list) + { +- async_synchronize_cookie_domain(next_cookie, list); ++ async_synchronize_cookie_special(next_cookie, list); + } +-EXPORT_SYMBOL_GPL(async_synchronize_full_domain); ++EXPORT_SYMBOL_GPL(async_synchronize_full_special); + +-/** +- * async_synchronize_cookie_domain - synchronize asynchronous function calls within a certain domain with cookie checkpointing +- * @cookie: async_cookie_t to use as checkpoint +- * @running: running list to synchronize on +- * +- * This function waits until all asynchronous function calls for the +- * synchronization domain specified by the running list @list submitted +- * prior to @cookie have been done. +- */ +-void async_synchronize_cookie_domain(async_cookie_t cookie, +- struct list_head *running) ++void async_synchronize_cookie_special(async_cookie_t cookie, struct list_head *running) + { + ktime_t starttime, delta, endtime; + +@@ -293,22 +247,14 @@ + delta = ktime_sub(endtime, starttime); + + printk("async_continuing @ %i after %lli usec\n", +- task_pid_nr(current), +- (long long)ktime_to_ns(delta) >> 10); ++ task_pid_nr(current), ktime_to_ns(delta) >> 10); + } + } +-EXPORT_SYMBOL_GPL(async_synchronize_cookie_domain); ++EXPORT_SYMBOL_GPL(async_synchronize_cookie_special); + +-/** +- * async_synchronize_cookie - synchronize asynchronous function calls with cookie checkpointing +- * @cookie: async_cookie_t to use as checkpoint +- * +- * This function waits until all asynchronous function calls prior to @cookie +- * have been done. +- */ + void async_synchronize_cookie(async_cookie_t cookie) + { +- async_synchronize_cookie_domain(cookie, &async_running); ++ async_synchronize_cookie_special(cookie, &async_running); + } + EXPORT_SYMBOL_GPL(async_synchronize_cookie); + +@@ -369,11 +315,7 @@ + ec = atomic_read(&entry_count); + + while (tc < ec && tc < MAX_THREADS) { +- if (IS_ERR(kthread_run(async_thread, NULL, "async/%i", +- tc))) { +- msleep(100); +- continue; +- } ++ kthread_run(async_thread, NULL, "async/%i", tc); + atomic_inc(&thread_count); + tc++; + } +@@ -388,9 +330,7 @@ + static int __init async_init(void) + { + if (async_enabled) +- if (IS_ERR(kthread_run(async_manager_thread, NULL, +- "async/mgr"))) +- async_enabled = 0; ++ kthread_run(async_manager_thread, NULL, "async/mgr"); + return 0; + } + +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/kernel/cgroup.c linux-2.6.29-rc3.owrt/kernel/cgroup.c +--- linux-2.6.29.owrt/kernel/cgroup.c 2009-05-10 22:04:41.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/kernel/cgroup.c 2009-05-10 23:48:29.000000000 +0200 +@@ -1115,15 +1115,13 @@ + } + write_unlock(&css_set_lock); + +- if (!list_empty(&root->root_list)) { +- list_del(&root->root_list); +- root_count--; +- } ++ list_del(&root->root_list); ++ root_count--; + + mutex_unlock(&cgroup_mutex); + +- kill_litter_super(sb); + kfree(root); ++ kill_litter_super(sb); + } + + static struct file_system_type cgroup_fs_type = { +@@ -2351,7 +2349,7 @@ + for (i = 0; i < CGROUP_SUBSYS_COUNT; i++) { + struct cgroup_subsys *ss = subsys[i]; + if (ss->root == root) +- mutex_lock(&ss->hierarchy_mutex); ++ mutex_lock_nested(&ss->hierarchy_mutex, i); + } + } + +@@ -2436,9 +2434,7 @@ + + err_remove: + +- cgroup_lock_hierarchy(root); + list_del(&cgrp->sibling); +- cgroup_unlock_hierarchy(root); + root->number_of_cgroups--; + + err_destroy: +@@ -2511,7 +2507,7 @@ + for_each_subsys(cgrp->root, ss) { + struct cgroup_subsys_state *css = cgrp->subsys[ss->subsys_id]; + int refcnt; +- while (1) { ++ do { + /* We can only remove a CSS with a refcnt==1 */ + refcnt = atomic_read(&css->refcnt); + if (refcnt > 1) { +@@ -2525,10 +2521,7 @@ + * css_tryget() to spin until we set the + * CSS_REMOVED bits or abort + */ +- if (atomic_cmpxchg(&css->refcnt, refcnt, 0) == refcnt) +- break; +- cpu_relax(); +- } ++ } while (atomic_cmpxchg(&css->refcnt, refcnt, 0) != refcnt); + } + done: + for_each_subsys(cgrp->root, ss) { +@@ -2637,7 +2630,6 @@ + BUG_ON(!list_empty(&init_task.tasks)); + + mutex_init(&ss->hierarchy_mutex); +- lockdep_set_class(&ss->hierarchy_mutex, &ss->subsys_key); + ss->active = 1; + } + +@@ -2999,21 +2991,20 @@ + mutex_unlock(&cgroup_mutex); + return 0; + } ++ task_lock(tsk); ++ cg = tsk->cgroups; ++ parent = task_cgroup(tsk, subsys->subsys_id); + + /* Pin the hierarchy */ +- if (!atomic_inc_not_zero(&root->sb->s_active)) { ++ if (!atomic_inc_not_zero(&parent->root->sb->s_active)) { + /* We race with the final deactivate_super() */ + mutex_unlock(&cgroup_mutex); + return 0; + } + + /* Keep the cgroup alive */ +- task_lock(tsk); +- parent = task_cgroup(tsk, subsys->subsys_id); +- cg = tsk->cgroups; + get_css_set(cg); + task_unlock(tsk); +- + mutex_unlock(&cgroup_mutex); + + /* Now do the VFS work to create a cgroup */ +@@ -3052,7 +3043,7 @@ + mutex_unlock(&inode->i_mutex); + put_css_set(cg); + +- deactivate_super(root->sb); ++ deactivate_super(parent->root->sb); + /* The cgroup is still accessible in the VFS, but + * we're not going to try to rmdir() it at this + * point. */ +@@ -3078,7 +3069,7 @@ + mutex_lock(&cgroup_mutex); + put_css_set(cg); + mutex_unlock(&cgroup_mutex); +- deactivate_super(root->sb); ++ deactivate_super(parent->root->sb); + return ret; + } + +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/kernel/cpuset.c linux-2.6.29-rc3.owrt/kernel/cpuset.c +--- linux-2.6.29.owrt/kernel/cpuset.c 2009-05-10 22:04:41.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/kernel/cpuset.c 2009-05-10 23:48:29.000000000 +0200 +@@ -61,14 +61,6 @@ + #include <linux/cgroup.h> + + /* +- * Workqueue for cpuset related tasks. +- * +- * Using kevent workqueue may cause deadlock when memory_migrate +- * is set. So we create a separate workqueue thread for cpuset. +- */ +-static struct workqueue_struct *cpuset_wq; +- +-/* + * Tracks how many cpusets are currently defined in system. + * When there is only one cpuset (the root cpuset) we can + * short circuit some hooks. +@@ -839,7 +831,7 @@ + */ + static void async_rebuild_sched_domains(void) + { +- queue_work(cpuset_wq, &rebuild_sched_domains_work); ++ schedule_work(&rebuild_sched_domains_work); + } + + /* +@@ -2119,9 +2111,6 @@ + + hotcpu_notifier(cpuset_track_online_cpus, 0); + hotplug_memory_notifier(cpuset_track_online_nodes, 10); +- +- cpuset_wq = create_singlethread_workqueue("cpuset"); +- BUG_ON(!cpuset_wq); + } + + /** +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/kernel/exit.c linux-2.6.29-rc3.owrt/kernel/exit.c +--- linux-2.6.29.owrt/kernel/exit.c 2009-05-10 22:04:41.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/kernel/exit.c 2009-05-10 23:48:29.000000000 +0200 +@@ -118,8 +118,6 @@ + * We won't ever get here for the group leader, since it + * will have been the last reference on the signal_struct. + */ +- sig->utime = cputime_add(sig->utime, task_utime(tsk)); +- sig->stime = cputime_add(sig->stime, task_stime(tsk)); + sig->gtime = cputime_add(sig->gtime, task_gtime(tsk)); + sig->min_flt += tsk->min_flt; + sig->maj_flt += tsk->maj_flt; +@@ -128,7 +126,6 @@ + sig->inblock += task_io_get_inblock(tsk); + sig->oublock += task_io_get_oublock(tsk); + task_io_accounting_add(&sig->ioac, &tsk->ioac); +- sig->sum_sched_runtime += tsk->se.sum_exec_runtime; + sig = NULL; /* Marker for below. */ + } + +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/kernel/fork.c linux-2.6.29-rc3.owrt/kernel/fork.c +--- linux-2.6.29.owrt/kernel/fork.c 2009-05-10 22:04:41.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/kernel/fork.c 2009-05-10 23:48:29.000000000 +0200 +@@ -852,14 +852,13 @@ + sig->tty_old_pgrp = NULL; + sig->tty = NULL; + +- sig->utime = sig->stime = sig->cutime = sig->cstime = cputime_zero; ++ sig->cutime = sig->cstime = cputime_zero; + sig->gtime = cputime_zero; + sig->cgtime = cputime_zero; + sig->nvcsw = sig->nivcsw = sig->cnvcsw = sig->cnivcsw = 0; + sig->min_flt = sig->maj_flt = sig->cmin_flt = sig->cmaj_flt = 0; + sig->inblock = sig->oublock = sig->cinblock = sig->coublock = 0; + task_io_accounting_init(&sig->ioac); +- sig->sum_sched_runtime = 0; + taskstats_tgid_init(sig); + + task_lock(current->group_leader); +@@ -1007,7 +1006,6 @@ + * triggers too late. This doesn't hurt, the check is only there + * to stop root fork bombs. + */ +- retval = -EAGAIN; + if (nr_threads >= max_threads) + goto bad_fork_cleanup_count; + +@@ -1096,7 +1094,7 @@ + #ifdef CONFIG_DEBUG_MUTEXES + p->blocked_on = NULL; /* not blocked yet */ + #endif +- if (unlikely(current->ptrace)) ++ if (unlikely(ptrace_reparented(current))) + ptrace_fork(p, clone_flags); + + /* Perform scheduler related setup. Assign this task to a CPU. */ +@@ -1180,6 +1178,10 @@ + #endif + clear_all_latency_tracing(p); + ++ /* Our parent execution domain becomes current domain ++ These must match for thread signalling to apply */ ++ p->parent_exec_id = p->self_exec_id; ++ + /* ok, now we should be set up.. */ + p->exit_signal = (clone_flags & CLONE_THREAD) ? -1 : (clone_flags & CSIGNAL); + p->pdeath_signal = 0; +@@ -1217,13 +1219,10 @@ + set_task_cpu(p, smp_processor_id()); + + /* CLONE_PARENT re-uses the old parent */ +- if (clone_flags & (CLONE_PARENT|CLONE_THREAD)) { ++ if (clone_flags & (CLONE_PARENT|CLONE_THREAD)) + p->real_parent = current->real_parent; +- p->parent_exec_id = current->parent_exec_id; +- } else { ++ else + p->real_parent = current; +- p->parent_exec_id = current->self_exec_id; +- } + + spin_lock(¤t->sighand->siglock); + +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/kernel/futex.c linux-2.6.29-rc3.owrt/kernel/futex.c +--- linux-2.6.29.owrt/kernel/futex.c 2009-05-10 22:04:41.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/kernel/futex.c 2009-05-10 23:48:29.000000000 +0200 +@@ -1165,7 +1165,6 @@ + u32 val, ktime_t *abs_time, u32 bitset, int clockrt) + { + struct task_struct *curr = current; +- struct restart_block *restart; + DECLARE_WAITQUEUE(wait, curr); + struct futex_hash_bucket *hb; + struct futex_q q; +@@ -1217,13 +1216,11 @@ + + if (!ret) + goto retry; +- goto out; ++ return ret; + } + ret = -EWOULDBLOCK; +- if (unlikely(uval != val)) { +- queue_unlock(&q, hb); +- goto out_put_key; +- } ++ if (uval != val) ++ goto out_unlock_put_key; + + /* Only actually queue if *uaddr contained val. */ + queue_me(&q, hb); +@@ -1287,38 +1284,38 @@ + */ + + /* If we were woken (and unqueued), we succeeded, whatever. */ +- ret = 0; + if (!unqueue_me(&q)) +- goto out_put_key; +- ret = -ETIMEDOUT; ++ return 0; + if (rem) +- goto out_put_key; ++ return -ETIMEDOUT; + + /* + * We expect signal_pending(current), but another thread may + * have handled it for us already. + */ +- ret = -ERESTARTSYS; + if (!abs_time) +- goto out_put_key; +- +- restart = ¤t_thread_info()->restart_block; +- restart->fn = futex_wait_restart; +- restart->futex.uaddr = (u32 *)uaddr; +- restart->futex.val = val; +- restart->futex.time = abs_time->tv64; +- restart->futex.bitset = bitset; +- restart->futex.flags = 0; +- +- if (fshared) +- restart->futex.flags |= FLAGS_SHARED; +- if (clockrt) +- restart->futex.flags |= FLAGS_CLOCKRT; +- +- ret = -ERESTART_RESTARTBLOCK; ++ return -ERESTARTSYS; ++ else { ++ struct restart_block *restart; ++ restart = ¤t_thread_info()->restart_block; ++ restart->fn = futex_wait_restart; ++ restart->futex.uaddr = (u32 *)uaddr; ++ restart->futex.val = val; ++ restart->futex.time = abs_time->tv64; ++ restart->futex.bitset = bitset; ++ restart->futex.flags = 0; ++ ++ if (fshared) ++ restart->futex.flags |= FLAGS_SHARED; ++ if (clockrt) ++ restart->futex.flags |= FLAGS_CLOCKRT; ++ return -ERESTART_RESTARTBLOCK; ++ } + +-out_put_key: ++out_unlock_put_key: ++ queue_unlock(&q, hb); + put_futex_key(fshared, &q.key); ++ + out: + return ret; + } +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/kernel/hrtimer.c linux-2.6.29-rc3.owrt/kernel/hrtimer.c +--- linux-2.6.29.owrt/kernel/hrtimer.c 2009-05-10 22:04:41.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/kernel/hrtimer.c 2009-05-10 23:48:29.000000000 +0200 +@@ -501,13 +501,6 @@ + continue; + timer = rb_entry(base->first, struct hrtimer, node); + expires = ktime_sub(hrtimer_get_expires(timer), base->offset); +- /* +- * clock_was_set() has changed base->offset so the +- * result might be negative. Fix it up to prevent a +- * false positive in clockevents_program_event() +- */ +- if (expires.tv64 < 0) +- expires.tv64 = 0; + if (expires.tv64 < cpu_base->expires_next.tv64) + cpu_base->expires_next = expires; + } +@@ -1165,29 +1158,6 @@ + + #ifdef CONFIG_HIGH_RES_TIMERS + +-static int force_clock_reprogram; +- +-/* +- * After 5 iteration's attempts, we consider that hrtimer_interrupt() +- * is hanging, which could happen with something that slows the interrupt +- * such as the tracing. Then we force the clock reprogramming for each future +- * hrtimer interrupts to avoid infinite loops and use the min_delta_ns +- * threshold that we will overwrite. +- * The next tick event will be scheduled to 3 times we currently spend on +- * hrtimer_interrupt(). This gives a good compromise, the cpus will spend +- * 1/4 of their time to process the hrtimer interrupts. This is enough to +- * let it running without serious starvation. +- */ +- +-static inline void +-hrtimer_interrupt_hanging(struct clock_event_device *dev, +- ktime_t try_time) +-{ +- force_clock_reprogram = 1; +- dev->min_delta_ns = (unsigned long)try_time.tv64 * 3; +- printk(KERN_WARNING "hrtimer: interrupt too slow, " +- "forcing clock min delta to %lu ns\n", dev->min_delta_ns); +-} + /* + * High resolution timer interrupt + * Called with interrupts disabled +@@ -1197,7 +1167,6 @@ + struct hrtimer_cpu_base *cpu_base = &__get_cpu_var(hrtimer_bases); + struct hrtimer_clock_base *base; + ktime_t expires_next, now; +- int nr_retries = 0; + int i; + + BUG_ON(!cpu_base->hres_active); +@@ -1205,10 +1174,6 @@ + dev->next_event.tv64 = KTIME_MAX; + + retry: +- /* 5 retries is enough to notice a hang */ +- if (!(++nr_retries % 5)) +- hrtimer_interrupt_hanging(dev, ktime_sub(ktime_get(), now)); +- + now = ktime_get(); + + expires_next.tv64 = KTIME_MAX; +@@ -1261,7 +1226,7 @@ + + /* Reprogramming necessary ? */ + if (expires_next.tv64 != KTIME_MAX) { +- if (tick_program_event(expires_next, force_clock_reprogram)) ++ if (tick_program_event(expires_next, 0)) + goto retry; + } + } +@@ -1615,10 +1580,6 @@ + break; + + #ifdef CONFIG_HOTPLUG_CPU +- case CPU_DYING: +- case CPU_DYING_FROZEN: +- clockevents_notify(CLOCK_EVT_NOTIFY_CPU_DYING, &scpu); +- break; + case CPU_DEAD: + case CPU_DEAD_FROZEN: + { +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/kernel/irq/chip.c linux-2.6.29-rc3.owrt/kernel/irq/chip.c +--- linux-2.6.29.owrt/kernel/irq/chip.c 2009-05-10 22:04:41.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/kernel/irq/chip.c 2009-05-10 23:48:29.000000000 +0200 +@@ -383,7 +383,6 @@ + out_unlock: + spin_unlock(&desc->lock); + } +-EXPORT_SYMBOL_GPL(handle_level_irq); + + /** + * handle_fasteoi_irq - irq handler for transparent controllers +@@ -594,7 +593,6 @@ + } + spin_unlock_irqrestore(&desc->lock, flags); + } +-EXPORT_SYMBOL_GPL(__set_irq_handler); + + void + set_irq_chip_and_handler(unsigned int irq, struct irq_chip *chip, +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/kernel/irq/numa_migrate.c linux-2.6.29-rc3.owrt/kernel/irq/numa_migrate.c +--- linux-2.6.29.owrt/kernel/irq/numa_migrate.c 2009-05-10 22:04:41.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/kernel/irq/numa_migrate.c 2009-05-10 23:48:29.000000000 +0200 +@@ -71,7 +71,7 @@ + desc = irq_desc_ptrs[irq]; + + if (desc && old_desc != desc) +- goto out_unlock; ++ goto out_unlock; + + node = cpu_to_node(cpu); + desc = kzalloc_node(sizeof(*desc), GFP_ATOMIC, node); +@@ -84,15 +84,10 @@ + init_copy_one_irq_desc(irq, old_desc, desc, cpu); + + irq_desc_ptrs[irq] = desc; +- spin_unlock_irqrestore(&sparse_irq_lock, flags); + + /* free the old one */ + free_one_irq_desc(old_desc, desc); +- spin_unlock(&old_desc->lock); + kfree(old_desc); +- spin_lock(&desc->lock); +- +- return desc; + + out_unlock: + spin_unlock_irqrestore(&sparse_irq_lock, flags); +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/kernel/itimer.c linux-2.6.29-rc3.owrt/kernel/itimer.c +--- linux-2.6.29.owrt/kernel/itimer.c 2009-05-10 22:04:41.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/kernel/itimer.c 2009-05-10 23:48:29.000000000 +0200 +@@ -62,7 +62,7 @@ + struct task_cputime cputime; + cputime_t utime; + +- thread_group_cputimer(tsk, &cputime); ++ thread_group_cputime(tsk, &cputime); + utime = cputime.utime; + if (cputime_le(cval, utime)) { /* about to fire */ + cval = jiffies_to_cputime(1); +@@ -82,7 +82,7 @@ + struct task_cputime times; + cputime_t ptime; + +- thread_group_cputimer(tsk, ×); ++ thread_group_cputime(tsk, ×); + ptime = cputime_add(times.utime, times.stime); + if (cputime_le(cval, ptime)) { /* about to fire */ + cval = jiffies_to_cputime(1); +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/kernel/kexec.c linux-2.6.29-rc3.owrt/kernel/kexec.c +--- linux-2.6.29.owrt/kernel/kexec.c 2009-05-10 22:04:41.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/kernel/kexec.c 2009-05-10 23:48:29.000000000 +0200 +@@ -1465,11 +1465,6 @@ + error = device_power_down(PMSG_FREEZE); + if (error) + goto Enable_irqs; +- +- /* Suspend system devices */ +- error = sysdev_suspend(PMSG_FREEZE); +- if (error) +- goto Power_up_devices; + } else + #endif + { +@@ -1482,8 +1477,6 @@ + + #ifdef CONFIG_KEXEC_JUMP + if (kexec_image->preserve_context) { +- sysdev_resume(); +- Power_up_devices: + device_power_up(PMSG_RESTORE); + Enable_irqs: + local_irq_enable(); +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/kernel/Makefile linux-2.6.29-rc3.owrt/kernel/Makefile +--- linux-2.6.29.owrt/kernel/Makefile 2009-05-10 22:04:41.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/kernel/Makefile 2009-05-10 23:48:29.000000000 +0200 +@@ -51,7 +51,6 @@ + obj-$(CONFIG_MODULES) += module.o + obj-$(CONFIG_KALLSYMS) += kallsyms.o + obj-$(CONFIG_PM) += power/ +-obj-$(CONFIG_FREEZER) += power/ + obj-$(CONFIG_BSD_PROCESS_ACCT) += acct.o + obj-$(CONFIG_KEXEC) += kexec.o + obj-$(CONFIG_BACKTRACE_SELF_TEST) += backtracetest.o +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/kernel/module.c linux-2.6.29-rc3.owrt/kernel/module.c +--- linux-2.6.29.owrt/kernel/module.c 2009-05-10 22:04:41.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/kernel/module.c 2009-05-10 23:48:29.000000000 +0200 +@@ -573,13 +573,13 @@ + /* Init the unload section of the module. */ + static void module_unload_init(struct module *mod) + { +- int cpu; ++ unsigned int i; + + INIT_LIST_HEAD(&mod->modules_which_use_me); +- for_each_possible_cpu(cpu) +- local_set(__module_ref_addr(mod, cpu), 0); ++ for (i = 0; i < NR_CPUS; i++) ++ local_set(&mod->ref[i].count, 0); + /* Hold reference count during initialization. */ +- local_set(__module_ref_addr(mod, raw_smp_processor_id()), 1); ++ local_set(&mod->ref[raw_smp_processor_id()].count, 1); + /* Backwards compatibility macros put refcount during init. */ + mod->waiter = current; + } +@@ -717,11 +717,10 @@ + + unsigned int module_refcount(struct module *mod) + { +- unsigned int total = 0; +- int cpu; ++ unsigned int i, total = 0; + +- for_each_possible_cpu(cpu) +- total += local_read(__module_ref_addr(mod, cpu)); ++ for (i = 0; i < NR_CPUS; i++) ++ total += local_read(&mod->ref[i].count); + return total; + } + EXPORT_SYMBOL(module_refcount); +@@ -895,7 +894,7 @@ + { + if (module) { + unsigned int cpu = get_cpu(); +- local_dec(__module_ref_addr(module, cpu)); ++ local_dec(&module->ref[cpu].count); + /* Maybe they're waiting for us to drop reference? */ + if (unlikely(!module_is_live(module))) + wake_up_process(module->waiter); +@@ -1465,10 +1464,7 @@ + kfree(mod->args); + if (mod->percpu) + percpu_modfree(mod->percpu); +-#if defined(CONFIG_MODULE_UNLOAD) && defined(CONFIG_SMP) +- if (mod->refptr) +- percpu_modfree(mod->refptr); +-#endif ++ + /* Free lock-classes: */ + lockdep_free_key_range(mod->module_core, mod->core_size); + +@@ -2074,14 +2070,6 @@ + /* Module has been moved. */ + mod = (void *)sechdrs[modindex].sh_addr; + +-#if defined(CONFIG_MODULE_UNLOAD) && defined(CONFIG_SMP) +- mod->refptr = percpu_modalloc(sizeof(local_t), __alignof__(local_t), +- mod->name); +- if (!mod->refptr) { +- err = -ENOMEM; +- goto free_init; +- } +-#endif + /* Now we've moved module, initialize linked lists, etc. */ + module_unload_init(mod); + +@@ -2288,14 +2276,9 @@ + ftrace_release(mod->module_core, mod->core_size); + free_unload: + module_unload_free(mod); +- free_init: +-#if defined(CONFIG_MODULE_UNLOAD) && defined(CONFIG_SMP) +- percpu_modfree(mod->refptr); +-#endif + module_free(mod, mod->module_init); + free_core: + module_free(mod, mod->module_core); +- /* mod will be freed with core. Don't access it beyond this line! */ + free_percpu: + if (percpu) + percpu_modfree(percpu); +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/kernel/posix-cpu-timers.c linux-2.6.29-rc3.owrt/kernel/posix-cpu-timers.c +--- linux-2.6.29.owrt/kernel/posix-cpu-timers.c 2009-05-10 22:04:41.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/kernel/posix-cpu-timers.c 2009-05-10 23:48:29.000000000 +0200 +@@ -230,71 +230,6 @@ + return 0; + } + +-void thread_group_cputime(struct task_struct *tsk, struct task_cputime *times) +-{ +- struct sighand_struct *sighand; +- struct signal_struct *sig; +- struct task_struct *t; +- +- *times = INIT_CPUTIME; +- +- rcu_read_lock(); +- sighand = rcu_dereference(tsk->sighand); +- if (!sighand) +- goto out; +- +- sig = tsk->signal; +- +- t = tsk; +- do { +- times->utime = cputime_add(times->utime, t->utime); +- times->stime = cputime_add(times->stime, t->stime); +- times->sum_exec_runtime += t->se.sum_exec_runtime; +- +- t = next_thread(t); +- } while (t != tsk); +- +- times->utime = cputime_add(times->utime, sig->utime); +- times->stime = cputime_add(times->stime, sig->stime); +- times->sum_exec_runtime += sig->sum_sched_runtime; +-out: +- rcu_read_unlock(); +-} +- +-static void update_gt_cputime(struct task_cputime *a, struct task_cputime *b) +-{ +- if (cputime_gt(b->utime, a->utime)) +- a->utime = b->utime; +- +- if (cputime_gt(b->stime, a->stime)) +- a->stime = b->stime; +- +- if (b->sum_exec_runtime > a->sum_exec_runtime) +- a->sum_exec_runtime = b->sum_exec_runtime; +-} +- +-void thread_group_cputimer(struct task_struct *tsk, struct task_cputime *times) +-{ +- struct thread_group_cputimer *cputimer = &tsk->signal->cputimer; +- struct task_cputime sum; +- unsigned long flags; +- +- spin_lock_irqsave(&cputimer->lock, flags); +- if (!cputimer->running) { +- cputimer->running = 1; +- /* +- * The POSIX timer interface allows for absolute time expiry +- * values through the TIMER_ABSTIME flag, therefore we have +- * to synchronize the timer to the clock every time we start +- * it. +- */ +- thread_group_cputime(tsk, &sum); +- update_gt_cputime(&cputimer->cputime, &sum); +- } +- *times = cputimer->cputime; +- spin_unlock_irqrestore(&cputimer->lock, flags); +-} +- + /* + * Sample a process (thread group) clock for the given group_leader task. + * Must be called with tasklist_lock held for reading. +@@ -522,7 +457,7 @@ + { + struct task_cputime cputime; + +- thread_group_cputimer(tsk, &cputime); ++ thread_group_cputime(tsk, &cputime); + cleanup_timers(tsk->signal->cpu_timers, + cputime.utime, cputime.stime, cputime.sum_exec_runtime); + } +@@ -681,33 +616,6 @@ + } + + /* +- * Sample a process (thread group) timer for the given group_leader task. +- * Must be called with tasklist_lock held for reading. +- */ +-static int cpu_timer_sample_group(const clockid_t which_clock, +- struct task_struct *p, +- union cpu_time_count *cpu) +-{ +- struct task_cputime cputime; +- +- thread_group_cputimer(p, &cputime); +- switch (CPUCLOCK_WHICH(which_clock)) { +- default: +- return -EINVAL; +- case CPUCLOCK_PROF: +- cpu->cpu = cputime_add(cputime.utime, cputime.stime); +- break; +- case CPUCLOCK_VIRT: +- cpu->cpu = cputime.utime; +- break; +- case CPUCLOCK_SCHED: +- cpu->sched = cputime.sum_exec_runtime + task_delta_exec(p); +- break; +- } +- return 0; +-} +- +-/* + * Guts of sys_timer_settime for CPU timers. + * This is called with the timer locked and interrupts disabled. + * If we return TIMER_RETRY, it's necessary to release the timer's lock +@@ -768,7 +676,7 @@ + if (CPUCLOCK_PERTHREAD(timer->it_clock)) { + cpu_clock_sample(timer->it_clock, p, &val); + } else { +- cpu_timer_sample_group(timer->it_clock, p, &val); ++ cpu_clock_sample_group(timer->it_clock, p, &val); + } + + if (old) { +@@ -916,7 +824,7 @@ + read_unlock(&tasklist_lock); + goto dead; + } else { +- cpu_timer_sample_group(timer->it_clock, p, &now); ++ cpu_clock_sample_group(timer->it_clock, p, &now); + clear_dead = (unlikely(p->exit_state) && + thread_group_empty(p)); + } +@@ -1056,19 +964,6 @@ + } + } + +-static void stop_process_timers(struct task_struct *tsk) +-{ +- struct thread_group_cputimer *cputimer = &tsk->signal->cputimer; +- unsigned long flags; +- +- if (!cputimer->running) +- return; +- +- spin_lock_irqsave(&cputimer->lock, flags); +- cputimer->running = 0; +- spin_unlock_irqrestore(&cputimer->lock, flags); +-} +- + /* + * Check for any per-thread CPU timers that have fired and move them + * off the tsk->*_timers list onto the firing list. Per-thread timers +@@ -1092,15 +987,13 @@ + sig->rlim[RLIMIT_CPU].rlim_cur == RLIM_INFINITY && + list_empty(&timers[CPUCLOCK_VIRT]) && + cputime_eq(sig->it_virt_expires, cputime_zero) && +- list_empty(&timers[CPUCLOCK_SCHED])) { +- stop_process_timers(tsk); ++ list_empty(&timers[CPUCLOCK_SCHED])) + return; +- } + + /* + * Collect the current process totals. + */ +- thread_group_cputimer(tsk, &cputime); ++ thread_group_cputime(tsk, &cputime); + utime = cputime.utime; + ptime = cputime_add(utime, cputime.stime); + sum_sched_runtime = cputime.sum_exec_runtime; +@@ -1271,7 +1164,7 @@ + clear_dead_task(timer, now); + goto out_unlock; + } +- cpu_timer_sample_group(timer->it_clock, p, &now); ++ cpu_clock_sample_group(timer->it_clock, p, &now); + bump_cpu_timer(timer, now); + /* Leave the tasklist_lock locked for the call below. */ + } +@@ -1366,7 +1259,7 @@ + if (!task_cputime_zero(&sig->cputime_expires)) { + struct task_cputime group_sample; + +- thread_group_cputimer(tsk, &group_sample); ++ thread_group_cputime(tsk, &group_sample); + if (task_cputime_expired(&group_sample, &sig->cputime_expires)) + return 1; + } +@@ -1448,7 +1341,7 @@ + struct list_head *head; + + BUG_ON(clock_idx == CPUCLOCK_SCHED); +- cpu_timer_sample_group(clock_idx, tsk, &now); ++ cpu_clock_sample_group(clock_idx, tsk, &now); + + if (oldval) { + if (!cputime_eq(*oldval, cputime_zero)) { +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/kernel/power/console.c linux-2.6.29-rc3.owrt/kernel/power/console.c +--- linux-2.6.29.owrt/kernel/power/console.c 2009-05-10 22:04:41.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/kernel/power/console.c 2009-05-10 23:48:29.000000000 +0200 +@@ -78,12 +78,6 @@ + } + set_console(orig_fgconsole); + release_console_sem(); +- +- if (vt_waitactive(orig_fgconsole)) { +- pr_debug("Resume: Can't switch VCs."); +- return; +- } +- + kmsg_redirect = orig_kmsg; + } + #endif +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/kernel/power/disk.c linux-2.6.29-rc3.owrt/kernel/power/disk.c +--- linux-2.6.29.owrt/kernel/power/disk.c 2009-05-10 22:04:41.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/kernel/power/disk.c 2009-05-10 23:48:29.000000000 +0200 +@@ -227,12 +227,6 @@ + "aborting hibernation\n"); + goto Enable_irqs; + } +- sysdev_suspend(PMSG_FREEZE); +- if (error) { +- printk(KERN_ERR "PM: Some devices failed to power down, " +- "aborting hibernation\n"); +- goto Power_up_devices; +- } + + if (hibernation_test(TEST_CORE)) + goto Power_up; +@@ -248,11 +242,9 @@ + if (!in_suspend) + platform_leave(platform_mode); + Power_up: +- sysdev_resume(); + /* NOTE: device_power_up() is just a resume() for devices + * that suspended with irqs off ... no overall powerup. + */ +- Power_up_devices: + device_power_up(in_suspend ? + (error ? PMSG_RECOVER : PMSG_THAW) : PMSG_RESTORE); + Enable_irqs: +@@ -343,7 +335,6 @@ + "aborting resume\n"); + goto Enable_irqs; + } +- sysdev_suspend(PMSG_QUIESCE); + /* We'll ignore saved state, but this gets preempt count (etc) right */ + save_processor_state(); + error = restore_highmem(); +@@ -366,7 +357,6 @@ + swsusp_free(); + restore_processor_state(); + touch_softlockup_watchdog(); +- sysdev_resume(); + device_power_up(PMSG_RECOVER); + Enable_irqs: + local_irq_enable(); +@@ -450,7 +440,6 @@ + local_irq_disable(); + error = device_power_down(PMSG_HIBERNATE); + if (!error) { +- sysdev_suspend(PMSG_HIBERNATE); + hibernation_ops->enter(); + /* We should never get here */ + while (1); +@@ -606,12 +595,6 @@ + unsigned int flags; + + /* +- * If the user said "noresume".. bail out early. +- */ +- if (noresume) +- return 0; +- +- /* + * name_to_dev_t() below takes a sysfs buffer mutex when sysfs + * is configured into the kernel. Since the regular hibernate + * trigger path is via sysfs which takes a buffer mutex before +@@ -627,11 +610,6 @@ + mutex_unlock(&pm_mutex); + return -ENOENT; + } +- /* +- * Some device discovery might still be in progress; we need +- * to wait for this to finish. +- */ +- wait_for_device_probe(); + swsusp_resume_device = name_to_dev_t(resume_file); + pr_debug("PM: Resume from partition %s\n", resume_file); + } else { +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/kernel/power/main.c linux-2.6.29-rc3.owrt/kernel/power/main.c +--- linux-2.6.29.owrt/kernel/power/main.c 2009-05-10 22:04:41.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/kernel/power/main.c 2009-05-10 23:48:29.000000000 +0200 +@@ -57,6 +57,16 @@ + #ifdef CONFIG_PM_DEBUG + int pm_test_level = TEST_NONE; + ++static int suspend_test(int level) ++{ ++ if (pm_test_level == level) { ++ printk(KERN_INFO "suspend debug: Waiting for 5 seconds.\n"); ++ mdelay(5000); ++ return 1; ++ } ++ return 0; ++} ++ + static const char * const pm_tests[__TEST_AFTER_LAST] = { + [TEST_NONE] = "none", + [TEST_CORE] = "core", +@@ -115,24 +125,14 @@ + } + + power_attr(pm_test); +-#endif /* CONFIG_PM_DEBUG */ ++#else /* !CONFIG_PM_DEBUG */ ++static inline int suspend_test(int level) { return 0; } ++#endif /* !CONFIG_PM_DEBUG */ + + #endif /* CONFIG_PM_SLEEP */ + + #ifdef CONFIG_SUSPEND + +-static int suspend_test(int level) +-{ +-#ifdef CONFIG_PM_DEBUG +- if (pm_test_level == level) { +- printk(KERN_INFO "suspend debug: Waiting for 5 seconds.\n"); +- mdelay(5000); +- return 1; +- } +-#endif /* !CONFIG_PM_DEBUG */ +- return 0; +-} +- + #ifdef CONFIG_PM_TEST_SUSPEND + + /* +@@ -298,12 +298,8 @@ + goto Done; + } + +- error = sysdev_suspend(PMSG_SUSPEND); +- if (!error) { +- if (!suspend_test(TEST_CORE)) +- error = suspend_ops->enter(state); +- sysdev_resume(); +- } ++ if (!suspend_test(TEST_CORE)) ++ error = suspend_ops->enter(state); + + device_power_up(PMSG_RESUME); + Done: +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/kernel/power/Makefile linux-2.6.29-rc3.owrt/kernel/power/Makefile +--- linux-2.6.29.owrt/kernel/power/Makefile 2009-05-10 22:04:41.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/kernel/power/Makefile 2009-05-10 23:48:29.000000000 +0200 +@@ -3,7 +3,7 @@ + EXTRA_CFLAGS += -DDEBUG + endif + +-obj-$(CONFIG_PM) += main.o ++obj-y := main.o + obj-$(CONFIG_PM_SLEEP) += console.o + obj-$(CONFIG_FREEZER) += process.o + obj-$(CONFIG_HIBERNATION) += swsusp.o disk.o snapshot.o swap.o user.o +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/kernel/power/swap.c linux-2.6.29-rc3.owrt/kernel/power/swap.c +--- linux-2.6.29.owrt/kernel/power/swap.c 2009-05-10 22:04:41.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/kernel/power/swap.c 2009-05-10 23:48:29.000000000 +0200 +@@ -60,7 +60,6 @@ + static int submit(int rw, pgoff_t page_off, struct page *page, + struct bio **bio_chain) + { +- const int bio_rw = rw | (1 << BIO_RW_SYNCIO) | (1 << BIO_RW_UNPLUG); + struct bio *bio; + + bio = bio_alloc(__GFP_WAIT | __GFP_HIGH, 1); +@@ -81,7 +80,7 @@ + bio_get(bio); + + if (bio_chain == NULL) { +- submit_bio(bio_rw, bio); ++ submit_bio(rw | (1 << BIO_RW_SYNC), bio); + wait_on_page_locked(page); + if (rw == READ) + bio_set_pages_dirty(bio); +@@ -91,7 +90,7 @@ + get_page(page); /* These pages are freed later */ + bio->bi_private = *bio_chain; + *bio_chain = bio; +- submit_bio(bio_rw, bio); ++ submit_bio(rw | (1 << BIO_RW_SYNC), bio); + } + return 0; + } +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/kernel/power/user.c linux-2.6.29-rc3.owrt/kernel/power/user.c +--- linux-2.6.29.owrt/kernel/power/user.c 2009-05-10 22:04:41.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/kernel/power/user.c 2009-05-10 23:48:29.000000000 +0200 +@@ -95,15 +95,15 @@ + data->swap = swsusp_resume_device ? + swap_type_of(swsusp_resume_device, 0, NULL) : -1; + data->mode = O_RDONLY; +- error = pm_notifier_call_chain(PM_HIBERNATION_PREPARE); ++ error = pm_notifier_call_chain(PM_RESTORE_PREPARE); + if (error) +- pm_notifier_call_chain(PM_POST_HIBERNATION); ++ pm_notifier_call_chain(PM_POST_RESTORE); + } else { + data->swap = -1; + data->mode = O_WRONLY; +- error = pm_notifier_call_chain(PM_RESTORE_PREPARE); ++ error = pm_notifier_call_chain(PM_HIBERNATION_PREPARE); + if (error) +- pm_notifier_call_chain(PM_POST_RESTORE); ++ pm_notifier_call_chain(PM_POST_HIBERNATION); + } + if (error) + atomic_inc(&snapshot_device_available); +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/kernel/printk.c linux-2.6.29-rc3.owrt/kernel/printk.c +--- linux-2.6.29.owrt/kernel/printk.c 2009-05-10 22:04:41.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/kernel/printk.c 2009-05-10 23:48:29.000000000 +0200 +@@ -73,6 +73,7 @@ + * driver system. + */ + static DECLARE_MUTEX(console_sem); ++static DECLARE_MUTEX(secondary_console_sem); + struct console *console_drivers; + EXPORT_SYMBOL_GPL(console_drivers); + +@@ -890,14 +891,12 @@ + printk("Suspending console(s) (use no_console_suspend to debug)\n"); + acquire_console_sem(); + console_suspended = 1; +- up(&console_sem); + } + + void resume_console(void) + { + if (!console_suspend_enabled) + return; +- down(&console_sem); + console_suspended = 0; + release_console_sem(); + } +@@ -913,9 +912,11 @@ + void acquire_console_sem(void) + { + BUG_ON(in_interrupt()); +- down(&console_sem); +- if (console_suspended) ++ if (console_suspended) { ++ down(&secondary_console_sem); + return; ++ } ++ down(&console_sem); + console_locked = 1; + console_may_schedule = 1; + } +@@ -925,10 +926,6 @@ + { + if (down_trylock(&console_sem)) + return -1; +- if (console_suspended) { +- up(&console_sem); +- return -1; +- } + console_locked = 1; + console_may_schedule = 0; + return 0; +@@ -982,7 +979,7 @@ + unsigned wake_klogd = 0; + + if (console_suspended) { +- up(&console_sem); ++ up(&secondary_console_sem); + return; + } + +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/kernel/profile.c linux-2.6.29-rc3.owrt/kernel/profile.c +--- linux-2.6.29.owrt/kernel/profile.c 2009-05-10 22:04:41.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/kernel/profile.c 2009-05-10 23:48:29.000000000 +0200 +@@ -114,15 +114,12 @@ + if (!slab_is_available()) { + prof_buffer = alloc_bootmem(buffer_bytes); + alloc_bootmem_cpumask_var(&prof_cpu_mask); +- cpumask_copy(prof_cpu_mask, cpu_possible_mask); + return 0; + } + + if (!alloc_cpumask_var(&prof_cpu_mask, GFP_KERNEL)) + return -ENOMEM; + +- cpumask_copy(prof_cpu_mask, cpu_possible_mask); +- + prof_buffer = kzalloc(buffer_bytes, GFP_KERNEL); + if (prof_buffer) + return 0; +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/kernel/rcuclassic.c linux-2.6.29-rc3.owrt/kernel/rcuclassic.c +--- linux-2.6.29.owrt/kernel/rcuclassic.c 2009-05-10 22:04:41.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/kernel/rcuclassic.c 2009-05-10 23:48:29.000000000 +0200 +@@ -679,8 +679,8 @@ + void rcu_check_callbacks(int cpu, int user) + { + if (user || +- (idle_cpu(cpu) && rcu_scheduler_active && +- !in_softirq() && hardirq_count() <= (1 << HARDIRQ_SHIFT))) { ++ (idle_cpu(cpu) && !in_softirq() && ++ hardirq_count() <= (1 << HARDIRQ_SHIFT))) { + + /* + * Get here if this CPU took its interrupt from user +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/kernel/rcupdate.c linux-2.6.29-rc3.owrt/kernel/rcupdate.c +--- linux-2.6.29.owrt/kernel/rcupdate.c 2009-05-10 22:04:41.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/kernel/rcupdate.c 2009-05-10 23:48:29.000000000 +0200 +@@ -44,7 +44,6 @@ + #include <linux/cpu.h> + #include <linux/mutex.h> + #include <linux/module.h> +-#include <linux/kernel_stat.h> + + enum rcu_barrier { + RCU_BARRIER_STD, +@@ -56,7 +55,6 @@ + static atomic_t rcu_barrier_cpu_count; + static DEFINE_MUTEX(rcu_barrier_mutex); + static struct completion rcu_barrier_completion; +-int rcu_scheduler_active __read_mostly; + + /* + * Awaken the corresponding synchronize_rcu() instance now that a +@@ -82,10 +80,6 @@ + void synchronize_rcu(void) + { + struct rcu_synchronize rcu; +- +- if (rcu_blocking_is_gp()) +- return; +- + init_completion(&rcu.completion); + /* Will wake me after RCU finished. */ + call_rcu(&rcu.head, wakeme_after_rcu); +@@ -181,9 +175,3 @@ + __rcu_init(); + } + +-void rcu_scheduler_starting(void) +-{ +- WARN_ON(num_online_cpus() != 1); +- WARN_ON(nr_context_switches() > 0); +- rcu_scheduler_active = 1; +-} +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/kernel/rcupreempt.c linux-2.6.29-rc3.owrt/kernel/rcupreempt.c +--- linux-2.6.29.owrt/kernel/rcupreempt.c 2009-05-10 22:04:41.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/kernel/rcupreempt.c 2009-05-10 23:48:29.000000000 +0200 +@@ -1181,9 +1181,6 @@ + { + struct rcu_synchronize rcu; + +- if (num_online_cpus() == 1) +- return; /* blocking is gp if only one CPU! */ +- + init_completion(&rcu.completion); + /* Will wake me after RCU finished. */ + call_rcu_sched(&rcu.head, wakeme_after_rcu); +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/kernel/rcutree.c linux-2.6.29-rc3.owrt/kernel/rcutree.c +--- linux-2.6.29.owrt/kernel/rcutree.c 2009-05-10 22:04:41.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/kernel/rcutree.c 2009-05-10 23:48:29.000000000 +0200 +@@ -948,8 +948,8 @@ + void rcu_check_callbacks(int cpu, int user) + { + if (user || +- (idle_cpu(cpu) && rcu_scheduler_active && +- !in_softirq() && hardirq_count() <= (1 << HARDIRQ_SHIFT))) { ++ (idle_cpu(cpu) && !in_softirq() && ++ hardirq_count() <= (1 << HARDIRQ_SHIFT))) { + + /* + * Get here if this CPU took its interrupt from user +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/kernel/sched.c linux-2.6.29-rc3.owrt/kernel/sched.c +--- linux-2.6.29.owrt/kernel/sched.c 2009-05-10 22:04:41.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/kernel/sched.c 2009-05-10 23:48:29.000000000 +0200 +@@ -223,7 +223,7 @@ + { + ktime_t now; + +- if (!rt_bandwidth_enabled() || rt_b->rt_runtime == RUNTIME_INF) ++ if (rt_bandwidth_enabled() && rt_b->rt_runtime == RUNTIME_INF) + return; + + if (hrtimer_active(&rt_b->rt_period_timer)) +@@ -3880,24 +3880,19 @@ + int cpu = smp_processor_id(); + + if (stop_tick) { ++ cpumask_set_cpu(cpu, nohz.cpu_mask); + cpu_rq(cpu)->in_nohz_recently = 1; + +- if (!cpu_active(cpu)) { +- if (atomic_read(&nohz.load_balancer) != cpu) +- return 0; +- +- /* +- * If we are going offline and still the leader, +- * give up! +- */ ++ /* ++ * If we are going offline and still the leader, give up! ++ */ ++ if (!cpu_active(cpu) && ++ atomic_read(&nohz.load_balancer) == cpu) { + if (atomic_cmpxchg(&nohz.load_balancer, cpu, -1) != cpu) + BUG(); +- + return 0; + } + +- cpumask_set_cpu(cpu, nohz.cpu_mask); +- + /* time for ilb owner also to sleep */ + if (cpumask_weight(nohz.cpu_mask) == num_online_cpus()) { + if (atomic_read(&nohz.load_balancer) == cpu) +@@ -4692,8 +4687,8 @@ + * started to run but is not in state TASK_RUNNING. try_to_wake_up() returns + * zero in this (rare) case, and we handle it by continuing to scan the queue. + */ +-void __wake_up_common(wait_queue_head_t *q, unsigned int mode, +- int nr_exclusive, int sync, void *key) ++static void __wake_up_common(wait_queue_head_t *q, unsigned int mode, ++ int nr_exclusive, int sync, void *key) + { + wait_queue_t *curr, *next; + +@@ -6945,26 +6940,20 @@ + + static void rq_attach_root(struct rq *rq, struct root_domain *rd) + { +- struct root_domain *old_rd = NULL; + unsigned long flags; + + spin_lock_irqsave(&rq->lock, flags); + + if (rq->rd) { +- old_rd = rq->rd; ++ struct root_domain *old_rd = rq->rd; + + if (cpumask_test_cpu(rq->cpu, old_rd->online)) + set_rq_offline(rq); + + cpumask_clear_cpu(rq->cpu, old_rd->span); + +- /* +- * If we dont want to free the old_rt yet then +- * set old_rd to NULL to skip the freeing later +- * in this function: +- */ +- if (!atomic_dec_and_test(&old_rd->refcount)) +- old_rd = NULL; ++ if (atomic_dec_and_test(&old_rd->refcount)) ++ free_rootdomain(old_rd); + } + + atomic_inc(&rd->refcount); +@@ -6975,9 +6964,6 @@ + set_rq_online(rq); + + spin_unlock_irqrestore(&rq->lock, flags); +- +- if (old_rd) +- free_rootdomain(old_rd); + } + + static int __init_refok init_rootdomain(struct root_domain *rd, bool bootmem) +@@ -9225,16 +9211,6 @@ + + return ret; + } +- +-int sched_rt_can_attach(struct task_group *tg, struct task_struct *tsk) +-{ +- /* Don't accept realtime tasks when there is no way for them to run */ +- if (rt_task(tsk) && tg->rt_bandwidth.rt_runtime == 0) +- return 0; +- +- return 1; +-} +- + #else /* !CONFIG_RT_GROUP_SCHED */ + static int sched_rt_global_constraints(void) + { +@@ -9328,7 +9304,8 @@ + struct task_struct *tsk) + { + #ifdef CONFIG_RT_GROUP_SCHED +- if (!sched_rt_can_attach(cgroup_tg(cgrp), tsk)) ++ /* Don't accept realtime tasks when there is no way for them to run */ ++ if (rt_task(tsk) && cgroup_tg(cgrp)->rt_bandwidth.rt_runtime == 0) + return -EINVAL; + #else + /* We don't support RT-tasks being in separate groups */ +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/kernel/sched_fair.c linux-2.6.29-rc3.owrt/kernel/sched_fair.c +--- linux-2.6.29.owrt/kernel/sched_fair.c 2009-05-10 22:04:41.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/kernel/sched_fair.c 2009-05-10 23:48:29.000000000 +0200 +@@ -719,7 +719,7 @@ + __enqueue_entity(cfs_rq, se); + } + +-static void __clear_buddies(struct cfs_rq *cfs_rq, struct sched_entity *se) ++static void clear_buddies(struct cfs_rq *cfs_rq, struct sched_entity *se) + { + if (cfs_rq->last == se) + cfs_rq->last = NULL; +@@ -728,12 +728,6 @@ + cfs_rq->next = NULL; + } + +-static void clear_buddies(struct cfs_rq *cfs_rq, struct sched_entity *se) +-{ +- for_each_sched_entity(se) +- __clear_buddies(cfs_rq_of(se), se); +-} +- + static void + dequeue_entity(struct cfs_rq *cfs_rq, struct sched_entity *se, int sleep) + { +@@ -774,14 +768,8 @@ + + ideal_runtime = sched_slice(cfs_rq, curr); + delta_exec = curr->sum_exec_runtime - curr->prev_sum_exec_runtime; +- if (delta_exec > ideal_runtime) { ++ if (delta_exec > ideal_runtime) + resched_task(rq_of(cfs_rq)->curr); +- /* +- * The current task ran long enough, ensure it doesn't get +- * re-elected due to buddy favours. +- */ +- clear_buddies(cfs_rq, curr); +- } + } + + static void +@@ -1464,11 +1452,6 @@ + + do { + se = pick_next_entity(cfs_rq); +- /* +- * If se was a buddy, clear it so that it will have to earn +- * the favour again. +- */ +- __clear_buddies(cfs_rq, se); + set_next_entity(cfs_rq, se); + cfs_rq = group_cfs_rq(se); + } while (cfs_rq); +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/kernel/sched_rt.c linux-2.6.29-rc3.owrt/kernel/sched_rt.c +--- linux-2.6.29.owrt/kernel/sched_rt.c 2009-05-10 22:04:41.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/kernel/sched_rt.c 2009-05-10 23:48:29.000000000 +0200 +@@ -968,8 +968,8 @@ + if ((this_cpu != -1) && cpu_isset(this_cpu, *mask)) + return this_cpu; + +- first = cpumask_first(mask); +- if (first < nr_cpu_ids) ++ first = first_cpu(*mask); ++ if (first != NR_CPUS) + return first; + + return -1; +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/kernel/sched_stats.h linux-2.6.29-rc3.owrt/kernel/sched_stats.h +--- linux-2.6.29.owrt/kernel/sched_stats.h 2009-05-10 22:04:41.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/kernel/sched_stats.h 2009-05-10 23:48:29.000000000 +0200 +@@ -296,21 +296,19 @@ + static inline void account_group_user_time(struct task_struct *tsk, + cputime_t cputime) + { +- struct thread_group_cputimer *cputimer; ++ struct task_cputime *times; ++ struct signal_struct *sig; + + /* tsk == current, ensure it is safe to use ->signal */ + if (unlikely(tsk->exit_state)) + return; + +- cputimer = &tsk->signal->cputimer; +- +- if (!cputimer->running) +- return; ++ sig = tsk->signal; ++ times = &sig->cputime.totals; + +- spin_lock(&cputimer->lock); +- cputimer->cputime.utime = +- cputime_add(cputimer->cputime.utime, cputime); +- spin_unlock(&cputimer->lock); ++ spin_lock(×->lock); ++ times->utime = cputime_add(times->utime, cputime); ++ spin_unlock(×->lock); + } + + /** +@@ -326,21 +324,19 @@ + static inline void account_group_system_time(struct task_struct *tsk, + cputime_t cputime) + { +- struct thread_group_cputimer *cputimer; ++ struct task_cputime *times; ++ struct signal_struct *sig; + + /* tsk == current, ensure it is safe to use ->signal */ + if (unlikely(tsk->exit_state)) + return; + +- cputimer = &tsk->signal->cputimer; +- +- if (!cputimer->running) +- return; ++ sig = tsk->signal; ++ times = &sig->cputime.totals; + +- spin_lock(&cputimer->lock); +- cputimer->cputime.stime = +- cputime_add(cputimer->cputime.stime, cputime); +- spin_unlock(&cputimer->lock); ++ spin_lock(×->lock); ++ times->stime = cputime_add(times->stime, cputime); ++ spin_unlock(×->lock); + } + + /** +@@ -356,7 +352,7 @@ + static inline void account_group_exec_runtime(struct task_struct *tsk, + unsigned long long ns) + { +- struct thread_group_cputimer *cputimer; ++ struct task_cputime *times; + struct signal_struct *sig; + + sig = tsk->signal; +@@ -365,12 +361,9 @@ + if (unlikely(!sig)) + return; + +- cputimer = &sig->cputimer; +- +- if (!cputimer->running) +- return; ++ times = &sig->cputime.totals; + +- spin_lock(&cputimer->lock); +- cputimer->cputime.sum_exec_runtime += ns; +- spin_unlock(&cputimer->lock); ++ spin_lock(×->lock); ++ times->sum_exec_runtime += ns; ++ spin_unlock(×->lock); + } +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/kernel/seccomp.c linux-2.6.29-rc3.owrt/kernel/seccomp.c +--- linux-2.6.29.owrt/kernel/seccomp.c 2009-05-10 22:04:41.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/kernel/seccomp.c 2009-05-10 23:48:29.000000000 +0200 +@@ -8,7 +8,6 @@ + + #include <linux/seccomp.h> + #include <linux/sched.h> +-#include <linux/compat.h> + + /* #define SECCOMP_DEBUG 1 */ + #define NR_SECCOMP_MODES 1 +@@ -23,7 +22,7 @@ + 0, /* null terminated */ + }; + +-#ifdef CONFIG_COMPAT ++#ifdef TIF_32BIT + static int mode1_syscalls_32[] = { + __NR_seccomp_read_32, __NR_seccomp_write_32, __NR_seccomp_exit_32, __NR_seccomp_sigreturn_32, + 0, /* null terminated */ +@@ -38,8 +37,8 @@ + switch (mode) { + case 1: + syscall = mode1_syscalls; +-#ifdef CONFIG_COMPAT +- if (is_compat_task()) ++#ifdef TIF_32BIT ++ if (test_thread_flag(TIF_32BIT)) + syscall = mode1_syscalls_32; + #endif + do { +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/kernel/signal.c linux-2.6.29-rc3.owrt/kernel/signal.c +--- linux-2.6.29.owrt/kernel/signal.c 2009-05-10 22:04:41.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/kernel/signal.c 2009-05-10 23:48:29.000000000 +0200 +@@ -909,9 +909,7 @@ + } + #endif + printk("\n"); +- preempt_disable(); + show_regs(regs); +- preempt_enable(); + } + + static int __init setup_print_fatal_signals(char *str) +@@ -1367,6 +1365,7 @@ + struct siginfo info; + unsigned long flags; + struct sighand_struct *psig; ++ struct task_cputime cputime; + int ret = sig; + + BUG_ON(sig == -1); +@@ -1396,10 +1395,9 @@ + info.si_uid = __task_cred(tsk)->uid; + rcu_read_unlock(); + +- info.si_utime = cputime_to_clock_t(cputime_add(tsk->utime, +- tsk->signal->utime)); +- info.si_stime = cputime_to_clock_t(cputime_add(tsk->stime, +- tsk->signal->stime)); ++ thread_group_cputime(tsk, &cputime); ++ info.si_utime = cputime_to_jiffies(cputime.utime); ++ info.si_stime = cputime_to_jiffies(cputime.stime); + + info.si_status = tsk->exit_code & 0x7f; + if (tsk->exit_code & 0x80) +@@ -1575,15 +1573,7 @@ + read_lock(&tasklist_lock); + if (may_ptrace_stop()) { + do_notify_parent_cldstop(current, CLD_TRAPPED); +- /* +- * Don't want to allow preemption here, because +- * sys_ptrace() needs this task to be inactive. +- * +- * XXX: implement read_unlock_no_resched(). +- */ +- preempt_disable(); + read_unlock(&tasklist_lock); +- preempt_enable_no_resched(); + schedule(); + } else { + /* +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/kernel/smp.c linux-2.6.29-rc3.owrt/kernel/smp.c +--- linux-2.6.29.owrt/kernel/smp.c 2009-05-10 22:04:41.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/kernel/smp.c 2009-05-10 23:48:29.000000000 +0200 +@@ -18,7 +18,6 @@ + enum { + CSD_FLAG_WAIT = 0x01, + CSD_FLAG_ALLOC = 0x02, +- CSD_FLAG_LOCK = 0x04, + }; + + struct call_function_data { +@@ -187,9 +186,6 @@ + if (data_flags & CSD_FLAG_WAIT) { + smp_wmb(); + data->flags &= ~CSD_FLAG_WAIT; +- } else if (data_flags & CSD_FLAG_LOCK) { +- smp_wmb(); +- data->flags &= ~CSD_FLAG_LOCK; + } else if (data_flags & CSD_FLAG_ALLOC) + kfree(data); + } +@@ -200,8 +196,6 @@ + } + } + +-static DEFINE_PER_CPU(struct call_single_data, csd_data); +- + /* + * smp_call_function_single - Run a function on a specific CPU + * @func: The function to run. This must be fast and non-blocking. +@@ -230,38 +224,14 @@ + func(info); + local_irq_restore(flags); + } else if ((unsigned)cpu < nr_cpu_ids && cpu_online(cpu)) { +- struct call_single_data *data; ++ struct call_single_data *data = NULL; + + if (!wait) { +- /* +- * We are calling a function on a single CPU +- * and we are not going to wait for it to finish. +- * We first try to allocate the data, but if we +- * fail, we fall back to use a per cpu data to pass +- * the information to that CPU. Since all callers +- * of this code will use the same data, we must +- * synchronize the callers to prevent a new caller +- * from corrupting the data before the callee +- * can access it. +- * +- * The CSD_FLAG_LOCK is used to let us know when +- * the IPI handler is done with the data. +- * The first caller will set it, and the callee +- * will clear it. The next caller must wait for +- * it to clear before we set it again. This +- * will make sure the callee is done with the +- * data before a new caller will use it. +- */ + data = kmalloc(sizeof(*data), GFP_ATOMIC); + if (data) + data->flags = CSD_FLAG_ALLOC; +- else { +- data = &per_cpu(csd_data, me); +- while (data->flags & CSD_FLAG_LOCK) +- cpu_relax(); +- data->flags = CSD_FLAG_LOCK; +- } +- } else { ++ } ++ if (!data) { + data = &d; + data->flags = CSD_FLAG_WAIT; + } +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/kernel/softirq.c linux-2.6.29-rc3.owrt/kernel/softirq.c +--- linux-2.6.29.owrt/kernel/softirq.c 2009-05-10 22:04:41.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/kernel/softirq.c 2009-05-10 23:48:29.000000000 +0200 +@@ -626,7 +626,6 @@ + preempt_enable_no_resched(); + cond_resched(); + preempt_disable(); +- rcu_qsctr_inc((long)__bind_cpu); + } + preempt_enable(); + set_current_state(TASK_INTERRUPTIBLE); +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/kernel/sys.c linux-2.6.29-rc3.owrt/kernel/sys.c +--- linux-2.6.29.owrt/kernel/sys.c 2009-05-10 22:04:41.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/kernel/sys.c 2009-05-10 23:48:29.000000000 +0200 +@@ -559,7 +559,7 @@ + abort_creds(new); + return retval; + } +- ++ + /* + * change the user struct in a credentials set to match the new UID + */ +@@ -571,11 +571,6 @@ + if (!new_user) + return -EAGAIN; + +- if (!task_can_switch_user(new_user, current)) { +- free_uid(new_user); +- return -EINVAL; +- } +- + if (atomic_read(&new_user->processes) >= + current->signal->rlim[RLIMIT_NPROC].rlim_cur && + new_user != INIT_USER) { +@@ -636,11 +631,10 @@ + goto error; + } + +- if (new->uid != old->uid) { +- retval = set_user(new); +- if (retval < 0) +- goto error; +- } ++ retval = -EAGAIN; ++ if (new->uid != old->uid && set_user(new) < 0) ++ goto error; ++ + if (ruid != (uid_t) -1 || + (euid != (uid_t) -1 && euid != old->uid)) + new->suid = new->euid; +@@ -686,10 +680,9 @@ + retval = -EPERM; + if (capable(CAP_SETUID)) { + new->suid = new->uid = uid; +- if (uid != old->uid) { +- retval = set_user(new); +- if (retval < 0) +- goto error; ++ if (uid != old->uid && set_user(new) < 0) { ++ retval = -EAGAIN; ++ goto error; + } + } else if (uid != old->uid && uid != new->suid) { + goto error; +@@ -741,13 +734,11 @@ + goto error; + } + ++ retval = -EAGAIN; + if (ruid != (uid_t) -1) { + new->uid = ruid; +- if (ruid != old->uid) { +- retval = set_user(new); +- if (retval < 0) +- goto error; +- } ++ if (ruid != old->uid && set_user(new) < 0) ++ goto error; + } + if (euid != (uid_t) -1) + new->euid = euid; +@@ -1534,14 +1525,22 @@ + return -EINVAL; + if (copy_from_user(&new_rlim, rlim, sizeof(*rlim))) + return -EFAULT; +- if (new_rlim.rlim_cur > new_rlim.rlim_max) +- return -EINVAL; + old_rlim = current->signal->rlim + resource; + if ((new_rlim.rlim_max > old_rlim->rlim_max) && + !capable(CAP_SYS_RESOURCE)) + return -EPERM; +- if (resource == RLIMIT_NOFILE && new_rlim.rlim_max > sysctl_nr_open) +- return -EPERM; ++ ++ if (resource == RLIMIT_NOFILE) { ++ if (new_rlim.rlim_max == RLIM_INFINITY) ++ new_rlim.rlim_max = sysctl_nr_open; ++ if (new_rlim.rlim_cur == RLIM_INFINITY) ++ new_rlim.rlim_cur = sysctl_nr_open; ++ if (new_rlim.rlim_max > sysctl_nr_open) ++ return -EPERM; ++ } ++ ++ if (new_rlim.rlim_cur > new_rlim.rlim_max) ++ return -EINVAL; + + retval = security_task_setrlimit(resource, &new_rlim); + if (retval) +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/kernel/sysctl.c linux-2.6.29-rc3.owrt/kernel/sysctl.c +--- linux-2.6.29.owrt/kernel/sysctl.c 2009-05-10 22:04:41.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/kernel/sysctl.c 2009-05-10 23:48:29.000000000 +0200 +@@ -101,7 +101,6 @@ + + static int zero; + static int one = 1; +-static unsigned long one_ul = 1; + static int one_hundred = 100; + + /* this is needed for the proc_dointvec_minmax for [fs_]overflow UID and GID */ +@@ -975,7 +974,7 @@ + .mode = 0644, + .proc_handler = &dirty_background_bytes_handler, + .strategy = &sysctl_intvec, +- .extra1 = &one_ul, ++ .extra1 = &one, + }, + { + .ctl_name = VM_DIRTY_RATIO, +@@ -996,7 +995,7 @@ + .mode = 0644, + .proc_handler = &dirty_bytes_handler, + .strategy = &sysctl_intvec, +- .extra1 = &one_ul, ++ .extra1 = &one, + }, + { + .procname = "dirty_writeback_centisecs", +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/kernel/time/tick-common.c linux-2.6.29-rc3.owrt/kernel/time/tick-common.c +--- linux-2.6.29.owrt/kernel/time/tick-common.c 2009-05-10 22:04:41.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/kernel/time/tick-common.c 2009-05-10 23:48:29.000000000 +0200 +@@ -274,21 +274,6 @@ + } + + /* +- * Transfer the do_timer job away from a dying cpu. +- * +- * Called with interrupts disabled. +- */ +-static void tick_handover_do_timer(int *cpup) +-{ +- if (*cpup == tick_do_timer_cpu) { +- int cpu = cpumask_first(cpu_online_mask); +- +- tick_do_timer_cpu = (cpu < nr_cpu_ids) ? cpu : +- TICK_DO_TIMER_NONE; +- } +-} +- +-/* + * Shutdown an event device on a given cpu: + * + * This is called on a life CPU, when a CPU is dead. So we cannot +@@ -312,6 +297,13 @@ + clockevents_exchange_device(dev, NULL); + td->evtdev = NULL; + } ++ /* Transfer the do_timer job away from this cpu */ ++ if (*cpup == tick_do_timer_cpu) { ++ int cpu = cpumask_first(cpu_online_mask); ++ ++ tick_do_timer_cpu = (cpu < nr_cpu_ids) ? cpu : ++ TICK_DO_TIMER_NONE; ++ } + spin_unlock_irqrestore(&tick_device_lock, flags); + } + +@@ -365,10 +357,6 @@ + tick_broadcast_oneshot_control(reason); + break; + +- case CLOCK_EVT_NOTIFY_CPU_DYING: +- tick_handover_do_timer(dev); +- break; +- + case CLOCK_EVT_NOTIFY_CPU_DEAD: + tick_shutdown_broadcast_oneshot(dev); + tick_shutdown_broadcast(dev); +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/kernel/trace/ftrace.c linux-2.6.29-rc3.owrt/kernel/trace/ftrace.c +--- linux-2.6.29.owrt/kernel/trace/ftrace.c 2009-05-10 22:04:41.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/kernel/trace/ftrace.c 2009-05-10 23:48:29.000000000 +0200 +@@ -17,7 +17,6 @@ + #include <linux/clocksource.h> + #include <linux/kallsyms.h> + #include <linux/seq_file.h> +-#include <linux/suspend.h> + #include <linux/debugfs.h> + #include <linux/hardirq.h> + #include <linux/kthread.h> +@@ -1737,12 +1736,9 @@ + { + struct task_struct *p; + +- rcu_read_lock(); + do_each_pid_task(pid, PIDTYPE_PID, p) { + clear_tsk_trace_trace(p); + } while_each_pid_task(pid, PIDTYPE_PID, p); +- rcu_read_unlock(); +- + put_pid(pid); + } + +@@ -1750,11 +1746,9 @@ + { + struct task_struct *p; + +- rcu_read_lock(); + do_each_pid_task(pid, PIDTYPE_PID, p) { + set_tsk_trace_trace(p); + } while_each_pid_task(pid, PIDTYPE_PID, p); +- rcu_read_unlock(); + } + + static void clear_ftrace_pid_task(struct pid **pid) +@@ -1971,7 +1965,6 @@ + #ifdef CONFIG_FUNCTION_GRAPH_TRACER + + static atomic_t ftrace_graph_active; +-static struct notifier_block ftrace_suspend_notifier; + + int ftrace_graph_entry_stub(struct ftrace_graph_ent *trace) + { +@@ -2033,7 +2026,7 @@ + static int start_graph_tracing(void) + { + struct ftrace_ret_stack **ret_stack_list; +- int ret, cpu; ++ int ret; + + ret_stack_list = kmalloc(FTRACE_RETSTACK_ALLOC_SIZE * + sizeof(struct ftrace_ret_stack *), +@@ -2042,10 +2035,6 @@ + if (!ret_stack_list) + return -ENOMEM; + +- /* The cpu_boot init_task->ret_stack will never be freed */ +- for_each_online_cpu(cpu) +- ftrace_graph_init_task(idle_task(cpu)); +- + do { + ret = alloc_retstack_tasklist(ret_stack_list); + } while (ret == -EAGAIN); +@@ -2054,27 +2043,6 @@ + return ret; + } + +-/* +- * Hibernation protection. +- * The state of the current task is too much unstable during +- * suspend/restore to disk. We want to protect against that. +- */ +-static int +-ftrace_suspend_notifier_call(struct notifier_block *bl, unsigned long state, +- void *unused) +-{ +- switch (state) { +- case PM_HIBERNATION_PREPARE: +- pause_graph_tracing(); +- break; +- +- case PM_POST_HIBERNATION: +- unpause_graph_tracing(); +- break; +- } +- return NOTIFY_DONE; +-} +- + int register_ftrace_graph(trace_func_graph_ret_t retfunc, + trace_func_graph_ent_t entryfunc) + { +@@ -2082,9 +2050,6 @@ + + mutex_lock(&ftrace_sysctl_lock); + +- ftrace_suspend_notifier.notifier_call = ftrace_suspend_notifier_call; +- register_pm_notifier(&ftrace_suspend_notifier); +- + atomic_inc(&ftrace_graph_active); + ret = start_graph_tracing(); + if (ret) { +@@ -2110,7 +2075,6 @@ + ftrace_graph_return = (trace_func_graph_ret_t)ftrace_stub; + ftrace_graph_entry = ftrace_graph_entry_stub; + ftrace_shutdown(FTRACE_STOP_FUNC_RET); +- unregister_pm_notifier(&ftrace_suspend_notifier); + + mutex_unlock(&ftrace_sysctl_lock); + } +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/kernel/trace/Kconfig linux-2.6.29-rc3.owrt/kernel/trace/Kconfig +--- linux-2.6.29.owrt/kernel/trace/Kconfig 2009-05-10 22:04:41.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/kernel/trace/Kconfig 2009-05-10 23:48:29.000000000 +0200 +@@ -52,7 +52,6 @@ + depends on HAVE_FUNCTION_TRACER + depends on DEBUG_KERNEL + select FRAME_POINTER +- select KALLSYMS + select TRACING + select CONTEXT_SWITCH_TRACER + help +@@ -239,7 +238,6 @@ + depends on DEBUG_KERNEL + select FUNCTION_TRACER + select STACKTRACE +- select KALLSYMS + help + This special tracer records the maximum stack footprint of the + kernel and displays it in debugfs/tracing/stack_trace. +@@ -304,27 +302,4 @@ + functioning properly. It will do tests on all the configured + tracers of ftrace. + +-config MMIOTRACE +- bool "Memory mapped IO tracing" +- depends on HAVE_MMIOTRACE_SUPPORT && DEBUG_KERNEL && PCI +- select TRACING +- help +- Mmiotrace traces Memory Mapped I/O access and is meant for +- debugging and reverse engineering. It is called from the ioremap +- implementation and works via page faults. Tracing is disabled by +- default and can be enabled at run-time. +- +- See Documentation/tracers/mmiotrace.txt. +- If you are not helping to develop drivers, say N. +- +-config MMIOTRACE_TEST +- tristate "Test module for mmiotrace" +- depends on MMIOTRACE && m +- help +- This is a dumb module for testing mmiotrace. It is very dangerous +- as it will write garbage to IO memory starting at a given address. +- However, it should be safe to use on e.g. unused portion of VRAM. +- +- Say N, unless you absolutely know what you are doing. +- + endmenu +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/kernel/trace/ring_buffer.c linux-2.6.29-rc3.owrt/kernel/trace/ring_buffer.c +--- linux-2.6.29.owrt/kernel/trace/ring_buffer.c 2009-05-10 22:04:41.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/kernel/trace/ring_buffer.c 2009-05-10 23:48:29.000000000 +0200 +@@ -246,7 +246,7 @@ + return 0; + } + +-#define BUF_PAGE_SIZE (PAGE_SIZE - offsetof(struct buffer_data_page, data)) ++#define BUF_PAGE_SIZE (PAGE_SIZE - sizeof(struct buffer_data_page)) + + /* + * head_page == tail_page && head == tail then buffer is empty. +@@ -1025,8 +1025,12 @@ + } + + if (next_page == head_page) { +- if (!(buffer->flags & RB_FL_OVERWRITE)) ++ if (!(buffer->flags & RB_FL_OVERWRITE)) { ++ /* reset write */ ++ if (tail <= BUF_PAGE_SIZE) ++ local_set(&tail_page->write, tail); + goto out_unlock; ++ } + + /* tail_page has not moved yet? */ + if (tail_page == cpu_buffer->tail_page) { +@@ -1101,10 +1105,6 @@ + return event; + + out_unlock: +- /* reset write */ +- if (tail <= BUF_PAGE_SIZE) +- local_set(&tail_page->write, tail); +- + __raw_spin_unlock(&cpu_buffer->lock); + local_irq_restore(flags); + return NULL; +@@ -2174,9 +2174,6 @@ + + cpu_buffer->overrun = 0; + cpu_buffer->entries = 0; +- +- cpu_buffer->write_stamp = 0; +- cpu_buffer->read_stamp = 0; + } + + /** +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/kernel/trace/trace.c linux-2.6.29-rc3.owrt/kernel/trace/trace.c +--- linux-2.6.29.owrt/kernel/trace/trace.c 2009-05-10 22:04:41.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/kernel/trace/trace.c 2009-05-10 23:48:29.000000000 +0200 +@@ -40,7 +40,7 @@ + + #define TRACE_BUFFER_FLAGS (RB_FL_OVERWRITE) + +-unsigned long __read_mostly tracing_max_latency; ++unsigned long __read_mostly tracing_max_latency = (cycle_t)ULONG_MAX; + unsigned long __read_mostly tracing_thresh; + + /* +@@ -3736,7 +3736,7 @@ + * it if we decide to change what log level the ftrace dump + * should be at. + */ +-#define KERN_TRACE KERN_EMERG ++#define KERN_TRACE KERN_INFO + + static void + trace_printk_seq(struct trace_seq *s) +@@ -3770,7 +3770,6 @@ + dump_ran = 1; + + /* No turning back! */ +- tracing_off(); + ftrace_kill(); + + for_each_tracing_cpu(cpu) { +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/kernel/trace/trace_irqsoff.c linux-2.6.29-rc3.owrt/kernel/trace/trace_irqsoff.c +--- linux-2.6.29.owrt/kernel/trace/trace_irqsoff.c 2009-05-10 22:04:41.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/kernel/trace/trace_irqsoff.c 2009-05-10 23:48:29.000000000 +0200 +@@ -380,7 +380,6 @@ + + static void __irqsoff_tracer_init(struct trace_array *tr) + { +- tracing_max_latency = 0; + irqsoff_trace = tr; + /* make sure that the tracer is visible */ + smp_wmb(); +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/kernel/trace/trace_mmiotrace.c linux-2.6.29-rc3.owrt/kernel/trace/trace_mmiotrace.c +--- linux-2.6.29.owrt/kernel/trace/trace_mmiotrace.c 2009-05-10 22:04:41.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/kernel/trace/trace_mmiotrace.c 2009-05-10 23:48:29.000000000 +0200 +@@ -9,7 +9,6 @@ + #include <linux/kernel.h> + #include <linux/mmiotrace.h> + #include <linux/pci.h> +-#include <asm/atomic.h> + + #include "trace.h" + +@@ -20,7 +19,6 @@ + static struct trace_array *mmio_trace_array; + static bool overrun_detected; + static unsigned long prev_overruns; +-static atomic_t dropped_count; + + static void mmio_reset_data(struct trace_array *tr) + { +@@ -123,11 +121,11 @@ + + static unsigned long count_overruns(struct trace_iterator *iter) + { +- unsigned long cnt = atomic_xchg(&dropped_count, 0); ++ unsigned long cnt = 0; + unsigned long over = ring_buffer_overruns(iter->tr->buffer); + + if (over > prev_overruns) +- cnt += over - prev_overruns; ++ cnt = over - prev_overruns; + prev_overruns = over; + return cnt; + } +@@ -312,10 +310,8 @@ + + event = ring_buffer_lock_reserve(tr->buffer, sizeof(*entry), + &irq_flags); +- if (!event) { +- atomic_inc(&dropped_count); ++ if (!event) + return; +- } + entry = ring_buffer_event_data(event); + tracing_generic_entry_update(&entry->ent, 0, preempt_count()); + entry->ent.type = TRACE_MMIO_RW; +@@ -342,10 +338,8 @@ + + event = ring_buffer_lock_reserve(tr->buffer, sizeof(*entry), + &irq_flags); +- if (!event) { +- atomic_inc(&dropped_count); ++ if (!event) + return; +- } + entry = ring_buffer_event_data(event); + tracing_generic_entry_update(&entry->ent, 0, preempt_count()); + entry->ent.type = TRACE_MMIO_MAP; +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/kernel/trace/trace_sched_wakeup.c linux-2.6.29-rc3.owrt/kernel/trace/trace_sched_wakeup.c +--- linux-2.6.29.owrt/kernel/trace/trace_sched_wakeup.c 2009-05-10 22:04:41.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/kernel/trace/trace_sched_wakeup.c 2009-05-10 23:48:29.000000000 +0200 +@@ -333,7 +333,6 @@ + + static int wakeup_tracer_init(struct trace_array *tr) + { +- tracing_max_latency = 0; + wakeup_trace = tr; + start_wakeup_tracer(tr); + return 0; +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/kernel/trace/trace_selftest.c linux-2.6.29-rc3.owrt/kernel/trace/trace_selftest.c +--- linux-2.6.29.owrt/kernel/trace/trace_selftest.c 2009-05-10 22:04:41.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/kernel/trace/trace_selftest.c 2009-05-10 23:48:29.000000000 +0200 +@@ -23,20 +23,10 @@ + { + struct ring_buffer_event *event; + struct trace_entry *entry; +- unsigned int loops = 0; + + while ((event = ring_buffer_consume(tr->buffer, cpu, NULL))) { + entry = ring_buffer_event_data(event); + +- /* +- * The ring buffer is a size of trace_buf_size, if +- * we loop more than the size, there's something wrong +- * with the ring buffer. +- */ +- if (loops++ > trace_buf_size) { +- printk(KERN_CONT ".. bad ring buffer "); +- goto failed; +- } + if (!trace_valid_entry(entry)) { + printk(KERN_CONT ".. invalid entry %d ", + entry->type); +@@ -67,20 +57,11 @@ + + cnt = ring_buffer_entries(tr->buffer); + +- /* +- * The trace_test_buffer_cpu runs a while loop to consume all data. +- * If the calling tracer is broken, and is constantly filling +- * the buffer, this will run forever, and hard lock the box. +- * We disable the ring buffer while we do this test to prevent +- * a hard lock up. +- */ +- tracing_off(); + for_each_possible_cpu(cpu) { + ret = trace_test_buffer_cpu(tr, cpu); + if (ret) + break; + } +- tracing_on(); + __raw_spin_unlock(&ftrace_max_lock); + local_irq_restore(flags); + +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/kernel/tsacct.c linux-2.6.29-rc3.owrt/kernel/tsacct.c +--- linux-2.6.29.owrt/kernel/tsacct.c 2009-05-10 22:04:41.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/kernel/tsacct.c 2009-05-10 23:48:29.000000000 +0200 +@@ -122,10 +122,8 @@ + if (likely(tsk->mm)) { + cputime_t time, dtime; + struct timeval value; +- unsigned long flags; + u64 delta; + +- local_irq_save(flags); + time = tsk->stime + tsk->utime; + dtime = cputime_sub(time, tsk->acct_timexpd); + jiffies_to_timeval(cputime_to_jiffies(dtime), &value); +@@ -133,12 +131,10 @@ + delta = delta * USEC_PER_SEC + value.tv_usec; + + if (delta == 0) +- goto out; ++ return; + tsk->acct_timexpd = time; + tsk->acct_rss_mem1 += delta * get_mm_rss(tsk->mm); + tsk->acct_vm_mem1 += delta * tsk->mm->total_vm; +- out: +- local_irq_restore(flags); + } + } + +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/kernel/user.c linux-2.6.29-rc3.owrt/kernel/user.c +--- linux-2.6.29.owrt/kernel/user.c 2009-05-10 22:04:41.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/kernel/user.c 2009-05-10 23:48:29.000000000 +0200 +@@ -72,7 +72,6 @@ + static void uid_hash_remove(struct user_struct *up) + { + hlist_del_init(&up->uidhash_node); +- put_user_ns(up->user_ns); + } + + static struct user_struct *uid_hash_find(uid_t uid, struct hlist_head *hashent) +@@ -286,12 +285,14 @@ + /* work function to remove sysfs directory for a user and free up + * corresponding structures. + */ +-static void cleanup_user_struct(struct work_struct *w) ++static void remove_user_sysfs_dir(struct work_struct *w) + { + struct user_struct *up = container_of(w, struct user_struct, work); + unsigned long flags; + int remove_user = 0; + ++ if (up->user_ns != &init_user_ns) ++ return; + /* Make uid_hash_remove() + sysfs_remove_file() + kobject_del() + * atomic. + */ +@@ -310,11 +311,9 @@ + if (!remove_user) + goto done; + +- if (up->user_ns == &init_user_ns) { +- kobject_uevent(&up->kobj, KOBJ_REMOVE); +- kobject_del(&up->kobj); +- kobject_put(&up->kobj); +- } ++ kobject_uevent(&up->kobj, KOBJ_REMOVE); ++ kobject_del(&up->kobj); ++ kobject_put(&up->kobj); + + sched_destroy_user(up); + key_put(up->uid_keyring); +@@ -335,7 +334,8 @@ + atomic_inc(&up->__count); + spin_unlock_irqrestore(&uidhash_lock, flags); + +- INIT_WORK(&up->work, cleanup_user_struct); ++ put_user_ns(up->user_ns); ++ INIT_WORK(&up->work, remove_user_sysfs_dir); + schedule_work(&up->work); + } + +@@ -357,29 +357,12 @@ + sched_destroy_user(up); + key_put(up->uid_keyring); + key_put(up->session_keyring); ++ put_user_ns(up->user_ns); + kmem_cache_free(uid_cachep, up); + } + + #endif + +-#if defined(CONFIG_RT_GROUP_SCHED) && defined(CONFIG_USER_SCHED) +-/* +- * We need to check if a setuid can take place. This function should be called +- * before successfully completing the setuid. +- */ +-int task_can_switch_user(struct user_struct *up, struct task_struct *tsk) +-{ +- +- return sched_rt_can_attach(up->tg, tsk); +- +-} +-#else +-int task_can_switch_user(struct user_struct *up, struct task_struct *tsk) +-{ +- return 1; +-} +-#endif +- + /* + * Locate the user_struct for the passed UID. If found, take a ref on it. The + * caller must undo that ref with free_uid(). +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/kernel/user_namespace.c linux-2.6.29-rc3.owrt/kernel/user_namespace.c +--- linux-2.6.29.owrt/kernel/user_namespace.c 2009-05-10 22:04:41.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/kernel/user_namespace.c 2009-05-10 23:48:29.000000000 +0200 +@@ -60,25 +60,12 @@ + return 0; + } + +-/* +- * Deferred destructor for a user namespace. This is required because +- * free_user_ns() may be called with uidhash_lock held, but we need to call +- * back to free_uid() which will want to take the lock again. +- */ +-static void free_user_ns_work(struct work_struct *work) +-{ +- struct user_namespace *ns = +- container_of(work, struct user_namespace, destroyer); +- free_uid(ns->creator); +- kfree(ns); +-} +- + void free_user_ns(struct kref *kref) + { +- struct user_namespace *ns = +- container_of(kref, struct user_namespace, kref); ++ struct user_namespace *ns; + +- INIT_WORK(&ns->destroyer, free_user_ns_work); +- schedule_work(&ns->destroyer); ++ ns = container_of(kref, struct user_namespace, kref); ++ free_uid(ns->creator); ++ kfree(ns); + } + EXPORT_SYMBOL(free_user_ns); +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/kernel/wait.c linux-2.6.29-rc3.owrt/kernel/wait.c +--- linux-2.6.29.owrt/kernel/wait.c 2009-05-10 22:04:41.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/kernel/wait.c 2009-05-10 23:48:29.000000000 +0200 +@@ -91,15 +91,6 @@ + } + EXPORT_SYMBOL(prepare_to_wait_exclusive); + +-/* +- * finish_wait - clean up after waiting in a queue +- * @q: waitqueue waited on +- * @wait: wait descriptor +- * +- * Sets current thread back to running state and removes +- * the wait descriptor from the given waitqueue if still +- * queued. +- */ + void finish_wait(wait_queue_head_t *q, wait_queue_t *wait) + { + unsigned long flags; +@@ -126,39 +117,6 @@ + } + EXPORT_SYMBOL(finish_wait); + +-/* +- * abort_exclusive_wait - abort exclusive waiting in a queue +- * @q: waitqueue waited on +- * @wait: wait descriptor +- * @state: runstate of the waiter to be woken +- * @key: key to identify a wait bit queue or %NULL +- * +- * Sets current thread back to running state and removes +- * the wait descriptor from the given waitqueue if still +- * queued. +- * +- * Wakes up the next waiter if the caller is concurrently +- * woken up through the queue. +- * +- * This prevents waiter starvation where an exclusive waiter +- * aborts and is woken up concurrently and noone wakes up +- * the next waiter. +- */ +-void abort_exclusive_wait(wait_queue_head_t *q, wait_queue_t *wait, +- unsigned int mode, void *key) +-{ +- unsigned long flags; +- +- __set_current_state(TASK_RUNNING); +- spin_lock_irqsave(&q->lock, flags); +- if (!list_empty(&wait->task_list)) +- list_del_init(&wait->task_list); +- else if (waitqueue_active(q)) +- __wake_up_common(q, mode, 1, 0, key); +- spin_unlock_irqrestore(&q->lock, flags); +-} +-EXPORT_SYMBOL(abort_exclusive_wait); +- + int autoremove_wake_function(wait_queue_t *wait, unsigned mode, int sync, void *key) + { + int ret = default_wake_function(wait, mode, sync, key); +@@ -219,20 +177,17 @@ + __wait_on_bit_lock(wait_queue_head_t *wq, struct wait_bit_queue *q, + int (*action)(void *), unsigned mode) + { +- do { +- int ret; ++ int ret = 0; + ++ do { + prepare_to_wait_exclusive(wq, &q->wait, mode); +- if (!test_bit(q->key.bit_nr, q->key.flags)) +- continue; +- ret = action(q->key.flags); +- if (!ret) +- continue; +- abort_exclusive_wait(wq, &q->wait, mode, &q->key); +- return ret; ++ if (test_bit(q->key.bit_nr, q->key.flags)) { ++ if ((ret = (*action)(q->key.flags))) ++ break; ++ } + } while (test_and_set_bit(q->key.bit_nr, q->key.flags)); + finish_wait(wq, &q->wait); +- return 0; ++ return ret; + } + EXPORT_SYMBOL(__wait_on_bit_lock); + +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/lib/bitmap.c linux-2.6.29-rc3.owrt/lib/bitmap.c +--- linux-2.6.29.owrt/lib/bitmap.c 2009-05-10 22:04:41.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/lib/bitmap.c 2009-05-10 23:48:29.000000000 +0200 +@@ -948,15 +948,15 @@ + */ + int bitmap_find_free_region(unsigned long *bitmap, int bits, int order) + { +- int pos, end; /* scans bitmap by regions of size order */ ++ int pos; /* scans bitmap by regions of size order */ + +- for (pos = 0 ; (end = pos + (1 << order)) <= bits; pos = end) { +- if (!__reg_op(bitmap, pos, order, REG_OP_ISFREE)) +- continue; +- __reg_op(bitmap, pos, order, REG_OP_ALLOC); +- return pos; +- } +- return -ENOMEM; ++ for (pos = 0; pos < bits; pos += (1 << order)) ++ if (__reg_op(bitmap, pos, order, REG_OP_ISFREE)) ++ break; ++ if (pos == bits) ++ return -ENOMEM; ++ __reg_op(bitmap, pos, order, REG_OP_ALLOC); ++ return pos; + } + EXPORT_SYMBOL(bitmap_find_free_region); + +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/lib/idr.c linux-2.6.29-rc3.owrt/lib/idr.c +--- linux-2.6.29.owrt/lib/idr.c 2009-05-10 22:04:41.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/lib/idr.c 2009-05-10 23:48:29.000000000 +0200 +@@ -449,7 +449,6 @@ + + n = idp->layers * IDR_BITS; + p = idp->top; +- rcu_assign_pointer(idp->top, NULL); + max = 1 << n; + + id = 0; +@@ -468,6 +467,7 @@ + p = *--paa; + } + } ++ rcu_assign_pointer(idp->top, NULL); + idp->layers = 0; + } + EXPORT_SYMBOL(idr_remove_all); +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/lib/Kconfig.debug linux-2.6.29-rc3.owrt/lib/Kconfig.debug +--- linux-2.6.29.owrt/lib/Kconfig.debug 2009-05-10 22:04:41.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/lib/Kconfig.debug 2009-05-10 23:48:29.000000000 +0200 +@@ -838,7 +838,7 @@ + + If unsure, say N. + +-config BUILD_DOCSRC ++menuconfig BUILD_DOCSRC + bool "Build targets in Documentation/ tree" + depends on HEADERS_CHECK + help +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/lib/smp_processor_id.c linux-2.6.29-rc3.owrt/lib/smp_processor_id.c +--- linux-2.6.29.owrt/lib/smp_processor_id.c 2009-05-10 22:04:41.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/lib/smp_processor_id.c 2009-05-10 23:48:29.000000000 +0200 +@@ -22,7 +22,7 @@ + * Kernel threads bound to a single CPU can safely use + * smp_processor_id(): + */ +- if (cpumask_equal(¤t->cpus_allowed, cpumask_of(this_cpu))) ++ if (cpus_equal(current->cpus_allowed, cpumask_of_cpu(this_cpu))) + goto out; + + /* +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/.mailmap linux-2.6.29-rc3.owrt/.mailmap +--- linux-2.6.29.owrt/.mailmap 2009-05-10 22:04:41.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/.mailmap 2009-05-10 23:48:29.000000000 +0200 +@@ -92,7 +92,6 @@ + Rui Saraiva <rmps@joel.ist.utl.pt> + Sachin P Sant <ssant@in.ibm.com> + Sam Ravnborg <sam@mars.ravnborg.org> +-Sascha Hauer <s.hauer@pengutronix.de> + S.ÇaÄŸlar Onur <caglar@pardus.org.tr> + Simon Kelley <simon@thekelleys.org.uk> + Stéphane Witzmann <stephane.witzmann@ubpmes.univ-bpclermont.fr> +@@ -101,7 +100,6 @@ + Thomas Graf <tgraf@suug.ch> + Tony Luck <tony.luck@intel.com> + Tsuneo Yoshioka <Tsuneo.Yoshioka@f-secure.com> +-Uwe Kleine-König <ukleinek@informatik.uni-freiburg.de> +-Uwe Kleine-König <ukl@pengutronix.de> + Uwe Kleine-König <Uwe.Kleine-Koenig@digi.com> ++Uwe Kleine-König <ukleinek@informatik.uni-freiburg.de> + Valdis Kletnieks <Valdis.Kletnieks@vt.edu> +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/MAINTAINERS linux-2.6.29-rc3.owrt/MAINTAINERS +--- linux-2.6.29.owrt/MAINTAINERS 2009-05-10 22:04:39.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/MAINTAINERS 2009-05-10 23:48:33.000000000 +0200 +@@ -692,13 +692,6 @@ + L: linux-arm-kernel@lists.arm.linux.org.uk (subscribers-only) + S: Maintained + +-ARM/NUVOTON W90X900 ARM ARCHITECTURE +-P: Wan ZongShun +-M: mcuos.com@gmail.com +-L: linux-arm-kernel@lists.arm.linux.org.uk (subscribers-only) +-W: http://www.mcuos.com +-S: Maintained +- + ARPD SUPPORT + P: Jonathan Layes + L: netdev@vger.kernel.org +@@ -918,7 +911,7 @@ + BLACKFIN ARCHITECTURE + P: Bryan Wu + M: cooloney@kernel.org +-L: uclinux-dist-devel@blackfin.uclinux.org ++L: uclinux-dist-devel@blackfin.uclinux.org (subscribers-only) + W: http://blackfin.uclinux.org + S: Supported + +@@ -1028,14 +1021,6 @@ + W: http://bu3sch.de/btgpio.php + S: Maintained + +-BTRFS FILE SYSTEM +-P: Chris Mason +-M: chris.mason@oracle.com +-L: linux-btrfs@vger.kernel.org +-W: http://btrfs.wiki.kernel.org/ +-T: git kernel.org:/pub/scm/linux/kernel/git/mason/btrfs-unstable.git +-S: Maintained +- + BTTV VIDEO4LINUX DRIVER + P: Mauro Carvalho Chehab + M: mchehab@infradead.org +@@ -1209,8 +1194,6 @@ + CONTROL GROUPS (CGROUPS) + P: Paul Menage + M: menage@google.com +-P: Li Zefan +-M: lizf@cn.fujitsu.com + L: containers@lists.linux-foundation.org + S: Maintained + +@@ -1469,6 +1452,8 @@ + S: Supported + + DOCUMENTATION (/Documentation directory) ++P: Michael Kerrisk ++M: mtk.manpages@gmail.com + P: Randy Dunlap + M: rdunlap@xenotime.net + L: linux-doc@vger.kernel.org +@@ -1910,10 +1895,10 @@ + S: Maintained + + HARD DRIVE ACTIVE PROTECTION SYSTEM (HDAPS) DRIVER +-P: Frank Seidel +-M: frank@f-seidel.de +-L: lm-sensors@lm-sensors.org +-W: http://www.kernel.org/pub/linux/kernel/people/fseidel/hdaps/ ++P: Robert Love ++M: rlove@rlove.org ++M: linux-kernel@vger.kernel.org ++W: http://www.kernel.org/pub/linux/kernel/people/rml/hdaps/ + S: Maintained + + GSPCA FINEPIX SUBDRIVER +@@ -2011,7 +1996,7 @@ + + HIBERNATION (aka Software Suspend, aka swsusp) + P: Pavel Machek +-M: pavel@ucw.cz ++M: pavel@suse.cz + P: Rafael J. Wysocki + M: rjw@sisk.pl + L: linux-pm@lists.linux-foundation.org +@@ -2232,7 +2217,7 @@ + M: sean.hefty@intel.com + P: Hal Rosenstock + M: hal.rosenstock@gmail.com +-L: general@lists.openfabrics.org (moderated for non-subscribers) ++L: general@lists.openfabrics.org + W: http://www.openib.org/ + T: git kernel.org:/pub/scm/linux/kernel/git/roland/infiniband.git + S: Supported +@@ -2467,7 +2452,7 @@ + + ISDN SUBSYSTEM + P: Karsten Keil +-M: isdn@linux-pingi.de ++M: kkeil@suse.de + L: isdn4linux@listserv.isdn4linux.de (subscribers-only) + W: http://www.isdn4linux.de + T: git kernel.org:/pub/scm/linux/kernel/kkeil/isdn-2.6.git +@@ -2856,6 +2841,8 @@ + MAC80211 + P: Johannes Berg + M: johannes@sipsolutions.net ++P: Michael Wu ++M: flamingice@sourmilk.net + L: linux-wireless@vger.kernel.org + W: http://linuxwireless.org/ + T: git kernel.org:/pub/scm/linux/kernel/git/linville/wireless-2.6.git +@@ -2882,7 +2869,7 @@ + M: mtk.manpages@gmail.com + W: http://www.kernel.org/doc/man-pages + L: linux-man@vger.kernel.org +-S: Maintained ++S: Supported + + MARVELL LIBERTAS WIRELESS DRIVER + P: Dan Williams +@@ -3337,8 +3324,8 @@ + M: jeremy@xensource.com + P: Chris Wright + M: chrisw@sous-sol.org +-P: Alok Kataria +-M: akataria@vmware.com ++P: Zachary Amsden ++M: zach@vmware.com + P: Rusty Russell + M: rusty@rustcorp.com.au + L: virtualization@lists.osdl.org +@@ -3355,8 +3342,10 @@ + PARISC ARCHITECTURE + P: Kyle McMartin + M: kyle@mcmartin.ca +-P: Helge Deller +-M: deller@gmx.de ++P: Matthew Wilcox ++M: matthew@wil.cx ++P: Grant Grundler ++M: grundler@parisc-linux.org + L: linux-parisc@vger.kernel.org + W: http://www.parisc-linux.org/ + T: git kernel.org:/pub/scm/linux/kernel/git/kyle/parisc-2.6.git +@@ -3547,12 +3536,6 @@ + PXA MMCI DRIVER + S: Orphan + +-PXA RTC DRIVER +-P: Robert Jarzmik +-M: robert.jarzmik@free.fr +-L: rtc-linux@googlegroups.com +-S: Maintained +- + QLOGIC QLA2XXX FC-SCSI DRIVER + P: Andrew Vasquez + M: linux-driver@qlogic.com +@@ -3881,15 +3864,6 @@ + T: git kernel.org:/pub/scm/linux/kernel/git/jgarzik/libata-dev.git + S: Supported + +-SERVER ENGINES 10Gbps NIC - BladeEngine 2 DRIVER +-P: Sathya Perla +-M: sathyap@serverengines.com +-P: Subbu Seetharaman +-M: subbus@serverengines.com +-L: netdev@vger.kernel.org +-W: http://www.serverengines.com +-S: Supported +- + SFC NETWORK DRIVER + P: Steve Hodgson + P: Ben Hutchings +@@ -4189,7 +4163,7 @@ + P: Len Brown + M: len.brown@intel.com + P: Pavel Machek +-M: pavel@ucw.cz ++M: pavel@suse.cz + P: Rafael J. Wysocki + M: rjw@sisk.pl + L: linux-pm@lists.linux-foundation.org +@@ -4310,8 +4284,8 @@ + M: srajiv@linux.vnet.ibm.com + W: http://tpmdd.sourceforge.net + P: Marcel Selhorst +-M: m.selhorst@sirrix.com +-W: http://www.sirrix.com ++M: tpm@selhorst.net ++W: http://www.prosec.rub.de/tpm/ + L: tpmdd-devel@lists.sourceforge.net (moderated for non-subscribers) + S: Maintained + +@@ -4874,7 +4848,6 @@ + M: mingo@redhat.com + P: H. Peter Anvin + M: hpa@zytor.com +-M: x86@kernel.org + L: linux-kernel@vger.kernel.org + T: git://git.kernel.org/pub/scm/linux/kernel/git/x86/linux-2.6-x86.git + S: Maintained +@@ -4941,11 +4914,11 @@ + S: Maintained + + ZR36067 VIDEO FOR LINUX DRIVER ++P: Ronald Bultje ++M: rbultje@ronald.bitfreak.net + L: mjpeg-users@lists.sourceforge.net +-L: linux-media@vger.kernel.org + W: http://mjpeg.sourceforge.net/driver-zoran/ +-T: Mercurial http://linuxtv.org/hg/v4l-dvb +-S: Odd Fixes ++S: Maintained + + ZS DECSTATION Z85C30 SERIAL DRIVER + P: Maciej W. Rozycki +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/Makefile linux-2.6.29-rc3.owrt/Makefile +--- linux-2.6.29.owrt/Makefile 2009-05-10 22:04:41.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/Makefile 2009-05-10 23:48:33.000000000 +0200 +@@ -2,7 +2,7 @@ + PATCHLEVEL = 6 + SUBLEVEL = 29 + EXTRAVERSION = +-NAME = Temporary Tasmanian Devil ++NAME = Erotic Pickled Herring + + # *DOCUMENTATION* + # To see a list of typical targets execute "make help" +@@ -389,7 +389,6 @@ + # output directory. + outputmakefile: + ifneq ($(KBUILD_SRC),) +- $(Q)ln -fsn $(srctree) source + $(Q)$(CONFIG_SHELL) $(srctree)/scripts/mkmakefile \ + $(srctree) $(objtree) $(VERSION) $(PATCHLEVEL) + endif +@@ -569,12 +568,6 @@ + # disable pointer signed / unsigned warnings in gcc 4.0 + KBUILD_CFLAGS += $(call cc-option,-Wno-pointer-sign,) + +-# disable invalid "can't wrap" optimzations for signed / pointers +-KBUILD_CFLAGS += $(call cc-option,-fwrapv) +- +-# revert to pre-gcc-4.4 behaviour of .eh_frame +-KBUILD_CFLAGS += $(call cc-option,-fno-dwarf2-cfi-asm) +- + # Add user supplied CPPFLAGS, AFLAGS and CFLAGS as the last assignments + # But warn user when we do so + warn-assign = \ +@@ -913,18 +906,12 @@ + # and if the SCM is know a tag from the SCM is appended. + # The appended tag is determined by the SCM used. + # +-# .scmversion is used when generating rpm packages so we do not loose +-# the version information from the SCM when we do the build of the kernel +-# from the copied source ++# Currently, only git is supported. ++# Other SCMs can edit scripts/setlocalversion and add the appropriate ++# checks as needed. + ifdef CONFIG_LOCALVERSION_AUTO +- +-ifeq ($(wildcard .scmversion),) +- _localver-auto = $(shell $(CONFIG_SHELL) \ +- $(srctree)/scripts/setlocalversion $(srctree)) +-else +- _localver-auto = $(shell cat .scmversion 2> /dev/null) +-endif +- ++ _localver-auto = $(shell $(CONFIG_SHELL) \ ++ $(srctree)/scripts/setlocalversion $(srctree)) + localver-auto = $(LOCALVERSION)$(_localver-auto) + endif + +@@ -962,6 +949,7 @@ + mkdir -p include2; \ + ln -fsn $(srctree)/include/asm-$(SRCARCH) include2/asm; \ + fi ++ ln -fsn $(srctree) source + endif + + # prepare2 creates a makefile if using a separate output directory +@@ -1552,7 +1540,7 @@ + cmd_depmod = \ + if [ -r System.map -a -x $(DEPMOD) ]; then \ + $(DEPMOD) -ae -F System.map \ +- $(if $(strip $(INSTALL_MOD_PATH)), -b $(INSTALL_MOD_PATH) ) \ ++ $(if $(strip $(INSTALL_MOD_PATH)), -b $(INSTALL_MOD_PATH) -r) \ + $(KERNELRELEASE); \ + fi + +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/mm/fremap.c linux-2.6.29-rc3.owrt/mm/fremap.c +--- linux-2.6.29.owrt/mm/fremap.c 2009-05-10 22:04:39.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/mm/fremap.c 2009-05-10 23:48:33.000000000 +0200 +@@ -198,7 +198,7 @@ + flags &= MAP_NONBLOCK; + get_file(file); + addr = mmap_region(file, start, size, +- flags, vma->vm_flags, pgoff); ++ flags, vma->vm_flags, pgoff, 1); + fput(file); + if (IS_ERR_VALUE(addr)) { + err = addr; +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/mm/hugetlb.c linux-2.6.29-rc3.owrt/mm/hugetlb.c +--- linux-2.6.29.owrt/mm/hugetlb.c 2009-05-10 22:04:39.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/mm/hugetlb.c 2009-05-10 23:48:33.000000000 +0200 +@@ -2269,18 +2269,12 @@ + + int hugetlb_reserve_pages(struct inode *inode, + long from, long to, +- struct vm_area_struct *vma, +- int acctflag) ++ struct vm_area_struct *vma) + { + long ret, chg; + struct hstate *h = hstate_inode(inode); + +- /* +- * Only apply hugepage reservation if asked. At fault time, an +- * attempt will be made for VM_NORESERVE to allocate a page +- * and filesystem quota without using reserves +- */ +- if (acctflag & VM_NORESERVE) ++ if (vma && vma->vm_flags & VM_NORESERVE) + return 0; + + /* +@@ -2305,31 +2299,13 @@ + if (chg < 0) + return chg; + +- /* There must be enough filesystem quota for the mapping */ + if (hugetlb_get_quota(inode->i_mapping, chg)) + return -ENOSPC; +- +- /* +- * Check enough hugepages are available for the reservation. +- * Hand back the quota if there are not +- */ + ret = hugetlb_acct_memory(h, chg); + if (ret < 0) { + hugetlb_put_quota(inode->i_mapping, chg); + return ret; + } +- +- /* +- * Account for the reservations made. Shared mappings record regions +- * that have reservations as they are shared by multiple VMAs. +- * When the last VMA disappears, the region map says how much +- * the reservation was and the page cache tells how much of +- * the reservation was consumed. Private mappings are per-VMA and +- * only the consumed reservations are tracked. When the VMA +- * disappears, the original reservation is the VMA size and the +- * consumed reservations are stored in the map. Hence, nothing +- * else has to be done for private mappings here +- */ + if (!vma || vma->vm_flags & VM_SHARED) + region_add(&inode->i_mapping->private_list, from, to); + return 0; +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/mm/memcontrol.c linux-2.6.29-rc3.owrt/mm/memcontrol.c +--- linux-2.6.29.owrt/mm/memcontrol.c 2009-05-10 22:04:39.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/mm/memcontrol.c 2009-05-10 23:48:33.000000000 +0200 +@@ -202,7 +202,6 @@ + + static void mem_cgroup_get(struct mem_cgroup *mem); + static void mem_cgroup_put(struct mem_cgroup *mem); +-static struct mem_cgroup *parent_mem_cgroup(struct mem_cgroup *mem); + + static void mem_cgroup_charge_statistics(struct mem_cgroup *mem, + struct page_cgroup *pc, +@@ -1685,7 +1684,7 @@ + /* This is for making all *used* pages to be on LRU. */ + lru_add_drain_all(); + ret = 0; +- for_each_node_state(node, N_HIGH_MEMORY) { ++ for_each_node_state(node, N_POSSIBLE) { + for (zid = 0; !ret && zid < MAX_NR_ZONES; zid++) { + enum lru_list l; + for_each_lru(l) { +@@ -2194,23 +2193,10 @@ + + static void mem_cgroup_put(struct mem_cgroup *mem) + { +- if (atomic_dec_and_test(&mem->refcnt)) { +- struct mem_cgroup *parent = parent_mem_cgroup(mem); ++ if (atomic_dec_and_test(&mem->refcnt)) + __mem_cgroup_free(mem); +- if (parent) +- mem_cgroup_put(parent); +- } + } + +-/* +- * Returns the parent mem_cgroup in memcgroup hierarchy with hierarchy enabled. +- */ +-static struct mem_cgroup *parent_mem_cgroup(struct mem_cgroup *mem) +-{ +- if (!mem->res.parent) +- return NULL; +- return mem_cgroup_from_res_counter(mem->res.parent, res); +-} + + #ifdef CONFIG_CGROUP_MEM_RES_CTLR_SWAP + static void __init enable_swap_cgroup(void) +@@ -2249,13 +2235,6 @@ + if (parent && parent->use_hierarchy) { + res_counter_init(&mem->res, &parent->res); + res_counter_init(&mem->memsw, &parent->memsw); +- /* +- * We increment refcnt of the parent to ensure that we can +- * safely access it on res_counter_charge/uncharge. +- * This refcnt will be decremented when freeing this +- * mem_cgroup(see mem_cgroup_put). +- */ +- mem_cgroup_get(parent); + } else { + res_counter_init(&mem->res, NULL); + res_counter_init(&mem->memsw, NULL); +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/mm/memory.c linux-2.6.29-rc3.owrt/mm/memory.c +--- linux-2.6.29.owrt/mm/memory.c 2009-05-10 22:04:39.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/mm/memory.c 2009-05-10 23:48:33.000000000 +0200 +@@ -2000,7 +2000,7 @@ + * Don't let another task, with possibly unlocked vma, + * keep the mlocked page. + */ +- if ((vma->vm_flags & VM_LOCKED) && old_page) { ++ if (vma->vm_flags & VM_LOCKED) { + lock_page(old_page); /* for LRU manipulation */ + clear_page_mlock(old_page); + unlock_page(old_page); +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/mm/migrate.c linux-2.6.29-rc3.owrt/mm/migrate.c +--- linux-2.6.29.owrt/mm/migrate.c 2009-05-10 22:04:39.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/mm/migrate.c 2009-05-10 23:48:33.000000000 +0200 +@@ -1129,7 +1129,7 @@ + struct vm_area_struct *vma; + int err = 0; + +- for (vma = mm->mmap; vma && !err; vma = vma->vm_next) { ++ for(vma = mm->mmap; vma->vm_next && !err; vma = vma->vm_next) { + if (vma->vm_ops && vma->vm_ops->migrate) { + err = vma->vm_ops->migrate(vma, to, from, flags); + if (err) +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/mm/mlock.c linux-2.6.29-rc3.owrt/mm/mlock.c +--- linux-2.6.29.owrt/mm/mlock.c 2009-05-10 22:04:39.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/mm/mlock.c 2009-05-10 23:48:33.000000000 +0200 +@@ -294,10 +294,14 @@ + * + * return number of pages [> 0] to be removed from locked_vm on success + * of "special" vmas. ++ * ++ * return negative error if vma spanning @start-@range disappears while ++ * mmap semaphore is dropped. Unlikely? + */ + long mlock_vma_pages_range(struct vm_area_struct *vma, + unsigned long start, unsigned long end) + { ++ struct mm_struct *mm = vma->vm_mm; + int nr_pages = (end - start) / PAGE_SIZE; + BUG_ON(!(vma->vm_flags & VM_LOCKED)); + +@@ -310,11 +314,20 @@ + if (!((vma->vm_flags & (VM_DONTEXPAND | VM_RESERVED)) || + is_vm_hugetlb_page(vma) || + vma == get_gate_vma(current))) { ++ long error; ++ downgrade_write(&mm->mmap_sem); + +- __mlock_vma_pages_range(vma, start, end, 1); ++ error = __mlock_vma_pages_range(vma, start, end, 1); + +- /* Hide errors from mmap() and other callers */ +- return 0; ++ up_read(&mm->mmap_sem); ++ /* vma can change or disappear */ ++ down_write(&mm->mmap_sem); ++ vma = find_vma(mm, start); ++ /* non-NULL vma must contain @start, but need to check @end */ ++ if (!vma || end > vma->vm_end) ++ return -ENOMEM; ++ ++ return 0; /* hide other errors from mmap(), et al */ + } + + /* +@@ -425,14 +438,41 @@ + vma->vm_flags = newflags; + + if (lock) { ++ /* ++ * mmap_sem is currently held for write. Downgrade the write ++ * lock to a read lock so that other faults, mmap scans, ... ++ * while we fault in all pages. ++ */ ++ downgrade_write(&mm->mmap_sem); ++ + ret = __mlock_vma_pages_range(vma, start, end, 1); + +- if (ret > 0) { ++ /* ++ * Need to reacquire mmap sem in write mode, as our callers ++ * expect this. We have no support for atomically upgrading ++ * a sem to write, so we need to check for ranges while sem ++ * is unlocked. ++ */ ++ up_read(&mm->mmap_sem); ++ /* vma can change or disappear */ ++ down_write(&mm->mmap_sem); ++ *prev = find_vma(mm, start); ++ /* non-NULL *prev must contain @start, but need to check @end */ ++ if (!(*prev) || end > (*prev)->vm_end) ++ ret = -ENOMEM; ++ else if (ret > 0) { + mm->locked_vm -= ret; + ret = 0; + } else + ret = __mlock_posix_error_return(ret); /* translate if needed */ + } else { ++ /* ++ * TODO: for unlocking, pages will already be resident, so ++ * we don't need to wait for allocations/reclaim/pagein, ... ++ * However, unlocking a very large region can still take a ++ * while. Should we downgrade the semaphore for both lock ++ * AND unlock ? ++ */ + __mlock_vma_pages_range(vma, start, end, 0); + } + +@@ -660,7 +700,7 @@ + return buffer; + } + +-void release_locked_buffer(void *buffer, size_t size) ++void free_locked_buffer(void *buffer, size_t size) + { + unsigned long pgsz = PAGE_ALIGN(size) >> PAGE_SHIFT; + +@@ -670,11 +710,6 @@ + current->mm->locked_vm -= pgsz; + + up_write(¤t->mm->mmap_sem); +-} +- +-void free_locked_buffer(void *buffer, size_t size) +-{ +- release_locked_buffer(buffer, size); + + kfree(buffer); + } +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/mm/mmap.c linux-2.6.29-rc3.owrt/mm/mmap.c +--- linux-2.6.29.owrt/mm/mmap.c 2009-05-10 22:04:39.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/mm/mmap.c 2009-05-10 23:48:33.000000000 +0200 +@@ -658,9 +658,6 @@ + validate_mm(mm); + } + +-/* Flags that can be inherited from an existing mapping when merging */ +-#define VM_MERGEABLE_FLAGS (VM_CAN_NONLINEAR) +- + /* + * If the vma has a ->close operation then the driver probably needs to release + * per-vma resources, so we don't attempt to merge those. +@@ -668,7 +665,7 @@ + static inline int is_mergeable_vma(struct vm_area_struct *vma, + struct file *file, unsigned long vm_flags) + { +- if ((vma->vm_flags ^ vm_flags) & ~VM_MERGEABLE_FLAGS) ++ if (vma->vm_flags != vm_flags) + return 0; + if (vma->vm_file != file) + return 0; +@@ -918,6 +915,7 @@ + struct inode *inode; + unsigned int vm_flags; + int error; ++ int accountable = 1; + unsigned long reqprot = prot; + + /* +@@ -1018,6 +1016,8 @@ + return -EPERM; + vm_flags &= ~VM_MAYEXEC; + } ++ if (is_file_hugepages(file)) ++ accountable = 0; + + if (!file->f_op || !file->f_op->mmap) + return -ENODEV; +@@ -1050,7 +1050,8 @@ + if (error) + return error; + +- return mmap_region(file, addr, len, flags, vm_flags, pgoff); ++ return mmap_region(file, addr, len, flags, vm_flags, pgoff, ++ accountable); + } + EXPORT_SYMBOL(do_mmap_pgoff); + +@@ -1086,25 +1087,10 @@ + mapping_cap_account_dirty(vma->vm_file->f_mapping); + } + +-/* +- * We account for memory if it's a private writeable mapping, +- * not hugepages and VM_NORESERVE wasn't set. +- */ +-static inline int accountable_mapping(struct file *file, unsigned int vm_flags) +-{ +- /* +- * hugetlb has its own accounting separate from the core VM +- * VM_HUGETLB may not be set yet so we cannot check for that flag. +- */ +- if (file && is_file_hugepages(file)) +- return 0; +- +- return (vm_flags & (VM_NORESERVE | VM_SHARED | VM_WRITE)) == VM_WRITE; +-} +- + unsigned long mmap_region(struct file *file, unsigned long addr, + unsigned long len, unsigned long flags, +- unsigned int vm_flags, unsigned long pgoff) ++ unsigned int vm_flags, unsigned long pgoff, ++ int accountable) + { + struct mm_struct *mm = current->mm; + struct vm_area_struct *vma, *prev; +@@ -1128,38 +1114,38 @@ + if (!may_expand_vm(mm, len >> PAGE_SHIFT)) + return -ENOMEM; + +- /* +- * Set 'VM_NORESERVE' if we should not account for the +- * memory use of this mapping. +- */ +- if ((flags & MAP_NORESERVE)) { +- /* We honor MAP_NORESERVE if allowed to overcommit */ +- if (sysctl_overcommit_memory != OVERCOMMIT_NEVER) +- vm_flags |= VM_NORESERVE; ++ if (flags & MAP_NORESERVE) ++ vm_flags |= VM_NORESERVE; + +- /* hugetlb applies strict overcommit unless MAP_NORESERVE */ +- if (file && is_file_hugepages(file)) +- vm_flags |= VM_NORESERVE; ++ if (accountable && (!(flags & MAP_NORESERVE) || ++ sysctl_overcommit_memory == OVERCOMMIT_NEVER)) { ++ if (vm_flags & VM_SHARED) { ++ /* Check memory availability in shmem_file_setup? */ ++ vm_flags |= VM_ACCOUNT; ++ } else if (vm_flags & VM_WRITE) { ++ /* ++ * Private writable mapping: check memory availability ++ */ ++ charged = len >> PAGE_SHIFT; ++ if (security_vm_enough_memory(charged)) ++ return -ENOMEM; ++ vm_flags |= VM_ACCOUNT; ++ } + } + + /* +- * Private writable mapping: check memory availability ++ * Can we just expand an old private anonymous mapping? ++ * The VM_SHARED test is necessary because shmem_zero_setup ++ * will create the file object for a shared anonymous map below. + */ +- if (accountable_mapping(file, vm_flags)) { +- charged = len >> PAGE_SHIFT; +- if (security_vm_enough_memory(charged)) +- return -ENOMEM; +- vm_flags |= VM_ACCOUNT; ++ if (!file && !(vm_flags & VM_SHARED)) { ++ vma = vma_merge(mm, prev, addr, addr + len, vm_flags, ++ NULL, NULL, pgoff, NULL); ++ if (vma) ++ goto out; + } + + /* +- * Can we just expand an old mapping? +- */ +- vma = vma_merge(mm, prev, addr, addr + len, vm_flags, NULL, file, pgoff, NULL); +- if (vma) +- goto out; +- +- /* + * Determine the object being mapped and call the appropriate + * specific mapper. the address has already been validated, but + * not unmapped, but the maps are removed from the list. +@@ -1200,6 +1186,14 @@ + goto free_vma; + } + ++ /* We set VM_ACCOUNT in a shared mapping's vm_flags, to inform ++ * shmem_zero_setup (perhaps called through /dev/zero's ->mmap) ++ * that memory reservation must be checked; but that reservation ++ * belongs to shared memory object, not to vma: so now clear it. ++ */ ++ if ((vm_flags & (VM_SHARED|VM_ACCOUNT)) == (VM_SHARED|VM_ACCOUNT)) ++ vma->vm_flags &= ~VM_ACCOUNT; ++ + /* Can addr have changed?? + * + * Answer: Yes, several device drivers can do it in their +@@ -1212,8 +1206,17 @@ + if (vma_wants_writenotify(vma)) + vma->vm_page_prot = vm_get_page_prot(vm_flags & ~VM_SHARED); + +- vma_link(mm, vma, prev, rb_link, rb_parent); +- file = vma->vm_file; ++ if (file && vma_merge(mm, prev, addr, vma->vm_end, ++ vma->vm_flags, NULL, file, pgoff, vma_policy(vma))) { ++ mpol_put(vma_policy(vma)); ++ kmem_cache_free(vm_area_cachep, vma); ++ fput(file); ++ if (vm_flags & VM_EXECUTABLE) ++ removed_exe_file_vma(mm); ++ } else { ++ vma_link(mm, vma, prev, rb_link, rb_parent); ++ file = vma->vm_file; ++ } + + /* Once vma denies write, undo our temporary denial count */ + if (correct_wcount) +@@ -2084,8 +2087,12 @@ + unsigned long end; + + /* mm's last user has gone, and its about to be pulled down */ ++ arch_exit_mmap(mm); + mmu_notifier_release(mm); + ++ if (!mm->mmap) /* Can happen if dup_mmap() received an OOM */ ++ return; ++ + if (mm->locked_vm) { + vma = mm->mmap; + while (vma) { +@@ -2094,13 +2101,7 @@ + vma = vma->vm_next; + } + } +- +- arch_exit_mmap(mm); +- + vma = mm->mmap; +- if (!vma) /* Can happen if dup_mmap() received an OOM */ +- return; +- + lru_add_drain(); + flush_cache_mm(mm); + tlb = tlb_gather_mmu(mm, 1); +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/mm/mprotect.c linux-2.6.29-rc3.owrt/mm/mprotect.c +--- linux-2.6.29.owrt/mm/mprotect.c 2009-05-10 22:04:39.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/mm/mprotect.c 2009-05-10 23:48:33.000000000 +0200 +@@ -151,11 +151,10 @@ + /* + * If we make a private mapping writable we increase our commit; + * but (without finer accounting) cannot reduce our commit if we +- * make it unwritable again. hugetlb mapping were accounted for +- * even if read-only so there is no need to account for them here ++ * make it unwritable again. + */ + if (newflags & VM_WRITE) { +- if (!(oldflags & (VM_ACCOUNT|VM_WRITE|VM_HUGETLB| ++ if (!(oldflags & (VM_ACCOUNT|VM_WRITE| + VM_SHARED|VM_NORESERVE))) { + charged = nrpages; + if (security_vm_enough_memory(charged)) +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/mm/page_alloc.c linux-2.6.29-rc3.owrt/mm/page_alloc.c +--- linux-2.6.29.owrt/mm/page_alloc.c 2009-05-10 22:04:39.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/mm/page_alloc.c 2009-05-10 23:48:33.000000000 +0200 +@@ -2989,7 +2989,7 @@ + * was used and there are no special requirements, this is a convenient + * alternative + */ +-int __meminit __early_pfn_to_nid(unsigned long pfn) ++int __meminit early_pfn_to_nid(unsigned long pfn) + { + int i; + +@@ -3000,33 +3000,10 @@ + if (start_pfn <= pfn && pfn < end_pfn) + return early_node_map[i].nid; + } +- /* This is a memory hole */ +- return -1; +-} +-#endif /* CONFIG_HAVE_ARCH_EARLY_PFN_TO_NID */ +- +-int __meminit early_pfn_to_nid(unsigned long pfn) +-{ +- int nid; + +- nid = __early_pfn_to_nid(pfn); +- if (nid >= 0) +- return nid; +- /* just returns 0 */ + return 0; + } +- +-#ifdef CONFIG_NODES_SPAN_OTHER_NODES +-bool __meminit early_pfn_in_nid(unsigned long pfn, int node) +-{ +- int nid; +- +- nid = __early_pfn_to_nid(pfn); +- if (nid >= 0 && nid != node) +- return false; +- return true; +-} +-#endif ++#endif /* CONFIG_HAVE_ARCH_EARLY_PFN_TO_NID */ + + /* Basic iterator support to walk early_node_map[] */ + #define for_each_active_range_index_in_nid(i, nid) \ +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/mm/page_cgroup.c linux-2.6.29-rc3.owrt/mm/page_cgroup.c +--- linux-2.6.29.owrt/mm/page_cgroup.c 2009-05-10 22:04:39.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/mm/page_cgroup.c 2009-05-10 23:48:33.000000000 +0200 +@@ -114,8 +114,7 @@ + nid = page_to_nid(pfn_to_page(pfn)); + table_size = sizeof(struct page_cgroup) * PAGES_PER_SECTION; + if (slab_is_available()) { +- base = kmalloc_node(table_size, +- GFP_KERNEL | __GFP_NOWARN, nid); ++ base = kmalloc_node(table_size, GFP_KERNEL, nid); + if (!base) + base = vmalloc_node(table_size, nid); + } else { +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/mm/page_io.c linux-2.6.29-rc3.owrt/mm/page_io.c +--- linux-2.6.29.owrt/mm/page_io.c 2009-05-10 22:04:39.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/mm/page_io.c 2009-05-10 23:48:33.000000000 +0200 +@@ -111,7 +111,7 @@ + goto out; + } + if (wbc->sync_mode == WB_SYNC_ALL) +- rw |= (1 << BIO_RW_SYNCIO) | (1 << BIO_RW_UNPLUG); ++ rw |= (1 << BIO_RW_SYNC); + count_vm_event(PSWPOUT); + set_page_writeback(page); + unlock_page(page); +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/mm/page-writeback.c linux-2.6.29-rc3.owrt/mm/page-writeback.c +--- linux-2.6.29.owrt/mm/page-writeback.c 2009-05-10 22:04:39.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/mm/page-writeback.c 2009-05-10 23:48:33.000000000 +0200 +@@ -209,7 +209,7 @@ + struct file *filp, void __user *buffer, size_t *lenp, + loff_t *ppos) + { +- unsigned long old_bytes = vm_dirty_bytes; ++ int old_bytes = vm_dirty_bytes; + int ret; + + ret = proc_doulongvec_minmax(table, write, filp, buffer, lenp, ppos); +@@ -240,7 +240,7 @@ + } + EXPORT_SYMBOL_GPL(bdi_writeout_inc); + +-void task_dirty_inc(struct task_struct *tsk) ++static inline void task_dirty_inc(struct task_struct *tsk) + { + prop_inc_single(&vm_dirties, &tsk->dirties); + } +@@ -1051,25 +1051,13 @@ + } + } + +- if (nr_to_write > 0) { +- nr_to_write--; +- if (nr_to_write == 0 && +- wbc->sync_mode == WB_SYNC_NONE) { +- /* +- * We stop writing back only if we are +- * not doing integrity sync. In case of +- * integrity sync we have to keep going +- * because someone may be concurrently +- * dirtying pages, and we might have +- * synced a lot of newly appeared dirty +- * pages, but have not synced all of the +- * old dirty pages. +- */ ++ if (wbc->sync_mode == WB_SYNC_NONE) { ++ wbc->nr_to_write--; ++ if (wbc->nr_to_write <= 0) { + done = 1; + break; + } + } +- + if (wbc->nonblocking && bdi_write_congested(bdi)) { + wbc->encountered_congestion = 1; + done = 1; +@@ -1079,7 +1067,7 @@ + pagevec_release(&pvec); + cond_resched(); + } +- if (!cycled && !done) { ++ if (!cycled) { + /* + * range_cyclic: + * We hit the last page and there is more work to be done: wrap +@@ -1230,7 +1218,6 @@ + __inc_zone_page_state(page, NR_FILE_DIRTY); + __inc_bdi_stat(mapping->backing_dev_info, + BDI_RECLAIMABLE); +- task_dirty_inc(current); + task_io_account_write(PAGE_CACHE_SIZE); + } + radix_tree_tag_set(&mapping->page_tree, +@@ -1263,7 +1250,7 @@ + * If the mapping doesn't provide a set_page_dirty a_op, then + * just fall through and assume that it wants buffer_heads. + */ +-int set_page_dirty(struct page *page) ++static int __set_page_dirty(struct page *page) + { + struct address_space *mapping = page_mapping(page); + +@@ -1281,6 +1268,14 @@ + } + return 0; + } ++ ++int set_page_dirty(struct page *page) ++{ ++ int ret = __set_page_dirty(page); ++ if (ret) ++ task_dirty_inc(current); ++ return ret; ++} + EXPORT_SYMBOL(set_page_dirty); + + /* +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/mm/rmap.c linux-2.6.29-rc3.owrt/mm/rmap.c +--- linux-2.6.29.owrt/mm/rmap.c 2009-05-10 22:04:39.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/mm/rmap.c 2009-05-10 23:48:33.000000000 +0200 +@@ -1072,8 +1072,7 @@ + spin_lock(&mapping->i_mmap_lock); + vma_prio_tree_foreach(vma, &iter, &mapping->i_mmap, pgoff, pgoff) { + if (MLOCK_PAGES && unlikely(unlock)) { +- if (!((vma->vm_flags & VM_LOCKED) && +- page_mapped_in_vma(page, vma))) ++ if (!(vma->vm_flags & VM_LOCKED)) + continue; /* must visit all vmas */ + ret = SWAP_MLOCK; + } else { +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/mm/shmem.c linux-2.6.29-rc3.owrt/mm/shmem.c +--- linux-2.6.29.owrt/mm/shmem.c 2009-05-10 22:04:39.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/mm/shmem.c 2009-05-10 23:48:33.000000000 +0200 +@@ -169,13 +169,13 @@ + */ + static inline int shmem_acct_size(unsigned long flags, loff_t size) + { +- return (flags & VM_NORESERVE) ? +- 0 : security_vm_enough_memory_kern(VM_ACCT(size)); ++ return (flags & VM_ACCOUNT) ? ++ security_vm_enough_memory_kern(VM_ACCT(size)) : 0; + } + + static inline void shmem_unacct_size(unsigned long flags, loff_t size) + { +- if (!(flags & VM_NORESERVE)) ++ if (flags & VM_ACCOUNT) + vm_unacct_memory(VM_ACCT(size)); + } + +@@ -187,13 +187,13 @@ + */ + static inline int shmem_acct_block(unsigned long flags) + { +- return (flags & VM_NORESERVE) ? +- security_vm_enough_memory_kern(VM_ACCT(PAGE_CACHE_SIZE)) : 0; ++ return (flags & VM_ACCOUNT) ? ++ 0 : security_vm_enough_memory_kern(VM_ACCT(PAGE_CACHE_SIZE)); + } + + static inline void shmem_unacct_blocks(unsigned long flags, long pages) + { +- if (flags & VM_NORESERVE) ++ if (!(flags & VM_ACCOUNT)) + vm_unacct_memory(pages * VM_ACCT(PAGE_CACHE_SIZE)); + } + +@@ -1515,8 +1515,8 @@ + return 0; + } + +-static struct inode *shmem_get_inode(struct super_block *sb, int mode, +- dev_t dev, unsigned long flags) ++static struct inode * ++shmem_get_inode(struct super_block *sb, int mode, dev_t dev) + { + struct inode *inode; + struct shmem_inode_info *info; +@@ -1537,7 +1537,6 @@ + info = SHMEM_I(inode); + memset(info, 0, (char *)inode - (char *)info); + spin_lock_init(&info->lock); +- info->flags = flags & VM_NORESERVE; + INIT_LIST_HEAD(&info->swaplist); + + switch (mode & S_IFMT) { +@@ -1780,10 +1779,9 @@ + static int + shmem_mknod(struct inode *dir, struct dentry *dentry, int mode, dev_t dev) + { +- struct inode *inode; ++ struct inode *inode = shmem_get_inode(dir->i_sb, mode, dev); + int error = -ENOSPC; + +- inode = shmem_get_inode(dir->i_sb, mode, dev, VM_NORESERVE); + if (inode) { + error = security_inode_init_security(inode, dir, NULL, NULL, + NULL); +@@ -1922,7 +1920,7 @@ + if (len > PAGE_CACHE_SIZE) + return -ENAMETOOLONG; + +- inode = shmem_get_inode(dir->i_sb, S_IFLNK|S_IRWXUGO, 0, VM_NORESERVE); ++ inode = shmem_get_inode(dir->i_sb, S_IFLNK|S_IRWXUGO, 0); + if (!inode) + return -ENOSPC; + +@@ -2334,7 +2332,7 @@ + sb->s_flags |= MS_POSIXACL; + #endif + +- inode = shmem_get_inode(sb, S_IFDIR | sbinfo->mode, 0, VM_NORESERVE); ++ inode = shmem_get_inode(sb, S_IFDIR | sbinfo->mode, 0); + if (!inode) + goto failed; + inode->i_uid = sbinfo->uid; +@@ -2576,12 +2574,12 @@ + return 0; + } + +-#define shmem_vm_ops generic_file_vm_ops +-#define shmem_file_operations ramfs_file_operations +-#define shmem_get_inode(sb, mode, dev, flags) ramfs_get_inode(sb, mode, dev) +-#define shmem_acct_size(flags, size) 0 +-#define shmem_unacct_size(flags, size) do {} while (0) +-#define SHMEM_MAX_BYTES LLONG_MAX ++#define shmem_file_operations ramfs_file_operations ++#define shmem_vm_ops generic_file_vm_ops ++#define shmem_get_inode ramfs_get_inode ++#define shmem_acct_size(a, b) 0 ++#define shmem_unacct_size(a, b) do {} while (0) ++#define SHMEM_MAX_BYTES LLONG_MAX + + #endif /* CONFIG_SHMEM */ + +@@ -2600,7 +2598,7 @@ + * shmem_file_setup - get an unlinked file living in tmpfs + * @name: name for dentry (to be seen in /proc/<pid>/maps + * @size: size to be set for the file +- * @flags: VM_NORESERVE suppresses pre-accounting of the entire object size ++ * @flags: vm_flags + */ + struct file *shmem_file_setup(char *name, loff_t size, unsigned long flags) + { +@@ -2634,10 +2632,13 @@ + goto put_dentry; + + error = -ENOSPC; +- inode = shmem_get_inode(root->d_sb, S_IFREG | S_IRWXUGO, 0, flags); ++ inode = shmem_get_inode(root->d_sb, S_IFREG | S_IRWXUGO, 0); + if (!inode) + goto close_file; + ++#ifdef CONFIG_SHMEM ++ SHMEM_I(inode)->flags = flags & VM_ACCOUNT; ++#endif + d_instantiate(dentry, inode); + inode->i_size = size; + inode->i_nlink = 0; /* It is unlinked */ +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/mm/slab.c linux-2.6.29-rc3.owrt/mm/slab.c +--- linux-2.6.29.owrt/mm/slab.c 2009-05-10 22:04:39.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/mm/slab.c 2009-05-10 23:48:33.000000000 +0200 +@@ -4457,4 +4457,3 @@ + + return obj_size(virt_to_cache(objp)); + } +-EXPORT_SYMBOL(ksize); +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/mm/slob.c linux-2.6.29-rc3.owrt/mm/slob.c +--- linux-2.6.29.owrt/mm/slob.c 2009-05-10 22:04:39.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/mm/slob.c 2009-05-10 23:48:33.000000000 +0200 +@@ -521,7 +521,6 @@ + } else + return sp->page.private; + } +-EXPORT_SYMBOL(ksize); + + struct kmem_cache { + unsigned int size, align; +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/mm/slub.c linux-2.6.29-rc3.owrt/mm/slub.c +--- linux-2.6.29.owrt/mm/slub.c 2009-05-10 22:04:39.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/mm/slub.c 2009-05-10 23:48:33.000000000 +0200 +@@ -1996,7 +1996,7 @@ + static void free_kmem_cache_cpu(struct kmem_cache_cpu *c, int cpu) + { + if (c < per_cpu(kmem_cache_cpu, cpu) || +- c >= per_cpu(kmem_cache_cpu, cpu) + NR_KMEM_CACHE_CPU) { ++ c > per_cpu(kmem_cache_cpu, cpu) + NR_KMEM_CACHE_CPU) { + kfree(c); + return; + } +@@ -2736,7 +2736,6 @@ + */ + return s->size; + } +-EXPORT_SYMBOL(ksize); + + void kfree(const void *x) + { +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/mm/swapfile.c linux-2.6.29-rc3.owrt/mm/swapfile.c +--- linux-2.6.29.owrt/mm/swapfile.c 2009-05-10 22:04:39.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/mm/swapfile.c 2009-05-10 23:48:33.000000000 +0200 +@@ -635,7 +635,7 @@ + + if (!bdev) { + if (bdev_p) +- *bdev_p = bdget(sis->bdev->bd_dev); ++ *bdev_p = sis->bdev; + + spin_unlock(&swap_lock); + return i; +@@ -647,7 +647,7 @@ + struct swap_extent, list); + if (se->start_block == offset) { + if (bdev_p) +- *bdev_p = bdget(sis->bdev->bd_dev); ++ *bdev_p = sis->bdev; + + spin_unlock(&swap_lock); + bdput(bdev); +@@ -698,10 +698,8 @@ + pte_t *pte; + int ret = 1; + +- if (mem_cgroup_try_charge_swapin(vma->vm_mm, page, GFP_KERNEL, &ptr)) { ++ if (mem_cgroup_try_charge_swapin(vma->vm_mm, page, GFP_KERNEL, &ptr)) + ret = -ENOMEM; +- goto out_nolock; +- } + + pte = pte_offset_map_lock(vma->vm_mm, pmd, addr, &ptl); + if (unlikely(!pte_same(*pte, swp_entry_to_pte(entry)))) { +@@ -725,7 +723,6 @@ + activate_page(page); + out: + pte_unmap_unlock(pte, ptl); +-out_nolock: + return ret; + } + +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/mm/util.c linux-2.6.29-rc3.owrt/mm/util.c +--- linux-2.6.29.owrt/mm/util.c 2009-05-10 22:04:39.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/mm/util.c 2009-05-10 23:48:33.000000000 +0200 +@@ -129,26 +129,6 @@ + } + EXPORT_SYMBOL(krealloc); + +-/** +- * kzfree - like kfree but zero memory +- * @p: object to free memory of +- * +- * The memory of the object @p points to is zeroed before freed. +- * If @p is %NULL, kzfree() does nothing. +- */ +-void kzfree(const void *p) +-{ +- size_t ks; +- void *mem = (void *)p; +- +- if (unlikely(ZERO_OR_NULL_PTR(mem))) +- return; +- ks = ksize(mem); +- memset(mem, 0, ks); +- kfree(mem); +-} +-EXPORT_SYMBOL(kzfree); +- + /* + * strndup_user - duplicate an existing string from user space + * @s: The string to duplicate +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/mm/vmalloc.c linux-2.6.29-rc3.owrt/mm/vmalloc.c +--- linux-2.6.29.owrt/mm/vmalloc.c 2009-05-10 22:04:39.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/mm/vmalloc.c 2009-05-10 23:48:33.000000000 +0200 +@@ -323,7 +323,6 @@ + unsigned long addr; + int purged = 0; + +- BUG_ON(!size); + BUG_ON(size & ~PAGE_MASK); + + va = kmalloc_node(sizeof(struct vmap_area), +@@ -335,9 +334,6 @@ + addr = ALIGN(vstart, align); + + spin_lock(&vmap_area_lock); +- if (addr + size - 1 < addr) +- goto overflow; +- + /* XXX: could have a last_hole cache */ + n = vmap_area_root.rb_node; + if (n) { +@@ -369,8 +365,6 @@ + + while (addr + size > first->va_start && addr + size <= vend) { + addr = ALIGN(first->va_end + PAGE_SIZE, align); +- if (addr + size - 1 < addr) +- goto overflow; + + n = rb_next(&first->rb_node); + if (n) +@@ -381,7 +375,6 @@ + } + found: + if (addr + size > vend) { +-overflow: + spin_unlock(&vmap_area_lock); + if (!purged) { + purge_vmap_area_lazy(); +@@ -505,7 +498,6 @@ + static DEFINE_SPINLOCK(purge_lock); + LIST_HEAD(valist); + struct vmap_area *va; +- struct vmap_area *n_va; + int nr = 0; + + /* +@@ -545,7 +537,7 @@ + + if (nr) { + spin_lock(&vmap_area_lock); +- list_for_each_entry_safe(va, n_va, &valist, purge_list) ++ list_for_each_entry(va, &valist, purge_list) + __free_vmap_area(va); + spin_unlock(&vmap_area_lock); + } +@@ -1020,8 +1012,6 @@ + void unmap_kernel_range(unsigned long addr, unsigned long size) + { + unsigned long end = addr + size; +- +- flush_cache_vunmap(addr, end); + vunmap_page_range(addr, end); + flush_tlb_kernel_range(addr, end); + } +@@ -1117,14 +1107,6 @@ + } + EXPORT_SYMBOL_GPL(__get_vm_area); + +-struct vm_struct *__get_vm_area_caller(unsigned long size, unsigned long flags, +- unsigned long start, unsigned long end, +- void *caller) +-{ +- return __get_vm_area_node(size, flags, start, end, -1, GFP_KERNEL, +- caller); +-} +- + /** + * get_vm_area - reserve a contiguous kernel virtual area + * @size: size of the area +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/mm/vmscan.c linux-2.6.29-rc3.owrt/mm/vmscan.c +--- linux-2.6.29.owrt/mm/vmscan.c 2009-05-10 22:04:39.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/mm/vmscan.c 2009-05-10 23:48:33.000000000 +0200 +@@ -1262,6 +1262,7 @@ + * Move the pages to the [file or anon] inactive list. + */ + pagevec_init(&pvec, 1); ++ pgmoved = 0; + lru = LRU_BASE + file * LRU_FILE; + + spin_lock_irq(&zone->lru_lock); +@@ -1273,7 +1274,6 @@ + */ + reclaim_stat->recent_rotated[!!file] += pgmoved; + +- pgmoved = 0; + while (!list_empty(&l_inactive)) { + page = lru_to_page(&l_inactive); + prefetchw_prev_lru_page(page, &l_inactive, flags); +@@ -1469,7 +1469,7 @@ + int file = is_file_lru(l); + int scan; + +- scan = zone_nr_pages(zone, sc, l); ++ scan = zone_page_state(zone, NR_LRU_BASE + l); + if (priority) { + scan >>= priority; + scan = (scan * percent[file]) / 100; +@@ -2057,31 +2057,31 @@ + int pass, struct scan_control *sc) + { + struct zone *zone; +- unsigned long ret = 0; ++ unsigned long nr_to_scan, ret = 0; ++ enum lru_list l; + + for_each_zone(zone) { +- enum lru_list l; + + if (!populated_zone(zone)) + continue; ++ + if (zone_is_all_unreclaimable(zone) && prio != DEF_PRIORITY) + continue; + + for_each_evictable_lru(l) { +- enum zone_stat_item ls = NR_LRU_BASE + l; +- unsigned long lru_pages = zone_page_state(zone, ls); +- + /* For pass = 0, we don't shrink the active list */ +- if (pass == 0 && (l == LRU_ACTIVE_ANON || +- l == LRU_ACTIVE_FILE)) ++ if (pass == 0 && ++ (l == LRU_ACTIVE || l == LRU_ACTIVE_FILE)) + continue; + +- zone->lru[l].nr_scan += (lru_pages >> prio) + 1; ++ zone->lru[l].nr_scan += ++ (zone_page_state(zone, NR_LRU_BASE + l) ++ >> prio) + 1; + if (zone->lru[l].nr_scan >= nr_pages || pass > 3) { +- unsigned long nr_to_scan; +- + zone->lru[l].nr_scan = 0; +- nr_to_scan = min(nr_pages, lru_pages); ++ nr_to_scan = min(nr_pages, ++ zone_page_state(zone, ++ NR_LRU_BASE + l)); + ret += shrink_list(l, nr_to_scan, zone, + sc, prio); + if (ret >= nr_pages) +@@ -2089,6 +2089,7 @@ + } + } + } ++ + return ret; + } + +@@ -2111,6 +2112,7 @@ + .may_swap = 0, + .swap_cluster_max = nr_pages, + .may_writepage = 1, ++ .swappiness = vm_swappiness, + .isolate_pages = isolate_pages_global, + }; + +@@ -2144,8 +2146,10 @@ + int prio; + + /* Force reclaiming mapped pages in the passes #3 and #4 */ +- if (pass > 2) ++ if (pass > 2) { + sc.may_swap = 1; ++ sc.swappiness = 100; ++ } + + for (prio = DEF_PRIORITY; prio >= 0; prio--) { + unsigned long nr_to_scan = nr_pages - ret; +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/net/802/tr.c linux-2.6.29-rc3.owrt/net/802/tr.c +--- linux-2.6.29.owrt/net/802/tr.c 2009-05-10 22:04:39.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/net/802/tr.c 2009-05-10 23:48:33.000000000 +0200 +@@ -668,5 +668,3 @@ + + EXPORT_SYMBOL(tr_type_trans); + EXPORT_SYMBOL(alloc_trdev); +- +-MODULE_LICENSE("GPL"); +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/net/8021q/vlan_core.c linux-2.6.29-rc3.owrt/net/8021q/vlan_core.c +--- linux-2.6.29.owrt/net/8021q/vlan_core.c 2009-05-10 22:04:39.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/net/8021q/vlan_core.c 2009-05-10 23:48:33.000000000 +0200 +@@ -1,16 +1,12 @@ + #include <linux/skbuff.h> + #include <linux/netdevice.h> + #include <linux/if_vlan.h> +-#include <linux/netpoll.h> + #include "vlan.h" + + /* VLAN rx hw acceleration helper. This acts like netif_{rx,receive_skb}(). */ + int __vlan_hwaccel_rx(struct sk_buff *skb, struct vlan_group *grp, + u16 vlan_tci, int polling) + { +- if (netpoll_rx(skb)) +- return NET_RX_DROP; +- + if (skb_bond_should_drop(skb)) + goto drop; + +@@ -104,9 +100,6 @@ + { + int err = NET_RX_SUCCESS; + +- if (netpoll_receive_skb(skb)) +- return NET_RX_DROP; +- + switch (vlan_gro_common(napi, grp, vlan_tci, skb)) { + case -1: + return netif_receive_skb(skb); +@@ -133,9 +126,6 @@ + if (!skb) + goto out; + +- if (netpoll_receive_skb(skb)) +- goto out; +- + err = NET_RX_SUCCESS; + + switch (vlan_gro_common(napi, grp, vlan_tci, skb)) { +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/net/8021q/vlan_dev.c linux-2.6.29-rc3.owrt/net/8021q/vlan_dev.c +--- linux-2.6.29.owrt/net/8021q/vlan_dev.c 2009-05-10 22:04:39.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/net/8021q/vlan_dev.c 2009-05-10 23:48:33.000000000 +0200 +@@ -553,7 +553,7 @@ + int err = 0; + + if (netif_device_present(real_dev) && ops->ndo_neigh_setup) +- err = ops->ndo_neigh_setup(real_dev, pa); ++ err = ops->ndo_neigh_setup(dev, pa); + + return err; + } +@@ -639,7 +639,6 @@ + dev->hard_header_len = real_dev->hard_header_len + VLAN_HLEN; + dev->netdev_ops = &vlan_netdev_ops; + } +- netdev_resync_ops(dev); + + if (is_vlan_dev(real_dev)) + subclass = 1; +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/net/9p/protocol.c linux-2.6.29-rc3.owrt/net/9p/protocol.c +--- linux-2.6.29.owrt/net/9p/protocol.c 2009-05-10 22:04:39.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/net/9p/protocol.c 2009-05-10 23:48:33.000000000 +0200 +@@ -29,7 +29,6 @@ + #include <linux/errno.h> + #include <linux/uaccess.h> + #include <linux/sched.h> +-#include <linux/types.h> + #include <net/9p/9p.h> + #include <net/9p/client.h> + #include "protocol.h" +@@ -161,32 +160,29 @@ + break; + case 'w':{ + int16_t *val = va_arg(ap, int16_t *); +- __le16 le_val; +- if (pdu_read(pdu, &le_val, sizeof(le_val))) { ++ if (pdu_read(pdu, val, sizeof(*val))) { + errcode = -EFAULT; + break; + } +- *val = le16_to_cpu(le_val); ++ *val = cpu_to_le16(*val); + } + break; + case 'd':{ + int32_t *val = va_arg(ap, int32_t *); +- __le32 le_val; +- if (pdu_read(pdu, &le_val, sizeof(le_val))) { ++ if (pdu_read(pdu, val, sizeof(*val))) { + errcode = -EFAULT; + break; + } +- *val = le32_to_cpu(le_val); ++ *val = cpu_to_le32(*val); + } + break; + case 'q':{ + int64_t *val = va_arg(ap, int64_t *); +- __le64 le_val; +- if (pdu_read(pdu, &le_val, sizeof(le_val))) { ++ if (pdu_read(pdu, val, sizeof(*val))) { + errcode = -EFAULT; + break; + } +- *val = le64_to_cpu(le_val); ++ *val = cpu_to_le64(*val); + } + break; + case 's':{ +@@ -366,19 +362,19 @@ + } + break; + case 'w':{ +- __le16 val = cpu_to_le16(va_arg(ap, int)); ++ int16_t val = va_arg(ap, int); + if (pdu_write(pdu, &val, sizeof(val))) + errcode = -EFAULT; + } + break; + case 'd':{ +- __le32 val = cpu_to_le32(va_arg(ap, int32_t)); ++ int32_t val = va_arg(ap, int32_t); + if (pdu_write(pdu, &val, sizeof(val))) + errcode = -EFAULT; + } + break; + case 'q':{ +- __le64 val = cpu_to_le64(va_arg(ap, int64_t)); ++ int64_t val = va_arg(ap, int64_t); + if (pdu_write(pdu, &val, sizeof(val))) + errcode = -EFAULT; + } +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/net/bridge/br_forward.c linux-2.6.29-rc3.owrt/net/bridge/br_forward.c +--- linux-2.6.29.owrt/net/bridge/br_forward.c 2009-05-10 22:04:39.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/net/bridge/br_forward.c 2009-05-10 23:48:33.000000000 +0200 +@@ -67,11 +67,6 @@ + { + struct net_device *indev; + +- if (skb_warn_if_lro(skb)) { +- kfree_skb(skb); +- return; +- } +- + indev = skb->dev; + skb->dev = to->dev; + skb_forward_csum(skb); +@@ -94,7 +89,7 @@ + /* called with rcu_read_lock */ + void br_forward(const struct net_bridge_port *to, struct sk_buff *skb) + { +- if (should_deliver(to, skb)) { ++ if (!skb_warn_if_lro(skb) && should_deliver(to, skb)) { + __br_forward(to, skb); + return; + } +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/net/core/dev.c linux-2.6.29-rc3.owrt/net/core/dev.c +--- linux-2.6.29.owrt/net/core/dev.c 2009-05-10 22:04:39.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/net/core/dev.c 2009-05-10 23:48:33.000000000 +0200 +@@ -1093,7 +1093,7 @@ + /* + * Enable NET_DMA + */ +- net_dmaengine_get(); ++ dmaengine_get(); + + /* + * Initialize multicasting status +@@ -1175,7 +1175,7 @@ + /* + * Shutdown NET_DMA + */ +- net_dmaengine_put(); ++ dmaengine_put(); + + return 0; + } +@@ -2274,6 +2274,12 @@ + + rcu_read_lock(); + ++ /* Don't receive packets in an exiting network namespace */ ++ if (!net_alive(dev_net(skb->dev))) { ++ kfree_skb(skb); ++ goto out; ++ } ++ + #ifdef CONFIG_NET_CLS_ACT + if (skb->tc_verd & TC_NCLS) { + skb->tc_verd = CLR_TC_NCLS(skb->tc_verd); +@@ -2489,9 +2495,6 @@ + + int napi_gro_receive(struct napi_struct *napi, struct sk_buff *skb) + { +- if (netpoll_receive_skb(skb)) +- return NET_RX_DROP; +- + switch (__napi_gro_receive(napi, skb)) { + case -1: + return netif_receive_skb(skb); +@@ -2562,9 +2565,6 @@ + if (!skb) + goto out; + +- if (netpoll_receive_skb(skb)) +- goto out; +- + err = NET_RX_SUCCESS; + + switch (__napi_gro_receive(napi, skb)) { +@@ -2595,9 +2595,9 @@ + local_irq_disable(); + skb = __skb_dequeue(&queue->input_pkt_queue); + if (!skb) { ++ __napi_complete(napi); + local_irq_enable(); +- napi_complete(napi); +- goto out; ++ break; + } + local_irq_enable(); + +@@ -2606,7 +2606,6 @@ + + napi_gro_flush(napi); + +-out: + return work; + } + +@@ -2679,7 +2678,7 @@ + struct sk_buff *skb, *next; + + list_del_init(&napi->dev_list); +- kfree_skb(napi->skb); ++ kfree(napi->skb); + + for (skb = napi->gro_list; skb; skb = next) { + next = skb->next; +@@ -4290,39 +4289,6 @@ + } + EXPORT_SYMBOL(netdev_fix_features); + +-/* Some devices need to (re-)set their netdev_ops inside +- * ->init() or similar. If that happens, we have to setup +- * the compat pointers again. +- */ +-void netdev_resync_ops(struct net_device *dev) +-{ +-#ifdef CONFIG_COMPAT_NET_DEV_OPS +- const struct net_device_ops *ops = dev->netdev_ops; +- +- dev->init = ops->ndo_init; +- dev->uninit = ops->ndo_uninit; +- dev->open = ops->ndo_open; +- dev->change_rx_flags = ops->ndo_change_rx_flags; +- dev->set_rx_mode = ops->ndo_set_rx_mode; +- dev->set_multicast_list = ops->ndo_set_multicast_list; +- dev->set_mac_address = ops->ndo_set_mac_address; +- dev->validate_addr = ops->ndo_validate_addr; +- dev->do_ioctl = ops->ndo_do_ioctl; +- dev->set_config = ops->ndo_set_config; +- dev->change_mtu = ops->ndo_change_mtu; +- dev->neigh_setup = ops->ndo_neigh_setup; +- dev->tx_timeout = ops->ndo_tx_timeout; +- dev->get_stats = ops->ndo_get_stats; +- dev->vlan_rx_register = ops->ndo_vlan_rx_register; +- dev->vlan_rx_add_vid = ops->ndo_vlan_rx_add_vid; +- dev->vlan_rx_kill_vid = ops->ndo_vlan_rx_kill_vid; +-#ifdef CONFIG_NET_POLL_CONTROLLER +- dev->poll_controller = ops->ndo_poll_controller; +-#endif +-#endif +-} +-EXPORT_SYMBOL(netdev_resync_ops); +- + /** + * register_netdevice - register a network device + * @dev: device to register +@@ -4367,7 +4333,27 @@ + * This is temporary until all network devices are converted. + */ + if (dev->netdev_ops) { +- netdev_resync_ops(dev); ++ const struct net_device_ops *ops = dev->netdev_ops; ++ ++ dev->init = ops->ndo_init; ++ dev->uninit = ops->ndo_uninit; ++ dev->open = ops->ndo_open; ++ dev->change_rx_flags = ops->ndo_change_rx_flags; ++ dev->set_rx_mode = ops->ndo_set_rx_mode; ++ dev->set_multicast_list = ops->ndo_set_multicast_list; ++ dev->set_mac_address = ops->ndo_set_mac_address; ++ dev->validate_addr = ops->ndo_validate_addr; ++ dev->do_ioctl = ops->ndo_do_ioctl; ++ dev->set_config = ops->ndo_set_config; ++ dev->change_mtu = ops->ndo_change_mtu; ++ dev->tx_timeout = ops->ndo_tx_timeout; ++ dev->get_stats = ops->ndo_get_stats; ++ dev->vlan_rx_register = ops->ndo_vlan_rx_register; ++ dev->vlan_rx_add_vid = ops->ndo_vlan_rx_add_vid; ++ dev->vlan_rx_kill_vid = ops->ndo_vlan_rx_kill_vid; ++#ifdef CONFIG_NET_POLL_CONTROLLER ++ dev->poll_controller = ops->ndo_poll_controller; ++#endif + } else { + char drivername[64]; + pr_info("%s (%s): not using net_device_ops yet\n", +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/net/core/neighbour.c linux-2.6.29-rc3.owrt/net/core/neighbour.c +--- linux-2.6.29.owrt/net/core/neighbour.c 2009-05-10 22:04:39.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/net/core/neighbour.c 2009-05-10 23:48:33.000000000 +0200 +@@ -1994,8 +1994,8 @@ + if (!net_eq(neigh_parms_net(p), net)) + continue; + +- if (nidx < neigh_skip) +- goto next; ++ if (nidx++ < neigh_skip) ++ continue; + + if (neightbl_fill_param_info(skb, tbl, p, + NETLINK_CB(cb->skb).pid, +@@ -2003,8 +2003,6 @@ + RTM_NEWNEIGHTBL, + NLM_F_MULTI) <= 0) + goto out; +- next: +- nidx++; + } + + neigh_skip = 0; +@@ -2084,10 +2082,12 @@ + if (h > s_h) + s_idx = 0; + for (n = tbl->hash_buckets[h], idx = 0; n; n = n->next) { ++ int lidx; + if (dev_net(n->dev) != net) + continue; +- if (idx < s_idx) +- goto next; ++ lidx = idx++; ++ if (lidx < s_idx) ++ continue; + if (neigh_fill_info(skb, n, NETLINK_CB(cb->skb).pid, + cb->nlh->nlmsg_seq, + RTM_NEWNEIGH, +@@ -2096,8 +2096,6 @@ + rc = -1; + goto out; + } +- next: +- idx++; + } + } + read_unlock_bh(&tbl->lock); +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/net/core/net_namespace.c linux-2.6.29-rc3.owrt/net/core/net_namespace.c +--- linux-2.6.29.owrt/net/core/net_namespace.c 2009-05-10 22:04:39.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/net/core/net_namespace.c 2009-05-10 23:48:33.000000000 +0200 +@@ -32,14 +32,24 @@ + { + /* Must be called with net_mutex held */ + struct pernet_operations *ops; +- int error = 0; ++ int error; ++ struct net_generic *ng; + + atomic_set(&net->count, 1); +- + #ifdef NETNS_REFCNT_DEBUG + atomic_set(&net->use_count, 0); + #endif + ++ error = -ENOMEM; ++ ng = kzalloc(sizeof(struct net_generic) + ++ INITIAL_NET_GEN_PTRS * sizeof(void *), GFP_KERNEL); ++ if (ng == NULL) ++ goto out; ++ ++ ng->len = INITIAL_NET_GEN_PTRS; ++ rcu_assign_pointer(net->gen, ng); ++ ++ error = 0; + list_for_each_entry(ops, &pernet_list, list) { + if (ops->init) { + error = ops->init(net); +@@ -60,50 +70,24 @@ + } + + rcu_barrier(); ++ kfree(ng); + goto out; + } + +-static struct net_generic *net_alloc_generic(void) +-{ +- struct net_generic *ng; +- size_t generic_size = sizeof(struct net_generic) + +- INITIAL_NET_GEN_PTRS * sizeof(void *); +- +- ng = kzalloc(generic_size, GFP_KERNEL); +- if (ng) +- ng->len = INITIAL_NET_GEN_PTRS; +- +- return ng; +-} +- + #ifdef CONFIG_NET_NS + static struct kmem_cache *net_cachep; + static struct workqueue_struct *netns_wq; + + static struct net *net_alloc(void) + { +- struct net *net = NULL; +- struct net_generic *ng; +- +- ng = net_alloc_generic(); +- if (!ng) +- goto out; +- +- net = kmem_cache_zalloc(net_cachep, GFP_KERNEL); +- if (!net) +- goto out_free; +- +- rcu_assign_pointer(net->gen, ng); +-out: +- return net; +- +-out_free: +- kfree(ng); +- goto out; ++ return kmem_cache_zalloc(net_cachep, GFP_KERNEL); + } + + static void net_free(struct net *net) + { ++ if (!net) ++ return; ++ + #ifdef NETNS_REFCNT_DEBUG + if (unlikely(atomic_read(&net->use_count) != 0)) { + printk(KERN_EMERG "network namespace not free! Usage: %d\n", +@@ -128,28 +112,27 @@ + err = -ENOMEM; + new_net = net_alloc(); + if (!new_net) +- goto out_err; ++ goto out; + + mutex_lock(&net_mutex); + err = setup_net(new_net); +- if (!err) { +- rtnl_lock(); +- list_add_tail(&new_net->list, &net_namespace_list); +- rtnl_unlock(); +- } +- mutex_unlock(&net_mutex); +- + if (err) +- goto out_free; ++ goto out_unlock; ++ ++ rtnl_lock(); ++ list_add_tail(&new_net->list, &net_namespace_list); ++ rtnl_unlock(); ++ ++ ++out_unlock: ++ mutex_unlock(&net_mutex); + out: + put_net(old_net); ++ if (err) { ++ net_free(new_net); ++ new_net = ERR_PTR(err); ++ } + return new_net; +- +-out_free: +- net_free(new_net); +-out_err: +- new_net = ERR_PTR(err); +- goto out; + } + + static void cleanup_net(struct work_struct *work) +@@ -157,6 +140,9 @@ + struct pernet_operations *ops; + struct net *net; + ++ /* Be very certain incoming network packets will not find us */ ++ rcu_barrier(); ++ + net = container_of(work, struct net, work); + + mutex_lock(&net_mutex); +@@ -202,7 +188,6 @@ + + static int __init net_ns_init(void) + { +- struct net_generic *ng; + int err; + + printk(KERN_INFO "net_namespace: %zd bytes\n", sizeof(struct net)); +@@ -217,12 +202,6 @@ + panic("Could not create netns workq"); + #endif + +- ng = net_alloc_generic(); +- if (!ng) +- panic("Could not allocate generic netns"); +- +- rcu_assign_pointer(init_net.gen, ng); +- + mutex_lock(&net_mutex); + err = setup_net(&init_net); + +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/net/core/net-sysfs.c linux-2.6.29-rc3.owrt/net/core/net-sysfs.c +--- linux-2.6.29.owrt/net/core/net-sysfs.c 2009-05-10 22:04:39.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/net/core/net-sysfs.c 2009-05-10 23:48:33.000000000 +0200 +@@ -77,9 +77,7 @@ + if (endp == buf) + goto err; + +- if (!rtnl_trylock()) +- return -ERESTARTSYS; +- ++ rtnl_lock(); + if (dev_isalive(net)) { + if ((ret = (*set)(net, new)) == 0) + ret = len; +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/net/core/skbuff.c linux-2.6.29-rc3.owrt/net/core/skbuff.c +--- linux-2.6.29.owrt/net/core/skbuff.c 2009-05-10 22:04:39.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/net/core/skbuff.c 2009-05-10 23:48:33.000000000 +0200 +@@ -220,6 +220,14 @@ + BUG(); + } + ++void skb_truesize_bug(struct sk_buff *skb) ++{ ++ WARN(net_ratelimit(), KERN_ERR "SKB BUG: Invalid truesize (%u) " ++ "len=%u, sizeof(sk_buff)=%Zd\n", ++ skb->truesize, skb->len, sizeof(struct sk_buff)); ++} ++EXPORT_SYMBOL(skb_truesize_bug); ++ + /* Allocate a new skbuff. We do this ourselves so we can fill in a few + * 'private' fields and also do memory statistics to find all the + * [BEEP] leaks. +@@ -2293,10 +2301,10 @@ + return 0; + + next_skb: +- block_limit = skb_headlen(st->cur_skb) + st->stepped_offset; ++ block_limit = skb_headlen(st->cur_skb); + + if (abs_offset < block_limit) { +- *data = st->cur_skb->data + (abs_offset - st->stepped_offset); ++ *data = st->cur_skb->data + abs_offset; + return block_limit - abs_offset; + } + +@@ -2331,15 +2339,14 @@ + st->frag_data = NULL; + } + +- if (st->root_skb == st->cur_skb && +- skb_shinfo(st->root_skb)->frag_list) { +- st->cur_skb = skb_shinfo(st->root_skb)->frag_list; +- st->frag_idx = 0; +- goto next_skb; +- } else if (st->cur_skb->next) { ++ if (st->cur_skb->next) { + st->cur_skb = st->cur_skb->next; + st->frag_idx = 0; + goto next_skb; ++ } else if (st->root_skb == st->cur_skb && ++ skb_shinfo(st->root_skb)->frag_list) { ++ st->cur_skb = skb_shinfo(st->root_skb)->frag_list; ++ goto next_skb; + } + + return 0; +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/net/core/sock.c linux-2.6.29-rc3.owrt/net/core/sock.c +--- linux-2.6.29.owrt/net/core/sock.c 2009-05-10 22:04:39.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/net/core/sock.c 2009-05-10 23:48:33.000000000 +0200 +@@ -696,8 +696,6 @@ + if (len < 0) + return -EINVAL; + +- memset(&v, 0, sizeof(v)); +- + switch(optname) { + case SO_DEBUG: + v.val = sock_flag(sk, SOCK_DBG); +@@ -1137,6 +1135,7 @@ + { + struct sock *sk = skb->sk; + ++ skb_truesize_check(skb); + atomic_sub(skb->truesize, &sk->sk_rmem_alloc); + sk_mem_uncharge(skb->sk, skb->truesize); + } +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/net/ipv4/cipso_ipv4.c linux-2.6.29-rc3.owrt/net/ipv4/cipso_ipv4.c +--- linux-2.6.29.owrt/net/ipv4/cipso_ipv4.c 2009-05-10 22:04:39.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/net/ipv4/cipso_ipv4.c 2009-05-10 23:48:33.000000000 +0200 +@@ -3,16 +3,11 @@ + * + * This is an implementation of the CIPSO 2.2 protocol as specified in + * draft-ietf-cipso-ipsecurity-01.txt with additional tag types as found in +- * FIPS-188. While CIPSO never became a full IETF RFC standard many vendors ++ * FIPS-188, copies of both documents can be found in the Documentation ++ * directory. While CIPSO never became a full IETF RFC standard many vendors + * have chosen to adopt the protocol and over the years it has become a + * de-facto standard for labeled networking. + * +- * The CIPSO draft specification can be found in the kernel's Documentation +- * directory as well as the following URL: +- * http://netlabel.sourceforge.net/files/draft-ietf-cipso-ipsecurity-01.txt +- * The FIPS-188 specification can be found at the following URL: +- * http://www.itl.nist.gov/fipspubs/fip188.htm +- * + * Author: Paul Moore <paul.moore@hp.com> + * + */ +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/net/ipv4/icmp.c linux-2.6.29-rc3.owrt/net/ipv4/icmp.c +--- linux-2.6.29.owrt/net/ipv4/icmp.c 2009-05-10 22:04:39.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/net/ipv4/icmp.c 2009-05-10 23:48:33.000000000 +0200 +@@ -1205,7 +1205,7 @@ + + int __init icmp_init(void) + { +- return register_pernet_subsys(&icmp_sk_ops); ++ return register_pernet_device(&icmp_sk_ops); + } + + EXPORT_SYMBOL(icmp_err_convert); +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/net/ipv4/ipconfig.c linux-2.6.29-rc3.owrt/net/ipv4/ipconfig.c +--- linux-2.6.29.owrt/net/ipv4/ipconfig.c 2009-05-10 22:04:39.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/net/ipv4/ipconfig.c 2009-05-10 23:48:33.000000000 +0200 +@@ -1268,9 +1268,6 @@ + static int __init ip_auto_config(void) + { + __be32 addr; +-#ifdef IPCONFIG_DYNAMIC +- int retries = CONF_OPEN_RETRIES; +-#endif + + #ifdef CONFIG_PROC_FS + proc_net_fops_create(&init_net, "pnp", S_IRUGO, &pnp_seq_fops); +@@ -1307,6 +1304,9 @@ + #endif + ic_first_dev->next) { + #ifdef IPCONFIG_DYNAMIC ++ ++ int retries = CONF_OPEN_RETRIES; ++ + if (ic_dynamic() < 0) { + ic_close_devs(); + +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/net/ipv4/ip_fragment.c linux-2.6.29-rc3.owrt/net/ipv4/ip_fragment.c +--- linux-2.6.29.owrt/net/ipv4/ip_fragment.c 2009-05-10 22:04:39.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/net/ipv4/ip_fragment.c 2009-05-10 23:48:33.000000000 +0200 +@@ -463,7 +463,6 @@ + static int ip_frag_reasm(struct ipq *qp, struct sk_buff *prev, + struct net_device *dev) + { +- struct net *net = container_of(qp->q.net, struct net, ipv4.frags); + struct iphdr *iph; + struct sk_buff *fp, *head = qp->q.fragments; + int len; +@@ -549,7 +548,7 @@ + iph = ip_hdr(head); + iph->frag_off = 0; + iph->tot_len = htons(len); +- IP_INC_STATS_BH(net, IPSTATS_MIB_REASMOKS); ++ IP_INC_STATS_BH(dev_net(dev), IPSTATS_MIB_REASMOKS); + qp->q.fragments = NULL; + return 0; + +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/net/ipv4/tcp.c linux-2.6.29-rc3.owrt/net/ipv4/tcp.c +--- linux-2.6.29.owrt/net/ipv4/tcp.c 2009-05-10 22:04:39.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/net/ipv4/tcp.c 2009-05-10 23:48:33.000000000 +0200 +@@ -524,8 +524,7 @@ + struct tcp_splice_state *tss = rd_desc->arg.data; + int ret; + +- ret = skb_splice_bits(skb, offset, tss->pipe, min(rd_desc->count, len), +- tss->flags); ++ ret = skb_splice_bits(skb, offset, tss->pipe, rd_desc->count, tss->flags); + if (ret > 0) + rd_desc->count -= ret; + return ret; +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/net/ipv4/tcp_input.c linux-2.6.29-rc3.owrt/net/ipv4/tcp_input.c +--- linux-2.6.29.owrt/net/ipv4/tcp_input.c 2009-05-10 22:04:39.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/net/ipv4/tcp_input.c 2009-05-10 23:48:34.000000000 +0200 +@@ -1374,8 +1374,7 @@ + + static int tcp_shifted_skb(struct sock *sk, struct sk_buff *skb, + struct tcp_sacktag_state *state, +- unsigned int pcount, int shifted, int mss, +- int dup_sack) ++ unsigned int pcount, int shifted, int mss) + { + struct tcp_sock *tp = tcp_sk(sk); + struct sk_buff *prev = tcp_write_queue_prev(sk, skb); +@@ -1411,7 +1410,7 @@ + } + + /* We discard results */ +- tcp_sacktag_one(skb, sk, state, dup_sack, pcount); ++ tcp_sacktag_one(skb, sk, state, 0, pcount); + + /* Difference in this won't matter, both ACKed by the same cumul. ACK */ + TCP_SKB_CB(prev)->sacked |= (TCP_SKB_CB(skb)->sacked & TCPCB_EVER_RETRANS); +@@ -1562,7 +1561,7 @@ + + if (!skb_shift(prev, skb, len)) + goto fallback; +- if (!tcp_shifted_skb(sk, skb, state, pcount, len, mss, dup_sack)) ++ if (!tcp_shifted_skb(sk, skb, state, pcount, len, mss)) + goto out; + + /* Hole filled allows collapsing with the next as well, this is very +@@ -1581,7 +1580,7 @@ + len = skb->len; + if (skb_shift(prev, skb, len)) { + pcount += tcp_skb_pcount(skb); +- tcp_shifted_skb(sk, skb, state, tcp_skb_pcount(skb), len, mss, 0); ++ tcp_shifted_skb(sk, skb, state, tcp_skb_pcount(skb), len, mss); + } + + out: +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/net/ipv4/tcp_ipv4.c linux-2.6.29-rc3.owrt/net/ipv4/tcp_ipv4.c +--- linux-2.6.29.owrt/net/ipv4/tcp_ipv4.c 2009-05-10 22:04:39.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/net/ipv4/tcp_ipv4.c 2009-05-10 23:48:34.000000000 +0200 +@@ -2443,7 +2443,7 @@ + void __init tcp_v4_init(void) + { + inet_hashinfo_init(&tcp_hashinfo); +- if (register_pernet_subsys(&tcp_sk_ops)) ++ if (register_pernet_device(&tcp_sk_ops)) + panic("Failed to create the TCP control socket.\n"); + } + +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/net/ipv4/tcp_output.c linux-2.6.29-rc3.owrt/net/ipv4/tcp_output.c +--- linux-2.6.29.owrt/net/ipv4/tcp_output.c 2009-05-10 22:04:39.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/net/ipv4/tcp_output.c 2009-05-10 23:48:34.000000000 +0200 +@@ -663,10 +663,14 @@ + th->urg_ptr = 0; + + /* The urg_mode check is necessary during a below snd_una win probe */ +- if (unlikely(tcp_urg_mode(tp) && +- between(tp->snd_up, tcb->seq + 1, tcb->seq + 0xFFFF))) { +- th->urg_ptr = htons(tp->snd_up - tcb->seq); +- th->urg = 1; ++ if (unlikely(tcp_urg_mode(tp))) { ++ if (between(tp->snd_up, tcb->seq + 1, tcb->seq + 0xFFFF)) { ++ th->urg_ptr = htons(tp->snd_up - tcb->seq); ++ th->urg = 1; ++ } else if (after(tcb->seq + 0xFFFF, tp->snd_nxt)) { ++ th->urg_ptr = 0xFFFF; ++ th->urg = 1; ++ } + } + + tcp_options_write((__be32 *)(th + 1), tp, &opts, &md5_hash_location); +@@ -2023,6 +2027,7 @@ + last_lost = tp->snd_una; + } + ++ /* First pass: retransmit lost packets. */ + tcp_for_write_queue_from(skb, sk) { + __u8 sacked = TCP_SKB_CB(skb)->sacked; + +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/net/ipv4/tcp_scalable.c linux-2.6.29-rc3.owrt/net/ipv4/tcp_scalable.c +--- linux-2.6.29.owrt/net/ipv4/tcp_scalable.c 2009-05-10 22:04:39.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/net/ipv4/tcp_scalable.c 2009-05-10 23:48:34.000000000 +0200 +@@ -1,6 +1,6 @@ + /* Tom Kelly's Scalable TCP + * +- * See http://www.deneholme.net/tom/scalable/ ++ * See htt://www-lce.eng.cam.ac.uk/~ctk21/scalable/ + * + * John Heffner <jheffner@sc.edu> + */ +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/net/ipv4/udp.c linux-2.6.29-rc3.owrt/net/ipv4/udp.c +--- linux-2.6.29.owrt/net/ipv4/udp.c 2009-05-10 22:04:39.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/net/ipv4/udp.c 2009-05-10 23:48:34.000000000 +0200 +@@ -120,11 +120,8 @@ + atomic_t udp_memory_allocated; + EXPORT_SYMBOL(udp_memory_allocated); + +-#define PORTS_PER_CHAIN (65536 / UDP_HTABLE_SIZE) +- + static int udp_lib_lport_inuse(struct net *net, __u16 num, + const struct udp_hslot *hslot, +- unsigned long *bitmap, + struct sock *sk, + int (*saddr_comp)(const struct sock *sk1, + const struct sock *sk2)) +@@ -135,17 +132,12 @@ + sk_nulls_for_each(sk2, node, &hslot->head) + if (net_eq(sock_net(sk2), net) && + sk2 != sk && +- (bitmap || sk2->sk_hash == num) && ++ sk2->sk_hash == num && + (!sk2->sk_reuse || !sk->sk_reuse) && + (!sk2->sk_bound_dev_if || !sk->sk_bound_dev_if + || sk2->sk_bound_dev_if == sk->sk_bound_dev_if) && +- (*saddr_comp)(sk, sk2)) { +- if (bitmap) +- __set_bit(sk2->sk_hash / UDP_HTABLE_SIZE, +- bitmap); +- else +- return 1; +- } ++ (*saddr_comp)(sk, sk2)) ++ return 1; + return 0; + } + +@@ -168,47 +160,32 @@ + if (!snum) { + int low, high, remaining; + unsigned rand; +- unsigned short first, last; +- DECLARE_BITMAP(bitmap, PORTS_PER_CHAIN); ++ unsigned short first; + + inet_get_local_port_range(&low, &high); + remaining = (high - low) + 1; + + rand = net_random(); +- first = (((u64)rand * remaining) >> 32) + low; +- /* +- * force rand to be an odd multiple of UDP_HTABLE_SIZE +- */ +- rand = (rand | 1) * UDP_HTABLE_SIZE; +- for (last = first + UDP_HTABLE_SIZE; first != last; first++) { +- hslot = &udptable->hash[udp_hashfn(net, first)]; +- bitmap_zero(bitmap, PORTS_PER_CHAIN); ++ snum = first = rand % remaining + low; ++ rand |= 1; ++ for (;;) { ++ hslot = &udptable->hash[udp_hashfn(net, snum)]; + spin_lock_bh(&hslot->lock); +- udp_lib_lport_inuse(net, snum, hslot, bitmap, sk, +- saddr_comp); +- +- snum = first; +- /* +- * Iterate on all possible values of snum for this hash. +- * Using steps of an odd multiple of UDP_HTABLE_SIZE +- * give us randomization and full range coverage. +- */ +- do { +- if (low <= snum && snum <= high && +- !test_bit(snum / UDP_HTABLE_SIZE, bitmap)) +- goto found; +- snum += rand; +- } while (snum != first); ++ if (!udp_lib_lport_inuse(net, snum, hslot, sk, saddr_comp)) ++ break; + spin_unlock_bh(&hslot->lock); ++ do { ++ snum = snum + rand; ++ } while (snum < low || snum > high); ++ if (snum == first) ++ goto fail; + } +- goto fail; + } else { + hslot = &udptable->hash[udp_hashfn(net, snum)]; + spin_lock_bh(&hslot->lock); +- if (udp_lib_lport_inuse(net, snum, hslot, NULL, sk, saddr_comp)) ++ if (udp_lib_lport_inuse(net, snum, hslot, sk, saddr_comp)) + goto fail_unlock; + } +-found: + inet_sk(sk)->num = snum; + sk->sk_hash = snum; + if (sk_unhashed(sk)) { +@@ -1015,11 +992,9 @@ + + if ((rc = sock_queue_rcv_skb(sk, skb)) < 0) { + /* Note that an ENOMEM error is charged twice */ +- if (rc == -ENOMEM) { ++ if (rc == -ENOMEM) + UDP_INC_STATS_BH(sock_net(sk), UDP_MIB_RCVBUFERRORS, + is_udplite); +- atomic_inc(&sk->sk_drops); +- } + goto drop; + } + +@@ -1231,10 +1206,11 @@ + int proto) + { + struct sock *sk; +- struct udphdr *uh; ++ struct udphdr *uh = udp_hdr(skb); + unsigned short ulen; + struct rtable *rt = (struct rtable*)skb->dst; +- __be32 saddr, daddr; ++ __be32 saddr = ip_hdr(skb)->saddr; ++ __be32 daddr = ip_hdr(skb)->daddr; + struct net *net = dev_net(skb->dev); + + /* +@@ -1243,7 +1219,6 @@ + if (!pskb_may_pull(skb, sizeof(struct udphdr))) + goto drop; /* No space for header. */ + +- uh = udp_hdr(skb); + ulen = ntohs(uh->len); + if (ulen > skb->len) + goto short_packet; +@@ -1258,9 +1233,6 @@ + if (udp4_csum_init(skb, uh, proto)) + goto csum_error; + +- saddr = ip_hdr(skb)->saddr; +- daddr = ip_hdr(skb)->daddr; +- + if (rt->rt_flags & (RTCF_BROADCAST|RTCF_MULTICAST)) + return __udp4_lib_mcast_deliver(net, skb, uh, + saddr, daddr, udptable); +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/net/ipv6/addrconf.c linux-2.6.29-rc3.owrt/net/ipv6/addrconf.c +--- linux-2.6.29.owrt/net/ipv6/addrconf.c 2009-05-10 22:04:39.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/net/ipv6/addrconf.c 2009-05-10 23:48:34.000000000 +0200 +@@ -493,17 +493,15 @@ + read_unlock(&dev_base_lock); + } + +-static int addrconf_fixup_forwarding(struct ctl_table *table, int *p, int old) ++static void addrconf_fixup_forwarding(struct ctl_table *table, int *p, int old) + { + struct net *net; + + net = (struct net *)table->extra2; + if (p == &net->ipv6.devconf_dflt->forwarding) +- return 0; +- +- if (!rtnl_trylock()) +- return -ERESTARTSYS; ++ return; + ++ rtnl_lock(); + if (p == &net->ipv6.devconf_all->forwarding) { + __s32 newf = net->ipv6.devconf_all->forwarding; + net->ipv6.devconf_dflt->forwarding = newf; +@@ -514,7 +512,6 @@ + + if (*p) + rt6_purge_dflt_routers(net); +- return 1; + } + #endif + +@@ -2611,6 +2608,9 @@ + + ASSERT_RTNL(); + ++ if ((dev->flags & IFF_LOOPBACK) && how == 1) ++ how = 0; ++ + rt6_ifdown(net, dev); + neigh_ifdown(&nd_tbl, dev); + +@@ -3983,7 +3983,7 @@ + ret = proc_dointvec(ctl, write, filp, buffer, lenp, ppos); + + if (write) +- ret = addrconf_fixup_forwarding(ctl, valp, val); ++ addrconf_fixup_forwarding(ctl, valp, val); + return ret; + } + +@@ -4019,7 +4019,8 @@ + } + + *valp = new; +- return addrconf_fixup_forwarding(table, valp, val); ++ addrconf_fixup_forwarding(table, valp, val); ++ return 1; + } + + static struct addrconf_sysctl_table +@@ -4249,7 +4250,7 @@ + .procname = "mc_forwarding", + .data = &ipv6_devconf.mc_forwarding, + .maxlen = sizeof(int), +- .mode = 0444, ++ .mode = 0644, + .proc_handler = proc_dointvec, + }, + #endif +@@ -4445,6 +4446,25 @@ + + EXPORT_SYMBOL(unregister_inet6addr_notifier); + ++static void addrconf_net_exit(struct net *net) ++{ ++ struct net_device *dev; ++ ++ rtnl_lock(); ++ /* clean dev list */ ++ for_each_netdev(net, dev) { ++ if (__in6_dev_get(dev) == NULL) ++ continue; ++ addrconf_ifdown(dev, 1); ++ } ++ addrconf_ifdown(net->loopback_dev, 2); ++ rtnl_unlock(); ++} ++ ++static struct pernet_operations addrconf_net_ops = { ++ .exit = addrconf_net_exit, ++}; ++ + /* + * Init / cleanup code + */ +@@ -4486,6 +4506,10 @@ + if (err) + goto errlo; + ++ err = register_pernet_device(&addrconf_net_ops); ++ if (err) ++ return err; ++ + register_netdevice_notifier(&ipv6_dev_notf); + + addrconf_verify(0); +@@ -4515,22 +4539,15 @@ + void addrconf_cleanup(void) + { + struct inet6_ifaddr *ifa; +- struct net_device *dev; + int i; + + unregister_netdevice_notifier(&ipv6_dev_notf); ++ unregister_pernet_device(&addrconf_net_ops); ++ + unregister_pernet_subsys(&addrconf_ops); + + rtnl_lock(); + +- /* clean dev list */ +- for_each_netdev(&init_net, dev) { +- if (__in6_dev_get(dev) == NULL) +- continue; +- addrconf_ifdown(dev, 1); +- } +- addrconf_ifdown(init_net.loopback_dev, 2); +- + /* + * Check hash table. + */ +@@ -4551,4 +4568,6 @@ + + del_timer(&addr_chk_timer); + rtnl_unlock(); ++ ++ unregister_pernet_subsys(&addrconf_net_ops); + } +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/net/ipv6/af_inet6.c linux-2.6.29-rc3.owrt/net/ipv6/af_inet6.c +--- linux-2.6.29.owrt/net/ipv6/af_inet6.c 2009-05-10 22:04:39.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/net/ipv6/af_inet6.c 2009-05-10 23:48:34.000000000 +0200 +@@ -72,10 +72,6 @@ + static struct list_head inetsw6[SOCK_MAX]; + static DEFINE_SPINLOCK(inetsw6_lock); + +-static int disable_ipv6 = 0; +-module_param_named(disable, disable_ipv6, int, 0); +-MODULE_PARM_DESC(disable, "Disable IPv6 such that it is non-functional"); +- + static __inline__ struct ipv6_pinfo *inet6_sk_generic(struct sock *sk) + { + const int offset = sk->sk_prot->obj_size - sizeof(struct ipv6_pinfo); +@@ -995,21 +991,10 @@ + { + struct sk_buff *dummy_skb; + struct list_head *r; +- int err = 0; ++ int err; + + BUILD_BUG_ON(sizeof(struct inet6_skb_parm) > sizeof(dummy_skb->cb)); + +- /* Register the socket-side information for inet6_create. */ +- for(r = &inetsw6[0]; r < &inetsw6[SOCK_MAX]; ++r) +- INIT_LIST_HEAD(r); +- +- if (disable_ipv6) { +- printk(KERN_INFO +- "IPv6: Loaded, but administratively disabled, " +- "reboot required to enable\n"); +- goto out; +- } +- + err = proto_register(&tcpv6_prot, 1); + if (err) + goto out; +@@ -1027,6 +1012,10 @@ + goto out_unregister_udplite_proto; + + ++ /* Register the socket-side information for inet6_create. */ ++ for(r = &inetsw6[0]; r < &inetsw6[SOCK_MAX]; ++r) ++ INIT_LIST_HEAD(r); ++ + /* We MUST register RAW sockets before we create the ICMP6, + * IGMP6, or NDISC control sockets. + */ +@@ -1192,9 +1181,6 @@ + + static void __exit inet6_exit(void) + { +- if (disable_ipv6) +- return; +- + /* First of all disallow new sockets creation. */ + sock_unregister(PF_INET6); + /* Disallow any further netlink messages */ +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/net/ipv6/icmp.c linux-2.6.29-rc3.owrt/net/ipv6/icmp.c +--- linux-2.6.29.owrt/net/ipv6/icmp.c 2009-05-10 22:04:39.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/net/ipv6/icmp.c 2009-05-10 23:48:34.000000000 +0200 +@@ -443,10 +443,10 @@ + if (xfrm_decode_session_reverse(skb, &fl2, AF_INET6)) + goto relookup_failed; + +- if (ip6_dst_lookup(sk, &dst2, &fl2)) ++ if (ip6_dst_lookup(sk, &dst2, &fl)) + goto relookup_failed; + +- err = xfrm_lookup(net, &dst2, &fl2, sk, XFRM_LOOKUP_ICMP); ++ err = xfrm_lookup(net, &dst2, &fl, sk, XFRM_LOOKUP_ICMP); + switch (err) { + case 0: + dst_release(dst); +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/net/ipv6/inet6_hashtables.c linux-2.6.29-rc3.owrt/net/ipv6/inet6_hashtables.c +--- linux-2.6.29.owrt/net/ipv6/inet6_hashtables.c 2009-05-10 22:04:39.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/net/ipv6/inet6_hashtables.c 2009-05-10 23:48:34.000000000 +0200 +@@ -258,11 +258,11 @@ + + if (twp != NULL) { + *twp = tw; +- NET_INC_STATS_BH(net, LINUX_MIB_TIMEWAITRECYCLED); ++ NET_INC_STATS_BH(twsk_net(tw), LINUX_MIB_TIMEWAITRECYCLED); + } else if (tw != NULL) { + /* Silly. Should hash-dance instead... */ + inet_twsk_deschedule(tw, death_row); +- NET_INC_STATS_BH(net, LINUX_MIB_TIMEWAITRECYCLED); ++ NET_INC_STATS_BH(twsk_net(tw), LINUX_MIB_TIMEWAITRECYCLED); + + inet_twsk_put(tw); + } +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/net/ipv6/ip6_flowlabel.c linux-2.6.29-rc3.owrt/net/ipv6/ip6_flowlabel.c +--- linux-2.6.29.owrt/net/ipv6/ip6_flowlabel.c 2009-05-10 22:04:39.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/net/ipv6/ip6_flowlabel.c 2009-05-10 23:48:34.000000000 +0200 +@@ -323,21 +323,17 @@ + fl_create(struct net *net, struct in6_flowlabel_req *freq, char __user *optval, + int optlen, int *err_p) + { +- struct ip6_flowlabel *fl = NULL; ++ struct ip6_flowlabel *fl; + int olen; + int addr_type; + int err; + +- olen = optlen - CMSG_ALIGN(sizeof(*freq)); +- err = -EINVAL; +- if (olen > 64 * 1024) +- goto done; +- + err = -ENOMEM; + fl = kzalloc(sizeof(*fl), GFP_KERNEL); + if (fl == NULL) + goto done; + ++ olen = optlen - CMSG_ALIGN(sizeof(*freq)); + if (olen > 0) { + struct msghdr msg; + struct flowi flowi; +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/net/ipv6/ip6_input.c linux-2.6.29-rc3.owrt/net/ipv6/ip6_input.c +--- linux-2.6.29.owrt/net/ipv6/ip6_input.c 2009-05-10 22:04:39.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/net/ipv6/ip6_input.c 2009-05-10 23:48:34.000000000 +0200 +@@ -255,7 +255,6 @@ + * IPv6 multicast router mode is now supported ;) + */ + if (dev_net(skb->dev)->ipv6.devconf_all->mc_forwarding && +- !(ipv6_addr_type(&hdr->daddr) & IPV6_ADDR_LINKLOCAL) && + likely(!(IP6CB(skb)->flags & IP6SKB_FORWARDED))) { + /* + * Okay, we try to forward - split and duplicate +@@ -317,6 +316,7 @@ + } + + if (skb2) { ++ skb2->dev = skb2->dst->dev; + ip6_mr_input(skb2); + } + } +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/net/ipv6/ip6mr.c linux-2.6.29-rc3.owrt/net/ipv6/ip6mr.c +--- linux-2.6.29.owrt/net/ipv6/ip6mr.c 2009-05-10 22:04:39.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/net/ipv6/ip6mr.c 2009-05-10 23:48:34.000000000 +0200 +@@ -48,7 +48,6 @@ + #include <linux/pim.h> + #include <net/addrconf.h> + #include <linux/netfilter_ipv6.h> +-#include <net/ip6_checksum.h> + + /* Big lock, protecting vif table, mrt cache and mroute socket state. + Note that the changes are semaphored via rtnl_lock. +@@ -366,9 +365,7 @@ + pim = (struct pimreghdr *)skb_transport_header(skb); + if (pim->type != ((PIM_VERSION << 4) | PIM_REGISTER) || + (pim->flags & PIM_NULL_REGISTER) || +- (csum_ipv6_magic(&ipv6_hdr(skb)->saddr, &ipv6_hdr(skb)->daddr, +- sizeof(*pim), IPPROTO_PIM, +- csum_partial((void *)pim, sizeof(*pim), 0)) && ++ (ip_compute_csum((void *)pim, sizeof(*pim)) != 0 && + csum_fold(skb_checksum(skb, 0, skb->len, 0)))) + goto drop; + +@@ -395,7 +392,7 @@ + skb_pull(skb, (u8 *)encap - skb->data); + skb_reset_network_header(skb); + skb->dev = reg_dev; +- skb->protocol = htons(ETH_P_IPV6); ++ skb->protocol = htons(ETH_P_IP); + skb->ip_summed = 0; + skb->pkt_type = PACKET_HOST; + dst_release(skb->dst); +@@ -484,7 +481,6 @@ + { + struct mif_device *v; + struct net_device *dev; +- struct inet6_dev *in6_dev; + if (vifi < 0 || vifi >= net->ipv6.maxvif) + return -EADDRNOTAVAIL; + +@@ -517,10 +513,6 @@ + + dev_set_allmulti(dev, -1); + +- in6_dev = __in6_dev_get(dev); +- if (in6_dev) +- in6_dev->cnf.mc_forwarding--; +- + if (v->flags & MIFF_REGISTER) + unregister_netdevice(dev); + +@@ -630,7 +622,6 @@ + int vifi = vifc->mif6c_mifi; + struct mif_device *v = &net->ipv6.vif6_table[vifi]; + struct net_device *dev; +- struct inet6_dev *in6_dev; + int err; + + /* Is vif busy ? */ +@@ -671,10 +662,6 @@ + return -EINVAL; + } + +- in6_dev = __in6_dev_get(dev); +- if (in6_dev) +- in6_dev->cnf.mc_forwarding++; +- + /* + * Fill in the VIF structures + */ +@@ -851,6 +838,8 @@ + + skb->dst = dst_clone(pkt->dst); + skb->ip_summed = CHECKSUM_UNNECESSARY; ++ ++ skb_pull(skb, sizeof(struct ipv6hdr)); + } + + if (net->ipv6.mroute6_sk == NULL) { +@@ -1233,10 +1222,8 @@ + + rtnl_lock(); + write_lock_bh(&mrt_lock); +- if (likely(net->ipv6.mroute6_sk == NULL)) { ++ if (likely(net->ipv6.mroute6_sk == NULL)) + net->ipv6.mroute6_sk = sk; +- net->ipv6.devconf_all->mc_forwarding++; +- } + else + err = -EADDRINUSE; + write_unlock_bh(&mrt_lock); +@@ -1255,7 +1242,6 @@ + if (sk == net->ipv6.mroute6_sk) { + write_lock_bh(&mrt_lock); + net->ipv6.mroute6_sk = NULL; +- net->ipv6.devconf_all->mc_forwarding--; + write_unlock_bh(&mrt_lock); + + mroute_clean_tables(net); +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/net/ipv6/ip6_output.c linux-2.6.29-rc3.owrt/net/ipv6/ip6_output.c +--- linux-2.6.29.owrt/net/ipv6/ip6_output.c 2009-05-10 22:04:39.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/net/ipv6/ip6_output.c 2009-05-10 23:48:34.000000000 +0200 +@@ -1105,18 +1105,6 @@ + return err; + } + +-static inline struct ipv6_opt_hdr *ip6_opt_dup(struct ipv6_opt_hdr *src, +- gfp_t gfp) +-{ +- return src ? kmemdup(src, (src->hdrlen + 1) * 8, gfp) : NULL; +-} +- +-static inline struct ipv6_rt_hdr *ip6_rthdr_dup(struct ipv6_rt_hdr *src, +- gfp_t gfp) +-{ +- return src ? kmemdup(src, (src->hdrlen + 1) * 8, gfp) : NULL; +-} +- + int ip6_append_data(struct sock *sk, int getfrag(void *from, char *to, + int offset, int len, int odd, struct sk_buff *skb), + void *from, int length, int transhdrlen, +@@ -1142,37 +1130,17 @@ + * setup for corking + */ + if (opt) { +- if (WARN_ON(np->cork.opt)) ++ if (np->cork.opt == NULL) { ++ np->cork.opt = kmalloc(opt->tot_len, ++ sk->sk_allocation); ++ if (unlikely(np->cork.opt == NULL)) ++ return -ENOBUFS; ++ } else if (np->cork.opt->tot_len < opt->tot_len) { ++ printk(KERN_DEBUG "ip6_append_data: invalid option length\n"); + return -EINVAL; +- +- np->cork.opt = kmalloc(opt->tot_len, sk->sk_allocation); +- if (unlikely(np->cork.opt == NULL)) +- return -ENOBUFS; +- +- np->cork.opt->tot_len = opt->tot_len; +- np->cork.opt->opt_flen = opt->opt_flen; +- np->cork.opt->opt_nflen = opt->opt_nflen; +- +- np->cork.opt->dst0opt = ip6_opt_dup(opt->dst0opt, +- sk->sk_allocation); +- if (opt->dst0opt && !np->cork.opt->dst0opt) +- return -ENOBUFS; +- +- np->cork.opt->dst1opt = ip6_opt_dup(opt->dst1opt, +- sk->sk_allocation); +- if (opt->dst1opt && !np->cork.opt->dst1opt) +- return -ENOBUFS; +- +- np->cork.opt->hopopt = ip6_opt_dup(opt->hopopt, +- sk->sk_allocation); +- if (opt->hopopt && !np->cork.opt->hopopt) +- return -ENOBUFS; +- +- np->cork.opt->srcrt = ip6_rthdr_dup(opt->srcrt, +- sk->sk_allocation); +- if (opt->srcrt && !np->cork.opt->srcrt) +- return -ENOBUFS; +- ++ } ++ memcpy(np->cork.opt, opt, opt->tot_len); ++ inet->cork.flags |= IPCORK_OPT; + /* need source address above miyazawa*/ + } + dst_hold(&rt->u.dst); +@@ -1199,7 +1167,8 @@ + } else { + rt = (struct rt6_info *)inet->cork.dst; + fl = &inet->cork.fl; +- opt = np->cork.opt; ++ if (inet->cork.flags & IPCORK_OPT) ++ opt = np->cork.opt; + transhdrlen = 0; + exthdrlen = 0; + mtu = inet->cork.fragsize; +@@ -1438,15 +1407,9 @@ + + static void ip6_cork_release(struct inet_sock *inet, struct ipv6_pinfo *np) + { +- if (np->cork.opt) { +- kfree(np->cork.opt->dst0opt); +- kfree(np->cork.opt->dst1opt); +- kfree(np->cork.opt->hopopt); +- kfree(np->cork.opt->srcrt); +- kfree(np->cork.opt); +- np->cork.opt = NULL; +- } +- ++ inet->cork.flags &= ~IPCORK_OPT; ++ kfree(np->cork.opt); ++ np->cork.opt = NULL; + if (inet->cork.dst) { + dst_release(inet->cork.dst); + inet->cork.dst = NULL; +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/net/ipv6/ip6_tunnel.c linux-2.6.29-rc3.owrt/net/ipv6/ip6_tunnel.c +--- linux-2.6.29.owrt/net/ipv6/ip6_tunnel.c 2009-05-10 22:04:39.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/net/ipv6/ip6_tunnel.c 2009-05-10 23:48:34.000000000 +0200 +@@ -249,8 +249,8 @@ + } + + t = netdev_priv(dev); +- t->parms = *p; + ip6_tnl_dev_init(dev); ++ t->parms = *p; + + if ((err = register_netdevice(dev)) < 0) + goto failed_free; +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/net/ipv6/netfilter/nf_conntrack_proto_icmpv6.c linux-2.6.29-rc3.owrt/net/ipv6/netfilter/nf_conntrack_proto_icmpv6.c +--- linux-2.6.29.owrt/net/ipv6/netfilter/nf_conntrack_proto_icmpv6.c 2009-05-10 22:04:39.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/net/ipv6/netfilter/nf_conntrack_proto_icmpv6.c 2009-05-10 23:48:34.000000000 +0200 +@@ -49,19 +49,8 @@ + static const u_int8_t invmap[] = { + [ICMPV6_ECHO_REQUEST - 128] = ICMPV6_ECHO_REPLY + 1, + [ICMPV6_ECHO_REPLY - 128] = ICMPV6_ECHO_REQUEST + 1, +- [ICMPV6_NI_QUERY - 128] = ICMPV6_NI_REPLY + 1, +- [ICMPV6_NI_REPLY - 128] = ICMPV6_NI_QUERY +1 +-}; +- +-static const u_int8_t noct_valid_new[] = { +- [ICMPV6_MGM_QUERY - 130] = 1, +- [ICMPV6_MGM_REPORT -130] = 1, +- [ICMPV6_MGM_REDUCTION - 130] = 1, +- [NDISC_ROUTER_SOLICITATION - 130] = 1, +- [NDISC_ROUTER_ADVERTISEMENT - 130] = 1, +- [NDISC_NEIGHBOUR_SOLICITATION - 130] = 1, +- [NDISC_NEIGHBOUR_ADVERTISEMENT - 130] = 1, +- [ICMPV6_MLD2_REPORT - 130] = 1 ++ [ICMPV6_NI_QUERY - 128] = ICMPV6_NI_QUERY + 1, ++ [ICMPV6_NI_REPLY - 128] = ICMPV6_NI_REPLY +1 + }; + + static bool icmpv6_invert_tuple(struct nf_conntrack_tuple *tuple, +@@ -189,7 +178,6 @@ + { + const struct icmp6hdr *icmp6h; + struct icmp6hdr _ih; +- int type; + + icmp6h = skb_header_pointer(skb, dataoff, sizeof(_ih), &_ih); + if (icmp6h == NULL) { +@@ -201,21 +189,11 @@ + + if (net->ct.sysctl_checksum && hooknum == NF_INET_PRE_ROUTING && + nf_ip6_checksum(skb, hooknum, dataoff, IPPROTO_ICMPV6)) { +- if (LOG_INVALID(net, IPPROTO_ICMPV6)) +- nf_log_packet(PF_INET6, 0, skb, NULL, NULL, NULL, +- "nf_ct_icmpv6: ICMPv6 checksum failed "); ++ nf_log_packet(PF_INET6, 0, skb, NULL, NULL, NULL, ++ "nf_ct_icmpv6: ICMPv6 checksum failed\n"); + return -NF_ACCEPT; + } + +- type = icmp6h->icmp6_type - 130; +- if (type >= 0 && type < sizeof(noct_valid_new) && +- noct_valid_new[type]) { +- skb->nfct = &nf_conntrack_untracked.ct_general; +- skb->nfctinfo = IP_CT_NEW; +- nf_conntrack_get(skb->nfct); +- return NF_ACCEPT; +- } +- + /* is not error message ? */ + if (icmp6h->icmp6_type >= 128) + return NF_ACCEPT; +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/net/ipv6/netfilter/nf_conntrack_reasm.c linux-2.6.29-rc3.owrt/net/ipv6/netfilter/nf_conntrack_reasm.c +--- linux-2.6.29.owrt/net/ipv6/netfilter/nf_conntrack_reasm.c 2009-05-10 22:04:39.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/net/ipv6/netfilter/nf_conntrack_reasm.c 2009-05-10 23:48:34.000000000 +0200 +@@ -528,14 +528,14 @@ + if (!ipv6_ext_hdr(nexthdr)) { + return -1; + } +- if (nexthdr == NEXTHDR_NONE) { +- pr_debug("next header is none\n"); +- return -1; +- } + if (len < (int)sizeof(struct ipv6_opt_hdr)) { + pr_debug("too short\n"); + return -1; + } ++ if (nexthdr == NEXTHDR_NONE) { ++ pr_debug("next header is none\n"); ++ return -1; ++ } + if (skb_copy_bits(skb, start, &hdr, sizeof(hdr))) + BUG(); + if (nexthdr == NEXTHDR_AUTH) +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/net/ipv6/reassembly.c linux-2.6.29-rc3.owrt/net/ipv6/reassembly.c +--- linux-2.6.29.owrt/net/ipv6/reassembly.c 2009-05-10 22:04:39.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/net/ipv6/reassembly.c 2009-05-10 23:48:34.000000000 +0200 +@@ -452,7 +452,6 @@ + static int ip6_frag_reasm(struct frag_queue *fq, struct sk_buff *prev, + struct net_device *dev) + { +- struct net *net = container_of(fq->q.net, struct net, ipv6.frags); + struct sk_buff *fp, *head = fq->q.fragments; + int payload_len; + unsigned int nhoff; +@@ -552,7 +551,8 @@ + head->csum); + + rcu_read_lock(); +- IP6_INC_STATS_BH(net, __in6_dev_get(dev), IPSTATS_MIB_REASMOKS); ++ IP6_INC_STATS_BH(dev_net(dev), ++ __in6_dev_get(dev), IPSTATS_MIB_REASMOKS); + rcu_read_unlock(); + fq->q.fragments = NULL; + return 1; +@@ -566,7 +566,8 @@ + printk(KERN_DEBUG "ip6_frag_reasm: no memory for reassembly\n"); + out_fail: + rcu_read_lock(); +- IP6_INC_STATS_BH(net, __in6_dev_get(dev), IPSTATS_MIB_REASMFAILS); ++ IP6_INC_STATS_BH(dev_net(dev), ++ __in6_dev_get(dev), IPSTATS_MIB_REASMFAILS); + rcu_read_unlock(); + return -1; + } +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/net/ipv6/route.c linux-2.6.29-rc3.owrt/net/ipv6/route.c +--- linux-2.6.29.owrt/net/ipv6/route.c 2009-05-10 22:04:39.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/net/ipv6/route.c 2009-05-10 23:48:34.000000000 +0200 +@@ -794,7 +794,7 @@ + .proto = iph->nexthdr, + }; + +- if (rt6_need_strict(&iph->daddr) && skb->dev->type != ARPHRD_PIMREG) ++ if (rt6_need_strict(&iph->daddr)) + flags |= RT6_LOOKUP_F_IFACE; + + skb->dst = fib6_rule_lookup(net, &fl, flags, ip6_pol_route_input); +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/net/ipv6/sit.c linux-2.6.29-rc3.owrt/net/ipv6/sit.c +--- linux-2.6.29.owrt/net/ipv6/sit.c 2009-05-10 22:04:39.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/net/ipv6/sit.c 2009-05-10 23:48:34.000000000 +0200 +@@ -188,9 +188,9 @@ + } + + nt = netdev_priv(dev); ++ ipip6_tunnel_init(dev); + + nt->parms = *parms; +- ipip6_tunnel_init(dev); + + if (parms->i_flags & SIT_ISATAP) + dev->priv_flags |= IFF_ISATAP; +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/net/mac80211/tx.c linux-2.6.29-rc3.owrt/net/mac80211/tx.c +--- linux-2.6.29.owrt/net/mac80211/tx.c 2009-05-10 22:04:39.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/net/mac80211/tx.c 2009-05-10 23:48:34.000000000 +0200 +@@ -752,8 +752,6 @@ + skb_copy_queue_mapping(frag, first); + + frag->do_not_encrypt = first->do_not_encrypt; +- frag->dev = first->dev; +- frag->iif = first->iif; + + pos += copylen; + left -= copylen; +@@ -1345,8 +1343,6 @@ + list) { + if (!netif_running(sdata->dev)) + continue; +- if (sdata->vif.type != NL80211_IFTYPE_AP) +- continue; + if (compare_ether_addr(sdata->dev->dev_addr, + hdr->addr2)) { + dev_hold(sdata->dev); +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/net/netfilter/nf_conntrack_core.c linux-2.6.29-rc3.owrt/net/netfilter/nf_conntrack_core.c +--- linux-2.6.29.owrt/net/netfilter/nf_conntrack_core.c 2009-05-10 22:04:39.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/net/netfilter/nf_conntrack_core.c 2009-05-10 23:48:34.000000000 +0200 +@@ -734,7 +734,7 @@ + NF_CT_ASSERT(skb->nfct); + + ret = l4proto->packet(ct, skb, dataoff, ctinfo, pf, hooknum); +- if (ret <= 0) { ++ if (ret < 0) { + /* Invalid: inverse of the return code tells + * the netfilter core what to do */ + pr_debug("nf_conntrack_in: Can't track with proto module\n"); +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/net/netfilter/nf_conntrack_netlink.c linux-2.6.29-rc3.owrt/net/netfilter/nf_conntrack_netlink.c +--- linux-2.6.29.owrt/net/netfilter/nf_conntrack_netlink.c 2009-05-10 22:04:39.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/net/netfilter/nf_conntrack_netlink.c 2009-05-10 23:48:34.000000000 +0200 +@@ -434,7 +434,7 @@ + } else + return NOTIFY_DONE; + +- if (!item->report && !nfnetlink_has_listeners(group)) ++ if (!nfnetlink_has_listeners(group)) + return NOTIFY_DONE; + + skb = alloc_skb(NLMSG_GOODSIZE, GFP_ATOMIC); +@@ -1215,16 +1215,6 @@ + } + } + +-#ifdef CONFIG_NF_NAT_NEEDED +- if (cda[CTA_NAT_SEQ_ADJ_ORIG] || cda[CTA_NAT_SEQ_ADJ_REPLY]) { +- err = ctnetlink_change_nat_seq_adj(ct, cda); +- if (err < 0) { +- rcu_read_unlock(); +- goto err; +- } +- } +-#endif +- + if (cda[CTA_PROTOINFO]) { + err = ctnetlink_change_protoinfo(ct, cda); + if (err < 0) { +@@ -1502,8 +1492,7 @@ + } else + return NOTIFY_DONE; + +- if (!item->report && +- !nfnetlink_has_listeners(NFNLGRP_CONNTRACK_EXP_NEW)) ++ if (!nfnetlink_has_listeners(NFNLGRP_CONNTRACK_EXP_NEW)) + return NOTIFY_DONE; + + skb = alloc_skb(NLMSG_GOODSIZE, GFP_ATOMIC); +@@ -1780,7 +1769,6 @@ + goto out; + } + +- exp->class = 0; + exp->expectfn = NULL; + exp->flags = 0; + exp->master = ct; +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/net/netfilter/nf_conntrack_proto_tcp.c linux-2.6.29-rc3.owrt/net/netfilter/nf_conntrack_proto_tcp.c +--- linux-2.6.29.owrt/net/netfilter/nf_conntrack_proto_tcp.c 2009-05-10 22:04:39.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/net/netfilter/nf_conntrack_proto_tcp.c 2009-05-10 23:48:34.000000000 +0200 +@@ -859,7 +859,7 @@ + */ + if (nf_ct_kill(ct)) + return -NF_REPEAT; +- return NF_DROP; ++ return -NF_DROP; + } + /* Fall through */ + case TCP_CONNTRACK_IGNORE: +@@ -892,7 +892,7 @@ + nf_log_packet(pf, 0, skb, NULL, NULL, NULL, + "nf_ct_tcp: killing out of sync session "); + nf_ct_kill(ct); +- return NF_DROP; ++ return -NF_DROP; + } + ct->proto.tcp.last_index = index; + ct->proto.tcp.last_dir = dir; +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/net/netfilter/nfnetlink_log.c linux-2.6.29-rc3.owrt/net/netfilter/nfnetlink_log.c +--- linux-2.6.29.owrt/net/netfilter/nfnetlink_log.c 2009-05-10 22:04:39.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/net/netfilter/nfnetlink_log.c 2009-05-10 23:48:34.000000000 +0200 +@@ -39,7 +39,7 @@ + #endif + + #define NFULNL_NLBUFSIZ_DEFAULT NLMSG_GOODSIZE +-#define NFULNL_TIMEOUT_DEFAULT 100 /* every second */ ++#define NFULNL_TIMEOUT_DEFAULT HZ /* every second */ + #define NFULNL_QTHRESH_DEFAULT 100 /* 100 packets */ + #define NFULNL_COPY_RANGE_MAX 0xFFFF /* max packet size is limited by 16-bit struct nfattr nfa_len field */ + +@@ -590,10 +590,8 @@ + + qthreshold = inst->qthreshold; + /* per-rule qthreshold overrides per-instance */ +- if (li->u.ulog.qthreshold) +- if (qthreshold > li->u.ulog.qthreshold) +- qthreshold = li->u.ulog.qthreshold; +- ++ if (qthreshold > li->u.ulog.qthreshold) ++ qthreshold = li->u.ulog.qthreshold; + + switch (inst->copy_mode) { + case NFULNL_COPY_META: +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/net/netfilter/x_tables.c linux-2.6.29-rc3.owrt/net/netfilter/x_tables.c +--- linux-2.6.29.owrt/net/netfilter/x_tables.c 2009-05-10 22:04:39.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/net/netfilter/x_tables.c 2009-05-10 23:48:34.000000000 +0200 +@@ -827,143 +827,59 @@ + .release = seq_release_net, + }; + +-/* +- * Traverse state for ip{,6}_{tables,matches} for helping crossing +- * the multi-AF mutexes. +- */ +-struct nf_mttg_trav { +- struct list_head *head, *curr; +- uint8_t class, nfproto; +-}; +- +-enum { +- MTTG_TRAV_INIT, +- MTTG_TRAV_NFP_UNSPEC, +- MTTG_TRAV_NFP_SPEC, +- MTTG_TRAV_DONE, +-}; +- +-static void *xt_mttg_seq_next(struct seq_file *seq, void *v, loff_t *ppos, +- bool is_target) +-{ +- static const uint8_t next_class[] = { +- [MTTG_TRAV_NFP_UNSPEC] = MTTG_TRAV_NFP_SPEC, +- [MTTG_TRAV_NFP_SPEC] = MTTG_TRAV_DONE, +- }; +- struct nf_mttg_trav *trav = seq->private; +- +- switch (trav->class) { +- case MTTG_TRAV_INIT: +- trav->class = MTTG_TRAV_NFP_UNSPEC; +- mutex_lock(&xt[NFPROTO_UNSPEC].mutex); +- trav->head = trav->curr = is_target ? +- &xt[NFPROTO_UNSPEC].target : &xt[NFPROTO_UNSPEC].match; +- break; +- case MTTG_TRAV_NFP_UNSPEC: +- trav->curr = trav->curr->next; +- if (trav->curr != trav->head) +- break; +- mutex_unlock(&xt[NFPROTO_UNSPEC].mutex); +- mutex_lock(&xt[trav->nfproto].mutex); +- trav->head = trav->curr = is_target ? +- &xt[trav->nfproto].target : &xt[trav->nfproto].match; +- trav->class = next_class[trav->class]; +- break; +- case MTTG_TRAV_NFP_SPEC: +- trav->curr = trav->curr->next; +- if (trav->curr != trav->head) +- break; +- /* fallthru, _stop will unlock */ +- default: +- return NULL; +- } +- +- if (ppos != NULL) +- ++*ppos; +- return trav; +-} +- +-static void *xt_mttg_seq_start(struct seq_file *seq, loff_t *pos, +- bool is_target) ++static void *xt_match_seq_start(struct seq_file *seq, loff_t *pos) + { +- struct nf_mttg_trav *trav = seq->private; +- unsigned int j; ++ struct proc_dir_entry *pde = (struct proc_dir_entry *)seq->private; ++ u_int16_t af = (unsigned long)pde->data; + +- trav->class = MTTG_TRAV_INIT; +- for (j = 0; j < *pos; ++j) +- if (xt_mttg_seq_next(seq, NULL, NULL, is_target) == NULL) +- return NULL; +- return trav; ++ mutex_lock(&xt[af].mutex); ++ return seq_list_start(&xt[af].match, *pos); + } + +-static void xt_mttg_seq_stop(struct seq_file *seq, void *v) ++static void *xt_match_seq_next(struct seq_file *seq, void *v, loff_t *pos) + { +- struct nf_mttg_trav *trav = seq->private; ++ struct proc_dir_entry *pde = (struct proc_dir_entry *)seq->private; ++ u_int16_t af = (unsigned long)pde->data; + +- switch (trav->class) { +- case MTTG_TRAV_NFP_UNSPEC: +- mutex_unlock(&xt[NFPROTO_UNSPEC].mutex); +- break; +- case MTTG_TRAV_NFP_SPEC: +- mutex_unlock(&xt[trav->nfproto].mutex); +- break; +- } ++ return seq_list_next(v, &xt[af].match, pos); + } + +-static void *xt_match_seq_start(struct seq_file *seq, loff_t *pos) ++static void xt_match_seq_stop(struct seq_file *seq, void *v) + { +- return xt_mttg_seq_start(seq, pos, false); +-} ++ struct proc_dir_entry *pde = seq->private; ++ u_int16_t af = (unsigned long)pde->data; + +-static void *xt_match_seq_next(struct seq_file *seq, void *v, loff_t *ppos) +-{ +- return xt_mttg_seq_next(seq, v, ppos, false); ++ mutex_unlock(&xt[af].mutex); + } + + static int xt_match_seq_show(struct seq_file *seq, void *v) + { +- const struct nf_mttg_trav *trav = seq->private; +- const struct xt_match *match; ++ struct xt_match *match = list_entry(v, struct xt_match, list); + +- switch (trav->class) { +- case MTTG_TRAV_NFP_UNSPEC: +- case MTTG_TRAV_NFP_SPEC: +- if (trav->curr == trav->head) +- return 0; +- match = list_entry(trav->curr, struct xt_match, list); +- return (*match->name == '\0') ? 0 : +- seq_printf(seq, "%s\n", match->name); +- } +- return 0; ++ if (strlen(match->name)) ++ return seq_printf(seq, "%s\n", match->name); ++ else ++ return 0; + } + + static const struct seq_operations xt_match_seq_ops = { + .start = xt_match_seq_start, + .next = xt_match_seq_next, +- .stop = xt_mttg_seq_stop, ++ .stop = xt_match_seq_stop, + .show = xt_match_seq_show, + }; + + static int xt_match_open(struct inode *inode, struct file *file) + { +- struct seq_file *seq; +- struct nf_mttg_trav *trav; + int ret; + +- trav = kmalloc(sizeof(*trav), GFP_KERNEL); +- if (trav == NULL) +- return -ENOMEM; +- + ret = seq_open(file, &xt_match_seq_ops); +- if (ret < 0) { +- kfree(trav); +- return ret; +- } ++ if (!ret) { ++ struct seq_file *seq = file->private_data; + +- seq = file->private_data; +- seq->private = trav; +- trav->nfproto = (unsigned long)PDE(inode)->data; +- return 0; ++ seq->private = PDE(inode); ++ } ++ return ret; + } + + static const struct file_operations xt_match_ops = { +@@ -971,63 +887,62 @@ + .open = xt_match_open, + .read = seq_read, + .llseek = seq_lseek, +- .release = seq_release_private, ++ .release = seq_release, + }; + + static void *xt_target_seq_start(struct seq_file *seq, loff_t *pos) + { +- return xt_mttg_seq_start(seq, pos, true); ++ struct proc_dir_entry *pde = (struct proc_dir_entry *)seq->private; ++ u_int16_t af = (unsigned long)pde->data; ++ ++ mutex_lock(&xt[af].mutex); ++ return seq_list_start(&xt[af].target, *pos); + } + +-static void *xt_target_seq_next(struct seq_file *seq, void *v, loff_t *ppos) ++static void *xt_target_seq_next(struct seq_file *seq, void *v, loff_t *pos) + { +- return xt_mttg_seq_next(seq, v, ppos, true); ++ struct proc_dir_entry *pde = (struct proc_dir_entry *)seq->private; ++ u_int16_t af = (unsigned long)pde->data; ++ ++ return seq_list_next(v, &xt[af].target, pos); ++} ++ ++static void xt_target_seq_stop(struct seq_file *seq, void *v) ++{ ++ struct proc_dir_entry *pde = seq->private; ++ u_int16_t af = (unsigned long)pde->data; ++ ++ mutex_unlock(&xt[af].mutex); + } + + static int xt_target_seq_show(struct seq_file *seq, void *v) + { +- const struct nf_mttg_trav *trav = seq->private; +- const struct xt_target *target; ++ struct xt_target *target = list_entry(v, struct xt_target, list); + +- switch (trav->class) { +- case MTTG_TRAV_NFP_UNSPEC: +- case MTTG_TRAV_NFP_SPEC: +- if (trav->curr == trav->head) +- return 0; +- target = list_entry(trav->curr, struct xt_target, list); +- return (*target->name == '\0') ? 0 : +- seq_printf(seq, "%s\n", target->name); +- } +- return 0; ++ if (strlen(target->name)) ++ return seq_printf(seq, "%s\n", target->name); ++ else ++ return 0; + } + + static const struct seq_operations xt_target_seq_ops = { + .start = xt_target_seq_start, + .next = xt_target_seq_next, +- .stop = xt_mttg_seq_stop, ++ .stop = xt_target_seq_stop, + .show = xt_target_seq_show, + }; + + static int xt_target_open(struct inode *inode, struct file *file) + { +- struct seq_file *seq; +- struct nf_mttg_trav *trav; + int ret; + +- trav = kmalloc(sizeof(*trav), GFP_KERNEL); +- if (trav == NULL) +- return -ENOMEM; +- + ret = seq_open(file, &xt_target_seq_ops); +- if (ret < 0) { +- kfree(trav); +- return ret; +- } ++ if (!ret) { ++ struct seq_file *seq = file->private_data; + +- seq = file->private_data; +- seq->private = trav; +- trav->nfproto = (unsigned long)PDE(inode)->data; +- return 0; ++ seq->private = PDE(inode); ++ } ++ return ret; + } + + static const struct file_operations xt_target_ops = { +@@ -1035,7 +950,7 @@ + .open = xt_target_open, + .read = seq_read, + .llseek = seq_lseek, +- .release = seq_release_private, ++ .release = seq_release, + }; + + #define FORMAT_TABLES "_tables_names" +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/net/netfilter/xt_recent.c linux-2.6.29-rc3.owrt/net/netfilter/xt_recent.c +--- linux-2.6.29.owrt/net/netfilter/xt_recent.c 2009-05-10 22:04:39.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/net/netfilter/xt_recent.c 2009-05-10 23:48:34.000000000 +0200 +@@ -542,7 +542,7 @@ + struct recent_entry *e; + char buf[sizeof("+b335:1d35:1e55:dead:c0de:1715:5afe:c0de")]; + const char *c = buf; +- union nf_inet_addr addr = {}; ++ union nf_inet_addr addr; + u_int16_t family; + bool add, succ; + +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/net/netfilter/xt_sctp.c linux-2.6.29-rc3.owrt/net/netfilter/xt_sctp.c +--- linux-2.6.29.owrt/net/netfilter/xt_sctp.c 2009-05-10 22:04:39.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/net/netfilter/xt_sctp.c 2009-05-10 23:48:34.000000000 +0200 +@@ -105,7 +105,7 @@ + + switch (chunk_match_type) { + case SCTP_CHUNK_MATCH_ALL: +- return SCTP_CHUNKMAP_IS_CLEAR(chunkmapcopy); ++ return SCTP_CHUNKMAP_IS_CLEAR(info->chunkmap); + case SCTP_CHUNK_MATCH_ANY: + return false; + case SCTP_CHUNK_MATCH_ONLY: +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/net/netlink/af_netlink.c linux-2.6.29-rc3.owrt/net/netlink/af_netlink.c +--- linux-2.6.29.owrt/net/netlink/af_netlink.c 2009-05-10 22:04:39.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/net/netlink/af_netlink.c 2009-05-10 23:48:34.000000000 +0200 +@@ -1084,13 +1084,6 @@ + return 0; + } + +-/** +- * netlink_set_err - report error to broadcast listeners +- * @ssk: the kernel netlink socket, as returned by netlink_kernel_create() +- * @pid: the PID of a process that we want to skip (if any) +- * @groups: the broadcast group that will notice the error +- * @code: error code, must be negative (as usual in kernelspace) +- */ + void netlink_set_err(struct sock *ssk, u32 pid, u32 group, int code) + { + struct netlink_set_err_data info; +@@ -1100,8 +1093,7 @@ + info.exclude_sk = ssk; + info.pid = pid; + info.group = group; +- /* sk->sk_err wants a positive error value */ +- info.code = -code; ++ info.code = code; + + read_lock(&nl_table_lock); + +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/net/packet/af_packet.c linux-2.6.29-rc3.owrt/net/packet/af_packet.c +--- linux-2.6.29.owrt/net/packet/af_packet.c 2009-05-10 22:04:39.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/net/packet/af_packet.c 2009-05-10 23:48:34.000000000 +0200 +@@ -77,7 +77,6 @@ + #include <linux/poll.h> + #include <linux/module.h> + #include <linux/init.h> +-#include <linux/mutex.h> + + #ifdef CONFIG_INET + #include <net/inet_common.h> +@@ -176,7 +175,6 @@ + #endif + struct packet_type prot_hook; + spinlock_t bind_lock; +- struct mutex pg_vec_lock; + unsigned int running:1, /* prot_hook is attached*/ + auxdata:1, + origdev:1; +@@ -223,13 +221,13 @@ + h.raw = po->pg_vec[pg_vec_pos] + (frame_offset * po->frame_size); + switch (po->tp_version) { + case TPACKET_V1: +- if (status != (h.h1->tp_status ? TP_STATUS_USER : +- TP_STATUS_KERNEL)) ++ if (status != h.h1->tp_status ? TP_STATUS_USER : ++ TP_STATUS_KERNEL) + return NULL; + break; + case TPACKET_V2: +- if (status != (h.h2->tp_status ? TP_STATUS_USER : +- TP_STATUS_KERNEL)) ++ if (status != h.h2->tp_status ? TP_STATUS_USER : ++ TP_STATUS_KERNEL) + return NULL; + break; + } +@@ -1074,7 +1072,6 @@ + */ + + 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); + +@@ -1889,7 +1886,6 @@ + synchronize_net(); + + err = -EBUSY; +- mutex_lock(&po->pg_vec_lock); + if (closing || atomic_read(&po->mapped) == 0) { + err = 0; + #define XC(a, b) ({ __typeof__ ((a)) __t; __t = (a); (a) = (b); __t; }) +@@ -1911,7 +1907,6 @@ + if (atomic_read(&po->mapped)) + printk(KERN_DEBUG "packet_mmap: vma is busy: %d\n", atomic_read(&po->mapped)); + } +- mutex_unlock(&po->pg_vec_lock); + + spin_lock(&po->bind_lock); + if (was_running && !po->running) { +@@ -1944,7 +1939,7 @@ + + size = vma->vm_end - vma->vm_start; + +- mutex_lock(&po->pg_vec_lock); ++ lock_sock(sk); + if (po->pg_vec == NULL) + goto out; + if (size != po->pg_vec_len*po->pg_vec_pages*PAGE_SIZE) +@@ -1967,7 +1962,7 @@ + err = 0; + + out: +- mutex_unlock(&po->pg_vec_lock); ++ release_sock(sk); + return err; + } + #endif +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/net/phonet/pep.c linux-2.6.29-rc3.owrt/net/phonet/pep.c +--- linux-2.6.29.owrt/net/phonet/pep.c 2009-05-10 22:04:39.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/net/phonet/pep.c 2009-05-10 23:48:34.000000000 +0200 +@@ -553,7 +553,7 @@ + { + struct pep_sock *pn = pep_sk(sk); + struct sock *sknode; +- struct pnpipehdr *hdr; ++ struct pnpipehdr *hdr = pnp_hdr(skb); + struct sockaddr_pn dst; + int err = NET_RX_SUCCESS; + u8 pipe_handle; +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/net/phonet/pep-gprs.c linux-2.6.29-rc3.owrt/net/phonet/pep-gprs.c +--- linux-2.6.29.owrt/net/phonet/pep-gprs.c 2009-05-10 22:04:39.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/net/phonet/pep-gprs.c 2009-05-10 23:48:34.000000000 +0200 +@@ -207,6 +207,7 @@ + dev->name, err); + dev->stats.tx_aborted_errors++; + dev->stats.tx_errors++; ++ dev_kfree_skb(skb); + } else { + dev->stats.tx_packets++; + dev->stats.tx_bytes += len; +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/net/rxrpc/af_rxrpc.c linux-2.6.29-rc3.owrt/net/rxrpc/af_rxrpc.c +--- linux-2.6.29.owrt/net/rxrpc/af_rxrpc.c 2009-05-10 22:04:39.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/net/rxrpc/af_rxrpc.c 2009-05-10 23:48:34.000000000 +0200 +@@ -284,13 +284,13 @@ + if (IS_ERR(trans)) { + call = ERR_CAST(trans); + trans = NULL; +- goto out_notrans; ++ goto out; + } + } else { + trans = rx->trans; + if (!trans) { + call = ERR_PTR(-ENOTCONN); +- goto out_notrans; ++ goto out; + } + atomic_inc(&trans->usage); + } +@@ -315,7 +315,6 @@ + rxrpc_put_bundle(trans, bundle); + out: + rxrpc_put_transport(trans); +-out_notrans: + release_sock(&rx->sk); + _leave(" = %p", call); + return call; +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/net/sched/act_police.c linux-2.6.29-rc3.owrt/net/sched/act_police.c +--- linux-2.6.29.owrt/net/sched/act_police.c 2009-05-10 22:04:39.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/net/sched/act_police.c 2009-05-10 23:48:34.000000000 +0200 +@@ -183,6 +183,13 @@ + if (R_tab == NULL) + goto failure; + ++ if (!est && (ret == ACT_P_CREATED || ++ !gen_estimator_active(&police->tcf_bstats, ++ &police->tcf_rate_est))) { ++ err = -EINVAL; ++ goto failure; ++ } ++ + if (parm->peakrate.rate) { + P_tab = qdisc_get_rtab(&parm->peakrate, + tb[TCA_POLICE_PEAKRATE]); +@@ -198,12 +205,6 @@ + &police->tcf_lock, est); + if (err) + goto failure_unlock; +- } else if (tb[TCA_POLICE_AVRATE] && +- (ret == ACT_P_CREATED || +- !gen_estimator_active(&police->tcf_bstats, +- &police->tcf_rate_est))) { +- err = -EINVAL; +- goto failure_unlock; + } + + /* No failure allowed after this point */ +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/net/sched/sch_drr.c linux-2.6.29-rc3.owrt/net/sched/sch_drr.c +--- linux-2.6.29.owrt/net/sched/sch_drr.c 2009-05-10 22:04:39.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/net/sched/sch_drr.c 2009-05-10 23:48:34.000000000 +0200 +@@ -66,15 +66,11 @@ + { + struct drr_sched *q = qdisc_priv(sch); + struct drr_class *cl = (struct drr_class *)*arg; +- struct nlattr *opt = tca[TCA_OPTIONS]; + struct nlattr *tb[TCA_DRR_MAX + 1]; + u32 quantum; + int err; + +- if (!opt) +- return -EINVAL; +- +- err = nla_parse_nested(tb, TCA_DRR_MAX, opt, drr_policy); ++ err = nla_parse_nested(tb, TCA_DRR_MAX, tca[TCA_OPTIONS], drr_policy); + if (err < 0) + return err; + +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/net/sctp/endpointola.c linux-2.6.29-rc3.owrt/net/sctp/endpointola.c +--- linux-2.6.29.owrt/net/sctp/endpointola.c 2009-05-10 22:04:39.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/net/sctp/endpointola.c 2009-05-10 23:48:34.000000000 +0200 +@@ -111,8 +111,7 @@ + if (sctp_addip_enable) { + auth_chunks->chunks[0] = SCTP_CID_ASCONF; + auth_chunks->chunks[1] = SCTP_CID_ASCONF_ACK; +- auth_chunks->param_hdr.length = +- htons(sizeof(sctp_paramhdr_t) + 2); ++ auth_chunks->param_hdr.length += htons(2); + } + } + +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/net/sctp/protocol.c linux-2.6.29-rc3.owrt/net/sctp/protocol.c +--- linux-2.6.29.owrt/net/sctp/protocol.c 2009-05-10 22:04:39.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/net/sctp/protocol.c 2009-05-10 23:48:34.000000000 +0200 +@@ -717,20 +717,15 @@ + static int sctp_ctl_sock_init(void) + { + int err; +- sa_family_t family = PF_INET; ++ sa_family_t family; + + if (sctp_get_pf_specific(PF_INET6)) + family = PF_INET6; ++ else ++ family = PF_INET; + + err = inet_ctl_sock_create(&sctp_ctl_sock, family, + SOCK_SEQPACKET, IPPROTO_SCTP, &init_net); +- +- /* If IPv6 socket could not be created, try the IPv4 socket */ +- if (err < 0 && family == PF_INET6) +- err = inet_ctl_sock_create(&sctp_ctl_sock, AF_INET, +- SOCK_SEQPACKET, IPPROTO_SCTP, +- &init_net); +- + if (err < 0) { + printk(KERN_ERR + "SCTP: Failed to create the SCTP control socket.\n"); +@@ -1327,8 +1322,9 @@ + out: + return status; + err_v6_add_protocol: +- sctp_v4_del_protocol(); ++ sctp_v6_del_protocol(); + err_add_protocol: ++ sctp_v4_del_protocol(); + inet_ctl_sock_destroy(sctp_ctl_sock); + err_ctl_sock_init: + sctp_v6_protosw_exit(); +@@ -1339,6 +1335,7 @@ + sctp_v4_pf_exit(); + sctp_v6_pf_exit(); + sctp_sysctl_unregister(); ++ list_del(&sctp_af_inet.list); + free_pages((unsigned long)sctp_port_hashtable, + get_order(sctp_port_hashsize * + sizeof(struct sctp_bind_hashbucket))); +@@ -1386,6 +1383,7 @@ + sctp_v4_pf_exit(); + + sctp_sysctl_unregister(); ++ list_del(&sctp_af_inet.list); + + free_pages((unsigned long)sctp_assoc_hashtable, + get_order(sctp_assoc_hashsize * +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/net/sctp/sm_sideeffect.c linux-2.6.29-rc3.owrt/net/sctp/sm_sideeffect.c +--- linux-2.6.29.owrt/net/sctp/sm_sideeffect.c 2009-05-10 22:04:39.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/net/sctp/sm_sideeffect.c 2009-05-10 23:48:34.000000000 +0200 +@@ -787,48 +787,36 @@ + struct sctp_association *asoc, + struct sctp_chunk *chunk) + { ++ struct sctp_operr_chunk *operr_chunk; + struct sctp_errhdr *err_hdr; +- struct sctp_ulpevent *ev; +- +- while (chunk->chunk_end > chunk->skb->data) { +- err_hdr = (struct sctp_errhdr *)(chunk->skb->data); + +- ev = sctp_ulpevent_make_remote_error(asoc, chunk, 0, +- GFP_ATOMIC); +- if (!ev) +- return; +- +- sctp_ulpq_tail_event(&asoc->ulpq, ev); ++ operr_chunk = (struct sctp_operr_chunk *)chunk->chunk_hdr; ++ err_hdr = &operr_chunk->err_hdr; + +- switch (err_hdr->cause) { +- case SCTP_ERROR_UNKNOWN_CHUNK: +- { +- sctp_chunkhdr_t *unk_chunk_hdr; +- +- unk_chunk_hdr = (sctp_chunkhdr_t *)err_hdr->variable; +- switch (unk_chunk_hdr->type) { +- /* ADDIP 4.1 A9) If the peer responds to an ASCONF with +- * an ERROR chunk reporting that it did not recognized +- * the ASCONF chunk type, the sender of the ASCONF MUST +- * NOT send any further ASCONF chunks and MUST stop its +- * T-4 timer. +- */ +- case SCTP_CID_ASCONF: +- if (asoc->peer.asconf_capable == 0) +- break; +- +- asoc->peer.asconf_capable = 0; +- sctp_add_cmd_sf(cmds, SCTP_CMD_TIMER_STOP, ++ switch (err_hdr->cause) { ++ case SCTP_ERROR_UNKNOWN_CHUNK: ++ { ++ struct sctp_chunkhdr *unk_chunk_hdr; ++ ++ unk_chunk_hdr = (struct sctp_chunkhdr *)err_hdr->variable; ++ switch (unk_chunk_hdr->type) { ++ /* ADDIP 4.1 A9) If the peer responds to an ASCONF with an ++ * ERROR chunk reporting that it did not recognized the ASCONF ++ * chunk type, the sender of the ASCONF MUST NOT send any ++ * further ASCONF chunks and MUST stop its T-4 timer. ++ */ ++ case SCTP_CID_ASCONF: ++ asoc->peer.asconf_capable = 0; ++ sctp_add_cmd_sf(cmds, SCTP_CMD_TIMER_STOP, + SCTP_TO(SCTP_EVENT_TIMEOUT_T4_RTO)); +- break; +- default: +- break; +- } + break; +- } + default: + break; + } ++ break; ++ } ++ default: ++ break; + } + } + +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/net/sctp/sm_statefuns.c linux-2.6.29-rc3.owrt/net/sctp/sm_statefuns.c +--- linux-2.6.29.owrt/net/sctp/sm_statefuns.c 2009-05-10 22:04:39.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/net/sctp/sm_statefuns.c 2009-05-10 23:48:34.000000000 +0200 +@@ -3163,6 +3163,7 @@ + sctp_cmd_seq_t *commands) + { + struct sctp_chunk *chunk = arg; ++ struct sctp_ulpevent *ev; + + if (!sctp_vtag_verify(chunk, asoc)) + return sctp_sf_pdiscard(ep, asoc, type, arg, commands); +@@ -3172,10 +3173,21 @@ + return sctp_sf_violation_chunklen(ep, asoc, type, arg, + commands); + +- sctp_add_cmd_sf(commands, SCTP_CMD_PROCESS_OPERR, +- SCTP_CHUNK(chunk)); ++ while (chunk->chunk_end > chunk->skb->data) { ++ ev = sctp_ulpevent_make_remote_error(asoc, chunk, 0, ++ GFP_ATOMIC); ++ if (!ev) ++ goto nomem; + ++ sctp_add_cmd_sf(commands, SCTP_CMD_EVENT_ULP, ++ SCTP_ULPEVENT(ev)); ++ sctp_add_cmd_sf(commands, SCTP_CMD_PROCESS_OPERR, ++ SCTP_CHUNK(chunk)); ++ } + return SCTP_DISPOSITION_CONSUME; ++ ++nomem: ++ return SCTP_DISPOSITION_NOMEM; + } + + /* +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/net/sunrpc/Kconfig linux-2.6.29-rc3.owrt/net/sunrpc/Kconfig +--- linux-2.6.29.owrt/net/sunrpc/Kconfig 2009-05-10 22:04:39.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/net/sunrpc/Kconfig 2009-05-10 23:48:34.000000000 +0200 +@@ -6,7 +6,7 @@ + + config SUNRPC_XPRT_RDMA + tristate +- depends on SUNRPC && INFINIBAND && INFINIBAND_ADDR_TRANS && EXPERIMENTAL ++ depends on SUNRPC && INFINIBAND && EXPERIMENTAL + default SUNRPC && INFINIBAND + help + This option allows the NFS client and server to support +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/net/sunrpc/sched.c linux-2.6.29-rc3.owrt/net/sunrpc/sched.c +--- linux-2.6.29.owrt/net/sunrpc/sched.c 2009-05-10 22:04:39.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/net/sunrpc/sched.c 2009-05-10 23:48:34.000000000 +0200 +@@ -293,6 +293,11 @@ + rpc_clear_queued(task); + if (rpc_test_and_set_running(task)) + return; ++ /* We might have raced */ ++ if (RPC_IS_QUEUED(task)) { ++ rpc_clear_running(task); ++ return; ++ } + if (RPC_IS_ASYNC(task)) { + int status; + +@@ -602,9 +607,7 @@ + */ + static void __rpc_execute(struct rpc_task *task) + { +- struct rpc_wait_queue *queue; +- int task_is_async = RPC_IS_ASYNC(task); +- int status = 0; ++ int status = 0; + + dprintk("RPC: %5u __rpc_execute flags=0x%x\n", + task->tk_pid, task->tk_flags); +@@ -644,25 +647,15 @@ + */ + if (!RPC_IS_QUEUED(task)) + continue; +- /* +- * The queue->lock protects against races with +- * rpc_make_runnable(). +- * +- * Note that once we clear RPC_TASK_RUNNING on an asynchronous +- * rpc_task, rpc_make_runnable() can assign it to a +- * different workqueue. We therefore cannot assume that the +- * rpc_task pointer may still be dereferenced. +- */ +- queue = task->tk_waitqueue; +- spin_lock_bh(&queue->lock); +- if (!RPC_IS_QUEUED(task)) { +- spin_unlock_bh(&queue->lock); ++ rpc_clear_running(task); ++ if (RPC_IS_ASYNC(task)) { ++ /* Careful! we may have raced... */ ++ if (RPC_IS_QUEUED(task)) ++ return; ++ if (rpc_test_and_set_running(task)) ++ return; + continue; + } +- rpc_clear_running(task); +- spin_unlock_bh(&queue->lock); +- if (task_is_async) +- return; + + /* sync task: sleep here */ + dprintk("RPC: %5u sync task going to sleep\n", task->tk_pid); +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/net/sunrpc/xprt.c linux-2.6.29-rc3.owrt/net/sunrpc/xprt.c +--- linux-2.6.29.owrt/net/sunrpc/xprt.c 2009-05-10 22:04:39.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/net/sunrpc/xprt.c 2009-05-10 23:48:34.000000000 +0200 +@@ -663,7 +663,7 @@ + xprt, (xprt_connected(xprt) ? "is" : "is not")); + + if (!xprt_bound(xprt)) { +- task->tk_status = -EAGAIN; ++ task->tk_status = -EIO; + return; + } + if (!xprt_lock_write(xprt, task)) +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/net/sunrpc/xprtsock.c linux-2.6.29-rc3.owrt/net/sunrpc/xprtsock.c +--- linux-2.6.29.owrt/net/sunrpc/xprtsock.c 2009-05-10 22:04:39.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/net/sunrpc/xprtsock.c 2009-05-10 23:48:34.000000000 +0200 +@@ -467,7 +467,7 @@ + int err, sent = 0; + + if (unlikely(!sock)) +- return -ENOTSOCK; ++ return -ENOTCONN; + + clear_bit(SOCK_ASYNC_NOSPACE, &sock->flags); + if (base != 0) { +@@ -577,8 +577,6 @@ + req->rq_svec->iov_base, + req->rq_svec->iov_len); + +- if (!xprt_bound(xprt)) +- return -ENOTCONN; + status = xs_sendpages(transport->sock, + xs_addr(xprt), + xprt->addrlen, xdr, +@@ -596,10 +594,6 @@ + } + + switch (status) { +- case -ENOTSOCK: +- status = -ENOTCONN; +- /* Should we call xs_close() here? */ +- break; + case -EAGAIN: + xs_nospace(task); + break; +@@ -699,10 +693,6 @@ + } + + switch (status) { +- case -ENOTSOCK: +- status = -ENOTCONN; +- /* Should we call xs_close() here? */ +- break; + case -EAGAIN: + xs_nospace(task); + break; +@@ -1533,7 +1523,7 @@ + struct socket *sock = transport->sock; + int err, status = -EIO; + +- if (xprt->shutdown) ++ if (xprt->shutdown || !xprt_bound(xprt)) + goto out; + + /* Start by resetting any existing state */ +@@ -1574,7 +1564,7 @@ + struct socket *sock = transport->sock; + int err, status = -EIO; + +- if (xprt->shutdown) ++ if (xprt->shutdown || !xprt_bound(xprt)) + goto out; + + /* Start by resetting any existing state */ +@@ -1658,9 +1648,6 @@ + write_unlock_bh(&sk->sk_callback_lock); + } + +- if (!xprt_bound(xprt)) +- return -ENOTCONN; +- + /* Tell the socket layer to start connecting... */ + xprt->stat.connect_count++; + xprt->stat.connect_start = jiffies; +@@ -1681,7 +1668,7 @@ + struct socket *sock = transport->sock; + int err, status = -EIO; + +- if (xprt->shutdown) ++ if (xprt->shutdown || !xprt_bound(xprt)) + goto out; + + if (!sock) { +@@ -1741,7 +1728,7 @@ + struct socket *sock = transport->sock; + int err, status = -EIO; + +- if (xprt->shutdown) ++ if (xprt->shutdown || !xprt_bound(xprt)) + goto out; + + if (!sock) { +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/net/wimax/debugfs.c linux-2.6.29-rc3.owrt/net/wimax/debugfs.c +--- linux-2.6.29.owrt/net/wimax/debugfs.c 2009-05-10 22:04:39.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/net/wimax/debugfs.c 2009-05-10 23:48:34.000000000 +0200 +@@ -28,6 +28,17 @@ + #include "debug-levels.h" + + ++/* Debug framework control of debug levels */ ++struct d_level D_LEVEL[] = { ++ D_SUBMODULE_DEFINE(debugfs), ++ D_SUBMODULE_DEFINE(id_table), ++ D_SUBMODULE_DEFINE(op_msg), ++ D_SUBMODULE_DEFINE(op_reset), ++ D_SUBMODULE_DEFINE(op_rfkill), ++ D_SUBMODULE_DEFINE(stack), ++}; ++size_t D_LEVEL_SIZE = ARRAY_SIZE(D_LEVEL); ++ + #define __debugfs_register(prefix, name, parent) \ + do { \ + result = d_level_register_debugfs(prefix, name, parent); \ +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/net/wimax/id-table.c linux-2.6.29-rc3.owrt/net/wimax/id-table.c +--- linux-2.6.29.owrt/net/wimax/id-table.c 2009-05-10 22:04:39.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/net/wimax/id-table.c 2009-05-10 23:48:34.000000000 +0200 +@@ -94,13 +94,12 @@ + list_for_each_entry(wimax_dev, &wimax_id_table, id_table_node) { + if (wimax_dev->net_dev->ifindex == ifindex) { + dev_hold(wimax_dev->net_dev); +- goto found; ++ break; + } + } +- wimax_dev = NULL; +- d_printf(1, NULL, "wimax: no devices found with ifindex %d\n", +- ifindex); +-found: ++ if (wimax_dev == NULL) ++ d_printf(1, NULL, "wimax: no devices found with ifindex %d\n", ++ ifindex); + spin_unlock(&wimax_id_table_lock); + d_fnend(3, NULL, "(info %p ifindex %d) = %p\n", + info, ifindex, wimax_dev); +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/net/wimax/stack.c linux-2.6.29-rc3.owrt/net/wimax/stack.c +--- linux-2.6.29.owrt/net/wimax/stack.c 2009-05-10 22:04:39.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/net/wimax/stack.c 2009-05-10 23:48:34.000000000 +0200 +@@ -516,19 +516,6 @@ + } + EXPORT_SYMBOL_GPL(wimax_dev_rm); + +- +-/* Debug framework control of debug levels */ +-struct d_level D_LEVEL[] = { +- D_SUBMODULE_DEFINE(debugfs), +- D_SUBMODULE_DEFINE(id_table), +- D_SUBMODULE_DEFINE(op_msg), +- D_SUBMODULE_DEFINE(op_reset), +- D_SUBMODULE_DEFINE(op_rfkill), +- D_SUBMODULE_DEFINE(stack), +-}; +-size_t D_LEVEL_SIZE = ARRAY_SIZE(D_LEVEL); +- +- + struct genl_family wimax_gnl_family = { + .id = GENL_ID_GENERATE, + .name = "WiMAX", +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/net/wireless/Kconfig linux-2.6.29-rc3.owrt/net/wireless/Kconfig +--- linux-2.6.29.owrt/net/wireless/Kconfig 2009-05-10 22:04:39.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/net/wireless/Kconfig 2009-05-10 23:48:34.000000000 +0200 +@@ -102,13 +102,3 @@ + + config LIB80211_CRYPT_TKIP + tristate +- +-config LIB80211_DEBUG +- bool "lib80211 debugging messages" +- depends on LIB80211 +- default n +- ---help--- +- You can enable this if you want verbose debugging messages +- from lib80211. +- +- If unsure, say N. +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/net/wireless/lib80211_crypt_ccmp.c linux-2.6.29-rc3.owrt/net/wireless/lib80211_crypt_ccmp.c +--- linux-2.6.29.owrt/net/wireless/lib80211_crypt_ccmp.c 2009-05-10 22:04:39.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/net/wireless/lib80211_crypt_ccmp.c 2009-05-10 23:48:34.000000000 +0200 +@@ -337,7 +337,6 @@ + pos += 8; + + if (ccmp_replay_check(pn, key->rx_pn)) { +-#ifdef CONFIG_LIB80211_DEBUG + if (net_ratelimit()) { + printk(KERN_DEBUG "CCMP: replay detected: STA=%pM " + "previous PN %02x%02x%02x%02x%02x%02x " +@@ -347,7 +346,6 @@ + key->rx_pn[3], key->rx_pn[4], key->rx_pn[5], + pn[0], pn[1], pn[2], pn[3], pn[4], pn[5]); + } +-#endif + key->dot11RSNAStatsCCMPReplays++; + return -4; + } +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/net/wireless/lib80211_crypt_tkip.c linux-2.6.29-rc3.owrt/net/wireless/lib80211_crypt_tkip.c +--- linux-2.6.29.owrt/net/wireless/lib80211_crypt_tkip.c 2009-05-10 22:04:39.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/net/wireless/lib80211_crypt_tkip.c 2009-05-10 23:48:34.000000000 +0200 +@@ -465,14 +465,12 @@ + pos += 8; + + if (tkip_replay_check(iv32, iv16, tkey->rx_iv32, tkey->rx_iv16)) { +-#ifdef CONFIG_LIB80211_DEBUG + if (net_ratelimit()) { + printk(KERN_DEBUG "TKIP: replay detected: STA=%pM" + " previous TSC %08x%04x received TSC " + "%08x%04x\n", hdr->addr2, + tkey->rx_iv32, tkey->rx_iv16, iv32, iv16); + } +-#endif + tkey->dot11RSNAStatsTKIPReplays++; + return -4; + } +@@ -507,12 +505,10 @@ + * it needs to be recalculated for the next packet. */ + tkey->rx_phase1_done = 0; + } +-#ifdef CONFIG_LIB80211_DEBUG + if (net_ratelimit()) { + printk(KERN_DEBUG "TKIP: ICV error detected: STA=" + "%pM\n", hdr->addr2); + } +-#endif + tkey->dot11RSNAStatsTKIPICVErrors++; + return -5; + } +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/net/wireless/nl80211.c linux-2.6.29-rc3.owrt/net/wireless/nl80211.c +--- linux-2.6.29.owrt/net/wireless/nl80211.c 2009-05-10 22:04:39.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/net/wireless/nl80211.c 2009-05-10 23:48:34.000000000 +0200 +@@ -1908,11 +1908,6 @@ + if (err) + return err; + +- if (!drv->ops->get_mesh_params) { +- err = -EOPNOTSUPP; +- goto out; +- } +- + /* Get the mesh params */ + rtnl_lock(); + err = drv->ops->get_mesh_params(&drv->wiphy, dev, &cur_params); +@@ -2022,11 +2017,6 @@ + if (err) + return err; + +- if (!drv->ops->set_mesh_params) { +- err = -EOPNOTSUPP; +- goto out; +- } +- + /* This makes sure that there aren't more than 32 mesh config + * parameters (otherwise our bitfield scheme would not work.) */ + BUILD_BUG_ON(NL80211_MESHCONF_ATTR_MAX > 32); +@@ -2071,7 +2061,6 @@ + err = drv->ops->set_mesh_params(&drv->wiphy, dev, &cfg, mask); + rtnl_unlock(); + +- out: + /* cleanup */ + cfg80211_put_dev(drv); + dev_put(dev); +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/net/wireless/reg.c linux-2.6.29-rc3.owrt/net/wireless/reg.c +--- linux-2.6.29.owrt/net/wireless/reg.c 2009-05-10 22:04:39.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/net/wireless/reg.c 2009-05-10 23:48:34.000000000 +0200 +@@ -380,8 +380,7 @@ + + freq_diff = freq_range->end_freq_khz - freq_range->start_freq_khz; + +- if (freq_range->end_freq_khz <= freq_range->start_freq_khz || +- freq_range->max_bandwidth_khz > freq_diff) ++ if (freq_diff <= 0 || freq_range->max_bandwidth_khz > freq_diff) + return false; + + return true; +@@ -499,7 +498,6 @@ + * calculate the number of reg rules we will need. We will need one + * for each channel subband */ + while (country_ie_len >= 3) { +- int end_channel = 0; + struct ieee80211_country_ie_triplet *triplet = + (struct ieee80211_country_ie_triplet *) country_ie; + int cur_sub_max_channel = 0, cur_channel = 0; +@@ -511,25 +509,9 @@ + continue; + } + +- /* 2 GHz */ +- if (triplet->chans.first_channel <= 14) +- end_channel = triplet->chans.first_channel + +- triplet->chans.num_channels; +- else +- /* +- * 5 GHz -- For example in country IEs if the first +- * channel given is 36 and the number of channels is 4 +- * then the individual channel numbers defined for the +- * 5 GHz PHY by these parameters are: 36, 40, 44, and 48 +- * and not 36, 37, 38, 39. +- * +- * See: http://tinyurl.com/11d-clarification +- */ +- end_channel = triplet->chans.first_channel + +- (4 * (triplet->chans.num_channels - 1)); +- + cur_channel = triplet->chans.first_channel; +- cur_sub_max_channel = end_channel; ++ cur_sub_max_channel = ieee80211_channel_to_frequency( ++ cur_channel + triplet->chans.num_channels); + + /* Basic sanity check */ + if (cur_sub_max_channel < cur_channel) +@@ -608,6 +590,15 @@ + end_channel = triplet->chans.first_channel + + triplet->chans.num_channels; + else ++ /* ++ * 5 GHz -- For example in country IEs if the first ++ * channel given is 36 and the number of channels is 4 ++ * then the individual channel numbers defined for the ++ * 5 GHz PHY by these parameters are: 36, 40, 44, and 48 ++ * and not 36, 37, 38, 39. ++ * ++ * See: http://tinyurl.com/11d-clarification ++ */ + end_channel = triplet->chans.first_channel + + (4 * (triplet->chans.num_channels - 1)); + +@@ -1285,7 +1276,7 @@ + if (intersected_rd) { + printk(KERN_DEBUG "cfg80211: We intersect both of these " + "and get:\n"); +- print_regdomain_info(intersected_rd); ++ print_regdomain_info(rd); + return; + } + printk(KERN_DEBUG "cfg80211: Intersection between both failed\n"); +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/net/xfrm/xfrm_state.c linux-2.6.29-rc3.owrt/net/xfrm/xfrm_state.c +--- linux-2.6.29.owrt/net/xfrm/xfrm_state.c 2009-05-10 22:04:39.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/net/xfrm/xfrm_state.c 2009-05-10 23:48:34.000000000 +0200 +@@ -748,51 +748,12 @@ + schedule_work(&net->xfrm.state_hash_work); + } + +-static void xfrm_state_look_at(struct xfrm_policy *pol, struct xfrm_state *x, +- struct flowi *fl, unsigned short family, +- xfrm_address_t *daddr, xfrm_address_t *saddr, +- struct xfrm_state **best, int *acq_in_progress, +- int *error) +-{ +- /* Resolution logic: +- * 1. There is a valid state with matching selector. Done. +- * 2. Valid state with inappropriate selector. Skip. +- * +- * Entering area of "sysdeps". +- * +- * 3. If state is not valid, selector is temporary, it selects +- * only session which triggered previous resolution. Key +- * manager will do something to install a state with proper +- * selector. +- */ +- if (x->km.state == XFRM_STATE_VALID) { +- if ((x->sel.family && +- !xfrm_selector_match(&x->sel, fl, x->sel.family)) || +- !security_xfrm_state_pol_flow_match(x, pol, fl)) +- return; +- +- if (!*best || +- (*best)->km.dying > x->km.dying || +- ((*best)->km.dying == x->km.dying && +- (*best)->curlft.add_time < x->curlft.add_time)) +- *best = x; +- } else if (x->km.state == XFRM_STATE_ACQ) { +- *acq_in_progress = 1; +- } else if (x->km.state == XFRM_STATE_ERROR || +- x->km.state == XFRM_STATE_EXPIRED) { +- if (xfrm_selector_match(&x->sel, fl, x->sel.family) && +- security_xfrm_state_pol_flow_match(x, pol, fl)) +- *error = -ESRCH; +- } +-} +- + struct xfrm_state * + xfrm_state_find(xfrm_address_t *daddr, xfrm_address_t *saddr, + struct flowi *fl, struct xfrm_tmpl *tmpl, + struct xfrm_policy *pol, int *err, + unsigned short family) + { +- static xfrm_address_t saddr_wildcard = { }; + struct net *net = xp_net(pol); + unsigned int h; + struct hlist_node *entry; +@@ -812,27 +773,40 @@ + xfrm_state_addr_check(x, daddr, saddr, family) && + tmpl->mode == x->props.mode && + tmpl->id.proto == x->id.proto && +- (tmpl->id.spi == x->id.spi || !tmpl->id.spi)) +- xfrm_state_look_at(pol, x, fl, family, daddr, saddr, +- &best, &acquire_in_progress, &error); +- } +- if (best) +- goto found; +- +- h = xfrm_dst_hash(net, daddr, &saddr_wildcard, tmpl->reqid, family); +- hlist_for_each_entry(x, entry, net->xfrm.state_bydst+h, bydst) { +- if (x->props.family == family && +- x->props.reqid == tmpl->reqid && +- !(x->props.flags & XFRM_STATE_WILDRECV) && +- xfrm_state_addr_check(x, daddr, saddr, family) && +- tmpl->mode == x->props.mode && +- tmpl->id.proto == x->id.proto && +- (tmpl->id.spi == x->id.spi || !tmpl->id.spi)) +- xfrm_state_look_at(pol, x, fl, family, daddr, saddr, +- &best, &acquire_in_progress, &error); ++ (tmpl->id.spi == x->id.spi || !tmpl->id.spi)) { ++ /* Resolution logic: ++ 1. There is a valid state with matching selector. ++ Done. ++ 2. Valid state with inappropriate selector. Skip. ++ ++ Entering area of "sysdeps". ++ ++ 3. If state is not valid, selector is temporary, ++ it selects only session which triggered ++ previous resolution. Key manager will do ++ something to install a state with proper ++ selector. ++ */ ++ if (x->km.state == XFRM_STATE_VALID) { ++ if ((x->sel.family && !xfrm_selector_match(&x->sel, fl, x->sel.family)) || ++ !security_xfrm_state_pol_flow_match(x, pol, fl)) ++ continue; ++ if (!best || ++ best->km.dying > x->km.dying || ++ (best->km.dying == x->km.dying && ++ best->curlft.add_time < x->curlft.add_time)) ++ best = x; ++ } else if (x->km.state == XFRM_STATE_ACQ) { ++ acquire_in_progress = 1; ++ } else if (x->km.state == XFRM_STATE_ERROR || ++ x->km.state == XFRM_STATE_EXPIRED) { ++ if (xfrm_selector_match(&x->sel, fl, x->sel.family) && ++ security_xfrm_state_pol_flow_match(x, pol, fl)) ++ error = -ESRCH; ++ } ++ } + } + +-found: + x = best; + if (!x && !error && !acquire_in_progress) { + if (tmpl->id.spi && +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/README linux-2.6.29-rc3.owrt/README +--- linux-2.6.29.owrt/README 2009-05-10 22:04:37.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/README 2009-05-10 23:48:34.000000000 +0200 +@@ -188,7 +188,7 @@ + values to random values. + + You can find more information on using the Linux kernel config tools +- in Documentation/kbuild/kconfig.txt. ++ in Documentation/kbuild/make-configs.txt. + + NOTES on "make config": + - having unnecessary drivers will make the kernel bigger, and can +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/scripts/bootgraph.pl linux-2.6.29-rc3.owrt/scripts/bootgraph.pl +--- linux-2.6.29.owrt/scripts/bootgraph.pl 2009-05-10 22:04:38.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/scripts/bootgraph.pl 2009-05-10 23:48:34.000000000 +0200 +@@ -51,7 +51,7 @@ + + while (<>) { + my $line = $_; +- if ($line =~ /([0-9\.]+)\] calling ([a-zA-Z0-9\_\.]+)\+/) { ++ if ($line =~ /([0-9\.]+)\] calling ([a-zA-Z0-9\_]+)\+/) { + my $func = $2; + if ($done == 0) { + $start{$func} = $1; +@@ -87,7 +87,7 @@ + $count = $count + 1; + } + +- if ($line =~ /([0-9\.]+)\] initcall ([a-zA-Z0-9\_\.]+)\+.*returned/) { ++ if ($line =~ /([0-9\.]+)\] initcall ([a-zA-Z0-9\_]+)\+.*returned/) { + if ($done == 0) { + $end{$2} = $1; + $maxtime = $1; +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/scripts/checkpatch.pl linux-2.6.29-rc3.owrt/scripts/checkpatch.pl +--- linux-2.6.29.owrt/scripts/checkpatch.pl 2009-05-10 22:04:38.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/scripts/checkpatch.pl 2009-05-10 23:48:34.000000000 +0200 +@@ -10,7 +10,7 @@ + my $P = $0; + $P =~ s@.*/@@g; + +-my $V = '0.28'; ++my $V = '0.27'; + + use Getopt::Long qw(:config no_auto_abbrev); + +@@ -110,8 +110,7 @@ + __iomem| + __must_check| + __init_refok| +- __kprobes| +- __ref ++ __kprobes + }x; + our $Attribute = qr{ + const| +@@ -1241,8 +1240,7 @@ + $realfile =~ s@^([^/]*)/@@; + + $p1_prefix = $1; +- if (!$file && $tree && $p1_prefix ne '' && +- -e "$root/$p1_prefix") { ++ if ($tree && $p1_prefix ne '' && -e "$root/$p1_prefix") { + WARN("patch prefix '$p1_prefix' exists, appears to be a -p0 patch\n"); + } + +@@ -1585,9 +1583,9 @@ + } + # TEST: allow direct testing of the attribute matcher. + if ($dbg_attr) { +- if ($line =~ /^.\s*$Modifier\s*$/) { ++ if ($line =~ /^.\s*$Attribute\s*$/) { + ERROR("TEST: is attr\n" . $herecurr); +- } elsif ($dbg_attr > 1 && $line =~ /^.+($Modifier)/) { ++ } elsif ($dbg_attr > 1 && $line =~ /^.+($Attribute)/) { + ERROR("TEST: is not attr ($1 is)\n". $herecurr); + } + next; +@@ -1659,7 +1657,7 @@ + + # * goes on variable not on type + # (char*[ const]) +- if ($line =~ m{\($NonptrType(\s*(?:$Modifier\b\s*|\*\s*)+)\)}) { ++ if ($line =~ m{\($NonptrType(\s*\*[\s\*]*(?:$Modifier\s*)*)\)}) { + my ($from, $to) = ($1, $1); + + # Should start with a space. +@@ -1674,7 +1672,7 @@ + if ($from ne $to) { + ERROR("\"(foo$from)\" should be \"(foo$to)\"\n" . $herecurr); + } +- } elsif ($line =~ m{\b$NonptrType(\s*(?:$Modifier\b\s*|\*\s*)+)($Ident)}) { ++ } elsif ($line =~ m{\b$NonptrType(\s*\*[\s\*]*(?:$Modifier\s*)?)($Ident)}) { + my ($from, $to, $ident) = ($1, $1, $2); + + # Should start with a space. +@@ -1687,8 +1685,8 @@ + # Modifiers should have spaces. + $to =~ s/(\b$Modifier$)/$1 /; + +- #print "from<$from> to<$to> ident<$ident>\n"; +- if ($from ne $to && $ident !~ /^$Modifier$/) { ++ #print "from<$from> to<$to>\n"; ++ if ($from ne $to) { + ERROR("\"foo${from}bar\" should be \"foo${to}bar\"\n" . $herecurr); + } + } +@@ -1887,11 +1885,11 @@ + if ($ctx !~ /[WEBC]x./ && $ca !~ /(?:\)|!|~|\*|-|\&|\||\+\+|\-\-|\{)$/) { + ERROR("space required before that '$op' $at\n" . $hereptr); + } +- if ($op eq '*' && $cc =~/\s*$Modifier\b/) { ++ if ($op eq '*' && $cc =~/\s*const\b/) { + # A unary '*' may be const + + } elsif ($ctx =~ /.xW/) { +- ERROR("Aspace prohibited after that '$op' $at\n" . $hereptr); ++ ERROR("space prohibited after that '$op' $at\n" . $hereptr); + } + + # unary ++ and unary -- are allowed no space on one side. +@@ -2562,7 +2560,7 @@ + if ($line =~ /\bin_atomic\s*\(/) { + if ($realfile =~ m@^drivers/@) { + ERROR("do not use in_atomic in drivers\n" . $herecurr); +- } elsif ($realfile !~ m@^kernel/@) { ++ } else { + WARN("use of in_atomic() is incorrect outside core kernel code\n" . $herecurr); + } + } +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/scripts/kconfig/conf.c linux-2.6.29-rc3.owrt/scripts/kconfig/conf.c +--- linux-2.6.29.owrt/scripts/kconfig/conf.c 2009-05-10 22:04:38.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/scripts/kconfig/conf.c 2009-05-10 23:48:34.000000000 +0200 +@@ -11,7 +11,6 @@ + #include <time.h> + #include <unistd.h> + #include <sys/stat.h> +-#include <sys/time.h> + + #define LKC_DIRECT_LINK + #include "lkc.h" +@@ -465,22 +464,9 @@ + input_mode = set_yes; + break; + case 'r': +- { +- struct timeval now; +- unsigned int seed; +- +- /* +- * Use microseconds derived seed, +- * compensate for systems where it may be zero +- */ +- gettimeofday(&now, NULL); +- +- seed = (unsigned int)((now.tv_sec + 1) * (now.tv_usec + 1)); +- srand(seed); +- + input_mode = set_random; ++ srand(time(NULL)); + break; +- } + case 'h': + printf(_("See README for usage info\n")); + exit(0); +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/scripts/kconfig/confdata.c linux-2.6.29-rc3.owrt/scripts/kconfig/confdata.c +--- linux-2.6.29.owrt/scripts/kconfig/confdata.c 2009-05-10 22:04:38.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/scripts/kconfig/confdata.c 2009-05-10 23:48:34.000000000 +0200 +@@ -843,7 +843,7 @@ + default: + continue; + } +- if (!(sym_is_choice(sym) && mode == def_random)) ++ if (!sym_is_choice(sym) || mode != def_random) + sym->flags |= SYMBOL_DEF_USER; + break; + default: +@@ -856,49 +856,28 @@ + + if (mode != def_random) + return; +- /* +- * We have different type of choice blocks. +- * If curr.tri equal to mod then we can select several +- * choice symbols in one block. +- * In this case we do nothing. +- * If curr.tri equal yes then only one symbol can be +- * selected in a choice block and we set it to yes, +- * and the rest to no. +- */ ++ + for_all_symbols(i, csym) { + if (sym_has_value(csym) || !sym_is_choice(csym)) + continue; + + sym_calc_value(csym); +- +- if (csym->curr.tri != yes) +- continue; +- + prop = sym_get_choice_prop(csym); +- +- /* count entries in choice block */ +- cnt = 0; +- expr_list_for_each_sym(prop->expr, e, sym) +- cnt++; +- +- /* +- * find a random value and set it to yes, +- * set the rest to no so we have only one set +- */ +- def = (rand() % cnt); +- +- cnt = 0; +- expr_list_for_each_sym(prop->expr, e, sym) { +- if (def == cnt++) { +- sym->def[S_DEF_USER].tri = yes; +- csym->def[S_DEF_USER].val = sym; +- } +- else { +- sym->def[S_DEF_USER].tri = no; ++ def = -1; ++ while (1) { ++ cnt = 0; ++ expr_list_for_each_sym(prop->expr, e, sym) { ++ if (sym->visible == no) ++ continue; ++ if (def == cnt++) { ++ csym->def[S_DEF_USER].val = sym; ++ break; ++ } + } ++ if (def >= 0 || cnt < 2) ++ break; ++ def = (rand() % cnt) + 1; + } + csym->flags |= SYMBOL_DEF_USER; +- /* clear VALID to get value calculated */ +- csym->flags &= ~(SYMBOL_VALID); + } + } +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/scripts/kernel-doc linux-2.6.29-rc3.owrt/scripts/kernel-doc +--- linux-2.6.29.owrt/scripts/kernel-doc 2009-05-10 22:04:38.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/scripts/kernel-doc 2009-05-10 23:48:34.000000000 +0200 +@@ -1827,40 +1827,6 @@ + $state = 0; + } + +-sub syscall_munge() { +- my $void = 0; +- +- $prototype =~ s@[\r\n\t]+@ @gos; # strip newlines/CR's/tabs +-## if ($prototype =~ m/SYSCALL_DEFINE0\s*\(\s*(a-zA-Z0-9_)*\s*\)/) { +- if ($prototype =~ m/SYSCALL_DEFINE0/) { +- $void = 1; +-## $prototype = "long sys_$1(void)"; +- } +- +- $prototype =~ s/SYSCALL_DEFINE.*\(/long sys_/; # fix return type & func name +- if ($prototype =~ m/long (sys_.*?),/) { +- $prototype =~ s/,/\(/; +- } elsif ($void) { +- $prototype =~ s/\)/\(void\)/; +- } +- +- # now delete all of the odd-number commas in $prototype +- # so that arg types & arg names don't have a comma between them +- my $count = 0; +- my $len = length($prototype); +- if ($void) { +- $len = 0; # skip the for-loop +- } +- for (my $ix = 0; $ix < $len; $ix++) { +- if (substr($prototype, $ix, 1) eq ',') { +- $count++; +- if ($count % 2 == 1) { +- substr($prototype, $ix, 1) = ' '; +- } +- } +- } +-} +- + sub process_state3_function($$) { + my $x = shift; + my $file = shift; +@@ -1873,15 +1839,11 @@ + elsif ($x =~ /([^\{]*)/) { + $prototype .= $1; + } +- + if (($x =~ /\{/) || ($x =~ /\#\s*define/) || ($x =~ /;/)) { + $prototype =~ s@/\*.*?\*/@@gos; # strip comments. + $prototype =~ s@[\r\n]+@ @gos; # strip newlines/cr's. + $prototype =~ s@^\s+@@gos; # strip leading spaces +- if ($prototype =~ /SYSCALL_DEFINE/) { +- syscall_munge(); +- } +- dump_function($prototype, $file); ++ dump_function($prototype,$file); + reset_state(); + } + } +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/scripts/markup_oops.pl linux-2.6.29-rc3.owrt/scripts/markup_oops.pl +--- linux-2.6.29.owrt/scripts/markup_oops.pl 2009-05-10 22:04:38.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/scripts/markup_oops.pl 2009-05-10 23:48:34.000000000 +0200 +@@ -1,4 +1,4 @@ +-#!/usr/bin/perl ++#!/usr/bin/perl -w + + use File::Basename; + +@@ -29,151 +29,27 @@ + my $target = "0"; + my $function; + my $module = ""; +-my $func_offset = 0; ++my $func_offset; + my $vmaoffset = 0; + +-my %regs; +- +- +-sub parse_x86_regs +-{ +- my ($line) = @_; +- if ($line =~ /EAX: ([0-9a-f]+) EBX: ([0-9a-f]+) ECX: ([0-9a-f]+) EDX: ([0-9a-f]+)/) { +- $regs{"%eax"} = $1; +- $regs{"%ebx"} = $2; +- $regs{"%ecx"} = $3; +- $regs{"%edx"} = $4; +- } +- if ($line =~ /ESI: ([0-9a-f]+) EDI: ([0-9a-f]+) EBP: ([0-9a-f]+) ESP: ([0-9a-f]+)/) { +- $regs{"%esi"} = $1; +- $regs{"%edi"} = $2; +- $regs{"%esp"} = $4; +- } +- if ($line =~ /RAX: ([0-9a-f]+) RBX: ([0-9a-f]+) RCX: ([0-9a-f]+)/) { +- $regs{"%eax"} = $1; +- $regs{"%ebx"} = $2; +- $regs{"%ecx"} = $3; +- } +- if ($line =~ /RDX: ([0-9a-f]+) RSI: ([0-9a-f]+) RDI: ([0-9a-f]+)/) { +- $regs{"%edx"} = $1; +- $regs{"%esi"} = $2; +- $regs{"%edi"} = $3; +- } +- if ($line =~ /RBP: ([0-9a-f]+) R08: ([0-9a-f]+) R09: ([0-9a-f]+)/) { +- $regs{"%r08"} = $2; +- $regs{"%r09"} = $3; +- } +- if ($line =~ /R10: ([0-9a-f]+) R11: ([0-9a-f]+) R12: ([0-9a-f]+)/) { +- $regs{"%r10"} = $1; +- $regs{"%r11"} = $2; +- $regs{"%r12"} = $3; +- } +- if ($line =~ /R13: ([0-9a-f]+) R14: ([0-9a-f]+) R15: ([0-9a-f]+)/) { +- $regs{"%r13"} = $1; +- $regs{"%r14"} = $2; +- $regs{"%r15"} = $3; +- } +-} +- +-sub reg_name +-{ +- my ($reg) = @_; +- $reg =~ s/r(.)x/e\1x/; +- $reg =~ s/r(.)i/e\1i/; +- $reg =~ s/r(.)p/e\1p/; +- return $reg; +-} +- +-sub process_x86_regs +-{ +- my ($line, $cntr) = @_; +- my $str = ""; +- if (length($line) < 40) { +- return ""; # not an asm istruction +- } +- +- # find the arguments to the instruction +- if ($line =~ /([0-9a-zA-Z\,\%\(\)\-\+]+)$/) { +- $lastword = $1; +- } else { +- return ""; +- } +- +- # we need to find the registers that get clobbered, +- # since their value is no longer relevant for previous +- # instructions in the stream. +- +- $clobber = $lastword; +- # first, remove all memory operands, they're read only +- $clobber =~ s/\([a-z0-9\%\,]+\)//g; +- # then, remove everything before the comma, thats the read part +- $clobber =~ s/.*\,//g; +- +- # if this is the instruction that faulted, we haven't actually done +- # the write yet... nothing is clobbered. +- if ($cntr == 0) { +- $clobber = ""; +- } +- +- foreach $reg (keys(%regs)) { +- my $clobberprime = reg_name($clobber); +- my $lastwordprime = reg_name($lastword); +- my $val = $regs{$reg}; +- if ($val =~ /^[0]+$/) { +- $val = "0"; +- } else { +- $val =~ s/^0*//; +- } +- +- # first check if we're clobbering this register; if we do +- # we print it with a =>, and then delete its value +- if ($clobber =~ /$reg/ || $clobberprime =~ /$reg/) { +- if (length($val) > 0) { +- $str = $str . " $reg => $val "; +- } +- $regs{$reg} = ""; +- $val = ""; +- } +- # now check if we're reading this register +- if ($lastword =~ /$reg/ || $lastwordprime =~ /$reg/) { +- if (length($val) > 0) { +- $str = $str . " $reg = $val "; +- } +- } +- } +- return $str; +-} +- +-# parse the oops + while (<STDIN>) { + my $line = $_; + if ($line =~ /EIP: 0060:\[\<([a-z0-9]+)\>\]/) { + $target = $1; + } +- if ($line =~ /RIP: 0010:\[\<([a-z0-9]+)\>\]/) { +- $target = $1; +- } + if ($line =~ /EIP is at ([a-zA-Z0-9\_]+)\+(0x[0-9a-f]+)\/0x[a-f0-9]/) { + $function = $1; + $func_offset = $2; + } +- if ($line =~ /RIP: 0010:\[\<[0-9a-f]+\>\] \[\<[0-9a-f]+\>\] ([a-zA-Z0-9\_]+)\+(0x[0-9a-f]+)\/0x[a-f0-9]/) { +- $function = $1; +- $func_offset = $2; +- } + + # check if it's a module + if ($line =~ /EIP is at ([a-zA-Z0-9\_]+)\+(0x[0-9a-f]+)\/0x[a-f0-9]+\W\[([a-zA-Z0-9\_\-]+)\]/) { + $module = $3; + } +- if ($line =~ /RIP: 0010:\[\<[0-9a-f]+\>\] \[\<[0-9a-f]+\>\] ([a-zA-Z0-9\_]+)\+(0x[0-9a-f]+)\/0x[a-f0-9]+\W\[([a-zA-Z0-9\_\-]+)\]/) { +- $module = $3; +- } +- parse_x86_regs($line); + } + + my $decodestart = hex($target) - hex($func_offset); +-my $decodestop = hex($target) + 8192; ++my $decodestop = $decodestart + 8192; + if ($target eq "0") { + print "No oops found!\n"; + print "Usage: \n"; +@@ -208,7 +84,6 @@ + my $state = 0; + my $center = 0; + my @lines; +-my @reglines; + + sub InRange { + my ($address, $target) = @_; +@@ -313,36 +188,16 @@ + + my $i; + +- +-# start annotating the registers in the asm. +-# this goes from the oopsing point back, so that the annotator +-# can track (opportunistically) which registers got written and +-# whos value no longer is relevant. +- +-$i = $center; +-while ($i >= $start) { +- $reglines[$i] = process_x86_regs($lines[$i], $center - $i); +- $i = $i - 1; +-} +- ++my $fulltext = ""; + $i = $start; + while ($i < $finish) { +- my $line; + if ($i == $center) { +- $line = "*$lines[$i] "; ++ $fulltext = $fulltext . "*$lines[$i] <----- faulting instruction\n"; + } else { +- $line = " $lines[$i] "; +- } +- print $line; +- if (defined($reglines[$i]) && length($reglines[$i]) > 0) { +- my $c = 60 - length($line); +- while ($c > 0) { print " "; $c = $c - 1; }; +- print "| $reglines[$i]"; ++ $fulltext = $fulltext . " $lines[$i]\n"; + } +- if ($i == $center) { +- print "<--- faulting instruction"; +- } +- print "\n"; + $i = $i +1; + } + ++print $fulltext; ++ +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/scripts/mod/file2alias.c linux-2.6.29-rc3.owrt/scripts/mod/file2alias.c +--- linux-2.6.29.owrt/scripts/mod/file2alias.c 2009-05-10 22:04:38.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/scripts/mod/file2alias.c 2009-05-10 23:48:34.000000000 +0200 +@@ -210,7 +210,6 @@ + static int do_hid_entry(const char *filename, + struct hid_device_id *id, char *alias) + { +- id->bus = TO_NATIVE(id->bus); + id->vendor = TO_NATIVE(id->vendor); + id->product = TO_NATIVE(id->product); + +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/scripts/package/Makefile linux-2.6.29-rc3.owrt/scripts/package/Makefile +--- linux-2.6.29.owrt/scripts/package/Makefile 2009-05-10 22:04:38.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/scripts/package/Makefile 2009-05-10 23:48:34.000000000 +0200 +@@ -35,10 +35,9 @@ + rpm-pkg rpm: $(objtree)/kernel.spec FORCE + $(MAKE) clean + $(PREV) ln -sf $(srctree) $(KERNELPATH) +- $(CONFIG_SHELL) $(srctree)/scripts/setlocalversion > $(objtree)/.scmversion + $(PREV) tar -cz $(RCS_TAR_IGNORE) -f $(KERNELPATH).tar.gz $(KERNELPATH)/. + $(PREV) rm $(KERNELPATH) +- rm -f $(objtree)/.scmversion ++ + set -e; \ + $(CONFIG_SHELL) $(srctree)/scripts/mkversion > $(objtree)/.tmp_version + set -e; \ +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/scripts/package/mkspec linux-2.6.29-rc3.owrt/scripts/package/mkspec +--- linux-2.6.29.owrt/scripts/package/mkspec 2009-05-10 22:04:38.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/scripts/package/mkspec 2009-05-10 23:48:34.000000000 +0200 +@@ -86,17 +86,9 @@ + echo 'cp System.map $RPM_BUILD_ROOT'"/boot/System.map-$KERNELRELEASE" + + echo 'cp .config $RPM_BUILD_ROOT'"/boot/config-$KERNELRELEASE" +- +-echo "%ifnarch ppc64" +-echo 'cp vmlinux vmlinux.orig' +-echo 'bzip2 -9 vmlinux' +-echo 'mv vmlinux.bz2 $RPM_BUILD_ROOT'"/boot/vmlinux-$KERNELRELEASE.bz2" +-echo 'mv vmlinux.orig vmlinux' +-echo "%endif" +- + echo "" + echo "%clean" +-echo 'rm -rf $RPM_BUILD_ROOT' ++echo '#echo -rf $RPM_BUILD_ROOT' + echo "" + echo "%files" + echo '%defattr (-, root, root)' +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/scripts/setlocalversion linux-2.6.29-rc3.owrt/scripts/setlocalversion +--- linux-2.6.29.owrt/scripts/setlocalversion 2009-05-10 22:04:38.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/scripts/setlocalversion 2009-05-10 23:48:34.000000000 +0200 +@@ -58,7 +58,14 @@ + # Check for svn and a svn repo. + if rev=`svn info 2>/dev/null | grep '^Last Changed Rev'`; then + rev=`echo $rev | awk '{print $NF}'` +- printf -- '-svn%s' "$rev" ++ changes=`svn status 2>/dev/null | grep '^[AMD]' | wc -l` ++ ++ # Are there uncommitted changes? ++ if [ $changes != 0 ]; then ++ printf -- '-svn%s%s' "$rev" -dirty ++ else ++ printf -- '-svn%s' "$rev" ++ fi + + # All done with svn + exit +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/scripts/tags.sh linux-2.6.29-rc3.owrt/scripts/tags.sh +--- linux-2.6.29.owrt/scripts/tags.sh 2009-05-10 22:04:38.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/scripts/tags.sh 2009-05-10 23:48:34.000000000 +0200 +@@ -76,10 +76,7 @@ + + all_kconfigs() + { +- for arch in $ALLSOURCE_ARCHS; do +- find_sources $arch 'Kconfig*' +- done +- find_other_sources 'Kconfig*' ++ find_sources $ALLSOURCE_ARCHS 'Kconfig*' + } + + all_defconfigs() +@@ -102,8 +99,7 @@ + -I ____cacheline_internodealigned_in_smp \ + -I EXPORT_SYMBOL,EXPORT_SYMBOL_GPL \ + --extra=+f --c-kinds=+px \ +- --regex-asm='/^ENTRY\(([^)]*)\).*/\1/' \ +- --regex-c='/^SYSCALL_DEFINE[[:digit:]]?\(([^,)]*).*/sys_\1/' ++ --regex-asm='/^ENTRY\(([^)]*)\).*/\1/' + + all_kconfigs | xargs $1 -a \ + --langdef=kconfig --language-force=kconfig \ +@@ -121,9 +117,7 @@ + + emacs() + { +- all_sources | xargs $1 -a \ +- --regex='/^ENTRY(\([^)]*\)).*/\1/' \ +- --regex='/^SYSCALL_DEFINE[0-9]?(\([^,)]*\).*/sys_\1/' ++ all_sources | xargs $1 -a + + all_kconfigs | xargs $1 -a \ + --regex='/^[ \t]*\(\(menu\)*config\)[ \t]+\([a-zA-Z0-9_]+\)/\3/' +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/scripts/unifdef.c linux-2.6.29-rc3.owrt/scripts/unifdef.c +--- linux-2.6.29.owrt/scripts/unifdef.c 2009-05-10 22:04:38.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/scripts/unifdef.c 2009-05-10 23:48:34.000000000 +0200 +@@ -206,7 +206,7 @@ + static void error(const char *); + static int findsym(const char *); + static void flushline(bool); +-static Linetype get_line(void); ++static Linetype getline(void); + static Linetype ifeval(const char **); + static void ignoreoff(void); + static void ignoreon(void); +@@ -512,7 +512,7 @@ + + for (;;) { + linenum++; +- lineval = get_line(); ++ lineval = getline(); + trans_table[ifstate[depth]][lineval](); + debug("process %s -> %s depth %d", + linetype_name[lineval], +@@ -526,7 +526,7 @@ + * help from skipcomment(). + */ + static Linetype +-get_line(void) ++getline(void) + { + const char *cp; + int cursym; +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/security/selinux/netlabel.c linux-2.6.29-rc3.owrt/security/selinux/netlabel.c +--- linux-2.6.29.owrt/security/selinux/netlabel.c 2009-05-10 22:04:39.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/security/selinux/netlabel.c 2009-05-10 23:48:34.000000000 +0200 +@@ -386,12 +386,11 @@ + if (!S_ISSOCK(inode->i_mode) || + ((mask & (MAY_WRITE | MAY_APPEND)) == 0)) + return 0; ++ + sock = SOCKET_I(inode); + sk = sock->sk; +- if (sk == NULL) +- return 0; + sksec = sk->sk_security; +- if (sksec == NULL || sksec->nlbl_state != NLBL_REQUIRE) ++ if (sksec->nlbl_state != NLBL_REQUIRE) + return 0; + + local_bh_disable(); +@@ -491,10 +490,8 @@ + lock_sock(sk); + rc = netlbl_sock_getattr(sk, &secattr); + release_sock(sk); +- if (rc == 0) ++ if (rc == 0 && secattr.flags != NETLBL_SECATTR_NONE) + rc = -EACCES; +- else if (rc == -ENOMSG) +- rc = 0; + netlbl_secattr_destroy(&secattr); + } + +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/security/smack/smackfs.c linux-2.6.29-rc3.owrt/security/smack/smackfs.c +--- linux-2.6.29.owrt/security/smack/smackfs.c 2009-05-10 22:04:39.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/security/smack/smackfs.c 2009-05-10 23:48:34.000000000 +0200 +@@ -650,6 +650,10 @@ + + return skp; + } ++/* ++#define BEMASK 0x80000000 ++*/ ++#define BEMASK 0x00000001 + #define BEBITS (sizeof(__be32) * 8) + + /* +@@ -659,10 +663,12 @@ + { + struct smk_netlbladdr *skp = (struct smk_netlbladdr *) v; + unsigned char *hp = (char *) &skp->smk_host.sin_addr.s_addr; +- int maskn; +- u32 temp_mask = be32_to_cpu(skp->smk_mask.s_addr); ++ __be32 bebits; ++ int maskn = 0; + +- for (maskn = 0; temp_mask; temp_mask <<= 1, maskn++); ++ for (bebits = BEMASK; bebits != 0; maskn++, bebits <<= 1) ++ if ((skp->smk_mask.s_addr & bebits) == 0) ++ break; + + seq_printf(s, "%u.%u.%u.%u/%d %s\n", + hp[0], hp[1], hp[2], hp[3], maskn, skp->smk_label); +@@ -696,42 +702,6 @@ + } + + /** +- * smk_netlbladdr_insert +- * @new : netlabel to insert +- * +- * This helper insert netlabel in the smack_netlbladdrs list +- * sorted by netmask length (longest to smallest) +- */ +-static void smk_netlbladdr_insert(struct smk_netlbladdr *new) +-{ +- struct smk_netlbladdr *m; +- +- if (smack_netlbladdrs == NULL) { +- smack_netlbladdrs = new; +- return; +- } +- +- /* the comparison '>' is a bit hacky, but works */ +- if (new->smk_mask.s_addr > smack_netlbladdrs->smk_mask.s_addr) { +- new->smk_next = smack_netlbladdrs; +- smack_netlbladdrs = new; +- return; +- } +- for (m = smack_netlbladdrs; m != NULL; m = m->smk_next) { +- if (m->smk_next == NULL) { +- m->smk_next = new; +- return; +- } +- if (new->smk_mask.s_addr > m->smk_next->smk_mask.s_addr) { +- new->smk_next = m->smk_next; +- m->smk_next = new; +- return; +- } +- } +-} +- +- +-/** + * smk_write_netlbladdr - write() for /smack/netlabel + * @filp: file pointer, not actually used + * @buf: where to get the data from +@@ -754,9 +724,8 @@ + struct netlbl_audit audit_info; + struct in_addr mask; + unsigned int m; +- u32 mask_bits = (1<<31); ++ __be32 bebits = BEMASK; + __be32 nsa; +- u32 temp_mask; + + /* + * Must have privilege. +@@ -792,13 +761,10 @@ + if (sp == NULL) + return -EINVAL; + +- for (temp_mask = 0; m > 0; m--) { +- temp_mask |= mask_bits; +- mask_bits >>= 1; ++ for (mask.s_addr = 0; m > 0; m--) { ++ mask.s_addr |= bebits; ++ bebits <<= 1; + } +- mask.s_addr = cpu_to_be32(temp_mask); +- +- newname.sin_addr.s_addr &= mask.s_addr; + /* + * Only allow one writer at a time. Writes should be + * quite rare and small in any case. +@@ -806,7 +772,6 @@ + mutex_lock(&smk_netlbladdr_lock); + + nsa = newname.sin_addr.s_addr; +- /* try to find if the prefix is already in the list */ + for (skp = smack_netlbladdrs; skp != NULL; skp = skp->smk_next) + if (skp->smk_host.sin_addr.s_addr == nsa && + skp->smk_mask.s_addr == mask.s_addr) +@@ -822,8 +787,9 @@ + rc = 0; + skp->smk_host.sin_addr.s_addr = newname.sin_addr.s_addr; + skp->smk_mask.s_addr = mask.s_addr; ++ skp->smk_next = smack_netlbladdrs; + skp->smk_label = sp; +- smk_netlbladdr_insert(skp); ++ smack_netlbladdrs = skp; + } + } else { + rc = netlbl_cfg_unlbl_static_del(&init_net, NULL, +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/security/smack/smack_lsm.c linux-2.6.29-rc3.owrt/security/smack/smack_lsm.c +--- linux-2.6.29.owrt/security/smack/smack_lsm.c 2009-05-10 22:04:39.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/security/smack/smack_lsm.c 2009-05-10 23:48:34.000000000 +0200 +@@ -1498,31 +1498,58 @@ + * looks for host based access restrictions + * + * This version will only be appropriate for really small +- * sets of single label hosts. ++ * sets of single label hosts. Because of the masking ++ * it cannot shortcut out on the first match. There are ++ * numerious ways to address the problem, but none of them ++ * have been applied here. + * + * Returns the label of the far end or NULL if it's not special. + */ + static char *smack_host_label(struct sockaddr_in *sip) + { + struct smk_netlbladdr *snp; ++ char *bestlabel = NULL; + struct in_addr *siap = &sip->sin_addr; ++ struct in_addr *liap; ++ struct in_addr *miap; ++ struct in_addr bestmask; + + if (siap->s_addr == 0) + return NULL; + ++ bestmask.s_addr = 0; ++ + for (snp = smack_netlbladdrs; snp != NULL; snp = snp->smk_next) { ++ liap = &snp->smk_host.sin_addr; ++ miap = &snp->smk_mask; ++ /* ++ * If the addresses match after applying the list entry mask ++ * the entry matches the address. If it doesn't move along to ++ * the next entry. ++ */ ++ if ((liap->s_addr & miap->s_addr) != ++ (siap->s_addr & miap->s_addr)) ++ continue; + /* +- * we break after finding the first match because +- * the list is sorted from longest to shortest mask +- * so we have found the most specific match ++ * If the list entry mask identifies a single address ++ * it can't get any more specific. + */ +- if ((&snp->smk_host.sin_addr)->s_addr == +- (siap->s_addr & (&snp->smk_mask)->s_addr)) { ++ if (miap->s_addr == 0xffffffff) + return snp->smk_label; +- } ++ /* ++ * If the list entry mask is less specific than the best ++ * already found this entry is uninteresting. ++ */ ++ if ((miap->s_addr | bestmask.s_addr) == bestmask.s_addr) ++ continue; ++ /* ++ * This is better than any entry found so far. ++ */ ++ bestmask.s_addr = miap->s_addr; ++ bestlabel = snp->smk_label; + } + +- return NULL; ++ return bestlabel; + } + + /** +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/sound/arm/aaci.c linux-2.6.29-rc3.owrt/sound/arm/aaci.c +--- linux-2.6.29.owrt/sound/arm/aaci.c 2009-05-10 22:04:39.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/sound/arm/aaci.c 2009-05-10 23:48:34.000000000 +0200 +@@ -90,7 +90,7 @@ + */ + do { + v = readl(aaci->base + AACI_SLFR); +- } while ((v & (SLFR_1TXB|SLFR_2TXB)) && --timeout); ++ } while ((v & (SLFR_1TXB|SLFR_2TXB)) && timeout--); + + if (!timeout) + dev_err(&aaci->dev->dev, +@@ -126,7 +126,7 @@ + */ + do { + v = readl(aaci->base + AACI_SLFR); +- } while ((v & SLFR_1TXB) && --timeout); ++ } while ((v & SLFR_1TXB) && timeout--); + + if (!timeout) { + dev_err(&aaci->dev->dev, "timeout on slot 1 TX busy\n"); +@@ -147,7 +147,7 @@ + do { + cond_resched(); + v = readl(aaci->base + AACI_SLFR) & (SLFR_1RXV|SLFR_2RXV); +- } while ((v != (SLFR_1RXV|SLFR_2RXV)) && --timeout); ++ } while ((v != (SLFR_1RXV|SLFR_2RXV)) && timeout--); + + if (!timeout) { + dev_err(&aaci->dev->dev, "timeout on RX valid\n"); +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/sound/core/jack.c linux-2.6.29-rc3.owrt/sound/core/jack.c +--- linux-2.6.29.owrt/sound/core/jack.c 2009-05-10 22:04:39.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/sound/core/jack.c 2009-05-10 23:48:34.000000000 +0200 +@@ -47,7 +47,7 @@ + int err; + + snprintf(jack->name, sizeof(jack->name), "%s %s", +- card->shortname, jack->id); ++ card->longname, jack->id); + jack->input_dev->name = jack->name; + + /* Default to the sound card device. */ +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/sound/core/oss/mixer_oss.c linux-2.6.29-rc3.owrt/sound/core/oss/mixer_oss.c +--- linux-2.6.29.owrt/sound/core/oss/mixer_oss.c 2009-05-10 22:04:39.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/sound/core/oss/mixer_oss.c 2009-05-10 23:48:34.000000000 +0200 +@@ -692,9 +692,6 @@ + snd_mixer_oss_put_volume1_vol(fmixer, pslot, slot->numid[SNDRV_MIXER_OSS_ITEM_PVOLUME], left, right); + if (slot->present & SNDRV_MIXER_OSS_PRESENT_CVOLUME) + snd_mixer_oss_put_volume1_vol(fmixer, pslot, slot->numid[SNDRV_MIXER_OSS_ITEM_CVOLUME], left, right); +- } else if (slot->present & SNDRV_MIXER_OSS_PRESENT_CVOLUME) { +- snd_mixer_oss_put_volume1_vol(fmixer, pslot, +- slot->numid[SNDRV_MIXER_OSS_ITEM_CVOLUME], left, right); + } else if (slot->present & SNDRV_MIXER_OSS_PRESENT_GVOLUME) { + snd_mixer_oss_put_volume1_vol(fmixer, pslot, slot->numid[SNDRV_MIXER_OSS_ITEM_GVOLUME], left, right); + } else if (slot->present & SNDRV_MIXER_OSS_PRESENT_GLOBAL) { +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/sound/core/oss/pcm_oss.c linux-2.6.29-rc3.owrt/sound/core/oss/pcm_oss.c +--- linux-2.6.29.owrt/sound/core/oss/pcm_oss.c 2009-05-10 22:04:39.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/sound/core/oss/pcm_oss.c 2009-05-10 23:48:34.000000000 +0200 +@@ -1767,7 +1767,7 @@ + AFMT_S8 | AFMT_U16_LE | + AFMT_U16_BE | + AFMT_S32_LE | AFMT_S32_BE | +- AFMT_S24_LE | AFMT_S24_BE | ++ AFMT_S24_LE | AFMT_S24_LE | + AFMT_S24_PACKED; + params = kmalloc(sizeof(*params), GFP_KERNEL); + if (!params) +@@ -2872,7 +2872,7 @@ + setup = kmalloc(sizeof(*setup), GFP_KERNEL); + if (! setup) { + buffer->error = -ENOMEM; +- mutex_unlock(&pstr->oss.setup_mutex); ++ mutex_lock(&pstr->oss.setup_mutex); + return; + } + if (pstr->oss.setup_list == NULL) +@@ -2886,7 +2886,7 @@ + if (! template.task_name) { + kfree(setup); + buffer->error = -ENOMEM; +- mutex_unlock(&pstr->oss.setup_mutex); ++ mutex_lock(&pstr->oss.setup_mutex); + return; + } + } +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/sound/core/oss/rate.c linux-2.6.29-rc3.owrt/sound/core/oss/rate.c +--- linux-2.6.29.owrt/sound/core/oss/rate.c 2009-05-10 22:04:39.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/sound/core/oss/rate.c 2009-05-10 23:48:34.000000000 +0200 +@@ -157,7 +157,7 @@ + while (dst_frames1 > 0) { + S1 = S2; + if (src_frames1-- > 0) { +- S2 = *src; ++ S1 = *src; + src += src_step; + } + if (pos & ~R_MASK) { +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/sound/core/sgbuf.c linux-2.6.29-rc3.owrt/sound/core/sgbuf.c +--- linux-2.6.29.owrt/sound/core/sgbuf.c 2009-05-10 22:04:39.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/sound/core/sgbuf.c 2009-05-10 23:48:34.000000000 +0200 +@@ -38,10 +38,6 @@ + if (! sgbuf) + return -EINVAL; + +- if (dmab->area) +- vunmap(dmab->area); +- dmab->area = NULL; +- + tmpb.dev.type = SNDRV_DMA_TYPE_DEV; + tmpb.dev.dev = sgbuf->dev; + for (i = 0; i < sgbuf->pages; i++) { +@@ -52,6 +48,9 @@ + tmpb.bytes = (sgbuf->table[i].addr & ~PAGE_MASK) << PAGE_SHIFT; + snd_dma_free_pages(&tmpb); + } ++ if (dmab->area) ++ vunmap(dmab->area); ++ dmab->area = NULL; + + kfree(sgbuf->table); + kfree(sgbuf->page_table); +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/sound/drivers/mtpav.c linux-2.6.29-rc3.owrt/sound/drivers/mtpav.c +--- linux-2.6.29.owrt/sound/drivers/mtpav.c 2009-05-10 22:04:39.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/sound/drivers/mtpav.c 2009-05-10 23:48:34.000000000 +0200 +@@ -706,6 +706,7 @@ + mtp_card->card = card; + mtp_card->irq = -1; + mtp_card->share_irq = 0; ++ mtp_card->inmidiport = 0xffffffff; + mtp_card->inmidistate = 0; + mtp_card->outmidihwport = 0xffffffff; + init_timer(&mtp_card->timer); +@@ -718,8 +719,6 @@ + if (err < 0) + goto __error; + +- mtp_card->inmidiport = mtp_card->num_ports + MTPAV_PIDX_BROADCAST; +- + err = snd_mtpav_get_ISA(mtp_card); + if (err < 0) + goto __error; +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/sound/isa/opl3sa2.c linux-2.6.29-rc3.owrt/sound/isa/opl3sa2.c +--- linux-2.6.29.owrt/sound/isa/opl3sa2.c 2009-05-10 22:04:39.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/sound/isa/opl3sa2.c 2009-05-10 23:48:34.000000000 +0200 +@@ -550,27 +550,21 @@ + #ifdef CONFIG_PM + static int snd_opl3sa2_suspend(struct snd_card *card, pm_message_t state) + { +- if (card) { +- struct snd_opl3sa2 *chip = card->private_data; ++ struct snd_opl3sa2 *chip = card->private_data; + +- snd_power_change_state(card, SNDRV_CTL_POWER_D3hot); +- chip->wss->suspend(chip->wss); +- /* power down */ +- snd_opl3sa2_write(chip, OPL3SA2_PM_CTRL, OPL3SA2_PM_D3); +- } ++ snd_power_change_state(card, SNDRV_CTL_POWER_D3hot); ++ chip->wss->suspend(chip->wss); ++ /* power down */ ++ snd_opl3sa2_write(chip, OPL3SA2_PM_CTRL, OPL3SA2_PM_D3); + + return 0; + } + + static int snd_opl3sa2_resume(struct snd_card *card) + { +- struct snd_opl3sa2 *chip; ++ struct snd_opl3sa2 *chip = card->private_data; + int i; + +- if (!card) +- return 0; +- +- chip = card->private_data; + /* power up */ + snd_opl3sa2_write(chip, OPL3SA2_PM_CTRL, OPL3SA2_PM_D0); + +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/sound/oss/dmasound/dmasound_atari.c linux-2.6.29-rc3.owrt/sound/oss/dmasound/dmasound_atari.c +--- linux-2.6.29.owrt/sound/oss/dmasound/dmasound_atari.c 2009-05-10 22:04:39.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/sound/oss/dmasound/dmasound_atari.c 2009-05-10 23:48:34.000000000 +0200 +@@ -847,23 +847,23 @@ + of events. So all we need to keep the music playing is + to provide the sound hardware with new data upon + an interrupt from timer A. */ +- st_mfp.tim_ct_a = 0; /* ++roman: Stop timer before programming! */ +- st_mfp.tim_dt_a = 1; /* Cause interrupt after first event. */ +- st_mfp.tim_ct_a = 8; /* Turn on event counting. */ ++ mfp.tim_ct_a = 0; /* ++roman: Stop timer before programming! */ ++ mfp.tim_dt_a = 1; /* Cause interrupt after first event. */ ++ mfp.tim_ct_a = 8; /* Turn on event counting. */ + /* Register interrupt handler. */ + if (request_irq(IRQ_MFP_TIMA, AtaInterrupt, IRQ_TYPE_SLOW, "DMA sound", + AtaInterrupt)) + return 0; +- st_mfp.int_en_a |= 0x20; /* Turn interrupt on. */ +- st_mfp.int_mk_a |= 0x20; ++ mfp.int_en_a |= 0x20; /* Turn interrupt on. */ ++ mfp.int_mk_a |= 0x20; + return 1; + } + + #ifdef MODULE + static void AtaIrqCleanUp(void) + { +- st_mfp.tim_ct_a = 0; /* stop timer */ +- st_mfp.int_en_a &= ~0x20; /* turn interrupt off */ ++ mfp.tim_ct_a = 0; /* stop timer */ ++ mfp.int_en_a &= ~0x20; /* turn interrupt off */ + free_irq(IRQ_MFP_TIMA, AtaInterrupt); + } + #endif /* MODULE */ +@@ -1599,7 +1599,7 @@ + is_falcon = 0; + } else + return -ENODEV; +- if ((st_mfp.int_en_a & st_mfp.int_mk_a & 0x20) == 0) ++ if ((mfp.int_en_a & mfp.int_mk_a & 0x20) == 0) + return dmasound_init(); + else { + printk("DMA sound driver: Timer A interrupt already in use\n"); +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/sound/pci/aw2/aw2-alsa.c linux-2.6.29-rc3.owrt/sound/pci/aw2/aw2-alsa.c +--- linux-2.6.29.owrt/sound/pci/aw2/aw2-alsa.c 2009-05-10 22:04:39.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/sound/pci/aw2/aw2-alsa.c 2009-05-10 23:48:34.000000000 +0200 +@@ -165,7 +165,7 @@ + MODULE_PARM_DESC(enable, "Enable Audiowerk2 soundcard."); + + static struct pci_device_id snd_aw2_ids[] = { +- {PCI_VENDOR_ID_SAA7146, PCI_DEVICE_ID_SAA7146, 0, 0, ++ {PCI_VENDOR_ID_SAA7146, PCI_DEVICE_ID_SAA7146, PCI_ANY_ID, PCI_ANY_ID, + 0, 0, 0}, + {0} + }; +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/sound/pci/emu10k1/emu10k1_main.c linux-2.6.29-rc3.owrt/sound/pci/emu10k1/emu10k1_main.c +--- linux-2.6.29.owrt/sound/pci/emu10k1/emu10k1_main.c 2009-05-10 22:04:39.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/sound/pci/emu10k1/emu10k1_main.c 2009-05-10 23:48:34.000000000 +0200 +@@ -1528,7 +1528,6 @@ + .ca0151_chip = 1, + .spk71 = 1, + .spdif_bug = 1, +- .invert_shared_spdif = 1, /* digital/analog switch swapped */ + .ac97_chip = 1} , + {.vendor = 0x1102, .device = 0x0004, .subsystem = 0x10021102, + .driver = "Audigy2", .name = "SB Audigy 2 Platinum [SB0240P]", +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/sound/pci/hda/hda_codec.c linux-2.6.29-rc3.owrt/sound/pci/hda/hda_codec.c +--- linux-2.6.29.owrt/sound/pci/hda/hda_codec.c 2009-05-10 22:04:39.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/sound/pci/hda/hda_codec.c 2009-05-10 23:48:34.000000000 +0200 +@@ -487,6 +487,7 @@ + { + struct hda_bus *bus; + int err; ++ char qname[8]; + static struct snd_device_ops dev_ops = { + .dev_register = snd_hda_bus_dev_register, + .dev_free = snd_hda_bus_dev_free, +@@ -516,12 +517,10 @@ + mutex_init(&bus->cmd_mutex); + INIT_LIST_HEAD(&bus->codec_list); + +- snprintf(bus->workq_name, sizeof(bus->workq_name), +- "hd-audio%d", card->number); +- bus->workq = create_singlethread_workqueue(bus->workq_name); ++ snprintf(qname, sizeof(qname), "hda%d", card->number); ++ bus->workq = create_workqueue(qname); + if (!bus->workq) { +- snd_printk(KERN_ERR "cannot create workqueue %s\n", +- bus->workq_name); ++ snd_printk(KERN_ERR "cannot create workqueue %s\n", qname); + kfree(bus); + return -ENOMEM; + } +@@ -3088,16 +3087,6 @@ + } + EXPORT_SYMBOL_HDA(snd_hda_multi_out_dig_prepare); + +-int snd_hda_multi_out_dig_cleanup(struct hda_codec *codec, +- struct hda_multi_out *mout) +-{ +- mutex_lock(&codec->spdif_mutex); +- cleanup_dig_out_stream(codec, mout->dig_out_nid); +- mutex_unlock(&codec->spdif_mutex); +- return 0; +-} +-EXPORT_SYMBOL_HDA(snd_hda_multi_out_dig_cleanup); +- + /* + * release the digital out + */ +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/sound/pci/hda/hda_codec.h linux-2.6.29-rc3.owrt/sound/pci/hda/hda_codec.h +--- linux-2.6.29.owrt/sound/pci/hda/hda_codec.h 2009-05-10 22:04:39.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/sound/pci/hda/hda_codec.h 2009-05-10 23:48:34.000000000 +0200 +@@ -614,7 +614,6 @@ + + /* unsolicited event queue */ + struct hda_bus_unsolicited *unsol; +- char workq_name[16]; + struct workqueue_struct *workq; /* common workqueue for codecs */ + + /* assigned PCMs */ +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/sound/pci/hda/hda_hwdep.c linux-2.6.29-rc3.owrt/sound/pci/hda/hda_hwdep.c +--- linux-2.6.29.owrt/sound/pci/hda/hda_hwdep.c 2009-05-10 22:04:39.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/sound/pci/hda/hda_hwdep.c 2009-05-10 23:48:34.000000000 +0200 +@@ -175,7 +175,7 @@ + err = snd_hda_codec_build_controls(codec); + if (err < 0) + return err; +- return snd_card_register(codec->bus->card); ++ return 0; + } + + /* +@@ -277,19 +277,18 @@ + { + struct snd_hwdep *hwdep = dev_get_drvdata(dev); + struct hda_codec *codec = hwdep->private_data; +- struct hda_verb *v; +- int nid, verb, param; ++ char *p; ++ struct hda_verb verb, *v; + +- if (sscanf(buf, "%i %i %i", &nid, &verb, ¶m) != 3) +- return -EINVAL; +- if (!nid || !verb) ++ verb.nid = simple_strtoul(buf, &p, 0); ++ verb.verb = simple_strtoul(p, &p, 0); ++ verb.param = simple_strtoul(p, &p, 0); ++ if (!verb.nid || !verb.verb || !verb.param) + return -EINVAL; + v = snd_array_new(&codec->init_verbs); + if (!v) + return -ENOMEM; +- v->nid = nid; +- v->verb = verb; +- v->param = param; ++ *v = verb; + return count; + } + +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/sound/pci/hda/hda_intel.c linux-2.6.29-rc3.owrt/sound/pci/hda/hda_intel.c +--- linux-2.6.29.owrt/sound/pci/hda/hda_intel.c 2009-05-10 22:04:39.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/sound/pci/hda/hda_intel.c 2009-05-10 23:48:34.000000000 +0200 +@@ -1947,13 +1947,16 @@ + return 0; + } + ++static int azx_resume_early(struct pci_dev *pci) ++{ ++ return pci_restore_state(pci); ++} ++ + static int azx_resume(struct pci_dev *pci) + { + struct snd_card *card = pci_get_drvdata(pci); + struct azx *chip = card->private_data; + +- pci_set_power_state(pci, PCI_D0); +- pci_restore_state(pci); + if (pci_enable_device(pci) < 0) { + printk(KERN_ERR "hda-intel: pci_enable_device failed, " + "disabling device\n"); +@@ -2059,31 +2062,26 @@ + { + const struct snd_pci_quirk *q; + +- switch (fix) { +- case POS_FIX_LPIB: +- case POS_FIX_POSBUF: +- return fix; +- } +- +- /* Check VIA/ATI HD Audio Controller exist */ +- switch (chip->driver_type) { +- case AZX_DRIVER_VIA: +- case AZX_DRIVER_ATI: ++ /* Check VIA HD Audio Controller exist */ ++ if (chip->pci->vendor == PCI_VENDOR_ID_VIA && ++ chip->pci->device == VIA_HDAC_DEVICE_ID) { + chip->via_dmapos_patch = 1; + /* Use link position directly, avoid any transfer problem. */ + return POS_FIX_LPIB; + } + chip->via_dmapos_patch = 0; + +- q = snd_pci_quirk_lookup(chip->pci, position_fix_list); +- if (q) { +- printk(KERN_INFO +- "hda_intel: position_fix set to %d " +- "for device %04x:%04x\n", +- q->value, q->subvendor, q->subdevice); +- return q->value; ++ if (fix == POS_FIX_AUTO) { ++ q = snd_pci_quirk_lookup(chip->pci, position_fix_list); ++ if (q) { ++ printk(KERN_INFO ++ "hda_intel: position_fix set to %d " ++ "for device %04x:%04x\n", ++ q->value, q->subvendor, q->subdevice); ++ return q->value; ++ } + } +- return POS_FIX_AUTO; ++ return fix; + } + + /* +@@ -2100,8 +2098,6 @@ + SND_PCI_QUIRK(0x1028, 0x20ac, "Dell Studio Desktop", 0x01), + /* including bogus ALC268 in slot#2 that conflicts with ALC888 */ + SND_PCI_QUIRK(0x17c0, 0x4085, "Medion MD96630", 0x01), +- /* conflict of ALC268 in slot#3 (digital I/O); a temporary fix */ +- SND_PCI_QUIRK(0x1179, 0xff00, "Toshiba laptop", 0x03), + {} + }; + +@@ -2215,17 +2211,9 @@ + gcap = azx_readw(chip, GCAP); + snd_printdd("chipset global capabilities = 0x%x\n", gcap); + +- /* ATI chips seems buggy about 64bit DMA addresses */ +- if (chip->driver_type == AZX_DRIVER_ATI) +- gcap &= ~0x01; +- + /* allow 64bit DMA address if supported by H/W */ + if ((gcap & 0x01) && !pci_set_dma_mask(pci, DMA_64BIT_MASK)) + pci_set_consistent_dma_mask(pci, DMA_64BIT_MASK); +- else { +- pci_set_dma_mask(pci, DMA_32BIT_MASK); +- pci_set_consistent_dma_mask(pci, DMA_32BIT_MASK); +- } + + /* read number of streams from GCAP register instead of using + * hardcoded value +@@ -2480,6 +2468,7 @@ + .remove = __devexit_p(azx_remove), + #ifdef CONFIG_PM + .suspend = azx_suspend, ++ .resume_early = azx_resume_early, + .resume = azx_resume, + #endif + }; +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/sound/pci/hda/hda_local.h linux-2.6.29-rc3.owrt/sound/pci/hda/hda_local.h +--- linux-2.6.29.owrt/sound/pci/hda/hda_local.h 2009-05-10 22:04:39.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/sound/pci/hda/hda_local.h 2009-05-10 23:48:34.000000000 +0200 +@@ -251,8 +251,6 @@ + unsigned int stream_tag, + unsigned int format, + struct snd_pcm_substream *substream); +-int snd_hda_multi_out_dig_cleanup(struct hda_codec *codec, +- struct hda_multi_out *mout); + int snd_hda_multi_out_analog_open(struct hda_codec *codec, + struct hda_multi_out *mout, + struct snd_pcm_substream *substream, +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/sound/pci/hda/hda_proc.c linux-2.6.29-rc3.owrt/sound/pci/hda/hda_proc.c +--- linux-2.6.29.owrt/sound/pci/hda/hda_proc.c 2009-05-10 22:04:39.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/sound/pci/hda/hda_proc.c 2009-05-10 23:48:34.000000000 +0200 +@@ -399,8 +399,7 @@ + { + int c, curr = -1; + +- if (conn_len > 1 && wid_type != AC_WID_AUD_MIX && +- wid_type != AC_WID_VOL_KNB) ++ if (conn_len > 1 && wid_type != AC_WID_AUD_MIX) + curr = snd_hda_codec_read(codec, nid, 0, + AC_VERB_GET_CONNECT_SEL, 0); + snd_iprintf(buffer, " Connection: %d\n", conn_len); +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/sound/pci/hda/patch_analog.c linux-2.6.29-rc3.owrt/sound/pci/hda/patch_analog.c +--- linux-2.6.29.owrt/sound/pci/hda/patch_analog.c 2009-05-10 22:04:39.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/sound/pci/hda/patch_analog.c 2009-05-10 23:48:34.000000000 +0200 +@@ -275,14 +275,6 @@ + format, substream); + } + +-static int ad198x_dig_playback_pcm_cleanup(struct hda_pcm_stream *hinfo, +- struct hda_codec *codec, +- struct snd_pcm_substream *substream) +-{ +- struct ad198x_spec *spec = codec->spec; +- return snd_hda_multi_out_dig_cleanup(codec, &spec->multiout); +-} +- + /* + * Analog capture + */ +@@ -341,8 +333,7 @@ + .ops = { + .open = ad198x_dig_playback_pcm_open, + .close = ad198x_dig_playback_pcm_close, +- .prepare = ad198x_dig_playback_pcm_prepare, +- .cleanup = ad198x_dig_playback_pcm_cleanup ++ .prepare = ad198x_dig_playback_pcm_prepare + }, + }; + +@@ -1894,8 +1885,8 @@ + #define AD1988_SPDIF_OUT_HDMI 0x0b + #define AD1988_SPDIF_IN 0x07 + +-static hda_nid_t ad1989b_slave_dig_outs[] = { +- AD1988_SPDIF_OUT, AD1988_SPDIF_OUT_HDMI, 0 ++static hda_nid_t ad1989b_slave_dig_outs[2] = { ++ AD1988_SPDIF_OUT, AD1988_SPDIF_OUT_HDMI + }; + + static struct hda_input_mux ad1988_6stack_capture_source = { +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/sound/pci/hda/patch_conexant.c linux-2.6.29-rc3.owrt/sound/pci/hda/patch_conexant.c +--- linux-2.6.29.owrt/sound/pci/hda/patch_conexant.c 2009-05-10 22:04:39.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/sound/pci/hda/patch_conexant.c 2009-05-10 23:48:34.000000000 +0200 +@@ -347,7 +347,6 @@ + &spec->cur_mux[adc_idx]); + } + +-#ifdef CONFIG_SND_JACK + static int conexant_add_jack(struct hda_codec *codec, + hda_nid_t nid, int type) + { +@@ -395,6 +394,7 @@ + + static int conexant_init_jacks(struct hda_codec *codec) + { ++#ifdef CONFIG_SND_JACK + struct conexant_spec *spec = codec->spec; + int i; + +@@ -422,19 +422,10 @@ + ++hv; + } + } ++#endif + return 0; + + } +-#else +-static inline void conexant_report_jack(struct hda_codec *codec, hda_nid_t nid) +-{ +-} +- +-static inline int conexant_init_jacks(struct hda_codec *codec) +-{ +- return 0; +-} +-#endif + + static int conexant_init(struct hda_codec *codec) + { +@@ -1575,7 +1566,6 @@ + SND_PCI_QUIRK(0x103c, 0x30a5, "HP DV5200T/DV8000T", CXT5047_LAPTOP_HP), + SND_PCI_QUIRK(0x103c, 0x30b2, "HP DV2000T/DV3000T", CXT5047_LAPTOP), + SND_PCI_QUIRK(0x103c, 0x30b5, "HP DV2000Z", CXT5047_LAPTOP), +- SND_PCI_QUIRK(0x103c, 0x30cf, "HP DV6700", CXT5047_LAPTOP), + SND_PCI_QUIRK(0x1179, 0xff31, "Toshiba P100", CXT5047_LAPTOP_EAPD), + {} + }; +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/sound/pci/hda/patch_intelhdmi.c linux-2.6.29-rc3.owrt/sound/pci/hda/patch_intelhdmi.c +--- linux-2.6.29.owrt/sound/pci/hda/patch_intelhdmi.c 2009-05-10 22:04:39.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/sound/pci/hda/patch_intelhdmi.c 2009-05-10 23:48:34.000000000 +0200 +@@ -49,6 +49,11 @@ + {} /* terminator */ + }; + ++static struct hda_verb pinout_disable_verb[] = { ++ {PIN_NID, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00}, ++ {} ++}; ++ + static struct hda_verb unsolicited_response_verb[] = { + {PIN_NID, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | + INTEL_HDMI_EVENT_TAG}, +@@ -243,6 +248,10 @@ + + static void hdmi_enable_output(struct hda_codec *codec) + { ++ /* Enable Audio InfoFrame Transmission */ ++ hdmi_set_dip_index(codec, PIN_NID, 0x0, 0x0); ++ snd_hda_codec_write(codec, PIN_NID, 0, AC_VERB_SET_HDMI_DIP_XMIT, ++ AC_DIPXMIT_BEST); + /* Unmute */ + if (get_wcaps(codec, PIN_NID) & AC_WCAP_OUT_AMP) + snd_hda_codec_write(codec, PIN_NID, 0, +@@ -251,24 +260,17 @@ + snd_hda_sequence_write(codec, pinout_enable_verb); + } + +-/* +- * Enable Audio InfoFrame Transmission +- */ +-static void hdmi_start_infoframe_trans(struct hda_codec *codec) ++static void hdmi_disable_output(struct hda_codec *codec) + { +- hdmi_set_dip_index(codec, PIN_NID, 0x0, 0x0); +- snd_hda_codec_write(codec, PIN_NID, 0, AC_VERB_SET_HDMI_DIP_XMIT, +- AC_DIPXMIT_BEST); +-} ++ snd_hda_sequence_write(codec, pinout_disable_verb); ++ if (get_wcaps(codec, PIN_NID) & AC_WCAP_OUT_AMP) ++ snd_hda_codec_write(codec, PIN_NID, 0, ++ AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE); + +-/* +- * Disable Audio InfoFrame Transmission +- */ +-static void hdmi_stop_infoframe_trans(struct hda_codec *codec) +-{ +- hdmi_set_dip_index(codec, PIN_NID, 0x0, 0x0); +- snd_hda_codec_write(codec, PIN_NID, 0, AC_VERB_SET_HDMI_DIP_XMIT, +- AC_DIPXMIT_DISABLE); ++ /* ++ * FIXME: noises may arise when playing music after reloading the ++ * kernel module, until the next X restart or monitor repower. ++ */ + } + + static int hdmi_get_channel_count(struct hda_codec *codec) +@@ -366,16 +368,11 @@ + struct hdmi_audio_infoframe *ai) + { + u8 *params = (u8 *)ai; +- u8 sum = 0; + int i; + + hdmi_debug_dip_size(codec); + hdmi_clear_dip_buffers(codec); /* be paranoid */ + +- for (i = 0; i < sizeof(ai); i++) +- sum += params[i]; +- ai->checksum = - sum; +- + hdmi_set_dip_index(codec, PIN_NID, 0x0, 0x0); + for (i = 0; i < sizeof(ai); i++) + hdmi_write_dip_byte(codec, PIN_NID, params[i]); +@@ -422,16 +419,12 @@ + /* + * CA defaults to 0 for basic stereo audio + */ +- if (channels <= 2) ++ if (!eld->eld_ver) + return 0; +- +- /* +- * HDMI sink's ELD info cannot always be retrieved for now, e.g. +- * in console or for audio devices. Assume the highest speakers +- * configuration, to _not_ prohibit multi-channel audio playback. +- */ + if (!eld->spk_alloc) +- eld->spk_alloc = 0xffff; ++ return 0; ++ if (channels <= 2) ++ return 0; + + /* + * expand ELD's speaker allocation mask +@@ -492,7 +485,6 @@ + hdmi_setup_channel_mapping(codec, &ai); + + hdmi_fill_audio_infoframe(codec, &ai); +- hdmi_start_infoframe_trans(codec); + } + + +@@ -570,7 +562,7 @@ + { + struct intel_hdmi_spec *spec = codec->spec; + +- hdmi_stop_infoframe_trans(codec); ++ hdmi_disable_output(codec); + + return snd_hda_multi_out_dig_close(codec, &spec->multiout); + } +@@ -590,6 +582,8 @@ + + hdmi_setup_audio_infoframe(codec, substream); + ++ hdmi_enable_output(codec); ++ + return 0; + } + +@@ -634,7 +628,8 @@ + + static int intel_hdmi_init(struct hda_codec *codec) + { +- hdmi_enable_output(codec); ++ /* disable audio output as early as possible */ ++ hdmi_disable_output(codec); + + snd_hda_sequence_write(codec, unsolicited_response_verb); + +@@ -684,7 +679,6 @@ + { .id = 0x80862801, .name = "G45 DEVBLC", .patch = patch_intel_hdmi }, + { .id = 0x80862802, .name = "G45 DEVCTG", .patch = patch_intel_hdmi }, + { .id = 0x80862803, .name = "G45 DEVELK", .patch = patch_intel_hdmi }, +- { .id = 0x80862804, .name = "G45 DEVIBX", .patch = patch_intel_hdmi }, + { .id = 0x10951392, .name = "SiI1392 HDMI", .patch = patch_intel_hdmi }, + {} /* terminator */ + }; +@@ -693,7 +687,6 @@ + MODULE_ALIAS("snd-hda-codec-id:80862801"); + MODULE_ALIAS("snd-hda-codec-id:80862802"); + MODULE_ALIAS("snd-hda-codec-id:80862803"); +-MODULE_ALIAS("snd-hda-codec-id:80862804"); + MODULE_ALIAS("snd-hda-codec-id:10951392"); + + MODULE_LICENSE("GPL"); +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/sound/pci/hda/patch_realtek.c linux-2.6.29-rc3.owrt/sound/pci/hda/patch_realtek.c +--- linux-2.6.29.owrt/sound/pci/hda/patch_realtek.c 2009-05-10 22:04:39.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/sound/pci/hda/patch_realtek.c 2009-05-10 23:48:34.000000000 +0200 +@@ -1037,7 +1037,6 @@ + case 0x10ec0267: + case 0x10ec0268: + case 0x10ec0269: +- case 0x10ec0272: + case 0x10ec0660: + case 0x10ec0662: + case 0x10ec0663: +@@ -1066,7 +1065,6 @@ + case 0x10ec0882: + case 0x10ec0883: + case 0x10ec0885: +- case 0x10ec0887: + case 0x10ec0889: + snd_hda_codec_write(codec, 0x20, 0, + AC_VERB_SET_COEF_INDEX, 7); +@@ -7014,15 +7012,12 @@ + break; + case 0x106b1000: /* iMac 24 */ + case 0x106b2800: /* AppleTV */ +- case 0x106b3e00: /* iMac 24 Aluminium */ + board_config = ALC885_IMAC24; + break; +- case 0x106b00a0: /* MacBookPro3,1 - Another revision */ + case 0x106b00a1: /* Macbook (might be wrong - PCI SSID?) */ + case 0x106b00a4: /* MacbookPro4,1 */ + case 0x106b2c00: /* Macbook Pro rev3 */ + case 0x106b3600: /* Macbook 3.1 */ +- case 0x106b3800: /* MacbookPro4,1 - latter revision */ + board_config = ALC885_MBP3; + break; + default: +@@ -8470,8 +8465,6 @@ + ALC888_ACER_ASPIRE_4930G), + SND_PCI_QUIRK(0x1025, 0x015e, "Acer Aspire 6930G", + ALC888_ACER_ASPIRE_4930G), +- SND_PCI_QUIRK(0x1025, 0x0166, "Acer Aspire 6530G", +- ALC888_ACER_ASPIRE_4930G), + SND_PCI_QUIRK(0x1025, 0, "Acer laptop", ALC883_ACER), /* default Acer */ + SND_PCI_QUIRK(0x1028, 0x020d, "Dell Inspiron 530", ALC888_6ST_DELL), + SND_PCI_QUIRK(0x103c, 0x2a3d, "HP Pavillion", ALC883_6ST_DIG), +@@ -8481,7 +8474,6 @@ + SND_PCI_QUIRK(0x103c, 0x2a66, "HP Acacia", ALC888_3ST_HP), + SND_PCI_QUIRK(0x1043, 0x1873, "Asus M90V", ALC888_ASUS_M90V), + SND_PCI_QUIRK(0x1043, 0x8249, "Asus M2A-VM HDMI", ALC883_3ST_6ch_DIG), +- SND_PCI_QUIRK(0x1043, 0x8284, "Asus Z37E", ALC883_6ST_DIG), + SND_PCI_QUIRK(0x1043, 0x82fe, "Asus P5Q-EM HDMI", ALC1200_ASUS_P5Q), + SND_PCI_QUIRK(0x1043, 0x835f, "Asus Eee 1601", ALC888_ASUS_EEE1601), + SND_PCI_QUIRK(0x105b, 0x0ce8, "Foxconn P35AX-S", ALC883_6ST_DIG), +@@ -8521,8 +8513,6 @@ + SND_PCI_QUIRK(0x1558, 0, "Clevo laptop", ALC883_LAPTOP_EAPD), + SND_PCI_QUIRK(0x15d9, 0x8780, "Supermicro PDSBA", ALC883_3ST_6ch), + SND_PCI_QUIRK(0x161f, 0x2054, "Medion laptop", ALC883_MEDION), +- SND_PCI_QUIRK(0x1734, 0x1107, "FSC AMILO Xi2550", +- ALC883_FUJITSU_PI2515), + SND_PCI_QUIRK(0x1734, 0x1108, "Fujitsu AMILO Pi2515", ALC883_FUJITSU_PI2515), + SND_PCI_QUIRK(0x1734, 0x113d, "Fujitsu AMILO Xa3530", + ALC888_FUJITSU_XA3530), +@@ -10557,7 +10547,6 @@ + SND_PCI_QUIRK(0x103c, 0x1309, "HP xw4*00", ALC262_HP_BPC), + SND_PCI_QUIRK(0x103c, 0x130a, "HP xw6*00", ALC262_HP_BPC), + SND_PCI_QUIRK(0x103c, 0x130b, "HP xw8*00", ALC262_HP_BPC), +- SND_PCI_QUIRK(0x103c, 0x170b, "HP xw*", ALC262_HP_BPC), + SND_PCI_QUIRK(0x103c, 0x2800, "HP D7000", ALC262_HP_BPC_D7000_WL), + SND_PCI_QUIRK(0x103c, 0x2801, "HP D7000", ALC262_HP_BPC_D7000_WF), + SND_PCI_QUIRK(0x103c, 0x2802, "HP D7000", ALC262_HP_BPC_D7000_WL), +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/sound/pci/hda/patch_sigmatel.c linux-2.6.29-rc3.owrt/sound/pci/hda/patch_sigmatel.c +--- linux-2.6.29.owrt/sound/pci/hda/patch_sigmatel.c 2009-05-10 22:04:39.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/sound/pci/hda/patch_sigmatel.c 2009-05-10 23:48:34.000000000 +0200 +@@ -1207,7 +1207,7 @@ + "LFE Playback Volume", + "Side Playback Volume", + "Headphone Playback Volume", +- "Headphone2 Playback Volume", ++ "Headphone Playback Volume", + "Speaker Playback Volume", + "External Speaker Playback Volume", + "Speaker2 Playback Volume", +@@ -1221,7 +1221,7 @@ + "LFE Playback Switch", + "Side Playback Switch", + "Headphone Playback Switch", +- "Headphone2 Playback Switch", ++ "Headphone Playback Switch", + "Speaker Playback Switch", + "External Speaker Playback Switch", + "Speaker2 Playback Switch", +@@ -1799,13 +1799,11 @@ + SND_PCI_QUIRK(PCI_VENDOR_ID_HP, 0x30f2, + "HP dv5", STAC_HP_M4), + SND_PCI_QUIRK(PCI_VENDOR_ID_HP, 0x30f4, +- "HP dv7", STAC_HP_DV5), ++ "HP dv7", STAC_HP_M4), + SND_PCI_QUIRK(PCI_VENDOR_ID_HP, 0x30f7, + "HP dv4", STAC_HP_DV5), + SND_PCI_QUIRK(PCI_VENDOR_ID_HP, 0x30fc, + "HP dv7", STAC_HP_M4), +- SND_PCI_QUIRK(PCI_VENDOR_ID_HP, 0x3600, +- "HP dv5", STAC_HP_DV5), + SND_PCI_QUIRK(PCI_VENDOR_ID_HP, 0x3603, + "HP dv5", STAC_HP_DV5), + SND_PCI_QUIRK(PCI_VENDOR_ID_HP, 0x361a, +@@ -2442,14 +2440,6 @@ + stream_tag, format, substream); + } + +-static int stac92xx_dig_playback_pcm_cleanup(struct hda_pcm_stream *hinfo, +- struct hda_codec *codec, +- struct snd_pcm_substream *substream) +-{ +- struct sigmatel_spec *spec = codec->spec; +- return snd_hda_multi_out_dig_cleanup(codec, &spec->multiout); +-} +- + + /* + * Analog capture callbacks +@@ -2494,8 +2484,7 @@ + .ops = { + .open = stac92xx_dig_playback_pcm_open, + .close = stac92xx_dig_playback_pcm_close, +- .prepare = stac92xx_dig_playback_pcm_prepare, +- .cleanup = stac92xx_dig_playback_pcm_cleanup ++ .prepare = stac92xx_dig_playback_pcm_prepare + }, + }; + +@@ -2550,8 +2539,6 @@ + + info->name = "STAC92xx Analog"; + info->stream[SNDRV_PCM_STREAM_PLAYBACK] = stac92xx_pcm_analog_playback; +- info->stream[SNDRV_PCM_STREAM_PLAYBACK].nid = +- spec->multiout.dac_nids[0]; + info->stream[SNDRV_PCM_STREAM_CAPTURE] = stac92xx_pcm_analog_capture; + info->stream[SNDRV_PCM_STREAM_CAPTURE].nid = spec->adc_nids[0]; + info->stream[SNDRV_PCM_STREAM_CAPTURE].substreams = spec->num_adcs; +@@ -3516,7 +3503,6 @@ + if (! spec->autocfg.line_outs) + return 0; /* can't find valid pin config */ + +-#if 0 /* FIXME: temporarily disabled */ + /* If we have no real line-out pin and multiple hp-outs, HPs should + * be set up as multi-channel outputs. + */ +@@ -3536,7 +3522,6 @@ + spec->autocfg.line_out_type = AUTO_PIN_HP_OUT; + spec->autocfg.hp_outs = 0; + } +-#endif /* FIXME: temporarily disabled */ + if (spec->autocfg.mono_out_pin) { + int dir = get_wcaps(codec, spec->autocfg.mono_out_pin) & + (AC_WCAP_OUT_AMP | AC_WCAP_IN_AMP); +@@ -4991,7 +4976,7 @@ + case STAC_DELL_M4_3: + spec->num_dmics = 1; + spec->num_smuxes = 0; +- spec->num_dmuxes = 1; ++ spec->num_dmuxes = 0; + break; + default: + spec->num_dmics = STAC92HD71BXX_NUM_DMICS; +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/sound/pci/intel8x0.c linux-2.6.29-rc3.owrt/sound/pci/intel8x0.c +--- linux-2.6.29.owrt/sound/pci/intel8x0.c 2009-05-10 22:04:39.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/sound/pci/intel8x0.c 2009-05-10 23:48:34.000000000 +0200 +@@ -617,7 +617,7 @@ + int time = 100; + if (chip->buggy_semaphore) + return 0; /* just ignore ... */ +- while (--time && (igetdword(chip, ICHREG(ALI_CAS)) & ALI_CAS_SEM_BUSY)) ++ while (time-- && (igetdword(chip, ICHREG(ALI_CAS)) & ALI_CAS_SEM_BUSY)) + udelay(1); + if (! time && ! chip->in_ac97_init) + snd_printk(KERN_WARNING "ali_codec_semaphore timeout\n"); +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/sound/pci/mixart/mixart.c linux-2.6.29-rc3.owrt/sound/pci/mixart/mixart.c +--- linux-2.6.29.owrt/sound/pci/mixart/mixart.c 2009-05-10 22:04:39.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/sound/pci/mixart/mixart.c 2009-05-10 23:48:34.000000000 +0200 +@@ -607,7 +607,6 @@ + /* set the format to the board */ + err = mixart_set_format(stream, format); + if(err < 0) { +- mutex_unlock(&mgr->setup_mutex); + return err; + } + +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/sound/pci/oxygen/virtuoso.c linux-2.6.29-rc3.owrt/sound/pci/oxygen/virtuoso.c +--- linux-2.6.29.owrt/sound/pci/oxygen/virtuoso.c 2009-05-10 22:04:39.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/sound/pci/oxygen/virtuoso.c 2009-05-10 23:48:34.000000000 +0200 +@@ -26,7 +26,7 @@ + * SPI 0 -> 1st PCM1796 (front) + * SPI 1 -> 2nd PCM1796 (surround) + * SPI 2 -> 3rd PCM1796 (center/LFE) +- * SPI 4 -> 4th PCM1796 (back) ++ * SPI 4 -> 4th PCM1796 (back) and EEPROM self-destruct (do not use!) + * + * GPIO 2 -> M0 of CS5381 + * GPIO 3 -> M1 of CS5381 +@@ -207,6 +207,12 @@ + static inline void pcm1796_write_spi(struct oxygen *chip, unsigned int codec, + u8 reg, u8 value) + { ++ /* ++ * We don't want to do writes on SPI 4 because the EEPROM, which shares ++ * the same pin, might get confused and broken. We'd better take care ++ * that the driver works with the default register values ... ++ */ ++#if 0 + /* maps ALSA channel pair number to SPI output */ + static const u8 codec_map[4] = { + 0, 1, 2, 4 +@@ -217,6 +223,7 @@ + (codec_map[codec] << OXYGEN_SPI_CODEC_SHIFT) | + OXYGEN_SPI_CEN_LATCH_CLOCK_HI, + (reg << 8) | value); ++#endif + } + + static inline void pcm1796_write_i2c(struct oxygen *chip, unsigned int codec, +@@ -750,6 +757,9 @@ + + static int xonar_d2_control_filter(struct snd_kcontrol_new *template) + { ++ if (!strncmp(template->name, "Master Playback ", 16)) ++ /* disable volume/mute because they would require SPI writes */ ++ return 1; + if (!strncmp(template->name, "CD Capture ", 11)) + /* CD in is actually connected to the video in pin */ + template->private_value ^= AC97_CD ^ AC97_VIDEO; +@@ -840,9 +850,8 @@ + .dac_volume_min = 0x0f, + .dac_volume_max = 0xff, + .misc_flags = OXYGEN_MISC_MIDI, +- .function_flags = OXYGEN_FUNCTION_SPI | +- OXYGEN_FUNCTION_ENABLE_SPI_4_5, +- .dac_i2s_format = OXYGEN_I2S_FORMAT_LJUST, ++ .function_flags = OXYGEN_FUNCTION_SPI, ++ .dac_i2s_format = OXYGEN_I2S_FORMAT_I2S, + .adc_i2s_format = OXYGEN_I2S_FORMAT_LJUST, + }; + +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/sound/pci/pcxhr/pcxhr.h linux-2.6.29-rc3.owrt/sound/pci/pcxhr/pcxhr.h +--- linux-2.6.29.owrt/sound/pci/pcxhr/pcxhr.h 2009-05-10 22:04:39.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/sound/pci/pcxhr/pcxhr.h 2009-05-10 23:48:34.000000000 +0200 +@@ -97,12 +97,12 @@ + int capture_chips; + int fw_file_set; + int firmware_num; +- unsigned int is_hr_stereo:1; +- unsigned int board_has_aes1:1; /* if 1 board has AES1 plug and SRC */ +- unsigned int board_has_analog:1; /* if 0 the board is digital only */ +- unsigned int board_has_mic:1; /* if 1 the board has microphone input */ +- unsigned int board_aes_in_192k:1;/* if 1 the aes input plugs do support 192kHz */ +- unsigned int mono_capture:1; /* if 1 the board does mono capture */ ++ int is_hr_stereo:1; ++ int board_has_aes1:1; /* if 1 board has AES1 plug and SRC */ ++ int board_has_analog:1; /* if 0 the board is digital only */ ++ int board_has_mic:1; /* if 1 the board has microphone input */ ++ int board_aes_in_192k:1;/* if 1 the aes input plugs do support 192kHz */ ++ int mono_capture:1; /* if 1 the board does mono capture */ + + struct snd_dma_buffer hostport; + +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/sound/soc/atmel/atmel_ssc_dai.c linux-2.6.29-rc3.owrt/sound/soc/atmel/atmel_ssc_dai.c +--- linux-2.6.29.owrt/sound/soc/atmel/atmel_ssc_dai.c 2009-05-10 22:04:39.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/sound/soc/atmel/atmel_ssc_dai.c 2009-05-10 23:48:34.000000000 +0200 +@@ -10,7 +10,7 @@ + * Based on at91-ssc.c by + * Frank Mandarino <fmandarino@endrelia.com> + * Based on pxa2xx Platform drivers by +- * Liam Girdwood <lrg@slimlogic.co.uk> ++ * Liam Girdwood <liam.girdwood@wolfsonmicro.com> + * + * 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 +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/sound/soc/atmel/atmel_ssc_dai.h linux-2.6.29-rc3.owrt/sound/soc/atmel/atmel_ssc_dai.h +--- linux-2.6.29.owrt/sound/soc/atmel/atmel_ssc_dai.h 2009-05-10 22:04:39.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/sound/soc/atmel/atmel_ssc_dai.h 2009-05-10 23:48:34.000000000 +0200 +@@ -10,7 +10,7 @@ + * Based on at91-ssc.c by + * Frank Mandarino <fmandarino@endrelia.com> + * Based on pxa2xx Platform drivers by +- * Liam Girdwood <lrg@slimlogic.co.uk> ++ * Liam Girdwood <liam.girdwood@wolfsonmicro.com> + * + * 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 +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/sound/soc/codecs/tlv320aic3x.c linux-2.6.29-rc3.owrt/sound/soc/codecs/tlv320aic3x.c +--- linux-2.6.29.owrt/sound/soc/codecs/tlv320aic3x.c 2009-05-10 22:04:39.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/sound/soc/codecs/tlv320aic3x.c 2009-05-10 23:48:34.000000000 +0200 +@@ -165,13 +165,10 @@ + struct snd_ctl_elem_value *ucontrol) + { + struct snd_soc_dapm_widget *widget = snd_kcontrol_chip(kcontrol); +- struct soc_mixer_control *mc = +- (struct soc_mixer_control *)kcontrol->private_value; +- unsigned int reg = mc->reg; +- unsigned int shift = mc->shift; +- int max = mc->max; +- unsigned int mask = (1 << fls(max)) - 1; +- unsigned int invert = mc->invert; ++ int reg = kcontrol->private_value & 0xff; ++ int shift = (kcontrol->private_value >> 8) & 0x0f; ++ int mask = (kcontrol->private_value >> 16) & 0xff; ++ int invert = (kcontrol->private_value >> 24) & 0x01; + unsigned short val, val_mask; + int ret; + struct snd_soc_dapm_path *path; +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/sound/soc/codecs/wm8350.c linux-2.6.29-rc3.owrt/sound/soc/codecs/wm8350.c +--- linux-2.6.29.owrt/sound/soc/codecs/wm8350.c 2009-05-10 22:04:39.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/sound/soc/codecs/wm8350.c 2009-05-10 23:48:34.000000000 +0200 +@@ -3,7 +3,7 @@ + * + * Copyright (C) 2007, 2008 Wolfson Microelectronics PLC. + * +- * Author: Liam Girdwood <lrg@slimlogic.co.uk> ++ * Author: Liam Girdwood <lg@opensource.wolfsonmicro.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 +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/sound/soc/codecs/wm8753.c linux-2.6.29-rc3.owrt/sound/soc/codecs/wm8753.c +--- linux-2.6.29.owrt/sound/soc/codecs/wm8753.c 2009-05-10 22:04:39.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/sound/soc/codecs/wm8753.c 2009-05-10 23:48:34.000000000 +0200 +@@ -1451,14 +1451,7 @@ + }, + }; + +-struct snd_soc_dai wm8753_dai[] = { +- { +- .name = "WM8753 DAI 0", +- }, +- { +- .name = "WM8753 DAI 1", +- }, +-}; ++struct snd_soc_dai wm8753_dai[2]; + EXPORT_SYMBOL_GPL(wm8753_dai); + + static void wm8753_set_dai_mode(struct snd_soc_codec *codec, unsigned int mode) +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/sound/soc/codecs/wm8990.c linux-2.6.29-rc3.owrt/sound/soc/codecs/wm8990.c +--- linux-2.6.29.owrt/sound/soc/codecs/wm8990.c 2009-05-10 22:04:39.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/sound/soc/codecs/wm8990.c 2009-05-10 23:48:34.000000000 +0200 +@@ -2,7 +2,8 @@ + * wm8990.c -- WM8990 ALSA Soc Audio driver + * + * Copyright 2008 Wolfson Microelectronics PLC. +- * Author: Liam Girdwood <lrg@slimlogic.co.uk> ++ * Author: Liam Girdwood ++ * lg@opensource.wolfsonmicro.com or linux@wolfsonmicro.com + * + * 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 +@@ -176,9 +177,7 @@ + struct snd_ctl_elem_value *ucontrol) + { + struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol); +- struct soc_mixer_control *mc = +- (struct soc_mixer_control *)kcontrol->private_value; +- int reg = mc->reg; ++ int reg = kcontrol->private_value & 0xff; + int ret; + u16 val; + +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/sound/soc/omap/omap-mcbsp.c linux-2.6.29-rc3.owrt/sound/soc/omap/omap-mcbsp.c +--- linux-2.6.29.owrt/sound/soc/omap/omap-mcbsp.c 2009-05-10 22:04:39.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/sound/soc/omap/omap-mcbsp.c 2009-05-10 23:48:34.000000000 +0200 +@@ -302,10 +302,6 @@ + regs->spcr1 |= RINTM(3); + regs->rcr2 |= RFIG; + regs->xcr2 |= XFIG; +- if (cpu_is_omap2430() || cpu_is_omap34xx()) { +- regs->xccr = DXENDLY(1) | XDMAEN; +- regs->rccr = RFULL_CYCLE | RDMAEN; +- } + + switch (fmt & SND_SOC_DAIFMT_FORMAT_MASK) { + case SND_SOC_DAIFMT_I2S: +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/sound/soc/omap/omap-pcm.c linux-2.6.29-rc3.owrt/sound/soc/omap/omap-pcm.c +--- linux-2.6.29.owrt/sound/soc/omap/omap-pcm.c 2009-05-10 22:04:39.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/sound/soc/omap/omap-pcm.c 2009-05-10 23:48:34.000000000 +0200 +@@ -175,10 +175,9 @@ + { + struct snd_pcm_runtime *runtime = substream->runtime; + struct omap_runtime_data *prtd = runtime->private_data; +- unsigned long flags; + int ret = 0; + +- spin_lock_irqsave(&prtd->lock, flags); ++ spin_lock_irq(&prtd->lock); + switch (cmd) { + case SNDRV_PCM_TRIGGER_START: + case SNDRV_PCM_TRIGGER_RESUME: +@@ -196,7 +195,7 @@ + default: + ret = -EINVAL; + } +- spin_unlock_irqrestore(&prtd->lock, flags); ++ spin_unlock_irq(&prtd->lock); + + return ret; + } +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/sound/soc/omap/sdp3430.c linux-2.6.29-rc3.owrt/sound/soc/omap/sdp3430.c +--- linux-2.6.29.owrt/sound/soc/omap/sdp3430.c 2009-05-10 22:04:39.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/sound/soc/omap/sdp3430.c 2009-05-10 23:48:34.000000000 +0200 +@@ -91,7 +91,7 @@ + }; + + /* Audio machine driver */ +-static struct snd_soc_card snd_soc_sdp3430 = { ++static struct snd_soc_machine snd_soc_machine_sdp3430 = { + .name = "SDP3430", + .platform = &omap_soc_platform, + .dai_link = &sdp3430_dai, +@@ -100,7 +100,7 @@ + + /* Audio subsystem */ + static struct snd_soc_device sdp3430_snd_devdata = { +- .card = &snd_soc_sdp3430, ++ .machine = &snd_soc_machine_sdp3430, + .codec_dev = &soc_codec_dev_twl4030, + }; + +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/sound/soc/soc-core.c linux-2.6.29-rc3.owrt/sound/soc/soc-core.c +--- linux-2.6.29.owrt/sound/soc/soc-core.c 2009-05-10 22:04:39.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/sound/soc/soc-core.c 2009-05-10 23:48:34.000000000 +0200 +@@ -1385,10 +1385,7 @@ + + mutex_lock(&codec->mutex); + #ifdef CONFIG_SND_SOC_AC97_BUS +- /* Only instantiate AC97 if not already done by the adaptor +- * for the generic AC97 subsystem. +- */ +- if (ac97 && strcmp(codec->name, "AC97") != 0) { ++ if (ac97) { + ret = soc_ac97_dev_register(codec); + if (ret < 0) { + printk(KERN_ERR "asoc: AC97 device register failed\n"); +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/sound/usb/usbaudio.c linux-2.6.29-rc3.owrt/sound/usb/usbaudio.c +--- linux-2.6.29.owrt/sound/usb/usbaudio.c 2009-05-10 22:04:39.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/sound/usb/usbaudio.c 2009-05-10 23:48:34.000000000 +0200 +@@ -2524,6 +2524,7 @@ + * build the rate table and bitmap flags + */ + int r, idx; ++ unsigned int nonzero_rates = 0; + + fp->rate_table = kmalloc(sizeof(int) * nr_rates, GFP_KERNEL); + if (fp->rate_table == NULL) { +@@ -2531,27 +2532,24 @@ + return -1; + } + +- fp->nr_rates = 0; +- fp->rate_min = fp->rate_max = 0; ++ fp->nr_rates = nr_rates; ++ fp->rate_min = fp->rate_max = combine_triple(&fmt[8]); + for (r = 0, idx = offset + 1; r < nr_rates; r++, idx += 3) { + unsigned int rate = combine_triple(&fmt[idx]); +- if (!rate) +- continue; + /* C-Media CM6501 mislabels its 96 kHz altsetting */ + if (rate == 48000 && nr_rates == 1 && +- (chip->usb_id == USB_ID(0x0d8c, 0x0201) || +- chip->usb_id == USB_ID(0x0d8c, 0x0102)) && ++ chip->usb_id == USB_ID(0x0d8c, 0x0201) && + fp->altsetting == 5 && fp->maxpacksize == 392) + rate = 96000; +- fp->rate_table[fp->nr_rates] = rate; +- if (!fp->rate_min || rate < fp->rate_min) ++ fp->rate_table[r] = rate; ++ nonzero_rates |= rate; ++ if (rate < fp->rate_min) + fp->rate_min = rate; +- if (!fp->rate_max || rate > fp->rate_max) ++ else if (rate > fp->rate_max) + fp->rate_max = rate; + fp->rates |= snd_pcm_rate_to_rate_bit(rate); +- fp->nr_rates++; + } +- if (!fp->nr_rates) { ++ if (!nonzero_rates) { + hwc_debug("All rates were zero. Skipping format!\n"); + return -1; + } +@@ -2968,7 +2966,6 @@ + return -EINVAL; + } + alts = &iface->altsetting[fp->altset_idx]; +- fp->maxpacksize = le16_to_cpu(get_endpoint(alts, 0)->wMaxPacketSize); + usb_set_interface(chip->dev, fp->iface, 0); + init_usb_pitch(chip->dev, fp->iface, alts, fp); + init_usb_sample_rate(chip->dev, fp->iface, alts, fp, fp->rate_max); +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/sound/usb/usbmidi.c linux-2.6.29-rc3.owrt/sound/usb/usbmidi.c +--- linux-2.6.29.owrt/sound/usb/usbmidi.c 2009-05-10 22:04:39.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/sound/usb/usbmidi.c 2009-05-10 23:48:34.000000000 +0200 +@@ -1625,7 +1625,6 @@ + } + + ep_info.out_ep = get_endpoint(hostif, 2)->bEndpointAddress & USB_ENDPOINT_NUMBER_MASK; +- ep_info.out_interval = 0; + ep_info.out_cables = endpoint->out_cables & 0x5555; + err = snd_usbmidi_out_endpoint_create(umidi, &ep_info, &umidi->endpoints[0]); + if (err < 0) +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/virt/kvm/iommu.c linux-2.6.29-rc3.owrt/virt/kvm/iommu.c +--- linux-2.6.29.owrt/virt/kvm/iommu.c 2009-05-10 22:04:39.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/virt/kvm/iommu.c 2009-05-10 23:48:34.000000000 +0200 +@@ -73,13 +73,14 @@ + { + int i, r = 0; + ++ down_read(&kvm->slots_lock); + for (i = 0; i < kvm->nmemslots; i++) { + r = kvm_iommu_map_pages(kvm, kvm->memslots[i].base_gfn, + kvm->memslots[i].npages); + if (r) + break; + } +- ++ up_read(&kvm->slots_lock); + return r; + } + +@@ -189,11 +190,12 @@ + static int kvm_iommu_unmap_memslots(struct kvm *kvm) + { + int i; +- ++ down_read(&kvm->slots_lock); + for (i = 0; i < kvm->nmemslots; i++) { + kvm_iommu_put_pages(kvm, kvm->memslots[i].base_gfn, + kvm->memslots[i].npages); + } ++ up_read(&kvm->slots_lock); + + return 0; + } +diff -ruN --exclude='*.rej' --exclude='*.orig' linux-2.6.29.owrt/virt/kvm/kvm_main.c linux-2.6.29-rc3.owrt/virt/kvm/kvm_main.c +--- linux-2.6.29.owrt/virt/kvm/kvm_main.c 2009-05-10 22:04:39.000000000 +0200 ++++ linux-2.6.29-rc3.owrt/virt/kvm/kvm_main.c 2009-05-10 23:48:34.000000000 +0200 +@@ -173,6 +173,7 @@ + assigned_dev->host_irq_disabled = false; + } + mutex_unlock(&assigned_dev->kvm->lock); ++ kvm_put_kvm(assigned_dev->kvm); + } + + static irqreturn_t kvm_assigned_dev_intr(int irq, void *dev_id) +@@ -180,6 +181,8 @@ + struct kvm_assigned_dev_kernel *assigned_dev = + (struct kvm_assigned_dev_kernel *) dev_id; + ++ kvm_get_kvm(assigned_dev->kvm); ++ + schedule_work(&assigned_dev->interrupt_work); + + disable_irq_nosync(irq); +@@ -210,7 +213,6 @@ + } + } + +-/* The function implicit hold kvm->lock mutex due to cancel_work_sync() */ + static void kvm_free_assigned_irq(struct kvm *kvm, + struct kvm_assigned_dev_kernel *assigned_dev) + { +@@ -226,24 +228,11 @@ + if (!assigned_dev->irq_requested_type) + return; + +- /* +- * In kvm_free_device_irq, cancel_work_sync return true if: +- * 1. work is scheduled, and then cancelled. +- * 2. work callback is executed. +- * +- * The first one ensured that the irq is disabled and no more events +- * would happen. But for the second one, the irq may be enabled (e.g. +- * for MSI). So we disable irq here to prevent further events. +- * +- * Notice this maybe result in nested disable if the interrupt type is +- * INTx, but it's OK for we are going to free it. +- * +- * If this function is a part of VM destroy, please ensure that till +- * now, the kvm state is still legal for probably we also have to wait +- * interrupt_work done. +- */ +- disable_irq_nosync(assigned_dev->host_irq); +- cancel_work_sync(&assigned_dev->interrupt_work); ++ if (cancel_work_sync(&assigned_dev->interrupt_work)) ++ /* We had pending work. That means we will have to take ++ * care of kvm_put_kvm. ++ */ ++ kvm_put_kvm(kvm); + + free_irq(assigned_dev->host_irq, (void *)assigned_dev); + +@@ -296,8 +285,8 @@ + + if (irqchip_in_kernel(kvm)) { + if (!msi2intx && +- (adev->irq_requested_type & KVM_ASSIGNED_DEV_HOST_MSI)) { +- free_irq(adev->host_irq, (void *)adev); ++ adev->irq_requested_type & KVM_ASSIGNED_DEV_HOST_MSI) { ++ free_irq(adev->host_irq, (void *)kvm); + pci_disable_msi(adev->dev); + } + +@@ -466,7 +455,6 @@ + struct kvm_assigned_dev_kernel *match; + struct pci_dev *dev; + +- down_read(&kvm->slots_lock); + mutex_lock(&kvm->lock); + + match = kvm_find_assigned_dev(&kvm->arch.assigned_dev_head, +@@ -528,7 +516,6 @@ + + out: + mutex_unlock(&kvm->lock); +- up_read(&kvm->slots_lock); + return r; + out_list_del: + list_del(&match->list); +@@ -540,7 +527,6 @@ + out_free: + kfree(match); + mutex_unlock(&kvm->lock); +- up_read(&kvm->slots_lock); + return r; + } + #endif +@@ -803,19 +789,11 @@ + return young; + } + +-static void kvm_mmu_notifier_release(struct mmu_notifier *mn, +- struct mm_struct *mm) +-{ +- struct kvm *kvm = mmu_notifier_to_kvm(mn); +- kvm_arch_flush_shadow(kvm); +-} +- + static const struct mmu_notifier_ops kvm_mmu_notifier_ops = { + .invalidate_page = kvm_mmu_notifier_invalidate_page, + .invalidate_range_start = kvm_mmu_notifier_invalidate_range_start, + .invalidate_range_end = kvm_mmu_notifier_invalidate_range_end, + .clear_flush_young = kvm_mmu_notifier_clear_flush_young, +- .release = kvm_mmu_notifier_release, + }; + #endif /* CONFIG_MMU_NOTIFIER && KVM_ARCH_WANT_MMU_NOTIFIER */ + +@@ -905,7 +883,6 @@ + { + struct mm_struct *mm = kvm->mm; + +- kvm_arch_sync_events(kvm); + spin_lock(&kvm_lock); + list_del(&kvm->vm_list); + spin_unlock(&kvm_lock); diff --git a/target/linux/s3c24xx/patches-2.6.29/001-merge-openmoko.patch b/target/linux/s3c24xx/patches-2.6.29/001-merge-openmoko.patch new file mode 100644 index 0000000000..59ce604ea4 --- /dev/null +++ b/target/linux/s3c24xx/patches-2.6.29/001-merge-openmoko.patch @@ -0,0 +1,96426 @@ +diff -ruN --exclude='*.orig' --exclude='*.rej' linux-2.6.29-rc3.owrt/arch/arm/include/asm/fiq.h linux-2.6.29-rc3.owrt.om/arch/arm/include/asm/fiq.h +--- linux-2.6.29-rc3.owrt/arch/arm/include/asm/fiq.h 2009-05-10 22:05:03.000000000 +0200 ++++ linux-2.6.29-rc3.owrt.om/arch/arm/include/asm/fiq.h 2009-05-10 22:27:59.000000000 +0200 +@@ -29,8 +29,9 @@ + extern int claim_fiq(struct fiq_handler *f); + extern void release_fiq(struct fiq_handler *f); + extern void set_fiq_handler(void *start, unsigned int length); +-extern void set_fiq_regs(struct pt_regs *regs); +-extern void get_fiq_regs(struct pt_regs *regs); ++extern void set_fiq_c_handler(void (*handler)(void)); ++extern void __attribute__((naked)) set_fiq_regs(struct pt_regs *regs); ++extern void __attribute__((naked)) get_fiq_regs(struct pt_regs *regs); + extern void enable_fiq(int fiq); + extern void disable_fiq(int fiq); + +diff -ruN --exclude='*.orig' --exclude='*.rej' linux-2.6.29-rc3.owrt/arch/arm/include/asm/hardware/tzic-sp890.h linux-2.6.29-rc3.owrt.om/arch/arm/include/asm/hardware/tzic-sp890.h +--- linux-2.6.29-rc3.owrt/arch/arm/include/asm/hardware/tzic-sp890.h 1970-01-01 01:00:00.000000000 +0100 ++++ linux-2.6.29-rc3.owrt.om/arch/arm/include/asm/hardware/tzic-sp890.h 2009-05-10 22:27:59.000000000 +0200 +@@ -0,0 +1,22 @@ ++#ifndef __SP890_TZIC_H__ ++#define __SP890_TZIC_H__ ++ ++#define SP890_TZIC_UNLOCK_MAGIC (0x0ACCE550) ++ ++#define SP890_TZIC_FIQSTATUS 0 ++#define SP890_TZIC_RAWINTR 4 ++#define SP890_TZIC_INTSELECT 8 ++#define SP890_TZIC_FIQENABLE 0xc ++#define SP890_TZIC_FIQENCLEAR 0x10 ++#define SP890_TZIC_FIQBYPASS 0x14 ++#define SP890_TZIC_PROTECTION 0x18 ++#define SP890_TZIC_LOCK 0x1c ++#define SP890_TZIC_LOCKSTATUS 0x20 ++#define SP890_TZIC_ITCR 0x300 ++#define SP890_TZIC_ITIP1 0x304 ++#define SP890_TZIC_ITIP2 0x308 ++#define SP890_TZIC_ITOP1 0x30c ++#define SP890_TZIC_ITOP2 0x310 ++#define SP890_TZIC_PERIPHIDO 0xfe0 ++ ++#endif +diff -ruN --exclude='*.orig' --exclude='*.rej' linux-2.6.29-rc3.owrt/arch/arm/include/asm/irqflags.h linux-2.6.29-rc3.owrt.om/arch/arm/include/asm/irqflags.h +--- linux-2.6.29-rc3.owrt/arch/arm/include/asm/irqflags.h 2009-05-10 22:05:03.000000000 +0200 ++++ linux-2.6.29-rc3.owrt.om/arch/arm/include/asm/irqflags.h 2009-05-10 22:27:59.000000000 +0200 +@@ -5,6 +5,16 @@ + + #include <asm/ptrace.h> + ++#ifdef CONFIG_FIND_IRQ_BLOCKERS ++void iblock_start(void); ++void iblock_end(void); ++void iblock_end_maybe(unsigned long flags); ++#else ++#define iblock_start() ++#define iblock_end() ++#define iblock_end_maybe(x) ++#endif ++ + /* + * CPU interrupt mask handling. + */ +@@ -31,6 +41,7 @@ + #define raw_local_irq_save(x) \ + ({ \ + unsigned long temp; \ ++ iblock_start(); \ + (void) (&temp == &x); \ + __asm__ __volatile__( \ + "mrs %0, cpsr @ local_irq_save\n" \ +@@ -47,6 +58,7 @@ + #define raw_local_irq_enable() \ + ({ \ + unsigned long temp; \ ++ iblock_end(); \ + __asm__ __volatile__( \ + "mrs %0, cpsr @ local_irq_enable\n" \ + " bic %0, %0, #128\n" \ +@@ -62,6 +74,7 @@ + #define raw_local_irq_disable() \ + ({ \ + unsigned long temp; \ ++ iblock_start(); \ + __asm__ __volatile__( \ + "mrs %0, cpsr @ local_irq_disable\n" \ + " orr %0, %0, #128\n" \ +@@ -117,11 +130,12 @@ + * restore saved IRQ & FIQ state + */ + #define raw_local_irq_restore(x) \ ++ ({ iblock_end_maybe(x); \ + __asm__ __volatile__( \ + "msr cpsr_c, %0 @ local_irq_restore\n" \ + : \ + : "r" (x) \ +- : "memory", "cc") ++ : "memory", "cc"); }) + + #define raw_irqs_disabled_flags(flags) \ + ({ \ +diff -ruN --exclude='*.orig' --exclude='*.rej' linux-2.6.29-rc3.owrt/arch/arm/include/asm/kexec.h linux-2.6.29-rc3.owrt.om/arch/arm/include/asm/kexec.h +--- linux-2.6.29-rc3.owrt/arch/arm/include/asm/kexec.h 2009-05-10 22:05:03.000000000 +0200 ++++ linux-2.6.29-rc3.owrt.om/arch/arm/include/asm/kexec.h 2009-05-10 22:27:59.000000000 +0200 +@@ -1,8 +1,6 @@ + #ifndef _ARM_KEXEC_H + #define _ARM_KEXEC_H + +-#ifdef CONFIG_KEXEC +- + /* Maximum physical address we can use pages from */ + #define KEXEC_SOURCE_MEMORY_LIMIT (-1UL) + /* Maximum address we can reach in physical address mode */ +@@ -14,6 +12,10 @@ + + #define KEXEC_ARCH KEXEC_ARCH_ARM + ++#define KEXEC_BOOT_PARAMS_SIZE 1536 ++ ++#ifdef CONFIG_KEXEC ++ + #define KEXEC_ARM_ATAGS_OFFSET 0x1000 + #define KEXEC_ARM_ZIMAGE_OFFSET 0x8000 + +@@ -29,3 +31,4 @@ + #endif /* CONFIG_KEXEC */ + + #endif /* _ARM_KEXEC_H */ ++ +diff -ruN --exclude='*.orig' --exclude='*.rej' linux-2.6.29-rc3.owrt/arch/arm/Kconfig linux-2.6.29-rc3.owrt.om/arch/arm/Kconfig +--- linux-2.6.29-rc3.owrt/arch/arm/Kconfig 2009-05-10 22:05:03.000000000 +0200 ++++ linux-2.6.29-rc3.owrt.om/arch/arm/Kconfig 2009-05-10 22:27:59.000000000 +0200 +@@ -1086,7 +1086,8 @@ + + menu "CPU Power Management" + +-if (ARCH_SA1100 || ARCH_INTEGRATOR || ARCH_OMAP || ARCH_IMX || ARCH_PXA) ++if (ARCH_SA1100 || ARCH_INTEGRATOR || ARCH_OMAP || ARCH_IMX || ARCH_PXA || \ ++ ARCH_S3C64XX) + + source "drivers/cpufreq/Kconfig" + +@@ -1126,6 +1127,10 @@ + default y + select CPU_FREQ_DEFAULT_GOV_USERSPACE + ++config CPU_FREQ_S3C64XX ++ bool "CPUfreq support for S3C64xx CPUs" ++ depends on CPU_FREQ && CPU_S3C6410 ++ + endif + + source "drivers/cpuidle/Kconfig" +@@ -1305,6 +1310,8 @@ + + source "drivers/uwb/Kconfig" + ++source "drivers/ar6000/Kconfig" ++ + source "drivers/mmc/Kconfig" + + source "drivers/memstick/Kconfig" +diff -ruN --exclude='*.orig' --exclude='*.rej' linux-2.6.29-rc3.owrt/arch/arm/kernel/fiq.c linux-2.6.29-rc3.owrt.om/arch/arm/kernel/fiq.c +--- linux-2.6.29-rc3.owrt/arch/arm/kernel/fiq.c 2009-05-10 22:08:41.000000000 +0200 ++++ linux-2.6.29-rc3.owrt.om/arch/arm/kernel/fiq.c 2009-05-10 22:27:59.000000000 +0200 +@@ -8,6 +8,8 @@ + * + * FIQ support re-written by Russell King to be more generic + * ++ * FIQ handler in C supoprt written by Andy Green <andy@openmoko.com> ++ * + * We now properly support a method by which the FIQ handlers can + * be stacked onto the vector. We still do not support sharing + * the FIQ vector itself. +@@ -124,6 +126,83 @@ + : "r" (®s->ARM_r8), "I" (PSR_I_BIT | PSR_F_BIT | FIQ_MODE)); + } + ++/* -------- FIQ handler in C --------- ++ * ++ * Major Caveats for using this ++ * --------------------------- ++ * * ++ * * 1) it CANNOT touch any vmalloc()'d memory, only memory ++ * that was kmalloc()'d. Static allocations in the monolithic kernel ++ * are kmalloc()'d so they are okay. You can touch memory-mapped IO, but ++ * the pointer for it has to have been stored in kmalloc'd memory. The ++ * reason for this is simple: every now and then Linux turns off interrupts ++ * and reorders the paging tables. If a FIQ happens during this time, the ++ * virtual memory space can be partly or entirely disordered or missing. ++ * ++ * 2) Because vmalloc() is used when a module is inserted, THIS FIQ ++ * ISR HAS TO BE IN THE MONOLITHIC KERNEL, not a module. But the way ++ * it is set up, you can all to enable and disable it from your module ++ * and intercommunicate with it through struct fiq_ipc ++ * fiq_ipc which you can define in ++ * asm/archfiq_ipc_type.h. The reason is the same as above, a ++ * FIQ could happen while even the ISR is not present in virtual memory ++ * space due to pagetables being changed at the time. ++ * ++ * 3) You can't call any Linux API code except simple macros ++ * - understand that FIQ can come in at any time, no matter what ++ * state of undress the kernel may privately be in, thinking it ++ * locked the door by turning off interrupts... FIQ is an ++ * unstoppable monster force (which is its value) ++ * - they are not vmalloc()'d memory safe ++ * - they might do crazy stuff like sleep: FIQ pisses fire and ++ * is not interested in 'sleep' that the weak seem to need ++ * - calling APIs from FIQ can re-enter un-renterable things ++ * - summary: you cannot interoperate with linux APIs directly in the FIQ ISR ++ * ++ * If you follow these rules, it is fantastic, an extremely powerful, solid, ++ * genuine hard realtime feature. ++ */ ++ ++static void (*current_fiq_c_isr)(void); ++#define FIQ_C_ISR_STACK_SIZE 256 ++ ++static void __attribute__((naked)) __jump_to_isr(void) ++{ ++ asm __volatile__ ("mov pc, r8"); ++} ++ ++ ++static void __attribute__((naked)) __actual_isr(void) ++{ ++ asm __volatile__ ( ++ "stmdb sp!, {r0-r12, lr};" ++ "mov fp, sp;" ++ ); ++ ++ current_fiq_c_isr(); ++ ++ asm __volatile__ ( ++ "ldmia sp!, {r0-r12, lr};" ++ "subs pc, lr, #4;" ++ ); ++} ++ ++void set_fiq_c_handler(void (*isr)(void)) ++{ ++ struct pt_regs regs; ++ ++ memset(®s, 0, sizeof(regs)); ++ regs.ARM_r8 = (unsigned long) __actual_isr; ++ regs.ARM_sp = 0xffff001c + FIQ_C_ISR_STACK_SIZE; ++ ++ set_fiq_handler(__jump_to_isr, 4); ++ ++ current_fiq_c_isr = isr; ++ ++ set_fiq_regs(®s); ++} ++/* -------- FIQ handler in C ---------*/ ++ + int claim_fiq(struct fiq_handler *f) + { + int ret = 0; +diff -ruN --exclude='*.orig' --exclude='*.rej' linux-2.6.29-rc3.owrt/arch/arm/kernel/iblock.c linux-2.6.29-rc3.owrt.om/arch/arm/kernel/iblock.c +--- linux-2.6.29-rc3.owrt/arch/arm/kernel/iblock.c 1970-01-01 01:00:00.000000000 +0100 ++++ linux-2.6.29-rc3.owrt.om/arch/arm/kernel/iblock.c 2009-05-10 22:27:59.000000000 +0200 +@@ -0,0 +1,158 @@ ++/* ++ * ++ * /sys/kernel/iblock/ ++ * All times are in microseconds (us). ++ * ++ * - limit ++ * Interrupt blocking time reporting limit, in microseconds. ++ * 0 disables reporting. Auto-resets to zero after reporting. ++ * ++ * - max ++ * Maximum blocking time recorded. Reset to zero by writing anything. ++ * ++ * - test ++ * Force a delay with interrupts disabled. ++ * ++ */ ++ ++ ++#include <linux/kernel.h> ++#include <linux/sysfs.h> ++#include <linux/kobject.h> ++#include <linux/device.h> ++#include <linux/init.h> ++#include <linux/delay.h> ++#include <asm/irqflags.h> ++ ++ ++unsigned long s3c2410_gettimeoffset(void); ++ ++ ++static unsigned long iblock_t0; ++int iblock_limit; ++static int iblock_max; ++ ++ ++void iblock_start(void) ++{ ++ unsigned long flags; ++ ++ raw_local_save_flags(flags); ++ if (raw_irqs_disabled_flags(flags)) ++ return; ++ iblock_t0 = s3c2410_gettimeoffset(); ++} ++EXPORT_SYMBOL_GPL(iblock_start); ++ ++void iblock_end(void) ++{ ++ unsigned long flags; ++ unsigned long t, us; ++ ++ raw_local_save_flags(flags); ++ if (!raw_irqs_disabled_flags(flags)) ++ return; ++ if (!iblock_t0) ++ return; ++ t = s3c2410_gettimeoffset(); ++ us = t-iblock_t0; ++ if (us > 40000000) ++ return; ++ if (us > iblock_max) ++ iblock_max = us; ++ if (!iblock_limit) ++ return; ++ if (us < iblock_limit) ++ return; ++// iblock_limit = 0; ++ printk(KERN_ERR "interrupts were disabled for %lu us !\n", us); ++// WARN_ON(1); ++} ++EXPORT_SYMBOL_GPL(iblock_end); ++ ++void iblock_end_maybe(unsigned long flags) ++{ ++ if (raw_irqs_disabled_flags(flags)) ++ return; ++ iblock_end(); ++} ++EXPORT_SYMBOL_GPL(iblock_end_maybe); ++ ++static ssize_t limit_read(struct device *dev, struct device_attribute *attr, ++ char *buf) ++{ ++ return sprintf(buf, "%u us\n", iblock_limit); ++} ++ ++ ++static ssize_t limit_write(struct device *dev, struct device_attribute *attr, ++ const char *buf, size_t count) ++{ ++ unsigned long tmp; ++ char *end; ++ ++ tmp = simple_strtoul(buf, &end, 0); ++ if (end == buf) ++ return -EINVAL; ++ iblock_limit = tmp; ++ return count; ++} ++ ++ ++static ssize_t max_read(struct device *dev, struct device_attribute *attr, ++ char *buf) ++{ ++ return sprintf(buf, "%u us\n", iblock_max); ++} ++ ++ ++static ssize_t max_write(struct device *dev, struct device_attribute *attr, ++ const char *buf, size_t count) ++{ ++ iblock_max = 0; ++ return count; ++} ++ ++ ++static ssize_t test_write(struct device *dev, ++ struct device_attribute *attr, const char *buf, size_t count) ++{ ++ unsigned long tmp, flags; ++ char *end; ++ ++ tmp = simple_strtoul(buf, &end, 0); ++ if (end == buf) ++ return -EINVAL; ++ local_irq_save(flags); ++ udelay(tmp); ++ local_irq_restore(flags); ++ return count; ++} ++ ++ ++static DEVICE_ATTR(limit, 0644, limit_read, limit_write); ++static DEVICE_ATTR(max, 0644, max_read, max_write); ++static DEVICE_ATTR(test, 0200, NULL, test_write); ++ ++ ++static struct attribute *sysfs_entries[] = { ++ &dev_attr_limit.attr, ++ &dev_attr_max.attr, ++ &dev_attr_test.attr, ++ NULL ++}; ++ ++ ++static struct attribute_group attr_group = { ++ .name = "iblock", ++ .attrs = sysfs_entries, ++}; ++ ++ ++static int __devinit iblock_init(void) ++{ ++ return sysfs_create_group(kernel_kobj, &attr_group); ++} ++ ++ ++module_init(iblock_init); +diff -ruN --exclude='*.orig' --exclude='*.rej' linux-2.6.29-rc3.owrt/arch/arm/kernel/irq.c linux-2.6.29-rc3.owrt.om/arch/arm/kernel/irq.c +--- linux-2.6.29-rc3.owrt/arch/arm/kernel/irq.c 2009-05-10 22:08:41.000000000 +0200 ++++ linux-2.6.29-rc3.owrt.om/arch/arm/kernel/irq.c 2009-05-10 22:27:59.000000000 +0200 +@@ -104,6 +104,11 @@ + .lock = SPIN_LOCK_UNLOCKED + }; + ++#ifdef CONFIG_FIND_IRQ_BLOCKERS ++extern int iblock_limit; ++unsigned long s3c2410_gettimeoffset(void); ++#endif ++ + /* + * do_IRQ handles all hardware IRQ's. Decoded IRQs should not + * come via this function. Instead, they should provide their +@@ -112,9 +117,15 @@ + asmlinkage void __exception asm_do_IRQ(unsigned int irq, struct pt_regs *regs) + { + struct pt_regs *old_regs = set_irq_regs(regs); +- ++#ifdef CONFIG_FIND_IRQ_BLOCKERS ++ unsigned long us; ++#endif + irq_enter(); + ++#ifdef CONFIG_FIND_IRQ_BLOCKERS ++ us = s3c2410_gettimeoffset(); ++#endif ++ + /* + * Some hardware gives randomly wrong interrupts. Rather + * than crashing, do something sensible. +@@ -124,6 +135,12 @@ + else + generic_handle_irq(irq); + ++#ifdef CONFIG_FIND_IRQ_BLOCKERS ++ us = s3c2410_gettimeoffset() - us; ++ ++ if (iblock_limit && us > iblock_limit && us < 10000000) ++ printk(KERN_ERR "asm_do_IRQ(%u): %lu us\n", irq, us); ++#endif + /* AT91 specific workaround */ + irq_finish(irq); + +diff -ruN --exclude='*.orig' --exclude='*.rej' linux-2.6.29-rc3.owrt/arch/arm/kernel/Makefile linux-2.6.29-rc3.owrt.om/arch/arm/kernel/Makefile +--- linux-2.6.29-rc3.owrt/arch/arm/kernel/Makefile 2009-05-10 22:05:04.000000000 +0200 ++++ linux-2.6.29-rc3.owrt.om/arch/arm/kernel/Makefile 2009-05-10 22:27:59.000000000 +0200 +@@ -44,5 +44,6 @@ + + head-y := head$(MMUEXT).o + obj-$(CONFIG_DEBUG_LL) += debug.o ++obj-$(CONFIG_FIND_IRQ_BLOCKERS) += iblock.o + + extra-y := $(head-y) init_task.o vmlinux.lds +diff -ruN --exclude='*.orig' --exclude='*.rej' linux-2.6.29-rc3.owrt/arch/arm/kernel/vmlinux.lds.S linux-2.6.29-rc3.owrt.om/arch/arm/kernel/vmlinux.lds.S +--- linux-2.6.29-rc3.owrt/arch/arm/kernel/vmlinux.lds.S 2009-05-10 22:05:04.000000000 +0200 ++++ linux-2.6.29-rc3.owrt.om/arch/arm/kernel/vmlinux.lds.S 2009-05-10 22:27:59.000000000 +0200 +@@ -106,6 +106,8 @@ + *(.got) /* Global offset table */ + } + ++ NOTES ++ + RODATA + + _etext = .; /* End of text and rodata section */ +diff -ruN --exclude='*.orig' --exclude='*.rej' linux-2.6.29-rc3.owrt/arch/arm/mach-s3c2410/dma.c linux-2.6.29-rc3.owrt.om/arch/arm/mach-s3c2410/dma.c +--- linux-2.6.29-rc3.owrt/arch/arm/mach-s3c2410/dma.c 2009-05-10 22:05:04.000000000 +0200 ++++ linux-2.6.29-rc3.owrt.om/arch/arm/mach-s3c2410/dma.c 2009-05-10 22:27:59.000000000 +0200 +@@ -17,18 +17,20 @@ + #include <linux/sysdev.h> + #include <linux/serial_core.h> + ++#include <mach/map.h> + #include <mach/dma.h> + + #include <plat/cpu.h> +-#include <plat/dma.h> ++#include <plat/dma-plat.h> + + #include <plat/regs-serial.h> + #include <mach/regs-gpio.h> + #include <plat/regs-ac97.h> ++#include <plat/regs-dma.h> + #include <mach/regs-mem.h> + #include <mach/regs-lcd.h> + #include <mach/regs-sdi.h> +-#include <asm/plat-s3c24xx/regs-iis.h> ++#include <plat/regs-iis.h> + #include <plat/regs-spi.h> + + static struct s3c24xx_dma_map __initdata s3c2410_dma_mappings[] = { +diff -ruN --exclude='*.orig' --exclude='*.rej' linux-2.6.29-rc3.owrt/arch/arm/mach-s3c2410/include/mach/audio.h linux-2.6.29-rc3.owrt.om/arch/arm/mach-s3c2410/include/mach/audio.h +--- linux-2.6.29-rc3.owrt/arch/arm/mach-s3c2410/include/mach/audio.h 2009-05-10 22:05:04.000000000 +0200 ++++ linux-2.6.29-rc3.owrt.om/arch/arm/mach-s3c2410/include/mach/audio.h 1970-01-01 01:00:00.000000000 +0100 +@@ -1,45 +0,0 @@ +-/* arch/arm/mach-s3c2410/include/mach/audio.h +- * +- * Copyright (c) 2004-2005 Simtec Electronics +- * http://www.simtec.co.uk/products/SWLINUX/ +- * Ben Dooks <ben@simtec.co.uk> +- * +- * S3C24XX - Audio platfrom_device info +- * +- * 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_ARCH_AUDIO_H +-#define __ASM_ARCH_AUDIO_H __FILE__ +- +-/* struct s3c24xx_iis_ops +- * +- * called from the s3c24xx audio core to deal with the architecture +- * or the codec's setup and control. +- * +- * the pointer to itself is passed through in case the caller wants to +- * embed this in an larger structure for easy reference to it's context. +-*/ +- +-struct s3c24xx_iis_ops { +- struct module *owner; +- +- int (*startup)(struct s3c24xx_iis_ops *me); +- void (*shutdown)(struct s3c24xx_iis_ops *me); +- int (*suspend)(struct s3c24xx_iis_ops *me); +- int (*resume)(struct s3c24xx_iis_ops *me); +- +- int (*open)(struct s3c24xx_iis_ops *me, struct snd_pcm_substream *strm); +- int (*close)(struct s3c24xx_iis_ops *me, struct snd_pcm_substream *strm); +- int (*prepare)(struct s3c24xx_iis_ops *me, struct snd_pcm_substream *strm, struct snd_pcm_runtime *rt); +-}; +- +-struct s3c24xx_platdata_iis { +- const char *codec_clk; +- struct s3c24xx_iis_ops *ops; +- int (*match_dev)(struct device *dev); +-}; +- +-#endif /* __ASM_ARCH_AUDIO_H */ +diff -ruN --exclude='*.orig' --exclude='*.rej' linux-2.6.29-rc3.owrt/arch/arm/mach-s3c2410/include/mach/dma.h linux-2.6.29-rc3.owrt.om/arch/arm/mach-s3c2410/include/mach/dma.h +--- linux-2.6.29-rc3.owrt/arch/arm/mach-s3c2410/include/mach/dma.h 2009-05-10 22:05:04.000000000 +0200 ++++ linux-2.6.29-rc3.owrt.om/arch/arm/mach-s3c2410/include/mach/dma.h 2009-05-10 22:27:59.000000000 +0200 +@@ -3,7 +3,7 @@ + * Copyright (C) 2003,2004,2006 Simtec Electronics + * Ben Dooks <ben@simtec.co.uk> + * +- * Samsung S3C241XX DMA support ++ * Samsung S3C24XX DMA support + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as +@@ -13,8 +13,8 @@ + #ifndef __ASM_ARCH_DMA_H + #define __ASM_ARCH_DMA_H __FILE__ + ++#include <plat/dma.h> + #include <linux/sysdev.h> +-#include <mach/hardware.h> + + #define MAX_DMA_TRANSFER_SIZE 0x100000 /* Data Unit is half word */ + +@@ -55,9 +55,9 @@ + + /* we have 4 dma channels */ + #ifndef CONFIG_CPU_S3C2443 +-#define S3C2410_DMA_CHANNELS (4) ++#define S3C_DMA_CHANNELS (4) + #else +-#define S3C2410_DMA_CHANNELS (6) ++#define S3C_DMA_CHANNELS (6) + #endif + + /* types */ +@@ -68,7 +68,6 @@ + S3C2410_DMA_PAUSED + }; + +- + /* enum s3c2410_dma_loadst + * + * This represents the state of the DMA engine, wrt to the loaded / running +@@ -104,32 +103,6 @@ + S3C2410_DMALOAD_1LOADED_1RUNNING, + }; + +-enum s3c2410_dma_buffresult { +- S3C2410_RES_OK, +- S3C2410_RES_ERR, +- S3C2410_RES_ABORT +-}; +- +-enum s3c2410_dmasrc { +- S3C2410_DMASRC_HW, /* source is memory */ +- S3C2410_DMASRC_MEM /* source is hardware */ +-}; +- +-/* enum s3c2410_chan_op +- * +- * operation codes passed to the DMA code by the user, and also used +- * to inform the current channel owner of any changes to the system state +-*/ +- +-enum s3c2410_chan_op { +- S3C2410_DMAOP_START, +- S3C2410_DMAOP_STOP, +- S3C2410_DMAOP_PAUSE, +- S3C2410_DMAOP_RESUME, +- S3C2410_DMAOP_FLUSH, +- S3C2410_DMAOP_TIMEOUT, /* internal signal to handler */ +- S3C2410_DMAOP_STARTED, /* indicate channel started */ +-}; + + /* flags */ + +@@ -137,19 +110,18 @@ + * waiting for reloads */ + #define S3C2410_DMAF_AUTOSTART (1<<1) /* auto-start if buffer queued */ + ++#define S3C2410_DMAF_CIRCULAR (0x00) /* circular enqueue not supp. */ ++ + /* dma buffer */ + +-struct s3c2410_dma_client { +- char *name; +-}; ++struct s3c2410_dma_buf; + +-/* s3c2410_dma_buf_s ++/* s3c2410_dma_buf + * + * internally used buffer structure to describe a queued or running + * buffer. + */ + +-struct s3c2410_dma_buf; + struct s3c2410_dma_buf { + struct s3c2410_dma_buf *next; + int magic; /* magic */ +@@ -161,20 +133,6 @@ + + /* [1] is this updated for both recv/send modes? */ + +-struct s3c2410_dma_chan; +- +-/* s3c2410_dma_cbfn_t +- * +- * buffer callback routine type +-*/ +- +-typedef void (*s3c2410_dma_cbfn_t)(struct s3c2410_dma_chan *, +- void *buf, int size, +- enum s3c2410_dma_buffresult result); +- +-typedef int (*s3c2410_dma_opfn_t)(struct s3c2410_dma_chan *, +- enum s3c2410_chan_op ); +- + struct s3c2410_dma_stats { + unsigned long loads; + unsigned long timeout_longest; +@@ -206,10 +164,10 @@ + + /* channel configuration */ + enum s3c2410_dmasrc source; ++ enum dma_ch req_ch; + unsigned long dev_addr; + unsigned long load_timeout; + unsigned int flags; /* channel flags */ +- unsigned int hw_cfg; /* last hw config */ + + struct s3c24xx_dma_map *map; /* channel hw maps */ + +@@ -236,213 +194,12 @@ + struct sys_device dev; + }; + +-/* the currently allocated channel information */ +-extern struct s3c2410_dma_chan s3c2410_chans[]; +- +-/* note, we don't really use dma_device_t at the moment */ + typedef unsigned long dma_device_t; + +-/* functions --------------------------------------------------------------- */ +- +-/* s3c2410_dma_request +- * +- * request a dma channel exclusivley +-*/ +- +-extern int s3c2410_dma_request(unsigned int channel, +- struct s3c2410_dma_client *, void *dev); +- +- +-/* s3c2410_dma_ctrl +- * +- * change the state of the dma channel +-*/ +- +-extern int s3c2410_dma_ctrl(unsigned int channel, enum s3c2410_chan_op op); +- +-/* s3c2410_dma_setflags +- * +- * set the channel's flags to a given state +-*/ +- +-extern int s3c2410_dma_setflags(unsigned int channel, +- unsigned int flags); +- +-/* s3c2410_dma_free +- * +- * free the dma channel (will also abort any outstanding operations) +-*/ +- +-extern int s3c2410_dma_free(unsigned int channel, struct s3c2410_dma_client *); +- +-/* s3c2410_dma_enqueue +- * +- * place the given buffer onto the queue of operations for the channel. +- * The buffer must be allocated from dma coherent memory, or the Dcache/WB +- * drained before the buffer is given to the DMA system. +-*/ +- +-extern int s3c2410_dma_enqueue(unsigned int channel, void *id, +- dma_addr_t data, int size); +- +-/* s3c2410_dma_config +- * +- * configure the dma channel +-*/ +- +-extern int s3c2410_dma_config(unsigned int channel, int xferunit, int dcon); +- +-/* s3c2410_dma_devconfig +- * +- * configure the device we're talking to +-*/ +- +-extern int s3c2410_dma_devconfig(int channel, enum s3c2410_dmasrc source, +- int hwcfg, unsigned long devaddr); +- +-/* s3c2410_dma_getposition +- * +- * get the position that the dma transfer is currently at +-*/ +- +-extern int s3c2410_dma_getposition(unsigned int channel, +- dma_addr_t *src, dma_addr_t *dest); +- +-extern int s3c2410_dma_set_opfn(unsigned int, s3c2410_dma_opfn_t rtn); +-extern int s3c2410_dma_set_buffdone_fn(unsigned int, s3c2410_dma_cbfn_t rtn); +- +-/* DMA Register definitions */ +- +-#define S3C2410_DMA_DISRC (0x00) +-#define S3C2410_DMA_DISRCC (0x04) +-#define S3C2410_DMA_DIDST (0x08) +-#define S3C2410_DMA_DIDSTC (0x0C) +-#define S3C2410_DMA_DCON (0x10) +-#define S3C2410_DMA_DSTAT (0x14) +-#define S3C2410_DMA_DCSRC (0x18) +-#define S3C2410_DMA_DCDST (0x1C) +-#define S3C2410_DMA_DMASKTRIG (0x20) +-#define S3C2412_DMA_DMAREQSEL (0x24) +-#define S3C2443_DMA_DMAREQSEL (0x24) +- +-#define S3C2410_DISRCC_INC (1<<0) +-#define S3C2410_DISRCC_APB (1<<1) +- +-#define S3C2410_DMASKTRIG_STOP (1<<2) +-#define S3C2410_DMASKTRIG_ON (1<<1) +-#define S3C2410_DMASKTRIG_SWTRIG (1<<0) +- +-#define S3C2410_DCON_DEMAND (0<<31) +-#define S3C2410_DCON_HANDSHAKE (1<<31) +-#define S3C2410_DCON_SYNC_PCLK (0<<30) +-#define S3C2410_DCON_SYNC_HCLK (1<<30) +- +-#define S3C2410_DCON_INTREQ (1<<29) +- +-#define S3C2410_DCON_CH0_XDREQ0 (0<<24) +-#define S3C2410_DCON_CH0_UART0 (1<<24) +-#define S3C2410_DCON_CH0_SDI (2<<24) +-#define S3C2410_DCON_CH0_TIMER (3<<24) +-#define S3C2410_DCON_CH0_USBEP1 (4<<24) +- +-#define S3C2410_DCON_CH1_XDREQ1 (0<<24) +-#define S3C2410_DCON_CH1_UART1 (1<<24) +-#define S3C2410_DCON_CH1_I2SSDI (2<<24) +-#define S3C2410_DCON_CH1_SPI (3<<24) +-#define S3C2410_DCON_CH1_USBEP2 (4<<24) +- +-#define S3C2410_DCON_CH2_I2SSDO (0<<24) +-#define S3C2410_DCON_CH2_I2SSDI (1<<24) +-#define S3C2410_DCON_CH2_SDI (2<<24) +-#define S3C2410_DCON_CH2_TIMER (3<<24) +-#define S3C2410_DCON_CH2_USBEP3 (4<<24) +- +-#define S3C2410_DCON_CH3_UART2 (0<<24) +-#define S3C2410_DCON_CH3_SDI (1<<24) +-#define S3C2410_DCON_CH3_SPI (2<<24) +-#define S3C2410_DCON_CH3_TIMER (3<<24) +-#define S3C2410_DCON_CH3_USBEP4 (4<<24) +- +-#define S3C2410_DCON_SRCSHIFT (24) +-#define S3C2410_DCON_SRCMASK (7<<24) +- +-#define S3C2410_DCON_BYTE (0<<20) +-#define S3C2410_DCON_HALFWORD (1<<20) +-#define S3C2410_DCON_WORD (2<<20) +- +-#define S3C2410_DCON_AUTORELOAD (0<<22) +-#define S3C2410_DCON_NORELOAD (1<<22) +-#define S3C2410_DCON_HWTRIG (1<<23) +- +-#ifdef CONFIG_CPU_S3C2440 +-#define S3C2440_DIDSTC_CHKINT (1<<2) +- +-#define S3C2440_DCON_CH0_I2SSDO (5<<24) +-#define S3C2440_DCON_CH0_PCMIN (6<<24) +- +-#define S3C2440_DCON_CH1_PCMOUT (5<<24) +-#define S3C2440_DCON_CH1_SDI (6<<24) +- +-#define S3C2440_DCON_CH2_PCMIN (5<<24) +-#define S3C2440_DCON_CH2_MICIN (6<<24) +- +-#define S3C2440_DCON_CH3_MICIN (5<<24) +-#define S3C2440_DCON_CH3_PCMOUT (6<<24) +-#endif +- +-#ifdef CONFIG_CPU_S3C2412 +- +-#define S3C2412_DMAREQSEL_SRC(x) ((x)<<1) +- +-#define S3C2412_DMAREQSEL_HW (1) +- +-#define S3C2412_DMAREQSEL_SPI0TX S3C2412_DMAREQSEL_SRC(0) +-#define S3C2412_DMAREQSEL_SPI0RX S3C2412_DMAREQSEL_SRC(1) +-#define S3C2412_DMAREQSEL_SPI1TX S3C2412_DMAREQSEL_SRC(2) +-#define S3C2412_DMAREQSEL_SPI1RX S3C2412_DMAREQSEL_SRC(3) +-#define S3C2412_DMAREQSEL_I2STX S3C2412_DMAREQSEL_SRC(4) +-#define S3C2412_DMAREQSEL_I2SRX S3C2412_DMAREQSEL_SRC(5) +-#define S3C2412_DMAREQSEL_TIMER S3C2412_DMAREQSEL_SRC(9) +-#define S3C2412_DMAREQSEL_SDI S3C2412_DMAREQSEL_SRC(10) +-#define S3C2412_DMAREQSEL_USBEP1 S3C2412_DMAREQSEL_SRC(13) +-#define S3C2412_DMAREQSEL_USBEP2 S3C2412_DMAREQSEL_SRC(14) +-#define S3C2412_DMAREQSEL_USBEP3 S3C2412_DMAREQSEL_SRC(15) +-#define S3C2412_DMAREQSEL_USBEP4 S3C2412_DMAREQSEL_SRC(16) +-#define S3C2412_DMAREQSEL_XDREQ0 S3C2412_DMAREQSEL_SRC(17) +-#define S3C2412_DMAREQSEL_XDREQ1 S3C2412_DMAREQSEL_SRC(18) +-#define S3C2412_DMAREQSEL_UART0_0 S3C2412_DMAREQSEL_SRC(19) +-#define S3C2412_DMAREQSEL_UART0_1 S3C2412_DMAREQSEL_SRC(20) +-#define S3C2412_DMAREQSEL_UART1_0 S3C2412_DMAREQSEL_SRC(21) +-#define S3C2412_DMAREQSEL_UART1_1 S3C2412_DMAREQSEL_SRC(22) +-#define S3C2412_DMAREQSEL_UART2_0 S3C2412_DMAREQSEL_SRC(23) +-#define S3C2412_DMAREQSEL_UART2_1 S3C2412_DMAREQSEL_SRC(24) +- +-#endif +- +-#define S3C2443_DMAREQSEL_SRC(x) ((x)<<1) +- +-#define S3C2443_DMAREQSEL_HW (1) + +-#define S3C2443_DMAREQSEL_SPI0TX S3C2443_DMAREQSEL_SRC(0) +-#define S3C2443_DMAREQSEL_SPI0RX S3C2443_DMAREQSEL_SRC(1) +-#define S3C2443_DMAREQSEL_SPI1TX S3C2443_DMAREQSEL_SRC(2) +-#define S3C2443_DMAREQSEL_SPI1RX S3C2443_DMAREQSEL_SRC(3) +-#define S3C2443_DMAREQSEL_I2STX S3C2443_DMAREQSEL_SRC(4) +-#define S3C2443_DMAREQSEL_I2SRX S3C2443_DMAREQSEL_SRC(5) +-#define S3C2443_DMAREQSEL_TIMER S3C2443_DMAREQSEL_SRC(9) +-#define S3C2443_DMAREQSEL_SDI S3C2443_DMAREQSEL_SRC(10) +-#define S3C2443_DMAREQSEL_XDREQ0 S3C2443_DMAREQSEL_SRC(17) +-#define S3C2443_DMAREQSEL_XDREQ1 S3C2443_DMAREQSEL_SRC(18) +-#define S3C2443_DMAREQSEL_UART0_0 S3C2443_DMAREQSEL_SRC(19) +-#define S3C2443_DMAREQSEL_UART0_1 S3C2443_DMAREQSEL_SRC(20) +-#define S3C2443_DMAREQSEL_UART1_0 S3C2443_DMAREQSEL_SRC(21) +-#define S3C2443_DMAREQSEL_UART1_1 S3C2443_DMAREQSEL_SRC(22) +-#define S3C2443_DMAREQSEL_UART2_0 S3C2443_DMAREQSEL_SRC(23) +-#define S3C2443_DMAREQSEL_UART2_1 S3C2443_DMAREQSEL_SRC(24) +-#define S3C2443_DMAREQSEL_UART3_0 S3C2443_DMAREQSEL_SRC(25) +-#define S3C2443_DMAREQSEL_UART3_1 S3C2443_DMAREQSEL_SRC(26) +-#define S3C2443_DMAREQSEL_PCMOUT S3C2443_DMAREQSEL_SRC(27) +-#define S3C2443_DMAREQSEL_PCMIN S3C2443_DMAREQSEL_SRC(28) +-#define S3C2443_DMAREQSEL_MICIN S3C2443_DMAREQSEL_SRC(29) ++static int s3c_dma_has_circular(void) ++{ ++ return 0; ++} + + #endif /* __ASM_ARCH_DMA_H */ +diff -ruN --exclude='*.orig' --exclude='*.rej' linux-2.6.29-rc3.owrt/arch/arm/mach-s3c2410/include/mach/gpio-core.h linux-2.6.29-rc3.owrt.om/arch/arm/mach-s3c2410/include/mach/gpio-core.h +--- linux-2.6.29-rc3.owrt/arch/arm/mach-s3c2410/include/mach/gpio-core.h 2009-05-10 22:05:04.000000000 +0200 ++++ linux-2.6.29-rc3.owrt.om/arch/arm/mach-s3c2410/include/mach/gpio-core.h 2009-05-10 22:27:59.000000000 +0200 +@@ -15,20 +15,7 @@ + #ifndef __ASM_ARCH_GPIO_CORE_H + #define __ASM_ARCH_GPIO_CORE_H __FILE__ + ++/* currently we just include the platform support */ + #include <plat/gpio-core.h> +-#include <mach/regs-gpio.h> +- +-extern struct s3c_gpio_chip s3c24xx_gpios[]; +- +-static inline struct s3c_gpio_chip *s3c_gpiolib_getchip(unsigned int pin) +-{ +- struct s3c_gpio_chip *chip; +- +- if (pin > S3C2410_GPG10) +- return NULL; +- +- chip = &s3c24xx_gpios[pin/32]; +- return (S3C2410_GPIO_OFFSET(pin) > chip->chip.ngpio) ? chip : NULL; +-} + + #endif /* __ASM_ARCH_GPIO_CORE_H */ +diff -ruN --exclude='*.orig' --exclude='*.rej' linux-2.6.29-rc3.owrt/arch/arm/mach-s3c2410/include/mach/gpio.h linux-2.6.29-rc3.owrt.om/arch/arm/mach-s3c2410/include/mach/gpio.h +--- linux-2.6.29-rc3.owrt/arch/arm/mach-s3c2410/include/mach/gpio.h 2009-05-10 22:05:04.000000000 +0200 ++++ linux-2.6.29-rc3.owrt.om/arch/arm/mach-s3c2410/include/mach/gpio.h 2009-05-10 22:27:59.000000000 +0200 +@@ -22,4 +22,13 @@ + + #define ARCH_NR_GPIOS (256 + CONFIG_S3C24XX_GPIO_EXTRA) + ++/* These two defines should be removed as soon as the ++ * generic irq handling makes it upstream */ ++#include <mach/hardware.h> ++#define irq_to_gpio(irq) s3c2410_gpio_irq2pin(irq) ++/* -- cut to here when generic irq makes it */ ++ + #include <asm-generic/gpio.h> ++#include <mach/gpio-nrs.h> ++ ++#define S3C_GPIO_END (S3C2410_GPIO_BANKH + 32) +diff -ruN --exclude='*.orig' --exclude='*.rej' linux-2.6.29-rc3.owrt/arch/arm/mach-s3c2410/include/mach/gpio-nrs.h linux-2.6.29-rc3.owrt.om/arch/arm/mach-s3c2410/include/mach/gpio-nrs.h +--- linux-2.6.29-rc3.owrt/arch/arm/mach-s3c2410/include/mach/gpio-nrs.h 1970-01-01 01:00:00.000000000 +0100 ++++ linux-2.6.29-rc3.owrt.om/arch/arm/mach-s3c2410/include/mach/gpio-nrs.h 2009-05-10 22:27:59.000000000 +0200 +@@ -0,0 +1,23 @@ ++/* arch/arm/mach-s3c2410/include/mach/gpio-nrs.h ++ * ++ * Copyright (c) 2008 Simtec Electronics ++ * http://armlinux.simtec.co.uk/ ++ * Ben Dooks <ben@simtec.co.uk> ++ * ++ * S3C2410 - GPIO bank numbering ++ * ++ * 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. ++*/ ++ ++#define S3C2410_GPIONO(bank,offset) ((bank) + (offset)) ++ ++#define S3C2410_GPIO_BANKA (32*0) ++#define S3C2410_GPIO_BANKB (32*1) ++#define S3C2410_GPIO_BANKC (32*2) ++#define S3C2410_GPIO_BANKD (32*3) ++#define S3C2410_GPIO_BANKE (32*4) ++#define S3C2410_GPIO_BANKF (32*5) ++#define S3C2410_GPIO_BANKG (32*6) ++#define S3C2410_GPIO_BANKH (32*7) +diff -ruN --exclude='*.orig' --exclude='*.rej' linux-2.6.29-rc3.owrt/arch/arm/mach-s3c2410/include/mach/gta01.h linux-2.6.29-rc3.owrt.om/arch/arm/mach-s3c2410/include/mach/gta01.h +--- linux-2.6.29-rc3.owrt/arch/arm/mach-s3c2410/include/mach/gta01.h 1970-01-01 01:00:00.000000000 +0100 ++++ linux-2.6.29-rc3.owrt.om/arch/arm/mach-s3c2410/include/mach/gta01.h 2009-05-10 22:27:59.000000000 +0200 +@@ -0,0 +1,76 @@ ++#ifndef _GTA01_H ++#define _GTA01_H ++ ++#include <mach/regs-gpio.h> ++#include <mach/irqs.h> ++ ++/* Different hardware revisions, passed in ATAG_REVISION by u-boot */ ++#define GTA01v3_SYSTEM_REV 0x00000130 ++#define GTA01v4_SYSTEM_REV 0x00000140 ++#define GTA01Bv2_SYSTEM_REV 0x00000220 ++#define GTA01Bv3_SYSTEM_REV 0x00000230 ++#define GTA01Bv4_SYSTEM_REV 0x00000240 ++ ++/* Backlight */ ++ ++extern void gta01bl_deferred_resume(void); ++ ++struct gta01bl_machinfo { ++ unsigned int default_intensity; ++ unsigned int max_intensity; ++ unsigned int limit_mask; ++ unsigned int defer_resume_backlight; ++}; ++ ++/* Definitions common to all revisions */ ++#define GTA01_GPIO_BACKLIGHT S3C2410_GPB0 ++#define GTA01_GPIO_GPS_PWRON S3C2410_GPB1 ++#define GTA01_GPIO_MODEM_RST S3C2410_GPB6 ++#define GTA01_GPIO_MODEM_ON S3C2410_GPB7 ++#define GTA01_GPIO_LCD_RESET S3C2410_GPC6 ++#define GTA01_GPIO_PMU_IRQ S3C2410_GPG8 ++#define GTA01_GPIO_JACK_INSERT S3C2410_GPF4 ++#define GTA01_GPIO_nSD_DETECT S3C2410_GPF5 ++#define GTA01_GPIO_AUX_KEY S3C2410_GPF6 ++#define GTA01_GPIO_HOLD_KEY S3C2410_GPF7 ++#define GTA01_GPIO_VIBRATOR_ON S3C2410_GPG11 ++ ++#define GTA01_IRQ_MODEM IRQ_EINT1 ++#define GTA01_IRQ_JACK_INSERT IRQ_EINT4 ++#define GTA01_IRQ_nSD_DETECT IRQ_EINT5 ++#define GTA01_IRQ_AUX_KEY IRQ_EINT6 ++#define GTA01_IRQ_PCF50606 IRQ_EINT16 ++ ++/* GTA01v3 */ ++#define GTA01v3_GPIO_nGSM_EN S3C2410_GPG9 ++ ++/* GTA01v4 */ ++#define GTA01_GPIO_MODEM_DNLOAD S3C2410_GPG0 ++ ++/* GTA01Bv2 */ ++#define GTA01Bv2_GPIO_nGSM_EN S3C2410_GPF2 ++#define GTA01Bv2_GPIO_VIBRATOR_ON S3C2410_GPB10 ++ ++/* GTA01Bv3 */ ++#define GTA01_GPIO_GPS_EN_3V3 S3C2410_GPG9 ++ ++#define GTA01_GPIO_SDMMC_ON S3C2410_GPB2 ++#define GTA01_GPIO_BT_EN S3C2410_GPB5 ++#define GTA01_GPIO_AB_DETECT S3C2410_GPB8 ++#define GTA01_GPIO_USB_PULLUP S3C2410_GPB9 ++#define GTA01_GPIO_USB_ATTACH S3C2410_GPB10 ++ ++#define GTA01_GPIO_GPS_EN_2V8 S3C2410_GPG9 ++#define GTA01_GPIO_GPS_EN_3V S3C2410_GPG10 ++#define GTA01_GPIO_GPS_RESET S3C2410_GPC0 ++ ++/* GTA01Bv4 */ ++#define GTA01Bv4_GPIO_nNAND_WP S3C2410_GPA16 ++#define GTA01Bv4_GPIO_VIBRATOR_ON S3C2410_GPB3 ++#define GTA01Bv4_GPIO_PMU_IRQ S3C2410_GPG1 ++ ++#define GTA01Bv4_IRQ_PCF50606 IRQ_EINT9 ++ ++extern struct pcf50606 *gta01_pcf; ++ ++#endif /* _GTA01_H */ +diff -ruN --exclude='*.orig' --exclude='*.rej' linux-2.6.29-rc3.owrt/arch/arm/mach-s3c2410/include/mach/gta02-pm-wlan.h linux-2.6.29-rc3.owrt.om/arch/arm/mach-s3c2410/include/mach/gta02-pm-wlan.h +--- linux-2.6.29-rc3.owrt/arch/arm/mach-s3c2410/include/mach/gta02-pm-wlan.h 1970-01-01 01:00:00.000000000 +0100 ++++ linux-2.6.29-rc3.owrt.om/arch/arm/mach-s3c2410/include/mach/gta02-pm-wlan.h 2009-05-10 22:27:59.000000000 +0200 +@@ -0,0 +1,10 @@ ++#ifndef __MACH_GTA02_PM_WLAN_H ++#define __MACH_GTA02_PM_WLAN_H ++ ++void gta02_wlan_reset(int assert_reset); ++int gta02_wlan_query_rfkill_lock(void); ++void gta02_wlan_query_rfkill_unlock(void); ++void gta02_wlan_set_rfkill_cb(int (*cb)(void *user, int on), void *user); ++void gta02_wlan_clear_rfkill_cb(void); ++ ++#endif /* __MACH_GTA02_PM_WLAN_H */ +diff -ruN --exclude='*.orig' --exclude='*.rej' linux-2.6.29-rc3.owrt/arch/arm/mach-s3c2410/include/mach/hardware.h linux-2.6.29-rc3.owrt.om/arch/arm/mach-s3c2410/include/mach/hardware.h +--- linux-2.6.29-rc3.owrt/arch/arm/mach-s3c2410/include/mach/hardware.h 2009-05-10 22:05:04.000000000 +0200 ++++ linux-2.6.29-rc3.owrt.om/arch/arm/mach-s3c2410/include/mach/hardware.h 2009-05-10 22:27:59.000000000 +0200 +@@ -131,7 +131,4 @@ + + /* machine specific hardware definitions should go after this */ + +-/* currently here until moved into config (todo) */ +-#define CONFIG_NO_MULTIWORD_IO +- + #endif /* __ASM_ARCH_HARDWARE_H */ +diff -ruN --exclude='*.orig' --exclude='*.rej' linux-2.6.29-rc3.owrt/arch/arm/mach-s3c2410/include/mach/io.h linux-2.6.29-rc3.owrt.om/arch/arm/mach-s3c2410/include/mach/io.h +--- linux-2.6.29-rc3.owrt/arch/arm/mach-s3c2410/include/mach/io.h 2009-05-10 22:05:04.000000000 +0200 ++++ linux-2.6.29-rc3.owrt.om/arch/arm/mach-s3c2410/include/mach/io.h 2009-05-10 22:27:59.000000000 +0200 +@@ -9,7 +9,7 @@ + #ifndef __ASM_ARM_ARCH_IO_H + #define __ASM_ARM_ARCH_IO_H + +-#include <mach/hardware.h> ++#include <mach/map.h> + + #define IO_SPACE_LIMIT 0xffffffff + +diff -ruN --exclude='*.orig' --exclude='*.rej' linux-2.6.29-rc3.owrt/arch/arm/mach-s3c2410/include/mach/irqs.h linux-2.6.29-rc3.owrt.om/arch/arm/mach-s3c2410/include/mach/irqs.h +--- linux-2.6.29-rc3.owrt/arch/arm/mach-s3c2410/include/mach/irqs.h 2009-05-10 22:05:04.000000000 +0200 ++++ linux-2.6.29-rc3.owrt.om/arch/arm/mach-s3c2410/include/mach/irqs.h 2009-05-10 22:27:59.000000000 +0200 +@@ -80,7 +80,7 @@ + #define IRQ_EINT22 S3C2410_IRQ(50) + #define IRQ_EINT23 S3C2410_IRQ(51) + +- ++#define IRQ_EINT_BIT(x) ((x) - IRQ_EINT4 + 4) + #define IRQ_EINT(x) (((x) >= 4) ? (IRQ_EINT4 + (x) - 4) : (IRQ_EINT0 + (x))) + + #define IRQ_LCD_FIFO S3C2410_IRQ(52) +@@ -153,9 +153,9 @@ + #define IRQ_S3C2443_AC97 S3C2410_IRQSUB(28) + + #ifdef CONFIG_CPU_S3C2443 +-#define NR_IRQS (IRQ_S3C2443_AC97+1) ++#define _NR_IRQS (IRQ_S3C2443_AC97+1) + #else +-#define NR_IRQS (IRQ_S3C2440_AC97+1) ++#define _NR_IRQS (IRQ_S3C2440_AC97+1) + #endif + + /* compatibility define. */ +@@ -167,4 +167,33 @@ + /* Our FIQs are routable from IRQ_EINT0 to IRQ_ADCPARENT */ + #define FIQ_START IRQ_EINT0 + ++ ++/* ++ * The next 16 interrupts are for board specific purposes. Since ++ * the kernel can only run on one machine at a time, we can re-use ++ * these. If you need more, increase IRQ_BOARD_END, but keep it ++ * within sensible limits. ++ */ ++#define IRQ_BOARD_START _NR_IRQS ++#define IRQ_BOARD_END (_NR_IRQS + 10) ++ ++#if defined(CONFIG_MACH_NEO1973_GTA02) ++#define NR_IRQS (IRQ_BOARD_END) ++#else ++#define NR_IRQS (IRQ_BOARD_START) ++#endif ++ ++/* Neo1973 GTA02 interrupts */ ++#define NEO1973_GTA02_IRQ(x) (IRQ_BOARD_START + (x)) ++#define IRQ_GLAMO(x) NEO1973_GTA02_IRQ(x) ++#define IRQ_GLAMO_HOSTBUS IRQ_GLAMO(0) ++#define IRQ_GLAMO_JPEG IRQ_GLAMO(1) ++#define IRQ_GLAMO_MPEG IRQ_GLAMO(2) ++#define IRQ_GLAMO_MPROC1 IRQ_GLAMO(3) ++#define IRQ_GLAMO_MPROC0 IRQ_GLAMO(4) ++#define IRQ_GLAMO_CMDQUEUE IRQ_GLAMO(5) ++#define IRQ_GLAMO_2D IRQ_GLAMO(6) ++#define IRQ_GLAMO_MMC IRQ_GLAMO(7) ++#define IRQ_GLAMO_RISC IRQ_GLAMO(8) ++ + #endif /* __ASM_ARCH_IRQ_H */ +diff -ruN --exclude='*.orig' --exclude='*.rej' linux-2.6.29-rc3.owrt/arch/arm/mach-s3c2410/include/mach/map.h linux-2.6.29-rc3.owrt.om/arch/arm/mach-s3c2410/include/mach/map.h +--- linux-2.6.29-rc3.owrt/arch/arm/mach-s3c2410/include/mach/map.h 2009-05-10 22:05:04.000000000 +0200 ++++ linux-2.6.29-rc3.owrt.om/arch/arm/mach-s3c2410/include/mach/map.h 2009-05-10 22:27:59.000000000 +0200 +@@ -84,7 +84,6 @@ + + #define S3C24XX_PA_IRQ S3C2410_PA_IRQ + #define S3C24XX_PA_MEMCTRL S3C2410_PA_MEMCTRL +-#define S3C24XX_PA_USBHOST S3C2410_PA_USBHOST + #define S3C24XX_PA_DMA S3C2410_PA_DMA + #define S3C24XX_PA_CLKPWR S3C2410_PA_CLKPWR + #define S3C24XX_PA_LCD S3C2410_PA_LCD +@@ -102,6 +101,7 @@ + + #define S3C_PA_IIC S3C2410_PA_IIC + #define S3C_PA_UART S3C24XX_PA_UART ++#define S3C_PA_USBHOST S3C2410_PA_USBHOST + #define S3C_PA_HSMMC0 S3C2443_PA_HSMMC + + #endif /* __ASM_ARCH_MAP_H */ +diff -ruN --exclude='*.orig' --exclude='*.rej' linux-2.6.29-rc3.owrt/arch/arm/mach-s3c2410/include/mach/mci.h linux-2.6.29-rc3.owrt.om/arch/arm/mach-s3c2410/include/mach/mci.h +--- linux-2.6.29-rc3.owrt/arch/arm/mach-s3c2410/include/mach/mci.h 1970-01-01 01:00:00.000000000 +0100 ++++ linux-2.6.29-rc3.owrt.om/arch/arm/mach-s3c2410/include/mach/mci.h 2009-05-10 22:27:59.000000000 +0200 +@@ -0,0 +1,13 @@ ++#ifndef _ARCH_MCI_H ++#define _ARCH_MCI_H ++ ++struct s3c24xx_mci_pdata { ++ unsigned int gpio_detect; ++ unsigned int gpio_wprotect; ++ unsigned long ocr_avail; ++ unsigned int do_dma; ++ void (*set_power)(unsigned char power_mode, ++ unsigned short vdd); ++}; ++ ++#endif /* _ARCH_NCI_H */ +diff -ruN --exclude='*.orig' --exclude='*.rej' linux-2.6.29-rc3.owrt/arch/arm/mach-s3c2410/include/mach/neo1973-pm-gsm.h linux-2.6.29-rc3.owrt.om/arch/arm/mach-s3c2410/include/mach/neo1973-pm-gsm.h +--- linux-2.6.29-rc3.owrt/arch/arm/mach-s3c2410/include/mach/neo1973-pm-gsm.h 1970-01-01 01:00:00.000000000 +0100 ++++ linux-2.6.29-rc3.owrt.om/arch/arm/mach-s3c2410/include/mach/neo1973-pm-gsm.h 2009-05-10 22:27:59.000000000 +0200 +@@ -0,0 +1 @@ ++extern int gta_gsm_interrupts; +diff -ruN --exclude='*.orig' --exclude='*.rej' linux-2.6.29-rc3.owrt/arch/arm/mach-s3c2410/include/mach/regs-gpio.h linux-2.6.29-rc3.owrt.om/arch/arm/mach-s3c2410/include/mach/regs-gpio.h +--- linux-2.6.29-rc3.owrt/arch/arm/mach-s3c2410/include/mach/regs-gpio.h 2009-05-10 22:05:04.000000000 +0200 ++++ linux-2.6.29-rc3.owrt.om/arch/arm/mach-s3c2410/include/mach/regs-gpio.h 2009-05-10 22:27:59.000000000 +0200 +@@ -14,16 +14,7 @@ + #ifndef __ASM_ARCH_REGS_GPIO_H + #define __ASM_ARCH_REGS_GPIO_H + +-#define S3C2410_GPIONO(bank,offset) ((bank) + (offset)) +- +-#define S3C2410_GPIO_BANKA (32*0) +-#define S3C2410_GPIO_BANKB (32*1) +-#define S3C2410_GPIO_BANKC (32*2) +-#define S3C2410_GPIO_BANKD (32*3) +-#define S3C2410_GPIO_BANKE (32*4) +-#define S3C2410_GPIO_BANKF (32*5) +-#define S3C2410_GPIO_BANKG (32*6) +-#define S3C2410_GPIO_BANKH (32*7) ++#include <mach/gpio-nrs.h> + + #ifdef CONFIG_CPU_S3C2400 + #define S3C24XX_GPIO_BASE(x) S3C2400_GPIO_BASE(x) +diff -ruN --exclude='*.orig' --exclude='*.rej' linux-2.6.29-rc3.owrt/arch/arm/mach-s3c2410/include/mach/regs-sdi.h linux-2.6.29-rc3.owrt.om/arch/arm/mach-s3c2410/include/mach/regs-sdi.h +--- linux-2.6.29-rc3.owrt/arch/arm/mach-s3c2410/include/mach/regs-sdi.h 2009-05-10 22:05:04.000000000 +0200 ++++ linux-2.6.29-rc3.owrt.om/arch/arm/mach-s3c2410/include/mach/regs-sdi.h 2009-05-10 22:27:59.000000000 +0200 +@@ -30,6 +30,7 @@ + #define S3C2410_SDIFSTA (0x38) + + #define S3C2410_SDIDATA (0x3C) ++#define S3C2410_SDIDATA_BYTE (0x3C) + #define S3C2410_SDIIMSK (0x40) + + #define S3C2440_SDIDATA (0x40) +@@ -37,6 +38,8 @@ + + #define S3C2440_SDICON_SDRESET (1<<8) + #define S3C2440_SDICON_MMCCLOCK (1<<5) ++#define S3C2440_SDIDATA_BYTE (0x48) ++ + #define S3C2410_SDICON_BYTEORDER (1<<4) + #define S3C2410_SDICON_SDIOIRQ (1<<3) + #define S3C2410_SDICON_RWAITEN (1<<2) +diff -ruN --exclude='*.orig' --exclude='*.rej' linux-2.6.29-rc3.owrt/arch/arm/mach-s3c2410/include/mach/s3c24xx-serial.h linux-2.6.29-rc3.owrt.om/arch/arm/mach-s3c2410/include/mach/s3c24xx-serial.h +--- linux-2.6.29-rc3.owrt/arch/arm/mach-s3c2410/include/mach/s3c24xx-serial.h 1970-01-01 01:00:00.000000000 +0100 ++++ linux-2.6.29-rc3.owrt.om/arch/arm/mach-s3c2410/include/mach/s3c24xx-serial.h 2009-05-10 22:27:59.000000000 +0200 +@@ -0,0 +1,5 @@ ++#include <linux/resume-dependency.h> ++ ++extern void s3c24xx_serial_console_set_silence(int silence); ++extern void s3c24xx_serial_register_resume_dependency(struct resume_dependency * ++ resume_dependency, int uart_index); +diff -ruN --exclude='*.orig' --exclude='*.rej' linux-2.6.29-rc3.owrt/arch/arm/mach-s3c2410/include/mach/spi-gpio.h linux-2.6.29-rc3.owrt.om/arch/arm/mach-s3c2410/include/mach/spi-gpio.h +--- linux-2.6.29-rc3.owrt/arch/arm/mach-s3c2410/include/mach/spi-gpio.h 2009-05-10 22:05:04.000000000 +0200 ++++ linux-2.6.29-rc3.owrt.om/arch/arm/mach-s3c2410/include/mach/spi-gpio.h 2009-05-10 22:27:59.000000000 +0200 +@@ -21,7 +21,8 @@ + int num_chipselect; + int bus_num; + +- void (*chip_select)(struct s3c2410_spigpio_info *spi, int cs); ++ int non_blocking_transfer; ++ void (*chip_select)(struct s3c2410_spigpio_info *spi, int csid, int cs); + }; + + +diff -ruN --exclude='*.orig' --exclude='*.rej' linux-2.6.29-rc3.owrt/arch/arm/mach-s3c2410/include/mach/ts.h linux-2.6.29-rc3.owrt.om/arch/arm/mach-s3c2410/include/mach/ts.h +--- linux-2.6.29-rc3.owrt/arch/arm/mach-s3c2410/include/mach/ts.h 1970-01-01 01:00:00.000000000 +0100 ++++ linux-2.6.29-rc3.owrt.om/arch/arm/mach-s3c2410/include/mach/ts.h 2009-05-10 22:27:59.000000000 +0200 +@@ -0,0 +1,35 @@ ++/* arch/arm/mach-s3c2410/include/mach/ts.h ++ * ++ * Copyright (c) 2005 Arnaud Patard <arnaud.patard@rtp-net.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. ++ * ++ * ++ * Changelog: ++ * 24-Mar-2005 RTP Created file ++ * 03-Aug-2005 RTP Renamed to ts.h ++ */ ++ ++#ifndef __ASM_ARM_TS_H ++#define __ASM_ARM_TS_H ++ ++#include <../drivers/input/touchscreen/ts_filter.h> ++ ++struct s3c2410_ts_mach_info { ++ /* Touchscreen delay. */ ++ int delay; ++ /* Prescaler value. */ ++ int presc; ++ /* ++ * Null-terminated array of pointers to filter APIs and configurations ++ * we want to use. In the same order they will be applied. ++ */ ++ const struct ts_filter_chain_configuration *filter_config; ++}; ++ ++void set_s3c2410ts_info(const struct s3c2410_ts_mach_info *hard_s3c2410ts_info); ++ ++#endif /* __ASM_ARM_TS_H */ +diff -ruN --exclude='*.orig' --exclude='*.rej' linux-2.6.29-rc3.owrt/arch/arm/mach-s3c2410/include/mach/usb-control.h linux-2.6.29-rc3.owrt.om/arch/arm/mach-s3c2410/include/mach/usb-control.h +--- linux-2.6.29-rc3.owrt/arch/arm/mach-s3c2410/include/mach/usb-control.h 2009-05-10 22:05:04.000000000 +0200 ++++ linux-2.6.29-rc3.owrt.om/arch/arm/mach-s3c2410/include/mach/usb-control.h 1970-01-01 01:00:00.000000000 +0100 +@@ -1,41 +0,0 @@ +-/* arch/arm/mach-s3c2410/include/mach/usb-control.h +- * +- * Copyright (c) 2004 Simtec Electronics +- * Ben Dooks <ben@simtec.co.uk> +- * +- * S3C2410 - usb port information +- * +- * 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_ARCH_USBCONTROL_H +-#define __ASM_ARCH_USBCONTROL_H "arch/arm/mach-s3c2410/include/mach/usb-control.h" +- +-#define S3C_HCDFLG_USED (1) +- +-struct s3c2410_hcd_port { +- unsigned char flags; +- unsigned char power; +- unsigned char oc_status; +- unsigned char oc_changed; +-}; +- +-struct s3c2410_hcd_info { +- struct usb_hcd *hcd; +- struct s3c2410_hcd_port port[2]; +- +- void (*power_control)(int port, int to); +- void (*enable_oc)(struct s3c2410_hcd_info *, int on); +- void (*report_oc)(struct s3c2410_hcd_info *, int ports); +-}; +- +-static void inline s3c2410_usb_report_oc(struct s3c2410_hcd_info *info, int ports) +-{ +- if (info->report_oc != NULL) { +- (info->report_oc)(info, ports); +- } +-} +- +-#endif /*__ASM_ARCH_USBCONTROL_H */ +diff -ruN --exclude='*.orig' --exclude='*.rej' linux-2.6.29-rc3.owrt/arch/arm/mach-s3c2410/Kconfig linux-2.6.29-rc3.owrt.om/arch/arm/mach-s3c2410/Kconfig +--- linux-2.6.29-rc3.owrt/arch/arm/mach-s3c2410/Kconfig 2009-05-10 22:05:04.000000000 +0200 ++++ linux-2.6.29-rc3.owrt.om/arch/arm/mach-s3c2410/Kconfig 2009-05-10 22:27:59.000000000 +0200 +@@ -10,6 +10,7 @@ + select CPU_ARM920T + select S3C2410_CLOCK + select S3C2410_GPIO ++ select S3C_PWM + select CPU_LLSERIAL_S3C2410 + select S3C2410_PM if PM + help +@@ -45,6 +46,7 @@ + Internal node for machines with an BAST style IDE + interface + ++ + menu "S3C2410 Machines" + + config ARCH_SMDK2410 +@@ -59,6 +61,7 @@ + bool "IPAQ H1940" + select CPU_S3C2410 + select PM_H1940 if PM ++ select S3C_DEV_USB_HOST + help + Say Y here if you are using the HP IPAQ H1940 + +@@ -70,6 +73,7 @@ + config MACH_N30 + bool "Acer N30 family" + select CPU_S3C2410 ++ select S3C_DEV_USB_HOST + help + Say Y here if you want suppt for the Acer N30, Acer N35, + Navman PiN570, Yakumo AlphaX or Airis NC05 PDAs. +@@ -82,6 +86,7 @@ + select MACH_BAST_IDE + select S3C24XX_DCLK + select ISA ++ select S3C_DEV_USB_HOST + help + Say Y here if you are using the Simtec Electronics EB2410ITX + development board (also known as BAST) +@@ -89,6 +94,7 @@ + config MACH_OTOM + bool "NexVision OTOM Board" + select CPU_S3C2410 ++ select S3C_DEV_USB_HOST + help + Say Y here if you are using the Nex Vision OTOM board + +@@ -96,6 +102,7 @@ + bool "AML M5900 Series" + select CPU_S3C2410 + select PM_SIMTEC if PM ++ select S3C_DEV_USB_HOST + help + Say Y here if you are using the American Microsystems M5900 Series + <http://www.amltd.com> +@@ -111,6 +118,7 @@ + config MACH_TCT_HAMMER + bool "TCT Hammer Board" + select CPU_S3C2410 ++ select S3C_DEV_USB_HOST + help + Say Y here if you are using the TinCanTools Hammer Board + <http://www.tincantools.com> +@@ -128,7 +136,27 @@ + config MACH_QT2410 + bool "QT2410" + select CPU_S3C2410 ++ select DISPLAY_JBT6K74 + help + Say Y here if you are using the Armzone QT2410 + ++config MACH_NEO1973_GTA01 ++ bool "FIC Neo1973 GSM Phone (GTA01 Hardware)" ++ select CPU_S3C2410 ++ select MACH_NEO1973 ++ select S3C_DEV_USB_HOST ++ select MFD_PCF50606 ++ select INPUT_PCF50606_PMU ++ select PCF50606_ADC ++ select PCF50606_GPIO ++ select RTC_DRV_PCF50606 ++ select REGULATOR_PCF50606 ++ select CHARGER_PCF50606 ++ select PCF50606_WATCHDOG ++ select POWER_SUPPLY ++ select BATTERY_GTA01 ++ ++ help ++ Say Y here if you are using the FIC Neo1973 GSM Phone ++ + endmenu +diff -ruN --exclude='*.orig' --exclude='*.rej' linux-2.6.29-rc3.owrt/arch/arm/mach-s3c2410/mach-gta01.c linux-2.6.29-rc3.owrt.om/arch/arm/mach-s3c2410/mach-gta01.c +--- linux-2.6.29-rc3.owrt/arch/arm/mach-s3c2410/mach-gta01.c 1970-01-01 01:00:00.000000000 +0100 ++++ linux-2.6.29-rc3.owrt.om/arch/arm/mach-s3c2410/mach-gta01.c 2009-05-10 22:27:59.000000000 +0200 +@@ -0,0 +1,1008 @@ ++/* ++ * linux/arch/arm/mach-s3c2410/mach-gta01.c ++ * ++ * S3C2410 Machine Support for the FIC Neo1973 GTA01 ++ * ++ * Copyright (C) 2006-2007 by Openmoko, Inc. ++ * Author: Harald Welte <laforge@openmoko.org> ++ * All rights reserved. ++ * ++ * 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, ++ * MA 02111-1307 USA ++ * ++ */ ++ ++#include <linux/kernel.h> ++#include <linux/types.h> ++#include <linux/interrupt.h> ++#include <linux/list.h> ++#include <linux/timer.h> ++#include <linux/init.h> ++#include <linux/workqueue.h> ++#include <linux/platform_device.h> ++#include <linux/i2c.h> ++#include <linux/serial_core.h> ++#include <mach/ts.h> ++#include <linux/spi/spi.h> ++#include <linux/spi/spi_bitbang.h> ++#include <linux/mmc/mmc.h> ++#include <linux/mmc/host.h> ++ ++#include <linux/mtd/mtd.h> ++#include <linux/mtd/nand.h> ++#include <linux/mtd/nand_ecc.h> ++#include <linux/mtd/partitions.h> ++ ++#include <linux/mmc/host.h> ++ ++#include <linux/mfd/pcf50606/core.h> ++#include <linux/mfd/pcf50606/pmic.h> ++#include <linux/mfd/pcf50606/mbc.h> ++#include <linux/mfd/pcf50606/adc.h> ++ ++#include <linux/gta01_battery.h> ++ ++#include <linux/regulator/machine.h> ++#include <linux/regulator/consumer.h> ++ ++ ++#include <asm/mach/arch.h> ++#include <asm/mach/map.h> ++#include <asm/mach/irq.h> ++ ++#include <mach/hardware.h> ++#include <mach/io.h> ++#include <asm/irq.h> ++#include <asm/mach-types.h> ++ ++#include <mach/regs-gpio.h> ++#include <mach/fb.h> ++#include <mach/spi.h> ++#include <mach/spi-gpio.h> ++#include <mach/cpu.h> ++ ++#include <mach/gta01.h> ++ ++#include <plat/regs-serial.h> ++#include <plat/nand.h> ++#include <plat/devs.h> ++#include <plat/cpu.h> ++#include <plat/pm.h> ++#include <plat/udc.h> ++#include <plat/iic.h> ++#include <plat/mci.h> ++#include <asm/plat-s3c24xx/neo1973.h> ++#include <plat/usb-control.h> ++#include <mach/neo1973-pm-gsm.h> ++ ++#include <linux/jbt6k74.h> ++ ++#include <../drivers/input/touchscreen/ts_filter_chain.h> ++#ifdef CONFIG_TOUCHSCREEN_FILTER ++#include <../drivers/input/touchscreen/ts_filter_linear.h> ++#include <../drivers/input/touchscreen/ts_filter_mean.h> ++#include <../drivers/input/touchscreen/ts_filter_median.h> ++#include <../drivers/input/touchscreen/ts_filter_group.h> ++#endif ++ ++ ++static struct map_desc gta01_iodesc[] __initdata = { ++ { ++ .virtual = 0xe0000000, ++ .pfn = __phys_to_pfn(S3C2410_CS3+0x01000000), ++ .length = SZ_1M, ++ .type = MT_DEVICE ++ }, ++}; ++ ++#define UCON S3C2410_UCON_DEFAULT ++#define ULCON S3C2410_LCON_CS8 | S3C2410_LCON_PNONE | S3C2410_LCON_STOPB ++#define UFCON S3C2410_UFCON_RXTRIG8 | S3C2410_UFCON_FIFOMODE ++/* UFCON for the gta01 sets the FIFO trigger level at 4, not 8 */ ++#define UFCON_GTA01_PORT0 S3C2410_UFCON_FIFOMODE ++ ++static struct s3c2410_uartcfg gta01_uartcfgs[] = { ++ [0] = { ++ .hwport = 0, ++ .flags = 0, ++ .ucon = UCON, ++ .ulcon = ULCON, ++ .ufcon = UFCON_GTA01_PORT0, ++ }, ++ [1] = { ++ .hwport = 1, ++ .flags = 0, ++ .ucon = UCON, ++ .ulcon = ULCON, ++ .ufcon = UFCON, ++ }, ++}; ++ ++/* TODO */ ++static void gta01_pmu_event_callback(struct pcf50606 *pcf, int irq) ++{ ++ /*TODO : Handle ACD here */ ++} ++ ++/* FIXME : Goes away when ACD is handled above */ ++#if 0 ++static int pmu_callback(struct device *dev, unsigned int feature, ++ enum pmu_event event) ++{ ++ switch (feature) { ++ case PCF50606_FEAT_ACD: ++ switch (event) { ++ case PMU_EVT_INSERT: ++ pcf50606_charge_fast(pcf50606_global, 1); ++ break; ++ case PMU_EVT_REMOVE: ++ pcf50606_charge_fast(pcf50606_global, 0); ++ break; ++ default: ++ break; ++ } ++ break; ++ default: ++ break; ++ } ++ ++ return 0; ++} ++#endif ++ ++struct pcf50606 *gta01_pcf; ++ ++static struct platform_device gta01_pm_gsm_dev = { ++ .name = "neo1973-pm-gsm", ++}; ++ ++static struct platform_device gta01_pm_bt_dev = { ++ .name = "neo1973-pm-bt", ++}; ++static struct platform_device gta01_pm_gps_dev = { ++ .name = "neo1973-pm-gps", ++}; ++ ++static struct regulator_consumer_supply ioreg_consumers[] = { ++ { ++ .dev = >a01_pm_gps_dev.dev, ++ .supply = "GPS_2V8", ++ }, ++}; ++ ++static struct regulator_consumer_supply d1reg_consumers[] = { ++ { ++ .dev = >a01_pm_gps_dev.dev, ++ .supply = "GPS_3V", ++ }, ++ { ++ .dev = >a01_pm_bt_dev.dev, ++ .supply = "BT_3V1", ++ }, ++}; ++ ++static struct regulator_consumer_supply dcd_consumers[] = { ++ { ++ .dev = >a01_pm_gps_dev.dev, ++ .supply = "GPS_3V3", ++ }, ++ { ++ .dev = >a01_pm_gps_dev.dev, ++ .supply = "GPS_1V5", ++ }, ++}; ++ ++static struct regulator_consumer_supply d2reg_consumers[] = { ++ { ++ .dev = >a01_pm_gps_dev.dev, ++ .supply = "GPS_2V5", ++ }, ++ { ++ .dev = &s3c_device_sdi.dev, ++ .supply = "SD_3V3", ++ }, ++}; ++ ++static int gta01_bat_get_charging_status(void) ++{ ++ struct pcf50606 *pcf = gta01_pcf; ++ u8 mbcc1, chgmod; ++ ++ mbcc1 = pcf50606_reg_read(pcf, PCF50606_REG_MBCC1); ++ chgmod = mbcc1 & PCF50606_MBCC1_CHGMOD_MASK; ++ ++ if (chgmod == PCF50606_MBCC1_CHGMOD_IDLE) ++ return 0; ++ else ++ return 1; ++} ++ ++static int gta01_bat_get_voltage(void) ++{ ++ struct pcf50606 *pcf = gta01_pcf; ++ u16 adc, mv = 0; ++ ++ adc = pcf50606_adc_sync_read(pcf, PCF50606_ADCMUX_BATVOLT_RES); ++ mv = (adc * 6000) / 1024; ++ ++ return mv; ++} ++ ++static int gta01_bat_get_current(void) ++{ ++ struct pcf50606 *pcf = gta01_pcf; ++ u16 adc_battvolt, adc_adcin1; ++ s32 res; ++ ++ adc_battvolt = pcf50606_adc_sync_read(pcf, PCF50606_ADCMUX_BATVOLT_SUBTR); ++ adc_adcin1 = pcf50606_adc_sync_read(pcf, PCF50606_ADCMUX_ADCIN1_SUBTR); ++ res = (adc_adcin1 - adc_battvolt) * 2400; ++ ++ /*rsense is 220 milli */ ++ return (res * 1000) / (220 * 1024); ++} ++ ++static struct gta01_bat_platform_data gta01_bat_pdata = { ++ .get_charging_status = gta01_bat_get_charging_status, ++ .get_voltage = gta01_bat_get_voltage, ++ .get_current = gta01_bat_get_current, ++}; ++ ++struct platform_device gta01_bat = { ++ .name = "gta01_battery", ++ .id = -1, ++ .dev = { ++ .platform_data = >a01_bat_pdata, ++ } ++}; ++ ++static void gta01_pcf_probe_done(struct pcf50606 *pcf) ++{ ++ gta01_pcf = pcf; ++ gta01_bat.dev.parent = pcf->dev; ++ platform_device_register(>a01_bat); ++} ++ ++static int gps_registered_regulators = 0; ++ ++static void gta01_pmu_regulator_registered(struct pcf50606 *pcf, int id) ++{ ++ switch(id) { ++ case PCF50606_REGULATOR_D1REG: ++ platform_device_register(>a01_pm_bt_dev); ++ gps_registered_regulators++; ++ break; ++ case PCF50606_REGULATOR_D2REG: ++ gps_registered_regulators++; ++ break; ++ case PCF50606_REGULATOR_IOREG: ++ case PCF50606_REGULATOR_DCD: ++ gps_registered_regulators++; ++ break; ++ } ++ ++ /* All GPS related regulators registered ? */ ++ if (gps_registered_regulators == 4) ++ platform_device_register(>a01_pm_gps_dev); ++ ++} ++ ++static struct pcf50606_platform_data gta01_pcf_pdata = { ++ .resumers = { ++ [0] = PCF50606_INT1_ALARM | ++ PCF50606_INT1_ONKEYF | ++ PCF50606_INT1_EXTONR, ++ [1] = PCF50606_INT2_CHGWD10S | ++ PCF50606_INT2_CHGPROT | ++ PCF50606_INT2_CHGERR, ++ [2] = PCF50606_INT3_LOWBAT | ++ PCF50606_INT3_HIGHTMP | ++ PCF50606_INT3_ACDINS, ++ }, ++ .mbc_event_callback = gta01_pmu_event_callback, ++ .reg_init_data = { ++ [PCF50606_REGULATOR_D1REG] = { ++ .constraints = { ++ .min_uV = 3000000, ++ .max_uV = 3150000, ++ .valid_modes_mask = REGULATOR_MODE_NORMAL, ++ .apply_uV = 1, ++ }, ++ .num_consumer_supplies = ARRAY_SIZE(d1reg_consumers), ++ .consumer_supplies = d1reg_consumers, ++ }, ++ ++ [PCF50606_REGULATOR_D2REG] = { ++ .constraints = { ++ .min_uV = 1650000, ++ .max_uV = 3300000, ++ .valid_modes_mask = REGULATOR_MODE_NORMAL, ++ .valid_ops_mask = REGULATOR_CHANGE_VOLTAGE, ++ .apply_uV = 1, ++ }, ++ .num_consumer_supplies = ARRAY_SIZE(d2reg_consumers), ++ .consumer_supplies = d2reg_consumers, ++ ++ }, ++ ++ [PCF50606_REGULATOR_D3REG] = { ++ .constraints = { ++ .min_uV = 1800000, ++ .max_uV = 2100000, ++ .valid_modes_mask = REGULATOR_MODE_NORMAL, ++ .state_mem = { ++ .enabled = 1, ++ }, ++ }, ++ .num_consumer_supplies = 0, ++ }, ++ ++ [PCF50606_REGULATOR_DCD] = { ++ .constraints = { ++ .min_uV = 1500000, ++ .max_uV = 1500000, ++ .valid_modes_mask = REGULATOR_MODE_NORMAL, ++ .apply_uV = 1, ++ }, ++ .num_consumer_supplies = ARRAY_SIZE(dcd_consumers), ++ .consumer_supplies = dcd_consumers, ++ }, ++ ++ [PCF50606_REGULATOR_DCDE] = { ++ .constraints = { ++ .min_uV = 3300000, ++ .max_uV = 3300000, ++ .valid_modes_mask = REGULATOR_MODE_NORMAL, ++ .apply_uV = 1, ++ .state_mem = { ++ .enabled = 1, ++ }, ++ }, ++ .num_consumer_supplies = 0, ++ }, ++ ++ [PCF50606_REGULATOR_DCUD] = { ++ .constraints = { ++ .min_uV = 2100000, ++ .max_uV = 2100000, ++ .valid_modes_mask = REGULATOR_MODE_NORMAL, ++ .apply_uV = 1, ++ .state_mem = { ++ .enabled = 1, ++ }, ++ }, ++ .num_consumer_supplies = 0, ++ }, ++ ++ [PCF50606_REGULATOR_IOREG] = { ++ .constraints = { ++ .min_uV = 3300000, ++ .max_uV = 3300000, ++ .valid_modes_mask = REGULATOR_MODE_NORMAL, ++ .apply_uV = 1, ++ }, ++ .num_consumer_supplies = ARRAY_SIZE(ioreg_consumers), ++ .consumer_supplies = ioreg_consumers, ++ ++ }, ++ ++ [PCF50606_REGULATOR_LPREG] = { ++ .constraints = { ++ .min_uV = 3300000, ++ .max_uV = 3300000, ++ .valid_modes_mask = REGULATOR_MODE_NORMAL, ++ .apply_uV = 1, ++ }, ++ .num_consumer_supplies = 0, ++ }, ++ }, ++ .probe_done = gta01_pcf_probe_done, ++ .regulator_registered = gta01_pmu_regulator_registered, ++}; ++ ++static void cfg_pmu_vrail(struct regulator_init_data *vrail, ++ unsigned int suspend_on, unsigned int min, ++ unsigned int max) ++{ ++ vrail->constraints.state_mem.enabled = suspend_on; ++ vrail->constraints.min_uV = min; ++ vrail->constraints.max_uV = min; ++ vrail->constraints.apply_uV = 1; ++} ++ ++static void mangle_pmu_pdata_by_system_rev(void) ++{ ++ struct regulator_init_data *reg_init_data; ++ ++ reg_init_data = gta01_pcf_pdata.reg_init_data; ++ ++ switch (S3C_SYSTEM_REV_ATAG) { ++ case GTA01Bv4_SYSTEM_REV: ++ ++ /* FIXME : gta01_pcf_pdata.used_features |= PCF50606_FEAT_ACD; */ ++ break; ++ case GTA01Bv3_SYSTEM_REV: ++ case GTA01Bv2_SYSTEM_REV: ++ reg_init_data[PCF50606_REGULATOR_D3REG].constraints.state_mem.enabled = 1; ++ break; ++ case GTA01v4_SYSTEM_REV: ++ cfg_pmu_vrail(®_init_data[PCF50606_REGULATOR_DCUD], ++ 1, 18000000, 1800000); ++ cfg_pmu_vrail(®_init_data[PCF50606_REGULATOR_D1REG], ++ 0, 3000000, 3000000); ++ cfg_pmu_vrail(®_init_data[PCF50606_REGULATOR_D3REG], ++ 0, 2800000, 2800000); ++ cfg_pmu_vrail(®_init_data[PCF50606_REGULATOR_DCD], ++ 0, 3500000, 3500000); ++ break; ++ case GTA01v3_SYSTEM_REV: ++ cfg_pmu_vrail(®_init_data[PCF50606_REGULATOR_D1REG], ++ 0, 3000000, 3000000); ++ cfg_pmu_vrail(®_init_data[PCF50606_REGULATOR_D2REG], ++ 0, 3300000, 3300000); ++ cfg_pmu_vrail(®_init_data[PCF50606_REGULATOR_D3REG], ++ 0, 3300000, 3300000); ++ cfg_pmu_vrail(®_init_data[PCF50606_REGULATOR_DCD], ++ 0, 3300000, 3300000); ++ cfg_pmu_vrail(®_init_data[PCF50606_REGULATOR_DCUD], ++ 1, 1800000, 1800000); ++ cfg_pmu_vrail(®_init_data[PCF50606_REGULATOR_IOREG], ++ 0, 2800000, 2800000); ++ break; ++ } ++} ++ ++static void gta01_power_off(void) ++{ ++ pcf50606_reg_write(gta01_pcf, PCF50606_REG_OOCC1, ++ PCF50606_OOCC1_GOSTDBY); ++} ++ ++/* LCD driver info */ ++ ++/* Configuration for 480x640 toppoly TD028TTEC1. ++ * Do not mark this as __initdata or it will break! */ ++static struct s3c2410fb_display gta01_displays[] = { ++ { ++ .type = S3C2410_LCDCON1_TFT, ++ .width = 43, ++ .height = 58, ++ .xres = 480, ++ .yres = 640, ++ .bpp = 16, ++ ++ .pixclock = 40000, /* HCLK/4 */ ++ .left_margin = 104, ++ .right_margin = 8, ++ .hsync_len = 8, ++ .upper_margin = 2, ++ .lower_margin = 16, ++ .vsync_len = 2, ++ .lcdcon5 = S3C2410_LCDCON5_FRM565 | ++ S3C2410_LCDCON5_INVVCLK | ++ S3C2410_LCDCON5_INVVLINE | ++ S3C2410_LCDCON5_INVVFRAME | ++ S3C2410_LCDCON5_PWREN | ++ S3C2410_LCDCON5_HWSWP, ++ }, ++ { ++ .type = S3C2410_LCDCON1_TFT, ++ .width = 43, ++ .height = 58, ++ .xres = 480, ++ .yres = 640, ++ .bpp = 32, ++ ++ .pixclock = 40000, /* HCLK/4 */ ++ .left_margin = 104, ++ .right_margin = 8, ++ .hsync_len = 8, ++ .upper_margin = 2, ++ .lower_margin = 16, ++ .vsync_len = 2, ++ .lcdcon5 = S3C2410_LCDCON5_FRM565 | ++ S3C2410_LCDCON5_INVVCLK | ++ S3C2410_LCDCON5_INVVLINE | ++ S3C2410_LCDCON5_INVVFRAME | ++ S3C2410_LCDCON5_PWREN | ++ S3C2410_LCDCON5_HWSWP, ++ }, ++ { ++ .type = S3C2410_LCDCON1_TFT, ++ .width = 43, ++ .height = 58, ++ .xres = 240, ++ .yres = 320, ++ .bpp = 16, ++ ++ .pixclock = 40000, /* HCLK/4 */ ++ .left_margin = 104, ++ .right_margin = 8, ++ .hsync_len = 8, ++ .upper_margin = 2, ++ .lower_margin = 16, ++ .vsync_len = 2, ++ .lcdcon5 = S3C2410_LCDCON5_FRM565 | ++ S3C2410_LCDCON5_INVVCLK | ++ S3C2410_LCDCON5_INVVLINE | ++ S3C2410_LCDCON5_INVVFRAME | ++ S3C2410_LCDCON5_PWREN | ++ S3C2410_LCDCON5_HWSWP, ++ }, ++}; ++ ++static struct s3c2410fb_mach_info gta01_lcd_cfg __initdata = { ++ .displays = gta01_displays, ++ .num_displays = ARRAY_SIZE(gta01_displays), ++ .default_display = 0, ++ ++ .lpcsel = ((0xCE6) & ~7) | 1<<4, ++}; ++ ++static struct platform_device *gta01_devices[] __initdata = { ++ &s3c_device_usb, ++ &s3c_device_lcd, ++ &s3c_device_wdt, ++ &s3c_device_i2c0, ++ &s3c_device_iis, ++ &s3c_device_sdi, ++ &s3c_device_usbgadget, ++ &s3c_device_nand, ++ &s3c_device_ts, ++}; ++ ++static struct s3c2410_nand_set gta01_nand_sets[] = { ++ [0] = { ++ .name = "neo1973-nand", ++ .nr_chips = 1, ++ .flags = S3C2410_NAND_BBT, ++ }, ++}; ++ ++static struct s3c2410_platform_nand gta01_nand_info = { ++ .tacls = 20, ++ .twrph0 = 60, ++ .twrph1 = 20, ++ .nr_sets = ARRAY_SIZE(gta01_nand_sets), ++ .sets = gta01_nand_sets, ++}; ++ ++static struct regulator *s3c_sdi_regulator; ++ ++static void gta01_mmc_set_power(unsigned char power_mode, unsigned short vdd) ++{ ++ int bit; ++ int mv = 1700; /* 1.7V for MMC_VDD_165_195 */ ++ struct regulator *regulator; ++ ++ printk(KERN_DEBUG "mmc_set_power(power_mode=%u, vdd=%u)\n", ++ power_mode, vdd); ++ ++ if (!s3c_sdi_regulator) { ++ s3c_sdi_regulator = ++ regulator_get(&s3c_device_sdi.dev, "SD_3V3"); ++ if (!s3c_sdi_regulator) { ++ printk(KERN_ERR "gta01_mmc_set_power : Cannot get regulator"); ++ return; ++ } ++ } ++ ++ regulator = s3c_sdi_regulator; ++ ++ return; ++ switch (S3C_SYSTEM_REV_ATAG) { ++ case GTA01v3_SYSTEM_REV: ++ switch (power_mode) { ++ case MMC_POWER_OFF: ++ regulator_disable(regulator); ++ break; ++ case MMC_POWER_ON: ++ /* translate MMC_VDD_* VDD bit to mv */ ++ for (bit = 8; bit != 24; bit++) ++ if (vdd == (1 << bit)) ++ mv += 100 * (bit - 4); ++ regulator_set_voltage(regulator, mv * 1000, mv * 10000); ++ break; ++ case MMC_POWER_UP: ++ regulator_enable(regulator); ++ break; ++ } ++ break; ++ case GTA01v4_SYSTEM_REV: ++ case GTA01Bv2_SYSTEM_REV: ++ case GTA01Bv3_SYSTEM_REV: ++ case GTA01Bv4_SYSTEM_REV: ++ switch (power_mode) { ++ case MMC_POWER_OFF: ++ neo1973_gpb_setpin(GTA01_GPIO_SDMMC_ON, 1); ++ break; ++ case MMC_POWER_ON: ++ neo1973_gpb_setpin(GTA01_GPIO_SDMMC_ON, 0); ++ break; ++ } ++ break; ++ } ++ ++ if (regulator) ++ regulator_put(regulator); ++} ++ ++static struct s3c24xx_mci_pdata gta01_mmc_cfg = { ++ .gpio_detect = GTA01_GPIO_nSD_DETECT, ++ .set_power = >a01_mmc_set_power, ++ .ocr_avail = MMC_VDD_165_195|MMC_VDD_20_21| ++ MMC_VDD_21_22|MMC_VDD_22_23|MMC_VDD_23_24| ++ MMC_VDD_24_25|MMC_VDD_25_26|MMC_VDD_26_27| ++ MMC_VDD_27_28|MMC_VDD_28_29|MMC_VDD_29_30| ++ MMC_VDD_30_31|MMC_VDD_31_32|MMC_VDD_32_33, ++}; ++ ++static void gta01_udc_command(enum s3c2410_udc_cmd_e cmd) ++{ ++ printk(KERN_DEBUG "%s(%d)\n", __func__, cmd); ++ ++ switch (cmd) { ++ case S3C2410_UDC_P_ENABLE: ++ neo1973_gpb_setpin(GTA01_GPIO_USB_PULLUP, 1); ++ break; ++ case S3C2410_UDC_P_DISABLE: ++ neo1973_gpb_setpin(GTA01_GPIO_USB_PULLUP, 0); ++ break; ++ default: ++ break; ++ } ++} ++ ++/* use a work queue, since I2C API inherently schedules ++ * and we get called in hardirq context from UDC driver */ ++ ++struct vbus_draw { ++ struct work_struct work; ++ int ma; ++}; ++static struct vbus_draw gta01_udc_vbus_drawer; ++ ++static void __gta01_udc_vbus_draw(struct work_struct *work) ++{ ++ /* ++ * This is a fix to work around boot-time ordering problems if the ++ * s3c2410_udc is initialized before the pcf50606 driver has defined ++ * pcf50606_global ++ */ ++ if (!gta01_pcf) ++ return; ++ ++ if (gta01_udc_vbus_drawer.ma >= 500) { ++ /* enable fast charge */ ++ printk(KERN_DEBUG "udc: enabling fast charge\n"); ++ pcf50606_charge_fast(gta01_pcf, 1); ++ } else { ++ /* disable fast charge */ ++ printk(KERN_DEBUG "udc: disabling fast charge\n"); ++ pcf50606_charge_fast(gta01_pcf, 0); ++ } ++} ++ ++static void gta01_udc_vbus_draw(unsigned int ma) ++{ ++ gta01_udc_vbus_drawer.ma = ma; ++ schedule_work(>a01_udc_vbus_drawer.work); ++} ++ ++static struct s3c2410_udc_mach_info gta01_udc_cfg = { ++ .vbus_draw = gta01_udc_vbus_draw, ++}; ++ ++/* Touchscreen configuration. */ ++ ++#ifdef CONFIG_TOUCHSCREEN_FILTER ++const static struct ts_filter_group_configuration gta01_ts_group = { ++ .length = 12, ++ .close_enough = 10, ++ .threshold = 6, /* At least half of the points in a group. */ ++ .attempts = 10, ++}; ++ ++const static struct ts_filter_median_configuration gta01_ts_median = { ++ .extent = 20, ++ .decimation_below = 3, ++ .decimation_threshold = 8 * 3, ++ .decimation_above = 4, ++}; ++ ++const static struct ts_filter_mean_configuration gta01_ts_mean = { ++ .length = 4, ++}; ++ ++const static struct ts_filter_linear_configuration gta01_ts_linear = { ++ .constants = {1, 0, 0, 0, 1, 0, 1}, /* Don't modify coords. */ ++ .coord0 = 0, ++ .coord1 = 1, ++}; ++#endif ++ ++const static struct ts_filter_chain_configuration gta01_filter_configuration[] = ++{ ++#ifdef CONFIG_TOUCHSCREEN_FILTER ++ {&ts_filter_group_api, >a01_ts_group.config}, ++ {&ts_filter_median_api, >a01_ts_median.config}, ++ {&ts_filter_mean_api, >a01_ts_mean.config}, ++ {&ts_filter_linear_api, >a01_ts_linear.config}, ++#endif ++ {NULL, NULL}, ++}; ++ ++const static struct s3c2410_ts_mach_info gta01_ts_cfg = { ++ .delay = 10000, ++ .presc = 0xff, /* slow as we can go */ ++ .filter_config = gta01_filter_configuration, ++}; ++ ++/* SPI */ ++ ++static void gta01_jbt6k74_reset(int devidx, int level) ++{ ++ /* empty place holder; gta01 does not yet use this */ ++ printk(KERN_DEBUG "gta01_jbt6k74_reset\n"); ++} ++ ++static void gta01_jbt6k74_resuming(int devidx) ++{ ++ gta01bl_deferred_resume(); ++} ++ ++const struct jbt6k74_platform_data gta01_jbt6k74_pdata = { ++ .reset = gta01_jbt6k74_reset, ++ .resuming = gta01_jbt6k74_resuming, ++}; ++ ++static struct spi_board_info gta01_spi_board_info[] = { ++ { ++ .modalias = "jbt6k74", ++ .platform_data = >a01_jbt6k74_pdata, ++ /* controller_data */ ++ /* irq */ ++ .max_speed_hz = 10 * 1000 * 1000, ++ .bus_num = 1, ++ /* chip_select */ ++ }, ++}; ++ ++static void spi_gpio_cs(struct s3c2410_spigpio_info *spi, int csidx, int cs) ++{ ++ switch (cs) { ++ case BITBANG_CS_ACTIVE: ++ s3c2410_gpio_setpin(S3C2410_GPG3, 0); ++ break; ++ case BITBANG_CS_INACTIVE: ++ s3c2410_gpio_setpin(S3C2410_GPG3, 1); ++ break; ++ } ++} ++ ++static struct s3c2410_spigpio_info spi_gpio_cfg = { ++ .pin_clk = S3C2410_GPG7, ++ .pin_mosi = S3C2410_GPG6, ++ .pin_miso = S3C2410_GPG5, ++ .chip_select = &spi_gpio_cs, ++ .num_chipselect = 2, /*** Should be 1 or 2 for gta01? ***/ ++}; ++ ++static struct resource s3c_spi_lcm_resource[] = { ++ [0] = { ++ .start = S3C2410_GPG3, ++ .end = S3C2410_GPG3, ++ }, ++ [1] = { ++ .start = S3C2410_GPG5, ++ .end = S3C2410_GPG5, ++ }, ++ [2] = { ++ .start = S3C2410_GPG6, ++ .end = S3C2410_GPG6, ++ }, ++ [3] = { ++ .start = S3C2410_GPG7, ++ .end = S3C2410_GPG7, ++ }, ++}; ++ ++struct platform_device s3c_device_spi_lcm = { ++ .name = "spi_s3c24xx_gpio", ++ .id = 1, ++ .num_resources = ARRAY_SIZE(s3c_spi_lcm_resource), ++ .resource = s3c_spi_lcm_resource, ++ .dev = { ++ .platform_data = &spi_gpio_cfg, ++ }, ++}; ++ ++static struct gta01bl_machinfo backlight_machinfo = { ++ .default_intensity = 1, ++ .max_intensity = 1, ++ .limit_mask = 1, ++ .defer_resume_backlight = 1, ++}; ++ ++static struct resource gta01_bl_resources[] = { ++ [0] = { ++ .start = GTA01_GPIO_BACKLIGHT, ++ .end = GTA01_GPIO_BACKLIGHT, ++ }, ++}; ++ ++struct platform_device gta01_bl_dev = { ++ .name = "gta01-bl", ++ .num_resources = ARRAY_SIZE(gta01_bl_resources), ++ .resource = gta01_bl_resources, ++ .dev = { ++ .platform_data = &backlight_machinfo, ++ }, ++}; ++ ++static struct resource gta01_led_resources[] = { ++ [0] = { ++ .start = GTA01_GPIO_VIBRATOR_ON, ++ .end = GTA01_GPIO_VIBRATOR_ON, ++ }, ++}; ++ ++struct platform_device gta01_led_dev = { ++ .name = "neo1973-vibrator", ++ .num_resources = ARRAY_SIZE(gta01_led_resources), ++ .resource = gta01_led_resources, ++}; ++ ++static struct resource gta01_button_resources[] = { ++ [0] = { ++ .start = GTA01_GPIO_AUX_KEY, ++ .end = GTA01_GPIO_AUX_KEY, ++ }, ++ [1] = { ++ .start = GTA01_GPIO_HOLD_KEY, ++ .end = GTA01_GPIO_HOLD_KEY, ++ }, ++ [2] = { ++ .start = GTA01_GPIO_JACK_INSERT, ++ .end = GTA01_GPIO_JACK_INSERT, ++ }, ++}; ++ ++struct platform_device gta01_button_dev = { ++ .name = "neo1973-button", ++ .num_resources = ARRAY_SIZE(gta01_button_resources), ++ .resource = gta01_button_resources, ++}; ++ ++/* USB */ ++static struct s3c2410_hcd_info gta01_usb_info = { ++ .port[0] = { ++ .flags = S3C_HCDFLG_USED, ++ }, ++ .port[1] = { ++ .flags = 0, ++ }, ++}; ++ ++static void __init gta01_map_io(void) ++{ ++ s3c24xx_init_io(gta01_iodesc, ARRAY_SIZE(gta01_iodesc)); ++ s3c24xx_init_clocks(12*1000*1000); ++ s3c24xx_init_uarts(gta01_uartcfgs, ARRAY_SIZE(gta01_uartcfgs)); ++} ++ ++static irqreturn_t gta01_modem_irq(int irq, void *param) ++{ ++ printk(KERN_DEBUG "GSM wakeup interrupt (IRQ %d)\n", irq); ++ gta_gsm_interrupts++; ++ return IRQ_HANDLED; ++} ++ ++static struct i2c_board_info gta01_i2c_devs[] __initdata = { ++ { ++ I2C_BOARD_INFO("pcf50606", 0x08), ++ .irq = GTA01_IRQ_PCF50606, ++ .platform_data = >a01_pcf_pdata, ++ }, ++ { ++ I2C_BOARD_INFO("lm4857", 0x7c), ++ }, ++ { ++ I2C_BOARD_INFO("wm8753", 0x1a), ++ }, ++}; ++ ++static void __init gta01_machine_init(void) ++{ ++ int rc; ++ ++ if (S3C_SYSTEM_REV_ATAG == GTA01v4_SYSTEM_REV || ++ S3C_SYSTEM_REV_ATAG == GTA01Bv2_SYSTEM_REV || ++ S3C_SYSTEM_REV_ATAG == GTA01Bv3_SYSTEM_REV || ++ S3C_SYSTEM_REV_ATAG == GTA01Bv4_SYSTEM_REV) { ++ gta01_udc_cfg.udc_command = gta01_udc_command; ++ gta01_mmc_cfg.ocr_avail = MMC_VDD_32_33; ++ } ++ ++ s3c_device_usb.dev.platform_data = >a01_usb_info; ++ s3c_device_nand.dev.platform_data = >a01_nand_info; ++ s3c_device_sdi.dev.platform_data = >a01_mmc_cfg; ++ ++ s3c24xx_fb_set_platdata(>a01_lcd_cfg); ++ ++ INIT_WORK(>a01_udc_vbus_drawer.work, __gta01_udc_vbus_draw); ++ s3c24xx_udc_set_platdata(>a01_udc_cfg); ++ s3c_i2c0_set_platdata(NULL); ++ set_s3c2410ts_info(>a01_ts_cfg); ++ ++ /* Set LCD_RESET / XRES to high */ ++ s3c2410_gpio_cfgpin(S3C2410_GPC6, S3C2410_GPIO_OUTPUT); ++ s3c2410_gpio_setpin(S3C2410_GPC6, 1); ++ ++ /* SPI chip select is gpio output */ ++ s3c2410_gpio_cfgpin(S3C2410_GPG3, S3C2410_GPIO_OUTPUT); ++ s3c2410_gpio_setpin(S3C2410_GPG3, 1); ++ platform_device_register(&s3c_device_spi_lcm); ++ ++ platform_device_register(>a01_bl_dev); ++ platform_device_register(>a01_button_dev); ++ platform_device_register(>a01_pm_gsm_dev); ++ ++ switch (S3C_SYSTEM_REV_ATAG) { ++ case GTA01v3_SYSTEM_REV: ++ case GTA01v4_SYSTEM_REV: ++ /* just use the default (GTA01_IRQ_PCF50606) */ ++ break; ++ case GTA01Bv2_SYSTEM_REV: ++ case GTA01Bv3_SYSTEM_REV: ++ /* just use the default (GTA01_IRQ_PCF50606) */ ++ gta01_led_resources[0].start = ++ gta01_led_resources[0].end = GTA01Bv2_GPIO_VIBRATOR_ON; ++ break; ++ case GTA01Bv4_SYSTEM_REV: ++ gta01_i2c_devs[0].irq = GTA01Bv4_IRQ_PCF50606; ++ gta01_led_resources[0].start = ++ gta01_led_resources[0].end = GTA01Bv4_GPIO_VIBRATOR_ON; ++ break; ++ } ++ mangle_pmu_pdata_by_system_rev(); ++ i2c_register_board_info(0, gta01_i2c_devs, ARRAY_SIZE(gta01_i2c_devs)); ++ spi_register_board_info(gta01_spi_board_info, ARRAY_SIZE(gta01_spi_board_info)); ++ ++ platform_device_register(>a01_led_dev); ++ ++ platform_add_devices(gta01_devices, ARRAY_SIZE(gta01_devices)); ++ ++ s3c_pm_init(); ++ ++ set_irq_type(GTA01_IRQ_MODEM, IRQ_TYPE_EDGE_RISING); ++ rc = request_irq(GTA01_IRQ_MODEM, gta01_modem_irq, IRQF_DISABLED, ++ "modem", NULL); ++ enable_irq_wake(GTA01_IRQ_MODEM); ++ printk(KERN_DEBUG "Enabled GSM wakeup IRQ %d (rc=%d)\n", ++ GTA01_IRQ_MODEM, rc); ++ ++ pm_power_off = >a01_power_off; ++} ++ ++MACHINE_START(NEO1973_GTA01, "GTA01") ++ .phys_io = S3C2410_PA_UART, ++ .io_pg_offst = (((u32)S3C24XX_VA_UART) >> 18) & 0xfffc, ++ .boot_params = S3C2410_SDRAM_PA + 0x100, ++ .map_io = gta01_map_io, ++ .init_irq = s3c24xx_init_irq, ++ .init_machine = gta01_machine_init, ++ .timer = &s3c24xx_timer, ++MACHINE_END +diff -ruN --exclude='*.orig' --exclude='*.rej' linux-2.6.29-rc3.owrt/arch/arm/mach-s3c2410/mach-h1940.c linux-2.6.29-rc3.owrt.om/arch/arm/mach-s3c2410/mach-h1940.c +--- linux-2.6.29-rc3.owrt/arch/arm/mach-s3c2410/mach-h1940.c 2009-05-10 22:05:04.000000000 +0200 ++++ linux-2.6.29-rc3.owrt.om/arch/arm/mach-s3c2410/mach-h1940.c 2009-05-10 22:27:59.000000000 +0200 +@@ -131,6 +131,11 @@ + .vbus_pin_inverted = 1, + }; + ++static struct s3c2410_ts_mach_info h1940_ts_cfg __initdata = { ++ .delay = 10000, ++ .presc = 49, ++ .oversampling_shift = 2, ++}; + + /** + * Set lcd on or off +@@ -188,6 +193,7 @@ + &s3c_device_i2c0, + &s3c_device_iis, + &s3c_device_usbgadget, ++ &s3c_device_ts, + &s3c_device_leds, + &s3c_device_bluetooth, + }; +@@ -203,7 +209,7 @@ + #ifdef CONFIG_PM_H1940 + memcpy(phys_to_virt(H1940_SUSPEND_RESUMEAT), h1940_pm_return, 1024); + #endif +- s3c2410_pm_init(); ++ s3c_pm_init(); + } + + static void __init h1940_init_irq(void) +@@ -216,6 +222,7 @@ + u32 tmp; + + s3c24xx_fb_set_platdata(&h1940_fb_info); ++ set_s3c2410ts_info(&h1940_ts_cfg); + s3c24xx_udc_set_platdata(&h1940_udc_cfg); + s3c_i2c0_set_platdata(NULL); + +diff -ruN --exclude='*.orig' --exclude='*.rej' linux-2.6.29-rc3.owrt/arch/arm/mach-s3c2410/mach-qt2410.c linux-2.6.29-rc3.owrt.om/arch/arm/mach-s3c2410/mach-qt2410.c +--- linux-2.6.29-rc3.owrt/arch/arm/mach-s3c2410/mach-qt2410.c 2009-05-10 22:05:04.000000000 +0200 ++++ linux-2.6.29-rc3.owrt.om/arch/arm/mach-s3c2410/mach-qt2410.c 2009-05-10 22:27:59.000000000 +0200 +@@ -1,6 +1,6 @@ + /* linux/arch/arm/mach-s3c2410/mach-qt2410.c + * +- * Copyright (C) 2006 by OpenMoko, Inc. ++ * Copyright (C) 2006 by Openmoko, Inc. + * Author: Harald Welte <laforge@openmoko.org> + * All rights reserved. + * +@@ -214,7 +214,7 @@ + + /* SPI */ + +-static void spi_gpio_cs(struct s3c2410_spigpio_info *spi, int cs) ++static void spi_gpio_cs(struct s3c2410_spigpio_info *spi, int csidx, int cs) + { + switch (cs) { + case BITBANG_CS_ACTIVE: +@@ -321,6 +321,24 @@ + + __setup("tft=", qt2410_tft_setup); + ++static struct resource qt2410_button_resources[] = { ++ [0] = { ++ .start = S3C2410_GPF0, ++ .end = S3C2410_GPF0, ++ }, ++ [1] = { ++ .start = S3C2410_GPF2, ++ .end = S3C2410_GPF2, ++ }, ++}; ++ ++struct platform_device qt2410_button_dev = { ++ .name ="qt2410-button", ++ .num_resources = ARRAY_SIZE(qt2410_button_resources), ++ .resource = qt2410_button_resources, ++}; ++ ++ + static void __init qt2410_map_io(void) + { + s3c24xx_init_io(qt2410_iodesc, ARRAY_SIZE(qt2410_iodesc)); +@@ -355,7 +373,7 @@ + s3c2410_gpio_cfgpin(S3C2410_GPB5, S3C2410_GPIO_OUTPUT); + + platform_add_devices(qt2410_devices, ARRAY_SIZE(qt2410_devices)); +- s3c2410_pm_init(); ++ s3c_pm_init(); + } + + MACHINE_START(QT2410, "QT2410") +diff -ruN --exclude='*.orig' --exclude='*.rej' linux-2.6.29-rc3.owrt/arch/arm/mach-s3c2410/Makefile linux-2.6.29-rc3.owrt.om/arch/arm/mach-s3c2410/Makefile +--- linux-2.6.29-rc3.owrt/arch/arm/mach-s3c2410/Makefile 2009-05-10 22:05:04.000000000 +0200 ++++ linux-2.6.29-rc3.owrt.om/arch/arm/mach-s3c2410/Makefile 2009-05-10 22:27:59.000000000 +0200 +@@ -15,6 +15,7 @@ + obj-$(CONFIG_CPU_S3C2410_DMA) += dma.o + obj-$(CONFIG_S3C2410_PM) += pm.o sleep.o + obj-$(CONFIG_S3C2410_GPIO) += gpio.o ++#obj-$(CONFIG_S3C2410_CLOCK) += clock.o + + # Machine support + +@@ -37,3 +38,5 @@ + # machine additions + + obj-$(CONFIG_MACH_BAST_IDE) += bast-ide.o ++obj-$(CONFIG_MACH_NEO1973_GTA01)+= mach-gta01.o ++ +diff -ruN --exclude='*.orig' --exclude='*.rej' linux-2.6.29-rc3.owrt/arch/arm/mach-s3c2410/pm.c linux-2.6.29-rc3.owrt.om/arch/arm/mach-s3c2410/pm.c +--- linux-2.6.29-rc3.owrt/arch/arm/mach-s3c2410/pm.c 2009-05-10 22:05:04.000000000 +0200 ++++ linux-2.6.29-rc3.owrt.om/arch/arm/mach-s3c2410/pm.c 2009-05-10 22:27:59.000000000 +0200 +@@ -37,21 +37,14 @@ + #include <plat/cpu.h> + #include <plat/pm.h> + +-#ifdef CONFIG_S3C2410_PM_DEBUG +-extern void pm_dbg(const char *fmt, ...); +-#define DBG(fmt...) pm_dbg(fmt) +-#else +-#define DBG(fmt...) printk(KERN_DEBUG fmt) +-#endif +- + static void s3c2410_pm_prepare(void) + { + /* ensure at least GSTATUS3 has the resume address */ + +- __raw_writel(virt_to_phys(s3c2410_cpu_resume), S3C2410_GSTATUS3); ++ __raw_writel(virt_to_phys(s3c_cpu_resume), S3C2410_GSTATUS3); + +- DBG("GSTATUS3 0x%08x\n", __raw_readl(S3C2410_GSTATUS3)); +- DBG("GSTATUS4 0x%08x\n", __raw_readl(S3C2410_GSTATUS4)); ++ S3C_PMDBG("GSTATUS3 0x%08x\n", __raw_readl(S3C2410_GSTATUS3)); ++ S3C_PMDBG("GSTATUS4 0x%08x\n", __raw_readl(S3C2410_GSTATUS4)); + + if (machine_is_h1940()) { + void *base = phys_to_virt(H1940_SUSPEND_CHECK); +diff -ruN --exclude='*.orig' --exclude='*.rej' linux-2.6.29-rc3.owrt/arch/arm/mach-s3c2412/dma.c linux-2.6.29-rc3.owrt.om/arch/arm/mach-s3c2412/dma.c +--- linux-2.6.29-rc3.owrt/arch/arm/mach-s3c2412/dma.c 2009-05-10 22:05:04.000000000 +0200 ++++ linux-2.6.29-rc3.owrt.om/arch/arm/mach-s3c2412/dma.c 2009-05-10 22:27:59.000000000 +0200 +@@ -20,17 +20,18 @@ + + #include <mach/dma.h> + +-#include <plat/dma.h> ++#include <plat/dma-plat.h> + #include <plat/cpu.h> + + #include <plat/regs-serial.h> + #include <mach/regs-gpio.h> + #include <plat/regs-ac97.h> ++#include <plat/regs-dma.h> + #include <mach/regs-mem.h> + #include <mach/regs-lcd.h> + #include <mach/regs-sdi.h> +-#include <asm/plat-s3c24xx/regs-s3c2412-iis.h> +-#include <asm/plat-s3c24xx/regs-iis.h> ++#include <plat/regs-s3c2412-iis.h> ++#include <plat/regs-iis.h> + #include <plat/regs-spi.h> + + #define MAP(x) { (x)| DMA_CH_VALID, (x)| DMA_CH_VALID, (x)| DMA_CH_VALID, (x)| DMA_CH_VALID } +diff -ruN --exclude='*.orig' --exclude='*.rej' linux-2.6.29-rc3.owrt/arch/arm/mach-s3c2412/Kconfig linux-2.6.29-rc3.owrt.om/arch/arm/mach-s3c2412/Kconfig +--- linux-2.6.29-rc3.owrt/arch/arm/mach-s3c2412/Kconfig 2009-05-10 22:05:04.000000000 +0200 ++++ linux-2.6.29-rc3.owrt.om/arch/arm/mach-s3c2412/Kconfig 2009-05-10 22:27:59.000000000 +0200 +@@ -38,6 +38,7 @@ + config MACH_JIVE + bool "Logitech Jive" + select CPU_S3C2412 ++ select S3C_DEV_USB_HOST + help + Say Y here if you are using the Logitech Jive. + +@@ -50,6 +51,7 @@ + select CPU_S3C2412 + select MACH_S3C2413 + select MACH_SMDK ++ select S3C_DEV_USB_HOST + help + Say Y here if you are using an SMDK2413 + +@@ -72,6 +74,7 @@ + config MACH_VSTMS + bool "VMSTMS" + select CPU_S3C2412 ++ select S3C_DEV_USB_HOST + help + Say Y here if you are using an VSTMS board + +diff -ruN --exclude='*.orig' --exclude='*.rej' linux-2.6.29-rc3.owrt/arch/arm/mach-s3c2412/mach-jive.c linux-2.6.29-rc3.owrt.om/arch/arm/mach-s3c2412/mach-jive.c +--- linux-2.6.29-rc3.owrt/arch/arm/mach-s3c2412/mach-jive.c 2009-05-10 22:05:04.000000000 +0200 ++++ linux-2.6.29-rc3.owrt.om/arch/arm/mach-s3c2412/mach-jive.c 2009-05-10 22:27:59.000000000 +0200 +@@ -494,7 +494,7 @@ + * correct address to resume from. */ + + __raw_writel(0x2BED, S3C2412_INFORM0); +- __raw_writel(virt_to_phys(s3c2410_cpu_resume), S3C2412_INFORM1); ++ __raw_writel(virt_to_phys(s3c_cpu_resume), S3C2412_INFORM1); + + return 0; + } +@@ -630,7 +630,7 @@ + + /* initialise the power management now we've setup everything. */ + +- s3c2410_pm_init(); ++ s3c_pm_init(); + + s3c_device_nand.dev.platform_data = &jive_nand_info; + +diff -ruN --exclude='*.orig' --exclude='*.rej' linux-2.6.29-rc3.owrt/arch/arm/mach-s3c2412/pm.c linux-2.6.29-rc3.owrt.om/arch/arm/mach-s3c2412/pm.c +--- linux-2.6.29-rc3.owrt/arch/arm/mach-s3c2412/pm.c 2009-05-10 22:05:04.000000000 +0200 ++++ linux-2.6.29-rc3.owrt.om/arch/arm/mach-s3c2412/pm.c 2009-05-10 22:27:59.000000000 +0200 +@@ -85,7 +85,7 @@ + + static int s3c2412_pm_suspend(struct sys_device *dev, pm_message_t state) + { +- s3c2410_pm_do_save(s3c2412_sleep, ARRAY_SIZE(s3c2412_sleep)); ++ s3c_pm_do_save(s3c2412_sleep, ARRAY_SIZE(s3c2412_sleep)); + return 0; + } + +@@ -98,7 +98,7 @@ + tmp |= S3C2412_PWRCFG_STANDBYWFI_IDLE; + __raw_writel(tmp, S3C2412_PWRCFG); + +- s3c2410_pm_do_restore(s3c2412_sleep, ARRAY_SIZE(s3c2412_sleep)); ++ s3c_pm_do_restore(s3c2412_sleep, ARRAY_SIZE(s3c2412_sleep)); + return 0; + } + +diff -ruN --exclude='*.orig' --exclude='*.rej' linux-2.6.29-rc3.owrt/arch/arm/mach-s3c2412/s3c2412.c linux-2.6.29-rc3.owrt.om/arch/arm/mach-s3c2412/s3c2412.c +--- linux-2.6.29-rc3.owrt/arch/arm/mach-s3c2412/s3c2412.c 2009-05-10 22:05:04.000000000 +0200 ++++ linux-2.6.29-rc3.owrt.om/arch/arm/mach-s3c2412/s3c2412.c 2009-05-10 22:27:59.000000000 +0200 +@@ -231,5 +231,8 @@ + { + printk("S3C2412: Initialising architecture\n"); + ++ /* make sure SD/MMC driver can distinguish 2412 from 2410 */ ++ s3c_device_sdi.name = "s3c2412-sdi"; ++ + return sysdev_register(&s3c2412_sysdev); + } +diff -ruN --exclude='*.orig' --exclude='*.rej' linux-2.6.29-rc3.owrt/arch/arm/mach-s3c2440/dma.c linux-2.6.29-rc3.owrt.om/arch/arm/mach-s3c2440/dma.c +--- linux-2.6.29-rc3.owrt/arch/arm/mach-s3c2440/dma.c 2009-05-10 22:05:04.000000000 +0200 ++++ linux-2.6.29-rc3.owrt.om/arch/arm/mach-s3c2440/dma.c 2009-05-10 22:27:59.000000000 +0200 +@@ -17,18 +17,20 @@ + #include <linux/sysdev.h> + #include <linux/serial_core.h> + ++#include <mach/map.h> + #include <mach/dma.h> + +-#include <plat/dma.h> ++#include <plat/dma-plat.h> + #include <plat/cpu.h> + + #include <plat/regs-serial.h> + #include <mach/regs-gpio.h> + #include <plat/regs-ac97.h> ++#include <plat/regs-dma.h> + #include <mach/regs-mem.h> + #include <mach/regs-lcd.h> + #include <mach/regs-sdi.h> +-#include <asm/plat-s3c24xx/regs-iis.h> ++#include <plat/regs-iis.h> + #include <plat/regs-spi.h> + + static struct s3c24xx_dma_map __initdata s3c2440_dma_mappings[] = { +diff -ruN --exclude='*.orig' --exclude='*.rej' linux-2.6.29-rc3.owrt/arch/arm/mach-s3c2440/Kconfig linux-2.6.29-rc3.owrt.om/arch/arm/mach-s3c2440/Kconfig +--- linux-2.6.29-rc3.owrt/arch/arm/mach-s3c2440/Kconfig 2009-05-10 22:05:04.000000000 +0200 ++++ linux-2.6.29-rc3.owrt.om/arch/arm/mach-s3c2440/Kconfig 2009-05-10 22:27:59.000000000 +0200 +@@ -23,7 +23,6 @@ + help + Support for S3C2440 specific DMA code5A + +- + menu "S3C2440 Machines" + + config MACH_ANUBIS +@@ -33,6 +32,7 @@ + select PM_SIMTEC if PM + select HAVE_PATA_PLATFORM + select S3C24XX_GPIO_EXTRA64 ++ select S3C_DEV_USB_HOST + help + Say Y here if you are using the Simtec Electronics ANUBIS + development system +@@ -43,6 +43,7 @@ + select S3C24XX_DCLK + select PM_SIMTEC if PM + select S3C24XX_GPIO_EXTRA128 ++ select S3C_DEV_USB_HOST + help + Say Y here if you are using the Simtec IM2440D20 module, also + known as the Osiris. +@@ -58,12 +59,14 @@ + bool "SMDK2440" + select CPU_S3C2440 + select MACH_SMDK ++ select S3C_DEV_USB_HOST + help + Say Y here if you are using the SMDK2440. + + config MACH_NEXCODER_2440 + bool "NexVision NEXCODER 2440 Light Board" + select CPU_S3C2440 ++ select S3C_DEV_USB_HOST + help + Say Y here if you are using the Nex Vision NEXCODER 2440 Light Board + +@@ -76,8 +79,17 @@ + config MACH_AT2440EVB + bool "Avantech AT2440EVB development board" + select CPU_S3C2440 ++ select S3C_DEV_USB_HOST + help + Say Y here if you are using the AT2440EVB development board + ++config NEO1973_GTA02_2440 ++ bool "Old FIC Neo1973 GTA02 hardware using S3C2440 CPU" ++ depends on MACH_NEO1973_GTA02 ++ select CPU_S3C2440 ++ help ++ Say Y here if you are using an early hardware revision ++ of the FIC/Openmoko Neo1973 GTA02 GSM Phone. ++ + endmenu + +diff -ruN --exclude='*.orig' --exclude='*.rej' linux-2.6.29-rc3.owrt/arch/arm/mach-s3c2440/mach-rx3715.c linux-2.6.29-rc3.owrt.om/arch/arm/mach-s3c2440/mach-rx3715.c +--- linux-2.6.29-rc3.owrt/arch/arm/mach-s3c2440/mach-rx3715.c 2009-05-10 22:05:04.000000000 +0200 ++++ linux-2.6.29-rc3.owrt.om/arch/arm/mach-s3c2440/mach-rx3715.c 2009-05-10 22:27:59.000000000 +0200 +@@ -203,7 +203,7 @@ + #ifdef CONFIG_PM_H1940 + memcpy(phys_to_virt(H1940_SUSPEND_RESUMEAT), h1940_pm_return, 1024); + #endif +- s3c2410_pm_init(); ++ s3c_pm_init(); + + s3c24xx_fb_set_platdata(&rx3715_fb_info); + platform_add_devices(rx3715_devices, ARRAY_SIZE(rx3715_devices)); +diff -ruN --exclude='*.orig' --exclude='*.rej' linux-2.6.29-rc3.owrt/arch/arm/mach-s3c2440/Makefile linux-2.6.29-rc3.owrt.om/arch/arm/mach-s3c2440/Makefile +--- linux-2.6.29-rc3.owrt/arch/arm/mach-s3c2440/Makefile 2009-05-10 22:05:04.000000000 +0200 ++++ linux-2.6.29-rc3.owrt.om/arch/arm/mach-s3c2440/Makefile 2009-05-10 22:27:59.000000000 +0200 +@@ -22,3 +22,5 @@ + obj-$(CONFIG_ARCH_S3C2440) += mach-smdk2440.o + obj-$(CONFIG_MACH_NEXCODER_2440) += mach-nexcoder.o + obj-$(CONFIG_MACH_AT2440EVB) += mach-at2440evb.o ++obj-$(CONFIG_MACH_HXD8) += mach-hxd8.o ++ +diff -ruN --exclude='*.orig' --exclude='*.rej' linux-2.6.29-rc3.owrt/arch/arm/mach-s3c2440/s3c2440.c linux-2.6.29-rc3.owrt.om/arch/arm/mach-s3c2440/s3c2440.c +--- linux-2.6.29-rc3.owrt/arch/arm/mach-s3c2440/s3c2440.c 2009-05-10 22:05:04.000000000 +0200 ++++ linux-2.6.29-rc3.owrt.om/arch/arm/mach-s3c2440/s3c2440.c 2009-05-10 22:27:59.000000000 +0200 +@@ -46,6 +46,9 @@ + s3c_device_wdt.resource[1].start = IRQ_S3C2440_WDT; + s3c_device_wdt.resource[1].end = IRQ_S3C2440_WDT; + ++ /* make sure SD/MMC driver can distinguish 2440 from 2410 */ ++ s3c_device_sdi.name = "s3c2440-sdi"; ++ + /* register our system device for everything else */ + + return sysdev_register(&s3c2440_sysdev); +diff -ruN --exclude='*.orig' --exclude='*.rej' linux-2.6.29-rc3.owrt/arch/arm/mach-s3c2442/include/mach/gta02.h linux-2.6.29-rc3.owrt.om/arch/arm/mach-s3c2442/include/mach/gta02.h +--- linux-2.6.29-rc3.owrt/arch/arm/mach-s3c2442/include/mach/gta02.h 1970-01-01 01:00:00.000000000 +0100 ++++ linux-2.6.29-rc3.owrt.om/arch/arm/mach-s3c2442/include/mach/gta02.h 2009-05-10 22:27:59.000000000 +0200 +@@ -0,0 +1,85 @@ ++#ifndef _GTA02_H ++#define _GTA02_H ++ ++#include <mach/regs-gpio.h> ++#include <mach/irqs.h> ++ ++/* Different hardware revisions, passed in ATAG_REVISION by u-boot */ ++#define GTA02v1_SYSTEM_REV 0x00000310 ++#define GTA02v2_SYSTEM_REV 0x00000320 ++#define GTA02v3_SYSTEM_REV 0x00000330 ++#define GTA02v4_SYSTEM_REV 0x00000340 ++#define GTA02v5_SYSTEM_REV 0x00000350 ++#define GTA02v6_SYSTEM_REV 0x00000360 ++ ++#define GTA02_GPIO_n3DL_GSM S3C2410_GPA13 /* v1 + v2 + v3 only */ ++ ++#define GTA02_GPIO_PWR_LED1 S3C2410_GPB0 ++#define GTA02_GPIO_PWR_LED2 S3C2410_GPB1 ++#define GTA02_GPIO_AUX_LED S3C2410_GPB2 ++#define GTA02_GPIO_VIBRATOR_ON S3C2410_GPB3 ++#define GTA02_GPIO_MODEM_RST S3C2410_GPB5 ++#define GTA02_GPIO_BT_EN S3C2410_GPB6 ++#define GTA02_GPIO_MODEM_ON S3C2410_GPB7 ++#define GTA02_GPIO_EXTINT8 S3C2410_GPB8 ++#define GTA02_GPIO_USB_PULLUP S3C2410_GPB9 ++ ++#define GTA02_GPIO_PIO5 S3C2410_GPC5 /* v3 + v4 only */ ++#define GTA02v3_GPIO_nG1_CS S3C2410_GPD12 /* v3 + v4 only */ ++#define GTA02v3_GPIO_nG2_CS S3C2410_GPD13 /* v3 + v4 only */ ++#define GTA02v5_GPIO_HDQ S3C2410_GPD14 /* v5 + */ ++ ++#define GTA02_GPIO_nG1_INT S3C2410_GPF0 ++#define GTA02_GPIO_IO1 S3C2410_GPF1 ++#define GTA02_GPIO_PIO_2 S3C2410_GPF2 /* v2 + v3 + v4 only */ ++#define GTA02_GPIO_JACK_INSERT S3C2410_GPF4 ++#define GTA02_GPIO_WLAN_GPIO1 S3C2410_GPF5 /* v2 + v3 + v4 only */ ++#define GTA02_GPIO_AUX_KEY S3C2410_GPF6 ++#define GTA02_GPIO_HOLD_KEY S3C2410_GPF7 ++ ++#define GTA02_GPIO_3D_IRQ S3C2410_GPG4 ++#define GTA02v2_GPIO_nG2_INT S3C2410_GPG8 /* v2 + v3 + v4 only */ ++#define GTA02v3_GPIO_nUSB_OC S3C2410_GPG9 /* v3 + v4 only */ ++#define GTA02v3_GPIO_nUSB_FLT S3C2410_GPG10 /* v3 + v4 only */ ++#define GTA02v3_GPIO_nGSM_OC S3C2410_GPG11 /* v3 + v4 only */ ++ ++#define GTA02_GPIO_AMP_SHUT S3C2440_GPJ1 /* v2 + v3 + v4 only */ ++#define GTA02v1_GPIO_WLAN_GPIO10 S3C2440_GPJ2 ++#define GTA02_GPIO_HP_IN S3C2440_GPJ2 /* v2 + v3 + v4 only */ ++#define GTA02_GPIO_INT0 S3C2440_GPJ3 /* v2 + v3 + v4 only */ ++#define GTA02_GPIO_nGSM_EN S3C2440_GPJ4 ++#define GTA02_GPIO_3D_RESET S3C2440_GPJ5 ++#define GTA02_GPIO_nDL_GSM S3C2440_GPJ6 /* v4 + v5 only */ ++#define GTA02_GPIO_WLAN_GPIO0 S3C2440_GPJ7 ++#define GTA02v1_GPIO_BAT_ID S3C2440_GPJ8 ++#define GTA02_GPIO_KEEPACT S3C2440_GPJ8 ++#define GTA02v1_GPIO_HP_IN S3C2440_GPJ10 ++#define GTA02_CHIP_PWD S3C2440_GPJ11 /* v2 + v3 + v4 only */ ++#define GTA02_GPIO_nWLAN_RESET S3C2440_GPJ12 /* v2 + v3 + v4 only */ ++ ++#define GTA02_IRQ_GSENSOR_1 IRQ_EINT0 ++#define GTA02_IRQ_MODEM IRQ_EINT1 ++#define GTA02_IRQ_PIO_2 IRQ_EINT2 /* v2 + v3 + v4 only */ ++#define GTA02_IRQ_nJACK_INSERT IRQ_EINT4 ++#define GTA02_IRQ_WLAN_GPIO1 IRQ_EINT5 ++#define GTA02_IRQ_AUX IRQ_EINT6 ++#define GTA02_IRQ_nHOLD IRQ_EINT7 ++#define GTA02_IRQ_PCF50633 IRQ_EINT9 ++#define GTA02_IRQ_3D IRQ_EINT12 ++#define GTA02_IRQ_GSENSOR_2 IRQ_EINT16 /* v2 + v3 + v4 only */ ++#define GTA02v3_IRQ_nUSB_OC IRQ_EINT17 /* v3 + v4 only */ ++#define GTA02v3_IRQ_nUSB_FLT IRQ_EINT18 /* v3 + v4 only */ ++#define GTA02v3_IRQ_nGSM_OC IRQ_EINT19 /* v3 + v4 only */ ++ ++/* returns 00 000 on GTA02 A5 and earlier, A6 returns 01 001 */ ++#define GTA02_PCB_ID1_0 S3C2410_GPC13 ++#define GTA02_PCB_ID1_1 S3C2410_GPC15 ++#define GTA02_PCB_ID1_2 S3C2410_GPD0 ++#define GTA02_PCB_ID2_0 S3C2410_GPD3 ++#define GTA02_PCB_ID2_1 S3C2410_GPD4 ++ ++int gta02_get_pcb_revision(void); ++ ++extern struct pcf50633 *gta02_pcf; ++ ++#endif /* _GTA02_H */ +diff -ruN --exclude='*.orig' --exclude='*.rej' linux-2.6.29-rc3.owrt/arch/arm/mach-s3c2442/Kconfig linux-2.6.29-rc3.owrt.om/arch/arm/mach-s3c2442/Kconfig +--- linux-2.6.29-rc3.owrt/arch/arm/mach-s3c2442/Kconfig 2009-05-10 22:05:02.000000000 +0200 ++++ linux-2.6.29-rc3.owrt.om/arch/arm/mach-s3c2442/Kconfig 2009-05-10 22:27:59.000000000 +0200 +@@ -11,6 +11,7 @@ + select S3C2410_CLOCK + select S3C2410_GPIO + select S3C2410_PM if PM ++ select S3C2440_DMA if S3C2410_DMA + select CPU_S3C244X + select CPU_LLSERIAL_S3C2440 + help +@@ -24,6 +25,20 @@ + depends on ARCH_S3C2440 + select CPU_S3C2442 + ++config MACH_NEO1973_GTA02 ++ bool "FIC Neo1973 GSM Phone (GTA02 Hardware)" ++ select CPU_S3C2442 ++ select MFD_PCF50633 ++ select PCF50633_GPIO ++ select I2C ++ select POWER_SUPPLY ++ select MACH_NEO1973 ++ select S3C_PWM ++ select FIQ ++ select S3C_DEV_USB_HOST ++ help ++ Say Y here if you are using the FIC Neo1973 GSM Phone ++ + + endmenu + +diff -ruN --exclude='*.orig' --exclude='*.rej' linux-2.6.29-rc3.owrt/arch/arm/mach-s3c2442/mach-gta02.c linux-2.6.29-rc3.owrt.om/arch/arm/mach-s3c2442/mach-gta02.c +--- linux-2.6.29-rc3.owrt/arch/arm/mach-s3c2442/mach-gta02.c 1970-01-01 01:00:00.000000000 +0100 ++++ linux-2.6.29-rc3.owrt.om/arch/arm/mach-s3c2442/mach-gta02.c 2009-05-10 22:27:59.000000000 +0200 +@@ -0,0 +1,1706 @@ ++/* ++ * linux/arch/arm/mach-s3c2440/mach-gta02.c ++ * ++ * S3C2440 Machine Support for the FIC GTA02 (Neo1973) ++ * ++ * Copyright (C) 2006-2007 by Openmoko, Inc. ++ * Author: Harald Welte <laforge@openmoko.org> ++ * All rights reserved. ++ * ++ * 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, ++ * MA 02111-1307 USA ++ * ++ */ ++ ++#include <linux/kernel.h> ++#include <linux/types.h> ++#include <linux/interrupt.h> ++#include <linux/list.h> ++#include <linux/delay.h> ++#include <linux/timer.h> ++#include <linux/init.h> ++#include <linux/workqueue.h> ++#include <linux/platform_device.h> ++#include <linux/serial_core.h> ++#include <linux/spi/spi.h> ++#include <linux/spi/glamo.h> ++#include <linux/spi/spi_bitbang.h> ++#include <linux/mmc/host.h> ++ ++#include <linux/mtd/mtd.h> ++#include <linux/mtd/nand.h> ++#include <linux/mtd/nand_ecc.h> ++#include <linux/mtd/partitions.h> ++#include <linux/mtd/physmap.h> ++ ++#include <linux/i2c.h> ++#include <linux/backlight.h> ++#include <linux/regulator/machine.h> ++ ++#include <linux/mfd/pcf50633/core.h> ++#include <linux/mfd/pcf50633/mbc.h> ++#include <linux/mfd/pcf50633/adc.h> ++#include <linux/mfd/pcf50633/gpio.h> ++#include <linux/mfd/pcf50633/pmic.h> ++ ++#include <linux/lis302dl.h> ++ ++#include <asm/mach/arch.h> ++#include <asm/mach/map.h> ++#include <asm/mach/irq.h> ++ ++#include <mach/hardware.h> ++#include <mach/io.h> ++#include <asm/irq.h> ++#include <asm/mach-types.h> ++ ++#include <mach/regs-irq.h> ++#include <mach/regs-gpio.h> ++#include <mach/regs-gpioj.h> ++#include <mach/fb.h> ++#include <mach/mci.h> ++#include <mach/ts.h> ++#include <mach/spi.h> ++#include <mach/spi-gpio.h> ++#include <mach/regs-mem.h> ++#include <mach/spi-gpio.h> ++#include <plat/pwm.h> ++#include <mach/cpu.h> ++ ++#include <mach/gta02.h> ++ ++#include <plat/regs-serial.h> ++#include <plat/nand.h> ++#include <plat/devs.h> ++#include <plat/cpu.h> ++#include <plat/pm.h> ++#include <plat/udc.h> ++#include <plat/iic.h> ++#include <plat/usb-control.h> ++#include <asm/plat-s3c24xx/neo1973.h> ++#include <mach/neo1973-pm-gsm.h> ++#include <mach/gta02-pm-wlan.h> ++#include <plat/regs-timer.h> ++ ++#include <linux/jbt6k74.h> ++ ++#include <linux/glamofb.h> ++ ++#include <linux/hdq.h> ++#include <linux/bq27000_battery.h> ++ ++#include "../plat-s3c24xx/neo1973_pm_gps.h" ++ ++#include <../drivers/input/touchscreen/ts_filter_chain.h> ++#ifdef CONFIG_TOUCHSCREEN_FILTER ++#include <../drivers/input/touchscreen/ts_filter_linear.h> ++#include <../drivers/input/touchscreen/ts_filter_mean.h> ++#include <../drivers/input/touchscreen/ts_filter_median.h> ++#include <../drivers/input/touchscreen/ts_filter_group.h> ++#endif ++ ++#include <asm/fiq.h> ++ ++#include <linux/neo1973_vibrator.h> ++ ++/* arbitrates which sensor IRQ owns the shared SPI bus */ ++static spinlock_t motion_irq_lock; ++ ++ ++/* ------------------------------------------------------------------------------- ++ * GTA02 FIQ related ++ * ++ * Calls into vibrator and hdq and based on the return values ++ * determines if we the FIQ source be kept alive ++ */ ++ ++#define DIVISOR_FROM_US(x) ((x) << 3) ++ ++#ifdef CONFIG_HDQ_GPIO_BITBANG ++#define FIQ_DIVISOR_HDQ DIVISOR_FROM_US(HDQ_SAMPLE_PERIOD_US) ++extern int hdq_fiq_handler(void); ++#endif ++ ++#ifdef CONFIG_LEDS_NEO1973_VIBRATOR ++#define FIQ_DIVISOR_VIBRATOR DIVISOR_FROM_US(100) ++extern int neo1973_vibrator_fiq_handler(void); ++#endif ++ ++/* Global data related to our fiq source */ ++static u32 gta02_fiq_ack_mask; ++static struct s3c2410_pwm gta02_fiq_pwm_timer; ++static u16 gta02_fiq_timer_index; ++static int gta02_fiq_irq; ++ ++static void gta02_fiq_handler(void) ++{ ++ u16 divisor = 0xffff; ++ ++ /* Vibrator servicing */ ++ ++ /* disable further timer interrupts if nobody has any work ++ * or adjust rate according to who still has work ++ * ++ * CAUTION: it means forground code must disable FIQ around ++ * its own non-atomic S3C2410_INTMSK changes... not common ++ * thankfully and taken care of by the fiq-basis patch ++ */ ++ ++#ifdef CONFIG_LEDS_NEO1973_VIBRATOR ++ if (neo1973_vibrator_fiq_handler()) ++ divisor = FIQ_DIVISOR_VIBRATOR; ++#endif ++ ++#ifdef CONFIG_HDQ_GPIO_BITBANG ++ if (hdq_fiq_handler()) ++ divisor = FIQ_DIVISOR_HDQ; ++#endif ++ ++ if (divisor == 0xffff) /* mask the fiq irq source */ ++ __raw_writel(__raw_readl(S3C2410_INTMSK) | gta02_fiq_ack_mask, ++ S3C2410_INTMSK); ++ else /* still working, maybe at a different rate */ ++ __raw_writel(divisor, S3C2410_TCNTB(gta02_fiq_timer_index)); ++ ++ __raw_writel(gta02_fiq_ack_mask, S3C2410_SRCPND); ++} ++ ++static void gta02_fiq_kick(void) ++{ ++ unsigned long flags; ++ u32 tcon; ++ ++ /* we have to take care about FIQ because this modification is ++ * non-atomic, FIQ could come in after the read and before the ++ * writeback and its changes to the register would be lost ++ * (platform INTMSK mod code is taken care of already) ++ */ ++ local_save_flags(flags); ++ local_fiq_disable(); ++ /* allow FIQs to resume */ ++ __raw_writel(__raw_readl(S3C2410_INTMSK) & ++ ~(1 << (gta02_fiq_irq - S3C2410_CPUIRQ_OFFSET)), ++ S3C2410_INTMSK); ++ tcon = __raw_readl(S3C2410_TCON) & ~S3C2410_TCON_T3START; ++ /* fake the timer to a count of 1 */ ++ __raw_writel(1, S3C2410_TCNTB(gta02_fiq_timer_index)); ++ __raw_writel(tcon | S3C2410_TCON_T3MANUALUPD, S3C2410_TCON); ++ __raw_writel(tcon | S3C2410_TCON_T3MANUALUPD | S3C2410_TCON_T3START, ++ S3C2410_TCON); ++ __raw_writel(tcon | S3C2410_TCON_T3START, S3C2410_TCON); ++ local_irq_restore(flags); ++} ++ ++static int gta02_fiq_enable(void) ++{ ++ int irq_index_fiq = IRQ_TIMER3; ++ int rc = 0; ++ ++ local_fiq_disable(); ++ ++ gta02_fiq_irq = irq_index_fiq; ++ gta02_fiq_ack_mask = 1 << (irq_index_fiq - S3C2410_CPUIRQ_OFFSET); ++ gta02_fiq_timer_index = (irq_index_fiq - IRQ_TIMER0); ++ ++ /* set up the timer to operate as a pwm device */ ++ ++ rc = s3c2410_pwm_init(>a02_fiq_pwm_timer); ++ if (rc) ++ goto bail; ++ ++ gta02_fiq_pwm_timer.timerid = PWM0 + gta02_fiq_timer_index; ++ gta02_fiq_pwm_timer.prescaler = (6 - 1) / 2; ++ gta02_fiq_pwm_timer.divider = S3C2410_TCFG1_MUX3_DIV2; ++ /* default rate == ~32us */ ++ gta02_fiq_pwm_timer.counter = gta02_fiq_pwm_timer.comparer = 3000; ++ ++ rc = s3c2410_pwm_enable(>a02_fiq_pwm_timer); ++ if (rc) ++ goto bail; ++ ++ s3c2410_pwm_start(>a02_fiq_pwm_timer); ++ ++ /* let our selected interrupt be a magic FIQ interrupt */ ++ __raw_writel(gta02_fiq_ack_mask, S3C2410_INTMOD); ++ ++ /* it's ready to go as soon as we unmask the source in S3C2410_INTMSK */ ++ local_fiq_enable(); ++ ++ set_fiq_c_handler(gta02_fiq_handler); ++ ++ return 0; ++ ++bail: ++ printk(KERN_ERR "Could not initialize FIQ for GTA02: %d\n", rc); ++ ++ return rc; ++} ++ ++static void gta02_fiq_disable(void) ++{ ++ __raw_writel(0, S3C2410_INTMOD); ++ local_fiq_disable(); ++ gta02_fiq_irq = 0; /* no active source interrupt now either */ ++ ++} ++/* -------------------- /GTA02 FIQ Handler ------------------------------------- */ ++ ++/* ++ * this gets called every 1ms when we paniced. ++ */ ++ ++static long gta02_panic_blink(long count) ++{ ++ long delay = 0; ++ static long last_blink; ++ static char led; ++ ++ if (count - last_blink < 100) /* 200ms period, fast blink */ ++ return 0; ++ ++ led ^= 1; ++ s3c2410_gpio_cfgpin(GTA02_GPIO_AUX_LED, S3C2410_GPIO_OUTPUT); ++ neo1973_gpb_setpin(GTA02_GPIO_AUX_LED, led); ++ ++ last_blink = count; ++ return delay; ++} ++ ++ ++/** ++ * returns PCB revision information in b9,b8 and b2,b1,b0 ++ * Pre-GTA02 A6 returns 0x000 ++ * GTA02 A6 returns 0x101 ++ * ... ++ */ ++ ++int gta02_get_pcb_revision(void) ++{ ++ int n; ++ int u = 0; ++ static unsigned long pinlist[] = { ++ GTA02_PCB_ID1_0, ++ GTA02_PCB_ID1_1, ++ GTA02_PCB_ID1_2, ++ GTA02_PCB_ID2_0, ++ GTA02_PCB_ID2_1, ++ }; ++ static int pin_offset[] = { ++ 0, 1, 2, 8, 9 ++ }; ++ ++ for (n = 0 ; n < ARRAY_SIZE(pinlist); n++) { ++ /* ++ * set the PCB version GPIO to be pulled-down input ++ * force low briefly first ++ */ ++ s3c2410_gpio_cfgpin(pinlist[n], S3C2410_GPIO_OUTPUT); ++ s3c2410_gpio_setpin(pinlist[n], 0); ++ /* misnomer: it is a pullDOWN in 2442 */ ++ s3c2410_gpio_pullup(pinlist[n], 1); ++ s3c2410_gpio_cfgpin(pinlist[n], S3C2410_GPIO_INPUT); ++ ++ udelay(10); ++ ++ if (s3c2410_gpio_getpin(pinlist[n])) ++ u |= 1 << pin_offset[n]; ++ ++ /* ++ * when not being interrogated, all of the revision GPIO ++ * are set to output HIGH without pulldown so no current flows ++ * if they are NC or pulled up. ++ */ ++ s3c2410_gpio_setpin(pinlist[n], 1); ++ s3c2410_gpio_cfgpin(pinlist[n], S3C2410_GPIO_OUTPUT); ++ /* misnomer: it is a pullDOWN in 2442 */ ++ s3c2410_gpio_pullup(pinlist[n], 0); ++ } ++ ++ return u; ++} ++ ++struct platform_device gta02_version_device = { ++ .name = "neo1973-version", ++ .num_resources = 0, ++}; ++ ++struct platform_device gta02_resume_reason_device = { ++ .name = "neo1973-resume", ++ .num_resources = 0, ++}; ++ ++struct platform_device gta02_memconfig_device = { ++ .name = "neo1973-memconfig", ++ .num_resources = 0, ++}; ++ ++static struct map_desc gta02_iodesc[] __initdata = { ++ { ++ .virtual = 0xe0000000, ++ .pfn = __phys_to_pfn(S3C2410_CS3+0x01000000), ++ .length = SZ_1M, ++ .type = MT_DEVICE ++ }, ++}; ++ ++#define UCON (S3C2410_UCON_DEFAULT | S3C2443_UCON_RXERR_IRQEN) ++#define ULCON S3C2410_LCON_CS8 | S3C2410_LCON_PNONE | S3C2410_LCON_STOPB ++#define UFCON S3C2410_UFCON_RXTRIG8 | S3C2410_UFCON_FIFOMODE ++ ++static struct s3c2410_uartcfg gta02_uartcfgs[] = { ++ [0] = { ++ .hwport = 0, ++ .flags = 0, ++ .ucon = UCON, ++ .ulcon = ULCON, ++ .ufcon = UFCON, ++ }, ++ [1] = { ++ .hwport = 1, ++ .flags = 0, ++ .ucon = UCON, ++ .ulcon = ULCON, ++ .ufcon = UFCON, ++ }, ++ [2] = { ++ .hwport = 2, ++ .flags = 0, ++ .ucon = UCON, ++ .ulcon = ULCON, ++ .ufcon = UFCON, ++ }, ++ ++}; ++ ++struct pcf50633 *gta02_pcf; ++ ++#ifdef CONFIG_CHARGER_PCF50633 ++static int gta02_get_charger_online_status(void) ++{ ++ struct pcf50633 *pcf = gta02_pcf; ++ ++ return pcf50633_mbc_get_status(pcf) & PCF50633_MBC_USB_ONLINE; ++} ++ ++static int gta02_get_charger_active_status(void) ++{ ++ struct pcf50633 *pcf = gta02_pcf; ++ ++ return pcf50633_mbc_get_status(pcf) & PCF50633_MBC_USB_ACTIVE; ++} ++ ++#define ADC_NOM_CHG_DETECT_1A 6 ++#define ADC_NOM_CHG_DETECT_USB 43 ++ ++static void ++gta02_configure_pmu_for_charger(struct pcf50633 *pcf, void *unused, int res) ++{ ++ int ma; ++ ++ /* Interpret charger type */ ++ if (res < ((ADC_NOM_CHG_DETECT_USB + ADC_NOM_CHG_DETECT_1A) / 2)) { ++ ++ /* Stop GPO driving out now that we have a IA charger */ ++ pcf50633_gpio_set(pcf, PCF50633_GPO, 0); ++ ++ ma = 1000; ++ } else ++ ma = 100; ++ ++ pcf50633_mbc_usb_curlim_set(pcf, ma); ++} ++ ++static struct delayed_work gta02_charger_work; ++static int gta02_usb_vbus_draw; ++ ++static void gta02_charger_worker(struct work_struct *work) ++{ ++ struct pcf50633 *pcf = gta02_pcf; ++ ++ if (gta02_usb_vbus_draw) { ++ pcf50633_mbc_usb_curlim_set(pcf, gta02_usb_vbus_draw); ++ return; ++ } else { ++#ifdef CONFIG_PCF50633_ADC ++ pcf50633_adc_async_read(pcf, ++ PCF50633_ADCC1_MUX_ADCIN1, ++ PCF50633_ADCC1_AVERAGE_16, ++ gta02_configure_pmu_for_charger, NULL); ++#else ++ /* If the PCF50633 ADC is disabled we fallback to a 100mA limit for safety. */ ++ pcf50633_mbc_usb_curlim_set(pcf, 100); ++#endif ++ return; ++ } ++} ++ ++#define GTA02_CHARGER_CONFIGURE_TIMEOUT ((3000 * HZ) / 1000) ++static void gta02_pmu_event_callback(struct pcf50633 *pcf, int irq) ++{ ++ if (irq == PCF50633_IRQ_USBINS) { ++ schedule_delayed_work(>a02_charger_work, ++ GTA02_CHARGER_CONFIGURE_TIMEOUT); ++ return; ++ } else if (irq == PCF50633_IRQ_USBREM) { ++ cancel_delayed_work_sync(>a02_charger_work); ++ gta02_usb_vbus_draw = 0; ++ } ++} ++ ++static void gta02_pmu_force_shutdown(struct pcf50633 *pcf) ++{ ++ pcf50633_reg_set_bit_mask(pcf, PCF50633_REG_OOCSHDWN, ++ PCF50633_OOCSHDWN_GOSTDBY, PCF50633_OOCSHDWN_GOSTDBY); ++} ++ ++ ++static void gta02_udc_vbus_draw(unsigned int ma) ++{ ++ if (!gta02_pcf) ++ return; ++ ++ gta02_usb_vbus_draw = ma; ++ ++ schedule_delayed_work(>a02_charger_work, ++ GTA02_CHARGER_CONFIGURE_TIMEOUT); ++} ++#else /* !CONFIG_CHARGER_PCF50633 */ ++#define gta02_get_charger_online_status NULL ++#define gta02_get_charger_active_status NULL ++#define gta02_pmu_event_callback NULL ++#define gta02_udc_vbus_draw NULL ++#endif ++ ++static struct platform_device gta01_pm_gps_dev = { ++ .name = "neo1973-pm-gps", ++}; ++ ++static struct platform_device gta01_pm_bt_dev = { ++ .name = "neo1973-pm-bt", ++}; ++ ++static struct platform_device gta02_pm_gsm_dev = { ++ .name = "neo1973-pm-gsm", ++}; ++ ++/* this is called when pc50633 is probed, unfortunately quite late in the ++ * day since it is an I2C bus device. Here we can belatedly define some ++ * platform devices with the advantage that we can mark the pcf50633 as the ++ * parent. This makes them get suspended and resumed with their parent ++ * the pcf50633 still around. ++ */ ++ ++static struct platform_device gta02_glamo_dev; ++static void mangle_glamo_res_by_system_rev(void); ++ ++static void gta02_pmu_attach_child_devices(struct pcf50633 *pcf); ++static void gta02_pmu_regulator_registered(struct pcf50633 *pcf, int id); ++ ++static struct platform_device gta02_pm_wlan_dev = { ++ .name = "gta02-pm-wlan", ++}; ++ ++static struct regulator_consumer_supply ldo4_consumers[] = { ++ { ++ .dev = >a01_pm_bt_dev.dev, ++ .supply = "BT_3V2", ++ }, ++}; ++ ++static struct regulator_consumer_supply ldo5_consumers[] = { ++ { ++ .dev = >a01_pm_gps_dev.dev, ++ .supply = "RF_3V", ++ }, ++}; ++ ++/* ++ * We need this dummy thing to fill the regulator consumers ++ */ ++static struct platform_device gta02_mmc_dev = { ++ /* details filled in by glamo core */ ++}; ++ ++static struct regulator_consumer_supply hcldo_consumers[] = { ++ { ++ .dev = >a02_mmc_dev.dev, ++ .supply = "SD_3V3", ++ }, ++}; ++ ++static char *gta02_batteries[] = { ++ "battery", ++}; ++ ++struct pcf50633_platform_data gta02_pcf_pdata = { ++ .resumers = { ++ [0] = PCF50633_INT1_USBINS | ++ PCF50633_INT1_USBREM | ++ PCF50633_INT1_ALARM, ++ [1] = PCF50633_INT2_ONKEYF, ++ [2] = PCF50633_INT3_ONKEY1S, ++ [3] = PCF50633_INT4_LOWSYS | ++ PCF50633_INT4_LOWBAT | ++ PCF50633_INT4_HIGHTMP, ++ }, ++ ++ .batteries = gta02_batteries, ++ .num_batteries = ARRAY_SIZE(gta02_batteries), ++ .charging_restart_interval = (900 * HZ), ++ .chg_ref_current_ma = 1000, ++ ++ .reg_init_data = { ++ [PCF50633_REGULATOR_AUTO] = { ++ .constraints = { ++ .name = "IO_3V3", ++ .min_uV = 3300000, ++ .max_uV = 3300000, ++ .valid_modes_mask = REGULATOR_MODE_NORMAL, ++ .boot_on = 1, ++ .apply_uV = 1, ++ .state_mem = { ++ .enabled = 1, ++ }, ++ }, ++ .num_consumer_supplies = 0, ++ }, ++ [PCF50633_REGULATOR_DOWN1] = { ++ .constraints = { ++ .name = "CORE_1V3", ++ .min_uV = 1300000, ++ .max_uV = 1600000, ++ .valid_modes_mask = REGULATOR_MODE_NORMAL, ++ .boot_on = 1, ++ .apply_uV = 1, ++ }, ++ .num_consumer_supplies = 0, ++ }, ++ [PCF50633_REGULATOR_DOWN2] = { ++ .constraints = { ++ .name = "IO_1V8", ++ .min_uV = 1800000, ++ .max_uV = 1800000, ++ .valid_modes_mask = REGULATOR_MODE_NORMAL, ++ .apply_uV = 1, ++ .boot_on = 1, ++ .state_mem = { ++ .enabled = 1, ++ }, ++ }, ++ .num_consumer_supplies = 0, ++ }, ++ [PCF50633_REGULATOR_HCLDO] = { ++ .constraints = { ++ .name = "SD_3V3", ++ .min_uV = 2000000, ++ .max_uV = 3300000, ++ .valid_modes_mask = REGULATOR_MODE_NORMAL, ++ .valid_ops_mask = REGULATOR_CHANGE_VOLTAGE, ++ .boot_on = 1, ++ }, ++ .num_consumer_supplies = 1, ++ .consumer_supplies = hcldo_consumers, ++ }, ++ [PCF50633_REGULATOR_LDO1] = { ++ .constraints = { ++ .name = "GSENSOR_3V3", ++ .min_uV = 1300000, ++ .max_uV = 1300000, ++ .valid_modes_mask = REGULATOR_MODE_NORMAL, ++ .apply_uV = 1, ++ }, ++ .num_consumer_supplies = 0, ++ }, ++ [PCF50633_REGULATOR_LDO2] = { ++ .constraints = { ++ .name = "CODEC_3V3", ++ .min_uV = 3300000, ++ .max_uV = 3300000, ++ .valid_modes_mask = REGULATOR_MODE_NORMAL, ++ .apply_uV = 1, ++ }, ++ .num_consumer_supplies = 0, ++ }, ++ [PCF50633_REGULATOR_LDO3] = { ++ .constraints = { ++ .min_uV = 3000000, ++ .max_uV = 3000000, ++ .valid_modes_mask = REGULATOR_MODE_NORMAL, ++ .apply_uV = 1, ++ }, ++ .num_consumer_supplies = 0, ++ }, ++ [PCF50633_REGULATOR_LDO4] = { ++ .constraints = { ++ .name = "BT_3V2", ++ .min_uV = 3200000, ++ .max_uV = 3200000, ++ .valid_modes_mask = REGULATOR_MODE_NORMAL, ++ .apply_uV = 1, ++ }, ++ .num_consumer_supplies = 1, ++ .consumer_supplies = ldo4_consumers, ++ }, ++ [PCF50633_REGULATOR_LDO5] = { ++ .constraints = { ++ .name = "RF_3V", ++ .min_uV = 1500000, ++ .max_uV = 1500000, ++ .valid_modes_mask = REGULATOR_MODE_NORMAL, ++ .apply_uV = 1, ++ .state_mem = { ++ .enabled = 1, ++ }, ++ }, ++ .num_consumer_supplies = 1, ++ .consumer_supplies = ldo5_consumers, ++ }, ++ [PCF50633_REGULATOR_LDO6] = { ++ .constraints = { ++ .name = "LCM_3V", ++ .min_uV = 0, ++ .max_uV = 3300000, ++ .valid_modes_mask = REGULATOR_MODE_NORMAL, ++ }, ++ .num_consumer_supplies = 0, ++ }, ++ [PCF50633_REGULATOR_MEMLDO] = { ++ .constraints = { ++ .min_uV = 1800000, ++ .max_uV = 1800000, ++ .valid_modes_mask = REGULATOR_MODE_NORMAL, ++ .state_mem = { ++ .enabled = 1, ++ }, ++ }, ++ .num_consumer_supplies = 0, ++ }, ++ ++ }, ++ .probe_done = gta02_pmu_attach_child_devices, ++ .regulator_registered = gta02_pmu_regulator_registered, ++ .mbc_event_callback = gta02_pmu_event_callback, ++ .force_shutdown = gta02_pmu_force_shutdown, ++}; ++ ++static void mangle_pmu_pdata_by_system_rev(void) ++{ ++ struct regulator_init_data *reg_init_data; ++ ++ reg_init_data = gta02_pcf_pdata.reg_init_data; ++ ++ switch (S3C_SYSTEM_REV_ATAG) { ++ case GTA02v1_SYSTEM_REV: ++ /* FIXME: this is only in v1 due to wrong PMU variant */ ++ reg_init_data[PCF50633_REGULATOR_DOWN2] ++ .constraints.state_mem.enabled = 1; ++ break; ++ case GTA02v2_SYSTEM_REV: ++ case GTA02v3_SYSTEM_REV: ++ case GTA02v4_SYSTEM_REV: ++ case GTA02v5_SYSTEM_REV: ++ case GTA02v6_SYSTEM_REV: ++ reg_init_data[PCF50633_REGULATOR_LDO1] ++ .constraints.min_uV = 3300000; ++ reg_init_data[PCF50633_REGULATOR_LDO1] ++ .constraints.min_uV = 3300000; ++ reg_init_data[PCF50633_REGULATOR_LDO1] ++ .constraints.state_mem.enabled = 0; ++ ++ reg_init_data[PCF50633_REGULATOR_LDO5] ++ .constraints.min_uV = 3000000; ++ reg_init_data[PCF50633_REGULATOR_LDO5] ++ .constraints.max_uV = 3000000; ++ ++ reg_init_data[PCF50633_REGULATOR_LDO6] ++ .constraints.min_uV = 3000000; ++ reg_init_data[PCF50633_REGULATOR_LDO6] ++ .constraints.max_uV = 3000000; ++ reg_init_data[PCF50633_REGULATOR_LDO6] ++ .constraints.apply_uV = 1; ++ break; ++ default: ++ break; ++ } ++} ++ ++#ifdef CONFIG_HDQ_GPIO_BITBANG ++/* BQ27000 Battery */ ++ ++struct bq27000_platform_data bq27000_pdata = { ++ .name = "battery", ++ .rsense_mohms = 20, ++ .hdq_read = hdq_read, ++ .hdq_write = hdq_write, ++ .hdq_initialized = hdq_initialized, ++ .get_charger_online_status = gta02_get_charger_online_status, ++ .get_charger_active_status = gta02_get_charger_active_status ++}; ++ ++struct platform_device bq27000_battery_device = { ++ .name = "bq27000-battery", ++ .dev = { ++ .platform_data = &bq27000_pdata, ++ }, ++}; ++ ++/* HDQ */ ++ ++static void gta02_hdq_attach_child_devices(struct device *parent_device) ++{ ++ switch (S3C_SYSTEM_REV_ATAG) { ++ case GTA02v5_SYSTEM_REV: ++ case GTA02v6_SYSTEM_REV: ++ bq27000_battery_device.dev.parent = parent_device; ++ platform_device_register(&bq27000_battery_device); ++ break; ++ default: ++ break; ++ } ++} ++ ++static void gta02_hdq_gpio_direction_out(void) ++{ ++ s3c2410_gpio_cfgpin(GTA02v5_GPIO_HDQ, S3C2410_GPIO_OUTPUT); ++} ++ ++static void gta02_hdq_gpio_direction_in(void) ++{ ++ s3c2410_gpio_cfgpin(GTA02v5_GPIO_HDQ, S3C2410_GPIO_INPUT); ++} ++ ++static void gta02_hdq_gpio_set_value(int val) ++{ ++ ++ s3c2410_gpio_setpin(GTA02v5_GPIO_HDQ, val); ++} ++ ++static int gta02_hdq_gpio_get_value(void) ++{ ++ return s3c2410_gpio_getpin(GTA02v5_GPIO_HDQ); ++} ++ ++static struct resource gta02_hdq_resources[] = { ++ [0] = { ++ .start = GTA02v5_GPIO_HDQ, ++ .end = GTA02v5_GPIO_HDQ, ++ }, ++}; ++ ++struct hdq_platform_data gta02_hdq_platform_data = { ++ .attach_child_devices = gta02_hdq_attach_child_devices, ++ .gpio_dir_out = gta02_hdq_gpio_direction_out, ++ .gpio_dir_in = gta02_hdq_gpio_direction_in, ++ .gpio_set = gta02_hdq_gpio_set_value, ++ .gpio_get = gta02_hdq_gpio_get_value, ++ ++ .enable_fiq = gta02_fiq_enable, ++ .disable_fiq = gta02_fiq_disable, ++ .kick_fiq = gta02_fiq_kick, ++ ++}; ++ ++struct platform_device gta02_hdq_device = { ++ .name = "hdq", ++ .num_resources = 1, ++ .resource = gta02_hdq_resources, ++ .dev = { ++ .platform_data = >a02_hdq_platform_data, ++ }, ++}; ++#endif ++ ++ ++#ifdef CONFIG_LEDS_NEO1973_VIBRATOR ++/* vibrator (child of FIQ) */ ++ ++static struct resource gta02_vibrator_resources[] = { ++ [0] = { ++ .start = GTA02_GPIO_VIBRATOR_ON, ++ .end = GTA02_GPIO_VIBRATOR_ON, ++ }, ++}; ++struct neo1973_vib_platform_data gta02_vib_pdata = { ++ .enable_fiq = gta02_fiq_enable, ++ .disable_fiq = gta02_fiq_disable, ++ .kick_fiq = gta02_fiq_kick, ++}; ++ ++static struct platform_device gta02_vibrator_dev = { ++ .name = "neo1973-vibrator", ++ .num_resources = ARRAY_SIZE(gta02_vibrator_resources), ++ .resource = gta02_vibrator_resources, ++ .dev = { ++ .platform_data = >a02_vib_pdata, ++ }, ++}; ++#endif ++ ++/* NOR Flash */ ++ ++#define GTA02_FLASH_BASE 0x18000000 /* GCS3 */ ++#define GTA02_FLASH_SIZE 0x200000 /* 2MBytes */ ++ ++static struct physmap_flash_data gta02_nor_flash_data = { ++ .width = 2, ++}; ++ ++static struct resource gta02_nor_flash_resource = { ++ .start = GTA02_FLASH_BASE, ++ .end = GTA02_FLASH_BASE + GTA02_FLASH_SIZE - 1, ++ .flags = IORESOURCE_MEM, ++}; ++ ++static struct platform_device gta02_nor_flash = { ++ .name = "physmap-flash", ++ .id = 0, ++ .dev = { ++ .platform_data = >a02_nor_flash_data, ++ }, ++ .resource = >a02_nor_flash_resource, ++ .num_resources = 1, ++}; ++ ++ ++struct platform_device s3c24xx_pwm_device = { ++ .name = "s3c24xx_pwm", ++ .num_resources = 0, ++}; ++ ++static struct i2c_board_info gta02_i2c_devs[] __initdata = { ++ { ++ I2C_BOARD_INFO("pcf50633", 0x73), ++ .irq = GTA02_IRQ_PCF50633, ++ .platform_data = >a02_pcf_pdata, ++ }, ++ { ++ I2C_BOARD_INFO("wm8753", 0x1a), ++ }, ++}; ++ ++static struct s3c2410_nand_set gta02_nand_sets[] = { ++ [0] = { ++ .name = "neo1973-nand", ++ .nr_chips = 1, ++ .flags = S3C2410_NAND_BBT, ++ }, ++}; ++ ++/* choose a set of timings derived from S3C@2442B MCP54 ++ * data sheet (K5D2G13ACM-D075 MCP Memory) ++ */ ++ ++static struct s3c2410_platform_nand gta02_nand_info = { ++ .tacls = 0, ++ .twrph0 = 25, ++ .twrph1 = 15, ++ .nr_sets = ARRAY_SIZE(gta02_nand_sets), ++ .sets = gta02_nand_sets, ++ .software_ecc = 1, ++}; ++ ++ ++static void gta02_s3c_mmc_set_power(unsigned char power_mode, ++ unsigned short vdd) ++{ ++ static int is_on = -1; ++ int on; ++ ++ on = power_mode == MMC_POWER_ON || power_mode == MMC_POWER_UP; ++ if (is_on != on) ++ gta02_wlan_reset(!on); ++ is_on = on; ++} ++ ++ ++static struct s3c24xx_mci_pdata gta02_s3c_mmc_cfg = { ++ .set_power = gta02_s3c_mmc_set_power, ++}; ++ ++static void gta02_udc_command(enum s3c2410_udc_cmd_e cmd) ++{ ++ switch (cmd) { ++ case S3C2410_UDC_P_ENABLE: ++ printk(KERN_DEBUG "%s S3C2410_UDC_P_ENABLE\n", __func__); ++ neo1973_gpb_setpin(GTA02_GPIO_USB_PULLUP, 1); ++ break; ++ case S3C2410_UDC_P_DISABLE: ++ printk(KERN_DEBUG "%s S3C2410_UDC_P_DISABLE\n", __func__); ++ neo1973_gpb_setpin(GTA02_GPIO_USB_PULLUP, 0); ++ break; ++ case S3C2410_UDC_P_RESET: ++ printk(KERN_DEBUG "%s S3C2410_UDC_P_RESET\n", __func__); ++ /* FIXME! */ ++ break; ++ default: ++ break; ++ } ++} ++ ++/* get PMU to set USB current limit accordingly */ ++ ++static struct s3c2410_udc_mach_info gta02_udc_cfg = { ++ .vbus_draw = gta02_udc_vbus_draw, ++ .udc_command = gta02_udc_command, ++ ++}; ++ ++ ++/* Touchscreen configuration. */ ++ ++#ifdef CONFIG_TOUCHSCREEN_FILTER ++const static struct ts_filter_group_configuration gta02_ts_group = { ++ .length = 12, ++ .close_enough = 10, ++ .threshold = 6, /* At least half of the points in a group. */ ++ .attempts = 10, ++}; ++ ++const static struct ts_filter_median_configuration gta02_ts_median = { ++ .extent = 20, ++ .decimation_below = 3, ++ .decimation_threshold = 8 * 3, ++ .decimation_above = 4, ++}; ++ ++const static struct ts_filter_mean_configuration gta02_ts_mean = { ++ .length = 4, ++}; ++ ++const static struct ts_filter_linear_configuration gta02_ts_linear = { ++ .constants = {1, 0, 0, 0, 1, 0, 1}, /* Don't modify coords. */ ++ .coord0 = 0, ++ .coord1 = 1, ++}; ++#endif ++ ++const static struct ts_filter_chain_configuration gta02_filter_configuration[] = ++{ ++#ifdef CONFIG_TOUCHSCREEN_FILTER ++ {&ts_filter_group_api, >a02_ts_group.config}, ++ {&ts_filter_median_api, >a02_ts_median.config}, ++ {&ts_filter_mean_api, >a02_ts_mean.config}, ++ {&ts_filter_linear_api, >a02_ts_linear.config}, ++#endif ++ {NULL, NULL}, ++}; ++ ++const static struct s3c2410_ts_mach_info gta02_ts_cfg = { ++ .delay = 10000, ++ .presc = 0xff, /* slow as we can go */ ++ .filter_config = gta02_filter_configuration, ++}; ++ ++ ++ ++static void gta02_bl_set_intensity(int intensity) ++{ ++ struct pcf50633 *pcf = gta02_pcf; ++ int old_intensity = pcf50633_reg_read(pcf, PCF50633_REG_LEDOUT); ++ int ret; ++ ++ intensity >>= 2; ++ ++ /* ++ * One code path that leads here is from a kernel panic. Trying to turn ++ * the backlight on just gives us a nearly endless stream of complaints ++ * and accomplishes nothing. We can't win. Just give up. ++ * ++ * In the unlikely event that there's another path leading here while ++ * we're atomic, we print at least a warning. ++ */ ++ if (in_atomic()) { ++ printk(KERN_ERR ++ "gta02_bl_set_intensity called while atomic\n"); ++ return; ++ } ++ ++ if (!(pcf50633_reg_read(pcf, PCF50633_REG_LEDENA) & 3)) ++ old_intensity = 0; ++ else ++ old_intensity = pcf50633_reg_read(pcf, PCF50633_REG_LEDOUT); ++ ++ if (intensity == old_intensity) ++ return; ++ ++ /* We can't do this anywhere else */ ++ pcf50633_reg_write(pcf, PCF50633_REG_LEDDIM, 5); ++ ++ /* ++ * The PCF50633 cannot handle LEDOUT = 0 (datasheet p60) ++ * if seen, you have to re-enable the LED unit ++ */ ++ if (!intensity || !old_intensity) ++ pcf50633_reg_write(pcf, PCF50633_REG_LEDENA, 0); ++ ++ if (!intensity) /* illegal to set LEDOUT to 0 */ ++ ret = pcf50633_reg_set_bit_mask(pcf, PCF50633_REG_LEDOUT, 0x3f, ++ 2); ++ else ++ ret = pcf50633_reg_set_bit_mask(pcf, PCF50633_REG_LEDOUT, 0x3f, ++ intensity); ++ ++ if (intensity) ++ pcf50633_reg_write(pcf, PCF50633_REG_LEDENA, 2); ++ ++} ++ ++static struct generic_bl_info gta02_bl_info = { ++ .name = "gta02-bl", ++ .max_intensity = 0xff, ++ .default_intensity = 0xff, ++ .set_bl_intensity = gta02_bl_set_intensity, ++}; ++ ++static struct platform_device gta02_bl_dev = { ++ .name = "generic-bl", ++ .id = 1, ++ .dev = { ++ .platform_data = >a02_bl_info, ++ }, ++}; ++ ++/* SPI: LCM control interface attached to Glamo3362 */ ++ ++static void gta02_jbt6k74_reset(int devidx, int level) ++{ ++ glamo_lcm_reset(level); ++} ++ ++static void gta02_jbt6k74_probe_completed(struct device *dev) ++{ ++ struct pcf50633 *pcf = gta02_pcf; ++ ++ /* Switch on backlight. Qi does not do it for us */ ++ pcf50633_reg_write(pcf, PCF50633_REG_LEDOUT, 0x01); ++ pcf50633_reg_write(pcf, PCF50633_REG_LEDENA, 0x00); ++ pcf50633_reg_write(pcf, PCF50633_REG_LEDDIM, 0x01); ++ pcf50633_reg_write(pcf, PCF50633_REG_LEDENA, 0x01); ++ ++ gta02_bl_dev.dev.parent = dev; ++ platform_device_register(>a02_bl_dev); ++} ++ ++const struct jbt6k74_platform_data jbt6k74_pdata = { ++ .reset = gta02_jbt6k74_reset, ++ .probe_completed = gta02_jbt6k74_probe_completed, ++}; ++ ++#if 0 /* currently this is not used and we use gpio spi */ ++static struct glamo_spi_info glamo_spi_cfg = { ++ .board_size = ARRAY_SIZE(gta02_spi_board_info), ++ .board_info = gta02_spi_board_info, ++}; ++#endif /* 0 */ ++ ++static struct glamo_spigpio_info glamo_spigpio_cfg = { ++ .pin_clk = GLAMO_GPIO10_OUTPUT, ++ .pin_mosi = GLAMO_GPIO11_OUTPUT, ++ .pin_cs = GLAMO_GPIO12_OUTPUT, ++ .pin_miso = 0, ++ .bus_num = 2, ++}; ++ ++/*----------- SPI: Accelerometers attached to SPI of s3c244x ----------------- */ ++ ++void gta02_lis302dl_suspend_io(struct lis302dl_info *lis, int resume) ++{ ++ struct lis302dl_platform_data *pdata = lis->pdata; ++ ++ if (!resume) { ++ /* ++ * we don't want to power them with a high level ++ * because GSENSOR_3V3 is not up during suspend ++ */ ++ s3c2410_gpio_setpin(pdata->pin_chip_select, 0); ++ s3c2410_gpio_setpin(pdata->pin_clk, 0); ++ s3c2410_gpio_setpin(pdata->pin_mosi, 0); ++ /* misnomer: it is a pullDOWN in 2442 */ ++ s3c2410_gpio_pullup(pdata->pin_miso, 1); ++ return; ++ } ++ ++ /* back to normal */ ++ s3c2410_gpio_setpin(pdata->pin_chip_select, 1); ++ s3c2410_gpio_setpin(pdata->pin_clk, 1); ++ /* misnomer: it is a pullDOWN in 2442 */ ++ s3c2410_gpio_pullup(pdata->pin_miso, 0); ++ ++ s3c2410_gpio_cfgpin(pdata->pin_chip_select, S3C2410_GPIO_OUTPUT); ++ s3c2410_gpio_cfgpin(pdata->pin_clk, S3C2410_GPIO_OUTPUT); ++ s3c2410_gpio_cfgpin(pdata->pin_mosi, S3C2410_GPIO_OUTPUT); ++ s3c2410_gpio_cfgpin(pdata->pin_miso, S3C2410_GPIO_INPUT); ++ ++} ++ ++struct lis302dl_platform_data lis302_pdata_top = { ++ .name = "lis302-1 (top)", ++ .pin_chip_select= S3C2410_GPD12, ++ .pin_clk = S3C2410_GPG7, ++ .pin_mosi = S3C2410_GPG6, ++ .pin_miso = S3C2410_GPG5, ++ .interrupt = GTA02_IRQ_GSENSOR_1, ++ .open_drain = 1, /* altered at runtime by PCB rev */ ++ .lis302dl_suspend_io = gta02_lis302dl_suspend_io, ++}; ++ ++struct lis302dl_platform_data lis302_pdata_bottom = { ++ .name = "lis302-2 (bottom)", ++ .pin_chip_select= S3C2410_GPD13, ++ .pin_clk = S3C2410_GPG7, ++ .pin_mosi = S3C2410_GPG6, ++ .pin_miso = S3C2410_GPG5, ++ .interrupt = GTA02_IRQ_GSENSOR_2, ++ .open_drain = 1, /* altered at runtime by PCB rev */ ++ .lis302dl_suspend_io = gta02_lis302dl_suspend_io, ++}; ++ ++static struct spi_board_info gta02_spi_board_info[] = { ++ { ++ .modalias = "jbt6k74", ++ /* platform_data */ ++ .platform_data = &jbt6k74_pdata, ++ /* controller_data */ ++ /* irq */ ++ .max_speed_hz = 100 * 1000, ++ .bus_num = 2, ++ /* chip_select */ ++ }, ++ { ++ .modalias = "lis302dl", ++ /* platform_data */ ++ .platform_data = &lis302_pdata_top, ++ /* controller_data */ ++ /* irq */ ++ .max_speed_hz = 100 * 1000, ++ .bus_num = 3, ++ .chip_select = 0, ++ }, ++ ++ { ++ .modalias = "lis302dl", ++ /* platform_data */ ++ .platform_data = &lis302_pdata_bottom, ++ /* controller_data */ ++ /* irq */ ++ .max_speed_hz = 100 * 1000, ++ .bus_num = 3, ++ .chip_select = 1, ++ }, ++ ++}; ++ ++static void gta02_lis302_chip_select(struct s3c2410_spigpio_info *info, int csid, int cs) ++{ ++ ++ /* ++ * Huh... "quirk"... CS on this device is not really "CS" like you can ++ * expect. ++ * ++ * When it is 0 it selects SPI interface mode. ++ * When it is 1 it selects I2C interface mode. ++ * ++ * Because we have 2 devices on one interface we have to make sure ++ * that the "disabled" device (actually in I2C mode) don't think we're ++ * talking to it. ++ * ++ * When we talk to the "enabled" device, the "disabled" device sees ++ * the clocks as I2C clocks, creating havoc. ++ * ++ * I2C sees MOSI going LOW while CLK HIGH as a START action, thus we ++ * must ensure this is never issued. ++ */ ++ ++ int cs_gpio, other_cs_gpio; ++ ++ cs_gpio = csid ? S3C2410_GPD13 : S3C2410_GPD12; ++ other_cs_gpio = (1 - csid) ? S3C2410_GPD13 : S3C2410_GPD12; ++ ++ ++ if (cs == BITBANG_CS_ACTIVE) { ++ s3c2410_gpio_setpin(other_cs_gpio, 1); ++ s3c2410_gpio_setpin(cs_gpio, 1); ++ s3c2410_gpio_setpin(info->pin_clk, 1); ++ s3c2410_gpio_setpin(cs_gpio, 0); ++ } else { ++ s3c2410_gpio_setpin(cs_gpio, 1); ++ s3c2410_gpio_setpin(other_cs_gpio, 1); ++ } ++} ++ ++static struct s3c2410_spigpio_info gta02_spigpio_cfg = { ++ .pin_clk = S3C2410_GPG7, ++ .pin_mosi = S3C2410_GPG6, ++ .pin_miso = S3C2410_GPG5, ++ .bus_num = 3, ++ .num_chipselect = 2, ++ .chip_select = gta02_lis302_chip_select, ++ .non_blocking_transfer = 1, ++}; ++ ++static struct platform_device gta02_spi_gpio_dev = { ++ .name = "spi_s3c24xx_gpio", ++ .dev = { ++ .platform_data = >a02_spigpio_cfg, ++ }, ++}; ++ ++/*----------- / SPI: Accelerometers attached to SPI of s3c244x ----------------- */ ++ ++static struct resource gta02_led_resources[] = { ++ { ++ .name = "gta02-power:orange", ++ .start = GTA02_GPIO_PWR_LED1, ++ .end = GTA02_GPIO_PWR_LED1, ++ }, { ++ .name = "gta02-power:blue", ++ .start = GTA02_GPIO_PWR_LED2, ++ .end = GTA02_GPIO_PWR_LED2, ++ }, { ++ .name = "gta02-aux:red", ++ .start = GTA02_GPIO_AUX_LED, ++ .end = GTA02_GPIO_AUX_LED, ++ }, ++}; ++ ++struct platform_device gta02_led_dev = { ++ .name = "gta02-led", ++ .num_resources = ARRAY_SIZE(gta02_led_resources), ++ .resource = gta02_led_resources, ++}; ++ ++static struct resource gta02_button_resources[] = { ++ [0] = { ++ .start = GTA02_GPIO_AUX_KEY, ++ .end = GTA02_GPIO_AUX_KEY, ++ }, ++ [1] = { ++ .start = GTA02_GPIO_HOLD_KEY, ++ .end = GTA02_GPIO_HOLD_KEY, ++ }, ++ [2] = { ++ .start = GTA02_GPIO_JACK_INSERT, ++ .end = GTA02_GPIO_JACK_INSERT, ++ }, ++ [3] = { ++ .start = 0, ++ .end = 0, ++ }, ++ [4] = { ++ .start = 0, ++ .end = 0, ++ }, ++}; ++ ++static struct platform_device gta02_button_dev = { ++ .name = "neo1973-button", ++ .num_resources = ARRAY_SIZE(gta02_button_resources), ++ .resource = gta02_button_resources, ++}; ++ ++ ++static struct platform_device gta02_pm_usbhost_dev = { ++ .name = "neo1973-pm-host", ++}; ++ ++ ++/* USB */ ++static struct s3c2410_hcd_info gta02_usb_info = { ++ .port[0] = { ++ .flags = S3C_HCDFLG_USED, ++ }, ++ .port[1] = { ++ .flags = 0, ++ }, ++}; ++ ++static int glamo_irq_is_wired(void) ++{ ++ int rc; ++ int count = 0; ++ ++ /* ++ * GTA02 S-Media IRQs prior to A5 are broken due to a lack of ++ * a pullup on the INT# line. Check for the bad behaviour. ++ */ ++ s3c2410_gpio_setpin(S3C2410_GPG4, 0); ++ s3c2410_gpio_cfgpin(S3C2410_GPG4, S3C2410_GPG4_OUTP); ++ s3c2410_gpio_cfgpin(S3C2410_GPG4, S3C2410_GPG4_INP); ++ /* ++ * we force it low ourselves for a moment and resume being input. ++ * If there is a pullup, it won't stay low for long. But if the ++ * level converter is there as on < A5 revision, the weak keeper ++ * on the input of the LC will hold the line low indefinitiely ++ */ ++ do ++ rc = s3c2410_gpio_getpin(S3C2410_GPG4); ++ while ((!rc) && ((count++) < 10)); ++ if (rc) { /* it got pulled back up, it's good */ ++ printk(KERN_INFO "Detected S-Media IRQ# pullup, " ++ "enabling interrupt\n"); ++ return 0; ++ } else /* Gah we can't work with this level converter */ ++ printk(KERN_WARNING "** Detected bad IRQ# circuit found" ++ " on pre-A5 GTA02: S-Media interrupt disabled **\n"); ++ return -ENODEV; ++} ++ ++static int gta02_glamo_can_set_mmc_power(void) ++{ ++ switch (S3C_SYSTEM_REV_ATAG) { ++ case GTA02v3_SYSTEM_REV: ++ case GTA02v4_SYSTEM_REV: ++ case GTA02v5_SYSTEM_REV: ++ case GTA02v6_SYSTEM_REV: ++ return 1; ++ } ++ ++ return 0; ++} ++ ++/* Smedia Glamo 3362 */ ++ ++/* ++ * we crank down SD Card clock dynamically when GPS is powered ++ */ ++ ++static int gta02_glamo_mci_use_slow(void) ++{ ++ return neo1973_pm_gps_is_on(); ++} ++ ++static void gta02_glamo_external_reset(int level) ++{ ++ s3c2410_gpio_setpin(GTA02_GPIO_3D_RESET, level); ++ s3c2410_gpio_cfgpin(GTA02_GPIO_3D_RESET, S3C2410_GPIO_OUTPUT); ++} ++ ++static struct glamofb_platform_data gta02_glamo_pdata = { ++ .width = 43, ++ .height = 58, ++ /* 24.5MHz --> 40.816ns */ ++ .pixclock = 40816, ++ .left_margin = 8, ++ .right_margin = 16, ++ .upper_margin = 2, ++ .lower_margin = 16, ++ .hsync_len = 8, ++ .vsync_len = 2, ++ .fb_mem_size = 0x400000, /* glamo has 8 megs of SRAM. we use 4 */ ++ .xres = { ++ .min = 240, ++ .max = 640, ++ .defval = 480, ++ }, ++ .yres = { ++ .min = 320, ++ .max = 640, ++ .defval = 640, ++ }, ++ .bpp = { ++ .min = 16, ++ .max = 16, ++ .defval = 16, ++ }, ++ //.spi_info = &glamo_spi_cfg, ++ .spigpio_info = &glamo_spigpio_cfg, ++ ++ /* glamo MMC function platform data */ ++ .mmc_dev = >a02_mmc_dev, ++ .glamo_can_set_mci_power = gta02_glamo_can_set_mmc_power, ++ .glamo_mci_use_slow = gta02_glamo_mci_use_slow, ++ .glamo_irq_is_wired = glamo_irq_is_wired, ++ .glamo_external_reset = gta02_glamo_external_reset ++}; ++ ++static struct resource gta02_glamo_resources[] = { ++ [0] = { ++ .start = S3C2410_CS1, ++ .end = S3C2410_CS1 + 0x1000000 - 1, ++ .flags = IORESOURCE_MEM, ++ }, ++ [1] = { ++ .start = GTA02_IRQ_3D, ++ .end = GTA02_IRQ_3D, ++ .flags = IORESOURCE_IRQ, ++ }, ++ [2] = { ++ .start = GTA02_GPIO_3D_RESET, ++ .end = GTA02_GPIO_3D_RESET, ++ }, ++}; ++ ++static struct platform_device gta02_glamo_dev = { ++ .name = "glamo3362", ++ .num_resources = ARRAY_SIZE(gta02_glamo_resources), ++ .resource = gta02_glamo_resources, ++ .dev = { ++ .platform_data = >a02_glamo_pdata, ++ }, ++}; ++ ++static void mangle_glamo_res_by_system_rev(void) ++{ ++ switch (S3C_SYSTEM_REV_ATAG) { ++ case GTA02v1_SYSTEM_REV: ++ break; ++ default: ++ gta02_glamo_resources[2].start = GTA02_GPIO_3D_RESET; ++ gta02_glamo_resources[2].end = GTA02_GPIO_3D_RESET; ++ break; ++ } ++ ++ switch (S3C_SYSTEM_REV_ATAG) { ++ case GTA02v1_SYSTEM_REV: ++ case GTA02v2_SYSTEM_REV: ++ case GTA02v3_SYSTEM_REV: ++ /* case GTA02v4_SYSTEM_REV: - FIXME: handle this later */ ++ /* The hardware is missing a pull-up resistor and thus can't ++ * support the Smedia Glamo IRQ */ ++ gta02_glamo_resources[1].start = 0; ++ gta02_glamo_resources[1].end = 0; ++ break; ++ } ++} ++ ++static void __init gta02_map_io(void) ++{ ++ s3c24xx_init_io(gta02_iodesc, ARRAY_SIZE(gta02_iodesc)); ++ s3c24xx_init_clocks(12000000); ++ s3c24xx_init_uarts(gta02_uartcfgs, ARRAY_SIZE(gta02_uartcfgs)); ++} ++ ++static irqreturn_t gta02_modem_irq(int irq, void *param) ++{ ++ printk(KERN_DEBUG "modem wakeup interrupt\n"); ++ gta_gsm_interrupts++; ++ return IRQ_HANDLED; ++} ++ ++static irqreturn_t ar6000_wow_irq(int irq, void *param) ++{ ++ printk(KERN_DEBUG "ar6000_wow interrupt\n"); ++ return IRQ_HANDLED; ++} ++ ++/* ++ * hardware_ecc=1|0 ++ */ ++static char hardware_ecc_str[4] __initdata = ""; ++ ++static int __init hardware_ecc_setup(char *str) ++{ ++ if (str) ++ strlcpy(hardware_ecc_str, str, sizeof(hardware_ecc_str)); ++ return 1; ++} ++ ++__setup("hardware_ecc=", hardware_ecc_setup); ++ ++/* these are the guys that don't need to be children of PMU */ ++ ++static struct platform_device *gta02_devices[] __initdata = { ++ >a02_version_device, ++ &s3c_device_usb, ++ &s3c_device_wdt, ++ >a02_memconfig_device, ++ &s3c_device_sdi, ++ &s3c_device_usbgadget, ++ &s3c_device_nand, ++ >a02_nor_flash, ++ ++ &s3c24xx_pwm_device, ++ >a02_led_dev, ++ >a02_pm_wlan_dev, /* not dependent on PMU */ ++ ++ &s3c_device_iis, ++ &s3c_device_i2c0, ++}; ++ ++/* these guys DO need to be children of PMU */ ++ ++static struct platform_device *gta02_devices_pmu_children[] = { ++ &s3c_device_ts, /* input 1 */ ++ >a02_pm_gsm_dev, ++ >a02_pm_usbhost_dev, ++ >a02_spi_gpio_dev, /* input 2 and 3 */ ++ >a02_button_dev, /* input 4 */ ++ >a02_resume_reason_device, ++}; ++ ++static void gta02_pmu_regulator_registered(struct pcf50633 *pcf, int id) ++{ ++ struct platform_device *regulator, *pdev; ++ ++ gta02_pcf = pcf; ++ ++ regulator = pcf->regulator_pdev[id]; ++ ++ switch(id) { ++ case PCF50633_REGULATOR_LDO4: ++ pdev = >a01_pm_bt_dev; ++ break; ++ case PCF50633_REGULATOR_LDO5: ++ pdev = >a01_pm_gps_dev; ++ break; ++ case PCF50633_REGULATOR_HCLDO: ++ pdev = >a02_glamo_dev; ++ break; ++ default: ++ return; ++ } ++ ++ pdev->dev.parent = ®ulator->dev; ++ platform_device_register(pdev); ++} ++ ++/* this is called when pc50633 is probed, unfortunately quite late in the ++ * day since it is an I2C bus device. Here we can belatedly define some ++ * platform devices with the advantage that we can mark the pcf50633 as the ++ * parent. This makes them get suspended and resumed with their parent ++ * the pcf50633 still around. ++ */ ++ ++static void gta02_pmu_attach_child_devices(struct pcf50633 *pcf) ++{ ++ int n; ++ ++ for (n = 0; n < ARRAY_SIZE(gta02_devices_pmu_children); n++) ++ gta02_devices_pmu_children[n]->dev.parent = pcf->dev; ++ ++ mangle_glamo_res_by_system_rev(); ++ platform_add_devices(gta02_devices_pmu_children, ++ ARRAY_SIZE(gta02_devices_pmu_children)); ++} ++ ++static void gta02_poweroff(void) ++{ ++ pcf50633_reg_set_bit_mask(gta02_pcf, PCF50633_REG_OOCSHDWN, ++ PCF50633_OOCSHDWN_GOSTDBY, PCF50633_OOCSHDWN_GOSTDBY); ++} ++ ++static void __init gta02_machine_init(void) ++{ ++ int rc; ++ ++ /* set the panic callback to make AUX blink fast */ ++ panic_blink = gta02_panic_blink; ++ ++ switch (S3C_SYSTEM_REV_ATAG) { ++ case GTA02v6_SYSTEM_REV: ++ /* we need push-pull interrupt from motion sensors */ ++ lis302_pdata_top.open_drain = 0; ++ lis302_pdata_bottom.open_drain = 0; ++ break; ++ default: ++ break; ++ } ++ ++ spin_lock_init(&motion_irq_lock); ++ ++#ifdef CONFIG_CHARGER_PCF50633 ++ INIT_DELAYED_WORK(>a02_charger_work, gta02_charger_worker); ++#endif ++ ++ /* Glamo chip select optimization */ ++/* *((u32 *)(S3C2410_MEMREG(((1 + 1) << 2)))) = 0x1280; */ ++ ++ /* do not force soft ecc if we are asked to use hardware_ecc */ ++ if (hardware_ecc_str[0] == '1') ++ gta02_nand_info.software_ecc = 0; ++ ++ s3c_device_usb.dev.platform_data = >a02_usb_info; ++ s3c_device_nand.dev.platform_data = >a02_nand_info; ++ s3c_device_sdi.dev.platform_data = >a02_s3c_mmc_cfg; ++ ++ /* acc sensor chip selects */ ++ s3c2410_gpio_setpin(S3C2410_GPD12, 1); ++ s3c2410_gpio_cfgpin(S3C2410_GPD12, S3C2410_GPIO_OUTPUT); ++ s3c2410_gpio_setpin(S3C2410_GPD13, 1); ++ s3c2410_gpio_cfgpin(S3C2410_GPD13, S3C2410_GPIO_OUTPUT); ++ ++ s3c24xx_udc_set_platdata(>a02_udc_cfg); ++ s3c_i2c0_set_platdata(NULL); ++ set_s3c2410ts_info(>a02_ts_cfg); ++ ++ mangle_glamo_res_by_system_rev(); ++ ++ i2c_register_board_info(0, gta02_i2c_devs, ARRAY_SIZE(gta02_i2c_devs)); ++ spi_register_board_info(gta02_spi_board_info, ++ ARRAY_SIZE(gta02_spi_board_info)); ++ ++ mangle_pmu_pdata_by_system_rev(); ++ ++ platform_add_devices(gta02_devices, ARRAY_SIZE(gta02_devices)); ++ ++ s3c_pm_init(); ++ ++ /* Make sure the modem can wake us up */ ++ set_irq_type(GTA02_IRQ_MODEM, IRQ_TYPE_EDGE_RISING); ++ rc = request_irq(GTA02_IRQ_MODEM, gta02_modem_irq, IRQF_DISABLED, ++ "modem", NULL); ++ if (rc < 0) ++ printk(KERN_ERR "GTA02: can't request GSM modem wakeup IRQ\n"); ++ enable_irq_wake(GTA02_IRQ_MODEM); ++ ++ /* Make sure the wifi module can wake us up*/ ++ set_irq_type(GTA02_IRQ_WLAN_GPIO1, IRQ_TYPE_EDGE_RISING); ++ rc = request_irq(GTA02_IRQ_WLAN_GPIO1, ar6000_wow_irq, IRQF_DISABLED, ++ "ar6000", NULL); ++ ++ if (rc < 0) ++ printk(KERN_ERR "GTA02: can't request ar6k wakeup IRQ\n"); ++ enable_irq_wake(GTA02_IRQ_WLAN_GPIO1); ++ ++ pm_power_off = gta02_poweroff; ++ ++ /* Register the HDQ and vibrator as children of pwm device */ ++#ifdef CONFIG_HDQ_GPIO_BITBANG ++ gta02_hdq_device.dev.parent = &s3c24xx_pwm_device.dev; ++ platform_device_register(>a02_hdq_device); ++#endif ++#ifdef CONFIG_LEDS_NEO1973_VIBRATOR ++ gta02_vibrator_dev.dev.parent = &s3c24xx_pwm_device.dev; ++ platform_device_register(>a02_vibrator_dev); ++#endif ++} ++ ++void DEBUG_LED(int n) ++{ ++// int *p = NULL; ++ switch (n) { ++ case 0: ++ neo1973_gpb_setpin(GTA02_GPIO_PWR_LED1, 1); ++ break; ++ case 1: ++ neo1973_gpb_setpin(GTA02_GPIO_PWR_LED2, 1); ++ break; ++ default: ++ neo1973_gpb_setpin(GTA02_GPIO_AUX_LED, 1); ++ break; ++ } ++// printk(KERN_ERR"die %d\n", *p); ++} ++EXPORT_SYMBOL_GPL(DEBUG_LED); ++ ++MACHINE_START(NEO1973_GTA02, "GTA02") ++ .phys_io = S3C2410_PA_UART, ++ .io_pg_offst = (((u32)S3C24XX_VA_UART) >> 18) & 0xfffc, ++ .boot_params = S3C2410_SDRAM_PA + 0x100, ++ .map_io = gta02_map_io, ++ .init_irq = s3c24xx_init_irq, ++ .init_machine = gta02_machine_init, ++ .timer = &s3c24xx_timer, ++MACHINE_END +diff -ruN --exclude='*.orig' --exclude='*.rej' linux-2.6.29-rc3.owrt/arch/arm/mach-s3c2442/Makefile linux-2.6.29-rc3.owrt.om/arch/arm/mach-s3c2442/Makefile +--- linux-2.6.29-rc3.owrt/arch/arm/mach-s3c2442/Makefile 2009-05-10 22:05:02.000000000 +0200 ++++ linux-2.6.29-rc3.owrt.om/arch/arm/mach-s3c2442/Makefile 2009-05-10 22:27:59.000000000 +0200 +@@ -9,8 +9,11 @@ + obj-n := + obj- := + ++obj-$(CONFIG_S3C2440_C_FIQ) += fiq_c_isr.o ++ + obj-$(CONFIG_CPU_S3C2442) += s3c2442.o + obj-$(CONFIG_CPU_S3C2442) += clock.o ++obj-$(CONFIG_MACH_NEO1973_GTA02) += mach-gta02.o + + # Machine support + +diff -ruN --exclude='*.orig' --exclude='*.rej' linux-2.6.29-rc3.owrt/arch/arm/mach-s3c2442/s3c2442.c linux-2.6.29-rc3.owrt.om/arch/arm/mach-s3c2442/s3c2442.c +--- linux-2.6.29-rc3.owrt/arch/arm/mach-s3c2442/s3c2442.c 2009-05-10 22:05:02.000000000 +0200 ++++ linux-2.6.29-rc3.owrt.om/arch/arm/mach-s3c2442/s3c2442.c 2009-05-10 22:27:59.000000000 +0200 +@@ -21,6 +21,7 @@ + + #include <plat/s3c2442.h> + #include <plat/cpu.h> ++#include <plat/devs.h> + + static struct sys_device s3c2442_sysdev = { + .cls = &s3c2442_sysclass, +@@ -30,5 +31,8 @@ + { + printk("S3C2442: Initialising architecture\n"); + ++ /* make sure SD/MMC driver can distinguish 2440 from 2410 */ ++ s3c_device_sdi.name = "s3c2440-sdi"; ++ + return sysdev_register(&s3c2442_sysdev); + } +diff -ruN --exclude='*.orig' --exclude='*.rej' linux-2.6.29-rc3.owrt/arch/arm/mach-s3c2443/dma.c linux-2.6.29-rc3.owrt.om/arch/arm/mach-s3c2443/dma.c +--- linux-2.6.29-rc3.owrt/arch/arm/mach-s3c2443/dma.c 2009-05-10 22:05:03.000000000 +0200 ++++ linux-2.6.29-rc3.owrt.om/arch/arm/mach-s3c2443/dma.c 2009-05-10 22:27:59.000000000 +0200 +@@ -20,16 +20,17 @@ + + #include <mach/dma.h> + +-#include <plat/dma.h> ++#include <plat/dma-plat.h> + #include <plat/cpu.h> + + #include <plat/regs-serial.h> + #include <mach/regs-gpio.h> + #include <plat/regs-ac97.h> ++#include <plat/regs-dma.h> + #include <mach/regs-mem.h> + #include <mach/regs-lcd.h> + #include <mach/regs-sdi.h> +-#include <asm/plat-s3c24xx/regs-iis.h> ++#include <plat/regs-iis.h> + #include <plat/regs-spi.h> + + #define MAP(x) { \ +diff -ruN --exclude='*.orig' --exclude='*.rej' linux-2.6.29-rc3.owrt/arch/arm/mach-s3c24a0/include/mach/io.h linux-2.6.29-rc3.owrt.om/arch/arm/mach-s3c24a0/include/mach/io.h +--- linux-2.6.29-rc3.owrt/arch/arm/mach-s3c24a0/include/mach/io.h 1970-01-01 01:00:00.000000000 +0100 ++++ linux-2.6.29-rc3.owrt.om/arch/arm/mach-s3c24a0/include/mach/io.h 2009-05-10 22:27:59.000000000 +0200 +@@ -0,0 +1,16 @@ ++/* arch/arm/mach-s3c24a0/include/mach/io.h ++ * ++ * Copyright 2008 Simtec Electronics ++ * Ben Dooks <ben-linux@fluff.org> ++ * ++ * IO access and mapping routines for the S3C24A0 ++ */ ++ ++#ifndef __ASM_ARM_ARCH_IO_H ++#define __ASM_ARM_ARCH_IO_H ++ ++/* No current ISA/PCI bus support. */ ++#define __io(a) ((void __iomem *)(a)) ++#define __mem_pci(a) (a) ++ ++#endif +diff -ruN --exclude='*.orig' --exclude='*.rej' linux-2.6.29-rc3.owrt/arch/arm/mach-s3c24a0/include/mach/irqs.h linux-2.6.29-rc3.owrt.om/arch/arm/mach-s3c24a0/include/mach/irqs.h +--- linux-2.6.29-rc3.owrt/arch/arm/mach-s3c24a0/include/mach/irqs.h 2009-05-10 22:05:03.000000000 +0200 ++++ linux-2.6.29-rc3.owrt.om/arch/arm/mach-s3c24a0/include/mach/irqs.h 2009-05-10 22:27:59.000000000 +0200 +@@ -70,6 +70,8 @@ + #define IRQ_EINT17 S3C2410_IRQ(49) + #define IRQ_EINT18 S3C2410_IRQ(50) + ++#define IRQ_EINT_BIT(x) ((x) - IRQ_EINT00) ++ + /* SUB IRQS */ + #define IRQ_S3CUART_RX0 S3C2410_IRQ(51) /* 67 */ + #define IRQ_S3CUART_TX0 S3C2410_IRQ(52) +diff -ruN --exclude='*.orig' --exclude='*.rej' linux-2.6.29-rc3.owrt/arch/arm/mach-s3c6400/include/mach/dma.h linux-2.6.29-rc3.owrt.om/arch/arm/mach-s3c6400/include/mach/dma.h +--- linux-2.6.29-rc3.owrt/arch/arm/mach-s3c6400/include/mach/dma.h 2009-05-10 22:05:04.000000000 +0200 ++++ linux-2.6.29-rc3.owrt.om/arch/arm/mach-s3c6400/include/mach/dma.h 2009-05-10 22:27:59.000000000 +0200 +@@ -11,6 +11,63 @@ + #ifndef __ASM_ARCH_DMA_H + #define __ASM_ARCH_DMA_H __FILE__ + +-/* currently nothing here, placeholder */ ++#define S3C_DMA_CHANNELS (16) ++ ++/* see mach-s3c2410/dma.h for notes on dma channel numbers */ ++ ++/* Note, for the S3C64XX architecture we keep the DMACH_ ++ * defines in the order they are allocated to [S]DMA0/[S]DMA1 ++ * so that is easy to do DHACH_ -> DMA controller conversion ++ */ ++enum dma_ch { ++ /* DMA0/SDMA0 */ ++ DMACH_UART0 = 0, ++ DMACH_UART0_SRC2, ++ DMACH_UART1, ++ DMACH_UART1_SRC2, ++ DMACH_UART2, ++ DMACH_UART2_SRC2, ++ DMACH_UART3, ++ DMACH_UART3_SRC2, ++ DMACH_PCM0_TX, ++ DMACH_PCM0_RX, ++ DMACH_I2S0_OUT, ++ DMACH_I2S0_IN, ++ DMACH_SPI0_TX, ++ DMACH_SPI0_RX, ++ DMACH_HSI_I2SV40_TX, ++ DMACH_HSI_I2SV40_RX, ++ ++ /* DMA1/SDMA1 */ ++ DMACH_PCM1_TX = 16, ++ DMACH_PCM1_RX, ++ DMACH_I2S1_OUT, ++ DMACH_I2S1_IN, ++ DMACH_SPI1_TX, ++ DMACH_SPI1_RX, ++ DMACH_AC97_PCMOUT, ++ DMACH_AC97_PCMIN, ++ DMACH_AC97_MICIN, ++ DMACH_PWM, ++ DMACH_IRDA, ++ DMACH_EXTERNAL, ++ DMACH_RES1, ++ DMACH_RES2, ++ DMACH_SECURITY_RX, /* SDMA1 only */ ++ DMACH_SECURITY_TX, /* SDMA1 only */ ++ DMACH_MAX /* the end */ ++}; ++ ++static __inline__ int s3c_dma_has_circular(void) ++{ ++ /* we will be supporting ciruclar buffers as soon as we have DMA ++ * engine support. ++ */ ++ return 1; ++} ++ ++#define S3C2410_DMAF_CIRCULAR (1 << 0) ++ ++#include <plat/dma.h> + + #endif /* __ASM_ARCH_IRQ_H */ +diff -ruN --exclude='*.orig' --exclude='*.rej' linux-2.6.29-rc3.owrt/arch/arm/mach-s3c6400/include/mach/map.h linux-2.6.29-rc3.owrt.om/arch/arm/mach-s3c6400/include/mach/map.h +--- linux-2.6.29-rc3.owrt/arch/arm/mach-s3c6400/include/mach/map.h 2009-05-10 22:05:03.000000000 +0200 ++++ linux-2.6.29-rc3.owrt.om/arch/arm/mach-s3c6400/include/mach/map.h 2009-05-10 22:27:59.000000000 +0200 +@@ -40,6 +40,8 @@ + + #define S3C64XX_PA_FB (0x77100000) + #define S3C64XX_PA_SYSCON (0x7E00F000) ++#define S3C64XX_PA_IIS0 (0x7F002000) ++#define S3C64XX_PA_IIS1 (0x7F003000) + #define S3C64XX_PA_TIMER (0x7F006000) + #define S3C64XX_PA_IIC0 (0x7F004000) + #define S3C64XX_PA_IIC1 (0x7F00F000) +@@ -49,12 +51,21 @@ + #define S3C64XX_SZ_GPIO SZ_4K + + #define S3C64XX_PA_SDRAM (0x50000000) ++#define S3C64XX_PA_TZIC0 (0x71000000) ++#define S3C64XX_PA_TZIC1 (0x71100000) + #define S3C64XX_PA_VIC0 (0x71200000) + #define S3C64XX_PA_VIC1 (0x71300000) + ++#define S3C64XX_PA_MODEM (0x74108000) ++#define S3C64XX_VA_MODEM S3C_ADDR(0x00600000) ++ ++#define S3C64XX_PA_USBHOST (0x74300000) ++ + /* place VICs close together */ + #define S3C_VA_VIC0 (S3C_VA_IRQ + 0x00) + #define S3C_VA_VIC1 (S3C_VA_IRQ + 0x10000) ++#define S3C_VA_TZIC0 (S3C_VA_IRQ + 0x20000) ++#define S3C_VA_TZIC1 (S3C_VA_IRQ + 0x30000) + + /* compatibiltiy defines. */ + #define S3C_PA_TIMER S3C64XX_PA_TIMER +@@ -64,5 +75,12 @@ + #define S3C_PA_IIC S3C64XX_PA_IIC0 + #define S3C_PA_IIC1 S3C64XX_PA_IIC1 + #define S3C_PA_FB S3C64XX_PA_FB ++#define S3C_PA_USBHOST S3C64XX_PA_USBHOST ++ ++#define S3C64XX_VA_OTG S3C_VA_OTG ++#define S3C64XX_PA_OTG (0x7C000000) ++ ++#define S3C64XX_VA_OTGSFR S3C_VA_OTGSFR ++#define S3C64XX_PA_OTGSFR (0x7C100000) + + #endif /* __ASM_ARCH_6400_MAP_H */ +diff -ruN --exclude='*.orig' --exclude='*.rej' linux-2.6.29-rc3.owrt/arch/arm/mach-s3c6400/include/mach/regs-clock.h linux-2.6.29-rc3.owrt.om/arch/arm/mach-s3c6400/include/mach/regs-clock.h +--- linux-2.6.29-rc3.owrt/arch/arm/mach-s3c6400/include/mach/regs-clock.h 1970-01-01 01:00:00.000000000 +0100 ++++ linux-2.6.29-rc3.owrt.om/arch/arm/mach-s3c6400/include/mach/regs-clock.h 2009-05-10 22:27:59.000000000 +0200 +@@ -0,0 +1,16 @@ ++/* linux/arch/arm/mach-s3c6400/include/mach/regs-clock.h ++ * ++ * Copyright 2008 Openmoko, Inc. ++ * Copyright 2008 Simtec Electronics ++ * http://armlinux.simtec.co.uk/ ++ * Ben Dooks <ben@simtec.co.uk> ++ * ++ * S3C64XX - clock register compatibility with s3c24xx ++ * ++ * 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 <plat/regs-clock.h> ++ +diff -ruN --exclude='*.orig' --exclude='*.rej' linux-2.6.29-rc3.owrt/arch/arm/mach-s3c6400/include/mach/system.h linux-2.6.29-rc3.owrt.om/arch/arm/mach-s3c6400/include/mach/system.h +--- linux-2.6.29-rc3.owrt/arch/arm/mach-s3c6400/include/mach/system.h 2009-05-10 22:05:04.000000000 +0200 ++++ linux-2.6.29-rc3.owrt.om/arch/arm/mach-s3c6400/include/mach/system.h 2009-05-10 22:27:59.000000000 +0200 +@@ -11,9 +11,29 @@ + #ifndef __ASM_ARCH_SYSTEM_H + #define __ASM_ARCH_SYSTEM_H __FILE__ + ++#include <linux/io.h> ++#include <mach/map.h> ++ ++#include <plat/regs-sys.h> ++#include <plat/regs-syscon-power.h> ++ + static void arch_idle(void) + { +- /* nothing here yet */ ++ unsigned long flags; ++ u32 mode; ++ ++ /* ensure that if we execute the cpu idle sequence that we ++ * go into idle mode instead of powering off. */ ++ ++ local_irq_save(flags); ++ mode = __raw_readl(S3C64XX_PWR_CFG); ++ mode &= ~S3C64XX_PWRCFG_CFG_WFI_MASK; ++ mode |= S3C64XX_PWRCFG_CFG_WFI_IDLE; ++ __raw_writel(mode, S3C64XX_PWR_CFG); ++ ++ local_irq_restore(flags); ++ ++ cpu_do_idle(); + } + + static void arch_reset(char mode) +diff -ruN --exclude='*.orig' --exclude='*.rej' linux-2.6.29-rc3.owrt/arch/arm/mach-s3c6410/include/mach/om-3d7k.h linux-2.6.29-rc3.owrt.om/arch/arm/mach-s3c6410/include/mach/om-3d7k.h +--- linux-2.6.29-rc3.owrt/arch/arm/mach-s3c6410/include/mach/om-3d7k.h 1970-01-01 01:00:00.000000000 +0100 ++++ linux-2.6.29-rc3.owrt.om/arch/arm/mach-s3c6410/include/mach/om-3d7k.h 2009-05-10 22:27:59.000000000 +0200 +@@ -0,0 +1,98 @@ ++/* ++ * 3D7K GPIO Mappings ++ * ++ * (C) 2008 by Openmoko Inc. ++ * Author: Andy Green <andy@openmoko.com> ++ * All rights reserved. ++ * ++ * 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 _OM_3D7K_H ++#define _OM_3D7K_H ++ ++#include <mach/gpio.h> ++#include <mach/irqs.h> ++#include <linux/mfd/pcf50633/core.h> ++ ++extern struct pcf50633 *om_3d7k_pcf; ++ ++/* ATAG_REVISION from bootloader */ ++#define OM_3D7Kv1_SYSTEM_REV 0x00000001 ++ ++#define OM_3D7K_GPIO_VIBRATOR_ON S3C64XX_GPF(13) ++#define OM_3D7K_GPIO_CLKOUT S3C64XX_GPF(14) ++ ++#define OM_3D7K_GPIO_ACCEL_MISO S3C64XX_GPC(0) ++#define OM_3D7K_GPIO_ACCEL_CLK S3C64XX_GPC(1) ++#define OM_3D7K_GPIO_ACCEL_MOSI S3C64XX_GPC(2) ++ ++#define OM_3D7K_GPIO_LCM_MISO S3C64XX_GPC(4) ++#define OM_3D7K_GPIO_LCM_CLK S3C64XX_GPC(5) ++#define OM_3D7K_GPIO_LCM_MOSI S3C64XX_GPC(6) ++#define OM_3D7K_GPIO_LCM_CS S3C64XX_GPC(7) ++ ++#define OM_3D7K_GPIO_BTPCM_SHARED_SCLK S3C64XX_GPE(0) ++#define OM_3D7K_GPIO_BTPCM_SHARED_EXTCLK S3C64XX_GPE(1) ++#define OM_3D7K_GPIO_BTPCM_SHARED_FSYNC S3C64XX_GPE(2) ++#define OM_3D7K_GPIO_BTPCM_SHARED_SIN S3C64XX_GPE(3) ++#define OM_3D7K_GPIO_BTPCM_SHARED_SOUT S3C64XX_GPE(4) ++ ++#define OM_3D7K_GPIO_WLAN_RESET S3C64XX_GPH(6) ++#define OM_3D7K_GPIO_HDQ S3C64XX_GPH(7) ++#define OM_3D7K_GPIO_WLAN_PWRDN S3C64XX_GPH(8) ++ ++#define OM_3D7K_GPIO_VERSION2 S3C64XX_GPI(0) ++#define OM_3D7K_GPIO_VERSION1 S3C64XX_GPI(1) ++#define OM_3D7K_GPIO_VERSION0 S3C64XX_GPI(8) ++ ++#define OM_3D7K_GPIO_NWLAN_POWER S3C64XX_GPK(0) ++#define OM_3D7K_GPIO_MODEM_ON S3C64XX_GPK(2) ++#define OM_3D7K_GPIO_LED_TRIG S3C64XX_GPK(3) ++#define OM_3D7K_GPIO_LED_EN S3C64XX_GPK(4) ++#define OM_3D7K_GPIO_LCM_RESET S3C64XX_GPK(6) ++ ++#define OM_3D7K_GPIO_LCM_SD S3C64XX_GPL(0) ++ ++#define OM_3D7K_GPIO_TP_RESET S3C64XX_GPM(0) ++#define OM_3D7K_GPIO_GPS_LNA_EN S3C64XX_GPM(2) ++ ++#define OM_3D7K_GPIO_USB_FLT S3C64XX_GPM(4) ++#define OM_3D7K_GPIO_USB_OC S3C64XX_GPM(5) ++ ++#define OM_3D7K_GPIO_ACCEL_INT1 S3C64XX_GPN(0) ++#define OM_3D7K_GPIO_KEY_MINUS S3C64XX_GPN(1) ++#define OM_3D7K_GPIO_KEY_PLUS S3C64XX_GPN(2) ++#define OM_3D7K_GPIO_PWR_IND S3C64XX_GPN(3) ++#define OM_3D7K_GPIO_PWR_IRQ S3C64XX_GPN(4) ++#define OM_3D7K_GPIO_TOUCH S3C64XX_GPN(5) ++#define OM_3D7K_GPIO_JACK_INSERT S3C64XX_GPN(6) ++#define OM_3D7K_GPIO_GPS_INT S3C64XX_GPN(7) ++#define OM_3D7K_GPIO_HOLD S3C64XX_GPN(8) ++#define OM_3D7K_GPIO_WLAN_WAKEUP S3C64XX_GPN(9) ++#define OM_3D7K_GPIO_ACCEL_INT2 S3C64XX_GPN(10) ++#define OM_3D7K_GPIO_IO1 S3C64XX_GPN(11) ++#define OM_3D7K_GPIO_NONKEYWAKE S3C64XX_GPN(12) ++ ++#define OM_3D7K_GPIO_N_MODEM_RESET S3C64XX_GPO(1) ++ ++#define OM_3D7K_IRQ_GSENSOR_1 S3C_EINT(0) ++#define OM_3D7K_IRQ_KEY_MINUS S3C_EINT(1) ++#define OM_3D7K_IRQ_KEY_PLUS S3C_EINT(2) ++#define OM_3D7K_IRQ_PWR_IND S3C_EINT(3) ++#define OM_3D7K_IRQ_PMU S3C_EINT(4) ++#define OM_3D7K_IRQ_TOUCH S3C_EINT(5) ++#define OM_3D7K_IRQ_JACK_INSERT S3C_EINT(6) ++#define OM_3D7K_IRQ_GPS_INT S3C_EINT(7) ++#define OM_3D7K_IRQ_NHOLD S3C_EINT(8) ++#define OM_3D7K_IRQ_WLAN_WAKEUP S3C_EINT(9) ++#define OM_3D7K_IRQ_GSENSOR_2 S3C_EINT(10) ++#define OM_3D7K_IRQ_IO1 S3C_EINT(11) ++#define OM_3D7K_IRQ_NONKEYWAKE S3C_EINT(12) ++ ++#define OM_3D7K_IRQ_LED IRQ_EINT_GROUP(6, 9) ++ ++#endif /* _OM_3D7K_H */ +diff -ruN --exclude='*.orig' --exclude='*.rej' linux-2.6.29-rc3.owrt/arch/arm/mach-s3c6410/include/mach/spi-gpio.h linux-2.6.29-rc3.owrt.om/arch/arm/mach-s3c6410/include/mach/spi-gpio.h +--- linux-2.6.29-rc3.owrt/arch/arm/mach-s3c6410/include/mach/spi-gpio.h 1970-01-01 01:00:00.000000000 +0100 ++++ linux-2.6.29-rc3.owrt.om/arch/arm/mach-s3c6410/include/mach/spi-gpio.h 2009-05-10 22:27:59.000000000 +0200 +@@ -0,0 +1,28 @@ ++/* arch/arm/mach-s3c6400/include/mach/spi-gpio.h ++ * ++ * Copyright (c) 2006 Simtec Electronics ++ * Ben Dooks <ben@simtec.co.uk> ++ * ++ * S3C64XX - SPI Controller platfrom_device info ++ * ++ * 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_ARCH_SPIGPIO_H ++#define __ASM_ARCH_SPIGPIO_H __FILE__ ++ ++struct s3c64xx_spigpio_info { ++ unsigned long pin_clk; ++ unsigned long pin_mosi; ++ unsigned long pin_miso; ++ ++ int bus_num; ++ int num_chipselect; ++ ++ void (*chip_select)(struct s3c64xx_spigpio_info *spi, int csid, int cs); ++}; ++ ++ ++#endif /* __ASM_ARCH_SPIGPIO_H */ +diff -ruN --exclude='*.orig' --exclude='*.rej' linux-2.6.29-rc3.owrt/arch/arm/mach-s3c6410/Kconfig linux-2.6.29-rc3.owrt.om/arch/arm/mach-s3c6410/Kconfig +--- linux-2.6.29-rc3.owrt/arch/arm/mach-s3c6410/Kconfig 2009-05-10 22:05:04.000000000 +0200 ++++ linux-2.6.29-rc3.owrt.om/arch/arm/mach-s3c6410/Kconfig 2009-05-10 22:27:59.000000000 +0200 +@@ -26,6 +26,7 @@ + select S3C_DEV_HSMMC1 + select S3C_DEV_I2C1 + select S3C_DEV_FB ++ select S3C_DEV_USB_HOST + select S3C6410_SETUP_SDHCI + select S3C64XX_SETUP_I2C1 + select S3C64XX_SETUP_FB_24BPP +@@ -60,3 +61,25 @@ + channels 0 and 1 are the same. + + endchoice ++ ++config MACH_OM_3D7K ++ bool "Openmoko 3D7K Phone" ++ select CPU_S3C6410 ++ select S3C_DEV_HSMMC ++ select S3C_DEV_HSMMC1 ++ select S3C_DEV_I2C1 ++ select S3C_DEV_USB_HOST ++ select S3C6410_SETUP_SDHCI ++ select S3C64XX_SETUP_I2C1 ++ select S3C_DEV_FB ++ select S3C_DEV_CAMIF ++ select S3C64XX_SETUP_FB_24BPP ++# select SENSORS_PCF50633 ++ select POWER_SUPPLY ++ select HDQ_GPIO_BITBANG ++ select S3C_PWM ++ select FIQ ++ select MACH_NEO1973 ++ help ++ Machine support for the Openmoko 3D7K Phone ++ +diff -ruN --exclude='*.orig' --exclude='*.rej' linux-2.6.29-rc3.owrt/arch/arm/mach-s3c6410/mach-om-3d7k.c linux-2.6.29-rc3.owrt.om/arch/arm/mach-s3c6410/mach-om-3d7k.c +--- linux-2.6.29-rc3.owrt/arch/arm/mach-s3c6410/mach-om-3d7k.c 1970-01-01 01:00:00.000000000 +0100 ++++ linux-2.6.29-rc3.owrt.om/arch/arm/mach-s3c6410/mach-om-3d7k.c 2009-05-10 22:27:59.000000000 +0200 +@@ -0,0 +1,1196 @@ ++/* linux/arch/arm/mach-s3c6410/mach-om-3d7k.c ++ * ++ * Copyright 2008 Openmoko, Inc. ++ * Andy Green <andy@openmoko.org> ++ * ++ * based on mach_smdk6410.c which is ++ * ++ * Copyright 2008 Openmoko, Inc. ++ * Copyright 2008 Simtec Electronics ++ * Ben Dooks <ben@simtec.co.uk> ++ * http://armlinux.simtec.co.uk/ ++ * ++ * 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/types.h> ++#include <linux/interrupt.h> ++#include <linux/list.h> ++#include <linux/timer.h> ++#include <linux/init.h> ++#include <linux/serial_core.h> ++#include <linux/platform_device.h> ++#include <linux/io.h> ++#include <linux/i2c.h> ++#include <linux/fb.h> ++#include <linux/delay.h> ++#include <linux/lis302dl.h> ++#include <linux/lp5521.h> ++#include <linux/spi/spi_bitbang.h> ++#include <linux/l1k002.h> ++#include <linux/pcap7200.h> ++#include <linux/bq27000_battery.h> ++#include <linux/hdq.h> ++#include <linux/jbt6k74.h> ++ ++#include <video/platform_lcd.h> ++ ++#include <asm/mach/arch.h> ++#include <asm/mach/map.h> ++#include <asm/mach/irq.h> ++ ++#include <mach/hardware.h> ++#include <asm/hardware/vic.h> ++#include <asm/hardware/tzic-sp890.h> ++#include <mach/map.h> ++#include <mach/regs-fb.h> ++#include <mach/spi-gpio.h> ++ ++#include <asm/irq.h> ++#include <asm/mach-types.h> ++#include <asm/fiq.h> ++ ++#include <plat/regs-serial.h> ++#include <plat/regs-timer.h> ++#include <plat/regs-gpio.h> ++#include <plat/iic.h> ++#include <plat/fb.h> ++#include <plat/gpio-cfg.h> ++#include <plat/pm.h> ++#include <plat/pwm.h> ++ ++#include <plat/s3c6410.h> ++#include <plat/clock.h> ++#include <plat/devs.h> ++#include <plat/cpu.h> ++#include <plat/tzic-sp890.h> ++#include <plat/usb-control.h> ++ ++/* #include <plat/udc.h> */ ++#include <linux/i2c.h> ++#include <linux/backlight.h> ++#include <linux/regulator/machine.h> ++ ++#include <mach/om-3d7k.h> ++ ++#include <linux/mfd/pcf50633/core.h> ++#include <linux/mfd/pcf50633/mbc.h> ++#include <linux/mfd/pcf50633/adc.h> ++#include <linux/mfd/pcf50633/gpio.h> ++#include <linux/mfd/pcf50633/pmic.h> ++ ++#include <plat/regs-usb-hs-otg.h> ++ ++extern struct platform_device s3c_device_usbgadget; ++extern struct platform_device s3c_device_camif; /* @@@ change plat/devs.h */ ++ ++ ++/* ------------------------------------------------------------------------------- ++ * OM_3D7K FIQ related ++ * ++ * Calls into vibrator and hdq and based on the return values ++ * determines if we the FIQ source be kept alive ++ */ ++ ++#define DIVISOR_FROM_US(x) ((x) * 23) ++ ++#ifdef CONFIG_HDQ_GPIO_BITBANG ++#define FIQ_DIVISOR_HDQ DIVISOR_FROM_US(HDQ_SAMPLE_PERIOD_US) ++extern int hdq_fiq_handler(void); ++#endif ++ ++/* Global data related to our fiq source */ ++static u32 om_3d7k_fiq_ack_mask; ++static u32 om_3d7k_fiq_mod_mask; ++static struct s3c2410_pwm om_3d7k_fiq_pwm_timer; ++static u16 om_3d7k_fiq_timer_index; ++static int om_3d7k_fiq_irq; ++ ++/* Convinience defines */ ++#define S3C6410_INTMSK (S3C_VA_VIC0 + VIC_INT_ENABLE) ++#define S3C6410_INTMOD (S3C_VA_VIC0 + VIC_INT_SELECT) ++ ++ ++ ++static void om_3d7k_fiq_handler(void) ++{ ++ u16 divisor = 0xffff; ++ ++ /* Vibrator servicing */ ++ ++ /* disable further timer interrupts if nobody has any work ++ * or adjust rate according to who still has work ++ * ++ * CAUTION: it means forground code must disable FIQ around ++ * its own non-atomic S3C2410_INTMSK changes... not common ++ * thankfully and taken care of by the fiq-basis patch ++ */ ++ ++#ifdef CONFIG_HDQ_GPIO_BITBANG ++ if (hdq_fiq_handler()) ++ divisor = (u16)FIQ_DIVISOR_HDQ; ++#endif ++ ++ if (divisor == 0xffff) /* mask the fiq irq source */ ++ __raw_writel((__raw_readl(S3C64XX_TINT_CSTAT) & 0x1f) & ~(1 << 3), ++ S3C64XX_TINT_CSTAT); ++ else /* still working, maybe at a different rate */ ++ __raw_writel(divisor, S3C2410_TCNTB(om_3d7k_fiq_timer_index)); ++ ++ __raw_writel((__raw_readl(S3C64XX_TINT_CSTAT) & 0x1f ) | 1 << 8 , S3C64XX_TINT_CSTAT); ++ ++} ++ ++static void om_3d7k_fiq_kick(void) ++{ ++ unsigned long flags; ++ u32 tcon; ++ ++ /* we have to take care about FIQ because this modification is ++ * non-atomic, FIQ could come in after the read and before the ++ * writeback and its changes to the register would be lost ++ * (platform INTMSK mod code is taken care of already) ++ */ ++ local_save_flags(flags); ++ local_fiq_disable(); ++ /* allow FIQs to resume */ ++ __raw_writel((__raw_readl(S3C64XX_TINT_CSTAT) & 0x1f)| 1 << 3, ++ S3C64XX_TINT_CSTAT); ++ ++ tcon = __raw_readl(S3C2410_TCON) & ~S3C2410_TCON_T3START; ++ /* fake the timer to a count of 1 */ ++ __raw_writel(1, S3C2410_TCNTB(om_3d7k_fiq_timer_index)); ++ __raw_writel(tcon | S3C2410_TCON_T3MANUALUPD, S3C2410_TCON); ++ __raw_writel(tcon | S3C2410_TCON_T3MANUALUPD | S3C2410_TCON_T3START, ++ S3C2410_TCON); ++ __raw_writel(tcon | S3C2410_TCON_T3START, S3C2410_TCON); ++ local_irq_restore(flags); ++} ++ ++static int om_3d7k_fiq_enable(void) ++{ ++ int irq_index_fiq = IRQ_TIMER3_VIC; ++ int rc = 0; ++ ++ local_fiq_disable(); ++ ++ om_3d7k_fiq_irq = irq_index_fiq; ++ om_3d7k_fiq_ack_mask = 1 << 3; ++ om_3d7k_fiq_mod_mask = 1 << 27; ++ om_3d7k_fiq_timer_index = 3; ++ ++ /* set up the timer to operate as a pwm device */ ++ ++ rc = s3c2410_pwm_init(&om_3d7k_fiq_pwm_timer); ++ if (rc) ++ goto bail; ++ ++ om_3d7k_fiq_pwm_timer.timerid = PWM0 + om_3d7k_fiq_timer_index; ++ om_3d7k_fiq_pwm_timer.prescaler = ((6 - 1) / 2); ++ om_3d7k_fiq_pwm_timer.divider = S3C64XX_TCFG1_MUX_DIV2 << S3C2410_TCFG1_SHIFT(3); ++ /* default rate == ~32us */ ++ om_3d7k_fiq_pwm_timer.counter = om_3d7k_fiq_pwm_timer.comparer = 3000; ++ ++ rc = s3c2410_pwm_enable(&om_3d7k_fiq_pwm_timer); ++ if (rc) ++ goto bail; ++ ++ /* let our selected interrupt be a magic FIQ interrupt */ ++ __raw_writel(om_3d7k_fiq_mod_mask, S3C6410_INTMSK + 4); ++ __raw_writel(om_3d7k_fiq_mod_mask, S3C6410_INTMOD); ++ __raw_writel(om_3d7k_fiq_mod_mask, S3C6410_INTMSK); ++ ++ __raw_writel(SP890_TZIC_UNLOCK_MAGIC, S3C64XX_VA_TZIC0_LOCK); ++ __raw_writel(om_3d7k_fiq_mod_mask, S3C64XX_VA_TZIC0_FIQENABLE); ++ __raw_writel(om_3d7k_fiq_mod_mask, S3C64XX_VA_TZIC0_INTSELECT); ++ ++ s3c2410_pwm_start(&om_3d7k_fiq_pwm_timer); ++ ++ /* it's ready to go as soon as we unmask the source in S3C2410_INTMSK */ ++ local_fiq_enable(); ++ ++ set_fiq_c_handler(om_3d7k_fiq_handler); ++ ++ if (rc < 0) ++ goto bail; ++ ++ return 0; ++bail: ++ printk(KERN_ERR "Count not initialize FIQ for OM_3D7K %d \n", rc); ++ return rc; ++} ++ ++static void om_3d7k_fiq_disable(void) ++{ ++ __raw_writel(0, S3C6410_INTMOD); ++ local_fiq_disable(); ++ om_3d7k_fiq_irq = 0; /* no active source interrupt now either */ ++ ++} ++/* -------------------- /OM_3D7K FIQ Handler ------------------------------------- */ ++ ++#define UCON S3C2410_UCON_DEFAULT | S3C2410_UCON_UCLK ++#define ULCON S3C2410_LCON_CS8 | S3C2410_LCON_PNONE | S3C2410_LCON_STOPB ++#define UFCON S3C2410_UFCON_RXTRIG8 | S3C2410_UFCON_FIFOMODE ++ ++static struct s3c2410_uartcfg om_3d7k_uartcfgs[] __initdata = { ++ [0] = { ++ .hwport = 0, ++ .flags = 0, ++ .ucon = 0x3c5, ++ .ulcon = 0x03, ++ .ufcon = 0x51, ++ }, ++ [1] = { ++ .hwport = 1, ++ .flags = 0, ++ .ucon = 0x3c5, ++ .ulcon = 0x03, ++ .ufcon = 0x51, ++ }, ++ [2] = { ++ .hwport = 2, ++ .flags = 0, ++ .ucon = 0x3c5, ++ .ulcon = 0x03, ++ .ufcon = 0x51, ++ }, ++ [3] = { ++ .hwport = 3, ++ .flags = 0, ++ .ucon = 0x3c5, ++ .ulcon = 0x03, ++ .ufcon = 0x51, ++ }, ++}; ++ ++ ++/* ++ * Situation is that Linux SPI can't work in an interrupt context, so we ++ * implement our own bitbang here. Arbitration is needed because not only ++ * can this interrupt happen at any time even if foreground wants to use ++ * the bitbang API from Linux, but multiple motion sensors can be on the ++ * same SPI bus, and multiple interrupts can happen. ++ * ++ * Foreground / interrupt arbitration is okay because the interrupts are ++ * disabled around all the foreground SPI code. ++ * ++ * Interrupt / Interrupt arbitration is evidently needed, otherwise we ++ * lose edge-triggered service after a while due to the two sensors sharing ++ * the SPI bus having irqs at the same time eventually. ++ * ++ * Servicing is typ 75 - 100us at 400MHz. ++ */ ++ ++/* #define DEBUG_SPEW_MS */ ++#define MG_PER_SAMPLE 18 ++ ++struct lis302dl_platform_data lis302_pdata; ++ ++/* ++ * generic SPI RX and TX bitbang ++ * only call with interrupts off! ++ */ ++ ++static void __3d7k_lis302dl_bitbang(struct lis302dl_info *lis, u8 *tx, ++ int tx_bytes, u8 *rx, int rx_bytes) ++{ ++ struct lis302dl_platform_data *pdata = lis->pdata; ++ int n; ++ u8 shifter = 0; ++ ++ gpio_direction_output(pdata->pin_chip_select, 1); ++ gpio_direction_output(pdata->pin_clk, 1); ++ gpio_direction_output(pdata->pin_chip_select, 0); ++ ++ /* send the register index, r/w and autoinc bits */ ++ for (n = 0; n < (tx_bytes << 3); n++) { ++ if (!(n & 7)) ++ shifter = ~tx[n >> 3]; ++ gpio_direction_output(pdata->pin_clk, 0); ++ gpio_direction_output(pdata->pin_mosi, !(shifter & 0x80)); ++ gpio_direction_output(pdata->pin_clk, 1); ++ shifter <<= 1; ++ } ++ ++ for (n = 0; n < (rx_bytes << 3); n++) { /* 8 bits each */ ++ gpio_direction_output(pdata->pin_clk, 0); ++ shifter <<= 1; ++ if (gpio_direction_input(pdata->pin_miso)) ++ shifter |= 1; ++ if ((n & 7) == 7) ++ rx[n >> 3] = shifter; ++ gpio_direction_output(pdata->pin_clk, 1); ++ } ++ gpio_direction_output(pdata->pin_chip_select, 1); ++} ++ ++ ++static int om_3d7k_lis302dl_bitbang_read_reg(struct lis302dl_info *lis, u8 reg) ++{ ++ u8 data = 0xc0 | reg; /* read, autoincrement */ ++ unsigned long flags; ++ ++ local_irq_save(flags); ++ ++ __3d7k_lis302dl_bitbang(lis, &data, 1, &data, 1); ++ ++ local_irq_restore(flags); ++ ++ return data; ++} ++ ++static void om_3d7k_lis302dl_bitbang_write_reg(struct lis302dl_info *lis, u8 reg, ++ u8 val) ++{ ++ u8 data[2] = { 0x00 | reg, val }; /* write, no autoincrement */ ++ unsigned long flags; ++ ++ local_irq_save(flags); ++ ++ __3d7k_lis302dl_bitbang(lis, &data[0], 2, NULL, 0); ++ ++ local_irq_restore(flags); ++ ++} ++ ++ ++void om_3d7k_lis302dl_suspend_io(struct lis302dl_info *lis, int resume) ++{ ++ struct lis302dl_platform_data *pdata = lis->pdata; ++ ++ if (!resume) { ++ /* ++ * we don't want to power them with a high level ++ * because GSENSOR_3V3 is not up during suspend ++ */ ++ gpio_direction_output(pdata->pin_chip_select, 0); ++ gpio_direction_output(pdata->pin_clk, 0); ++ gpio_direction_output(pdata->pin_mosi, 0); ++ s3c_gpio_setpull(pdata->pin_miso, S3C_GPIO_PULL_DOWN); ++ ++ return; ++ } ++ ++ /* back to normal */ ++ gpio_direction_output(pdata->pin_chip_select, 1); ++ gpio_direction_output(pdata->pin_clk, 1); ++ s3c_gpio_setpull(pdata->pin_miso, S3C_GPIO_PULL_NONE); ++ ++ s3c_gpio_cfgpin(pdata->pin_chip_select, S3C_GPIO_SFN(1)); ++ s3c_gpio_cfgpin(pdata->pin_clk, S3C_GPIO_SFN(1)); ++ s3c_gpio_cfgpin(pdata->pin_mosi, S3C_GPIO_SFN(1)); ++ s3c_gpio_cfgpin(pdata->pin_miso, S3C_GPIO_SFN(0)); ++ ++} ++#if 0 ++struct lis302dl_platform_data lis302_pdata = { ++ .name = "lis302", ++ .pin_chip_select= S3C64XX_GPC(3), /* NC */ ++ .pin_clk = OM_3D7K_GPIO_ACCEL_CLK, ++ .pin_mosi = OM_3D7K_GPIO_ACCEL_MOSI, ++ .pin_miso = OM_3D7K_GPIO_ACCEL_MISO, ++ .interrupt = OM_3D7K_IRQ_GSENSOR_1, ++ .open_drain = 0, ++ .lis302dl_bitbang = __3d7k_lis302dl_bitbang, ++ .lis302dl_bitbang_reg_read = om_3d7k_lis302dl_bitbang_read_reg, ++ .lis302dl_bitbang_reg_write = om_3d7k_lis302dl_bitbang_write_reg, ++ .lis302dl_suspend_io = om_3d7k_lis302dl_suspend_io, ++}; ++ ++static struct platform_device s3c_device_spi_acc1 = { ++ .name = "lis302dl", ++ .id = 1, ++ .dev = { ++ .platform_data = &lis302_pdata, ++ }, ++}; ++ ++#endif ++ ++/* framebuffer and LCD setup. */ ++ ++/* GPF15 = LCD backlight control ++ * GPF13 => Panel power ++ * GPN5 = LCD nRESET signal ++ * PWM_TOUT1 => backlight brightness ++ */ ++ ++static void om_3d7k_lcd_power_set(struct plat_lcd_data *pd, ++ unsigned int power) ++{ ++ ++} ++ ++static struct plat_lcd_data om_3d7k_lcd_power_data = { ++ .set_power = om_3d7k_lcd_power_set, ++}; ++ ++static struct platform_device om_3d7k_lcd_powerdev = { ++ .name = "platform-lcd", ++ .dev.parent = &s3c_device_fb.dev, ++ .dev.platform_data = &om_3d7k_lcd_power_data, ++}; ++ ++static struct s3c_fb_pd_win om_3d7k_fb_win0 = { ++ /* this is to ensure we use win0 */ ++ .win_mode = { ++ .pixclock = 40816, ++ .left_margin = 8, ++ .right_margin = 16, ++ .upper_margin = 2, ++ .lower_margin = 16, ++ .hsync_len = 8, ++ .vsync_len = 2, ++ .xres = 480, ++ .yres = 640, ++ }, ++ .max_bpp = 32, ++ .default_bpp = 16, ++}; ++ ++static void om_3d7k_fb_gpio_setup(void) ++{ ++ unsigned int gpio; ++ ++ /* GPI0, GPI1, GPI8 are for hardware version contrl. ++ * They should be set as input in order to prevent ++ * current leaking ++ */ ++ for (gpio = S3C64XX_GPI(2); gpio <= S3C64XX_GPI(15); gpio++) { ++ if (gpio != S3C64XX_GPI(8)) { ++ s3c_gpio_cfgpin(gpio, S3C_GPIO_SFN(2)); ++ s3c_gpio_setpull(gpio, S3C_GPIO_PULL_NONE); ++ } ++ } ++ ++ for (gpio = S3C64XX_GPJ(0); gpio <= S3C64XX_GPJ(11); gpio++) { ++ s3c_gpio_cfgpin(gpio, S3C_GPIO_SFN(2)); ++ s3c_gpio_setpull(gpio, S3C_GPIO_PULL_NONE); ++ } ++} ++ ++static struct s3c_fb_platdata om_3d7k_lcd_pdata __initdata = { ++ .setup_gpio = om_3d7k_fb_gpio_setup, ++ .win[0] = &om_3d7k_fb_win0, ++ .vidcon0 = VIDCON0_VIDOUT_RGB | VIDCON0_PNRMODE_RGB, ++ .vidcon1 = VIDCON1_INV_HSYNC | VIDCON1_INV_VSYNC, ++}; ++ ++ ++struct map_desc om_3d7k_6410_iodesc[] = {}; ++ ++static struct resource om_3d7k_button_resources[] = { ++ [0] = { ++ .start = 0, ++ .end = 0, ++ }, ++ [1] = { ++ .start = OM_3D7K_GPIO_HOLD, ++ .end = OM_3D7K_GPIO_HOLD, ++ }, ++ [2] = { ++ .start = OM_3D7K_GPIO_JACK_INSERT, ++ .end = OM_3D7K_GPIO_JACK_INSERT, ++ }, ++ [3] = { ++ .start = OM_3D7K_GPIO_KEY_PLUS, ++ .end = OM_3D7K_GPIO_KEY_PLUS, ++ }, ++ [4] = { ++ .start = OM_3D7K_GPIO_KEY_MINUS, ++ .end = OM_3D7K_GPIO_KEY_MINUS, ++ }, ++}; ++ ++static struct platform_device om_3d7k_button_dev = { ++ .name = "neo1973-button", ++ .num_resources = ARRAY_SIZE(om_3d7k_button_resources), ++ .resource = om_3d7k_button_resources, ++}; ++ ++ ++/********************** PMU ***************************/ ++/* ++ * OM_3D7K PMU Mapping info ++ * ++ * name maxcurr default Nom consumers ++ * ++ * AUTO 1100mA ON 3.3V 3.3V Main 3.3V rail ++ * DOWN1 500mA ON 1.2V 1.2V CPU VddARM, VddINT, VddMPLL, VddOTGI ++ * DOWN2 500mA ON 1.8V 1.8V CPU VddAlive via LDO, Memories, WLAN ++ * LED 25mA OFF 18V Backlight ++ * HCLDO 200mA OFF 2.8V Camera 2V8 ++ * LDO1 50mA ON 3.3V 3.3V Accel ++ * LDO2 50mA OFF 1.5V Camera 1V5 ++ * LDO3 50mA OFF 3.3V CODEC 3.3V ++ * LDO4 150mA ON 2.8V 2.7V uSD power ++ * LDO5 150mA OFF 3.0V GPS 3V ++ * LDO6 50mA ON 3.0V 3.0V LCM 3V ++ * ++ */ ++ ++ ++/* PMU driver info */ ++ ++ ++static struct regulator_consumer_supply ldo4_consumers[] = { ++ { ++ .dev = &s3c_device_hsmmc0.dev, ++ .supply = "SD_3V", ++ }, ++}; ++ ++static struct platform_device om_3d7k_features_dev = { ++ .name = "om-3d7k", ++}; ++ ++static struct regulator_consumer_supply ldo5_consumers[] = { ++ { ++ .dev = &om_3d7k_features_dev.dev, ++ .supply = "RF_3V", ++ }, ++}; ++ ++ ++static void om_3d7k_pmu_event_callback(struct pcf50633 *pcf, int irq) ++{ ++#if 0 ++ if (irq == PCF50633_IRQ_USBINS) { ++ schedule_delayed_work(&om_3d7k_charger_work, ++ GTA02_CHARGER_CONFIGURE_TIMEOUT); ++ return; ++ } else if (irq == PCF50633_IRQ_USBREM) { ++ cancel_delayed_work_sync(&om_3d7k_charger_work); ++ pcf50633_mbc_usb_curlim_set(pcf, 0); ++ om_3d7k_usb_vbus_draw = 0; ++ } ++ ++ bq27000_charging_state_change(&bq27000_battery_device); ++#endif ++} ++ ++static void om_3d7k_pcf50633_attach_child_devices(struct pcf50633 *pcf); ++static void om_3d7k_pmu_regulator_registered(struct pcf50633 *pcf, int id); ++ ++/* Global reference */ ++struct pcf50633 *om_3d7k_pcf; ++ ++struct pcf50633_platform_data om_3d7k_pcf_pdata = { ++ ++ .resumers = { ++ [0] = PCF50633_INT1_USBINS | ++ PCF50633_INT1_USBREM | ++ PCF50633_INT1_ALARM, ++ [1] = PCF50633_INT2_ONKEYF, ++ [2] = PCF50633_INT3_ONKEY1S ++ }, ++ .chg_ref_current_ma = 1000, ++ .reg_init_data = { ++ /* OM_3D7K: Main 3.3V rail */ ++ [PCF50633_REGULATOR_AUTO] = { ++ .constraints = { ++ .min_uV = 3300000, ++ .max_uV = 3300000, ++ .valid_modes_mask = REGULATOR_MODE_NORMAL, ++ .apply_uV = 1, ++ .state_mem = { ++ .enabled = 1, ++ }, ++ }, ++ .num_consumer_supplies = 0, ++ }, ++ /* OM_3D7K: CPU core power */ ++ [PCF50633_REGULATOR_DOWN1] = { ++ .constraints = { ++ .min_uV = 900000, ++ .max_uV = 1200000, ++ .valid_modes_mask = REGULATOR_MODE_NORMAL, ++ .apply_uV = 1, ++ }, ++ .num_consumer_supplies = 0, ++ }, ++ /* OM_3D7K: Memories */ ++ [PCF50633_REGULATOR_DOWN2] = { ++ .constraints = { ++ .min_uV = 1800000, ++ .max_uV = 1800000, ++ .valid_modes_mask = REGULATOR_MODE_NORMAL, ++ .apply_uV = 1, ++ .state_mem = { ++ .enabled = 1, ++ }, ++ }, ++ .num_consumer_supplies = 0, ++ }, ++ /* OM_3D7K: Camera 2V8 */ ++ [PCF50633_REGULATOR_HCLDO] = { ++ .constraints = { ++ .min_uV = 2800000, ++ .max_uV = 2800000, ++ .valid_modes_mask = REGULATOR_MODE_NORMAL, ++ }, ++ .num_consumer_supplies = 0, ++/* .consumer_supplies = hcldo_consumers, */ ++ }, ++ ++ /* OM_3D7K: Accel 3V3 */ ++ [PCF50633_REGULATOR_LDO1] = { ++ .constraints = { ++ .min_uV = 3300000, ++ .max_uV = 3300000, ++ .valid_modes_mask = REGULATOR_MODE_NORMAL, ++ .apply_uV = 1, ++ }, ++ .num_consumer_supplies = 0, ++ }, ++ /* OM_3D7K: Camera 1V5 */ ++ [PCF50633_REGULATOR_LDO2] = { ++ .constraints = { ++ .min_uV = 1500000, ++ .max_uV = 1500000, ++ .valid_modes_mask = REGULATOR_MODE_NORMAL, ++ .apply_uV = 1, ++ }, ++ .num_consumer_supplies = 0, ++ }, ++ /* OM_3D7K: Codec 3.3V */ ++ [PCF50633_REGULATOR_LDO3] = { ++ .constraints = { ++ .min_uV = 3300000, ++ .max_uV = 3300000, ++ .valid_modes_mask = REGULATOR_MODE_NORMAL, ++ .apply_uV = 1, ++ .always_on = 1, ++ }, ++ .num_consumer_supplies = 0, ++ }, ++ /* OM_3D7K: uSD Power */ ++ [PCF50633_REGULATOR_LDO4] = { ++ .constraints = { ++ .min_uV = 3000000, ++ .max_uV = 3000000, ++ .valid_modes_mask = REGULATOR_MODE_NORMAL, ++ .apply_uV = 1, ++ }, ++ .num_consumer_supplies = 1, ++ .consumer_supplies = ldo4_consumers, ++ }, ++ /* OM_3D7K: GPS 3V */ ++ [PCF50633_REGULATOR_LDO5] = { ++ .constraints = { ++ .min_uV = 3000000, ++ .max_uV = 3000000, ++ .valid_modes_mask = REGULATOR_MODE_NORMAL, ++ .apply_uV = 1, ++ }, ++ .num_consumer_supplies = 1, ++ .consumer_supplies = ldo5_consumers, ++ }, ++ /* OM_3D7K: LCM 3V */ ++ [PCF50633_REGULATOR_LDO6] = { ++ .constraints = { ++ .min_uV = 3000000, ++ .max_uV = 3000000, ++ .valid_modes_mask = REGULATOR_MODE_NORMAL, ++ .state_mem = { ++ .enabled = 1, ++ }, ++ }, ++ .num_consumer_supplies = 0, ++ }, ++ /* power for memories in suspend */ ++ [PCF50633_REGULATOR_MEMLDO] = { ++ .constraints = { ++ .min_uV = 1800000, ++ .max_uV = 1800000, ++ .valid_modes_mask = REGULATOR_MODE_NORMAL, ++ .state_mem = { ++ .enabled = 1, ++ }, ++ }, ++ .num_consumer_supplies = 0, ++ }, ++ ++ }, ++ .probe_done = om_3d7k_pcf50633_attach_child_devices, ++ .regulator_registered = om_3d7k_pmu_regulator_registered, ++ .mbc_event_callback = om_3d7k_pmu_event_callback, ++}; ++ ++static void om_3d7k_bl_set_intensity(int intensity) ++{ ++ struct pcf50633 *pcf = om_3d7k_pcf; ++ int old_intensity = pcf50633_reg_read(pcf, PCF50633_REG_LEDOUT); ++ int ret; ++ ++ intensity >>= 2; ++ ++ /* ++ * One code path that leads here is from a kernel panic. Trying to turn ++ * the backlight on just gives us a nearly endless stream of complaints ++ * and accomplishes nothing. We can't win. Just give up. ++ * ++ * In the unlikely event that there's another path leading here while ++ * we're atomic, we print at least a warning. ++ */ ++ if (in_atomic()) { ++ printk(KERN_ERR ++ "3d7k_bl_set_intensity called while atomic\n"); ++ return; ++ } ++ ++ old_intensity = pcf50633_reg_read(pcf, PCF50633_REG_LEDOUT); ++ if (intensity == old_intensity) ++ return; ++ ++ /* We can't do this anywhere else */ ++ pcf50633_reg_write(pcf, PCF50633_REG_LEDDIM, 5); ++ ++ if (!(pcf50633_reg_read(pcf, PCF50633_REG_LEDENA) & 3)) ++ old_intensity = 0; ++ ++ /* ++ * The PCF50633 cannot handle LEDOUT = 0 (datasheet p60) ++ * if seen, you have to re-enable the LED unit ++ */ ++ if (!intensity || !old_intensity) ++ pcf50633_reg_write(pcf, PCF50633_REG_LEDENA, 0); ++ ++ if (!intensity) /* illegal to set LEDOUT to 0 */ ++ ret = pcf50633_reg_set_bit_mask(pcf, PCF50633_REG_LEDOUT, 0x3f, ++ 2); ++ else ++ ret = pcf50633_reg_set_bit_mask(pcf, PCF50633_REG_LEDOUT, 0x3f, ++ intensity); ++ ++ if (intensity) ++ pcf50633_reg_write(pcf, PCF50633_REG_LEDENA, 2); ++ ++} ++ ++static struct generic_bl_info om_3d7k_bl_info = { ++ .name = "om-3d7k-bl", ++ .max_intensity = 0xff, ++ .default_intensity = 0x7f, ++ .set_bl_intensity = om_3d7k_bl_set_intensity, ++}; ++ ++static struct platform_device om_3d7k_bl_dev = { ++ .name = "generic-bl", ++ .id = 1, ++ .dev = { ++ .platform_data = &om_3d7k_bl_info, ++ }, ++}; ++ ++/* BQ27000 Battery */ ++static int om_3d7k_get_charger_online_status(void) ++{ ++ struct pcf50633 *pcf = om_3d7k_pcf; ++ ++ return pcf50633_mbc_get_status(pcf) & PCF50633_MBC_USB_ONLINE; ++} ++ ++static int om_3d7k_get_charger_active_status(void) ++{ ++ struct pcf50633 *pcf = om_3d7k_pcf; ++ ++ return pcf50633_mbc_get_status(pcf) & PCF50633_MBC_USB_ACTIVE; ++} ++ ++ ++struct bq27000_platform_data bq27000_pdata = { ++ .name = "battery", ++ .rsense_mohms = 20, ++ .hdq_read = hdq_read, ++ .hdq_write = hdq_write, ++ .hdq_initialized = hdq_initialized, ++ .get_charger_online_status = om_3d7k_get_charger_online_status, ++ .get_charger_active_status = om_3d7k_get_charger_active_status ++}; ++ ++struct platform_device bq27000_battery_device = { ++ .name = "bq27000-battery", ++ .dev = { ++ .platform_data = &bq27000_pdata, ++ }, ++}; ++ ++#ifdef CONFIG_HDQ_GPIO_BITBANG ++/* HDQ */ ++ ++static void om_3d7k_hdq_attach_child_devices(struct device *parent_device) ++{ ++ bq27000_battery_device.dev.parent = parent_device; ++ platform_device_register(&bq27000_battery_device); ++} ++ ++static void om_3d7k_hdq_gpio_direction_out(void) ++{ ++ unsigned long con; ++ void __iomem *regcon = S3C64XX_GPH_BASE; ++ ++ con = __raw_readl(regcon); ++ con &= ~(0xf << 28); ++ con |= 0x01 << 28; ++ __raw_writel(con, regcon); ++ ++ /* Set pull-up enabled */ ++ con = __raw_readl(regcon + 0x0c); ++ con |= 3 << 14; ++ __raw_writel(con, regcon + 0x0c); ++} ++ ++static void om_3d7k_hdq_gpio_direction_in(void) ++{ ++ unsigned long con; ++ void __iomem *regcon = S3C64XX_GPH_BASE; ++ ++ con = __raw_readl(regcon); ++ con &= ~(0xf << 28); ++ __raw_writel(con, regcon); ++} ++ ++static void om_3d7k_hdq_gpio_set_value(int val) ++{ ++ u32 dat; ++ void __iomem *base = S3C64XX_GPH_BASE; ++ ++ dat = __raw_readl(base + 0x08); ++ if (val) ++ dat |= 1 << 7; ++ else ++ dat &= ~(1 << 7); ++ ++ __raw_writel(dat, base + 0x08); ++} ++ ++static int om_3d7k_hdq_gpio_get_value(void) ++{ ++ u32 dat; ++ void *base = S3C64XX_GPH_BASE; ++ ++ dat = __raw_readl(base + 0x08); ++ ++ return dat & (1 << 7); ++} ++ ++static struct resource om_3d7k_hdq_resources[] = { ++ [0] = { ++ .start = S3C64XX_GPH(7), ++ .end = S3C64XX_GPH(7), ++ }, ++}; ++ ++struct hdq_platform_data om_3d7k_hdq_platform_data = { ++ .attach_child_devices = om_3d7k_hdq_attach_child_devices, ++ .gpio_dir_out = om_3d7k_hdq_gpio_direction_out, ++ .gpio_dir_in = om_3d7k_hdq_gpio_direction_in, ++ .gpio_set = om_3d7k_hdq_gpio_set_value, ++ .gpio_get = om_3d7k_hdq_gpio_get_value, ++ ++ .enable_fiq = om_3d7k_fiq_enable, ++ .disable_fiq = om_3d7k_fiq_disable, ++ .kick_fiq = om_3d7k_fiq_kick, ++ ++}; ++ ++struct platform_device om_3d7k_hdq_device = { ++ .name = "hdq", ++ .num_resources = 1, ++ .resource = om_3d7k_hdq_resources, ++ .dev = { ++ .platform_data = &om_3d7k_hdq_platform_data, ++ }, ++}; ++#endif ++ ++static void om_3d7k_lp5521_chip_enable(int level) ++{ ++ gpio_direction_output(OM_3D7K_GPIO_LED_EN, level); ++ udelay(500); ++} ++ ++static struct lp5521_platform_data om_3d7k_lp5521_pdata = { ++ .channels = { ++ [LP5521_BLUE] = LP5521_CONNECTED, ++ [LP5521_GREEN] = LP5521_CONNECTED, ++ [LP5521_RED] = LP5521_NC, ++ }, ++ .ext_enable = om_3d7k_lp5521_chip_enable, ++}; ++ ++static void om_3d7k_pcap7200_reset(void) ++{ ++ gpio_direction_output(OM_3D7K_GPIO_TP_RESET, 1); ++ udelay(10); ++ gpio_direction_output(OM_3D7K_GPIO_TP_RESET, 0); ++} ++ ++static struct pcap7200_platform_data om_3d7k_pcap7200_pdata = { ++ .mode = MULTI_TOUCH, ++ .reset = om_3d7k_pcap7200_reset, ++}; ++ ++static struct i2c_board_info om_3d7k_i2c_devs[] __initdata = { ++ { ++ I2C_BOARD_INFO("pcf50633", 0x73), ++ .irq = OM_3D7K_IRQ_PMU, ++ .platform_data = &om_3d7k_pcf_pdata, ++ }, ++ { ++ I2C_BOARD_INFO("pcap7200", 0x0a), ++ .irq = OM_3D7K_IRQ_TOUCH, ++ .platform_data = &om_3d7k_pcap7200_pdata, ++ }, ++ { ++ I2C_BOARD_INFO("lp5521", 0x32), ++ /* mark this temporarily, since LED INT is connected ++ * to EXT group6_9, the handling of EXT group1~group9 ++ * is not implemented. Besides, we don't need this IRQ ++ * now ++ */ ++#if 0 ++ .irq = OM_3D7K_IRQ_LED, ++#endif ++ .platform_data = &om_3d7k_lp5521_pdata, ++ }, ++ { ++ I2C_BOARD_INFO("wm8753", 0x1a), ++ }, ++}; ++ ++struct platform_device s3c24xx_pwm_device = { ++ .name = "s3c24xx_pwm", ++ .num_resources = 0, ++}; ++ ++struct platform_device om_3d7k_device_spi_lcm; ++ ++static struct platform_device *om_3d7k_devices[] __initdata = { ++ &s3c_device_fb, ++ &s3c_device_i2c0, ++ &om_3d7k_device_spi_lcm, ++ &s3c_device_usbgadget, ++ &s3c24xx_pwm_device, ++#ifdef CONFIG_S3C_DEV_CAMIF ++ &s3c_device_camif, ++#endif ++}; ++ ++ ++static void om_3d7k_pmu_regulator_registered(struct pcf50633 *pcf, int id) ++{ ++ struct platform_device *regulator, *pdev; ++ ++ regulator = pcf->regulator_pdev[id]; ++ ++ switch(id) { ++ case PCF50633_REGULATOR_LDO4: ++ pdev = &s3c_device_hsmmc0; /* uSD card */ ++ break; ++ case PCF50633_REGULATOR_LDO5: /* GPS regulator */ ++ pdev = &om_3d7k_features_dev; ++ break; ++ case PCF50633_REGULATOR_LDO6: ++ pdev = &om_3d7k_lcd_powerdev; ++ break; ++ default: ++ return; ++ } ++ ++ pdev->dev.parent = ®ulator->dev; ++ platform_device_register(pdev); ++} ++ ++static struct platform_device *om_3d7k_devices_pmu_children[] = { ++ &om_3d7k_button_dev, ++// &s3c_device_spi_acc1, /* relies on PMU reg for power */ ++ &s3c_device_usb, ++}; ++ ++/* this is called when pc50633 is probed, unfortunately quite late in the ++ * day since it is an I2C bus device. Here we can belatedly define some ++ * platform devices with the advantage that we can mark the pcf50633 as the ++ * parent. This makes them get suspended and resumed with their parent ++ * the pcf50633 still around. ++ */ ++ ++static void om_3d7k_pcf50633_attach_child_devices(struct pcf50633 *pcf) ++{ ++ int n; ++ ++ om_3d7k_pcf = pcf; ++ ++ for (n = 0; n < ARRAY_SIZE(om_3d7k_devices_pmu_children); n++) ++ om_3d7k_devices_pmu_children[n]->dev.parent = pcf->dev; ++ ++ platform_add_devices(om_3d7k_devices_pmu_children, ++ ARRAY_SIZE(om_3d7k_devices_pmu_children)); ++ ++ /* backlight device should be registered until pcf50633 probe is done */ ++ om_3d7k_bl_dev.dev.parent = &om_3d7k_device_spi_lcm.dev; ++ platform_device_register(&om_3d7k_bl_dev); ++ ++ /* Switch on backlight. Qi does not do it for us */ ++ pcf50633_reg_write(pcf, PCF50633_REG_LEDENA, 0x00); ++ pcf50633_reg_write(pcf, PCF50633_REG_LEDDIM, 0x01); ++ pcf50633_reg_write(pcf, PCF50633_REG_LEDENA, 0x01); ++} ++ ++static void om_3d7k_l1k002_pwronoff(int level) ++{ ++ gpio_direction_output(OM_3D7K_GPIO_LCM_SD, 1); ++ udelay(15); ++ ++ gpio_direction_output(OM_3D7K_GPIO_LCM_RESET, !!level); ++ ++ if (level){ ++ udelay(15); ++ gpio_direction_output(OM_3D7K_GPIO_LCM_SD, 0); ++ } ++} ++ ++const struct l1k002_platform_data om_3d7k_l1k002_pdata = { ++ .pwr_onoff = om_3d7k_l1k002_pwronoff, ++}; ++ ++static struct spi_board_info om_3d7k_spi_board_info[] = { ++ { ++ .modalias = "l1k002", ++ .platform_data = &om_3d7k_l1k002_pdata, ++ /* controller_data */ ++ /* irq */ ++ .max_speed_hz = 10 * 1000 * 1000, ++ .bus_num = 1, ++ /* chip_select */ ++ }, ++}; ++ ++static void om_3d7k_jbt6k74_probe_completed(struct device *dev) ++{ ++ dev_info(dev, "device attached\n"); ++} ++ ++const struct jbt6k74_platform_data jbt6k74_pdata = { ++ .probe_completed = om_3d7k_jbt6k74_probe_completed, ++}; ++ ++static struct spi_board_info alt_om_3d7k_spi_board_info[] = { ++ { ++ .modalias = "jbt6k74", ++ .platform_data = &jbt6k74_pdata, ++ /* controller_data */ ++ /* irq */ ++ .max_speed_hz = 100 * 1000, ++ .bus_num = 1, ++ /* chip_select */ ++ }, ++}; ++ ++static void spi_gpio_cs(struct s3c64xx_spigpio_info *spi, int csidx, int cs) ++{ ++ switch (cs) { ++ case BITBANG_CS_ACTIVE: ++ gpio_direction_output(OM_3D7K_GPIO_LCM_CS, 0); ++ break; ++ case BITBANG_CS_INACTIVE: ++ gpio_direction_output(OM_3D7K_GPIO_LCM_CS, 1); ++ break; ++ } ++} ++ ++static struct s3c64xx_spigpio_info spi_gpio_cfg = { ++ .pin_clk = OM_3D7K_GPIO_LCM_CLK, ++ .pin_mosi = OM_3D7K_GPIO_LCM_MOSI, ++ /* no pinout to MISO */ ++ .chip_select = &spi_gpio_cs, ++ .num_chipselect = 1, ++ .bus_num = 1, ++}; ++ ++struct platform_device om_3d7k_device_spi_lcm = { ++ .name = "spi_s3c64xx_gpio", ++ .id = 1, ++ .dev = { ++ .platform_data = &spi_gpio_cfg, ++ }, ++}; ++ ++static int attached_lcm; ++ ++static int __init om3d7k_lcm_probe(char *s) ++{ ++ if (!strcmp(s, "jbt6k74")) ++ attached_lcm = 1; ++ ++ return 1; ++} ++__setup("om_3d7k_lcm=", om3d7k_lcm_probe); ++ ++extern void s3c64xx_init_io(struct map_desc *, int); ++ ++struct s3c_plat_otg_data s3c_hs_otg_plat_data = { ++ .phyclk = 0 ++}; ++ ++/* USB */ ++static struct s3c2410_hcd_info om3d7k_usb_info = { ++ .port[0] = { ++ .flags = S3C_HCDFLG_USED, ++ }, ++ .port[1] = { ++ .flags = 0, ++ }, ++}; ++ ++static void __init om_3d7k_map_io(void) ++{ ++ s3c64xx_init_io(om_3d7k_6410_iodesc, ARRAY_SIZE(om_3d7k_6410_iodesc)); ++ s3c24xx_init_clocks(12000000); ++ s3c24xx_init_uarts(om_3d7k_uartcfgs, ARRAY_SIZE(om_3d7k_uartcfgs)); ++} ++ ++static void __init om_3d7k_machine_init(void) ++{ ++ s3c_pm_init(); ++ ++ s3c_device_usb.dev.platform_data = &om3d7k_usb_info; ++ s3c_device_usbgadget.dev.platform_data = &s3c_hs_otg_plat_data; ++ ++ s3c_i2c0_set_platdata(NULL); ++ s3c_fb_set_platdata(&om_3d7k_lcd_pdata); ++ ++ i2c_register_board_info(0, om_3d7k_i2c_devs, ++ ARRAY_SIZE(om_3d7k_i2c_devs)); ++ if (attached_lcm) ++ spi_register_board_info(alt_om_3d7k_spi_board_info, ++ ARRAY_SIZE(alt_om_3d7k_spi_board_info)); ++ else ++ spi_register_board_info(om_3d7k_spi_board_info, ++ ARRAY_SIZE(om_3d7k_spi_board_info)); ++ ++ platform_add_devices(om_3d7k_devices, ARRAY_SIZE(om_3d7k_devices)); ++ ++ /* Register the HDQ and vibrator as children of pwm device */ ++ om_3d7k_hdq_device.dev.parent = &s3c24xx_pwm_device.dev; ++ platform_device_register(&om_3d7k_hdq_device); ++} ++ ++MACHINE_START(OM_3D7K, "OM-3D7K") ++ /* Maintainer: Andy Green <andy@openmoko.com> */ ++ .phys_io = S3C_PA_UART & 0xfff00000, ++ .io_pg_offst = (((u32)S3C_VA_UART) >> 18) & 0xfffc, ++ .boot_params = S3C64XX_PA_SDRAM + 0x100, ++ ++ .init_irq = s3c6410_init_irq, ++ .map_io = om_3d7k_map_io, ++ .init_machine = om_3d7k_machine_init, ++ .timer = &s3c24xx_timer, ++MACHINE_END ++ +diff -ruN --exclude='*.orig' --exclude='*.rej' linux-2.6.29-rc3.owrt/arch/arm/mach-s3c6410/mach-smdk6410.c linux-2.6.29-rc3.owrt.om/arch/arm/mach-s3c6410/mach-smdk6410.c +--- linux-2.6.29-rc3.owrt/arch/arm/mach-s3c6410/mach-smdk6410.c 2009-05-10 22:08:41.000000000 +0200 ++++ linux-2.6.29-rc3.owrt.om/arch/arm/mach-s3c6410/mach-smdk6410.c 2009-05-10 22:27:59.000000000 +0200 +@@ -39,14 +39,20 @@ + #include <asm/mach-types.h> + + #include <plat/regs-serial.h> ++#include <plat/regs-modem.h> ++#include <plat/regs-gpio.h> ++#include <plat/regs-sys.h> + #include <plat/iic.h> + #include <plat/fb.h> ++#include <plat/pm.h> + + #include <plat/s3c6410.h> + #include <plat/clock.h> + #include <plat/devs.h> + #include <plat/cpu.h> + ++#include <plat/regs-usb-hs-otg.h> ++ + #define UCON S3C2410_UCON_DEFAULT | S3C2410_UCON_UCLK + #define ULCON S3C2410_LCON_CS8 | S3C2410_LCON_PNONE | S3C2410_LCON_STOPB + #define UFCON S3C2410_UFCON_RXTRIG8 | S3C2410_UFCON_FIFOMODE +@@ -141,7 +147,10 @@ + &s3c_device_i2c0, + &s3c_device_i2c1, + &s3c_device_fb, ++ &s3c_device_usb, + &smdk6410_lcd_powerdev, ++ &s3c_device_usbgadget, ++ + }; + + static struct i2c_board_info i2c_devs0[] __initdata = { +@@ -155,13 +164,36 @@ + + static void __init smdk6410_map_io(void) + { ++ u32 tmp; ++ + s3c64xx_init_io(smdk6410_iodesc, ARRAY_SIZE(smdk6410_iodesc)); + s3c24xx_init_clocks(12000000); + s3c24xx_init_uarts(smdk6410_uartcfgs, ARRAY_SIZE(smdk6410_uartcfgs)); ++ ++ /* set the LCD type */ ++ ++ tmp = __raw_readl(S3C64XX_SPCON); ++ tmp &= ~S3C64XX_SPCON_LCD_SEL_MASK; ++ tmp |= S3C64XX_SPCON_LCD_SEL_RGB; ++ __raw_writel(tmp, S3C64XX_SPCON); ++ ++ /* remove the lcd bypass */ ++ tmp = __raw_readl(S3C64XX_MODEM_MIFPCON); ++ tmp &= ~MIFPCON_LCD_BYPASS; ++ __raw_writel(tmp, S3C64XX_MODEM_MIFPCON); + } + ++struct s3c_plat_otg_data s3c_hs_otg_plat_data = { ++ .phyclk = REF_CLK_OSCC ++}; ++ ++ + static void __init smdk6410_machine_init(void) + { ++ s3c_pm_init(); ++ ++ s3c_device_usbgadget.dev.platform_data = &s3c_hs_otg_plat_data; ++ + s3c_i2c0_set_platdata(NULL); + s3c_i2c1_set_platdata(NULL); + s3c_fb_set_platdata(&smdk6410_lcd_pdata); +diff -ruN --exclude='*.orig' --exclude='*.rej' linux-2.6.29-rc3.owrt/arch/arm/mach-s3c6410/Makefile linux-2.6.29-rc3.owrt.om/arch/arm/mach-s3c6410/Makefile +--- linux-2.6.29-rc3.owrt/arch/arm/mach-s3c6410/Makefile 2009-05-10 22:05:04.000000000 +0200 ++++ linux-2.6.29-rc3.owrt.om/arch/arm/mach-s3c6410/Makefile 2009-05-10 22:27:59.000000000 +0200 +@@ -21,3 +21,6 @@ + # machine support + + obj-$(CONFIG_MACH_SMDK6410) += mach-smdk6410.o ++obj-$(CONFIG_MACH_OM_3D7K) += mach-om-3d7k.o \ ++ om-3d7k-features.o ++ +diff -ruN --exclude='*.orig' --exclude='*.rej' linux-2.6.29-rc3.owrt/arch/arm/mach-s3c6410/om-3d7k-features.c linux-2.6.29-rc3.owrt.om/arch/arm/mach-s3c6410/om-3d7k-features.c +--- linux-2.6.29-rc3.owrt/arch/arm/mach-s3c6410/om-3d7k-features.c 1970-01-01 01:00:00.000000000 +0100 ++++ linux-2.6.29-rc3.owrt.om/arch/arm/mach-s3c6410/om-3d7k-features.c 2009-05-10 22:27:59.000000000 +0200 +@@ -0,0 +1,273 @@ ++/* ++ * Support for features of Openmoko 3D7K ++ * ++ * (C) 2008 by Openmoko Inc. ++ * Author: Andy Green <andy@openmoko.com> ++ * All rights reserved. ++ * ++ * Somewhat based on the GTA01 / 02 neo1973_pm_ stuff mainly by Harald Welte ++ * ++ * 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/init.h> ++#include <linux/kernel.h> ++#include <linux/delay.h> ++#include <linux/platform_device.h> ++ ++#include <mach/hardware.h> ++#include <mach/om-3d7k.h> ++#include <asm/mach-types.h> ++ ++#include <linux/regulator/consumer.h> ++#include <linux/mfd/pcf50633/core.h> ++#include <linux/mfd/pcf50633/gpio.h> ++#include <linux/mmc/host.h> ++ ++#include <plat/sdhci.h> ++#include <plat/devs.h> ++ ++#include <plat/gpio-cfg.h> ++ ++enum feature { ++ OM_3D7K_GSM, /* GSM module */ ++ OM_3D7K_USBHOST, /* USB Host power generation */ ++ OM_3D7K_VIB, /* Vibrator */ ++ ++ OM_3D7K_FEATURE_COUNT /* always last */ ++}; ++ ++ ++struct om_3d7k_feature_info { ++ const char * name; ++ int depower_on_suspend; ++ int on; ++}; ++ ++static struct om_3d7k_feature_info feature_info[OM_3D7K_FEATURE_COUNT] = { ++ [OM_3D7K_GSM] = { "gsm_power", 0, 0 }, ++ [OM_3D7K_USBHOST] = { "usbhost_power", 1, 0 }, ++ [OM_3D7K_VIB] = { "vibrator_power", 1, 0 }, ++}; ++ ++static struct regulator *gps_regulator; ++ ++ ++ ++static void om_3d7k_features_pwron_set_on(enum feature feature) ++{ ++ switch (feature) { ++ case OM_3D7K_GSM: ++ /* give power to GSM module */ ++ s3c_gpio_setpull(OM_3D7K_GPIO_N_MODEM_RESET, S3C_GPIO_PULL_NONE); ++ s3c_gpio_setpull(OM_3D7K_GPIO_MODEM_ON, S3C_GPIO_PULL_NONE); ++ s3c_gpio_cfgpin(OM_3D7K_GPIO_N_MODEM_RESET, S3C_GPIO_SFN(1)); ++ s3c_gpio_cfgpin(OM_3D7K_GPIO_MODEM_ON, S3C_GPIO_SFN(1)); ++ gpio_direction_output(OM_3D7K_GPIO_N_MODEM_RESET, 0); ++ gpio_direction_output(OM_3D7K_GPIO_MODEM_ON, 1); ++ msleep(10); ++ gpio_direction_output(OM_3D7K_GPIO_MODEM_ON, 0); ++ msleep(150); ++ gpio_direction_output(OM_3D7K_GPIO_N_MODEM_RESET, 1); ++ msleep(300); ++ gpio_direction_output(OM_3D7K_GPIO_MODEM_ON, 1); ++ break; ++ case OM_3D7K_USBHOST: ++ pcf50633_gpio_set(om_3d7k_pcf, PCF50633_GPO, 1); ++ break; ++ case OM_3D7K_VIB: ++ gpio_direction_output(OM_3D7K_GPIO_VIBRATOR_ON, 1); ++ break; ++ default: ++ break; ++ } ++} ++ ++static void om_3d7k_features_pwron_set_off(enum feature feature) ++{ ++ switch (feature) { ++ case OM_3D7K_GSM: ++ /* remove power from WLAN / BT module */ ++ s3c_gpio_cfgpin(OM_3D7K_GPIO_MODEM_ON, S3C_GPIO_SFN(1)); ++ gpio_direction_output(OM_3D7K_GPIO_MODEM_ON, 0); ++ msleep(1100); ++ gpio_direction_output(OM_3D7K_GPIO_MODEM_ON, 1); ++ break; ++ case OM_3D7K_USBHOST: ++ pcf50633_gpio_set(om_3d7k_pcf, PCF50633_GPO, 0); ++ break; ++ case OM_3D7K_VIB: ++ gpio_direction_output(OM_3D7K_GPIO_VIBRATOR_ON, 0); ++ break; ++ default: ++ break; ++ } ++} ++ ++static void om_3d7k_features_pwron_set(enum feature feature, int on) ++{ ++ if ((on) && (!feature_info[feature].on)) ++ om_3d7k_features_pwron_set_on(feature); ++ else ++ if ((!on) && (feature_info[feature].on)) ++ om_3d7k_features_pwron_set_off(feature); ++} ++ ++static ssize_t om_3d7k_feature_read(struct device *dev, ++ struct device_attribute *attr, char *buf) ++{ ++ int on; ++ int feature = 0; ++ int hit = 0; ++ ++ while (!hit && feature < OM_3D7K_FEATURE_COUNT) { ++ if (!strcmp(attr->attr.name, feature_info[feature].name)) ++ hit = 1; ++ else ++ feature++; ++ } ++ ++ if (!hit) ++ return -EINVAL; ++ ++ switch (feature) { ++ case OM_3D7K_USBHOST: ++ on = pcf50633_gpio_get(om_3d7k_pcf, PCF50633_GPO); ++ break; ++ default: ++ on = feature_info[feature].on; ++ } ++ ++ *buf++ = '0' + on; ++ *buf++='\n'; ++ *buf = '\0'; ++ ++ return 3; ++} ++ ++static ssize_t om_3d7k_feature_write(struct device *dev, ++ struct device_attribute *attr, ++ const char *buf, size_t count) ++{ ++ int on = !!simple_strtoul(buf, NULL, 10); ++ int feature = 0; ++ int hit = 0; ++ ++ while (!hit && feature < OM_3D7K_FEATURE_COUNT) { ++ if (!strcmp(attr->attr.name, feature_info[feature].name)) ++ hit = 1; ++ else ++ feature++; ++ } ++ ++ if (!hit) ++ return -EINVAL; ++ ++ om_3d7k_features_pwron_set(feature, on); ++ feature_info[feature].on = on; ++ ++ return count; ++} ++ ++ ++static DEVICE_ATTR(gsm_power, 0644, om_3d7k_feature_read, ++ om_3d7k_feature_write); ++ ++static DEVICE_ATTR(usbhost_power, 0644, om_3d7k_feature_read, ++ om_3d7k_feature_write); ++ ++static DEVICE_ATTR(vibrator_power, 0644, om_3d7k_feature_read, ++ om_3d7k_feature_write); ++ ++ ++static struct attribute *om_3d7k_features_sysfs_entries[] = { ++ &dev_attr_gsm_power.attr, ++ &dev_attr_usbhost_power.attr, ++ &dev_attr_vibrator_power.attr, ++ NULL ++}; ++ ++ ++static struct attribute_group om_3d7k_features_attr_group = { ++ .name = NULL, ++ .attrs = om_3d7k_features_sysfs_entries, ++}; ++ ++static int __init om_3d7k_features_probe(struct platform_device *pdev) ++{ ++ gps_regulator = regulator_get(&pdev->dev, "RF_3V"); ++ dev_info(&pdev->dev, "starting\n"); ++ ++ return sysfs_create_group(&pdev->dev.kobj, ++ &om_3d7k_features_attr_group); ++} ++ ++static int om_3d7k_features_remove(struct platform_device *pdev) ++{ ++ ++ regulator_put(gps_regulator); ++ sysfs_remove_group(&pdev->dev.kobj, &om_3d7k_features_attr_group); ++ ++ return 0; ++} ++ ++ ++#ifdef CONFIG_PM ++static int om_3d7k_features_suspend(struct platform_device *pdev, ++ pm_message_t state) ++{ ++ int feature; ++ ++ for (feature = 0; feature < OM_3D7K_FEATURE_COUNT; feature++) ++ if (feature_info[feature].depower_on_suspend) ++ om_3d7k_features_pwron_set_off(feature); ++ ++ return 0; ++} ++ ++static int om_3d7k_features_resume(struct platform_device *pdev) ++{ ++ int feature; ++ ++ for (feature = 0; feature < OM_3D7K_FEATURE_COUNT; feature++) ++ if (feature_info[feature].depower_on_suspend) ++ if (feature_info[feature].on) ++ om_3d7k_features_pwron_set_on(feature); ++ ++ return 0; ++} ++#else ++#define om_3d7k_features_suspend NULL ++#define om_3d7k_features_resume NULL ++#endif ++ ++static struct platform_driver om_3d7k_features_driver = { ++ .probe = om_3d7k_features_probe, ++ .remove = om_3d7k_features_remove, ++ .suspend = om_3d7k_features_suspend, ++ .resume = om_3d7k_features_resume, ++ .driver = { ++ .name = "om-3d7k", ++ }, ++}; ++ ++static int __devinit om_3d7k_features_init(void) ++{ ++ return platform_driver_register(&om_3d7k_features_driver); ++} ++ ++static void om_3d7k_features_exit(void) ++{ ++ platform_driver_unregister(&om_3d7k_features_driver); ++} ++ ++module_init(om_3d7k_features_init); ++module_exit(om_3d7k_features_exit); ++ ++MODULE_LICENSE("GPL"); ++MODULE_AUTHOR("Andy Green <andy@openmoko.com>"); ++MODULE_DESCRIPTION("Openmoko OM_3D7K Feature Driver"); +diff -ruN --exclude='*.orig' --exclude='*.rej' linux-2.6.29-rc3.owrt/arch/arm/mach-s3c6410/setup-sdhci.c linux-2.6.29-rc3.owrt.om/arch/arm/mach-s3c6410/setup-sdhci.c +--- linux-2.6.29-rc3.owrt/arch/arm/mach-s3c6410/setup-sdhci.c 2009-05-10 22:05:04.000000000 +0200 ++++ linux-2.6.29-rc3.owrt.om/arch/arm/mach-s3c6410/setup-sdhci.c 2009-05-10 22:27:59.000000000 +0200 +@@ -48,7 +48,8 @@ + s3c_gpio_setpull(gpio, S3C_GPIO_PULL_NONE); + } + +- s3c_gpio_setpull(S3C64XX_GPG(6), S3C_GPIO_PULL_UP); ++ /* FIXME this needs defining in machine as to if we even have CD */ ++ s3c_gpio_setpull(S3C64XX_GPG(6), S3C_GPIO_PULL_DOWN); + s3c_gpio_cfgpin(S3C64XX_GPG(6), S3C_GPIO_SFN(2)); + } + +@@ -79,7 +80,7 @@ + else + ctrl3 = (S3C_SDHCI_CTRL3_FCSEL1 | S3C_SDHCI_CTRL3_FCSEL0); + +- printk(KERN_INFO "%s: CTRL 2=%08x, 3=%08x\n", __func__, ctrl2, ctrl3); ++ printk(KERN_INFO "%s: %p CTRL 2=%08x, 3=%08x\n", __func__, r, ctrl2, ctrl3); + writel(ctrl2, r + S3C_SDHCI_CONTROL2); + writel(ctrl3, r + S3C_SDHCI_CONTROL3); + } +@@ -94,9 +95,9 @@ + /* Set all the necessary GPG pins to special-function 0 */ + for (gpio = S3C64XX_GPH(0); gpio < end; gpio++) { + s3c_gpio_cfgpin(gpio, S3C_GPIO_SFN(2)); +- s3c_gpio_setpull(gpio, S3C_GPIO_PULL_NONE); ++ s3c_gpio_setpull(gpio, S3C_GPIO_PULL_UP); + } + +- s3c_gpio_setpull(S3C64XX_GPG(6), S3C_GPIO_PULL_UP); +- s3c_gpio_cfgpin(S3C64XX_GPG(6), S3C_GPIO_SFN(3)); ++// s3c_gpio_setpull(S3C64XX_GPG(6), S3C_GPIO_PULL_UP); ++// s3c_gpio_cfgpin(S3C64XX_GPG(6), S3C_GPIO_SFN(3)); + } +diff -ruN --exclude='*.orig' --exclude='*.rej' linux-2.6.29-rc3.owrt/arch/arm/mach-shark/include/mach/io.h linux-2.6.29-rc3.owrt.om/arch/arm/mach-shark/include/mach/io.h +--- linux-2.6.29-rc3.owrt/arch/arm/mach-shark/include/mach/io.h 2009-05-10 22:05:04.000000000 +0200 ++++ linux-2.6.29-rc3.owrt.om/arch/arm/mach-shark/include/mach/io.h 2009-05-10 22:27:59.000000000 +0200 +@@ -14,7 +14,7 @@ + #define PCIO_BASE 0xe0000000 + #define IO_SPACE_LIMIT 0xffffffff + +-#define __io(a) ((void __iomem *)(PCIO_BASE + (a))) ++#define __io(a) __typesafe_io(PCIO_BASE + (a)) + #define __mem_pci(addr) (addr) + + #endif +diff -ruN --exclude='*.orig' --exclude='*.rej' linux-2.6.29-rc3.owrt/arch/arm/Makefile linux-2.6.29-rc3.owrt.om/arch/arm/Makefile +--- linux-2.6.29-rc3.owrt/arch/arm/Makefile 2009-05-10 22:05:04.000000000 +0200 ++++ linux-2.6.29-rc3.owrt.om/arch/arm/Makefile 2009-05-10 22:27:59.000000000 +0200 +@@ -55,7 +55,8 @@ + arch-$(CONFIG_CPU_32v6K) :=-D__LINUX_ARM_ARCH__=6 $(call cc-option,-march=armv6k,-march=armv5t -Wa$(comma)-march=armv6k) + endif + arch-$(CONFIG_CPU_32v5) :=-D__LINUX_ARM_ARCH__=5 $(call cc-option,-march=armv5te,-march=armv4t) +-arch-$(CONFIG_CPU_32v4T) :=-D__LINUX_ARM_ARCH__=4 -march=armv4t ++# We can't load armv4t modules, but still need to assemble some armv4t code to be linked in. ++arch-$(CONFIG_CPU_32v4T) :=-D__LINUX_ARM_ARCH__=4 -march=armv4 -Wa,-march=armv4t + arch-$(CONFIG_CPU_32v4) :=-D__LINUX_ARM_ARCH__=4 -march=armv4 + arch-$(CONFIG_CPU_32v3) :=-D__LINUX_ARM_ARCH__=3 -march=armv3 + +diff -ruN --exclude='*.orig' --exclude='*.rej' linux-2.6.29-rc3.owrt/arch/arm/plat-s3c/dev-camif.c linux-2.6.29-rc3.owrt.om/arch/arm/plat-s3c/dev-camif.c +--- linux-2.6.29-rc3.owrt/arch/arm/plat-s3c/dev-camif.c 1970-01-01 01:00:00.000000000 +0100 ++++ linux-2.6.29-rc3.owrt.om/arch/arm/plat-s3c/dev-camif.c 2009-05-10 22:27:59.000000000 +0200 +@@ -0,0 +1,65 @@ ++/* linux/arch/arm/plat-s3c/dev-camif.c ++ * ++ * Copyright 2009 Openmoko, Inc. ++ * Werner Almesberger <werner@openmoko.org> ++ * ++ * based on dev-hsmmc.c which is ++ * ++ * Copyright (c) 2008 Simtec Electronics ++ * Ben Dooks <ben@simtec.co.uk> ++ * http://armlinux.simtec.co.uk/ ++ * ++ * S3C series device definition for camera interface devices ++ * ++ * 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/platform_device.h> ++#include <linux/mmc/host.h> ++ ++#include <mach/map.h> ++#include <plat/devs.h> ++#include <plat/cpu.h> ++ ++ ++#define S3C6400_PA_CAMIF 0x78000000 ++#define S3C24XX_SZ_CAMIF (0x1000) ++ ++ ++static struct resource s3c_camif_resource[] = { ++ [0] = { ++ .start = S3C6400_PA_CAMIF, ++ .end = S3C6400_PA_CAMIF + S3C24XX_SZ_CAMIF - 1, ++ .flags = IORESOURCE_MEM, ++ }, ++ [1] = { ++ .start = IRQ_CAMIF_C, ++ .end = IRQ_CAMIF_C, ++ .flags = IORESOURCE_IRQ, ++ }, ++ [2] = { ++ .start = IRQ_CAMIF_P, ++ .end = IRQ_CAMIF_P, ++ .flags = IORESOURCE_IRQ, ++ } ++ ++}; ++ ++static u64 s3c_device_camif_dmamask = 0xffffffffUL; ++ ++struct platform_device s3c_device_camif = { ++ .name = "s3c-camif", ++ .id = -1, ++ .num_resources = ARRAY_SIZE(s3c_camif_resource), ++ .resource = s3c_camif_resource, ++ .dev = { ++ .dma_mask = &s3c_device_camif_dmamask, ++ .coherent_dma_mask = 0xffffffffUL ++ } ++}; ++ ++EXPORT_SYMBOL(s3c_device_camif); ++ +diff -ruN --exclude='*.orig' --exclude='*.rej' linux-2.6.29-rc3.owrt/arch/arm/plat-s3c/dev-i2c0.c linux-2.6.29-rc3.owrt.om/arch/arm/plat-s3c/dev-i2c0.c +--- linux-2.6.29-rc3.owrt/arch/arm/plat-s3c/dev-i2c0.c 2009-05-10 22:05:04.000000000 +0200 ++++ linux-2.6.29-rc3.owrt.om/arch/arm/plat-s3c/dev-i2c0.c 2009-05-10 22:27:59.000000000 +0200 +@@ -51,8 +51,8 @@ + .flags = 0, + .slave_addr = 0x10, + .bus_freq = 100*1000, +- .max_freq = 400*1000, +- .sda_delay = S3C2410_IICLC_SDA_DELAY5 | S3C2410_IICLC_FILTER_ON, ++ .max_freq = 100*1000, ++ .sda_delay = S3C2410_IICLC_SDA_DELAY15 | S3C2410_IICLC_FILTER_ON, + }; + + void __init s3c_i2c0_set_platdata(struct s3c2410_platform_i2c *pd) +diff -ruN --exclude='*.orig' --exclude='*.rej' linux-2.6.29-rc3.owrt/arch/arm/plat-s3c/dev-usb.c linux-2.6.29-rc3.owrt.om/arch/arm/plat-s3c/dev-usb.c +--- linux-2.6.29-rc3.owrt/arch/arm/plat-s3c/dev-usb.c 1970-01-01 01:00:00.000000000 +0100 ++++ linux-2.6.29-rc3.owrt.om/arch/arm/plat-s3c/dev-usb.c 2009-05-10 22:27:59.000000000 +0200 +@@ -0,0 +1,50 @@ ++/* linux/arch/arm/plat-s3c/dev-usb.c ++ * ++ * Copyright 2008 Simtec Electronics ++ * Ben Dooks <ben@simtec.co.uk> ++ * http://armlinux.simtec.co.uk/ ++ * ++ * S3C series device definition for USB host ++ * ++ * 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/string.h> ++#include <linux/platform_device.h> ++ ++#include <mach/irqs.h> ++#include <mach/map.h> ++ ++#include <plat/devs.h> ++ ++ ++static struct resource s3c_usb_resource[] = { ++ [0] = { ++ .start = S3C_PA_USBHOST, ++ .end = S3C_PA_USBHOST + 0x100 - 1, ++ .flags = IORESOURCE_MEM, ++ }, ++ [1] = { ++ .start = IRQ_USBH, ++ .end = IRQ_USBH, ++ .flags = IORESOURCE_IRQ, ++ } ++}; ++ ++static u64 s3c_device_usb_dmamask = 0xffffffffUL; ++ ++struct platform_device s3c_device_usb = { ++ .name = "s3c-ohci", ++ .id = -1, ++ .num_resources = ARRAY_SIZE(s3c_usb_resource), ++ .resource = s3c_usb_resource, ++ .dev = { ++ .dma_mask = &s3c_device_usb_dmamask, ++ .coherent_dma_mask = 0xffffffffUL ++ } ++}; ++ ++EXPORT_SYMBOL(s3c_device_usb); +diff -ruN --exclude='*.orig' --exclude='*.rej' linux-2.6.29-rc3.owrt/arch/arm/plat-s3c/dma.c linux-2.6.29-rc3.owrt.om/arch/arm/plat-s3c/dma.c +--- linux-2.6.29-rc3.owrt/arch/arm/plat-s3c/dma.c 1970-01-01 01:00:00.000000000 +0100 ++++ linux-2.6.29-rc3.owrt.om/arch/arm/plat-s3c/dma.c 2009-05-10 22:27:59.000000000 +0200 +@@ -0,0 +1,86 @@ ++/* linux/arch/arm/plat-s3c/dma.c ++ * ++ * Copyright (c) 2003-2005,2006,2009 Simtec Electronics ++ * Ben Dooks <ben@simtec.co.uk> ++ * http://armlinux.simtec.co.uk/ ++ * ++ * S3C DMA core ++ * ++ * This program is free software; you can redistribute it and/or modify ++ * it under the terms of the GNU General Public License version 2 as ++ * published by the Free Software Foundation. ++*/ ++ ++struct s3c2410_dma_buf; ++ ++#include <linux/kernel.h> ++#include <linux/module.h> ++#include <linux/errno.h> ++ ++#include <mach/dma.h> ++#include <mach/irqs.h> ++ ++#include <plat/dma-plat.h> ++ ++/* dma channel state information */ ++struct s3c2410_dma_chan s3c2410_chans[S3C_DMA_CHANNELS]; ++struct s3c2410_dma_chan *s3c_dma_chan_map[DMACH_MAX]; ++ ++/* s3c_dma_lookup_channel ++ * ++ * change the dma channel number given into a real dma channel id ++*/ ++ ++struct s3c2410_dma_chan *s3c_dma_lookup_channel(unsigned int channel) ++{ ++ if (channel & DMACH_LOW_LEVEL) ++ return &s3c2410_chans[channel & ~DMACH_LOW_LEVEL]; ++ else ++ return s3c_dma_chan_map[channel]; ++} ++ ++/* do we need to protect the settings of the fields from ++ * irq? ++*/ ++ ++int s3c2410_dma_set_opfn(unsigned int channel, s3c2410_dma_opfn_t rtn) ++{ ++ struct s3c2410_dma_chan *chan = s3c_dma_lookup_channel(channel); ++ ++ if (chan == NULL) ++ return -EINVAL; ++ ++ pr_debug("%s: chan=%p, op rtn=%p\n", __func__, chan, rtn); ++ ++ chan->op_fn = rtn; ++ ++ return 0; ++} ++EXPORT_SYMBOL(s3c2410_dma_set_opfn); ++ ++int s3c2410_dma_set_buffdone_fn(unsigned int channel, s3c2410_dma_cbfn_t rtn) ++{ ++ struct s3c2410_dma_chan *chan = s3c_dma_lookup_channel(channel); ++ ++ if (chan == NULL) ++ return -EINVAL; ++ ++ pr_debug("%s: chan=%p, callback rtn=%p\n", __func__, chan, rtn); ++ ++ chan->callback_fn = rtn; ++ ++ return 0; ++} ++EXPORT_SYMBOL(s3c2410_dma_set_buffdone_fn); ++ ++int s3c2410_dma_setflags(unsigned int channel, unsigned int flags) ++{ ++ struct s3c2410_dma_chan *chan = s3c_dma_lookup_channel(channel); ++ ++ if (chan == NULL) ++ return -EINVAL; ++ ++ chan->flags = flags; ++ return 0; ++} ++EXPORT_SYMBOL(s3c2410_dma_setflags); +diff -ruN --exclude='*.orig' --exclude='*.rej' linux-2.6.29-rc3.owrt/arch/arm/plat-s3c/gpio.c linux-2.6.29-rc3.owrt.om/arch/arm/plat-s3c/gpio.c +--- linux-2.6.29-rc3.owrt/arch/arm/plat-s3c/gpio.c 2009-05-10 22:05:04.000000000 +0200 ++++ linux-2.6.29-rc3.owrt.om/arch/arm/plat-s3c/gpio.c 2009-05-10 22:27:59.000000000 +0200 +@@ -16,7 +16,7 @@ + #include <linux/io.h> + #include <linux/gpio.h> + +-#include <plat/gpio-core.h> ++#include <mach/gpio-core.h> + + #ifdef CONFIG_S3C_GPIO_TRACK + struct s3c_gpio_chip *s3c_gpios[S3C_GPIO_END]; +@@ -140,6 +140,15 @@ + if (!gc->get) + gc->get = s3c_gpiolib_get; + ++#ifdef CONFIG_PM ++ if (chip->pm != NULL) { ++ if (!chip->pm->save || !chip->pm->resume) ++ printk(KERN_ERR "gpio: %s has missing PM functions\n", ++ gc->label); ++ } else ++ printk(KERN_ERR "gpio: %s has no PM function\n", gc->label); ++#endif ++ + /* gpiochip_add() prints own failure message on error. */ + ret = gpiochip_add(gc); + if (ret >= 0) +diff -ruN --exclude='*.orig' --exclude='*.rej' linux-2.6.29-rc3.owrt/arch/arm/plat-s3c/gpio-config.c linux-2.6.29-rc3.owrt.om/arch/arm/plat-s3c/gpio-config.c +--- linux-2.6.29-rc3.owrt/arch/arm/plat-s3c/gpio-config.c 2009-05-10 22:05:04.000000000 +0200 ++++ linux-2.6.29-rc3.owrt.om/arch/arm/plat-s3c/gpio-config.c 2009-05-10 22:27:59.000000000 +0200 +@@ -13,6 +13,7 @@ + */ + + #include <linux/kernel.h> ++#include <linux/module.h> + #include <linux/gpio.h> + #include <linux/io.h> + +@@ -38,6 +39,7 @@ + + return ret; + } ++EXPORT_SYMBOL(s3c_gpio_cfgpin); + + int s3c_gpio_setpull(unsigned int pin, s3c_gpio_pull_t pull) + { +@@ -56,6 +58,7 @@ + + return ret; + } ++EXPORT_SYMBOL(s3c_gpio_setpull); + + #ifdef CONFIG_S3C_GPIO_CFG_S3C24XX + int s3c_gpio_setcfg_s3c24xx_banka(struct s3c_gpio_chip *chip, +diff -ruN --exclude='*.orig' --exclude='*.rej' linux-2.6.29-rc3.owrt/arch/arm/plat-s3c/include/mach/cpu.h linux-2.6.29-rc3.owrt.om/arch/arm/plat-s3c/include/mach/cpu.h +--- linux-2.6.29-rc3.owrt/arch/arm/plat-s3c/include/mach/cpu.h 1970-01-01 01:00:00.000000000 +0100 ++++ linux-2.6.29-rc3.owrt.om/arch/arm/plat-s3c/include/mach/cpu.h 2009-05-10 22:27:59.000000000 +0200 +@@ -0,0 +1,165 @@ ++/* ++ * arch/arm/plat-s3c/include/mach/cpu.h ++ * ++ * S3C cpu type detection ++ * ++ * Copyright (C) 2008 Samsung Electronics ++ * Kyungmin Park <kyungmin.park@samsung.com> ++ * ++ * Derived from OMAP cpu.h ++ * ++ * 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, MA 02111-1307 USA ++ */ ++ ++#ifndef __ASM_ARCH_S3C_CPU_H ++#define __ASM_ARCH_S3C_CPU_H ++ ++extern unsigned int system_rev; ++ ++#define S3C_SYSTEM_REV_ATAG (system_rev & 0xffff) ++#define S3C_SYSTEM_REV_CPU (system_rev & 0xffff0000) ++ ++/* ++ * cpu_is_s3c24xx(): True for s3c2400, s3c2410, s3c2440 and so on ++ * cpu_is_s3c241x(): True fro s3c2410, s3c2412 ++ * cpu_is_s3c244x(): True fro s3c2440, s3c2442, s3c2443 ++ * cpu_is_s3c64xx(): True for s3c6400, s3c6410 ++ */ ++#define GET_S3C_CLASS ((system_rev >> 24) & 0xff) ++ ++#define IS_S3C_CLASS(class, id) \ ++static inline int is_s3c ##class (void) \ ++{ \ ++ return (GET_S3C_CLASS == (id)) ? 1 : 0; \ ++} ++ ++#define GET_S3C_SUBCLASS ((system_rev >> 20) & 0xfff) ++ ++#define IS_S3C_SUBCLASS(subclass, id) \ ++static inline int is_s3c ##subclass (void) \ ++{ \ ++ return (GET_S3C_SUBCLASS == (id)) ? 1 : 0; \ ++} ++ ++IS_S3C_CLASS(24xx, 0x24) ++IS_S3C_CLASS(64xx, 0x64) ++ ++IS_S3C_SUBCLASS(241x, 0x241) ++IS_S3C_SUBCLASS(244x, 0x244) ++ ++#define cpu_is_s3c24xx() 0 ++#define cpu_is_s3c241x() 0 ++#define cpu_is_s3c244x() 0 ++#define cpu_is_s3c64xx() 0 ++ ++#if defined(CONFIG_ARCH_S3C2410) ++# undef cpu_is_s3c24xx ++# undef cpu_is_s3c241x ++# undef cpu_is_s3c244x ++# define cpu_is_s3c24xx() is_s3c24xx() ++# define cpu_is_s3c241x() is_s3c241x() ++# define cpu_is_s3c244x() is_s3c244x() ++#endif ++ ++#if defined(CONFIG_ARCH_S3C64XX) ++# undef cpu_is_s3c64xx ++# define cpu_is_s3c64xx() is_s3c64xx() ++#endif ++ ++/* ++ * Macros to detect individual cpu types. ++ * cpu_is_s3c2410(): True for s3c2410 ++ * cpu_is_s3c2440(): True for s3c2440 ++ * cpu_is_s3c6400(): True for s3c6400 ++ * cpu_is_s3c6410(): True for s3c6410 ++ * ++ * Exception: ++ * Store Revision A to 1 ++ * s3c2410a -> s3c2411 ++ * s3c2440a -> s3c2441 ++ */ ++ ++#define GET_S3C_TYPE ((system_rev >> 16) & 0xffff) ++ ++#define IS_S3C_TYPE(type, id) \ ++static inline int is_s3c ##type (void) \ ++{ \ ++ return (GET_S3C_TYPE == (id)) ? 1 : 0; \ ++} ++ ++IS_S3C_TYPE(2400, 0x2400) ++IS_S3C_TYPE(2410, 0x2410) ++IS_S3C_TYPE(2410a, 0x2411) ++IS_S3C_TYPE(2412, 0x2412) ++IS_S3C_TYPE(2440, 0x2440) ++IS_S3C_TYPE(2440a, 0x2441) ++IS_S3C_TYPE(2442, 0x2442) ++IS_S3C_TYPE(2443, 0x2443) ++IS_S3C_TYPE(6400, 0x6400) ++IS_S3C_TYPE(6410, 0x6410) ++ ++#define cpu_is_s3c2400() 0 ++#define cpu_is_s3c2410() 0 ++#define cpu_is_s3c2410a() 0 ++#define cpu_is_s3c2412() 0 ++#define cpu_is_s3c2440() 0 ++#define cpu_is_s3c2440a() 0 ++#define cpu_is_s3c2442() 0 ++#define cpu_is_s3c2443() 0 ++#define cpu_is_s3c6400() 0 ++#define cpu_is_s3c6410() 0 ++ ++#if defined(CONFIG_ARCH_S3C2410) ++# undef cpu_is_s3c2400 ++# define cpu_is_s3c2400() is_s3c2400() ++#endif ++ ++#if defined(CONFIG_CPU_S3C2410) ++# undef cpu_is_s3c2410 ++# undef cpu_is_s3c2410a ++# define cpu_is_s3c2410() is_s3c2410() ++# define cpu_is_s3c2410a() is_s3c2410a() ++#endif ++ ++#if defined(CONFIG_CPU_S3C2412) ++# undef cpu_is_s3c2412 ++# define cpu_is_s3c2412() is_s3c2412() ++#endif ++ ++#if defined(CONFIG_CPU_S3C2440) ++# undef cpu_is_s3c2440 ++# undef cpu_is_s3c2440a ++# define cpu_is_s3c2440() is_s3c2440() ++# define cpu_is_s3c2440a() is_s3c2440a() ++#endif ++ ++#if defined(CONFIG_CPU_S3C2442) ++# undef cpu_is_s3c2442 ++# define cpu_is_s3c2442() is_s3c2442() ++#endif ++ ++#if defined(CONFIG_CPU_S3C2443) ++# undef cpu_is_s3c2443 ++# define cpu_is_s3c2443() is_s3c2443() ++#endif ++ ++#if defined(CONFIG_ARCH_S3C64XX) ++# undef cpu_is_s3c6400 ++# undef cpu_is_s3c6410 ++# define cpu_is_s3c6400() is_s3c6400() ++# define cpu_is_s3c6410() is_s3c6410() ++#endif ++ ++#endif +diff -ruN --exclude='*.orig' --exclude='*.rej' linux-2.6.29-rc3.owrt/arch/arm/plat-s3c/include/mach/io.h linux-2.6.29-rc3.owrt.om/arch/arm/plat-s3c/include/mach/io.h +--- linux-2.6.29-rc3.owrt/arch/arm/plat-s3c/include/mach/io.h 2009-05-10 22:05:04.000000000 +0200 ++++ linux-2.6.29-rc3.owrt.om/arch/arm/plat-s3c/include/mach/io.h 2009-05-10 22:27:59.000000000 +0200 +@@ -10,6 +10,7 @@ + #define __ASM_ARM_ARCH_IO_H + + /* No current ISA/PCI bus support. */ ++ + #define __io(a) __typesafe_io(a) + #define __mem_pci(a) (a) + +diff -ruN --exclude='*.orig' --exclude='*.rej' linux-2.6.29-rc3.owrt/arch/arm/plat-s3c/include/plat/audio.h linux-2.6.29-rc3.owrt.om/arch/arm/plat-s3c/include/plat/audio.h +--- linux-2.6.29-rc3.owrt/arch/arm/plat-s3c/include/plat/audio.h 1970-01-01 01:00:00.000000000 +0100 ++++ linux-2.6.29-rc3.owrt.om/arch/arm/plat-s3c/include/plat/audio.h 2009-05-10 22:27:59.000000000 +0200 +@@ -0,0 +1,45 @@ ++/* arch/arm/mach-s3c2410/include/mach/audio.h ++ * ++ * Copyright (c) 2004-2005 Simtec Electronics ++ * http://www.simtec.co.uk/products/SWLINUX/ ++ * Ben Dooks <ben@simtec.co.uk> ++ * ++ * S3C24XX - Audio platfrom_device info ++ * ++ * 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_ARCH_AUDIO_H ++#define __ASM_ARCH_AUDIO_H __FILE__ ++ ++/* struct s3c24xx_iis_ops ++ * ++ * called from the s3c24xx audio core to deal with the architecture ++ * or the codec's setup and control. ++ * ++ * the pointer to itself is passed through in case the caller wants to ++ * embed this in an larger structure for easy reference to it's context. ++*/ ++ ++struct s3c24xx_iis_ops { ++ struct module *owner; ++ ++ int (*startup)(struct s3c24xx_iis_ops *me); ++ void (*shutdown)(struct s3c24xx_iis_ops *me); ++ int (*suspend)(struct s3c24xx_iis_ops *me); ++ int (*resume)(struct s3c24xx_iis_ops *me); ++ ++ int (*open)(struct s3c24xx_iis_ops *me, struct snd_pcm_substream *strm); ++ int (*close)(struct s3c24xx_iis_ops *me, struct snd_pcm_substream *strm); ++ int (*prepare)(struct s3c24xx_iis_ops *me, struct snd_pcm_substream *strm, struct snd_pcm_runtime *rt); ++}; ++ ++struct s3c24xx_platdata_iis { ++ const char *codec_clk; ++ struct s3c24xx_iis_ops *ops; ++ int (*match_dev)(struct device *dev); ++}; ++ ++#endif /* __ASM_ARCH_AUDIO_H */ +diff -ruN --exclude='*.orig' --exclude='*.rej' linux-2.6.29-rc3.owrt/arch/arm/plat-s3c/include/plat/clock.h linux-2.6.29-rc3.owrt.om/arch/arm/plat-s3c/include/plat/clock.h +--- linux-2.6.29-rc3.owrt/arch/arm/plat-s3c/include/plat/clock.h 2009-05-10 22:05:04.000000000 +0200 ++++ linux-2.6.29-rc3.owrt.om/arch/arm/plat-s3c/include/plat/clock.h 2009-05-10 22:27:59.000000000 +0200 +@@ -50,6 +50,7 @@ + extern struct clk clk_ext; + + /* S3C64XX specific clocks */ ++extern struct clk clk_h2; + extern struct clk clk_27m; + extern struct clk clk_48m; + +@@ -80,6 +81,7 @@ + + /* S3C64XX specific functions and clocks */ + ++extern int s3c64xx_hclk_ctrl(struct clk *clk, int enable); + extern int s3c64xx_sclk_ctrl(struct clk *clk, int enable); + + /* Init for pwm clock code */ +diff -ruN --exclude='*.orig' --exclude='*.rej' linux-2.6.29-rc3.owrt/arch/arm/plat-s3c/include/plat/cpu.h linux-2.6.29-rc3.owrt.om/arch/arm/plat-s3c/include/plat/cpu.h +--- linux-2.6.29-rc3.owrt/arch/arm/plat-s3c/include/plat/cpu.h 2009-05-10 22:05:04.000000000 +0200 ++++ linux-2.6.29-rc3.owrt.om/arch/arm/plat-s3c/include/plat/cpu.h 2009-05-10 22:27:59.000000000 +0200 +@@ -69,3 +69,6 @@ + extern struct sysdev_class s3c2440_sysclass; + extern struct sysdev_class s3c2442_sysclass; + extern struct sysdev_class s3c2443_sysclass; ++extern struct sysdev_class s3c6410_sysclass; ++extern struct sysdev_class s3c64xx_sysclass; ++ +diff -ruN --exclude='*.orig' --exclude='*.rej' linux-2.6.29-rc3.owrt/arch/arm/plat-s3c/include/plat/devs.h linux-2.6.29-rc3.owrt.om/arch/arm/plat-s3c/include/plat/devs.h +--- linux-2.6.29-rc3.owrt/arch/arm/plat-s3c/include/plat/devs.h 2009-05-10 22:05:04.000000000 +0200 ++++ linux-2.6.29-rc3.owrt.om/arch/arm/plat-s3c/include/plat/devs.h 2009-05-10 22:27:59.000000000 +0200 +@@ -16,6 +16,10 @@ + unsigned long nr_resources; + }; + ++struct s3c_plat_otg_data { ++ int phyclk; ++}; ++ + extern struct s3c24xx_uart_resources s3c2410_uart_resources[]; + extern struct s3c24xx_uart_resources s3c64xx_uart_resources[]; + +@@ -45,10 +49,11 @@ + + extern struct platform_device s3c_device_usbgadget; + ++extern struct platform_device s3c_device_ts; ++ + /* s3c2440 specific devices */ + + #ifdef CONFIG_CPU_S3C2440 + + extern struct platform_device s3c_device_camif; +- + #endif +diff -ruN --exclude='*.orig' --exclude='*.rej' linux-2.6.29-rc3.owrt/arch/arm/plat-s3c/include/plat/dma-core.h linux-2.6.29-rc3.owrt.om/arch/arm/plat-s3c/include/plat/dma-core.h +--- linux-2.6.29-rc3.owrt/arch/arm/plat-s3c/include/plat/dma-core.h 1970-01-01 01:00:00.000000000 +0100 ++++ linux-2.6.29-rc3.owrt.om/arch/arm/plat-s3c/include/plat/dma-core.h 2009-05-10 22:27:59.000000000 +0200 +@@ -0,0 +1,22 @@ ++/* arch/arm/plat-s3c/include/plat/dma.h ++ * ++ * Copyright 2008 Openmoko, Inc. ++ * Copyright 2008 Simtec Electronics ++ * Ben Dooks <ben@simtec.co.uk> ++ * http://armlinux.simtec.co.uk/ ++ * ++ * Samsung S3C DMA core support ++ * ++ * This program is free software; you can redistribute it and/or modify ++ * it under the terms of the GNU General Public License version 2 as ++ * published by the Free Software Foundation. ++*/ ++ ++extern struct s3c2410_dma_chan *s3c_dma_lookup_channel(unsigned int channel); ++ ++extern struct s3c2410_dma_chan *s3c_dma_chan_map[]; ++ ++/* the currently allocated channel information */ ++extern struct s3c2410_dma_chan s3c2410_chans[]; ++ ++ +diff -ruN --exclude='*.orig' --exclude='*.rej' linux-2.6.29-rc3.owrt/arch/arm/plat-s3c/include/plat/dma.h linux-2.6.29-rc3.owrt.om/arch/arm/plat-s3c/include/plat/dma.h +--- linux-2.6.29-rc3.owrt/arch/arm/plat-s3c/include/plat/dma.h 1970-01-01 01:00:00.000000000 +0100 ++++ linux-2.6.29-rc3.owrt.om/arch/arm/plat-s3c/include/plat/dma.h 2009-05-10 22:27:59.000000000 +0200 +@@ -0,0 +1,128 @@ ++/* arch/arm/plat-s3c/include/plat/dma.h ++ * ++ * Copyright (C) 2003,2004,2006 Simtec Electronics ++ * Ben Dooks <ben@simtec.co.uk> ++ * ++ * Samsung S3C DMA support ++ * ++ * This program is free software; you can redistribute it and/or modify ++ * it under the terms of the GNU General Public License version 2 as ++ * published by the Free Software Foundation. ++*/ ++ ++enum s3c2410_dma_buffresult { ++ S3C2410_RES_OK, ++ S3C2410_RES_ERR, ++ S3C2410_RES_ABORT ++}; ++ ++enum s3c2410_dmasrc { ++ S3C2410_DMASRC_HW, /* source is memory */ ++ S3C2410_DMASRC_MEM /* source is hardware */ ++}; ++ ++/* enum s3c2410_chan_op ++ * ++ * operation codes passed to the DMA code by the user, and also used ++ * to inform the current channel owner of any changes to the system state ++*/ ++ ++enum s3c2410_chan_op { ++ S3C2410_DMAOP_START, ++ S3C2410_DMAOP_STOP, ++ S3C2410_DMAOP_PAUSE, ++ S3C2410_DMAOP_RESUME, ++ S3C2410_DMAOP_FLUSH, ++ S3C2410_DMAOP_TIMEOUT, /* internal signal to handler */ ++ S3C2410_DMAOP_STARTED, /* indicate channel started */ ++}; ++ ++struct s3c2410_dma_client { ++ char *name; ++}; ++ ++struct s3c2410_dma_chan; ++ ++/* s3c2410_dma_cbfn_t ++ * ++ * buffer callback routine type ++*/ ++ ++typedef void (*s3c2410_dma_cbfn_t)(struct s3c2410_dma_chan *, ++ void *buf, int size, ++ enum s3c2410_dma_buffresult result); ++ ++typedef int (*s3c2410_dma_opfn_t)(struct s3c2410_dma_chan *, ++ enum s3c2410_chan_op ); ++ ++ ++ ++/* s3c2410_dma_request ++ * ++ * request a dma channel exclusivley ++*/ ++ ++extern int s3c2410_dma_request(unsigned int channel, ++ struct s3c2410_dma_client *, void *dev); ++ ++ ++/* s3c2410_dma_ctrl ++ * ++ * change the state of the dma channel ++*/ ++ ++extern int s3c2410_dma_ctrl(unsigned int channel, enum s3c2410_chan_op op); ++ ++/* s3c2410_dma_setflags ++ * ++ * set the channel's flags to a given state ++*/ ++ ++extern int s3c2410_dma_setflags(unsigned int channel, ++ unsigned int flags); ++ ++/* s3c2410_dma_free ++ * ++ * free the dma channel (will also abort any outstanding operations) ++*/ ++ ++extern int s3c2410_dma_free(unsigned int channel, struct s3c2410_dma_client *); ++ ++/* s3c2410_dma_enqueue ++ * ++ * place the given buffer onto the queue of operations for the channel. ++ * The buffer must be allocated from dma coherent memory, or the Dcache/WB ++ * drained before the buffer is given to the DMA system. ++*/ ++ ++extern int s3c2410_dma_enqueue(unsigned int channel, void *id, ++ dma_addr_t data, int size); ++ ++ ++/* s3c2410_dma_config ++ * ++ * configure the dma channel ++*/ ++ ++extern int s3c2410_dma_config(unsigned int channel, int xferunit); ++ ++/* s3c2410_dma_devconfig ++ * ++ * configure the device we're talking to ++*/ ++ ++extern int s3c2410_dma_devconfig(int channel, enum s3c2410_dmasrc source, ++ unsigned long devaddr); ++ ++/* s3c2410_dma_getposition ++ * ++ * get the position that the dma transfer is currently at ++*/ ++ ++extern int s3c2410_dma_getposition(unsigned int channel, ++ dma_addr_t *src, dma_addr_t *dest); ++ ++extern int s3c2410_dma_set_opfn(unsigned int, s3c2410_dma_opfn_t rtn); ++extern int s3c2410_dma_set_buffdone_fn(unsigned int, s3c2410_dma_cbfn_t rtn); ++ ++ +diff -ruN --exclude='*.orig' --exclude='*.rej' linux-2.6.29-rc3.owrt/arch/arm/plat-s3c/include/plat/gpio-core.h linux-2.6.29-rc3.owrt.om/arch/arm/plat-s3c/include/plat/gpio-core.h +--- linux-2.6.29-rc3.owrt/arch/arm/plat-s3c/include/plat/gpio-core.h 2009-05-10 22:05:04.000000000 +0200 ++++ linux-2.6.29-rc3.owrt.om/arch/arm/plat-s3c/include/plat/gpio-core.h 2009-05-10 22:27:59.000000000 +0200 +@@ -20,6 +20,19 @@ + * specific code. + */ + ++struct s3c_gpio_chip; ++ ++/** ++ * struct s3c_gpio_pm - power management (suspend/resume) information ++ * @save: Routine to save the state of the GPIO block ++ * @resume: Routine to resume the GPIO block. ++ */ ++struct s3c_gpio_pm { ++ void (*save)(struct s3c_gpio_chip *chip); ++ void (*resume)(struct s3c_gpio_chip *chip); ++}; ++ ++ + struct s3c_gpio_cfg; + + /** +@@ -27,6 +40,7 @@ + * @chip: The chip structure to be exported via gpiolib. + * @base: The base pointer to the gpio configuration registers. + * @config: special function and pull-resistor control information. ++ * @pm_save: Save information for suspend/resume support. + * + * This wrapper provides the necessary information for the Samsung + * specific gpios being registered with gpiolib. +@@ -34,7 +48,11 @@ + struct s3c_gpio_chip { + struct gpio_chip chip; + struct s3c_gpio_cfg *config; ++ struct s3c_gpio_pm *pm; + void __iomem *base; ++#ifdef CONFIG_PM ++ u32 pm_save[4]; ++#endif + }; + + static inline struct s3c_gpio_chip *to_s3c_gpio(struct gpio_chip *gpc) +@@ -75,3 +93,16 @@ + + static inline void s3c_gpiolib_track(struct s3c_gpio_chip *chip) { } + #endif ++ ++#ifdef CONFIG_PM ++extern struct s3c_gpio_pm s3c_gpio_pm_1bit; ++extern struct s3c_gpio_pm s3c_gpio_pm_2bit; ++extern struct s3c_gpio_pm s3c_gpio_pm_4bit; ++#define __gpio_pm(x) x ++#else ++#define s3c_gpio_pm_1bit NULL ++#define s3c_gpio_pm_2bit NULL ++#define s3c_gpio_pm_4bit NULL ++#define __gpio_pm(x) NULL ++ ++#endif /* CONFIG_PM */ +diff -ruN --exclude='*.orig' --exclude='*.rej' linux-2.6.29-rc3.owrt/arch/arm/plat-s3c/include/plat/map-base.h linux-2.6.29-rc3.owrt.om/arch/arm/plat-s3c/include/plat/map-base.h +--- linux-2.6.29-rc3.owrt/arch/arm/plat-s3c/include/plat/map-base.h 2009-05-10 22:05:04.000000000 +0200 ++++ linux-2.6.29-rc3.owrt.om/arch/arm/plat-s3c/include/plat/map-base.h 2009-05-10 22:27:59.000000000 +0200 +@@ -36,5 +36,7 @@ + #define S3C_VA_TIMER S3C_ADDR(0x00300000) /* timer block */ + #define S3C_VA_WATCHDOG S3C_ADDR(0x00400000) /* watchdog */ + #define S3C_VA_UART S3C_ADDR(0x01000000) /* UART */ ++#define S3C_VA_OTG S3C_ADDR(0x03900000) /* OTG */ ++#define S3C_VA_OTGSFR S3C_ADDR(0x03a00000) /* OTGSFR */ + + #endif /* __ASM_PLAT_MAP_H */ +diff -ruN --exclude='*.orig' --exclude='*.rej' linux-2.6.29-rc3.owrt/arch/arm/plat-s3c/include/plat/nand.h linux-2.6.29-rc3.owrt.om/arch/arm/plat-s3c/include/plat/nand.h +--- linux-2.6.29-rc3.owrt/arch/arm/plat-s3c/include/plat/nand.h 2009-05-10 22:05:04.000000000 +0200 ++++ linux-2.6.29-rc3.owrt.om/arch/arm/plat-s3c/include/plat/nand.h 2009-05-10 22:27:59.000000000 +0200 +@@ -21,11 +21,14 @@ + * partitions = mtd partition list + */ + ++#define S3C2410_NAND_BBT 0x0001 ++ + struct s3c2410_nand_set { + unsigned int disable_ecc : 1; + + int nr_chips; + int nr_partitions; ++ unsigned int flags; + char *name; + int *nr_map; + struct mtd_partition *partitions; +@@ -44,6 +47,9 @@ + int nr_sets; + struct s3c2410_nand_set *sets; + ++ /* force software_ecc at runtime */ ++ int software_ecc; ++ + void (*select_chip)(struct s3c2410_nand_set *, + int chip); + }; +diff -ruN --exclude='*.orig' --exclude='*.rej' linux-2.6.29-rc3.owrt/arch/arm/plat-s3c/include/plat/pm.h linux-2.6.29-rc3.owrt.om/arch/arm/plat-s3c/include/plat/pm.h +--- linux-2.6.29-rc3.owrt/arch/arm/plat-s3c/include/plat/pm.h 1970-01-01 01:00:00.000000000 +0100 ++++ linux-2.6.29-rc3.owrt.om/arch/arm/plat-s3c/include/plat/pm.h 2009-05-10 22:27:59.000000000 +0200 +@@ -0,0 +1,184 @@ ++/* linux/include/asm-arm/plat-s3c24xx/pm.h ++ * ++ * Copyright (c) 2004 Simtec Electronics ++ * http://armlinux.simtec.co.uk/ ++ * Written by Ben Dooks, <ben@simtec.co.uk> ++ * ++ * 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/sysdev.h> ++ ++/* s3c_pm_init ++ * ++ * called from board at initialisation time to setup the power ++ * management ++*/ ++ ++#ifdef CONFIG_PM ++ ++extern __init int s3c_pm_init(void); ++ ++#else ++ ++static inline int s3c_pm_init(void) ++{ ++ return 0; ++} ++#endif ++ ++/* configuration for the IRQ mask over sleep */ ++extern unsigned long s3c_irqwake_intmask; ++extern unsigned long s3c_irqwake_eintmask; ++ ++/* IRQ masks for IRQs allowed to go to sleep (see irq.c) */ ++extern unsigned long s3c_irqwake_intallow; ++extern unsigned long s3c_irqwake_eintallow; ++ ++/* per-cpu sleep functions */ ++ ++extern void (*pm_cpu_prep)(void); ++extern void (*pm_cpu_sleep)(void); ++ ++/* Flags for PM Control */ ++ ++extern unsigned long s3c_pm_flags; ++ ++extern unsigned char pm_uart_udivslot; /* true to save UART UDIVSLOT */ ++ ++/* from sleep.S */ ++ ++extern int s3c_cpu_save(unsigned long *saveblk); ++extern void s3c_cpu_resume(void); ++ ++extern void s3c2410_cpu_suspend(void); ++ ++extern unsigned long s3c_sleep_save_phys; ++ ++/* sleep save info */ ++ ++/** ++ * struct sleep_save - save information for shared peripherals. ++ * @reg: Pointer to the register to save. ++ * @val: Holder for the value saved from reg. ++ * ++ * This describes a list of registers which is used by the pm core and ++ * other subsystem to save and restore register values over suspend. ++ */ ++struct sleep_save { ++ void __iomem *reg; ++ unsigned long val; ++}; ++ ++#define SAVE_ITEM(x) \ ++ { .reg = (x) } ++ ++/** ++ * struct pm_uart_save - save block for core UART ++ * @ulcon: Save value for S3C2410_ULCON ++ * @ucon: Save value for S3C2410_UCON ++ * @ufcon: Save value for S3C2410_UFCON ++ * @umcon: Save value for S3C2410_UMCON ++ * @ubrdiv: Save value for S3C2410_UBRDIV ++ * ++ * Save block for UART registers to be held over sleep and restored if they ++ * are needed (say by debug). ++*/ ++struct pm_uart_save { ++ u32 ulcon; ++ u32 ucon; ++ u32 ufcon; ++ u32 umcon; ++ u32 ubrdiv; ++ u32 udivslot; ++}; ++ ++/* helper functions to save/restore lists of registers. */ ++ ++extern void s3c_pm_do_save(struct sleep_save *ptr, int count); ++extern void s3c_pm_do_restore(struct sleep_save *ptr, int count); ++extern void s3c_pm_do_restore_core(struct sleep_save *ptr, int count); ++ ++#ifdef CONFIG_PM ++extern int s3c_irqext_wake(unsigned int irqno, unsigned int state); ++extern int s3c24xx_irq_suspend(struct sys_device *dev, pm_message_t state); ++extern int s3c24xx_irq_resume(struct sys_device *dev); ++#else ++#define s3c_irqext_wake NULL ++#define s3c24xx_irq_suspend NULL ++#define s3c24xx_irq_resume NULL ++#endif ++ ++/* PM debug functions */ ++ ++#ifdef CONFIG_S3C2410_PM_DEBUG ++/** ++ * s3c_pm_dbg() - low level debug function for use in suspend/resume. ++ * @msg: The message to print. ++ * ++ * This function is used mainly to debug the resume process before the system ++ * can rely on printk/console output. It uses the low-level debugging output ++ * routine printascii() to do its work. ++ */ ++extern void s3c_pm_dbg(const char *msg, ...); ++ ++#define S3C_PMDBG(fmt...) s3c_pm_dbg(fmt) ++#else ++#define S3C_PMDBG(fmt...) printk(KERN_DEBUG fmt) ++#endif ++ ++#ifdef CONFIG_S3C_PM_DEBUG_LED_SMDK ++/** ++ * s3c_pm_debug_smdkled() - Debug PM suspend/resume via SMDK Board LEDs ++ * @set: set bits for the state of the LEDs ++ * @clear: clear bits for the state of the LEDs. ++ */ ++extern void s3c_pm_debug_smdkled(u32 set, u32 clear); ++ ++#else ++static inline void s3c_pm_debug_smdkled(u32 set, u32 clear) { } ++#endif /* CONFIG_S3C_PM_DEBUG_LED_SMDK */ ++ ++/* suspend memory checking */ ++ ++#ifdef CONFIG_S3C2410_PM_CHECK ++extern void s3c_pm_check_prepare(void); ++extern void s3c_pm_check_restore(void); ++extern void s3c_pm_check_cleanup(void); ++extern void s3c_pm_check_store(void); ++#else ++#define s3c_pm_check_prepare() do { } while(0) ++#define s3c_pm_check_restore() do { } while(0) ++#define s3c_pm_check_cleanup() do { } while(0) ++#define s3c_pm_check_store() do { } while(0) ++#endif ++ ++/** ++ * s3c_pm_configure_extint() - ensure pins are correctly set for IRQ ++ * ++ * Setup all the necessary GPIO pins for waking the system on external ++ * interrupt. ++ */ ++extern void s3c_pm_configure_extint(void); ++ ++/** ++ * s3c_pm_restore_gpios() - restore the state of the gpios after sleep. ++ * ++ * Restore the state of the GPIO pins after sleep, which may involve ensuring ++ * that we do not glitch the state of the pins from that the bootloader's ++ * resume code has done. ++*/ ++extern void s3c_pm_restore_gpios(void); ++ ++/** ++ * s3c_pm_save_gpios() - save the state of the GPIOs for restoring after sleep. ++ * ++ * Save the GPIO states for resotration on resume. See s3c_pm_restore_gpios(). ++ */ ++extern void s3c_pm_save_gpios(void); ++ ++extern void s3c_pm_save_core(void); ++extern void s3c_pm_restore_core(void); ++ +diff -ruN --exclude='*.orig' --exclude='*.rej' linux-2.6.29-rc3.owrt/arch/arm/plat-s3c/include/plat/pwm.h linux-2.6.29-rc3.owrt.om/arch/arm/plat-s3c/include/plat/pwm.h +--- linux-2.6.29-rc3.owrt/arch/arm/plat-s3c/include/plat/pwm.h 1970-01-01 01:00:00.000000000 +0100 ++++ linux-2.6.29-rc3.owrt.om/arch/arm/plat-s3c/include/plat/pwm.h 2009-05-10 22:27:59.000000000 +0200 +@@ -0,0 +1,45 @@ ++#ifndef __S3C2410_PWM_H ++#define __S3C2410_PWM_H ++ ++#include <linux/err.h> ++#include <linux/platform_device.h> ++#include <linux/clk.h> ++ ++#include <mach/io.h> ++#include <mach/hardware.h> ++#include <asm/mach-types.h> ++#include <plat/regs-timer.h> ++ ++enum pwm_timer { ++ PWM0, ++ PWM1, ++ PWM2, ++ PWM3, ++ PWM4 ++}; ++ ++struct s3c2410_pwm { ++ enum pwm_timer timerid; ++ struct clk *pclk; ++ unsigned long pclk_rate; ++ unsigned long prescaler; ++ unsigned long divider; ++ unsigned long counter; ++ unsigned long comparer; ++}; ++ ++struct s3c24xx_pwm_platform_data{ ++ /* callback to attach platform children (to enforce suspend / resume ++ * ordering */ ++ void (*attach_child_devices)(struct device *parent_device); ++}; ++ ++int s3c2410_pwm_init(struct s3c2410_pwm *s3c2410_pwm); ++int s3c2410_pwm_enable(struct s3c2410_pwm *s3c2410_pwm); ++int s3c2410_pwm_disable(struct s3c2410_pwm *s3c2410_pwm); ++int s3c2410_pwm_start(struct s3c2410_pwm *s3c2410_pwm); ++int s3c2410_pwm_stop(struct s3c2410_pwm *s3c2410_pwm); ++int s3c2410_pwm_duty_cycle(int reg_value, struct s3c2410_pwm *s3c2410_pwm); ++int s3c2410_pwm_dumpregs(void); ++ ++#endif /* __S3C2410_PWM_H */ +diff -ruN --exclude='*.orig' --exclude='*.rej' linux-2.6.29-rc3.owrt/arch/arm/plat-s3c/include/plat/regs-s3c2412-iis.h linux-2.6.29-rc3.owrt.om/arch/arm/plat-s3c/include/plat/regs-s3c2412-iis.h +--- linux-2.6.29-rc3.owrt/arch/arm/plat-s3c/include/plat/regs-s3c2412-iis.h 1970-01-01 01:00:00.000000000 +0100 ++++ linux-2.6.29-rc3.owrt.om/arch/arm/plat-s3c/include/plat/regs-s3c2412-iis.h 2009-05-10 22:27:59.000000000 +0200 +@@ -0,0 +1,75 @@ ++/* linux/include/asm-arm/plat-s3c24xx/regs-s3c2412-iis.h ++ * ++ * Copyright 2007 Simtec Electronics <linux@simtec.co.uk> ++ * http://armlinux.simtec.co.uk/ ++ * ++ * 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. ++ * ++ * S3C2412 IIS register definition ++*/ ++ ++#ifndef __ASM_ARCH_REGS_S3C2412_IIS_H ++#define __ASM_ARCH_REGS_S3C2412_IIS_H ++ ++#define S3C2412_IISCON (0x00) ++#define S3C2412_IISMOD (0x04) ++#define S3C2412_IISFIC (0x08) ++#define S3C2412_IISPSR (0x0C) ++#define S3C2412_IISTXD (0x10) ++#define S3C2412_IISRXD (0x14) ++ ++#define S3C2412_IISCON_LRINDEX (1 << 11) ++#define S3C2412_IISCON_TXFIFO_EMPTY (1 << 10) ++#define S3C2412_IISCON_RXFIFO_EMPTY (1 << 9) ++#define S3C2412_IISCON_TXFIFO_FULL (1 << 8) ++#define S3C2412_IISCON_RXFIFO_FULL (1 << 7) ++#define S3C2412_IISCON_TXDMA_PAUSE (1 << 6) ++#define S3C2412_IISCON_RXDMA_PAUSE (1 << 5) ++#define S3C2412_IISCON_TXCH_PAUSE (1 << 4) ++#define S3C2412_IISCON_RXCH_PAUSE (1 << 3) ++#define S3C2412_IISCON_TXDMA_ACTIVE (1 << 2) ++#define S3C2412_IISCON_RXDMA_ACTIVE (1 << 1) ++#define S3C2412_IISCON_IIS_ACTIVE (1 << 0) ++ ++#define S3C64XX_IISMOD_IMS_PCLK (0 << 10) ++#define S3C64XX_IISMOD_IMS_SYSMUX (1 << 10) ++ ++#define S3C2412_IISMOD_MASTER_INTERNAL (0 << 10) ++#define S3C2412_IISMOD_MASTER_EXTERNAL (1 << 10) ++#define S3C2412_IISMOD_SLAVE (2 << 10) ++#define S3C2412_IISMOD_MASTER_MASK (3 << 10) ++#define S3C2412_IISMOD_MODE_TXONLY (0 << 8) ++#define S3C2412_IISMOD_MODE_RXONLY (1 << 8) ++#define S3C2412_IISMOD_MODE_TXRX (2 << 8) ++#define S3C2412_IISMOD_MODE_MASK (3 << 8) ++#define S3C2412_IISMOD_LR_LLOW (0 << 7) ++#define S3C2412_IISMOD_LR_RLOW (1 << 7) ++#define S3C2412_IISMOD_SDF_IIS (0 << 5) ++#define S3C2412_IISMOD_SDF_MSB (1 << 5) ++#define S3C2412_IISMOD_SDF_LSB (2 << 5) ++#define S3C2412_IISMOD_SDF_MASK (3 << 5) ++#define S3C2412_IISMOD_RCLK_256FS (0 << 3) ++#define S3C2412_IISMOD_RCLK_512FS (1 << 3) ++#define S3C2412_IISMOD_RCLK_384FS (2 << 3) ++#define S3C2412_IISMOD_RCLK_768FS (3 << 3) ++#define S3C2412_IISMOD_RCLK_MASK (3 << 3) ++#define S3C2412_IISMOD_BCLK_32FS (0 << 1) ++#define S3C2412_IISMOD_BCLK_48FS (1 << 1) ++#define S3C2412_IISMOD_BCLK_16FS (2 << 1) ++#define S3C2412_IISMOD_BCLK_24FS (3 << 1) ++#define S3C2412_IISMOD_BCLK_MASK (3 << 1) ++#define S3C2412_IISMOD_8BIT (1 << 0) ++ ++#define S3C2412_IISPSR_PSREN (1 << 15) ++ ++#define S3C2412_IISFIC_TXFLUSH (1 << 15) ++#define S3C2412_IISFIC_RXFLUSH (1 << 7) ++#define S3C2412_IISFIC_TXCOUNT(x) (((x) >> 8) & 0xf) ++#define S3C2412_IISFIC_RXCOUNT(x) (((x) >> 0) & 0xf) ++ ++ ++ ++#endif /* __ASM_ARCH_REGS_S3C2412_IIS_H */ ++ +diff -ruN --exclude='*.orig' --exclude='*.rej' linux-2.6.29-rc3.owrt/arch/arm/plat-s3c/include/plat/regs-serial.h linux-2.6.29-rc3.owrt.om/arch/arm/plat-s3c/include/plat/regs-serial.h +--- linux-2.6.29-rc3.owrt/arch/arm/plat-s3c/include/plat/regs-serial.h 2009-05-10 22:05:04.000000000 +0200 ++++ linux-2.6.29-rc3.owrt.om/arch/arm/plat-s3c/include/plat/regs-serial.h 2009-05-10 22:27:59.000000000 +0200 +@@ -189,6 +189,11 @@ + + #define S3C2443_DIVSLOT (0x2C) + ++/* S3C64XX interrupt registers. */ ++#define S3C64XX_UINTP 0x30 ++#define S3C64XX_UINTSP 0x34 ++#define S3C64XX_UINTM 0x38 ++ + #ifndef __ASSEMBLY__ + + /* struct s3c24xx_uart_clksrc +diff -ruN --exclude='*.orig' --exclude='*.rej' linux-2.6.29-rc3.owrt/arch/arm/plat-s3c/include/plat/regs-timer.h linux-2.6.29-rc3.owrt.om/arch/arm/plat-s3c/include/plat/regs-timer.h +--- linux-2.6.29-rc3.owrt/arch/arm/plat-s3c/include/plat/regs-timer.h 2009-05-10 22:05:04.000000000 +0200 ++++ linux-2.6.29-rc3.owrt.om/arch/arm/plat-s3c/include/plat/regs-timer.h 2009-05-10 22:27:59.000000000 +0200 +@@ -10,6 +10,8 @@ + * S3C2410 Timer configuration + */ + ++#include <plat/map-base.h> ++ + #ifndef __ASM_ARCH_REGS_TIMER_H + #define __ASM_ARCH_REGS_TIMER_H + +diff -ruN --exclude='*.orig' --exclude='*.rej' linux-2.6.29-rc3.owrt/arch/arm/plat-s3c/include/plat/regs-usb-hs-otg.h linux-2.6.29-rc3.owrt.om/arch/arm/plat-s3c/include/plat/regs-usb-hs-otg.h +--- linux-2.6.29-rc3.owrt/arch/arm/plat-s3c/include/plat/regs-usb-hs-otg.h 1970-01-01 01:00:00.000000000 +0100 ++++ linux-2.6.29-rc3.owrt.om/arch/arm/plat-s3c/include/plat/regs-usb-hs-otg.h 2009-05-10 22:27:59.000000000 +0200 +@@ -0,0 +1,360 @@ ++/* linux/include/asm-arm/arch-s3c2410/regs-udc.h ++ * ++ * Copyright (C) 2008 Samsung Electronics ++ * Copyright (C) 2004 Herbert Poetzl <herbert@13thfloor.at> ++ * ++ * This include file 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. ++*/ ++ ++#ifndef __ASM_ARCH_REGS_USB_HS_OTG_H ++#define __ASM_ARCH_REGS_USB_HS_OTG_H ++ ++/* USB2.0 OTG Controller register */ ++#define S3C_USBOTG_PHYREG(x) ((x) + 0x100000 /* S3C64XX_VA_OTGSFR */) ++#define S3C_USBOTG_PHYPWR S3C_USBOTG_PHYREG(0x0) ++#define S3C_USBOTG_PHYCLK S3C_USBOTG_PHYREG(0x4) ++#define S3C_USBOTG_RSTCON S3C_USBOTG_PHYREG(0x8) ++ ++/* USB2.0 OTG Controller register */ ++/* Core Global Registers */ ++#define S3C_USBOTGREG(x) ((x) /*+ S3C64XX_VA_OTG */) ++/* OTG Control & Status */ ++#define S3C_UDC_OTG_GOTGCTL S3C_USBOTGREG(0x000) ++/* OTG Interrupt */ ++#define S3C_UDC_OTG_GOTGINT S3C_USBOTGREG(0x004) ++/* Core AHB Configuration */ ++#define S3C_UDC_OTG_GAHBCFG S3C_USBOTGREG(0x008) ++/* Core USB Configuration */ ++#define S3C_UDC_OTG_GUSBCFG S3C_USBOTGREG(0x00C) ++/* Core Reset */ ++#define S3C_UDC_OTG_GRSTCTL S3C_USBOTGREG(0x010) ++/* Core Interrupt */ ++#define S3C_UDC_OTG_GINTSTS S3C_USBOTGREG(0x014) ++/* Core Interrupt Mask */ ++#define S3C_UDC_OTG_GINTMSK S3C_USBOTGREG(0x018) ++/* Receive Status Debug Read/Status Read */ ++#define S3C_UDC_OTG_GRXSTSR S3C_USBOTGREG(0x01C) ++/* Receive Status Debug Pop/Status Pop */ ++#define S3C_UDC_OTG_GRXSTSP S3C_USBOTGREG(0x020) ++/* Receive FIFO Size */ ++#define S3C_UDC_OTG_GRXFSIZ S3C_USBOTGREG(0x024) ++/* Non-Periodic Transmit FIFO Size */ ++#define S3C_UDC_OTG_GNPTXFSIZ S3C_USBOTGREG(0x028) ++/* Non-Periodic Transmit FIFO/Queue Status */ ++#define S3C_UDC_OTG_GNPTXSTS S3C_USBOTGREG(0x02C) ++ ++/* Host Periodic Transmit FIFO Size */ ++#define S3C_UDC_OTG_HPTXFSIZ S3C_USBOTGREG(0x100) ++/* Device Periodic Transmit FIFO-1 Size */ ++#define S3C_UDC_OTG_DPTXFSIZ1 S3C_USBOTGREG(0x104) ++/* Device Periodic Transmit FIFO-2 Size */ ++#define S3C_UDC_OTG_DPTXFSIZ2 S3C_USBOTGREG(0x108) ++/* Device Periodic Transmit FIFO-3 Size */ ++#define S3C_UDC_OTG_DPTXFSIZ3 S3C_USBOTGREG(0x10C) ++/* Device Periodic Transmit FIFO-4 Size */ ++#define S3C_UDC_OTG_DPTXFSIZ4 S3C_USBOTGREG(0x110) ++/* Device Periodic Transmit FIFO-5 Size */ ++#define S3C_UDC_OTG_DPTXFSIZ5 S3C_USBOTGREG(0x114) ++/* Device Periodic Transmit FIFO-6 Size */ ++#define S3C_UDC_OTG_DPTXFSIZ6 S3C_USBOTGREG(0x118) ++/* Device Periodic Transmit FIFO-7 Size */ ++#define S3C_UDC_OTG_DPTXFSIZ7 S3C_USBOTGREG(0x11C) ++/* Device Periodic Transmit FIFO-8 Size */ ++#define S3C_UDC_OTG_DPTXFSIZ8 S3C_USBOTGREG(0x120) ++/* Device Periodic Transmit FIFO-9 Size */ ++#define S3C_UDC_OTG_DPTXFSIZ9 S3C_USBOTGREG(0x124) ++/* Device Periodic Transmit FIFO-10 Size */ ++#define S3C_UDC_OTG_DPTXFSIZ10 S3C_USBOTGREG(0x128) ++/* Device Periodic Transmit FIFO-11 Size */ ++#define S3C_UDC_OTG_DPTXFSIZ11 S3C_USBOTGREG(0x12C) ++/* Device Periodic Transmit FIFO-12 Size */ ++#define S3C_UDC_OTG_DPTXFSIZ12 S3C_USBOTGREG(0x130) ++/* Device Periodic Transmit FIFO-13 Size */ ++#define S3C_UDC_OTG_DPTXFSIZ13 S3C_USBOTGREG(0x134) ++/* Device Periodic Transmit FIFO-14 Size */ ++#define S3C_UDC_OTG_DPTXFSIZ14 S3C_USBOTGREG(0x138) ++/* Device Periodic Transmit FIFO-15 Size */ ++#define S3C_UDC_OTG_DPTXFSIZ15 S3C_USBOTGREG(0x13C) ++ ++/* Host Mode Registers ++ * Host Global Registers */ ++/* Host Configuration */ ++#define S3C_UDC_OTG_HCFG S3C_USBOTGREG(0x400) ++/* Host Frame Interval */ ++#define S3C_UDC_OTG_HFIR S3C_USBOTGREG(0x404) ++/* Host Frame Number/Frame Time Remaining */ ++#define S3C_UDC_OTG_HFNUM S3C_USBOTGREG(0x408) ++/* Host Periodic Transmit FIFO/Queue Status */ ++#define S3C_UDC_OTG_HPTXSTS S3C_USBOTGREG(0x410) ++/* Host All Channels Interrupt */ ++#define S3C_UDC_OTG_HAINT S3C_USBOTGREG(0x414) ++/* Host All Channels Interrupt Mask */ ++#define S3C_UDC_OTG_HAINTMSK S3C_USBOTGREG(0x418) ++ ++/* Host Port Control & Status Registers */ ++#define S3C_UDC_OTG_HPRT S3C_USBOTGREG(0x440) ++ ++/* Host Channel-Specific Registers */ ++/* Host Channel-0 Characteristics */ ++#define S3C_UDC_OTG_HCCHAR0 S3C_USBOTGREG(0x500) ++/* Host Channel-0 Split Control */ ++#define S3C_UDC_OTG_HCSPLT0 S3C_USBOTGREG(0x504) ++/* Host Channel-0 Interrupt */ ++#define S3C_UDC_OTG_HCINT0 S3C_USBOTGREG(0x508) ++/* Host Channel-0 Interrupt Mask */ ++#define S3C_UDC_OTG_HCINTMSK0 S3C_USBOTGREG(0x50C) ++/* Host Channel-0 Transfer Size */ ++#define S3C_UDC_OTG_HCTSIZ0 S3C_USBOTGREG(0x510) ++/* Host Channel-0 DMA Address */ ++#define S3C_UDC_OTG_HCDMA0 S3C_USBOTGREG(0x514) ++ ++/* Device Mode Registers ++ * Device Global Registers */ ++/* Device Configuration */ ++#define S3C_UDC_OTG_DCFG S3C_USBOTGREG(0x800) ++/* Device Control */ ++#define S3C_UDC_OTG_DCTL S3C_USBOTGREG(0x804) ++/* Device Status */ ++#define S3C_UDC_OTG_DSTS S3C_USBOTGREG(0x808) ++/* Device IN Endpoint Common Interrupt Mask */ ++#define S3C_UDC_OTG_DIEPMSK S3C_USBOTGREG(0x810) ++/* Device OUT Endpoint Common Interrupt Mask */ ++#define S3C_UDC_OTG_DOEPMSK S3C_USBOTGREG(0x814) ++/* Device All Endpoints Interrupt */ ++#define S3C_UDC_OTG_DAINT S3C_USBOTGREG(0x818) ++/* Device All Endpoints Interrupt Mask */ ++#define S3C_UDC_OTG_DAINTMSK S3C_USBOTGREG(0x81C) ++/* Device IN Token Sequence Learning Queue Read 1 */ ++#define S3C_UDC_OTG_DTKNQR1 S3C_USBOTGREG(0x820) ++/* Device IN Token Sequence Learning Queue Read 2 */ ++#define S3C_UDC_OTG_DTKNQR2 S3C_USBOTGREG(0x824) ++/* Device VBUS Discharge Time */ ++#define S3C_UDC_OTG_DVBUSDIS S3C_USBOTGREG(0x828) ++/* Device VBUS Pulsing Time */ ++#define S3C_UDC_OTG_DVBUSPULSE S3C_USBOTGREG(0x82C) ++/* Device IN Token Sequence Learning Queue Read 3 */ ++#define S3C_UDC_OTG_DTKNQR3 S3C_USBOTGREG(0x830) ++/* Device IN Token Sequence Learning Queue Read 4 */ ++#define S3C_UDC_OTG_DTKNQR4 S3C_USBOTGREG(0x834) ++ ++/* Device Logical IN Endpoint-Specific Registers */ ++/* Device IN Endpoint 0 Control */ ++#define S3C_UDC_OTG_DIEPCTL0 S3C_USBOTGREG(0x900) ++/* Device IN Endpoint 0 Interrupt */ ++#define S3C_UDC_OTG_DIEPINT0 S3C_USBOTGREG(0x908) ++/* Device IN Endpoint 0 Transfer Size */ ++#define S3C_UDC_OTG_DIEPTSIZ0 S3C_USBOTGREG(0x910) ++/* Device IN Endpoint 0 DMA Address */ ++#define S3C_UDC_OTG_DIEPDMA0 S3C_USBOTGREG(0x914) ++ ++/* Device IN Endpoint 2 Control */ ++#define S3C_UDC_OTG_DIEPCTL2 S3C_USBOTGREG(0x940) ++/* Device IN Endpoint 2 Interrupt */ ++#define S3C_UDC_OTG_DIEPINT2 S3C_USBOTGREG(0x948) ++/* Device IN Endpoint 2 Transfer Size */ ++#define S3C_UDC_OTG_DIEPTSIZ2 S3C_USBOTGREG(0x950) ++/* Device IN Endpoint 2 DMA Address */ ++#define S3C_UDC_OTG_DIEPDMA2 S3C_USBOTGREG(0x954) ++ ++/* Device IN Endpoint 3 Control */ ++#define S3C_UDC_OTG_DIEPCTL3 S3C_USBOTGREG(0x960) ++/* Device IN Endpoint 3 Interrupt */ ++#define S3C_UDC_OTG_DIEPINT3 S3C_USBOTGREG(0x968) ++/* Device IN Endpoint 3 Transfer Size */ ++#define S3C_UDC_OTG_DIEPTSIZ3 S3C_USBOTGREG(0x970) ++/* Device IN Endpoint 3 DMA Address */ ++#define S3C_UDC_OTG_DIEPDMA3 S3C_USBOTGREG(0x974) ++ ++/* Device Logical OUT Endpoint-Specific Registers */ ++/* Device OUT Endpoint 0 Control */ ++#define S3C_UDC_OTG_DOEPCTL0 S3C_USBOTGREG(0xB00) ++/* Device OUT Endpoint 0 Interrupt */ ++#define S3C_UDC_OTG_DOEPINT0 S3C_USBOTGREG(0xB08) ++/* Device OUT Endpoint 0 Transfer Size */ ++#define S3C_UDC_OTG_DOEPTSIZ0 S3C_USBOTGREG(0xB10) ++/* Device OUT Endpoint 0 DMA Address */ ++#define S3C_UDC_OTG_DOEPDMA0 S3C_USBOTGREG(0xB14) ++ ++/* Device OUT Endpoint 1 Control */ ++#define S3C_UDC_OTG_DOEPCTL1 S3C_USBOTGREG(0xB20) ++/* Device OUT Endpoint 1 Interrupt */ ++#define S3C_UDC_OTG_DOEPINT1 S3C_USBOTGREG(0xB28) ++/* Device OUT Endpoint 1 Transfer Size */ ++#define S3C_UDC_OTG_DOEPTSIZ1 S3C_USBOTGREG(0xB30) ++/* Device OUT Endpoint 1 DMA Address */ ++#define S3C_UDC_OTG_DOEPDMA1 S3C_USBOTGREG(0xB34) ++ ++/* Endpoint FIFO address */ ++#define S3C_UDC_OTG_EP0_FIFO S3C_USBOTGREG(0x1000) ++#define S3C_UDC_OTG_EP1_FIFO S3C_USBOTGREG(0x2000) ++#define S3C_UDC_OTG_EP2_FIFO S3C_USBOTGREG(0x3000) ++#define S3C_UDC_OTG_EP3_FIFO S3C_USBOTGREG(0x4000) ++#define S3C_UDC_OTG_EP4_FIFO S3C_USBOTGREG(0x5000) ++#define S3C_UDC_OTG_EP5_FIFO S3C_USBOTGREG(0x6000) ++#define S3C_UDC_OTG_EP6_FIFO S3C_USBOTGREG(0x7000) ++#define S3C_UDC_OTG_EP7_FIFO S3C_USBOTGREG(0x8000) ++#define S3C_UDC_OTG_EP8_FIFO S3C_USBOTGREG(0x9000) ++ ++/* S3C_USBOTG_PHYPWR */ ++#define OTG_ENABLE (0x0<<4) ++#define OTG_DISABLE (0x1<<4) ++#define ANALOG_PWR_UP (0x0<<3) ++#define ANALOG_PWR_DOWN (0x1<<3) ++#define SUSPEND_DISABLE (0x0<<0) ++#define SUSPEND_ENABLE (0x1<<0) ++ ++/* S3C_USBOTG_PHYCLK */ ++#define REF_CLK_CRYSTAL (0x0<<5) ++#define REF_CLK_OSCC (0x1<<5) ++ ++/* S3C_USBOTG_RSTCON */ ++#define SW_RST_OFF (0x0<<0) ++#define SW_RST_ON (0x1<<0) ++ ++/* S3C_UDC_OTG_GOTGCTL */ ++#define B_SESSION_VALID (0x1<<19) ++#define A_SESSION_VALID (0x1<<18) ++ ++/* S3C_UDC_OTG_GAHBCFG */ ++#define PTXFE_HALF (0x0<<8) ++#define PTXFE_ZERO (0x1<<8) ++#define NPTXFE_HALF (0x0<<7) ++#define NPTXFE_ZERO (0x1<<7) ++#define MODE_SLAVE (0x0<<5) ++#define MODE_DMA (0x1<<5) ++#define BURST_SINGLE (0x0<<1) ++#define BURST_INCR (0x1<<1) ++#define BURST_INCR4 (0x3<<1) ++#define BURST_INCR8 (0x5<<1) ++#define BURST_INCR16 (0x7<<1) ++#define GBL_INT_UNMASK (0x1<<0) ++#define GBL_INT_MASK (0x0<<0) ++ ++/* S3C_UDC_OTG_GUSBCFG */ ++#define PHY_CLK_480M (0x0<<15) ++#define PHY_CLK_48M (0x1<<15) ++#define TXFIFO_RE_DIS (0x0<<14) ++#define TXFIFO_RE_EN (0x1<<14) ++#define TURN_AROUND (0x5<<10) ++#define HNP_DISABLE (0x0<<9) ++#define HNP_ENABLE (0x1<<9) ++#define SRP_DISABLE (0x0<<8) ++#define SRP_ENABLE (0x1<<8) ++#define ULPI_DDR (0x0<<7) ++#define HS_UTMI (0x0<<6) ++#define INTERF_UTMI (0x0<<4) ++#define INTERF_ULPI (0x1<<4) ++#define PHY_INTERF_8 (0x0<<3) ++#define PHY_INTERF_16 (0x1<<3) ++#define TIME_OUT_CAL (0x7<<0) ++ ++/* S3C_UDC_OTG_GRSTCTL */ ++#define AHB_MASTER_IDLE (1u<<31) ++#define CORE_SOFT_RESET (0x1<<0) ++ ++/* S3C_UDC_OTG_GINTSTS/S3C_UDC_OTG_GINTMSK core interrupt register */ ++#define INT_RESUME (0x1<<31) ++#define INT_DISCONN (0x1<<29) ++#define INT_CONN_CNG (0x1<<28) ++#define INT_OUT_EP (0x1<<19) ++#define INT_IN_EP (0x1<<18) ++#define INT_ENUMDONE (0x1<<13) ++#define INT_RESET (0x1<<12) ++#define INT_SUSPEND (0x1<<11) ++#define INT_EARLY_SUSPEND (0x1<<10) ++#define INT_TX_FIFO_EMPTY (0x1<<5) ++#define INT_RX_FIFO_NOT_EMPTY (0x1<<4) ++#define INT_SOF (0x1<<3) ++#define INT_DEV_MODE (0x0<<0) ++#define INT_HOST_MODE (0x1<<1) ++ ++#define FULL_SPEED_CONTROL_PKT_SIZE 8 ++#define FULL_SPEED_BULK_PKT_SIZE 64 ++ ++#define HIGH_SPEED_CONTROL_PKT_SIZE 64 ++#define HIGH_SPEED_BULK_PKT_SIZE 512 ++ ++/* S3C_UDC_OTG_DSTS */ ++#define RX_FIFO_SIZE (2048<<0) ++#define NPTX_FIFO_START_ADDR (RX_FIFO_SIZE<<0) ++#define NPTX_FIFO_SIZE (2048<<16) ++#define PTX_FIFO_SIZE (2048<<16) ++#define USB_HIGH_30_60MHZ (0x0<<1) ++#define USB_FULL_30_60MHZ (0x1<<1) ++#define USB_LOW_6MHZ (0x2<<1) ++#define USB_FULL_48MHZ (0x3<<1) ++ ++/* S3C_UDC_OTG_GRXSTSP */ ++#define BYTE_COUNT(x) ((x & (0x7FF<<4)) >> 4) ++#define PKT_STS(x) ((x & (0xF<<17)) >> 17) ++#define EP_NUM(x) (x & 0xF) ++ ++#define OUT_PKT_RECEIVED (0x2) ++#define OUT_COMPLELTED (0x3) ++#define SETUP_COMPLETED (0x4) ++#define SETUP_PKT_RECEIVED (0x6) ++ ++/* S3C_UDC_OTG_DCFG */ ++#define EP_MIS_CNT(x) (x<<18) ++#define DEVICE_ADDR(x) (x<<4) ++#define SPEED_2_HIGH (0x0<<0) ++#define SPEED_2_FULL (0x1<<0) ++#define SPEED_1_LOW (0x2<<0) ++#define SPEED_1_FULL (0x3<<0) ++ ++/* S3C_UDC_OTG_DCTL device control register */ ++#define NORMAL_OPERATION (0x1<<0) ++#define SOFT_DISCONNECT (0x1<<1) ++ ++/* S3C_UDC_OTG_DSTS */ ++#define ENUM_SPEED(x) (x & (0x3<<1)) ++#define FRAME_CNT(x) (x & (0x3ff<<8)) ++ ++/* S3C_UDC_OTG_DAINT device all endpoint interrupt register */ ++#define S3C_UDC_INT_IN_EP0 (0x1<<0) ++#define S3C_UDC_INT_IN_EP2 (0x1<<2) ++#define S3C_UDC_INT_IN_EP3 (0x1<<3) ++#define S3C_UDC_INT_OUT_EP0 (0x1<<16) ++#define S3C_UDC_INT_OUT_EP1 (0x1<<17) ++#define S3C_UDC_INT_OUT_EP4 (0x1<<20) ++ ++/* S3C_UDC_OTG_DIEPCTL0/DOEPCTL0 device control ++ IN/OUT endpoint 0 control register */ ++#define DEPCTL_EPENA (0x1<<31) ++#define DEPCTL_EPDIS (0x1<<30) ++#define DEPCTL_SNAK (0x1<<27) ++#define DEPCTL_CNAK (0x1<<26) ++#define DEPCTL_CTRL_TYPE (0x0<<18) ++#define DEPCTL_ISO_TYPE (0x1<<18) ++#define DEPCTL_BULK_TYPE (0x2<<18) ++#define DEPCTL_INTR_TYPE (0x3<<18) ++#define DEPCTL_USBACTEP (0x1<<15) ++#define DEPCTL0_MPS_64 (0x0<<0) ++#define DEPCTL0_MPS_32 (0x1<<0) ++#define DEPCTL0_MPS_16 (0x2<<0) ++#define DEPCTL0_MPS_8 (0x3<<0) ++ ++/* S3C_UDC_OTG_DIEPINTn */ ++#define IN_EP_NAK_EFF (0x1<<6) ++#define IN_TK_EPMIS (0x1<<5) ++#define IN_TK_TXFEMP (0x1<<4) ++#define IN_EP_TIMEOUT (0x1<<3) ++ ++/* S3C_UDC_OTG_DOEPINTn */ ++#define BACK2BACK_SETUP (0x1<<6) ++#define OUT_TK_EP_DIS (0x1<<4) ++#define SETUP_PHASE_DONE (0x1<<3) ++ ++/* S3C_UDC_OTG_DIEPINTn/DOEPINTn */ ++#define AHB_ERROR (0x1<<2) ++#define EPDISBLD (0x1<<1) ++#define TRANSFER_DONE (0x1<<0) ++ ++/* S3C_UDC_OTG_DIEPTSIZn */ ++#define PKT_CNT(x) (x<<19) ++#define XFERSIZE(x) (x<<0) ++ ++#endif +diff -ruN --exclude='*.orig' --exclude='*.rej' linux-2.6.29-rc3.owrt/arch/arm/plat-s3c/include/plat/sdhci.h linux-2.6.29-rc3.owrt.om/arch/arm/plat-s3c/include/plat/sdhci.h +--- linux-2.6.29-rc3.owrt/arch/arm/plat-s3c/include/plat/sdhci.h 2009-05-10 22:05:04.000000000 +0200 ++++ linux-2.6.29-rc3.owrt.om/arch/arm/plat-s3c/include/plat/sdhci.h 2009-05-10 22:27:59.000000000 +0200 +@@ -29,6 +29,7 @@ + * is necessary the controllers and/or GPIO blocks require the + * changing of driver-strength and other controls dependant on + * the card and speed of operation. ++ * sdhci_host: Pointer kept during init, allows presence change notification + * + * Initialisation data specific to either the machine or the platform + * for the device driver to use or call-back when configuring gpio or +@@ -45,8 +46,11 @@ + void __iomem *regbase, + struct mmc_ios *ios, + struct mmc_card *card); ++ struct sdhci_host * sdhci_host; + }; + ++extern void sdhci_s3c_force_presence_change(struct platform_device *pdev); ++ + /** + * s3c_sdhci0_set_platdata - Set platform data for S3C SDHCI device. + * @pd: Platform data to register to device. +diff -ruN --exclude='*.orig' --exclude='*.rej' linux-2.6.29-rc3.owrt/arch/arm/plat-s3c/include/plat/usb-control.h linux-2.6.29-rc3.owrt.om/arch/arm/plat-s3c/include/plat/usb-control.h +--- linux-2.6.29-rc3.owrt/arch/arm/plat-s3c/include/plat/usb-control.h 1970-01-01 01:00:00.000000000 +0100 ++++ linux-2.6.29-rc3.owrt.om/arch/arm/plat-s3c/include/plat/usb-control.h 2009-05-10 22:27:59.000000000 +0200 +@@ -0,0 +1,41 @@ ++/* arch/arm/plat-s3c/include/plat/usb-control.h ++ * ++ * Copyright (c) 2004 Simtec Electronics ++ * Ben Dooks <ben@simtec.co.uk> ++ * ++ * S3C2410 - usb port information ++ * ++ * 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_ARCH_USBCONTROL_H ++#define __ASM_ARCH_USBCONTROL_H "arch/arm/plat-s3c/include/plat/usb-control.h" ++ ++#define S3C_HCDFLG_USED (1) ++ ++struct s3c2410_hcd_port { ++ unsigned char flags; ++ unsigned char power; ++ unsigned char oc_status; ++ unsigned char oc_changed; ++}; ++ ++struct s3c2410_hcd_info { ++ struct usb_hcd *hcd; ++ struct s3c2410_hcd_port port[2]; ++ ++ void (*power_control)(int port, int to); ++ void (*enable_oc)(struct s3c2410_hcd_info *, int on); ++ void (*report_oc)(struct s3c2410_hcd_info *, int ports); ++}; ++ ++static void inline s3c2410_usb_report_oc(struct s3c2410_hcd_info *info, int ports) ++{ ++ if (info->report_oc != NULL) { ++ (info->report_oc)(info, ports); ++ } ++} ++ ++#endif /*__ASM_ARCH_USBCONTROL_H */ +diff -ruN --exclude='*.orig' --exclude='*.rej' linux-2.6.29-rc3.owrt/arch/arm/plat-s3c/init.c linux-2.6.29-rc3.owrt.om/arch/arm/plat-s3c/init.c +--- linux-2.6.29-rc3.owrt/arch/arm/plat-s3c/init.c 2009-05-10 22:05:04.000000000 +0200 ++++ linux-2.6.29-rc3.owrt.om/arch/arm/plat-s3c/init.c 2009-05-10 22:27:59.000000000 +0200 +@@ -31,6 +31,34 @@ + + static struct cpu_table *cpu; + ++static void __init set_system_rev(unsigned int idcode) ++{ ++ /* ++ * system_rev encoding is as follows ++ * system_rev & 0xff000000 -> S3C Class (24xx/64xx) ++ * system_rev & 0xfff00000 -> S3C Sub Class (241x/244x) ++ * system_rev & 0xffff0000 -> S3C Type (2410/2440/6400/6410) ++ * ++ * Remaining[15:0] are preserved from the value set by ATAG ++ * ++ * Exception: ++ * Store Revision A to 1 such as ++ * s3c2410A to s3c2411 ++ * s3c2440A to s3c2441 ++ */ ++ ++ system_rev &= 0xffff; ++ system_rev |= (idcode & 0x0ffff000) << 4; ++ ++ if (idcode == 0x32410002 || idcode == 0x32440001) ++ system_rev |= (0x1 << 16); ++ if (idcode == 0x32440aaa /* s3c2442 */ ++ || idcode == 0x32440aab) /* s3c2442b */ ++ system_rev |= (0x2 << 16); ++ if (idcode == 0x0) /* s3c2400 */ ++ system_rev |= (0x2400 << 16); ++} ++ + static struct cpu_table * __init s3c_lookup_cpu(unsigned long idcode, + struct cpu_table *tab, + unsigned int count) +@@ -53,6 +81,8 @@ + panic("Unknown S3C24XX CPU"); + } + ++ set_system_rev(idcode); ++ + printk("CPU %s (id 0x%08lx)\n", cpu->name, idcode); + + if (cpu->map_io == NULL || cpu->init == NULL) { +diff -ruN --exclude='*.orig' --exclude='*.rej' linux-2.6.29-rc3.owrt/arch/arm/plat-s3c/Kconfig linux-2.6.29-rc3.owrt.om/arch/arm/plat-s3c/Kconfig +--- linux-2.6.29-rc3.owrt/arch/arm/plat-s3c/Kconfig 2009-05-10 22:05:04.000000000 +0200 ++++ linux-2.6.29-rc3.owrt.om/arch/arm/plat-s3c/Kconfig 2009-05-10 22:27:59.000000000 +0200 +@@ -71,6 +71,15 @@ + Resume code. See <file:Documentation/arm/Samsung-S3C24XX/Suspend.txt> + for more information. + ++config S3C_PM_DEBUG_LED_SMDK ++ bool "SMDK LED suspend/resume debugging" ++ depends on PM && (MACH_SMDK6410) ++ help ++ Say Y here to enable the use of the SMDK LEDs on the baseboard ++ for debugging of the state of the suspend and resume process. ++ ++ Note, this currently only works for S3C64XX based SMDK boards. ++ + config S3C2410_PM_CHECK + bool "S3C2410 PM Suspend Memory CRC" + depends on PM && CRC32 +@@ -150,6 +159,18 @@ + Internal configuration to enable S3C64XX style GPIO configuration + functions. + ++# DMA ++ ++config S3C_DMA ++ bool ++ help ++ Internal configuration for S3C DMA core ++ ++config S3C_PWM ++ bool ++ help ++ PWM timer code for the S3C2410, and similar processors ++ + # device definitions to compile in + + config S3C_DEV_HSMMC +@@ -172,4 +193,14 @@ + help + Compile in platform device definition for framebuffer + ++config S3C_DEV_USB_HOST ++ bool ++ help ++ Compile in platform device definition for USB host. ++ ++config S3C_DEV_CAMIF ++ bool ++ help ++ Compile in platform device definitions for camera interface code ++ + endif +diff -ruN --exclude='*.orig' --exclude='*.rej' linux-2.6.29-rc3.owrt/arch/arm/plat-s3c/Makefile linux-2.6.29-rc3.owrt.om/arch/arm/plat-s3c/Makefile +--- linux-2.6.29-rc3.owrt/arch/arm/plat-s3c/Makefile 2009-05-10 22:05:04.000000000 +0200 ++++ linux-2.6.29-rc3.owrt.om/arch/arm/plat-s3c/Makefile 2009-05-10 22:27:59.000000000 +0200 +@@ -18,6 +18,16 @@ + obj-y += gpio.o + obj-y += gpio-config.o + ++# DMA support ++ ++obj-$(CONFIG_S3C_DMA) += dma.o ++ ++# PM support ++ ++obj-$(CONFIG_PM) += pm.o ++obj-$(CONFIG_PM) += pm-gpio.o ++obj-$(CONFIG_S3C2410_PM_CHECK) += pm-check.o ++ + # devices + + obj-$(CONFIG_S3C_DEV_HSMMC) += dev-hsmmc.o +@@ -25,3 +35,9 @@ + obj-y += dev-i2c0.o + obj-$(CONFIG_S3C_DEV_I2C1) += dev-i2c1.o + obj-$(CONFIG_S3C_DEV_FB) += dev-fb.o ++obj-$(CONFIG_S3C_DEV_USB_HOST) += dev-usb.o ++obj-$(CONFIG_S3C_DEV_CAMIF) += dev-camif.o ++ ++obj-$(CONFIG_S3C_PWM) += pwm.o ++obj-$(CONFIG_S3C_DMA) += dma.o ++ +diff -ruN --exclude='*.orig' --exclude='*.rej' linux-2.6.29-rc3.owrt/arch/arm/plat-s3c/pm.c linux-2.6.29-rc3.owrt.om/arch/arm/plat-s3c/pm.c +--- linux-2.6.29-rc3.owrt/arch/arm/plat-s3c/pm.c 1970-01-01 01:00:00.000000000 +0100 ++++ linux-2.6.29-rc3.owrt.om/arch/arm/plat-s3c/pm.c 2009-05-10 22:27:59.000000000 +0200 +@@ -0,0 +1,375 @@ ++/* linux/arch/arm/plat-s3c/pm.c ++ * ++ * Copyright 2008 Openmoko, Inc. ++ * Copyright 2004,2006,2008 Simtec Electronics ++ * Ben Dooks <ben@simtec.co.uk> ++ * http://armlinux.simtec.co.uk/ ++ * ++ * S3C common power management (suspend to ram) support. ++ * ++ * This program is free software; you can redistribute it and/or modify ++ * it under the terms of the GNU General Public License version 2 as ++ * published by the Free Software Foundation. ++*/ ++ ++#include <linux/init.h> ++#include <linux/suspend.h> ++#include <linux/errno.h> ++#include <linux/delay.h> ++#include <linux/serial_core.h> ++#include <linux/io.h> ++ ++#include <asm/cacheflush.h> ++#include <mach/hardware.h> ++#include <mach/map.h> ++ ++#include <plat/regs-serial.h> ++#include <mach/regs-clock.h> ++#include <mach/regs-irq.h> ++#include <asm/irq.h> ++ ++#include <plat/pm.h> ++#include <plat/pm-core.h> ++ ++/* for external use */ ++ ++unsigned long s3c_pm_flags; ++ ++/* Debug code: ++ * ++ * This code supports debug output to the low level UARTs for use on ++ * resume before the console layer is available. ++*/ ++ ++#ifdef CONFIG_S3C2410_PM_DEBUG ++extern void printascii(const char *); ++ ++void s3c_pm_dbg(const char *fmt, ...) ++{ ++ va_list va; ++ char buff[256]; ++ ++ va_start(va, fmt); ++ vsprintf(buff, fmt, va); ++ va_end(va); ++ ++ printascii(buff); ++} ++ ++static inline void s3c_pm_debug_init(void) ++{ ++ /* restart uart clocks so we can use them to output */ ++ s3c_pm_debug_init_uart(); ++} ++ ++#else ++#define s3c_pm_debug_init() do { } while(0) ++ ++#endif /* CONFIG_S3C2410_PM_DEBUG */ ++ ++/* Save the UART configurations if we are configured for debug. */ ++ ++unsigned char pm_uart_udivslot; ++ ++#ifdef CONFIG_S3C2410_PM_DEBUG ++ ++struct pm_uart_save uart_save[CONFIG_SERIAL_SAMSUNG_UARTS]; ++ ++static void s3c_pm_save_uart(unsigned int uart, struct pm_uart_save *save) ++{ ++ void __iomem *regs = S3C_VA_UARTx(uart); ++ ++ save->ulcon = __raw_readl(regs + S3C2410_ULCON); ++ save->ucon = __raw_readl(regs + S3C2410_UCON); ++ save->ufcon = __raw_readl(regs + S3C2410_UFCON); ++ save->umcon = __raw_readl(regs + S3C2410_UMCON); ++ save->ubrdiv = __raw_readl(regs + S3C2410_UBRDIV); ++ ++ if (pm_uart_udivslot) ++ save->udivslot = __raw_readl(regs + S3C2443_DIVSLOT); ++ ++ S3C_PMDBG("UART[%d]: ULCON=%04x, UCON=%04x, UFCON=%04x, UBRDIV=%04x\n", ++ uart, save->ulcon, save->ucon, save->ufcon, save->ubrdiv); ++} ++ ++static void s3c_pm_save_uarts(void) ++{ ++ struct pm_uart_save *save = uart_save; ++ unsigned int uart; ++ ++ for (uart = 0; uart < CONFIG_SERIAL_SAMSUNG_UARTS; uart++, save++) ++ s3c_pm_save_uart(uart, save); ++} ++ ++static void s3c_pm_restore_uart(unsigned int uart, struct pm_uart_save *save) ++{ ++ void __iomem *regs = S3C_VA_UARTx(uart); ++ ++ s3c_pm_arch_update_uart(regs, save); ++ ++ __raw_writel(save->ulcon, regs + S3C2410_ULCON); ++ __raw_writel(save->ucon, regs + S3C2410_UCON); ++ __raw_writel(save->ufcon, regs + S3C2410_UFCON); ++ __raw_writel(save->umcon, regs + S3C2410_UMCON); ++ __raw_writel(save->ubrdiv, regs + S3C2410_UBRDIV); ++ ++ if (pm_uart_udivslot) ++ __raw_writel(save->udivslot, regs + S3C2443_DIVSLOT); ++} ++ ++static void s3c_pm_restore_uarts(void) ++{ ++ struct pm_uart_save *save = uart_save; ++ unsigned int uart; ++ ++ for (uart = 0; uart < CONFIG_SERIAL_SAMSUNG_UARTS; uart++, save++) ++ s3c_pm_restore_uart(uart, save); ++} ++#else ++static void s3c_pm_save_uarts(void) { } ++static void s3c_pm_restore_uarts(void) { } ++#endif ++ ++/* The IRQ ext-int code goes here, it is too small to currently bother ++ * with its own file. */ ++ ++unsigned long s3c_irqwake_intmask = 0xffffffffL; ++unsigned long s3c_irqwake_eintmask = 0xffffffffL; ++ ++int s3c_irqext_wake(unsigned int irqno, unsigned int state) ++{ ++ unsigned long bit = 1L << IRQ_EINT_BIT(irqno); ++ ++ if (!(s3c_irqwake_eintallow & bit)) ++ return -ENOENT; ++ ++ printk(KERN_INFO "wake %s for irq %d\n", ++ state ? "enabled" : "disabled", irqno); ++ ++ if (!state) ++ s3c_irqwake_eintmask |= bit; ++ else ++ s3c_irqwake_eintmask &= ~bit; ++ ++ return 0; ++} ++ ++/* helper functions to save and restore register state */ ++ ++/** ++ * s3c_pm_do_save() - save a set of registers for restoration on resume. ++ * @ptr: Pointer to an array of registers. ++ * @count: Size of the ptr array. ++ * ++ * Run through the list of registers given, saving their contents in the ++ * array for later restoration when we wakeup. ++ */ ++void s3c_pm_do_save(struct sleep_save *ptr, int count) ++{ ++ for (; count > 0; count--, ptr++) { ++ ptr->val = __raw_readl(ptr->reg); ++ S3C_PMDBG("saved %p value %08lx\n", ptr->reg, ptr->val); ++ } ++} ++ ++/** ++ * s3c_pm_do_restore() - restore register values from the save list. ++ * @ptr: Pointer to an array of registers. ++ * @count: Size of the ptr array. ++ * ++ * Restore the register values saved from s3c_pm_do_save(). ++ * ++ * Note, we do not use S3C_PMDBG() in here, as the system may not have ++ * restore the UARTs state yet ++*/ ++ ++void s3c_pm_do_restore(struct sleep_save *ptr, int count) ++{ ++ for (; count > 0; count--, ptr++) { ++ printk(KERN_DEBUG "restore %p (restore %08lx, was %08x)\n", ++ ptr->reg, ptr->val, __raw_readl(ptr->reg)); ++ ++ __raw_writel(ptr->val, ptr->reg); ++ } ++} ++ ++/** ++ * s3c_pm_do_restore_core() - early restore register values from save list. ++ * ++ * This is similar to s3c_pm_do_restore() except we try and minimise the ++ * side effects of the function in case registers that hardware might need ++ * to work has been restored. ++ * ++ * WARNING: Do not put any debug in here that may effect memory or use ++ * peripherals, as things may be changing! ++*/ ++ ++void s3c_pm_do_restore_core(struct sleep_save *ptr, int count) ++{ ++ for (; count > 0; count--, ptr++) ++ __raw_writel(ptr->val, ptr->reg); ++} ++ ++/* s3c2410_pm_show_resume_irqs ++ * ++ * print any IRQs asserted at resume time (ie, we woke from) ++*/ ++static void s3c_pm_show_resume_irqs(int start, unsigned long which, ++ unsigned long mask) ++{ ++ int i; ++ ++ which &= ~mask; ++ ++ for (i = 0; i <= 31; i++) { ++ if (which & (1L<<i)) { ++ S3C_PMDBG("IRQ %d asserted at resume\n", start+i); ++ } ++ } ++} ++ ++ ++void (*pm_cpu_prep)(void); ++void (*pm_cpu_sleep)(void); ++ ++#define any_allowed(mask, allow) (((mask) & (allow)) != (allow)) ++ ++/* s3c_pm_enter ++ * ++ * central control for sleep/resume process ++*/ ++ ++static int s3c_pm_enter(suspend_state_t state) ++{ ++ unsigned long regs_save[16]; ++ ++ /* ensure the debug is initialised (if enabled) */ ++ ++ s3c_pm_debug_init(); ++ ++ S3C_PMDBG("%s(%d)\n", __func__, state); ++ ++ if (pm_cpu_prep == NULL || pm_cpu_sleep == NULL) { ++ printk(KERN_ERR "%s: error: no cpu sleep function\n", __func__); ++ return -EINVAL; ++ } ++ ++ /* check if we have anything to wake-up with... bad things seem ++ * to happen if you suspend with no wakeup (system will often ++ * require a full power-cycle) ++ */ ++ ++ if (!any_allowed(s3c_irqwake_intmask, s3c_irqwake_intallow) && ++ !any_allowed(s3c_irqwake_eintmask, s3c_irqwake_eintallow)) { ++ printk(KERN_ERR "%s: No wake-up sources!\n", __func__); ++ printk(KERN_ERR "%s: Aborting sleep\n", __func__); ++ return -EINVAL; ++ } ++ ++ /* store the physical address of the register recovery block */ ++ ++ s3c_sleep_save_phys = virt_to_phys(regs_save); ++ ++ S3C_PMDBG("s3c_sleep_save_phys=0x%08lx\n", s3c_sleep_save_phys); ++ ++ /* save all necessary core registers not covered by the drivers */ ++ ++ s3c_pm_save_gpios(); ++ s3c_pm_save_uarts(); ++ s3c_pm_save_core(); ++ ++ /* set the irq configuration for wake */ ++ ++ s3c_pm_configure_extint(); ++ ++ S3C_PMDBG("sleep: irq wakeup masks: %08lx,%08lx\n", ++ s3c_irqwake_intmask, s3c_irqwake_eintmask); ++ ++ s3c_pm_arch_prepare_irqs(); ++ ++ /* call cpu specific preparation */ ++ ++ pm_cpu_prep(); ++ ++ /* flush cache back to ram */ ++ ++ flush_cache_all(); ++ ++ s3c_pm_check_store(); ++ ++ /* send the cpu to sleep... */ ++ ++ s3c_pm_arch_stop_clocks(); ++ ++ /* s3c2410_cpu_save will also act as our return point from when ++ * we resume as it saves its own register state, so use the return ++ * code to differentiate return from save and return from sleep */ ++ ++ if (s3c_cpu_save(regs_save) == 0) { ++ flush_cache_all(); ++ pm_cpu_sleep(); ++ } ++ ++ /* restore the cpu state using the kernel's cpu init code. */ ++ ++ cpu_init(); ++ ++ /* restore the system state */ ++ ++ s3c_pm_restore_core(); ++ s3c_pm_restore_uarts(); ++ s3c_pm_restore_gpios(); ++ ++ s3c_pm_debug_init(); ++ ++ /* check what irq (if any) restored the system */ ++ ++ s3c_pm_arch_show_resume_irqs(); ++ ++ S3C_PMDBG("%s: post sleep, preparing to return\n", __func__); ++ ++ s3c_pm_check_restore(); ++ ++ /* LEDs should now be 1110 */ ++ s3c_pm_debug_smdkled(1 << 1, 0); ++ ++ /* ok, let's return from sleep */ ++ ++ S3C_PMDBG("S3C PM Resume (post-restore)\n"); ++ return 0; ++} ++ ++static int s3c_pm_prepare(void) ++{ ++ /* prepare check area if configured */ ++ ++ s3c_pm_check_prepare(); ++ return 0; ++} ++ ++static void s3c_pm_finish(void) ++{ ++ s3c_pm_check_cleanup(); ++} ++ ++static struct platform_suspend_ops s3c_pm_ops = { ++ .enter = s3c_pm_enter, ++ .prepare = s3c_pm_prepare, ++ .finish = s3c_pm_finish, ++ .valid = suspend_valid_only_mem, ++}; ++ ++/* s3c_pm_init ++ * ++ * Attach the power management functions. This should be called ++ * from the board specific initialisation if the board supports ++ * it. ++*/ ++ ++int __init s3c_pm_init(void) ++{ ++ printk("S3C Power Management, Copyright 2004 Simtec Electronics\n"); ++ ++ suspend_set_ops(&s3c_pm_ops); ++ return 0; ++} +diff -ruN --exclude='*.orig' --exclude='*.rej' linux-2.6.29-rc3.owrt/arch/arm/plat-s3c/pm-check.c linux-2.6.29-rc3.owrt.om/arch/arm/plat-s3c/pm-check.c +--- linux-2.6.29-rc3.owrt/arch/arm/plat-s3c/pm-check.c 1970-01-01 01:00:00.000000000 +0100 ++++ linux-2.6.29-rc3.owrt.om/arch/arm/plat-s3c/pm-check.c 2009-05-10 22:27:59.000000000 +0200 +@@ -0,0 +1,242 @@ ++/* linux/arch/arm/plat-s3c/pm-check.c ++ * originally in linux/arch/arm/plat-s3c24xx/pm.c ++ * ++ * Copyright (c) 2004,2006,2008 Simtec Electronics ++ * http://armlinux.simtec.co.uk ++ * Ben Dooks <ben@simtec.co.uk> ++ * ++ * S3C Power Mangament - suspend/resume memory corruptiuon check. ++ * ++ * 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/suspend.h> ++#include <linux/init.h> ++#include <linux/crc32.h> ++#include <linux/ioport.h> ++ ++#include <plat/pm.h> ++ ++#if CONFIG_S3C2410_PM_CHECK_CHUNKSIZE < 1 ++#error CONFIG_S3C2410_PM_CHECK_CHUNKSIZE must be a positive non-zero value ++#endif ++ ++/* suspend checking code... ++ * ++ * this next area does a set of crc checks over all the installed ++ * memory, so the system can verify if the resume was ok. ++ * ++ * CONFIG_S3C2410_PM_CHECK_CHUNKSIZE defines the block-size for the CRC, ++ * increasing it will mean that the area corrupted will be less easy to spot, ++ * and reducing the size will cause the CRC save area to grow ++*/ ++ ++#define CHECK_CHUNKSIZE (CONFIG_S3C2410_PM_CHECK_CHUNKSIZE * 1024) ++ ++static u32 crc_size; /* size needed for the crc block */ ++static u32 *crcs; /* allocated over suspend/resume */ ++ ++typedef u32 *(run_fn_t)(struct resource *ptr, u32 *arg); ++ ++/* s3c_pm_run_res ++ * ++ * go through the given resource list, and look for system ram ++*/ ++ ++static void s3c_pm_run_res(struct resource *ptr, run_fn_t fn, u32 *arg) ++{ ++ while (ptr != NULL) { ++ if (ptr->child != NULL) ++ s3c_pm_run_res(ptr->child, fn, arg); ++ ++ if ((ptr->flags & IORESOURCE_MEM) && ++ strcmp(ptr->name, "System RAM") == 0) { ++ S3C_PMDBG("Found system RAM at %08lx..%08lx\n", ++ (unsigned long)ptr->start, ++ (unsigned long)ptr->end); ++ arg = (fn)(ptr, arg); ++ } ++ ++ ptr = ptr->sibling; ++ } ++} ++ ++static void s3c_pm_run_sysram(run_fn_t fn, u32 *arg) ++{ ++ s3c_pm_run_res(&iomem_resource, fn, arg); ++} ++ ++static u32 *s3c_pm_countram(struct resource *res, u32 *val) ++{ ++ u32 size = (u32)(res->end - res->start)+1; ++ ++ size += CHECK_CHUNKSIZE-1; ++ size /= CHECK_CHUNKSIZE; ++ ++ S3C_PMDBG("Area %08lx..%08lx, %d blocks\n", ++ (unsigned long)res->start, (unsigned long)res->end, size); ++ ++ *val += size * sizeof(u32); ++ return val; ++} ++ ++/* s3c_pm_prepare_check ++ * ++ * prepare the necessary information for creating the CRCs. This ++ * must be done before the final save, as it will require memory ++ * allocating, and thus touching bits of the kernel we do not ++ * know about. ++*/ ++ ++void s3c_pm_check_prepare(void) ++{ ++ crc_size = 0; ++ ++ s3c_pm_run_sysram(s3c_pm_countram, &crc_size); ++ ++ S3C_PMDBG("s3c_pm_prepare_check: %u checks needed\n", crc_size); ++ ++ crcs = kmalloc(crc_size+4, GFP_KERNEL); ++ if (crcs == NULL) ++ printk(KERN_ERR "Cannot allocated CRC save area\n"); ++} ++ ++static u32 *s3c_pm_makecheck(struct resource *res, u32 *val) ++{ ++ unsigned long addr, left; ++ ++ for (addr = res->start; addr < res->end; ++ addr += CHECK_CHUNKSIZE) { ++ left = res->end - addr; ++ ++ if (left > CHECK_CHUNKSIZE) ++ left = CHECK_CHUNKSIZE; ++ ++ *val = crc32_le(~0, phys_to_virt(addr), left); ++ val++; ++ } ++ ++ return val; ++} ++ ++/* s3c_pm_check_store ++ * ++ * compute the CRC values for the memory blocks before the final ++ * sleep. ++*/ ++ ++void s3c_pm_check_store(void) ++{ ++ if (crcs != NULL) ++ s3c_pm_run_sysram(s3c_pm_makecheck, crcs); ++} ++ ++/* in_region ++ * ++ * return TRUE if the area defined by ptr..ptr+size contains the ++ * what..what+whatsz ++*/ ++ ++static inline int in_region(void *ptr, int size, void *what, size_t whatsz) ++{ ++ if ((what+whatsz) < ptr) ++ return 0; ++ ++ if (what > (ptr+size)) ++ return 0; ++ ++ return 1; ++} ++ ++/** ++ * s3c_pm_runcheck() - helper to check a resource on restore. ++ * @res: The resource to check ++ * @vak: Pointer to list of CRC32 values to check. ++ * ++ * Called from the s3c_pm_check_restore() via s3c_pm_run_sysram(), this ++ * function runs the given memory resource checking it against the stored ++ * CRC to ensure that memory is restored. The function tries to skip as ++ * many of the areas used during the suspend process. ++ */ ++static u32 *s3c_pm_runcheck(struct resource *res, u32 *val) ++{ ++ void *save_at = phys_to_virt(s3c_sleep_save_phys); ++ unsigned long addr; ++ unsigned long left; ++ void *stkpage; ++ void *ptr; ++ u32 calc; ++ ++ stkpage = (void *)((u32)&calc & ~PAGE_MASK); ++ ++ for (addr = res->start; addr < res->end; ++ addr += CHECK_CHUNKSIZE) { ++ left = res->end - addr; ++ ++ if (left > CHECK_CHUNKSIZE) ++ left = CHECK_CHUNKSIZE; ++ ++ ptr = phys_to_virt(addr); ++ ++ if (in_region(ptr, left, stkpage, 4096)) { ++ S3C_PMDBG("skipping %08lx, has stack in\n", addr); ++ goto skip_check; ++ } ++ ++ if (in_region(ptr, left, crcs, crc_size)) { ++ S3C_PMDBG("skipping %08lx, has crc block in\n", addr); ++ goto skip_check; ++ } ++ ++ if (in_region(ptr, left, save_at, 32*4 )) { ++ S3C_PMDBG("skipping %08lx, has save block in\n", addr); ++ goto skip_check; ++ } ++ ++ /* calculate and check the checksum */ ++ ++ calc = crc32_le(~0, ptr, left); ++ if (calc != *val) { ++ printk(KERN_ERR "Restore CRC error at " ++ "%08lx (%08x vs %08x)\n", addr, calc, *val); ++ ++ S3C_PMDBG("Restore CRC error at %08lx (%08x vs %08x)\n", ++ addr, calc, *val); ++ } ++ ++ skip_check: ++ val++; ++ } ++ ++ return val; ++} ++ ++/** ++ * s3c_pm_check_restore() - memory check called on resume ++ * ++ * check the CRCs after the restore event and free the memory used ++ * to hold them ++*/ ++void s3c_pm_check_restore(void) ++{ ++ if (crcs != NULL) ++ s3c_pm_run_sysram(s3c_pm_runcheck, crcs); ++} ++ ++/** ++ * s3c_pm_check_cleanup() - free memory resources ++ * ++ * Free the resources that where allocated by the suspend ++ * memory check code. We do this separately from the ++ * s3c_pm_check_restore() function as we cannot call any ++ * functions that might sleep during that resume. ++ */ ++void s3c_pm_check_cleanup(void) ++{ ++ kfree(crcs); ++ crcs = NULL; ++} ++ +diff -ruN --exclude='*.orig' --exclude='*.rej' linux-2.6.29-rc3.owrt/arch/arm/plat-s3c/pm-gpio.c linux-2.6.29-rc3.owrt.om/arch/arm/plat-s3c/pm-gpio.c +--- linux-2.6.29-rc3.owrt/arch/arm/plat-s3c/pm-gpio.c 1970-01-01 01:00:00.000000000 +0100 ++++ linux-2.6.29-rc3.owrt.om/arch/arm/plat-s3c/pm-gpio.c 2009-05-10 22:27:59.000000000 +0200 +@@ -0,0 +1,378 @@ ++/* linux/arch/arm/plat-s3c/pm-gpio.c ++ * ++ * Copyright 2008 Openmoko, Inc. ++ * Copyright 2008 Simtec Electronics ++ * Ben Dooks <ben@simtec.co.uk> ++ * http://armlinux.simtec.co.uk/ ++ * ++ * S3C series GPIO PM code ++ * ++ * 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/io.h> ++#include <linux/gpio.h> ++ ++#include <mach/gpio-core.h> ++#include <plat/pm.h> ++ ++/* PM GPIO helpers */ ++ ++#define OFFS_CON (0x00) ++#define OFFS_DAT (0X04) ++#define OFFS_UP (0X08) ++ ++static void s3c_gpio_pm_1bit_save(struct s3c_gpio_chip *chip) ++{ ++ chip->pm_save[0] = __raw_readl(chip->base + OFFS_CON); ++ chip->pm_save[1] = __raw_readl(chip->base + OFFS_DAT); ++} ++ ++static void s3c_gpio_pm_1bit_resume(struct s3c_gpio_chip *chip) ++{ ++ void __iomem *base = chip->base; ++ u32 old_gpcon = __raw_readl(base + OFFS_CON); ++ u32 old_gpdat = __raw_readl(base + OFFS_DAT); ++ u32 gps_gpcon = chip->pm_save[0]; ++ u32 gps_gpdat = chip->pm_save[1]; ++ u32 gpcon; ++ ++ /* GPACON only has one bit per control / data and no PULLUPs. ++ * GPACON[x] = 0 => Output, 1 => SFN */ ++ ++ /* first set all SFN bits to SFN */ ++ ++ gpcon = old_gpcon | gps_gpcon; ++ __raw_writel(gpcon, base + OFFS_CON); ++ ++ /* now set all the other bits */ ++ ++ __raw_writel(gps_gpdat, base + OFFS_DAT); ++ __raw_writel(gps_gpcon, base + OFFS_CON); ++ ++ S3C_PMDBG("%s: CON %08x => %08x, DAT %08x => %08x\n", ++ chip->chip.label, old_gpcon, gps_gpcon, old_gpdat, gps_gpdat); ++} ++ ++struct s3c_gpio_pm s3c_gpio_pm_1bit = { ++ .save = s3c_gpio_pm_1bit_save, ++ .resume = s3c_gpio_pm_1bit_resume, ++}; ++ ++static void s3c_gpio_pm_2bit_save(struct s3c_gpio_chip *chip) ++{ ++ chip->pm_save[0] = __raw_readl(chip->base + OFFS_CON); ++ chip->pm_save[1] = __raw_readl(chip->base + OFFS_DAT); ++ chip->pm_save[2] = __raw_readl(chip->base + OFFS_UP); ++} ++ ++/* Test whether the given masked+shifted bits of an GPIO configuration ++ * are one of the SFN (special function) modes. */ ++ ++static inline int is_sfn(unsigned long con) ++{ ++ return con >= 2; ++} ++ ++/* Test if the given masked+shifted GPIO configuration is an input */ ++ ++static inline int is_in(unsigned long con) ++{ ++ return con == 0; ++} ++ ++/* Test if the given masked+shifted GPIO configuration is an output */ ++ ++static inline int is_out(unsigned long con) ++{ ++ return con == 1; ++} ++ ++/** ++ * s3c_gpio_pm_2bit_resume() - restore the given GPIO bank ++ * @chip: The chip information to resume. ++ * ++ * Restore one of the GPIO banks that was saved during suspend. This is ++ * not as simple as once thought, due to the possibility of glitches ++ * from the order that the CON and DAT registers are set in. ++ * ++ * The three states the pin can be are {IN,OUT,SFN} which gives us 9 ++ * combinations of changes to check. Three of these, if the pin stays ++ * in the same configuration can be discounted. This leaves us with ++ * the following: ++ * ++ * { IN => OUT } Change DAT first ++ * { IN => SFN } Change CON first ++ * { OUT => SFN } Change CON first, so new data will not glitch ++ * { OUT => IN } Change CON first, so new data will not glitch ++ * { SFN => IN } Change CON first ++ * { SFN => OUT } Change DAT first, so new data will not glitch [1] ++ * ++ * We do not currently deal with the UP registers as these control ++ * weak resistors, so a small delay in change should not need to bring ++ * these into the calculations. ++ * ++ * [1] this assumes that writing to a pin DAT whilst in SFN will set the ++ * state for when it is next output. ++ */ ++static void s3c_gpio_pm_2bit_resume(struct s3c_gpio_chip *chip) ++{ ++ void __iomem *base = chip->base; ++ u32 old_gpcon = __raw_readl(base + OFFS_CON); ++ u32 old_gpdat = __raw_readl(base + OFFS_DAT); ++ u32 gps_gpcon = chip->pm_save[0]; ++ u32 gps_gpdat = chip->pm_save[1]; ++ u32 gpcon, old, new, mask; ++ u32 change_mask = 0x0; ++ int nr; ++ ++ /* restore GPIO pull-up settings */ ++ __raw_writel(chip->pm_save[2], base + OFFS_UP); ++ ++ /* Create a change_mask of all the items that need to have ++ * their CON value changed before their DAT value, so that ++ * we minimise the work between the two settings. ++ */ ++ ++ for (nr = 0, mask = 0x03; nr < 32; nr += 2, mask <<= 2) { ++ old = (old_gpcon & mask) >> nr; ++ new = (gps_gpcon & mask) >> nr; ++ ++ /* If there is no change, then skip */ ++ ++ if (old == new) ++ continue; ++ ++ /* If both are special function, then skip */ ++ ++ if (is_sfn(old) && is_sfn(new)) ++ continue; ++ ++ /* Change is IN => OUT, do not change now */ ++ ++ if (is_in(old) && is_out(new)) ++ continue; ++ ++ /* Change is SFN => OUT, do not change now */ ++ ++ if (is_sfn(old) && is_out(new)) ++ continue; ++ ++ /* We should now be at the case of IN=>SFN, ++ * OUT=>SFN, OUT=>IN, SFN=>IN. */ ++ ++ change_mask |= mask; ++ } ++ ++ ++ /* Write the new CON settings */ ++ ++ gpcon = old_gpcon & ~change_mask; ++ gpcon |= gps_gpcon & change_mask; ++ ++ __raw_writel(gpcon, base + OFFS_CON); ++ ++ /* Now change any items that require DAT,CON */ ++ ++ __raw_writel(gps_gpdat, base + OFFS_DAT); ++ __raw_writel(gps_gpcon, base + OFFS_CON); ++ ++ S3C_PMDBG("%s: CON %08x => %08x, DAT %08x => %08x\n", ++ chip->chip.label, old_gpcon, gps_gpcon, old_gpdat, gps_gpdat); ++} ++ ++struct s3c_gpio_pm s3c_gpio_pm_2bit = { ++ .save = s3c_gpio_pm_2bit_save, ++ .resume = s3c_gpio_pm_2bit_resume, ++}; ++ ++#ifdef CONFIG_ARCH_S3C64XX ++static void s3c_gpio_pm_4bit_save(struct s3c_gpio_chip *chip) ++{ ++ chip->pm_save[1] = __raw_readl(chip->base + OFFS_CON); ++ chip->pm_save[2] = __raw_readl(chip->base + OFFS_DAT); ++ chip->pm_save[3] = __raw_readl(chip->base + OFFS_UP); ++ ++ if (chip->chip.ngpio > 8) ++ chip->pm_save[0] = __raw_readl(chip->base - 4); ++} ++ ++static u32 s3c_gpio_pm_4bit_mask(u32 old_gpcon, u32 gps_gpcon) ++{ ++ u32 old, new, mask; ++ u32 change_mask = 0x0; ++ int nr; ++ ++ for (nr = 0, mask = 0x0f; nr < 16; nr += 4, mask <<= 4) { ++ old = (old_gpcon & mask) >> nr; ++ new = (gps_gpcon & mask) >> nr; ++ ++ /* If there is no change, then skip */ ++ ++ if (old == new) ++ continue; ++ ++ /* If both are special function, then skip */ ++ ++ if (is_sfn(old) && is_sfn(new)) ++ continue; ++ ++ /* Change is IN => OUT, do not change now */ ++ ++ if (is_in(old) && is_out(new)) ++ continue; ++ ++ /* Change is SFN => OUT, do not change now */ ++ ++ if (is_sfn(old) && is_out(new)) ++ continue; ++ ++ /* We should now be at the case of IN=>SFN, ++ * OUT=>SFN, OUT=>IN, SFN=>IN. */ ++ ++ change_mask |= mask; ++ } ++ ++ return change_mask; ++} ++ ++static void s3c_gpio_pm_4bit_con(struct s3c_gpio_chip *chip, int index) ++{ ++ void __iomem *con = chip->base + (index * 4); ++ u32 old_gpcon = __raw_readl(con); ++ u32 gps_gpcon = chip->pm_save[index + 1]; ++ u32 gpcon, mask; ++ ++ mask = s3c_gpio_pm_4bit_mask(old_gpcon, gps_gpcon); ++ ++ gpcon = old_gpcon & ~mask; ++ gpcon |= gps_gpcon & mask; ++ ++ __raw_writel(gpcon, con); ++} ++ ++static void s3c_gpio_pm_4bit_resume(struct s3c_gpio_chip *chip) ++{ ++ void __iomem *base = chip->base; ++ u32 old_gpcon[2]; ++ u32 old_gpdat = __raw_readl(base + OFFS_DAT); ++ u32 gps_gpdat = chip->pm_save[2]; ++ ++ /* First, modify the CON settings */ ++ ++ old_gpcon[0] = 0; ++ old_gpcon[1] = __raw_readl(base + OFFS_CON); ++ ++ s3c_gpio_pm_4bit_con(chip, 0); ++ if (chip->chip.ngpio > 8) { ++ old_gpcon[0] = __raw_readl(base - 4); ++ s3c_gpio_pm_4bit_con(chip, -1); ++ } ++ ++ /* Now change the configurations that require DAT,CON */ ++ ++ __raw_writel(chip->pm_save[2], base + OFFS_DAT); ++ __raw_writel(chip->pm_save[1], base + OFFS_CON); ++ if (chip->chip.ngpio > 8) ++ __raw_writel(chip->pm_save[0], base - 4); ++ ++ __raw_writel(chip->pm_save[2], base + OFFS_DAT); ++ __raw_writel(chip->pm_save[3], base + OFFS_UP); ++ ++ if (chip->chip.ngpio > 8) { ++ S3C_PMDBG("%s: CON4 %08x,%08x => %08x,%08x, DAT %08x => %08x\n", ++ chip->chip.label, old_gpcon[0], old_gpcon[1], ++ __raw_readl(base - 4), ++ __raw_readl(base + OFFS_CON), ++ old_gpdat, gps_gpdat); ++ } else ++ S3C_PMDBG("%s: CON4 %08x => %08x, DAT %08x => %08x\n", ++ chip->chip.label, old_gpcon[1], ++ __raw_readl(base + OFFS_CON), ++ old_gpdat, gps_gpdat); ++} ++ ++struct s3c_gpio_pm s3c_gpio_pm_4bit = { ++ .save = s3c_gpio_pm_4bit_save, ++ .resume = s3c_gpio_pm_4bit_resume, ++}; ++#endif /* CONFIG_ARCH_S3C64XX */ ++ ++/** ++ * s3c_pm_save_gpio() - save gpio chip data for suspend ++ * @ourchip: The chip for suspend. ++ */ ++static void s3c_pm_save_gpio(struct s3c_gpio_chip *ourchip) ++{ ++ struct s3c_gpio_pm *pm = ourchip->pm; ++ ++ if (pm == NULL || pm->save == NULL) ++ S3C_PMDBG("%s: no pm for %s\n", __func__, ourchip->chip.label); ++ else ++ pm->save(ourchip); ++} ++ ++/** ++ * s3c_pm_save_gpios() - Save the state of the GPIO banks. ++ * ++ * For all the GPIO banks, save the state of each one ready for going ++ * into a suspend mode. ++ */ ++void s3c_pm_save_gpios(void) ++{ ++ struct s3c_gpio_chip *ourchip; ++ unsigned int gpio_nr; ++ ++ for (gpio_nr = 0; gpio_nr < S3C_GPIO_END; gpio_nr++) { ++ ourchip = s3c_gpiolib_getchip(gpio_nr); ++ if (!ourchip) ++ continue; ++ ++ s3c_pm_save_gpio(ourchip); ++ ++ S3C_PMDBG("%s: save %08x,%08x,%08x,%08x\n", ++ ourchip->chip.label, ++ ourchip->pm_save[0], ++ ourchip->pm_save[1], ++ ourchip->pm_save[2], ++ ourchip->pm_save[3]); ++ ++ gpio_nr += ourchip->chip.ngpio; ++ gpio_nr += CONFIG_S3C_GPIO_SPACE; ++ } ++} ++ ++/** ++ * s3c_pm_resume_gpio() - restore gpio chip data after suspend ++ * @ourchip: The suspended chip. ++ */ ++static void s3c_pm_resume_gpio(struct s3c_gpio_chip *ourchip) ++{ ++ struct s3c_gpio_pm *pm = ourchip->pm; ++ ++ if (pm == NULL || pm->resume == NULL) ++ S3C_PMDBG("%s: no pm for %s\n", __func__, ourchip->chip.label); ++ else ++ pm->resume(ourchip); ++} ++ ++void s3c_pm_restore_gpios(void) ++{ ++ struct s3c_gpio_chip *ourchip; ++ unsigned int gpio_nr; ++ ++ for (gpio_nr = 0; gpio_nr < S3C_GPIO_END; gpio_nr++) { ++ ourchip = s3c_gpiolib_getchip(gpio_nr); ++ if (!ourchip) ++ continue; ++ ++ s3c_pm_resume_gpio(ourchip); ++ ++ gpio_nr += ourchip->chip.ngpio; ++ gpio_nr += CONFIG_S3C_GPIO_SPACE; ++ } ++} +diff -ruN --exclude='*.orig' --exclude='*.rej' linux-2.6.29-rc3.owrt/arch/arm/plat-s3c/pwm.c linux-2.6.29-rc3.owrt.om/arch/arm/plat-s3c/pwm.c +--- linux-2.6.29-rc3.owrt/arch/arm/plat-s3c/pwm.c 1970-01-01 01:00:00.000000000 +0100 ++++ linux-2.6.29-rc3.owrt.om/arch/arm/plat-s3c/pwm.c 2009-05-10 22:27:59.000000000 +0200 +@@ -0,0 +1,288 @@ ++/* ++ * arch/arm/plat-s3c/pwm.c ++ * ++ * Copyright (c) by Javi Roman <javiroman@kernel-labs.org> ++ * for the Openmoko Project. ++ * ++ * S3C2410A SoC PWM support ++ * ++ * 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. ++ * ++ * 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, MA 02111-1307 USA ++ * ++ */ ++ ++#include <linux/kernel.h> ++#include <linux/init.h> ++#include <linux/clk.h> ++#include <linux/device.h> ++#include <mach/hardware.h> ++#include <plat/regs-timer.h> ++#include <plat/pwm.h> ++#include <asm/io.h> ++ ++#ifdef CONFIG_PM ++ static unsigned long standby_reg_tcon; ++ static unsigned long standby_reg_tcfg0; ++ static unsigned long standby_reg_tcfg1; ++#endif ++ ++int s3c2410_pwm_disable(struct s3c2410_pwm *pwm) ++{ ++ unsigned long tcon; ++ ++ /* stop timer */ ++ tcon = __raw_readl(S3C2410_TCON); ++ tcon &= 0xffffff00; ++ __raw_writel(tcon, S3C2410_TCON); ++ ++ clk_disable(pwm->pclk); ++ clk_put(pwm->pclk); ++ ++ return 0; ++} ++EXPORT_SYMBOL_GPL(s3c2410_pwm_disable); ++ ++int s3c2410_pwm_init(struct s3c2410_pwm *pwm) ++{ ++ pwm->pclk = clk_get(NULL, "timers"); ++ if (IS_ERR(pwm->pclk)) ++ return PTR_ERR(pwm->pclk); ++ ++ clk_enable(pwm->pclk); ++ pwm->pclk_rate = clk_get_rate(pwm->pclk); ++ return 0; ++} ++EXPORT_SYMBOL_GPL(s3c2410_pwm_init); ++ ++int s3c2410_pwm_enable(struct s3c2410_pwm *pwm) ++{ ++ unsigned long tcfg0, tcfg1, tcnt, tcmp; ++ ++ /* control registers bits */ ++ tcfg1 = __raw_readl(S3C2410_TCFG1); ++ tcfg0 = __raw_readl(S3C2410_TCFG0); ++ ++ /* divider & scaler slection */ ++ switch (pwm->timerid) { ++ case PWM0: ++ tcfg1 &= ~S3C2410_TCFG1_MUX0_MASK; ++ tcfg0 &= ~S3C2410_TCFG_PRESCALER0_MASK; ++ break; ++ case PWM1: ++ tcfg1 &= ~S3C2410_TCFG1_MUX1_MASK; ++ tcfg0 &= ~S3C2410_TCFG_PRESCALER0_MASK; ++ break; ++ case PWM2: ++ tcfg1 &= ~S3C2410_TCFG1_MUX2_MASK; ++ tcfg0 &= ~S3C2410_TCFG_PRESCALER1_MASK; ++ break; ++ case PWM3: ++ tcfg1 &= ~S3C2410_TCFG1_MUX3_MASK; ++ tcfg0 &= ~S3C2410_TCFG_PRESCALER1_MASK; ++ break; ++ case PWM4: ++ /* timer four is not capable of doing PWM */ ++ break; ++ default: ++ clk_disable(pwm->pclk); ++ clk_put(pwm->pclk); ++ return -1; ++ } ++ ++ /* divider & scaler values */ ++ tcfg1 |= pwm->divider; ++ __raw_writel(tcfg1, S3C2410_TCFG1); ++ ++ switch (pwm->timerid) { ++ case PWM0: ++ case PWM1: ++ tcfg0 |= pwm->prescaler; ++ __raw_writel(tcfg0, S3C2410_TCFG0); ++ break; ++ default: ++ if ((tcfg0 | pwm->prescaler) != tcfg0) { ++ printk(KERN_WARNING "not changing prescaler of PWM %u," ++ " since it's shared with timer4 (clock tick)\n", ++ pwm->timerid); ++ } ++ break; ++ } ++ ++ /* timer count and compare buffer initial values */ ++ tcnt = pwm->counter; ++ tcmp = pwm->comparer; ++ ++ __raw_writel(tcnt, S3C2410_TCNTB(pwm->timerid)); ++ __raw_writel(tcmp, S3C2410_TCMPB(pwm->timerid)); ++ ++ /* ensure timer is stopped */ ++ s3c2410_pwm_stop(pwm); ++ ++ return 0; ++} ++EXPORT_SYMBOL_GPL(s3c2410_pwm_enable); ++ ++int s3c2410_pwm_start(struct s3c2410_pwm *pwm) ++{ ++ unsigned long tcon; ++ ++ tcon = __raw_readl(S3C2410_TCON); ++ ++ switch (pwm->timerid) { ++ case PWM0: ++ tcon |= S3C2410_TCON_T0START; ++ tcon &= ~S3C2410_TCON_T0MANUALUPD; ++ break; ++ case PWM1: ++ tcon |= S3C2410_TCON_T1START; ++ tcon &= ~S3C2410_TCON_T1MANUALUPD; ++ break; ++ case PWM2: ++ tcon |= S3C2410_TCON_T2START; ++ tcon &= ~S3C2410_TCON_T2MANUALUPD; ++ break; ++ case PWM3: ++ tcon |= S3C2410_TCON_T3START; ++ tcon &= ~S3C2410_TCON_T3MANUALUPD; ++ break; ++ case PWM4: ++ /* timer four is not capable of doing PWM */ ++ default: ++ return -ENODEV; ++ } ++ ++ __raw_writel(tcon, S3C2410_TCON); ++ ++ return 0; ++} ++EXPORT_SYMBOL_GPL(s3c2410_pwm_start); ++ ++int s3c2410_pwm_stop(struct s3c2410_pwm *pwm) ++{ ++ unsigned long tcon; ++ ++ tcon = __raw_readl(S3C2410_TCON); ++ ++ switch (pwm->timerid) { ++ case PWM0: ++ tcon &= ~0x00000000; ++ tcon |= S3C2410_TCON_T0RELOAD; ++ tcon |= S3C2410_TCON_T0MANUALUPD; ++ break; ++ case PWM1: ++ tcon &= ~0x00000080; ++ tcon |= S3C2410_TCON_T1RELOAD; ++ tcon |= S3C2410_TCON_T1MANUALUPD; ++ break; ++ case PWM2: ++ tcon &= ~0x00000800; ++ tcon |= S3C2410_TCON_T2RELOAD; ++ tcon |= S3C2410_TCON_T2MANUALUPD; ++ break; ++ case PWM3: ++ tcon &= ~0x00008000; ++ tcon |= S3C2410_TCON_T3RELOAD; ++ tcon |= S3C2410_TCON_T3MANUALUPD; ++ break; ++ case PWM4: ++ /* timer four is not capable of doing PWM */ ++ default: ++ return -ENODEV; ++ } ++ ++ __raw_writel(tcon, S3C2410_TCON); ++ ++ return 0; ++} ++EXPORT_SYMBOL_GPL(s3c2410_pwm_stop); ++ ++int s3c2410_pwm_duty_cycle(int reg_value, struct s3c2410_pwm *pwm) ++{ ++ __raw_writel(reg_value, S3C2410_TCMPB(pwm->timerid)); ++ ++ return 0; ++} ++EXPORT_SYMBOL_GPL(s3c2410_pwm_duty_cycle); ++ ++int s3c2410_pwm_dumpregs(void) ++{ ++ printk(KERN_INFO "TCON: %08lx, TCFG0: %08lx, TCFG1: %08lx\n", ++ (unsigned long) __raw_readl(S3C2410_TCON), ++ (unsigned long) __raw_readl(S3C2410_TCFG0), ++ (unsigned long) __raw_readl(S3C2410_TCFG1)); ++ ++ return 0; ++} ++EXPORT_SYMBOL_GPL(s3c2410_pwm_dumpregs); ++ ++static int __init s3c24xx_pwm_probe(struct platform_device *pdev) ++{ ++ struct s3c24xx_pwm_platform_data *pdata = pdev->dev.platform_data; ++ ++ dev_info(&pdev->dev, "s3c24xx_pwm is registered \n"); ++ ++ /* if platform was interested, give him a chance to register ++ * platform devices that switch power with us as the parent ++ * at registration time -- ensures suspend / resume ordering ++ */ ++ if (pdata) ++ if (pdata->attach_child_devices) ++ (pdata->attach_child_devices)(&pdev->dev); ++ ++ return 0; ++} ++ ++#ifdef CONFIG_PM ++static int s3c24xx_pwm_suspend(struct platform_device *pdev, pm_message_t state) ++{ ++ /* PWM config should be kept in suspending */ ++ standby_reg_tcon = __raw_readl(S3C2410_TCON); ++ standby_reg_tcfg0 = __raw_readl(S3C2410_TCFG0); ++ standby_reg_tcfg1 = __raw_readl(S3C2410_TCFG1); ++ ++ return 0; ++} ++ ++static int s3c24xx_pwm_resume(struct platform_device *pdev) ++{ ++ __raw_writel(standby_reg_tcon, S3C2410_TCON); ++ __raw_writel(standby_reg_tcfg0, S3C2410_TCFG0); ++ __raw_writel(standby_reg_tcfg1, S3C2410_TCFG1); ++ ++ return 0; ++} ++#else ++#define s3c24xx_pwm_suspend NULL ++#define s3c24xx_pwm_resume NULL ++#endif ++ ++static struct platform_driver s3c24xx_pwm_driver = { ++ .driver = { ++ .name = "s3c24xx_pwm", ++ .owner = THIS_MODULE, ++ }, ++ .probe = s3c24xx_pwm_probe, ++ .suspend = s3c24xx_pwm_suspend, ++ .resume = s3c24xx_pwm_resume, ++}; ++ ++static int __init s3c24xx_pwm_init(void) ++{ ++ return platform_driver_register(&s3c24xx_pwm_driver); ++} ++ ++static void __exit s3c24xx_pwm_exit(void) ++{ ++} ++ ++MODULE_AUTHOR("Javi Roman <javiroman@kernel-labs.org>"); ++MODULE_LICENSE("GPL"); ++ ++module_init(s3c24xx_pwm_init); ++module_exit(s3c24xx_pwm_exit); +diff -ruN --exclude='*.orig' --exclude='*.rej' linux-2.6.29-rc3.owrt/arch/arm/plat-s3c/time.c linux-2.6.29-rc3.owrt.om/arch/arm/plat-s3c/time.c +--- linux-2.6.29-rc3.owrt/arch/arm/plat-s3c/time.c 2009-05-10 22:05:04.000000000 +0200 ++++ linux-2.6.29-rc3.owrt.om/arch/arm/plat-s3c/time.c 2009-05-10 22:27:59.000000000 +0200 +@@ -97,7 +97,7 @@ + * IRQs are disabled before entering here from do_gettimeofday() + */ + +-static unsigned long s3c2410_gettimeoffset (void) ++unsigned long s3c2410_gettimeoffset (void) + { + unsigned long tdone; + unsigned long tval; +diff -ruN --exclude='*.orig' --exclude='*.rej' linux-2.6.29-rc3.owrt/arch/arm/plat-s3c24xx/clock-dclk.c linux-2.6.29-rc3.owrt.om/arch/arm/plat-s3c24xx/clock-dclk.c +--- linux-2.6.29-rc3.owrt/arch/arm/plat-s3c24xx/clock-dclk.c 2009-05-10 22:05:03.000000000 +0200 ++++ linux-2.6.29-rc3.owrt.om/arch/arm/plat-s3c24xx/clock-dclk.c 2009-05-10 22:27:59.000000000 +0200 +@@ -18,6 +18,7 @@ + + #include <mach/regs-clock.h> + #include <mach/regs-gpio.h> ++#include <mach/hardware.h> + + #include <plat/clock.h> + #include <plat/cpu.h> +diff -ruN --exclude='*.orig' --exclude='*.rej' linux-2.6.29-rc3.owrt/arch/arm/plat-s3c24xx/common-smdk.c linux-2.6.29-rc3.owrt.om/arch/arm/plat-s3c24xx/common-smdk.c +--- linux-2.6.29-rc3.owrt/arch/arm/plat-s3c24xx/common-smdk.c 2009-05-10 22:05:03.000000000 +0200 ++++ linux-2.6.29-rc3.owrt.om/arch/arm/plat-s3c24xx/common-smdk.c 2009-05-10 22:27:59.000000000 +0200 +@@ -201,5 +201,5 @@ + + platform_add_devices(smdk_devs, ARRAY_SIZE(smdk_devs)); + +- s3c2410_pm_init(); ++ s3c_pm_init(); + } +diff -ruN --exclude='*.orig' --exclude='*.rej' linux-2.6.29-rc3.owrt/arch/arm/plat-s3c24xx/cpu.c linux-2.6.29-rc3.owrt.om/arch/arm/plat-s3c24xx/cpu.c +--- linux-2.6.29-rc3.owrt/arch/arm/plat-s3c24xx/cpu.c 2009-05-10 22:05:03.000000000 +0200 ++++ linux-2.6.29-rc3.owrt.om/arch/arm/plat-s3c24xx/cpu.c 2009-05-10 22:27:59.000000000 +0200 +@@ -61,6 +61,7 @@ + static const char name_s3c2412[] = "S3C2412"; + static const char name_s3c2440[] = "S3C2440"; + static const char name_s3c2442[] = "S3C2442"; ++static const char name_s3c2442b[] = "S3C2442B"; + static const char name_s3c2443[] = "S3C2443"; + static const char name_s3c2410a[] = "S3C2410A"; + static const char name_s3c2440a[] = "S3C2440A"; +@@ -112,6 +113,15 @@ + .name = name_s3c2442 + }, + { ++ .idcode = 0x32440aab, ++ .idmask = 0xffffffff, ++ .map_io = s3c244x_map_io, ++ .init_clocks = s3c244x_init_clocks, ++ .init_uarts = s3c244x_init_uarts, ++ .init = s3c2442_init, ++ .name = name_s3c2442b ++ }, ++ { + .idcode = 0x32412001, + .idmask = 0xffffffff, + .map_io = s3c2412_map_io, +diff -ruN --exclude='*.orig' --exclude='*.rej' linux-2.6.29-rc3.owrt/arch/arm/plat-s3c24xx/devs.c linux-2.6.29-rc3.owrt.om/arch/arm/plat-s3c24xx/devs.c +--- linux-2.6.29-rc3.owrt/arch/arm/plat-s3c24xx/devs.c 2009-05-10 22:05:03.000000000 +0200 ++++ linux-2.6.29-rc3.owrt.om/arch/arm/plat-s3c24xx/devs.c 2009-05-10 22:27:59.000000000 +0200 +@@ -26,6 +26,8 @@ + #include <asm/mach/irq.h> + #include <mach/fb.h> + #include <mach/hardware.h> ++#include <mach/ts.h> ++#include <asm/io.h> + #include <asm/irq.h> + + #include <plat/regs-serial.h> +@@ -136,36 +138,6 @@ + struct platform_device *s3c24xx_uart_devs[4] = { + }; + +-/* USB Host Controller */ +- +-static struct resource s3c_usb_resource[] = { +- [0] = { +- .start = S3C24XX_PA_USBHOST, +- .end = S3C24XX_PA_USBHOST + S3C24XX_SZ_USBHOST - 1, +- .flags = IORESOURCE_MEM, +- }, +- [1] = { +- .start = IRQ_USBH, +- .end = IRQ_USBH, +- .flags = IORESOURCE_IRQ, +- } +-}; +- +-static u64 s3c_device_usb_dmamask = 0xffffffffUL; +- +-struct platform_device s3c_device_usb = { +- .name = "s3c2410-ohci", +- .id = -1, +- .num_resources = ARRAY_SIZE(s3c_usb_resource), +- .resource = s3c_usb_resource, +- .dev = { +- .dma_mask = &s3c_device_usb_dmamask, +- .coherent_dma_mask = 0xffffffffUL +- } +-}; +- +-EXPORT_SYMBOL(s3c_device_usb); +- + /* LCD Controller */ + + static struct resource s3c_lcd_resource[] = { +@@ -229,6 +201,24 @@ + + EXPORT_SYMBOL(s3c_device_nand); + ++/* Touchscreen */ ++struct platform_device s3c_device_ts = { ++ .name = "s3c2410-ts", ++ .id = -1, ++}; ++ ++EXPORT_SYMBOL(s3c_device_ts); ++ ++static struct s3c2410_ts_mach_info s3c2410ts_info; ++ ++void set_s3c2410ts_info(const struct s3c2410_ts_mach_info *hard_s3c2410ts_info) ++{ ++ memcpy(&s3c2410ts_info, hard_s3c2410ts_info, ++ sizeof(struct s3c2410_ts_mach_info)); ++ s3c_device_ts.dev.platform_data = &s3c2410ts_info; ++} ++EXPORT_SYMBOL(set_s3c2410ts_info); ++ + /* USB Device (Gadget)*/ + + static struct resource s3c_usbgadget_resource[] = { +diff -ruN --exclude='*.orig' --exclude='*.rej' linux-2.6.29-rc3.owrt/arch/arm/plat-s3c24xx/dma.c linux-2.6.29-rc3.owrt.om/arch/arm/plat-s3c24xx/dma.c +--- linux-2.6.29-rc3.owrt/arch/arm/plat-s3c24xx/dma.c 2009-05-10 22:05:03.000000000 +0200 ++++ linux-2.6.29-rc3.owrt.om/arch/arm/plat-s3c24xx/dma.c 2009-05-10 22:27:59.000000000 +0200 +@@ -31,10 +31,11 @@ + #include <asm/irq.h> + #include <mach/hardware.h> + #include <mach/dma.h> +- + #include <mach/map.h> + +-#include <plat/dma.h> ++#include <plat/dma-core.h> ++#include <plat/regs-dma.h> ++#include <plat/dma-plat.h> + + /* io map for dma */ + static void __iomem *dma_base; +@@ -44,8 +45,6 @@ + + static struct s3c24xx_dma_selection dma_sel; + +-/* dma channel state information */ +-struct s3c2410_dma_chan s3c2410_chans[S3C2410_DMA_CHANNELS]; + + /* debugging functions */ + +@@ -135,21 +134,6 @@ + #define dbg_showchan(chan) do { } while(0) + #endif /* CONFIG_S3C2410_DMA_DEBUG */ + +-static struct s3c2410_dma_chan *dma_chan_map[DMACH_MAX]; +- +-/* lookup_dma_channel +- * +- * change the dma channel number given into a real dma channel id +-*/ +- +-static struct s3c2410_dma_chan *lookup_dma_channel(unsigned int channel) +-{ +- if (channel & DMACH_LOW_LEVEL) +- return &s3c2410_chans[channel & ~DMACH_LOW_LEVEL]; +- else +- return dma_chan_map[channel]; +-} +- + /* s3c2410_dma_stats_timeout + * + * Update DMA stats from timeout info +@@ -214,8 +198,6 @@ + return 0; + } + +- +- + /* s3c2410_dma_loadbuffer + * + * load a buffer, and update the channel state +@@ -453,7 +435,7 @@ + int s3c2410_dma_enqueue(unsigned int channel, void *id, + dma_addr_t data, int size) + { +- struct s3c2410_dma_chan *chan = lookup_dma_channel(channel); ++ struct s3c2410_dma_chan *chan = s3c_dma_lookup_channel(channel); + struct s3c2410_dma_buf *buf; + unsigned long flags; + +@@ -804,7 +786,7 @@ + + int s3c2410_dma_free(unsigned int channel, struct s3c2410_dma_client *client) + { +- struct s3c2410_dma_chan *chan = lookup_dma_channel(channel); ++ struct s3c2410_dma_chan *chan = s3c_dma_lookup_channel(channel); + unsigned long flags; + + if (chan == NULL) +@@ -836,7 +818,7 @@ + chan->irq_claimed = 0; + + if (!(channel & DMACH_LOW_LEVEL)) +- dma_chan_map[channel] = NULL; ++ s3c_dma_chan_map[channel] = NULL; + + local_irq_restore(flags); + +@@ -995,7 +977,7 @@ + int + s3c2410_dma_ctrl(unsigned int channel, enum s3c2410_chan_op op) + { +- struct s3c2410_dma_chan *chan = lookup_dma_channel(channel); ++ struct s3c2410_dma_chan *chan = s3c_dma_lookup_channel(channel); + + if (chan == NULL) + return -EINVAL; +@@ -1038,14 +1020,13 @@ + /* s3c2410_dma_config + * + * xfersize: size of unit in bytes (1,2,4) +- * dcon: base value of the DCONx register + */ + + int s3c2410_dma_config(unsigned int channel, +- int xferunit, +- int dcon) ++ int xferunit) + { +- struct s3c2410_dma_chan *chan = lookup_dma_channel(channel); ++ struct s3c2410_dma_chan *chan = s3c_dma_lookup_channel(channel); ++ unsigned int dcon; + + pr_debug("%s: chan=%d, xfer_unit=%d, dcon=%08x\n", + __func__, channel, xferunit, dcon); +@@ -1055,10 +1036,33 @@ + + pr_debug("%s: Initial dcon is %08x\n", __func__, dcon); + +- dcon |= chan->dcon & dma_sel.dcon_mask; ++ dcon = chan->dcon & dma_sel.dcon_mask; + + pr_debug("%s: New dcon is %08x\n", __func__, dcon); + ++ switch (chan->req_ch) { ++ case DMACH_I2S_IN: ++ case DMACH_I2S_OUT: ++ case DMACH_PCM_IN: ++ case DMACH_PCM_OUT: ++ case DMACH_MIC_IN: ++ default: ++ dcon |= S3C2410_DCON_HANDSHAKE; ++ dcon |= S3C2410_DCON_SYNC_PCLK; ++ break; ++ ++ case DMACH_SDI: ++ /* note, ensure if need HANDSHAKE or not */ ++ dcon |= S3C2410_DCON_SYNC_PCLK; ++ break; ++ ++ case DMACH_XD0: ++ case DMACH_XD1: ++ dcon |= S3C2410_DCON_HANDSHAKE; ++ dcon |= S3C2410_DCON_SYNC_HCLK; ++ break; ++ } ++ + switch (xferunit) { + case 1: + dcon |= S3C2410_DCON_BYTE; +@@ -1089,10 +1093,10 @@ + } + + EXPORT_SYMBOL(s3c2410_dma_config); +- ++#if 0 /* moved to plat-s3c? */ + int s3c2410_dma_setflags(unsigned int channel, unsigned int flags) + { +- struct s3c2410_dma_chan *chan = lookup_dma_channel(channel); ++ struct s3c2410_dma_chan *chan = s3c_dma_lookup_channel(channel); + + if (chan == NULL) + return -EINVAL; +@@ -1105,43 +1109,7 @@ + } + + EXPORT_SYMBOL(s3c2410_dma_setflags); +- +- +-/* do we need to protect the settings of the fields from +- * irq? +-*/ +- +-int s3c2410_dma_set_opfn(unsigned int channel, s3c2410_dma_opfn_t rtn) +-{ +- struct s3c2410_dma_chan *chan = lookup_dma_channel(channel); +- +- if (chan == NULL) +- return -EINVAL; +- +- pr_debug("%s: chan=%p, op rtn=%p\n", __func__, chan, rtn); +- +- chan->op_fn = rtn; +- +- return 0; +-} +- +-EXPORT_SYMBOL(s3c2410_dma_set_opfn); +- +-int s3c2410_dma_set_buffdone_fn(unsigned int channel, s3c2410_dma_cbfn_t rtn) +-{ +- struct s3c2410_dma_chan *chan = lookup_dma_channel(channel); +- +- if (chan == NULL) +- return -EINVAL; +- +- pr_debug("%s: chan=%p, callback rtn=%p\n", __func__, chan, rtn); +- +- chan->callback_fn = rtn; +- +- return 0; +-} +- +-EXPORT_SYMBOL(s3c2410_dma_set_buffdone_fn); ++#endif + + /* s3c2410_dma_devconfig + * +@@ -1150,29 +1118,38 @@ + * source: S3C2410_DMASRC_HW: source is hardware + * S3C2410_DMASRC_MEM: source is memory + * +- * hwcfg: the value for xxxSTCn register, +- * bit 0: 0=increment pointer, 1=leave pointer +- * bit 1: 0=source is AHB, 1=source is APB +- * + * devaddr: physical address of the source + */ + + int s3c2410_dma_devconfig(int channel, + enum s3c2410_dmasrc source, +- int hwcfg, + unsigned long devaddr) + { +- struct s3c2410_dma_chan *chan = lookup_dma_channel(channel); ++ struct s3c2410_dma_chan *chan = s3c_dma_lookup_channel(channel); ++ unsigned int hwcfg; + + if (chan == NULL) + return -EINVAL; + +- pr_debug("%s: source=%d, hwcfg=%08x, devaddr=%08lx\n", +- __func__, (int)source, hwcfg, devaddr); ++ pr_debug("%s: source=%d, devaddr=%08lx\n", ++ __func__, (int)source, devaddr); + + chan->source = source; + chan->dev_addr = devaddr; +- chan->hw_cfg = hwcfg; ++ ++ switch (chan->req_ch) { ++ case DMACH_XD0: ++ case DMACH_XD1: ++ hwcfg = 0; /* AHB */ ++ break; ++ ++ default: ++ hwcfg = S3C2410_DISRCC_APB; ++ } ++ ++ /* always assume our peripheral desintation is a fixed ++ * address in memory. */ ++ hwcfg |= S3C2410_DISRCC_INC; + + switch (source) { + case S3C2410_DMASRC_HW: +@@ -1219,7 +1196,7 @@ + + int s3c2410_dma_getposition(unsigned int channel, dma_addr_t *src, dma_addr_t *dst) + { +- struct s3c2410_dma_chan *chan = lookup_dma_channel(channel); ++ struct s3c2410_dma_chan *chan = s3c_dma_lookup_channel(channel); + + if (chan == NULL) + return -EINVAL; +@@ -1278,8 +1255,8 @@ + + printk(KERN_INFO "dma%d: restoring configuration\n", cp->number); + +- s3c2410_dma_config(no, cp->xfer_unit, cp->dcon); +- s3c2410_dma_devconfig(no, cp->source, cp->hw_cfg, cp->dev_addr); ++ s3c2410_dma_config(no, cp->xfer_unit); ++ s3c2410_dma_devconfig(no, cp->source, cp->dev_addr); + + /* re-select the dma source for this channel */ + +@@ -1476,7 +1453,8 @@ + found: + dmach = &s3c2410_chans[ch]; + dmach->map = ch_map; +- dma_chan_map[channel] = dmach; ++ dmach->req_ch = channel; ++ s3c_dma_chan_map[channel] = dmach; + + /* select the channel */ + +diff -ruN --exclude='*.orig' --exclude='*.rej' linux-2.6.29-rc3.owrt/arch/arm/plat-s3c24xx/gpio.c linux-2.6.29-rc3.owrt.om/arch/arm/plat-s3c24xx/gpio.c +--- linux-2.6.29-rc3.owrt/arch/arm/plat-s3c24xx/gpio.c 2009-05-10 22:05:03.000000000 +0200 ++++ linux-2.6.29-rc3.owrt.om/arch/arm/plat-s3c24xx/gpio.c 2009-05-10 22:27:59.000000000 +0200 +@@ -32,6 +32,7 @@ + #include <asm/irq.h> + + #include <mach/regs-gpio.h> ++#include <mach/regs-gpioj.h> + + void s3c2410_gpio_cfgpin(unsigned int pin, unsigned int function) + { +@@ -215,3 +216,423 @@ + } + + EXPORT_SYMBOL(s3c2410_gpio_irq2pin); ++ ++static void pretty_dump(u32 cfg, u32 state, u32 pull, ++ const char ** function_names_2, ++ const char ** function_names_3, ++ const char * prefix, ++ int count) ++{ ++ int n; ++ const char *tag_type = NULL, ++ *tag_state = NULL, ++ *tag_pulldown = NULL, ++ * level0 = "0", ++ * level1 = "1"; ++ ++ for (n = 0; n < count; n++) { ++ switch ((cfg >> (2 * n)) & 3) { ++ case 0: ++ tag_type = "input "; ++ break; ++ case 1: ++ tag_type = "OUTPUT "; ++ break; ++ case 2: ++ if (function_names_2) { ++ if (function_names_2[n]) ++ tag_type = function_names_2[n]; ++ else ++ tag_type = "*** ILLEGAL CFG (2) *** "; ++ } else ++ tag_type = "(function) "; ++ break; ++ default: ++ if (function_names_3) { ++ if (function_names_3[n]) ++ tag_type = function_names_3[n]; ++ else ++ tag_type = "*** ILLEGAL CFG (3) *** "; ++ } else ++ tag_type = "(function) "; ++ break; ++ } ++ if ((state >> n) & 1) ++ tag_state = level1; ++ else ++ tag_state = level0; ++ ++ if (((pull >> n) & 1)) ++ tag_pulldown = ""; ++ else ++ tag_pulldown = "(pulldown)"; ++ ++ printk(KERN_INFO"%s%02d: %s %s %s\n", prefix, n, tag_type, ++ tag_state, tag_pulldown); ++ } ++ printk(KERN_INFO"\n"); ++} ++ ++static void pretty_dump_a(u32 cfg, u32 state, ++ const char ** function_names, ++ const char * prefix, ++ int count) ++{ ++ int n; ++ const char *tag_type = NULL, ++ *tag_state = NULL, ++ * level0 = "0", ++ * level1 = "1"; ++ ++ for (n = 0; n < count; n++) { ++ switch ((cfg >> n) & 1) { ++ case 0: ++ tag_type = "OUTPUT "; ++ break; ++ default: ++ if (function_names) { ++ if (function_names[n]) ++ tag_type = function_names[n]; ++ else ++ tag_type = "*** ILLEGAL CFG *** "; ++ } else ++ tag_type = "(function) "; ++ break; ++ } ++ if ((state >> n) & 1) ++ tag_state = level1; ++ else ++ tag_state = level0; ++ ++ printk(KERN_INFO"%s%02d: %s %s\n", prefix, n, tag_type, ++ tag_state); ++ } ++ printk(KERN_INFO"\n"); ++} ++ ++static const char * funcs_a[] = { ++ "ADDR0 ", ++ "ADDR16 ", ++ "ADDR17 ", ++ "ADDR18 ", ++ "ADDR19 ", ++ "ADDR20 ", ++ "ADDR21 ", ++ "ADDR22 ", ++ "ADDR23 ", ++ "ADDR24 ", ++ "ADDR25 ", ++ "ADDR26 ", ++ "nGCS[1] ", ++ "nGCS[2] ", ++ "nGCS[3] ", ++ "nGCS[4] ", ++ "nGCS[5] ", ++ "CLE ", ++ "ALE ", ++ "nFWE ", ++ "nFRE ", ++ "nRSTOUT ", ++ "nFCE ", ++ NULL, ++ NULL ++}; ++ ++ ++static const char * funcs_b2[] = { ++ "TOUT0 ", ++ "TOUT1 ", ++ "TOUT2 ", ++ "TOUT3 ", ++ "TCLK[0] ", ++ "nXBACK ", ++ "nXBREQ ", ++ "nXDACK1 ", ++ "nXDREQ1 ", ++ "nXDACK0 ", ++ "nXDREQ0 ", ++}; ++static const char * funcs_b3[] = { ++ NULL, ++ NULL, ++ NULL, ++ NULL, ++ NULL, ++ NULL, ++ NULL, ++ NULL, ++ NULL, ++ NULL, ++ NULL, ++}; ++ ++static const char * funcs_c2[] = { ++ "LEND ", ++ "VCLK ", ++ "VLINE ", ++ "VFRAME ", ++ "VM ", ++ "LCD_LPCOE ", ++ "LCD_LPCREV ", ++ "LCD_LPCREVB", ++ "VD[0] ", ++ "VD[1] ", ++ "VD[2] ", ++ "VD[3] ", ++ "VD[4] ", ++ "VD[5] ", ++ "VD[6] ", ++ "VD[7] ", ++}; ++static const char * funcs_c3[] = { ++ NULL, ++ NULL, ++ NULL, ++ NULL, ++ "I2SSDI ", ++ NULL, ++ NULL, ++ NULL, ++ NULL, ++ NULL, ++ NULL, ++ NULL, ++ NULL, ++ NULL, ++ NULL, ++ NULL, ++}; ++ ++static const char * funcs_d2[] = { ++ "VD[8] ", ++ "VD[9] ", ++ "VD[10] ", ++ "VD[11] ", ++ "VD[12] ", ++ "VD[13] ", ++ "VD[14] ", ++ "VD[15] ", ++ "VD[16] ", ++ "VD[17] ", ++ "VD[18] ", ++ "VD[19] ", ++ "VD[20] ", ++ "VD[21] ", ++ "VD[22] ", ++ "VD[23] ", ++}; ++static const char * funcs_d3[] = { ++ "nSPICS1 ", ++ "SPICLK1 ", ++ NULL, ++ NULL, ++ NULL, ++ NULL, ++ NULL, ++ NULL, ++ "SPIMISO1 ", ++ "SPIMOSI1 ", ++ "SPICLK1 ", ++ NULL, ++ NULL, ++ NULL, ++ "nSS1 ", ++ "nSS0 ", ++}; ++ ++static const char * funcs_e2[] = { ++ "I2SLRCK ", ++ "I2SSCLK ", ++ "CDCLK ", ++ "I2SDI ", ++ "I2SDO ", ++ "SDCLK ", ++ "SDCMD ", ++ "SDDAT0 ", ++ "SDDAT1 ", ++ "SDDAT2 ", ++ "SDDAT3 ", ++ "SPIMISO0 ", ++ "SPIMOSI0 ", ++ "SPICLK0 ", ++ "IICSCL ", ++ "IICSDA ", ++}; ++static const char * funcs_e3[] = { ++ NULL, ++ NULL, ++ NULL, ++ NULL, ++ NULL, ++ NULL, ++ NULL, ++ NULL, ++ NULL, ++ NULL, ++ NULL, ++ NULL, ++ NULL, ++ NULL, ++ NULL, ++ NULL, ++}; ++ ++static const char * funcs_f2[] = { ++ "EINT[0] ", ++ "EINT[1] ", ++ "EINT[2] ", ++ "EINT[3] ", ++ "EINT[4] ", ++ "EINT[5] ", ++ "EINT[6] ", ++ "EINT[7] ", ++}; ++static const char * funcs_f3[] = { ++ NULL, ++ NULL, ++ NULL, ++ NULL, ++ NULL, ++ NULL, ++ NULL, ++ NULL, ++}; ++ ++ ++static const char * funcs_g2[] = { ++ "EINT[8] ", ++ "EINT[9] ", ++ "EINT[10] ", ++ "EINT[11] ", ++ "EINT[12] ", ++ "EINT[13] ", ++ "EINT[14] ", ++ "EINT[15] ", ++ "EINT[16] ", ++ "EINT[17] ", ++ "EINT[18] ", ++ "EINT[19] ", ++ "EINT[20] ", ++ "EINT[21] ", ++ "EINT[22] ", ++ "EINT[23] ", ++}; ++static const char * funcs_g3[] = { ++ NULL, ++ NULL, ++ "nSS0 ", ++ "nSS1 ", ++ "LCD_PWRDN ", ++ "SPIMISO1 ", ++ "SPIMOSI1 ", ++ "SPICLK1 ", ++ NULL, ++ "nRTS1 ", ++ "nCTS1 ", ++ "TCLK[1] ", ++ "nSPICS0 ", ++ NULL, ++ NULL, ++ NULL, ++}; ++ ++static const char * funcs_h2[] = { ++ "nCTS0 ", ++ "nRTS0 ", ++ "TXD[0] ", ++ "RXD[0] ", ++ "TXD[1] ", ++ "RXD[1] ", ++ "TXD[2] ", ++ "RXD[2] ", ++ "UEXTCLK ", ++ "CLKOUT0 ", ++ "CLKOUT1 ", ++}; ++static const char * funcs_h3[] = { ++ NULL, ++ NULL, ++ NULL, ++ NULL, ++ NULL, ++ NULL, ++ "nRTS1 ", ++ "nCTS1 ", ++ NULL, ++ "nSPICS0 ", ++ NULL, ++}; ++ ++static const char * funcs_j2[] = { ++ "CAMDATA[0] ", ++ "CAMDATA[1] ", ++ "CAMDATA[2] ", ++ "CAMDATA[3] ", ++ "CAMDATA[4] ", ++ "CAMDATA[5] ", ++ "CAMDATA[6] ", ++ "CAMDATA[7] ", ++ "CAMPCLK ", ++ "CAMVSYNC ", ++ "CAMHREF ", ++ "CAMCLKOUT ", ++ "CAMRESET ", ++}; ++static const char * funcs_j3[] = { ++ NULL, ++ NULL, ++ NULL, ++ NULL, ++ NULL, ++ NULL, ++ NULL, ++ NULL, ++ NULL, ++ NULL, ++ NULL, ++ NULL, ++ NULL, ++}; ++ ++/* used to dump GPIO states at suspend */ ++void s3c24xx_dump_gpio_states(void) ++{ ++ pretty_dump_a(__raw_readl(S3C2410_GPACON), ++ __raw_readl(S3C2410_GPADAT), ++ funcs_a, "GPA", 25); ++ pretty_dump(__raw_readl(S3C2410_GPBCON), ++ __raw_readl(S3C2410_GPBDAT), ++ __raw_readl(S3C2410_GPBUP), ++ funcs_b2, funcs_b3, "GPB", 11); ++ pretty_dump(__raw_readl(S3C2410_GPCCON), ++ __raw_readl(S3C2410_GPCDAT), ++ __raw_readl(S3C2410_GPCUP), ++ funcs_c2, funcs_c3, "GPC", 16); ++ pretty_dump(__raw_readl(S3C2410_GPDCON), ++ __raw_readl(S3C2410_GPDDAT), ++ __raw_readl(S3C2410_GPDUP), ++ funcs_d2, funcs_d3, "GPD", 16); ++ pretty_dump(__raw_readl(S3C2410_GPECON), ++ __raw_readl(S3C2410_GPEDAT), ++ __raw_readl(S3C2410_GPEUP), ++ funcs_e2, funcs_e3, "GPE", 16); ++ pretty_dump(__raw_readl(S3C2410_GPFCON), ++ __raw_readl(S3C2410_GPFDAT), ++ __raw_readl(S3C2410_GPFUP), ++ funcs_f2, funcs_f3, "GPF", 8); ++ pretty_dump(__raw_readl(S3C2410_GPGCON), ++ __raw_readl(S3C2410_GPGDAT), ++ __raw_readl(S3C2410_GPGUP), ++ funcs_g2, funcs_g3, "GPG", 16); ++ pretty_dump(__raw_readl(S3C2410_GPHCON), ++ __raw_readl(S3C2410_GPHDAT), ++ __raw_readl(S3C2410_GPHUP), ++ funcs_h2, funcs_h3, "GPH", 11); ++ pretty_dump(__raw_readl(S3C2440_GPJCON), ++ __raw_readl(S3C2440_GPJDAT), ++ __raw_readl(S3C2440_GPJUP), ++ funcs_j2, funcs_j3, "GPJ", 13); ++ ++} ++EXPORT_SYMBOL(s3c24xx_dump_gpio_states); ++ +diff -ruN --exclude='*.orig' --exclude='*.rej' linux-2.6.29-rc3.owrt/arch/arm/plat-s3c24xx/gpiolib.c linux-2.6.29-rc3.owrt.om/arch/arm/plat-s3c24xx/gpiolib.c +--- linux-2.6.29-rc3.owrt/arch/arm/plat-s3c24xx/gpiolib.c 2009-05-10 22:05:03.000000000 +0200 ++++ linux-2.6.29-rc3.owrt.om/arch/arm/plat-s3c24xx/gpiolib.c 2009-05-10 22:27:59.000000000 +0200 +@@ -22,6 +22,7 @@ + #include <plat/gpio-core.h> + #include <mach/hardware.h> + #include <asm/irq.h> ++#include <plat/pm.h> + + #include <mach/regs-gpio.h> + +@@ -78,6 +79,7 @@ + struct s3c_gpio_chip s3c24xx_gpios[] = { + [0] = { + .base = S3C24XX_GPIO_BASE(S3C2410_GPA0), ++ .pm = __gpio_pm(&s3c_gpio_pm_1bit), + .chip = { + .base = S3C2410_GPA0, + .owner = THIS_MODULE, +@@ -89,6 +91,7 @@ + }, + [1] = { + .base = S3C24XX_GPIO_BASE(S3C2410_GPB0), ++ .pm = __gpio_pm(&s3c_gpio_pm_2bit), + .chip = { + .base = S3C2410_GPB0, + .owner = THIS_MODULE, +@@ -98,6 +101,7 @@ + }, + [2] = { + .base = S3C24XX_GPIO_BASE(S3C2410_GPC0), ++ .pm = __gpio_pm(&s3c_gpio_pm_2bit), + .chip = { + .base = S3C2410_GPC0, + .owner = THIS_MODULE, +@@ -107,6 +111,7 @@ + }, + [3] = { + .base = S3C24XX_GPIO_BASE(S3C2410_GPD0), ++ .pm = __gpio_pm(&s3c_gpio_pm_2bit), + .chip = { + .base = S3C2410_GPD0, + .owner = THIS_MODULE, +@@ -116,6 +121,7 @@ + }, + [4] = { + .base = S3C24XX_GPIO_BASE(S3C2410_GPE0), ++ .pm = __gpio_pm(&s3c_gpio_pm_2bit), + .chip = { + .base = S3C2410_GPE0, + .label = "GPIOE", +@@ -125,6 +131,7 @@ + }, + [5] = { + .base = S3C24XX_GPIO_BASE(S3C2410_GPF0), ++ .pm = __gpio_pm(&s3c_gpio_pm_2bit), + .chip = { + .base = S3C2410_GPF0, + .owner = THIS_MODULE, +@@ -135,12 +142,23 @@ + }, + [6] = { + .base = S3C24XX_GPIO_BASE(S3C2410_GPG0), ++ .pm = __gpio_pm(&s3c_gpio_pm_2bit), + .chip = { + .base = S3C2410_GPG0, + .owner = THIS_MODULE, + .label = "GPIOG", +- .ngpio = 10, + .to_irq = s3c24xx_gpiolib_bankg_toirq, ++ .ngpio = 16, ++ }, ++ }, ++ [7] = { ++ .base = S3C24XX_GPIO_BASE(S3C2410_GPH0), ++ .pm = __gpio_pm(&s3c_gpio_pm_2bit), ++ .chip = { ++ .base = S3C2410_GPH0, ++ .owner = THIS_MODULE, ++ .label = "GPIOH", ++ .ngpio = 11, + }, + }, + }; +diff -ruN --exclude='*.orig' --exclude='*.rej' linux-2.6.29-rc3.owrt/arch/arm/plat-s3c24xx/gta02_pm_wlan.c linux-2.6.29-rc3.owrt.om/arch/arm/plat-s3c24xx/gta02_pm_wlan.c +--- linux-2.6.29-rc3.owrt/arch/arm/plat-s3c24xx/gta02_pm_wlan.c 1970-01-01 01:00:00.000000000 +0100 ++++ linux-2.6.29-rc3.owrt.om/arch/arm/plat-s3c24xx/gta02_pm_wlan.c 2009-05-10 22:27:59.000000000 +0200 +@@ -0,0 +1,222 @@ ++/* ++ * GTA02 WLAN power management ++ * ++ * (C) 2008, 2009 by Openmoko Inc. ++ * Author: Andy Green <andy@openmoko.com> ++ * All rights reserved. ++ * ++ * 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/init.h> ++#include <linux/kernel.h> ++#include <linux/mutex.h> ++#include <linux/platform_device.h> ++ ++#include <mach/hardware.h> ++#include <asm/mach-types.h> ++#include <asm/plat-s3c24xx/neo1973.h> ++ ++#include <mach/gta02.h> ++#include <mach/gta02-pm-wlan.h> ++#include <mach/regs-gpio.h> ++#include <mach/regs-gpioj.h> ++ ++#include <linux/delay.h> ++#include <linux/rfkill.h> ++ ++ ++/* ----- Module hardware reset ("power") ----------------------------------- */ ++ ++ ++void gta02_wlan_reset(int assert_reset) ++{ ++ if (assert_reset) { ++ s3c2410_gpio_setpin(GTA02_GPIO_nWLAN_RESET, 0); ++ msleep(200); /* probably excessive but we don't have specs */ ++ } else { ++ s3c2410_gpio_setpin(GTA02_GPIO_nWLAN_RESET, 1); ++ } ++} ++ ++#ifdef CONFIG_PM ++static int gta02_wlan_suspend(struct platform_device *pdev, pm_message_t state) ++{ ++ dev_dbg(&pdev->dev, "suspending\n"); ++ ++ return 0; ++} ++ ++static int gta02_wlan_resume(struct platform_device *pdev) ++{ ++ dev_dbg(&pdev->dev, "resuming\n"); ++ ++ return 0; ++} ++#else ++#define gta02_wlan_suspend NULL ++#define gta02_wlan_resume NULL ++#endif ++ ++ ++/* ----- rfkill ------------------------------------------------------------ */ ++ ++/* ++ * S3C MCI handles suspend/resume through device removal/insertion. In order to ++ * preserve rfkill state, as required in clause 7 of section 3.1 in rfkill.txt, ++ * we therefore need to maintain rfkill state outside the driver. ++ * ++ * This platform driver is as good a place as any other. ++ */ ++ ++static int (*gta02_wlan_rfkill_cb)(void *user, int on); ++static void *gta02_wlan_rfkill_user; ++static DEFINE_MUTEX(gta02_wlan_rfkill_lock); ++static int gta02_wlan_rfkill_on; ++ ++ ++/* ++ * gta02_wlan_query_rfkill_lock is used to obtain the rfkill state before the ++ * driver is ready to process rfkill callbacks. To prevent the state from ++ * changing until the driver has completed its initialization, we grab and hold ++ * the rfkill lock. ++ * ++ * A call to gta02_wlan_query_rfkill_lock must be followed by either ++ * - a call to gta02_wlan_set_rfkill_cb, to complete the setup, or ++ * - a call to gta02_wlan_query_rfkill_unlock to abort the setup process. ++ */ ++ ++int gta02_wlan_query_rfkill_lock(void) ++{ ++ mutex_lock(>a02_wlan_rfkill_lock); ++ return gta02_wlan_rfkill_on; ++} ++EXPORT_SYMBOL_GPL(gta02_wlan_query_rfkill_lock); ++ ++void gta02_wlan_query_rfkill_unlock(void) ++{ ++ mutex_unlock(>a02_wlan_rfkill_lock); ++} ++EXPORT_SYMBOL_GPL(gta02_wlan_query_rfkill_unlock); ++ ++ ++void gta02_wlan_set_rfkill_cb(int (*cb)(void *user, int on), void *user) ++{ ++ BUG_ON(!mutex_is_locked(>a02_wlan_rfkill_lock)); ++ BUG_ON(gta02_wlan_rfkill_cb); ++ gta02_wlan_rfkill_cb = cb; ++ gta02_wlan_rfkill_user = user; ++ mutex_unlock(>a02_wlan_rfkill_lock); ++} ++EXPORT_SYMBOL_GPL(gta02_wlan_set_rfkill_cb); ++ ++void gta02_wlan_clear_rfkill_cb(void) ++{ ++ mutex_lock(>a02_wlan_rfkill_lock); ++ BUG_ON(!gta02_wlan_rfkill_cb); ++ gta02_wlan_rfkill_cb = NULL; ++ mutex_unlock(>a02_wlan_rfkill_lock); ++} ++EXPORT_SYMBOL_GPL(gta02_wlan_clear_rfkill_cb); ++ ++static int gta02_wlan_toggle_radio(void *data, enum rfkill_state state) ++{ ++ struct device *dev = data; ++ int on = state == RFKILL_STATE_UNBLOCKED; ++ int res = 0; ++ ++ dev_dbg(dev, "gta02_wlan_toggle_radio: state %d (%p)\n", ++ state, gta02_wlan_rfkill_cb); ++ mutex_lock(>a02_wlan_rfkill_lock); ++ if (gta02_wlan_rfkill_cb) ++ res = gta02_wlan_rfkill_cb(gta02_wlan_rfkill_user, on); ++ if (!res) ++ gta02_wlan_rfkill_on = on; ++ mutex_unlock(>a02_wlan_rfkill_lock); ++ return res; ++} ++ ++ ++/* ----- Initialization/removal -------------------------------------------- */ ++ ++ ++static int __init gta02_wlan_probe(struct platform_device *pdev) ++{ ++ /* default-on for now */ ++ const int default_state = 1; ++ struct rfkill *rfkill; ++ int error; ++ ++ if (!machine_is_neo1973_gta02()) ++ return -EINVAL; ++ ++ dev_info(&pdev->dev, "starting\n"); ++ ++ s3c2410_gpio_cfgpin(GTA02_GPIO_nWLAN_RESET, S3C2410_GPIO_OUTPUT); ++ gta02_wlan_reset(1); ++ gta02_wlan_reset(0); ++ ++ rfkill = rfkill_allocate(&pdev->dev, RFKILL_TYPE_WLAN); ++ rfkill->name = "ar6000"; ++ rfkill->data = &pdev->dev; ++ rfkill->state = default_state ? RFKILL_STATE_ON : RFKILL_STATE_OFF; ++ /* ++ * If the WLAN driver somehow managed to get activated before we're ++ * ready, the driver is now in an unknown state, which isn't something ++ * we're prepared to handle. This can't happen, so just fail hard. ++ */ ++ BUG_ON(gta02_wlan_rfkill_cb); ++ gta02_wlan_rfkill_on = default_state; ++ rfkill->toggle_radio = gta02_wlan_toggle_radio; ++ ++ error = rfkill_register(rfkill); ++ if (error) { ++ rfkill_free(rfkill); ++ return error; ++ } ++ ++ dev_set_drvdata(&pdev->dev, rfkill); ++ ++ return 0; ++} ++ ++static int gta02_wlan_remove(struct platform_device *pdev) ++{ ++ struct rfkill *rfkill = dev_get_drvdata(&pdev->dev); ++ ++ rfkill_unregister(rfkill); ++ rfkill_free(rfkill); ++ ++ return 0; ++} ++ ++static struct platform_driver gta02_wlan_driver = { ++ .probe = gta02_wlan_probe, ++ .remove = gta02_wlan_remove, ++ .suspend = gta02_wlan_suspend, ++ .resume = gta02_wlan_resume, ++ .driver = { ++ .name = "gta02-pm-wlan", ++ }, ++}; ++ ++static int __devinit gta02_wlan_init(void) ++{ ++ return platform_driver_register(>a02_wlan_driver); ++} ++ ++static void gta02_wlan_exit(void) ++{ ++ platform_driver_unregister(>a02_wlan_driver); ++} ++ ++module_init(gta02_wlan_init); ++module_exit(gta02_wlan_exit); ++ ++MODULE_LICENSE("GPL"); ++MODULE_AUTHOR("Andy Green <andy@openmoko.com>"); ++MODULE_DESCRIPTION("Openmoko GTA02 WLAN power management"); +diff -ruN --exclude='*.orig' --exclude='*.rej' linux-2.6.29-rc3.owrt/arch/arm/plat-s3c24xx/include/plat/dma.h linux-2.6.29-rc3.owrt.om/arch/arm/plat-s3c24xx/include/plat/dma.h +--- linux-2.6.29-rc3.owrt/arch/arm/plat-s3c24xx/include/plat/dma.h 2009-05-10 22:05:03.000000000 +0200 ++++ linux-2.6.29-rc3.owrt.om/arch/arm/plat-s3c24xx/include/plat/dma.h 1970-01-01 01:00:00.000000000 +0100 +@@ -1,82 +0,0 @@ +-/* linux/include/asm-arm/plat-s3c24xx/dma.h +- * +- * Copyright (C) 2006 Simtec Electronics +- * Ben Dooks <ben@simtec.co.uk> +- * +- * Samsung S3C24XX DMA support +- * +- * This program is free software; you can redistribute it and/or modify +- * it under the terms of the GNU General Public License version 2 as +- * published by the Free Software Foundation. +-*/ +- +-extern struct sysdev_class dma_sysclass; +-extern struct s3c2410_dma_chan s3c2410_chans[S3C2410_DMA_CHANNELS]; +- +-#define DMA_CH_VALID (1<<31) +-#define DMA_CH_NEVER (1<<30) +- +-struct s3c24xx_dma_addr { +- unsigned long from; +- unsigned long to; +-}; +- +-/* struct s3c24xx_dma_map +- * +- * this holds the mapping information for the channel selected +- * to be connected to the specified device +-*/ +- +-struct s3c24xx_dma_map { +- const char *name; +- struct s3c24xx_dma_addr hw_addr; +- +- unsigned long channels[S3C2410_DMA_CHANNELS]; +- unsigned long channels_rx[S3C2410_DMA_CHANNELS]; +-}; +- +-struct s3c24xx_dma_selection { +- struct s3c24xx_dma_map *map; +- unsigned long map_size; +- unsigned long dcon_mask; +- +- void (*select)(struct s3c2410_dma_chan *chan, +- struct s3c24xx_dma_map *map); +- +- void (*direction)(struct s3c2410_dma_chan *chan, +- struct s3c24xx_dma_map *map, +- enum s3c2410_dmasrc dir); +-}; +- +-extern int s3c24xx_dma_init_map(struct s3c24xx_dma_selection *sel); +- +-/* struct s3c24xx_dma_order_ch +- * +- * channel map for one of the `enum dma_ch` dma channels. the list +- * entry contains a set of low-level channel numbers, orred with +- * DMA_CH_VALID, which are checked in the order in the array. +-*/ +- +-struct s3c24xx_dma_order_ch { +- unsigned int list[S3C2410_DMA_CHANNELS]; /* list of channels */ +- unsigned int flags; /* flags */ +-}; +- +-/* struct s3c24xx_dma_order +- * +- * information provided by either the core or the board to give the +- * dma system a hint on how to allocate channels +-*/ +- +-struct s3c24xx_dma_order { +- struct s3c24xx_dma_order_ch channels[DMACH_MAX]; +-}; +- +-extern int s3c24xx_dma_order_set(struct s3c24xx_dma_order *map); +- +-/* DMA init code, called from the cpu support code */ +- +-extern int s3c2410_dma_init(void); +- +-extern int s3c24xx_dma_init(unsigned int channels, unsigned int irq, +- unsigned int stride); +diff -ruN --exclude='*.orig' --exclude='*.rej' linux-2.6.29-rc3.owrt/arch/arm/plat-s3c24xx/include/plat/dma-plat.h linux-2.6.29-rc3.owrt.om/arch/arm/plat-s3c24xx/include/plat/dma-plat.h +--- linux-2.6.29-rc3.owrt/arch/arm/plat-s3c24xx/include/plat/dma-plat.h 1970-01-01 01:00:00.000000000 +0100 ++++ linux-2.6.29-rc3.owrt.om/arch/arm/plat-s3c24xx/include/plat/dma-plat.h 2009-05-10 22:27:59.000000000 +0200 +@@ -0,0 +1,84 @@ ++/* linux/arch/arm/plat-s3c24xx/include/plat/dma-plat.h ++ * ++ * Copyright (C) 2006 Simtec Electronics ++ * Ben Dooks <ben@simtec.co.uk> ++ * ++ * Samsung S3C24XX DMA support ++ * ++ * This program is free software; you can redistribute it and/or modify ++ * it under the terms of the GNU General Public License version 2 as ++ * published by the Free Software Foundation. ++*/ ++ ++#include <plat/dma-core.h> ++ ++extern struct sysdev_class dma_sysclass; ++extern struct s3c2410_dma_chan s3c2410_chans[S3C_DMA_CHANNELS]; ++ ++#define DMA_CH_VALID (1<<31) ++#define DMA_CH_NEVER (1<<30) ++ ++struct s3c24xx_dma_addr { ++ unsigned long from; ++ unsigned long to; ++}; ++ ++/* struct s3c24xx_dma_map ++ * ++ * this holds the mapping information for the channel selected ++ * to be connected to the specified device ++*/ ++ ++struct s3c24xx_dma_map { ++ const char *name; ++ struct s3c24xx_dma_addr hw_addr; ++ ++ unsigned long channels[S3C_DMA_CHANNELS]; ++ unsigned long channels_rx[S3C_DMA_CHANNELS]; ++}; ++ ++struct s3c24xx_dma_selection { ++ struct s3c24xx_dma_map *map; ++ unsigned long map_size; ++ unsigned long dcon_mask; ++ ++ void (*select)(struct s3c2410_dma_chan *chan, ++ struct s3c24xx_dma_map *map); ++ ++ void (*direction)(struct s3c2410_dma_chan *chan, ++ struct s3c24xx_dma_map *map, ++ enum s3c2410_dmasrc dir); ++}; ++ ++extern int s3c24xx_dma_init_map(struct s3c24xx_dma_selection *sel); ++ ++/* struct s3c24xx_dma_order_ch ++ * ++ * channel map for one of the `enum dma_ch` dma channels. the list ++ * entry contains a set of low-level channel numbers, orred with ++ * DMA_CH_VALID, which are checked in the order in the array. ++*/ ++ ++struct s3c24xx_dma_order_ch { ++ unsigned int list[S3C_DMA_CHANNELS]; /* list of channels */ ++ unsigned int flags; /* flags */ ++}; ++ ++/* struct s3c24xx_dma_order ++ * ++ * information provided by either the core or the board to give the ++ * dma system a hint on how to allocate channels ++*/ ++ ++struct s3c24xx_dma_order { ++ struct s3c24xx_dma_order_ch channels[DMACH_MAX]; ++}; ++ ++extern int s3c24xx_dma_order_set(struct s3c24xx_dma_order *map); ++ ++/* DMA init code, called from the cpu support code */ ++ ++extern int s3c2410_dma_init(void); ++ ++extern int s3c24xx_dma_init(unsigned int channels, unsigned int irq, ++ unsigned int stride); +diff -ruN --exclude='*.orig' --exclude='*.rej' linux-2.6.29-rc3.owrt/arch/arm/plat-s3c24xx/include/plat/irq.h linux-2.6.29-rc3.owrt.om/arch/arm/plat-s3c24xx/include/plat/irq.h +--- linux-2.6.29-rc3.owrt/arch/arm/plat-s3c24xx/include/plat/irq.h 2009-05-10 22:05:03.000000000 +0200 ++++ linux-2.6.29-rc3.owrt.om/arch/arm/plat-s3c24xx/include/plat/irq.h 2009-05-10 22:27:59.000000000 +0200 +@@ -10,6 +10,13 @@ + * published by the Free Software Foundation. + */ + ++#include <linux/io.h> ++ ++#include <mach/irqs.h> ++#include <mach/hardware.h> ++#include <mach/regs-irq.h> ++#include <mach/regs-gpio.h> ++ + #define irqdbf(x...) + #define irqdbf2(x...) + +@@ -25,8 +32,15 @@ + { + unsigned long mask; + unsigned long submask; ++#ifdef CONFIG_S3C2440_C_FIQ ++ unsigned long flags; ++#endif + + submask = __raw_readl(S3C2410_INTSUBMSK); ++#ifdef CONFIG_S3C2440_C_FIQ ++ local_save_flags(flags); ++ local_fiq_disable(); ++#endif + mask = __raw_readl(S3C2410_INTMSK); + + submask |= (1UL << (irqno - IRQ_S3CUART_RX0)); +@@ -39,6 +53,9 @@ + + /* write back masks */ + __raw_writel(submask, S3C2410_INTSUBMSK); ++#ifdef CONFIG_S3C2440_C_FIQ ++ local_irq_restore(flags); ++#endif + + } + +@@ -47,8 +64,15 @@ + { + unsigned long mask; + unsigned long submask; ++#ifdef CONFIG_S3C2440_C_FIQ ++ unsigned long flags; ++#endif + + submask = __raw_readl(S3C2410_INTSUBMSK); ++#ifdef CONFIG_S3C2440_C_FIQ ++ local_save_flags(flags); ++ local_fiq_disable(); ++#endif + mask = __raw_readl(S3C2410_INTMSK); + + submask &= ~(1UL << (irqno - IRQ_S3CUART_RX0)); +@@ -57,6 +81,9 @@ + /* write back masks */ + __raw_writel(submask, S3C2410_INTSUBMSK); + __raw_writel(mask, S3C2410_INTMSK); ++#ifdef CONFIG_S3C2440_C_FIQ ++ local_irq_restore(flags); ++#endif + } + + +diff -ruN --exclude='*.orig' --exclude='*.rej' linux-2.6.29-rc3.owrt/arch/arm/plat-s3c24xx/include/plat/map.h linux-2.6.29-rc3.owrt.om/arch/arm/plat-s3c24xx/include/plat/map.h +--- linux-2.6.29-rc3.owrt/arch/arm/plat-s3c24xx/include/plat/map.h 2009-05-10 22:05:03.000000000 +0200 ++++ linux-2.6.29-rc3.owrt.om/arch/arm/plat-s3c24xx/include/plat/map.h 2009-05-10 22:27:59.000000000 +0200 +@@ -31,6 +31,8 @@ + #define S3C24XX_SZ_UART SZ_1M + #define S3C_UART_OFFSET (0x4000) + ++#define S3C_VA_UARTx(uart) (S3C_VA_UART + ((uart * S3C_UART_OFFSET))) ++ + /* Timers */ + #define S3C24XX_VA_TIMER S3C_VA_TIMER + #define S3C2410_PA_TIMER (0x51000000) +@@ -56,7 +58,6 @@ + #define S3C24XX_SZ_SPI SZ_1M + #define S3C24XX_SZ_SDI SZ_1M + #define S3C24XX_SZ_NAND SZ_1M +-#define S3C24XX_SZ_USBHOST SZ_1M + + /* GPIO ports */ + +diff -ruN --exclude='*.orig' --exclude='*.rej' linux-2.6.29-rc3.owrt/arch/arm/plat-s3c24xx/include/plat/pm-core.h linux-2.6.29-rc3.owrt.om/arch/arm/plat-s3c24xx/include/plat/pm-core.h +--- linux-2.6.29-rc3.owrt/arch/arm/plat-s3c24xx/include/plat/pm-core.h 1970-01-01 01:00:00.000000000 +0100 ++++ linux-2.6.29-rc3.owrt.om/arch/arm/plat-s3c24xx/include/plat/pm-core.h 2009-05-10 22:27:59.000000000 +0200 +@@ -0,0 +1,64 @@ ++/* linux/arch/arm/plat-s3c24xx/include/plat/pll.h ++ * ++ * Copyright 2008 Simtec Electronics ++ * Ben Dooks <ben@simtec.co.uk> ++ * http://armlinux.simtec.co.uk/ ++ * ++ * S3C24xx - PM core support for arch/arm/plat-s3c/pm.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. ++ */ ++ ++static inline void s3c_pm_debug_init_uart(void) ++{ ++ unsigned long tmp = __raw_readl(S3C2410_CLKCON); ++ ++ /* re-start uart clocks */ ++ tmp |= S3C2410_CLKCON_UART0; ++ tmp |= S3C2410_CLKCON_UART1; ++ tmp |= S3C2410_CLKCON_UART2; ++ ++ __raw_writel(tmp, S3C2410_CLKCON); ++ udelay(10); ++} ++ ++static inline void s3c_pm_arch_prepare_irqs(void) ++{ ++ __raw_writel(s3c_irqwake_intmask, S3C2410_INTMSK); ++ __raw_writel(s3c_irqwake_eintmask, S3C2410_EINTMASK); ++ ++ /* ack any outstanding external interrupts before we go to sleep */ ++ ++ __raw_writel(__raw_readl(S3C2410_EINTPEND), S3C2410_EINTPEND); ++ __raw_writel(__raw_readl(S3C2410_INTPND), S3C2410_INTPND); ++ __raw_writel(__raw_readl(S3C2410_SRCPND), S3C2410_SRCPND); ++ ++} ++ ++static inline void s3c_pm_arch_stop_clocks(void) ++{ ++ __raw_writel(0x00, S3C2410_CLKCON); /* turn off clocks over sleep */ ++} ++ ++static void s3c_pm_show_resume_irqs(int start, unsigned long which, ++ unsigned long mask); ++ ++static inline void s3c_pm_arch_show_resume_irqs(void) ++{ ++ S3C_PMDBG("post sleep: IRQs 0x%08x, 0x%08x\n", ++ __raw_readl(S3C2410_SRCPND), ++ __raw_readl(S3C2410_EINTPEND)); ++ ++ s3c_pm_show_resume_irqs(IRQ_EINT0, __raw_readl(S3C2410_SRCPND), ++ s3c_irqwake_intmask); ++ ++ s3c_pm_show_resume_irqs(IRQ_EINT4-4, __raw_readl(S3C2410_EINTPEND), ++ s3c_irqwake_eintmask); ++} ++ ++static inline void s3c_pm_arch_update_uart(void __iomem *regs, ++ struct pm_uart_save *save) ++{ ++} +diff -ruN --exclude='*.orig' --exclude='*.rej' linux-2.6.29-rc3.owrt/arch/arm/plat-s3c24xx/include/plat/pm.h linux-2.6.29-rc3.owrt.om/arch/arm/plat-s3c24xx/include/plat/pm.h +--- linux-2.6.29-rc3.owrt/arch/arm/plat-s3c24xx/include/plat/pm.h 2009-05-10 22:05:03.000000000 +0200 ++++ linux-2.6.29-rc3.owrt.om/arch/arm/plat-s3c24xx/include/plat/pm.h 1970-01-01 01:00:00.000000000 +0100 +@@ -1,73 +0,0 @@ +-/* linux/include/asm-arm/plat-s3c24xx/pm.h +- * +- * Copyright (c) 2004 Simtec Electronics +- * Written by Ben Dooks, <ben@simtec.co.uk> +- * +- * 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. +-*/ +- +-/* s3c2410_pm_init +- * +- * called from board at initialisation time to setup the power +- * management +-*/ +- +-#ifdef CONFIG_PM +- +-extern __init int s3c2410_pm_init(void); +- +-#else +- +-static inline int s3c2410_pm_init(void) +-{ +- return 0; +-} +-#endif +- +-/* configuration for the IRQ mask over sleep */ +-extern unsigned long s3c_irqwake_intmask; +-extern unsigned long s3c_irqwake_eintmask; +- +-/* IRQ masks for IRQs allowed to go to sleep (see irq.c) */ +-extern unsigned long s3c_irqwake_intallow; +-extern unsigned long s3c_irqwake_eintallow; +- +-/* per-cpu sleep functions */ +- +-extern void (*pm_cpu_prep)(void); +-extern void (*pm_cpu_sleep)(void); +- +-/* Flags for PM Control */ +- +-extern unsigned long s3c_pm_flags; +- +-/* from sleep.S */ +- +-extern int s3c2410_cpu_save(unsigned long *saveblk); +-extern void s3c2410_cpu_suspend(void); +-extern void s3c2410_cpu_resume(void); +- +-extern unsigned long s3c2410_sleep_save_phys; +- +-/* sleep save info */ +- +-struct sleep_save { +- void __iomem *reg; +- unsigned long val; +-}; +- +-#define SAVE_ITEM(x) \ +- { .reg = (x) } +- +-extern void s3c2410_pm_do_save(struct sleep_save *ptr, int count); +-extern void s3c2410_pm_do_restore(struct sleep_save *ptr, int count); +- +-#ifdef CONFIG_PM +-extern int s3c24xx_irq_suspend(struct sys_device *dev, pm_message_t state); +-extern int s3c24xx_irq_resume(struct sys_device *dev); +-#else +-#define s3c24xx_irq_suspend NULL +-#define s3c24xx_irq_resume NULL +-#endif +diff -ruN --exclude='*.orig' --exclude='*.rej' linux-2.6.29-rc3.owrt/arch/arm/plat-s3c24xx/include/plat/regs-dma.h linux-2.6.29-rc3.owrt.om/arch/arm/plat-s3c24xx/include/plat/regs-dma.h +--- linux-2.6.29-rc3.owrt/arch/arm/plat-s3c24xx/include/plat/regs-dma.h 1970-01-01 01:00:00.000000000 +0100 ++++ linux-2.6.29-rc3.owrt.om/arch/arm/plat-s3c24xx/include/plat/regs-dma.h 2009-05-10 22:27:59.000000000 +0200 +@@ -0,0 +1,145 @@ ++/* arch/arm/mach-s3c2410/include/mach/dma.h ++ * ++ * Copyright (C) 2003,2004,2006 Simtec Electronics ++ * Ben Dooks <ben@simtec.co.uk> ++ * ++ * Samsung S3C24XX DMA support ++ * ++ * This program is free software; you can redistribute it and/or modify ++ * it under the terms of the GNU General Public License version 2 as ++ * published by the Free Software Foundation. ++*/ ++ ++/* DMA Register definitions */ ++ ++#define S3C2410_DMA_DISRC (0x00) ++#define S3C2410_DMA_DISRCC (0x04) ++#define S3C2410_DMA_DIDST (0x08) ++#define S3C2410_DMA_DIDSTC (0x0C) ++#define S3C2410_DMA_DCON (0x10) ++#define S3C2410_DMA_DSTAT (0x14) ++#define S3C2410_DMA_DCSRC (0x18) ++#define S3C2410_DMA_DCDST (0x1C) ++#define S3C2410_DMA_DMASKTRIG (0x20) ++#define S3C2412_DMA_DMAREQSEL (0x24) ++#define S3C2443_DMA_DMAREQSEL (0x24) ++ ++#define S3C2410_DISRCC_INC (1<<0) ++#define S3C2410_DISRCC_APB (1<<1) ++ ++#define S3C2410_DMASKTRIG_STOP (1<<2) ++#define S3C2410_DMASKTRIG_ON (1<<1) ++#define S3C2410_DMASKTRIG_SWTRIG (1<<0) ++ ++#define S3C2410_DCON_DEMAND (0<<31) ++#define S3C2410_DCON_HANDSHAKE (1<<31) ++#define S3C2410_DCON_SYNC_PCLK (0<<30) ++#define S3C2410_DCON_SYNC_HCLK (1<<30) ++ ++#define S3C2410_DCON_INTREQ (1<<29) ++ ++#define S3C2410_DCON_CH0_XDREQ0 (0<<24) ++#define S3C2410_DCON_CH0_UART0 (1<<24) ++#define S3C2410_DCON_CH0_SDI (2<<24) ++#define S3C2410_DCON_CH0_TIMER (3<<24) ++#define S3C2410_DCON_CH0_USBEP1 (4<<24) ++ ++#define S3C2410_DCON_CH1_XDREQ1 (0<<24) ++#define S3C2410_DCON_CH1_UART1 (1<<24) ++#define S3C2410_DCON_CH1_I2SSDI (2<<24) ++#define S3C2410_DCON_CH1_SPI (3<<24) ++#define S3C2410_DCON_CH1_USBEP2 (4<<24) ++ ++#define S3C2410_DCON_CH2_I2SSDO (0<<24) ++#define S3C2410_DCON_CH2_I2SSDI (1<<24) ++#define S3C2410_DCON_CH2_SDI (2<<24) ++#define S3C2410_DCON_CH2_TIMER (3<<24) ++#define S3C2410_DCON_CH2_USBEP3 (4<<24) ++ ++#define S3C2410_DCON_CH3_UART2 (0<<24) ++#define S3C2410_DCON_CH3_SDI (1<<24) ++#define S3C2410_DCON_CH3_SPI (2<<24) ++#define S3C2410_DCON_CH3_TIMER (3<<24) ++#define S3C2410_DCON_CH3_USBEP4 (4<<24) ++ ++#define S3C2410_DCON_SRCSHIFT (24) ++#define S3C2410_DCON_SRCMASK (7<<24) ++ ++#define S3C2410_DCON_BYTE (0<<20) ++#define S3C2410_DCON_HALFWORD (1<<20) ++#define S3C2410_DCON_WORD (2<<20) ++ ++#define S3C2410_DCON_AUTORELOAD (0<<22) ++#define S3C2410_DCON_NORELOAD (1<<22) ++#define S3C2410_DCON_HWTRIG (1<<23) ++ ++#if defined(CONFIG_CPU_S3C2440) || defined(CONFIG_CPU_S3C2442) ++#define S3C2440_DIDSTC_CHKINT (1<<2) ++ ++#define S3C2440_DCON_CH0_I2SSDO (5<<24) ++#define S3C2440_DCON_CH0_PCMIN (6<<24) ++ ++#define S3C2440_DCON_CH1_PCMOUT (5<<24) ++#define S3C2440_DCON_CH1_SDI (6<<24) ++ ++#define S3C2440_DCON_CH2_PCMIN (5<<24) ++#define S3C2440_DCON_CH2_MICIN (6<<24) ++ ++#define S3C2440_DCON_CH3_MICIN (5<<24) ++#define S3C2440_DCON_CH3_PCMOUT (6<<24) ++#endif ++ ++#ifdef CONFIG_CPU_S3C2412 ++ ++#define S3C2412_DMAREQSEL_SRC(x) ((x)<<1) ++ ++#define S3C2412_DMAREQSEL_HW (1) ++ ++#define S3C2412_DMAREQSEL_SPI0TX S3C2412_DMAREQSEL_SRC(0) ++#define S3C2412_DMAREQSEL_SPI0RX S3C2412_DMAREQSEL_SRC(1) ++#define S3C2412_DMAREQSEL_SPI1TX S3C2412_DMAREQSEL_SRC(2) ++#define S3C2412_DMAREQSEL_SPI1RX S3C2412_DMAREQSEL_SRC(3) ++#define S3C2412_DMAREQSEL_I2STX S3C2412_DMAREQSEL_SRC(4) ++#define S3C2412_DMAREQSEL_I2SRX S3C2412_DMAREQSEL_SRC(5) ++#define S3C2412_DMAREQSEL_TIMER S3C2412_DMAREQSEL_SRC(9) ++#define S3C2412_DMAREQSEL_SDI S3C2412_DMAREQSEL_SRC(10) ++#define S3C2412_DMAREQSEL_USBEP1 S3C2412_DMAREQSEL_SRC(13) ++#define S3C2412_DMAREQSEL_USBEP2 S3C2412_DMAREQSEL_SRC(14) ++#define S3C2412_DMAREQSEL_USBEP3 S3C2412_DMAREQSEL_SRC(15) ++#define S3C2412_DMAREQSEL_USBEP4 S3C2412_DMAREQSEL_SRC(16) ++#define S3C2412_DMAREQSEL_XDREQ0 S3C2412_DMAREQSEL_SRC(17) ++#define S3C2412_DMAREQSEL_XDREQ1 S3C2412_DMAREQSEL_SRC(18) ++#define S3C2412_DMAREQSEL_UART0_0 S3C2412_DMAREQSEL_SRC(19) ++#define S3C2412_DMAREQSEL_UART0_1 S3C2412_DMAREQSEL_SRC(20) ++#define S3C2412_DMAREQSEL_UART1_0 S3C2412_DMAREQSEL_SRC(21) ++#define S3C2412_DMAREQSEL_UART1_1 S3C2412_DMAREQSEL_SRC(22) ++#define S3C2412_DMAREQSEL_UART2_0 S3C2412_DMAREQSEL_SRC(23) ++#define S3C2412_DMAREQSEL_UART2_1 S3C2412_DMAREQSEL_SRC(24) ++ ++#endif ++ ++#define S3C2443_DMAREQSEL_SRC(x) ((x)<<1) ++ ++#define S3C2443_DMAREQSEL_HW (1) ++ ++#define S3C2443_DMAREQSEL_SPI0TX S3C2443_DMAREQSEL_SRC(0) ++#define S3C2443_DMAREQSEL_SPI0RX S3C2443_DMAREQSEL_SRC(1) ++#define S3C2443_DMAREQSEL_SPI1TX S3C2443_DMAREQSEL_SRC(2) ++#define S3C2443_DMAREQSEL_SPI1RX S3C2443_DMAREQSEL_SRC(3) ++#define S3C2443_DMAREQSEL_I2STX S3C2443_DMAREQSEL_SRC(4) ++#define S3C2443_DMAREQSEL_I2SRX S3C2443_DMAREQSEL_SRC(5) ++#define S3C2443_DMAREQSEL_TIMER S3C2443_DMAREQSEL_SRC(9) ++#define S3C2443_DMAREQSEL_SDI S3C2443_DMAREQSEL_SRC(10) ++#define S3C2443_DMAREQSEL_XDREQ0 S3C2443_DMAREQSEL_SRC(17) ++#define S3C2443_DMAREQSEL_XDREQ1 S3C2443_DMAREQSEL_SRC(18) ++#define S3C2443_DMAREQSEL_UART0_0 S3C2443_DMAREQSEL_SRC(19) ++#define S3C2443_DMAREQSEL_UART0_1 S3C2443_DMAREQSEL_SRC(20) ++#define S3C2443_DMAREQSEL_UART1_0 S3C2443_DMAREQSEL_SRC(21) ++#define S3C2443_DMAREQSEL_UART1_1 S3C2443_DMAREQSEL_SRC(22) ++#define S3C2443_DMAREQSEL_UART2_0 S3C2443_DMAREQSEL_SRC(23) ++#define S3C2443_DMAREQSEL_UART2_1 S3C2443_DMAREQSEL_SRC(24) ++#define S3C2443_DMAREQSEL_UART3_0 S3C2443_DMAREQSEL_SRC(25) ++#define S3C2443_DMAREQSEL_UART3_1 S3C2443_DMAREQSEL_SRC(26) ++#define S3C2443_DMAREQSEL_PCMOUT S3C2443_DMAREQSEL_SRC(27) ++#define S3C2443_DMAREQSEL_PCMIN S3C2443_DMAREQSEL_SRC(28) ++#define S3C2443_DMAREQSEL_MICIN S3C2443_DMAREQSEL_SRC(29) +diff -ruN --exclude='*.orig' --exclude='*.rej' linux-2.6.29-rc3.owrt/arch/arm/plat-s3c24xx/include/plat/regs-iis.h linux-2.6.29-rc3.owrt.om/arch/arm/plat-s3c24xx/include/plat/regs-iis.h +--- linux-2.6.29-rc3.owrt/arch/arm/plat-s3c24xx/include/plat/regs-iis.h 1970-01-01 01:00:00.000000000 +0100 ++++ linux-2.6.29-rc3.owrt.om/arch/arm/plat-s3c24xx/include/plat/regs-iis.h 2009-05-10 22:27:59.000000000 +0200 +@@ -0,0 +1,77 @@ ++/* arch/arm/mach-s3c2410/include/mach/regs-iis.h ++ * ++ * Copyright (c) 2003 Simtec Electronics <linux@simtec.co.uk> ++ * http://www.simtec.co.uk/products/SWLINUX/ ++ * ++ * 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. ++ * ++ * S3C2410 IIS register definition ++*/ ++ ++#ifndef __ASM_ARCH_REGS_IIS_H ++#define __ASM_ARCH_REGS_IIS_H ++ ++#define S3C2410_IISCON (0x00) ++ ++#define S3C2410_IISCON_LRINDEX (1<<8) ++#define S3C2410_IISCON_TXFIFORDY (1<<7) ++#define S3C2410_IISCON_RXFIFORDY (1<<6) ++#define S3C2410_IISCON_TXDMAEN (1<<5) ++#define S3C2410_IISCON_RXDMAEN (1<<4) ++#define S3C2410_IISCON_TXIDLE (1<<3) ++#define S3C2410_IISCON_RXIDLE (1<<2) ++#define S3C2410_IISCON_PSCEN (1<<1) ++#define S3C2410_IISCON_IISEN (1<<0) ++ ++#define S3C2410_IISMOD (0x04) ++ ++#define S3C2440_IISMOD_MPLL (1<<9) ++#define S3C2410_IISMOD_SLAVE (1<<8) ++#define S3C2410_IISMOD_NOXFER (0<<6) ++#define S3C2410_IISMOD_RXMODE (1<<6) ++#define S3C2410_IISMOD_TXMODE (2<<6) ++#define S3C2410_IISMOD_TXRXMODE (3<<6) ++#define S3C2410_IISMOD_LR_LLOW (0<<5) ++#define S3C2410_IISMOD_LR_RLOW (1<<5) ++#define S3C2410_IISMOD_IIS (0<<4) ++#define S3C2410_IISMOD_MSB (1<<4) ++#define S3C2410_IISMOD_8BIT (0<<3) ++#define S3C2410_IISMOD_16BIT (1<<3) ++#define S3C2410_IISMOD_BITMASK (1<<3) ++#define S3C2410_IISMOD_256FS (0<<2) ++#define S3C2410_IISMOD_384FS (1<<2) ++#define S3C2410_IISMOD_16FS (0<<0) ++#define S3C2410_IISMOD_32FS (1<<0) ++#define S3C2410_IISMOD_48FS (2<<0) ++#define S3C2410_IISMOD_FS_MASK (3<<0) ++ ++#define S3C2410_IISPSR (0x08) ++#define S3C2410_IISPSR_INTMASK (31<<5) ++#define S3C2410_IISPSR_INTSHIFT (5) ++#define S3C2410_IISPSR_EXTMASK (31<<0) ++#define S3C2410_IISPSR_EXTSHFIT (0) ++ ++#define S3C2410_IISFCON (0x0c) ++ ++#define S3C2410_IISFCON_TXDMA (1<<15) ++#define S3C2410_IISFCON_RXDMA (1<<14) ++#define S3C2410_IISFCON_TXENABLE (1<<13) ++#define S3C2410_IISFCON_RXENABLE (1<<12) ++#define S3C2410_IISFCON_TXMASK (0x3f << 6) ++#define S3C2410_IISFCON_TXSHIFT (6) ++#define S3C2410_IISFCON_RXMASK (0x3f) ++#define S3C2410_IISFCON_RXSHIFT (0) ++ ++#define S3C2400_IISFCON_TXDMA (1<<11) ++#define S3C2400_IISFCON_RXDMA (1<<10) ++#define S3C2400_IISFCON_TXENABLE (1<<9) ++#define S3C2400_IISFCON_RXENABLE (1<<8) ++#define S3C2400_IISFCON_TXMASK (0x07 << 4) ++#define S3C2400_IISFCON_TXSHIFT (4) ++#define S3C2400_IISFCON_RXMASK (0x07) ++#define S3C2400_IISFCON_RXSHIFT (0) ++ ++#define S3C2410_IISFIFO (0x10) ++#endif /* __ASM_ARCH_REGS_IIS_H */ +diff -ruN --exclude='*.orig' --exclude='*.rej' linux-2.6.29-rc3.owrt/arch/arm/plat-s3c24xx/irq.c linux-2.6.29-rc3.owrt.om/arch/arm/plat-s3c24xx/irq.c +--- linux-2.6.29-rc3.owrt/arch/arm/plat-s3c24xx/irq.c 2009-05-10 22:05:03.000000000 +0200 ++++ linux-2.6.29-rc3.owrt.om/arch/arm/plat-s3c24xx/irq.c 2009-05-10 22:27:59.000000000 +0200 +@@ -1,6 +1,6 @@ + /* linux/arch/arm/plat-s3c24xx/irq.c + * +- * Copyright (c) 2003,2004 Simtec Electronics ++ * Copyright (c) 2003,2004 Simtec Electronics + * Ben Dooks <ben@simtec.co.uk> + * + * This program is free software; you can redistribute it and/or modify +@@ -16,38 +16,6 @@ + * 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, MA 02111-1307 USA +- * +- * Changelog: +- * +- * 22-Jul-2004 Ben Dooks <ben@simtec.co.uk> +- * Fixed compile warnings +- * +- * 22-Jul-2004 Roc Wu <cooloney@yahoo.com.cn> +- * Fixed s3c_extirq_type +- * +- * 21-Jul-2004 Arnaud Patard (Rtp) <arnaud.patard@rtp-net.org> +- * Addition of ADC/TC demux +- * +- * 04-Oct-2004 Klaus Fetscher <k.fetscher@fetron.de> +- * Fix for set_irq_type() on low EINT numbers +- * +- * 05-Oct-2004 Ben Dooks <ben@simtec.co.uk> +- * Tidy up KF's patch and sort out new release +- * +- * 05-Oct-2004 Ben Dooks <ben@simtec.co.uk> +- * Add support for power management controls +- * +- * 04-Nov-2004 Ben Dooks +- * Fix standard IRQ wake for EINT0..4 and RTC +- * +- * 22-Feb-2005 Ben Dooks +- * Fixed edge-triggering on ADC IRQ +- * +- * 28-Jun-2005 Ben Dooks +- * Mark IRQ_LCD valid +- * +- * 25-Jul-2005 Ben Dooks +- * Split the S3C2440 IRQ code to separate file + */ + + #include <linux/init.h> +@@ -55,11 +23,8 @@ + #include <linux/interrupt.h> + #include <linux/ioport.h> + #include <linux/sysdev.h> +-#include <linux/io.h> + +-#include <mach/hardware.h> + #include <asm/irq.h> +- + #include <asm/mach/irq.h> + + #include <plat/regs-irqtype.h> +@@ -70,76 +35,24 @@ + #include <plat/pm.h> + #include <plat/irq.h> + +-/* wakeup irq control */ +- +-#ifdef CONFIG_PM +- +-/* state for IRQs over sleep */ +- +-/* default is to allow for EINT0..EINT15, and IRQ_RTC as wakeup sources +- * +- * set bit to 1 in allow bitfield to enable the wakeup settings on it +-*/ +- +-unsigned long s3c_irqwake_intallow = 1L << (IRQ_RTC - IRQ_EINT0) | 0xfL; +-unsigned long s3c_irqwake_intmask = 0xffffffffL; +-unsigned long s3c_irqwake_eintallow = 0x0000fff0L; +-unsigned long s3c_irqwake_eintmask = 0xffffffffL; +- +-int +-s3c_irq_wake(unsigned int irqno, unsigned int state) +-{ +- unsigned long irqbit = 1 << (irqno - IRQ_EINT0); +- +- if (!(s3c_irqwake_intallow & irqbit)) +- return -ENOENT; +- +- printk(KERN_INFO "wake %s for irq %d\n", +- state ? "enabled" : "disabled", irqno); +- +- if (!state) +- s3c_irqwake_intmask |= irqbit; +- else +- s3c_irqwake_intmask &= ~irqbit; +- +- return 0; +-} +- +-static int +-s3c_irqext_wake(unsigned int irqno, unsigned int state) +-{ +- unsigned long bit = 1L << (irqno - EXTINT_OFF); +- +- if (!(s3c_irqwake_eintallow & bit)) +- return -ENOENT; +- +- printk(KERN_INFO "wake %s for irq %d\n", +- state ? "enabled" : "disabled", irqno); +- +- if (!state) +- s3c_irqwake_eintmask |= bit; +- else +- s3c_irqwake_eintmask &= ~bit; +- +- return 0; +-} +- +-#else +-#define s3c_irqext_wake NULL +-#define s3c_irq_wake NULL +-#endif +- +- + static void + s3c_irq_mask(unsigned int irqno) + { + unsigned long mask; +- ++#ifdef CONFIG_S3C2440_C_FIQ ++ unsigned long flags; ++#endif + irqno -= IRQ_EINT0; +- ++#ifdef CONFIG_S3C2440_C_FIQ ++ local_save_flags(flags); ++ local_fiq_disable(); ++#endif + mask = __raw_readl(S3C2410_INTMSK); + mask |= 1UL << irqno; + __raw_writel(mask, S3C2410_INTMSK); ++#ifdef CONFIG_S3C2440_C_FIQ ++ local_irq_restore(flags); ++#endif + } + + static inline void +@@ -156,9 +69,19 @@ + { + unsigned long bitval = 1UL << (irqno - IRQ_EINT0); + unsigned long mask; ++#ifdef CONFIG_S3C2440_C_FIQ ++ unsigned long flags; ++#endif + ++#ifdef CONFIG_S3C2440_C_FIQ ++ local_save_flags(flags); ++ local_fiq_disable(); ++#endif + mask = __raw_readl(S3C2410_INTMSK); + __raw_writel(mask|bitval, S3C2410_INTMSK); ++#ifdef CONFIG_S3C2440_C_FIQ ++ local_irq_restore(flags); ++#endif + + __raw_writel(bitval, S3C2410_SRCPND); + __raw_writel(bitval, S3C2410_INTPND); +@@ -169,15 +92,25 @@ + s3c_irq_unmask(unsigned int irqno) + { + unsigned long mask; ++#ifdef CONFIG_S3C2440_C_FIQ ++ unsigned long flags; ++#endif + + if (irqno != IRQ_TIMER4 && irqno != IRQ_EINT8t23) + irqdbf2("s3c_irq_unmask %d\n", irqno); + + irqno -= IRQ_EINT0; + ++#ifdef CONFIG_S3C2440_C_FIQ ++ local_save_flags(flags); ++ local_fiq_disable(); ++#endif + mask = __raw_readl(S3C2410_INTMSK); + mask &= ~(1UL << irqno); + __raw_writel(mask, S3C2410_INTMSK); ++#ifdef CONFIG_S3C2440_C_FIQ ++ local_irq_restore(flags); ++#endif + } + + struct irq_chip s3c_irq_level_chip = { +@@ -590,59 +523,6 @@ + } + } + +-#ifdef CONFIG_PM +- +-static struct sleep_save irq_save[] = { +- SAVE_ITEM(S3C2410_INTMSK), +- SAVE_ITEM(S3C2410_INTSUBMSK), +-}; +- +-/* the extint values move between the s3c2410/s3c2440 and the s3c2412 +- * so we use an array to hold them, and to calculate the address of +- * the register at run-time +-*/ +- +-static unsigned long save_extint[3]; +-static unsigned long save_eintflt[4]; +-static unsigned long save_eintmask; +- +-int s3c24xx_irq_suspend(struct sys_device *dev, pm_message_t state) +-{ +- unsigned int i; +- +- for (i = 0; i < ARRAY_SIZE(save_extint); i++) +- save_extint[i] = __raw_readl(S3C24XX_EXTINT0 + (i*4)); +- +- for (i = 0; i < ARRAY_SIZE(save_eintflt); i++) +- save_eintflt[i] = __raw_readl(S3C24XX_EINFLT0 + (i*4)); +- +- s3c2410_pm_do_save(irq_save, ARRAY_SIZE(irq_save)); +- save_eintmask = __raw_readl(S3C24XX_EINTMASK); +- +- return 0; +-} +- +-int s3c24xx_irq_resume(struct sys_device *dev) +-{ +- unsigned int i; +- +- for (i = 0; i < ARRAY_SIZE(save_extint); i++) +- __raw_writel(save_extint[i], S3C24XX_EXTINT0 + (i*4)); +- +- for (i = 0; i < ARRAY_SIZE(save_eintflt); i++) +- __raw_writel(save_eintflt[i], S3C24XX_EINFLT0 + (i*4)); +- +- s3c2410_pm_do_restore(irq_save, ARRAY_SIZE(irq_save)); +- __raw_writel(save_eintmask, S3C24XX_EINTMASK); +- +- return 0; +-} +- +-#else +-#define s3c24xx_irq_suspend NULL +-#define s3c24xx_irq_resume NULL +-#endif +- + /* s3c24xx_init_irq + * + * Initialise S3C2410 IRQ system +@@ -673,26 +553,26 @@ + + last = 0; + for (i = 0; i < 4; i++) { +- pend = __raw_readl(S3C2410_INTPND); ++ pend = __raw_readl(S3C2410_SUBSRCPND); + + if (pend == 0 || pend == last) + break; + +- __raw_writel(pend, S3C2410_SRCPND); +- __raw_writel(pend, S3C2410_INTPND); +- printk("irq: clearing pending status %08x\n", (int)pend); ++ printk("irq: clearing subpending status %08x\n", (int)pend); ++ __raw_writel(pend, S3C2410_SUBSRCPND); + last = pend; + } + + last = 0; + for (i = 0; i < 4; i++) { +- pend = __raw_readl(S3C2410_SUBSRCPND); ++ pend = __raw_readl(S3C2410_INTPND); + + if (pend == 0 || pend == last) + break; + +- printk("irq: clearing subpending status %08x\n", (int)pend); +- __raw_writel(pend, S3C2410_SUBSRCPND); ++ __raw_writel(pend, S3C2410_SRCPND); ++ __raw_writel(pend, S3C2410_INTPND); ++ printk("irq: clearing pending status %08x\n", (int)pend); + last = pend; + } + +diff -ruN --exclude='*.orig' --exclude='*.rej' linux-2.6.29-rc3.owrt/arch/arm/plat-s3c24xx/irq-pm.c linux-2.6.29-rc3.owrt.om/arch/arm/plat-s3c24xx/irq-pm.c +--- linux-2.6.29-rc3.owrt/arch/arm/plat-s3c24xx/irq-pm.c 1970-01-01 01:00:00.000000000 +0100 ++++ linux-2.6.29-rc3.owrt.om/arch/arm/plat-s3c24xx/irq-pm.c 2009-05-10 22:27:59.000000000 +0200 +@@ -0,0 +1,118 @@ ++/* linux/arch/arm/plat-s3c24xx/irq-om.c ++ * ++ * Copyright (c) 2003,2004 Simtec Electronics ++ * Ben Dooks <ben@simtec.co.uk> ++ * http://armlinux.simtec.co.uk/ ++ * ++ * S3C24XX - IRQ PM code ++ * ++ * This program is free software; you can redistribute it and/or modify ++ * it under the terms of the GNU General Public License version 2 as ++ * published by the Free Software Foundation. ++ */ ++ ++#include <linux/init.h> ++#include <linux/module.h> ++#include <linux/interrupt.h> ++#include <linux/sysdev.h> ++#include <linux/irq.h> ++ ++#include <plat/cpu.h> ++#include <plat/pm.h> ++#include <plat/irq.h> ++ ++/* state for IRQs over sleep */ ++ ++/* default is to allow for EINT0..EINT15, and IRQ_RTC as wakeup sources ++ * ++ * set bit to 1 in allow bitfield to enable the wakeup settings on it ++*/ ++ ++unsigned long s3c_irqwake_intallow = 1L << (IRQ_RTC - IRQ_EINT0) | 0xfL; ++unsigned long s3c_irqwake_eintallow = 0x0000fff0L; ++ ++int s3c_irq_wake(unsigned int irqno, unsigned int state) ++{ ++ unsigned long irqbit = 1 << (irqno - IRQ_EINT0); ++ ++ if (!(s3c_irqwake_intallow & irqbit)) ++ return -ENOENT; ++ ++ printk(KERN_INFO "wake %s for irq %d\n", ++ state ? "enabled" : "disabled", irqno); ++ ++ if (!state) ++ s3c_irqwake_intmask |= irqbit; ++ else ++ s3c_irqwake_intmask &= ~irqbit; ++ ++ return 0; ++} ++ ++static struct sleep_save irq_save[] = { ++ SAVE_ITEM(S3C2410_INTMSK), ++ SAVE_ITEM(S3C2410_INTSUBMSK), ++}; ++ ++/* the extint values move between the s3c2410/s3c2440 and the s3c2412 ++ * so we use an array to hold them, and to calculate the address of ++ * the register at run-time ++*/ ++ ++static unsigned long save_extint[3]; ++static unsigned long save_eintflt[4]; ++static unsigned long save_eintmask; ++ ++int s3c24xx_irq_suspend(struct sys_device *dev, pm_message_t state) ++{ ++ unsigned int i; ++ ++ for (i = 0; i < ARRAY_SIZE(save_extint); i++) ++ save_extint[i] = __raw_readl(S3C24XX_EXTINT0 + (i*4)); ++ ++ for (i = 0; i < ARRAY_SIZE(save_eintflt); i++) ++ save_eintflt[i] = __raw_readl(S3C24XX_EINFLT0 + (i*4)); ++ ++ s3c_pm_do_save(irq_save, ARRAY_SIZE(irq_save)); ++ save_eintmask = __raw_readl(S3C24XX_EINTMASK); ++ ++ return 0; ++} ++ ++int s3c24xx_irq_resume(struct sys_device *dev) ++{ ++ unsigned int i, irq; ++ unsigned long eintpnd; ++ struct irq_desc *desc; ++ ++ for (i = 0; i < ARRAY_SIZE(save_extint); i++) ++ __raw_writel(save_extint[i], S3C24XX_EXTINT0 + (i*4)); ++ ++ for (i = 0; i < ARRAY_SIZE(save_eintflt); i++) ++ __raw_writel(save_eintflt[i], S3C24XX_EINFLT0 + (i*4)); ++ ++ s3c_pm_do_restore(irq_save, ARRAY_SIZE(irq_save)); ++ __raw_writel(save_eintmask, S3C24XX_EINTMASK); ++ ++ /* ++ * ACK those interrupts which are now masked and pending. ++ * Level interrupts if not ACKed here, create an interrupt storm ++ * because they are not handled at all. ++ */ ++ ++ eintpnd = __raw_readl(S3C24XX_EINTPEND); ++ ++ eintpnd &= save_eintmask; ++ eintpnd &= ~0xff; /* ignore lower irqs */ ++ ++ while (eintpnd) { ++ irq = __ffs(eintpnd); ++ eintpnd &= ~(1 << irq); ++ ++ irq += (IRQ_EINT4 - 4); ++ desc = irq_to_desc(irq); ++ desc->chip->ack(irq); ++ } ++ ++ return 0; ++} +diff -ruN --exclude='*.orig' --exclude='*.rej' linux-2.6.29-rc3.owrt/arch/arm/plat-s3c24xx/Kconfig linux-2.6.29-rc3.owrt.om/arch/arm/plat-s3c24xx/Kconfig +--- linux-2.6.29-rc3.owrt/arch/arm/plat-s3c24xx/Kconfig 2009-05-10 22:05:03.000000000 +0200 ++++ linux-2.6.29-rc3.owrt.om/arch/arm/plat-s3c24xx/Kconfig 2009-05-10 22:27:59.000000000 +0200 +@@ -10,6 +10,7 @@ + default y + select NO_IOPORT + select ARCH_REQUIRE_GPIOLIB ++ select S3C_GPIO_TRACK + help + Base platform code for any Samsung S3C24XX device + +@@ -30,7 +31,7 @@ + + config CPU_S3C244X + bool +- depends on ARCH_S3C2410 && (CPU_S3C2440 || CPU_S3C2442) ++ default y if CPU_S3C2440 || CPU_S3C2442 + help + Support for S3C2440 and S3C2442 Samsung Mobile CPU based systems. + +@@ -71,6 +72,7 @@ + config S3C2410_DMA + bool "S3C2410 DMA support" + depends on ARCH_S3C2410 ++ select S3C_DMA + help + S3C2410 DMA support. This is needed for drivers like sound which + use the S3C2410's DMA system to move data to and from the +@@ -111,4 +113,12 @@ + help + Common machine code for SMDK2410 and SMDK2440 + ++config MACH_NEO1973 ++ bool ++ select RFKILL ++ select SERIAL_SAMSUNG ++ select SERIAL_SAMSUNG_CONSOLE ++ help ++ Common machine code for Neo1973 hardware ++ + endif +diff -ruN --exclude='*.orig' --exclude='*.rej' linux-2.6.29-rc3.owrt/arch/arm/plat-s3c24xx/Makefile linux-2.6.29-rc3.owrt.om/arch/arm/plat-s3c24xx/Makefile +--- linux-2.6.29-rc3.owrt/arch/arm/plat-s3c24xx/Makefile 2009-05-10 22:05:03.000000000 +0200 ++++ linux-2.6.29-rc3.owrt.om/arch/arm/plat-s3c24xx/Makefile 2009-05-10 22:27:59.000000000 +0200 +@@ -27,6 +27,7 @@ + obj-$(CONFIG_CPU_S3C244X) += s3c244x-clock.o + obj-$(CONFIG_PM_SIMTEC) += pm-simtec.o + obj-$(CONFIG_PM) += pm.o ++obj-$(CONFIG_PM) += irq-pm.o + obj-$(CONFIG_PM) += sleep.o + obj-$(CONFIG_HAVE_PWM) += pwm.o + obj-$(CONFIG_S3C2410_CLOCK) += s3c2410-clock.o +@@ -44,3 +45,9 @@ + # machine common support + + obj-$(CONFIG_MACH_SMDK) += common-smdk.o ++obj-$(CONFIG_MACH_NEO1973) += \ ++ neo1973_pm_gsm.o \ ++ neo1973_pm_gps.o \ ++ neo1973_pm_bt.o \ ++ gta02_pm_wlan.o \ ++ neo1973_shadow.o +diff -ruN --exclude='*.orig' --exclude='*.rej' linux-2.6.29-rc3.owrt/arch/arm/plat-s3c24xx/neo1973_pm_bt.c linux-2.6.29-rc3.owrt.om/arch/arm/plat-s3c24xx/neo1973_pm_bt.c +--- linux-2.6.29-rc3.owrt/arch/arm/plat-s3c24xx/neo1973_pm_bt.c 1970-01-01 01:00:00.000000000 +0100 ++++ linux-2.6.29-rc3.owrt.om/arch/arm/plat-s3c24xx/neo1973_pm_bt.c 2009-05-10 22:27:59.000000000 +0200 +@@ -0,0 +1,339 @@ ++/* ++ * Bluetooth PM code for the FIC Neo1973 GSM Phone ++ * ++ * (C) 2007 by Openmoko Inc. ++ * Author: Harald Welte <laforge@openmoko.org> ++ * All rights reserved. ++ * ++ * 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/init.h> ++#include <linux/kernel.h> ++#include <linux/platform_device.h> ++#include <linux/rfkill.h> ++#include <linux/err.h> ++ ++#include <mach/hardware.h> ++#include <asm/mach-types.h> ++#include <asm/plat-s3c24xx/neo1973.h> ++ ++/* For GTA01 */ ++#include <mach/gta01.h> ++#include <linux/pcf50606.h> ++ ++/* For GTA02 */ ++#include <mach/gta02.h> ++#include <linux/mfd/pcf50633/gpio.h> ++ ++#include <linux/regulator/consumer.h> ++ ++#define DRVMSG "FIC Neo1973 Bluetooth Power Management" ++ ++struct gta01_pm_bt_data { ++ struct regulator *regulator; ++ struct rfkill *rfkill; ++ int pre_resume_state; ++}; ++ ++static ssize_t bt_read(struct device *dev, struct device_attribute *attr, ++ char *buf) ++{ ++ int ret = 0; ++ struct gta01_pm_bt_data *bt_data = dev_get_drvdata(dev); ++ ++ if (!strcmp(attr->attr.name, "power_on")) { ++ if (machine_is_neo1973_gta01()) { ++ ret = regulator_is_enabled(bt_data->regulator); ++ } else if (machine_is_neo1973_gta02()) { ++ if (s3c2410_gpio_getpin(GTA02_GPIO_BT_EN)) ++ ret = 1; ++ } ++ } else if (!strcmp(attr->attr.name, "reset")) { ++ if (machine_is_neo1973_gta01()) { ++ if (s3c2410_gpio_getpin(GTA01_GPIO_BT_EN) == 0) ++ ret = 1; ++ } else if (machine_is_neo1973_gta02()) { ++ if (s3c2410_gpio_getpin(GTA02_GPIO_BT_EN) == 0) ++ ret = 1; ++ } ++ } ++ ++ if (!ret) { ++ return strlcpy(buf, "0\n", 3); ++ } else { ++ return strlcpy(buf, "1\n", 3); ++ } ++} ++ ++static void __gta02_pm_bt_toggle_radio(struct device *dev, unsigned int on) ++{ ++ struct gta01_pm_bt_data *bt_data = dev_get_drvdata(dev); ++ ++ dev_info(dev, "__gta02_pm_bt_toggle_radio %d\n", on); ++ ++ if (machine_is_neo1973_gta02()) { ++ ++ bt_data = dev_get_drvdata(dev); ++ ++ neo1973_gpb_setpin(GTA02_GPIO_BT_EN, !on); ++ ++ if (on) { ++ if (!regulator_is_enabled(bt_data->regulator)) ++ regulator_enable(bt_data->regulator); ++ } else { ++ if (regulator_is_enabled(bt_data->regulator)) ++ regulator_disable(bt_data->regulator); ++ } ++ ++ neo1973_gpb_setpin(GTA02_GPIO_BT_EN, on); ++ } ++} ++ ++ ++static int bt_rfkill_toggle_radio(void *data, enum rfkill_state state) ++{ ++ struct device *dev = data; ++ unsigned long on = (state == RFKILL_STATE_ON); ++ struct gta01_pm_bt_data *bt_data = dev_get_drvdata(dev); ++ ++ if (machine_is_neo1973_gta01()) { ++ /* if we are powering up, assert reset, then power, ++ * then release reset */ ++ if (on) { ++ neo1973_gpb_setpin(GTA01_GPIO_BT_EN, 0); ++ if (!regulator_is_enabled(bt_data->regulator)) ++ regulator_enable(bt_data->regulator); ++ } else { ++ if (regulator_is_enabled(bt_data->regulator)) ++ regulator_disable(bt_data->regulator); ++ } ++ neo1973_gpb_setpin(GTA01_GPIO_BT_EN, on); ++ } else if (machine_is_neo1973_gta02()) ++ __gta02_pm_bt_toggle_radio(dev, on); ++ ++ return 0; ++} ++ ++static ssize_t bt_write(struct device *dev, struct device_attribute *attr, ++ const char *buf, size_t count) ++{ ++ unsigned long on = simple_strtoul(buf, NULL, 10); ++ struct gta01_pm_bt_data *bt_data = dev_get_drvdata(dev); ++ ++ if (!strcmp(attr->attr.name, "power_on")) { ++ enum rfkill_state state = on ? RFKILL_STATE_ON : RFKILL_STATE_OFF; ++ bt_rfkill_toggle_radio(dev, state); ++ bt_data->rfkill->state = state; ++ ++ if (machine_is_neo1973_gta01()) { ++ /* if we are powering up, assert reset, then power, ++ * then release reset */ ++ if (on) { ++ neo1973_gpb_setpin(GTA01_GPIO_BT_EN, 0); ++ if (!regulator_is_enabled(bt_data->regulator)) ++ regulator_enable(bt_data->regulator); ++ } else { ++ if (regulator_is_enabled(bt_data->regulator)) ++ regulator_disable(bt_data->regulator); ++ } ++ ++ neo1973_gpb_setpin(GTA01_GPIO_BT_EN, on); ++ } else if (machine_is_neo1973_gta02()) ++ __gta02_pm_bt_toggle_radio(dev, on); ++ ++ } else if (!strcmp(attr->attr.name, "reset")) { ++ /* reset is low-active, so we need to invert */ ++ if (machine_is_neo1973_gta01()) { ++ neo1973_gpb_setpin(GTA01_GPIO_BT_EN, on ? 0 : 1); ++ } else if (machine_is_neo1973_gta02()) { ++ neo1973_gpb_setpin(GTA02_GPIO_BT_EN, on ? 0 : 1); ++ } ++ } ++ ++ return count; ++} ++ ++static DEVICE_ATTR(power_on, 0644, bt_read, bt_write); ++static DEVICE_ATTR(reset, 0644, bt_read, bt_write); ++ ++#ifdef CONFIG_PM ++static int gta01_bt_suspend(struct platform_device *pdev, pm_message_t state) ++{ ++ struct gta01_pm_bt_data *bt_data = dev_get_drvdata(&pdev->dev); ++ ++ dev_dbg(&pdev->dev, DRVMSG ": suspending\n"); ++ ++ if (machine_is_neo1973_gta01()) { ++ if (regulator_is_enabled(bt_data->regulator)) ++ regulator_disable(bt_data->regulator); ++ } else if (machine_is_neo1973_gta02()) { ++ bt_data->pre_resume_state = ++ s3c2410_gpio_getpin(GTA02_GPIO_BT_EN); ++ __gta02_pm_bt_toggle_radio(&pdev->dev, 0); ++ } ++ ++ return 0; ++} ++ ++static int gta01_bt_resume(struct platform_device *pdev) ++{ ++ struct gta01_pm_bt_data *bt_data = dev_get_drvdata(&pdev->dev); ++ dev_dbg(&pdev->dev, DRVMSG ": resuming\n"); ++ ++ if (machine_is_neo1973_gta02()) { ++ __gta02_pm_bt_toggle_radio(&pdev->dev, ++ bt_data->pre_resume_state); ++ } ++ ++ return 0; ++} ++#else ++#define gta01_bt_suspend NULL ++#define gta01_bt_resume NULL ++#endif ++ ++static struct attribute *gta01_bt_sysfs_entries[] = { ++ &dev_attr_power_on.attr, ++ &dev_attr_reset.attr, ++ NULL ++}; ++ ++static struct attribute_group gta01_bt_attr_group = { ++ .name = NULL, ++ .attrs = gta01_bt_sysfs_entries, ++}; ++ ++static int __init gta01_bt_probe(struct platform_device *pdev) ++{ ++ struct rfkill *rfkill; ++ struct regulator *regulator; ++ struct gta01_pm_bt_data *bt_data; ++ int ret; ++ ++ dev_info(&pdev->dev, DRVMSG ": starting\n"); ++ ++ bt_data = kzalloc(sizeof(*bt_data), GFP_KERNEL); ++ dev_set_drvdata(&pdev->dev, bt_data); ++ ++ if (machine_is_neo1973_gta01()) { ++ /* we make sure that the voltage is off */ ++ regulator = regulator_get(&pdev->dev, "BT_3V1"); ++ if (IS_ERR(regulator)) ++ return -ENODEV; ++ ++ bt_data->regulator = regulator; ++ ++ /* this tests the true physical state of the regulator... */ ++ if (regulator_is_enabled(regulator)) { ++ /* ++ * but these only operate on the logical state of the ++ * regulator... so we need to logicaly "adopt" it on ++ * to turn it off ++ */ ++ regulator_enable(regulator); ++ regulator_disable(regulator); ++ } ++ ++ /* we pull reset to low to make sure that the chip doesn't ++ * drain power through the reset line */ ++ neo1973_gpb_setpin(GTA01_GPIO_BT_EN, 0); ++ } else if (machine_is_neo1973_gta02()) { ++ regulator = regulator_get(&pdev->dev, "BT_3V2"); ++ if (IS_ERR(regulator)) ++ return -ENODEV; ++ ++ bt_data->regulator = regulator; ++ ++ /* this tests the true physical state of the regulator... */ ++ if (regulator_is_enabled(regulator)) { ++ /* ++ * but these only operate on the logical state of the ++ * regulator... so we need to logicaly "adopt" it on ++ * to turn it off ++ */ ++ regulator_enable(regulator); ++ regulator_disable(regulator); ++ } ++ ++ /* we pull reset to low to make sure that the chip doesn't ++ * drain power through the reset line */ ++ neo1973_gpb_setpin(GTA02_GPIO_BT_EN, 0); ++ } ++ ++ rfkill = rfkill_allocate(&pdev->dev, RFKILL_TYPE_BLUETOOTH); ++ ++ rfkill->name = pdev->name; ++ rfkill->data = &pdev->dev; ++ rfkill->state = RFKILL_STATE_OFF; ++ rfkill->toggle_radio = bt_rfkill_toggle_radio; ++ ++ ret = rfkill_register(rfkill); ++ if (ret) { ++ dev_err(&pdev->dev, "Failed to register rfkill\n"); ++ return ret; ++ } ++ ++ bt_data->rfkill = rfkill; ++ ++ return sysfs_create_group(&pdev->dev.kobj, >a01_bt_attr_group); ++} ++ ++static int gta01_bt_remove(struct platform_device *pdev) ++{ ++ struct gta01_pm_bt_data *bt_data = dev_get_drvdata(&pdev->dev); ++ struct regulator *regulator; ++ ++ sysfs_remove_group(&pdev->dev.kobj, >a01_bt_attr_group); ++ ++ if (bt_data->rfkill) { ++ rfkill_unregister(bt_data->rfkill); ++ rfkill_free(bt_data->rfkill); ++ } ++ ++ if (!bt_data || !bt_data->regulator) ++ return 0; ++ ++ regulator = bt_data->regulator; ++ ++ /* Make sure regulator is disabled before calling regulator_put */ ++ if (regulator_is_enabled(regulator)) ++ regulator_disable(regulator); ++ ++ regulator_put(regulator); ++ ++ kfree(bt_data); ++ ++ return 0; ++} ++ ++static struct platform_driver gta01_bt_driver = { ++ .probe = gta01_bt_probe, ++ .remove = gta01_bt_remove, ++ .suspend = gta01_bt_suspend, ++ .resume = gta01_bt_resume, ++ .driver = { ++ .name = "neo1973-pm-bt", ++ }, ++}; ++ ++static int __devinit gta01_bt_init(void) ++{ ++ return platform_driver_register(>a01_bt_driver); ++} ++ ++static void gta01_bt_exit(void) ++{ ++ platform_driver_unregister(>a01_bt_driver); ++} ++ ++module_init(gta01_bt_init); ++module_exit(gta01_bt_exit); ++ ++MODULE_LICENSE("GPL"); ++MODULE_AUTHOR("Harald Welte <laforge@openmoko.org>"); ++MODULE_DESCRIPTION(DRVMSG); +diff -ruN --exclude='*.orig' --exclude='*.rej' linux-2.6.29-rc3.owrt/arch/arm/plat-s3c24xx/neo1973_pm_gps.c linux-2.6.29-rc3.owrt.om/arch/arm/plat-s3c24xx/neo1973_pm_gps.c +--- linux-2.6.29-rc3.owrt/arch/arm/plat-s3c24xx/neo1973_pm_gps.c 1970-01-01 01:00:00.000000000 +0100 ++++ linux-2.6.29-rc3.owrt.om/arch/arm/plat-s3c24xx/neo1973_pm_gps.c 2009-05-10 22:27:59.000000000 +0200 +@@ -0,0 +1,803 @@ ++/* ++ * GPS Power Management code for the FIC Neo1973 GSM Phone ++ * ++ * (C) 2007-2009 by Openmoko Inc. ++ * Author: Harald Welte <laforge@openmoko.org> ++ * All rights reserved. ++ * ++ * 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/init.h> ++#include <linux/kernel.h> ++#include <linux/delay.h> ++#include <linux/platform_device.h> ++ ++#include <mach/hardware.h> ++#include <mach/cpu.h> ++ ++#include <asm/mach-types.h> ++ ++#include <asm/plat-s3c24xx/neo1973.h> ++ ++/* For GTA01 */ ++#include <mach/gta01.h> ++#include <linux/mfd/pcf50606/core.h> ++#include <linux/mfd/pcf50606/gpo.h> ++ ++/* For GTA02 */ ++#include <mach/gta02.h> ++#include <linux/mfd/pcf50633/core.h> ++#include <linux/mfd/pcf50633/pmic.h> ++ ++#include <linux/regulator/consumer.h> ++#include <linux/err.h> ++ ++enum gta01_pm_gps_supplies { ++ ++ /* GTA01 */ ++ GTA01_GPS_REG_2V8, ++ GTA01_GPS_REG_3V, ++ GTA01_GPS_REG_3V3, ++ GTA01_GPS_REG_1V5, ++ GTA01_GPS_REG_2V5, ++ ++ /* GTA02 */ ++ GTA02_GPS_REG_RF_3V, ++ ++ /* Always last */ ++ GTA01_GPS_NUM_REG ++}; ++ ++struct neo1973_pm_gps_data { ++#ifdef CONFIG_PM ++ int keep_on_in_suspend; ++#endif ++ int power_was_on; /* For GTA02 only */ ++ int regulator_state[GTA01_GPS_NUM_REG]; ++ struct regulator *regulator[GTA01_GPS_NUM_REG]; ++}; ++ ++static struct neo1973_pm_gps_data neo1973_gps; ++ ++int neo1973_pm_gps_is_on(void) ++{ ++ return neo1973_gps.power_was_on; ++} ++EXPORT_SYMBOL_GPL(neo1973_pm_gps_is_on); ++ ++#ifdef CONFIG_MACH_NEO1973_GTA01 ++ ++/* This is the 2.8V supply for the RTC crystal, the mail clock crystal and ++ * the input to VDD_RF */ ++static void gps_power_2v8_set(int on) ++{ ++ struct regulator *regulator = neo1973_gps.regulator[GTA01_GPS_REG_2V8]; ++ ++ switch (S3C_SYSTEM_REV_ATAG) { ++ case GTA01v3_SYSTEM_REV: ++ case GTA01v4_SYSTEM_REV: ++ if (on) ++ regulator_enable(regulator); ++ else ++ regulator_disable(regulator); ++ neo1973_gps.regulator_state[GTA01_GPS_REG_2V8] = on; ++ break; ++ case GTA01Bv2_SYSTEM_REV: ++ s3c2410_gpio_setpin(GTA01_GPIO_GPS_EN_2V8, on); ++ break; ++ case GTA01Bv3_SYSTEM_REV: ++ case GTA01Bv4_SYSTEM_REV: ++ break; ++ } ++} ++ ++static int gps_power_2v8_get(void) ++{ ++ int ret = 0; ++ struct regulator *regulator = neo1973_gps.regulator[GTA01_GPS_REG_2V8]; ++ ++ switch (S3C_SYSTEM_REV_ATAG) { ++ case GTA01v3_SYSTEM_REV: ++ case GTA01v4_SYSTEM_REV: ++ ret = regulator_is_enabled(regulator); ++ break; ++ case GTA01Bv2_SYSTEM_REV: ++ if (s3c2410_gpio_getpin(GTA01_GPIO_GPS_EN_2V8)) ++ ret = 1; ++ break; ++ case GTA01Bv3_SYSTEM_REV: ++ case GTA01Bv4_SYSTEM_REV: ++ break; ++ } ++ ++ return ret; ++} ++ ++/* This is the 3V supply (AVDD) for the external RF frontend (LNA bias) */ ++static void gps_power_3v_set(int on) ++{ ++ struct regulator *regulator = neo1973_gps.regulator[GTA01_GPS_REG_3V]; ++ ++ switch (S3C_SYSTEM_REV_ATAG) { ++ case GTA01v3_SYSTEM_REV: ++ case GTA01v4_SYSTEM_REV: ++ if (on) ++ regulator_enable(regulator); ++ else ++ regulator_disable(regulator); ++ neo1973_gps.regulator_state[GTA01_GPS_REG_3V] = on; ++ break; ++ case GTA01Bv2_SYSTEM_REV: ++ case GTA01Bv3_SYSTEM_REV: ++ case GTA01Bv4_SYSTEM_REV: ++ s3c2410_gpio_setpin(GTA01_GPIO_GPS_EN_3V, on); ++ break; ++ } ++} ++ ++static int gps_power_3v_get(void) ++{ ++ int ret = 0; ++ struct regulator *regulator = neo1973_gps.regulator[GTA01_GPS_REG_3V]; ++ ++ switch (S3C_SYSTEM_REV_ATAG) { ++ case GTA01v3_SYSTEM_REV: ++ case GTA01v4_SYSTEM_REV: ++ ret = regulator_is_enabled(regulator); ++ break; ++ case GTA01Bv2_SYSTEM_REV: ++ case GTA01Bv3_SYSTEM_REV: ++ case GTA01Bv4_SYSTEM_REV: ++ if (s3c2410_gpio_getpin(GTA01_GPIO_GPS_EN_3V)) ++ ret = 1; ++ break; ++ } ++ ++ return ret; ++} ++ ++/* This is the 3.3V supply for VDD_IO and VDD_LPREG input */ ++static void gps_power_3v3_set(int on) ++{ ++ struct regulator *regulator = neo1973_gps.regulator[GTA01_GPS_REG_3V3]; ++ ++ switch (S3C_SYSTEM_REV_ATAG) { ++ case GTA01v3_SYSTEM_REV: ++ case GTA01v4_SYSTEM_REV: ++ case GTA01Bv2_SYSTEM_REV: ++ if (on) ++ regulator_enable(regulator); ++ else ++ regulator_disable(regulator); ++ neo1973_gps.regulator_state[GTA01_GPS_REG_3V3] = on; ++ break; ++ case GTA01Bv3_SYSTEM_REV: ++ case GTA01Bv4_SYSTEM_REV: ++ s3c2410_gpio_setpin(GTA01_GPIO_GPS_EN_3V3, on); ++ break; ++ } ++} ++ ++static int gps_power_3v3_get(void) ++{ ++ int ret = 0; ++ struct regulator *regulator = neo1973_gps.regulator[GTA01_GPS_REG_3V3]; ++ ++ switch (S3C_SYSTEM_REV_ATAG) { ++ case GTA01v3_SYSTEM_REV: ++ case GTA01v4_SYSTEM_REV: ++ case GTA01Bv2_SYSTEM_REV: ++ ret = regulator_is_enabled(regulator); ++ break; ++ case GTA01Bv3_SYSTEM_REV: ++ case GTA01Bv4_SYSTEM_REV: ++ if (s3c2410_gpio_getpin(GTA01_GPIO_GPS_EN_3V3)) ++ ret = 1; ++ break; ++ } ++ ++ return ret; ++} ++ ++/* This is the 2.5V supply for VDD_PLLREG and VDD_COREREG input */ ++static void gps_power_2v5_set(int on) ++{ ++ struct regulator *regulator = neo1973_gps.regulator[GTA01_GPS_REG_2V5]; ++ ++ switch (S3C_SYSTEM_REV_ATAG) { ++ case GTA01v3_SYSTEM_REV: ++ /* This is CORE_1V8 and cannot be disabled */ ++ break; ++ case GTA01v4_SYSTEM_REV: ++ case GTA01Bv2_SYSTEM_REV: ++ case GTA01Bv3_SYSTEM_REV: ++ case GTA01Bv4_SYSTEM_REV: ++ if (on) ++ regulator_enable(regulator); ++ else ++ regulator_disable(regulator); ++ neo1973_gps.regulator_state[GTA01_GPS_REG_2V5] = on; ++ break; ++ } ++} ++ ++static int gps_power_2v5_get(void) ++{ ++ int ret = 0; ++ struct regulator *regulator = neo1973_gps.regulator[GTA01_GPS_REG_2V5]; ++ ++ switch (S3C_SYSTEM_REV_ATAG) { ++ case GTA01v3_SYSTEM_REV: ++ /* This is CORE_1V8 and cannot be disabled */ ++ ret = 1; ++ break; ++ case GTA01v4_SYSTEM_REV: ++ case GTA01Bv2_SYSTEM_REV: ++ case GTA01Bv3_SYSTEM_REV: ++ case GTA01Bv4_SYSTEM_REV: ++ ret = regulator_is_enabled(regulator); ++ break; ++ } ++ ++ return ret; ++} ++ ++/* This is the 1.5V supply for VDD_CORE */ ++static void gps_power_1v5_set(int on) ++{ ++ struct regulator *regulator = neo1973_gps.regulator[GTA01_GPS_REG_1V5]; ++ ++ switch (S3C_SYSTEM_REV_ATAG) { ++ case GTA01v3_SYSTEM_REV: ++ case GTA01v4_SYSTEM_REV: ++ case GTA01Bv2_SYSTEM_REV: ++ /* This is switched via 2v5 */ ++ break; ++ case GTA01Bv3_SYSTEM_REV: ++ case GTA01Bv4_SYSTEM_REV: ++ if (on) ++ regulator_enable(regulator); ++ else ++ regulator_disable(regulator); ++ neo1973_gps.regulator_state[GTA01_GPS_REG_1V5] = on; ++ break; ++ } ++} ++ ++static int gps_power_1v5_get(void) ++{ ++ int ret = 0; ++ struct regulator *regulator = neo1973_gps.regulator[GTA01_GPS_REG_1V5]; ++ ++ switch (S3C_SYSTEM_REV_ATAG) { ++ case GTA01v3_SYSTEM_REV: ++ case GTA01v4_SYSTEM_REV: ++ case GTA01Bv2_SYSTEM_REV: ++ /* This is switched via 2v5 */ ++ ret = 1; ++ break; ++ case GTA01Bv3_SYSTEM_REV: ++ case GTA01Bv4_SYSTEM_REV: ++ ret = regulator_is_enabled(regulator); ++ break; ++ } ++ ++ return ret; ++} ++#endif ++ ++/* This is the POWERON pin */ ++static void gps_pwron_set(int on) ++{ ++ ++ if (machine_is_neo1973_gta01()) ++ neo1973_gpb_setpin(GTA01_GPIO_GPS_PWRON, on); ++ ++ if (machine_is_neo1973_gta02()) { ++ if (on) { ++ /* return UART pins to being UART pins */ ++ s3c2410_gpio_cfgpin(S3C2410_GPH4, S3C2410_GPH4_TXD1); ++ /* remove pulldown now it won't be floating any more */ ++ s3c2410_gpio_pullup(S3C2410_GPH5, 0); ++ ++ if (!neo1973_gps.power_was_on) ++ regulator_enable(neo1973_gps.regulator[ ++ GTA02_GPS_REG_RF_3V]); ++ return; ++ } ++ ++ /* ++ * take care not to power unpowered GPS from UART TX ++ * return them to GPIO and force low ++ */ ++ s3c2410_gpio_cfgpin(S3C2410_GPH4, S3C2410_GPH4_OUTP); ++ s3c2410_gpio_setpin(S3C2410_GPH4, 0); ++ /* don't let RX from unpowered GPS float */ ++ s3c2410_gpio_pullup(S3C2410_GPH5, 1); ++ if (neo1973_gps.power_was_on) ++ regulator_disable(neo1973_gps.regulator[ ++ GTA02_GPS_REG_RF_3V]); ++ } ++} ++ ++static int gps_pwron_get(void) ++{ ++ if (machine_is_neo1973_gta01()) ++ return !!s3c2410_gpio_getpin(GTA01_GPIO_GPS_PWRON); ++ ++ if (machine_is_neo1973_gta02()) ++ return regulator_is_enabled(neo1973_gps.regulator[GTA02_GPS_REG_RF_3V]); ++ return -1; ++} ++ ++ ++#ifdef CONFIG_MACH_NEO1973_GTA01 ++static void gps_rst_set(int on); ++static int gps_rst_get(void); ++#endif ++ ++#ifdef CONFIG_PM ++/* This is the flag for keeping gps ON during suspend */ ++static void gps_keep_on_in_suspend_set(int on) ++{ ++ neo1973_gps.keep_on_in_suspend = on; ++} ++ ++static int gps_keep_on_in_suspend_get(void) ++{ ++ return neo1973_gps.keep_on_in_suspend; ++} ++#endif ++ ++static ssize_t power_gps_read(struct device *dev, ++ struct device_attribute *attr, char *buf) ++{ ++ int ret = 0; ++ ++ if (!strcmp(attr->attr.name, "power_on") || ++ !strcmp(attr->attr.name, "pwron")) { ++ ret = gps_pwron_get(); ++#ifdef CONFIG_PM ++ } else if (!strcmp(attr->attr.name, "keep_on_in_suspend")) { ++ ret = gps_keep_on_in_suspend_get(); ++#endif ++#ifdef CONFIG_MACH_NEO1973_GTA01 ++ } else if (!strcmp(attr->attr.name, "power_avdd_3v")) { ++ ret = gps_power_3v_get(); ++ } else if (!strcmp(attr->attr.name, "power_tcxo_2v8")) { ++ ret = gps_power_2v8_get(); ++ } else if (!strcmp(attr->attr.name, "reset")) { ++ ret = gps_rst_get(); ++ } else if (!strcmp(attr->attr.name, "power_lp_io_3v3")) { ++ ret = gps_power_3v3_get(); ++ } else if (!strcmp(attr->attr.name, "power_pll_core_2v5")) { ++ ret = gps_power_2v5_get(); ++ } else if (!strcmp(attr->attr.name, "power_core_1v5") || ++ !strcmp(attr->attr.name, "power_vdd_core_1v5")) { ++ ret = gps_power_1v5_get(); ++#endif ++ } ++ if (ret) ++ return strlcpy(buf, "1\n", 3); ++ else ++ return strlcpy(buf, "0\n", 3); ++} ++ ++static ssize_t power_gps_write(struct device *dev, ++ struct device_attribute *attr, const char *buf, ++ size_t count) ++{ ++ unsigned long on = simple_strtoul(buf, NULL, 10); ++ ++ if (!strcmp(attr->attr.name, "power_on") || ++ !strcmp(attr->attr.name, "pwron")) { ++ gps_pwron_set(on); ++ neo1973_gps.power_was_on = !!on; ++#ifdef CONFIG_PM ++ } else if (!strcmp(attr->attr.name, "keep_on_in_suspend")) { ++ gps_keep_on_in_suspend_set(on); ++#endif ++#ifdef CONFIG_MACH_NEO1973_GTA01 ++ } else if (!strcmp(attr->attr.name, "power_avdd_3v")) { ++ gps_power_3v_set(on); ++ } else if (!strcmp(attr->attr.name, "power_tcxo_2v8")) { ++ gps_power_2v8_set(on); ++ } else if (!strcmp(attr->attr.name, "reset")) { ++ gps_rst_set(on); ++ } else if (!strcmp(attr->attr.name, "power_lp_io_3v3")) { ++ gps_power_3v3_set(on); ++ } else if (!strcmp(attr->attr.name, "power_pll_core_2v5")) { ++ gps_power_2v5_set(on); ++ } else if (!strcmp(attr->attr.name, "power_core_1v5") || ++ !strcmp(attr->attr.name, "power_vdd_core_1v5")) { ++ gps_power_1v5_set(on); ++#endif ++ } ++ return count; ++} ++ ++ ++#ifdef CONFIG_MACH_NEO1973_GTA01 ++ ++/* This is the nRESET pin */ ++static void gps_rst_set(int on) ++{ ++ switch (S3C_SYSTEM_REV_ATAG) { ++ case GTA01v3_SYSTEM_REV: ++ pcf50606_gpo_set_active(gta01_pcf, PCF50606_GPO1, on); ++ break; ++ case GTA01v4_SYSTEM_REV: ++ case GTA01Bv2_SYSTEM_REV: ++ case GTA01Bv3_SYSTEM_REV: ++ case GTA01Bv4_SYSTEM_REV: ++ s3c2410_gpio_setpin(GTA01_GPIO_GPS_RESET, on); ++ break; ++ } ++} ++ ++static int gps_rst_get(void) ++{ ++ switch (S3C_SYSTEM_REV_ATAG) { ++ case GTA01v3_SYSTEM_REV: ++ return pcf50606_gpo_get_active(gta01_pcf, PCF50606_GPO1); ++ break; ++ case GTA01v4_SYSTEM_REV: ++ case GTA01Bv2_SYSTEM_REV: ++ case GTA01Bv3_SYSTEM_REV: ++ case GTA01Bv4_SYSTEM_REV: ++ if (s3c2410_gpio_getpin(GTA01_GPIO_GPS_RESET)) ++ return 1; ++ break; ++ } ++ ++ return 0; ++} ++ ++ ++static void gps_power_sequence_up(void) ++{ ++ /* According to PMB2520 Data Sheet, Rev. 2006-06-05, ++ * Chapter 4.2.2 */ ++ ++ /* nRESET must be asserted low */ ++ gps_rst_set(0); ++ ++ /* POWERON must be de-asserted (low) */ ++ gps_pwron_set(0); ++ ++ /* Apply VDD_IO and VDD_LPREG_IN */ ++ gps_power_3v3_set(1); ++ ++ /* VDD_COREREG_IN, VDD_PLLREG_IN */ ++ gps_power_1v5_set(1); ++ gps_power_2v5_set(1); ++ ++ /* and VDD_RF may be applied */ ++ gps_power_2v8_set(1); ++ ++ /* We need to enable AVDD, since in GTA01Bv3 it is ++ * shared with RFREG_IN */ ++ gps_power_3v_set(1); ++ ++ msleep(3); /* Is 3ms enough? */ ++ ++ /* De-asert nRESET */ ++ gps_rst_set(1); ++ ++ /* Switch power on */ ++ gps_pwron_set(1); ++ ++} ++ ++static void gps_power_sequence_down(void) ++{ ++ /* According to PMB2520 Data Sheet, Rev. 2006-06-05, ++ * Chapter 4.2.3.1 */ ++ gps_pwron_set(0); ++ ++ /* Don't disable AVDD before PWRON is cleared, since ++ * in GTA01Bv3, AVDD and RFREG_IN are shared */ ++ if (neo1973_gps.regulator_state[GTA01_GPS_REG_3V]) ++ gps_power_3v_set(0); ++ ++ /* Remove VDD_COREREG_IN, VDD_PLLREG_IN and VDD_REFREG_IN */ ++ if (neo1973_gps.regulator_state[GTA01_GPS_REG_1V5]) ++ gps_power_1v5_set(0); ++ if (neo1973_gps.regulator_state[GTA01_GPS_REG_2V5]) ++ gps_power_2v5_set(0); ++ if (neo1973_gps.regulator_state[GTA01_GPS_REG_2V8]) ++ gps_power_2v8_set(0); ++ ++ /* Remove VDD_LPREG_IN and VDD_IO */ ++ if (neo1973_gps.regulator_state[GTA01_GPS_REG_3V3]) ++ gps_power_3v3_set(0); ++ ++} ++ ++static ssize_t power_sequence_read(struct device *dev, ++ struct device_attribute *attr, ++ char *buf) ++{ ++ return strlcpy(buf, "power_up power_down\n", PAGE_SIZE); ++} ++ ++static ssize_t power_sequence_write(struct device *dev, ++ struct device_attribute *attr, ++ const char *buf, size_t count) ++{ ++ dev_dbg(dev, "wrote: '%s'\n", buf); ++ ++ if (!strncmp(buf, "power_up", 8)) ++ gps_power_sequence_up(); ++ else if (!strncmp(buf, "power_down", 10)) ++ gps_power_sequence_down(); ++ else ++ return -EINVAL; ++ ++ return count; ++} ++ ++static DEVICE_ATTR(power_tcxo_2v8, 0644, power_gps_read, power_gps_write); ++static DEVICE_ATTR(power_avdd_3v, 0644, power_gps_read, power_gps_write); ++static DEVICE_ATTR(reset, 0644, power_gps_read, power_gps_write); ++static DEVICE_ATTR(power_lp_io_3v3, 0644, power_gps_read, power_gps_write); ++static DEVICE_ATTR(power_pll_core_2v5, 0644, power_gps_read, power_gps_write); ++static DEVICE_ATTR(power_core_1v5, 0644, power_gps_read, power_gps_write); ++static DEVICE_ATTR(power_vdd_core_1v5, 0644, power_gps_read, power_gps_write); ++static DEVICE_ATTR(power_sequence, 0644, power_sequence_read, ++ power_sequence_write); ++#endif ++ ++#ifdef CONFIG_PM ++static int gta01_pm_gps_suspend(struct platform_device *pdev, ++ pm_message_t state) ++{ ++#ifdef CONFIG_MACH_NEO1973_GTA01 ++ if (machine_is_neo1973_gta01()) ++ /* FIXME */ ++ gps_power_sequence_down(); ++#endif ++ if (machine_is_neo1973_gta02()) { ++ if (!neo1973_gps.keep_on_in_suspend || ++ !neo1973_gps.power_was_on) ++ gps_pwron_set(0); ++ else ++ dev_warn(&pdev->dev, "GTA02: keeping gps ON " ++ "during suspend\n"); ++ } ++ ++ return 0; ++} ++ ++static int gta01_pm_gps_resume(struct platform_device *pdev) ++{ ++#ifdef CONFIG_MACH_NEO1973_GTA01 ++ if (machine_is_neo1973_gta01()) ++ if (neo1973_gps.power_was_on) ++ gps_power_sequence_up(); ++#endif ++ if (machine_is_neo1973_gta02()) ++ if (!neo1973_gps.keep_on_in_suspend && neo1973_gps.power_was_on) ++ gps_pwron_set(1); ++ ++ return 0; ++} ++ ++static DEVICE_ATTR(keep_on_in_suspend, 0644, power_gps_read, power_gps_write); ++#else ++#define gta01_pm_gps_suspend NULL ++#define gta01_pm_gps_resume NULL ++#endif ++ ++static DEVICE_ATTR(power_on, 0644, power_gps_read, power_gps_write); ++static DEVICE_ATTR(pwron, 0644, power_gps_read, power_gps_write); ++ ++ ++static struct attribute *gta01_gps_sysfs_entries[] = { ++ &dev_attr_power_on.attr, ++ &dev_attr_pwron.attr, ++#ifdef CONFIG_MACH_NEO1973_GTA01 ++ &dev_attr_power_avdd_3v.attr, ++ &dev_attr_reset.attr, ++ &dev_attr_power_lp_io_3v3.attr, ++ &dev_attr_power_pll_core_2v5.attr, ++ &dev_attr_power_sequence.attr, ++ NULL, /* power_core_1v5 */ ++ NULL, /* power_vdd_core_1v5 */ ++#endif ++ NULL /* terminating entry */ ++}; ++ ++static struct attribute_group gta01_gps_attr_group = { ++ .name = NULL, ++ .attrs = gta01_gps_sysfs_entries, ++}; ++ ++static struct attribute *gta02_gps_sysfs_entries[] = { ++ &dev_attr_power_on.attr, ++#ifdef CONFIG_PM ++ &dev_attr_keep_on_in_suspend.attr, ++#endif ++ NULL ++}; ++ ++static struct attribute_group gta02_gps_attr_group = { ++ .name = NULL, ++ .attrs = gta02_gps_sysfs_entries, ++}; ++ ++static int __init gta01_pm_gps_probe(struct platform_device *pdev) ++{ ++ int ret; ++#ifdef CONFIG_MACH_NEO1973_GTA01 ++ int entries = ARRAY_SIZE(gta01_gps_sysfs_entries); ++#endif ++ ++ if (machine_is_neo1973_gta01()) { ++ s3c2410_gpio_cfgpin(GTA01_GPIO_GPS_PWRON, S3C2410_GPIO_OUTPUT); ++ ++ switch (S3C_SYSTEM_REV_ATAG) { ++ case GTA01v3_SYSTEM_REV: ++ break; ++ case GTA01v4_SYSTEM_REV: ++ s3c2410_gpio_cfgpin(GTA01_GPIO_GPS_RESET, ++ S3C2410_GPIO_OUTPUT); ++ break; ++ case GTA01Bv3_SYSTEM_REV: ++ case GTA01Bv4_SYSTEM_REV: ++ s3c2410_gpio_cfgpin(GTA01_GPIO_GPS_EN_3V3, ++ S3C2410_GPIO_OUTPUT); ++ /* fallthrough */ ++ case GTA01Bv2_SYSTEM_REV: ++ s3c2410_gpio_cfgpin(GTA01_GPIO_GPS_EN_2V8, ++ S3C2410_GPIO_OUTPUT); ++ s3c2410_gpio_cfgpin(GTA01_GPIO_GPS_EN_3V, ++ S3C2410_GPIO_OUTPUT); ++ s3c2410_gpio_cfgpin(GTA01_GPIO_GPS_RESET, ++ S3C2410_GPIO_OUTPUT); ++ break; ++ default: ++ dev_warn(&pdev->dev, "Unknown GTA01 Revision 0x%x, " ++ "AGPS PM features not available!!!\n", ++ system_rev); ++ return -1; ++ break; ++ } ++ ++#ifdef CONFIG_MACH_NEO1973_GTA01 ++ ++ neo1973_gps.regulator[GTA01_GPS_REG_2V8] = ++ regulator_get(&pdev->dev, "GPS_2V8"); ++ neo1973_gps.regulator[GTA01_GPS_REG_3V] = ++ regulator_get(&pdev->dev, "GPS_3V"); ++ neo1973_gps.regulator[GTA01_GPS_REG_3V3] = ++ regulator_get(&pdev->dev, "GPS_3V3"); ++ neo1973_gps.regulator[GTA01_GPS_REG_1V5] = ++ regulator_get(&pdev->dev, "GPS_1V5"); ++ neo1973_gps.regulator[GTA01_GPS_REG_2V5] = ++ regulator_get(&pdev->dev, "GPS_2V5"); ++ ++ gps_power_sequence_down(); ++ ++ switch (S3C_SYSTEM_REV_ATAG) { ++ case GTA01v3_SYSTEM_REV: ++ case GTA01v4_SYSTEM_REV: ++ case GTA01Bv2_SYSTEM_REV: ++ gta01_gps_sysfs_entries[entries-3] = ++ &dev_attr_power_tcxo_2v8.attr; ++ break; ++ case GTA01Bv3_SYSTEM_REV: ++ case GTA01Bv4_SYSTEM_REV: ++ gta01_gps_sysfs_entries[entries-3] = ++ &dev_attr_power_core_1v5.attr; ++ gta01_gps_sysfs_entries[entries-2] = ++ &dev_attr_power_vdd_core_1v5.attr; ++ break; ++ } ++#endif ++ ret = sysfs_create_group(&pdev->dev.kobj, ++ >a01_gps_attr_group); ++ if (ret) ++ return ret; ++ return bus_create_device_link(&platform_bus_type, ++ &pdev->dev.kobj, "gta01-pm-gps.0"); ++ } ++ ++ if (machine_is_neo1973_gta02()) { ++ ++ neo1973_gps.regulator[GTA02_GPS_REG_RF_3V] = regulator_get( ++ &pdev->dev, "RF_3V"); ++ if (IS_ERR(neo1973_gps.regulator)) { ++ dev_err(&pdev->dev, "probe failed %ld\n", ++ PTR_ERR(neo1973_gps.regulator)); ++ ++ return PTR_ERR(neo1973_gps.regulator); ++ } ++ ++ dev_info(&pdev->dev, "starting\n"); ++ ++ /* ++ * Here we should call the code that handles the set GPS power ++ * off action. But, the regulator API does not allow us to ++ * reassert regulator state, and when we read the regulator API ++ * logical state, it can differ from the actual state, So ++ * a workaround for this is to just set the regulator off in the ++ * PMU directly. Because that's different from normal flow, we ++ * have to reproduce other things from the OFF action here too. ++ */ ++ ++ /* ++ * u-boot enables LDO5 (GPS), which doesn't make sense and ++ * causes confusion. We therefore disable the regulator here. ++ */ ++ pcf50633_reg_write(gta02_pcf, PCF50633_REG_LDO5ENA, 0); ++ ++ /* ++ * take care not to power unpowered GPS from UART TX ++ * return them to GPIO and force low ++ */ ++ s3c2410_gpio_cfgpin(S3C2410_GPH4, S3C2410_GPH4_OUTP); ++ s3c2410_gpio_setpin(S3C2410_GPH4, 0); ++ /* don't let RX from unpowered GPS float */ ++ s3c2410_gpio_pullup(S3C2410_GPH5, 1); ++ ++ return sysfs_create_group(&pdev->dev.kobj, ++ >a02_gps_attr_group); ++ } ++ return -1; ++} ++ ++static int gta01_pm_gps_remove(struct platform_device *pdev) ++{ ++ if (machine_is_neo1973_gta01()) { ++#ifdef CONFIG_MACH_NEO1973_GTA01 ++ int i; ++ ++ gps_power_sequence_down(); ++ /* Now disable all regulators */ ++ for (i = 0; i < GTA01_GPS_NUM_REG; i++) { ++ regulator_put(neo1973_gps.regulator[i]); ++ } ++#endif ++ bus_remove_device_link(&platform_bus_type, "gta01-pm-gps.0"); ++ sysfs_remove_group(&pdev->dev.kobj, >a01_gps_attr_group); ++ } ++ ++ if (machine_is_neo1973_gta02()) { ++ regulator_put(neo1973_gps.regulator[GTA02_GPS_REG_RF_3V]); ++ sysfs_remove_group(&pdev->dev.kobj, >a02_gps_attr_group); ++ } ++ return 0; ++} ++ ++static struct platform_driver gta01_pm_gps_driver = { ++ .probe = gta01_pm_gps_probe, ++ .remove = gta01_pm_gps_remove, ++ .suspend = gta01_pm_gps_suspend, ++ .resume = gta01_pm_gps_resume, ++ .driver = { ++ .name = "neo1973-pm-gps", ++ }, ++}; ++ ++static int __devinit gta01_pm_gps_init(void) ++{ ++ return platform_driver_register(>a01_pm_gps_driver); ++} ++ ++static void gta01_pm_gps_exit(void) ++{ ++ platform_driver_unregister(>a01_pm_gps_driver); ++} ++ ++module_init(gta01_pm_gps_init); ++module_exit(gta01_pm_gps_exit); ++ ++MODULE_LICENSE("GPL"); ++MODULE_AUTHOR("Harald Welte <laforge@openmoko.org>"); ++MODULE_DESCRIPTION("FIC Neo1973 GPS Power Management"); +diff -ruN --exclude='*.orig' --exclude='*.rej' linux-2.6.29-rc3.owrt/arch/arm/plat-s3c24xx/neo1973_pm_gps.h linux-2.6.29-rc3.owrt.om/arch/arm/plat-s3c24xx/neo1973_pm_gps.h +--- linux-2.6.29-rc3.owrt/arch/arm/plat-s3c24xx/neo1973_pm_gps.h 1970-01-01 01:00:00.000000000 +0100 ++++ linux-2.6.29-rc3.owrt.om/arch/arm/plat-s3c24xx/neo1973_pm_gps.h 2009-05-10 22:27:59.000000000 +0200 +@@ -0,0 +1 @@ ++extern int neo1973_pm_gps_is_on(void); +diff -ruN --exclude='*.orig' --exclude='*.rej' linux-2.6.29-rc3.owrt/arch/arm/plat-s3c24xx/neo1973_pm_gsm.c linux-2.6.29-rc3.owrt.om/arch/arm/plat-s3c24xx/neo1973_pm_gsm.c +--- linux-2.6.29-rc3.owrt/arch/arm/plat-s3c24xx/neo1973_pm_gsm.c 1970-01-01 01:00:00.000000000 +0100 ++++ linux-2.6.29-rc3.owrt.om/arch/arm/plat-s3c24xx/neo1973_pm_gsm.c 2009-05-10 22:27:59.000000000 +0200 +@@ -0,0 +1,380 @@ ++/* ++ * GSM Management code for the FIC Neo1973 GSM Phone ++ * ++ * (C) 2007 by Openmoko Inc. ++ * Author: Harald Welte <laforge@openmoko.org> ++ * All rights reserved. ++ * ++ * 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/init.h> ++#include <linux/kernel.h> ++#include <linux/platform_device.h> ++#include <linux/console.h> ++#include <linux/errno.h> ++#include <linux/interrupt.h> ++#include <linux/delay.h> ++ ++#include <mach/gpio.h> ++#include <asm/mach-types.h> ++#include <mach/gta01.h> ++#include <asm/plat-s3c24xx/neo1973.h> ++#include <mach/s3c24xx-serial.h> ++ ++#include <mach/hardware.h> ++#include <mach/cpu.h> ++ ++/* For GTA02 */ ++#include <mach/gta02.h> ++#include <linux/mfd/pcf50633/gpio.h> ++#include <mach/regs-gpio.h> ++#include <mach/regs-gpioj.h> ++ ++int gta_gsm_interrupts; ++EXPORT_SYMBOL(gta_gsm_interrupts); ++ ++extern void s3c24xx_serial_console_set_silence(int); ++ ++struct gta01pm_priv { ++ int gpio_ngsm_en; ++ int gpio_ndl_gsm; ++ ++ struct console *con; ++}; ++ ++static struct gta01pm_priv gta01_gsm; ++ ++static struct console *find_s3c24xx_console(void) ++{ ++ struct console *con; ++ ++ acquire_console_sem(); ++ ++ for (con = console_drivers; con; con = con->next) { ++ if (!strcmp(con->name, "ttySAC")) ++ break; ++ } ++ ++ release_console_sem(); ++ ++ return con; ++} ++ ++static ssize_t gsm_read(struct device *dev, struct device_attribute *attr, ++ char *buf) ++{ ++ if (!strcmp(attr->attr.name, "power_on")) { ++ if (gta01_gsm.gpio_ngsm_en) { ++ if (!s3c2410_gpio_getpin(gta01_gsm.gpio_ngsm_en)) ++ goto out_1; ++ } else if (machine_is_neo1973_gta02()) ++ if (pcf50633_gpio_get(gta02_pcf, PCF50633_GPIO2)) ++ goto out_1; ++ } else if (!strcmp(attr->attr.name, "download")) { ++ if (machine_is_neo1973_gta01()) { ++ if (s3c2410_gpio_getpin(GTA01_GPIO_MODEM_DNLOAD)) ++ goto out_1; ++ } else if (machine_is_neo1973_gta02()) { ++ if (!s3c2410_gpio_getpin(GTA02_GPIO_nDL_GSM)) ++ goto out_1; ++ } ++ } else if (!strcmp(attr->attr.name, "flowcontrolled")) { ++ if (s3c2410_gpio_getcfg(S3C2410_GPH1) == S3C2410_GPIO_OUTPUT) ++ goto out_1; ++ } ++ ++ return strlcpy(buf, "0\n", 3); ++out_1: ++ return strlcpy(buf, "1\n", 3); ++} ++ ++static void gsm_on_off(struct device *dev, int on) ++{ ++ if (!on) { ++ if (machine_is_neo1973_gta02()) { ++ /* ++ * Do not drive into powered-down GSM side ++ * GTA02 only, because on GTA01 maybe serial ++ * is used otherwise. ++ */ ++ s3c2410_gpio_cfgpin(S3C2410_GPH1, S3C2410_GPIO_INPUT); ++ s3c2410_gpio_cfgpin(S3C2410_GPH2, S3C2410_GPIO_INPUT); ++ ++ pcf50633_gpio_set(gta02_pcf, PCF50633_GPIO2, 0); ++ } ++ ++ if (gta01_gsm.gpio_ngsm_en) ++ s3c2410_gpio_setpin(gta01_gsm.gpio_ngsm_en, 1); ++ ++ if (gta01_gsm.con) { ++ s3c24xx_serial_console_set_silence(0); ++ console_start(gta01_gsm.con); ++ ++ dev_dbg(dev, "powered down GTA01 GSM, enabling " ++ "serial console\n"); ++ } ++ ++ return; ++ } ++ ++ if (gta01_gsm.con) { ++ dev_dbg(dev, "powering up GSM, thus " ++ "disconnecting serial console\n"); ++ ++ console_stop(gta01_gsm.con); ++ s3c24xx_serial_console_set_silence(1); ++ } ++ ++ /* allow UART to talk to GSM side now we will power it */ ++ s3c2410_gpio_cfgpin(S3C2410_GPH1, S3C2410_GPH1_nRTS0); ++ s3c2410_gpio_cfgpin(S3C2410_GPH2, S3C2410_GPH2_TXD0); ++ ++ if (gta01_gsm.gpio_ngsm_en) ++ s3c2410_gpio_setpin(gta01_gsm.gpio_ngsm_en, 0); ++ ++ if (machine_is_neo1973_gta02()) ++ pcf50633_gpio_set(gta02_pcf, PCF50633_GPIO2, 7); ++ ++ msleep(100); ++ ++ neo1973_gpb_setpin(GTA01_GPIO_MODEM_ON, 1); ++ msleep(500); ++ neo1973_gpb_setpin(GTA01_GPIO_MODEM_ON, 0); ++ ++ /* ++ * workaround for calypso firmware moko10 and earlier, ++ * without this it will leave IRQ line high after ++ * booting ++ */ ++ s3c2410_gpio_setpin(S3C2410_GPH1, 1); ++ s3c2410_gpio_cfgpin(S3C2410_GPH1, S3C2410_GPH1_OUTP); ++ msleep(1000); ++ s3c2410_gpio_cfgpin(S3C2410_GPH1, S3C2410_GPH1_nRTS0); ++ ++} ++ ++static ssize_t gsm_write(struct device *dev, struct device_attribute *attr, ++ const char *buf, size_t count) ++{ ++ unsigned long on = simple_strtoul(buf, NULL, 10); ++ ++ if (!strcmp(attr->attr.name, "power_on")) { ++ gsm_on_off(dev, on); ++ ++ return count; ++ } ++ ++ if (!strcmp(attr->attr.name, "download")) { ++ if (machine_is_neo1973_gta01()) ++ s3c2410_gpio_setpin(GTA01_GPIO_MODEM_DNLOAD, on); ++ ++ if (machine_is_neo1973_gta02()) { ++ /* ++ * the keyboard / buttons driver requests and enables ++ * the JACK_INSERT IRQ. We have to take care about ++ * not enabling and disabling the IRQ when it was ++ * already in that state or we get "unblanaced IRQ" ++ * kernel warnings and stack dumps. So we use the ++ * copy of the ndl_gsm state to figure out if we should ++ * enable or disable the jack interrupt ++ */ ++ if (on) { ++ if (gta01_gsm.gpio_ndl_gsm) ++ disable_irq(gpio_to_irq( ++ GTA02_GPIO_JACK_INSERT)); ++ } else { ++ if (!gta01_gsm.gpio_ndl_gsm) ++ enable_irq(gpio_to_irq( ++ GTA02_GPIO_JACK_INSERT)); ++ } ++ ++ gta01_gsm.gpio_ndl_gsm = !on; ++ s3c2410_gpio_setpin(GTA02_GPIO_nDL_GSM, !on); ++ } ++ ++ return count; ++ } ++ ++ if (!strcmp(attr->attr.name, "flowcontrolled")) { ++ if (on) { ++ gta_gsm_interrupts = 0; ++ s3c2410_gpio_setpin(S3C2410_GPH1, 1); ++ s3c2410_gpio_cfgpin(S3C2410_GPH1, S3C2410_GPH1_OUTP); ++ } else ++ s3c2410_gpio_cfgpin(S3C2410_GPH1, S3C2410_GPH1_nRTS0); ++ } ++ ++ return count; ++} ++ ++static DEVICE_ATTR(power_on, 0644, gsm_read, gsm_write); ++static DEVICE_ATTR(reset, 0644, gsm_read, gsm_write); ++static DEVICE_ATTR(download, 0644, gsm_read, gsm_write); ++static DEVICE_ATTR(flowcontrolled, 0644, gsm_read, gsm_write); ++ ++#ifdef CONFIG_PM ++ ++static int gta01_gsm_resume(struct platform_device *pdev); ++static int gta01_gsm_suspend(struct platform_device *pdev, pm_message_t state) ++{ ++ /* GPIO state is saved/restored by S3C2410 core GPIO driver, so we ++ * don't need to do much here. */ ++ ++ /* If flowcontrol asserted, abort if GSM already interrupted */ ++ if (s3c2410_gpio_getcfg(S3C2410_GPH1) == S3C2410_GPIO_OUTPUT) { ++ if (gta_gsm_interrupts) ++ goto busy; ++ } ++ ++ /* disable DL GSM to prevent jack_insert becoming 'floating' */ ++ if (machine_is_neo1973_gta02()) ++ s3c2410_gpio_setpin(GTA02_GPIO_nDL_GSM, 1); ++ return 0; ++ ++busy: ++ return -EBUSY; ++} ++ ++static int ++gta01_gsm_suspend_late(struct platform_device *pdev, pm_message_t state) ++{ ++ /* Last chance: abort if GSM already interrupted */ ++ if (s3c2410_gpio_getcfg(S3C2410_GPH1) == S3C2410_GPIO_OUTPUT) { ++ if (gta_gsm_interrupts) ++ return -EBUSY; ++ } ++ return 0; ++} ++ ++static int gta01_gsm_resume(struct platform_device *pdev) ++{ ++ /* GPIO state is saved/restored by S3C2410 core GPIO driver, so we ++ * don't need to do much here. */ ++ ++ /* Make sure that the kernel console on the serial port is still ++ * disabled. FIXME: resume ordering race with serial driver! */ ++ if (gta01_gsm.con && s3c2410_gpio_getpin(GTA01_GPIO_MODEM_ON)) ++ console_stop(gta01_gsm.con); ++ ++ if (machine_is_neo1973_gta02()) ++ s3c2410_gpio_setpin(GTA02_GPIO_nDL_GSM, gta01_gsm.gpio_ndl_gsm); ++ ++ return 0; ++} ++#else ++#define gta01_gsm_suspend NULL ++#define gta01_gsm_suspend_late NULL ++#define gta01_gsm_resume NULL ++#endif /* CONFIG_PM */ ++ ++static struct attribute *gta01_gsm_sysfs_entries[] = { ++ &dev_attr_power_on.attr, ++ &dev_attr_reset.attr, ++ &dev_attr_download.attr, ++ &dev_attr_flowcontrolled.attr, ++ NULL ++}; ++ ++static struct attribute_group gta01_gsm_attr_group = { ++ .name = NULL, ++ .attrs = gta01_gsm_sysfs_entries, ++}; ++ ++static int __init gta01_gsm_probe(struct platform_device *pdev) ++{ ++ switch (S3C_SYSTEM_REV_ATAG) { ++ case GTA01v3_SYSTEM_REV: ++ gta01_gsm.gpio_ngsm_en = GTA01v3_GPIO_nGSM_EN; ++ break; ++ case GTA01v4_SYSTEM_REV: ++ gta01_gsm.gpio_ngsm_en = 0; ++ break; ++ case GTA01Bv2_SYSTEM_REV: ++ case GTA01Bv3_SYSTEM_REV: ++ case GTA01Bv4_SYSTEM_REV: ++ gta01_gsm.gpio_ngsm_en = GTA01Bv2_GPIO_nGSM_EN; ++ s3c2410_gpio_setpin(GTA01v3_GPIO_nGSM_EN, 0); ++ break; ++ case GTA02v1_SYSTEM_REV: ++ case GTA02v2_SYSTEM_REV: ++ case GTA02v3_SYSTEM_REV: ++ case GTA02v4_SYSTEM_REV: ++ case GTA02v5_SYSTEM_REV: ++ case GTA02v6_SYSTEM_REV: ++ gta01_gsm.gpio_ngsm_en = 0; ++ break; ++ default: ++ dev_warn(&pdev->dev, "Unknown Neo1973 Revision 0x%x, " ++ "some PM features not available!!!\n", ++ system_rev); ++ break; ++ } ++ ++ switch (S3C_SYSTEM_REV_ATAG) { ++ case GTA01v4_SYSTEM_REV: ++ case GTA01Bv2_SYSTEM_REV: ++ gta01_gsm_sysfs_entries[ARRAY_SIZE(gta01_gsm_sysfs_entries)-2] = ++ &dev_attr_download.attr; ++ break; ++ default: ++ break; ++ } ++ ++ if (machine_is_neo1973_gta01()) { ++ gta01_gsm.con = find_s3c24xx_console(); ++ if (!gta01_gsm.con) ++ dev_warn(&pdev->dev, ++ "cannot find S3C24xx console driver\n"); ++ } else ++ gta01_gsm.con = NULL; ++ ++ /* note that download initially disabled, and enforce that */ ++ gta01_gsm.gpio_ndl_gsm = 1; ++ if (machine_is_neo1973_gta02()) ++ s3c2410_gpio_setpin(GTA02_GPIO_nDL_GSM, 1); ++ ++ /* GSM is to be initially off (at boot, or if this module inserted) */ ++ gsm_on_off(&pdev->dev, 0); ++ ++ return sysfs_create_group(&pdev->dev.kobj, >a01_gsm_attr_group); ++} ++ ++static int gta01_gsm_remove(struct platform_device *pdev) ++{ ++ sysfs_remove_group(&pdev->dev.kobj, >a01_gsm_attr_group); ++ ++ return 0; ++} ++ ++static struct platform_driver gta01_gsm_driver = { ++ .probe = gta01_gsm_probe, ++ .remove = gta01_gsm_remove, ++ .suspend = gta01_gsm_suspend, ++ .suspend_late = gta01_gsm_suspend_late, ++ .resume = gta01_gsm_resume, ++ .driver = { ++ .name = "neo1973-pm-gsm", ++ }, ++}; ++ ++static int __devinit gta01_gsm_init(void) ++{ ++ return platform_driver_register(>a01_gsm_driver); ++} ++ ++static void gta01_gsm_exit(void) ++{ ++ platform_driver_unregister(>a01_gsm_driver); ++} ++ ++module_init(gta01_gsm_init); ++module_exit(gta01_gsm_exit); ++ ++MODULE_LICENSE("GPL"); ++MODULE_AUTHOR("Harald Welte <laforge@openmoko.org>"); ++MODULE_DESCRIPTION("FIC Neo1973 GSM Power Management"); +diff -ruN --exclude='*.orig' --exclude='*.rej' linux-2.6.29-rc3.owrt/arch/arm/plat-s3c24xx/neo1973_shadow.c linux-2.6.29-rc3.owrt.om/arch/arm/plat-s3c24xx/neo1973_shadow.c +--- linux-2.6.29-rc3.owrt/arch/arm/plat-s3c24xx/neo1973_shadow.c 1970-01-01 01:00:00.000000000 +0100 ++++ linux-2.6.29-rc3.owrt.om/arch/arm/plat-s3c24xx/neo1973_shadow.c 2009-05-10 22:27:59.000000000 +0200 +@@ -0,0 +1,88 @@ ++/* ++ * include/asm-arm/plat-s3c24xx/neo1973.h ++ * ++ * Common utility code for GTA01 and GTA02 ++ * ++ * Copyright (C) 2008 by Openmoko, Inc. ++ * Author: Holger Hans Peter Freyther <freyther@openmoko.org> ++ * All rights reserved. ++ * ++ * 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, ++ * MA 02111-1307 USA ++ * ++ */ ++ ++#include <linux/module.h> ++#include <linux/io.h> ++#include <linux/irq.h> ++ ++#include <asm/gpio.h> ++#include <mach/regs-gpio.h> ++#include <asm/plat-s3c24xx/neo1973.h> ++ ++/** ++ * Shadow GPIO bank B handling. For the LEDs we need to keep track of the state ++ * in software. The s3c2410_gpio_setpin must not be used for GPIOs on bank B ++ */ ++static unsigned long gpb_mask; ++static unsigned long gpb_state; ++ ++void neo1973_gpb_add_shadow_gpio(unsigned int gpio) ++{ ++ unsigned long offset = S3C2410_GPIO_OFFSET(gpio); ++ unsigned long flags; ++ ++ local_irq_save(flags); ++ gpb_mask |= 1L << offset; ++ local_irq_restore(flags); ++} ++EXPORT_SYMBOL(neo1973_gpb_add_shadow_gpio); ++ ++static void set_shadow_gpio(unsigned long offset, unsigned int value) ++{ ++ unsigned long state = value != 0; ++ ++ gpb_state &= ~(1L << offset); ++ gpb_state |= state << offset; ++} ++ ++void neo1973_gpb_setpin(unsigned int pin, unsigned to) ++{ ++ void __iomem *base = S3C24XX_GPIO_BASE(S3C2410_GPB0); ++ unsigned long offset = S3C2410_GPIO_OFFSET(pin); ++ unsigned long flags; ++ unsigned long dat; ++ ++ BUG_ON(base != S3C24XX_GPIO_BASE(pin)); ++ ++ local_irq_save(flags); ++ dat = __raw_readl(base + 0x04); ++ ++ /* Add the shadow values */ ++ dat &= ~gpb_mask; ++ dat |= gpb_state; ++ ++ /* Do the operation like s3c2410_gpio_setpin */ ++ dat &= ~(1L << offset); ++ dat |= to << offset; ++ ++ /* Update the shadow state */ ++ if ((1L << offset) & gpb_mask) ++ set_shadow_gpio(offset, to); ++ ++ __raw_writel(dat, base + 0x04); ++ local_irq_restore(flags); ++} ++EXPORT_SYMBOL(neo1973_gpb_setpin); +diff -ruN --exclude='*.orig' --exclude='*.rej' linux-2.6.29-rc3.owrt/arch/arm/plat-s3c24xx/pm.c linux-2.6.29-rc3.owrt.om/arch/arm/plat-s3c24xx/pm.c +--- linux-2.6.29-rc3.owrt/arch/arm/plat-s3c24xx/pm.c 2009-05-10 22:05:03.000000000 +0200 ++++ linux-2.6.29-rc3.owrt.om/arch/arm/plat-s3c24xx/pm.c 2009-05-10 22:27:59.000000000 +0200 +@@ -31,28 +31,20 @@ + #include <linux/errno.h> + #include <linux/time.h> + #include <linux/interrupt.h> +-#include <linux/crc32.h> +-#include <linux/ioport.h> + #include <linux/serial_core.h> + #include <linux/io.h> + +-#include <asm/cacheflush.h> +-#include <mach/hardware.h> +- + #include <plat/regs-serial.h> + #include <mach/regs-clock.h> + #include <mach/regs-gpio.h> + #include <mach/regs-mem.h> + #include <mach/regs-irq.h> ++#include <mach/hardware.h> + + #include <asm/mach/time.h> + + #include <plat/pm.h> + +-/* for external use */ +- +-unsigned long s3c_pm_flags; +- + #define PFX "s3c24xx-pm: " + + static struct sleep_save core_save[] = { +@@ -84,364 +76,17 @@ + SAVE_ITEM(S3C2410_CLKSLOW), + }; + +-static struct gpio_sleep { +- void __iomem *base; +- unsigned int gpcon; +- unsigned int gpdat; +- unsigned int gpup; +-} gpio_save[] = { +- [0] = { +- .base = S3C2410_GPACON, +- }, +- [1] = { +- .base = S3C2410_GPBCON, +- }, +- [2] = { +- .base = S3C2410_GPCCON, +- }, +- [3] = { +- .base = S3C2410_GPDCON, +- }, +- [4] = { +- .base = S3C2410_GPECON, +- }, +- [5] = { +- .base = S3C2410_GPFCON, +- }, +- [6] = { +- .base = S3C2410_GPGCON, +- }, +- [7] = { +- .base = S3C2410_GPHCON, +- }, +-}; +- + static struct sleep_save misc_save[] = { + SAVE_ITEM(S3C2410_DCLKCON), + }; + +-#ifdef CONFIG_S3C2410_PM_DEBUG +- +-#define SAVE_UART(va) \ +- SAVE_ITEM((va) + S3C2410_ULCON), \ +- SAVE_ITEM((va) + S3C2410_UCON), \ +- SAVE_ITEM((va) + S3C2410_UFCON), \ +- SAVE_ITEM((va) + S3C2410_UMCON), \ +- SAVE_ITEM((va) + S3C2410_UBRDIV) +- +-static struct sleep_save uart_save[] = { +- SAVE_UART(S3C24XX_VA_UART0), +- SAVE_UART(S3C24XX_VA_UART1), +-#ifndef CONFIG_CPU_S3C2400 +- SAVE_UART(S3C24XX_VA_UART2), +-#endif +-}; +- +-/* debug +- * +- * we send the debug to printascii() to allow it to be seen if the +- * system never wakes up from the sleep +-*/ +- +-extern void printascii(const char *); +- +-void pm_dbg(const char *fmt, ...) +-{ +- va_list va; +- char buff[256]; +- +- va_start(va, fmt); +- vsprintf(buff, fmt, va); +- va_end(va); +- +- printascii(buff); +-} +- +-static void s3c2410_pm_debug_init(void) +-{ +- unsigned long tmp = __raw_readl(S3C2410_CLKCON); +- +- /* re-start uart clocks */ +- tmp |= S3C2410_CLKCON_UART0; +- tmp |= S3C2410_CLKCON_UART1; +- tmp |= S3C2410_CLKCON_UART2; +- +- __raw_writel(tmp, S3C2410_CLKCON); +- udelay(10); +-} +- +-#define DBG(fmt...) pm_dbg(fmt) +-#else +-#define DBG(fmt...) printk(KERN_DEBUG fmt) +- +-#define s3c2410_pm_debug_init() do { } while(0) +- +-static struct sleep_save uart_save[] = {}; +-#endif +- +-#if defined(CONFIG_S3C2410_PM_CHECK) && CONFIG_S3C2410_PM_CHECK_CHUNKSIZE != 0 +- +-/* suspend checking code... +- * +- * this next area does a set of crc checks over all the installed +- * memory, so the system can verify if the resume was ok. +- * +- * CONFIG_S3C2410_PM_CHECK_CHUNKSIZE defines the block-size for the CRC, +- * increasing it will mean that the area corrupted will be less easy to spot, +- * and reducing the size will cause the CRC save area to grow +-*/ +- +-#define CHECK_CHUNKSIZE (CONFIG_S3C2410_PM_CHECK_CHUNKSIZE * 1024) +- +-static u32 crc_size; /* size needed for the crc block */ +-static u32 *crcs; /* allocated over suspend/resume */ +- +-typedef u32 *(run_fn_t)(struct resource *ptr, u32 *arg); +- +-/* s3c2410_pm_run_res +- * +- * go thorugh the given resource list, and look for system ram +-*/ +- +-static void s3c2410_pm_run_res(struct resource *ptr, run_fn_t fn, u32 *arg) +-{ +- while (ptr != NULL) { +- if (ptr->child != NULL) +- s3c2410_pm_run_res(ptr->child, fn, arg); +- +- if ((ptr->flags & IORESOURCE_MEM) && +- strcmp(ptr->name, "System RAM") == 0) { +- DBG("Found system RAM at %08lx..%08lx\n", +- ptr->start, ptr->end); +- arg = (fn)(ptr, arg); +- } +- +- ptr = ptr->sibling; +- } +-} +- +-static void s3c2410_pm_run_sysram(run_fn_t fn, u32 *arg) +-{ +- s3c2410_pm_run_res(&iomem_resource, fn, arg); +-} +- +-static u32 *s3c2410_pm_countram(struct resource *res, u32 *val) +-{ +- u32 size = (u32)(res->end - res->start)+1; +- +- size += CHECK_CHUNKSIZE-1; +- size /= CHECK_CHUNKSIZE; +- +- DBG("Area %08lx..%08lx, %d blocks\n", res->start, res->end, size); +- +- *val += size * sizeof(u32); +- return val; +-} +- +-/* s3c2410_pm_prepare_check +- * +- * prepare the necessary information for creating the CRCs. This +- * must be done before the final save, as it will require memory +- * allocating, and thus touching bits of the kernel we do not +- * know about. +-*/ +- +-static void s3c2410_pm_check_prepare(void) +-{ +- crc_size = 0; +- +- s3c2410_pm_run_sysram(s3c2410_pm_countram, &crc_size); +- +- DBG("s3c2410_pm_prepare_check: %u checks needed\n", crc_size); +- +- crcs = kmalloc(crc_size+4, GFP_KERNEL); +- if (crcs == NULL) +- printk(KERN_ERR "Cannot allocated CRC save area\n"); +-} +- +-static u32 *s3c2410_pm_makecheck(struct resource *res, u32 *val) +-{ +- unsigned long addr, left; +- +- for (addr = res->start; addr < res->end; +- addr += CHECK_CHUNKSIZE) { +- left = res->end - addr; +- +- if (left > CHECK_CHUNKSIZE) +- left = CHECK_CHUNKSIZE; +- +- *val = crc32_le(~0, phys_to_virt(addr), left); +- val++; +- } +- +- return val; +-} +- +-/* s3c2410_pm_check_store +- * +- * compute the CRC values for the memory blocks before the final +- * sleep. +-*/ +- +-static void s3c2410_pm_check_store(void) +-{ +- if (crcs != NULL) +- s3c2410_pm_run_sysram(s3c2410_pm_makecheck, crcs); +-} +- +-/* in_region +- * +- * return TRUE if the area defined by ptr..ptr+size contatins the +- * what..what+whatsz +-*/ +- +-static inline int in_region(void *ptr, int size, void *what, size_t whatsz) +-{ +- if ((what+whatsz) < ptr) +- return 0; +- +- if (what > (ptr+size)) +- return 0; +- +- return 1; +-} +- +-static u32 *s3c2410_pm_runcheck(struct resource *res, u32 *val) +-{ +- void *save_at = phys_to_virt(s3c2410_sleep_save_phys); +- unsigned long addr; +- unsigned long left; +- void *ptr; +- u32 calc; +- +- for (addr = res->start; addr < res->end; +- addr += CHECK_CHUNKSIZE) { +- left = res->end - addr; +- +- if (left > CHECK_CHUNKSIZE) +- left = CHECK_CHUNKSIZE; +- +- ptr = phys_to_virt(addr); +- +- if (in_region(ptr, left, crcs, crc_size)) { +- DBG("skipping %08lx, has crc block in\n", addr); +- goto skip_check; +- } +- +- if (in_region(ptr, left, save_at, 32*4 )) { +- DBG("skipping %08lx, has save block in\n", addr); +- goto skip_check; +- } +- +- /* calculate and check the checksum */ +- +- calc = crc32_le(~0, ptr, left); +- if (calc != *val) { +- printk(KERN_ERR PFX "Restore CRC error at " +- "%08lx (%08x vs %08x)\n", addr, calc, *val); +- +- DBG("Restore CRC error at %08lx (%08x vs %08x)\n", +- addr, calc, *val); +- } +- +- skip_check: +- val++; +- } +- +- return val; +-} +- +-/* s3c2410_pm_check_restore +- * +- * check the CRCs after the restore event and free the memory used +- * to hold them +-*/ +- +-static void s3c2410_pm_check_restore(void) +-{ +- if (crcs != NULL) { +- s3c2410_pm_run_sysram(s3c2410_pm_runcheck, crcs); +- kfree(crcs); +- crcs = NULL; +- } +-} +- +-#else +- +-#define s3c2410_pm_check_prepare() do { } while(0) +-#define s3c2410_pm_check_restore() do { } while(0) +-#define s3c2410_pm_check_store() do { } while(0) +-#endif +- +-/* helper functions to save and restore register state */ +- +-void s3c2410_pm_do_save(struct sleep_save *ptr, int count) +-{ +- for (; count > 0; count--, ptr++) { +- ptr->val = __raw_readl(ptr->reg); +- DBG("saved %p value %08lx\n", ptr->reg, ptr->val); +- } +-} +- +-/* s3c2410_pm_do_restore +- * +- * restore the system from the given list of saved registers +- * +- * Note, we do not use DBG() in here, as the system may not have +- * restore the UARTs state yet +-*/ +- +-void s3c2410_pm_do_restore(struct sleep_save *ptr, int count) +-{ +- for (; count > 0; count--, ptr++) { +- printk(KERN_DEBUG "restore %p (restore %08lx, was %08x)\n", +- ptr->reg, ptr->val, __raw_readl(ptr->reg)); +- +- __raw_writel(ptr->val, ptr->reg); +- } +-} +- +-/* s3c2410_pm_do_restore_core +- * +- * similar to s3c2410_pm_do_restore_core +- * +- * WARNING: Do not put any debug in here that may effect memory or use +- * peripherals, as things may be changing! +-*/ +- +-static void s3c2410_pm_do_restore_core(struct sleep_save *ptr, int count) +-{ +- for (; count > 0; count--, ptr++) { +- __raw_writel(ptr->val, ptr->reg); +- } +-} +- +-/* s3c2410_pm_show_resume_irqs +- * +- * print any IRQs asserted at resume time (ie, we woke from) +-*/ +- +-static void s3c2410_pm_show_resume_irqs(int start, unsigned long which, +- unsigned long mask) +-{ +- int i; +- +- which &= ~mask; +- +- for (i = 0; i <= 31; i++) { +- if ((which) & (1L<<i)) { +- DBG("IRQ %d asserted at resume\n", start+i); +- } +- } +-} +- +-/* s3c2410_pm_check_resume_pin ++/* s3c_pm_check_resume_pin + * + * check to see if the pin is configured correctly for sleep mode, and + * make any necessary adjustments if it is not + */ + +-static void s3c2410_pm_check_resume_pin(unsigned int pin, unsigned int irqoffs) ++static void s3c_pm_check_resume_pin(unsigned int pin, unsigned int irqoffs) + { + unsigned long irqstate; + unsigned long pinstate; +@@ -456,21 +101,21 @@ + + if (!irqstate) { + if (pinstate == S3C2410_GPIO_IRQ) +- DBG("Leaving IRQ %d (pin %d) enabled\n", irq, pin); ++ S3C_PMDBG("Leaving IRQ %d (pin %d) enabled\n", irq, pin); + } else { + if (pinstate == S3C2410_GPIO_IRQ) { +- DBG("Disabling IRQ %d (pin %d)\n", irq, pin); ++ S3C_PMDBG("Disabling IRQ %d (pin %d)\n", irq, pin); + s3c2410_gpio_cfgpin(pin, S3C2410_GPIO_INPUT); + } + } + } + +-/* s3c2410_pm_configure_extint ++/* s3c_pm_configure_extint + * + * configure all external interrupt pins + */ + +-static void s3c2410_pm_configure_extint(void) ++void s3c_pm_configure_extint(void) + { + int pin; + +@@ -480,336 +125,24 @@ + */ + + for (pin = S3C2410_GPF0; pin <= S3C2410_GPF7; pin++) { +- s3c2410_pm_check_resume_pin(pin, pin - S3C2410_GPF0); ++ s3c_pm_check_resume_pin(pin, pin - S3C2410_GPF0); + } + + for (pin = S3C2410_GPG0; pin <= S3C2410_GPG7; pin++) { +- s3c2410_pm_check_resume_pin(pin, (pin - S3C2410_GPG0)+8); +- } +-} +- +-/* offsets for CON/DAT/UP registers */ +- +-#define OFFS_CON (S3C2410_GPACON - S3C2410_GPACON) +-#define OFFS_DAT (S3C2410_GPADAT - S3C2410_GPACON) +-#define OFFS_UP (S3C2410_GPBUP - S3C2410_GPBCON) +- +-/* s3c2410_pm_save_gpios() +- * +- * Save the state of the GPIOs +- */ +- +-static void s3c2410_pm_save_gpios(void) +-{ +- struct gpio_sleep *gps = gpio_save; +- unsigned int gpio; +- +- for (gpio = 0; gpio < ARRAY_SIZE(gpio_save); gpio++, gps++) { +- void __iomem *base = gps->base; +- +- gps->gpcon = __raw_readl(base + OFFS_CON); +- gps->gpdat = __raw_readl(base + OFFS_DAT); +- +- if (gpio > 0) +- gps->gpup = __raw_readl(base + OFFS_UP); +- +- } +-} +- +-/* Test whether the given masked+shifted bits of an GPIO configuration +- * are one of the SFN (special function) modes. */ +- +-static inline int is_sfn(unsigned long con) +-{ +- return (con == 2 || con == 3); +-} +- +-/* Test if the given masked+shifted GPIO configuration is an input */ +- +-static inline int is_in(unsigned long con) +-{ +- return con == 0; +-} +- +-/* Test if the given masked+shifted GPIO configuration is an output */ +- +-static inline int is_out(unsigned long con) +-{ +- return con == 1; +-} +- +-/* s3c2410_pm_restore_gpio() +- * +- * Restore one of the GPIO banks that was saved during suspend. This is +- * not as simple as once thought, due to the possibility of glitches +- * from the order that the CON and DAT registers are set in. +- * +- * The three states the pin can be are {IN,OUT,SFN} which gives us 9 +- * combinations of changes to check. Three of these, if the pin stays +- * in the same configuration can be discounted. This leaves us with +- * the following: +- * +- * { IN => OUT } Change DAT first +- * { IN => SFN } Change CON first +- * { OUT => SFN } Change CON first, so new data will not glitch +- * { OUT => IN } Change CON first, so new data will not glitch +- * { SFN => IN } Change CON first +- * { SFN => OUT } Change DAT first, so new data will not glitch [1] +- * +- * We do not currently deal with the UP registers as these control +- * weak resistors, so a small delay in change should not need to bring +- * these into the calculations. +- * +- * [1] this assumes that writing to a pin DAT whilst in SFN will set the +- * state for when it is next output. +- */ +- +-static void s3c2410_pm_restore_gpio(int index, struct gpio_sleep *gps) +-{ +- void __iomem *base = gps->base; +- unsigned long gps_gpcon = gps->gpcon; +- unsigned long gps_gpdat = gps->gpdat; +- unsigned long old_gpcon; +- unsigned long old_gpdat; +- unsigned long old_gpup = 0x0; +- unsigned long gpcon; +- int nr; +- +- old_gpcon = __raw_readl(base + OFFS_CON); +- old_gpdat = __raw_readl(base + OFFS_DAT); +- +- if (base == S3C2410_GPACON) { +- /* GPACON only has one bit per control / data and no PULLUPs. +- * GPACON[x] = 0 => Output, 1 => SFN */ +- +- /* first set all SFN bits to SFN */ +- +- gpcon = old_gpcon | gps->gpcon; +- __raw_writel(gpcon, base + OFFS_CON); +- +- /* now set all the other bits */ +- +- __raw_writel(gps_gpdat, base + OFFS_DAT); +- __raw_writel(gps_gpcon, base + OFFS_CON); +- } else { +- unsigned long old, new, mask; +- unsigned long change_mask = 0x0; +- +- old_gpup = __raw_readl(base + OFFS_UP); +- +- /* Create a change_mask of all the items that need to have +- * their CON value changed before their DAT value, so that +- * we minimise the work between the two settings. +- */ +- +- for (nr = 0, mask = 0x03; nr < 32; nr += 2, mask <<= 2) { +- old = (old_gpcon & mask) >> nr; +- new = (gps_gpcon & mask) >> nr; +- +- /* If there is no change, then skip */ +- +- if (old == new) +- continue; +- +- /* If both are special function, then skip */ +- +- if (is_sfn(old) && is_sfn(new)) +- continue; +- +- /* Change is IN => OUT, do not change now */ +- +- if (is_in(old) && is_out(new)) +- continue; +- +- /* Change is SFN => OUT, do not change now */ +- +- if (is_sfn(old) && is_out(new)) +- continue; +- +- /* We should now be at the case of IN=>SFN, +- * OUT=>SFN, OUT=>IN, SFN=>IN. */ +- +- change_mask |= mask; +- } +- +- /* Write the new CON settings */ +- +- gpcon = old_gpcon & ~change_mask; +- gpcon |= gps_gpcon & change_mask; +- +- __raw_writel(gpcon, base + OFFS_CON); +- +- /* Now change any items that require DAT,CON */ +- +- __raw_writel(gps_gpdat, base + OFFS_DAT); +- __raw_writel(gps_gpcon, base + OFFS_CON); +- __raw_writel(gps->gpup, base + OFFS_UP); ++ s3c_pm_check_resume_pin(pin, (pin - S3C2410_GPG0)+8); + } +- +- DBG("GPIO[%d] CON %08lx => %08lx, DAT %08lx => %08lx\n", +- index, old_gpcon, gps_gpcon, old_gpdat, gps_gpdat); + } + + +-/** s3c2410_pm_restore_gpios() +- * +- * Restore the state of the GPIOs +- */ +- +-static void s3c2410_pm_restore_gpios(void) ++void s3c_pm_restore_core(void) + { +- struct gpio_sleep *gps = gpio_save; +- int gpio; +- +- for (gpio = 0; gpio < ARRAY_SIZE(gpio_save); gpio++, gps++) { +- s3c2410_pm_restore_gpio(gpio, gps); +- } ++ s3c_pm_do_restore_core(core_save, ARRAY_SIZE(core_save)); ++ s3c_pm_do_restore(misc_save, ARRAY_SIZE(misc_save)); + } + +-void (*pm_cpu_prep)(void); +-void (*pm_cpu_sleep)(void); +- +-#define any_allowed(mask, allow) (((mask) & (allow)) != (allow)) +- +-/* s3c2410_pm_enter +- * +- * central control for sleep/resume process +-*/ +- +-static int s3c2410_pm_enter(suspend_state_t state) ++void s3c_pm_save_core(void) + { +- unsigned long regs_save[16]; +- +- /* ensure the debug is initialised (if enabled) */ +- +- s3c2410_pm_debug_init(); +- +- DBG("s3c2410_pm_enter(%d)\n", state); +- +- if (pm_cpu_prep == NULL || pm_cpu_sleep == NULL) { +- printk(KERN_ERR PFX "error: no cpu sleep functions set\n"); +- return -EINVAL; +- } +- +- /* check if we have anything to wake-up with... bad things seem +- * to happen if you suspend with no wakeup (system will often +- * require a full power-cycle) +- */ +- +- if (!any_allowed(s3c_irqwake_intmask, s3c_irqwake_intallow) && +- !any_allowed(s3c_irqwake_eintmask, s3c_irqwake_eintallow)) { +- printk(KERN_ERR PFX "No sources enabled for wake-up!\n"); +- printk(KERN_ERR PFX "Aborting sleep\n"); +- return -EINVAL; +- } +- +- /* prepare check area if configured */ +- +- s3c2410_pm_check_prepare(); +- +- /* store the physical address of the register recovery block */ +- +- s3c2410_sleep_save_phys = virt_to_phys(regs_save); +- +- DBG("s3c2410_sleep_save_phys=0x%08lx\n", s3c2410_sleep_save_phys); +- +- /* save all necessary core registers not covered by the drivers */ +- +- s3c2410_pm_save_gpios(); +- s3c2410_pm_do_save(misc_save, ARRAY_SIZE(misc_save)); +- s3c2410_pm_do_save(core_save, ARRAY_SIZE(core_save)); +- s3c2410_pm_do_save(uart_save, ARRAY_SIZE(uart_save)); +- +- /* set the irq configuration for wake */ +- +- s3c2410_pm_configure_extint(); +- +- DBG("sleep: irq wakeup masks: %08lx,%08lx\n", +- s3c_irqwake_intmask, s3c_irqwake_eintmask); +- +- __raw_writel(s3c_irqwake_intmask, S3C2410_INTMSK); +- __raw_writel(s3c_irqwake_eintmask, S3C2410_EINTMASK); +- +- /* ack any outstanding external interrupts before we go to sleep */ +- +- __raw_writel(__raw_readl(S3C2410_EINTPEND), S3C2410_EINTPEND); +- __raw_writel(__raw_readl(S3C2410_INTPND), S3C2410_INTPND); +- __raw_writel(__raw_readl(S3C2410_SRCPND), S3C2410_SRCPND); +- +- /* call cpu specific preparation */ +- +- pm_cpu_prep(); +- +- /* flush cache back to ram */ +- +- flush_cache_all(); +- +- s3c2410_pm_check_store(); +- +- /* send the cpu to sleep... */ +- +- __raw_writel(0x00, S3C2410_CLKCON); /* turn off clocks over sleep */ +- +- /* s3c2410_cpu_save will also act as our return point from when +- * we resume as it saves its own register state, so use the return +- * code to differentiate return from save and return from sleep */ +- +- if (s3c2410_cpu_save(regs_save) == 0) { +- flush_cache_all(); +- pm_cpu_sleep(); +- } +- +- /* restore the cpu state */ +- +- cpu_init(); +- +- /* restore the system state */ +- +- s3c2410_pm_do_restore_core(core_save, ARRAY_SIZE(core_save)); +- s3c2410_pm_do_restore(misc_save, ARRAY_SIZE(misc_save)); +- s3c2410_pm_do_restore(uart_save, ARRAY_SIZE(uart_save)); +- s3c2410_pm_restore_gpios(); +- +- s3c2410_pm_debug_init(); +- +- /* check what irq (if any) restored the system */ +- +- DBG("post sleep: IRQs 0x%08x, 0x%08x\n", +- __raw_readl(S3C2410_SRCPND), +- __raw_readl(S3C2410_EINTPEND)); +- +- s3c2410_pm_show_resume_irqs(IRQ_EINT0, __raw_readl(S3C2410_SRCPND), +- s3c_irqwake_intmask); +- +- s3c2410_pm_show_resume_irqs(IRQ_EINT4-4, __raw_readl(S3C2410_EINTPEND), +- s3c_irqwake_eintmask); +- +- DBG("post sleep, preparing to return\n"); +- +- s3c2410_pm_check_restore(); +- +- /* ok, let's return from sleep */ +- +- DBG("S3C2410 PM Resume (post-restore)\n"); +- return 0; ++ s3c_pm_do_save(misc_save, ARRAY_SIZE(misc_save)); ++ s3c_pm_do_save(core_save, ARRAY_SIZE(core_save)); + } + +-static struct platform_suspend_ops s3c2410_pm_ops = { +- .enter = s3c2410_pm_enter, +- .valid = suspend_valid_only_mem, +-}; +- +-/* s3c2410_pm_init +- * +- * Attach the power management functions. This should be called +- * from the board specific initialisation if the board supports +- * it. +-*/ +- +-int __init s3c2410_pm_init(void) +-{ +- printk("S3C2410 Power Management, (c) 2004 Simtec Electronics\n"); +- +- suspend_set_ops(&s3c2410_pm_ops); +- return 0; +-} +diff -ruN --exclude='*.orig' --exclude='*.rej' linux-2.6.29-rc3.owrt/arch/arm/plat-s3c24xx/pm-simtec.c linux-2.6.29-rc3.owrt.om/arch/arm/plat-s3c24xx/pm-simtec.c +--- linux-2.6.29-rc3.owrt/arch/arm/plat-s3c24xx/pm-simtec.c 2009-05-10 22:05:03.000000000 +0200 ++++ linux-2.6.29-rc3.owrt.om/arch/arm/plat-s3c24xx/pm-simtec.c 2009-05-10 22:27:59.000000000 +0200 +@@ -61,7 +61,7 @@ + + __raw_writel(gstatus4, S3C2410_GSTATUS4); + +- return s3c2410_pm_init(); ++ return s3c_pm_init(); + } + + arch_initcall(pm_simtec_init); +diff -ruN --exclude='*.orig' --exclude='*.rej' linux-2.6.29-rc3.owrt/arch/arm/plat-s3c24xx/pwm-clock.c linux-2.6.29-rc3.owrt.om/arch/arm/plat-s3c24xx/pwm-clock.c +--- linux-2.6.29-rc3.owrt/arch/arm/plat-s3c24xx/pwm-clock.c 1970-01-01 01:00:00.000000000 +0100 ++++ linux-2.6.29-rc3.owrt.om/arch/arm/plat-s3c24xx/pwm-clock.c 2009-05-10 22:27:59.000000000 +0200 +@@ -0,0 +1,437 @@ ++/* linux/arch/arm/plat-s3c24xx/pwm-clock.c ++ * ++ * Copyright (c) 2007 Simtec Electronics ++ * Copyright (c) 2007, 2008 Ben Dooks ++ * Ben Dooks <ben-linux@fluff.org> ++ * ++ * 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. ++*/ ++ ++#include <linux/init.h> ++#include <linux/module.h> ++#include <linux/kernel.h> ++#include <linux/list.h> ++#include <linux/errno.h> ++#include <linux/clk.h> ++#include <linux/err.h> ++#include <linux/io.h> ++ ++#include <mach/hardware.h> ++#include <asm/irq.h> ++ ++#include <mach/regs-clock.h> ++#include <mach/regs-gpio.h> ++ ++#include <asm/plat-s3c24xx/clock.h> ++#include <asm/plat-s3c24xx/cpu.h> ++ ++#include <asm/plat-s3c/regs-timer.h> ++ ++/* Each of the timers 0 through 5 go through the following ++ * clock tree, with the inputs depending on the timers. ++ * ++ * pclk ---- [ prescaler 0 ] -+---> timer 0 ++ * +---> timer 1 ++ * ++ * pclk ---- [ prescaler 1 ] -+---> timer 2 ++ * +---> timer 3 ++ * \---> timer 4 ++ * ++ * Which are fed into the timers as so: ++ * ++ * prescaled 0 ---- [ div 2,4,8,16 ] ---\ ++ * [mux] -> timer 0 ++ * tclk 0 ------------------------------/ ++ * ++ * prescaled 0 ---- [ div 2,4,8,16 ] ---\ ++ * [mux] -> timer 1 ++ * tclk 0 ------------------------------/ ++ * ++ * ++ * prescaled 1 ---- [ div 2,4,8,16 ] ---\ ++ * [mux] -> timer 2 ++ * tclk 1 ------------------------------/ ++ * ++ * prescaled 1 ---- [ div 2,4,8,16 ] ---\ ++ * [mux] -> timer 3 ++ * tclk 1 ------------------------------/ ++ * ++ * prescaled 1 ---- [ div 2,4,8, 16 ] --\ ++ * [mux] -> timer 4 ++ * tclk 1 ------------------------------/ ++ * ++ * Since the mux and the divider are tied together in the ++ * same register space, it is impossible to set the parent ++ * and the rate at the same time. To avoid this, we add an ++ * intermediate 'prescaled-and-divided' clock to select ++ * as the parent for the timer input clock called tdiv. ++ * ++ * prescaled clk --> pwm-tdiv ---\ ++ * [ mux ] --> timer X ++ * tclk -------------------------/ ++*/ ++ ++static unsigned long clk_pwm_scaler_getrate(struct clk *clk) ++{ ++ unsigned long tcfg0 = __raw_readl(S3C2410_TCFG0); ++ ++ if (clk->id == 1) { ++ tcfg0 &= S3C2410_TCFG_PRESCALER1_MASK; ++ tcfg0 >>= S3C2410_TCFG_PRESCALER1_SHIFT; ++ } else { ++ tcfg0 &= S3C2410_TCFG_PRESCALER0_MASK; ++ } ++ ++ return clk_get_rate(clk->parent) / (tcfg0 + 1); ++} ++ ++/* TODO - add set rate calls. */ ++ ++static struct clk clk_timer_scaler[] = { ++ [0] = { ++ .name = "pwm-scaler0", ++ .id = -1, ++ .get_rate = clk_pwm_scaler_getrate, ++ }, ++ [1] = { ++ .name = "pwm-scaler1", ++ .id = -1, ++ .get_rate = clk_pwm_scaler_getrate, ++ }, ++}; ++ ++static struct clk clk_timer_tclk[] = { ++ [0] = { ++ .name = "pwm-tclk0", ++ .id = -1, ++ }, ++ [1] = { ++ .name = "pwm-tclk1", ++ .id = -1, ++ }, ++}; ++ ++struct pwm_tdiv_clk { ++ struct clk clk; ++ unsigned int divisor; ++}; ++ ++static inline struct pwm_tdiv_clk *to_tdiv(struct clk *clk) ++{ ++ return container_of(clk, struct pwm_tdiv_clk, clk); ++} ++ ++static inline unsigned long tcfg_to_divisor(unsigned long tcfg1) ++{ ++ return 1 << (1 + tcfg1); ++} ++ ++static unsigned long clk_pwm_tdiv_get_rate(struct clk *clk) ++{ ++ unsigned long tcfg1 = __raw_readl(S3C2410_TCFG1); ++ unsigned int divisor; ++ ++ tcfg1 >>= S3C2410_TCFG1_SHIFT(clk->id); ++ tcfg1 &= S3C2410_TCFG1_MUX_MASK; ++ ++ if (tcfg1 == S3C2410_TCFG1_MUX_TCLK) ++ divisor = to_tdiv(clk)->divisor; ++ else ++ divisor = tcfg_to_divisor(tcfg1); ++ ++ return clk_get_rate(clk->parent) / divisor; ++} ++ ++static unsigned long clk_pwm_tdiv_round_rate(struct clk *clk, ++ unsigned long rate) ++{ ++ unsigned long parent_rate; ++ unsigned long divisor; ++ ++ parent_rate = clk_get_rate(clk->parent); ++ divisor = parent_rate / rate; ++ ++ if (divisor <= 2) ++ divisor = 2; ++ else if (divisor <= 4) ++ divisor = 4; ++ else if (divisor <= 8) ++ divisor = 8; ++ else ++ divisor = 16; ++ ++ return parent_rate / divisor; ++} ++ ++static unsigned long clk_pwm_tdiv_bits(struct pwm_tdiv_clk *divclk) ++{ ++ unsigned long bits; ++ ++ switch (divclk->divisor) { ++ case 2: ++ bits = S3C2410_TCFG1_MUX_DIV2; ++ break; ++ case 4: ++ bits = S3C2410_TCFG1_MUX_DIV4; ++ break; ++ case 8: ++ bits = S3C2410_TCFG1_MUX_DIV8; ++ break; ++ case 16: ++ default: ++ bits = S3C2410_TCFG1_MUX_DIV16; ++ break; ++ } ++ ++ return bits; ++} ++ ++static void clk_pwm_tdiv_update(struct pwm_tdiv_clk *divclk) ++{ ++ unsigned long tcfg1 = __raw_readl(S3C2410_TCFG1); ++ unsigned long bits = clk_pwm_tdiv_bits(divclk); ++ unsigned long flags; ++ unsigned long shift = S3C2410_TCFG1_SHIFT(divclk->clk.id); ++ ++ local_irq_save(flags); ++ ++ tcfg1 = __raw_readl(S3C2410_TCFG1); ++ tcfg1 &= ~(S3C2410_TCFG1_MUX_MASK << shift); ++ tcfg1 |= bits << shift; ++ __raw_writel(tcfg1, S3C2410_TCFG1); ++ ++ local_irq_restore(flags); ++} ++ ++static int clk_pwm_tdiv_set_rate(struct clk *clk, unsigned long rate) ++{ ++ struct pwm_tdiv_clk *divclk = to_tdiv(clk); ++ unsigned long tcfg1 = __raw_readl(S3C2410_TCFG1); ++ unsigned long parent_rate = clk_get_rate(clk->parent); ++ unsigned long divisor; ++ ++ tcfg1 >>= S3C2410_TCFG1_SHIFT(clk->id); ++ tcfg1 &= S3C2410_TCFG1_MUX_MASK; ++ ++ rate = clk_round_rate(clk, rate); ++ divisor = parent_rate / rate; ++ ++ if (divisor > 16) ++ return -EINVAL; ++ ++ divclk->divisor = divisor; ++ ++ /* Update the current MUX settings if we are currently ++ * selected as the clock source for this clock. */ ++ ++ if (tcfg1 != S3C2410_TCFG1_MUX_TCLK) ++ clk_pwm_tdiv_update(divclk); ++ ++ return 0; ++} ++ ++static struct pwm_tdiv_clk clk_timer_tdiv[] = { ++ [0] = { ++ .clk = { ++ .name = "pwm-tdiv", ++ .parent = &clk_timer_scaler[0], ++ .get_rate = clk_pwm_tdiv_get_rate, ++ .set_rate = clk_pwm_tdiv_set_rate, ++ .round_rate = clk_pwm_tdiv_round_rate, ++ }, ++ }, ++ [1] = { ++ .clk = { ++ .name = "pwm-tdiv", ++ .parent = &clk_timer_scaler[0], ++ .get_rate = clk_pwm_tdiv_get_rate, ++ .set_rate = clk_pwm_tdiv_set_rate, ++ .round_rate = clk_pwm_tdiv_round_rate, ++ } ++ }, ++ [2] = { ++ .clk = { ++ .name = "pwm-tdiv", ++ .parent = &clk_timer_scaler[1], ++ .get_rate = clk_pwm_tdiv_get_rate, ++ .set_rate = clk_pwm_tdiv_set_rate, ++ .round_rate = clk_pwm_tdiv_round_rate, ++ }, ++ }, ++ [3] = { ++ .clk = { ++ .name = "pwm-tdiv", ++ .parent = &clk_timer_scaler[1], ++ .get_rate = clk_pwm_tdiv_get_rate, ++ .set_rate = clk_pwm_tdiv_set_rate, ++ .round_rate = clk_pwm_tdiv_round_rate, ++ }, ++ }, ++ [4] = { ++ .clk = { ++ .name = "pwm-tdiv", ++ .parent = &clk_timer_scaler[1], ++ .get_rate = clk_pwm_tdiv_get_rate, ++ .set_rate = clk_pwm_tdiv_set_rate, ++ .round_rate = clk_pwm_tdiv_round_rate, ++ }, ++ }, ++}; ++ ++static int __init clk_pwm_tdiv_register(unsigned int id) ++{ ++ struct pwm_tdiv_clk *divclk = &clk_timer_tdiv[id]; ++ unsigned long tcfg1 = __raw_readl(S3C2410_TCFG1); ++ ++ tcfg1 >>= S3C2410_TCFG1_SHIFT(id); ++ tcfg1 &= S3C2410_TCFG1_MUX_MASK; ++ ++ divclk->clk.id = id; ++ divclk->divisor = tcfg_to_divisor(tcfg1); ++ ++ return s3c24xx_register_clock(&divclk->clk); ++} ++ ++static inline struct clk *s3c24xx_pwmclk_tclk(unsigned int id) ++{ ++ return (id >= 2) ? &clk_timer_tclk[1] : &clk_timer_tclk[0]; ++} ++ ++static inline struct clk *s3c24xx_pwmclk_tdiv(unsigned int id) ++{ ++ return &clk_timer_tdiv[id].clk; ++} ++ ++static int clk_pwm_tin_set_parent(struct clk *clk, struct clk *parent) ++{ ++ unsigned int id = clk->id; ++ unsigned long tcfg1; ++ unsigned long flags; ++ unsigned long bits; ++ unsigned long shift = S3C2410_TCFG1_SHIFT(id); ++ ++ if (parent == s3c24xx_pwmclk_tclk(id)) ++ bits = S3C2410_TCFG1_MUX_TCLK << shift; ++ else if (parent == s3c24xx_pwmclk_tdiv(id)) ++ bits = clk_pwm_tdiv_bits(to_tdiv(parent)) << shift; ++ else ++ return -EINVAL; ++ ++ clk->parent = parent; ++ ++ local_irq_save(flags); ++ ++ tcfg1 = __raw_readl(S3C2410_TCFG1); ++ tcfg1 &= ~(S3C2410_TCFG1_MUX_MASK << shift); ++ __raw_writel(tcfg1 | bits, S3C2410_TCFG1); ++ ++ local_irq_restore(flags); ++ ++ return 0; ++} ++ ++static struct clk clk_tin[] = { ++ [0] = { ++ .name = "pwm-tin", ++ .id = 0, ++ .set_parent = clk_pwm_tin_set_parent, ++ }, ++ [1] = { ++ .name = "pwm-tin", ++ .id = 1, ++ .set_parent = clk_pwm_tin_set_parent, ++ }, ++ [2] = { ++ .name = "pwm-tin", ++ .id = 2, ++ .set_parent = clk_pwm_tin_set_parent, ++ }, ++ [3] = { ++ .name = "pwm-tin", ++ .id = 3, ++ .set_parent = clk_pwm_tin_set_parent, ++ }, ++ [4] = { ++ .name = "pwm-tin", ++ .id = 4, ++ .set_parent = clk_pwm_tin_set_parent, ++ }, ++}; ++ ++static __init int clk_pwm_tin_register(struct clk *pwm) ++{ ++ unsigned long tcfg1 = __raw_readl(S3C2410_TCFG1); ++ unsigned int id = pwm->id; ++ ++ struct clk *parent; ++ int ret; ++ ++ ret = s3c24xx_register_clock(pwm); ++ if (ret < 0) ++ return ret; ++ ++ tcfg1 >>= S3C2410_TCFG1_SHIFT(id); ++ tcfg1 &= S3C2410_TCFG1_MUX_MASK; ++ ++ if (tcfg1 == S3C2410_TCFG1_MUX_TCLK) ++ parent = s3c24xx_pwmclk_tclk(id); ++ else ++ parent = s3c24xx_pwmclk_tdiv(id); ++ ++ return clk_set_parent(pwm, parent); ++} ++ ++static __init int s3c24xx_pwmclk_init(void) ++{ ++ struct clk *clk_timers; ++ unsigned int clk; ++ int ret; ++ ++ clk_timers = clk_get(NULL, "timers"); ++ if (IS_ERR(clk_timers)) { ++ printk(KERN_ERR "%s: no parent clock\n", __func__); ++ return -EINVAL; ++ } ++ ++ for (clk = 0; clk < ARRAY_SIZE(clk_timer_scaler); clk++) { ++ clk_timer_scaler[clk].parent = clk_timers; ++ ret = s3c24xx_register_clock(&clk_timer_scaler[clk]); ++ if (ret < 0) { ++ printk(KERN_ERR "error adding pwm scaler%d clock\n", clk); ++ goto err; ++ } ++ } ++ ++ for (clk = 0; clk < ARRAY_SIZE(clk_timer_tclk); clk++) { ++ ret = s3c24xx_register_clock(&clk_timer_tclk[clk]); ++ if (ret < 0) { ++ printk(KERN_ERR "error adding pww tclk%d\n", clk); ++ goto err; ++ } ++ } ++ ++ for (clk = 0; clk < ARRAY_SIZE(clk_timer_tdiv); clk++) { ++ ret = clk_pwm_tdiv_register(clk); ++ if (ret < 0) { ++ printk(KERN_ERR "error adding pwm%d tdiv clock\n", clk); ++ goto err; ++ } ++ } ++ ++ for (clk = 0; clk < ARRAY_SIZE(clk_tin); clk++) { ++ ret = clk_pwm_tin_register(&clk_tin[clk]); ++ if (ret < 0) { ++ printk(KERN_ERR "error adding pwm%d tin clock\n", clk); ++ goto err; ++ } ++ } ++ ++ return 0; ++ ++ err: ++ return ret; ++} ++ ++arch_initcall(s3c24xx_pwmclk_init); +diff -ruN --exclude='*.orig' --exclude='*.rej' linux-2.6.29-rc3.owrt/arch/arm/plat-s3c24xx/s3c244x.c linux-2.6.29-rc3.owrt.om/arch/arm/plat-s3c24xx/s3c244x.c +--- linux-2.6.29-rc3.owrt/arch/arm/plat-s3c24xx/s3c244x.c 2009-05-10 22:05:03.000000000 +0200 ++++ linux-2.6.29-rc3.owrt.om/arch/arm/plat-s3c24xx/s3c244x.c 2009-05-10 22:27:59.000000000 +0200 +@@ -59,6 +59,8 @@ + s3c24xx_init_uartdevs("s3c2440-uart", s3c2410_uart_resources, cfg, no); + } + ++extern struct platform_device s3c_device_ts; ++ + void __init s3c244x_map_io(void) + { + /* register our io-tables */ +@@ -70,6 +72,7 @@ + s3c_device_sdi.name = "s3c2440-sdi"; + s3c_device_i2c0.name = "s3c2440-i2c"; + s3c_device_nand.name = "s3c2440-nand"; ++ s3c_device_ts.name = "s3c2440-ts"; + s3c_device_usbgadget.name = "s3c2440-usbgadget"; + } + +@@ -145,13 +148,13 @@ + + static int s3c244x_suspend(struct sys_device *dev, pm_message_t state) + { +- s3c2410_pm_do_save(s3c244x_sleep, ARRAY_SIZE(s3c244x_sleep)); ++ s3c_pm_do_save(s3c244x_sleep, ARRAY_SIZE(s3c244x_sleep)); + return 0; + } + + static int s3c244x_resume(struct sys_device *dev) + { +- s3c2410_pm_do_restore(s3c244x_sleep, ARRAY_SIZE(s3c244x_sleep)); ++ s3c_pm_do_restore(s3c244x_sleep, ARRAY_SIZE(s3c244x_sleep)); + return 0; + } + +diff -ruN --exclude='*.orig' --exclude='*.rej' linux-2.6.29-rc3.owrt/arch/arm/plat-s3c24xx/sleep.S linux-2.6.29-rc3.owrt.om/arch/arm/plat-s3c24xx/sleep.S +--- linux-2.6.29-rc3.owrt/arch/arm/plat-s3c24xx/sleep.S 2009-05-10 22:05:03.000000000 +0200 ++++ linux-2.6.29-rc3.owrt.om/arch/arm/plat-s3c24xx/sleep.S 2009-05-10 22:27:59.000000000 +0200 +@@ -41,7 +41,7 @@ + + .text + +- /* s3c2410_cpu_save ++ /* s3c_cpu_save + * + * save enough of the CPU state to allow us to re-start + * pm.c code. as we store items like the sp/lr, we will +@@ -59,7 +59,7 @@ + * 1 => resumed from sleep + */ + +-ENTRY(s3c2410_cpu_save) ++ENTRY(s3c_cpu_save) + stmfd sp!, { r4 - r12, lr } + + @@ store co-processor registers +@@ -84,7 +84,7 @@ + .ltorg + + @@ the next bits sit in the .data segment, even though they +- @@ happen to be code... the s3c2410_sleep_save_phys needs to be ++ @@ happen to be code... the s3c_sleep_save_phys needs to be + @@ accessed by the resume code before it can restore the MMU. + @@ This means that the variable has to be close enough for the + @@ code to read it... since the .text segment needs to be RO, +@@ -92,19 +92,19 @@ + + .data + +- .global s3c2410_sleep_save_phys +-s3c2410_sleep_save_phys: ++ .global s3c_sleep_save_phys ++s3c_sleep_save_phys: + .word 0 + + + /* sleep magic, to allow the bootloader to check for an valid + * image to resume to. Must be the first word before the +- * s3c2410_cpu_resume entry. ++ * s3c_cpu_resume entry. + */ + + .word 0x2bedf00d + +- /* s3c2410_cpu_resume ++ /* s3c_cpu_resume + * + * resume code entry for bootloader to call + * +@@ -113,7 +113,7 @@ + * must not write to the code segment (code is read-only) + */ + +-ENTRY(s3c2410_cpu_resume) ++ENTRY(s3c_cpu_resume) + mov r0, #PSR_I_BIT | PSR_F_BIT | SVC_MODE + msr cpsr_c, r0 + +@@ -145,7 +145,7 @@ + mcr p15, 0, r1, c8, c7, 0 @@ invalidate I & D TLBs + mcr p15, 0, r1, c7, c7, 0 @@ invalidate I & D caches + +- ldr r0, s3c2410_sleep_save_phys @ address of restore block ++ ldr r0, s3c_sleep_save_phys @ address of restore block + ldmia r0, { r4 - r13 } + + mcr p15, 0, r4, c13, c0, 0 @ PID +diff -ruN --exclude='*.orig' --exclude='*.rej' linux-2.6.29-rc3.owrt/arch/arm/plat-s3c24xx/time.c linux-2.6.29-rc3.owrt.om/arch/arm/plat-s3c24xx/time.c +--- linux-2.6.29-rc3.owrt/arch/arm/plat-s3c24xx/time.c 1970-01-01 01:00:00.000000000 +0100 ++++ linux-2.6.29-rc3.owrt.om/arch/arm/plat-s3c24xx/time.c 2009-05-10 22:27:59.000000000 +0200 +@@ -0,0 +1,480 @@ ++/* linux/arch/arm/plat-s3c24xx/time.c ++ * ++ * Copyright (C) 2003-2005 Simtec Electronics ++ * Ben Dooks, <ben@simtec.co.uk> ++ * ++ * dyn_tick support by Andrzej Zaborowski based on omap_dyn_tick_timer. ++ * ++ * 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, MA 02111-1307 USA ++ */ ++ ++#include <linux/kernel.h> ++#include <linux/sched.h> ++#include <linux/init.h> ++#include <linux/interrupt.h> ++#include <linux/irq.h> ++#include <linux/err.h> ++#include <linux/clk.h> ++ ++#include <asm/system.h> ++#include <asm/leds.h> ++#include <asm/mach-types.h> ++ ++#include <asm/io.h> ++#include <asm/irq.h> ++#include <mach/map.h> ++#include <asm/plat-s3c/regs-timer.h> ++#include <mach/regs-irq.h> ++#include <asm/mach/time.h> ++ ++#include <asm/plat-s3c24xx/clock.h> ++#include <asm/plat-s3c24xx/cpu.h> ++ ++static unsigned long timer_startval; ++static unsigned long timer_usec_ticks; ++static struct work_struct resume_work; ++ ++unsigned long pclk; ++struct clk *clk; ++ ++#define TIMER_USEC_SHIFT 16 ++ ++/* we use the shifted arithmetic to work out the ratio of timer ticks ++ * to usecs, as often the peripheral clock is not a nice even multiple ++ * of 1MHz. ++ * ++ * shift of 14 and 15 are too low for the 12MHz, 16 seems to be ok ++ * for the current HZ value of 200 without producing overflows. ++ * ++ * Original patch by Dimitry Andric, updated by Ben Dooks ++*/ ++ ++ ++/* timer_mask_usec_ticks ++ * ++ * given a clock and divisor, make the value to pass into timer_ticks_to_usec ++ * to scale the ticks into usecs ++*/ ++ ++static inline unsigned long ++timer_mask_usec_ticks(unsigned long scaler, unsigned long pclk) ++{ ++ unsigned long den = pclk / 1000; ++ ++ return ((1000 << TIMER_USEC_SHIFT) * scaler + (den >> 1)) / den; ++} ++ ++/* timer_ticks_to_usec ++ * ++ * convert timer ticks to usec. ++*/ ++ ++static inline unsigned long timer_ticks_to_usec(unsigned long ticks) ++{ ++ unsigned long res; ++ ++ res = ticks * timer_usec_ticks; ++ res += 1 << (TIMER_USEC_SHIFT - 4); /* round up slightly */ ++ ++ return res >> TIMER_USEC_SHIFT; ++} ++ ++/*** ++ * Returns microsecond since last clock interrupt. Note that interrupts ++ * will have been disabled by do_gettimeoffset() ++ * IRQs are disabled before entering here from do_gettimeofday() ++ */ ++ ++#define SRCPND_TIMER4 (1<<(IRQ_TIMER4 - IRQ_EINT0)) ++ ++unsigned long s3c2410_gettimeoffset (void) ++{ ++ unsigned long tdone; ++ unsigned long irqpend; ++ unsigned long tval; ++ ++ /* work out how many ticks have gone since last timer interrupt */ ++ ++ tval = __raw_readl(S3C2410_TCNTO(4)); ++ tdone = timer_startval - tval; ++ ++ /* check to see if there is an interrupt pending */ ++ ++ irqpend = __raw_readl(S3C2410_SRCPND); ++ if (irqpend & SRCPND_TIMER4) { ++ /* re-read the timer, and try and fix up for the missed ++ * interrupt. Note, the interrupt may go off before the ++ * timer has re-loaded from wrapping. ++ */ ++ ++ tval = __raw_readl(S3C2410_TCNTO(4)); ++ tdone = timer_startval - tval; ++ ++ if (tval != 0) ++ tdone += timer_startval; ++ } ++ ++ return timer_ticks_to_usec(tdone); ++} ++ ++ ++/* ++ * IRQ handler for the timer ++ */ ++static irqreturn_t ++s3c2410_timer_interrupt(int irq, void *dev_id) ++{ ++ timer_tick(); ++ return IRQ_HANDLED; ++} ++ ++static struct irqaction s3c2410_timer_irq = { ++ .name = "S3C2410 Timer Tick", ++ .flags = IRQF_DISABLED | IRQF_TIMER | IRQF_IRQPOLL, ++ .handler = s3c2410_timer_interrupt, ++}; ++ ++#define use_tclk1_12() ( \ ++ machine_is_bast() || \ ++ machine_is_vr1000() || \ ++ machine_is_anubis() || \ ++ machine_is_osiris() ) ++ ++/* ++ * Set up timer interrupt, and return the current time in seconds. ++ * ++ * Currently we only use timer4, as it is the only timer which has no ++ * other function that can be exploited externally ++ */ ++static void s3c2410_timer_setup (void) ++{ ++ unsigned long tcon; ++ unsigned long tcnt; ++ unsigned long tcfg1; ++ unsigned long tcfg0; ++ ++ tcnt = 0xffff; /* default value for tcnt */ ++ ++ /* read the current timer configuration bits */ ++ ++ tcon = __raw_readl(S3C2410_TCON); ++ tcfg1 = __raw_readl(S3C2410_TCFG1); ++ tcfg0 = __raw_readl(S3C2410_TCFG0); ++ ++ /* configure the system for whichever machine is in use */ ++ ++ if (use_tclk1_12()) { ++ /* timer is at 12MHz, scaler is 1 */ ++ timer_usec_ticks = timer_mask_usec_ticks(1, 12000000); ++ tcnt = 12000000 / HZ; ++ ++ tcfg1 &= ~S3C2410_TCFG1_MUX4_MASK; ++ tcfg1 |= S3C2410_TCFG1_MUX4_TCLK1; ++ } else { ++ /* since values around 50 to ++ * 70MHz are not values we can directly generate the timer ++ * value from, we need to pre-scale and divide before using it. ++ * ++ * for instance, using 50.7MHz and dividing by 6 gives 8.45MHz ++ * (8.45 ticks per usec) ++ */ ++ ++ /* configure clock tick */ ++ timer_usec_ticks = timer_mask_usec_ticks(6, pclk); ++ printk("timer_usec_ticks = %lu\n", timer_usec_ticks); ++ ++ tcfg1 &= ~S3C2410_TCFG1_MUX4_MASK; ++ tcfg1 |= S3C2410_TCFG1_MUX4_DIV2; ++ ++ tcfg0 &= ~S3C2410_TCFG_PRESCALER1_MASK; ++ tcfg0 |= ((6 - 1) / 2) << S3C2410_TCFG_PRESCALER1_SHIFT; ++ ++ tcnt = (pclk / 6) / HZ; ++ } ++ ++ /* timers reload after counting zero, so reduce the count by 1 */ ++ ++ tcnt--; ++ ++ printk("timer tcon=%08lx, tcnt %04lx, tcfg %08lx,%08lx, usec %08lx\n", ++ tcon, tcnt, tcfg0, tcfg1, timer_usec_ticks); ++ ++ /* check to see if timer is within 16bit range... */ ++ if (tcnt > 0xffff) { ++ panic("setup_timer: HZ is too small, cannot configure timer!"); ++ return; ++ } ++ ++ __raw_writel(tcfg1, S3C2410_TCFG1); ++ __raw_writel(tcfg0, S3C2410_TCFG0); ++ ++ timer_startval = tcnt; ++ __raw_writel(tcnt, S3C2410_TCNTB(4)); ++ ++ /* ensure timer is stopped... */ ++ ++ tcon &= ~(7<<20); ++ tcon |= S3C2410_TCON_T4RELOAD; ++ tcon |= S3C2410_TCON_T4MANUALUPD; ++ ++ __raw_writel(tcon, S3C2410_TCON); ++ __raw_writel(tcnt, S3C2410_TCNTB(4)); ++ __raw_writel(tcnt, S3C2410_TCMPB(4)); ++ ++ /* start the timer running */ ++ tcon |= S3C2410_TCON_T4START; ++ tcon &= ~S3C2410_TCON_T4MANUALUPD; ++ __raw_writel(tcon, S3C2410_TCON); ++ ++ __raw_writel(__raw_readl(S3C2410_INTMSK) & (~(1UL << 14)), ++ S3C2410_INTMSK); ++ ++} ++ ++struct sys_timer s3c24xx_timer; ++static void timer_resume_work(struct work_struct *work) ++{ ++ clk_enable(clk); ++ ++#ifdef CONFIG_NO_IDLE_HZ ++ if (s3c24xx_timer.dyn_tick->state & DYN_TICK_ENABLED) ++ s3c24xx_timer.dyn_tick->enable(); ++ else ++#endif ++ s3c2410_timer_setup(); ++} ++ ++static void __init s3c2410_timer_init (void) ++{ ++ if (!use_tclk1_12()) { ++ /* for the h1940 (and others), we use the pclk from the core ++ * to generate the timer values. ++ */ ++ ++ /* this is used as default if no other timer can be found */ ++ clk = clk_get(NULL, "timers"); ++ if (IS_ERR(clk)) ++ panic("failed to get clock for system timer"); ++ ++ clk_enable(clk); ++ ++ pclk = clk_get_rate(clk); ++ printk("pclk = %lu\n", pclk); ++ } ++ ++ INIT_WORK(&resume_work, timer_resume_work); ++ s3c2410_timer_setup(); ++ setup_irq(IRQ_TIMER4, &s3c2410_timer_irq); ++} ++ ++static void s3c2410_timer_resume_work(struct work_struct *work) ++{ ++ s3c2410_timer_setup(); ++} ++ ++static void s3c2410_timer_resume(void) ++{ ++ static DECLARE_WORK(work, s3c2410_timer_resume_work); ++ int res; ++ ++ res = schedule_work(&work); ++ if (!res) ++ printk(KERN_ERR ++ "s3c2410_timer_resume_work already queued ???\n"); ++} ++ ++#ifdef CONFIG_NO_IDLE_HZ ++/* ++ * We'll set a constant prescaler so we don't have to bother setting it ++ * when reprogramming and so that we avoid costly divisions. ++ * ++ * (2 * HZ) << INPUT_FREQ_SHIFT is the desired frequency after prescaler. ++ * At HZ == 200, HZ * 1024 should work for PCLKs of up to ~53.5 MHz. ++ */ ++#define INPUT_FREQ_SHIFT 9 ++ ++static int ticks_last; ++static int ticks_left; ++static uint32_t tcnto_last; ++ ++static inline int s3c24xx_timer_read(void) ++{ ++ uint32_t tcnto = __raw_readl(S3C2410_TCNTO(4)); ++ ++ /* ++ * WARNING: sometimes we get called before TCNTB has been ++ * loaded into the counter and TCNTO then returns its previous ++ * value and kill us, so don't do anything before counter is ++ * reloaded. ++ */ ++ if (unlikely(tcnto == tcnto_last)) ++ return ticks_last; ++ ++ tcnto_last = -1; ++ return tcnto << ++ ((__raw_readl(S3C2410_TCFG1) >> S3C2410_TCFG1_MUX4_SHIFT) & 3); ++} ++ ++static inline void s3c24xx_timer_program(int ticks) ++{ ++ uint32_t tcon = __raw_readl(S3C2410_TCON) & ~(7 << 20); ++ uint32_t tcfg1 = __raw_readl(S3C2410_TCFG1) & ~S3C2410_TCFG1_MUX4_MASK; ++ ++ /* Just make sure the timer is stopped. */ ++ __raw_writel(tcon, S3C2410_TCON); ++ ++ /* TODO: add likely()ies / unlikely()ies */ ++ if (ticks >> 18) { ++ ticks_last = min(ticks, 0xffff << 3); ++ ticks_left = ticks - ticks_last; ++ __raw_writel(tcfg1 | S3C2410_TCFG1_MUX4_DIV16, S3C2410_TCFG1); ++ __raw_writel(ticks_last >> 3, S3C2410_TCNTB(4)); ++ } else if (ticks >> 17) { ++ ticks_last = ticks; ++ ticks_left = 0; ++ __raw_writel(tcfg1 | S3C2410_TCFG1_MUX4_DIV8, S3C2410_TCFG1); ++ __raw_writel(ticks_last >> 2, S3C2410_TCNTB(4)); ++ } else if (ticks >> 16) { ++ ticks_last = ticks; ++ ticks_left = 0; ++ __raw_writel(tcfg1 | S3C2410_TCFG1_MUX4_DIV4, S3C2410_TCFG1); ++ __raw_writel(ticks_last >> 1, S3C2410_TCNTB(4)); ++ } else { ++ ticks_last = ticks; ++ ticks_left = 0; ++ __raw_writel(tcfg1 | S3C2410_TCFG1_MUX4_DIV2, S3C2410_TCFG1); ++ __raw_writel(ticks_last >> 0, S3C2410_TCNTB(4)); ++ } ++ ++ tcnto_last = __raw_readl(S3C2410_TCNTO(4)); ++ __raw_writel(tcon | S3C2410_TCON_T4MANUALUPD, ++ S3C2410_TCON); ++ __raw_writel(tcon | S3C2410_TCON_T4START, ++ S3C2410_TCON); ++} ++ ++/* ++ * If we have already waited all the time we were supposed to wait, ++ * kick the timer, setting the longest allowed timeout value just ++ * for time-keeping. ++ */ ++static inline void s3c24xx_timer_program_idle(void) ++{ ++ s3c24xx_timer_program(0xffff << 3); ++} ++ ++static inline void s3c24xx_timer_update(int restart) ++{ ++ int ticks_cur = s3c24xx_timer_read(); ++ int jiffies_elapsed = (ticks_last - ticks_cur) >> INPUT_FREQ_SHIFT; ++ int subjiffy = ticks_last - (jiffies_elapsed << INPUT_FREQ_SHIFT); ++ ++ if (restart) { ++ if (ticks_left >= (1 << INPUT_FREQ_SHIFT)) ++ s3c24xx_timer_program(ticks_left); ++ else ++ s3c24xx_timer_program_idle(); ++ ticks_last += subjiffy; ++ } else ++ ticks_last = subjiffy; ++ ++ while (jiffies_elapsed --) ++ timer_tick(); ++} ++ ++/* Called when the timer expires. */ ++static irqreturn_t s3c24xx_timer_handler(int irq, void *dev_id) ++{ ++ tcnto_last = -1; ++ s3c24xx_timer_update(1); ++ ++ return IRQ_HANDLED; ++} ++ ++/* Called to update jiffies with time elapsed. */ ++static irqreturn_t s3c24xx_timer_handler_dyn_tick(int irq, void *dev_id) ++{ ++ s3c24xx_timer_update(0); ++ ++ return IRQ_HANDLED; ++} ++ ++/* ++ * Programs the next timer interrupt needed. Called when dynamic tick is ++ * enabled, and to reprogram the ticks to skip from pm_idle. The CPU goes ++ * to sleep directly after this. ++ */ ++static void s3c24xx_timer_reprogram_dyn_tick(unsigned long next_jiffies) ++{ ++ int subjiffy_left = ticks_last - s3c24xx_timer_read(); ++ ++ s3c24xx_timer_program(max((int) next_jiffies, 1) << INPUT_FREQ_SHIFT); ++ ticks_last += subjiffy_left; ++} ++ ++static unsigned long s3c24xx_timer_offset_dyn_tick(void) ++{ ++ /* TODO */ ++ return 0; ++} ++ ++static int s3c24xx_timer_enable_dyn_tick(void) ++{ ++ /* Set our constant prescaler. */ ++ uint32_t tcfg0 = __raw_readl(S3C2410_TCFG0); ++ int prescaler = ++ max(min(256, (int) pclk / (HZ << (INPUT_FREQ_SHIFT + 1))), 1); ++ ++ tcfg0 &= ~S3C2410_TCFG_PRESCALER1_MASK; ++ tcfg0 |= (prescaler - 1) << S3C2410_TCFG_PRESCALER1_SHIFT; ++ __raw_writel(tcfg0, S3C2410_TCFG0); ++ ++ /* Override handlers. */ ++ s3c2410_timer_irq.handler = s3c24xx_timer_handler; ++ s3c24xx_timer.offset = s3c24xx_timer_offset_dyn_tick; ++ ++ printk(KERN_INFO "dyn_tick enabled on s3c24xx timer 4, " ++ "%li Hz pclk with prescaler %i\n", pclk, prescaler); ++ ++ s3c24xx_timer_program_idle(); ++ ++ return 0; ++} ++ ++static int s3c24xx_timer_disable_dyn_tick(void) ++{ ++ s3c2410_timer_irq.handler = s3c2410_timer_interrupt; ++ s3c24xx_timer.offset = s3c2410_gettimeoffset; ++ s3c2410_timer_setup(); ++ ++ return 0; ++} ++ ++static struct dyn_tick_timer s3c24xx_dyn_tick_timer = { ++ .enable = s3c24xx_timer_enable_dyn_tick, ++ .disable = s3c24xx_timer_disable_dyn_tick, ++ .reprogram = s3c24xx_timer_reprogram_dyn_tick, ++ .handler = s3c24xx_timer_handler_dyn_tick, ++}; ++#endif /* CONFIG_NO_IDLE_HZ */ ++ ++struct sys_timer s3c24xx_timer = { ++ .init = s3c2410_timer_init, ++ .offset = s3c2410_gettimeoffset, ++ .resume = s3c2410_timer_resume, ++#ifdef CONFIG_NO_IDLE_HZ ++ .dyn_tick = &s3c24xx_dyn_tick_timer, ++#endif ++}; +diff -ruN --exclude='*.orig' --exclude='*.rej' linux-2.6.29-rc3.owrt/arch/arm/plat-s3c64xx/clock.c linux-2.6.29-rc3.owrt.om/arch/arm/plat-s3c64xx/clock.c +--- linux-2.6.29-rc3.owrt/arch/arm/plat-s3c64xx/clock.c 2009-05-10 22:08:41.000000000 +0200 ++++ linux-2.6.29-rc3.owrt.om/arch/arm/plat-s3c64xx/clock.c 2009-05-10 22:27:59.000000000 +0200 +@@ -27,6 +27,12 @@ + #include <plat/devs.h> + #include <plat/clock.h> + ++struct clk clk_h2 = { ++ .name = "hclk2", ++ .id = -1, ++ .rate = 0, ++}; ++ + struct clk clk_27m = { + .name = "clk_27m", + .id = -1, +@@ -83,7 +89,7 @@ + return s3c64xx_gate(S3C_PCLK_GATE, clk, enable); + } + +-static int s3c64xx_hclk_ctrl(struct clk *clk, int enable) ++int s3c64xx_hclk_ctrl(struct clk *clk, int enable) + { + return s3c64xx_gate(S3C_HCLK_GATE, clk, enable); + } +@@ -152,6 +158,30 @@ + .parent = &clk_48m, + .enable = s3c64xx_sclk_ctrl, + .ctrlbit = S3C_CLKCON_SCLK_MMC2_48, ++ }, { ++ .name = "dma0", ++ .id = -1, ++ .parent = &clk_h, ++ .enable = s3c64xx_hclk_ctrl, ++ .ctrlbit = S3C_CLKCON_HCLK_DMA0, ++ }, { ++ .name = "dma1", ++ .id = -1, ++ .parent = &clk_h, ++ .enable = s3c64xx_hclk_ctrl, ++ .ctrlbit = S3C_CLKCON_HCLK_DMA1, ++ }, { ++ .name = "dma2", ++ .id = -1, ++ .parent = &clk_h, ++ .enable = s3c64xx_hclk_ctrl, ++ .ctrlbit = S3C_CLKCON_HCLK_SDMA0, ++ }, { ++ .name = "dma3", ++ .id = -1, ++ .parent = &clk_h, ++ .enable = s3c64xx_hclk_ctrl, ++ .ctrlbit = S3C_CLKCON_HCLK_SDMA1, + }, + }; + +@@ -246,6 +276,7 @@ + &clk_epll, + &clk_27m, + &clk_48m, ++ &clk_h2, + }; + + void s3c64xx_register_clocks(void) +diff -ruN --exclude='*.orig' --exclude='*.rej' linux-2.6.29-rc3.owrt/arch/arm/plat-s3c64xx/cpu.c linux-2.6.29-rc3.owrt.om/arch/arm/plat-s3c64xx/cpu.c +--- linux-2.6.29-rc3.owrt/arch/arm/plat-s3c64xx/cpu.c 2009-05-10 22:05:04.000000000 +0200 ++++ linux-2.6.29-rc3.owrt.om/arch/arm/plat-s3c64xx/cpu.c 2009-05-10 22:27:59.000000000 +0200 +@@ -16,6 +16,7 @@ + #include <linux/module.h> + #include <linux/interrupt.h> + #include <linux/ioport.h> ++#include <linux/sysdev.h> + #include <linux/serial_core.h> + #include <linux/platform_device.h> + #include <linux/io.h> +@@ -96,9 +97,34 @@ + .pfn = __phys_to_pfn(S3C64XX_PA_GPIO), + .length = SZ_4K, + .type = MT_DEVICE, +- }, ++ }, { ++ .virtual = (unsigned long)S3C64XX_VA_MODEM, ++ .pfn = __phys_to_pfn(S3C64XX_PA_MODEM), ++ .length = SZ_4K, ++ .type = MT_DEVICE, ++ }, { ++ .virtual = (unsigned long)S3C_VA_TZIC0, ++ .pfn = __phys_to_pfn(S3C64XX_PA_TZIC0), ++ .length = SZ_4K, ++ .type = MT_DEVICE, ++ }, { ++ .virtual = (unsigned long)S3C_VA_TZIC1, ++ .pfn = __phys_to_pfn(S3C64XX_PA_TZIC1), ++ .length = SZ_4K, ++ .type = MT_DEVICE, ++ } + }; + ++ ++struct sysdev_class s3c64xx_sysclass = { ++ .name = "s3c64xx-core", ++}; ++ ++static struct sys_device s3c64xx_sysdev = { ++ .cls = &s3c64xx_sysclass, ++}; ++ ++ + /* read cpu identification code */ + + void __init s3c64xx_init_io(struct map_desc *mach_desc, int size) +@@ -112,3 +138,11 @@ + idcode = __raw_readl(S3C_VA_SYS + 0x118); + s3c_init_cpu(idcode, cpu_ids, ARRAY_SIZE(cpu_ids)); + } ++ ++static __init int s3c64xx_sysdev_init(void) ++{ ++ sysdev_class_register(&s3c64xx_sysclass); ++ return sysdev_register(&s3c64xx_sysdev); ++} ++ ++core_initcall(s3c64xx_sysdev_init); +diff -ruN --exclude='*.orig' --exclude='*.rej' linux-2.6.29-rc3.owrt/arch/arm/plat-s3c64xx/cpufreq.c linux-2.6.29-rc3.owrt.om/arch/arm/plat-s3c64xx/cpufreq.c +--- linux-2.6.29-rc3.owrt/arch/arm/plat-s3c64xx/cpufreq.c 1970-01-01 01:00:00.000000000 +0100 ++++ linux-2.6.29-rc3.owrt.om/arch/arm/plat-s3c64xx/cpufreq.c 2009-05-10 22:27:59.000000000 +0200 +@@ -0,0 +1,225 @@ ++/* linux/arch/arm/plat-s3c64xx/cpufreq.c ++ * ++ * Copyright 2009 Wolfson Microelectronics plc ++ * ++ * S3C64XX CPUfreq Support ++ * ++ * This program is free software; you can redistribute it and/or modify ++ * it under the terms of the GNU General Public License version 2 as ++ * published by the Free Software Foundation. ++ */ ++ ++#include <linux/kernel.h> ++#include <linux/types.h> ++#include <linux/init.h> ++#include <linux/cpufreq.h> ++#include <linux/clk.h> ++#include <linux/err.h> ++#include <linux/regulator/consumer.h> ++ ++#include <mach/cpu.h> ++ ++static struct clk *armclk; ++static struct regulator *vddarm; ++ ++struct s3c64xx_dvfs { ++ unsigned int vddarm_min; ++ unsigned int vddarm_max; ++}; ++ ++static struct s3c64xx_dvfs s3c6410_dvfs_table[] = { ++ [0] = { 1000000, 1000000 }, ++ [1] = { 1000000, 1050000 }, ++ [2] = { 1050000, 1100000 }, ++ [3] = { 1050000, 1150000 }, ++ [4] = { 1250000, 1350000 }, ++}; ++ ++static struct cpufreq_frequency_table s3c6410_freq_table[] = { ++ { 0, 66000 }, ++ { 0, 133000 }, ++ { 1, 222000 }, ++ { 1, 266000 }, ++ { 2, 333000 }, ++ { 2, 400000 }, ++ { 3, 532000 }, ++ { 3, 533000 }, ++ { 4, 667000 }, ++ { 0, CPUFREQ_TABLE_END }, ++}; ++ ++/* Data tables for current CPU and maximum index into it */ ++static struct cpufreq_frequency_table *s3c64xx_freq_table; ++static struct s3c64xx_dvfs *s3c64xx_dvfs_table; ++ ++static int s3c64xx_cpufreq_verify_speed(struct cpufreq_policy *policy) ++{ ++ if (policy->cpu != 0) ++ return -EINVAL; ++ ++ return cpufreq_frequency_table_verify(policy, s3c64xx_freq_table); ++} ++ ++static unsigned int s3c64xx_cpufreq_get_speed(unsigned int cpu) ++{ ++ if (cpu != 0) ++ return 0; ++ ++ return clk_get_rate(armclk) / 1000; ++} ++ ++static int s3c64xx_cpufreq_set_target(struct cpufreq_policy *policy, ++ unsigned int target_freq, ++ unsigned int relation) ++{ ++ int ret = 0; ++ unsigned int i; ++ struct cpufreq_freqs freqs; ++ struct s3c64xx_dvfs *dvfs; ++ ++ ret = cpufreq_frequency_table_target(policy, s3c64xx_freq_table, ++ target_freq, relation, &i); ++ if (ret != 0) ++ return ret; ++ ++ freqs.cpu = 0; ++ freqs.old = clk_get_rate(armclk) / 1000; ++ freqs.new = s3c64xx_freq_table[i].frequency; ++ freqs.flags = 0; ++ dvfs = &s3c64xx_dvfs_table[s3c64xx_freq_table[i].index]; ++ ++ if (freqs.old == freqs.new) ++ return 0; ++ ++ pr_debug("cpufreq: Transition %d-%dkHz\n", freqs.old, freqs.new); ++ ++ cpufreq_notify_transition(&freqs, CPUFREQ_PRECHANGE); ++ ++#ifdef CONFIG_REGULATOR ++ if (vddarm && freqs.new > freqs.old) { ++ ret = regulator_set_voltage(vddarm, ++ dvfs->vddarm_min, ++ dvfs->vddarm_max); ++ if (ret != 0) { ++ pr_err("cpufreq: Failed to set VDDARM for %dkHz: %d\n", ++ freqs.new, ret); ++ goto err; ++ } ++ } ++#endif ++ ++ ret = clk_set_rate(armclk, freqs.new * 1000); ++ if (ret < 0) { ++ pr_err("cpufreq: Failed to set rate %dkHz: %d\n", ++ freqs.new, ret); ++ goto err; ++ } ++ ++#ifdef CONFIG_REGULATOR ++ if (vddarm && freqs.new < freqs.old) { ++ ret = regulator_set_voltage(vddarm, ++ dvfs->vddarm_min, ++ dvfs->vddarm_max); ++ if (ret != 0) { ++ pr_err("cpufreq: Failed to set VDDARM for %dkHz: %d\n", ++ freqs.new, ret); ++ goto err_clk; ++ } ++ } ++#endif ++ ++ cpufreq_notify_transition(&freqs, CPUFREQ_POSTCHANGE); ++ ++ pr_debug("cpufreq: Set actual frequency %lukHz\n", ++ clk_get_rate(armclk) / 1000); ++ ++ return 0; ++ ++err_clk: ++ if (clk_set_rate(armclk, freqs.old * 1000) < 0) ++ pr_err("Failed to restore original clock rate\n"); ++err: ++ cpufreq_notify_transition(&freqs, CPUFREQ_POSTCHANGE); ++ ++ return ret; ++} ++ ++ ++static int __init s3c64xx_cpufreq_driver_init(struct cpufreq_policy *policy) ++{ ++ int ret; ++ struct cpufreq_frequency_table *freq;; ++ ++ if (policy->cpu != 0) ++ return -EINVAL; ++ ++ if (cpu_is_s3c6410()) { ++ s3c64xx_freq_table = s3c6410_freq_table; ++ s3c64xx_dvfs_table = s3c6410_dvfs_table; ++ } ++ ++ if (s3c64xx_freq_table == NULL) { ++ pr_err("cpufreq: No frequency information for this CPU\n"); ++ return -ENODEV; ++ } ++ ++ armclk = clk_get(NULL, "armclk"); ++ if (IS_ERR(armclk)) { ++ pr_err("cpufreq: Unable to obtain ARMCLK: %ld\n", ++ PTR_ERR(armclk)); ++ return PTR_ERR(armclk); ++ } ++ ++#ifdef CONFIG_REGULATOR ++ vddarm = regulator_get(NULL, "vddarm"); ++ if (IS_ERR(vddarm)) { ++ ret = PTR_ERR(vddarm); ++ pr_err("cpufreq: Failed to obtain VDDARM: %d\n", ret); ++ pr_err("cpufreq: Only frequency scaling available\n"); ++ vddarm = NULL; ++ } ++#endif ++ ++ /* Check for frequencies we can generate */ ++ freq = s3c64xx_freq_table; ++ while (freq->frequency != CPUFREQ_TABLE_END) { ++ unsigned long r; ++ ++ r = clk_round_rate(armclk, freq->frequency * 1000); ++ r /= 1000; ++ ++ if (r != freq->frequency) ++ freq->frequency = CPUFREQ_ENTRY_INVALID; ++ ++ freq++; ++ } ++ ++ policy->cur = clk_get_rate(armclk) / 1000; ++ policy->cpuinfo.transition_latency = CPUFREQ_ETERNAL; ++ ++ ret = cpufreq_frequency_table_cpuinfo(policy, s3c64xx_freq_table); ++ if (ret == 0) ++ return ret; ++ ++ pr_err("cpufreq: Failed to configure frequency table: %d\n", ret); ++ ++ regulator_put(vddarm); ++ clk_put(armclk); ++ return ret; ++} ++ ++static struct cpufreq_driver s3c64xx_cpufreq_driver = { ++ .owner = THIS_MODULE, ++ .flags = 0, ++ .verify = s3c64xx_cpufreq_verify_speed, ++ .target = s3c64xx_cpufreq_set_target, ++ .get = s3c64xx_cpufreq_get_speed, ++ .init = s3c64xx_cpufreq_driver_init, ++ .name = "s3c64xx", ++}; ++ ++static int __init s3c64xx_cpufreq_init(void) ++{ ++ return cpufreq_register_driver(&s3c64xx_cpufreq_driver); ++} ++module_init(s3c64xx_cpufreq_init); +diff -ruN --exclude='*.orig' --exclude='*.rej' linux-2.6.29-rc3.owrt/arch/arm/plat-s3c64xx/dev-usbgadget.c linux-2.6.29-rc3.owrt.om/arch/arm/plat-s3c64xx/dev-usbgadget.c +--- linux-2.6.29-rc3.owrt/arch/arm/plat-s3c64xx/dev-usbgadget.c 1970-01-01 01:00:00.000000000 +0100 ++++ linux-2.6.29-rc3.owrt.om/arch/arm/plat-s3c64xx/dev-usbgadget.c 2009-05-10 22:27:59.000000000 +0200 +@@ -0,0 +1,32 @@ ++/* Base S3C64XX usbgadget resource and device definitions */ ++ ++#include <linux/kernel.h> ++#include <linux/interrupt.h> ++#include <linux/platform_device.h> ++#include <linux/ioport.h> ++ ++#include <mach/map.h> ++#include <plat/map-base.h> ++#include <plat/devs.h> ++#include <plat/irqs.h> ++ ++static struct resource s3c_usbgadget_resource[] = { ++ [0] = { ++ .start = S3C64XX_PA_OTG, ++ .end = S3C64XX_PA_OTG + 0x200000 - 1, ++ .flags = IORESOURCE_MEM, ++ }, ++ [1] = { ++ .start = IRQ_OTG, ++ .end = IRQ_OTG, ++ .flags = IORESOURCE_IRQ, ++ } ++}; ++ ++struct platform_device s3c_device_usbgadget = { ++ .name = "s3c-otg-usbgadget", ++ .id = -1, ++ .num_resources = ARRAY_SIZE(s3c_usbgadget_resource), ++ .resource = s3c_usbgadget_resource, ++}; ++EXPORT_SYMBOL(s3c_device_usbgadget); +diff -ruN --exclude='*.orig' --exclude='*.rej' linux-2.6.29-rc3.owrt/arch/arm/plat-s3c64xx/dma.c linux-2.6.29-rc3.owrt.om/arch/arm/plat-s3c64xx/dma.c +--- linux-2.6.29-rc3.owrt/arch/arm/plat-s3c64xx/dma.c 1970-01-01 01:00:00.000000000 +0100 ++++ linux-2.6.29-rc3.owrt.om/arch/arm/plat-s3c64xx/dma.c 2009-05-10 22:27:59.000000000 +0200 +@@ -0,0 +1,728 @@ ++/* linux/arch/arm/plat-s3c64xx/dma.c ++ * ++ * Copyright 2009 Openmoko, Inc. ++ * Copyright 2009 Simtec Electronics ++ * Ben Dooks <ben@simtec.co.uk> ++ * http://armlinux.simtec.co.uk/ ++ * ++ * S3C64XX DMA core ++ * ++ * 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/interrupt.h> ++#include <linux/dmapool.h> ++#include <linux/sysdev.h> ++#include <linux/errno.h> ++#include <linux/delay.h> ++#include <linux/clk.h> ++#include <linux/err.h> ++#include <linux/io.h> ++ ++#include <mach/dma.h> ++#include <mach/irqs.h> ++ ++#include <plat/dma-plat.h> ++ ++#include <plat/pl080.h> ++#include <mach/map.h> ++#include <plat/regs-sys.h> ++ ++#define DEBUG ++ ++#undef pr_debug ++#define pr_debug(x...) printk(x) ++ ++/* dma channel state information */ ++ ++ ++struct s3c64xx_dmac { ++ struct sys_device sysdev; ++ struct clk *clk; ++ void __iomem *regs; ++ struct s3c2410_dma_chan *channels; ++ enum dma_ch chanbase; ++}; ++ ++/* pool to provide LLI buffers */ ++static struct dma_pool *dma_pool; ++ ++/* Debug configuration and code */ ++ ++static unsigned char debug_show_buffs = 0; ++ ++static void dbg_showchan(struct s3c2410_dma_chan *chan) ++{ ++ pr_debug("DMA%d: %08x->%08x L %08x C %08x,%08x S %08x\n", ++ chan->number, ++ readl(chan->regs + PL080_CH_SRC_ADDR), ++ readl(chan->regs + PL080_CH_DST_ADDR), ++ readl(chan->regs + PL080_CH_LLI), ++ readl(chan->regs + PL080_CH_CONTROL), ++ readl(chan->regs + PL080S_CH_CONTROL2), ++ readl(chan->regs + PL080S_CH_CONFIG)); ++} ++ ++static void show_lli(struct pl080_lli *lli) ++{ ++ pr_debug("LLI[%p] %08x->%08x, NL %08x C %08x,%08x\n", ++ lli, lli->src_addr, lli->dst_addr, lli->next_lli, ++ lli->control0, lli->control1); ++} ++ ++static void dbg_showbuffs(struct s3c2410_dma_chan *chan) ++{ ++ struct s3c64xx_dma_buff *ptr; ++ struct s3c64xx_dma_buff *end; ++ ++ pr_debug("DMA%d: buffs next %p, curr %p, end %p\n", ++ chan->number, chan->next, chan->curr, chan->end); ++ ++ ptr = chan->next; ++ end = chan->end; ++ ++ if (debug_show_buffs) { ++ for (; ptr != NULL; ptr = ptr->next) { ++ pr_debug("DMA%d: %08x ", ++ chan->number, ptr->lli_dma); ++ show_lli(ptr->lli); ++ } ++ } ++} ++ ++/* End of Debug */ ++ ++static struct s3c2410_dma_chan *s3c64xx_dma_map_channel(unsigned int channel) ++{ ++ struct s3c2410_dma_chan *chan; ++ unsigned int start, offs; ++ ++ start = 0; ++ ++ if (channel >= DMACH_PCM1_TX) ++ start = 8; ++ ++ for (offs = 0; offs < 8; offs++) { ++ chan = &s3c2410_chans[start + offs]; ++ if (!chan->in_use) ++ goto found; ++ } ++ ++ return NULL; ++ ++found: ++ s3c_dma_chan_map[channel] = chan; ++ return chan; ++} ++ ++int s3c2410_dma_config(unsigned int channel, int xferunit) ++{ ++ struct s3c2410_dma_chan *chan = s3c_dma_lookup_channel(channel); ++ ++ if (chan == NULL) ++ return -EINVAL; ++ ++ switch (xferunit) { ++ case 1: ++ chan->hw_width = 0; ++ break; ++ case 2: ++ chan->hw_width = 1; ++ break; ++ case 4: ++ chan->hw_width = 2; ++ break; ++ default: ++ printk(KERN_ERR "%s: illegal width %d\n", __func__, xferunit); ++ return -EINVAL; ++ } ++ ++ return 0; ++} ++EXPORT_SYMBOL(s3c2410_dma_config); ++ ++static void s3c64xx_dma_fill_lli(struct s3c2410_dma_chan *chan, ++ struct pl080_lli *lli, ++ dma_addr_t data, int size) ++{ ++ dma_addr_t src, dst; ++ u32 control0, control1; ++ ++ switch (chan->source) { ++ case S3C2410_DMASRC_HW: ++ src = chan->dev_addr; ++ dst = data; ++ control0 = PL080_CONTROL_SRC_AHB2; ++ control0 |= (u32)chan->hw_width << PL080_CONTROL_SWIDTH_SHIFT; ++ control0 |= 2 << PL080_CONTROL_DWIDTH_SHIFT; ++ control0 |= PL080_CONTROL_DST_INCR; ++ break; ++ ++ case S3C2410_DMASRC_MEM: ++ src = data; ++ dst = chan->dev_addr; ++ control0 = PL080_CONTROL_DST_AHB2; ++ control0 |= (u32)chan->hw_width << PL080_CONTROL_DWIDTH_SHIFT; ++ control0 |= 2 << PL080_CONTROL_SWIDTH_SHIFT; ++ control0 |= PL080_CONTROL_SRC_INCR; ++ break; ++ default: ++ BUG(); ++ } ++ ++ /* todo - burst control */ ++ ++ control1 = size / 4; /* TODO - calculate */ ++ control0 |= PL080_CONTROL_PROT_SYS; /* always in priv. mode */ ++ control0 |= PL080_CONTROL_TC_IRQ_EN; /* always fire IRQ */ ++ ++ lli->src_addr = src; ++ lli->dst_addr = dst; ++ lli->next_lli = 0; ++ lli->control0 = control0; ++ lli->control1 = control1; ++} ++ ++static void s3c64xx_lli_to_regs(struct s3c2410_dma_chan *chan, ++ struct pl080_lli *lli) ++{ ++ void __iomem *regs = chan->regs; ++ ++ pr_debug("%s: LLI %p => regs\n", __func__, lli); ++ show_lli(lli); ++ ++ writel(lli->src_addr, regs + PL080_CH_SRC_ADDR); ++ writel(lli->dst_addr, regs + PL080_CH_DST_ADDR); ++ writel(lli->next_lli, regs + PL080_CH_LLI); ++ writel(lli->control0, regs + PL080_CH_CONTROL); ++ writel(lli->control1, regs + PL080S_CH_CONTROL2); ++} ++ ++static int s3c64xx_dma_start(struct s3c2410_dma_chan *chan) ++{ ++ struct s3c64xx_dmac *dmac = chan->dmac; ++ u32 config; ++ u32 bit = chan->bit; ++ ++ dbg_showchan(chan); ++ ++ pr_debug("%s: clearing interrupts\n", __func__); ++ ++ /* clear interrupts */ ++ writel(bit, dmac->regs + PL080_TC_CLEAR); ++ writel(bit, dmac->regs + PL080_ERR_CLEAR); ++ ++ pr_debug("%s: starting channel\n", __func__); ++ ++ config = readl(chan->regs + PL080S_CH_CONFIG); ++ config |= PL080_CONFIG_ENABLE; ++ ++ pr_debug("%s: writing config %08x\n", __func__, config); ++ writel(config, chan->regs + PL080S_CH_CONFIG); ++ ++ return 0; ++} ++ ++static int s3c64xx_dma_stop(struct s3c2410_dma_chan *chan) ++{ ++ u32 config; ++ int timeout; ++ ++ pr_debug("%s: stopping channel\n", __func__); ++ ++ dbg_showchan(chan); ++ ++ config = readl(chan->regs + PL080S_CH_CONFIG); ++ config |= PL080_CONFIG_HALT; ++ writel(config, chan->regs + PL080S_CH_CONFIG); ++ ++ timeout = 1000; ++ do { ++ config = readl(chan->regs + PL080S_CH_CONFIG); ++ pr_debug("%s: %d - config %08x\n", __func__, timeout, config); ++ if (config & PL080_CONFIG_ACTIVE) ++ udelay(100); ++ else ++ break; ++ } while (--timeout > 0); ++ ++ if (config & PL080_CONFIG_ACTIVE) { ++ printk(KERN_ERR "%s: channel still active\n", __func__); ++ return -EFAULT; ++ } ++ ++ config = readl(chan->regs + PL080S_CH_CONFIG); ++ config &= ~PL080_CONFIG_ENABLE; ++ writel(config, chan->regs + PL080S_CH_CONFIG); ++ ++ return 0; ++} ++ ++static inline void s3c64xx_dma_bufffdone(struct s3c2410_dma_chan *chan, ++ struct s3c64xx_dma_buff *buf, ++ enum s3c2410_dma_buffresult result) ++{ ++ if (chan->callback_fn != NULL) ++ (chan->callback_fn)(chan, buf->pw, 0, result); ++} ++ ++static void s3c64xx_dma_freebuff(struct s3c64xx_dma_buff *buff) ++{ ++ dma_pool_free(dma_pool, buff->lli, buff->lli_dma); ++ kfree(buff); ++} ++ ++static int s3c64xx_dma_flush(struct s3c2410_dma_chan *chan) ++{ ++ struct s3c64xx_dma_buff *buff, *next; ++ u32 config; ++ ++ dbg_showchan(chan); ++ ++ pr_debug("%s: flushing channel\n", __func__); ++ ++ config = readl(chan->regs + PL080S_CH_CONFIG); ++ config &= ~PL080_CONFIG_ENABLE; ++ writel(config, chan->regs + PL080S_CH_CONFIG); ++ ++ /* dump all the buffers associated with this channel */ ++ ++ for (buff = chan->curr; buff != NULL; buff = next) { ++ next = buff->next; ++ pr_debug("%s: buff %p (next %p)\n", __func__, buff, buff->next); ++ ++ s3c64xx_dma_bufffdone(chan, buff, S3C2410_RES_ABORT); ++ s3c64xx_dma_freebuff(buff); ++ } ++ ++ chan->curr = chan->next = chan->end = NULL; ++ ++ return 0; ++} ++ ++int s3c2410_dma_ctrl(unsigned int channel, enum s3c2410_chan_op op) ++{ ++ struct s3c2410_dma_chan *chan = s3c_dma_lookup_channel(channel); ++ ++ WARN_ON(!chan); ++ if (!chan) ++ return -EINVAL; ++ ++ switch (op) { ++ case S3C2410_DMAOP_START: ++ return s3c64xx_dma_start(chan); ++ ++ case S3C2410_DMAOP_STOP: ++ return s3c64xx_dma_stop(chan); ++ ++ case S3C2410_DMAOP_FLUSH: ++ return s3c64xx_dma_flush(chan); ++ ++ /* belive PAUSE/RESUME are no-ops */ ++ case S3C2410_DMAOP_PAUSE: ++ case S3C2410_DMAOP_RESUME: ++ case S3C2410_DMAOP_STARTED: ++ case S3C2410_DMAOP_TIMEOUT: ++ return 0; ++ } ++ ++ return -ENOENT; ++} ++EXPORT_SYMBOL(s3c2410_dma_ctrl); ++ ++/* s3c2410_dma_enque ++ * ++ */ ++ ++int s3c2410_dma_enqueue(unsigned int channel, void *id, ++ dma_addr_t data, int size) ++{ ++ struct s3c2410_dma_chan *chan = s3c_dma_lookup_channel(channel); ++ struct s3c64xx_dma_buff *next; ++ struct s3c64xx_dma_buff *buff; ++ struct pl080_lli *lli; ++ int ret; ++ ++ WARN_ON(!chan); ++ if (!chan) ++ return -EINVAL; ++ ++ buff = kzalloc(sizeof(struct s3c64xx_dma_buff), GFP_KERNEL); ++ if (!buff) { ++ printk(KERN_ERR "%s: no memory for buffer\n", __func__); ++ return -ENOMEM; ++ } ++ ++ lli = dma_pool_alloc(dma_pool, GFP_KERNEL, &buff->lli_dma); ++ if (!lli) { ++ printk(KERN_ERR "%s: no memory for lli\n", __func__); ++ ret = -ENOMEM; ++ goto err_buff; ++ } ++ ++ pr_debug("%s: buff %p, dp %08x lli (%p, %08x) %d\n", ++ __func__, buff, data, lli, (u32)buff->lli_dma, size); ++ ++ buff->lli = lli; ++ buff->pw = id; ++ ++ s3c64xx_dma_fill_lli(chan, lli, data, size); ++ ++ if ((next = chan->next) != NULL) { ++ struct s3c64xx_dma_buff *end = chan->end; ++ struct pl080_lli *endlli = end->lli; ++ ++ pr_debug("enquing onto channel\n"); ++ ++ end->next = buff; ++ endlli->next_lli = buff->lli_dma; ++ ++ if (chan->flags & S3C2410_DMAF_CIRCULAR) { ++ struct s3c64xx_dma_buff *curr = chan->curr; ++ lli->next_lli = curr->lli_dma; ++ } ++ ++ if (next == chan->curr) { ++ writel(buff->lli_dma, chan->regs + PL080_CH_LLI); ++ chan->next = buff; ++ } ++ ++ show_lli(endlli); ++ chan->end = buff; ++ } else { ++ pr_debug("enquing onto empty channel\n"); ++ ++ chan->curr = buff; ++ chan->next = buff; ++ chan->end = buff; ++ ++ s3c64xx_lli_to_regs(chan, lli); ++ } ++ ++ show_lli(lli); ++ ++ dbg_showchan(chan); ++ dbg_showbuffs(chan); ++ return 0; ++ ++err_buff: ++ kfree(buff); ++ return ret; ++} ++ ++EXPORT_SYMBOL(s3c2410_dma_enqueue); ++ ++ ++int s3c2410_dma_devconfig(int channel, ++ enum s3c2410_dmasrc source, ++ unsigned long devaddr) ++{ ++ struct s3c2410_dma_chan *chan = s3c_dma_lookup_channel(channel); ++ u32 peripheral; ++ u32 config = 0; ++ ++ printk("%s: channel %d, source %d, dev %08lx, chan %p\n", ++ __func__, channel, source, devaddr, chan); ++ ++ WARN_ON(!chan); ++ if (!chan) ++ return -EINVAL; ++ ++ peripheral = (chan->peripheral & 0xf); ++ chan->source = source; ++ chan->dev_addr = devaddr; ++ ++ pr_debug("%s: peripheral %d\n", __func__, peripheral); ++ ++ switch (source) { ++ case S3C2410_DMASRC_HW: ++ config = 2 << PL080_CONFIG_FLOW_CONTROL_SHIFT; ++ config |= peripheral << PL080_CONFIG_SRC_SEL_SHIFT; ++ break; ++ case S3C2410_DMASRC_MEM: ++ config = 1 << PL080_CONFIG_FLOW_CONTROL_SHIFT; ++ config |= peripheral << PL080_CONFIG_DST_SEL_SHIFT; ++ break; ++ default: ++ printk(KERN_ERR "%s: bad source\n", __func__); ++ return -EINVAL; ++ } ++ ++ /* allow TC and ERR interrupts */ ++ config |= PL080_CONFIG_TC_IRQ_MASK; ++ config |= PL080_CONFIG_ERR_IRQ_MASK; ++ ++ pr_debug("%s: config %08x\n", __func__, config); ++ ++ writel(config, chan->regs + PL080S_CH_CONFIG); ++ ++ return 0; ++} ++EXPORT_SYMBOL(s3c2410_dma_devconfig); ++ ++ ++int s3c2410_dma_getposition(unsigned int channel, ++ dma_addr_t *src, dma_addr_t *dst) ++{ ++ struct s3c2410_dma_chan *chan = s3c_dma_lookup_channel(channel); ++ ++ WARN_ON(!chan); ++ if (!chan) ++ return -EINVAL; ++ ++ if (src != NULL) ++ *src = readl(chan->regs + PL080_CH_SRC_ADDR); ++ ++ if (dst != NULL) ++ *dst = readl(chan->regs + PL080_CH_DST_ADDR); ++ ++ return 0; ++} ++EXPORT_SYMBOL(s3c2410_dma_getposition); ++ ++/* s3c2410_request_dma ++ * ++ * get control of an dma channel ++*/ ++ ++int s3c2410_dma_request(unsigned int channel, ++ struct s3c2410_dma_client *client, ++ void *dev) ++{ ++ struct s3c2410_dma_chan *chan; ++ unsigned long flags; ++ ++ pr_debug("dma%d: s3c2410_request_dma: client=%s, dev=%p\n", ++ channel, client->name, dev); ++ ++ local_irq_save(flags); ++ ++ chan = s3c64xx_dma_map_channel(channel); ++ if (chan == NULL) { ++ local_irq_restore(flags); ++ return -EBUSY; ++ } ++ ++ dbg_showchan(chan); ++ ++ chan->client = client; ++ chan->in_use = 1; ++ chan->peripheral = channel; ++ ++ local_irq_restore(flags); ++ ++ /* need to setup */ ++ ++ pr_debug("%s: channel initialised, %p\n", __func__, chan); ++ ++ return chan->number | DMACH_LOW_LEVEL; ++} ++ ++EXPORT_SYMBOL(s3c2410_dma_request); ++ ++/* s3c2410_dma_free ++ * ++ * release the given channel back to the system, will stop and flush ++ * any outstanding transfers, and ensure the channel is ready for the ++ * next claimant. ++ * ++ * Note, although a warning is currently printed if the freeing client ++ * info is not the same as the registrant's client info, the free is still ++ * allowed to go through. ++*/ ++ ++int s3c2410_dma_free(unsigned int channel, struct s3c2410_dma_client *client) ++{ ++ struct s3c2410_dma_chan *chan = s3c_dma_lookup_channel(channel); ++ unsigned long flags; ++ ++ if (chan == NULL) ++ return -EINVAL; ++ ++ local_irq_save(flags); ++ ++ if (chan->client != client) { ++ printk(KERN_WARNING "dma%d: possible free from different client (channel %p, passed %p)\n", ++ channel, chan->client, client); ++ } ++ ++ /* sort out stopping and freeing the channel */ ++ ++ ++ chan->client = NULL; ++ chan->in_use = 0; ++ ++ if (!(channel & DMACH_LOW_LEVEL)) ++ s3c_dma_chan_map[channel] = NULL; ++ ++ local_irq_restore(flags); ++ ++ return 0; ++} ++ ++EXPORT_SYMBOL(s3c2410_dma_free); ++ ++ ++static void s3c64xx_dma_tcirq(struct s3c64xx_dmac *dmac, int offs) ++{ ++ struct s3c2410_dma_chan *chan = dmac->channels + offs; ++ ++ /* note, we currently do not bother to work out which buffer ++ * or buffers have been completed since the last tc-irq. */ ++ ++ if (chan->callback_fn) ++ (chan->callback_fn)(chan, chan->curr->pw, 0, S3C2410_RES_OK); ++} ++ ++static void s3c64xx_dma_errirq(struct s3c64xx_dmac *dmac, int offs) ++{ ++ printk(KERN_DEBUG "%s: offs %d\n", __func__, offs); ++} ++ ++static irqreturn_t s3c64xx_dma_irq(int irq, void *pw) ++{ ++ struct s3c64xx_dmac *dmac = pw; ++ u32 tcstat, errstat; ++ u32 bit; ++ int offs; ++ ++ tcstat = readl(dmac->regs + PL080_TC_STATUS); ++ errstat = readl(dmac->regs + PL080_ERR_STATUS); ++ ++ for (offs = 0, bit = 1; offs < 8; offs++, bit <<= 1) { ++ if (tcstat & bit) { ++ writel(bit, dmac->regs + PL080_TC_CLEAR); ++ s3c64xx_dma_tcirq(dmac, offs); ++ } ++ ++ if (errstat & bit) { ++ s3c64xx_dma_errirq(dmac, offs); ++ writel(bit, dmac->regs + PL080_ERR_CLEAR); ++ } ++ } ++ ++ return IRQ_HANDLED; ++} ++ ++static struct sysdev_class dma_sysclass = { ++ .name = "s3c64xx-dma", ++}; ++ ++static int s3c64xx_dma_init1(int chno, enum dma_ch chbase, ++ int irq, unsigned int base) ++{ ++ struct s3c2410_dma_chan *chptr = &s3c2410_chans[chno]; ++ struct s3c64xx_dmac *dmac; ++ char clkname[16]; ++ void __iomem *regs; ++ void __iomem *regptr; ++ int err, ch; ++ ++ dmac = kzalloc(sizeof(struct s3c64xx_dmac), GFP_KERNEL); ++ if (!dmac) { ++ printk(KERN_ERR "%s: failed to alloc mem\n", __func__); ++ return -ENOMEM; ++ } ++ ++ dmac->sysdev.id = chno / 8; ++ dmac->sysdev.cls = &dma_sysclass; ++ ++ err = sysdev_register(&dmac->sysdev); ++ if (err) { ++ printk(KERN_ERR "%s: failed to register sysdevice\n", __func__); ++ goto err_alloc; ++ } ++ ++ regs = ioremap(base, 0x200); ++ if (!regs) { ++ printk(KERN_ERR "%s: failed to ioremap()\n", __func__); ++ err = -ENXIO; ++ goto err_dev; ++ } ++ ++ snprintf(clkname, sizeof(clkname), "dma%d", dmac->sysdev.id); ++ ++ dmac->clk = clk_get(NULL, clkname); ++ if (IS_ERR(dmac->clk)) { ++ printk(KERN_ERR "%s: failed to get clock %s\n", __func__, clkname); ++ err = PTR_ERR(dmac->clk); ++ goto err_map; ++ } ++ ++ clk_enable(dmac->clk); ++ ++ dmac->regs = regs; ++ dmac->chanbase = chbase; ++ dmac->channels = chptr; ++ ++ err = request_irq(irq, s3c64xx_dma_irq, 0, "DMA", dmac); ++ if (err < 0) { ++ printk(KERN_ERR "%s: failed to get irq\n", __func__); ++ goto err_clk; ++ } ++ ++ regptr = regs + PL080_Cx_BASE(0); ++ ++ for (ch = 0; ch < 8; ch++, chno++, chptr++) { ++ printk(KERN_INFO "%s: registering DMA %d (%p)\n", ++ __func__, chno, regptr); ++ ++ chptr->bit = 1 << ch; ++ chptr->number = chno; ++ chptr->dmac = dmac; ++ chptr->regs = regptr; ++ regptr += PL008_Cx_STRIDE; ++ } ++ ++ /* for the moment, permanently enable the controller */ ++ writel(PL080_CONFIG_ENABLE, regs + PL080_CONFIG); ++ ++ printk(KERN_INFO "PL080: IRQ %d, at %p\n", irq, regs); ++ ++ return 0; ++ ++err_clk: ++ clk_disable(dmac->clk); ++ clk_put(dmac->clk); ++err_map: ++ iounmap(regs); ++err_dev: ++ sysdev_unregister(&dmac->sysdev); ++err_alloc: ++ kfree(dmac); ++ return err; ++} ++ ++static int __init s3c64xx_dma_init(void) ++{ ++ int ret; ++ ++ printk(KERN_INFO "%s: Registering DMA channels\n", __func__); ++ ++ dma_pool = dma_pool_create("DMA-LLI", NULL, 32, 16, 0); ++ if (!dma_pool) { ++ printk(KERN_ERR "%s: failed to create pool\n", __func__); ++ return -ENOMEM; ++ } ++ ++ ret = sysdev_class_register(&dma_sysclass); ++ if (ret) { ++ printk(KERN_ERR "%s: failed to create sysclass\n", __func__); ++ return -ENOMEM; ++ } ++ ++ /* Set all DMA configuration to be DMA, not SDMA */ ++ writel(0xffffff, S3C_SYSREG(0x110)); ++ ++ /* Register standard DMA controlers */ ++ s3c64xx_dma_init1(0, DMACH_UART0, IRQ_DMA0, 0x75000000); ++ s3c64xx_dma_init1(8, DMACH_PCM1_TX, IRQ_DMA1, 0x75100000); ++ ++ return 0; ++} ++ ++arch_initcall(s3c64xx_dma_init); +diff -ruN --exclude='*.orig' --exclude='*.rej' linux-2.6.29-rc3.owrt/arch/arm/plat-s3c64xx/dma-fake.c linux-2.6.29-rc3.owrt.om/arch/arm/plat-s3c64xx/dma-fake.c +--- linux-2.6.29-rc3.owrt/arch/arm/plat-s3c64xx/dma-fake.c 1970-01-01 01:00:00.000000000 +0100 ++++ linux-2.6.29-rc3.owrt.om/arch/arm/plat-s3c64xx/dma-fake.c 2009-05-10 22:27:59.000000000 +0200 +@@ -0,0 +1,36 @@ ++/* linux/arch/arm/plat-s3c64xx/dma.c ++ * ++ * Copyright 2009 Simtec Electronics ++ * Ben Dooks <ben@simtec.co.uk> ++ * ++ * S3C64XX DMA core - fake ++ * ++ * http://armlinux.simtec.co.uk/ ++ * ++ * 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/init.h> ++#include <linux/sched.h> ++#include <linux/spinlock.h> ++#include <linux/interrupt.h> ++#include <linux/sysdev.h> ++#include <linux/slab.h> ++#include <linux/errno.h> ++#include <linux/io.h> ++ ++#include <asm/system.h> ++#include <asm/irq.h> ++#include <mach/hardware.h> ++#include <mach/dma.h> ++ ++ ++int s3c2410_dma_ctrl(unsigned int channel, enum s3c2410_chan_op op) ++{ ++ return 0; ++} ++ ++EXPORT_SYMBOL(s3c2410_dma_ctrl); +diff -ruN --exclude='*.orig' --exclude='*.rej' linux-2.6.29-rc3.owrt/arch/arm/plat-s3c64xx/gpiolib.c linux-2.6.29-rc3.owrt.om/arch/arm/plat-s3c64xx/gpiolib.c +--- linux-2.6.29-rc3.owrt/arch/arm/plat-s3c64xx/gpiolib.c 2009-05-10 22:08:41.000000000 +0200 ++++ linux-2.6.29-rc3.owrt.om/arch/arm/plat-s3c64xx/gpiolib.c 2009-05-10 22:27:59.000000000 +0200 +@@ -18,6 +18,7 @@ + + #include <mach/map.h> + #include <mach/gpio.h> ++#include <mach/irqs.h> + #include <mach/gpio-core.h> + + #include <plat/gpio-cfg.h> +@@ -321,6 +322,11 @@ + .get_pull = s3c_gpio_getpull_updown, + }; + ++static int s3c_gpiolib_bankn_toirq(struct gpio_chip *chip, unsigned offset) ++{ ++ return S3C_EINT(0) + offset; ++} ++ + static struct s3c_gpio_chip gpio_2bit[] = { + { + .base = S3C64XX_GPF_BASE, +@@ -353,6 +359,7 @@ + .base = S3C64XX_GPN(0), + .ngpio = S3C64XX_GPIO_N_NR, + .label = "GPN", ++ .to_irq = s3c_gpiolib_bankn_toirq, + }, + }, { + .base = S3C64XX_GPO_BASE, +@@ -385,12 +392,19 @@ + { + chip->chip.direction_input = s3c64xx_gpiolib_4bit_input; + chip->chip.direction_output = s3c64xx_gpiolib_4bit_output; ++ chip->pm = __gpio_pm(&s3c_gpio_pm_4bit); + } + + static __init void s3c64xx_gpiolib_add_4bit2(struct s3c_gpio_chip *chip) + { + chip->chip.direction_input = s3c64xx_gpiolib_4bit2_input; + chip->chip.direction_output = s3c64xx_gpiolib_4bit2_output; ++ chip->pm = __gpio_pm(&s3c_gpio_pm_4bit); ++} ++ ++static __init void s3c64xx_gpiolib_add_2bit(struct s3c_gpio_chip *chip) ++{ ++ chip->pm = __gpio_pm(&s3c_gpio_pm_2bit); + } + + static __init void s3c64xx_gpiolib_add(struct s3c_gpio_chip *chips, +@@ -412,7 +426,8 @@ + s3c64xx_gpiolib_add(gpio_4bit2, ARRAY_SIZE(gpio_4bit2), + s3c64xx_gpiolib_add_4bit2); + +- s3c64xx_gpiolib_add(gpio_2bit, ARRAY_SIZE(gpio_2bit), NULL); ++ s3c64xx_gpiolib_add(gpio_2bit, ARRAY_SIZE(gpio_2bit), ++ s3c64xx_gpiolib_add_2bit); + + return 0; + } +diff -ruN --exclude='*.orig' --exclude='*.rej' linux-2.6.29-rc3.owrt/arch/arm/plat-s3c64xx/include/plat/dma-plat.h linux-2.6.29-rc3.owrt.om/arch/arm/plat-s3c64xx/include/plat/dma-plat.h +--- linux-2.6.29-rc3.owrt/arch/arm/plat-s3c64xx/include/plat/dma-plat.h 1970-01-01 01:00:00.000000000 +0100 ++++ linux-2.6.29-rc3.owrt.om/arch/arm/plat-s3c64xx/include/plat/dma-plat.h 2009-05-10 22:27:59.000000000 +0200 +@@ -0,0 +1,70 @@ ++/* linux/arch/arm/plat-s3c64xx/include/plat/dma-plat.h ++ * ++ * Copyright 2009 Openmoko, Inc. ++ * Copyright 2009 Simtec Electronics ++ * Ben Dooks <ben@simtec.co.uk> ++ * http://armlinux.simtec.co.uk/ ++ * ++ * S3C64XX DMA core ++ * ++ * 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. ++*/ ++ ++#define DMACH_LOW_LEVEL (1<<28) /* use this to specifiy hardware ch no */ ++ ++struct s3c64xx_dma_buff; ++ ++/** s3c64xx_dma_buff - S3C64XX DMA buffer descriptor ++ * @next: Pointer to next buffer in queue or ring. ++ * @pw: Client provided identifier ++ * @lli: Pointer to hardware descriptor this buffer is associated with. ++ * @lli_dma: Hardare address of the descriptor. ++ */ ++struct s3c64xx_dma_buff { ++ struct s3c64xx_dma_buff *next; ++ ++ void *pw; ++ struct pl080_lli *lli; ++ dma_addr_t lli_dma; ++}; ++ ++struct s3c64xx_dmac; ++ ++struct s3c2410_dma_chan { ++ unsigned char number; /* number of this dma channel */ ++ unsigned char in_use; /* channel allocated */ ++ unsigned char bit; /* bit for enable/disable/etc */ ++ unsigned char hw_width; ++ unsigned char peripheral; ++ ++ unsigned int flags; ++ enum s3c2410_dmasrc source; ++ ++ ++ dma_addr_t dev_addr; ++ ++ struct s3c2410_dma_client *client; ++ struct s3c64xx_dmac *dmac; /* pointer to controller */ ++ ++ void __iomem *regs; ++ ++ /* cdriver callbacks */ ++ s3c2410_dma_cbfn_t callback_fn; /* buffer done callback */ ++ s3c2410_dma_opfn_t op_fn; /* channel op callback */ ++ ++ /* buffer list and information */ ++ struct s3c64xx_dma_buff *curr; /* current dma buffer */ ++ struct s3c64xx_dma_buff *next; /* next buffer to load */ ++ struct s3c64xx_dma_buff *end; /* end of queue */ ++ ++ /* note, when channel is running in circular mode, curr is the ++ * first buffer enqueued, end is the last and curr is where the ++ * last buffer-done event is set-at. The buffers are not freed ++ * and the last buffer hardware descriptor points back to the ++ * first. ++ */ ++}; ++ ++#include <plat/dma-core.h> +diff -ruN --exclude='*.orig' --exclude='*.rej' linux-2.6.29-rc3.owrt/arch/arm/plat-s3c64xx/include/plat/irqs.h linux-2.6.29-rc3.owrt.om/arch/arm/plat-s3c64xx/include/plat/irqs.h +--- linux-2.6.29-rc3.owrt/arch/arm/plat-s3c64xx/include/plat/irqs.h 2009-05-10 22:08:41.000000000 +0200 ++++ linux-2.6.29-rc3.owrt.om/arch/arm/plat-s3c64xx/include/plat/irqs.h 2009-05-10 22:27:59.000000000 +0200 +@@ -148,6 +148,7 @@ + /* compatibility for device defines */ + + #define IRQ_IIC1 IRQ_S3C6410_IIC1 ++#define IRQ_USBH IRQ_UHOST + + /* Since the IRQ_EINT(x) are a linear mapping on current s3c64xx series + * we just defined them as an IRQ_EINT(x) macro from S3C_IRQ_EINT_BASE +@@ -157,6 +158,7 @@ + + #define S3C_EINT(x) ((x) + S3C_IRQ_EINT_BASE) + #define IRQ_EINT(x) S3C_EINT(x) ++#define IRQ_EINT_BIT(x) ((x) - S3C_EINT(0)) + + /* Next the external interrupt groups. These are similar to the IRQ_EINT(x) + * that they are sourced from the GPIO pins but with a different scheme for +@@ -197,5 +199,6 @@ + + #define NR_IRQS (IRQ_EINT_GROUP9_BASE + IRQ_EINT_GROUP9_NR + 1) + ++#define FIQ_START S3C_IRQ(0) + #endif /* __ASM_PLAT_S3C64XX_IRQS_H */ + +diff -ruN --exclude='*.orig' --exclude='*.rej' linux-2.6.29-rc3.owrt/arch/arm/plat-s3c64xx/include/plat/pl080.h linux-2.6.29-rc3.owrt.om/arch/arm/plat-s3c64xx/include/plat/pl080.h +--- linux-2.6.29-rc3.owrt/arch/arm/plat-s3c64xx/include/plat/pl080.h 1970-01-01 01:00:00.000000000 +0100 ++++ linux-2.6.29-rc3.owrt.om/arch/arm/plat-s3c64xx/include/plat/pl080.h 2009-05-10 22:27:59.000000000 +0200 +@@ -0,0 +1,110 @@ ++/* arch/arm/include/asm/hardware/pl080.h ++ * ++ * Copyright 2008 Openmoko, Inc. ++ * Copyright 2008 Simtec Electronics ++ * http://armlinux.simtec.co.uk/ ++ * Ben Dooks <ben@simtec.co.uk> ++ * ++ * ARM PrimeCell PL080 DMA controller ++ * ++ * 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. ++*/ ++ ++/* Note, there are some Samsung updates to this controller block which ++ * make it not entierly compatible with the PL080 specification from ++ * ARM. When in doubt, check the Samsung documentation first. ++ * ++ * The Samsung defines are PL080S, and add an extra controll register, ++ * the ability to move more than 2^11 counts of data and some extra ++ * OneNAND features. ++*/ ++ ++#define PL080_INT_STATUS (0x00) ++#define PL080_TC_STATUS (0x04) ++#define PL080_TC_CLEAR (0x08) ++#define PL080_ERR_STATUS (0x0C) ++#define PL080_ERR_CLEAR (0x10) ++#define PL080_RAW_TC_STATUS (0x14) ++#define PL080_RAW_ERR_STATUS (0x18) ++#define PL080_EN_CHAN (0x1c) ++#define PL080_SOFT_BREQ (0x20) ++#define PL080_SOFT_SREQ (0x24) ++#define PL080_SOFT_LBREQ (0x28) ++#define PL080_SOFT_LSREQ (0x2C) ++ ++#define PL080_CONFIG (0x30) ++#define PL080_CONFIG_M2_BE (1 << 2) ++#define PL080_CONFIG_M1_BE (1 << 1) ++#define PL080_CONFIG_ENABLE (1 << 0) ++ ++#define PL080_SYNC (0x34) ++ ++/* Per channel configuration registers */ ++ ++#define PL008_Cx_STRIDE (0x20) ++#define PL080_Cx_BASE(x) ((0x100 + (x * 0x20))) ++#define PL080_Cx_SRC_ADDR(x) ((0x100 + (x * 0x20))) ++#define PL080_Cx_DST_ADDR(x) ((0x104 + (x * 0x20))) ++#define PL080_Cx_LLI(x) ((0x108 + (x * 0x20))) ++#define PL080_Cx_CONTROL(x) ((0x10C + (x * 0x20))) ++#define PL080_Cx_CONFIG(x) ((0x110 + (x * 0x20))) ++#define PL080S_Cx_CONTROL2(x) ((0x110 + (x * 0x20))) ++#define PL080S_Cx_CONFIG(x) ((0x114 + (x * 0x20))) ++ ++#define PL080_CH_SRC_ADDR (0x00) ++#define PL080_CH_DST_ADDR (0x04) ++#define PL080_CH_LLI (0x08) ++#define PL080_CH_CONTROL (0x0C) ++#define PL080_CH_CONFIG (0x10) ++#define PL080S_CH_CONTROL2 (0x10) ++#define PL080S_CH_CONFIG (0x14) ++ ++#define PL080_LLI_ADDR_MASK (0x3fffffff << 2) ++#define PL080_LLI_ADDR_SHIFT (2) ++#define PL080_LLI_LM_AHB2 (1 << 0) ++ ++#define PL080_CONTROL_TC_IRQ_EN (1 << 31) ++#define PL080_CONTROL_PROT_MASK (0x7 << 28) ++#define PL080_CONTROL_PROT_SHIFT (28) ++#define PL080_CONTROL_PROT_SYS (1 << 28) ++#define PL080_CONTROL_DST_INCR (1 << 27) ++#define PL080_CONTROL_SRC_INCR (1 << 26) ++#define PL080_CONTROL_DST_AHB2 (1 << 25) ++#define PL080_CONTROL_SRC_AHB2 (1 << 24) ++#define PL080_CONTROL_DWIDTH_MASK (0x7 << 21) ++#define PL080_CONTROL_DWIDTH_SHIFT (21) ++#define PL080_CONTROL_SWIDTH_MASK (0x7 << 18) ++#define PL080_CONTROL_SWIDTH_SHIFT (18) ++#define PL080_CONTROL_DB_SIZE_MASK (0x7 << 15) ++#define PL080_CONTROL_DB_SIZE_SHIFT (15) ++#define PL080_CONTROL_SB_SIZE_MASK (0x7 << 12) ++#define PL080_CONTROL_SB_SIZE_SHIFT (12) ++#define PL080_CONTROL_TRANSFER_SIZE_MASK (0xfff << 0) ++#define PL080_CONTROL_TRANSFER_SIZE_SHIFT (0) ++ ++#define PL080_CONFIG_HALT (1 << 18) ++#define PL080_CONFIG_ACTIVE (1 << 17) ++#define PL080_CONFIG_LOCK (1 << 16) ++#define PL080_CONFIG_TC_IRQ_MASK (1 << 15) ++#define PL080_CONFIG_ERR_IRQ_MASK (1 << 14) ++#define PL080_CONFIG_FLOW_CONTROL_MASK (0x7 << 11) ++#define PL080_CONFIG_FLOW_CONTROL_SHIFT (11) ++#define PL080_CONFIG_DST_SEL_MASK (0xf << 6) ++#define PL080_CONFIG_DST_SEL_SHIFT (6) ++#define PL080_CONFIG_SRC_SEL_MASK (0xf << 1) ++#define PL080_CONFIG_SRC_SEL_SHIFT (1) ++#define PL080_CONFIG_ENABLE (1 << 0) ++ ++ ++/* DMA linked list chain structure */ ++ ++struct pl080_lli { ++ u32 src_addr; ++ u32 dst_addr; ++ u32 next_lli; ++ u32 control0; ++ u32 control1; ++}; ++ +diff -ruN --exclude='*.orig' --exclude='*.rej' linux-2.6.29-rc3.owrt/arch/arm/plat-s3c64xx/include/plat/pm-core.h linux-2.6.29-rc3.owrt.om/arch/arm/plat-s3c64xx/include/plat/pm-core.h +--- linux-2.6.29-rc3.owrt/arch/arm/plat-s3c64xx/include/plat/pm-core.h 1970-01-01 01:00:00.000000000 +0100 ++++ linux-2.6.29-rc3.owrt.om/arch/arm/plat-s3c64xx/include/plat/pm-core.h 2009-05-10 22:27:59.000000000 +0200 +@@ -0,0 +1,106 @@ ++/* linux/arch/arm/plat-s3c64xx/include/plat/pm-core.h ++ * ++ * Copyright 2008 Openmoko, Inc. ++ * Copyright 2008 Simtec Electronics ++ * Ben Dooks <ben@simtec.co.uk> ++ * http://armlinux.simtec.co.uk/ ++ * ++ * S3C64XX - PM core support for arch/arm/plat-s3c/pm.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 <plat/regs-gpio.h> ++ ++static inline void s3c_pm_debug_init_uart(void) ++{ ++ u32 tmp = __raw_readl(S3C_PCLK_GATE); ++ ++ /* As a note, since the S3C64XX UARTs generally have multiple ++ * clock sources, we simply enable PCLK at the moment and hope ++ * that the resume settings for the UART are suitable for the ++ * use with PCLK. ++ */ ++ ++ tmp |= S3C_CLKCON_PCLK_UART0; ++ tmp |= S3C_CLKCON_PCLK_UART1; ++ tmp |= S3C_CLKCON_PCLK_UART2; ++ tmp |= S3C_CLKCON_PCLK_UART3; ++ ++ __raw_writel(tmp, S3C_PCLK_GATE); ++ udelay(10); ++} ++ ++static inline void s3c_pm_arch_clear_vic(void __iomem *base) ++{ ++ __raw_writel(~0, base + VIC_INT_ENABLE_CLEAR); ++ __raw_writel(~0, base + VIC_INT_SOFT_CLEAR); ++} ++ ++static inline void s3c_pm_arch_prepare_irqs(void) ++{ ++ /* shutdown the VICs */ ++ s3c_pm_arch_clear_vic(S3C_VA_VIC0); ++ s3c_pm_arch_clear_vic(S3C_VA_VIC1); ++ ++ /* clear any pending EINT0 interrupts */ ++ __raw_writel(__raw_readl(S3C64XX_EINT0PEND), S3C64XX_EINT0PEND); ++} ++ ++static inline void s3c_pm_arch_stop_clocks(void) ++{ ++} ++ ++static inline void s3c_pm_arch_show_resume_irqs(void) ++{ ++} ++ ++/* make these defines, we currently do not have any need to change ++ * the IRQ wake controls depending on the CPU we are running on */ ++ ++#define s3c_irqwake_eintallow ((1 << 28) - 1) ++#define s3c_irqwake_intallow (0) ++ ++static inline void s3c_pm_arch_update_uart(void __iomem *regs, ++ struct pm_uart_save *save) ++{ ++ u32 ucon = __raw_readl(regs + S3C2410_UCON); ++ u32 ucon_clk = ucon & S3C6400_UCON_CLKMASK; ++ u32 save_clk = save->ucon & S3C6400_UCON_CLKMASK; ++ u32 new_ucon; ++ u32 delta; ++ ++ /* S3C64XX UART blocks only support level interrupts, so ensure that ++ * when we restore unused UART blocks we force the level interrupt ++ * settigs. */ ++ save->ucon |= S3C2410_UCON_TXILEVEL | S3C2410_UCON_RXILEVEL; ++ ++ /* We have a constraint on changing the clock type of the UART ++ * between UCLKx and PCLK, so ensure that when we restore UCON ++ * that the CLK field is correctly modified if the bootloader ++ * has changed anything. ++ */ ++ if (ucon_clk != save_clk) { ++ new_ucon = save->ucon; ++ delta = ucon_clk ^ save_clk; ++ ++ /* change from UCLKx => wrong PCLK, ++ * either UCLK can be tested for by a bit-test ++ * with UCLK0 */ ++ if (ucon_clk & S3C6400_UCON_UCLK0 && ++ !(save_clk & S3C6400_UCON_UCLK0) && ++ delta & S3C6400_UCON_PCLK2) { ++ new_ucon &= ~S3C6400_UCON_UCLK0; ++ } else if (delta == S3C6400_UCON_PCLK2) { ++ /* as an precaution, don't change from ++ * PCLK2 => PCLK or vice-versa */ ++ new_ucon ^= S3C6400_UCON_PCLK2; ++ } ++ ++ S3C_PMDBG("ucon change %04x => %04x (save=%04x)\n", ++ ucon, new_ucon, save->ucon); ++ save->ucon = new_ucon; ++ } ++} +diff -ruN --exclude='*.orig' --exclude='*.rej' linux-2.6.29-rc3.owrt/arch/arm/plat-s3c64xx/include/plat/regs-camif.h linux-2.6.29-rc3.owrt.om/arch/arm/plat-s3c64xx/include/plat/regs-camif.h +--- linux-2.6.29-rc3.owrt/arch/arm/plat-s3c64xx/include/plat/regs-camif.h 1970-01-01 01:00:00.000000000 +0100 ++++ linux-2.6.29-rc3.owrt.om/arch/arm/plat-s3c64xx/include/plat/regs-camif.h 2009-05-10 22:27:59.000000000 +0200 +@@ -0,0 +1,460 @@ ++/* arch/arm/plat-s3c64xx/include/plat/regs-camif.h ++ * ++ * Copyright (c) 2003 Simtec Electronics <linux@simtec.co.uk> ++ * http://www.simtec.co.uk/products/SWLINUX/ ++ * ++ * 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_ARCH_REGS_CAMIF_H ++#define ___ASM_ARCH_REGS_CAMIF_H ++ ++#define S3C_CAMIFREG(x) (x) ++ ++/************************************************************************* ++ * Macro part ++ ************************************************************************/ ++#define S3C_CISRCFMT_SOURCEHSIZE(x) ((x) << 16) ++#define S3C_CISRCFMT_GET_SOURCEHSIZE(x) (((x) >> 16) & 0x1FFFF) ++#define S3C_CISRCFMT_SOURCEVSIZE(x) ((x) << 0) ++#define S3C_CISRCFMT_GET_SOURCEVSIZE(x) (((x) >> 0) & 0x1FFF) ++ ++#define S3C_CIWDOFST_WINHOROFST(x) ((x) << 16) ++#define S3C_CIWDOFST_GET_WINHOROFST(x) (((x) >> 16) & 0x7FF) ++#define S3C_CIWDOFST_WINVEROFST(x) ((x) << 0) ++#define S3C_CIWDOFST_GET_WINVEROFST(x) (((x) >> 0) & 0x7FF) ++ ++#define S3C_CIDOWSFT2_WINHOROFST2(x) ((x) << 16) ++#define S3C_CIDOWSFT2_GET_WINHOROFST2(x) (((x) >> 16) & 0x7FF) ++#define S3C_CIDOWSFT2_WINVEROFST2(x) ((x) << 0) ++#define S3C_CIDOWSFT2_GET_WINVEROFST2(x) (((x) >> 0) & 0x7FF) ++ ++#define S3C_CICOTRGFMT_TARGETHSIZE_CO(x) ((x) << 16) ++#define S3C_CICOTRGFMT_GET_TARGETHSIZE_CO(x) (((x) >> 16) & 0x1FFF) ++ ++#define S3C_CICOTRGFMT_TARGETVSIZE_CO(x) ((x) << 0) ++#define S3C_CICOTRGFMT_GET_TARGETVSIZE_CO(x) (((x) >> 0) & 0x1FFF) ++ ++#define S3C_CICOCTRL_YBURST1_CO(x) ((x) << 19) ++#define S3C_CICOCTRL_YBURST2_CO(x) ((x) << 14) ++#define S3C_CICOCTRL_CBURST1_CO(x) ((x) << 9) ++#define S3C_CICOCTRL_CBURST2_CO(x) ((x) << 4) ++ ++#define S3C_CICOSCPRERATIO_SHFACTOR_CO(x) ((x) << 28) ++#define S3C_CICOSCPRERATIO_GET_SHFACTOR_CO(x) (((x) >> 28) & 0x7F) ++#define S3C_CICOSCPRERATIO_PREHORRATIO_CO(x) ((x) << 16) ++#define S3C_CICOSCPRERATIO_GET_PREHORRATIO_CO(x) (((x) >> 16) & 0x7F) ++#define S3C_CICOSCPRERATIO_PREVERRATIO_CO(x) ((x) << 0) ++#define S3C_CICOSCPRERATIO_GET_PREVERRATIO_CO(x) (((x) >> 0) & 0x7F) ++ ++#define S3C_CICOSCPREDST_PREDSTWIDTH_CO(x) ((x) << 16) ++#define S3C_CICOSCPREDST_GET_PREDSTWIDTH_CO(x) (((x) >> 16) & 0x7FF) ++#define S3C_CICOSCPREDST_PREDSTHEIGHT_CO(x) ((x) << 0) ++#define S3C_CICOSCPREDST_GET_PREDSTHEIGHT_CO(x) (((x) >> 0) & 0x7FF) ++ ++#define S3C_CICOSCCTRL_MAINHORRATIO_CO(x) ((x) << 16) ++#define S3C_CICOSCCTRL_GET_MAINHORRATIO_CO(x) (((x) >> 16) & 0x1FF) ++#define S3C_CICOSCCTRL_MAINVERRATIO_CO(x) ((x) << 0) ++ ++#define S3C_CICOSTATUS_FRAMECNT_CO(x) ((x) << 26) ++#define S3C_CICOSTATUS_GET_FRAMECNT_CO(x) (((x) >> 26) & 0x3) ++ ++#define S3C_CIPRTRGFMT_TARGETHSIZE_PR(x) ((x) << 16) ++#define S3C_CIPRTRGFMT_GET_TARGETHSIZE_PR(x) (((x) >> 16) & 0x1FFF) ++ ++#define S3C_CIPRTRGFMT_GET_ROT90_PR(x) (((x) >> 13) & 0x1) ++ ++#define S3C_CIPRTRGFMT_TARGETVSIZE_PR(x) ((x) << 0) ++#define S3C_CIPRTRGFMT_GET_TARGETVSIZE_PR(x) (((x) >> 0) & 0x1FFF) ++ ++#define S3C_CIPRSCPRERATIO_SHFACTOR_PR(x) ((x) << 28) ++#define S3C_CIPRSCPRERATIO_GET_SHFACTOR_PR(x) (((x) >> 28) & 0xF) ++#define S3C_CIPRSCPRERATIO_PREHORRATIO_PR(x) ((x) << 16) ++#define S3C_CIPRSCPRERATIO_GET_PREHORRATIO_PR(x) (((x) >> 16) & 0x7F) ++#define S3C_CIPRSCPRERATIO_PREVERRATIO_PR(x) ((x) << 0) ++#define S3C_CIPRSCPRERATIO_GET_PREVERRATIO_PR(x) (((x) >> 0) & 0x7F) ++ ++#define S3C_CIPRSCPREDST_PREDSTWIDTH_PR(x) ((x) << 16) ++#define S3C_CIPRSCPREDST_GET_PREDSTWIDTH_PR(x) (((x) >> 16) & 0xFFF) ++#define S3C_CIPRSCPREDST_PREDSTHEIGHT_PR(x) ((x) << 0) ++#define S3C_CIPRSCPREDST_GET_PREDSTHEIGHT_PR(x) (((x) >> 0) & 0xFFF) ++ ++#define S3C_CIPRSCCTRL_MAINHORRATIO_PR(x) ((x) << 16) ++#define S3C_CIPRSCCTRL_GET_MAINHORRATIO_PR(x) (((x) >> 16) && 0x1FF) ++#define S3C_CIPRSCCTRL_MAINVERRATIO_PR(x) ((x) << 0) ++#define S3C_CIPRSCCTRL_GET_MAINVERRATIO_PR(x) (((x) >> 0) && 0x1FF) ++ ++/************************************************************************* ++ * Bit definition part ++ ************************************************************************/ ++/* Windows Offset Register */ ++#define S3C_CIWDOFST_WINOFSEN (1 << 31) ++#define S3C_CIWDOFST_CLROVCOFIY (1 << 30) ++#define S3C_CIWDOFST_CLROVRLB_CO (1 << 29) ++#define S3C_CIWDOFST_CLROVRLB_PR (1 << 28) ++#define S3C_CIWDOFST_CLROVPRFIY (1 << 27) ++#define S3C_CIWDOFST_CLROVCOFICB (1 << 15) ++#define S3C_CIWDOFST_CLROVCOFICR (1 << 14) ++#define S3C_CIWDOFST_CLROVPRFICB (1 << 13) ++#define S3C_CIWDOFST_CLROVPRFICR (1 << 12) ++ ++/* Global Control Register */ ++#define S3C_CIGCTRL_SWRST (1 << 31) ++#define S3C_CIGCTRL_CAMRST (1 << 30) ++ ++#if defined (CONFIG_CPU_S3C6400) || defined (CONFIG_CPU_S3C6410) ++#define S3C_CIGCTRL_IRQ_LEVEL (1 << 20) ++#endif ++ ++#define S3C_CIGCTRL_TESTPATTERN_VER_INC (3 << 27) ++#define S3C_CIGCTRL_TESTPATTERN_HOR_INC (2 << 27) ++#define S3C_CIGCTRL_TESTPATTERN_COLOR_BAR (1 << 27) ++#define S3C_CIGCTRL_TESTPATTERN_NORMAL (0 << 27) ++ ++#define S3C_CIGCTRL_INVPOLPCLK (1 << 26) ++#define S3C_CIGCTRL_INVPOLVSYNC (1 << 25) ++#define S3C_CIGCTRL_INVPOLHREF (1 << 24) ++#define S3C_CIGCTRL_IRQ_OVFEN (1 << 22) ++#define S3C_CIGCTRL_HREF_MASK (1 << 21) ++#define S3C_CIGCTRL_IRQ_LEVEL (1 << 20) ++#define S3C_CIGCTRL_IRQ_CLR_C (1 << 19) ++#define S3C_CIGCTRL_IRQ_CLR_P (1 << 18) ++ ++/* Codec Target Format Register */ ++#if defined(CONFIG_CPU_S3C2443) || defined(CONFIG_CPU_S3C2450) || defined(CONFIG_CPU_S3C2416) ++#define S3C_CICOTRGFMT_IN422_422 (1 << 31) ++#define S3C_CICOTRGFMT_IN422_420 (0 << 31) ++#define S3C_CICOTRGFMT_OUT422_422 (1 << 30) ++#define S3C_CICOTRGFMT_OUT422_420 (0 << 30) ++ ++#elif defined(CONFIG_CPU_S3C6400) || defined(CONFIG_CPU_S3C6410) ++#define S3C_CICOTRGFMT_OUTFORMAT_RGBOUT (3 << 29) ++#define S3C_CICOTRGFMT_OUTFORMAT_YCBCR422OUTINTERLEAVE (2 << 29) ++#define S3C_CICOTRGFMT_OUTFORMAT_YCBCR422OUT (1 << 29) ++#define S3C_CICOTRGFMT_OUTFORMAT_YCBCR420OUT (0 << 29) ++#endif ++ ++#define S3C_CICOTRGFMT_INTERLEAVE_ON (1 << 29) ++#define S3C_CICOTRGFMT_INTERLEAVE_OFF (0 << 29) ++ ++#define S3C_CICOTRGFMT_FLIP_180 (3 << 14) ++#define S3C_CICOTRGFMT_FLIP_Y_MIRROR (2 << 14) ++#define S3C_CICOTRGFMT_FLIP_X_MIRROR (1 << 14) ++#define S3C_CICOTRGFMT_FLIP_NORMAL (0 << 14) ++ ++/* Codec DMA Control Register */ ++#define S3C_CICOCTRL_LASTIRQEN (1 << 2) ++#define S3C_CICOCTRL_ORDER422_CRYCBY (3 << 0) ++#define S3C_CICOCTRL_ORDER422_CBYCRY (2 << 0) ++#define S3C_CICOCTRL_ORDER422_YCRYCB (1 << 0) ++#define S3C_CICOCTRL_ORDER422_YCBYCR (0 << 0) ++ ++/* Codec Main-Scaler Control Register */ ++#define S3C_CICOSCCTRL_SCALERBYPASS_CO (1 << 31) ++#define S3C_CICOSCCTRL_SCALEUP_H (1 << 30) ++#define S3C_CICOSCCTRL_SCALEUP_V (1 << 29) ++ ++#define S3C_CICOSCCTRL_CSCR2Y_WIDE (1 << 28) ++#define S3C_CICOSCCTRL_CSCR2Y_NARROW (0 << 28) ++ ++#define S3C_CICOSCCTRL_CSCY2R_WIDE (1 << 27) ++#define S3C_CICOSCCTRL_CSCY2R_NARROW (0 << 27) ++ ++#define S3C_CICOSCCTRL_LCDPATHEN_FIFO (1 << 26) ++#define S3C_CICOSCCTRL_LCDPATHEN_DMA (0 << 26) ++ ++#define S3C_CICOSCCTRL_INTERLACE_INTERLACE (1 << 25) ++#define S3C_CICOSCCTRL_INTERLACE_PROGRESSIVE (0 << 25) ++ ++#define S3C_CICOSCCTRL_COSCALERSTART (1 << 15) ++ ++#define S3C_CICOSCCTRL_INRGB_FMT_RGB888 (2 << 13) ++#define S3C_CICOSCCTRL_INRGB_FMT_RGB666 (1 << 13) ++#define S3C_CICOSCCTRL_INRGB_FMT_RGB565 (0 << 13) ++ ++#define S3C_CICOSCCTRL_OUTRGB_FMT_RGB888 (2 << 11) ++#define S3C_CICOSCCTRL_OUTRGB_FMT_RGB666 (1 << 11) ++#define S3C_CICOSCCTRL_OUTRGB_FMT_RGB565 (0 << 11) ++ ++#define S3C_CICOSCCTRL_EXTRGB_EXTENSION (1 << 10) ++#define S3C_CICOSCCTRL_EXTRGB_NORMAL (0 << 10) ++ ++/* Codec Status Register */ ++#define S3C_CICOSTATUS_OVFIY_CO (1 << 31) ++#define S3C_CICOSTATUS_OVFICB_CO (1 << 30) ++#define S3C_CICOSTATUS_OVFICR_CO (1 << 29) ++#define S3C_CICOSTATUS_VSYNC (1 << 28) ++#define S3C_CICOSTATUS_WINOFSTEN_CO (1 << 25) ++#define S3C_CICOSTATUS_IMGCPTEN_CAMIF (1 << 22) ++#define S3C_CICOSTATUS_IMGCPTEN_COSC (1 << 21) ++#define S3C_CICOSTATUS_VSYNC_A (1 << 20) ++#define S3C_CICOSTATUS_VSYNC_B (1 << 19) ++#define S3C_CICOSTATUS_OVRLB_CO (1 << 18) ++#define S3C_CICOSTATUS_FRAMEEND_CO (1 << 17) ++ ++/* Preview Target Format Register */ ++#define S3C_CIPRTRGFMT_FLIPMD_180ROT (3 << 14) ++#define S3C_CIPRTRGFMT_FLIPMD_YMIRROR (2 << 14) ++#define S3C_CIPRTRGFMT_FLIPMD_XMIRROR (1 << 14) ++#define S3C_CIPRTRGFMT_FLIPMD_NORMAL (0 << 14) ++ ++#define S3C_CIPRTRGFMT_ROT90_ROTATE (1 << 13) ++#define S3C_CIPRTRGFMT_ROT90_BYPASS (0 << 13) ++ ++/* Preview DMA Control Register */ ++#define S3C_CIPRCTRL_LASTIRQEN_ENABLE (1 << 2) ++#define S3C_CIPRCTRL_LASTIRQEN_NORMAL (0 << 2) ++ ++#define S3C_CIPRCTRL_ORDER422_CRYCBY (3 << 0) ++#define S3C_CIPRCTRL_ORDER422_CBYCRY (2 << 0) ++#define S3C_CIPRCTRL_ORDER422_YCRYCB (1 << 0) ++#define S3C_CIPRCTRL_ORDER422_YCBYCR (0 << 0) ++ ++/* Preview Main-Scaler Control Register */ ++#define S3C_CIPRSCCTRL_SAMPLE_PR (1 << 31) ++ ++#define S3C_CIPRSCCTRL_RGBFORMAT_24 (1 << 30) ++#define S3C_CIPRSCCTRL_RGBFORMAT_16 (0 << 30) ++ ++#define S3C_CIPRSCCTRL_START (1 << 15) ++ ++#define S3C_CIPRSCCTRL_INRGB_FMT_PR_RGB888 (2 << 13) ++#define S3C_CIPRSCCTRL_INRGB_FMT_PR_RGB666 (1 << 13) ++#define S3C_CIPRSCCTRL_INRGB_FMT_PR_RGB565 (0 << 13) ++ ++#define S3C_CIPRSCCTRL_OUTRGB_FMT_PR_RGB888 (2 << 11) ++#define S3C_CIPRSCCTRL_OUTRGB_FMT_PR_RGB666 (1 << 11) ++#define S3C_CIPRSCCTRL_OUTRGB_FMT_PR_RGB565 (0 << 11) ++ ++/* Preview Status Register */ ++#if defined(CONFIG_CPU_S3C2443) || defined(CONFIG_CPU_S3C2450) || defined(CONFIG_CPU_S3C2416) ++#define S3C_CIPRSTATUS_OVFICB_PR (1 << 31) ++#define S3C_CIPRSTATUS_OVFICR_PR (1 << 30) ++ ++#elif defined CONFIG_CPU_S3C6400 || defined CONFIG_CPU_S3C6410 ++#define S3C_CIPRSTATUS_OVFIY_PR (1 << 31) ++#define S3C_CIPRSTATUS_OVFICB_PR (1 << 30) ++#define S3C_CIPRSTATUS_OVFICR_PR (1 << 29) ++#endif ++ ++/* Image Capture Enable Register */ ++#define S3C_CIIMGCPT_IMGCPTEN (1 << 31) ++#define S3C_CIIMGCPT_IMGCPTEN_COSC (1 << 30) ++#define S3C_CIIMGCPT_IMGCPTEN_PRSC (1 << 29) ++ ++#define S3C_CIIMGCPT_CPT_CODMA_SEL_RGB (1 << 26) ++#define S3C_CIIMGCPT_CPT_CODMA_SEL_YUV (0 << 26) ++ ++#if defined(CONFIG_CPU_S3C2443) || defined(CONFIG_CPU_S3C2450) || defined(CONFIG_CPU_S3C2416) ++#define S3C_CIIMGCPT_CPT_CODMA_RGBFMT_24 (1 << 25) ++#define S3C_CIIMGCPT_CPT_CODMA_RGBFMT_16 (0 << 25) ++#define S3C_CIIMGCPT_CPT_CODMA_ENABLE (1 << 24) ++#define S3C_CIIMGCPT_CPT_CODMA_DISABLE (0 << 24) ++#define S3C_CIIMGCPT_CPT_CODMA_MOD_CNT (1 << 18) ++#define S3C_CIIMGCPT_CPT_CODMA_MOD_EN (0 << 18) ++ ++#elif defined CONFIG_CPU_S3C6400 || defined CONFIG_CPU_S3C6410 ++#define S3C_CIIMGCPT_CPT_FREN_CO_ENABLE (1 << 25) ++#define S3C_CIIMGCPT_CPT_FREN_CO_DISABLE (0 << 25) ++#define S3C_CIIMGCPT_CPT_FREN_PR_ENABLE (1 << 24) ++#define S3C_CIIMGCPT_CPT_FREN_PR_DISABLE (0 << 24) ++#define S3C_CIIMGCPT_CPT_FRMOD_CNT (1 << 18) ++#define S3C_CIIMGCPT_CPT_FRMOD_EN (0 << 18) ++#endif ++ ++/* Image Effects Register */ ++#define S3C_CIIMGEFF_IE_ON_PR_ENABLE (1 << 31) ++#define S3C_CIIMGEFF_IE_ON_PR_DISABLE (0 << 31) ++ ++#define S3C_CIIMGEFF_IE_ON_CO_ENABLE (1 << 30) ++#define S3C_CIIMGEFF_IE_ON_CO_DISABLE (0 << 30) ++ ++#define S3C_CIIMGEFF_IE_AFTER_SC_BEFORE (0 << 29) ++#define S3C_CIIMGEFF_IE_AFTER_SC_AFTER (1 << 29) ++ ++#define S3C_CIIMGEFF_FIN_SILHOUETTE (5 << 26) ++#define S3C_CIIMGEFF_FIN_EMBOSSING (4 << 26) ++#define S3C_CIIMGEFF_FIN_ARTFREEZE (3 << 26) ++#define S3C_CIIMGEFF_FIN_NEGATIVE (2 << 26) ++#define S3C_CIIMGEFF_FIN_ARBITRARY (1 << 26) ++#define S3C_CIIMGEFF_FIN_BYPASS (0 << 26) ++ ++/* MSDMA for Codec Source Image Width Register */ ++#define S3C_MSCOWIDTH_AUTOLOAD_ENABLE (1 << 31) ++#define S3C_MSCOWIDTH_AUTOLOAD_DISABLE (0 << 31) ++ ++#define S3C_MSCOWIDTH_ADDR_CH_ENABLE (1 << 30) ++#define S3C_MSCOWIDTH_ADDR_CH_DISABLE (0 << 30) ++ ++/* MSDMA Control Register */ ++#if defined(CONFIG_CPU_S3C2443) || defined(CONFIG_CPU_S3C2450) || defined(CONFIG_CPU_S3C2416) ++#define S3C_CIMSCTRL_INTERLEAVE_MS_INTERLEAVE (1 << 5) ++#define S3C_CIMSCTRL_INTERLEAVE_MS_NONINTERLEAVE (0 << 5) ++#define S3C_CIMSCTRL_ORDER422_MS_CRYCBY (3 << 3) ++#define S3C_CIMSCTRL_ORDER422_MS_CBYCRY (2 << 3) ++#define S3C_CIMSCTRL_ORDER422_MS_YCRYCB (1 << 3) ++#define S3C_CIMSCTRL_ORDER422_MS_YCBYCR (0 << 3) ++#define S3C_CIMSCTRL_SEL_DMA_CAM_MEMORY (1 << 2) ++#define S3C_CIMSCTRL_SEL_DMA_CAM_EXTCAM (0 << 2) ++#define S3C_CIMSCTRL_SRC420_MS_420 (1 << 1) ++#define S3C_CIMSCTRL_SRC420_MS_422 (0 << 1) ++#define S3C_CIMSCTRL_ENVID_MS_SET (1 << 0) ++ ++#elif defined CONFIG_CPU_S3C6400 || defined CONFIG_CPU_S3C6410 ++#define S3C_MSCOCTRL_BC_SEL_FRAME (0 << 10) ++#define S3C_MSCOCTRL_BC_SEL_FIELD (1 << 10) ++#define S3C_MSCOCTRL_BUFFER_INI_0 (0 << 8) ++#define S3C_MSCOCTRL_BUFFER_INI_1 (1 << 8) ++#define S3C_MSCOCTRL_TRG_MODE_SOFT (0 << 7) ++#define S3C_MSCOCTRL_TRG_MODE_HARD (1 << 7) ++#define S3C_MSCOCTRL_ORDER422_M_C_YCBYCR (0 << 4) ++#define S3C_MSCOCTRL_ORDER422_M_C_YCRYCB (1 << 4) ++#define S3C_MSCOCTRL_ORDER422_M_C_CBYCRY (2 << 4) ++#define S3C_MSCOCTRL_ORDER422_M_C_CRYCBY (3 << 4) ++#define S3C_MSCOCTRL_SEL_DMA_CAM_C_EXTCAM (0 << 3) ++#define S3C_MSCOCTRL_SEL_DMA_CAM_C_MEMORY (1 << 3) ++#define S3C_MSCOCTRL_INFORMAT_M_C_420 (0 << 1) ++#define S3C_MSCOCTRL_INFORMAT_M_C_422 (1 << 1) ++#define S3C_MSCOCTRL_INFORMAT_M_C_422_INT (2 << 1) ++#define S3C_MSCOCTRL_INFORMAT_M_C_RGB (3 << 1) ++#define S3C_MSCOCTRL_ENVID_M_C_SET (1 << 0) ++#define S3C_MSPRCTRL_BC_SEL_FIELD (0 << 10) ++#define S3C_MSPRCTRL_BC_SEL_FRAME (1 << 10) ++#define S3C_MSPRCTRL_BUFFER_INI_0 (0 << 8) ++#define S3C_MSPRCTRL_BUFFER_INI_1 (1 << 8) ++#define S3C_MSPRCTRL_TRG_MODE_SOFT (0 << 7) ++#define S3C_MSPRCTRL_TRG_MODE_HARD (1 << 7) ++#define S3C_MSPRCTRL_ORDER422_M_P_YCBYCR (0 << 4) ++#define S3C_MSPRCTRL_ORDER422_M_P_YCRYCB (1 << 4) ++#define S3C_MSPRCTRL_ORDER422_M_P_CBYCRY (2 << 4) ++#define S3C_MSPRCTRL_ORDER422_M_P_CRYCBY (3 << 4) ++#define S3C_MSPRCTRL_SEL_DMA_CAM_P_EXTCAM (0 << 3) ++#define S3C_MSPRCTRL_SEL_DMA_CAM_P_MEMORY (1 << 3) ++#define S3C_MSPRCTRL_INFORMAT_M_P_420 (0 << 1) ++#define S3C_MSPRCTRL_INFORMAT_M_P_422 (1 << 1) ++#define S3C_MSPRCTRL_INFORMAT_M_P_422_INT (2 << 1) ++#define S3C_MSPRCTRL_INFORMAT_M_P_RGB (3 << 1) ++#define S3C_MSPRCTRL_ENVID_M_P_SET (1 << 0) ++#endif ++ ++/************************************************************************* ++ * Register part ++ ************************************************************************/ ++#define S3C_CICOYSA(__x) S3C_CAMIFREG(0x18 + (__x) * 4) ++#define S3C_CICOCBSA(__x) S3C_CAMIFREG(0x28 + (__x) * 4) ++#define S3C_CICOCRSA(__x) S3C_CAMIFREG(0x38 + (__x) * 4) ++#define S3C_CIPRCLRSA(__x) S3C_CAMIFREG(0x6C + (__x) * 4) ++#define S3C_CIPRYSA(__x) S3C_CAMIFREG(0x6C + (__x) * 4) ++#define S3C_CIPRCBSA(__x) S3C_CAMIFREG(0x7C + (__x) * 4) ++#define S3C_CIPRCRSA(__x) S3C_CAMIFREG(0x8C + (__x) * 4) ++ ++#define S3C_CISRCFMT S3C_CAMIFREG(0x00) ++#define S3C_CIWDOFST S3C_CAMIFREG(0x04) ++#define S3C_CIGCTRL S3C_CAMIFREG(0x08) ++#define S3C_CIDOWSFT2 S3C_CAMIFREG(0x14) ++#define S3C_CICOYSA1 S3C_CAMIFREG(0x18) ++#define S3C_CICOYSA2 S3C_CAMIFREG(0x1C) ++#define S3C_CICOYSA3 S3C_CAMIFREG(0x20) ++#define S3C_CICOYSA4 S3C_CAMIFREG(0x24) ++#define S3C_CICOCBSA1 S3C_CAMIFREG(0x28) ++#define S3C_CICOCBSA2 S3C_CAMIFREG(0x2C) ++#define S3C_CICOCBSA3 S3C_CAMIFREG(0x30) ++#define S3C_CICOCBSA4 S3C_CAMIFREG(0x34) ++#define S3C_CICOCRSA1 S3C_CAMIFREG(0x38) ++#define S3C_CICOCRSA2 S3C_CAMIFREG(0x3C) ++#define S3C_CICOCRSA3 S3C_CAMIFREG(0x40) ++#define S3C_CICOCRSA4 S3C_CAMIFREG(0x44) ++#define S3C_CICOTRGFMT S3C_CAMIFREG(0x48) /* CODEC target format */ ++#define S3C_CICOCTRL S3C_CAMIFREG(0x4C) /* CODEC DMA control register */ ++#define S3C_CICOSCPRERATIO S3C_CAMIFREG(0x50) /* CODEC pre-scaler control register 1 */ ++#define S3C_CICOSCPREDST S3C_CAMIFREG(0x54) /* CODEC pre-scaler control register 2 */ ++#define S3C_CICOSCCTRL S3C_CAMIFREG(0x58) /* CODEC main-scaler control */ ++#define S3C_CICOTAREA S3C_CAMIFREG(0x5C) /* CODEC DMA target area register */ ++#define S3C_CICOSTATUS S3C_CAMIFREG(0x64) /* CODEC status register */ ++ ++#if defined (CONFIG_CPU_S3C2443) || defined(CONFIG_CPU_S3C2450) || defined(CONFIG_CPU_S3C2416) ++#define S3C_CIPRCLRSA1 S3C_CAMIFREG(0x6C) /* RGB 1st frame start address for preview DMA */ ++#define S3C_CIPRCLRSA2 S3C_CAMIFREG(0x70) /* RGB 2nd frame start address for preview DMA */ ++#define S3C_CIPRCLRSA3 S3C_CAMIFREG(0x74) /* RGB 3rd frame start address for preview DMA */ ++#define S3C_CIPRCLRSA4 S3C_CAMIFREG(0x78) /* RGB 4th frame start address for preview DMA */ ++#define S3C_CIPRTRGFMT S3C_CAMIFREG(0x7C) /* PREVIEW target format register */ ++#define S3C_CIPRCTRL S3C_CAMIFREG(0x80) /* PREVIEW DMA control register */ ++#define S3C_CIPRSCPRERATIO S3C_CAMIFREG(0x84) /* PREVIEW pre-scaler control register 1 */ ++#define S3C_CIPRSCPREDST S3C_CAMIFREG(0x88) /* PREVIEW pre-scaler control register 2 */ ++#define S3C_CIPRSCCTRL S3C_CAMIFREG(0x8C) /* PREVIEW main-scaler control register */ ++#define S3C_CIPRTAREA S3C_CAMIFREG(0x90) /* PREVIEW DMA target area register */ ++#define S3C_CIPRSTATUS S3C_CAMIFREG(0x98) /* PREVIEW status register */ ++#define S3C_CIIMGCPT S3C_CAMIFREG(0xA0) /* image capture enable register */ ++#define S3C_CICOCPTSEQ S3C_CAMIFREG(0xA4) /* CODEC capture sequence register */ ++#define S3C_CICOSCOS S3C_CAMIFREG(0xA8) /* CODEC scan line offset register */ ++#define S3C_CIIMGEFF S3C_CAMIFREG(0xB0) /* image effect register */ ++#define S3C_CIMSYSA S3C_CAMIFREG(0xB4) /* MSDMA Y start address register */ ++#define S3C_CIMSCBSA S3C_CAMIFREG(0xB8) /* MSDMA CB start address register */ ++#define S3C_CIMSCRSA S3C_CAMIFREG(0xBC) /* MSDMA CR start address register */ ++#define S3C_CIMSYEND S3C_CAMIFREG(0xC0) /* MSDMA Y end address register */ ++#define S3C_CIMSCBEND S3C_CAMIFREG(0xC4) /* MSDMA CB end address register */ ++#define S3C_CIMSCREND S3C_CAMIFREG(0xC8) /* MSDMA CR end address register */ ++#define S3C_CIMSYOFF S3C_CAMIFREG(0xCC) /* MSDMA Y offset register */ ++#define S3C_CIMSCBOFF S3C_CAMIFREG(0xD0) /* MSDMA CB offset register */ ++#define S3C_CIMSCROFF S3C_CAMIFREG(0xD4) /* MSDMA CR offset register */ ++#define S3C_CIMSWIDTH S3C_CAMIFREG(0xD8) /* MSDMA source image width register */ ++#define S3C_CIMSCTRL S3C_CAMIFREG(0xDC) /* MSDMA control register */ ++ ++#elif defined CONFIG_CPU_S3C6400 || defined CONFIG_CPU_S3C6410 ++#define S3C_CIPRYSA1 S3C_CAMIFREG(0x6C) /* 1st frame start address for preview DMA */ ++#define S3C_CIPRYSA2 S3C_CAMIFREG(0x70) /* 2nd frame start address for preview DMA */ ++#define S3C_CIPRYSA3 S3C_CAMIFREG(0x74) /* 3rd frame start address for preview DMA */ ++#define S3C_CIPRYSA4 S3C_CAMIFREG(0x78) /* 4th frame start address for preview DMA */ ++#define S3C_CIPRCBSA1 S3C_CAMIFREG(0x7C) /* 1st frame start address for preview DMA */ ++#define S3C_CIPRCBSA2 S3C_CAMIFREG(0x80) /* 2nd frame start address for preview DMA */ ++#define S3C_CIPRCBSA3 S3C_CAMIFREG(0x84) /* 3rd frame start address for preview DMA */ ++#define S3C_CIPRCBSA4 S3C_CAMIFREG(0x88) /* 4th frame start address for preview DMA */ ++#define S3C_CIPRCRSA1 S3C_CAMIFREG(0x8C) /* 1st frame start address for preview DMA */ ++#define S3C_CIPRCRSA2 S3C_CAMIFREG(0x90) /* 2nd frame start address for preview DMA */ ++#define S3C_CIPRCRSA3 S3C_CAMIFREG(0x94) /* 3rd frame start address for preview DMA */ ++#define S3C_CIPRCRSA4 S3C_CAMIFREG(0x98) /* 4th frame start address for preview DMA */ ++#define S3C_CIPRTRGFMT S3C_CAMIFREG(0x9C) /* PREVIEW target format register */ ++#define S3C_CIPRCTRL S3C_CAMIFREG(0xA0) /* PREVIEW DMA control register */ ++#define S3C_CIPRSCPRERATIO S3C_CAMIFREG(0xA4) /* PREVIEW pre-scaler control register 1 */ ++#define S3C_CIPRSCPREDST S3C_CAMIFREG(0xA8) /* PREVIEW pre-scaler control register 2 */ ++#define S3C_CIPRSCCTRL S3C_CAMIFREG(0xAC) /* PREVIEW main-scaler control register */ ++#define S3C_CIPRTAREA S3C_CAMIFREG(0xB0) /* PREVIEW DMA target area register */ ++#define S3C_CIPRSTATUS S3C_CAMIFREG(0xB8) /* PREVIEW status register */ ++#define S3C_CIIMGCPT S3C_CAMIFREG(0xC0) /* image capture enable register */ ++#define S3C_CICOCPTSEQ S3C_CAMIFREG(0xC4) /* CODEC capture sequence register */ ++#define S3C_CIIMGEFF S3C_CAMIFREG(0xD0) /* image effect register */ ++#define S3C_MSCOY0SA S3C_CAMIFREG(0xD4) /* MSDMA for CODEC Y start address register */ ++#define S3C_MSCOCB0SA S3C_CAMIFREG(0xD8) /* MSDMA for CODEC CB start address register */ ++#define S3C_MSCOCR0SA S3C_CAMIFREG(0xDC) /* MSDMA for CODEC CR start address register */ ++#define S3C_MSCOY0END S3C_CAMIFREG(0xE0) /* MSDMA for CODEC Y end address register */ ++#define S3C_MSCOCB0END S3C_CAMIFREG(0xE4) /* MSDMA for CODEC CB end address register */ ++#define S3C_MSCOCR0END S3C_CAMIFREG(0xE8) /* MSDMA for CODEC CR end address register */ ++#define S3C_MSCOYOFF S3C_CAMIFREG(0xEC) /* MSDMA for CODEC Y offset register */ ++#define S3C_MSCOCBOFF S3C_CAMIFREG(0xF0) /* MSDMA for CODEC CB offset register */ ++#define S3C_MSCOCROFF S3C_CAMIFREG(0xF4) /* MSDMA for CODEC CR offset register */ ++#define S3C_MSCOWIDTH S3C_CAMIFREG(0xF8) /* MSDMA for CODEC source image width register */ ++#define S3C_MSCOCTRL S3C_CAMIFREG(0xFC) /* MSDMA for CODEC control register */ ++#define S3C_MSPRY0SA S3C_CAMIFREG(0x100) /* MSDMA for PREVIEW Y0 start address register */ ++#define S3C_MSPRCB0SA S3C_CAMIFREG(0x104) /* MSDMA for PREVIEW CB0 start address register */ ++#define S3C_MSPRCR0SA S3C_CAMIFREG(0x108) /* MSDMA for PREVIEW CR0 start address register */ ++#define S3C_MSPRY0END S3C_CAMIFREG(0x10C) /* MSDMA for PREVIEW Y0 end address register */ ++#define S3C_MSPRCB0END S3C_CAMIFREG(0x110) /* MSDMA for PREVIEW CB0 end address register */ ++#define S3C_MSPRCR0END S3C_CAMIFREG(0x114) /* MSDMA for PREVIEW CR0 end address register */ ++#define S3C_MSPRYOFF S3C_CAMIFREG(0x118) /* MSDMA for PREVIEW Y offset register */ ++#define S3C_MSPRCBOFF S3C_CAMIFREG(0x11C) /* MSDMA for PREVIEW CB offset register */ ++#define S3C_MSPRCROFF S3C_CAMIFREG(0x120) /* MSDMA for PREVIEW CR offset register */ ++#define S3C_MSPRWIDTH S3C_CAMIFREG(0x124) /* MSDMA for PREVIEW source image width register */ ++#define S3C_CIMSCTRL S3C_CAMIFREG(0x128) /* MSDMA for PREVIEW control register */ ++#define S3C_CICOSCOSY S3C_CAMIFREG(0x12C) /* CODEC scan line Y offset register */ ++#define S3C_CICOSCOSCB S3C_CAMIFREG(0x130) /* CODEC scan line CB offset register */ ++#define S3C_CICOSCOSCR S3C_CAMIFREG(0x134) /* CODEC scan line CR offset register */ ++#define S3C_CIPRSCOSY S3C_CAMIFREG(0x138) /* PREVIEW scan line Y offset register */ ++#define S3C_CIPRSCOSCB S3C_CAMIFREG(0x13C) /* PREVIEW scan line CB offset register */ ++#define S3C_CIPRSCOSCR S3C_CAMIFREG(0x140) /* PREVIEW scan line CR offset register */ ++#endif ++ ++#endif /* ___ASM_ARCH_REGS_CAMIF_H */ ++ +diff -ruN --exclude='*.orig' --exclude='*.rej' linux-2.6.29-rc3.owrt/arch/arm/plat-s3c64xx/include/plat/regs-clock.h linux-2.6.29-rc3.owrt.om/arch/arm/plat-s3c64xx/include/plat/regs-clock.h +--- linux-2.6.29-rc3.owrt/arch/arm/plat-s3c64xx/include/plat/regs-clock.h 2009-05-10 22:05:04.000000000 +0200 ++++ linux-2.6.29-rc3.owrt.om/arch/arm/plat-s3c64xx/include/plat/regs-clock.h 2009-05-10 22:27:59.000000000 +0200 +@@ -32,6 +32,7 @@ + #define S3C_HCLK_GATE S3C_CLKREG(0x30) + #define S3C_PCLK_GATE S3C_CLKREG(0x34) + #define S3C_SCLK_GATE S3C_CLKREG(0x38) ++#define S3C_MEM0_GATE S3C_CLKREG(0x3C) + + /* CLKDIV0 */ + #define S3C6400_CLKDIV0_MFC_MASK (0xf << 28) +@@ -88,10 +89,10 @@ + + /* HCLK GATE Registers */ + #define S3C_CLKCON_HCLK_BUS (1<<30) +-#define S3C_CLKCON_HCLK_SECUR (1<<29) +-#define S3C_CLKCON_HCLK_SDMA1 (1<<28) +-#define S3C_CLKCON_HCLK_SDMA2 (1<<27) +-#define S3C_CLKCON_HCLK_UHOST (1<<26) ++#define S3C_CLKCON_HCLK_UHOST (1<<29) ++#define S3C_CLKCON_HCLK_SECUR (1<<28) ++#define S3C_CLKCON_HCLK_SDMA1 (1<<27) ++#define S3C_CLKCON_HCLK_SDMA0 (1<<26) + #define S3C_CLKCON_HCLK_IROM (1<<25) + #define S3C_CLKCON_HCLK_DDR1 (1<<24) + #define S3C_CLKCON_HCLK_DDR0 (1<<23) +diff -ruN --exclude='*.orig' --exclude='*.rej' linux-2.6.29-rc3.owrt/arch/arm/plat-s3c64xx/include/plat/regs-gpio.h linux-2.6.29-rc3.owrt.om/arch/arm/plat-s3c64xx/include/plat/regs-gpio.h +--- linux-2.6.29-rc3.owrt/arch/arm/plat-s3c64xx/include/plat/regs-gpio.h 2009-05-10 22:05:04.000000000 +0200 ++++ linux-2.6.29-rc3.owrt.om/arch/arm/plat-s3c64xx/include/plat/regs-gpio.h 2009-05-10 22:27:59.000000000 +0200 +@@ -13,23 +13,175 @@ + + /* Base addresses for each of the banks */ + +-#define S3C64XX_GPA_BASE (S3C64XX_VA_GPIO + 0x0000) +-#define S3C64XX_GPB_BASE (S3C64XX_VA_GPIO + 0x0020) +-#define S3C64XX_GPC_BASE (S3C64XX_VA_GPIO + 0x0040) +-#define S3C64XX_GPD_BASE (S3C64XX_VA_GPIO + 0x0060) +-#define S3C64XX_GPE_BASE (S3C64XX_VA_GPIO + 0x0080) +-#define S3C64XX_GPF_BASE (S3C64XX_VA_GPIO + 0x00A0) +-#define S3C64XX_GPG_BASE (S3C64XX_VA_GPIO + 0x00C0) +-#define S3C64XX_GPH_BASE (S3C64XX_VA_GPIO + 0x00E0) +-#define S3C64XX_GPI_BASE (S3C64XX_VA_GPIO + 0x0100) +-#define S3C64XX_GPJ_BASE (S3C64XX_VA_GPIO + 0x0120) +-#define S3C64XX_GPK_BASE (S3C64XX_VA_GPIO + 0x0800) +-#define S3C64XX_GPL_BASE (S3C64XX_VA_GPIO + 0x0810) +-#define S3C64XX_GPM_BASE (S3C64XX_VA_GPIO + 0x0820) +-#define S3C64XX_GPN_BASE (S3C64XX_VA_GPIO + 0x0830) +-#define S3C64XX_GPO_BASE (S3C64XX_VA_GPIO + 0x0140) +-#define S3C64XX_GPP_BASE (S3C64XX_VA_GPIO + 0x0160) +-#define S3C64XX_GPQ_BASE (S3C64XX_VA_GPIO + 0x0180) ++#define S3C64XX_GPIOREG(reg) (S3C64XX_VA_GPIO + (reg)) ++ ++#define S3C64XX_GPA_BASE S3C64XX_GPIOREG(0x0000) ++#define S3C64XX_GPB_BASE S3C64XX_GPIOREG(0x0020) ++#define S3C64XX_GPC_BASE S3C64XX_GPIOREG(0x0040) ++#define S3C64XX_GPD_BASE S3C64XX_GPIOREG(0x0060) ++#define S3C64XX_GPE_BASE S3C64XX_GPIOREG(0x0080) ++#define S3C64XX_GPF_BASE S3C64XX_GPIOREG(0x00A0) ++#define S3C64XX_GPG_BASE S3C64XX_GPIOREG(0x00C0) ++#define S3C64XX_GPH_BASE S3C64XX_GPIOREG(0x00E0) ++#define S3C64XX_GPI_BASE S3C64XX_GPIOREG(0x0100) ++#define S3C64XX_GPJ_BASE S3C64XX_GPIOREG(0x0120) ++#define S3C64XX_GPK_BASE S3C64XX_GPIOREG(0x0800) ++#define S3C64XX_GPL_BASE S3C64XX_GPIOREG(0x0810) ++#define S3C64XX_GPM_BASE S3C64XX_GPIOREG(0x0820) ++#define S3C64XX_GPN_BASE S3C64XX_GPIOREG(0x0830) ++#define S3C64XX_GPO_BASE S3C64XX_GPIOREG(0x0140) ++#define S3C64XX_GPP_BASE S3C64XX_GPIOREG(0x0160) ++#define S3C64XX_GPQ_BASE S3C64XX_GPIOREG(0x0180) ++ ++/* SPCON */ ++ ++#define S3C64XX_SPCON S3C64XX_GPIOREG(0x1A0) ++ ++#define S3C64XX_SPCON_DRVCON_CAM_MASK (0x3 << 30) ++#define S3C64XX_SPCON_DRVCON_CAM_SHIFT (30) ++#define S3C64XX_SPCON_DRVCON_CAM_2mA (0x0 << 30) ++#define S3C64XX_SPCON_DRVCON_CAM_4mA (0x1 << 30) ++#define S3C64XX_SPCON_DRVCON_CAM_7mA (0x2 << 30) ++#define S3C64XX_SPCON_DRVCON_CAM_9mA (0x3 << 30) ++ ++#define S3C64XX_SPCON_DRVCON_HSSPI_MASK (0x3 << 28) ++#define S3C64XX_SPCON_DRVCON_HSSPI_SHIFT (28) ++#define S3C64XX_SPCON_DRVCON_HSSPI_2mA (0x0 << 28) ++#define S3C64XX_SPCON_DRVCON_HSSPI_4mA (0x1 << 28) ++#define S3C64XX_SPCON_DRVCON_HSSPI_7mA (0x2 << 28) ++#define S3C64XX_SPCON_DRVCON_HSSPI_9mA (0x3 << 28) ++ ++#define S3C64XX_SPCON_DRVCON_HSMMC_MASK (0x3 << 26) ++#define S3C64XX_SPCON_DRVCON_HSMMC_SHIFT (26) ++#define S3C64XX_SPCON_DRVCON_HSMMC_2mA (0x0 << 26) ++#define S3C64XX_SPCON_DRVCON_HSMMC_4mA (0x1 << 26) ++#define S3C64XX_SPCON_DRVCON_HSMMC_7mA (0x2 << 26) ++#define S3C64XX_SPCON_DRVCON_HSMMC_9mA (0x3 << 26) ++ ++#define S3C64XX_SPCON_DRVCON_LCD_MASK (0x3 << 24) ++#define S3C64XX_SPCON_DRVCON_LCD_SHIFT (24) ++#define S3C64XX_SPCON_DRVCON_LCD_2mA (0x0 << 24) ++#define S3C64XX_SPCON_DRVCON_LCD_4mA (0x1 << 24) ++#define S3C64XX_SPCON_DRVCON_LCD_7mA (0x2 << 24) ++#define S3C64XX_SPCON_DRVCON_LCD_9mA (0x3 << 24) ++ ++#define S3C64XX_SPCON_DRVCON_MODEM_MASK (0x3 << 22) ++#define S3C64XX_SPCON_DRVCON_MODEM_SHIFT (22) ++#define S3C64XX_SPCON_DRVCON_MODEM_2mA (0x0 << 22) ++#define S3C64XX_SPCON_DRVCON_MODEM_4mA (0x1 << 22) ++#define S3C64XX_SPCON_DRVCON_MODEM_7mA (0x2 << 22) ++#define S3C64XX_SPCON_DRVCON_MODEM_9mA (0x3 << 22) ++ ++#define S3C64XX_SPCON_nRSTOUT_OEN (1 << 21) ++ ++#define S3C64XX_SPCON_DRVCON_SPICLK1_MASK (0x3 << 18) ++#define S3C64XX_SPCON_DRVCON_SPICLK1_SHIFT (18) ++#define S3C64XX_SPCON_DRVCON_SPICLK1_2mA (0x0 << 18) ++#define S3C64XX_SPCON_DRVCON_SPICLK1_4mA (0x1 << 18) ++#define S3C64XX_SPCON_DRVCON_SPICLK1_7mA (0x2 << 18) ++#define S3C64XX_SPCON_DRVCON_SPICLK1_9mA (0x3 << 18) ++ ++#define S3C64XX_SPCON_MEM1_DQS_PUD_MASK (0x3 << 16) ++#define S3C64XX_SPCON_MEM1_DQS_PUD_SHIFT (16) ++#define S3C64XX_SPCON_MEM1_DQS_PUD_DISABLED (0x0 << 16) ++#define S3C64XX_SPCON_MEM1_DQS_PUD_DOWN (0x1 << 16) ++#define S3C64XX_SPCON_MEM1_DQS_PUD_UP (0x2 << 16) ++ ++#define S3C64XX_SPCON_MEM1_D_PUD1_MASK (0x3 << 14) ++#define S3C64XX_SPCON_MEM1_D_PUD1_SHIFT (14) ++#define S3C64XX_SPCON_MEM1_D_PUD1_DISABLED (0x0 << 14) ++#define S3C64XX_SPCON_MEM1_D_PUD1_DOWN (0x1 << 14) ++#define S3C64XX_SPCON_MEM1_D_PUD1_UP (0x2 << 14) ++ ++#define S3C64XX_SPCON_MEM1_D_PUD0_MASK (0x3 << 12) ++#define S3C64XX_SPCON_MEM1_D_PUD0_SHIFT (12) ++#define S3C64XX_SPCON_MEM1_D_PUD0_DISABLED (0x0 << 12) ++#define S3C64XX_SPCON_MEM1_D_PUD0_DOWN (0x1 << 12) ++#define S3C64XX_SPCON_MEM1_D_PUD0_UP (0x2 << 12) ++ ++#define S3C64XX_SPCON_MEM0_D_PUD_MASK (0x3 << 8) ++#define S3C64XX_SPCON_MEM0_D_PUD_SHIFT (8) ++#define S3C64XX_SPCON_MEM0_D_PUD_DISABLED (0x0 << 8) ++#define S3C64XX_SPCON_MEM0_D_PUD_DOWN (0x1 << 8) ++#define S3C64XX_SPCON_MEM0_D_PUD_UP (0x2 << 8) ++ ++#define S3C64XX_SPCON_USBH_DMPD (1 << 7) ++#define S3C64XX_SPCON_USBH_DPPD (1 << 6) ++#define S3C64XX_SPCON_USBH_PUSW2 (1 << 5) ++#define S3C64XX_SPCON_USBH_PUSW1 (1 << 4) ++#define S3C64XX_SPCON_USBH_SUSPND (1 << 3) ++ ++#define S3C64XX_SPCON_LCD_SEL_MASK (0x3 << 0) ++#define S3C64XX_SPCON_LCD_SEL_SHIFT (0) ++#define S3C64XX_SPCON_LCD_SEL_HOST (0x0 << 0) ++#define S3C64XX_SPCON_LCD_SEL_RGB (0x1 << 0) ++#define S3C64XX_SPCON_LCD_SEL_606_656 (0x2 << 0) ++ ++ ++/* External interrupt registers */ ++ ++#define S3C64XX_EINT12CON S3C64XX_GPIOREG(0x200) ++#define S3C64XX_EINT34CON S3C64XX_GPIOREG(0x204) ++#define S3C64XX_EINT56CON S3C64XX_GPIOREG(0x208) ++#define S3C64XX_EINT78CON S3C64XX_GPIOREG(0x20C) ++#define S3C64XX_EINT9CON S3C64XX_GPIOREG(0x210) ++ ++#define S3C64XX_EINT12FLTCON S3C64XX_GPIOREG(0x220) ++#define S3C64XX_EINT34FLTCON S3C64XX_GPIOREG(0x224) ++#define S3C64XX_EINT56FLTCON S3C64XX_GPIOREG(0x228) ++#define S3C64XX_EINT78FLTCON S3C64XX_GPIOREG(0x22C) ++#define S3C64XX_EINT9FLTCON S3C64XX_GPIOREG(0x230) ++ ++#define S3C64XX_EINT12MASK S3C64XX_GPIOREG(0x240) ++#define S3C64XX_EINT34MASK S3C64XX_GPIOREG(0x244) ++#define S3C64XX_EINT56MASK S3C64XX_GPIOREG(0x248) ++#define S3C64XX_EINT78MASK S3C64XX_GPIOREG(0x24C) ++#define S3C64XX_EINT9MASK S3C64XX_GPIOREG(0x250) ++ ++#define S3C64XX_EINT12PEND S3C64XX_GPIOREG(0x260) ++#define S3C64XX_EINT34PEND S3C64XX_GPIOREG(0x264) ++#define S3C64XX_EINT56PEND S3C64XX_GPIOREG(0x268) ++#define S3C64XX_EINT78PEND S3C64XX_GPIOREG(0x26C) ++#define S3C64XX_EINT9PEND S3C64XX_GPIOREG(0x270) ++ ++#define S3C64XX_PRIORITY S3C64XX_GPIOREG(0x280) ++#define S3C64XX_PRIORITY_ARB(x) (1 << (x)) ++ ++#define S3C64XX_SERVICE S3C64XX_GPIOREG(0x284) ++#define S3C64XX_SERVICEPEND S3C64XX_GPIOREG(0x288) ++ ++#define S3C64XX_EINT0CON0 S3C64XX_GPIOREG(0x900) ++#define S3C64XX_EINT0CON1 S3C64XX_GPIOREG(0x904) ++#define S3C64XX_EINT0FLTCON0 S3C64XX_GPIOREG(0x910) ++#define S3C64XX_EINT0FLTCON1 S3C64XX_GPIOREG(0x914) ++#define S3C64XX_EINT0FLTCON2 S3C64XX_GPIOREG(0x918) ++#define S3C64XX_EINT0FLTCON3 S3C64XX_GPIOREG(0x91C) ++ ++#define S3C64XX_EINT0MASK S3C64XX_GPIOREG(0x920) ++#define S3C64XX_EINT0PEND S3C64XX_GPIOREG(0x924) ++ ++/* GPIO sleep configuration */ ++ ++#define S3C64XX_SPCONSLP S3C64XX_GPIOREG(0x880) ++ ++#define S3C64XX_SPCONSLP_TDO_PULLDOWN (1 << 14) ++#define S3C64XX_SPCONSLP_CKE1INIT (1 << 5) ++ ++#define S3C64XX_SPCONSLP_RSTOUT_MASK (0x3 << 12) ++#define S3C64XX_SPCONSLP_RSTOUT_OUT0 (0x0 << 12) ++#define S3C64XX_SPCONSLP_RSTOUT_OUT1 (0x1 << 12) ++#define S3C64XX_SPCONSLP_RSTOUT_HIZ (0x2 << 12) ++ ++#define S3C64XX_SPCONSLP_KPCOL_MASK (0x3 << 0) ++#define S3C64XX_SPCONSLP_KPCOL_OUT0 (0x0 << 0) ++#define S3C64XX_SPCONSLP_KPCOL_OUT1 (0x1 << 0) ++#define S3C64XX_SPCONSLP_KPCOL_INP (0x2 << 0) ++ ++ ++#define S3C64XX_SLPEN S3C64XX_GPIOREG(0x930) ++ ++#define S3C64XX_SLPEN_USE_xSLP (1 << 0) ++#define S3C64XX_SLPEN_CFG_BYSLPEN (1 << 1) + + #endif /* __ASM_PLAT_S3C64XX_REGS_GPIO_H */ + +diff -ruN --exclude='*.orig' --exclude='*.rej' linux-2.6.29-rc3.owrt/arch/arm/plat-s3c64xx/include/plat/regs-gpio-memport.h linux-2.6.29-rc3.owrt.om/arch/arm/plat-s3c64xx/include/plat/regs-gpio-memport.h +--- linux-2.6.29-rc3.owrt/arch/arm/plat-s3c64xx/include/plat/regs-gpio-memport.h 1970-01-01 01:00:00.000000000 +0100 ++++ linux-2.6.29-rc3.owrt.om/arch/arm/plat-s3c64xx/include/plat/regs-gpio-memport.h 2009-05-10 22:27:59.000000000 +0200 +@@ -0,0 +1,25 @@ ++/* linux/arch/arm/plat-s3c64xx/include/mach/regs-gpio-memport.h ++ * ++ * Copyright 2008 Openmoko, Inc. ++ * Copyright 2008 Simtec Electronics ++ * Ben Dooks <ben@simtec.co.uk> ++ * http://armlinux.simtec.co.uk/ ++ * ++ * S3C64XX - GPIO memory port register definitions ++ */ ++ ++#ifndef __ASM_PLAT_S3C64XX_REGS_GPIO_MEMPORT_H ++#define __ASM_PLAT_S3C64XX_REGS_GPIO_MEMPORT_H __FILE__ ++ ++#define S3C64XX_MEM0CONSTOP S3C64XX_GPIOREG(0x1B0) ++#define S3C64XX_MEM1CONSTOP S3C64XX_GPIOREG(0x1B4) ++ ++#define S3C64XX_MEM0CONSLP0 S3C64XX_GPIOREG(0x1C0) ++#define S3C64XX_MEM0CONSLP1 S3C64XX_GPIOREG(0x1C4) ++#define S3C64XX_MEM1CONSLP S3C64XX_GPIOREG(0x1C8) ++ ++#define S3C64XX_MEM0DRVCON S3C64XX_GPIOREG(0x1D0) ++#define S3C64XX_MEM1DRVCON S3C64XX_GPIOREG(0x1D4) ++ ++#endif /* __ASM_PLAT_S3C64XX_REGS_GPIO_MEMPORT_H */ ++ +diff -ruN --exclude='*.orig' --exclude='*.rej' linux-2.6.29-rc3.owrt/arch/arm/plat-s3c64xx/include/plat/regs-modem.h linux-2.6.29-rc3.owrt.om/arch/arm/plat-s3c64xx/include/plat/regs-modem.h +--- linux-2.6.29-rc3.owrt/arch/arm/plat-s3c64xx/include/plat/regs-modem.h 1970-01-01 01:00:00.000000000 +0100 ++++ linux-2.6.29-rc3.owrt.om/arch/arm/plat-s3c64xx/include/plat/regs-modem.h 2009-05-10 22:27:59.000000000 +0200 +@@ -0,0 +1,31 @@ ++/* arch/arm/plat-s3c64xx/include/plat/regs-modem.h ++ * ++ * Copyright 2008 Openmoko, Inc. ++ * Copyright 2008 Simtec Electronics ++ * http://armlinux.simtec.co.uk/ ++ * Ben Dooks <ben@simtec.co.uk> ++ * ++ * S3C64XX - modem block registers ++ * ++ * 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 __PLAT_S3C64XX_REGS_MODEM_H ++#define __PLAT_S3C64XX_REGS_MODEM_H __FILE__ ++ ++#define S3C64XX_MODEMREG(x) (S3C64XX_VA_MODEM + (x)) ++ ++#define S3C64XX_MODEM_INT2AP S3C64XX_MODEMREG(0x0) ++#define S3C64XX_MODEM_INT2MODEM S3C64XX_MODEMREG(0x4) ++#define S3C64XX_MODEM_MIFCON S3C64XX_MODEMREG(0x8) ++#define S3C64XX_MODEM_MIFPCON S3C64XX_MODEMREG(0xC) ++#define S3C64XX_MODEM_INTCLR S3C64XX_MODEMREG(0x10) ++#define S3C64XX_MODEM_DMA_TXADDR S3C64XX_MODEMREG(0x14) ++#define S3C64XX_MODEM_DMA_RXADDR S3C64XX_MODEMREG(0x18) ++ ++#define MIFPCON_INT2M_LEVEL (1 << 4) ++#define MIFPCON_LCD_BYPASS (1 << 3) ++ ++#endif /* __PLAT_S3C64XX_REGS_MODEM_H */ +diff -ruN --exclude='*.orig' --exclude='*.rej' linux-2.6.29-rc3.owrt/arch/arm/plat-s3c64xx/include/plat/regs-syscon-power.h linux-2.6.29-rc3.owrt.om/arch/arm/plat-s3c64xx/include/plat/regs-syscon-power.h +--- linux-2.6.29-rc3.owrt/arch/arm/plat-s3c64xx/include/plat/regs-syscon-power.h 1970-01-01 01:00:00.000000000 +0100 ++++ linux-2.6.29-rc3.owrt.om/arch/arm/plat-s3c64xx/include/plat/regs-syscon-power.h 2009-05-10 22:27:59.000000000 +0200 +@@ -0,0 +1,116 @@ ++/* arch/arm/plat-s3c64xx/include/plat/regs-syscon-power.h ++ * ++ * Copyright 2008 Openmoko, Inc. ++ * Copyright 2008 Simtec Electronics ++ * http://armlinux.simtec.co.uk/ ++ * Ben Dooks <ben@simtec.co.uk> ++ * ++ * S3C64XX - syscon power and sleep control registers ++ * ++ * 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 __PLAT_S3C64XX_REGS_SYSCON_POWER_H ++#define __PLAT_S3C64XX_REGS_SYSCON_POWER_H __FILE__ ++ ++#define S3C64XX_PWR_CFG S3C_SYSREG(0x804) ++ ++#define S3C64XX_PWRCFG_OSC_OTG_DISABLE (1 << 17) ++#define S3C64XX_PWRCFG_MMC2_DISABLE (1 << 16) ++#define S3C64XX_PWRCFG_MMC1_DISABLE (1 << 15) ++#define S3C64XX_PWRCFG_MMC0_DISABLE (1 << 14) ++#define S3C64XX_PWRCFG_HSI_DISABLE (1 << 13) ++#define S3C64XX_PWRCFG_TS_DISABLE (1 << 12) ++#define S3C64XX_PWRCFG_RTC_TICK_DISABLE (1 << 11) ++#define S3C64XX_PWRCFG_RTC_ALARM_DISABLE (1 << 10) ++#define S3C64XX_PWRCFG_MSM_DISABLE (1 << 9) ++#define S3C64XX_PWRCFG_KEY_DISABLE (1 << 8) ++#define S3C64XX_PWRCFG_BATF_DISABLE (1 << 7) ++ ++#define S3C64XX_PWRCFG_CFG_WFI_MASK (0x3 << 5) ++#define S3C64XX_PWRCFG_CFG_WFI_SHIFT (5) ++#define S3C64XX_PWRCFG_CFG_WFI_IGNORE (0x0 << 5) ++#define S3C64XX_PWRCFG_CFG_WFI_IDLE (0x1 << 5) ++#define S3C64XX_PWRCFG_CFG_WFI_STOP (0x2 << 5) ++#define S3C64XX_PWRCFG_CFG_WFI_SLEEP (0x3 << 5) ++ ++#define S3C64XX_PWRCFG_CFG_BATFLT_MASK (0x3 << 3) ++#define S3C64XX_PWRCFG_CFG_BATFLT_SHIFT (3) ++#define S3C64XX_PWRCFG_CFG_BATFLT_IGNORE (0x0 << 3) ++#define S3C64XX_PWRCFG_CFG_BATFLT_IRQ (0x1 << 3) ++#define S3C64XX_PWRCFG_CFG_BATFLT_SLEEP (0x3 << 3) ++ ++#define S3C64XX_PWRCFG_CFG_BAT_WAKE (1 << 2) ++#define S3C64XX_PWRCFG_OSC27_EN (1 << 0) ++ ++#define S3C64XX_EINT_MASK S3C_SYSREG(0x808) ++ ++#define S3C64XX_NORMAL_CFG S3C_SYSREG(0x810) ++ ++#define S3C64XX_NORMALCFG_IROM_ON (1 << 30) ++#define S3C64XX_NORMALCFG_DOMAIN_ETM_ON (1 << 16) ++#define S3C64XX_NORMALCFG_DOMAIN_S_ON (1 << 15) ++#define S3C64XX_NORMALCFG_DOMAIN_F_ON (1 << 14) ++#define S3C64XX_NORMALCFG_DOMAIN_P_ON (1 << 13) ++#define S3C64XX_NORMALCFG_DOMAIN_I_ON (1 << 12) ++#define S3C64XX_NORMALCFG_DOMAIN_G_ON (1 << 10) ++#define S3C64XX_NORMALCFG_DOMAIN_V_ON (1 << 9) ++ ++#define S3C64XX_STOP_CFG S3C_SYSREG(0x814) ++ ++#define S3C64XX_STOPCFG_MEMORY_ARM_ON (1 << 29) ++#define S3C64XX_STOPCFG_TOP_MEMORY_ON (1 << 20) ++#define S3C64XX_STOPCFG_ARM_LOGIC_ON (1 << 17) ++#define S3C64XX_STOPCFG_TOP_LOGIC_ON (1 << 8) ++#define S3C64XX_STOPCFG_OSC_EN (1 << 0) ++ ++#define S3C64XX_SLEEP_CFG S3C_SYSREG(0x818) ++ ++#define S3C64XX_SLEEPCFG_OSC_EN (1 << 0) ++ ++#define S3C64XX_STOP_MEM_CFG S3C_SYSREG(0x81c) ++ ++#define S3C64XX_STOPMEMCFG_MODEMIF_RETAIN (1 << 6) ++#define S3C64XX_STOPMEMCFG_HOSTIF_RETAIN (1 << 5) ++#define S3C64XX_STOPMEMCFG_OTG_RETAIN (1 << 4) ++#define S3C64XX_STOPMEMCFG_HSMCC_RETAIN (1 << 3) ++#define S3C64XX_STOPMEMCFG_IROM_RETAIN (1 << 2) ++#define S3C64XX_STOPMEMCFG_IRDA_RETAIN (1 << 1) ++#define S3C64XX_STOPMEMCFG_NFCON_RETAIN (1 << 0) ++ ++#define S3C64XX_OSC_STABLE S3C_SYSREG(0x824) ++#define S3C64XX_PWR_STABLE S3C_SYSREG(0x828) ++ ++#define S3C64XX_WAKEUP_STAT S3C_SYSREG(0x908) ++ ++#define S3C64XX_WAKEUPSTAT_MMC2 (1 << 11) ++#define S3C64XX_WAKEUPSTAT_MMC1 (1 << 10) ++#define S3C64XX_WAKEUPSTAT_MMC0 (1 << 9) ++#define S3C64XX_WAKEUPSTAT_HSI (1 << 8) ++#define S3C64XX_WAKEUPSTAT_BATFLT (1 << 6) ++#define S3C64XX_WAKEUPSTAT_MSM (1 << 5) ++#define S3C64XX_WAKEUPSTAT_KEY (1 << 4) ++#define S3C64XX_WAKEUPSTAT_TS (1 << 3) ++#define S3C64XX_WAKEUPSTAT_RTC_TICK (1 << 2) ++#define S3C64XX_WAKEUPSTAT_RTC_ALARM (1 << 1) ++#define S3C64XX_WAKEUPSTAT_EINT (1 << 0) ++ ++#define S3C64XX_BLK_PWR_STAT S3C_SYSREG(0x90c) ++ ++#define S3C64XX_BLKPWRSTAT_G (1 << 7) ++#define S3C64XX_BLKPWRSTAT_ETM (1 << 6) ++#define S3C64XX_BLKPWRSTAT_S (1 << 5) ++#define S3C64XX_BLKPWRSTAT_F (1 << 4) ++#define S3C64XX_BLKPWRSTAT_P (1 << 3) ++#define S3C64XX_BLKPWRSTAT_I (1 << 2) ++#define S3C64XX_BLKPWRSTAT_V (1 << 1) ++#define S3C64XX_BLKPWRSTAT_TOP (1 << 0) ++ ++#define S3C64XX_INFORM0 S3C_SYSREG(0xA00) ++#define S3C64XX_INFORM1 S3C_SYSREG(0xA04) ++#define S3C64XX_INFORM2 S3C_SYSREG(0xA08) ++#define S3C64XX_INFORM3 S3C_SYSREG(0xA0C) ++ ++#endif /* __PLAT_S3C64XX_REGS_SYSCON_POWER_H */ +diff -ruN --exclude='*.orig' --exclude='*.rej' linux-2.6.29-rc3.owrt/arch/arm/plat-s3c64xx/include/plat/regs-sys.h linux-2.6.29-rc3.owrt.om/arch/arm/plat-s3c64xx/include/plat/regs-sys.h +--- linux-2.6.29-rc3.owrt/arch/arm/plat-s3c64xx/include/plat/regs-sys.h 2009-05-10 22:05:04.000000000 +0200 ++++ linux-2.6.29-rc3.owrt.om/arch/arm/plat-s3c64xx/include/plat/regs-sys.h 2009-05-10 22:27:59.000000000 +0200 +@@ -17,6 +17,10 @@ + + #define S3C_SYSREG(x) (S3C_VA_SYS + (x)) + ++#define S3C64XX_AHB_CON0 S3C_SYSREG(0x100) ++#define S3C64XX_AHB_CON1 S3C_SYSREG(0x104) ++#define S3C64XX_AHB_CON2 S3C_SYSREG(0x108) ++ + #define S3C64XX_OTHERS S3C_SYSREG(0x900) + + #define S3C64XX_OTHERS_USBMASK (1 << 16) +diff -ruN --exclude='*.orig' --exclude='*.rej' linux-2.6.29-rc3.owrt/arch/arm/plat-s3c64xx/include/plat/tzic-sp890.h linux-2.6.29-rc3.owrt.om/arch/arm/plat-s3c64xx/include/plat/tzic-sp890.h +--- linux-2.6.29-rc3.owrt/arch/arm/plat-s3c64xx/include/plat/tzic-sp890.h 1970-01-01 01:00:00.000000000 +0100 ++++ linux-2.6.29-rc3.owrt.om/arch/arm/plat-s3c64xx/include/plat/tzic-sp890.h 2009-05-10 22:27:59.000000000 +0200 +@@ -0,0 +1,21 @@ ++#ifndef __S3C64XX_TZIC_SP890_H__ ++#define __S3C64XX_TZIC_SP890_H__ ++ ++ ++#define S3C64XX_VA_TZIC0_FIQ_STATUS (S3C_VA_TZIC0 + SP890_TZIC_FIQSTATUS) ++#define S3C64XX_VA_TZIC0_RAWINTR (S3C_VA_TZIC0 + SP890_TZIC_RAWINTR) ++#define S3C64XX_VA_TZIC0_INTSELECT (S3C_VA_TZIC0 + SP890_TZIC_INTSELECT) ++#define S3C64XX_VA_TZIC0_FIQENABLE (S3C_VA_TZIC0 + SP890_TZIC_FIQENABLE) ++#define S3C64XX_VA_TZIC0_FIQENCLEAR (S3C_VA_TZIC0 + SP890_TZIC_FIQENCLEAR) ++#define S3C64XX_VA_TZIC0_FIQBYPASS (S3C_VA_TZIC0 + SP890_TZIC_FIQBYPASS) ++#define S3C64XX_VA_TZIC0_FPROTECTION (S3C_VA_TZIC0 + SP890_TZIC_PROTECTION) ++#define S3C64XX_VA_TZIC0_LOCK (S3C_VA_TZIC0 + SP890_TZIC_LOCK) ++#define S3C64XX_VA_TZIC0_LOCKSTATUS (S3C_VA_TZIC0 + SP890_TZIC_LOCKSTATUS) ++#define S3C64XX_VA_TZIC0_ITCR (S3C_VA_TZIC0 + SP890_TZIC_ITCR) ++#define S3C64XX_VA_TZIC0_ITIP1 (S3C_VA_TZIC0 + SP890_TZIC_ITIP1) ++#define S3C64XX_VA_TZIC0_ITIP2 (S3C_VA_TZIC0 + SP890_TZIC_ITIP2) ++#define S3C64XX_VA_TZIC0_ITOP1 (S3C_VA_TZIC0 + SP890_TZIC_ITOP1) ++#define S3C64XX_VA_TZIC0_ITOP2 (S3C_VA_TZIC0 + SP890_TZIC_ITOP2) ++#define S3C64XX_VA_TZIC0_PERIPHIDO (S3C_VA_TZIC0 + SP890_TZIC_PERIPHIDO) ++ ++#endif +diff -ruN --exclude='*.orig' --exclude='*.rej' linux-2.6.29-rc3.owrt/arch/arm/plat-s3c64xx/irq.c linux-2.6.29-rc3.owrt.om/arch/arm/plat-s3c64xx/irq.c +--- linux-2.6.29-rc3.owrt/arch/arm/plat-s3c64xx/irq.c 2009-05-10 22:08:41.000000000 +0200 ++++ linux-2.6.29-rc3.owrt.om/arch/arm/plat-s3c64xx/irq.c 2009-05-10 22:27:59.000000000 +0200 +@@ -14,12 +14,14 @@ + + #include <linux/kernel.h> + #include <linux/interrupt.h> ++#include <linux/serial_core.h> + #include <linux/irq.h> + #include <linux/io.h> + + #include <asm/hardware/vic.h> + + #include <mach/map.h> ++#include <plat/regs-serial.h> + #include <plat/regs-timer.h> + #include <plat/cpu.h> + +@@ -135,9 +137,6 @@ + } + + /* UART interrupt registers, not worth adding to seperate include header */ +-#define S3C64XX_UINTP 0x30 +-#define S3C64XX_UINTSP 0x34 +-#define S3C64XX_UINTM 0x38 + + static void s3c_irq_uart_mask(unsigned int irq) + { +diff -ruN --exclude='*.orig' --exclude='*.rej' linux-2.6.29-rc3.owrt/arch/arm/plat-s3c64xx/irq-eint.c linux-2.6.29-rc3.owrt.om/arch/arm/plat-s3c64xx/irq-eint.c +--- linux-2.6.29-rc3.owrt/arch/arm/plat-s3c64xx/irq-eint.c 2009-05-10 22:08:41.000000000 +0200 ++++ linux-2.6.29-rc3.owrt.om/arch/arm/plat-s3c64xx/irq-eint.c 2009-05-10 22:27:59.000000000 +0200 +@@ -14,29 +14,20 @@ + + #include <linux/kernel.h> + #include <linux/interrupt.h> ++#include <linux/gpio.h> + #include <linux/irq.h> + #include <linux/io.h> ++#include <linux/gpio.h> + + #include <asm/hardware/vic.h> + + #include <plat/regs-irqtype.h> ++#include <plat/regs-gpio.h> ++#include <plat/gpio-cfg.h> + + #include <mach/map.h> + #include <plat/cpu.h> +- +-/* GPIO is 0x7F008xxx, */ +-#define S3C64XX_GPIOREG(x) (S3C64XX_VA_GPIO + (x)) +- +-#define S3C64XX_EINT0CON0 S3C64XX_GPIOREG(0x900) +-#define S3C64XX_EINT0CON1 S3C64XX_GPIOREG(0x904) +-#define S3C64XX_EINT0FLTCON0 S3C64XX_GPIOREG(0x910) +-#define S3C64XX_EINT0FLTCON1 S3C64XX_GPIOREG(0x914) +-#define S3C64XX_EINT0FLTCON2 S3C64XX_GPIOREG(0x918) +-#define S3C64XX_EINT0FLTCON3 S3C64XX_GPIOREG(0x91C) +- +-#define S3C64XX_EINT0MASK S3C64XX_GPIOREG(0x920) +-#define S3C64XX_EINT0PEND S3C64XX_GPIOREG(0x924) +- ++#include <plat/pm.h> + + #define eint_offset(irq) ((irq) - IRQ_EINT(0)) + #define eint_irq_to_bit(irq) (1 << eint_offset(irq)) +@@ -55,7 +46,7 @@ + u32 mask; + + mask = __raw_readl(S3C64XX_EINT0MASK); +- mask |= eint_irq_to_bit(irq); ++ mask &= ~eint_irq_to_bit(irq); + __raw_writel(mask, S3C64XX_EINT0MASK); + } + +@@ -74,6 +65,7 @@ + static int s3c_irq_eint_set_type(unsigned int irq, unsigned int type) + { + int offs = eint_offset(irq); ++ int pin; + int shift; + u32 ctrl, mask; + u32 newvalue = 0; +@@ -125,6 +117,14 @@ + ctrl |= newvalue << shift; + __raw_writel(ctrl, reg); + ++ /* set the GPIO pin appropriately */ ++ ++ if (offs < 23) ++ pin = S3C64XX_GPN(offs); ++ else ++ pin = S3C64XX_GPM(offs - 23); ++ ++ s3c_gpio_cfgpin(pin, S3C_GPIO_SFN(2)); + return 0; + } + +@@ -135,6 +135,7 @@ + .mask_ack = s3c_irq_eint_maskack, + .ack = s3c_irq_eint_ack, + .set_type = s3c_irq_eint_set_type, ++ .set_wake = s3c_irqext_wake, + }; + + /* s3c_irq_demux_eint +diff -ruN --exclude='*.orig' --exclude='*.rej' linux-2.6.29-rc3.owrt/arch/arm/plat-s3c64xx/irq-pm.c linux-2.6.29-rc3.owrt.om/arch/arm/plat-s3c64xx/irq-pm.c +--- linux-2.6.29-rc3.owrt/arch/arm/plat-s3c64xx/irq-pm.c 1970-01-01 01:00:00.000000000 +0100 ++++ linux-2.6.29-rc3.owrt.om/arch/arm/plat-s3c64xx/irq-pm.c 2009-05-10 22:27:59.000000000 +0200 +@@ -0,0 +1,173 @@ ++/* arch/arm/plat-s3c64xx/irq-pm.c ++ * ++ * Copyright 2008 Openmoko, Inc. ++ * Copyright 2008 Simtec Electronics ++ * Ben Dooks <ben@simtec.co.uk> ++ * http://armlinux.simtec.co.uk/ ++ * ++ * S3C64XX - Interrupt handling Power Management ++ * ++ * 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/sysdev.h> ++#include <linux/interrupt.h> ++#include <linux/serial_core.h> ++#include <linux/irq.h> ++#include <linux/io.h> ++ ++#include <asm/hardware/vic.h> ++ ++#include <mach/map.h> ++ ++#include <plat/regs-serial.h> ++#include <plat/regs-timer.h> ++#include <plat/regs-gpio.h> ++#include <plat/cpu.h> ++#include <plat/pm.h> ++ ++/* We handled all the IRQ types in this code, to save having to make several ++ * small files to handle each different type separately. Having the EINT_GRP ++ * code here shouldn't be as much bloat as the IRQ table space needed when ++ * they are enabled. The added benefit is we ensure that these registers are ++ * in the same state as we suspended. ++ */ ++ ++static struct sleep_save irq_save[] = { ++ SAVE_ITEM(S3C64XX_PRIORITY), ++ SAVE_ITEM(S3C64XX_EINT0CON0), ++ SAVE_ITEM(S3C64XX_EINT0CON1), ++ SAVE_ITEM(S3C64XX_EINT0FLTCON0), ++ SAVE_ITEM(S3C64XX_EINT0FLTCON1), ++ SAVE_ITEM(S3C64XX_EINT0FLTCON2), ++ SAVE_ITEM(S3C64XX_EINT0FLTCON3), ++ SAVE_ITEM(S3C64XX_EINT0MASK), ++ SAVE_ITEM(S3C64XX_TINT_CSTAT), ++}; ++ ++static struct irq_grp_save { ++ u32 fltcon; ++ u32 con; ++ u32 mask; ++} eint_grp_save[5]; ++ ++struct irq_vic_save { ++ u32 int_select; ++ u32 int_enable; ++ u32 soft_int; ++ u32 protect; ++ u32 vect_addr[32]; ++ u32 vect_cntl[32]; ++}; ++ ++static struct irq_vic_save irq_pm_vic0_save; ++static struct irq_vic_save irq_pm_vic1_save; ++ ++static u32 irq_uart_mask[CONFIG_SERIAL_SAMSUNG_UARTS]; ++ ++static void s3c64xx_vic_save(void __iomem *base, struct irq_vic_save *save) ++{ ++ int v; ++ ++ save->int_select = readl(base + VIC_INT_SELECT); ++ save->int_enable = readl(base + VIC_INT_ENABLE); ++ save->soft_int = readl(base + VIC_INT_SOFT); ++ save->protect = readl(base + VIC_PROTECT); ++ ++ S3C_PMDBG("%s: select=%08x, enable=%08x, protect=%08x\n", __func__, ++ save->int_select, save->int_enable, save->protect); ++ ++ for (v = 0; v < ARRAY_SIZE(save->vect_addr); v++) { ++ save->vect_addr[v] = readl(base + VIC_VECT_ADDR0 + (v * 4)); ++ save->vect_cntl[v] = readl(base + VIC_VECT_CNTL0 + (v * 4)); ++ } ++} ++ ++static void s3c64xx_vic_restore(void __iomem *base, struct irq_vic_save *save) ++{ ++ int v; ++ ++ writel(save->int_select, base + VIC_INT_SELECT); ++ writel(save->protect, base + VIC_PROTECT); ++ ++ /* set the enabled ints and then clear the non-enabled */ ++ writel(save->int_enable, base + VIC_INT_ENABLE); ++ writel(~save->int_enable, base + VIC_INT_ENABLE_CLEAR); ++ ++ /* and the same for the soft-int register */ ++ ++ writel(save->soft_int, base + VIC_INT_SOFT); ++ writel(~save->soft_int, base + VIC_INT_SOFT_CLEAR); ++ ++ S3C_PMDBG("%s: vic int_enable=%08x\n", __func__, readl(base + VIC_INT_ENABLE)); ++ ++ for (v = 0; v < ARRAY_SIZE(save->vect_addr); v++) { ++ writel(save->vect_addr[v], base + VIC_VECT_ADDR0 + (v * 4)); ++ writel(save->vect_cntl[v], base + VIC_VECT_CNTL0 + (v * 4)); ++ } ++} ++ ++static int s3c64xx_irq_pm_suspend(struct sys_device *dev, pm_message_t state) ++{ ++ struct irq_grp_save *grp = eint_grp_save; ++ int i; ++ ++ S3C_PMDBG("%s: suspending IRQs\n", __func__); ++ ++ s3c64xx_vic_save(S3C_VA_VIC0, &irq_pm_vic0_save); ++ s3c64xx_vic_save(S3C_VA_VIC1, &irq_pm_vic1_save); ++ ++ s3c_pm_do_save(irq_save, ARRAY_SIZE(irq_save)); ++ ++ for (i = 0; i < CONFIG_SERIAL_SAMSUNG_UARTS; i++) ++ irq_uart_mask[i] = __raw_readl(S3C_VA_UARTx(i) + S3C64XX_UINTM); ++ ++ for (i = 0; i < ARRAY_SIZE(eint_grp_save); i++, grp++) { ++ grp->con = __raw_readl(S3C64XX_EINT12CON + (i * 4)); ++ grp->mask = __raw_readl(S3C64XX_EINT12MASK + (i * 4)); ++ grp->fltcon = __raw_readl(S3C64XX_EINT12FLTCON + (i * 4)); ++ } ++ ++ return 0; ++} ++ ++static int s3c64xx_irq_pm_resume(struct sys_device *dev) ++{ ++ struct irq_grp_save *grp = eint_grp_save; ++ int i; ++ ++ S3C_PMDBG("%s: resuming IRQs\n", __func__); ++ ++ s3c_pm_do_restore(irq_save, ARRAY_SIZE(irq_save)); ++ ++ s3c64xx_vic_restore(S3C_VA_VIC0, &irq_pm_vic0_save); ++ s3c64xx_vic_restore(S3C_VA_VIC1, &irq_pm_vic1_save); ++ ++ for (i = 0; i < CONFIG_SERIAL_SAMSUNG_UARTS; i++) ++ __raw_writel(irq_uart_mask[i], S3C_VA_UARTx(i) + S3C64XX_UINTM); ++ ++ for (i = 0; i < ARRAY_SIZE(eint_grp_save); i++, grp++) { ++ __raw_writel(grp->con, S3C64XX_EINT12CON + (i * 4)); ++ __raw_writel(grp->mask, S3C64XX_EINT12MASK + (i * 4)); ++ __raw_writel(grp->fltcon, S3C64XX_EINT12FLTCON + (i * 4)); ++ } ++ ++ S3C_PMDBG("%s: IRQ configuration restored\n", __func__); ++ return 0; ++} ++ ++static struct sysdev_driver s3c64xx_irq_driver = { ++ .suspend = s3c64xx_irq_pm_suspend, ++ .resume = s3c64xx_irq_pm_resume, ++}; ++ ++static int __init s3c64xx_irq_pm_init(void) ++{ ++ return sysdev_driver_register(&s3c64xx_sysclass, &s3c64xx_irq_driver); ++} ++ ++arch_initcall(s3c64xx_irq_pm_init); ++ +diff -ruN --exclude='*.orig' --exclude='*.rej' linux-2.6.29-rc3.owrt/arch/arm/plat-s3c64xx/Kconfig linux-2.6.29-rc3.owrt.om/arch/arm/plat-s3c64xx/Kconfig +--- linux-2.6.29-rc3.owrt/arch/arm/plat-s3c64xx/Kconfig 2009-05-10 22:05:04.000000000 +0200 ++++ linux-2.6.29-rc3.owrt.om/arch/arm/plat-s3c64xx/Kconfig 2009-05-10 22:27:59.000000000 +0200 +@@ -19,6 +19,8 @@ + select S3C_GPIO_PULL_UPDOWN + select S3C_GPIO_CFG_S3C24XX + select S3C_GPIO_CFG_S3C64XX ++ select USB_ARCH_HAS_OHCI ++ select S3C64XX_SETUP_USBOTG + help + Base platform code for any Samsung S3C64XX device + +@@ -38,6 +40,10 @@ + Common clock support code for the S3C6400 that is shared + by other CPUs in the series, such as the S3C6410. + ++config S3C64XX_DMA ++ bool "S3C64XX DMA" ++ select S3C_DMA ++ + # platform specific device setup + + config S3C64XX_SETUP_I2C0 +@@ -59,4 +65,10 @@ + help + Common setup code for S3C64XX with an 24bpp RGB display helper. + ++config S3C64XX_SETUP_USBOTG ++ bool ++ help ++ Common setup code for S3C64XX with USB OTG ++ ++ + endif +diff -ruN --exclude='*.orig' --exclude='*.rej' linux-2.6.29-rc3.owrt/arch/arm/plat-s3c64xx/Makefile linux-2.6.29-rc3.owrt.om/arch/arm/plat-s3c64xx/Makefile +--- linux-2.6.29-rc3.owrt/arch/arm/plat-s3c64xx/Makefile 2009-05-10 22:05:04.000000000 +0200 ++++ linux-2.6.29-rc3.owrt.om/arch/arm/plat-s3c64xx/Makefile 2009-05-10 22:27:59.000000000 +0200 +@@ -24,8 +24,22 @@ + obj-$(CONFIG_CPU_S3C6400_INIT) += s3c6400-init.o + obj-$(CONFIG_CPU_S3C6400_CLOCK) += s3c6400-clock.o + ++# DMA support ++ ++obj-$(CONFIG_S3C64XX_DMA) += dma.o ++ ++# PM support ++ ++obj-$(CONFIG_PM) += pm.o ++obj-$(CONFIG_PM) += sleep.o ++obj-$(CONFIG_PM) += irq-pm.o ++ ++obj-$(CONFIG_CPU_FREQ_S3C64XX) += cpufreq.o ++ + # Device setup + + obj-$(CONFIG_S3C64XX_SETUP_I2C0) += setup-i2c0.o + obj-$(CONFIG_S3C64XX_SETUP_I2C1) += setup-i2c1.o + obj-$(CONFIG_S3C64XX_SETUP_FB_24BPP) += setup-fb-24bpp.o ++obj-$(CONFIG_S3C64XX_SETUP_USBOTG) += dev-usbgadget.o ++ +diff -ruN --exclude='*.orig' --exclude='*.rej' linux-2.6.29-rc3.owrt/arch/arm/plat-s3c64xx/pm.c linux-2.6.29-rc3.owrt.om/arch/arm/plat-s3c64xx/pm.c +--- linux-2.6.29-rc3.owrt/arch/arm/plat-s3c64xx/pm.c 1970-01-01 01:00:00.000000000 +0100 ++++ linux-2.6.29-rc3.owrt.om/arch/arm/plat-s3c64xx/pm.c 2009-05-10 22:27:59.000000000 +0200 +@@ -0,0 +1,177 @@ ++/* linux/arch/arm/plat-s3c64xx/pm.c ++ * ++ * Copyright 2008 Openmoko, Inc. ++ * Copyright 2008 Simtec Electronics ++ * Ben Dooks <ben@simtec.co.uk> ++ * http://armlinux.simtec.co.uk/ ++ * ++ * S3C64XX CPU PM support. ++ * ++ * This program is free software; you can redistribute it and/or modify ++ * it under the terms of the GNU General Public License version 2 as ++ * published by the Free Software Foundation. ++*/ ++ ++#include <linux/init.h> ++#include <linux/suspend.h> ++#include <linux/serial_core.h> ++#include <linux/io.h> ++ ++#include <mach/map.h> ++ ++#include <plat/pm.h> ++#include <plat/regs-sys.h> ++#include <plat/regs-gpio.h> ++#include <plat/regs-clock.h> ++#include <plat/regs-modem.h> ++#include <plat/regs-syscon-power.h> ++#include <plat/regs-gpio-memport.h> ++ ++#ifdef CONFIG_S3C_PM_DEBUG_LED_SMDK ++#include <plat/gpio-bank-n.h> ++ ++void s3c_pm_debug_smdkled(u32 set, u32 clear) ++{ ++ unsigned long flags; ++ u32 reg; ++ ++ local_irq_save(flags); ++ reg = __raw_readl(S3C64XX_GPNCON); ++ reg &= ~(S3C64XX_GPN_CONMASK(12) | S3C64XX_GPN_CONMASK(13) | ++ S3C64XX_GPN_CONMASK(14) | S3C64XX_GPN_CONMASK(15)); ++ reg |= S3C64XX_GPN_OUTPUT(12) | S3C64XX_GPN_OUTPUT(13) | ++ S3C64XX_GPN_OUTPUT(14) | S3C64XX_GPN_OUTPUT(15); ++ __raw_writel(reg, S3C64XX_GPNCON); ++ ++ reg = __raw_readl(S3C64XX_GPNDAT); ++ reg &= ~(clear << 12); ++ reg |= set << 12; ++ __raw_writel(reg, S3C64XX_GPNDAT); ++ ++ local_irq_restore(flags); ++} ++#endif ++ ++static struct sleep_save core_save[] = { ++ SAVE_ITEM(S3C_APLL_LOCK), ++ SAVE_ITEM(S3C_MPLL_LOCK), ++ SAVE_ITEM(S3C_EPLL_LOCK), ++ SAVE_ITEM(S3C_CLK_SRC), ++ SAVE_ITEM(S3C_CLK_DIV0), ++ SAVE_ITEM(S3C_CLK_DIV1), ++ SAVE_ITEM(S3C_CLK_DIV2), ++ SAVE_ITEM(S3C_CLK_OUT), ++ SAVE_ITEM(S3C_HCLK_GATE), ++ SAVE_ITEM(S3C_PCLK_GATE), ++ SAVE_ITEM(S3C_SCLK_GATE), ++ SAVE_ITEM(S3C_MEM0_GATE), ++ ++ SAVE_ITEM(S3C_EPLL_CON1), ++ SAVE_ITEM(S3C_EPLL_CON0), ++ ++ SAVE_ITEM(S3C64XX_MEM0DRVCON), ++ SAVE_ITEM(S3C64XX_MEM1DRVCON), ++ ++#ifndef CONFIG_CPU_FREQ ++ SAVE_ITEM(S3C_APLL_CON), ++ SAVE_ITEM(S3C_MPLL_CON), ++#endif ++}; ++ ++static struct sleep_save misc_save[] = { ++ SAVE_ITEM(S3C64XX_AHB_CON0), ++ SAVE_ITEM(S3C64XX_AHB_CON1), ++ SAVE_ITEM(S3C64XX_AHB_CON2), ++ ++ SAVE_ITEM(S3C64XX_MODEM_MIFPCON), ++ SAVE_ITEM(S3C64XX_SPCON), ++ ++ SAVE_ITEM(S3C64XX_MEM0CONSTOP), ++ SAVE_ITEM(S3C64XX_MEM1CONSTOP), ++ SAVE_ITEM(S3C64XX_MEM0CONSLP0), ++ SAVE_ITEM(S3C64XX_MEM0CONSLP1), ++ SAVE_ITEM(S3C64XX_MEM1CONSLP), ++}; ++ ++void s3c_pm_configure_extint(void) ++{ ++ __raw_writel(s3c_irqwake_eintmask, S3C64XX_EINT_MASK); ++} ++ ++void s3c_pm_restore_core(void) ++{ ++ __raw_writel(0, S3C64XX_EINT_MASK); ++ ++ s3c_pm_debug_smdkled(1 << 2, 0); ++ ++ s3c_pm_do_restore_core(core_save, ARRAY_SIZE(core_save)); ++ s3c_pm_do_restore(misc_save, ARRAY_SIZE(misc_save)); ++} ++ ++void s3c_pm_save_core(void) ++{ ++ s3c_pm_do_save(misc_save, ARRAY_SIZE(misc_save)); ++ s3c_pm_do_save(core_save, ARRAY_SIZE(core_save)); ++} ++ ++/* since both s3c6400 and s3c6410 share the same sleep pm calls, we ++ * put the per-cpu code in here until any new cpu comes along and changes ++ * this. ++ */ ++ ++#include <plat/regs-gpio.h> ++ ++static void s3c64xx_cpu_suspend(void) ++{ ++ unsigned long tmp; ++ ++ /* set our standby method to sleep */ ++ ++ tmp = __raw_readl(S3C64XX_PWR_CFG); ++ tmp &= ~S3C64XX_PWRCFG_CFG_WFI_MASK; ++ tmp |= S3C64XX_PWRCFG_CFG_WFI_SLEEP; ++ __raw_writel(tmp, S3C64XX_PWR_CFG); ++ ++ /* clear any old wakeup */ ++ ++ __raw_writel(__raw_readl(S3C64XX_WAKEUP_STAT), ++ S3C64XX_WAKEUP_STAT); ++ ++ /* set the LED state to 0110 over sleep */ ++ s3c_pm_debug_smdkled(3 << 1, 0xf); ++ ++ /* issue the standby signal into the pm unit. Note, we ++ * issue a write-buffer drain just in case */ ++ ++ tmp = 0; ++ ++ asm("b 1f\n\t" ++ ".align 5\n\t" ++ "1:\n\t" ++ "mcr p15, 0, %0, c7, c10, 5\n\t" ++ "mcr p15, 0, %0, c7, c10, 4\n\t" ++ "mcr p15, 0, %0, c7, c0, 4" :: "r" (tmp)); ++ ++ /* we should never get past here */ ++ ++ panic("sleep resumed to originator?"); ++} ++ ++static void s3c64xx_pm_prepare(void) ++{ ++ /* store address of resume. */ ++ __raw_writel(virt_to_phys(s3c_cpu_resume), S3C64XX_INFORM0); ++ ++ /* ensure previous wakeup state is cleared before sleeping */ ++ __raw_writel(__raw_readl(S3C64XX_WAKEUP_STAT), S3C64XX_WAKEUP_STAT); ++} ++ ++static int s3c64xx_pm_init(void) ++{ ++ pm_cpu_prep = s3c64xx_pm_prepare; ++ pm_cpu_sleep = s3c64xx_cpu_suspend; ++ pm_uart_udivslot = 1; ++ return 0; ++} ++ ++arch_initcall(s3c64xx_pm_init); +diff -ruN --exclude='*.orig' --exclude='*.rej' linux-2.6.29-rc3.owrt/arch/arm/plat-s3c64xx/s3c6400-clock.c linux-2.6.29-rc3.owrt.om/arch/arm/plat-s3c64xx/s3c6400-clock.c +--- linux-2.6.29-rc3.owrt/arch/arm/plat-s3c64xx/s3c6400-clock.c 2009-05-10 22:08:41.000000000 +0200 ++++ linux-2.6.29-rc3.owrt.om/arch/arm/plat-s3c64xx/s3c6400-clock.c 2009-05-10 22:27:59.000000000 +0200 +@@ -24,6 +24,7 @@ + + #include <mach/hardware.h> + #include <mach/map.h> ++#include <mach/cpu.h> + + #include <plat/cpu-freq.h> + +@@ -88,6 +89,80 @@ + .sources = &clk_src_apll, + }; + ++static u32 clk_arm_div_mask(void) ++{ ++ if (cpu_is_s3c6400()) ++ return S3C6400_CLKDIV0_ARM_MASK; ++ ++ if (cpu_is_s3c6410()) ++ return S3C6410_CLKDIV0_ARM_MASK; ++ ++ return 0; ++} ++ ++static unsigned long s3c64xx_clk_arm_get_rate(struct clk *clk) ++{ ++ unsigned long rate = clk_get_rate(clk->parent); ++ u32 val; ++ ++ val = __raw_readl(S3C_CLK_DIV0); ++ val &= clk_arm_div_mask(); ++ ++ return rate / (val + 1); ++} ++ ++static unsigned long s3c64xx_clk_arm_round_rate(struct clk *clk, ++ unsigned long rate) ++{ ++ unsigned long parent = clk_get_rate(clk->parent); ++ int div; ++ int max = clk_arm_div_mask() + 1; ++ ++ if (parent < rate) ++ return parent; ++ ++ div = parent / rate; ++ ++ if (div < 1) ++ div = 1; ++ if (div > max) ++ div = max; ++ ++ return parent / div; ++} ++ ++static int s3c64xx_clk_arm_set_rate(struct clk *clk, unsigned long rate) ++{ ++ unsigned int div; ++ u32 val; ++ unsigned long flags; ++ ++ div = (clk_get_rate(clk->parent) / rate) - 1; ++ ++ if (div > clk_arm_div_mask()) ++ return -EINVAL; ++ ++ local_irq_save(flags); ++ ++ val = __raw_readl(S3C_CLK_DIV0); ++ val &= ~clk_arm_div_mask(); ++ val |= div; ++ ++ __raw_writel(val, S3C_CLK_DIV0); ++ local_irq_restore(flags); ++ ++ return 0; ++} ++ ++static struct clk clk_arm = { ++ .name = "armclk", ++ .id = -1, ++ .parent = &clk_mout_apll.clk, ++ .round_rate = &s3c64xx_clk_arm_round_rate, ++ .get_rate = s3c64xx_clk_arm_get_rate, ++ .set_rate = s3c64xx_clk_arm_set_rate, ++}; ++ + struct clk clk_fout_epll = { + .name = "fout_epll", + .id = -1, +@@ -239,10 +314,12 @@ + + rate = clk_round_rate(clk, rate); + div = clk_get_rate(clk->parent) / rate; ++ if (div > 16) ++ return -EINVAL; + + val = __raw_readl(reg); +- val &= ~sclk->mask; +- val |= (rate - 1) << sclk->shift; ++ val &= ~(0xf << sclk->divider_shift); ++ val |= (div - 1) << sclk->divider_shift; + __raw_writel(val, reg); + + return 0; +@@ -282,7 +359,7 @@ + if (rate > parent_rate) + rate = parent_rate; + else { +- div = rate / parent_rate; ++ div = parent_rate / rate; + + if (div == 0) + div = 1; +@@ -351,7 +428,7 @@ + + static struct clksrc_clk clk_usbhost = { + .clk = { +- .name = "usb-host-bus", ++ .name = "usb-bus-host", + .id = -1, + .ctrlbit = S3C_CLKCON_SCLK_UHOST, + .enable = s3c64xx_sclk_ctrl, +@@ -518,6 +595,55 @@ + .reg_divider = S3C_CLK_DIV2, + }; + ++static struct clk *clkset_camera_list[] = { ++ &clk_h2, ++}; ++ ++static struct clk_sources clkset_camera = { ++ .sources = clkset_camera_list, ++ .nr_sources = ARRAY_SIZE(clkset_camera_list), ++}; ++ ++static struct clksrc_clk clk_camera = { ++ .clk = { ++ .name = "camera", ++ .id = -1, ++ .ctrlbit = S3C_CLKCON_SCLK_CAM, ++ .enable = s3c64xx_sclk_ctrl, ++ .set_parent = s3c64xx_setparent_clksrc, ++ .get_rate = s3c64xx_getrate_clksrc, ++ .set_rate = s3c64xx_setrate_clksrc, ++ .round_rate = s3c64xx_roundrate_clksrc, ++ }, ++ .shift = 0, ++ .mask = 0, ++ .sources = &clkset_camera, ++ .divider_shift = S3C6400_CLKDIV0_CAM_SHIFT, ++ .reg_divider = S3C_CLK_DIV0, ++}; ++ ++static struct clk *clkset_camif_list[] = { ++ &clk_h, ++}; ++ ++static struct clk_sources clkset_camif = { ++ .sources = clkset_camif_list, ++ .nr_sources = ARRAY_SIZE(clkset_camif_list), ++}; ++ ++static struct clksrc_clk clk_camif = { ++ .clk = { ++ .name = "camif", ++ .id = -1, ++ .ctrlbit = S3C_CLKCON_HCLK_CAMIF, ++ .enable = s3c64xx_hclk_ctrl, ++ .set_parent = s3c64xx_setparent_clksrc, ++ }, ++ .shift = 0, ++ .mask = 0, ++ .sources = &clkset_camif, ++}; ++ + /* Clock initialisation code */ + + static struct clksrc_clk *init_parents[] = { +@@ -534,6 +660,8 @@ + &clk_audio0, + &clk_audio1, + &clk_irda, ++ &clk_camif, ++ &clk_camera, + }; + + static void __init_or_cpufreq s3c6400_set_clksrc(struct clksrc_clk *clk) +@@ -606,6 +734,7 @@ + clk_fout_epll.rate = epll; + clk_fout_apll.rate = apll; + ++ clk_h2.rate = hclk2; + clk_h.rate = hclk; + clk_p.rate = pclk; + clk_f.rate = fclk; +@@ -633,6 +762,9 @@ + &clk_audio0.clk, + &clk_audio1.clk, + &clk_irda.clk, ++ &clk_camera.clk, ++ &clk_camif.clk, ++ &clk_arm, + }; + + void __init s3c6400_register_clocks(void) +@@ -650,6 +782,5 @@ + } + } + +- clk_mpll.parent = &clk_mout_mpll.clk; + clk_epll.parent = &clk_mout_epll.clk; + } +diff -ruN --exclude='*.orig' --exclude='*.rej' linux-2.6.29-rc3.owrt/arch/arm/plat-s3c64xx/sleep.S linux-2.6.29-rc3.owrt.om/arch/arm/plat-s3c64xx/sleep.S +--- linux-2.6.29-rc3.owrt/arch/arm/plat-s3c64xx/sleep.S 1970-01-01 01:00:00.000000000 +0100 ++++ linux-2.6.29-rc3.owrt.om/arch/arm/plat-s3c64xx/sleep.S 2009-05-10 22:27:59.000000000 +0200 +@@ -0,0 +1,143 @@ ++/* linux/0arch/arm/plat-s3c64xx/sleep.S ++ * ++ * Copyright 2008 Openmoko, Inc. ++ * Copyright 2008 Simtec Electronics ++ * Ben Dooks <ben@simtec.co.uk> ++ * http://armlinux.simtec.co.uk/ ++ * ++ * S3C64XX CPU sleep code ++ * ++ * 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/linkage.h> ++#include <asm/assembler.h> ++#include <mach/map.h> ++ ++#undef S3C64XX_VA_GPIO ++#define S3C64XX_VA_GPIO (0x0) ++ ++#include <plat/regs-gpio.h> ++#include <plat/gpio-bank-n.h> ++ ++#define LL_UART (S3C_PA_UART + (0x400 * CONFIG_S3C_LOWLEVEL_UART_PORT)) ++ ++ .text ++ ++ /* s3c_cpu_save ++ * ++ * Save enough processor state to allow the restart of the pm.c ++ * code after resume. ++ * ++ * entry: ++ * r0 = pointer to the save block ++ * exit: ++ * r0 = exit code: 1 => stored data ++ * 0 => resumed from sleep ++ */ ++ ++ENTRY(s3c_cpu_save) ++ stmfd sp!, { r4 - r12, lr } ++ ++ mrc p15, 0, r4, c13, c0, 0 @ FCSE/PID ++ mrc p15, 0, r5, c3, c0, 0 @ Domain ID ++ mrc p15, 0, r6, c2, c0, 0 @ Translation Table BASE0 ++ mrc p15, 0, r7, c2, c0, 1 @ Translation Table BASE1 ++ mrc p15, 0, r8, c2, c0, 2 @ Translation Table Control ++ mrc p15, 0, r9, c1, c0, 0 @ Control register ++ mrc p15, 0, r10, c1, c0, 1 @ Auxiliary control register ++ mrc p15, 0, r11, c1, c0, 2 @ Co-processor access controls ++ ++ stmia r0, { r4 - r13 } @ Save CP registers and SP ++ mov r0, #0 ++ ldmfd sp, { r4 - r12, pc } @ return, not disturbing SP ++ ++ @@ return to the caller, after the MMU is turned on. ++ @@ restore the last bits of the stack and return. ++resume_with_mmu: ++ mov r0, #1 ++ ldmfd sp!, { r4 - r12, pc } @ return, from sp from s3c_cpu_save ++ ++ .data ++ ++ /* the next bit is code, but it requires easy access to the ++ * s3c_sleep_save_phys data before the MMU is switched on, so ++ * we store the code that needs this variable in the .data where ++ * the value can be written to (the .text segment is RO). ++ */ ++ ++ .global s3c_sleep_save_phys ++s3c_sleep_save_phys: ++ .word 0 ++ ++ /* Sleep magic, the word before the resume entry point so that the ++ * bootloader can check for a resumeable image. */ ++ ++ .word 0x2bedf00d ++ ++ /* s3c_cpu_reusme ++ * ++ * This is the entry point, stored by whatever method the bootloader ++ * requires to get the kernel runnign again. This code expects to be ++ * entered with no caches live and the MMU disabled. It will then ++ * restore the MMU and other basic CP registers saved and restart ++ * the kernel C code to finish the resume code. ++ */ ++ ++ENTRY(s3c_cpu_resume) ++ msr cpsr_c, #PSR_I_BIT | PSR_F_BIT | SVC_MODE ++ ldr r2, =LL_UART /* for debug */ ++ ++#ifdef CONFIG_S3C_PM_DEBUG_LED_SMDK ++ /* Initialise the GPIO state if we are debugging via the SMDK LEDs, ++ * as the uboot version supplied resets these to inputs during the ++ * resume checks. ++ */ ++ ++ ldr r3, =S3C64XX_PA_GPIO ++ ldr r0, [ r3, #S3C64XX_GPNCON ] ++ bic r0, r0, #(S3C64XX_GPN_CONMASK(12) | S3C64XX_GPN_CONMASK(13) | \ ++ S3C64XX_GPN_CONMASK(14) | S3C64XX_GPN_CONMASK(15)) ++ orr r0, r0, #(S3C64XX_GPN_OUTPUT(12) | S3C64XX_GPN_OUTPUT(13) | \ ++ S3C64XX_GPN_OUTPUT(14) | S3C64XX_GPN_OUTPUT(15)) ++ str r0, [ r3, #S3C64XX_GPNCON ] ++ ++ ldr r0, [ r3, #S3C64XX_GPNDAT ] ++ bic r0, r0, #0xf << 12 @ GPN12..15 ++ orr r0, r0, #1 << 15 @ GPN15 ++ str r0, [ r3, #S3C64XX_GPNDAT ] ++#endif ++ ++ /* __v6_setup from arch/arm/mm/proc-v6.S, ensure that the caches ++ * are thoroughly cleaned just in case the bootloader didn't do it ++ * for us. */ ++ mov r0, #0 ++ mcr p15, 0, r0, c7, c14, 0 @ clean+invalidate D cache ++ mcr p15, 0, r0, c7, c5, 0 @ invalidate I cache ++ mcr p15, 0, r0, c7, c15, 0 @ clean+invalidate cache ++ mcr p15, 0, r0, c7, c10, 4 @ drain write buffer ++ @@mcr p15, 0, r0, c8, c7, 0 @ invalidate I + D TLBs ++ @@mcr p15, 0, r0, c7, c7, 0 @ Invalidate I + D caches ++ ++ ldr r0, s3c_sleep_save_phys ++ ldmia r0, { r4 - r13 } ++ ++ mcr p15, 0, r4, c13, c0, 0 @ FCSE/PID ++ mcr p15, 0, r5, c3, c0, 0 @ Domain ID ++ mcr p15, 0, r6, c2, c0, 0 @ Translation Table BASE0 ++ mcr p15, 0, r7, c2, c0, 1 @ Translation Table BASE1 ++ mcr p15, 0, r8, c2, c0, 2 @ Translation Table Control ++ mcr p15, 0, r10, c1, c0, 1 @ Auxiliary control register ++ ++ mov r0, #0 @ restore copro access controls ++ mcr p15, 0, r11, c1, c0, 2 @ Co-processor access controls ++ mcr p15, 0, r0, c7, c5, 4 ++ ++ ldr r2, =resume_with_mmu ++ mcr p15, 0, r9, c1, c0, 0 /* turn mmu back on */ ++ nop ++ mov pc, r2 /* jump back */ ++ ++ .end +diff -ruN --exclude='*.orig' --exclude='*.rej' linux-2.6.29-rc3.owrt/arch/arm/tools/mach-types linux-2.6.29-rc3.owrt.om/arch/arm/tools/mach-types +--- linux-2.6.29-rc3.owrt/arch/arm/tools/mach-types 2009-05-10 22:08:41.000000000 +0200 ++++ linux-2.6.29-rc3.owrt.om/arch/arm/tools/mach-types 2009-05-10 22:27:59.000000000 +0200 +@@ -1994,3 +1994,5 @@ + blaze MACH_BLAZE BLAZE 2004 + linkstation_ls_hgl MACH_LINKSTATION_LS_HGL LINKSTATION_LS_HGL 2005 + htcvenus MACH_HTCVENUS HTCVENUS 2006 ++om_3d7k MACH_OM_3D7K OM_3D7K 2120 ++ +diff -ruN --exclude='*.orig' --exclude='*.rej' linux-2.6.29-rc3.owrt/build linux-2.6.29-rc3.owrt.om/build +--- linux-2.6.29-rc3.owrt/build 1970-01-01 01:00:00.000000000 +0100 ++++ linux-2.6.29-rc3.owrt.om/build 2009-05-10 22:27:59.000000000 +0200 +@@ -0,0 +1,128 @@ ++#!/bin/sh ++# ++# Kernel building helper script (C)2008 Openmoko, Inc ++# Andy Green <andy@openmoko.org> ++# ++# Licensed under GPLv3 or later ++# ++# ++# you need to run this from the top level source dir, but it creates all ++# object files into a subdir given in the first argument, eg ++# ++# ./build GTA02 ++# ++# this radically speeds up swapping between build contexts. Note the config ++# for each build lives in the subdir. ++ ++PARALLEL=16 ++ ++if [ -z "$1" ] ; then ++ echo "Specify the build subdir, eg, GTA02 which contains the .config" ++ echo "and will hold the object files" ++ exit 1 ++fi ++ ++mkdir -p $1 ++ ++if [ -z "$CROSS_COMPILE" ]; then ++ export CROSS_COMPILE=/usr/local/openmoko/arm/bin/arm-angstrom-linux-gnueabi- ++fi ++make O=$1 ARCH=arm silentoldconfig ++ ++# ++# figure out what we are building ++# ++ ++PRODUCT= ++ ++if [ ! -z "`grep CONFIG_MACH_NEO1973_GTA01=y $1/.config`" ] ; then ++ START=30008000 ++ PRODUCT=GTA01 ++fi ++ ++if [ ! -z "`grep CONFIG_MACH_NEO1973_GTA02=y $1/.config`" ] ; then ++ START=30008000 ++ PRODUCT=GTA02 ++fi ++ ++if [ ! -z "`grep CONFIG_MACH_OM_3D7K=y $1/.config`" ] ; then ++ START=50008000 ++ PRODUCT=OM_3D7K ++fi ++ ++if [ ! -z "`grep CONFIG_MACH_SMDK6410=y $1/.config`" ] ; then ++ START=50008000 ++ PRODUCT=SMDK6410 ++fi ++ ++if [ ! -z "`grep CONFIG_MACH_M800=y $1/.config`" ] ; then ++ START=30008000 ++ PRODUCT=M800 ++fi ++ ++if [ -z "$PRODUCT" ] ; then ++ echo "Unable to figure out what we are building from the config" ++ exit 1 ++fi ++ ++# ++# check that we are in a valid branch ++# ++ ++if git branch | head -n1 | grep -q "* (no branch)"; then ++ cat <<EOF 1>&2 ++There is no branch in the local copy of the repository right now! ++Hint: type git-branch, make sure you are in a valid branch and then try again ++EOF ++ exit 1 ++fi; ++ ++# ++# get the branch and head hash for the version we are building to ++# allow source tracability ++# ++ ++VERSION= ++if [ -d .git ] ; then ++ HEAD=`git show --pretty=oneline | head -n1 | cut -d' ' -f1 | cut -b1-16` ++ BRANCH=`git branch | grep ^\* | cut -d' ' -f2 | sed s/-hist//g` ++ VERSION=-$PRODUCT\_$BRANCH ++fi ++ ++ ++echo $MKIMAGECMD ++ ++# ++# actually make it ++# ++ ++if make -j$PARALLEL O=$1 ARCH=arm CONFIG_DEBUG_SECTION_MISMATCH=y EXTRAVERSION=$VERSION; then ++ ++ # ++ # if the build is happy, postprocess it by strip and with U-Boot header wrapper ++ # you can get mkimage from U-Boot or Qi build ++ # ++ ++ ${CROSS_COMPILE}objcopy -O binary -R .note -R .comment -S $1/arch/arm/boot/compressed/vmlinux $1/linux.bin ++ mkimage -A arm -O linux -T kernel -C none -a $START -e $START -n "OM $PRODUCT $BRANCH""_$HEAD" -d $1/linux.bin $1/uImage-$PRODUCT.bin ++ ++ # we can see if it is an "moredrivers" build by looking for USB Eth gadget ++ # if it is then keep a stamped copy of last build ++ ++ if [ ! -z "`grep CONFIG_USB_USBNET=y $1/.config`" ] ; then ++ rm -f $1/uImage-moredrivers-$PRODUCT*.bin $1/modules-$PRODUCT*.tar.gz ++ cp $1/uImage-$PRODUCT.bin $1/uImage-moredrivers$VERSION-$HEAD.bin ++ rm -rf $1/staging ++ mkdir -p $1/staging ++ if [ ! -z "$2" ] ; then ++ make O=$1 ARCH=arm modules_install INSTALL_MOD_PATH=staging ++ cd $1/staging ++ tar czf ../modules$VERSION-$HEAD.tar.gz . ++ cd ../.. ++ fi ++ fi ++ exit 0 ++else ++ exit 1 ++fi ++ +diff -ruN --exclude='*.orig' --exclude='*.rej' linux-2.6.29-rc3.owrt/dfu-kern linux-2.6.29-rc3.owrt.om/dfu-kern +--- linux-2.6.29-rc3.owrt/dfu-kern 1970-01-01 01:00:00.000000000 +0100 ++++ linux-2.6.29-rc3.owrt.om/dfu-kern 2009-05-10 22:27:59.000000000 +0200 +@@ -0,0 +1,16 @@ ++#!/bin/bash ++ ++if [ -z "$1" ] ; then ++ echo "Usage: $0 <DEVICE> eg, $0 GTA02" ++ exit 1 ++fi ++ ++NAME=`echo $1 | cut -d'-' -f1` ++ ++../../dfu-util/src/dfu-util -a 3 -d 0x1d50:0x5119 -D $1/uImage-$NAME.bin ++if [ $? -eq 1 ] ; then ++../../dfu-util/src/dfu-util -a 3 -d 0x1d50:0x5120 -D $1/uImage-$NAME.bin ++../../dfu-util/src/dfu-util -a 3 -d 0x1d50:0x5119 -D $1/uImage-$NAME.bin ++fi ++ ++ +diff -ruN --exclude='*.orig' --exclude='*.rej' linux-2.6.29-rc3.owrt/Documentation/arm/Samsung-S3C24XX/Suspend.txt linux-2.6.29-rc3.owrt.om/Documentation/arm/Samsung-S3C24XX/Suspend.txt +--- linux-2.6.29-rc3.owrt/Documentation/arm/Samsung-S3C24XX/Suspend.txt 2009-05-10 22:05:01.000000000 +0200 ++++ linux-2.6.29-rc3.owrt.om/Documentation/arm/Samsung-S3C24XX/Suspend.txt 2009-05-10 22:27:59.000000000 +0200 +@@ -40,13 +40,13 @@ + Machine Support + --------------- + +- The machine specific functions must call the s3c2410_pm_init() function ++ The machine specific functions must call the s3c_pm_init() function + to say that its bootloader is capable of resuming. This can be as + simple as adding the following to the machine's definition: + +- INITMACHINE(s3c2410_pm_init) ++ INITMACHINE(s3c_pm_init) + +- A board can do its own setup before calling s3c2410_pm_init, if it ++ A board can do its own setup before calling s3c_pm_init, if it + needs to setup anything else for power management support. + + There is currently no support for over-riding the default method of +@@ -74,7 +74,7 @@ + + enable_irq_wake(IRQ_EINT0); + +- s3c2410_pm_init(); ++ s3c_pm_init(); + } + + +diff -ruN --exclude='*.orig' --exclude='*.rej' linux-2.6.29-rc3.owrt/drivers/ar6000/ar6000/ar6000_drv.c linux-2.6.29-rc3.owrt.om/drivers/ar6000/ar6000/ar6000_drv.c +--- linux-2.6.29-rc3.owrt/drivers/ar6000/ar6000/ar6000_drv.c 1970-01-01 01:00:00.000000000 +0100 ++++ linux-2.6.29-rc3.owrt.om/drivers/ar6000/ar6000/ar6000_drv.c 2009-05-10 22:27:59.000000000 +0200 +@@ -0,0 +1,3128 @@ ++/* ++ * ++ * Copyright (c) 2004-2007 Atheros Communications Inc. ++ * All rights reserved. ++ * ++ * ++ * 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; ++ * ++ * Software distributed under the License is distributed on an "AS ++ * IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or ++ * implied. See the License for the specific language governing ++ * rights and limitations under the License. ++ * ++ * ++ * ++ */ ++ ++/* ++ * This driver is a pseudo ethernet driver to access the Atheros AR6000 ++ * WLAN Device ++ */ ++static const char athId[] __attribute__ ((unused)) = "$Id: //depot/sw/releases/olca2.0-GPL/host/os/linux/ar6000_drv.c#2 $"; ++ ++#include "ar6000_drv.h" ++#include "htc.h" ++ ++MODULE_LICENSE("GPL and additional rights"); ++ ++#ifndef REORG_APTC_HEURISTICS ++#undef ADAPTIVE_POWER_THROUGHPUT_CONTROL ++#endif /* REORG_APTC_HEURISTICS */ ++ ++#ifdef ADAPTIVE_POWER_THROUGHPUT_CONTROL ++#define APTC_TRAFFIC_SAMPLING_INTERVAL 100 /* msec */ ++#define APTC_UPPER_THROUGHPUT_THRESHOLD 3000 /* Kbps */ ++#define APTC_LOWER_THROUGHPUT_THRESHOLD 2000 /* Kbps */ ++ ++typedef struct aptc_traffic_record { ++ A_BOOL timerScheduled; ++ struct timeval samplingTS; ++ unsigned long bytesReceived; ++ unsigned long bytesTransmitted; ++} APTC_TRAFFIC_RECORD; ++ ++A_TIMER aptcTimer; ++APTC_TRAFFIC_RECORD aptcTR; ++#endif /* ADAPTIVE_POWER_THROUGHPUT_CONTROL */ ++ ++int bmienable = 0; ++unsigned int bypasswmi = 0; ++unsigned int debuglevel = 0; ++int tspecCompliance = 1; ++unsigned int busspeedlow = 0; ++unsigned int onebitmode = 0; ++unsigned int skipflash = 0; ++unsigned int wmitimeout = 2; ++unsigned int wlanNodeCaching = 1; ++unsigned int enableuartprint = 0; ++unsigned int logWmiRawMsgs = 0; ++unsigned int enabletimerwar = 0; ++unsigned int mbox_yield_limit = 99; ++int reduce_credit_dribble = 1 + HTC_CONNECT_FLAGS_THRESHOLD_LEVEL_ONE_HALF; ++int allow_trace_signal = 0; ++#ifdef CONFIG_HOST_TCMD_SUPPORT ++unsigned int testmode =0; ++#endif ++ ++#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,0) ++module_param(bmienable, int, 0644); ++module_param(bypasswmi, int, 0644); ++module_param(debuglevel, int, 0644); ++module_param(tspecCompliance, int, 0644); ++module_param(onebitmode, int, 0644); ++module_param(busspeedlow, int, 0644); ++module_param(skipflash, int, 0644); ++module_param(wmitimeout, int, 0644); ++module_param(wlanNodeCaching, int, 0644); ++module_param(logWmiRawMsgs, int, 0644); ++module_param(enableuartprint, int, 0644); ++module_param(enabletimerwar, int, 0644); ++module_param(mbox_yield_limit, int, 0644); ++module_param(reduce_credit_dribble, int, 0644); ++module_param(allow_trace_signal, int, 0644); ++#ifdef CONFIG_HOST_TCMD_SUPPORT ++module_param(testmode, int, 0644); ++#endif ++#else ++ ++#define __user ++/* for linux 2.4 and lower */ ++MODULE_PARM(bmienable,"i"); ++MODULE_PARM(bypasswmi,"i"); ++MODULE_PARM(debuglevel, "i"); ++MODULE_PARM(onebitmode,"i"); ++MODULE_PARM(busspeedlow, "i"); ++MODULE_PARM(skipflash, "i"); ++MODULE_PARM(wmitimeout, "i"); ++MODULE_PARM(wlanNodeCaching, "i"); ++MODULE_PARM(enableuartprint,"i"); ++MODULE_PARM(logWmiRawMsgs, "i"); ++MODULE_PARM(enabletimerwar,"i"); ++MODULE_PARM(mbox_yield_limit,"i"); ++MODULE_PARM(reduce_credit_dribble,"i"); ++MODULE_PARM(allow_trace_signal,"i"); ++#ifdef CONFIG_HOST_TCMD_SUPPORT ++MODULE_PARM(testmode, "i"); ++#endif ++#endif ++ ++#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,10) ++/* in 2.6.10 and later this is now a pointer to a uint */ ++unsigned int _mboxnum = HTC_MAILBOX_NUM_MAX; ++#define mboxnum &_mboxnum ++#else ++unsigned int mboxnum = HTC_MAILBOX_NUM_MAX; ++#endif ++ ++#ifdef CONFIG_AR6000_WLAN_RESET ++unsigned int resetok = 1; ++#else ++unsigned int resetok = 0; ++#endif ++ ++#ifdef DEBUG ++A_UINT32 g_dbg_flags = DBG_DEFAULTS; ++unsigned int debugflags = 0; ++int debugdriver = 1; ++unsigned int debughtc = 128; ++unsigned int debugbmi = 1; ++unsigned int debughif = 2; ++unsigned int txcreditsavailable[HTC_MAILBOX_NUM_MAX] = {0}; ++unsigned int txcreditsconsumed[HTC_MAILBOX_NUM_MAX] = {0}; ++unsigned int txcreditintrenable[HTC_MAILBOX_NUM_MAX] = {0}; ++unsigned int txcreditintrenableaggregate[HTC_MAILBOX_NUM_MAX] = {0}; ++ ++#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,0) ++module_param(debugflags, int, 0644); ++module_param(debugdriver, int, 0644); ++module_param(debughtc, int, 0644); ++module_param(debugbmi, int, 0644); ++module_param(debughif, int, 0644); ++module_param(resetok, int, 0644); ++module_param_array(txcreditsavailable, int, mboxnum, 0644); ++module_param_array(txcreditsconsumed, int, mboxnum, 0644); ++module_param_array(txcreditintrenable, int, mboxnum, 0644); ++module_param_array(txcreditintrenableaggregate, int, mboxnum, 0644); ++#else ++/* linux 2.4 and lower */ ++MODULE_PARM(debugflags,"i"); ++MODULE_PARM(debugdriver, "i"); ++MODULE_PARM(debughtc, "i"); ++MODULE_PARM(debugbmi, "i"); ++MODULE_PARM(debughif, "i"); ++MODULE_PARM(resetok, "i"); ++MODULE_PARM(txcreditsavailable, "0-3i"); ++MODULE_PARM(txcreditsconsumed, "0-3i"); ++MODULE_PARM(txcreditintrenable, "0-3i"); ++MODULE_PARM(txcreditintrenableaggregate, "0-3i"); ++#endif ++ ++#endif /* DEBUG */ ++ ++unsigned int tx_attempt[HTC_MAILBOX_NUM_MAX] = {0}; ++unsigned int tx_post[HTC_MAILBOX_NUM_MAX] = {0}; ++unsigned int tx_complete[HTC_MAILBOX_NUM_MAX] = {0}; ++unsigned int hifBusRequestNumMax = 40; ++unsigned int war23838_disabled = 0; ++#ifdef ADAPTIVE_POWER_THROUGHPUT_CONTROL ++unsigned int enableAPTCHeuristics = 1; ++#endif /* ADAPTIVE_POWER_THROUGHPUT_CONTROL */ ++#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,0) ++module_param_array(tx_attempt, int, mboxnum, 0644); ++module_param_array(tx_post, int, mboxnum, 0644); ++module_param_array(tx_complete, int, mboxnum, 0644); ++module_param(hifBusRequestNumMax, int, 0644); ++module_param(war23838_disabled, int, 0644); ++#ifdef ADAPTIVE_POWER_THROUGHPUT_CONTROL ++module_param(enableAPTCHeuristics, int, 0644); ++#endif /* ADAPTIVE_POWER_THROUGHPUT_CONTROL */ ++#else ++MODULE_PARM(tx_attempt, "0-3i"); ++MODULE_PARM(tx_post, "0-3i"); ++MODULE_PARM(tx_complete, "0-3i"); ++MODULE_PARM(hifBusRequestNumMax, "i"); ++MODULE_PARM(war23838_disabled, "i"); ++#ifdef ADAPTIVE_POWER_THROUGHPUT_CONTROL ++MODULE_PARM(enableAPTCHeuristics, "i"); ++#endif /* ADAPTIVE_POWER_THROUGHPUT_CONTROL */ ++#endif ++ ++#ifdef BLOCK_TX_PATH_FLAG ++int blocktx = 0; ++#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,0) ++module_param(blocktx, int, 0644); ++#else ++MODULE_PARM(blocktx, "i"); ++#endif ++#endif /* BLOCK_TX_PATH_FLAG */ ++ ++// TODO move to arsoft_c ++USER_RSSI_THOLD rssi_map[12]; ++ ++int reconnect_flag = 0; ++ ++DECLARE_WAIT_QUEUE_HEAD(ar6000_scan_queue); ++ ++/* Function declarations */ ++static int ar6000_init_module(void); ++static void ar6000_cleanup_module(void); ++ ++int ar6000_init(struct net_device *dev); ++static int ar6000_open(struct net_device *dev); ++static int ar6000_close(struct net_device *dev); ++static void ar6000_init_control_info(AR_SOFTC_T *ar); ++static int ar6000_data_tx(struct sk_buff *skb, struct net_device *dev); ++ ++static void ar6000_destroy(struct net_device *dev, unsigned int unregister); ++static void ar6000_detect_error(unsigned long ptr); ++static struct net_device_stats *ar6000_get_stats(struct net_device *dev); ++static struct iw_statistics *ar6000_get_iwstats(struct net_device * dev); ++ ++/* ++ * HTC service connection handlers ++ */ ++static void ar6000_avail_ev(HTC_HANDLE HTCHandle); ++ ++static void ar6000_unavail_ev(void *Instance); ++ ++static void ar6000_target_failure(void *Instance, A_STATUS Status); ++ ++static void ar6000_rx(void *Context, HTC_PACKET *pPacket); ++ ++static void ar6000_rx_refill(void *Context,HTC_ENDPOINT_ID Endpoint); ++ ++static void ar6000_tx_complete(void *Context, HTC_PACKET *pPacket); ++ ++static void ar6000_tx_queue_full(void *Context, HTC_ENDPOINT_ID Endpoint); ++ ++static void ar6000_tx_queue_avail(void *Context, HTC_ENDPOINT_ID Endpoint); ++ ++/* ++ * Static variables ++ */ ++ ++static struct net_device *ar6000_devices[MAX_AR6000]; ++extern struct iw_handler_def ath_iw_handler_def; ++DECLARE_WAIT_QUEUE_HEAD(arEvent); ++static void ar6000_cookie_init(AR_SOFTC_T *ar); ++static void ar6000_cookie_cleanup(AR_SOFTC_T *ar); ++static void ar6000_free_cookie(AR_SOFTC_T *ar, struct ar_cookie * cookie); ++static struct ar_cookie *ar6000_alloc_cookie(AR_SOFTC_T *ar); ++static void ar6000_TxDataCleanup(AR_SOFTC_T *ar); ++ ++#ifdef USER_KEYS ++static A_STATUS ar6000_reinstall_keys(AR_SOFTC_T *ar,A_UINT8 key_op_ctrl); ++#endif ++ ++ ++static struct ar_cookie s_ar_cookie_mem[MAX_COOKIE_NUM]; ++ ++#define HOST_INTEREST_ITEM_ADDRESS(ar, item) \ ++((ar->arTargetType == TARGET_TYPE_AR6001) ? \ ++ AR6001_HOST_INTEREST_ITEM_ADDRESS(item) : \ ++ AR6002_HOST_INTEREST_ITEM_ADDRESS(item)) ++ ++ ++/* Debug log support */ ++ ++/* ++ * Flag to govern whether the debug logs should be parsed in the kernel ++ * or reported to the application. ++ */ ++#ifdef DEBUG ++#define REPORT_DEBUG_LOGS_TO_APP ++#endif ++ ++A_STATUS ++ar6000_set_host_app_area(AR_SOFTC_T *ar) ++{ ++ A_UINT32 address, data; ++ struct host_app_area_s host_app_area; ++ ++ /* Fetch the address of the host_app_area_s instance in the host interest area */ ++ address = HOST_INTEREST_ITEM_ADDRESS(ar, hi_app_host_interest); ++ if (ar6000_ReadRegDiag(ar->arHifDevice, &address, &data) != A_OK) { ++ return A_ERROR; ++ } ++ address = data; ++ host_app_area.wmi_protocol_ver = WMI_PROTOCOL_VERSION; ++ if (ar6000_WriteDataDiag(ar->arHifDevice, address, ++ (A_UCHAR *)&host_app_area, ++ sizeof(struct host_app_area_s)) != A_OK) ++ { ++ return A_ERROR; ++ } ++ ++ return A_OK; ++} ++ ++A_UINT32 ++dbglog_get_debug_hdr_ptr(AR_SOFTC_T *ar) ++{ ++ A_UINT32 param; ++ A_UINT32 address; ++ A_STATUS status; ++ ++ address = HOST_INTEREST_ITEM_ADDRESS(ar, hi_dbglog_hdr); ++ if ((status = ar6000_ReadDataDiag(ar->arHifDevice, address, ++ (A_UCHAR *)¶m, 4)) != A_OK) ++ { ++ param = 0; ++ } ++ ++ return param; ++} ++ ++/* ++ * The dbglog module has been initialized. Its ok to access the relevant ++ * data stuctures over the diagnostic window. ++ */ ++void ++ar6000_dbglog_init_done(AR_SOFTC_T *ar) ++{ ++ ar->dbglog_init_done = TRUE; ++} ++ ++A_UINT32 ++dbglog_get_debug_fragment(A_INT8 *datap, A_UINT32 len, A_UINT32 limit) ++{ ++ A_INT32 *buffer; ++ A_UINT32 count; ++ A_UINT32 numargs; ++ A_UINT32 length; ++ A_UINT32 fraglen; ++ ++ count = fraglen = 0; ++ buffer = (A_INT32 *)datap; ++ length = (limit >> 2); ++ ++ if (len <= limit) { ++ fraglen = len; ++ } else { ++ while (count < length) { ++ numargs = DBGLOG_GET_NUMARGS(buffer[count]); ++ fraglen = (count << 2); ++ count += numargs + 1; ++ } ++ } ++ ++ return fraglen; ++} ++ ++void ++dbglog_parse_debug_logs(A_INT8 *datap, A_UINT32 len) ++{ ++ A_INT32 *buffer; ++ A_UINT32 count; ++ A_UINT32 timestamp; ++ A_UINT32 debugid; ++ A_UINT32 moduleid; ++ A_UINT32 numargs; ++ A_UINT32 length; ++ ++ count = 0; ++ buffer = (A_INT32 *)datap; ++ length = (len >> 2); ++ while (count < length) { ++ debugid = DBGLOG_GET_DBGID(buffer[count]); ++ moduleid = DBGLOG_GET_MODULEID(buffer[count]); ++ numargs = DBGLOG_GET_NUMARGS(buffer[count]); ++ timestamp = DBGLOG_GET_TIMESTAMP(buffer[count]); ++ switch (numargs) { ++ case 0: ++ AR_DEBUG_PRINTF("%d %d (%d)\n", moduleid, debugid, timestamp); ++ break; ++ ++ case 1: ++ AR_DEBUG_PRINTF("%d %d (%d): 0x%x\n", moduleid, debugid, ++ timestamp, buffer[count+1]); ++ break; ++ ++ case 2: ++ AR_DEBUG_PRINTF("%d %d (%d): 0x%x, 0x%x\n", moduleid, debugid, ++ timestamp, buffer[count+1], buffer[count+2]); ++ break; ++ ++ default: ++ AR_DEBUG_PRINTF("Invalid args: %d\n", numargs); ++ } ++ count += numargs + 1; ++ } ++} ++ ++int ++ar6000_dbglog_get_debug_logs(AR_SOFTC_T *ar) ++{ ++ struct dbglog_hdr_s debug_hdr; ++ struct dbglog_buf_s debug_buf; ++ A_UINT32 address; ++ A_UINT32 length; ++ A_UINT32 dropped; ++ A_UINT32 firstbuf; ++ A_UINT32 debug_hdr_ptr; ++ ++ if (!ar->dbglog_init_done) return A_ERROR; ++ ++#ifndef CONFIG_AR6000_WLAN_DEBUG ++ return 0; ++#endif ++ ++ AR6000_SPIN_LOCK(&ar->arLock, 0); ++ ++ if (ar->dbgLogFetchInProgress) { ++ AR6000_SPIN_UNLOCK(&ar->arLock, 0); ++ return A_EBUSY; ++ } ++ ++ /* block out others */ ++ ar->dbgLogFetchInProgress = TRUE; ++ ++ AR6000_SPIN_UNLOCK(&ar->arLock, 0); ++ ++ debug_hdr_ptr = dbglog_get_debug_hdr_ptr(ar); ++ printk("debug_hdr_ptr: 0x%x\n", debug_hdr_ptr); ++ ++ /* Get the contents of the ring buffer */ ++ if (debug_hdr_ptr) { ++ address = debug_hdr_ptr; ++ length = sizeof(struct dbglog_hdr_s); ++ ar6000_ReadDataDiag(ar->arHifDevice, address, ++ (A_UCHAR *)&debug_hdr, length); ++ address = (A_UINT32)debug_hdr.dbuf; ++ firstbuf = address; ++ dropped = debug_hdr.dropped; ++ length = sizeof(struct dbglog_buf_s); ++ ar6000_ReadDataDiag(ar->arHifDevice, address, ++ (A_UCHAR *)&debug_buf, length); ++ ++ do { ++ address = (A_UINT32)debug_buf.buffer; ++ length = debug_buf.length; ++ if ((length) && (debug_buf.length <= debug_buf.bufsize)) { ++ /* Rewind the index if it is about to overrun the buffer */ ++ if (ar->log_cnt > (DBGLOG_HOST_LOG_BUFFER_SIZE - length)) { ++ ar->log_cnt = 0; ++ } ++ if(A_OK != ar6000_ReadDataDiag(ar->arHifDevice, address, ++ (A_UCHAR *)&ar->log_buffer[ar->log_cnt], length)) ++ { ++ break; ++ } ++ ar6000_dbglog_event(ar, dropped, &ar->log_buffer[ar->log_cnt], length); ++ ar->log_cnt += length; ++ } else { ++ AR_DEBUG_PRINTF("Length: %d (Total size: %d)\n", ++ debug_buf.length, debug_buf.bufsize); ++ } ++ ++ address = (A_UINT32)debug_buf.next; ++ length = sizeof(struct dbglog_buf_s); ++ if(A_OK != ar6000_ReadDataDiag(ar->arHifDevice, address, ++ (A_UCHAR *)&debug_buf, length)) ++ { ++ break; ++ } ++ ++ } while (address != firstbuf); ++ } ++ ++ ar->dbgLogFetchInProgress = FALSE; ++ ++ return A_OK; ++} ++ ++void ++ar6000_dbglog_event(AR_SOFTC_T *ar, A_UINT32 dropped, ++ A_INT8 *buffer, A_UINT32 length) ++{ ++#ifdef REPORT_DEBUG_LOGS_TO_APP ++ #define MAX_WIRELESS_EVENT_SIZE 252 ++ /* ++ * Break it up into chunks of MAX_WIRELESS_EVENT_SIZE bytes of messages. ++ * There seems to be a limitation on the length of message that could be ++ * transmitted to the user app via this mechanism. ++ */ ++ A_UINT32 send, sent; ++ ++ sent = 0; ++ send = dbglog_get_debug_fragment(&buffer[sent], length - sent, ++ MAX_WIRELESS_EVENT_SIZE); ++ while (send) { ++ ar6000_send_event_to_app(ar, WMIX_DBGLOG_EVENTID, &buffer[sent], send); ++ sent += send; ++ send = dbglog_get_debug_fragment(&buffer[sent], length - sent, ++ MAX_WIRELESS_EVENT_SIZE); ++ } ++#else ++ AR_DEBUG_PRINTF("Dropped logs: 0x%x\nDebug info length: %d\n", ++ dropped, length); ++ ++ /* Interpret the debug logs */ ++ dbglog_parse_debug_logs(buffer, length); ++#endif /* REPORT_DEBUG_LOGS_TO_APP */ ++} ++ ++ ++ ++static int __init ++ar6000_init_module(void) ++{ ++ static int probed = 0; ++ A_STATUS status; ++ HTC_INIT_INFO initInfo; ++ ++ A_MEMZERO(&initInfo,sizeof(initInfo)); ++ initInfo.AddInstance = ar6000_avail_ev; ++ initInfo.DeleteInstance = ar6000_unavail_ev; ++ initInfo.TargetFailure = ar6000_target_failure; ++ ++ ++#ifdef DEBUG ++ /* Set the debug flags if specified at load time */ ++ if(debugflags != 0) ++ { ++ g_dbg_flags = debugflags; ++ } ++#endif ++ ++ if (probed) { ++ return -ENODEV; ++ } ++ probed++; ++ ++#ifdef ADAPTIVE_POWER_THROUGHPUT_CONTROL ++ memset(&aptcTR, 0, sizeof(APTC_TRAFFIC_RECORD)); ++#endif /* ADAPTIVE_POWER_THROUGHPUT_CONTROL */ ++ ++#ifdef CONFIG_HOST_GPIO_SUPPORT ++ ar6000_gpio_init(); ++#endif /* CONFIG_HOST_GPIO_SUPPORT */ ++ ++ status = HTCInit(&initInfo); ++ if(status != A_OK) ++ return -ENODEV; ++ ++ return 0; ++} ++ ++static void __exit ++ar6000_cleanup_module(void) ++{ ++ int i = 0; ++ struct net_device *ar6000_netdev; ++ ++#ifdef ADAPTIVE_POWER_THROUGHPUT_CONTROL ++ /* Delete the Adaptive Power Control timer */ ++ if (timer_pending(&aptcTimer)) { ++ del_timer_sync(&aptcTimer); ++ } ++#endif /* ADAPTIVE_POWER_THROUGHPUT_CONTROL */ ++ ++ for (i=0; i < MAX_AR6000; i++) { ++ if (ar6000_devices[i] != NULL) { ++ ar6000_netdev = ar6000_devices[i]; ++ ar6000_devices[i] = NULL; ++ ar6000_destroy(ar6000_netdev, 1); ++ } ++ } ++ ++ /* shutting down HTC will cause the HIF layer to detach from the ++ * underlying bus driver which will cause the subsequent deletion of ++ * all HIF and HTC instances */ ++ HTCShutDown(); ++ ++ AR_DEBUG_PRINTF("ar6000_cleanup: success\n"); ++} ++ ++#ifdef ADAPTIVE_POWER_THROUGHPUT_CONTROL ++void ++aptcTimerHandler(unsigned long arg) ++{ ++ A_UINT32 numbytes; ++ A_UINT32 throughput; ++ AR_SOFTC_T *ar; ++ A_STATUS status; ++ ++ ar = (AR_SOFTC_T *)arg; ++ A_ASSERT(ar != NULL); ++ A_ASSERT(!timer_pending(&aptcTimer)); ++ ++ AR6000_SPIN_LOCK(&ar->arLock, 0); ++ ++ /* Get the number of bytes transferred */ ++ numbytes = aptcTR.bytesTransmitted + aptcTR.bytesReceived; ++ aptcTR.bytesTransmitted = aptcTR.bytesReceived = 0; ++ ++ /* Calculate and decide based on throughput thresholds */ ++ throughput = ((numbytes * 8)/APTC_TRAFFIC_SAMPLING_INTERVAL); /* Kbps */ ++ if (throughput < APTC_LOWER_THROUGHPUT_THRESHOLD) { ++ /* Enable Sleep and delete the timer */ ++ A_ASSERT(ar->arWmiReady == TRUE); ++ AR6000_SPIN_UNLOCK(&ar->arLock, 0); ++ status = wmi_powermode_cmd(ar->arWmi, REC_POWER); ++ AR6000_SPIN_LOCK(&ar->arLock, 0); ++ A_ASSERT(status == A_OK); ++ aptcTR.timerScheduled = FALSE; ++ } else { ++ A_TIMEOUT_MS(&aptcTimer, APTC_TRAFFIC_SAMPLING_INTERVAL, 0); ++ } ++ ++ AR6000_SPIN_UNLOCK(&ar->arLock, 0); ++} ++#endif /* ADAPTIVE_POWER_THROUGHPUT_CONTROL */ ++ ++ ++ ++/* set HTC block size, assume BMI is already initialized */ ++A_STATUS ar6000_SetHTCBlockSize(AR_SOFTC_T *ar) ++{ ++ A_STATUS status; ++ A_UINT32 blocksizes[HTC_MAILBOX_NUM_MAX]; ++ ++ do { ++ /* get the block sizes */ ++ status = HIFConfigureDevice(ar->arHifDevice, HIF_DEVICE_GET_MBOX_BLOCK_SIZE, ++ blocksizes, sizeof(blocksizes)); ++ ++ if (A_FAILED(status)) { ++ AR_DEBUG_PRINTF("Failed to get block size info from HIF layer...\n"); ++ break; ++ } ++ /* note: we actually get the block size for mailbox 1, for SDIO the block ++ * size on mailbox 0 is artificially set to 1 */ ++ /* must be a power of 2 */ ++ A_ASSERT((blocksizes[1] & (blocksizes[1] - 1)) == 0); ++ ++ /* set the host interest area for the block size */ ++ status = BMIWriteMemory(ar->arHifDevice, ++ HOST_INTEREST_ITEM_ADDRESS(ar, hi_mbox_io_block_sz), ++ (A_UCHAR *)&blocksizes[1], ++ 4); ++ ++ if (A_FAILED(status)) { ++ AR_DEBUG_PRINTF("BMIWriteMemory for IO block size failed \n"); ++ break; ++ } ++ ++ AR_DEBUG_PRINTF("Block Size Set: %d (target address:0x%X)\n", ++ blocksizes[1], HOST_INTEREST_ITEM_ADDRESS(ar, hi_mbox_io_block_sz)); ++ ++ /* set the host interest area for the mbox ISR yield limit */ ++ status = BMIWriteMemory(ar->arHifDevice, ++ HOST_INTEREST_ITEM_ADDRESS(ar, hi_mbox_isr_yield_limit), ++ (A_UCHAR *)&mbox_yield_limit, ++ 4); ++ ++ if (A_FAILED(status)) { ++ AR_DEBUG_PRINTF("BMIWriteMemory for yield limit failed \n"); ++ break; ++ } ++ ++ } while (FALSE); ++ ++ return status; ++} ++ ++static void free_raw_buffers(AR_SOFTC_T *ar) ++{ ++ int i, j; ++ ++ for (i = 0; i != HTC_RAW_STREAM_NUM_MAX; i++) { ++ for (j = 0; j != RAW_HTC_READ_BUFFERS_NUM; j++) ++ kfree(ar->raw_htc_read_buffer[i][j]); ++ for (j = 0; j != RAW_HTC_WRITE_BUFFERS_NUM; j++) ++ kfree(ar->raw_htc_write_buffer[i][j]); ++ } ++} ++ ++static int alloc_raw_buffers(AR_SOFTC_T *ar) ++{ ++ int i, j; ++ raw_htc_buffer *b; ++ ++ for (i = 0; i != HTC_RAW_STREAM_NUM_MAX; i++) { ++ for (j = 0; j != RAW_HTC_READ_BUFFERS_NUM; j++) { ++ b = kzalloc(sizeof(*b), GFP_KERNEL); ++ if (!b) ++ return -ENOMEM; ++ ar->raw_htc_read_buffer[i][j] = b; ++ } ++ for (j = 0; j != RAW_HTC_WRITE_BUFFERS_NUM; j++) { ++ b = kzalloc(sizeof(*b), GFP_KERNEL); ++ if (!b) ++ return -ENOMEM; ++ ar->raw_htc_write_buffer[i][j] = b; ++ } ++ } ++ return 0; ++} ++ ++/* ++ * HTC Event handlers ++ */ ++static void ++ar6000_avail_ev(HTC_HANDLE HTCHandle) ++{ ++ int i; ++ struct net_device *dev; ++ AR_SOFTC_T *ar; ++ int device_index = 0; ++ ++ AR_DEBUG_PRINTF("ar6000_available\n"); ++ ++ for (i=0; i < MAX_AR6000; i++) { ++ if (ar6000_devices[i] == NULL) { ++ break; ++ } ++ } ++ ++ if (i == MAX_AR6000) { ++ AR_DEBUG_PRINTF("ar6000_available: max devices reached\n"); ++ return; ++ } ++ ++ /* Save this. It gives a bit better readability especially since */ ++ /* we use another local "i" variable below. */ ++ device_index = i; ++ ++ A_ASSERT(HTCHandle != NULL); ++ ++ dev = alloc_etherdev(sizeof(AR_SOFTC_T)); ++ if (dev == NULL) { ++ AR_DEBUG_PRINTF("ar6000_available: can't alloc etherdev\n"); ++ return; ++ } ++ ++ ether_setup(dev); ++ ++ if (netdev_priv(dev) == NULL) { ++ printk(KERN_CRIT "ar6000_available: Could not allocate memory\n"); ++ return; ++ } ++ ++ A_MEMZERO(netdev_priv(dev), sizeof(AR_SOFTC_T)); ++ ++ ar = (AR_SOFTC_T *)netdev_priv(dev); ++ ar->arNetDev = dev; ++ ar->arHtcTarget = HTCHandle; ++ ar->arHifDevice = HTCGetHifDevice(HTCHandle); ++ ar->arWlanState = WLAN_ENABLED; ++ ar->arRadioSwitch = WLAN_ENABLED; ++ ar->arDeviceIndex = device_index; ++ ++ A_INIT_TIMER(&ar->arHBChallengeResp.timer, ar6000_detect_error, dev); ++ ar->arHBChallengeResp.seqNum = 0; ++ ar->arHBChallengeResp.outstanding = FALSE; ++ ar->arHBChallengeResp.missCnt = 0; ++ ar->arHBChallengeResp.frequency = AR6000_HB_CHALLENGE_RESP_FREQ_DEFAULT; ++ ar->arHBChallengeResp.missThres = AR6000_HB_CHALLENGE_RESP_MISS_THRES_DEFAULT; ++ ++ ar6000_init_control_info(ar); ++ init_waitqueue_head(&arEvent); ++ sema_init(&ar->arSem, 1); ++ ++ if (alloc_raw_buffers(ar)) { ++ free_raw_buffers(ar); ++ /* ++ * @@@ Clean up our own mess, but for anything else, cheerfully mimick ++ * the beautiful error non-handling of the rest of this function. ++ */ ++ return; ++ } ++ ++#ifdef ADAPTIVE_POWER_THROUGHPUT_CONTROL ++ A_INIT_TIMER(&aptcTimer, aptcTimerHandler, ar); ++#endif /* ADAPTIVE_POWER_THROUGHPUT_CONTROL */ ++ ++ /* ++ * If requested, perform some magic which requires no cooperation from ++ * the Target. It causes the Target to ignore flash and execute to the ++ * OS from ROM. ++ * ++ * This is intended to support recovery from a corrupted flash on Targets ++ * that support flash. ++ */ ++ if (skipflash) ++ { ++ ar6000_reset_device_skipflash(ar->arHifDevice); ++ } ++ ++ BMIInit(); ++ { ++ struct bmi_target_info targ_info; ++ ++ if (BMIGetTargetInfo(ar->arHifDevice, &targ_info) != A_OK) { ++ return; ++ } ++ ++ ar->arVersion.target_ver = targ_info.target_ver; ++ ar->arTargetType = targ_info.target_type; ++ } ++ ++ if (enableuartprint) { ++ A_UINT32 param; ++ param = 1; ++ if (BMIWriteMemory(ar->arHifDevice, ++ HOST_INTEREST_ITEM_ADDRESS(ar, hi_serial_enable), ++ (A_UCHAR *)¶m, ++ 4)!= A_OK) ++ { ++ AR_DEBUG_PRINTF("BMIWriteMemory for enableuartprint failed \n"); ++ return ; ++ } ++ AR_DEBUG_PRINTF("Serial console prints enabled\n"); ++ } ++#ifdef CONFIG_HOST_TCMD_SUPPORT ++ if(testmode) { ++ ar->arTargetMode = AR6000_TCMD_MODE; ++ }else { ++ ar->arTargetMode = AR6000_WLAN_MODE; ++ } ++#endif ++ if (enabletimerwar) { ++ A_UINT32 param; ++ ++ if (BMIReadMemory(ar->arHifDevice, ++ HOST_INTEREST_ITEM_ADDRESS(ar, hi_option_flag), ++ (A_UCHAR *)¶m, ++ 4)!= A_OK) ++ { ++ AR_DEBUG_PRINTF("BMIReadMemory for enabletimerwar failed \n"); ++ return; ++ } ++ ++ param |= HI_OPTION_TIMER_WAR; ++ ++ if (BMIWriteMemory(ar->arHifDevice, ++ HOST_INTEREST_ITEM_ADDRESS(ar, hi_option_flag), ++ (A_UCHAR *)¶m, ++ 4) != A_OK) ++ { ++ AR_DEBUG_PRINTF("BMIWriteMemory for enabletimerwar failed \n"); ++ return; ++ } ++ AR_DEBUG_PRINTF("Timer WAR enabled\n"); ++ } ++ ++ ++ /* since BMIInit is called in the driver layer, we have to set the block ++ * size here for the target */ ++ ++ if (A_FAILED(ar6000_SetHTCBlockSize(ar))) { ++ return; ++ } ++ ++ spin_lock_init(&ar->arLock); ++ ++ /* Don't install the init function if BMI is requested */ ++ if(!bmienable) ++ { ++ dev->init = ar6000_init; ++ } else { ++ AR_DEBUG_PRINTF(" BMI enabled \n"); ++ } ++ ++ dev->open = &ar6000_open; ++ dev->stop = &ar6000_close; ++ dev->hard_start_xmit = &ar6000_data_tx; ++ dev->get_stats = &ar6000_get_stats; ++ ++ /* dev->tx_timeout = ar6000_tx_timeout; */ ++ dev->do_ioctl = &ar6000_ioctl; ++ dev->watchdog_timeo = AR6000_TX_TIMEOUT; ++ ar6000_ioctl_iwsetup(&ath_iw_handler_def); ++ dev->wireless_handlers = &ath_iw_handler_def; ++ ath_iw_handler_def.get_wireless_stats = ar6000_get_iwstats; /*Displayed via proc fs */ ++ ++ /* ++ * We need the OS to provide us with more headroom in order to ++ * perform dix to 802.3, WMI header encap, and the HTC header ++ */ ++ dev->hard_header_len = ETH_HLEN + sizeof(ATH_LLC_SNAP_HDR) + ++ sizeof(WMI_DATA_HDR) + HTC_HEADER_LEN; ++ ++ /* This runs the init function */ ++ SET_NETDEV_DEV(dev, HIFGetOSDevice(ar->arHifDevice)); ++ if (register_netdev(dev)) { ++ AR_DEBUG_PRINTF("ar6000_avail: register_netdev failed\n"); ++ ar6000_destroy(dev, 0); ++ return; ++ } ++ ++ HTCSetInstance(ar->arHtcTarget, ar); ++ ++ /* We only register the device in the global list if we succeed. */ ++ /* If the device is in the global list, it will be destroyed */ ++ /* when the module is unloaded. */ ++ ar6000_devices[device_index] = dev; ++ ++ AR_DEBUG_PRINTF("ar6000_avail: name=%s htcTarget=0x%x, dev=0x%x (%d), ar=0x%x\n", ++ dev->name, (A_UINT32)HTCHandle, (A_UINT32)dev, device_index, ++ (A_UINT32)ar); ++} ++ ++static void ar6000_target_failure(void *Instance, A_STATUS Status) ++{ ++ AR_SOFTC_T *ar = (AR_SOFTC_T *)Instance; ++ WMI_TARGET_ERROR_REPORT_EVENT errEvent; ++ static A_BOOL sip = FALSE; ++ ++ if (Status != A_OK) { ++ if (timer_pending(&ar->arHBChallengeResp.timer)) { ++ A_UNTIMEOUT(&ar->arHBChallengeResp.timer); ++ } ++ ++ /* try dumping target assertion information (if any) */ ++ ar6000_dump_target_assert_info(ar->arHifDevice,ar->arTargetType); ++ ++ /* ++ * Fetch the logs from the target via the diagnostic ++ * window. ++ */ ++ ar6000_dbglog_get_debug_logs(ar); ++ ++ /* Report the error only once */ ++ if (!sip) { ++ sip = TRUE; ++ errEvent.errorVal = WMI_TARGET_COM_ERR | ++ WMI_TARGET_FATAL_ERR; ++#ifdef SEND_EVENT_TO_APP ++ ar6000_send_event_to_app(ar, WMI_ERROR_REPORT_EVENTID, ++ (A_UINT8 *)&errEvent, ++ sizeof(WMI_TARGET_ERROR_REPORT_EVENT)); ++#endif ++ } ++ } ++} ++ ++static void ++ar6000_unavail_ev(void *Instance) ++{ ++ AR_SOFTC_T *ar = (AR_SOFTC_T *)Instance; ++ /* NULL out it's entry in the global list */ ++ ar6000_devices[ar->arDeviceIndex] = NULL; ++ ar6000_destroy(ar->arNetDev, 1); ++} ++ ++/* ++ * We need to differentiate between the surprise and planned removal of the ++ * device because of the following consideration: ++ * - In case of surprise removal, the hcd already frees up the pending ++ * for the device and hence there is no need to unregister the function ++ * driver inorder to get these requests. For planned removal, the function ++ * driver has to explictly unregister itself to have the hcd return all the ++ * pending requests before the data structures for the devices are freed up. ++ * Note that as per the current implementation, the function driver will ++ * end up releasing all the devices since there is no API to selectively ++ * release a particular device. ++ * - Certain commands issued to the target can be skipped for surprise ++ * removal since they will anyway not go through. ++ */ ++static void ++ar6000_destroy(struct net_device *dev, unsigned int unregister) ++{ ++ AR_SOFTC_T *ar; ++ ++ AR_DEBUG_PRINTF("+ar6000_destroy \n"); ++ ++ if((dev == NULL) || ((ar = netdev_priv(dev)) == NULL)) ++ { ++ AR_DEBUG_PRINTF("%s(): Failed to get device structure.\n", __func__); ++ return; ++ } ++ ++ /* Clear the tx counters */ ++ memset(tx_attempt, 0, sizeof(tx_attempt)); ++ memset(tx_post, 0, sizeof(tx_post)); ++ memset(tx_complete, 0, sizeof(tx_complete)); ++ ++ /* Free up the device data structure */ ++ if (unregister) { ++ unregister_netdev(dev); ++ } else { ++ ar6000_close(dev); ++ } ++ ++ free_raw_buffers(ar); ++ ++#ifndef free_netdev ++ kfree(dev); ++#else ++ free_netdev(dev); ++#endif ++ ++ AR_DEBUG_PRINTF("-ar6000_destroy \n"); ++} ++ ++static void ar6000_detect_error(unsigned long ptr) ++{ ++ struct net_device *dev = (struct net_device *)ptr; ++ AR_SOFTC_T *ar = (AR_SOFTC_T *)netdev_priv(dev); ++ WMI_TARGET_ERROR_REPORT_EVENT errEvent; ++ ++ AR6000_SPIN_LOCK(&ar->arLock, 0); ++ ++ if (ar->arHBChallengeResp.outstanding) { ++ ar->arHBChallengeResp.missCnt++; ++ } else { ++ ar->arHBChallengeResp.missCnt = 0; ++ } ++ ++ if (ar->arHBChallengeResp.missCnt > ar->arHBChallengeResp.missThres) { ++ /* Send Error Detect event to the application layer and do not reschedule the error detection module timer */ ++ ar->arHBChallengeResp.missCnt = 0; ++ ar->arHBChallengeResp.seqNum = 0; ++ errEvent.errorVal = WMI_TARGET_COM_ERR | WMI_TARGET_FATAL_ERR; ++ AR6000_SPIN_UNLOCK(&ar->arLock, 0); ++#ifdef SEND_EVENT_TO_APP ++ ar6000_send_event_to_app(ar, WMI_ERROR_REPORT_EVENTID, ++ (A_UINT8 *)&errEvent, ++ sizeof(WMI_TARGET_ERROR_REPORT_EVENT)); ++#endif ++ return; ++ } ++ ++ /* Generate the sequence number for the next challenge */ ++ ar->arHBChallengeResp.seqNum++; ++ ar->arHBChallengeResp.outstanding = TRUE; ++ ++ AR6000_SPIN_UNLOCK(&ar->arLock, 0); ++ ++ /* Send the challenge on the control channel */ ++ if (wmi_get_challenge_resp_cmd(ar->arWmi, ar->arHBChallengeResp.seqNum, DRV_HB_CHALLENGE) != A_OK) { ++ AR_DEBUG_PRINTF("Unable to send heart beat challenge\n"); ++ } ++ ++ ++ /* Reschedule the timer for the next challenge */ ++ A_TIMEOUT_MS(&ar->arHBChallengeResp.timer, ar->arHBChallengeResp.frequency * 1000, 0); ++} ++ ++void ar6000_init_profile_info(AR_SOFTC_T *ar) ++{ ++ ar->arSsidLen = 0; ++ A_MEMZERO(ar->arSsid, sizeof(ar->arSsid)); ++ ar->arNetworkType = INFRA_NETWORK; ++ ar->arDot11AuthMode = OPEN_AUTH; ++ ar->arAuthMode = NONE_AUTH; ++ ar->arPairwiseCrypto = NONE_CRYPT; ++ ar->arPairwiseCryptoLen = 0; ++ ar->arGroupCrypto = NONE_CRYPT; ++ ar->arGroupCryptoLen = 0; ++ A_MEMZERO(ar->arWepKeyList, sizeof(ar->arWepKeyList)); ++ A_MEMZERO(ar->arReqBssid, sizeof(ar->arReqBssid)); ++ A_MEMZERO(ar->arBssid, sizeof(ar->arBssid)); ++ ar->arBssChannel = 0; ++} ++ ++static void ++ar6000_init_control_info(AR_SOFTC_T *ar) ++{ ++ ar->arWmiEnabled = FALSE; ++ ar6000_init_profile_info(ar); ++ ar->arDefTxKeyIndex = 0; ++ A_MEMZERO(ar->arWepKeyList, sizeof(ar->arWepKeyList)); ++ ar->arChannelHint = 0; ++ ar->arListenInterval = MAX_LISTEN_INTERVAL; ++ ar->arVersion.host_ver = AR6K_SW_VERSION; ++ ar->arRssi = 0; ++ ar->arTxPwr = 0; ++ ar->arTxPwrSet = FALSE; ++ ar->arSkipScan = 0; ++ ar->arBeaconInterval = 0; ++ ar->arBitRate = 0; ++ ar->arMaxRetries = 0; ++ ar->arWmmEnabled = TRUE; ++} ++ ++static int ++ar6000_open(struct net_device *dev) ++{ ++ /* Wake up the queues */ ++ netif_start_queue(dev); ++ ++ return 0; ++} ++ ++static int ++ar6000_close(struct net_device *dev) ++{ ++ AR_SOFTC_T *ar = netdev_priv(dev); ++ ++ /* Stop the transmit queues */ ++ netif_stop_queue(dev); ++ ++ /* Disable the target and the interrupts associated with it */ ++ if (ar->arWmiReady == TRUE) ++ { ++ if (!bypasswmi) ++ { ++ if (ar->arConnected == TRUE || ar->arConnectPending == TRUE) ++ { ++ AR_DEBUG_PRINTF("%s(): Disconnect\n", __func__); ++ AR6000_SPIN_LOCK(&ar->arLock, 0); ++ ar6000_init_profile_info(ar); ++ AR6000_SPIN_UNLOCK(&ar->arLock, 0); ++ wmi_disconnect_cmd(ar->arWmi); ++ } ++ ++ ar6000_dbglog_get_debug_logs(ar); ++ ar->arWmiReady = FALSE; ++ ar->arConnected = FALSE; ++ ar->arConnectPending = FALSE; ++ wmi_shutdown(ar->arWmi); ++ ar->arWmiEnabled = FALSE; ++ ar->arWmi = NULL; ++ ar->arWlanState = WLAN_ENABLED; ++#ifdef USER_KEYS ++ ar->user_savedkeys_stat = USER_SAVEDKEYS_STAT_INIT; ++ ar->user_key_ctrl = 0; ++#endif ++ } ++ ++ AR_DEBUG_PRINTF("%s(): WMI stopped\n", __func__); ++ } ++ else ++ { ++ AR_DEBUG_PRINTF("%s(): WMI not ready 0x%08x 0x%08x\n", ++ __func__, (unsigned int) ar, (unsigned int) ar->arWmi); ++ ++ /* Shut down WMI if we have started it */ ++ if(ar->arWmiEnabled == TRUE) ++ { ++ AR_DEBUG_PRINTF("%s(): Shut down WMI\n", __func__); ++ wmi_shutdown(ar->arWmi); ++ ar->arWmiEnabled = FALSE; ++ ar->arWmi = NULL; ++ } ++ } ++ ++ /* stop HTC */ ++ HTCStop(ar->arHtcTarget); ++ ++ /* set the instance to NULL so we do not get called back on remove incase we ++ * we're explicity destroyed by module unload */ ++ HTCSetInstance(ar->arHtcTarget, NULL); ++ ++ if (resetok) { ++ /* try to reset the device if we can ++ * The driver may have been configure NOT to reset the target during ++ * a debug session */ ++ AR_DEBUG_PRINTF(" Attempting to reset target on instance destroy.... \n"); ++ ar6000_reset_device(ar->arHifDevice, ar->arTargetType); ++ } else { ++ AR_DEBUG_PRINTF(" Host does not want target reset. \n"); ++ } ++ ++ /* Done with cookies */ ++ ar6000_cookie_cleanup(ar); ++ ++ /* Cleanup BMI */ ++ BMIInit(); ++ ++ return 0; ++} ++ ++/* connect to a service */ ++static A_STATUS ar6000_connectservice(AR_SOFTC_T *ar, ++ HTC_SERVICE_CONNECT_REQ *pConnect, ++ WMI_PRI_STREAM_ID WmiStreamID, ++ char *pDesc) ++{ ++ A_STATUS status; ++ HTC_SERVICE_CONNECT_RESP response; ++ ++ do { ++ ++ A_MEMZERO(&response,sizeof(response)); ++ ++ status = HTCConnectService(ar->arHtcTarget, ++ pConnect, ++ &response); ++ ++ if (A_FAILED(status)) { ++ AR_DEBUG_PRINTF(" Failed to connect to %s service status:%d \n", pDesc, status); ++ break; ++ } ++ ++ if (WmiStreamID == WMI_NOT_MAPPED) { ++ /* done */ ++ break; ++ } ++ ++ /* set endpoint mapping for the WMI stream in the driver layer */ ++ arSetWMIStream2EndpointIDMap(ar,WmiStreamID,response.Endpoint); ++ ++ } while (FALSE); ++ ++ return status; ++} ++ ++static void ar6000_TxDataCleanup(AR_SOFTC_T *ar) ++{ ++ /* flush all the data (non-control) streams ++ * we only flush packets that are tagged as data, we leave any control packets that ++ * were in the TX queues alone */ ++ HTCFlushEndpoint(ar->arHtcTarget, ++ arWMIStream2EndpointID(ar,WMI_BEST_EFFORT_PRI), ++ AR6K_DATA_PKT_TAG); ++ HTCFlushEndpoint(ar->arHtcTarget, ++ arWMIStream2EndpointID(ar,WMI_LOW_PRI), ++ AR6K_DATA_PKT_TAG); ++ HTCFlushEndpoint(ar->arHtcTarget, ++ arWMIStream2EndpointID(ar,WMI_HIGH_PRI), ++ AR6K_DATA_PKT_TAG); ++ HTCFlushEndpoint(ar->arHtcTarget, ++ arWMIStream2EndpointID(ar,WMI_HIGHEST_PRI), ++ AR6K_DATA_PKT_TAG); ++} ++ ++/* This function does one time initialization for the lifetime of the device */ ++int ar6000_init(struct net_device *dev) ++{ ++ AR_SOFTC_T *ar; ++ A_STATUS status; ++ A_INT32 timeleft; ++ ++ if((ar = netdev_priv(dev)) == NULL) ++ { ++ return(-EIO); ++ } ++ ++ /* Do we need to finish the BMI phase */ ++ if(BMIDone(ar->arHifDevice) != A_OK) ++ { ++ return -EIO; ++ } ++ ++ if (!bypasswmi) ++ { ++#if 0 /* TBDXXX */ ++ if (ar->arVersion.host_ver != ar->arVersion.target_ver) { ++ A_PRINTF("WARNING: Host version 0x%x does not match Target " ++ " version 0x%x!\n", ++ ar->arVersion.host_ver, ar->arVersion.target_ver); ++ } ++#endif ++ ++ /* Indicate that WMI is enabled (although not ready yet) */ ++ ar->arWmiEnabled = TRUE; ++ if ((ar->arWmi = wmi_init((void *) ar)) == NULL) ++ { ++ AR_DEBUG_PRINTF("%s() Failed to initialize WMI.\n", __func__); ++ return(-EIO); ++ } ++ ++ AR_DEBUG_PRINTF("%s() Got WMI @ 0x%08x.\n", __func__, ++ (unsigned int) ar->arWmi); ++ } ++ ++ do { ++ HTC_SERVICE_CONNECT_REQ connect; ++ ++ /* the reason we have to wait for the target here is that the driver layer ++ * has to init BMI in order to set the host block size, ++ */ ++ status = HTCWaitTarget(ar->arHtcTarget); ++ ++ if (A_FAILED(status)) { ++ break; ++ } ++ ++ A_MEMZERO(&connect,sizeof(connect)); ++ /* meta data is unused for now */ ++ connect.pMetaData = NULL; ++ connect.MetaDataLength = 0; ++ /* these fields are the same for all service endpoints */ ++ connect.EpCallbacks.pContext = ar; ++ connect.EpCallbacks.EpTxComplete = ar6000_tx_complete; ++ connect.EpCallbacks.EpRecv = ar6000_rx; ++ connect.EpCallbacks.EpRecvRefill = ar6000_rx_refill; ++ connect.EpCallbacks.EpSendFull = ar6000_tx_queue_full; ++ connect.EpCallbacks.EpSendAvail = ar6000_tx_queue_avail; ++ /* set the max queue depth so that our ar6000_tx_queue_full handler gets called. ++ * Linux has the peculiarity of not providing flow control between the ++ * NIC and the network stack. There is no API to indicate that a TX packet ++ * was sent which could provide some back pressure to the network stack. ++ * Under linux you would have to wait till the network stack consumed all sk_buffs ++ * before any back-flow kicked in. Which isn't very friendly. ++ * So we have to manage this ourselves */ ++ connect.MaxSendQueueDepth = 32; ++ ++ /* connect to control service */ ++ connect.ServiceID = WMI_CONTROL_SVC; ++ status = ar6000_connectservice(ar, ++ &connect, ++ WMI_CONTROL_PRI, ++ "WMI CONTROL"); ++ if (A_FAILED(status)) { ++ break; ++ } ++ ++ /* for the remaining data services set the connection flag to reduce dribbling, ++ * if configured to do so */ ++ if (reduce_credit_dribble) { ++ connect.ConnectionFlags |= HTC_CONNECT_FLAGS_REDUCE_CREDIT_DRIBBLE; ++ /* the credit dribble trigger threshold is (reduce_credit_dribble - 1) for a value ++ * of 0-3 */ ++ connect.ConnectionFlags &= ~HTC_CONNECT_FLAGS_THRESHOLD_LEVEL_MASK; ++ connect.ConnectionFlags |= ++ ((A_UINT16)reduce_credit_dribble - 1) & HTC_CONNECT_FLAGS_THRESHOLD_LEVEL_MASK; ++ } ++ /* connect to best-effort service */ ++ connect.ServiceID = WMI_DATA_BE_SVC; ++ ++ status = ar6000_connectservice(ar, ++ &connect, ++ WMI_BEST_EFFORT_PRI, ++ "WMI DATA BE"); ++ if (A_FAILED(status)) { ++ break; ++ } ++ ++ /* connect to back-ground ++ * map this to WMI LOW_PRI */ ++ connect.ServiceID = WMI_DATA_BK_SVC; ++ status = ar6000_connectservice(ar, ++ &connect, ++ WMI_LOW_PRI, ++ "WMI DATA BK"); ++ if (A_FAILED(status)) { ++ break; ++ } ++ ++ /* connect to Video service, map this to ++ * to HI PRI */ ++ connect.ServiceID = WMI_DATA_VI_SVC; ++ status = ar6000_connectservice(ar, ++ &connect, ++ WMI_HIGH_PRI, ++ "WMI DATA VI"); ++ if (A_FAILED(status)) { ++ break; ++ } ++ ++ /* connect to VO service, this is currently not ++ * mapped to a WMI priority stream due to historical reasons. ++ * WMI originally defined 3 priorities over 3 mailboxes ++ * We can change this when WMI is reworked so that priorities are not ++ * dependent on mailboxes */ ++ connect.ServiceID = WMI_DATA_VO_SVC; ++ status = ar6000_connectservice(ar, ++ &connect, ++ WMI_HIGHEST_PRI, ++ "WMI DATA VO"); ++ if (A_FAILED(status)) { ++ break; ++ } ++ ++ A_ASSERT(arWMIStream2EndpointID(ar,WMI_CONTROL_PRI) != 0); ++ A_ASSERT(arWMIStream2EndpointID(ar,WMI_BEST_EFFORT_PRI) != 0); ++ A_ASSERT(arWMIStream2EndpointID(ar,WMI_LOW_PRI) != 0); ++ A_ASSERT(arWMIStream2EndpointID(ar,WMI_HIGH_PRI) != 0); ++ A_ASSERT(arWMIStream2EndpointID(ar,WMI_HIGHEST_PRI) != 0); ++ } while (FALSE); ++ ++ if (A_FAILED(status)) { ++ return (-EIO); ++ } ++ ++ /* ++ * give our connected endpoints some buffers ++ */ ++ ar6000_rx_refill(ar, arWMIStream2EndpointID(ar,WMI_CONTROL_PRI)); ++ ++ ar6000_rx_refill(ar, arWMIStream2EndpointID(ar,WMI_BEST_EFFORT_PRI)); ++ ++ /* ++ * We will post the receive buffers only for SPE testing and so we are ++ * making it conditional on the 'bypasswmi' flag. ++ */ ++ if (bypasswmi) { ++ ar6000_rx_refill(ar,arWMIStream2EndpointID(ar,WMI_LOW_PRI)); ++ ar6000_rx_refill(ar,arWMIStream2EndpointID(ar,WMI_HIGH_PRI)); ++ } ++ ++ /* setup credit distribution */ ++ ar6000_setup_credit_dist(ar->arHtcTarget, &ar->arCreditStateInfo); ++ ++ /* Since cookies are used for HTC transports, they should be */ ++ /* initialized prior to enabling HTC. */ ++ ar6000_cookie_init(ar); ++ ++ /* start HTC */ ++ status = HTCStart(ar->arHtcTarget); ++ ++ if (status != A_OK) { ++ if (ar->arWmiEnabled == TRUE) { ++ wmi_shutdown(ar->arWmi); ++ ar->arWmiEnabled = FALSE; ++ ar->arWmi = NULL; ++ } ++ ar6000_cookie_cleanup(ar); ++ return -EIO; ++ } ++ ++ if (!bypasswmi) { ++ /* Wait for Wmi event to be ready */ ++ timeleft = wait_event_interruptible_timeout(arEvent, ++ (ar->arWmiReady == TRUE), wmitimeout * HZ); ++ ++ if(!timeleft || signal_pending(current)) ++ { ++ AR_DEBUG_PRINTF("WMI is not ready or wait was interrupted\n"); ++#if defined(DWSIM) /* TBDXXX */ ++ AR_DEBUG_PRINTF(".....but proceed anyway.\n"); ++#else ++ return -EIO; ++#endif ++ } ++ ++ AR_DEBUG_PRINTF("%s() WMI is ready\n", __func__); ++ ++ /* Communicate the wmi protocol verision to the target */ ++ if ((ar6000_set_host_app_area(ar)) != A_OK) { ++ AR_DEBUG_PRINTF("Unable to set the host app area\n"); ++ } ++ } ++ ++ ar->arNumDataEndPts = 1; ++ ++ return(0); ++} ++ ++ ++void ++ar6000_bitrate_rx(void *devt, A_INT32 rateKbps) ++{ ++ AR_SOFTC_T *ar = (AR_SOFTC_T *)devt; ++ ++ ar->arBitRate = rateKbps; ++ wake_up(&arEvent); ++} ++ ++void ++ar6000_ratemask_rx(void *devt, A_UINT16 ratemask) ++{ ++ AR_SOFTC_T *ar = (AR_SOFTC_T *)devt; ++ ++ ar->arRateMask = ratemask; ++ wake_up(&arEvent); ++} ++ ++void ++ar6000_txPwr_rx(void *devt, A_UINT8 txPwr) ++{ ++ AR_SOFTC_T *ar = (AR_SOFTC_T *)devt; ++ ++ ar->arTxPwr = txPwr; ++ wake_up(&arEvent); ++} ++ ++ ++void ++ar6000_channelList_rx(void *devt, A_INT8 numChan, A_UINT16 *chanList) ++{ ++ AR_SOFTC_T *ar = (AR_SOFTC_T *)devt; ++ ++ A_MEMCPY(ar->arChannelList, chanList, numChan * sizeof (A_UINT16)); ++ ar->arNumChannels = numChan; ++ ++ wake_up(&arEvent); ++} ++ ++A_UINT8 ++ar6000_ibss_map_epid(struct sk_buff *skb, struct net_device *dev, A_UINT32 * mapNo) ++{ ++ AR_SOFTC_T *ar = (AR_SOFTC_T *)netdev_priv(dev); ++ A_UINT8 *datap; ++ ATH_MAC_HDR *macHdr; ++ A_UINT32 i, eptMap; ++ ++ (*mapNo) = 0; ++ datap = A_NETBUF_DATA(skb); ++ macHdr = (ATH_MAC_HDR *)(datap + sizeof(WMI_DATA_HDR)); ++ if (IEEE80211_IS_MULTICAST(macHdr->dstMac)) { ++ return ENDPOINT_2; ++ } ++ ++ eptMap = -1; ++ for (i = 0; i < ar->arNodeNum; i ++) { ++ if (IEEE80211_ADDR_EQ(macHdr->dstMac, ar->arNodeMap[i].macAddress)) { ++ (*mapNo) = i + 1; ++ ar->arNodeMap[i].txPending ++; ++ return ar->arNodeMap[i].epId; ++ } ++ ++ if ((eptMap == -1) && !ar->arNodeMap[i].txPending) { ++ eptMap = i; ++ } ++ } ++ ++ if (eptMap == -1) { ++ eptMap = ar->arNodeNum; ++ ar->arNodeNum ++; ++ A_ASSERT(ar->arNodeNum <= MAX_NODE_NUM); ++ } ++ ++ A_MEMCPY(ar->arNodeMap[eptMap].macAddress, macHdr->dstMac, IEEE80211_ADDR_LEN); ++ ++ for (i = ENDPOINT_2; i <= ENDPOINT_5; i ++) { ++ if (!ar->arTxPending[i]) { ++ ar->arNodeMap[eptMap].epId = i; ++ break; ++ } ++ // No free endpoint is available, start redistribution on the inuse endpoints. ++ if (i == ENDPOINT_5) { ++ ar->arNodeMap[eptMap].epId = ar->arNexEpId; ++ ar->arNexEpId ++; ++ if (ar->arNexEpId > ENDPOINT_5) { ++ ar->arNexEpId = ENDPOINT_2; ++ } ++ } ++ } ++ ++ (*mapNo) = eptMap + 1; ++ ar->arNodeMap[eptMap].txPending ++; ++ ++ return ar->arNodeMap[eptMap].epId; ++} ++ ++#ifdef DEBUG ++static void ar6000_dump_skb(struct sk_buff *skb) ++{ ++ u_char *ch; ++ for (ch = A_NETBUF_DATA(skb); ++ (A_UINT32)ch < ((A_UINT32)A_NETBUF_DATA(skb) + ++ A_NETBUF_LEN(skb)); ch++) ++ { ++ AR_DEBUG_PRINTF("%2.2x ", *ch); ++ } ++ AR_DEBUG_PRINTF("\n"); ++} ++#endif ++ ++static int ++ar6000_data_tx(struct sk_buff *skb, struct net_device *dev) ++{ ++ AR_SOFTC_T *ar = (AR_SOFTC_T *)netdev_priv(dev); ++ WMI_PRI_STREAM_ID streamID = WMI_NOT_MAPPED; ++ A_UINT32 mapNo = 0; ++ int len; ++ struct ar_cookie *cookie; ++ A_BOOL checkAdHocPsMapping = FALSE; ++ ++#if LINUX_VERSION_CODE <= KERNEL_VERSION(2,6,13) ++ skb->list = NULL; ++#endif ++ ++ AR_DEBUG2_PRINTF("ar6000_data_tx start - skb=0x%x, data=0x%x, len=0x%x\n", ++ (A_UINT32)skb, (A_UINT32)A_NETBUF_DATA(skb), ++ A_NETBUF_LEN(skb)); ++#ifdef CONFIG_HOST_TCMD_SUPPORT ++ /* TCMD doesnt support any data, free the buf and return */ ++ if(ar->arTargetMode == AR6000_TCMD_MODE) { ++ A_NETBUF_FREE(skb); ++ return 0; ++ } ++#endif ++ do { ++ ++ if (ar->arWmiReady == FALSE && bypasswmi == 0) { ++ break; ++ } ++ ++#ifdef BLOCK_TX_PATH_FLAG ++ if (blocktx) { ++ break; ++ } ++#endif /* BLOCK_TX_PATH_FLAG */ ++ ++ if (ar->arWmiEnabled) { ++ if (A_NETBUF_HEADROOM(skb) < dev->hard_header_len) { ++ struct sk_buff *newbuf; ++ /* ++ * We really should have gotten enough headroom but sometimes ++ * we still get packets with not enough headroom. Copy the packet. ++ */ ++ len = A_NETBUF_LEN(skb); ++ newbuf = A_NETBUF_ALLOC(len); ++ if (newbuf == NULL) { ++ break; ++ } ++ A_NETBUF_PUT(newbuf, len); ++ A_MEMCPY(A_NETBUF_DATA(newbuf), A_NETBUF_DATA(skb), len); ++ A_NETBUF_FREE(skb); ++ skb = newbuf; ++ /* fall through and assemble header */ ++ } ++ ++ if (wmi_dix_2_dot3(ar->arWmi, skb) != A_OK) { ++ AR_DEBUG_PRINTF("ar6000_data_tx - wmi_dix_2_dot3 failed\n"); ++ break; ++ } ++ ++ if (wmi_data_hdr_add(ar->arWmi, skb, DATA_MSGTYPE) != A_OK) { ++ AR_DEBUG_PRINTF("ar6000_data_tx - wmi_data_hdr_add failed\n"); ++ break; ++ } ++ ++ if ((ar->arNetworkType == ADHOC_NETWORK) && ++ ar->arIbssPsEnable && ar->arConnected) { ++ /* flag to check adhoc mapping once we take the lock below: */ ++ checkAdHocPsMapping = TRUE; ++ ++ } else { ++ /* get the stream mapping */ ++ if (ar->arWmmEnabled) { ++ streamID = wmi_get_stream_id(ar->arWmi, ++ wmi_implicit_create_pstream(ar->arWmi, skb, UPLINK_TRAFFIC, UNDEFINED_PRI)); ++ } else { ++ streamID = WMI_BEST_EFFORT_PRI; ++ } ++ } ++ ++ } else { ++ struct iphdr *ipHdr; ++ /* ++ * the endpoint is directly based on the TOS field in the IP ++ * header **** only for testing ****** ++ */ ++ ipHdr = A_NETBUF_DATA(skb) + sizeof(ATH_MAC_HDR); ++ /* here we map the TOS field to an endpoint number, this is for ++ * the endpointping test application */ ++ streamID = IP_TOS_TO_WMI_PRI(ipHdr->tos); ++ } ++ ++ } while (FALSE); ++ ++ /* did we succeed ? */ ++ if ((streamID == WMI_NOT_MAPPED) && !checkAdHocPsMapping) { ++ /* cleanup and exit */ ++ A_NETBUF_FREE(skb); ++ AR6000_STAT_INC(ar, tx_dropped); ++ AR6000_STAT_INC(ar, tx_aborted_errors); ++ return 0; ++ } ++ ++ cookie = NULL; ++ ++ /* take the lock to protect driver data */ ++ AR6000_SPIN_LOCK(&ar->arLock, 0); ++ ++ do { ++ ++ if (checkAdHocPsMapping) { ++ streamID = ar6000_ibss_map_epid(skb, dev, &mapNo); ++ } ++ ++ A_ASSERT(streamID != WMI_NOT_MAPPED); ++ ++ /* validate that the endpoint is connected */ ++ if (arWMIStream2EndpointID(ar,streamID) == 0) { ++ AR_DEBUG_PRINTF("Stream %d is NOT mapped!\n",streamID); ++ break; ++ } ++ /* allocate resource for this packet */ ++ cookie = ar6000_alloc_cookie(ar); ++ ++ if (cookie != NULL) { ++ /* update counts while the lock is held */ ++ ar->arTxPending[streamID]++; ++ ar->arTotalTxDataPending++; ++ } ++ ++ } while (FALSE); ++ ++ AR6000_SPIN_UNLOCK(&ar->arLock, 0); ++ ++ if (cookie != NULL) { ++ cookie->arc_bp[0] = (A_UINT32)skb; ++ cookie->arc_bp[1] = mapNo; ++ SET_HTC_PACKET_INFO_TX(&cookie->HtcPkt, ++ cookie, ++ A_NETBUF_DATA(skb), ++ A_NETBUF_LEN(skb), ++ arWMIStream2EndpointID(ar,streamID), ++ AR6K_DATA_PKT_TAG); ++ ++#ifdef DEBUG ++ if (debugdriver >= 3) { ++ ar6000_dump_skb(skb); ++ } ++#endif ++ /* HTC interface is asynchronous, if this fails, cleanup will happen in ++ * the ar6000_tx_complete callback */ ++ HTCSendPkt(ar->arHtcTarget, &cookie->HtcPkt); ++ } else { ++ /* no packet to send, cleanup */ ++ A_NETBUF_FREE(skb); ++ AR6000_STAT_INC(ar, tx_dropped); ++ AR6000_STAT_INC(ar, tx_aborted_errors); ++ } ++ ++ return 0; ++} ++ ++#ifdef ADAPTIVE_POWER_THROUGHPUT_CONTROL ++static void ++tvsub(register struct timeval *out, register struct timeval *in) ++{ ++ if((out->tv_usec -= in->tv_usec) < 0) { ++ out->tv_sec--; ++ out->tv_usec += 1000000; ++ } ++ out->tv_sec -= in->tv_sec; ++} ++ ++void ++applyAPTCHeuristics(AR_SOFTC_T *ar) ++{ ++ A_UINT32 duration; ++ A_UINT32 numbytes; ++ A_UINT32 throughput; ++ struct timeval ts; ++ A_STATUS status; ++ ++ AR6000_SPIN_LOCK(&ar->arLock, 0); ++ ++ if ((enableAPTCHeuristics) && (!aptcTR.timerScheduled)) { ++ do_gettimeofday(&ts); ++ tvsub(&ts, &aptcTR.samplingTS); ++ duration = ts.tv_sec * 1000 + ts.tv_usec / 1000; /* ms */ ++ numbytes = aptcTR.bytesTransmitted + aptcTR.bytesReceived; ++ ++ if (duration > APTC_TRAFFIC_SAMPLING_INTERVAL) { ++ /* Initialize the time stamp and byte count */ ++ aptcTR.bytesTransmitted = aptcTR.bytesReceived = 0; ++ do_gettimeofday(&aptcTR.samplingTS); ++ ++ /* Calculate and decide based on throughput thresholds */ ++ throughput = ((numbytes * 8) / duration); ++ if (throughput > APTC_UPPER_THROUGHPUT_THRESHOLD) { ++ /* Disable Sleep and schedule a timer */ ++ A_ASSERT(ar->arWmiReady == TRUE); ++ AR6000_SPIN_UNLOCK(&ar->arLock, 0); ++ status = wmi_powermode_cmd(ar->arWmi, MAX_PERF_POWER); ++ AR6000_SPIN_LOCK(&ar->arLock, 0); ++ A_TIMEOUT_MS(&aptcTimer, APTC_TRAFFIC_SAMPLING_INTERVAL, 0); ++ aptcTR.timerScheduled = TRUE; ++ } ++ } ++ } ++ ++ AR6000_SPIN_UNLOCK(&ar->arLock, 0); ++} ++#endif /* ADAPTIVE_POWER_THROUGHPUT_CONTROL */ ++ ++static void ++ar6000_tx_queue_full(void *Context, HTC_ENDPOINT_ID Endpoint) ++{ ++ AR_SOFTC_T *ar = (AR_SOFTC_T *) Context; ++ ++ if (Endpoint == arWMIStream2EndpointID(ar,WMI_CONTROL_PRI)) { ++ if (!bypasswmi) { ++ /* under normal WMI if this is getting full, then something is running rampant ++ * the host should not be exhausting the WMI queue with too many commands ++ * the only exception to this is during testing using endpointping */ ++ ++ AR6000_SPIN_LOCK(&ar->arLock, 0); ++ /* set flag to handle subsequent messages */ ++ ar->arWMIControlEpFull = TRUE; ++ AR6000_SPIN_UNLOCK(&ar->arLock, 0); ++ AR_DEBUG_PRINTF("WMI Control Endpoint is FULL!!! \n"); ++ } ++ } else { ++ /* one of the data endpoints queues is getting full..need to stop network stack ++ * the queue will resume after credits received */ ++ netif_stop_queue(ar->arNetDev); ++ } ++} ++ ++static void ++ar6000_tx_queue_avail(void *Context, HTC_ENDPOINT_ID Endpoint) ++{ ++ AR_SOFTC_T *ar = (AR_SOFTC_T *)Context; ++ ++ if (Endpoint == arWMIStream2EndpointID(ar,WMI_CONTROL_PRI)) { ++ /* FIXME: what do for it? */ ++ } else { ++ /* Wake up interface, rescheduling prevented. */ ++ if (ar->arConnected == TRUE || bypasswmi) ++ netif_wake_queue(ar->arNetDev); ++ } ++} ++ ++static void ++ar6000_tx_complete(void *Context, HTC_PACKET *pPacket) ++{ ++ AR_SOFTC_T *ar = (AR_SOFTC_T *)Context; ++ void *cookie = (void *)pPacket->pPktContext; ++ struct sk_buff *skb = NULL; ++ A_UINT32 mapNo = 0; ++ A_STATUS status; ++ struct ar_cookie * ar_cookie; ++ WMI_PRI_STREAM_ID streamID; ++ A_BOOL wakeEvent = FALSE; ++ ++ status = pPacket->Status; ++ ar_cookie = (struct ar_cookie *)cookie; ++ skb = (struct sk_buff *)ar_cookie->arc_bp[0]; ++ streamID = arEndpoint2WMIStreamID(ar,pPacket->Endpoint); ++ mapNo = ar_cookie->arc_bp[1]; ++ ++ A_ASSERT(skb); ++ A_ASSERT(pPacket->pBuffer == A_NETBUF_DATA(skb)); ++ ++ if (A_SUCCESS(status)) { ++ A_ASSERT(pPacket->ActualLength == A_NETBUF_LEN(skb)); ++ } ++ ++ AR_DEBUG2_PRINTF("ar6000_tx_complete skb=0x%x data=0x%x len=0x%x sid=%d ", ++ (A_UINT32)skb, (A_UINT32)pPacket->pBuffer, ++ pPacket->ActualLength, ++ streamID); ++ ++ /* lock the driver as we update internal state */ ++ AR6000_SPIN_LOCK(&ar->arLock, 0); ++ ++ ar->arTxPending[streamID]--; ++ ++ if ((streamID != WMI_CONTROL_PRI) || bypasswmi) { ++ ar->arTotalTxDataPending--; ++ } ++ ++ if (streamID == WMI_CONTROL_PRI) ++ { ++ if (ar->arWMIControlEpFull) { ++ /* since this packet completed, the WMI EP is no longer full */ ++ ar->arWMIControlEpFull = FALSE; ++ } ++ ++ if (ar->arTxPending[streamID] == 0) { ++ wakeEvent = TRUE; ++ } ++ } ++ ++ if (A_FAILED(status)) { ++ AR_DEBUG_PRINTF("%s() -TX ERROR, status: 0x%x\n", __func__, ++ status); ++ AR6000_STAT_INC(ar, tx_errors); ++ } else { ++ AR_DEBUG2_PRINTF("OK\n"); ++ AR6000_STAT_INC(ar, tx_packets); ++ ar->arNetStats.tx_bytes += A_NETBUF_LEN(skb); ++#ifdef ADAPTIVE_POWER_THROUGHPUT_CONTROL ++ aptcTR.bytesTransmitted += a_netbuf_to_len(skb); ++ applyAPTCHeuristics(ar); ++#endif /* ADAPTIVE_POWER_THROUGHPUT_CONTROL */ ++ } ++ ++ // TODO this needs to be looked at ++ if ((ar->arNetworkType == ADHOC_NETWORK) && ar->arIbssPsEnable ++ && (streamID != WMI_CONTROL_PRI) && mapNo) ++ { ++ mapNo --; ++ ar->arNodeMap[mapNo].txPending --; ++ ++ if (!ar->arNodeMap[mapNo].txPending && (mapNo == (ar->arNodeNum - 1))) { ++ A_UINT32 i; ++ for (i = ar->arNodeNum; i > 0; i --) { ++ if (!ar->arNodeMap[i - 1].txPending) { ++ A_MEMZERO(&ar->arNodeMap[i - 1], sizeof(struct ar_node_mapping)); ++ ar->arNodeNum --; ++ } else { ++ break; ++ } ++ } ++ } ++ } ++ ++ /* Freeing a cookie should not be contingent on either of */ ++ /* these flags, just if we have a cookie or not. */ ++ /* Can we even get here without a cookie? Fix later. */ ++ if (ar->arWmiReady == TRUE || (bypasswmi)) ++ { ++ ar6000_free_cookie(ar, cookie); ++ } ++ ++ AR6000_SPIN_UNLOCK(&ar->arLock, 0); ++ ++ /* lock is released, we can freely call other kernel APIs */ ++ ++ /* this indirectly frees the HTC_PACKET */ ++ A_NETBUF_FREE(skb); ++ ++ if (wakeEvent) { ++ wake_up(&arEvent); ++ } ++} ++ ++/* ++ * Receive event handler. This is called by HTC when a packet is received ++ */ ++int pktcount; ++static void ++ar6000_rx(void *Context, HTC_PACKET *pPacket) ++{ ++ AR_SOFTC_T *ar = (AR_SOFTC_T *)Context; ++ struct sk_buff *skb = (struct sk_buff *)pPacket->pPktContext; ++ int minHdrLen; ++ A_STATUS status = pPacket->Status; ++ WMI_PRI_STREAM_ID streamID = arEndpoint2WMIStreamID(ar,pPacket->Endpoint); ++ HTC_ENDPOINT_ID ept = pPacket->Endpoint; ++ ++ A_ASSERT((status != A_OK) || (pPacket->pBuffer == (A_NETBUF_DATA(skb) + HTC_HEADER_LEN))); ++ ++ AR_DEBUG2_PRINTF("ar6000_rx ar=0x%x sid=%d, skb=0x%x, data=0x%x, len=0x%x ", ++ (A_UINT32)ar, streamID, (A_UINT32)skb, (A_UINT32)pPacket->pBuffer, ++ pPacket->ActualLength); ++ if (status != A_OK) { ++ AR_DEBUG2_PRINTF("ERR\n"); ++ } else { ++ AR_DEBUG2_PRINTF("OK\n"); ++ } ++ ++ /* take lock to protect buffer counts ++ * and adaptive power throughput state */ ++ AR6000_SPIN_LOCK(&ar->arLock, 0); ++ ++ ar->arRxBuffers[streamID]--; ++ ++ if (A_SUCCESS(status)) { ++ AR6000_STAT_INC(ar, rx_packets); ++ ar->arNetStats.rx_bytes += pPacket->ActualLength; ++#ifdef ADAPTIVE_POWER_THROUGHPUT_CONTROL ++ aptcTR.bytesReceived += a_netbuf_to_len(skb); ++ applyAPTCHeuristics(ar); ++#endif /* ADAPTIVE_POWER_THROUGHPUT_CONTROL */ ++ ++ A_NETBUF_PUT(skb, pPacket->ActualLength + HTC_HEADER_LEN); ++ A_NETBUF_PULL(skb, HTC_HEADER_LEN); ++ ++#ifdef DEBUG ++ if (debugdriver >= 2) { ++ ar6000_dump_skb(skb); ++ } ++#endif /* DEBUG */ ++ } ++ ++ AR6000_SPIN_UNLOCK(&ar->arLock, 0); ++ ++ if (status != A_OK) { ++ AR6000_STAT_INC(ar, rx_errors); ++ A_NETBUF_FREE(skb); ++ } else if (ar->arWmiEnabled == TRUE) { ++ if (streamID == WMI_CONTROL_PRI) { ++ /* ++ * this is a wmi control msg ++ */ ++ wmi_control_rx(ar->arWmi, skb); ++ } else { ++ WMI_DATA_HDR *dhdr = (WMI_DATA_HDR *)A_NETBUF_DATA(skb); ++ if (WMI_DATA_HDR_IS_MSG_TYPE(dhdr, CNTL_MSGTYPE)) { ++ /* ++ * this is a wmi control msg ++ */ ++ /* strip off WMI hdr */ ++ wmi_data_hdr_remove(ar->arWmi, skb); ++ wmi_control_rx(ar->arWmi, skb); ++ } else { ++ /* ++ * this is a wmi data packet ++ */ ++ minHdrLen = sizeof (WMI_DATA_HDR) + sizeof(ATH_MAC_HDR) + ++ sizeof(ATH_LLC_SNAP_HDR); ++ ++ if ((pPacket->ActualLength < minHdrLen) || ++ (pPacket->ActualLength > AR6000_BUFFER_SIZE)) ++ { ++ /* ++ * packet is too short or too long ++ */ ++ AR_DEBUG_PRINTF("TOO SHORT or TOO LONG\n"); ++ AR6000_STAT_INC(ar, rx_errors); ++ AR6000_STAT_INC(ar, rx_length_errors); ++ A_NETBUF_FREE(skb); ++ } else { ++ if (ar->arWmmEnabled) { ++ wmi_implicit_create_pstream(ar->arWmi, skb, ++ DNLINK_TRAFFIC, UNDEFINED_PRI); ++ } ++#if 0 ++ /* Access RSSI values here */ ++ AR_DEBUG_PRINTF("RSSI %d\n", ++ ((WMI_DATA_HDR *) A_NETBUF_DATA(skb))->rssi); ++#endif ++ wmi_data_hdr_remove(ar->arWmi, skb); ++ wmi_dot3_2_dix(ar->arWmi, skb); ++ ++#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,0) ++ /* ++ * extra push and memcpy, for eth_type_trans() of 2.4 kernel ++ * will pull out hard_header_len bytes of the skb. ++ */ ++ A_NETBUF_PUSH(skb, sizeof(WMI_DATA_HDR) + sizeof(ATH_LLC_SNAP_HDR) + HTC_HEADER_LEN); ++ A_MEMCPY(A_NETBUF_DATA(skb), A_NETBUF_DATA(skb) + sizeof(WMI_DATA_HDR) + ++ sizeof(ATH_LLC_SNAP_HDR) + HTC_HEADER_LEN, sizeof(ATH_MAC_HDR)); ++#endif ++ if ((ar->arNetDev->flags & IFF_UP) == IFF_UP) ++ { ++ skb->dev = ar->arNetDev; ++ skb->protocol = eth_type_trans(skb, ar->arNetDev); ++ netif_rx(skb); ++ } ++ else ++ { ++ A_NETBUF_FREE(skb); ++ } ++ } ++ } ++ } ++ } else { ++ if ((ar->arNetDev->flags & IFF_UP) == IFF_UP) ++ { ++ skb->dev = ar->arNetDev; ++ skb->protocol = eth_type_trans(skb, ar->arNetDev); ++ netif_rx(skb); ++ } ++ else ++ { ++ A_NETBUF_FREE(skb); ++ } ++ } ++ ++ if (status != A_ECANCELED) { ++ /* ++ * HTC provides A_ECANCELED status when it doesn't want to be refilled ++ * (probably due to a shutdown) ++ */ ++ ar6000_rx_refill(Context, ept); ++ } ++ ++ ++} ++ ++static void ++ar6000_rx_refill(void *Context, HTC_ENDPOINT_ID Endpoint) ++{ ++ AR_SOFTC_T *ar = (AR_SOFTC_T *)Context; ++ void *osBuf; ++ int RxBuffers; ++ int buffersToRefill; ++ HTC_PACKET *pPacket; ++ WMI_PRI_STREAM_ID streamId = arEndpoint2WMIStreamID(ar,Endpoint); ++ ++ buffersToRefill = (int)AR6000_MAX_RX_BUFFERS - ++ (int)ar->arRxBuffers[streamId]; ++ ++ if (buffersToRefill <= 0) { ++ /* fast return, nothing to fill */ ++ return; ++ } ++ ++ AR_DEBUG2_PRINTF("ar6000_rx_refill: providing htc with %d buffers at eid=%d\n", ++ buffersToRefill, Endpoint); ++ ++ for (RxBuffers = 0; RxBuffers < buffersToRefill; RxBuffers++) { ++ osBuf = A_NETBUF_ALLOC(AR6000_BUFFER_SIZE); ++ if (NULL == osBuf) { ++ break; ++ } ++ /* the HTC packet wrapper is at the head of the reserved area ++ * in the skb */ ++ pPacket = (HTC_PACKET *)(A_NETBUF_HEAD(osBuf)); ++ /* set re-fill info */ ++ SET_HTC_PACKET_INFO_RX_REFILL(pPacket,osBuf,A_NETBUF_DATA(osBuf),AR6000_BUFFER_SIZE,Endpoint); ++ /* add this packet */ ++ HTCAddReceivePkt(ar->arHtcTarget, pPacket); ++ } ++ ++ /* update count */ ++ AR6000_SPIN_LOCK(&ar->arLock, 0); ++ ar->arRxBuffers[streamId] += RxBuffers; ++ AR6000_SPIN_UNLOCK(&ar->arLock, 0); ++} ++ ++static struct net_device_stats * ++ar6000_get_stats(struct net_device *dev) ++{ ++ AR_SOFTC_T *ar = (AR_SOFTC_T *)netdev_priv(dev); ++ return &ar->arNetStats; ++} ++ ++static struct iw_statistics * ++ar6000_get_iwstats(struct net_device * dev) ++{ ++ AR_SOFTC_T *ar = (AR_SOFTC_T *)netdev_priv(dev); ++ TARGET_STATS *pStats = &ar->arTargetStats; ++ struct iw_statistics * pIwStats = &ar->arIwStats; ++ ++ if ((ar->arWmiReady == FALSE) ++ /* ++ * The in_atomic function is used to determine if the scheduling is ++ * allowed in the current context or not. This was introduced in 2.6 ++ * From what I have read on the differences between 2.4 and 2.6, the ++ * 2.4 kernel did not support preemption and so this check might not ++ * be required for 2.4 kernels. ++ */ ++#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,0) ++ || (in_atomic()) ++#endif ++ ) ++ { ++ pIwStats->status = 0; ++ pIwStats->qual.qual = 0; ++ pIwStats->qual.level =0; ++ pIwStats->qual.noise = 0; ++ pIwStats->discard.code =0; ++ pIwStats->discard.retries=0; ++ pIwStats->miss.beacon =0; ++ return pIwStats; ++ } ++ if (down_interruptible(&ar->arSem)) { ++ pIwStats->status = 0; ++ return pIwStats; ++ } ++ ++ ++ ar->statsUpdatePending = TRUE; ++ ++ if(wmi_get_stats_cmd(ar->arWmi) != A_OK) { ++ up(&ar->arSem); ++ pIwStats->status = 0; ++ return pIwStats; ++ } ++ ++ wait_event_interruptible_timeout(arEvent, ar->statsUpdatePending == FALSE, wmitimeout * HZ); ++ ++ if (signal_pending(current)) { ++ AR_DEBUG_PRINTF("ar6000 : WMI get stats timeout \n"); ++ up(&ar->arSem); ++ pIwStats->status = 0; ++ return pIwStats; ++ } ++ pIwStats->status = 1 ; ++ pIwStats->qual.qual = pStats->cs_aveBeacon_rssi; ++ pIwStats->qual.level =pStats->cs_aveBeacon_rssi + 161; /* noise is -95 dBm */ ++ pIwStats->qual.noise = pStats->noise_floor_calibation; ++ pIwStats->discard.code = pStats->rx_decrypt_err; ++ pIwStats->discard.retries = pStats->tx_retry_cnt; ++ pIwStats->miss.beacon = pStats->cs_bmiss_cnt; ++ up(&ar->arSem); ++ return pIwStats; ++} ++ ++void ++ar6000_ready_event(void *devt, A_UINT8 *datap, A_UINT8 phyCap) ++{ ++ AR_SOFTC_T *ar = (AR_SOFTC_T *)devt; ++ struct net_device *dev = ar->arNetDev; ++ ++ ar->arWmiReady = TRUE; ++ wake_up(&arEvent); ++ A_MEMCPY(dev->dev_addr, datap, AR6000_ETH_ADDR_LEN); ++ AR_DEBUG_PRINTF("mac address = %2.2x:%2.2x:%2.2x:%2.2x:%2.2x:%2.2x\n", ++ dev->dev_addr[0], dev->dev_addr[1], ++ dev->dev_addr[2], dev->dev_addr[3], ++ dev->dev_addr[4], dev->dev_addr[5]); ++ ++ ar->arPhyCapability = phyCap; ++} ++ ++A_UINT8 ++ar6000_iptos_to_userPriority(A_UINT8 *pkt) ++{ ++ struct iphdr *ipHdr = (struct iphdr *)pkt; ++ A_UINT8 userPriority; ++ ++ /* ++ * IP Tos format : ++ * (Refer Pg 57 WMM-test-plan-v1.2) ++ * IP-TOS - 8bits ++ * : DSCP(6-bits) ECN(2-bits) ++ * : DSCP - P2 P1 P0 X X X ++ * where (P2 P1 P0) form 802.1D ++ */ ++ userPriority = ipHdr->tos >> 5; ++ return (userPriority & 0x7); ++} ++ ++void ++ar6000_connect_event(AR_SOFTC_T *ar, A_UINT16 channel, A_UINT8 *bssid, ++ A_UINT16 listenInterval, A_UINT16 beaconInterval, ++ NETWORK_TYPE networkType, A_UINT8 beaconIeLen, ++ A_UINT8 assocReqLen, A_UINT8 assocRespLen, ++ A_UINT8 *assocInfo) ++{ ++ union iwreq_data wrqu; ++ int i, beacon_ie_pos, assoc_resp_ie_pos, assoc_req_ie_pos; ++ static const char *tag1 = "ASSOCINFO(ReqIEs="; ++ static const char *tag2 = "ASSOCRESPIE="; ++ static const char *beaconIetag = "BEACONIE="; ++ char buf[WMI_CONTROL_MSG_MAX_LEN * 2 + sizeof(tag1)]; ++ char *pos; ++ A_UINT8 key_op_ctrl; ++ ++ A_MEMCPY(ar->arBssid, bssid, sizeof(ar->arBssid)); ++ ar->arBssChannel = channel; ++ ++ A_PRINTF("AR6000 connected event on freq %d ", channel); ++ A_PRINTF("with bssid %2.2x:%2.2x:%2.2x:%2.2x:%2.2x:%2.2x " ++ " listenInterval=%d, beaconInterval = %d, beaconIeLen = %d assocReqLen=%d" ++ " assocRespLen =%d\n", ++ bssid[0], bssid[1], bssid[2], ++ bssid[3], bssid[4], bssid[5], ++ listenInterval, beaconInterval, ++ beaconIeLen, assocReqLen, assocRespLen); ++ if (networkType & ADHOC_NETWORK) { ++ if (networkType & ADHOC_CREATOR) { ++ A_PRINTF("Network: Adhoc (Creator)\n"); ++ } else { ++ A_PRINTF("Network: Adhoc (Joiner)\n"); ++ } ++ } else { ++ A_PRINTF("Network: Infrastructure\n"); ++ } ++ ++ if (beaconIeLen && (sizeof(buf) > (9 + beaconIeLen * 2))) { ++ AR_DEBUG_PRINTF("\nBeaconIEs= "); ++ ++ beacon_ie_pos = 0; ++ A_MEMZERO(buf, sizeof(buf)); ++ sprintf(buf, "%s", beaconIetag); ++ pos = buf + 9; ++ for (i = beacon_ie_pos; i < beacon_ie_pos + beaconIeLen; i++) { ++ AR_DEBUG_PRINTF("%2.2x ", assocInfo[i]); ++ sprintf(pos, "%2.2x", assocInfo[i]); ++ pos += 2; ++ } ++ AR_DEBUG_PRINTF("\n"); ++ ++ A_MEMZERO(&wrqu, sizeof(wrqu)); ++ wrqu.data.length = strlen(buf); ++ wireless_send_event(ar->arNetDev, IWEVCUSTOM, &wrqu, buf); ++ } ++ ++ if (assocRespLen && (sizeof(buf) > (12 + (assocRespLen * 2)))) ++ { ++ assoc_resp_ie_pos = beaconIeLen + assocReqLen + ++ sizeof(A_UINT16) + /* capinfo*/ ++ sizeof(A_UINT16) + /* status Code */ ++ sizeof(A_UINT16) ; /* associd */ ++ A_MEMZERO(buf, sizeof(buf)); ++ sprintf(buf, "%s", tag2); ++ pos = buf + 12; ++ AR_DEBUG_PRINTF("\nAssocRespIEs= "); ++ /* ++ * The Association Response Frame w.o. the WLAN header is delivered to ++ * the host, so skip over to the IEs ++ */ ++ for (i = assoc_resp_ie_pos; i < assoc_resp_ie_pos + assocRespLen - 6; i++) ++ { ++ AR_DEBUG_PRINTF("%2.2x ", assocInfo[i]); ++ sprintf(pos, "%2.2x", assocInfo[i]); ++ pos += 2; ++ } ++ AR_DEBUG_PRINTF("\n"); ++ ++ A_MEMZERO(&wrqu, sizeof(wrqu)); ++ wrqu.data.length = strlen(buf); ++ wireless_send_event(ar->arNetDev, IWEVCUSTOM, &wrqu, buf); ++ } ++ ++ if (assocReqLen && (sizeof(buf) > (17 + (assocReqLen * 2)))) { ++ /* ++ * assoc Request includes capability and listen interval. Skip these. ++ */ ++ assoc_req_ie_pos = beaconIeLen + ++ sizeof(A_UINT16) + /* capinfo*/ ++ sizeof(A_UINT16); /* listen interval */ ++ ++ A_MEMZERO(buf, sizeof(buf)); ++ sprintf(buf, "%s", tag1); ++ pos = buf + 17; ++ AR_DEBUG_PRINTF("AssocReqIEs= "); ++ for (i = assoc_req_ie_pos; i < assoc_req_ie_pos + assocReqLen - 4; i++) { ++ AR_DEBUG_PRINTF("%2.2x ", assocInfo[i]); ++ sprintf(pos, "%2.2x", assocInfo[i]); ++ pos += 2;; ++ } ++ AR_DEBUG_PRINTF("\n"); ++ ++ A_MEMZERO(&wrqu, sizeof(wrqu)); ++ wrqu.data.length = strlen(buf); ++ wireless_send_event(ar->arNetDev, IWEVCUSTOM, &wrqu, buf); ++ } ++ ++#ifdef USER_KEYS ++ if (ar->user_savedkeys_stat == USER_SAVEDKEYS_STAT_RUN && ++ ar->user_saved_keys.keyOk == TRUE) ++ { ++ ++ key_op_ctrl = KEY_OP_VALID_MASK & ~KEY_OP_INIT_TSC; ++ if (ar->user_key_ctrl & AR6000_USER_SETKEYS_RSC_UNCHANGED) { ++ key_op_ctrl &= ~KEY_OP_INIT_RSC; ++ } else { ++ key_op_ctrl |= KEY_OP_INIT_RSC; ++ } ++ ar6000_reinstall_keys(ar, key_op_ctrl); ++ } ++#endif /* USER_KEYS */ ++ ++ /* flush data queues */ ++ ar6000_TxDataCleanup(ar); ++ ++ netif_start_queue(ar->arNetDev); ++ ++ if ((OPEN_AUTH == ar->arDot11AuthMode) && ++ (NONE_AUTH == ar->arAuthMode) && ++ (WEP_CRYPT == ar->arPairwiseCrypto)) ++ { ++ if (!ar->arConnected) { ++ ar6000_install_static_wep_keys(ar); ++ } ++ } ++ ++ ar->arConnected = TRUE; ++ ar->arConnectPending = FALSE; ++ ++ reconnect_flag = 0; ++ ++ A_MEMZERO(&wrqu, sizeof(wrqu)); ++ A_MEMCPY(wrqu.addr.sa_data, bssid, IEEE80211_ADDR_LEN); ++ wrqu.addr.sa_family = ARPHRD_ETHER; ++ wireless_send_event(ar->arNetDev, SIOCGIWAP, &wrqu, NULL); ++ if ((ar->arNetworkType == ADHOC_NETWORK) && ar->arIbssPsEnable) { ++ A_MEMZERO(ar->arNodeMap, sizeof(ar->arNodeMap)); ++ ar->arNodeNum = 0; ++ ar->arNexEpId = ENDPOINT_2; ++ } ++ ++} ++ ++void ar6000_set_numdataendpts(AR_SOFTC_T *ar, A_UINT32 num) ++{ ++ A_ASSERT(num <= (HTC_MAILBOX_NUM_MAX - 1)); ++ ar->arNumDataEndPts = num; ++} ++ ++void ++ar6000_disconnect_event(AR_SOFTC_T *ar, A_UINT8 reason, A_UINT8 *bssid, ++ A_UINT8 assocRespLen, A_UINT8 *assocInfo, A_UINT16 protocolReasonStatus) ++{ ++ A_UINT8 i; ++ ++ A_PRINTF("AR6000 disconnected"); ++ if (bssid[0] || bssid[1] || bssid[2] || bssid[3] || bssid[4] || bssid[5]) { ++ A_PRINTF(" from %2.2x:%2.2x:%2.2x:%2.2x:%2.2x:%2.2x ", ++ bssid[0], bssid[1], bssid[2], bssid[3], bssid[4], bssid[5]); ++ } ++ A_PRINTF("\n"); ++ ++ AR_DEBUG_PRINTF("\nDisconnect Reason is %d", reason); ++ AR_DEBUG_PRINTF("\nProtocol Reason/Status Code is %d", protocolReasonStatus); ++ AR_DEBUG_PRINTF("\nAssocResp Frame = %s", ++ assocRespLen ? " " : "NULL"); ++ for (i = 0; i < assocRespLen; i++) { ++ if (!(i % 0x10)) { ++ AR_DEBUG_PRINTF("\n"); ++ } ++ AR_DEBUG_PRINTF("%2.2x ", assocInfo[i]); ++ } ++ AR_DEBUG_PRINTF("\n"); ++ /* ++ * If the event is due to disconnect cmd from the host, only they the target ++ * would stop trying to connect. Under any other condition, target would ++ * keep trying to connect. ++ * ++ */ ++ if( reason == DISCONNECT_CMD) ++ { ++ ar->arConnectPending = FALSE; ++ } else { ++ ar->arConnectPending = TRUE; ++ if (((reason == ASSOC_FAILED) && (protocolReasonStatus == 0x11)) || ++ ((reason == ASSOC_FAILED) && (protocolReasonStatus == 0x0) && (reconnect_flag == 1))) { ++ ar->arConnected = TRUE; ++ return; ++ } ++ } ++ ar->arConnected = FALSE; ++ ++ if( (reason != CSERV_DISCONNECT) || (reconnect_flag != 1) ) { ++ reconnect_flag = 0; ++ } ++ ++#ifdef USER_KEYS ++ if (reason != CSERV_DISCONNECT) ++ { ++ ar->user_savedkeys_stat = USER_SAVEDKEYS_STAT_INIT; ++ ar->user_key_ctrl = 0; ++ } ++#endif /* USER_KEYS */ ++ ++ netif_stop_queue(ar->arNetDev); ++ A_MEMZERO(ar->arBssid, sizeof(ar->arBssid)); ++ ar->arBssChannel = 0; ++ ar->arBeaconInterval = 0; ++ ++ ar6000_TxDataCleanup(ar); ++} ++ ++void ++ar6000_regDomain_event(AR_SOFTC_T *ar, A_UINT32 regCode) ++{ ++ A_PRINTF("AR6000 Reg Code = 0x%x\n", regCode); ++ ar->arRegCode = regCode; ++} ++ ++void ++ar6000_neighborReport_event(AR_SOFTC_T *ar, int numAps, WMI_NEIGHBOR_INFO *info) ++{ ++ static const char *tag = "PRE-AUTH"; ++ char buf[128]; ++ union iwreq_data wrqu; ++ int i; ++ ++ AR_DEBUG_PRINTF("AR6000 Neighbor Report Event\n"); ++ for (i=0; i < numAps; info++, i++) { ++ AR_DEBUG_PRINTF("bssid %2.2x:%2.2x:%2.2x:%2.2x:%2.2x:%2.2x ", ++ info->bssid[0], info->bssid[1], info->bssid[2], ++ info->bssid[3], info->bssid[4], info->bssid[5]); ++ if (info->bssFlags & WMI_PREAUTH_CAPABLE_BSS) { ++ AR_DEBUG_PRINTF("preauth-cap"); ++ } ++ if (info->bssFlags & WMI_PMKID_VALID_BSS) { ++ AR_DEBUG_PRINTF(" pmkid-valid\n"); ++ continue; /* we skip bss if the pmkid is already valid */ ++ } ++ AR_DEBUG_PRINTF("\n"); ++ snprintf(buf, sizeof(buf), "%s%2.2x%2.2x%2.2x%2.2x%2.2x%2.2x%2.2x%2.2x", ++ tag, ++ info->bssid[0], info->bssid[1], info->bssid[2], ++ info->bssid[3], info->bssid[4], info->bssid[5], ++ i, info->bssFlags); ++ A_MEMZERO(&wrqu, sizeof(wrqu)); ++ wrqu.data.length = strlen(buf); ++ wireless_send_event(ar->arNetDev, IWEVCUSTOM, &wrqu, buf); ++ } ++} ++ ++void ++ar6000_tkip_micerr_event(AR_SOFTC_T *ar, A_UINT8 keyid, A_BOOL ismcast) ++{ ++ static const char *tag = "MLME-MICHAELMICFAILURE.indication"; ++ char buf[128]; ++ union iwreq_data wrqu; ++ ++ A_PRINTF("AR6000 TKIP MIC error received for keyid %d %scast\n", ++ keyid, ismcast ? "multi": "uni"); ++ snprintf(buf, sizeof(buf), "%s(keyid=%d %scat)", tag, keyid, ++ ismcast ? "multi" : "uni"); ++ memset(&wrqu, 0, sizeof(wrqu)); ++ wrqu.data.length = strlen(buf); ++ wireless_send_event(ar->arNetDev, IWEVCUSTOM, &wrqu, buf); ++} ++ ++void ++ar6000_scanComplete_event(AR_SOFTC_T *ar, A_STATUS status) ++{ ++ AR_DEBUG_PRINTF("AR6000 scan complete: %d\n", status); ++ ++ ar->scan_complete = 1; ++ wake_up_interruptible(&ar6000_scan_queue); ++} ++ ++void ++ar6000_targetStats_event(AR_SOFTC_T *ar, WMI_TARGET_STATS *pTarget) ++{ ++ TARGET_STATS *pStats = &ar->arTargetStats; ++ A_UINT8 ac; ++ ++ /*A_PRINTF("AR6000 updating target stats\n");*/ ++ pStats->tx_packets += pTarget->txrxStats.tx_stats.tx_packets; ++ pStats->tx_bytes += pTarget->txrxStats.tx_stats.tx_bytes; ++ pStats->tx_unicast_pkts += pTarget->txrxStats.tx_stats.tx_unicast_pkts; ++ pStats->tx_unicast_bytes += pTarget->txrxStats.tx_stats.tx_unicast_bytes; ++ pStats->tx_multicast_pkts += pTarget->txrxStats.tx_stats.tx_multicast_pkts; ++ pStats->tx_multicast_bytes += pTarget->txrxStats.tx_stats.tx_multicast_bytes; ++ pStats->tx_broadcast_pkts += pTarget->txrxStats.tx_stats.tx_broadcast_pkts; ++ pStats->tx_broadcast_bytes += pTarget->txrxStats.tx_stats.tx_broadcast_bytes; ++ pStats->tx_rts_success_cnt += pTarget->txrxStats.tx_stats.tx_rts_success_cnt; ++ for(ac = 0; ac < WMM_NUM_AC; ac++) ++ pStats->tx_packet_per_ac[ac] += pTarget->txrxStats.tx_stats.tx_packet_per_ac[ac]; ++ pStats->tx_errors += pTarget->txrxStats.tx_stats.tx_errors; ++ pStats->tx_failed_cnt += pTarget->txrxStats.tx_stats.tx_failed_cnt; ++ pStats->tx_retry_cnt += pTarget->txrxStats.tx_stats.tx_retry_cnt; ++ pStats->tx_rts_fail_cnt += pTarget->txrxStats.tx_stats.tx_rts_fail_cnt; ++ pStats->tx_unicast_rate = wmi_get_rate(pTarget->txrxStats.tx_stats.tx_unicast_rate); ++ ++ pStats->rx_packets += pTarget->txrxStats.rx_stats.rx_packets; ++ pStats->rx_bytes += pTarget->txrxStats.rx_stats.rx_bytes; ++ pStats->rx_unicast_pkts += pTarget->txrxStats.rx_stats.rx_unicast_pkts; ++ pStats->rx_unicast_bytes += pTarget->txrxStats.rx_stats.rx_unicast_bytes; ++ pStats->rx_multicast_pkts += pTarget->txrxStats.rx_stats.rx_multicast_pkts; ++ pStats->rx_multicast_bytes += pTarget->txrxStats.rx_stats.rx_multicast_bytes; ++ pStats->rx_broadcast_pkts += pTarget->txrxStats.rx_stats.rx_broadcast_pkts; ++ pStats->rx_broadcast_bytes += pTarget->txrxStats.rx_stats.rx_broadcast_bytes; ++ pStats->rx_fragment_pkt += pTarget->txrxStats.rx_stats.rx_fragment_pkt; ++ pStats->rx_errors += pTarget->txrxStats.rx_stats.rx_errors; ++ pStats->rx_crcerr += pTarget->txrxStats.rx_stats.rx_crcerr; ++ pStats->rx_key_cache_miss += pTarget->txrxStats.rx_stats.rx_key_cache_miss; ++ pStats->rx_decrypt_err += pTarget->txrxStats.rx_stats.rx_decrypt_err; ++ pStats->rx_duplicate_frames += pTarget->txrxStats.rx_stats.rx_duplicate_frames; ++ pStats->rx_unicast_rate = wmi_get_rate(pTarget->txrxStats.rx_stats.rx_unicast_rate); ++ ++ ++ pStats->tkip_local_mic_failure ++ += pTarget->txrxStats.tkipCcmpStats.tkip_local_mic_failure; ++ pStats->tkip_counter_measures_invoked ++ += pTarget->txrxStats.tkipCcmpStats.tkip_counter_measures_invoked; ++ pStats->tkip_replays += pTarget->txrxStats.tkipCcmpStats.tkip_replays; ++ pStats->tkip_format_errors += pTarget->txrxStats.tkipCcmpStats.tkip_format_errors; ++ pStats->ccmp_format_errors += pTarget->txrxStats.tkipCcmpStats.ccmp_format_errors; ++ pStats->ccmp_replays += pTarget->txrxStats.tkipCcmpStats.ccmp_replays; ++ ++ ++ pStats->power_save_failure_cnt += pTarget->pmStats.power_save_failure_cnt; ++ pStats->noise_floor_calibation = pTarget->noise_floor_calibation; ++ ++ pStats->cs_bmiss_cnt += pTarget->cservStats.cs_bmiss_cnt; ++ pStats->cs_lowRssi_cnt += pTarget->cservStats.cs_lowRssi_cnt; ++ pStats->cs_connect_cnt += pTarget->cservStats.cs_connect_cnt; ++ pStats->cs_disconnect_cnt += pTarget->cservStats.cs_disconnect_cnt; ++ pStats->cs_aveBeacon_snr = pTarget->cservStats.cs_aveBeacon_snr; ++ pStats->cs_aveBeacon_rssi = pTarget->cservStats.cs_aveBeacon_rssi; ++ pStats->cs_lastRoam_msec = pTarget->cservStats.cs_lastRoam_msec; ++ pStats->cs_snr = pTarget->cservStats.cs_snr; ++ pStats->cs_rssi = pTarget->cservStats.cs_rssi; ++ ++ pStats->lq_val = pTarget->lqVal; ++ ++ pStats->wow_num_pkts_dropped += pTarget->wowStats.wow_num_pkts_dropped; ++ pStats->wow_num_host_pkt_wakeups += pTarget->wowStats.wow_num_host_pkt_wakeups; ++ pStats->wow_num_host_event_wakeups += pTarget->wowStats.wow_num_host_event_wakeups; ++ pStats->wow_num_events_discarded += pTarget->wowStats.wow_num_events_discarded; ++ ++ ar->statsUpdatePending = FALSE; ++ wake_up(&arEvent); ++} ++ ++void ++ar6000_rssiThreshold_event(AR_SOFTC_T *ar, WMI_RSSI_THRESHOLD_VAL newThreshold, A_INT16 rssi) ++{ ++ USER_RSSI_THOLD userRssiThold; ++ ++ userRssiThold.tag = rssi_map[newThreshold].tag; ++ userRssiThold.rssi = rssi; ++ AR_DEBUG2_PRINTF("rssi Threshold range = %d tag = %d rssi = %d\n", newThreshold, userRssiThold.tag, rssi); ++#ifdef SEND_EVENT_TO_APP ++ ar6000_send_event_to_app(ar, WMI_RSSI_THRESHOLD_EVENTID,(A_UINT8 *)&userRssiThold, sizeof(USER_RSSI_THOLD)); ++#endif ++} ++ ++ ++void ++ar6000_hbChallengeResp_event(AR_SOFTC_T *ar, A_UINT32 cookie, A_UINT32 source) ++{ ++ if (source == APP_HB_CHALLENGE) { ++ /* Report it to the app in case it wants a positive acknowledgement */ ++#ifdef SEND_EVENT_TO_APP ++ ar6000_send_event_to_app(ar, WMIX_HB_CHALLENGE_RESP_EVENTID, ++ (A_UINT8 *)&cookie, sizeof(cookie)); ++#endif ++ } else { ++ /* This would ignore the replys that come in after their due time */ ++ if (cookie == ar->arHBChallengeResp.seqNum) { ++ ar->arHBChallengeResp.outstanding = FALSE; ++ } ++ } ++} ++ ++ ++void ++ar6000_reportError_event(AR_SOFTC_T *ar, WMI_TARGET_ERROR_VAL errorVal) ++{ ++ char *errString[] = { ++ [WMI_TARGET_PM_ERR_FAIL] "WMI_TARGET_PM_ERR_FAIL", ++ [WMI_TARGET_KEY_NOT_FOUND] "WMI_TARGET_KEY_NOT_FOUND", ++ [WMI_TARGET_DECRYPTION_ERR] "WMI_TARGET_DECRYPTION_ERR", ++ [WMI_TARGET_BMISS] "WMI_TARGET_BMISS", ++ [WMI_PSDISABLE_NODE_JOIN] "WMI_PSDISABLE_NODE_JOIN" ++ }; ++ ++ A_PRINTF("AR6000 Error on Target. Error = 0x%x\n", errorVal); ++ ++ /* One error is reported at a time, and errorval is a bitmask */ ++ if(errorVal & (errorVal - 1)) ++ return; ++ ++ A_PRINTF("AR6000 Error type = "); ++ switch(errorVal) ++ { ++ case WMI_TARGET_PM_ERR_FAIL: ++ case WMI_TARGET_KEY_NOT_FOUND: ++ case WMI_TARGET_DECRYPTION_ERR: ++ case WMI_TARGET_BMISS: ++ case WMI_PSDISABLE_NODE_JOIN: ++ A_PRINTF("%s\n", errString[errorVal]); ++ break; ++ default: ++ A_PRINTF("INVALID\n"); ++ break; ++ } ++ ++} ++ ++ ++void ++ar6000_cac_event(AR_SOFTC_T *ar, A_UINT8 ac, A_UINT8 cacIndication, ++ A_UINT8 statusCode, A_UINT8 *tspecSuggestion) ++{ ++ WMM_TSPEC_IE *tspecIe; ++ ++ /* ++ * This is the TSPEC IE suggestion from AP. ++ * Suggestion provided by AP under some error ++ * cases, could be helpful for the host app. ++ * Check documentation. ++ */ ++ tspecIe = (WMM_TSPEC_IE *)tspecSuggestion; ++ ++ /* ++ * What do we do, if we get TSPEC rejection? One thought ++ * that comes to mind is implictly delete the pstream... ++ */ ++ A_PRINTF("AR6000 CAC notification. " ++ "AC = %d, cacIndication = 0x%x, statusCode = 0x%x\n", ++ ac, cacIndication, statusCode); ++} ++ ++#define AR6000_PRINT_BSSID(_pBss) do { \ ++ A_PRINTF("%2.2x:%2.2x:%2.2x:%2.2x:%2.2x:%2.2x ",\ ++ (_pBss)[0],(_pBss)[1],(_pBss)[2],(_pBss)[3],\ ++ (_pBss)[4],(_pBss)[5]); \ ++} while(0) ++ ++void ++ar6000_roam_tbl_event(AR_SOFTC_T *ar, WMI_TARGET_ROAM_TBL *pTbl) ++{ ++ A_UINT8 i; ++ ++ A_PRINTF("ROAM TABLE NO OF ENTRIES is %d ROAM MODE is %d\n", ++ pTbl->numEntries, pTbl->roamMode); ++ for (i= 0; i < pTbl->numEntries; i++) { ++ A_PRINTF("[%d]bssid %2.2x:%2.2x:%2.2x:%2.2x:%2.2x:%2.2x ", i, ++ pTbl->bssRoamInfo[i].bssid[0], pTbl->bssRoamInfo[i].bssid[1], ++ pTbl->bssRoamInfo[i].bssid[2], ++ pTbl->bssRoamInfo[i].bssid[3], ++ pTbl->bssRoamInfo[i].bssid[4], ++ pTbl->bssRoamInfo[i].bssid[5]); ++ A_PRINTF("RSSI %d RSSIDT %d LAST RSSI %d UTIL %d ROAM_UTIL %d" ++ " BIAS %d\n", ++ pTbl->bssRoamInfo[i].rssi, ++ pTbl->bssRoamInfo[i].rssidt, ++ pTbl->bssRoamInfo[i].last_rssi, ++ pTbl->bssRoamInfo[i].util, ++ pTbl->bssRoamInfo[i].roam_util, ++ pTbl->bssRoamInfo[i].bias); ++ } ++} ++ ++void ++ar6000_wow_list_event(struct ar6_softc *ar, A_UINT8 num_filters, WMI_GET_WOW_LIST_REPLY *wow_reply) ++{ ++ A_UINT8 i,j; ++ ++ /*Each event now contains exactly one filter, see bug 26613*/ ++ A_PRINTF("WOW pattern %d of %d patterns\n", wow_reply->this_filter_num, wow_reply->num_filters); ++ A_PRINTF("wow mode = %s host mode = %s\n", ++ (wow_reply->wow_mode == 0? "disabled":"enabled"), ++ (wow_reply->host_mode == 1 ? "awake":"asleep")); ++ ++ ++ /*If there are no patterns, the reply will only contain generic ++ WoW information. Pattern information will exist only if there are ++ patterns present. Bug 26716*/ ++ ++ /* If this event contains pattern information, display it*/ ++ if (wow_reply->this_filter_num) { ++ i=0; ++ A_PRINTF("id=%d size=%d offset=%d\n", ++ wow_reply->wow_filters[i].wow_filter_id, ++ wow_reply->wow_filters[i].wow_filter_size, ++ wow_reply->wow_filters[i].wow_filter_offset); ++ A_PRINTF("wow pattern = "); ++ for (j=0; j< wow_reply->wow_filters[i].wow_filter_size; j++) { ++ A_PRINTF("%2.2x",wow_reply->wow_filters[i].wow_filter_pattern[j]); ++ } ++ ++ A_PRINTF("\nwow mask = "); ++ for (j=0; j< wow_reply->wow_filters[i].wow_filter_size; j++) { ++ A_PRINTF("%2.2x",wow_reply->wow_filters[i].wow_filter_mask[j]); ++ } ++ A_PRINTF("\n"); ++ } ++} ++ ++/* ++ * Report the Roaming related data collected on the target ++ */ ++void ++ar6000_display_roam_time(WMI_TARGET_ROAM_TIME *p) ++{ ++ A_PRINTF("Disconnect Data : BSSID: "); ++ AR6000_PRINT_BSSID(p->disassoc_bssid); ++ A_PRINTF(" RSSI %d DISASSOC Time %d NO_TXRX_TIME %d\n", ++ p->disassoc_bss_rssi,p->disassoc_time, ++ p->no_txrx_time); ++ A_PRINTF("Connect Data: BSSID: "); ++ AR6000_PRINT_BSSID(p->assoc_bssid); ++ A_PRINTF(" RSSI %d ASSOC Time %d TXRX_TIME %d\n", ++ p->assoc_bss_rssi,p->assoc_time, ++ p->allow_txrx_time); ++ A_PRINTF("Last Data Tx Time (b4 Disassoc) %d "\ ++ "First Data Tx Time (after Assoc) %d\n", ++ p->last_data_txrx_time, p->first_data_txrx_time); ++} ++ ++void ++ar6000_roam_data_event(AR_SOFTC_T *ar, WMI_TARGET_ROAM_DATA *p) ++{ ++ switch (p->roamDataType) { ++ case ROAM_DATA_TIME: ++ ar6000_display_roam_time(&p->u.roamTime); ++ break; ++ default: ++ break; ++ } ++} ++ ++void ++ar6000_bssInfo_event_rx(AR_SOFTC_T *ar, A_UINT8 *datap, int len) ++{ ++ struct sk_buff *skb; ++ WMI_BSS_INFO_HDR *bih = (WMI_BSS_INFO_HDR *)datap; ++ ++ ++ if (!ar->arMgmtFilter) { ++ return; ++ } ++ if (((ar->arMgmtFilter & IEEE80211_FILTER_TYPE_BEACON) && ++ (bih->frameType != BEACON_FTYPE)) || ++ ((ar->arMgmtFilter & IEEE80211_FILTER_TYPE_PROBE_RESP) && ++ (bih->frameType != PROBERESP_FTYPE))) ++ { ++ return; ++ } ++ ++ if ((skb = A_NETBUF_ALLOC_RAW(len)) != NULL) { ++ ++ A_NETBUF_PUT(skb, len); ++ A_MEMCPY(A_NETBUF_DATA(skb), datap, len); ++ skb->dev = ar->arNetDev; ++ printk("MAC RAW...\n"); ++// skb->mac.raw = A_NETBUF_DATA(skb); ++ skb->ip_summed = CHECKSUM_NONE; ++ skb->pkt_type = PACKET_OTHERHOST; ++ skb->protocol = __constant_htons(0x0019); ++ netif_rx(skb); ++ } ++} ++ ++A_UINT32 wmiSendCmdNum; ++ ++A_STATUS ++ar6000_control_tx(void *devt, void *osbuf, WMI_PRI_STREAM_ID streamID) ++{ ++ AR_SOFTC_T *ar = (AR_SOFTC_T *)devt; ++ A_STATUS status = A_OK; ++ struct ar_cookie *cookie = NULL; ++ int i; ++ ++ /* take lock to protect ar6000_alloc_cookie() */ ++ AR6000_SPIN_LOCK(&ar->arLock, 0); ++ ++ do { ++ ++ AR_DEBUG2_PRINTF("ar_contrstatus = ol_tx: skb=0x%x, len=0x%x, sid=%d\n", ++ (A_UINT32)osbuf, A_NETBUF_LEN(osbuf), streamID); ++ ++ if ((streamID == WMI_CONTROL_PRI) && (ar->arWMIControlEpFull)) { ++ /* control endpoint is full, don't allocate resources, we ++ * are just going to drop this packet */ ++ cookie = NULL; ++ AR_DEBUG_PRINTF(" WMI Control EP full, dropping packet : 0x%X, len:%d \n", ++ (A_UINT32)osbuf, A_NETBUF_LEN(osbuf)); ++ } else { ++ cookie = ar6000_alloc_cookie(ar); ++ } ++ ++ if (cookie == NULL) { ++ status = A_NO_MEMORY; ++ break; ++ } ++ ++ if(logWmiRawMsgs) { ++ A_PRINTF("WMI cmd send, msgNo %d :", wmiSendCmdNum); ++ for(i = 0; i < a_netbuf_to_len(osbuf); i++) ++ A_PRINTF("%x ", ((A_UINT8 *)a_netbuf_to_data(osbuf))[i]); ++ A_PRINTF("\n"); ++ } ++ ++ wmiSendCmdNum++; ++ ++ } while (FALSE); ++ ++ if (cookie != NULL) { ++ /* got a structure to send it out on */ ++ ar->arTxPending[streamID]++; ++ ++ if (streamID != WMI_CONTROL_PRI) { ++ ar->arTotalTxDataPending++; ++ } ++ } ++ ++ AR6000_SPIN_UNLOCK(&ar->arLock, 0); ++ ++ if (cookie != NULL) { ++ cookie->arc_bp[0] = (A_UINT32)osbuf; ++ cookie->arc_bp[1] = 0; ++ SET_HTC_PACKET_INFO_TX(&cookie->HtcPkt, ++ cookie, ++ A_NETBUF_DATA(osbuf), ++ A_NETBUF_LEN(osbuf), ++ arWMIStream2EndpointID(ar,streamID), ++ AR6K_CONTROL_PKT_TAG); ++ /* this interface is asynchronous, if there is an error, cleanup will happen in the ++ * TX completion callback */ ++ HTCSendPkt(ar->arHtcTarget, &cookie->HtcPkt); ++ status = A_OK; ++ } ++ ++ return status; ++} ++ ++/* indicate tx activity or inactivity on a WMI stream */ ++void ar6000_indicate_tx_activity(void *devt, A_UINT8 TrafficClass, A_BOOL Active) ++{ ++ AR_SOFTC_T *ar = (AR_SOFTC_T *)devt; ++ WMI_PRI_STREAM_ID streamid; ++ ++ if (ar->arWmiEnabled) { ++ streamid = wmi_get_stream_id(ar->arWmi, TrafficClass); ++ } else { ++ /* for mbox ping testing, the traffic class is mapped directly as a stream ID, ++ * see handling of AR6000_XIOCTL_TRAFFIC_ACTIVITY_CHANGE in ioctl.c */ ++ streamid = (WMI_PRI_STREAM_ID)TrafficClass; ++ } ++ ++ /* notify HTC, this may cause credit distribution changes */ ++ ++ HTCIndicateActivityChange(ar->arHtcTarget, ++ arWMIStream2EndpointID(ar,streamid), ++ Active); ++ ++} ++ ++module_init(ar6000_init_module); ++module_exit(ar6000_cleanup_module); ++ ++/* Init cookie queue */ ++static void ++ar6000_cookie_init(AR_SOFTC_T *ar) ++{ ++ A_UINT32 i; ++ ++ ar->arCookieList = NULL; ++ A_MEMZERO(s_ar_cookie_mem, sizeof(s_ar_cookie_mem)); ++ ++ for (i = 0; i < MAX_COOKIE_NUM; i++) { ++ ar6000_free_cookie(ar, &s_ar_cookie_mem[i]); ++ } ++} ++ ++/* cleanup cookie queue */ ++static void ++ar6000_cookie_cleanup(AR_SOFTC_T *ar) ++{ ++ /* It is gone .... */ ++ ar->arCookieList = NULL; ++} ++ ++/* Init cookie queue */ ++static void ++ar6000_free_cookie(AR_SOFTC_T *ar, struct ar_cookie * cookie) ++{ ++ /* Insert first */ ++ A_ASSERT(ar != NULL); ++ A_ASSERT(cookie != NULL); ++ cookie->arc_list_next = ar->arCookieList; ++ ar->arCookieList = cookie; ++} ++ ++/* cleanup cookie queue */ ++static struct ar_cookie * ++ar6000_alloc_cookie(AR_SOFTC_T *ar) ++{ ++ struct ar_cookie *cookie; ++ ++ cookie = ar->arCookieList; ++ if(cookie != NULL) ++ { ++ ar->arCookieList = cookie->arc_list_next; ++ } ++ ++ return cookie; ++} ++ ++#ifdef SEND_EVENT_TO_APP ++/* ++ * This function is used to send event which come from taget to ++ * the application. The buf which send to application is include ++ * the event ID and event content. ++ */ ++#define EVENT_ID_LEN 2 ++void ar6000_send_event_to_app(AR_SOFTC_T *ar, A_UINT16 eventId, ++ A_UINT8 *datap, int len) ++{ ++ ++#if (WIRELESS_EXT >= 15) ++ ++/* note: IWEVCUSTOM only exists in wireless extensions after version 15 */ ++ ++ char *buf; ++ A_UINT16 size; ++ union iwreq_data wrqu; ++ ++ size = len + EVENT_ID_LEN; ++ ++ if (size > IW_CUSTOM_MAX) { ++ AR_DEBUG_PRINTF("WMI event ID : 0x%4.4X, len = %d too big for IWEVCUSTOM (max=%d) \n", ++ eventId, size, IW_CUSTOM_MAX); ++ return; ++ } ++ ++ buf = A_MALLOC_NOWAIT(size); ++ A_MEMZERO(buf, size); ++ A_MEMCPY(buf, &eventId, EVENT_ID_LEN); ++ A_MEMCPY(buf+EVENT_ID_LEN, datap, len); ++ ++ //AR_DEBUG_PRINTF("event ID = %d,len = %d\n",*(A_UINT16*)buf, size); ++ A_MEMZERO(&wrqu, sizeof(wrqu)); ++ wrqu.data.length = size; ++ wireless_send_event(ar->arNetDev, IWEVCUSTOM, &wrqu, buf); ++ ++ A_FREE(buf); ++#endif ++ ++ ++} ++#endif ++ ++ ++void ++ar6000_tx_retry_err_event(void *devt) ++{ ++ AR_DEBUG2_PRINTF("Tx retries reach maximum!\n"); ++} ++ ++void ++ar6000_snrThresholdEvent_rx(void *devt, WMI_SNR_THRESHOLD_VAL newThreshold, A_UINT8 snr) ++{ ++ AR_DEBUG2_PRINTF("snr threshold range %d, snr %d\n", newThreshold, snr); ++} ++ ++void ++ar6000_lqThresholdEvent_rx(void *devt, WMI_LQ_THRESHOLD_VAL newThreshold, A_UINT8 lq) ++{ ++ AR_DEBUG2_PRINTF("lq threshold range %d, lq %d\n", newThreshold, lq); ++} ++ ++ ++ ++A_UINT32 ++a_copy_to_user(void *to, const void *from, A_UINT32 n) ++{ ++ return(copy_to_user(to, from, n)); ++} ++ ++A_UINT32 ++a_copy_from_user(void *to, const void *from, A_UINT32 n) ++{ ++ return(copy_from_user(to, from, n)); ++} ++ ++ ++A_STATUS ++ar6000_get_driver_cfg(struct net_device *dev, ++ A_UINT16 cfgParam, ++ void *result) ++{ ++ ++ A_STATUS ret = 0; ++ ++ switch(cfgParam) ++ { ++ case AR6000_DRIVER_CFG_GET_WLANNODECACHING: ++ *((A_UINT32 *)result) = wlanNodeCaching; ++ break; ++ case AR6000_DRIVER_CFG_LOG_RAW_WMI_MSGS: ++ *((A_UINT32 *)result) = logWmiRawMsgs; ++ break; ++ default: ++ ret = EINVAL; ++ break; ++ } ++ ++ return ret; ++} ++ ++void ++ar6000_keepalive_rx(void *devt, A_UINT8 configured) ++{ ++ AR_SOFTC_T *ar = (AR_SOFTC_T *)devt; ++ ++ ar->arKeepaliveConfigured = configured; ++ wake_up(&arEvent); ++} ++ ++void ++ar6000_pmkid_list_event(void *devt, A_UINT8 numPMKID, WMI_PMKID *pmkidList) ++{ ++ A_UINT8 i, j; ++ ++ A_PRINTF("Number of Cached PMKIDs is %d\n", numPMKID); ++ ++ for (i = 0; i < numPMKID; i++) { ++ A_PRINTF("\nPMKID %d ", i); ++ for (j = 0; j < WMI_PMKID_LEN; j++) { ++ A_PRINTF("%2.2x", pmkidList->pmkid[j]); ++ } ++ pmkidList++; ++ } ++} ++ ++#ifdef USER_KEYS ++static A_STATUS ++ ++ar6000_reinstall_keys(AR_SOFTC_T *ar, A_UINT8 key_op_ctrl) ++{ ++ A_STATUS status = A_OK; ++ struct ieee80211req_key *uik = &ar->user_saved_keys.ucast_ik; ++ struct ieee80211req_key *bik = &ar->user_saved_keys.bcast_ik; ++ CRYPTO_TYPE keyType = ar->user_saved_keys.keyType; ++ ++ if (IEEE80211_CIPHER_CCKM_KRK != uik->ik_type) { ++ if (NONE_CRYPT == keyType) { ++ goto _reinstall_keys_out; ++ } ++ ++ if (uik->ik_keylen) { ++ status = wmi_addKey_cmd(ar->arWmi, uik->ik_keyix, ++ ar->user_saved_keys.keyType, PAIRWISE_USAGE, ++ uik->ik_keylen, (A_UINT8 *)&uik->ik_keyrsc, ++ uik->ik_keydata, key_op_ctrl, SYNC_BEFORE_WMIFLAG); ++ } ++ ++ } else { ++ status = wmi_add_krk_cmd(ar->arWmi, uik->ik_keydata); ++ } ++ ++ if (IEEE80211_CIPHER_CCKM_KRK != bik->ik_type) { ++ if (NONE_CRYPT == keyType) { ++ goto _reinstall_keys_out; ++ } ++ ++ if (bik->ik_keylen) { ++ status = wmi_addKey_cmd(ar->arWmi, bik->ik_keyix, ++ ar->user_saved_keys.keyType, GROUP_USAGE, ++ bik->ik_keylen, (A_UINT8 *)&bik->ik_keyrsc, ++ bik->ik_keydata, key_op_ctrl, NO_SYNC_WMIFLAG); ++ } ++ } else { ++ status = wmi_add_krk_cmd(ar->arWmi, bik->ik_keydata); ++ } ++ ++_reinstall_keys_out: ++ ar->user_savedkeys_stat = USER_SAVEDKEYS_STAT_INIT; ++ ar->user_key_ctrl = 0; ++ ++ return status; ++} ++#endif /* USER_KEYS */ ++ ++ ++void ++ar6000_dset_open_req( ++ void *context, ++ A_UINT32 id, ++ A_UINT32 targHandle, ++ A_UINT32 targReplyFn, ++ A_UINT32 targReplyArg) ++{ ++} ++ ++void ++ar6000_dset_close( ++ void *context, ++ A_UINT32 access_cookie) ++{ ++ return; ++} ++ ++void ++ar6000_dset_data_req( ++ void *context, ++ A_UINT32 accessCookie, ++ A_UINT32 offset, ++ A_UINT32 length, ++ A_UINT32 targBuf, ++ A_UINT32 targReplyFn, ++ A_UINT32 targReplyArg) ++{ ++} +diff -ruN --exclude='*.orig' --exclude='*.rej' linux-2.6.29-rc3.owrt/drivers/ar6000/ar6000/ar6000_drv.h linux-2.6.29-rc3.owrt.om/drivers/ar6000/ar6000/ar6000_drv.h +--- linux-2.6.29-rc3.owrt/drivers/ar6000/ar6000/ar6000_drv.h 1970-01-01 01:00:00.000000000 +0100 ++++ linux-2.6.29-rc3.owrt.om/drivers/ar6000/ar6000/ar6000_drv.h 2009-05-10 22:27:59.000000000 +0200 +@@ -0,0 +1,360 @@ ++/* ++ * ++ * Copyright (c) 2004-2007 Atheros Communications Inc. ++ * All rights reserved. ++ * ++ * ++ * 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; ++ * ++ * Software distributed under the License is distributed on an "AS ++ * IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or ++ * implied. See the License for the specific language governing ++ * rights and limitations under the License. ++ * ++ * ++ * ++ */ ++ ++#ifndef _AR6000_H_ ++#define _AR6000_H_ ++ ++#include <linux/version.h> ++ ++ ++#include <linux/autoconf.h> ++#include <linux/init.h> ++#include <linux/kernel.h> ++#include <linux/spinlock.h> ++#include <linux/skbuff.h> ++#include <linux/if_ether.h> ++#include <linux/netdevice.h> ++#include <linux/etherdevice.h> ++#include <net/iw_handler.h> ++#include <linux/if_arp.h> ++#include <linux/ip.h> ++#include <linux/semaphore.h> ++#include <linux/wireless.h> ++#include <linux/module.h> ++#include <asm/io.h> ++ ++#include <a_config.h> ++#include <athdefs.h> ++#include "a_types.h" ++#include "a_osapi.h" ++#include "htc_api.h" ++#include "wmi.h" ++#include "a_drv.h" ++#include "bmi.h" ++#include <ieee80211.h> ++#include <ieee80211_ioctl.h> ++#include <wlan_api.h> ++#include <wmi_api.h> ++#include "gpio_api.h" ++#include "gpio.h" ++#include <host_version.h> ++#include <linux/rtnetlink.h> ++#include <linux/init.h> ++#include <linux/moduleparam.h> ++#include "AR6Khwreg.h" ++#include "ar6000_api.h" ++#ifdef CONFIG_HOST_TCMD_SUPPORT ++#include <testcmd.h> ++#endif ++ ++#include "targaddrs.h" ++#include "dbglog_api.h" ++#include "ar6000_diag.h" ++#include "common_drv.h" ++ ++#ifndef __dev_put ++#define __dev_put(dev) dev_put(dev) ++#endif ++ ++#ifdef USER_KEYS ++ ++#define USER_SAVEDKEYS_STAT_INIT 0 ++#define USER_SAVEDKEYS_STAT_RUN 1 ++ ++// TODO this needs to move into the AR_SOFTC struct ++struct USER_SAVEDKEYS { ++ struct ieee80211req_key ucast_ik; ++ struct ieee80211req_key bcast_ik; ++ CRYPTO_TYPE keyType; ++ A_BOOL keyOk; ++}; ++#endif ++ ++#define DBG_INFO 0x00000001 ++#define DBG_ERROR 0x00000002 ++#define DBG_WARNING 0x00000004 ++#define DBG_SDIO 0x00000008 ++#define DBG_HIF 0x00000010 ++#define DBG_HTC 0x00000020 ++#define DBG_WMI 0x00000040 ++#define DBG_WMI2 0x00000080 ++#define DBG_DRIVER 0x00000100 ++ ++#define DBG_DEFAULTS (DBG_ERROR|DBG_WARNING) ++ ++ ++#ifdef DEBUG ++#define AR_DEBUG_PRINTF(args...) if (debugdriver) A_PRINTF(args); ++#define AR_DEBUG2_PRINTF(args...) if (debugdriver >= 2) A_PRINTF(args); ++extern int debugdriver; ++#else ++#define AR_DEBUG_PRINTF(args...) ++#define AR_DEBUG2_PRINTF(args...) ++#endif ++ ++A_STATUS ar6000_ReadRegDiag(HIF_DEVICE *hifDevice, A_UINT32 *address, A_UINT32 *data); ++A_STATUS ar6000_WriteRegDiag(HIF_DEVICE *hifDevice, A_UINT32 *address, A_UINT32 *data); ++ ++#ifdef __cplusplus ++extern "C" { ++#endif ++ ++#define MAX_AR6000 1 ++#define AR6000_MAX_RX_BUFFERS 16 ++#define AR6000_BUFFER_SIZE 1664 ++#define AR6000_TX_TIMEOUT 10 ++#define AR6000_ETH_ADDR_LEN 6 ++#define AR6000_MAX_ENDPOINTS 4 ++#define MAX_NODE_NUM 15 ++#define MAX_COOKIE_NUM 150 ++#define AR6000_HB_CHALLENGE_RESP_FREQ_DEFAULT 1 ++#define AR6000_HB_CHALLENGE_RESP_MISS_THRES_DEFAULT 1 ++ ++enum { ++ DRV_HB_CHALLENGE = 0, ++ APP_HB_CHALLENGE ++}; ++ ++/* HTC RAW streams */ ++typedef enum _HTC_RAW_STREAM_ID { ++ HTC_RAW_STREAM_NOT_MAPPED = -1, ++ HTC_RAW_STREAM_0 = 0, ++ HTC_RAW_STREAM_1 = 1, ++ HTC_RAW_STREAM_2 = 2, ++ HTC_RAW_STREAM_3 = 3, ++ HTC_RAW_STREAM_NUM_MAX ++} HTC_RAW_STREAM_ID; ++ ++#define RAW_HTC_READ_BUFFERS_NUM 4 ++#define RAW_HTC_WRITE_BUFFERS_NUM 4 ++ ++typedef struct { ++ int currPtr; ++ int length; ++ unsigned char data[AR6000_BUFFER_SIZE]; ++ HTC_PACKET HTCPacket; ++} raw_htc_buffer; ++ ++#ifdef CONFIG_HOST_TCMD_SUPPORT ++/* ++ * add TCMD_MODE besides wmi and bypasswmi ++ * in TCMD_MODE, only few TCMD releated wmi commands ++ * counld be hanlder ++ */ ++enum { ++ AR6000_WMI_MODE = 0, ++ AR6000_BYPASS_MODE, ++ AR6000_TCMD_MODE, ++ AR6000_WLAN_MODE ++}; ++#endif /* CONFIG_HOST_TCMD_SUPPORT */ ++ ++struct ar_wep_key { ++ A_UINT8 arKeyIndex; ++ A_UINT8 arKeyLen; ++ A_UINT8 arKey[64]; ++} ; ++ ++struct ar_node_mapping { ++ A_UINT8 macAddress[6]; ++ A_UINT8 epId; ++ A_UINT8 txPending; ++}; ++ ++struct ar_cookie { ++ A_UINT32 arc_bp[2]; /* Must be first field */ ++ HTC_PACKET HtcPkt; /* HTC packet wrapper */ ++ struct ar_cookie *arc_list_next; ++}; ++ ++struct ar_hb_chlng_resp { ++ A_TIMER timer; ++ A_UINT32 frequency; ++ A_UINT32 seqNum; ++ A_BOOL outstanding; ++ A_UINT8 missCnt; ++ A_UINT8 missThres; ++}; ++ ++typedef struct ar6_softc { ++ struct net_device *arNetDev; /* net_device pointer */ ++ void *arWmi; ++ int arTxPending[WMI_PRI_MAX_COUNT]; ++ int arTotalTxDataPending; ++ A_UINT8 arNumDataEndPts; ++ A_BOOL arWmiEnabled; ++ A_BOOL arWmiReady; ++ A_BOOL arConnected; ++ A_BOOL arRadioSwitch; ++ HTC_HANDLE arHtcTarget; ++ void *arHifDevice; ++ spinlock_t arLock; ++ struct semaphore arSem; ++ int arRxBuffers[WMI_PRI_MAX_COUNT]; ++ int arSsidLen; ++ u_char arSsid[32]; ++ A_UINT8 arNetworkType; ++ A_UINT8 arDot11AuthMode; ++ A_UINT8 arAuthMode; ++ A_UINT8 arPairwiseCrypto; ++ A_UINT8 arPairwiseCryptoLen; ++ A_UINT8 arGroupCrypto; ++ A_UINT8 arGroupCryptoLen; ++ A_UINT8 arDefTxKeyIndex; ++ struct ar_wep_key arWepKeyList[WMI_MAX_KEY_INDEX + 1]; ++ A_UINT8 arBssid[6]; ++ A_UINT8 arReqBssid[6]; ++ A_UINT16 arChannelHint; ++ A_UINT16 arBssChannel; ++ A_UINT16 arListenInterval; ++ struct ar6000_version arVersion; ++ A_UINT32 arTargetType; ++ A_INT8 arRssi; ++ A_UINT8 arTxPwr; ++ A_BOOL arTxPwrSet; ++ A_INT32 arBitRate; ++ struct net_device_stats arNetStats; ++ struct iw_statistics arIwStats; ++ A_INT8 arNumChannels; ++ A_UINT16 arChannelList[32]; ++ A_UINT32 arRegCode; ++ A_BOOL statsUpdatePending; ++ TARGET_STATS arTargetStats; ++ A_INT8 arMaxRetries; ++ A_UINT8 arPhyCapability; ++#ifdef CONFIG_HOST_TCMD_SUPPORT ++ A_UINT8 tcmdRxReport; ++ A_UINT32 tcmdRxTotalPkt; ++ A_INT32 tcmdRxRssi; ++ A_UINT32 tcmdPm; ++ A_UINT32 arTargetMode; ++#endif ++ AR6000_WLAN_STATE arWlanState; ++ struct ar_node_mapping arNodeMap[MAX_NODE_NUM]; ++ A_UINT8 arIbssPsEnable; ++ A_UINT8 arNodeNum; ++ A_UINT8 arNexEpId; ++ struct ar_cookie *arCookieList; ++ A_UINT16 arRateMask; ++ A_UINT8 arSkipScan; ++ A_UINT16 arBeaconInterval; ++ A_BOOL arConnectPending; ++ A_BOOL arWmmEnabled; ++ struct ar_hb_chlng_resp arHBChallengeResp; ++ A_UINT8 arKeepaliveConfigured; ++ A_UINT32 arMgmtFilter; ++ HTC_ENDPOINT_ID arWmi2EpMapping[WMI_PRI_MAX_COUNT]; ++ WMI_PRI_STREAM_ID arEp2WmiMapping[ENDPOINT_MAX]; ++#ifdef HTC_RAW_INTERFACE ++ HTC_ENDPOINT_ID arRaw2EpMapping[HTC_RAW_STREAM_NUM_MAX]; ++ HTC_RAW_STREAM_ID arEp2RawMapping[ENDPOINT_MAX]; ++ struct semaphore raw_htc_read_sem[HTC_RAW_STREAM_NUM_MAX]; ++ struct semaphore raw_htc_write_sem[HTC_RAW_STREAM_NUM_MAX]; ++ wait_queue_head_t raw_htc_read_queue[HTC_RAW_STREAM_NUM_MAX]; ++ wait_queue_head_t raw_htc_write_queue[HTC_RAW_STREAM_NUM_MAX]; ++ raw_htc_buffer *raw_htc_read_buffer[HTC_RAW_STREAM_NUM_MAX][RAW_HTC_READ_BUFFERS_NUM]; ++ raw_htc_buffer *raw_htc_write_buffer[HTC_RAW_STREAM_NUM_MAX][RAW_HTC_WRITE_BUFFERS_NUM]; ++ A_BOOL write_buffer_available[HTC_RAW_STREAM_NUM_MAX]; ++ A_BOOL read_buffer_available[HTC_RAW_STREAM_NUM_MAX]; ++#endif ++ A_BOOL arRawIfInit; ++ int arDeviceIndex; ++ COMMON_CREDIT_STATE_INFO arCreditStateInfo; ++ A_BOOL arWMIControlEpFull; ++ A_BOOL dbgLogFetchInProgress; ++ A_UCHAR log_buffer[DBGLOG_HOST_LOG_BUFFER_SIZE]; ++ A_UINT32 log_cnt; ++ A_UINT32 dbglog_init_done; ++ A_UINT32 arConnectCtrlFlags; ++ A_UINT32 scan_complete; ++#ifdef USER_KEYS ++ A_INT32 user_savedkeys_stat; ++ A_UINT32 user_key_ctrl; ++ struct USER_SAVEDKEYS user_saved_keys; ++#endif ++} AR_SOFTC_T; ++ ++ ++#define arWMIStream2EndpointID(ar,wmi) (ar)->arWmi2EpMapping[(wmi)] ++#define arSetWMIStream2EndpointIDMap(ar,wmi,ep) \ ++{ (ar)->arWmi2EpMapping[(wmi)] = (ep); \ ++ (ar)->arEp2WmiMapping[(ep)] = (wmi); } ++#define arEndpoint2WMIStreamID(ar,ep) (ar)->arEp2WmiMapping[(ep)] ++ ++#define arRawIfEnabled(ar) (ar)->arRawIfInit ++#define arRawStream2EndpointID(ar,raw) (ar)->arRaw2EpMapping[(raw)] ++#define arSetRawStream2EndpointIDMap(ar,raw,ep) \ ++{ (ar)->arRaw2EpMapping[(raw)] = (ep); \ ++ (ar)->arEp2RawMapping[(ep)] = (raw); } ++#define arEndpoint2RawStreamID(ar,ep) (ar)->arEp2RawMapping[(ep)] ++ ++struct ar_giwscan_param { ++ char *current_ev; ++ char *end_buf; ++ A_BOOL firstPass; ++}; ++ ++#define AR6000_STAT_INC(ar, stat) (ar->arNetStats.stat++) ++ ++#define AR6000_SPIN_LOCK(lock, param) do { \ ++ if (irqs_disabled()) { \ ++ AR_DEBUG_PRINTF("IRQs disabled:AR6000_LOCK\n"); \ ++ } \ ++ spin_lock_bh(lock); \ ++} while (0) ++ ++#define AR6000_SPIN_UNLOCK(lock, param) do { \ ++ if (irqs_disabled()) { \ ++ AR_DEBUG_PRINTF("IRQs disabled: AR6000_UNLOCK\n"); \ ++ } \ ++ spin_unlock_bh(lock); \ ++} while (0) ++ ++int ar6000_ioctl(struct net_device *dev, struct ifreq *rq, int cmd); ++int ar6000_ioctl_dispatcher(struct net_device *dev, struct ifreq *rq, int cmd); ++void ar6000_ioctl_iwsetup(struct iw_handler_def *def); ++void ar6000_gpio_init(void); ++void ar6000_init_profile_info(AR_SOFTC_T *ar); ++void ar6000_install_static_wep_keys(AR_SOFTC_T *ar); ++int ar6000_init(struct net_device *dev); ++int ar6000_dbglog_get_debug_logs(AR_SOFTC_T *ar); ++A_STATUS ar6000_SetHTCBlockSize(AR_SOFTC_T *ar); ++ ++#ifdef HTC_RAW_INTERFACE ++ ++#ifndef __user ++#define __user ++#endif ++ ++int ar6000_htc_raw_open(AR_SOFTC_T *ar); ++int ar6000_htc_raw_close(AR_SOFTC_T *ar); ++ssize_t ar6000_htc_raw_read(AR_SOFTC_T *ar, ++ HTC_RAW_STREAM_ID StreamID, ++ char __user *buffer, size_t count); ++ssize_t ar6000_htc_raw_write(AR_SOFTC_T *ar, ++ HTC_RAW_STREAM_ID StreamID, ++ char __user *buffer, size_t count); ++ ++#endif /* HTC_RAW_INTERFACE */ ++ ++#ifdef __cplusplus ++} ++#endif ++ ++#endif /* _AR6000_H_ */ +diff -ruN --exclude='*.orig' --exclude='*.rej' linux-2.6.29-rc3.owrt/drivers/ar6000/ar6000/ar6000_raw_if.c linux-2.6.29-rc3.owrt.om/drivers/ar6000/ar6000/ar6000_raw_if.c +--- linux-2.6.29-rc3.owrt/drivers/ar6000/ar6000/ar6000_raw_if.c 1970-01-01 01:00:00.000000000 +0100 ++++ linux-2.6.29-rc3.owrt.om/drivers/ar6000/ar6000/ar6000_raw_if.c 2009-05-10 22:27:59.000000000 +0200 +@@ -0,0 +1,440 @@ ++/* ++ * ++ * Copyright (c) 2004-2007 Atheros Communications Inc. ++ * All rights reserved. ++ * ++ * ++ * 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; ++ * ++ * Software distributed under the License is distributed on an "AS ++ * IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or ++ * implied. See the License for the specific language governing ++ * rights and limitations under the License. ++ * ++ * ++ * ++ */ ++ ++#include "ar6000_drv.h" ++ ++#ifdef HTC_RAW_INTERFACE ++ ++static void ++ar6000_htc_raw_read_cb(void *Context, HTC_PACKET *pPacket) ++{ ++ AR_SOFTC_T *ar = (AR_SOFTC_T *)Context; ++ raw_htc_buffer *busy; ++ HTC_RAW_STREAM_ID streamID; ++ ++ busy = (raw_htc_buffer *)pPacket->pPktContext; ++ A_ASSERT(busy != NULL); ++ ++ if (pPacket->Status == A_ECANCELED) { ++ /* ++ * HTC provides A_ECANCELED status when it doesn't want to be refilled ++ * (probably due to a shutdown) ++ */ ++ return; ++ } ++ ++ streamID = arEndpoint2RawStreamID(ar,pPacket->Endpoint); ++ A_ASSERT(streamID != HTC_RAW_STREAM_NOT_MAPPED); ++ ++#ifdef CF ++ if (down_trylock(&ar->raw_htc_read_sem[streamID])) { ++#else ++ if (down_interruptible(&ar->raw_htc_read_sem[streamID])) { ++#endif /* CF */ ++ AR_DEBUG2_PRINTF("Unable to down the semaphore\n"); ++ } ++ ++ A_ASSERT((pPacket->Status != A_OK) || ++ (pPacket->pBuffer == (busy->data + HTC_HEADER_LEN))); ++ ++ busy->length = pPacket->ActualLength + HTC_HEADER_LEN; ++ busy->currPtr = HTC_HEADER_LEN; ++ ar->read_buffer_available[streamID] = TRUE; ++ //AR_DEBUG_PRINTF("raw read cb: 0x%X 0x%X \n", busy->currPtr,busy->length); ++ up(&ar->raw_htc_read_sem[streamID]); ++ ++ /* Signal the waiting process */ ++ AR_DEBUG2_PRINTF("Waking up the StreamID(%d) read process\n", streamID); ++ wake_up_interruptible(&ar->raw_htc_read_queue[streamID]); ++} ++ ++static void ++ar6000_htc_raw_write_cb(void *Context, HTC_PACKET *pPacket) ++{ ++ AR_SOFTC_T *ar = (AR_SOFTC_T *)Context; ++ raw_htc_buffer *free; ++ HTC_RAW_STREAM_ID streamID; ++ ++ free = (raw_htc_buffer *)pPacket->pPktContext; ++ A_ASSERT(free != NULL); ++ ++ if (pPacket->Status == A_ECANCELED) { ++ /* ++ * HTC provides A_ECANCELED status when it doesn't want to be refilled ++ * (probably due to a shutdown) ++ */ ++ return; ++ } ++ ++ streamID = arEndpoint2RawStreamID(ar,pPacket->Endpoint); ++ A_ASSERT(streamID != HTC_RAW_STREAM_NOT_MAPPED); ++ ++#ifdef CF ++ if (down_trylock(&ar->raw_htc_write_sem[streamID])) { ++#else ++ if (down_interruptible(&ar->raw_htc_write_sem[streamID])) { ++#endif ++ AR_DEBUG2_PRINTF("Unable to down the semaphore\n"); ++ } ++ ++ A_ASSERT(pPacket->pBuffer == (free->data + HTC_HEADER_LEN)); ++ ++ free->length = 0; ++ ar->write_buffer_available[streamID] = TRUE; ++ up(&ar->raw_htc_write_sem[streamID]); ++ ++ /* Signal the waiting process */ ++ AR_DEBUG2_PRINTF("Waking up the StreamID(%d) write process\n", streamID); ++ wake_up_interruptible(&ar->raw_htc_write_queue[streamID]); ++} ++ ++/* connect to a service */ ++static A_STATUS ar6000_connect_raw_service(AR_SOFTC_T *ar, ++ HTC_RAW_STREAM_ID StreamID) ++{ ++ A_STATUS status; ++ HTC_SERVICE_CONNECT_RESP response; ++ A_UINT8 streamNo; ++ HTC_SERVICE_CONNECT_REQ connect; ++ ++ do { ++ ++ A_MEMZERO(&connect,sizeof(connect)); ++ /* pass the stream ID as meta data to the RAW streams service */ ++ streamNo = (A_UINT8)StreamID; ++ connect.pMetaData = &streamNo; ++ connect.MetaDataLength = sizeof(A_UINT8); ++ /* these fields are the same for all endpoints */ ++ connect.EpCallbacks.pContext = ar; ++ connect.EpCallbacks.EpTxComplete = ar6000_htc_raw_write_cb; ++ connect.EpCallbacks.EpRecv = ar6000_htc_raw_read_cb; ++ /* simple interface, we don't need these optional callbacks */ ++ connect.EpCallbacks.EpRecvRefill = NULL; ++ connect.EpCallbacks.EpSendFull = NULL; ++ connect.EpCallbacks.EpSendAvail = NULL; ++ connect.MaxSendQueueDepth = RAW_HTC_WRITE_BUFFERS_NUM; ++ ++ /* connect to the raw streams service, we may be able to get 1 or more ++ * connections, depending on WHAT is running on the target */ ++ connect.ServiceID = HTC_RAW_STREAMS_SVC; ++ ++ A_MEMZERO(&response,sizeof(response)); ++ ++ /* try to connect to the raw stream, it is okay if this fails with ++ * status HTC_SERVICE_NO_MORE_EP */ ++ status = HTCConnectService(ar->arHtcTarget, ++ &connect, ++ &response); ++ ++ if (A_FAILED(status)) { ++ if (response.ConnectRespCode == HTC_SERVICE_NO_MORE_EP) { ++ AR_DEBUG_PRINTF("HTC RAW , No more streams allowed \n"); ++ status = A_OK; ++ } ++ break; ++ } ++ ++ /* set endpoint mapping for the RAW HTC streams */ ++ arSetRawStream2EndpointIDMap(ar,StreamID,response.Endpoint); ++ ++ AR_DEBUG_PRINTF("HTC RAW : stream ID: %d, endpoint: %d\n", ++ StreamID, arRawStream2EndpointID(ar,StreamID)); ++ ++ } while (FALSE); ++ ++ return status; ++} ++ ++int ar6000_htc_raw_open(AR_SOFTC_T *ar) ++{ ++ A_STATUS status; ++ int streamID, endPt, count2; ++ raw_htc_buffer *buffer; ++ HTC_SERVICE_ID servicepriority; ++ ++ A_ASSERT(ar->arHtcTarget != NULL); ++ ++ /* wait for target */ ++ status = HTCWaitTarget(ar->arHtcTarget); ++ ++ if (A_FAILED(status)) { ++ AR_DEBUG_PRINTF("HTCWaitTarget failed (%d)\n", status); ++ return -ENODEV; ++ } ++ ++ for (endPt = 0; endPt < ENDPOINT_MAX; endPt++) { ++ ar->arEp2RawMapping[endPt] = HTC_RAW_STREAM_NOT_MAPPED; ++ } ++ ++ for (streamID = HTC_RAW_STREAM_0; streamID < HTC_RAW_STREAM_NUM_MAX; streamID++) { ++ /* Initialize the data structures */ ++ init_MUTEX(&ar->raw_htc_read_sem[streamID]); ++ init_MUTEX(&ar->raw_htc_write_sem[streamID]); ++ init_waitqueue_head(&ar->raw_htc_read_queue[streamID]); ++ init_waitqueue_head(&ar->raw_htc_write_queue[streamID]); ++ ++ /* try to connect to the raw service */ ++ status = ar6000_connect_raw_service(ar,streamID); ++ ++ if (A_FAILED(status)) { ++ break; ++ } ++ ++ if (arRawStream2EndpointID(ar,streamID) == 0) { ++ break; ++ } ++ ++ for (count2 = 0; count2 < RAW_HTC_READ_BUFFERS_NUM; count2 ++) { ++ /* Initialize the receive buffers */ ++ buffer = ar->raw_htc_write_buffer[streamID][count2]; ++ memset(buffer, 0, sizeof(raw_htc_buffer)); ++ buffer = ar->raw_htc_read_buffer[streamID][count2]; ++ memset(buffer, 0, sizeof(raw_htc_buffer)); ++ ++ SET_HTC_PACKET_INFO_RX_REFILL(&buffer->HTCPacket, ++ buffer, ++ buffer->data, ++ AR6000_BUFFER_SIZE, ++ arRawStream2EndpointID(ar,streamID)); ++ ++ /* Queue buffers to HTC for receive */ ++ if ((status = HTCAddReceivePkt(ar->arHtcTarget, &buffer->HTCPacket)) != A_OK) ++ { ++ BMIInit(); ++ return -EIO; ++ } ++ } ++ ++ for (count2 = 0; count2 < RAW_HTC_WRITE_BUFFERS_NUM; count2 ++) { ++ /* Initialize the receive buffers */ ++ buffer = ar->raw_htc_write_buffer[streamID][count2]; ++ memset(buffer, 0, sizeof(raw_htc_buffer)); ++ } ++ ++ ar->read_buffer_available[streamID] = FALSE; ++ ar->write_buffer_available[streamID] = TRUE; ++ } ++ ++ if (A_FAILED(status)) { ++ return -EIO; ++ } ++ ++ AR_DEBUG_PRINTF("HTC RAW, number of streams the target supports: %d \n", streamID); ++ ++ servicepriority = HTC_RAW_STREAMS_SVC; /* only 1 */ ++ ++ /* set callbacks and priority list */ ++ HTCSetCreditDistribution(ar->arHtcTarget, ++ ar, ++ NULL, /* use default */ ++ NULL, /* use default */ ++ &servicepriority, ++ 1); ++ ++ /* Start the HTC component */ ++ if ((status = HTCStart(ar->arHtcTarget)) != A_OK) { ++ BMIInit(); ++ return -EIO; ++ } ++ ++ (ar)->arRawIfInit = TRUE; ++ ++ return 0; ++} ++ ++int ar6000_htc_raw_close(AR_SOFTC_T *ar) ++{ ++ A_PRINTF("ar6000_htc_raw_close called \n"); ++ HTCStop(ar->arHtcTarget); ++ ++ /* reset the device */ ++ ar6000_reset_device(ar->arHifDevice, ar->arTargetType); ++ /* Initialize the BMI component */ ++ BMIInit(); ++ ++ return 0; ++} ++ ++raw_htc_buffer * ++get_filled_buffer(AR_SOFTC_T *ar, HTC_RAW_STREAM_ID StreamID) ++{ ++ int count; ++ raw_htc_buffer *busy; ++ ++ /* Check for data */ ++ for (count = 0; count < RAW_HTC_READ_BUFFERS_NUM; count ++) { ++ busy = ar->raw_htc_read_buffer[StreamID][count]; ++ if (busy->length) { ++ break; ++ } ++ } ++ if (busy->length) { ++ ar->read_buffer_available[StreamID] = TRUE; ++ } else { ++ ar->read_buffer_available[StreamID] = FALSE; ++ } ++ ++ return busy; ++} ++ ++ssize_t ar6000_htc_raw_read(AR_SOFTC_T *ar, HTC_RAW_STREAM_ID StreamID, ++ char __user *buffer, size_t length) ++{ ++ int readPtr; ++ raw_htc_buffer *busy; ++ ++ if (arRawStream2EndpointID(ar,StreamID) == 0) { ++ AR_DEBUG_PRINTF("StreamID(%d) not connected! \n", StreamID); ++ return -EFAULT; ++ } ++ ++ if (down_interruptible(&ar->raw_htc_read_sem[StreamID])) { ++ return -ERESTARTSYS; ++ } ++ ++ busy = get_filled_buffer(ar,StreamID); ++ while (!ar->read_buffer_available[StreamID]) { ++ up(&ar->raw_htc_read_sem[StreamID]); ++ ++ /* Wait for the data */ ++ AR_DEBUG2_PRINTF("Sleeping StreamID(%d) read process\n", StreamID); ++ if (wait_event_interruptible(ar->raw_htc_read_queue[StreamID], ++ ar->read_buffer_available[StreamID])) ++ { ++ return -EINTR; ++ } ++ if (down_interruptible(&ar->raw_htc_read_sem[StreamID])) { ++ return -ERESTARTSYS; ++ } ++ busy = get_filled_buffer(ar,StreamID); ++ } ++ ++ /* Read the data */ ++ readPtr = busy->currPtr; ++ if (length > busy->length - HTC_HEADER_LEN) { ++ length = busy->length - HTC_HEADER_LEN; ++ } ++ if (copy_to_user(buffer, &busy->data[readPtr], length)) { ++ up(&ar->raw_htc_read_sem[StreamID]); ++ return -EFAULT; ++ } ++ ++ busy->currPtr += length; ++ ++ //AR_DEBUG_PRINTF("raw read ioctl: currPTR : 0x%X 0x%X \n", busy->currPtr,busy->length); ++ ++ if (busy->currPtr == busy->length) ++ { ++ busy->currPtr = 0; ++ busy->length = 0; ++ HTC_PACKET_RESET_RX(&busy->HTCPacket); ++ //AR_DEBUG_PRINTF("raw read ioctl: ep for packet:%d \n", busy->HTCPacket.Endpoint); ++ HTCAddReceivePkt(ar->arHtcTarget, &busy->HTCPacket); ++ } ++ ar->read_buffer_available[StreamID] = FALSE; ++ up(&ar->raw_htc_read_sem[StreamID]); ++ ++ return length; ++} ++ ++static raw_htc_buffer * ++get_free_buffer(AR_SOFTC_T *ar, HTC_ENDPOINT_ID StreamID) ++{ ++ int count; ++ raw_htc_buffer *free; ++ ++ free = NULL; ++ for (count = 0; count < RAW_HTC_WRITE_BUFFERS_NUM; count ++) { ++ free = ar->raw_htc_write_buffer[StreamID][count]; ++ if (free->length == 0) { ++ break; ++ } ++ } ++ if (!free->length) { ++ ar->write_buffer_available[StreamID] = TRUE; ++ } else { ++ ar->write_buffer_available[StreamID] = FALSE; ++ } ++ ++ return free; ++} ++ ++ssize_t ar6000_htc_raw_write(AR_SOFTC_T *ar, HTC_RAW_STREAM_ID StreamID, ++ char __user *buffer, size_t length) ++{ ++ int writePtr; ++ raw_htc_buffer *free; ++ ++ if (arRawStream2EndpointID(ar,StreamID) == 0) { ++ AR_DEBUG_PRINTF("StreamID(%d) not connected! \n", StreamID); ++ return -EFAULT; ++ } ++ ++ if (down_interruptible(&ar->raw_htc_write_sem[StreamID])) { ++ return -ERESTARTSYS; ++ } ++ ++ /* Search for a free buffer */ ++ free = get_free_buffer(ar,StreamID); ++ ++ /* Check if there is space to write else wait */ ++ while (!ar->write_buffer_available[StreamID]) { ++ up(&ar->raw_htc_write_sem[StreamID]); ++ ++ /* Wait for buffer to become free */ ++ AR_DEBUG2_PRINTF("Sleeping StreamID(%d) write process\n", StreamID); ++ if (wait_event_interruptible(ar->raw_htc_write_queue[StreamID], ++ ar->write_buffer_available[StreamID])) ++ { ++ return -EINTR; ++ } ++ if (down_interruptible(&ar->raw_htc_write_sem[StreamID])) { ++ return -ERESTARTSYS; ++ } ++ free = get_free_buffer(ar,StreamID); ++ } ++ ++ /* Send the data */ ++ writePtr = HTC_HEADER_LEN; ++ if (length > (AR6000_BUFFER_SIZE - HTC_HEADER_LEN)) { ++ length = AR6000_BUFFER_SIZE - HTC_HEADER_LEN; ++ } ++ ++ if (copy_from_user(&free->data[writePtr], buffer, length)) { ++ up(&ar->raw_htc_read_sem[StreamID]); ++ return -EFAULT; ++ } ++ ++ free->length = length; ++ ++ SET_HTC_PACKET_INFO_TX(&free->HTCPacket, ++ free, ++ &free->data[writePtr], ++ length, ++ arRawStream2EndpointID(ar,StreamID), ++ AR6K_DATA_PKT_TAG); ++ ++ HTCSendPkt(ar->arHtcTarget,&free->HTCPacket); ++ ++ ar->write_buffer_available[StreamID] = FALSE; ++ up(&ar->raw_htc_write_sem[StreamID]); ++ ++ return length; ++} ++#endif /* HTC_RAW_INTERFACE */ +diff -ruN --exclude='*.orig' --exclude='*.rej' linux-2.6.29-rc3.owrt/drivers/ar6000/ar6000/ar6xapi_linux.h linux-2.6.29-rc3.owrt.om/drivers/ar6000/ar6000/ar6xapi_linux.h +--- linux-2.6.29-rc3.owrt/drivers/ar6000/ar6000/ar6xapi_linux.h 1970-01-01 01:00:00.000000000 +0100 ++++ linux-2.6.29-rc3.owrt.om/drivers/ar6000/ar6000/ar6xapi_linux.h 2009-05-10 22:27:59.000000000 +0200 +@@ -0,0 +1,128 @@ ++#ifndef _AR6XAPI_LINUX_H ++#define _AR6XAPI_LINUX_H ++/* ++ * ++ * Copyright (c) 2004-2007 Atheros Communications Inc. ++ * All rights reserved. ++ * ++ * ++ * 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; ++ * ++ * Software distributed under the License is distributed on an "AS ++ * IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or ++ * implied. See the License for the specific language governing ++ * rights and limitations under the License. ++ * ++ * ++ * ++ */ ++ ++#ifdef __cplusplus ++extern "C" { ++#endif ++ ++struct ar6_softc; ++ ++void ar6000_ready_event(void *devt, A_UINT8 *datap, A_UINT8 phyCap); ++A_UINT8 ar6000_iptos_to_userPriority(A_UINT8 *pkt); ++A_STATUS ar6000_control_tx(void *devt, void *osbuf, WMI_PRI_STREAM_ID streamID); ++void ar6000_connect_event(struct ar6_softc *ar, A_UINT16 channel, ++ A_UINT8 *bssid, A_UINT16 listenInterval, ++ A_UINT16 beaconInterval, NETWORK_TYPE networkType, ++ A_UINT8 beaconIeLen, A_UINT8 assocReqLen, ++ A_UINT8 assocRespLen,A_UINT8 *assocInfo); ++void ar6000_disconnect_event(struct ar6_softc *ar, A_UINT8 reason, ++ A_UINT8 *bssid, A_UINT8 assocRespLen, ++ A_UINT8 *assocInfo, A_UINT16 protocolReasonStatus); ++void ar6000_tkip_micerr_event(struct ar6_softc *ar, A_UINT8 keyid, ++ A_BOOL ismcast); ++void ar6000_bitrate_rx(void *devt, A_INT32 rateKbps); ++void ar6000_channelList_rx(void *devt, A_INT8 numChan, A_UINT16 *chanList); ++void ar6000_regDomain_event(struct ar6_softc *ar, A_UINT32 regCode); ++void ar6000_txPwr_rx(void *devt, A_UINT8 txPwr); ++void ar6000_keepalive_rx(void *devt, A_UINT8 configured); ++void ar6000_neighborReport_event(struct ar6_softc *ar, int numAps, ++ WMI_NEIGHBOR_INFO *info); ++void ar6000_set_numdataendpts(struct ar6_softc *ar, A_UINT32 num); ++void ar6000_scanComplete_event(struct ar6_softc *ar, A_STATUS status); ++void ar6000_targetStats_event(struct ar6_softc *ar, WMI_TARGET_STATS *pStats); ++void ar6000_rssiThreshold_event(struct ar6_softc *ar, ++ WMI_RSSI_THRESHOLD_VAL newThreshold, ++ A_INT16 rssi); ++void ar6000_reportError_event(struct ar6_softc *, WMI_TARGET_ERROR_VAL errorVal); ++void ar6000_cac_event(struct ar6_softc *ar, A_UINT8 ac, A_UINT8 cac_indication, ++ A_UINT8 statusCode, A_UINT8 *tspecSuggestion); ++void ar6000_hbChallengeResp_event(struct ar6_softc *, A_UINT32 cookie, A_UINT32 source); ++void ++ar6000_roam_tbl_event(struct ar6_softc *ar, WMI_TARGET_ROAM_TBL *pTbl); ++ ++void ++ar6000_roam_data_event(struct ar6_softc *ar, WMI_TARGET_ROAM_DATA *p); ++ ++void ++ar6000_wow_list_event(struct ar6_softc *ar, A_UINT8 num_filters, ++ WMI_GET_WOW_LIST_REPLY *wow_reply); ++ ++void ar6000_pmkid_list_event(void *devt, A_UINT8 numPMKID, ++ WMI_PMKID *pmkidList); ++ ++void ar6000_gpio_intr_rx(A_UINT32 intr_mask, A_UINT32 input_values); ++void ar6000_gpio_data_rx(A_UINT32 reg_id, A_UINT32 value); ++void ar6000_gpio_ack_rx(void); ++ ++void ar6000_dbglog_init_done(struct ar6_softc *ar); ++ ++#ifdef SEND_EVENT_TO_APP ++void ar6000_send_event_to_app(struct ar6_softc *ar, A_UINT16 eventId, A_UINT8 *datap, int len); ++#endif ++ ++#ifdef CONFIG_HOST_TCMD_SUPPORT ++void ar6000_tcmd_rx_report_event(void *devt, A_UINT8 * results, int len); ++#endif ++ ++void ar6000_tx_retry_err_event(void *devt); ++ ++void ar6000_snrThresholdEvent_rx(void *devt, ++ WMI_SNR_THRESHOLD_VAL newThreshold, ++ A_UINT8 snr); ++ ++void ar6000_lqThresholdEvent_rx(void *devt, WMI_LQ_THRESHOLD_VAL range, A_UINT8 lqVal); ++ ++ ++void ar6000_ratemask_rx(void *devt, A_UINT16 ratemask); ++ ++A_STATUS ar6000_get_driver_cfg(struct net_device *dev, ++ A_UINT16 cfgParam, ++ void *result); ++void ar6000_bssInfo_event_rx(struct ar6_softc *ar, A_UINT8 *data, int len); ++ ++void ar6000_dbglog_event(struct ar6_softc *ar, A_UINT32 dropped, ++ A_INT8 *buffer, A_UINT32 length); ++ ++int ar6000_dbglog_get_debug_logs(struct ar6_softc *ar); ++ ++void ar6000_indicate_tx_activity(void *devt, A_UINT8 trafficClass, A_BOOL Active); ++ ++void ar6000_dset_open_req(void *devt, ++ A_UINT32 id, ++ A_UINT32 targ_handle, ++ A_UINT32 targ_reply_fn, ++ A_UINT32 targ_reply_arg); ++void ar6000_dset_close(void *devt, A_UINT32 access_cookie); ++void ar6000_dset_data_req(void *devt, ++ A_UINT32 access_cookie, ++ A_UINT32 offset, ++ A_UINT32 length, ++ A_UINT32 targ_buf, ++ A_UINT32 targ_reply_fn, ++ A_UINT32 targ_reply_arg); ++ ++ ++ ++#ifdef __cplusplus ++} ++#endif ++ ++#endif +diff -ruN --exclude='*.orig' --exclude='*.rej' linux-2.6.29-rc3.owrt/drivers/ar6000/ar6000/athdrv_linux.h linux-2.6.29-rc3.owrt.om/drivers/ar6000/ar6000/athdrv_linux.h +--- linux-2.6.29-rc3.owrt/drivers/ar6000/ar6000/athdrv_linux.h 1970-01-01 01:00:00.000000000 +0100 ++++ linux-2.6.29-rc3.owrt.om/drivers/ar6000/ar6000/athdrv_linux.h 2009-05-10 22:27:59.000000000 +0200 +@@ -0,0 +1,993 @@ ++/* ++ * Copyright (c) 2004-2006 Atheros Communications Inc. ++ * All rights reserved. ++ * ++ * ++ * ++ * 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; ++ * ++ * Software distributed under the License is distributed on an "AS ++ * IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or ++ * implied. See the License for the specific language governing ++ * rights and limitations under the License. ++ * ++ * ++ * ++ */ ++ ++#ifndef _ATHDRV_LINUX_H ++#define _ATHDRV_LINUX_H ++ ++#ifdef __cplusplus ++extern "C" { ++#endif ++ ++ ++/* ++ * There are two types of ioctl's here: Standard ioctls and ++ * eXtended ioctls. All extended ioctls (XIOCTL) are multiplexed ++ * off of the single ioctl command, AR6000_IOCTL_EXTENDED. The ++ * arguments for every XIOCTL starts with a 32-bit command word ++ * that is used to select which extended ioctl is in use. After ++ * the command word are command-specific arguments. ++ */ ++ ++/* Linux standard Wireless Extensions, private ioctl interfaces */ ++#define IEEE80211_IOCTL_SETPARAM (SIOCIWFIRSTPRIV+0) ++#define IEEE80211_IOCTL_GETPARAM (SIOCIWFIRSTPRIV+1) ++#define IEEE80211_IOCTL_SETKEY (SIOCIWFIRSTPRIV+2) ++#define IEEE80211_IOCTL_SETWMMPARAMS (SIOCIWFIRSTPRIV+3) ++#define IEEE80211_IOCTL_DELKEY (SIOCIWFIRSTPRIV+4) ++#define IEEE80211_IOCTL_GETWMMPARAMS (SIOCIWFIRSTPRIV+5) ++#define IEEE80211_IOCTL_SETOPTIE (SIOCIWFIRSTPRIV+6) ++#define IEEE80211_IOCTL_SETMLME (SIOCIWFIRSTPRIV+7) ++//#define IEEE80211_IOCTL_GETOPTIE (SIOCIWFIRSTPRIV+7) ++#define IEEE80211_IOCTL_ADDPMKID (SIOCIWFIRSTPRIV+8) ++//#define IEEE80211_IOCTL_SETAUTHALG (SIOCIWFIRSTPRIV+10) ++#define IEEE80211_IOCTL_LASTONE (SIOCIWFIRSTPRIV+9) ++ ++ ++ ++/* ====WMI Ioctls==== */ ++/* ++ * ++ * Many ioctls simply provide WMI services to application code: ++ * an application makes such an ioctl call with a set of arguments ++ * that are packaged into the corresponding WMI message, and sent ++ * to the Target. ++ */ ++ ++#define AR6000_IOCTL_WMI_GETREV (SIOCIWFIRSTPRIV+10) ++/* ++ * arguments: ++ * ar6000_version *revision ++ */ ++ ++#define AR6000_IOCTL_WMI_SETPWR (SIOCIWFIRSTPRIV+11) ++/* ++ * arguments: ++ * WMI_POWER_MODE_CMD pwrModeCmd (see include/wmi.h) ++ * uses: WMI_SET_POWER_MODE_CMDID ++ */ ++ ++#define AR6000_IOCTL_WMI_SETSCAN (SIOCIWFIRSTPRIV+12) ++/* ++ * arguments: ++ * WMI_SCAN_PARAMS_CMD scanParams (see include/wmi.h) ++ * uses: WMI_SET_SCAN_PARAMS_CMDID ++ */ ++ ++#define AR6000_IOCTL_WMI_SETLISTENINT (SIOCIWFIRSTPRIV+13) ++/* ++ * arguments: ++ * UINT32 listenInterval ++ * uses: WMI_SET_LISTEN_INT_CMDID ++ */ ++ ++#define AR6000_IOCTL_WMI_SETBSSFILTER (SIOCIWFIRSTPRIV+14) ++/* ++ * arguments: ++ * WMI_BSS_FILTER filter (see include/wmi.h) ++ * uses: WMI_SET_BSS_FILTER_CMDID ++ */ ++ ++#define AR6000_IOCTL_WMI_SET_CHANNELPARAMS (SIOCIWFIRSTPRIV+16) ++/* ++ * arguments: ++ * WMI_CHANNEL_PARAMS_CMD chParams ++ * uses: WMI_SET_CHANNEL_PARAMS_CMDID ++ */ ++ ++#define AR6000_IOCTL_WMI_SET_PROBEDSSID (SIOCIWFIRSTPRIV+17) ++/* ++ * arguments: ++ * WMI_PROBED_SSID_CMD probedSsids (see include/wmi.h) ++ * uses: WMI_SETPROBED_SSID_CMDID ++ */ ++ ++#define AR6000_IOCTL_WMI_SET_PMPARAMS (SIOCIWFIRSTPRIV+18) ++/* ++ * arguments: ++ * WMI_POWER_PARAMS_CMD powerParams (see include/wmi.h) ++ * uses: WMI_SET_POWER_PARAMS_CMDID ++ */ ++ ++#define AR6000_IOCTL_WMI_SET_BADAP (SIOCIWFIRSTPRIV+19) ++/* ++ * arguments: ++ * WMI_ADD_BAD_AP_CMD badAPs (see include/wmi.h) ++ * uses: WMI_ADD_BAD_AP_CMDID ++ */ ++ ++#define AR6000_IOCTL_WMI_GET_QOS_QUEUE (SIOCIWFIRSTPRIV+20) ++/* ++ * arguments: ++ * ar6000_queuereq queueRequest (see below) ++ */ ++ ++#define AR6000_IOCTL_WMI_CREATE_QOS (SIOCIWFIRSTPRIV+21) ++/* ++ * arguments: ++ * WMI_CREATE_PSTREAM createPstreamCmd (see include/wmi.h) ++ * uses: WMI_CREATE_PSTREAM_CMDID ++ */ ++ ++#define AR6000_IOCTL_WMI_DELETE_QOS (SIOCIWFIRSTPRIV+22) ++/* ++ * arguments: ++ * WMI_DELETE_PSTREAM_CMD deletePstreamCmd (see include/wmi.h) ++ * uses: WMI_DELETE_PSTREAM_CMDID ++ */ ++ ++#define AR6000_IOCTL_WMI_SET_SNRTHRESHOLD (SIOCIWFIRSTPRIV+23) ++/* ++ * arguments: ++ * WMI_SNR_THRESHOLD_PARAMS_CMD thresholdParams (see include/wmi.h) ++ * uses: WMI_SNR_THRESHOLD_PARAMS_CMDID ++ */ ++ ++#define AR6000_IOCTL_WMI_SET_ERROR_REPORT_BITMASK (SIOCIWFIRSTPRIV+24) ++/* ++ * arguments: ++ * WMI_TARGET_ERROR_REPORT_BITMASK errorReportBitMask (see include/wmi.h) ++ * uses: WMI_TARGET_ERROR_REPORT_BITMASK_CMDID ++ */ ++ ++#define AR6000_IOCTL_WMI_GET_TARGET_STATS (SIOCIWFIRSTPRIV+25) ++/* ++ * arguments: ++ * TARGET_STATS *targetStats (see below) ++ * uses: WMI_GET_STATISTICS_CMDID ++ */ ++ ++#define AR6000_IOCTL_WMI_SET_ASSOC_INFO (SIOCIWFIRSTPRIV+26) ++/* ++ * arguments: ++ * WMI_SET_ASSOC_INFO_CMD setAssocInfoCmd ++ * uses: WMI_SET_ASSOC_INFO_CMDID ++ */ ++ ++#define AR6000_IOCTL_WMI_SET_ACCESS_PARAMS (SIOCIWFIRSTPRIV+27) ++/* ++ * arguments: ++ * WMI_SET_ACCESS_PARAMS_CMD setAccessParams (see include/wmi.h) ++ * uses: WMI_SET_ACCESS_PARAMS_CMDID ++ */ ++ ++#define AR6000_IOCTL_WMI_SET_BMISS_TIME (SIOCIWFIRSTPRIV+28) ++/* ++ * arguments: ++ * UINT32 beaconMissTime ++ * uses: WMI_SET_BMISS_TIME_CMDID ++ */ ++ ++#define AR6000_IOCTL_WMI_SET_DISC_TIMEOUT (SIOCIWFIRSTPRIV+29) ++/* ++ * arguments: ++ * WMI_DISC_TIMEOUT_CMD disconnectTimeoutCmd (see include/wmi.h) ++ * uses: WMI_SET_DISC_TIMEOUT_CMDID ++ */ ++ ++#define AR6000_IOCTL_WMI_SET_IBSS_PM_CAPS (SIOCIWFIRSTPRIV+30) ++/* ++ * arguments: ++ * WMI_IBSS_PM_CAPS_CMD ibssPowerMgmtCapsCmd ++ * uses: WMI_SET_IBSS_PM_CAPS_CMDID ++ */ ++ ++/* ++ * There is a very small space available for driver-private ++ * wireless ioctls. In order to circumvent this limitation, ++ * we multiplex a bunch of ioctls (XIOCTLs) on top of a ++ * single AR6000_IOCTL_EXTENDED ioctl. ++ */ ++#define AR6000_IOCTL_EXTENDED (SIOCIWFIRSTPRIV+31) ++ ++ ++/* ====BMI Extended Ioctls==== */ ++ ++#define AR6000_XIOCTL_BMI_DONE 1 ++/* ++ * arguments: ++ * UINT32 cmd (AR6000_XIOCTL_BMI_DONE) ++ * uses: BMI_DONE ++ */ ++ ++#define AR6000_XIOCTL_BMI_READ_MEMORY 2 ++/* ++ * arguments: ++ * union { ++ * struct { ++ * UINT32 cmd (AR6000_XIOCTL_BMI_READ_MEMORY) ++ * UINT32 address ++ * UINT32 length ++ * } ++ * char results[length] ++ * } ++ * uses: BMI_READ_MEMORY ++ */ ++ ++#define AR6000_XIOCTL_BMI_WRITE_MEMORY 3 ++/* ++ * arguments: ++ * UINT32 cmd (AR6000_XIOCTL_BMI_WRITE_MEMORY) ++ * UINT32 address ++ * UINT32 length ++ * char data[length] ++ * uses: BMI_WRITE_MEMORY ++ */ ++ ++#define AR6000_XIOCTL_BMI_EXECUTE 4 ++/* ++ * arguments: ++ * UINT32 cmd (AR6000_XIOCTL_BMI_EXECUTE) ++ * UINT32 TargetAddress ++ * UINT32 parameter ++ * uses: BMI_EXECUTE ++ */ ++ ++#define AR6000_XIOCTL_BMI_SET_APP_START 5 ++/* ++ * arguments: ++ * UINT32 cmd (AR6000_XIOCTL_BMI_SET_APP_START) ++ * UINT32 TargetAddress ++ * uses: BMI_SET_APP_START ++ */ ++ ++#define AR6000_XIOCTL_BMI_READ_SOC_REGISTER 6 ++/* ++ * arguments: ++ * union { ++ * struct { ++ * UINT32 cmd (AR6000_XIOCTL_BMI_READ_SOC_REGISTER) ++ * UINT32 TargetAddress, 32-bit aligned ++ * } ++ * UINT32 result ++ * } ++ * uses: BMI_READ_SOC_REGISTER ++ */ ++ ++#define AR6000_XIOCTL_BMI_WRITE_SOC_REGISTER 7 ++/* ++ * arguments: ++ * struct { ++ * UINT32 cmd (AR6000_XIOCTL_BMI_WRITE_SOC_REGISTER) ++ * UINT32 TargetAddress, 32-bit aligned ++ * UINT32 newValue ++ * } ++ * uses: BMI_WRITE_SOC_REGISTER ++ */ ++ ++#define AR6000_XIOCTL_BMI_TEST 8 ++/* ++ * arguments: ++ * UINT32 cmd (AR6000_XIOCTL_BMI_TEST) ++ * UINT32 address ++ * UINT32 length ++ * UINT32 count ++ */ ++ ++ ++ ++/* Historical Host-side DataSet support */ ++#define AR6000_XIOCTL_UNUSED9 9 ++#define AR6000_XIOCTL_UNUSED10 10 ++#define AR6000_XIOCTL_UNUSED11 11 ++ ++/* ====Misc Extended Ioctls==== */ ++ ++#define AR6000_XIOCTL_FORCE_TARGET_RESET 12 ++/* ++ * arguments: ++ * UINT32 cmd (AR6000_XIOCTL_FORCE_TARGET_RESET) ++ */ ++ ++ ++#ifdef HTC_RAW_INTERFACE ++/* HTC Raw Interface Ioctls */ ++#define AR6000_XIOCTL_HTC_RAW_OPEN 13 ++/* ++ * arguments: ++ * UINT32 cmd (AR6000_XIOCTL_HTC_RAW_OPEN) ++ */ ++ ++#define AR6000_XIOCTL_HTC_RAW_CLOSE 14 ++/* ++ * arguments: ++ * UINT32 cmd (AR6000_XIOCTL_HTC_RAW_CLOSE) ++ */ ++ ++#define AR6000_XIOCTL_HTC_RAW_READ 15 ++/* ++ * arguments: ++ * union { ++ * struct { ++ * UINT32 cmd (AR6000_XIOCTL_HTC_RAW_READ) ++ * UINT32 mailboxID ++ * UINT32 length ++ * } ++ * results[length] ++ * } ++ */ ++ ++#define AR6000_XIOCTL_HTC_RAW_WRITE 16 ++/* ++ * arguments: ++ * UINT32 cmd (AR6000_XIOCTL_HTC_RAW_WRITE) ++ * UINT32 mailboxID ++ * UINT32 length ++ * char buffer[length] ++ */ ++#endif /* HTC_RAW_INTERFACE */ ++ ++#define AR6000_XIOCTL_CHECK_TARGET_READY 17 ++/* ++ * arguments: ++ * UINT32 cmd (AR6000_XIOCTL_CHECK_TARGET_READY) ++ */ ++ ++ ++ ++/* ====GPIO (General Purpose I/O) Extended Ioctls==== */ ++ ++#define AR6000_XIOCTL_GPIO_OUTPUT_SET 18 ++/* ++ * arguments: ++ * UINT32 cmd (AR6000_XIOCTL_GPIO_OUTPUT_SET) ++ * ar6000_gpio_output_set_cmd_s (see below) ++ * uses: WMIX_GPIO_OUTPUT_SET_CMDID ++ */ ++ ++#define AR6000_XIOCTL_GPIO_INPUT_GET 19 ++/* ++ * arguments: ++ * UINT32 cmd (AR6000_XIOCTL_GPIO_INPUT_GET) ++ * uses: WMIX_GPIO_INPUT_GET_CMDID ++ */ ++ ++#define AR6000_XIOCTL_GPIO_REGISTER_SET 20 ++/* ++ * arguments: ++ * UINT32 cmd (AR6000_XIOCTL_GPIO_REGISTER_SET) ++ * ar6000_gpio_register_cmd_s (see below) ++ * uses: WMIX_GPIO_REGISTER_SET_CMDID ++ */ ++ ++#define AR6000_XIOCTL_GPIO_REGISTER_GET 21 ++/* ++ * arguments: ++ * UINT32 cmd (AR6000_XIOCTL_GPIO_REGISTER_GET) ++ * ar6000_gpio_register_cmd_s (see below) ++ * uses: WMIX_GPIO_REGISTER_GET_CMDID ++ */ ++ ++#define AR6000_XIOCTL_GPIO_INTR_ACK 22 ++/* ++ * arguments: ++ * UINT32 cmd (AR6000_XIOCTL_GPIO_INTR_ACK) ++ * ar6000_cpio_intr_ack_cmd_s (see below) ++ * uses: WMIX_GPIO_INTR_ACK_CMDID ++ */ ++ ++#define AR6000_XIOCTL_GPIO_INTR_WAIT 23 ++/* ++ * arguments: ++ * UINT32 cmd (AR6000_XIOCTL_GPIO_INTR_WAIT) ++ */ ++ ++ ++ ++/* ====more wireless commands==== */ ++ ++#define AR6000_XIOCTL_SET_ADHOC_BSSID 24 ++/* ++ * arguments: ++ * UINT32 cmd (AR6000_XIOCTL_SET_ADHOC_BSSID) ++ * WMI_SET_ADHOC_BSSID_CMD setAdHocBssidCmd (see include/wmi.h) ++ */ ++ ++#define AR6000_XIOCTL_SET_OPT_MODE 25 ++/* ++ * arguments: ++ * UINT32 cmd (AR6000_XIOCTL_SET_OPT_MODE) ++ * WMI_SET_OPT_MODE_CMD setOptModeCmd (see include/wmi.h) ++ * uses: WMI_SET_OPT_MODE_CMDID ++ */ ++ ++#define AR6000_XIOCTL_OPT_SEND_FRAME 26 ++/* ++ * arguments: ++ * UINT32 cmd (AR6000_XIOCTL_OPT_SEND_FRAME) ++ * WMI_OPT_TX_FRAME_CMD optTxFrameCmd (see include/wmi.h) ++ * uses: WMI_OPT_TX_FRAME_CMDID ++ */ ++ ++#define AR6000_XIOCTL_SET_ADHOC_BEACON_INTVAL 27 ++/* ++ * arguments: ++ * UINT32 cmd (AR6000_XIOCTL_SET_ADHOC_BEACON_INTVAL) ++ * WMI_BEACON_INT_CMD beaconIntCmd (see include/wmi.h) ++ * uses: WMI_SET_BEACON_INT_CMDID ++ */ ++ ++ ++#define IEEE80211_IOCTL_SETAUTHALG 28 ++ ++ ++#define AR6000_XIOCTL_SET_VOICE_PKT_SIZE 29 ++/* ++ * arguments: ++ * UINT32 cmd (AR6000_XIOCTL_SET_VOICE_PKT_SIZE) ++ * WMI_SET_VOICE_PKT_SIZE_CMD setVoicePktSizeCmd (see include/wmi.h) ++ * uses: WMI_SET_VOICE_PKT_SIZE_CMDID ++ */ ++ ++ ++#define AR6000_XIOCTL_SET_MAX_SP 30 ++/* ++ * arguments: ++ * UINT32 cmd (AR6000_XIOCTL_SET_MAX_SP) ++ * WMI_SET_MAX_SP_LEN_CMD maxSPLen(see include/wmi.h) ++ * uses: WMI_SET_MAX_SP_LEN_CMDID ++ */ ++ ++#define AR6000_XIOCTL_WMI_GET_ROAM_TBL 31 ++ ++#define AR6000_XIOCTL_WMI_SET_ROAM_CTRL 32 ++ ++#define AR6000_XIOCTRL_WMI_SET_POWERSAVE_TIMERS 33 ++ ++ ++/* ++ * arguments: ++ * UINT32 cmd (AR6000_XIOCTRL_WMI_SET_POWERSAVE_TIMERS) ++ * WMI_SET_POWERSAVE_TIMERS_CMD powerSaveTimers(see include/wmi.h) ++ * WMI_SET_POWERSAVE_TIMERS_CMDID ++ */ ++ ++#define AR6000_XIOCTRL_WMI_GET_POWER_MODE 34 ++/* ++ * arguments: ++ * UINT32 cmd (AR6000_XIOCTRL_WMI_GET_POWER_MODE) ++ */ ++ ++#define AR6000_XIOCTRL_WMI_SET_WLAN_STATE 35 ++typedef enum { ++ WLAN_DISABLED, ++ WLAN_ENABLED ++} AR6000_WLAN_STATE; ++/* ++ * arguments: ++ * enable/disable ++ */ ++ ++#define AR6000_XIOCTL_WMI_GET_ROAM_DATA 36 ++ ++#define AR6000_XIOCTL_WMI_SETRETRYLIMITS 37 ++/* ++ * arguments: ++ * WMI_SET_RETRY_LIMITS_CMD ibssSetRetryLimitsCmd ++ * uses: WMI_SET_RETRY_LIMITS_CMDID ++ */ ++ ++#ifdef CONFIG_HOST_TCMD_SUPPORT ++/* ====extended commands for radio test ==== */ ++ ++#define AR6000_XIOCTL_TCMD_CONT_TX 38 ++/* ++ * arguments: ++ * UINT32 cmd (AR6000_XIOCTL_TCMD_CONT_TX) ++ * WMI_TCMD_CONT_TX_CMD contTxCmd (see include/wmi.h) ++ * uses: WMI_TCMD_CONT_TX_CMDID ++ */ ++ ++#define AR6000_XIOCTL_TCMD_CONT_RX 39 ++/* ++ * arguments: ++ * UINT32 cmd (AR6000_XIOCTL_TCMD_CONT_RX) ++ * WMI_TCMD_CONT_RX_CMD rxCmd (see include/wmi.h) ++ * uses: WMI_TCMD_CONT_RX_CMDID ++ */ ++ ++#define AR6000_XIOCTL_TCMD_PM 40 ++/* ++ * arguments: ++ * UINT32 cmd (AR6000_XIOCTL_TCMD_PM) ++ * WMI_TCMD_PM_CMD pmCmd (see include/wmi.h) ++ * uses: WMI_TCMD_PM_CMDID ++ */ ++ ++#endif /* CONFIG_HOST_TCMD_SUPPORT */ ++ ++#define AR6000_XIOCTL_WMI_STARTSCAN 41 ++/* ++ * arguments: ++ * UINT32 cmd (AR6000_XIOCTL_WMI_STARTSCAN) ++ * UINT8 scanType ++ * UINT8 scanConnected ++ * A_BOOL forceFgScan ++ * uses: WMI_START_SCAN_CMDID ++ */ ++ ++#define AR6000_XIOCTL_WMI_SETFIXRATES 42 ++ ++#define AR6000_XIOCTL_WMI_GETFIXRATES 43 ++ ++ ++#define AR6000_XIOCTL_WMI_SET_RSSITHRESHOLD 44 ++/* ++ * arguments: ++ * WMI_RSSI_THRESHOLD_PARAMS_CMD thresholdParams (see include/wmi.h) ++ * uses: WMI_RSSI_THRESHOLD_PARAMS_CMDID ++ */ ++ ++#define AR6000_XIOCTL_WMI_CLR_RSSISNR 45 ++/* ++ * arguments: ++ * WMI_CLR_RSSISNR_CMD thresholdParams (see include/wmi.h) ++ * uses: WMI_CLR_RSSISNR_CMDID ++ */ ++ ++#define AR6000_XIOCTL_WMI_SET_LQTHRESHOLD 46 ++/* ++ * arguments: ++ * WMI_LQ_THRESHOLD_PARAMS_CMD thresholdParams (see include/wmi.h) ++ * uses: WMI_LQ_THRESHOLD_PARAMS_CMDID ++ */ ++ ++#define AR6000_XIOCTL_WMI_SET_RTS 47 ++/* ++ * arguments: ++ * WMI_SET_RTS_MODE_CMD (see include/wmi.h) ++ * uses: WMI_SET_RTS_MODE_CMDID ++ */ ++ ++#define AR6000_XIOCTL_WMI_SET_LPREAMBLE 48 ++ ++#define AR6000_XIOCTL_WMI_SET_AUTHMODE 49 ++/* ++ * arguments: ++ * UINT32 cmd (AR6000_XIOCTL_WMI_SET_AUTHMODE) ++ * UINT8 mode ++ * uses: WMI_SET_RECONNECT_AUTH_MODE_CMDID ++ */ ++ ++#define AR6000_XIOCTL_WMI_SET_REASSOCMODE 50 ++ ++/* ++ * arguments: ++ * UINT32 cmd (AR6000_XIOCTL_WMI_SET_WMM) ++ * UINT8 mode ++ * uses: WMI_SET_WMM_CMDID ++ */ ++#define AR6000_XIOCTL_WMI_SET_WMM 51 ++ ++/* ++ * arguments: ++ * UINT32 cmd (AR6000_XIOCTL_WMI_SET_HB_CHALLENGE_RESP_PARAMS) ++ * UINT32 frequency ++ * UINT8 threshold ++ */ ++#define AR6000_XIOCTL_WMI_SET_HB_CHALLENGE_RESP_PARAMS 52 ++ ++/* ++ * arguments: ++ * UINT32 cmd (AR6000_XIOCTL_WMI_GET_HB_CHALLENGE_RESP) ++ * UINT32 cookie ++ */ ++#define AR6000_XIOCTL_WMI_GET_HB_CHALLENGE_RESP 53 ++ ++/* ++ * arguments: ++ * UINT32 cmd (AR6000_XIOCTL_WMI_GET_RD) ++ * UINT32 regDomain ++ */ ++#define AR6000_XIOCTL_WMI_GET_RD 54 ++ ++#define AR6000_XIOCTL_DIAG_READ 55 ++ ++#define AR6000_XIOCTL_DIAG_WRITE 56 ++ ++/* ++ * arguments cmd (AR6000_XIOCTL_SET_TXOP) ++ * WMI_TXOP_CFG txopEnable ++ */ ++#define AR6000_XIOCTL_WMI_SET_TXOP 57 ++ ++#ifdef USER_KEYS ++/* ++ * arguments: ++ * UINT32 cmd (AR6000_XIOCTL_USER_SETKEYS) ++ * UINT32 keyOpCtrl ++ * uses AR6000_USER_SETKEYS_INFO ++ */ ++#define AR6000_XIOCTL_USER_SETKEYS 58 ++#endif /* USER_KEYS */ ++ ++#define AR6000_XIOCTL_WMI_SET_KEEPALIVE 59 ++/* ++ * arguments: ++ * UINT8 cmd (AR6000_XIOCTL_WMI_SET_KEEPALIVE) ++ * UINT8 keepaliveInterval ++ * uses: WMI_SET_KEEPALIVE_CMDID ++ */ ++ ++#define AR6000_XIOCTL_WMI_GET_KEEPALIVE 60 ++/* ++ * arguments: ++ * UINT8 cmd (AR6000_XIOCTL_WMI_GET_KEEPALIVE) ++ * UINT8 keepaliveInterval ++ * A_BOOL configured ++ * uses: WMI_GET_KEEPALIVE_CMDID ++ */ ++ ++/* ====ROM Patching Extended Ioctls==== */ ++ ++#define AR6000_XIOCTL_BMI_ROMPATCH_INSTALL 61 ++/* ++ * arguments: ++ * union { ++ * struct { ++ * UINT32 cmd (AR6000_XIOCTL_BMI_ROMPATCH_INSTALL) ++ * UINT32 ROM Address ++ * UINT32 RAM Address ++ * UINT32 number of bytes ++ * UINT32 activate? (0 or 1) ++ * } ++ * A_UINT32 resulting rompatch ID ++ * } ++ * uses: BMI_ROMPATCH_INSTALL ++ */ ++ ++#define AR6000_XIOCTL_BMI_ROMPATCH_UNINSTALL 62 ++/* ++ * arguments: ++ * struct { ++ * UINT32 cmd (AR6000_XIOCTL_BMI_ROMPATCH_UNINSTALL) ++ * UINT32 rompatch ID ++ * } ++ * uses: BMI_ROMPATCH_UNINSTALL ++ */ ++ ++#define AR6000_XIOCTL_BMI_ROMPATCH_ACTIVATE 63 ++/* ++ * arguments: ++ * struct { ++ * UINT32 cmd (AR6000_XIOCTL_BMI_ROMPATCH_ACTIVATE) ++ * UINT32 rompatch count ++ * UINT32 rompatch IDs[rompatch count] ++ * } ++ * uses: BMI_ROMPATCH_ACTIVATE ++ */ ++ ++#define AR6000_XIOCTL_BMI_ROMPATCH_DEACTIVATE 64 ++/* ++ * arguments: ++ * struct { ++ * UINT32 cmd (AR6000_XIOCTL_BMI_ROMPATCH_DEACTIVATE) ++ * UINT32 rompatch count ++ * UINT32 rompatch IDs[rompatch count] ++ * } ++ * uses: BMI_ROMPATCH_DEACTIVATE ++ */ ++ ++#define AR6000_XIOCTL_WMI_SET_APPIE 65 ++/* ++ * arguments: ++ * struct { ++ * UINT32 cmd (AR6000_XIOCTL_WMI_SET_APPIE) ++ * UINT32 app_frmtype; ++ * UINT32 app_buflen; ++ * UINT8 app_buf[]; ++ * } ++ */ ++#define AR6000_XIOCTL_WMI_SET_MGMT_FRM_RX_FILTER 66 ++/* ++ * arguments: ++ * A_UINT32 filter_type; ++ */ ++ ++#define AR6000_XIOCTL_DBGLOG_CFG_MODULE 67 ++ ++#define AR6000_XIOCTL_DBGLOG_GET_DEBUG_LOGS 68 ++ ++#define AR6000_XIOCTL_WMI_SET_WSC_STATUS 70 ++/* ++ * arguments: ++ * A_UINT32 wsc_status; ++ * (WSC_REG_INACTIVE or WSC_REG_ACTIVE) ++ */ ++ ++/* ++ * arguments: ++ * struct { ++ * A_UINT8 streamType; ++ * A_UINT8 status; ++ * } ++ * uses: WMI_SET_BT_STATUS_CMDID ++ */ ++#define AR6000_XIOCTL_WMI_SET_BT_STATUS 71 ++ ++/* ++ * arguments: ++ * struct { ++ * A_UINT8 paramType; ++ * union { ++ * A_UINT8 noSCOPkts; ++ * BT_PARAMS_A2DP a2dpParams; ++ * BT_COEX_REGS regs; ++ * }; ++ * } ++ * uses: WMI_SET_BT_PARAM_CMDID ++ */ ++#define AR6000_XIOCTL_WMI_SET_BT_PARAMS 72 ++ ++#define AR6000_XIOCTL_WMI_SET_HOST_SLEEP_MODE 73 ++#define AR6000_XIOCTL_WMI_SET_WOW_MODE 74 ++#define AR6000_XIOCTL_WMI_GET_WOW_LIST 75 ++#define AR6000_XIOCTL_WMI_ADD_WOW_PATTERN 76 ++#define AR6000_XIOCTL_WMI_DEL_WOW_PATTERN 77 ++ ++ ++ ++#define AR6000_XIOCTL_TARGET_INFO 78 ++/* ++ * arguments: ++ * UINT32 cmd (AR6000_XIOCTL_TARGET_INFO) ++ * A_UINT32 TargetVersion (returned) ++ * A_UINT32 TargetType (returned) ++ * (See also bmi_msg.h target_ver and target_type) ++ */ ++ ++#define AR6000_XIOCTL_DUMP_HTC_CREDIT_STATE 79 ++/* ++ * arguments: ++ * none ++ */ ++ ++#define AR6000_XIOCTL_TRAFFIC_ACTIVITY_CHANGE 80 ++/* ++ * This ioctl is used to emulate traffic activity ++ * timeouts. Activity/inactivity will trigger the driver ++ * to re-balance credits. ++ * ++ * arguments: ++ * ar6000_traffic_activity_change ++ */ ++ ++#define AR6000_XIOCTL_WMI_SET_CONNECT_CTRL_FLAGS 81 ++/* ++ * This ioctl is used to set the connect control flags ++ * ++ * arguments: ++ * A_UINT32 connectCtrlFlags ++ */ ++ ++#define AR6000_XIOCTL_WMI_SET_AKMP_PARAMS 82 ++/* ++ * This IOCTL sets any Authentication,Key Management and Protection ++ * related parameters. This is used along with the information set in ++ * Connect Command. ++ * Currently this enables Multiple PMKIDs to an AP. ++ * ++ * arguments: ++ * struct { ++ * A_UINT32 akmpInfo; ++ * } ++ * uses: WMI_SET_AKMP_PARAMS_CMD ++ */ ++ ++#define AR6000_XIOCTL_WMI_GET_PMKID_LIST 83 ++ ++#define AR6000_XIOCTL_WMI_SET_PMKID_LIST 84 ++/* ++ * This IOCTL is used to set a list of PMKIDs. This list of ++ * PMKIDs is used in the [Re]AssocReq Frame. This list is used ++ * only if the MultiPMKID option is enabled via the ++ * AR6000_XIOCTL_WMI_SET_AKMP_PARAMS IOCTL. ++ * ++ * arguments: ++ * struct { ++ * A_UINT32 numPMKID; ++ * WMI_PMKID pmkidList[WMI_MAX_PMKID_CACHE]; ++ * } ++ * uses: WMI_SET_PMKIDLIST_CMD ++ */ ++ ++/* Historical DSETPATCH support for INI patches */ ++#define AR6000_XIOCTL_UNUSED90 90 ++ ++ ++ ++/* used by AR6000_IOCTL_WMI_GETREV */ ++struct ar6000_version { ++ A_UINT32 host_ver; ++ A_UINT32 target_ver; ++}; ++ ++/* used by AR6000_IOCTL_WMI_GET_QOS_QUEUE */ ++struct ar6000_queuereq { ++ A_UINT8 trafficClass; ++ A_UINT16 activeTsids; ++}; ++ ++/* used by AR6000_IOCTL_WMI_GET_TARGET_STATS */ ++typedef struct targetStats_t { ++ A_UINT64 tx_packets; ++ A_UINT64 tx_bytes; ++ A_UINT64 tx_unicast_pkts; ++ A_UINT64 tx_unicast_bytes; ++ A_UINT64 tx_multicast_pkts; ++ A_UINT64 tx_multicast_bytes; ++ A_UINT64 tx_broadcast_pkts; ++ A_UINT64 tx_broadcast_bytes; ++ A_UINT64 tx_rts_success_cnt; ++ A_UINT64 tx_packet_per_ac[4]; ++ ++ A_UINT64 tx_errors; ++ A_UINT64 tx_failed_cnt; ++ A_UINT64 tx_retry_cnt; ++ A_UINT64 tx_rts_fail_cnt; ++ A_INT32 tx_unicast_rate; ++ A_UINT64 rx_packets; ++ A_UINT64 rx_bytes; ++ A_UINT64 rx_unicast_pkts; ++ A_UINT64 rx_unicast_bytes; ++ A_UINT64 rx_multicast_pkts; ++ A_UINT64 rx_multicast_bytes; ++ A_UINT64 rx_broadcast_pkts; ++ A_UINT64 rx_broadcast_bytes; ++ A_UINT64 rx_fragment_pkt; ++ ++ A_UINT64 rx_errors; ++ A_UINT64 rx_crcerr; ++ A_UINT64 rx_key_cache_miss; ++ A_UINT64 rx_decrypt_err; ++ A_UINT64 rx_duplicate_frames; ++ A_INT32 rx_unicast_rate; ++ ++ A_UINT64 tkip_local_mic_failure; ++ A_UINT64 tkip_counter_measures_invoked; ++ A_UINT64 tkip_replays; ++ A_UINT64 tkip_format_errors; ++ A_UINT64 ccmp_format_errors; ++ A_UINT64 ccmp_replays; ++ ++ A_UINT64 power_save_failure_cnt; ++ A_INT16 noise_floor_calibation; ++ ++ A_UINT64 cs_bmiss_cnt; ++ A_UINT64 cs_lowRssi_cnt; ++ A_UINT64 cs_connect_cnt; ++ A_UINT64 cs_disconnect_cnt; ++ A_UINT8 cs_aveBeacon_snr; ++ A_INT16 cs_aveBeacon_rssi; ++ A_UINT8 cs_lastRoam_msec; ++ A_UINT8 cs_snr; ++ A_INT16 cs_rssi; ++ ++ A_UINT32 lq_val; ++ ++ A_UINT32 wow_num_pkts_dropped; ++ A_UINT8 wow_num_host_pkt_wakeups; ++ A_UINT8 wow_num_host_event_wakeups; ++ A_UINT16 wow_num_events_discarded; ++ ++}TARGET_STATS; ++ ++typedef struct targetStats_cmd_t { ++ TARGET_STATS targetStats; ++ int clearStats; ++} TARGET_STATS_CMD; ++ ++/* used by AR6000_XIOCTL_USER_SETKEYS */ ++ ++/* ++ * Setting this bit to 1 doesnot initialize the RSC on the firmware ++ */ ++#define AR6000_XIOCTL_USER_SETKEYS_RSC_CTRL 1 ++#define AR6000_USER_SETKEYS_RSC_UNCHANGED 0x00000002 ++ ++typedef struct { ++ A_UINT32 keyOpCtrl; /* Bit Map of Key Mgmt Ctrl Flags */ ++} AR6000_USER_SETKEYS_INFO; ++ ++ ++/* used by AR6000_XIOCTL_GPIO_OUTPUT_SET */ ++struct ar6000_gpio_output_set_cmd_s { ++ A_UINT32 set_mask; ++ A_UINT32 clear_mask; ++ A_UINT32 enable_mask; ++ A_UINT32 disable_mask; ++}; ++ ++/* ++ * used by AR6000_XIOCTL_GPIO_REGISTER_GET and AR6000_XIOCTL_GPIO_REGISTER_SET ++ */ ++struct ar6000_gpio_register_cmd_s { ++ A_UINT32 gpioreg_id; ++ A_UINT32 value; ++}; ++ ++/* used by AR6000_XIOCTL_GPIO_INTR_ACK */ ++struct ar6000_gpio_intr_ack_cmd_s { ++ A_UINT32 ack_mask; ++}; ++ ++/* used by AR6000_XIOCTL_GPIO_INTR_WAIT */ ++struct ar6000_gpio_intr_wait_cmd_s { ++ A_UINT32 intr_mask; ++ A_UINT32 input_values; ++}; ++ ++/* used by the AR6000_XIOCTL_DBGLOG_CFG_MODULE */ ++typedef struct ar6000_dbglog_module_config_s { ++ A_UINT32 valid; ++ A_UINT16 mmask; ++ A_UINT16 tsr; ++ A_BOOL rep; ++ A_UINT16 size; ++} DBGLOG_MODULE_CONFIG; ++ ++typedef struct user_rssi_thold_t { ++ A_INT16 tag; ++ A_INT16 rssi; ++} USER_RSSI_THOLD; ++ ++typedef struct user_rssi_params_t { ++ A_UINT8 weight; ++ A_UINT32 pollTime; ++ USER_RSSI_THOLD tholds[12]; ++} USER_RSSI_PARAMS; ++ ++/* ++ * Host driver may have some config parameters. Typically, these ++ * config params are one time config parameters. These could ++ * correspond to any of the underlying modules. Host driver exposes ++ * an api for the underlying modules to get this config. ++ */ ++#define AR6000_DRIVER_CFG_BASE 0x8000 ++ ++/* Should driver perform wlan node caching? */ ++#define AR6000_DRIVER_CFG_GET_WLANNODECACHING 0x8001 ++/*Should we log raw WMI msgs */ ++#define AR6000_DRIVER_CFG_LOG_RAW_WMI_MSGS 0x8002 ++ ++/* used by AR6000_XIOCTL_DIAG_READ & AR6000_XIOCTL_DIAG_WRITE */ ++struct ar6000_diag_window_cmd_s { ++ unsigned int addr; ++ unsigned int value; ++}; ++ ++ ++struct ar6000_traffic_activity_change { ++ A_UINT32 StreamID; /* stream ID to indicate activity change */ ++ A_UINT32 Active; /* active (1) or inactive (0) */ ++}; ++ ++#ifdef __cplusplus ++} ++#endif ++#endif +diff -ruN --exclude='*.orig' --exclude='*.rej' linux-2.6.29-rc3.owrt/drivers/ar6000/ar6000/athtypes_linux.h linux-2.6.29-rc3.owrt.om/drivers/ar6000/ar6000/athtypes_linux.h +--- linux-2.6.29-rc3.owrt/drivers/ar6000/ar6000/athtypes_linux.h 1970-01-01 01:00:00.000000000 +0100 ++++ linux-2.6.29-rc3.owrt.om/drivers/ar6000/ar6000/athtypes_linux.h 2009-05-10 22:27:59.000000000 +0200 +@@ -0,0 +1,47 @@ ++/* ++ * $Id: //depot/sw/releases/olca2.0-GPL/host/os/linux/include/athtypes_linux.h#1 $ ++ * ++ * This file contains the definitions of the basic atheros data types. ++ * It is used to map the data types in atheros files to a platform specific ++ * type. ++ * ++ * Copyright 2003-2005 Atheros Communications, Inc., All Rights Reserved. ++ * ++ * ++ * 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; ++ * ++ * Software distributed under the License is distributed on an "AS ++ * IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or ++ * implied. See the License for the specific language governing ++ * rights and limitations under the License. ++ * ++ * ++ * ++ */ ++ ++#ifndef _ATHTYPES_LINUX_H_ ++#define _ATHTYPES_LINUX_H_ ++ ++#ifdef __KERNEL__ ++#include <linux/types.h> ++#endif ++ ++typedef int8_t A_INT8; ++typedef int16_t A_INT16; ++typedef int32_t A_INT32; ++typedef int64_t A_INT64; ++ ++typedef u_int8_t A_UINT8; ++typedef u_int16_t A_UINT16; ++typedef u_int32_t A_UINT32; ++typedef u_int64_t A_UINT64; ++ ++typedef int A_BOOL; ++typedef char A_CHAR; ++typedef unsigned char A_UCHAR; ++typedef unsigned long A_ATH_TIMER; ++ ++ ++#endif /* _ATHTYPES_LINUX_H_ */ +diff -ruN --exclude='*.orig' --exclude='*.rej' linux-2.6.29-rc3.owrt/drivers/ar6000/ar6000/config_linux.h linux-2.6.29-rc3.owrt.om/drivers/ar6000/ar6000/config_linux.h +--- linux-2.6.29-rc3.owrt/drivers/ar6000/ar6000/config_linux.h 1970-01-01 01:00:00.000000000 +0100 ++++ linux-2.6.29-rc3.owrt.om/drivers/ar6000/ar6000/config_linux.h 2009-05-10 22:27:59.000000000 +0200 +@@ -0,0 +1,44 @@ ++/* ++ * Copyright (c) 2004-2007 Atheros Communications Inc. ++ * All rights reserved. ++ * ++ * ++ * 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; ++ * ++ * Software distributed under the License is distributed on an "AS ++ * IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or ++ * implied. See the License for the specific language governing ++ * rights and limitations under the License. ++ * ++ * ++ * ++ */ ++ ++#ifndef _CONFIG_LINUX_H_ ++#define _CONFIG_LINUX_H_ ++ ++#ifdef __cplusplus ++extern "C" { ++#endif ++ ++/* ++ * Host-side GPIO support is optional. ++ * If run-time access to GPIO pins is not required, then ++ * this should be changed to #undef. ++ */ ++#define CONFIG_HOST_GPIO_SUPPORT ++ ++/* ++ * Host side Test Command support ++ */ ++#define CONFIG_HOST_TCMD_SUPPORT ++ ++#define USE_4BYTE_REGISTER_ACCESS ++ ++#ifdef __cplusplus ++} ++#endif ++ ++#endif +diff -ruN --exclude='*.orig' --exclude='*.rej' linux-2.6.29-rc3.owrt/drivers/ar6000/ar6000/debug_linux.h linux-2.6.29-rc3.owrt.om/drivers/ar6000/ar6000/debug_linux.h +--- linux-2.6.29-rc3.owrt/drivers/ar6000/ar6000/debug_linux.h 1970-01-01 01:00:00.000000000 +0100 ++++ linux-2.6.29-rc3.owrt.om/drivers/ar6000/ar6000/debug_linux.h 2009-05-10 22:27:59.000000000 +0200 +@@ -0,0 +1,86 @@ ++/* ++ * Copyright (c) 2004-2006 Atheros Communications Inc. ++ * All rights reserved. ++ * ++ * ++ * 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; ++ * ++ * Software distributed under the License is distributed on an "AS ++ * IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or ++ * implied. See the License for the specific language governing ++ * rights and limitations under the License. ++ * ++ * ++ * ++ */ ++ ++#ifndef _DEBUG_LINUX_H_ ++#define _DEBUG_LINUX_H_ ++ ++#define DBG_DEFAULTS (DBG_ERROR|DBG_WARNING) ++ ++extern A_UINT32 g_dbg_flags; ++ ++#define DBGFMT "%s() : " ++#define DBGARG __func__ ++#define DBGFN A_PRINTF ++ ++/* ------- Debug related stuff ------- */ ++enum { ++ ATH_DEBUG_SEND = 0x0001, ++ ATH_DEBUG_RECV = 0x0002, ++ ATH_DEBUG_SYNC = 0x0004, ++ ATH_DEBUG_DUMP = 0x0008, ++ ATH_DEBUG_IRQ = 0x0010, ++ ATH_DEBUG_TRC = 0x0020, ++ ATH_DEBUG_WARN = 0x0040, ++ ATH_DEBUG_ERR = 0x0080, ++ ATH_LOG_INF = 0x0100, ++ ATH_DEBUG_BMI = 0x0110, ++ ATH_DEBUG_WMI = 0x0120, ++ ATH_DEBUG_HIF = 0x0140, ++ ATH_DEBUG_HTC = 0x0180, ++ ATH_DEBUG_WLAN = 0x1000, ++ ATH_LOG_ERR = 0x1010, ++ ATH_DEBUG_ANY = 0xFFFF, ++}; ++ ++#ifdef DEBUG ++ ++#define A_DPRINTF(f, a) \ ++ if(g_dbg_flags & (f)) \ ++ { \ ++ DBGFN a ; \ ++ } ++ ++ ++// TODO FIX usage of A_PRINTF! ++#define AR_DEBUG_LVL_CHECK(lvl) (debughtc & (lvl)) ++#define AR_DEBUG_PRINTBUF(buffer, length, desc) do { \ ++ if (debughtc & ATH_DEBUG_DUMP) { \ ++ DebugDumpBytes(buffer, length,desc); \ ++ } \ ++} while(0) ++#define PRINTX_ARG(arg...) arg ++#define AR_DEBUG_PRINTF(flags, args) do { \ ++ if (debughtc & (flags)) { \ ++ A_PRINTF(KERN_ALERT PRINTX_ARG args); \ ++ } \ ++} while (0) ++#define AR_DEBUG_ASSERT(test) do { \ ++ if (!(test)) { \ ++ AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("Debug Assert Caught, File %s, Line: %d, Test:%s \n",__FILE__, __LINE__,#test)); \ ++ } \ ++} while(0) ++extern int debughtc; ++#else ++#define AR_DEBUG_PRINTF(flags, args) ++#define AR_DEBUG_PRINTBUF(buffer, length, desc) ++#define AR_DEBUG_ASSERT(test) ++#define AR_DEBUG_LVL_CHECK(lvl) 0 ++#define A_DPRINTF(f, a) ++#endif ++ ++#endif /* _DEBUG_LINUX_H_ */ +diff -ruN --exclude='*.orig' --exclude='*.rej' linux-2.6.29-rc3.owrt/drivers/ar6000/ar6000/ioctl.c linux-2.6.29-rc3.owrt.om/drivers/ar6000/ar6000/ioctl.c +--- linux-2.6.29-rc3.owrt/drivers/ar6000/ar6000/ioctl.c 1970-01-01 01:00:00.000000000 +0100 ++++ linux-2.6.29-rc3.owrt.om/drivers/ar6000/ar6000/ioctl.c 2009-05-10 22:27:59.000000000 +0200 +@@ -0,0 +1,2540 @@ ++/* ++ * ++ * Copyright (c) 2004-2007 Atheros Communications Inc. ++ * All rights reserved. ++ * ++ * ++ * 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; ++ * ++ * Software distributed under the License is distributed on an "AS ++ * IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or ++ * implied. See the License for the specific language governing ++ * rights and limitations under the License. ++ * ++ * ++ * ++ */ ++ ++#include "ar6000_drv.h" ++ ++static A_UINT8 bcast_mac[] = {0xff, 0xff, 0xff, 0xff, 0xff, 0xff}; ++static A_UINT8 null_mac[] = {0x0, 0x0, 0x0, 0x0, 0x0, 0x0}; ++extern USER_RSSI_THOLD rssi_map[12]; ++extern unsigned int wmitimeout; ++extern A_WAITQUEUE_HEAD arEvent; ++extern int tspecCompliance; ++extern int bmienable; ++extern int bypasswmi; ++ ++static int ++ar6000_ioctl_get_roam_tbl(struct net_device *dev, struct ifreq *rq) ++{ ++ AR_SOFTC_T *ar = (AR_SOFTC_T *)netdev_priv(dev); ++ ++ if (ar->arWmiReady == FALSE) { ++ return -EIO; ++ } ++ ++ if(wmi_get_roam_tbl_cmd(ar->arWmi) != A_OK) { ++ return -EIO; ++ } ++ ++ return 0; ++} ++ ++static int ++ar6000_ioctl_get_roam_data(struct net_device *dev, struct ifreq *rq) ++{ ++ AR_SOFTC_T *ar = (AR_SOFTC_T *)netdev_priv(dev); ++ ++ if (ar->arWmiReady == FALSE) { ++ return -EIO; ++ } ++ ++ ++ /* currently assume only roam times are required */ ++ if(wmi_get_roam_data_cmd(ar->arWmi, ROAM_DATA_TIME) != A_OK) { ++ return -EIO; ++ } ++ ++ ++ return 0; ++} ++ ++static int ++ar6000_ioctl_set_roam_ctrl(struct net_device *dev, char *userdata) ++{ ++ AR_SOFTC_T *ar = (AR_SOFTC_T *)netdev_priv(dev); ++ WMI_SET_ROAM_CTRL_CMD cmd; ++ A_UINT8 size = sizeof(cmd); ++ ++ if (ar->arWmiReady == FALSE) { ++ return -EIO; ++ } ++ ++ ++ if (copy_from_user(&cmd, userdata, size)) { ++ return -EFAULT; ++ } ++ ++ if (cmd.roamCtrlType == WMI_SET_HOST_BIAS) { ++ if (cmd.info.bssBiasInfo.numBss > 1) { ++ size += (cmd.info.bssBiasInfo.numBss - 1) * sizeof(WMI_BSS_BIAS); ++ } ++ } ++ ++ if (copy_from_user(&cmd, userdata, size)) { ++ return -EFAULT; ++ } ++ ++ if(wmi_set_roam_ctrl_cmd(ar->arWmi, &cmd, size) != A_OK) { ++ return -EIO; ++ } ++ ++ return 0; ++} ++ ++static int ++ar6000_ioctl_set_powersave_timers(struct net_device *dev, char *userdata) ++{ ++ AR_SOFTC_T *ar = (AR_SOFTC_T *)netdev_priv(dev); ++ WMI_POWERSAVE_TIMERS_POLICY_CMD cmd; ++ A_UINT8 size = sizeof(cmd); ++ ++ if (ar->arWmiReady == FALSE) { ++ return -EIO; ++ } ++ ++ if (copy_from_user(&cmd, userdata, size)) { ++ return -EFAULT; ++ } ++ ++ if (copy_from_user(&cmd, userdata, size)) { ++ return -EFAULT; ++ } ++ ++ if(wmi_set_powersave_timers_cmd(ar->arWmi, &cmd, size) != A_OK) { ++ return -EIO; ++ } ++ ++ return 0; ++} ++ ++static int ++ar6000_ioctl_set_wmm(struct net_device *dev, struct ifreq *rq) ++{ ++ AR_SOFTC_T *ar = (AR_SOFTC_T *)netdev_priv(dev); ++ WMI_SET_WMM_CMD cmd; ++ A_STATUS ret; ++ ++ if ((dev->flags & IFF_UP) != IFF_UP) { ++ return -EIO; ++ } ++ if (ar->arWmiReady == FALSE) { ++ return -EIO; ++ } ++ ++ if (copy_from_user(&cmd, (char *)((unsigned int*)rq->ifr_data + 1), ++ sizeof(cmd))) ++ { ++ return -EFAULT; ++ } ++ ++ if (cmd.status == WMI_WMM_ENABLED) { ++ ar->arWmmEnabled = TRUE; ++ } else { ++ ar->arWmmEnabled = FALSE; ++ } ++ ++ ret = wmi_set_wmm_cmd(ar->arWmi, cmd.status); ++ ++ switch (ret) { ++ case A_OK: ++ return 0; ++ case A_EBUSY : ++ return -EBUSY; ++ case A_NO_MEMORY: ++ return -ENOMEM; ++ case A_EINVAL: ++ default: ++ return -EFAULT; ++ } ++} ++ ++static int ++ar6000_ioctl_set_txop(struct net_device *dev, struct ifreq *rq) ++{ ++ AR_SOFTC_T *ar = (AR_SOFTC_T *)netdev_priv(dev); ++ WMI_SET_WMM_TXOP_CMD cmd; ++ A_STATUS ret; ++ ++ if ((dev->flags & IFF_UP) != IFF_UP) { ++ return -EIO; ++ } ++ if (ar->arWmiReady == FALSE) { ++ return -EIO; ++ } ++ ++ if (copy_from_user(&cmd, (char *)((unsigned int*)rq->ifr_data + 1), ++ sizeof(cmd))) ++ { ++ return -EFAULT; ++ } ++ ++ ret = wmi_set_wmm_txop(ar->arWmi, cmd.txopEnable); ++ ++ switch (ret) { ++ case A_OK: ++ return 0; ++ case A_EBUSY : ++ return -EBUSY; ++ case A_NO_MEMORY: ++ return -ENOMEM; ++ case A_EINVAL: ++ default: ++ return -EFAULT; ++ } ++} ++ ++static int ++ar6000_ioctl_get_rd(struct net_device *dev, struct ifreq *rq) ++{ ++ AR_SOFTC_T *ar = (AR_SOFTC_T *)netdev_priv(dev); ++ A_STATUS ret = 0; ++ ++ if ((dev->flags & IFF_UP) != IFF_UP || ar->arWmiReady == FALSE) { ++ return -EIO; ++ } ++ ++ if(copy_to_user((char *)((unsigned int*)rq->ifr_data + 1), ++ &ar->arRegCode, sizeof(ar->arRegCode))) ++ ret = -EFAULT; ++ ++ return ret; ++} ++ ++ ++/* Get power mode command */ ++static int ++ar6000_ioctl_get_power_mode(struct net_device *dev, struct ifreq *rq) ++{ ++ AR_SOFTC_T *ar = (AR_SOFTC_T *)netdev_priv(dev); ++ WMI_POWER_MODE_CMD power_mode; ++ int ret = 0; ++ ++ if (ar->arWmiReady == FALSE) { ++ return -EIO; ++ } ++ ++ power_mode.powerMode = wmi_get_power_mode_cmd(ar->arWmi); ++ if (copy_to_user(rq->ifr_data, &power_mode, sizeof(WMI_POWER_MODE_CMD))) { ++ ret = -EFAULT; ++ } ++ ++ return ret; ++} ++ ++ ++static int ++ar6000_ioctl_set_channelParams(struct net_device *dev, struct ifreq *rq) ++{ ++ AR_SOFTC_T *ar = (AR_SOFTC_T *)netdev_priv(dev); ++ WMI_CHANNEL_PARAMS_CMD cmd, *cmdp; ++ int ret = 0; ++ ++ if (ar->arWmiReady == FALSE) { ++ return -EIO; ++ } ++ ++ ++ if (copy_from_user(&cmd, rq->ifr_data, sizeof(cmd))) { ++ return -EFAULT; ++ } ++ ++ if (cmd.numChannels > 1) { ++ cmdp = A_MALLOC(130); ++ if (copy_from_user(cmdp, rq->ifr_data, ++ sizeof (*cmdp) + ++ ((cmd.numChannels - 1) * sizeof(A_UINT16)))) ++ { ++ kfree(cmdp); ++ return -EFAULT; ++ } ++ } else { ++ cmdp = &cmd; ++ } ++ ++ if ((ar->arPhyCapability == WMI_11G_CAPABILITY) && ++ ((cmdp->phyMode == WMI_11A_MODE) || (cmdp->phyMode == WMI_11AG_MODE))) ++ { ++ ret = -EINVAL; ++ } ++ ++ if (!ret && ++ (wmi_set_channelParams_cmd(ar->arWmi, cmdp->scanParam, cmdp->phyMode, ++ cmdp->numChannels, cmdp->channelList) ++ != A_OK)) ++ { ++ ret = -EIO; ++ } ++ ++ if (cmd.numChannels > 1) { ++ kfree(cmdp); ++ } ++ ++ return ret; ++} ++ ++static int ++ar6000_ioctl_set_snr_threshold(struct net_device *dev, struct ifreq *rq) ++{ ++ ++ AR_SOFTC_T *ar = (AR_SOFTC_T *)netdev_priv(dev); ++ WMI_SNR_THRESHOLD_PARAMS_CMD cmd; ++ int ret = 0; ++ ++ if (ar->arWmiReady == FALSE) { ++ return -EIO; ++ } ++ ++ if (copy_from_user(&cmd, rq->ifr_data, sizeof(cmd))) { ++ return -EFAULT; ++ } ++ ++ if( wmi_set_snr_threshold_params(ar->arWmi, &cmd) != A_OK ) { ++ ret = -EIO; ++ } ++ ++ return ret; ++} ++ ++static int ++ar6000_ioctl_set_rssi_threshold(struct net_device *dev, struct ifreq *rq) ++{ ++#define SWAP_THOLD(thold1, thold2) do { \ ++ USER_RSSI_THOLD tmpThold; \ ++ tmpThold.tag = thold1.tag; \ ++ tmpThold.rssi = thold1.rssi; \ ++ thold1.tag = thold2.tag; \ ++ thold1.rssi = thold2.rssi; \ ++ thold2.tag = tmpThold.tag; \ ++ thold2.rssi = tmpThold.rssi; \ ++} while (0) ++ ++ AR_SOFTC_T *ar = (AR_SOFTC_T *)netdev_priv(dev); ++ WMI_RSSI_THRESHOLD_PARAMS_CMD cmd; ++ USER_RSSI_PARAMS rssiParams; ++ A_INT32 i, j; ++ ++ int ret = 0; ++ ++ if (ar->arWmiReady == FALSE) { ++ return -EIO; ++ } ++ ++ if (copy_from_user((char *)&rssiParams, (char *)((unsigned int *)rq->ifr_data + 1), sizeof(USER_RSSI_PARAMS))) { ++ return -EFAULT; ++ } ++ cmd.weight = rssiParams.weight; ++ cmd.pollTime = rssiParams.pollTime; ++ ++ A_MEMCPY(rssi_map, &rssiParams.tholds, sizeof(rssi_map)); ++ /* ++ * only 6 elements, so use bubble sorting, in ascending order ++ */ ++ for (i = 5; i > 0; i--) { ++ for (j = 0; j < i; j++) { /* above tholds */ ++ if (rssi_map[j+1].rssi < rssi_map[j].rssi) { ++ SWAP_THOLD(rssi_map[j+1], rssi_map[j]); ++ } else if (rssi_map[j+1].rssi == rssi_map[j].rssi) { ++ return EFAULT; ++ } ++ } ++ } ++ for (i = 11; i > 6; i--) { ++ for (j = 6; j < i; j++) { /* below tholds */ ++ if (rssi_map[j+1].rssi < rssi_map[j].rssi) { ++ SWAP_THOLD(rssi_map[j+1], rssi_map[j]); ++ } else if (rssi_map[j+1].rssi == rssi_map[j].rssi) { ++ return EFAULT; ++ } ++ } ++ } ++ ++#ifdef DEBUG ++ for (i = 0; i < 12; i++) { ++ AR_DEBUG2_PRINTF("thold[%d].tag: %d, thold[%d].rssi: %d \n", ++ i, rssi_map[i].tag, i, rssi_map[i].rssi); ++ } ++#endif ++ cmd.thresholdAbove1_Val = rssi_map[0].rssi; ++ cmd.thresholdAbove2_Val = rssi_map[1].rssi; ++ cmd.thresholdAbove3_Val = rssi_map[2].rssi; ++ cmd.thresholdAbove4_Val = rssi_map[3].rssi; ++ cmd.thresholdAbove5_Val = rssi_map[4].rssi; ++ cmd.thresholdAbove6_Val = rssi_map[5].rssi; ++ cmd.thresholdBelow1_Val = rssi_map[6].rssi; ++ cmd.thresholdBelow2_Val = rssi_map[7].rssi; ++ cmd.thresholdBelow3_Val = rssi_map[8].rssi; ++ cmd.thresholdBelow4_Val = rssi_map[9].rssi; ++ cmd.thresholdBelow5_Val = rssi_map[10].rssi; ++ cmd.thresholdBelow6_Val = rssi_map[11].rssi; ++ ++ if( wmi_set_rssi_threshold_params(ar->arWmi, &cmd) != A_OK ) { ++ ret = -EIO; ++ } ++ ++ return ret; ++} ++ ++static int ++ar6000_ioctl_set_lq_threshold(struct net_device *dev, struct ifreq *rq) ++{ ++ ++ AR_SOFTC_T *ar = (AR_SOFTC_T *)netdev_priv(dev); ++ WMI_LQ_THRESHOLD_PARAMS_CMD cmd; ++ int ret = 0; ++ ++ if (ar->arWmiReady == FALSE) { ++ return -EIO; ++ } ++ ++ if (copy_from_user(&cmd, (char *)((unsigned int *)rq->ifr_data + 1), sizeof(cmd))) { ++ return -EFAULT; ++ } ++ ++ if( wmi_set_lq_threshold_params(ar->arWmi, &cmd) != A_OK ) { ++ ret = -EIO; ++ } ++ ++ return ret; ++} ++ ++ ++static int ++ar6000_ioctl_set_probedSsid(struct net_device *dev, struct ifreq *rq) ++{ ++ AR_SOFTC_T *ar = (AR_SOFTC_T *)netdev_priv(dev); ++ WMI_PROBED_SSID_CMD cmd; ++ int ret = 0; ++ ++ if (ar->arWmiReady == FALSE) { ++ return -EIO; ++ } ++ ++ if (copy_from_user(&cmd, rq->ifr_data, sizeof(cmd))) { ++ return -EFAULT; ++ } ++ ++ if (wmi_probedSsid_cmd(ar->arWmi, cmd.entryIndex, cmd.flag, cmd.ssidLength, ++ cmd.ssid) != A_OK) ++ { ++ ret = -EIO; ++ } ++ ++ return ret; ++} ++ ++static int ++ar6000_ioctl_set_badAp(struct net_device *dev, struct ifreq *rq) ++{ ++ AR_SOFTC_T *ar = (AR_SOFTC_T *)netdev_priv(dev); ++ WMI_ADD_BAD_AP_CMD cmd; ++ int ret = 0; ++ ++ if (ar->arWmiReady == FALSE) { ++ return -EIO; ++ } ++ ++ ++ if (copy_from_user(&cmd, rq->ifr_data, sizeof(cmd))) { ++ return -EFAULT; ++ } ++ ++ if (cmd.badApIndex > WMI_MAX_BAD_AP_INDEX) { ++ return -EIO; ++ } ++ ++ if (A_MEMCMP(cmd.bssid, null_mac, AR6000_ETH_ADDR_LEN) == 0) { ++ /* ++ * This is a delete badAP. ++ */ ++ if (wmi_deleteBadAp_cmd(ar->arWmi, cmd.badApIndex) != A_OK) { ++ ret = -EIO; ++ } ++ } else { ++ if (wmi_addBadAp_cmd(ar->arWmi, cmd.badApIndex, cmd.bssid) != A_OK) { ++ ret = -EIO; ++ } ++ } ++ ++ return ret; ++} ++ ++static int ++ar6000_ioctl_create_qos(struct net_device *dev, struct ifreq *rq) ++{ ++ AR_SOFTC_T *ar = (AR_SOFTC_T *)netdev_priv(dev); ++ WMI_CREATE_PSTREAM_CMD cmd; ++ A_STATUS ret; ++ ++ if (ar->arWmiReady == FALSE) { ++ return -EIO; ++ } ++ ++ ++ if (copy_from_user(&cmd, rq->ifr_data, sizeof(cmd))) { ++ return -EFAULT; ++ } ++ ++ ret = wmi_verify_tspec_params(&cmd, tspecCompliance); ++ if (ret == A_OK) ++ ret = wmi_create_pstream_cmd(ar->arWmi, &cmd); ++ ++ switch (ret) { ++ case A_OK: ++ return 0; ++ case A_EBUSY : ++ return -EBUSY; ++ case A_NO_MEMORY: ++ return -ENOMEM; ++ case A_EINVAL: ++ default: ++ return -EFAULT; ++ } ++} ++ ++static int ++ar6000_ioctl_delete_qos(struct net_device *dev, struct ifreq *rq) ++{ ++ AR_SOFTC_T *ar = (AR_SOFTC_T *)netdev_priv(dev); ++ WMI_DELETE_PSTREAM_CMD cmd; ++ int ret = 0; ++ ++ if (ar->arWmiReady == FALSE) { ++ return -EIO; ++ } ++ ++ if (copy_from_user(&cmd, rq->ifr_data, sizeof(cmd))) { ++ return -EFAULT; ++ } ++ ++ ret = wmi_delete_pstream_cmd(ar->arWmi, cmd.trafficClass, cmd.tsid); ++ ++ switch (ret) { ++ case A_OK: ++ return 0; ++ case A_EBUSY : ++ return -EBUSY; ++ case A_NO_MEMORY: ++ return -ENOMEM; ++ case A_EINVAL: ++ default: ++ return -EFAULT; ++ } ++} ++ ++static int ++ar6000_ioctl_get_qos_queue(struct net_device *dev, struct ifreq *rq) ++{ ++ AR_SOFTC_T *ar = (AR_SOFTC_T *)netdev_priv(dev); ++ struct ar6000_queuereq qreq; ++ int ret = 0; ++ ++ if (ar->arWmiReady == FALSE) { ++ return -EIO; ++ } ++ ++ if( copy_from_user(&qreq, rq->ifr_data, ++ sizeof(struct ar6000_queuereq))) ++ return -EFAULT; ++ ++ qreq.activeTsids = wmi_get_mapped_qos_queue(ar->arWmi, qreq.trafficClass); ++ ++ if (copy_to_user(rq->ifr_data, &qreq, ++ sizeof(struct ar6000_queuereq))) ++ { ++ ret = -EFAULT; ++ } ++ ++ return ret; ++} ++ ++#ifdef CONFIG_HOST_TCMD_SUPPORT ++static A_STATUS ++ar6000_ioctl_tcmd_get_rx_report(struct net_device *dev, ++ struct ifreq *rq, A_UINT8 *data, A_UINT32 len) ++{ ++ AR_SOFTC_T *ar = (AR_SOFTC_T *)netdev_priv(dev); ++ A_UINT32 buf[2]; ++ int ret = 0; ++ ++ if (ar->arWmiReady == FALSE) { ++ return -EIO; ++ } ++ ++ if (down_interruptible(&ar->arSem)) { ++ return -ERESTARTSYS; ++ } ++ ar->tcmdRxReport = 0; ++ if (wmi_test_cmd(ar->arWmi, data, len) != A_OK) { ++ up(&ar->arSem); ++ return -EIO; ++ } ++ ++ wait_event_interruptible_timeout(arEvent, ar->tcmdRxReport != 0, wmitimeout * HZ); ++ ++ if (signal_pending(current)) { ++ ret = -EINTR; ++ } ++ ++ buf[0] = ar->tcmdRxTotalPkt; ++ buf[1] = ar->tcmdRxRssi; ++ if (!ret && copy_to_user(rq->ifr_data, buf, sizeof(buf))) { ++ ret = -EFAULT; ++ } ++ ++ up(&ar->arSem); ++ ++ return ret; ++} ++ ++void ++ar6000_tcmd_rx_report_event(void *devt, A_UINT8 * results, int len) ++{ ++ AR_SOFTC_T *ar = (AR_SOFTC_T *)devt; ++ TCMD_CONT_RX * rx_rep = (TCMD_CONT_RX *)results; ++ ++ ar->tcmdRxTotalPkt = rx_rep->u.report.totalPkt; ++ ar->tcmdRxRssi = rx_rep->u.report.rssiInDBm; ++ ar->tcmdRxReport = 1; ++ ++ wake_up(&arEvent); ++} ++#endif /* CONFIG_HOST_TCMD_SUPPORT*/ ++ ++static int ++ar6000_ioctl_set_error_report_bitmask(struct net_device *dev, struct ifreq *rq) ++{ ++ AR_SOFTC_T *ar = (AR_SOFTC_T *)netdev_priv(dev); ++ WMI_TARGET_ERROR_REPORT_BITMASK cmd; ++ int ret = 0; ++ ++ if (ar->arWmiReady == FALSE) { ++ return -EIO; ++ } ++ ++ if (copy_from_user(&cmd, rq->ifr_data, sizeof(cmd))) { ++ return -EFAULT; ++ } ++ ++ ret = wmi_set_error_report_bitmask(ar->arWmi, cmd.bitmask); ++ ++ return (ret==0 ? ret : -EINVAL); ++} ++ ++static int ++ar6000_clear_target_stats(struct net_device *dev) ++{ ++ AR_SOFTC_T *ar = (AR_SOFTC_T *)netdev_priv(dev); ++ TARGET_STATS *pStats = &ar->arTargetStats; ++ int ret = 0; ++ ++ if (ar->arWmiReady == FALSE) { ++ return -EIO; ++ } ++ AR6000_SPIN_LOCK(&ar->arLock, 0); ++ A_MEMZERO(pStats, sizeof(TARGET_STATS)); ++ AR6000_SPIN_UNLOCK(&ar->arLock, 0); ++ return ret; ++} ++ ++static int ++ar6000_ioctl_get_target_stats(struct net_device *dev, struct ifreq *rq) ++{ ++ AR_SOFTC_T *ar = (AR_SOFTC_T *)netdev_priv(dev); ++ TARGET_STATS_CMD cmd; ++ TARGET_STATS *pStats = &ar->arTargetStats; ++ int ret = 0; ++ ++ if (ar->arWmiReady == FALSE) { ++ return -EIO; ++ } ++ if (copy_from_user(&cmd, rq->ifr_data, sizeof(cmd))) { ++ return -EFAULT; ++ } ++ if (down_interruptible(&ar->arSem)) { ++ return -ERESTARTSYS; ++ } ++ ++ ar->statsUpdatePending = TRUE; ++ ++ if(wmi_get_stats_cmd(ar->arWmi) != A_OK) { ++ up(&ar->arSem); ++ return -EIO; ++ } ++ ++ wait_event_interruptible_timeout(arEvent, ar->statsUpdatePending == FALSE, wmitimeout * HZ); ++ ++ if (signal_pending(current)) { ++ ret = -EINTR; ++ } ++ ++ if (!ret && copy_to_user(rq->ifr_data, pStats, sizeof(*pStats))) { ++ ret = -EFAULT; ++ } ++ ++ if (cmd.clearStats == 1) { ++ ret = ar6000_clear_target_stats(dev); ++ } ++ ++ up(&ar->arSem); ++ ++ return ret; ++} ++ ++static int ++ar6000_ioctl_set_access_params(struct net_device *dev, struct ifreq *rq) ++{ ++ AR_SOFTC_T *ar = (AR_SOFTC_T *)netdev_priv(dev); ++ WMI_SET_ACCESS_PARAMS_CMD cmd; ++ int ret = 0; ++ ++ if (ar->arWmiReady == FALSE) { ++ return -EIO; ++ } ++ ++ if (copy_from_user(&cmd, rq->ifr_data, sizeof(cmd))) { ++ return -EFAULT; ++ } ++ ++ if (wmi_set_access_params_cmd(ar->arWmi, cmd.txop, cmd.eCWmin, cmd.eCWmax, ++ cmd.aifsn) == A_OK) ++ { ++ ret = 0; ++ } else { ++ ret = -EINVAL; ++ } ++ ++ return (ret); ++} ++ ++static int ++ar6000_ioctl_set_disconnect_timeout(struct net_device *dev, struct ifreq *rq) ++{ ++ AR_SOFTC_T *ar = (AR_SOFTC_T *)netdev_priv(dev); ++ WMI_DISC_TIMEOUT_CMD cmd; ++ int ret = 0; ++ ++ if (ar->arWmiReady == FALSE) { ++ return -EIO; ++ } ++ ++ if (copy_from_user(&cmd, rq->ifr_data, sizeof(cmd))) { ++ return -EFAULT; ++ } ++ ++ if (wmi_disctimeout_cmd(ar->arWmi, cmd.disconnectTimeout) == A_OK) ++ { ++ ret = 0; ++ } else { ++ ret = -EINVAL; ++ } ++ ++ return (ret); ++} ++ ++static int ++ar6000_xioctl_set_voice_pkt_size(struct net_device *dev, char * userdata) ++{ ++ AR_SOFTC_T *ar = (AR_SOFTC_T *)netdev_priv(dev); ++ WMI_SET_VOICE_PKT_SIZE_CMD cmd; ++ int ret = 0; ++ ++ if (ar->arWmiReady == FALSE) { ++ return -EIO; ++ } ++ ++ if (copy_from_user(&cmd, userdata, sizeof(cmd))) { ++ return -EFAULT; ++ } ++ ++ if (wmi_set_voice_pkt_size_cmd(ar->arWmi, cmd.voicePktSize) == A_OK) ++ { ++ ret = 0; ++ } else { ++ ret = -EINVAL; ++ } ++ ++ ++ return (ret); ++} ++ ++static int ++ar6000_xioctl_set_max_sp_len(struct net_device *dev, char * userdata) ++{ ++ AR_SOFTC_T *ar = (AR_SOFTC_T *)netdev_priv(dev); ++ WMI_SET_MAX_SP_LEN_CMD cmd; ++ int ret = 0; ++ ++ if (ar->arWmiReady == FALSE) { ++ return -EIO; ++ } ++ ++ if (copy_from_user(&cmd, userdata, sizeof(cmd))) { ++ return -EFAULT; ++ } ++ ++ if (wmi_set_max_sp_len_cmd(ar->arWmi, cmd.maxSPLen) == A_OK) ++ { ++ ret = 0; ++ } else { ++ ret = -EINVAL; ++ } ++ ++ return (ret); ++} ++ ++ ++static int ++ar6000_xioctl_set_bt_status_cmd(struct net_device *dev, char * userdata) ++{ ++ AR_SOFTC_T *ar = (AR_SOFTC_T *)netdev_priv(dev); ++ WMI_SET_BT_STATUS_CMD cmd; ++ int ret = 0; ++ ++ if (ar->arWmiReady == FALSE) { ++ return -EIO; ++ } ++ ++ if (copy_from_user(&cmd, userdata, sizeof(cmd))) { ++ return -EFAULT; ++ } ++ ++ if (wmi_set_bt_status_cmd(ar->arWmi, cmd.streamType, cmd.status) == A_OK) ++ { ++ ret = 0; ++ } else { ++ ret = -EINVAL; ++ } ++ ++ return (ret); ++} ++ ++static int ++ar6000_xioctl_set_bt_params_cmd(struct net_device *dev, char * userdata) ++{ ++ AR_SOFTC_T *ar = (AR_SOFTC_T *)netdev_priv(dev); ++ WMI_SET_BT_PARAMS_CMD cmd; ++ int ret = 0; ++ ++ if (ar->arWmiReady == FALSE) { ++ return -EIO; ++ } ++ ++ if (copy_from_user(&cmd, userdata, sizeof(cmd))) { ++ return -EFAULT; ++ } ++ ++ if (wmi_set_bt_params_cmd(ar->arWmi, &cmd) == A_OK) ++ { ++ ret = 0; ++ } else { ++ ret = -EINVAL; ++ } ++ ++ return (ret); ++} ++ ++#ifdef CONFIG_HOST_GPIO_SUPPORT ++struct ar6000_gpio_intr_wait_cmd_s gpio_intr_results; ++/* gpio_reg_results and gpio_data_available are protected by arSem */ ++static struct ar6000_gpio_register_cmd_s gpio_reg_results; ++static A_BOOL gpio_data_available; /* Requested GPIO data available */ ++static A_BOOL gpio_intr_available; /* GPIO interrupt info available */ ++static A_BOOL gpio_ack_received; /* GPIO ack was received */ ++ ++/* Host-side initialization for General Purpose I/O support */ ++void ar6000_gpio_init(void) ++{ ++ gpio_intr_available = FALSE; ++ gpio_data_available = FALSE; ++ gpio_ack_received = FALSE; ++} ++ ++/* ++ * Called when a GPIO interrupt is received from the Target. ++ * intr_values shows which GPIO pins have interrupted. ++ * input_values shows a recent value of GPIO pins. ++ */ ++void ++ar6000_gpio_intr_rx(A_UINT32 intr_mask, A_UINT32 input_values) ++{ ++ gpio_intr_results.intr_mask = intr_mask; ++ gpio_intr_results.input_values = input_values; ++ *((volatile A_BOOL *)&gpio_intr_available) = TRUE; ++ wake_up(&arEvent); ++} ++ ++/* ++ * This is called when a response is received from the Target ++ * for a previous or ar6000_gpio_input_get or ar6000_gpio_register_get ++ * call. ++ */ ++void ++ar6000_gpio_data_rx(A_UINT32 reg_id, A_UINT32 value) ++{ ++ gpio_reg_results.gpioreg_id = reg_id; ++ gpio_reg_results.value = value; ++ *((volatile A_BOOL *)&gpio_data_available) = TRUE; ++ wake_up(&arEvent); ++} ++ ++/* ++ * This is called when an acknowledgement is received from the Target ++ * for a previous or ar6000_gpio_output_set or ar6000_gpio_register_set ++ * call. ++ */ ++void ++ar6000_gpio_ack_rx(void) ++{ ++ gpio_ack_received = TRUE; ++ wake_up(&arEvent); ++} ++ ++A_STATUS ++ar6000_gpio_output_set(struct net_device *dev, ++ A_UINT32 set_mask, ++ A_UINT32 clear_mask, ++ A_UINT32 enable_mask, ++ A_UINT32 disable_mask) ++{ ++ AR_SOFTC_T *ar = (AR_SOFTC_T *)netdev_priv(dev); ++ ++ gpio_ack_received = FALSE; ++ return wmi_gpio_output_set(ar->arWmi, ++ set_mask, clear_mask, enable_mask, disable_mask); ++} ++ ++static A_STATUS ++ar6000_gpio_input_get(struct net_device *dev) ++{ ++ AR_SOFTC_T *ar = (AR_SOFTC_T *)netdev_priv(dev); ++ ++ *((volatile A_BOOL *)&gpio_data_available) = FALSE; ++ return wmi_gpio_input_get(ar->arWmi); ++} ++ ++static A_STATUS ++ar6000_gpio_register_set(struct net_device *dev, ++ A_UINT32 gpioreg_id, ++ A_UINT32 value) ++{ ++ AR_SOFTC_T *ar = (AR_SOFTC_T *)netdev_priv(dev); ++ ++ gpio_ack_received = FALSE; ++ return wmi_gpio_register_set(ar->arWmi, gpioreg_id, value); ++} ++ ++static A_STATUS ++ar6000_gpio_register_get(struct net_device *dev, ++ A_UINT32 gpioreg_id) ++{ ++ AR_SOFTC_T *ar = (AR_SOFTC_T *)netdev_priv(dev); ++ ++ *((volatile A_BOOL *)&gpio_data_available) = FALSE; ++ return wmi_gpio_register_get(ar->arWmi, gpioreg_id); ++} ++ ++static A_STATUS ++ar6000_gpio_intr_ack(struct net_device *dev, ++ A_UINT32 ack_mask) ++{ ++ AR_SOFTC_T *ar = (AR_SOFTC_T *)netdev_priv(dev); ++ ++ gpio_intr_available = FALSE; ++ return wmi_gpio_intr_ack(ar->arWmi, ack_mask); ++} ++#endif /* CONFIG_HOST_GPIO_SUPPORT */ ++ ++int ar6000_ioctl(struct net_device *dev, struct ifreq *rq, int cmd) ++{ ++ AR_SOFTC_T *ar = (AR_SOFTC_T *)netdev_priv(dev); ++ HIF_DEVICE *hifDevice = ar->arHifDevice; ++ int ret, param, param2; ++ unsigned int address = 0; ++ unsigned int length = 0; ++ unsigned char *buffer; ++ char *userdata; ++ A_UINT32 connectCtrlFlags; ++ ++ ++ static WMI_SCAN_PARAMS_CMD scParams = {0, 0, 0, 0, 0, ++ WMI_SHORTSCANRATIO_DEFAULT, ++ DEFAULT_SCAN_CTRL_FLAGS, ++ 0}; ++ WMI_SET_AKMP_PARAMS_CMD akmpParams; ++ WMI_SET_PMKID_LIST_CMD pmkidInfo; ++ ++ if (cmd == AR6000_IOCTL_EXTENDED) ++ { ++ /* ++ * This allows for many more wireless ioctls than would otherwise ++ * be available. Applications embed the actual ioctl command in ++ * the first word of the parameter block, and use the command ++ * AR6000_IOCTL_EXTENDED_CMD on the ioctl call. ++ */ ++ get_user(cmd, (int *)rq->ifr_data); ++ userdata = (char *)(((unsigned int *)rq->ifr_data)+1); ++ } ++ else ++ { ++ userdata = (char *)rq->ifr_data; ++ } ++ ++ if ((ar->arWlanState == WLAN_DISABLED) && ++ ((cmd != AR6000_XIOCTRL_WMI_SET_WLAN_STATE) && ++ (cmd != AR6000_XIOCTL_DIAG_READ) && ++ (cmd != AR6000_XIOCTL_DIAG_WRITE))) ++ { ++ return -EIO; ++ } ++ ++ ret = 0; ++ switch(cmd) ++ { ++#ifdef CONFIG_HOST_TCMD_SUPPORT ++ case AR6000_XIOCTL_TCMD_CONT_TX: ++ { ++ TCMD_CONT_TX txCmd; ++ ++ if (ar->tcmdPm == TCMD_PM_SLEEP) { ++ A_PRINTF("Can NOT send tx tcmd when target is asleep! \n"); ++ return -EFAULT; ++ } ++ ++ if(copy_from_user(&txCmd, userdata, sizeof(TCMD_CONT_TX))) ++ return -EFAULT; ++ wmi_test_cmd(ar->arWmi,(A_UINT8 *)&txCmd, sizeof(TCMD_CONT_TX)); ++ } ++ break; ++ case AR6000_XIOCTL_TCMD_CONT_RX: ++ { ++ TCMD_CONT_RX rxCmd; ++ ++ if (ar->tcmdPm == TCMD_PM_SLEEP) { ++ A_PRINTF("Can NOT send rx tcmd when target is asleep! \n"); ++ return -EFAULT; ++ } ++ if(copy_from_user(&rxCmd, userdata, sizeof(TCMD_CONT_RX))) ++ return -EFAULT; ++ switch(rxCmd.act) ++ { ++ case TCMD_CONT_RX_PROMIS: ++ case TCMD_CONT_RX_FILTER: ++ case TCMD_CONT_RX_SETMAC: ++ wmi_test_cmd(ar->arWmi,(A_UINT8 *)&rxCmd, ++ sizeof(TCMD_CONT_RX)); ++ break; ++ case TCMD_CONT_RX_REPORT: ++ ar6000_ioctl_tcmd_get_rx_report(dev, rq, ++ (A_UINT8 *)&rxCmd, sizeof(TCMD_CONT_RX)); ++ break; ++ default: ++ A_PRINTF("Unknown Cont Rx mode: %d\n",rxCmd.act); ++ return -EINVAL; ++ } ++ } ++ break; ++ case AR6000_XIOCTL_TCMD_PM: ++ { ++ TCMD_PM pmCmd; ++ ++ if(copy_from_user(&pmCmd, userdata, sizeof(TCMD_PM))) ++ return -EFAULT; ++ ar->tcmdPm = pmCmd.mode; ++ wmi_test_cmd(ar->arWmi, (A_UINT8*)&pmCmd, sizeof(TCMD_PM)); ++ } ++ break; ++#endif /* CONFIG_HOST_TCMD_SUPPORT */ ++ ++ case AR6000_XIOCTL_BMI_DONE: ++ if(bmienable) ++ { ++ ret = ar6000_init(dev); ++ } ++ else ++ { ++ ret = BMIDone(hifDevice); ++ } ++ break; ++ ++ case AR6000_XIOCTL_BMI_READ_MEMORY: ++ get_user(address, (unsigned int *)userdata); ++ get_user(length, (unsigned int *)userdata + 1); ++ AR_DEBUG_PRINTF("Read Memory (address: 0x%x, length: %d)\n", ++ address, length); ++ if ((buffer = (unsigned char *)A_MALLOC(length)) != NULL) { ++ A_MEMZERO(buffer, length); ++ ret = BMIReadMemory(hifDevice, address, buffer, length); ++ if (copy_to_user(rq->ifr_data, buffer, length)) { ++ ret = -EFAULT; ++ } ++ A_FREE(buffer); ++ } else { ++ ret = -ENOMEM; ++ } ++ break; ++ ++ case AR6000_XIOCTL_BMI_WRITE_MEMORY: ++ get_user(address, (unsigned int *)userdata); ++ get_user(length, (unsigned int *)userdata + 1); ++ AR_DEBUG_PRINTF("Write Memory (address: 0x%x, length: %d)\n", ++ address, length); ++ if ((buffer = (unsigned char *)A_MALLOC(length)) != NULL) { ++ A_MEMZERO(buffer, length); ++ if (copy_from_user(buffer, &userdata[sizeof(address) + ++ sizeof(length)], length)) ++ { ++ ret = -EFAULT; ++ } else { ++ ret = BMIWriteMemory(hifDevice, address, buffer, length); ++ } ++ A_FREE(buffer); ++ } else { ++ ret = -ENOMEM; ++ } ++ break; ++ ++ case AR6000_XIOCTL_BMI_TEST: ++ AR_DEBUG_PRINTF("No longer supported\n"); ++ ret = -EOPNOTSUPP; ++ break; ++ ++ case AR6000_XIOCTL_BMI_EXECUTE: ++ get_user(address, (unsigned int *)userdata); ++ get_user(param, (unsigned int *)userdata + 1); ++ AR_DEBUG_PRINTF("Execute (address: 0x%x, param: %d)\n", ++ address, param); ++ ret = BMIExecute(hifDevice, address, ¶m); ++ put_user(param, (unsigned int *)rq->ifr_data); /* return value */ ++ break; ++ ++ case AR6000_XIOCTL_BMI_SET_APP_START: ++ get_user(address, (unsigned int *)userdata); ++ AR_DEBUG_PRINTF("Set App Start (address: 0x%x)\n", address); ++ ret = BMISetAppStart(hifDevice, address); ++ break; ++ ++ case AR6000_XIOCTL_BMI_READ_SOC_REGISTER: ++ get_user(address, (unsigned int *)userdata); ++ ret = BMIReadSOCRegister(hifDevice, address, ¶m); ++ put_user(param, (unsigned int *)rq->ifr_data); /* return value */ ++ break; ++ ++ case AR6000_XIOCTL_BMI_WRITE_SOC_REGISTER: ++ get_user(address, (unsigned int *)userdata); ++ get_user(param, (unsigned int *)userdata + 1); ++ ret = BMIWriteSOCRegister(hifDevice, address, param); ++ break; ++ ++#ifdef HTC_RAW_INTERFACE ++ case AR6000_XIOCTL_HTC_RAW_OPEN: ++ ret = A_OK; ++ if (!arRawIfEnabled(ar)) { ++ /* make sure block size is set in case the target was reset since last ++ * BMI phase (i.e. flashup downloads) */ ++ ret = ar6000_SetHTCBlockSize(ar); ++ if (A_FAILED(ret)) { ++ break; ++ } ++ /* Terminate the BMI phase */ ++ ret = BMIDone(hifDevice); ++ if (ret == A_OK) { ++ ret = ar6000_htc_raw_open(ar); ++ } ++ } ++ break; ++ ++ case AR6000_XIOCTL_HTC_RAW_CLOSE: ++ if (arRawIfEnabled(ar)) { ++ ret = ar6000_htc_raw_close(ar); ++ arRawIfEnabled(ar) = FALSE; ++ } else { ++ ret = A_ERROR; ++ } ++ break; ++ ++ case AR6000_XIOCTL_HTC_RAW_READ: ++ if (arRawIfEnabled(ar)) { ++ unsigned int streamID; ++ get_user(streamID, (unsigned int *)userdata); ++ get_user(length, (unsigned int *)userdata + 1); ++ buffer = rq->ifr_data + sizeof(length); ++ ret = ar6000_htc_raw_read(ar, (HTC_RAW_STREAM_ID)streamID, ++ buffer, length); ++ put_user(ret, (unsigned int *)rq->ifr_data); ++ } else { ++ ret = A_ERROR; ++ } ++ break; ++ ++ case AR6000_XIOCTL_HTC_RAW_WRITE: ++ if (arRawIfEnabled(ar)) { ++ unsigned int streamID; ++ get_user(streamID, (unsigned int *)userdata); ++ get_user(length, (unsigned int *)userdata + 1); ++ buffer = userdata + sizeof(streamID) + sizeof(length); ++ ret = ar6000_htc_raw_write(ar, (HTC_RAW_STREAM_ID)streamID, ++ buffer, length); ++ put_user(ret, (unsigned int *)rq->ifr_data); ++ } else { ++ ret = A_ERROR; ++ } ++ break; ++#endif /* HTC_RAW_INTERFACE */ ++ ++ case AR6000_IOCTL_WMI_GETREV: ++ { ++ if (copy_to_user(rq->ifr_data, &ar->arVersion, ++ sizeof(ar->arVersion))) ++ { ++ ret = -EFAULT; ++ } ++ break; ++ } ++ case AR6000_IOCTL_WMI_SETPWR: ++ { ++ WMI_POWER_MODE_CMD pwrModeCmd; ++ ++ if (ar->arWmiReady == FALSE) { ++ ret = -EIO; ++ } else if (copy_from_user(&pwrModeCmd, userdata, ++ sizeof(pwrModeCmd))) ++ { ++ ret = -EFAULT; ++ } else { ++ if (wmi_powermode_cmd(ar->arWmi, pwrModeCmd.powerMode) ++ != A_OK) ++ { ++ ret = -EIO; ++ } ++ } ++ break; ++ } ++ case AR6000_IOCTL_WMI_SET_IBSS_PM_CAPS: ++ { ++ WMI_IBSS_PM_CAPS_CMD ibssPmCaps; ++ ++ if (ar->arWmiReady == FALSE) { ++ ret = -EIO; ++ } else if (copy_from_user(&ibssPmCaps, userdata, ++ sizeof(ibssPmCaps))) ++ { ++ ret = -EFAULT; ++ } else { ++ if (wmi_ibsspmcaps_cmd(ar->arWmi, ibssPmCaps.power_saving, ibssPmCaps.ttl, ++ ibssPmCaps.atim_windows, ibssPmCaps.timeout_value) != A_OK) ++ { ++ ret = -EIO; ++ } ++ AR6000_SPIN_LOCK(&ar->arLock, 0); ++ ar->arIbssPsEnable = ibssPmCaps.power_saving; ++ AR6000_SPIN_UNLOCK(&ar->arLock, 0); ++ } ++ break; ++ } ++ case AR6000_IOCTL_WMI_SET_PMPARAMS: ++ { ++ WMI_POWER_PARAMS_CMD pmParams; ++ ++ if (ar->arWmiReady == FALSE) { ++ ret = -EIO; ++ } else if (copy_from_user(&pmParams, userdata, ++ sizeof(pmParams))) ++ { ++ ret = -EFAULT; ++ } else { ++ if (wmi_pmparams_cmd(ar->arWmi, pmParams.idle_period, ++ pmParams.pspoll_number, ++ pmParams.dtim_policy) != A_OK) ++ { ++ ret = -EIO; ++ } ++ } ++ break; ++ } ++ case AR6000_IOCTL_WMI_SETSCAN: ++ { ++ if (ar->arWmiReady == FALSE) { ++ ret = -EIO; ++ } else if (copy_from_user(&scParams, userdata, ++ sizeof(scParams))) ++ { ++ ret = -EFAULT; ++ } else { ++ if (CAN_SCAN_IN_CONNECT(scParams.scanCtrlFlags)) { ++ ar->arSkipScan = FALSE; ++ } else { ++ ar->arSkipScan = TRUE; ++ } ++ ++ if (wmi_scanparams_cmd(ar->arWmi, scParams.fg_start_period, ++ scParams.fg_end_period, ++ scParams.bg_period, ++ scParams.minact_chdwell_time, ++ scParams.maxact_chdwell_time, ++ scParams.pas_chdwell_time, ++ scParams.shortScanRatio, ++ scParams.scanCtrlFlags, ++ scParams.max_dfsch_act_time) != A_OK) ++ { ++ ret = -EIO; ++ } ++ } ++ break; ++ } ++ case AR6000_IOCTL_WMI_SETLISTENINT: ++ { ++ WMI_LISTEN_INT_CMD listenCmd; ++ ++ if (ar->arWmiReady == FALSE) { ++ ret = -EIO; ++ } else if (copy_from_user(&listenCmd, userdata, ++ sizeof(listenCmd))) ++ { ++ ret = -EFAULT; ++ } else { ++ if (wmi_listeninterval_cmd(ar->arWmi, listenCmd.listenInterval, listenCmd.numBeacons) != A_OK) { ++ ret = -EIO; ++ } else { ++ AR6000_SPIN_LOCK(&ar->arLock, 0); ++ ar->arListenInterval = param; ++ AR6000_SPIN_UNLOCK(&ar->arLock, 0); ++ } ++ ++ } ++ break; ++ } ++ case AR6000_IOCTL_WMI_SET_BMISS_TIME: ++ { ++ WMI_BMISS_TIME_CMD bmissCmd; ++ ++ if (ar->arWmiReady == FALSE) { ++ ret = -EIO; ++ } else if (copy_from_user(&bmissCmd, userdata, ++ sizeof(bmissCmd))) ++ { ++ ret = -EFAULT; ++ } else { ++ if (wmi_bmisstime_cmd(ar->arWmi, bmissCmd.bmissTime, bmissCmd.numBeacons) != A_OK) { ++ ret = -EIO; ++ } ++ } ++ break; ++ } ++ case AR6000_IOCTL_WMI_SETBSSFILTER: ++ { ++ if (ar->arWmiReady == FALSE) { ++ ret = -EIO; ++ } else { ++ ++ get_user(param, (unsigned char *)userdata); ++ get_user(param2, (unsigned int *)(userdata + 1)); ++ printk("SETBSSFILTER: filter 0x%x, mask: 0x%x\n", param, param2); ++ if (wmi_bssfilter_cmd(ar->arWmi, param, param2) != A_OK) { ++ ret = -EIO; ++ } ++ } ++ break; ++ } ++ case AR6000_IOCTL_WMI_SET_SNRTHRESHOLD: ++ { ++ ret = ar6000_ioctl_set_snr_threshold(dev, rq); ++ break; ++ } ++ case AR6000_XIOCTL_WMI_SET_RSSITHRESHOLD: ++ { ++ ret = ar6000_ioctl_set_rssi_threshold(dev, rq); ++ break; ++ } ++ case AR6000_XIOCTL_WMI_CLR_RSSISNR: ++ { ++ if (ar->arWmiReady == FALSE) { ++ ret = -EIO; ++ } ++ ret = wmi_clr_rssi_snr(ar->arWmi); ++ break; ++ } ++ case AR6000_XIOCTL_WMI_SET_LQTHRESHOLD: ++ { ++ ret = ar6000_ioctl_set_lq_threshold(dev, rq); ++ break; ++ } ++ case AR6000_XIOCTL_WMI_SET_LPREAMBLE: ++ { ++ WMI_SET_LPREAMBLE_CMD setLpreambleCmd; ++ ++ if (ar->arWmiReady == FALSE) { ++ ret = -EIO; ++ } else if (copy_from_user(&setLpreambleCmd, userdata, ++ sizeof(setLpreambleCmd))) ++ { ++ ret = -EFAULT; ++ } else { ++ if (wmi_set_lpreamble_cmd(ar->arWmi, setLpreambleCmd.status) ++ != A_OK) ++ { ++ ret = -EIO; ++ } ++ } ++ ++ break; ++ } ++ case AR6000_XIOCTL_WMI_SET_RTS: ++ { ++ WMI_SET_RTS_CMD rtsCmd; ++ ++ if (ar->arWmiReady == FALSE) { ++ ret = -EIO; ++ } else if (copy_from_user(&rtsCmd, userdata, ++ sizeof(rtsCmd))) ++ { ++ ret = -EFAULT; ++ } else { ++ if (wmi_set_rts_cmd(ar->arWmi, rtsCmd.threshold) ++ != A_OK) ++ { ++ ret = -EIO; ++ } ++ } ++ ++ break; ++ } ++ case AR6000_XIOCTL_WMI_SET_WMM: ++ { ++ ret = ar6000_ioctl_set_wmm(dev, rq); ++ break; ++ } ++ case AR6000_XIOCTL_WMI_SET_TXOP: ++ { ++ ret = ar6000_ioctl_set_txop(dev, rq); ++ break; ++ } ++ case AR6000_XIOCTL_WMI_GET_RD: ++ { ++ ret = ar6000_ioctl_get_rd(dev, rq); ++ break; ++ } ++ case AR6000_IOCTL_WMI_SET_CHANNELPARAMS: ++ { ++ ret = ar6000_ioctl_set_channelParams(dev, rq); ++ break; ++ } ++ case AR6000_IOCTL_WMI_SET_PROBEDSSID: ++ { ++ ret = ar6000_ioctl_set_probedSsid(dev, rq); ++ break; ++ } ++ case AR6000_IOCTL_WMI_SET_BADAP: ++ { ++ ret = ar6000_ioctl_set_badAp(dev, rq); ++ break; ++ } ++ case AR6000_IOCTL_WMI_CREATE_QOS: ++ { ++ ret = ar6000_ioctl_create_qos(dev, rq); ++ break; ++ } ++ case AR6000_IOCTL_WMI_DELETE_QOS: ++ { ++ ret = ar6000_ioctl_delete_qos(dev, rq); ++ break; ++ } ++ case AR6000_IOCTL_WMI_GET_QOS_QUEUE: ++ { ++ ret = ar6000_ioctl_get_qos_queue(dev, rq); ++ break; ++ } ++ case AR6000_IOCTL_WMI_GET_TARGET_STATS: ++ { ++ ret = ar6000_ioctl_get_target_stats(dev, rq); ++ break; ++ } ++ case AR6000_IOCTL_WMI_SET_ERROR_REPORT_BITMASK: ++ { ++ ret = ar6000_ioctl_set_error_report_bitmask(dev, rq); ++ break; ++ } ++ case AR6000_IOCTL_WMI_SET_ASSOC_INFO: ++ { ++ WMI_SET_ASSOC_INFO_CMD cmd; ++ A_UINT8 assocInfo[WMI_MAX_ASSOC_INFO_LEN]; ++ ++ if (ar->arWmiReady == FALSE) { ++ ret = -EIO; ++ } else { ++ get_user(cmd.ieType, userdata); ++ if (cmd.ieType >= WMI_MAX_ASSOC_INFO_TYPE) { ++ ret = -EIO; ++ } else { ++ get_user(cmd.bufferSize, userdata + 1); ++ if (cmd.bufferSize > WMI_MAX_ASSOC_INFO_LEN) { ++ ret = -EFAULT; ++ break; ++ } ++ if (copy_from_user(assocInfo, userdata + 2, ++ cmd.bufferSize)) ++ { ++ ret = -EFAULT; ++ } else { ++ if (wmi_associnfo_cmd(ar->arWmi, cmd.ieType, ++ cmd.bufferSize, ++ assocInfo) != A_OK) ++ { ++ ret = -EIO; ++ } ++ } ++ } ++ } ++ break; ++ } ++ case AR6000_IOCTL_WMI_SET_ACCESS_PARAMS: ++ { ++ ret = ar6000_ioctl_set_access_params(dev, rq); ++ break; ++ } ++ case AR6000_IOCTL_WMI_SET_DISC_TIMEOUT: ++ { ++ ret = ar6000_ioctl_set_disconnect_timeout(dev, rq); ++ break; ++ } ++ case AR6000_XIOCTL_FORCE_TARGET_RESET: ++ { ++ if (ar->arHtcTarget) ++ { ++// HTCForceReset(htcTarget); ++ } ++ else ++ { ++ AR_DEBUG_PRINTF("ar6000_ioctl cannot attempt reset.\n"); ++ } ++ break; ++ } ++ case AR6000_XIOCTL_TARGET_INFO: ++ case AR6000_XIOCTL_CHECK_TARGET_READY: /* backwards compatibility */ ++ { ++ /* If we made it to here, then the Target exists and is ready. */ ++ ++ if (cmd == AR6000_XIOCTL_TARGET_INFO) { ++ if (copy_to_user((A_UINT32 *)rq->ifr_data, &ar->arVersion.target_ver, ++ sizeof(ar->arVersion.target_ver))) ++ { ++ ret = -EFAULT; ++ } ++ if (copy_to_user(((A_UINT32 *)rq->ifr_data)+1, &ar->arTargetType, ++ sizeof(ar->arTargetType))) ++ { ++ ret = -EFAULT; ++ } ++ } ++ break; ++ } ++ case AR6000_XIOCTL_WMI_SET_HB_CHALLENGE_RESP_PARAMS: ++ { ++ WMI_SET_HB_CHALLENGE_RESP_PARAMS_CMD hbparam; ++ ++ if (copy_from_user(&hbparam, userdata, sizeof(hbparam))) ++ { ++ ret = -EFAULT; ++ } else { ++ AR6000_SPIN_LOCK(&ar->arLock, 0); ++ /* Start a cyclic timer with the parameters provided. */ ++ if (hbparam.frequency) { ++ ar->arHBChallengeResp.frequency = hbparam.frequency; ++ } ++ if (hbparam.threshold) { ++ ar->arHBChallengeResp.missThres = hbparam.threshold; ++ } ++ ++ /* Delete the pending timer and start a new one */ ++ if (timer_pending(&ar->arHBChallengeResp.timer)) { ++ A_UNTIMEOUT(&ar->arHBChallengeResp.timer); ++ } ++ A_TIMEOUT_MS(&ar->arHBChallengeResp.timer, ar->arHBChallengeResp.frequency * 1000, 0); ++ AR6000_SPIN_UNLOCK(&ar->arLock, 0); ++ } ++ break; ++ } ++ case AR6000_XIOCTL_WMI_GET_HB_CHALLENGE_RESP: ++ { ++ A_UINT32 cookie; ++ ++ if (copy_from_user(&cookie, userdata, sizeof(cookie))) { ++ return -EFAULT; ++ } ++ ++ /* Send the challenge on the control channel */ ++ if (wmi_get_challenge_resp_cmd(ar->arWmi, cookie, APP_HB_CHALLENGE) != A_OK) { ++ return -EIO; ++ } ++ break; ++ } ++#ifdef USER_KEYS ++ case AR6000_XIOCTL_USER_SETKEYS: ++ { ++ ++ ar->user_savedkeys_stat = USER_SAVEDKEYS_STAT_RUN; ++ ++ if (copy_from_user(&ar->user_key_ctrl, userdata, ++ sizeof(ar->user_key_ctrl))) ++ { ++ return -EFAULT; ++ } ++ ++ A_PRINTF("ar6000 USER set key %x\n", ar->user_key_ctrl); ++ break; ++ } ++#endif /* USER_KEYS */ ++ ++#ifdef CONFIG_HOST_GPIO_SUPPORT ++ case AR6000_XIOCTL_GPIO_OUTPUT_SET: ++ { ++ struct ar6000_gpio_output_set_cmd_s gpio_output_set_cmd; ++ ++ if (ar->arWmiReady == FALSE) { ++ return -EIO; ++ } ++ if (down_interruptible(&ar->arSem)) { ++ return -ERESTARTSYS; ++ } ++ ++ if (copy_from_user(&gpio_output_set_cmd, userdata, ++ sizeof(gpio_output_set_cmd))) ++ { ++ ret = -EFAULT; ++ } else { ++ ret = ar6000_gpio_output_set(dev, ++ gpio_output_set_cmd.set_mask, ++ gpio_output_set_cmd.clear_mask, ++ gpio_output_set_cmd.enable_mask, ++ gpio_output_set_cmd.disable_mask); ++ if (ret != A_OK) { ++ ret = EIO; ++ } ++ } ++ up(&ar->arSem); ++ break; ++ } ++ case AR6000_XIOCTL_GPIO_INPUT_GET: ++ { ++ if (ar->arWmiReady == FALSE) { ++ return -EIO; ++ } ++ if (down_interruptible(&ar->arSem)) { ++ return -ERESTARTSYS; ++ } ++ ++ ret = ar6000_gpio_input_get(dev); ++ if (ret != A_OK) { ++ up(&ar->arSem); ++ return -EIO; ++ } ++ ++ /* Wait for Target to respond. */ ++ wait_event_interruptible(arEvent, gpio_data_available); ++ if (signal_pending(current)) { ++ ret = -EINTR; ++ } else { ++ A_ASSERT(gpio_reg_results.gpioreg_id == GPIO_ID_NONE); ++ ++ if (copy_to_user(userdata, &gpio_reg_results.value, ++ sizeof(gpio_reg_results.value))) ++ { ++ ret = -EFAULT; ++ } ++ } ++ up(&ar->arSem); ++ break; ++ } ++ case AR6000_XIOCTL_GPIO_REGISTER_SET: ++ { ++ struct ar6000_gpio_register_cmd_s gpio_register_cmd; ++ ++ if (ar->arWmiReady == FALSE) { ++ return -EIO; ++ } ++ if (down_interruptible(&ar->arSem)) { ++ return -ERESTARTSYS; ++ } ++ ++ if (copy_from_user(&gpio_register_cmd, userdata, ++ sizeof(gpio_register_cmd))) ++ { ++ ret = -EFAULT; ++ } else { ++ ret = ar6000_gpio_register_set(dev, ++ gpio_register_cmd.gpioreg_id, ++ gpio_register_cmd.value); ++ if (ret != A_OK) { ++ ret = EIO; ++ } ++ ++ /* Wait for acknowledgement from Target */ ++ wait_event_interruptible(arEvent, gpio_ack_received); ++ if (signal_pending(current)) { ++ ret = -EINTR; ++ } ++ } ++ up(&ar->arSem); ++ break; ++ } ++ case AR6000_XIOCTL_GPIO_REGISTER_GET: ++ { ++ struct ar6000_gpio_register_cmd_s gpio_register_cmd; ++ ++ if (ar->arWmiReady == FALSE) { ++ return -EIO; ++ } ++ if (down_interruptible(&ar->arSem)) { ++ return -ERESTARTSYS; ++ } ++ ++ if (copy_from_user(&gpio_register_cmd, userdata, ++ sizeof(gpio_register_cmd))) ++ { ++ ret = -EFAULT; ++ } else { ++ ret = ar6000_gpio_register_get(dev, gpio_register_cmd.gpioreg_id); ++ if (ret != A_OK) { ++ up(&ar->arSem); ++ return -EIO; ++ } ++ ++ /* Wait for Target to respond. */ ++ wait_event_interruptible(arEvent, gpio_data_available); ++ if (signal_pending(current)) { ++ ret = -EINTR; ++ } else { ++ A_ASSERT(gpio_register_cmd.gpioreg_id == gpio_reg_results.gpioreg_id); ++ if (copy_to_user(userdata, &gpio_reg_results, ++ sizeof(gpio_reg_results))) ++ { ++ ret = -EFAULT; ++ } ++ } ++ } ++ up(&ar->arSem); ++ break; ++ } ++ case AR6000_XIOCTL_GPIO_INTR_ACK: ++ { ++ struct ar6000_gpio_intr_ack_cmd_s gpio_intr_ack_cmd; ++ ++ if (ar->arWmiReady == FALSE) { ++ return -EIO; ++ } ++ if (down_interruptible(&ar->arSem)) { ++ return -ERESTARTSYS; ++ } ++ ++ if (copy_from_user(&gpio_intr_ack_cmd, userdata, ++ sizeof(gpio_intr_ack_cmd))) ++ { ++ ret = -EFAULT; ++ } else { ++ ret = ar6000_gpio_intr_ack(dev, gpio_intr_ack_cmd.ack_mask); ++ if (ret != A_OK) { ++ ret = EIO; ++ } ++ } ++ up(&ar->arSem); ++ break; ++ } ++ case AR6000_XIOCTL_GPIO_INTR_WAIT: ++ { ++ /* Wait for Target to report an interrupt. */ ++ dev_hold(dev); ++ rtnl_unlock(); ++ wait_event_interruptible(arEvent, gpio_intr_available); ++ rtnl_lock(); ++ __dev_put(dev); ++ ++ if (signal_pending(current)) { ++ ret = -EINTR; ++ } else { ++ if (copy_to_user(userdata, &gpio_intr_results, ++ sizeof(gpio_intr_results))) ++ { ++ ret = -EFAULT; ++ } ++ } ++ break; ++ } ++#endif /* CONFIG_HOST_GPIO_SUPPORT */ ++ ++ case AR6000_XIOCTL_DBGLOG_CFG_MODULE: ++ { ++ struct ar6000_dbglog_module_config_s config; ++ ++ if (copy_from_user(&config, userdata, sizeof(config))) { ++ return -EFAULT; ++ } ++ ++ /* Send the challenge on the control channel */ ++ if (wmi_config_debug_module_cmd(ar->arWmi, config.mmask, ++ config.tsr, config.rep, ++ config.size, config.valid) != A_OK) ++ { ++ return -EIO; ++ } ++ break; ++ } ++ ++ case AR6000_XIOCTL_DBGLOG_GET_DEBUG_LOGS: ++ { ++ /* Send the challenge on the control channel */ ++ if (ar6000_dbglog_get_debug_logs(ar) != A_OK) ++ { ++ return -EIO; ++ } ++ break; ++ } ++ ++ case AR6000_XIOCTL_SET_ADHOC_BSSID: ++ { ++ WMI_SET_ADHOC_BSSID_CMD adhocBssid; ++ ++ if (ar->arWmiReady == FALSE) { ++ ret = -EIO; ++ } else if (copy_from_user(&adhocBssid, userdata, ++ sizeof(adhocBssid))) ++ { ++ ret = -EFAULT; ++ } else if (A_MEMCMP(adhocBssid.bssid, bcast_mac, ++ AR6000_ETH_ADDR_LEN) == 0) ++ { ++ ret = -EFAULT; ++ } else { ++ ++ A_MEMCPY(ar->arReqBssid, adhocBssid.bssid, sizeof(ar->arReqBssid)); ++ } ++ break; ++ } ++ ++ case AR6000_XIOCTL_SET_OPT_MODE: ++ { ++ WMI_SET_OPT_MODE_CMD optModeCmd; ++ AR_SOFTC_T *ar = (AR_SOFTC_T *)netdev_priv(dev); ++ ++ if (ar->arWmiReady == FALSE) { ++ ret = -EIO; ++ } else if (copy_from_user(&optModeCmd, userdata, ++ sizeof(optModeCmd))) ++ { ++ ret = -EFAULT; ++ } else if (ar->arConnected && optModeCmd.optMode == SPECIAL_ON) { ++ ret = -EFAULT; ++ ++ } else if (wmi_set_opt_mode_cmd(ar->arWmi, optModeCmd.optMode) ++ != A_OK) ++ { ++ ret = -EIO; ++ } ++ break; ++ } ++ ++ case AR6000_XIOCTL_OPT_SEND_FRAME: ++ { ++ WMI_OPT_TX_FRAME_CMD optTxFrmCmd; ++ A_UINT8 data[MAX_OPT_DATA_LEN]; ++ ++ if (ar->arWmiReady == FALSE) { ++ ret = -EIO; ++ } else if (copy_from_user(&optTxFrmCmd, userdata, ++ sizeof(optTxFrmCmd))) ++ { ++ ret = -EFAULT; ++ } else if (copy_from_user(data, ++ userdata+sizeof(WMI_OPT_TX_FRAME_CMD)-1, ++ optTxFrmCmd.optIEDataLen)) ++ { ++ ret = -EFAULT; ++ } else { ++ ret = wmi_opt_tx_frame_cmd(ar->arWmi, ++ optTxFrmCmd.frmType, ++ optTxFrmCmd.dstAddr, ++ optTxFrmCmd.bssid, ++ optTxFrmCmd.optIEDataLen, ++ data); ++ } ++ ++ break; ++ } ++ case AR6000_XIOCTL_WMI_SETRETRYLIMITS: ++ { ++ WMI_SET_RETRY_LIMITS_CMD setRetryParams; ++ ++ if (ar->arWmiReady == FALSE) { ++ ret = -EIO; ++ } else if (copy_from_user(&setRetryParams, userdata, ++ sizeof(setRetryParams))) ++ { ++ ret = -EFAULT; ++ } else { ++ if (wmi_set_retry_limits_cmd(ar->arWmi, setRetryParams.frameType, ++ setRetryParams.trafficClass, ++ setRetryParams.maxRetries, ++ setRetryParams.enableNotify) != A_OK) ++ { ++ ret = -EIO; ++ } ++ AR6000_SPIN_LOCK(&ar->arLock, 0); ++ ar->arMaxRetries = setRetryParams.maxRetries; ++ AR6000_SPIN_UNLOCK(&ar->arLock, 0); ++ } ++ break; ++ } ++ ++ case AR6000_XIOCTL_SET_ADHOC_BEACON_INTVAL: ++ { ++ WMI_BEACON_INT_CMD bIntvlCmd; ++ ++ if (ar->arWmiReady == FALSE) { ++ ret = -EIO; ++ } else if (copy_from_user(&bIntvlCmd, userdata, ++ sizeof(bIntvlCmd))) ++ { ++ ret = -EFAULT; ++ } else if (wmi_set_adhoc_bconIntvl_cmd(ar->arWmi, bIntvlCmd.beaconInterval) ++ != A_OK) ++ { ++ ret = -EIO; ++ } ++ break; ++ } ++ case IEEE80211_IOCTL_SETAUTHALG: ++ { ++ AR_SOFTC_T *ar = (AR_SOFTC_T *)netdev_priv(dev); ++ struct ieee80211req_authalg req; ++ ++ if (ar->arWmiReady == FALSE) { ++ ret = -EIO; ++ } else if (copy_from_user(&req, userdata, ++ sizeof(struct ieee80211req_authalg))) ++ { ++ ret = -EFAULT; ++ } else if (req.auth_alg == AUTH_ALG_OPEN_SYSTEM) { ++ ar->arDot11AuthMode = OPEN_AUTH; ++ ar->arPairwiseCrypto = NONE_CRYPT; ++ ar->arGroupCrypto = NONE_CRYPT; ++ } else if (req.auth_alg == AUTH_ALG_LEAP) { ++ ar->arDot11AuthMode = LEAP_AUTH; ++ } else { ++ ret = -EIO; ++ } ++ break; ++ } ++ ++ case AR6000_XIOCTL_SET_VOICE_PKT_SIZE: ++ ret = ar6000_xioctl_set_voice_pkt_size(dev, userdata); ++ break; ++ ++ case AR6000_XIOCTL_SET_MAX_SP: ++ ret = ar6000_xioctl_set_max_sp_len(dev, userdata); ++ break; ++ ++ case AR6000_XIOCTL_WMI_GET_ROAM_TBL: ++ ret = ar6000_ioctl_get_roam_tbl(dev, rq); ++ break; ++ case AR6000_XIOCTL_WMI_SET_ROAM_CTRL: ++ ret = ar6000_ioctl_set_roam_ctrl(dev, userdata); ++ break; ++ case AR6000_XIOCTRL_WMI_SET_POWERSAVE_TIMERS: ++ ret = ar6000_ioctl_set_powersave_timers(dev, userdata); ++ break; ++ case AR6000_XIOCTRL_WMI_GET_POWER_MODE: ++ ret = ar6000_ioctl_get_power_mode(dev, rq); ++ break; ++ case AR6000_XIOCTRL_WMI_SET_WLAN_STATE: ++ get_user(ar->arWlanState, (unsigned int *)userdata); ++ if (ar->arWmiReady == FALSE) { ++ ret = -EIO; ++ break; ++ } ++ ++ if (ar->arWlanState == WLAN_ENABLED) { ++ /* Enable foreground scanning */ ++ if (wmi_scanparams_cmd(ar->arWmi, scParams.fg_start_period, ++ scParams.fg_end_period, ++ scParams.bg_period, ++ scParams.minact_chdwell_time, ++ scParams.maxact_chdwell_time, ++ scParams.pas_chdwell_time, ++ scParams.shortScanRatio, ++ scParams.scanCtrlFlags, ++ scParams.max_dfsch_act_time) != A_OK) ++ { ++ ret = -EIO; ++ } ++ if (ar->arSsidLen) { ++ ar->arConnectPending = TRUE; ++ if (wmi_connect_cmd(ar->arWmi, ar->arNetworkType, ++ ar->arDot11AuthMode, ar->arAuthMode, ++ ar->arPairwiseCrypto, ++ ar->arPairwiseCryptoLen, ++ ar->arGroupCrypto, ar->arGroupCryptoLen, ++ ar->arSsidLen, ar->arSsid, ++ ar->arReqBssid, ar->arChannelHint, ++ ar->arConnectCtrlFlags) != A_OK) ++ { ++ ret = -EIO; ++ ar->arConnectPending = FALSE; ++ } ++ } ++ } else { ++ /* Disconnect from the AP and disable foreground scanning */ ++ AR6000_SPIN_LOCK(&ar->arLock, 0); ++ if (ar->arConnected == TRUE || ar->arConnectPending == TRUE) { ++ AR6000_SPIN_UNLOCK(&ar->arLock, 0); ++ wmi_disconnect_cmd(ar->arWmi); ++ } else { ++ AR6000_SPIN_UNLOCK(&ar->arLock, 0); ++ } ++ ++ if (wmi_scanparams_cmd(ar->arWmi, 0xFFFF, 0, 0, 0, 0, 0, 0, 0xFF, 0) != A_OK) ++ { ++ ret = -EIO; ++ } ++ } ++ break; ++ case AR6000_XIOCTL_WMI_GET_ROAM_DATA: ++ ret = ar6000_ioctl_get_roam_data(dev, rq); ++ break; ++ case AR6000_XIOCTL_WMI_SET_BT_STATUS: ++ ret = ar6000_xioctl_set_bt_status_cmd(dev, userdata); ++ break; ++ case AR6000_XIOCTL_WMI_SET_BT_PARAMS: ++ ret = ar6000_xioctl_set_bt_params_cmd(dev, userdata); ++ break; ++ case AR6000_XIOCTL_WMI_STARTSCAN: ++ { ++ WMI_START_SCAN_CMD setStartScanCmd; ++ ++ if (ar->arWmiReady == FALSE) { ++ ret = -EIO; ++ } else if (copy_from_user(&setStartScanCmd, userdata, ++ sizeof(setStartScanCmd))) ++ { ++ ret = -EFAULT; ++ } else { ++ if (wmi_startscan_cmd(ar->arWmi, setStartScanCmd.scanType, ++ setStartScanCmd.forceFgScan, ++ setStartScanCmd.isLegacy, ++ setStartScanCmd.homeDwellTime, ++ setStartScanCmd.forceScanInterval) != A_OK) ++ { ++ ret = -EIO; ++ } ++ } ++ break; ++ } ++ case AR6000_XIOCTL_WMI_SETFIXRATES: ++ { ++ WMI_FIX_RATES_CMD setFixRatesCmd; ++ A_STATUS returnStatus; ++ ++ if (ar->arWmiReady == FALSE) { ++ ret = -EIO; ++ } else if (copy_from_user(&setFixRatesCmd, userdata, ++ sizeof(setFixRatesCmd))) ++ { ++ ret = -EFAULT; ++ } else { ++ returnStatus = wmi_set_fixrates_cmd(ar->arWmi, setFixRatesCmd.fixRateMask); ++ if (returnStatus == A_EINVAL) ++ { ++ ret = -EINVAL; ++ } ++ else if(returnStatus != A_OK) { ++ ret = -EIO; ++ } ++ } ++ break; ++ } ++ ++ case AR6000_XIOCTL_WMI_GETFIXRATES: ++ { ++ WMI_FIX_RATES_CMD getFixRatesCmd; ++ AR_SOFTC_T *ar = (AR_SOFTC_T *)netdev_priv(dev); ++ int ret = 0; ++ ++ if (ar->arWmiReady == FALSE) { ++ return -EIO; ++ } ++ ++ if (down_interruptible(&ar->arSem)) { ++ return -ERESTARTSYS; ++ } ++ /* Used copy_from_user/copy_to_user to access user space data */ ++ if (copy_from_user(&getFixRatesCmd, userdata, sizeof(getFixRatesCmd))) { ++ ret = -EFAULT; ++ } else { ++ ar->arRateMask = 0xFFFF; ++ ++ if (wmi_get_ratemask_cmd(ar->arWmi) != A_OK) { ++ up(&ar->arSem); ++ return -EIO; ++ } ++ ++ wait_event_interruptible_timeout(arEvent, ar->arRateMask != 0xFFFF, wmitimeout * HZ); ++ ++ if (signal_pending(current)) { ++ ret = -EINTR; ++ } ++ ++ if (!ret) { ++ getFixRatesCmd.fixRateMask = ar->arRateMask; ++ } ++ ++ if(copy_to_user(userdata, &getFixRatesCmd, sizeof(getFixRatesCmd))) { ++ ret = -EFAULT; ++ } ++ ++ up(&ar->arSem); ++ } ++ break; ++ } ++ case AR6000_XIOCTL_WMI_SET_AUTHMODE: ++ { ++ WMI_SET_AUTH_MODE_CMD setAuthMode; ++ ++ if (ar->arWmiReady == FALSE) { ++ ret = -EIO; ++ } else if (copy_from_user(&setAuthMode, userdata, ++ sizeof(setAuthMode))) ++ { ++ ret = -EFAULT; ++ } else { ++ if (wmi_set_authmode_cmd(ar->arWmi, setAuthMode.mode) != A_OK) ++ { ++ ret = -EIO; ++ } ++ } ++ break; ++ } ++ case AR6000_XIOCTL_WMI_SET_REASSOCMODE: ++ { ++ WMI_SET_REASSOC_MODE_CMD setReassocMode; ++ ++ if (ar->arWmiReady == FALSE) { ++ ret = -EIO; ++ } else if (copy_from_user(&setReassocMode, userdata, ++ sizeof(setReassocMode))) ++ { ++ ret = -EFAULT; ++ } else { ++ if (wmi_set_reassocmode_cmd(ar->arWmi, setReassocMode.mode) != A_OK) ++ { ++ ret = -EIO; ++ } ++ } ++ break; ++ } ++ case AR6000_XIOCTL_DIAG_READ: ++ { ++ A_UINT32 addr, data; ++ get_user(addr, (unsigned int *)userdata); ++ if (ar6000_ReadRegDiag(ar->arHifDevice, &addr, &data) != A_OK) { ++ ret = -EIO; ++ } ++ put_user(data, (unsigned int *)userdata + 1); ++ break; ++ } ++ case AR6000_XIOCTL_DIAG_WRITE: ++ { ++ A_UINT32 addr, data; ++ get_user(addr, (unsigned int *)userdata); ++ get_user(data, (unsigned int *)userdata + 1); ++ if (ar6000_WriteRegDiag(ar->arHifDevice, &addr, &data) != A_OK) { ++ ret = -EIO; ++ } ++ break; ++ } ++ case AR6000_XIOCTL_WMI_SET_KEEPALIVE: ++ { ++ WMI_SET_KEEPALIVE_CMD setKeepAlive; ++ if (ar->arWmiReady == FALSE) { ++ return -EIO; ++ } else if (copy_from_user(&setKeepAlive, userdata, ++ sizeof(setKeepAlive))){ ++ ret = -EFAULT; ++ } else { ++ if (wmi_set_keepalive_cmd(ar->arWmi, setKeepAlive.keepaliveInterval) != A_OK) { ++ ret = -EIO; ++ } ++ } ++ break; ++ } ++ case AR6000_XIOCTL_WMI_GET_KEEPALIVE: ++ { ++ AR_SOFTC_T *ar = (AR_SOFTC_T *)netdev_priv(dev); ++ WMI_GET_KEEPALIVE_CMD getKeepAlive; ++ int ret = 0; ++ if (ar->arWmiReady == FALSE) { ++ return -EIO; ++ } ++ if (down_interruptible(&ar->arSem)) { ++ return -ERESTARTSYS; ++ } ++ if (copy_from_user(&getKeepAlive, userdata,sizeof(getKeepAlive))) { ++ ret = -EFAULT; ++ } else { ++ getKeepAlive.keepaliveInterval = wmi_get_keepalive_cmd(ar->arWmi); ++ ar->arKeepaliveConfigured = 0xFF; ++ if (wmi_get_keepalive_configured(ar->arWmi) != A_OK){ ++ up(&ar->arSem); ++ return -EIO; ++ } ++ wait_event_interruptible_timeout(arEvent, ar->arKeepaliveConfigured != 0xFF, wmitimeout * HZ); ++ if (signal_pending(current)) { ++ ret = -EINTR; ++ } ++ ++ if (!ret) { ++ getKeepAlive.configured = ar->arKeepaliveConfigured; ++ } ++ if (copy_to_user(userdata, &getKeepAlive, sizeof(getKeepAlive))) { ++ ret = -EFAULT; ++ } ++ up(&ar->arSem); ++ } ++ break; ++ } ++ case AR6000_XIOCTL_WMI_SET_APPIE: ++ { ++ WMI_SET_APPIE_CMD appIEcmd; ++ A_UINT8 appIeInfo[IEEE80211_APPIE_FRAME_MAX_LEN]; ++ A_UINT32 fType,ieLen; ++ ++ if (ar->arWmiReady == FALSE) { ++ return -EIO; ++ } ++ get_user(fType, (A_UINT32 *)userdata); ++ appIEcmd.mgmtFrmType = fType; ++ if (appIEcmd.mgmtFrmType >= IEEE80211_APPIE_NUM_OF_FRAME) { ++ ret = -EIO; ++ } else { ++ get_user(ieLen, (A_UINT32 *)(userdata + 4)); ++ appIEcmd.ieLen = ieLen; ++ if (appIEcmd.ieLen > IEEE80211_APPIE_FRAME_MAX_LEN) { ++ ret = -EIO; ++ break; ++ } ++ if (copy_from_user(appIeInfo, userdata + 8, appIEcmd.ieLen)) { ++ ret = -EFAULT; ++ } else { ++ if (wmi_set_appie_cmd(ar->arWmi, appIEcmd.mgmtFrmType, ++ appIEcmd.ieLen, appIeInfo) != A_OK) ++ { ++ ret = -EIO; ++ } ++ } ++ } ++ break; ++ } ++ case AR6000_XIOCTL_WMI_SET_MGMT_FRM_RX_FILTER: ++ { ++ WMI_BSS_FILTER_CMD cmd; ++ A_UINT32 filterType; ++ ++ if (copy_from_user(&filterType, userdata, sizeof(A_UINT32))) ++ { ++ return -EFAULT; ++ } ++ if (filterType & (IEEE80211_FILTER_TYPE_BEACON | ++ IEEE80211_FILTER_TYPE_PROBE_RESP)) ++ { ++ cmd.bssFilter = ALL_BSS_FILTER; ++ } else { ++ cmd.bssFilter = NONE_BSS_FILTER; ++ } ++ if (wmi_bssfilter_cmd(ar->arWmi, cmd.bssFilter, 0) != A_OK) { ++ ret = -EIO; ++ } ++ ++ AR6000_SPIN_LOCK(&ar->arLock, 0); ++ ar->arMgmtFilter = filterType; ++ AR6000_SPIN_UNLOCK(&ar->arLock, 0); ++ break; ++ } ++ case AR6000_XIOCTL_WMI_SET_WSC_STATUS: ++ { ++ A_UINT32 wsc_status; ++ ++ if (copy_from_user(&wsc_status, userdata, sizeof(A_UINT32))) ++ { ++ return -EFAULT; ++ } ++ if (wmi_set_wsc_status_cmd(ar->arWmi, wsc_status) != A_OK) { ++ ret = -EIO; ++ } ++ break; ++ } ++ case AR6000_XIOCTL_BMI_ROMPATCH_INSTALL: ++ { ++ A_UINT32 ROM_addr; ++ A_UINT32 RAM_addr; ++ A_UINT32 nbytes; ++ A_UINT32 do_activate; ++ A_UINT32 rompatch_id; ++ ++ get_user(ROM_addr, (A_UINT32 *)userdata); ++ get_user(RAM_addr, (A_UINT32 *)userdata + 1); ++ get_user(nbytes, (A_UINT32 *)userdata + 2); ++ get_user(do_activate, (A_UINT32 *)userdata + 3); ++ AR_DEBUG_PRINTF("Install rompatch from ROM: 0x%x to RAM: 0x%x length: %d\n", ++ ROM_addr, RAM_addr, nbytes); ++ ret = BMIrompatchInstall(hifDevice, ROM_addr, RAM_addr, ++ nbytes, do_activate, &rompatch_id); ++ if (ret == A_OK) { ++ put_user(rompatch_id, (unsigned int *)rq->ifr_data); /* return value */ ++ } ++ break; ++ } ++ ++ case AR6000_XIOCTL_BMI_ROMPATCH_UNINSTALL: ++ { ++ A_UINT32 rompatch_id; ++ ++ get_user(rompatch_id, (A_UINT32 *)userdata); ++ AR_DEBUG_PRINTF("UNinstall rompatch_id %d\n", rompatch_id); ++ ret = BMIrompatchUninstall(hifDevice, rompatch_id); ++ break; ++ } ++ ++ case AR6000_XIOCTL_BMI_ROMPATCH_ACTIVATE: ++ case AR6000_XIOCTL_BMI_ROMPATCH_DEACTIVATE: ++ { ++ A_UINT32 rompatch_count; ++ ++ get_user(rompatch_count, (A_UINT32 *)userdata); ++ AR_DEBUG_PRINTF("Change rompatch activation count=%d\n", rompatch_count); ++ length = sizeof(A_UINT32) * rompatch_count; ++ if ((buffer = (unsigned char *)A_MALLOC(length)) != NULL) { ++ A_MEMZERO(buffer, length); ++ if (copy_from_user(buffer, &userdata[sizeof(rompatch_count)], length)) ++ { ++ ret = -EFAULT; ++ } else { ++ if (cmd == AR6000_XIOCTL_BMI_ROMPATCH_ACTIVATE) { ++ ret = BMIrompatchActivate(hifDevice, rompatch_count, (A_UINT32 *)buffer); ++ } else { ++ ret = BMIrompatchDeactivate(hifDevice, rompatch_count, (A_UINT32 *)buffer); ++ } ++ } ++ A_FREE(buffer); ++ } else { ++ ret = -ENOMEM; ++ } ++ ++ break; ++ } ++ ++ case AR6000_XIOCTL_WMI_SET_HOST_SLEEP_MODE: ++ { ++ WMI_SET_HOST_SLEEP_MODE_CMD setHostSleepMode; ++ ++ if (ar->arWmiReady == FALSE) { ++ ret = -EIO; ++ } else if (copy_from_user(&setHostSleepMode, userdata, ++ sizeof(setHostSleepMode))) ++ { ++ ret = -EFAULT; ++ } else { ++ if (wmi_set_host_sleep_mode_cmd(ar->arWmi, ++ &setHostSleepMode) != A_OK) ++ { ++ ret = -EIO; ++ } ++ } ++ break; ++ } ++ case AR6000_XIOCTL_WMI_SET_WOW_MODE: ++ { ++ WMI_SET_WOW_MODE_CMD setWowMode; ++ ++ if (ar->arWmiReady == FALSE) { ++ ret = -EIO; ++ } else if (copy_from_user(&setWowMode, userdata, ++ sizeof(setWowMode))) ++ { ++ ret = -EFAULT; ++ } else { ++ if (wmi_set_wow_mode_cmd(ar->arWmi, ++ &setWowMode) != A_OK) ++ { ++ ret = -EIO; ++ } ++ } ++ break; ++ } ++ case AR6000_XIOCTL_WMI_GET_WOW_LIST: ++ { ++ WMI_GET_WOW_LIST_CMD getWowList; ++ ++ if (ar->arWmiReady == FALSE) { ++ ret = -EIO; ++ } else if (copy_from_user(&getWowList, userdata, ++ sizeof(getWowList))) ++ { ++ ret = -EFAULT; ++ } else { ++ if (wmi_get_wow_list_cmd(ar->arWmi, ++ &getWowList) != A_OK) ++ { ++ ret = -EIO; ++ } ++ } ++ break; ++ } ++ case AR6000_XIOCTL_WMI_ADD_WOW_PATTERN: ++ { ++#define WOW_PATTERN_SIZE 64 ++#define WOW_MASK_SIZE 64 ++ ++ WMI_ADD_WOW_PATTERN_CMD cmd; ++ A_UINT8 mask_data[WOW_PATTERN_SIZE]={0}; ++ A_UINT8 pattern_data[WOW_PATTERN_SIZE]={0}; ++ ++ if (ar->arWmiReady == FALSE) { ++ ret = -EIO; ++ } else { ++ ++ if(copy_from_user(&cmd, userdata, ++ sizeof(WMI_ADD_WOW_PATTERN_CMD))) ++ return -EFAULT; ++ if (copy_from_user(pattern_data, ++ userdata + 3, ++ cmd.filter_size)){ ++ ret = -EFAULT; ++ break; ++ } ++ if (copy_from_user(mask_data, ++ (userdata + 3 + cmd.filter_size), ++ cmd.filter_size)){ ++ ret = -EFAULT; ++ break; ++ } else { ++ if (wmi_add_wow_pattern_cmd(ar->arWmi, ++ &cmd, pattern_data, mask_data, cmd.filter_size) != A_OK){ ++ ret = -EIO; ++ } ++ } ++ } ++#undef WOW_PATTERN_SIZE ++#undef WOW_MASK_SIZE ++ break; ++ } ++ case AR6000_XIOCTL_WMI_DEL_WOW_PATTERN: ++ { ++ WMI_DEL_WOW_PATTERN_CMD delWowPattern; ++ ++ if (ar->arWmiReady == FALSE) { ++ ret = -EIO; ++ } else if (copy_from_user(&delWowPattern, userdata, ++ sizeof(delWowPattern))) ++ { ++ ret = -EFAULT; ++ } else { ++ if (wmi_del_wow_pattern_cmd(ar->arWmi, ++ &delWowPattern) != A_OK) ++ { ++ ret = -EIO; ++ } ++ } ++ break; ++ } ++ case AR6000_XIOCTL_DUMP_HTC_CREDIT_STATE: ++ if (ar->arHtcTarget != NULL) { ++ HTCDumpCreditStates(ar->arHtcTarget); ++ } ++ break; ++ case AR6000_XIOCTL_TRAFFIC_ACTIVITY_CHANGE: ++ if (ar->arHtcTarget != NULL) { ++ struct ar6000_traffic_activity_change data; ++ ++ if (copy_from_user(&data, userdata, sizeof(data))) ++ { ++ return -EFAULT; ++ } ++ /* note, this is used for testing (mbox ping testing), indicate activity ++ * change using the stream ID as the traffic class */ ++ ar6000_indicate_tx_activity(ar, ++ (A_UINT8)data.StreamID, ++ data.Active ? TRUE : FALSE); ++ } ++ break; ++ case AR6000_XIOCTL_WMI_SET_CONNECT_CTRL_FLAGS: ++ if (ar->arWmiReady == FALSE) { ++ ret = -EIO; ++ } else if (copy_from_user(&connectCtrlFlags, userdata, ++ sizeof(connectCtrlFlags))) ++ { ++ ret = -EFAULT; ++ } else { ++ ar->arConnectCtrlFlags = connectCtrlFlags; ++ } ++ break; ++ case AR6000_XIOCTL_WMI_SET_AKMP_PARAMS: ++ if (ar->arWmiReady == FALSE) { ++ ret = -EIO; ++ } else if (copy_from_user(&akmpParams, userdata, ++ sizeof(WMI_SET_AKMP_PARAMS_CMD))) ++ { ++ ret = -EFAULT; ++ } else { ++ if (wmi_set_akmp_params_cmd(ar->arWmi, &akmpParams) != A_OK) { ++ ret = -EIO; ++ } ++ } ++ break; ++ case AR6000_XIOCTL_WMI_SET_PMKID_LIST: ++ if (ar->arWmiReady == FALSE) { ++ ret = -EIO; ++ } else { ++ if (copy_from_user(&pmkidInfo.numPMKID, userdata, ++ sizeof(pmkidInfo.numPMKID))) ++ { ++ ret = -EFAULT; ++ break; ++ } ++ if (copy_from_user(&pmkidInfo.pmkidList, ++ userdata + sizeof(pmkidInfo.numPMKID), ++ pmkidInfo.numPMKID * sizeof(WMI_PMKID))) ++ { ++ ret = -EFAULT; ++ break; ++ } ++ if (wmi_set_pmkid_list_cmd(ar->arWmi, &pmkidInfo) != A_OK) { ++ ret = -EIO; ++ } ++ } ++ break; ++ case AR6000_XIOCTL_WMI_GET_PMKID_LIST: ++ if (ar->arWmiReady == FALSE) { ++ ret = -EIO; ++ } else { ++ if (wmi_get_pmkid_list_cmd(ar->arWmi) != A_OK) { ++ ret = -EIO; ++ } ++ } ++ break; ++ default: ++ ret = -EOPNOTSUPP; ++ } ++ return ret; ++} ++ +diff -ruN --exclude='*.orig' --exclude='*.rej' linux-2.6.29-rc3.owrt/drivers/ar6000/ar6000/netbuf.c linux-2.6.29-rc3.owrt.om/drivers/ar6000/ar6000/netbuf.c +--- linux-2.6.29-rc3.owrt/drivers/ar6000/ar6000/netbuf.c 1970-01-01 01:00:00.000000000 +0100 ++++ linux-2.6.29-rc3.owrt.om/drivers/ar6000/ar6000/netbuf.c 2009-05-10 22:27:59.000000000 +0200 +@@ -0,0 +1,225 @@ ++ ++/* ++ * ++ * Copyright (c) 2004-2007 Atheros Communications Inc. ++ * All rights reserved. ++ * ++ * ++ * 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; ++ * ++ * Software distributed under the License is distributed on an "AS ++ * IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or ++ * implied. See the License for the specific language governing ++ * rights and limitations under the License. ++ * ++ * ++ * ++ */ ++#include <linux/kernel.h> ++#include <linux/skbuff.h> ++#include <a_config.h> ++#include "athdefs.h" ++#include "a_types.h" ++#include "a_osapi.h" ++#include "htc_packet.h" ++ ++#define AR6000_DATA_OFFSET 64 ++ ++void a_netbuf_enqueue(A_NETBUF_QUEUE_T *q, void *pkt) ++{ ++ skb_queue_tail((struct sk_buff_head *) q, (struct sk_buff *) pkt); ++} ++ ++void a_netbuf_prequeue(A_NETBUF_QUEUE_T *q, void *pkt) ++{ ++ skb_queue_head((struct sk_buff_head *) q, (struct sk_buff *) pkt); ++} ++ ++void *a_netbuf_dequeue(A_NETBUF_QUEUE_T *q) ++{ ++ return((void *) skb_dequeue((struct sk_buff_head *) q)); ++} ++ ++int a_netbuf_queue_size(A_NETBUF_QUEUE_T *q) ++{ ++ return(skb_queue_len((struct sk_buff_head *) q)); ++} ++ ++int a_netbuf_queue_empty(A_NETBUF_QUEUE_T *q) ++{ ++ return(skb_queue_empty((struct sk_buff_head *) q)); ++} ++ ++void a_netbuf_queue_init(A_NETBUF_QUEUE_T *q) ++{ ++ skb_queue_head_init((struct sk_buff_head *) q); ++} ++ ++void * ++a_netbuf_alloc(int size) ++{ ++ struct sk_buff *skb; ++ skb = dev_alloc_skb(AR6000_DATA_OFFSET + sizeof(HTC_PACKET) + size); ++ skb_reserve(skb, AR6000_DATA_OFFSET + sizeof(HTC_PACKET)); ++ return ((void *)skb); ++} ++ ++/* ++ * Allocate an SKB w.o. any encapsulation requirement. ++ */ ++void * ++a_netbuf_alloc_raw(int size) ++{ ++ struct sk_buff *skb; ++ ++ skb = dev_alloc_skb(size); ++ ++ return ((void *)skb); ++} ++ ++void ++a_netbuf_free(void *bufPtr) ++{ ++ struct sk_buff *skb = (struct sk_buff *)bufPtr; ++ ++ dev_kfree_skb(skb); ++} ++ ++A_UINT32 ++a_netbuf_to_len(void *bufPtr) ++{ ++ return (((struct sk_buff *)bufPtr)->len); ++} ++ ++void * ++a_netbuf_to_data(void *bufPtr) ++{ ++ return (((struct sk_buff *)bufPtr)->data); ++} ++ ++/* ++ * Add len # of bytes to the beginning of the network buffer ++ * pointed to by bufPtr ++ */ ++A_STATUS ++a_netbuf_push(void *bufPtr, A_INT32 len) ++{ ++ skb_push((struct sk_buff *)bufPtr, len); ++ ++ return A_OK; ++} ++ ++/* ++ * Add len # of bytes to the beginning of the network buffer ++ * pointed to by bufPtr and also fill with data ++ */ ++A_STATUS ++a_netbuf_push_data(void *bufPtr, char *srcPtr, A_INT32 len) ++{ ++ skb_push((struct sk_buff *) bufPtr, len); ++ A_MEMCPY(((struct sk_buff *)bufPtr)->data, srcPtr, len); ++ ++ return A_OK; ++} ++ ++/* ++ * Add len # of bytes to the end of the network buffer ++ * pointed to by bufPtr ++ */ ++A_STATUS ++a_netbuf_put(void *bufPtr, A_INT32 len) ++{ ++ skb_put((struct sk_buff *)bufPtr, len); ++ ++ return A_OK; ++} ++ ++/* ++ * Add len # of bytes to the end of the network buffer ++ * pointed to by bufPtr and also fill with data ++ */ ++A_STATUS ++a_netbuf_put_data(void *bufPtr, char *srcPtr, A_INT32 len) ++{ ++ char *start = ((struct sk_buff *)bufPtr)->data + ++ ((struct sk_buff *)bufPtr)->len; ++ skb_put((struct sk_buff *)bufPtr, len); ++ A_MEMCPY(start, srcPtr, len); ++ ++ return A_OK; ++} ++ ++ ++/* ++ * Trim the network buffer pointed to by bufPtr to len # of bytes ++ */ ++A_STATUS ++a_netbuf_setlen(void *bufPtr, A_INT32 len) ++{ ++ skb_trim((struct sk_buff *)bufPtr, len); ++ ++ return A_OK; ++} ++ ++/* ++ * Chop of len # of bytes from the end of the buffer. ++ */ ++A_STATUS ++a_netbuf_trim(void *bufPtr, A_INT32 len) ++{ ++ skb_trim((struct sk_buff *)bufPtr, ((struct sk_buff *)bufPtr)->len - len); ++ ++ return A_OK; ++} ++ ++/* ++ * Chop of len # of bytes from the end of the buffer and return the data. ++ */ ++A_STATUS ++a_netbuf_trim_data(void *bufPtr, char *dstPtr, A_INT32 len) ++{ ++ char *start = ((struct sk_buff *)bufPtr)->data + ++ (((struct sk_buff *)bufPtr)->len - len); ++ ++ A_MEMCPY(dstPtr, start, len); ++ skb_trim((struct sk_buff *)bufPtr, ((struct sk_buff *)bufPtr)->len - len); ++ ++ return A_OK; ++} ++ ++ ++/* ++ * Returns the number of bytes available to a a_netbuf_push() ++ */ ++A_INT32 ++a_netbuf_headroom(void *bufPtr) ++{ ++ return (skb_headroom((struct sk_buff *)bufPtr)); ++} ++ ++/* ++ * Removes specified number of bytes from the beginning of the buffer ++ */ ++A_STATUS ++a_netbuf_pull(void *bufPtr, A_INT32 len) ++{ ++ skb_pull((struct sk_buff *)bufPtr, len); ++ ++ return A_OK; ++} ++ ++/* ++ * Removes specified number of bytes from the beginning of the buffer ++ * and return the data ++ */ ++A_STATUS ++a_netbuf_pull_data(void *bufPtr, char *dstPtr, A_INT32 len) ++{ ++ A_MEMCPY(dstPtr, ((struct sk_buff *)bufPtr)->data, len); ++ skb_pull((struct sk_buff *)bufPtr, len); ++ ++ return A_OK; ++} ++ +diff -ruN --exclude='*.orig' --exclude='*.rej' linux-2.6.29-rc3.owrt/drivers/ar6000/ar6000/osapi_linux.h linux-2.6.29-rc3.owrt.om/drivers/ar6000/ar6000/osapi_linux.h +--- linux-2.6.29-rc3.owrt/drivers/ar6000/ar6000/osapi_linux.h 1970-01-01 01:00:00.000000000 +0100 ++++ linux-2.6.29-rc3.owrt.om/drivers/ar6000/ar6000/osapi_linux.h 2009-05-10 22:27:59.000000000 +0200 +@@ -0,0 +1,319 @@ ++/* ++ * $Id: //depot/sw/releases/olca2.0-GPL/host/os/linux/include/osapi_linux.h#1 $ ++ * ++ * This file contains the definitions of the basic atheros data types. ++ * It is used to map the data types in atheros files to a platform specific ++ * type. ++ * ++ * Copyright 2003-2005 Atheros Communications, Inc., All Rights Reserved. ++ * ++ * ++ * 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; ++ * ++ * Software distributed under the License is distributed on an "AS ++ * IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or ++ * implied. See the License for the specific language governing ++ * rights and limitations under the License. ++ * ++ * ++ * ++ */ ++ ++#ifndef _OSAPI_LINUX_H_ ++#define _OSAPI_LINUX_H_ ++ ++#ifdef __KERNEL__ ++ ++#include <linux/version.h> ++#include <linux/types.h> ++#include <linux/kernel.h> ++#include <linux/string.h> ++#include <linux/skbuff.h> ++#include <linux/netdevice.h> ++#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,0) ++#include <linux/jiffies.h> ++#endif ++#include <linux/timer.h> ++#include <linux/delay.h> ++#include <linux/wait.h> ++#ifdef KERNEL_2_4 ++#include <asm/arch/irq.h> ++#include <asm/irq.h> ++#endif ++ ++#ifdef __GNUC__ ++#define __ATTRIB_PACK __attribute__ ((packed)) ++#define __ATTRIB_PRINTF __attribute__ ((format (printf, 1, 2))) ++#define __ATTRIB_NORETURN __attribute__ ((noreturn)) ++#ifndef INLINE ++#define INLINE __inline__ ++#endif ++#else /* Not GCC */ ++#define __ATTRIB_PACK ++#define __ATTRIB_PRINTF ++#define __ATTRIB_NORETURN ++#ifndef INLINE ++#define INLINE __inline ++#endif ++#endif /* End __GNUC__ */ ++ ++#define PREPACK ++#define POSTPACK __ATTRIB_PACK ++ ++/* ++ * Endianes macros ++ */ ++#define A_BE2CPU8(x) ntohb(x) ++#define A_BE2CPU16(x) ntohs(x) ++#define A_BE2CPU32(x) ntohl(x) ++ ++#define A_LE2CPU8(x) (x) ++#define A_LE2CPU16(x) (x) ++#define A_LE2CPU32(x) (x) ++ ++#define A_CPU2BE8(x) htonb(x) ++#define A_CPU2BE16(x) htons(x) ++#define A_CPU2BE32(x) htonl(x) ++ ++#define A_MEMCPY(dst, src, len) memcpy((A_UINT8 *)(dst), (src), (len)) ++#define A_MEMZERO(addr, len) memset(addr, 0, len) ++#define A_MEMCMP(addr1, addr2, len) memcmp((addr1), (addr2), (len)) ++#define A_MALLOC(size) kmalloc((size), GFP_KERNEL) ++#define A_MALLOC_NOWAIT(size) kmalloc((size), GFP_ATOMIC) ++#define A_FREE(addr) kfree(addr) ++#define A_PRINTF(args...) printk(args) ++ ++/* Mutual Exclusion */ ++typedef spinlock_t A_MUTEX_T; ++#define A_MUTEX_INIT(mutex) spin_lock_init(mutex) ++#define A_MUTEX_LOCK(mutex) spin_lock_bh(mutex) ++#define A_MUTEX_UNLOCK(mutex) spin_unlock_bh(mutex) ++#define A_IS_MUTEX_VALID(mutex) TRUE /* okay to return true, since A_MUTEX_DELETE does nothing */ ++#define A_MUTEX_DELETE(mutex) /* spin locks are not kernel resources so nothing to free.. */ ++ ++/* Get current time in ms adding a constant offset (in ms) */ ++#define A_GET_MS(offset) \ ++ (jiffies + ((offset) / 1000) * HZ) ++ ++/* ++ * Timer Functions ++ */ ++#define A_MDELAY(msecs) mdelay(msecs) ++typedef struct timer_list A_TIMER; ++ ++#define A_INIT_TIMER(pTimer, pFunction, pArg) do { \ ++ init_timer(pTimer); \ ++ (pTimer)->function = (pFunction); \ ++ (pTimer)->data = (unsigned long)(pArg); \ ++} while (0) ++ ++/* ++ * Start a Timer that elapses after 'periodMSec' milli-seconds ++ * Support is provided for a one-shot timer. The 'repeatFlag' is ++ * ignored. ++ */ ++#define A_TIMEOUT_MS(pTimer, periodMSec, repeatFlag) do { \ ++ if (repeatFlag) { \ ++ printk("\n" __FILE__ ":%d: Timer Repeat requested\n",__LINE__); \ ++ panic("Timer Repeat"); \ ++ } \ ++ mod_timer((pTimer), jiffies + HZ * (periodMSec) / 1000); \ ++} while (0) ++ ++/* ++ * Cancel the Timer. ++ */ ++#define A_UNTIMEOUT(pTimer) do { \ ++ del_timer((pTimer)); \ ++} while (0) ++ ++#define A_DELETE_TIMER(pTimer) do { \ ++} while (0) ++ ++/* ++ * Wait Queue related functions ++ */ ++typedef wait_queue_head_t A_WAITQUEUE_HEAD; ++#define A_INIT_WAITQUEUE_HEAD(head) init_waitqueue_head(head) ++#ifndef wait_event_interruptible_timeout ++#define __wait_event_interruptible_timeout(wq, condition, ret) \ ++do { \ ++ wait_queue_t __wait; \ ++ init_waitqueue_entry(&__wait, current); \ ++ \ ++ add_wait_queue(&wq, &__wait); \ ++ for (;;) { \ ++ set_current_state(TASK_INTERRUPTIBLE); \ ++ if (condition) \ ++ break; \ ++ if (!signal_pending(current)) { \ ++ ret = schedule_timeout(ret); \ ++ if (!ret) \ ++ break; \ ++ continue; \ ++ } \ ++ ret = -ERESTARTSYS; \ ++ break; \ ++ } \ ++ current->state = TASK_RUNNING; \ ++ remove_wait_queue(&wq, &__wait); \ ++} while (0) ++ ++#define wait_event_interruptible_timeout(wq, condition, timeout) \ ++({ \ ++ long __ret = timeout; \ ++ if (!(condition)) \ ++ __wait_event_interruptible_timeout(wq, condition, __ret); \ ++ __ret; \ ++}) ++#endif /* wait_event_interruptible_timeout */ ++ ++#define A_WAIT_EVENT_INTERRUPTIBLE_TIMEOUT(head, condition, timeout) do { \ ++ wait_event_interruptible_timeout(head, condition, timeout); \ ++} while (0) ++ ++#define A_WAKE_UP(head) wake_up(head) ++ ++#ifdef DEBUG ++#define A_ASSERT(expr) \ ++ if (!(expr)) { \ ++ printk(KERN_ALERT "\n" __FILE__ ":%d: Assertion " #expr " failed!\n",__LINE__); \ ++ panic(#expr); \ ++ } ++ ++#else ++#define A_ASSERT(expr) ++#endif /* DEBUG */ ++ ++/* ++ * Initialization of the network buffer subsystem ++ */ ++#define A_NETBUF_INIT() ++ ++/* ++ * Network buffer queue support ++ */ ++typedef struct sk_buff_head A_NETBUF_QUEUE_T; ++ ++#define A_NETBUF_QUEUE_INIT(q) \ ++ a_netbuf_queue_init(q) ++ ++#define A_NETBUF_ENQUEUE(q, pkt) \ ++ a_netbuf_enqueue((q), (pkt)) ++#define A_NETBUF_PREQUEUE(q, pkt) \ ++ a_netbuf_prequeue((q), (pkt)) ++#define A_NETBUF_DEQUEUE(q) \ ++ (a_netbuf_dequeue(q)) ++#define A_NETBUF_QUEUE_SIZE(q) \ ++ a_netbuf_queue_size(q) ++#define A_NETBUF_QUEUE_EMPTY(q) \ ++ a_netbuf_queue_empty(q) ++ ++/* ++ * Network buffer support ++ */ ++#define A_NETBUF_ALLOC(size) \ ++ a_netbuf_alloc(size) ++#define A_NETBUF_ALLOC_RAW(size) \ ++ a_netbuf_alloc_raw(size) ++#define A_NETBUF_FREE(bufPtr) \ ++ a_netbuf_free(bufPtr) ++#define A_NETBUF_DATA(bufPtr) \ ++ a_netbuf_to_data(bufPtr) ++#define A_NETBUF_LEN(bufPtr) \ ++ a_netbuf_to_len(bufPtr) ++#define A_NETBUF_PUSH(bufPtr, len) \ ++ a_netbuf_push(bufPtr, len) ++#define A_NETBUF_PUT(bufPtr, len) \ ++ a_netbuf_put(bufPtr, len) ++#define A_NETBUF_TRIM(bufPtr,len) \ ++ a_netbuf_trim(bufPtr, len) ++#define A_NETBUF_PULL(bufPtr, len) \ ++ a_netbuf_pull(bufPtr, len) ++#define A_NETBUF_HEADROOM(bufPtr)\ ++ a_netbuf_headroom(bufPtr) ++#define A_NETBUF_SETLEN(bufPtr,len) \ ++ a_netbuf_setlen(bufPtr, len) ++ ++/* Add data to end of a buffer */ ++#define A_NETBUF_PUT_DATA(bufPtr, srcPtr, len) \ ++ a_netbuf_put_data(bufPtr, srcPtr, len) ++ ++/* Add data to start of the buffer */ ++#define A_NETBUF_PUSH_DATA(bufPtr, srcPtr, len) \ ++ a_netbuf_push_data(bufPtr, srcPtr, len) ++ ++/* Remove data at start of the buffer */ ++#define A_NETBUF_PULL_DATA(bufPtr, dstPtr, len) \ ++ a_netbuf_pull_data(bufPtr, dstPtr, len) ++ ++/* Remove data from the end of the buffer */ ++#define A_NETBUF_TRIM_DATA(bufPtr, dstPtr, len) \ ++ a_netbuf_trim_data(bufPtr, dstPtr, len) ++ ++/* View data as "size" contiguous bytes of type "t" */ ++#define A_NETBUF_VIEW_DATA(bufPtr, t, size) \ ++ (t )( ((struct skbuf *)(bufPtr))->data) ++ ++/* return the beginning of the headroom for the buffer */ ++#define A_NETBUF_HEAD(bufPtr) \ ++ ((((struct sk_buff *)(bufPtr))->head)) ++ ++/* ++ * OS specific network buffer access routines ++ */ ++void *a_netbuf_alloc(int size); ++void *a_netbuf_alloc_raw(int size); ++void a_netbuf_free(void *bufPtr); ++void *a_netbuf_to_data(void *bufPtr); ++A_UINT32 a_netbuf_to_len(void *bufPtr); ++A_STATUS a_netbuf_push(void *bufPtr, A_INT32 len); ++A_STATUS a_netbuf_push_data(void *bufPtr, char *srcPtr, A_INT32 len); ++A_STATUS a_netbuf_put(void *bufPtr, A_INT32 len); ++A_STATUS a_netbuf_put_data(void *bufPtr, char *srcPtr, A_INT32 len); ++A_STATUS a_netbuf_pull(void *bufPtr, A_INT32 len); ++A_STATUS a_netbuf_pull_data(void *bufPtr, char *dstPtr, A_INT32 len); ++A_STATUS a_netbuf_trim(void *bufPtr, A_INT32 len); ++A_STATUS a_netbuf_trim_data(void *bufPtr, char *dstPtr, A_INT32 len); ++A_STATUS a_netbuf_setlen(void *bufPtr, A_INT32 len); ++A_INT32 a_netbuf_headroom(void *bufPtr); ++void a_netbuf_enqueue(A_NETBUF_QUEUE_T *q, void *pkt); ++void a_netbuf_prequeue(A_NETBUF_QUEUE_T *q, void *pkt); ++void *a_netbuf_dequeue(A_NETBUF_QUEUE_T *q); ++int a_netbuf_queue_size(A_NETBUF_QUEUE_T *q); ++int a_netbuf_queue_empty(A_NETBUF_QUEUE_T *q); ++int a_netbuf_queue_empty(A_NETBUF_QUEUE_T *q); ++void a_netbuf_queue_init(A_NETBUF_QUEUE_T *q); ++ ++/* ++ * Kernel v.s User space functions ++ */ ++A_UINT32 a_copy_to_user(void *to, const void *from, A_UINT32 n); ++A_UINT32 a_copy_from_user(void *to, const void *from, A_UINT32 n); ++ ++#else /* __KERNEL__ */ ++ ++#ifdef __GNUC__ ++#define __ATTRIB_PACK __attribute__ ((packed)) ++#define __ATTRIB_PRINTF __attribute__ ((format (printf, 1, 2))) ++#define __ATTRIB_NORETURN __attribute__ ((noreturn)) ++#ifndef INLINE ++#define INLINE __inline__ ++#endif ++#else /* Not GCC */ ++#define __ATTRIB_PACK ++#define __ATTRIB_PRINTF ++#define __ATTRIB_NORETURN ++#ifndef INLINE ++#define INLINE __inline ++#endif ++#endif /* End __GNUC__ */ ++ ++#define PREPACK ++#define POSTPACK __ATTRIB_PACK ++ ++#endif /* __KERNEL__ */ ++ ++#endif /* _OSAPI_LINUX_H_ */ +diff -ruN --exclude='*.orig' --exclude='*.rej' linux-2.6.29-rc3.owrt/drivers/ar6000/ar6000/wireless_ext.c linux-2.6.29-rc3.owrt.om/drivers/ar6000/ar6000/wireless_ext.c +--- linux-2.6.29-rc3.owrt/drivers/ar6000/ar6000/wireless_ext.c 1970-01-01 01:00:00.000000000 +0100 ++++ linux-2.6.29-rc3.owrt.om/drivers/ar6000/ar6000/wireless_ext.c 2009-05-10 22:27:59.000000000 +0200 +@@ -0,0 +1,1979 @@ ++/* ++ * ++ * Copyright (c) 2004-2007 Atheros Communications Inc. ++ * All rights reserved. ++ * ++ * ++ * 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; ++ * ++ * Software distributed under the License is distributed on an "AS ++ * IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or ++ * implied. See the License for the specific language governing ++ * rights and limitations under the License. ++ * ++ * ++ * ++ */ ++ ++#include "ar6000_drv.h" ++ ++static A_UINT8 bcast_mac[] = {0xff, 0xff, 0xff, 0xff, 0xff, 0xff}; ++static void ar6000_set_quality(struct iw_quality *iq, A_INT8 rssi); ++extern unsigned int wmitimeout; ++extern A_WAITQUEUE_HEAD arEvent; ++extern wait_queue_head_t ar6000_scan_queue; ++ ++/* ++ * Encode a WPA or RSN information element as a custom ++ * element using the hostap format. ++ */ ++static u_int ++encode_ie(void *buf, size_t bufsize, ++ const u_int8_t *ie, size_t ielen, ++ const char *leader, size_t leader_len) ++{ ++ u_int8_t *p; ++ int i; ++ ++ if (bufsize < leader_len) ++ return 0; ++ p = buf; ++ memcpy(p, leader, leader_len); ++ bufsize -= leader_len; ++ p += leader_len; ++ for (i = 0; i < ielen && bufsize > 2; i++) ++ p += sprintf(p, "%02x", ie[i]); ++ return (i == ielen ? p - (u_int8_t *)buf : 0); ++} ++ ++void ++ar6000_scan_node(void *arg, bss_t *ni) ++{ ++ struct iw_event iwe; ++#if WIRELESS_EXT > 14 ++ char buf[64*2 + 30]; ++#endif ++ struct ar_giwscan_param *param; ++ A_CHAR *current_ev; ++ A_CHAR *end_buf; ++ struct ieee80211_common_ie *cie; ++ struct iw_request_info info; ++ ++ info.cmd = 0; ++ info.flags = 0; ++ ++ param = (struct ar_giwscan_param *)arg; ++ ++ if (param->current_ev >= param->end_buf) { ++ return; ++ } ++ if ((param->firstPass == TRUE) && ++ ((ni->ni_cie.ie_wpa == NULL) && (ni->ni_cie.ie_rsn == NULL))) { ++ /* ++ * Only forward wpa bss's in first pass ++ */ ++ return; ++ } ++ ++ if ((param->firstPass == FALSE) && ++ ((ni->ni_cie.ie_wpa != NULL) || (ni->ni_cie.ie_rsn != NULL))) { ++ /* ++ * Only forward non-wpa bss's in 2nd pass ++ */ ++ return; ++ } ++ ++ current_ev = param->current_ev; ++ end_buf = param->end_buf; ++ ++ cie = &ni->ni_cie; ++ ++ A_MEMZERO(&iwe, sizeof(iwe)); ++ iwe.cmd = SIOCGIWAP; ++ iwe.u.ap_addr.sa_family = ARPHRD_ETHER; ++ A_MEMCPY(iwe.u.ap_addr.sa_data, ni->ni_macaddr, 6); ++ current_ev = iwe_stream_add_event(&info, current_ev, end_buf, &iwe, ++ IW_EV_ADDR_LEN); ++ ++ A_MEMZERO(&iwe, sizeof(iwe)); ++ iwe.cmd = SIOCGIWESSID; ++ iwe.u.data.flags = 1; ++ iwe.u.data.length = cie->ie_ssid[1]; ++ current_ev = iwe_stream_add_point(&info, current_ev, end_buf, &iwe, ++ &cie->ie_ssid[2]); ++ ++ if (cie->ie_capInfo & (IEEE80211_CAPINFO_ESS|IEEE80211_CAPINFO_IBSS)) { ++ A_MEMZERO(&iwe, sizeof(iwe)); ++ iwe.cmd = SIOCGIWMODE; ++ iwe.u.mode = cie->ie_capInfo & IEEE80211_CAPINFO_ESS ? ++ IW_MODE_MASTER : IW_MODE_ADHOC; ++ current_ev = iwe_stream_add_event(&info, current_ev, end_buf, &iwe, ++ IW_EV_UINT_LEN); ++ } ++ ++ A_MEMZERO(&iwe, sizeof(iwe)); ++ iwe.cmd = SIOCGIWFREQ; ++ iwe.u.freq.m = cie->ie_chan * 100000; ++ iwe.u.freq.e = 1; ++ current_ev = iwe_stream_add_event(&info, current_ev, end_buf, &iwe, ++ IW_EV_FREQ_LEN); ++ ++ A_MEMZERO(&iwe, sizeof(iwe)); ++ iwe.cmd = IWEVQUAL; ++ ar6000_set_quality(&iwe.u.qual, ni->ni_snr); ++ current_ev = iwe_stream_add_event(&info, current_ev, end_buf, &iwe, ++ IW_EV_QUAL_LEN); ++ ++ A_MEMZERO(&iwe, sizeof(iwe)); ++ iwe.cmd = SIOCGIWENCODE; ++ if (cie->ie_capInfo & IEEE80211_CAPINFO_PRIVACY) { ++ iwe.u.data.flags = IW_ENCODE_ENABLED | IW_ENCODE_NOKEY; ++ } else { ++ iwe.u.data.flags = IW_ENCODE_DISABLED; ++ } ++ iwe.u.data.length = 0; ++ current_ev = iwe_stream_add_point(&info, current_ev, end_buf, &iwe, ""); ++ ++ A_MEMZERO(&iwe, sizeof(iwe)); ++ iwe.cmd = IWEVCUSTOM; ++ snprintf(buf, sizeof(buf), "bcn_int=%d", cie->ie_beaconInt); ++ iwe.u.data.length = strlen(buf); ++ current_ev = iwe_stream_add_point(&info, current_ev, end_buf, &iwe, buf); ++ ++ if (cie->ie_wpa != NULL) { ++ static const char wpa_leader[] = "wpa_ie="; ++ ++ A_MEMZERO(&iwe, sizeof(iwe)); ++ iwe.cmd = IWEVCUSTOM; ++ iwe.u.data.length = encode_ie(buf, sizeof(buf), cie->ie_wpa, ++ cie->ie_wpa[1]+2, ++ wpa_leader, sizeof(wpa_leader)-1); ++ ++ if (iwe.u.data.length != 0) { ++ current_ev = iwe_stream_add_point(&info, current_ev, end_buf, &iwe, ++ buf); ++ } ++ } ++ ++ if (cie->ie_rsn != NULL && cie->ie_rsn[0] == IEEE80211_ELEMID_RSN) { ++ static const char rsn_leader[] = "rsn_ie="; ++ ++ A_MEMZERO(&iwe, sizeof(iwe)); ++ iwe.cmd = IWEVCUSTOM; ++ iwe.u.data.length = encode_ie(buf, sizeof(buf), cie->ie_rsn, ++ cie->ie_rsn[1]+2, ++ rsn_leader, sizeof(rsn_leader)-1); ++ ++ if (iwe.u.data.length != 0) { ++ current_ev = iwe_stream_add_point(&info, current_ev, end_buf, &iwe, ++ buf); ++ } ++ } ++ ++ if (cie->ie_wmm != NULL) { ++ static const char wmm_leader[] = "wmm_ie="; ++ ++ A_MEMZERO(&iwe, sizeof(iwe)); ++ iwe.cmd = IWEVCUSTOM; ++ iwe.u.data.length = encode_ie(buf, sizeof(buf), cie->ie_wmm, ++ cie->ie_wmm[1]+2, ++ wmm_leader, sizeof(wmm_leader)-1); ++ if (iwe.u.data.length != 0) { ++ current_ev = iwe_stream_add_point(&info, current_ev, end_buf, &iwe, ++ buf); ++ } ++ } ++ ++ if (cie->ie_ath != NULL) { ++ static const char ath_leader[] = "ath_ie="; ++ ++ A_MEMZERO(&iwe, sizeof(iwe)); ++ iwe.cmd = IWEVCUSTOM; ++ iwe.u.data.length = encode_ie(buf, sizeof(buf), cie->ie_ath, ++ cie->ie_ath[1]+2, ++ ath_leader, sizeof(ath_leader)-1); ++ if (iwe.u.data.length != 0) { ++ current_ev = iwe_stream_add_point(&info, current_ev, end_buf, &iwe, ++ buf); ++ } ++ } ++ ++ param->current_ev = current_ev; ++} ++ ++int ++ar6000_ioctl_giwscan(struct net_device *dev, ++ struct iw_request_info *info, ++ struct iw_point *data, char *extra) ++{ ++ AR_SOFTC_T *ar = (AR_SOFTC_T *)netdev_priv(dev); ++ struct ar_giwscan_param param; ++ int i; ++ ++ if (ar->arWlanState == WLAN_DISABLED) { ++ return -EIO; ++ } ++ ++ if (ar->arWmiReady == FALSE) { ++ return -EIO; ++ } ++ ++ param.current_ev = extra; ++ param.end_buf = extra + IW_SCAN_MAX_DATA; ++ param.firstPass = TRUE; ++ ++ /* ++ * Do two passes to insure WPA scan candidates ++ * are sorted to the front. This is a hack to deal with ++ * the wireless extensions capping scan results at ++ * IW_SCAN_MAX_DATA bytes. In densely populated environments ++ * it's easy to overflow this buffer (especially with WPA/RSN ++ * information elements). Note this sorting hack does not ++ * guarantee we won't overflow anyway. ++ */ ++ for (i = 0; i < 2; i++) { ++ /* ++ * Translate data to WE format. ++ */ ++ wmi_iterate_nodes(ar->arWmi, ar6000_scan_node, ¶m); ++ param.firstPass = FALSE; ++ if (param.current_ev >= param.end_buf) { ++ data->length = param.current_ev - extra; ++ return -E2BIG; ++ } ++ } ++ ++ data->length = param.current_ev - extra; ++ return 0; ++} ++ ++extern int reconnect_flag; ++/* SIOCSIWESSID */ ++static int ++ar6000_ioctl_siwessid(struct net_device *dev, ++ struct iw_request_info *info, ++ struct iw_point *data, char *ssid) ++{ ++ AR_SOFTC_T *ar = (AR_SOFTC_T *)netdev_priv(dev); ++ A_STATUS status; ++ A_UINT8 arNetworkType; ++ ++ if (ar->arWlanState == WLAN_DISABLED) { ++ return -EIO; ++ } ++ ++ if (ar->arWmiReady == FALSE) { ++ return -EIO; ++ } ++ ++ /* ++ * iwconfig passes a string with length excluding any trailing NUL. ++ * FIXME: we should be able to set an ESSID of 32 bytes, yet things fall ++ * over badly if we do. So we limit the ESSID to 31 bytes. ++ */ ++ if (data->flags && (!data->length || data->length >= sizeof(ar->arSsid))) { ++ /* ++ * ssid is invalid ++ */ ++ return -EINVAL; ++ } ++ /* Added for bug 25178, return an IOCTL error instead of target returning ++ Illegal parameter error when either the BSSID or channel is missing ++ and we cannot scan during connect. ++ */ ++ if (data->flags) { ++ if (ar->arSkipScan == TRUE && ++ (ar->arChannelHint == 0 || ++ (!ar->arReqBssid[0] && !ar->arReqBssid[1] && !ar->arReqBssid[2] && ++ !ar->arReqBssid[3] && !ar->arReqBssid[4] && !ar->arReqBssid[5]))) ++ { ++ return -EINVAL; ++ } ++ } ++ ++ if (down_interruptible(&ar->arSem)) { ++ return -ERESTARTSYS; ++ } ++ ++ if (ar->arTxPending[WMI_CONTROL_PRI]) { ++ /* ++ * sleep until the command queue drains ++ */ ++ wait_event_interruptible_timeout(arEvent, ++ ar->arTxPending[WMI_CONTROL_PRI] == 0, wmitimeout * HZ); ++ if (signal_pending(current)) { ++ return -EINTR; ++ } ++ } ++ ++ if (!data->flags) { ++ arNetworkType = ar->arNetworkType; ++ ar6000_init_profile_info(ar); ++ ar->arNetworkType = arNetworkType; ++ } ++ ++ /* ++ * The original logic here prevented a disconnect if issuing an "essid off" ++ * if no ESSID was set, presumably to prevent sending multiple disconnects ++ * to the WMI. ++ * ++ * Unfortunately, this also meant that no disconnect was sent when we were ++ * already connected, but the profile has been changed since (which also ++ * clears the ESSID as a reminder that the WMI needs updating.) ++ * ++ * The "1 ||" makes sure we always disconnect or reconnect. The WMI doesn't ++ * seem to mind being sent multiple disconnects. ++ */ ++ if (1 || (ar->arSsidLen) || (!data->flags)) ++ { ++ if ((!data->flags) || ++ (A_MEMCMP(ar->arSsid, ssid, ar->arSsidLen) != 0) || ++ (ar->arSsidLen != (data->length))) ++ { ++ /* ++ * SSID set previously or essid off has been issued. ++ * ++ * Disconnect Command is issued in two cases after wmi is ready ++ * (1) ssid is different from the previous setting ++ * (2) essid off has been issued ++ * ++ */ ++ if (ar->arWmiReady == TRUE) { ++ reconnect_flag = 0; ++ status = wmi_disconnect_cmd(ar->arWmi); ++ A_MEMZERO(ar->arSsid, sizeof(ar->arSsid)); ++ ar->arSsidLen = 0; ++ if (ar->arSkipScan == FALSE) { ++ A_MEMZERO(ar->arReqBssid, sizeof(ar->arReqBssid)); ++ } ++ if (!data->flags) { ++ up(&ar->arSem); ++ return 0; ++ } ++ } else { ++ up(&ar->arSem); ++ } ++ } ++ else ++ { ++ /* ++ * SSID is same, so we assume profile hasn't changed. ++ * If the interface is up and wmi is ready, we issue ++ * a reconnect cmd. Issue a reconnect only we are already ++ * connected. ++ */ ++ if((ar->arConnected == TRUE) && (ar->arWmiReady == TRUE)) ++ { ++ reconnect_flag = TRUE; ++ status = wmi_reconnect_cmd(ar->arWmi,ar->arReqBssid, ++ ar->arChannelHint); ++ up(&ar->arSem); ++ if (status != A_OK) { ++ return -EIO; ++ } ++ return 0; ++ } ++ else{ ++ /* ++ * Dont return if connect is pending. ++ */ ++ if(!(ar->arConnectPending)) { ++ up(&ar->arSem); ++ return 0; ++ } ++ } ++ } ++ } ++ ++ ar->arSsidLen = data->length; ++ A_MEMCPY(ar->arSsid, ssid, ar->arSsidLen); ++ ++ /* The ssid length check prevents second "essid off" from the user, ++ to be treated as a connect cmd. The second "essid off" is ignored. ++ */ ++ if((ar->arWmiReady == TRUE) && (ar->arSsidLen > 0) ) ++ { ++ AR6000_SPIN_LOCK(&ar->arLock, 0); ++ if (SHARED_AUTH == ar->arDot11AuthMode) { ++ ar6000_install_static_wep_keys(ar); ++ } ++ AR_DEBUG_PRINTF("Connect called with authmode %d dot11 auth %d"\ ++ " PW crypto %d PW crypto Len %d GRP crypto %d"\ ++ " GRP crypto Len %d\n", ++ ar->arAuthMode, ar->arDot11AuthMode, ++ ar->arPairwiseCrypto, ar->arPairwiseCryptoLen, ++ ar->arGroupCrypto, ar->arGroupCryptoLen); ++ reconnect_flag = 0; ++ AR6000_SPIN_UNLOCK(&ar->arLock, 0); ++ status = wmi_connect_cmd(ar->arWmi, ar->arNetworkType, ++ ar->arDot11AuthMode, ar->arAuthMode, ++ ar->arPairwiseCrypto, ar->arPairwiseCryptoLen, ++ ar->arGroupCrypto,ar->arGroupCryptoLen, ++ ar->arSsidLen, ar->arSsid, ++ ar->arReqBssid, ar->arChannelHint, ++ ar->arConnectCtrlFlags); ++ ++ ++ up(&ar->arSem); ++ ++ if (status != A_OK) { ++ return -EIO; ++ } ++ ar->arConnectPending = TRUE; ++ }else{ ++ up(&ar->arSem); ++ } ++ return 0; ++} ++ ++/* SIOCGIWESSID */ ++static int ++ar6000_ioctl_giwessid(struct net_device *dev, ++ struct iw_request_info *info, ++ struct iw_point *data, char *essid) ++{ ++ AR_SOFTC_T *ar = (AR_SOFTC_T *)netdev_priv(dev); ++ ++ if (ar->arWlanState == WLAN_DISABLED) { ++ return -EIO; ++ } ++ ++ data->flags = 1; ++ data->length = ar->arSsidLen; ++ A_MEMCPY(essid, ar->arSsid, ar->arSsidLen); ++ ++ return 0; ++} ++ ++ ++void ar6000_install_static_wep_keys(AR_SOFTC_T *ar) ++{ ++ A_UINT8 index; ++ A_UINT8 keyUsage; ++ ++ for (index = WMI_MIN_KEY_INDEX; index <= WMI_MAX_KEY_INDEX; index++) { ++ if (ar->arWepKeyList[index].arKeyLen) { ++ keyUsage = GROUP_USAGE; ++ if (index == ar->arDefTxKeyIndex) { ++ keyUsage |= TX_USAGE; ++ } ++ wmi_addKey_cmd(ar->arWmi, ++ index, ++ WEP_CRYPT, ++ keyUsage, ++ ar->arWepKeyList[index].arKeyLen, ++ NULL, ++ ar->arWepKeyList[index].arKey, KEY_OP_INIT_VAL, ++ NO_SYNC_WMIFLAG); ++ } ++ } ++} ++ ++int ++ar6000_ioctl_delkey(struct net_device *dev, struct iw_request_info *info, ++ void *w, char *extra) ++{ ++ return 0; ++} ++ ++int ++ar6000_ioctl_setmlme(struct net_device *dev, struct iw_request_info *info, ++ void *w, char *extra) ++{ ++ AR_SOFTC_T *ar = (AR_SOFTC_T *)netdev_priv(dev); ++ struct ieee80211req_mlme *mlme = (struct ieee80211req_mlme *)extra; ++ ++ if ((ar->arWmiReady == FALSE) || (ar->arConnected != TRUE)) ++ return -EIO; ++ ++ switch (mlme->im_op) { ++ case IEEE80211_MLME_DISASSOC: ++ case IEEE80211_MLME_DEAUTH: ++ /* Not Supported */ ++ break; ++ default: ++ break; ++ } ++ return 0; ++} ++ ++ ++int ++ar6000_ioctl_setwmmparams(struct net_device *dev, struct iw_request_info *info, ++ void *w, char *extra) ++{ ++ return -EIO; /* for now */ ++} ++ ++int ++ar6000_ioctl_getwmmparams(struct net_device *dev, struct iw_request_info *info, ++ void *w, char *extra) ++{ ++ return -EIO; /* for now */ ++} ++ ++int ar6000_ioctl_setoptie(struct net_device *dev, struct iw_request_info *info, ++ struct iw_point *data, char *extra) ++{ ++ /* The target generates the WPA/RSN IE */ ++ return 0; ++} ++ ++int ++ar6000_ioctl_setauthalg(struct net_device *dev, struct iw_request_info *info, ++ void *w, char *extra) ++{ ++ AR_SOFTC_T *ar = (AR_SOFTC_T *)netdev_priv(dev); ++ struct ieee80211req_authalg *req = (struct ieee80211req_authalg *)extra; ++ int ret = 0; ++ ++ ++ AR6000_SPIN_LOCK(&ar->arLock, 0); ++ ++ if (req->auth_alg == AUTH_ALG_OPEN_SYSTEM) { ++ ar->arDot11AuthMode = OPEN_AUTH; ++ } else if (req->auth_alg == AUTH_ALG_LEAP) { ++ ar->arDot11AuthMode = LEAP_AUTH; ++ ar->arPairwiseCrypto = WEP_CRYPT; ++ ar->arGroupCrypto = WEP_CRYPT; ++ } else { ++ ret = -EIO; ++ } ++ ++ AR6000_SPIN_UNLOCK(&ar->arLock, 0); ++ ++ return ret; ++} ++static int ++ar6000_ioctl_addpmkid(struct net_device *dev, struct iw_request_info *info, ++ void *w, char *extra) ++{ ++ AR_SOFTC_T *ar = (AR_SOFTC_T *)netdev_priv(dev); ++ struct ieee80211req_addpmkid *req = (struct ieee80211req_addpmkid *)extra; ++ A_STATUS status; ++ ++ if (ar->arWlanState == WLAN_DISABLED) { ++ return -EIO; ++ } ++ ++ AR_DEBUG_PRINTF("Add pmkid for %2.2x:%2.2x:%2.2x:%2.2x:%2.2x:%2.2x en=%d\n", ++ req->pi_bssid[0], req->pi_bssid[1], req->pi_bssid[2], ++ req->pi_bssid[3], req->pi_bssid[4], req->pi_bssid[5], ++ req->pi_enable); ++ ++ status = wmi_setPmkid_cmd(ar->arWmi, req->pi_bssid, req->pi_pmkid, ++ req->pi_enable); ++ ++ if (status != A_OK) { ++ return -EIO; ++ } ++ ++ return 0; ++} ++ ++/* ++ * SIOCSIWRATE ++ */ ++int ++ar6000_ioctl_siwrate(struct net_device *dev, ++ struct iw_request_info *info, ++ struct iw_param *rrq, char *extra) ++{ ++ AR_SOFTC_T *ar = (AR_SOFTC_T *)netdev_priv(dev); ++ A_UINT32 kbps; ++ ++ if (rrq->fixed) { ++ kbps = rrq->value / 1000; /* rrq->value is in bps */ ++ } else { ++ kbps = -1; /* -1 indicates auto rate */ ++ } ++ if(kbps != -1 && wmi_validate_bitrate(ar->arWmi, kbps) == A_EINVAL) ++ { ++ AR_DEBUG_PRINTF("BitRate is not Valid %d\n", kbps); ++ return -EINVAL; ++ } ++ ar->arBitRate = kbps; ++ if(ar->arWmiReady == TRUE) ++ { ++ if (wmi_set_bitrate_cmd(ar->arWmi, kbps) != A_OK) { ++ return -EINVAL; ++ } ++ } ++ return 0; ++} ++ ++/* ++ * SIOCGIWRATE ++ */ ++int ++ar6000_ioctl_giwrate(struct net_device *dev, ++ struct iw_request_info *info, ++ struct iw_param *rrq, char *extra) ++{ ++ AR_SOFTC_T *ar = (AR_SOFTC_T *)netdev_priv(dev); ++ int ret = 0; ++ ++ if (down_interruptible(&ar->arSem)) { ++ return -ERESTARTSYS; ++ } ++ if(ar->arWmiReady == TRUE) ++ { ++ ar->arBitRate = 0xFFFF; ++ if (wmi_get_bitrate_cmd(ar->arWmi) != A_OK) { ++ up(&ar->arSem); ++ return -EIO; ++ } ++ wait_event_interruptible_timeout(arEvent, ar->arBitRate != 0xFFFF, wmitimeout * HZ); ++ if (signal_pending(current)) { ++ ret = -EINTR; ++ } ++ } ++ /* If the interface is down or wmi is not ready or the target is not ++ connected - return the value stored in the device structure */ ++ if (!ret) { ++ if (ar->arBitRate == -1) { ++ rrq->fixed = TRUE; ++ rrq->value = 0; ++ } else { ++ rrq->value = ar->arBitRate * 1000; ++ } ++ } ++ ++ up(&ar->arSem); ++ ++ return ret; ++} ++ ++/* ++ * SIOCSIWTXPOW ++ */ ++static int ++ar6000_ioctl_siwtxpow(struct net_device *dev, ++ struct iw_request_info *info, ++ struct iw_param *rrq, char *extra) ++{ ++ AR_SOFTC_T *ar = (AR_SOFTC_T *)netdev_priv(dev); ++ A_UINT8 dbM; ++ ++ if (ar->arWlanState == WLAN_DISABLED) { ++ return -EIO; ++ } ++ ++ if (ar->arRadioSwitch == WLAN_ENABLED ++ && rrq->disabled) { ++ if (wmi_switch_radio(ar->arWmi, WLAN_DISABLED) < 0) ++ return -EIO; ++ ar->arRadioSwitch = WLAN_DISABLED; ++ } else if (ar->arRadioSwitch == WLAN_DISABLED ++ && !rrq->disabled) { ++ if (wmi_switch_radio(ar->arWmi, WLAN_ENABLED) < 0) ++ return -EIO; ++ ar->arRadioSwitch = WLAN_ENABLED; ++ } ++ ++ if (rrq->fixed) { ++ if (rrq->flags != IW_TXPOW_DBM) { ++ return -EOPNOTSUPP; ++ } ++ ar->arTxPwr= dbM = rrq->value; ++ ar->arTxPwrSet = TRUE; ++ } else { ++ ar->arTxPwr = dbM = 0; ++ ar->arTxPwrSet = FALSE; ++ } ++ if(ar->arWmiReady == TRUE) ++ { ++ AR_DEBUG_PRINTF("Set tx pwr cmd %d dbM\n", dbM); ++ wmi_set_txPwr_cmd(ar->arWmi, dbM); ++ } ++ return 0; ++} ++ ++/* ++ * SIOCGIWTXPOW ++ */ ++int ++ar6000_ioctl_giwtxpow(struct net_device *dev, ++ struct iw_request_info *info, ++ struct iw_param *rrq, char *extra) ++{ ++ AR_SOFTC_T *ar = (AR_SOFTC_T *)netdev_priv(dev); ++ int ret = 0; ++ ++ if (ar->arWlanState == WLAN_DISABLED) { ++ return -EIO; ++ } ++ ++ if (ar->arRadioSwitch == WLAN_DISABLED) { ++ rrq->disabled = 1; ++ return 0; ++ } ++ ++ if (down_interruptible(&ar->arSem)) { ++ return -ERESTARTSYS; ++ } ++ if((ar->arWmiReady == TRUE) && (ar->arConnected == TRUE)) ++ { ++ ar->arTxPwr = 0; ++ ++ if (wmi_get_txPwr_cmd(ar->arWmi) != A_OK) { ++ up(&ar->arSem); ++ return -EIO; ++ } ++ ++ wait_event_interruptible_timeout(arEvent, ar->arTxPwr != 0, wmitimeout * HZ); ++ ++ if (signal_pending(current)) { ++ ret = -EINTR; ++ } ++ } ++ /* If the interace is down or wmi is not ready or target is not connected ++ then return value stored in the device structure */ ++ ++ if (!ret) { ++ if (ar->arTxPwrSet == TRUE) { ++ rrq->fixed = TRUE; ++ } ++ rrq->value = ar->arTxPwr; ++ rrq->flags = IW_TXPOW_DBM; ++ } ++ ++ up(&ar->arSem); ++ ++ return ret; ++} ++ ++/* ++ * SIOCSIWRETRY ++ * since iwconfig only provides us with one max retry value, we use it ++ * to apply to data frames of the BE traffic class. ++ */ ++static int ++ar6000_ioctl_siwretry(struct net_device *dev, ++ struct iw_request_info *info, ++ struct iw_param *rrq, char *extra) ++{ ++ AR_SOFTC_T *ar = (AR_SOFTC_T *)netdev_priv(dev); ++ ++ if (ar->arWlanState == WLAN_DISABLED) { ++ return -EIO; ++ } ++ ++ if (rrq->disabled) { ++ return -EOPNOTSUPP; ++ } ++ ++ if ((rrq->flags & IW_RETRY_TYPE) != IW_RETRY_LIMIT) { ++ return -EOPNOTSUPP; ++ } ++ ++ if ( !(rrq->value >= WMI_MIN_RETRIES) || !(rrq->value <= WMI_MAX_RETRIES)) { ++ return - EINVAL; ++ } ++ if(ar->arWmiReady == TRUE) ++ { ++ if (wmi_set_retry_limits_cmd(ar->arWmi, DATA_FRAMETYPE, WMM_AC_BE, ++ rrq->value, 0) != A_OK){ ++ return -EINVAL; ++ } ++ } ++ ar->arMaxRetries = rrq->value; ++ return 0; ++} ++ ++/* ++ * SIOCGIWRETRY ++ */ ++static int ++ar6000_ioctl_giwretry(struct net_device *dev, ++ struct iw_request_info *info, ++ struct iw_param *rrq, char *extra) ++{ ++ AR_SOFTC_T *ar = (AR_SOFTC_T *)netdev_priv(dev); ++ ++ if (ar->arWlanState == WLAN_DISABLED) { ++ return -EIO; ++ } ++ ++ rrq->disabled = 0; ++ switch (rrq->flags & IW_RETRY_TYPE) { ++ case IW_RETRY_LIFETIME: ++ return -EOPNOTSUPP; ++ break; ++ case IW_RETRY_LIMIT: ++ rrq->flags = IW_RETRY_LIMIT; ++ switch (rrq->flags & IW_RETRY_MODIFIER) { ++ case IW_RETRY_MIN: ++ rrq->flags |= IW_RETRY_MIN; ++ rrq->value = WMI_MIN_RETRIES; ++ break; ++ case IW_RETRY_MAX: ++ rrq->flags |= IW_RETRY_MAX; ++ rrq->value = ar->arMaxRetries; ++ break; ++ } ++ break; ++ } ++ return 0; ++} ++ ++/* ++ * SIOCSIWENCODE ++ */ ++static int ++ar6000_ioctl_siwencode(struct net_device *dev, ++ struct iw_request_info *info, ++ struct iw_point *erq, char *keybuf) ++{ ++ AR_SOFTC_T *ar = (AR_SOFTC_T *)netdev_priv(dev); ++ int index; ++ A_INT32 auth = ar->arDot11AuthMode; ++ ++ if (ar->arWlanState == WLAN_DISABLED) { ++ return -EIO; ++ } ++ ++ index = erq->flags & IW_ENCODE_INDEX; ++ ++ if (index && (((index - 1) < WMI_MIN_KEY_INDEX) || ++ ((index - 1) > WMI_MAX_KEY_INDEX))) ++ { ++ return -EIO; ++ } ++ ++ if (erq->flags & IW_ENCODE_DISABLED) { ++ /* ++ * Encryption disabled ++ */ ++ if (index) { ++ /* ++ * If key index was specified then clear the specified key ++ */ ++ index--; ++ A_MEMZERO(ar->arWepKeyList[index].arKey, ++ sizeof(ar->arWepKeyList[index].arKey)); ++ ar->arWepKeyList[index].arKeyLen = 0; ++ } ++ ar->arDot11AuthMode = OPEN_AUTH; ++ ar->arPairwiseCrypto = NONE_CRYPT; ++ ar->arGroupCrypto = NONE_CRYPT; ++ ar->arAuthMode = NONE_AUTH; ++ } else { ++ /* ++ * Enabling WEP encryption ++ */ ++ if (index) { ++ index--; /* keyindex is off base 1 in iwconfig */ ++ } ++ ++ if (erq->flags & IW_ENCODE_OPEN) { ++ auth = OPEN_AUTH; ++ } else if (erq->flags & IW_ENCODE_RESTRICTED) { ++ auth = SHARED_AUTH; ++ } ++ ++ if (erq->length) { ++ if (!IEEE80211_IS_VALID_WEP_CIPHER_LEN(erq->length)) { ++ return -EIO; ++ } ++ ++ A_MEMZERO(ar->arWepKeyList[index].arKey, ++ sizeof(ar->arWepKeyList[index].arKey)); ++ A_MEMCPY(ar->arWepKeyList[index].arKey, keybuf, erq->length); ++ ar->arWepKeyList[index].arKeyLen = erq->length; ++ } else { ++ if (ar->arWepKeyList[index].arKeyLen == 0) { ++ return -EIO; ++ } ++ ar->arDefTxKeyIndex = index; ++ } ++ ++ ar->arPairwiseCrypto = WEP_CRYPT; ++ ar->arGroupCrypto = WEP_CRYPT; ++ ar->arDot11AuthMode = auth; ++ ar->arAuthMode = NONE_AUTH; ++ } ++ ++ /* ++ * profile has changed. Erase ssid to signal change ++ */ ++ A_MEMZERO(ar->arSsid, sizeof(ar->arSsid)); ++ ar->arSsidLen = 0; ++ ++ return 0; ++} ++ ++static int ++ar6000_ioctl_giwencode(struct net_device *dev, ++ struct iw_request_info *info, ++ struct iw_point *erq, char *key) ++{ ++ AR_SOFTC_T *ar = (AR_SOFTC_T *)netdev_priv(dev); ++ A_UINT8 keyIndex; ++ struct ar_wep_key *wk; ++ ++ if (ar->arWlanState == WLAN_DISABLED) { ++ return -EIO; ++ } ++ ++ if (ar->arPairwiseCrypto == NONE_CRYPT) { ++ erq->length = 0; ++ erq->flags = IW_ENCODE_DISABLED; ++ } else { ++ /* get the keyIndex */ ++ keyIndex = erq->flags & IW_ENCODE_INDEX; ++ if (0 == keyIndex) { ++ keyIndex = ar->arDefTxKeyIndex; ++ } else if ((keyIndex - 1 < WMI_MIN_KEY_INDEX) || ++ (keyIndex - 1 > WMI_MAX_KEY_INDEX)) ++ { ++ keyIndex = WMI_MIN_KEY_INDEX; ++ } else { ++ keyIndex--; ++ } ++ erq->flags = keyIndex + 1; ++ erq->flags |= IW_ENCODE_ENABLED; ++ wk = &ar->arWepKeyList[keyIndex]; ++ if (erq->length > wk->arKeyLen) { ++ erq->length = wk->arKeyLen; ++ } ++ if (wk->arKeyLen) { ++ A_MEMCPY(key, wk->arKey, erq->length); ++ } ++ if (ar->arDot11AuthMode == OPEN_AUTH) { ++ erq->flags |= IW_ENCODE_OPEN; ++ } else if (ar->arDot11AuthMode == SHARED_AUTH) { ++ erq->flags |= IW_ENCODE_RESTRICTED; ++ } ++ } ++ ++ return 0; ++} ++ ++static int ar6000_ioctl_siwpower(struct net_device *dev, ++ struct iw_request_info *info, ++ union iwreq_data *wrqu, char *extra) ++{ ++ AR_SOFTC_T *ar = (AR_SOFTC_T *)netdev_priv(dev); ++ WMI_POWER_MODE power_mode; ++ ++ if (wrqu->power.disabled) ++ power_mode = MAX_PERF_POWER; ++ else ++ power_mode = REC_POWER; ++ ++ if (wmi_powermode_cmd(ar->arWmi, power_mode) < 0) ++ return -EIO; ++ ++ return 0; ++} ++ ++static int ar6000_ioctl_giwpower(struct net_device *dev, ++ struct iw_request_info *info, ++ union iwreq_data *wrqu, char *extra) ++{ ++ AR_SOFTC_T *ar = (AR_SOFTC_T *)netdev_priv(dev); ++ ++ /* ++ * FIXME: ++ * https://docs.openmoko.org/trac/ticket/2267 ++ * When starting wpa_supplicant the kernel oopses. ++ * The following condition avoids the oops. ++ * Remove this comment to bless this solution. ++ */ ++ if (ar->arWlanState == WLAN_DISABLED || ar->arWmiReady == FALSE) ++ return -EIO; ++ ++ return wmi_get_power_mode_cmd(ar->arWmi); ++} ++ ++static int ar6000_ioctl_siwgenie(struct net_device *dev, ++ struct iw_request_info *info, ++ struct iw_point *dwrq, ++ char *extra) ++{ ++ /* The target does that for us */ ++ return 0; ++} ++ ++static int ar6000_ioctl_giwgenie(struct net_device *dev, ++ struct iw_request_info *info, ++ struct iw_point *dwrq, ++ char *extra) ++{ ++ return 0; ++} ++ ++static int ar6000_ioctl_siwauth(struct net_device *dev, ++ struct iw_request_info *info, ++ struct iw_param *param, ++ char *extra) ++{ ++ AR_SOFTC_T *ar = (AR_SOFTC_T *)netdev_priv(dev); ++ int reset = 0; ++ ++ switch (param->flags & IW_AUTH_INDEX) { ++ case IW_AUTH_WPA_VERSION: ++ if (param->value & IW_AUTH_WPA_VERSION_DISABLED) { ++ ar->arAuthMode = NONE_AUTH; ++ } ++ if (param->value & IW_AUTH_WPA_VERSION_WPA) { ++ ar->arAuthMode = WPA_AUTH; ++ } ++ if (param->value & IW_AUTH_WPA_VERSION_WPA2) { ++ ar->arAuthMode = WPA2_AUTH; ++ } ++ ++ reset = 1; ++ break; ++ case IW_AUTH_CIPHER_PAIRWISE: ++ if (param->value & IW_AUTH_CIPHER_NONE) { ++ ar->arPairwiseCrypto = NONE_CRYPT; ++ } ++ if (param->value & IW_AUTH_CIPHER_WEP40) { ++ ar->arPairwiseCrypto = WEP_CRYPT; ++ } ++ if (param->value & IW_AUTH_CIPHER_TKIP) { ++ ar->arPairwiseCrypto = TKIP_CRYPT; ++ } ++ if (param->value & IW_AUTH_CIPHER_CCMP) { ++ ar->arPairwiseCrypto = AES_CRYPT; ++ } ++ ++ reset = 1; ++ break; ++ case IW_AUTH_CIPHER_GROUP: ++ if (param->value & IW_AUTH_CIPHER_NONE) { ++ ar->arGroupCrypto = NONE_CRYPT; ++ } ++ if (param->value & IW_AUTH_CIPHER_WEP40) { ++ ar->arGroupCrypto = WEP_CRYPT; ++ } ++ if (param->value & IW_AUTH_CIPHER_TKIP) { ++ ar->arGroupCrypto = TKIP_CRYPT; ++ } ++ if (param->value & IW_AUTH_CIPHER_CCMP) { ++ ar->arGroupCrypto = AES_CRYPT; ++ } ++ ++ reset = 1; ++ break; ++ case IW_AUTH_KEY_MGMT: ++ if (param->value & IW_AUTH_KEY_MGMT_PSK) { ++ if (ar->arAuthMode == WPA_AUTH) { ++ ar->arAuthMode = WPA_PSK_AUTH; ++ } else if (ar->arAuthMode == WPA2_AUTH) { ++ ar->arAuthMode = WPA2_PSK_AUTH; ++ } ++ ++ reset = 1; ++ } ++ break; ++ ++ case IW_AUTH_TKIP_COUNTERMEASURES: ++ if (ar->arWmiReady == FALSE) { ++ return -EIO; ++ } ++ wmi_set_tkip_countermeasures_cmd(ar->arWmi, param->value); ++ break; ++ ++ case IW_AUTH_DROP_UNENCRYPTED: ++ break; ++ ++ case IW_AUTH_80211_AUTH_ALG: ++ if (param->value & IW_AUTH_ALG_OPEN_SYSTEM) { ++ ar->arDot11AuthMode = OPEN_AUTH; ++ } ++ if (param->value & IW_AUTH_ALG_SHARED_KEY) { ++ ar->arDot11AuthMode = SHARED_AUTH; ++ } ++ if (param->value & IW_AUTH_ALG_LEAP) { ++ ar->arDot11AuthMode = LEAP_AUTH; ++ ar->arPairwiseCrypto = WEP_CRYPT; ++ ar->arGroupCrypto = WEP_CRYPT; ++ } ++ ++ reset = 1; ++ break; ++ ++ case IW_AUTH_WPA_ENABLED: ++ reset = 1; ++ break; ++ ++ case IW_AUTH_RX_UNENCRYPTED_EAPOL: ++ break; ++ ++ case IW_AUTH_PRIVACY_INVOKED: ++ break; ++ ++ default: ++ printk("%s(): Unknown flag 0x%x\n", __FUNCTION__, param->flags); ++ return -EOPNOTSUPP; ++ } ++ ++ if (reset) { ++ A_MEMZERO(ar->arSsid, sizeof(ar->arSsid)); ++ ar->arSsidLen = 0; ++ } ++ ++ return 0; ++} ++ ++static int ar6000_ioctl_giwauth(struct net_device *dev, ++ struct iw_request_info *info, ++ struct iw_param *dwrq, ++ char *extra) ++{ ++ return 0; ++} ++ ++static int ar6000_ioctl_siwencodeext(struct net_device *dev, ++ struct iw_request_info *info, ++ union iwreq_data *wrqu, ++ char *extra) ++{ ++ AR_SOFTC_T *ar = (AR_SOFTC_T *)netdev_priv(dev); ++ struct iw_point *encoding = &wrqu->encoding; ++ struct iw_encode_ext *ext = (struct iw_encode_ext *)extra; ++ int alg = ext->alg, idx; ++ ++ if (ar->arWlanState == WLAN_DISABLED) { ++ return -EIO; ++ } ++ ++ /* Determine and validate the key index */ ++ idx = (encoding->flags & IW_ENCODE_INDEX) - 1; ++ if (idx) { ++ if (idx < 0 || idx > 3) ++ return -EINVAL; ++ } ++ ++ if ((alg == IW_ENCODE_ALG_TKIP) || (alg == IW_ENCODE_ALG_CCMP)) { ++ struct ieee80211req_key ik; ++ KEY_USAGE key_usage; ++ CRYPTO_TYPE key_type = NONE_CRYPT; ++ int status; ++ ++ ar->user_saved_keys.keyOk = FALSE; ++ ++ if (alg == IW_ENCODE_ALG_TKIP) { ++ key_type = TKIP_CRYPT; ++ ik.ik_type = IEEE80211_CIPHER_TKIP; ++ } else { ++ key_type = AES_CRYPT; ++ ik.ik_type = IEEE80211_CIPHER_AES_CCM; ++ } ++ ++ ik.ik_keyix = idx; ++ ik.ik_keylen = ext->key_len; ++ ik.ik_flags = IEEE80211_KEY_RECV; ++ if (ext->ext_flags & IW_ENCODE_EXT_SET_TX_KEY) { ++ ik.ik_flags |= IEEE80211_KEY_XMIT ++ | IEEE80211_KEY_DEFAULT; ++ } ++ ++ if (ext->ext_flags & IW_ENCODE_EXT_RX_SEQ_VALID) { ++ memcpy(&ik.ik_keyrsc, ext->rx_seq, 8); ++ } ++ ++ memcpy(ik.ik_keydata, ext->key, ext->key_len); ++ ++ ar->user_saved_keys.keyType = key_type; ++ if (ext->ext_flags & IW_ENCODE_EXT_GROUP_KEY) { ++ key_usage = GROUP_USAGE; ++ memset(ik.ik_macaddr, 0, ETH_ALEN); ++ memcpy(&ar->user_saved_keys.bcast_ik, &ik, ++ sizeof(struct ieee80211req_key)); ++ } else { ++ key_usage = PAIRWISE_USAGE; ++ memcpy(ik.ik_macaddr, ext->addr.sa_data, ETH_ALEN); ++ memcpy(&ar->user_saved_keys.ucast_ik, &ik, ++ sizeof(struct ieee80211req_key)); ++ } ++ ++ status = wmi_addKey_cmd(ar->arWmi, ik.ik_keyix, key_type, ++ key_usage, ik.ik_keylen, ++ (A_UINT8 *)&ik.ik_keyrsc, ++ ik.ik_keydata, ++ KEY_OP_INIT_VAL, SYNC_BEFORE_WMIFLAG); ++ ++ if (status < 0) ++ return -EIO; ++ ++ ar->user_saved_keys.keyOk = TRUE; ++ ++ return 0; ++ ++ } else { ++ /* WEP falls back to SIWENCODE */ ++ return -EOPNOTSUPP; ++ } ++ ++ return 0; ++} ++ ++ ++static int ar6000_ioctl_giwencodeext(struct net_device *dev, ++ struct iw_request_info *info, ++ struct iw_point *dwrq, ++ char *extra) ++{ ++ return 0; ++} ++ ++ ++static int ++ar6000_ioctl_setparam(struct net_device *dev, ++ struct iw_request_info *info, ++ void *erq, char *extra) ++{ ++ AR_SOFTC_T *ar = (AR_SOFTC_T *)netdev_priv(dev); ++ int *i = (int *)extra; ++ int param = i[0]; ++ int value = i[1]; ++ int ret = 0; ++ A_BOOL profChanged = FALSE; ++ ++ if (ar->arWlanState == WLAN_DISABLED) { ++ return -EIO; ++ } ++ ++ switch (param) { ++ case IEEE80211_PARAM_WPA: ++ switch (value) { ++ case WPA_MODE_WPA1: ++ ar->arAuthMode = WPA_AUTH; ++ profChanged = TRUE; ++ break; ++ case WPA_MODE_WPA2: ++ ar->arAuthMode = WPA2_AUTH; ++ profChanged = TRUE; ++ break; ++ case WPA_MODE_NONE: ++ ar->arAuthMode = NONE_AUTH; ++ profChanged = TRUE; ++ break; ++ default: ++ printk("IEEE80211_PARAM_WPA: Unknown value %d\n", value); ++ } ++ break; ++ case IEEE80211_PARAM_AUTHMODE: ++ switch(value) { ++ case IEEE80211_AUTH_WPA_PSK: ++ if (WPA_AUTH == ar->arAuthMode) { ++ ar->arAuthMode = WPA_PSK_AUTH; ++ profChanged = TRUE; ++ } else if (WPA2_AUTH == ar->arAuthMode) { ++ ar->arAuthMode = WPA2_PSK_AUTH; ++ profChanged = TRUE; ++ } else { ++ AR_DEBUG_PRINTF("Error - Setting PSK mode when WPA "\ ++ "param was set to %d\n", ++ ar->arAuthMode); ++ ret = -1; ++ } ++ break; ++ case IEEE80211_AUTH_WPA_CCKM: ++ if (WPA2_AUTH == ar->arAuthMode) { ++ ar->arAuthMode = WPA2_AUTH_CCKM; ++ } else { ++ ar->arAuthMode = WPA_AUTH_CCKM; ++ } ++ break; ++ default: ++ break; ++ } ++ break; ++ case IEEE80211_PARAM_UCASTCIPHER: ++ switch (value) { ++ case IEEE80211_CIPHER_AES_CCM: ++ ar->arPairwiseCrypto = AES_CRYPT; ++ profChanged = TRUE; ++ break; ++ case IEEE80211_CIPHER_TKIP: ++ ar->arPairwiseCrypto = TKIP_CRYPT; ++ profChanged = TRUE; ++ break; ++ case IEEE80211_CIPHER_WEP: ++ ar->arPairwiseCrypto = WEP_CRYPT; ++ profChanged = TRUE; ++ break; ++ case IEEE80211_CIPHER_NONE: ++ ar->arPairwiseCrypto = NONE_CRYPT; ++ profChanged = TRUE; ++ break; ++ } ++ break; ++ case IEEE80211_PARAM_UCASTKEYLEN: ++ if (!IEEE80211_IS_VALID_WEP_CIPHER_LEN(value)) { ++ ret = -EIO; ++ } else { ++ ar->arPairwiseCryptoLen = value; ++ } ++ break; ++ case IEEE80211_PARAM_MCASTCIPHER: ++ switch (value) { ++ case IEEE80211_CIPHER_AES_CCM: ++ ar->arGroupCrypto = AES_CRYPT; ++ profChanged = TRUE; ++ break; ++ case IEEE80211_CIPHER_TKIP: ++ ar->arGroupCrypto = TKIP_CRYPT; ++ profChanged = TRUE; ++ break; ++ case IEEE80211_CIPHER_WEP: ++ ar->arGroupCrypto = WEP_CRYPT; ++ profChanged = TRUE; ++ break; ++ case IEEE80211_CIPHER_NONE: ++ ar->arGroupCrypto = NONE_CRYPT; ++ profChanged = TRUE; ++ break; ++ } ++ break; ++ case IEEE80211_PARAM_MCASTKEYLEN: ++ if (!IEEE80211_IS_VALID_WEP_CIPHER_LEN(value)) { ++ ret = -EIO; ++ } else { ++ ar->arGroupCryptoLen = value; ++ } ++ break; ++ case IEEE80211_PARAM_COUNTERMEASURES: ++ if (ar->arWmiReady == FALSE) { ++ return -EIO; ++ } ++ wmi_set_tkip_countermeasures_cmd(ar->arWmi, value); ++ break; ++ default: ++ break; ++ } ++ ++ if (profChanged == TRUE) { ++ /* ++ * profile has changed. Erase ssid to signal change ++ */ ++ A_MEMZERO(ar->arSsid, sizeof(ar->arSsid)); ++ ar->arSsidLen = 0; ++ } ++ ++ return ret; ++} ++ ++int ++ar6000_ioctl_getparam(struct net_device *dev, struct iw_request_info *info, ++ void *w, char *extra) ++{ ++ return -EIO; /* for now */ ++} ++ ++int ++ar6000_ioctl_setkey(struct net_device *dev, struct iw_request_info *info, ++ void *w, char *extra) ++{ ++ AR_SOFTC_T *ar = (AR_SOFTC_T *)netdev_priv(dev); ++ struct ieee80211req_key *ik = (struct ieee80211req_key *)extra; ++ KEY_USAGE keyUsage; ++ A_STATUS status; ++ CRYPTO_TYPE keyType = NONE_CRYPT; ++ ++ if (ar->arWlanState == WLAN_DISABLED) { ++ return -EIO; ++ } ++ ++ ar->user_saved_keys.keyOk = FALSE; ++ ++ if ( 0 == memcmp(ik->ik_macaddr, "\x00\x00\x00\x00\x00\x00", ++ IEEE80211_ADDR_LEN)) { ++ keyUsage = GROUP_USAGE; ++ A_MEMCPY(&ar->user_saved_keys.bcast_ik, ik, ++ sizeof(struct ieee80211req_key)); ++ } else { ++ keyUsage = PAIRWISE_USAGE; ++ A_MEMCPY(&ar->user_saved_keys.ucast_ik, ik, ++ sizeof(struct ieee80211req_key)); ++ } ++ ++ switch (ik->ik_type) { ++ case IEEE80211_CIPHER_WEP: ++ keyType = WEP_CRYPT; ++ break; ++ case IEEE80211_CIPHER_TKIP: ++ keyType = TKIP_CRYPT; ++ break; ++ case IEEE80211_CIPHER_AES_CCM: ++ keyType = AES_CRYPT; ++ break; ++ default: ++ break; ++ } ++ ar->user_saved_keys.keyType = keyType; ++ ++ if (IEEE80211_CIPHER_CCKM_KRK != ik->ik_type) { ++ if (NONE_CRYPT == keyType) { ++ return -EIO; ++ } ++ ++ status = wmi_addKey_cmd(ar->arWmi, ik->ik_keyix, keyType, keyUsage, ++ ik->ik_keylen, (A_UINT8 *)&ik->ik_keyrsc, ++ ik->ik_keydata, KEY_OP_INIT_VAL, ++ SYNC_BEFORE_WMIFLAG); ++ ++ if (status != A_OK) { ++ return -EIO; ++ } ++ } else { ++ status = wmi_add_krk_cmd(ar->arWmi, ik->ik_keydata); ++ } ++ ++ ar->user_saved_keys.keyOk = TRUE; ++ ++ return 0; ++} ++ ++ ++/* ++ * SIOCGIWNAME ++ */ ++int ++ar6000_ioctl_giwname(struct net_device *dev, ++ struct iw_request_info *info, ++ char *name, char *extra) ++{ ++ AR_SOFTC_T *ar = (AR_SOFTC_T *)netdev_priv(dev); ++ ++ if (ar->arWlanState == WLAN_DISABLED) { ++ return -EIO; ++ } ++ ++ switch (ar->arPhyCapability) { ++ case (WMI_11A_CAPABILITY): ++ strncpy(name, "AR6000 802.11a", IFNAMSIZ); ++ break; ++ case (WMI_11G_CAPABILITY): ++ strncpy(name, "AR6000 802.11g", IFNAMSIZ); ++ break; ++ case (WMI_11AG_CAPABILITY): ++ strncpy(name, "AR6000 802.11ag", IFNAMSIZ); ++ break; ++ default: ++ strncpy(name, "AR6000 802.11", IFNAMSIZ); ++ break; ++ } ++ ++ return 0; ++} ++ ++/* ++ * SIOCSIWFREQ ++ */ ++int ++ar6000_ioctl_siwfreq(struct net_device *dev, ++ struct iw_request_info *info, ++ struct iw_freq *freq, char *extra) ++{ ++ AR_SOFTC_T *ar = (AR_SOFTC_T *)netdev_priv(dev); ++ ++ if (ar->arWlanState == WLAN_DISABLED) { ++ return -EIO; ++ } ++ ++ /* ++ * We support limiting the channels via wmiconfig. ++ * ++ * We use this command to configure the channel hint for the connect cmd ++ * so it is possible the target will end up connecting to a different ++ * channel. ++ */ ++ if (freq->e > 1) { ++ return -EINVAL; ++ } else if (freq->e == 1) { ++ ar->arChannelHint = freq->m / 100000; ++ } else { ++ ar->arChannelHint = wlan_ieee2freq(freq->m); ++ } ++ ++ A_PRINTF("channel hint set to %d\n", ar->arChannelHint); ++ return 0; ++} ++ ++/* ++ * SIOCGIWFREQ ++ */ ++int ++ar6000_ioctl_giwfreq(struct net_device *dev, ++ struct iw_request_info *info, ++ struct iw_freq *freq, char *extra) ++{ ++ AR_SOFTC_T *ar = (AR_SOFTC_T *)netdev_priv(dev); ++ ++ if (ar->arWlanState == WLAN_DISABLED) { ++ return -EIO; ++ } ++ ++ if (ar->arConnected != TRUE) { ++ return -EINVAL; ++ } ++ ++ freq->m = ar->arBssChannel * 100000; ++ freq->e = 1; ++ ++ return 0; ++} ++ ++/* ++ * SIOCSIWMODE ++ */ ++int ++ar6000_ioctl_siwmode(struct net_device *dev, ++ struct iw_request_info *info, ++ __u32 *mode, char *extra) ++{ ++ AR_SOFTC_T *ar = (AR_SOFTC_T *)netdev_priv(dev); ++ ++ if (ar->arWlanState == WLAN_DISABLED) { ++ return -EIO; ++ } ++ ++ switch (*mode) { ++ case IW_MODE_INFRA: ++ ar->arNetworkType = INFRA_NETWORK; ++ break; ++ case IW_MODE_ADHOC: ++ ar->arNetworkType = ADHOC_NETWORK; ++ break; ++ default: ++ return -EINVAL; ++ } ++ ++ return 0; ++} ++ ++/* ++ * SIOCGIWMODE ++ */ ++int ++ar6000_ioctl_giwmode(struct net_device *dev, ++ struct iw_request_info *info, ++ __u32 *mode, char *extra) ++{ ++ AR_SOFTC_T *ar = (AR_SOFTC_T *)netdev_priv(dev); ++ ++ if (ar->arWlanState == WLAN_DISABLED) { ++ return -EIO; ++ } ++ ++ switch (ar->arNetworkType) { ++ case INFRA_NETWORK: ++ *mode = IW_MODE_INFRA; ++ break; ++ case ADHOC_NETWORK: ++ *mode = IW_MODE_ADHOC; ++ break; ++ default: ++ return -EIO; ++ } ++ return 0; ++} ++ ++/* ++ * SIOCSIWSENS ++ */ ++int ++ar6000_ioctl_siwsens(struct net_device *dev, ++ struct iw_request_info *info, ++ struct iw_param *sens, char *extra) ++{ ++ return 0; ++} ++ ++/* ++ * SIOCGIWSENS ++ */ ++int ++ar6000_ioctl_giwsens(struct net_device *dev, ++ struct iw_request_info *info, ++ struct iw_param *sens, char *extra) ++{ ++ sens->value = 0; ++ sens->fixed = 1; ++ ++ return 0; ++} ++ ++/* ++ * SIOCGIWRANGE ++ */ ++int ++ar6000_ioctl_giwrange(struct net_device *dev, ++ struct iw_request_info *info, ++ struct iw_point *data, char *extra) ++{ ++ AR_SOFTC_T *ar = (AR_SOFTC_T *)netdev_priv(dev); ++ struct iw_range *range = (struct iw_range *) extra; ++ int i, ret = 0; ++ ++ if (ar->arWmiReady == FALSE) { ++ return -EIO; ++ } ++ ++ if (ar->arWlanState == WLAN_DISABLED) { ++ return -EIO; ++ } ++ ++ if (down_interruptible(&ar->arSem)) { ++ return -ERESTARTSYS; ++ } ++ ar->arNumChannels = -1; ++ A_MEMZERO(ar->arChannelList, sizeof (ar->arChannelList)); ++ ++ if (wmi_get_channelList_cmd(ar->arWmi) != A_OK) { ++ up(&ar->arSem); ++ return -EIO; ++ } ++ ++ wait_event_interruptible_timeout(arEvent, ar->arNumChannels != -1, wmitimeout * HZ); ++ ++ if (signal_pending(current)) { ++ up(&ar->arSem); ++ return -EINTR; ++ } ++ ++ data->length = sizeof(struct iw_range); ++ A_MEMZERO(range, sizeof(struct iw_range)); ++ ++ range->txpower_capa = IW_TXPOW_DBM; ++ ++ range->min_pmp = 1 * 1024; ++ range->max_pmp = 65535 * 1024; ++ range->min_pmt = 1 * 1024; ++ range->max_pmt = 1000 * 1024; ++ range->pmp_flags = IW_POWER_PERIOD; ++ range->pmt_flags = IW_POWER_TIMEOUT; ++ range->pm_capa = 0; ++ ++ range->we_version_compiled = WIRELESS_EXT; ++ range->we_version_source = 13; ++ ++ range->retry_capa = IW_RETRY_LIMIT; ++ range->retry_flags = IW_RETRY_LIMIT; ++ range->min_retry = 0; ++ range->max_retry = 255; ++ ++ range->num_frequency = range->num_channels = ar->arNumChannels; ++ for (i = 0; i < ar->arNumChannels; i++) { ++ range->freq[i].i = wlan_freq2ieee(ar->arChannelList[i]); ++ range->freq[i].m = ar->arChannelList[i] * 100000; ++ range->freq[i].e = 1; ++ /* ++ * Linux supports max of 32 channels, bail out once you ++ * reach the max. ++ */ ++ if (i == IW_MAX_FREQUENCIES) { ++ break; ++ } ++ } ++ ++ /* Max quality is max field value minus noise floor */ ++ range->max_qual.qual = 0xff - 161; ++ ++ /* ++ * In order to use dBm measurements, 'level' must be lower ++ * than any possible measurement (see iw_print_stats() in ++ * wireless tools). It's unclear how this is meant to be ++ * done, but setting zero in these values forces dBm and ++ * the actual numbers are not used. ++ */ ++ range->max_qual.level = 0; ++ range->max_qual.noise = 0; ++ ++ range->sensitivity = 3; ++ ++ range->max_encoding_tokens = 4; ++ /* XXX query driver to find out supported key sizes */ ++ range->num_encoding_sizes = 3; ++ range->encoding_size[0] = 5; /* 40-bit */ ++ range->encoding_size[1] = 13; /* 104-bit */ ++ range->encoding_size[2] = 16; /* 128-bit */ ++ ++ range->num_bitrates = 0; ++ ++ /* estimated maximum TCP throughput values (bps) */ ++ range->throughput = 22000000; ++ ++ range->min_rts = 0; ++ range->max_rts = 2347; ++ range->min_frag = 256; ++ range->max_frag = 2346; ++ ++ up(&ar->arSem); ++ ++ return ret; ++} ++ ++ ++/* ++ * SIOCSIWAP ++ * This ioctl is used to set the desired bssid for the connect command. ++ */ ++int ++ar6000_ioctl_siwap(struct net_device *dev, ++ struct iw_request_info *info, ++ struct sockaddr *ap_addr, char *extra) ++{ ++ AR_SOFTC_T *ar = (AR_SOFTC_T *)netdev_priv(dev); ++ ++ if (ar->arWlanState == WLAN_DISABLED) { ++ return -EIO; ++ } ++ ++ if (ap_addr->sa_family != ARPHRD_ETHER) { ++ return -EIO; ++ } ++ ++ if (A_MEMCMP(&ap_addr->sa_data, bcast_mac, AR6000_ETH_ADDR_LEN) == 0) { ++ A_MEMZERO(ar->arReqBssid, sizeof(ar->arReqBssid)); ++ } else { ++ A_MEMCPY(ar->arReqBssid, &ap_addr->sa_data, sizeof(ar->arReqBssid)); ++ } ++ ++ return 0; ++} ++ ++/* ++ * SIOCGIWAP ++ */ ++int ++ar6000_ioctl_giwap(struct net_device *dev, ++ struct iw_request_info *info, ++ struct sockaddr *ap_addr, char *extra) ++{ ++ AR_SOFTC_T *ar = (AR_SOFTC_T *)netdev_priv(dev); ++ ++ if (ar->arWlanState == WLAN_DISABLED) { ++ return -EIO; ++ } ++ ++ if (ar->arConnected != TRUE) { ++ return -EINVAL; ++ } ++ ++ A_MEMCPY(&ap_addr->sa_data, ar->arBssid, sizeof(ar->arBssid)); ++ ap_addr->sa_family = ARPHRD_ETHER; ++ ++ return 0; ++} ++ ++/* ++ * SIOCGIWAPLIST ++ */ ++int ++ar6000_ioctl_iwaplist(struct net_device *dev, ++ struct iw_request_info *info, ++ struct iw_point *data, char *extra) ++{ ++ return -EIO; /* for now */ ++} ++ ++/* ++ * SIOCSIWSCAN ++ */ ++int ++ar6000_ioctl_siwscan(struct net_device *dev, ++ struct iw_request_info *info, ++ struct iw_point *data, char *extra) ++{ ++#define ACT_DWELLTIME_DEFAULT 105 ++#define HOME_TXDRAIN_TIME 100 ++#define SCAN_INT HOME_TXDRAIN_TIME + ACT_DWELLTIME_DEFAULT ++ AR_SOFTC_T *ar = (AR_SOFTC_T *)netdev_priv(dev); ++ int ret = 0; ++ ++ if (ar->arWmiReady == FALSE) { ++ return -EIO; ++ } ++ ++ if (ar->arWlanState == WLAN_DISABLED) { ++ return -EIO; ++ } ++ ++ /* We ask for everything from the target */ ++ if (wmi_bssfilter_cmd(ar->arWmi, ALL_BSS_FILTER, 0) != A_OK) { ++ printk("Couldn't set filtering\n"); ++ ret = -EIO; ++ } ++ ++ if (wmi_startscan_cmd(ar->arWmi, WMI_LONG_SCAN, FALSE, FALSE, \ ++ HOME_TXDRAIN_TIME, SCAN_INT) != A_OK) { ++ ret = -EIO; ++ } ++ ++ ar->scan_complete = 0; ++ wait_event_interruptible_timeout(ar6000_scan_queue, ar->scan_complete, ++ 5 * HZ); ++ ++ if (wmi_bssfilter_cmd(ar->arWmi, NONE_BSS_FILTER, 0) != A_OK) { ++ printk("Couldn't set filtering\n"); ++ ret = -EIO; ++ } ++ ++ return ret; ++#undef ACT_DWELLTIME_DEFAULT ++#undef HOME_TXDRAIN_TIME ++#undef SCAN_INT ++} ++ ++ ++/* ++ * Units are in db above the noise floor. That means the ++ * rssi values reported in the tx/rx descriptors in the ++ * driver are the SNR expressed in db. ++ * ++ * If you assume that the noise floor is -95, which is an ++ * excellent assumption 99.5 % of the time, then you can ++ * derive the absolute signal level (i.e. -95 + rssi). ++ * There are some other slight factors to take into account ++ * depending on whether the rssi measurement is from 11b, ++ * 11g, or 11a. These differences are at most 2db and ++ * can be documented. ++ * ++ * NB: various calculations are based on the orinoco/wavelan ++ * drivers for compatibility ++ */ ++static void ++ar6000_set_quality(struct iw_quality *iq, A_INT8 rssi) ++{ ++ if (rssi < 0) { ++ iq->qual = 0; ++ } else { ++ iq->qual = rssi; ++ } ++ ++ /* NB: max is 94 because noise is hardcoded to 161 */ ++ if (iq->qual > 94) ++ iq->qual = 94; ++ ++ iq->noise = 161; /* -95dBm */ ++ iq->level = iq->noise + iq->qual; ++ iq->updated = 7; ++} ++ ++ ++/* Structures to export the Wireless Handlers */ ++static const iw_handler ath_handlers[] = { ++ (iw_handler) NULL, /* SIOCSIWCOMMIT */ ++ (iw_handler) ar6000_ioctl_giwname, /* SIOCGIWNAME */ ++ (iw_handler) NULL, /* SIOCSIWNWID */ ++ (iw_handler) NULL, /* SIOCGIWNWID */ ++ (iw_handler) ar6000_ioctl_siwfreq, /* SIOCSIWFREQ */ ++ (iw_handler) ar6000_ioctl_giwfreq, /* SIOCGIWFREQ */ ++ (iw_handler) ar6000_ioctl_siwmode, /* SIOCSIWMODE */ ++ (iw_handler) ar6000_ioctl_giwmode, /* SIOCGIWMODE */ ++ (iw_handler) ar6000_ioctl_siwsens, /* SIOCSIWSENS */ ++ (iw_handler) ar6000_ioctl_giwsens, /* SIOCGIWSENS */ ++ (iw_handler) NULL /* not _used */, /* SIOCSIWRANGE */ ++ (iw_handler) ar6000_ioctl_giwrange, /* SIOCGIWRANGE */ ++ (iw_handler) NULL /* not used */, /* SIOCSIWPRIV */ ++ (iw_handler) NULL /* kernel code */, /* SIOCGIWPRIV */ ++ (iw_handler) NULL /* not used */, /* SIOCSIWSTATS */ ++ (iw_handler) NULL /* kernel code */, /* SIOCGIWSTATS */ ++ (iw_handler) NULL, /* SIOCSIWSPY */ ++ (iw_handler) NULL, /* SIOCGIWSPY */ ++ (iw_handler) NULL, /* SIOCSIWTHRSPY */ ++ (iw_handler) NULL, /* SIOCGIWTHRSPY */ ++ (iw_handler) ar6000_ioctl_siwap, /* SIOCSIWAP */ ++ (iw_handler) ar6000_ioctl_giwap, /* SIOCGIWAP */ ++ (iw_handler) NULL, /* -- hole -- */ ++ (iw_handler) ar6000_ioctl_iwaplist, /* SIOCGIWAPLIST */ ++ (iw_handler) ar6000_ioctl_siwscan, /* SIOCSIWSCAN */ ++ (iw_handler) ar6000_ioctl_giwscan, /* SIOCGIWSCAN */ ++ (iw_handler) ar6000_ioctl_siwessid, /* SIOCSIWESSID */ ++ (iw_handler) ar6000_ioctl_giwessid, /* SIOCGIWESSID */ ++ (iw_handler) NULL, /* SIOCSIWNICKN */ ++ (iw_handler) NULL, /* SIOCGIWNICKN */ ++ (iw_handler) NULL, /* -- hole -- */ ++ (iw_handler) NULL, /* -- hole -- */ ++ (iw_handler) ar6000_ioctl_siwrate, /* SIOCSIWRATE */ ++ (iw_handler) ar6000_ioctl_giwrate, /* SIOCGIWRATE */ ++ (iw_handler) NULL, /* SIOCSIWRTS */ ++ (iw_handler) NULL, /* SIOCGIWRTS */ ++ (iw_handler) NULL, /* SIOCSIWFRAG */ ++ (iw_handler) NULL, /* SIOCGIWFRAG */ ++ (iw_handler) ar6000_ioctl_siwtxpow, /* SIOCSIWTXPOW */ ++ (iw_handler) ar6000_ioctl_giwtxpow, /* SIOCGIWTXPOW */ ++ (iw_handler) ar6000_ioctl_siwretry, /* SIOCSIWRETRY */ ++ (iw_handler) ar6000_ioctl_giwretry, /* SIOCGIWRETRY */ ++ (iw_handler) ar6000_ioctl_siwencode, /* SIOCSIWENCODE */ ++ (iw_handler) ar6000_ioctl_giwencode, /* SIOCGIWENCODE */ ++ (iw_handler) ar6000_ioctl_siwpower, /* SIOCSIWPOWER */ ++ (iw_handler) ar6000_ioctl_giwpower, /* SIOCGIWPOWER */ ++ (iw_handler) NULL, /* -- hole -- */ ++ (iw_handler) NULL, /* -- hole -- */ ++ (iw_handler) ar6000_ioctl_siwgenie, /* SIOCSIWGENIE */ ++ (iw_handler) ar6000_ioctl_giwgenie, /* SIOCGIWGENIE */ ++ (iw_handler) ar6000_ioctl_siwauth, /* SIOCSIWAUTH */ ++ (iw_handler) ar6000_ioctl_giwauth, /* SIOCGIWAUTH */ ++ (iw_handler) ar6000_ioctl_siwencodeext,/* SIOCSIWENCODEEXT */ ++ (iw_handler) ar6000_ioctl_giwencodeext,/* SIOCGIWENCODEEXT */ ++ (iw_handler) NULL, /* SIOCSIWPMKSA */ ++}; ++ ++static const iw_handler ath_priv_handlers[] = { ++ (iw_handler) ar6000_ioctl_setparam, /* SIOCWFIRSTPRIV+0 */ ++ (iw_handler) ar6000_ioctl_getparam, /* SIOCWFIRSTPRIV+1 */ ++ (iw_handler) ar6000_ioctl_setkey, /* SIOCWFIRSTPRIV+2 */ ++ (iw_handler) ar6000_ioctl_setwmmparams, /* SIOCWFIRSTPRIV+3 */ ++ (iw_handler) ar6000_ioctl_delkey, /* SIOCWFIRSTPRIV+4 */ ++ (iw_handler) ar6000_ioctl_getwmmparams, /* SIOCWFIRSTPRIV+5 */ ++ (iw_handler) ar6000_ioctl_setoptie, /* SIOCWFIRSTPRIV+6 */ ++ (iw_handler) ar6000_ioctl_setmlme, /* SIOCWFIRSTPRIV+7 */ ++ (iw_handler) ar6000_ioctl_addpmkid, /* SIOCWFIRSTPRIV+8 */ ++}; ++ ++#define IW_PRIV_TYPE_KEY \ ++ (IW_PRIV_TYPE_BYTE | sizeof(struct ieee80211req_key)) ++#define IW_PRIV_TYPE_DELKEY \ ++ (IW_PRIV_TYPE_BYTE | sizeof(struct ieee80211req_del_key)) ++#define IW_PRIV_TYPE_MLME \ ++ (IW_PRIV_TYPE_BYTE | sizeof(struct ieee80211req_mlme)) ++#define IW_PRIV_TYPE_ADDPMKID \ ++ (IW_PRIV_TYPE_BYTE | sizeof(struct ieee80211req_addpmkid)) ++ ++static const struct iw_priv_args ar6000_priv_args[] = { ++ { IEEE80211_IOCTL_SETKEY, ++ IW_PRIV_TYPE_KEY | IW_PRIV_SIZE_FIXED, 0, "setkey"}, ++ { IEEE80211_IOCTL_DELKEY, ++ IW_PRIV_TYPE_DELKEY | IW_PRIV_SIZE_FIXED, 0, "delkey"}, ++ { IEEE80211_IOCTL_SETPARAM, ++ IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 2, 0, "setparam"}, ++ { IEEE80211_IOCTL_GETPARAM, ++ IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, ++ IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, "getparam"}, ++ { IEEE80211_IOCTL_SETWMMPARAMS, ++ IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 4, 0, "setwmmparams"}, ++ { IEEE80211_IOCTL_GETWMMPARAMS, ++ IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 3, ++ IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, "getwmmparams"}, ++ { IEEE80211_IOCTL_SETOPTIE, ++ IW_PRIV_TYPE_BYTE, 0, "setie"}, ++ { IEEE80211_IOCTL_SETMLME, ++ IW_PRIV_TYPE_MLME, 0, "setmlme"}, ++ { IEEE80211_IOCTL_ADDPMKID, ++ IW_PRIV_TYPE_ADDPMKID | IW_PRIV_SIZE_FIXED, 0, "addpmkid"}, ++}; ++ ++void ar6000_ioctl_iwsetup(struct iw_handler_def *def) ++{ ++ def->private_args = (struct iw_priv_args *)ar6000_priv_args; ++ def->num_private_args = ARRAY_SIZE(ar6000_priv_args); ++} ++ ++struct iw_handler_def ath_iw_handler_def = { ++ .standard = (iw_handler *)ath_handlers, ++ .num_standard = ARRAY_SIZE(ath_handlers), ++ .private = (iw_handler *)ath_priv_handlers, ++ .num_private = ARRAY_SIZE(ath_priv_handlers), ++}; ++ ++ +diff -ruN --exclude='*.orig' --exclude='*.rej' linux-2.6.29-rc3.owrt/drivers/ar6000/bmi/bmi.c linux-2.6.29-rc3.owrt.om/drivers/ar6000/bmi/bmi.c +--- linux-2.6.29-rc3.owrt/drivers/ar6000/bmi/bmi.c 1970-01-01 01:00:00.000000000 +0100 ++++ linux-2.6.29-rc3.owrt.om/drivers/ar6000/bmi/bmi.c 2009-05-10 22:27:59.000000000 +0200 +@@ -0,0 +1,657 @@ ++/* ++ * Copyright (c) 2004-2007 Atheros Communications Inc. ++ * All rights reserved. ++ * ++ * ++ * 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; ++ * ++ * Software distributed under the License is distributed on an "AS ++ * IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or ++ * implied. See the License for the specific language governing ++ * rights and limitations under the License. ++ * ++ * ++ * ++ */ ++ ++#include "hif.h" ++#include "bmi.h" ++#include "htc_api.h" ++#include "bmi_internal.h" ++ ++/* ++Although we had envisioned BMI to run on top of HTC, this is not what the ++final implementation boiled down to on dragon. Its a part of BSP and does ++not use the HTC protocol either. On the host side, however, we were still ++living with the original idea. I think the time has come to accept the truth ++and separate it from HTC which has been carrying BMI's burden all this while. ++It shall make HTC state machine relatively simpler ++*/ ++ ++/* APIs visible to the driver */ ++void ++BMIInit(void) ++{ ++ bmiDone = FALSE; ++} ++ ++A_STATUS ++BMIDone(HIF_DEVICE *device) ++{ ++ A_STATUS status; ++ A_UINT32 cid; ++ ++ if (bmiDone) { ++ AR_DEBUG_PRINTF (ATH_DEBUG_BMI, ("BMIDone skipped\n")); ++ return A_OK; ++ } ++ ++ AR_DEBUG_PRINTF(ATH_DEBUG_BMI, ("BMI Done: Enter (device: 0x%p)\n", device)); ++ bmiDone = TRUE; ++ cid = BMI_DONE; ++ ++ status = bmiBufferSend(device, (A_UCHAR *)&cid, sizeof(cid)); ++ if (status != A_OK) { ++ AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("Unable to write to the device\n")); ++ return A_ERROR; ++ } ++ AR_DEBUG_PRINTF(ATH_DEBUG_BMI, ("BMI Done: Exit\n")); ++ ++ return A_OK; ++} ++ ++A_STATUS ++BMIGetTargetInfo(HIF_DEVICE *device, struct bmi_target_info *targ_info) ++{ ++ A_STATUS status; ++ A_UINT32 cid; ++ ++ if (bmiDone) { ++ AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("Command disallowed\n")); ++ return A_ERROR; ++ } ++ ++ AR_DEBUG_PRINTF(ATH_DEBUG_BMI, ("BMI Get Target Info: Enter (device: 0x%p)\n", device)); ++ cid = BMI_GET_TARGET_INFO; ++ ++ status = bmiBufferSend(device, (A_UCHAR *)&cid, sizeof(cid)); ++ if (status != A_OK) { ++ AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("Unable to write to the device\n")); ++ return A_ERROR; ++ } ++ ++ status = bmiBufferReceive(device, (A_UCHAR *)&targ_info->target_ver, ++ sizeof(targ_info->target_ver)); ++ if (status != A_OK) { ++ AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("Unable to read Target Version from the device\n")); ++ return A_ERROR; ++ } ++ ++ if (targ_info->target_ver == TARGET_VERSION_SENTINAL) { ++ /* Determine how many bytes are in the Target's targ_info */ ++ status = bmiBufferReceive(device, (A_UCHAR *)&targ_info->target_info_byte_count, ++ sizeof(targ_info->target_info_byte_count)); ++ if (status != A_OK) { ++ AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("Unable to read Target Info Byte Count from the device\n")); ++ return A_ERROR; ++ } ++ ++ /* ++ * The Target's targ_info doesn't match the Host's targ_info. ++ * We need to do some backwards compatibility work to make this OK. ++ */ ++ A_ASSERT(targ_info->target_info_byte_count == sizeof(*targ_info)); ++ ++ /* Read the remainder of the targ_info */ ++ status = bmiBufferReceive(device, ++ ((A_UCHAR *)targ_info)+sizeof(targ_info->target_info_byte_count), ++ sizeof(*targ_info)-sizeof(targ_info->target_info_byte_count)); ++ if (status != A_OK) { ++ AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("Unable to read Target Info (%d bytes) from the device\n", ++ targ_info->target_info_byte_count)); ++ return A_ERROR; ++ } ++ } else { ++ /* ++ * Target must be an AR6001 whose firmware does not ++ * support BMI_GET_TARGET_INFO. Construct the data ++ * that it would have sent. ++ */ ++ targ_info->target_info_byte_count = sizeof(targ_info); ++ targ_info->target_type = TARGET_TYPE_AR6001; ++ } ++ ++ AR_DEBUG_PRINTF(ATH_DEBUG_BMI, ("BMI Get Target Info: Exit (ver: 0x%x type: 0x%x)\n", ++ targ_info->target_ver, targ_info->target_type)); ++ printk("BMI Get Target Info: Exit (ver: 0x%x type: 0x%x)\n", ++ targ_info->target_ver, targ_info->target_type); ++ ++ return A_OK; ++} ++ ++A_STATUS ++BMIReadMemory(HIF_DEVICE *device, ++ A_UINT32 address, ++ A_UCHAR *buffer, ++ A_UINT32 length) ++{ ++ A_UINT32 cid; ++ A_STATUS status; ++ A_UINT32 offset; ++ A_UINT32 remaining, rxlen; ++ static A_UCHAR data[BMI_DATASZ_MAX + sizeof(cid) + sizeof(address) + sizeof(length)]; ++ memset (&data, 0, BMI_DATASZ_MAX + sizeof(cid) + sizeof(address) + sizeof(length)); ++ ++ if (bmiDone) { ++ AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("Command disallowed\n")); ++ return A_ERROR; ++ } ++ ++ AR_DEBUG_PRINTF(ATH_DEBUG_BMI, ++ ("BMI Read Memory: Enter (device: 0x%p, address: 0x%x, length: %d)\n", ++ device, address, length)); ++ ++ cid = BMI_READ_MEMORY; ++ ++ remaining = length; ++ ++ while (remaining) ++ { ++ rxlen = (remaining < BMI_DATASZ_MAX) ? remaining : BMI_DATASZ_MAX; ++ offset = 0; ++ A_MEMCPY(&data[offset], &cid, sizeof(cid)); ++ offset += sizeof(cid); ++ A_MEMCPY(&data[offset], &address, sizeof(address)); ++ offset += sizeof(address); ++ A_MEMCPY(&data[offset], &rxlen, sizeof(rxlen)); ++ offset += sizeof(length); ++ ++ status = bmiBufferSend(device, data, offset); ++ if (status != A_OK) { ++ AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("Unable to write to the device\n")); ++ return A_ERROR; ++ } ++ status = bmiBufferReceive(device, data, rxlen); ++ if (status != A_OK) { ++ AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("Unable to read from the device\n")); ++ return A_ERROR; ++ } ++ A_MEMCPY(&buffer[length - remaining], data, rxlen); ++ remaining -= rxlen; address += rxlen; ++ } ++ ++ AR_DEBUG_PRINTF(ATH_DEBUG_BMI, ("BMI Read Memory: Exit\n")); ++ return A_OK; ++} ++ ++A_STATUS ++BMIWriteMemory(HIF_DEVICE *device, ++ A_UINT32 address, ++ A_UCHAR *buffer, ++ A_UINT32 length) ++{ ++ A_UINT32 cid; ++ A_STATUS status; ++ A_UINT32 offset; ++ A_UINT32 remaining, txlen; ++ const A_UINT32 header = sizeof(cid) + sizeof(address) + sizeof(length); ++ static A_UCHAR data[BMI_DATASZ_MAX + sizeof(cid) + sizeof(address) + sizeof(length)]; ++ memset (&data, 0, header); ++ ++ if (bmiDone) { ++ AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("Command disallowed\n")); ++ return A_ERROR; ++ } ++ ++ AR_DEBUG_PRINTF(ATH_DEBUG_BMI, ++ ("BMI Write Memory: Enter (device: 0x%p, address: 0x%x, length: %d)\n", ++ device, address, length)); ++ ++ cid = BMI_WRITE_MEMORY; ++ ++ remaining = length; ++ while (remaining) ++ { ++ txlen = (remaining < (BMI_DATASZ_MAX - header)) ? ++ remaining : (BMI_DATASZ_MAX - header); ++ offset = 0; ++ A_MEMCPY(&data[offset], &cid, sizeof(cid)); ++ offset += sizeof(cid); ++ A_MEMCPY(&data[offset], &address, sizeof(address)); ++ offset += sizeof(address); ++ A_MEMCPY(&data[offset], &txlen, sizeof(txlen)); ++ offset += sizeof(txlen); ++ A_MEMCPY(&data[offset], &buffer[length - remaining], txlen); ++ offset += txlen; ++ status = bmiBufferSend(device, data, offset); ++ if (status != A_OK) { ++ AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("Unable to write to the device\n")); ++ return A_ERROR; ++ } ++ remaining -= txlen; address += txlen; ++ } ++ ++ AR_DEBUG_PRINTF(ATH_DEBUG_BMI, ("BMI Write Memory: Exit\n")); ++ ++ return A_OK; ++} ++ ++A_STATUS ++BMIExecute(HIF_DEVICE *device, ++ A_UINT32 address, ++ A_UINT32 *param) ++{ ++ A_UINT32 cid; ++ A_STATUS status; ++ A_UINT32 offset; ++ static A_UCHAR data[sizeof(cid) + sizeof(address) + sizeof(*param)]; ++ memset (&data, 0, sizeof(cid) + sizeof(address) + sizeof(*param)); ++ ++ if (bmiDone) { ++ AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("Command disallowed\n")); ++ return A_ERROR; ++ } ++ ++ AR_DEBUG_PRINTF(ATH_DEBUG_BMI, ++ ("BMI Execute: Enter (device: 0x%p, address: 0x%x, param: %d)\n", ++ device, address, *param)); ++ ++ cid = BMI_EXECUTE; ++ ++ offset = 0; ++ A_MEMCPY(&data[offset], &cid, sizeof(cid)); ++ offset += sizeof(cid); ++ A_MEMCPY(&data[offset], &address, sizeof(address)); ++ offset += sizeof(address); ++ A_MEMCPY(&data[offset], param, sizeof(*param)); ++ offset += sizeof(*param); ++ status = bmiBufferSend(device, data, offset); ++ if (status != A_OK) { ++ AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("Unable to write to the device\n")); ++ return A_ERROR; ++ } ++ ++ status = bmiBufferReceive(device, data, sizeof(*param)); ++ if (status != A_OK) { ++ AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("Unable to read from the device\n")); ++ return A_ERROR; ++ } ++ ++ A_MEMCPY(param, data, sizeof(*param)); ++ ++ AR_DEBUG_PRINTF(ATH_DEBUG_BMI, ("BMI Execute: Exit (param: %d)\n", *param)); ++ return A_OK; ++} ++ ++A_STATUS ++BMISetAppStart(HIF_DEVICE *device, ++ A_UINT32 address) ++{ ++ A_UINT32 cid; ++ A_STATUS status; ++ A_UINT32 offset; ++ static A_UCHAR data[sizeof(cid) + sizeof(address)]; ++ memset (&data, 0, sizeof(cid) + sizeof(address)); ++ ++ if (bmiDone) { ++ AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("Command disallowed\n")); ++ return A_ERROR; ++ } ++ ++ AR_DEBUG_PRINTF(ATH_DEBUG_BMI, ++ ("BMI Set App Start: Enter (device: 0x%p, address: 0x%x)\n", ++ device, address)); ++ ++ cid = BMI_SET_APP_START; ++ ++ offset = 0; ++ A_MEMCPY(&data[offset], &cid, sizeof(cid)); ++ offset += sizeof(cid); ++ A_MEMCPY(&data[offset], &address, sizeof(address)); ++ offset += sizeof(address); ++ status = bmiBufferSend(device, data, offset); ++ if (status != A_OK) { ++ AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("Unable to write to the device\n")); ++ return A_ERROR; ++ } ++ ++ AR_DEBUG_PRINTF(ATH_DEBUG_BMI, ("BMI Set App Start: Exit\n")); ++ return A_OK; ++} ++ ++A_STATUS ++BMIReadSOCRegister(HIF_DEVICE *device, ++ A_UINT32 address, ++ A_UINT32 *param) ++{ ++ A_UINT32 cid; ++ A_STATUS status; ++ A_UINT32 offset; ++ static A_UCHAR data[sizeof(cid) + sizeof(address)]; ++ memset (&data, 0, sizeof(cid) + sizeof(address)); ++ ++ if (bmiDone) { ++ AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("Command disallowed\n")); ++ return A_ERROR; ++ } ++ ++ AR_DEBUG_PRINTF(ATH_DEBUG_BMI, ++ ("BMI Read SOC Register: Enter (device: 0x%p, address: 0x%x)\n", ++ device, address)); ++ ++ cid = BMI_READ_SOC_REGISTER; ++ ++ offset = 0; ++ A_MEMCPY(&data[offset], &cid, sizeof(cid)); ++ offset += sizeof(cid); ++ A_MEMCPY(&data[offset], &address, sizeof(address)); ++ offset += sizeof(address); ++ ++ status = bmiBufferSend(device, data, offset); ++ if (status != A_OK) { ++ AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("Unable to write to the device\n")); ++ return A_ERROR; ++ } ++ ++ status = bmiBufferReceive(device, data, sizeof(*param)); ++ if (status != A_OK) { ++ AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("Unable to read from the device\n")); ++ return A_ERROR; ++ } ++ A_MEMCPY(param, data, sizeof(*param)); ++ ++ AR_DEBUG_PRINTF(ATH_DEBUG_BMI, ("BMI Read SOC Register: Exit (value: %d)\n", *param)); ++ return A_OK; ++} ++ ++A_STATUS ++BMIWriteSOCRegister(HIF_DEVICE *device, ++ A_UINT32 address, ++ A_UINT32 param) ++{ ++ A_UINT32 cid; ++ A_STATUS status; ++ A_UINT32 offset; ++ static A_UCHAR data[sizeof(cid) + sizeof(address) + sizeof(param)]; ++ ++ memset (&data, 0, sizeof(cid) + sizeof(address) + sizeof(param)); ++ ++ if (bmiDone) { ++ AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("Command disallowed\n")); ++ return A_ERROR; ++ } ++ ++ AR_DEBUG_PRINTF(ATH_DEBUG_BMI, ++ ("BMI Write SOC Register: Enter (device: 0x%p, address: 0x%x, param: %d)\n", ++ device, address, param)); ++ ++ cid = BMI_WRITE_SOC_REGISTER; ++ ++ offset = 0; ++ A_MEMCPY(&data[offset], &cid, sizeof(cid)); ++ offset += sizeof(cid); ++ A_MEMCPY(&data[offset], &address, sizeof(address)); ++ offset += sizeof(address); ++ A_MEMCPY(&data[offset], ¶m, sizeof(param)); ++ offset += sizeof(param); ++ status = bmiBufferSend(device, data, offset); ++ if (status != A_OK) { ++ AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("Unable to write to the device\n")); ++ return A_ERROR; ++ } ++ ++ AR_DEBUG_PRINTF(ATH_DEBUG_BMI, ("BMI Read SOC Register: Exit\n")); ++ return A_OK; ++} ++ ++A_STATUS ++BMIrompatchInstall(HIF_DEVICE *device, ++ A_UINT32 ROM_addr, ++ A_UINT32 RAM_addr, ++ A_UINT32 nbytes, ++ A_UINT32 do_activate, ++ A_UINT32 *rompatch_id) ++{ ++ A_UINT32 cid; ++ A_STATUS status; ++ A_UINT32 offset; ++ static A_UCHAR data[sizeof(cid) + sizeof(ROM_addr) + sizeof(RAM_addr) + ++ sizeof(nbytes) + sizeof(do_activate)]; ++ ++ memset (&data, 0, sizeof(cid) + sizeof(ROM_addr) + sizeof(RAM_addr) + ++ sizeof(nbytes) + sizeof(do_activate)); ++ ++ if (bmiDone) { ++ AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("Command disallowed\n")); ++ return A_ERROR; ++ } ++ ++ AR_DEBUG_PRINTF(ATH_DEBUG_BMI, ++ ("BMI rompatch Install: Enter (device: 0x%p, ROMaddr: 0x%x, RAMaddr: 0x%x length: %d activate: %d)\n", ++ device, ROM_addr, RAM_addr, nbytes, do_activate)); ++ ++ cid = BMI_ROMPATCH_INSTALL; ++ ++ offset = 0; ++ A_MEMCPY(&data[offset], &cid, sizeof(cid)); ++ offset += sizeof(cid); ++ A_MEMCPY(&data[offset], &ROM_addr, sizeof(ROM_addr)); ++ offset += sizeof(ROM_addr); ++ A_MEMCPY(&data[offset], &RAM_addr, sizeof(RAM_addr)); ++ offset += sizeof(RAM_addr); ++ A_MEMCPY(&data[offset], &nbytes, sizeof(nbytes)); ++ offset += sizeof(nbytes); ++ A_MEMCPY(&data[offset], &do_activate, sizeof(do_activate)); ++ offset += sizeof(do_activate); ++ status = bmiBufferSend(device, data, offset); ++ if (status != A_OK) { ++ AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("Unable to write to the device\n")); ++ return A_ERROR; ++ } ++ ++ status = bmiBufferReceive(device, (A_UCHAR *)rompatch_id, sizeof(*rompatch_id)); ++ if (status != A_OK) { ++ AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("Unable to read from the device\n")); ++ return A_ERROR; ++ } ++ ++ AR_DEBUG_PRINTF(ATH_DEBUG_BMI, ("BMI rompatch Install: (rompatch_id=%d)\n", *rompatch_id)); ++ return A_OK; ++} ++ ++A_STATUS ++BMIrompatchUninstall(HIF_DEVICE *device, ++ A_UINT32 rompatch_id) ++{ ++ A_UINT32 cid; ++ A_STATUS status; ++ A_UINT32 offset; ++ static A_UCHAR data[sizeof(cid) + sizeof(rompatch_id)]; ++ memset (&data, 0, sizeof(cid) + sizeof(rompatch_id)); ++ ++ if (bmiDone) { ++ AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("Command disallowed\n")); ++ return A_ERROR; ++ } ++ ++ AR_DEBUG_PRINTF(ATH_DEBUG_BMI, ++ ("BMI rompatch Uninstall: Enter (device: 0x%p, rompatch_id: %d)\n", ++ device, rompatch_id)); ++ ++ cid = BMI_ROMPATCH_UNINSTALL; ++ ++ offset = 0; ++ A_MEMCPY(&data[offset], &cid, sizeof(cid)); ++ offset += sizeof(cid); ++ A_MEMCPY(&data[offset], &rompatch_id, sizeof(rompatch_id)); ++ offset += sizeof(rompatch_id); ++ status = bmiBufferSend(device, data, offset); ++ if (status != A_OK) { ++ AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("Unable to write to the device\n")); ++ return A_ERROR; ++ } ++ ++ AR_DEBUG_PRINTF(ATH_DEBUG_BMI, ("BMI rompatch UNinstall: (rompatch_id=0x%x)\n", rompatch_id)); ++ return A_OK; ++} ++ ++static A_STATUS ++_BMIrompatchChangeActivation(HIF_DEVICE *device, ++ A_UINT32 rompatch_count, ++ A_UINT32 *rompatch_list, ++ A_UINT32 do_activate) ++{ ++ A_UINT32 cid; ++ A_STATUS status; ++ A_UINT32 offset; ++ static A_UCHAR data[BMI_DATASZ_MAX + sizeof(cid) + sizeof(rompatch_count)]; ++ A_UINT32 length; ++ ++ memset (&data, 0, BMI_DATASZ_MAX + sizeof(cid) + sizeof(rompatch_count)); ++ ++ if (bmiDone) { ++ AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("Command disallowed\n")); ++ return A_ERROR; ++ } ++ ++ AR_DEBUG_PRINTF(ATH_DEBUG_BMI, ++ ("BMI Change rompatch Activation: Enter (device: 0x%p, count: %d)\n", ++ device, rompatch_count)); ++ ++ cid = do_activate ? BMI_ROMPATCH_ACTIVATE : BMI_ROMPATCH_DEACTIVATE; ++ ++ offset = 0; ++ A_MEMCPY(&data[offset], &cid, sizeof(cid)); ++ offset += sizeof(cid); ++ A_MEMCPY(&data[offset], &rompatch_count, sizeof(rompatch_count)); ++ offset += sizeof(rompatch_count); ++ length = rompatch_count * sizeof(*rompatch_list); ++ A_MEMCPY(&data[offset], rompatch_list, length); ++ offset += length; ++ status = bmiBufferSend(device, data, offset); ++ if (status != A_OK) { ++ AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("Unable to write to the device\n")); ++ return A_ERROR; ++ } ++ ++ AR_DEBUG_PRINTF(ATH_DEBUG_BMI, ("BMI Change rompatch Activation: Exit\n")); ++ ++ return A_OK; ++} ++ ++A_STATUS ++BMIrompatchActivate(HIF_DEVICE *device, ++ A_UINT32 rompatch_count, ++ A_UINT32 *rompatch_list) ++{ ++ return _BMIrompatchChangeActivation(device, rompatch_count, rompatch_list, 1); ++} ++ ++A_STATUS ++BMIrompatchDeactivate(HIF_DEVICE *device, ++ A_UINT32 rompatch_count, ++ A_UINT32 *rompatch_list) ++{ ++ return _BMIrompatchChangeActivation(device, rompatch_count, rompatch_list, 0); ++} ++ ++/* BMI Access routines */ ++A_STATUS ++bmiBufferSend(HIF_DEVICE *device, ++ A_UCHAR *buffer, ++ A_UINT32 length) ++{ ++ A_STATUS status; ++ A_UINT32 timeout; ++ A_UINT32 address; ++ static A_UINT32 cmdCredits; ++ A_UINT32 mboxAddress[HTC_MAILBOX_NUM_MAX]; ++ ++ HIFConfigureDevice(device, HIF_DEVICE_GET_MBOX_ADDR, ++ &mboxAddress, sizeof(mboxAddress)); ++ ++ cmdCredits = 0; ++ timeout = BMI_COMMUNICATION_TIMEOUT; ++ ++ while(timeout-- && !cmdCredits) { ++ /* Read the counter register to get the command credits */ ++ address = COUNT_DEC_ADDRESS + (HTC_MAILBOX_NUM_MAX + ENDPOINT1) * 4; ++ /* hit the credit counter with a 4-byte access, the first byte read will hit the counter and cause ++ * a decrement, while the remaining 3 bytes has no effect. The rationale behind this is to ++ * make all HIF accesses 4-byte aligned */ ++ status = HIFReadWrite(device, address, (A_UINT8 *)&cmdCredits, 4, ++ HIF_RD_SYNC_BYTE_INC, NULL); ++ if (status != A_OK) { ++ AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("Unable to decrement the command credit count register\n")); ++ return A_ERROR; ++ } ++ /* the counter is only 8=bits, ignore anything in the upper 3 bytes */ ++ cmdCredits &= 0xFF; ++ } ++ ++ if (cmdCredits) { ++ address = mboxAddress[ENDPOINT1]; ++ status = HIFReadWrite(device, address, buffer, length, ++ HIF_WR_SYNC_BYTE_INC, NULL); ++ if (status != A_OK) { ++ AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("Unable to send the BMI data to the device\n")); ++ return A_ERROR; ++ } ++ } else { ++ AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("BMI Communication timeout\n")); ++ return A_ERROR; ++ } ++ ++ return status; ++} ++ ++A_STATUS ++bmiBufferReceive(HIF_DEVICE *device, ++ A_UCHAR *buffer, ++ A_UINT32 length) ++{ ++ A_STATUS status; ++ A_UINT32 address; ++ A_UINT32 timeout; ++ static A_UINT32 cmdCredits; ++ A_UINT32 mboxAddress[HTC_MAILBOX_NUM_MAX]; ++ ++ HIFConfigureDevice(device, HIF_DEVICE_GET_MBOX_ADDR, ++ &mboxAddress, sizeof(mboxAddress)); ++ ++ cmdCredits = 0; ++ timeout = BMI_COMMUNICATION_TIMEOUT; ++ while(timeout-- && !cmdCredits) { ++ /* Read the counter register to get the command credits */ ++ address = COUNT_ADDRESS + (HTC_MAILBOX_NUM_MAX + ENDPOINT1) * 1; ++ /* read the counter using a 4-byte read. Since the counter is NOT auto-decrementing, ++ * we can read this counter multiple times using a non-incrementing address mode. ++ * The rationale here is to make all HIF accesses a multiple of 4 bytes */ ++ status = HIFReadWrite(device, address, (A_UINT8 *)&cmdCredits, sizeof(cmdCredits), ++ HIF_RD_SYNC_BYTE_FIX, NULL); ++ if (status != A_OK) { ++ AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("Unable to read the command credit count register\n")); ++ return A_ERROR; ++ } ++ /* we did a 4-byte read to the same count register so mask off upper bytes */ ++ cmdCredits &= 0xFF; ++ status = A_ERROR; ++ } ++ ++ if (cmdCredits) { ++ address = mboxAddress[ENDPOINT1]; ++ status = HIFReadWrite(device, address, buffer, length, ++ HIF_RD_SYNC_BYTE_INC, NULL); ++ if (status != A_OK) { ++ AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("Unable to read the BMI data from the device\n")); ++ return A_ERROR; ++ } ++ } else { ++ AR_DEBUG_PRINTF(ATH_DEBUG_BMI, ("BMI Communication timeout\n")); ++ return A_ERROR; ++ } ++ ++ return status; ++} +diff -ruN --exclude='*.orig' --exclude='*.rej' linux-2.6.29-rc3.owrt/drivers/ar6000/bmi/bmi_internal.h linux-2.6.29-rc3.owrt.om/drivers/ar6000/bmi/bmi_internal.h +--- linux-2.6.29-rc3.owrt/drivers/ar6000/bmi/bmi_internal.h 1970-01-01 01:00:00.000000000 +0100 ++++ linux-2.6.29-rc3.owrt.om/drivers/ar6000/bmi/bmi_internal.h 2009-05-10 22:27:59.000000000 +0200 +@@ -0,0 +1,45 @@ ++#ifndef BMI_INTERNAL_H ++#define BMI_INTERNAL_H ++/* ++ * ++ * Copyright (c) 2004-2007 Atheros Communications Inc. ++ * All rights reserved. ++ * ++ * ++ * 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; ++ * ++ * Software distributed under the License is distributed on an "AS ++ * IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or ++ * implied. See the License for the specific language governing ++ * rights and limitations under the License. ++ * ++ * ++ * ++ */ ++ ++#include "a_config.h" ++#include "athdefs.h" ++#include "a_types.h" ++#include "a_osapi.h" ++#include "a_debug.h" ++#include "AR6Khwreg.h" ++#include "bmi_msg.h" ++ ++#define BMI_COMMUNICATION_TIMEOUT 100000 ++ ++/* ------ Global Variable Declarations ------- */ ++A_BOOL bmiDone; ++ ++A_STATUS ++bmiBufferSend(HIF_DEVICE *device, ++ A_UCHAR *buffer, ++ A_UINT32 length); ++ ++A_STATUS ++bmiBufferReceive(HIF_DEVICE *device, ++ A_UCHAR *buffer, ++ A_UINT32 length); ++ ++#endif +diff -ruN --exclude='*.orig' --exclude='*.rej' linux-2.6.29-rc3.owrt/drivers/ar6000/hif/hif2.c linux-2.6.29-rc3.owrt.om/drivers/ar6000/hif/hif2.c +--- linux-2.6.29-rc3.owrt/drivers/ar6000/hif/hif2.c 1970-01-01 01:00:00.000000000 +0100 ++++ linux-2.6.29-rc3.owrt.om/drivers/ar6000/hif/hif2.c 2009-05-10 22:27:59.000000000 +0200 +@@ -0,0 +1,768 @@ ++/* ++ * hif2.c - HIF layer re-implementation for the Linux SDIO stack ++ * ++ * Copyright (C) 2008, 2009 by OpenMoko, Inc. ++ * Written by Werner Almesberger <werner@openmoko.org> ++ * All Rights Reserved ++ * ++ * 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; ++ * ++ * Based on: ++ * ++ * @abstract: HIF layer reference implementation for Atheros SDIO stack ++ * @notice: Copyright (c) 2004-2006 Atheros Communications Inc. ++ */ ++ ++ ++#include <linux/kernel.h> ++#include <linux/kthread.h> ++#include <linux/list.h> ++#include <linux/wait.h> ++#include <linux/spinlock.h> ++#include <linux/mutex.h> ++#include <linux/sched.h> ++#include <linux/mmc/sdio_func.h> ++#include <linux/mmc/sdio.h> ++#include <linux/mmc/sdio_ids.h> ++ ++#include "athdefs.h" ++#include "a_types.h" ++#include "hif.h" ++ ++ ++/* @@@ Hack - this wants cleaning up */ ++ ++#ifdef CONFIG_MACH_NEO1973_GTA02 ++ ++#include <mach/gta02-pm-wlan.h> ++ ++#else /* CONFIG_MACH_NEO1973_GTA02 */ ++ ++#define gta02_wlan_query_rfkill_lock() 1 ++#define gta02_wlan_set_rfkill_cb(cb, hif) ((void) cb) ++#define gta02_wlan_query_rfkill_unlock() ++#define gta02_wlan_clear_rfkill_cb() ++ ++#endif /* !CONFIG_MACH_NEO1973_GTA02 */ ++ ++ ++/* ++ * KNOWN BUGS: ++ * ++ * - HIF_DEVICE_IRQ_ASYNC_SYNC doesn't work yet (gets MMC errors) ++ * - latency can reach hundreds of ms, probably because of scheduling delays ++ * - packets go through about three queues before finally hitting the network ++ */ ++ ++/* ++ * Differences from Atheros' HIFs: ++ * ++ * - synchronous and asynchronous requests may get reordered with respect to ++ * each other, e.g., if HIFReadWrite returns for an asynchronous request and ++ * then HIFReadWrite is called for a synchronous request, the synchronous ++ * request may be executed before the asynchronous request. ++ * ++ * - request queue locking seems unnecessarily complex in the Atheros HIFs. ++ * ++ * - Atheros mask interrupts by calling sdio_claim_irq/sdio_release_irq, which ++ * can cause quite a bit of overhead. This HIF has its own light-weight ++ * interrupt masking. ++ * ++ * - Atheros call deviceInsertedHandler from a thread spawned off the probe or ++ * device insertion function. The original explanation for the Atheros SDIO ++ * stack said that this is done because a delay is needed to let the chip ++ * complete initialization. There is indeed a one second delay in the thread. ++ * ++ * The Atheros Linux SDIO HIF removes the delay and only retains the thread. ++ * Experimentally removing the thread didn't show any conflicts, so let's get ++ * rid of it for good. ++ * ++ * - The Atheros SDIO stack with Samuel's driver sets SDIO_CCCR_POWER in ++ * SDIO_POWER_EMPC. Atheros' Linux SDIO code apparently doesn't. We don't ++ * either, and this seems to work fine. ++ * @@@ Need to check this with Atheros. ++ */ ++ ++ ++#define MBOXES 4 ++ ++#define HIF_MBOX_BLOCK_SIZE 128 ++#define HIF_MBOX_BASE_ADDR 0x800 ++#define HIF_MBOX_WIDTH 0x800 ++#define HIF_MBOX_START_ADDR(mbox) \ ++ (HIF_MBOX_BASE_ADDR+(mbox)*HIF_MBOX_WIDTH) ++ ++ ++struct hif_device { ++ void *htc_handle; ++ struct sdio_func *func; ++ ++ /* ++ * @@@ our sweet little bit of bogosity - the mechanism that lets us ++ * use the SDIO stack from softirqs. This really wants to use skbs. ++ */ ++ struct list_head queue; ++ spinlock_t queue_lock; ++ struct task_struct *io_task; ++ wait_queue_head_t wait; ++ ++ /* ++ * activate_lock protects "active" and the activation/deactivation ++ * process itself. ++ * ++ * Relation to other locks: The SDIO function can be claimed while ++ * activate_lock is being held, but trying to acquire activate_lock ++ * while having ownership of the SDIO function could cause a deadlock. ++ */ ++ int active; ++ struct mutex activate_lock; ++}; ++ ++struct hif_request { ++ struct list_head list; ++ struct sdio_func *func; ++ int (*read)(struct sdio_func *func, ++ void *dst, unsigned int addr, int count); ++ int (*write)(struct sdio_func *func, ++ unsigned int addr, void *src, int count); ++ void *buf; ++ unsigned long addr; ++ int len; ++ A_STATUS (*completion)(void *context, A_STATUS status); ++ void *context; ++}; ++ ++ ++static HTC_CALLBACKS htcCallbacks; ++ ++/* ++ * shutdown_lock prevents recursion through HIFShutDownDevice ++ */ ++static DEFINE_MUTEX(shutdown_lock); ++ ++ ++/* ----- Request processing ------------------------------------------------ */ ++ ++ ++static A_STATUS process_request(struct hif_request *req) ++{ ++ int ret; ++ A_STATUS status; ++ ++ dev_dbg(&req->func->dev, "process_request(req %p)\n", req); ++ sdio_claim_host(req->func); ++ if (req->read) { ++ ret = req->read(req->func, req->buf, req->addr, req->len); ++ } else { ++ ret = req->write(req->func, req->addr, req->buf, req->len); ++ } ++ sdio_release_host(req->func); ++ status = ret ? A_ERROR : A_OK; ++ if (req->completion) ++ req->completion(req->context, status); ++ kfree(req); ++ return status; ++} ++ ++ ++static void enqueue_request(struct hif_device *hif, struct hif_request *req) ++{ ++ unsigned long flags; ++ ++ dev_dbg(&req->func->dev, "enqueue_request(req %p)\n", req); ++ spin_lock_irqsave(&hif->queue_lock, flags); ++ list_add_tail(&req->list, &hif->queue); ++ spin_unlock_irqrestore(&hif->queue_lock, flags); ++ wake_up(&hif->wait); ++} ++ ++ ++static struct hif_request *dequeue_request(struct hif_device *hif) ++{ ++ struct hif_request *req; ++ unsigned long flags; ++ ++ spin_lock_irqsave(&hif->queue_lock, flags); ++ if (list_empty(&hif->queue)) ++ req = NULL; ++ else { ++ req = list_first_entry(&hif->queue, ++ struct hif_request, list); ++ list_del(&req->list); ++ } ++ spin_unlock_irqrestore(&hif->queue_lock, flags); ++ return req; ++} ++ ++ ++static void wait_queue_empty(struct hif_device *hif) ++{ ++ unsigned long flags; ++ int empty; ++ ++ while (1) { ++ spin_lock_irqsave(&hif->queue_lock, flags); ++ empty = list_empty(&hif->queue); ++ spin_unlock_irqrestore(&hif->queue_lock, flags); ++ if (empty) ++ break; ++ else ++ yield(); ++ } ++} ++ ++ ++static int io(void *data) ++{ ++ struct hif_device *hif = data; ++ struct sched_param param = { .sched_priority = 2 }; ++ /* one priority level slower than ksdioirqd (which is at 1) */ ++ DEFINE_WAIT(wait); ++ struct hif_request *req; ++ ++ sched_setscheduler(current, SCHED_FIFO, ¶m); ++ ++ while (1) { ++ while (1) { ++ /* ++ * Since we never use signals here, one might think ++ * that this ought to be TASK_UNINTERRUPTIBLE. However, ++ * such a task would increase the load average and, ++ * worse, it would trigger the softlockup check. ++ */ ++ prepare_to_wait(&hif->wait, &wait, TASK_INTERRUPTIBLE); ++ if (kthread_should_stop()) { ++ finish_wait(&hif->wait, &wait); ++ return 0; ++ } ++ req = dequeue_request(hif); ++ if (req) ++ break; ++ schedule(); ++ } ++ finish_wait(&hif->wait, &wait); ++ ++ (void) process_request(req); ++ } ++ return 0; ++} ++ ++ ++A_STATUS HIFReadWrite(HIF_DEVICE *hif, A_UINT32 address, A_UCHAR *buffer, ++ A_UINT32 length, A_UINT32 request, void *context) ++{ ++ struct device *dev = HIFGetOSDevice(hif); ++ struct hif_request *req; ++ ++ dev_dbg(dev, "HIFReadWrite(device %p, address 0x%x, buffer %p, " ++ "length %d, request 0x%x, context %p)\n", ++ hif, address, buffer, length, request, context); ++ ++ BUG_ON(!(request & (HIF_SYNCHRONOUS | HIF_ASYNCHRONOUS))); ++ BUG_ON(!(request & (HIF_BYTE_BASIS | HIF_BLOCK_BASIS))); ++ BUG_ON(!(request & (HIF_READ | HIF_WRITE))); ++ BUG_ON(!(request & HIF_EXTENDED_IO)); ++ ++ if (address >= HIF_MBOX_START_ADDR(0) && ++ address < HIF_MBOX_START_ADDR(MBOXES+1)) { ++ BUG_ON(length > HIF_MBOX_WIDTH); ++ /* Adjust the address so that the last byte falls on the EOM ++ address. */ ++ address += HIF_MBOX_WIDTH-length; ++ } ++ ++ req = kzalloc(sizeof(*req), GFP_ATOMIC); ++ if (!req) { ++ if (request & HIF_ASYNCHRONOUS) ++ htcCallbacks.rwCompletionHandler(context, A_ERROR); ++ return A_ERROR; ++ } ++ ++ req->func = hif->func; ++ req->addr = address; ++ req->buf = buffer; ++ req->len = length; ++ ++ if (request & HIF_READ) { ++ if (request & HIF_FIXED_ADDRESS) ++ req->read = sdio_readsb; ++ else ++ req->read = sdio_memcpy_fromio; ++ } else { ++ if (request & HIF_FIXED_ADDRESS) ++ req->write = sdio_writesb; ++ else ++ req->write = sdio_memcpy_toio; ++ } ++ ++ if (!(request & HIF_ASYNCHRONOUS)) ++ return process_request(req); ++ ++ req->completion = htcCallbacks.rwCompletionHandler; ++ req->context = context; ++ enqueue_request(hif, req); ++ ++ return A_OK; ++} ++ ++ ++/* ----- Interrupt handling ------------------------------------------------ */ ++ ++/* ++ * Volatile ought to be good enough to make gcc do the right thing on S3C24xx. ++ * No need to use atomic or put barriers, keeping the code more readable. ++ * ++ * Warning: this story changes if going SMP/SMT. ++ */ ++ ++static volatile int masked = 1; ++static volatile int pending; ++static volatile int in_interrupt; ++ ++ ++static void ar6000_do_irq(struct sdio_func *func) ++{ ++ HIF_DEVICE *hif = sdio_get_drvdata(func); ++ struct device *dev = HIFGetOSDevice(hif); ++ A_STATUS status; ++ ++ dev_dbg(dev, "ar6000_do_irq -> %p\n", htcCallbacks.dsrHandler); ++ ++ status = htcCallbacks.dsrHandler(hif->htc_handle); ++ BUG_ON(status != A_OK); ++} ++ ++ ++static void sdio_ar6000_irq(struct sdio_func *func) ++{ ++ HIF_DEVICE *hif = sdio_get_drvdata(func); ++ struct device *dev = HIFGetOSDevice(hif); ++ ++ dev_dbg(dev, "sdio_ar6000_irq\n"); ++ ++ in_interrupt = 1; ++ if (masked) { ++ in_interrupt = 0; ++ pending++; ++ return; ++ } ++ /* ++ * @@@ This is ugly. If we don't drop the lock, we'll deadlock when ++ * the handler tries to do SDIO. So there are four choices: ++ * ++ * 1) Break the call chain by calling the callback from a workqueue. ++ * Ugh. ++ * 2) Make process_request aware that we already have the lock. ++ * 3) Drop the lock. Which is ugly but should be safe as long as we're ++ * making sure the device doesn't go away. ++ * 4) Change the AR6k driver such that it only issues asynchronous ++ * quests when called from an interrupt. ++ * ++ * Solution 2) is probably the best for now. Will try it later. ++ */ ++ sdio_release_host(func); ++ ar6000_do_irq(func); ++ sdio_claim_host(func); ++ in_interrupt = 0; ++} ++ ++ ++void HIFAckInterrupt(HIF_DEVICE *hif) ++{ ++ struct device *dev = HIFGetOSDevice(hif); ++ ++ dev_dbg(dev, "HIFAckInterrupt\n"); ++ /* do nothing */ ++} ++ ++ ++void HIFUnMaskInterrupt(HIF_DEVICE *hif) ++{ ++ struct device *dev = HIFGetOSDevice(hif); ++ ++ dev_dbg(dev, "HIFUnMaskInterrupt\n"); ++ do { ++ masked = 1; ++ if (pending) { ++ pending = 0; ++ ar6000_do_irq(hif->func); ++ /* We may take an interrupt before unmasking and thus ++ get it pending. In this case, we just loop back. */ ++ } ++ masked = 0; ++ } ++ while (pending); ++} ++ ++ ++void HIFMaskInterrupt(HIF_DEVICE *hif) ++{ ++ struct device *dev = HIFGetOSDevice(hif); ++ ++ dev_dbg(dev, "HIFMaskInterrupt\n"); ++ /* ++ * Since sdio_ar6000_irq can also be called from a process context, we ++ * may conceivably end up racing with it. Thus, we need to wait until ++ * we can be sure that no concurrent interrupt processing is going on ++ * before we return. ++ * ++ * Note: this may be a bit on the paranoid side - the callers may ++ * actually be nice enough to disable scheduling. Check later. ++ */ ++ masked = 1; ++ while (in_interrupt) ++ yield(); ++} ++ ++ ++/* ----- HIF API glue functions -------------------------------------------- */ ++ ++ ++struct device *HIFGetOSDevice(HIF_DEVICE *hif) ++{ ++ return &hif->func->dev; ++} ++ ++ ++void HIFSetHandle(void *hif_handle, void *handle) ++{ ++ HIF_DEVICE *hif = (HIF_DEVICE *) hif_handle; ++ ++ hif->htc_handle = handle; ++} ++ ++ ++/* ----- Device configuration (HIF side) ----------------------------------- */ ++ ++ ++A_STATUS HIFConfigureDevice(HIF_DEVICE *hif, ++ HIF_DEVICE_CONFIG_OPCODE opcode, void *config, A_UINT32 configLen) ++{ ++ struct device *dev = HIFGetOSDevice(hif); ++ HIF_DEVICE_IRQ_PROCESSING_MODE *ipm_cfg = config; ++ A_UINT32 *mbs_cfg = config; ++ int i; ++ ++ dev_dbg(dev, "HIFConfigureDevice\n"); ++ ++ switch (opcode) { ++ case HIF_DEVICE_GET_MBOX_BLOCK_SIZE: ++ for (i = 0; i != MBOXES; i++) ++ mbs_cfg[i] = HIF_MBOX_BLOCK_SIZE; ++ break; ++ case HIF_DEVICE_GET_MBOX_ADDR: ++ for (i = 0; i != MBOXES; i++) ++ mbs_cfg[i] = HIF_MBOX_START_ADDR(i); ++ break; ++ case HIF_DEVICE_GET_IRQ_PROC_MODE: ++ *ipm_cfg = HIF_DEVICE_IRQ_SYNC_ONLY; ++// *ipm_cfg = HIF_DEVICE_IRQ_ASYNC_SYNC; ++ break; ++ default: ++ return A_ERROR; ++ } ++ return A_OK; ++} ++ ++ ++/* ----- Device probe and removal (Linux side) ----------------------------- */ ++ ++ ++static int ar6000_do_activate(struct hif_device *hif) ++{ ++ struct sdio_func *func = hif->func; ++ struct device *dev = &func->dev; ++ int ret; ++ ++ dev_dbg(dev, "ar6000_do_activate\n"); ++ ++ sdio_claim_host(func); ++ sdio_enable_func(func); ++ ++ INIT_LIST_HEAD(&hif->queue); ++ init_waitqueue_head(&hif->wait); ++ spin_lock_init(&hif->queue_lock); ++ ++ ret = sdio_set_block_size(func, HIF_MBOX_BLOCK_SIZE); ++ if (ret < 0) { ++ dev_err(dev, "sdio_set_block_size returns %d\n", ret); ++ goto out_enabled; ++ } ++ ret = sdio_claim_irq(func, sdio_ar6000_irq); ++ if (ret) { ++ dev_err(dev, "sdio_claim_irq returns %d\n", ret); ++ goto out_enabled; ++ } ++ /* Set SDIO_BUS_CD_DISABLE in SDIO_CCCR_IF ? */ ++#if 0 ++ sdio_f0_writeb(func, SDIO_CCCR_CAP_E4MI, SDIO_CCCR_CAPS, &ret); ++ if (ret) { ++ dev_err(dev, "sdio_f0_writeb(SDIO_CCCR_CAPS) returns %d\n", ++ ret); ++ goto out_got_irq; ++ } ++#else ++ if (0) /* avoid warning */ ++ goto out_got_irq; ++#endif ++ ++ sdio_release_host(func); ++ ++ hif->io_task = kthread_run(io, hif, "ar6000_io"); ++ ret = IS_ERR(hif->io_task); ++ if (ret) { ++ dev_err(dev, "kthread_run(ar6000_io): %d\n", ret); ++ goto out_func_ready; ++ } ++ ++ ret = htcCallbacks.deviceInsertedHandler(hif); ++ if (ret == A_OK) ++ return 0; ++ ++ dev_err(dev, "deviceInsertedHandler: %d\n", ret); ++ ++ ret = kthread_stop(hif->io_task); ++ if (ret) ++ dev_err(dev, "kthread_stop (ar6000_io): %d\n", ret); ++ ++out_func_ready: ++ sdio_claim_host(func); ++ ++out_got_irq: ++ sdio_release_irq(func); ++ ++out_enabled: ++ sdio_disable_func(func); ++ sdio_release_host(func); ++ ++ return ret; ++} ++ ++ ++static void ar6000_do_deactivate(struct hif_device *hif) ++{ ++ struct sdio_func *func = hif->func; ++ struct device *dev = &func->dev; ++ int ret; ++ ++ dev_dbg(dev, "ar6000_do_deactivate\n"); ++ if (!hif->active) ++ return; ++ ++ if (mutex_trylock(&shutdown_lock)) { ++ /* ++ * Funny, Atheros' HIF does this call, but this just puts us in ++ * a recursion through HTCShutDown/HIFShutDown if unloading the ++ * module. ++ * ++ * However, we need it for suspend/resume. See the comment at ++ * HIFShutDown, below. ++ */ ++ ret = htcCallbacks.deviceRemovedHandler(hif->htc_handle, A_OK); ++ if (ret != A_OK) ++ dev_err(dev, "deviceRemovedHandler: %d\n", ret); ++ mutex_unlock(&shutdown_lock); ++ } ++ wait_queue_empty(hif); ++ ret = kthread_stop(hif->io_task); ++ if (ret) ++ dev_err(dev, "kthread_stop (ar6000_io): %d\n", ret); ++ sdio_claim_host(func); ++ sdio_release_irq(func); ++ sdio_disable_func(func); ++ sdio_release_host(func); ++} ++ ++ ++static int ar6000_activate(struct hif_device *hif) ++{ ++ int ret = 0; ++ ++ dev_dbg(&hif->func->dev, "ar6000_activate\n"); ++ mutex_lock(&hif->activate_lock); ++ if (!hif->active) { ++ ret = ar6000_do_activate(hif); ++ if (ret) { ++ printk(KERN_ERR "%s: Failed to activate %d\n", ++ __func__, ret); ++ goto out; ++ } ++ hif->active = 1; ++ } ++out: ++ mutex_unlock(&hif->activate_lock); ++ return ret; ++} ++ ++ ++static void ar6000_deactivate(struct hif_device *hif) ++{ ++ dev_dbg(&hif->func->dev, "ar6000_deactivate\n"); ++ mutex_lock(&hif->activate_lock); ++ if (hif->active) { ++ ar6000_do_deactivate(hif); ++ hif->active = 0; ++ } ++ mutex_unlock(&hif->activate_lock); ++} ++ ++ ++static int ar6000_rfkill_cb(void *data, int on) ++{ ++ struct hif_device *hif = data; ++ struct sdio_func *func = hif->func; ++ struct device *dev = &func->dev; ++ ++ dev_dbg(dev, "ar6000_rfkill_cb: on %d\n", on); ++ if (on) ++ return ar6000_activate(hif); ++ ar6000_deactivate(hif); ++ return 0; ++} ++ ++ ++static int sdio_ar6000_probe(struct sdio_func *func, ++ const struct sdio_device_id *id) ++{ ++ struct device *dev = &func->dev; ++ struct hif_device *hif; ++ int ret = 0; ++ ++ dev_dbg(dev, "sdio_ar6000_probe\n"); ++ BUG_ON(!htcCallbacks.deviceInsertedHandler); ++ ++ hif = kzalloc(sizeof(*hif), GFP_KERNEL); ++ if (!hif) ++ return -ENOMEM; ++ ++ sdio_set_drvdata(func, hif); ++ hif->func = func; ++ mutex_init(&hif->activate_lock); ++ hif->active = 0; ++ ++ if (gta02_wlan_query_rfkill_lock()) ++ ret = ar6000_activate(hif); ++ if (!ret) { ++ gta02_wlan_set_rfkill_cb(ar6000_rfkill_cb, hif); ++ return 0; ++ } ++ gta02_wlan_query_rfkill_unlock(); ++ sdio_set_drvdata(func, NULL); ++ kfree(hif); ++ return ret; ++} ++ ++ ++static void sdio_ar6000_remove(struct sdio_func *func) ++{ ++ struct device *dev = &func->dev; ++ HIF_DEVICE *hif = sdio_get_drvdata(func); ++ ++ dev_dbg(dev, "sdio_ar6000_remove\n"); ++ gta02_wlan_clear_rfkill_cb(); ++ ar6000_deactivate(hif); ++ sdio_set_drvdata(func, NULL); ++ kfree(hif); ++} ++ ++ ++/* ----- Device registration/unregistration (called by HIF) ---------------- */ ++ ++ ++#define ATHEROS_SDIO_DEVICE(id, offset) \ ++ SDIO_DEVICE(SDIO_VENDOR_ID_ATHEROS, SDIO_DEVICE_ID_ATHEROS_##id | (offset)) ++ ++static const struct sdio_device_id sdio_ar6000_ids[] = { ++ { ATHEROS_SDIO_DEVICE(AR6002, 0) }, ++ { ATHEROS_SDIO_DEVICE(AR6002, 0x1) }, ++ { ATHEROS_SDIO_DEVICE(AR6001, 0x8) }, ++ { ATHEROS_SDIO_DEVICE(AR6001, 0x9) }, ++ { ATHEROS_SDIO_DEVICE(AR6001, 0xa) }, ++ { ATHEROS_SDIO_DEVICE(AR6001, 0xb) }, ++ { /* end: all zeroes */ }, ++}; ++ ++MODULE_DEVICE_TABLE(sdio, sdio_ar6000_ids); ++ ++ ++static struct sdio_driver sdio_ar6000_driver = { ++ .probe = sdio_ar6000_probe, ++ .remove = sdio_ar6000_remove, ++ .name = "sdio_ar6000", ++ .id_table = sdio_ar6000_ids, ++}; ++ ++ ++int HIFInit(HTC_CALLBACKS *callbacks) ++{ ++ int ret; ++ ++ BUG_ON(!callbacks); ++ ++ printk(KERN_DEBUG "HIFInit\n"); ++ htcCallbacks = *callbacks; ++ ++ ret = sdio_register_driver(&sdio_ar6000_driver); ++ if (ret) { ++ printk(KERN_ERR ++ "sdio_register_driver(sdio_ar6000_driver): %d\n", ret); ++ return A_ERROR; ++ } ++ ++ return 0; ++} ++ ++ ++/* ++ * We have four possible call chains here: ++ * ++ * System shutdown/reboot: ++ * ++ * kernel_restart_prepare ...> device_shutdown ... > s3cmci_shutdown -> ++ * mmc_remove_host ..> sdio_bus_remove -> sdio_ar6000_remove -> ++ * ar6000_deactivate -> ar6000_do_deactivate -> ++ * deviceRemovedHandler (HTCTargetRemovedHandler) -> HIFShutDownDevice ++ * ++ * This is roughly the same sequence as suspend, described below. ++ * ++ * Module removal: ++ * ++ * sys_delete_module -> ar6000_cleanup_module -> HTCShutDown -> ++ * HIFShutDownDevice -> sdio_unregister_driver ...> sdio_bus_remove -> ++ * sdio_ar6000_remove -> ar6000_deactivate -> ar6000_do_deactivate ++ * ++ * In this case, HIFShutDownDevice must call sdio_unregister_driver to ++ * notify the driver about its removal. ar6000_do_deactivate must not call ++ * deviceRemovedHandler, because that would loop back into HIFShutDownDevice. ++ * ++ * Suspend: ++ * ++ * device_suspend ...> s3cmci_suspend ...> sdio_bus_remove -> ++ * sdio_ar6000_remove -> ar6000_deactivate -> ar6000_do_deactivate -> ++ * deviceRemovedHandler (HTCTargetRemovedHandler) -> HIFShutDownDevice ++ * ++ * We must call deviceRemovedHandler to inform the ar6k stack that the device ++ * has been removed. Since HTCTargetRemovedHandler calls back into ++ * HIFShutDownDevice, we must also prevent the call to ++ * sdio_unregister_driver, or we'd end up recursing into the SDIO stack, ++ * eventually deadlocking somewhere. ++ * ++ * rfkill: ++ * ++ * rfkill_state_store -> rfkill_toggle_radio -> gta02_wlan_toggle_radio -> ++ * ar6000_rfkill_cb -> ar6000_deactivate -> ar6000_do_deactivate -> ++ * deviceRemovedHandler (HTCTargetRemovedHandler) -> HIFShutDownDevice ++ * ++ * This is similar to suspend - only the entry point changes. ++ */ ++ ++void HIFShutDownDevice(HIF_DEVICE *hif) ++{ ++ /* Beware, HTCShutDown calls us with hif == NULL ! */ ++ if (mutex_trylock(&shutdown_lock)) { ++ sdio_unregister_driver(&sdio_ar6000_driver); ++ mutex_unlock(&shutdown_lock); ++ } ++} +diff -ruN --exclude='*.orig' --exclude='*.rej' linux-2.6.29-rc3.owrt/drivers/ar6000/hif/hif.c linux-2.6.29-rc3.owrt.om/drivers/ar6000/hif/hif.c +--- linux-2.6.29-rc3.owrt/drivers/ar6000/hif/hif.c 1970-01-01 01:00:00.000000000 +0100 ++++ linux-2.6.29-rc3.owrt.om/drivers/ar6000/hif/hif.c 2009-05-10 22:27:59.000000000 +0200 +@@ -0,0 +1,824 @@ ++/* ++ * @file: hif.c ++ * ++ * @abstract: HIF layer reference implementation for Atheros SDIO stack ++ * ++ * @notice: Copyright (c) 2004-2006 Atheros Communications Inc. ++ * ++ * ++ * 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; ++ * ++ * Software distributed under the License is distributed on an "AS ++ * IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or ++ * implied. See the License for the specific language governing ++ * rights and limitations under the License. ++ * ++ * ++ * ++ */ ++ ++#include "hif_internal.h" ++ ++/* ------ Static Variables ------ */ ++ ++/* ------ Global Variable Declarations ------- */ ++SD_PNP_INFO Ids[] = { ++ { ++ .SDIO_ManufacturerID = MANUFACTURER_ID_AR6001_BASE | 0xB, ++ .SDIO_ManufacturerCode = MANUFACTURER_CODE, ++ .SDIO_FunctionClass = FUNCTION_CLASS, ++ .SDIO_FunctionNo = 1 ++ }, ++ { ++ .SDIO_ManufacturerID = MANUFACTURER_ID_AR6001_BASE | 0xA, ++ .SDIO_ManufacturerCode = MANUFACTURER_CODE, ++ .SDIO_FunctionClass = FUNCTION_CLASS, ++ .SDIO_FunctionNo = 1 ++ }, ++ { ++ .SDIO_ManufacturerID = MANUFACTURER_ID_AR6001_BASE | 0x9, ++ .SDIO_ManufacturerCode = MANUFACTURER_CODE, ++ .SDIO_FunctionClass = FUNCTION_CLASS, ++ .SDIO_FunctionNo = 1 ++ }, ++ { ++ .SDIO_ManufacturerID = MANUFACTURER_ID_AR6001_BASE | 0x8, ++ .SDIO_ManufacturerCode = MANUFACTURER_CODE, ++ .SDIO_FunctionClass = FUNCTION_CLASS, ++ .SDIO_FunctionNo = 1 ++ }, ++ { ++ .SDIO_ManufacturerID = MANUFACTURER_ID_AR6002_BASE | 0x0, ++ .SDIO_ManufacturerCode = MANUFACTURER_CODE, ++ .SDIO_FunctionClass = FUNCTION_CLASS, ++ .SDIO_FunctionNo = 1 ++ }, ++ { ++ .SDIO_ManufacturerID = MANUFACTURER_ID_AR6002_BASE | 0x1, ++ .SDIO_ManufacturerCode = MANUFACTURER_CODE, ++ .SDIO_FunctionClass = FUNCTION_CLASS, ++ .SDIO_FunctionNo = 1 ++ }, ++ { ++ } //list is null termintaed ++}; ++ ++TARGET_FUNCTION_CONTEXT FunctionContext = { ++ .function.Version = CT_SDIO_STACK_VERSION_CODE, ++ .function.pName = "sdio_wlan", ++ .function.MaxDevices = 1, ++ .function.NumDevices = 0, ++ .function.pIds = Ids, ++ .function.pProbe = hifDeviceInserted, ++ .function.pRemove = hifDeviceRemoved, ++ .function.pSuspend = NULL, ++ .function.pResume = NULL, ++ .function.pWake = NULL, ++ .function.pContext = &FunctionContext, ++}; ++ ++HIF_DEVICE hifDevice[HIF_MAX_DEVICES]; ++HTC_CALLBACKS htcCallbacks; ++BUS_REQUEST busRequest[BUS_REQUEST_MAX_NUM]; ++static BUS_REQUEST *s_busRequestFreeQueue = NULL; ++OS_CRITICALSECTION lock; ++extern A_UINT32 onebitmode; ++extern A_UINT32 busspeedlow; ++ ++#ifdef DEBUG ++extern A_UINT32 debughif; ++#define ATH_DEBUG_ERROR 1 ++#define ATH_DEBUG_WARN 2 ++#define ATH_DEBUG_TRACE 3 ++#define _AR_DEBUG_PRINTX_ARG(arg...) arg ++#define AR_DEBUG_PRINTF(lvl, args)\ ++ {if (lvl <= debughif)\ ++ A_PRINTF(KERN_ALERT _AR_DEBUG_PRINTX_ARG args);\ ++ } ++#else ++#define AR_DEBUG_PRINTF(lvl, args) ++#endif ++ ++static BUS_REQUEST *hifAllocateBusRequest(void); ++static void hifFreeBusRequest(BUS_REQUEST *busrequest); ++static THREAD_RETURN insert_helper_func(POSKERNEL_HELPER pHelper); ++static void ResetAllCards(void); ++ ++/* ------ Functions ------ */ ++int HIFInit(HTC_CALLBACKS *callbacks) ++{ ++ SDIO_STATUS status; ++ DBG_ASSERT(callbacks != NULL); ++ ++ /* Store the callback and event handlers */ ++ htcCallbacks.deviceInsertedHandler = callbacks->deviceInsertedHandler; ++ htcCallbacks.deviceRemovedHandler = callbacks->deviceRemovedHandler; ++ htcCallbacks.deviceSuspendHandler = callbacks->deviceSuspendHandler; ++ htcCallbacks.deviceResumeHandler = callbacks->deviceResumeHandler; ++ htcCallbacks.deviceWakeupHandler = callbacks->deviceWakeupHandler; ++ htcCallbacks.rwCompletionHandler = callbacks->rwCompletionHandler; ++ htcCallbacks.dsrHandler = callbacks->dsrHandler; ++ ++ CriticalSectionInit(&lock); ++ ++ /* Register with bus driver core */ ++ status = SDIO_RegisterFunction(&FunctionContext.function); ++ DBG_ASSERT(SDIO_SUCCESS(status)); ++ ++ return(0); ++} ++ ++A_STATUS ++HIFReadWrite(HIF_DEVICE *device, ++ A_UINT32 address, ++ A_UCHAR *buffer, ++ A_UINT32 length, ++ A_UINT32 request, ++ void *context) ++{ ++ A_UINT8 rw; ++ A_UINT8 mode; ++ A_UINT8 funcNo; ++ A_UINT8 opcode; ++ A_UINT16 count; ++ SDREQUEST *sdrequest; ++ SDIO_STATUS sdiostatus; ++ BUS_REQUEST *busrequest; ++ A_STATUS status = A_OK; ++ ++ DBG_ASSERT(device != NULL); ++ DBG_ASSERT(device->handle != NULL); ++ ++ AR_DEBUG_PRINTF(ATH_DEBUG_TRACE, ("Device: %p\n", device)); ++ ++ do { ++ busrequest = hifAllocateBusRequest(); ++ if (busrequest == NULL) { ++ AR_DEBUG_PRINTF(ATH_DEBUG_ERROR, ("HIF Unable to allocate bus request\n")); ++ status = A_NO_RESOURCE; ++ break; ++ } ++ ++ sdrequest = busrequest->request; ++ busrequest->context = context; ++ ++ sdrequest->pDataBuffer = buffer; ++ if (request & HIF_SYNCHRONOUS) { ++ sdrequest->Flags = SDREQ_FLAGS_RESP_SDIO_R5 | SDREQ_FLAGS_DATA_TRANS; ++ sdrequest->pCompleteContext = NULL; ++ sdrequest->pCompletion = NULL; ++ AR_DEBUG_PRINTF(ATH_DEBUG_TRACE, ("Execution mode: Synchronous\n")); ++ } else if (request & HIF_ASYNCHRONOUS) { ++ sdrequest->Flags = SDREQ_FLAGS_RESP_SDIO_R5 | SDREQ_FLAGS_DATA_TRANS | ++ SDREQ_FLAGS_TRANS_ASYNC; ++ sdrequest->pCompleteContext = busrequest; ++ sdrequest->pCompletion = hifRWCompletionHandler; ++ AR_DEBUG_PRINTF(ATH_DEBUG_TRACE, ("Execution mode: Asynchronous\n")); ++ } else { ++ AR_DEBUG_PRINTF(ATH_DEBUG_ERROR, ++ ("Invalid execution mode: 0x%08x\n", request)); ++ status = A_EINVAL; ++ break; ++ } ++ ++ if (request & HIF_EXTENDED_IO) { ++ AR_DEBUG_PRINTF(ATH_DEBUG_TRACE, ("Command type: CMD53\n")); ++ sdrequest->Command = CMD53; ++ } else { ++ AR_DEBUG_PRINTF(ATH_DEBUG_ERROR, ++ ("Invalid command type: 0x%08x\n", request)); ++ status = A_EINVAL; ++ break; ++ } ++ ++ if (request & HIF_BLOCK_BASIS) { ++ mode = CMD53_BLOCK_BASIS; ++ sdrequest->BlockLen = HIF_MBOX_BLOCK_SIZE; ++ sdrequest->BlockCount = length / HIF_MBOX_BLOCK_SIZE; ++ count = sdrequest->BlockCount; ++ AR_DEBUG_PRINTF(ATH_DEBUG_TRACE, ++ ("Block mode (BlockLen: %d, BlockCount: %d)\n", ++ sdrequest->BlockLen, sdrequest->BlockCount)); ++ } else if (request & HIF_BYTE_BASIS) { ++ mode = CMD53_BYTE_BASIS; ++ sdrequest->BlockLen = length; ++ sdrequest->BlockCount = 1; ++ count = sdrequest->BlockLen; ++ AR_DEBUG_PRINTF(ATH_DEBUG_TRACE, ++ ("Byte mode (BlockLen: %d, BlockCount: %d)\n", ++ sdrequest->BlockLen, sdrequest->BlockCount)); ++ } else { ++ AR_DEBUG_PRINTF(ATH_DEBUG_ERROR, ++ ("Invalid data mode: 0x%08x\n", request)); ++ status = A_EINVAL; ++ break; ++ } ++ ++#if 0 ++ /* useful for checking register accesses */ ++ if (length & 0x3) { ++ A_PRINTF(KERN_ALERT"HIF (%s) is not a multiple of 4 bytes, addr:0x%X, len:%d\n", ++ request & HIF_WRITE ? "write":"read", address, length); ++ } ++#endif ++ ++ if ((address >= HIF_MBOX_START_ADDR(0)) && ++ (address <= HIF_MBOX_END_ADDR(3))) ++ { ++ ++ DBG_ASSERT(length <= HIF_MBOX_WIDTH); ++ ++ /* ++ * Mailbox write. Adjust the address so that the last byte ++ * falls on the EOM address. ++ */ ++ address += (HIF_MBOX_WIDTH - length); ++ } ++ ++ ++ ++ if (request & HIF_WRITE) { ++ rw = CMD53_WRITE; ++ sdrequest->Flags |= SDREQ_FLAGS_DATA_WRITE; ++ AR_DEBUG_PRINTF(ATH_DEBUG_TRACE, ("Direction: Write\n")); ++ } else if (request & HIF_READ) { ++ rw = CMD53_READ; ++ AR_DEBUG_PRINTF(ATH_DEBUG_TRACE, ("Direction: Read\n")); ++ } else { ++ AR_DEBUG_PRINTF(ATH_DEBUG_ERROR, ++ ("Invalid direction: 0x%08x\n", request)); ++ status = A_EINVAL; ++ break; ++ } ++ ++ if (request & HIF_FIXED_ADDRESS) { ++ opcode = CMD53_FIXED_ADDRESS; ++ AR_DEBUG_PRINTF(ATH_DEBUG_TRACE, ("Address mode: Fixed\n")); ++ } else if (request & HIF_INCREMENTAL_ADDRESS) { ++ opcode = CMD53_INCR_ADDRESS; ++ AR_DEBUG_PRINTF(ATH_DEBUG_TRACE, ("Address mode: Incremental\n")); ++ } else { ++ AR_DEBUG_PRINTF(ATH_DEBUG_ERROR, ++ ("Invalid address mode: 0x%08x\n", request)); ++ status = A_EINVAL; ++ break; ++ } ++ ++ funcNo = SDDEVICE_GET_SDIO_FUNCNO(device->handle); ++ AR_DEBUG_PRINTF(ATH_DEBUG_TRACE, ("Function number: %d\n", funcNo)); ++ SDIO_SET_CMD53_ARG(sdrequest->Argument, rw, funcNo, ++ mode, opcode, address, count); ++ ++ /* Send the command out */ ++ sdiostatus = SDDEVICE_CALL_REQUEST_FUNC(device->handle, sdrequest); ++ ++ if (!SDIO_SUCCESS(sdiostatus)) { ++ status = A_ERROR; ++ } ++ ++ } while (FALSE); ++ ++ if (A_FAILED(status) || (request & HIF_SYNCHRONOUS)) { ++ if (busrequest != NULL) { ++ hifFreeBusRequest(busrequest); ++ } ++ } ++ ++ if (A_FAILED(status) && (request & HIF_ASYNCHRONOUS)) { ++ /* call back async handler on failure */ ++ htcCallbacks.rwCompletionHandler(context, status); ++ } ++ ++ return status; ++} ++ ++A_STATUS ++HIFConfigureDevice(HIF_DEVICE *device, HIF_DEVICE_CONFIG_OPCODE opcode, ++ void *config, A_UINT32 configLen) ++{ ++ A_UINT32 count; ++ ++ switch(opcode) { ++ case HIF_DEVICE_GET_MBOX_BLOCK_SIZE: ++ ((A_UINT32 *)config)[0] = HIF_MBOX0_BLOCK_SIZE; ++ ((A_UINT32 *)config)[1] = HIF_MBOX1_BLOCK_SIZE; ++ ((A_UINT32 *)config)[2] = HIF_MBOX2_BLOCK_SIZE; ++ ((A_UINT32 *)config)[3] = HIF_MBOX3_BLOCK_SIZE; ++ break; ++ ++ case HIF_DEVICE_GET_MBOX_ADDR: ++ for (count = 0; count < 4; count ++) { ++ ((A_UINT32 *)config)[count] = HIF_MBOX_START_ADDR(count); ++ } ++ break; ++ case HIF_DEVICE_GET_IRQ_PROC_MODE: ++ /* the SDIO stack allows the interrupts to be processed either way, ASYNC or SYNC */ ++ *((HIF_DEVICE_IRQ_PROCESSING_MODE *)config) = HIF_DEVICE_IRQ_ASYNC_SYNC; ++ break; ++ default: ++ AR_DEBUG_PRINTF(ATH_DEBUG_WARN, ++ ("Unsupported configuration opcode: %d\n", opcode)); ++ return A_ERROR; ++ } ++ ++ return A_OK; ++} ++ ++void ++HIFShutDownDevice(HIF_DEVICE *device) ++{ ++ A_UINT8 data; ++ A_UINT32 count; ++ SDIO_STATUS status; ++ SDCONFIG_BUS_MODE_DATA busSettings; ++ SDCONFIG_FUNC_ENABLE_DISABLE_DATA fData; ++ ++ if (device != NULL) { ++ DBG_ASSERT(device->handle != NULL); ++ ++ /* Remove the allocated current if any */ ++ status = SDLIB_IssueConfig(device->handle, ++ SDCONFIG_FUNC_FREE_SLOT_CURRENT, NULL, 0); ++ DBG_ASSERT(SDIO_SUCCESS(status)); ++ ++ /* Disable the card */ ++ fData.EnableFlags = SDCONFIG_DISABLE_FUNC; ++ fData.TimeOut = 1; ++ status = SDLIB_IssueConfig(device->handle, SDCONFIG_FUNC_ENABLE_DISABLE, ++ &fData, sizeof(fData)); ++ DBG_ASSERT(SDIO_SUCCESS(status)); ++ ++ /* Perform a soft I/O reset */ ++ data = SDIO_IO_RESET; ++ status = SDLIB_IssueCMD52(device->handle, 0, SDIO_IO_ABORT_REG, ++ &data, 1, 1); ++ DBG_ASSERT(SDIO_SUCCESS(status)); ++ ++ /* ++ * WAR - Codetelligence driver does not seem to shutdown correctly in 1 ++ * bit mode. By default it configures the HC in the 4 bit. Its later in ++ * our driver that we switch to 1 bit mode. If we try to shutdown, the ++ * driver hangs so we revert to 4 bit mode, to be transparent to the ++ * underlying bus driver. ++ */ ++ if (onebitmode) { ++ ZERO_OBJECT(busSettings); ++ busSettings.BusModeFlags = SDDEVICE_GET_BUSMODE_FLAGS(device->handle); ++ SDCONFIG_SET_BUS_WIDTH(busSettings.BusModeFlags, ++ SDCONFIG_BUS_WIDTH_4_BIT); ++ ++ /* Issue config request to change the bus width to 4 bit */ ++ status = SDLIB_IssueConfig(device->handle, SDCONFIG_BUS_MODE_CTRL, ++ &busSettings, ++ sizeof(SDCONFIG_BUS_MODE_DATA)); ++ DBG_ASSERT(SDIO_SUCCESS(status)); ++ } ++ ++ /* Free the bus requests */ ++ for (count = 0; count < BUS_REQUEST_MAX_NUM; count ++) { ++ SDDeviceFreeRequest(device->handle, busRequest[count].request); ++ } ++ /* Clean up the queue */ ++ s_busRequestFreeQueue = NULL; ++ } else { ++ /* since we are unloading the driver anyways, reset all cards in case the SDIO card ++ * is externally powered and we are unloading the SDIO stack. This avoids the problem when ++ * the SDIO stack is reloaded and attempts are made to re-enumerate a card that is already ++ * enumerated */ ++ ResetAllCards(); ++ /* Unregister with bus driver core */ ++ AR_DEBUG_PRINTF(ATH_DEBUG_TRACE, ++ ("Unregistering with the bus driver\n")); ++ status = SDIO_UnregisterFunction(&FunctionContext.function); ++ DBG_ASSERT(SDIO_SUCCESS(status)); ++ } ++} ++ ++void ++hifRWCompletionHandler(SDREQUEST *request) ++{ ++ A_STATUS status; ++ void *context; ++ BUS_REQUEST *busrequest; ++ ++ if (SDIO_SUCCESS(request->Status)) { ++ status = A_OK; ++ } else { ++ status = A_ERROR; ++ } ++ ++ DBG_ASSERT(status == A_OK); ++ busrequest = (BUS_REQUEST *) request->pCompleteContext; ++ context = (void *) busrequest->context; ++ /* free the request before calling the callback, in case the ++ * callback submits another request, this guarantees that ++ * there is at least 1 free request available everytime the callback ++ * is invoked */ ++ hifFreeBusRequest(busrequest); ++ htcCallbacks.rwCompletionHandler(context, status); ++} ++ ++void ++hifIRQHandler(void *context) ++{ ++ A_STATUS status; ++ HIF_DEVICE *device; ++ ++ device = (HIF_DEVICE *)context; ++ AR_DEBUG_PRINTF(ATH_DEBUG_TRACE, ("Device: %p\n", device)); ++ status = htcCallbacks.dsrHandler(device->htc_handle); ++ DBG_ASSERT(status == A_OK); ++} ++ ++BOOL ++hifDeviceInserted(SDFUNCTION *function, SDDEVICE *handle) ++{ ++ BOOL enabled; ++ A_UINT8 data; ++ A_UINT32 count; ++ HIF_DEVICE *device; ++ SDIO_STATUS status; ++ A_UINT16 maxBlocks; ++ A_UINT16 maxBlockSize; ++ SDCONFIG_BUS_MODE_DATA busSettings; ++ SDCONFIG_FUNC_ENABLE_DISABLE_DATA fData; ++ TARGET_FUNCTION_CONTEXT *functionContext; ++ SDCONFIG_FUNC_SLOT_CURRENT_DATA slotCurrent; ++ SD_BUSCLOCK_RATE currentBusClock; ++ ++ DBG_ASSERT(function != NULL); ++ DBG_ASSERT(handle != NULL); ++ ++ device = addHifDevice(handle); ++ AR_DEBUG_PRINTF(ATH_DEBUG_TRACE, ("Device: %p\n", device)); ++ functionContext = (TARGET_FUNCTION_CONTEXT *)function->pContext; ++ ++ /* ++ * Issue commands to get the manufacturer ID and stuff and compare it ++ * against the rev Id derived from the ID registered during the ++ * initialization process. Report the device only in the case there ++ * is a match. In the case od SDIO, the bus driver has already queried ++ * these details so we just need to use their data structures to get the ++ * relevant values. Infact, the driver has already matched it against ++ * the Ids that we registered with it so we dont need to the step here. ++ */ ++ ++ /* Configure the SDIO Bus Width */ ++ if (onebitmode) { ++ data = SDIO_BUS_WIDTH_1_BIT; ++ status = SDLIB_IssueCMD52(handle, 0, SDIO_BUS_IF_REG, &data, 1, 1); ++ if (!SDIO_SUCCESS(status)) { ++ AR_DEBUG_PRINTF(ATH_DEBUG_ERROR, ++ ("Unable to set the bus width to 1 bit\n")); ++ return FALSE; ++ } ++ } ++ ++ /* Get current bus flags */ ++ ZERO_OBJECT(busSettings); ++ ++ busSettings.BusModeFlags = SDDEVICE_GET_BUSMODE_FLAGS(handle); ++ if (onebitmode) { ++ SDCONFIG_SET_BUS_WIDTH(busSettings.BusModeFlags, ++ SDCONFIG_BUS_WIDTH_1_BIT); ++ } ++ ++ /* get the current operating clock, the bus driver sets us up based ++ * on what our CIS reports and what the host controller can handle ++ * we can use this to determine whether we want to drop our clock rate ++ * down */ ++ currentBusClock = SDDEVICE_GET_OPER_CLOCK(handle); ++ busSettings.ClockRate = currentBusClock; ++ ++ AR_DEBUG_PRINTF(ATH_DEBUG_TRACE, ++ ("HIF currently running at: %d \n",currentBusClock)); ++ ++ /* see if HIF wants to run at a lower clock speed, we may already be ++ * at that lower clock speed */ ++ if (currentBusClock > (SDIO_CLOCK_FREQUENCY_DEFAULT >> busspeedlow)) { ++ busSettings.ClockRate = SDIO_CLOCK_FREQUENCY_DEFAULT >> busspeedlow; ++ AR_DEBUG_PRINTF(ATH_DEBUG_WARN, ++ ("HIF overriding clock to %d \n",busSettings.ClockRate)); ++ } ++ ++ /* Issue config request to override clock rate */ ++ status = SDLIB_IssueConfig(handle, SDCONFIG_FUNC_CHANGE_BUS_MODE, &busSettings, ++ sizeof(SDCONFIG_BUS_MODE_DATA)); ++ if (!SDIO_SUCCESS(status)) { ++ AR_DEBUG_PRINTF(ATH_DEBUG_ERROR, ++ ("Unable to configure the host clock\n")); ++ return FALSE; ++ } else { ++ AR_DEBUG_PRINTF(ATH_DEBUG_TRACE, ++ ("Configured clock: %d, Maximum clock: %d\n", ++ busSettings.ActualClockRate, ++ SDDEVICE_GET_MAX_CLOCK(handle))); ++ } ++ ++ /* ++ * Check if the target supports block mode. This result of this check ++ * can be used to implement the HIFReadWrite API. ++ */ ++ if (SDDEVICE_GET_SDIO_FUNC_MAXBLKSIZE(handle)) { ++ /* Limit block size to operational block limit or card function ++ capability */ ++ maxBlockSize = min(SDDEVICE_GET_OPER_BLOCK_LEN(handle), ++ SDDEVICE_GET_SDIO_FUNC_MAXBLKSIZE(handle)); ++ ++ /* check if the card support multi-block transfers */ ++ if (!(SDDEVICE_GET_SDIOCARD_CAPS(handle) & SDIO_CAPS_MULTI_BLOCK)) { ++ AR_DEBUG_PRINTF(ATH_DEBUG_TRACE, ("Byte basis only\n")); ++ ++ /* Limit block size to max byte basis */ ++ maxBlockSize = min(maxBlockSize, ++ (A_UINT16)SDIO_MAX_LENGTH_BYTE_BASIS); ++ maxBlocks = 1; ++ } else { ++ AR_DEBUG_PRINTF(ATH_DEBUG_TRACE, ("Multi-block capable\n")); ++ maxBlocks = SDDEVICE_GET_OPER_BLOCKS(handle); ++ status = SDLIB_SetFunctionBlockSize(handle, HIF_MBOX_BLOCK_SIZE); ++ if (!SDIO_SUCCESS(status)) { ++ AR_DEBUG_PRINTF(ATH_DEBUG_ERROR, ++ ("Failed to set block size. Err:%d\n", status)); ++ return FALSE; ++ } ++ } ++ ++ AR_DEBUG_PRINTF(ATH_DEBUG_TRACE, ++ ("Bytes Per Block: %d bytes, Block Count:%d \n", ++ maxBlockSize, maxBlocks)); ++ } else { ++ AR_DEBUG_PRINTF(ATH_DEBUG_ERROR, ++ ("Function does not support Block Mode!\n")); ++ return FALSE; ++ } ++ ++ /* Allocate the slot current */ ++ status = SDLIB_GetDefaultOpCurrent(handle, &slotCurrent.SlotCurrent); ++ if (SDIO_SUCCESS(status)) { ++ AR_DEBUG_PRINTF(ATH_DEBUG_TRACE, ("Allocating Slot current: %d mA\n", ++ slotCurrent.SlotCurrent)); ++ status = SDLIB_IssueConfig(handle, SDCONFIG_FUNC_ALLOC_SLOT_CURRENT, ++ &slotCurrent, sizeof(slotCurrent)); ++ if (!SDIO_SUCCESS(status)) { ++ AR_DEBUG_PRINTF(ATH_DEBUG_ERROR, ++ ("Failed to allocate slot current %d\n", status)); ++ return FALSE; ++ } ++ } ++ ++ /* Enable the dragon function */ ++ count = 0; ++ enabled = FALSE; ++ fData.TimeOut = 1; ++ fData.EnableFlags = SDCONFIG_ENABLE_FUNC; ++ while ((count++ < SDWLAN_ENABLE_DISABLE_TIMEOUT) && !enabled) ++ { ++ /* Enable dragon */ ++ status = SDLIB_IssueConfig(handle, SDCONFIG_FUNC_ENABLE_DISABLE, ++ &fData, sizeof(fData)); ++ if (!SDIO_SUCCESS(status)) { ++ AR_DEBUG_PRINTF(ATH_DEBUG_TRACE, ++ ("Attempting to enable the card again\n")); ++ continue; ++ } ++ ++ /* Mark the status as enabled */ ++ enabled = TRUE; ++ } ++ ++ /* Check if we were succesful in enabling the target */ ++ if (!enabled) { ++ AR_DEBUG_PRINTF(ATH_DEBUG_ERROR, ++ ("Failed to communicate with the target\n")); ++ return FALSE; ++ } ++ ++ /* Allocate the bus requests to be used later */ ++ A_MEMZERO(busRequest, sizeof(busRequest)); ++ for (count = 0; count < BUS_REQUEST_MAX_NUM; count ++) { ++ if ((busRequest[count].request = SDDeviceAllocRequest(handle)) == NULL){ ++ AR_DEBUG_PRINTF(ATH_DEBUG_ERROR, ("Unable to allocate memory\n")); ++ /* TODO: Free the memory that has already been allocated */ ++ return FALSE; ++ } ++ hifFreeBusRequest(&busRequest[count]); ++ ++ AR_DEBUG_PRINTF(ATH_DEBUG_TRACE, ++ ("0x%08x = busRequest[%d].request = 0x%08x\n", ++ (unsigned int) &busRequest[count], count, ++ (unsigned int) busRequest[count].request)); ++ } ++ ++ /* Schedule a worker to handle device inserted, this is a temporary workaround ++ * to fix a deadlock if the device fails to intialize in the insertion handler ++ * The failure causes the instance to shutdown the HIF layer and unregister the ++ * function driver within the busdriver probe context which can deadlock ++ * ++ * NOTE: we cannot use the default work queue because that would block ++ * SD bus request processing for all synchronous I/O. We must use a kernel ++ * thread that is creating using the helper library. ++ * */ ++ ++ if (SDIO_SUCCESS(SDLIB_OSCreateHelper(&device->insert_helper, ++ insert_helper_func, ++ device))) { ++ device->helper_started = TRUE; ++ } ++ ++ return TRUE; ++} ++ ++static THREAD_RETURN insert_helper_func(POSKERNEL_HELPER pHelper) ++{ ++ ++ /* ++ * Adding a wait of around a second before we issue the very first ++ * command to dragon. During the process of loading/unloading the ++ * driver repeatedly it was observed that we get a data timeout ++ * while accessing function 1 registers in the chip. The theory at ++ * this point is that some initialization delay in dragon is ++ * causing the SDIO state in dragon core to be not ready even after ++ * the ready bit indicates that function 1 is ready. Accomodating ++ * for this behavior by adding some delay in the driver before it ++ * issues the first command after switching on dragon. Need to ++ * investigate this a bit more - TODO ++ */ ++ ++ A_MDELAY(1000); ++ /* Inform HTC */ ++ if ((htcCallbacks.deviceInsertedHandler(SD_GET_OS_HELPER_CONTEXT(pHelper))) != A_OK) { ++ AR_DEBUG_PRINTF(ATH_DEBUG_TRACE, ("Device rejected\n")); ++ } ++ ++ return 0; ++} ++ ++void ++HIFAckInterrupt(HIF_DEVICE *device) ++{ ++ SDIO_STATUS status; ++ DBG_ASSERT(device != NULL); ++ DBG_ASSERT(device->handle != NULL); ++ ++ /* Acknowledge our function IRQ */ ++ status = SDLIB_IssueConfig(device->handle, SDCONFIG_FUNC_ACK_IRQ, ++ NULL, 0); ++ DBG_ASSERT(SDIO_SUCCESS(status)); ++} ++ ++void ++HIFUnMaskInterrupt(HIF_DEVICE *device) ++{ ++ SDIO_STATUS status; ++ ++ DBG_ASSERT(device != NULL); ++ DBG_ASSERT(device->handle != NULL); ++ ++ /* Register the IRQ Handler */ ++ SDDEVICE_SET_IRQ_HANDLER(device->handle, hifIRQHandler, device); ++ ++ /* Unmask our function IRQ */ ++ status = SDLIB_IssueConfig(device->handle, SDCONFIG_FUNC_UNMASK_IRQ, ++ NULL, 0); ++ DBG_ASSERT(SDIO_SUCCESS(status)); ++} ++ ++void HIFMaskInterrupt(HIF_DEVICE *device) ++{ ++ SDIO_STATUS status; ++ DBG_ASSERT(device != NULL); ++ DBG_ASSERT(device->handle != NULL); ++ ++ /* Mask our function IRQ */ ++ status = SDLIB_IssueConfig(device->handle, SDCONFIG_FUNC_MASK_IRQ, ++ NULL, 0); ++ DBG_ASSERT(SDIO_SUCCESS(status)); ++ ++ /* Unregister the IRQ Handler */ ++ SDDEVICE_SET_IRQ_HANDLER(device->handle, NULL, NULL); ++} ++ ++static BUS_REQUEST *hifAllocateBusRequest(void) ++{ ++ BUS_REQUEST *busrequest; ++ ++ /* Acquire lock */ ++ CriticalSectionAcquire(&lock); ++ ++ /* Remove first in list */ ++ if((busrequest = s_busRequestFreeQueue) != NULL) ++ { ++ s_busRequestFreeQueue = busrequest->next; ++ } ++ ++ /* Release lock */ ++ CriticalSectionRelease(&lock); ++ ++ return busrequest; ++} ++ ++static void ++hifFreeBusRequest(BUS_REQUEST *busrequest) ++{ ++ DBG_ASSERT(busrequest != NULL); ++ ++ /* Acquire lock */ ++ CriticalSectionAcquire(&lock); ++ ++ /* Insert first in list */ ++ busrequest->next = s_busRequestFreeQueue; ++ s_busRequestFreeQueue = busrequest; ++ ++ /* Release lock */ ++ CriticalSectionRelease(&lock); ++} ++ ++void ++hifDeviceRemoved(SDFUNCTION *function, SDDEVICE *handle) ++{ ++ A_STATUS status; ++ HIF_DEVICE *device; ++ DBG_ASSERT(function != NULL); ++ DBG_ASSERT(handle != NULL); ++ ++ device = getHifDevice(handle); ++ status = htcCallbacks.deviceRemovedHandler(device->htc_handle, A_OK); ++ ++ /* cleanup the helper thread */ ++ if (device->helper_started) { ++ SDLIB_OSDeleteHelper(&device->insert_helper); ++ device->helper_started = FALSE; ++ } ++ ++ delHifDevice(handle); ++ DBG_ASSERT(status == A_OK); ++} ++ ++HIF_DEVICE * ++addHifDevice(SDDEVICE *handle) ++{ ++ DBG_ASSERT(handle != NULL); ++ hifDevice[0].handle = handle; ++ return &hifDevice[0]; ++} ++ ++HIF_DEVICE * ++getHifDevice(SDDEVICE *handle) ++{ ++ DBG_ASSERT(handle != NULL); ++ return &hifDevice[0]; ++} ++ ++void ++delHifDevice(SDDEVICE *handle) ++{ ++ DBG_ASSERT(handle != NULL); ++ hifDevice[0].handle = NULL; ++} ++ ++struct device* ++HIFGetOSDevice(HIF_DEVICE *device) ++{ ++ return &device->handle->Device->dev; ++} ++ ++static void ResetAllCards(void) ++{ ++ UINT8 data; ++ SDIO_STATUS status; ++ int i; ++ ++ data = SDIO_IO_RESET; ++ ++ /* set the I/O CARD reset bit: ++ * NOTE: we are exploiting a "feature" of the SDIO core that resets the core when you ++ * set the RES bit in the SDIO_IO_ABORT register. This bit however "normally" resets the ++ * I/O functions leaving the SDIO core in the same state (as per SDIO spec). ++ * In this design, this reset can be used to reset the SDIO core itself */ ++ for (i = 0; i < HIF_MAX_DEVICES; i++) { ++ if (hifDevice[i].handle != NULL) { ++ AR_DEBUG_PRINTF(ATH_DEBUG_TRACE, ++ ("Issuing I/O Card reset for instance: %d \n",i)); ++ /* set the I/O Card reset bit */ ++ status = SDLIB_IssueCMD52(hifDevice[i].handle, ++ 0, /* function 0 space */ ++ SDIO_IO_ABORT_REG, ++ &data, ++ 1, /* 1 byte */ ++ TRUE); /* write */ ++ } ++ } ++ ++} ++ ++void HIFSetHandle(void *hif_handle, void *handle) ++{ ++ HIF_DEVICE *device = (HIF_DEVICE *) hif_handle; ++ ++ device->htc_handle = handle; ++ ++ return; ++} +diff -ruN --exclude='*.orig' --exclude='*.rej' linux-2.6.29-rc3.owrt/drivers/ar6000/hif/hif_internal.h linux-2.6.29-rc3.owrt.om/drivers/ar6000/hif/hif_internal.h +--- linux-2.6.29-rc3.owrt/drivers/ar6000/hif/hif_internal.h 1970-01-01 01:00:00.000000000 +0100 ++++ linux-2.6.29-rc3.owrt.om/drivers/ar6000/hif/hif_internal.h 2009-05-10 22:27:59.000000000 +0200 +@@ -0,0 +1,102 @@ ++/* ++ * @file: hif_internal.h ++ * ++ * @abstract: internal header file for hif layer ++ * ++ * @notice: Copyright (c) 2004-2006 Atheros Communications Inc. ++ * ++ * ++ * 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; ++ * ++ * Software distributed under the License is distributed on an "AS ++ * IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or ++ * implied. See the License for the specific language governing ++ * rights and limitations under the License. ++ * ++ * ++ * ++ */ ++ ++#include <linux/sdio/ctsystem.h> ++#include <linux/sdio/sdio_busdriver.h> ++#include <linux/sdio/_sdio_defs.h> ++#include <linux/sdio/sdio_lib.h> ++#include "a_config.h" ++#include "athdefs.h" ++#include "a_types.h" ++#include "a_osapi.h" ++#include "hif.h" ++ ++#define MANUFACTURER_ID_AR6001_BASE 0x100 ++#define MANUFACTURER_ID_AR6002_BASE 0x200 ++#define FUNCTION_CLASS 0x0 ++#define MANUFACTURER_CODE 0x271 ++ ++#define BUS_REQUEST_MAX_NUM 64 ++ ++#define SDIO_CLOCK_FREQUENCY_DEFAULT 25000000 ++#define SDWLAN_ENABLE_DISABLE_TIMEOUT 20 ++#define FLAGS_CARD_ENAB 0x02 ++#define FLAGS_CARD_IRQ_UNMSK 0x04 ++ ++#define HIF_MBOX_BLOCK_SIZE 128 ++#define HIF_MBOX_BASE_ADDR 0x800 ++#define HIF_MBOX_WIDTH 0x800 ++#define HIF_MBOX0_BLOCK_SIZE 1 ++#define HIF_MBOX1_BLOCK_SIZE HIF_MBOX_BLOCK_SIZE ++#define HIF_MBOX2_BLOCK_SIZE HIF_MBOX_BLOCK_SIZE ++#define HIF_MBOX3_BLOCK_SIZE HIF_MBOX_BLOCK_SIZE ++ ++#define HIF_MBOX_START_ADDR(mbox) \ ++ HIF_MBOX_BASE_ADDR + mbox * HIF_MBOX_WIDTH ++ ++#define HIF_MBOX_END_ADDR(mbox) \ ++ HIF_MBOX_START_ADDR(mbox) + HIF_MBOX_WIDTH - 1 ++ ++struct hif_device { ++ SDDEVICE *handle; ++ void *htc_handle; ++ OSKERNEL_HELPER insert_helper; ++ BOOL helper_started; ++}; ++ ++typedef struct target_function_context { ++ SDFUNCTION function; /* function description of the bus driver */ ++ OS_SEMAPHORE instanceSem; /* instance lock. Unused */ ++ SDLIST instanceList; /* list of instances. Unused */ ++} TARGET_FUNCTION_CONTEXT; ++ ++typedef struct bus_request { ++ struct bus_request *next; ++ SDREQUEST *request; ++ void *context; ++} BUS_REQUEST; ++ ++BOOL ++hifDeviceInserted(SDFUNCTION *function, SDDEVICE *device); ++ ++void ++hifDeviceRemoved(SDFUNCTION *function, SDDEVICE *device); ++ ++SDREQUEST * ++hifAllocateDeviceRequest(SDDEVICE *device); ++ ++void ++hifFreeDeviceRequest(SDREQUEST *request); ++ ++void ++hifRWCompletionHandler(SDREQUEST *request); ++ ++void ++hifIRQHandler(void *context); ++ ++HIF_DEVICE * ++addHifDevice(SDDEVICE *handle); ++ ++HIF_DEVICE * ++getHifDevice(SDDEVICE *handle); ++ ++void ++delHifDevice(SDDEVICE *handle); +diff -ruN --exclude='*.orig' --exclude='*.rej' linux-2.6.29-rc3.owrt/drivers/ar6000/htc/ar6k.c linux-2.6.29-rc3.owrt.om/drivers/ar6000/htc/ar6k.c +--- linux-2.6.29-rc3.owrt/drivers/ar6000/htc/ar6k.c 1970-01-01 01:00:00.000000000 +0100 ++++ linux-2.6.29-rc3.owrt.om/drivers/ar6000/htc/ar6k.c 2009-05-10 22:27:59.000000000 +0200 +@@ -0,0 +1,991 @@ ++/* ++ * AR6K device layer that handles register level I/O ++ * ++ * Copyright (c) 2007 Atheros Communications Inc. ++ * All rights reserved. ++ * ++ * ++ * 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; ++ * ++ * Software distributed under the License is distributed on an "AS ++ * IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or ++ * implied. See the License for the specific language governing ++ * rights and limitations under the License. ++ * ++ * ++ * ++ */ ++#include "a_config.h" ++#include "athdefs.h" ++#include "a_types.h" ++#include "AR6Khwreg.h" ++#include "a_osapi.h" ++#include "a_debug.h" ++#include "hif.h" ++#include "htc_packet.h" ++#include "ar6k.h" ++ ++#define MAILBOX_FOR_BLOCK_SIZE 1 ++ ++extern A_UINT32 resetok; ++ ++static A_STATUS DevEnableInterrupts(AR6K_DEVICE *pDev); ++static A_STATUS DevDisableInterrupts(AR6K_DEVICE *pDev); ++ ++#define LOCK_AR6K(p) A_MUTEX_LOCK(&(p)->Lock); ++#define UNLOCK_AR6K(p) A_MUTEX_UNLOCK(&(p)->Lock); ++ ++void AR6KFreeIOPacket(AR6K_DEVICE *pDev, HTC_PACKET *pPacket) ++{ ++ LOCK_AR6K(pDev); ++ HTC_PACKET_ENQUEUE(&pDev->RegisterIOList,pPacket); ++ UNLOCK_AR6K(pDev); ++} ++ ++HTC_PACKET *AR6KAllocIOPacket(AR6K_DEVICE *pDev) ++{ ++ HTC_PACKET *pPacket; ++ ++ LOCK_AR6K(pDev); ++ pPacket = HTC_PACKET_DEQUEUE(&pDev->RegisterIOList); ++ UNLOCK_AR6K(pDev); ++ ++ return pPacket; ++} ++ ++A_STATUS DevSetup(AR6K_DEVICE *pDev) ++{ ++ A_UINT32 mailboxaddrs[AR6K_MAILBOXES]; ++ A_UINT32 blocksizes[AR6K_MAILBOXES]; ++ A_STATUS status = A_OK; ++ int i; ++ ++ AR_DEBUG_ASSERT(AR6K_IRQ_PROC_REGS_SIZE == 16); ++ AR_DEBUG_ASSERT(AR6K_IRQ_ENABLE_REGS_SIZE == 4); ++ ++ do { ++ /* give a handle to HIF for this target */ ++ HIFSetHandle(pDev->HIFDevice, (void *)pDev); ++ /* initialize our free list of IO packets */ ++ INIT_HTC_PACKET_QUEUE(&pDev->RegisterIOList); ++ A_MUTEX_INIT(&pDev->Lock); ++ ++ /* get the addresses for all 4 mailboxes */ ++ status = HIFConfigureDevice(pDev->HIFDevice, HIF_DEVICE_GET_MBOX_ADDR, ++ mailboxaddrs, sizeof(mailboxaddrs)); ++ ++ if (status != A_OK) { ++ AR_DEBUG_ASSERT(FALSE); ++ break; ++ } ++ ++ /* carve up register I/O packets (these are for ASYNC register I/O ) */ ++ for (i = 0; i < AR6K_MAX_REG_IO_BUFFERS; i++) { ++ HTC_PACKET *pIOPacket; ++ pIOPacket = &pDev->RegIOBuffers[i].HtcPacket; ++ SET_HTC_PACKET_INFO_RX_REFILL(pIOPacket, ++ pDev, ++ pDev->RegIOBuffers[i].Buffer, ++ AR6K_REG_IO_BUFFER_SIZE, ++ 0); /* don't care */ ++ AR6KFreeIOPacket(pDev,pIOPacket); ++ } ++ ++ /* get the address of the mailbox we are using */ ++ pDev->MailboxAddress = mailboxaddrs[HTC_MAILBOX]; ++ ++ /* get the block sizes */ ++ status = HIFConfigureDevice(pDev->HIFDevice, HIF_DEVICE_GET_MBOX_BLOCK_SIZE, ++ blocksizes, sizeof(blocksizes)); ++ ++ if (status != A_OK) { ++ AR_DEBUG_ASSERT(FALSE); ++ break; ++ } ++ ++ /* note: we actually get the block size of a mailbox other than 0, for SDIO the block ++ * size on mailbox 0 is artificially set to 1. So we use the block size that is set ++ * for the other 3 mailboxes */ ++ pDev->BlockSize = blocksizes[MAILBOX_FOR_BLOCK_SIZE]; ++ /* must be a power of 2 */ ++ AR_DEBUG_ASSERT((pDev->BlockSize & (pDev->BlockSize - 1)) == 0); ++ ++ /* assemble mask, used for padding to a block */ ++ pDev->BlockMask = pDev->BlockSize - 1; ++ ++ AR_DEBUG_PRINTF(ATH_DEBUG_TRC,("BlockSize: %d, MailboxAddress:0x%X \n", ++ pDev->BlockSize, pDev->MailboxAddress)); ++ ++ pDev->GetPendingEventsFunc = NULL; ++ /* see if the HIF layer implements the get pending events function */ ++ HIFConfigureDevice(pDev->HIFDevice, ++ HIF_DEVICE_GET_PENDING_EVENTS_FUNC, ++ &pDev->GetPendingEventsFunc, ++ sizeof(pDev->GetPendingEventsFunc)); ++ ++ /* assume we can process HIF interrupt events asynchronously */ ++ pDev->HifIRQProcessingMode = HIF_DEVICE_IRQ_ASYNC_SYNC; ++ ++ /* see if the HIF layer overrides this assumption */ ++ HIFConfigureDevice(pDev->HIFDevice, ++ HIF_DEVICE_GET_IRQ_PROC_MODE, ++ &pDev->HifIRQProcessingMode, ++ sizeof(pDev->HifIRQProcessingMode)); ++ ++ switch (pDev->HifIRQProcessingMode) { ++ case HIF_DEVICE_IRQ_SYNC_ONLY: ++ AR_DEBUG_PRINTF(ATH_DEBUG_TRC,("HIF Interrupt processing is SYNC ONLY\n")); ++ break; ++ case HIF_DEVICE_IRQ_ASYNC_SYNC: ++ AR_DEBUG_PRINTF(ATH_DEBUG_TRC,("HIF Interrupt processing is ASYNC and SYNC\n")); ++ break; ++ default: ++ AR_DEBUG_ASSERT(FALSE); ++ } ++ ++ pDev->HifMaskUmaskRecvEvent = NULL; ++ ++ /* see if the HIF layer implements the mask/unmask recv events function */ ++ HIFConfigureDevice(pDev->HIFDevice, ++ HIF_DEVICE_GET_RECV_EVENT_MASK_UNMASK_FUNC, ++ &pDev->HifMaskUmaskRecvEvent, ++ sizeof(pDev->HifMaskUmaskRecvEvent)); ++ ++ AR_DEBUG_PRINTF(ATH_DEBUG_TRC,("HIF special overrides : 0x%X , 0x%X\n", ++ (A_UINT32)pDev->GetPendingEventsFunc, (A_UINT32)pDev->HifMaskUmaskRecvEvent)); ++ ++ status = DevDisableInterrupts(pDev); ++ ++ } while (FALSE); ++ ++ if (A_FAILED(status)) { ++ /* make sure handle is cleared */ ++ HIFSetHandle(pDev->HIFDevice, NULL); ++ } ++ ++ return status; ++ ++} ++ ++static A_STATUS DevEnableInterrupts(AR6K_DEVICE *pDev) ++{ ++ A_STATUS status; ++ AR6K_IRQ_ENABLE_REGISTERS regs; ++ ++ LOCK_AR6K(pDev); ++ ++ /* Enable all the interrupts except for the dragon interrupt */ ++ pDev->IrqEnableRegisters.int_status_enable = INT_STATUS_ENABLE_ERROR_SET(0x01) | ++ INT_STATUS_ENABLE_CPU_SET(0x01) | ++ INT_STATUS_ENABLE_COUNTER_SET(0x01); ++ ++ if (NULL == pDev->GetPendingEventsFunc) { ++ pDev->IrqEnableRegisters.int_status_enable |= INT_STATUS_ENABLE_MBOX_DATA_SET(0x01); ++ } else { ++ /* The HIF layer provided us with a pending events function which means that ++ * the detection of pending mbox messages is handled in the HIF layer. ++ * This is the case for the SPI2 interface. ++ * In the normal case we enable MBOX interrupts, for the case ++ * with HIFs that offer this mechanism, we keep these interrupts ++ * masked */ ++ pDev->IrqEnableRegisters.int_status_enable &= ~INT_STATUS_ENABLE_MBOX_DATA_SET(0x01); ++ } ++ ++ ++ /* Set up the CPU Interrupt Status Register */ ++ pDev->IrqEnableRegisters.cpu_int_status_enable = CPU_INT_STATUS_ENABLE_BIT_SET(0x00); ++ ++ /* Set up the Error Interrupt Status Register */ ++ pDev->IrqEnableRegisters.error_status_enable = ++ ERROR_STATUS_ENABLE_RX_UNDERFLOW_SET(0x01) | ++ ERROR_STATUS_ENABLE_TX_OVERFLOW_SET(0x01); ++ ++ /* Set up the Counter Interrupt Status Register (only for debug interrupt to catch fatal errors) */ ++ pDev->IrqEnableRegisters.counter_int_status_enable = ++ COUNTER_INT_STATUS_ENABLE_BIT_SET(AR6K_TARGET_DEBUG_INTR_MASK); ++ ++ /* copy into our temp area */ ++ A_MEMCPY(®s,&pDev->IrqEnableRegisters,AR6K_IRQ_ENABLE_REGS_SIZE); ++ ++ UNLOCK_AR6K(pDev); ++ ++ /* always synchronous */ ++ status = HIFReadWrite(pDev->HIFDevice, ++ INT_STATUS_ENABLE_ADDRESS, ++ ®s.int_status_enable, ++ AR6K_IRQ_ENABLE_REGS_SIZE, ++ HIF_WR_SYNC_BYTE_INC, ++ NULL); ++ ++ if (status != A_OK) { ++ /* Can't write it for some reason */ ++ AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ++ ("Failed to update interrupt control registers err: %d\n", status)); ++ ++ } ++ ++ return status; ++} ++ ++static A_STATUS DevDisableInterrupts(AR6K_DEVICE *pDev) ++{ ++ AR6K_IRQ_ENABLE_REGISTERS regs; ++ ++ LOCK_AR6K(pDev); ++ /* Disable all interrupts */ ++ pDev->IrqEnableRegisters.int_status_enable = 0; ++ pDev->IrqEnableRegisters.cpu_int_status_enable = 0; ++ pDev->IrqEnableRegisters.error_status_enable = 0; ++ pDev->IrqEnableRegisters.counter_int_status_enable = 0; ++ /* copy into our temp area */ ++ A_MEMCPY(®s,&pDev->IrqEnableRegisters,AR6K_IRQ_ENABLE_REGS_SIZE); ++ ++ UNLOCK_AR6K(pDev); ++ ++ /* always synchronous */ ++ return HIFReadWrite(pDev->HIFDevice, ++ INT_STATUS_ENABLE_ADDRESS, ++ ®s.int_status_enable, ++ AR6K_IRQ_ENABLE_REGS_SIZE, ++ HIF_WR_SYNC_BYTE_INC, ++ NULL); ++} ++ ++/* enable device interrupts */ ++A_STATUS DevUnmaskInterrupts(AR6K_DEVICE *pDev) ++{ ++ /* Unmask the host controller interrupts */ ++ HIFUnMaskInterrupt(pDev->HIFDevice); ++ ++ return DevEnableInterrupts(pDev); ++} ++ ++/* disable all device interrupts */ ++A_STATUS DevMaskInterrupts(AR6K_DEVICE *pDev) ++{ ++ A_STATUS status; ++ ++ status = DevDisableInterrupts(pDev); ++ ++ if (A_SUCCESS(status)) { ++ /* Disable the interrupt at the HIF layer */ ++ HIFMaskInterrupt(pDev->HIFDevice); ++ } ++ ++ return status; ++} ++ ++/* callback when our fetch to enable/disable completes */ ++static void DevDoEnableDisableRecvAsyncHandler(void *Context, HTC_PACKET *pPacket) ++{ ++ AR6K_DEVICE *pDev = (AR6K_DEVICE *)Context; ++ ++ AR_DEBUG_PRINTF(ATH_DEBUG_IRQ,("+DevDoEnableDisableRecvAsyncHandler: (dev: 0x%X)\n", (A_UINT32)pDev)); ++ ++ if (A_FAILED(pPacket->Status)) { ++ AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ++ (" Failed to disable receiver, status:%d \n", pPacket->Status)); ++ } ++ /* free this IO packet */ ++ AR6KFreeIOPacket(pDev,pPacket); ++ AR_DEBUG_PRINTF(ATH_DEBUG_IRQ,("-DevDoEnableDisableRecvAsyncHandler \n")); ++} ++ ++/* disable packet reception (used in case the host runs out of buffers) ++ * this is the "override" method when the HIF reports another methods to ++ * disable recv events */ ++static A_STATUS DevDoEnableDisableRecvOverride(AR6K_DEVICE *pDev, A_BOOL EnableRecv, A_BOOL AsyncMode) ++{ ++ A_STATUS status = A_OK; ++ HTC_PACKET *pIOPacket = NULL; ++ ++ AR_DEBUG_PRINTF(ATH_DEBUG_TRC,("DevDoEnableDisableRecvOverride: Enable:%d Mode:%d\n", ++ EnableRecv,AsyncMode)); ++ ++ do { ++ ++ if (AsyncMode) { ++ ++ pIOPacket = AR6KAllocIOPacket(pDev); ++ ++ if (NULL == pIOPacket) { ++ status = A_NO_MEMORY; ++ AR_DEBUG_ASSERT(FALSE); ++ break; ++ } ++ ++ /* stick in our completion routine when the I/O operation completes */ ++ pIOPacket->Completion = DevDoEnableDisableRecvAsyncHandler; ++ pIOPacket->pContext = pDev; ++ ++ /* call the HIF layer override and do this asynchronously */ ++ status = pDev->HifMaskUmaskRecvEvent(pDev->HIFDevice, ++ EnableRecv ? HIF_UNMASK_RECV : HIF_MASK_RECV, ++ pIOPacket); ++ break; ++ } ++ ++ /* if we get here we are doing it synchronously */ ++ status = pDev->HifMaskUmaskRecvEvent(pDev->HIFDevice, ++ EnableRecv ? HIF_UNMASK_RECV : HIF_MASK_RECV, ++ NULL); ++ ++ } while (FALSE); ++ ++ if (A_FAILED(status) && (pIOPacket != NULL)) { ++ AR6KFreeIOPacket(pDev,pIOPacket); ++ } ++ ++ return status; ++} ++ ++/* disable packet reception (used in case the host runs out of buffers) ++ * this is the "normal" method using the interrupt enable registers through ++ * the host I/F */ ++static A_STATUS DevDoEnableDisableRecvNormal(AR6K_DEVICE *pDev, A_BOOL EnableRecv, A_BOOL AsyncMode) ++{ ++ A_STATUS status = A_OK; ++ HTC_PACKET *pIOPacket = NULL; ++ AR6K_IRQ_ENABLE_REGISTERS regs; ++ ++ /* take the lock to protect interrupt enable shadows */ ++ LOCK_AR6K(pDev); ++ ++ if (EnableRecv) { ++ pDev->IrqEnableRegisters.int_status_enable |= INT_STATUS_ENABLE_MBOX_DATA_SET(0x01); ++ } else { ++ pDev->IrqEnableRegisters.int_status_enable &= ~INT_STATUS_ENABLE_MBOX_DATA_SET(0x01); ++ } ++ ++ /* copy into our temp area */ ++ A_MEMCPY(®s,&pDev->IrqEnableRegisters,AR6K_IRQ_ENABLE_REGS_SIZE); ++ UNLOCK_AR6K(pDev); ++ ++ do { ++ ++ if (AsyncMode) { ++ ++ pIOPacket = AR6KAllocIOPacket(pDev); ++ ++ if (NULL == pIOPacket) { ++ status = A_NO_MEMORY; ++ AR_DEBUG_ASSERT(FALSE); ++ break; ++ } ++ ++ /* copy values to write to our async I/O buffer */ ++ A_MEMCPY(pIOPacket->pBuffer,®s,AR6K_IRQ_ENABLE_REGS_SIZE); ++ ++ /* stick in our completion routine when the I/O operation completes */ ++ pIOPacket->Completion = DevDoEnableDisableRecvAsyncHandler; ++ pIOPacket->pContext = pDev; ++ ++ /* write it out asynchronously */ ++ HIFReadWrite(pDev->HIFDevice, ++ INT_STATUS_ENABLE_ADDRESS, ++ pIOPacket->pBuffer, ++ AR6K_IRQ_ENABLE_REGS_SIZE, ++ HIF_WR_ASYNC_BYTE_INC, ++ pIOPacket); ++ break; ++ } ++ ++ /* if we get here we are doing it synchronously */ ++ ++ status = HIFReadWrite(pDev->HIFDevice, ++ INT_STATUS_ENABLE_ADDRESS, ++ ®s.int_status_enable, ++ AR6K_IRQ_ENABLE_REGS_SIZE, ++ HIF_WR_SYNC_BYTE_INC, ++ NULL); ++ ++ } while (FALSE); ++ ++ if (A_FAILED(status) && (pIOPacket != NULL)) { ++ AR6KFreeIOPacket(pDev,pIOPacket); ++ } ++ ++ return status; ++} ++ ++ ++A_STATUS DevStopRecv(AR6K_DEVICE *pDev, A_BOOL AsyncMode) ++{ ++ if (NULL == pDev->HifMaskUmaskRecvEvent) { ++ return DevDoEnableDisableRecvNormal(pDev,FALSE,AsyncMode); ++ } else { ++ return DevDoEnableDisableRecvOverride(pDev,FALSE,AsyncMode); ++ } ++} ++ ++A_STATUS DevEnableRecv(AR6K_DEVICE *pDev, A_BOOL AsyncMode) ++{ ++ if (NULL == pDev->HifMaskUmaskRecvEvent) { ++ return DevDoEnableDisableRecvNormal(pDev,TRUE,AsyncMode); ++ } else { ++ return DevDoEnableDisableRecvOverride(pDev,TRUE,AsyncMode); ++ } ++} ++ ++void DevDumpRegisters(AR6K_IRQ_PROC_REGISTERS *pIrqProcRegs, ++ AR6K_IRQ_ENABLE_REGISTERS *pIrqEnableRegs) ++{ ++ ++ AR_DEBUG_PRINTF(ATH_DEBUG_DUMP, ("\n<------- Register Table -------->\n")); ++ ++ if (pIrqProcRegs != NULL) { ++ AR_DEBUG_PRINTF(ATH_DEBUG_DUMP, ++ ("Int Status: 0x%x\n",pIrqProcRegs->host_int_status)); ++ AR_DEBUG_PRINTF(ATH_DEBUG_DUMP, ++ ("CPU Int Status: 0x%x\n",pIrqProcRegs->cpu_int_status)); ++ AR_DEBUG_PRINTF(ATH_DEBUG_DUMP, ++ ("Error Int Status: 0x%x\n",pIrqProcRegs->error_int_status)); ++ AR_DEBUG_PRINTF(ATH_DEBUG_DUMP, ++ ("Counter Int Status: 0x%x\n",pIrqProcRegs->counter_int_status)); ++ AR_DEBUG_PRINTF(ATH_DEBUG_DUMP, ++ ("Mbox Frame: 0x%x\n",pIrqProcRegs->mbox_frame)); ++ AR_DEBUG_PRINTF(ATH_DEBUG_DUMP, ++ ("Rx Lookahead Valid: 0x%x\n",pIrqProcRegs->rx_lookahead_valid)); ++ AR_DEBUG_PRINTF(ATH_DEBUG_DUMP, ++ ("Rx Lookahead 0: 0x%x\n",pIrqProcRegs->rx_lookahead[0])); ++ AR_DEBUG_PRINTF(ATH_DEBUG_DUMP, ++ ("Rx Lookahead 1: 0x%x\n",pIrqProcRegs->rx_lookahead[1])); ++ } ++ ++ if (pIrqEnableRegs != NULL) { ++ AR_DEBUG_PRINTF(ATH_DEBUG_DUMP, ++ ("Int Status Enable: 0x%x\n",pIrqEnableRegs->int_status_enable)); ++ AR_DEBUG_PRINTF(ATH_DEBUG_DUMP, ++ ("Counter Int Status Enable: 0x%x\n",pIrqEnableRegs->counter_int_status_enable)); ++ AR_DEBUG_PRINTF(ATH_DEBUG_DUMP, ("<------------------------------->\n")); ++ } ++} ++ ++ ++#ifdef MBOXHW_UNIT_TEST ++ ++ ++/* This is a mailbox hardware unit test that must be called in a schedulable context ++ * This test is very simple, it will send a list of buffers with a counting pattern ++ * and the target will invert the data and send the message back ++ * ++ * the unit test has the following constraints: ++ * ++ * The target has at least 8 buffers of 256 bytes each. The host will send ++ * the following pattern of buffers in rapid succession : ++ * ++ * 1 buffer - 128 bytes ++ * 1 buffer - 256 bytes ++ * 1 buffer - 512 bytes ++ * 1 buffer - 1024 bytes ++ * ++ * The host will send the buffers to one mailbox and wait for buffers to be reflected ++ * back from the same mailbox. The target sends the buffers FIFO order. ++ * Once the final buffer has been received for a mailbox, the next mailbox is tested. ++ * ++ * ++ * Note: To simplifythe test , we assume that the chosen buffer sizes ++ * will fall on a nice block pad ++ * ++ * It is expected that higher-order tests will be written to stress the mailboxes using ++ * a message-based protocol (with some performance timming) that can create more ++ * randomness in the packets sent over mailboxes. ++ * ++ * */ ++ ++#define A_ROUND_UP_PWR2(x, align) (((int) (x) + ((align)-1)) & ~((align)-1)) ++ ++#define BUFFER_BLOCK_PAD 128 ++ ++#if 0 ++#define BUFFER1 128 ++#define BUFFER2 256 ++#define BUFFER3 512 ++#define BUFFER4 1024 ++#endif ++ ++#if 1 ++#define BUFFER1 80 ++#define BUFFER2 200 ++#define BUFFER3 444 ++#define BUFFER4 800 ++#endif ++ ++#define TOTAL_BYTES (A_ROUND_UP_PWR2(BUFFER1,BUFFER_BLOCK_PAD) + \ ++ A_ROUND_UP_PWR2(BUFFER2,BUFFER_BLOCK_PAD) + \ ++ A_ROUND_UP_PWR2(BUFFER3,BUFFER_BLOCK_PAD) + \ ++ A_ROUND_UP_PWR2(BUFFER4,BUFFER_BLOCK_PAD) ) ++ ++#define TEST_BYTES (BUFFER1 + BUFFER2 + BUFFER3 + BUFFER4) ++ ++#define TEST_CREDITS_RECV_TIMEOUT 100 ++ ++static A_UINT8 g_Buffer[TOTAL_BYTES]; ++static A_UINT32 g_MailboxAddrs[AR6K_MAILBOXES]; ++static A_UINT32 g_BlockSizes[AR6K_MAILBOXES]; ++ ++#define BUFFER_PROC_LIST_DEPTH 4 ++ ++typedef struct _BUFFER_PROC_LIST{ ++ A_UINT8 *pBuffer; ++ A_UINT32 length; ++}BUFFER_PROC_LIST; ++ ++ ++#define PUSH_BUFF_PROC_ENTRY(pList,len,pCurrpos) \ ++{ \ ++ (pList)->pBuffer = (pCurrpos); \ ++ (pList)->length = (len); \ ++ (pCurrpos) += (len); \ ++ (pList)++; \ ++} ++ ++/* a simple and crude way to send different "message" sizes */ ++static void AssembleBufferList(BUFFER_PROC_LIST *pList) ++{ ++ A_UINT8 *pBuffer = g_Buffer; ++ ++#if BUFFER_PROC_LIST_DEPTH < 4 ++#error "Buffer processing list depth is not deep enough!!" ++#endif ++ ++ PUSH_BUFF_PROC_ENTRY(pList,BUFFER1,pBuffer); ++ PUSH_BUFF_PROC_ENTRY(pList,BUFFER2,pBuffer); ++ PUSH_BUFF_PROC_ENTRY(pList,BUFFER3,pBuffer); ++ PUSH_BUFF_PROC_ENTRY(pList,BUFFER4,pBuffer); ++ ++} ++ ++#define FILL_ZERO TRUE ++#define FILL_COUNTING FALSE ++static void InitBuffers(A_BOOL Zero) ++{ ++ A_UINT16 *pBuffer16 = (A_UINT16 *)g_Buffer; ++ int i; ++ ++ /* fill buffer with 16 bit counting pattern or zeros */ ++ for (i = 0; i < (TOTAL_BYTES / 2) ; i++) { ++ if (!Zero) { ++ pBuffer16[i] = (A_UINT16)i; ++ } else { ++ pBuffer16[i] = 0; ++ } ++ } ++} ++ ++ ++static A_BOOL CheckOneBuffer(A_UINT16 *pBuffer16, int Length) ++{ ++ int i; ++ A_UINT16 startCount; ++ A_BOOL success = TRUE; ++ ++ /* get the starting count */ ++ startCount = pBuffer16[0]; ++ /* invert it, this is the expected value */ ++ startCount = ~startCount; ++ /* scan the buffer and verify */ ++ for (i = 0; i < (Length / 2) ; i++,startCount++) { ++ /* target will invert all the data */ ++ if ((A_UINT16)pBuffer16[i] != (A_UINT16)~startCount) { ++ success = FALSE; ++ AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("Invalid Data Got:0x%X, Expecting:0x%X (offset:%d, total:%d) \n", ++ pBuffer16[i], ((A_UINT16)~startCount), i, Length)); ++ AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("0x%X 0x%X 0x%X 0x%X \n", ++ pBuffer16[i], pBuffer16[i + 1], pBuffer16[i + 2],pBuffer16[i+3])); ++ break; ++ } ++ } ++ ++ return success; ++} ++ ++static A_BOOL CheckBuffers(void) ++{ ++ int i; ++ A_BOOL success = TRUE; ++ BUFFER_PROC_LIST checkList[BUFFER_PROC_LIST_DEPTH]; ++ ++ /* assemble the list */ ++ AssembleBufferList(checkList); ++ ++ /* scan the buffers and verify */ ++ for (i = 0; i < BUFFER_PROC_LIST_DEPTH ; i++) { ++ success = CheckOneBuffer((A_UINT16 *)checkList[i].pBuffer, checkList[i].length); ++ if (!success) { ++ AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("Buffer : 0x%X, Length:%d failed verify \n", ++ (A_UINT32)checkList[i].pBuffer, checkList[i].length)); ++ break; ++ } ++ } ++ ++ return success; ++} ++ ++ /* find the end marker for the last buffer we will be sending */ ++static A_UINT16 GetEndMarker(void) ++{ ++ A_UINT8 *pBuffer; ++ BUFFER_PROC_LIST checkList[BUFFER_PROC_LIST_DEPTH]; ++ ++ /* fill up buffers with the normal counting pattern */ ++ InitBuffers(FILL_COUNTING); ++ ++ /* assemble the list we will be sending down */ ++ AssembleBufferList(checkList); ++ /* point to the last 2 bytes of the last buffer */ ++ pBuffer = &(checkList[BUFFER_PROC_LIST_DEPTH - 1].pBuffer[(checkList[BUFFER_PROC_LIST_DEPTH - 1].length) - 2]); ++ ++ /* the last count in the last buffer is the marker */ ++ return (A_UINT16)pBuffer[0] | ((A_UINT16)pBuffer[1] << 8); ++} ++ ++#define ATH_PRINT_OUT_ZONE ATH_DEBUG_ERR ++ ++/* send the ordered buffers to the target */ ++static A_STATUS SendBuffers(AR6K_DEVICE *pDev, int mbox) ++{ ++ A_STATUS status = A_OK; ++ A_UINT32 request = HIF_WR_SYNC_BLOCK_INC; ++ BUFFER_PROC_LIST sendList[BUFFER_PROC_LIST_DEPTH]; ++ int i; ++ int totalBytes = 0; ++ int paddedLength; ++ int totalwPadding = 0; ++ ++ AR_DEBUG_PRINTF(ATH_PRINT_OUT_ZONE, ("Sending buffers on mailbox : %d \n",mbox)); ++ ++ /* fill buffer with counting pattern */ ++ InitBuffers(FILL_COUNTING); ++ ++ /* assemble the order in which we send */ ++ AssembleBufferList(sendList); ++ ++ for (i = 0; i < BUFFER_PROC_LIST_DEPTH; i++) { ++ ++ /* we are doing block transfers, so we need to pad everything to a block size */ ++ paddedLength = (sendList[i].length + (g_BlockSizes[mbox] - 1)) & ++ (~(g_BlockSizes[mbox] - 1)); ++ ++ /* send each buffer synchronously */ ++ status = HIFReadWrite(pDev->HIFDevice, ++ g_MailboxAddrs[mbox], ++ sendList[i].pBuffer, ++ paddedLength, ++ request, ++ NULL); ++ if (status != A_OK) { ++ break; ++ } ++ totalBytes += sendList[i].length; ++ totalwPadding += paddedLength; ++ } ++ ++ AR_DEBUG_PRINTF(ATH_PRINT_OUT_ZONE, ("Sent %d bytes (%d padded bytes) to mailbox : %d \n",totalBytes,totalwPadding,mbox)); ++ ++ return status; ++} ++ ++/* poll the mailbox credit counter until we get a credit or timeout */ ++static A_STATUS GetCredits(AR6K_DEVICE *pDev, int mbox, int *pCredits) ++{ ++ A_STATUS status = A_OK; ++ int timeout = TEST_CREDITS_RECV_TIMEOUT; ++ A_UINT8 credits = 0; ++ A_UINT32 address; ++ ++ while (TRUE) { ++ ++ /* Read the counter register to get credits, this auto-decrements */ ++ address = COUNT_DEC_ADDRESS + (AR6K_MAILBOXES + mbox) * 4; ++ status = HIFReadWrite(pDev->HIFDevice, address, &credits, sizeof(credits), ++ HIF_RD_SYNC_BYTE_FIX, NULL); ++ if (status != A_OK) { ++ AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ++ ("Unable to decrement the command credit count register (mbox=%d)\n",mbox)); ++ status = A_ERROR; ++ break; ++ } ++ ++ if (credits) { ++ break; ++ } ++ ++ timeout--; ++ ++ if (timeout <= 0) { ++ AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ++ (" Timeout reading credit registers (mbox=%d, address:0x%X) \n",mbox,address)); ++ status = A_ERROR; ++ break; ++ } ++ ++ /* delay a little, target may not be ready */ ++ msleep(1000); ++ ++ } ++ ++ if (status == A_OK) { ++ *pCredits = credits; ++ } ++ ++ return status; ++} ++ ++ ++/* wait for the buffers to come back */ ++static A_STATUS RecvBuffers(AR6K_DEVICE *pDev, int mbox) ++{ ++ A_STATUS status = A_OK; ++ A_UINT32 request = HIF_RD_SYNC_BLOCK_INC; ++ BUFFER_PROC_LIST recvList[BUFFER_PROC_LIST_DEPTH]; ++ int curBuffer; ++ int credits; ++ int i; ++ int totalBytes = 0; ++ int paddedLength; ++ int totalwPadding = 0; ++ ++ AR_DEBUG_PRINTF(ATH_PRINT_OUT_ZONE, ("Waiting for buffers on mailbox : %d \n",mbox)); ++ ++ /* zero the buffers */ ++ InitBuffers(FILL_ZERO); ++ ++ /* assemble the order in which we should receive */ ++ AssembleBufferList(recvList); ++ ++ curBuffer = 0; ++ ++ while (curBuffer < BUFFER_PROC_LIST_DEPTH) { ++ ++ /* get number of buffers that have been completed, this blocks ++ * until we get at least 1 credit or it times out */ ++ status = GetCredits(pDev, mbox, &credits); ++ ++ if (status != A_OK) { ++ break; ++ } ++ ++ AR_DEBUG_PRINTF(ATH_PRINT_OUT_ZONE, ("Got %d messages on mailbox : %d \n",credits, mbox)); ++ ++ /* get all the buffers that are sitting on the queue */ ++ for (i = 0; i < credits; i++) { ++ AR_DEBUG_ASSERT(curBuffer < BUFFER_PROC_LIST_DEPTH); ++ /* recv the current buffer synchronously, the buffers should come back in ++ * order... with padding applied by the target */ ++ paddedLength = (recvList[curBuffer].length + (g_BlockSizes[mbox] - 1)) & ++ (~(g_BlockSizes[mbox] - 1)); ++ ++ status = HIFReadWrite(pDev->HIFDevice, ++ g_MailboxAddrs[mbox], ++ recvList[curBuffer].pBuffer, ++ paddedLength, ++ request, ++ NULL); ++ if (status != A_OK) { ++ AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("Failed to read %d bytes on mailbox:%d : address:0x%X \n", ++ recvList[curBuffer].length, mbox, g_MailboxAddrs[mbox])); ++ break; ++ } ++ ++ totalwPadding += paddedLength; ++ totalBytes += recvList[curBuffer].length; ++ curBuffer++; ++ } ++ ++ if (status != A_OK) { ++ break; ++ } ++ /* go back and get some more */ ++ credits = 0; ++ } ++ ++ if (totalBytes != TEST_BYTES) { ++ AR_DEBUG_ASSERT(FALSE); ++ } else { ++ AR_DEBUG_PRINTF(ATH_PRINT_OUT_ZONE, ("Got all buffers on mbox:%d total recv :%d (w/Padding : %d) \n", ++ mbox, totalBytes, totalwPadding)); ++ } ++ ++ return status; ++ ++ ++} ++ ++static A_STATUS DoOneMboxHWTest(AR6K_DEVICE *pDev, int mbox) ++{ ++ A_STATUS status; ++ ++ do { ++ /* send out buffers */ ++ status = SendBuffers(pDev,mbox); ++ ++ if (status != A_OK) { ++ AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("Sending buffers Failed : %d mbox:%d\n",status,mbox)); ++ break; ++ } ++ ++ /* go get them, this will block */ ++ status = RecvBuffers(pDev, mbox); ++ ++ if (status != A_OK) { ++ AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("Recv buffers Failed : %d mbox:%d\n",status,mbox)); ++ break; ++ } ++ ++ /* check the returned data patterns */ ++ if (!CheckBuffers()) { ++ AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("Buffer Verify Failed : mbox:%d\n",mbox)); ++ status = A_ERROR; ++ break; ++ } ++ ++ AR_DEBUG_PRINTF(ATH_PRINT_OUT_ZONE, (" Send/Recv success! mailbox : %d \n",mbox)); ++ ++ } while (FALSE); ++ ++ return status; ++} ++ ++/* here is where the test starts */ ++A_STATUS DoMboxHWTest(AR6K_DEVICE *pDev) ++{ ++ int i; ++ A_STATUS status; ++ int credits = 0; ++ A_UINT8 params[4]; ++ int numBufs; ++ int bufferSize; ++ A_UINT16 temp; ++ ++ ++ AR_DEBUG_PRINTF(ATH_PRINT_OUT_ZONE, (" DoMboxHWTest START - \n")); ++ ++ do { ++ /* get the addresses for all 4 mailboxes */ ++ status = HIFConfigureDevice(pDev->HIFDevice, HIF_DEVICE_GET_MBOX_ADDR, ++ g_MailboxAddrs, sizeof(g_MailboxAddrs)); ++ ++ if (status != A_OK) { ++ AR_DEBUG_ASSERT(FALSE); ++ break; ++ } ++ ++ /* get the block sizes */ ++ status = HIFConfigureDevice(pDev->HIFDevice, HIF_DEVICE_GET_MBOX_BLOCK_SIZE, ++ g_BlockSizes, sizeof(g_BlockSizes)); ++ ++ if (status != A_OK) { ++ AR_DEBUG_ASSERT(FALSE); ++ break; ++ } ++ ++ /* note, the HIF layer usually reports mbox 0 to have a block size of ++ * 1, but our test wants to run in block-mode for all mailboxes, so we treat all mailboxes ++ * the same. */ ++ g_BlockSizes[0] = g_BlockSizes[1]; ++ AR_DEBUG_PRINTF(ATH_PRINT_OUT_ZONE, ("Block Size to use: %d \n",g_BlockSizes[0])); ++ ++ if (g_BlockSizes[1] > BUFFER_BLOCK_PAD) { ++ AR_DEBUG_PRINTF(ATH_PRINT_OUT_ZONE, ("%d Block size is too large for buffer pad %d\n", ++ g_BlockSizes[1], BUFFER_BLOCK_PAD)); ++ break; ++ } ++ ++ AR_DEBUG_PRINTF(ATH_PRINT_OUT_ZONE, ("Waiting for target.... \n")); ++ ++ /* the target lets us know it is ready by giving us 1 credit on ++ * mailbox 0 */ ++ status = GetCredits(pDev, 0, &credits); ++ ++ if (status != A_OK) { ++ AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("Failed to wait for target ready \n")); ++ break; ++ } ++ ++ AR_DEBUG_PRINTF(ATH_PRINT_OUT_ZONE, ("Target is ready ...\n")); ++ ++ /* read the first 4 scratch registers */ ++ status = HIFReadWrite(pDev->HIFDevice, ++ SCRATCH_ADDRESS, ++ params, ++ 4, ++ HIF_RD_SYNC_BYTE_INC, ++ NULL); ++ ++ if (status != A_OK) { ++ AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("Failed to wait get parameters \n")); ++ break; ++ } ++ ++ numBufs = params[0]; ++ bufferSize = (int)(((A_UINT16)params[2] << 8) | (A_UINT16)params[1]); ++ ++ AR_DEBUG_PRINTF(ATH_PRINT_OUT_ZONE, ++ ("Target parameters: bufs per mailbox:%d, buffer size:%d bytes (total space: %d, minimum required space (w/padding): %d) \n", ++ numBufs, bufferSize, (numBufs * bufferSize), TOTAL_BYTES)); ++ ++ if ((numBufs * bufferSize) < TOTAL_BYTES) { ++ AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("Not Enough buffer space to run test! need:%d, got:%d \n", ++ TOTAL_BYTES, (numBufs*bufferSize))); ++ status = A_ERROR; ++ break; ++ } ++ ++ temp = GetEndMarker(); ++ ++ status = HIFReadWrite(pDev->HIFDevice, ++ SCRATCH_ADDRESS + 4, ++ (A_UINT8 *)&temp, ++ 2, ++ HIF_WR_SYNC_BYTE_INC, ++ NULL); ++ ++ if (status != A_OK) { ++ AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("Failed to write end marker \n")); ++ break; ++ } ++ ++ AR_DEBUG_PRINTF(ATH_PRINT_OUT_ZONE, ("End Marker: 0x%X \n",temp)); ++ ++ temp = (A_UINT16)g_BlockSizes[1]; ++ /* convert to a mask */ ++ temp = temp - 1; ++ status = HIFReadWrite(pDev->HIFDevice, ++ SCRATCH_ADDRESS + 6, ++ (A_UINT8 *)&temp, ++ 2, ++ HIF_WR_SYNC_BYTE_INC, ++ NULL); ++ ++ if (status != A_OK) { ++ AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("Failed to write block mask \n")); ++ break; ++ } ++ ++ AR_DEBUG_PRINTF(ATH_PRINT_OUT_ZONE, ("Set Block Mask: 0x%X \n",temp)); ++ ++ /* execute the test on each mailbox */ ++ for (i = 0; i < AR6K_MAILBOXES; i++) { ++ status = DoOneMboxHWTest(pDev, i); ++ if (status != A_OK) { ++ break; ++ } ++ } ++ ++ } while (FALSE); ++ ++ if (status == A_OK) { ++ AR_DEBUG_PRINTF(ATH_PRINT_OUT_ZONE, (" DoMboxHWTest DONE - SUCCESS! - \n")); ++ } else { ++ AR_DEBUG_PRINTF(ATH_PRINT_OUT_ZONE, (" DoMboxHWTest DONE - FAILED! - \n")); ++ } ++ /* don't let HTC_Start continue, the target is actually not running any HTC code */ ++ return A_ERROR; ++} ++#endif ++ ++ ++ +diff -ruN --exclude='*.orig' --exclude='*.rej' linux-2.6.29-rc3.owrt/drivers/ar6000/htc/ar6k_events.c linux-2.6.29-rc3.owrt.om/drivers/ar6000/htc/ar6k_events.c +--- linux-2.6.29-rc3.owrt/drivers/ar6000/htc/ar6k_events.c 1970-01-01 01:00:00.000000000 +0100 ++++ linux-2.6.29-rc3.owrt.om/drivers/ar6000/htc/ar6k_events.c 2009-05-10 22:27:59.000000000 +0200 +@@ -0,0 +1,638 @@ ++/* ++ * AR6K Driver layer event handling (i.e. interrupts, message polling) ++ * ++ * Copyright (c) 2007 Atheros Communications Inc. ++ * All rights reserved. ++ * ++ * ++ * 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; ++ * ++ * Software distributed under the License is distributed on an "AS ++ * IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or ++ * implied. See the License for the specific language governing ++ * rights and limitations under the License. ++ * ++ * ++ * ++ */ ++#include "a_config.h" ++#include "athdefs.h" ++#include "a_types.h" ++#include "AR6Khwreg.h" ++#include "a_osapi.h" ++#include "a_debug.h" ++#include "hif.h" ++#include "htc_packet.h" ++#include "ar6k.h" ++ ++extern void AR6KFreeIOPacket(AR6K_DEVICE *pDev, HTC_PACKET *pPacket); ++extern HTC_PACKET *AR6KAllocIOPacket(AR6K_DEVICE *pDev); ++ ++static A_STATUS DevServiceDebugInterrupt(AR6K_DEVICE *pDev); ++ ++#define DELAY_PER_INTERVAL_MS 10 /* 10 MS delay per polling interval */ ++ ++/* completion routine for ALL HIF layer async I/O */ ++A_STATUS DevRWCompletionHandler(void *context, A_STATUS status) ++{ ++ HTC_PACKET *pPacket = (HTC_PACKET *)context; ++ ++ COMPLETE_HTC_PACKET(pPacket,status); ++ ++ return A_OK; ++} ++ ++/* mailbox recv message polling */ ++A_STATUS DevPollMboxMsgRecv(AR6K_DEVICE *pDev, ++ A_UINT32 *pLookAhead, ++ int TimeoutMS) ++{ ++ A_STATUS status = A_OK; ++ int timeout = TimeoutMS/DELAY_PER_INTERVAL_MS; ++ ++ AR_DEBUG_ASSERT(timeout > 0); ++ ++ AR_DEBUG_PRINTF(ATH_DEBUG_RECV,("+DevPollMboxMsgRecv \n")); ++ ++ while (TRUE) { ++ ++ if (pDev->GetPendingEventsFunc != NULL) ++ { ++ ++ HIF_PENDING_EVENTS_INFO events; ++ ++ /* the HIF layer uses a special mechanism to get events, do this ++ * synchronously */ ++ status = pDev->GetPendingEventsFunc(pDev->HIFDevice, ++ &events, ++ NULL); ++ if (A_FAILED(status)) ++ { ++ AR_DEBUG_PRINTF(ATH_DEBUG_ERR,("Failed to get pending events \n")); ++ break; ++ } ++ ++ if (events.Events & HIF_RECV_MSG_AVAIL) ++ { ++ /* there is a message available, the lookahead should be valid now */ ++ *pLookAhead = events.LookAhead; ++ ++ break; ++ } ++ } ++ else ++ { ++ ++ /* this is the standard HIF way.... */ ++ /* load the register table */ ++ status = HIFReadWrite(pDev->HIFDevice, ++ HOST_INT_STATUS_ADDRESS, ++ (A_UINT8 *)&pDev->IrqProcRegisters, ++ AR6K_IRQ_PROC_REGS_SIZE, ++ HIF_RD_SYNC_BYTE_INC, ++ NULL); ++ ++ if (A_FAILED(status)) ++ { ++ AR_DEBUG_PRINTF(ATH_DEBUG_ERR,("Failed to read register table \n")); ++ break; ++ } ++ ++ /* check for MBOX data and valid lookahead */ ++ if (pDev->IrqProcRegisters.host_int_status & (1 << HTC_MAILBOX)) ++ { ++ if (pDev->IrqProcRegisters.rx_lookahead_valid & (1 << HTC_MAILBOX)) ++ { ++ /* mailbox has a message and the look ahead is valid */ ++ *pLookAhead = pDev->IrqProcRegisters.rx_lookahead[HTC_MAILBOX]; ++ break; ++ } ++ } ++ ++ } ++ ++ timeout--; ++ ++ if (timeout <= 0) ++ { ++ AR_DEBUG_PRINTF(ATH_DEBUG_ERR, (" Timeout waiting for recv message \n")); ++ status = A_ERROR; ++ ++ /* check if the target asserted */ ++ if ( pDev->IrqProcRegisters.counter_int_status & AR6K_TARGET_DEBUG_INTR_MASK) { ++ /* target signaled an assert, process this pending interrupt ++ * this will call the target failure handler */ ++ DevServiceDebugInterrupt(pDev); ++ } ++ ++ break; ++ } ++ ++ /* delay a little */ ++ msleep(DELAY_PER_INTERVAL_MS); ++ AR_DEBUG_PRINTF(ATH_DEBUG_RECV,(" Retry Mbox Poll : %d \n",timeout)); ++ } ++ ++ AR_DEBUG_PRINTF(ATH_DEBUG_RECV,("-DevPollMboxMsgRecv \n")); ++ ++ return status; ++} ++ ++static A_STATUS DevServiceCPUInterrupt(AR6K_DEVICE *pDev) ++{ ++ A_STATUS status; ++ A_UINT8 cpu_int_status; ++ A_UINT8 regBuffer[4]; ++ ++ AR_DEBUG_PRINTF(ATH_DEBUG_IRQ, ("CPU Interrupt\n")); ++ cpu_int_status = pDev->IrqProcRegisters.cpu_int_status & ++ pDev->IrqEnableRegisters.cpu_int_status_enable; ++ AR_DEBUG_ASSERT(cpu_int_status); ++ AR_DEBUG_PRINTF(ATH_DEBUG_IRQ, ++ ("Valid interrupt source(s) in CPU_INT_STATUS: 0x%x\n", ++ cpu_int_status)); ++ ++ /* Clear the interrupt */ ++ pDev->IrqProcRegisters.cpu_int_status &= ~cpu_int_status; /* W1C */ ++ ++ /* set up the register transfer buffer to hit the register 4 times , this is done ++ * to make the access 4-byte aligned to mitigate issues with host bus interconnects that ++ * restrict bus transfer lengths to be a multiple of 4-bytes */ ++ ++ /* set W1C value to clear the interrupt, this hits the register first */ ++ regBuffer[0] = cpu_int_status; ++ /* the remaining 4 values are set to zero which have no-effect */ ++ regBuffer[1] = 0; ++ regBuffer[2] = 0; ++ regBuffer[3] = 0; ++ ++ status = HIFReadWrite(pDev->HIFDevice, ++ CPU_INT_STATUS_ADDRESS, ++ regBuffer, ++ 4, ++ HIF_WR_SYNC_BYTE_FIX, ++ NULL); ++ ++ AR_DEBUG_ASSERT(status == A_OK); ++ return status; ++} ++ ++ ++static A_STATUS DevServiceErrorInterrupt(AR6K_DEVICE *pDev) ++{ ++ A_STATUS status; ++ A_UINT8 error_int_status; ++ A_UINT8 regBuffer[4]; ++ ++ AR_DEBUG_PRINTF(ATH_DEBUG_IRQ, ("Error Interrupt\n")); ++ error_int_status = pDev->IrqProcRegisters.error_int_status & 0x0F; ++ AR_DEBUG_ASSERT(error_int_status); ++ AR_DEBUG_PRINTF(ATH_DEBUG_IRQ, ++ ("Valid interrupt source(s) in ERROR_INT_STATUS: 0x%x\n", ++ error_int_status)); ++ ++ if (ERROR_INT_STATUS_WAKEUP_GET(error_int_status)) { ++ /* Wakeup */ ++ AR_DEBUG_PRINTF(ATH_DEBUG_IRQ, ("Error : Wakeup\n")); ++ } ++ ++ if (ERROR_INT_STATUS_RX_UNDERFLOW_GET(error_int_status)) { ++ /* Rx Underflow */ ++ AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("Error : Rx Underflow\n")); ++ } ++ ++ if (ERROR_INT_STATUS_TX_OVERFLOW_GET(error_int_status)) { ++ /* Tx Overflow */ ++ AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("Error : Tx Overflow\n")); ++ } ++ ++ /* Clear the interrupt */ ++ pDev->IrqProcRegisters.error_int_status &= ~error_int_status; /* W1C */ ++ ++ /* set up the register transfer buffer to hit the register 4 times , this is done ++ * to make the access 4-byte aligned to mitigate issues with host bus interconnects that ++ * restrict bus transfer lengths to be a multiple of 4-bytes */ ++ ++ /* set W1C value to clear the interrupt, this hits the register first */ ++ regBuffer[0] = error_int_status; ++ /* the remaining 4 values are set to zero which have no-effect */ ++ regBuffer[1] = 0; ++ regBuffer[2] = 0; ++ regBuffer[3] = 0; ++ ++ status = HIFReadWrite(pDev->HIFDevice, ++ ERROR_INT_STATUS_ADDRESS, ++ regBuffer, ++ 4, ++ HIF_WR_SYNC_BYTE_FIX, ++ NULL); ++ ++ AR_DEBUG_ASSERT(status == A_OK); ++ return status; ++} ++ ++static A_STATUS DevServiceDebugInterrupt(AR6K_DEVICE *pDev) ++{ ++ A_UINT32 dummy; ++ A_STATUS status; ++ ++ /* Send a target failure event to the application */ ++ AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("Target debug interrupt\n")); ++ ++ if (pDev->TargetFailureCallback != NULL) { ++ pDev->TargetFailureCallback(pDev->HTCContext); ++ } ++ ++ /* clear the interrupt , the debug error interrupt is ++ * counter 0 */ ++ /* read counter to clear interrupt */ ++ status = HIFReadWrite(pDev->HIFDevice, ++ COUNT_DEC_ADDRESS, ++ (A_UINT8 *)&dummy, ++ 4, ++ HIF_RD_SYNC_BYTE_INC, ++ NULL); ++ ++ AR_DEBUG_ASSERT(status == A_OK); ++ return status; ++} ++ ++static A_STATUS DevServiceCounterInterrupt(AR6K_DEVICE *pDev) ++{ ++ A_UINT8 counter_int_status; ++ ++ AR_DEBUG_PRINTF(ATH_DEBUG_IRQ, ("Counter Interrupt\n")); ++ ++ counter_int_status = pDev->IrqProcRegisters.counter_int_status & ++ pDev->IrqEnableRegisters.counter_int_status_enable; ++ ++ AR_DEBUG_ASSERT(counter_int_status); ++ AR_DEBUG_PRINTF(ATH_DEBUG_IRQ, ++ ("Valid interrupt source(s) in COUNTER_INT_STATUS: 0x%x\n", ++ counter_int_status)); ++ ++ /* Check if the debug interrupt is pending */ ++ if (counter_int_status & AR6K_TARGET_DEBUG_INTR_MASK) { ++ return DevServiceDebugInterrupt(pDev); ++ } ++ ++ return A_OK; ++} ++ ++/* callback when our fetch to get interrupt status registers completes */ ++static void DevGetEventAsyncHandler(void *Context, HTC_PACKET *pPacket) ++{ ++ AR6K_DEVICE *pDev = (AR6K_DEVICE *)Context; ++ A_UINT32 lookAhead = 0; ++ A_BOOL otherInts = FALSE; ++ ++ AR_DEBUG_PRINTF(ATH_DEBUG_IRQ,("+DevGetEventAsyncHandler: (dev: 0x%X)\n", (A_UINT32)pDev)); ++ ++ do { ++ ++ if (A_FAILED(pPacket->Status)) { ++ AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ++ (" GetEvents I/O request failed, status:%d \n", pPacket->Status)); ++ /* bail out, don't unmask HIF interrupt */ ++ break; ++ } ++ ++ if (pDev->GetPendingEventsFunc != NULL) { ++ /* the HIF layer collected the information for us */ ++ HIF_PENDING_EVENTS_INFO *pEvents = (HIF_PENDING_EVENTS_INFO *)pPacket->pBuffer; ++ if (pEvents->Events & HIF_RECV_MSG_AVAIL) { ++ lookAhead = pEvents->LookAhead; ++ if (0 == lookAhead) { ++ AR_DEBUG_PRINTF(ATH_DEBUG_ERR,(" DevGetEventAsyncHandler1, lookAhead is zero! \n")); ++ } ++ } ++ if (pEvents->Events & HIF_OTHER_EVENTS) { ++ otherInts = TRUE; ++ } ++ } else { ++ /* standard interrupt table handling.... */ ++ AR6K_IRQ_PROC_REGISTERS *pReg = (AR6K_IRQ_PROC_REGISTERS *)pPacket->pBuffer; ++ A_UINT8 host_int_status; ++ ++ host_int_status = pReg->host_int_status & pDev->IrqEnableRegisters.int_status_enable; ++ ++ if (host_int_status & (1 << HTC_MAILBOX)) { ++ host_int_status &= ~(1 << HTC_MAILBOX); ++ if (pReg->rx_lookahead_valid & (1 << HTC_MAILBOX)) { ++ /* mailbox has a message and the look ahead is valid */ ++ lookAhead = pReg->rx_lookahead[HTC_MAILBOX]; ++ if (0 == lookAhead) { ++ AR_DEBUG_PRINTF(ATH_DEBUG_ERR,(" DevGetEventAsyncHandler2, lookAhead is zero! \n")); ++ } ++ } ++ } ++ ++ if (host_int_status) { ++ /* there are other interrupts to handle */ ++ otherInts = TRUE; ++ } ++ } ++ ++ if (otherInts || (lookAhead == 0)) { ++ /* if there are other interrupts to process, we cannot do this in the async handler so ++ * ack the interrupt which will cause our sync handler to run again ++ * if however there are no more messages, we can now ack the interrupt */ ++ AR_DEBUG_PRINTF(ATH_DEBUG_IRQ, ++ (" Acking interrupt from DevGetEventAsyncHandler (otherints:%d, lookahead:0x%X)\n", ++ otherInts, lookAhead)); ++ HIFAckInterrupt(pDev->HIFDevice); ++ } else { ++ AR_DEBUG_PRINTF(ATH_DEBUG_IRQ, ++ (" DevGetEventAsyncHandler : detected another message, lookahead :0x%X \n", ++ lookAhead)); ++ /* lookahead is non-zero and there are no other interrupts to service, ++ * go get the next message */ ++ pDev->MessagePendingCallback(pDev->HTCContext, lookAhead, NULL); ++ } ++ ++ } while (FALSE); ++ ++ /* free this IO packet */ ++ AR6KFreeIOPacket(pDev,pPacket); ++ AR_DEBUG_PRINTF(ATH_DEBUG_IRQ,("-DevGetEventAsyncHandler \n")); ++} ++ ++/* called by the HTC layer when it wants us to check if the device has any more pending ++ * recv messages, this starts off a series of async requests to read interrupt registers */ ++A_STATUS DevCheckPendingRecvMsgsAsync(void *context) ++{ ++ AR6K_DEVICE *pDev = (AR6K_DEVICE *)context; ++ A_STATUS status = A_OK; ++ HTC_PACKET *pIOPacket; ++ ++ /* this is called in an ASYNC only context, we may NOT block, sleep or call any apis that can ++ * cause us to switch contexts */ ++ ++ AR_DEBUG_PRINTF(ATH_DEBUG_IRQ,("+DevCheckPendingRecvMsgsAsync: (dev: 0x%X)\n", (A_UINT32)pDev)); ++ ++ do { ++ ++ if (HIF_DEVICE_IRQ_SYNC_ONLY == pDev->HifIRQProcessingMode) { ++ /* break the async processing chain right here, no need to continue. ++ * The DevDsrHandler() will handle things in a loop when things are driven ++ * synchronously */ ++ break; ++ } ++ /* first allocate one of our HTC packets we created for async I/O ++ * we reuse HTC packet definitions so that we can use the completion mechanism ++ * in DevRWCompletionHandler() */ ++ pIOPacket = AR6KAllocIOPacket(pDev); ++ ++ if (NULL == pIOPacket) { ++ /* there should be only 1 asynchronous request out at a time to read these registers ++ * so this should actually never happen */ ++ status = A_NO_MEMORY; ++ AR_DEBUG_ASSERT(FALSE); ++ break; ++ } ++ ++ /* stick in our completion routine when the I/O operation completes */ ++ pIOPacket->Completion = DevGetEventAsyncHandler; ++ pIOPacket->pContext = pDev; ++ ++ if (pDev->GetPendingEventsFunc) { ++ /* HIF layer has it's own mechanism, pass the IO to it.. */ ++ status = pDev->GetPendingEventsFunc(pDev->HIFDevice, ++ (HIF_PENDING_EVENTS_INFO *)pIOPacket->pBuffer, ++ pIOPacket); ++ ++ } else { ++ /* standard way, read the interrupt register table asynchronously again */ ++ status = HIFReadWrite(pDev->HIFDevice, ++ HOST_INT_STATUS_ADDRESS, ++ pIOPacket->pBuffer, ++ AR6K_IRQ_PROC_REGS_SIZE, ++ HIF_RD_ASYNC_BYTE_INC, ++ pIOPacket); ++ } ++ ++ AR_DEBUG_PRINTF(ATH_DEBUG_IRQ,(" Async IO issued to get interrupt status...\n")); ++ } while (FALSE); ++ ++ AR_DEBUG_PRINTF(ATH_DEBUG_IRQ,("-DevCheckPendingRecvMsgsAsync \n")); ++ ++ return status; ++} ++ ++/* process pending interrupts synchronously */ ++static A_STATUS ProcessPendingIRQs(AR6K_DEVICE *pDev, A_BOOL *pDone, A_BOOL *pASyncProcessing) ++{ ++ A_STATUS status = A_OK; ++ A_UINT8 host_int_status = 0; ++ A_UINT32 lookAhead = 0; ++ ++ AR_DEBUG_PRINTF(ATH_DEBUG_IRQ,("+ProcessPendingIRQs: (dev: 0x%X)\n", (A_UINT32)pDev)); ++ ++ /*** NOTE: the HIF implementation guarantees that the context of this call allows ++ * us to perform SYNCHRONOUS I/O, that is we can block, sleep or call any API that ++ * can block or switch thread/task ontexts. ++ * This is a fully schedulable context. ++ * */ ++ do { ++ ++ if (pDev->GetPendingEventsFunc != NULL) { ++ HIF_PENDING_EVENTS_INFO events; ++ ++ /* the HIF layer uses a special mechanism to get events ++ * get this synchronously */ ++ status = pDev->GetPendingEventsFunc(pDev->HIFDevice, ++ &events, ++ NULL); ++ ++ if (A_FAILED(status)) { ++ break; ++ } ++ ++ if (events.Events & HIF_RECV_MSG_AVAIL) { ++ lookAhead = events.LookAhead; ++ if (0 == lookAhead) { ++ AR_DEBUG_PRINTF(ATH_DEBUG_ERR,(" ProcessPendingIRQs1 lookAhead is zero! \n")); ++ } ++ } ++ ++ if (!(events.Events & HIF_OTHER_EVENTS) || ++ !(pDev->IrqEnableRegisters.int_status_enable & OTHER_INTS_ENABLED)) { ++ /* no need to read the register table, no other interesting interrupts. ++ * Some interfaces (like SPI) can shadow interrupt sources without ++ * requiring the host to do a full table read */ ++ break; ++ } ++ ++ /* otherwise fall through and read the register table */ ++ } ++ ++ /* ++ * Read the first 28 bytes of the HTC register table. This will yield us ++ * the value of different int status registers and the lookahead ++ * registers. ++ * length = sizeof(int_status) + sizeof(cpu_int_status) + ++ * sizeof(error_int_status) + sizeof(counter_int_status) + ++ * sizeof(mbox_frame) + sizeof(rx_lookahead_valid) + ++ * sizeof(hole) + sizeof(rx_lookahead) + ++ * sizeof(int_status_enable) + sizeof(cpu_int_status_enable) + ++ * sizeof(error_status_enable) + ++ * sizeof(counter_int_status_enable); ++ * ++ */ ++ status = HIFReadWrite(pDev->HIFDevice, ++ HOST_INT_STATUS_ADDRESS, ++ (A_UINT8 *)&pDev->IrqProcRegisters, ++ AR6K_IRQ_PROC_REGS_SIZE, ++ HIF_RD_SYNC_BYTE_INC, ++ NULL); ++ ++ if (A_FAILED(status)) { ++ break; ++ } ++ ++ if (AR_DEBUG_LVL_CHECK(ATH_DEBUG_IRQ)) { ++ DevDumpRegisters(&pDev->IrqProcRegisters, ++ &pDev->IrqEnableRegisters); ++ } ++ ++ /* Update only those registers that are enabled */ ++ host_int_status = pDev->IrqProcRegisters.host_int_status & ++ pDev->IrqEnableRegisters.int_status_enable; ++ ++ if (NULL == pDev->GetPendingEventsFunc) { ++ /* only look at mailbox status if the HIF layer did not provide this function, ++ * on some HIF interfaces reading the RX lookahead is not valid to do */ ++ if (host_int_status & (1 << HTC_MAILBOX)) { ++ /* mask out pending mailbox value, we use "lookAhead" as the real flag for ++ * mailbox processing below */ ++ host_int_status &= ~(1 << HTC_MAILBOX); ++ if (pDev->IrqProcRegisters.rx_lookahead_valid & (1 << HTC_MAILBOX)) { ++ /* mailbox has a message and the look ahead is valid */ ++ lookAhead = pDev->IrqProcRegisters.rx_lookahead[HTC_MAILBOX]; ++ if (0 == lookAhead) { ++ AR_DEBUG_PRINTF(ATH_DEBUG_ERR,(" ProcessPendingIRQs2, lookAhead is zero! \n")); ++ } ++ } ++ } ++ } else { ++ /* not valid to check if the HIF has another mechanism for reading mailbox pending status*/ ++ host_int_status &= ~(1 << HTC_MAILBOX); ++ } ++ ++ } while (FALSE); ++ ++ ++ do { ++ ++ /* did the interrupt status fetches succeed? */ ++ if (A_FAILED(status)) { ++ break; ++ } ++ ++ if ((0 == host_int_status) && (0 == lookAhead)) { ++ /* nothing to process, the caller can use this to break out of a loop */ ++ *pDone = TRUE; ++ break; ++ } ++ ++ if (lookAhead != 0) { ++ AR_DEBUG_PRINTF(ATH_DEBUG_IRQ,("Pending mailbox message, LookAhead: 0x%X\n",lookAhead)); ++ /* Mailbox Interrupt, the HTC layer may issue async requests to empty the ++ * mailbox... ++ * When emptying the recv mailbox we use the async handler above called from the ++ * completion routine of the callers read request. This can improve performance ++ * by reducing context switching when we rapidly pull packets */ ++ status = pDev->MessagePendingCallback(pDev->HTCContext, lookAhead, pASyncProcessing); ++ if (A_FAILED(status)) { ++ break; ++ } ++ } ++ ++ /* now handle the rest of them */ ++ AR_DEBUG_PRINTF(ATH_DEBUG_IRQ, ++ (" Valid interrupt source(s) for OTHER interrupts: 0x%x\n", ++ host_int_status)); ++ ++ if (HOST_INT_STATUS_CPU_GET(host_int_status)) { ++ /* CPU Interrupt */ ++ status = DevServiceCPUInterrupt(pDev); ++ if (A_FAILED(status)){ ++ break; ++ } ++ } ++ ++ if (HOST_INT_STATUS_ERROR_GET(host_int_status)) { ++ /* Error Interrupt */ ++ status = DevServiceErrorInterrupt(pDev); ++ if (A_FAILED(status)){ ++ break; ++ } ++ } ++ ++ if (HOST_INT_STATUS_COUNTER_GET(host_int_status)) { ++ /* Counter Interrupt */ ++ status = DevServiceCounterInterrupt(pDev); ++ if (A_FAILED(status)){ ++ break; ++ } ++ } ++ ++ } while (FALSE); ++ ++ AR_DEBUG_PRINTF(ATH_DEBUG_IRQ,("-ProcessPendingIRQs: (done:%d, async:%d) status=%d \n", ++ *pDone, *pASyncProcessing, status)); ++ ++ return status; ++} ++ ++ ++/* Synchronousinterrupt handler, this handler kicks off all interrupt processing.*/ ++A_STATUS DevDsrHandler(void *context) ++{ ++ AR6K_DEVICE *pDev = (AR6K_DEVICE *)context; ++ A_STATUS status = A_OK; ++ A_BOOL done = FALSE; ++ A_BOOL asyncProc = FALSE; ++ ++ AR_DEBUG_PRINTF(ATH_DEBUG_IRQ,("+DevDsrHandler: (dev: 0x%X)\n", (A_UINT32)pDev)); ++ ++ ++ while (!done) { ++ status = ProcessPendingIRQs(pDev, &done, &asyncProc); ++ if (A_FAILED(status)) { ++ break; ++ } ++ ++ if (HIF_DEVICE_IRQ_SYNC_ONLY == pDev->HifIRQProcessingMode) { ++ /* the HIF layer does not allow async IRQ processing, override the asyncProc flag */ ++ asyncProc = FALSE; ++ /* this will cause us to re-enter ProcessPendingIRQ() and re-read interrupt status registers. ++ * this has a nice side effect of blocking us until all async read requests are completed. ++ * This behavior is required on some HIF implementations that do not allow ASYNC ++ * processing in interrupt handlers (like Windows CE) */ ++ } ++ ++ if (asyncProc) { ++ /* the function performed some async I/O for performance, we ++ need to exit the ISR immediately, the check below will prevent the interrupt from being ++ Ack'd while we handle it asynchronously */ ++ break; ++ } ++ ++ } ++ ++ if (A_SUCCESS(status) && !asyncProc) { ++ /* Ack the interrupt only if : ++ * 1. we did not get any errors in processing interrupts ++ * 2. there are no outstanding async processing requests */ ++ AR_DEBUG_PRINTF(ATH_DEBUG_IRQ,(" Acking interrupt from DevDsrHandler \n")); ++ HIFAckInterrupt(pDev->HIFDevice); ++ } ++ ++ AR_DEBUG_PRINTF(ATH_DEBUG_IRQ,("-DevDsrHandler \n")); ++ return A_OK; ++} ++ ++ +diff -ruN --exclude='*.orig' --exclude='*.rej' linux-2.6.29-rc3.owrt/drivers/ar6000/htc/ar6k.h linux-2.6.29-rc3.owrt.om/drivers/ar6000/htc/ar6k.h +--- linux-2.6.29-rc3.owrt/drivers/ar6000/htc/ar6k.h 1970-01-01 01:00:00.000000000 +0100 ++++ linux-2.6.29-rc3.owrt.om/drivers/ar6000/htc/ar6k.h 2009-05-10 22:27:59.000000000 +0200 +@@ -0,0 +1,191 @@ ++/* ++ * ++ * Copyright (c) 2007 Atheros Communications Inc. ++ * All rights reserved. ++ * ++ * ++ * 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; ++ * ++ * Software distributed under the License is distributed on an "AS ++ * IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or ++ * implied. See the License for the specific language governing ++ * rights and limitations under the License. ++ * ++ * ++ * ++ */ ++ ++#ifndef AR6K_H_ ++#define AR6K_H_ ++ ++#define AR6K_MAILBOXES 4 ++ ++/* HTC runs over mailbox 0 */ ++#define HTC_MAILBOX 0 ++ ++#define AR6K_TARGET_DEBUG_INTR_MASK 0x01 ++ ++#define OTHER_INTS_ENABLED (INT_STATUS_ENABLE_ERROR_MASK | \ ++ INT_STATUS_ENABLE_CPU_MASK | \ ++ INT_STATUS_ENABLE_COUNTER_MASK) ++ ++//#define MBOXHW_UNIT_TEST 1 ++ ++#include "athstartpack.h" ++typedef PREPACK struct _AR6K_IRQ_PROC_REGISTERS { ++ A_UINT8 host_int_status; ++ A_UINT8 cpu_int_status; ++ A_UINT8 error_int_status; ++ A_UINT8 counter_int_status; ++ A_UINT8 mbox_frame; ++ A_UINT8 rx_lookahead_valid; ++ A_UINT8 hole[2]; ++ A_UINT32 rx_lookahead[2]; ++} POSTPACK AR6K_IRQ_PROC_REGISTERS; ++ ++#define AR6K_IRQ_PROC_REGS_SIZE sizeof(AR6K_IRQ_PROC_REGISTERS) ++ ++ ++ ++typedef PREPACK struct _AR6K_IRQ_ENABLE_REGISTERS { ++ A_UINT8 int_status_enable; ++ A_UINT8 cpu_int_status_enable; ++ A_UINT8 error_status_enable; ++ A_UINT8 counter_int_status_enable; ++} POSTPACK AR6K_IRQ_ENABLE_REGISTERS; ++ ++#include "athendpack.h" ++ ++#define AR6K_IRQ_ENABLE_REGS_SIZE sizeof(AR6K_IRQ_ENABLE_REGISTERS) ++ ++#define AR6K_REG_IO_BUFFER_SIZE 32 ++#define AR6K_MAX_REG_IO_BUFFERS 8 ++ ++/* buffers for ASYNC I/O */ ++typedef struct AR6K_ASYNC_REG_IO_BUFFER { ++ HTC_PACKET HtcPacket; /* we use an HTC packet as a wrapper for our async register-based I/O */ ++ A_UINT8 Buffer[AR6K_REG_IO_BUFFER_SIZE]; ++} AR6K_ASYNC_REG_IO_BUFFER; ++ ++typedef struct _AR6K_DEVICE { ++ A_MUTEX_T Lock; ++ AR6K_IRQ_PROC_REGISTERS IrqProcRegisters; ++ AR6K_IRQ_ENABLE_REGISTERS IrqEnableRegisters; ++ void *HIFDevice; ++ A_UINT32 BlockSize; ++ A_UINT32 BlockMask; ++ A_UINT32 MailboxAddress; ++ HIF_PENDING_EVENTS_FUNC GetPendingEventsFunc; ++ void *HTCContext; ++ HTC_PACKET_QUEUE RegisterIOList; ++ AR6K_ASYNC_REG_IO_BUFFER RegIOBuffers[AR6K_MAX_REG_IO_BUFFERS]; ++ void (*TargetFailureCallback)(void *Context); ++ A_STATUS (*MessagePendingCallback)(void *Context, A_UINT32 LookAhead, A_BOOL *pAsyncProc); ++ HIF_DEVICE_IRQ_PROCESSING_MODE HifIRQProcessingMode; ++ HIF_MASK_UNMASK_RECV_EVENT HifMaskUmaskRecvEvent; ++} AR6K_DEVICE; ++ ++#define IS_DEV_IRQ_PROCESSING_ASYNC_ALLOWED(pDev) ((pDev)->HifIRQProcessingMode != HIF_DEVICE_IRQ_SYNC_ONLY) ++ ++A_STATUS DevSetup(AR6K_DEVICE *pDev); ++A_STATUS DevUnmaskInterrupts(AR6K_DEVICE *pDev); ++A_STATUS DevMaskInterrupts(AR6K_DEVICE *pDev); ++A_STATUS DevPollMboxMsgRecv(AR6K_DEVICE *pDev, ++ A_UINT32 *pLookAhead, ++ int TimeoutMS); ++A_STATUS DevRWCompletionHandler(void *context, A_STATUS status); ++A_STATUS DevDsrHandler(void *context); ++A_STATUS DevCheckPendingRecvMsgsAsync(void *context); ++void DevDumpRegisters(AR6K_IRQ_PROC_REGISTERS *pIrqProcRegs, ++ AR6K_IRQ_ENABLE_REGISTERS *pIrqEnableRegs); ++ ++#define DEV_STOP_RECV_ASYNC TRUE ++#define DEV_STOP_RECV_SYNC FALSE ++#define DEV_ENABLE_RECV_ASYNC TRUE ++#define DEV_ENABLE_RECV_SYNC FALSE ++A_STATUS DevStopRecv(AR6K_DEVICE *pDev, A_BOOL ASyncMode); ++A_STATUS DevEnableRecv(AR6K_DEVICE *pDev, A_BOOL ASyncMode); ++ ++static INLINE A_STATUS DevSendPacket(AR6K_DEVICE *pDev, HTC_PACKET *pPacket, A_UINT32 SendLength) { ++ A_UINT32 paddedLength; ++ A_BOOL sync = (pPacket->Completion == NULL) ? TRUE : FALSE; ++ A_STATUS status; ++ ++ /* adjust the length to be a multiple of block size if appropriate */ ++ paddedLength = (SendLength + (pDev->BlockMask)) & ++ (~(pDev->BlockMask)); ++#if 0 // BufferLength may not be set in , fix this... ++ if (paddedLength > pPacket->BufferLength) { ++ AR_DEBUG_ASSERT(FALSE); ++ if (pPacket->Completion != NULL) { ++ COMPLETE_HTC_PACKET(pPacket,A_EINVAL); ++ } ++ return A_EINVAL; ++ } ++#endif ++ AR_DEBUG_PRINTF(ATH_DEBUG_SEND, ++ ("DevSendPacket, Padded Length: %d Mbox:0x%X (mode:%s)\n", ++ paddedLength, ++ pDev->MailboxAddress, ++ sync ? "SYNC" : "ASYNC")); ++ ++ status = HIFReadWrite(pDev->HIFDevice, ++ pDev->MailboxAddress, ++ pPacket->pBuffer, ++ paddedLength, /* the padded length */ ++ sync ? HIF_WR_SYNC_BLOCK_INC : HIF_WR_ASYNC_BLOCK_INC, ++ sync ? NULL : pPacket); /* pass the packet as the context to the HIF request */ ++ ++ if (sync) { ++ pPacket->Status = status; ++ } ++ ++ return status; ++} ++ ++static INLINE A_STATUS DevRecvPacket(AR6K_DEVICE *pDev, HTC_PACKET *pPacket, A_UINT32 RecvLength) { ++ A_UINT32 paddedLength; ++ A_STATUS status; ++ A_BOOL sync = (pPacket->Completion == NULL) ? TRUE : FALSE; ++ ++ /* adjust the length to be a multiple of block size if appropriate */ ++ paddedLength = (RecvLength + (pDev->BlockMask)) & ++ (~(pDev->BlockMask)); ++ if (paddedLength > pPacket->BufferLength) { ++ AR_DEBUG_ASSERT(FALSE); ++ AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ++ ("DevRecvPacket, Not enough space for padlen:%d recvlen:%d bufferlen:%d \n", ++ paddedLength,RecvLength,pPacket->BufferLength)); ++ if (pPacket->Completion != NULL) { ++ COMPLETE_HTC_PACKET(pPacket,A_EINVAL); ++ } ++ return A_EINVAL; ++ } ++ ++ AR_DEBUG_PRINTF(ATH_DEBUG_RECV, ++ ("DevRecvPacket, Padded Length: %d Mbox:0x%X (mode:%s)\n", ++ paddedLength, ++ pDev->MailboxAddress, ++ sync ? "SYNC" : "ASYNC")); ++ ++ status = HIFReadWrite(pDev->HIFDevice, ++ pDev->MailboxAddress, ++ pPacket->pBuffer, ++ paddedLength, ++ sync ? HIF_RD_SYNC_BLOCK_INC : HIF_RD_ASYNC_BLOCK_INC, ++ sync ? NULL : pPacket); /* pass the packet as the context to the HIF request */ ++ ++ if (sync) { ++ pPacket->Status = status; ++ } ++ ++ return status; ++} ++ ++#ifdef MBOXHW_UNIT_TEST ++A_STATUS DoMboxHWTest(AR6K_DEVICE *pDev); ++#endif ++ ++#endif /*AR6K_H_*/ +diff -ruN --exclude='*.orig' --exclude='*.rej' linux-2.6.29-rc3.owrt/drivers/ar6000/htc/htc.c linux-2.6.29-rc3.owrt.om/drivers/ar6000/htc/htc.c +--- linux-2.6.29-rc3.owrt/drivers/ar6000/htc/htc.c 1970-01-01 01:00:00.000000000 +0100 ++++ linux-2.6.29-rc3.owrt.om/drivers/ar6000/htc/htc.c 2009-05-10 22:27:59.000000000 +0200 +@@ -0,0 +1,508 @@ ++/* ++ * ++ * Copyright (c) 2007 Atheros Communications Inc. ++ * All rights reserved. ++ * ++ * ++ * 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; ++ * ++ * Software distributed under the License is distributed on an "AS ++ * IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or ++ * implied. See the License for the specific language governing ++ * rights and limitations under the License. ++ * ++ * ++ * ++ */ ++ ++#include "htc_internal.h" ++ ++ ++static HTC_INIT_INFO HTCInitInfo = {NULL,NULL,NULL}; ++static A_BOOL HTCInitialized = FALSE; ++ ++static A_STATUS HTCTargetInsertedHandler(void *hif_handle); ++static A_STATUS HTCTargetRemovedHandler(void *handle, A_STATUS status); ++static void HTCReportFailure(void *Context); ++ ++/* Initializes the HTC layer */ ++A_STATUS HTCInit(HTC_INIT_INFO *pInitInfo) ++{ ++ HTC_CALLBACKS htcCallbacks; ++ ++ AR_DEBUG_PRINTF(ATH_DEBUG_TRC, ("HTCInit: Enter\n")); ++ if (HTCInitialized) { ++ AR_DEBUG_PRINTF(ATH_DEBUG_TRC, ("HTCInit: Exit\n")); ++ return A_OK; ++ } ++ ++ A_MEMCPY(&HTCInitInfo,pInitInfo,sizeof(HTC_INIT_INFO)); ++ ++ A_MEMZERO(&htcCallbacks, sizeof(HTC_CALLBACKS)); ++ ++ /* setup HIF layer callbacks */ ++ htcCallbacks.deviceInsertedHandler = HTCTargetInsertedHandler; ++ htcCallbacks.deviceRemovedHandler = HTCTargetRemovedHandler; ++ /* the device layer handles these */ ++ htcCallbacks.rwCompletionHandler = DevRWCompletionHandler; ++ htcCallbacks.dsrHandler = DevDsrHandler; ++ HIFInit(&htcCallbacks); ++ HTCInitialized = TRUE; ++ ++ AR_DEBUG_PRINTF(ATH_DEBUG_TRC, ("HTCInit: Exit\n")); ++ return A_OK; ++} ++ ++void HTCFreeControlBuffer(HTC_TARGET *target, HTC_PACKET *pPacket, HTC_PACKET_QUEUE *pList) ++{ ++ LOCK_HTC(target); ++ HTC_PACKET_ENQUEUE(pList,pPacket); ++ UNLOCK_HTC(target); ++} ++ ++HTC_PACKET *HTCAllocControlBuffer(HTC_TARGET *target, HTC_PACKET_QUEUE *pList) ++{ ++ HTC_PACKET *pPacket; ++ ++ LOCK_HTC(target); ++ pPacket = HTC_PACKET_DEQUEUE(pList); ++ UNLOCK_HTC(target); ++ ++ return pPacket; ++} ++ ++/* cleanup the HTC instance */ ++static void HTCCleanup(HTC_TARGET *target) ++{ ++ if (A_IS_MUTEX_VALID(&target->HTCLock)) { ++ A_MUTEX_DELETE(&target->HTCLock); ++ } ++ ++ if (A_IS_MUTEX_VALID(&target->HTCRxLock)) { ++ A_MUTEX_DELETE(&target->HTCRxLock); ++ } ++ ++ if (A_IS_MUTEX_VALID(&target->HTCTxLock)) { ++ A_MUTEX_DELETE(&target->HTCTxLock); ++ } ++ /* free our instance */ ++ A_FREE(target); ++} ++ ++/* registered target arrival callback from the HIF layer */ ++static A_STATUS HTCTargetInsertedHandler(void *hif_handle) ++{ ++ HTC_TARGET *target = NULL; ++ A_STATUS status; ++ int i; ++ ++ AR_DEBUG_PRINTF(ATH_DEBUG_TRC, ("htcTargetInserted - Enter\n")); ++ ++ do { ++ ++ /* allocate target memory */ ++ if ((target = (HTC_TARGET *)A_MALLOC(sizeof(HTC_TARGET))) == NULL) { ++ AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("Unable to allocate memory\n")); ++ status = A_ERROR; ++ break; ++ } ++ ++ A_MEMZERO(target, sizeof(HTC_TARGET)); ++ A_MUTEX_INIT(&target->HTCLock); ++ A_MUTEX_INIT(&target->HTCRxLock); ++ A_MUTEX_INIT(&target->HTCTxLock); ++ INIT_HTC_PACKET_QUEUE(&target->ControlBufferTXFreeList); ++ INIT_HTC_PACKET_QUEUE(&target->ControlBufferRXFreeList); ++ ++ /* give device layer the hif device handle */ ++ target->Device.HIFDevice = hif_handle; ++ /* give the device layer our context (for event processing) ++ * the device layer will register it's own context with HIF ++ * so we need to set this so we can fetch it in the target remove handler */ ++ target->Device.HTCContext = target; ++ /* set device layer target failure callback */ ++ target->Device.TargetFailureCallback = HTCReportFailure; ++ /* set device layer recv message pending callback */ ++ target->Device.MessagePendingCallback = HTCRecvMessagePendingHandler; ++ target->EpWaitingForBuffers = ENDPOINT_MAX; ++ ++ /* setup device layer */ ++ status = DevSetup(&target->Device); ++ ++ if (A_FAILED(status)) { ++ break; ++ } ++ ++ /* carve up buffers/packets for control messages */ ++ for (i = 0; i < NUM_CONTROL_RX_BUFFERS; i++) { ++ HTC_PACKET *pControlPacket; ++ pControlPacket = &target->HTCControlBuffers[i].HtcPacket; ++ SET_HTC_PACKET_INFO_RX_REFILL(pControlPacket, ++ target, ++ target->HTCControlBuffers[i].Buffer, ++ HTC_CONTROL_BUFFER_SIZE, ++ ENDPOINT_0); ++ HTC_FREE_CONTROL_RX(target,pControlPacket); ++ } ++ ++ for (;i < NUM_CONTROL_BUFFERS;i++) { ++ HTC_PACKET *pControlPacket; ++ pControlPacket = &target->HTCControlBuffers[i].HtcPacket; ++ INIT_HTC_PACKET_INFO(pControlPacket, ++ target->HTCControlBuffers[i].Buffer, ++ HTC_CONTROL_BUFFER_SIZE); ++ HTC_FREE_CONTROL_TX(target,pControlPacket); ++ } ++ ++ } while (FALSE); ++ ++ if (A_SUCCESS(status)) { ++ AR_DEBUG_PRINTF(ATH_DEBUG_TRC, (" calling AddInstance callback \n")); ++ /* announce ourselves */ ++ HTCInitInfo.AddInstance((HTC_HANDLE)target); ++ } else { ++ if (target != NULL) { ++ HTCCleanup(target); ++ } ++ } ++ ++ AR_DEBUG_PRINTF(ATH_DEBUG_TRC, ("htcTargetInserted - Exit\n")); ++ ++ return status; ++} ++ ++/* registered removal callback from the HIF layer */ ++static A_STATUS HTCTargetRemovedHandler(void *handle, A_STATUS status) ++{ ++ HTC_TARGET *target; ++ ++ AR_DEBUG_PRINTF(ATH_DEBUG_TRC, ("+HTCTargetRemovedHandler handle:0x%X \n",(A_UINT32)handle)); ++ ++ if (NULL == handle) { ++ /* this could be NULL in the event that target initialization failed */ ++ return A_OK; ++ } ++ ++ target = ((AR6K_DEVICE *)handle)->HTCContext; ++ ++ AR_DEBUG_PRINTF(ATH_DEBUG_TRC, (" removing target:0x%X instance:0x%X ... \n", ++ (A_UINT32)target, (A_UINT32)target->pInstanceContext)); ++ ++ if (target->pInstanceContext != NULL) { ++ /* let upper layer know, it needs to call HTCStop() */ ++ HTCInitInfo.DeleteInstance(target->pInstanceContext); ++ } ++ ++ HIFShutDownDevice(target->Device.HIFDevice); ++ ++ HTCCleanup(target); ++ AR_DEBUG_PRINTF(ATH_DEBUG_TRC, ("-HTCTargetRemovedHandler \n")); ++ return A_OK; ++} ++ ++/* get the low level HIF device for the caller , the caller may wish to do low level ++ * HIF requests */ ++void *HTCGetHifDevice(HTC_HANDLE HTCHandle) ++{ ++ HTC_TARGET *target = GET_HTC_TARGET_FROM_HANDLE(HTCHandle); ++ return target->Device.HIFDevice; ++} ++ ++/* set the instance block for this HTC handle, so that on removal, the blob can be ++ * returned to the caller */ ++void HTCSetInstance(HTC_HANDLE HTCHandle, void *Instance) ++{ ++ HTC_TARGET *target = GET_HTC_TARGET_FROM_HANDLE(HTCHandle); ++ ++ target->pInstanceContext = Instance; ++} ++ ++/* wait for the target to arrive (sends HTC Ready message) ++ * this operation is fully synchronous and the message is polled for */ ++A_STATUS HTCWaitTarget(HTC_HANDLE HTCHandle) ++{ ++ HTC_TARGET *target = GET_HTC_TARGET_FROM_HANDLE(HTCHandle); ++ A_STATUS status; ++ HTC_PACKET *pPacket = NULL; ++ HTC_READY_MSG *pRdyMsg; ++ HTC_SERVICE_CONNECT_REQ connect; ++ HTC_SERVICE_CONNECT_RESP resp; ++ ++ AR_DEBUG_PRINTF(ATH_DEBUG_TRC, ("HTCWaitTarget - Enter (target:0x%X) \n", (A_UINT32)target)); ++ ++ do { ++ ++#ifdef MBOXHW_UNIT_TEST ++ ++ status = DoMboxHWTest(&target->Device); ++ ++ if (status != A_OK) { ++ break; ++ } ++ ++#endif ++ ++ /* we should be getting 1 control message that the target is ready */ ++ status = HTCWaitforControlMessage(target, &pPacket); ++ ++ if (A_FAILED(status)) { ++ AR_DEBUG_PRINTF(ATH_DEBUG_ERR, (" Target Not Available!!\n")); ++ break; ++ } ++ ++ /* we controlled the buffer creation so it has to be properly aligned */ ++ pRdyMsg = (HTC_READY_MSG *)pPacket->pBuffer; ++ ++ if ((pRdyMsg->MessageID != HTC_MSG_READY_ID) || ++ (pPacket->ActualLength < sizeof(HTC_READY_MSG))) { ++ /* this message is not valid */ ++ AR_DEBUG_ASSERT(FALSE); ++ status = A_EPROTO; ++ break; ++ } ++ ++ if (pRdyMsg->CreditCount == 0 || pRdyMsg->CreditSize == 0) { ++ /* this message is not valid */ ++ AR_DEBUG_ASSERT(FALSE); ++ status = A_EPROTO; ++ break; ++ } ++ ++ target->TargetCredits = pRdyMsg->CreditCount; ++ target->TargetCreditSize = pRdyMsg->CreditSize; ++ ++ AR_DEBUG_PRINTF(ATH_DEBUG_TRC, (" Target Ready: credits: %d credit size: %d\n", ++ target->TargetCredits, target->TargetCreditSize)); ++ ++ /* setup our pseudo HTC control endpoint connection */ ++ A_MEMZERO(&connect,sizeof(connect)); ++ A_MEMZERO(&resp,sizeof(resp)); ++ connect.EpCallbacks.pContext = target; ++ connect.EpCallbacks.EpTxComplete = HTCControlTxComplete; ++ connect.EpCallbacks.EpRecv = HTCControlRecv; ++ connect.EpCallbacks.EpRecvRefill = NULL; /* not needed */ ++ connect.EpCallbacks.EpSendFull = NULL; /* not needed */ ++ connect.EpCallbacks.EpSendAvail = NULL; /* not needed */ ++ connect.MaxSendQueueDepth = NUM_CONTROL_BUFFERS; ++ connect.ServiceID = HTC_CTRL_RSVD_SVC; ++ ++ /* connect fake service */ ++ status = HTCConnectService((HTC_HANDLE)target, ++ &connect, ++ &resp); ++ ++ if (!A_FAILED(status)) { ++ break; ++ } ++ ++ } while (FALSE); ++ ++ if (pPacket != NULL) { ++ HTC_FREE_CONTROL_RX(target,pPacket); ++ } ++ ++ AR_DEBUG_PRINTF(ATH_DEBUG_TRC, ("HTCWaitTarget - Exit\n")); ++ ++ return status; ++} ++ ++ ++ ++/* Start HTC, enable interrupts and let the target know host has finished setup */ ++A_STATUS HTCStart(HTC_HANDLE HTCHandle) ++{ ++ HTC_TARGET *target = GET_HTC_TARGET_FROM_HANDLE(HTCHandle); ++ HTC_PACKET *pPacket; ++ A_STATUS status; ++ ++ AR_DEBUG_PRINTF(ATH_DEBUG_TRC, ("HTCStart Enter\n")); ++ ++ /* now that we are starting, push control receive buffers into the ++ * HTC control endpoint */ ++ ++ while (1) { ++ pPacket = HTC_ALLOC_CONTROL_RX(target); ++ if (NULL == pPacket) { ++ break; ++ } ++ HTCAddReceivePkt((HTC_HANDLE)target,pPacket); ++ } ++ ++ do { ++ ++ AR_DEBUG_ASSERT(target->InitCredits != NULL); ++ AR_DEBUG_ASSERT(target->EpCreditDistributionListHead != NULL); ++ AR_DEBUG_ASSERT(target->EpCreditDistributionListHead->pNext != NULL); ++ ++ /* call init credits callback to do the distribution , ++ * NOTE: the first entry in the distribution list is ENDPOINT_0, so ++ * we pass the start of the list after this one. */ ++ target->InitCredits(target->pCredDistContext, ++ target->EpCreditDistributionListHead->pNext, ++ target->TargetCredits); ++ ++ if (AR_DEBUG_LVL_CHECK(ATH_DEBUG_TRC)) { ++ DumpCreditDistStates(target); ++ } ++ ++ /* the caller is done connecting to services, so we can indicate to the ++ * target that the setup phase is complete */ ++ status = HTCSendSetupComplete(target); ++ ++ if (A_FAILED(status)) { ++ break; ++ } ++ ++ /* unmask interrupts */ ++ status = DevUnmaskInterrupts(&target->Device); ++ ++ if (A_FAILED(status)) { ++ HTCStop(target); ++ } ++ ++ } while (FALSE); ++ ++ AR_DEBUG_PRINTF(ATH_DEBUG_TRC, ("HTCStart Exit\n")); ++ return status; ++} ++ ++ ++/* stop HTC communications, i.e. stop interrupt reception, and flush all queued buffers */ ++void HTCStop(HTC_HANDLE HTCHandle) ++{ ++ HTC_TARGET *target = GET_HTC_TARGET_FROM_HANDLE(HTCHandle); ++ AR_DEBUG_PRINTF(ATH_DEBUG_TRC, ("+HTCStop \n")); ++ ++ /* mark that we are shutting down .. */ ++ target->HTCStateFlags |= HTC_STATE_STOPPING; ++ ++ /* Masking interrupts is a synchronous operation, when this function returns ++ * all pending HIF I/O has completed, we can safely flush the queues */ ++ DevMaskInterrupts(&target->Device); ++ ++ /* flush all send packets */ ++ HTCFlushSendPkts(target); ++ /* flush all recv buffers */ ++ HTCFlushRecvBuffers(target); ++ ++ AR_DEBUG_PRINTF(ATH_DEBUG_TRC, ("-HTCStop \n")); ++} ++ ++/* undo what was done in HTCInit() */ ++void HTCShutDown(void) ++{ ++ AR_DEBUG_PRINTF(ATH_DEBUG_TRC, ("+HTCShutDown: \n")); ++ HTCInitialized = FALSE; ++ /* undo HTCInit */ ++ HIFShutDownDevice(NULL); ++ AR_DEBUG_PRINTF(ATH_DEBUG_TRC, ("-HTCShutDown: \n")); ++} ++ ++void HTCDumpCreditStates(HTC_HANDLE HTCHandle) ++{ ++ HTC_TARGET *target = GET_HTC_TARGET_FROM_HANDLE(HTCHandle); ++ ++ LOCK_HTC_TX(target); ++ ++ DumpCreditDistStates(target); ++ ++ UNLOCK_HTC_TX(target); ++} ++ ++/* report a target failure from the device, this is a callback from the device layer ++ * which uses a mechanism to report errors from the target (i.e. special interrupts) */ ++static void HTCReportFailure(void *Context) ++{ ++ HTC_TARGET *target = (HTC_TARGET *)Context; ++ ++ target->TargetFailure = TRUE; ++ ++ if ((target->pInstanceContext != NULL) && (HTCInitInfo.TargetFailure != NULL)) { ++ /* let upper layer know, it needs to call HTCStop() */ ++ HTCInitInfo.TargetFailure(target->pInstanceContext, A_ERROR); ++ } ++} ++ ++void DebugDumpBytes(A_UCHAR *buffer, A_UINT16 length, char *pDescription) ++{ ++ A_CHAR stream[60]; ++ A_UINT32 i; ++ A_UINT16 offset, count; ++ ++ AR_DEBUG_PRINTF(ATH_DEBUG_ANY, ("<---------Dumping %d Bytes : %s ------>\n", length, pDescription)); ++ ++ count = 0; ++ offset = 0; ++ for(i = 0; i < length; i++) { ++ sprintf(stream + offset, "%2.2X ", buffer[i]); ++ count ++; ++ offset += 3; ++ ++ if(count == 16) { ++ count = 0; ++ offset = 0; ++ AR_DEBUG_PRINTF(ATH_DEBUG_ANY, ("[H]: %s\n", stream)); ++ A_MEMZERO(stream, 60); ++ } ++ } ++ ++ if(offset != 0) { ++ AR_DEBUG_PRINTF(ATH_DEBUG_ANY, ("[H]: %s\n", stream)); ++ } ++ ++ AR_DEBUG_PRINTF(ATH_DEBUG_ANY, ("<------------------------------------------------->\n")); ++} ++ ++A_BOOL HTCGetEndpointStatistics(HTC_HANDLE HTCHandle, ++ HTC_ENDPOINT_ID Endpoint, ++ HTC_ENDPOINT_STAT_ACTION Action, ++ HTC_ENDPOINT_STATS *pStats) ++{ ++ ++#ifdef HTC_EP_STAT_PROFILING ++ HTC_TARGET *target = GET_HTC_TARGET_FROM_HANDLE(HTCHandle); ++ A_BOOL clearStats = FALSE; ++ A_BOOL sample = FALSE; ++ ++ switch (Action) { ++ case HTC_EP_STAT_SAMPLE : ++ sample = TRUE; ++ break; ++ case HTC_EP_STAT_SAMPLE_AND_CLEAR : ++ sample = TRUE; ++ clearStats = TRUE; ++ break; ++ case HTC_EP_STAT_CLEAR : ++ clearStats = TRUE; ++ break; ++ default: ++ break; ++ } ++ ++ A_ASSERT(Endpoint < ENDPOINT_MAX); ++ ++ /* lock out TX and RX while we sample and/or clear */ ++ LOCK_HTC_TX(target); ++ LOCK_HTC_RX(target); ++ ++ if (sample) { ++ A_ASSERT(pStats != NULL); ++ /* return the stats to the caller */ ++ A_MEMCPY(pStats, &target->EndPoint[Endpoint].EndPointStats, sizeof(HTC_ENDPOINT_STATS)); ++ } ++ ++ if (clearStats) { ++ /* reset stats */ ++ A_MEMZERO(&target->EndPoint[Endpoint].EndPointStats, sizeof(HTC_ENDPOINT_STATS)); ++ } ++ ++ UNLOCK_HTC_RX(target); ++ UNLOCK_HTC_TX(target); ++ ++ return TRUE; ++#else ++ return FALSE; ++#endif ++} +diff -ruN --exclude='*.orig' --exclude='*.rej' linux-2.6.29-rc3.owrt/drivers/ar6000/htc/htc_debug.h linux-2.6.29-rc3.owrt.om/drivers/ar6000/htc/htc_debug.h +--- linux-2.6.29-rc3.owrt/drivers/ar6000/htc/htc_debug.h 1970-01-01 01:00:00.000000000 +0100 ++++ linux-2.6.29-rc3.owrt.om/drivers/ar6000/htc/htc_debug.h 2009-05-10 22:27:59.000000000 +0200 +@@ -0,0 +1,65 @@ ++#ifndef HTC_DEBUG_H_ ++#define HTC_DEBUG_H_ ++/* ++ * ++ * Copyright (c) 2004-2007 Atheros Communications Inc. ++ * All rights reserved. ++ * ++ * ++ * 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; ++ * ++ * Software distributed under the License is distributed on an "AS ++ * IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or ++ * implied. See the License for the specific language governing ++ * rights and limitations under the License. ++ * ++ * ++ * ++ */ ++ ++/* ------- Debug related stuff ------- */ ++enum { ++ ATH_DEBUG_SEND = 0x0001, ++ ATH_DEBUG_RECV = 0x0002, ++ ATH_DEBUG_SYNC = 0x0004, ++ ATH_DEBUG_DUMP = 0x0008, ++ ATH_DEBUG_IRQ = 0x0010, ++ ATH_DEBUG_TRC = 0x0020, ++ ATH_DEBUG_WARN = 0x0040, ++ ATH_DEBUG_ERR = 0x0080, ++ ATH_DEBUG_ANY = 0xFFFF, ++}; ++ ++#ifdef DEBUG ++ ++// TODO FIX usage of A_PRINTF! ++#define AR_DEBUG_LVL_CHECK(lvl) (debughtc & (lvl)) ++#define AR_DEBUG_PRINTBUF(buffer, length, desc) do { \ ++ if (debughtc & ATH_DEBUG_DUMP) { \ ++ DebugDumpBytes(buffer, length,desc); \ ++ } \ ++} while(0) ++#define PRINTX_ARG(arg...) arg ++#define AR_DEBUG_PRINTF(flags, args) do { \ ++ if (debughtc & (flags)) { \ ++ A_PRINTF(KERN_ALERT PRINTX_ARG args); \ ++ } \ ++} while (0) ++#define AR_DEBUG_ASSERT(test) do { \ ++ if (!(test)) { \ ++ AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("Debug Assert Caught, File %s, Line: %d, Test:%s \n",__FILE__, __LINE__,#test)); \ ++ } \ ++} while(0) ++extern int debughtc; ++#else ++#define AR_DEBUG_PRINTF(flags, args) ++#define AR_DEBUG_PRINTBUF(buffer, length, desc) ++#define AR_DEBUG_ASSERT(test) ++#define AR_DEBUG_LVL_CHECK(lvl) 0 ++#endif ++ ++void DebugDumpBytes(A_UCHAR *buffer, A_UINT16 length, char *pDescription); ++ ++#endif /*HTC_DEBUG_H_*/ +diff -ruN --exclude='*.orig' --exclude='*.rej' linux-2.6.29-rc3.owrt/drivers/ar6000/htc/htc_internal.h linux-2.6.29-rc3.owrt.om/drivers/ar6000/htc/htc_internal.h +--- linux-2.6.29-rc3.owrt/drivers/ar6000/htc/htc_internal.h 1970-01-01 01:00:00.000000000 +0100 ++++ linux-2.6.29-rc3.owrt.om/drivers/ar6000/htc/htc_internal.h 2009-05-10 22:27:59.000000000 +0200 +@@ -0,0 +1,168 @@ ++/* ++ * ++ * Copyright (c) 2007 Atheros Communications Inc. ++ * All rights reserved. ++ * ++ * ++ * 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; ++ * ++ * Software distributed under the License is distributed on an "AS ++ * IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or ++ * implied. See the License for the specific language governing ++ * rights and limitations under the License. ++ * ++ * ++ * ++ */ ++ ++#ifndef _HTC_INTERNAL_H_ ++#define _HTC_INTERNAL_H_ ++ ++/* for debugging, uncomment this to capture the last frame header, on frame header ++ * processing errors, the last frame header is dump for comparison */ ++//#define HTC_CAPTURE_LAST_FRAME ++ ++//#define HTC_EP_STAT_PROFILING ++ ++#ifdef __cplusplus ++extern "C" { ++#endif /* __cplusplus */ ++ ++/* Header files */ ++#include "a_config.h" ++#include "athdefs.h" ++#include "a_types.h" ++#include "a_osapi.h" ++#include "a_debug.h" ++#include "htc.h" ++#include "htc_api.h" ++#include "bmi_msg.h" ++#include "hif.h" ++#include "ar6k.h" ++ ++/* HTC operational parameters */ ++#define HTC_TARGET_RESPONSE_TIMEOUT 2000 /* in ms */ ++#define HTC_TARGET_DEBUG_INTR_MASK 0x01 ++#define HTC_TARGET_CREDIT_INTR_MASK 0xF0 ++ ++typedef struct _HTC_ENDPOINT { ++ HTC_SERVICE_ID ServiceID; /* service ID this endpoint is bound to ++ non-zero value means this endpoint is in use */ ++ HTC_PACKET_QUEUE TxQueue; /* HTC frame buffer TX queue */ ++ HTC_PACKET_QUEUE RxBuffers; /* HTC frame buffer RX list */ ++ HTC_ENDPOINT_CREDIT_DIST CreditDist; /* credit distribution structure (exposed to driver layer) */ ++ HTC_EP_CALLBACKS EpCallBacks; /* callbacks associated with this endpoint */ ++ int MaxTxQueueDepth; /* max depth of the TX queue before we need to ++ call driver's full handler */ ++ int CurrentTxQueueDepth; /* current TX queue depth */ ++ int MaxMsgLength; /* max length of endpoint message */ ++#ifdef HTC_EP_STAT_PROFILING ++ HTC_ENDPOINT_STATS EndPointStats; /* endpoint statistics */ ++#endif ++} HTC_ENDPOINT; ++ ++#ifdef HTC_EP_STAT_PROFILING ++#define INC_HTC_EP_STAT(p,stat,count) (p)->EndPointStats.stat += (count); ++#else ++#define INC_HTC_EP_STAT(p,stat,count) ++#endif ++ ++#define HTC_SERVICE_TX_PACKET_TAG HTC_TX_PACKET_TAG_INTERNAL ++ ++#define NUM_CONTROL_BUFFERS 8 ++#define NUM_CONTROL_TX_BUFFERS 2 ++#define NUM_CONTROL_RX_BUFFERS (NUM_CONTROL_BUFFERS - NUM_CONTROL_TX_BUFFERS) ++ ++#define HTC_CONTROL_BUFFER_SIZE (HTC_MAX_CONTROL_MESSAGE_LENGTH + HTC_HDR_LENGTH) ++ ++typedef struct HTC_CONTROL_BUFFER { ++ HTC_PACKET HtcPacket; ++ A_UINT8 Buffer[HTC_CONTROL_BUFFER_SIZE]; ++} HTC_CONTROL_BUFFER; ++ ++/* our HTC target state */ ++typedef struct _HTC_TARGET { ++ HTC_ENDPOINT EndPoint[ENDPOINT_MAX]; ++ HTC_CONTROL_BUFFER HTCControlBuffers[NUM_CONTROL_BUFFERS]; ++ HTC_ENDPOINT_CREDIT_DIST *EpCreditDistributionListHead; ++ HTC_PACKET_QUEUE ControlBufferTXFreeList; ++ HTC_PACKET_QUEUE ControlBufferRXFreeList; ++ HTC_CREDIT_DIST_CALLBACK DistributeCredits; ++ HTC_CREDIT_INIT_CALLBACK InitCredits; ++ void *pCredDistContext; ++ int TargetCredits; ++ int TargetCreditSize; ++ A_MUTEX_T HTCLock; ++ A_MUTEX_T HTCRxLock; ++ A_MUTEX_T HTCTxLock; ++ AR6K_DEVICE Device; /* AR6K - specific state */ ++ A_UINT32 HTCStateFlags; ++ HTC_ENDPOINT_ID EpWaitingForBuffers; ++ A_BOOL TargetFailure; ++ void *pInstanceContext; ++#define HTC_STATE_WAIT_BUFFERS (1 << 0) ++#define HTC_STATE_STOPPING (1 << 1) ++#ifdef HTC_CAPTURE_LAST_FRAME ++ HTC_FRAME_HDR LastFrameHdr; /* useful for debugging */ ++ A_UINT8 LastTrailer[256]; ++ A_UINT8 LastTrailerLength; ++#endif ++} HTC_TARGET; ++ ++#define HTC_STOPPING(t) ((t)->HTCStateFlags & HTC_STATE_STOPPING) ++#define LOCK_HTC(t) A_MUTEX_LOCK(&(t)->HTCLock); ++#define UNLOCK_HTC(t) A_MUTEX_UNLOCK(&(t)->HTCLock); ++#define LOCK_HTC_RX(t) A_MUTEX_LOCK(&(t)->HTCRxLock); ++#define UNLOCK_HTC_RX(t) A_MUTEX_UNLOCK(&(t)->HTCRxLock); ++#define LOCK_HTC_TX(t) A_MUTEX_LOCK(&(t)->HTCTxLock); ++#define UNLOCK_HTC_TX(t) A_MUTEX_UNLOCK(&(t)->HTCTxLock); ++ ++#define GET_HTC_TARGET_FROM_HANDLE(hnd) ((HTC_TARGET *)(hnd)) ++#define HTC_RECYCLE_RX_PKT(target,p) \ ++{ \ ++ HTC_PACKET_RESET_RX(pPacket); \ ++ HTCAddReceivePkt((HTC_HANDLE)(target),(p)); \ ++} ++ ++/* internal HTC functions */ ++void HTCControlTxComplete(void *Context, HTC_PACKET *pPacket); ++void HTCControlRecv(void *Context, HTC_PACKET *pPacket); ++A_STATUS HTCWaitforControlMessage(HTC_TARGET *target, HTC_PACKET **ppControlPacket); ++HTC_PACKET *HTCAllocControlBuffer(HTC_TARGET *target, HTC_PACKET_QUEUE *pList); ++void HTCFreeControlBuffer(HTC_TARGET *target, HTC_PACKET *pPacket, HTC_PACKET_QUEUE *pList); ++A_STATUS HTCIssueSend(HTC_TARGET *target, HTC_PACKET *pPacket, A_UINT8 Flags); ++A_STATUS HTCIssueRecv(HTC_TARGET *target, HTC_PACKET *pPacket); ++void HTCRecvCompleteHandler(void *Context, HTC_PACKET *pPacket); ++A_STATUS HTCRecvMessagePendingHandler(void *Context, A_UINT32 LookAhead, A_BOOL *pAsyncProc); ++void HTCProcessCreditRpt(HTC_TARGET *target, HTC_CREDIT_REPORT *pRpt, int NumEntries, HTC_ENDPOINT_ID FromEndpoint); ++A_STATUS HTCSendSetupComplete(HTC_TARGET *target); ++void HTCFlushRecvBuffers(HTC_TARGET *target); ++void HTCFlushSendPkts(HTC_TARGET *target); ++void DumpCreditDist(HTC_ENDPOINT_CREDIT_DIST *pEPDist); ++void DumpCreditDistStates(HTC_TARGET *target); ++void DebugDumpBytes(A_UCHAR *buffer, A_UINT16 length, char *pDescription); ++ ++static INLINE HTC_PACKET *HTC_ALLOC_CONTROL_TX(HTC_TARGET *target) { ++ HTC_PACKET *pPacket = HTCAllocControlBuffer(target,&target->ControlBufferTXFreeList); ++ if (pPacket != NULL) { ++ /* set payload pointer area with some headroom */ ++ pPacket->pBuffer = pPacket->pBufferStart + HTC_HDR_LENGTH; ++ } ++ return pPacket; ++} ++ ++#define HTC_FREE_CONTROL_TX(t,p) HTCFreeControlBuffer((t),(p),&(t)->ControlBufferTXFreeList) ++#define HTC_ALLOC_CONTROL_RX(t) HTCAllocControlBuffer((t),&(t)->ControlBufferRXFreeList) ++#define HTC_FREE_CONTROL_RX(t,p) \ ++{ \ ++ HTC_PACKET_RESET_RX(p); \ ++ HTCFreeControlBuffer((t),(p),&(t)->ControlBufferRXFreeList); \ ++} ++ ++#ifdef __cplusplus ++} ++#endif ++ ++#endif /* _HTC_INTERNAL_H_ */ +diff -ruN --exclude='*.orig' --exclude='*.rej' linux-2.6.29-rc3.owrt/drivers/ar6000/htc/htc_recv.c linux-2.6.29-rc3.owrt.om/drivers/ar6000/htc/htc_recv.c +--- linux-2.6.29-rc3.owrt/drivers/ar6000/htc/htc_recv.c 1970-01-01 01:00:00.000000000 +0100 ++++ linux-2.6.29-rc3.owrt.om/drivers/ar6000/htc/htc_recv.c 2009-05-10 22:27:59.000000000 +0200 +@@ -0,0 +1,703 @@ ++/* ++ * ++ * Copyright (c) 2007 Atheros Communications Inc. ++ * All rights reserved. ++ * ++ * ++ * 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; ++ * ++ * Software distributed under the License is distributed on an "AS ++ * IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or ++ * implied. See the License for the specific language governing ++ * rights and limitations under the License. ++ * ++ * ++ * ++ */ ++ ++#include "htc_internal.h" ++ ++#define HTCIssueRecv(t, p) \ ++ DevRecvPacket(&(t)->Device, \ ++ (p), \ ++ (p)->ActualLength) ++ ++#define DO_RCV_COMPLETION(t,p,e) \ ++{ \ ++ if ((p)->ActualLength > 0) { \ ++ AR_DEBUG_PRINTF(ATH_DEBUG_RECV, (" completing packet 0x%X (%d bytes) on ep : %d \n", \ ++ (A_UINT32)(p), (p)->ActualLength, (p)->Endpoint)); \ ++ (e)->EpCallBacks.EpRecv((e)->EpCallBacks.pContext, \ ++ (p)); \ ++ } else { \ ++ AR_DEBUG_PRINTF(ATH_DEBUG_RECV, (" recycling empty packet \n")); \ ++ HTC_RECYCLE_RX_PKT((t), (p)); \ ++ } \ ++} ++ ++#ifdef HTC_EP_STAT_PROFILING ++#define HTC_RX_STAT_PROFILE(t,ep,lookAhead) \ ++{ \ ++ LOCK_HTC_RX((t)); \ ++ INC_HTC_EP_STAT((ep), RxReceived, 1); \ ++ if ((lookAhead) != 0) { \ ++ INC_HTC_EP_STAT((ep), RxLookAheads, 1); \ ++ } \ ++ UNLOCK_HTC_RX((t)); \ ++} ++#else ++#define HTC_RX_STAT_PROFILE(t,ep,lookAhead) ++#endif ++ ++static INLINE A_STATUS HTCProcessTrailer(HTC_TARGET *target, ++ A_UINT8 *pBuffer, ++ int Length, ++ A_UINT32 *pNextLookAhead, ++ HTC_ENDPOINT_ID FromEndpoint) ++{ ++ HTC_RECORD_HDR *pRecord; ++ A_UINT8 *pRecordBuf; ++ HTC_LOOKAHEAD_REPORT *pLookAhead; ++ A_UINT8 *pOrigBuffer; ++ int origLength; ++ A_STATUS status; ++ ++ AR_DEBUG_PRINTF(ATH_DEBUG_RECV, ("+HTCProcessTrailer (length:%d) \n", Length)); ++ ++ if (AR_DEBUG_LVL_CHECK(ATH_DEBUG_RECV)) { ++ AR_DEBUG_PRINTBUF(pBuffer,Length,"Recv Trailer"); ++ } ++ ++ pOrigBuffer = pBuffer; ++ origLength = Length; ++ status = A_OK; ++ ++ while (Length > 0) { ++ ++ if (Length < sizeof(HTC_RECORD_HDR)) { ++ status = A_EPROTO; ++ break; ++ } ++ /* these are byte aligned structs */ ++ pRecord = (HTC_RECORD_HDR *)pBuffer; ++ Length -= sizeof(HTC_RECORD_HDR); ++ pBuffer += sizeof(HTC_RECORD_HDR); ++ ++ if (pRecord->Length > Length) { ++ /* no room left in buffer for record */ ++ AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ++ (" invalid record length: %d (id:%d) buffer has: %d bytes left \n", ++ pRecord->Length, pRecord->RecordID, Length)); ++ status = A_EPROTO; ++ break; ++ } ++ /* start of record follows the header */ ++ pRecordBuf = pBuffer; ++ ++ switch (pRecord->RecordID) { ++ case HTC_RECORD_CREDITS: ++ AR_DEBUG_ASSERT(pRecord->Length >= sizeof(HTC_CREDIT_REPORT)); ++ HTCProcessCreditRpt(target, ++ (HTC_CREDIT_REPORT *)pRecordBuf, ++ pRecord->Length / (sizeof(HTC_CREDIT_REPORT)), ++ FromEndpoint); ++ break; ++ case HTC_RECORD_LOOKAHEAD: ++ AR_DEBUG_ASSERT(pRecord->Length >= sizeof(HTC_LOOKAHEAD_REPORT)); ++ pLookAhead = (HTC_LOOKAHEAD_REPORT *)pRecordBuf; ++ if ((pLookAhead->PreValid == ((~pLookAhead->PostValid) & 0xFF)) && ++ (pNextLookAhead != NULL)) { ++ ++ AR_DEBUG_PRINTF(ATH_DEBUG_RECV, ++ (" LookAhead Report Found (pre valid:0x%X, post valid:0x%X) \n", ++ pLookAhead->PreValid, ++ pLookAhead->PostValid)); ++ ++ /* look ahead bytes are valid, copy them over */ ++ ((A_UINT8 *)pNextLookAhead)[0] = pLookAhead->LookAhead[0]; ++ ((A_UINT8 *)pNextLookAhead)[1] = pLookAhead->LookAhead[1]; ++ ((A_UINT8 *)pNextLookAhead)[2] = pLookAhead->LookAhead[2]; ++ ((A_UINT8 *)pNextLookAhead)[3] = pLookAhead->LookAhead[3]; ++ ++ if (AR_DEBUG_LVL_CHECK(ATH_DEBUG_RECV)) { ++ DebugDumpBytes((A_UINT8 *)pNextLookAhead,4,"Next Look Ahead"); ++ } ++ } ++ break; ++ default: ++ AR_DEBUG_PRINTF(ATH_DEBUG_ERR, (" unhandled record: id:%d length:%d \n", ++ pRecord->RecordID, pRecord->Length)); ++ break; ++ } ++ ++ if (A_FAILED(status)) { ++ break; ++ } ++ ++ /* advance buffer past this record for next time around */ ++ pBuffer += pRecord->Length; ++ Length -= pRecord->Length; ++ } ++ ++ if (A_FAILED(status)) { ++ DebugDumpBytes(pOrigBuffer,origLength,"BAD Recv Trailer"); ++ } ++ ++ AR_DEBUG_PRINTF(ATH_DEBUG_RECV, ("-HTCProcessTrailer \n")); ++ return status; ++ ++} ++ ++/* process a received message (i.e. strip off header, process any trailer data) ++ * note : locks must be released when this function is called */ ++static A_STATUS HTCProcessRecvHeader(HTC_TARGET *target, HTC_PACKET *pPacket, A_UINT32 *pNextLookAhead) ++{ ++ A_UINT8 temp; ++ A_UINT8 *pBuf; ++ A_STATUS status = A_OK; ++ A_UINT16 payloadLen; ++ A_UINT32 lookAhead; ++ ++ pBuf = pPacket->pBuffer; ++ ++ AR_DEBUG_PRINTF(ATH_DEBUG_RECV, ("+HTCProcessRecvHeader \n")); ++ ++ if (AR_DEBUG_LVL_CHECK(ATH_DEBUG_RECV)) { ++ AR_DEBUG_PRINTBUF(pBuf,pPacket->ActualLength,"HTC Recv PKT"); ++ } ++ ++ do { ++ /* note, we cannot assume the alignment of pBuffer, so we use the safe macros to ++ * retrieve 16 bit fields */ ++ payloadLen = A_GET_UINT16_FIELD(pBuf, HTC_FRAME_HDR, PayloadLen); ++ ++ ((A_UINT8 *)&lookAhead)[0] = pBuf[0]; ++ ((A_UINT8 *)&lookAhead)[1] = pBuf[1]; ++ ((A_UINT8 *)&lookAhead)[2] = pBuf[2]; ++ ((A_UINT8 *)&lookAhead)[3] = pBuf[3]; ++ ++ if (lookAhead != pPacket->HTCReserved) { ++ /* somehow the lookahead that gave us the full read length did not ++ * reflect the actual header in the pending message */ ++ AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ++ ("HTCProcessRecvHeader, lookahead mismatch! \n")); ++ DebugDumpBytes((A_UINT8 *)&pPacket->HTCReserved,4,"Expected Message LookAhead"); ++ DebugDumpBytes(pBuf,sizeof(HTC_FRAME_HDR),"Current Frame Header"); ++#ifdef HTC_CAPTURE_LAST_FRAME ++ DebugDumpBytes((A_UINT8 *)&target->LastFrameHdr,sizeof(HTC_FRAME_HDR),"Last Frame Header"); ++ if (target->LastTrailerLength != 0) { ++ DebugDumpBytes(target->LastTrailer, ++ target->LastTrailerLength, ++ "Last trailer"); ++ } ++#endif ++ status = A_EPROTO; ++ break; ++ } ++ ++ /* get flags */ ++ temp = A_GET_UINT8_FIELD(pBuf, HTC_FRAME_HDR, Flags); ++ ++ if (temp & HTC_FLAGS_RECV_TRAILER) { ++ /* this packet has a trailer */ ++ ++ /* extract the trailer length in control byte 0 */ ++ temp = A_GET_UINT8_FIELD(pBuf, HTC_FRAME_HDR, ControlBytes[0]); ++ ++ if ((temp < sizeof(HTC_RECORD_HDR)) || (temp > payloadLen)) { ++ AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ++ ("HTCProcessRecvHeader, invalid header (payloadlength should be :%d, CB[0] is:%d) \n", ++ payloadLen, temp)); ++ status = A_EPROTO; ++ break; ++ } ++ ++ /* process trailer data that follows HDR + application payload */ ++ status = HTCProcessTrailer(target, ++ (pBuf + HTC_HDR_LENGTH + payloadLen - temp), ++ temp, ++ pNextLookAhead, ++ pPacket->Endpoint); ++ ++ if (A_FAILED(status)) { ++ break; ++ } ++ ++#ifdef HTC_CAPTURE_LAST_FRAME ++ A_MEMCPY(target->LastTrailer, (pBuf + HTC_HDR_LENGTH + payloadLen - temp), temp); ++ target->LastTrailerLength = temp; ++#endif ++ /* trim length by trailer bytes */ ++ pPacket->ActualLength -= temp; ++ } ++#ifdef HTC_CAPTURE_LAST_FRAME ++ else { ++ target->LastTrailerLength = 0; ++ } ++#endif ++ ++ /* if we get to this point, the packet is good */ ++ /* remove header and adjust length */ ++ pPacket->pBuffer += HTC_HDR_LENGTH; ++ pPacket->ActualLength -= HTC_HDR_LENGTH; ++ ++ } while (FALSE); ++ ++ if (A_FAILED(status)) { ++ /* dump the whole packet */ ++ DebugDumpBytes(pBuf,pPacket->ActualLength,"BAD HTC Recv PKT"); ++ } else { ++#ifdef HTC_CAPTURE_LAST_FRAME ++ A_MEMCPY(&target->LastFrameHdr,pBuf,sizeof(HTC_FRAME_HDR)); ++#endif ++ if (AR_DEBUG_LVL_CHECK(ATH_DEBUG_RECV)) { ++ if (pPacket->ActualLength > 0) { ++ AR_DEBUG_PRINTBUF(pPacket->pBuffer,pPacket->ActualLength,"HTC - Application Msg"); ++ } ++ } ++ } ++ ++ AR_DEBUG_PRINTF(ATH_DEBUG_RECV, ("-HTCProcessRecvHeader \n")); ++ return status; ++} ++ ++/* asynchronous completion handler for recv packet fetching, when the device layer ++ * completes a read request, it will call this completion handler */ ++void HTCRecvCompleteHandler(void *Context, HTC_PACKET *pPacket) ++{ ++ HTC_TARGET *target = (HTC_TARGET *)Context; ++ HTC_ENDPOINT *pEndpoint; ++ A_UINT32 nextLookAhead = 0; ++ A_STATUS status; ++ ++ AR_DEBUG_PRINTF(ATH_DEBUG_RECV, ("+HTCRecvCompleteHandler (status:%d, ep:%d) \n", ++ pPacket->Status, pPacket->Endpoint)); ++ ++ AR_DEBUG_ASSERT(pPacket->Endpoint < ENDPOINT_MAX); ++ pEndpoint = &target->EndPoint[pPacket->Endpoint]; ++ pPacket->Completion = NULL; ++ ++ /* get completion status */ ++ status = pPacket->Status; ++ ++ do { ++ if (A_FAILED(status)) { ++ AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("HTCRecvCompleteHandler: request failed (status:%d, ep:%d) \n", ++ pPacket->Status, pPacket->Endpoint)); ++ break; ++ } ++ /* process the header for any trailer data */ ++ status = HTCProcessRecvHeader(target,pPacket,&nextLookAhead); ++ ++ if (A_FAILED(status)) { ++ break; ++ } ++ /* was there a lookahead for the next packet? */ ++ if (nextLookAhead != 0) { ++ A_STATUS nextStatus; ++ AR_DEBUG_PRINTF(ATH_DEBUG_RECV, ++ ("HTCRecvCompleteHandler - next look ahead was non-zero : 0x%X \n", ++ nextLookAhead)); ++ /* we have another packet, get the next packet fetch started (pipelined) before ++ * we call into the endpoint's callback, this will start another async request */ ++ nextStatus = HTCRecvMessagePendingHandler(target,nextLookAhead,NULL); ++ if (A_EPROTO == nextStatus) { ++ AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ++ ("Next look ahead from recv header was INVALID\n")); ++ DebugDumpBytes((A_UINT8 *)&nextLookAhead, ++ 4, ++ "BAD lookahead from lookahead report"); ++ } ++ } else { ++ AR_DEBUG_PRINTF(ATH_DEBUG_RECV, ++ ("HTCRecvCompleteHandler - rechecking for more messages...\n")); ++ /* if we did not get anything on the look-ahead, ++ * call device layer to asynchronously re-check for messages. If we can keep the async ++ * processing going we get better performance. If there is a pending message we will keep processing ++ * messages asynchronously which should pipeline things nicely */ ++ DevCheckPendingRecvMsgsAsync(&target->Device); ++ } ++ ++ HTC_RX_STAT_PROFILE(target,pEndpoint,nextLookAhead); ++ DO_RCV_COMPLETION(target,pPacket,pEndpoint); ++ ++ } while (FALSE); ++ ++ if (A_FAILED(status)) { ++ AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ++ ("HTCRecvCompleteHandler , message fetch failed (status = %d) \n", ++ status)); ++ /* recyle this packet */ ++ HTC_RECYCLE_RX_PKT(target, pPacket); ++ } ++ ++ AR_DEBUG_PRINTF(ATH_DEBUG_RECV, ("-HTCRecvCompleteHandler\n")); ++} ++ ++/* synchronously wait for a control message from the target, ++ * This function is used at initialization time ONLY. At init messages ++ * on ENDPOINT 0 are expected. */ ++A_STATUS HTCWaitforControlMessage(HTC_TARGET *target, HTC_PACKET **ppControlPacket) ++{ ++ A_STATUS status; ++ A_UINT32 lookAhead; ++ HTC_PACKET *pPacket = NULL; ++ HTC_FRAME_HDR *pHdr; ++ ++ AR_DEBUG_PRINTF(ATH_DEBUG_RECV,("+HTCWaitforControlMessage \n")); ++ ++ do { ++ ++ *ppControlPacket = NULL; ++ ++ /* call the polling function to see if we have a message */ ++ status = DevPollMboxMsgRecv(&target->Device, ++ &lookAhead, ++ HTC_TARGET_RESPONSE_TIMEOUT); ++ ++ if (A_FAILED(status)) { ++ break; ++ } ++ ++ AR_DEBUG_PRINTF(ATH_DEBUG_RECV, ++ ("HTCWaitforControlMessage : lookAhead : 0x%X \n", lookAhead)); ++ ++ /* check the lookahead */ ++ pHdr = (HTC_FRAME_HDR *)&lookAhead; ++ ++ if (pHdr->EndpointID != ENDPOINT_0) { ++ /* unexpected endpoint number, should be zero */ ++ AR_DEBUG_ASSERT(FALSE); ++ status = A_EPROTO; ++ break; ++ } ++ ++ if (A_FAILED(status)) { ++ /* bad message */ ++ AR_DEBUG_ASSERT(FALSE); ++ status = A_EPROTO; ++ break; ++ } ++ ++ pPacket = HTC_ALLOC_CONTROL_RX(target); ++ ++ if (pPacket == NULL) { ++ AR_DEBUG_ASSERT(FALSE); ++ status = A_NO_MEMORY; ++ break; ++ } ++ ++ pPacket->HTCReserved = lookAhead; ++ pPacket->ActualLength = pHdr->PayloadLen + HTC_HDR_LENGTH; ++ ++ if (pPacket->ActualLength > pPacket->BufferLength) { ++ AR_DEBUG_ASSERT(FALSE); ++ status = A_EPROTO; ++ break; ++ } ++ ++ /* we want synchronous operation */ ++ pPacket->Completion = NULL; ++ ++ /* get the message from the device, this will block */ ++ status = HTCIssueRecv(target, pPacket); ++ ++ if (A_FAILED(status)) { ++ break; ++ } ++ ++ /* process receive header */ ++ status = HTCProcessRecvHeader(target,pPacket,NULL); ++ ++ pPacket->Status = status; ++ ++ if (A_FAILED(status)) { ++ AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ++ ("HTCWaitforControlMessage, HTCProcessRecvHeader failed (status = %d) \n", ++ status)); ++ break; ++ } ++ ++ /* give the caller this control message packet, they are responsible to free */ ++ *ppControlPacket = pPacket; ++ ++ } while (FALSE); ++ ++ if (A_FAILED(status)) { ++ if (pPacket != NULL) { ++ /* cleanup buffer on error */ ++ HTC_FREE_CONTROL_RX(target,pPacket); ++ } ++ } ++ ++ AR_DEBUG_PRINTF(ATH_DEBUG_RECV,("-HTCWaitforControlMessage \n")); ++ ++ return status; ++} ++ ++/* callback when device layer or lookahead report parsing detects a pending message */ ++A_STATUS HTCRecvMessagePendingHandler(void *Context, A_UINT32 LookAhead, A_BOOL *pAsyncProc) ++{ ++ HTC_TARGET *target = (HTC_TARGET *)Context; ++ A_STATUS status = A_OK; ++ HTC_PACKET *pPacket = NULL; ++ HTC_FRAME_HDR *pHdr; ++ HTC_ENDPOINT *pEndpoint; ++ A_BOOL asyncProc = FALSE; ++ ++ AR_DEBUG_PRINTF(ATH_DEBUG_RECV,("+HTCRecvMessagePendingHandler LookAhead:0x%X \n",LookAhead)); ++ ++ if (IS_DEV_IRQ_PROCESSING_ASYNC_ALLOWED(&target->Device)) { ++ /* We use async mode to get the packets if the device layer supports it. ++ * The device layer interfaces with HIF in which HIF may have restrictions on ++ * how interrupts are processed */ ++ asyncProc = TRUE; ++ } ++ ++ if (pAsyncProc != NULL) { ++ /* indicate to caller how we decided to process this */ ++ *pAsyncProc = asyncProc; ++ } ++ ++ while (TRUE) { ++ ++ pHdr = (HTC_FRAME_HDR *)&LookAhead; ++ ++ if (pHdr->EndpointID >= ENDPOINT_MAX) { ++ AR_DEBUG_PRINTF(ATH_DEBUG_ERR,("Invalid Endpoint in look-ahead: %d \n",pHdr->EndpointID)); ++ /* invalid endpoint */ ++ status = A_EPROTO; ++ break; ++ } ++ ++ if (pHdr->PayloadLen > HTC_MAX_PAYLOAD_LENGTH) { ++ AR_DEBUG_PRINTF(ATH_DEBUG_ERR,("Payload length %d exceeds max HTC : %d !\n", ++ pHdr->PayloadLen, HTC_MAX_PAYLOAD_LENGTH)); ++ status = A_EPROTO; ++ break; ++ } ++ ++ pEndpoint = &target->EndPoint[pHdr->EndpointID]; ++ ++ if (0 == pEndpoint->ServiceID) { ++ AR_DEBUG_PRINTF(ATH_DEBUG_ERR,("Endpoint %d is not connected !\n",pHdr->EndpointID)); ++ /* endpoint isn't even connected */ ++ status = A_EPROTO; ++ break; ++ } ++ ++ /* lock RX to get a buffer */ ++ LOCK_HTC_RX(target); ++ ++ /* get a packet from the endpoint recv queue */ ++ pPacket = HTC_PACKET_DEQUEUE(&pEndpoint->RxBuffers); ++ ++ if (NULL == pPacket) { ++ /* check for refill handler */ ++ if (pEndpoint->EpCallBacks.EpRecvRefill != NULL) { ++ UNLOCK_HTC_RX(target); ++ /* call the re-fill handler */ ++ pEndpoint->EpCallBacks.EpRecvRefill(pEndpoint->EpCallBacks.pContext, ++ pHdr->EndpointID); ++ LOCK_HTC_RX(target); ++ /* check if we have more buffers */ ++ pPacket = HTC_PACKET_DEQUEUE(&pEndpoint->RxBuffers); ++ /* fall through */ ++ } ++ } ++ ++ if (NULL == pPacket) { ++ /* this is not an error, we simply need to mark that we are waiting for buffers.*/ ++ target->HTCStateFlags |= HTC_STATE_WAIT_BUFFERS; ++ target->EpWaitingForBuffers = pHdr->EndpointID; ++ status = A_NO_MEMORY; ++ } ++ ++ UNLOCK_HTC_RX(target); ++ ++ if (A_FAILED(status)) { ++ /* no buffers */ ++ break; ++ } ++ ++ AR_DEBUG_ASSERT(pPacket->Endpoint == pHdr->EndpointID); ++ ++ /* make sure this message can fit in the endpoint buffer */ ++ if ((pHdr->PayloadLen + HTC_HDR_LENGTH) > pPacket->BufferLength) { ++ AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ++ ("Payload Length Error : header reports payload of: %d, endpoint buffer size: %d \n", ++ pHdr->PayloadLen, pPacket->BufferLength)); ++ status = A_EPROTO; ++ break; ++ } ++ ++ pPacket->HTCReserved = LookAhead; /* set expected look ahead */ ++ /* set the amount of data to fetch */ ++ pPacket->ActualLength = pHdr->PayloadLen + HTC_HDR_LENGTH; ++ ++ if (asyncProc) { ++ /* we use async mode to get the packet if the device layer supports it ++ * set our callback and context */ ++ pPacket->Completion = HTCRecvCompleteHandler; ++ pPacket->pContext = target; ++ } else { ++ /* fully synchronous */ ++ pPacket->Completion = NULL; ++ } ++ ++ /* go fetch the packet */ ++ status = HTCIssueRecv(target, pPacket); ++ ++ if (A_FAILED(status)) { ++ break; ++ } ++ ++ if (asyncProc) { ++ /* we did this asynchronously so we can get out of the loop, the asynch processing ++ * creates a chain of requests to continue processing pending messages in the ++ * context of callbacks */ ++ break; ++ } ++ ++ /* in the sync case, we process the packet, check lookaheads and then repeat */ ++ ++ LookAhead = 0; ++ status = HTCProcessRecvHeader(target,pPacket,&LookAhead); ++ ++ if (A_FAILED(status)) { ++ break; ++ } ++ ++ HTC_RX_STAT_PROFILE(target,pEndpoint,LookAhead); ++ DO_RCV_COMPLETION(target,pPacket,pEndpoint); ++ ++ pPacket = NULL; ++ ++ if (0 == LookAhead) { ++ break; ++ } ++ ++ } ++ ++ if (A_NO_MEMORY == status) { ++ AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ++ (" Endpoint :%d has no buffers, blocking receiver to prevent overrun.. \n", ++ pHdr->EndpointID)); ++ /* try to stop receive at the device layer */ ++ DevStopRecv(&target->Device, asyncProc ? DEV_STOP_RECV_ASYNC : DEV_STOP_RECV_SYNC); ++ status = A_OK; ++ } else if (A_FAILED(status)) { ++ AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ++ ("Failed to get pending message : LookAhead Value: 0x%X (status = %d) \n", ++ LookAhead, status)); ++ if (pPacket != NULL) { ++ /* clean up packet on error */ ++ HTC_RECYCLE_RX_PKT(target, pPacket); ++ } ++ } ++ ++ AR_DEBUG_PRINTF(ATH_DEBUG_RECV,("-HTCRecvMessagePendingHandler \n")); ++ ++ return status; ++} ++ ++/* Makes a buffer available to the HTC module */ ++A_STATUS HTCAddReceivePkt(HTC_HANDLE HTCHandle, HTC_PACKET *pPacket) ++{ ++ HTC_TARGET *target = GET_HTC_TARGET_FROM_HANDLE(HTCHandle); ++ HTC_ENDPOINT *pEndpoint; ++ A_BOOL unblockRecv = FALSE; ++ A_STATUS status = A_OK; ++ ++ AR_DEBUG_PRINTF(ATH_DEBUG_SEND, ++ ("+- HTCAddReceivePkt: endPointId: %d, buffer: 0x%X, length: %d\n", ++ pPacket->Endpoint, (A_UINT32)pPacket->pBuffer, pPacket->BufferLength)); ++ ++ do { ++ ++ if (HTC_STOPPING(target)) { ++ status = A_ECANCELED; ++ break; ++ } ++ ++ AR_DEBUG_ASSERT(pPacket->Endpoint < ENDPOINT_MAX); ++ ++ pEndpoint = &target->EndPoint[pPacket->Endpoint]; ++ ++ LOCK_HTC_RX(target); ++ ++ /* store receive packet */ ++ HTC_PACKET_ENQUEUE(&pEndpoint->RxBuffers, pPacket); ++ ++ /* check if we are blocked waiting for a new buffer */ ++ if (target->HTCStateFlags & HTC_STATE_WAIT_BUFFERS) { ++ if (target->EpWaitingForBuffers == pPacket->Endpoint) { ++ AR_DEBUG_PRINTF(ATH_DEBUG_RECV,(" receiver was blocked on ep:%d, unblocking.. \n", ++ target->EpWaitingForBuffers)); ++ target->HTCStateFlags &= ~HTC_STATE_WAIT_BUFFERS; ++ target->EpWaitingForBuffers = ENDPOINT_MAX; ++ unblockRecv = TRUE; ++ } ++ } ++ ++ UNLOCK_HTC_RX(target); ++ ++ if (unblockRecv && !HTC_STOPPING(target)) { ++ /* TODO : implement a buffer threshold count? */ ++ DevEnableRecv(&target->Device,DEV_ENABLE_RECV_SYNC); ++ } ++ ++ } while (FALSE); ++ ++ return status; ++} ++ ++static void HTCFlushEndpointRX(HTC_TARGET *target, HTC_ENDPOINT *pEndpoint) ++{ ++ HTC_PACKET *pPacket; ++ ++ LOCK_HTC_RX(target); ++ ++ while (1) { ++ pPacket = HTC_PACKET_DEQUEUE(&pEndpoint->RxBuffers); ++ if (NULL == pPacket) { ++ break; ++ } ++ UNLOCK_HTC_RX(target); ++ pPacket->Status = A_ECANCELED; ++ pPacket->ActualLength = 0; ++ AR_DEBUG_PRINTF(ATH_DEBUG_RECV, (" Flushing RX packet:0x%X, length:%d, ep:%d \n", ++ (A_UINT32)pPacket, pPacket->BufferLength, pPacket->Endpoint)); ++ /* give the packet back */ ++ pEndpoint->EpCallBacks.EpRecv(pEndpoint->EpCallBacks.pContext, ++ pPacket); ++ LOCK_HTC_RX(target); ++ } ++ ++ UNLOCK_HTC_RX(target); ++ ++ ++} ++ ++void HTCFlushRecvBuffers(HTC_TARGET *target) ++{ ++ HTC_ENDPOINT *pEndpoint; ++ int i; ++ ++ /* NOTE: no need to flush endpoint 0, these buffers were ++ * allocated as part of the HTC struct */ ++ for (i = ENDPOINT_1; i < ENDPOINT_MAX; i++) { ++ pEndpoint = &target->EndPoint[i]; ++ if (pEndpoint->ServiceID == 0) { ++ /* not in use.. */ ++ continue; ++ } ++ HTCFlushEndpointRX(target,pEndpoint); ++ } ++ ++ ++} ++ ++ +diff -ruN --exclude='*.orig' --exclude='*.rej' linux-2.6.29-rc3.owrt/drivers/ar6000/htc/htc_send.c linux-2.6.29-rc3.owrt.om/drivers/ar6000/htc/htc_send.c +--- linux-2.6.29-rc3.owrt/drivers/ar6000/htc/htc_send.c 1970-01-01 01:00:00.000000000 +0100 ++++ linux-2.6.29-rc3.owrt.om/drivers/ar6000/htc/htc_send.c 2009-05-10 22:27:59.000000000 +0200 +@@ -0,0 +1,538 @@ ++/* ++ * ++ * Copyright (c) 2007 Atheros Communications Inc. ++ * All rights reserved. ++ * ++ * ++ * 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; ++ * ++ * Software distributed under the License is distributed on an "AS ++ * IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or ++ * implied. See the License for the specific language governing ++ * rights and limitations under the License. ++ * ++ * ++ * ++ */ ++ ++#include "htc_internal.h" ++ ++#define DO_EP_TX_COMPLETION(ep,p) \ ++{ \ ++ (p)->Completion = NULL; \ ++ (ep)->EpCallBacks.EpTxComplete((ep)->EpCallBacks.pContext,(p)); \ ++} ++ ++ ++/* call the distribute credits callback with the distribution */ ++#define DO_DISTRIBUTION(t,reason,description,pList) \ ++{ \ ++ AR_DEBUG_PRINTF(ATH_DEBUG_SEND, \ ++ (" calling distribute function (%s) (dfn:0x%X, ctxt:0x%X, dist:0x%X) \n", \ ++ (description), \ ++ (A_UINT32)(t)->DistributeCredits, \ ++ (A_UINT32)(t)->pCredDistContext, \ ++ (A_UINT32)pList)); \ ++ (t)->DistributeCredits((t)->pCredDistContext, \ ++ (pList), \ ++ (reason)); \ ++} ++ ++/* our internal send packet completion handler when packets are submited to the AR6K device ++ * layer */ ++static void HTCSendPktCompletionHandler(void *Context, HTC_PACKET *pPacket) ++{ ++ HTC_TARGET *target = (HTC_TARGET *)Context; ++ HTC_ENDPOINT *pEndpoint = &target->EndPoint[pPacket->Endpoint]; ++ ++ ++ if (A_FAILED(pPacket->Status)) { ++ AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ++ ("HTCSendPktCompletionHandler: request failed (status:%d, ep:%d) \n", ++ pPacket->Status, pPacket->Endpoint)); ++ } ++ /* first, fixup the head room we allocated */ ++ pPacket->pBuffer += HTC_HDR_LENGTH; ++ /* do completion */ ++ DO_EP_TX_COMPLETION(pEndpoint,pPacket); ++} ++ ++A_STATUS HTCIssueSend(HTC_TARGET *target, HTC_PACKET *pPacket, A_UINT8 SendFlags) ++{ ++ A_STATUS status; ++ A_UINT8 *pHdrBuf; ++ A_BOOL sync = FALSE; ++ ++ /* caller always provides headrooom */ ++ pPacket->pBuffer -= HTC_HDR_LENGTH; ++ pHdrBuf = pPacket->pBuffer; ++ /* setup frame header */ ++ A_SET_UINT16_FIELD(pHdrBuf,HTC_FRAME_HDR,PayloadLen,(A_UINT16)pPacket->ActualLength); ++ A_SET_UINT8_FIELD(pHdrBuf,HTC_FRAME_HDR,Flags,SendFlags); ++ A_SET_UINT8_FIELD(pHdrBuf,HTC_FRAME_HDR,EndpointID, (A_UINT8)pPacket->Endpoint); ++ ++ if (pPacket->Completion == NULL) { ++ /* mark that this request was synchronously issued */ ++ sync = TRUE; ++ } ++ ++ AR_DEBUG_PRINTF(ATH_DEBUG_SEND, ++ ("+-HTCIssueSend: transmit length : %d (%s) \n", ++ pPacket->ActualLength + HTC_HDR_LENGTH, ++ sync ? "SYNC" : "ASYNC" )); ++ ++ /* send message to device */ ++ status = DevSendPacket(&target->Device, ++ pPacket, ++ pPacket->ActualLength + HTC_HDR_LENGTH); ++ ++ if (sync) { ++ /* use local sync variable. If this was issued asynchronously, pPacket is no longer ++ * safe to access. */ ++ pPacket->pBuffer += HTC_HDR_LENGTH; ++ } ++ ++ /* if this request was asynchronous, the packet completion routine will be invoked by ++ * the device layer when the HIF layer completes the request */ ++ ++ return status; ++} ++ ++/* try to send the current packet or a packet at the head of the TX queue, ++ * if there are no credits, the packet remains in the queue. */ ++static void HTCTrySend(HTC_TARGET *target, ++ HTC_PACKET *pPacketToSend, ++ HTC_ENDPOINT_ID ep) ++{ ++ HTC_PACKET *pPacket; ++ HTC_ENDPOINT *pEndpoint; ++ int creditsRequired; ++ A_UINT8 sendFlags; ++ ++ AR_DEBUG_PRINTF(ATH_DEBUG_SEND,("+HTCTrySend (pPkt:0x%X)\n",(A_UINT32)pPacketToSend)); ++ ++ pEndpoint = &target->EndPoint[ep]; ++ ++ LOCK_HTC_TX(target); ++ ++ if (pPacketToSend != NULL) { ++ /* caller supplied us a packet to queue to the tail of the HTC TX queue before ++ * we check the tx queue */ ++ HTC_PACKET_ENQUEUE(&pEndpoint->TxQueue,pPacketToSend); ++ pEndpoint->CurrentTxQueueDepth++; ++ } ++ ++ /* now drain the TX queue for transmission as long as we have enough ++ * credits */ ++ ++ while (1) { ++ ++ if (HTC_QUEUE_EMPTY(&pEndpoint->TxQueue)) { ++ /* nothing in the queue */ ++ break; ++ } ++ ++ sendFlags = 0; ++ ++ /* get packet at head, but don't remove it */ ++ pPacket = HTC_GET_PKT_AT_HEAD(&pEndpoint->TxQueue); ++ AR_DEBUG_PRINTF(ATH_DEBUG_SEND,(" Got head packet:0x%X , Queue Depth: %d\n", ++ (A_UINT32)pPacket, pEndpoint->CurrentTxQueueDepth)); ++ ++ /* figure out how many credits this message requires */ ++ creditsRequired = pPacket->ActualLength + HTC_HDR_LENGTH; ++ creditsRequired += target->TargetCreditSize - 1; ++ creditsRequired /= target->TargetCreditSize; ++ ++ AR_DEBUG_PRINTF(ATH_DEBUG_SEND,(" Creds Required:%d Got:%d\n", ++ creditsRequired, pEndpoint->CreditDist.TxCredits)); ++ ++ if (pEndpoint->CreditDist.TxCredits < creditsRequired) { ++ ++ /* not enough credits */ ++ ++ if (pPacket->Endpoint == ENDPOINT_0) { ++ /* leave it in the queue */ ++ break; ++ } ++ /* invoke the registered distribution function only if this is not ++ * endpoint 0, we let the driver layer provide more credits if it can. ++ * We pass the credit distribution list starting at the endpoint in question ++ * */ ++ ++ /* set how many credits we need */ ++ pEndpoint->CreditDist.TxCreditsSeek = ++ creditsRequired - pEndpoint->CreditDist.TxCredits; ++ DO_DISTRIBUTION(target, ++ HTC_CREDIT_DIST_SEEK_CREDITS, ++ "Seek Credits", ++ &pEndpoint->CreditDist); ++ ++ pEndpoint->CreditDist.TxCreditsSeek = 0; ++ ++ if (pEndpoint->CreditDist.TxCredits < creditsRequired) { ++ /* still not enough credits to send, leave packet in the queue */ ++ AR_DEBUG_PRINTF(ATH_DEBUG_SEND, ++ (" Not enough credits for ep %d leaving packet in queue..\n", ++ pPacket->Endpoint)); ++ break; ++ } ++ ++ } ++ ++ pEndpoint->CreditDist.TxCredits -= creditsRequired; ++ INC_HTC_EP_STAT(pEndpoint, TxCreditsConsummed, creditsRequired); ++ ++ /* check if we need credits */ ++ if (pEndpoint->CreditDist.TxCredits < pEndpoint->CreditDist.TxCreditsPerMaxMsg) { ++ sendFlags |= HTC_FLAGS_NEED_CREDIT_UPDATE; ++ INC_HTC_EP_STAT(pEndpoint, TxCreditLowIndications, 1); ++ AR_DEBUG_PRINTF(ATH_DEBUG_SEND,(" Host Needs Credits \n")); ++ } ++ ++ /* now we can fully dequeue */ ++ pPacket = HTC_PACKET_DEQUEUE(&pEndpoint->TxQueue); ++ pEndpoint->CurrentTxQueueDepth--; ++ ++ INC_HTC_EP_STAT(pEndpoint, TxIssued, 1); ++ ++ UNLOCK_HTC_TX(target); ++ ++ HTCIssueSend(target, pPacket, sendFlags); ++ ++ LOCK_HTC_TX(target); ++ ++ /* go back and check for more messages */ ++ } ++ ++ if (pEndpoint->CurrentTxQueueDepth >= pEndpoint->MaxTxQueueDepth) { ++ AR_DEBUG_PRINTF(ATH_DEBUG_SEND, (" Endpoint %d, TX queue is full, Depth:%d, Max:%d \n", ++ ep, pEndpoint->CurrentTxQueueDepth, pEndpoint->MaxTxQueueDepth)); ++ UNLOCK_HTC_TX(target); ++ /* queue is now full, let caller know */ ++ if (pEndpoint->EpCallBacks.EpSendFull != NULL) { ++ AR_DEBUG_PRINTF(ATH_DEBUG_SEND, (" Calling driver's send full callback.... \n")); ++ pEndpoint->EpCallBacks.EpSendFull(pEndpoint->EpCallBacks.pContext, ep); ++ } ++ } else { ++ UNLOCK_HTC_TX(target); ++ /* queue is now available for new packet, let caller know */ ++ if (pEndpoint->EpCallBacks.EpSendAvail) ++ pEndpoint->EpCallBacks.EpSendAvail(pEndpoint->EpCallBacks.pContext, ep); ++ } ++ ++ AR_DEBUG_PRINTF(ATH_DEBUG_SEND,("-HTCTrySend: \n")); ++} ++ ++/* HTC API - HTCSendPkt */ ++A_STATUS HTCSendPkt(HTC_HANDLE HTCHandle, HTC_PACKET *pPacket) ++{ ++ HTC_TARGET *target = GET_HTC_TARGET_FROM_HANDLE(HTCHandle); ++ HTC_ENDPOINT *pEndpoint; ++ HTC_ENDPOINT_ID ep; ++ A_STATUS status = A_OK; ++ ++ AR_DEBUG_PRINTF(ATH_DEBUG_SEND, ++ ("+HTCSendPkt: Enter endPointId: %d, buffer: 0x%X, length: %d \n", ++ pPacket->Endpoint, (A_UINT32)pPacket->pBuffer, pPacket->ActualLength)); ++ ++ ep = pPacket->Endpoint; ++ AR_DEBUG_ASSERT(ep < ENDPOINT_MAX); ++ pEndpoint = &target->EndPoint[ep]; ++ ++ do { ++ ++ if (HTC_STOPPING(target)) { ++ status = A_ECANCELED; ++ pPacket->Status = status; ++ DO_EP_TX_COMPLETION(pEndpoint,pPacket); ++ break; ++ } ++ /* everything sent through this interface is asynchronous */ ++ /* fill in HTC completion routines */ ++ pPacket->Completion = HTCSendPktCompletionHandler; ++ pPacket->pContext = target; ++ ++ HTCTrySend(target, pPacket, ep); ++ ++ } while (FALSE); ++ ++ AR_DEBUG_PRINTF(ATH_DEBUG_SEND, ("-HTCSendPkt \n")); ++ ++ return status; ++} ++ ++ ++/* check TX queues to drain because of credit distribution update */ ++static INLINE void HTCCheckEndpointTxQueues(HTC_TARGET *target) ++{ ++ HTC_ENDPOINT *pEndpoint; ++ HTC_ENDPOINT_CREDIT_DIST *pDistItem; ++ ++ AR_DEBUG_PRINTF(ATH_DEBUG_SEND, ("+HTCCheckEndpointTxQueues \n")); ++ pDistItem = target->EpCreditDistributionListHead; ++ ++ /* run through the credit distribution list to see ++ * if there are packets queued ++ * NOTE: no locks need to be taken since the distribution list ++ * is not dynamic (cannot be re-ordered) and we are not modifying any state */ ++ while (pDistItem != NULL) { ++ pEndpoint = (HTC_ENDPOINT *)pDistItem->pHTCReserved; ++ ++ if (pEndpoint->CurrentTxQueueDepth > 0) { ++ AR_DEBUG_PRINTF(ATH_DEBUG_SEND, (" Ep %d has %d credits and %d Packets in TX Queue \n", ++ pDistItem->Endpoint, pEndpoint->CreditDist.TxCredits, pEndpoint->CurrentTxQueueDepth)); ++ /* try to start the stalled queue, this list is ordered by priority. ++ * Highest priority queue get's processed first, if there are credits available the ++ * highest priority queue will get a chance to reclaim credits from lower priority ++ * ones */ ++ HTCTrySend(target, NULL, pDistItem->Endpoint); ++ } ++ ++ pDistItem = pDistItem->pNext; ++ } ++ ++ AR_DEBUG_PRINTF(ATH_DEBUG_SEND, ("-HTCCheckEndpointTxQueues \n")); ++} ++ ++/* process credit reports and call distribution function */ ++void HTCProcessCreditRpt(HTC_TARGET *target, HTC_CREDIT_REPORT *pRpt, int NumEntries, HTC_ENDPOINT_ID FromEndpoint) ++{ ++ int i; ++ HTC_ENDPOINT *pEndpoint; ++ int totalCredits = 0; ++ A_BOOL doDist = FALSE; ++ ++ AR_DEBUG_PRINTF(ATH_DEBUG_SEND, ("+HTCProcessCreditRpt, Credit Report Entries:%d \n", NumEntries)); ++ ++ /* lock out TX while we update credits */ ++ LOCK_HTC_TX(target); ++ ++ for (i = 0; i < NumEntries; i++, pRpt++) { ++ if (pRpt->EndpointID >= ENDPOINT_MAX) { ++ AR_DEBUG_ASSERT(FALSE); ++ break; ++ } ++ ++ pEndpoint = &target->EndPoint[pRpt->EndpointID]; ++ ++ AR_DEBUG_PRINTF(ATH_DEBUG_SEND, (" Endpoint %d got %d credits \n", ++ pRpt->EndpointID, pRpt->Credits)); ++ ++ ++#ifdef HTC_EP_STAT_PROFILING ++ ++ INC_HTC_EP_STAT(pEndpoint, TxCreditRpts, 1); ++ INC_HTC_EP_STAT(pEndpoint, TxCreditsReturned, pRpt->Credits); ++ ++ if (FromEndpoint == pRpt->EndpointID) { ++ /* this credit report arrived on the same endpoint indicating it arrived in an RX ++ * packet */ ++ INC_HTC_EP_STAT(pEndpoint, TxCreditsFromRx, pRpt->Credits); ++ INC_HTC_EP_STAT(pEndpoint, TxCreditRptsFromRx, 1); ++ } else if (FromEndpoint == ENDPOINT_0) { ++ /* this credit arrived on endpoint 0 as a NULL message */ ++ INC_HTC_EP_STAT(pEndpoint, TxCreditsFromEp0, pRpt->Credits); ++ INC_HTC_EP_STAT(pEndpoint, TxCreditRptsFromEp0, 1); ++ } else { ++ /* arrived on another endpoint */ ++ INC_HTC_EP_STAT(pEndpoint, TxCreditsFromOther, pRpt->Credits); ++ INC_HTC_EP_STAT(pEndpoint, TxCreditRptsFromOther, 1); ++ } ++ ++#endif ++ ++ if (ENDPOINT_0 == pRpt->EndpointID) { ++ /* always give endpoint 0 credits back */ ++ pEndpoint->CreditDist.TxCredits += pRpt->Credits; ++ } else { ++ /* for all other endpoints, update credits to distribute, the distribution function ++ * will handle giving out credits back to the endpoints */ ++ pEndpoint->CreditDist.TxCreditsToDist += pRpt->Credits; ++ /* flag that we have to do the distribution */ ++ doDist = TRUE; ++ } ++ ++ totalCredits += pRpt->Credits; ++ } ++ ++ AR_DEBUG_PRINTF(ATH_DEBUG_SEND, (" Report indicated %d credits to distribute \n", totalCredits)); ++ ++ if (doDist) { ++ /* this was a credit return based on a completed send operations ++ * note, this is done with the lock held */ ++ DO_DISTRIBUTION(target, ++ HTC_CREDIT_DIST_SEND_COMPLETE, ++ "Send Complete", ++ target->EpCreditDistributionListHead->pNext); ++ } ++ ++ UNLOCK_HTC_TX(target); ++ ++ if (totalCredits) { ++ HTCCheckEndpointTxQueues(target); ++ } ++ ++ AR_DEBUG_PRINTF(ATH_DEBUG_SEND, ("-HTCProcessCreditRpt \n")); ++} ++ ++/* flush endpoint TX queue */ ++static void HTCFlushEndpointTX(HTC_TARGET *target, HTC_ENDPOINT *pEndpoint, HTC_TX_TAG Tag) ++{ ++ HTC_PACKET *pPacket; ++ HTC_PACKET_QUEUE discardQueue; ++ ++ /* initialize the discard queue */ ++ INIT_HTC_PACKET_QUEUE(&discardQueue); ++ ++ LOCK_HTC_TX(target); ++ ++ /* interate from the front of the TX queue and flush out packets */ ++ ITERATE_OVER_LIST_ALLOW_REMOVE(&pEndpoint->TxQueue, pPacket, HTC_PACKET, ListLink) { ++ ++ /* check for removal */ ++ if ((HTC_TX_PACKET_TAG_ALL == Tag) || (Tag == pPacket->PktInfo.AsTx.Tag)) { ++ /* remove from queue */ ++ HTC_PACKET_REMOVE(pPacket); ++ /* add it to the discard pile */ ++ HTC_PACKET_ENQUEUE(&discardQueue, pPacket); ++ pEndpoint->CurrentTxQueueDepth--; ++ } ++ ++ } ITERATE_END; ++ ++ UNLOCK_HTC_TX(target); ++ ++ /* empty the discard queue */ ++ while (1) { ++ pPacket = HTC_PACKET_DEQUEUE(&discardQueue); ++ if (NULL == pPacket) { ++ break; ++ } ++ pPacket->Status = A_ECANCELED; ++ AR_DEBUG_PRINTF(ATH_DEBUG_TRC, (" Flushing TX packet:0x%X, length:%d, ep:%d tag:0x%X \n", ++ (A_UINT32)pPacket, pPacket->ActualLength, pPacket->Endpoint, pPacket->PktInfo.AsTx.Tag)); ++ DO_EP_TX_COMPLETION(pEndpoint,pPacket); ++ } ++ ++} ++ ++void DumpCreditDist(HTC_ENDPOINT_CREDIT_DIST *pEPDist) ++{ ++#ifdef DEBUG ++ HTC_ENDPOINT *pEndpoint = (HTC_ENDPOINT *)pEPDist->pHTCReserved; ++#endif ++ ++ AR_DEBUG_PRINTF(ATH_DEBUG_ANY, ("--- EP : %d ServiceID: 0x%X --------------\n", ++ pEPDist->Endpoint, pEPDist->ServiceID)); ++ AR_DEBUG_PRINTF(ATH_DEBUG_ANY, (" this:0x%X next:0x%X prev:0x%X\n", ++ (A_UINT32)pEPDist, (A_UINT32)pEPDist->pNext, (A_UINT32)pEPDist->pPrev)); ++ AR_DEBUG_PRINTF(ATH_DEBUG_ANY, (" DistFlags : 0x%X \n", pEPDist->DistFlags)); ++ AR_DEBUG_PRINTF(ATH_DEBUG_ANY, (" TxCreditsNorm : %d \n", pEPDist->TxCreditsNorm)); ++ AR_DEBUG_PRINTF(ATH_DEBUG_ANY, (" TxCreditsMin : %d \n", pEPDist->TxCreditsMin)); ++ AR_DEBUG_PRINTF(ATH_DEBUG_ANY, (" TxCredits : %d \n", pEPDist->TxCredits)); ++ AR_DEBUG_PRINTF(ATH_DEBUG_ANY, (" TxCreditsAssigned : %d \n", pEPDist->TxCreditsAssigned)); ++ AR_DEBUG_PRINTF(ATH_DEBUG_ANY, (" TxCreditsSeek : %d \n", pEPDist->TxCreditsSeek)); ++ AR_DEBUG_PRINTF(ATH_DEBUG_ANY, (" TxCreditSize : %d \n", pEPDist->TxCreditSize)); ++ AR_DEBUG_PRINTF(ATH_DEBUG_ANY, (" TxCreditsPerMaxMsg : %d \n", pEPDist->TxCreditsPerMaxMsg)); ++ AR_DEBUG_PRINTF(ATH_DEBUG_ANY, (" TxCreditsToDist : %d \n", pEPDist->TxCreditsToDist)); ++ AR_DEBUG_PRINTF(ATH_DEBUG_ANY, (" TxQueueDepth : %d \n", pEndpoint->CurrentTxQueueDepth)); ++ AR_DEBUG_PRINTF(ATH_DEBUG_ANY, ("----------------------------------------------------\n")); ++} ++ ++void DumpCreditDistStates(HTC_TARGET *target) ++{ ++ HTC_ENDPOINT_CREDIT_DIST *pEPList = target->EpCreditDistributionListHead; ++ ++ while (pEPList != NULL) { ++ DumpCreditDist(pEPList); ++ pEPList = pEPList->pNext; ++ } ++ ++ if (target->DistributeCredits != NULL) { ++ DO_DISTRIBUTION(target, ++ HTC_DUMP_CREDIT_STATE, ++ "Dump State", ++ NULL); ++ } ++} ++ ++/* flush all send packets from all endpoint queues */ ++void HTCFlushSendPkts(HTC_TARGET *target) ++{ ++ HTC_ENDPOINT *pEndpoint; ++ int i; ++ ++ DumpCreditDistStates(target); ++ ++ for (i = ENDPOINT_0; i < ENDPOINT_MAX; i++) { ++ pEndpoint = &target->EndPoint[i]; ++ if (pEndpoint->ServiceID == 0) { ++ /* not in use.. */ ++ continue; ++ } ++ HTCFlushEndpointTX(target,pEndpoint,HTC_TX_PACKET_TAG_ALL); ++ } ++ ++} ++ ++/* HTC API to flush an endpoint's TX queue*/ ++void HTCFlushEndpoint(HTC_HANDLE HTCHandle, HTC_ENDPOINT_ID Endpoint, HTC_TX_TAG Tag) ++{ ++ HTC_TARGET *target = GET_HTC_TARGET_FROM_HANDLE(HTCHandle); ++ HTC_ENDPOINT *pEndpoint = &target->EndPoint[Endpoint]; ++ ++ if (pEndpoint->ServiceID == 0) { ++ AR_DEBUG_ASSERT(FALSE); ++ /* not in use.. */ ++ return; ++ } ++ ++ HTCFlushEndpointTX(target, pEndpoint, Tag); ++} ++ ++/* HTC API to indicate activity to the credit distribution function */ ++void HTCIndicateActivityChange(HTC_HANDLE HTCHandle, ++ HTC_ENDPOINT_ID Endpoint, ++ A_BOOL Active) ++{ ++ HTC_TARGET *target = GET_HTC_TARGET_FROM_HANDLE(HTCHandle); ++ HTC_ENDPOINT *pEndpoint = &target->EndPoint[Endpoint]; ++ A_BOOL doDist = FALSE; ++ ++ if (pEndpoint->ServiceID == 0) { ++ AR_DEBUG_ASSERT(FALSE); ++ /* not in use.. */ ++ return; ++ } ++ ++ LOCK_HTC_TX(target); ++ ++ if (Active) { ++ if (!(pEndpoint->CreditDist.DistFlags & HTC_EP_ACTIVE)) { ++ /* mark active now */ ++ pEndpoint->CreditDist.DistFlags |= HTC_EP_ACTIVE; ++ doDist = TRUE; ++ } ++ } else { ++ if (pEndpoint->CreditDist.DistFlags & HTC_EP_ACTIVE) { ++ /* mark inactive now */ ++ pEndpoint->CreditDist.DistFlags &= ~HTC_EP_ACTIVE; ++ doDist = TRUE; ++ } ++ } ++ ++ if (doDist) { ++ /* do distribution again based on activity change ++ * note, this is done with the lock held */ ++ DO_DISTRIBUTION(target, ++ HTC_CREDIT_DIST_ACTIVITY_CHANGE, ++ "Activity Change", ++ target->EpCreditDistributionListHead->pNext); ++ } ++ ++ UNLOCK_HTC_TX(target); ++ ++} +diff -ruN --exclude='*.orig' --exclude='*.rej' linux-2.6.29-rc3.owrt/drivers/ar6000/htc/htc_services.c linux-2.6.29-rc3.owrt.om/drivers/ar6000/htc/htc_services.c +--- linux-2.6.29-rc3.owrt/drivers/ar6000/htc/htc_services.c 1970-01-01 01:00:00.000000000 +0100 ++++ linux-2.6.29-rc3.owrt.om/drivers/ar6000/htc/htc_services.c 2009-05-10 22:27:59.000000000 +0200 +@@ -0,0 +1,403 @@ ++/* ++ * ++ * Copyright (c) 2007 Atheros Communications Inc. ++ * All rights reserved. ++ * ++ * ++ * 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; ++ * ++ * Software distributed under the License is distributed on an "AS ++ * IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or ++ * implied. See the License for the specific language governing ++ * rights and limitations under the License. ++ * ++ * ++ * ++ */ ++ ++#include "htc_internal.h" ++ ++void HTCControlTxComplete(void *Context, HTC_PACKET *pPacket) ++{ ++ /* not implemented ++ * we do not send control TX frames during normal runtime, only during setup */ ++ AR_DEBUG_ASSERT(FALSE); ++} ++ ++ /* callback when a control message arrives on this endpoint */ ++void HTCControlRecv(void *Context, HTC_PACKET *pPacket) ++{ ++ AR_DEBUG_ASSERT(pPacket->Endpoint == ENDPOINT_0); ++ ++ /* the only control messages we are expecting are NULL messages (credit resports), which should ++ * never get here */ ++ AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ++ ("HTCControlRecv, got message with length:%d \n", ++ pPacket->ActualLength + HTC_HDR_LENGTH)); ++ ++ /* dump header and message */ ++ DebugDumpBytes(pPacket->pBuffer - HTC_HDR_LENGTH, ++ pPacket->ActualLength + HTC_HDR_LENGTH, ++ "Unexpected ENDPOINT 0 Message"); ++ ++ HTC_RECYCLE_RX_PKT((HTC_TARGET*)Context,pPacket); ++} ++ ++A_STATUS HTCSendSetupComplete(HTC_TARGET *target) ++{ ++ HTC_PACKET *pSendPacket = NULL; ++ A_STATUS status; ++ HTC_SETUP_COMPLETE_MSG *pSetupComplete; ++ ++ do { ++ /* allocate a packet to send to the target */ ++ pSendPacket = HTC_ALLOC_CONTROL_TX(target); ++ ++ if (NULL == pSendPacket) { ++ status = A_NO_MEMORY; ++ break; ++ } ++ ++ /* assemble setup complete message */ ++ pSetupComplete = (HTC_SETUP_COMPLETE_MSG *)pSendPacket->pBuffer; ++ A_MEMZERO(pSetupComplete,sizeof(HTC_SETUP_COMPLETE_MSG)); ++ pSetupComplete->MessageID = HTC_MSG_SETUP_COMPLETE_ID; ++ ++ SET_HTC_PACKET_INFO_TX(pSendPacket, ++ NULL, ++ (A_UINT8 *)pSetupComplete, ++ sizeof(HTC_SETUP_COMPLETE_MSG), ++ ENDPOINT_0, ++ HTC_SERVICE_TX_PACKET_TAG); ++ ++ /* we want synchronous operation */ ++ pSendPacket->Completion = NULL; ++ /* send the message */ ++ status = HTCIssueSend(target,pSendPacket,0); ++ ++ } while (FALSE); ++ ++ if (pSendPacket != NULL) { ++ HTC_FREE_CONTROL_TX(target,pSendPacket); ++ } ++ ++ return status; ++} ++ ++ ++A_STATUS HTCConnectService(HTC_HANDLE HTCHandle, ++ HTC_SERVICE_CONNECT_REQ *pConnectReq, ++ HTC_SERVICE_CONNECT_RESP *pConnectResp) ++{ ++ HTC_TARGET *target = GET_HTC_TARGET_FROM_HANDLE(HTCHandle); ++ A_STATUS status = A_OK; ++ HTC_PACKET *pRecvPacket = NULL; ++ HTC_PACKET *pSendPacket = NULL; ++ HTC_CONNECT_SERVICE_RESPONSE_MSG *pResponseMsg; ++ HTC_CONNECT_SERVICE_MSG *pConnectMsg; ++ HTC_ENDPOINT_ID assignedEndpoint = ENDPOINT_MAX; ++ HTC_ENDPOINT *pEndpoint; ++ int maxMsgSize = 0; ++ ++ AR_DEBUG_PRINTF(ATH_DEBUG_TRC, ("+HTCConnectService, target:0x%X SvcID:0x%X \n", ++ (A_UINT32)target, pConnectReq->ServiceID)); ++ ++ do { ++ ++ AR_DEBUG_ASSERT(pConnectReq->ServiceID != 0); ++ ++ if (HTC_CTRL_RSVD_SVC == pConnectReq->ServiceID) { ++ /* special case for pseudo control service */ ++ assignedEndpoint = ENDPOINT_0; ++ maxMsgSize = HTC_MAX_CONTROL_MESSAGE_LENGTH; ++ } else { ++ /* allocate a packet to send to the target */ ++ pSendPacket = HTC_ALLOC_CONTROL_TX(target); ++ ++ if (NULL == pSendPacket) { ++ AR_DEBUG_ASSERT(FALSE); ++ status = A_NO_MEMORY; ++ break; ++ } ++ /* assemble connect service message */ ++ pConnectMsg = (HTC_CONNECT_SERVICE_MSG *)pSendPacket->pBuffer; ++ AR_DEBUG_ASSERT(pConnectMsg != NULL); ++ A_MEMZERO(pConnectMsg,sizeof(HTC_CONNECT_SERVICE_MSG)); ++ pConnectMsg->MessageID = HTC_MSG_CONNECT_SERVICE_ID; ++ pConnectMsg->ServiceID = pConnectReq->ServiceID; ++ pConnectMsg->ConnectionFlags = pConnectReq->ConnectionFlags; ++ /* check caller if it wants to transfer meta data */ ++ if ((pConnectReq->pMetaData != NULL) && ++ (pConnectReq->MetaDataLength <= HTC_SERVICE_META_DATA_MAX_LENGTH)) { ++ /* copy meta data into message buffer (after header ) */ ++ A_MEMCPY((A_UINT8 *)pConnectMsg + sizeof(HTC_CONNECT_SERVICE_MSG), ++ pConnectReq->pMetaData, ++ pConnectReq->MetaDataLength); ++ pConnectMsg->ServiceMetaLength = pConnectReq->MetaDataLength; ++ } ++ ++ SET_HTC_PACKET_INFO_TX(pSendPacket, ++ NULL, ++ (A_UINT8 *)pConnectMsg, ++ sizeof(HTC_CONNECT_SERVICE_MSG) + pConnectMsg->ServiceMetaLength, ++ ENDPOINT_0, ++ HTC_SERVICE_TX_PACKET_TAG); ++ ++ /* we want synchronous operation */ ++ pSendPacket->Completion = NULL; ++ ++ status = HTCIssueSend(target,pSendPacket,0); ++ ++ if (A_FAILED(status)) { ++ break; ++ } ++ ++ /* wait for response */ ++ status = HTCWaitforControlMessage(target, &pRecvPacket); ++ ++ if (A_FAILED(status)) { ++ break; ++ } ++ /* we controlled the buffer creation so it has to be properly aligned */ ++ pResponseMsg = (HTC_CONNECT_SERVICE_RESPONSE_MSG *)pRecvPacket->pBuffer; ++ ++ if ((pResponseMsg->MessageID != HTC_MSG_CONNECT_SERVICE_RESPONSE_ID) || ++ (pRecvPacket->ActualLength < sizeof(HTC_CONNECT_SERVICE_RESPONSE_MSG))) { ++ /* this message is not valid */ ++ AR_DEBUG_ASSERT(FALSE); ++ status = A_EPROTO; ++ break; ++ } ++ ++ pConnectResp->ConnectRespCode = pResponseMsg->Status; ++ /* check response status */ ++ if (pResponseMsg->Status != HTC_SERVICE_SUCCESS) { ++ AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ++ (" Target failed service 0x%X connect request (status:%d)\n", ++ pResponseMsg->ServiceID, pResponseMsg->Status)); ++ status = A_EPROTO; ++ break; ++ } ++ ++ assignedEndpoint = pResponseMsg->EndpointID; ++ maxMsgSize = pResponseMsg->MaxMsgSize; ++ ++ if ((pConnectResp->pMetaData != NULL) && ++ (pResponseMsg->ServiceMetaLength > 0) && ++ (pResponseMsg->ServiceMetaLength <= HTC_SERVICE_META_DATA_MAX_LENGTH)) { ++ /* caller supplied a buffer and the target responded with data */ ++ int copyLength = min((int)pConnectResp->BufferLength, (int)pResponseMsg->ServiceMetaLength); ++ /* copy the meta data */ ++ A_MEMCPY(pConnectResp->pMetaData, ++ ((A_UINT8 *)pResponseMsg) + sizeof(HTC_CONNECT_SERVICE_RESPONSE_MSG), ++ copyLength); ++ pConnectResp->ActualLength = copyLength; ++ } ++ ++ } ++ ++ /* the rest of these are parameter checks so set the error status */ ++ status = A_EPROTO; ++ ++ if (assignedEndpoint >= ENDPOINT_MAX) { ++ AR_DEBUG_ASSERT(FALSE); ++ break; ++ } ++ ++ if (0 == maxMsgSize) { ++ AR_DEBUG_ASSERT(FALSE); ++ break; ++ } ++ ++ pEndpoint = &target->EndPoint[assignedEndpoint]; ++ ++ if (pEndpoint->ServiceID != 0) { ++ /* endpoint already in use! */ ++ AR_DEBUG_ASSERT(FALSE); ++ break; ++ } ++ ++ /* return assigned endpoint to caller */ ++ pConnectResp->Endpoint = assignedEndpoint; ++ pConnectResp->MaxMsgLength = maxMsgSize; ++ ++ /* setup the endpoint */ ++ pEndpoint->ServiceID = pConnectReq->ServiceID; /* this marks the endpoint in use */ ++ pEndpoint->MaxTxQueueDepth = pConnectReq->MaxSendQueueDepth; ++ pEndpoint->MaxMsgLength = maxMsgSize; ++ /* copy all the callbacks */ ++ pEndpoint->EpCallBacks = pConnectReq->EpCallbacks; ++ INIT_HTC_PACKET_QUEUE(&pEndpoint->RxBuffers); ++ INIT_HTC_PACKET_QUEUE(&pEndpoint->TxQueue); ++ /* set the credit distribution info for this endpoint, this information is ++ * passed back to the credit distribution callback function */ ++ pEndpoint->CreditDist.ServiceID = pConnectReq->ServiceID; ++ pEndpoint->CreditDist.pHTCReserved = pEndpoint; ++ pEndpoint->CreditDist.Endpoint = assignedEndpoint; ++ pEndpoint->CreditDist.TxCreditSize = target->TargetCreditSize; ++ pEndpoint->CreditDist.TxCreditsPerMaxMsg = maxMsgSize / target->TargetCreditSize; ++ ++ if (0 == pEndpoint->CreditDist.TxCreditsPerMaxMsg) { ++ pEndpoint->CreditDist.TxCreditsPerMaxMsg = 1; ++ } ++ ++ status = A_OK; ++ ++ } while (FALSE); ++ ++ if (pSendPacket != NULL) { ++ HTC_FREE_CONTROL_TX(target,pSendPacket); ++ } ++ ++ if (pRecvPacket != NULL) { ++ HTC_FREE_CONTROL_RX(target,pRecvPacket); ++ } ++ ++ AR_DEBUG_PRINTF(ATH_DEBUG_TRC, ("-HTCConnectService \n")); ++ ++ return status; ++} ++ ++static void AddToEndpointDistList(HTC_TARGET *target, HTC_ENDPOINT_CREDIT_DIST *pEpDist) ++{ ++ HTC_ENDPOINT_CREDIT_DIST *pCurEntry,*pLastEntry; ++ ++ if (NULL == target->EpCreditDistributionListHead) { ++ target->EpCreditDistributionListHead = pEpDist; ++ pEpDist->pNext = NULL; ++ pEpDist->pPrev = NULL; ++ return; ++ } ++ ++ /* queue to the end of the list, this does not have to be very ++ * fast since this list is built at startup time */ ++ pCurEntry = target->EpCreditDistributionListHead; ++ ++ while (pCurEntry) { ++ pLastEntry = pCurEntry; ++ pCurEntry = pCurEntry->pNext; ++ } ++ ++ pLastEntry->pNext = pEpDist; ++ pEpDist->pPrev = pLastEntry; ++ pEpDist->pNext = NULL; ++} ++ ++ ++ ++/* default credit init callback */ ++static void HTCDefaultCreditInit(void *Context, ++ HTC_ENDPOINT_CREDIT_DIST *pEPList, ++ int TotalCredits) ++{ ++ HTC_ENDPOINT_CREDIT_DIST *pCurEpDist; ++ int totalEps = 0; ++ int creditsPerEndpoint; ++ ++ pCurEpDist = pEPList; ++ /* first run through the list and figure out how many endpoints we are dealing with */ ++ while (pCurEpDist != NULL) { ++ pCurEpDist = pCurEpDist->pNext; ++ totalEps++; ++ } ++ ++ /* even distribution */ ++ creditsPerEndpoint = TotalCredits/totalEps; ++ ++ pCurEpDist = pEPList; ++ /* run through the list and set minimum and normal credits and ++ * provide the endpoint with some credits to start */ ++ while (pCurEpDist != NULL) { ++ ++ if (creditsPerEndpoint < pCurEpDist->TxCreditsPerMaxMsg) { ++ /* too many endpoints and not enough credits */ ++ AR_DEBUG_ASSERT(FALSE); ++ break; ++ } ++ /* our minimum is set for at least 1 max message */ ++ pCurEpDist->TxCreditsMin = pCurEpDist->TxCreditsPerMaxMsg; ++ /* this value is ignored by our credit alg, since we do ++ * not dynamically adjust credits, this is the policy of ++ * the "default" credit distribution, something simple and easy */ ++ pCurEpDist->TxCreditsNorm = 0xFFFF; ++ /* give the endpoint minimum credits */ ++ pCurEpDist->TxCredits = creditsPerEndpoint; ++ pCurEpDist->TxCreditsAssigned = creditsPerEndpoint; ++ pCurEpDist = pCurEpDist->pNext; ++ } ++ ++} ++ ++/* default credit distribution callback, NOTE, this callback holds the TX lock */ ++void HTCDefaultCreditDist(void *Context, ++ HTC_ENDPOINT_CREDIT_DIST *pEPDistList, ++ HTC_CREDIT_DIST_REASON Reason) ++{ ++ HTC_ENDPOINT_CREDIT_DIST *pCurEpDist; ++ ++ if (Reason == HTC_CREDIT_DIST_SEND_COMPLETE) { ++ pCurEpDist = pEPDistList; ++ /* simple distribution */ ++ while (pCurEpDist != NULL) { ++ if (pCurEpDist->TxCreditsToDist > 0) { ++ /* just give the endpoint back the credits */ ++ pCurEpDist->TxCredits += pCurEpDist->TxCreditsToDist; ++ pCurEpDist->TxCreditsToDist = 0; ++ } ++ pCurEpDist = pCurEpDist->pNext; ++ } ++ } ++ ++ /* note we do not need to handle the other reason codes as this is a very ++ * simple distribution scheme, no need to seek for more credits or handle inactivity */ ++} ++ ++void HTCSetCreditDistribution(HTC_HANDLE HTCHandle, ++ void *pCreditDistContext, ++ HTC_CREDIT_DIST_CALLBACK CreditDistFunc, ++ HTC_CREDIT_INIT_CALLBACK CreditInitFunc, ++ HTC_SERVICE_ID ServicePriorityOrder[], ++ int ListLength) ++{ ++ HTC_TARGET *target = GET_HTC_TARGET_FROM_HANDLE(HTCHandle); ++ int i; ++ int ep; ++ ++ if (CreditInitFunc != NULL) { ++ /* caller has supplied their own distribution functions */ ++ target->InitCredits = CreditInitFunc; ++ AR_DEBUG_ASSERT(CreditDistFunc != NULL); ++ target->DistributeCredits = CreditDistFunc; ++ target->pCredDistContext = pCreditDistContext; ++ } else { ++ /* caller wants HTC to do distribution */ ++ /* if caller wants service to handle distributions then ++ * it must set both of these to NULL! */ ++ AR_DEBUG_ASSERT(CreditDistFunc == NULL); ++ target->InitCredits = HTCDefaultCreditInit; ++ target->DistributeCredits = HTCDefaultCreditDist; ++ target->pCredDistContext = target; ++ } ++ ++ /* always add HTC control endpoint first, we only expose the list after the ++ * first one, this is added for TX queue checking */ ++ AddToEndpointDistList(target, &target->EndPoint[ENDPOINT_0].CreditDist); ++ ++ /* build the list of credit distribution structures in priority order ++ * supplied by the caller, these will follow endpoint 0 */ ++ for (i = 0; i < ListLength; i++) { ++ /* match services with endpoints and add the endpoints to the distribution list ++ * in FIFO order */ ++ for (ep = ENDPOINT_1; ep < ENDPOINT_MAX; ep++) { ++ if (target->EndPoint[ep].ServiceID == ServicePriorityOrder[i]) { ++ /* queue this one to the list */ ++ AddToEndpointDistList(target, &target->EndPoint[ep].CreditDist); ++ break; ++ } ++ } ++ AR_DEBUG_ASSERT(ep < ENDPOINT_MAX); ++ } ++ ++} +diff -ruN --exclude='*.orig' --exclude='*.rej' linux-2.6.29-rc3.owrt/drivers/ar6000/include/a_config.h linux-2.6.29-rc3.owrt.om/drivers/ar6000/include/a_config.h +--- linux-2.6.29-rc3.owrt/drivers/ar6000/include/a_config.h 1970-01-01 01:00:00.000000000 +0100 ++++ linux-2.6.29-rc3.owrt.om/drivers/ar6000/include/a_config.h 2009-05-10 22:27:59.000000000 +0200 +@@ -0,0 +1,27 @@ ++#ifndef _A_CONFIG_H_ ++#define _A_CONFIG_H_ ++/* ++ * Copyright (c) 2004-2005 Atheros Communications Inc. ++ * All rights reserved. ++ * ++ * ++ * 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; ++ * ++ * Software distributed under the License is distributed on an "AS ++ * IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or ++ * implied. See the License for the specific language governing ++ * rights and limitations under the License. ++ * ++ * ++ * ++ */ ++ ++/* ++ * This file contains software configuration options that enables ++ * specific software "features" ++ */ ++#include "../ar6000/config_linux.h" ++ ++#endif +diff -ruN --exclude='*.orig' --exclude='*.rej' linux-2.6.29-rc3.owrt/drivers/ar6000/include/a_debug.h linux-2.6.29-rc3.owrt.om/drivers/ar6000/include/a_debug.h +--- linux-2.6.29-rc3.owrt/drivers/ar6000/include/a_debug.h 1970-01-01 01:00:00.000000000 +0100 ++++ linux-2.6.29-rc3.owrt.om/drivers/ar6000/include/a_debug.h 2009-05-10 22:27:59.000000000 +0200 +@@ -0,0 +1,41 @@ ++#ifndef _A_DEBUG_H_ ++#define _A_DEBUG_H_ ++/* ++ * Copyright (c) 2004-2006 Atheros Communications Inc. ++ * All rights reserved. ++ * ++ * Copyright (c) 2004-2007 Atheros Communications Inc. ++ * All rights reserved. ++ * ++ * ++ * 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; ++ * ++ * Software distributed under the License is distributed on an "AS ++ * IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or ++ * implied. See the License for the specific language governing ++ * rights and limitations under the License. ++ * ++ * ++ * ++ */ ++ ++#include <a_types.h> ++#include <a_osapi.h> ++ ++#define DBG_INFO 0x00000001 ++#define DBG_ERROR 0x00000002 ++#define DBG_WARNING 0x00000004 ++#define DBG_SDIO 0x00000008 ++#define DBG_HIF 0x00000010 ++#define DBG_HTC 0x00000020 ++#define DBG_WMI 0x00000040 ++#define DBG_WMI2 0x00000080 ++#define DBG_DRIVER 0x00000100 ++ ++#define DBG_DEFAULTS (DBG_ERROR|DBG_WARNING) ++ ++#include "../ar6000/debug_linux.h" ++ ++#endif +diff -ruN --exclude='*.orig' --exclude='*.rej' linux-2.6.29-rc3.owrt/drivers/ar6000/include/a_drv_api.h linux-2.6.29-rc3.owrt.om/drivers/ar6000/include/a_drv_api.h +--- linux-2.6.29-rc3.owrt/drivers/ar6000/include/a_drv_api.h 1970-01-01 01:00:00.000000000 +0100 ++++ linux-2.6.29-rc3.owrt.om/drivers/ar6000/include/a_drv_api.h 2009-05-10 22:27:59.000000000 +0200 +@@ -0,0 +1,185 @@ ++#ifndef _A_DRV_API_H_ ++#define _A_DRV_API_H_ ++/* ++ * Copyright (c) 2004-2006 Atheros Communications Inc. ++ * All rights reserved. ++ * ++ * ++ * 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; ++ * ++ * Software distributed under the License is distributed on an "AS ++ * IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or ++ * implied. See the License for the specific language governing ++ * rights and limitations under the License. ++ * ++ * ++ * ++ */ ++ ++#ifdef __cplusplus ++extern "C" { ++#endif ++ ++/****************************************************************************/ ++/****************************************************************************/ ++/** **/ ++/** WMI related hooks **/ ++/** **/ ++/****************************************************************************/ ++/****************************************************************************/ ++ ++#include <ar6000_api.h> ++ ++#define A_WMI_CHANNELLIST_RX(devt, numChan, chanList) \ ++ ar6000_channelList_rx((devt), (numChan), (chanList)) ++ ++#define A_WMI_SET_NUMDATAENDPTS(devt, num) \ ++ ar6000_set_numdataendpts((devt), (num)) ++ ++#define A_WMI_CONTROL_TX(devt, osbuf, streamID) \ ++ ar6000_control_tx((devt), (osbuf), (streamID)) ++ ++#define A_WMI_TARGETSTATS_EVENT(devt, pStats) \ ++ ar6000_targetStats_event((devt), (pStats)) ++ ++#define A_WMI_SCANCOMPLETE_EVENT(devt, status) \ ++ ar6000_scanComplete_event((devt), (status)) ++ ++#ifdef CONFIG_HOST_DSET_SUPPORT ++ ++#define A_WMI_DSET_DATA_REQ(devt, access_cookie, offset, length, targ_buf, targ_reply_fn, targ_reply_arg) \ ++ ar6000_dset_data_req((devt), (access_cookie), (offset), (length), (targ_buf), (targ_reply_fn), (targ_reply_arg)) ++ ++#define A_WMI_DSET_CLOSE(devt, access_cookie) \ ++ ar6000_dset_close((devt), (access_cookie)) ++ ++#endif ++ ++#define A_WMI_DSET_OPEN_REQ(devt, id, targ_handle, targ_reply_fn, targ_reply_arg) \ ++ ar6000_dset_open_req((devt), (id), (targ_handle), (targ_reply_fn), (targ_reply_arg)) ++ ++#define A_WMI_CONNECT_EVENT(devt, channel, bssid, listenInterval, beaconInterval, networkType, beaconIeLen, assocReqLen, assocRespLen, assocInfo) \ ++ ar6000_connect_event((devt), (channel), (bssid), (listenInterval), (beaconInterval), (networkType), (beaconIeLen), (assocReqLen), (assocRespLen), (assocInfo)) ++ ++#define A_WMI_REGDOMAIN_EVENT(devt, regCode) \ ++ ar6000_regDomain_event((devt), (regCode)) ++ ++#define A_WMI_NEIGHBORREPORT_EVENT(devt, numAps, info) \ ++ ar6000_neighborReport_event((devt), (numAps), (info)) ++ ++#define A_WMI_DISCONNECT_EVENT(devt, reason, bssid, assocRespLen, assocInfo, protocolReasonStatus) \ ++ ar6000_disconnect_event((devt), (reason), (bssid), (assocRespLen), (assocInfo), (protocolReasonStatus)) ++ ++#define A_WMI_TKIP_MICERR_EVENT(devt, keyid, ismcast) \ ++ ar6000_tkip_micerr_event((devt), (keyid), (ismcast)) ++ ++#define A_WMI_BITRATE_RX(devt, rateKbps) \ ++ ar6000_bitrate_rx((devt), (rateKbps)) ++ ++#define A_WMI_TXPWR_RX(devt, txPwr) \ ++ ar6000_txPwr_rx((devt), (txPwr)) ++ ++#define A_WMI_READY_EVENT(devt, datap, phyCap) \ ++ ar6000_ready_event((devt), (datap), (phyCap)) ++ ++#define A_WMI_DBGLOG_INIT_DONE(ar) \ ++ ar6000_dbglog_init_done(ar); ++ ++#define A_WMI_RSSI_THRESHOLD_EVENT(devt, newThreshold, rssi) \ ++ ar6000_rssiThreshold_event((devt), (newThreshold), (rssi)) ++ ++#define A_WMI_REPORT_ERROR_EVENT(devt, errorVal) \ ++ ar6000_reportError_event((devt), (errorVal)) ++ ++#define A_WMI_ROAM_TABLE_EVENT(devt, pTbl) \ ++ ar6000_roam_tbl_event((devt), (pTbl)) ++ ++#define A_WMI_ROAM_DATA_EVENT(devt, p) \ ++ ar6000_roam_data_event((devt), (p)) ++ ++#define A_WMI_WOW_LIST_EVENT(devt, num_filters, wow_filters) \ ++ ar6000_wow_list_event((devt), (num_filters), (wow_filters)) ++ ++#define A_WMI_CAC_EVENT(devt, ac, cac_indication, statusCode, tspecSuggestion) \ ++ ar6000_cac_event((devt), (ac), (cac_indication), (statusCode), (tspecSuggestion)) ++ ++#define A_WMI_IPTOS_TO_USERPRIORITY(pkt) \ ++ ar6000_iptos_to_userPriority((pkt)) ++ ++#define A_WMI_PMKID_LIST_EVENT(devt, num_pmkid, pmkid_list) \ ++ ar6000_pmkid_list_event((devt), (num_pmkid), (pmkid_list)) ++ ++#ifdef CONFIG_HOST_GPIO_SUPPORT ++ ++#define A_WMI_GPIO_INTR_RX(intr_mask, input_values) \ ++ ar6000_gpio_intr_rx((intr_mask), (input_values)) ++ ++#define A_WMI_GPIO_DATA_RX(reg_id, value) \ ++ ar6000_gpio_data_rx((reg_id), (value)) ++ ++#define A_WMI_GPIO_ACK_RX() \ ++ ar6000_gpio_ack_rx() ++ ++#endif ++ ++#ifdef SEND_EVENT_TO_APP ++ ++#define A_WMI_SEND_EVENT_TO_APP(ar, eventId, datap, len) \ ++ ar6000_send_event_to_app((ar), (eventId), (datap), (len)) ++ ++#else ++ ++#define A_WMI_SEND_EVENT_TO_APP(ar, eventId, datap, len) ++ ++#endif ++ ++#ifdef CONFIG_HOST_TCMD_SUPPORT ++#define A_WMI_TCMD_RX_REPORT_EVENT(devt, results, len) \ ++ ar6000_tcmd_rx_report_event((devt), (results), (len)) ++#endif ++ ++#define A_WMI_HBCHALLENGERESP_EVENT(devt, cookie, source) \ ++ ar6000_hbChallengeResp_event((devt), (cookie), (source)) ++ ++#define A_WMI_TX_RETRY_ERR_EVENT(devt) \ ++ ar6000_tx_retry_err_event((devt)) ++ ++#define A_WMI_SNR_THRESHOLD_EVENT_RX(devt, newThreshold, snr) \ ++ ar6000_snrThresholdEvent_rx((devt), (newThreshold), (snr)) ++ ++#define A_WMI_LQ_THRESHOLD_EVENT_RX(devt, range, lqVal) \ ++ ar6000_lqThresholdEvent_rx((devt), (range), (lqVal)) ++ ++#define A_WMI_RATEMASK_RX(devt, ratemask) \ ++ ar6000_ratemask_rx((devt), (ratemask)) ++ ++#define A_WMI_KEEPALIVE_RX(devt, configured) \ ++ ar6000_keepalive_rx((devt), (configured)) ++ ++#define A_WMI_BSSINFO_EVENT_RX(ar, datp, len) \ ++ ar6000_bssInfo_event_rx((ar), (datap), (len)) ++ ++#define A_WMI_DBGLOG_EVENT(ar, dropped, buffer, length) \ ++ ar6000_dbglog_event((ar), (dropped), (buffer), (length)); ++ ++#define A_WMI_STREAM_TX_ACTIVE(devt,trafficClass) \ ++ ar6000_indicate_tx_activity((devt),(trafficClass), TRUE) ++ ++#define A_WMI_STREAM_TX_INACTIVE(devt,trafficClass) \ ++ ar6000_indicate_tx_activity((devt),(trafficClass), FALSE) ++ ++/****************************************************************************/ ++/****************************************************************************/ ++/** **/ ++/** HTC related hooks **/ ++/** **/ ++/****************************************************************************/ ++/****************************************************************************/ ++ ++#ifdef __cplusplus ++} ++#endif ++ ++#endif +diff -ruN --exclude='*.orig' --exclude='*.rej' linux-2.6.29-rc3.owrt/drivers/ar6000/include/a_drv.h linux-2.6.29-rc3.owrt.om/drivers/ar6000/include/a_drv.h +--- linux-2.6.29-rc3.owrt/drivers/ar6000/include/a_drv.h 1970-01-01 01:00:00.000000000 +0100 ++++ linux-2.6.29-rc3.owrt.om/drivers/ar6000/include/a_drv.h 2009-05-10 22:27:59.000000000 +0200 +@@ -0,0 +1,28 @@ ++#ifndef _A_DRV_H_ ++#define _A_DRV_H_ ++/* ++ * $Id: //depot/sw/releases/olca2.0-GPL/host/include/a_drv.h#1 $ ++ * ++ * This file contains the definitions of the basic atheros data types. ++ * It is used to map the data types in atheros files to a platform specific ++ * type. ++ * ++ * Copyright 2003-2005 Atheros Communications, Inc., All Rights Reserved. ++ * ++ * ++ * 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; ++ * ++ * Software distributed under the License is distributed on an "AS ++ * IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or ++ * implied. See the License for the specific language governing ++ * rights and limitations under the License. ++ * ++ * ++ * ++ */ ++ ++#include "../ar6000/athdrv_linux.h" ++ ++#endif /* _ADRV_H_ */ +diff -ruN --exclude='*.orig' --exclude='*.rej' linux-2.6.29-rc3.owrt/drivers/ar6000/include/a_osapi.h linux-2.6.29-rc3.owrt.om/drivers/ar6000/include/a_osapi.h +--- linux-2.6.29-rc3.owrt/drivers/ar6000/include/a_osapi.h 1970-01-01 01:00:00.000000000 +0100 ++++ linux-2.6.29-rc3.owrt.om/drivers/ar6000/include/a_osapi.h 2009-05-10 22:27:59.000000000 +0200 +@@ -0,0 +1,28 @@ ++#ifndef _A_OSAPI_H_ ++#define _A_OSAPI_H_ ++/* ++ * $Id: //depot/sw/releases/olca2.0-GPL/host/include/a_osapi.h#1 $ ++ * ++ * This file contains the definitions of the basic atheros data types. ++ * It is used to map the data types in atheros files to a platform specific ++ * type. ++ * ++ * Copyright 2003-2005 Atheros Communications, Inc., All Rights Reserved. ++ * ++ * ++ * 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; ++ * ++ * Software distributed under the License is distributed on an "AS ++ * IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or ++ * implied. See the License for the specific language governing ++ * rights and limitations under the License. ++ * ++ * ++ * ++ */ ++ ++#include "../ar6000/osapi_linux.h" ++ ++#endif /* _OSAPI_H_ */ +diff -ruN --exclude='*.orig' --exclude='*.rej' linux-2.6.29-rc3.owrt/drivers/ar6000/include/ar6000_api.h linux-2.6.29-rc3.owrt.om/drivers/ar6000/include/ar6000_api.h +--- linux-2.6.29-rc3.owrt/drivers/ar6000/include/ar6000_api.h 1970-01-01 01:00:00.000000000 +0100 ++++ linux-2.6.29-rc3.owrt.om/drivers/ar6000/include/ar6000_api.h 2009-05-10 22:27:59.000000000 +0200 +@@ -0,0 +1,29 @@ ++#ifndef _AR6000_API_H_ ++#define _AR6000_API_H_ ++/* ++ * Copyright (c) 2004-2005 Atheros Communications Inc. ++ * All rights reserved. ++ * ++ * This file contains the API to access the OS dependent atheros host driver ++ * by the WMI or WLAN generic modules. ++ * ++ * $Id: //depot/sw/releases/olca2.0-GPL/host/include/ar6000_api.h#1 $ ++ * ++ * ++ * 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; ++ * ++ * Software distributed under the License is distributed on an "AS ++ * IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or ++ * implied. See the License for the specific language governing ++ * rights and limitations under the License. ++ * ++ * ++ * ++ */ ++ ++#include "../ar6000/ar6xapi_linux.h" ++ ++#endif /* _AR6000_API_H */ ++ +diff -ruN --exclude='*.orig' --exclude='*.rej' linux-2.6.29-rc3.owrt/drivers/ar6000/include/ar6000_diag.h linux-2.6.29-rc3.owrt.om/drivers/ar6000/include/ar6000_diag.h +--- linux-2.6.29-rc3.owrt/drivers/ar6000/include/ar6000_diag.h 1970-01-01 01:00:00.000000000 +0100 ++++ linux-2.6.29-rc3.owrt.om/drivers/ar6000/include/ar6000_diag.h 2009-05-10 22:27:59.000000000 +0200 +@@ -0,0 +1,38 @@ ++/* ++ * ++ * Copyright (c) 2004-2007 Atheros Communications Inc. ++ * All rights reserved. ++ * ++ * ++ * 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; ++ * ++ * Software distributed under the License is distributed on an "AS ++ * IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or ++ * implied. See the License for the specific language governing ++ * rights and limitations under the License. ++ * ++ * ++ * ++ */ ++ ++#ifndef AR6000_DIAG_H_ ++#define AR6000_DIAG_H_ ++ ++ ++A_STATUS ++ar6000_ReadRegDiag(HIF_DEVICE *hifDevice, A_UINT32 *address, A_UINT32 *data); ++ ++A_STATUS ++ar6000_WriteRegDiag(HIF_DEVICE *hifDevice, A_UINT32 *address, A_UINT32 *data); ++ ++A_STATUS ++ar6000_ReadDataDiag(HIF_DEVICE *hifDevice, A_UINT32 address, ++ A_UCHAR *data, A_UINT32 length); ++ ++A_STATUS ++ar6000_WriteDataDiag(HIF_DEVICE *hifDevice, A_UINT32 address, ++ A_UCHAR *data, A_UINT32 length); ++ ++#endif /*AR6000_DIAG_H_*/ +diff -ruN --exclude='*.orig' --exclude='*.rej' linux-2.6.29-rc3.owrt/drivers/ar6000/include/AR6001_regdump.h linux-2.6.29-rc3.owrt.om/drivers/ar6000/include/AR6001_regdump.h +--- linux-2.6.29-rc3.owrt/drivers/ar6000/include/AR6001_regdump.h 1970-01-01 01:00:00.000000000 +0100 ++++ linux-2.6.29-rc3.owrt.om/drivers/ar6000/include/AR6001_regdump.h 2009-05-10 22:27:59.000000000 +0200 +@@ -0,0 +1,100 @@ ++/* ++ * Copyright (c) 2006 Atheros Communications Inc. ++ * All rights reserved. ++ * ++ * $ATH_LICENSE_HOSTSDK0_C$ ++ * ++ */ ++ ++#ifndef __AR6000_REGDUMP_H__ ++#define __AR6000_REGDUMP_H__ ++ ++#if !defined(__ASSEMBLER__) ++/* ++ * Target CPU state at the time of failure is reflected ++ * in a register dump, which the Host can fetch through ++ * the diagnostic window. ++ */ ++ ++struct MIPS_exception_frame_s { ++ A_UINT32 pc; /* Program Counter */ ++ A_UINT32 at; /* MIPS General Purpose registers */ ++ A_UINT32 v0; ++ A_UINT32 v1; ++ A_UINT32 a0; ++ A_UINT32 a1; ++ A_UINT32 a2; ++ A_UINT32 a3; ++ A_UINT32 t0; ++ A_UINT32 t1; ++ A_UINT32 t2; ++ A_UINT32 t3; ++ A_UINT32 t4; ++ A_UINT32 t5; ++ A_UINT32 t6; ++ A_UINT32 t7; ++ A_UINT32 s0; ++ A_UINT32 s1; ++ A_UINT32 s2; ++ A_UINT32 s3; ++ A_UINT32 s4; ++ A_UINT32 s5; ++ A_UINT32 s6; ++ A_UINT32 s7; ++ A_UINT32 t8; ++ A_UINT32 t9; ++ A_UINT32 k0; ++ A_UINT32 k1; ++ A_UINT32 gp; ++ A_UINT32 sp; ++ A_UINT32 s8; ++ A_UINT32 ra; ++ A_UINT32 cause; /* Selected coprocessor regs */ ++ A_UINT32 status; ++}; ++typedef struct MIPS_exception_frame_s CPU_exception_frame_t; ++ ++#endif ++ ++/* ++ * Offsets into MIPS_exception_frame structure, for use in assembler code ++ * MUST MATCH C STRUCTURE ABOVE ++ */ ++#define RD_pc 0 ++#define RD_at 1 ++#define RD_v0 2 ++#define RD_v1 3 ++#define RD_a0 4 ++#define RD_a1 5 ++#define RD_a2 6 ++#define RD_a3 7 ++#define RD_t0 8 ++#define RD_t1 9 ++#define RD_t2 10 ++#define RD_t3 11 ++#define RD_t4 12 ++#define RD_t5 13 ++#define RD_t6 14 ++#define RD_t7 15 ++#define RD_s0 16 ++#define RD_s1 17 ++#define RD_s2 18 ++#define RD_s3 19 ++#define RD_s4 20 ++#define RD_s5 21 ++#define RD_s6 22 ++#define RD_s7 23 ++#define RD_t8 24 ++#define RD_t9 25 ++#define RD_k0 26 ++#define RD_k1 27 ++#define RD_gp 28 ++#define RD_sp 29 ++#define RD_s8 30 ++#define RD_ra 31 ++#define RD_cause 32 ++#define RD_status 33 ++ ++#define RD_SIZE (34*4) /* Space for this number of words */ ++ ++#endif /* __AR6000_REGDUMP_H__ */ +diff -ruN --exclude='*.orig' --exclude='*.rej' linux-2.6.29-rc3.owrt/drivers/ar6000/include/AR6Khwreg.h linux-2.6.29-rc3.owrt.om/drivers/ar6000/include/AR6Khwreg.h +--- linux-2.6.29-rc3.owrt/drivers/ar6000/include/AR6Khwreg.h 1970-01-01 01:00:00.000000000 +0100 ++++ linux-2.6.29-rc3.owrt.om/drivers/ar6000/include/AR6Khwreg.h 2009-05-10 22:27:59.000000000 +0200 +@@ -0,0 +1,147 @@ ++/* ++ * Copyright (c) 2004-2007 Atheros Communications Inc. ++ * All rights reserved. ++ * ++ * $ATH_LICENSE_HOSTSDK0_C$ ++ * ++ * This file contains the definitions for AR6001 registers ++ * that may be directly manipulated by Host software. ++ */ ++ ++#ifndef __AR6KHWREG_H__ ++#define __AR6KHWREG_H__ ++ ++#ifdef __cplusplus ++extern "C" { ++#endif ++ ++/* Host registers */ ++#define HOST_INT_STATUS_ADDRESS 0x00000400 ++#define CPU_INT_STATUS_ADDRESS 0x00000401 ++#define ERROR_INT_STATUS_ADDRESS 0x00000402 ++#define INT_STATUS_ENABLE_ADDRESS 0x00000418 ++#define CPU_INT_STATUS_ENABLE_ADDRESS 0x00000419 ++#define COUNT_ADDRESS 0x00000420 ++#define COUNT_DEC_ADDRESS 0x00000440 ++#define WINDOW_DATA_ADDRESS 0x00000474 ++#define WINDOW_WRITE_ADDR_ADDRESS 0x00000478 ++#define WINDOW_READ_ADDR_ADDRESS 0x0000047c ++ ++/* Target addresses */ ++#define RESET_CONTROL_ADDRESS 0x0c000000 ++#define MC_REMAP_VALID_ADDRESS 0x0c004080 ++#define MC_REMAP_SIZE_ADDRESS 0x0c004100 ++#define MC_REMAP_COMPARE_ADDRESS 0x0c004180 ++#define MC_REMAP_TARGET_ADDRESS 0x0c004200 ++#define LOCAL_COUNT_ADDRESS 0x0c014080 ++#define LOCAL_SCRATCH_ADDRESS 0x0c0140c0 ++ ++ ++#define INT_STATUS_ENABLE_ERROR_MSB 7 ++#define INT_STATUS_ENABLE_ERROR_LSB 7 ++#define INT_STATUS_ENABLE_ERROR_MASK 0x00000080 ++#define INT_STATUS_ENABLE_ERROR_GET(x) (((x) & INT_STATUS_ENABLE_ERROR_MASK) >> INT_STATUS_ENABLE_ERROR_LSB) ++#define INT_STATUS_ENABLE_ERROR_SET(x) (((x) << INT_STATUS_ENABLE_ERROR_LSB) & INT_STATUS_ENABLE_ERROR_MASK) ++ ++#define INT_STATUS_ENABLE_CPU_MSB 6 ++#define INT_STATUS_ENABLE_CPU_LSB 6 ++#define INT_STATUS_ENABLE_CPU_MASK 0x00000040 ++#define INT_STATUS_ENABLE_CPU_GET(x) (((x) & INT_STATUS_ENABLE_CPU_MASK) >> INT_STATUS_ENABLE_CPU_LSB) ++#define INT_STATUS_ENABLE_CPU_SET(x) (((x) << INT_STATUS_ENABLE_CPU_LSB) & INT_STATUS_ENABLE_CPU_MASK) ++ ++#define INT_STATUS_ENABLE_COUNTER_MSB 4 ++#define INT_STATUS_ENABLE_COUNTER_LSB 4 ++#define INT_STATUS_ENABLE_COUNTER_MASK 0x00000010 ++#define INT_STATUS_ENABLE_COUNTER_GET(x) (((x) & INT_STATUS_ENABLE_COUNTER_MASK) >> INT_STATUS_ENABLE_COUNTER_LSB) ++#define INT_STATUS_ENABLE_COUNTER_SET(x) (((x) << INT_STATUS_ENABLE_COUNTER_LSB) & INT_STATUS_ENABLE_COUNTER_MASK) ++ ++#define INT_STATUS_ENABLE_MBOX_DATA_MSB 3 ++#define INT_STATUS_ENABLE_MBOX_DATA_LSB 0 ++#define INT_STATUS_ENABLE_MBOX_DATA_MASK 0x0000000f ++#define INT_STATUS_ENABLE_MBOX_DATA_GET(x) (((x) & INT_STATUS_ENABLE_MBOX_DATA_MASK) >> INT_STATUS_ENABLE_MBOX_DATA_LSB) ++#define INT_STATUS_ENABLE_MBOX_DATA_SET(x) (((x) << INT_STATUS_ENABLE_MBOX_DATA_LSB) & INT_STATUS_ENABLE_MBOX_DATA_MASK) ++ ++#define ERROR_STATUS_ENABLE_RX_UNDERFLOW_MSB 1 ++#define ERROR_STATUS_ENABLE_RX_UNDERFLOW_LSB 1 ++#define ERROR_STATUS_ENABLE_RX_UNDERFLOW_MASK 0x00000002 ++#define ERROR_STATUS_ENABLE_RX_UNDERFLOW_GET(x) (((x) & ERROR_STATUS_ENABLE_RX_UNDERFLOW_MASK) >> ERROR_STATUS_ENABLE_RX_UNDERFLOW_LSB) ++#define ERROR_STATUS_ENABLE_RX_UNDERFLOW_SET(x) (((x) << ERROR_STATUS_ENABLE_RX_UNDERFLOW_LSB) & ERROR_STATUS_ENABLE_RX_UNDERFLOW_MASK) ++ ++#define ERROR_STATUS_ENABLE_TX_OVERFLOW_MSB 0 ++#define ERROR_STATUS_ENABLE_TX_OVERFLOW_LSB 0 ++#define ERROR_STATUS_ENABLE_TX_OVERFLOW_MASK 0x00000001 ++#define ERROR_STATUS_ENABLE_TX_OVERFLOW_GET(x) (((x) & ERROR_STATUS_ENABLE_TX_OVERFLOW_MASK) >> ERROR_STATUS_ENABLE_TX_OVERFLOW_LSB) ++#define ERROR_STATUS_ENABLE_TX_OVERFLOW_SET(x) (((x) << ERROR_STATUS_ENABLE_TX_OVERFLOW_LSB) & ERROR_STATUS_ENABLE_TX_OVERFLOW_MASK) ++ ++ ++#define CPU_INT_STATUS_ENABLE_BIT_MSB 7 ++#define CPU_INT_STATUS_ENABLE_BIT_LSB 0 ++#define CPU_INT_STATUS_ENABLE_BIT_MASK 0x000000ff ++#define CPU_INT_STATUS_ENABLE_BIT_GET(x) (((x) & CPU_INT_STATUS_ENABLE_BIT_MASK) >> CPU_INT_STATUS_ENABLE_BIT_LSB) ++#define CPU_INT_STATUS_ENABLE_BIT_SET(x) (((x) << CPU_INT_STATUS_ENABLE_BIT_LSB) & CPU_INT_STATUS_ENABLE_BIT_MASK) ++ ++#define COUNTER_INT_STATUS_ENABLE_BIT_MSB 7 ++#define COUNTER_INT_STATUS_ENABLE_BIT_LSB 0 ++#define COUNTER_INT_STATUS_ENABLE_BIT_MASK 0x000000ff ++#define COUNTER_INT_STATUS_ENABLE_BIT_GET(x) (((x) & COUNTER_INT_STATUS_ENABLE_BIT_MASK) >> COUNTER_INT_STATUS_ENABLE_BIT_LSB) ++#define COUNTER_INT_STATUS_ENABLE_BIT_SET(x) (((x) << COUNTER_INT_STATUS_ENABLE_BIT_LSB) & COUNTER_INT_STATUS_ENABLE_BIT_MASK) ++ ++#define ERROR_INT_STATUS_WAKEUP_MSB 2 ++#define ERROR_INT_STATUS_WAKEUP_LSB 2 ++#define ERROR_INT_STATUS_WAKEUP_MASK 0x00000004 ++#define ERROR_INT_STATUS_WAKEUP_GET(x) (((x) & ERROR_INT_STATUS_WAKEUP_MASK) >> ERROR_INT_STATUS_WAKEUP_LSB) ++#define ERROR_INT_STATUS_WAKEUP_SET(x) (((x) << ERROR_INT_STATUS_WAKEUP_LSB) & ERROR_INT_STATUS_WAKEUP_MASK) ++ ++#define ERROR_INT_STATUS_RX_UNDERFLOW_MSB 1 ++#define ERROR_INT_STATUS_RX_UNDERFLOW_LSB 1 ++#define ERROR_INT_STATUS_RX_UNDERFLOW_MASK 0x00000002 ++#define ERROR_INT_STATUS_RX_UNDERFLOW_GET(x) (((x) & ERROR_INT_STATUS_RX_UNDERFLOW_MASK) >> ERROR_INT_STATUS_RX_UNDERFLOW_LSB) ++#define ERROR_INT_STATUS_RX_UNDERFLOW_SET(x) (((x) << ERROR_INT_STATUS_RX_UNDERFLOW_LSB) & ERROR_INT_STATUS_RX_UNDERFLOW_MASK) ++ ++#define ERROR_INT_STATUS_TX_OVERFLOW_MSB 0 ++#define ERROR_INT_STATUS_TX_OVERFLOW_LSB 0 ++#define ERROR_INT_STATUS_TX_OVERFLOW_MASK 0x00000001 ++#define ERROR_INT_STATUS_TX_OVERFLOW_GET(x) (((x) & ERROR_INT_STATUS_TX_OVERFLOW_MASK) >> ERROR_INT_STATUS_TX_OVERFLOW_LSB) ++#define ERROR_INT_STATUS_TX_OVERFLOW_SET(x) (((x) << ERROR_INT_STATUS_TX_OVERFLOW_LSB) & ERROR_INT_STATUS_TX_OVERFLOW_MASK) ++ ++#define HOST_INT_STATUS_ERROR_MSB 7 ++#define HOST_INT_STATUS_ERROR_LSB 7 ++#define HOST_INT_STATUS_ERROR_MASK 0x00000080 ++#define HOST_INT_STATUS_ERROR_GET(x) (((x) & HOST_INT_STATUS_ERROR_MASK) >> HOST_INT_STATUS_ERROR_LSB) ++#define HOST_INT_STATUS_ERROR_SET(x) (((x) << HOST_INT_STATUS_ERROR_LSB) & HOST_INT_STATUS_ERROR_MASK) ++ ++#define HOST_INT_STATUS_CPU_MSB 6 ++#define HOST_INT_STATUS_CPU_LSB 6 ++#define HOST_INT_STATUS_CPU_MASK 0x00000040 ++#define HOST_INT_STATUS_CPU_GET(x) (((x) & HOST_INT_STATUS_CPU_MASK) >> HOST_INT_STATUS_CPU_LSB) ++#define HOST_INT_STATUS_CPU_SET(x) (((x) << HOST_INT_STATUS_CPU_LSB) & HOST_INT_STATUS_CPU_MASK) ++ ++#define HOST_INT_STATUS_COUNTER_MSB 4 ++#define HOST_INT_STATUS_COUNTER_LSB 4 ++#define HOST_INT_STATUS_COUNTER_MASK 0x00000010 ++#define HOST_INT_STATUS_COUNTER_GET(x) (((x) & HOST_INT_STATUS_COUNTER_MASK) >> HOST_INT_STATUS_COUNTER_LSB) ++#define HOST_INT_STATUS_COUNTER_SET(x) (((x) << HOST_INT_STATUS_COUNTER_LSB) & HOST_INT_STATUS_COUNTER_MASK) ++ ++#define RESET_CONTROL_WARM_RST_MSB 7 ++#define RESET_CONTROL_WARM_RST_LSB 7 ++#define RESET_CONTROL_WARM_RST_MASK 0x00000080 ++#define RESET_CONTROL_WARM_RST_GET(x) (((x) & RESET_CONTROL_WARM_RST_MASK) >> RESET_CONTROL_WARM_RST_LSB) ++#define RESET_CONTROL_WARM_RST_SET(x) (((x) << RESET_CONTROL_WARM_RST_LSB) & RESET_CONTROL_WARM_RST_MASK) ++ ++#define RESET_CONTROL_COLD_RST_MSB 8 ++#define RESET_CONTROL_COLD_RST_LSB 8 ++#define RESET_CONTROL_COLD_RST_MASK 0x00000100 ++#define RESET_CONTROL_COLD_RST_GET(x) (((x) & RESET_CONTROL_COLD_RST_MASK) >> RESET_CONTROL_COLD_RST_LSB) ++#define RESET_CONTROL_COLD_RST_SET(x) (((x) << RESET_CONTROL_COLD_RST_LSB) & RESET_CONTROL_COLD_RST_MASK) ++ ++#define RESET_CAUSE_LAST_MSB 2 ++#define RESET_CAUSE_LAST_LSB 0 ++#define RESET_CAUSE_LAST_MASK 0x00000007 ++#define RESET_CAUSE_LAST_GET(x) (((x) & RESET_CAUSE_LAST_MASK) >> RESET_CAUSE_LAST_LSB) ++#define RESET_CAUSE_LAST_SET(x) (((x) << RESET_CAUSE_LAST_LSB) & RESET_CAUSE_LAST_MASK) ++ ++#ifdef __cplusplus ++} ++#endif ++ ++#endif /* __AR6KHWREG_H__ */ +diff -ruN --exclude='*.orig' --exclude='*.rej' linux-2.6.29-rc3.owrt/drivers/ar6000/include/AR6K_version.h linux-2.6.29-rc3.owrt.om/drivers/ar6000/include/AR6K_version.h +--- linux-2.6.29-rc3.owrt/drivers/ar6000/include/AR6K_version.h 1970-01-01 01:00:00.000000000 +0100 ++++ linux-2.6.29-rc3.owrt.om/drivers/ar6000/include/AR6K_version.h 2009-05-10 22:27:59.000000000 +0200 +@@ -0,0 +1,36 @@ ++#define __VER_MAJOR_ 2 ++#define __VER_MINOR_ 0 ++#define __VER_PATCH_ 0 ++ ++ ++/* ++ * Copyright (c) 2004-2007 Atheros Communications Inc. ++ * All rights reserved. ++ * ++ * $ATH_LICENSE_HOSTSDK0_C$ ++ * ++ * The makear6ksdk script (used for release builds) modifies the following line. ++ */ ++#define __BUILD_NUMBER_ 18 ++ ++ ++/* Format of the version number. */ ++#define VER_MAJOR_BIT_OFFSET 28 ++#define VER_MINOR_BIT_OFFSET 24 ++#define VER_PATCH_BIT_OFFSET 16 ++#define VER_BUILD_NUM_BIT_OFFSET 0 ++ ++ ++/* ++ * The version has the following format: ++ * Bits 28-31: Major version ++ * Bits 24-27: Minor version ++ * Bits 16-23: Patch version ++ * Bits 0-15: Build number (automatically generated during build process ) ++ * E.g. Build 1.1.3.7 would be represented as 0x11030007. ++ * ++ * DO NOT split the following macro into multiple lines as this may confuse the build scripts. ++ */ ++#define AR6K_SW_VERSION ( ( __VER_MAJOR_ << VER_MAJOR_BIT_OFFSET ) + ( __VER_MINOR_ << VER_MINOR_BIT_OFFSET ) + ( __VER_PATCH_ << VER_PATCH_BIT_OFFSET ) + ( __BUILD_NUMBER_ << VER_BUILD_NUM_BIT_OFFSET ) ) ++ ++ +diff -ruN --exclude='*.orig' --exclude='*.rej' linux-2.6.29-rc3.owrt/drivers/ar6000/include/AR6K_version.h.NEW linux-2.6.29-rc3.owrt.om/drivers/ar6000/include/AR6K_version.h.NEW +--- linux-2.6.29-rc3.owrt/drivers/ar6000/include/AR6K_version.h.NEW 1970-01-01 01:00:00.000000000 +0100 ++++ linux-2.6.29-rc3.owrt.om/drivers/ar6000/include/AR6K_version.h.NEW 2009-05-10 22:27:59.000000000 +0200 +@@ -0,0 +1,36 @@ ++#define __VER_MAJOR_ 2 ++#define __VER_MINOR_ 0 ++#define __VER_PATCH_ 0 ++ ++ ++/* ++ * Copyright (c) 2004-2007 Atheros Communications Inc. ++ * All rights reserved. ++ * ++ * $ATH_LICENSE_HOSTSDK0_C$ ++ * ++ * The makear6ksdk script (used for release builds) modifies the following line. ++ */ ++#define __BUILD_NUMBER_ 18 ++ ++ ++/* Format of the version number. */ ++#define VER_MAJOR_BIT_OFFSET 28 ++#define VER_MINOR_BIT_OFFSET 24 ++#define VER_PATCH_BIT_OFFSET 16 ++#define VER_BUILD_NUM_BIT_OFFSET 0 ++ ++ ++/* ++ * The version has the following format: ++ * Bits 28-31: Major version ++ * Bits 24-27: Minor version ++ * Bits 16-23: Patch version ++ * Bits 0-15: Build number (automatically generated during build process ) ++ * E.g. Build 1.1.3.7 would be represented as 0x11030007. ++ * ++ * DO NOT split the following macro into multiple lines as this may confuse the build scripts. ++ */ ++#define AR6K_SW_VERSION ( ( __VER_MAJOR_ << VER_MAJOR_BIT_OFFSET ) + ( __VER_MINOR_ << VER_MINOR_BIT_OFFSET ) + ( __VER_PATCH_ << VER_PATCH_BIT_OFFSET ) + ( __BUILD_NUMBER_ << VER_BUILD_NUM_BIT_OFFSET ) ) ++ ++ +diff -ruN --exclude='*.orig' --exclude='*.rej' linux-2.6.29-rc3.owrt/drivers/ar6000/include/athdefs.h linux-2.6.29-rc3.owrt.om/drivers/ar6000/include/athdefs.h +--- linux-2.6.29-rc3.owrt/drivers/ar6000/include/athdefs.h 1970-01-01 01:00:00.000000000 +0100 ++++ linux-2.6.29-rc3.owrt.om/drivers/ar6000/include/athdefs.h 2009-05-10 22:27:59.000000000 +0200 +@@ -0,0 +1,85 @@ ++#ifndef __ATHDEFS_H__ ++#define __ATHDEFS_H__ ++ ++/* ++ * Copyright (c) 2004-2007 Atheros Communications Inc. ++ * All rights reserved. ++ * ++ * $ATH_LICENSE_HOSTSDK0_C$ ++ * ++ * This file contains definitions that may be used across both ++ * Host and Target software. Nothing here is module-dependent ++ * or platform-dependent. ++ */ ++ ++/* ++ * Generic error codes that can be used by hw, sta, ap, sim, dk ++ * and any other environments. Since these are enums, feel free to ++ * add any more codes that you need. ++ */ ++ ++typedef enum { ++ A_ERROR = -1, /* Generic error return */ ++ A_OK = 0, /* success */ ++ /* Following values start at 1 */ ++ A_DEVICE_NOT_FOUND, /* not able to find PCI device */ ++ A_NO_MEMORY, /* not able to allocate memory, not available */ ++ A_MEMORY_NOT_AVAIL, /* memory region is not free for mapping */ ++ A_NO_FREE_DESC, /* no free descriptors available */ ++ A_BAD_ADDRESS, /* address does not match descriptor */ ++ A_WIN_DRIVER_ERROR, /* used in NT_HW version, if problem at init */ ++ A_REGS_NOT_MAPPED, /* registers not correctly mapped */ ++ A_EPERM, /* Not superuser */ ++ A_EACCES, /* Access denied */ ++ A_ENOENT, /* No such entry, search failed, etc. */ ++ A_EEXIST, /* The object already exists (can't create) */ ++ A_EFAULT, /* Bad address fault */ ++ A_EBUSY, /* Object is busy */ ++ A_EINVAL, /* Invalid parameter */ ++ A_EMSGSIZE, /* Inappropriate message buffer length */ ++ A_ECANCELED, /* Operation canceled */ ++ A_ENOTSUP, /* Operation not supported */ ++ A_ECOMM, /* Communication error on send */ ++ A_EPROTO, /* Protocol error */ ++ A_ENODEV, /* No such device */ ++ A_EDEVNOTUP, /* device is not UP */ ++ A_NO_RESOURCE, /* No resources for requested operation */ ++ A_HARDWARE, /* Hardware failure */ ++ A_PENDING, /* Asynchronous routine; will send up results la ++ter (typically in callback) */ ++ A_EBADCHANNEL, /* The channel cannot be used */ ++ A_DECRYPT_ERROR, /* Decryption error */ ++ A_PHY_ERROR, /* RX PHY error */ ++ A_CONSUMED /* Object was consumed */ ++} A_STATUS; ++ ++#define A_SUCCESS(x) (x == A_OK) ++#define A_FAILED(x) (!A_SUCCESS(x)) ++ ++#ifndef TRUE ++#define TRUE 1 ++#endif ++ ++#ifndef FALSE ++#define FALSE 0 ++#endif ++ ++/* ++ * The following definition is WLAN specific definition ++ */ ++typedef enum { ++ MODE_11A = 0, /* 11a Mode */ ++ MODE_11G = 1, /* 11g + 11b Mode */ ++ MODE_11B = 2, /* 11b Mode */ ++ MODE_11GONLY = 3, /* 11g only Mode */ ++ MODE_UNKNOWN = 4, ++ MODE_MAX = 4 ++} WLAN_PHY_MODE; ++ ++typedef enum { ++ WLAN_11A_CAPABILITY = 1, ++ WLAN_11G_CAPABILITY = 2, ++ WLAN_11AG_CAPABILITY = 3, ++}WLAN_CAPABILITY; ++ ++#endif /* __ATHDEFS_H__ */ +diff -ruN --exclude='*.orig' --exclude='*.rej' linux-2.6.29-rc3.owrt/drivers/ar6000/include/athdrv.h linux-2.6.29-rc3.owrt.om/drivers/ar6000/include/athdrv.h +--- linux-2.6.29-rc3.owrt/drivers/ar6000/include/athdrv.h 1970-01-01 01:00:00.000000000 +0100 ++++ linux-2.6.29-rc3.owrt.om/drivers/ar6000/include/athdrv.h 2009-05-10 22:27:59.000000000 +0200 +@@ -0,0 +1,32 @@ ++/* ++ * Copyright (c) 2004-2006 Atheros Communications Inc. ++ * All rights reserved. ++ * ++ * ++ * ++ * 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; ++ * ++ * Software distributed under the License is distributed on an "AS ++ * IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or ++ * implied. See the License for the specific language governing ++ * rights and limitations under the License. ++ * ++ * ++ * ++ */ ++ ++#ifndef _ATHDRV_H_ ++#define _ATHDRV_H_ ++ ++#ifdef __cplusplus ++extern "C" { ++#endif ++ ++ ++#ifdef __cplusplus ++} ++#endif ++ ++#endif /* _ATHDRV_H_ */ +diff -ruN --exclude='*.orig' --exclude='*.rej' linux-2.6.29-rc3.owrt/drivers/ar6000/include/athendpack.h linux-2.6.29-rc3.owrt.om/drivers/ar6000/include/athendpack.h +--- linux-2.6.29-rc3.owrt/drivers/ar6000/include/athendpack.h 1970-01-01 01:00:00.000000000 +0100 ++++ linux-2.6.29-rc3.owrt.om/drivers/ar6000/include/athendpack.h 2009-05-10 22:27:59.000000000 +0200 +@@ -0,0 +1,41 @@ ++/*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ ++ * @file: athendpack.h ++ * ++ * @abstract: end compiler-specific structure packing ++ * ++ * Copyright (c) 2004-2007 Atheros Communications Inc. ++ * All rights reserved. ++ * ++ * ++ * 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; ++ * ++ * Software distributed under the License is distributed on an "AS ++ * IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or ++ * implied. See the License for the specific language governing ++ * rights and limitations under the License. ++ * ++ * ++ * ++ */ ++#ifdef VXWORKS ++#endif /* VXWORKS */ ++ ++#ifdef LINUX ++#endif /* LINUX */ ++ ++#ifdef QNX ++#endif /* QNX */ ++ ++#ifdef INTEGRITY ++#include "integrity/athendpack_integrity.h" ++#endif /* INTEGRITY */ ++ ++#ifdef NUCLEUS ++#endif /* NUCLEUS */ ++ ++#ifdef UNDER_CE ++#include "../os/wince/include/athendpack_wince.h" ++#endif /* WINCE */ ++ +diff -ruN --exclude='*.orig' --exclude='*.rej' linux-2.6.29-rc3.owrt/drivers/ar6000/include/athstartpack.h linux-2.6.29-rc3.owrt.om/drivers/ar6000/include/athstartpack.h +--- linux-2.6.29-rc3.owrt/drivers/ar6000/include/athstartpack.h 1970-01-01 01:00:00.000000000 +0100 ++++ linux-2.6.29-rc3.owrt.om/drivers/ar6000/include/athstartpack.h 2009-05-10 22:27:59.000000000 +0200 +@@ -0,0 +1,42 @@ ++/*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ ++ * @file: athstartpack.h ++ * ++ * @abstract: start compiler-specific structure packing ++ * ++ * Copyright (c) 2004-2007 Atheros Communications Inc. ++ * All rights reserved. ++ * ++ * ++ * 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; ++ * ++ * Software distributed under the License is distributed on an "AS ++ * IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or ++ * implied. See the License for the specific language governing ++ * rights and limitations under the License. ++ * ++ * ++ * ++ */ ++ ++#ifdef VXWORKS ++#endif /* VXWORKS */ ++ ++#ifdef LINUX ++#endif /* LINUX */ ++ ++#ifdef QNX ++#endif /* QNX */ ++ ++#ifdef INTEGRITY ++#include "integrity/athstartpack_integrity.h" ++#endif /* INTEGRITY */ ++ ++#ifdef NUCLEUS ++#endif /* NUCLEUS */ ++ ++#ifdef UNDER_CE ++#include "../os/wince/include/athstartpack_wince.h" ++#endif /* WINCE */ ++ +diff -ruN --exclude='*.orig' --exclude='*.rej' linux-2.6.29-rc3.owrt/drivers/ar6000/include/a_types.h linux-2.6.29-rc3.owrt.om/drivers/ar6000/include/a_types.h +--- linux-2.6.29-rc3.owrt/drivers/ar6000/include/a_types.h 1970-01-01 01:00:00.000000000 +0100 ++++ linux-2.6.29-rc3.owrt.om/drivers/ar6000/include/a_types.h 2009-05-10 22:27:59.000000000 +0200 +@@ -0,0 +1,28 @@ ++#ifndef _A_TYPES_H_ ++#define _A_TYPES_H_ ++/* ++ * $Id: //depot/sw/releases/olca2.0-GPL/host/include/a_types.h#1 $ ++ * ++ * This file contains the definitions of the basic atheros data types. ++ * It is used to map the data types in atheros files to a platform specific ++ * type. ++ * ++ * Copyright 2003-2005 Atheros Communications, Inc., All Rights Reserved. ++ * ++ * ++ * 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; ++ * ++ * Software distributed under the License is distributed on an "AS ++ * IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or ++ * implied. See the License for the specific language governing ++ * rights and limitations under the License. ++ * ++ * ++ * ++ */ ++ ++#include "../ar6000/athtypes_linux.h" ++ ++#endif /* _ATHTYPES_H_ */ +diff -ruN --exclude='*.orig' --exclude='*.rej' linux-2.6.29-rc3.owrt/drivers/ar6000/include/bmi.h linux-2.6.29-rc3.owrt.om/drivers/ar6000/include/bmi.h +--- linux-2.6.29-rc3.owrt/drivers/ar6000/include/bmi.h 1970-01-01 01:00:00.000000000 +0100 ++++ linux-2.6.29-rc3.owrt.om/drivers/ar6000/include/bmi.h 2009-05-10 22:27:59.000000000 +0200 +@@ -0,0 +1,100 @@ ++#ifndef _BMI_H_ ++#define _BMI_H_ ++/* ++ * Copyright (c) 2004-2005 Atheros Communications Inc. ++ * All rights reserved. ++ * ++ * ++ * 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; ++ * ++ * Software distributed under the License is distributed on an "AS ++ * IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or ++ * implied. See the License for the specific language governing ++ * rights and limitations under the License. ++ * ++ * ++ * ++ * BMI declarations and prototypes ++ */ ++ ++#ifdef __cplusplus ++extern "C" { ++#endif /* __cplusplus */ ++ ++/* Header files */ ++#include "a_config.h" ++#include "athdefs.h" ++#include "a_types.h" ++#include "hif.h" ++#include "a_osapi.h" ++#include "bmi_msg.h" ++ ++void ++BMIInit(void); ++ ++A_STATUS ++BMIDone(HIF_DEVICE *device); ++ ++A_STATUS ++BMIGetTargetInfo(HIF_DEVICE *device, struct bmi_target_info *targ_info); ++ ++A_STATUS ++BMIReadMemory(HIF_DEVICE *device, ++ A_UINT32 address, ++ A_UCHAR *buffer, ++ A_UINT32 length); ++ ++A_STATUS ++BMIWriteMemory(HIF_DEVICE *device, ++ A_UINT32 address, ++ A_UCHAR *buffer, ++ A_UINT32 length); ++ ++A_STATUS ++BMIExecute(HIF_DEVICE *device, ++ A_UINT32 address, ++ A_UINT32 *param); ++ ++A_STATUS ++BMISetAppStart(HIF_DEVICE *device, ++ A_UINT32 address); ++ ++A_STATUS ++BMIReadSOCRegister(HIF_DEVICE *device, ++ A_UINT32 address, ++ A_UINT32 *param); ++ ++A_STATUS ++BMIWriteSOCRegister(HIF_DEVICE *device, ++ A_UINT32 address, ++ A_UINT32 param); ++ ++A_STATUS ++BMIrompatchInstall(HIF_DEVICE *device, ++ A_UINT32 ROM_addr, ++ A_UINT32 RAM_addr, ++ A_UINT32 nbytes, ++ A_UINT32 do_activate, ++ A_UINT32 *patch_id); ++ ++A_STATUS ++BMIrompatchUninstall(HIF_DEVICE *device, ++ A_UINT32 rompatch_id); ++ ++A_STATUS ++BMIrompatchActivate(HIF_DEVICE *device, ++ A_UINT32 rompatch_count, ++ A_UINT32 *rompatch_list); ++ ++A_STATUS ++BMIrompatchDeactivate(HIF_DEVICE *device, ++ A_UINT32 rompatch_count, ++ A_UINT32 *rompatch_list); ++ ++#ifdef __cplusplus ++} ++#endif ++ ++#endif /* _BMI_H_ */ +diff -ruN --exclude='*.orig' --exclude='*.rej' linux-2.6.29-rc3.owrt/drivers/ar6000/include/bmi_msg.h linux-2.6.29-rc3.owrt.om/drivers/ar6000/include/bmi_msg.h +--- linux-2.6.29-rc3.owrt/drivers/ar6000/include/bmi_msg.h 1970-01-01 01:00:00.000000000 +0100 ++++ linux-2.6.29-rc3.owrt.om/drivers/ar6000/include/bmi_msg.h 2009-05-10 22:27:59.000000000 +0200 +@@ -0,0 +1,199 @@ ++#ifndef __BMI_MSG_H__ ++#define __BMI_MSG_H__ ++/* ++ * ++ * Copyright (c) 2004-2007 Atheros Communications Inc. ++ * All rights reserved. ++ * ++ * ++ * 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; ++ * ++ * Software distributed under the License is distributed on an "AS ++ * IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or ++ * implied. See the License for the specific language governing ++ * rights and limitations under the License. ++ * ++ * ++ * ++ */ ++ ++/* ++ * Bootloader Messaging Interface (BMI) ++ * ++ * BMI is a very simple messaging interface used during initialization ++ * to read memory, write memory, execute code, and to define an ++ * application entry PC. ++ * ++ * It is used to download an application to AR6K, to provide ++ * patches to code that is already resident on AR6K, and generally ++ * to examine and modify state. The Host has an opportunity to use ++ * BMI only once during bootup. Once the Host issues a BMI_DONE ++ * command, this opportunity ends. ++ * ++ * The Host writes BMI requests to mailbox0, and reads BMI responses ++ * from mailbox0. BMI requests all begin with a command ++ * (see below for specific commands), and are followed by ++ * command-specific data. ++ * ++ * Flow control: ++ * The Host can only issue a command once the Target gives it a ++ * "BMI Command Credit", using AR6K Counter #4. As soon as the ++ * Target has completed a command, it issues another BMI Command ++ * Credit (so the Host can issue the next command). ++ * ++ * BMI handles all required Target-side cache flushing. ++ */ ++ ++ ++/* Maximum data size used for BMI transfers */ ++#define BMI_DATASZ_MAX 32 ++ ++/* BMI Commands */ ++ ++#define BMI_NO_COMMAND 0 ++ ++#define BMI_DONE 1 ++ /* ++ * Semantics: Host is done using BMI ++ * Request format: ++ * A_UINT32 command (BMI_DONE) ++ * Response format: none ++ */ ++ ++#define BMI_READ_MEMORY 2 ++ /* ++ * Semantics: Host reads AR6K memory ++ * Request format: ++ * A_UINT32 command (BMI_READ_MEMORY) ++ * A_UINT32 address ++ * A_UINT32 length, at most BMI_DATASZ_MAX ++ * Response format: ++ * A_UINT8 data[length] ++ */ ++ ++#define BMI_WRITE_MEMORY 3 ++ /* ++ * Semantics: Host writes AR6K memory ++ * Request format: ++ * A_UINT32 command (BMI_WRITE_MEMORY) ++ * A_UINT32 address ++ * A_UINT32 length, at most BMI_DATASZ_MAX ++ * A_UINT8 data[length] ++ * Response format: none ++ */ ++ ++#define BMI_EXECUTE 4 ++ /* ++ * Semantics: Causes AR6K to execute code ++ * Request format: ++ * A_UINT32 command (BMI_EXECUTE) ++ * A_UINT32 address ++ * A_UINT32 parameter ++ * Response format: ++ * A_UINT32 return value ++ */ ++ ++#define BMI_SET_APP_START 5 ++ /* ++ * Semantics: Set Target application starting address ++ * Request format: ++ * A_UINT32 command (BMI_SET_APP_START) ++ * A_UINT32 address ++ * Response format: none ++ */ ++ ++#define BMI_READ_SOC_REGISTER 6 ++ /* ++ * Semantics: Read a 32-bit Target SOC register. ++ * Request format: ++ * A_UINT32 command (BMI_READ_REGISTER) ++ * A_UINT32 address ++ * Response format: ++ * A_UINT32 value ++ */ ++ ++#define BMI_WRITE_SOC_REGISTER 7 ++ /* ++ * Semantics: Write a 32-bit Target SOC register. ++ * Request format: ++ * A_UINT32 command (BMI_WRITE_REGISTER) ++ * A_UINT32 address ++ * A_UINT32 value ++ * ++ * Response format: none ++ */ ++ ++#define BMI_GET_TARGET_ID 8 ++#define BMI_GET_TARGET_INFO 8 ++ /* ++ * Semantics: Fetch the 4-byte Target information ++ * Request format: ++ * A_UINT32 command (BMI_GET_TARGET_ID/INFO) ++ * Response format1 (old firmware): ++ * A_UINT32 TargetVersionID ++ * Response format2 (newer firmware): ++ * A_UINT32 TARGET_VERSION_SENTINAL ++ * struct bmi_target_info; ++ */ ++ ++struct bmi_target_info { ++ A_UINT32 target_info_byte_count; /* size of this structure */ ++ A_UINT32 target_ver; /* Target Version ID */ ++ A_UINT32 target_type; /* Target type */ ++}; ++#define TARGET_VERSION_SENTINAL 0xffffffff ++#define TARGET_TYPE_AR6001 1 ++#define TARGET_TYPE_AR6002 2 ++ ++ ++#define BMI_ROMPATCH_INSTALL 9 ++ /* ++ * Semantics: Install a ROM Patch. ++ * Request format: ++ * A_UINT32 command (BMI_ROMPATCH_INSTALL) ++ * A_UINT32 Target ROM Address ++ * A_UINT32 Target RAM Address ++ * A_UINT32 Size, in bytes ++ * A_UINT32 Activate? 1-->activate; ++ * 0-->install but do not activate ++ * Response format: ++ * A_UINT32 PatchID ++ */ ++ ++#define BMI_ROMPATCH_UNINSTALL 10 ++ /* ++ * Semantics: Uninstall a previously-installed ROM Patch, ++ * automatically deactivating, if necessary. ++ * Request format: ++ * A_UINT32 command (BMI_ROMPATCH_UNINSTALL) ++ * A_UINT32 PatchID ++ * ++ * Response format: none ++ */ ++ ++#define BMI_ROMPATCH_ACTIVATE 11 ++ /* ++ * Semantics: Activate a list of previously-installed ROM Patches. ++ * Request format: ++ * A_UINT32 command (BMI_ROMPATCH_ACTIVATE) ++ * A_UINT32 rompatch_count ++ * A_UINT32 PatchID[rompatch_count] ++ * ++ * Response format: none ++ */ ++ ++#define BMI_ROMPATCH_DEACTIVATE 12 ++ /* ++ * Semantics: Deactivate a list of active ROM Patches. ++ * Request format: ++ * A_UINT32 command (BMI_ROMPATCH_DEACTIVATE) ++ * A_UINT32 rompatch_count ++ * A_UINT32 PatchID[rompatch_count] ++ * ++ * Response format: none ++ */ ++ ++ ++#endif /* __BMI_MSG_H__ */ +diff -ruN --exclude='*.orig' --exclude='*.rej' linux-2.6.29-rc3.owrt/drivers/ar6000/include/common_drv.h linux-2.6.29-rc3.owrt.om/drivers/ar6000/include/common_drv.h +--- linux-2.6.29-rc3.owrt/drivers/ar6000/include/common_drv.h 1970-01-01 01:00:00.000000000 +0100 ++++ linux-2.6.29-rc3.owrt.om/drivers/ar6000/include/common_drv.h 2009-05-10 22:27:59.000000000 +0200 +@@ -0,0 +1,61 @@ ++/* ++ * ++ * Copyright (c) 2004-2007 Atheros Communications Inc. ++ * All rights reserved. ++ * ++ * ++ * 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; ++ * ++ * Software distributed under the License is distributed on an "AS ++ * IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or ++ * implied. See the License for the specific language governing ++ * rights and limitations under the License. ++ * ++ * ++ * ++ */ ++ ++ ++#ifndef COMMON_DRV_H_ ++#define COMMON_DRV_H_ ++ ++#include "hif.h" ++#include "htc_packet.h" ++ ++ ++ ++/* structure that is the state information for the default credit distribution callback ++ * drivers should instantiate (zero-init as well) this structure in their driver instance ++ * and pass it as a context to the HTC credit distribution functions */ ++typedef struct _COMMON_CREDIT_STATE_INFO { ++ int TotalAvailableCredits; /* total credits in the system at startup */ ++ int CurrentFreeCredits; /* credits available in the pool that have not been ++ given out to endpoints */ ++ HTC_ENDPOINT_CREDIT_DIST *pLowestPriEpDist; /* pointer to the lowest priority endpoint dist struct */ ++} COMMON_CREDIT_STATE_INFO; ++ ++ ++/* HTC TX packet tagging definitions */ ++#define AR6K_CONTROL_PKT_TAG HTC_TX_PACKET_TAG_USER_DEFINED ++#define AR6K_DATA_PKT_TAG (AR6K_CONTROL_PKT_TAG + 1) ++ ++#ifdef __cplusplus ++extern "C" { ++#endif ++ ++/* OS-independent APIs */ ++A_STATUS ar6000_setup_credit_dist(HTC_HANDLE HTCHandle, COMMON_CREDIT_STATE_INFO *pCredInfo); ++A_STATUS ar6000_ReadRegDiag(HIF_DEVICE *hifDevice, A_UINT32 *address, A_UINT32 *data); ++A_STATUS ar6000_WriteRegDiag(HIF_DEVICE *hifDevice, A_UINT32 *address, A_UINT32 *data); ++A_STATUS ar6000_ReadDataDiag(HIF_DEVICE *hifDevice, A_UINT32 address, A_UCHAR *data, A_UINT32 length); ++A_STATUS ar6000_reset_device(HIF_DEVICE *hifDevice, A_UINT32 TargetType); ++void ar6000_dump_target_assert_info(HIF_DEVICE *hifDevice, A_UINT32 TargetType); ++A_STATUS ar6000_reset_device_skipflash(HIF_DEVICE *hifDevice); ++ ++#ifdef __cplusplus ++} ++#endif ++ ++#endif /*COMMON_DRV_H_*/ +diff -ruN --exclude='*.orig' --exclude='*.rej' linux-2.6.29-rc3.owrt/drivers/ar6000/include/dbglog_api.h linux-2.6.29-rc3.owrt.om/drivers/ar6000/include/dbglog_api.h +--- linux-2.6.29-rc3.owrt/drivers/ar6000/include/dbglog_api.h 1970-01-01 01:00:00.000000000 +0100 ++++ linux-2.6.29-rc3.owrt.om/drivers/ar6000/include/dbglog_api.h 2009-05-10 22:27:59.000000000 +0200 +@@ -0,0 +1,46 @@ ++#ifndef _DBGLOG_API_H_ ++#define _DBGLOG_API_H_ ++/* ++ * Copyright (c) 2004-2006 Atheros Communications Inc. ++ * All rights reserved. ++ * ++ * ++ * 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; ++ * ++ * Software distributed under the License is distributed on an "AS ++ * IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or ++ * implied. See the License for the specific language governing ++ * rights and limitations under the License. ++ * ++ * ++ * ++ * This file contains host side debug primitives. ++ */ ++ ++#ifdef __cplusplus ++extern "C" { ++#endif ++ ++#include "dbglog.h" ++ ++#define DBGLOG_HOST_LOG_BUFFER_SIZE DBGLOG_LOG_BUFFER_SIZE ++ ++#define DBGLOG_GET_DBGID(arg) \ ++ ((arg & DBGLOG_DBGID_MASK) >> DBGLOG_DBGID_OFFSET) ++ ++#define DBGLOG_GET_MODULEID(arg) \ ++ ((arg & DBGLOG_MODULEID_MASK) >> DBGLOG_MODULEID_OFFSET) ++ ++#define DBGLOG_GET_NUMARGS(arg) \ ++ ((arg & DBGLOG_NUM_ARGS_MASK) >> DBGLOG_NUM_ARGS_OFFSET) ++ ++#define DBGLOG_GET_TIMESTAMP(arg) \ ++ ((arg & DBGLOG_TIMESTAMP_MASK) >> DBGLOG_TIMESTAMP_OFFSET) ++ ++#ifdef __cplusplus ++} ++#endif ++ ++#endif /* _DBGLOG_API_H_ */ +diff -ruN --exclude='*.orig' --exclude='*.rej' linux-2.6.29-rc3.owrt/drivers/ar6000/include/dbglog.h linux-2.6.29-rc3.owrt.om/drivers/ar6000/include/dbglog.h +--- linux-2.6.29-rc3.owrt/drivers/ar6000/include/dbglog.h 1970-01-01 01:00:00.000000000 +0100 ++++ linux-2.6.29-rc3.owrt.om/drivers/ar6000/include/dbglog.h 2009-05-10 22:27:59.000000000 +0200 +@@ -0,0 +1,107 @@ ++/* ++ * Copyright (c) 2004-2007 Atheros Communications Inc. ++ * All rights reserved. ++ * ++ * $ATH_LICENSE_HOSTSDK0_C$ ++ * ++ * This file contains the definitions and data structures associated with ++ * the log based debug mechanism. ++ * ++ */ ++ ++#ifndef _DBGLOG_H_ ++#define _DBGLOG_H_ ++ ++#ifdef __cplusplus ++extern "C" { ++#endif ++ ++#define DBGLOG_TIMESTAMP_OFFSET 0 ++#define DBGLOG_TIMESTAMP_MASK 0x0000FFFF /* Bit 0-15. Contains bit ++ 8-23 of the LF0 timer */ ++#define DBGLOG_DBGID_OFFSET 16 ++#define DBGLOG_DBGID_MASK 0x03FF0000 /* Bit 16-25 */ ++#define DBGLOG_DBGID_NUM_MAX 256 /* Upper limit is width of mask */ ++ ++#define DBGLOG_MODULEID_OFFSET 26 ++#define DBGLOG_MODULEID_MASK 0x3C000000 /* Bit 26-29 */ ++#define DBGLOG_MODULEID_NUM_MAX 16 /* Upper limit is width of mask */ ++ ++/* ++ * Please ensure that the definition of any new module intrduced is captured ++ * between the DBGLOG_MODULEID_START and DBGLOG_MODULEID_END defines. The ++ * structure is required for the parser to correctly pick up the values for ++ * different modules. ++ */ ++#define DBGLOG_MODULEID_START ++#define DBGLOG_MODULEID_INF 0 ++#define DBGLOG_MODULEID_WMI 1 ++#define DBGLOG_MODULEID_CSERV 2 ++#define DBGLOG_MODULEID_PM 3 ++#define DBGLOG_MODULEID_TXRX_MGMTBUF 4 ++#define DBGLOG_MODULEID_TXRX_TXBUF 5 ++#define DBGLOG_MODULEID_TXRX_RXBUF 6 ++#define DBGLOG_MODULEID_WOW 7 ++#define DBGLOG_MODULEID_WHAL 8 ++#define DBGLOG_MODULEID_END ++ ++#define DBGLOG_NUM_ARGS_OFFSET 30 ++#define DBGLOG_NUM_ARGS_MASK 0xC0000000 /* Bit 30-31 */ ++#define DBGLOG_NUM_ARGS_MAX 2 /* Upper limit is width of mask */ ++ ++#define DBGLOG_MODULE_LOG_ENABLE_OFFSET 0 ++#define DBGLOG_MODULE_LOG_ENABLE_MASK 0x0000FFFF ++ ++#define DBGLOG_REPORTING_ENABLED_OFFSET 16 ++#define DBGLOG_REPORTING_ENABLED_MASK 0x00010000 ++ ++#define DBGLOG_TIMESTAMP_RESOLUTION_OFFSET 17 ++#define DBGLOG_TIMESTAMP_RESOLUTION_MASK 0x000E0000 ++ ++#define DBGLOG_REPORT_SIZE_OFFSET 20 ++#define DBGLOG_REPORT_SIZE_MASK 0x3FF00000 ++ ++#define DBGLOG_LOG_BUFFER_SIZE 1500 ++#define DBGLOG_DBGID_DEFINITION_LEN_MAX 64 ++ ++struct dbglog_buf_s { ++ struct dbglog_buf_s *next; ++ A_INT8 *buffer; ++ A_UINT32 bufsize; ++ A_UINT32 length; ++ A_UINT32 count; ++ A_UINT32 free; ++}; ++ ++struct dbglog_hdr_s { ++ struct dbglog_buf_s *dbuf; ++ A_UINT32 dropped; ++}; ++ ++struct dbglog_config_s { ++ A_UINT32 cfgvalid; /* Mask with valid config bits */ ++ union { ++ /* TODO: Take care of endianness */ ++ struct { ++ A_UINT32 mmask:16; /* Mask of modules with logging on */ ++ A_UINT32 rep:1; /* Reporting enabled or not */ ++ A_UINT32 tsr:3; /* Time stamp resolution. Def: 1 ms */ ++ A_UINT32 size:10; /* Report size in number of messages */ ++ A_UINT32 reserved:2; ++ } dbglog_config; ++ ++ A_UINT32 value; ++ } u; ++}; ++ ++#define cfgmmask u.dbglog_config.mmask ++#define cfgrep u.dbglog_config.rep ++#define cfgtsr u.dbglog_config.tsr ++#define cfgsize u.dbglog_config.size ++#define cfgvalue u.value ++ ++#ifdef __cplusplus ++} ++#endif ++ ++#endif /* _DBGLOG_H_ */ +diff -ruN --exclude='*.orig' --exclude='*.rej' linux-2.6.29-rc3.owrt/drivers/ar6000/include/dbglog_id.h linux-2.6.29-rc3.owrt.om/drivers/ar6000/include/dbglog_id.h +--- linux-2.6.29-rc3.owrt/drivers/ar6000/include/dbglog_id.h 1970-01-01 01:00:00.000000000 +0100 ++++ linux-2.6.29-rc3.owrt.om/drivers/ar6000/include/dbglog_id.h 2009-05-10 22:27:59.000000000 +0200 +@@ -0,0 +1,307 @@ ++/* ++ * ++ * Copyright (c) 2004-2007 Atheros Communications Inc. ++ * All rights reserved. ++ * ++ * $ATH_LICENSE_HOSTSDK0_C$ ++ * ++ * This file contains the definitions of the debug identifiers for different ++ * modules. ++ * ++ */ ++ ++#ifndef _DBGLOG_ID_H_ ++#define _DBGLOG_ID_H_ ++ ++#ifdef __cplusplus ++extern "C" { ++#endif ++ ++/* ++ * The nomenclature for the debug identifiers is MODULE_DESCRIPTION. ++ * Please ensure that the definition of any new debugid introduced is captured ++ * between the <MODULE>_DBGID_DEFINITION_START and ++ * <MODULE>_DBGID_DEFINITION_END defines. The structure is required for the ++ * parser to correctly pick up the values for different debug identifiers. ++ */ ++ ++/* INF debug identifier definitions */ ++#define INF_DBGID_DEFINITION_START ++#define INF_ASSERTION_FAILED 1 ++#define INF_TARGET_ID 2 ++#define INF_DBGID_DEFINITION_END ++ ++/* WMI debug identifier definitions */ ++#define WMI_DBGID_DEFINITION_START ++#define WMI_CMD_RX_XTND_PKT_TOO_SHORT 1 ++#define WMI_EXTENDED_CMD_NOT_HANDLED 2 ++#define WMI_CMD_RX_PKT_TOO_SHORT 3 ++#define WMI_CALLING_WMI_EXTENSION_FN 4 ++#define WMI_CMD_NOT_HANDLED 5 ++#define WMI_IN_SYNC 6 ++#define WMI_TARGET_WMI_SYNC_CMD 7 ++#define WMI_SET_SNR_THRESHOLD_PARAMS 8 ++#define WMI_SET_RSSI_THRESHOLD_PARAMS 9 ++#define WMI_SET_LQ_TRESHOLD_PARAMS 10 ++#define WMI_TARGET_CREATE_PSTREAM_CMD 11 ++#define WMI_WI_DTM_INUSE 12 ++#define WMI_TARGET_DELETE_PSTREAM_CMD 13 ++#define WMI_TARGET_IMPLICIT_DELETE_PSTREAM_CMD 14 ++#define WMI_TARGET_GET_BIT_RATE_CMD 15 ++#define WMI_GET_RATE_MASK_CMD_FIX_RATE_MASK_IS 16 ++#define WMI_TARGET_GET_AVAILABLE_CHANNELS_CMD 17 ++#define WMI_TARGET_GET_TX_PWR_CMD 18 ++#define WMI_FREE_EVBUF_WMIBUF 19 ++#define WMI_FREE_EVBUF_DATABUF 20 ++#define WMI_FREE_EVBUF_BADFLAG 21 ++#define WMI_HTC_RX_ERROR_DATA_PACKET 22 ++#define WMI_HTC_RX_SYNC_PAUSING_FOR_MBOX 23 ++#define WMI_INCORRECT_WMI_DATA_HDR_DROPPING_PKT 24 ++#define WMI_SENDING_READY_EVENT 25 ++#define WMI_SETPOWER_MDOE_TO_MAXPERF 26 ++#define WMI_SETPOWER_MDOE_TO_REC 27 ++#define WMI_BSSINFO_EVENT_FROM 28 ++#define WMI_TARGET_GET_STATS_CMD 29 ++#define WMI_SENDING_SCAN_COMPLETE_EVENT 30 ++#define WMI_SENDING_RSSI_INDB_THRESHOLD_EVENT 31 ++#define WMI_SENDING_RSSI_INDBM_THRESHOLD_EVENT 32 ++#define WMI_SENDING_LINK_QUALITY_THRESHOLD_EVENT 33 ++#define WMI_SENDING_ERROR_REPORT_EVENT 34 ++#define WMI_SENDING_CAC_EVENT 35 ++#define WMI_TARGET_GET_ROAM_TABLE_CMD 36 ++#define WMI_TARGET_GET_ROAM_DATA_CMD 37 ++#define WMI_SENDING_GPIO_INTR_EVENT 38 ++#define WMI_SENDING_GPIO_ACK_EVENT 39 ++#define WMI_SENDING_GPIO_DATA_EVENT 40 ++#define WMI_CMD_RX 41 ++#define WMI_CMD_RX_XTND 42 ++#define WMI_EVENT_SEND 43 ++#define WMI_EVENT_SEND_XTND 44 ++#define WMI_DBGID_DEFINITION_END ++ ++/* CSERV debug identifier definitions */ ++#define CSERV_DBGID_DEFINITION_START ++#define CSERV_BEGIN_SCAN1 1 ++#define CSERV_BEGIN_SCAN2 2 ++#define CSERV_END_SCAN1 3 ++#define CSERV_END_SCAN2 4 ++#define CSERV_CHAN_SCAN_START 5 ++#define CSERV_CHAN_SCAN_STOP 6 ++#define CSERV_CHANNEL_OPPPORTUNITY 7 ++#define CSERV_NC_TIMEOUT 8 ++#define CSERV_BACK_HOME 10 ++#define CSERV_CHMGR_CH_CALLBACK1 11 ++#define CSERV_CHMGR_CH_CALLBACK2 12 ++#define CSERV_CHMGR_CH_CALLBACK3 13 ++#define CSERV_SET_SCAN_PARAMS1 14 ++#define CSERV_SET_SCAN_PARAMS2 15 ++#define CSERV_SET_SCAN_PARAMS3 16 ++#define CSERV_SET_SCAN_PARAMS4 17 ++#define CSERV_ABORT_SCAN 18 ++#define CSERV_NEWSTATE 19 ++#define CSERV_MINCHMGR_OP_END 20 ++#define CSERV_CHMGR_OP_END 21 ++#define CSERV_DISCONNECT_TIMEOUT 22 ++#define CSERV_ROAM_TIMEOUT 23 ++#define CSERV_FORCE_SCAN1 24 ++#define CSERV_FORCE_SCAN2 25 ++#define CSERV_FORCE_SCAN3 26 ++#define CSERV_UTIL_TIMEOUT 27 ++#define CSERV_RSSIPOLLER 28 ++#define CSERV_RETRY_CONNECT_TIMEOUT 29 ++#define CSERV_RSSIINDBMPOLLER 30 ++#define CSERV_BGSCAN_ENABLE 31 ++#define CSERV_BGSCAN_DISABLE 32 ++#define CSERV_WLAN_START_SCAN_CMD1 33 ++#define CSERV_WLAN_START_SCAN_CMD2 34 ++#define CSERV_WLAN_START_SCAN_CMD3 35 ++#define CSERV_START_SCAN_CMD 36 ++#define CSERV_START_FORCE_SCAN 37 ++#define CSERV_NEXT_CHAN 38 ++#define CSERV_SET_REGCODE 39 ++#define CSERV_START_ADHOC 40 ++#define CSERV_ADHOC_AT_HOME 41 ++#define CSERV_OPT_AT_HOME 42 ++#define CSERV_WLAN_CONNECT_CMD 43 ++#define CSERV_WLAN_RECONNECT_CMD 44 ++#define CSERV_WLAN_DISCONNECT_CMD 45 ++#define CSERV_BSS_CHANGE_CHANNEL 46 ++#define CSERV_BEACON_RX 47 ++#define CSERV_KEEPALIVE_CHECK 48 ++#define CSERV_RC_BEGIN_SCAN 49 ++#define CSERV_RC_SCAN_START 50 ++#define CSERV_RC_SCAN_STOP 51 ++#define CSERV_RC_NEXT 52 ++#define CSERV_RC_SCAN_END 53 ++#define CSERV_PROBE_CALLBACK 54 ++#define CSERV_ROAM1 55 ++#define CSERV_ROAM2 56 ++#define CSERV_ROAM3 57 ++#define CSERV_CONNECT_EVENT 58 ++#define CSERV_DISCONNECT_EVENT 59 ++#define CSERV_BMISS_HANDLER1 60 ++#define CSERV_BMISS_HANDLER2 61 ++#define CSERV_BMISS_HANDLER3 62 ++#define CSERV_LOWRSSI_HANDLER 63 ++#define CSERV_WLAN_SET_PMKID_CMD 64 ++#define CSERV_RECONNECT_REQUEST 65 ++#define CSERV_KEYSPLUMBED_EVENT 66 ++#define CSERV_NEW_REG 67 ++#define CSERV_SET_RSSI_THOLD 68 ++#define CSERV_RSSITHRESHOLDCHECK 69 ++#define CSERV_RSSIINDBMTHRESHOLDCHECK 70 ++#define CSERV_WLAN_SET_OPT_CMD1 71 ++#define CSERV_WLAN_SET_OPT_CMD2 72 ++#define CSERV_WLAN_SET_OPT_CMD3 73 ++#define CSERV_WLAN_SET_OPT_CMD4 74 ++#define CSERV_SCAN_CONNECT_STOP 75 ++#define CSERV_BMISS_HANDLER4 76 ++#define CSERV_INITIALIZE_TIMER 77 ++#define CSERV_ARM_TIMER 78 ++#define CSERV_DISARM_TIMER 79 ++#define CSERV_UNINITIALIZE_TIMER 80 ++#define CSERV_DISCONNECT_EVENT2 81 ++#define CSERV_SCAN_CONNECT_START 82 ++#define CSERV_BSSINFO_MEMORY_ALLOC_FAILED 83 ++#define CSERV_SET_SCAN_PARAMS5 84 ++#define CSERV_DBGID_DEFINITION_END ++ ++/* TXRX debug identifier definitions */ ++#define TXRX_TXBUF_DBGID_DEFINITION_START ++#define TXRX_TXBUF_ALLOCATE_BUF 1 ++#define TXRX_TXBUF_QUEUE_BUF_TO_MBOX 2 ++#define TXRX_TXBUF_QUEUE_BUF_TO_TXQ 3 ++#define TXRX_TXBUF_TXQ_DEPTH 4 ++#define TXRX_TXBUF_IBSS_QUEUE_TO_SFQ 5 ++#define TXRX_TXBUF_IBSS_QUEUE_TO_TXQ_FRM_SFQ 6 ++#define TXRX_TXBUF_INITIALIZE_TIMER 7 ++#define TXRX_TXBUF_ARM_TIMER 8 ++#define TXRX_TXBUF_DISARM_TIMER 9 ++#define TXRX_TXBUF_UNINITIALIZE_TIMER 10 ++#define TXRX_TXBUF_DBGID_DEFINITION_END ++ ++#define TXRX_RXBUF_DBGID_DEFINITION_START ++#define TXRX_RXBUF_ALLOCATE_BUF 1 ++#define TXRX_RXBUF_QUEUE_TO_HOST 2 ++#define TXRX_RXBUF_QUEUE_TO_WLAN 3 ++#define TXRX_RXBUF_ZERO_LEN_BUF 4 ++#define TXRX_RXBUF_QUEUE_TO_HOST_LASTBUF_IN_RXCHAIN 5 ++#define TXRX_RXBUF_LASTBUF_IN_RXCHAIN_ZEROBUF 6 ++#define TXRX_RXBUF_QUEUE_EMPTY_QUEUE_TO_WLAN 7 ++#define TXRX_RXBUF_SEND_TO_RECV_MGMT 8 ++#define TXRX_RXBUF_SEND_TO_IEEE_LAYER 9 ++#define TXRX_RXBUF_DBGID_DEFINITION_END ++ ++#define TXRX_MGMTBUF_DBGID_DEFINITION_START ++#define TXRX_MGMTBUF_ALLOCATE_BUF 1 ++#define TXRX_MGMTBUF_ALLOCATE_SM_BUF 2 ++#define TXRX_MGMTBUF_ALLOCATE_RMBUF 3 ++#define TXRX_MGMTBUF_GET_BUF 4 ++#define TXRX_MGMTBUF_GET_SM_BUF 5 ++#define TXRX_MGMTBUF_QUEUE_BUF_TO_TXQ 6 ++#define TXRX_MGMTBUF_REAPED_BUF 7 ++#define TXRX_MGMTBUF_REAPED_SM_BUF 8 ++#define TXRX_MGMTBUF_WAIT_FOR_TXQ_DRAIN 9 ++#define TXRX_MGMTBUF_WAIT_FOR_TXQ_SFQ_DRAIN 10 ++#define TXRX_MGMTBUF_ENQUEUE_INTO_SFQ 11 ++#define TXRX_MGMTBUF_DEQUEUE_FROM_SFQ 12 ++#define TXRX_MGMTBUF_PAUSE_TXQ 13 ++#define TXRX_MGMTBUF_RESUME_TXQ 14 ++#define TXRX_MGMTBUF_WAIT_FORTXQ_DRAIN_TIMEOUT 15 ++#define TXRX_MGMTBUF_DRAINQ 16 ++#define TXRX_MGMTBUF_INDICATE_Q_DRAINED 17 ++#define TXRX_MGMTBUF_DBGID_DEFINITION_END ++ ++/* PM (Power Module) debug identifier definitions */ ++#define PM_DBGID_DEFINITION_START ++#define PM_INIT 1 ++#define PM_ENABLE 2 ++#define PM_SET_STATE 3 ++#define PM_SET_POWERMODE 4 ++#define PM_CONN_NOTIFY 5 ++#define PM_REF_COUNT_NEGATIVE 6 ++#define PM_APSD_ENABLE 7 ++#define PM_UPDATE_APSD_STATE 8 ++#define PM_CHAN_OP_REQ 9 ++#define PM_SET_MY_BEACON_POLICY 10 ++#define PM_SET_ALL_BEACON_POLICY 11 ++#define PM_SET_PM_PARAMS1 12 ++#define PM_SET_PM_PARAMS2 13 ++#define PM_ADHOC_SET_PM_CAPS_FAIL 14 ++#define PM_ADHOC_UNKNOWN_IBSS_ATTRIB_ID 15 ++#define PM_DBGID_DEFINITION_END ++ ++/* Wake on Wireless debug identifier definitions */ ++#define WOW_DBGID_DEFINITION_START ++#define WOW_INIT 1 ++#define WOW_GET_CONFIG_DSET 2 ++#define WOW_NO_CONFIG_DSET 3 ++#define WOW_INVALID_CONFIG_DSET 4 ++#define WOW_USE_DEFAULT_CONFIG 5 ++#define WOW_SETUP_GPIO 6 ++#define WOW_INIT_DONE 7 ++#define WOW_SET_GPIO_PIN 8 ++#define WOW_CLEAR_GPIO_PIN 9 ++#define WOW_SET_WOW_MODE_CMD 10 ++#define WOW_SET_HOST_MODE_CMD 11 ++#define WOW_ADD_WOW_PATTERN_CMD 12 ++#define WOW_NEW_WOW_PATTERN_AT_INDEX 13 ++#define WOW_DEL_WOW_PATTERN_CMD 14 ++#define WOW_LIST_CONTAINS_PATTERNS 15 ++#define WOW_GET_WOW_LIST_CMD 16 ++#define WOW_INVALID_FILTER_ID 17 ++#define WOW_INVALID_FILTER_LISTID 18 ++#define WOW_NO_VALID_FILTER_AT_ID 19 ++#define WOW_NO_VALID_LIST_AT_ID 20 ++#define WOW_NUM_PATTERNS_EXCEEDED 21 ++#define WOW_NUM_LISTS_EXCEEDED 22 ++#define WOW_GET_WOW_STATS 23 ++#define WOW_CLEAR_WOW_STATS 24 ++#define WOW_WAKEUP_HOST 25 ++#define WOW_EVENT_WAKEUP_HOST 26 ++#define WOW_EVENT_DISCARD 27 ++#define WOW_PATTERN_MATCH 28 ++#define WOW_PATTERN_NOT_MATCH 29 ++#define WOW_PATTERN_NOT_MATCH_OFFSET 30 ++#define WOW_DISABLED_HOST_ASLEEP 31 ++#define WOW_ENABLED_HOST_ASLEEP_NO_PATTERNS 32 ++#define WOW_ENABLED_HOST_ASLEEP_NO_MATCH_FOUND 33 ++#define WOW_DBGID_DEFINITION_END ++ ++/* WHAL debug identifier definitions */ ++#define WHAL_DBGID_DEFINITION_START ++#define WHAL_ERROR_ANI_CONTROL 1 ++#define WHAL_ERROR_CHIP_TEST1 2 ++#define WHAL_ERROR_CHIP_TEST2 3 ++#define WHAL_ERROR_EEPROM_CHECKSUM 4 ++#define WHAL_ERROR_EEPROM_MACADDR 5 ++#define WHAL_ERROR_INTERRUPT_HIU 6 ++#define WHAL_ERROR_KEYCACHE_RESET 7 ++#define WHAL_ERROR_KEYCACHE_SET 8 ++#define WHAL_ERROR_KEYCACHE_TYPE 9 ++#define WHAL_ERROR_KEYCACHE_TKIPENTRY 10 ++#define WHAL_ERROR_KEYCACHE_WEPLENGTH 11 ++#define WHAL_ERROR_PHY_INVALID_CHANNEL 12 ++#define WHAL_ERROR_POWER_AWAKE 13 ++#define WHAL_ERROR_POWER_SET 14 ++#define WHAL_ERROR_RECV_STOPDMA 15 ++#define WHAL_ERROR_RECV_STOPPCU 16 ++#define WHAL_ERROR_RESET_CHANNF1 17 ++#define WHAL_ERROR_RESET_CHANNF2 18 ++#define WHAL_ERROR_RESET_PM 19 ++#define WHAL_ERROR_RESET_OFFSETCAL 20 ++#define WHAL_ERROR_RESET_RFGRANT 21 ++#define WHAL_ERROR_RESET_RXFRAME 22 ++#define WHAL_ERROR_RESET_STOPDMA 23 ++#define WHAL_ERROR_RESET_RECOVER 24 ++#define WHAL_ERROR_XMIT_COMPUTE 25 ++#define WHAL_ERROR_XMIT_NOQUEUE 26 ++#define WHAL_ERROR_XMIT_ACTIVEQUEUE 27 ++#define WHAL_ERROR_XMIT_BADTYPE 28 ++#define WHAL_DBGID_DEFINITION_END ++ ++#ifdef __cplusplus ++} ++#endif ++ ++#endif /* _DBGLOG_ID_H_ */ +diff -ruN --exclude='*.orig' --exclude='*.rej' linux-2.6.29-rc3.owrt/drivers/ar6000/include/dl_list.h linux-2.6.29-rc3.owrt.om/drivers/ar6000/include/dl_list.h +--- linux-2.6.29-rc3.owrt/drivers/ar6000/include/dl_list.h 1970-01-01 01:00:00.000000000 +0100 ++++ linux-2.6.29-rc3.owrt.om/drivers/ar6000/include/dl_list.h 2009-05-10 22:27:59.000000000 +0200 +@@ -0,0 +1,114 @@ ++/* ++ * ++ * Double-link list definitions (adapted from Atheros SDIO stack) ++ * ++ * Copyright (c) 2007 Atheros Communications Inc. ++ * All rights reserved. ++ * ++ * ++ * 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; ++ * ++ * Software distributed under the License is distributed on an "AS ++ * IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or ++ * implied. See the License for the specific language governing ++ * rights and limitations under the License. ++ * ++ * ++ * ++ */ ++#ifndef __DL_LIST_H___ ++#define __DL_LIST_H___ ++ ++#define A_CONTAINING_STRUCT(address, struct_type, field_name)\ ++ ((struct_type *)((A_UINT32)(address) - (A_UINT32)(&((struct_type *)0)->field_name))) ++ ++/* list functions */ ++/* pointers for the list */ ++typedef struct _DL_LIST { ++ struct _DL_LIST *pPrev; ++ struct _DL_LIST *pNext; ++}DL_LIST, *PDL_LIST; ++/* ++ * DL_LIST_INIT , initialize doubly linked list ++*/ ++#define DL_LIST_INIT(pList)\ ++ {(pList)->pPrev = pList; (pList)->pNext = pList;} ++ ++#define DL_LIST_IS_EMPTY(pList) (((pList)->pPrev == (pList)) && ((pList)->pNext == (pList))) ++#define DL_LIST_GET_ITEM_AT_HEAD(pList) (pList)->pNext ++#define DL_LIST_GET_ITEM_AT_TAIL(pList) (pList)->pPrev ++/* ++ * ITERATE_OVER_LIST pStart is the list, pTemp is a temp list member ++ * NOT: do not use this function if the items in the list are deleted inside the ++ * iteration loop ++*/ ++#define ITERATE_OVER_LIST(pStart, pTemp) \ ++ for((pTemp) =(pStart)->pNext; pTemp != (pStart); (pTemp) = (pTemp)->pNext) ++ ++ ++/* safe iterate macro that allows the item to be removed from the list ++ * the iteration continues to the next item in the list ++ */ ++#define ITERATE_OVER_LIST_ALLOW_REMOVE(pStart,pItem,st,offset) \ ++{ \ ++ PDL_LIST pTemp; \ ++ pTemp = (pStart)->pNext; \ ++ while (pTemp != (pStart)) { \ ++ (pItem) = A_CONTAINING_STRUCT(pTemp,st,offset); \ ++ pTemp = pTemp->pNext; \ ++ ++#define ITERATE_END }} ++ ++/* ++ * DL_ListInsertTail - insert pAdd to the end of the list ++*/ ++static INLINE PDL_LIST DL_ListInsertTail(PDL_LIST pList, PDL_LIST pAdd) { ++ /* insert at tail */ ++ pAdd->pPrev = pList->pPrev; ++ pAdd->pNext = pList; ++ pList->pPrev->pNext = pAdd; ++ pList->pPrev = pAdd; ++ return pAdd; ++} ++ ++/* ++ * DL_ListInsertHead - insert pAdd into the head of the list ++*/ ++static INLINE PDL_LIST DL_ListInsertHead(PDL_LIST pList, PDL_LIST pAdd) { ++ /* insert at head */ ++ pAdd->pPrev = pList; ++ pAdd->pNext = pList->pNext; ++ pList->pNext->pPrev = pAdd; ++ pList->pNext = pAdd; ++ return pAdd; ++} ++ ++#define DL_ListAdd(pList,pItem) DL_ListInsertHead((pList),(pItem)) ++/* ++ * DL_ListRemove - remove pDel from list ++*/ ++static INLINE PDL_LIST DL_ListRemove(PDL_LIST pDel) { ++ pDel->pNext->pPrev = pDel->pPrev; ++ pDel->pPrev->pNext = pDel->pNext; ++ /* point back to itself just to be safe, incase remove is called again */ ++ pDel->pNext = pDel; ++ pDel->pPrev = pDel; ++ return pDel; ++} ++ ++/* ++ * DL_ListRemoveItemFromHead - get a list item from the head ++*/ ++static INLINE PDL_LIST DL_ListRemoveItemFromHead(PDL_LIST pList) { ++ PDL_LIST pItem = NULL; ++ if (pList->pNext != pList) { ++ pItem = pList->pNext; ++ /* remove the first item from head */ ++ DL_ListRemove(pItem); ++ } ++ return pItem; ++} ++ ++#endif /* __DL_LIST_H___ */ +diff -ruN --exclude='*.orig' --exclude='*.rej' linux-2.6.29-rc3.owrt/drivers/ar6000/include/dset_api.h linux-2.6.29-rc3.owrt.om/drivers/ar6000/include/dset_api.h +--- linux-2.6.29-rc3.owrt/drivers/ar6000/include/dset_api.h 1970-01-01 01:00:00.000000000 +0100 ++++ linux-2.6.29-rc3.owrt.om/drivers/ar6000/include/dset_api.h 2009-05-10 22:27:59.000000000 +0200 +@@ -0,0 +1,63 @@ ++/* ++ * Copyright (c) 2004-2006 Atheros Communications Inc. ++ * All rights reserved. ++ * ++ * ++ * 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; ++ * ++ * Software distributed under the License is distributed on an "AS ++ * IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or ++ * implied. See the License for the specific language governing ++ * rights and limitations under the License. ++ * ++ * ++ * ++ * $Id: //depot/sw/releases/olca2.0-GPL/host/include/dset_api.h#1 $ ++ * ++ * Host-side DataSet API. ++ * ++ */ ++ ++#ifndef _DSET_API_H_ ++#define _DSET_API_H_ ++ ++#ifdef __cplusplus ++extern "C" { ++#endif /* __cplusplus */ ++ ++/* ++ * Host-side DataSet support is optional, and is not ++ * currently required for correct operation. To disable ++ * Host-side DataSet support, set this to 0. ++ */ ++#ifndef CONFIG_HOST_DSET_SUPPORT ++#define CONFIG_HOST_DSET_SUPPORT 1 ++#endif ++ ++/* Called to send a DataSet Open Reply back to the Target. */ ++A_STATUS wmi_dset_open_reply(struct wmi_t *wmip, ++ A_UINT32 status, ++ A_UINT32 access_cookie, ++ A_UINT32 size, ++ A_UINT32 version, ++ A_UINT32 targ_handle, ++ A_UINT32 targ_reply_fn, ++ A_UINT32 targ_reply_arg); ++ ++/* Called to send a DataSet Data Reply back to the Target. */ ++A_STATUS wmi_dset_data_reply(struct wmi_t *wmip, ++ A_UINT32 status, ++ A_UINT8 *host_buf, ++ A_UINT32 length, ++ A_UINT32 targ_buf, ++ A_UINT32 targ_reply_fn, ++ A_UINT32 targ_reply_arg); ++ ++#ifdef __cplusplus ++} ++#endif /* __cplusplus */ ++ ++ ++#endif /* _DSET_API_H_ */ +diff -ruN --exclude='*.orig' --exclude='*.rej' linux-2.6.29-rc3.owrt/drivers/ar6000/include/dsetid.h linux-2.6.29-rc3.owrt.om/drivers/ar6000/include/dsetid.h +--- linux-2.6.29-rc3.owrt/drivers/ar6000/include/dsetid.h 1970-01-01 01:00:00.000000000 +0100 ++++ linux-2.6.29-rc3.owrt.om/drivers/ar6000/include/dsetid.h 2009-05-10 22:27:59.000000000 +0200 +@@ -0,0 +1,110 @@ ++/* ++ * Copyright (c) 2004-2007 Atheros Communications Inc. ++ * All rights reserved. ++ * ++ * $ATH_LICENSE_HOSTSDK0_C$ ++ * ++ */ ++ ++#ifndef __DSETID_H__ ++#define __DSETID_H__ ++ ++/* Well-known DataSet IDs */ ++#define DSETID_UNUSED 0x00000000 ++#define DSETID_BOARD_DATA 0x00000001 /* Cal and board data */ ++#define DSETID_REGDB 0x00000002 /* Regulatory Database */ ++#define DSETID_POWER_CONTROL 0x00000003 /* TX Pwr Lim & Ant Gain */ ++#define DSETID_USER_CONFIG 0x00000004 /* User Configuration */ ++ ++#define DSETID_ANALOG_CONTROL_DATA_START 0x00000005 ++#define DSETID_ANALOG_CONTROL_DATA_END 0x00000025 ++/* ++ * Get DSETID for various reference clock speeds. ++ * For each speed there are three DataSets that correspond ++ * to the three columns of bank6 data (addr, 11a, 11b/g). ++ * This macro returns the dsetid of the first of those ++ * three DataSets. ++ */ ++#define ANALOG_CONTROL_DATA_DSETID(refclk) \ ++ (DSETID_ANALOG_CONTROL_DATA_START + 3*refclk) ++ ++/* ++ * There are TWO STARTUP_PATCH DataSets. ++ * DSETID_STARTUP_PATCH is historical, and was applied before BMI on ++ * earlier systems. On AR6002, it is applied after BMI, just like ++ * DSETID_STARTUP_PATCH2. ++ */ ++#define DSETID_STARTUP_PATCH 0x00000026 ++#define DSETID_GPIO_CONFIG_PATCH 0x00000027 ++#define DSETID_WLANREGS 0x00000028 /* override wlan regs */ ++#define DSETID_STARTUP_PATCH2 0x00000029 ++ ++#define DSETID_WOW_CONFIG 0x00000090 /* WoW Configuration */ ++ ++/* Add WHAL_INI_DATA_ID to DSETID_INI_DATA for a specific WHAL INI table. */ ++#define DSETID_INI_DATA 0x00000100 ++/* Reserved for WHAL INI Tables: 0x100..0x11f */ ++#define DSETID_INI_DATA_END 0x0000011f ++ ++#define DSETID_VENDOR_START 0x00010000 /* Vendor-defined DataSets */ ++ ++#define DSETID_INDEX_END 0xfffffffe /* Reserved to indicate the ++ end of a memory-based ++ DataSet Index */ ++#define DSETID_INDEX_FREE 0xffffffff /* An unused index entry */ ++ ++/* ++ * PATCH DataSet format: ++ * A list of patches, terminated by a patch with ++ * address=PATCH_END. ++ * ++ * This allows for patches to be stored in flash. ++ */ ++struct patch_s { ++ A_UINT32 *address; ++ A_UINT32 data; ++}; ++ ++/* ++ * Skip some patches. Can be used to erase a single patch in a ++ * patch DataSet without having to re-write the DataSet. May ++ * also be used to embed information for use by subsequent ++ * patch code. The "data" in a PATCH_SKIP tells how many ++ * bytes of length "patch_s" to skip. ++ */ ++#define PATCH_SKIP ((A_UINT32 *)0x00000000) ++ ++/* ++ * Execute code at the address specified by "data". ++ * The address of the patch structure is passed as ++ * the one parameter. ++ */ ++#define PATCH_CODE_ABS ((A_UINT32 *)0x00000001) ++ ++/* ++ * Same as PATCH_CODE_ABS, but treat "data" as an ++ * offset from the start of the patch word. ++ */ ++#define PATCH_CODE_REL ((A_UINT32 *)0x00000002) ++ ++/* Mark the end of this patch DataSet. */ ++#define PATCH_END ((A_UINT32 *)0xffffffff) ++ ++/* ++ * A DataSet which contains a Binary Patch to some other DataSet ++ * uses the original dsetid with the DSETID_BPATCH_FLAG bit set. ++ * Such a BPatch DataSet consists of BPatch metadata followed by ++ * the bdiff bytes. BPatch metadata consists of a single 32-bit ++ * word that contains the size of the BPatched final image. ++ * ++ * To create a suitable bdiff DataSet, use bdiff in host/tools/bdiff ++ * to create "diffs": ++ * bdiff -q -O -nooldmd5 -nonewmd5 -d ORIGfile NEWfile diffs ++ * Then add BPatch metadata to the start of "diffs". ++ * ++ * NB: There are some implementation-induced restrictions ++ * on which DataSets can be BPatched. ++ */ ++#define DSETID_BPATCH_FLAG 0x80000000 ++ ++#endif /* __DSETID_H__ */ +diff -ruN --exclude='*.orig' --exclude='*.rej' linux-2.6.29-rc3.owrt/drivers/ar6000/include/dset_internal.h linux-2.6.29-rc3.owrt.om/drivers/ar6000/include/dset_internal.h +--- linux-2.6.29-rc3.owrt/drivers/ar6000/include/dset_internal.h 1970-01-01 01:00:00.000000000 +0100 ++++ linux-2.6.29-rc3.owrt.om/drivers/ar6000/include/dset_internal.h 2009-05-10 22:27:59.000000000 +0200 +@@ -0,0 +1,39 @@ ++/* ++ * Copyright (c) 2007 Atheros Communications Inc. ++ * All rights reserved. ++ * ++ * $ATH_LICENSE_HOSTSDK0_C$ ++ * ++ */ ++ ++#ifndef __DSET_INTERNAL_H__ ++#define __DSET_INTERNAL_H__ ++ ++/* ++ * Internal dset definitions, common for DataSet layer. ++ */ ++ ++#define DSET_TYPE_STANDARD 0 ++#define DSET_TYPE_BPATCHED 1 ++#define DSET_TYPE_COMPRESSED 2 ++ ++/* Dataset descriptor */ ++ ++typedef struct dset_descriptor_s { ++ struct dset_descriptor_s *next; /* List link. NULL only at the last ++ descriptor */ ++ A_UINT16 id; /* Dset ID */ ++ A_UINT16 size; /* Dset size. */ ++ void *DataPtr; /* Pointer to raw data for standard ++ DataSet or pointer to original ++ dset_descriptor for patched ++ DataSet */ ++ A_UINT32 data_type; /* DSET_TYPE_*, above */ ++ ++ void *AuxPtr; /* Additional data that might ++ needed for data_type. For ++ example, pointer to patch ++ Dataset descriptor for BPatch. */ ++} dset_descriptor_t; ++ ++#endif /* __DSET_INTERNAL_H__ */ +diff -ruN --exclude='*.orig' --exclude='*.rej' linux-2.6.29-rc3.owrt/drivers/ar6000/include/gpio_api.h linux-2.6.29-rc3.owrt.om/drivers/ar6000/include/gpio_api.h +--- linux-2.6.29-rc3.owrt/drivers/ar6000/include/gpio_api.h 1970-01-01 01:00:00.000000000 +0100 ++++ linux-2.6.29-rc3.owrt.om/drivers/ar6000/include/gpio_api.h 2009-05-10 22:27:59.000000000 +0200 +@@ -0,0 +1,57 @@ ++#ifndef _GPIO_API_H_ ++#define _GPIO_API_H_ ++/* ++ * Copyright 2005 Atheros Communications, Inc., All Rights Reserved. ++ * ++ * ++ * 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; ++ * ++ * Software distributed under the License is distributed on an "AS ++ * IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or ++ * implied. See the License for the specific language governing ++ * rights and limitations under the License. ++ * ++ * ++ * ++ */ ++ ++/* ++ * Host-side General Purpose I/O API. ++ * ++ * $Id: //depot/sw/releases/olca2.0-GPL/host/include/gpio_api.h#1 $ ++ */ ++ ++/* ++ * Send a command to the Target in order to change output on GPIO pins. ++ */ ++A_STATUS wmi_gpio_output_set(struct wmi_t *wmip, ++ A_UINT32 set_mask, ++ A_UINT32 clear_mask, ++ A_UINT32 enable_mask, ++ A_UINT32 disable_mask); ++ ++/* ++ * Send a command to the Target requesting input state of GPIO pins. ++ */ ++A_STATUS wmi_gpio_input_get(struct wmi_t *wmip); ++ ++/* ++ * Send a command to the Target to change the value of a GPIO register. ++ */ ++A_STATUS wmi_gpio_register_set(struct wmi_t *wmip, ++ A_UINT32 gpioreg_id, ++ A_UINT32 value); ++ ++/* ++ * Send a command to the Target to fetch the value of a GPIO register. ++ */ ++A_STATUS wmi_gpio_register_get(struct wmi_t *wmip, A_UINT32 gpioreg_id); ++ ++/* ++ * Send a command to the Target, acknowledging some GPIO interrupts. ++ */ ++A_STATUS wmi_gpio_intr_ack(struct wmi_t *wmip, A_UINT32 ack_mask); ++ ++#endif /* _GPIO_API_H_ */ +diff -ruN --exclude='*.orig' --exclude='*.rej' linux-2.6.29-rc3.owrt/drivers/ar6000/include/gpio.h linux-2.6.29-rc3.owrt.om/drivers/ar6000/include/gpio.h +--- linux-2.6.29-rc3.owrt/drivers/ar6000/include/gpio.h 1970-01-01 01:00:00.000000000 +0100 ++++ linux-2.6.29-rc3.owrt.om/drivers/ar6000/include/gpio.h 2009-05-10 22:27:59.000000000 +0200 +@@ -0,0 +1,34 @@ ++/* ++ * Copyright (c) 2005 Atheros Communications Inc. ++ * All rights reserved. ++ * ++ * $ATH_LICENSE_HOSTSDK0_C$ ++ * ++ */ ++ ++#if defined(AR6001) ++#define GPIO_PIN_COUNT 18 ++#else ++#define GPIO_PIN_COUNT 18 ++#endif ++ ++/* ++ * Possible values for WMIX_GPIO_SET_REGISTER_CMDID. ++ * NB: These match hardware order, so that addresses can ++ * easily be computed. ++ */ ++#define GPIO_ID_OUT 0x00000000 ++#define GPIO_ID_OUT_W1TS 0x00000001 ++#define GPIO_ID_OUT_W1TC 0x00000002 ++#define GPIO_ID_ENABLE 0x00000003 ++#define GPIO_ID_ENABLE_W1TS 0x00000004 ++#define GPIO_ID_ENABLE_W1TC 0x00000005 ++#define GPIO_ID_IN 0x00000006 ++#define GPIO_ID_STATUS 0x00000007 ++#define GPIO_ID_STATUS_W1TS 0x00000008 ++#define GPIO_ID_STATUS_W1TC 0x00000009 ++#define GPIO_ID_PIN0 0x0000000a ++#define GPIO_ID_PIN(n) (GPIO_ID_PIN0+(n)) ++ ++#define GPIO_LAST_REGISTER_ID GPIO_ID_PIN(17) ++#define GPIO_ID_NONE 0xffffffff +diff -ruN --exclude='*.orig' --exclude='*.rej' linux-2.6.29-rc3.owrt/drivers/ar6000/include/hif.h linux-2.6.29-rc3.owrt.om/drivers/ar6000/include/hif.h +--- linux-2.6.29-rc3.owrt/drivers/ar6000/include/hif.h 1970-01-01 01:00:00.000000000 +0100 ++++ linux-2.6.29-rc3.owrt.om/drivers/ar6000/include/hif.h 2009-05-10 22:27:59.000000000 +0200 +@@ -0,0 +1,296 @@ ++/* ++ * Copyright (c) 2004-2007 Atheros Communications Inc. ++ * All rights reserved. ++ * ++ * ++ * 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; ++ * ++ * Software distributed under the License is distributed on an "AS ++ * IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or ++ * implied. See the License for the specific language governing ++ * rights and limitations under the License. ++ * ++ * ++ * ++ * HIF specific declarations and prototypes ++ */ ++ ++#ifndef _HIF_H_ ++#define _HIF_H_ ++ ++#ifdef __cplusplus ++extern "C" { ++#endif /* __cplusplus */ ++ ++/* Header files */ ++#include "a_config.h" ++#include "athdefs.h" ++#include "a_types.h" ++#include "a_osapi.h" ++ ++typedef struct htc_callbacks HTC_CALLBACKS; ++typedef struct hif_device HIF_DEVICE; ++ ++/* ++ * direction - Direction of transfer (HIF_READ/HIF_WRITE). ++ */ ++#define HIF_READ 0x00000001 ++#define HIF_WRITE 0x00000002 ++#define HIF_DIR_MASK (HIF_READ | HIF_WRITE) ++ ++/* ++ * type - An interface may support different kind of read/write commands. ++ * The command type is divided into a basic and an extended command ++ * and can be specified using HIF_BASIC_IO/HIF_EXTENDED_IO. ++ */ ++#define HIF_BASIC_IO 0x00000004 ++#define HIF_EXTENDED_IO 0x00000008 ++#define HIF_TYPE_MASK (HIF_BASIC_IO | HIF_EXTENDED_IO) ++ ++/* ++ * emode - This indicates the whether the command is to be executed in a ++ * blocking or non-blocking fashion (HIF_SYNCHRONOUS/ ++ * HIF_ASYNCHRONOUS). The read/write data paths in HTC have been ++ * implemented using the asynchronous mode allowing the the bus ++ * driver to indicate the completion of operation through the ++ * registered callback routine. The requirement primarily comes ++ * from the contexts these operations get called from (a driver's ++ * transmit context or the ISR context in case of receive). ++ * Support for both of these modes is essential. ++ */ ++#define HIF_SYNCHRONOUS 0x00000010 ++#define HIF_ASYNCHRONOUS 0x00000020 ++#define HIF_EMODE_MASK (HIF_SYNCHRONOUS | HIF_ASYNCHRONOUS) ++ ++/* ++ * dmode - An interface may support different kinds of commands based on ++ * the tradeoff between the amount of data it can carry and the ++ * setup time. Byte and Block modes are supported (HIF_BYTE_BASIS/ ++ * HIF_BLOCK_BASIS). In case of latter, the data is rounded off ++ * to the nearest block size by padding. The size of the block is ++ * configurable at compile time using the HIF_BLOCK_SIZE and is ++ * negotiated with the target during initialization after the ++ * dragon interrupts are enabled. ++ */ ++#define HIF_BYTE_BASIS 0x00000040 ++#define HIF_BLOCK_BASIS 0x00000080 ++#define HIF_DMODE_MASK (HIF_BYTE_BASIS | HIF_BLOCK_BASIS) ++ ++/* ++ * amode - This indicates if the address has to be incremented on dragon ++ * after every read/write operation (HIF?FIXED_ADDRESS/ ++ * HIF_INCREMENTAL_ADDRESS). ++ */ ++#define HIF_FIXED_ADDRESS 0x00000100 ++#define HIF_INCREMENTAL_ADDRESS 0x00000200 ++#define HIF_AMODE_MASK (HIF_FIXED_ADDRESS | HIF_INCREMENTAL_ADDRESS) ++ ++#define HIF_WR_ASYNC_BYTE_FIX \ ++ (HIF_WRITE | HIF_ASYNCHRONOUS | HIF_EXTENDED_IO | HIF_BYTE_BASIS | HIF_FIXED_ADDRESS) ++#define HIF_WR_ASYNC_BYTE_INC \ ++ (HIF_WRITE | HIF_ASYNCHRONOUS | HIF_EXTENDED_IO | HIF_BYTE_BASIS | HIF_INCREMENTAL_ADDRESS) ++#define HIF_WR_ASYNC_BLOCK_INC \ ++ (HIF_WRITE | HIF_ASYNCHRONOUS | HIF_EXTENDED_IO | HIF_BLOCK_BASIS | HIF_INCREMENTAL_ADDRESS) ++#define HIF_WR_SYNC_BYTE_FIX \ ++ (HIF_WRITE | HIF_SYNCHRONOUS | HIF_EXTENDED_IO | HIF_BYTE_BASIS | HIF_FIXED_ADDRESS) ++#define HIF_WR_SYNC_BYTE_INC \ ++ (HIF_WRITE | HIF_SYNCHRONOUS | HIF_EXTENDED_IO | HIF_BYTE_BASIS | HIF_INCREMENTAL_ADDRESS) ++#define HIF_WR_SYNC_BLOCK_INC \ ++ (HIF_WRITE | HIF_SYNCHRONOUS | HIF_EXTENDED_IO | HIF_BLOCK_BASIS | HIF_INCREMENTAL_ADDRESS) ++#define HIF_RD_SYNC_BYTE_INC \ ++ (HIF_READ | HIF_SYNCHRONOUS | HIF_EXTENDED_IO | HIF_BYTE_BASIS | HIF_INCREMENTAL_ADDRESS) ++#define HIF_RD_SYNC_BYTE_FIX \ ++ (HIF_READ | HIF_SYNCHRONOUS | HIF_EXTENDED_IO | HIF_BYTE_BASIS | HIF_FIXED_ADDRESS) ++#define HIF_RD_ASYNC_BYTE_FIX \ ++ (HIF_READ | HIF_ASYNCHRONOUS | HIF_EXTENDED_IO | HIF_BYTE_BASIS | HIF_FIXED_ADDRESS) ++#define HIF_RD_ASYNC_BLOCK_FIX \ ++ (HIF_READ | HIF_ASYNCHRONOUS | HIF_EXTENDED_IO | HIF_BLOCK_BASIS | HIF_FIXED_ADDRESS) ++#define HIF_RD_ASYNC_BYTE_INC \ ++ (HIF_READ | HIF_ASYNCHRONOUS | HIF_EXTENDED_IO | HIF_BYTE_BASIS | HIF_INCREMENTAL_ADDRESS) ++#define HIF_RD_ASYNC_BLOCK_INC \ ++ (HIF_READ | HIF_ASYNCHRONOUS | HIF_EXTENDED_IO | HIF_BLOCK_BASIS | HIF_INCREMENTAL_ADDRESS) ++#define HIF_RD_SYNC_BLOCK_INC \ ++ (HIF_READ | HIF_SYNCHRONOUS | HIF_EXTENDED_IO | HIF_BLOCK_BASIS | HIF_INCREMENTAL_ADDRESS) ++ ++ ++typedef enum { ++ HIF_DEVICE_POWER_STATE = 0, ++ HIF_DEVICE_GET_MBOX_BLOCK_SIZE, ++ HIF_DEVICE_GET_MBOX_ADDR, ++ HIF_DEVICE_GET_PENDING_EVENTS_FUNC, ++ HIF_DEVICE_GET_IRQ_PROC_MODE, ++ HIF_DEVICE_GET_RECV_EVENT_MASK_UNMASK_FUNC, ++} HIF_DEVICE_CONFIG_OPCODE; ++ ++/* ++ * HIF CONFIGURE definitions: ++ * ++ * HIF_DEVICE_GET_MBOX_BLOCK_SIZE ++ * input : none ++ * output : array of 4 A_UINT32s ++ * notes: block size is returned for each mailbox (4) ++ * ++ * HIF_DEVICE_GET_MBOX_ADDR ++ * input : none ++ * output : array of 4 A_UINT32 ++ * notes: address is returned for each mailbox (4) in the array ++ * ++ * HIF_DEVICE_GET_PENDING_EVENTS_FUNC ++ * input : none ++ * output: HIF_PENDING_EVENTS_FUNC function pointer ++ * notes: this is optional for the HIF layer, if the request is ++ * not handled then it indicates that the upper layer can use ++ * the standard device methods to get pending events (IRQs, mailbox messages etc..) ++ * otherwise it can call the function pointer to check pending events. ++ * ++ * HIF_DEVICE_GET_IRQ_PROC_MODE ++ * input : none ++ * output : HIF_DEVICE_IRQ_PROCESSING_MODE (interrupt processing mode) ++ * note: the hif layer interfaces with the underlying OS-specific bus driver. The HIF ++ * layer can report whether IRQ processing is requires synchronous behavior or ++ * can be processed using asynchronous bus requests (typically faster). ++ * ++ * HIF_DEVICE_GET_RECV_EVENT_MASK_UNMASK_FUNC ++ * input : ++ * output : HIF_MASK_UNMASK_RECV_EVENT function pointer ++ * notes: this is optional for the HIF layer. The HIF layer may require a special mechanism ++ * to mask receive message events. The upper layer can call this pointer when it needs ++ * to mask/unmask receive events (in case it runs out of buffers). ++ * ++ * ++ */ ++ ++typedef enum { ++ HIF_DEVICE_IRQ_SYNC_ONLY, /* for HIF implementations that require the DSR to process all ++ interrupts before returning */ ++ HIF_DEVICE_IRQ_ASYNC_SYNC, /* for HIF implementations that allow DSR to process interrupts ++ using ASYNC I/O (that is HIFAckInterrupt can be called at a ++ later time */ ++} HIF_DEVICE_IRQ_PROCESSING_MODE; ++ ++#define HIF_MAX_DEVICES 1 ++ ++struct htc_callbacks { ++ A_UCHAR *name; ++ A_UINT32 id; ++ A_STATUS (* deviceInsertedHandler)(void *hif_handle); ++ A_STATUS (* deviceRemovedHandler)(void *htc_handle, A_STATUS status); ++ A_STATUS (* deviceSuspendHandler)(void *htc_handle); ++ A_STATUS (* deviceResumeHandler)(void *htc_handle); ++ A_STATUS (* deviceWakeupHandler)(void *htc_handle); ++ A_STATUS (* rwCompletionHandler)(void *context, A_STATUS status); ++ A_STATUS (* dsrHandler)(void *htc_handle); ++}; ++ ++ ++#define HIF_OTHER_EVENTS (1 << 0) /* other interrupts (non-Recv) are pending, host ++ needs to read the register table to figure out what */ ++#define HIF_RECV_MSG_AVAIL (1 << 1) /* pending recv packet */ ++ ++typedef struct _HIF_PENDING_EVENTS_INFO { ++ A_UINT32 Events; ++ A_UINT32 LookAhead; ++} HIF_PENDING_EVENTS_INFO; ++ ++ /* function to get pending events , some HIF modules use special mechanisms ++ * to detect packet available and other interrupts */ ++typedef A_STATUS ( *HIF_PENDING_EVENTS_FUNC)(HIF_DEVICE *device, ++ HIF_PENDING_EVENTS_INFO *pEvents, ++ void *AsyncContext); ++ ++#define HIF_MASK_RECV TRUE ++#define HIF_UNMASK_RECV FALSE ++ /* function to mask recv events */ ++typedef A_STATUS ( *HIF_MASK_UNMASK_RECV_EVENT)(HIF_DEVICE *device, ++ A_BOOL Mask, ++ void *AsyncContext); ++ ++ ++/* ++ * This API is used by the HTC layer to initialize the HIF layer and to ++ * register different callback routines. Support for following events has ++ * been captured - DSR, Read/Write completion, Device insertion/removal, ++ * Device suspension/resumption/wakeup. In addition to this, the API is ++ * also used to register the name and the revision of the chip. The latter ++ * can be used to verify the revision of the chip read from the device ++ * before reporting it to HTC. ++ */ ++int HIFInit(HTC_CALLBACKS *callbacks); ++ ++/* ++ * This API is used to provide the read/write interface over the specific bus ++ * interface. ++ * address - Starting address in the dragon's address space. For mailbox ++ * writes, it refers to the start of the mbox boundary. It should ++ * be ensured that the last byte falls on the mailbox's EOM. For ++ * mailbox reads, it refers to the end of the mbox boundary. ++ * buffer - Pointer to the buffer containg the data to be transmitted or ++ * received. ++ * length - Amount of data to be transmitted or received. ++ * request - Characterizes the attributes of the command. ++ */ ++A_STATUS ++HIFReadWrite(HIF_DEVICE *device, ++ A_UINT32 address, ++ A_UCHAR *buffer, ++ A_UINT32 length, ++ A_UINT32 request, ++ void *context); ++ ++/* ++ * This can be initiated from the unload driver context ie when the HTCShutdown ++ * routine is called. ++ */ ++void HIFShutDownDevice(HIF_DEVICE *device); ++ ++/* ++ * This should translate to an acknowledgment to the bus driver indicating that ++ * the previous interrupt request has been serviced and the all the relevant ++ * sources have been cleared. HTC is ready to process more interrupts. ++ * This should prevent the bus driver from raising an interrupt unless the ++ * previous one has been serviced and acknowledged using the previous API. ++ */ ++void HIFAckInterrupt(HIF_DEVICE *device); ++ ++void HIFMaskInterrupt(HIF_DEVICE *device); ++ ++void HIFUnMaskInterrupt(HIF_DEVICE *device); ++ ++/* ++ * This set of functions are to be used by the bus driver to notify ++ * the HIF module about various events. ++ * These are not implemented if the bus driver provides an alternative ++ * way for this notification though callbacks for instance. ++ */ ++int HIFInsertEventNotify(void); ++ ++int HIFRemoveEventNotify(void); ++ ++int HIFIRQEventNotify(void); ++ ++int HIFRWCompleteEventNotify(void); ++ ++/* ++ * This function associates a opaque handle with the HIF layer ++ * to be used in communication with upper layer i.e. HTC. ++ * This would normaly be a pointer to htc_target data structure. ++ */ ++void HIFSetHandle(void *hif_handle, void *handle); ++ ++A_STATUS ++HIFConfigureDevice(HIF_DEVICE *device, HIF_DEVICE_CONFIG_OPCODE opcode, ++ void *config, A_UINT32 configLen); ++ ++ ++struct device; ++struct device* ++HIFGetOSDevice(HIF_DEVICE *device); ++ ++ ++#ifdef __cplusplus ++} ++#endif ++ ++#endif /* _HIF_H_ */ +diff -ruN --exclude='*.orig' --exclude='*.rej' linux-2.6.29-rc3.owrt/drivers/ar6000/include/host_version.h linux-2.6.29-rc3.owrt.om/drivers/ar6000/include/host_version.h +--- linux-2.6.29-rc3.owrt/drivers/ar6000/include/host_version.h 1970-01-01 01:00:00.000000000 +0100 ++++ linux-2.6.29-rc3.owrt.om/drivers/ar6000/include/host_version.h 2009-05-10 22:27:59.000000000 +0200 +@@ -0,0 +1,49 @@ ++#ifndef _HOST_VERSION_H_ ++#define _HOST_VERSION_H_ ++/* ++ * Copyright (c) 2004-2005 Atheros Communications Inc. ++ * All rights reserved. ++ * ++ * This file contains version information for the sample host driver for the ++ * AR6000 chip ++ * ++ * $Id: //depot/sw/releases/olca2.0-GPL/host/include/host_version.h#2 $ ++ * ++ * ++ * 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; ++ * ++ * Software distributed under the License is distributed on an "AS ++ * IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or ++ * implied. See the License for the specific language governing ++ * rights and limitations under the License. ++ * ++ * ++ * ++ */ ++ ++#ifdef __cplusplus ++extern "C" { ++#endif ++ ++#include <AR6K_version.h> ++ ++/* ++ * The version number is made up of major, minor, patch and build ++ * numbers. These are 16 bit numbers. The build and release script will ++ * set the build number using a Perforce counter. Here the build number is ++ * set to 9999 so that builds done without the build-release script are easily ++ * identifiable. ++ */ ++ ++#define ATH_SW_VER_MAJOR __VER_MAJOR_ ++#define ATH_SW_VER_MINOR __VER_MINOR_ ++#define ATH_SW_VER_PATCH __VER_PATCH_ ++#define ATH_SW_VER_BUILD 9999 ++ ++#ifdef __cplusplus ++} ++#endif ++ ++#endif /* _HOST_VERSION_H_ */ +diff -ruN --exclude='*.orig' --exclude='*.rej' linux-2.6.29-rc3.owrt/drivers/ar6000/include/htc_api.h linux-2.6.29-rc3.owrt.om/drivers/ar6000/include/htc_api.h +--- linux-2.6.29-rc3.owrt/drivers/ar6000/include/htc_api.h 1970-01-01 01:00:00.000000000 +0100 ++++ linux-2.6.29-rc3.owrt.om/drivers/ar6000/include/htc_api.h 2009-05-10 22:27:59.000000000 +0200 +@@ -0,0 +1,439 @@ ++/* ++ * ++ * Copyright (c) 2007 Atheros Communications Inc. ++ * All rights reserved. ++ * ++ * ++ * 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; ++ * ++ * Software distributed under the License is distributed on an "AS ++ * IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or ++ * implied. See the License for the specific language governing ++ * rights and limitations under the License. ++ * ++ * ++ * ++ */ ++ ++#ifndef _HTC_API_H_ ++#define _HTC_API_H_ ++ ++#include <htc.h> ++#include <htc_services.h> ++#include "htc_packet.h" ++ ++#ifdef __cplusplus ++extern "C" { ++#endif /* __cplusplus */ ++ ++/* TODO.. for BMI */ ++#define ENDPOINT1 0 ++// TODO -remove me, but we have to fix BMI first ++#define HTC_MAILBOX_NUM_MAX 4 ++ ++ ++/* ------ Endpoint IDS ------ */ ++typedef enum ++{ ++ ENDPOINT_UNUSED = -1, ++ ENDPOINT_0 = 0, ++ ENDPOINT_1 = 1, ++ ENDPOINT_2 = 2, ++ ENDPOINT_3, ++ ENDPOINT_4, ++ ENDPOINT_5, ++ ENDPOINT_6, ++ ENDPOINT_7, ++ ENDPOINT_8, ++ ENDPOINT_MAX, ++} HTC_ENDPOINT_ID; ++ ++/* this is the amount of header room required by users of HTC */ ++#define HTC_HEADER_LEN HTC_HDR_LENGTH ++ ++typedef void *HTC_HANDLE; ++ ++typedef A_UINT16 HTC_SERVICE_ID; ++ ++typedef struct _HTC_INIT_INFO { ++ void (*AddInstance)(HTC_HANDLE); ++ void (*DeleteInstance)(void *Instance); ++ void (*TargetFailure)(void *Instance, A_STATUS Status); ++} HTC_INIT_INFO; ++ ++/* per service connection send completion */ ++typedef void (*HTC_EP_SEND_PKT_COMPLETE)(void *,HTC_PACKET *); ++/* per service connection pkt received */ ++typedef void (*HTC_EP_RECV_PKT)(void *,HTC_PACKET *); ++ ++/* Optional per service connection receive buffer re-fill callback, ++ * On some OSes (like Linux) packets are allocated from a global pool and indicated up ++ * to the network stack. The driver never gets the packets back from the OS. For these OSes ++ * a refill callback can be used to allocate and re-queue buffers into HTC. ++ * ++ * On other OSes, the network stack can call into the driver's OS-specifc "return_packet" handler and ++ * the driver can re-queue these buffers into HTC. In this regard a refill callback is ++ * unnecessary */ ++typedef void (*HTC_EP_RECV_REFILL)(void *, HTC_ENDPOINT_ID Endpoint); ++ ++/* Optional per service connection callback when a send queue is full. This can occur if the ++ * host continues queueing up TX packets faster than credits can arrive ++ * To prevent the host (on some Oses like Linux) from continuously queueing packets ++ * and consuming resources, this callback is provided so that that the host ++ * can disable TX in the subsystem (i.e. network stack) ++ * Other OSes require a "per-packet" indication_RAW_STREAM_NUM_MAX for each completed TX packet, this ++ * closed loop mechanism will prevent the network stack from overunning the NIC */ ++typedef void (*HTC_EP_SEND_QUEUE_FULL)(void *, HTC_ENDPOINT_ID Endpoint); ++/* Optional per service connection callback when a send queue is available for receive new packet. */ ++typedef void (*HTC_EP_SEND_QUEUE_AVAIL)(void *, HTC_ENDPOINT_ID Endpoint); ++ ++typedef struct _HTC_EP_CALLBACKS { ++ void *pContext; /* context for each callback */ ++ HTC_EP_SEND_PKT_COMPLETE EpTxComplete; /* tx completion callback for connected endpoint */ ++ HTC_EP_RECV_PKT EpRecv; /* receive callback for connected endpoint */ ++ HTC_EP_RECV_REFILL EpRecvRefill; /* OPTIONAL receive re-fill callback for connected endpoint */ ++ HTC_EP_SEND_QUEUE_FULL EpSendFull; /* OPTIONAL send full callback */ ++ HTC_EP_SEND_QUEUE_AVAIL EpSendAvail; /* OPTIONAL send available callback */ ++} HTC_EP_CALLBACKS; ++ ++/* service connection information */ ++typedef struct _HTC_SERVICE_CONNECT_REQ { ++ HTC_SERVICE_ID ServiceID; /* service ID to connect to */ ++ A_UINT16 ConnectionFlags; /* connection flags, see htc protocol definition */ ++ A_UINT8 *pMetaData; /* ptr to optional service-specific meta-data */ ++ A_UINT8 MetaDataLength; /* optional meta data length */ ++ HTC_EP_CALLBACKS EpCallbacks; /* endpoint callbacks */ ++ int MaxSendQueueDepth; /* maximum depth of any send queue */ ++} HTC_SERVICE_CONNECT_REQ; ++ ++/* service connection response information */ ++typedef struct _HTC_SERVICE_CONNECT_RESP { ++ A_UINT8 *pMetaData; /* caller supplied buffer to optional meta-data */ ++ A_UINT8 BufferLength; /* length of caller supplied buffer */ ++ A_UINT8 ActualLength; /* actual length of meta data */ ++ HTC_ENDPOINT_ID Endpoint; /* endpoint to communicate over */ ++ int MaxMsgLength; /* max length of all messages over this endpoint */ ++ A_UINT8 ConnectRespCode; /* connect response code from target */ ++} HTC_SERVICE_CONNECT_RESP; ++ ++/* endpoint distribution structure */ ++typedef struct _HTC_ENDPOINT_CREDIT_DIST { ++ struct _HTC_ENDPOINT_CREDIT_DIST *pNext; ++ struct _HTC_ENDPOINT_CREDIT_DIST *pPrev; ++ HTC_SERVICE_ID ServiceID; /* Service ID (set by HTC) */ ++ HTC_ENDPOINT_ID Endpoint; /* endpoint for this distribution struct (set by HTC) */ ++ A_UINT32 DistFlags; /* distribution flags, distribution function can ++ set default activity using SET_EP_ACTIVE() macro */ ++ int TxCreditsNorm; /* credits for normal operation, anything above this ++ indicates the endpoint is over-subscribed, this field ++ is only relevant to the credit distribution function */ ++ int TxCreditsMin; /* floor for credit distribution, this field is ++ only relevant to the credit distribution function */ ++ int TxCreditsAssigned; /* number of credits assigned to this EP, this field ++ is only relevant to the credit dist function */ ++ int TxCredits; /* current credits available, this field is used by ++ HTC to determine whether a message can be sent or ++ must be queued */ ++ int TxCreditsToDist; /* pending credits to distribute on this endpoint, this ++ is set by HTC when credit reports arrive. ++ The credit distribution functions sets this to zero ++ when it distributes the credits */ ++ int TxCreditsSeek; /* this is the number of credits that the current pending TX ++ packet needs to transmit. This is set by HTC when ++ and endpoint needs credits in order to transmit */ ++ int TxCreditSize; /* size in bytes of each credit (set by HTC) */ ++ int TxCreditsPerMaxMsg; /* credits required for a maximum sized messages (set by HTC) */ ++ void *pHTCReserved; /* reserved for HTC use */ ++} HTC_ENDPOINT_CREDIT_DIST; ++ ++#define HTC_EP_ACTIVE (1 << 31) ++ ++/* macro to check if an endpoint has gone active, useful for credit ++ * distributions */ ++#define IS_EP_ACTIVE(epDist) ((epDist)->DistFlags & HTC_EP_ACTIVE) ++#define SET_EP_ACTIVE(epDist) (epDist)->DistFlags |= HTC_EP_ACTIVE ++ ++ /* credit distibution code that is passed into the distrbution function, ++ * there are mandatory and optional codes that must be handled */ ++typedef enum _HTC_CREDIT_DIST_REASON { ++ HTC_CREDIT_DIST_SEND_COMPLETE = 0, /* credits available as a result of completed ++ send operations (MANDATORY) resulting in credit reports */ ++ HTC_CREDIT_DIST_ACTIVITY_CHANGE = 1, /* a change in endpoint activity occured (OPTIONAL) */ ++ HTC_CREDIT_DIST_SEEK_CREDITS, /* an endpoint needs to "seek" credits (OPTIONAL) */ ++ HTC_DUMP_CREDIT_STATE /* for debugging, dump any state information that is kept by ++ the distribution function */ ++} HTC_CREDIT_DIST_REASON; ++ ++typedef void (*HTC_CREDIT_DIST_CALLBACK)(void *Context, ++ HTC_ENDPOINT_CREDIT_DIST *pEPList, ++ HTC_CREDIT_DIST_REASON Reason); ++ ++typedef void (*HTC_CREDIT_INIT_CALLBACK)(void *Context, ++ HTC_ENDPOINT_CREDIT_DIST *pEPList, ++ int TotalCredits); ++ ++ /* endpoint statistics action */ ++typedef enum _HTC_ENDPOINT_STAT_ACTION { ++ HTC_EP_STAT_SAMPLE = 0, /* only read statistics */ ++ HTC_EP_STAT_SAMPLE_AND_CLEAR = 1, /* sample and immediately clear statistics */ ++ HTC_EP_STAT_CLEAR /* clear only */ ++} HTC_ENDPOINT_STAT_ACTION; ++ ++ /* endpoint statistics */ ++typedef struct _HTC_ENDPOINT_STATS { ++ A_UINT32 TxCreditLowIndications; /* number of times the host set the credit-low flag in a send message on ++ this endpoint */ ++ A_UINT32 TxIssued; /* running count of TX packets issued */ ++ A_UINT32 TxCreditRpts; /* running count of total credit reports received for this endpoint */ ++ A_UINT32 TxCreditRptsFromRx; ++ A_UINT32 TxCreditRptsFromOther; ++ A_UINT32 TxCreditRptsFromEp0; ++ A_UINT32 TxCreditsFromRx; /* count of credits received via Rx packets on this endpoint */ ++ A_UINT32 TxCreditsFromOther; /* count of credits received via another endpoint */ ++ A_UINT32 TxCreditsFromEp0; /* count of credits received via another endpoint */ ++ A_UINT32 TxCreditsConsummed; /* count of consummed credits */ ++ A_UINT32 TxCreditsReturned; /* count of credits returned */ ++ A_UINT32 RxReceived; /* count of RX packets received */ ++ A_UINT32 RxLookAheads; /* count of lookahead records ++ found in messages received on this endpoint */ ++} HTC_ENDPOINT_STATS; ++ ++/* ------ Function Prototypes ------ */ ++/*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ ++ @desc: Initialize HTC ++ @function name: HTCInit ++ @input: pInfo - initialization information ++ @output: ++ @return: A_OK on success ++ @notes: The caller initializes global HTC state and registers various instance ++ notification callbacks (see HTC_INIT_INFO). ++ ++ @example: ++ @see also: HTCShutdown +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*/ ++A_STATUS HTCInit(HTC_INIT_INFO *pInfo); ++/*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ ++ @desc: Get the underlying HIF device handle ++ @function name: HTCGetHifDevice ++ @input: HTCHandle - handle passed into the AddInstance callback ++ @output: ++ @return: opaque HIF device handle usable in HIF API calls. ++ @notes: ++ @example: ++ @see also: +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*/ ++void *HTCGetHifDevice(HTC_HANDLE HTCHandle); ++/*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ ++ @desc: Set the associated instance for the HTC handle ++ @function name: HTCSetInstance ++ @input: HTCHandle - handle passed into the AddInstance callback ++ Instance - caller supplied instance object ++ @output: ++ @return: ++ @notes: Caller must set the instance information for the HTC handle in order to receive ++ notifications for instance deletion (DeleteInstance callback is called) and for target ++ failure notification. ++ @example: ++ @see also: +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*/ ++void HTCSetInstance(HTC_HANDLE HTCHandle, void *Instance); ++/*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ ++ @desc: Set credit distribution parameters ++ @function name: HTCSetCreditDistribution ++ @input: HTCHandle - HTC handle ++ pCreditDistCont - caller supplied context to pass into distribution functions ++ CreditDistFunc - Distribution function callback ++ CreditDistInit - Credit Distribution initialization callback ++ ServicePriorityOrder - Array containing list of service IDs, lowest index is highest ++ priority ++ ListLength - number of elements in ServicePriorityOrder ++ @output: ++ @return: ++ @notes: The user can set a custom credit distribution function to handle special requirements ++ for each endpoint. A default credit distribution routine can be used by setting ++ CreditInitFunc to NULL. The default credit distribution is only provided for simple ++ "fair" credit distribution without regard to any prioritization. ++ ++ @example: ++ @see also: +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*/ ++void HTCSetCreditDistribution(HTC_HANDLE HTCHandle, ++ void *pCreditDistContext, ++ HTC_CREDIT_DIST_CALLBACK CreditDistFunc, ++ HTC_CREDIT_INIT_CALLBACK CreditInitFunc, ++ HTC_SERVICE_ID ServicePriorityOrder[], ++ int ListLength); ++/*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ ++ @desc: Wait for the target to indicate the HTC layer is ready ++ @function name: HTCWaitTarget ++ @input: HTCHandle - HTC handle ++ @output: ++ @return: ++ @notes: This API blocks until the target responds with an HTC ready message. ++ The caller should not connect services until the target has indicated it is ++ ready. ++ @example: ++ @see also: HTCConnectService +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*/ ++A_STATUS HTCWaitTarget(HTC_HANDLE HTCHandle); ++/*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ ++ @desc: Start target service communications ++ @function name: HTCStart ++ @input: HTCHandle - HTC handle ++ @output: ++ @return: ++ @notes: This API indicates to the target that the service connection phase is complete ++ and the target can freely start all connected services. This API should only be ++ called AFTER all service connections have been made. TCStart will issue a ++ SETUP_COMPLETE message to the target to indicate that all service connections ++ have been made and the target can start communicating over the endpoints. ++ @example: ++ @see also: HTCConnectService +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*/ ++A_STATUS HTCStart(HTC_HANDLE HTCHandle); ++/*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ ++ @desc: Add receive packet to HTC ++ @function name: HTCAddReceivePkt ++ @input: HTCHandle - HTC handle ++ pPacket - HTC receive packet to add ++ @output: ++ @return: A_OK on success ++ @notes: user must supply HTC packets for capturing incomming HTC frames. The caller ++ must initialize each HTC packet using the SET_HTC_PACKET_INFO_RX_REFILL() ++ macro. ++ @example: ++ @see also: +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*/ ++A_STATUS HTCAddReceivePkt(HTC_HANDLE HTCHandle, HTC_PACKET *pPacket); ++/*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ ++ @desc: Connect to an HTC service ++ @function name: HTCConnectService ++ @input: HTCHandle - HTC handle ++ pReq - connection details ++ @output: pResp - connection response ++ @return: ++ @notes: Service connections must be performed before HTCStart. User provides callback handlers ++ for various endpoint events. ++ @example: ++ @see also: HTCStart +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*/ ++A_STATUS HTCConnectService(HTC_HANDLE HTCHandle, ++ HTC_SERVICE_CONNECT_REQ *pReq, ++ HTC_SERVICE_CONNECT_RESP *pResp); ++/*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ ++ @desc: Send an HTC packet ++ @function name: HTCSendPkt ++ @input: HTCHandle - HTC handle ++ pPacket - packet to send ++ @output: ++ @return: A_OK ++ @notes: Caller must initialize packet using SET_HTC_PACKET_INFO_TX() macro. ++ This interface is fully asynchronous. On error, HTC SendPkt will ++ call the registered Endpoint callback to cleanup the packet. ++ @example: ++ @see also: HTCFlushEndpoint +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*/ ++A_STATUS HTCSendPkt(HTC_HANDLE HTCHandle, HTC_PACKET *pPacket); ++/*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ ++ @desc: Stop HTC service communications ++ @function name: HTCStop ++ @input: HTCHandle - HTC handle ++ @output: ++ @return: ++ @notes: HTC communications is halted. All receive and pending TX packets will ++ be flushed. ++ @example: ++ @see also: +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*/ ++void HTCStop(HTC_HANDLE HTCHandle); ++/*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ ++ @desc: Shutdown HTC ++ @function name: HTCShutdown ++ @input: ++ @output: ++ @return: ++ @notes: This cleans up all resources allocated by HTCInit(). ++ @example: ++ @see also: HTCInit +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*/ ++void HTCShutDown(void); ++/*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ ++ @desc: Flush pending TX packets ++ @function name: HTCFlushEndpoint ++ @input: HTCHandle - HTC handle ++ Endpoint - Endpoint to flush ++ Tag - flush tag ++ @output: ++ @return: ++ @notes: The Tag parameter is used to selectively flush packets with matching tags. ++ The value of 0 forces all packets to be flush regardless of tag. ++ @example: ++ @see also: HTCSendPkt +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*/ ++void HTCFlushEndpoint(HTC_HANDLE HTCHandle, HTC_ENDPOINT_ID Endpoint, HTC_TX_TAG Tag); ++/*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ ++ @desc: Dump credit distribution state ++ @function name: HTCDumpCreditStates ++ @input: HTCHandle - HTC handle ++ @output: ++ @return: ++ @notes: This dumps all credit distribution information to the debugger ++ @example: ++ @see also: +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*/ ++void HTCDumpCreditStates(HTC_HANDLE HTCHandle); ++/*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ ++ @desc: Indicate a traffic activity change on an endpoint ++ @function name: HTCIndicateActivityChange ++ @input: HTCHandle - HTC handle ++ Endpoint - endpoint in which activity has changed ++ Active - TRUE if active, FALSE if it has become inactive ++ @output: ++ @return: ++ @notes: This triggers the registered credit distribution function to ++ re-adjust credits for active/inactive endpoints. ++ @example: ++ @see also: +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*/ ++void HTCIndicateActivityChange(HTC_HANDLE HTCHandle, ++ HTC_ENDPOINT_ID Endpoint, ++ A_BOOL Active); ++ ++/*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ ++ @desc: Get endpoint statistics ++ @function name: HTCGetEndpointStatistics ++ @input: HTCHandle - HTC handle ++ Endpoint - Endpoint identifier ++ Action - action to take with statistics ++ @output: ++ pStats - statistics that were sampled (can be NULL if Action is HTC_EP_STAT_CLEAR) ++ ++ @return: TRUE if statistics profiling is enabled, otherwise FALSE. ++ ++ @notes: Statistics is a compile-time option and this function may return FALSE ++ if HTC is not compiled with profiling. ++ ++ The caller can specify the statistic "action" to take when sampling ++ the statistics. This includes: ++ ++ HTC_EP_STAT_SAMPLE: The pStats structure is filled with the current values. ++ HTC_EP_STAT_SAMPLE_AND_CLEAR: The structure is filled and the current statistics ++ are cleared. ++ HTC_EP_STAT_CLEA : the statistics are cleared, the called can pass a NULL value for ++ pStats ++ ++ @example: ++ @see also: +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*/ ++A_BOOL HTCGetEndpointStatistics(HTC_HANDLE HTCHandle, ++ HTC_ENDPOINT_ID Endpoint, ++ HTC_ENDPOINT_STAT_ACTION Action, ++ HTC_ENDPOINT_STATS *pStats); ++ ++#ifdef __cplusplus ++} ++#endif ++ ++#endif /* _HTC_API_H_ */ +diff -ruN --exclude='*.orig' --exclude='*.rej' linux-2.6.29-rc3.owrt/drivers/ar6000/include/htc.h linux-2.6.29-rc3.owrt.om/drivers/ar6000/include/htc.h +--- linux-2.6.29-rc3.owrt/drivers/ar6000/include/htc.h 1970-01-01 01:00:00.000000000 +0100 ++++ linux-2.6.29-rc3.owrt.om/drivers/ar6000/include/htc.h 2009-05-10 22:27:59.000000000 +0200 +@@ -0,0 +1,190 @@ ++/* ++ * Copyright (c) 2007 Atheros Communications Inc. ++ * All rights reserved. ++ * ++ * $ATH_LICENSE_HOSTSDK0_C$ ++ * ++ */ ++ ++ ++#ifndef __HTC_H__ ++#define __HTC_H__ ++ ++#ifndef ATH_TARGET ++#include "athstartpack.h" ++#endif ++ ++#define A_OFFSETOF(type,field) (int)(&(((type *)NULL)->field)) ++ ++#define ASSEMBLE_UNALIGNED_UINT16(p,highbyte,lowbyte) \ ++ (((A_UINT16)(((A_UINT8 *)(p))[(highbyte)])) << 8 | (A_UINT16)(((A_UINT8 *)(p))[(lowbyte)])) ++ ++/* alignment independent macros (little-endian) to fetch UINT16s or UINT8s from a ++ * structure using only the type and field name. ++ * Use these macros if there is the potential for unaligned buffer accesses. */ ++#define A_GET_UINT16_FIELD(p,type,field) \ ++ ASSEMBLE_UNALIGNED_UINT16(p,\ ++ A_OFFSETOF(type,field) + 1, \ ++ A_OFFSETOF(type,field)) ++ ++#define A_SET_UINT16_FIELD(p,type,field,value) \ ++{ \ ++ ((A_UINT8 *)(p))[A_OFFSETOF(type,field)] = (A_UINT8)(value); \ ++ ((A_UINT8 *)(p))[A_OFFSETOF(type,field) + 1] = (A_UINT8)((value) >> 8); \ ++} ++ ++#define A_GET_UINT8_FIELD(p,type,field) \ ++ ((A_UINT8 *)(p))[A_OFFSETOF(type,field)] ++ ++#define A_SET_UINT8_FIELD(p,type,field,value) \ ++ ((A_UINT8 *)(p))[A_OFFSETOF(type,field)] = (value) ++ ++/****** DANGER DANGER *************** ++ * ++ * The frame header length and message formats defined herein were ++ * selected to accommodate optimal alignment for target processing. This reduces code ++ * size and improves performance. ++ * ++ * Any changes to the header length may alter the alignment and cause exceptions ++ * on the target. When adding to the message structures insure that fields are ++ * properly aligned. ++ * ++ */ ++ ++/* HTC frame header */ ++typedef PREPACK struct _HTC_FRAME_HDR{ ++ /* do not remove or re-arrange these fields, these are minimally required ++ * to take advantage of 4-byte lookaheads in some hardware implementations */ ++ A_UINT8 EndpointID; ++ A_UINT8 Flags; ++ A_UINT16 PayloadLen; /* length of data (including trailer) that follows the header */ ++ ++ /***** end of 4-byte lookahead ****/ ++ ++ A_UINT8 ControlBytes[2]; ++ ++ /* message payload starts after the header */ ++ ++} POSTPACK HTC_FRAME_HDR; ++ ++/* frame header flags */ ++#define HTC_FLAGS_NEED_CREDIT_UPDATE (1 << 0) ++#define HTC_FLAGS_RECV_TRAILER (1 << 1) ++ ++ ++#define HTC_HDR_LENGTH (sizeof(HTC_FRAME_HDR)) ++#define HTC_MAX_TRAILER_LENGTH 255 ++#define HTC_MAX_PAYLOAD_LENGTH (2048 - sizeof(HTC_FRAME_HDR)) ++ ++/* HTC control message IDs */ ++typedef enum { ++ HTC_MSG_READY_ID = 1, ++ HTC_MSG_CONNECT_SERVICE_ID = 2, ++ HTC_MSG_CONNECT_SERVICE_RESPONSE_ID = 3, ++ HTC_MSG_SETUP_COMPLETE_ID = 4, ++} HTC_MSG_IDS; ++ ++#define HTC_MAX_CONTROL_MESSAGE_LENGTH 256 ++ ++/* base message ID header */ ++typedef PREPACK struct { ++ A_UINT16 MessageID; ++} POSTPACK HTC_UNKNOWN_MSG; ++ ++/* HTC ready message ++ * direction : target-to-host */ ++typedef PREPACK struct { ++ A_UINT16 MessageID; /* ID */ ++ A_UINT16 CreditCount; /* number of credits the target can offer */ ++ A_UINT16 CreditSize; /* size of each credit */ ++ A_UINT8 MaxEndpoints; /* maximum number of endpoints the target has resources for */ ++ A_UINT8 _Pad1; ++} POSTPACK HTC_READY_MSG; ++ ++#define HTC_SERVICE_META_DATA_MAX_LENGTH 128 ++ ++/* connect service ++ * direction : host-to-target */ ++typedef PREPACK struct { ++ A_UINT16 MessageID; ++ A_UINT16 ServiceID; /* service ID of the service to connect to */ ++ A_UINT16 ConnectionFlags; /* connection flags */ ++ ++#define HTC_CONNECT_FLAGS_REDUCE_CREDIT_DRIBBLE (1 << 2) /* reduce credit dribbling when ++ the host needs credits */ ++#define HTC_CONNECT_FLAGS_THRESHOLD_LEVEL_MASK (0x3) ++#define HTC_CONNECT_FLAGS_THRESHOLD_LEVEL_ONE_FOURTH 0x0 ++#define HTC_CONNECT_FLAGS_THRESHOLD_LEVEL_ONE_HALF 0x1 ++#define HTC_CONNECT_FLAGS_THRESHOLD_LEVEL_THREE_FOURTHS 0x2 ++#define HTC_CONNECT_FLAGS_THRESHOLD_LEVEL_UNITY 0x3 ++ ++ A_UINT8 ServiceMetaLength; /* length of meta data that follows */ ++ A_UINT8 _Pad1; ++ ++ /* service-specific meta data starts after the header */ ++ ++} POSTPACK HTC_CONNECT_SERVICE_MSG; ++ ++/* connect response ++ * direction : target-to-host */ ++typedef PREPACK struct { ++ A_UINT16 MessageID; ++ A_UINT16 ServiceID; /* service ID that the connection request was made */ ++ A_UINT8 Status; /* service connection status */ ++ A_UINT8 EndpointID; /* assigned endpoint ID */ ++ A_UINT16 MaxMsgSize; /* maximum expected message size on this endpoint */ ++ A_UINT8 ServiceMetaLength; /* length of meta data that follows */ ++ A_UINT8 _Pad1; ++ ++ /* service-specific meta data starts after the header */ ++ ++} POSTPACK HTC_CONNECT_SERVICE_RESPONSE_MSG; ++ ++typedef PREPACK struct { ++ A_UINT16 MessageID; ++ /* currently, no other fields */ ++} POSTPACK HTC_SETUP_COMPLETE_MSG; ++ ++ ++/* connect response status codes */ ++#define HTC_SERVICE_SUCCESS 0 /* success */ ++#define HTC_SERVICE_NOT_FOUND 1 /* service could not be found */ ++#define HTC_SERVICE_FAILED 2 /* specific service failed the connect */ ++#define HTC_SERVICE_NO_RESOURCES 3 /* no resources (i.e. no more endpoints) */ ++#define HTC_SERVICE_NO_MORE_EP 4 /* specific service is not allowing any more ++ endpoints */ ++ ++/* report record IDs */ ++typedef enum { ++ HTC_RECORD_NULL = 0, ++ HTC_RECORD_CREDITS = 1, ++ HTC_RECORD_LOOKAHEAD = 2, ++} HTC_RPT_IDS; ++ ++typedef PREPACK struct { ++ A_UINT8 RecordID; /* Record ID */ ++ A_UINT8 Length; /* Length of record */ ++} POSTPACK HTC_RECORD_HDR; ++ ++typedef PREPACK struct { ++ A_UINT8 EndpointID; /* Endpoint that owns these credits */ ++ A_UINT8 Credits; /* credits to report since last report */ ++} POSTPACK HTC_CREDIT_REPORT; ++ ++typedef PREPACK struct { ++ A_UINT8 PreValid; /* pre valid guard */ ++ A_UINT8 LookAhead[4]; /* 4 byte lookahead */ ++ A_UINT8 PostValid; /* post valid guard */ ++ ++ /* NOTE: the LookAhead array is guarded by a PreValid and Post Valid guard bytes. ++ * The PreValid bytes must equal the inverse of the PostValid byte */ ++ ++} POSTPACK HTC_LOOKAHEAD_REPORT; ++ ++#ifndef ATH_TARGET ++#include "athendpack.h" ++#endif ++ ++ ++#endif /* __HTC_H__ */ ++ +diff -ruN --exclude='*.orig' --exclude='*.rej' linux-2.6.29-rc3.owrt/drivers/ar6000/include/htc_packet.h linux-2.6.29-rc3.owrt.om/drivers/ar6000/include/htc_packet.h +--- linux-2.6.29-rc3.owrt/drivers/ar6000/include/htc_packet.h 1970-01-01 01:00:00.000000000 +0100 ++++ linux-2.6.29-rc3.owrt.om/drivers/ar6000/include/htc_packet.h 2009-05-10 22:27:59.000000000 +0200 +@@ -0,0 +1,138 @@ ++/* ++ * ++ * Copyright (c) 2007 Atheros Communications Inc. ++ * All rights reserved. ++ * ++ * ++ * 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; ++ * ++ * Software distributed under the License is distributed on an "AS ++ * IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or ++ * implied. See the License for the specific language governing ++ * rights and limitations under the License. ++ * ++ * ++ * ++ */ ++ ++#ifndef HTC_PACKET_H_ ++#define HTC_PACKET_H_ ++ ++ ++#include "dl_list.h" ++ ++struct _HTC_PACKET; ++ ++typedef void (* HTC_PACKET_COMPLETION)(void *,struct _HTC_PACKET *); ++ ++typedef A_UINT16 HTC_TX_TAG; ++ ++typedef struct _HTC_TX_PACKET_INFO { ++ HTC_TX_TAG Tag; /* tag used to selective flush packets */ ++} HTC_TX_PACKET_INFO; ++ ++#define HTC_TX_PACKET_TAG_ALL 0 /* a tag of zero is reserved and used to flush ALL packets */ ++#define HTC_TX_PACKET_TAG_INTERNAL 1 /* internal tags start here */ ++#define HTC_TX_PACKET_TAG_USER_DEFINED (HTC_TX_PACKET_TAG_INTERNAL + 9) /* user-defined tags start here */ ++ ++typedef struct _HTC_RX_PACKET_INFO { ++ A_UINT32 Unused; /* for future use and to make compilers happy */ ++} HTC_RX_PACKET_INFO; ++ ++/* wrapper around endpoint-specific packets */ ++typedef struct _HTC_PACKET { ++ DL_LIST ListLink; /* double link */ ++ void *pPktContext; /* caller's per packet specific context */ ++ ++ A_UINT8 *pBufferStart; /* the true buffer start , the caller can ++ store the real buffer start here. In ++ receive callbacks, the HTC layer sets pBuffer ++ to the start of the payload past the header. This ++ field allows the caller to reset pBuffer when it ++ recycles receive packets back to HTC */ ++ /* ++ * Pointer to the start of the buffer. In the transmit ++ * direction this points to the start of the payload. In the ++ * receive direction, however, the buffer when queued up ++ * points to the start of the HTC header but when returned ++ * to the caller points to the start of the payload ++ */ ++ A_UINT8 *pBuffer; /* payload start (RX/TX) */ ++ A_UINT32 BufferLength; /* length of buffer */ ++ A_UINT32 ActualLength; /* actual length of payload */ ++ int Endpoint; /* endpoint that this packet was sent/recv'd from */ ++ A_STATUS Status; /* completion status */ ++ union { ++ HTC_TX_PACKET_INFO AsTx; /* Tx Packet specific info */ ++ HTC_RX_PACKET_INFO AsRx; /* Rx Packet specific info */ ++ } PktInfo; ++ ++ /* the following fields are for internal HTC use */ ++ HTC_PACKET_COMPLETION Completion; /* completion */ ++ void *pContext; /* HTC private completion context */ ++ A_UINT32 HTCReserved; /* reserved */ ++} HTC_PACKET; ++ ++ ++ ++#define COMPLETE_HTC_PACKET(p,status) \ ++{ \ ++ (p)->Status = (status); \ ++ (p)->Completion((p)->pContext,(p)); \ ++} ++ ++#define INIT_HTC_PACKET_INFO(p,b,len) \ ++{ \ ++ (p)->pBufferStart = (b); \ ++ (p)->BufferLength = (len); \ ++} ++ ++/* macro to set an initial RX packet for refilling HTC */ ++#define SET_HTC_PACKET_INFO_RX_REFILL(p,c,b,len,ep) \ ++{ \ ++ (p)->pPktContext = (c); \ ++ (p)->pBuffer = (b); \ ++ (p)->pBufferStart = (b); \ ++ (p)->BufferLength = (len); \ ++ (p)->Endpoint = (ep); \ ++} ++ ++/* fast macro to recycle an RX packet that will be re-queued to HTC */ ++#define HTC_PACKET_RESET_RX(p) \ ++ (p)->pBuffer = (p)->pBufferStart ++ ++/* macro to set packet parameters for TX */ ++#define SET_HTC_PACKET_INFO_TX(p,c,b,len,ep,tag) \ ++{ \ ++ (p)->pPktContext = (c); \ ++ (p)->pBuffer = (b); \ ++ (p)->ActualLength = (len); \ ++ (p)->Endpoint = (ep); \ ++ (p)->PktInfo.AsTx.Tag = (tag); \ ++} ++ ++/* HTC Packet Queueing Macros */ ++typedef DL_LIST HTC_PACKET_QUEUE; ++/* initialize queue */ ++#define INIT_HTC_PACKET_QUEUE(pQ) DL_LIST_INIT((pQ)) ++/* enqueue HTC packet to the tail of the queue */ ++#define HTC_PACKET_ENQUEUE(pQ,p) DL_ListInsertTail((pQ),&(p)->ListLink) ++/* test if a queue is empty */ ++#define HTC_QUEUE_EMPTY(pQ) DL_LIST_IS_EMPTY((pQ)) ++/* get packet at head without removing it */ ++#define HTC_GET_PKT_AT_HEAD(pQ) A_CONTAINING_STRUCT((DL_LIST_GET_ITEM_AT_HEAD(pQ)),HTC_PACKET,ListLink); ++/* remove a packet from the current list it is linked to */ ++#define HTC_PACKET_REMOVE(p) DL_ListRemove(&(p)->ListLink) ++ ++/* dequeue an HTC packet from the head of the queue */ ++static INLINE HTC_PACKET *HTC_PACKET_DEQUEUE(HTC_PACKET_QUEUE *queue) { ++ DL_LIST *pItem = DL_ListRemoveItemFromHead(queue); ++ if (pItem != NULL) { ++ return A_CONTAINING_STRUCT(pItem, HTC_PACKET, ListLink); ++ } ++ return NULL; ++} ++ ++#endif /*HTC_PACKET_H_*/ +diff -ruN --exclude='*.orig' --exclude='*.rej' linux-2.6.29-rc3.owrt/drivers/ar6000/include/htc_services.h linux-2.6.29-rc3.owrt.om/drivers/ar6000/include/htc_services.h +--- linux-2.6.29-rc3.owrt/drivers/ar6000/include/htc_services.h 1970-01-01 01:00:00.000000000 +0100 ++++ linux-2.6.29-rc3.owrt.om/drivers/ar6000/include/htc_services.h 2009-05-10 22:27:59.000000000 +0200 +@@ -0,0 +1,37 @@ ++/* ++ * Copyright (c) 2007 Atheros Communications Inc. ++ * All rights reserved. ++ * ++ * $ATH_LICENSE_HOSTSDK0_C$ ++ * ++ */ ++ ++#ifndef __HTC_SERVICES_H__ ++#define __HTC_SERVICES_H__ ++ ++/* Current service IDs */ ++ ++typedef enum { ++ RSVD_SERVICE_GROUP = 0, ++ WMI_SERVICE_GROUP = 1, ++ ++ HTC_TEST_GROUP = 254, ++ HTC_SERVICE_GROUP_LAST = 255 ++}HTC_SERVICE_GROUP_IDS; ++ ++#define MAKE_SERVICE_ID(group,index) \ ++ (int)(((int)group << 8) | (int)(index)) ++ ++/* NOTE: service ID of 0x0000 is reserved and should never be used */ ++#define HTC_CTRL_RSVD_SVC MAKE_SERVICE_ID(RSVD_SERVICE_GROUP,1) ++#define WMI_CONTROL_SVC MAKE_SERVICE_ID(WMI_SERVICE_GROUP,0) ++#define WMI_DATA_BE_SVC MAKE_SERVICE_ID(WMI_SERVICE_GROUP,1) ++#define WMI_DATA_BK_SVC MAKE_SERVICE_ID(WMI_SERVICE_GROUP,2) ++#define WMI_DATA_VI_SVC MAKE_SERVICE_ID(WMI_SERVICE_GROUP,3) ++#define WMI_DATA_VO_SVC MAKE_SERVICE_ID(WMI_SERVICE_GROUP,4) ++#define WMI_MAX_SERVICES 5 ++ ++/* raw stream service (i.e. flash, tcmd, calibration apps) */ ++#define HTC_RAW_STREAMS_SVC MAKE_SERVICE_ID(HTC_TEST_GROUP,0) ++ ++#endif /*HTC_SERVICES_H_*/ +diff -ruN --exclude='*.orig' --exclude='*.rej' linux-2.6.29-rc3.owrt/drivers/ar6000/include/ieee80211.h linux-2.6.29-rc3.owrt.om/drivers/ar6000/include/ieee80211.h +--- linux-2.6.29-rc3.owrt/drivers/ar6000/include/ieee80211.h 1970-01-01 01:00:00.000000000 +0100 ++++ linux-2.6.29-rc3.owrt.om/drivers/ar6000/include/ieee80211.h 2009-05-10 22:27:59.000000000 +0200 +@@ -0,0 +1,342 @@ ++/*- ++ * Copyright (c) 2001 Atsushi Onoe ++ * Copyright (c) 2002-2004 Sam Leffler, Errno Consulting ++ * Copyright (c) 2006 Atheros Communications, Inc. ++ * ++ * Wireless Network driver for Atheros AR6001 ++ * All rights reserved. ++ * ++ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR ++ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES ++ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. ++ * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, ++ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT ++ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, ++ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY ++ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT ++ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF ++ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ++ * ++ */ ++#ifndef _NET80211_IEEE80211_H_ ++#define _NET80211_IEEE80211_H_ ++ ++#include "athstartpack.h" ++ ++/* ++ * 802.11 protocol definitions. ++ */ ++ ++#define IEEE80211_ADDR_LEN 6 /* size of 802.11 address */ ++/* is 802.11 address multicast/broadcast? */ ++#define IEEE80211_IS_MULTICAST(_a) (*(_a) & 0x01) ++#define IEEE80211_ADDR_EQ(addr1, addr2) \ ++ (A_MEMCMP(addr1, addr2, IEEE80211_ADDR_LEN) == 0) ++ ++#define IEEE80211_KEYBUF_SIZE 16 ++#define IEEE80211_MICBUF_SIZE (8+8) /* space for both tx and rx */ ++ ++/* ++ * NB: these values are ordered carefully; there are lots of ++ * of implications in any reordering. In particular beware ++ * that 4 is not used to avoid conflicting with IEEE80211_F_PRIVACY. ++ */ ++#define IEEE80211_CIPHER_WEP 0 ++#define IEEE80211_CIPHER_TKIP 1 ++#define IEEE80211_CIPHER_AES_OCB 2 ++#define IEEE80211_CIPHER_AES_CCM 3 ++#define IEEE80211_CIPHER_CKIP 5 ++#define IEEE80211_CIPHER_CCKM_KRK 6 ++#define IEEE80211_CIPHER_NONE 7 /* pseudo value */ ++ ++#define IEEE80211_CIPHER_MAX (IEEE80211_CIPHER_NONE+1) ++ ++#define IEEE80211_IS_VALID_WEP_CIPHER_LEN(len) \ ++ (((len) == 5) || ((len) == 13) || ((len) == 16)) ++ ++ ++ ++/* ++ * generic definitions for IEEE 802.11 frames ++ */ ++PREPACK struct ieee80211_frame { ++ A_UINT8 i_fc[2]; ++ A_UINT8 i_dur[2]; ++ A_UINT8 i_addr1[IEEE80211_ADDR_LEN]; ++ A_UINT8 i_addr2[IEEE80211_ADDR_LEN]; ++ A_UINT8 i_addr3[IEEE80211_ADDR_LEN]; ++ A_UINT8 i_seq[2]; ++ /* possibly followed by addr4[IEEE80211_ADDR_LEN]; */ ++ /* see below */ ++} POSTPACK; ++ ++#define IEEE80211_FC0_VERSION_MASK 0x03 ++#define IEEE80211_FC0_VERSION_SHIFT 0 ++#define IEEE80211_FC0_VERSION_0 0x00 ++#define IEEE80211_FC0_TYPE_MASK 0x0c ++#define IEEE80211_FC0_TYPE_SHIFT 2 ++#define IEEE80211_FC0_TYPE_MGT 0x00 ++#define IEEE80211_FC0_TYPE_CTL 0x04 ++#define IEEE80211_FC0_TYPE_DATA 0x08 ++ ++#define IEEE80211_FC0_SUBTYPE_MASK 0xf0 ++#define IEEE80211_FC0_SUBTYPE_SHIFT 4 ++/* for TYPE_MGT */ ++#define IEEE80211_FC0_SUBTYPE_ASSOC_REQ 0x00 ++#define IEEE80211_FC0_SUBTYPE_ASSOC_RESP 0x10 ++#define IEEE80211_FC0_SUBTYPE_REASSOC_REQ 0x20 ++#define IEEE80211_FC0_SUBTYPE_REASSOC_RESP 0x30 ++#define IEEE80211_FC0_SUBTYPE_PROBE_REQ 0x40 ++#define IEEE80211_FC0_SUBTYPE_PROBE_RESP 0x50 ++#define IEEE80211_FC0_SUBTYPE_BEACON 0x80 ++#define IEEE80211_FC0_SUBTYPE_ATIM 0x90 ++#define IEEE80211_FC0_SUBTYPE_DISASSOC 0xa0 ++#define IEEE80211_FC0_SUBTYPE_AUTH 0xb0 ++#define IEEE80211_FC0_SUBTYPE_DEAUTH 0xc0 ++/* for TYPE_CTL */ ++#define IEEE80211_FC0_SUBTYPE_PS_POLL 0xa0 ++#define IEEE80211_FC0_SUBTYPE_RTS 0xb0 ++#define IEEE80211_FC0_SUBTYPE_CTS 0xc0 ++#define IEEE80211_FC0_SUBTYPE_ACK 0xd0 ++#define IEEE80211_FC0_SUBTYPE_CF_END 0xe0 ++#define IEEE80211_FC0_SUBTYPE_CF_END_ACK 0xf0 ++/* for TYPE_DATA (bit combination) */ ++#define IEEE80211_FC0_SUBTYPE_DATA 0x00 ++#define IEEE80211_FC0_SUBTYPE_CF_ACK 0x10 ++#define IEEE80211_FC0_SUBTYPE_CF_POLL 0x20 ++#define IEEE80211_FC0_SUBTYPE_CF_ACPL 0x30 ++#define IEEE80211_FC0_SUBTYPE_NODATA 0x40 ++#define IEEE80211_FC0_SUBTYPE_CFACK 0x50 ++#define IEEE80211_FC0_SUBTYPE_CFPOLL 0x60 ++#define IEEE80211_FC0_SUBTYPE_CF_ACK_CF_ACK 0x70 ++#define IEEE80211_FC0_SUBTYPE_QOS 0x80 ++#define IEEE80211_FC0_SUBTYPE_QOS_NULL 0xc0 ++ ++#define IEEE80211_FC1_DIR_MASK 0x03 ++#define IEEE80211_FC1_DIR_NODS 0x00 /* STA->STA */ ++#define IEEE80211_FC1_DIR_TODS 0x01 /* STA->AP */ ++#define IEEE80211_FC1_DIR_FROMDS 0x02 /* AP ->STA */ ++#define IEEE80211_FC1_DIR_DSTODS 0x03 /* AP ->AP */ ++ ++#define IEEE80211_FC1_MORE_FRAG 0x04 ++#define IEEE80211_FC1_RETRY 0x08 ++#define IEEE80211_FC1_PWR_MGT 0x10 ++#define IEEE80211_FC1_MORE_DATA 0x20 ++#define IEEE80211_FC1_WEP 0x40 ++#define IEEE80211_FC1_ORDER 0x80 ++ ++#define IEEE80211_SEQ_FRAG_MASK 0x000f ++#define IEEE80211_SEQ_FRAG_SHIFT 0 ++#define IEEE80211_SEQ_SEQ_MASK 0xfff0 ++#define IEEE80211_SEQ_SEQ_SHIFT 4 ++ ++#define IEEE80211_NWID_LEN 32 ++ ++/* ++ * 802.11 rate set. ++ */ ++#define IEEE80211_RATE_SIZE 8 /* 802.11 standard */ ++#define IEEE80211_RATE_MAXSIZE 15 /* max rates we'll handle */ ++ ++#define WMM_NUM_AC 4 /* 4 AC categories */ ++ ++#define WMM_PARAM_ACI_M 0x60 /* Mask for ACI field */ ++#define WMM_PARAM_ACI_S 5 /* Shift for ACI field */ ++#define WMM_PARAM_ACM_M 0x10 /* Mask for ACM bit */ ++#define WMM_PARAM_ACM_S 4 /* Shift for ACM bit */ ++#define WMM_PARAM_AIFSN_M 0x0f /* Mask for aifsn field */ ++#define WMM_PARAM_LOGCWMIN_M 0x0f /* Mask for CwMin field (in log) */ ++#define WMM_PARAM_LOGCWMAX_M 0xf0 /* Mask for CwMax field (in log) */ ++#define WMM_PARAM_LOGCWMAX_S 4 /* Shift for CwMax field */ ++ ++#define WMM_AC_TO_TID(_ac) ( \ ++ ((_ac) == WMM_AC_VO) ? 6 : \ ++ ((_ac) == WMM_AC_VI) ? 5 : \ ++ ((_ac) == WMM_AC_BK) ? 1 : \ ++ 0) ++ ++#define TID_TO_WMM_AC(_tid) ( \ ++ ((_tid) < 1) ? WMM_AC_BE : \ ++ ((_tid) < 3) ? WMM_AC_BK : \ ++ ((_tid) < 6) ? WMM_AC_VI : \ ++ WMM_AC_VO) ++/* ++ * Management information element payloads. ++ */ ++ ++enum { ++ IEEE80211_ELEMID_SSID = 0, ++ IEEE80211_ELEMID_RATES = 1, ++ IEEE80211_ELEMID_FHPARMS = 2, ++ IEEE80211_ELEMID_DSPARMS = 3, ++ IEEE80211_ELEMID_CFPARMS = 4, ++ IEEE80211_ELEMID_TIM = 5, ++ IEEE80211_ELEMID_IBSSPARMS = 6, ++ IEEE80211_ELEMID_COUNTRY = 7, ++ IEEE80211_ELEMID_CHALLENGE = 16, ++ /* 17-31 reserved for challenge text extension */ ++ IEEE80211_ELEMID_PWRCNSTR = 32, ++ IEEE80211_ELEMID_PWRCAP = 33, ++ IEEE80211_ELEMID_TPCREQ = 34, ++ IEEE80211_ELEMID_TPCREP = 35, ++ IEEE80211_ELEMID_SUPPCHAN = 36, ++ IEEE80211_ELEMID_CHANSWITCH = 37, ++ IEEE80211_ELEMID_MEASREQ = 38, ++ IEEE80211_ELEMID_MEASREP = 39, ++ IEEE80211_ELEMID_QUIET = 40, ++ IEEE80211_ELEMID_IBSSDFS = 41, ++ IEEE80211_ELEMID_ERP = 42, ++ IEEE80211_ELEMID_RSN = 48, ++ IEEE80211_ELEMID_XRATES = 50, ++ IEEE80211_ELEMID_TPC = 150, ++ IEEE80211_ELEMID_CCKM = 156, ++ IEEE80211_ELEMID_VENDOR = 221, /* vendor private */ ++}; ++ ++#define ATH_OUI 0x7f0300 /* Atheros OUI */ ++#define ATH_OUI_TYPE 0x01 ++#define ATH_OUI_SUBTYPE 0x01 ++#define ATH_OUI_VERSION 0x00 ++ ++#define WPA_OUI 0xf25000 ++#define WPA_OUI_TYPE 0x01 ++#define WPA_VERSION 1 /* current supported version */ ++ ++#define WPA_CSE_NULL 0x00 ++#define WPA_CSE_WEP40 0x01 ++#define WPA_CSE_TKIP 0x02 ++#define WPA_CSE_CCMP 0x04 ++#define WPA_CSE_WEP104 0x05 ++ ++#define WPA_ASE_NONE 0x00 ++#define WPA_ASE_8021X_UNSPEC 0x01 ++#define WPA_ASE_8021X_PSK 0x02 ++ ++#define RSN_OUI 0xac0f00 ++#define RSN_VERSION 1 /* current supported version */ ++ ++#define RSN_CSE_NULL 0x00 ++#define RSN_CSE_WEP40 0x01 ++#define RSN_CSE_TKIP 0x02 ++#define RSN_CSE_WRAP 0x03 ++#define RSN_CSE_CCMP 0x04 ++#define RSN_CSE_WEP104 0x05 ++ ++#define RSN_ASE_NONE 0x00 ++#define RSN_ASE_8021X_UNSPEC 0x01 ++#define RSN_ASE_8021X_PSK 0x02 ++ ++#define RSN_CAP_PREAUTH 0x01 ++ ++#define WMM_OUI 0xf25000 ++#define WMM_OUI_TYPE 0x02 ++#define WMM_INFO_OUI_SUBTYPE 0x00 ++#define WMM_PARAM_OUI_SUBTYPE 0x01 ++#define WMM_VERSION 1 ++ ++/* WMM stream classes */ ++#define WMM_NUM_AC 4 ++#define WMM_AC_BE 0 /* best effort */ ++#define WMM_AC_BK 1 /* background */ ++#define WMM_AC_VI 2 /* video */ ++#define WMM_AC_VO 3 /* voice */ ++ ++/* TSPEC related */ ++#define ACTION_CATEGORY_CODE_TSPEC 17 ++#define ACTION_CODE_TSPEC_ADDTS 0 ++#define ACTION_CODE_TSPEC_ADDTS_RESP 1 ++#define ACTION_CODE_TSPEC_DELTS 2 ++ ++typedef enum { ++ TSPEC_STATUS_CODE_ADMISSION_ACCEPTED = 0, ++ TSPEC_STATUS_CODE_ADDTS_INVALID_PARAMS = 0x1, ++ TSPEC_STATUS_CODE_ADDTS_REQUEST_REFUSED = 0x3, ++ TSPEC_STATUS_CODE_UNSPECIFIED_QOS_RELATED_FAILURE = 0xC8, ++ TSPEC_STATUS_CODE_REQUESTED_REFUSED_POLICY_CONFIGURATION = 0xC9, ++ TSPEC_STATUS_CODE_INSUFFCIENT_BANDWIDTH = 0xCA, ++ TSPEC_STATUS_CODE_INVALID_PARAMS = 0xCB, ++ TSPEC_STATUS_CODE_DELTS_SENT = 0x30, ++ TSPEC_STATUS_CODE_DELTS_RECV = 0x31, ++} TSPEC_STATUS_CODE; ++ ++/* ++ * WMM/802.11e Tspec Element ++ */ ++typedef PREPACK struct wmm_tspec_ie_t { ++ A_UINT8 elementId; ++ A_UINT8 len; ++ A_UINT8 oui[3]; ++ A_UINT8 ouiType; ++ A_UINT8 ouiSubType; ++ A_UINT8 version; ++ A_UINT16 tsInfo_info; ++ A_UINT8 tsInfo_reserved; ++ A_UINT16 nominalMSDU; ++ A_UINT16 maxMSDU; ++ A_UINT32 minServiceInt; ++ A_UINT32 maxServiceInt; ++ A_UINT32 inactivityInt; ++ A_UINT32 suspensionInt; ++ A_UINT32 serviceStartTime; ++ A_UINT32 minDataRate; ++ A_UINT32 meanDataRate; ++ A_UINT32 peakDataRate; ++ A_UINT32 maxBurstSize; ++ A_UINT32 delayBound; ++ A_UINT32 minPhyRate; ++ A_UINT16 sba; ++ A_UINT16 mediumTime; ++} POSTPACK WMM_TSPEC_IE; ++ ++ ++/* ++ * BEACON management packets ++ * ++ * octet timestamp[8] ++ * octet beacon interval[2] ++ * octet capability information[2] ++ * information element ++ * octet elemid ++ * octet length ++ * octet information[length] ++ */ ++ ++#define IEEE80211_BEACON_INTERVAL(beacon) \ ++ ((beacon)[8] | ((beacon)[9] << 8)) ++#define IEEE80211_BEACON_CAPABILITY(beacon) \ ++ ((beacon)[10] | ((beacon)[11] << 8)) ++ ++#define IEEE80211_CAPINFO_ESS 0x0001 ++#define IEEE80211_CAPINFO_IBSS 0x0002 ++#define IEEE80211_CAPINFO_CF_POLLABLE 0x0004 ++#define IEEE80211_CAPINFO_CF_POLLREQ 0x0008 ++#define IEEE80211_CAPINFO_PRIVACY 0x0010 ++#define IEEE80211_CAPINFO_SHORT_PREAMBLE 0x0020 ++#define IEEE80211_CAPINFO_PBCC 0x0040 ++#define IEEE80211_CAPINFO_CHNL_AGILITY 0x0080 ++/* bits 8-9 are reserved */ ++#define IEEE80211_CAPINFO_SHORT_SLOTTIME 0x0400 ++#define IEEE80211_CAPINFO_APSD 0x0800 ++/* bit 12 is reserved */ ++#define IEEE80211_CAPINFO_DSSSOFDM 0x2000 ++/* bits 14-15 are reserved */ ++ ++/* ++ * Authentication Modes ++ */ ++ ++enum ieee80211_authmode { ++ IEEE80211_AUTH_NONE = 0, ++ IEEE80211_AUTH_OPEN = 1, ++ IEEE80211_AUTH_SHARED = 2, ++ IEEE80211_AUTH_8021X = 3, ++ IEEE80211_AUTH_AUTO = 4, /* auto-select/accept */ ++ /* NB: these are used only for ioctls */ ++ IEEE80211_AUTH_WPA = 5, /* WPA/RSN w/ 802.1x */ ++ IEEE80211_AUTH_WPA_PSK = 6, /* WPA/RSN w/ PSK */ ++ IEEE80211_AUTH_WPA_CCKM = 7, /* WPA/RSN IE w/ CCKM */ ++}; ++ ++#include "athendpack.h" ++ ++#endif /* _NET80211_IEEE80211_H_ */ +diff -ruN --exclude='*.orig' --exclude='*.rej' linux-2.6.29-rc3.owrt/drivers/ar6000/include/ieee80211_ioctl.h linux-2.6.29-rc3.owrt.om/drivers/ar6000/include/ieee80211_ioctl.h +--- linux-2.6.29-rc3.owrt/drivers/ar6000/include/ieee80211_ioctl.h 1970-01-01 01:00:00.000000000 +0100 ++++ linux-2.6.29-rc3.owrt.om/drivers/ar6000/include/ieee80211_ioctl.h 2009-05-10 22:27:59.000000000 +0200 +@@ -0,0 +1,163 @@ ++/* ++ * Copyright (c) 2004-2005 Atheros Communications Inc. ++ * All rights reserved. ++ * ++ * ++ * 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; ++ * ++ * Software distributed under the License is distributed on an "AS ++ * IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or ++ * implied. See the License for the specific language governing ++ * rights and limitations under the License. ++ * ++ * ++ * ++ * ++ * $Id: //depot/sw/releases/olca2.0-GPL/host/os/linux/include/ieee80211_ioctl.h#1 $ ++ */ ++ ++#ifndef _IEEE80211_IOCTL_H_ ++#define _IEEE80211_IOCTL_H_ ++ ++#ifdef __cplusplus ++extern "C" { ++#endif ++ ++/* ++ * Extracted from the MADWIFI net80211/ieee80211_ioctl.h ++ */ ++ ++/* ++ * WPA/RSN get/set key request. Specify the key/cipher ++ * type and whether the key is to be used for sending and/or ++ * receiving. The key index should be set only when working ++ * with global keys (use IEEE80211_KEYIX_NONE for ``no index''). ++ * Otherwise a unicast/pairwise key is specified by the bssid ++ * (on a station) or mac address (on an ap). They key length ++ * must include any MIC key data; otherwise it should be no ++ more than IEEE80211_KEYBUF_SIZE. ++ */ ++struct ieee80211req_key { ++ u_int8_t ik_type; /* key/cipher type */ ++ u_int8_t ik_pad; ++ u_int16_t ik_keyix; /* key index */ ++ u_int8_t ik_keylen; /* key length in bytes */ ++ u_int8_t ik_flags; ++#define IEEE80211_KEY_XMIT 0x01 ++#define IEEE80211_KEY_RECV 0x02 ++#define IEEE80211_KEY_DEFAULT 0x80 /* default xmit key */ ++ u_int8_t ik_macaddr[IEEE80211_ADDR_LEN]; ++ u_int64_t ik_keyrsc; /* key receive sequence counter */ ++ u_int64_t ik_keytsc; /* key transmit sequence counter */ ++ u_int8_t ik_keydata[IEEE80211_KEYBUF_SIZE+IEEE80211_MICBUF_SIZE]; ++}; ++/* ++ * Delete a key either by index or address. Set the index ++ * to IEEE80211_KEYIX_NONE when deleting a unicast key. ++ */ ++struct ieee80211req_del_key { ++ u_int8_t idk_keyix; /* key index */ ++ u_int8_t idk_macaddr[IEEE80211_ADDR_LEN]; ++}; ++/* ++ * MLME state manipulation request. IEEE80211_MLME_ASSOC ++ * only makes sense when operating as a station. The other ++ * requests can be used when operating as a station or an ++ * ap (to effect a station). ++ */ ++struct ieee80211req_mlme { ++ u_int8_t im_op; /* operation to perform */ ++#define IEEE80211_MLME_ASSOC 1 /* associate station */ ++#define IEEE80211_MLME_DISASSOC 2 /* disassociate station */ ++#define IEEE80211_MLME_DEAUTH 3 /* deauthenticate station */ ++#define IEEE80211_MLME_AUTHORIZE 4 /* authorize station */ ++#define IEEE80211_MLME_UNAUTHORIZE 5 /* unauthorize station */ ++ u_int16_t im_reason; /* 802.11 reason code */ ++ u_int8_t im_macaddr[IEEE80211_ADDR_LEN]; ++}; ++ ++struct ieee80211req_addpmkid { ++ u_int8_t pi_bssid[IEEE80211_ADDR_LEN]; ++ u_int8_t pi_enable; ++ u_int8_t pi_pmkid[16]; ++}; ++ ++#define AUTH_ALG_OPEN_SYSTEM 0x01 ++#define AUTH_ALG_SHARED_KEY 0x02 ++#define AUTH_ALG_LEAP 0x04 ++ ++struct ieee80211req_authalg { ++ u_int8_t auth_alg; ++}; ++ ++/* ++ * Request to add an IE to a Management Frame ++ */ ++enum{ ++ IEEE80211_APPIE_FRAME_BEACON = 0, ++ IEEE80211_APPIE_FRAME_PROBE_REQ = 1, ++ IEEE80211_APPIE_FRAME_PROBE_RESP = 2, ++ IEEE80211_APPIE_FRAME_ASSOC_REQ = 3, ++ IEEE80211_APPIE_FRAME_ASSOC_RESP = 4, ++ IEEE80211_APPIE_NUM_OF_FRAME = 5 ++}; ++ ++/* ++ * The Maximum length of the IE that can be added to a Management frame ++ */ ++#define IEEE80211_APPIE_FRAME_MAX_LEN 78 ++ ++struct ieee80211req_getset_appiebuf { ++ u_int32_t app_frmtype; /* management frame type for which buffer is added */ ++ u_int32_t app_buflen; /*application supplied buffer length */ ++ u_int8_t app_buf[]; ++}; ++ ++/* ++ * The following definitions are used by an application to set filter ++ * for receiving management frames ++ */ ++enum { ++ IEEE80211_FILTER_TYPE_BEACON = 0x1, ++ IEEE80211_FILTER_TYPE_PROBE_REQ = 0x2, ++ IEEE80211_FILTER_TYPE_PROBE_RESP = 0x4, ++ IEEE80211_FILTER_TYPE_ASSOC_REQ = 0x8, ++ IEEE80211_FILTER_TYPE_ASSOC_RESP = 0x10, ++ IEEE80211_FILTER_TYPE_AUTH = 0x20, ++ IEEE80211_FILTER_TYPE_DEAUTH = 0x40, ++ IEEE80211_FILTER_TYPE_DISASSOC = 0x80, ++ IEEE80211_FILTER_TYPE_ALL = 0xFF /* used to check the valid filter bits */ ++}; ++ ++struct ieee80211req_set_filter { ++ u_int32_t app_filterype; /* management frame filter type */ ++}; ++ ++enum { ++ IEEE80211_PARAM_AUTHMODE = 3, /* Authentication Mode */ ++ IEEE80211_PARAM_MCASTCIPHER = 5, ++ IEEE80211_PARAM_MCASTKEYLEN = 6, /* multicast key length */ ++ IEEE80211_PARAM_UCASTCIPHER = 8, ++ IEEE80211_PARAM_UCASTKEYLEN = 9, /* unicast key length */ ++ IEEE80211_PARAM_WPA = 10, /* WPA mode (0,1,2) */ ++ IEEE80211_PARAM_ROAMING = 12, /* roaming mode */ ++ IEEE80211_PARAM_PRIVACY = 13, /* privacy invoked */ ++ IEEE80211_PARAM_COUNTERMEASURES = 14, /* WPA/TKIP countermeasures */ ++ IEEE80211_PARAM_DROPUNENCRYPTED = 15, /* discard unencrypted frames */ ++}; ++ ++/* ++ * Values for IEEE80211_PARAM_WPA ++ */ ++#define WPA_MODE_WPA1 1 ++#define WPA_MODE_WPA2 2 ++#define WPA_MODE_AUTO 3 ++#define WPA_MODE_NONE 4 ++ ++#ifdef __cplusplus ++} ++#endif ++ ++#endif /* _IEEE80211_IOCTL_H_ */ +diff -ruN --exclude='*.orig' --exclude='*.rej' linux-2.6.29-rc3.owrt/drivers/ar6000/include/ieee80211_node.h linux-2.6.29-rc3.owrt.om/drivers/ar6000/include/ieee80211_node.h +--- linux-2.6.29-rc3.owrt/drivers/ar6000/include/ieee80211_node.h 1970-01-01 01:00:00.000000000 +0100 ++++ linux-2.6.29-rc3.owrt.om/drivers/ar6000/include/ieee80211_node.h 2009-05-10 22:27:59.000000000 +0200 +@@ -0,0 +1,77 @@ ++/*- ++ * Copyright (c) 2001 Atsushi Onoe ++ * Copyright (c) 2002-2004 Sam Leffler, Errno Consulting ++ * Copyright (c) 2006 Atheros Communications, Inc. ++ * ++ * Wireless Network driver for Atheros AR6001 ++ * All rights reserved. ++ * ++ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR ++ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES ++ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. ++ * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, ++ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT ++ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, ++ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY ++ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT ++ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF ++ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ++ * ++ */ ++#ifndef _IEEE80211_NODE_H_ ++#define _IEEE80211_NODE_H_ ++ ++/* ++ * Node locking definitions. ++ */ ++#define IEEE80211_NODE_LOCK_INIT(_nt) A_MUTEX_INIT(&(_nt)->nt_nodelock) ++#define IEEE80211_NODE_LOCK_DESTROY(_nt) ++#define IEEE80211_NODE_LOCK(_nt) A_MUTEX_LOCK(&(_nt)->nt_nodelock) ++#define IEEE80211_NODE_UNLOCK(_nt) A_MUTEX_UNLOCK(&(_nt)->nt_nodelock) ++#define IEEE80211_NODE_LOCK_BH(_nt) A_MUTEX_LOCK(&(_nt)->nt_nodelock) ++#define IEEE80211_NODE_UNLOCK_BH(_nt) A_MUTEX_UNLOCK(&(_nt)->nt_nodelock) ++#define IEEE80211_NODE_LOCK_ASSERT(_nt) ++ ++/* ++ * Node reference counting definitions. ++ * ++ * ieee80211_node_initref initialize the reference count to 1 ++ * ieee80211_node_incref add a reference ++ * ieee80211_node_decref remove a reference ++ * ieee80211_node_dectestref remove a reference and return 1 if this ++ * is the last reference, otherwise 0 ++ * ieee80211_node_refcnt reference count for printing (only) ++ */ ++#define ieee80211_node_initref(_ni) ((_ni)->ni_refcnt = 1) ++#define ieee80211_node_incref(_ni) ((_ni)->ni_refcnt++) ++#define ieee80211_node_decref(_ni) ((_ni)->ni_refcnt--) ++#define ieee80211_node_dectestref(_ni) (((_ni)->ni_refcnt--) == 0) ++#define ieee80211_node_refcnt(_ni) ((_ni)->ni_refcnt) ++ ++#define IEEE80211_NODE_HASHSIZE 32 ++/* simple hash is enough for variation of macaddr */ ++#define IEEE80211_NODE_HASH(addr) \ ++ (((const A_UINT8 *)(addr))[IEEE80211_ADDR_LEN - 1] % \ ++ IEEE80211_NODE_HASHSIZE) ++ ++/* ++ * Table of ieee80211_node instances. Each ieee80211com ++ * has at least one for holding the scan candidates. ++ * When operating as an access point or in ibss mode there ++ * is a second table for associated stations or neighbors. ++ */ ++struct ieee80211_node_table { ++ void *nt_wmip; /* back reference */ ++ A_MUTEX_T nt_nodelock; /* on node table */ ++ struct bss *nt_node_first; /* information of all nodes */ ++ struct bss *nt_node_last; /* information of all nodes */ ++ struct bss *nt_hash[IEEE80211_NODE_HASHSIZE]; ++ const char *nt_name; /* for debugging */ ++ A_UINT32 nt_scangen; /* gen# for timeout scan */ ++ A_TIMER nt_inact_timer; ++ A_UINT8 isTimerArmed; /* is the node timer armed */ ++}; ++ ++#define WLAN_NODE_INACT_TIMEOUT_MSEC 10000 ++ ++#endif /* _IEEE80211_NODE_H_ */ +diff -ruN --exclude='*.orig' --exclude='*.rej' linux-2.6.29-rc3.owrt/drivers/ar6000/include/ini_dset.h linux-2.6.29-rc3.owrt.om/drivers/ar6000/include/ini_dset.h +--- linux-2.6.29-rc3.owrt/drivers/ar6000/include/ini_dset.h 1970-01-01 01:00:00.000000000 +0100 ++++ linux-2.6.29-rc3.owrt.om/drivers/ar6000/include/ini_dset.h 2009-05-10 22:27:59.000000000 +0200 +@@ -0,0 +1,40 @@ ++/* ++ * Copyright (c) 2004-2007 Atheros Communications Inc. ++ * All rights reserved. ++ * ++ * $ATH_LICENSE_HOSTSDK0_C$ ++ * ++ */ ++#ifndef _INI_DSET_H_ ++#define _INI_DSET_H_ ++ ++/* ++ * Each of these represents a WHAL INI table, which consists ++ * of an "address column" followed by 1 or more "value columns". ++ * ++ * Software uses the base WHAL_INI_DATA_ID+column to access a ++ * DataSet that holds a particular column of data. ++ */ ++typedef enum { ++ WHAL_INI_DATA_ID_NULL =0, ++ WHAL_INI_DATA_ID_MODE_SPECIFIC =1, /* 2,3 */ ++ WHAL_INI_DATA_ID_COMMON =4, /* 5 */ ++ WHAL_INI_DATA_ID_BB_RFGAIN =6, /* 7,8 */ ++ WHAL_INI_DATA_ID_ANALOG_BANK1 =9, /* 10 */ ++ WHAL_INI_DATA_ID_ANALOG_BANK2 =11, /* 12 */ ++ WHAL_INI_DATA_ID_ANALOG_BANK3 =13, /* 14, 15 */ ++ WHAL_INI_DATA_ID_ANALOG_BANK6 =16, /* 17, 18 */ ++ WHAL_INI_DATA_ID_ANALOG_BANK7 =19, /* 20 */ ++ WHAL_INI_DATA_ID_MODE_OVERRIDES =21, /* 22,23 */ ++ WHAL_INI_DATA_ID_COMMON_OVERRIDES =24, /* 25 */ ++ ++ WHAL_INI_DATA_ID_MAX =25 ++} WHAL_INI_DATA_ID; ++ ++typedef PREPACK struct { ++ A_UINT16 freqIndex; // 1 - A mode 2 - B or G mode 0 - common ++ A_UINT16 offset; ++ A_UINT32 newValue; ++} POSTPACK INI_DSET_REG_OVERRIDE; ++ ++#endif +diff -ruN --exclude='*.orig' --exclude='*.rej' linux-2.6.29-rc3.owrt/drivers/ar6000/include/regDb.h linux-2.6.29-rc3.owrt.om/drivers/ar6000/include/regDb.h +--- linux-2.6.29-rc3.owrt/drivers/ar6000/include/regDb.h 1970-01-01 01:00:00.000000000 +0100 ++++ linux-2.6.29-rc3.owrt.om/drivers/ar6000/include/regDb.h 2009-05-10 22:27:59.000000000 +0200 +@@ -0,0 +1,19 @@ ++/* ++ * Copyright (c) 2005 Atheros Communications, Inc. ++ * All rights reserved. ++ * ++ * ++ * $ATH_LICENSE_HOSTSDK0_C$ ++ * ++ * This module contains the header files for regulatory module, ++ * which include the DB schema and DB values. ++ * $Id: ++ */ ++ ++#ifndef __REG_DB_H__ ++#define __REG_DB_H__ ++ ++#include "./regulatory/reg_dbschema.h" ++#include "./regulatory/reg_dbvalues.h" ++ ++#endif /* __REG_DB_H__ */ +diff -ruN --exclude='*.orig' --exclude='*.rej' linux-2.6.29-rc3.owrt/drivers/ar6000/include/regdump.h linux-2.6.29-rc3.owrt.om/drivers/ar6000/include/regdump.h +--- linux-2.6.29-rc3.owrt/drivers/ar6000/include/regdump.h 1970-01-01 01:00:00.000000000 +0100 ++++ linux-2.6.29-rc3.owrt.om/drivers/ar6000/include/regdump.h 2009-05-10 22:27:59.000000000 +0200 +@@ -0,0 +1,33 @@ ++#ifndef __REGDUMP_H__ ++#define __REGDUMP_H__ ++/* ++ * Copyright (c) 2004-2007 Atheros Communications Inc. ++ * All rights reserved. ++ * ++ * $ATH_LICENSE_HOSTSDK0_C$ ++ * ++ */ ++#if defined(AR6001) ++#include "AR6001/AR6001_regdump.h" ++#endif ++#if defined(AR6002) ++#include "AR6002/AR6002_regdump.h" ++#endif ++ ++#if !defined(__ASSEMBLER__) ++/* ++ * Target CPU state at the time of failure is reflected ++ * in a register dump, which the Host can fetch through ++ * the diagnostic window. ++ */ ++struct register_dump_s { ++ A_UINT32 target_id; /* Target ID */ ++ A_UINT32 assline; /* Line number (if assertion failure) */ ++ A_UINT32 pc; /* Program Counter at time of exception */ ++ A_UINT32 badvaddr; /* Virtual address causing exception */ ++ CPU_exception_frame_t exc_frame; /* CPU-specific exception info */ ++ ++ /* Could copy top of stack here, too.... */ ++}; ++#endif /* __ASSEMBLER__ */ ++#endif /* __REGDUMP_H__ */ +diff -ruN --exclude='*.orig' --exclude='*.rej' linux-2.6.29-rc3.owrt/drivers/ar6000/include/targaddrs.h linux-2.6.29-rc3.owrt.om/drivers/ar6000/include/targaddrs.h +--- linux-2.6.29-rc3.owrt/drivers/ar6000/include/targaddrs.h 1970-01-01 01:00:00.000000000 +0100 ++++ linux-2.6.29-rc3.owrt.om/drivers/ar6000/include/targaddrs.h 2009-05-10 22:27:59.000000000 +0200 +@@ -0,0 +1,158 @@ ++/* ++ * Copyright (c) 2004-2007 Atheros Communications Inc. ++ * All rights reserved. ++ * ++ * $ATH_LICENSE_HOSTSDK0_C$ ++ * ++ */ ++ ++#ifndef __TARGADDRS_H__ ++#define __TARGADDRS_H__ ++#if defined(AR6001) ++#include "AR6001/addrs.h" ++#endif ++#if defined(AR6002) ++#include "AR6002/addrs.h" ++#endif ++ ++/* ++ * AR6K option bits, to enable/disable various features. ++ * By default, all option bits are 0. ++ * These bits can be set in LOCAL_SCRATCH register 0. ++ */ ++#define AR6K_OPTION_BMI_DISABLE 0x01 /* Disable BMI comm with Host */ ++#define AR6K_OPTION_SERIAL_ENABLE 0x02 /* Enable serial port msgs */ ++#define AR6K_OPTION_WDT_DISABLE 0x04 /* WatchDog Timer override */ ++#define AR6K_OPTION_SLEEP_DISABLE 0x08 /* Disable system sleep */ ++#define AR6K_OPTION_STOP_BOOT 0x10 /* Stop boot processes (for ATE) */ ++#define AR6K_OPTION_ENABLE_NOANI 0x20 /* Operate without ANI */ ++#define AR6K_OPTION_DSET_DISABLE 0x40 /* Ignore DataSets */ ++#define AR6K_OPTION_IGNORE_FLASH 0x80 /* Ignore flash during bootup */ ++ ++/* ++ * xxx_HOST_INTEREST_ADDRESS is the address in Target RAM of the ++ * host_interest structure. It must match the address of the _host_interest ++ * symbol (see linker script). ++ * ++ * Host Interest is shared between Host and Target in order to coordinate ++ * between the two, and is intended to remain constant (with additions only ++ * at the end) across software releases. ++ */ ++#define AR6001_HOST_INTEREST_ADDRESS 0x80000600 ++#define AR6002_HOST_INTEREST_ADDRESS 0x00500400 ++ ++#define HOST_INTEREST_MAX_SIZE 0x100 ++ ++#if !defined(__ASSEMBLER__) ++struct register_dump_s; ++struct dbglog_hdr_s; ++ ++/* ++ * These are items that the Host may need to access ++ * via BMI or via the Diagnostic Window. The position ++ * of items in this structure must remain constant ++ * across firmware revisions! ++ * ++ * Types for each item must be fixed size across ++ * target and host platforms. ++ * ++ * More items may be added at the end. ++ */ ++struct host_interest_s { ++ /* ++ * Pointer to application-defined area, if any. ++ * Set by Target application during startup. ++ */ ++ A_UINT32 hi_app_host_interest; /* 0x00 */ ++ ++ /* Pointer to register dump area, valid after Target crash. */ ++ A_UINT32 hi_failure_state; /* 0x04 */ ++ ++ /* Pointer to debug logging header */ ++ A_UINT32 hi_dbglog_hdr; /* 0x08 */ ++ ++ /* Indicates whether or not flash is present on Target. ++ * NB: flash_is_present indicator is here not just ++ * because it might be of interest to the Host; but ++ * also because it's set early on by Target's startup ++ * asm code and we need it to have a special RAM address ++ * so that it doesn't get reinitialized with the rest ++ * of data. ++ */ ++ A_UINT32 hi_flash_is_present; /* 0x0c */ ++ ++ /* ++ * General-purpose flag bits, similar to AR6000_OPTION_* flags. ++ * Can be used by application rather than by OS. ++ */ ++ A_UINT32 hi_option_flag; /* 0x10 */ ++ ++ /* ++ * Boolean that determines whether or not to ++ * display messages on the serial port. ++ */ ++ A_UINT32 hi_serial_enable; /* 0x14 */ ++ ++ /* Start address of Flash DataSet index, if any */ ++ A_UINT32 hi_dset_list_head; /* 0x18 */ ++ ++ /* Override Target application start address */ ++ A_UINT32 hi_app_start; /* 0x1c */ ++ ++ /* Clock and voltage tuning */ ++ A_UINT32 hi_skip_clock_init; /* 0x20 */ ++ A_UINT32 hi_core_clock_setting; /* 0x24 */ ++ A_UINT32 hi_cpu_clock_setting; /* 0x28 */ ++ A_UINT32 hi_system_sleep_setting; /* 0x2c */ ++ A_UINT32 hi_xtal_control_setting; /* 0x30 */ ++ A_UINT32 hi_pll_ctrl_setting_24ghz; /* 0x34 */ ++ A_UINT32 hi_pll_ctrl_setting_5ghz; /* 0x38 */ ++ A_UINT32 hi_ref_voltage_trim_setting; /* 0x3c */ ++ A_UINT32 hi_clock_info; /* 0x40 */ ++ ++ /* ++ * Flash configuration overrides, used only ++ * when firmware is not executing from flash. ++ * (When using flash, modify the global variables ++ * with equivalent names.) ++ */ ++ A_UINT32 hi_bank0_addr_value; /* 0x44 */ ++ A_UINT32 hi_bank0_read_value; /* 0x48 */ ++ A_UINT32 hi_bank0_write_value; /* 0x4c */ ++ A_UINT32 hi_bank0_config_value; /* 0x50 */ ++ ++ /* Pointer to Board Data */ ++ A_UINT32 hi_board_data; /* 0x54 */ ++ A_UINT32 hi_board_data_initialized; /* 0x58 */ ++ ++ A_UINT32 hi_dset_RAM_index_table; /* 0x5c */ ++ ++ A_UINT32 hi_desired_baud_rate; /* 0x60 */ ++ A_UINT32 hi_dbglog_config; /* 0x64 */ ++ A_UINT32 hi_end_RAM_reserve_sz; /* 0x68 */ ++ A_UINT32 hi_mbox_io_block_sz; /* 0x6c */ ++ ++ A_UINT32 hi_num_bpatch_streams; /* 0x70 */ ++ A_UINT32 hi_mbox_isr_yield_limit; /* 0x74 */ ++ ++ A_UINT32 hi_refclk_hz; /* 0x78 */ ++}; ++ ++/* Bits defined in hi_option_flag */ ++#define HI_OPTION_TIMER_WAR 1 /* not really used */ ++ ++/* ++ * Intended for use by Host software, this macro returns the Target RAM ++ * address of any item in the host_interest structure. ++ * Example: target_addr = AR6001_HOST_INTEREST_ITEM_ADDRESS(hi_board_data); ++ */ ++#define AR6001_HOST_INTEREST_ITEM_ADDRESS(item) \ ++ ((A_UINT32)&((((struct host_interest_s *)(AR6001_HOST_INTEREST_ADDRESS))->item))) ++ ++#define AR6002_HOST_INTEREST_ITEM_ADDRESS(item) \ ++ ((A_UINT32)&((((struct host_interest_s *)(AR6002_HOST_INTEREST_ADDRESS))->item))) ++ ++ ++#endif /* !__ASSEMBLER__ */ ++ ++#endif /* __TARGADDRS_H__ */ +diff -ruN --exclude='*.orig' --exclude='*.rej' linux-2.6.29-rc3.owrt/drivers/ar6000/include/testcmd.h linux-2.6.29-rc3.owrt.om/drivers/ar6000/include/testcmd.h +--- linux-2.6.29-rc3.owrt/drivers/ar6000/include/testcmd.h 1970-01-01 01:00:00.000000000 +0100 ++++ linux-2.6.29-rc3.owrt.om/drivers/ar6000/include/testcmd.h 2009-05-10 22:27:59.000000000 +0200 +@@ -0,0 +1,144 @@ ++/* ++ * Copyright (c) 2004-2005 Atheros Communications Inc. ++ * All rights reserved. ++ * ++ * ++ * $ATH_LICENSE_HOSTSDK0_C$ ++ * ++ */ ++ ++#ifndef TESTCMD_H_ ++#define TESTCMD_H_ ++ ++#ifdef __cplusplus ++extern "C" { ++#endif ++ ++typedef enum { ++ ZEROES_PATTERN = 0, ++ ONES_PATTERN, ++ REPEATING_10, ++ PN7_PATTERN, ++ PN9_PATTERN, ++ PN15_PATTERN ++}TX_DATA_PATTERN; ++ ++/* Continous tx ++ mode : TCMD_CONT_TX_OFF - Disabling continous tx ++ TCMD_CONT_TX_SINE - Enable continuous unmodulated tx ++ TCMD_CONT_TX_FRAME- Enable continuous modulated tx ++ freq : Channel freq in Mhz. (e.g 2412 for channel 1 in 11 g) ++dataRate: 0 - 1 Mbps ++ 1 - 2 Mbps ++ 2 - 5.5 Mbps ++ 3 - 11 Mbps ++ 4 - 6 Mbps ++ 5 - 9 Mbps ++ 6 - 12 Mbps ++ 7 - 18 Mbps ++ 8 - 24 Mbps ++ 9 - 36 Mbps ++ 10 - 28 Mbps ++ 11 - 54 Mbps ++ txPwr: Tx power in dBm[5 -11] for unmod Tx, [5-14] for mod Tx ++antenna: 1 - one antenna ++ 2 - two antenna ++Note : Enable/disable continuous tx test cmd works only when target is awake. ++*/ ++ ++typedef enum { ++ TCMD_CONT_TX_OFF = 0, ++ TCMD_CONT_TX_SINE, ++ TCMD_CONT_TX_FRAME, ++ TCMD_CONT_TX_TX99, ++ TCMD_CONT_TX_TX100 ++} TCMD_CONT_TX_MODE; ++ ++typedef PREPACK struct { ++ A_UINT32 testCmdId; ++ A_UINT32 mode; ++ A_UINT32 freq; ++ A_UINT32 dataRate; ++ A_INT32 txPwr; ++ A_UINT32 antenna; ++ A_UINT32 enANI; ++ A_UINT32 scramblerOff; ++ A_UINT32 aifsn; ++ A_UINT16 pktSz; ++ A_UINT16 txPattern; ++} POSTPACK TCMD_CONT_TX; ++ ++#define TCMD_TXPATTERN_ZERONE 0x1 ++#define TCMD_TXPATTERN_ZERONE_DIS_SCRAMBLE 0x2 ++ ++/* Continuous Rx ++ act: TCMD_CONT_RX_PROMIS - promiscuous mode (accept all incoming frames) ++ TCMD_CONT_RX_FILTER - filter mode (accept only frames with dest ++ address equal specified ++ mac address (set via act =3) ++ TCMD_CONT_RX_REPORT off mode (disable cont rx mode and get the ++ report from the last cont ++ Rx test) ++ ++ TCMD_CONT_RX_SETMAC - set MacAddr mode (sets the MAC address for the ++ target. This Overrides ++ the default MAC address.) ++ ++*/ ++typedef enum { ++ TCMD_CONT_RX_PROMIS =0, ++ TCMD_CONT_RX_FILTER, ++ TCMD_CONT_RX_REPORT, ++ TCMD_CONT_RX_SETMAC ++} TCMD_CONT_RX_ACT; ++ ++typedef PREPACK struct { ++ A_UINT32 testCmdId; ++ A_UINT32 act; ++ A_UINT32 enANI; ++ PREPACK union { ++ struct PREPACK TCMD_CONT_RX_PARA { ++ A_UINT32 freq; ++ A_UINT32 antenna; ++ } POSTPACK para; ++ struct PREPACK TCMD_CONT_RX_REPORT { ++ A_UINT32 totalPkt; ++ A_INT32 rssiInDBm; ++ } POSTPACK report; ++ struct PREPACK TCMD_CONT_RX_MAC { ++ A_UCHAR addr[ATH_MAC_LEN]; ++ } POSTPACK mac; ++ } POSTPACK u; ++} POSTPACK TCMD_CONT_RX; ++ ++/* Force sleep/wake test cmd ++ mode: TCMD_PM_WAKEUP - Wakeup the target ++ TCMD_PM_SLEEP - Force the target to sleep. ++ */ ++typedef enum { ++ TCMD_PM_WAKEUP = 1, /* be consistent with target */ ++ TCMD_PM_SLEEP ++} TCMD_PM_MODE; ++ ++typedef PREPACK struct { ++ A_UINT32 testCmdId; ++ A_UINT32 mode; ++} POSTPACK TCMD_PM; ++ ++typedef enum{ ++ TCMD_CONT_TX_ID, ++ TCMD_CONT_RX_ID, ++ TCMD_PM_ID ++ } TCMD_ID; ++ ++typedef PREPACK union { ++ TCMD_CONT_TX contTx; ++ TCMD_CONT_RX contRx; ++ TCMD_PM pm ; ++} POSTPACK TEST_CMD; ++ ++#ifdef __cplusplus ++} ++#endif ++ ++#endif /* TESTCMD_H_ */ +diff -ruN --exclude='*.orig' --exclude='*.rej' linux-2.6.29-rc3.owrt/drivers/ar6000/include/wlan_api.h linux-2.6.29-rc3.owrt.om/drivers/ar6000/include/wlan_api.h +--- linux-2.6.29-rc3.owrt/drivers/ar6000/include/wlan_api.h 1970-01-01 01:00:00.000000000 +0100 ++++ linux-2.6.29-rc3.owrt.om/drivers/ar6000/include/wlan_api.h 2009-05-10 22:27:59.000000000 +0200 +@@ -0,0 +1,101 @@ ++#ifndef _HOST_WLAN_API_H_ ++#define _HOST_WLAN_API_H_ ++/* ++ * Copyright (c) 2004-2005 Atheros Communications Inc. ++ * All rights reserved. ++ * ++ * This file contains the API for the host wlan module ++ * ++ * $Id: //depot/sw/releases/olca2.0-GPL/host/include/wlan_api.h#1 $ ++ * ++ * ++ * 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; ++ * ++ * Software distributed under the License is distributed on an "AS ++ * IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or ++ * implied. See the License for the specific language governing ++ * rights and limitations under the License. ++ * ++ * ++ * ++ */ ++ ++#ifdef __cplusplus ++extern "C" { ++#endif ++ ++struct ieee80211_node_table; ++struct ieee80211_frame; ++ ++struct ieee80211_common_ie { ++ A_UINT16 ie_chan; ++ A_UINT8 *ie_tstamp; ++ A_UINT8 *ie_ssid; ++ A_UINT8 *ie_rates; ++ A_UINT8 *ie_xrates; ++ A_UINT8 *ie_country; ++ A_UINT8 *ie_wpa; ++ A_UINT8 *ie_rsn; ++ A_UINT8 *ie_wmm; ++ A_UINT8 *ie_ath; ++ A_UINT16 ie_capInfo; ++ A_UINT16 ie_beaconInt; ++ A_UINT8 *ie_tim; ++ A_UINT8 *ie_chswitch; ++ A_UINT8 ie_erp; ++ A_UINT8 *ie_wsc; ++}; ++ ++typedef struct bss { ++ A_UINT8 ni_macaddr[6]; ++ A_UINT8 ni_snr; ++ A_INT16 ni_rssi; ++ struct bss *ni_list_next; ++ struct bss *ni_list_prev; ++ struct bss *ni_hash_next; ++ struct bss *ni_hash_prev; ++ struct ieee80211_common_ie ni_cie; ++ A_UINT8 *ni_buf; ++ struct ieee80211_node_table *ni_table; ++ A_UINT32 ni_refcnt; ++ int ni_scangen; ++ A_UINT32 ni_tstamp; ++} bss_t; ++ ++typedef void wlan_node_iter_func(void *arg, bss_t *); ++ ++bss_t *wlan_node_alloc(struct ieee80211_node_table *nt, int wh_size); ++void wlan_node_free(bss_t *ni); ++void wlan_setup_node(struct ieee80211_node_table *nt, bss_t *ni, ++ const A_UINT8 *macaddr); ++bss_t *wlan_find_node(struct ieee80211_node_table *nt, const A_UINT8 *macaddr); ++void wlan_node_reclaim(struct ieee80211_node_table *nt, bss_t *ni); ++void wlan_free_allnodes(struct ieee80211_node_table *nt); ++void wlan_iterate_nodes(struct ieee80211_node_table *nt, wlan_node_iter_func *f, ++ void *arg); ++ ++void wlan_node_table_init(void *wmip, struct ieee80211_node_table *nt); ++void wlan_node_table_reset(struct ieee80211_node_table *nt); ++void wlan_node_table_cleanup(struct ieee80211_node_table *nt); ++ ++A_STATUS wlan_parse_beacon(A_UINT8 *buf, int framelen, ++ struct ieee80211_common_ie *cie); ++ ++A_UINT16 wlan_ieee2freq(int chan); ++A_UINT32 wlan_freq2ieee(A_UINT16 freq); ++ ++ ++bss_t * ++wlan_find_Ssidnode (struct ieee80211_node_table *nt, A_UCHAR *pSsid, ++ A_UINT32 ssidLength, A_BOOL bIsWPA2); ++ ++void ++wlan_node_return (struct ieee80211_node_table *nt, bss_t *ni); ++ ++#ifdef __cplusplus ++} ++#endif ++ ++#endif /* _HOST_WLAN_API_H_ */ +diff -ruN --exclude='*.orig' --exclude='*.rej' linux-2.6.29-rc3.owrt/drivers/ar6000/include/wlan_dset.h linux-2.6.29-rc3.owrt.om/drivers/ar6000/include/wlan_dset.h +--- linux-2.6.29-rc3.owrt/drivers/ar6000/include/wlan_dset.h 1970-01-01 01:00:00.000000000 +0100 ++++ linux-2.6.29-rc3.owrt.om/drivers/ar6000/include/wlan_dset.h 2009-05-10 22:27:59.000000000 +0200 +@@ -0,0 +1,20 @@ ++/* ++ * Copyright (c) 2007 Atheros Communications, Inc. ++ * All rights reserved. ++ * ++ * ++ * $ATH_LICENSE_HOSTSDK0_C$ ++ * ++ */ ++ ++#ifndef __WLAN_DSET_H__ ++#define __WKAN_DSET_H__ ++ ++typedef PREPACK struct wow_config_dset { ++ ++ A_UINT8 valid_dset; ++ A_UINT8 gpio_enable; ++ A_UINT16 gpio_pin; ++} POSTPACK WOW_CONFIG_DSET; ++ ++#endif +diff -ruN --exclude='*.orig' --exclude='*.rej' linux-2.6.29-rc3.owrt/drivers/ar6000/include/wmi_api.h linux-2.6.29-rc3.owrt.om/drivers/ar6000/include/wmi_api.h +--- linux-2.6.29-rc3.owrt/drivers/ar6000/include/wmi_api.h 1970-01-01 01:00:00.000000000 +0100 ++++ linux-2.6.29-rc3.owrt.om/drivers/ar6000/include/wmi_api.h 2009-05-10 22:27:59.000000000 +0200 +@@ -0,0 +1,260 @@ ++#ifndef _WMI_API_H_ ++#define _WMI_API_H_ ++/* ++ * Copyright (c) 2004-2006 Atheros Communications Inc. ++ * All rights reserved. ++ * ++ * This file contains the definitions for the Wireless Module Interface (WMI). ++ * ++ * $Id: //depot/sw/releases/olca2.0-GPL/host/include/wmi_api.h#2 $ ++ * ++ * ++ * 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; ++ * ++ * Software distributed under the License is distributed on an "AS ++ * IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or ++ * implied. See the License for the specific language governing ++ * rights and limitations under the License. ++ * ++ * ++ * ++ */ ++ ++#ifdef __cplusplus ++extern "C" { ++#endif ++ ++/* ++ * IP QoS Field definitions according to 802.1p ++ */ ++#define BEST_EFFORT_PRI 0 ++#define BACKGROUND_PRI 1 ++#define EXCELLENT_EFFORT_PRI 3 ++#define CONTROLLED_LOAD_PRI 4 ++#define VIDEO_PRI 5 ++#define VOICE_PRI 6 ++#define NETWORK_CONTROL_PRI 7 ++#define MAX_NUM_PRI 8 ++ ++#define UNDEFINED_PRI (0xff) ++ ++/* simple mapping of IP TOS field to a WMI priority stream ++ * this mapping was taken from the original linux driver implementation ++ * The operation maps the following ++ * ++ * */ ++#define IP_TOS_TO_WMI_PRI(tos) \ ++ ((WMI_PRI_STREAM_ID)(((tos) >> 1) & 0x03)) ++ ++#define WMI_IMPLICIT_PSTREAM_INACTIVITY_INT 5000 /* 5 seconds */ ++ ++ ++struct wmi_t; ++ ++void *wmi_init(void *devt); ++ ++void wmi_qos_state_init(struct wmi_t *wmip); ++void wmi_shutdown(struct wmi_t *wmip); ++A_UINT16 wmi_get_mapped_qos_queue(struct wmi_t *, A_UINT8); ++A_STATUS wmi_dix_2_dot3(struct wmi_t *wmip, void *osbuf); ++A_STATUS wmi_data_hdr_add(struct wmi_t *wmip, void *osbuf, A_UINT8 msgType); ++A_STATUS wmi_dot3_2_dix(struct wmi_t *wmip, void *osbuf); ++A_STATUS wmi_data_hdr_remove(struct wmi_t *wmip, void *osbuf); ++A_STATUS wmi_syncpoint(struct wmi_t *wmip); ++A_STATUS wmi_syncpoint_reset(struct wmi_t *wmip); ++WMI_PRI_STREAM_ID wmi_get_stream_id(struct wmi_t *wmip, A_UINT8 trafficClass); ++A_UINT8 wmi_implicit_create_pstream(struct wmi_t *wmip, void *osbuf, A_UINT8 dir, A_UINT8 up); ++ ++A_STATUS wmi_control_rx(struct wmi_t *wmip, void *osbuf); ++void wmi_iterate_nodes(struct wmi_t *wmip, wlan_node_iter_func *f, void *arg); ++void wmi_free_allnodes(struct wmi_t *wmip); ++bss_t *wmi_find_node(struct wmi_t *wmip, const A_UINT8 *macaddr); ++ ++ ++typedef enum { ++ NO_SYNC_WMIFLAG = 0, ++ SYNC_BEFORE_WMIFLAG, /* transmit all queued data before cmd */ ++ SYNC_AFTER_WMIFLAG, /* any new data waits until cmd execs */ ++ SYNC_BOTH_WMIFLAG, ++ END_WMIFLAG /* end marker */ ++} WMI_SYNC_FLAG; ++ ++A_STATUS wmi_cmd_send(struct wmi_t *wmip, void *osbuf, WMI_COMMAND_ID cmdId, ++ WMI_SYNC_FLAG flag); ++A_STATUS wmi_connect_cmd(struct wmi_t *wmip, ++ NETWORK_TYPE netType, ++ DOT11_AUTH_MODE dot11AuthMode, ++ AUTH_MODE authMode, ++ CRYPTO_TYPE pairwiseCrypto, ++ A_UINT8 pairwiseCryptoLen, ++ CRYPTO_TYPE groupCrypto, ++ A_UINT8 groupCryptoLen, ++ int ssidLength, ++ A_UCHAR *ssid, ++ A_UINT8 *bssid, ++ A_UINT16 channel, ++ A_UINT32 ctrl_flags); ++A_STATUS wmi_reconnect_cmd(struct wmi_t *wmip, ++ A_UINT8 *bssid, ++ A_UINT16 channel); ++A_STATUS wmi_disconnect_cmd(struct wmi_t *wmip); ++A_STATUS wmi_getrev_cmd(struct wmi_t *wmip); ++A_STATUS wmi_startscan_cmd(struct wmi_t *wmip, WMI_SCAN_TYPE scanType, ++ A_BOOL forceFgScan, A_BOOL isLegacy, ++ A_UINT32 homeDwellTime, A_UINT32 forceScanInterval); ++A_STATUS wmi_scanparams_cmd(struct wmi_t *wmip, A_UINT16 fg_start_sec, ++ A_UINT16 fg_end_sec, A_UINT16 bg_sec, ++ A_UINT16 minact_chdw_msec, ++ A_UINT16 maxact_chdw_msec, A_UINT16 pas_chdw_msec, ++ A_UINT8 shScanRatio, A_UINT8 scanCtrlFlags, ++ A_UINT32 max_dfsch_act_time); ++A_STATUS wmi_bssfilter_cmd(struct wmi_t *wmip, A_UINT8 filter, A_UINT32 ieMask); ++A_STATUS wmi_probedSsid_cmd(struct wmi_t *wmip, A_UINT8 index, A_UINT8 flag, ++ A_UINT8 ssidLength, A_UCHAR *ssid); ++A_STATUS wmi_listeninterval_cmd(struct wmi_t *wmip, A_UINT16 listenInterval, A_UINT16 listenBeacons); ++A_STATUS wmi_bmisstime_cmd(struct wmi_t *wmip, A_UINT16 bmisstime, A_UINT16 bmissbeacons); ++A_STATUS wmi_associnfo_cmd(struct wmi_t *wmip, A_UINT8 ieType, ++ A_UINT8 ieLen, A_UINT8 *ieInfo); ++A_STATUS wmi_powermode_cmd(struct wmi_t *wmip, A_UINT8 powerMode); ++A_STATUS wmi_ibsspmcaps_cmd(struct wmi_t *wmip, A_UINT8 pmEnable, A_UINT8 ttl, ++ A_UINT16 atim_windows, A_UINT16 timeout_value); ++A_STATUS wmi_pmparams_cmd(struct wmi_t *wmip, A_UINT16 idlePeriod, ++ A_UINT16 psPollNum, A_UINT16 dtimPolicy); ++A_STATUS wmi_disctimeout_cmd(struct wmi_t *wmip, A_UINT8 timeout); ++A_STATUS wmi_sync_cmd(struct wmi_t *wmip, A_UINT8 syncNumber); ++A_STATUS wmi_create_pstream_cmd(struct wmi_t *wmip, WMI_CREATE_PSTREAM_CMD *pstream); ++A_STATUS wmi_delete_pstream_cmd(struct wmi_t *wmip, A_UINT8 trafficClass, A_UINT8 streamID); ++A_STATUS wmi_set_bitrate_cmd(struct wmi_t *wmip, A_INT32 rate); ++A_STATUS wmi_get_bitrate_cmd(struct wmi_t *wmip); ++A_INT8 wmi_validate_bitrate(struct wmi_t *wmip, A_INT32 rate); ++A_STATUS wmi_get_regDomain_cmd(struct wmi_t *wmip); ++A_STATUS wmi_get_channelList_cmd(struct wmi_t *wmip); ++A_STATUS wmi_set_channelParams_cmd(struct wmi_t *wmip, A_UINT8 scanParam, ++ WMI_PHY_MODE mode, A_INT8 numChan, ++ A_UINT16 *channelList); ++ ++A_STATUS wmi_set_snr_threshold_params(struct wmi_t *wmip, ++ WMI_SNR_THRESHOLD_PARAMS_CMD *snrCmd); ++A_STATUS wmi_set_rssi_threshold_params(struct wmi_t *wmip, ++ WMI_RSSI_THRESHOLD_PARAMS_CMD *rssiCmd); ++A_STATUS wmi_clr_rssi_snr(struct wmi_t *wmip); ++A_STATUS wmi_set_lq_threshold_params(struct wmi_t *wmip, ++ WMI_LQ_THRESHOLD_PARAMS_CMD *lqCmd); ++A_STATUS wmi_set_rts_cmd(struct wmi_t *wmip, A_UINT16 threshold); ++A_STATUS wmi_set_lpreamble_cmd(struct wmi_t *wmip, A_UINT8 status); ++ ++A_STATUS wmi_set_error_report_bitmask(struct wmi_t *wmip, A_UINT32 bitmask); ++ ++A_STATUS wmi_get_challenge_resp_cmd(struct wmi_t *wmip, A_UINT32 cookie, ++ A_UINT32 source); ++A_STATUS wmi_config_debug_module_cmd(struct wmi_t *wmip, A_UINT16 mmask, ++ A_UINT16 tsr, A_BOOL rep, A_UINT16 size, ++ A_UINT32 valid); ++A_STATUS wmi_get_stats_cmd(struct wmi_t *wmip); ++A_STATUS wmi_addKey_cmd(struct wmi_t *wmip, A_UINT8 keyIndex, ++ CRYPTO_TYPE keyType, A_UINT8 keyUsage, ++ A_UINT8 keyLength,A_UINT8 *keyRSC, ++ A_UINT8 *keyMaterial, A_UINT8 key_op_ctrl, ++ WMI_SYNC_FLAG sync_flag); ++A_STATUS wmi_add_krk_cmd(struct wmi_t *wmip, A_UINT8 *krk); ++A_STATUS wmi_delete_krk_cmd(struct wmi_t *wmip); ++A_STATUS wmi_deleteKey_cmd(struct wmi_t *wmip, A_UINT8 keyIndex); ++A_STATUS wmi_set_akmp_params_cmd(struct wmi_t *wmip, ++ WMI_SET_AKMP_PARAMS_CMD *akmpParams); ++A_STATUS wmi_get_pmkid_list_cmd(struct wmi_t *wmip); ++A_STATUS wmi_set_pmkid_list_cmd(struct wmi_t *wmip, ++ WMI_SET_PMKID_LIST_CMD *pmkInfo); ++A_STATUS wmi_set_txPwr_cmd(struct wmi_t *wmip, A_UINT8 dbM); ++A_STATUS wmi_get_txPwr_cmd(struct wmi_t *wmip); ++A_STATUS wmi_switch_radio(struct wmi_t *wmip, A_UINT8 on); ++A_STATUS wmi_addBadAp_cmd(struct wmi_t *wmip, A_UINT8 apIndex, A_UINT8 *bssid); ++A_STATUS wmi_deleteBadAp_cmd(struct wmi_t *wmip, A_UINT8 apIndex); ++A_STATUS wmi_set_tkip_countermeasures_cmd(struct wmi_t *wmip, A_BOOL en); ++A_STATUS wmi_setPmkid_cmd(struct wmi_t *wmip, A_UINT8 *bssid, A_UINT8 *pmkId, ++ A_BOOL set); ++A_STATUS wmi_set_access_params_cmd(struct wmi_t *wmip, A_UINT16 txop, ++ A_UINT8 eCWmin, A_UINT8 eCWmax, ++ A_UINT8 aifsn); ++A_STATUS wmi_set_retry_limits_cmd(struct wmi_t *wmip, A_UINT8 frameType, ++ A_UINT8 trafficClass, A_UINT8 maxRetries, ++ A_UINT8 enableNotify); ++ ++void wmi_get_current_bssid(struct wmi_t *wmip, A_UINT8 *bssid); ++ ++A_STATUS wmi_get_roam_tbl_cmd(struct wmi_t *wmip); ++A_STATUS wmi_get_roam_data_cmd(struct wmi_t *wmip, A_UINT8 roamDataType); ++A_STATUS wmi_set_roam_ctrl_cmd(struct wmi_t *wmip, WMI_SET_ROAM_CTRL_CMD *p, ++ A_UINT8 size); ++A_STATUS wmi_set_powersave_timers_cmd(struct wmi_t *wmip, ++ WMI_POWERSAVE_TIMERS_POLICY_CMD *pCmd, ++ A_UINT8 size); ++ ++A_STATUS wmi_set_opt_mode_cmd(struct wmi_t *wmip, A_UINT8 optMode); ++A_STATUS wmi_opt_tx_frame_cmd(struct wmi_t *wmip, ++ A_UINT8 frmType, ++ A_UINT8 *dstMacAddr, ++ A_UINT8 *bssid, ++ A_UINT16 optIEDataLen, ++ A_UINT8 *optIEData); ++ ++A_STATUS wmi_set_adhoc_bconIntvl_cmd(struct wmi_t *wmip, A_UINT16 intvl); ++A_STATUS wmi_set_voice_pkt_size_cmd(struct wmi_t *wmip, A_UINT16 voicePktSize); ++A_STATUS wmi_set_max_sp_len_cmd(struct wmi_t *wmip, A_UINT8 maxSpLen); ++A_UINT8 convert_userPriority_to_trafficClass(A_UINT8 userPriority); ++A_UINT8 wmi_get_power_mode_cmd(struct wmi_t *wmip); ++A_STATUS wmi_verify_tspec_params(WMI_CREATE_PSTREAM_CMD *pCmd, A_BOOL tspecCompliance); ++ ++#ifdef CONFIG_HOST_TCMD_SUPPORT ++A_STATUS wmi_test_cmd(struct wmi_t *wmip, A_UINT8 *buf, A_UINT32 len); ++#endif ++ ++A_STATUS wmi_set_bt_status_cmd(struct wmi_t *wmip, A_UINT8 streamType, A_UINT8 status); ++A_STATUS wmi_set_bt_params_cmd(struct wmi_t *wmip, WMI_SET_BT_PARAMS_CMD* cmd); ++ ++ ++/* ++ * This function is used to configure the fix rates mask to the target. ++ */ ++A_STATUS wmi_set_fixrates_cmd(struct wmi_t *wmip, A_INT16 fixRatesMask); ++A_STATUS wmi_get_ratemask_cmd(struct wmi_t *wmip); ++ ++A_STATUS wmi_set_authmode_cmd(struct wmi_t *wmip, A_UINT8 mode); ++ ++A_STATUS wmi_set_reassocmode_cmd(struct wmi_t *wmip, A_UINT8 mode); ++ ++A_STATUS wmi_set_wmm_cmd(struct wmi_t *wmip, WMI_WMM_STATUS status); ++A_STATUS wmi_set_wmm_txop(struct wmi_t *wmip, WMI_TXOP_CFG txEnable); ++ ++A_STATUS wmi_get_keepalive_configured(struct wmi_t *wmip); ++A_UINT8 wmi_get_keepalive_cmd(struct wmi_t *wmip); ++A_STATUS wmi_set_keepalive_cmd(struct wmi_t *wmip, A_UINT8 keepaliveInterval); ++ ++A_STATUS wmi_set_appie_cmd(struct wmi_t *wmip, A_UINT8 mgmtFrmType, ++ A_UINT8 ieLen,A_UINT8 *ieInfo); ++ ++A_STATUS wmi_set_halparam_cmd(struct wmi_t *wmip, A_UINT8 *cmd, A_UINT16 dataLen); ++A_INT32 wmi_get_rate(A_INT8 rateindex); ++ ++/*Wake on Wireless WMI commands*/ ++A_STATUS wmi_set_host_sleep_mode_cmd(struct wmi_t *wmip, WMI_SET_HOST_SLEEP_MODE_CMD *cmd); ++A_STATUS wmi_set_wow_mode_cmd(struct wmi_t *wmip, WMI_SET_WOW_MODE_CMD *cmd); ++A_STATUS wmi_get_wow_list_cmd(struct wmi_t *wmip, WMI_GET_WOW_LIST_CMD *cmd); ++A_STATUS wmi_add_wow_pattern_cmd(struct wmi_t *wmip, ++ WMI_ADD_WOW_PATTERN_CMD *cmd, A_UINT8* pattern, A_UINT8* mask, A_UINT8 pattern_size); ++A_STATUS wmi_del_wow_pattern_cmd(struct wmi_t *wmip, ++ WMI_DEL_WOW_PATTERN_CMD *cmd); ++A_STATUS wmi_set_wsc_status_cmd(struct wmi_t *wmip, A_UINT32 status); ++ ++bss_t * ++wmi_find_Ssidnode (struct wmi_t *wmip, A_UCHAR *pSsid, ++ A_UINT32 ssidLength, A_BOOL bIsWPA2); ++ ++void ++wmi_node_return (struct wmi_t *wmip, bss_t *bss); ++#ifdef __cplusplus ++} ++#endif ++ ++#endif /* _WMI_API_H_ */ +diff -ruN --exclude='*.orig' --exclude='*.rej' linux-2.6.29-rc3.owrt/drivers/ar6000/include/wmi.h linux-2.6.29-rc3.owrt.om/drivers/ar6000/include/wmi.h +--- linux-2.6.29-rc3.owrt/drivers/ar6000/include/wmi.h 1970-01-01 01:00:00.000000000 +0100 ++++ linux-2.6.29-rc3.owrt.om/drivers/ar6000/include/wmi.h 2009-05-10 22:27:59.000000000 +0200 +@@ -0,0 +1,1743 @@ ++/* ++ * Copyright (c) 2004-2006 Atheros Communications Inc. ++ * All rights reserved. ++ * ++ * ++ * $ATH_LICENSE_HOSTSDK0_C$ ++ * ++ * This file contains the definitions of the WMI protocol specified in the ++ * Wireless Module Interface (WMI). It includes definitions of all the ++ * commands and events. Commands are messages from the host to the WM. ++ * Events and Replies are messages from the WM to the host. ++ * ++ * Ownership of correctness in regards to WMI commands ++ * belongs to the host driver and the WM is not required to validate ++ * parameters for value, proper range, or any other checking. ++ * ++ */ ++ ++#ifndef _WMI_H_ ++#define _WMI_H_ ++ ++#ifndef ATH_TARGET ++#include "athstartpack.h" ++#endif ++ ++#include "wmix.h" ++ ++#ifdef __cplusplus ++extern "C" { ++#endif ++ ++#define WMI_PROTOCOL_VERSION 0x0002 ++#define WMI_PROTOCOL_REVISION 0x0000 ++ ++#define ATH_MAC_LEN 6 /* length of mac in bytes */ ++#define WMI_CMD_MAX_LEN 100 ++#define WMI_CONTROL_MSG_MAX_LEN 256 ++#define WMI_OPT_CONTROL_MSG_MAX_LEN 1536 ++#define IS_ETHERTYPE(_typeOrLen) ((_typeOrLen) >= 0x0600) ++#define RFC1042OUI {0x00, 0x00, 0x00} ++ ++#define IP_ETHERTYPE 0x0800 ++ ++#define WMI_IMPLICIT_PSTREAM 0xFF ++#define WMI_MAX_THINSTREAM 15 ++ ++struct host_app_area_s { ++ A_UINT32 wmi_protocol_ver; ++}; ++ ++/* ++ * Data Path ++ */ ++typedef PREPACK struct { ++ A_UINT8 dstMac[ATH_MAC_LEN]; ++ A_UINT8 srcMac[ATH_MAC_LEN]; ++ A_UINT16 typeOrLen; ++} POSTPACK ATH_MAC_HDR; ++ ++typedef PREPACK struct { ++ A_UINT8 dsap; ++ A_UINT8 ssap; ++ A_UINT8 cntl; ++ A_UINT8 orgCode[3]; ++ A_UINT16 etherType; ++} POSTPACK ATH_LLC_SNAP_HDR; ++ ++typedef enum { ++ DATA_MSGTYPE = 0x0, ++ CNTL_MSGTYPE, ++ SYNC_MSGTYPE ++} WMI_MSG_TYPE; ++ ++ ++typedef PREPACK struct { ++ A_INT8 rssi; ++ A_UINT8 info; /* WMI_MSG_TYPE in lower 2 bits - b1b0 */ ++ /* UP in next 3 bits - b4b3b2 */ ++#define WMI_DATA_HDR_MSG_TYPE_MASK 0x03 ++#define WMI_DATA_HDR_MSG_TYPE_SHIFT 0 ++#define WMI_DATA_HDR_UP_MASK 0x07 ++#define WMI_DATA_HDR_UP_SHIFT 2 ++#define WMI_DATA_HDR_IS_MSG_TYPE(h, t) (((h)->info & (WMI_DATA_HDR_MSG_TYPE_MASK)) == (t)) ++} POSTPACK WMI_DATA_HDR; ++ ++ ++#define WMI_DATA_HDR_SET_MSG_TYPE(h, t) (h)->info = (((h)->info & ~(WMI_DATA_HDR_MSG_TYPE_MASK << WMI_DATA_HDR_MSG_TYPE_SHIFT)) | (t << WMI_DATA_HDR_MSG_TYPE_SHIFT)) ++#define WMI_DATA_HDR_SET_UP(h, p) (h)->info = (((h)->info & ~(WMI_DATA_HDR_UP_MASK << WMI_DATA_HDR_UP_SHIFT)) | (p << WMI_DATA_HDR_UP_SHIFT)) ++ ++/* ++ * Control Path ++ */ ++typedef PREPACK struct { ++ A_UINT16 commandId; ++} POSTPACK WMI_CMD_HDR; /* used for commands and events */ ++ ++/* ++ * List of Commnands ++ */ ++typedef enum { ++ WMI_CONNECT_CMDID = 0x0001, ++ WMI_RECONNECT_CMDID, ++ WMI_DISCONNECT_CMDID, ++ WMI_SYNCHRONIZE_CMDID, ++ WMI_CREATE_PSTREAM_CMDID, ++ WMI_DELETE_PSTREAM_CMDID, ++ WMI_START_SCAN_CMDID, ++ WMI_SET_SCAN_PARAMS_CMDID, ++ WMI_SET_BSS_FILTER_CMDID, ++ WMI_SET_PROBED_SSID_CMDID, ++ WMI_SET_LISTEN_INT_CMDID, ++ WMI_SET_BMISS_TIME_CMDID, ++ WMI_SET_DISC_TIMEOUT_CMDID, ++ WMI_GET_CHANNEL_LIST_CMDID, ++ WMI_SET_BEACON_INT_CMDID, ++ WMI_GET_STATISTICS_CMDID, ++ WMI_SET_CHANNEL_PARAMS_CMDID, ++ WMI_SET_POWER_MODE_CMDID, ++ WMI_SET_IBSS_PM_CAPS_CMDID, ++ WMI_SET_POWER_PARAMS_CMDID, ++ WMI_SET_POWERSAVE_TIMERS_POLICY_CMDID, ++ WMI_ADD_CIPHER_KEY_CMDID, ++ WMI_DELETE_CIPHER_KEY_CMDID, ++ WMI_ADD_KRK_CMDID, ++ WMI_DELETE_KRK_CMDID, ++ WMI_SET_PMKID_CMDID, ++ WMI_SET_TX_PWR_CMDID, ++ WMI_GET_TX_PWR_CMDID, ++ WMI_SET_ASSOC_INFO_CMDID, ++ WMI_ADD_BAD_AP_CMDID, ++ WMI_DELETE_BAD_AP_CMDID, ++ WMI_SET_TKIP_COUNTERMEASURES_CMDID, ++ WMI_RSSI_THRESHOLD_PARAMS_CMDID, ++ WMI_TARGET_ERROR_REPORT_BITMASK_CMDID, ++ WMI_SET_ACCESS_PARAMS_CMDID, ++ WMI_SET_RETRY_LIMITS_CMDID, ++ WMI_SET_OPT_MODE_CMDID, ++ WMI_OPT_TX_FRAME_CMDID, ++ WMI_SET_VOICE_PKT_SIZE_CMDID, ++ WMI_SET_MAX_SP_LEN_CMDID, ++ WMI_SET_ROAM_CTRL_CMDID, ++ WMI_GET_ROAM_TBL_CMDID, ++ WMI_GET_ROAM_DATA_CMDID, ++ WMI_ENABLE_RM_CMDID, ++ WMI_SET_MAX_OFFHOME_DURATION_CMDID, ++ WMI_EXTENSION_CMDID, /* Non-wireless extensions */ ++ WMI_SNR_THRESHOLD_PARAMS_CMDID, ++ WMI_LQ_THRESHOLD_PARAMS_CMDID, ++ WMI_SET_LPREAMBLE_CMDID, ++ WMI_SET_RTS_CMDID, ++ WMI_CLR_RSSI_SNR_CMDID, ++ WMI_SET_FIXRATES_CMDID, ++ WMI_GET_FIXRATES_CMDID, ++ WMI_SET_AUTH_MODE_CMDID, ++ WMI_SET_REASSOC_MODE_CMDID, ++ WMI_SET_WMM_CMDID, ++ WMI_SET_WMM_TXOP_CMDID, ++ WMI_TEST_CMDID, ++ WMI_SET_BT_STATUS_CMDID, ++ WMI_SET_BT_PARAMS_CMDID, ++ ++ WMI_SET_KEEPALIVE_CMDID, ++ WMI_GET_KEEPALIVE_CMDID, ++ WMI_SET_APPIE_CMDID, ++ WMI_GET_APPIE_CMDID, ++ WMI_SET_WSC_STATUS_CMDID, ++ ++ /* Wake on Wireless */ ++ WMI_SET_HOST_SLEEP_MODE_CMDID, ++ WMI_SET_WOW_MODE_CMDID, ++ WMI_GET_WOW_LIST_CMDID, ++ WMI_ADD_WOW_PATTERN_CMDID, ++ WMI_DEL_WOW_PATTERN_CMDID, ++ WMI_SET_MAC_ADDRESS_CMDID, ++ WMI_SET_AKMP_PARAMS_CMDID, ++ WMI_SET_PMKID_LIST_CMDID, ++ WMI_GET_PMKID_LIST_CMDID, ++ ++ /* ++ * Developer commands starts at 0xF000 ++ */ ++ WMI_SET_BITRATE_CMDID = 0xF000, ++ WMI_GET_BITRATE_CMDID, ++ WMI_SET_WHALPARAM_CMDID, ++ ++} WMI_COMMAND_ID; ++ ++/* ++ * Frame Types ++ */ ++typedef enum { ++ WMI_FRAME_BEACON = 0, ++ WMI_FRAME_PROBE_REQ, ++ WMI_FRAME_PROBE_RESP, ++ WMI_FRAME_ASSOC_REQ, ++ WMI_FRAME_ASSOC_RESP, ++ WMI_NUM_MGMT_FRAME ++} WMI_MGMT_FRAME_TYPE; ++ ++/* ++ * Connect Command ++ */ ++typedef enum { ++ INFRA_NETWORK = 0x01, ++ ADHOC_NETWORK = 0x02, ++ ADHOC_CREATOR = 0x04, ++} NETWORK_TYPE; ++ ++typedef enum { ++ OPEN_AUTH = 0x01, ++ SHARED_AUTH = 0x02, ++ LEAP_AUTH = 0x04, /* different from IEEE_AUTH_MODE definitions */ ++} DOT11_AUTH_MODE; ++ ++typedef enum { ++ NONE_AUTH = 0x01, ++ WPA_AUTH = 0x02, ++ WPA_PSK_AUTH = 0x03, ++ WPA2_AUTH = 0x04, ++ WPA2_PSK_AUTH = 0x05, ++ WPA_AUTH_CCKM = 0x06, ++ WPA2_AUTH_CCKM = 0x07, ++} AUTH_MODE; ++ ++typedef enum { ++ NONE_CRYPT = 0x01, ++ WEP_CRYPT = 0x02, ++ TKIP_CRYPT = 0x03, ++ AES_CRYPT = 0x04, ++} CRYPTO_TYPE; ++ ++#define WMI_MIN_CRYPTO_TYPE NONE_CRYPT ++#define WMI_MAX_CRYPTO_TYPE (AES_CRYPT + 1) ++ ++#define WMI_MIN_KEY_INDEX 0 ++#define WMI_MAX_KEY_INDEX 3 ++ ++#define WMI_MAX_KEY_LEN 32 ++ ++#define WMI_MAX_SSID_LEN 32 ++ ++typedef enum { ++ CONNECT_ASSOC_POLICY_USER = 0x0001, ++ CONNECT_SEND_REASSOC = 0x0002, ++ CONNECT_IGNORE_WPAx_GROUP_CIPHER = 0x0004, ++ CONNECT_PROFILE_MATCH_DONE = 0x0008, ++ CONNECT_IGNORE_AAC_BEACON = 0x0010, ++ CONNECT_CSA_FOLLOW_BSS = 0x0020, ++} WMI_CONNECT_CTRL_FLAGS_BITS; ++ ++#define DEFAULT_CONNECT_CTRL_FLAGS (CONNECT_CSA_FOLLOW_BSS) ++ ++typedef PREPACK struct { ++ A_UINT8 networkType; ++ A_UINT8 dot11AuthMode; ++ A_UINT8 authMode; ++ A_UINT8 pairwiseCryptoType; ++ A_UINT8 pairwiseCryptoLen; ++ A_UINT8 groupCryptoType; ++ A_UINT8 groupCryptoLen; ++ A_UINT8 ssidLength; ++ A_UCHAR ssid[WMI_MAX_SSID_LEN]; ++ A_UINT16 channel; ++ A_UINT8 bssid[ATH_MAC_LEN]; ++ A_UINT32 ctrl_flags; ++} POSTPACK WMI_CONNECT_CMD; ++ ++/* ++ * WMI_RECONNECT_CMDID ++ */ ++typedef PREPACK struct { ++ A_UINT16 channel; /* hint */ ++ A_UINT8 bssid[ATH_MAC_LEN]; /* mandatory if set */ ++} POSTPACK WMI_RECONNECT_CMD; ++ ++/* ++ * WMI_ADD_CIPHER_KEY_CMDID ++ */ ++typedef enum { ++ PAIRWISE_USAGE = 0x00, ++ GROUP_USAGE = 0x01, ++ TX_USAGE = 0x02, /* default Tx Key - Static WEP only */ ++} KEY_USAGE; ++ ++/* ++ * Bit Flag ++ * Bit 0 - Initialise TSC - default is Initialize ++ */ ++#define KEY_OP_INIT_TSC 0x01 ++#define KEY_OP_INIT_RSC 0x02 ++ ++#define KEY_OP_INIT_VAL 0x03 /* Default Initialise the TSC & RSC */ ++#define KEY_OP_VALID_MASK 0x03 ++ ++typedef PREPACK struct { ++ A_UINT8 keyIndex; ++ A_UINT8 keyType; ++ A_UINT8 keyUsage; /* KEY_USAGE */ ++ A_UINT8 keyLength; ++ A_UINT8 keyRSC[8]; /* key replay sequence counter */ ++ A_UINT8 key[WMI_MAX_KEY_LEN]; ++ A_UINT8 key_op_ctrl; /* Additional Key Control information */ ++} POSTPACK WMI_ADD_CIPHER_KEY_CMD; ++ ++/* ++ * WMI_DELETE_CIPHER_KEY_CMDID ++ */ ++typedef PREPACK struct { ++ A_UINT8 keyIndex; ++} POSTPACK WMI_DELETE_CIPHER_KEY_CMD; ++ ++#define WMI_KRK_LEN 16 ++/* ++ * WMI_ADD_KRK_CMDID ++ */ ++typedef PREPACK struct { ++ A_UINT8 krk[WMI_KRK_LEN]; ++} POSTPACK WMI_ADD_KRK_CMD; ++ ++/* ++ * WMI_SET_TKIP_COUNTERMEASURES_CMDID ++ */ ++typedef enum { ++ WMI_TKIP_CM_DISABLE = 0x0, ++ WMI_TKIP_CM_ENABLE = 0x1, ++} WMI_TKIP_CM_CONTROL; ++ ++typedef PREPACK struct { ++ A_UINT8 cm_en; /* WMI_TKIP_CM_CONTROL */ ++} POSTPACK WMI_SET_TKIP_COUNTERMEASURES_CMD; ++ ++/* ++ * WMI_SET_PMKID_CMDID ++ */ ++ ++#define WMI_PMKID_LEN 16 ++ ++typedef enum { ++ PMKID_DISABLE = 0, ++ PMKID_ENABLE = 1, ++} PMKID_ENABLE_FLG; ++ ++typedef PREPACK struct { ++ A_UINT8 bssid[ATH_MAC_LEN]; ++ A_UINT8 enable; /* PMKID_ENABLE_FLG */ ++ A_UINT8 pmkid[WMI_PMKID_LEN]; ++} POSTPACK WMI_SET_PMKID_CMD; ++ ++/* ++ * WMI_START_SCAN_CMD ++ */ ++typedef enum { ++ WMI_LONG_SCAN = 0, ++ WMI_SHORT_SCAN = 1, ++} WMI_SCAN_TYPE; ++ ++typedef PREPACK struct { ++ A_BOOL forceFgScan; ++ A_BOOL isLegacy; /* For Legacy Cisco AP compatibility */ ++ A_UINT32 homeDwellTime; /* Maximum duration in the home channel(milliseconds) */ ++ A_UINT32 forceScanInterval; /* Time interval between scans (milliseconds)*/ ++ A_UINT8 scanType; /* WMI_SCAN_TYPE */ ++} POSTPACK WMI_START_SCAN_CMD; ++ ++/* ++ * WMI_SET_SCAN_PARAMS_CMDID ++ */ ++#define WMI_SHORTSCANRATIO_DEFAULT 3 ++typedef enum { ++ CONNECT_SCAN_CTRL_FLAGS = 0x01, /* set if can scan in the Connect cmd */ ++ SCAN_CONNECTED_CTRL_FLAGS = 0x02, /* set if scan for the SSID it is */ ++ /* already connected to */ ++ ACTIVE_SCAN_CTRL_FLAGS = 0x04, /* set if enable active scan */ ++ ROAM_SCAN_CTRL_FLAGS = 0x08, /* set if enable roam scan when bmiss and lowrssi */ ++ REPORT_BSSINFO_CTRL_FLAGS = 0x10, /* set if follows customer BSSINFO reporting rule */ ++ ENABLE_AUTO_CTRL_FLAGS = 0x20, /* if disabled, target doesn't ++ scan after a disconnect event */ ++ ENABLE_SCAN_ABORT_EVENT = 0x40 /* Scan complete event with canceled status will be generated when a scan is prempted before it gets completed */ ++ ++} WMI_SCAN_CTRL_FLAGS_BITS; ++ ++#define CAN_SCAN_IN_CONNECT(flags) (flags & CONNECT_SCAN_CTRL_FLAGS) ++#define CAN_SCAN_CONNECTED(flags) (flags & SCAN_CONNECTED_CTRL_FLAGS) ++#define ENABLE_ACTIVE_SCAN(flags) (flags & ACTIVE_SCAN_CTRL_FLAGS) ++#define ENABLE_ROAM_SCAN(flags) (flags & ROAM_SCAN_CTRL_FLAGS) ++#define CONFIG_REPORT_BSSINFO(flags) (flags & REPORT_BSSINFO_CTRL_FLAGS) ++#define IS_AUTO_SCAN_ENABLED(flags) (flags & ENABLE_AUTO_CTRL_FLAGS) ++#define SCAN_ABORT_EVENT_ENABLED(flags) (flags & ENABLE_SCAN_ABORT_EVENT) ++ ++#define DEFAULT_SCAN_CTRL_FLAGS (CONNECT_SCAN_CTRL_FLAGS| SCAN_CONNECTED_CTRL_FLAGS| ACTIVE_SCAN_CTRL_FLAGS| ROAM_SCAN_CTRL_FLAGS | ENABLE_AUTO_CTRL_FLAGS) ++ ++ ++typedef PREPACK struct { ++ A_UINT16 fg_start_period; /* seconds */ ++ A_UINT16 fg_end_period; /* seconds */ ++ A_UINT16 bg_period; /* seconds */ ++ A_UINT16 maxact_chdwell_time; /* msec */ ++ A_UINT16 pas_chdwell_time; /* msec */ ++ A_UINT8 shortScanRatio; /* how many shorts scan for one long */ ++ A_UINT8 scanCtrlFlags; ++ A_UINT16 minact_chdwell_time; /* msec */ ++ A_UINT32 max_dfsch_act_time; /* msecs */ ++} POSTPACK WMI_SCAN_PARAMS_CMD; ++ ++/* ++ * WMI_SET_BSS_FILTER_CMDID ++ */ ++typedef enum { ++ NONE_BSS_FILTER = 0x0, /* no beacons forwarded */ ++ ALL_BSS_FILTER, /* all beacons forwarded */ ++ PROFILE_FILTER, /* only beacons matching profile */ ++ ALL_BUT_PROFILE_FILTER, /* all but beacons matching profile */ ++ CURRENT_BSS_FILTER, /* only beacons matching current BSS */ ++ ALL_BUT_BSS_FILTER, /* all but beacons matching BSS */ ++ PROBED_SSID_FILTER, /* beacons matching probed ssid */ ++ LAST_BSS_FILTER, /* marker only */ ++} WMI_BSS_FILTER; ++ ++typedef PREPACK struct { ++ A_UINT8 bssFilter; /* see WMI_BSS_FILTER */ ++ A_UINT32 ieMask; ++} POSTPACK WMI_BSS_FILTER_CMD; ++ ++/* ++ * WMI_SET_PROBED_SSID_CMDID ++ */ ++#define MAX_PROBED_SSID_INDEX 5 ++ ++typedef enum { ++ DISABLE_SSID_FLAG = 0, /* disables entry */ ++ SPECIFIC_SSID_FLAG = 0x01, /* probes specified ssid */ ++ ANY_SSID_FLAG = 0x02, /* probes for any ssid */ ++} WMI_SSID_FLAG; ++ ++typedef PREPACK struct { ++ A_UINT8 entryIndex; /* 0 to MAX_PROBED_SSID_INDEX */ ++ A_UINT8 flag; /* WMI_SSID_FLG */ ++ A_UINT8 ssidLength; ++ A_UINT8 ssid[32]; ++} POSTPACK WMI_PROBED_SSID_CMD; ++ ++/* ++ * WMI_SET_LISTEN_INT_CMDID ++ * The Listen interval is between 15 and 3000 TUs ++ */ ++#define MIN_LISTEN_INTERVAL 15 ++#define MAX_LISTEN_INTERVAL 5000 ++#define MIN_LISTEN_BEACONS 1 ++#define MAX_LISTEN_BEACONS 50 ++ ++typedef PREPACK struct { ++ A_UINT16 listenInterval; ++ A_UINT16 numBeacons; ++} POSTPACK WMI_LISTEN_INT_CMD; ++ ++/* ++ * WMI_SET_BEACON_INT_CMDID ++ */ ++typedef PREPACK struct { ++ A_UINT16 beaconInterval; ++} POSTPACK WMI_BEACON_INT_CMD; ++ ++/* ++ * WMI_SET_BMISS_TIME_CMDID ++ * valid values are between 1000 and 5000 TUs ++ */ ++ ++#define MIN_BMISS_TIME 1000 ++#define MAX_BMISS_TIME 5000 ++#define MIN_BMISS_BEACONS 1 ++#define MAX_BMISS_BEACONS 50 ++ ++typedef PREPACK struct { ++ A_UINT16 bmissTime; ++ A_UINT16 numBeacons; ++} POSTPACK WMI_BMISS_TIME_CMD; ++ ++/* ++ * WMI_SET_POWER_MODE_CMDID ++ */ ++typedef enum { ++ REC_POWER = 0x01, ++ MAX_PERF_POWER, ++} WMI_POWER_MODE; ++ ++typedef PREPACK struct { ++ A_UINT8 powerMode; /* WMI_POWER_MODE */ ++} POSTPACK WMI_POWER_MODE_CMD; ++ ++/* ++ * WMI_SET_POWER_PARAMS_CMDID ++ */ ++typedef enum { ++ IGNORE_DTIM = 0x01, ++ NORMAL_DTIM = 0x02, ++ STICK_DTIM = 0x03, ++} WMI_DTIM_POLICY; ++ ++typedef PREPACK struct { ++ A_UINT16 idle_period; /* msec */ ++ A_UINT16 pspoll_number; ++ A_UINT16 dtim_policy; ++} POSTPACK WMI_POWER_PARAMS_CMD; ++ ++typedef PREPACK struct { ++ A_UINT8 power_saving; ++ A_UINT8 ttl; /* number of beacon periods */ ++ A_UINT16 atim_windows; /* msec */ ++ A_UINT16 timeout_value; /* msec */ ++} POSTPACK WMI_IBSS_PM_CAPS_CMD; ++ ++/* ++ * WMI_SET_POWERSAVE_TIMERS_POLICY_CMDID ++ */ ++typedef enum { ++ IGNORE_TIM_ALL_QUEUES_APSD = 0, ++ PROCESS_TIM_ALL_QUEUES_APSD = 1, ++ IGNORE_TIM_SIMULATED_APSD = 2, ++ PROCESS_TIM_SIMULATED_APSD = 3, ++} APSD_TIM_POLICY; ++ ++typedef PREPACK struct { ++ A_UINT16 psPollTimeout; /* msec */ ++ A_UINT16 triggerTimeout; /* msec */ ++ A_UINT32 apsdTimPolicy; /* TIM behavior with ques APSD enabled. Default is IGNORE_TIM_ALL_QUEUES_APSD */ ++ A_UINT32 simulatedAPSDTimPolicy; /* TIM behavior with simulated APSD enabled. Default is PROCESS_TIM_SIMULATED_APSD */ ++} POSTPACK WMI_POWERSAVE_TIMERS_POLICY_CMD; ++ ++/* ++ * WMI_SET_VOICE_PKT_SIZE_CMDID ++ */ ++typedef PREPACK struct { ++ A_UINT16 voicePktSize; ++} POSTPACK WMI_SET_VOICE_PKT_SIZE_CMD; ++ ++/* ++ * WMI_SET_MAX_SP_LEN_CMDID ++ */ ++typedef enum { ++ DELIVER_ALL_PKT = 0x0, ++ DELIVER_2_PKT = 0x1, ++ DELIVER_4_PKT = 0x2, ++ DELIVER_6_PKT = 0x3, ++} APSD_SP_LEN_TYPE; ++ ++typedef PREPACK struct { ++ A_UINT8 maxSPLen; ++} POSTPACK WMI_SET_MAX_SP_LEN_CMD; ++ ++/* ++ * WMI_SET_DISC_TIMEOUT_CMDID ++ */ ++typedef PREPACK struct { ++ A_UINT8 disconnectTimeout; /* seconds */ ++} POSTPACK WMI_DISC_TIMEOUT_CMD; ++ ++typedef enum { ++ UPLINK_TRAFFIC = 0, ++ DNLINK_TRAFFIC = 1, ++ BIDIR_TRAFFIC = 2, ++} DIR_TYPE; ++ ++typedef enum { ++ DISABLE_FOR_THIS_AC = 0, ++ ENABLE_FOR_THIS_AC = 1, ++ ENABLE_FOR_ALL_AC = 2, ++} VOICEPS_CAP_TYPE; ++ ++typedef enum { ++ TRAFFIC_TYPE_APERIODIC = 0, ++ TRAFFIC_TYPE_PERIODIC = 1, ++}TRAFFIC_TYPE; ++ ++/* ++ * WMI_CREATE_PSTREAM_CMDID ++ */ ++typedef PREPACK struct { ++ A_UINT32 minServiceInt; /* in milli-sec */ ++ A_UINT32 maxServiceInt; /* in milli-sec */ ++ A_UINT32 inactivityInt; /* in milli-sec */ ++ A_UINT32 suspensionInt; /* in milli-sec */ ++ A_UINT32 serviceStartTime; ++ A_UINT32 minDataRate; /* in bps */ ++ A_UINT32 meanDataRate; /* in bps */ ++ A_UINT32 peakDataRate; /* in bps */ ++ A_UINT32 maxBurstSize; ++ A_UINT32 delayBound; ++ A_UINT32 minPhyRate; /* in bps */ ++ A_UINT32 sba; ++ A_UINT32 mediumTime; ++ A_UINT16 nominalMSDU; /* in octects */ ++ A_UINT16 maxMSDU; /* in octects */ ++ A_UINT8 trafficClass; ++ A_UINT8 trafficType; /* TRAFFIC_TYPE */ ++ A_UINT8 trafficDirection; /* TRAFFIC_DIR */ ++ A_UINT8 voicePSCapability; /* VOICEPS_CAP_TYPE */ ++ A_UINT8 tsid; ++ A_UINT8 userPriority; /* 802.1D user priority */ ++} POSTPACK WMI_CREATE_PSTREAM_CMD; ++ ++/* ++ * WMI_DELETE_PSTREAM_CMDID ++ */ ++typedef PREPACK struct { ++ A_UINT8 trafficClass; ++ A_UINT8 tsid; ++} POSTPACK WMI_DELETE_PSTREAM_CMD; ++ ++/* ++ * WMI_SET_CHANNEL_PARAMS_CMDID ++ */ ++typedef enum { ++ WMI_11A_MODE = 0x1, ++ WMI_11G_MODE = 0x2, ++ WMI_11AG_MODE = 0x3, ++ WMI_11B_MODE = 0x4, ++ WMI_11GONLY_MODE = 0x5, ++} WMI_PHY_MODE; ++ ++#define WMI_MAX_CHANNELS 32 ++ ++typedef PREPACK struct { ++ A_UINT8 reserved1; ++ A_UINT8 scanParam; /* set if enable scan */ ++ A_UINT8 phyMode; /* see WMI_PHY_MODE */ ++ A_UINT8 numChannels; /* how many channels follow */ ++ A_UINT16 channelList[1]; /* channels in Mhz */ ++} POSTPACK WMI_CHANNEL_PARAMS_CMD; ++ ++ ++/* ++ * WMI_RSSI_THRESHOLD_PARAMS_CMDID ++ * Setting the polltime to 0 would disable polling. ++ * Threshold values are in the ascending order, and should agree to: ++ * (lowThreshold_lowerVal < lowThreshold_upperVal < highThreshold_lowerVal ++ * < highThreshold_upperVal) ++ */ ++ ++typedef PREPACK struct WMI_RSSI_THRESHOLD_PARAMS{ ++ A_UINT32 pollTime; /* Polling time as a factor of LI */ ++ A_INT16 thresholdAbove1_Val; /* lowest of upper */ ++ A_INT16 thresholdAbove2_Val; ++ A_INT16 thresholdAbove3_Val; ++ A_INT16 thresholdAbove4_Val; ++ A_INT16 thresholdAbove5_Val; ++ A_INT16 thresholdAbove6_Val; /* highest of upper */ ++ A_INT16 thresholdBelow1_Val; /* lowest of bellow */ ++ A_INT16 thresholdBelow2_Val; ++ A_INT16 thresholdBelow3_Val; ++ A_INT16 thresholdBelow4_Val; ++ A_INT16 thresholdBelow5_Val; ++ A_INT16 thresholdBelow6_Val; /* highest of bellow */ ++ A_UINT8 weight; /* "alpha" */ ++ A_UINT8 reserved[3]; ++} POSTPACK WMI_RSSI_THRESHOLD_PARAMS_CMD; ++ ++/* ++ * WMI_SNR_THRESHOLD_PARAMS_CMDID ++ * Setting the polltime to 0 would disable polling. ++ */ ++ ++typedef PREPACK struct WMI_SNR_THRESHOLD_PARAMS{ ++ A_UINT32 pollTime; /* Polling time as a factor of LI */ ++ A_UINT8 weight; /* "alpha" */ ++ A_UINT8 thresholdAbove1_Val; /* lowest of uppper*/ ++ A_UINT8 thresholdAbove2_Val; ++ A_UINT8 thresholdAbove3_Val; ++ A_UINT8 thresholdAbove4_Val; /* highest of upper */ ++ A_UINT8 thresholdBelow1_Val; /* lowest of bellow */ ++ A_UINT8 thresholdBelow2_Val; ++ A_UINT8 thresholdBelow3_Val; ++ A_UINT8 thresholdBelow4_Val; /* highest of bellow */ ++ A_UINT8 reserved[3]; ++} POSTPACK WMI_SNR_THRESHOLD_PARAMS_CMD; ++ ++/* ++ * WMI_LQ_THRESHOLD_PARAMS_CMDID ++ */ ++typedef PREPACK struct WMI_LQ_THRESHOLD_PARAMS { ++ A_UINT8 enable; ++ A_UINT8 thresholdAbove1_Val; ++ A_UINT8 thresholdAbove2_Val; ++ A_UINT8 thresholdAbove3_Val; ++ A_UINT8 thresholdAbove4_Val; ++ A_UINT8 thresholdBelow1_Val; ++ A_UINT8 thresholdBelow2_Val; ++ A_UINT8 thresholdBelow3_Val; ++ A_UINT8 thresholdBelow4_Val; ++ A_UINT8 reserved[3]; ++} POSTPACK WMI_LQ_THRESHOLD_PARAMS_CMD; ++ ++typedef enum { ++ WMI_LPREAMBLE_DISABLED = 0, ++ WMI_LPREAMBLE_ENABLED ++} WMI_LPREAMBLE_STATUS; ++ ++typedef PREPACK struct { ++ A_UINT8 status; ++}POSTPACK WMI_SET_LPREAMBLE_CMD; ++ ++typedef PREPACK struct { ++ A_UINT16 threshold; ++}POSTPACK WMI_SET_RTS_CMD; ++ ++/* ++ * WMI_TARGET_ERROR_REPORT_BITMASK_CMDID ++ * Sets the error reporting event bitmask in target. Target clears it ++ * upon an error. Subsequent errors are counted, but not reported ++ * via event, unless the bitmask is set again. ++ */ ++typedef PREPACK struct { ++ A_UINT32 bitmask; ++} POSTPACK WMI_TARGET_ERROR_REPORT_BITMASK; ++ ++/* ++ * WMI_SET_TX_PWR_CMDID ++ */ ++typedef PREPACK struct { ++ A_UINT8 dbM; /* in dbM units */ ++} POSTPACK WMI_SET_TX_PWR_CMD, WMI_TX_PWR_REPLY; ++ ++/* ++ * WMI_SET_ASSOC_INFO_CMDID ++ * ++ * A maximum of 2 private IEs can be sent in the [Re]Assoc request. ++ * A 3rd one, the CCX version IE can also be set from the host. ++ */ ++#define WMI_MAX_ASSOC_INFO_TYPE 2 ++#define WMI_CCX_VER_IE 2 /* ieType to set CCX Version IE */ ++ ++#define WMI_MAX_ASSOC_INFO_LEN 240 ++ ++typedef PREPACK struct { ++ A_UINT8 ieType; ++ A_UINT8 bufferSize; ++ A_UINT8 assocInfo[1]; /* up to WMI_MAX_ASSOC_INFO_LEN */ ++} POSTPACK WMI_SET_ASSOC_INFO_CMD; ++ ++ ++/* ++ * WMI_GET_TX_PWR_CMDID does not take any parameters ++ */ ++ ++/* ++ * WMI_ADD_BAD_AP_CMDID ++ */ ++#define WMI_MAX_BAD_AP_INDEX 1 ++ ++typedef PREPACK struct { ++ A_UINT8 badApIndex; /* 0 to WMI_MAX_BAD_AP_INDEX */ ++ A_UINT8 bssid[ATH_MAC_LEN]; ++} POSTPACK WMI_ADD_BAD_AP_CMD; ++ ++/* ++ * WMI_DELETE_BAD_AP_CMDID ++ */ ++typedef PREPACK struct { ++ A_UINT8 badApIndex; /* 0 to WMI_MAX_BAD_AP_INDEX */ ++} POSTPACK WMI_DELETE_BAD_AP_CMD; ++ ++/* ++ * WMI_SET_ACCESS_PARAMS_CMDID ++ */ ++#define WMI_DEFAULT_TXOP_ACPARAM 0 /* implies one MSDU */ ++#define WMI_DEFAULT_ECWMIN_ACPARAM 4 /* corresponds to CWmin of 15 */ ++#define WMI_DEFAULT_ECWMAX_ACPARAM 10 /* corresponds to CWmax of 1023 */ ++#define WMI_MAX_CW_ACPARAM 15 /* maximum eCWmin or eCWmax */ ++#define WMI_DEFAULT_AIFSN_ACPARAM 2 ++#define WMI_MAX_AIFSN_ACPARAM 15 ++typedef PREPACK struct { ++ A_UINT16 txop; /* in units of 32 usec */ ++ A_UINT8 eCWmin; ++ A_UINT8 eCWmax; ++ A_UINT8 aifsn; ++} POSTPACK WMI_SET_ACCESS_PARAMS_CMD; ++ ++ ++/* ++ * WMI_SET_RETRY_LIMITS_CMDID ++ * ++ * This command is used to customize the number of retries the ++ * wlan device will perform on a given frame. ++ */ ++#define WMI_MIN_RETRIES 2 ++#define WMI_MAX_RETRIES 13 ++typedef enum { ++ MGMT_FRAMETYPE = 0, ++ CONTROL_FRAMETYPE = 1, ++ DATA_FRAMETYPE = 2 ++} WMI_FRAMETYPE; ++ ++typedef PREPACK struct { ++ A_UINT8 frameType; /* WMI_FRAMETYPE */ ++ A_UINT8 trafficClass; /* applies only to DATA_FRAMETYPE */ ++ A_UINT8 maxRetries; ++ A_UINT8 enableNotify; ++} POSTPACK WMI_SET_RETRY_LIMITS_CMD; ++ ++/* ++ * WMI_SET_ROAM_CTRL_CMDID ++ * ++ * This command is used to influence the Roaming behaviour ++ * Set the host biases of the BSSs before setting the roam mode as bias ++ * based. ++ */ ++ ++/* ++ * Different types of Roam Control ++ */ ++ ++typedef enum { ++ WMI_FORCE_ROAM = 1, /* Roam to the specified BSSID */ ++ WMI_SET_ROAM_MODE = 2, /* default ,progd bias, no roam */ ++ WMI_SET_HOST_BIAS = 3, /* Set the Host Bias */ ++ WMI_SET_LOWRSSI_SCAN_PARAMS = 4, /* Set lowrssi Scan parameters */ ++} WMI_ROAM_CTRL_TYPE; ++ ++#define WMI_MIN_ROAM_CTRL_TYPE WMI_FORCE_ROAM ++#define WMI_MAX_ROAM_CTRL_TYPE WMI_SET_LOWRSSI_SCAN_PARAMS ++ ++/* ++ * ROAM MODES ++ */ ++ ++typedef enum { ++ WMI_DEFAULT_ROAM_MODE = 1, /* RSSI based ROAM */ ++ WMI_HOST_BIAS_ROAM_MODE = 2, /* HOST BIAS based ROAM */ ++ WMI_LOCK_BSS_MODE = 3 /* Lock to the Current BSS - no Roam */ ++} WMI_ROAM_MODE; ++ ++/* ++ * BSS HOST BIAS INFO ++ */ ++ ++typedef PREPACK struct { ++ A_UINT8 bssid[ATH_MAC_LEN]; ++ A_INT8 bias; ++} POSTPACK WMI_BSS_BIAS; ++ ++typedef PREPACK struct { ++ A_UINT8 numBss; ++ WMI_BSS_BIAS bssBias[1]; ++} POSTPACK WMI_BSS_BIAS_INFO; ++ ++typedef PREPACK struct WMI_LOWRSSI_SCAN_PARAMS { ++ A_UINT16 lowrssi_scan_period; ++ A_INT16 lowrssi_scan_threshold; ++ A_INT16 lowrssi_roam_threshold; ++ A_UINT8 roam_rssi_floor; ++ A_UINT8 reserved[1]; /* For alignment */ ++} POSTPACK WMI_LOWRSSI_SCAN_PARAMS; ++ ++typedef PREPACK struct { ++ PREPACK union { ++ A_UINT8 bssid[ATH_MAC_LEN]; /* WMI_FORCE_ROAM */ ++ A_UINT8 roamMode; /* WMI_SET_ROAM_MODE */ ++ WMI_BSS_BIAS_INFO bssBiasInfo; /* WMI_SET_HOST_BIAS */ ++ WMI_LOWRSSI_SCAN_PARAMS lrScanParams; ++ } POSTPACK info; ++ A_UINT8 roamCtrlType ; ++} POSTPACK WMI_SET_ROAM_CTRL_CMD; ++ ++/* ++ * WMI_ENABLE_RM_CMDID ++ */ ++typedef PREPACK struct { ++ A_BOOL enable_radio_measurements; ++} POSTPACK WMI_ENABLE_RM_CMD; ++ ++/* ++ * WMI_SET_MAX_OFFHOME_DURATION_CMDID ++ */ ++typedef PREPACK struct { ++ A_UINT8 max_offhome_duration; ++} POSTPACK WMI_SET_MAX_OFFHOME_DURATION_CMD; ++ ++typedef PREPACK struct { ++ A_UINT32 frequency; ++ A_UINT8 threshold; ++} POSTPACK WMI_SET_HB_CHALLENGE_RESP_PARAMS_CMD; ++ ++typedef enum { ++ BT_STREAM_UNDEF = 0, ++ BT_STREAM_SCO, /* SCO stream */ ++ BT_STREAM_A2DP, /* A2DP stream */ ++ BT_STREAM_MAX ++} BT_STREAM_TYPE; ++ ++typedef enum { ++ BT_PARAM_SCO = 1, /* SCO stream parameters */ ++ BT_PARAM_A2DP, /* A2DP stream parameters */ ++ BT_PARAM_MISC, /* miscellaneous parameters */ ++ BT_PARAM_REGS, /* co-existence register parameters */ ++ BT_PARAM_MAX ++} BT_PARAM_TYPE; ++ ++typedef enum { ++ BT_STATUS_UNDEF = 0, ++ BT_STATUS_START, ++ BT_STATUS_STOP, ++ BT_STATUS_RESUME, ++ BT_STATUS_SUSPEND, ++ BT_STATUS_MAX ++} BT_STREAM_STATUS; ++ ++typedef PREPACK struct { ++ A_UINT8 streamType; ++ A_UINT8 status; ++} POSTPACK WMI_SET_BT_STATUS_CMD; ++ ++typedef PREPACK struct { ++ A_UINT8 noSCOPkts; ++ A_UINT8 pspollTimeout; ++ A_UINT8 stompbt; ++} POSTPACK BT_PARAMS_SCO; ++ ++typedef PREPACK struct { ++ A_UINT32 period; ++ A_UINT32 dutycycle; ++ A_UINT8 stompbt; ++} POSTPACK BT_PARAMS_A2DP; ++ ++typedef PREPACK struct { ++ A_UINT32 mode; ++ A_UINT32 scoWghts; ++ A_UINT32 a2dpWghts; ++ A_UINT32 genWghts; ++ A_UINT32 mode2; ++ A_UINT8 setVal; ++} POSTPACK BT_COEX_REGS; ++ ++typedef enum { ++ WLAN_PROTECT_POLICY = 1, ++ WLAN_COEX_CTRL_FLAGS ++} BT_PARAMS_MISC_TYPE; ++ ++typedef enum { ++ WLAN_PROTECT_PER_STREAM = 0x01, /* default */ ++ WLAN_PROTECT_ANY_TX = 0x02 ++} WLAN_PROTECT_FLAGS; ++ ++ ++#define WLAN_DISABLE_COEX_IN_DISCONNECT 0x01 /* default */ ++#define WLAN_KEEP_COEX_IN_DISCONNECT 0x02 ++#define WLAN_STOMPBT_IN_DISCONNECT 0x04 ++ ++#define WLAN_DISABLE_COEX_IN_ROAM 0x10 /* default */ ++#define WLAN_KEEP_COEX_IN_ROAM 0x20 ++#define WLAN_STOMPBT_IN_ROAM 0x40 ++ ++#define WLAN_DISABLE_COEX_IN_SCAN 0x100 /* default */ ++#define WLAN_KEEP_COEX_IN_SCAN 0x200 ++#define WLAN_STOMPBT_IN_SCAN 0x400 ++ ++#define WLAN_DISABLE_COEX_BT_OFF 0x1000 /* default */ ++#define WLAN_KEEP_COEX_BT_OFF 0x2000 ++#define WLAN_STOMPBT_BT_OFF 0x4000 ++ ++typedef PREPACK struct { ++ A_UINT32 period; ++ A_UINT32 dutycycle; ++ A_UINT8 stompbt; ++ A_UINT8 policy; ++} POSTPACK WLAN_PROTECT_POLICY_TYPE; ++ ++typedef PREPACK struct { ++ PREPACK union { ++ WLAN_PROTECT_POLICY_TYPE protectParams; ++ A_UINT16 wlanCtrlFlags; ++ } POSTPACK info; ++ A_UINT8 paramType; ++} POSTPACK BT_PARAMS_MISC; ++ ++typedef PREPACK struct { ++ PREPACK union { ++ BT_PARAMS_SCO scoParams; ++ BT_PARAMS_A2DP a2dpParams; ++ BT_PARAMS_MISC miscParams; ++ BT_COEX_REGS regs; ++ } POSTPACK info; ++ A_UINT8 paramType; ++} POSTPACK WMI_SET_BT_PARAMS_CMD; ++ ++/* ++ * Command Replies ++ */ ++ ++/* ++ * WMI_GET_CHANNEL_LIST_CMDID reply ++ */ ++typedef PREPACK struct { ++ A_UINT8 reserved1; ++ A_UINT8 numChannels; /* number of channels in reply */ ++ A_UINT16 channelList[1]; /* channel in Mhz */ ++} POSTPACK WMI_CHANNEL_LIST_REPLY; ++ ++typedef enum { ++ A_SUCCEEDED = A_OK, ++ A_FAILED_DELETE_STREAM_DOESNOT_EXIST=250, ++ A_SUCCEEDED_MODIFY_STREAM=251, ++ A_FAILED_INVALID_STREAM = 252, ++ A_FAILED_MAX_THINSTREAMS = 253, ++ A_FAILED_CREATE_REMOVE_PSTREAM_FIRST = 254, ++} PSTREAM_REPLY_STATUS; ++ ++/* ++ * List of Events (target to host) ++ */ ++typedef enum { ++ WMI_READY_EVENTID = 0x1001, ++ WMI_CONNECT_EVENTID, ++ WMI_DISCONNECT_EVENTID, ++ WMI_BSSINFO_EVENTID, ++ WMI_CMDERROR_EVENTID, ++ WMI_REGDOMAIN_EVENTID, ++ WMI_PSTREAM_TIMEOUT_EVENTID, ++ WMI_NEIGHBOR_REPORT_EVENTID, ++ WMI_TKIP_MICERR_EVENTID, ++ WMI_SCAN_COMPLETE_EVENTID, ++ WMI_REPORT_STATISTICS_EVENTID, ++ WMI_RSSI_THRESHOLD_EVENTID, ++ WMI_ERROR_REPORT_EVENTID, ++ WMI_OPT_RX_FRAME_EVENTID, ++ WMI_REPORT_ROAM_TBL_EVENTID, ++ WMI_EXTENSION_EVENTID, ++ WMI_CAC_EVENTID, ++ WMI_SNR_THRESHOLD_EVENTID, ++ WMI_LQ_THRESHOLD_EVENTID, ++ WMI_TX_RETRY_ERR_EVENTID, ++ WMI_REPORT_ROAM_DATA_EVENTID, ++ WMI_TEST_EVENTID, ++ WMI_APLIST_EVENTID, ++ WMI_GET_WOW_LIST_EVENTID, ++ WMI_GET_PMKID_LIST_EVENTID ++} WMI_EVENT_ID; ++ ++typedef enum { ++ WMI_11A_CAPABILITY = 1, ++ WMI_11G_CAPABILITY = 2, ++ WMI_11AG_CAPABILITY = 3, ++} WMI_PHY_CAPABILITY; ++ ++typedef PREPACK struct { ++ A_UINT8 macaddr[ATH_MAC_LEN]; ++ A_UINT8 phyCapability; /* WMI_PHY_CAPABILITY */ ++} POSTPACK WMI_READY_EVENT; ++ ++/* ++ * Connect Event ++ */ ++typedef PREPACK struct { ++ A_UINT16 channel; ++ A_UINT8 bssid[ATH_MAC_LEN]; ++ A_UINT16 listenInterval; ++ A_UINT16 beaconInterval; ++ A_UINT32 networkType; ++ A_UINT8 beaconIeLen; ++ A_UINT8 assocReqLen; ++ A_UINT8 assocRespLen; ++ A_UINT8 assocInfo[1]; ++} POSTPACK WMI_CONNECT_EVENT; ++ ++/* ++ * Disconnect Event ++ */ ++typedef enum { ++ NO_NETWORK_AVAIL = 0x01, ++ LOST_LINK = 0x02, /* bmiss */ ++ DISCONNECT_CMD = 0x03, ++ BSS_DISCONNECTED = 0x04, ++ AUTH_FAILED = 0x05, ++ ASSOC_FAILED = 0x06, ++ NO_RESOURCES_AVAIL = 0x07, ++ CSERV_DISCONNECT = 0x08, ++ INVALID_PROFILE = 0x0a, ++ DOT11H_CHANNEL_SWITCH = 0x0b, ++} WMI_DISCONNECT_REASON; ++ ++typedef PREPACK struct { ++ A_UINT16 protocolReasonStatus; /* reason code, see 802.11 spec. */ ++ A_UINT8 bssid[ATH_MAC_LEN]; /* set if known */ ++ A_UINT8 disconnectReason ; /* see WMI_DISCONNECT_REASON */ ++ A_UINT8 assocRespLen; ++ A_UINT8 assocInfo[1]; ++} POSTPACK WMI_DISCONNECT_EVENT; ++ ++/* ++ * BSS Info Event. ++ * Mechanism used to inform host of the presence and characteristic of ++ * wireless networks present. Consists of bss info header followed by ++ * the beacon or probe-response frame body. The 802.11 header is not included. ++ */ ++typedef enum { ++ BEACON_FTYPE = 0x1, ++ PROBERESP_FTYPE, ++ ACTION_MGMT_FTYPE, ++} WMI_BI_FTYPE; ++ ++enum { ++ BSS_ELEMID_CHANSWITCH = 0x01, ++ BSS_ELEMID_ATHEROS = 0x02, ++}; ++ ++typedef PREPACK struct { ++ A_UINT16 channel; ++ A_UINT8 frameType; /* see WMI_BI_FTYPE */ ++ A_UINT8 snr; ++ A_INT16 rssi; ++ A_UINT8 bssid[ATH_MAC_LEN]; ++ A_UINT32 ieMask; ++} POSTPACK WMI_BSS_INFO_HDR; ++ ++/* ++ * Command Error Event ++ */ ++typedef enum { ++ INVALID_PARAM = 0x01, ++ ILLEGAL_STATE = 0x02, ++ INTERNAL_ERROR = 0x03, ++} WMI_ERROR_CODE; ++ ++typedef PREPACK struct { ++ A_UINT16 commandId; ++ A_UINT8 errorCode; ++} POSTPACK WMI_CMD_ERROR_EVENT; ++ ++/* ++ * New Regulatory Domain Event ++ */ ++typedef PREPACK struct { ++ A_UINT32 regDomain; ++} POSTPACK WMI_REG_DOMAIN_EVENT; ++ ++typedef PREPACK struct { ++ A_UINT8 trafficClass; ++} POSTPACK WMI_PSTREAM_TIMEOUT_EVENT; ++ ++/* ++ * The WMI_NEIGHBOR_REPORT Event is generated by the target to inform ++ * the host of BSS's it has found that matches the current profile. ++ * It can be used by the host to cache PMKs and/to initiate pre-authentication ++ * if the BSS supports it. The first bssid is always the current associated ++ * BSS. ++ * The bssid and bssFlags information repeats according to the number ++ * or APs reported. ++ */ ++typedef enum { ++ WMI_DEFAULT_BSS_FLAGS = 0x00, ++ WMI_PREAUTH_CAPABLE_BSS = 0x01, ++ WMI_PMKID_VALID_BSS = 0x02, ++} WMI_BSS_FLAGS; ++ ++typedef PREPACK struct { ++ A_UINT8 bssid[ATH_MAC_LEN]; ++ A_UINT8 bssFlags; /* see WMI_BSS_FLAGS */ ++} POSTPACK WMI_NEIGHBOR_INFO; ++ ++typedef PREPACK struct { ++ A_INT8 numberOfAps; ++ WMI_NEIGHBOR_INFO neighbor[1]; ++} POSTPACK WMI_NEIGHBOR_REPORT_EVENT; ++ ++/* ++ * TKIP MIC Error Event ++ */ ++typedef PREPACK struct { ++ A_UINT8 keyid; ++ A_UINT8 ismcast; ++} POSTPACK WMI_TKIP_MICERR_EVENT; ++ ++/* ++ * WMI_SCAN_COMPLETE_EVENTID - no parameters (old), staus parameter (new) ++ */ ++typedef PREPACK struct { ++ A_STATUS status; ++} POSTPACK WMI_SCAN_COMPLETE_EVENT; ++ ++#define MAX_OPT_DATA_LEN 1400 ++ ++/* ++ * WMI_SET_ADHOC_BSSID_CMDID ++ */ ++typedef PREPACK struct { ++ A_UINT8 bssid[ATH_MAC_LEN]; ++} POSTPACK WMI_SET_ADHOC_BSSID_CMD; ++ ++/* ++ * WMI_SET_OPT_MODE_CMDID ++ */ ++typedef enum { ++ SPECIAL_OFF, ++ SPECIAL_ON, ++} OPT_MODE_TYPE; ++ ++typedef PREPACK struct { ++ A_UINT8 optMode; ++} POSTPACK WMI_SET_OPT_MODE_CMD; ++ ++/* ++ * WMI_TX_OPT_FRAME_CMDID ++ */ ++typedef enum { ++ OPT_PROBE_REQ = 0x01, ++ OPT_PROBE_RESP = 0x02, ++ OPT_CPPP_START = 0x03, ++ OPT_CPPP_STOP = 0x04, ++} WMI_OPT_FTYPE; ++ ++typedef PREPACK struct { ++ A_UINT16 optIEDataLen; ++ A_UINT8 frmType; ++ A_UINT8 dstAddr[ATH_MAC_LEN]; ++ A_UINT8 bssid[ATH_MAC_LEN]; ++ A_UINT8 reserved; /* For alignment */ ++ A_UINT8 optIEData[1]; ++} POSTPACK WMI_OPT_TX_FRAME_CMD; ++ ++/* ++ * Special frame receive Event. ++ * Mechanism used to inform host of the receiption of the special frames. ++ * Consists of special frame info header followed by special frame body. ++ * The 802.11 header is not included. ++ */ ++typedef PREPACK struct { ++ A_UINT16 channel; ++ A_UINT8 frameType; /* see WMI_OPT_FTYPE */ ++ A_INT8 snr; ++ A_UINT8 srcAddr[ATH_MAC_LEN]; ++ A_UINT8 bssid[ATH_MAC_LEN]; ++} POSTPACK WMI_OPT_RX_INFO_HDR; ++ ++/* ++ * Reporting statistics. ++ */ ++typedef PREPACK struct { ++ A_UINT32 tx_packets; ++ A_UINT32 tx_bytes; ++ A_UINT32 tx_unicast_pkts; ++ A_UINT32 tx_unicast_bytes; ++ A_UINT32 tx_multicast_pkts; ++ A_UINT32 tx_multicast_bytes; ++ A_UINT32 tx_broadcast_pkts; ++ A_UINT32 tx_broadcast_bytes; ++ A_UINT32 tx_rts_success_cnt; ++ A_UINT32 tx_packet_per_ac[4]; ++ A_UINT32 tx_errors_per_ac[4]; ++ ++ A_UINT32 tx_errors; ++ A_UINT32 tx_failed_cnt; ++ A_UINT32 tx_retry_cnt; ++ A_UINT32 tx_rts_fail_cnt; ++ A_INT32 tx_unicast_rate; ++}POSTPACK tx_stats_t; ++ ++typedef PREPACK struct { ++ A_UINT32 rx_packets; ++ A_UINT32 rx_bytes; ++ A_UINT32 rx_unicast_pkts; ++ A_UINT32 rx_unicast_bytes; ++ A_UINT32 rx_multicast_pkts; ++ A_UINT32 rx_multicast_bytes; ++ A_UINT32 rx_broadcast_pkts; ++ A_UINT32 rx_broadcast_bytes; ++ A_UINT32 rx_fragment_pkt; ++ ++ A_UINT32 rx_errors; ++ A_UINT32 rx_crcerr; ++ A_UINT32 rx_key_cache_miss; ++ A_UINT32 rx_decrypt_err; ++ A_UINT32 rx_duplicate_frames; ++ A_INT32 rx_unicast_rate; ++}POSTPACK rx_stats_t; ++ ++typedef PREPACK struct { ++ A_UINT32 tkip_local_mic_failure; ++ A_UINT32 tkip_counter_measures_invoked; ++ A_UINT32 tkip_replays; ++ A_UINT32 tkip_format_errors; ++ A_UINT32 ccmp_format_errors; ++ A_UINT32 ccmp_replays; ++}POSTPACK tkip_ccmp_stats_t; ++ ++typedef PREPACK struct { ++ A_UINT32 power_save_failure_cnt; ++}POSTPACK pm_stats_t; ++ ++typedef PREPACK struct { ++ A_UINT32 cs_bmiss_cnt; ++ A_UINT32 cs_lowRssi_cnt; ++ A_UINT16 cs_connect_cnt; ++ A_UINT16 cs_disconnect_cnt; ++ A_INT16 cs_aveBeacon_rssi; ++ A_UINT16 cs_roam_count; ++ A_UINT16 cs_rssi; ++ A_UINT8 cs_snr; ++ A_UINT8 cs_aveBeacon_snr; ++ A_UINT8 cs_lastRoam_msec; ++} POSTPACK cserv_stats_t; ++ ++typedef PREPACK struct { ++ tx_stats_t tx_stats; ++ rx_stats_t rx_stats; ++ tkip_ccmp_stats_t tkipCcmpStats; ++}POSTPACK wlan_net_stats_t; ++ ++typedef PREPACK struct { ++ A_UINT32 wow_num_pkts_dropped; ++ A_UINT16 wow_num_events_discarded; ++ A_UINT8 wow_num_host_pkt_wakeups; ++ A_UINT8 wow_num_host_event_wakeups; ++} POSTPACK wlan_wow_stats_t; ++ ++typedef PREPACK struct { ++ A_UINT32 lqVal; ++ A_INT32 noise_floor_calibation; ++ pm_stats_t pmStats; ++ wlan_net_stats_t txrxStats; ++ wlan_wow_stats_t wowStats; ++ cserv_stats_t cservStats; ++} POSTPACK WMI_TARGET_STATS; ++ ++/* ++ * WMI_RSSI_THRESHOLD_EVENTID. ++ * Indicate the RSSI events to host. Events are indicated when we breach a ++ * thresold value. ++ */ ++typedef enum{ ++ WMI_RSSI_THRESHOLD1_ABOVE = 0, ++ WMI_RSSI_THRESHOLD2_ABOVE, ++ WMI_RSSI_THRESHOLD3_ABOVE, ++ WMI_RSSI_THRESHOLD4_ABOVE, ++ WMI_RSSI_THRESHOLD5_ABOVE, ++ WMI_RSSI_THRESHOLD6_ABOVE, ++ WMI_RSSI_THRESHOLD1_BELOW, ++ WMI_RSSI_THRESHOLD2_BELOW, ++ WMI_RSSI_THRESHOLD3_BELOW, ++ WMI_RSSI_THRESHOLD4_BELOW, ++ WMI_RSSI_THRESHOLD5_BELOW, ++ WMI_RSSI_THRESHOLD6_BELOW ++}WMI_RSSI_THRESHOLD_VAL; ++ ++typedef PREPACK struct { ++ A_INT16 rssi; ++ A_UINT8 range; ++}POSTPACK WMI_RSSI_THRESHOLD_EVENT; ++ ++/* ++ * WMI_ERROR_REPORT_EVENTID ++ */ ++typedef enum{ ++ WMI_TARGET_PM_ERR_FAIL = 0x00000001, ++ WMI_TARGET_KEY_NOT_FOUND = 0x00000002, ++ WMI_TARGET_DECRYPTION_ERR = 0x00000004, ++ WMI_TARGET_BMISS = 0x00000008, ++ WMI_PSDISABLE_NODE_JOIN = 0x00000010, ++ WMI_TARGET_COM_ERR = 0x00000020, ++ WMI_TARGET_FATAL_ERR = 0x00000040 ++} WMI_TARGET_ERROR_VAL; ++ ++typedef PREPACK struct { ++ A_UINT32 errorVal; ++}POSTPACK WMI_TARGET_ERROR_REPORT_EVENT; ++ ++typedef PREPACK struct { ++ A_UINT8 retrys; ++}POSTPACK WMI_TX_RETRY_ERR_EVENT; ++ ++typedef enum{ ++ WMI_SNR_THRESHOLD1_ABOVE = 1, ++ WMI_SNR_THRESHOLD1_BELOW, ++ WMI_SNR_THRESHOLD2_ABOVE, ++ WMI_SNR_THRESHOLD2_BELOW, ++ WMI_SNR_THRESHOLD3_ABOVE, ++ WMI_SNR_THRESHOLD3_BELOW, ++ WMI_SNR_THRESHOLD4_ABOVE, ++ WMI_SNR_THRESHOLD4_BELOW ++} WMI_SNR_THRESHOLD_VAL; ++ ++typedef PREPACK struct { ++ A_UINT8 range; /* WMI_SNR_THRESHOLD_VAL */ ++ A_UINT8 snr; ++}POSTPACK WMI_SNR_THRESHOLD_EVENT; ++ ++typedef enum{ ++ WMI_LQ_THRESHOLD1_ABOVE = 1, ++ WMI_LQ_THRESHOLD1_BELOW, ++ WMI_LQ_THRESHOLD2_ABOVE, ++ WMI_LQ_THRESHOLD2_BELOW, ++ WMI_LQ_THRESHOLD3_ABOVE, ++ WMI_LQ_THRESHOLD3_BELOW, ++ WMI_LQ_THRESHOLD4_ABOVE, ++ WMI_LQ_THRESHOLD4_BELOW ++} WMI_LQ_THRESHOLD_VAL; ++ ++typedef PREPACK struct { ++ A_INT32 lq; ++ A_UINT8 range; /* WMI_LQ_THRESHOLD_VAL */ ++}POSTPACK WMI_LQ_THRESHOLD_EVENT; ++/* ++ * WMI_REPORT_ROAM_TBL_EVENTID ++ */ ++#define MAX_ROAM_TBL_CAND 5 ++ ++typedef PREPACK struct { ++ A_INT32 roam_util; ++ A_UINT8 bssid[ATH_MAC_LEN]; ++ A_INT8 rssi; ++ A_INT8 rssidt; ++ A_INT8 last_rssi; ++ A_INT8 util; ++ A_INT8 bias; ++ A_UINT8 reserved; /* For alignment */ ++} POSTPACK WMI_BSS_ROAM_INFO; ++ ++ ++typedef PREPACK struct { ++ A_UINT16 roamMode; ++ A_UINT16 numEntries; ++ WMI_BSS_ROAM_INFO bssRoamInfo[1]; ++} POSTPACK WMI_TARGET_ROAM_TBL; ++ ++/* ++ * WMI_CAC_EVENTID ++ */ ++typedef enum { ++ CAC_INDICATION_ADMISSION = 0x00, ++ CAC_INDICATION_ADMISSION_RESP = 0x01, ++ CAC_INDICATION_DELETE = 0x02, ++ CAC_INDICATION_NO_RESP = 0x03, ++}CAC_INDICATION; ++ ++#define WMM_TSPEC_IE_LEN 63 ++ ++typedef PREPACK struct { ++ A_UINT8 ac; ++ A_UINT8 cac_indication; ++ A_UINT8 statusCode; ++ A_UINT8 tspecSuggestion[WMM_TSPEC_IE_LEN]; ++}POSTPACK WMI_CAC_EVENT; ++ ++/* ++ * WMI_APLIST_EVENTID ++ */ ++ ++typedef enum { ++ APLIST_VER1 = 1, ++} APLIST_VER; ++ ++typedef PREPACK struct { ++ A_UINT8 bssid[ATH_MAC_LEN]; ++ A_UINT16 channel; ++} POSTPACK WMI_AP_INFO_V1; ++ ++typedef PREPACK union { ++ WMI_AP_INFO_V1 apInfoV1; ++} POSTPACK WMI_AP_INFO; ++ ++typedef PREPACK struct { ++ A_UINT8 apListVer; ++ A_UINT8 numAP; ++ WMI_AP_INFO apList[1]; ++} POSTPACK WMI_APLIST_EVENT; ++ ++/* ++ * developer commands ++ */ ++ ++/* ++ * WMI_SET_BITRATE_CMDID ++ * ++ * Get bit rate cmd uses same definition as set bit rate cmd ++ */ ++typedef enum { ++ RATE_AUTO = -1, ++ RATE_1Mb = 0, ++ RATE_2Mb = 1, ++ RATE_5_5Mb = 2, ++ RATE_11Mb = 3, ++ RATE_6Mb = 4, ++ RATE_9Mb = 5, ++ RATE_12Mb = 6, ++ RATE_18Mb = 7, ++ RATE_24Mb = 8, ++ RATE_36Mb = 9, ++ RATE_48Mb = 10, ++ RATE_54Mb = 11, ++} WMI_BIT_RATE; ++ ++typedef PREPACK struct { ++ A_INT8 rateIndex; /* see WMI_BIT_RATE */ ++} POSTPACK WMI_BIT_RATE_CMD, WMI_BIT_RATE_REPLY; ++ ++/* ++ * WMI_SET_FIXRATES_CMDID ++ * ++ * Get fix rates cmd uses same definition as set fix rates cmd ++ */ ++typedef enum { ++ FIX_RATE_1Mb = 0x1, ++ FIX_RATE_2Mb = 0x2, ++ FIX_RATE_5_5Mb = 0x4, ++ FIX_RATE_11Mb = 0x8, ++ FIX_RATE_6Mb = 0x10, ++ FIX_RATE_9Mb = 0x20, ++ FIX_RATE_12Mb = 0x40, ++ FIX_RATE_18Mb = 0x80, ++ FIX_RATE_24Mb = 0x100, ++ FIX_RATE_36Mb = 0x200, ++ FIX_RATE_48Mb = 0x400, ++ FIX_RATE_54Mb = 0x800, ++} WMI_FIX_RATES_MASK; ++ ++typedef PREPACK struct { ++ A_UINT16 fixRateMask; /* see WMI_BIT_RATE */ ++} POSTPACK WMI_FIX_RATES_CMD, WMI_FIX_RATES_REPLY; ++ ++/* ++ * WMI_SET_RECONNECT_AUTH_MODE_CMDID ++ * ++ * Set authentication mode ++ */ ++typedef enum { ++ RECONN_DO_AUTH = 0x00, ++ RECONN_NOT_AUTH = 0x01 ++} WMI_AUTH_MODE; ++ ++typedef PREPACK struct { ++ A_UINT8 mode; ++} POSTPACK WMI_SET_AUTH_MODE_CMD; ++ ++/* ++ * WMI_SET_REASSOC_MODE_CMDID ++ * ++ * Set authentication mode ++ */ ++typedef enum { ++ REASSOC_DO_DISASSOC = 0x00, ++ REASSOC_DONOT_DISASSOC = 0x01 ++} WMI_REASSOC_MODE; ++ ++typedef PREPACK struct { ++ A_UINT8 mode; ++}POSTPACK WMI_SET_REASSOC_MODE_CMD; ++ ++typedef enum { ++ ROAM_DATA_TIME = 1, /* Get The Roam Time Data */ ++} ROAM_DATA_TYPE; ++ ++typedef PREPACK struct { ++ A_UINT32 disassoc_time; ++ A_UINT32 no_txrx_time; ++ A_UINT32 assoc_time; ++ A_UINT32 allow_txrx_time; ++ A_UINT32 last_data_txrx_time; ++ A_UINT32 first_data_txrx_time; ++ A_UINT8 disassoc_bssid[ATH_MAC_LEN]; ++ A_INT8 disassoc_bss_rssi; ++ A_UINT8 assoc_bssid[ATH_MAC_LEN]; ++ A_INT8 assoc_bss_rssi; ++} POSTPACK WMI_TARGET_ROAM_TIME; ++ ++typedef PREPACK struct { ++ PREPACK union { ++ WMI_TARGET_ROAM_TIME roamTime; ++ } POSTPACK u; ++ A_UINT8 roamDataType ; ++} POSTPACK WMI_TARGET_ROAM_DATA; ++ ++typedef enum { ++ WMI_WMM_DISABLED = 0, ++ WMI_WMM_ENABLED ++} WMI_WMM_STATUS; ++ ++typedef PREPACK struct { ++ A_UINT8 status; ++}POSTPACK WMI_SET_WMM_CMD; ++ ++typedef enum { ++ WMI_TXOP_DISABLED = 0, ++ WMI_TXOP_ENABLED ++} WMI_TXOP_CFG; ++ ++typedef PREPACK struct { ++ A_UINT8 txopEnable; ++}POSTPACK WMI_SET_WMM_TXOP_CMD; ++ ++typedef PREPACK struct { ++ A_UINT8 keepaliveInterval; ++} POSTPACK WMI_SET_KEEPALIVE_CMD; ++ ++typedef PREPACK struct { ++ A_BOOL configured; ++ A_UINT8 keepaliveInterval; ++} POSTPACK WMI_GET_KEEPALIVE_CMD; ++ ++/* ++ * Add Application specified IE to a management frame ++ */ ++#define WMI_MAX_IE_LEN 78 ++ ++typedef PREPACK struct { ++ A_UINT8 mgmtFrmType; /* one of WMI_MGMT_FRAME_TYPE */ ++ A_UINT8 ieLen; /* Length of the IE that should be added to the MGMT frame */ ++ A_UINT8 ieInfo[1]; ++} POSTPACK WMI_SET_APPIE_CMD; ++ ++/* ++ * Notify the WSC registration status to the target ++ */ ++#define WSC_REG_ACTIVE 1 ++#define WSC_REG_INACTIVE 0 ++/* Generic Hal Interface for setting hal paramters. */ ++/* Add new Set HAL Param cmdIds here for newer params */ ++typedef enum { ++ WHAL_SETCABTO_CMDID = 1, ++}WHAL_CMDID; ++ ++typedef PREPACK struct { ++ A_UINT8 cabTimeOut; ++} POSTPACK WHAL_SETCABTO_PARAM; ++ ++typedef PREPACK struct { ++ A_UINT8 whalCmdId; ++ A_UINT8 data[1]; ++} POSTPACK WHAL_PARAMCMD; ++ ++ ++#define WOW_MAX_FILTER_LISTS 1 /*4*/ ++#define WOW_MAX_FILTERS_PER_LIST 4 ++#define WOW_PATTERN_SIZE 64 ++#define WOW_MASK_SIZE 64 ++ ++typedef PREPACK struct { ++ A_UINT8 wow_valid_filter; ++ A_UINT8 wow_filter_id; ++ A_UINT8 wow_filter_size; ++ A_UINT8 wow_filter_offset; ++ A_UINT8 wow_filter_mask[WOW_MASK_SIZE]; ++ A_UINT8 wow_filter_pattern[WOW_PATTERN_SIZE]; ++} POSTPACK WOW_FILTER; ++ ++ ++typedef PREPACK struct { ++ A_UINT8 wow_valid_list; ++ A_UINT8 wow_list_id; ++ A_UINT8 wow_num_filters; ++ A_UINT8 wow_total_list_size; ++ WOW_FILTER list[WOW_MAX_FILTERS_PER_LIST]; ++} POSTPACK WOW_FILTER_LIST; ++ ++typedef PREPACK struct { ++ A_BOOL awake; ++ A_BOOL asleep; ++} POSTPACK WMI_SET_HOST_SLEEP_MODE_CMD; ++ ++typedef PREPACK struct { ++ A_BOOL enable_wow; ++} POSTPACK WMI_SET_WOW_MODE_CMD; ++ ++typedef PREPACK struct { ++ A_UINT8 filter_list_id; ++} POSTPACK WMI_GET_WOW_LIST_CMD; ++ ++/* ++ * WMI_GET_WOW_LIST_CMD reply ++ */ ++typedef PREPACK struct { ++ A_UINT8 num_filters; /* number of patterns in reply */ ++ A_UINT8 this_filter_num; /* this is filter # x of total num_filters */ ++ A_UINT8 wow_mode; ++ A_UINT8 host_mode; ++ WOW_FILTER wow_filters[1]; ++} POSTPACK WMI_GET_WOW_LIST_REPLY; ++ ++typedef PREPACK struct { ++ A_UINT8 filter_list_id; ++ A_UINT8 filter_size; ++ A_UINT8 filter_offset; ++ A_UINT8 filter[1]; ++} POSTPACK WMI_ADD_WOW_PATTERN_CMD; ++ ++typedef PREPACK struct { ++ A_UINT16 filter_list_id; ++ A_UINT16 filter_id; ++} POSTPACK WMI_DEL_WOW_PATTERN_CMD; ++ ++typedef PREPACK struct { ++ A_UINT8 macaddr[ATH_MAC_LEN]; ++} POSTPACK WMI_SET_MAC_ADDRESS_CMD; ++ ++/* ++ * WMI_SET_AKMP_PARAMS_CMD ++ */ ++ ++#define WMI_AKMP_MULTI_PMKID_EN 0x000001 ++ ++typedef PREPACK struct { ++ A_UINT32 akmpInfo; ++} POSTPACK WMI_SET_AKMP_PARAMS_CMD; ++ ++typedef PREPACK struct { ++ A_UINT8 pmkid[WMI_PMKID_LEN]; ++} POSTPACK WMI_PMKID; ++ ++/* ++ * WMI_SET_PMKID_LIST_CMD ++ */ ++#define WMI_MAX_PMKID_CACHE 8 ++ ++typedef PREPACK struct { ++ A_UINT32 numPMKID; ++ WMI_PMKID pmkidList[WMI_MAX_PMKID_CACHE]; ++} POSTPACK WMI_SET_PMKID_LIST_CMD; ++ ++/* ++ * WMI_GET_PMKID_LIST_CMD Reply ++ * Following the Number of PMKIDs is the list of PMKIDs ++ */ ++typedef PREPACK struct { ++ A_UINT32 numPMKID; ++ WMI_PMKID pmkidList[1]; ++} POSTPACK WMI_PMKID_LIST_REPLY; ++ ++/* index used for priority streams */ ++typedef enum { ++ WMI_NOT_MAPPED = -1, ++ WMI_CONTROL_PRI = 0, ++ WMI_BEST_EFFORT_PRI = 1, ++ WMI_LOW_PRI = 2, ++ WMI_HIGH_PRI = 3, ++ WMI_HIGHEST_PRI, ++ WMI_PRI_MAX_COUNT ++} WMI_PRI_STREAM_ID; ++ ++#ifndef ATH_TARGET ++#include "athendpack.h" ++#endif ++ ++#ifdef __cplusplus ++} ++#endif ++ ++#endif /* _WMI_H_ */ +diff -ruN --exclude='*.orig' --exclude='*.rej' linux-2.6.29-rc3.owrt/drivers/ar6000/include/wmix.h linux-2.6.29-rc3.owrt.om/drivers/ar6000/include/wmix.h +--- linux-2.6.29-rc3.owrt/drivers/ar6000/include/wmix.h 1970-01-01 01:00:00.000000000 +0100 ++++ linux-2.6.29-rc3.owrt.om/drivers/ar6000/include/wmix.h 2009-05-10 22:27:59.000000000 +0200 +@@ -0,0 +1,233 @@ ++/* ++ * Copyright (c) 2004-2005 Atheros Communications Inc. ++ * All rights reserved. ++ * ++ * ++ * $ATH_LICENSE_HOSTSDK0_C$ ++ * ++ * This file contains extensions of the WMI protocol specified in the ++ * Wireless Module Interface (WMI). It includes definitions of all ++ * extended commands and events. Extensions include useful commands ++ * that are not directly related to wireless activities. They may ++ * be hardware-specific, and they might not be supported on all ++ * implementations. ++ * ++ * Extended WMIX commands are encapsulated in a WMI message with ++ * cmd=WMI_EXTENSION_CMD. ++ * ++ */ ++ ++#ifndef _WMIX_H_ ++#define _WMIX_H_ ++ ++#ifdef __cplusplus ++extern "C" { ++#endif ++ ++#ifndef ATH_TARGET ++#include "athstartpack.h" ++#endif ++ ++#include "dbglog.h" ++ ++/* ++ * Extended WMI commands are those that are needed during wireless ++ * operation, but which are not really wireless commands. This allows, ++ * for instance, platform-specific commands. Extended WMI commands are ++ * embedded in a WMI command message with WMI_COMMAND_ID=WMI_EXTENSION_CMDID. ++ * Extended WMI events are similarly embedded in a WMI event message with ++ * WMI_EVENT_ID=WMI_EXTENSION_EVENTID. ++ */ ++typedef PREPACK struct { ++ A_UINT32 commandId; ++} POSTPACK WMIX_CMD_HDR; ++ ++typedef enum { ++ WMIX_DSETOPEN_REPLY_CMDID = 0x2001, ++ WMIX_DSETDATA_REPLY_CMDID, ++ WMIX_GPIO_OUTPUT_SET_CMDID, ++ WMIX_GPIO_INPUT_GET_CMDID, ++ WMIX_GPIO_REGISTER_SET_CMDID, ++ WMIX_GPIO_REGISTER_GET_CMDID, ++ WMIX_GPIO_INTR_ACK_CMDID, ++ WMIX_HB_CHALLENGE_RESP_CMDID, ++ WMIX_DBGLOG_CFG_MODULE_CMDID, ++} WMIX_COMMAND_ID; ++ ++typedef enum { ++ WMIX_DSETOPENREQ_EVENTID = 0x3001, ++ WMIX_DSETCLOSE_EVENTID, ++ WMIX_DSETDATAREQ_EVENTID, ++ WMIX_GPIO_INTR_EVENTID, ++ WMIX_GPIO_DATA_EVENTID, ++ WMIX_GPIO_ACK_EVENTID, ++ WMIX_HB_CHALLENGE_RESP_EVENTID, ++ WMIX_DBGLOG_EVENTID, ++} WMIX_EVENT_ID; ++ ++/* ++ * =============DataSet support================= ++ */ ++ ++/* ++ * WMIX_DSETOPENREQ_EVENTID ++ * DataSet Open Request Event ++ */ ++typedef PREPACK struct { ++ A_UINT32 dset_id; ++ A_UINT32 targ_dset_handle; /* echo'ed, not used by Host, */ ++ A_UINT32 targ_reply_fn; /* echo'ed, not used by Host, */ ++ A_UINT32 targ_reply_arg; /* echo'ed, not used by Host, */ ++} POSTPACK WMIX_DSETOPENREQ_EVENT; ++ ++/* ++ * WMIX_DSETCLOSE_EVENTID ++ * DataSet Close Event ++ */ ++typedef PREPACK struct { ++ A_UINT32 access_cookie; ++} POSTPACK WMIX_DSETCLOSE_EVENT; ++ ++/* ++ * WMIX_DSETDATAREQ_EVENTID ++ * DataSet Data Request Event ++ */ ++typedef PREPACK struct { ++ A_UINT32 access_cookie; ++ A_UINT32 offset; ++ A_UINT32 length; ++ A_UINT32 targ_buf; /* echo'ed, not used by Host, */ ++ A_UINT32 targ_reply_fn; /* echo'ed, not used by Host, */ ++ A_UINT32 targ_reply_arg; /* echo'ed, not used by Host, */ ++} POSTPACK WMIX_DSETDATAREQ_EVENT; ++ ++typedef PREPACK struct { ++ A_UINT32 status; ++ A_UINT32 targ_dset_handle; ++ A_UINT32 targ_reply_fn; ++ A_UINT32 targ_reply_arg; ++ A_UINT32 access_cookie; ++ A_UINT32 size; ++ A_UINT32 version; ++} POSTPACK WMIX_DSETOPEN_REPLY_CMD; ++ ++typedef PREPACK struct { ++ A_UINT32 status; ++ A_UINT32 targ_buf; ++ A_UINT32 targ_reply_fn; ++ A_UINT32 targ_reply_arg; ++ A_UINT32 length; ++ A_UINT8 buf[1]; ++} POSTPACK WMIX_DSETDATA_REPLY_CMD; ++ ++ ++/* ++ * =============GPIO support================= ++ * All masks are 18-bit masks with bit N operating on GPIO pin N. ++ */ ++ ++#include "gpio.h" ++ ++/* ++ * Set GPIO pin output state. ++ * In order for output to be driven, a pin must be enabled for output. ++ * This can be done during initialization through the GPIO Configuration ++ * DataSet, or during operation with the enable_mask. ++ * ++ * If a request is made to simultaneously set/clear or set/disable or ++ * clear/disable or disable/enable, results are undefined. ++ */ ++typedef PREPACK struct { ++ A_UINT32 set_mask; /* pins to set */ ++ A_UINT32 clear_mask; /* pins to clear */ ++ A_UINT32 enable_mask; /* pins to enable for output */ ++ A_UINT32 disable_mask; /* pins to disable/tristate */ ++} POSTPACK WMIX_GPIO_OUTPUT_SET_CMD; ++ ++/* ++ * Set a GPIO register. For debug/exceptional cases. ++ * Values for gpioreg_id are GPIO_REGISTER_IDs, defined in a ++ * platform-dependent header. ++ */ ++typedef PREPACK struct { ++ A_UINT32 gpioreg_id; /* GPIO register ID */ ++ A_UINT32 value; /* value to write */ ++} POSTPACK WMIX_GPIO_REGISTER_SET_CMD; ++ ++/* Get a GPIO register. For debug/exceptional cases. */ ++typedef PREPACK struct { ++ A_UINT32 gpioreg_id; /* GPIO register to read */ ++} POSTPACK WMIX_GPIO_REGISTER_GET_CMD; ++ ++/* ++ * Host acknowledges and re-arms GPIO interrupts. A single ++ * message should be used to acknowledge all interrupts that ++ * were delivered in an earlier WMIX_GPIO_INTR_EVENT message. ++ */ ++typedef PREPACK struct { ++ A_UINT32 ack_mask; /* interrupts to acknowledge */ ++} POSTPACK WMIX_GPIO_INTR_ACK_CMD; ++ ++/* ++ * Target informs Host of GPIO interrupts that have ocurred since the ++ * last WMIX_GIPO_INTR_ACK_CMD was received. Additional information -- ++ * the current GPIO input values is provided -- in order to support ++ * use of a GPIO interrupt as a Data Valid signal for other GPIO pins. ++ */ ++typedef PREPACK struct { ++ A_UINT32 intr_mask; /* pending GPIO interrupts */ ++ A_UINT32 input_values; /* recent GPIO input values */ ++} POSTPACK WMIX_GPIO_INTR_EVENT; ++ ++/* ++ * Target responds to Host's earlier WMIX_GPIO_INPUT_GET_CMDID request ++ * using a GPIO_DATA_EVENT with ++ * value set to the mask of GPIO pin inputs and ++ * reg_id set to GPIO_ID_NONE ++ * ++ * ++ * Target responds to Hosts's earlier WMIX_GPIO_REGISTER_GET_CMDID request ++ * using a GPIO_DATA_EVENT with ++ * value set to the value of the requested register and ++ * reg_id identifying the register (reflects the original request) ++ * NB: reg_id supports the future possibility of unsolicited ++ * WMIX_GPIO_DATA_EVENTs (for polling GPIO input), and it may ++ * simplify Host GPIO support. ++ */ ++typedef PREPACK struct { ++ A_UINT32 value; ++ A_UINT32 reg_id; ++} POSTPACK WMIX_GPIO_DATA_EVENT; ++ ++/* ++ * =============Error Detection support================= ++ */ ++ ++/* ++ * WMIX_HB_CHALLENGE_RESP_CMDID ++ * Heartbeat Challenge Response command ++ */ ++typedef PREPACK struct { ++ A_UINT32 cookie; ++ A_UINT32 source; ++} POSTPACK WMIX_HB_CHALLENGE_RESP_CMD; ++ ++/* ++ * WMIX_HB_CHALLENGE_RESP_EVENTID ++ * Heartbeat Challenge Response Event ++ */ ++#define WMIX_HB_CHALLENGE_RESP_EVENT WMIX_HB_CHALLENGE_RESP_CMD ++ ++typedef PREPACK struct { ++ struct dbglog_config_s config; ++} POSTPACK WMIX_DBGLOG_CFG_MODULE_CMD; ++ ++#ifndef ATH_TARGET ++#include "athendpack.h" ++#endif ++ ++#ifdef __cplusplus ++} ++#endif ++ ++#endif /* _WMIX_H_ */ +diff -ruN --exclude='*.orig' --exclude='*.rej' linux-2.6.29-rc3.owrt/drivers/ar6000/Kconfig linux-2.6.29-rc3.owrt.om/drivers/ar6000/Kconfig +--- linux-2.6.29-rc3.owrt/drivers/ar6000/Kconfig 1970-01-01 01:00:00.000000000 +0100 ++++ linux-2.6.29-rc3.owrt.om/drivers/ar6000/Kconfig 2009-05-10 22:27:59.000000000 +0200 +@@ -0,0 +1,31 @@ ++config AR6000_WLAN ++ tristate "AR6000 wireless networking over SDIO" ++ depends on MMC ++ select WIRELESS_EXT ++ default m ++ help ++ good luck. ++ ++config AR6000_WLAN_DEBUG ++ bool "Enable retrieval of firmware debugging information" ++ depends on AR6000_WLAN ++ default n ++ help ++ The AR6k firmware maintains a log of debugging events that ++ gets flushed to the host on various occasions. Retrieval of ++ this data is very slow, taking several seconds. ++ ++ If in doubt, say N. ++ ++config AR6000_WLAN_RESET ++ bool "Soft-reset when shutting down" ++ depends on AR6000_WLAN ++ default n ++ help ++ The AR6k module can be explicitly reset when shutting down ++ the device. This adds a delay of about two seconds to suspend, ++ module removal, and so on. Since the WLAN SDIO function is ++ generally disabled soon thereafter anyway, this reset seems ++ superfluous. ++ ++ If in doubt, say N. +diff -ruN --exclude='*.orig' --exclude='*.rej' linux-2.6.29-rc3.owrt/drivers/ar6000/Makefile linux-2.6.29-rc3.owrt.om/drivers/ar6000/Makefile +--- linux-2.6.29-rc3.owrt/drivers/ar6000/Makefile 1970-01-01 01:00:00.000000000 +0100 ++++ linux-2.6.29-rc3.owrt.om/drivers/ar6000/Makefile 2009-05-10 22:27:59.000000000 +0200 +@@ -0,0 +1,38 @@ ++REV ?= 2 ++ ++PWD := $(shell pwd) ++ ++EXTRA_CFLAGS += -I$(src)/include ++ ++EXTRA_CFLAGS += -DLINUX -D__KERNEL__ -DHTC_RAW_INTERFACE\ ++ -DTCMD -DUSER_KEYS \ ++ -DNO_SYNC_FLUSH #\ ++ -DMULTIPLE_FRAMES_PER_INTERRUPT -DAR6000REV$(REV) \ ++ -DBLOCK_TX_PATH_FLAG \ ++ -DSDIO \ ++ ++EXTRA_CFLAGS += -DKERNEL_2_6 ++ ++obj-$(CONFIG_AR6000_WLAN) += ar6000.o ++ ++ar6000-objs += htc/ar6k.o \ ++ htc/ar6k_events.o \ ++ htc/htc_send.o \ ++ htc/htc_recv.o \ ++ htc/htc_services.o \ ++ htc/htc.o \ ++ hif/hif2.o \ ++ bmi/bmi.o \ ++ ar6000/ar6000_drv.o \ ++ ar6000/ar6000_raw_if.o \ ++ ar6000/netbuf.o \ ++ ar6000/wireless_ext.o \ ++ ar6000/ioctl.o \ ++ miscdrv/common_drv.o \ ++ miscdrv/credit_dist.o \ ++ wmi/wmi.o \ ++ wlan/wlan_node.o \ ++ wlan/wlan_recv_beacon.o \ ++ wlan/wlan_utils.o ++ ++ +diff -ruN --exclude='*.orig' --exclude='*.rej' linux-2.6.29-rc3.owrt/drivers/ar6000/miscdrv/common_drv.c linux-2.6.29-rc3.owrt.om/drivers/ar6000/miscdrv/common_drv.c +--- linux-2.6.29-rc3.owrt/drivers/ar6000/miscdrv/common_drv.c 1970-01-01 01:00:00.000000000 +0100 ++++ linux-2.6.29-rc3.owrt.om/drivers/ar6000/miscdrv/common_drv.c 2009-05-10 22:27:59.000000000 +0200 +@@ -0,0 +1,467 @@ ++ ++/* ++ * ++ * Copyright (c) 2004-2007 Atheros Communications Inc. ++ * All rights reserved. ++ * ++ * ++ * 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; ++ * ++ * Software distributed under the License is distributed on an "AS ++ * IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or ++ * implied. See the License for the specific language governing ++ * rights and limitations under the License. ++ * ++ * ++ * ++ */ ++ ++#include "a_config.h" ++#include "athdefs.h" ++#include "a_types.h" ++#include "AR6Khwreg.h" ++#include "targaddrs.h" ++#include "a_osapi.h" ++#include "hif.h" ++#include "htc_api.h" ++#include "bmi.h" ++#include "bmi_msg.h" ++#include "common_drv.h" ++#include "a_debug.h" ++#include "targaddrs.h" ++ ++#define HOST_INTEREST_ITEM_ADDRESS(target, item) \ ++(((TargetType) == TARGET_TYPE_AR6001) ? \ ++ AR6001_HOST_INTEREST_ITEM_ADDRESS(item) : \ ++ AR6002_HOST_INTEREST_ITEM_ADDRESS(item)) ++ ++ ++/* Compile the 4BYTE version of the window register setup routine, ++ * This mitigates host interconnect issues with non-4byte aligned bus requests, some ++ * interconnects use bus adapters that impose strict limitations. ++ * Since diag window access is not intended for performance critical operations, the 4byte mode should ++ * be satisfactory even though it generates 4X the bus activity. */ ++ ++#ifdef USE_4BYTE_REGISTER_ACCESS ++ ++ /* set the window address register (using 4-byte register access ). */ ++A_STATUS ar6000_SetAddressWindowRegister(HIF_DEVICE *hifDevice, A_UINT32 RegisterAddr, A_UINT32 Address) ++{ ++ A_STATUS status; ++ A_UINT8 addrValue[4]; ++ int i; ++ ++ /* write bytes 1,2,3 of the register to set the upper address bytes, the LSB is written ++ * last to initiate the access cycle */ ++ ++ for (i = 1; i <= 3; i++) { ++ /* fill the buffer with the address byte value we want to hit 4 times*/ ++ addrValue[0] = ((A_UINT8 *)&Address)[i]; ++ addrValue[1] = addrValue[0]; ++ addrValue[2] = addrValue[0]; ++ addrValue[3] = addrValue[0]; ++ ++ /* hit each byte of the register address with a 4-byte write operation to the same address, ++ * this is a harmless operation */ ++ status = HIFReadWrite(hifDevice, ++ RegisterAddr+i, ++ addrValue, ++ 4, ++ HIF_WR_SYNC_BYTE_FIX, ++ NULL); ++ if (status != A_OK) { ++ break; ++ } ++ } ++ ++ if (status != A_OK) { ++ AR_DEBUG_PRINTF(ATH_LOG_ERR, ("Cannot write initial bytes of 0x%x to window reg: 0x%X \n", ++ RegisterAddr, Address)); ++ return status; ++ } ++ ++ /* write the address register again, this time write the whole 4-byte value. ++ * The effect here is that the LSB write causes the cycle to start, the extra ++ * 3 byte write to bytes 1,2,3 has no effect since we are writing the same values again */ ++ status = HIFReadWrite(hifDevice, ++ RegisterAddr, ++ (A_UCHAR *)(&Address), ++ 4, ++ HIF_WR_SYNC_BYTE_INC, ++ NULL); ++ ++ if (status != A_OK) { ++ AR_DEBUG_PRINTF(ATH_LOG_ERR, ("Cannot write 0x%x to window reg: 0x%X \n", ++ RegisterAddr, Address)); ++ return status; ++ } ++ ++ return A_OK; ++ ++ ++ ++} ++ ++ ++#else ++ ++ /* set the window address register */ ++A_STATUS ar6000_SetAddressWindowRegister(HIF_DEVICE *hifDevice, A_UINT32 RegisterAddr, A_UINT32 Address) ++{ ++ A_STATUS status; ++ ++ /* write bytes 1,2,3 of the register to set the upper address bytes, the LSB is written ++ * last to initiate the access cycle */ ++ status = HIFReadWrite(hifDevice, ++ RegisterAddr+1, /* write upper 3 bytes */ ++ ((A_UCHAR *)(&Address))+1, ++ sizeof(A_UINT32)-1, ++ HIF_WR_SYNC_BYTE_INC, ++ NULL); ++ ++ if (status != A_OK) { ++ AR_DEBUG_PRINTF(ATH_LOG_ERR, ("Cannot write initial bytes of 0x%x to window reg: 0x%X \n", ++ RegisterAddr, Address)); ++ return status; ++ } ++ ++ /* write the LSB of the register, this initiates the operation */ ++ status = HIFReadWrite(hifDevice, ++ RegisterAddr, ++ (A_UCHAR *)(&Address), ++ sizeof(A_UINT8), ++ HIF_WR_SYNC_BYTE_INC, ++ NULL); ++ ++ if (status != A_OK) { ++ AR_DEBUG_PRINTF(ATH_LOG_ERR, ("Cannot write 0x%x to window reg: 0x%X \n", ++ RegisterAddr, Address)); ++ return status; ++ } ++ ++ return A_OK; ++} ++ ++#endif ++ ++/* ++ * Read from the AR6000 through its diagnostic window. ++ * No cooperation from the Target is required for this. ++ */ ++A_STATUS ++ar6000_ReadRegDiag(HIF_DEVICE *hifDevice, A_UINT32 *address, A_UINT32 *data) ++{ ++ A_STATUS status; ++ ++ /* set window register to start read cycle */ ++ status = ar6000_SetAddressWindowRegister(hifDevice, ++ WINDOW_READ_ADDR_ADDRESS, ++ *address); ++ ++ if (status != A_OK) { ++ return status; ++ } ++ ++ /* read the data */ ++ status = HIFReadWrite(hifDevice, ++ WINDOW_DATA_ADDRESS, ++ (A_UCHAR *)data, ++ sizeof(A_UINT32), ++ HIF_RD_SYNC_BYTE_INC, ++ NULL); ++ if (status != A_OK) { ++ AR_DEBUG_PRINTF(ATH_LOG_ERR, ("Cannot read from WINDOW_DATA_ADDRESS\n")); ++ return status; ++ } ++ ++ return status; ++} ++ ++ ++/* ++ * Write to the AR6000 through its diagnostic window. ++ * No cooperation from the Target is required for this. ++ */ ++A_STATUS ++ar6000_WriteRegDiag(HIF_DEVICE *hifDevice, A_UINT32 *address, A_UINT32 *data) ++{ ++ A_STATUS status; ++ ++ /* set write data */ ++ status = HIFReadWrite(hifDevice, ++ WINDOW_DATA_ADDRESS, ++ (A_UCHAR *)data, ++ sizeof(A_UINT32), ++ HIF_WR_SYNC_BYTE_INC, ++ NULL); ++ if (status != A_OK) { ++ AR_DEBUG_PRINTF(ATH_LOG_ERR, ("Cannot write 0x%x to WINDOW_DATA_ADDRESS\n", *data)); ++ return status; ++ } ++ ++ /* set window register, which starts the write cycle */ ++ return ar6000_SetAddressWindowRegister(hifDevice, ++ WINDOW_WRITE_ADDR_ADDRESS, ++ *address); ++} ++ ++A_STATUS ++ar6000_ReadDataDiag(HIF_DEVICE *hifDevice, A_UINT32 address, ++ A_UCHAR *data, A_UINT32 length) ++{ ++ A_UINT32 count; ++ A_STATUS status = A_OK; ++ ++ for (count = 0; count < length; count += 4, address += 4) { ++ if ((status = ar6000_ReadRegDiag(hifDevice, &address, ++ (A_UINT32 *)&data[count])) != A_OK) ++ { ++ break; ++ } ++ } ++ ++ return status; ++} ++ ++A_STATUS ++ar6000_WriteDataDiag(HIF_DEVICE *hifDevice, A_UINT32 address, ++ A_UCHAR *data, A_UINT32 length) ++{ ++ A_UINT32 count; ++ A_STATUS status = A_OK; ++ ++ for (count = 0; count < length; count += 4, address += 4) { ++ if ((status = ar6000_WriteRegDiag(hifDevice, &address, ++ (A_UINT32 *)&data[count])) != A_OK) ++ { ++ break; ++ } ++ } ++ ++ return status; ++} ++ ++A_STATUS ++ar6000_reset_device_skipflash(HIF_DEVICE *hifDevice) ++{ ++ int i; ++ struct forceROM_s { ++ A_UINT32 addr; ++ A_UINT32 data; ++ }; ++ struct forceROM_s *ForceROM; ++ int szForceROM; ++ A_UINT32 instruction; ++ ++ static struct forceROM_s ForceROM_REV2[] = { ++ /* NB: This works for old REV2 ROM (old). */ ++ {0x00001ff0, 0x175b0027}, /* jump instruction at 0xa0001ff0 */ ++ {0x00001ff4, 0x00000000}, /* nop instruction at 0xa0001ff4 */ ++ ++ {MC_REMAP_TARGET_ADDRESS, 0x00001ff0}, /* remap to 0xa0001ff0 */ ++ {MC_REMAP_COMPARE_ADDRESS, 0x01000040},/* ...from 0xbfc00040 */ ++ {MC_REMAP_SIZE_ADDRESS, 0x00000000}, /* ...1 cache line */ ++ {MC_REMAP_VALID_ADDRESS, 0x00000001}, /* ...remap is valid */ ++ ++ {LOCAL_COUNT_ADDRESS+0x10, 0}, /* clear BMI credit counter */ ++ ++ {RESET_CONTROL_ADDRESS, RESET_CONTROL_WARM_RST_MASK}, ++ }; ++ ++ static struct forceROM_s ForceROM_NEW[] = { ++ /* NB: This works for AR6000 ROM REV3 and beyond. */ ++ {LOCAL_SCRATCH_ADDRESS, AR6K_OPTION_IGNORE_FLASH}, ++ {LOCAL_COUNT_ADDRESS+0x10, 0}, /* clear BMI credit counter */ ++ {RESET_CONTROL_ADDRESS, RESET_CONTROL_WARM_RST_MASK}, ++ }; ++ ++ /* ++ * Examine a semi-arbitrary instruction that's different ++ * in REV2 and other revisions. ++ * NB: If a Host port does not require simultaneous support ++ * for multiple revisions of Target ROM, this code can be elided. ++ */ ++ (void)ar6000_ReadDataDiag(hifDevice, 0x01000040, ++ (A_UCHAR *)&instruction, 4); ++ ++ AR_DEBUG_PRINTF(ATH_LOG_ERR, ("instruction=0x%x\n", instruction)); ++ ++ if (instruction == 0x3c1aa200) { ++ /* It's an old ROM */ ++ ForceROM = ForceROM_REV2; ++ szForceROM = sizeof(ForceROM_REV2)/sizeof(*ForceROM); ++ AR_DEBUG_PRINTF(ATH_LOG_ERR, ("Using OLD method\n")); ++ } else { ++ ForceROM = ForceROM_NEW; ++ szForceROM = sizeof(ForceROM_NEW)/sizeof(*ForceROM); ++ AR_DEBUG_PRINTF(ATH_LOG_ERR, ("Using NEW method\n")); ++ } ++ ++ AR_DEBUG_PRINTF(ATH_LOG_ERR, ("Force Target to execute from ROM....\n")); ++ for (i = 0; i < szForceROM; i++) ++ { ++ if (ar6000_WriteRegDiag(hifDevice, ++ &ForceROM[i].addr, ++ &ForceROM[i].data) != A_OK) ++ { ++ AR_DEBUG_PRINTF(ATH_LOG_ERR, ("Cannot force Target to execute ROM!\n")); ++ return A_ERROR; ++ } ++ } ++ ++ msleep(50); /* delay to allow dragon to come to BMI phase */ ++ return A_OK; ++} ++ ++/* reset device */ ++A_STATUS ar6000_reset_device(HIF_DEVICE *hifDevice, A_UINT32 TargetType) ++{ ++ ++#if !defined(DWSIM) ++ A_STATUS status = A_OK; ++ A_UINT32 address; ++ A_UINT32 data; ++ ++ do { ++ ++ // address = RESET_CONTROL_ADDRESS; ++ data = RESET_CONTROL_COLD_RST_MASK; ++ ++ /* Hardcode the address of RESET_CONTROL_ADDRESS based on the target type */ ++ if (TargetType == TARGET_TYPE_AR6001) { ++ address = 0x0C000000; ++ } else { ++ if (TargetType == TARGET_TYPE_AR6002) { ++ address = 0x00004000; ++ } else { ++ A_ASSERT(0); ++ } ++ } ++ ++ status = ar6000_WriteRegDiag(hifDevice, &address, &data); ++ ++ if (A_FAILED(status)) { ++ break; ++ } ++ ++ /* ++ * Read back the RESET CAUSE register to ensure that the cold reset ++ * went through. ++ */ ++ msleep(2000); /* 2 second delay to allow things to settle down */ ++ ++ ++ // address = RESET_CAUSE_ADDRESS; ++ /* Hardcode the address of RESET_CAUSE_ADDRESS based on the target type */ ++ if (TargetType == TARGET_TYPE_AR6001) { ++ address = 0x0C0000CC; ++ } else { ++ if (TargetType == TARGET_TYPE_AR6002) { ++ address = 0x000040C0; ++ } else { ++ A_ASSERT(0); ++ } ++ } ++ ++ data = 0; ++ status = ar6000_ReadRegDiag(hifDevice, &address, &data); ++ ++ if (A_FAILED(status)) { ++ break; ++ } ++ ++ AR_DEBUG_PRINTF(ATH_LOG_ERR, ("Reset Cause readback: 0x%X \n",data)); ++ data &= RESET_CAUSE_LAST_MASK; ++ if (data != 2) { ++ AR_DEBUG_PRINTF(ATH_LOG_ERR, ("Unable to cold reset the target \n")); ++ } ++ ++ } while (FALSE); ++ ++ if (A_FAILED(status)) { ++ AR_DEBUG_PRINTF(ATH_LOG_ERR, ("Failed to reset target \n")); ++ } ++#endif ++ return A_OK; ++} ++ ++#define REG_DUMP_COUNT_AR6001 38 /* WORDs, derived from AR6001_regdump.h */ ++#define REG_DUMP_COUNT_AR6002 32 /* WORDs, derived from AR6002_regdump.h */ ++ ++ ++#if REG_DUMP_COUNT_AR6001 <= REG_DUMP_COUNT_AR6002 ++#define REGISTER_DUMP_LEN_MAX REG_DUMP_COUNT_AR6002 ++#else ++#define REGISTER_DUMP_LEN_MAX REG_DUMP_COUNT_AR6001 ++#endif ++ ++void ar6000_dump_target_assert_info(HIF_DEVICE *hifDevice, A_UINT32 TargetType) ++{ ++ A_UINT32 address; ++ A_UINT32 regDumpArea = 0; ++ A_STATUS status; ++ A_UINT32 regDumpValues[REGISTER_DUMP_LEN_MAX]; ++ A_UINT32 regDumpCount = 0; ++ A_UINT32 i; ++ ++ do { ++ ++ /* the reg dump pointer is copied to the host interest area */ ++ address = HOST_INTEREST_ITEM_ADDRESS(TargetType, hi_failure_state); ++ ++ if (TargetType == TARGET_TYPE_AR6001) { ++ /* for AR6001, this is a fixed location because the ptr is actually stuck in cache, ++ * this may be fixed in later firmware versions */ ++ address = 0x18a0; ++ regDumpCount = REG_DUMP_COUNT_AR6001; ++ ++ } else if (TargetType == TARGET_TYPE_AR6002) { ++ ++ regDumpCount = REG_DUMP_COUNT_AR6002; ++ ++ } else { ++ A_ASSERT(0); ++ } ++ ++ /* read RAM location through diagnostic window */ ++ status = ar6000_ReadRegDiag(hifDevice, &address, ®DumpArea); ++ ++ if (A_FAILED(status)) { ++ AR_DEBUG_PRINTF(ATH_DEBUG_ERR,("AR6K: Failed to get ptr to register dump area \n")); ++ break; ++ } ++ ++ AR_DEBUG_PRINTF(ATH_DEBUG_ERR,("AR6K: Location of register dump data: 0x%X \n",regDumpArea)); ++ ++ if (regDumpArea == 0) { ++ /* no reg dump */ ++ break; ++ } ++ ++ if (TargetType == TARGET_TYPE_AR6001) { ++ regDumpArea &= 0x0FFFFFFF; /* convert to physical address in target memory */ ++ } ++ ++ /* fetch register dump data */ ++ status = ar6000_ReadDataDiag(hifDevice, ++ regDumpArea, ++ (A_UCHAR *)®DumpValues[0], ++ regDumpCount * (sizeof(A_UINT32))); ++ ++ if (A_FAILED(status)) { ++ AR_DEBUG_PRINTF(ATH_DEBUG_ERR,("AR6K: Failed to get register dump \n")); ++ break; ++ } ++ ++ AR_DEBUG_PRINTF(ATH_DEBUG_ERR,("AR6K: Register Dump: \n")); ++ ++ for (i = 0; i < regDumpCount; i++) { ++ AR_DEBUG_PRINTF(ATH_DEBUG_ERR,(" %d : 0x%8.8X \n",i, regDumpValues[i])); ++ } ++ ++ } while (FALSE); ++ ++} ++ +diff -ruN --exclude='*.orig' --exclude='*.rej' linux-2.6.29-rc3.owrt/drivers/ar6000/miscdrv/credit_dist.c linux-2.6.29-rc3.owrt.om/drivers/ar6000/miscdrv/credit_dist.c +--- linux-2.6.29-rc3.owrt/drivers/ar6000/miscdrv/credit_dist.c 1970-01-01 01:00:00.000000000 +0100 ++++ linux-2.6.29-rc3.owrt.om/drivers/ar6000/miscdrv/credit_dist.c 2009-05-10 22:27:59.000000000 +0200 +@@ -0,0 +1,346 @@ ++ ++/* ++ * ++ * Copyright (c) 2004-2007 Atheros Communications Inc. ++ * All rights reserved. ++ * ++ * ++ * 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; ++ * ++ * Software distributed under the License is distributed on an "AS ++ * IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or ++ * implied. See the License for the specific language governing ++ * rights and limitations under the License. ++ * ++ * ++ * ++ */ ++ ++#include "a_config.h" ++#include "athdefs.h" ++#include "a_types.h" ++#include "a_osapi.h" ++#include "a_debug.h" ++#include "htc_api.h" ++#include "common_drv.h" ++ ++/********* CREDIT DISTRIBUTION FUNCTIONS ******************************************/ ++ ++#define NO_VO_SERVICE 1 /* currently WMI only uses 3 data streams, so we leave VO service inactive */ ++ ++#ifdef NO_VO_SERVICE ++#define DATA_SVCS_USED 3 ++#else ++#define DATA_SVCS_USED 4 ++#endif ++ ++static void RedistributeCredits(COMMON_CREDIT_STATE_INFO *pCredInfo, ++ HTC_ENDPOINT_CREDIT_DIST *pEPDistList); ++ ++static void SeekCredits(COMMON_CREDIT_STATE_INFO *pCredInfo, ++ HTC_ENDPOINT_CREDIT_DIST *pEPDistList); ++ ++/* reduce an ep's credits back to a set limit */ ++static INLINE void ReduceCredits(COMMON_CREDIT_STATE_INFO *pCredInfo, ++ HTC_ENDPOINT_CREDIT_DIST *pEpDist, ++ int Limit) ++{ ++ int credits; ++ ++ /* set the new limit */ ++ pEpDist->TxCreditsAssigned = Limit; ++ ++ if (pEpDist->TxCredits <= Limit) { ++ return; ++ } ++ ++ /* figure out how much to take away */ ++ credits = pEpDist->TxCredits - Limit; ++ /* take them away */ ++ pEpDist->TxCredits -= credits; ++ pCredInfo->CurrentFreeCredits += credits; ++} ++ ++/* give an endpoint some credits from the free credit pool */ ++#define GiveCredits(pCredInfo,pEpDist,credits) \ ++{ \ ++ (pEpDist)->TxCredits += (credits); \ ++ (pEpDist)->TxCreditsAssigned += (credits); \ ++ (pCredInfo)->CurrentFreeCredits -= (credits); \ ++} ++ ++ ++/* default credit init callback. ++ * This function is called in the context of HTCStart() to setup initial (application-specific) ++ * credit distributions */ ++static void ar6000_credit_init(void *Context, ++ HTC_ENDPOINT_CREDIT_DIST *pEPList, ++ int TotalCredits) ++{ ++ HTC_ENDPOINT_CREDIT_DIST *pCurEpDist; ++ int count; ++ COMMON_CREDIT_STATE_INFO *pCredInfo = (COMMON_CREDIT_STATE_INFO *)Context; ++ ++ pCredInfo->CurrentFreeCredits = TotalCredits; ++ pCredInfo->TotalAvailableCredits = TotalCredits; ++ ++ pCurEpDist = pEPList; ++ ++ /* run through the list and initialize */ ++ while (pCurEpDist != NULL) { ++ ++ /* set minimums for each endpoint */ ++ pCurEpDist->TxCreditsMin = pCurEpDist->TxCreditsPerMaxMsg; ++ ++ if (pCurEpDist->ServiceID == WMI_CONTROL_SVC) { ++ /* give control service some credits */ ++ GiveCredits(pCredInfo,pCurEpDist,pCurEpDist->TxCreditsMin); ++ /* control service is always marked active, it never goes inactive EVER */ ++ SET_EP_ACTIVE(pCurEpDist); ++ } else if (pCurEpDist->ServiceID == WMI_DATA_BK_SVC) { ++ /* this is the lowest priority data endpoint, save this off for easy access */ ++ pCredInfo->pLowestPriEpDist = pCurEpDist; ++ } ++ ++ /* Streams have to be created (explicit | implicit)for all kinds ++ * of traffic. BE endpoints are also inactive in the beginning. ++ * When BE traffic starts it creates implicit streams that ++ * redistributes credits. ++ */ ++ ++ /* note, all other endpoints have minimums set but are initially given NO credits. ++ * Credits will be distributed as traffic activity demands */ ++ pCurEpDist = pCurEpDist->pNext; ++ } ++ ++ if (pCredInfo->CurrentFreeCredits <= 0) { ++ AR_DEBUG_PRINTF(ATH_LOG_INF, ("Not enough credits (%d) to do credit distributions \n", TotalCredits)); ++ A_ASSERT(FALSE); ++ return; ++ } ++ ++ /* reset list */ ++ pCurEpDist = pEPList; ++ /* now run through the list and set max operating credit limits for everyone */ ++ while (pCurEpDist != NULL) { ++ if (pCurEpDist->ServiceID == WMI_CONTROL_SVC) { ++ /* control service max is just 1 max message */ ++ pCurEpDist->TxCreditsNorm = pCurEpDist->TxCreditsPerMaxMsg; ++ } else { ++ /* for the remaining data endpoints, we assume that each TxCreditsPerMaxMsg are ++ * the same. ++ * We use a simple calculation here, we take the remaining credits and ++ * determine how many max messages this can cover and then set each endpoint's ++ * normal value equal to half this amount. ++ * */ ++ count = (pCredInfo->CurrentFreeCredits/pCurEpDist->TxCreditsPerMaxMsg) * pCurEpDist->TxCreditsPerMaxMsg; ++ count = count >> 1; ++ count = max(count,pCurEpDist->TxCreditsPerMaxMsg); ++ /* set normal */ ++ pCurEpDist->TxCreditsNorm = count; ++ ++ } ++ pCurEpDist = pCurEpDist->pNext; ++ } ++ ++} ++ ++ ++/* default credit distribution callback ++ * This callback is invoked whenever endpoints require credit distributions. ++ * A lock is held while this function is invoked, this function shall NOT block. ++ * The pEPDistList is a list of distribution structures in prioritized order as ++ * defined by the call to the HTCSetCreditDistribution() api. ++ * ++ */ ++static void ar6000_credit_distribute(void *Context, ++ HTC_ENDPOINT_CREDIT_DIST *pEPDistList, ++ HTC_CREDIT_DIST_REASON Reason) ++{ ++ HTC_ENDPOINT_CREDIT_DIST *pCurEpDist; ++ COMMON_CREDIT_STATE_INFO *pCredInfo = (COMMON_CREDIT_STATE_INFO *)Context; ++ ++ switch (Reason) { ++ case HTC_CREDIT_DIST_SEND_COMPLETE : ++ pCurEpDist = pEPDistList; ++ /* we are given the start of the endpoint distribution list. ++ * There may be one or more endpoints to service. ++ * Run through the list and distribute credits */ ++ while (pCurEpDist != NULL) { ++ ++ if (pCurEpDist->TxCreditsToDist > 0) { ++ /* return the credits back to the endpoint */ ++ pCurEpDist->TxCredits += pCurEpDist->TxCreditsToDist; ++ /* always zero out when we are done */ ++ pCurEpDist->TxCreditsToDist = 0; ++ ++ if (pCurEpDist->TxCredits > pCurEpDist->TxCreditsAssigned) { ++ /* reduce to the assigned limit, previous credit reductions ++ * could have caused the limit to change */ ++ ReduceCredits(pCredInfo, pCurEpDist, pCurEpDist->TxCreditsAssigned); ++ } ++ ++ if (pCurEpDist->TxCredits > pCurEpDist->TxCreditsNorm) { ++ /* oversubscribed endpoints need to reduce back to normal */ ++ ReduceCredits(pCredInfo, pCurEpDist, pCurEpDist->TxCreditsNorm); ++ } ++ } ++ ++ pCurEpDist = pCurEpDist->pNext; ++ } ++ ++ A_ASSERT(pCredInfo->CurrentFreeCredits <= pCredInfo->TotalAvailableCredits); ++ ++ break; ++ ++ case HTC_CREDIT_DIST_ACTIVITY_CHANGE : ++ RedistributeCredits(pCredInfo,pEPDistList); ++ break; ++ case HTC_CREDIT_DIST_SEEK_CREDITS : ++ SeekCredits(pCredInfo,pEPDistList); ++ break; ++ case HTC_DUMP_CREDIT_STATE : ++ AR_DEBUG_PRINTF(ATH_LOG_INF, ("Credit Distribution, total : %d, free : %d\n", ++ pCredInfo->TotalAvailableCredits, pCredInfo->CurrentFreeCredits)); ++ break; ++ default: ++ break; ++ ++ } ++ ++} ++ ++/* redistribute credits based on activity change */ ++static void RedistributeCredits(COMMON_CREDIT_STATE_INFO *pCredInfo, ++ HTC_ENDPOINT_CREDIT_DIST *pEPDistList) ++{ ++ HTC_ENDPOINT_CREDIT_DIST *pCurEpDist = pEPDistList; ++ ++ /* walk through the list and remove credits from inactive endpoints */ ++ while (pCurEpDist != NULL) { ++ ++ if (pCurEpDist->ServiceID != WMI_CONTROL_SVC) { ++ if (!IS_EP_ACTIVE(pCurEpDist)) { ++ /* EP is inactive, reduce credits back to zero */ ++ ReduceCredits(pCredInfo, pCurEpDist, 0); ++ } ++ } ++ ++ /* NOTE in the active case, we do not need to do anything further, ++ * when an EP goes active and needs credits, HTC will call into ++ * our distribution function using a reason code of HTC_CREDIT_DIST_SEEK_CREDITS */ ++ ++ pCurEpDist = pCurEpDist->pNext; ++ } ++ ++ A_ASSERT(pCredInfo->CurrentFreeCredits <= pCredInfo->TotalAvailableCredits); ++ ++} ++ ++/* HTC has an endpoint that needs credits, pEPDist is the endpoint in question */ ++static void SeekCredits(COMMON_CREDIT_STATE_INFO *pCredInfo, ++ HTC_ENDPOINT_CREDIT_DIST *pEPDist) ++{ ++ HTC_ENDPOINT_CREDIT_DIST *pCurEpDist; ++ int credits = 0; ++ int need; ++ ++ do { ++ ++ if (pEPDist->ServiceID == WMI_CONTROL_SVC) { ++ /* we never oversubscribe on the control service, this is not ++ * a high performance path and the target never holds onto control ++ * credits for too long */ ++ break; ++ } ++ ++ /* for all other services, we follow a simple algorithm of ++ * 1. checking the free pool for credits ++ * 2. checking lower priority endpoints for credits to take */ ++ ++ if (pCredInfo->CurrentFreeCredits >= 2 * pEPDist->TxCreditsSeek) { ++ /* try to give more credits than it needs */ ++ credits = 2 * pEPDist->TxCreditsSeek; ++ } else { ++ /* give what we can */ ++ credits = min(pCredInfo->CurrentFreeCredits,pEPDist->TxCreditsSeek); ++ } ++ ++ if (credits >= pEPDist->TxCreditsSeek) { ++ /* we found some to fullfill the seek request */ ++ break; ++ } ++ ++ /* we don't have enough in the free pool, try taking away from lower priority services ++ * ++ * The rule for taking away credits: ++ * 1. Only take from lower priority endpoints ++ * 2. Only take what is allocated above the minimum (never starve an endpoint completely) ++ * 3. Only take what you need. ++ * ++ * */ ++ ++ /* starting at the lowest priority */ ++ pCurEpDist = pCredInfo->pLowestPriEpDist; ++ ++ /* work backwards until we hit the endpoint again */ ++ while (pCurEpDist != pEPDist) { ++ /* calculate how many we need so far */ ++ need = pEPDist->TxCreditsSeek - pCredInfo->CurrentFreeCredits; ++ ++ if ((pCurEpDist->TxCreditsAssigned - need) > pCurEpDist->TxCreditsMin) { ++ /* the current one has been allocated more than it's minimum and it ++ * has enough credits assigned above it's minimum to fullfill our need ++ * try to take away just enough to fullfill our need */ ++ ReduceCredits(pCredInfo, ++ pCurEpDist, ++ pCurEpDist->TxCreditsAssigned - need); ++ ++ if (pCredInfo->CurrentFreeCredits >= pEPDist->TxCreditsSeek) { ++ /* we have enough */ ++ break; ++ } ++ } ++ ++ pCurEpDist = pCurEpDist->pPrev; ++ } ++ ++ /* return what we can get */ ++ credits = min(pCredInfo->CurrentFreeCredits,pEPDist->TxCreditsSeek); ++ ++ } while (FALSE); ++ ++ /* did we find some credits? */ ++ if (credits) { ++ /* give what we can */ ++ GiveCredits(pCredInfo, pEPDist, credits); ++ } ++ ++} ++ ++/* initialize and setup credit distribution */ ++A_STATUS ar6000_setup_credit_dist(HTC_HANDLE HTCHandle, COMMON_CREDIT_STATE_INFO *pCredInfo) ++{ ++ HTC_SERVICE_ID servicepriority[5]; ++ ++ A_MEMZERO(pCredInfo,sizeof(COMMON_CREDIT_STATE_INFO)); ++ ++ servicepriority[0] = WMI_CONTROL_SVC; /* highest */ ++ servicepriority[1] = WMI_DATA_VO_SVC; ++ servicepriority[2] = WMI_DATA_VI_SVC; ++ servicepriority[3] = WMI_DATA_BE_SVC; ++ servicepriority[4] = WMI_DATA_BK_SVC; /* lowest */ ++ ++ /* set callbacks and priority list */ ++ HTCSetCreditDistribution(HTCHandle, ++ pCredInfo, ++ ar6000_credit_distribute, ++ ar6000_credit_init, ++ servicepriority, ++ 5); ++ ++ return A_OK; ++} ++ +diff -ruN --exclude='*.orig' --exclude='*.rej' linux-2.6.29-rc3.owrt/drivers/ar6000/wlan/wlan_node.c linux-2.6.29-rc3.owrt.om/drivers/ar6000/wlan/wlan_node.c +--- linux-2.6.29-rc3.owrt/drivers/ar6000/wlan/wlan_node.c 1970-01-01 01:00:00.000000000 +0100 ++++ linux-2.6.29-rc3.owrt.om/drivers/ar6000/wlan/wlan_node.c 2009-05-10 22:27:59.000000000 +0200 +@@ -0,0 +1,371 @@ ++/*- ++ * Copyright (c) 2001 Atsushi Onoe ++ * Copyright (c) 2002-2004 Sam Leffler, Errno Consulting ++ * Copyright (c) 2004-2005 Atheros Communications ++ * All rights reserved. ++ * ++ * Redistribution and use in source and binary forms, with or without ++ * modification, are permitted provided that the following conditions ++ * are met: ++ * 1. Redistributions of source code must retain the above copyright ++ * notice, this list of conditions and the following disclaimer. ++ * 2. Redistributions in binary form must reproduce the above copyright ++ * notice, this list of conditions and the following disclaimer in the ++ * documentation and/or other materials provided with the distribution. ++ * 3. The name of the author may not be used to endorse or promote products ++ * derived from this software without specific prior written permission. ++ * ++ * Alternatively, this software may be distributed under the terms of the ++ * GNU General Public License ("GPL") version 2 as published by the Free ++ * Software Foundation. ++ * ++ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR ++ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES ++ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. ++ * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, ++ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT ++ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, ++ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY ++ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT ++ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF ++ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ++ * ++ * $Id: //depot/sw/releases/olca2.0-GPL/host/wlan/src/wlan_node.c#1 $ ++ */ ++/* ++ * IEEE 802.11 node handling support. ++ */ ++#include <a_config.h> ++#include <athdefs.h> ++#include <a_types.h> ++#include <a_osapi.h> ++#include <a_debug.h> ++#include <ieee80211.h> ++#include <wlan_api.h> ++#include <ieee80211_node.h> ++#include <htc_api.h> ++#include <wmi.h> ++#include <wmi_api.h> ++ ++static void wlan_node_timeout(A_ATH_TIMER arg); ++static bss_t * _ieee80211_find_node(struct ieee80211_node_table *nt, ++ const A_UINT8 *macaddr); ++ ++bss_t * ++wlan_node_alloc(struct ieee80211_node_table *nt, int wh_size) ++{ ++ bss_t *ni; ++ ++ ni = A_MALLOC_NOWAIT(sizeof(bss_t)); ++ ++ if (ni != NULL) { ++ ni->ni_buf = A_MALLOC_NOWAIT(wh_size); ++ if (ni->ni_buf == NULL) { ++ A_FREE(ni); ++ ni = NULL; ++ return ni; ++ } ++ } else { ++ return ni; ++ } ++ ++ /* Make sure our lists are clean */ ++ ni->ni_list_next = NULL; ++ ni->ni_list_prev = NULL; ++ ni->ni_hash_next = NULL; ++ ni->ni_hash_prev = NULL; ++ ++ // ++ // ni_scangen never initialized before and during suspend/resume of winmobile, customer (LG/SEMCO) identified ++ // that some junk has been stored in this, due to this scan list didn't properly updated ++ // ++ ni->ni_scangen = 0; ++ ++ return ni; ++} ++ ++void ++wlan_node_free(bss_t *ni) ++{ ++ if (ni->ni_buf != NULL) { ++ A_FREE(ni->ni_buf); ++ } ++ A_FREE(ni); ++} ++ ++void ++wlan_setup_node(struct ieee80211_node_table *nt, bss_t *ni, ++ const A_UINT8 *macaddr) ++{ ++ int hash; ++ ++ A_MEMCPY(ni->ni_macaddr, macaddr, IEEE80211_ADDR_LEN); ++ hash = IEEE80211_NODE_HASH(macaddr); ++ ieee80211_node_initref(ni); /* mark referenced */ ++ ++ ni->ni_tstamp = A_GET_MS(WLAN_NODE_INACT_TIMEOUT_MSEC); ++ IEEE80211_NODE_LOCK_BH(nt); ++ ++ /* Insert at the end of the node list */ ++ ni->ni_list_next = NULL; ++ ni->ni_list_prev = nt->nt_node_last; ++ if(nt->nt_node_last != NULL) ++ { ++ nt->nt_node_last->ni_list_next = ni; ++ } ++ nt->nt_node_last = ni; ++ if(nt->nt_node_first == NULL) ++ { ++ nt->nt_node_first = ni; ++ } ++ ++ /* Insert into the hash list i.e. the bucket */ ++ if((ni->ni_hash_next = nt->nt_hash[hash]) != NULL) ++ { ++ nt->nt_hash[hash]->ni_hash_prev = ni; ++ } ++ ni->ni_hash_prev = NULL; ++ nt->nt_hash[hash] = ni; ++ ++ if (!nt->isTimerArmed) { ++ A_TIMEOUT_MS(&nt->nt_inact_timer, WLAN_NODE_INACT_TIMEOUT_MSEC, 0); ++ nt->isTimerArmed = TRUE; ++ } ++ ++ IEEE80211_NODE_UNLOCK_BH(nt); ++} ++ ++static bss_t * ++_ieee80211_find_node(struct ieee80211_node_table *nt, ++ const A_UINT8 *macaddr) ++{ ++ bss_t *ni; ++ int hash; ++ ++ IEEE80211_NODE_LOCK_ASSERT(nt); ++ ++ hash = IEEE80211_NODE_HASH(macaddr); ++ for(ni = nt->nt_hash[hash]; ni; ni = ni->ni_hash_next) { ++ if (IEEE80211_ADDR_EQ(ni->ni_macaddr, macaddr)) { ++ ieee80211_node_incref(ni); /* mark referenced */ ++ return ni; ++ } ++ } ++ return NULL; ++} ++ ++bss_t * ++wlan_find_node(struct ieee80211_node_table *nt, const A_UINT8 *macaddr) ++{ ++ bss_t *ni; ++ ++ IEEE80211_NODE_LOCK(nt); ++ ni = _ieee80211_find_node(nt, macaddr); ++ IEEE80211_NODE_UNLOCK(nt); ++ return ni; ++} ++ ++/* ++ * Reclaim a node. If this is the last reference count then ++ * do the normal free work. Otherwise remove it from the node ++ * table and mark it gone by clearing the back-reference. ++ */ ++void ++wlan_node_reclaim(struct ieee80211_node_table *nt, bss_t *ni) ++{ ++ IEEE80211_NODE_LOCK(nt); ++ ++ if(ni->ni_list_prev == NULL) ++ { ++ /* First in list so fix the list head */ ++ nt->nt_node_first = ni->ni_list_next; ++ } ++ else ++ { ++ ni->ni_list_prev->ni_list_next = ni->ni_list_next; ++ } ++ ++ if(ni->ni_list_next == NULL) ++ { ++ /* Last in list so fix list tail */ ++ nt->nt_node_last = ni->ni_list_prev; ++ } ++ else ++ { ++ ni->ni_list_next->ni_list_prev = ni->ni_list_prev; ++ } ++ ++ if(ni->ni_hash_prev == NULL) ++ { ++ /* First in list so fix the list head */ ++ int hash; ++ hash = IEEE80211_NODE_HASH(ni->ni_macaddr); ++ nt->nt_hash[hash] = ni->ni_hash_next; ++ } ++ else ++ { ++ ni->ni_hash_prev->ni_hash_next = ni->ni_hash_next; ++ } ++ ++ if(ni->ni_hash_next != NULL) ++ { ++ ni->ni_hash_next->ni_hash_prev = ni->ni_hash_prev; ++ } ++ wlan_node_free(ni); ++ ++ IEEE80211_NODE_UNLOCK(nt); ++} ++ ++static void ++wlan_node_dec_free(bss_t *ni) ++{ ++ if (ieee80211_node_dectestref(ni)) { ++ wlan_node_free(ni); ++ } ++} ++ ++void ++wlan_free_allnodes(struct ieee80211_node_table *nt) ++{ ++ bss_t *ni; ++ ++ while ((ni = nt->nt_node_first) != NULL) { ++ wlan_node_reclaim(nt, ni); ++ } ++} ++ ++void ++wlan_iterate_nodes(struct ieee80211_node_table *nt, wlan_node_iter_func *f, ++ void *arg) ++{ ++ bss_t *ni; ++ A_UINT32 gen; ++ ++ gen = ++nt->nt_scangen; ++ ++ IEEE80211_NODE_LOCK(nt); ++ for (ni = nt->nt_node_first; ni; ni = ni->ni_list_next) { ++ if (ni->ni_scangen != gen) { ++ ni->ni_scangen = gen; ++ (void) ieee80211_node_incref(ni); ++ (*f)(arg, ni); ++ wlan_node_dec_free(ni); ++ } ++ } ++ IEEE80211_NODE_UNLOCK(nt); ++} ++ ++/* ++ * Node table support. ++ */ ++void ++wlan_node_table_init(void *wmip, struct ieee80211_node_table *nt) ++{ ++ int i; ++ ++ AR_DEBUG_PRINTF(ATH_DEBUG_WLAN, ("node table = 0x%x\n", (A_UINT32)nt)); ++ IEEE80211_NODE_LOCK_INIT(nt); ++ ++ nt->nt_node_first = nt->nt_node_last = NULL; ++ for(i = 0; i < IEEE80211_NODE_HASHSIZE; i++) ++ { ++ nt->nt_hash[i] = NULL; ++ } ++ A_INIT_TIMER(&nt->nt_inact_timer, wlan_node_timeout, nt); ++ nt->isTimerArmed = FALSE; ++ nt->nt_wmip = wmip; ++} ++ ++static void ++wlan_node_timeout(A_ATH_TIMER arg) ++{ ++ struct ieee80211_node_table *nt = (struct ieee80211_node_table *)arg; ++ bss_t *bss, *nextBss; ++ A_UINT8 myBssid[IEEE80211_ADDR_LEN], reArmTimer = FALSE; ++ ++ wmi_get_current_bssid(nt->nt_wmip, myBssid); ++ ++ bss = nt->nt_node_first; ++ while (bss != NULL) ++ { ++ nextBss = bss->ni_list_next; ++ if (A_MEMCMP(myBssid, bss->ni_macaddr, sizeof(myBssid)) != 0) ++ { ++ ++ if (bss->ni_tstamp <= A_GET_MS(0)) ++ { ++ /* ++ * free up all but the current bss - if set ++ */ ++ wlan_node_reclaim(nt, bss); ++ } ++ else ++ { ++ /* ++ * Re-arm timer, only when we have a bss other than ++ * current bss AND it is not aged-out. ++ */ ++ reArmTimer = TRUE; ++ } ++ } ++ bss = nextBss; ++ } ++ ++ if(reArmTimer) ++ A_TIMEOUT_MS(&nt->nt_inact_timer, WLAN_NODE_INACT_TIMEOUT_MSEC, 0); ++ ++ nt->isTimerArmed = reArmTimer; ++} ++ ++void ++wlan_node_table_cleanup(struct ieee80211_node_table *nt) ++{ ++ A_UNTIMEOUT(&nt->nt_inact_timer); ++ A_DELETE_TIMER(&nt->nt_inact_timer); ++ wlan_free_allnodes(nt); ++ IEEE80211_NODE_LOCK_DESTROY(nt); ++} ++ ++bss_t * ++wlan_find_Ssidnode (struct ieee80211_node_table *nt, A_UCHAR *pSsid, ++ A_UINT32 ssidLength, A_BOOL bIsWPA2) ++{ ++ bss_t *ni = NULL; ++ A_UCHAR *pIESsid = NULL; ++ ++ IEEE80211_NODE_LOCK (nt); ++ ++ for (ni = nt->nt_node_first; ni; ni = ni->ni_list_next) { ++ pIESsid = ni->ni_cie.ie_ssid; ++ if (pIESsid[1] <= 32) { ++ ++ // Step 1 : Check SSID ++ if (0x00 == memcmp (pSsid, &pIESsid[2], ssidLength)) { ++ ++ // Step 2 : if SSID matches, check WPA or WPA2 ++ if (TRUE == bIsWPA2 && NULL != ni->ni_cie.ie_rsn) { ++ ieee80211_node_incref (ni); /* mark referenced */ ++ IEEE80211_NODE_UNLOCK (nt); ++ return ni; ++ } ++ if (FALSE == bIsWPA2 && NULL != ni->ni_cie.ie_wpa) { ++ ieee80211_node_incref(ni); /* mark referenced */ ++ IEEE80211_NODE_UNLOCK (nt); ++ return ni; ++ } ++ } ++ } ++ } ++ ++ IEEE80211_NODE_UNLOCK (nt); ++ ++ return NULL; ++} ++ ++void ++wlan_node_return (struct ieee80211_node_table *nt, bss_t *ni) ++{ ++ IEEE80211_NODE_LOCK (nt); ++ wlan_node_dec_free (ni); ++ IEEE80211_NODE_UNLOCK (nt); ++} +diff -ruN --exclude='*.orig' --exclude='*.rej' linux-2.6.29-rc3.owrt/drivers/ar6000/wlan/wlan_recv_beacon.c linux-2.6.29-rc3.owrt.om/drivers/ar6000/wlan/wlan_recv_beacon.c +--- linux-2.6.29-rc3.owrt/drivers/ar6000/wlan/wlan_recv_beacon.c 1970-01-01 01:00:00.000000000 +0100 ++++ linux-2.6.29-rc3.owrt.om/drivers/ar6000/wlan/wlan_recv_beacon.c 2009-05-10 22:27:59.000000000 +0200 +@@ -0,0 +1,192 @@ ++/*- ++ * Copyright (c) 2001 Atsushi Onoe ++ * Copyright (c) 2002-2004 Sam Leffler, Errno Consulting ++ * All rights reserved. ++ * ++ * Redistribution and use in source and binary forms, with or without ++ * modification, are permitted provided that the following conditions ++ * are met: ++ * 1. Redistributions of source code must retain the above copyright ++ * notice, this list of conditions and the following disclaimer. ++ * 2. Redistributions in binary form must reproduce the above copyright ++ * notice, this list of conditions and the following disclaimer in the ++ * documentation and/or other materials provided with the distribution. ++ * 3. The name of the author may not be used to endorse or promote products ++ * derived from this software without specific prior written permission. ++ * ++ * Alternatively, this software may be distributed under the terms of the ++ * GNU General Public License ("GPL") version 2 as published by the Free ++ * Software Foundation. ++ * ++ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR ++ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES ++ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. ++ * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, ++ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT ++ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, ++ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY ++ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT ++ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF ++ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ++ */ ++/* ++ * IEEE 802.11 input handling. ++ */ ++ ++#include "a_config.h" ++#include "athdefs.h" ++#include "a_types.h" ++#include "a_osapi.h" ++#include <wmi.h> ++#include <ieee80211.h> ++#include <wlan_api.h> ++ ++#define IEEE80211_VERIFY_LENGTH(_len, _minlen) do { \ ++ if ((_len) < (_minlen)) { \ ++ return A_EINVAL; \ ++ } \ ++} while (0) ++ ++#define IEEE80211_VERIFY_ELEMENT(__elem, __maxlen) do { \ ++ if ((__elem) == NULL) { \ ++ return A_EINVAL; \ ++ } \ ++ if ((__elem)[1] > (__maxlen)) { \ ++ return A_EINVAL; \ ++ } \ ++} while (0) ++ ++ ++/* unaligned little endian access */ ++#define LE_READ_2(p) \ ++ ((A_UINT16) \ ++ ((((A_UINT8 *)(p))[0] ) | (((A_UINT8 *)(p))[1] << 8))) ++ ++#define LE_READ_4(p) \ ++ ((A_UINT32) \ ++ ((((A_UINT8 *)(p))[0] ) | (((A_UINT8 *)(p))[1] << 8) | \ ++ (((A_UINT8 *)(p))[2] << 16) | (((A_UINT8 *)(p))[3] << 24))) ++ ++ ++static int __inline ++iswpaoui(const A_UINT8 *frm) ++{ ++ return frm[1] > 3 && LE_READ_4(frm+2) == ((WPA_OUI_TYPE<<24)|WPA_OUI); ++} ++ ++static int __inline ++iswmmoui(const A_UINT8 *frm) ++{ ++ return frm[1] > 3 && LE_READ_4(frm+2) == ((WMM_OUI_TYPE<<24)|WMM_OUI); ++} ++ ++static int __inline ++iswmmparam(const A_UINT8 *frm) ++{ ++ return frm[1] > 5 && frm[6] == WMM_PARAM_OUI_SUBTYPE; ++} ++ ++static int __inline ++iswmminfo(const A_UINT8 *frm) ++{ ++ return frm[1] > 5 && frm[6] == WMM_INFO_OUI_SUBTYPE; ++} ++ ++static int __inline ++isatherosoui(const A_UINT8 *frm) ++{ ++ return frm[1] > 3 && LE_READ_4(frm+2) == ((ATH_OUI_TYPE<<24)|ATH_OUI); ++} ++ ++static int __inline ++iswscoui(const A_UINT8 *frm) ++{ ++ return frm[1] > 3 && LE_READ_4(frm+2) == ((0x04<<24)|WPA_OUI); ++} ++ ++A_STATUS ++wlan_parse_beacon(A_UINT8 *buf, int framelen, struct ieee80211_common_ie *cie) ++{ ++ A_UINT8 *frm, *efrm; ++ ++ frm = buf; ++ efrm = (A_UINT8 *) (frm + framelen); ++ ++ /* ++ * beacon/probe response frame format ++ * [8] time stamp ++ * [2] beacon interval ++ * [2] capability information ++ * [tlv] ssid ++ * [tlv] supported rates ++ * [tlv] country information ++ * [tlv] parameter set (FH/DS) ++ * [tlv] erp information ++ * [tlv] extended supported rates ++ * [tlv] WMM ++ * [tlv] WPA or RSN ++ * [tlv] Atheros Advanced Capabilities ++ */ ++ IEEE80211_VERIFY_LENGTH(efrm - frm, 12); ++ A_MEMZERO(cie, sizeof(*cie)); ++ ++ cie->ie_tstamp = frm; frm += 8; ++ cie->ie_beaconInt = A_LE2CPU16(*(A_UINT16 *)frm); frm += 2; ++ cie->ie_capInfo = A_LE2CPU16(*(A_UINT16 *)frm); frm += 2; ++ cie->ie_chan = 0; ++ ++ while (frm < efrm) { ++ switch (*frm) { ++ case IEEE80211_ELEMID_SSID: ++ cie->ie_ssid = frm; ++ break; ++ case IEEE80211_ELEMID_RATES: ++ cie->ie_rates = frm; ++ break; ++ case IEEE80211_ELEMID_COUNTRY: ++ cie->ie_country = frm; ++ break; ++ case IEEE80211_ELEMID_FHPARMS: ++ break; ++ case IEEE80211_ELEMID_DSPARMS: ++ cie->ie_chan = frm[2]; ++ break; ++ case IEEE80211_ELEMID_TIM: ++ cie->ie_tim = frm; ++ break; ++ case IEEE80211_ELEMID_IBSSPARMS: ++ break; ++ case IEEE80211_ELEMID_XRATES: ++ cie->ie_xrates = frm; ++ break; ++ case IEEE80211_ELEMID_ERP: ++ if (frm[1] != 1) { ++ //A_PRINTF("Discarding ERP Element - Bad Len\n"); ++ return A_EINVAL; ++ } ++ cie->ie_erp = frm[2]; ++ break; ++ case IEEE80211_ELEMID_RSN: ++ cie->ie_rsn = frm; ++ break; ++ case IEEE80211_ELEMID_VENDOR: ++ if (iswpaoui(frm)) { ++ cie->ie_wpa = frm; ++ } else if (iswmmoui(frm)) { ++ cie->ie_wmm = frm; ++ } else if (isatherosoui(frm)) { ++ cie->ie_ath = frm; ++ } else if(iswscoui(frm)) { ++ cie->ie_wsc = frm; ++ } ++ break; ++ default: ++ break; ++ } ++ frm += frm[1] + 2; ++ } ++ IEEE80211_VERIFY_ELEMENT(cie->ie_rates, IEEE80211_RATE_MAXSIZE); ++ IEEE80211_VERIFY_ELEMENT(cie->ie_ssid, IEEE80211_NWID_LEN); ++ ++ return A_OK; ++} +diff -ruN --exclude='*.orig' --exclude='*.rej' linux-2.6.29-rc3.owrt/drivers/ar6000/wlan/wlan_utils.c linux-2.6.29-rc3.owrt.om/drivers/ar6000/wlan/wlan_utils.c +--- linux-2.6.29-rc3.owrt/drivers/ar6000/wlan/wlan_utils.c 1970-01-01 01:00:00.000000000 +0100 ++++ linux-2.6.29-rc3.owrt.om/drivers/ar6000/wlan/wlan_utils.c 2009-05-10 22:27:59.000000000 +0200 +@@ -0,0 +1,59 @@ ++/* ++ * Copyright (c) 2004-2005 Atheros Communications Inc. ++ * All rights reserved. ++ * ++ * This module implements frequently used wlan utilies ++ * ++ * $Id: //depot/sw/releases/olca2.0-GPL/host/wlan/src/wlan_utils.c#1 $ ++ * ++ * ++ * 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; ++ * ++ * Software distributed under the License is distributed on an "AS ++ * IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or ++ * implied. See the License for the specific language governing ++ * rights and limitations under the License. ++ * ++ * ++ * ++ */ ++ ++#include <a_config.h> ++#include <athdefs.h> ++#include <a_types.h> ++#include <a_osapi.h> ++ ++/* ++ * converts ieee channel number to frequency ++ */ ++A_UINT16 ++wlan_ieee2freq(int chan) ++{ ++ if (chan == 14) { ++ return 2484; ++ } ++ if (chan < 14) { /* 0-13 */ ++ return (2407 + (chan*5)); ++ } ++ if (chan < 27) { /* 15-26 */ ++ return (2512 + ((chan-15)*20)); ++ } ++ return (5000 + (chan*5)); ++} ++ ++/* ++ * Converts MHz frequency to IEEE channel number. ++ */ ++A_UINT32 ++wlan_freq2ieee(A_UINT16 freq) ++{ ++ if (freq == 2484) ++ return 14; ++ if (freq < 2484) ++ return (freq - 2407) / 5; ++ if (freq < 5000) ++ return 15 + ((freq - 2512) / 20); ++ return (freq - 5000) / 5; ++} +diff -ruN --exclude='*.orig' --exclude='*.rej' linux-2.6.29-rc3.owrt/drivers/ar6000/wmi/wmi.c linux-2.6.29-rc3.owrt.om/drivers/ar6000/wmi/wmi.c +--- linux-2.6.29-rc3.owrt/drivers/ar6000/wmi/wmi.c 1970-01-01 01:00:00.000000000 +0100 ++++ linux-2.6.29-rc3.owrt.om/drivers/ar6000/wmi/wmi.c 2009-05-10 22:27:59.000000000 +0200 +@@ -0,0 +1,3954 @@ ++/* ++ * Copyright (c) 2004-2007 Atheros Communications Inc. ++ * All rights reserved. ++ * ++ * This module implements the hardware independent layer of the ++ * Wireless Module Interface (WMI) protocol. ++ * ++ * $Id: //depot/sw/releases/olca2.0-GPL/host/wmi/wmi.c#3 $ ++ * ++ * ++ * 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; ++ * ++ * Software distributed under the License is distributed on an "AS ++ * IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or ++ * implied. See the License for the specific language governing ++ * rights and limitations under the License. ++ * ++ * ++ * ++ */ ++ ++#include <a_config.h> ++#include <athdefs.h> ++#include <a_types.h> ++#include <a_osapi.h> ++#include "htc.h" ++#include "htc_api.h" ++#include "wmi.h" ++#include <ieee80211.h> ++#include <ieee80211_node.h> ++#include <wlan_api.h> ++#include <wmi_api.h> ++#include "dset_api.h" ++#include "gpio_api.h" ++#include "wmi_host.h" ++#include "a_drv.h" ++#include "a_drv_api.h" ++#include "a_debug.h" ++#include "dbglog_api.h" ++ ++static A_STATUS wmi_ready_event_rx(struct wmi_t *wmip, A_UINT8 *datap, int len); ++ ++static A_STATUS wmi_connect_event_rx(struct wmi_t *wmip, A_UINT8 *datap, ++ int len); ++static A_STATUS wmi_disconnect_event_rx(struct wmi_t *wmip, A_UINT8 *datap, ++ int len); ++static A_STATUS wmi_tkip_micerr_event_rx(struct wmi_t *wmip, A_UINT8 *datap, ++ int len); ++static A_STATUS wmi_bssInfo_event_rx(struct wmi_t *wmip, A_UINT8 *datap, ++ int len); ++static A_STATUS wmi_opt_frame_event_rx(struct wmi_t *wmip, A_UINT8 *datap, ++ int len); ++static A_STATUS wmi_pstream_timeout_event_rx(struct wmi_t *wmip, A_UINT8 *datap, ++ int len); ++static A_STATUS wmi_sync_point(struct wmi_t *wmip); ++ ++static A_STATUS wmi_bitrate_reply_rx(struct wmi_t *wmip, A_UINT8 *datap, ++ int len); ++static A_STATUS wmi_ratemask_reply_rx(struct wmi_t *wmip, A_UINT8 *datap, ++ int len); ++static A_STATUS wmi_channelList_reply_rx(struct wmi_t *wmip, A_UINT8 *datap, ++ int len); ++static A_STATUS wmi_regDomain_event_rx(struct wmi_t *wmip, A_UINT8 *datap, ++ int len); ++static A_STATUS wmi_txPwr_reply_rx(struct wmi_t *wmip, A_UINT8 *datap, int len); ++static A_STATUS wmi_neighborReport_event_rx(struct wmi_t *wmip, A_UINT8 *datap, ++ int len); ++ ++static A_STATUS wmi_dset_open_req_rx(struct wmi_t *wmip, A_UINT8 *datap, ++ int len); ++#ifdef CONFIG_HOST_DSET_SUPPORT ++static A_STATUS wmi_dset_close_rx(struct wmi_t *wmip, A_UINT8 *datap, int len); ++static A_STATUS wmi_dset_data_req_rx(struct wmi_t *wmip, A_UINT8 *datap, ++ int len); ++#endif /* CONFIG_HOST_DSET_SUPPORT */ ++ ++ ++static A_STATUS wmi_scanComplete_rx(struct wmi_t *wmip, A_UINT8 *datap, ++ int len); ++static A_STATUS wmi_errorEvent_rx(struct wmi_t *wmip, A_UINT8 *datap, int len); ++static A_STATUS wmi_statsEvent_rx(struct wmi_t *wmip, A_UINT8 *datap, int len); ++static A_STATUS wmi_rssiThresholdEvent_rx(struct wmi_t *wmip, A_UINT8 *datap, int len); ++static A_STATUS wmi_hbChallengeResp_rx(struct wmi_t *wmip, A_UINT8 *datap, int len); ++static A_STATUS wmi_reportErrorEvent_rx(struct wmi_t *wmip, A_UINT8 *datap, int len); ++static A_STATUS wmi_cac_event_rx(struct wmi_t *wmip, A_UINT8 *datap, int len); ++static A_STATUS wmi_roam_tbl_event_rx(struct wmi_t *wmip, A_UINT8 *datap, ++ int len); ++static A_STATUS wmi_roam_data_event_rx(struct wmi_t *wmip, A_UINT8 *datap, ++ int len); ++static A_STATUS wmi_get_wow_list_event_rx(struct wmi_t *wmip, A_UINT8 *datap, ++ int len); ++static A_STATUS ++wmi_get_pmkid_list_event_rx(struct wmi_t *wmip, A_UINT8 *datap, A_UINT32 len); ++ ++#ifdef CONFIG_HOST_GPIO_SUPPORT ++static A_STATUS wmi_gpio_intr_rx(struct wmi_t *wmip, A_UINT8 *datap, int len); ++static A_STATUS wmi_gpio_data_rx(struct wmi_t *wmip, A_UINT8 *datap, int len); ++static A_STATUS wmi_gpio_ack_rx(struct wmi_t *wmip, A_UINT8 *datap, int len); ++#endif /* CONFIG_HOST_GPIO_SUPPORT */ ++ ++#ifdef CONFIG_HOST_TCMD_SUPPORT ++static A_STATUS ++wmi_tcmd_test_report_rx(struct wmi_t *wmip, A_UINT8 *datap, int len); ++#endif ++ ++static A_STATUS ++wmi_txRetryErrEvent_rx(struct wmi_t *wmip, A_UINT8 *datap, int len); ++ ++static A_STATUS ++wmi_snrThresholdEvent_rx(struct wmi_t *wmip, A_UINT8 *datap, int len); ++ ++static A_STATUS ++wmi_lqThresholdEvent_rx(struct wmi_t *wmip, A_UINT8 *datap, int len); ++ ++static A_BOOL ++wmi_is_bitrate_index_valid(struct wmi_t *wmip, A_UINT32 rateIndex); ++ ++static A_STATUS ++wmi_aplistEvent_rx(struct wmi_t *wmip, A_UINT8 *datap, int len); ++ ++static A_STATUS ++wmi_dbglog_event_rx(struct wmi_t *wmip, A_UINT8 *datap, int len); ++ ++static A_STATUS wmi_keepalive_reply_rx(struct wmi_t *wmip, A_UINT8 *datap, int len); ++ ++int wps_enable; ++static const A_INT32 wmi_rateTable[] = { ++ 1000, ++ 2000, ++ 5500, ++ 11000, ++ 6000, ++ 9000, ++ 12000, ++ 18000, ++ 24000, ++ 36000, ++ 48000, ++ 54000, ++ 0}; ++ ++#define MODE_A_SUPPORT_RATE_START 4 ++#define MODE_A_SUPPORT_RATE_STOP 11 ++ ++#define MODE_GONLY_SUPPORT_RATE_START MODE_A_SUPPORT_RATE_START ++#define MODE_GONLY_SUPPORT_RATE_STOP MODE_A_SUPPORT_RATE_STOP ++ ++#define MODE_B_SUPPORT_RATE_START 0 ++#define MODE_B_SUPPORT_RATE_STOP 3 ++ ++#define MODE_G_SUPPORT_RATE_START 0 ++#define MODE_G_SUPPORT_RATE_STOP 11 ++ ++#define MAX_NUMBER_OF_SUPPORT_RATES (MODE_G_SUPPORT_RATE_STOP + 1) ++ ++/* 802.1d to AC mapping. Refer pg 57 of WMM-test-plan-v1.2 */ ++const A_UINT8 up_to_ac[]= { ++ WMM_AC_BE, ++ WMM_AC_BK, ++ WMM_AC_BK, ++ WMM_AC_BE, ++ WMM_AC_VI, ++ WMM_AC_VI, ++ WMM_AC_VO, ++ WMM_AC_VO, ++ }; ++ ++void * ++wmi_init(void *devt) ++{ ++ struct wmi_t *wmip; ++ ++ wmip = A_MALLOC(sizeof(struct wmi_t)); ++ if (wmip == NULL) { ++ return (NULL); ++ } ++ A_MEMZERO(wmip, sizeof(*wmip)); ++ A_MUTEX_INIT(&wmip->wmi_lock); ++ wmip->wmi_devt = devt; ++ wlan_node_table_init(wmip, &wmip->wmi_scan_table); ++ wmi_qos_state_init(wmip); ++ wmip->wmi_powerMode = REC_POWER; ++ wmip->wmi_phyMode = WMI_11G_MODE; ++ ++ return (wmip); ++} ++ ++void ++wmi_qos_state_init(struct wmi_t *wmip) ++{ ++ A_UINT8 i; ++ ++ if (wmip == NULL) { ++ return; ++ } ++ LOCK_WMI(wmip); ++ ++ /* Initialize QoS States */ ++ wmip->wmi_numQoSStream = 0; ++ ++ wmip->wmi_fatPipeExists = 0; ++ ++ for (i=0; i < WMM_NUM_AC; i++) { ++ wmip->wmi_streamExistsForAC[i]=0; ++ } ++ ++ /* Initialize the static Wmi stream Pri to WMM AC mappings Arrays */ ++ WMI_INIT_WMISTREAM_AC_MAP(wmip); ++ ++ UNLOCK_WMI(wmip); ++ ++ A_WMI_SET_NUMDATAENDPTS(wmip->wmi_devt, 1); ++} ++ ++void ++wmi_shutdown(struct wmi_t *wmip) ++{ ++ if (wmip != NULL) { ++ wlan_node_table_cleanup(&wmip->wmi_scan_table); ++ if (A_IS_MUTEX_VALID(&wmip->wmi_lock)) { ++ A_MUTEX_DELETE(&wmip->wmi_lock); ++ } ++ A_FREE(wmip); ++ } ++} ++ ++/* ++ * performs DIX to 802.3 encapsulation for transmit packets. ++ * uses passed in buffer. Returns buffer or NULL if failed. ++ * Assumes the entire DIX header is contigous and that there is ++ * enough room in the buffer for a 802.3 mac header and LLC+SNAP headers. ++ */ ++A_STATUS ++wmi_dix_2_dot3(struct wmi_t *wmip, void *osbuf) ++{ ++ A_UINT8 *datap; ++ A_UINT16 typeorlen; ++ ATH_MAC_HDR macHdr; ++ ATH_LLC_SNAP_HDR *llcHdr; ++ ++ A_ASSERT(osbuf != NULL); ++ ++ if (A_NETBUF_HEADROOM(osbuf) < ++ (sizeof(ATH_LLC_SNAP_HDR) + sizeof(WMI_DATA_HDR))) ++ { ++ return A_NO_MEMORY; ++ } ++ ++ datap = A_NETBUF_DATA(osbuf); ++ ++ typeorlen = *(A_UINT16 *)(datap + ATH_MAC_LEN + ATH_MAC_LEN); ++ ++ if (!IS_ETHERTYPE(A_BE2CPU16(typeorlen))) { ++ /* ++ * packet is already in 802.3 format - return success ++ */ ++ A_DPRINTF(DBG_WMI, (DBGFMT "packet already 802.3\n", DBGARG)); ++ return (A_OK); ++ } ++ ++ /* ++ * Save mac fields and length to be inserted later ++ */ ++ A_MEMCPY(macHdr.dstMac, datap, ATH_MAC_LEN); ++ A_MEMCPY(macHdr.srcMac, datap + ATH_MAC_LEN, ATH_MAC_LEN); ++ macHdr.typeOrLen = A_CPU2BE16(A_NETBUF_LEN(osbuf) - sizeof(ATH_MAC_HDR) + ++ sizeof(ATH_LLC_SNAP_HDR)); ++ ++ /* ++ * Make room for LLC+SNAP headers ++ */ ++ if (A_NETBUF_PUSH(osbuf, sizeof(ATH_LLC_SNAP_HDR)) != A_OK) { ++ return A_NO_MEMORY; ++ } ++ ++ datap = A_NETBUF_DATA(osbuf); ++ ++ A_MEMCPY(datap, &macHdr, sizeof (ATH_MAC_HDR)); ++ ++ llcHdr = (ATH_LLC_SNAP_HDR *)(datap + sizeof(ATH_MAC_HDR)); ++ llcHdr->dsap = 0xAA; ++ llcHdr->ssap = 0xAA; ++ llcHdr->cntl = 0x03; ++ llcHdr->orgCode[0] = 0x0; ++ llcHdr->orgCode[1] = 0x0; ++ llcHdr->orgCode[2] = 0x0; ++ llcHdr->etherType = typeorlen; ++ ++ return (A_OK); ++} ++ ++/* ++ * Adds a WMI data header ++ * Assumes there is enough room in the buffer to add header. ++ */ ++A_STATUS ++wmi_data_hdr_add(struct wmi_t *wmip, void *osbuf, A_UINT8 msgType) ++{ ++ WMI_DATA_HDR *dtHdr; ++ ++ A_ASSERT(osbuf != NULL); ++ ++ if (A_NETBUF_PUSH(osbuf, sizeof(WMI_DATA_HDR)) != A_OK) { ++ return A_NO_MEMORY; ++ } ++ ++ dtHdr = (WMI_DATA_HDR *)A_NETBUF_DATA(osbuf); ++ dtHdr->info = msgType; ++ dtHdr->rssi = 0; ++ ++ return (A_OK); ++} ++ ++A_UINT8 wmi_implicit_create_pstream(struct wmi_t *wmip, void *osbuf, A_UINT8 dir, A_UINT8 up) ++{ ++ A_UINT8 *datap; ++ A_UINT8 trafficClass = WMM_AC_BE, userPriority = up; ++ ATH_LLC_SNAP_HDR *llcHdr; ++ A_UINT16 ipType = IP_ETHERTYPE; ++ WMI_DATA_HDR *dtHdr; ++ WMI_CREATE_PSTREAM_CMD cmd; ++ A_BOOL streamExists = FALSE; ++ ++ A_ASSERT(osbuf != NULL); ++ ++ datap = A_NETBUF_DATA(osbuf); ++ ++ if (up == UNDEFINED_PRI) { ++ llcHdr = (ATH_LLC_SNAP_HDR *)(datap + sizeof(WMI_DATA_HDR) + ++ sizeof(ATH_MAC_HDR)); ++ ++ if (llcHdr->etherType == A_CPU2BE16(ipType)) { ++ /* Extract the endpoint info from the TOS field in the IP header */ ++ userPriority = A_WMI_IPTOS_TO_USERPRIORITY(((A_UINT8 *)llcHdr) + sizeof(ATH_LLC_SNAP_HDR)); ++ } ++ } ++ ++ if (userPriority < MAX_NUM_PRI) { ++ trafficClass = convert_userPriority_to_trafficClass(userPriority); ++ } ++ ++ dtHdr = (WMI_DATA_HDR *)datap; ++ if(dir==UPLINK_TRAFFIC) ++ dtHdr->info |= (userPriority & WMI_DATA_HDR_UP_MASK) << WMI_DATA_HDR_UP_SHIFT; /* lower 3-bits are 802.1d priority */ ++ ++ LOCK_WMI(wmip); ++ streamExists = wmip->wmi_fatPipeExists; ++ UNLOCK_WMI(wmip); ++ ++ if (!(streamExists & (1 << trafficClass))) { ++ ++ A_MEMZERO(&cmd, sizeof(cmd)); ++ cmd.trafficClass = trafficClass; ++ cmd.userPriority = userPriority; ++ cmd.inactivityInt = WMI_IMPLICIT_PSTREAM_INACTIVITY_INT; ++ /* Implicit streams are created with TSID 0xFF */ ++ cmd.tsid = WMI_IMPLICIT_PSTREAM; ++ wmi_create_pstream_cmd(wmip, &cmd); ++ } ++ ++ return trafficClass; ++} ++ ++WMI_PRI_STREAM_ID ++wmi_get_stream_id(struct wmi_t *wmip, A_UINT8 trafficClass) ++{ ++ return WMI_ACCESSCATEGORY_WMISTREAM(wmip, trafficClass); ++} ++ ++/* ++ * performs 802.3 to DIX encapsulation for received packets. ++ * Assumes the entire 802.3 header is contigous. ++ */ ++A_STATUS ++wmi_dot3_2_dix(struct wmi_t *wmip, void *osbuf) ++{ ++ A_UINT8 *datap; ++ ATH_MAC_HDR macHdr; ++ ATH_LLC_SNAP_HDR *llcHdr; ++ ++ A_ASSERT(osbuf != NULL); ++ datap = A_NETBUF_DATA(osbuf); ++ ++ A_MEMCPY(&macHdr, datap, sizeof(ATH_MAC_HDR)); ++ llcHdr = (ATH_LLC_SNAP_HDR *)(datap + sizeof(ATH_MAC_HDR)); ++ macHdr.typeOrLen = llcHdr->etherType; ++ ++ if (A_NETBUF_PULL(osbuf, sizeof(ATH_LLC_SNAP_HDR)) != A_OK) { ++ return A_NO_MEMORY; ++ } ++ ++ datap = A_NETBUF_DATA(osbuf); ++ ++ A_MEMCPY(datap, &macHdr, sizeof (ATH_MAC_HDR)); ++ ++ return (A_OK); ++} ++ ++/* ++ * Removes a WMI data header ++ */ ++A_STATUS ++wmi_data_hdr_remove(struct wmi_t *wmip, void *osbuf) ++{ ++ A_ASSERT(osbuf != NULL); ++ ++ return (A_NETBUF_PULL(osbuf, sizeof(WMI_DATA_HDR))); ++} ++ ++void ++wmi_iterate_nodes(struct wmi_t *wmip, wlan_node_iter_func *f, void *arg) ++{ ++ wlan_iterate_nodes(&wmip->wmi_scan_table, f, arg); ++} ++ ++/* ++ * WMI Extended Event received from Target. ++ */ ++A_STATUS ++wmi_control_rx_xtnd(struct wmi_t *wmip, void *osbuf) ++{ ++ WMIX_CMD_HDR *cmd; ++ A_UINT16 id; ++ A_UINT8 *datap; ++ A_UINT32 len; ++ A_STATUS status = A_OK; ++ ++ if (A_NETBUF_LEN(osbuf) < sizeof(WMIX_CMD_HDR)) { ++ A_DPRINTF(DBG_WMI, (DBGFMT "bad packet 1\n", DBGARG)); ++ wmip->wmi_stats.cmd_len_err++; ++ A_NETBUF_FREE(osbuf); ++ return A_ERROR; ++ } ++ ++ cmd = (WMIX_CMD_HDR *)A_NETBUF_DATA(osbuf); ++ id = cmd->commandId; ++ ++ if (A_NETBUF_PULL(osbuf, sizeof(WMIX_CMD_HDR)) != A_OK) { ++ A_DPRINTF(DBG_WMI, (DBGFMT "bad packet 2\n", DBGARG)); ++ wmip->wmi_stats.cmd_len_err++; ++ A_NETBUF_FREE(osbuf); ++ return A_ERROR; ++ } ++ ++ datap = A_NETBUF_DATA(osbuf); ++ len = A_NETBUF_LEN(osbuf); ++ ++ switch (id) { ++ case (WMIX_DSETOPENREQ_EVENTID): ++ status = wmi_dset_open_req_rx(wmip, datap, len); ++ break; ++#ifdef CONFIG_HOST_DSET_SUPPORT ++ case (WMIX_DSETCLOSE_EVENTID): ++ status = wmi_dset_close_rx(wmip, datap, len); ++ break; ++ case (WMIX_DSETDATAREQ_EVENTID): ++ status = wmi_dset_data_req_rx(wmip, datap, len); ++ break; ++#endif /* CONFIG_HOST_DSET_SUPPORT */ ++#ifdef CONFIG_HOST_GPIO_SUPPORT ++ case (WMIX_GPIO_INTR_EVENTID): ++ wmi_gpio_intr_rx(wmip, datap, len); ++ break; ++ case (WMIX_GPIO_DATA_EVENTID): ++ wmi_gpio_data_rx(wmip, datap, len); ++ break; ++ case (WMIX_GPIO_ACK_EVENTID): ++ wmi_gpio_ack_rx(wmip, datap, len); ++ break; ++#endif /* CONFIG_HOST_GPIO_SUPPORT */ ++ case (WMIX_HB_CHALLENGE_RESP_EVENTID): ++ wmi_hbChallengeResp_rx(wmip, datap, len); ++ break; ++ case (WMIX_DBGLOG_EVENTID): ++ wmi_dbglog_event_rx(wmip, datap, len); ++ break; ++ default: ++ A_DPRINTF(DBG_WMI|DBG_ERROR, ++ (DBGFMT "Unknown id 0x%x\n", DBGARG, id)); ++ wmip->wmi_stats.cmd_id_err++; ++ status = A_ERROR; ++ break; ++ } ++ ++ return status; ++} ++ ++/* ++ * Control Path ++ */ ++A_UINT32 cmdRecvNum; ++ ++A_STATUS ++wmi_control_rx(struct wmi_t *wmip, void *osbuf) ++{ ++ WMI_CMD_HDR *cmd; ++ A_UINT16 id; ++ A_UINT8 *datap; ++ A_UINT32 len, i, loggingReq; ++ A_STATUS status = A_OK; ++ ++ A_ASSERT(osbuf != NULL); ++ if (A_NETBUF_LEN(osbuf) < sizeof(WMI_CMD_HDR)) { ++ A_DPRINTF(DBG_WMI, (DBGFMT "bad packet 1\n", DBGARG)); ++ wmip->wmi_stats.cmd_len_err++; ++ A_NETBUF_FREE(osbuf); ++ return A_ERROR; ++ } ++ ++ cmd = (WMI_CMD_HDR *)A_NETBUF_DATA(osbuf); ++ id = cmd->commandId; ++ ++ if (A_NETBUF_PULL(osbuf, sizeof(WMI_CMD_HDR)) != A_OK) { ++ A_DPRINTF(DBG_WMI, (DBGFMT "bad packet 2\n", DBGARG)); ++ wmip->wmi_stats.cmd_len_err++; ++ A_NETBUF_FREE(osbuf); ++ return A_ERROR; ++ } ++ ++ datap = A_NETBUF_DATA(osbuf); ++ len = A_NETBUF_LEN(osbuf); ++ ++ ar6000_get_driver_cfg(wmip->wmi_devt, ++ AR6000_DRIVER_CFG_LOG_RAW_WMI_MSGS, ++ &loggingReq); ++ ++ if(loggingReq) { ++ AR_DEBUG_PRINTF(ATH_DEBUG_WMI, ("WMI %d \n",id)); ++ AR_DEBUG_PRINTF(ATH_DEBUG_WMI, ("WMI recv, MsgNo %d : ", cmdRecvNum)); ++ for(i = 0; i < len; i++) ++ AR_DEBUG_PRINTF(ATH_DEBUG_WMI, ("%x ", datap[i])); ++ AR_DEBUG_PRINTF(ATH_DEBUG_WMI, ("\n")); ++ } ++ ++ LOCK_WMI(wmip); ++ cmdRecvNum++; ++ UNLOCK_WMI(wmip); ++ ++ switch (id) { ++ case (WMI_GET_BITRATE_CMDID): ++ A_DPRINTF(DBG_WMI, (DBGFMT "WMI_GET_BITRATE_CMDID\n", DBGARG)); ++ status = wmi_bitrate_reply_rx(wmip, datap, len); ++ break; ++ case (WMI_GET_CHANNEL_LIST_CMDID): ++ A_DPRINTF(DBG_WMI, (DBGFMT "WMI_GET_CHANNEL_LIST_CMDID\n", DBGARG)); ++ status = wmi_channelList_reply_rx(wmip, datap, len); ++ break; ++ case (WMI_GET_TX_PWR_CMDID): ++ A_DPRINTF(DBG_WMI, (DBGFMT "WMI_GET_TX_PWR_CMDID\n", DBGARG)); ++ status = wmi_txPwr_reply_rx(wmip, datap, len); ++ break; ++ case (WMI_READY_EVENTID): ++ A_DPRINTF(DBG_WMI, (DBGFMT "WMI_READY_EVENTID\n", DBGARG)); ++ status = wmi_ready_event_rx(wmip, datap, len); ++ A_WMI_SEND_EVENT_TO_APP(wmip->wmi_devt, id, datap, len); ++ A_WMI_DBGLOG_INIT_DONE(wmip->wmi_devt); ++ break; ++ case (WMI_CONNECT_EVENTID): ++ A_DPRINTF(DBG_WMI, (DBGFMT "WMI_CONNECT_EVENTID\n", DBGARG)); ++ status = wmi_connect_event_rx(wmip, datap, len); ++ A_WMI_SEND_EVENT_TO_APP(wmip->wmi_devt, id, datap, len); ++ break; ++ case (WMI_DISCONNECT_EVENTID): ++ A_DPRINTF(DBG_WMI, (DBGFMT "WMI_DISCONNECT_EVENTID\n", DBGARG)); ++ status = wmi_disconnect_event_rx(wmip, datap, len); ++ A_WMI_SEND_EVENT_TO_APP(wmip->wmi_devt, id, datap, len); ++ break; ++ case (WMI_TKIP_MICERR_EVENTID): ++ A_DPRINTF(DBG_WMI, (DBGFMT "WMI_TKIP_MICERR_EVENTID\n", DBGARG)); ++ status = wmi_tkip_micerr_event_rx(wmip, datap, len); ++ break; ++ case (WMI_BSSINFO_EVENTID): ++ A_DPRINTF(DBG_WMI, (DBGFMT "WMI_BSSINFO_EVENTID\n", DBGARG)); ++ status = wmi_bssInfo_event_rx(wmip, datap, len); ++ A_WMI_SEND_EVENT_TO_APP(wmip->wmi_devt, id, datap, len); ++ break; ++ case (WMI_REGDOMAIN_EVENTID): ++ A_DPRINTF(DBG_WMI, (DBGFMT "WMI_REGDOMAIN_EVENTID\n", DBGARG)); ++ status = wmi_regDomain_event_rx(wmip, datap, len); ++ break; ++ case (WMI_PSTREAM_TIMEOUT_EVENTID): ++ A_DPRINTF(DBG_WMI, (DBGFMT "WMI_PSTREAM_TIMEOUT_EVENTID\n", DBGARG)); ++ status = wmi_pstream_timeout_event_rx(wmip, datap, len); ++ /* pstreams are fatpipe abstractions that get implicitly created. ++ * User apps only deal with thinstreams. creation of a thinstream ++ * by the user or data traffic flow in an AC triggers implicit ++ * pstream creation. Do we need to send this event to App..? ++ * no harm in sending it. ++ */ ++ A_WMI_SEND_EVENT_TO_APP(wmip->wmi_devt, id, datap, len); ++ break; ++ case (WMI_NEIGHBOR_REPORT_EVENTID): ++ A_DPRINTF(DBG_WMI, (DBGFMT "WMI_NEIGHBOR_REPORT_EVENTID\n", DBGARG)); ++ status = wmi_neighborReport_event_rx(wmip, datap, len); ++ break; ++ case (WMI_SCAN_COMPLETE_EVENTID): ++ A_DPRINTF(DBG_WMI, (DBGFMT "WMI_SCAN_COMPLETE_EVENTID\n", DBGARG)); ++ status = wmi_scanComplete_rx(wmip, datap, len); ++ A_WMI_SEND_EVENT_TO_APP(wmip->wmi_devt, id, datap, len); ++ break; ++ case (WMI_CMDERROR_EVENTID): ++ A_DPRINTF(DBG_WMI, (DBGFMT "WMI_CMDERROR_EVENTID\n", DBGARG)); ++ status = wmi_errorEvent_rx(wmip, datap, len); ++ break; ++ case (WMI_REPORT_STATISTICS_EVENTID): ++ A_DPRINTF(DBG_WMI, (DBGFMT "WMI_REPORT_STATISTICS_EVENTID\n", DBGARG)); ++ status = wmi_statsEvent_rx(wmip, datap, len); ++ break; ++ case (WMI_RSSI_THRESHOLD_EVENTID): ++ A_DPRINTF(DBG_WMI, (DBGFMT "WMI_RSSI_THRESHOLD_EVENTID\n", DBGARG)); ++ status = wmi_rssiThresholdEvent_rx(wmip, datap, len); ++ break; ++ case (WMI_ERROR_REPORT_EVENTID): ++ A_DPRINTF(DBG_WMI, (DBGFMT "WMI_ERROR_REPORT_EVENTID\n", DBGARG)); ++ status = wmi_reportErrorEvent_rx(wmip, datap, len); ++ A_WMI_SEND_EVENT_TO_APP(wmip->wmi_devt, id, datap, len); ++ break; ++ case (WMI_OPT_RX_FRAME_EVENTID): ++ A_DPRINTF(DBG_WMI, (DBGFMT "WMI_OPT_RX_FRAME_EVENTID\n", DBGARG)); ++ status = wmi_opt_frame_event_rx(wmip, datap, len); ++ break; ++ case (WMI_REPORT_ROAM_TBL_EVENTID): ++ A_DPRINTF(DBG_WMI, (DBGFMT "WMI_REPORT_ROAM_TBL_EVENTID\n", DBGARG)); ++ status = wmi_roam_tbl_event_rx(wmip, datap, len); ++ break; ++ case (WMI_EXTENSION_EVENTID): ++ A_DPRINTF(DBG_WMI, (DBGFMT "WMI_EXTENSION_EVENTID\n", DBGARG)); ++ status = wmi_control_rx_xtnd(wmip, osbuf); ++ break; ++ case (WMI_CAC_EVENTID): ++ A_DPRINTF(DBG_WMI, (DBGFMT "WMI_CAC_EVENTID\n", DBGARG)); ++ status = wmi_cac_event_rx(wmip, datap, len); ++ break; ++ case (WMI_REPORT_ROAM_DATA_EVENTID): ++ A_DPRINTF(DBG_WMI, (DBGFMT "WMI_REPORT_ROAM_DATA_EVENTID\n", DBGARG)); ++ status = wmi_roam_data_event_rx(wmip, datap, len); ++ break; ++#ifdef CONFIG_HOST_TCMD_SUPPORT ++ case (WMI_TEST_EVENTID): ++ A_DPRINTF(DBG_WMI, (DBGFMT "WMI_TEST_EVENTID\n", DBGARG)); ++ status = wmi_tcmd_test_report_rx(wmip, datap, len); ++ break; ++#endif ++ case (WMI_GET_FIXRATES_CMDID): ++ A_DPRINTF(DBG_WMI, (DBGFMT "WMI_GET_FIXRATES_CMDID\n", DBGARG)); ++ status = wmi_ratemask_reply_rx(wmip, datap, len); ++ break; ++ case (WMI_TX_RETRY_ERR_EVENTID): ++ A_DPRINTF(DBG_WMI, (DBGFMT "WMI_TX_RETRY_ERR_EVENTID\n", DBGARG)); ++ status = wmi_txRetryErrEvent_rx(wmip, datap, len); ++ A_WMI_SEND_EVENT_TO_APP(wmip->wmi_devt, id, datap, len); ++ break; ++ case (WMI_SNR_THRESHOLD_EVENTID): ++ A_DPRINTF(DBG_WMI, (DBGFMT "WMI_SNR_THRESHOLD_EVENTID\n", DBGARG)); ++ status = wmi_snrThresholdEvent_rx(wmip, datap, len); ++ A_WMI_SEND_EVENT_TO_APP(wmip->wmi_devt, id, datap, len); ++ break; ++ case (WMI_LQ_THRESHOLD_EVENTID): ++ A_DPRINTF(DBG_WMI, (DBGFMT "WMI_LQ_THRESHOLD_EVENTID\n", DBGARG)); ++ status = wmi_lqThresholdEvent_rx(wmip, datap, len); ++ A_WMI_SEND_EVENT_TO_APP(wmip->wmi_devt, id, datap, len); ++ break; ++ case (WMI_APLIST_EVENTID): ++ AR_DEBUG_PRINTF(ATH_DEBUG_WMI, ("Received APLIST Event\n")); ++ status = wmi_aplistEvent_rx(wmip, datap, len); ++ break; ++ case (WMI_GET_KEEPALIVE_CMDID): ++ A_DPRINTF(DBG_WMI, (DBGFMT "WMI_GET_KEEPALIVE_CMDID\n", DBGARG)); ++ status = wmi_keepalive_reply_rx(wmip, datap, len); ++ break; ++ case (WMI_GET_WOW_LIST_EVENTID): ++ status = wmi_get_wow_list_event_rx(wmip, datap, len); ++ break; ++ case (WMI_GET_PMKID_LIST_EVENTID): ++ A_DPRINTF(DBG_WMI, (DBGFMT "WMI_GET_PMKID_LIST Event\n", DBGARG)); ++ status = wmi_get_pmkid_list_event_rx(wmip, datap, len); ++ break; ++ default: ++ A_DPRINTF(DBG_WMI|DBG_ERROR, ++ (DBGFMT "Unknown id 0x%x\n", DBGARG, id)); ++ wmip->wmi_stats.cmd_id_err++; ++ status = A_ERROR; ++ break; ++ } ++ ++ A_NETBUF_FREE(osbuf); ++ ++ return status; ++} ++ ++static A_STATUS ++wmi_ready_event_rx(struct wmi_t *wmip, A_UINT8 *datap, int len) ++{ ++ WMI_READY_EVENT *ev = (WMI_READY_EVENT *)datap; ++ ++ if (len < sizeof(WMI_READY_EVENT)) { ++ return A_EINVAL; ++ } ++ A_DPRINTF(DBG_WMI, (DBGFMT "Enter\n", DBGARG)); ++ wmip->wmi_ready = TRUE; ++ A_WMI_READY_EVENT(wmip->wmi_devt, ev->macaddr, ev->phyCapability); ++ ++ return A_OK; ++} ++ ++static A_STATUS ++wmi_connect_event_rx(struct wmi_t *wmip, A_UINT8 *datap, int len) ++{ ++ WMI_CONNECT_EVENT *ev; ++ ++ if (len < sizeof(WMI_CONNECT_EVENT)) { ++ return A_EINVAL; ++ } ++ ev = (WMI_CONNECT_EVENT *)datap; ++ A_DPRINTF(DBG_WMI, ++ (DBGFMT "freq %d bssid %2.2x:%2.2x:%2.2x:%2.2x:%2.2x:%2.2x\n", ++ DBGARG, ev->channel, ++ ev->bssid[0], ev->bssid[1], ev->bssid[2], ++ ev->bssid[3], ev->bssid[4], ev->bssid[5])); ++ ++ A_MEMCPY(wmip->wmi_bssid, ev->bssid, ATH_MAC_LEN); ++ ++ A_WMI_CONNECT_EVENT(wmip->wmi_devt, ev->channel, ev->bssid, ++ ev->listenInterval, ev->beaconInterval, ++ ev->networkType, ev->beaconIeLen, ++ ev->assocReqLen, ev->assocRespLen, ++ ev->assocInfo); ++ ++ return A_OK; ++} ++ ++static A_STATUS ++wmi_regDomain_event_rx(struct wmi_t *wmip, A_UINT8 *datap, int len) ++{ ++ WMI_REG_DOMAIN_EVENT *ev; ++ ++ if (len < sizeof(*ev)) { ++ return A_EINVAL; ++ } ++ ev = (WMI_REG_DOMAIN_EVENT *)datap; ++ ++ A_WMI_REGDOMAIN_EVENT(wmip->wmi_devt, ev->regDomain); ++ ++ return A_OK; ++} ++ ++static A_STATUS ++wmi_neighborReport_event_rx(struct wmi_t *wmip, A_UINT8 *datap, int len) ++{ ++ WMI_NEIGHBOR_REPORT_EVENT *ev; ++ int numAps; ++ ++ if (len < sizeof(*ev)) { ++ return A_EINVAL; ++ } ++ ev = (WMI_NEIGHBOR_REPORT_EVENT *)datap; ++ numAps = ev->numberOfAps; ++ ++ if (len < (int)(sizeof(*ev) + ((numAps - 1) * sizeof(WMI_NEIGHBOR_INFO)))) { ++ return A_EINVAL; ++ } ++ ++ A_WMI_NEIGHBORREPORT_EVENT(wmip->wmi_devt, numAps, ev->neighbor); ++ ++ return A_OK; ++} ++ ++static A_STATUS ++wmi_disconnect_event_rx(struct wmi_t *wmip, A_UINT8 *datap, int len) ++{ ++ WMI_DISCONNECT_EVENT *ev; ++ ++ if (len < sizeof(WMI_DISCONNECT_EVENT)) { ++ return A_EINVAL; ++ } ++ A_DPRINTF(DBG_WMI, (DBGFMT "Enter\n", DBGARG)); ++ ++ ev = (WMI_DISCONNECT_EVENT *)datap; ++ ++ A_MEMZERO(wmip->wmi_bssid, sizeof(wmip->wmi_bssid)); ++ ++ A_WMI_DISCONNECT_EVENT(wmip->wmi_devt, ev->disconnectReason, ev->bssid, ++ ev->assocRespLen, ev->assocInfo, ev->protocolReasonStatus); ++ ++ return A_OK; ++} ++ ++static A_STATUS ++wmi_tkip_micerr_event_rx(struct wmi_t *wmip, A_UINT8 *datap, int len) ++{ ++ WMI_TKIP_MICERR_EVENT *ev; ++ ++ if (len < sizeof(*ev)) { ++ return A_EINVAL; ++ } ++ A_DPRINTF(DBG_WMI, (DBGFMT "Enter\n", DBGARG)); ++ ++ ev = (WMI_TKIP_MICERR_EVENT *)datap; ++ A_WMI_TKIP_MICERR_EVENT(wmip->wmi_devt, ev->keyid, ev->ismcast); ++ ++ return A_OK; ++} ++ ++static A_STATUS ++wmi_bssInfo_event_rx(struct wmi_t *wmip, A_UINT8 *datap, int len) ++{ ++ bss_t *bss; ++ WMI_BSS_INFO_HDR *bih; ++ A_UINT8 *buf; ++ A_UINT32 nodeCachingAllowed; ++ ++ if (len <= sizeof(WMI_BSS_INFO_HDR)) { ++ return A_EINVAL; ++ } ++ ++ A_WMI_BSSINFO_EVENT_RX(wmip->wmi_devt, datap, len); ++ /* What is driver config for wlan node caching? */ ++ if(ar6000_get_driver_cfg(wmip->wmi_devt, ++ AR6000_DRIVER_CFG_GET_WLANNODECACHING, ++ &nodeCachingAllowed) != A_OK) { ++ return A_EINVAL; ++ } ++ ++ if(!nodeCachingAllowed) { ++ return A_OK; ++ } ++ ++ ++ bih = (WMI_BSS_INFO_HDR *)datap; ++ buf = datap + sizeof(WMI_BSS_INFO_HDR); ++ len -= sizeof(WMI_BSS_INFO_HDR); ++ ++ A_DPRINTF(DBG_WMI2, (DBGFMT "bssInfo event - ch %u, rssi %02x, " ++ "bssid \"%02x:%02x:%02x:%02x:%02x:%02x\"\n", DBGARG, ++ bih->channel, (unsigned char) bih->rssi, bih->bssid[0], ++ bih->bssid[1], bih->bssid[2], bih->bssid[3], bih->bssid[4], ++ bih->bssid[5])); ++ ++ if(wps_enable && (bih->frameType == PROBERESP_FTYPE) ) { ++ printk("%s() A_OK 2\n", __FUNCTION__); ++ return A_OK; ++ } ++ ++ bss = wlan_find_node(&wmip->wmi_scan_table, bih->bssid); ++ if (bss != NULL) { ++ /* ++ * Free up the node. Not the most efficient process given ++ * we are about to allocate a new node but it is simple and should be ++ * adequate. ++ */ ++ wlan_node_reclaim(&wmip->wmi_scan_table, bss); ++ } ++ ++ bss = wlan_node_alloc(&wmip->wmi_scan_table, len); ++ if (bss == NULL) { ++ return A_NO_MEMORY; ++ } ++ ++ bss->ni_snr = bih->snr; ++ bss->ni_rssi = bih->rssi; ++ A_ASSERT(bss->ni_buf != NULL); ++ A_MEMCPY(bss->ni_buf, buf, len); ++ ++ if (wlan_parse_beacon(bss->ni_buf, len, &bss->ni_cie) != A_OK) { ++ wlan_node_free(bss); ++ return A_EINVAL; ++ } ++ ++ /* ++ * Update the frequency in ie_chan, overwriting of channel number ++ * which is done in wlan_parse_beacon ++ */ ++ bss->ni_cie.ie_chan = bih->channel; ++ wlan_setup_node(&wmip->wmi_scan_table, bss, bih->bssid); ++ ++ return A_OK; ++} ++ ++static A_STATUS ++wmi_opt_frame_event_rx(struct wmi_t *wmip, A_UINT8 *datap, int len) ++{ ++ bss_t *bss; ++ WMI_OPT_RX_INFO_HDR *bih; ++ A_UINT8 *buf; ++ ++ if (len <= sizeof(WMI_OPT_RX_INFO_HDR)) { ++ return A_EINVAL; ++ } ++ ++ bih = (WMI_OPT_RX_INFO_HDR *)datap; ++ buf = datap + sizeof(WMI_OPT_RX_INFO_HDR); ++ len -= sizeof(WMI_OPT_RX_INFO_HDR); ++ ++ A_DPRINTF(DBG_WMI2, (DBGFMT "opt frame event %2.2x:%2.2x\n", DBGARG, ++ bih->bssid[4], bih->bssid[5])); ++ ++ bss = wlan_find_node(&wmip->wmi_scan_table, bih->bssid); ++ if (bss != NULL) { ++ /* ++ * Free up the node. Not the most efficient process given ++ * we are about to allocate a new node but it is simple and should be ++ * adequate. ++ */ ++ wlan_node_reclaim(&wmip->wmi_scan_table, bss); ++ } ++ ++ bss = wlan_node_alloc(&wmip->wmi_scan_table, len); ++ if (bss == NULL) { ++ return A_NO_MEMORY; ++ } ++ ++ bss->ni_snr = bih->snr; ++ bss->ni_cie.ie_chan = bih->channel; ++ A_ASSERT(bss->ni_buf != NULL); ++ A_MEMCPY(bss->ni_buf, buf, len); ++ wlan_setup_node(&wmip->wmi_scan_table, bss, bih->bssid); ++ ++ return A_OK; ++} ++ ++ /* This event indicates inactivity timeout of a fatpipe(pstream) ++ * at the target ++ */ ++static A_STATUS ++wmi_pstream_timeout_event_rx(struct wmi_t *wmip, A_UINT8 *datap, int len) ++{ ++ WMI_PSTREAM_TIMEOUT_EVENT *ev; ++ ++ if (len < sizeof(WMI_PSTREAM_TIMEOUT_EVENT)) { ++ return A_EINVAL; ++ } ++ ++ A_DPRINTF(DBG_WMI, (DBGFMT "wmi_pstream_timeout_event_rx\n", DBGARG)); ++ ++ ev = (WMI_PSTREAM_TIMEOUT_EVENT *)datap; ++ ++ /* When the pstream (fat pipe == AC) timesout, it means there were no ++ * thinStreams within this pstream & it got implicitly created due to ++ * data flow on this AC. We start the inactivity timer only for ++ * implicitly created pstream. Just reset the host state. ++ */ ++ /* Set the activeTsids for this AC to 0 */ ++ LOCK_WMI(wmip); ++ wmip->wmi_streamExistsForAC[ev->trafficClass]=0; ++ wmip->wmi_fatPipeExists &= ~(1 << ev->trafficClass); ++ UNLOCK_WMI(wmip); ++ ++ /*Indicate inactivity to driver layer for this fatpipe (pstream)*/ ++ A_WMI_STREAM_TX_INACTIVE(wmip->wmi_devt, ev->trafficClass); ++ ++ return A_OK; ++} ++ ++static A_STATUS ++wmi_bitrate_reply_rx(struct wmi_t *wmip, A_UINT8 *datap, int len) ++{ ++ WMI_BIT_RATE_CMD *reply; ++ A_INT32 rate; ++ ++ if (len < sizeof(WMI_BIT_RATE_CMD)) { ++ return A_EINVAL; ++ } ++ reply = (WMI_BIT_RATE_CMD *)datap; ++ A_DPRINTF(DBG_WMI, ++ (DBGFMT "Enter - rateindex %d\n", DBGARG, reply->rateIndex)); ++ ++ if (reply->rateIndex == RATE_AUTO) { ++ rate = RATE_AUTO; ++ } else { ++ rate = wmi_rateTable[(A_UINT32) reply->rateIndex]; ++ } ++ ++ A_WMI_BITRATE_RX(wmip->wmi_devt, rate); ++ ++ return A_OK; ++} ++ ++static A_STATUS ++wmi_ratemask_reply_rx(struct wmi_t *wmip, A_UINT8 *datap, int len) ++{ ++ WMI_FIX_RATES_CMD *reply; ++ ++ if (len < sizeof(WMI_BIT_RATE_CMD)) { ++ return A_EINVAL; ++ } ++ reply = (WMI_FIX_RATES_CMD *)datap; ++ A_DPRINTF(DBG_WMI, ++ (DBGFMT "Enter - fixed rate mask %x\n", DBGARG, reply->fixRateMask)); ++ ++ A_WMI_RATEMASK_RX(wmip->wmi_devt, reply->fixRateMask); ++ ++ return A_OK; ++} ++ ++static A_STATUS ++wmi_channelList_reply_rx(struct wmi_t *wmip, A_UINT8 *datap, int len) ++{ ++ WMI_CHANNEL_LIST_REPLY *reply; ++ ++ if (len < sizeof(WMI_CHANNEL_LIST_REPLY)) { ++ return A_EINVAL; ++ } ++ reply = (WMI_CHANNEL_LIST_REPLY *)datap; ++ A_DPRINTF(DBG_WMI, (DBGFMT "Enter\n", DBGARG)); ++ ++ A_WMI_CHANNELLIST_RX(wmip->wmi_devt, reply->numChannels, ++ reply->channelList); ++ ++ return A_OK; ++} ++ ++static A_STATUS ++wmi_txPwr_reply_rx(struct wmi_t *wmip, A_UINT8 *datap, int len) ++{ ++ WMI_TX_PWR_REPLY *reply; ++ ++ if (len < sizeof(*reply)) { ++ return A_EINVAL; ++ } ++ reply = (WMI_TX_PWR_REPLY *)datap; ++ A_DPRINTF(DBG_WMI, (DBGFMT "Enter\n", DBGARG)); ++ ++ A_WMI_TXPWR_RX(wmip->wmi_devt, reply->dbM); ++ ++ return A_OK; ++} ++static A_STATUS ++wmi_keepalive_reply_rx(struct wmi_t *wmip, A_UINT8 *datap, int len) ++{ ++ WMI_GET_KEEPALIVE_CMD *reply; ++ ++ if (len < sizeof(*reply)) { ++ return A_EINVAL; ++ } ++ reply = (WMI_GET_KEEPALIVE_CMD *)datap; ++ A_DPRINTF(DBG_WMI, (DBGFMT "Enter\n", DBGARG)); ++ ++ A_WMI_KEEPALIVE_RX(wmip->wmi_devt, reply->configured); ++ ++ return A_OK; ++} ++ ++ ++static A_STATUS ++wmi_dset_open_req_rx(struct wmi_t *wmip, A_UINT8 *datap, int len) ++{ ++ WMIX_DSETOPENREQ_EVENT *dsetopenreq; ++ ++ if (len < sizeof(WMIX_DSETOPENREQ_EVENT)) { ++ return A_EINVAL; ++ } ++ dsetopenreq = (WMIX_DSETOPENREQ_EVENT *)datap; ++ A_DPRINTF(DBG_WMI, ++ (DBGFMT "Enter - dset_id=0x%x\n", DBGARG, dsetopenreq->dset_id)); ++ A_WMI_DSET_OPEN_REQ(wmip->wmi_devt, ++ dsetopenreq->dset_id, ++ dsetopenreq->targ_dset_handle, ++ dsetopenreq->targ_reply_fn, ++ dsetopenreq->targ_reply_arg); ++ ++ return A_OK; ++} ++ ++#ifdef CONFIG_HOST_DSET_SUPPORT ++static A_STATUS ++wmi_dset_close_rx(struct wmi_t *wmip, A_UINT8 *datap, int len) ++{ ++ WMIX_DSETCLOSE_EVENT *dsetclose; ++ ++ if (len < sizeof(WMIX_DSETCLOSE_EVENT)) { ++ return A_EINVAL; ++ } ++ A_DPRINTF(DBG_WMI, (DBGFMT "Enter\n", DBGARG)); ++ ++ dsetclose = (WMIX_DSETCLOSE_EVENT *)datap; ++ A_WMI_DSET_CLOSE(wmip->wmi_devt, dsetclose->access_cookie); ++ ++ return A_OK; ++} ++ ++static A_STATUS ++wmi_dset_data_req_rx(struct wmi_t *wmip, A_UINT8 *datap, int len) ++{ ++ WMIX_DSETDATAREQ_EVENT *dsetdatareq; ++ ++ if (len < sizeof(WMIX_DSETDATAREQ_EVENT)) { ++ return A_EINVAL; ++ } ++ A_DPRINTF(DBG_WMI, (DBGFMT "Enter\n", DBGARG)); ++ ++ dsetdatareq = (WMIX_DSETDATAREQ_EVENT *)datap; ++ A_WMI_DSET_DATA_REQ(wmip->wmi_devt, ++ dsetdatareq->access_cookie, ++ dsetdatareq->offset, ++ dsetdatareq->length, ++ dsetdatareq->targ_buf, ++ dsetdatareq->targ_reply_fn, ++ dsetdatareq->targ_reply_arg); ++ ++ return A_OK; ++} ++#endif /* CONFIG_HOST_DSET_SUPPORT */ ++ ++static A_STATUS ++wmi_scanComplete_rx(struct wmi_t *wmip, A_UINT8 *datap, int len) ++{ ++ WMI_SCAN_COMPLETE_EVENT *ev; ++ ++ ev = (WMI_SCAN_COMPLETE_EVENT *)datap; ++ A_WMI_SCANCOMPLETE_EVENT(wmip->wmi_devt, ev->status); ++ ++ return A_OK; ++} ++ ++/* ++ * Target is reporting a programming error. This is for ++ * developer aid only. Target only checks a few common violations ++ * and it is responsibility of host to do all error checking. ++ * Behavior of target after wmi error event is undefined. ++ * A reset is recommended. ++ */ ++static A_STATUS ++wmi_errorEvent_rx(struct wmi_t *wmip, A_UINT8 *datap, int len) ++{ ++ WMI_CMD_ERROR_EVENT *ev; ++ ++ ev = (WMI_CMD_ERROR_EVENT *)datap; ++ AR_DEBUG_PRINTF(ATH_DEBUG_WMI, ("Programming Error: cmd=%d ", ev->commandId)); ++ switch (ev->errorCode) { ++ case (INVALID_PARAM): ++ AR_DEBUG_PRINTF(ATH_DEBUG_WMI, ("Illegal Parameter\n")); ++ break; ++ case (ILLEGAL_STATE): ++ AR_DEBUG_PRINTF(ATH_DEBUG_WMI, ("Illegal State\n")); ++ break; ++ case (INTERNAL_ERROR): ++ AR_DEBUG_PRINTF(ATH_DEBUG_WMI, ("Internal Error\n")); ++ break; ++ } ++ ++ return A_OK; ++} ++ ++ ++static A_STATUS ++wmi_statsEvent_rx(struct wmi_t *wmip, A_UINT8 *datap, int len) ++{ ++ WMI_TARGET_STATS *reply; ++ ++ if (len < sizeof(*reply)) { ++ return A_EINVAL; ++ } ++ reply = (WMI_TARGET_STATS *)datap; ++ A_DPRINTF(DBG_WMI, (DBGFMT "Enter\n", DBGARG)); ++ ++ A_WMI_TARGETSTATS_EVENT(wmip->wmi_devt, reply); ++ ++ return A_OK; ++} ++ ++static A_STATUS ++wmi_rssiThresholdEvent_rx(struct wmi_t *wmip, A_UINT8 *datap, int len) ++{ ++ WMI_RSSI_THRESHOLD_EVENT *reply; ++ ++ if (len < sizeof(*reply)) { ++ return A_EINVAL; ++ } ++ reply = (WMI_RSSI_THRESHOLD_EVENT *)datap; ++ A_DPRINTF(DBG_WMI, (DBGFMT "Enter\n", DBGARG)); ++ ++ A_WMI_RSSI_THRESHOLD_EVENT(wmip->wmi_devt, reply->range, reply->rssi); ++ ++ return A_OK; ++} ++ ++ ++static A_STATUS ++wmi_reportErrorEvent_rx(struct wmi_t *wmip, A_UINT8 *datap, int len) ++{ ++ WMI_TARGET_ERROR_REPORT_EVENT *reply; ++ ++ if (len < sizeof(*reply)) { ++ return A_EINVAL; ++ } ++ reply = (WMI_TARGET_ERROR_REPORT_EVENT *)datap; ++ A_DPRINTF(DBG_WMI, (DBGFMT "Enter\n", DBGARG)); ++ ++ A_WMI_REPORT_ERROR_EVENT(wmip->wmi_devt, reply->errorVal); ++ ++ return A_OK; ++} ++ ++static A_STATUS ++wmi_cac_event_rx(struct wmi_t *wmip, A_UINT8 *datap, int len) ++{ ++ WMI_CAC_EVENT *reply; ++ ++ if (len < sizeof(*reply)) { ++ return A_EINVAL; ++ } ++ reply = (WMI_CAC_EVENT *)datap; ++ A_DPRINTF(DBG_WMI, (DBGFMT "Enter\n", DBGARG)); ++ ++ A_WMI_CAC_EVENT(wmip->wmi_devt, reply->ac, ++ reply->cac_indication, reply->statusCode, ++ reply->tspecSuggestion); ++ ++ return A_OK; ++} ++ ++static A_STATUS ++wmi_hbChallengeResp_rx(struct wmi_t *wmip, A_UINT8 *datap, int len) ++{ ++ WMIX_HB_CHALLENGE_RESP_EVENT *reply; ++ ++ if (len < sizeof(*reply)) { ++ return A_EINVAL; ++ } ++ reply = (WMIX_HB_CHALLENGE_RESP_EVENT *)datap; ++ A_DPRINTF(DBG_WMI, (DBGFMT "wmi: challenge response event\n", DBGARG)); ++ ++ A_WMI_HBCHALLENGERESP_EVENT(wmip->wmi_devt, reply->cookie, reply->source); ++ ++ return A_OK; ++} ++ ++static A_STATUS ++wmi_roam_tbl_event_rx(struct wmi_t *wmip, A_UINT8 *datap, int len) ++{ ++ WMI_TARGET_ROAM_TBL *reply; ++ ++ if (len < sizeof(*reply)) { ++ return A_EINVAL; ++ } ++ reply = (WMI_TARGET_ROAM_TBL *)datap; ++ A_DPRINTF(DBG_WMI, (DBGFMT "Enter\n", DBGARG)); ++ ++ A_WMI_ROAM_TABLE_EVENT(wmip->wmi_devt, reply); ++ ++ return A_OK; ++} ++ ++static A_STATUS ++wmi_roam_data_event_rx(struct wmi_t *wmip, A_UINT8 *datap, int len) ++{ ++ WMI_TARGET_ROAM_DATA *reply; ++ ++ if (len < sizeof(*reply)) { ++ return A_EINVAL; ++ } ++ reply = (WMI_TARGET_ROAM_DATA *)datap; ++ A_DPRINTF(DBG_WMI, (DBGFMT "Enter\n", DBGARG)); ++ ++ A_WMI_ROAM_DATA_EVENT(wmip->wmi_devt, reply); ++ ++ return A_OK; ++} ++ ++static A_STATUS ++wmi_txRetryErrEvent_rx(struct wmi_t *wmip, A_UINT8 *datap, int len) ++{ ++ WMI_TX_RETRY_ERR_EVENT *reply; ++ ++ if (len < sizeof(*reply)) { ++ return A_EINVAL; ++ } ++ reply = (WMI_TX_RETRY_ERR_EVENT *)datap; ++ A_DPRINTF(DBG_WMI, (DBGFMT "Enter\n", DBGARG)); ++ ++ A_WMI_TX_RETRY_ERR_EVENT(wmip->wmi_devt); ++ ++ return A_OK; ++} ++ ++static A_STATUS ++wmi_snrThresholdEvent_rx(struct wmi_t *wmip, A_UINT8 *datap, int len) ++{ ++ WMI_SNR_THRESHOLD_EVENT *reply; ++ ++ if (len < sizeof(*reply)) { ++ return A_EINVAL; ++ } ++ reply = (WMI_SNR_THRESHOLD_EVENT *)datap; ++ A_DPRINTF(DBG_WMI, (DBGFMT "Enter\n", DBGARG)); ++ ++ A_WMI_SNR_THRESHOLD_EVENT_RX(wmip->wmi_devt, reply->range, reply->snr); ++ ++ return A_OK; ++} ++ ++static A_STATUS ++wmi_lqThresholdEvent_rx(struct wmi_t *wmip, A_UINT8 *datap, int len) ++{ ++ WMI_LQ_THRESHOLD_EVENT *reply; ++ ++ if (len < sizeof(*reply)) { ++ return A_EINVAL; ++ } ++ reply = (WMI_LQ_THRESHOLD_EVENT *)datap; ++ A_DPRINTF(DBG_WMI, (DBGFMT "Enter\n", DBGARG)); ++ ++ A_WMI_LQ_THRESHOLD_EVENT_RX(wmip->wmi_devt, reply->range, reply->lq); ++ ++ return A_OK; ++} ++ ++static A_STATUS ++wmi_aplistEvent_rx(struct wmi_t *wmip, A_UINT8 *datap, int len) ++{ ++ A_UINT16 ap_info_entry_size; ++ WMI_APLIST_EVENT *ev = (WMI_APLIST_EVENT *)datap; ++ WMI_AP_INFO_V1 *ap_info_v1; ++ A_UINT8 i; ++ ++ if (len < sizeof(WMI_APLIST_EVENT)) { ++ return A_EINVAL; ++ } ++ ++ if (ev->apListVer == APLIST_VER1) { ++ ap_info_entry_size = sizeof(WMI_AP_INFO_V1); ++ ap_info_v1 = (WMI_AP_INFO_V1 *)ev->apList; ++ } else { ++ return A_EINVAL; ++ } ++ ++ AR_DEBUG_PRINTF(ATH_DEBUG_WMI, ("Number of APs in APLIST Event is %d\n", ev->numAP)); ++ if (len < (int)(sizeof(WMI_APLIST_EVENT) + ++ (ev->numAP - 1) * ap_info_entry_size)) ++ { ++ return A_EINVAL; ++ } ++ ++ /* ++ * AP List Ver1 Contents ++ */ ++ for (i = 0; i < ev->numAP; i++) { ++ AR_DEBUG_PRINTF(ATH_DEBUG_WMI, ("AP#%d BSSID %2.2x %2.2x %2.2x %2.2x %2.2x %2.2x "\ ++ "Channel %d\n", i, ++ ap_info_v1->bssid[0], ap_info_v1->bssid[1], ++ ap_info_v1->bssid[2], ap_info_v1->bssid[3], ++ ap_info_v1->bssid[4], ap_info_v1->bssid[5], ++ ap_info_v1->channel)); ++ ap_info_v1++; ++ } ++ return A_OK; ++} ++ ++static A_STATUS ++wmi_dbglog_event_rx(struct wmi_t *wmip, A_UINT8 *datap, int len) ++{ ++ A_UINT32 dropped; ++ ++ dropped = *((A_UINT32 *)datap); ++ datap += sizeof(dropped); ++ len -= sizeof(dropped); ++ A_WMI_DBGLOG_EVENT(wmip->wmi_devt, dropped, datap, len); ++ return A_OK; ++} ++ ++#ifdef CONFIG_HOST_GPIO_SUPPORT ++static A_STATUS ++wmi_gpio_intr_rx(struct wmi_t *wmip, A_UINT8 *datap, int len) ++{ ++ WMIX_GPIO_INTR_EVENT *gpio_intr = (WMIX_GPIO_INTR_EVENT *)datap; ++ ++ A_DPRINTF(DBG_WMI, ++ (DBGFMT "Enter - intrmask=0x%x input=0x%x.\n", DBGARG, ++ gpio_intr->intr_mask, gpio_intr->input_values)); ++ ++ A_WMI_GPIO_INTR_RX(gpio_intr->intr_mask, gpio_intr->input_values); ++ ++ return A_OK; ++} ++ ++static A_STATUS ++wmi_gpio_data_rx(struct wmi_t *wmip, A_UINT8 *datap, int len) ++{ ++ WMIX_GPIO_DATA_EVENT *gpio_data = (WMIX_GPIO_DATA_EVENT *)datap; ++ ++ A_DPRINTF(DBG_WMI, ++ (DBGFMT "Enter - reg=%d value=0x%x\n", DBGARG, ++ gpio_data->reg_id, gpio_data->value)); ++ ++ A_WMI_GPIO_DATA_RX(gpio_data->reg_id, gpio_data->value); ++ ++ return A_OK; ++} ++ ++static A_STATUS ++wmi_gpio_ack_rx(struct wmi_t *wmip, A_UINT8 *datap, int len) ++{ ++ A_DPRINTF(DBG_WMI, (DBGFMT "Enter\n", DBGARG)); ++ ++ A_WMI_GPIO_ACK_RX(); ++ ++ return A_OK; ++} ++#endif /* CONFIG_HOST_GPIO_SUPPORT */ ++ ++/* ++ * Called to send a wmi command. Command specific data is already built ++ * on osbuf and current osbuf->data points to it. ++ */ ++A_STATUS ++wmi_cmd_send(struct wmi_t *wmip, void *osbuf, WMI_COMMAND_ID cmdId, ++ WMI_SYNC_FLAG syncflag) ++{ ++#define IS_LONG_CMD(cmdId) ((cmdId == WMI_OPT_TX_FRAME_CMDID) || (cmdId == WMI_ADD_WOW_PATTERN_CMDID)) ++ WMI_CMD_HDR *cHdr; ++ WMI_PRI_STREAM_ID streamID = WMI_CONTROL_PRI; ++ ++ A_ASSERT(osbuf != NULL); ++ ++ if (syncflag >= END_WMIFLAG) { ++ return A_EINVAL; ++ } ++ ++ if ((syncflag == SYNC_BEFORE_WMIFLAG) || (syncflag == SYNC_BOTH_WMIFLAG)) { ++ /* ++ * We want to make sure all data currently queued is transmitted before ++ * the cmd execution. Establish a new sync point. ++ */ ++ wmi_sync_point(wmip); ++ } ++ ++ if (A_NETBUF_PUSH(osbuf, sizeof(WMI_CMD_HDR)) != A_OK) { ++ return A_NO_MEMORY; ++ } ++ ++ cHdr = (WMI_CMD_HDR *)A_NETBUF_DATA(osbuf); ++ cHdr->commandId = cmdId; ++ ++ /* ++ * Send cmd, some via control pipe, others via data pipe ++ */ ++ if (IS_LONG_CMD(cmdId)) { ++ wmi_data_hdr_add(wmip, osbuf, CNTL_MSGTYPE); ++ // TODO ... these can now go through the control endpoint via HTC 2.0 ++ streamID = WMI_BEST_EFFORT_PRI; ++ } ++ A_WMI_CONTROL_TX(wmip->wmi_devt, osbuf, streamID); ++ ++ if ((syncflag == SYNC_AFTER_WMIFLAG) || (syncflag == SYNC_BOTH_WMIFLAG)) { ++ /* ++ * We want to make sure all new data queued waits for the command to ++ * execute. Establish a new sync point. ++ */ ++ wmi_sync_point(wmip); ++ } ++ return (A_OK); ++#undef IS_LONG_CMD ++} ++ ++A_STATUS ++wmi_cmd_send_xtnd(struct wmi_t *wmip, void *osbuf, WMI_COMMAND_ID cmdId, ++ WMI_SYNC_FLAG syncflag) ++{ ++ WMIX_CMD_HDR *cHdr; ++ ++ if (A_NETBUF_PUSH(osbuf, sizeof(WMIX_CMD_HDR)) != A_OK) { ++ return A_NO_MEMORY; ++ } ++ ++ cHdr = (WMIX_CMD_HDR *)A_NETBUF_DATA(osbuf); ++ cHdr->commandId = cmdId; ++ ++ return wmi_cmd_send(wmip, osbuf, WMI_EXTENSION_CMDID, syncflag); ++} ++ ++A_STATUS ++wmi_connect_cmd(struct wmi_t *wmip, NETWORK_TYPE netType, ++ DOT11_AUTH_MODE dot11AuthMode, AUTH_MODE authMode, ++ CRYPTO_TYPE pairwiseCrypto, A_UINT8 pairwiseCryptoLen, ++ CRYPTO_TYPE groupCrypto,A_UINT8 groupCryptoLen, ++ int ssidLength, A_UCHAR *ssid, ++ A_UINT8 *bssid, A_UINT16 channel, A_UINT32 ctrl_flags) ++{ ++ void *osbuf; ++ WMI_CONNECT_CMD *cc; ++ ++ if ((pairwiseCrypto == NONE_CRYPT) && (groupCrypto != NONE_CRYPT)) { ++ return A_EINVAL; ++ } ++ if ((pairwiseCrypto != NONE_CRYPT) && (groupCrypto == NONE_CRYPT)) { ++ return A_EINVAL; ++ } ++ ++ osbuf = A_NETBUF_ALLOC(sizeof(WMI_CONNECT_CMD)); ++ if (osbuf == NULL) { ++ return A_NO_MEMORY; ++ } ++ ++ A_NETBUF_PUT(osbuf, sizeof(WMI_CONNECT_CMD)); ++ ++ cc = (WMI_CONNECT_CMD *)(A_NETBUF_DATA(osbuf)); ++ A_MEMZERO(cc, sizeof(*cc)); ++ ++ A_MEMCPY(cc->ssid, ssid, ssidLength); ++ cc->ssidLength = ssidLength; ++ cc->networkType = netType; ++ cc->dot11AuthMode = dot11AuthMode; ++ cc->authMode = authMode; ++ cc->pairwiseCryptoType = pairwiseCrypto; ++ cc->pairwiseCryptoLen = pairwiseCryptoLen; ++ cc->groupCryptoType = groupCrypto; ++ cc->groupCryptoLen = groupCryptoLen; ++ cc->channel = channel; ++ cc->ctrl_flags = ctrl_flags; ++ ++ if (bssid != NULL) { ++ A_MEMCPY(cc->bssid, bssid, ATH_MAC_LEN); ++ } ++ if (wmi_set_keepalive_cmd(wmip, wmip->wmi_keepaliveInterval) != A_OK) { ++ return(A_ERROR); ++ } ++ ++ return (wmi_cmd_send(wmip, osbuf, WMI_CONNECT_CMDID, NO_SYNC_WMIFLAG)); ++} ++ ++A_STATUS ++wmi_reconnect_cmd(struct wmi_t *wmip, A_UINT8 *bssid, A_UINT16 channel) ++{ ++ void *osbuf; ++ WMI_RECONNECT_CMD *cc; ++ ++ osbuf = A_NETBUF_ALLOC(sizeof(WMI_RECONNECT_CMD)); ++ if (osbuf == NULL) { ++ return A_NO_MEMORY; ++ } ++ ++ A_NETBUF_PUT(osbuf, sizeof(WMI_RECONNECT_CMD)); ++ ++ cc = (WMI_RECONNECT_CMD *)(A_NETBUF_DATA(osbuf)); ++ A_MEMZERO(cc, sizeof(*cc)); ++ ++ cc->channel = channel; ++ ++ if (bssid != NULL) { ++ A_MEMCPY(cc->bssid, bssid, ATH_MAC_LEN); ++ } ++ ++ return (wmi_cmd_send(wmip, osbuf, WMI_RECONNECT_CMDID, NO_SYNC_WMIFLAG)); ++} ++ ++A_STATUS ++wmi_disconnect_cmd(struct wmi_t *wmip) ++{ ++ void *osbuf; ++ A_STATUS status; ++ ++ osbuf = A_NETBUF_ALLOC(0); /* no payload */ ++ if (osbuf == NULL) { ++ return A_NO_MEMORY; ++ } ++ ++ /* Bug fix for 24817(elevator bug) - the disconnect command does not ++ need to do a SYNC before.*/ ++ status = (wmi_cmd_send(wmip, osbuf, WMI_DISCONNECT_CMDID, ++ NO_SYNC_WMIFLAG)); ++ ++ return status; ++} ++ ++A_STATUS ++wmi_startscan_cmd(struct wmi_t *wmip, WMI_SCAN_TYPE scanType, ++ A_BOOL forceFgScan, A_BOOL isLegacy, ++ A_UINT32 homeDwellTime, A_UINT32 forceScanInterval) ++{ ++ void *osbuf; ++ WMI_START_SCAN_CMD *sc; ++ ++ if ((scanType != WMI_LONG_SCAN) && (scanType != WMI_SHORT_SCAN)) { ++ return A_EINVAL; ++ } ++ ++ osbuf = A_NETBUF_ALLOC(sizeof(*sc)); ++ if (osbuf == NULL) { ++ return A_NO_MEMORY; ++ } ++ ++ A_NETBUF_PUT(osbuf, sizeof(*sc)); ++ ++ sc = (WMI_START_SCAN_CMD *)(A_NETBUF_DATA(osbuf)); ++ sc->scanType = scanType; ++ sc->forceFgScan = forceFgScan; ++ sc->isLegacy = isLegacy; ++ sc->homeDwellTime = homeDwellTime; ++ sc->forceScanInterval = forceScanInterval; ++ ++ return (wmi_cmd_send(wmip, osbuf, WMI_START_SCAN_CMDID, NO_SYNC_WMIFLAG)); ++} ++ ++A_STATUS ++wmi_scanparams_cmd(struct wmi_t *wmip, A_UINT16 fg_start_sec, ++ A_UINT16 fg_end_sec, A_UINT16 bg_sec, ++ A_UINT16 minact_chdw_msec, A_UINT16 maxact_chdw_msec, ++ A_UINT16 pas_chdw_msec, ++ A_UINT8 shScanRatio, A_UINT8 scanCtrlFlags, ++ A_UINT32 max_dfsch_act_time) ++{ ++ void *osbuf; ++ WMI_SCAN_PARAMS_CMD *sc; ++ ++ osbuf = A_NETBUF_ALLOC(sizeof(*sc)); ++ if (osbuf == NULL) { ++ return A_NO_MEMORY; ++ } ++ ++ A_NETBUF_PUT(osbuf, sizeof(*sc)); ++ ++ sc = (WMI_SCAN_PARAMS_CMD *)(A_NETBUF_DATA(osbuf)); ++ A_MEMZERO(sc, sizeof(*sc)); ++ sc->fg_start_period = fg_start_sec; ++ sc->fg_end_period = fg_end_sec; ++ sc->bg_period = bg_sec; ++ sc->minact_chdwell_time = minact_chdw_msec; ++ sc->maxact_chdwell_time = maxact_chdw_msec; ++ sc->pas_chdwell_time = pas_chdw_msec; ++ sc->shortScanRatio = shScanRatio; ++ sc->scanCtrlFlags = scanCtrlFlags; ++ sc->max_dfsch_act_time = max_dfsch_act_time; ++ ++ return (wmi_cmd_send(wmip, osbuf, WMI_SET_SCAN_PARAMS_CMDID, ++ NO_SYNC_WMIFLAG)); ++} ++ ++A_STATUS ++wmi_bssfilter_cmd(struct wmi_t *wmip, A_UINT8 filter, A_UINT32 ieMask) ++{ ++ void *osbuf; ++ WMI_BSS_FILTER_CMD *cmd; ++ ++ if (filter >= LAST_BSS_FILTER) { ++ return A_EINVAL; ++ } ++ ++ osbuf = A_NETBUF_ALLOC(sizeof(*cmd)); ++ if (osbuf == NULL) { ++ return A_NO_MEMORY; ++ } ++ ++ A_NETBUF_PUT(osbuf, sizeof(*cmd)); ++ ++ cmd = (WMI_BSS_FILTER_CMD *)(A_NETBUF_DATA(osbuf)); ++ A_MEMZERO(cmd, sizeof(*cmd)); ++ cmd->bssFilter = filter; ++ cmd->ieMask = ieMask; ++ ++ return (wmi_cmd_send(wmip, osbuf, WMI_SET_BSS_FILTER_CMDID, ++ NO_SYNC_WMIFLAG)); ++} ++ ++A_STATUS ++wmi_probedSsid_cmd(struct wmi_t *wmip, A_UINT8 index, A_UINT8 flag, ++ A_UINT8 ssidLength, A_UCHAR *ssid) ++{ ++ void *osbuf; ++ WMI_PROBED_SSID_CMD *cmd; ++ ++ if (index > MAX_PROBED_SSID_INDEX) { ++ return A_EINVAL; ++ } ++ if (ssidLength > sizeof(cmd->ssid)) { ++ return A_EINVAL; ++ } ++ if ((flag & (DISABLE_SSID_FLAG | ANY_SSID_FLAG)) && (ssidLength > 0)) { ++ return A_EINVAL; ++ } ++ if ((flag & SPECIFIC_SSID_FLAG) && !ssidLength) { ++ return A_EINVAL; ++ } ++ ++ osbuf = A_NETBUF_ALLOC(sizeof(*cmd)); ++ if (osbuf == NULL) { ++ return A_NO_MEMORY; ++ } ++ ++ A_NETBUF_PUT(osbuf, sizeof(*cmd)); ++ ++ cmd = (WMI_PROBED_SSID_CMD *)(A_NETBUF_DATA(osbuf)); ++ A_MEMZERO(cmd, sizeof(*cmd)); ++ cmd->entryIndex = index; ++ cmd->flag = flag; ++ cmd->ssidLength = ssidLength; ++ A_MEMCPY(cmd->ssid, ssid, ssidLength); ++ ++ return (wmi_cmd_send(wmip, osbuf, WMI_SET_PROBED_SSID_CMDID, ++ NO_SYNC_WMIFLAG)); ++} ++ ++A_STATUS ++wmi_listeninterval_cmd(struct wmi_t *wmip, A_UINT16 listenInterval, A_UINT16 listenBeacons) ++{ ++ void *osbuf; ++ WMI_LISTEN_INT_CMD *cmd; ++ ++ osbuf = A_NETBUF_ALLOC(sizeof(*cmd)); ++ if (osbuf == NULL) { ++ return A_NO_MEMORY; ++ } ++ ++ A_NETBUF_PUT(osbuf, sizeof(*cmd)); ++ ++ cmd = (WMI_LISTEN_INT_CMD *)(A_NETBUF_DATA(osbuf)); ++ A_MEMZERO(cmd, sizeof(*cmd)); ++ cmd->listenInterval = listenInterval; ++ cmd->numBeacons = listenBeacons; ++ ++ return (wmi_cmd_send(wmip, osbuf, WMI_SET_LISTEN_INT_CMDID, ++ NO_SYNC_WMIFLAG)); ++} ++ ++A_STATUS ++wmi_bmisstime_cmd(struct wmi_t *wmip, A_UINT16 bmissTime, A_UINT16 bmissBeacons) ++{ ++ void *osbuf; ++ WMI_BMISS_TIME_CMD *cmd; ++ ++ osbuf = A_NETBUF_ALLOC(sizeof(*cmd)); ++ if (osbuf == NULL) { ++ return A_NO_MEMORY; ++ } ++ ++ A_NETBUF_PUT(osbuf, sizeof(*cmd)); ++ ++ cmd = (WMI_BMISS_TIME_CMD *)(A_NETBUF_DATA(osbuf)); ++ A_MEMZERO(cmd, sizeof(*cmd)); ++ cmd->bmissTime = bmissTime; ++ cmd->numBeacons = bmissBeacons; ++ ++ return (wmi_cmd_send(wmip, osbuf, WMI_SET_BMISS_TIME_CMDID, ++ NO_SYNC_WMIFLAG)); ++} ++ ++A_STATUS ++wmi_associnfo_cmd(struct wmi_t *wmip, A_UINT8 ieType, ++ A_UINT8 ieLen, A_UINT8 *ieInfo) ++{ ++ void *osbuf; ++ WMI_SET_ASSOC_INFO_CMD *cmd; ++ A_UINT16 cmdLen; ++ ++ cmdLen = sizeof(*cmd) + ieLen - 1; ++ osbuf = A_NETBUF_ALLOC(cmdLen); ++ if (osbuf == NULL) { ++ return A_NO_MEMORY; ++ } ++ ++ A_NETBUF_PUT(osbuf, cmdLen); ++ ++ cmd = (WMI_SET_ASSOC_INFO_CMD *)(A_NETBUF_DATA(osbuf)); ++ A_MEMZERO(cmd, cmdLen); ++ cmd->ieType = ieType; ++ cmd->bufferSize = ieLen; ++ A_MEMCPY(cmd->assocInfo, ieInfo, ieLen); ++ ++ return (wmi_cmd_send(wmip, osbuf, WMI_SET_ASSOC_INFO_CMDID, ++ NO_SYNC_WMIFLAG)); ++} ++ ++A_STATUS ++wmi_powermode_cmd(struct wmi_t *wmip, A_UINT8 powerMode) ++{ ++ void *osbuf; ++ WMI_POWER_MODE_CMD *cmd; ++ ++ osbuf = A_NETBUF_ALLOC(sizeof(*cmd)); ++ if (osbuf == NULL) { ++ return A_NO_MEMORY; ++ } ++ ++ A_NETBUF_PUT(osbuf, sizeof(*cmd)); ++ ++ cmd = (WMI_POWER_MODE_CMD *)(A_NETBUF_DATA(osbuf)); ++ A_MEMZERO(cmd, sizeof(*cmd)); ++ cmd->powerMode = powerMode; ++ wmip->wmi_powerMode = powerMode; ++ ++ return (wmi_cmd_send(wmip, osbuf, WMI_SET_POWER_MODE_CMDID, ++ NO_SYNC_WMIFLAG)); ++} ++ ++A_STATUS ++wmi_ibsspmcaps_cmd(struct wmi_t *wmip, A_UINT8 pmEnable, A_UINT8 ttl, ++ A_UINT16 atim_windows, A_UINT16 timeout_value) ++{ ++ void *osbuf; ++ WMI_IBSS_PM_CAPS_CMD *cmd; ++ ++ osbuf = A_NETBUF_ALLOC(sizeof(*cmd)); ++ if (osbuf == NULL) { ++ return A_NO_MEMORY; ++ } ++ ++ A_NETBUF_PUT(osbuf, sizeof(*cmd)); ++ ++ cmd = (WMI_IBSS_PM_CAPS_CMD *)(A_NETBUF_DATA(osbuf)); ++ A_MEMZERO(cmd, sizeof(*cmd)); ++ cmd->power_saving = pmEnable; ++ cmd->ttl = ttl; ++ cmd->atim_windows = atim_windows; ++ cmd->timeout_value = timeout_value; ++ ++ return (wmi_cmd_send(wmip, osbuf, WMI_SET_IBSS_PM_CAPS_CMDID, ++ NO_SYNC_WMIFLAG)); ++} ++ ++A_STATUS ++wmi_pmparams_cmd(struct wmi_t *wmip, A_UINT16 idlePeriod, ++ A_UINT16 psPollNum, A_UINT16 dtimPolicy) ++{ ++ void *osbuf; ++ WMI_POWER_PARAMS_CMD *pm; ++ ++ osbuf = A_NETBUF_ALLOC(sizeof(*pm)); ++ if (osbuf == NULL) { ++ return A_NO_MEMORY; ++ } ++ ++ A_NETBUF_PUT(osbuf, sizeof(*pm)); ++ ++ pm = (WMI_POWER_PARAMS_CMD *)(A_NETBUF_DATA(osbuf)); ++ A_MEMZERO(pm, sizeof(*pm)); ++ pm->idle_period = idlePeriod; ++ pm->pspoll_number = psPollNum; ++ pm->dtim_policy = dtimPolicy; ++ ++ return (wmi_cmd_send(wmip, osbuf, WMI_SET_POWER_PARAMS_CMDID, ++ NO_SYNC_WMIFLAG)); ++} ++ ++A_STATUS ++wmi_disctimeout_cmd(struct wmi_t *wmip, A_UINT8 timeout) ++{ ++ void *osbuf; ++ WMI_DISC_TIMEOUT_CMD *cmd; ++ ++ osbuf = A_NETBUF_ALLOC(sizeof(*cmd)); ++ if (osbuf == NULL) { ++ return A_NO_MEMORY; ++ } ++ ++ A_NETBUF_PUT(osbuf, sizeof(*cmd)); ++ ++ cmd = (WMI_DISC_TIMEOUT_CMD *)(A_NETBUF_DATA(osbuf)); ++ A_MEMZERO(cmd, sizeof(*cmd)); ++ cmd->disconnectTimeout = timeout; ++ ++ return (wmi_cmd_send(wmip, osbuf, WMI_SET_DISC_TIMEOUT_CMDID, ++ NO_SYNC_WMIFLAG)); ++} ++ ++A_STATUS ++wmi_addKey_cmd(struct wmi_t *wmip, A_UINT8 keyIndex, CRYPTO_TYPE keyType, ++ A_UINT8 keyUsage, A_UINT8 keyLength, A_UINT8 *keyRSC, ++ A_UINT8 *keyMaterial, A_UINT8 key_op_ctrl, ++ WMI_SYNC_FLAG sync_flag) ++{ ++ void *osbuf; ++ WMI_ADD_CIPHER_KEY_CMD *cmd; ++ ++ if ((keyIndex > WMI_MAX_KEY_INDEX) || (keyLength > WMI_MAX_KEY_LEN) || ++ (keyMaterial == NULL)) ++ { ++ return A_EINVAL; ++ } ++ ++ if ((WEP_CRYPT != keyType) && (NULL == keyRSC)) { ++ return A_EINVAL; ++ } ++ ++ osbuf = A_NETBUF_ALLOC(sizeof(*cmd)); ++ if (osbuf == NULL) { ++ return A_NO_MEMORY; ++ } ++ ++ A_NETBUF_PUT(osbuf, sizeof(*cmd)); ++ ++ cmd = (WMI_ADD_CIPHER_KEY_CMD *)(A_NETBUF_DATA(osbuf)); ++ A_MEMZERO(cmd, sizeof(*cmd)); ++ cmd->keyIndex = keyIndex; ++ cmd->keyType = keyType; ++ cmd->keyUsage = keyUsage; ++ cmd->keyLength = keyLength; ++ A_MEMCPY(cmd->key, keyMaterial, keyLength); ++ if (NULL != keyRSC) { ++ A_MEMCPY(cmd->keyRSC, keyRSC, sizeof(cmd->keyRSC)); ++ } ++ cmd->key_op_ctrl = key_op_ctrl; ++ ++ return (wmi_cmd_send(wmip, osbuf, WMI_ADD_CIPHER_KEY_CMDID, sync_flag)); ++} ++ ++A_STATUS ++wmi_add_krk_cmd(struct wmi_t *wmip, A_UINT8 *krk) ++{ ++ void *osbuf; ++ WMI_ADD_KRK_CMD *cmd; ++ ++ osbuf = A_NETBUF_ALLOC(sizeof(*cmd)); ++ ++ if (osbuf == NULL) { ++ return A_NO_MEMORY; ++ } ++ ++ A_NETBUF_PUT(osbuf, sizeof(*cmd)); ++ ++ cmd = (WMI_ADD_KRK_CMD *)(A_NETBUF_DATA(osbuf)); ++ A_MEMZERO(cmd, sizeof(*cmd)); ++ A_MEMCPY(cmd->krk, krk, WMI_KRK_LEN); ++ ++ return (wmi_cmd_send(wmip, osbuf, WMI_ADD_KRK_CMDID, NO_SYNC_WMIFLAG)); ++} ++ ++A_STATUS ++wmi_delete_krk_cmd(struct wmi_t *wmip) ++{ ++ void *osbuf; ++ ++ osbuf = A_NETBUF_ALLOC(0); ++ ++ if (osbuf == NULL) { ++ return A_NO_MEMORY; ++ } ++ ++ return (wmi_cmd_send(wmip, osbuf, WMI_DELETE_KRK_CMDID, NO_SYNC_WMIFLAG)); ++} ++ ++A_STATUS ++wmi_deleteKey_cmd(struct wmi_t *wmip, A_UINT8 keyIndex) ++{ ++ void *osbuf; ++ WMI_DELETE_CIPHER_KEY_CMD *cmd; ++ ++ if (keyIndex > WMI_MAX_KEY_INDEX) { ++ return A_EINVAL; ++ } ++ ++ osbuf = A_NETBUF_ALLOC(sizeof(*cmd)); ++ if (osbuf == NULL) { ++ return A_NO_MEMORY; ++ } ++ ++ A_NETBUF_PUT(osbuf, sizeof(*cmd)); ++ ++ cmd = (WMI_DELETE_CIPHER_KEY_CMD *)(A_NETBUF_DATA(osbuf)); ++ A_MEMZERO(cmd, sizeof(*cmd)); ++ cmd->keyIndex = keyIndex; ++ ++ return (wmi_cmd_send(wmip, osbuf, WMI_DELETE_CIPHER_KEY_CMDID, ++ NO_SYNC_WMIFLAG)); ++} ++ ++A_STATUS ++wmi_setPmkid_cmd(struct wmi_t *wmip, A_UINT8 *bssid, A_UINT8 *pmkId, ++ A_BOOL set) ++{ ++ void *osbuf; ++ WMI_SET_PMKID_CMD *cmd; ++ ++ if (bssid == NULL) { ++ return A_EINVAL; ++ } ++ ++ if ((set == TRUE) && (pmkId == NULL)) { ++ return A_EINVAL; ++ } ++ ++ osbuf = A_NETBUF_ALLOC(sizeof(*cmd)); ++ if (osbuf == NULL) { ++ return A_NO_MEMORY; ++ } ++ ++ A_NETBUF_PUT(osbuf, sizeof(*cmd)); ++ ++ cmd = (WMI_SET_PMKID_CMD *)(A_NETBUF_DATA(osbuf)); ++ A_MEMCPY(cmd->bssid, bssid, sizeof(cmd->bssid)); ++ if (set == TRUE) { ++ A_MEMCPY(cmd->pmkid, pmkId, sizeof(cmd->pmkid)); ++ cmd->enable = PMKID_ENABLE; ++ } else { ++ A_MEMZERO(cmd->pmkid, sizeof(cmd->pmkid)); ++ cmd->enable = PMKID_DISABLE; ++ } ++ ++ return (wmi_cmd_send(wmip, osbuf, WMI_SET_PMKID_CMDID, NO_SYNC_WMIFLAG)); ++} ++ ++A_STATUS ++wmi_set_tkip_countermeasures_cmd(struct wmi_t *wmip, A_BOOL en) ++{ ++ void *osbuf; ++ WMI_SET_TKIP_COUNTERMEASURES_CMD *cmd; ++ ++ osbuf = A_NETBUF_ALLOC(sizeof(*cmd)); ++ if (osbuf == NULL) { ++ return A_NO_MEMORY; ++ } ++ ++ A_NETBUF_PUT(osbuf, sizeof(*cmd)); ++ ++ cmd = (WMI_SET_TKIP_COUNTERMEASURES_CMD *)(A_NETBUF_DATA(osbuf)); ++ cmd->cm_en = (en == TRUE)? WMI_TKIP_CM_ENABLE : WMI_TKIP_CM_DISABLE; ++ ++ return (wmi_cmd_send(wmip, osbuf, WMI_SET_TKIP_COUNTERMEASURES_CMDID, ++ NO_SYNC_WMIFLAG)); ++} ++ ++A_STATUS ++wmi_set_akmp_params_cmd(struct wmi_t *wmip, ++ WMI_SET_AKMP_PARAMS_CMD *akmpParams) ++{ ++ void *osbuf; ++ WMI_SET_AKMP_PARAMS_CMD *cmd; ++ ++ osbuf = A_NETBUF_ALLOC(sizeof(*cmd)); ++ if (osbuf == NULL) { ++ return A_NO_MEMORY; ++ } ++ ++ A_NETBUF_PUT(osbuf, sizeof(*cmd)); ++ cmd = (WMI_SET_AKMP_PARAMS_CMD *)(A_NETBUF_DATA(osbuf)); ++ cmd->akmpInfo = akmpParams->akmpInfo; ++ ++ return (wmi_cmd_send(wmip, osbuf, WMI_SET_AKMP_PARAMS_CMDID, ++ NO_SYNC_WMIFLAG)); ++} ++ ++A_STATUS ++wmi_set_pmkid_list_cmd(struct wmi_t *wmip, ++ WMI_SET_PMKID_LIST_CMD *pmkInfo) ++{ ++ void *osbuf; ++ WMI_SET_PMKID_LIST_CMD *cmd; ++ A_UINT16 cmdLen; ++ A_UINT8 i; ++ ++ cmdLen = sizeof(pmkInfo->numPMKID) + ++ pmkInfo->numPMKID * sizeof(WMI_PMKID); ++ ++ osbuf = A_NETBUF_ALLOC(cmdLen); ++ ++ if (osbuf == NULL) { ++ return A_NO_MEMORY; ++ } ++ ++ A_NETBUF_PUT(osbuf, cmdLen); ++ cmd = (WMI_SET_PMKID_LIST_CMD *)(A_NETBUF_DATA(osbuf)); ++ cmd->numPMKID = pmkInfo->numPMKID; ++ ++ for (i = 0; i < cmd->numPMKID; i++) { ++ A_MEMCPY(&cmd->pmkidList[i], &pmkInfo->pmkidList[i], ++ WMI_PMKID_LEN); ++ } ++ ++ return (wmi_cmd_send(wmip, osbuf, WMI_SET_PMKID_LIST_CMDID, ++ NO_SYNC_WMIFLAG)); ++} ++ ++A_STATUS ++wmi_get_pmkid_list_cmd(struct wmi_t *wmip) ++{ ++ void *osbuf; ++ ++ osbuf = A_NETBUF_ALLOC(0); /* no payload */ ++ if (osbuf == NULL) { ++ return A_NO_MEMORY; ++ } ++ ++ return (wmi_cmd_send(wmip, osbuf, WMI_GET_PMKID_LIST_CMDID, ++ NO_SYNC_WMIFLAG)); ++} ++ ++A_STATUS ++wmi_dataSync_send(struct wmi_t *wmip, void *osbuf, WMI_PRI_STREAM_ID streamID) ++{ ++ WMI_DATA_HDR *dtHdr; ++ ++ A_ASSERT(streamID != WMI_CONTROL_PRI); ++ A_ASSERT(osbuf != NULL); ++ ++ if (A_NETBUF_PUSH(osbuf, sizeof(WMI_DATA_HDR)) != A_OK) { ++ return A_NO_MEMORY; ++ } ++ ++ dtHdr = (WMI_DATA_HDR *)A_NETBUF_DATA(osbuf); ++ dtHdr->info = ++ (SYNC_MSGTYPE & WMI_DATA_HDR_MSG_TYPE_MASK) << WMI_DATA_HDR_MSG_TYPE_SHIFT; ++ ++ A_DPRINTF(DBG_WMI, (DBGFMT "Enter - streamID %d\n", DBGARG, streamID)); ++ ++ return (A_WMI_CONTROL_TX(wmip->wmi_devt, osbuf, streamID)); ++} ++ ++typedef struct _WMI_DATA_SYNC_BUFS { ++ A_UINT8 trafficClass; ++ void *osbuf; ++}WMI_DATA_SYNC_BUFS; ++ ++static A_STATUS ++wmi_sync_point(struct wmi_t *wmip) ++{ ++ void *cmd_osbuf; ++ WMI_DATA_SYNC_BUFS dataSyncBufs[WMM_NUM_AC]; ++ A_UINT8 i,numPriStreams=0; ++ A_STATUS status; ++ ++ A_DPRINTF(DBG_WMI, (DBGFMT "Enter\n", DBGARG)); ++ ++ memset(dataSyncBufs,0,sizeof(dataSyncBufs)); ++ ++ /* lock out while we walk through the priority list and assemble our local array */ ++ LOCK_WMI(wmip); ++ ++ for (i=0; i < WMM_NUM_AC ; i++) { ++ if (wmip->wmi_fatPipeExists & (1 << i)) { ++ numPriStreams++; ++ dataSyncBufs[numPriStreams-1].trafficClass = i; ++ } ++ } ++ ++ UNLOCK_WMI(wmip); ++ ++ /* dataSyncBufs is now filled with entries (starting at index 0) containing valid streamIDs */ ++ ++ do { ++ /* ++ * We allocate all network buffers needed so we will be able to ++ * send all required frames. ++ */ ++ cmd_osbuf = A_NETBUF_ALLOC(0); /* no payload */ ++ if (cmd_osbuf == NULL) { ++ status = A_NO_MEMORY; ++ break; ++ } ++ ++ for (i=0; i < numPriStreams ; i++) { ++ dataSyncBufs[i].osbuf = A_NETBUF_ALLOC(0); ++ if (dataSyncBufs[i].osbuf == NULL) { ++ status = A_NO_MEMORY; ++ break; ++ } ++ } //end for ++ ++ /* ++ * Send sync cmd followed by sync data messages on all endpoints being ++ * used ++ */ ++ status = wmi_cmd_send(wmip, cmd_osbuf, WMI_SYNCHRONIZE_CMDID, ++ NO_SYNC_WMIFLAG); ++ ++ if (A_FAILED(status)) { ++ break; ++ } ++ /* cmd buffer sent, we no longer own it */ ++ cmd_osbuf = NULL; ++ ++ for(i=0; i < numPriStreams; i++) { ++ A_ASSERT(dataSyncBufs[i].osbuf != NULL); ++ ++ status = wmi_dataSync_send(wmip, dataSyncBufs[i].osbuf, ++ WMI_ACCESSCATEGORY_WMISTREAM(wmip,dataSyncBufs[i].trafficClass)); ++ ++ if (A_FAILED(status)) { ++ break; ++ } ++ /* we don't own this buffer anymore, NULL it out of the array so it ++ * won't get cleaned up */ ++ dataSyncBufs[i].osbuf = NULL; ++ } //end for ++ ++ } while(FALSE); ++ ++ /* free up any resources left over (possibly due to an error) */ ++ ++ if (cmd_osbuf != NULL) { ++ A_NETBUF_FREE(cmd_osbuf); ++ } ++ ++ for (i = 0; i < numPriStreams; i++) { ++ if (dataSyncBufs[i].osbuf != NULL) { ++ A_NETBUF_FREE(dataSyncBufs[i].osbuf); ++ } ++ } ++ ++ return (status); ++} ++ ++A_STATUS ++wmi_create_pstream_cmd(struct wmi_t *wmip, WMI_CREATE_PSTREAM_CMD *params) ++{ ++ void *osbuf; ++ WMI_CREATE_PSTREAM_CMD *cmd; ++ A_UINT16 activeTsids=0; ++ A_UINT8 fatPipeExistsForAC=0; ++ ++ /* Validate all the parameters. */ ++ if( !((params->userPriority < 8) && ++ (params->userPriority <= 0x7) && ++ (convert_userPriority_to_trafficClass(params->userPriority) == params->trafficClass) && ++ (params->trafficDirection == UPLINK_TRAFFIC || ++ params->trafficDirection == DNLINK_TRAFFIC || ++ params->trafficDirection == BIDIR_TRAFFIC) && ++ (params->trafficType == TRAFFIC_TYPE_APERIODIC || ++ params->trafficType == TRAFFIC_TYPE_PERIODIC ) && ++ (params->voicePSCapability == DISABLE_FOR_THIS_AC || ++ params->voicePSCapability == ENABLE_FOR_THIS_AC || ++ params->voicePSCapability == ENABLE_FOR_ALL_AC) && ++ (params->tsid == WMI_IMPLICIT_PSTREAM || params->tsid <= WMI_MAX_THINSTREAM)) ) ++ { ++ return A_EINVAL; ++ } ++ ++ osbuf = A_NETBUF_ALLOC(sizeof(*cmd)); ++ if (osbuf == NULL) { ++ return A_NO_MEMORY; ++ } ++ ++ A_NETBUF_PUT(osbuf, sizeof(*cmd)); ++ ++ A_DPRINTF(DBG_WMI, ++ (DBGFMT "Sending create_pstream_cmd: ac=%d tsid:%d\n", DBGARG, ++ params->trafficClass, params->tsid)); ++ ++ cmd = (WMI_CREATE_PSTREAM_CMD *)(A_NETBUF_DATA(osbuf)); ++ A_MEMZERO(cmd, sizeof(*cmd)); ++ A_MEMCPY(cmd, params, sizeof(*cmd)); ++ ++ /* this is an implicitly created Fat pipe */ ++ if (params->tsid == WMI_IMPLICIT_PSTREAM) { ++ LOCK_WMI(wmip); ++ fatPipeExistsForAC = (wmip->wmi_fatPipeExists & (1 << params->trafficClass)); ++ wmip->wmi_fatPipeExists |= (1<<params->trafficClass); ++ UNLOCK_WMI(wmip); ++ } else { ++ /* this is an explicitly created thin stream within a fat pipe */ ++ LOCK_WMI(wmip); ++ fatPipeExistsForAC = (wmip->wmi_fatPipeExists & (1 << params->trafficClass)); ++ activeTsids = wmip->wmi_streamExistsForAC[params->trafficClass]; ++ wmip->wmi_streamExistsForAC[params->trafficClass] |= (1<<params->tsid); ++ /* if a thinstream becomes active, the fat pipe automatically ++ * becomes active ++ */ ++ wmip->wmi_fatPipeExists |= (1<<params->trafficClass); ++ UNLOCK_WMI(wmip); ++ } ++ ++ /* Indicate activty change to driver layer only if this is the ++ * first TSID to get created in this AC explicitly or an implicit ++ * fat pipe is getting created. ++ */ ++ if (!fatPipeExistsForAC) { ++ A_WMI_STREAM_TX_ACTIVE(wmip->wmi_devt, params->trafficClass); ++ } ++ ++ /* mike: should be SYNC_BEFORE_WMIFLAG */ ++ return (wmi_cmd_send(wmip, osbuf, WMI_CREATE_PSTREAM_CMDID, ++ NO_SYNC_WMIFLAG)); ++} ++ ++A_STATUS ++wmi_delete_pstream_cmd(struct wmi_t *wmip, A_UINT8 trafficClass, A_UINT8 tsid) ++{ ++ void *osbuf; ++ WMI_DELETE_PSTREAM_CMD *cmd; ++ A_STATUS status; ++ A_UINT16 activeTsids=0; ++ ++ osbuf = A_NETBUF_ALLOC(sizeof(*cmd)); ++ if (osbuf == NULL) { ++ return A_NO_MEMORY; ++ } ++ ++ A_NETBUF_PUT(osbuf, sizeof(*cmd)); ++ ++ cmd = (WMI_DELETE_PSTREAM_CMD *)(A_NETBUF_DATA(osbuf)); ++ A_MEMZERO(cmd, sizeof(*cmd)); ++ ++ cmd->trafficClass = trafficClass; ++ cmd->tsid = tsid; ++ ++ LOCK_WMI(wmip); ++ activeTsids = wmip->wmi_streamExistsForAC[trafficClass]; ++ UNLOCK_WMI(wmip); ++ ++ /* Check if the tsid was created & exists */ ++ if (!(activeTsids & (1<<tsid))) { ++ ++ A_DPRINTF(DBG_WMI, ++ (DBGFMT "TSID %d does'nt exist for trafficClass: %d\n", DBGARG, tsid, trafficClass)); ++ /* TODO: return a more appropriate err code */ ++ return A_ERROR; ++ } ++ ++ A_DPRINTF(DBG_WMI, ++ (DBGFMT "Sending delete_pstream_cmd: trafficClass: %d tsid=%d\n", DBGARG, trafficClass, tsid)); ++ ++ status = (wmi_cmd_send(wmip, osbuf, WMI_DELETE_PSTREAM_CMDID, ++ SYNC_BEFORE_WMIFLAG)); ++ ++ LOCK_WMI(wmip); ++ wmip->wmi_streamExistsForAC[trafficClass] &= ~(1<<tsid); ++ activeTsids = wmip->wmi_streamExistsForAC[trafficClass]; ++ UNLOCK_WMI(wmip); ++ ++ ++ /* Indicate stream inactivity to driver layer only if all tsids ++ * within this AC are deleted. ++ */ ++ if(!activeTsids) { ++ A_WMI_STREAM_TX_INACTIVE(wmip->wmi_devt, trafficClass); ++ wmip->wmi_fatPipeExists &= ~(1<<trafficClass); ++ } ++ ++ return status; ++} ++ ++/* ++ * used to set the bit rate. rate is in Kbps. If rate == -1 ++ * then auto selection is used. ++ */ ++A_STATUS ++wmi_set_bitrate_cmd(struct wmi_t *wmip, A_INT32 rate) ++{ ++ void *osbuf; ++ WMI_BIT_RATE_CMD *cmd; ++ A_INT8 index; ++ ++ if (rate != -1) { ++ index = wmi_validate_bitrate(wmip, rate); ++ if(index == A_EINVAL){ ++ return A_EINVAL; ++ } ++ } else { ++ index = -1; ++ } ++ ++ osbuf = A_NETBUF_ALLOC(sizeof(*cmd)); ++ if (osbuf == NULL) { ++ return A_NO_MEMORY; ++ } ++ ++ A_NETBUF_PUT(osbuf, sizeof(*cmd)); ++ ++ cmd = (WMI_BIT_RATE_CMD *)(A_NETBUF_DATA(osbuf)); ++ A_MEMZERO(cmd, sizeof(*cmd)); ++ ++ cmd->rateIndex = index; ++ ++ return (wmi_cmd_send(wmip, osbuf, WMI_SET_BITRATE_CMDID, NO_SYNC_WMIFLAG)); ++} ++ ++A_STATUS ++wmi_get_bitrate_cmd(struct wmi_t *wmip) ++{ ++ void *osbuf; ++ ++ osbuf = A_NETBUF_ALLOC(0); /* no payload */ ++ if (osbuf == NULL) { ++ return A_NO_MEMORY; ++ } ++ ++ return (wmi_cmd_send(wmip, osbuf, WMI_GET_BITRATE_CMDID, NO_SYNC_WMIFLAG)); ++} ++ ++/* ++ * Returns TRUE iff the given rate index is legal in the current PHY mode. ++ */ ++A_BOOL ++wmi_is_bitrate_index_valid(struct wmi_t *wmip, A_UINT32 rateIndex) ++{ ++ WMI_PHY_MODE phyMode = wmip->wmi_phyMode; ++ A_BOOL isValid = TRUE; ++ switch(phyMode) { ++ case WMI_11A_MODE: ++ if ((rateIndex < MODE_A_SUPPORT_RATE_START) || (rateIndex > MODE_A_SUPPORT_RATE_STOP)) { ++ isValid = FALSE; ++ } ++ break; ++ ++ case WMI_11B_MODE: ++ if ((rateIndex < MODE_B_SUPPORT_RATE_START) || (rateIndex > MODE_B_SUPPORT_RATE_STOP)) { ++ isValid = FALSE; ++ } ++ break; ++ ++ case WMI_11GONLY_MODE: ++ if ((rateIndex < MODE_GONLY_SUPPORT_RATE_START) || (rateIndex > MODE_GONLY_SUPPORT_RATE_STOP)) { ++ isValid = FALSE; ++ } ++ break; ++ ++ case WMI_11G_MODE: ++ case WMI_11AG_MODE: ++ if ((rateIndex < MODE_G_SUPPORT_RATE_START) || (rateIndex > MODE_G_SUPPORT_RATE_STOP)) { ++ isValid = FALSE; ++ } ++ break; ++ ++ default: ++ A_ASSERT(FALSE); ++ break; ++ } ++ ++ return isValid; ++} ++ ++A_INT8 ++wmi_validate_bitrate(struct wmi_t *wmip, A_INT32 rate) ++{ ++ A_INT8 i; ++ if (rate != -1) ++ { ++ for (i=0;;i++) ++ { ++ if (wmi_rateTable[(A_UINT32) i] == 0) { ++ return A_EINVAL; ++ } ++ if (wmi_rateTable[(A_UINT32) i] == rate) { ++ break; ++ } ++ } ++ } ++ else{ ++ i = -1; ++ } ++ ++ if(wmi_is_bitrate_index_valid(wmip, i) != TRUE) { ++ return A_EINVAL; ++ } ++ ++ return i; ++} ++ ++A_STATUS ++wmi_set_fixrates_cmd(struct wmi_t *wmip, A_INT16 fixRatesMask) ++{ ++ void *osbuf; ++ WMI_FIX_RATES_CMD *cmd; ++ A_UINT32 rateIndex; ++ ++ /* Make sure all rates in the mask are valid in the current PHY mode */ ++ for(rateIndex = 0; rateIndex < MAX_NUMBER_OF_SUPPORT_RATES; rateIndex++) { ++ if((1 << rateIndex) & (A_UINT32)fixRatesMask) { ++ if(wmi_is_bitrate_index_valid(wmip, rateIndex) != TRUE) { ++ A_DPRINTF(DBG_WMI, (DBGFMT "Set Fix Rates command failed: Given rate is illegal in current PHY mode\n", DBGARG)); ++ return A_EINVAL; ++ } ++ } ++ } ++ ++ ++ osbuf = A_NETBUF_ALLOC(sizeof(*cmd)); ++ if (osbuf == NULL) { ++ return A_NO_MEMORY; ++ } ++ ++ A_NETBUF_PUT(osbuf, sizeof(*cmd)); ++ ++ cmd = (WMI_FIX_RATES_CMD *)(A_NETBUF_DATA(osbuf)); ++ A_MEMZERO(cmd, sizeof(*cmd)); ++ ++ cmd->fixRateMask = fixRatesMask; ++ ++ return (wmi_cmd_send(wmip, osbuf, WMI_SET_FIXRATES_CMDID, NO_SYNC_WMIFLAG)); ++} ++ ++A_STATUS ++wmi_get_ratemask_cmd(struct wmi_t *wmip) ++{ ++ void *osbuf; ++ ++ osbuf = A_NETBUF_ALLOC(0); /* no payload */ ++ if (osbuf == NULL) { ++ return A_NO_MEMORY; ++ } ++ ++ return (wmi_cmd_send(wmip, osbuf, WMI_GET_FIXRATES_CMDID, NO_SYNC_WMIFLAG)); ++} ++ ++A_STATUS ++wmi_get_channelList_cmd(struct wmi_t *wmip) ++{ ++ void *osbuf; ++ ++ osbuf = A_NETBUF_ALLOC(0); /* no payload */ ++ if (osbuf == NULL) { ++ return A_NO_MEMORY; ++ } ++ ++ return (wmi_cmd_send(wmip, osbuf, WMI_GET_CHANNEL_LIST_CMDID, ++ NO_SYNC_WMIFLAG)); ++} ++ ++/* ++ * used to generate a wmi sey channel Parameters cmd. ++ * mode should always be specified and corresponds to the phy mode of the ++ * wlan. ++ * numChan should alway sbe specified. If zero indicates that all available ++ * channels should be used. ++ * channelList is an array of channel frequencies (in Mhz) which the radio ++ * should limit its operation to. It should be NULL if numChan == 0. Size of ++ * array should correspond to numChan entries. ++ */ ++A_STATUS ++wmi_set_channelParams_cmd(struct wmi_t *wmip, A_UINT8 scanParam, ++ WMI_PHY_MODE mode, A_INT8 numChan, ++ A_UINT16 *channelList) ++{ ++ void *osbuf; ++ WMI_CHANNEL_PARAMS_CMD *cmd; ++ A_INT8 size; ++ ++ size = sizeof (*cmd); ++ ++ if (numChan) { ++ if (numChan > WMI_MAX_CHANNELS) { ++ return A_EINVAL; ++ } ++ size += sizeof(A_UINT16) * (numChan - 1); ++ } ++ ++ osbuf = A_NETBUF_ALLOC(size); ++ if (osbuf == NULL) { ++ return A_NO_MEMORY; ++ } ++ ++ A_NETBUF_PUT(osbuf, size); ++ ++ cmd = (WMI_CHANNEL_PARAMS_CMD *)(A_NETBUF_DATA(osbuf)); ++ A_MEMZERO(cmd, size); ++ ++ wmip->wmi_phyMode = mode; ++ cmd->scanParam = scanParam; ++ cmd->phyMode = mode; ++ cmd->numChannels = numChan; ++ A_MEMCPY(cmd->channelList, channelList, numChan * sizeof(A_UINT16)); ++ ++ return (wmi_cmd_send(wmip, osbuf, WMI_SET_CHANNEL_PARAMS_CMDID, ++ NO_SYNC_WMIFLAG)); ++} ++ ++A_STATUS ++wmi_set_rssi_threshold_params(struct wmi_t *wmip, ++ WMI_RSSI_THRESHOLD_PARAMS_CMD *rssiCmd) ++{ ++ void *osbuf; ++ A_INT8 size; ++ WMI_RSSI_THRESHOLD_PARAMS_CMD *cmd; ++ /* These values are in ascending order */ ++ if( rssiCmd->thresholdAbove6_Val <= rssiCmd->thresholdAbove5_Val || ++ rssiCmd->thresholdAbove5_Val <= rssiCmd->thresholdAbove4_Val || ++ rssiCmd->thresholdAbove4_Val <= rssiCmd->thresholdAbove3_Val || ++ rssiCmd->thresholdAbove3_Val <= rssiCmd->thresholdAbove2_Val || ++ rssiCmd->thresholdAbove2_Val <= rssiCmd->thresholdAbove1_Val || ++ rssiCmd->thresholdBelow6_Val <= rssiCmd->thresholdBelow5_Val || ++ rssiCmd->thresholdBelow5_Val <= rssiCmd->thresholdBelow4_Val || ++ rssiCmd->thresholdBelow4_Val <= rssiCmd->thresholdBelow3_Val || ++ rssiCmd->thresholdBelow3_Val <= rssiCmd->thresholdBelow2_Val || ++ rssiCmd->thresholdBelow2_Val <= rssiCmd->thresholdBelow1_Val) { ++ ++ return A_EINVAL; ++ } ++ ++ size = sizeof (*cmd); ++ ++ osbuf = A_NETBUF_ALLOC(size); ++ if (osbuf == NULL) { ++ return A_NO_MEMORY; ++ } ++ ++ A_NETBUF_PUT(osbuf, size); ++ ++ cmd = (WMI_RSSI_THRESHOLD_PARAMS_CMD *)(A_NETBUF_DATA(osbuf)); ++ A_MEMZERO(cmd, size); ++ A_MEMCPY(cmd, rssiCmd, sizeof(WMI_RSSI_THRESHOLD_PARAMS_CMD)); ++ ++ return (wmi_cmd_send(wmip, osbuf, WMI_RSSI_THRESHOLD_PARAMS_CMDID, ++ NO_SYNC_WMIFLAG)); ++} ++ ++A_STATUS ++wmi_set_host_sleep_mode_cmd(struct wmi_t *wmip, ++ WMI_SET_HOST_SLEEP_MODE_CMD *hostModeCmd) ++{ ++ void *osbuf; ++ A_INT8 size; ++ WMI_SET_HOST_SLEEP_MODE_CMD *cmd; ++ ++ if( hostModeCmd->awake == hostModeCmd->asleep) { ++ return A_EINVAL; ++ } ++ ++ size = sizeof (*cmd); ++ ++ osbuf = A_NETBUF_ALLOC(size); ++ if (osbuf == NULL) { ++ return A_NO_MEMORY; ++ } ++ ++ A_NETBUF_PUT(osbuf, size); ++ ++ cmd = (WMI_SET_HOST_SLEEP_MODE_CMD *)(A_NETBUF_DATA(osbuf)); ++ A_MEMZERO(cmd, size); ++ A_MEMCPY(cmd, hostModeCmd, sizeof(WMI_SET_HOST_SLEEP_MODE_CMD)); ++ ++ return (wmi_cmd_send(wmip, osbuf, WMI_SET_HOST_SLEEP_MODE_CMDID, ++ NO_SYNC_WMIFLAG)); ++} ++ ++A_STATUS ++wmi_set_wow_mode_cmd(struct wmi_t *wmip, ++ WMI_SET_WOW_MODE_CMD *wowModeCmd) ++{ ++ void *osbuf; ++ A_INT8 size; ++ WMI_SET_WOW_MODE_CMD *cmd; ++ ++ size = sizeof (*cmd); ++ ++ osbuf = A_NETBUF_ALLOC(size); ++ if (osbuf == NULL) { ++ return A_NO_MEMORY; ++ } ++ ++ A_NETBUF_PUT(osbuf, size); ++ ++ cmd = (WMI_SET_WOW_MODE_CMD *)(A_NETBUF_DATA(osbuf)); ++ A_MEMZERO(cmd, size); ++ A_MEMCPY(cmd, wowModeCmd, sizeof(WMI_SET_WOW_MODE_CMD)); ++ ++ return (wmi_cmd_send(wmip, osbuf, WMI_SET_WOW_MODE_CMDID, ++ NO_SYNC_WMIFLAG)); ++ ++} ++ ++A_STATUS ++wmi_get_wow_list_cmd(struct wmi_t *wmip, ++ WMI_GET_WOW_LIST_CMD *wowListCmd) ++{ ++ void *osbuf; ++ A_INT8 size; ++ WMI_GET_WOW_LIST_CMD *cmd; ++ ++ size = sizeof (*cmd); ++ ++ osbuf = A_NETBUF_ALLOC(size); ++ if (osbuf == NULL) { ++ return A_NO_MEMORY; ++ } ++ ++ A_NETBUF_PUT(osbuf, size); ++ ++ cmd = (WMI_GET_WOW_LIST_CMD *)(A_NETBUF_DATA(osbuf)); ++ A_MEMZERO(cmd, size); ++ A_MEMCPY(cmd, wowListCmd, sizeof(WMI_GET_WOW_LIST_CMD)); ++ ++ return (wmi_cmd_send(wmip, osbuf, WMI_GET_WOW_LIST_CMDID, ++ NO_SYNC_WMIFLAG)); ++ ++} ++ ++static A_STATUS ++wmi_get_wow_list_event_rx(struct wmi_t *wmip, A_UINT8 *datap, int len) ++{ ++ WMI_GET_WOW_LIST_REPLY *reply; ++ ++ if (len < sizeof(WMI_GET_WOW_LIST_REPLY)) { ++ return A_EINVAL; ++ } ++ reply = (WMI_GET_WOW_LIST_REPLY *)datap; ++ ++ A_WMI_WOW_LIST_EVENT(wmip->wmi_devt, reply->num_filters, ++ reply); ++ ++ return A_OK; ++} ++ ++A_STATUS wmi_add_wow_pattern_cmd(struct wmi_t *wmip, ++ WMI_ADD_WOW_PATTERN_CMD *addWowCmd, ++ A_UINT8* pattern, A_UINT8* mask, ++ A_UINT8 pattern_size) ++{ ++ void *osbuf; ++ A_INT8 size; ++ WMI_ADD_WOW_PATTERN_CMD *cmd; ++ A_UINT8 *filter_mask = NULL; ++ ++ size = sizeof (*cmd); ++ ++ size += ((2 * addWowCmd->filter_size)* sizeof(A_UINT8)); ++ osbuf = A_NETBUF_ALLOC(size); ++ if (osbuf == NULL) { ++ return A_NO_MEMORY; ++ } ++ ++ A_NETBUF_PUT(osbuf, size); ++ ++ cmd = (WMI_ADD_WOW_PATTERN_CMD *)(A_NETBUF_DATA(osbuf)); ++ cmd->filter_list_id = addWowCmd->filter_list_id; ++ cmd->filter_offset = addWowCmd->filter_offset; ++ cmd->filter_size = addWowCmd->filter_size; ++ ++ A_MEMCPY(cmd->filter, pattern, addWowCmd->filter_size); ++ ++ filter_mask = (A_UINT8*)(cmd->filter + cmd->filter_size); ++ A_MEMCPY(filter_mask, mask, addWowCmd->filter_size); ++ ++ ++ return (wmi_cmd_send(wmip, osbuf, WMI_ADD_WOW_PATTERN_CMDID, ++ NO_SYNC_WMIFLAG)); ++} ++ ++A_STATUS ++wmi_del_wow_pattern_cmd(struct wmi_t *wmip, ++ WMI_DEL_WOW_PATTERN_CMD *delWowCmd) ++{ ++ void *osbuf; ++ A_INT8 size; ++ WMI_DEL_WOW_PATTERN_CMD *cmd; ++ ++ size = sizeof (*cmd); ++ ++ osbuf = A_NETBUF_ALLOC(size); ++ if (osbuf == NULL) { ++ return A_NO_MEMORY; ++ } ++ ++ A_NETBUF_PUT(osbuf, size); ++ ++ cmd = (WMI_DEL_WOW_PATTERN_CMD *)(A_NETBUF_DATA(osbuf)); ++ A_MEMZERO(cmd, size); ++ A_MEMCPY(cmd, delWowCmd, sizeof(WMI_DEL_WOW_PATTERN_CMD)); ++ ++ return (wmi_cmd_send(wmip, osbuf, WMI_DEL_WOW_PATTERN_CMDID, ++ NO_SYNC_WMIFLAG)); ++ ++} ++ ++A_STATUS ++wmi_set_snr_threshold_params(struct wmi_t *wmip, ++ WMI_SNR_THRESHOLD_PARAMS_CMD *snrCmd) ++{ ++ void *osbuf; ++ A_INT8 size; ++ WMI_SNR_THRESHOLD_PARAMS_CMD *cmd; ++ /* These values are in ascending order */ ++ if( snrCmd->thresholdAbove4_Val <= snrCmd->thresholdAbove3_Val || ++ snrCmd->thresholdAbove3_Val <= snrCmd->thresholdAbove2_Val || ++ snrCmd->thresholdAbove2_Val <= snrCmd->thresholdAbove1_Val || ++ snrCmd->thresholdBelow4_Val <= snrCmd->thresholdBelow3_Val || ++ snrCmd->thresholdBelow3_Val <= snrCmd->thresholdBelow2_Val || ++ snrCmd->thresholdBelow2_Val <= snrCmd->thresholdBelow1_Val) { ++ ++ return A_EINVAL; ++ } ++ ++ size = sizeof (*cmd); ++ ++ osbuf = A_NETBUF_ALLOC(size); ++ if (osbuf == NULL) { ++ return A_NO_MEMORY; ++ } ++ ++ A_NETBUF_PUT(osbuf, size); ++ ++ cmd = (WMI_SNR_THRESHOLD_PARAMS_CMD *)(A_NETBUF_DATA(osbuf)); ++ A_MEMZERO(cmd, size); ++ A_MEMCPY(cmd, snrCmd, sizeof(WMI_SNR_THRESHOLD_PARAMS_CMD)); ++ ++ return (wmi_cmd_send(wmip, osbuf, WMI_SNR_THRESHOLD_PARAMS_CMDID, ++ NO_SYNC_WMIFLAG)); ++} ++ ++A_STATUS ++wmi_clr_rssi_snr(struct wmi_t *wmip) ++{ ++ void *osbuf; ++ ++ osbuf = A_NETBUF_ALLOC(sizeof(int)); ++ if (osbuf == NULL) { ++ return A_NO_MEMORY; ++ } ++ ++ return (wmi_cmd_send(wmip, osbuf, WMI_CLR_RSSI_SNR_CMDID, ++ NO_SYNC_WMIFLAG)); ++} ++ ++A_STATUS ++wmi_set_lq_threshold_params(struct wmi_t *wmip, ++ WMI_LQ_THRESHOLD_PARAMS_CMD *lqCmd) ++{ ++ void *osbuf; ++ A_INT8 size; ++ WMI_LQ_THRESHOLD_PARAMS_CMD *cmd; ++ /* These values are in ascending order */ ++ if( lqCmd->thresholdAbove4_Val <= lqCmd->thresholdAbove3_Val || ++ lqCmd->thresholdAbove3_Val <= lqCmd->thresholdAbove2_Val || ++ lqCmd->thresholdAbove2_Val <= lqCmd->thresholdAbove1_Val || ++ lqCmd->thresholdBelow4_Val <= lqCmd->thresholdBelow3_Val || ++ lqCmd->thresholdBelow3_Val <= lqCmd->thresholdBelow2_Val || ++ lqCmd->thresholdBelow2_Val <= lqCmd->thresholdBelow1_Val ) { ++ ++ return A_EINVAL; ++ } ++ ++ size = sizeof (*cmd); ++ ++ osbuf = A_NETBUF_ALLOC(size); ++ if (osbuf == NULL) { ++ return A_NO_MEMORY; ++ } ++ ++ A_NETBUF_PUT(osbuf, size); ++ ++ cmd = (WMI_LQ_THRESHOLD_PARAMS_CMD *)(A_NETBUF_DATA(osbuf)); ++ A_MEMZERO(cmd, size); ++ A_MEMCPY(cmd, lqCmd, sizeof(WMI_LQ_THRESHOLD_PARAMS_CMD)); ++ ++ return (wmi_cmd_send(wmip, osbuf, WMI_LQ_THRESHOLD_PARAMS_CMDID, ++ NO_SYNC_WMIFLAG)); ++} ++ ++A_STATUS ++wmi_set_error_report_bitmask(struct wmi_t *wmip, A_UINT32 mask) ++{ ++ void *osbuf; ++ A_INT8 size; ++ WMI_TARGET_ERROR_REPORT_BITMASK *cmd; ++ ++ size = sizeof (*cmd); ++ ++ osbuf = A_NETBUF_ALLOC(size); ++ if (osbuf == NULL) { ++ return A_NO_MEMORY; ++ } ++ ++ A_NETBUF_PUT(osbuf, size); ++ ++ cmd = (WMI_TARGET_ERROR_REPORT_BITMASK *)(A_NETBUF_DATA(osbuf)); ++ A_MEMZERO(cmd, size); ++ ++ cmd->bitmask = mask; ++ ++ return (wmi_cmd_send(wmip, osbuf, WMI_TARGET_ERROR_REPORT_BITMASK_CMDID, ++ NO_SYNC_WMIFLAG)); ++} ++ ++A_STATUS ++wmi_get_challenge_resp_cmd(struct wmi_t *wmip, A_UINT32 cookie, A_UINT32 source) ++{ ++ void *osbuf; ++ WMIX_HB_CHALLENGE_RESP_CMD *cmd; ++ ++ osbuf = A_NETBUF_ALLOC(sizeof(*cmd)); ++ if (osbuf == NULL) { ++ return A_NO_MEMORY; ++ } ++ ++ A_NETBUF_PUT(osbuf, sizeof(*cmd)); ++ ++ cmd = (WMIX_HB_CHALLENGE_RESP_CMD *)(A_NETBUF_DATA(osbuf)); ++ cmd->cookie = cookie; ++ cmd->source = source; ++ ++ return (wmi_cmd_send_xtnd(wmip, osbuf, WMIX_HB_CHALLENGE_RESP_CMDID, ++ NO_SYNC_WMIFLAG)); ++} ++ ++A_STATUS ++wmi_config_debug_module_cmd(struct wmi_t *wmip, A_UINT16 mmask, ++ A_UINT16 tsr, A_BOOL rep, A_UINT16 size, ++ A_UINT32 valid) ++{ ++ void *osbuf; ++ WMIX_DBGLOG_CFG_MODULE_CMD *cmd; ++ ++ osbuf = A_NETBUF_ALLOC(sizeof(*cmd)); ++ if (osbuf == NULL) { ++ return A_NO_MEMORY; ++ } ++ ++ A_NETBUF_PUT(osbuf, sizeof(*cmd)); ++ ++ cmd = (WMIX_DBGLOG_CFG_MODULE_CMD *)(A_NETBUF_DATA(osbuf)); ++ cmd->config.cfgmmask = mmask; ++ cmd->config.cfgtsr = tsr; ++ cmd->config.cfgrep = rep; ++ cmd->config.cfgsize = size; ++ cmd->config.cfgvalid = valid; ++ ++ return (wmi_cmd_send_xtnd(wmip, osbuf, WMIX_DBGLOG_CFG_MODULE_CMDID, ++ NO_SYNC_WMIFLAG)); ++} ++ ++A_STATUS ++wmi_get_stats_cmd(struct wmi_t *wmip) ++{ ++ void *osbuf; ++ ++ osbuf = A_NETBUF_ALLOC(0); /* no payload */ ++ if (osbuf == NULL) { ++ return A_NO_MEMORY; ++ } ++ ++ return (wmi_cmd_send(wmip, osbuf, WMI_GET_STATISTICS_CMDID, ++ NO_SYNC_WMIFLAG)); ++} ++ ++A_STATUS ++wmi_addBadAp_cmd(struct wmi_t *wmip, A_UINT8 apIndex, A_UINT8 *bssid) ++{ ++ void *osbuf; ++ WMI_ADD_BAD_AP_CMD *cmd; ++ ++ if ((bssid == NULL) || (apIndex > WMI_MAX_BAD_AP_INDEX)) { ++ return A_EINVAL; ++ } ++ ++ osbuf = A_NETBUF_ALLOC(sizeof(*cmd)); ++ if (osbuf == NULL) { ++ return A_NO_MEMORY; ++ } ++ ++ A_NETBUF_PUT(osbuf, sizeof(*cmd)); ++ ++ cmd = (WMI_ADD_BAD_AP_CMD *)(A_NETBUF_DATA(osbuf)); ++ cmd->badApIndex = apIndex; ++ A_MEMCPY(cmd->bssid, bssid, sizeof(cmd->bssid)); ++ ++ return (wmi_cmd_send(wmip, osbuf, WMI_ADD_BAD_AP_CMDID, NO_SYNC_WMIFLAG)); ++} ++ ++A_STATUS ++wmi_deleteBadAp_cmd(struct wmi_t *wmip, A_UINT8 apIndex) ++{ ++ void *osbuf; ++ WMI_DELETE_BAD_AP_CMD *cmd; ++ ++ if (apIndex > WMI_MAX_BAD_AP_INDEX) { ++ return A_EINVAL; ++ } ++ ++ osbuf = A_NETBUF_ALLOC(sizeof(*cmd)); ++ if (osbuf == NULL) { ++ return A_NO_MEMORY; ++ } ++ ++ A_NETBUF_PUT(osbuf, sizeof(*cmd)); ++ ++ cmd = (WMI_DELETE_BAD_AP_CMD *)(A_NETBUF_DATA(osbuf)); ++ cmd->badApIndex = apIndex; ++ ++ return (wmi_cmd_send(wmip, osbuf, WMI_DELETE_BAD_AP_CMDID, ++ NO_SYNC_WMIFLAG)); ++} ++ ++A_STATUS ++wmi_set_txPwr_cmd(struct wmi_t *wmip, A_UINT8 dbM) ++{ ++ void *osbuf; ++ WMI_SET_TX_PWR_CMD *cmd; ++ ++ osbuf = A_NETBUF_ALLOC(sizeof(*cmd)); ++ if (osbuf == NULL) { ++ return A_NO_MEMORY; ++ } ++ ++ A_NETBUF_PUT(osbuf, sizeof(*cmd)); ++ ++ cmd = (WMI_SET_TX_PWR_CMD *)(A_NETBUF_DATA(osbuf)); ++ cmd->dbM = dbM; ++ ++ return (wmi_cmd_send(wmip, osbuf, WMI_SET_TX_PWR_CMDID, NO_SYNC_WMIFLAG)); ++} ++ ++A_STATUS ++wmi_get_txPwr_cmd(struct wmi_t *wmip) ++{ ++ void *osbuf; ++ ++ osbuf = A_NETBUF_ALLOC(0); /* no payload */ ++ if (osbuf == NULL) { ++ return A_NO_MEMORY; ++ } ++ ++ return (wmi_cmd_send(wmip, osbuf, WMI_GET_TX_PWR_CMDID, NO_SYNC_WMIFLAG)); ++} ++ ++A_STATUS ++wmi_switch_radio(struct wmi_t *wmip, A_UINT8 on) ++{ ++ WMI_SCAN_PARAMS_CMD scParams = {0, 0, 0, 0, 0, ++ WMI_SHORTSCANRATIO_DEFAULT, ++ DEFAULT_SCAN_CTRL_FLAGS, ++ 0}; ++ ++ if (on) { ++ /* Enable foreground scanning */ ++ if (wmi_scanparams_cmd(wmip, scParams.fg_start_period, ++ scParams.fg_end_period, ++ scParams.bg_period, ++ scParams.minact_chdwell_time, ++ scParams.maxact_chdwell_time, ++ scParams.pas_chdwell_time, ++ scParams.shortScanRatio, ++ scParams.scanCtrlFlags, ++ scParams.max_dfsch_act_time) != A_OK) { ++ return -EIO; ++ } ++ } else { ++ wmi_disconnect_cmd(wmip); ++ if (wmi_scanparams_cmd(wmip, 0xFFFF, 0, 0, 0, ++ 0, 0, 0, 0xFF, 0) != A_OK) { ++ return -EIO; ++ } ++ } ++ ++ return A_OK; ++} ++ ++ ++A_UINT16 ++wmi_get_mapped_qos_queue(struct wmi_t *wmip, A_UINT8 trafficClass) ++{ ++ A_UINT16 activeTsids=0; ++ ++ LOCK_WMI(wmip); ++ activeTsids = wmip->wmi_streamExistsForAC[trafficClass]; ++ UNLOCK_WMI(wmip); ++ ++ return activeTsids; ++} ++ ++A_STATUS ++wmi_get_roam_tbl_cmd(struct wmi_t *wmip) ++{ ++ void *osbuf; ++ ++ osbuf = A_NETBUF_ALLOC(0); /* no payload */ ++ if (osbuf == NULL) { ++ return A_NO_MEMORY; ++ } ++ ++ return (wmi_cmd_send(wmip, osbuf, WMI_GET_ROAM_TBL_CMDID, ++ NO_SYNC_WMIFLAG)); ++} ++ ++A_STATUS ++wmi_get_roam_data_cmd(struct wmi_t *wmip, A_UINT8 roamDataType) ++{ ++ void *osbuf; ++ A_UINT32 size = sizeof(A_UINT8); ++ WMI_TARGET_ROAM_DATA *cmd; ++ ++ osbuf = A_NETBUF_ALLOC(size); /* no payload */ ++ if (osbuf == NULL) { ++ return A_NO_MEMORY; ++ } ++ ++ A_NETBUF_PUT(osbuf, size); ++ ++ cmd = (WMI_TARGET_ROAM_DATA *)(A_NETBUF_DATA(osbuf)); ++ cmd->roamDataType = roamDataType; ++ ++ return (wmi_cmd_send(wmip, osbuf, WMI_GET_ROAM_DATA_CMDID, ++ NO_SYNC_WMIFLAG)); ++} ++ ++A_STATUS ++wmi_set_roam_ctrl_cmd(struct wmi_t *wmip, WMI_SET_ROAM_CTRL_CMD *p, ++ A_UINT8 size) ++{ ++ void *osbuf; ++ WMI_SET_ROAM_CTRL_CMD *cmd; ++ ++ osbuf = A_NETBUF_ALLOC(size); ++ if (osbuf == NULL) { ++ return A_NO_MEMORY; ++ } ++ ++ A_NETBUF_PUT(osbuf, size); ++ ++ cmd = (WMI_SET_ROAM_CTRL_CMD *)(A_NETBUF_DATA(osbuf)); ++ A_MEMZERO(cmd, size); ++ ++ A_MEMCPY(cmd, p, size); ++ ++ return (wmi_cmd_send(wmip, osbuf, WMI_SET_ROAM_CTRL_CMDID, ++ NO_SYNC_WMIFLAG)); ++} ++ ++A_STATUS ++wmi_set_powersave_timers_cmd(struct wmi_t *wmip, ++ WMI_POWERSAVE_TIMERS_POLICY_CMD *pCmd, ++ A_UINT8 size) ++{ ++ void *osbuf; ++ WMI_POWERSAVE_TIMERS_POLICY_CMD *cmd; ++ ++ /* These timers can't be zero */ ++ if(!pCmd->psPollTimeout || !pCmd->triggerTimeout || ++ !(pCmd->apsdTimPolicy == IGNORE_TIM_ALL_QUEUES_APSD || ++ pCmd->apsdTimPolicy == PROCESS_TIM_ALL_QUEUES_APSD) || ++ !(pCmd->simulatedAPSDTimPolicy == IGNORE_TIM_SIMULATED_APSD || ++ pCmd->simulatedAPSDTimPolicy == PROCESS_TIM_SIMULATED_APSD)) ++ return A_EINVAL; ++ ++ osbuf = A_NETBUF_ALLOC(size); ++ if (osbuf == NULL) { ++ return A_NO_MEMORY; ++ } ++ ++ A_NETBUF_PUT(osbuf, size); ++ ++ cmd = (WMI_POWERSAVE_TIMERS_POLICY_CMD *)(A_NETBUF_DATA(osbuf)); ++ A_MEMZERO(cmd, size); ++ ++ A_MEMCPY(cmd, pCmd, size); ++ ++ return (wmi_cmd_send(wmip, osbuf, WMI_SET_POWERSAVE_TIMERS_POLICY_CMDID, ++ NO_SYNC_WMIFLAG)); ++} ++ ++#ifdef CONFIG_HOST_GPIO_SUPPORT ++/* Send a command to Target to change GPIO output pins. */ ++A_STATUS ++wmi_gpio_output_set(struct wmi_t *wmip, ++ A_UINT32 set_mask, ++ A_UINT32 clear_mask, ++ A_UINT32 enable_mask, ++ A_UINT32 disable_mask) ++{ ++ void *osbuf; ++ WMIX_GPIO_OUTPUT_SET_CMD *output_set; ++ int size; ++ ++ size = sizeof(*output_set); ++ ++ A_DPRINTF(DBG_WMI, ++ (DBGFMT "Enter - set=0x%x clear=0x%x enb=0x%x dis=0x%x\n", DBGARG, ++ set_mask, clear_mask, enable_mask, disable_mask)); ++ ++ osbuf = A_NETBUF_ALLOC(size); ++ if (osbuf == NULL) { ++ return A_NO_MEMORY; ++ } ++ A_NETBUF_PUT(osbuf, size); ++ output_set = (WMIX_GPIO_OUTPUT_SET_CMD *)(A_NETBUF_DATA(osbuf)); ++ ++ output_set->set_mask = set_mask; ++ output_set->clear_mask = clear_mask; ++ output_set->enable_mask = enable_mask; ++ output_set->disable_mask = disable_mask; ++ ++ return (wmi_cmd_send_xtnd(wmip, osbuf, WMIX_GPIO_OUTPUT_SET_CMDID, ++ NO_SYNC_WMIFLAG)); ++} ++ ++/* Send a command to the Target requesting state of the GPIO input pins */ ++A_STATUS ++wmi_gpio_input_get(struct wmi_t *wmip) ++{ ++ void *osbuf; ++ ++ A_DPRINTF(DBG_WMI, (DBGFMT "Enter\n", DBGARG)); ++ ++ osbuf = A_NETBUF_ALLOC(0); ++ if (osbuf == NULL) { ++ return A_NO_MEMORY; ++ } ++ ++ return (wmi_cmd_send_xtnd(wmip, osbuf, WMIX_GPIO_INPUT_GET_CMDID, ++ NO_SYNC_WMIFLAG)); ++} ++ ++/* Send a command to the Target that changes the value of a GPIO register. */ ++A_STATUS ++wmi_gpio_register_set(struct wmi_t *wmip, ++ A_UINT32 gpioreg_id, ++ A_UINT32 value) ++{ ++ void *osbuf; ++ WMIX_GPIO_REGISTER_SET_CMD *register_set; ++ int size; ++ ++ size = sizeof(*register_set); ++ ++ A_DPRINTF(DBG_WMI, ++ (DBGFMT "Enter - reg=%d value=0x%x\n", DBGARG, gpioreg_id, value)); ++ ++ osbuf = A_NETBUF_ALLOC(size); ++ if (osbuf == NULL) { ++ return A_NO_MEMORY; ++ } ++ A_NETBUF_PUT(osbuf, size); ++ register_set = (WMIX_GPIO_REGISTER_SET_CMD *)(A_NETBUF_DATA(osbuf)); ++ ++ register_set->gpioreg_id = gpioreg_id; ++ register_set->value = value; ++ ++ return (wmi_cmd_send_xtnd(wmip, osbuf, WMIX_GPIO_REGISTER_SET_CMDID, ++ NO_SYNC_WMIFLAG)); ++} ++ ++/* Send a command to the Target to fetch the value of a GPIO register. */ ++A_STATUS ++wmi_gpio_register_get(struct wmi_t *wmip, ++ A_UINT32 gpioreg_id) ++{ ++ void *osbuf; ++ WMIX_GPIO_REGISTER_GET_CMD *register_get; ++ int size; ++ ++ size = sizeof(*register_get); ++ ++ A_DPRINTF(DBG_WMI, (DBGFMT "Enter - reg=%d\n", DBGARG, gpioreg_id)); ++ ++ osbuf = A_NETBUF_ALLOC(size); ++ if (osbuf == NULL) { ++ return A_NO_MEMORY; ++ } ++ A_NETBUF_PUT(osbuf, size); ++ register_get = (WMIX_GPIO_REGISTER_GET_CMD *)(A_NETBUF_DATA(osbuf)); ++ ++ register_get->gpioreg_id = gpioreg_id; ++ ++ return (wmi_cmd_send_xtnd(wmip, osbuf, WMIX_GPIO_REGISTER_GET_CMDID, ++ NO_SYNC_WMIFLAG)); ++} ++ ++/* Send a command to the Target acknowledging some GPIO interrupts. */ ++A_STATUS ++wmi_gpio_intr_ack(struct wmi_t *wmip, ++ A_UINT32 ack_mask) ++{ ++ void *osbuf; ++ WMIX_GPIO_INTR_ACK_CMD *intr_ack; ++ int size; ++ ++ size = sizeof(*intr_ack); ++ ++ A_DPRINTF(DBG_WMI, (DBGFMT "Enter ack_mask=0x%x\n", DBGARG, ack_mask)); ++ ++ osbuf = A_NETBUF_ALLOC(size); ++ if (osbuf == NULL) { ++ return A_NO_MEMORY; ++ } ++ A_NETBUF_PUT(osbuf, size); ++ intr_ack = (WMIX_GPIO_INTR_ACK_CMD *)(A_NETBUF_DATA(osbuf)); ++ ++ intr_ack->ack_mask = ack_mask; ++ ++ return (wmi_cmd_send_xtnd(wmip, osbuf, WMIX_GPIO_INTR_ACK_CMDID, ++ NO_SYNC_WMIFLAG)); ++} ++#endif /* CONFIG_HOST_GPIO_SUPPORT */ ++ ++A_STATUS ++wmi_set_access_params_cmd(struct wmi_t *wmip, A_UINT16 txop, A_UINT8 eCWmin, ++ A_UINT8 eCWmax, A_UINT8 aifsn) ++{ ++ void *osbuf; ++ WMI_SET_ACCESS_PARAMS_CMD *cmd; ++ ++ if ((eCWmin > WMI_MAX_CW_ACPARAM) || (eCWmax > WMI_MAX_CW_ACPARAM) || ++ (aifsn > WMI_MAX_AIFSN_ACPARAM)) ++ { ++ return A_EINVAL; ++ } ++ ++ osbuf = A_NETBUF_ALLOC(sizeof(*cmd)); ++ if (osbuf == NULL) { ++ return A_NO_MEMORY; ++ } ++ ++ A_NETBUF_PUT(osbuf, sizeof(*cmd)); ++ ++ cmd = (WMI_SET_ACCESS_PARAMS_CMD *)(A_NETBUF_DATA(osbuf)); ++ cmd->txop = txop; ++ cmd->eCWmin = eCWmin; ++ cmd->eCWmax = eCWmax; ++ cmd->aifsn = aifsn; ++ ++ return (wmi_cmd_send(wmip, osbuf, WMI_SET_ACCESS_PARAMS_CMDID, ++ NO_SYNC_WMIFLAG)); ++} ++ ++A_STATUS ++wmi_set_retry_limits_cmd(struct wmi_t *wmip, A_UINT8 frameType, ++ A_UINT8 trafficClass, A_UINT8 maxRetries, ++ A_UINT8 enableNotify) ++{ ++ void *osbuf; ++ WMI_SET_RETRY_LIMITS_CMD *cmd; ++ ++ if ((frameType != MGMT_FRAMETYPE) && (frameType != CONTROL_FRAMETYPE) && ++ (frameType != DATA_FRAMETYPE)) ++ { ++ return A_EINVAL; ++ } ++ ++ if (maxRetries > WMI_MAX_RETRIES) { ++ return A_EINVAL; ++ } ++ ++ if (frameType != DATA_FRAMETYPE) { ++ trafficClass = 0; ++ } ++ ++ osbuf = A_NETBUF_ALLOC(sizeof(*cmd)); ++ if (osbuf == NULL) { ++ return A_NO_MEMORY; ++ } ++ ++ A_NETBUF_PUT(osbuf, sizeof(*cmd)); ++ ++ cmd = (WMI_SET_RETRY_LIMITS_CMD *)(A_NETBUF_DATA(osbuf)); ++ cmd->frameType = frameType; ++ cmd->trafficClass = trafficClass; ++ cmd->maxRetries = maxRetries; ++ cmd->enableNotify = enableNotify; ++ ++ return (wmi_cmd_send(wmip, osbuf, WMI_SET_RETRY_LIMITS_CMDID, ++ NO_SYNC_WMIFLAG)); ++} ++ ++void ++wmi_get_current_bssid(struct wmi_t *wmip, A_UINT8 *bssid) ++{ ++ if (bssid != NULL) { ++ A_MEMCPY(bssid, wmip->wmi_bssid, ATH_MAC_LEN); ++ } ++} ++ ++A_STATUS ++wmi_set_opt_mode_cmd(struct wmi_t *wmip, A_UINT8 optMode) ++{ ++ void *osbuf; ++ WMI_SET_OPT_MODE_CMD *cmd; ++ ++ osbuf = A_NETBUF_ALLOC(sizeof(*cmd)); ++ if (osbuf == NULL) { ++ return A_NO_MEMORY; ++ } ++ ++ A_NETBUF_PUT(osbuf, sizeof(*cmd)); ++ ++ cmd = (WMI_SET_OPT_MODE_CMD *)(A_NETBUF_DATA(osbuf)); ++ A_MEMZERO(cmd, sizeof(*cmd)); ++ cmd->optMode = optMode; ++ ++ return (wmi_cmd_send(wmip, osbuf, WMI_SET_OPT_MODE_CMDID, ++ SYNC_BOTH_WMIFLAG)); ++} ++ ++A_STATUS ++wmi_opt_tx_frame_cmd(struct wmi_t *wmip, ++ A_UINT8 frmType, ++ A_UINT8 *dstMacAddr, ++ A_UINT8 *bssid, ++ A_UINT16 optIEDataLen, ++ A_UINT8 *optIEData) ++{ ++ void *osbuf; ++ WMI_OPT_TX_FRAME_CMD *cmd; ++ osbuf = A_NETBUF_ALLOC(optIEDataLen + sizeof(*cmd)); ++ if (osbuf == NULL) { ++ return A_NO_MEMORY; ++ } ++ ++ A_NETBUF_PUT(osbuf, (optIEDataLen + sizeof(*cmd))); ++ ++ cmd = (WMI_OPT_TX_FRAME_CMD *)(A_NETBUF_DATA(osbuf)); ++ A_MEMZERO(cmd, (optIEDataLen + sizeof(*cmd)-1)); ++ ++ cmd->frmType = frmType; ++ cmd->optIEDataLen = optIEDataLen; ++ //cmd->optIEData = (A_UINT8 *)((int)cmd + sizeof(*cmd)); ++ A_MEMCPY(cmd->bssid, bssid, sizeof(cmd->bssid)); ++ A_MEMCPY(cmd->dstAddr, dstMacAddr, sizeof(cmd->dstAddr)); ++ A_MEMCPY(&cmd->optIEData[0], optIEData, optIEDataLen); ++ ++ return (wmi_cmd_send(wmip, osbuf, WMI_OPT_TX_FRAME_CMDID, ++ NO_SYNC_WMIFLAG)); ++} ++ ++A_STATUS ++wmi_set_adhoc_bconIntvl_cmd(struct wmi_t *wmip, A_UINT16 intvl) ++{ ++ void *osbuf; ++ WMI_BEACON_INT_CMD *cmd; ++ ++ osbuf = A_NETBUF_ALLOC(sizeof(*cmd)); ++ if (osbuf == NULL) { ++ return A_NO_MEMORY; ++ } ++ ++ A_NETBUF_PUT(osbuf, sizeof(*cmd)); ++ ++ cmd = (WMI_BEACON_INT_CMD *)(A_NETBUF_DATA(osbuf)); ++ A_MEMZERO(cmd, sizeof(*cmd)); ++ cmd->beaconInterval = intvl; ++ ++ return (wmi_cmd_send(wmip, osbuf, WMI_SET_BEACON_INT_CMDID, ++ NO_SYNC_WMIFLAG)); ++} ++ ++ ++A_STATUS ++wmi_set_voice_pkt_size_cmd(struct wmi_t *wmip, A_UINT16 voicePktSize) ++{ ++ void *osbuf; ++ WMI_SET_VOICE_PKT_SIZE_CMD *cmd; ++ ++ osbuf = A_NETBUF_ALLOC(sizeof(*cmd)); ++ if (osbuf == NULL) { ++ return A_NO_MEMORY; ++ } ++ ++ A_NETBUF_PUT(osbuf, sizeof(*cmd)); ++ ++ cmd = (WMI_SET_VOICE_PKT_SIZE_CMD *)(A_NETBUF_DATA(osbuf)); ++ A_MEMZERO(cmd, sizeof(*cmd)); ++ cmd->voicePktSize = voicePktSize; ++ ++ return (wmi_cmd_send(wmip, osbuf, WMI_SET_VOICE_PKT_SIZE_CMDID, ++ NO_SYNC_WMIFLAG)); ++} ++ ++ ++A_STATUS ++wmi_set_max_sp_len_cmd(struct wmi_t *wmip, A_UINT8 maxSPLen) ++{ ++ void *osbuf; ++ WMI_SET_MAX_SP_LEN_CMD *cmd; ++ ++ /* maxSPLen is a two-bit value. If user trys to set anything ++ * other than this, then its invalid ++ */ ++ if(maxSPLen & ~0x03) ++ return A_EINVAL; ++ ++ osbuf = A_NETBUF_ALLOC(sizeof(*cmd)); ++ if (osbuf == NULL) { ++ return A_NO_MEMORY; ++ } ++ ++ A_NETBUF_PUT(osbuf, sizeof(*cmd)); ++ ++ cmd = (WMI_SET_MAX_SP_LEN_CMD *)(A_NETBUF_DATA(osbuf)); ++ A_MEMZERO(cmd, sizeof(*cmd)); ++ cmd->maxSPLen = maxSPLen; ++ ++ return (wmi_cmd_send(wmip, osbuf, WMI_SET_MAX_SP_LEN_CMDID, ++ NO_SYNC_WMIFLAG)); ++} ++ ++A_UINT8 ++convert_userPriority_to_trafficClass(A_UINT8 userPriority) ++{ ++ return (up_to_ac[userPriority & 0x7]); ++} ++ ++A_UINT8 ++wmi_get_power_mode_cmd(struct wmi_t *wmip) ++{ ++ return wmip->wmi_powerMode; ++} ++ ++A_STATUS ++wmi_verify_tspec_params(WMI_CREATE_PSTREAM_CMD *pCmd, A_BOOL tspecCompliance) ++{ ++ return A_OK; ++} ++ ++#ifdef CONFIG_HOST_TCMD_SUPPORT ++static A_STATUS ++wmi_tcmd_test_report_rx(struct wmi_t *wmip, A_UINT8 *datap, int len) ++{ ++ ++ A_DPRINTF(DBG_WMI, (DBGFMT "Enter\n", DBGARG)); ++ ++ A_WMI_TCMD_RX_REPORT_EVENT(wmip->wmi_devt, datap, len); ++ ++ return A_OK; ++} ++ ++#endif /* CONFIG_HOST_TCMD_SUPPORT*/ ++ ++A_STATUS ++wmi_set_authmode_cmd(struct wmi_t *wmip, A_UINT8 mode) ++{ ++ void *osbuf; ++ WMI_SET_AUTH_MODE_CMD *cmd; ++ ++ osbuf = A_NETBUF_ALLOC(sizeof(*cmd)); ++ if (osbuf == NULL) { ++ return A_NO_MEMORY; ++ } ++ ++ A_NETBUF_PUT(osbuf, sizeof(*cmd)); ++ ++ cmd = (WMI_SET_AUTH_MODE_CMD *)(A_NETBUF_DATA(osbuf)); ++ A_MEMZERO(cmd, sizeof(*cmd)); ++ cmd->mode = mode; ++ ++ return (wmi_cmd_send(wmip, osbuf, WMI_SET_AUTH_MODE_CMDID, ++ NO_SYNC_WMIFLAG)); ++} ++ ++A_STATUS ++wmi_set_reassocmode_cmd(struct wmi_t *wmip, A_UINT8 mode) ++{ ++ void *osbuf; ++ WMI_SET_REASSOC_MODE_CMD *cmd; ++ ++ osbuf = A_NETBUF_ALLOC(sizeof(*cmd)); ++ if (osbuf == NULL) { ++ return A_NO_MEMORY; ++ } ++ ++ A_NETBUF_PUT(osbuf, sizeof(*cmd)); ++ ++ cmd = (WMI_SET_REASSOC_MODE_CMD *)(A_NETBUF_DATA(osbuf)); ++ A_MEMZERO(cmd, sizeof(*cmd)); ++ cmd->mode = mode; ++ ++ return (wmi_cmd_send(wmip, osbuf, WMI_SET_REASSOC_MODE_CMDID, ++ NO_SYNC_WMIFLAG)); ++} ++ ++A_STATUS ++wmi_set_lpreamble_cmd(struct wmi_t *wmip, A_UINT8 status) ++{ ++ void *osbuf; ++ WMI_SET_LPREAMBLE_CMD *cmd; ++ ++ osbuf = A_NETBUF_ALLOC(sizeof(*cmd)); ++ if (osbuf == NULL) { ++ return A_NO_MEMORY; ++ } ++ ++ A_NETBUF_PUT(osbuf, sizeof(*cmd)); ++ ++ cmd = (WMI_SET_LPREAMBLE_CMD *)(A_NETBUF_DATA(osbuf)); ++ A_MEMZERO(cmd, sizeof(*cmd)); ++ cmd->status = status; ++ ++ return (wmi_cmd_send(wmip, osbuf, WMI_SET_LPREAMBLE_CMDID, ++ NO_SYNC_WMIFLAG)); ++} ++ ++A_STATUS ++wmi_set_rts_cmd(struct wmi_t *wmip, A_UINT16 threshold) ++{ ++ void *osbuf; ++ WMI_SET_RTS_CMD *cmd; ++ ++ osbuf = A_NETBUF_ALLOC(sizeof(*cmd)); ++ if (osbuf == NULL) { ++ return A_NO_MEMORY; ++ } ++ ++ A_NETBUF_PUT(osbuf, sizeof(*cmd)); ++ ++ cmd = (WMI_SET_RTS_CMD*)(A_NETBUF_DATA(osbuf)); ++ A_MEMZERO(cmd, sizeof(*cmd)); ++ cmd->threshold = threshold; ++ ++ return (wmi_cmd_send(wmip, osbuf, WMI_SET_RTS_CMDID, ++ NO_SYNC_WMIFLAG)); ++} ++ ++A_STATUS ++wmi_set_wmm_cmd(struct wmi_t *wmip, WMI_WMM_STATUS status) ++{ ++ void *osbuf; ++ WMI_SET_WMM_CMD *cmd; ++ ++ osbuf = A_NETBUF_ALLOC(sizeof(*cmd)); ++ if (osbuf == NULL) { ++ return A_NO_MEMORY; ++ } ++ ++ A_NETBUF_PUT(osbuf, sizeof(*cmd)); ++ ++ cmd = (WMI_SET_WMM_CMD*)(A_NETBUF_DATA(osbuf)); ++ A_MEMZERO(cmd, sizeof(*cmd)); ++ cmd->status = status; ++ ++ return (wmi_cmd_send(wmip, osbuf, WMI_SET_WMM_CMDID, ++ NO_SYNC_WMIFLAG)); ++ ++} ++ ++A_STATUS ++wmi_set_wmm_txop(struct wmi_t *wmip, WMI_TXOP_CFG cfg) ++{ ++ void *osbuf; ++ WMI_SET_WMM_TXOP_CMD *cmd; ++ ++ if( !((cfg == WMI_TXOP_DISABLED) || (cfg == WMI_TXOP_ENABLED)) ) ++ return A_EINVAL; ++ ++ osbuf = A_NETBUF_ALLOC(sizeof(*cmd)); ++ if (osbuf == NULL) { ++ return A_NO_MEMORY; ++ } ++ ++ A_NETBUF_PUT(osbuf, sizeof(*cmd)); ++ ++ cmd = (WMI_SET_WMM_TXOP_CMD *)(A_NETBUF_DATA(osbuf)); ++ A_MEMZERO(cmd, sizeof(*cmd)); ++ cmd->txopEnable = cfg; ++ ++ return (wmi_cmd_send(wmip, osbuf, WMI_SET_WMM_TXOP_CMDID, ++ NO_SYNC_WMIFLAG)); ++ ++} ++ ++#ifdef CONFIG_HOST_TCMD_SUPPORT ++/* WMI layer doesn't need to know the data type of the test cmd. ++ This would be beneficial for customers like Qualcomm, who might ++ have different test command requirements from differnt manufacturers ++ */ ++A_STATUS ++wmi_test_cmd(struct wmi_t *wmip, A_UINT8 *buf, A_UINT32 len) ++{ ++ void *osbuf; ++ char *data; ++ ++ A_DPRINTF(DBG_WMI, (DBGFMT "Enter\n", DBGARG)); ++ ++ osbuf= A_NETBUF_ALLOC(len); ++ if(osbuf == NULL) ++ { ++ return A_NO_MEMORY; ++ } ++ A_NETBUF_PUT(osbuf, len); ++ data = A_NETBUF_DATA(osbuf); ++ A_MEMCPY(data, buf, len); ++ ++ return(wmi_cmd_send(wmip, osbuf, WMI_TEST_CMDID, ++ NO_SYNC_WMIFLAG)); ++} ++ ++#endif ++ ++A_STATUS ++wmi_set_bt_status_cmd(struct wmi_t *wmip, A_UINT8 streamType, A_UINT8 status) ++{ ++ void *osbuf; ++ WMI_SET_BT_STATUS_CMD *cmd; ++ ++ osbuf = A_NETBUF_ALLOC(sizeof(*cmd)); ++ if (osbuf == NULL) { ++ return A_NO_MEMORY; ++ } ++ ++ A_NETBUF_PUT(osbuf, sizeof(*cmd)); ++ ++ cmd = (WMI_SET_BT_STATUS_CMD *)(A_NETBUF_DATA(osbuf)); ++ A_MEMZERO(cmd, sizeof(*cmd)); ++ cmd->streamType = streamType; ++ cmd->status = status; ++ ++ return (wmi_cmd_send(wmip, osbuf, WMI_SET_BT_STATUS_CMDID, ++ NO_SYNC_WMIFLAG)); ++} ++ ++A_STATUS ++wmi_set_bt_params_cmd(struct wmi_t *wmip, WMI_SET_BT_PARAMS_CMD* cmd) ++{ ++ void *osbuf; ++ WMI_SET_BT_PARAMS_CMD* alloc_cmd; ++ ++ osbuf = A_NETBUF_ALLOC(sizeof(*cmd)); ++ if (osbuf == NULL) { ++ return A_NO_MEMORY; ++ } ++ ++ A_NETBUF_PUT(osbuf, sizeof(*cmd)); ++ ++ alloc_cmd = (WMI_SET_BT_PARAMS_CMD *)(A_NETBUF_DATA(osbuf)); ++ A_MEMZERO(alloc_cmd, sizeof(*cmd)); ++ A_MEMCPY(alloc_cmd, cmd, sizeof(*cmd)); ++ ++ return (wmi_cmd_send(wmip, osbuf, WMI_SET_BT_PARAMS_CMDID, ++ NO_SYNC_WMIFLAG)); ++} ++ ++A_STATUS ++wmi_get_keepalive_configured(struct wmi_t *wmip) ++{ ++ void *osbuf; ++ WMI_GET_KEEPALIVE_CMD *cmd; ++ osbuf = A_NETBUF_ALLOC(sizeof(*cmd)); ++ if (osbuf == NULL) { ++ return A_NO_MEMORY; ++ } ++ A_NETBUF_PUT(osbuf, sizeof(*cmd)); ++ cmd = (WMI_GET_KEEPALIVE_CMD *)(A_NETBUF_DATA(osbuf)); ++ A_MEMZERO(cmd, sizeof(*cmd)); ++ return (wmi_cmd_send(wmip, osbuf, WMI_GET_KEEPALIVE_CMDID, ++ NO_SYNC_WMIFLAG)); ++} ++ ++A_UINT8 ++wmi_get_keepalive_cmd(struct wmi_t *wmip) ++{ ++ return wmip->wmi_keepaliveInterval; ++} ++ ++A_STATUS ++wmi_set_keepalive_cmd(struct wmi_t *wmip, A_UINT8 keepaliveInterval) ++{ ++ void *osbuf; ++ WMI_SET_KEEPALIVE_CMD *cmd; ++ ++ osbuf = A_NETBUF_ALLOC(sizeof(*cmd)); ++ if (osbuf == NULL) { ++ return A_NO_MEMORY; ++ } ++ ++ A_NETBUF_PUT(osbuf, sizeof(*cmd)); ++ ++ cmd = (WMI_SET_KEEPALIVE_CMD *)(A_NETBUF_DATA(osbuf)); ++ A_MEMZERO(cmd, sizeof(*cmd)); ++ cmd->keepaliveInterval = keepaliveInterval; ++ wmip->wmi_keepaliveInterval = keepaliveInterval; ++ ++ return (wmi_cmd_send(wmip, osbuf, WMI_SET_KEEPALIVE_CMDID, ++ NO_SYNC_WMIFLAG)); ++} ++ ++A_STATUS ++wmi_set_appie_cmd(struct wmi_t *wmip, A_UINT8 mgmtFrmType, A_UINT8 ieLen, ++ A_UINT8 *ieInfo) ++{ ++ void *osbuf; ++ WMI_SET_APPIE_CMD *cmd; ++ A_UINT16 cmdLen; ++ ++ if (ieLen > WMI_MAX_IE_LEN) { ++ return A_ERROR; ++ } ++ cmdLen = sizeof(*cmd) + ieLen - 1; ++ osbuf = A_NETBUF_ALLOC(cmdLen); ++ if (osbuf == NULL) { ++ return A_NO_MEMORY; ++ } ++ ++ A_NETBUF_PUT(osbuf, cmdLen); ++ ++ cmd = (WMI_SET_APPIE_CMD *)(A_NETBUF_DATA(osbuf)); ++ A_MEMZERO(cmd, cmdLen); ++ ++ cmd->mgmtFrmType = mgmtFrmType; ++ cmd->ieLen = ieLen; ++ A_MEMCPY(cmd->ieInfo, ieInfo, ieLen); ++ ++ return (wmi_cmd_send(wmip, osbuf, WMI_SET_APPIE_CMDID, NO_SYNC_WMIFLAG)); ++} ++ ++A_STATUS ++wmi_set_halparam_cmd(struct wmi_t *wmip, A_UINT8 *cmd, A_UINT16 dataLen) ++{ ++ void *osbuf; ++ A_UINT8 *data; ++ ++ osbuf = A_NETBUF_ALLOC(dataLen); ++ if (osbuf == NULL) { ++ return A_NO_MEMORY; ++ } ++ ++ A_NETBUF_PUT(osbuf, dataLen); ++ ++ data = A_NETBUF_DATA(osbuf); ++ ++ A_MEMCPY(data, cmd, dataLen); ++ ++ return (wmi_cmd_send(wmip, osbuf, WMI_SET_WHALPARAM_CMDID, NO_SYNC_WMIFLAG)); ++} ++ ++A_INT32 ++wmi_get_rate(A_INT8 rateindex) ++{ ++ if (rateindex == RATE_AUTO) { ++ return 0; ++ } else { ++ return(wmi_rateTable[(A_UINT32) rateindex]); ++ } ++} ++ ++void ++wmi_node_return (struct wmi_t *wmip, bss_t *bss) ++{ ++ if (NULL != bss) ++ { ++ wlan_node_return (&wmip->wmi_scan_table, bss); ++ } ++} ++ ++bss_t * ++wmi_find_Ssidnode (struct wmi_t *wmip, A_UCHAR *pSsid, ++ A_UINT32 ssidLength, A_BOOL bIsWPA2) ++{ ++ bss_t *node = NULL; ++ node = wlan_find_Ssidnode (&wmip->wmi_scan_table, pSsid, ++ ssidLength, bIsWPA2); ++ return node; ++} ++ ++void ++wmi_free_allnodes(struct wmi_t *wmip) ++{ ++ wlan_free_allnodes(&wmip->wmi_scan_table); ++} ++ ++bss_t * ++wmi_find_node(struct wmi_t *wmip, const A_UINT8 *macaddr) ++{ ++ bss_t *ni=NULL; ++ ni=wlan_find_node(&wmip->wmi_scan_table,macaddr); ++ return ni; ++} ++ ++A_STATUS ++wmi_dset_open_reply(struct wmi_t *wmip, ++ A_UINT32 status, ++ A_UINT32 access_cookie, ++ A_UINT32 dset_size, ++ A_UINT32 dset_version, ++ A_UINT32 targ_handle, ++ A_UINT32 targ_reply_fn, ++ A_UINT32 targ_reply_arg) ++{ ++ void *osbuf; ++ WMIX_DSETOPEN_REPLY_CMD *open_reply; ++ ++ A_DPRINTF(DBG_WMI, (DBGFMT "Enter - wmip=0x%x\n", DBGARG, (int)wmip)); ++ ++ osbuf = A_NETBUF_ALLOC(sizeof(*open_reply)); ++ if (osbuf == NULL) { ++ return A_NO_MEMORY; ++ } ++ ++ A_NETBUF_PUT(osbuf, sizeof(*open_reply)); ++ open_reply = (WMIX_DSETOPEN_REPLY_CMD *)(A_NETBUF_DATA(osbuf)); ++ ++ open_reply->status = status; ++ open_reply->targ_dset_handle = targ_handle; ++ open_reply->targ_reply_fn = targ_reply_fn; ++ open_reply->targ_reply_arg = targ_reply_arg; ++ open_reply->access_cookie = access_cookie; ++ open_reply->size = dset_size; ++ open_reply->version = dset_version; ++ ++ return (wmi_cmd_send_xtnd(wmip, osbuf, WMIX_DSETOPEN_REPLY_CMDID, ++ NO_SYNC_WMIFLAG)); ++} ++ ++static A_STATUS ++wmi_get_pmkid_list_event_rx(struct wmi_t *wmip, A_UINT8 *datap, A_UINT32 len) ++{ ++ WMI_PMKID_LIST_REPLY *reply; ++ A_UINT32 expected_len; ++ ++ if (len < sizeof(WMI_PMKID_LIST_REPLY)) { ++ return A_EINVAL; ++ } ++ reply = (WMI_PMKID_LIST_REPLY *)datap; ++ expected_len = sizeof(reply->numPMKID) + reply->numPMKID * WMI_PMKID_LEN; ++ ++ if (len < expected_len) { ++ return A_EINVAL; ++ } ++ ++ A_WMI_PMKID_LIST_EVENT(wmip->wmi_devt, reply->numPMKID, ++ reply->pmkidList); ++ ++ return A_OK; ++} ++ ++#ifdef CONFIG_HOST_DSET_SUPPORT ++A_STATUS ++wmi_dset_data_reply(struct wmi_t *wmip, ++ A_UINT32 status, ++ A_UINT8 *user_buf, ++ A_UINT32 length, ++ A_UINT32 targ_buf, ++ A_UINT32 targ_reply_fn, ++ A_UINT32 targ_reply_arg) ++{ ++ void *osbuf; ++ WMIX_DSETDATA_REPLY_CMD *data_reply; ++ int size; ++ ++ size = sizeof(*data_reply) + length; ++ ++ A_DPRINTF(DBG_WMI, ++ (DBGFMT "Enter - length=%d status=%d\n", DBGARG, length, status)); ++ ++ osbuf = A_NETBUF_ALLOC(size); ++ if (osbuf == NULL) { ++ return A_NO_MEMORY; ++ } ++ A_NETBUF_PUT(osbuf, size); ++ data_reply = (WMIX_DSETDATA_REPLY_CMD *)(A_NETBUF_DATA(osbuf)); ++ ++ data_reply->status = status; ++ data_reply->targ_buf = targ_buf; ++ data_reply->targ_reply_fn = targ_reply_fn; ++ data_reply->targ_reply_arg = targ_reply_arg; ++ data_reply->length = length; ++ ++ if (status == A_OK) { ++ if (a_copy_from_user(data_reply->buf, user_buf, length)) { ++ return A_ERROR; ++ } ++ } ++ ++ return (wmi_cmd_send_xtnd(wmip, osbuf, WMIX_DSETDATA_REPLY_CMDID, ++ NO_SYNC_WMIFLAG)); ++} ++#endif /* CONFIG_HOST_DSET_SUPPORT */ ++ ++A_STATUS ++wmi_set_wsc_status_cmd(struct wmi_t *wmip, A_UINT32 status) ++{ ++ void *osbuf; ++ char *cmd; ++ ++ wps_enable = status; ++ ++ osbuf = a_netbuf_alloc(sizeof(1)); ++ if (osbuf == NULL) { ++ return A_NO_MEMORY; ++ } ++ ++ a_netbuf_put(osbuf, sizeof(1)); ++ ++ cmd = (char *)(a_netbuf_to_data(osbuf)); ++ ++ A_MEMZERO(cmd, sizeof(*cmd)); ++ cmd[0] = (status?1:0); ++ return (wmi_cmd_send(wmip, osbuf, WMI_SET_WSC_STATUS_CMDID, ++ NO_SYNC_WMIFLAG)); ++} ++ +diff -ruN --exclude='*.orig' --exclude='*.rej' linux-2.6.29-rc3.owrt/drivers/ar6000/wmi/wmi_doc.h linux-2.6.29-rc3.owrt.om/drivers/ar6000/wmi/wmi_doc.h +--- linux-2.6.29-rc3.owrt/drivers/ar6000/wmi/wmi_doc.h 1970-01-01 01:00:00.000000000 +0100 ++++ linux-2.6.29-rc3.owrt.om/drivers/ar6000/wmi/wmi_doc.h 2009-05-10 22:27:59.000000000 +0200 +@@ -0,0 +1,4421 @@ ++/* ++ * ++ * Copyright (c) 2004-2007 Atheros Communications Inc. ++ * All rights reserved. ++ * ++ * ++ * 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; ++ * ++ * Software distributed under the License is distributed on an "AS ++ * IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or ++ * implied. See the License for the specific language governing ++ * rights and limitations under the License. ++ * ++ * ++ * ++ */ ++ ++ ++#if 0 ++Wireless Module Interface (WMI) Documentaion ++ ++ This section describes the format and the usage model for WMI control and ++ data messages between the host and the AR6000-based targets. The header ++ file include/wmi.h contains all command and event manifest constants as ++ well as structure typedefs for each set of command and reply parameters. ++ ++Data Frames ++ ++ The data payload transmitted and received by the target follows RFC-1042 ++ encapsulation and thus starts with an 802.2-style LLC-SNAP header. The ++ WLAN module completes 802.11 encapsulation of the payload, including the ++ MAC header, FCS, and WLAN security related fields. At the interface to the ++ message transport (HTC), a data frame is encapsulated in a WMI message. ++ ++WMI Message Structure ++ ++ The WMI protocol leverages an 802.3-style Ethernet header in communicating ++ the source and destination information between the host and the AR6000 ++ modules using a 14-byte 802.3 header ahead of the 802.2-style payload. In ++ addition, the WMI protocol adds a header to all data messages: ++ ++ { ++ INT8 rssi ++ The RSSI of the received packet and its units are shown in db above the ++ noise floor, and the noise floor is shown in dbm. ++ UINT8 info ++ Contains information on message type and user priority. Message type ++ differentiates between a data packet and a synchronization message. ++ } WMI_DATA_HDR ++ ++ User priority contains the 802.1d user priority info from host to target. Host ++ software translates the host Ethernet format to 802.3 format prior to Tx and ++ 802.3 format to host format in the Rx direction. The host does not transmit the ++ FCS that follows the data. MsgType differentiates between a regular data ++ packet (msgType=0) and a synchronization message (msgType=1). ++ ++Data Endpoints ++ ++ The AR6000 chipset provides several data endpoints to support quality of ++ service (QoS) and maintains separate queues and separate DMA engines for ++ each data endpoint. A data endpoint can be bi-directional. ++ ++ Best effort (BE) class traffic uses the default data endpoint (2). The host can ++ establish up to two additional data endpoints for other traffic classes. Once ++ such a data endpoint is established, it sends and receives corresponding QoS ++ traffic in a manner similar to the default data endpoint. ++ ++ If QoS is desired over the interconnect, host software must classify each data ++ packet and place it on the appropriate data endpoint. The information ++ required to classify data is generally available in-band as an 802.1p/q style ++ tag or as the ToS field in the IP header. The information may also be available ++ out-of-band depending on the host DDI. ++ ++Connection States ++ ++ Table B-1 describes the AR6000 WLAN connection states: ++ ++ Table B-1. AR6000 Connection States ++ ++Connection State ++ Description ++ ++ DISCONNECTED ++ In this state, the AR6000 device is not connected to a wireless ++ network. The device is in this state after reset when it sends the ++ WIRELESS MODULE “READY” EVENT, after it processes a ++ DISCONNECT command, and when it loses its link with the ++ access point (AP) that it was connected to. The device signals a ++ transition to the DISCONNECTED state with a “DISCONNECT” ++ event. ++ ++CONNECTED ++ In this state, the AR6000 device is connected to wireless networks. ++ The device enters this state after successfully processing a ++ CONNECT, which establishes a connection with a wireless ++ network. The device signals a transition to the CONNECTED state ++ with a “CONNECT” event. ++ ++ ++Message Types ++ ++ WMI uses commands, replies, and events for the control and configuration of ++ the AR6000 device. The control protocol is asynchronous. Table B-2 describes ++ AR6000 message types: ++ ++Table B-2. AR6000 Message Types ++ ++Message Type ++ Description ++ ++Commands ++ Control messages that flow from the host to the device ++ ++Replies/Events ++ Control messages that flow from the device to the host. ++ ++ The device issues a reply to some WMI commands, but not to others. ++ The payload in a reply is command-specific, and some commands do ++ not trigger a reply message at all. Events are control messages issued ++ by the device to signal the occurrence of an asynchronous event. ++ ++ ++WMI Message Format ++ ++ All WMI control commands, replies and events use the header format: ++ ++ WMI_CMD_HDR Header Format ++ { ++ UINT16 id ++ This 16-bit constant identifies which WMI command the host is issuing, ++ which command the target is replying to, or which event has occurred. ++ WMI_CMD_HDR ++ } ++ ++ ++ A variable-size command-, reply-, or event-specific payload follows the ++ header. Over the interconnect, all fields in control messages (including ++ WMI_CMD_HDR and the command specific payload) use 32-bit little Endian ++ byte ordering and fields are packed. The AR6000 device always executes ++ commands in order, and the host may send multiple commands without ++ waiting for previous commands to complete. A majority of commands are ++ processed to completion once received. Other commands trigger a longer ++ duration activity whose completion is signaled to the host through an event. ++ ++Command Restrictions ++ ++ Some commands may only be issued when the AR6000 device is in a certain ++ state. The host is required to wait for an event signaling a state transition ++ before such a command can be issued. For example, if a command requires ++ the device to be in the CONNECTED state, then the host is required to wait ++ for a “CONNECT” event before it issues that command. ++ ++ The device ignores any commands inappropriate for its current state. If the ++ command triggers a reply, the device generates an error reply. Otherwise, the ++ device silently ignores the inappropriate command. ++ ++Command and Data Synchronization ++ ++ WMI provides a mechanism for a host to advise the device of necessary ++ synchronization between commands and data. The device implements ++ synchronization; no implicit synchronization exists between endpoints. ++ ++ The host controls synchronization using the “SYNCHRONIZE” command ++ over the control channel and synchronization messages over data channels. ++ The device stops each data channel upon receiving a synchronization message ++ on that channel, processing all data packets received prior to that message. ++ After the device receives synchronization messages for each data endpoint ++ and the “SYNCHRONIZE” command, it resumes all channels. ++ ++ When the host must guarantee a command executes before processing new ++ data packets, it first issues the command, then issues the “SYNCHRONIZE” ++ command and sends synchronization messages on data channels. When the ++ host must guarantee the device has processed all old data packets before a ++ processing a new command, it issues a “SYNCHRONIZE” command and ++ synchronization messages on all data channels, then issues the desired ++ command. ++ ++ ++ ++WMI Commands ++ ++ ADD_BAD_AP ++ Cause the AR6000 device to avoid a particular AP ++ ADD_CIPHER_KEY ++ Add or replace any of the four AR6000 encryption keys ++ ADD_WOW_PATTERN ++ Used to add a pattern to the WoW pattern list ++ CLR_RSSI_SNR ++ Clear the current calculated RSSI and SNR value ++ CONNECT_CMD ++ Request that the AR6000 device establish a wireless connection ++ with the specified SSID ++ CREATE_PSTREAM ++ Create prioritized data endpoint between the host and device ++ DELETE_BAD_AP ++ Clear an entry in the bad AP table ++ DELETE_CIPHER_KEY ++ Delete a previously added cipher key ++ DELETE_PSTREAM ++ Delete a prioritized data endpoint ++ DELETE_WOW_PATTERN ++ Remove a pre-specified pattern from the WoW pattern list ++ EXTENSION ++ WMI message interface command ++ GET_BIT_RATE ++ Retrieve rate most recently used by the AR6000 ++ GET_CHANNEL_LIST ++ Retrieve list of channels used by the AR6000 ++ GET_FIXRATES ++ Retrieves the rate-mask set via the SET_FIXRATES command. ++ GET_PMKID_LIST_CMD ++ Retrieve the firmware list of PMKIDs ++ GET_ROAM_DATA ++ Internal use for data collection; available in special build only ++ GET_ROAM_TBL ++ Retrieve the roaming table maintained on the target ++ GET_TARGET_STATS ++ Request that the target send the statistics it maintains ++ GET_TX_PWR ++ Retrieve the current AR6000 device Tx power levels ++ GET_WOW_LIST ++ Retrieve the current list of WoW patterns ++ LQ_THRESHOLD_PARAMS ++ Set the link quality thresholds ++ OPT_TX_FRAME ++ Send a special frame (special feature) ++ RECONNECT ++ Request a reconnection to a BSS ++ RSSI_THRESHOLD_PARAMS ++ Configure how the AR6000 device monitors and reports signal ++ strength (RSSI) of the connected BSS ++ SCAN_PARAMS ++ Determine dwell time and changes scanned channels ++ SET_ACCESS_PARAMS ++ Set access parameters for the wireless network ++ SET_ADHOC_BSSID ++ Set the BSSID for an ad hoc network ++ SET_AKMP_PARAMS ++ Set multiPMKID mode ++ SET_APPIE ++ Add application-specified IE to a management frame ++ SET_ASSOC_INFO ++ Specify the IEs the device should add to association or ++ reassociation requests ++ SET_AUTH_MODE ++ Set 802.11 authentication mode of reconnection ++ SET_BEACON_INT ++ Set the beacon interval for an ad hoc network ++ SET_BIT_RATE ++ Set the AR6000 to a specific fixed bit rate ++ SET_BMISS_TIME ++ Set the beacon miss time ++ SET_BSS_FILTER ++ Inform the AR6000 of network types about which it wants to ++ receive information using a “BSSINFO” event ++ SET_BT_PARAMS ++ Set the status of a Bluetooth stream (SCO or A2DP) or set ++ Bluetooth coexistence register parameters ++ SET_BT_STATUS ++ Set the status of a Bluetooth stream (SCO or A2DP) ++ SET_CHANNEL_PARAMETERS ++ Configure WLAN channel parameters ++ SET_DISC_TIMEOUT ++ Set the amount of time the AR6000 spends attempting to ++ reestablish a connection ++ SET_FIXRATES ++ Set the device to a specific fixed PHY rate (supported subset) ++ SET_HALPARAM ++ Internal AR6000 command to set certain hardware parameters ++ SET_HOST_SLEEP_MODE ++ Set the host mode to asleep or awake ++ SET_IBSS_PM_CAPS ++ Support a non-standard power management scheme for an ++ ad hoc network ++ SET_LISTEN_INT ++ Request a listen interval ++ SET_LPREAMBLE ++ Override the short preamble capability of the AR6000 device ++ SET_MAX_SP_LEN ++ Set the maximum service period ++ SET_OPT_MODE ++ Set the special mode on/off (special feature) ++ SET_PMKID ++ Set the pairwise master key ID (PMKID) ++ SET_PMKID_LIST_CMD ++ Configure the firmware list of PMKIDs ++ SET_POWER_MODE ++ Set guidelines on trade-off between power utilization ++ SET_POWER_PARAMS ++ Configure power parameters ++ SET_POWERSAVE_PARAMS ++ Set the two AR6000 power save timers ++ SET_PROBED_SSID ++ Provide list of SSIDs the device should seek ++ SET_REASSOC_MODE ++ Specify whether the disassociated frame should be sent upon ++ reassociation ++ SET_RETRY_LIMITS ++ Limit how many times the device tries to send a frame ++ SET_ROAM_CTRL ++ Control roaming behavior ++ SET_RTS ++ Determine when RTS should be sent ++ SET_SCAN_PARAMS ++ Set the AR6000 scan parameters ++ SET_TKIP_COUNTERMEASURES ++ Enable/disable reports of TKIP MIC errors ++ SET_TX_PWR ++ Specify the AR6000 device Tx power levels ++ SET_VOICE_PKT_SIZE ++ Set voice packet size ++ SET_WMM ++ Override the AR6000 WMM capability ++ SET_WMM_TXOP ++ Configure TxOP bursting when sending traffic to a WMM- ++ capable AP ++ SET_WOW_MODE ++ Enable/disable WoW mode ++ SET_WSC_STATUS ++ Enable/disable profile check in cserv when the WPS protocol ++ is in progress ++ SNR_THRESHOLD_PARAMS ++ Configure how the device monitors and reports SNR of BSS ++ START_SCAN ++ Start a long or short channel scan ++ SYNCHRONIZE ++ Force a synchronization point between command and data ++ paths ++ TARGET_REPORT_ERROR_BITMASK ++ Control “ERROR_REPORT” events from the AR6000 ++ ++ ++ ++ ++Name ++ ADD_BAD_AP ++ ++Synopsis ++ The host uses this command to cause the AR6000 to avoid a particular AP. The ++ AR6000 maintain a table with up to two APs to avoid. An ADD_BAD_AP command ++ adds or replaces the specified entry in this bad AP table. ++ ++ If the AR6000 are currently connected to the AP specified in this command, they ++ disassociate. ++ ++Command ++ wmiconfig eth1 --badap <bssid> <badApIndex> ++ ++Command Parameters ++ UINT8 badApIndex Index [0...1] that identifies which entry in the ++ bad AP table to use ++ ++ ++ UINT8 bssid[6] MAC address of the AP to avoid ++ ++Command Values ++ badApIndex = 0, 1 Entry in the bad AP table to use ++ ++Reset Value ++ The bad AP table is cleared ++ ++Restrictions ++ None ++ ++See Also ++ “DELETE_BAD_AP” on page B-13 ++ ++===================================================================== ++Name ++ ADD_CIPHER_KEY ++ ++Synopsis ++ The host uses this command to add/replace any of four encryption keys on the ++ AR6000. The ADD_CIPHER_KEY command is issued after the CONNECT event ++ has been received by the host for all dot11Auth modes except for SHARED_AUTH. ++ When the dot11AuthMode is SHARED_AUTH, then the ADD_CIPHER_KEY ++ command should be issued before the “CONNECT” command. ++ ++Command ++ wmiconfig eth1 --cipherkey <keyIndex> <keyType> <keyUsage> ++ <keyLength> <keyopctrl> <keyRSC> <key> ++ ++Command Parameters ++ UINT8 keyIndex Index (0...3) of the key to add/replace; ++ uniquely identifies the key ++ UINT8 keyType CRYPTO_TYPE ++ UINT8 keyUsage Specifies usage parameters of the key when ++ keyType = WEP_CRYPT ++ UINT8 keyLength Length of the key in bytes ++ UINT8 keyOpCtrl bit[0] = Initialize TSC (default), ++ bit[1] = Initialize RSC ++ UINT8 keyRSC[8] Key replay sequence counter (RSC) initial ++ value the device should use ++ UINT8 key[32] Key material used for this connection ++ Command Values ++ { ++ NONE_CRYPT = 1 ++ WEP_CRYPT = 2 ++ TKIP_CRYPT = 3 ++ AES_CRYPT = 4 ++ KEY_OP_INIT_TSC 0x01 ++ KEY_OP_INIT_RSC 0x02 ++ KEY_OP_INIT_VAL 0x03 ++ Default is to Initialize the TSC ++ KEY_OP_VALID_MASK 0x04 ++ Two operations defined ++ } CRYPTO_TYPE ++ ++ { ++ PAIRWISE_USAGE = 0 Set if the key is used for unicast traffic only ++ GROUP_USAGE = 1 Set if the key is used to receive multicast ++ traffic (also set for static WEP keys) ++ TX_USAGE = 2 Set for the GROUP key used to transmit frames ++ All others are reserved ++ } KEY_USAGE ++ ++Reset Value ++ The four available keys are disabled. ++ ++Restrictions ++ The cipher should correspond to the encryption mode specified in the “CONNECT” ++ command. ++ ++See Also ++ “DELETE_CIPHER_KEY” ++ ++===================================================================== ++ ++ ++Name ++ ADD_WOW_PATTERN ++ ++Synopsis ++ The host uses this command to add a pattern to the WoW pattern list; used for ++ pattern-matching for host wakeups by the WoW module. If the host mode is asleep ++ and WoW is enabled, all packets are matched against the existing WoW patterns. If a ++ packet matches any of the patterns specified, the target will wake up the host. All ++ non-matching packets are discarded by the target without being sent up to the host. ++ ++Command ++ wmiconfig –addwowpattern <list-id> <filter-size> <filter-offset> ++ <pattern> <mask> ++ ++Command Parameters ++ A_UINT8 filter_list_id ID of the list that is to include the new pattern ++ A_UINT8 filter_size Size of the new pattern ++ A_UINT8 filter_offset Offset at which the pattern matching for this ++ new pattern should begin at ++ A_UINT8 filter[1] Byte stream that contains both the pattern and ++ the mask of the new WoW wake-up pattern ++ ++Reply Parameters ++ None ++ ++Reset Value ++ None defined (default host mode is awake) ++ ++Restrictions ++ None ++ ++See Also ++ “DELETE_WOW_PATTERN” ++ ++===================================================================== ++ ++ ++Name ++ CLR_RSSI_SNR ++ ++Synopsis ++ Clears the current calculated RSSI and SNR value. RSSI and SNR are reported by ++ running-average value. This command will clear the history and have a fresh start ++ for the running-average mechanism. ++ ++Command ++ wmiconfig eth1 --cleanRssiSnr ++ ++Command Parameters ++ None ++ ++Reply Parameters ++ None ++ ++Reset Value ++ None defined ++ ++Restrictions ++ None ++ ++===================================================================== ++ ++Name ++ CONNECT_CMD ++ ++Synopsis ++ New connect control information (connectCtrl) is added, with 32 possible modifiers. ++ ++ CONNECT_SEND_REASSOC ++ Valid only for a host-controlled connection to a ++ particular AP. If this bit is set, a reassociation frame is ++ sent. If this bit is clear, an association request frame is ++ sent to the AP. ++ ++ CONNECT_IGNORE_WPAx_GROUP_CIPHER ++ No group key is issued in the CONNECT command, ++ so use the group key advertised by the AP. In a target- ++ initiated roaming situation this allows a STA to roam ++ between APs that support different multicast ciphers. ++ ++ CONNECT_PROFILE_MATCH_DONE ++ In a host-controlled connection case, it is possible that ++ during connect, firmware may not have the ++ information for a profile match (e.g, when the AP ++ supports hidden SSIDs and the device may not ++ transmit probe requests during connect). By setting ++ this bit in the connection control information, the ++ firmware waits for a beacon from the AP with the ++ BSSID supplied in the CONNECT command. No ++ additional profile checks are done. ++ ++ CONNECT_IGNORE_AAC_BEACON ++ Ignore the Admission Capacity information in the ++ beacon of the AP ++ ++ CONNECT_ASSOC_POLICY_USER ++ When set, the CONNECT_SEND_REASSOC setting ++ determines if an Assoc or Reassoc is sent to an AP ++ ++Command ++ wmiconfig --setconnectctrl <ctrl flags bitmask> ++ ++Command Parameters ++ typedef struct{ ++ A_UINT8 networktype; ++ A_UINT8 dot11authmode; ++ A_UINT8 authmode; ++ A_UINT8 pairwiseCryptoType; /*CRYPTO_TYPE*/ ++ A_UINT8 pairwiseCryptoLen; ++ A_UINT8 groupCryptoType; /*CRYPTO_TYPE*/ ++ A_UINT8 groupCryptoLen; ++ A_UINT8 ssidLength; ++ A_UCHAR ssid[WMI_MAX_SSID_LEN]; ++ A_UINT16 channel; ++ A_UINT8 bssid[AUTH_MAC_LEN]; ++ A_UINT8 ctrl_flags; /*WMI_CONNECT_CTRL_FLAGS_BITS*/ ++ } WMI_CONNECT_CMD; ++ ++ ctrl flags bitmask ++ = 0x0001 CONNECT_ASSOC_POLICY_USER ++ Assoc frames are sent using the policy specified by ++ the flag ++ = 0x0002 CONNECT_SEND_REASSOC ++ Send Reassoc frame while connecting, otherwise send ++ assoc frames ++ = 0x0004 CONNECT_IGNORE_WPAx_GROUP_CIPHER ++ Ignore WPAx group cipher for WPA/WPA2 ++ = 0x0008 CONNECT_PROFILE_MATCH_DONE ++ Ignore any profile check ++ = 0x0010 CONNECT_IGNORE_AAC_BEACON ++ Ignore the admission control information in the ++ beacon ++ ... CONNECT_CMD, continued ++ Command Values ++ typedef enum { ++ INFRA_NETWORK = 0x01, ++ ADHOC_NETWORK = 0x02, ++ ADHOC_CREATOR = 0x04, ++ } NETWORK_TYPE; ++ ++ typedef enum { ++ OPEN_AUTH = 0x01, ++ SHARED_AUTH = 0x02, ++ LEAP_AUTH = 0x04, ++ } DOT11_AUTH_MODE; ++ typedef enum { ++ NONE_AUTH = 0x01, ++ WPA_AUTH = 0x02, ++ WPA_PSK_AUTH = 0x03, ++ WPA2_AUTH = 0x04, ++ WPA2_PSK_AUTH = 0x05, ++ WPA_AUTH_CCKM = 0x06, ++ WPA2_AUTH_CCKM = 0x07, ++ } AUTH_MODE; ++ typedef enum { ++ NONE_CRYPT = 0x01, ++ WEP_CRYPT = 0x02, ++ TKIP_CRYPT = 0x03, ++ AES_CRYPT = 0x04, ++ } CRYPTO_TYPE; ++ typedef enum { ++ CONNECT_ASSOC_POLICY_USER = 0x0001, ++ CONNECT_SEND_REASSOC = 0x0002, ++ CONNECT_IGNORE_WPAx_GROUP_CIPHER = 0x0004, ++ CONNECT_PROFILE_MATCH_DONE = 0x0008, ++ CONNECT_IGNORE_AAC_BEACON = 0x0010, ++ } WMI_CONNECT_CTRL_FLAGS_BITS; ++ ++ pairwiseCryptoLen and groupCryptoLen are valid when the respective ++ CryptoTypesis WEP_CRYPT, otherwise this value should be 0. This is the length in ++ bytes. ++ ++Reset Value ++ None defined ++ ++Restrictions ++ None ++ ++===================================================================== ++ ++ ++Name ++ CREATE_PSTREAM ++ ++Synopsis ++ The host uses this command to create a new prioritized data endpoint between the ++ host and the AR6000 device that carries a prioritized stream of data. If the AP that the ++ device connects to requires TSPEC stream establishment, the device requests the ++ corresponding TSPEC with the AP. The maximum and minimum service interval ++ ranges from 0 – 0x7FFFFFFF (ms), where 0 = disabled. The device does not send a ++ reply event for this command, as it is always assumed the command has succeeded. ++ An AP admission control response comes to the host via a WMI_CAC_INDICATION ++ event, once the response for the ADDTS frame comes. ++ ++ Examples of cases where reassociation is generated (when WMM) and cases where ++ ADDTS is generated (when WMM and enabling ACM) are when: ++ Changing UAPSD flags in WMM mode, reassociation is generated ++ Changing the interval of sending auto QoS Null frame in WMM mode; ++ reassociation is not generated ++ Issuing a command with same previous parameters in WMM mode and enabling ++ ACM, an ADDTS request is generated ++ Changing the interval of a QoS null frame sending in WMM mode and enabling ++ ACM, an ADDTS request is generated ++ Issuing the command in disconnected state, reassociation or ADDTS is not ++ generated but the parameters are available after (re)association ++ ++Command ++ --createqos <user priority> <direction> <traffic class> ++<trafficType> <voice PS capability> <min service interval> <max ++service interval> <inactivity interval> <suspension interval> ++<service start time> <tsid> <nominal MSDU> <max MSDU> <min data ++rate> <mean data rate> <peak data rate> <max burst size> <delay ++bound> <min phy rate> <sba> <medium time> where: ++ ++ <user priority> ++ 802.1D user priority range (0–7) ++ <direction> ++ = 0 Tx (uplink) traffic ++ = 1 Rx (downlink) traffic ++ = 2 Bi-directional traffic ++ <traffic class> ++ = 1 BK ++ = 2 VI ++ = 3 VO ++ <trafficType> ++ = 0 Aperiodic ++ = 1 Periodic ++ <voice PS capability> ++ Specifies whether the voice power save mechanism ++ (APSD if AP supports it or legacy/simulated APSD ++ [using PS-Poll]) should be used ++ = 0 Disable voice power save for traffic class ++ = 1 Enable APSD voice power save for traffic class ++ = 2 Enable voice power save for all traffic classes ++ <min service interval> ++ (In ms) ++ <max service interval> ++ Inactivity interval (in ms) (0 = Infinite) ++ <suspension interval> ++ (In ms) ++ <service start time> ++ Service start time ++ <tsid> ++ TSID range (0–15) ++ <nominal MSDU> ++ Nominal MAC SDU size ++ <max MSDU> ++ Maximum MAC SDU size ++ <min data rate> ++ Minimum data rate (in bps) ++ <mean data rate> ++ Mean data rate (in bps) ++ <peak data rate> ++ Peak data rate (in bps) ++ <max burst size> ++ Maximum burst size (in bps) ++ <delay bound> ++ Delay bound ++ <min phy rate> ++ Minimum PHY rate (in bps) ++ <sba> ++ Surplus bandwidth allowance ++ <medium time> ++ Medium time in TU of 32-ms periods per sec ++ ... CREATE_PSTREAM (continued) ++ ++Command Parameters ++ UINT8 trafficClass TRAFFIC_CLASS value ++ UINT8 traffic ++ Direction ++ DIR_TYPE value ++ UINT8 rxQueueNum ++ AR6000 device mailbox index (2 or 3) ++ corresponding to the endpoint the host ++ wishes to use to receive packets for the ++ prioritized stream ++ UINT8 trafficType TRAFFIC_TYPE value ++ UINT8 voicePS ++Capability ++ VOICEPS_CAP_TYPE value ++ UINT8 tsid Traffic stream ID ++ UINT8 userPriority 802.1D user priority ++ UINT16 nominalMSDU Nominal MSDU in octets ++ UINT16 maxMSDU Maximum MSDU in octets ++ UINT32 minServiceInt Minimum service interval: the min. ++ period of traffic specified (in ms) ++ UINT32 maxServiceInt Maximum service interval: the max. ++ period of traffic specified (in ms) ++ UINT32 inactivityInt Indicates how many ms an established ++ stream is inactive before the prioritized ++ data endpoint is taken down and the ++ corresponding T-SPEC deleted ++ UINT32 suspensionInt Suspension interval (in ms) ++ UINT32 service StartTime Service start time ++ UINT32 minDataRate Minimum data rate (in bps) ++ UINT32 meanDataRate Mean data rate (in bps) ++ UINT32 peakDataRate Peak data rate (in bps) ++ UINT32 maxBurstSize ++ UINT32 delayBound ++ UINT32 minPhyRate Minimum PHY rate for TSPEC (in bps) ++ UINT32 sba Surplus bandwidth allowance ++ UINT32 mediumTime Medium TSPEC time (in units of 32 ms) ++Command Values ++ { ++ WMM_AC_BE = 0 Best Effort ++ WMM_AC_BK = 1 Background ++ WMM_AC_VI = 2 Video ++ WMM_AC_VO = 3 Voice ++ All other values reserved ++ } TRAFFIC_CLASS ++ { ++ UPLINK_TRAFFIC = 0 From the AR6000 device to the AP ++ DOWNLINK_TRAFFIC = 1 From the AP to the AR6000 device ++ BIDIR_TRAFFIC = 2 Bi-directional traffic ++ All other values reserved ++ } DIR_TYPE ++ { ++ DISABLE_FOR_THIS_AC = 0 ++ ENABLE_FOR_THIS_AC = 1 ++ ENABLE_FOR_ALL_AC = 2 ++ All other values reserved ++ } VOICEPS_CAP_TYPE ++ ++ ... CREATE_PSTREAM (continued) ++ ++ ++ VI BE BK Supported, Y/N? ++ 0 0 0 0 Y ++ 0 0 0 1 Y ++ 0 0 1 0 N ++ 0 0 1 1 N ++ 0 1 0 0 Y ++ 0 1 0 1 Y ++ 0 1 1 0 N ++ 0 1 1 1 N ++ 1 0 0 0 Y ++ 1 0 0 1 Y ++ 1 0 1 0 N ++ 1 1 0 0 N ++ 1 1 0 1 Y ++ 1 1 0 0 N ++ 1 1 1 0 N ++ 1 1 1 1 Y ++ ++Reset Value ++ No pstream is present after reset; each of the BE, BK, VI,VO pstreams must be created ++ (either implicitly by data flow or explicitly by user) ++ ++Restrictions ++ This command can only be issued when the device is in the CONNECTED state. If ++ the device receives the command while in DISCONNECTED state, it replies with a ++ failure indication. At most four prioritized data endpoints can be created, one for ++ each AC. ++ ++See Also ++ “DELETE_PSTREAM” ++===================================================================== ++ ++Name ++ DELETE_BAD_AP ++ ++Synopsis ++ The host uses this command to clear a particular entry in the bad AP table ++ ++Command ++ wmiconfig eth1 --rmAP [--num=<index>] // used to clear a badAP ++ entry. num is index from 0-3 ++ ++Command Parameters ++ UINT8 badApIndex Index [0...n] that identifies the entry in the bad ++ AP table to delete ++ ++Command Values ++ badApIndex = 0, 1, 2, 3 ++ Entry in the bad AP table ++ ++Reset Value ++ None defined ++ ++Restrictions ++ None ++ ++See Also ++ “ADD_BAD_AP” ++ ++===================================================================== ++ ++ ++Name ++ DELETE_CIPHER_KEY ++ ++Synopsis ++ The host uses this command to delete a key that was previously added with the ++ “ADD_CIPHER_KEY” command. ++ ++Command ++ TBD ++ ++Command Parameters ++ UINT8 keyIndex Index (0...3) of the key to be deleted ++ ++Command Values ++ keyIndex = 0, 1,2, 3 Key to delete ++ ++Reset Value ++ None ++ ++Restrictions ++ The host should not delete a key that is currently in use by the AR6000. ++ ++See Also ++ “ADD_CIPHER_KEY” ++ ++===================================================================== ++ ++Name ++ DELETE_PSTREAM ++ ++Synopsis ++ The host uses this command to delete a prioritized data endpoint created by a ++ previous “CREATE_PSTREAM” command ++ ++Command ++ --deleteqos <trafficClass> <tsid>, where: ++ ++ <traffic class> ++ = 0 BE ++ = 1 BK ++ = 2 VI ++ = 3 VO ++ <tsid> ++ The TSpec ID; use the -qosqueue option ++ to get the active TSpec IDs for each traffic class ++ ++Command Parameters ++ A_UINT8 trafficClass Indicate the traffic class of the stream ++ being deleted ++ ++Command Values ++ { ++ WMM_AC_BE = 0 Best effort ++ WMM_AC_BK = 1 Background ++ WMM_AC_VI = 2 Video ++ WMM_AC_VO = 3 Voice ++ } TRAFFIC CLASS ++ ++ 0-15 for TSID ++ ++Reply Values ++ N/A ++ ++Restrictions ++ This command should only be issued after a “CREATE_PSTREAM” command has ++ successfully created a prioritized stream ++ ++See Also ++ “CREATE_PSTREAM” ++ ++===================================================================== ++ ++ ++Name ++ DELETE_WOW_PATTERN ++ ++Synopsis ++ The host uses this command to remove a pre-specified pattern from the ++ WoW pattern list. ++ ++Command ++ wmiconfig –delwowpattern <list-id> <pattern-id> ++ ++Command Parameters ++ A_UINT8 filter_list_id ID of the list that contains the WoW filter ++ pattern to delete ++ A_UINT8 filter_id ID of the WoW filter pattern to delete ++ ++Reply Parameters ++ None ++ ++ ++ ++Reset Value ++ None defined ++ ++Restrictions ++ None ++ ++See Also ++ “ADD_WOW_PATTERN” ++ ++===================================================================== ++ ++ ++Name ++ EXTENSION ++ ++Synopsis ++ The WMI message interface is used mostly for wireless control messages to a wireless ++ module applicable to wireless module management regardless of the target platform ++ implementation. However, some commands only peripherally related to wireless ++ management are desired during operation. These wireless extension commands may ++ be platform-specific or implementation-dependent. ++ ++Command ++ N/A ++ ++Command Parameters ++ Command-specific ++ ++Command Values ++ Command-specific ++ ++Reply Parameters ++ Command-specific ++ ++Reset Values ++ None defined ++ ++Restrictions ++ None defined ++ ++===================================================================== ++ ++ ++Name ++ GET_BIT_RATE ++ ++Synopsis ++ Used by the host to obtain the rate most recently used by the AR6000 device ++ ++Command ++ wmiconfig eth1 --getfixrates ++ ++Command Parameters ++ None ++ ++ ++ ++Reply Parameters ++ INT8 ++ rateIndex ++ See the “SET_BIT_RATE” command ++ ++Reset Values ++ None ++ ++Restrictions ++ This command should only be used during development/debug; it is not intended ++for use in production. It is only valid when the device is in the CONNECTED state ++ ++See Also ++ “SET_BIT_RATE” ++ ++===================================================================== ++ ++ ++Name ++ GET_CHANNEL_LIST ++ ++Synopsis ++ Used by the host uses to retrieve the list of channels that can be used by the device ++ while in the current wireless mode and in the current regulatory domain. ++ ++Command ++ TBD ++ ++Command Parameters ++ None ++ ++Reply Parameters ++ UINT8 reserved Reserved ++ UINT8 numberOfChannels Number of channels the reply contains ++ UINT16 channelList[numberOfChannels] Array of channel frequencies (in MHz) ++ ++Reset Values ++ None defined ++ ++Restrictions ++ The maximum number of channels that can be reported are 32 ++ ++===================================================================== ++ ++ ++Name ++ GET_FIXRATES ++ ++Synopsis ++ Clears the current calculated RSSI and SNR value. RSSI and SNR are reported by ++ running-average value. This command will clear the history and have a fresh start for ++ the running-average mechanism. ++ ++Synopsis ++ This returns rate-mask set via WMI_SET_FIXRATES to retrieve the current fixed rate ++ that the AR6001 or AR6001 is using. See “SET_FIXRATES”. ++ ++Command ++ wmiconfig eth1 --getfixrates ++ ++Command Parameters ++ A_UINT16 fixRateMask; Note: if this command is used prior to ++ using WMI_SET_FIXRATES, AR6000 ++ returns 0xffff as fixRateMask, indicating ++ all the rates are enabled ++ ++Reply Parameters ++ None ++ ++Reset Value ++ None defined ++ ++Restrictions ++ None ++ ++See Also ++ “SET_FIXRATES” ++ ++===================================================================== ++ ++ ++ ++Name ++ GET_PMKID_LIST_CMD ++ ++Synopsis ++ Retrieves the list of PMKIDs on the firmware. The ++ WMI_GET_PMKID_LIST_EVENT is generated by the firmware. ++ ++Command ++ TBD ++ ++Command Parameters ++ ++Reset Values ++ None ++ ++Restrictions ++ None ++ ++See Also ++ SET_PMKID_LIST_CMD GET_PMKID_LIST_EVENT ++ ++===================================================================== ++ ++ ++Name ++ GET_ROAM_TBL ++ ++Synopsis ++ Retrieve the roaming table maintained on the target. The response is reported ++ asynchronously through the ROAM_TBL_EVENT. ++ ++Command ++ wmiconfig --getroamtable <roamctrl> <info> ++ ++Command Parameters ++ A_UINT8 roamCtrlType; ++ A_UINT16 roamMode ++ A_UINT16 numEntries ++ WMI_BSS_ROAM_INFO bssRoamInfo[1] ++ ++Reply Value ++ Reported asynchronously through the ROAM_TBL_EVENT ++ ++Reset Value ++ None defined ++ ++Restrictions ++ None ++ ++See Also ++ SET_KEEPALIVE ++ ++===================================================================== ++ ++ ++Name ++ GET_TARGET_STATS ++ ++Synopsis ++ The host uses this command to request that the target send the statistics that it ++ maintains. The statistics obtained from the target are accrued in the host every time ++ the GET_TARGET_STATS command is issued. The --clearStats option is added to ++ clear the target statistics maintained in the host. ++ ++Command ++ wmiconfig --getTargetStats --clearStats ++ ++Command Parameters ++ TARGET_STATS targetStats ++ WMI_TARGET_STATS ++ UINT8 clearStats ++ ++ ++Reply Value ++ RSSI return value (0–100) ++ ++Reset Values ++ All statistics are cleared (zeroed) ++ ++Restrictions ++ The --getTargetStats option must be used; the --clearStats option is also available also ++ ++ ++===================================================================== ++ ++Name ++ GET_TX_PWR ++ ++Synopsis ++ The host uses this command to retrieve the current Tx power level ++ ++Command ++ wmiconfig -i eth1 --getpower ++ ++Command Parameters ++ None ++ ++Reply Parameters ++ UINT16 dbM The current Tx power level specified in dbM ++ ++Reset Values ++ The maximum permitted by the regulatory domain ++ ++Restrictions ++ None ++ ++See Also ++ “SET_TX_PWR” ++ ++===================================================================== ++ ++ ++Name ++ GET_WOW_LIST ++ ++Synopsis ++ The host uses this command to retrieve the current list of WoW patterns. ++ ++Command ++ wmiconfig –getwowlist <list-id> ++ ++Command Parameters ++ A_UINT8 filter_list_id ID of the list of WoW patterns to retrieve ++ ++Reply Value(s) ++ A_UINT16 num_filters Number of WoW patterns contained in the list ++ A_UINT8 wow_mode Current mode of WoW (enabled or disabled) ++ A_UINT8 host_mode Current host mode (asleep or awake) ++ WOW_FILTER wow_filters[1] ++ Contents of the WoW filter pattern list ++ (contains mask, pattern, offset and size ++ information for each of the patterns) ++ ++Reset Value ++ None defined ++ ++Restrictions ++ None ++ ++See Also ++ “SET_WSC_STATUS” ++ ++===================================================================== ++ ++ ++Name ++ LQ_THRESHOLD_PARAMS ++ ++Synopsis ++ Sets Link Quality thresholds, the sampling will happen at every unicast data frame ++ Tx if a certain threshold is met, and the corresponding event will be sent to the host. ++ ++Command ++ --lqThreshold <enable> <upper_threshold_1> ... ++ <upper_threshold_4> <lower_threshold_1> ... <lower_threshold_4> ++ ++Command Parameters ++ <enable> = 0 Disable link quality sampling ++ = 1 Enable link quality sampling ++ <upper_threshold_x> Above thresholds (value in [0,100]), in ++ ascending order ++ <lower_threshold_x> Below thresholds (value in [0,100]), in ++ ascending order ++ ++Command Values ++ See command parameters ++ ++Reset Value ++ None defined ++ ++Restrictions ++ None ++ ++===================================================================== ++ ++ ++Name ++ OPT_TX_FRAME ++ ++Synopsis ++ Special feature, sends a special frame. ++ ++Command ++ wmiconfig --sendframe <frmType> <dstaddr> <bssid> <optIEDatalen> ++ <optIEData> ++ ++Command Parameters ++ { ++ A_UINT16 optIEDataLen; ++ A_UINT8 frmType; ++ A_UINT8 dstAddr[ATH_MAC_LEN]; ++ A_UINT8 bssid[ATH_MAC_LEN]; ++ A_UINT8 optIEData[1]; ++ } WMI_OPT_TX_FRAME_CMD; ++ ++Command Values ++ <frmtype> = 1 Probe request frame ++ = 2 Probe response frame ++ = 3 CPPP start ++ = 4 CPPP stop ++ ++Reset Value ++ None defined ++ ++Restrictions ++ Send a special frame only when special mode is on. ++ ++===================================================================== ++ ++ ++Name ++ RECONNECT ++ ++Synopsis ++ This command requests a reconnection to a BSS to which the AR6000 device was ++ formerly connected ++ ++Command ++ TBD ++ ++Command Parameters ++ UINT16 channel Provides a hint as to which channel was ++ used for a previous connection ++ UINT8 bssid[6] If set, indicates which BSSID to connect to ++ ++Command Values ++ None ++ ++Reset Values ++ None ++ ++Restrictions ++ None ++ ++See Also ++ “CONNECT_CMD” ++ ++===================================================================== ++ ++ ++Name ++ RSSI_THRESHOLD_PARAMS ++ ++Synopsis ++ Configures how the AR6000 device monitors and reports signal strength (RSSI) of the ++ connected BSS, which is used as a link quality metric. The four RSSI threshold sets (in ++ dbM) of the host specification divide the signal strength range into six segments. ++ When signal strength increases or decreases across one of the boundaries, an ++ RSSI_THRESHOLD event is signaled to the host. The host may then choose to take ++ action (such as influencing roaming). ++ ++Command ++ wmiconfig eth1 --rssiThreshold <weight> <pollTime> ++ <above_threshold_val_1> ... <above_threshold_tag_6> ++ <above_threshold_val_6> ++ <below_threshold_tag_1> <below_threshold_val_1> ... ++ <below_threshold_tag_6> <below_threshold_val_6> ++ ++Command Parameters ++ UINT8 weight Range in [1, 16] used to calculate average RSSI ++ UINT32 pollTime RSSI (signal strength) sampling frequency in ++ seconds (if pollTime = 0, single strength ++ sampling is disabled) ++ USER_RSS__THOLD tholds[12] Thresholds (6 x 2) ++ ++Command Values ++ None defined ++ ++Reset Values ++ pollTime is 0, and sampling is disabled ++ ++Restrictions ++ Can only be issued if the AR6000 device is connected ++ ++ ++===================================================================== ++ ++Name ++ SCAN_PARAMS ++ ++Synopsis ++ The minact parameter determines the minimum active channel dwell time, within ++ which if the STA receives any beacon, it remains on that channel until the maxact ++ channel dwell time. If the STA does not receive a beacon within the minact dwell ++ time, it switches to scan the next channel. ++ ++Command ++ wmiconfig -scan -minact=<ms> --maxact=<ms> ++ ++Command Parameters ++ UINT16 maxact Channel dwell time (in ms), default = 0 ++ UINT16 minact Channel dwell time (in ms), default = 105 ++ ++Command Values ++ See channel parameters ++ ++Reset Values ++ None defined ++ ++Restrictions ++ The minact value should be greater than 0; maxact should be between 5–65535 ms ++ and greater than minact ++ ++===================================================================== ++ ++ ++Name ++ SET_ACCESS_PARAMS ++ ++Synopsis ++ Allows the host to set access parameters for the wireless network. A thorough ++ understanding of IEEE 802.11 is required to properly manipulate these parameters. ++ ++Command ++ wmiconfig eth1 --acparams --txop <limit> --cwmin <0-15> ++ --cwmax <0-15> --aifsn<0-15> ++ ++Command Parameters ++ UINT16 txop The maximum time (expressed in units of ++ 32 ms) the device can spend transmitting ++ after acquiring the right to transmit ++ UINT8 eCWmin Minimum contention window ++ UINT8 eCWmax Maximum contention window ++ UINT8 aifsn The arbitration inter-frame space number ++ ++Command Values ++ None ++ ++Reset Values ++ Reasonable defaults that vary, between endpoints (prioritized streams) ++ ++Restrictions ++ None ++ ++===================================================================== ++ ++ ++Name ++ SET_ADHOC_BSSID ++ ++Synopsis ++ Allows the host to set the BSSID for an ad hoc network. If a network with this BSSID ++ is not found, the target creates an ad hoc network with this BSSID after the connect ++ WMI command is triggered (e.g., by the SIOCSIWESSID IOCTL). ++ ++Command ++ wmiconfig eth1 --adhocbssid <bssid> ++ ++Command Parameters ++ A_UINT8 bssid[ATH_MAC_LEN] BSSID is specified in xx:xx:xx:xx:xx:xx format ++ ++Command Values ++ None ++ ++Reset Values ++ None ++ ++Restrictions ++ None ++ ++===================================================================== ++ ++ ++Name ++ SET_AKMP_PARAMS ++ ++Synopsis ++ Enables or disables multi PMKID mode. ++ ++Command ++ wmiconfig eth1 --setakmp --multipmkid=<on/off> ++ ++Command Parameters ++ typedef struct { ++ A_UINT32 akmpInfo; ++ } WMI_SET_AKMP_PARAMS_CMD; ++ ++Command Values ++ akmpInfo; ++ bit[0] = 0 ++ MultiPMKID mode is disabled and PMKIDs that ++ were set using the WMI_SET_PMKID_CMD are ++ used in the [Re]AssocRequest frame. ++ bit[0] = 1 ++ MultiPMKID mode is enabled and PMKIDs issued ++ by the WMI_SET_PMKID_LIST_CMD are used in ++ the next [Re]AssocRequest sent to the AP. ++ ++Reset Values ++ MultiPMKID mode is disabled ++ ++Restrictions ++ None ++ ++===================================================================== ++ ++ ++Name ++ SET_APPIE ++ ++Synopsis ++ Add an application-specified IE to a management frame. The maximum length is ++ 76 bytes. Including the length and the element ID, this translates to 78 bytes. ++ ++Command ++ wmiconfig --setappie <frame> <IE>, where: ++ ++ frame ++ One of beacon, probe, respon, assoc ++ ++ IE ++ A hex string beginning with DD (if = 0, no ++ IE is sent in the management frame) ++ ++Command Parameters ++ mgmtFrmType; ++ A WMI_MGMT_FRAME_TYPE ++ ++ ieLen; ++ Length of the IE to add to the GMT frame ++ ++Command Values ++ None ++ ++Reset Value ++ None defined ++ ++Restrictions ++ Supported only for the probe request and association request management frame ++types. Also, only one IE can be added per management frame type. ++ ++===================================================================== ++ ++ ++Name ++ SET_ASSOC_INFO ++ ++Synopsis ++ The host uses this command to specify any information elements (IEs) it wishes the ++ AR6000 device to add to all future association and reassociation requests. IEs must be ++ correct and are used as is by the device. IEs specified through this command are ++ cleared with a DISCONNECT. ++ ++Command ++ wmiconfig eth1 --setAssocIe <IE> ++ ++Command Parameters ++ UINT8 ieType Used directly in 802.11 frames ++ UINT8 bufferSize Size of assocInfo (in bytes) ranging from ++ 0–240. If = 0, previously set IEs are cleared. ++ UINT8 assocInfo[bufferSize] Used directly in 802.11 frames ++ ++Command Values ++ None ++ ++Reset Values ++ IEs are cleared ++ ++Restrictions ++ This command can only be issued in the DISCONNECTED state ++ ++===================================================================== ++ ++ ++Name ++ SET_AUTHMODE ++ ++Synopsis ++ Sets the 802.11 authentication mode of reconnection ++ ++Command ++ wmiconfig eth1 --setauthmode <mode> ++ ++Command Parameters ++ UINT8 mode ++ ++Command Values ++ mode = 0x00 Proceed with authentication during reconnect ++ = 0x01 Do not proceed with authentication during reconnect ++ ++Reset Values ++ Authentication ++ ++Restrictions ++ None ++ ++===================================================================== ++ ++ ++Name ++ SET_BEACON_INT ++ ++Synopsis ++ Sets the beacon interval for an ad hoc network. Beacon interval selection may have an ++ impact on power savings. To some degree, a longer interval reduces power ++ consumption but also decreases throughput. A thorough understanding of IEEE ++ 802.11 ad hoc networks is required to use this command effectively. ++ ++Command ++ wmiconfig eth1 --ibssconintv ++ ++Command Parameters ++ UINT16 beaconInterval Specifies the beacon interval in TU units (1024 ms) ++ ++Command Values ++ None ++ ++Reset Values ++ The default beacon interval is 100 TUs (102.4 ms) ++ ++Restrictions ++ This command can only be issued before the AR6000 device starts an ad hoc network ++ ++See Also ++ “SET_IBSS_PM_CAPS” ++ ++===================================================================== ++ ++ ++Name ++ SET_BIT_RATE ++ ++Synopsis ++ The host uses this command to set the AR6000 device to a specific fixed rate. ++ ++Command ++ wmiconfig eth1 --setfixrates <rate_0> ... <rate_n> ++ ++Command Parameters ++ INT8 rateIndex ++ A WMI_BIT_RATE value ++ { ++ RATE_AUTO = -1 ++ RATE_1Mb = 0 ++ RATE_2Mb = 1 ++ RATE_5_5M = 2 ++ RATE_11Mb = 3 ++ RATE_6Mb = 4 ++ RATE_9Mb = 5 ++ RATE_12Mb = 6 ++ RATE_18Mb = 7 ++ RATE_24Mb = 8 ++ RATE_36Mb = 9 ++ RATE_48Mb = 10 ++ RATE_54Mb = 11 ++ } WMI_BIT_RATE ++ ++ ++Command Values ++ See command parameters ++ ++Reset Values ++ The dynamic rate is determined by the AR6000 device ++ ++Restrictions ++ This command is intended for use only during development/debug; it is not ++intended for use in production ++ ++See Also ++ “GET_BIT_RATE” ++ ++===================================================================== ++ ++ ++Name ++ SET_BMISS_TIME ++ ++Synopsis ++ This command sets the beacon miss (BMISS) time, which the AR6000 hardware use ++ to recognize missed beacons. When an excessive number (15) of consecutive beacons ++ are missed, the AR6000 consider switching to a different BSS. The time can be ++ specified in number of beacons or in TUs. ++ ++Command(s) ++ wmiconfig eth1 --setbmissbeacons=<val> ++ wmiconfig eth1 --setbmisstime=<val> ++ ++Command Parameters ++ UINT16 bmissTime Specifies the beacon miss time ++ [1000...5000] in TUs (1024 ms) ++ UINT16 bmissbeacons Specifies the number of beacons [5...50] ++ ++Command Values ++ None ++ ++Reset Values ++ bmissTime is 1500 TUs (1536 ms) ++ ++Restrictions ++ None ++ ++===================================================================== ++ ++ ++Name ++ SET_BSS_FILTER ++ ++Synopsis ++ The host uses this to inform the AR6000 device of the types of networks about which ++ it wants to receive information from the “BSSINFO” event. As the device performs ++ either foreground or background scans, it applies the filter and sends “BSSINFO” ++ events only for the networks that pass the filter. If any of the bssFilter or the ieMask ++ filter matches, a BSS Info is sent to the host. The ieMask currently is used as a match ++ for the IEs in the beacons, probe reponses and channel switch action management ++ frame. See also “Scan and Roam” on page C-1. ++ ++ The BSS filter command has been enhanced to support IE based filtering. The IEs can ++ be specified as a bitmask through this command using this enum. ++ ++Command ++ wmiconfig eth1 –filter = <filter> --ieMask 0x<mask> ++ ++Command Parameters ++ UINT8 BssFilter ++ ++ Command Values ++ typedef struct { ++ A_UINT8 bssFilter; See WMI_BSS_FILTER ++ A_UINT32 ieMask; ++ } __ATTRIB_PACK WMI_BSS_FILTER_CMD; ++ ++ The ieMask can take this combination of values: ++ ++ enum { ++ BSS_ELEMID_CHANSWITCH = 0x01 ++ BSS_ELEMID_ATHEROS = 0x02, ++ } ++ ++Reply Value ++ None ++ ++Reset Value ++ BssFilter = NONE_BSS_FILTER (0) ++ ++Restrictions ++ None ++ ++See Also ++ “CONNECT_CMD” ++ ++===================================================================== ++ ++ ++Name ++ SET_BT_PARAMS ++ ++Synopsis ++ This command is used to set the status of a Bluetooth stream or set Bluetooth ++ coexistence register parameters. The stream may be an SCO or an A2DP stream and ++ its status can be started/stopped/suspended/resumed. ++ ++Command ++ wmiconfig –setBTparams <paramType> <params> ++ ++Command Parameters ++ struct { ++ union { ++ BT_PARAMS_SCO scoParams; ++ BT_PARAMS_A2DP a2dpParams; ++ BT_PARAMS_MISC miscParams; ++ BT_COEX_REGS regs; ++ } info; ++ A_UINT8 paramType; ++ struct { ++ A_UINT8 noSCOPkts; Number of SCO packets between consecutive PS-POLLs ++ A_UINT8 pspollTimeout; ++ A_UINT8 stompbt; ++ } BT_PARAMS_SCO; ++ struct { ++ A2DP BT stream parameters ++ A_UINT32 period; ++ A_UINT32 dutycycle; ++ A_UINT8 stompbt; ++ } BT_PARAMS_A2DP; ++ struct { ++ union { ++ WLAN_PROTECT_POLICY_TYPE protectParams; ++ A_UINT16 wlanCtrlFlags; ++ }info; ++ A_UINT8 paramType; ++ } BT_PARAMS_MISC; ++ struct { ++ BT coexistence registers values ++ A_UINT32 mode; Coexistence mode ++ A_UINT32 scoWghts; WLAN and BT weights ++ A_UINT32 a2dpWghts; ++ A_UINT32 genWghts; ++ A_UINT32 mode2; Coexistence mode2 ++ A_UINT8 setVal; ++ } BT_COEX_REGS; ++ ++Command Values ++ None defined ++ ++Reset Value ++ None ++ ++Restrictions ++ None ++ ++===================================================================== ++ ++ ++Name ++ SET_BT_STATUS ++ ++Synopsis ++ Sets the status of a Bluetooth stream. The stream may be a SCO or an A2DP stream ++ and its status can be started/stopped/suspended/resumed. ++ ++Command ++ wmiconfig –setBTstatus <streamType> <status> ++ ++Command Parameters ++ { ++ A_UINT8 streamType; Stream type ++ A_UINT8 status; Stream status ++ }WMI_SET_BT_STATUS_CMD; ++ ++Command Values ++ { ++ BT_STREAM_UNDEF = 0 ++ BT_STREAM_SCO ++ SCO stream ++ BT_STREAM_A2DP ++ A2DP stream ++ BT_STREAM_MAX ++ } BT_STREAM_TYPE; ++ ++ { ++ BT_STATUS_UNDEF = 0 ++ BT_STATUS_START ++ BT_STATUS_STOP ++ BT_STATUS_RESUME ++ BT_STATUS_SUSPEND ++ BT_STATUS_MAX ++ } BT_STREAM_STATUS; ++ ++Reset Value ++ None defined ++ ++Restrictions ++ None ++ ++===================================================================== ++ ++ ++Name ++ SET_CHANNEL_PARAMETERS ++ ++Synopsis ++ Configures various WLAN parameters related to channels, sets the wireless mode, ++ and can restrict the AR6000 device to a subset of available channels. The list of ++ available channels varies depending on the wireless mode and the regulatory ++ domain. The device never operates on a channel outside of its regulatory domain. The ++ device starts to scan the list of channels right after this command. ++ ++Command ++ wmiconfig eth1 --wmode <mode> <list> ++ ++Command Parameters ++ UINT8 phyMode See Values below. ++ UINT8 numberOfChannels ++ Number of channels in the channel array that ++ follows. If = 0, then the device uses all of the ++ channels permitted by the regulatory domain ++ and by the specified phyMode. ++ UINT16 channel[numberOfChannels] ++ Array listing the subset of channels (expressed ++ as frequencies in MHz) the host wants the ++ device to use. Any channel not permitted by ++ the specified phyMode or by the specified ++ regulatory domain is ignored by the device. ++ ++Command Values ++ phyMode = { ++ Wireless mode ++ 11a = 0x01 ++ 11g = 0x02 ++ 11ag = 0x03 ++ 11b = 0x04 ++ 11g only = 0x05 ++ } ++ ++Reset Values ++ phyMode ++ 11ag ++ 802.11a/g modules ++ 11g ++ 802.11g module ++ channels ++ Defaults to all channels permitted by the ++ current regulatory domain. ++ ++Restrictions ++ This command, if issued, should be issued soon after reset and prior to the first ++ connection. This command should only be issued in the DISCONNECTED state. ++ ++===================================================================== ++ ++ ++Name ++ SET_DISC_TIMEOUT ++ ++Synopsis ++ The host uses this command to configure the amount of time that the AR6000 should ++ spend when it attempts to reestablish a connection after losing link with its current ++ BSS. If this time limit is exceeded, the AR6000 send a “DISCONNECT” event. After ++ sending the “DISCONNECT” event the AR6000 continues to attempt to reestablish a ++ connection, but they do so at the interval corresponding to a foreground scan as ++ established by the “SET_SCAN_PARAMS” command. ++ ++ A timeout value of 0 indicates that the AR6000 will disable all autonomous roaming, ++ so that the AR6000 will not perform any scans after sending a “DISCONNECT” ++ event to the host. The state is maintained until a shutdown or host sets different ++ timeout value from 0. ++ ++Command ++ wmiconfig eth1 --disc=<timeout in seconds> ++ ++Command Parameters ++ UINT8 disconnectTimeout ++ Specifies the time limit (in seconds) after ++ which a failure to reestablish a connection ++ results in a “DISCONNECT” event ++ ++Command Values ++ None ++ ++Reset Values ++ disconnectTimeout is 10 seconds ++ ++Restrictions ++ This command can only be issued while in a DISCONNECTED state ++ ++===================================================================== ++ ++ ++Name ++ SET_FIXRATES ++ ++Synopsis ++ By default, the AR6000 device uses all PHY rates based on mode of operation. If the ++ host application requires the device to use subset of supported rates, it can set those ++ rates with this command. In 802.11g mode, the AR6000 device takes the entire ++ 802.11g basic rate set and the rates specified with this command and uses it as the ++ supported rate set. ++ ++ This rate set is advertised in the probe request and the assoc/re-assoc request as ++ supported rates. Upon successful association, the device modifies the rate set pool ++ using the: intersection of AP-supported rates with the union of the 802.11g basic rate ++ set and rates set using this command. The device picks transmission rates from this ++ pool based on a rate control algorithm. ++ ++Command ++ TBD ++ ++Command Parameters ++ A_UINT16 fixRateMask; ++ The individual bit is an index for rate table, ++ and setting the that index to 1 would set that ++ corresponding rate. E.g., fixRateMask = 9 ++ (1001) sets 1 Mbps and 11 Mbps. ++ ++Command Values ++ None ++ ++Reset Value ++ None defined ++ ++Restrictions ++ None ++ ++See Also ++ “GET_FIXRATES” ++ ++===================================================================== ++ ++ ++Name ++ SET_WHAL_PARAM ++ ++Synopsis ++ An internal AR6000 command that is used to set certain hardware parameters. The ++ description of this command is in $WORKAREA/include/halapi.h. ++ ++Command ++ TBD ++ ++Command Parameters ++ ATH_HAL_SETCABTO_CMDID ++ Sets the timeout waiting for the multicast ++ traffic after a DTIM beacon (in TUs). ++ ++Command Values ++ None ++ ++Reset Value ++ Default = 10 TUs ++ ++Restrictions ++ This command should be executed before issuing a connect command. ++ ++===================================================================== ++ ++ ++Name ++ SET_HOST_SLEEP_MODE ++ ++Synopsis ++ The host uses this command to set the host mode to asleep or awake. All packets are ++ delivered to the host when the host mode is awake. When host mode is asleep, only if ++ WoW is enabled and the incoming packet matches one of the specified WoW ++ patterns, will the packet be delivered to the host. The host will also be woken up by ++ the target for pattern-matching packets and important events. ++ ++Command ++ wmiconfig –sethostmode=<asleep/awake> ++ ++Command Parameters ++ A_BOOL awake Set the host mode to awake ++ A_BOOL asleep Set the host mode to asleep ++ ++Command Values ++ 1 = awake, 0 = asleep ++ ++Reset Value ++ None defined (default host mode is awake) ++ ++Restrictions ++ None ++ ++ ++===================================================================== ++ ++Name ++ SET_IBSS_PM_CAPS ++ ++Synopsis ++ Used to support a non-standard power management scheme for an ad hoc wireless ++ network consisting of up to eight stations (STAs) that support this form of power ++ saving (e.g., Atheros-based STAs). A thorough understanding of IEEE 802.11 ad hoc ++ networks is required to use this command effectively. ++ ++Command ++ wmiconfig eth1 --ibsspmcaps --ps=<enable/disable> ++ --aw=<ATIM Windows in ms> ++ --ttl=<Time to live in number of beacon periods> ++ --to=<timeout in ms> ++ ++Command Parameters ++ UINT8 power_saving ++ = 0 ++ The non-standard power saving scheme is ++ disabled and maximum throughput (with no ++ power saving) is obtained. ++ ++ = 1 ++ Ad hoc power saving scheme is enabled (but ++ throughput may be decreased) ++ ++ UINT16 atim_windows ++ Specifies the length (in ms) of the ad hoc traffic ++ indication message (ATIM) windows used in an ad ++ hoc network. All Atheros-based STAs that join the ++ network use this duration ATIM window. ++ ++ The duration is communicated between wireless ++ STAs through an IE in beacons and probe responses. ++ ++ The host sets atim_windows to control trade-offs ++ between power use and throughput. The value ++ chosen should be based on the beacon interval (see ++ the “SET_BEACON_INT” command) on the ++ expected number of STAs in the IBSS, and on the ++ amount of traffic and traffic patterns between STAs. ++ ++ UINT16 timeout_value ++ Specifies the timeout (in ms). The value is the same ++ for all ad hoc connections, but tracks separately for ++ each. ++ ++ Applicable only for a beacon period and used to ++ derive actual timeout values on the Tx and Rx sides. ++ On the Tx side, the value defines a window during ++ which the STA accepts the frame(s) from the host for a ++ particular connection. Until closed, the window ++ restarts with every frame received from the host. On ++ the Rx side, indicates the time until which the STA ++ continues accepting frames from a particular ++ connection. The value resets with every frame ++ received. The value can be used to determine the ++ trade off between throughput and power. ++ Default = 10 ms ++ ++ UINT8 ttl ++ Specifies the value in number of beacon periods. The ++ value is used to set a limit on the time until which a ++ frame is kept alive in the AR6001 before being ++ discarded. Default = 5 ++ ++Command Values ++ None ++ ++Reset Values ++ By default, power_saving is enabled with atim_window = 20 ms ++ ++Restrictions ++ Can only be issued before the AR6000 starts an ad hoc network ++ ++See Also ++ “SET_BEACON_INT” ++ ++===================================================================== ++ ++ ++ ++Name ++ SET_LISTEN_INT ++ ++Synopsis ++ The host uses this command to request a listen interval, which determines how often ++ the AR6000 device should wake up and listen for traffic. The listen interval can be set ++ by the TUs or by the number of beacons. The device may not be able to comply with ++ the request (e.g., if the beacon interval is greater than the requested listen interval, the ++ device sets the listen interval to the beacon interval). The actual listen interval used ++ by the device is available in the “CONNECT” event. ++ ++Command ++ wmiconfig eth1 --listen=<#of TUs, can range from 15 to 3000> ++ ++ --listenbeacons=<#of beacons, can range from 1 to 50> ++ ++Command Parameters ++ UINT16 listenInterval ++ Specifies the listen interval in Kms ++ (1024 ms), ranging from 100 to 1000 ++ ++ UINT16 listenbeacons ++ Specifies the listen interval in beacons, ++ ranging from 1 to 50 ++ ++Command Values ++ None ++ ++Reset Values ++ The device sets the listen interval equal to the beacon interval of the AP it associates ++ to. ++ ++Restrictions ++ None ++ ++===================================================================== ++ ++ ++Name ++ SET_LPREAMBLE ++ ++Synopsis ++ Overrides the short preamble capability of the AR6000 device ++ ++Command ++ TBD ++ ++Command Parameters ++ WMI_LPREAMBLE_DISABLED ++ The device is short-preamble capable ++ ++ WMI_LPREAMBLE_ENABLED ++ The device supports only the long- ++ preamble mode ++ ++Command Values ++ None ++ ++Reset Value ++ None defined ++ ++Restrictions ++ None ++ ++ ++===================================================================== ++ ++Name ++ SET_MAX_SP_LEN ++ ++Synopsis ++ Set the maximum service period; indicates the number of packets the AR6001 can ++ receive from the AP when triggered ++ ++Command ++ wmiconfig eth1 --setMaxSPLength <maxSPLen> ++ ++Command Parameters ++ UINT8 maxSPLen ++ An APSD_SP_LEN_TYPE value ++ ++Command Values ++ { ++ DELIVER_ALL_PKT = 0x0 ++ DELIVER_2_PKT = 0x1 ++ DELIVER_4_PKT = 0x2 ++ DELIVER_6_PKT = 0x3 ++ }APSD_SP_LEN_TYPE ++ ++ ++Reset Values ++ maxSPLen is DELIVER_ALL_PKT ++ ++Restrictions ++ None ++ ++===================================================================== ++ ++ ++Name ++ SET_OPT_MODE ++ ++Synopsis ++ Special feature, sets the special mode on/off ++ ++Command ++ wmiconfig eth1 --mode <mode> ++ Set the optional mode, where mode is special or off ++ ++Command Parameters ++ enum { ++ SPECIAL_OFF ++ SPECIAL_ON ++ } OPT_MODE_TYPE; ++ ++Command Values ++ ++Reset Value ++ Mode = Off ++ ++Restrictions ++ None ++ ++===================================================================== ++ ++ ++Name ++ SET_PMKID ++ ++Synopsis ++ The host uses this command to enable or disable a pairwise master key ID (PMKID) ++ in the AR6000 PMKID cache. The AR6000 clears its PMKID cache on receipt of a ++ DISCONNECT command from the host. Individual entries in the cache might be ++ deleted as the AR6000 detect new APs and decides to remove old ones. ++ ++Command ++ wmiconfig eth1 --setbsspmkid --bssid=<aabbccddeeff> ++ --bsspmkid=<pmkid> ++ ++Command Parameters ++ UINT8 bssid[6] ++ The MAC address of the AP that the ++ PMKID corresponds to (6 bytes in hex ++ format) ++ ++ UINT8 enable ++ Either PMKID_DISABLE (0) to disable ++ the PMKID or PMKID_ENABLE (1) to ++ enable it (16 bytes in hex format) ++ ++ UINT8 pmkid[16] ++ Meaningful only if enable is ++ PMKID_ENABLE, when it is the PMKID ++ that the AR6000 should use on the next ++ reassociation with the specified AP ++ ++Command Values ++ enable ++ = 0 (disable), 1 (enable) ++ PKMID enabled/disabled ++ ++Reset Values ++ None defined ++ ++Restrictions ++ Only supported in infrastructure networks ++ ++===================================================================== ++ ++ ++Name ++ SET_PMKID_LIST_CMD ++ ++Synopsis ++ Configures the list of PMKIDs on the firmware. ++ ++Command ++ wmiconfig --setpmkidlist --numpmkid=<n> --pmkid=<pmkid_1> ++ ... --pmkid=<pmkid_n> ++ ++ Where n is the number of pmkids (maximum = 8) and pmkid_i is the ith pmkid (16 ++ bytes in hex format) ++ ++Command Parameters ++ { ++ A_UINT8 pmkid[WMI_PMKID_LEN]; ++ } __ATTRIB_PACK WMI_PMKID; ++ ++ { ++ A_UINT32 numPMKID; ++ WMI_PMKID pmkidList[WMI_MAX_PMKID_CACHE]; ++ } __ATTRIB_PACK WMI_SET_PMKID_LIST_CMD; ++ ++Command Values ++ None ++ ++Reset Values ++ None ++ ++Restrictions ++ Supported only in infrastructure modes ++ ++===================================================================== ++ ++ ++Name ++ SET_POWER_MODE ++ ++Synopsis ++ The host uses this command to provide the AR6000 device with guidelines on the ++ desired trade-off between power utilization and performance. ++ ++ In normal power mode, the device enters a sleep state if they have nothing to do, ++ which conserves power but may cost performance as it can take up to 2 ms to ++ resume operation after leaving sleep state. ++ ++ In maximum performance mode, the device never enters sleep state, thus no time ++ is spent waking up, resulting in higher power consumption and better ++ performance. ++ ++Command ++ TBD ++ ++Command Parameters ++ UINT8 powerMode ++ WMI_POWER_MODE value ++ { ++ REC_POWER = 1 ++ (Recommended setting) Tries to conserve ++ power without sacrificing performance ++ MAX_PERF_POWER = 2 ++ Setting that maximizes performance at ++ the expense of power ++ ++ All other values are reserved ++ } WMI_POWER_MODE ++ ++Command Values ++ See command parameters ++ ++Reset Values ++ powerMode is REC_POWER ++ ++Restrictions ++ This command should only be issued in the DISCONNECTED state for the ++ infrastructure network. ++ ++ For a PM-disabled ad hoc network, the power mode should remain in ++ MAX_PERF_POWER. ++ ++ For a PM-enabled ad hoc network, the device can have REC_POWER or ++ MAX_PERF_POWER set, but either way it must follow the power save ad hoc ++ protocol. The host can change power modes in the CONNECTED state. ++ ++ Host changes to the PS setting when the STA is off the home channel take no effect ++ and cause a TARGET_PM_FAIL event. ++ ++===================================================================== ++ ++ ++Name ++ SET_POWER_PARAMS ++ ++Synopsis ++ The host uses this command to configure power parameters ++ ++Command ++ wmiconfig eth1 --pmparams --it=<ms> --np=<number of PS POLL> ++ --dp=<DTIM policy: ignore/normal/stick> ++ ++Command Parameters ++ UINT16 idle_period ++ Length of time (in ms) the AR6000 device ++ remains awake after frame Rx/Tx before going ++ to SLEEP state ++ ++ UINT16 pspoll_number ++ The number of PowerSavePoll (PS-poll) ++ messages the device should send before ++ notifying the AP it is awake ++ ++ UINT16 dtim_policy ++ A WMI_POWER_PARAMS_CMD value ++ ++ { ++ IGNORE_DTIM =1 ++ The device does not listen to any content after ++ beacon (CAB) traffic ++ NORMAL_DTIM = 2 ++ DTIM period follows the listen interval (e.g., if ++ the listen interval is 4 and the DTIM period is 2, ++ the device wakes up every fourth beacon) ++ STICK_DTIM = 3 ++ Device attempt to receive all CAB traffic (e.g., if ++ the DTIM period is 2 and the listen interval is 4, ++ the device wakes up every second beacon) ++ } WMI_POWER_PARAMS_CMD ++ ++Command Parameters ++ See command parameters ++ ++Reset Values ++ idle_period ++ 200 ms ++ ++ pspoll_number ++ = 1 ++ ++ dtim_policy ++ = NORMAL_DTIM ++ ++Restrictions ++ None ++ ++===================================================================== ++ ++ ++Name ++ SET_POWERSAVE_PARAMS ++ ++Synopsis ++ Set the two AR6000 power save timers (PS-POLL timer and APSD trigger timer) and ++ the two ASPD TIM policies ++ ++Command ++ wmiconfig eth1--psparams --psPollTimer=<psPollTimeout in ms> ++ --triggerTimer=<triggerTimeout in ms> --apsdTimPolicy=<ignore/ ++ adhere> --simulatedAPSDTimPolicy=<ignore/adhere> ++ ++Command Parameters ++ typedef struct { ++ A_UINT16 psPollTimeout; ++ Timeout (in ms) after sending PS-POLL; the ++ AR6000 device sleeps if it does not receive a ++ data packet from the AP ++ ++ A_UINT16 triggerTimeout; ++ Timeout (in ms) after sending a trigger; the ++ device sleeps if it does not receive any data ++ or null frame from the AP ++ ++ APSD_TIM_POLICY apsdTimPolicy; ++ TIM behavior with queue APSD enabled ++ ++ APSD_TIM_POLICY simulatedAPSD ++ ++ TimPolicy; ++ TIM behavior with simulated APSD ++ enabled ++ ++ typedef enum { ++ IGNORE_TIM_ALL_QUEUES_APSD = 0, ++ PROCESS_TIM_ALL_QUEUES_APSD = 1, ++ IGNORE_TIM_SIMULATED_APSD = 2, ++ POWERSAVE_TIMERS_POLICY = 3, ++ } APSD_TIM_POLICY; ++ ++Command Values ++ None ++ ++Reset Values ++ psPollTimeout is 50 ms; triggerTimeout is 10 ms; ++ apsdTimPolicy = IGNORE_TIM_ALL_QUEUES_APSD; ++ simulatedAPSDTimPolicy = POWERSAVE_TIMERS_POLICY ++ ++Restrictions ++ When this command is used, all parameters must be set; this command does not ++ allow setting only one parameter. ++ ++===================================================================== ++ ++ ++Name ++ SET_PROBED_SSID ++ ++Synopsis ++ The host uses this command to provide a list of up to MAX_PROBED_SSID_INDEX ++ (six) SSIDs that the AR6000 device should actively look for. It lists the active SSID ++ table. By default, the device actively looks for only the SSID specified in the ++ “CONNECT_CMD” command, and only when the regulatory domain allows active ++ probing. With this command, specified SSIDs are probed for, even if they are hidden. ++ ++Command ++ wmiconfig eth1 --ssid=<ssid> [--num=<index>] ++ ++Command Parameters ++ { ++ A_UINT8 numSsids ++ A number from 0 to ++ MAX_PROBED_SSID_INDEX indicating ++ the active SSID table entry index for this ++ command (if the specified entry index ++ already has an SSID, the SSID specified in ++ this command replaces it) ++ ++ WMI_PROBED_SSID_INFO probedSSID[1] ++ } WMI_PROBED_SSID_CMD ++ ++ { ++ A_UINT8 flag ++ WMI_SSID_FLAG indicates the current ++ entry in the active SSID table ++ A_UINT8 ssidLength ++ Length of the specified SSID in bytes. ++ If = 0, the entry corresponding to the ++ index is erased ++ A_UINT8 ssid[32] ++ SSID string actively probed for when ++ permitted by the regulatory domain ++ } WMI_PROBED_SSID_INFO ++ ++Command Values ++ WMI_SSID_FLAG ++ { ++ DISABLE_SSID_FLAG = 0 ++ Disables entry ++ SPECIFIC_SSID_FLAG = 1 ++ Probes specified SSID ++ ANY_SSID_FLAG = 2 ++ Probes for any SSID ++ } WMI_SSID_FLAG ++ ++Reset Value ++ The entries are unused. ++ ++Restrictions ++ None ++ ++===================================================================== ++ ++ ++Name ++ SET_REASSOC_MODE ++ ++Synopsis ++ Specify whether the disassociated frame should be sent or not upon reassociation. ++ ++Command ++ wmiconfig eth1 --setreassocmode <mode> ++ ++Command Parameters ++ UINT8 mode ++ ++Command Values ++ mode ++ = 0x00 ++ Send disassoc to a previously connected AP ++ upon reassociation ++ = 0x01 ++ Do not send disassoc to previously connected ++ AP upon reassociation ++ ++Reset Values ++ None defined ++ ++Restrictions ++ None ++ ++ ++===================================================================== ++ ++Name ++ SET_RETRY_LIMITS ++ ++Synopsis ++ Allows the host to influence the number of times that the AR6000 device should ++ attempt to send a frame before they give up. ++ ++Command ++ wmiconfig --setretrylimits <frameType> <trafficClass> <maxRetries> ++ <enableNotify> ++ ++Command Parameters ++ { ++ UINT8 frameType ++ A WMI_FRAMETYPE specifying ++ which type of frame is of interest. ++ UINT8 trafficClass ++ Specifies a traffic class (see ++ “CREATE_PSTREAM”). This ++ parameter is only significant when ++ frameType = DATA_FRAMETYPE. ++ UINT8 maxRetries ++ Maximum number of times the ++ device attempts to retry a frame Tx, ++ ranging from WMI_MIN_RETRIES ++ (2) to WMI_MAX_RETRIES (15). If ++ the special value 0 is used, ++ maxRetries is set to 15. ++ A_UINT8 enableNotify ++ Notify when enabled ++ } WMI_RETRY_LIMIT_INFO ++ ++ { ++ A_UINT8 numEntries ++ WMI_RETRY_LIMIT_INFO retryLimitInfo[1] ++ } WMI_SET_RETRY_LIMITS_CMD ++ ++Command Values ++ { ++ MGMT_FRAMETYPE = 0 Management frame ++ CONTROL_FRAMETYPE = 1 Control frame ++ DATA_FRAMETYPE = 2 Data frame ++ } WMI_FRAMETYPE ++ ++Reset Values ++ Retries are set to 15 ++ ++Restrictions ++ None ++ ++===================================================================== ++ ++ ++Name ++ SET_ROAM_CTRL ++ ++Synopsis ++ Affects how the AR6000 device selects a BSS. The host uses this command to set and ++ enable low RSSI scan parameters. The time period of low RSSI background scan is ++ mentioned in scan period. Low RSSI scan is triggered when the current RSSI ++ threshold (75% of current RSSI) is equal to or less than scan threshold. ++ ++ Low RSSI roam is triggered when the current RSSI threshold falls below the roam ++ threshold and roams to a better AP by the end of the scan cycle. During Low RSSI ++ roam, if the STA finds a new AP with an RSSI greater than roam RSSI to floor, during ++ scan, it roams immediately to it instead of waiting for the end of the scan cycle. See ++ also “Scan and Roam” on page C-1. ++ ++Command ++ wmiconfig --roam <roamctrl> <info>, where info is <scan period> ++ <scan threshold> <roam threshold> <roam rssi floor> ++ ++Command Parameters ++ A_UINT8 roamCtrlType; ++ ++Command Values ++ WMI_FORCE_ROAM = 1 ++ Roam to the specified BSSID ++ ++ WMI_SET_ROAM_MODE = 2 ++ Default, progd bias, no roam ++ ++ WMI_SET_HOST_BIAS = 3 ++ Set the host bias ++ ++ WMI_SET_LOWRSSI_SCAN_PARAMS = 4 ++ Info parameters ++ ++ A_UINT8 bssid[ATH_MAC_LEN]; ++ WMI_FORCE_ROAM ++ ++ A_UINT8 roamMode; ++ WMI_SET_ROAM_MODE ++ ++ A_UINT8 bssBiasInfo; ++ WMI_SET_HOST_BIAS ++ ++ A_UINT16 lowrssi_scan_period; ++ WMI_SET_LOWRSSI_SCAN_PARAMS ++ ++ A_INT16 ++ lowrssi_scan_threshold; ++ WMI_SET_LOWRSSI_SCAN_PARAMS ++ ++ A_INT16 lowrssi_roam_threshold; ++ WMI_SET_LOWRSSI_SCAN_PARAMS ++ ++ A_UINT8 roam_rssi_floor; ++ WMI_SET_LOWRSSI_SCAN_PARAMS ++ ++Reset Value ++ None defined (default lowrssi scan is disabled. Enabled only when scan period is set.) ++ ++Restrictions ++ None ++ ++===================================================================== ++ ++ ++Name ++ SET_RTS ++ ++Synopsis ++ Decides when RTS should be sent. ++ ++Command ++ wmiconfig eth1 --setRTS <pkt length threshold> ++ ++Command Parameters ++ A_UINT16 ++ threshold; ++ Command parameter threshold in bytes. An RTS is ++ sent if the data length is more than this threshold. ++ The default is to NOT send RTS. ++ ++Command Values ++ None ++ ++Reset Value ++ Not to send RTS. ++ ++Restrictions ++ None ++ ++ ++===================================================================== ++ ++Name ++ SET_SCAN_PARAMS ++ ++Synopsis ++ The host uses this command to set the AR6000 scan parameters, including the duty ++ cycle for both foreground and background scanning. Foreground scanning takes ++ place when the AR6000 device is not connected, and discovers all available wireless ++ networks to find the best BSS to join. Background scanning takes place when the ++ device is already connected to a network and scans for potential roaming candidates ++ and maintains them in order of best to worst. A second priority of background ++ scanning is to find new wireless networks. ++ ++ The device initiates a scan when necessary. For example, a foreground scan is always ++ started on receipt of a “CONNECT_CMD” command or when the device cannot find ++ a BSS to connect to. Foreground scanning is disabled by default until receipt of a ++ CONNECT command. Background scanning is enabled by default and occurs every ++ 60 seconds after the device is connected. ++ ++ The device implements a binary backoff interval for foreground scanning when it ++ enters the DISCONNECTED state after losing connectivity with an AP or when a ++ CONNECT command is received. The first interval is ForegroundScanStartPeriod, ++ which doubles after each scan until the interval reaches ForegroundScanEndPeriod. ++ If the host terminates a connection with DISCONNECT, the foreground scan period ++ is ForegroundScanEndPeriod. All scan intervals are measured from the time a full ++ scan ends to the time the next full scan starts. The host starts a scan by issuing a ++ “START_SCAN” command. See also “Scan and Roam” on page C-1. ++ ++Command ++ wmiconfig eth1 --scan --fgstart=<sec> --fgend=<sec> --bg=<sec> -- ++ act=<msec> --pas=<msec> --sr=<short scan ratio> --scanctrlflags ++ <connScan> <scanConnected> <activeScan> <reportBSSINFO> ++ ++Command Parameters ++ UINT16 fgStartPeriod ++ First interval used by the device when it ++ disconnects from an AP or receives a ++ CONNECT command, specified in seconds (0– ++ 65535). If = 0, the device uses the reset value. ++ If = 65535, the device disables foreground ++ scanning. ++ ++ UINT16 fgEndPeriod ++ The maximum interval the device waits between ++ foreground scans specified in seconds (from ++ ForegroundScanStartPeriod to 65535). If = 0, the ++ device uses the reset value. ++ ++ UINT16 bgScanPeriod ++ The period of background scan specified in ++ seconds (0–65535). By default, it is set to the reset ++ value of 60 seconds. If 0 or 65535 is specified, the ++ device disables background scanning. ++ ++ UINT16 maxactChDwellTime ++ The period of time the device stays on a ++ particular channel while active scanning. It is ++ specified in ms (10–65535). If the special value of ++ 0 is specified, the device uses the reset value. ++ ++ UINT16 PasChDwellTime ++ The period of time the device remains on a ++ particular channel while passive scanning. It is ++ specified in ms (10–65535). If the special value of ++ 0 is specified, the device uses the reset value. ++ ++ UINT8 shortScanRatio ++ Number of short scans to perform for each ++ long scan. ++ ++ UINT8 scanCtrlFlasgs ++ ++ UINT16 minactChDwellTime ++ Specified in ms ++ ++ UINT32 maxDFSchActTime ++ The maximum time a DFS channel can stay ++ active before being marked passive, specified in ++ ms. ++ ++Command Values ++ None ++ ++Reset Values ++ ForegroundScanStart ++Period ++ 1 sec ++ ++ ForegroundScanEndPeriod ++ 60 sec ++ ++ BackgroundScanPeriod ++ 60 sec ++ ++ ActiveChannelDwellTime ++ 105 ms ++ ++===================================================================== ++ ++ ++Name ++ SET_TKIP_COUNTERMEASURES ++ ++Synopsis ++ The host issues this command to tell the target whether to enable or disable TKIP ++ countermeasures. ++ ++Command ++ TBD ++ ++Command Parameters ++ UINT8 WMI_TKIP_CM_ENABLE ++ Enables the countermeasures ++ ++ ++ UINT8 TKIP_CM_DISABLE ++ Disables the countermeasures ++ ++Command Values ++ None ++ ++Reset Values ++ By default, TKIP MIC reporting is disabled ++ ++Restrictions ++ None ++ ++===================================================================== ++ ++ ++Name ++ SET_TX_PWR ++ ++Synopsis ++ The host uses this command to specify the Tx power level of the AR6000. Cannot be ++ used to exceed the power limit permitted by the regulatory domain. The maximum ++ output power is limited in the chip to 31.5 dBm; the range is 0 – 31.5 dbm. ++ ++Command ++ wmiconfig --power <dbM> ++ ++Command Parameters ++ UINT8 dbM ++ The desired Tx power specified in dbM. ++ If = 0, the device chooses the maximum ++ permitted by the regulatory domain. ++ ++Command Values ++ None ++ ++Reset Values ++ The maximum permitted by the regulatory domain ++ ++Restrictions ++ None ++ ++See Also ++ “GET_TX_PWR” ++ ++ ++===================================================================== ++ ++Name ++ SET_VOICE_PKT_SIZE ++ ++Synopsis ++ If an AP does not support WMM, it has no way to differentiate voice from data. ++ Because the voice packet is typically small, packet in size less than voicePktSize are ++ assumed to be voice, otherwise it is treated as data. ++ ++Command ++ wmiconfig eth1 --setVoicePktSize <size-in-bytes> ++ ++Command Parameters ++ UINT16 voicePktSize ++ Packet size in octets ++ ++Command Values ++ None ++ ++Reset Values ++ voicePktSize default is 400 bytes ++ ++Restrictions ++ No effect if WMM is unavailable ++ ++ ++===================================================================== ++ ++Name ++ SET_WMM ++ ++Synopsis ++ Overrides the AR6000 device WMM capability ++ ++Command ++ wmiconfig eth1 --setwmm <enable> ++ ++Command Parameters ++ WMI_WMM_ENABLED ++ Enables WMM ++ ++ WMI_WMM_DISABLED ++ Disables WMM support ++ ++Command Values ++ 0 = disabled ++ 1 = enabled ++ ++Reset Value ++ WMM Disabled ++ ++Restrictions ++ None ++ ++ ++===================================================================== ++ ++Name ++ SET_WMM_TXOP ++ ++Synopsis ++ Configures TxOP Bursting when sending traffic to a WMM capable AP ++ ++Command ++ wmiconfig eth1 --txopbursting <burstEnable> ++ ++ <burstEnable> ++ = 0 ++ Disallow TxOp bursting ++ ++ = 1 ++ Allow TxOp bursting ++ ++Command Parameters ++ txopEnable ++ = WMI_TXOP_DISABLED ++ Disabled ++ ++ = WMI_TXOP_ENABLED ++ Enabled ++ ++Command Values ++ txopEnable ++ = 0 Disabled ++ ++ = 1 Enabled ++ ++Reset Value ++ Bursting is off by default ++ ++Restrictions ++ None ++ ++===================================================================== ++ ++ ++Name ++ SET_WOW_MODE ++ ++Synopsis ++ The host uses this command to enable or disable the WoW mode. When WoW mode ++ is enabled and the host is asleep, pattern matching takes place at the target level. ++ Only packets that match any of the pre-specified WoW filter patterns, will be passed ++ up to the host. The host will also be woken up by the target. Packets which do not ++ match any of the WoW patterns are discarded. ++ ++Command ++ wmiconfig –setwowmode <enable/disable> ++ ++Command Parameters ++ A_BOOL enable_wow ++ Enable or disable WoW: ++ ++Command Values ++ = 0 ++ Disable WoW ++ ++ = 1 ++ Enable WoW ++ ++Reset Value ++ None defined (default WoW mode is disabled). ++ ++Restrictions ++ None ++ ++See Also ++ “GET_WOW_LIST” ++ ++ ++===================================================================== ++ ++Name ++ SET_WSC_STATUS ++ ++Synopsis ++ The supplicant uses this command to inform the target about the status of the WSC ++ registration protocol. During the WSC registration protocol, a flag is set so the target ++ bypasses some of the checks in the CSERV module. At the end of the registration, this ++ flag is reset. ++ ++Command ++ N/A ++ ++Command Parameters ++ A_BOOL status ++ = 1 WSC registration in progress ++ = 0 WSC protocol not running ++ ++Reply Parameters ++ None ++ ++Reset Value ++ None defined (default = 0) ++ ++Restrictions ++ None ++ ++ ++===================================================================== ++ ++Name ++ SNR_THRESHOLD_PARAMS ++ ++Synopsis ++ Configures how the AR6000 device monitors and reports SNR of the connected BSS, ++ used as a link quality metric. ++ ++Command ++ --snrThreshold <weight> <upper_threshold_1> ... ++ <upper_threshold_4> <lower_threshold_1> ... <lower_threshold_4> ++ <pollTimer> ++ ++Command Parameters ++ <weight> ++ Share with rssiThreshold. Range in [1, 16], used ++ in the formula to calculate average RSSI ++ ++ <upper_threshold_x> ++ Above thresholds expressed in db, in ascending ++ order ++ ++ <lower_threshold_x> ++ Below thresholds expressed in db, in ascending ++ order ++ ++ <pollTimer> ++ The signal strength sampling frequency in ++ seconds. If polltime = 0, signal strength ++ sampling is disabled ++ ++Command Values ++ None ++ ++Reset Value ++ None defined ++ ++Restrictions ++ None ++ ++===================================================================== ++ ++ ++Name ++ START_SCAN ++ ++Synopsis ++ The host uses this command to start a long or short channel scan. All future scans are ++ relative to the time the AR6000 device processes this command. The device performs ++ a channel scan on receipt of this command, even if a scan was already in progress. ++ The host uses this command when it wishes to refresh its cached database of wireless ++ networks. The isLegacy field will be removed (0 for now) because it is achieved by ++ setting CONNECT_PROFILE_MATCH_DONE in the CONNECT command. See also ++ “Scan and Roam” ++ ++Command ++ wmiconfig eth1 --startscan <scan type> <forcefgscan> 0 ++ <homeDwellTime> <forceScanInterval> ++ ++Command Parameters ++ UINT8 scanType ++ WMI_SCAN_TYPE ++ ++Command Values ++ { ++ WMI_LONG_SCAN =0x0 ++ Requests a full scan ++ WMI_SHORT_SCAN =0x1 ++ Requests a short scan ++ } WMI_SCAN_TYPE ++ ++ A_BOOL forceFgScan ++ forceFgScan ++ = 0 ++ Disable the foreground scan ++ ++ forceFgScan ++ = 1 ++ Forces a foreground scan ++ ++ A_UINT32 homeDwellTime ++ Maximum duration in the home ++ channel (in ms) ++ ++ A_UINT32 forceScanInterval ++ Time interval between scans (in ms) ++ ++ A_UINT32 scanType ++ WMI_SCAN_TYPE ++ ++Reset Value ++ Disable forcing foreground scan ++ ++Restrictions ++ isLegacy field will no longer be supported (pass as 0 for now) ++ ++ ++===================================================================== ++ ++Name ++ SYNCHRONIZE ++ ++Synopsis ++ The host uses this command to force a synchronization point between the command ++ and data paths ++ ++Command ++ TBD ++ ++Command Parameters ++ None ++ ++ ++ ++Command Values ++ None ++ ++ ++ ++Reset Values ++ None ++ ++ ++ ++Restrictions ++ None ++ ++ ++===================================================================== ++ ++Name ++ TARGET_ERROR_REPORT_BITMASK ++ ++Synopsis ++ Allows the host to control “ERROR_REPORT” events from the AR6000 device. ++ ++ If error reporting is disabled for an error type, a count of errors of that type is ++ maintained by the device. ++ ++ If error reporting is enabled for an error type, an “ERROR_REPORT” event is ++ sent when an error occurs and the error report bit is cleared. ++ ++ Error counts for each error type are available through the “GET_TARGET_STATS” ++ command. ++ ++Command ++ wmiconfig eth1 --setErrorReportingBitmask ++ ++Command Parameters ++ UINT32 bitmask ++ Represents the set of ++ WMI_TARGET_ERROR_VAL error types ++ enabled for reporting ++ ++Command Values ++ { ++ WMI_TARGET_PM_ERR_FAIL = 0x00000001 ++ Power save fails (only two cases): ++ Retry out of null function/QoS null ++ function to associated AP for PS ++ indication' ++ Host changes the PS setting when ++ STA is off home channel ++ ++ WMI_TARGET_KEY_NOT_FOUND = 0x00000002 ++ No cipher key ++ WMI_TARGET_DECRYPTION_ERR = 0x00000004 ++ Decryption error ++ WMI_TARGET_BMISS = 0x00000008 ++ Beacon miss ++ WMI_PSDISABLE_NODE_JOIN = 0x00000010 ++ A non-PS-enabled STA joined the ++ PS-enabled network ++ WMI_TARGET_COM_ERR = 0x00000020 ++ Host/target communication error ++ WMI_TARGET_FATAL_ERR = 0x00000040 ++ Fatal error ++ } WMI_TARGET_ERROR_VAL ++ ++Reset Values ++ Bitmask is 0, and all error reporting is disabled ++ ++Restrictions ++ None ++ ++ ++===================================================================== ++WMI Events ++ ++Event ++ Description ++ Page ++ ++ ++BSSINFO ++ Contains information describing BSSs collected during a scan ++ ++CAC_EVENTID ++ Indicates signalling events in admission control ++ ++CMDERROR ++ The AR6000 device encounters an error while attempting to process ++ a command ++ ++CONNECT ++ The device has connected to a wireless network ++ ++DISCONNECT ++ The device lost connectivity with a wireless network ++ ++ERROR_REPORT ++ An error has occurred for which the host previously requested ++ notification with the command ++ “TARGET_ERROR_REPORT_BITMASK” ++ ++EXTENSION ++ WMI extension event ++ ++GET_PMKID_LIST_EVENT ++ Created in response to a “GET_PMKID_LIST_CMD” command ++ ++GET_WOW_LIST_EVENT ++ Response to the wmiconfig “GET_WOW_LIST” command to ++ retrieve the configured WoW patterns ++ ++NEIGHBOR_REPORT ++ Neighbor APs that match the current profile were detected ++ ++OPT_RX_FRAME_EVENT ++ (Special feature) informs the host of the reception of a special frame ++ ++PSTREAM_TIMEOUT ++ A prioritized stream has been idle for a specified interval ++ ++READY ++ The AR6000 device is ready to accept commands ++ ++REGDOMAIN ++ The regulatory domain has changed ++ ++REPORT_ROAM_DATA_EVENT ++ Reports the roam time calculations made by the device ++ (generated with a special build) ++ — ++ ++REPORT_STATISTICS ++ Reply to a “GET_TARGET_STATS” command ++ ++ROAM_TBL_EVENT ++ Reports the roam table ++ ++RSSI_THRESHOLD ++ Signal strength from the connected AP has crossed the threshold ++ defined in the “RSSI_THRESHOLD_PARAMS” command ++ ++SCAN_COMPLETE_EVENT ++ A scan has completed (added status SCAN_ABORTED in release 2.0) ++ ++TEST_EVENT ++ Event generated by the TCMD ++ ++TKIP_MICERROR ++ TKIP MIC errors were detected ++ ++===================================================================== ++ ++Name ++ BSSINFO ++ ++Synopsis ++ Contains information describing one or more BSSs as collected during a scan. ++ Information includes the BSSID, SSID, RSSI, network type, channel, supported rates, ++ and IEs. BSSINFO events are sent only after the device receives a beacon or probe- ++ response frame that pass the filter specified in the “SET_BSS_FILTER” command. ++ BSSINFO events consist of a small header followed by a copy of the beacon or probe ++ response frame. The 802.11 header is not present. For formats of beacon and probe- ++ response frames please consult the IEEE 802.11 specification. ++ ++ The beacons or probe responses containing the IE specified by the ++ WMI_BSS_FILTER_CMD are passed to the host through the ++ WMI_BSSINFO_EVENT. The event carries a 32-bit bitmask that indicates the IEs that ++ were detected in the management frame. The frame type field has been extended to ++ indicate action management frames. This would be helpful to route these frames ++ through the same event mechanism as used by the beacon processing function. ++ ++ If the bssFilter in the SET_BSS_FILTER matches, then the ieMask is not relevant ++ because the BSSINFO event is sent to the host. If the bssFilter doesnot match in the ++ beacons/probe respones, then the ieMask match dictates whether the BSSINFO ++ event is sent to the host. In the case of action management frames, the ieMask is the ++ filter that is applied. ++ ++Event ID ++ 0x1004 ++ ++Event Parameters ++ typedef struct { ++ A_UINT16 channel; ++ Specifies the frequency (in MHz) where the ++ frame was received ++ A_UINT8 frameType; ++ A WMI_BI_FTYPE value ++ A_UINT8 snr; ++ A_INT16 rssi; ++ Indicates signal strength ++ A_UINT8 bssid[ATH_MAC_LEN]; ++ A_UINT32 ieMask; ++ } _ATTRIB_PACK_WMI_BSS_INFO_HDR; ++ ++ Beacon or Probe Response Frame ++ ++Event Values ++ { ++ BEACON_FTYPE = 0x1 ++ Indicates a beacon frame ++ PROBERESP_FTYPE ++ Indicates a probe response frame ++ ACTION_MGMT_FTYPE ++ } WMI_BI_FTYPE ++ ++===================================================================== ++ ++Name ++ CAC_EVENTID ++ ++Synopsis ++ Indicates signalling events in admission control. Events are generated when ++ admission is accepted, rejected, or deleted by either the host or the AP. If the AP does ++ not respond to an admission request within a timeout of 500 ms, an event is ++ generated to the host. ++ ++Event ID ++ 0x1011 ++ ++Event Parameters ++ UINT8 ++ ac ++ Access class pertaining to the ++signalling ++ ++ UINT8 cac_indication ++ Type of indication; indications are ++ listed in WMI_CAC_INDICATION ++ ++ UINT8 statusCode ++ AP response status code for a ++ request ++ ++ UINT8 tspecSuggestion[63] ++ Suggested TSPEC from AP ++ ++Event Values ++ { ++ CAC_INDICATION_ADMISSION = 0x00 ++ CAC_INDICATION_ADMISSION_RESP = 0x01 ++ CAC_INDICATION_DELETE = 0x02 ++ CAC_INDICATION_NO_RESP = 0x03 ++ } WMI_CAC_INDICATION ++ ++ ++===================================================================== ++ ++ ++Name ++ CMDERROR ++ ++Synopsis ++ Indicates that the AR6000 device encountered an error while attempting to process a ++ command. This error is fatal and indicates that the device requires a reset. ++ ++Event ID ++ 0x1005 ++ ++Event Parameters ++ UINT16 commandId ++ Corresponds to the command which generated ++ the error ++ UINT8 errorCode ++ A WMI_ERROR_CODE value ++ ++Event Values ++ { ++ INVALID_PARAM = 1 ++ Invalid parameter ++ ILLEGAL_STATE = 2 ++ Illegal state ++ INTERNAL_ERROR = 3 ++ Internal Error ++ All other values reserved ++ } WMI_ERROR_CODE ++ ++ ++===================================================================== ++ ++ ++Name ++ CONNECT ++ ++Synopsis ++ Signals that the AR6000 connected to a wireless network. Connection occurs due to a ++ “CONNECT” command or roaming to a new AP. For infrastructure networks, shows ++ that the AR6000 successfully performed 802.11 authentication and AP association. ++ ++Event ID ++ 0x1002 ++ ++Event Parameters ++ UINT16 channel ++ Channel frequency (in MHz) of the network the ++ AR6000 are connected to ++ ++ UINT8 bssid[6] ++ MAC address of the AP the AR6000 are ++ connected to or the BSSID of the ad hoc ++ network ++ ++ UINT16 listenInterval ++ Listen interval (in Kms) that the AR6000 are ++ using ++ ++ UINT 8 beaconIeLen ++ Length (in bytes) of the beacon IEs ++ ++ UINT8 assocInfo ++ Pointer to an array containing beacon IEs, ++ followed first by association request IEs then by ++ association response IEs ++ ++ UINT8 assocReqLen ++ Length (in bytes) of the assocReqIEs array ++ ++ UINT8 assocRespLen ++ Length (in bytes) of the assocRespIEs array ++ ++Event Values ++ None defined ++ ++===================================================================== ++ ++ ++Name ++ DISCONNECT ++ ++Synopsis ++ Signals that the AR6000 device lost connectivity with the wireless network. ++ DISCONENCT is generated when the device fails to complete a “CONNECT” ++ command or as a result of a transition from a connected state to disconnected state. ++ ++ After sending the “DISCONNECT” event the device continually tries to re-establish ++ a connection. A LOST_LINK occurs when STA cannot receive beacons within the ++ specified time for the SET_BMISS_TIME command. ++ ++Event ID ++ 0x1003 ++ ++Event Parameters ++ UINT8 disconnect ++ Reason ++ A WMI_DISCONNECT_REASON value ++ ++ UINT8 bssid[6] ++ Indicates which BSS the device was connected to ++ ++ UINT8 assocRespLen ++ Length of the 802.11 association response frame ++ that triggered this event, or 0 if not applicable ++ ++ UINT8 assocInfo[assocRespLen] ++ Copy of the 802.11 association response frame ++ ++Event Values ++ { ++ NO_NETWORK_AVAIL =0x01 ++ Indicates that the device was unable to ++ establish or find the desired network ++ LOST_LINK =0x02 ++ Indicates the devices is no longer receiving ++ beacons from the BSS it was previously ++ connected to ++ ++ DISCONNECT_CMD =0x03 ++ Indicates a “DISCONNECT” command was ++ processed ++ BSS_DISCONNECTED =0x04 ++ Indicates the BSS explicitly disconnected the ++ device. Possible mechanisms include the AP ++ sending 802.11 management frames ++ (e.g., disassociate or deauthentication ++ messages). ++ AUTH_FAILED =0x05 ++ Indicates that the device failed 802.11 ++ authentication with the BSS ++ ASSOC_FAILED =0x06 ++ Indicates that the device failed 802.11 ++ association with the BSS ++ NO_RESOURCES_AVAIL =0x07 ++ Indicates that a connection failed because the ++ AP had insufficient resources to complete the ++ connection ++ CSERV_DISCONNECT =0x08 ++ Indicates that the device’s connection services ++ module decided to disconnect from a BSS, ++ which can happen for a variety of reasons (e.g., ++ the host marks the current connected AP as a ++ bad AP). ++ INVALID_PROFILE =0x0A ++ Indicates that an attempt was made to ++ reconnect to a BSS that no longer matches the ++ current profile ++ All other values are reserved ++ } WMI_DISCONNECT_REASON ++ ++ ++===================================================================== ++ ++ ++Name ++ ERROR_REPORT ++ ++Synopsis ++ Signals that a type of error has occurred for which the host previously requested ++ notification through the “TARGET_ERROR_REPORT_BITMASK” command. ++ ++Event ID ++ 0x100D ++ ++Event Parameters ++ UINT32 errorVal ++ WMI_TARGET_ERROR_VAL value. See ++ “TARGET_ERROR_REPORT_BITMASK”. ++ ++Event Values ++ errorVal ++ = 0x00000001 ++ Power save fails ++ ++ = 0x00000002 ++ No cipher key ++ ++ = 0x00000004 ++ Decryption error ++ ++ = 0x00000008 ++ Beacon miss ++ ++ = 0x00000010 ++ A non-power save disabled node has joined ++ the PS-enabled network ++ ++ ++===================================================================== ++ ++ ++Name ++ EXTENSION ++ ++Synopsis ++ The WMI is used mostly for wireless control messages to a wireless module that ++ apply to wireless module management regardless of the target platform ++ implementation. However, some events peripherally related to wireless management ++ are desired during operation. These wireless extension events may be platform- ++ specific or implementation-dependent. See “WMI Extension Commands” ++ ++ ++Event ID ++ 0x1010 ++ ++ ++===================================================================== ++ ++ ++Name ++ GET_PMKID_LIST_EVENT ++ ++Synopsis ++ Generated by firmware in response to a “GET_PMKID_LIST_CMD” command. ++ ++Event Parameters ++ typedef struct { ++ A_UINT32 numPMKID; ++ Contains the number of PMKIDs in the reply ++ WMI_PMKID pmkidList[1]; ++ } __ATTRIB_PACK WMI_PMKID_LIST_REPLY; ++ ++Event Values ++ None ++ ++ ++===================================================================== ++ ++ ++Name ++ GET_WOW_LIST_EVENT ++ ++Synopsis ++ Response to the wmiconfig –getwowlist command to retrieve the configured Wake on ++ Wireless patterns ++ ++Event ID ++ 0x10018 ++ ++Event Parameters ++ { ++ ++ A_UINT8 num_filters ++ Total number of patterns in the list ++ A_UINT8 this_filter_num ++ The filter number ++ A_UINT8 wow_mode ++ Shows whether WoW is enabled or disabled ++ A_UINT8 host_mode ++ Shows whether the host is asleep or awake ++ WOW_FILTER wow_filters[1] ++ List of WoW filters (pattern and mask data bytes) ++ } WMI_GET_WOW_LIST_REPLY; ++ ++ { ++ Each wow_filter_list element shows: ++ A_UINT8 wow_valid_filter ++ Whether the filter is valid ++ A_UINT8 wow_filter_list_id ++ Filter List ID (23 = default) ++ A_UINT8 wow_filter_size ++ Size in bytes of the filter ++ A_UINT8 wow_filter_offset ++ Offset of the pattern to search in the data packet ++ A_UINT8 wow_filter_mask[MASK_SIZE] ++ The mask to be applied to the pattern ++ A_UINT8 wow_filter_pattern[WOW_PATTERN_SIZE] ++ The pattern that to match to wake up the host ++ } WOW_FILTER ++ ++Event Values ++ None ++ ++===================================================================== ++ ++ ++ ++Name ++ NEIGHBOR_REPORT ++ ++Synopsis ++ Indicates the existence of neighbor APs that match the current profile. The host uses ++ this event to populate the PMKID cache on the AR6000 and/or to perform ++ preauthentication. This event is only generated in infrastructure mode. ++ ++ A total of numberOfAps pairs of bssid/bssFlags exist, one pair for each AP. ++ ++Event ID ++ 0x1008 ++ ++Event Parameters ++ UINT8 numberOfAps ++ The number of APs reported about in ++ this event ++ { ++ UINT8 bssid[6] ++ MAC address of a neighbor AP ++ UINT8 bssFlags ++ A WMI_BSS_FLAGS value ++ }[numberOfAps] ++ ++ ++Event Values ++ { ++ WMI_DEFAULT_BSS_FLAGS = 0 ++ Logical OR of 1 or more ++ WMI_BSS_FLAGS ++ WMI_PREAUTH_CAPABLE_BSS ++ = 1 ++ Indicates that this AP is capable of ++ preauthentication ++ WMI_PMKID_VALID_BSS ++ = 2 ++ Indicates that the AR6000 have a ++ valid pairwise master key for this AP ++ } WMI_BSS_FLAGS ++ ++ ++===================================================================== ++ ++ ++ ++Name ++ OPT_RX_FRAME_EVENT ++ ++Synopsis ++ Special feature, informs host of the reception of a special frame. ++ ++Event ID ++ 0x100E ++ ++Event Parameters ++ { ++ A_UINT16 channel; ++ A_UINT8 frameType; ++ A_INT8 snr; ++ A_UINT8 srcAddr[ATH_MAC_LEN]; ++ A_UINT8 bssid[ATH_MAC_LEN]; ++ }WMI_OPT_RX_INFO_HDR ++ ++Event Values ++ None ++ ++===================================================================== ++ ++ ++ ++Name ++ PSTREAM_TIMEOUT ++ ++Synopsis ++ Indicates that a priority stream that got created as a result of priority-marked data ++ flow (priority marked in IP TOS) being idle for the default inactivity interval period ++ (specified in the “CREATE_PSTREAM” command) used for priority streams created ++ implicitly by the driver. This event is not indicated for user-created priority streams. ++ User-created priority streams exist until the users delete them explicitly. They do not ++ timeout due to data inactivity. ++ ++Event ID ++ 0x1007 ++ ++Event Parameters ++ A_UINT8 ++ trafficClass ++ Indicated the traffic class of priority ++ stream that timed out ++ ++Event Values ++ { ++ WMM_AC_BE = 0 ++ Best effort ++ WMM_AC_BK = 1 ++ Background ++ WMM_AC_VI = 2 ++ Video ++ WMM_AC_VO = 3 ++ Voice ++ } TRAFFIC CLASS ++ ++ ++===================================================================== ++ ++Name ++ READY ++ ++Synopsis ++ Indicates that the AR6000 device is prepared to accept commands. It is sent once after ++ power on or reset. It also indicates the MAC address of the device. ++ ++Event ID ++ 0x1001 ++ ++Event Parameters ++ UINT8 macAddr[6] ++ Device MAC address ++ UINT8 phyCapability ++ A WMI_PHY_CAPABILITY value. Indicates the ++ capabilities of the device wireless module’s radio ++ ++Event Values ++ { ++ WMI_11A_CAPABILITY = 1 ++ WMI_11G_CAPABILITY = 2 ++ WMI_11AG_CAPABILITY = 3 ++ } WMI_PHY_CAPABILITY ++ ++ ++===================================================================== ++ ++Name ++ REGDOMAIN ++ ++Synopsis ++ Indicates that the regulatory domain has changed. It initially occurs when the ++ AR6000 device reads the board data information. The regulatory domain can also ++ change when the device is a world-mode SKU. In this case, the regulatory domain is ++ based on the country advertised by APs per the IEEE 802.11d specification. A ++ potential side effect of a regulatory domain change is a change in the list of available ++ channels. Any channel restrictions that exist as a result of a previous ++ “SET_CHANNEL_PARAMETERS” command are lifted. ++ ++Event ID ++ 0x1006 ++ ++Event Parameters ++ UINT32 regDomain ++ The range of 0x0000 – 0x00FF ++ corresponds to an ISO country code. ++ ++ Other regCodes are reserved for world ++ mode settings and specific regulatory ++ domains. ++ ++Event Values ++ None ++ ++ ++===================================================================== ++ ++ ++ ++Name ++ REPORT_STATISTICS ++ ++Synopsis ++ A reply to a “GET_TARGET_STATS” command. ++ ++Event ID ++ 0x100B ++ ++Event Parameters ++ When the statistics are sent to the host, the AR6001 clear them so that a new set of ++ statistics are collected for the next report. ++ ++ UINT32 tx_packets ++ UINT32 tx_bytes ++ UINT32 tx_unicast_pkts ++ UINT32 tx_unicast_bytes ++ UINT32 tx_multicast_pkts ++ UINT32 tx_multicast_bytes ++ UINT32 tx_broadcast_pkts ++ UINT32 tx_broadcast_bytes ++ UINT32 tx_rts_success_cnt ++ UINT32 tx_packet_per_ac[4] ++ Tx packets per AC: [0] = BE, [1] = BK, ++ [2] = VI, [3] = VO ++ UINT32 tx_errors ++ Number of packets which failed Tx, due ++ to all failures ++ ... REPORT_STATISTICS, continued ++ UINT32 tx_failed_cnt ++ Number of data packets that failed Tx ++ UINT32 tx_retry_cnt ++ Number of Tx retries for all packets ++ UINT32 tx_rts_fail_cnt ++ Number of RTS Tx failed count ++ UINT32 rx_packets ++ UINT32 rx_bytes ++ UINT32 rx_unicast_pkts ++ UINT32 rx_unicast_bytes ++ UINT32 rx_multicast_pkts ++ UINT32 rx_multicast_bytes ++ UINT32 rx_broadcast_pkts ++ UINT32 rx_broadcast_bytes ++ UINT32 rx_fragment_pkt ++ Number of fragmented packets received ++ UINT32 rx_errors ++ Number of Rx errors due to all failures ++ UINT32 rx_crcerr ++ Number of Rx errors due to CRC errors ++ UINT32 rx_key_cache_miss ++ Number of Rx errors due to a key not ++ being plumbed ++ UINT32 rx_decrypt_err ++ Number of Rx errors due to decryption ++ failure ++ UINT32 rx_duplicate_frames ++ Number of duplicate frames received ++ UINT32 tkip_local_mic_failure ++ Number of TKIP MIC errors detected ++ UINT32 tkip_counter_measures_invoked ++ Number of times TKIP countermeasures ++ were invoked ++ UINT32 tkip_replays ++ Number of frames that replayed a TKIP ++ encrypted frame received earlier ++ UINT32 tkip_format_errors ++ Number of frames that did not conform ++ to the TKIP frame format ++ UINT32 ccmp_format_errors ++ Number of frames that did not conform ++ to the CCMP frame format ++ UINT32 ccmp_replays ++ Number of frames that replayed a CCMP ++ encrypted frame received earlier ++ UINT32 power_save_failure_cnt ++ Number of failures that occurred when ++ the AR6001 could not go to sleep ++ UINT32 cs_bmiss_cnt ++ Number of BMISS interrupts since ++ connection ++ UINT32 cs_lowRssi_cnt ++ Number of the times the RSSI went below ++ the low RSSI threshold ++ UINT16 cs_connect_cnt ++ Number of connection times ++ UINT16 cs_disconnect_cnt ++ Number of disconnection times ++ UINT8 cs_aveBeacon_rssi ++ The current averaged value of the RSSI ++ from the beacons of the connected BSS ++ UINT8 cs_lastRoam_msec ++ Time that the last roaming took, in ms. ++ This time is the difference between ++ roaming start and actual connection. ++ ++Event Values ++ None defined ++ ++ ++===================================================================== ++ ++Name ++ ROAM_TBL_EVENT ++ ++Synopsis ++ Reports the roam table, which contains the current roam mode and this information ++ for every BSS: ++ ++Event ID ++ 0x100F ++ ++Event Parameters ++ A_UINT8 bssid[ATH_MAC_LEN]; ++ BSSID ++ A_UINT8 rssi ++ Averaged RSSI ++ A_UINT8 rssidt ++ Change in RSSI ++ A_UINT8 last_rssi ++ Last recorded RSSI ++ A_UINT8 roam_util ++ Utility value used in roaming decision ++ A_UINT8 util ++ Base utility with the BSS ++ A_UINT8 bias ++ Host configured for this BSS ++ ++Event Values ++ roamMode ++ Current roam mode ++ ++ = 1 ++ RSSI based roam ++ ++ = 2 ++ Host bias-based roam ++ ++ = 3 ++ Lock to the current BSS ++ ++ = 4 ++ Autonomous roaming disabled ++ ++ ++===================================================================== ++ ++Name ++ RSSI_THRESHOLD ++ ++Synopsis ++ Alerts the host that the signal strength from the connected AP has crossed a ++ interesting threshold as defined in a previous “RSSI_THRESHOLD_PARAMS” ++ command. ++ ++Event ID ++ 0x100C ++ ++Event Parameters ++ UINT8 range ++ A WMI_RSSI_THRESHOLD_VAL ++ value, which indicates the range of ++ the average signal strength ++ ++Event Values ++ { ++ WMI_RSSI_LOWTHRESHOLD_BELOW_LOWERVAL = 1 ++ WMI_RSSI_LOWTHRESHOLD_LOWERVAL = 2 ++ WMI_RSSI_LOWTHRESHOLD_UPPERVAL = 3 ++ WMI_RSSI_HIGHTHRESHOLD_LOWERVAL = 4 ++ WMI_RSSI_HIGHTHRESHOLD_HIGHERVAL = 5 ++ } WMI_RSSI_THRESHOLD_VAL ++ ++ ++===================================================================== ++ ++Name ++ SCAN_COMPLETE_EVENT ++ ++Synopsis ++ Indicates the scan status. if the Scan was not completed, this event is generated with ++ the status A_ECANCELED. ++ ++Event ID ++ 0x100A ++ ++Event Parameters ++ A_UINT8 scanStatus ++ ++Event Values ++ { ++ #define SCAN_ABORTED 16 ++ #define SCAN_COMPLETED 0 ++ A_UINT8 scanStatus ++ A_OK or A_ECANCELED ++ } WMI_SCAN_COMPLETE_EVENT; ++ ++ ++===================================================================== ++ ++Name ++ TEST_EVENT ++ ++Synopsis ++ The TCMD application uses a single WMI event (WMI_TEST_EVENTID) to ++ communicate events from target to host. The events are parsed by the TCMD ++ application and WMI layer is oblivious of it. ++ ++Event ID ++ 0x1016 ++ ++Event Parameters ++ WMI_TEST_EVENTID ++ ++ ++Event Values ++ None ++ ++ ++===================================================================== ++ ++ ++ ++Name ++ TKIP_MICERR ++ ++Synopsis ++ Indicates that TKIP MIC errors were detected. ++ ++Event ID ++ 0x1009 ++ ++Event Parameters ++ UINT8 keyid ++ Indicates the TKIP key ID ++ ++ UINT8 ismcast ++ 0 = Unicast ++ 1 = Multicast ++ ++Event Values ++ See event parameters ++ ++===================================================================== ++ ++WMI Extension Commands ++ ++The WMI EXTENSION command is used to multiplex a collection of ++commands that: ++ ++ Are not generic wireless commands ++ May be implementation-specific ++ May be target platform-specific ++ May be optional for a host implementation ++ ++ An extension command is sent to the AR6000 targets like any other WMI ++command message and uses the WMI_EXTENSION. The first field of the ++payload for this EXTENSION command is another commandId, sometimes ++called the subcommandId, which indicates which extension command is ++being used. A subcommandId-specific payload follows the subcommandId. ++ ++All extensions (subcommandIds) are listed in the header file include/wmix.h. ++See also “WMI Extension Events” on page B-58. ++ ++ ++WMI Extension Commands ++ ++ ++GPIO_INPUT_GET ++ Read GPIO pins configured for input ++ ++GPIO_INTR_ACK ++ Acknowledge and re-arm GPIO interrupts reported earlier ++ ++GPIO_OUTPUT_SET ++ Manage output on GPIO pins configured for output ++ ++GPIO_REGISTER_GET ++ Read an arbitrary GPIO register ++ ++GPIO_REGISTER_SET ++ Dynamically change GPIO configuration ++ ++SET_LQTHRESHOLD ++ Set link quality thresholds; the sampling happens at every unicast ++ data frame Tx, if certain thresholds are met, and corresponding ++ events are sent to the host ++ ++ ++===================================================================== ++ ++Name ++ GPIO_INPUT_GET ++ ++Synopsis ++ Allows the host to read GPIO pins that are configured for input. The values read are ++ returned through a “GPIO_DATA” extension event. ++ ++NOTE: Support for GPIO is optional. ++ ++Command ++ N/A ++ ++Command Parameters ++ None ++ ++ ++ ++Reply Parameters ++ None ++ ++ ++Reset Value ++ None ++ ++ ++ ++Restrictions ++ None ++ ++===================================================================== ++ ++ ++Name ++ GPIO_INTR_ACK ++ ++Synopsis ++ The host uses this command to acknowledge and to re-arm GPIO interrupts reported ++ through an earlier “GPIO_INTR” extension event. A single “GPIO_INTR_ACK” ++ command should be used to acknowledge all GPIO interrupts that the host knows to ++ be outstanding (if pending interrupts are not acknowledged through ++ “GPIO_INTR_ACK”, another “GPIO_INTR” extension event is raised). ++ ++NOTE: Support for GPIO is optional. ++ ++Command ++ N/A ++ ++Command Parameters ++ UINT32 ack_mask ++ A mask of interrupting GPIO pins (e.g., ack_mask ++ bit [3] acknowledges an interrupt from the pin GPIO3). ++ ++Command Values ++ None ++ ++Reset Value ++ None ++ ++Restrictions ++ The host should acknowledge only interrupts about which it was notified. ++ ++ ++===================================================================== ++ ++Name ++ GPIO_OUTPUT_SET ++ ++Synopsis ++ Manages output on GPIO pins configured for output. ++ ++ Conflicts between set_mask and clear_mask or enable_mask and disable_mask result ++ in undefined behavior. ++ ++NOTE: Support for GPIO is optional. ++ ++Command ++ N/A ++ ++Command Parameters ++ UINT32 set_mask ++ Specifies which pins should drive a 1 out ++ UINT32 clear_mask ++ Specifies which pins should drive a 0 out ++ UINT32 enable_mask ++ Specifies which pins should be enabled for output ++ UINT32 disable_mask ++ Specifies which pins should be disabled for output ++ ++Command Values ++ None ++ ++ ++Reset Value ++ None ++ ++ ++Restrictions ++ None ++ ++ ++ ++===================================================================== ++ ++ ++Name ++ GPIO_REGISTER_GET ++ ++Synopsis ++ Allows the host to read an arbitrary GPIO register. It is intended for use during ++ bringup/debug. The target responds to this command with a “GPIO_DATA” event. ++ ++NOTE: Support for GPIO is optional. ++ ++Command ++ N/A ++ ++Command Parameters ++ UINT32 ++ gpioreg_id ++ Specifies a GPIO register identifier, as defined ++in include/AR6000/AR6000_gpio.h ++ ++Reply Parameters ++ None ++ ++Reset Value ++ N/A ++ ++Restrictions ++ None ++ ++ ++===================================================================== ++ ++Name ++ GPIO_REGISTER_SET ++ ++Synopsis ++ Allows the host to dynamically change GPIO configuration (usually handled ++ statically through the GPIO configuration DataSet). ++ ++NOTE: Support for GPIO is optional. ++ ++Command ++ N/A ++ ++Command Parameters ++ UINT32 gpioreg_id ++ Specifies a GPIO register identifier, as defined in ++ include/AR6000/AR6000_gpio.h ++ UINT32 value ++ Specifies a value to write to the specified ++ GPIO register ++ ++Command Values ++ None ++ ++ ++Reset Value ++ Initial hardware configuration is as defined in the AR6001 or AR6002 ROCmTM ++ Single-Chip MAC/BB/Radio for 2.4/5 GHz Embedded WLAN Applications data sheet. This ++ configuration is modified by the GPIO Configuration DataSet, if one exists. ++ ++Restrictions ++ None ++ ++ ++===================================================================== ++ ++ ++Name ++ SET_LQTHRESHOLD ++ ++Synopsis ++ Set link quality thresholds, the sampling happens at every unicast data frame Tx, if ++ certain threshold is met, corresponding event will be sent to host. ++ ++Command ++ wmiconfig eth1 --lqThreshold <enable> <upper_threshold_1>... ++ <upper_threshold_4> <lower_threshold_1>... <lower_threshold_4> ++ ++Command Parameters ++ A_UINT8 enable; ++ A_UINT8 thresholdAbove1_Val; ++ A_UINT8 thresholdAbove2_Val; ++ A_UINT8 thresholdAbove3_Val; ++ A_UINT8 thresholdAbove4_Val; ++ A_UINT8 thresholdBelow1_Val; ++ A_UINT8 thresholdBelow2_Val; ++ A_UINT8 thresholdBelow3_Val; ++ A_UINT8 thresholdBelow4_Val; ++ ++Command Values ++ enable ++ = 0 ++ Disable link quality sampling ++ ++ = 1 ++ Enable link quality sampling ++ ++ ++ thresholdAbove_Val ++ [1...4] ++ Above thresholds (value in [0,100]), in ascending ++ order threshold ++ ++ Below_Val [1...4] = below thresholds (value ++ in [0,100]), in ascending order ++ ++Reset Values ++ None ++ ++Restrictions ++ None ++ ++===================================================================== ++WMI Extension Events ++ ++The WMI EXTENSION event is used for a collection of events that: ++ ++ Are not generic wireless events ++ May be implementation-specific ++ May be target platform-specific ++ May be optional for a host implementation ++ ++ An extension event is sent from the AR6000 device targets to the host just like ++any other WMI event message, using the WMI_EXTENSION_EVENTID. The ++first field of the payload for this “EXTENSION” event is another commandId ++(sometimes called the subcommandId) that indicates which “EXTENSION” ++event is being used. A subcommandId-specific payload follows the ++subcommandId. ++ ++All extensions (subcommandIds) are listed in the header file include/wmix.h. ++See also “WMI Extension Commands” on page B-55. ++ ++ ++WMI Extension Events ++ ++ ++GPIO_ACK ++ Acknowledges a host set command has been processed by the device ++ ++GPIO_DATA ++ Response to a host’s request for data ++ ++GPIO_INTR ++ Signals that GPIO interrupts are pending ++ ++ ++===================================================================== ++ ++Name ++ GPIO_ACK ++ ++Synopsis ++ Acknowledges that a host set command (either “GPIO_OUTPUT_SET” or ++ “GPIO_REGISTER_SET”) has been processed by the AR6000 device. ++ ++NOTE: Support for GPIO is optional. ++ ++Event ID ++ N/A ++ ++Event Parameters ++ None ++ ++ ++Event Values ++ None ++ ++===================================================================== ++ ++ ++Name ++ GPIO_DATA ++ ++Synopsis ++ The AR6000 device uses this event to respond to the host’s earlier request for data ++ (through either a “GPIO_REGISTER_GET” or a “GPIO_INPUT_GET” command). ++ ++NOTE: Support for GPIO is optional. ++ ++Event ID ++ N/A ++ ++Event Parameters ++ UINT32 value ++ Holds the data of interest, which is either a register value ++ (in the case of “GPIO_REGISTER_GET”) or a mask of ++ pin inputs (in the case of “GPIO_INPUT_GET”). ++ UINT32 reg_id ++ Indicates which register was read (in the case of ++ “GPIO_REGISTER_GET”) or is GPIO_ID_NONE (in the ++ case of “GPIO_INPUT_GET”) ++ ++Event Values ++ None ++ ++ ++===================================================================== ++ ++ ++ ++Name ++ GPIO_INTR ++ ++Synopsis ++ The AR6000 device raises this event to signal that GPIO interrupts are pending. ++ These GPIOs may be interrupts that occurred after the last “GPIO_INTR_ACK” ++ command was issued, or may be GPIO interrupts that the host failed to acknowledge ++ in the last “GPIO_INTR_ACK”. The AR6000 will not raise another GPIO_INTR ++ event until this event is acknowledged through a “GPIO_INTR_ACK” command. ++ ++NOTE: Support for GPIO is optional. ++ ++Event ID ++ N/A ++ ++Event Parameters ++ UINT32 intr_mask ++ Indicates which GPIO interrupts are currently pending ++ ++ UINT32 input_values ++ A recent copy of the GPIO input values, taken at the ++ time the most recent GPIO interrupt was processed ++ ++Event Values ++ None ++ ++ ++ ++===================================================================== ++#endif +diff -ruN --exclude='*.orig' --exclude='*.rej' linux-2.6.29-rc3.owrt/drivers/ar6000/wmi/wmi_host.h linux-2.6.29-rc3.owrt.om/drivers/ar6000/wmi/wmi_host.h +--- linux-2.6.29-rc3.owrt/drivers/ar6000/wmi/wmi_host.h 1970-01-01 01:00:00.000000000 +0100 ++++ linux-2.6.29-rc3.owrt.om/drivers/ar6000/wmi/wmi_host.h 2009-05-10 22:27:59.000000000 +0200 +@@ -0,0 +1,71 @@ ++#ifndef _WMI_HOST_H_ ++#define _WMI_HOST_H_ ++/* ++ * Copyright (c) 2004-2006 Atheros Communications Inc. ++ * All rights reserved. ++ * ++ * This file contains local definitios for the wmi host module. ++ * ++ * $Id: //depot/sw/releases/olca2.0-GPL/host/wmi/wmi_host.h#1 $ ++ * ++ * ++ * 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; ++ * ++ * Software distributed under the License is distributed on an "AS ++ * IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or ++ * implied. See the License for the specific language governing ++ * rights and limitations under the License. ++ * ++ * ++ * ++ */ ++ ++#ifdef __cplusplus ++extern "C" { ++#endif ++ ++struct wmi_stats { ++ A_UINT32 cmd_len_err; ++ A_UINT32 cmd_id_err; ++}; ++ ++struct wmi_t { ++ A_BOOL wmi_ready; ++ A_BOOL wmi_numQoSStream; ++ A_UINT8 wmi_wmiStream2AcMapping[WMI_PRI_MAX_COUNT]; ++ WMI_PRI_STREAM_ID wmi_ac2WmiStreamMapping[WMM_NUM_AC]; ++ A_UINT16 wmi_streamExistsForAC[WMM_NUM_AC]; ++ A_UINT8 wmi_fatPipeExists; ++ void *wmi_devt; ++ struct wmi_stats wmi_stats; ++ struct ieee80211_node_table wmi_scan_table; ++ A_UINT8 wmi_bssid[ATH_MAC_LEN]; ++ A_UINT8 wmi_powerMode; ++ A_UINT8 wmi_phyMode; ++ A_UINT8 wmi_keepaliveInterval; ++ A_MUTEX_T wmi_lock; ++}; ++ ++#define WMI_INIT_WMISTREAM_AC_MAP(w) \ ++{ (w)->wmi_wmiStream2AcMapping[WMI_BEST_EFFORT_PRI] = WMM_AC_BE; \ ++ (w)->wmi_wmiStream2AcMapping[WMI_LOW_PRI] = WMM_AC_BK; \ ++ (w)->wmi_wmiStream2AcMapping[WMI_HIGH_PRI] = WMM_AC_VI; \ ++ (w)->wmi_wmiStream2AcMapping[WMI_HIGHEST_PRI] = WMM_AC_VO; \ ++ (w)->wmi_ac2WmiStreamMapping[WMM_AC_BE] = WMI_BEST_EFFORT_PRI; \ ++ (w)->wmi_ac2WmiStreamMapping[WMM_AC_BK] = WMI_LOW_PRI; \ ++ (w)->wmi_ac2WmiStreamMapping[WMM_AC_VI] = WMI_HIGH_PRI; \ ++ (w)->wmi_ac2WmiStreamMapping[WMM_AC_VO] = WMI_HIGHEST_PRI; } ++ ++#define WMI_WMISTREAM_ACCESSCATEGORY(w,s) (w)->wmi_wmiStream2AcMapping[s] ++#define WMI_ACCESSCATEGORY_WMISTREAM(w,ac) (w)->wmi_ac2WmiStreamMapping[ac] ++ ++#define LOCK_WMI(w) A_MUTEX_LOCK(&(w)->wmi_lock); ++#define UNLOCK_WMI(w) A_MUTEX_UNLOCK(&(w)->wmi_lock); ++ ++#ifdef __cplusplus ++} ++#endif ++ ++#endif /* _WMI_HOST_H_ */ +diff -ruN --exclude='*.orig' --exclude='*.rej' linux-2.6.29-rc3.owrt/drivers/base/bus.c linux-2.6.29-rc3.owrt.om/drivers/base/bus.c +--- linux-2.6.29-rc3.owrt/drivers/base/bus.c 2009-05-10 22:04:49.000000000 +0200 ++++ linux-2.6.29-rc3.owrt.om/drivers/base/bus.c 2009-05-10 22:27:59.000000000 +0200 +@@ -141,6 +141,29 @@ + } + EXPORT_SYMBOL_GPL(bus_remove_file); + ++int bus_create_device_link(struct bus_type *bus, struct kobject *target, ++ const char *name) ++{ ++ int error; ++ if (bus_get(bus)) { ++ error = sysfs_create_link(&bus->p->devices_kset->kobj, target, ++ name); ++ bus_put(bus); ++ } else ++ error = -EINVAL; ++ return error; ++} ++EXPORT_SYMBOL_GPL(bus_create_device_link); ++ ++void bus_remove_device_link(struct bus_type *bus, const char *name) ++{ ++ if (bus_get(bus)) { ++ sysfs_remove_link(&bus->p->devices_kset->kobj, name); ++ bus_put(bus); ++ } ++} ++EXPORT_SYMBOL_GPL(bus_remove_device_link); ++ + static struct kobj_type bus_ktype = { + .sysfs_ops = &bus_sysfs_ops, + }; +diff -ruN --exclude='*.orig' --exclude='*.rej' linux-2.6.29-rc3.owrt/drivers/base/core.c linux-2.6.29-rc3.owrt.om/drivers/base/core.c +--- linux-2.6.29-rc3.owrt/drivers/base/core.c 2009-05-10 22:08:41.000000000 +0200 ++++ linux-2.6.29-rc3.owrt.om/drivers/base/core.c 2009-05-10 22:27:59.000000000 +0200 +@@ -55,6 +55,11 @@ + */ + const char *dev_driver_string(const struct device *dev) + { ++ if (!dev) { ++ printk(KERN_ERR"Null dev to dev_driver_string\n"); ++ dump_stack(); ++ return "*NULL*"; ++ } + return dev->driver ? dev->driver->name : + (dev->bus ? dev->bus->name : + (dev->class ? dev->class->name : "")); +diff -ruN --exclude='*.orig' --exclude='*.rej' linux-2.6.29-rc3.owrt/drivers/base/power/main.c linux-2.6.29-rc3.owrt.om/drivers/base/power/main.c +--- linux-2.6.29-rc3.owrt/drivers/base/power/main.c 2009-05-10 22:08:41.000000000 +0200 ++++ linux-2.6.29-rc3.owrt.om/drivers/base/power/main.c 2009-05-10 22:27:59.000000000 +0200 +@@ -69,9 +69,9 @@ + */ + void device_pm_add(struct device *dev) + { +- pr_debug("PM: Adding info for %s:%s\n", ++ /* pr_debug("PM: Adding info for %s:%s\n", + dev->bus ? dev->bus->name : "No Bus", +- kobject_name(&dev->kobj)); ++ kobject_name(&dev->kobj)); */ + mutex_lock(&dpm_list_mtx); + if (dev->parent) { + if (dev->parent->power.status >= DPM_SUSPENDING) +diff -ruN --exclude='*.orig' --exclude='*.rej' linux-2.6.29-rc3.owrt/drivers/char/Kconfig linux-2.6.29-rc3.owrt.om/drivers/char/Kconfig +--- linux-2.6.29-rc3.owrt/drivers/char/Kconfig 2009-05-10 22:08:42.000000000 +0200 ++++ linux-2.6.29-rc3.owrt.om/drivers/char/Kconfig 2009-05-10 22:27:59.000000000 +0200 +@@ -66,6 +66,18 @@ + + If unsure, say Y. + ++config NR_TTY_DEVICES ++ int "Maximum tty device number" ++ depends on VT ++ default 63 ++ ---help--- ++ This is the highest numbered device created in /dev. You will actually have ++ NR_TTY_DEVICES+1 devices in /dev. The default is 63, which will result in ++ 64 /dev entries. The lowest number you can set is 11, anything below that, ++ and it will default to 11. 63 is also the upper limit so we don't overrun ++ the serial consoles. ++ ++ + config HW_CONSOLE + bool + depends on VT && !S390 && !UML +diff -ruN --exclude='*.orig' --exclude='*.rej' linux-2.6.29-rc3.owrt/drivers/gpio/gpiolib.c linux-2.6.29-rc3.owrt.om/drivers/gpio/gpiolib.c +--- linux-2.6.29-rc3.owrt/drivers/gpio/gpiolib.c 2009-05-10 22:08:42.000000000 +0200 ++++ linux-2.6.29-rc3.owrt.om/drivers/gpio/gpiolib.c 2009-05-10 22:27:59.000000000 +0200 +@@ -6,8 +6,7 @@ + #include <linux/err.h> + #include <linux/debugfs.h> + #include <linux/seq_file.h> +-#include <linux/gpio.h> +- ++#include <mach/gpio.h> + + /* Optional implementation infrastructure for GPIO interfaces. + * +diff -ruN --exclude='*.orig' --exclude='*.rej' linux-2.6.29-rc3.owrt/drivers/i2c/busses/i2c-s3c2410.c linux-2.6.29-rc3.owrt.om/drivers/i2c/busses/i2c-s3c2410.c +--- linux-2.6.29-rc3.owrt/drivers/i2c/busses/i2c-s3c2410.c 2009-05-10 22:04:49.000000000 +0200 ++++ linux-2.6.29-rc3.owrt.om/drivers/i2c/busses/i2c-s3c2410.c 2009-05-10 22:27:59.000000000 +0200 +@@ -34,9 +34,9 @@ + #include <linux/platform_device.h> + #include <linux/clk.h> + #include <linux/cpufreq.h> ++#include <linux/io.h> + + #include <asm/irq.h> +-#include <asm/io.h> + + #include <plat/regs-iic.h> + #include <plat/iic.h> +@@ -135,6 +135,14 @@ + unsigned long tmp; + + tmp = readl(i2c->regs + S3C2410_IICCON); ++ ++/* S3c2442 datasheet ++ * ++ * If the IICCON[5]=0, IICCON[4] does not operate correctly. ++ * So, It is recommended that you should set IICCON[5]=1, ++ * although you does not use the IIC interrupt. ++ */ ++ + writel(tmp & ~S3C2410_IICCON_IRQEN, i2c->regs + S3C2410_IICCON); + } + +@@ -480,6 +488,15 @@ + if (i2c->suspended) + return -EIO; + ++ if (i2c->suspended) { ++ dev_err(i2c->dev, ++ "Hey I am still asleep (suspended: %d), retry later\n", ++ i2c->suspended); ++ dump_stack(); ++ ret = -EAGAIN; ++ goto out; ++ } ++ + ret = s3c24xx_i2c_set_master(i2c); + if (ret != 0) { + dev_err(i2c->dev, "cannot get bus (error %d)\n", ret); +diff -ruN --exclude='*.orig' --exclude='*.rej' linux-2.6.29-rc3.owrt/drivers/i2c/busses/Kconfig linux-2.6.29-rc3.owrt.om/drivers/i2c/busses/Kconfig +--- linux-2.6.29-rc3.owrt/drivers/i2c/busses/Kconfig 2009-05-10 22:04:49.000000000 +0200 ++++ linux-2.6.29-rc3.owrt.om/drivers/i2c/busses/Kconfig 2009-05-10 22:27:59.000000000 +0200 +@@ -455,11 +455,12 @@ + I2C bus. + + config I2C_S3C2410 +- tristate "S3C2410 I2C Driver" +- depends on ARCH_S3C2410 ++ tristate "Samsung SoC I2C Driver (S3C24XX and S3C64XX series)" ++ depends on ARCH_S3C2410 || ARCH_S3C64XX + help + Say Y here to include support for I2C controller in the +- Samsung S3C2410 based System-on-Chip devices. ++ Samsung S3C based System-on-Chip devices such as the S3C2410, ++ S3C2440, S3C2442, S3C2443 and S3C6410. + + config I2C_SH7760 + tristate "Renesas SH7760 I2C Controller" +diff -ruN --exclude='*.orig' --exclude='*.rej' linux-2.6.29-rc3.owrt/drivers/i2c/chips/Kconfig linux-2.6.29-rc3.owrt.om/drivers/i2c/chips/Kconfig +--- linux-2.6.29-rc3.owrt/drivers/i2c/chips/Kconfig 2009-05-10 22:04:49.000000000 +0200 ++++ linux-2.6.29-rc3.owrt.om/drivers/i2c/chips/Kconfig 2009-05-10 22:27:59.000000000 +0200 +@@ -16,6 +16,53 @@ + This driver can also be built as a module. If so, the module + will be called ds1682. + ++config AT24 ++ tristate "EEPROMs from most vendors" ++ depends on SYSFS && EXPERIMENTAL ++ help ++ Enable this driver to get read/write support to most I2C EEPROMs, ++ after you configure the driver to know about each EEPROM on ++ your target board. Use these generic chip names, instead of ++ vendor-specific ones like at24c64 or 24lc02: ++ ++ 24c00, 24c01, 24c02, spd (readonly 24c02), 24c04, 24c08, ++ 24c16, 24c32, 24c64, 24c128, 24c256, 24c512, 24c1024 ++ ++ Unless you like data loss puzzles, always be sure that any chip ++ you configure as a 24c32 (32 kbit) or larger is NOT really a ++ 24c16 (16 kbit) or smaller, and vice versa. Marking the chip ++ as read-only won't help recover from this. Also, if your chip ++ has any software write-protect mechanism you may want to review the ++ code to make sure this driver won't turn it on by accident. ++ ++ If you use this with an SMBus adapter instead of an I2C adapter, ++ full functionality is not available. Only smaller devices are ++ supported (24c16 and below, max 4 kByte). ++ ++ This driver can also be built as a module. If so, the module ++ will be called at24. ++ ++config SENSORS_EEPROM ++ tristate "EEPROM reader" ++ depends on EXPERIMENTAL ++ help ++ If you say yes here you get read-only access to the EEPROM data ++ available on modern memory DIMMs and Sony Vaio laptops. Such ++ EEPROMs could theoretically be available on other devices as well. ++ ++ This driver can also be built as a module. If so, the module ++ will be called eeprom. ++ ++config SENSORS_PCF50606 ++ tristate "Philips/NXP PCF50606" ++ depends on I2C ++ help ++ If you say yes here you get support for Philips/NXP PCF50606 ++ PMU (Power Management Unit) chips. ++ ++ This driver can also be built as a module. If so, the module ++ will be called pcf50606. ++ + config SENSORS_PCF8574 + tristate "Philips PCF8574 and PCF8574A (DEPRECATED)" + depends on EXPERIMENTAL && GPIO_PCF857X = "n" +@@ -102,4 +149,14 @@ + This driver can also be built as a module. If so, the module + will be called tsl2550. + ++config PCA9632 ++ tristate "Philips/NXP PCA9632 low power LED driver" ++ depends on I2C ++ help ++ If you say yes here you get support for the Philips/NXP PCA9632 ++ LED driver. ++ ++ This driver can also be built as a module. If so, the module ++ will be called pca9632. ++ + endmenu +diff -ruN --exclude='*.orig' --exclude='*.rej' linux-2.6.29-rc3.owrt/drivers/i2c/chips/Makefile linux-2.6.29-rc3.owrt.om/drivers/i2c/chips/Makefile +--- linux-2.6.29-rc3.owrt/drivers/i2c/chips/Makefile 2009-05-10 22:04:49.000000000 +0200 ++++ linux-2.6.29-rc3.owrt.om/drivers/i2c/chips/Makefile 2009-05-10 22:27:59.000000000 +0200 +@@ -13,10 +13,12 @@ + obj-$(CONFIG_DS1682) += ds1682.o + obj-$(CONFIG_SENSORS_MAX6875) += max6875.o + obj-$(CONFIG_SENSORS_PCA9539) += pca9539.o ++obj-$(CONFIG_SENSORS_PCF50606) += pcf50606.o + obj-$(CONFIG_SENSORS_PCF8574) += pcf8574.o + obj-$(CONFIG_PCF8575) += pcf8575.o + obj-$(CONFIG_SENSORS_PCF8591) += pcf8591.o + obj-$(CONFIG_SENSORS_TSL2550) += tsl2550.o ++obj-$(CONFIG_PCA9632) += pca9632.o + + ifeq ($(CONFIG_I2C_DEBUG_CHIP),y) + EXTRA_CFLAGS += -DDEBUG +diff -ruN --exclude='*.orig' --exclude='*.rej' linux-2.6.29-rc3.owrt/drivers/i2c/chips/pca9632.c linux-2.6.29-rc3.owrt.om/drivers/i2c/chips/pca9632.c +--- linux-2.6.29-rc3.owrt/drivers/i2c/chips/pca9632.c 1970-01-01 01:00:00.000000000 +0100 ++++ linux-2.6.29-rc3.owrt.om/drivers/i2c/chips/pca9632.c 2009-05-10 22:27:59.000000000 +0200 +@@ -0,0 +1,551 @@ ++/* ++ * Philips/NXP PCA9632 low power LED driver. ++ * Copyright (C) 2008 Matt Hsu <matt_hsu@openmoko.org> ++ * ++ * low_level implementation are based on pcf50606 driver ++ * ++ * 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; version 2 of the License. ++ * ++ * TODO: ++ * - attach ledclass?? ++ * - add platform data ++ * ++ */ ++ ++#include <linux/module.h> ++#include <linux/init.h> ++#include <linux/i2c.h> ++#include <linux/platform_device.h> ++ ++#include "pca9632.h" ++ ++/* Addresses to scan */ ++static unsigned short normal_i2c[] = { 0x62, I2C_CLIENT_END }; ++ ++/* Insmod parameters */ ++I2C_CLIENT_INSMOD_1(pca9632); ++ ++enum pca9632_pwr_state { ++ PCA9632_NORMAL, ++ PCA9632_SLEEP, ++}; ++ ++enum pca9632_led_output { ++ PCA9632_OFF, ++ PCA9632_ON, ++ PCA9632_CTRL_BY_PWM, ++ PCA9632_CTRL_BY_PWM_GRPPWM, ++}; ++ ++static const char *led_output_name[] = { ++ [PCA9632_OFF] = "off", ++ [PCA9632_ON] = "fully-on", ++ [PCA9632_CTRL_BY_PWM] = "ctrl-by-pwm", ++ [PCA9632_CTRL_BY_PWM_GRPPWM] = "ctrl-by-pwm-grppwm", ++}; ++ ++struct pca9632_data { ++ struct i2c_client client; ++ struct mutex lock; ++}; ++ ++static struct i2c_driver pca9632_driver; ++static struct platform_device *pca9632_pdev; ++ ++static int pca9632_attach_adapter(struct i2c_adapter *adapter); ++static int pca9632_detach_client(struct i2c_client *client); ++ ++static int __reg_write(struct pca9632_data *pca, u_int8_t reg, u_int8_t val) ++{ ++ return i2c_smbus_write_byte_data(&pca->client, reg, val); ++} ++ ++static int reg_write(struct pca9632_data *pca, u_int8_t reg, u_int8_t val) ++{ ++ int ret; ++ ++ mutex_lock(&pca->lock); ++ ret = __reg_write(pca, reg, val); ++ mutex_unlock(&pca->lock); ++ ++ return ret; ++} ++ ++static int32_t __reg_read(struct pca9632_data *pca, u_int8_t reg) ++{ ++ int32_t ret; ++ ++ ret = i2c_smbus_read_byte_data(&pca->client, reg); ++ ++ return ret; ++} ++ ++static u_int8_t reg_read(struct pca9632_data *pca, u_int8_t reg) ++{ ++ int32_t ret; ++ ++ mutex_lock(&pca->lock); ++ ret = __reg_read(pca, reg); ++ mutex_unlock(&pca->lock); ++ ++ return ret & 0xff; ++} ++ ++static int reg_set_bit_mask(struct pca9632_data *pca, ++ u_int8_t reg, u_int8_t mask, u_int8_t val) ++{ ++ int ret; ++ u_int8_t tmp; ++ ++ val &= mask; ++ ++ mutex_lock(&pca->lock); ++ ++ tmp = __reg_read(pca, reg); ++ tmp &= ~mask; ++ tmp |= val; ++ ret = __reg_write(pca, reg, tmp); ++ ++ mutex_unlock(&pca->lock); ++ ++ return ret; ++} ++ ++static inline int calc_dc(uint8_t idc) ++{ ++ return (idc * 100) / 256; ++} ++ ++/* ++ * Software reset ++ */ ++static int software_rst(struct i2c_adapter *adapter) ++{ ++ u8 buf[] = { 0xa5, 0x5a }; ++ ++ struct i2c_msg msg[] = { ++ { ++ .addr = 0x3, ++ .flags = 0, ++ .buf = &buf, ++ .len = sizeof(buf) ++ } ++ }; ++ ++ return i2c_transfer(adapter, msg, 1); ++} ++ ++/* ++ * Group dmblnk control ++ */ ++static void config_group_dmblnk(struct pca9632_data *pca, int group_dmblnk_mode) ++{ ++ reg_set_bit_mask(pca, PCA9632_REG_MODE2, 0x20, ++ group_dmblnk_mode << PCA9632_DMBLNK_SHIFT); ++} ++ ++static int get_group_dmblnk(struct pca9632_data *pca) ++{ ++ return reg_read(pca, PCA9632_REG_MODE2) >> PCA9632_DMBLNK_SHIFT; ++} ++ ++static ssize_t show_group_dmblnk(struct device *dev, struct device_attribute ++ *attr, char *buf) ++{ ++ struct i2c_client *client = to_i2c_client(dev); ++ struct pca9632_data *pca = i2c_get_clientdata(client); ++ ++ if (get_group_dmblnk(pca)) ++ return sprintf(buf, "blinking\n"); ++ else ++ return sprintf(buf, "dimming\n"); ++} ++ ++static ssize_t set_group_dmblnk(struct device *dev, struct device_attribute ++ *attr, const char *buf, size_t count) ++{ ++ struct i2c_client *client = to_i2c_client(dev); ++ struct pca9632_data *pca = i2c_get_clientdata(client); ++ unsigned int mode = simple_strtoul(buf, NULL, 10); ++ ++ if (mode) ++ dev_info(&pca->client.dev, "blinking\n"); ++ else ++ dev_info(&pca->client.dev, "dimming\n"); ++ ++ config_group_dmblnk(pca, mode); ++ ++ return count; ++} ++ ++static DEVICE_ATTR(group_dmblnk, S_IRUGO | S_IWUSR, show_group_dmblnk, ++ set_group_dmblnk); ++ ++static int reg_id_by_name(const char *name) ++{ ++ int reg_id = -1; ++ ++ if (!strncmp(name, "led0", 4)) ++ reg_id = PCA9632_REG_PWM0; ++ else if (!strncmp(name, "led1", 4)) ++ reg_id = PCA9632_REG_PWM1; ++ else if (!strncmp(name, "led2", 4)) ++ reg_id = PCA9632_REG_PWM2; ++ else if (!strncmp(name, "led3", 4)) ++ reg_id = PCA9632_REG_PWM3; ++ ++ return reg_id; ++} ++ ++static int get_led_output(struct pca9632_data *pca, int ldrx) ++{ ++ u_int8_t led_state; ++ ++ ldrx = ldrx - 2; ++ led_state = reg_read(pca, PCA9632_REG_LEDOUT); ++ led_state = (led_state >> (2 * ldrx)) & 0x03; ++ ++ return led_state; ++} ++ ++static void config_led_output(struct pca9632_data *pca, int ldrx, ++ enum pca9632_led_output led_output) ++{ ++ u_int8_t mask; ++ int tmp; ++ ++ ldrx = ldrx - 2; ++ mask = 0x03 << (2 * ldrx); ++ tmp = reg_set_bit_mask(pca, PCA9632_REG_LEDOUT, ++ mask, led_output << (2 * ldrx)); ++} ++ ++/* ++ * Individual brightness control ++ */ ++static ssize_t show_brightness(struct device *dev, struct device_attribute ++ *attr, char *buf) ++{ ++ struct i2c_client *client = to_i2c_client(dev); ++ struct pca9632_data *pca = i2c_get_clientdata(client); ++ int ldrx; ++ ++ ldrx = reg_id_by_name(attr->attr.name); ++ ++ switch (get_led_output(pca, ldrx)) { ++ ++ case PCA9632_OFF: ++ case PCA9632_ON: ++ return sprintf(buf, "%s", ++ led_output_name[get_led_output(pca, ldrx)]); ++ ++ case PCA9632_CTRL_BY_PWM: ++ return sprintf(buf, "%d%% \n", calc_dc(reg_read(pca, ldrx))); ++ ++ case PCA9632_CTRL_BY_PWM_GRPPWM: ++ /* check group dmblnk */ ++ if (get_group_dmblnk(pca)) ++ return sprintf(buf, "%d%% \n", ++ calc_dc(reg_read(pca, ldrx))); ++ return sprintf(buf, "%d%% \n", ++ calc_dc((reg_read(pca, ldrx) & 0xfc))); ++ default: ++ break; ++ } ++ ++ return sprintf(buf, "invalid argument\n"); ++} ++ ++static ssize_t set_brightness(struct device *dev, struct device_attribute *attr, ++ const char *buf, size_t count) ++{ ++ struct i2c_client *client = to_i2c_client(dev); ++ struct pca9632_data *pca = i2c_get_clientdata(client); ++ unsigned int pwm = simple_strtoul(buf, NULL, 10); ++ int ldrx; ++ ++ ldrx = reg_id_by_name(attr->attr.name); ++ reg_set_bit_mask(pca, ldrx, 0xff, pwm); ++ ++ return count; ++} ++ ++static ++DEVICE_ATTR(led0_pwm, S_IRUGO | S_IWUSR, show_brightness, set_brightness); ++static ++DEVICE_ATTR(led1_pwm, S_IRUGO | S_IWUSR, show_brightness, set_brightness); ++static ++DEVICE_ATTR(led2_pwm, S_IRUGO | S_IWUSR, show_brightness, set_brightness); ++static ++DEVICE_ATTR(led3_pwm, S_IRUGO | S_IWUSR, show_brightness, set_brightness); ++ ++/* ++ * Group frequency control ++ */ ++static ssize_t show_group_freq(struct device *dev, struct device_attribute ++ *attr, char *buf) ++{ ++ uint32_t period; ++ struct i2c_client *client = to_i2c_client(dev); ++ struct pca9632_data *pca = i2c_get_clientdata(client); ++ ++ period = ((reg_read(pca, PCA9632_REG_GRPFREQ) + 1) * 1000) / 24; ++ ++ return sprintf(buf, "%d ms\n", period); ++} ++ ++static ssize_t set_group_freq(struct device *dev, struct device_attribute *attr, ++ const char *buf, size_t count) ++{ ++ struct i2c_client *client = to_i2c_client(dev); ++ struct pca9632_data *pca = i2c_get_clientdata(client); ++ ++ unsigned int freq = simple_strtoul(buf, NULL, 10); ++ reg_write(pca, PCA9632_REG_GRPFREQ, freq); ++ return count; ++} ++ ++static ++DEVICE_ATTR(group_freq, S_IRUGO | S_IWUSR, show_group_freq, set_group_freq); ++ ++/* ++ * Group duty cycle tonrol* ++ */ ++static ssize_t show_group_dc(struct device *dev, struct device_attribute *attr, ++ char *buf) ++{ ++ struct i2c_client *client = to_i2c_client(dev); ++ struct pca9632_data *pca = i2c_get_clientdata(client); ++ ++ if (get_group_dmblnk(pca)) { ++ ++ if (reg_read(pca, PCA9632_REG_GRPFREQ) <= 0x03) ++ return sprintf(buf, "%d%% \n", ++ calc_dc(reg_read(pca, PCA9632_REG_GRPPWM) & 0xfc)); ++ ++ return sprintf(buf, "%d%% \n", calc_dc(reg_read(pca, ++ PCA9632_REG_GRPPWM))); ++ } ++ ++ return sprintf(buf, "%d%% \n", calc_dc(reg_read(pca, ++ PCA9632_REG_GRPPWM) & 0xf0)); ++} ++ ++static ssize_t set_group_dc(struct device *dev, struct device_attribute *attr, ++ const char *buf, size_t count) ++{ ++ struct i2c_client *client = to_i2c_client(dev); ++ struct pca9632_data *pca = i2c_get_clientdata(client); ++ ++ unsigned int dc = simple_strtoul(buf, NULL, 10); ++ ++ reg_set_bit_mask(pca, PCA9632_REG_GRPPWM, 0xff, dc); ++ ++ return count; ++} ++ ++static DEVICE_ATTR(group_dc, S_IRUGO | S_IWUSR, show_group_dc, set_group_dc); ++ ++/* ++ * LED driver output ++ */ ++static ssize_t show_led_output(struct device *dev, struct device_attribute ++ *attr, char *buf) ++{ ++ struct i2c_client *client = to_i2c_client(dev); ++ struct pca9632_data *pca = i2c_get_clientdata(client); ++ int ldrx; ++ ++ ldrx = reg_id_by_name(attr->attr.name); ++ ++ return sprintf(buf, "%s \n", ++ led_output_name[get_led_output(pca, ldrx)]); ++ ++} ++static ssize_t set_led_output(struct device *dev, struct device_attribute *attr, ++ const char *buf, size_t count) ++{ ++ struct i2c_client *client = to_i2c_client(dev); ++ struct pca9632_data *pca = i2c_get_clientdata(client); ++ enum pca9632_led_output led_output; ++ int ldrx; ++ ++ led_output = simple_strtoul(buf, NULL, 10); ++ ldrx = reg_id_by_name(attr->attr.name); ++ config_led_output(pca, ldrx, led_output); ++ ++ return count; ++} ++ ++static ++DEVICE_ATTR(led0_output, S_IRUGO | S_IWUSR, show_led_output, set_led_output); ++static ++DEVICE_ATTR(led1_output, S_IRUGO | S_IWUSR, show_led_output, set_led_output); ++static ++DEVICE_ATTR(led2_output, S_IRUGO | S_IWUSR, show_led_output, set_led_output); ++static ++DEVICE_ATTR(led3_output, S_IRUGO | S_IWUSR, show_led_output, set_led_output); ++ ++static struct attribute *pca_sysfs_entries[] = { ++ &dev_attr_group_dmblnk.attr, ++ &dev_attr_led0_pwm.attr, ++ &dev_attr_led1_pwm.attr, ++ &dev_attr_led2_pwm.attr, ++ &dev_attr_led3_pwm.attr, ++ &dev_attr_group_dc.attr, ++ &dev_attr_group_freq.attr, ++ &dev_attr_led0_output.attr, ++ &dev_attr_led1_output.attr, ++ &dev_attr_led2_output.attr, ++ &dev_attr_led3_output.attr, ++ NULL ++}; ++ ++static struct attribute_group pca_attr_group = { ++ .name = NULL, /* put in device directory */ ++ .attrs = pca_sysfs_entries, ++}; ++ ++#ifdef CONFIG_PM ++static int pca9632_suspend(struct device *dev, pm_message_t state) ++{ ++ /* FIXME: Not implemented */ ++ return 0; ++} ++ ++static int pca9632_resume(struct device *dev) ++{ ++ /* FIXME: Not implemented */ ++ return 0; ++} ++#else ++#define pca9632_suspend NULL ++#define pca9632_resume NULL ++#endif ++ ++static struct i2c_driver pca9632_driver = { ++ .driver = { ++ .name = "pca9632", ++ .suspend = pca9632_suspend, ++ .resume = pca9632_resume, ++ }, ++ .id = I2C_DRIVERID_PCA9632, ++ .attach_adapter = pca9632_attach_adapter, ++ .detach_client = pca9632_detach_client, ++}; ++ ++static int pca9632_detect(struct i2c_adapter *adapter, int address, int kind) ++{ ++ struct i2c_client *new_client; ++ struct pca9632_data *pca; ++ int err; ++ ++ pca = kzalloc(sizeof(struct pca9632_data), GFP_KERNEL); ++ if (!pca) ++ return -ENOMEM; ++ ++ mutex_init(&pca->lock); ++ ++ new_client = &pca->client; ++ i2c_set_clientdata(new_client, pca); ++ new_client->addr = address; ++ new_client->adapter = adapter; ++ new_client->driver = &pca9632_driver; ++ new_client->flags = 0; ++ ++ strlcpy(new_client->name, "pca9632", I2C_NAME_SIZE); ++ ++ /* register with i2c core */ ++ err = i2c_attach_client(new_client); ++ if (err) ++ goto exit_kfree; ++ ++ err = sysfs_create_group(&new_client->dev.kobj, &pca_attr_group); ++ if (err) ++ goto exit_detach; ++ ++ /* software reset */ ++ if (!software_rst(adapter)) ++ dev_info(&pca->client.dev, "pca9632 sw-rst done\n"); ++ ++ /* enter normal mode */ ++ reg_set_bit_mask(pca, PCA9632_REG_MODE1, 0x10, PCA9632_NORMAL); ++ ++ return 0; ++ ++exit_detach: ++ i2c_detach_client(new_client); ++exit_kfree: ++ kfree(pca); ++ ++ return err; ++} ++ ++static int pca9632_attach_adapter(struct i2c_adapter *adapter) ++{ ++ return i2c_probe(adapter, &addr_data, pca9632_detect); ++} ++ ++static int pca9632_detach_client(struct i2c_client *client) ++{ ++ int err; ++ ++ sysfs_remove_group(&client->dev.kobj, &pca_attr_group); ++ err = i2c_detach_client(client); ++ ++ if (err) ++ return err; ++ ++ kfree(i2c_get_clientdata(client)); ++ ++ return 0; ++} ++ ++static int __init pca9632_plat_probe(struct platform_device *pdev) ++{ ++ /* FIXME: platform data should be attached here */ ++ pca9632_pdev = pdev; ++ ++ return 0; ++} ++ ++static int pca9632_plat_remove(struct platform_device *pdev) ++{ ++ return 0; ++} ++ ++static struct platform_driver pca9632_plat_driver = { ++ .probe = pca9632_plat_probe, ++ .remove = pca9632_plat_remove, ++ .driver = { ++ .owner = THIS_MODULE, ++ .name = "pca9632", ++ }, ++}; ++ ++static int __init pca9632_init(void) ++{ ++ int rc; ++ ++ rc = platform_driver_register(&pca9632_plat_driver); ++ if (!rc) ++ i2c_add_driver(&pca9632_driver); ++ ++ return rc; ++} ++ ++static void __exit pca9632_exit(void) ++{ ++ i2c_del_driver(&pca9632_driver); ++ ++ platform_driver_unregister(&pca9632_plat_driver); ++} ++ ++MODULE_AUTHOR("Matt Hsu <matt_hsu@openmoko.org>"); ++MODULE_DESCRIPTION("NXP PCA9632 driver"); ++MODULE_LICENSE("GPL"); ++ ++module_init(pca9632_init); ++module_exit(pca9632_exit); +diff -ruN --exclude='*.orig' --exclude='*.rej' linux-2.6.29-rc3.owrt/drivers/i2c/chips/pca9632.h linux-2.6.29-rc3.owrt.om/drivers/i2c/chips/pca9632.h +--- linux-2.6.29-rc3.owrt/drivers/i2c/chips/pca9632.h 1970-01-01 01:00:00.000000000 +0100 ++++ linux-2.6.29-rc3.owrt.om/drivers/i2c/chips/pca9632.h 2009-05-10 22:27:59.000000000 +0200 +@@ -0,0 +1,24 @@ ++#ifndef _PCA9632_H ++#define _PCA9632_H ++ ++ ++enum pca9632_regs{ ++ ++ PCA9632_REG_MODE1 = 0x00, ++ PCA9632_REG_MODE2 = 0x01, ++ PCA9632_REG_PWM0 = 0x02, ++ PCA9632_REG_PWM1 = 0x03, ++ PCA9632_REG_PWM2 = 0x04, ++ PCA9632_REG_PWM3 = 0x05, ++ PCA9632_REG_GRPPWM = 0x06, ++ PCA9632_REG_GRPFREQ = 0x07, ++ PCA9632_REG_LEDOUT = 0x08, ++ PCA9632_REG_SUBADDR1 = 0x09, ++ PCA9632_REG_SUBADDR2 = 0x0a, ++ PCA9632_REG_SUBADDR3 = 0x0b, ++ PCA9632_REG_ALLCALLADR1 = 0x0c, ++}; ++ ++#define PCA9632_DMBLNK_SHIFT 5 ++ ++#endif /* _PCA9632_H */ +diff -ruN --exclude='*.orig' --exclude='*.rej' linux-2.6.29-rc3.owrt/drivers/i2c/chips/pcf50606.c linux-2.6.29-rc3.owrt.om/drivers/i2c/chips/pcf50606.c +--- linux-2.6.29-rc3.owrt/drivers/i2c/chips/pcf50606.c 1970-01-01 01:00:00.000000000 +0100 ++++ linux-2.6.29-rc3.owrt.om/drivers/i2c/chips/pcf50606.c 2009-05-10 22:27:59.000000000 +0200 +@@ -0,0 +1,2193 @@ ++/* Philips/NXP PCF50606 Power Management Unit (PMU) driver ++ * ++ * (C) 2006-2007 by Openmoko, Inc. ++ * Authors: Harald Welte <laforge@openmoko.org>, ++ * Matt Hsu <matt@openmoko.org> ++ * All rights reserved. ++ * ++ * 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, ++ * MA 02111-1307 USA ++ * ++ * This driver is a monster ;) It provides the following features ++ * - voltage control for a dozen different voltage domains ++ * - charging control for main and backup battery ++ * - rtc / alarm ++ * - watchdog ++ * - adc driver (hw_sensors like) ++ * - pwm driver ++ * - backlight ++ * ++ */ ++ ++#include <linux/module.h> ++#include <linux/init.h> ++#include <linux/i2c.h> ++#include <linux/types.h> ++#include <linux/interrupt.h> ++#include <linux/irq.h> ++#include <linux/workqueue.h> ++#include <linux/delay.h> ++#include <linux/rtc.h> ++#include <linux/bcd.h> ++#include <linux/watchdog.h> ++#include <linux/miscdevice.h> ++#include <linux/input.h> ++#include <linux/fb.h> ++#include <linux/backlight.h> ++#include <linux/sched.h> ++#include <linux/platform_device.h> ++#include <linux/pcf50606.h> ++#include <linux/apm-emulation.h> ++ ++#include <asm/mach-types.h> ++#include <mach/gta01.h> ++ ++#include "pcf50606.h" ++ ++/* we use dev_dbg() throughout the code, but sometimes don't want to ++ * write an entire line of debug related information. This DEBUGPC ++ * macro is a continuation for dev_dbg() */ ++#ifdef DEBUG ++#define DEBUGPC(x, args ...) printk(x, ## args) ++#else ++#define DEBUGPC(x, args ...) ++#endif ++ ++/*********************************************************************** ++ * Static data / structures ++ ***********************************************************************/ ++ ++static unsigned short normal_i2c[] = { 0x08, I2C_CLIENT_END }; ++ ++I2C_CLIENT_INSMOD_1(pcf50606); ++ ++#define PCF50606_B_CHG_FAST 0 /* Charger Fast allowed */ ++#define PCF50606_B_CHG_PRESENT 1 /* Charger present */ ++#define PCF50606_B_CHG_FOK 2 /* Fast OK for battery */ ++#define PCF50606_B_CHG_ERR 3 /* Charger Error */ ++#define PCF50606_B_CHG_PROT 4 /* Charger Protection */ ++#define PCF50606_B_CHG_READY 5 /* Charging completed */ ++ ++#define PCF50606_F_CHG_FAST (1<<PCF50606_B_CHG_FAST) ++#define PCF50606_F_CHG_PRESENT (1<<PCF50606_B_CHG_PRESENT) ++#define PCF50606_F_CHG_FOK (1<<PCF50606_B_CHG_FOK) ++#define PCF50606_F_CHG_ERR (1<<PCF50606_B_CHG_ERR) ++#define PCF50606_F_CHG_PROT (1<<PCF50606_B_CHG_PROT) ++#define PCF50606_F_CHG_READY (1<<PCF50606_B_CHG_READY) ++#define PCF50606_F_CHG_MASK 0x000000fc ++ ++#define PCF50606_F_PWR_PRESSED 0x00000100 ++#define PCF50606_F_RTC_SECOND 0x00000200 ++ ++enum close_state { ++ CLOSE_STATE_NOT, ++ CLOSE_STATE_ALLOW = 0x2342, ++}; ++ ++enum pcf50606_suspend_states { ++ PCF50606_SS_RUNNING, ++ PCF50606_SS_STARTING_SUSPEND, ++ PCF50606_SS_COMPLETED_SUSPEND, ++ PCF50606_SS_RESUMING_BUT_NOT_US_YET, ++ PCF50606_SS_STARTING_RESUME, ++ PCF50606_SS_COMPLETED_RESUME, ++}; ++ ++struct pcf50606_data { ++ struct i2c_client client; ++ struct pcf50606_platform_data *pdata; ++ struct backlight_device *backlight; ++ struct mutex lock; ++ unsigned int flags; ++ unsigned int working; ++ struct mutex working_lock; ++ struct work_struct work; ++ struct rtc_device *rtc; ++ struct input_dev *input_dev; ++ int allow_close; ++ int onkey_seconds; ++ int irq; ++ int coldplug_done; ++ int suppress_onkey_events; ++ enum pcf50606_suspend_states suspend_state; ++#ifdef CONFIG_PM ++ struct { ++ u_int8_t dcdc1, dcdc2; ++ u_int8_t dcdec1; ++ u_int8_t dcudc1; ++ u_int8_t ioregc; ++ u_int8_t d1regc1; ++ u_int8_t d2regc1; ++ u_int8_t d3regc1; ++ u_int8_t lpregc1; ++ u_int8_t adcc1, adcc2; ++ u_int8_t pwmc1; ++ u_int8_t int1m, int2m, int3m; ++ } standby_regs; ++#endif ++}; ++ ++static struct i2c_driver pcf50606_driver; ++ ++/* This is an ugly construct on how to access the (currently single/global) ++ * pcf50606 handle from other code in the kernel. I didn't really come up with ++ * a more decent method of dynamically resolving this */ ++struct pcf50606_data *pcf50606_global; ++EXPORT_SYMBOL_GPL(pcf50606_global); ++ ++static struct platform_device *pcf50606_pdev; ++ ++/* This is a 10k, B=3370 NTC Thermistor -10..79 centigrade */ ++/* Table entries are offset by +0.5C so a properly rounded value is generated */ ++static const u_int16_t ntc_table_10k_3370B[] = { ++ /* -10 */ ++ 43888, 41819, 39862, 38010, 36257, 34596, 33024, 31534, 30121, 28781, ++ 27510, 26304, 25159, 24071, 23038, 22056, 21122, 20234, 19390, 18586, ++ 17821, 17093, 16399, 15738, 15107, 14506, 13933, 13387, 12865, 12367, ++ 11891, 11437, 11003, 10588, 10192, 9813, 9450, 9103, 8771, 8453, ++ 8149, 7857, 7578, 7310, 7054, 6808, 6572, 6346, 6129, 5920, ++ 5720, 5528, 5344, 5167, 4996, 4833, 4675, 4524, 4379, 4239, ++ 4104, 3975, 3850, 3730, 3614, 3503, 3396, 3292, 3193, 3097, ++ 3004, 2915, 2829, 2745, 2665, 2588, 2513, 2441, 2371, 2304, ++ 2239, 2176, 2116, 2057, 2000, 1945, 1892, 1841, 1791, 1743, ++}; ++ ++ ++/*********************************************************************** ++ * Low-Level routines ++ ***********************************************************************/ ++ ++static inline int __reg_write(struct pcf50606_data *pcf, u_int8_t reg, ++ u_int8_t val) ++{ ++ if (pcf->suspend_state == PCF50606_SS_COMPLETED_SUSPEND) { ++ dev_err(&pcf->client.dev, "__reg_write while suspended.\n"); ++ dump_stack(); ++ } ++ return i2c_smbus_write_byte_data(&pcf->client, reg, val); ++} ++ ++static int reg_write(struct pcf50606_data *pcf, u_int8_t reg, u_int8_t val) ++{ ++ int ret; ++ ++ mutex_lock(&pcf->lock); ++ ret = __reg_write(pcf, reg, val); ++ mutex_unlock(&pcf->lock); ++ ++ return ret; ++} ++ ++static inline int32_t __reg_read(struct pcf50606_data *pcf, u_int8_t reg) ++{ ++ int32_t ret; ++ ++ if (pcf->suspend_state == PCF50606_SS_COMPLETED_SUSPEND) { ++ dev_err(&pcf->client.dev, "__reg_read while suspended.\n"); ++ dump_stack(); ++ } ++ ret = i2c_smbus_read_byte_data(&pcf->client, reg); ++ ++ return ret; ++} ++ ++static u_int8_t reg_read(struct pcf50606_data *pcf, u_int8_t reg) ++{ ++ int32_t ret; ++ ++ mutex_lock(&pcf->lock); ++ ret = __reg_read(pcf, reg); ++ mutex_unlock(&pcf->lock); ++ ++ return ret & 0xff; ++} ++ ++static int reg_set_bit_mask(struct pcf50606_data *pcf, ++ u_int8_t reg, u_int8_t mask, u_int8_t val) ++{ ++ int ret; ++ u_int8_t tmp; ++ ++ val &= mask; ++ ++ mutex_lock(&pcf->lock); ++ ++ tmp = __reg_read(pcf, reg); ++ tmp &= ~mask; ++ tmp |= val; ++ ret = __reg_write(pcf, reg, tmp); ++ ++ mutex_unlock(&pcf->lock); ++ ++ return ret; ++} ++ ++static int reg_clear_bits(struct pcf50606_data *pcf, u_int8_t reg, u_int8_t val) ++{ ++ int ret; ++ u_int8_t tmp; ++ ++ mutex_lock(&pcf->lock); ++ ++ tmp = __reg_read(pcf, reg); ++ tmp &= ~val; ++ ret = __reg_write(pcf, reg, tmp); ++ ++ mutex_unlock(&pcf->lock); ++ ++ return ret; ++} ++ ++/* synchronously read one ADC channel (busy-wait for result to be complete) */ ++static u_int16_t adc_read(struct pcf50606_data *pcf, int channel, ++ u_int16_t *data2) ++{ ++ u_int8_t adcs2, adcs1; ++ u_int16_t ret; ++ ++ dev_dbg(&pcf->client.dev, "entering (pcf=%p, channel=%u, data2=%p)\n", ++ pcf, channel, data2); ++ ++ channel &= PCF50606_ADCC2_ADCMUX_MASK; ++ ++ mutex_lock(&pcf->lock); ++ ++ /* start ADC conversion of selected channel */ ++ __reg_write(pcf, PCF50606_REG_ADCC2, channel | ++ PCF50606_ADCC2_ADCSTART | PCF50606_ADCC2_RES_10BIT); ++ ++ do { ++ adcs2 = __reg_read(pcf, PCF50606_REG_ADCS2); ++ } while (!(adcs2 & PCF50606_ADCS2_ADCRDY)); ++ ++ adcs1 = __reg_read(pcf, PCF50606_REG_ADCS1); ++ ret = (adcs1 << 2) | (adcs2 & 0x03); ++ ++ if (data2) { ++ adcs1 = __reg_read(pcf, PCF50606_REG_ADCS3); ++ *data2 = (adcs1 << 2) | ((adcs2 & 0x0c) >> 2); ++ } ++ ++ mutex_unlock(&pcf->lock); ++ ++ dev_dbg(&pcf->client.dev, "returning %u %u\n", ret, ++ data2 ? *data2 : 0); ++ ++ return ret; ++} ++ ++/*********************************************************************** ++ * Voltage / ADC ++ ***********************************************************************/ ++ ++static u_int8_t dcudc_voltage(unsigned int millivolts) ++{ ++ if (millivolts < 900) ++ return 0; ++ if (millivolts > 5500) ++ return 0x1f; ++ if (millivolts <= 3300) { ++ millivolts -= 900; ++ return millivolts/300; ++ } ++ if (millivolts < 4000) ++ return 0x0f; ++ else { ++ millivolts -= 4000; ++ return millivolts/100; ++ } ++} ++ ++static unsigned int dcudc_2voltage(u_int8_t bits) ++{ ++ bits &= 0x1f; ++ if (bits < 0x08) ++ return 900 + bits * 300; ++ else if (bits < 0x10) ++ return 3300; ++ else ++ return 4000 + bits * 100; ++} ++ ++static u_int8_t dcdec_voltage(unsigned int millivolts) ++{ ++ if (millivolts < 900) ++ return 0; ++ else if (millivolts > 3300) ++ return 0x0f; ++ ++ millivolts -= 900; ++ return millivolts/300; ++} ++ ++static unsigned int dcdec_2voltage(u_int8_t bits) ++{ ++ bits &= 0x0f; ++ return 900 + bits*300; ++} ++ ++static u_int8_t dcdc_voltage(unsigned int millivolts) ++{ ++ if (millivolts < 900) ++ return 0; ++ else if (millivolts > 3600) ++ return 0x1f; ++ ++ if (millivolts < 1500) { ++ millivolts -= 900; ++ return millivolts/25; ++ } else { ++ millivolts -= 1500; ++ return 0x18 + millivolts/300; ++ } ++} ++ ++static unsigned int dcdc_2voltage(u_int8_t bits) ++{ ++ bits &= 0x1f; ++ if ((bits & 0x18) == 0x18) ++ return 1500 + ((bits & 0x7) * 300); ++ else ++ return 900 + (bits * 25); ++} ++ ++static u_int8_t dx_voltage(unsigned int millivolts) ++{ ++ if (millivolts < 900) ++ return 0; ++ else if (millivolts > 3300) ++ return 0x18; ++ ++ millivolts -= 900; ++ return millivolts/100; ++} ++ ++static unsigned int dx_2voltage(u_int8_t bits) ++{ ++ bits &= 0x1f; ++ return 900 + (bits * 100); ++} ++ ++static const u_int8_t regulator_registers[__NUM_PCF50606_REGULATORS] = { ++ [PCF50606_REGULATOR_DCD] = PCF50606_REG_DCDC1, ++ [PCF50606_REGULATOR_DCDE] = PCF50606_REG_DCDEC1, ++ [PCF50606_REGULATOR_DCUD] = PCF50606_REG_DCUDC1, ++ [PCF50606_REGULATOR_D1REG] = PCF50606_REG_D1REGC1, ++ [PCF50606_REGULATOR_D2REG] = PCF50606_REG_D2REGC1, ++ [PCF50606_REGULATOR_D3REG] = PCF50606_REG_D3REGC1, ++ [PCF50606_REGULATOR_LPREG] = PCF50606_REG_LPREGC1, ++ [PCF50606_REGULATOR_IOREG] = PCF50606_REG_IOREGC, ++}; ++ ++int pcf50606_onoff_set(struct pcf50606_data *pcf, ++ enum pcf50606_regulator_id reg, int on) ++{ ++ u_int8_t addr; ++ ++ if (reg >= __NUM_PCF50606_REGULATORS) ++ return -EINVAL; ++ ++ /* IOREG cannot be powered off since it powers the PMU I2C */ ++ if (reg == PCF50606_REGULATOR_IOREG) ++ return -EIO; ++ ++ addr = regulator_registers[reg]; ++ ++ if (on == 0) ++ reg_set_bit_mask(pcf, addr, 0xe0, 0x00); ++ else ++ reg_set_bit_mask(pcf, addr, 0xe0, 0xe0); ++ ++ return 0; ++} ++EXPORT_SYMBOL_GPL(pcf50606_onoff_set); ++ ++int pcf50606_onoff_get(struct pcf50606_data *pcf, ++ enum pcf50606_regulator_id reg) ++{ ++ u_int8_t val, addr; ++ ++ if (reg >= __NUM_PCF50606_REGULATORS) ++ return -EINVAL; ++ ++ addr = regulator_registers[reg]; ++ val = (reg_read(pcf, addr) & 0xe0) >> 5; ++ ++ /* PWREN1 = 1, PWREN2 = 1, see table 16 of datasheet */ ++ switch (val) { ++ case 0: ++ case 5: ++ return 0; ++ default: ++ return 1; ++ } ++} ++EXPORT_SYMBOL_GPL(pcf50606_onoff_get); ++ ++int pcf50606_voltage_set(struct pcf50606_data *pcf, ++ enum pcf50606_regulator_id reg, ++ unsigned int millivolts) ++{ ++ u_int8_t volt_bits; ++ u_int8_t regnr; ++ int rc; ++ ++ dev_dbg(&pcf->client.dev, "pcf=%p, reg=%d, mvolts=%d\n", pcf, reg, ++ millivolts); ++ ++ if (reg >= __NUM_PCF50606_REGULATORS) ++ return -EINVAL; ++ ++ if (millivolts > pcf->pdata->rails[reg].voltage.max) ++ return -EINVAL; ++ ++ switch (reg) { ++ case PCF50606_REGULATOR_DCD: ++ volt_bits = dcdc_voltage(millivolts); ++ rc = reg_set_bit_mask(pcf, PCF50606_REG_DCDC1, 0x1f, ++ volt_bits); ++ break; ++ case PCF50606_REGULATOR_DCDE: ++ volt_bits = dcdec_voltage(millivolts); ++ rc = reg_set_bit_mask(pcf, PCF50606_REG_DCDEC1, 0x0f, ++ volt_bits); ++ break; ++ case PCF50606_REGULATOR_DCUD: ++ volt_bits = dcudc_voltage(millivolts); ++ rc = reg_set_bit_mask(pcf, PCF50606_REG_DCUDC1, 0x1f, ++ volt_bits); ++ break; ++ case PCF50606_REGULATOR_D1REG: ++ case PCF50606_REGULATOR_D2REG: ++ case PCF50606_REGULATOR_D3REG: ++ regnr = PCF50606_REG_D1REGC1 + (reg - PCF50606_REGULATOR_D1REG); ++ volt_bits = dx_voltage(millivolts); ++ rc = reg_set_bit_mask(pcf, regnr, 0x1f, volt_bits); ++ break; ++ case PCF50606_REGULATOR_LPREG: ++ volt_bits = dx_voltage(millivolts); ++ rc = reg_set_bit_mask(pcf, PCF50606_REG_LPREGC1, 0x1f, ++ volt_bits); ++ break; ++ case PCF50606_REGULATOR_IOREG: ++ if (millivolts < 1800) ++ return -EINVAL; ++ volt_bits = dx_voltage(millivolts); ++ rc = reg_set_bit_mask(pcf, PCF50606_REG_IOREGC, 0x1f, ++ volt_bits); ++ break; ++ default: ++ return -EINVAL; ++ } ++ ++ return rc; ++} ++EXPORT_SYMBOL_GPL(pcf50606_voltage_set); ++ ++unsigned int pcf50606_voltage_get(struct pcf50606_data *pcf, ++ enum pcf50606_regulator_id reg) ++{ ++ u_int8_t volt_bits; ++ u_int8_t regnr; ++ unsigned int rc = 0; ++ ++ if (reg >= __NUM_PCF50606_REGULATORS) ++ return -EINVAL; ++ ++ switch (reg) { ++ case PCF50606_REGULATOR_DCD: ++ volt_bits = reg_read(pcf, PCF50606_REG_DCDC1) & 0x1f; ++ rc = dcdc_2voltage(volt_bits); ++ break; ++ case PCF50606_REGULATOR_DCDE: ++ volt_bits = reg_read(pcf, PCF50606_REG_DCDEC1) & 0x0f; ++ rc = dcdec_2voltage(volt_bits); ++ break; ++ case PCF50606_REGULATOR_DCUD: ++ volt_bits = reg_read(pcf, PCF50606_REG_DCUDC1) & 0x1f; ++ rc = dcudc_2voltage(volt_bits); ++ break; ++ case PCF50606_REGULATOR_D1REG: ++ case PCF50606_REGULATOR_D2REG: ++ case PCF50606_REGULATOR_D3REG: ++ regnr = PCF50606_REG_D1REGC1 + (reg - PCF50606_REGULATOR_D1REG); ++ volt_bits = reg_read(pcf, regnr) & 0x1f; ++ if (volt_bits > 0x18) ++ volt_bits = 0x18; ++ rc = dx_2voltage(volt_bits); ++ break; ++ case PCF50606_REGULATOR_LPREG: ++ volt_bits = reg_read(pcf, PCF50606_REG_LPREGC1) & 0x1f; ++ if (volt_bits > 0x18) ++ volt_bits = 0x18; ++ rc = dx_2voltage(volt_bits); ++ break; ++ case PCF50606_REGULATOR_IOREG: ++ volt_bits = reg_read(pcf, PCF50606_REG_IOREGC) & 0x1f; ++ if (volt_bits > 0x18) ++ volt_bits = 0x18; ++ rc = dx_2voltage(volt_bits); ++ break; ++ default: ++ return -EINVAL; ++ } ++ ++ return rc; ++} ++EXPORT_SYMBOL_GPL(pcf50606_voltage_get); ++ ++/* go into 'STANDBY' mode, i.e. power off the main CPU and peripherals */ ++void pcf50606_go_standby(void) ++{ ++ reg_write(pcf50606_global, PCF50606_REG_OOCC1, ++ PCF50606_OOCC1_GOSTDBY); ++} ++EXPORT_SYMBOL_GPL(pcf50606_go_standby); ++ ++void pcf50606_gpo0_set(struct pcf50606_data *pcf, int on) ++{ ++ u_int8_t val; ++ ++ if (on) ++ val = 0x07; ++ else ++ val = 0x0f; ++ ++ reg_set_bit_mask(pcf, PCF50606_REG_GPOC1, 0x0f, val); ++} ++EXPORT_SYMBOL_GPL(pcf50606_gpo0_set); ++ ++int pcf50606_gpo0_get(struct pcf50606_data *pcf) ++{ ++ u_int8_t reg = reg_read(pcf, PCF50606_REG_GPOC1) & 0x0f; ++ ++ if (reg == 0x07 || reg == 0x08) ++ return 1; ++ ++ return 0; ++} ++EXPORT_SYMBOL_GPL(pcf50606_gpo0_get); ++ ++static void pcf50606_work(struct work_struct *work) ++{ ++ struct pcf50606_data *pcf = ++ container_of(work, struct pcf50606_data, work); ++ u_int8_t pcfirq[3]; ++ int ret; ++ ++ mutex_lock(&pcf->working_lock); ++ pcf->working = 1; ++ ++ /* sanity */ ++ if (!&pcf->client.dev) ++ goto bail; ++ ++ /* ++ * if we are presently suspending, we are not in a position to deal ++ * with pcf50606 interrupts at all. ++ * ++ * Because we didn't clear the int pending registers, there will be ++ * no edge / interrupt waiting for us when we wake. But it is OK ++ * because at the end of our resume, we call this workqueue function ++ * gratuitously, clearing the pending register and re-enabling ++ * servicing this interrupt. ++ */ ++ ++ if ((pcf->suspend_state == PCF50606_SS_STARTING_SUSPEND) || ++ (pcf->suspend_state == PCF50606_SS_COMPLETED_SUSPEND)) ++ goto bail; ++ ++ /* ++ * If we are inside suspend -> resume completion time we don't attempt ++ * service until we have fully resumed. Although we could talk to the ++ * device as soon as I2C is up, the regs in the device which we might ++ * choose to modify as part of the service action have not been ++ * reloaded with their pre-suspend states yet. Therefore we will ++ * defer our service if we are called like that until our resume has ++ * completed. ++ * ++ * This shouldn't happen any more because we disable servicing this ++ * interrupt in suspend and don't re-enable it until resume is ++ * completed. ++ */ ++ ++ if (pcf->suspend_state && ++ (pcf->suspend_state != PCF50606_SS_COMPLETED_RESUME)) ++ goto reschedule; ++ ++ /* this is the case early in resume! Sanity check! */ ++ if (i2c_get_clientdata(&pcf->client) == NULL) ++ goto reschedule; ++ ++ /* ++ * p35 pcf50606 datasheet rev 2.2: ++ * ''The system controller shall read all interrupt registers in ++ * one I2C read action'' ++ * because if you don't INT# gets stuck asserted forever after a ++ * while ++ */ ++ ret = i2c_smbus_read_i2c_block_data(&pcf->client, PCF50606_REG_INT1, ++ sizeof(pcfirq), pcfirq); ++ if (ret != sizeof(pcfirq)) { ++ DEBUGPC("Oh crap PMU IRQ register read failed %d\n", ret); ++ /* ++ * it shouldn't fail, we no longer attempt to use ++ * I2C while it can be suspended. But we don't have ++ * much option but to retry if if it ever did fail, ++ * because if we don't service the interrupt to clear ++ * it, we will never see another PMU interrupt edge. ++ */ ++ goto reschedule; ++ } ++ ++ /* hey did we just resume? (because we don't get here unless we are ++ * running normally or the first call after resumption) ++ * ++ * pcf50606 resume is really really over now then. ++ */ ++ if (pcf->suspend_state != PCF50606_SS_RUNNING) { ++ pcf->suspend_state = PCF50606_SS_RUNNING; ++ ++ /* peek at the IRQ reason, if power button then set a flag ++ * so that we do not signal the event to userspace ++ */ ++ if (pcfirq[0] & (PCF50606_INT1_ONKEYF | PCF50606_INT1_ONKEYR)) { ++ pcf->suppress_onkey_events = 1; ++ dev_dbg(&pcf->client.dev, ++ "Wake by ONKEY, suppressing ONKEY events"); ++ } else { ++ pcf->suppress_onkey_events = 0; ++ } ++ } ++ ++ if (!pcf->coldplug_done) { ++ DEBUGPC("PMU Coldplug init\n"); ++ ++ /* we used SECOND to kick ourselves started -- turn it off */ ++ pcfirq[0] &= ~PCF50606_INT1_SECOND; ++ reg_set_bit_mask(pcf, PCF50606_REG_INT1M, PCF50606_INT1_SECOND, ++ PCF50606_INT1_SECOND); ++ ++ /* coldplug the USB if present */ ++ if (__reg_read(pcf, PCF50606_REG_OOCS) & PCF50606_OOCS_EXTON) { ++ /* Charger inserted */ ++ DEBUGPC("COLD CHGINS "); ++ input_report_key(pcf->input_dev, KEY_BATTERY, 1); ++ apm_queue_event(APM_POWER_STATUS_CHANGE); ++ pcf->flags |= PCF50606_F_CHG_PRESENT; ++ if (pcf->pdata->cb) ++ pcf->pdata->cb(&pcf->client.dev, ++ PCF50606_FEAT_MBC, ++ PMU_EVT_INSERT); ++ } ++ ++ pcf->coldplug_done = 1; ++ } ++ ++ ++ dev_dbg(&pcf->client.dev, "INT1=0x%02x INT2=0x%02x INT3=0x%02x:", ++ pcfirq[0], pcfirq[1], pcfirq[2]); ++ ++ if (pcfirq[0] & PCF50606_INT1_ONKEYF) { ++ /* ONKEY falling edge (start of button press) */ ++ pcf->flags |= PCF50606_F_PWR_PRESSED; ++ if (!pcf->suppress_onkey_events) { ++ DEBUGPC("ONKEYF "); ++ input_report_key(pcf->input_dev, KEY_POWER, 1); ++ } else { ++ DEBUGPC("ONKEYF(unreported) "); ++ } ++ } ++ if (pcfirq[0] & PCF50606_INT1_ONKEY1S) { ++ /* ONKEY pressed for more than 1 second */ ++ pcf->onkey_seconds = 0; ++ DEBUGPC("ONKEY1S "); ++ /* Tell PMU we are taking care of this */ ++ reg_set_bit_mask(pcf, PCF50606_REG_OOCC1, ++ PCF50606_OOCC1_TOTRST, ++ PCF50606_OOCC1_TOTRST); ++ /* enable SECOND interrupt (hz tick) */ ++ reg_clear_bits(pcf, PCF50606_REG_INT1M, PCF50606_INT1_SECOND); ++ } ++ if (pcfirq[0] & PCF50606_INT1_ONKEYR) { ++ /* ONKEY rising edge (end of button press) */ ++ pcf->flags &= ~PCF50606_F_PWR_PRESSED; ++ pcf->onkey_seconds = -1; ++ if (!pcf->suppress_onkey_events) { ++ DEBUGPC("ONKEYR "); ++ input_report_key(pcf->input_dev, KEY_POWER, 0); ++ } else { ++ DEBUGPC("ONKEYR(suppressed) "); ++ /* don't suppress any more power button events */ ++ pcf->suppress_onkey_events = 0; ++ } ++ /* disable SECOND interrupt in case RTC didn't ++ * request it */ ++ if (!(pcf->flags & PCF50606_F_RTC_SECOND)) ++ reg_set_bit_mask(pcf, PCF50606_REG_INT1M, ++ PCF50606_INT1_SECOND, ++ PCF50606_INT1_SECOND); ++ } ++ if (pcfirq[0] & PCF50606_INT1_EXTONR) { ++ DEBUGPC("EXTONR "); ++ input_report_key(pcf->input_dev, KEY_POWER2, 1); ++ } ++ if (pcfirq[0] & PCF50606_INT1_EXTONF) { ++ DEBUGPC("EXTONF "); ++ input_report_key(pcf->input_dev, KEY_POWER2, 0); ++ } ++ if (pcfirq[0] & PCF50606_INT1_SECOND) { ++ DEBUGPC("SECOND "); ++ if (pcf->flags & PCF50606_F_RTC_SECOND) ++ rtc_update_irq(pcf->rtc, 1, ++ RTC_PF | RTC_IRQF); ++ ++ if (pcf->onkey_seconds >= 0 && ++ pcf->flags & PCF50606_F_PWR_PRESSED) { ++ DEBUGPC("ONKEY_SECONDS(%u, OOCC1=0x%02x) ", ++ pcf->onkey_seconds, ++ reg_read(pcf, PCF50606_REG_OOCC1)); ++ pcf->onkey_seconds++; ++ if (pcf->onkey_seconds >= ++ pcf->pdata->onkey_seconds_required) { ++ /* Ask init to do 'ctrlaltdel' */ ++ /* ++ * currently Linux reacts badly to issuing a ++ * signal to PID #1 before init is started. ++ * What happens is that the next kernel thread ++ * to start, which is the JFFS2 Garbage ++ * collector in our case, gets the signal ++ * instead and proceeds to fail to fork -- ++ * which is very bad. Therefore we confirm ++ * PID #1 exists before issuing the signal ++ */ ++ if (find_task_by_pid_ns(1, &init_pid_ns)) { ++ kill_pid(task_pid(find_task_by_pid_ns(1, ++ &init_pid_ns)), SIGINT, 1); ++ DEBUGPC("SIGINT(init) "); ++ } ++ /* FIXME: what to do if userspace doesn't ++ * shut down? Do we want to force it? */ ++ } ++ } ++ } ++ if (pcfirq[0] & PCF50606_INT1_ALARM) { ++ DEBUGPC("ALARM "); ++ if (pcf->pdata->used_features & PCF50606_FEAT_RTC) ++ rtc_update_irq(pcf->rtc, 1, ++ RTC_AF | RTC_IRQF); ++ } ++ ++ if (pcfirq[1] & PCF50606_INT2_CHGINS) { ++ /* Charger inserted */ ++ DEBUGPC("CHGINS "); ++ input_report_key(pcf->input_dev, KEY_BATTERY, 1); ++ apm_queue_event(APM_POWER_STATUS_CHANGE); ++ pcf->flags |= PCF50606_F_CHG_PRESENT; ++ if (pcf->pdata->cb) ++ pcf->pdata->cb(&pcf->client.dev, ++ PCF50606_FEAT_MBC, PMU_EVT_INSERT); ++ /* FIXME: how to signal this to userspace */ ++ } ++ if (pcfirq[1] & PCF50606_INT2_CHGRM) { ++ /* Charger removed */ ++ DEBUGPC("CHGRM "); ++ input_report_key(pcf->input_dev, KEY_BATTERY, 0); ++ apm_queue_event(APM_POWER_STATUS_CHANGE); ++ pcf->flags &= ~(PCF50606_F_CHG_MASK|PCF50606_F_CHG_PRESENT); ++ if (pcf->pdata->cb) ++ pcf->pdata->cb(&pcf->client.dev, ++ PCF50606_FEAT_MBC, PMU_EVT_INSERT); ++ /* FIXME: how signal this to userspace */ ++ } ++ if (pcfirq[1] & PCF50606_INT2_CHGFOK) { ++ /* Battery ready for fast charging */ ++ DEBUGPC("CHGFOK "); ++ pcf->flags |= PCF50606_F_CHG_FOK; ++ /* FIXME: how to signal this to userspace */ ++ } ++ if (pcfirq[1] & PCF50606_INT2_CHGERR) { ++ /* Error in charge mode */ ++ DEBUGPC("CHGERR "); ++ pcf->flags |= PCF50606_F_CHG_ERR; ++ pcf->flags &= ~(PCF50606_F_CHG_FOK|PCF50606_F_CHG_READY); ++ /* FIXME: how to signal this to userspace */ ++ } ++ if (pcfirq[1] & PCF50606_INT2_CHGFRDY) { ++ /* Fast charge completed */ ++ DEBUGPC("CHGFRDY "); ++ pcf->flags |= PCF50606_F_CHG_READY; ++ pcf->flags &= ~PCF50606_F_CHG_FOK; ++ /* FIXME: how to signal this to userspace */ ++ } ++ if (pcfirq[1] & PCF50606_INT2_CHGPROT) { ++ /* Charging protection interrupt */ ++ DEBUGPC("CHGPROT "); ++ pcf->flags &= ~(PCF50606_F_CHG_FOK|PCF50606_F_CHG_READY); ++ /* FIXME: signal this to userspace */ ++ } ++ if (pcfirq[1] & PCF50606_INT2_CHGWD10S) { ++ /* Charger watchdog will expire in 10 seconds */ ++ DEBUGPC("CHGWD10S "); ++ reg_set_bit_mask(pcf, PCF50606_REG_OOCC1, ++ PCF50606_OOCC1_WDTRST, ++ PCF50606_OOCC1_WDTRST); ++ } ++ if (pcfirq[1] & PCF50606_INT2_CHGWDEXP) { ++ /* Charger watchdog expires */ ++ DEBUGPC("CHGWDEXP "); ++ /* FIXME: how to signal this to userspace */ ++ } ++ ++ if (pcfirq[2] & PCF50606_INT3_ADCRDY) { ++ /* ADC result ready */ ++ DEBUGPC("ADCRDY "); ++ } ++ if (pcfirq[2] & PCF50606_INT3_ACDINS) { ++ /* Accessory insertion detected */ ++ DEBUGPC("ACDINS "); ++ if (pcf->pdata->cb) ++ pcf->pdata->cb(&pcf->client.dev, ++ PCF50606_FEAT_ACD, PMU_EVT_INSERT); ++ } ++ if (pcfirq[2] & PCF50606_INT3_ACDREM) { ++ /* Accessory removal detected */ ++ DEBUGPC("ACDREM "); ++ if (pcf->pdata->cb) ++ pcf->pdata->cb(&pcf->client.dev, ++ PCF50606_FEAT_ACD, PMU_EVT_REMOVE); ++ } ++ /* FIXME: TSCPRES */ ++ if (pcfirq[2] & PCF50606_INT3_LOWBAT) { ++ if (__reg_read(pcf, PCF50606_REG_OOCS) & PCF50606_OOCS_EXTON) { ++ /* ++ * hey no need to freak out, we have some kind of ++ * valid charger power ++ */ ++ DEBUGPC("(NO)BAT "); ++ } else { ++ /* Really low battery voltage, we have 8 seconds left */ ++ DEBUGPC("LOWBAT "); ++ /* ++ * currently Linux reacts badly to issuing a signal to ++ * PID #1 before init is started. What happens is that ++ * the next kernel thread to start, which is the JFFS2 ++ * Garbage collector in our case, gets the signal ++ * instead and proceeds to fail to fork -- which is ++ * very bad. Therefore we confirm PID #1 exists ++ * before issuing SPIGPWR ++ */ ++ if (find_task_by_pid_ns(1, &init_pid_ns)) { ++ apm_queue_event(APM_LOW_BATTERY); ++ DEBUGPC("SIGPWR(init) "); ++ kill_pid(task_pid(find_task_by_pid_ns(1, &init_pid_ns)), SIGPWR, 1); ++ } else ++ /* ++ * well, our situation is like this: we do not ++ * have any external power, we have a low ++ * battery and since PID #1 doesn't exist yet, ++ * we are early in the boot, likely before ++ * rootfs mount. We should just call it a day ++ */ ++ apm_queue_event(APM_CRITICAL_SUSPEND); ++ } ++ /* Tell PMU we are taking care of this */ ++ reg_set_bit_mask(pcf, PCF50606_REG_OOCC1, ++ PCF50606_OOCC1_TOTRST, ++ PCF50606_OOCC1_TOTRST); ++ } ++ if (pcfirq[2] & PCF50606_INT3_HIGHTMP) { ++ /* High temperature */ ++ DEBUGPC("HIGHTMP "); ++ apm_queue_event(APM_CRITICAL_SUSPEND); ++ } ++ ++ DEBUGPC("\n"); ++ ++bail: ++ pcf->working = 0; ++ input_sync(pcf->input_dev); ++ put_device(&pcf->client.dev); ++ mutex_unlock(&pcf->working_lock); ++ ++ return; ++ ++reschedule: ++ ++ if ((pcf->suspend_state != PCF50606_SS_STARTING_SUSPEND) && ++ (pcf->suspend_state != PCF50606_SS_COMPLETED_SUSPEND)) { ++ msleep(10); ++ dev_info(&pcf->client.dev, "rescheduling interrupt service\n"); ++ } ++ if (!schedule_work(&pcf->work)) ++ dev_err(&pcf->client.dev, "int service reschedule failed\n"); ++ ++ /* we don't put the device here, hold it for next time */ ++ mutex_unlock(&pcf->working_lock); ++} ++ ++static irqreturn_t pcf50606_irq(int irq, void *_pcf) ++{ ++ struct pcf50606_data *pcf = _pcf; ++ ++ dev_dbg(&pcf->client.dev, "entering(irq=%u, pcf=%p): scheduling work\n", ++ irq, _pcf); ++ get_device(&pcf->client.dev); ++ if (!schedule_work(&pcf->work) && !pcf->working) ++ dev_err(&pcf->client.dev, "pcf irq work already queued.\n"); ++ ++ return IRQ_HANDLED; ++} ++ ++static u_int16_t adc_to_batt_millivolts(u_int16_t adc) ++{ ++ u_int16_t mvolts; ++ ++ mvolts = (adc * 6000) / 1024; ++ ++ return mvolts; ++} ++ ++#define BATTVOLT_SCALE_START 2800 ++#define BATTVOLT_SCALE_END 4200 ++#define BATTVOLT_SCALE_DIVIDER ((BATTVOLT_SCALE_END - BATTVOLT_SCALE_START)/100) ++ ++static u_int8_t battvolt_scale(u_int16_t battvolt) ++{ ++ /* FIXME: this linear scale is completely bogus */ ++ u_int16_t battvolt_relative = battvolt - BATTVOLT_SCALE_START; ++ unsigned int percent = battvolt_relative / BATTVOLT_SCALE_DIVIDER; ++ ++ return percent; ++} ++ ++u_int16_t pcf50606_battvolt(struct pcf50606_data *pcf) ++{ ++ u_int16_t adc; ++ adc = adc_read(pcf, PCF50606_ADCMUX_BATVOLT_RES, NULL); ++ ++ return adc_to_batt_millivolts(adc); ++} ++EXPORT_SYMBOL_GPL(pcf50606_battvolt); ++ ++static ssize_t show_battvolt(struct device *dev, struct device_attribute *attr, ++ char *buf) ++{ ++ struct i2c_client *client = to_i2c_client(dev); ++ struct pcf50606_data *pcf = i2c_get_clientdata(client); ++ ++ return sprintf(buf, "%u\n", pcf50606_battvolt(pcf)); ++} ++static DEVICE_ATTR(battvolt, S_IRUGO | S_IWUSR, show_battvolt, NULL); ++ ++static int reg_id_by_name(const char *name) ++{ ++ int reg_id; ++ ++ if (!strcmp(name, "voltage_dcd")) ++ reg_id = PCF50606_REGULATOR_DCD; ++ else if (!strcmp(name, "voltage_dcde")) ++ reg_id = PCF50606_REGULATOR_DCDE; ++ else if (!strcmp(name, "voltage_dcud")) ++ reg_id = PCF50606_REGULATOR_DCUD; ++ else if (!strcmp(name, "voltage_d1reg")) ++ reg_id = PCF50606_REGULATOR_D1REG; ++ else if (!strcmp(name, "voltage_d2reg")) ++ reg_id = PCF50606_REGULATOR_D2REG; ++ else if (!strcmp(name, "voltage_d3reg")) ++ reg_id = PCF50606_REGULATOR_D3REG; ++ else if (!strcmp(name, "voltage_lpreg")) ++ reg_id = PCF50606_REGULATOR_LPREG; ++ else if (!strcmp(name, "voltage_ioreg")) ++ reg_id = PCF50606_REGULATOR_IOREG; ++ else ++ reg_id = -1; ++ ++ return reg_id; ++} ++ ++static ssize_t show_vreg(struct device *dev, struct device_attribute *attr, ++ char *buf) ++{ ++ struct i2c_client *client = to_i2c_client(dev); ++ struct pcf50606_data *pcf = i2c_get_clientdata(client); ++ unsigned int reg_id; ++ ++ reg_id = reg_id_by_name(attr->attr.name); ++ if (reg_id < 0) ++ return 0; ++ ++ if (pcf50606_onoff_get(pcf, reg_id) > 0) ++ return sprintf(buf, "%u\n", pcf50606_voltage_get(pcf, reg_id)); ++ else ++ return strlcpy(buf, "0\n", PAGE_SIZE); ++} ++ ++static ssize_t set_vreg(struct device *dev, struct device_attribute *attr, ++ const char *buf, size_t count) ++{ ++ struct i2c_client *client = to_i2c_client(dev); ++ struct pcf50606_data *pcf = i2c_get_clientdata(client); ++ unsigned long mvolts = simple_strtoul(buf, NULL, 10); ++ unsigned int reg_id; ++ ++ reg_id = reg_id_by_name(attr->attr.name); ++ if (reg_id < 0) ++ return -EIO; ++ ++ dev_dbg(dev, "attempting to set %s(%d) to %lu mvolts\n", ++ attr->attr.name, reg_id, mvolts); ++ ++ if (mvolts == 0) { ++ pcf50606_onoff_set(pcf, reg_id, 0); ++ } else { ++ if (pcf50606_voltage_set(pcf, reg_id, mvolts) < 0) { ++ dev_warn(dev, "refusing to set %s(%d) to %lu mvolts " ++ "(max=%u)\n", attr->attr.name, reg_id, mvolts, ++ pcf->pdata->rails[reg_id].voltage.max); ++ return -EINVAL; ++ } ++ pcf50606_onoff_set(pcf, reg_id, 1); ++ } ++ ++ return count; ++} ++ ++static DEVICE_ATTR(voltage_dcd, S_IRUGO | S_IWUSR, show_vreg, set_vreg); ++static DEVICE_ATTR(voltage_dcde, S_IRUGO | S_IWUSR, show_vreg, set_vreg); ++static DEVICE_ATTR(voltage_dcud, S_IRUGO | S_IWUSR, show_vreg, set_vreg); ++static DEVICE_ATTR(voltage_d1reg, S_IRUGO | S_IWUSR, show_vreg, set_vreg); ++static DEVICE_ATTR(voltage_d2reg, S_IRUGO | S_IWUSR, show_vreg, set_vreg); ++static DEVICE_ATTR(voltage_d3reg, S_IRUGO | S_IWUSR, show_vreg, set_vreg); ++static DEVICE_ATTR(voltage_lpreg, S_IRUGO | S_IWUSR, show_vreg, set_vreg); ++static DEVICE_ATTR(voltage_ioreg, S_IRUGO | S_IWUSR, show_vreg, set_vreg); ++ ++/*********************************************************************** ++ * Charger Control ++ ***********************************************************************/ ++ ++/* Enable/disable fast charging (500mA in the GTA01) */ ++void pcf50606_charge_fast(struct pcf50606_data *pcf, int on) ++{ ++ if (!(pcf->pdata->used_features & PCF50606_FEAT_MBC)) ++ return; ++ ++ if (on) { ++ /* We can allow PCF to automatically charge ++ * using Ifast */ ++ pcf->flags |= PCF50606_F_CHG_FAST; ++ reg_set_bit_mask(pcf, PCF50606_REG_MBCC1, ++ PCF50606_MBCC1_AUTOFST, ++ PCF50606_MBCC1_AUTOFST); ++ } else { ++ pcf->flags &= ~PCF50606_F_CHG_FAST; ++ /* disable automatic fast-charge */ ++ reg_clear_bits(pcf, PCF50606_REG_MBCC1, ++ PCF50606_MBCC1_AUTOFST); ++ /* switch to idle mode to abort existing charge ++ * process */ ++ reg_set_bit_mask(pcf, PCF50606_REG_MBCC1, ++ PCF50606_MBCC1_CHGMOD_MASK, ++ PCF50606_MBCC1_CHGMOD_IDLE); ++ } ++} ++EXPORT_SYMBOL_GPL(pcf50606_charge_fast); ++ ++static inline u_int16_t adc_to_rntc(struct pcf50606_data *pcf, u_int16_t adc) ++{ ++ u_int32_t r_ntc = (adc * (u_int32_t)pcf->pdata->r_fix_batt) ++ / (1023 - adc); ++ ++ return r_ntc; ++} ++ ++static inline int16_t rntc_to_temp(u_int16_t rntc) ++{ ++ int i; ++ ++ for (i = 0; i < ARRAY_SIZE(ntc_table_10k_3370B); i++) { ++ if (rntc > ntc_table_10k_3370B[i]) ++ return i - 10; /* First element is -10 */ ++ } ++ return -99; /* Below our range */ ++} ++ ++static ssize_t show_battemp(struct device *dev, struct device_attribute *attr, ++ char *buf) ++{ ++ struct i2c_client *client = to_i2c_client(dev); ++ struct pcf50606_data *pcf = i2c_get_clientdata(client); ++ u_int16_t adc; ++ ++ adc = adc_read(pcf, PCF50606_ADCMUX_BATTEMP, NULL); ++ ++ return sprintf(buf, "%d\n", rntc_to_temp(adc_to_rntc(pcf, adc))); ++} ++static DEVICE_ATTR(battemp, S_IRUGO | S_IWUSR, show_battemp, NULL); ++ ++static inline int16_t adc_to_chg_milliamps(struct pcf50606_data *pcf, ++ u_int16_t adc_adcin1, ++ u_int16_t adc_batvolt) ++{ ++ int32_t res = (adc_adcin1 - adc_batvolt) * 2400; ++ return (res * 1000) / (pcf->pdata->r_sense_milli * 1024); ++} ++ ++static ssize_t show_chgcur(struct device *dev, struct device_attribute *attr, ++ char *buf) ++{ ++ struct i2c_client *client = to_i2c_client(dev); ++ struct pcf50606_data *pcf = i2c_get_clientdata(client); ++ u_int16_t adc_batvolt, adc_adcin1; ++ int16_t ma; ++ ++ adc_batvolt = adc_read(pcf, PCF50606_ADCMUX_BATVOLT_ADCIN1, ++ &adc_adcin1); ++ ma = adc_to_chg_milliamps(pcf, adc_adcin1, adc_batvolt); ++ ++ return sprintf(buf, "%d\n", ma); ++} ++static DEVICE_ATTR(chgcur, S_IRUGO | S_IWUSR, show_chgcur, NULL); ++ ++static const char *chgmode_names[] = { ++ [PCF50606_MBCC1_CHGMOD_QUAL] = "qualification", ++ [PCF50606_MBCC1_CHGMOD_PRE] = "pre", ++ [PCF50606_MBCC1_CHGMOD_TRICKLE] = "trickle", ++ [PCF50606_MBCC1_CHGMOD_FAST_CCCV] = "fast_cccv", ++ [PCF50606_MBCC1_CHGMOD_FAST_NOCC] = "fast_nocc", ++ [PCF50606_MBCC1_CHGMOD_FAST_NOCV] = "fast_nocv", ++ [PCF50606_MBCC1_CHGMOD_FAST_SW] = "fast_switch", ++ [PCF50606_MBCC1_CHGMOD_IDLE] = "idle", ++}; ++ ++static ssize_t show_chgmode(struct device *dev, struct device_attribute *attr, ++ char *buf) ++{ ++ struct i2c_client *client = to_i2c_client(dev); ++ struct pcf50606_data *pcf = i2c_get_clientdata(client); ++ u_int8_t mbcc1 = reg_read(pcf, PCF50606_REG_MBCC1); ++ u_int8_t chgmod = (mbcc1 & PCF50606_MBCC1_CHGMOD_MASK); ++ ++ return sprintf(buf, "%s\n", chgmode_names[chgmod]); ++} ++ ++static ssize_t set_chgmode(struct device *dev, struct device_attribute *attr, ++ const char *buf, size_t count) ++{ ++ struct i2c_client *client = to_i2c_client(dev); ++ struct pcf50606_data *pcf = i2c_get_clientdata(client); ++ u_int8_t mbcc1 = reg_read(pcf, PCF50606_REG_MBCC1); ++ ++ mbcc1 &= ~PCF50606_MBCC1_CHGMOD_MASK; ++ ++ if (!strcmp(buf, "qualification")) ++ mbcc1 |= PCF50606_MBCC1_CHGMOD_QUAL; ++ else if (!strcmp(buf, "pre")) ++ mbcc1 |= PCF50606_MBCC1_CHGMOD_PRE; ++ else if (!strcmp(buf, "trickle")) ++ mbcc1 |= PCF50606_MBCC1_CHGMOD_TRICKLE; ++ else if (!strcmp(buf, "fast_cccv")) ++ mbcc1 |= PCF50606_MBCC1_CHGMOD_FAST_CCCV; ++ /* We don't allow the other fast modes for security reasons */ ++ else if (!strcmp(buf, "idle")) ++ mbcc1 |= PCF50606_MBCC1_CHGMOD_IDLE; ++ else ++ return -EINVAL; ++ ++ reg_write(pcf, PCF50606_REG_MBCC1, mbcc1); ++ ++ return count; ++} ++ ++static DEVICE_ATTR(chgmode, S_IRUGO | S_IWUSR, show_chgmode, set_chgmode); ++ ++static const char *chgstate_names[] = { ++ [PCF50606_B_CHG_FAST] = "fast_enabled", ++ [PCF50606_B_CHG_PRESENT] = "present", ++ [PCF50606_B_CHG_FOK] = "fast_ok", ++ [PCF50606_B_CHG_ERR] = "error", ++ [PCF50606_B_CHG_PROT] = "protection", ++ [PCF50606_B_CHG_READY] = "ready", ++}; ++ ++static ssize_t show_chgstate(struct device *dev, struct device_attribute *attr, ++ char *buf) ++{ ++ struct i2c_client *client = to_i2c_client(dev); ++ struct pcf50606_data *pcf = i2c_get_clientdata(client); ++ char *b = buf; ++ int i; ++ ++ for (i = 0; i < 32; i++) ++ if (pcf->flags & (1 << i) && i < ARRAY_SIZE(chgstate_names)) ++ b += sprintf(b, "%s ", chgstate_names[i]); ++ ++ if (b > buf) ++ b += sprintf(b, "\n"); ++ ++ return b - buf; ++} ++static DEVICE_ATTR(chgstate, S_IRUGO | S_IWUSR, show_chgstate, NULL); ++ ++/*********************************************************************** ++ * APM emulation ++ ***********************************************************************/ ++ ++static void pcf50606_get_power_status(struct apm_power_info *info) ++{ ++ struct pcf50606_data *pcf = pcf50606_global; ++ u_int8_t mbcc1 = reg_read(pcf, PCF50606_REG_MBCC1); ++ u_int8_t chgmod = mbcc1 & PCF50606_MBCC1_CHGMOD_MASK; ++ u_int16_t battvolt = pcf50606_battvolt(pcf); ++ ++ if (reg_read(pcf, PCF50606_REG_OOCS) & PCF50606_OOCS_EXTON) ++ info->ac_line_status = APM_AC_ONLINE; ++ else ++ info->ac_line_status = APM_AC_OFFLINE; ++ ++ switch (chgmod) { ++ case PCF50606_MBCC1_CHGMOD_QUAL: ++ case PCF50606_MBCC1_CHGMOD_PRE: ++ case PCF50606_MBCC1_CHGMOD_IDLE: ++ info->battery_life = battvolt_scale(battvolt); ++ break; ++ default: ++ info->battery_status = APM_BATTERY_STATUS_CHARGING; ++ info->battery_flag = APM_BATTERY_FLAG_CHARGING; ++ break; ++ } ++} ++ ++/*********************************************************************** ++ * RTC ++ ***********************************************************************/ ++ ++struct pcf50606_time { ++ u_int8_t sec; ++ u_int8_t min; ++ u_int8_t hour; ++ u_int8_t wkday; ++ u_int8_t day; ++ u_int8_t month; ++ u_int8_t year; ++}; ++ ++static void pcf2rtc_time(struct rtc_time *rtc, struct pcf50606_time *pcf) ++{ ++ rtc->tm_sec = bcd2bin(pcf->sec); ++ rtc->tm_min = bcd2bin(pcf->min); ++ rtc->tm_hour = bcd2bin(pcf->hour); ++ rtc->tm_wday = bcd2bin(pcf->wkday); ++ rtc->tm_mday = bcd2bin(pcf->day); ++ rtc->tm_mon = bcd2bin(pcf->month); ++ rtc->tm_year = bcd2bin(pcf->year) + 100; ++} ++ ++static void rtc2pcf_time(struct pcf50606_time *pcf, struct rtc_time *rtc) ++{ ++ pcf->sec = bin2bcd(rtc->tm_sec); ++ pcf->min = bin2bcd(rtc->tm_min); ++ pcf->hour = bin2bcd(rtc->tm_hour); ++ pcf->wkday = bin2bcd(rtc->tm_wday); ++ pcf->day = bin2bcd(rtc->tm_mday); ++ pcf->month = bin2bcd(rtc->tm_mon); ++ pcf->year = bin2bcd(rtc->tm_year - 100); ++} ++ ++static int pcf50606_rtc_ioctl(struct device *dev, unsigned int cmd, ++ unsigned long arg) ++{ ++ struct i2c_client *client = to_i2c_client(dev); ++ struct pcf50606_data *pcf = i2c_get_clientdata(client); ++ ++ switch (cmd) { ++ case RTC_AIE_OFF: ++ /* disable the alarm interrupt */ ++ reg_set_bit_mask(pcf, PCF50606_REG_INT1M, ++ PCF50606_INT1_ALARM, PCF50606_INT1_ALARM); ++ return 0; ++ case RTC_AIE_ON: ++ /* enable the alarm interrupt */ ++ reg_clear_bits(pcf, PCF50606_REG_INT1M, PCF50606_INT1_ALARM); ++ return 0; ++ case RTC_PIE_OFF: ++ /* disable periodic interrupt (hz tick) */ ++ pcf->flags &= ~PCF50606_F_RTC_SECOND; ++ reg_set_bit_mask(pcf, PCF50606_REG_INT1M, ++ PCF50606_INT1_SECOND, PCF50606_INT1_SECOND); ++ return 0; ++ case RTC_PIE_ON: ++ /* ensable periodic interrupt (hz tick) */ ++ pcf->flags |= PCF50606_F_RTC_SECOND; ++ reg_clear_bits(pcf, PCF50606_REG_INT1M, PCF50606_INT1_SECOND); ++ return 0; ++ } ++ return -ENOIOCTLCMD; ++} ++ ++static int pcf50606_rtc_read_time(struct device *dev, struct rtc_time *tm) ++{ ++ struct i2c_client *client = to_i2c_client(dev); ++ struct pcf50606_data *pcf = i2c_get_clientdata(client); ++ struct pcf50606_time pcf_tm; ++ ++ mutex_lock(&pcf->lock); ++ pcf_tm.sec = __reg_read(pcf, PCF50606_REG_RTCSC); ++ pcf_tm.min = __reg_read(pcf, PCF50606_REG_RTCMN); ++ pcf_tm.hour = __reg_read(pcf, PCF50606_REG_RTCHR); ++ pcf_tm.wkday = __reg_read(pcf, PCF50606_REG_RTCWD); ++ pcf_tm.day = __reg_read(pcf, PCF50606_REG_RTCDT); ++ pcf_tm.month = __reg_read(pcf, PCF50606_REG_RTCMT); ++ pcf_tm.year = __reg_read(pcf, PCF50606_REG_RTCYR); ++ mutex_unlock(&pcf->lock); ++ ++ dev_dbg(dev, "PCF_TIME: %02x.%02x.%02x %02x:%02x:%02x\n", ++ pcf_tm.day, pcf_tm.month, pcf_tm.year, ++ pcf_tm.hour, pcf_tm.min, pcf_tm.sec); ++ ++ pcf2rtc_time(tm, &pcf_tm); ++ ++ dev_dbg(dev, "RTC_TIME: %u.%u.%u %u:%u:%u\n", ++ tm->tm_mday, tm->tm_mon, tm->tm_year, ++ tm->tm_hour, tm->tm_min, tm->tm_sec); ++ ++ return 0; ++} ++ ++static int pcf50606_rtc_set_time(struct device *dev, struct rtc_time *tm) ++{ ++ struct i2c_client *client = to_i2c_client(dev); ++ struct pcf50606_data *pcf = i2c_get_clientdata(client); ++ struct pcf50606_time pcf_tm; ++ u_int8_t int1m; ++ ++ dev_dbg(dev, "RTC_TIME: %u.%u.%u %u:%u:%u\n", ++ tm->tm_mday, tm->tm_mon, tm->tm_year, ++ tm->tm_hour, tm->tm_min, tm->tm_sec); ++ rtc2pcf_time(&pcf_tm, tm); ++ dev_dbg(dev, "PCF_TIME: %02x.%02x.%02x %02x:%02x:%02x\n", ++ pcf_tm.day, pcf_tm.month, pcf_tm.year, ++ pcf_tm.hour, pcf_tm.min, pcf_tm.sec); ++ ++ mutex_lock(&pcf->lock); ++ ++ /* disable SECOND interrupt */ ++ int1m = __reg_read(pcf, PCF50606_REG_INT1M); ++ __reg_write(pcf, PCF50606_REG_INT1M, int1m | PCF50606_INT1_SECOND); ++ ++ __reg_write(pcf, PCF50606_REG_RTCSC, pcf_tm.sec); ++ __reg_write(pcf, PCF50606_REG_RTCMN, pcf_tm.min); ++ __reg_write(pcf, PCF50606_REG_RTCHR, pcf_tm.hour); ++ __reg_write(pcf, PCF50606_REG_RTCWD, pcf_tm.wkday); ++ __reg_write(pcf, PCF50606_REG_RTCDT, pcf_tm.day); ++ __reg_write(pcf, PCF50606_REG_RTCMT, pcf_tm.month); ++ __reg_write(pcf, PCF50606_REG_RTCYR, pcf_tm.year); ++ ++ /* restore INT1M, potentially re-enable SECOND interrupt */ ++ __reg_write(pcf, PCF50606_REG_INT1M, int1m); ++ ++ mutex_unlock(&pcf->lock); ++ ++ return 0; ++} ++ ++static int pcf50606_rtc_read_alarm(struct device *dev, struct rtc_wkalrm *alrm) ++{ ++ struct i2c_client *client = to_i2c_client(dev); ++ struct pcf50606_data *pcf = i2c_get_clientdata(client); ++ struct pcf50606_time pcf_tm; ++ ++ mutex_lock(&pcf->lock); ++ alrm->enabled = ++ __reg_read(pcf, PCF50606_REG_INT1M) & PCF50606_INT1_ALARM ++ ? 0 : 1; ++ pcf_tm.sec = __reg_read(pcf, PCF50606_REG_RTCSCA); ++ pcf_tm.min = __reg_read(pcf, PCF50606_REG_RTCMNA); ++ pcf_tm.hour = __reg_read(pcf, PCF50606_REG_RTCHRA); ++ pcf_tm.wkday = __reg_read(pcf, PCF50606_REG_RTCWDA); ++ pcf_tm.day = __reg_read(pcf, PCF50606_REG_RTCDTA); ++ pcf_tm.month = __reg_read(pcf, PCF50606_REG_RTCMTA); ++ pcf_tm.year = __reg_read(pcf, PCF50606_REG_RTCYRA); ++ mutex_unlock(&pcf->lock); ++ ++ pcf2rtc_time(&alrm->time, &pcf_tm); ++ ++ return 0; ++} ++ ++static int pcf50606_rtc_set_alarm(struct device *dev, struct rtc_wkalrm *alrm) ++{ ++ struct i2c_client *client = to_i2c_client(dev); ++ struct pcf50606_data *pcf = i2c_get_clientdata(client); ++ struct pcf50606_time pcf_tm; ++ u_int8_t irqmask; ++ ++ rtc2pcf_time(&pcf_tm, &alrm->time); ++ ++ mutex_lock(&pcf->lock); ++ ++ /* disable alarm interrupt */ ++ irqmask = __reg_read(pcf, PCF50606_REG_INT1M); ++ irqmask |= PCF50606_INT1_ALARM; ++ __reg_write(pcf, PCF50606_REG_INT1M, irqmask); ++ ++ __reg_write(pcf, PCF50606_REG_RTCSCA, pcf_tm.sec); ++ __reg_write(pcf, PCF50606_REG_RTCMNA, pcf_tm.min); ++ __reg_write(pcf, PCF50606_REG_RTCHRA, pcf_tm.hour); ++ __reg_write(pcf, PCF50606_REG_RTCWDA, pcf_tm.wkday); ++ __reg_write(pcf, PCF50606_REG_RTCDTA, pcf_tm.day); ++ __reg_write(pcf, PCF50606_REG_RTCMTA, pcf_tm.month); ++ __reg_write(pcf, PCF50606_REG_RTCYRA, pcf_tm.year); ++ ++ if (alrm->enabled) { ++ /* (re-)enaable alarm interrupt */ ++ irqmask = __reg_read(pcf, PCF50606_REG_INT1M); ++ irqmask &= ~PCF50606_INT1_ALARM; ++ __reg_write(pcf, PCF50606_REG_INT1M, irqmask); ++ } ++ ++ mutex_unlock(&pcf->lock); ++ ++ /* FIXME */ ++ return 0; ++} ++ ++static struct rtc_class_ops pcf50606_rtc_ops = { ++ .ioctl = pcf50606_rtc_ioctl, ++ .read_time = pcf50606_rtc_read_time, ++ .set_time = pcf50606_rtc_set_time, ++ .read_alarm = pcf50606_rtc_read_alarm, ++ .set_alarm = pcf50606_rtc_set_alarm, ++}; ++ ++/*********************************************************************** ++ * Watchdog ++ ***********************************************************************/ ++ ++static void pcf50606_wdt_start(struct pcf50606_data *pcf) ++{ ++ reg_set_bit_mask(pcf, PCF50606_REG_OOCC1, PCF50606_OOCC1_WDTRST, ++ PCF50606_OOCC1_WDTRST); ++} ++ ++static void pcf50606_wdt_stop(struct pcf50606_data *pcf) ++{ ++ reg_clear_bits(pcf, PCF50606_REG_OOCS, PCF50606_OOCS_WDTEXP); ++} ++ ++static void pcf50606_wdt_keepalive(struct pcf50606_data *pcf) ++{ ++ pcf50606_wdt_start(pcf); ++} ++ ++static int pcf50606_wdt_open(struct inode *inode, struct file *file) ++{ ++ struct pcf50606_data *pcf = pcf50606_global; ++ ++ file->private_data = pcf; ++ ++ /* start the timer */ ++ pcf50606_wdt_start(pcf); ++ ++ return nonseekable_open(inode, file); ++} ++ ++static int pcf50606_wdt_release(struct inode *inode, struct file *file) ++{ ++ struct pcf50606_data *pcf = file->private_data; ++ ++ if (pcf->allow_close == CLOSE_STATE_ALLOW) ++ pcf50606_wdt_stop(pcf); ++ else { ++ printk(KERN_CRIT "Unexpected close, not stopping watchdog!\n"); ++ pcf50606_wdt_keepalive(pcf); ++ } ++ ++ pcf->allow_close = CLOSE_STATE_NOT; ++ ++ return 0; ++} ++ ++static ssize_t pcf50606_wdt_write(struct file *file, const char __user *data, ++ size_t len, loff_t *ppos) ++{ ++ struct pcf50606_data *pcf = file->private_data; ++ if (len) { ++ size_t i; ++ ++ for (i = 0; i != len; i++) { ++ char c; ++ if (get_user(c, data + i)) ++ return -EFAULT; ++ if (c == 'V') ++ pcf->allow_close = CLOSE_STATE_ALLOW; ++ } ++ pcf50606_wdt_keepalive(pcf); ++ } ++ ++ return len; ++} ++ ++static struct watchdog_info pcf50606_wdt_ident = { ++ .options = WDIOF_MAGICCLOSE, ++ .firmware_version = 0, ++ .identity = "PCF50606 Watchdog", ++}; ++ ++static int pcf50606_wdt_ioctl(struct inode *inode, struct file *file, ++ unsigned int cmd, unsigned long arg) ++{ ++ struct pcf50606_data *pcf = file->private_data; ++ void __user *argp = (void __user *)arg; ++ int __user *p = argp; ++ ++ switch (cmd) { ++ case WDIOC_GETSUPPORT: ++ return copy_to_user(argp, &pcf50606_wdt_ident, ++ sizeof(pcf50606_wdt_ident)) ? -EFAULT : 0; ++ break; ++ case WDIOC_GETSTATUS: ++ case WDIOC_GETBOOTSTATUS: ++ return put_user(0, p); ++ case WDIOC_KEEPALIVE: ++ pcf50606_wdt_keepalive(pcf); ++ return 0; ++ case WDIOC_GETTIMEOUT: ++ return put_user(8, p); ++ default: ++ return -ENOIOCTLCMD; ++ } ++} ++ ++static struct file_operations pcf50606_wdt_fops = { ++ .owner = THIS_MODULE, ++ .llseek = no_llseek, ++ .write = &pcf50606_wdt_write, ++ .ioctl = &pcf50606_wdt_ioctl, ++ .open = &pcf50606_wdt_open, ++ .release = &pcf50606_wdt_release, ++}; ++ ++static struct miscdevice pcf50606_wdt_miscdev = { ++ .minor = WATCHDOG_MINOR, ++ .name = "watchdog", ++ .fops = &pcf50606_wdt_fops, ++}; ++ ++/*********************************************************************** ++ * PWM ++ ***********************************************************************/ ++ ++static const char *pwm_dc_table[] = { ++ "0/16", "1/16", "2/16", "3/16", ++ "4/16", "5/16", "6/16", "7/16", ++ "8/16", "9/16", "10/16", "11/16", ++ "12/16", "13/16", "14/16", "15/16", ++}; ++ ++static ssize_t show_pwm_dc(struct device *dev, struct device_attribute *attr, ++ char *buf) ++{ ++ struct i2c_client *client = to_i2c_client(dev); ++ struct pcf50606_data *pcf = i2c_get_clientdata(client); ++ u_int8_t val; ++ ++ val = reg_read(pcf, PCF50606_REG_PWMC1) >> PCF50606_PWMC1_DC_SHIFT; ++ val &= 0xf; ++ ++ return sprintf(buf, "%s\n", pwm_dc_table[val]); ++} ++ ++static ssize_t set_pwm_dc(struct device *dev, struct device_attribute *attr, ++ const char *buf, size_t count) ++{ ++ struct i2c_client *client = to_i2c_client(dev); ++ struct pcf50606_data *pcf = i2c_get_clientdata(client); ++ u_int8_t i; ++ ++ for (i = 0; i < ARRAY_SIZE(pwm_dc_table); i++) { ++ if (!strncmp(buf, pwm_dc_table[i], strlen(pwm_dc_table[i]))) { ++ dev_dbg(dev, "setting pwm dc %s\n\r", pwm_dc_table[i]); ++ reg_set_bit_mask(pcf, PCF50606_REG_PWMC1, 0x1e, ++ (i << PCF50606_PWMC1_DC_SHIFT)); ++ } ++ } ++ return count; ++} ++ ++static DEVICE_ATTR(pwm_dc, S_IRUGO | S_IWUSR, show_pwm_dc, set_pwm_dc); ++ ++static const char *pwm_clk_table[] = { ++ "512", "256", "128", "64", ++ "56300", "28100", "14100", "7000", ++}; ++ ++static ssize_t show_pwm_clk(struct device *dev, struct device_attribute *attr, ++ char *buf) ++{ ++ struct i2c_client *client = to_i2c_client(dev); ++ struct pcf50606_data *pcf = i2c_get_clientdata(client); ++ u_int8_t val; ++ ++ val = reg_read(pcf, PCF50606_REG_PWMC1) >> PCF50606_PWMC1_CLK_SHIFT; ++ val &= 0x7; ++ ++ return sprintf(buf, "%s\n", pwm_clk_table[val]); ++} ++ ++static ssize_t set_pwm_clk(struct device *dev, struct device_attribute *attr, ++ const char *buf, size_t count) ++{ ++ struct i2c_client *client = to_i2c_client(dev); ++ struct pcf50606_data *pcf = i2c_get_clientdata(client); ++ u_int8_t i; ++ ++ for (i = 0; i < ARRAY_SIZE(pwm_clk_table); i++) { ++ if (!strncmp(buf, pwm_clk_table[i], strlen(pwm_clk_table[i]))) { ++ dev_dbg(dev, "setting pwm clk %s\n\r", ++ pwm_clk_table[i]); ++ reg_set_bit_mask(pcf, PCF50606_REG_PWMC1, 0xe0, ++ (i << PCF50606_PWMC1_CLK_SHIFT)); ++ } ++ } ++ return count; ++} ++ ++static DEVICE_ATTR(pwm_clk, S_IRUGO | S_IWUSR, show_pwm_clk, set_pwm_clk); ++ ++static int pcf50606bl_get_intensity(struct backlight_device *bd) ++{ ++ struct pcf50606_data *pcf = bl_get_data(bd); ++ int intensity = reg_read(pcf, PCF50606_REG_PWMC1); ++ intensity = (intensity >> PCF50606_PWMC1_DC_SHIFT); ++ ++ return intensity & 0xf; ++} ++ ++static int pcf50606bl_set_intensity(struct backlight_device *bd) ++{ ++ struct pcf50606_data *pcf = bl_get_data(bd); ++ int intensity = bd->props.brightness; ++ ++ if (bd->props.power != FB_BLANK_UNBLANK) ++ intensity = 0; ++ if (bd->props.fb_blank != FB_BLANK_UNBLANK) ++ intensity = 0; ++ ++ return reg_set_bit_mask(pcf, PCF50606_REG_PWMC1, 0x1e, ++ (intensity << PCF50606_PWMC1_DC_SHIFT)); ++} ++ ++static struct backlight_ops pcf50606bl_ops = { ++ .get_brightness = pcf50606bl_get_intensity, ++ .update_status = pcf50606bl_set_intensity, ++}; ++ ++/*********************************************************************** ++ * Driver initialization ++ ***********************************************************************/ ++ ++#ifdef CONFIG_MACH_NEO1973_GTA01 ++/* We currently place those platform devices here to make sure the device ++ * suspend/resume order is correct */ ++static struct platform_device gta01_pm_gps_dev = { ++ .name = "neo1973-pm-gps", ++}; ++ ++static struct platform_device gta01_pm_bt_dev = { ++ .name = "neo1973-pm-bt", ++}; ++#endif ++ ++static struct attribute *pcf_sysfs_entries[16] = { ++ &dev_attr_voltage_dcd.attr, ++ &dev_attr_voltage_dcde.attr, ++ &dev_attr_voltage_dcud.attr, ++ &dev_attr_voltage_d1reg.attr, ++ &dev_attr_voltage_d2reg.attr, ++ &dev_attr_voltage_d3reg.attr, ++ &dev_attr_voltage_lpreg.attr, ++ &dev_attr_voltage_ioreg.attr, ++ NULL ++}; ++ ++static struct attribute_group pcf_attr_group = { ++ .name = NULL, /* put in device directory */ ++ .attrs = pcf_sysfs_entries, ++}; ++ ++static void populate_sysfs_group(struct pcf50606_data *pcf) ++{ ++ int i = 0; ++ struct attribute **attr; ++ ++ for (attr = pcf_sysfs_entries; *attr; attr++) ++ i++; ++ ++ if (pcf->pdata->used_features & PCF50606_FEAT_MBC) { ++ pcf_sysfs_entries[i++] = &dev_attr_chgstate.attr; ++ pcf_sysfs_entries[i++] = &dev_attr_chgmode.attr; ++ } ++ ++ if (pcf->pdata->used_features & PCF50606_FEAT_CHGCUR) ++ pcf_sysfs_entries[i++] = &dev_attr_chgcur.attr; ++ ++ if (pcf->pdata->used_features & PCF50606_FEAT_BATVOLT) ++ pcf_sysfs_entries[i++] = &dev_attr_battvolt.attr; ++ ++ if (pcf->pdata->used_features & PCF50606_FEAT_BATTEMP) ++ pcf_sysfs_entries[i++] = &dev_attr_battemp.attr; ++ ++ if (pcf->pdata->used_features & PCF50606_FEAT_PWM) { ++ pcf_sysfs_entries[i++] = &dev_attr_pwm_dc.attr; ++ pcf_sysfs_entries[i++] = &dev_attr_pwm_clk.attr; ++ } ++} ++ ++static int pcf50606_detect(struct i2c_adapter *adapter, int address, int kind) ++{ ++ struct i2c_client *new_client; ++ struct pcf50606_data *data; ++ int err = 0; ++ int irq; ++ ++ if (!pcf50606_pdev) { ++ printk(KERN_ERR "pcf50606: driver needs a platform_device!\n"); ++ return -EIO; ++ } ++ ++ irq = platform_get_irq(pcf50606_pdev, 0); ++ if (irq < 0) { ++ dev_err(&pcf50606_pdev->dev, "no irq in platform resources!\n"); ++ return -EIO; ++ } ++ ++ /* At the moment, we only support one PCF50606 in a system */ ++ if (pcf50606_global) { ++ dev_err(&pcf50606_pdev->dev, ++ "currently only one chip supported\n"); ++ return -EBUSY; ++ } ++ ++ data = kzalloc(sizeof(*data), GFP_KERNEL); ++ if (!data) ++ return -ENOMEM; ++ ++ mutex_init(&data->lock); ++ mutex_init(&data->working_lock); ++ INIT_WORK(&data->work, pcf50606_work); ++ data->irq = irq; ++ data->working = 0; ++ data->suppress_onkey_events = 0; ++ data->onkey_seconds = -1; ++ data->pdata = pcf50606_pdev->dev.platform_data; ++ ++ new_client = &data->client; ++ i2c_set_clientdata(new_client, data); ++ new_client->addr = address; ++ new_client->adapter = adapter; ++ new_client->driver = &pcf50606_driver; ++ new_client->flags = 0; ++ strlcpy(new_client->name, "pcf50606", I2C_NAME_SIZE); ++ ++ /* now we try to detect the chip */ ++ ++ /* register with i2c core */ ++ err = i2c_attach_client(new_client); ++ if (err) { ++ dev_err(&new_client->dev, ++ "error during i2c_attach_client()\n"); ++ goto exit_free; ++ } ++ ++ populate_sysfs_group(data); ++ ++ err = sysfs_create_group(&new_client->dev.kobj, &pcf_attr_group); ++ if (err) { ++ dev_err(&new_client->dev, "error creating sysfs group\n"); ++ goto exit_detach; ++ } ++ ++ /* create virtual charger 'device' */ ++ ++ /* input device registration */ ++ data->input_dev = input_allocate_device(); ++ if (!data->input_dev) ++ goto exit_sysfs; ++ ++ data->input_dev->name = "FIC Neo1973 PMU events"; ++ data->input_dev->phys = "I2C"; ++ data->input_dev->id.bustype = BUS_I2C; ++ ++ data->input_dev->evbit[0] = BIT(EV_KEY) | BIT(EV_PWR); ++ set_bit(KEY_POWER, data->input_dev->keybit); ++ set_bit(KEY_POWER2, data->input_dev->keybit); ++ set_bit(KEY_BATTERY, data->input_dev->keybit); ++ ++ err = input_register_device(data->input_dev); ++ if (err) ++ goto exit_sysfs; ++ ++ /* register power off handler with core power management */ ++ pm_power_off = &pcf50606_go_standby; ++ ++ /* configure interrupt mask */ ++ /* we don't mask SECOND here, because we want one to do coldplug with */ ++ reg_write(data, PCF50606_REG_INT1M, 0x00); ++ reg_write(data, PCF50606_REG_INT2M, 0x00); ++ reg_write(data, PCF50606_REG_INT3M, PCF50606_INT3_TSCPRES); ++ ++ err = request_irq(irq, pcf50606_irq, IRQF_TRIGGER_FALLING, ++ "pcf50606", data); ++ if (err < 0) ++ goto exit_input; ++ ++ if (enable_irq_wake(irq) < 0) ++ dev_err(&new_client->dev, "IRQ %u cannot be enabled as wake-up" ++ "source in this hardware revision!", irq); ++ ++ pcf50606_global = data; ++ ++ if (data->pdata->used_features & PCF50606_FEAT_RTC) { ++ data->rtc = rtc_device_register("pcf50606", &new_client->dev, ++ &pcf50606_rtc_ops, THIS_MODULE); ++ if (IS_ERR(data->rtc)) { ++ err = PTR_ERR(data->rtc); ++ goto exit_irq; ++ } ++ } ++ ++ if (data->pdata->used_features & PCF50606_FEAT_WDT) { ++ err = misc_register(&pcf50606_wdt_miscdev); ++ if (err) { ++ dev_err(&new_client->dev, "cannot register miscdev on " ++ "minor=%d (%d)\n", WATCHDOG_MINOR, err); ++ goto exit_rtc; ++ } ++ } ++ ++ if (data->pdata->used_features & PCF50606_FEAT_PWM) { ++ /* enable PWM controller */ ++ reg_set_bit_mask(data, PCF50606_REG_PWMC1, ++ PCF50606_PWMC1_ACTSET, ++ PCF50606_PWMC1_ACTSET); ++ } ++ ++ if (data->pdata->used_features & PCF50606_FEAT_PWM_BL) { ++ data->backlight = backlight_device_register("pcf50606-bl", ++ &new_client->dev, ++ data, ++ &pcf50606bl_ops); ++ if (!data->backlight) ++ goto exit_misc; ++ data->backlight->props.max_brightness = 16; ++ data->backlight->props.power = FB_BLANK_UNBLANK; ++ data->backlight->props.brightness = ++ data->pdata->init_brightness; ++ backlight_update_status(data->backlight); ++ } ++ ++ apm_get_power_status = pcf50606_get_power_status; ++ ++#ifdef CONFIG_MACH_NEO1973_GTA01 ++ if (machine_is_neo1973_gta01()) { ++ gta01_pm_gps_dev.dev.parent = &new_client->dev; ++ switch (system_rev) { ++ case GTA01Bv2_SYSTEM_REV: ++ case GTA01Bv3_SYSTEM_REV: ++ case GTA01Bv4_SYSTEM_REV: ++ gta01_pm_bt_dev.dev.parent = &new_client->dev; ++ platform_device_register(>a01_pm_bt_dev); ++ break; ++ } ++ platform_device_register(>a01_pm_gps_dev); ++ /* a link for gllin compatibility */ ++ err = bus_create_device_link(&platform_bus_type, ++ >a01_pm_gps_dev.dev.kobj, "gta01-pm-gps.0"); ++ if (err) ++ printk(KERN_ERR ++ "sysfs_create_link (gta01-pm-gps.0): %d\n", err); ++ } ++#endif ++ ++ if (data->pdata->used_features & PCF50606_FEAT_ACD) ++ reg_set_bit_mask(data, PCF50606_REG_ACDC1, ++ PCF50606_ACDC1_ACDAPE, PCF50606_ACDC1_ACDAPE); ++ else ++ reg_clear_bits(data, PCF50606_REG_ACDC1, ++ PCF50606_ACDC1_ACDAPE); ++ ++ return 0; ++ ++exit_misc: ++ if (data->pdata->used_features & PCF50606_FEAT_WDT) ++ misc_deregister(&pcf50606_wdt_miscdev); ++exit_rtc: ++ if (data->pdata->used_features & PCF50606_FEAT_RTC) ++ rtc_device_unregister(pcf50606_global->rtc); ++exit_irq: ++ free_irq(pcf50606_global->irq, pcf50606_global); ++ pcf50606_global = NULL; ++exit_input: ++ pm_power_off = NULL; ++ input_unregister_device(data->input_dev); ++exit_sysfs: ++ sysfs_remove_group(&new_client->dev.kobj, &pcf_attr_group); ++exit_detach: ++ i2c_detach_client(new_client); ++exit_free: ++ kfree(data); ++ return err; ++} ++ ++static int pcf50606_attach_adapter(struct i2c_adapter *adapter) ++{ ++ return i2c_probe(adapter, &addr_data, &pcf50606_detect); ++} ++ ++static int pcf50606_detach_client(struct i2c_client *client) ++{ ++ struct pcf50606_data *pcf = i2c_get_clientdata(client); ++ ++ apm_get_power_status = NULL; ++ input_unregister_device(pcf->input_dev); ++ ++ if (pcf->pdata->used_features & PCF50606_FEAT_PWM_BL) ++ backlight_device_unregister(pcf->backlight); ++ ++ if (pcf->pdata->used_features & PCF50606_FEAT_WDT) ++ misc_deregister(&pcf50606_wdt_miscdev); ++ ++ if (pcf->pdata->used_features & PCF50606_FEAT_RTC) ++ rtc_device_unregister(pcf->rtc); ++ ++ free_irq(pcf->irq, pcf); ++ ++ sysfs_remove_group(&client->dev.kobj, &pcf_attr_group); ++ ++ pm_power_off = NULL; ++ ++ kfree(pcf); ++ ++ return 0; ++} ++ ++#ifdef CONFIG_PM ++#define INT1M_RESUMERS (PCF50606_INT1_ALARM | \ ++ PCF50606_INT1_ONKEYF | \ ++ PCF50606_INT1_EXTONR) ++#define INT2M_RESUMERS (PCF50606_INT2_CHGWD10S | \ ++ PCF50606_INT2_CHGPROT | \ ++ PCF50606_INT2_CHGERR) ++#define INT3M_RESUMERS (PCF50606_INT3_LOWBAT | \ ++ PCF50606_INT3_HIGHTMP | \ ++ PCF50606_INT3_ACDINS) ++static int pcf50606_suspend(struct device *dev, pm_message_t state) ++{ ++ struct i2c_client *client = to_i2c_client(dev); ++ struct pcf50606_data *pcf = i2c_get_clientdata(client); ++ int i; ++ ++ /* we suspend once (!) as late as possible in the suspend sequencing */ ++ ++ if ((state.event != PM_EVENT_SUSPEND) || ++ (pcf->suspend_state != PCF50606_SS_RUNNING)) ++ return -EBUSY; ++ ++ /* The general idea is to power down all unused power supplies, ++ * and then mask all PCF50606 interrup sources but EXTONR, ONKEYF ++ * and ALARM */ ++ ++ mutex_lock(&pcf->lock); ++ ++ pcf->suspend_state = PCF50606_SS_STARTING_SUSPEND; ++ ++ /* we are not going to service any further interrupts until we ++ * resume. If the IRQ workqueue is still pending in the background, ++ * it will bail when it sees we set suspend state above. ++ */ ++ ++ disable_irq(pcf->irq); ++ ++ /* Save all registers that don't "survive" standby state */ ++ pcf->standby_regs.dcdc1 = __reg_read(pcf, PCF50606_REG_DCDC1); ++ pcf->standby_regs.dcdc2 = __reg_read(pcf, PCF50606_REG_DCDC2); ++ pcf->standby_regs.dcdec1 = __reg_read(pcf, PCF50606_REG_DCDEC1); ++ pcf->standby_regs.dcudc1 = __reg_read(pcf, PCF50606_REG_DCUDC1); ++ pcf->standby_regs.ioregc = __reg_read(pcf, PCF50606_REG_IOREGC); ++ pcf->standby_regs.d1regc1 = __reg_read(pcf, PCF50606_REG_D1REGC1); ++ pcf->standby_regs.d2regc1 = __reg_read(pcf, PCF50606_REG_D2REGC1); ++ pcf->standby_regs.d3regc1 = __reg_read(pcf, PCF50606_REG_D3REGC1); ++ pcf->standby_regs.lpregc1 = __reg_read(pcf, PCF50606_REG_LPREGC1); ++ pcf->standby_regs.adcc1 = __reg_read(pcf, PCF50606_REG_ADCC1); ++ pcf->standby_regs.adcc2 = __reg_read(pcf, PCF50606_REG_ADCC2); ++ pcf->standby_regs.pwmc1 = __reg_read(pcf, PCF50606_REG_PWMC1); ++ ++ /* switch off power supplies that are not needed during suspend */ ++ for (i = 0; i < __NUM_PCF50606_REGULATORS; i++) { ++ if (!(pcf->pdata->rails[i].flags & PMU_VRAIL_F_SUSPEND_ON)) { ++ u_int8_t tmp; ++ ++ /* IOREG powers the I@C interface so we cannot switch ++ * it off */ ++ if (i == PCF50606_REGULATOR_IOREG) ++ continue; ++ ++ dev_dbg(dev, "disabling pcf50606 regulator %u\n", i); ++ /* we cannot use pcf50606_onoff_set() because we're ++ * already under the mutex */ ++ tmp = __reg_read(pcf, regulator_registers[i]); ++ tmp &= 0x1f; ++ __reg_write(pcf, regulator_registers[i], tmp); ++ } ++ } ++ ++ pcf->standby_regs.int1m = __reg_read(pcf, PCF50606_REG_INT1M); ++ pcf->standby_regs.int2m = __reg_read(pcf, PCF50606_REG_INT2M); ++ pcf->standby_regs.int3m = __reg_read(pcf, PCF50606_REG_INT3M); ++ __reg_write(pcf, PCF50606_REG_INT1M, ~INT1M_RESUMERS & 0xff); ++ __reg_write(pcf, PCF50606_REG_INT2M, ~INT2M_RESUMERS & 0xff); ++ __reg_write(pcf, PCF50606_REG_INT3M, ~INT3M_RESUMERS & 0xff); ++ ++ pcf->suspend_state = PCF50606_SS_COMPLETED_SUSPEND; ++ ++ mutex_unlock(&pcf->lock); ++ ++ return 0; ++} ++ ++static int pcf50606_resume(struct device *dev) ++{ ++ struct i2c_client *client = to_i2c_client(dev); ++ struct pcf50606_data *pcf = i2c_get_clientdata(client); ++ ++ mutex_lock(&pcf->lock); ++ ++ pcf->suspend_state = PCF50606_SS_STARTING_RESUME; ++ ++ /* Resume all saved registers that don't "survive" standby state */ ++ __reg_write(pcf, PCF50606_REG_INT1M, pcf->standby_regs.int1m); ++ __reg_write(pcf, PCF50606_REG_INT2M, pcf->standby_regs.int2m); ++ __reg_write(pcf, PCF50606_REG_INT3M, pcf->standby_regs.int3m); ++ ++ __reg_write(pcf, PCF50606_REG_DCDC1, pcf->standby_regs.dcdc1); ++ __reg_write(pcf, PCF50606_REG_DCDC2, pcf->standby_regs.dcdc2); ++ __reg_write(pcf, PCF50606_REG_DCDEC1, pcf->standby_regs.dcdec1); ++ __reg_write(pcf, PCF50606_REG_DCUDC1, pcf->standby_regs.dcudc1); ++ __reg_write(pcf, PCF50606_REG_IOREGC, pcf->standby_regs.ioregc); ++ __reg_write(pcf, PCF50606_REG_D1REGC1, pcf->standby_regs.d1regc1); ++ __reg_write(pcf, PCF50606_REG_D2REGC1, pcf->standby_regs.d2regc1); ++ __reg_write(pcf, PCF50606_REG_D3REGC1, pcf->standby_regs.d3regc1); ++ __reg_write(pcf, PCF50606_REG_LPREGC1, pcf->standby_regs.lpregc1); ++ __reg_write(pcf, PCF50606_REG_ADCC1, pcf->standby_regs.adcc1); ++ __reg_write(pcf, PCF50606_REG_ADCC2, pcf->standby_regs.adcc2); ++ __reg_write(pcf, PCF50606_REG_PWMC1, pcf->standby_regs.pwmc1); ++ ++ pcf->suspend_state = PCF50606_SS_COMPLETED_RESUME; ++ ++ enable_irq(pcf->irq); ++ ++ mutex_unlock(&pcf->lock); ++ ++ /* Call PCF work function; this fixes an issue on the gta01 where ++ * the power button "goes away" if it is used to wake the device. ++ */ ++ get_device(&pcf->client.dev); ++ pcf50606_work(&pcf->work); ++ ++ return 0; ++} ++#else ++#define pcf50606_suspend NULL ++#define pcf50606_resume NULL ++#endif ++ ++static struct i2c_driver pcf50606_driver = { ++ .driver = { ++ .name = "pcf50606", ++ .suspend = pcf50606_suspend, ++ .resume = pcf50606_resume, ++ }, ++ .id = I2C_DRIVERID_PCF50606, ++ .attach_adapter = pcf50606_attach_adapter, ++ .detach_client = pcf50606_detach_client, ++}; ++ ++/* platform driver, since i2c devices don't have platform_data */ ++static int __init pcf50606_plat_probe(struct platform_device *pdev) ++{ ++ struct pcf50606_platform_data *pdata = pdev->dev.platform_data; ++ ++ if (!pdata) ++ return -ENODEV; ++ ++ pcf50606_pdev = pdev; ++ ++ return 0; ++} ++ ++static int pcf50606_plat_remove(struct platform_device *pdev) ++{ ++ return 0; ++} ++ ++/* We have this purely to capture an early indication that we are coming out ++ * of suspend, before our device resume got called; async interrupt service is ++ * interested in this. ++ */ ++ ++static int pcf50606_plat_resume(struct platform_device *pdev) ++{ ++ /* i2c_get_clientdata(to_i2c_client(&pdev->dev)) returns NULL at this ++ * early resume time so we have to use pcf50606_global ++ */ ++ pcf50606_global->suspend_state = PCF50606_SS_RESUMING_BUT_NOT_US_YET; ++ ++ return 0; ++} ++ ++static struct platform_driver pcf50606_plat_driver = { ++ .probe = pcf50606_plat_probe, ++ .remove = pcf50606_plat_remove, ++ .resume_early = pcf50606_plat_resume, ++ .driver = { ++ .owner = THIS_MODULE, ++ .name = "pcf50606", ++ }, ++}; ++ ++static int __init pcf50606_init(void) ++{ ++ int rc; ++ ++ rc = platform_driver_register(&pcf50606_plat_driver); ++ if (!rc) ++ rc = i2c_add_driver(&pcf50606_driver); ++ ++ return rc; ++} ++ ++static void pcf50606_exit(void) ++{ ++ i2c_del_driver(&pcf50606_driver); ++ platform_driver_unregister(&pcf50606_plat_driver); ++} ++ ++MODULE_DESCRIPTION("I2C chip driver for NXP PCF50606 power management unit"); ++MODULE_AUTHOR("Harald Welte <laforge@openmoko.org>"); ++MODULE_LICENSE("GPL"); ++ ++module_init(pcf50606_init); ++module_exit(pcf50606_exit); +diff -ruN --exclude='*.orig' --exclude='*.rej' linux-2.6.29-rc3.owrt/drivers/i2c/chips/pcf50606.h linux-2.6.29-rc3.owrt.om/drivers/i2c/chips/pcf50606.h +--- linux-2.6.29-rc3.owrt/drivers/i2c/chips/pcf50606.h 1970-01-01 01:00:00.000000000 +0100 ++++ linux-2.6.29-rc3.owrt.om/drivers/i2c/chips/pcf50606.h 2009-05-10 22:27:59.000000000 +0200 +@@ -0,0 +1,302 @@ ++#ifndef _PCF50606_H ++#define _PCF50606_H ++ ++/* Philips PCF50606 Power Managemnt Unit (PMU) driver ++ * (C) 2006-2007 by Openmoko, Inc. ++ * Author: Harald Welte <laforge@openmoko.org> ++ * ++ */ ++ ++enum pfc50606_regs { ++ PCF50606_REG_ID = 0x00, ++ PCF50606_REG_OOCS = 0x01, ++ PCF50606_REG_INT1 = 0x02, /* Interrupt Status */ ++ PCF50606_REG_INT2 = 0x03, /* Interrupt Status */ ++ PCF50606_REG_INT3 = 0x04, /* Interrupt Status */ ++ PCF50606_REG_INT1M = 0x05, /* Interrupt Mask */ ++ PCF50606_REG_INT2M = 0x06, /* Interrupt Mask */ ++ PCF50606_REG_INT3M = 0x07, /* Interrupt Mask */ ++ PCF50606_REG_OOCC1 = 0x08, ++ PCF50606_REG_OOCC2 = 0x09, ++ PCF50606_REG_RTCSC = 0x0a, /* Second */ ++ PCF50606_REG_RTCMN = 0x0b, /* Minute */ ++ PCF50606_REG_RTCHR = 0x0c, /* Hour */ ++ PCF50606_REG_RTCWD = 0x0d, /* Weekday */ ++ PCF50606_REG_RTCDT = 0x0e, /* Day */ ++ PCF50606_REG_RTCMT = 0x0f, /* Month */ ++ PCF50606_REG_RTCYR = 0x10, /* Year */ ++ PCF50606_REG_RTCSCA = 0x11, /* Alarm Second */ ++ PCF50606_REG_RTCMNA = 0x12, /* Alarm Minute */ ++ PCF50606_REG_RTCHRA = 0x13, /* Alarm Hour */ ++ PCF50606_REG_RTCWDA = 0x14, /* Alarm Weekday */ ++ PCF50606_REG_RTCDTA = 0x15, /* Alarm Day */ ++ PCF50606_REG_RTCMTA = 0x16, /* Alarm Month */ ++ PCF50606_REG_RTCYRA = 0x17, /* Alarm Year */ ++ PCF50606_REG_PSSC = 0x18, /* Power sequencing */ ++ PCF50606_REG_PWROKM = 0x19, /* PWROK mask */ ++ PCF50606_REG_PWROKS = 0x1a, /* PWROK status */ ++ PCF50606_REG_DCDC1 = 0x1b, ++ PCF50606_REG_DCDC2 = 0x1c, ++ PCF50606_REG_DCDC3 = 0x1d, ++ PCF50606_REG_DCDC4 = 0x1e, ++ PCF50606_REG_DCDEC1 = 0x1f, ++ PCF50606_REG_DCDEC2 = 0x20, ++ PCF50606_REG_DCUDC1 = 0x21, ++ PCF50606_REG_DCUDC2 = 0x22, ++ PCF50606_REG_IOREGC = 0x23, ++ PCF50606_REG_D1REGC1 = 0x24, ++ PCF50606_REG_D2REGC1 = 0x25, ++ PCF50606_REG_D3REGC1 = 0x26, ++ PCF50606_REG_LPREGC1 = 0x27, ++ PCF50606_REG_LPREGC2 = 0x28, ++ PCF50606_REG_MBCC1 = 0x29, ++ PCF50606_REG_MBCC2 = 0x2a, ++ PCF50606_REG_MBCC3 = 0x2b, ++ PCF50606_REG_MBCS1 = 0x2c, ++ PCF50606_REG_BBCC = 0x2d, ++ PCF50606_REG_ADCC1 = 0x2e, ++ PCF50606_REG_ADCC2 = 0x2f, ++ PCF50606_REG_ADCS1 = 0x30, ++ PCF50606_REG_ADCS2 = 0x31, ++ PCF50606_REG_ADCS3 = 0x32, ++ PCF50606_REG_ACDC1 = 0x33, ++ PCF50606_REG_BVMC = 0x34, ++ PCF50606_REG_PWMC1 = 0x35, ++ PCF50606_REG_LEDC1 = 0x36, ++ PCF50606_REG_LEDC2 = 0x37, ++ PCF50606_REG_GPOC1 = 0x38, ++ PCF50606_REG_GPOC2 = 0x39, ++ PCF50606_REG_GPOC3 = 0x3a, ++ PCF50606_REG_GPOC4 = 0x3b, ++ PCF50606_REG_GPOC5 = 0x3c, ++ __NUM_PCF50606_REGS ++}; ++ ++enum pcf50606_reg_oocs { ++ PFC50606_OOCS_ONKEY = 0x01, ++ PCF50606_OOCS_EXTON = 0x02, ++ PCF50606_OOCS_PWROKRST = 0x04, ++ PCF50606_OOCS_BATOK = 0x08, ++ PCF50606_OOCS_BACKOK = 0x10, ++ PCF50606_OOCS_CHGOK = 0x20, ++ PCF50606_OOCS_TEMPOK = 0x40, ++ PCF50606_OOCS_WDTEXP = 0x80, ++}; ++ ++enum pcf50606_reg_oocc1 { ++ PCF50606_OOCC1_GOSTDBY = 0x01, ++ PCF50606_OOCC1_TOTRST = 0x02, ++ PCF50606_OOCC1_CLK32ON = 0x04, ++ PCF50606_OOCC1_WDTRST = 0x08, ++ PCF50606_OOCC1_RTCWAK = 0x10, ++ PCF50606_OOCC1_CHGWAK = 0x20, ++ PCF50606_OOCC1_EXTONWAK_HIGH = 0x40, ++ PCF50606_OOCC1_EXTONWAK_LOW = 0x80, ++}; ++ ++enum pcf50606_reg_oocc2 { ++ PCF50606_OOCC2_ONKEYDB_NONE = 0x00, ++ PCF50606_OOCC2_ONKEYDB_14ms = 0x01, ++ PCF50606_OOCC2_ONKEYDB_62ms = 0x02, ++ PCF50606_OOCC2_ONKEYDB_500ms = 0x03, ++ PCF50606_OOCC2_EXTONDB_NONE = 0x00, ++ PCF50606_OOCC2_EXTONDB_14ms = 0x04, ++ PCF50606_OOCC2_EXTONDB_62ms = 0x08, ++ PCF50606_OOCC2_EXTONDB_500ms = 0x0c, ++}; ++ ++enum pcf50606_reg_int1 { ++ PCF50606_INT1_ONKEYR = 0x01, /* ONKEY rising edge */ ++ PCF50606_INT1_ONKEYF = 0x02, /* ONKEY falling edge */ ++ PCF50606_INT1_ONKEY1S = 0x04, /* OMKEY at least 1sec low */ ++ PCF50606_INT1_EXTONR = 0x08, /* EXTON rising edge */ ++ PCF50606_INT1_EXTONF = 0x10, /* EXTON falling edge */ ++ PCF50606_INT1_SECOND = 0x40, /* RTC periodic second interrupt */ ++ PCF50606_INT1_ALARM = 0x80, /* RTC alarm time is reached */ ++}; ++ ++enum pcf50606_reg_int2 { ++ PCF50606_INT2_CHGINS = 0x01, /* Charger inserted */ ++ PCF50606_INT2_CHGRM = 0x02, /* Charger removed */ ++ PCF50606_INT2_CHGFOK = 0x04, /* Fast charging OK */ ++ PCF50606_INT2_CHGERR = 0x08, /* Error in charging mode */ ++ PCF50606_INT2_CHGFRDY = 0x10, /* Fast charge completed */ ++ PCF50606_INT2_CHGPROT = 0x20, /* Charging protection interrupt */ ++ PCF50606_INT2_CHGWD10S = 0x40, /* Charger watchdig expires in 10s */ ++ PCF50606_INT2_CHGWDEXP = 0x80, /* Charger watchdog expires */ ++}; ++ ++enum pcf50606_reg_int3 { ++ PCF50606_INT3_ADCRDY = 0x01, /* ADC conversion finished */ ++ PCF50606_INT3_ACDINS = 0x02, /* Accessory inserted */ ++ PCF50606_INT3_ACDREM = 0x04, /* Accessory removed */ ++ PCF50606_INT3_TSCPRES = 0x08, /* Touch screen pressed */ ++ PCF50606_INT3_LOWBAT = 0x40, /* Low battery voltage */ ++ PCF50606_INT3_HIGHTMP = 0x80, /* High temperature */ ++}; ++ ++/* used by PSSC, PWROKM, PWROKS, */ ++enum pcf50606_regu { ++ PCF50606_REGU_DCD = 0x01, /* DCD in phase 2 */ ++ PCF50606_REGU_DCDE = 0x02, /* DCDE in phase 2 */ ++ PCF50606_REGU_DCUD = 0x04, /* DCDU in phase 2 */ ++ PCF50606_REGU_IO = 0x08, /* IO in phase 2 */ ++ PCF50606_REGU_D1 = 0x10, /* D1 in phase 2 */ ++ PCF50606_REGU_D2 = 0x20, /* D2 in phase 2 */ ++ PCF50606_REGU_D3 = 0x40, /* D3 in phase 2 */ ++ PCF50606_REGU_LP = 0x80, /* LP in phase 2 */ ++}; ++ ++enum pcf50606_reg_dcdc4 { ++ PCF50606_DCDC4_MODE_AUTO = 0x00, ++ PCF50606_DCDC4_MODE_PWM = 0x01, ++ PCF50606_DCDC4_MODE_PCF = 0x02, ++ PCF50606_DCDC4_OFF_FLOAT = 0x00, ++ PCF50606_DCDC4_OFF_BYPASS = 0x04, ++ PCF50606_DCDC4_OFF_PULLDOWN = 0x08, ++ PCF50606_DCDC4_CURLIM_500mA = 0x00, ++ PCF50606_DCDC4_CURLIM_750mA = 0x10, ++ PCF50606_DCDC4_CURLIM_1000mA = 0x20, ++ PCF50606_DCDC4_CURLIM_1250mA = 0x30, ++ PCF50606_DCDC4_TOGGLE = 0x40, ++ PCF50606_DCDC4_REGSEL_DCDC2 = 0x80, ++}; ++ ++enum pcf50606_reg_dcdec2 { ++ PCF50606_DCDEC2_MODE_AUTO = 0x00, ++ PCF50606_DCDEC2_MODE_PWM = 0x01, ++ PCF50606_DCDEC2_MODE_PCF = 0x02, ++ PCF50606_DCDEC2_OFF_FLOAT = 0x00, ++ PCF50606_DCDEC2_OFF_BYPASS = 0x04, ++}; ++ ++enum pcf50606_reg_dcudc2 { ++ PCF50606_DCUDC2_MODE_AUTO = 0x00, ++ PCF50606_DCUDC2_MODE_PWM = 0x01, ++ PCF50606_DCUDC2_MODE_PCF = 0x02, ++ PCF50606_DCUDC2_OFF_FLOAT = 0x00, ++ PCF50606_DCUDC2_OFF_BYPASS = 0x04, ++}; ++ ++enum pcf50606_reg_adcc1 { ++ PCF50606_ADCC1_TSCMODACT = 0x01, ++ PCF50606_ADCC1_TSCMODSTB = 0x02, ++ PCF50606_ADCC1_TRATSET = 0x04, ++ PCF50606_ADCC1_NTCSWAPE = 0x08, ++ PCF50606_ADCC1_NTCSWAOFF = 0x10, ++ PCF50606_ADCC1_EXTSYNCBREAK = 0x20, ++ /* reserved */ ++ PCF50606_ADCC1_TSCINT = 0x80, ++}; ++ ++enum pcf50606_reg_adcc2 { ++ PCF50606_ADCC2_ADCSTART = 0x01, ++ /* see enum pcf50606_adcc2_adcmux */ ++ PCF50606_ADCC2_SYNC_NONE = 0x00, ++ PCF50606_ADCC2_SYNC_TXON = 0x20, ++ PCF50606_ADCC2_SYNC_PWREN1 = 0x40, ++ PCF50606_ADCC2_SYNC_PWREN2 = 0x60, ++ PCF50606_ADCC2_RES_10BIT = 0x00, ++ PCF50606_ADCC2_RES_8BIT = 0x80, ++}; ++ ++#define PCF50606_ADCC2_ADCMUX_MASK (0xf << 1) ++ ++#define ADCMUX_SHIFT 1 ++enum pcf50606_adcc2_adcmux { ++ PCF50606_ADCMUX_BATVOLT_RES = 0x0 << ADCMUX_SHIFT, ++ PCF50606_ADCMUX_BATVOLT_SUBTR = 0x1 << ADCMUX_SHIFT, ++ PCF50606_ADCMUX_ADCIN1_RES = 0x2 << ADCMUX_SHIFT, ++ PCF50606_ADCMUX_ADCIN1_SUBTR = 0x3 << ADCMUX_SHIFT, ++ PCF50606_ADCMUX_BATTEMP = 0x4 << ADCMUX_SHIFT, ++ PCF50606_ADCMUX_ADCIN2 = 0x5 << ADCMUX_SHIFT, ++ PCF50606_ADCMUX_ADCIN3 = 0x6 << ADCMUX_SHIFT, ++ PCF50606_ADCMUX_ADCIN3_RATIO = 0x7 << ADCMUX_SHIFT, ++ PCF50606_ADCMUX_XPOS = 0x8 << ADCMUX_SHIFT, ++ PCF50606_ADCMUX_YPOS = 0x9 << ADCMUX_SHIFT, ++ PCF50606_ADCMUX_P1 = 0xa << ADCMUX_SHIFT, ++ PCF50606_ADCMUX_P2 = 0xb << ADCMUX_SHIFT, ++ PCF50606_ADCMUX_BATVOLT_ADCIN1 = 0xc << ADCMUX_SHIFT, ++ PCF50606_ADCMUX_XY_SEQUENCE = 0xe << ADCMUX_SHIFT, ++ PCF50606_P1_P2_RESISTANCE = 0xf << ADCMUX_SHIFT, ++}; ++ ++enum pcf50606_adcs2 { ++ PCF50606_ADCS2_ADCRDY = 0x80, ++}; ++ ++enum pcf50606_reg_mbcc1 { ++ PCF50606_MBCC1_CHGAPE = 0x01, ++ PCF50606_MBCC1_AUTOFST = 0x02, ++#define PCF50606_MBCC1_CHGMOD_MASK 0x1c ++#define PCF50606_MBCC1_CHGMOD_SHIFT 2 ++ PCF50606_MBCC1_CHGMOD_QUAL = 0x00, ++ PCF50606_MBCC1_CHGMOD_PRE = 0x04, ++ PCF50606_MBCC1_CHGMOD_TRICKLE = 0x08, ++ PCF50606_MBCC1_CHGMOD_FAST_CCCV = 0x0c, ++ PCF50606_MBCC1_CHGMOD_FAST_NOCC = 0x10, ++ PCF50606_MBCC1_CHGMOD_FAST_NOCV = 0x14, ++ PCF50606_MBCC1_CHGMOD_FAST_SW = 0x18, ++ PCF50606_MBCC1_CHGMOD_IDLE = 0x1c, ++ PCF50606_MBCC1_DETMOD_LOWCHG = 0x20, ++ PCF50606_MBCC1_DETMOD_WDRST = 0x40, ++}; ++ ++enum pcf50606_reg_acdc1 { ++ PCF50606_ACDC1_ACDDET = 0x01, ++ PCF50606_ACDC1_THRSHLD_1V0 = 0x00, ++ PCF50606_ACDC1_THRSHLD_1V2 = 0x02, ++ PCF50606_ACDC1_THRSHLD_1V4 = 0x04, ++ PCF50606_ACDC1_THRSHLD_1V6 = 0x06, ++ PCF50606_ACDC1_THRSHLD_1V8 = 0x08, ++ PCF50606_ACDC1_THRSHLD_2V0 = 0x0a, ++ PCF50606_ACDC1_THRSHLD_2V2 = 0x0c, ++ PCF50606_ACDC1_THRSHLD_2V4 = 0x0e, ++ PCF50606_ACDC1_DISDB = 0x10, ++ PCF50606_ACDC1_ACDAPE = 0x80, ++}; ++ ++enum pcf50606_reg_bvmc { ++ PCF50606_BVMC_LOWBAT = 0x01, ++ PCF50606_BVMC_THRSHLD_NULL = 0x00, ++ PCF50606_BVMC_THRSHLD_2V8 = 0x02, ++ PCF50606_BVMC_THRSHLD_2V9 = 0x04, ++ PCF50606_BVMC_THRSHLD_3V = 0x08, ++ PCF50606_BVMC_THRSHLD_3V1 = 0x08, ++ PCF50606_BVMC_THRSHLD_3V2 = 0x0a, ++ PCF50606_BVMC_THRSHLD_3V3 = 0x0c, ++ PCF50606_BVMC_THRSHLD_3V4 = 0x0e, ++ PCF50606_BVMC_DISDB = 0x10, ++}; ++ ++enum pcf50606_reg_pwmc1 { ++ PCF50606_PWMC1_ACTSET = 0x01, ++ PCF50606_PWMC1_PWMDC_0_16 = 0x00, ++ PCF50606_PWMC1_PWMDC_1_16 = 0x02, ++ PCF50606_PWMC1_PWMDC_2_16 = 0x04, ++ PCF50606_PWMC1_PWMDC_3_16 = 0x06, ++ PCF50606_PWMC1_PWMDC_4_16 = 0x08, ++ PCF50606_PWMC1_PWMDC_5_16 = 0x0a, ++ PCF50606_PWMC1_PWMDC_6_16 = 0x0c, ++ PCF50606_PWMC1_PWMDC_7_16 = 0x0e, ++ PCF50606_PWMC1_PWMDC_8_16 = 0x10, ++ PCF50606_PWMC1_PWMDC_9_16 = 0x12, ++ PCF50606_PWMC1_PWMDC_10_16 = 0x14, ++ PCF50606_PWMC1_PWMDC_11_16 = 0x16, ++ PCF50606_PWMC1_PWMDC_12_16 = 0x18, ++ PCF50606_PWMC1_PWMDC_13_16 = 0x1a, ++ PCF50606_PWMC1_PWMDC_14_16 = 0x1c, ++ PCF50606_PWMC1_PWMDC_15_16 = 0x1e, ++ PCF50606_PWMC1_PRESC_512Hz = 0x20, ++ PCF50606_PWMC1_PRESC_256Hz = 0x40, ++ PCF50606_PWMC1_PRESC_64Hz = 0x60, ++ PCF50606_PWMC1_PRESC_56kHz = 0x80, ++ PCF50606_PWMC1_PRESC_28kHz = 0xa0, ++ PCF50606_PWMC1_PRESC_14kHz = 0xc0, ++ PCF50606_PWMC1_PRESC_7kHz = 0xe0, ++}; ++#define PCF50606_PWMC1_CLK_SHIFT 5 ++#define PCF50606_PWMC1_DC_SHIFT 1 ++ ++#endif /* _PCF50606_H */ ++ +diff -ruN --exclude='*.orig' --exclude='*.rej' linux-2.6.29-rc3.owrt/drivers/i2c/chips/pcf50633.h linux-2.6.29-rc3.owrt.om/drivers/i2c/chips/pcf50633.h +--- linux-2.6.29-rc3.owrt/drivers/i2c/chips/pcf50633.h 1970-01-01 01:00:00.000000000 +0100 ++++ linux-2.6.29-rc3.owrt.om/drivers/i2c/chips/pcf50633.h 2009-05-10 22:27:59.000000000 +0200 +@@ -0,0 +1,349 @@ ++#ifndef _PCF50633_H ++#define _PCF50633_H ++ ++/* Philips PCF50633 Power Managemnt Unit (PMU) driver ++ * (C) 2006-2007 by Openmoko, Inc. ++ * Author: Harald Welte <laforge@openmoko.org> ++ * ++ */ ++ ++enum pfc50633_regs { ++ PCF50633_REG_VERSION = 0x00, ++ PCF50633_REG_VARIANT = 0x01, ++ PCF50633_REG_INT1 = 0x02, /* Interrupt Status */ ++ PCF50633_REG_INT2 = 0x03, /* Interrupt Status */ ++ PCF50633_REG_INT3 = 0x04, /* Interrupt Status */ ++ PCF50633_REG_INT4 = 0x05, /* Interrupt Status */ ++ PCF50633_REG_INT5 = 0x06, /* Interrupt Status */ ++ PCF50633_REG_INT1M = 0x07, /* Interrupt Mask */ ++ PCF50633_REG_INT2M = 0x08, /* Interrupt Mask */ ++ PCF50633_REG_INT3M = 0x09, /* Interrupt Mask */ ++ PCF50633_REG_INT4M = 0x0a, /* Interrupt Mask */ ++ PCF50633_REG_INT5M = 0x0b, /* Interrupt Mask */ ++ PCF50633_REG_OOCSHDWN = 0x0c, ++ PCF50633_REG_OOCWAKE = 0x0d, ++ PCF50633_REG_OOCTIM1 = 0x0e, ++ PCF50633_REG_OOCTIM2 = 0x0f, ++ PCF50633_REG_OOCMODE = 0x10, ++ PCF50633_REG_OOCCTL = 0x11, ++ PCF50633_REG_OOCSTAT = 0x12, ++ PCF50633_REG_GPIOCTL = 0x13, ++ PCF50633_REG_GPIO1CFG = 0x14, ++ PCF50633_REG_GPIO2CFG = 0x15, ++ PCF50633_REG_GPIO3CFG = 0x16, ++ PCF50633_REG_GPOCFG = 0x17, ++ PCF50633_REG_BVMCTL = 0x18, ++ PCF50633_REG_SVMCTL = 0x19, ++ PCF50633_REG_AUTOOUT = 0x1a, ++ PCF50633_REG_AUTOENA = 0x1b, ++ PCF50633_REG_AUTOCTL = 0x1c, ++ PCF50633_REG_AUTOMXC = 0x1d, ++ PCF50633_REG_DOWN1OUT = 0x1e, ++ PCF50633_REG_DOWN1ENA = 0x1f, ++ PCF50633_REG_DOWN1CTL = 0x20, ++ PCF50633_REG_DOWN1MXC = 0x21, ++ PCF50633_REG_DOWN2OUT = 0x22, ++ PCF50633_REG_DOWN2ENA = 0x23, ++ PCF50633_REG_DOWN2CTL = 0x24, ++ PCF50633_REG_DOWN2MXC = 0x25, ++ PCF50633_REG_MEMLDOOUT = 0x26, ++ PCF50633_REG_MEMLDOENA = 0x27, ++ PCF50633_REG_LEDOUT = 0x28, ++ PCF50633_REG_LEDENA = 0x29, ++ PCF50633_REG_LEDCTL = 0x2a, ++ PCF50633_REG_LEDDIM = 0x2b, ++ /* reserved */ ++ PCF50633_REG_LDO1OUT = 0x2d, ++ PCF50633_REG_LDO1ENA = 0x2e, ++ PCF50633_REG_LDO2OUT = 0x2f, ++ PCF50633_REG_LDO2ENA = 0x30, ++ PCF50633_REG_LDO3OUT = 0x31, ++ PCF50633_REG_LDO3ENA = 0x32, ++ PCF50633_REG_LDO4OUT = 0x33, ++ PCF50633_REG_LDO4ENA = 0x34, ++ PCF50633_REG_LDO5OUT = 0x35, ++ PCF50633_REG_LDO5ENA = 0x36, ++ PCF50633_REG_LDO6OUT = 0x37, ++ PCF50633_REG_LDO6ENA = 0x38, ++ PCF50633_REG_HCLDOOUT = 0x39, ++ PCF50633_REG_HCLDOENA = 0x3a, ++ PCF50633_REG_STBYCTL1 = 0x3b, ++ PCF50633_REG_STBYCTL2 = 0x3c, ++ PCF50633_REG_DEBPF1 = 0x3d, ++ PCF50633_REG_DEBPF2 = 0x3e, ++ PCF50633_REG_DEBPF3 = 0x3f, ++ PCF50633_REG_HCLDOOVL = 0x40, ++ PCF50633_REG_DCDCSTAT = 0x41, ++ PCF50633_REG_LDOSTAT = 0x42, ++ PCF50633_REG_MBCC1 = 0x43, ++ PCF50633_REG_MBCC2 = 0x44, ++ PCF50633_REG_MBCC3 = 0x45, ++ PCF50633_REG_MBCC4 = 0x46, ++ PCF50633_REG_MBCC5 = 0x47, ++ PCF50633_REG_MBCC6 = 0x48, ++ PCF50633_REG_MBCC7 = 0x49, ++ PCF50633_REG_MBCC8 = 0x4a, ++ PCF50633_REG_MBCS1 = 0x4b, ++ PCF50633_REG_MBCS2 = 0x4c, ++ PCF50633_REG_MBCS3 = 0x4d, ++ PCF50633_REG_BBCCTL = 0x4e, ++ PCF50633_REG_ALMGAIN = 0x4f, ++ PCF50633_REG_ALMDATA = 0x50, ++ /* reserved */ ++ PCF50633_REG_ADCC3 = 0x52, ++ PCF50633_REG_ADCC2 = 0x53, ++ PCF50633_REG_ADCC1 = 0x54, ++ PCF50633_REG_ADCS1 = 0x55, ++ PCF50633_REG_ADCS2 = 0x56, ++ PCF50633_REG_ADCS3 = 0x57, ++ /* reserved */ ++ PCF50633_REG_RTCSC = 0x59, /* Second */ ++ PCF50633_REG_RTCMN = 0x5a, /* Minute */ ++ PCF50633_REG_RTCHR = 0x5b, /* Hour */ ++ PCF50633_REG_RTCWD = 0x5c, /* Weekday */ ++ PCF50633_REG_RTCDT = 0x5d, /* Day */ ++ PCF50633_REG_RTCMT = 0x5e, /* Month */ ++ PCF50633_REG_RTCYR = 0x5f, /* Year */ ++ PCF50633_REG_RTCSCA = 0x60, /* Alarm Second */ ++ PCF50633_REG_RTCMNA = 0x61, /* Alarm Minute */ ++ PCF50633_REG_RTCHRA = 0x62, /* Alarm Hour */ ++ PCF50633_REG_RTCWDA = 0x63, /* Alarm Weekday */ ++ PCF50633_REG_RTCDTA = 0x64, /* Alarm Day */ ++ PCF50633_REG_RTCMTA = 0x65, /* Alarm Month */ ++ PCF50633_REG_RTCYRA = 0x66, /* Alarm Year */ ++ ++ PCF50633_REG_MEMBYTE0 = 0x67, ++ PCF50633_REG_MEMBYTE1 = 0x68, ++ PCF50633_REG_MEMBYTE2 = 0x69, ++ PCF50633_REG_MEMBYTE3 = 0x6a, ++ PCF50633_REG_MEMBYTE4 = 0x6b, ++ PCF50633_REG_MEMBYTE5 = 0x6c, ++ PCF50633_REG_MEMBYTE6 = 0x6d, ++ PCF50633_REG_MEMBYTE7 = 0x6e, ++ /* reserved */ ++ PCF50633_REG_DCDCPFM = 0x84, ++ __NUM_PCF50633_REGS ++}; ++ ++ ++enum pcf50633_reg_oocshdwn { ++ PCF50633_OOCSHDWN_GOSTDBY = 0x01, ++ PCF50633_OOCSHDWN_TOTRST = 0x04, ++ PCF50633_OOCSHDWN_COLDBOOT = 0x08, ++}; ++ ++enum pcf50633_reg_oocwake { ++ PCF50633_OOCWAKE_ONKEY = 0x01, ++ PCF50633_OOCWAKE_EXTON1 = 0x02, ++ PCF50633_OOCWAKE_EXTON2 = 0x04, ++ PCF50633_OOCWAKE_EXTON3 = 0x08, ++ PCF50633_OOCWAKE_RTC = 0x10, ++ /* reserved */ ++ PCF50633_OOCWAKE_USB = 0x40, ++ PCF50633_OOCWAKE_ADP = 0x80, ++}; ++ ++enum pcf50633_reg_mbcc1 { ++ PCF50633_MBCC1_CHGENA = 0x01, /* Charger enable */ ++ PCF50633_MBCC1_AUTOSTOP = 0x02, ++ PCF50633_MBCC1_AUTORES = 0x04, /* automatic resume */ ++ PCF50633_MBCC1_RESUME = 0x08, /* explicit resume cmd */ ++ PCF50633_MBCC1_RESTART = 0x10, /* restart charging */ ++ PCF50633_MBCC1_PREWDTIME_60M = 0x20, /* max. precharging time */ ++ PCF50633_MBCC1_WDTIME_1H = 0x00, ++ PCF50633_MBCC1_WDTIME_2H = 0x40, ++ PCF50633_MBCC1_WDTIME_4H = 0x80, ++ PCF50633_MBCC1_WDTIME_6H = 0xc0, ++}; ++#define PCF50633_MBCC1_WDTIME_MASK 0xc0 ++ ++enum pcf50633_reg_mbcc2 { ++ PCF50633_MBCC2_VBATCOND_2V7 = 0x00, ++ PCF50633_MBCC2_VBATCOND_2V85 = 0x01, ++ PCF50633_MBCC2_VBATCOND_3V0 = 0x02, ++ PCF50633_MBCC2_VBATCOND_3V15 = 0x03, ++ PCF50633_MBCC2_VMAX_4V = 0x00, ++ PCF50633_MBCC2_VMAX_4V20 = 0x28, ++ PCF50633_MBCC2_VRESDEBTIME_64S = 0x80, /* debounce time (32/64sec) */ ++}; ++#define PCF50633_MBCC2_VBATCOND_MASK 0x03 ++#define PCF50633_MBCC2_VMAX_MASK 0x3c ++ ++enum pcf50633_reg_adcc1 { ++ PCF50633_ADCC1_ADCSTART = 0x01, ++ PCF50633_ADCC1_RES_10BIT = 0x02, ++ PCF50633_ADCC1_AVERAGE_NO = 0x00, ++ PCF50633_ADCC1_AVERAGE_4 = 0x04, ++ PCF50633_ADCC1_AVERAGE_8 = 0x08, ++ PCF50633_ADCC1_AVERAGE_16 = 0x0c, ++ ++ PCF50633_ADCC1_MUX_BATSNS_RES = 0x00, ++ PCF50633_ADCC1_MUX_BATSNS_SUBTR = 0x10, ++ PCF50633_ADCC1_MUX_ADCIN2_RES = 0x20, ++ PCF50633_ADCC1_MUX_ADCIN2_SUBTR = 0x30, ++ PCF50633_ADCC1_MUX_BATTEMP = 0x60, ++ PCF50633_ADCC1_MUX_ADCIN1 = 0x70, ++}; ++#define PCF50633_ADCC1_AVERAGE_MASK 0x0c ++#define PCF50633_ADCC1_ADCMUX_MASK 0xf0 ++ ++enum pcf50633_reg_adcc2 { ++ PCF50633_ADCC2_RATIO_NONE = 0x00, ++ PCF50633_ADCC2_RATIO_BATTEMP = 0x01, ++ PCF50633_ADCC2_RATIO_ADCIN1 = 0x02, ++ PCF50633_ADCC2_RATIO_BOTH = 0x03, ++ PCF50633_ADCC2_RATIOSETTL_100US = 0x04, ++}; ++#define PCF50633_ADCC2_RATIO_MASK 0x03 ++ ++enum pcf50633_reg_adcc3 { ++ PCF50633_ADCC3_ACCSW_EN = 0x01, ++ PCF50633_ADCC3_NTCSW_EN = 0x04, ++ PCF50633_ADCC3_RES_DIV_TWO = 0x10, ++ PCF50633_ADCC3_RES_DIV_THREE = 0x00, ++}; ++ ++enum pcf50633_reg_adcs3 { ++ PCF50633_ADCS3_REF_NTCSW = 0x00, ++ PCF50633_ADCS3_REF_ACCSW = 0x10, ++ PCF50633_ADCS3_REF_2V0 = 0x20, ++ PCF50633_ADCS3_REF_VISA = 0x30, ++ PCF50633_ADCS3_REF_2V0_2 = 0x70, ++ PCF50633_ADCS3_ADCRDY = 0x80, ++}; ++#define PCF50633_ADCS3_ADCDAT1L_MASK 0x03 ++#define PCF50633_ADCS3_ADCDAT2L_MASK 0x0c ++#define PCF50633_ADCS3_ADCDAT2L_SHIFT 2 ++#define PCF50633_ASCS3_REF_MASK 0x70 ++ ++enum pcf50633_regulator_enable { ++ PCF50633_REGULATOR_ON = 0x01, ++ PCF50633_REGULATOR_ON_GPIO1 = 0x02, ++ PCF50633_REGULATOR_ON_GPIO2 = 0x04, ++ PCF50633_REGULATOR_ON_GPIO3 = 0x08, ++}; ++#define PCF50633_REGULATOR_ON_MASK 0x0f ++ ++enum pcf50633_regulator_phase { ++ PCF50633_REGULATOR_ACTPH1 = 0x00, ++ PCF50633_REGULATOR_ACTPH2 = 0x10, ++ PCF50633_REGULATOR_ACTPH3 = 0x20, ++ PCF50633_REGULATOR_ACTPH4 = 0x30, ++}; ++#define PCF50633_REGULATOR_ACTPH_MASK 0x30 ++ ++enum pcf50633_reg_gpocfg { ++ PCF50633_GPOCFG_GPOSEL_0 = 0x00, ++ PCF50633_GPOCFG_GPOSEL_LED_NFET = 0x01, ++ PCF50633_GPOCFG_GPOSEL_SYSxOK = 0x02, ++ PCF50633_GPOCFG_GPOSEL_CLK32K = 0x03, ++ PCF50633_GPOCFG_GPOSEL_ADAPUSB = 0x04, ++ PCF50633_GPOCFG_GPOSEL_USBxOK = 0x05, ++ PCF50633_GPOCFG_GPOSEL_ACTPH4 = 0x06, ++ PCF50633_GPOCFG_GPOSEL_1 = 0x07, ++ PCF50633_GPOCFG_GPOSEL_INVERSE = 0x08, ++}; ++#define PCF50633_GPOCFG_GPOSEL_MASK 0x07 ++ ++#if 0 ++enum pcf50633_reg_mbcc1 { ++ PCF50633_MBCC1_CHGENA = 0x01, ++ PCF50633_MBCC1_AUTOSTOP = 0x02, ++ PCF50633_MBCC1_AUTORES = 0x04, ++ PCF50633_MBCC1_RESUME = 0x08, ++ PCF50633_MBCC1_RESTART = 0x10, ++ PCF50633_MBCC1_PREWDTIME_30MIN = 0x00, ++ PCF50633_MBCC1_PREWDTIME_60MIN = 0x20, ++ PCF50633_MBCC1_WDTIME_2HRS = 0x40, ++ PCF50633_MBCC1_WDTIME_4HRS = 0x80, ++ PCF50633_MBCC1_WDTIME_6HRS = 0xc0, ++}; ++ ++enum pcf50633_reg_mbcc2 { ++ PCF50633_MBCC2_VBATCOND_2V7 = 0x00, ++ PCF50633_MBCC2_VBATCOND_2V85 = 0x01, ++ PCF50633_MBCC2_VBATCOND_3V0 = 0x02, ++ PCF50633_MBCC2_VBATCOND_3V15 = 0x03, ++ PCF50633_MBCC2_VRESDEBTIME_64S = 0x80, ++}; ++#define PCF50633_MBCC2_VMAX_MASK 0x3c ++#endif ++ ++enum pcf50633_reg_mbcc7 { ++ PCF50633_MBCC7_USB_100mA = 0x00, ++ PCF50633_MBCC7_USB_500mA = 0x01, ++ PCF50633_MBCC7_USB_1000mA = 0x02, ++ PCF50633_MBCC7_USB_SUSPEND = 0x03, ++ PCF50633_MBCC7_BATTEMP_EN = 0x04, ++ PCF50633_MBCC7_BATSYSIMAX_1A6 = 0x00, ++ PCF50633_MBCC7_BATSYSIMAX_1A8 = 0x40, ++ PCF50633_MBCC7_BATSYSIMAX_2A0 = 0x80, ++ PCF50633_MBCC7_BATSYSIMAX_2A2 = 0xc0, ++}; ++#define PCF56033_MBCC7_USB_MASK 0x03 ++ ++enum pcf50633_reg_mbcc8 { ++ PCF50633_MBCC8_USBENASUS = 0x10, ++}; ++ ++enum pcf50633_reg_mbcs1 { ++ PCF50633_MBCS1_USBPRES = 0x01, ++ PCF50633_MBCS1_USBOK = 0x02, ++ PCF50633_MBCS1_ADAPTPRES = 0x04, ++ PCF50633_MBCS1_ADAPTOK = 0x08, ++ PCF50633_MBCS1_TBAT_OK = 0x00, ++ PCF50633_MBCS1_TBAT_ABOVE = 0x10, ++ PCF50633_MBCS1_TBAT_BELOW = 0x20, ++ PCF50633_MBCS1_TBAT_UNDEF = 0x30, ++ PCF50633_MBCS1_PREWDTEXP = 0x40, ++ PCF50633_MBCS1_WDTEXP = 0x80, ++}; ++ ++enum pcf50633_reg_mbcs2_mbcmod { ++ PCF50633_MBCS2_MBC_PLAY = 0x00, ++ PCF50633_MBCS2_MBC_USB_PRE = 0x01, ++ PCF50633_MBCS2_MBC_USB_PRE_WAIT = 0x02, ++ PCF50633_MBCS2_MBC_USB_FAST = 0x03, ++ PCF50633_MBCS2_MBC_USB_FAST_WAIT= 0x04, ++ PCF50633_MBCS2_MBC_USB_SUSPEND = 0x05, ++ PCF50633_MBCS2_MBC_ADP_PRE = 0x06, ++ PCF50633_MBCS2_MBC_ADP_PRE_WAIT = 0x07, ++ PCF50633_MBCS2_MBC_ADP_FAST = 0x08, ++ PCF50633_MBCS2_MBC_ADP_FAST_WAIT= 0x09, ++ PCF50633_MBCS2_MBC_BAT_FULL = 0x0a, ++ PCF50633_MBCS2_MBC_HALT = 0x0b, ++}; ++#define PCF50633_MBCS2_MBC_MASK 0x0f ++enum pcf50633_reg_mbcs2_chgstat { ++ PCF50633_MBCS2_CHGS_NONE = 0x00, ++ PCF50633_MBCS2_CHGS_ADAPTER = 0x10, ++ PCF50633_MBCS2_CHGS_USB = 0x20, ++ PCF50633_MBCS2_CHGS_BOTH = 0x30, ++}; ++#define PCF50633_MBCS2_RESSTAT_AUTO 0x40 ++ ++enum pcf50633_reg_mbcs3 { ++ PCF50633_MBCS3_USBLIM_PLAY = 0x01, ++ PCF50633_MBCS3_USBLIM_CGH = 0x02, ++ PCF50633_MBCS3_TLIM_PLAY = 0x04, ++ PCF50633_MBCS3_TLIM_CHG = 0x08, ++ PCF50633_MBCS3_ILIM = 0x10, /* 1: Ibat > Icutoff */ ++ PCF50633_MBCS3_VLIM = 0x20, /* 1: Vbat == Vmax */ ++ PCF50633_MBCS3_VBATSTAT = 0x40, /* 1: Vbat > Vbatcond */ ++ PCF50633_MBCS3_VRES = 0x80, /* 1: Vbat > Vth(RES) */ ++}; ++ ++/* this is to be provided by the board implementation */ ++extern const u_int8_t pcf50633_initial_regs[__NUM_PCF50633_REGS]; ++ ++void pcf50633_reg_write(u_int8_t reg, u_int8_t val); ++ ++u_int8_t pcf50633_reg_read(u_int8_t reg); ++ ++void pcf50633_reg_set_bit_mask(u_int8_t reg, u_int8_t mask, u_int8_t val); ++void pcf50633_reg_clear_bits(u_int8_t reg, u_int8_t bits); ++ ++void pcf50633_charge_autofast(int on); ++ ++#endif /* _PCF50606_H */ ++ +diff -ruN --exclude='*.orig' --exclude='*.rej' linux-2.6.29-rc3.owrt/drivers/i2c/i2c-core.c linux-2.6.29-rc3.owrt.om/drivers/i2c/i2c-core.c +--- linux-2.6.29-rc3.owrt/drivers/i2c/i2c-core.c 2009-05-10 22:08:42.000000000 +0200 ++++ linux-2.6.29-rc3.owrt.om/drivers/i2c/i2c-core.c 2009-05-10 22:27:59.000000000 +0200 +@@ -1,4 +1,3 @@ +-/* i2c-core.c - a device driver for the iic-bus interface */ + /* ------------------------------------------------------------------------- */ + /* Copyright (C) 1995-99 Simon G. Vogl + +@@ -158,10 +157,16 @@ + + if (!dev->driver) + return 0; ++#if 0 + driver = to_i2c_driver(dev->driver); + if (!driver->suspend) + return 0; + return driver->suspend(to_i2c_client(dev), mesg); ++#else ++ if (!dev->driver->suspend) ++ return 0; ++ return dev->driver->suspend(dev, mesg); ++#endif + } + + static int i2c_device_resume(struct device * dev) +@@ -170,10 +175,16 @@ + + if (!dev->driver) + return 0; ++#if 0 + driver = to_i2c_driver(dev->driver); + if (!driver->resume) + return 0; + return driver->resume(to_i2c_client(dev)); ++#else ++ if (!dev->driver->resume) ++ return 0; ++ return dev->driver->resume(dev); ++#endif + } + + static void i2c_client_release(struct device *dev) +@@ -1129,11 +1140,11 @@ + int err; + + /* Make sure the address is valid */ +- if (addr < 0x03 || addr > 0x77) { ++ /*if (addr < 0x03 || addr > 0x77) { + dev_warn(&adapter->dev, "Invalid probe address 0x%02x\n", + addr); + return -EINVAL; +- } ++ }*/ + + /* Skip if already in use */ + if (i2c_check_addr(adapter, addr)) +diff -ruN --exclude='*.orig' --exclude='*.rej' linux-2.6.29-rc3.owrt/drivers/input/keyboard/gpio_keys.c linux-2.6.29-rc3.owrt.om/drivers/input/keyboard/gpio_keys.c +--- linux-2.6.29-rc3.owrt/drivers/input/keyboard/gpio_keys.c 2009-05-10 22:04:49.000000000 +0200 ++++ linux-2.6.29-rc3.owrt.om/drivers/input/keyboard/gpio_keys.c 2009-05-10 22:27:59.000000000 +0200 +@@ -23,7 +23,7 @@ + #include <linux/input.h> + #include <linux/gpio_keys.h> + +-#include <asm/gpio.h> ++#include <mach/gpio.h> + + struct gpio_button_data { + struct gpio_keys_button *button; +diff -ruN --exclude='*.orig' --exclude='*.rej' linux-2.6.29-rc3.owrt/drivers/input/keyboard/Kconfig linux-2.6.29-rc3.owrt.om/drivers/input/keyboard/Kconfig +--- linux-2.6.29-rc3.owrt/drivers/input/keyboard/Kconfig 2009-05-10 22:04:49.000000000 +0200 ++++ linux-2.6.29-rc3.owrt.om/drivers/input/keyboard/Kconfig 2009-05-10 22:27:59.000000000 +0200 +@@ -332,4 +332,21 @@ + + To compile this driver as a module, choose M here: the + module will be called sh_keysc. ++config KEYBOARD_NEO1973 ++ tristate "FIC Neo1973 buttons" ++ depends on MACH_NEO1973 ++ default y ++ help ++ Say Y here to enable the buttons on the FIC Neo1973 ++ GSM phone. ++ ++ To compile this driver as a module, choose M here: the ++ module will be called neo1973kbd. ++ ++config KEYBOARD_QT2410 ++ tristate "QT2410 buttons" ++ depends on MACH_QT2410 ++ default y ++ ++ + endif +diff -ruN --exclude='*.orig' --exclude='*.rej' linux-2.6.29-rc3.owrt/drivers/input/keyboard/Makefile linux-2.6.29-rc3.owrt.om/drivers/input/keyboard/Makefile +--- linux-2.6.29-rc3.owrt/drivers/input/keyboard/Makefile 2009-05-10 22:04:49.000000000 +0200 ++++ linux-2.6.29-rc3.owrt.om/drivers/input/keyboard/Makefile 2009-05-10 22:27:59.000000000 +0200 +@@ -14,6 +14,8 @@ + obj-$(CONFIG_KEYBOARD_NEWTON) += newtonkbd.o + obj-$(CONFIG_KEYBOARD_STOWAWAY) += stowaway.o + obj-$(CONFIG_KEYBOARD_CORGI) += corgikbd.o ++obj-$(CONFIG_KEYBOARD_NEO1973) += neo1973kbd.o ++obj-$(CONFIG_KEYBOARD_QT2410) += qt2410kbd.o + obj-$(CONFIG_KEYBOARD_SPITZ) += spitzkbd.o + obj-$(CONFIG_KEYBOARD_TOSA) += tosakbd.o + obj-$(CONFIG_KEYBOARD_HIL) += hil_kbd.o +diff -ruN --exclude='*.orig' --exclude='*.rej' linux-2.6.29-rc3.owrt/drivers/input/keyboard/neo1973kbd.c linux-2.6.29-rc3.owrt.om/drivers/input/keyboard/neo1973kbd.c +--- linux-2.6.29-rc3.owrt/drivers/input/keyboard/neo1973kbd.c 1970-01-01 01:00:00.000000000 +0100 ++++ linux-2.6.29-rc3.owrt.om/drivers/input/keyboard/neo1973kbd.c 2009-05-10 22:27:59.000000000 +0200 +@@ -0,0 +1,467 @@ ++/* ++ * Keyboard driver for FIC Neo1973 GSM phone ++ * ++ * (C) 2006-2007 by Openmoko, Inc. ++ * Author: Harald Welte <laforge@openmoko.org> ++ * All rights reserved. ++ * ++ * inspired by corkgbd.c by Richard Purdie ++ * ++ * 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/delay.h> ++#include <linux/platform_device.h> ++#include <linux/init.h> ++#include <linux/input.h> ++#include <linux/interrupt.h> ++#include <linux/jiffies.h> ++#include <linux/module.h> ++#include <linux/slab.h> ++#include <linux/workqueue.h> ++ ++#include <mach/gpio.h> ++#include <asm/mach-types.h> ++ ++#ifdef CONFIG_PM ++extern int global_inside_suspend; ++#else ++#define global_inside_suspend 0 ++#endif ++ ++struct neo1973kbd { ++ struct platform_device *pdev; ++ struct input_dev *input; ++ struct device *cdev; ++ struct work_struct work; ++ int aux_state; ++ int work_in_progress; ++ int hp_irq_count_in_work; ++ int hp_irq_count; ++ int jack_irq; ++}; ++ ++static struct class *neo1973kbd_switch_class; ++ ++enum keys { ++ NEO1973_KEY_AUX, /* GTA01 / 02 only */ ++ NEO1973_KEY_HOLD, ++ NEO1973_KEY_JACK, ++ NEO1973_KEY_PLUS, /* GTA03 only */ ++ NEO1973_KEY_MINUS, /* GTA03 only */ ++}; ++ ++struct neo1973kbd_key { ++ const char * name; ++ irqreturn_t (*isr)(int irq, void *dev_id); ++ int irq; ++ int input_key; ++}; ++ ++static irqreturn_t neo1973kbd_aux_irq(int irq, void *dev_id); ++static irqreturn_t neo1973kbd_headphone_irq(int irq, void *dev_id); ++static irqreturn_t neo1973kbd_default_key_irq(int irq, void *dev_id); ++ ++ ++static struct neo1973kbd_key keys[] = { ++ [NEO1973_KEY_AUX] = { ++ .name = "Neo1973 AUX button", ++ .isr = neo1973kbd_aux_irq, ++ .input_key = KEY_PHONE, ++ }, ++ [NEO1973_KEY_HOLD] = { ++ .name = "Neo1973 HOLD button", ++ .isr = neo1973kbd_default_key_irq, ++ .input_key = KEY_PAUSE, ++ }, ++ [NEO1973_KEY_JACK] = { ++ .name = "Neo1973 Headphone jack", ++ .isr = neo1973kbd_headphone_irq, ++ }, ++ [NEO1973_KEY_PLUS] = { ++ .name = "GTA03 PLUS button", ++ .isr = neo1973kbd_default_key_irq, ++ .input_key = KEY_KPPLUS, ++ }, ++ [NEO1973_KEY_MINUS] = { ++ .name = "GTA03 MINUS button", ++ .isr = neo1973kbd_default_key_irq, ++ .input_key = KEY_KPMINUS, ++ }, ++}; ++ ++/* This timer section filters AUX button IRQ bouncing */ ++ ++static void aux_key_timer_f(unsigned long data); ++ ++static struct timer_list aux_key_timer = ++ TIMER_INITIALIZER(aux_key_timer_f, 0, 0); ++ ++#define AUX_TIMER_TIMEOUT (HZ >> 7) ++#define AUX_TIMER_ALLOWED_NOOP 2 ++#define AUX_TIMER_CONSECUTIVE_EVENTS 5 ++ ++struct neo1973kbd *timer_kbd; ++ ++static void aux_key_timer_f(unsigned long data) ++{ ++ static int noop_counter; ++ static int last_key = -1; ++ static int last_count; ++ int key_pressed; ++ ++ key_pressed = ++ !gpio_get_value(timer_kbd->pdev->resource[NEO1973_KEY_AUX].start); ++ if (machine_is_neo1973_gta02()) ++ key_pressed = !key_pressed; ++ ++ if (likely(key_pressed == last_key)) ++ last_count++; ++ else { ++ last_count = 1; ++ last_key = key_pressed; ++ } ++ ++ if (unlikely(last_count >= AUX_TIMER_CONSECUTIVE_EVENTS)) { ++ if (timer_kbd->aux_state != last_key) { ++ input_report_key(timer_kbd->input, KEY_PHONE, last_key); ++ input_sync(timer_kbd->input); ++ ++ timer_kbd->aux_state = last_key; ++ noop_counter = 0; ++ } ++ last_count = 0; ++ if (unlikely(++noop_counter > AUX_TIMER_ALLOWED_NOOP)) { ++ noop_counter = 0; ++ return; ++ } ++ } ++ ++ mod_timer(&aux_key_timer, jiffies + AUX_TIMER_TIMEOUT); ++} ++ ++static irqreturn_t neo1973kbd_aux_irq(int irq, void *dev) ++{ ++ mod_timer(&aux_key_timer, jiffies + AUX_TIMER_TIMEOUT); ++ ++ return IRQ_HANDLED; ++} ++ ++static irqreturn_t neo1973kbd_default_key_irq(int irq, void *dev_id) ++{ ++ struct neo1973kbd *kbd = dev_id; ++ int n; ++ ++ for (n = 0; n < ARRAY_SIZE(keys); n++) { ++ ++ if (irq != keys[n].irq) ++ continue; ++ ++ input_report_key(kbd->input, keys[n].input_key, ++ gpio_get_value(kbd->pdev->resource[n].start)); ++ input_sync(kbd->input); ++ } ++ ++ return IRQ_HANDLED; ++} ++ ++ ++static const char *event_array_jack[2][4] = { ++ [0] = { ++ "SWITCH_NAME=headset", ++ "SWITCH_STATE=0", ++ "EVENT=remove", ++ NULL ++ }, ++ [1] = { ++ "SWITCH_NAME=headset", ++ "SWITCH_STATE=1", ++ "EVENT=insert", ++ NULL ++ }, ++}; ++ ++static void neo1973kbd_jack_event(struct device *dev, int num) ++{ ++ kobject_uevent_env(&dev->kobj, KOBJ_CHANGE, (char **)event_array_jack[!!num]); ++} ++ ++ ++static void neo1973kbd_debounce_jack(struct work_struct *work) ++{ ++ struct neo1973kbd *kbd = container_of(work, struct neo1973kbd, work); ++ unsigned long flags; ++ int loop = 0; ++ int level; ++ ++ do { ++ /* ++ * we wait out any multiple interrupt ++ * stuttering in 100ms lumps ++ */ ++ do { ++ kbd->hp_irq_count_in_work = kbd->hp_irq_count; ++ msleep(100); ++ } while (kbd->hp_irq_count != kbd->hp_irq_count_in_work); ++ /* ++ * no new interrupts on jack for 100ms... ++ * ok we will report it ++ */ ++ level = gpio_get_value(kbd->pdev->resource[NEO1973_KEY_JACK].start); ++ input_report_switch(kbd->input, SW_HEADPHONE_INSERT, level); ++ input_sync(kbd->input); ++ neo1973kbd_jack_event(kbd->cdev, level); ++ /* ++ * we go around the outer loop again if we detect that more ++ * interrupts came while we are servicing here. But we have ++ * to sequence it carefully with interrupts off ++ */ ++ local_save_flags(flags); ++ /* no interrupts during this work means we can exit the work */ ++ loop = !!(kbd->hp_irq_count != kbd->hp_irq_count_in_work); ++ if (!loop) ++ kbd->work_in_progress = 0; ++ local_irq_restore(flags); ++ /* ++ * interrupt that comes here will either queue a new work action ++ * since work_in_progress is cleared now, or be dealt with ++ * when we loop. ++ */ ++ } while (loop); ++} ++ ++ ++static irqreturn_t neo1973kbd_headphone_irq(int irq, void *dev_id) ++{ ++ struct neo1973kbd *neo1973kbd_data = dev_id; ++ ++ /* ++ * this interrupt is prone to bouncing and userspace doesn't like ++ * to have to deal with that kind of thing. So we do not accept ++ * that a jack interrupt is equal to a jack event. Instead we fire ++ * some work on the first interrupt, and it hangs about in 100ms units ++ * until no more interrupts come. Then it accepts the state it finds ++ * for jack insert and reports it once ++ */ ++ ++ neo1973kbd_data->hp_irq_count++; ++ /* ++ * the first interrupt we see for a while, we fire the work item ++ * and record the interrupt count when we did that. If more interrupts ++ * come in the meanwhile, we can tell by the difference in that ++ * stored count and hp_irq_count which increments every interrupt ++ */ ++ if (!neo1973kbd_data->work_in_progress) { ++ neo1973kbd_data->jack_irq = irq; ++ neo1973kbd_data->hp_irq_count_in_work = ++ neo1973kbd_data->hp_irq_count; ++ if (!schedule_work(&neo1973kbd_data->work)) ++ printk(KERN_ERR ++ "Unable to schedule headphone debounce\n"); ++ else ++ neo1973kbd_data->work_in_progress = 1; ++ } ++ ++ return IRQ_HANDLED; ++} ++ ++#ifdef CONFIG_PM ++static int neo1973kbd_suspend(struct platform_device *dev, pm_message_t state) ++{ ++ if (machine_is_neo1973_gta02()) { ++ disable_irq(keys[NEO1973_KEY_AUX].irq); ++ del_timer_sync(&aux_key_timer); ++ } ++ return 0; ++} ++ ++static int neo1973kbd_resume(struct platform_device *dev) ++{ ++ if (machine_is_neo1973_gta02()) ++ enable_irq(keys[NEO1973_KEY_AUX].irq); ++ ++ return 0; ++} ++#else ++#define neo1973kbd_suspend NULL ++#define neo1973kbd_resume NULL ++#endif ++ ++static ssize_t neo1973kbd_switch_name_show(struct device *dev, ++ struct device_attribute *attr, char *buf) ++{ ++ return sprintf(buf, "%s\n", "neo1973 Headset Jack"); ++} ++ ++static ssize_t neo1973kbd_switch_state_show(struct device *dev, ++ struct device_attribute *attr, char *buf) ++{ ++ struct neo1973kbd *kbd = dev_get_drvdata(dev); ++ return sprintf(buf, "%d\n", ++ gpio_get_value(kbd->pdev->resource[NEO1973_KEY_JACK].start)); ++} ++ ++static DEVICE_ATTR(name, S_IRUGO , neo1973kbd_switch_name_show, NULL); ++static DEVICE_ATTR(state, S_IRUGO , neo1973kbd_switch_state_show, NULL); ++ ++static int neo1973kbd_probe(struct platform_device *pdev) ++{ ++ struct neo1973kbd *neo1973kbd; ++ struct input_dev *input_dev; ++ int rc; ++ int irq; ++ int n; ++ ++ neo1973kbd = kzalloc(sizeof(struct neo1973kbd), GFP_KERNEL); ++ input_dev = input_allocate_device(); ++ if (!neo1973kbd || !input_dev) { ++ kfree(neo1973kbd); ++ input_free_device(input_dev); ++ return -ENOMEM; ++ } ++ ++ neo1973kbd->pdev = pdev; ++ timer_kbd = neo1973kbd; ++ ++ if (pdev->resource[0].flags != 0) ++ return -EINVAL; ++ ++ platform_set_drvdata(pdev, neo1973kbd); ++ ++ neo1973kbd->input = input_dev; ++ ++ INIT_WORK(&neo1973kbd->work, neo1973kbd_debounce_jack); ++ ++ input_dev->name = "Neo1973 Buttons"; ++ input_dev->phys = "neo1973kbd/input0"; ++ input_dev->id.bustype = BUS_HOST; ++ input_dev->id.vendor = 0x0001; ++ input_dev->id.product = 0x0001; ++ input_dev->id.version = 0x0100; ++ input_dev->dev.parent = &pdev->dev; ++ ++ input_dev->evbit[0] = BIT(EV_KEY) | BIT(EV_SW); ++ set_bit(SW_HEADPHONE_INSERT, input_dev->swbit); ++ set_bit(KEY_PHONE, input_dev->keybit); ++ set_bit(KEY_PAUSE, input_dev->keybit); ++ ++ rc = input_register_device(neo1973kbd->input); ++ if (rc) ++ goto out_register; ++ ++ neo1973kbd->cdev = device_create(neo1973kbd_switch_class, ++ &pdev->dev, 0, neo1973kbd, "headset"); ++ if (unlikely(IS_ERR(neo1973kbd->cdev))) { ++ rc = PTR_ERR(neo1973kbd->cdev); ++ goto out_device_create; ++ } ++ ++ rc = device_create_file(neo1973kbd->cdev, &dev_attr_name); ++ if(rc) ++ goto out_device_create_file; ++ ++ rc = device_create_file(neo1973kbd->cdev, &dev_attr_state); ++ if(rc) ++ goto out_device_create_file; ++ ++ /* register GPIO IRQs */ ++ for(n = 0; n < min(pdev->num_resources, ARRAY_SIZE(keys)); n++) { ++ ++ if (!pdev->resource[0].start) ++ continue; ++ ++ irq = gpio_to_irq(pdev->resource[n].start); ++ if (irq < 0) ++ continue; ++ ++ if (request_irq(irq, keys[n].isr, IRQF_DISABLED | ++ IRQF_TRIGGER_RISING | IRQF_TRIGGER_FALLING, ++ keys[n].name, neo1973kbd)) { ++ dev_err(&pdev->dev, "Can't get IRQ %u\n", irq); ++ ++ /* unwind any irq registrations and fail */ ++ ++ while (n > 0) { ++ n--; ++ free_irq(gpio_to_irq(pdev->resource[n].start), ++ neo1973kbd); ++ } ++ goto out_device_create_file; ++ } ++ ++ keys[n].irq = irq; ++ } ++ ++ /* ++ * GTA01 revisions before Bv4 can't be resumed by the PMU, so we use ++ * resume by AUX. ++ */ ++ if (machine_is_neo1973_gta01()) ++ enable_irq_wake(keys[NEO1973_KEY_AUX].irq); ++ ++ enable_irq_wake(keys[NEO1973_KEY_JACK].irq); ++ ++ return 0; ++ ++out_device_create_file: ++ device_unregister(neo1973kbd->cdev); ++out_device_create: ++ input_unregister_device(neo1973kbd->input); ++out_register: ++ input_free_device(neo1973kbd->input); ++ platform_set_drvdata(pdev, NULL); ++ kfree(neo1973kbd); ++ ++ return -ENODEV; ++} ++ ++static int neo1973kbd_remove(struct platform_device *pdev) ++{ ++ struct neo1973kbd *neo1973kbd = platform_get_drvdata(pdev); ++ ++ free_irq(gpio_to_irq(pdev->resource[2].start), neo1973kbd); ++ free_irq(gpio_to_irq(pdev->resource[1].start), neo1973kbd); ++ free_irq(gpio_to_irq(pdev->resource[0].start), neo1973kbd); ++ ++ device_unregister(neo1973kbd->cdev); ++ input_unregister_device(neo1973kbd->input); ++ input_free_device(neo1973kbd->input); ++ platform_set_drvdata(pdev, NULL); ++ kfree(neo1973kbd); ++ ++ return 0; ++} ++ ++static struct platform_driver neo1973kbd_driver = { ++ .probe = neo1973kbd_probe, ++ .remove = neo1973kbd_remove, ++ .suspend = neo1973kbd_suspend, ++ .resume = neo1973kbd_resume, ++ .driver = { ++ .name = "neo1973-button", ++ }, ++}; ++ ++static int __devinit neo1973kbd_init(void) ++{ ++ neo1973kbd_switch_class = class_create(THIS_MODULE, "switch"); ++ if (IS_ERR(neo1973kbd_switch_class)) ++ return PTR_ERR(neo1973kbd_switch_class); ++ return platform_driver_register(&neo1973kbd_driver); ++} ++ ++static void __exit neo1973kbd_exit(void) ++{ ++ platform_driver_unregister(&neo1973kbd_driver); ++ class_destroy(neo1973kbd_switch_class); ++} ++ ++module_init(neo1973kbd_init); ++module_exit(neo1973kbd_exit); ++ ++MODULE_AUTHOR("Harald Welte <laforge@openmoko.org>"); ++MODULE_DESCRIPTION("FIC Neo1973 buttons input driver"); ++MODULE_LICENSE("GPL"); +diff -ruN --exclude='*.orig' --exclude='*.rej' linux-2.6.29-rc3.owrt/drivers/input/keyboard/qt2410kbd.c linux-2.6.29-rc3.owrt.om/drivers/input/keyboard/qt2410kbd.c +--- linux-2.6.29-rc3.owrt/drivers/input/keyboard/qt2410kbd.c 1970-01-01 01:00:00.000000000 +0100 ++++ linux-2.6.29-rc3.owrt.om/drivers/input/keyboard/qt2410kbd.c 2009-05-10 22:27:59.000000000 +0200 +@@ -0,0 +1,231 @@ ++/* ++ * Keyboard driver for Armzone QT2410 ++ * ++ * (C) 2006 by Openmoko, Inc. ++ * Author: Harald Welte <laforge@openmoko.org> ++ * All rights reserved. ++ * ++ * 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/delay.h> ++#include <linux/platform_device.h> ++#include <linux/init.h> ++#include <linux/input.h> ++#include <linux/interrupt.h> ++#include <linux/jiffies.h> ++#include <linux/module.h> ++#include <linux/slab.h> ++ ++#include <mach/hardware.h> ++#include <mach/gta01.h> ++ ++struct gta01kbd { ++ struct input_dev *input; ++ unsigned int suspended; ++ unsigned long suspend_jiffies; ++}; ++ ++static irqreturn_t gta01kbd_interrupt(int irq, void *dev_id) ++{ ++ struct gta01kbd *gta01kbd_data = dev_id; ++ ++ /* FIXME: use GPIO from platform_dev resources */ ++ if (s3c2410_gpio_getpin(S3C2410_GPF0)) ++ input_report_key(gta01kbd_data->input, KEY_PHONE, 1); ++ else ++ input_report_key(gta01kbd_data->input, KEY_PHONE, 0); ++ ++ input_sync(gta01kbd_data->input); ++ ++ return IRQ_HANDLED; ++} ++ ++ ++#ifdef CONFIG_PM ++static int gta01kbd_suspend(struct platform_device *dev, pm_message_t state) ++{ ++ struct gta01kbd *gta01kbd = platform_get_drvdata(dev); ++ ++ gta01kbd->suspended = 1; ++ ++ return 0; ++} ++ ++static int gta01kbd_resume(struct platform_device *dev) ++{ ++ struct gta01kbd *gta01kbd = platform_get_drvdata(dev); ++ ++ gta01kbd->suspended = 0; ++ ++ return 0; ++} ++#else ++#define gta01kbd_suspend NULL ++#define gta01kbd_resume NULL ++#endif ++ ++static int gta01kbd_probe(struct platform_device *pdev) ++{ ++ struct gta01kbd *gta01kbd; ++ struct input_dev *input_dev; ++ int irq_911; ++ int rc = 0; ++ ++ gta01kbd = kzalloc(sizeof(struct gta01kbd), GFP_KERNEL); ++ if (!gta01kbd) { ++ rc = -ENOMEM; ++ goto bail; ++ } ++ input_dev = input_allocate_device(); ++ if (!gta01kbd || !input_dev) { ++ rc = -ENOMEM; ++ goto bail_free; ++ } ++ ++ if (pdev->resource[0].flags != 0) {\ ++ rc = -EINVAL; ++ goto bail_free_dev; ++ } ++ ++ irq_911 = s3c2410_gpio_getirq(pdev->resource[0].start); ++ if (irq_911 < 0) { ++ rc = -EINVAL; ++ goto bail_free_dev; ++ } ++ ++ platform_set_drvdata(pdev, gta01kbd); ++ ++ gta01kbd->input = input_dev; ++ ++#if 0 ++ spin_lock_init(>a01kbd->lock); ++ /* Init Keyboard rescan timer */ ++ init_timer(&corgikbd->timer); ++ corgikbd->timer.function = corgikbd_timer_callback; ++ corgikbd->timer.data = (unsigned long) corgikbd; ++ ++ /* Init Hinge Timer */ ++ init_timer(&corgikbd->htimer); ++ corgikbd->htimer.function = corgikbd_hinge_timer; ++ corgikbd->htimer.data = (unsigned long) corgikbd; ++ ++ corgikbd->suspend_jiffies=jiffies; ++ ++ memcpy(corgikbd->keycode, corgikbd_keycode, sizeof(corgikbd->keycode)); ++#endif ++ ++ input_dev->name = "QT2410 Buttons"; ++ input_dev->phys = "qt2410kbd/input0"; ++ input_dev->id.bustype = BUS_HOST; ++ input_dev->id.vendor = 0x0001; ++ input_dev->id.product = 0x0001; ++ input_dev->id.version = 0x0100; ++ ++ input_dev->evbit[0] = BIT(EV_KEY); ++#if 0 ++ input_dev->keycode = gta01kbd->keycode; ++ input_dev->keycodesize = sizeof(unsigned char); ++ input_dev->keycodemax = ARRAY_SIZE(corgikbd_keycode); ++ ++ for (i = 0; i < ARRAY_SIZE(corgikbd_keycode); i++) ++ set_bit(corgikbd->keycode[i], input_dev->keybit); ++ clear_bit(0, input_dev->keybit); ++ set_bit(SW_LID, input_dev->swbit); ++ set_bit(SW_TABLET_MODE, input_dev->swbit); ++ set_bit(SW_HEADPHONE_INSERT, input_dev->swbit); ++#endif ++ ++ rc = input_register_device(gta01kbd->input); ++ if (rc) ++ goto bail_free_dev; ++ ++ s3c2410_gpio_cfgpin(S3C2410_GPF0, S3C2410_GPF0_EINT0); ++ if (request_irq(irq_911, gta01kbd_interrupt, ++ IRQF_DISABLED | IRQF_TRIGGER_RISING | ++ IRQF_TRIGGER_FALLING, "qt2410kbd_eint0", gta01kbd)) ++ printk(KERN_WARNING "gta01kbd: Can't get IRQ\n"); ++ enable_irq_wake(irq_911); ++ ++ /* FIXME: headphone insert */ ++ ++#if 0 ++ mod_timer(&corgikbd->htimer, jiffies + msecs_to_jiffies(HINGE_SCAN_INTERVAL)); ++ ++ /* Setup sense interrupts - RisingEdge Detect, sense lines as inputs */ ++ for (i = 0; i < CORGI_KEY_SENSE_NUM; i++) { ++ pxa_gpio_mode(CORGI_GPIO_KEY_SENSE(i) | GPIO_IN); ++ if (request_irq(CORGI_IRQ_GPIO_KEY_SENSE(i), corgikbd_interrupt, ++ SA_INTERRUPT | SA_TRIGGER_RISING, ++ "corgikbd", corgikbd)) ++ printk(KERN_WARNING "corgikbd: Can't get IRQ: %d!\n", i); ++ } ++ ++ /* Set Strobe lines as outputs - set high */ ++ for (i = 0; i < CORGI_KEY_STROBE_NUM; i++) ++ pxa_gpio_mode(CORGI_GPIO_KEY_STROBE(i) | GPIO_OUT | GPIO_DFLT_HIGH); ++ ++ /* Setup the headphone jack as an input */ ++ pxa_gpio_mode(CORGI_GPIO_AK_INT | GPIO_IN); ++#endif ++ ++ return 0; ++ ++bail_free_dev: ++ input_free_device(input_dev); ++bail_free: ++ kfree(gta01kbd); ++bail: ++ return rc; ++} ++ ++static int gta01kbd_remove(struct platform_device *pdev) ++{ ++ struct gta01kbd *gta01kbd = platform_get_drvdata(pdev); ++ ++ free_irq(s3c2410_gpio_getirq(pdev->resource[0].start), gta01kbd); ++#if 0 ++ int i; ++ ++ for (i = 0; i < CORGI_KEY_SENSE_NUM; i++) ++ free_irq(CORGI_IRQ_GPIO_KEY_SENSE(i), corgikbd); ++ ++ del_timer_sync(&corgikbd->htimer); ++ del_timer_sync(&corgikbd->timer); ++#endif ++ input_unregister_device(gta01kbd->input); ++ ++ kfree(gta01kbd); ++ ++ return 0; ++} ++ ++static struct platform_driver gta01kbd_driver = { ++ .probe = gta01kbd_probe, ++ .remove = gta01kbd_remove, ++ .suspend = gta01kbd_suspend, ++ .resume = gta01kbd_resume, ++ .driver = { ++ .name = "qt2410-button", ++ }, ++}; ++ ++static int __devinit gta01kbd_init(void) ++{ ++ return platform_driver_register(>a01kbd_driver); ++} ++ ++static void __exit gta01kbd_exit(void) ++{ ++ platform_driver_unregister(>a01kbd_driver); ++} ++ ++module_init(gta01kbd_init); ++module_exit(gta01kbd_exit); ++ ++MODULE_AUTHOR("Harald Welte <laforge@openmoko.org>"); ++MODULE_DESCRIPTION("Armzone QT2410 Buttons Driver"); ++MODULE_LICENSE("GPL"); +diff -ruN --exclude='*.orig' --exclude='*.rej' linux-2.6.29-rc3.owrt/drivers/input/misc/Kconfig linux-2.6.29-rc3.owrt.om/drivers/input/misc/Kconfig +--- linux-2.6.29-rc3.owrt/drivers/input/misc/Kconfig 2009-05-10 22:04:49.000000000 +0200 ++++ linux-2.6.29-rc3.owrt.om/drivers/input/misc/Kconfig 2009-05-10 22:27:59.000000000 +0200 +@@ -220,12 +220,26 @@ + Say Y here if you want to support the built-in real time clock + of the HP SDC controller. + ++config INPUT_LIS302DL ++ tristate "STmicro LIS302DL 3-axis accelerometer" ++ depends on SPI_MASTER ++ help ++ SPI driver for the STmicro LIS302DL 3-axis accelerometer. ++ ++ The userspece interface is a 3-axis (X/Y/Z) relative movement ++ Linux input device, reporting REL_[XYZ] events. ++ + config INPUT_PCF50633_PMU + tristate "PCF50633 PMU events" + depends on MFD_PCF50633 + help +- Say Y to include support for delivering PMU events via input +- layer on NXP PCF50633. ++ Say Y to include support for input events on NXP PCF50633. ++ ++config INPUT_PCF50606_PMU ++ tristate "PCF50606 PMU events" ++ depends on MFD_PCF50606 ++ help ++ Say Y to include support for input events on NXP PCF50606. + + config INPUT_GPIO_BUTTONS + tristate "Polled GPIO buttons interface" +diff -ruN --exclude='*.orig' --exclude='*.rej' linux-2.6.29-rc3.owrt/drivers/input/misc/lis302dl.c linux-2.6.29-rc3.owrt.om/drivers/input/misc/lis302dl.c +--- linux-2.6.29-rc3.owrt/drivers/input/misc/lis302dl.c 1970-01-01 01:00:00.000000000 +0100 ++++ linux-2.6.29-rc3.owrt.om/drivers/input/misc/lis302dl.c 2009-05-10 22:27:59.000000000 +0200 +@@ -0,0 +1,958 @@ ++/* Linux kernel driver for the ST LIS302D 3-axis accelerometer ++ * ++ * Copyright (C) 2007-2008 by Openmoko, Inc. ++ * Author: Harald Welte <laforge@openmoko.org> ++ * converted to private bitbang by: ++ * Andy Green <andy@openmoko.com> ++ * ability to set acceleration threshold added by: ++ * Simon Kagstrom <simon.kagstrom@gmail.com> ++ * All rights reserved. ++ * ++ * 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, ++ * MA 02111-1307 USA ++ * ++ * TODO ++ * * statistics for overflow events ++ * * configuration interface (sysfs) for ++ * * enable/disable x/y/z axis data ready ++ * * enable/disable resume from freee fall / click ++ * * free fall / click parameters ++ * * high pass filter parameters ++ */ ++#include <linux/kernel.h> ++#include <linux/types.h> ++#include <linux/module.h> ++#include <linux/device.h> ++#include <linux/platform_device.h> ++#include <linux/delay.h> ++#include <linux/irq.h> ++#include <linux/interrupt.h> ++#include <linux/sysfs.h> ++#include <linux/spi/spi.h> ++ ++#include <linux/lis302dl.h> ++ ++/* Utility functions */ ++static u8 __reg_read(struct lis302dl_info *lis, u8 reg) ++{ ++ struct spi_message msg; ++ struct spi_transfer t; ++ u8 data[2] = {0xc0 | reg}; ++ int rc; ++ ++ spi_message_init(&msg); ++ memset(&t, 0, sizeof t); ++ t.len = 2; ++ spi_message_add_tail(&t, &msg); ++ t.tx_buf = &data[0]; ++ t.rx_buf = &data[0]; ++ ++ /* Should complete without blocking */ ++ rc = spi_non_blocking_transfer(lis->spi, &msg); ++ if (rc < 0) { ++ dev_err(lis->dev, "Error reading register\n"); ++ return rc; ++ } ++ ++ return data[1]; ++} ++ ++static void __reg_write(struct lis302dl_info *lis, u8 reg, u8 val) ++{ ++ struct spi_message msg; ++ struct spi_transfer t; ++ u8 data[2] = {reg, val}; ++ ++ spi_message_init(&msg); ++ memset(&t, 0, sizeof t); ++ t.len = 2; ++ spi_message_add_tail(&t, &msg); ++ t.tx_buf = &data[0]; ++ t.rx_buf = &data[0]; ++ ++ /* Completes without blocking */ ++ if (spi_non_blocking_transfer(lis->spi, &msg) < 0) ++ dev_err(lis->dev, "Error writing register\n"); ++} ++ ++static void __reg_set_bit_mask(struct lis302dl_info *lis, u8 reg, u8 mask, ++ u8 val) ++{ ++ u_int8_t tmp; ++ ++ val &= mask; ++ ++ tmp = __reg_read(lis, reg); ++ tmp &= ~mask; ++ tmp |= val; ++ __reg_write(lis, reg, tmp); ++} ++ ++static int __ms_to_duration(struct lis302dl_info *lis, int ms) ++{ ++ /* If we have 400 ms sampling rate, the stepping is 2.5 ms, ++ * on 100 ms the stepping is 10ms */ ++ if (lis->flags & LIS302DL_F_DR) ++ return min((ms * 10) / 25, 637); ++ ++ return min(ms / 10, 2550); ++} ++ ++static int __duration_to_ms(struct lis302dl_info *lis, int duration) ++{ ++ if (lis->flags & LIS302DL_F_DR) ++ return (duration * 25) / 10; ++ ++ return duration * 10; ++} ++ ++static u8 __mg_to_threshold(struct lis302dl_info *lis, int mg) ++{ ++ /* If FS is set each bit is 71mg, otherwise 18mg. The THS register ++ * has 7 bits for the threshold value */ ++ if (lis->flags & LIS302DL_F_FS) ++ return min(mg / 71, 127); ++ ++ return min(mg / 18, 127); ++} ++ ++static int __threshold_to_mg(struct lis302dl_info *lis, u8 threshold) ++{ ++ if (lis->flags & LIS302DL_F_FS) ++ return threshold * 71; ++ ++ return threshold * 18; ++} ++ ++/* interrupt handling related */ ++ ++enum lis302dl_intmode { ++ LIS302DL_INTMODE_GND = 0x00, ++ LIS302DL_INTMODE_FF_WU_1 = 0x01, ++ LIS302DL_INTMODE_FF_WU_2 = 0x02, ++ LIS302DL_INTMODE_FF_WU_12 = 0x03, ++ LIS302DL_INTMODE_DATA_READY = 0x04, ++ LIS302DL_INTMODE_CLICK = 0x07, ++}; ++ ++static void __lis302dl_int_mode(struct device *dev, int int_pin, ++ enum lis302dl_intmode mode) ++{ ++ struct lis302dl_info *lis = dev_get_drvdata(dev); ++ ++ switch (int_pin) { ++ case 1: ++ __reg_set_bit_mask(lis, LIS302DL_REG_CTRL3, 0x07, mode); ++ break; ++ case 2: ++ __reg_set_bit_mask(lis, LIS302DL_REG_CTRL3, 0x38, mode << 3); ++ break; ++ default: ++ BUG(); ++ } ++} ++ ++static void __enable_wakeup(struct lis302dl_info *lis) ++{ ++ __reg_write(lis, LIS302DL_REG_CTRL1, 0); ++ ++ /* First zero to get to a known state */ ++ __reg_write(lis, LIS302DL_REG_FF_WU_CFG_1, LIS302DL_FFWUCFG_XHIE | ++ LIS302DL_FFWUCFG_YHIE | LIS302DL_FFWUCFG_ZHIE | ++ LIS302DL_FFWUCFG_LIR); ++ __reg_write(lis, LIS302DL_REG_FF_WU_THS_1, ++ __mg_to_threshold(lis, lis->wakeup.threshold)); ++ __reg_write(lis, LIS302DL_REG_FF_WU_DURATION_1, ++ __ms_to_duration(lis, lis->wakeup.duration)); ++ ++ /* Route the interrupt for wakeup */ ++ __lis302dl_int_mode(lis->dev, 1, ++ LIS302DL_INTMODE_FF_WU_1); ++ ++ __reg_read(lis, LIS302DL_REG_HP_FILTER_RESET); ++ __reg_read(lis, LIS302DL_REG_OUT_X); ++ __reg_read(lis, LIS302DL_REG_OUT_Y); ++ __reg_read(lis, LIS302DL_REG_OUT_Z); ++ __reg_read(lis, LIS302DL_REG_STATUS); ++ __reg_read(lis, LIS302DL_REG_FF_WU_SRC_1); ++ __reg_read(lis, LIS302DL_REG_FF_WU_SRC_2); ++ __reg_write(lis, LIS302DL_REG_CTRL1, LIS302DL_CTRL1_PD | 7); ++} ++ ++static void __enable_data_collection(struct lis302dl_info *lis) ++{ ++ u_int8_t ctrl1 = LIS302DL_CTRL1_PD | LIS302DL_CTRL1_Xen | ++ LIS302DL_CTRL1_Yen | LIS302DL_CTRL1_Zen; ++ ++ /* make sure we're powered up and generate data ready */ ++ __reg_set_bit_mask(lis, LIS302DL_REG_CTRL1, ctrl1, ctrl1); ++ ++ /* If the threshold is zero, let the device generated an interrupt ++ * on each datum */ ++ if (lis->threshold == 0) { ++ __reg_write(lis, LIS302DL_REG_CTRL2, 0); ++ __lis302dl_int_mode(lis->dev, 1, LIS302DL_INTMODE_DATA_READY); ++ __lis302dl_int_mode(lis->dev, 2, LIS302DL_INTMODE_DATA_READY); ++ } else { ++ __reg_write(lis, LIS302DL_REG_CTRL2, ++ LIS302DL_CTRL2_HPFF1); ++ __reg_write(lis, LIS302DL_REG_FF_WU_THS_1, ++ __mg_to_threshold(lis, lis->threshold)); ++ __reg_write(lis, LIS302DL_REG_FF_WU_DURATION_1, ++ __ms_to_duration(lis, lis->duration)); ++ ++ /* Clear the HP filter "starting point" */ ++ __reg_read(lis, LIS302DL_REG_HP_FILTER_RESET); ++ __reg_write(lis, LIS302DL_REG_FF_WU_CFG_1, ++ LIS302DL_FFWUCFG_XHIE | LIS302DL_FFWUCFG_YHIE | ++ LIS302DL_FFWUCFG_ZHIE | LIS302DL_FFWUCFG_LIR); ++ __lis302dl_int_mode(lis->dev, 1, LIS302DL_INTMODE_FF_WU_12); ++ __lis302dl_int_mode(lis->dev, 2, LIS302DL_INTMODE_FF_WU_12); ++ } ++} ++ ++#if 0 ++static void _report_btn_single(struct input_dev *inp, int btn) ++{ ++ input_report_key(inp, btn, 1); ++ input_sync(inp); ++ input_report_key(inp, btn, 0); ++} ++ ++static void _report_btn_double(struct input_dev *inp, int btn) ++{ ++ input_report_key(inp, btn, 1); ++ input_sync(inp); ++ input_report_key(inp, btn, 0); ++ input_sync(inp); ++ input_report_key(inp, btn, 1); ++ input_sync(inp); ++ input_report_key(inp, btn, 0); ++} ++#endif ++ ++ ++static void lis302dl_bitbang_read_sample(struct lis302dl_info *lis) ++{ ++ u8 data[(LIS302DL_REG_OUT_Z - LIS302DL_REG_STATUS) + 2] = {0xC0 | LIS302DL_REG_STATUS}; ++ u8 *read = data + 1; ++ unsigned long flags; ++ int mg_per_sample = __threshold_to_mg(lis, 1); ++ struct spi_message msg; ++ struct spi_transfer t; ++ ++ spi_message_init(&msg); ++ memset(&t, 0, sizeof t); ++ t.len = sizeof(data); ++ spi_message_add_tail(&t, &msg); ++ t.tx_buf = &data[0]; ++ t.rx_buf = &data[0]; ++ ++ /* grab the set of register containing status and XYZ data */ ++ ++ local_irq_save(flags); ++ ++ /* Should complete without blocking */ ++ if (spi_non_blocking_transfer(lis->spi, &msg) < 0) ++ dev_err(lis->dev, "Error reading registers\n"); ++ ++ local_irq_restore(flags); ++ ++ /* ++ * at the minute the test below fails 50% of the time due to ++ * a problem with level interrupts causing ISRs to get called twice. ++ * This is a workaround for that, but actually this test is still ++ * valid and the information can be used for overrrun stats. ++ */ ++ ++ /* has any kind of overrun been observed by the lis302dl? */ ++ if (read[0] & (LIS302DL_STATUS_XOR | ++ LIS302DL_STATUS_YOR | ++ LIS302DL_STATUS_ZOR)) ++ lis->overruns++; ++ ++ /* we have a valid sample set? */ ++ if (read[0] & LIS302DL_STATUS_XYZDA) { ++ input_report_abs(lis->input_dev, ABS_X, mg_per_sample * ++ (s8)read[LIS302DL_REG_OUT_X - LIS302DL_REG_STATUS]); ++ input_report_abs(lis->input_dev, ABS_Y, mg_per_sample * ++ (s8)read[LIS302DL_REG_OUT_Y - LIS302DL_REG_STATUS]); ++ input_report_abs(lis->input_dev, ABS_Z, mg_per_sample * ++ (s8)read[LIS302DL_REG_OUT_Z - LIS302DL_REG_STATUS]); ++ ++ input_sync(lis->input_dev); ++ } ++ ++ if (lis->threshold) ++ /* acknowledge the wakeup source */ ++ __reg_read(lis, LIS302DL_REG_FF_WU_SRC_1); ++} ++ ++static irqreturn_t lis302dl_interrupt(int irq, void *_lis) ++{ ++ struct lis302dl_info *lis = _lis; ++ ++ lis302dl_bitbang_read_sample(lis); ++ return IRQ_HANDLED; ++} ++ ++/* sysfs */ ++ ++static ssize_t show_overruns(struct device *dev, struct device_attribute *attr, ++ char *buf) ++{ ++ struct lis302dl_info *lis = dev_get_drvdata(dev); ++ ++ return sprintf(buf, "%u\n", lis->overruns); ++} ++ ++static DEVICE_ATTR(overruns, S_IRUGO, show_overruns, NULL); ++ ++static ssize_t show_rate(struct device *dev, struct device_attribute *attr, ++ char *buf) ++{ ++ struct lis302dl_info *lis = dev_get_drvdata(dev); ++ u8 ctrl1; ++ unsigned long flags; ++ ++ local_irq_save(flags); ++ ctrl1 = __reg_read(lis, LIS302DL_REG_CTRL1); ++ local_irq_restore(flags); ++ ++ return sprintf(buf, "%d\n", ctrl1 & LIS302DL_CTRL1_DR ? 400 : 100); ++} ++ ++static ssize_t set_rate(struct device *dev, struct device_attribute *attr, ++ const char *buf, size_t count) ++{ ++ struct lis302dl_info *lis = dev_get_drvdata(dev); ++ unsigned long flags; ++ ++ local_irq_save(flags); ++ ++ if (!strcmp(buf, "400\n")) { ++ __reg_set_bit_mask(lis, LIS302DL_REG_CTRL1, LIS302DL_CTRL1_DR, ++ LIS302DL_CTRL1_DR); ++ lis->flags |= LIS302DL_F_DR; ++ } else { ++ __reg_set_bit_mask(lis, LIS302DL_REG_CTRL1, LIS302DL_CTRL1_DR, ++ 0); ++ lis->flags &= ~LIS302DL_F_DR; ++ } ++ local_irq_restore(flags); ++ ++ return count; ++} ++ ++static DEVICE_ATTR(sample_rate, S_IRUGO | S_IWUSR, show_rate, set_rate); ++ ++static ssize_t show_scale(struct device *dev, struct device_attribute *attr, ++ char *buf) ++{ ++ struct lis302dl_info *lis = dev_get_drvdata(dev); ++ u_int8_t ctrl1; ++ unsigned long flags; ++ ++ local_irq_save(flags); ++ ctrl1 = __reg_read(lis, LIS302DL_REG_CTRL1); ++ local_irq_restore(flags); ++ ++ return sprintf(buf, "%s\n", ctrl1 & LIS302DL_CTRL1_FS ? "9.2" : "2.3"); ++} ++ ++static ssize_t set_scale(struct device *dev, struct device_attribute *attr, ++ const char *buf, size_t count) ++{ ++ struct lis302dl_info *lis = dev_get_drvdata(dev); ++ unsigned long flags; ++ ++ local_irq_save(flags); ++ ++ if (!strcmp(buf, "9.2\n")) { ++ __reg_set_bit_mask(lis, LIS302DL_REG_CTRL1, LIS302DL_CTRL1_FS, ++ LIS302DL_CTRL1_FS); ++ lis->flags |= LIS302DL_F_FS; ++ } else { ++ __reg_set_bit_mask(lis, LIS302DL_REG_CTRL1, LIS302DL_CTRL1_FS, ++ 0); ++ lis->flags &= ~LIS302DL_F_FS; ++ } ++ ++ if (lis->flags & LIS302DL_F_INPUT_OPEN) ++ __enable_data_collection(lis); ++ ++ local_irq_restore(flags); ++ ++ return count; ++} ++ ++static DEVICE_ATTR(full_scale, S_IRUGO | S_IWUSR, show_scale, set_scale); ++ ++static ssize_t show_threshold(struct device *dev, struct device_attribute *attr, ++ char *buf) ++{ ++ struct lis302dl_info *lis = dev_get_drvdata(dev); ++ ++ /* Display the device view of the threshold setting */ ++ return sprintf(buf, "%d\n", __threshold_to_mg(lis, ++ __mg_to_threshold(lis, lis->threshold))); ++} ++ ++static ssize_t set_threshold(struct device *dev, struct device_attribute *attr, ++ const char *buf, size_t count) ++{ ++ struct lis302dl_info *lis = dev_get_drvdata(dev); ++ unsigned int val; ++ ++ if (sscanf(buf, "%u\n", &val) != 1) ++ return -EINVAL; ++ /* 8g is the maximum if FS is 1 */ ++ if (val > 8000) ++ return -ERANGE; ++ ++ /* Set the threshold and write it out if the device is used */ ++ lis->threshold = val; ++ ++ if (lis->flags & LIS302DL_F_INPUT_OPEN) { ++ unsigned long flags; ++ ++ local_irq_save(flags); ++ __enable_data_collection(lis); ++ local_irq_restore(flags); ++ } ++ ++ return count; ++} ++ ++static DEVICE_ATTR(threshold, S_IRUGO | S_IWUSR, show_threshold, set_threshold); ++ ++static ssize_t show_duration(struct device *dev, struct device_attribute *attr, ++ char *buf) ++{ ++ struct lis302dl_info *lis = dev_get_drvdata(dev); ++ ++ return sprintf(buf, "%d\n", __duration_to_ms(lis, ++ __ms_to_duration(lis, lis->duration))); ++} ++ ++static ssize_t set_duration(struct device *dev, struct device_attribute *attr, ++ const char *buf, size_t count) ++{ ++ struct lis302dl_info *lis = dev_get_drvdata(dev); ++ unsigned int val; ++ ++ if (sscanf(buf, "%u\n", &val) != 1) ++ return -EINVAL; ++ if (val > 2550) ++ return -ERANGE; ++ ++ lis->duration = val; ++ if (lis->flags & LIS302DL_F_INPUT_OPEN) ++ __reg_write(lis, LIS302DL_REG_FF_WU_DURATION_1, ++ __ms_to_duration(lis, lis->duration)); ++ ++ return count; ++} ++ ++static DEVICE_ATTR(duration, S_IRUGO | S_IWUSR, show_duration, set_duration); ++ ++static ssize_t lis302dl_dump(struct device *dev, struct device_attribute *attr, ++ char *buf) ++{ ++ struct lis302dl_info *lis = dev_get_drvdata(dev); ++ int n = 0; ++ u8 reg[0x40]; ++ char *end = buf; ++ unsigned long flags; ++ ++ local_irq_save(flags); ++ ++ for (n = 0; n < sizeof(reg); n++) ++ reg[n] = __reg_read(lis, n); ++ ++ local_irq_restore(flags); ++ ++ for (n = 0; n < sizeof(reg); n += 16) { ++ hex_dump_to_buffer(reg + n, 16, 16, 1, end, 128, 0); ++ end += strlen(end); ++ *end++ = '\n'; ++ *end++ = '\0'; ++ } ++ ++ return end - buf; ++} ++static DEVICE_ATTR(dump, S_IRUGO, lis302dl_dump, NULL); ++ ++/* Configure freefall/wakeup interrupts */ ++static ssize_t set_wakeup_threshold(struct device *dev, ++ struct device_attribute *attr, const char *buf, size_t count) ++{ ++ struct lis302dl_info *lis = dev_get_drvdata(dev); ++ unsigned int threshold; ++ ++ if (sscanf(buf, "%u\n", &threshold) != 1) ++ return -EINVAL; ++ ++ if (threshold > 8000) ++ return -ERANGE; ++ ++ /* Zero turns the feature off */ ++ if (threshold == 0) { ++ if (lis->flags & LIS302DL_F_IRQ_WAKE) { ++ disable_irq_wake(lis->pdata->interrupt); ++ lis->flags &= ~LIS302DL_F_IRQ_WAKE; ++ } ++ ++ return count; ++ } ++ ++ lis->wakeup.threshold = threshold; ++ ++ if (!(lis->flags & LIS302DL_F_IRQ_WAKE)) { ++ enable_irq_wake(lis->pdata->interrupt); ++ lis->flags |= LIS302DL_F_IRQ_WAKE; ++ } ++ ++ return count; ++} ++ ++static ssize_t show_wakeup_threshold(struct device *dev, ++ struct device_attribute *attr, char *buf) ++{ ++ struct lis302dl_info *lis = dev_get_drvdata(dev); ++ ++ /* All events off? */ ++ if (lis->wakeup.threshold == 0) ++ return sprintf(buf, "off\n"); ++ ++ return sprintf(buf, "%u\n", lis->wakeup.threshold); ++} ++ ++static DEVICE_ATTR(wakeup_threshold, S_IRUGO | S_IWUSR, show_wakeup_threshold, ++ set_wakeup_threshold); ++ ++static ssize_t set_wakeup_duration(struct device *dev, ++ struct device_attribute *attr, const char *buf, size_t count) ++{ ++ struct lis302dl_info *lis = dev_get_drvdata(dev); ++ unsigned int duration; ++ ++ if (sscanf(buf, "%u\n", &duration) != 1) ++ return -EINVAL; ++ ++ if (duration > 2550) ++ return -ERANGE; ++ ++ lis->wakeup.duration = duration; ++ ++ return count; ++} ++ ++static ssize_t show_wakeup_duration(struct device *dev, ++ struct device_attribute *attr, char *buf) ++{ ++ struct lis302dl_info *lis = dev_get_drvdata(dev); ++ ++ return sprintf(buf, "%u\n", lis->wakeup.duration); ++} ++ ++static DEVICE_ATTR(wakeup_duration, S_IRUGO | S_IWUSR, show_wakeup_duration, ++ set_wakeup_duration); ++ ++static struct attribute *lis302dl_sysfs_entries[] = { ++ &dev_attr_sample_rate.attr, ++ &dev_attr_full_scale.attr, ++ &dev_attr_threshold.attr, ++ &dev_attr_duration.attr, ++ &dev_attr_dump.attr, ++ &dev_attr_wakeup_threshold.attr, ++ &dev_attr_wakeup_duration.attr, ++ &dev_attr_overruns.attr, ++ NULL ++}; ++ ++static struct attribute_group lis302dl_attr_group = { ++ .name = NULL, ++ .attrs = lis302dl_sysfs_entries, ++}; ++ ++/* input device handling and driver core interaction */ ++ ++static int lis302dl_input_open(struct input_dev *inp) ++{ ++ struct lis302dl_info *lis = input_get_drvdata(inp); ++ unsigned long flags; ++ ++ local_irq_save(flags); ++ ++ __enable_data_collection(lis); ++ lis->flags |= LIS302DL_F_INPUT_OPEN; ++ ++ local_irq_restore(flags); ++ ++ return 0; ++} ++ ++static void lis302dl_input_close(struct input_dev *inp) ++{ ++ struct lis302dl_info *lis = input_get_drvdata(inp); ++ u_int8_t ctrl1 = LIS302DL_CTRL1_Xen | LIS302DL_CTRL1_Yen | ++ LIS302DL_CTRL1_Zen; ++ unsigned long flags; ++ ++ local_irq_save(flags); ++ ++ /* since the input core already serializes access and makes sure we ++ * only see close() for the close of the last user, we can safely ++ * disable the data ready events */ ++ __reg_set_bit_mask(lis, LIS302DL_REG_CTRL1, ctrl1, 0x00); ++ lis->flags &= ~LIS302DL_F_INPUT_OPEN; ++ ++ /* however, don't power down the whole device if still needed */ ++ if (!(lis->flags & LIS302DL_F_WUP_FF || ++ lis->flags & LIS302DL_F_WUP_CLICK)) { ++ __reg_set_bit_mask(lis, LIS302DL_REG_CTRL1, LIS302DL_CTRL1_PD, ++ 0x00); ++ } ++ local_irq_restore(flags); ++} ++ ++/* get the device to reload its coefficients from EEPROM and wait for it ++ * to complete ++ */ ++ ++static int __lis302dl_reset_device(struct lis302dl_info *lis) ++{ ++ int timeout = 10; ++ ++ __reg_write(lis, LIS302DL_REG_CTRL2, ++ LIS302DL_CTRL2_BOOT | LIS302DL_CTRL2_FDS); ++ ++ while ((__reg_read(lis, LIS302DL_REG_CTRL2) ++ & LIS302DL_CTRL2_BOOT) && (timeout--)) ++ mdelay(1); ++ ++ return !!(timeout < 0); ++} ++ ++static int __devinit lis302dl_probe(struct spi_device *spi) ++{ ++ int rc; ++ struct lis302dl_info *lis; ++ u_int8_t wai; ++ unsigned long flags; ++ struct lis302dl_platform_data *pdata = spi->dev.platform_data; ++ ++ spi->mode = SPI_MODE_3; ++ rc = spi_setup(spi); ++ if (rc < 0) { ++ dev_err(&spi->dev, "spi_setup failed\n"); ++ return rc; ++ } ++ ++ lis = kzalloc(sizeof(*lis), GFP_KERNEL); ++ if (!lis) ++ return -ENOMEM; ++ ++ lis->dev = &spi->dev; ++ lis->spi = spi; ++ ++ dev_set_drvdata(lis->dev, lis); ++ ++ lis->pdata = pdata; ++ ++ rc = sysfs_create_group(&lis->dev->kobj, &lis302dl_attr_group); ++ if (rc) { ++ dev_err(lis->dev, "error creating sysfs group\n"); ++ goto bail_free_lis; ++ } ++ ++ /* initialize input layer details */ ++ lis->input_dev = input_allocate_device(); ++ if (!lis->input_dev) { ++ dev_err(lis->dev, "Unable to allocate input device\n"); ++ goto bail_sysfs; ++ } ++ ++ input_set_drvdata(lis->input_dev, lis); ++ lis->input_dev->name = pdata->name; ++ /* SPI Bus not defined as a valid bus for input subsystem*/ ++ lis->input_dev->id.bustype = BUS_I2C; /* lie about it */ ++ lis->input_dev->open = lis302dl_input_open; ++ lis->input_dev->close = lis302dl_input_close; ++ ++ rc = input_register_device(lis->input_dev); ++ if (rc) { ++ dev_err(lis->dev, "error %d registering input device\n", rc); ++ goto bail_inp_dev; ++ } ++ ++ local_irq_save(flags); ++ /* Configure our IO */ ++ (lis->pdata->lis302dl_suspend_io)(lis, 1); ++ ++ wai = __reg_read(lis, LIS302DL_REG_WHO_AM_I); ++ if (wai != LIS302DL_WHO_AM_I_MAGIC) { ++ dev_err(lis->dev, "unknown who_am_i signature 0x%02x\n", wai); ++ dev_set_drvdata(lis->dev, NULL); ++ rc = -ENODEV; ++ local_irq_restore(flags); ++ goto bail_inp_reg; ++ } ++ ++ set_bit(EV_ABS, lis->input_dev->evbit); ++ input_set_abs_params(lis->input_dev, ABS_X, 0, 0, 0, 0); ++ input_set_abs_params(lis->input_dev, ABS_Y, 0, 0, 0, 0); ++ input_set_abs_params(lis->input_dev, ABS_Z, 0, 0, 0, 0); ++ ++ ++ lis->threshold = 0; ++ lis->duration = 0; ++ memset(&lis->wakeup, 0, sizeof(lis->wakeup)); ++ ++ if (__lis302dl_reset_device(lis)) ++ dev_err(lis->dev, "device BOOT reload failed\n"); ++ ++ /* force us powered */ ++ __reg_write(lis, LIS302DL_REG_CTRL1, LIS302DL_CTRL1_PD | ++ LIS302DL_CTRL1_Xen | ++ LIS302DL_CTRL1_Yen | ++ LIS302DL_CTRL1_Zen); ++ mdelay(1); ++ ++ __reg_write(lis, LIS302DL_REG_CTRL2, 0); ++ __reg_write(lis, LIS302DL_REG_CTRL3, ++ LIS302DL_CTRL3_PP_OD | LIS302DL_CTRL3_IHL); ++ __reg_write(lis, LIS302DL_REG_FF_WU_THS_1, 0x0); ++ __reg_write(lis, LIS302DL_REG_FF_WU_DURATION_1, 0x00); ++ __reg_write(lis, LIS302DL_REG_FF_WU_CFG_1, 0x0); ++ ++ /* start off in powered down mode; we power up when someone opens us */ ++ __reg_write(lis, LIS302DL_REG_CTRL1, LIS302DL_CTRL1_Xen | ++ LIS302DL_CTRL1_Yen | LIS302DL_CTRL1_Zen); ++ ++ if (pdata->open_drain) ++ /* switch interrupt to open collector, active-low */ ++ __reg_write(lis, LIS302DL_REG_CTRL3, ++ LIS302DL_CTRL3_PP_OD | LIS302DL_CTRL3_IHL); ++ else ++ /* push-pull, active-low */ ++ __reg_write(lis, LIS302DL_REG_CTRL3, LIS302DL_CTRL3_IHL); ++ ++ __lis302dl_int_mode(lis->dev, 1, LIS302DL_INTMODE_GND); ++ __lis302dl_int_mode(lis->dev, 2, LIS302DL_INTMODE_GND); ++ ++ __reg_read(lis, LIS302DL_REG_STATUS); ++ __reg_read(lis, LIS302DL_REG_FF_WU_SRC_1); ++ __reg_read(lis, LIS302DL_REG_FF_WU_SRC_2); ++ __reg_read(lis, LIS302DL_REG_CLICK_SRC); ++ local_irq_restore(flags); ++ ++ dev_info(lis->dev, "Found %s\n", pdata->name); ++ ++ lis->pdata = pdata; ++ ++ set_irq_handler(lis->pdata->interrupt, handle_level_irq); ++ ++ rc = request_irq(lis->pdata->interrupt, lis302dl_interrupt, ++ IRQF_TRIGGER_LOW, "lis302dl", lis); ++ ++ if (rc < 0) { ++ dev_err(lis->dev, "error requesting IRQ %d\n", ++ lis->pdata->interrupt); ++ goto bail_inp_reg; ++ } ++ return 0; ++ ++bail_inp_reg: ++ input_unregister_device(lis->input_dev); ++bail_inp_dev: ++ input_free_device(lis->input_dev); ++bail_sysfs: ++ sysfs_remove_group(&lis->dev->kobj, &lis302dl_attr_group); ++bail_free_lis: ++ kfree(lis); ++ return rc; ++} ++ ++static int __devexit lis302dl_remove(struct spi_device *spi) ++{ ++ struct lis302dl_info *lis = dev_get_drvdata(&spi->dev); ++ unsigned long flags; ++ ++ /* Disable interrupts */ ++ if (lis->flags & LIS302DL_F_IRQ_WAKE) ++ disable_irq_wake(lis->pdata->interrupt); ++ free_irq(lis->pdata->interrupt, lis); ++ ++ /* Reset and power down the device */ ++ local_irq_save(flags); ++ __reg_write(lis, LIS302DL_REG_CTRL3, 0x00); ++ __reg_write(lis, LIS302DL_REG_CTRL2, 0x00); ++ __reg_write(lis, LIS302DL_REG_CTRL1, 0x00); ++ local_irq_restore(flags); ++ ++ /* Cleanup resources */ ++ sysfs_remove_group(&spi->dev.kobj, &lis302dl_attr_group); ++ input_unregister_device(lis->input_dev); ++ if (lis->input_dev) ++ input_free_device(lis->input_dev); ++ dev_set_drvdata(lis->dev, NULL); ++ kfree(lis); ++ ++ return 0; ++} ++ ++#ifdef CONFIG_PM ++ ++static u8 regs_to_save[] = { ++ LIS302DL_REG_CTRL1, ++ LIS302DL_REG_CTRL2, ++ LIS302DL_REG_CTRL3, ++ LIS302DL_REG_FF_WU_CFG_1, ++ LIS302DL_REG_FF_WU_THS_1, ++ LIS302DL_REG_FF_WU_DURATION_1, ++ LIS302DL_REG_FF_WU_CFG_2, ++ LIS302DL_REG_FF_WU_THS_2, ++ LIS302DL_REG_FF_WU_DURATION_2, ++ LIS302DL_REG_CLICK_CFG, ++ LIS302DL_REG_CLICK_THSY_X, ++ LIS302DL_REG_CLICK_THSZ, ++ LIS302DL_REG_CLICK_TIME_LIMIT, ++ LIS302DL_REG_CLICK_LATENCY, ++ LIS302DL_REG_CLICK_WINDOW, ++ ++}; ++ ++static int lis302dl_suspend(struct spi_device *spi, pm_message_t state) ++{ ++ struct lis302dl_info *lis = dev_get_drvdata(&spi->dev); ++ unsigned long flags; ++ u_int8_t tmp; ++ int n; ++ ++ /* determine if we want to wake up from the accel. */ ++ if (lis->flags & LIS302DL_F_WUP_CLICK) ++ return 0; ++ ++ disable_irq(lis->pdata->interrupt); ++ local_irq_save(flags); ++ ++ /* ++ * When we share SPI over multiple sensors, there is a race here ++ * that one or more sensors will lose. In that case, the shared ++ * SPI bus GPIO will be in sleep mode and partially pulled down. So ++ * we explicitly put our IO into "wake" mode here before the final ++ * traffic to the sensor. ++ */ ++ (lis->pdata->lis302dl_suspend_io)(lis, 1); ++ ++ /* save registers */ ++ for (n = 0; n < ARRAY_SIZE(regs_to_save); n++) ++ lis->regs[regs_to_save[n]] = ++ __reg_read(lis, regs_to_save[n]); ++ ++ /* power down or enable wakeup */ ++ ++ if (lis->wakeup.threshold == 0) { ++ tmp = __reg_read(lis, LIS302DL_REG_CTRL1); ++ tmp &= ~LIS302DL_CTRL1_PD; ++ __reg_write(lis, LIS302DL_REG_CTRL1, tmp); ++ } else ++ __enable_wakeup(lis); ++ ++ /* place our IO to the device in sleep-compatible states */ ++ (lis->pdata->lis302dl_suspend_io)(lis, 0); ++ ++ local_irq_restore(flags); ++ ++ return 0; ++} ++ ++static int lis302dl_resume(struct spi_device *spi) ++{ ++ struct lis302dl_info *lis = dev_get_drvdata(&spi->dev); ++ unsigned long flags; ++ int n; ++ ++ if (lis->flags & LIS302DL_F_WUP_CLICK) ++ return 0; ++ ++ local_irq_save(flags); ++ ++ /* get our IO to the device back in operational states */ ++ (lis->pdata->lis302dl_suspend_io)(lis, 1); ++ ++ /* resume from powerdown first! */ ++ __reg_write(lis, LIS302DL_REG_CTRL1, ++ LIS302DL_CTRL1_PD | ++ LIS302DL_CTRL1_Xen | ++ LIS302DL_CTRL1_Yen | ++ LIS302DL_CTRL1_Zen); ++ mdelay(1); ++ ++ if (__lis302dl_reset_device(lis)) ++ dev_err(&spi->dev, "device BOOT reload failed\n"); ++ ++ lis->regs[LIS302DL_REG_CTRL1] |= LIS302DL_CTRL1_PD | ++ LIS302DL_CTRL1_Xen | ++ LIS302DL_CTRL1_Yen | ++ LIS302DL_CTRL1_Zen; ++ ++ /* restore registers after resume */ ++ for (n = 0; n < ARRAY_SIZE(regs_to_save); n++) ++ __reg_write(lis, regs_to_save[n], lis->regs[regs_to_save[n]]); ++ ++ /* if someone had us open, reset the non-wake threshold stuff */ ++ if (lis->flags & LIS302DL_F_INPUT_OPEN) ++ __enable_data_collection(lis); ++ ++ local_irq_restore(flags); ++ enable_irq(lis->pdata->interrupt); ++ ++ return 0; ++} ++#else ++#define lis302dl_suspend NULL ++#define lis302dl_resume NULL ++#endif ++ ++static struct spi_driver lis302dl_spi_driver = { ++ .driver = { ++ .name = "lis302dl", ++ .owner = THIS_MODULE, ++ }, ++ ++ .probe = lis302dl_probe, ++ .remove = __devexit_p(lis302dl_remove), ++ .suspend = lis302dl_suspend, ++ .resume = lis302dl_resume, ++}; ++ ++static int __devinit lis302dl_init(void) ++{ ++ return spi_register_driver(&lis302dl_spi_driver); ++} ++ ++static void __exit lis302dl_exit(void) ++{ ++ spi_unregister_driver(&lis302dl_spi_driver); ++} ++ ++MODULE_AUTHOR("Harald Welte <laforge@openmoko.org>"); ++MODULE_LICENSE("GPL"); ++ ++module_init(lis302dl_init); ++module_exit(lis302dl_exit); +diff -ruN --exclude='*.orig' --exclude='*.rej' linux-2.6.29-rc3.owrt/drivers/input/misc/Makefile linux-2.6.29-rc3.owrt.om/drivers/input/misc/Makefile +--- linux-2.6.29-rc3.owrt/drivers/input/misc/Makefile 2009-05-10 22:04:49.000000000 +0200 ++++ linux-2.6.29-rc3.owrt.om/drivers/input/misc/Makefile 2009-05-10 22:29:16.000000000 +0200 +@@ -21,5 +21,7 @@ + obj-$(CONFIG_INPUT_UINPUT) += uinput.o + obj-$(CONFIG_INPUT_APANEL) += apanel.o + obj-$(CONFIG_INPUT_SGI_BTNS) += sgi_btns.o ++obj-$(CONFIG_INPUT_LIS302DL) += lis302dl.o + obj-$(CONFIG_INPUT_PCF50633_PMU) += pcf50633-input.o ++obj-$(CONFIG_INPUT_PCF50606_PMU) += pcf50606-input.o + obj-$(CONFIG_INPUT_GPIO_BUTTONS) += gpio_buttons.o +diff -ruN --exclude='*.orig' --exclude='*.rej' linux-2.6.29-rc3.owrt/drivers/input/misc/pcf50606-input.c linux-2.6.29-rc3.owrt.om/drivers/input/misc/pcf50606-input.c +--- linux-2.6.29-rc3.owrt/drivers/input/misc/pcf50606-input.c 1970-01-01 01:00:00.000000000 +0100 ++++ linux-2.6.29-rc3.owrt.om/drivers/input/misc/pcf50606-input.c 2009-05-10 22:27:59.000000000 +0200 +@@ -0,0 +1,140 @@ ++/* Philips PCF50606 Input Driver ++ * ++ * (C) 2006-2008 by Openmoko, Inc. ++ * Author: Balaji Rao <balajirrao@openmoko.org> ++ * All rights reserved. ++ * ++ * Broken down from monstrous PCF50606 driver mainly by ++ * Harald Welte, Matt Hsu, Andy Green and Werner Almesberger ++ * ++ * 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. ++ * ++ */ ++ ++#include <linux/kernel.h> ++#include <linux/module.h> ++#include <linux/init.h> ++#include <linux/device.h> ++#include <linux/platform_device.h> ++#include <linux/input.h> ++ ++#include <linux/mfd/pcf50606/core.h> ++ ++#define PCF50606_OOCS_ONKEY 0x01 ++#define PCF50606_OOCS_EXTON 0x02 ++ ++#define PCF50606_OOCC2_ONKEYDB_NONE 0x00 ++#define PCF50606_OOCC2_ONKEYDB_14ms 0x01 ++#define PCF50606_OOCC2_ONKEYDB_62ms 0x02 ++#define PCF50606_OOCC2_ONKEYDB_500ms 0x03 ++#define PCF50606_OOCC2_EXTONDB_NONE 0x00 ++#define PCF50606_OOCC2_EXTONDB_14ms 0x04 ++#define PCF50606_OOCC2_EXTONDB_62ms 0x08 ++#define PCF50606_OOCC2_EXTONDB_500ms 0x0c ++ ++#define PCF50606_REG_OOCS 0x01 ++ ++struct pcf50606_input { ++ struct pcf50606 *pcf; ++ struct input_dev *input_dev; ++}; ++ ++static void ++pcf50606_input_irq(int irq, void *data) ++{ ++ struct pcf50606_input *input; ++ int onkey_released; ++ ++ input = data; ++ onkey_released = pcf50606_reg_read(input->pcf, PCF50606_REG_OOCS) & ++ PCF50606_OOCS_ONKEY; ++ ++ if (irq == PCF50606_IRQ_ONKEYF && !onkey_released) ++ input_report_key(input->input_dev, KEY_POWER, 1); ++ else if (irq == PCF50606_IRQ_ONKEYR && onkey_released) ++ input_report_key(input->input_dev, KEY_POWER, 0); ++ ++ input_sync(input->input_dev); ++} ++ ++static int __devinit pcf50606_input_probe(struct platform_device *pdev) ++{ ++ struct pcf50606_input *input; ++ struct pcf50606_subdev_pdata *pdata = pdev->dev.platform_data; ++ struct input_dev *input_dev; ++ int ret; ++ ++ ++ input = kzalloc(sizeof(*input), GFP_KERNEL); ++ if (!input) ++ return -ENOMEM; ++ ++ input_dev = input_allocate_device(); ++ if (!input_dev) { ++ kfree(input); ++ return -ENOMEM; ++ } ++ ++ platform_set_drvdata(pdev, input); ++ input->pcf = pdata->pcf; ++ input->input_dev = input_dev; ++ ++ input_dev->name = "PCF50606 PMU events"; ++ input_dev->id.bustype = BUS_I2C; ++ input_dev->evbit[0] = BIT(EV_KEY) | BIT(EV_PWR); ++ set_bit(KEY_POWER, input_dev->keybit); ++ ++ ret = input_register_device(input_dev); ++ if (ret) { ++ input_free_device(input_dev); ++ kfree(input); ++ return ret; ++ } ++ pcf50606_register_irq(pdata->pcf, PCF50606_IRQ_ONKEYR, ++ pcf50606_input_irq, input); ++ pcf50606_register_irq(pdata->pcf, PCF50606_IRQ_ONKEYF, ++ pcf50606_input_irq, input); ++ ++ return 0; ++} ++ ++static int __devexit pcf50606_input_remove(struct platform_device *pdev) ++{ ++ struct pcf50606_input *input = platform_get_drvdata(pdev); ++ ++ input_unregister_device(input->input_dev); ++ pcf50606_free_irq(input->pcf, PCF50606_IRQ_ONKEYR); ++ pcf50606_free_irq(input->pcf, PCF50606_IRQ_ONKEYF); ++ ++ kfree(input); ++ ++ return 0; ++} ++ ++static struct platform_driver pcf50606_input_driver = { ++ .driver = { ++ .name = "pcf50606-input", ++ }, ++ .probe = pcf50606_input_probe, ++ .remove = __devexit_p(pcf50606_input_remove), ++}; ++ ++static int __init pcf50606_input_init(void) ++{ ++ return platform_driver_register(&pcf50606_input_driver); ++} ++module_init(pcf50606_input_init); ++ ++static void __exit pcf50606_input_exit(void) ++{ ++ platform_driver_unregister(&pcf50606_input_driver); ++} ++module_exit(pcf50606_input_exit); ++ ++MODULE_AUTHOR("Balaji Rao <balajirrao@openmoko.org>"); ++MODULE_DESCRIPTION("PCF50606 input driver"); ++MODULE_LICENSE("GPL"); ++MODULE_ALIAS("platform:pcf50606-input"); +diff -ruN --exclude='*.orig' --exclude='*.rej' linux-2.6.29-rc3.owrt/drivers/input/mousedev.c linux-2.6.29-rc3.owrt.om/drivers/input/mousedev.c +--- linux-2.6.29-rc3.owrt/drivers/input/mousedev.c 2009-05-10 22:04:49.000000000 +0200 ++++ linux-2.6.29-rc3.owrt.om/drivers/input/mousedev.c 2009-05-10 22:27:59.000000000 +0200 +@@ -1015,6 +1015,7 @@ + .evbit = { BIT_MASK(EV_KEY) | BIT_MASK(EV_REL) }, + .relbit = { BIT_MASK(REL_WHEEL) }, + }, /* A separate scrollwheel */ ++#if 0 + { + .flags = INPUT_DEVICE_ID_MATCH_EVBIT | + INPUT_DEVICE_ID_MATCH_KEYBIT | +@@ -1024,6 +1025,7 @@ + .absbit = { BIT_MASK(ABS_X) | BIT_MASK(ABS_Y) }, + }, /* A tablet like device, at least touch detection, + two absolute axes */ ++#endif + { + .flags = INPUT_DEVICE_ID_MATCH_EVBIT | + INPUT_DEVICE_ID_MATCH_KEYBIT | +diff -ruN --exclude='*.orig' --exclude='*.rej' linux-2.6.29-rc3.owrt/drivers/input/touchscreen/Kconfig linux-2.6.29-rc3.owrt.om/drivers/input/touchscreen/Kconfig +--- linux-2.6.29-rc3.owrt/drivers/input/touchscreen/Kconfig 2009-05-10 22:04:49.000000000 +0200 ++++ linux-2.6.29-rc3.owrt.om/drivers/input/touchscreen/Kconfig 2009-05-10 22:27:59.000000000 +0200 +@@ -11,6 +11,54 @@ + + if INPUT_TOUCHSCREEN + ++menuconfig TOUCHSCREEN_FILTER ++ boolean "Touchscreen Filtering" ++ depends on INPUT_TOUCHSCREEN ++ select TOUCHSCREEN_FILTER_GROUP ++ select TOUCHSCREEN_FILTER_MEDIAN ++ select TOUCHSCREEN_FILTER_MEAN ++ select TOUCHSCREEN_FILTER_LINEAR ++ help ++ Select this to include kernel touchscreen filter support. The filters ++ can be combined in any order in your machine init and the parameters ++ for them can also be set there. ++ ++if TOUCHSCREEN_FILTER ++ ++config TOUCHSCREEN_FILTER_GROUP ++ bool "Group Touchscreen Filter" ++ depends on INPUT_TOUCHSCREEN && TOUCHSCREEN_FILTER ++ default Y ++ help ++ Say Y here if you want to use the Group touchscreen filter, it ++ avoids using atypical samples. ++ ++config TOUCHSCREEN_FILTER_MEDIAN ++ bool "Median Average Touchscreen Filter" ++ depends on INPUT_TOUCHSCREEN && TOUCHSCREEN_FILTER ++ default Y ++ help ++ Say Y here if you want to use the Median touchscreen filter, it's ++ highly effective if you data is noisy with occasional excursions. ++ ++config TOUCHSCREEN_FILTER_MEAN ++ bool "Mean Average Touchscreen Filter" ++ depends on INPUT_TOUCHSCREEN && TOUCHSCREEN_FILTER ++ default Y ++ help ++ Say Y here if you want to use the Mean touchscreen filter, it ++ can further improve decent quality data by removing jitter ++ ++config TOUCHSCREEN_FILTER_LINEAR ++ bool "Linear Touchscreen Filter" ++ depends on INPUT_TOUCHSCREEN && TOUCHSCREEN_FILTER ++ default Y ++ help ++ Say Y here if you want to use the Linear touchscreen filter, it ++ enables the use of calibration data for the touchscreen. ++ ++endif ++ + config TOUCHSCREEN_ADS7846 + tristate "ADS7846/TSC2046 and ADS7843 based touchscreens" + depends on SPI_MASTER +@@ -79,6 +127,24 @@ + To compile this driver as a module, choose M here: the + module will be called fujitsu-ts. + ++config TOUCHSCREEN_S3C2410 ++ tristate "Samsung S3C2410 touchscreen input driver" ++ depends on ARCH_S3C2410 && INPUT && INPUT_TOUCHSCREEN ++ select SERIO ++ help ++ Say Y here if you have the s3c2410 touchscreen. ++ ++ If unsure, say N. ++ ++ To compile this driver as a module, choose M here: the ++ module will be called s3c2410_ts. ++ ++config TOUCHSCREEN_S3C2410_DEBUG ++ boolean "Samsung S3C2410 touchscreen debug messages" ++ depends on TOUCHSCREEN_S3C2410 ++ help ++ Select this if you want debug messages ++ + config TOUCHSCREEN_GUNZE + tristate "Gunze AHL-51S touchscreen" + select SERIO +@@ -408,4 +474,15 @@ + To compile this driver as a module, choose M here: the + module will be called tsc2007. + ++config TOUCHSCREEN_PCAP7200 ++ tristate "EETI Projected capacitive touchscreen controller" ++ help ++ Say Y here if you have the EETI PCAP7200 touchscreen ++ controller chip in your system. ++ ++ If unsure, say N. ++ ++ To compile this driver as a module, choose M here: the ++ module will be called pcap7200. + endif ++ +diff -ruN --exclude='*.orig' --exclude='*.rej' linux-2.6.29-rc3.owrt/drivers/input/touchscreen/Makefile linux-2.6.29-rc3.owrt.om/drivers/input/touchscreen/Makefile +--- linux-2.6.29-rc3.owrt/drivers/input/touchscreen/Makefile 2009-05-10 22:04:49.000000000 +0200 ++++ linux-2.6.29-rc3.owrt.om/drivers/input/touchscreen/Makefile 2009-05-10 22:27:59.000000000 +0200 +@@ -34,3 +34,10 @@ + wm97xx-ts-$(CONFIG_TOUCHSCREEN_WM9712) += wm9712.o + wm97xx-ts-$(CONFIG_TOUCHSCREEN_WM9713) += wm9713.o + obj-$(CONFIG_TOUCHSCREEN_WM97XX_MAINSTONE) += mainstone-wm97xx.o ++obj-$(CONFIG_TOUCHSCREEN_S3C2410) += s3c2410_ts.o ++obj-$(CONFIG_TOUCHSCREEN_FILTER) += ts_filter_chain.o ++obj-$(CONFIG_TOUCHSCREEN_FILTER_GROUP) += ts_filter_group.o ++obj-$(CONFIG_TOUCHSCREEN_FILTER_LINEAR) += ts_filter_linear.o ++obj-$(CONFIG_TOUCHSCREEN_FILTER_MEDIAN) += ts_filter_median.o ++obj-$(CONFIG_TOUCHSCREEN_FILTER_MEAN) += ts_filter_mean.o ++obj-$(CONFIG_TOUCHSCREEN_PCAP7200) += pcap7200_ts.o +diff -ruN --exclude='*.orig' --exclude='*.rej' linux-2.6.29-rc3.owrt/drivers/input/touchscreen/pcap7200_ts.c linux-2.6.29-rc3.owrt.om/drivers/input/touchscreen/pcap7200_ts.c +--- linux-2.6.29-rc3.owrt/drivers/input/touchscreen/pcap7200_ts.c 1970-01-01 01:00:00.000000000 +0100 ++++ linux-2.6.29-rc3.owrt.om/drivers/input/touchscreen/pcap7200_ts.c 2009-05-10 22:27:59.000000000 +0200 +@@ -0,0 +1,309 @@ ++ /* Projected capacitive touchscreen controller driver. ++ * ++ * Copyright(c) 2008 Openmoko Inc. ++ * ++ * Author: Matt Hsu <matt_hsu@openmoko.org> ++ * ++ * 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. ++ * ++ * TODO ++ * - apply ts_filter ++ * - add support for gesture event ++ * ++ */ ++ ++#include <linux/kernel.h> ++#include <linux/module.h> ++#include <linux/init.h> ++#include <linux/input.h> ++#include <linux/i2c.h> ++#include <linux/platform_device.h> ++#include <linux/interrupt.h> ++#include <linux/workqueue.h> ++#include <linux/input.h> ++#include <linux/device.h> ++ ++#include <linux/pcap7200.h> ++#include <../drivers/input/touchscreen/ts_filter.h> ++ ++#include <mach/om-3d7k.h> ++ ++#define PCAP7200_OP_MODE_REG 0x07 ++#define RPT_PKT_SIZE 5 ++#define EVENT_UP 0x80 ++#define EVENT_DOWN 0x81 ++ ++ ++#define coord_interpret(msb_byte, lsb_byte) \ ++ (msb_byte << 7 | lsb_byte) ++ ++struct pcap7200_data{ ++ struct i2c_client *client; ++ struct input_dev *dev; ++ struct ts_filter **tsf; ++ struct mutex lock; ++ int irq; ++ struct work_struct work; ++}; ++ ++static void pcap7200_work(struct work_struct *work) ++{ ++ struct pcap7200_data *pcap = ++ container_of(work, struct pcap7200_data, work); ++ uint8_t rpt_pkt[RPT_PKT_SIZE], event; ++ int coords[2]; ++ int ret; ++ ++ mutex_lock(&pcap->lock); ++ ++ memset(rpt_pkt, 0, sizeof(rpt_pkt)); ++ ++ BUG_ON(pcap == NULL); ++ ++ ret = i2c_master_recv(pcap->client, rpt_pkt, RPT_PKT_SIZE); ++ ++ event = rpt_pkt[0]; ++ ++ /* ++ * this is annonying. system would receive two consecutive interrupts if we set INT ++ * type as LOW_LEVEL. the data we pull from pcap7200 are invalid which are all ++ * zero in the second interrupt. ++ */ ++ if (event != 0) { ++ dev_dbg(&pcap->client->dev, "[%2x][%2x][%2x][%2x][%2x]: %d bytes return \n", ++ rpt_pkt[0], rpt_pkt[1], rpt_pkt[2], ++ rpt_pkt[3], rpt_pkt[4], ret); ++ ++ coords[0] = coord_interpret(rpt_pkt[1], rpt_pkt[2]); ++ coords[1] = coord_interpret(rpt_pkt[3], rpt_pkt[4]); ++ ++ if (event == EVENT_DOWN) { ++ input_report_abs(pcap->dev, ABS_X, coords[0]); ++ input_report_abs(pcap->dev, ABS_Y, coords[1]); ++ input_report_key(pcap->dev, BTN_TOUCH, 1); ++ input_report_abs(pcap->dev, ABS_PRESSURE, 1); ++ } else if (event == EVENT_UP) { ++ input_report_key(pcap->dev, BTN_TOUCH, 0); ++ input_report_abs(pcap->dev, ABS_PRESSURE, 0); ++ } else { ++ /* FIMXE: gesture events should be reported here. */ ++ } ++ ++ input_sync(pcap->dev); ++ } ++ ++ mutex_unlock(&pcap->lock); ++ enable_irq(pcap->irq); ++} ++ ++static const char *op_mode_name[] = { ++ [SLEEP] = "sleep", ++ [WAKEUP] = "wakeup", ++ [SINGLE_TOUCH] = "single_touch", ++ [MULTI_TOUCH] = "multi_touch", ++}; ++ ++static struct i2c_driver pcap7200_driver; ++ ++static int __set_op_mode(struct pcap7200_data *pcap, u_int8_t val) ++{ ++ u8 buf[] = { PCAP7200_OP_MODE_REG, val}; ++ int ret, i; ++ ++ mutex_lock(&pcap->lock); ++ ++ val = val & 0x03; ++ ++ /* this chip has an issue. ++ * you need to give wakeup call for 3 times if it's ++ * in sleep mode. ++ */ ++ if (val == WAKEUP) { ++ for (i = 0; i < 3; i++) ++ ret = i2c_master_send(pcap->client, buf, sizeof(buf)); ++ } else ++ ret = i2c_master_send(pcap->client, buf, sizeof(buf)); ++ ++ mutex_unlock(&pcap->lock); ++ return ret; ++} ++ ++static ssize_t set_op_mode(struct device *dev, struct device_attribute *attr, ++ const char *buf, size_t count) ++{ ++ struct i2c_client *client = to_i2c_client(dev); ++ struct pcap7200_data *pcap = i2c_get_clientdata(client); ++ u_int8_t i; ++ ++ for (i = 0; i < ARRAY_SIZE(op_mode_name); i++) { ++ if (!strncmp(buf, op_mode_name[i], strlen(op_mode_name[i]))) ++ __set_op_mode(pcap, i); ++ } ++ ++ return count; ++} ++ ++static DEVICE_ATTR(op_mode, S_IRUGO | S_IWUSR, NULL, set_op_mode); ++ ++static irqreturn_t pcap7200_irq(int irq, void *_pcap) ++{ ++ struct pcap7200_data *pcap = _pcap; ++ ++ disable_irq(pcap->irq); ++ schedule_work(&pcap->work); ++ ++ return IRQ_HANDLED; ++} ++ ++static int ++pcap7200_probe(struct i2c_client *client, const struct i2c_device_id *ids) ++{ ++ struct pcap7200_data *pcap; ++ struct input_dev *input_dev; ++ int err; ++ struct pcap7200_platform_data *pdata = client->dev.platform_data; ++ ++ /* allocate pcap7200 data */ ++ pcap = kzalloc(sizeof(struct pcap7200_data), GFP_KERNEL); ++ if (!pcap) ++ return -ENOMEM; ++ ++ i2c_set_clientdata(client, pcap); ++ pcap->client = client; ++ ++ mutex_init(&pcap->lock); ++ ++ /* reset */ ++ if (pdata->reset) { ++ pdata->reset(); ++ dev_dbg(&client->dev, "hard reset\n"); ++ } ++ ++ /* operating mode */ ++ __set_op_mode(pcap, pdata->mode); ++ ++ /* initialize input device */ ++ input_dev = input_allocate_device(); ++ if (!input_dev) { ++ dev_err(&client->dev, "Unable to allocate the input device\n"); ++ err = -ENOMEM; ++ goto exit_kfree; ++ } ++ ++ pcap->dev = input_dev; ++ input_dev->evbit[0] = BIT_MASK(EV_SYN) | BIT_MASK(EV_KEY) | ++ BIT_MASK(EV_ABS); ++ input_dev->keybit[BIT_WORD(BTN_TOUCH)] = BIT_MASK(BTN_TOUCH); ++ ++ /* configurable resolution 2048x2048 */ ++ input_set_abs_params(pcap->dev, ABS_X, 0, 0x7FF, 0, 0); ++ input_set_abs_params(pcap->dev, ABS_Y, 0, 0x7FF, 0, 0); ++ input_set_abs_params(pcap->dev, ABS_PRESSURE, 0, 1, 0, 0); ++ ++ input_dev->name = client->name; ++ input_dev->id.bustype = BUS_I2C; ++ input_dev->dev.parent = &client->dev; ++ ++ err = input_register_device(input_dev); ++ ++ if (err) ++ goto exit_unreg; ++ ++ INIT_WORK(&pcap->work, pcap7200_work); ++ ++ err = sysfs_create_file(&client->dev.kobj, &dev_attr_op_mode.attr); ++ ++ if (err) { ++ dev_err(&client->dev, "Failed to create sysfs\n"); ++ goto exit_unreg; ++ } ++ ++ /* setup IRQ */ ++ if (client->irq < 0) { ++ dev_err(&client->dev, ++ "No irq allocated in client resources!\n"); ++ goto exit_rmsysfs; ++ } ++ ++ pcap->irq = client->irq; ++ err = request_irq(pcap->irq, pcap7200_irq, IRQF_TRIGGER_LOW, "pcap7200", pcap); ++ ++ if (err < 0) ++ goto exit_rmsysfs; ++ ++ return 0; ++ ++exit_rmsysfs: ++ sysfs_remove_file(&client->dev.kobj, &dev_attr_op_mode.attr); ++exit_unreg: ++ input_unregister_device(input_dev); ++exit_kfree: ++ kfree(pcap); ++ return err; ++} ++ ++static int pcap7200_remove(struct i2c_client *client) ++{ ++ struct pcap7200_data *pcap = i2c_get_clientdata(client); ++ ++ free_irq(pcap->irq, pcap); ++ input_unregister_device(pcap->dev); ++ kfree(pcap); ++ return 0; ++} ++ ++#ifdef CONFIG_PM ++static int pcap7200_suspend(struct device *dev, pm_message_t state) ++{ ++ struct i2c_client *client = to_i2c_client(dev); ++ struct pcap7200_data *pcap = i2c_get_clientdata(client); ++ ++ __set_op_mode(pcap, SLEEP); ++ return 0; ++} ++ ++static int pcap7200_resume(struct device *dev) ++{ ++ struct i2c_client *client = to_i2c_client(dev); ++ struct pcap7200_data *pcap = i2c_get_clientdata(client); ++ ++ __set_op_mode(pcap, WAKEUP); ++ return 0; ++} ++#else ++#define pcap7200_suspend NULL ++#define pcap7200_resume NULL ++#endif ++ ++static struct i2c_device_id pcap7200_id_table[] = { ++ {"pcap7200", 0x0a}, ++}; ++ ++static struct i2c_driver pcap7200_driver = { ++ .driver = { ++ .name = "pcap7200", ++ .suspend = pcap7200_suspend, ++ .resume = pcap7200_resume, ++ }, ++ .id_table = pcap7200_id_table, ++ .probe = pcap7200_probe, ++ .remove = pcap7200_remove, ++}; ++ ++static int __init pcap7200_init(void) ++{ ++ return i2c_add_driver(&pcap7200_driver); ++} ++ ++static void pcap7200_exit(void) ++{ ++ i2c_del_driver(&pcap7200_driver); ++} ++module_init(pcap7200_init); ++module_exit(pcap7200_exit); ++ ++MODULE_AUTHOR("Matt Hsu <matt_hsu@openmoko.org>"); ++MODULE_LICENSE("GPLv2"); +diff -ruN --exclude='*.orig' --exclude='*.rej' linux-2.6.29-rc3.owrt/drivers/input/touchscreen/s3c2410_ts.c linux-2.6.29-rc3.owrt.om/drivers/input/touchscreen/s3c2410_ts.c +--- linux-2.6.29-rc3.owrt/drivers/input/touchscreen/s3c2410_ts.c 1970-01-01 01:00:00.000000000 +0100 ++++ linux-2.6.29-rc3.owrt.om/drivers/input/touchscreen/s3c2410_ts.c 2009-05-10 22:27:59.000000000 +0200 +@@ -0,0 +1,593 @@ ++/* ++ * 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, MA 02111-1307 USA ++ * ++ * Copyright (c) 2004 Arnaud Patard <arnaud.patard@rtp-net.org> ++ * iPAQ H1940 touchscreen support ++ * ++ * ChangeLog ++ * ++ * 2004-09-05: Herbert Pötzl <herbert@13thfloor.at> ++ * - added clock (de-)allocation code ++ * ++ * 2005-03-06: Arnaud Patard <arnaud.patard@rtp-net.org> ++ * - h1940_ -> s3c2410 (this driver is now also used on the n30 ++ * machines :P) ++ * - Debug messages are now enabled with the config option ++ * TOUCHSCREEN_S3C2410_DEBUG ++ * - Changed the way the value are read ++ * - Input subsystem should now work ++ * - Use ioremap and readl/writel ++ * ++ * 2005-03-23: Arnaud Patard <arnaud.patard@rtp-net.org> ++ * - Make use of some undocumented features of the touchscreen ++ * controller ++ * ++ * 2007-05-23: Harald Welte <laforge@openmoko.org> ++ * - Add proper support for S32440 ++ * ++ * 2008-06-23: Andy Green <andy@openmoko.com> ++ * - removed averaging system ++ * - added generic Touchscreen filter stuff ++ * ++ * 2008-11-27: Nelson Castillo <arhuaco@freaks-unidos.net> ++ * - improve interrupt handling ++ */ ++ ++#include <linux/errno.h> ++#include <linux/kernel.h> ++#include <linux/module.h> ++#include <linux/slab.h> ++#include <linux/input.h> ++#include <linux/init.h> ++#include <linux/serio.h> ++#include <linux/timer.h> ++#include <linux/kfifo.h> ++#include <linux/delay.h> ++#include <linux/platform_device.h> ++#include <linux/clk.h> ++#include <asm/io.h> ++#include <asm/irq.h> ++ ++#include <mach/regs-gpio.h> ++#include <mach/ts.h> ++#include <mach/hardware.h> ++#include <plat/regs-adc.h> ++ ++#include "ts_filter_chain.h" ++ ++/* For ts.dev.id.version */ ++#define S3C2410TSVERSION 0x0101 ++ ++#define TSC_SLEEP (S3C2410_ADCTSC_PULL_UP_DISABLE | S3C2410_ADCTSC_XY_PST(0)) ++ ++#define WAIT4INT(x) (((x)<<8) | \ ++ S3C2410_ADCTSC_YM_SEN | \ ++ S3C2410_ADCTSC_YP_SEN | \ ++ S3C2410_ADCTSC_XP_SEN | \ ++ S3C2410_ADCTSC_XY_PST(3)) ++ ++#define AUTOPST (S3C2410_ADCTSC_YM_SEN | \ ++ S3C2410_ADCTSC_YP_SEN | \ ++ S3C2410_ADCTSC_XP_SEN | \ ++ S3C2410_ADCTSC_AUTO_PST | \ ++ S3C2410_ADCTSC_XY_PST(0)) ++ ++#define DEBUG_LVL KERN_DEBUG ++ ++MODULE_AUTHOR("Arnaud Patard <arnaud.patard@rtp-net.org>"); ++MODULE_DESCRIPTION("s3c2410 touchscreen driver"); ++MODULE_LICENSE("GPL"); ++ ++/* ++ * Definitions & global arrays. ++ */ ++ ++static char *s3c2410ts_name = "s3c2410 TouchScreen"; ++ ++#define TS_RELEASE_TIMEOUT (HZ >> 7 ? HZ >> 7 : 1) /* 8ms (5ms if HZ is 200) */ ++#define TS_EVENT_FIFO_SIZE (2 << 6) /* must be a power of 2 */ ++ ++#define TS_STATE_STANDBY 0 /* initial state */ ++#define TS_STATE_PRESSED 1 ++#define TS_STATE_RELEASE_PENDING 2 ++#define TS_STATE_RELEASE 3 ++ ++/* ++ * Per-touchscreen data. ++ */ ++ ++struct s3c2410ts { ++ struct input_dev *dev; ++ struct ts_filter_chain *chain; ++ int is_down; ++ int state; ++ struct kfifo *event_fifo; ++}; ++ ++static struct s3c2410ts ts; ++ ++static void __iomem *base_addr; ++ ++/* ++ * A few low level functions. ++ */ ++ ++static inline void s3c2410_ts_connect(void) ++{ ++ s3c2410_gpio_cfgpin(S3C2410_GPG12, S3C2410_GPG12_XMON); ++ s3c2410_gpio_cfgpin(S3C2410_GPG13, S3C2410_GPG13_nXPON); ++ s3c2410_gpio_cfgpin(S3C2410_GPG14, S3C2410_GPG14_YMON); ++ s3c2410_gpio_cfgpin(S3C2410_GPG15, S3C2410_GPG15_nYPON); ++} ++ ++static void s3c2410_ts_start_adc_conversion(void) ++{ ++ writel(S3C2410_ADCTSC_PULL_UP_DISABLE | AUTOPST, ++ base_addr + S3C2410_ADCTSC); ++ writel(readl(base_addr + S3C2410_ADCCON) | S3C2410_ADCCON_ENABLE_START, ++ base_addr + S3C2410_ADCCON); ++} ++ ++/* ++ * Just send the input events. ++ */ ++ ++enum ts_input_event {IE_DOWN = 0, IE_UP}; ++ ++static void ts_input_report(int event, int coords[]) ++{ ++#ifdef CONFIG_TOUCHSCREEN_S3C2410_DEBUG ++ static char *s[] = {"down", "up"}; ++ struct timeval tv; ++ ++ do_gettimeofday(&tv); ++#endif ++ ++ if (event == IE_DOWN) { ++ input_report_abs(ts.dev, ABS_X, coords[0]); ++ input_report_abs(ts.dev, ABS_Y, coords[1]); ++ input_report_key(ts.dev, BTN_TOUCH, 1); ++ input_report_abs(ts.dev, ABS_PRESSURE, 1); ++ ++#ifdef CONFIG_TOUCHSCREEN_S3C2410_DEBUG ++ printk(DEBUG_LVL "T:%06d %6s (X:%03d, Y:%03d)\n", ++ (int)tv.tv_usec, s[event], coords[0], coords[1]); ++#endif ++ } else { ++ input_report_key(ts.dev, BTN_TOUCH, 0); ++ input_report_abs(ts.dev, ABS_PRESSURE, 0); ++ ++#ifdef CONFIG_TOUCHSCREEN_S3C2410_DEBUG ++ printk(DEBUG_LVL "T:%06d %6s\n", ++ (int)tv.tv_usec, s[event]); ++#endif ++ } ++ ++ input_sync(ts.dev); ++} ++ ++/* ++ * Manage the state of the touchscreen. ++ */ ++ ++static void event_send_timer_f(unsigned long data); ++ ++static struct timer_list event_send_timer = ++ TIMER_INITIALIZER(event_send_timer_f, 0, 0); ++ ++static void event_send_timer_f(unsigned long data) ++{ ++ static int noop_counter; ++ int event_type; ++ ++ while (__kfifo_get(ts.event_fifo, (unsigned char *)&event_type, ++ sizeof(int))) { ++ int buf[2]; ++ ++ switch (event_type) { ++ case 'D': ++ if (ts.state == TS_STATE_RELEASE_PENDING) ++ /* Ignore short UP event */ ++ ts.state = TS_STATE_PRESSED; ++ break; ++ ++ case 'U': ++ ts.state = TS_STATE_RELEASE_PENDING; ++ break; ++ ++ case 'P': ++ if (ts.is_down) /* stylus_action needs a conversion */ ++ s3c2410_ts_start_adc_conversion(); ++ ++ if (unlikely(__kfifo_get(ts.event_fifo, ++ (unsigned char *)buf, ++ sizeof(int) * 2) ++ != sizeof(int) * 2)) ++ goto ts_exit_error; ++ ++ ts_input_report(IE_DOWN, buf); ++ ts.state = TS_STATE_PRESSED; ++ break; ++ ++ default: ++ goto ts_exit_error; ++ } ++ ++ noop_counter = 0; ++ } ++ ++ if (noop_counter++ >= 1) { ++ noop_counter = 0; ++ if (ts.state == TS_STATE_RELEASE_PENDING) { ++ /* ++ * We delay the UP event for a while to avoid jitter. ++ * If we get a DOWN event we do not send it. ++ */ ++ ts_input_report(IE_UP, NULL); ++ ts.state = TS_STATE_STANDBY; ++ ++ ts_filter_chain_clear(ts.chain); ++ } ++ } else { ++ mod_timer(&event_send_timer, jiffies + TS_RELEASE_TIMEOUT); ++ } ++ ++ return; ++ ++ts_exit_error: /* should not happen unless we have a bug */ ++ printk(KERN_ERR __FILE__ ": event_send_timer_f failed\n"); ++} ++ ++/* ++ * Manage interrupts. ++ */ ++ ++static irqreturn_t stylus_updown(int irq, void *dev_id) ++{ ++ unsigned long data0; ++ unsigned long data1; ++ int event_type; ++ ++ data0 = readl(base_addr+S3C2410_ADCDAT0); ++ data1 = readl(base_addr+S3C2410_ADCDAT1); ++ ++ ts.is_down = (!(data0 & S3C2410_ADCDAT0_UPDOWN)) && ++ (!(data1 & S3C2410_ADCDAT0_UPDOWN)); ++ ++ event_type = ts.is_down ? 'D' : 'U'; ++ ++ if (unlikely(__kfifo_put(ts.event_fifo, (unsigned char *)&event_type, ++ sizeof(int)) != sizeof(int))) /* should not happen */ ++ printk(KERN_ERR __FILE__": stylus_updown lost event!\n"); ++ ++ if (ts.is_down) ++ s3c2410_ts_start_adc_conversion(); ++ else ++ writel(WAIT4INT(0), base_addr+S3C2410_ADCTSC); ++ ++ mod_timer(&event_send_timer, jiffies + 1); ++ ++ return IRQ_HANDLED; ++} ++ ++static irqreturn_t stylus_action(int irq, void *dev_id) ++{ ++ int buf[3]; ++ ++ /* Grab the ADC results. */ ++ buf[1] = readl(base_addr + S3C2410_ADCDAT0) & ++ S3C2410_ADCDAT0_XPDATA_MASK; ++ buf[2] = readl(base_addr + S3C2410_ADCDAT1) & ++ S3C2410_ADCDAT1_YPDATA_MASK; ++ ++ switch (ts_filter_chain_feed(ts.chain, &buf[1])) { ++ case 0: ++ /* The filter wants more points. */ ++ s3c2410_ts_start_adc_conversion(); ++ return IRQ_HANDLED; ++ case 1: ++ /* We have a point from the filters or no filtering enabled. */ ++ buf[0] = 'P'; ++ break; ++ default: ++ printk(KERN_ERR __FILE__ ++ ":%d Invalid ts_filter_chain_feed return value.\n", ++ __LINE__); ++ case -1: ++ /* Error. Ignore the event. */ ++ ts_filter_chain_clear(ts.chain); ++ writel(WAIT4INT(1), base_addr + S3C2410_ADCTSC); ++ return IRQ_HANDLED; ++ }; ++ ++ if (unlikely(__kfifo_put(ts.event_fifo, (unsigned char *)buf, ++ sizeof(int) * 3) != sizeof(int) * 3)) ++ printk(KERN_ERR __FILE__":stylus_action bug.\n"); ++ ++ writel(WAIT4INT(1), base_addr + S3C2410_ADCTSC); ++ mod_timer(&event_send_timer, jiffies + 1); ++ ++ return IRQ_HANDLED; ++} ++ ++static struct clk *adc_clock; ++ ++/* ++ * The functions for inserting/removing us as a module. ++ */ ++ ++static int __init s3c2410ts_probe(struct platform_device *pdev) ++{ ++ int rc; ++ struct s3c2410_ts_mach_info *info; ++ struct input_dev *input_dev; ++ int ret = 0; ++ ++ dev_info(&pdev->dev, "Starting\n"); ++ ++ info = (struct s3c2410_ts_mach_info *)pdev->dev.platform_data; ++ ++ if (!info) ++ { ++ dev_err(&pdev->dev, "Hm... too bad: no platform data for ts\n"); ++ return -EINVAL; ++ } ++ ++#ifdef CONFIG_TOUCHSCREEN_S3C2410_DEBUG ++ printk(DEBUG_LVL "Entering s3c2410ts_init\n"); ++#endif ++ ++ adc_clock = clk_get(NULL, "adc"); ++ if (!adc_clock) { ++ dev_err(&pdev->dev, "failed to get adc clock source\n"); ++ return -ENOENT; ++ } ++ clk_enable(adc_clock); ++ ++#ifdef CONFIG_TOUCHSCREEN_S3C2410_DEBUG ++ printk(DEBUG_LVL "got and enabled clock\n"); ++#endif ++ ++ base_addr = ioremap(S3C2410_PA_ADC,0x20); ++ if (base_addr == NULL) { ++ dev_err(&pdev->dev, "Failed to remap register block\n"); ++ ret = -ENOMEM; ++ goto bail0; ++ } ++ ++ ++ /* If we acutally are a S3C2410: Configure GPIOs */ ++ if (!strcmp(pdev->name, "s3c2410-ts")) ++ s3c2410_ts_connect(); ++ ++ if ((info->presc & 0xff) > 0) ++ writel(S3C2410_ADCCON_PRSCEN | ++ S3C2410_ADCCON_PRSCVL(info->presc&0xFF), ++ base_addr + S3C2410_ADCCON); ++ else ++ writel(0, base_addr+S3C2410_ADCCON); ++ ++ /* Initialise registers */ ++ if ((info->delay & 0xffff) > 0) ++ writel(info->delay & 0xffff, base_addr + S3C2410_ADCDLY); ++ ++ writel(WAIT4INT(0), base_addr + S3C2410_ADCTSC); ++ ++ /* Initialise input stuff */ ++ memset(&ts, 0, sizeof(struct s3c2410ts)); ++ input_dev = input_allocate_device(); ++ ++ if (!input_dev) { ++ dev_err(&pdev->dev, "Unable to allocate the input device\n"); ++ ret = -ENOMEM; ++ goto bail1; ++ } ++ ++ ts.dev = input_dev; ++ ts.dev->evbit[0] = BIT_MASK(EV_SYN) | BIT_MASK(EV_KEY) | ++ BIT_MASK(EV_ABS); ++ ts.dev->keybit[BIT_WORD(BTN_TOUCH)] = BIT_MASK(BTN_TOUCH); ++ input_set_abs_params(ts.dev, ABS_X, 0, 0x3FF, 0, 0); ++ input_set_abs_params(ts.dev, ABS_Y, 0, 0x3FF, 0, 0); ++ input_set_abs_params(ts.dev, ABS_PRESSURE, 0, 1, 0, 0); ++ ++ ts.dev->name = s3c2410ts_name; ++ ts.dev->id.bustype = BUS_RS232; ++ ts.dev->id.vendor = 0xDEAD; ++ ts.dev->id.product = 0xBEEF; ++ ts.dev->id.version = S3C2410TSVERSION; ++ ts.state = TS_STATE_STANDBY; ++ ts.event_fifo = kfifo_alloc(TS_EVENT_FIFO_SIZE, GFP_KERNEL, NULL); ++ if (IS_ERR(ts.event_fifo)) { ++ ret = -EIO; ++ goto bail2; ++ } ++ ++ /* create the filter chain set up for the 2 coordinates we produce */ ++ ts.chain = ts_filter_chain_create(pdev, info->filter_config, 2); ++ ++ if (IS_ERR(ts.chain)) ++ goto bail2; ++ ++ ts_filter_chain_clear(ts.chain); ++ ++ /* Get irqs */ ++ if (request_irq(IRQ_ADC, stylus_action, IRQF_SAMPLE_RANDOM, ++ "s3c2410_action", ts.dev)) { ++ dev_err(&pdev->dev, "Could not allocate ts IRQ_ADC !\n"); ++ iounmap(base_addr); ++ ret = -EIO; ++ goto bail3; ++ } ++ if (request_irq(IRQ_TC, stylus_updown, IRQF_SAMPLE_RANDOM, ++ "s3c2410_action", ts.dev)) { ++ dev_err(&pdev->dev, "Could not allocate ts IRQ_TC !\n"); ++ free_irq(IRQ_ADC, ts.dev); ++ iounmap(base_addr); ++ ret = -EIO; ++ goto bail4; ++ } ++ ++ dev_info(&pdev->dev, "Successfully loaded\n"); ++ ++ /* All went ok, so register to the input system */ ++ rc = input_register_device(ts.dev); ++ if (rc) { ++ ret = -EIO; ++ goto bail5; ++ } ++ ++ return 0; ++ ++bail5: ++ free_irq(IRQ_TC, ts.dev); ++ free_irq(IRQ_ADC, ts.dev); ++ clk_disable(adc_clock); ++ iounmap(base_addr); ++ disable_irq(IRQ_TC); ++bail4: ++ disable_irq(IRQ_ADC); ++bail3: ++ ts_filter_chain_destroy(ts.chain); ++ kfifo_free(ts.event_fifo); ++bail2: ++ input_unregister_device(ts.dev); ++bail1: ++ iounmap(base_addr); ++bail0: ++ ++ return ret; ++} ++ ++static int s3c2410ts_remove(struct platform_device *pdev) ++{ ++ disable_irq(IRQ_ADC); ++ disable_irq(IRQ_TC); ++ free_irq(IRQ_TC,ts.dev); ++ free_irq(IRQ_ADC,ts.dev); ++ ++ if (adc_clock) { ++ clk_disable(adc_clock); ++ clk_put(adc_clock); ++ adc_clock = NULL; ++ } ++ ++ input_unregister_device(ts.dev); ++ iounmap(base_addr); ++ ++ ts_filter_chain_destroy(ts.chain); ++ ++ kfifo_free(ts.event_fifo); ++ ++ return 0; ++} ++ ++#ifdef CONFIG_PM ++static int s3c2410ts_suspend(struct platform_device *pdev, pm_message_t state) ++{ ++ writel(TSC_SLEEP, base_addr+S3C2410_ADCTSC); ++ writel(readl(base_addr+S3C2410_ADCCON) | S3C2410_ADCCON_STDBM, ++ base_addr+S3C2410_ADCCON); ++ ++ disable_irq(IRQ_ADC); ++ disable_irq(IRQ_TC); ++ ++ clk_disable(adc_clock); ++ ++ return 0; ++} ++ ++static int s3c2410ts_resume(struct platform_device *pdev) ++{ ++ struct s3c2410_ts_mach_info *info = ++ ( struct s3c2410_ts_mach_info *)pdev->dev.platform_data; ++ ++ clk_enable(adc_clock); ++ mdelay(1); ++ ++ ts_filter_chain_clear(ts.chain); ++ ++ enable_irq(IRQ_ADC); ++ enable_irq(IRQ_TC); ++ ++ if ((info->presc&0xff) > 0) ++ writel(S3C2410_ADCCON_PRSCEN | ++ S3C2410_ADCCON_PRSCVL(info->presc&0xFF), ++ base_addr+S3C2410_ADCCON); ++ else ++ writel(0,base_addr+S3C2410_ADCCON); ++ ++ /* Initialise registers */ ++ if ((info->delay & 0xffff) > 0) ++ writel(info->delay & 0xffff, base_addr+S3C2410_ADCDLY); ++ ++ writel(WAIT4INT(0), base_addr+S3C2410_ADCTSC); ++ ++ return 0; ++} ++ ++#else ++#define s3c2410ts_suspend NULL ++#define s3c2410ts_resume NULL ++#endif ++ ++static struct platform_driver s3c2410ts_driver = { ++ .driver = { ++ .name = "s3c2410-ts", ++ .owner = THIS_MODULE, ++ }, ++ .probe = s3c2410ts_probe, ++ .remove = s3c2410ts_remove, ++ .suspend = s3c2410ts_suspend, ++ .resume = s3c2410ts_resume, ++ ++}; ++ ++static struct platform_driver s3c2440ts_driver = { ++ .driver = { ++ .name = "s3c2440-ts", ++ .owner = THIS_MODULE, ++ }, ++ .probe = s3c2410ts_probe, ++ .remove = s3c2410ts_remove, ++ .suspend = s3c2410ts_suspend, ++ .resume = s3c2410ts_resume, ++ ++}; ++ ++static int __init s3c2410ts_init(void) ++{ ++ int rc; ++ ++ rc = platform_driver_register(&s3c2410ts_driver); ++ if (rc < 0) ++ return rc; ++ ++ rc = platform_driver_register(&s3c2440ts_driver); ++ if (rc < 0) ++ platform_driver_unregister(&s3c2410ts_driver); ++ ++ return rc; ++} ++ ++static void __exit s3c2410ts_exit(void) ++{ ++ platform_driver_unregister(&s3c2440ts_driver); ++ platform_driver_unregister(&s3c2410ts_driver); ++} ++ ++module_init(s3c2410ts_init); ++module_exit(s3c2410ts_exit); ++ +diff -ruN --exclude='*.orig' --exclude='*.rej' linux-2.6.29-rc3.owrt/drivers/input/touchscreen/ts_filter_chain.c linux-2.6.29-rc3.owrt.om/drivers/input/touchscreen/ts_filter_chain.c +--- linux-2.6.29-rc3.owrt/drivers/input/touchscreen/ts_filter_chain.c 1970-01-01 01:00:00.000000000 +0100 ++++ linux-2.6.29-rc3.owrt.om/drivers/input/touchscreen/ts_filter_chain.c 2009-05-10 22:27:59.000000000 +0200 +@@ -0,0 +1,183 @@ ++/* ++ * 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, MA 02111-1307 USA ++ * ++ * Copyright (c) 2008,2009 Andy Green <andy@openmoko.com> ++ */ ++ ++#include <linux/kernel.h> ++#include <linux/device.h> ++ ++#include "ts_filter_chain.h" ++#include "ts_filter.h" ++ ++/* ++ * Tux, would you like the following function in /lib? ++ * It helps us avoid silly code. ++ */ ++ ++/** ++ * sptrlen - Count how many non-null pointers are in a pointer array ++ * @arr: The array of pointers ++ */ ++static int sptrlen(const void *arr) ++{ ++ /* All pointers have the same size. */ ++ const int **p = (const int **)arr; ++ int len = 0; ++ ++ while (*(p++)) ++ len++; ++ ++ return len; ++} ++ ++ ++struct ts_filter_chain { ++ /* All of the filters. */ ++ struct ts_filter **arr; ++ /* Filters that can propagate values in the chain. */ ++ struct ts_filter **pchain; ++ /* Length of the pchain array. */ ++ int pchain_len; ++ /* FIXME: Add a spinlock and use it. */ ++}; ++ ++struct ts_filter_chain *ts_filter_chain_create( ++ struct platform_device *pdev, ++ const struct ts_filter_chain_configuration conf[], ++ int count_coords) ++{ ++ struct ts_filter_chain *c; ++ int count = 0; ++ int len; ++ ++ BUG_ON((count_coords < 1)); ++ BUG_ON(count_coords > MAX_TS_FILTER_COORDS); ++ ++ c = kzalloc(sizeof(struct ts_filter_chain), GFP_KERNEL); ++ if (!c) ++ goto create_err_1; ++ ++ len = (sptrlen(conf) + 1); ++ /* Memory for two null-terminated arrays of filters. */ ++ c->arr = kzalloc(2 * sizeof(struct ts_filter *) * len, GFP_KERNEL); ++ if (!c->arr) ++ goto create_err_1; ++ c->pchain = c->arr + len; ++ ++ while (conf->api) { ++ /* TODO: Can we get away with only sending pdev->dev? */ ++ struct ts_filter *f = ++ (conf->api->create)(pdev, conf->config, count_coords); ++ if (!f) { ++ dev_info(&pdev->dev, "Filter %d creation failed\n", ++ count); ++ goto create_err_2; ++ } ++ ++ f->api = conf->api; ++ c->arr[count++] = f; ++ ++ if (f->api->haspoint && f->api->getpoint && f->api->process) ++ c->pchain[c->pchain_len++] = f; ++ ++ conf++; ++ } ++ ++ dev_info(&pdev->dev, "%d filter(s) initialized\n", count); ++ ++ return c; ++ ++create_err_2: ++ ts_filter_chain_destroy(c); /* Also frees c. */ ++create_err_1: ++ dev_info(&pdev->dev, "Error in filter chain initialization\n"); ++ /* ++ * FIXME: Individual filters have to return errors this way. ++ * We only have to forward the errors we find. ++ */ ++ return ERR_PTR(-ENOMEM); ++} ++EXPORT_SYMBOL_GPL(ts_filter_chain_create); ++ ++void ts_filter_chain_destroy(struct ts_filter_chain *c) ++{ ++ if (c->arr) { ++ struct ts_filter **a = c->arr; ++ while (*a) { ++ ((*a)->api->destroy)(*a); ++ a++; ++ } ++ kfree(c->arr); ++ } ++ kfree(c); ++} ++EXPORT_SYMBOL_GPL(ts_filter_chain_destroy); ++ ++void ts_filter_chain_clear(struct ts_filter_chain *c) ++{ ++ struct ts_filter **a = c->arr; ++ ++ while (*a) { ++ if ((*a)->api->clear) ++ ((*a)->api->clear)(*a); ++ a++; ++ } ++} ++EXPORT_SYMBOL_GPL(ts_filter_chain_clear); ++ ++static void ts_filter_chain_scale(struct ts_filter_chain *c, int *coords) ++{ ++ struct ts_filter **a = c->arr; ++ while (*a) { ++ if ((*a)->api->scale) ++ ((*a)->api->scale)(*a, coords); ++ a++; ++ } ++} ++ ++int ts_filter_chain_feed(struct ts_filter_chain *c, int *coords) ++{ ++ int len = c->pchain_len; ++ int i = len - 1; ++ ++ if (!c->pchain[0]) ++ return 1; /* Nothing to do. */ ++ ++ BUG_ON(c->pchain[0]->api->haspoint(c->pchain[0])); ++ ++ if (c->pchain[0]->api->process(c->pchain[0], coords)) ++ return -1; ++ ++ while (i >= 0 && i < len) { ++ if (c->pchain[i]->api->haspoint(c->pchain[i])) { ++ c->pchain[i]->api->getpoint(c->pchain[i], coords); ++ if (++i < len && ++ c->pchain[i]->api->process(c->pchain[i], coords)) ++ return -1; /* Error. */ ++ } else { ++ i--; ++ } ++ } ++ ++ if (i >= 0) { /* Same as i == len. */ ++ ts_filter_chain_scale(c, coords); ++ return 1; ++ } ++ ++ return 0; ++} ++EXPORT_SYMBOL_GPL(ts_filter_chain_feed); ++ +diff -ruN --exclude='*.orig' --exclude='*.rej' linux-2.6.29-rc3.owrt/drivers/input/touchscreen/ts_filter_chain.h linux-2.6.29-rc3.owrt.om/drivers/input/touchscreen/ts_filter_chain.h +--- linux-2.6.29-rc3.owrt/drivers/input/touchscreen/ts_filter_chain.h 1970-01-01 01:00:00.000000000 +0100 ++++ linux-2.6.29-rc3.owrt.om/drivers/input/touchscreen/ts_filter_chain.h 2009-05-10 22:27:59.000000000 +0200 +@@ -0,0 +1,58 @@ ++#ifndef __TS_FILTER_CHAIN_H__ ++#define __TS_FILTER_CHAIN_H__ ++ ++/* ++ * Touchscreen filter chains. ++ * ++ * (c) 2008,2009 Andy Green <andy@openmoko.com> ++ */ ++ ++#include "ts_filter.h" ++ ++#include <linux/err.h> ++ ++struct ts_filter_chain_configuration { ++ /* API to use. */ ++ const struct ts_filter_api *api; ++ /* Generic filter configuration. Different for each filter. */ ++ const struct ts_filter_configuration *config; ++}; ++ ++struct ts_filter_chain; ++ ++#ifdef CONFIG_TOUCHSCREEN_FILTER ++ ++/* ++ * Create a filter chain. It will allocate an array of ++ * null-terminated pointers to filters. On error it will return ++ * an error you can check with IS_ERR. ++ */ ++extern struct ts_filter_chain *ts_filter_chain_create( ++ struct platform_device *pdev, ++ const struct ts_filter_chain_configuration conf[], ++ int count_coords); ++ ++/* Destroy the chain. */ ++extern void ts_filter_chain_destroy(struct ts_filter_chain *c); ++ ++/* Clear the filter chain. */ ++extern void ts_filter_chain_clear(struct ts_filter_chain *c); ++ ++/* ++ * Try to get one point. Returns 0 if no points are available. ++ * coords will be used as temporal space, thus you supply a point ++ * using coords but you shouldn't rely on its value on return unless ++ * it returns a nonzero value that is not -1. ++ * If one of the filters find an error then this function will ++ * return -1. ++ */ ++int ts_filter_chain_feed(struct ts_filter_chain *c, int *coords); ++ ++#else /* !CONFIG_TOUCHSCREEN_FILTER */ ++#define ts_filter_chain_create(pdev, config, count_coords) (NULL) ++#define ts_filter_chain_destroy(c) do { } while (0) ++#define ts_filter_chain_clear(c) do { } while (0) ++#define ts_filter_chain_feed(c, coords) (1) ++#endif ++ ++#endif +diff -ruN --exclude='*.orig' --exclude='*.rej' linux-2.6.29-rc3.owrt/drivers/input/touchscreen/ts_filter_group.c linux-2.6.29-rc3.owrt.om/drivers/input/touchscreen/ts_filter_group.c +--- linux-2.6.29-rc3.owrt/drivers/input/touchscreen/ts_filter_group.c 1970-01-01 01:00:00.000000000 +0100 ++++ linux-2.6.29-rc3.owrt.om/drivers/input/touchscreen/ts_filter_group.c 2009-05-10 22:27:59.000000000 +0200 +@@ -0,0 +1,296 @@ ++/* ++ * 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, MA 02111-1307 USA ++ * ++ * Copyright (C) 2008,2009 by Openmoko, Inc. ++ * Author: Nelson Castillo <arhuaco@freaks-unidos.net> ++ * All rights reserved. ++ * ++ * ++ * This filter is useful to reject samples that are not reliable. We consider ++ * that a sample is not reliable if it deviates form the Majority. ++ * ++ * 1) We collect S samples. ++ * ++ * 2) For each dimension: ++ * ++ * - We sort the points. ++ * - Points that are "close enough" are considered to be in the same set. ++ * - We choose the set with more elements. If more than "threshold" ++ * points are in this set we use the first and the last point of the set ++ * to define the valid range for this dimension [min, max], otherwise we ++ * discard all the points and go to step 1. ++ * ++ * 3) We consider the unsorted S samples and try to feed them to the next ++ * filter in the chain. If one of the points of each sample ++ * is not in the allowed range for its dimension, we discard the sample. ++ * ++ */ ++ ++#include <linux/kernel.h> ++#include <linux/slab.h> ++#include <linux/sort.h> ++#include "ts_filter_group.h" ++ ++struct ts_filter_group { ++ /* Private filter configuration. */ ++ struct ts_filter_group_configuration *config; ++ /* Filter API. */ ++ struct ts_filter tsf; ++ ++ int N; /* How many samples we have. */ ++ int *samples[MAX_TS_FILTER_COORDS]; /* The samples: our input. */ ++ ++ int *group_size; /* Used for temporal computations. */ ++ int *sorted_samples; /* Used for temporal computations. */ ++ ++ int range_max[MAX_TS_FILTER_COORDS]; /* Max. computed ranges. */ ++ int range_min[MAX_TS_FILTER_COORDS]; /* Min. computed ranges. */ ++ ++ int tries_left; /* We finish if we don't get enough samples. */ ++ int ready; /* If we are ready to deliver samples. */ ++ int result; /* Index of the point being returned. */ ++}; ++ ++#define ts_filter_to_filter_group(f) \ ++ container_of(f, struct ts_filter_group, tsf) ++ ++ ++static void ts_filter_group_clear_internal(struct ts_filter_group *tsfg, ++ int attempts) ++{ ++ tsfg->N = 0; ++ tsfg->tries_left = attempts; ++ tsfg->ready = 0; ++ tsfg->result = 0; ++} ++ ++static void ts_filter_group_clear(struct ts_filter *tsf) ++{ ++ struct ts_filter_group *tsfg = ts_filter_to_filter_group(tsf); ++ ++ ts_filter_group_clear_internal(tsfg, tsfg->config->attempts); ++} ++ ++static struct ts_filter *ts_filter_group_create( ++ struct platform_device *pdev, ++ const struct ts_filter_configuration *conf, ++ int count_coords) ++{ ++ struct ts_filter_group *tsfg; ++ int i; ++ ++ tsfg = kzalloc(sizeof(struct ts_filter_group), GFP_KERNEL); ++ if (!tsfg) ++ return NULL; ++ ++ tsfg->config = container_of(conf, ++ struct ts_filter_group_configuration, ++ config); ++ tsfg->tsf.count_coords = count_coords; ++ ++ BUG_ON(tsfg->config->attempts <= 0); ++ ++ tsfg->samples[0] = kmalloc((2 + count_coords) * sizeof(int) * ++ tsfg->config->length, GFP_KERNEL); ++ if (!tsfg->samples[0]) { ++ kfree(tsfg); ++ return NULL; ++ } ++ for (i = 1; i < count_coords; ++i) ++ tsfg->samples[i] = tsfg->samples[0] + i * tsfg->config->length; ++ tsfg->sorted_samples = tsfg->samples[0] + count_coords * ++ tsfg->config->length; ++ tsfg->group_size = tsfg->samples[0] + (1 + count_coords) * ++ tsfg->config->length; ++ ++ ts_filter_group_clear_internal(tsfg, tsfg->config->attempts); ++ ++ dev_info(&pdev->dev, "Created Group filter len:%d coords:%d close:%d " ++ "thresh:%d\n", tsfg->config->length, count_coords, ++ tsfg->config->close_enough, tsfg->config->threshold); ++ ++ return &tsfg->tsf; ++} ++ ++static void ts_filter_group_destroy(struct ts_filter *tsf) ++{ ++ struct ts_filter_group *tsfg = ts_filter_to_filter_group(tsf); ++ ++ kfree(tsfg->samples[0]); /* first guy has pointer from kmalloc */ ++ kfree(tsf); ++} ++ ++static int int_cmp(const void *_a, const void *_b) ++{ ++ const int *a = _a; ++ const int *b = _b; ++ ++ if (*a > *b) ++ return 1; ++ if (*a < *b) ++ return -1; ++ return 0; ++} ++ ++static void ts_filter_group_prepare_next(struct ts_filter *tsf); ++ ++static int ts_filter_group_process(struct ts_filter *tsf, int *coords) ++{ ++ struct ts_filter_group *tsfg = ts_filter_to_filter_group(tsf); ++ int n; ++ int i; ++ ++ BUG_ON(tsfg->N >= tsfg->config->length); ++ BUG_ON(tsfg->ready); ++ ++ for (n = 0; n < tsf->count_coords; n++) ++ tsfg->samples[n][tsfg->N] = coords[n]; ++ ++ if (++tsfg->N < tsfg->config->length) ++ return 0; /* We need more samples. */ ++ ++ for (n = 0; n < tsfg->tsf.count_coords; n++) { ++ int *v = tsfg->sorted_samples; ++ int ngroups = 0; ++ int best_size; ++ int best_idx = 0; ++ int idx = 0; ++ ++ memcpy(v, tsfg->samples[n], tsfg->N * sizeof(int)); ++ /* ++ * FIXME: Remove this sort call. We already have the ++ * algorithm for this modification. The filter will ++ * need less points (about half) if there is not a ++ * lot of noise. Right now we are doing a constant ++ * amount of work no matter how much noise we are ++ * dealing with. ++ */ ++ sort(v, tsfg->N, sizeof(int), int_cmp, NULL); ++ ++ tsfg->group_size[0] = 1; ++ for (i = 1; i < tsfg->N; ++i) { ++ if (v[i] - v[i - 1] <= tsfg->config->close_enough) ++ tsfg->group_size[ngroups]++; ++ else ++ tsfg->group_size[++ngroups] = 1; ++ } ++ ngroups++; ++ ++ best_size = tsfg->group_size[0]; ++ for (i = 1; i < ngroups; i++) { ++ idx += tsfg->group_size[i - 1]; ++ if (best_size < tsfg->group_size[i]) { ++ best_size = tsfg->group_size[i]; ++ best_idx = idx; ++ } ++ } ++ ++ if (best_size < tsfg->config->threshold) { ++ /* This set is not good enough for us. */ ++ if (--tsfg->tries_left) { ++ ts_filter_group_clear_internal ++ (tsfg, tsfg->tries_left); ++ /* No errors but we need more samples. */ ++ return 0; ++ } ++ return 1; /* We give up: error. */ ++ } ++ ++ tsfg->range_min[n] = v[best_idx]; ++ tsfg->range_max[n] = v[best_idx + best_size - 1]; ++ } ++ ++ ts_filter_group_prepare_next(tsf); ++ ++ return 0; ++} ++ ++/* ++ * This private function prepares a point that will be returned ++ * in ts_filter_group_getpoint if it is available. It updates ++ * the priv->ready state also. ++ */ ++static void ts_filter_group_prepare_next(struct ts_filter *tsf) ++{ ++ struct ts_filter_group *priv = ts_filter_to_filter_group(tsf); ++ int n; ++ ++ while (priv->result < priv->N) { ++ for (n = 0; n < priv->tsf.count_coords; ++n) { ++ if (priv->samples[n][priv->result] < ++ priv->range_min[n] || ++ priv->samples[n][priv->result] > priv->range_max[n]) ++ break; ++ } ++ ++ if (n == priv->tsf.count_coords) /* Sample is OK. */ ++ break; ++ ++ priv->result++; ++ } ++ ++ if (unlikely(priv->result >= priv->N)) { /* No sample to deliver. */ ++ ts_filter_group_clear_internal(priv, priv->config->attempts); ++ priv->ready = 0; ++ } else { ++ priv->ready = 1; ++ } ++} ++ ++static int ts_filter_group_haspoint(struct ts_filter *tsf) ++{ ++ struct ts_filter_group *priv = ts_filter_to_filter_group(tsf); ++ ++ return priv->ready; ++} ++ ++static void ts_filter_group_getpoint(struct ts_filter *tsf, int *point) ++{ ++ struct ts_filter_group *priv = ts_filter_to_filter_group(tsf); ++ int n; ++ ++ BUG_ON(!priv->ready); ++ ++ for (n = 0; n < priv->tsf.count_coords; n++) ++ point[n] = priv->samples[n][priv->result]; ++ ++ priv->result++; ++ ++ /* This call will update priv->ready. */ ++ ts_filter_group_prepare_next(tsf); ++} ++ ++/* ++ * Get ready to process the next batch of points, forget ++ * points we could have delivered. ++ */ ++static void ts_filter_group_scale(struct ts_filter *tsf, int *coords) ++{ ++ struct ts_filter_group *priv = ts_filter_to_filter_group(tsf); ++ ++ ts_filter_group_clear_internal(priv, priv->config->attempts); ++} ++ ++const struct ts_filter_api ts_filter_group_api = { ++ .create = ts_filter_group_create, ++ .destroy = ts_filter_group_destroy, ++ .clear = ts_filter_group_clear, ++ .process = ts_filter_group_process, ++ .haspoint = ts_filter_group_haspoint, ++ .getpoint = ts_filter_group_getpoint, ++ .scale = ts_filter_group_scale, ++}; ++EXPORT_SYMBOL_GPL(ts_filter_group_api); ++ +diff -ruN --exclude='*.orig' --exclude='*.rej' linux-2.6.29-rc3.owrt/drivers/input/touchscreen/ts_filter_group.h linux-2.6.29-rc3.owrt.om/drivers/input/touchscreen/ts_filter_group.h +--- linux-2.6.29-rc3.owrt/drivers/input/touchscreen/ts_filter_group.h 1970-01-01 01:00:00.000000000 +0100 ++++ linux-2.6.29-rc3.owrt.om/drivers/input/touchscreen/ts_filter_group.h 2009-05-10 22:27:59.000000000 +0200 +@@ -0,0 +1,36 @@ ++#ifndef __TS_FILTER_GROUP_H__ ++#define __TS_FILTER_GROUP_H__ ++ ++#include "ts_filter.h" ++ ++/* ++ * Touchscreen group filter. ++ * ++ * Copyright (C) 2008,2009 by Openmoko, Inc. ++ * Author: Nelson Castillo <arhuaco@freaks-unidos.net> ++ * ++ */ ++ ++struct ts_filter_group_configuration { ++ /* Size of the filter. */ ++ int length; ++ /* ++ * If two points are separated by this distance or less they ++ * are considered to be members of the same group. ++ */ ++ int close_enough; ++ /* Minimum allowed size for the biggest group in the sample set. */ ++ int threshold; ++ /* ++ * Number of times we try to get a group of points with at least ++ * threshold points. ++ */ ++ int attempts; ++ ++ /* Generic filter configuration. */ ++ struct ts_filter_configuration config; ++}; ++ ++extern const struct ts_filter_api ts_filter_group_api; ++ ++#endif +diff -ruN --exclude='*.orig' --exclude='*.rej' linux-2.6.29-rc3.owrt/drivers/input/touchscreen/ts_filter.h linux-2.6.29-rc3.owrt.om/drivers/input/touchscreen/ts_filter.h +--- linux-2.6.29-rc3.owrt/drivers/input/touchscreen/ts_filter.h 1970-01-01 01:00:00.000000000 +0100 ++++ linux-2.6.29-rc3.owrt.om/drivers/input/touchscreen/ts_filter.h 2009-05-10 22:27:59.000000000 +0200 +@@ -0,0 +1,74 @@ ++#ifndef __TS_FILTER_H__ ++#define __TS_FILTER_H__ ++ ++/* ++ * Touchscreen filter. ++ * ++ * (c) 2008,2009 Andy Green <andy@openmoko.com> ++ */ ++ ++#include <linux/platform_device.h> ++ ++#define MAX_TS_FILTER_COORDS 3 /* X, Y and Z (pressure). */ ++ ++struct ts_filter; ++struct ts_filter_configuration; ++ ++/* Operations that a filter can perform. */ ++ ++struct ts_filter_api { ++ /* Create the filter - mandatory. */ ++ struct ts_filter * (*create)( ++ struct platform_device *pdev, ++ const struct ts_filter_configuration *config, ++ int count_coords); ++ /* Destroy the filter - mandatory. */ ++ void (*destroy)(struct ts_filter *filter); ++ /* Clear the filter - optional. */ ++ void (*clear)(struct ts_filter *filter); ++ ++ ++ /* ++ * The next three API functions only make sense if all of them are ++ * set for a filter. If a filter has the next three methods then ++ * it can propagate coordinates in the chain. ++ */ ++ ++ /* ++ * Process the filter. ++ * It returns non-zero if the filter reaches an error. ++ */ ++ int (*process)(struct ts_filter *filter, int *coords); ++ /* ++ * Is the filter ready to return a point? ++ * Please do not code side effects in this function. ++ */ ++ int (*haspoint)(struct ts_filter *filter); ++ /* ++ * Get a point. ++ * Do not call unless the filter actually has a point to deliver. ++ */ ++ void (*getpoint)(struct ts_filter *filter, int *coords); ++ ++ /* ++ * Scale the points - optional. ++ * A filter could only scale coordinates. ++ */ ++ void (*scale)(struct ts_filter *filter, int *coords); ++}; ++ ++/* ++ * Generic filter configuration. Actual configurations have this structure ++ * as a member. ++ */ ++struct ts_filter_configuration { ++}; ++ ++struct ts_filter { ++ /* Operations for this filter. */ ++ const struct ts_filter_api *api; ++ /* Number of coordinates to process. */ ++ int count_coords; ++}; ++ ++#endif +diff -ruN --exclude='*.orig' --exclude='*.rej' linux-2.6.29-rc3.owrt/drivers/input/touchscreen/ts_filter_linear.c linux-2.6.29-rc3.owrt.om/drivers/input/touchscreen/ts_filter_linear.c +--- linux-2.6.29-rc3.owrt/drivers/input/touchscreen/ts_filter_linear.c 1970-01-01 01:00:00.000000000 +0100 ++++ linux-2.6.29-rc3.owrt.om/drivers/input/touchscreen/ts_filter_linear.c 2009-05-10 22:27:59.000000000 +0200 +@@ -0,0 +1,212 @@ ++/* ++ * 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; 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, MA 02111-1307 USA ++ * ++ * Copyright (C) 2008,2009 by Openmoko, Inc. ++ * Author: Nelson Castillo <arhuaco@freaks-unidos.net> ++ * All rights reserved. ++ * ++ * Linearly scale touchscreen values. ++ * ++ * Expose the TS_FILTER_LINEAR_NCONSTANTS for the linear transformation ++ * using sysfs. ++ * ++ */ ++ ++#include <linux/kernel.h> ++#include <linux/slab.h> ++#include <linux/string.h> ++ ++#include "ts_filter_linear.h" ++ ++struct ts_filter_linear; ++ ++/* Sysfs code. */ ++ ++struct const_obj { ++ /* The actual private object. */ ++ struct ts_filter_linear *tsfl; ++ /* Our kobject. */ ++ struct kobject kobj; ++}; ++ ++#define to_const_obj(x) container_of(x, struct const_obj, kobj) ++ ++struct const_attribute { ++ struct attribute attr; ++ ssize_t (*show)(struct const_obj *const, struct const_attribute *attr, ++ char *buf); ++ ssize_t (*store)(struct const_obj *const, struct const_attribute *attr, ++ const char *buf, size_t count); ++}; ++ ++#define to_const_attr(x) container_of(x, struct const_attribute, attr) ++ ++ ++/* Private linear filter structure. */ ++ ++struct ts_filter_linear { ++ /* Private configuration for this filter. */ ++ struct ts_filter_linear_configuration *config; ++ ++ /* Generic filter API. */ ++ struct ts_filter tsf; ++ ++ /* Linear constants for the transformation. */ ++ int constants[TS_FILTER_LINEAR_NCONSTANTS]; ++ ++ /* Sysfs. */ ++ ++ /* Our const_object. */ ++ struct const_obj c_obj; ++ /* Our type. We will stick operations to it. */ ++ struct kobj_type const_ktype; ++ /* Attrs. of the virtual files. */ ++ struct const_attribute kattrs[TS_FILTER_LINEAR_NCONSTANTS]; ++ /* Default Attrs. Always NULL for us. */ ++ struct attribute *attrs[TS_FILTER_LINEAR_NCONSTANTS + 1]; ++ /* Storage for the name of the virtual files. */ ++ char attr_names[TS_FILTER_LINEAR_NCONSTANTS][2]; ++}; ++ ++#define ts_filter_to_filter_linear(f) \ ++ container_of(f, struct ts_filter_linear, tsf) ++ ++/* Sysfs functions. */ ++ ++static ssize_t const_attr_show(struct kobject *kobj, ++ struct attribute *attr, ++ char *buf) ++{ ++ struct const_attribute *a = to_const_attr(attr); ++ ++ return a->show(to_const_obj(kobj), a, buf); ++} ++ ++static ssize_t const_attr_store(struct kobject *kobj, ++ struct attribute *attr, ++ const char *buf, size_t len) ++{ ++ struct const_attribute *a = to_const_attr(attr); ++ ++ return a->store(to_const_obj(kobj), a, buf, len); ++} ++ ++static struct sysfs_ops const_sysfs_ops = { ++ .show = const_attr_show, ++ .store = const_attr_store, ++}; ++ ++static void const_release(struct kobject *kobj) ++{ ++ kfree(to_const_obj(kobj)->tsfl); ++} ++ ++static ssize_t const_show(struct const_obj *obj, struct const_attribute *attr, ++ char *buf) ++{ ++ int who; ++ ++ sscanf(attr->attr.name, "%d", &who); ++ return sprintf(buf, "%d\n", obj->tsfl->constants[who]); ++} ++ ++static ssize_t const_store(struct const_obj *obj, struct const_attribute *attr, ++ const char *buf, size_t count) ++{ ++ int who; ++ ++ sscanf(attr->attr.name, "%d", &who); ++ sscanf(buf, "%d", &obj->tsfl->constants[who]); ++ return count; ++} ++ ++/* Filter functions. */ ++ ++static struct ts_filter *ts_filter_linear_create( ++ struct platform_device *pdev, ++ const struct ts_filter_configuration *conf, ++ int count_coords) ++{ ++ struct ts_filter_linear *tsfl; ++ int i; ++ int ret; ++ ++ tsfl = kzalloc(sizeof(struct ts_filter_linear), GFP_KERNEL); ++ if (!tsfl) ++ return NULL; ++ ++ tsfl->config = container_of(conf, ++ struct ts_filter_linear_configuration, ++ config); ++ ++ tsfl->tsf.count_coords = count_coords; ++ ++ for (i = 0; i < TS_FILTER_LINEAR_NCONSTANTS; ++i) { ++ tsfl->constants[i] = tsfl->config->constants[i]; ++ ++ /* sysfs */ ++ sprintf(tsfl->attr_names[i], "%d", i); ++ tsfl->kattrs[i].attr.name = tsfl->attr_names[i]; ++ tsfl->kattrs[i].attr.mode = 0666; ++ tsfl->kattrs[i].show = const_show; ++ tsfl->kattrs[i].store = const_store; ++ tsfl->attrs[i] = &tsfl->kattrs[i].attr; ++ } ++ tsfl->attrs[i] = NULL; ++ ++ tsfl->const_ktype.sysfs_ops = &const_sysfs_ops; ++ tsfl->const_ktype.release = const_release; ++ tsfl->const_ktype.default_attrs = tsfl->attrs; ++ tsfl->c_obj.tsfl = tsfl; /* kernel frees tsfl in const_release */ ++ ++ ret = kobject_init_and_add(&tsfl->c_obj.kobj, &tsfl->const_ktype, ++ &pdev->dev.kobj, "calibration"); ++ if (ret) { ++ kobject_put(&tsfl->c_obj.kobj); ++ return NULL; ++ } ++ ++ dev_info(&pdev->dev, "Created Linear filter coords:%d\n", count_coords); ++ ++ return &tsfl->tsf; ++} ++ ++static void ts_filter_linear_destroy(struct ts_filter *tsf) ++{ ++ struct ts_filter_linear *tsfl = ts_filter_to_filter_linear(tsf); ++ ++ /* Kernel frees tsfl in const_release. */ ++ kobject_put(&tsfl->c_obj.kobj); ++} ++ ++static void ts_filter_linear_scale(struct ts_filter *tsf, int *coords) ++{ ++ struct ts_filter_linear *tsfl = ts_filter_to_filter_linear(tsf); ++ ++ int *k = tsfl->constants; ++ int c0 = coords[tsfl->config->coord0]; ++ int c1 = coords[tsfl->config->coord1]; ++ ++ coords[tsfl->config->coord0] = (k[2] + k[0] * c0 + k[1] * c1) / k[6]; ++ coords[tsfl->config->coord1] = (k[5] + k[3] * c0 + k[4] * c1) / k[6]; ++} ++ ++const struct ts_filter_api ts_filter_linear_api = { ++ .create = ts_filter_linear_create, ++ .destroy = ts_filter_linear_destroy, ++ .scale = ts_filter_linear_scale, ++}; ++EXPORT_SYMBOL_GPL(ts_filter_linear_api); ++ +diff -ruN --exclude='*.orig' --exclude='*.rej' linux-2.6.29-rc3.owrt/drivers/input/touchscreen/ts_filter_linear.h linux-2.6.29-rc3.owrt.om/drivers/input/touchscreen/ts_filter_linear.h +--- linux-2.6.29-rc3.owrt/drivers/input/touchscreen/ts_filter_linear.h 1970-01-01 01:00:00.000000000 +0100 ++++ linux-2.6.29-rc3.owrt.om/drivers/input/touchscreen/ts_filter_linear.h 2009-05-10 22:27:59.000000000 +0200 +@@ -0,0 +1,31 @@ ++#ifndef __TS_FILTER_LINEAR_H__ ++#define __TS_FILTER_LINEAR_H__ ++ ++#include "ts_filter.h" ++#include <linux/kobject.h> ++ ++/* ++ * Touchscreen linear filter. ++ * ++ * Copyright (C) 2008,2009 by Openmoko, Inc. ++ * Author: Nelson Castillo <arhuaco@freaks-unidos.net> ++ * ++ */ ++ ++#define TS_FILTER_LINEAR_NCONSTANTS 7 ++ ++struct ts_filter_linear_configuration { ++ /* Calibration constants. */ ++ int constants[TS_FILTER_LINEAR_NCONSTANTS]; ++ /* First coordinate. */ ++ int coord0; ++ /* Second coordinate. */ ++ int coord1; ++ ++ /* Generic filter configuration. */ ++ struct ts_filter_configuration config; ++}; ++ ++extern const struct ts_filter_api ts_filter_linear_api; ++ ++#endif +diff -ruN --exclude='*.orig' --exclude='*.rej' linux-2.6.29-rc3.owrt/drivers/input/touchscreen/ts_filter_mean.c linux-2.6.29-rc3.owrt.om/drivers/input/touchscreen/ts_filter_mean.c +--- linux-2.6.29-rc3.owrt/drivers/input/touchscreen/ts_filter_mean.c 1970-01-01 01:00:00.000000000 +0100 ++++ linux-2.6.29-rc3.owrt.om/drivers/input/touchscreen/ts_filter_mean.c 2009-05-10 22:27:59.000000000 +0200 +@@ -0,0 +1,174 @@ ++/* ++ * 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, MA 02111-1307 USA ++ * ++ * Copyright (c) 2008,2009 ++ * Andy Green <andy@openmoko.com> ++ * Nelson Castillo <arhuaco@freaks-unidos.net> ++ * ++ * Simple mean filter. ++ * ++ */ ++ ++#include <linux/errno.h> ++#include <linux/kernel.h> ++#include <linux/slab.h> ++ ++#include "ts_filter_mean.h" ++ ++struct ts_filter_mean { ++ /* Copy of the private filter configuration. */ ++ struct ts_filter_mean_configuration *config; ++ /* Filter API. */ ++ struct ts_filter tsf; ++ ++ /* Index on a circular buffer. */ ++ int curr; ++ /* Useful to tell if the circular buffer is full(read:ready). */ ++ int count; ++ /* Sumation used to compute the mean. */ ++ int sum[MAX_TS_FILTER_COORDS]; ++ /* Keep point values and decrement them from the sum on time. */ ++ int *fifo[MAX_TS_FILTER_COORDS]; ++ /* Store the output of this filter. */ ++ int ready; ++}; ++ ++#define ts_filter_to_filter_mean(f) container_of(f, struct ts_filter_mean, tsf) ++ ++ ++static void ts_filter_mean_clear(struct ts_filter *tsf); ++ ++static struct ts_filter *ts_filter_mean_create( ++ struct platform_device *pdev, ++ const struct ts_filter_configuration *conf, ++ int count_coords) ++{ ++ struct ts_filter_mean *priv; ++ int *v; ++ int n; ++ ++ priv = kzalloc(sizeof(struct ts_filter_mean), GFP_KERNEL); ++ if (!priv) ++ return NULL; ++ ++ priv->tsf.count_coords = count_coords; ++ priv->config = container_of(conf, ++ struct ts_filter_mean_configuration, ++ config); ++ ++ BUG_ON(priv->config->length <= 0); ++ ++ v = kmalloc(priv->config->length * sizeof(int) * count_coords, ++ GFP_KERNEL); ++ if (!v) ++ return NULL; ++ ++ for (n = 0; n < count_coords; n++) { ++ priv->fifo[n] = v; ++ v += priv->config->length; ++ } ++ ++ ts_filter_mean_clear(&priv->tsf); ++ ++ dev_info(&pdev->dev, "Created Mean filter len:%d coords:%d\n", ++ priv->config->length, count_coords); ++ ++ return &priv->tsf; ++} ++ ++static void ts_filter_mean_destroy(struct ts_filter *tsf) ++{ ++ struct ts_filter_mean *priv = ts_filter_to_filter_mean(tsf); ++ ++ kfree(priv->fifo[0]); /* first guy has pointer from kmalloc */ ++ kfree(tsf); ++} ++ ++static void ts_filter_mean_clear(struct ts_filter *tsf) ++{ ++ struct ts_filter_mean *priv = ts_filter_to_filter_mean(tsf); ++ ++ priv->count = 0; ++ priv->curr = 0; ++ priv->ready = 0; ++ memset(priv->sum, 0, tsf->count_coords * sizeof(int)); ++} ++ ++static int ts_filter_mean_process(struct ts_filter *tsf, int *coords) ++{ ++ struct ts_filter_mean *priv = ts_filter_to_filter_mean(tsf); ++ int n; ++ ++ BUG_ON(priv->ready); ++ ++ for (n = 0; n < tsf->count_coords; n++) { ++ priv->sum[n] += coords[n]; ++ priv->fifo[n][priv->curr] = coords[n]; ++ } ++ ++ if (priv->count + 1 == priv->config->length) ++ priv->ready = 1; ++ else ++ priv->count++; ++ ++ priv->curr = (priv->curr + 1) % priv->config->length; ++ ++ return 0; /* No error. */ ++} ++ ++static int ts_filter_mean_haspoint(struct ts_filter *tsf) ++{ ++ struct ts_filter_mean *priv = ts_filter_to_filter_mean(tsf); ++ ++ return priv->ready; ++} ++ ++static void ts_filter_mean_getpoint(struct ts_filter *tsf, int *point) ++{ ++ struct ts_filter_mean *priv = ts_filter_to_filter_mean(tsf); ++ int n; ++ ++ BUG_ON(!priv->ready); ++ ++ for (n = 0; n < tsf->count_coords; n++) { ++ point[n] = priv->sum[n]; ++ priv->sum[n] -= priv->fifo[n][priv->curr]; ++ } ++ ++ priv->ready = 0; ++} ++ ++static void ts_filter_mean_scale(struct ts_filter *tsf, int *coords) ++{ ++ int n; ++ struct ts_filter_mean *priv = ts_filter_to_filter_mean(tsf); ++ ++ for (n = 0; n < tsf->count_coords; n++) { ++ coords[n] += priv->config->length >> 1; /* Rounding. */ ++ coords[n] /= priv->config->length; ++ } ++} ++ ++const struct ts_filter_api ts_filter_mean_api = { ++ .create = ts_filter_mean_create, ++ .destroy = ts_filter_mean_destroy, ++ .clear = ts_filter_mean_clear, ++ .process = ts_filter_mean_process, ++ .scale = ts_filter_mean_scale, ++ .haspoint = ts_filter_mean_haspoint, ++ .getpoint = ts_filter_mean_getpoint, ++}; ++EXPORT_SYMBOL_GPL(ts_filter_mean_api); ++ +diff -ruN --exclude='*.orig' --exclude='*.rej' linux-2.6.29-rc3.owrt/drivers/input/touchscreen/ts_filter_mean.h linux-2.6.29-rc3.owrt.om/drivers/input/touchscreen/ts_filter_mean.h +--- linux-2.6.29-rc3.owrt/drivers/input/touchscreen/ts_filter_mean.h 1970-01-01 01:00:00.000000000 +0100 ++++ linux-2.6.29-rc3.owrt.om/drivers/input/touchscreen/ts_filter_mean.h 2009-05-10 22:27:59.000000000 +0200 +@@ -0,0 +1,28 @@ ++#ifndef __TS_FILTER_MEAN_H__ ++#define __TS_FILTER_MEAN_H__ ++ ++#include "ts_filter.h" ++ ++/* ++ * Touchscreen filter. ++ * ++ * mean ++ * ++ * (c) 2008,2009 ++ * Andy Green <andy@openmoko.com> ++ * Nelson Castillo <arhuaco@freaks-unidos.net> ++ */ ++ ++/* Configuration for this filter. */ ++struct ts_filter_mean_configuration { ++ /* Number of points for the mean. */ ++ int length; ++ ++ /* Generic filter configuration. */ ++ struct ts_filter_configuration config; ++}; ++ ++/* API functions for the mean filter */ ++extern const struct ts_filter_api ts_filter_mean_api; ++ ++#endif /* __TS_FILTER_MEAN_H__ */ +diff -ruN --exclude='*.orig' --exclude='*.rej' linux-2.6.29-rc3.owrt/drivers/input/touchscreen/ts_filter_median.c linux-2.6.29-rc3.owrt.om/drivers/input/touchscreen/ts_filter_median.c +--- linux-2.6.29-rc3.owrt/drivers/input/touchscreen/ts_filter_median.c 1970-01-01 01:00:00.000000000 +0100 ++++ linux-2.6.29-rc3.owrt.om/drivers/input/touchscreen/ts_filter_median.c 2009-05-10 22:27:59.000000000 +0200 +@@ -0,0 +1,261 @@ ++/* ++ * 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, MA 02111-1307 USA ++ * ++ * Copyright (c) 2008 Andy Green <andy@openmoko.com> ++ * ++ * ++ * Median averaging stuff. We sort incoming raw samples into an array of ++ * MEDIAN_SIZE length, discarding the oldest sample each time once we are full. ++ * We then return the sum of the middle three samples for X and Y. It means ++ * the final result must be divided by (3 * scaling factor) to correct for ++ * avoiding the repeated /3. ++ * ++ * This strongly rejects brief excursions away from a central point that is ++ * sticky in time compared to the excursion duration. ++ * ++ * Thanks to Dale Schumacher (who wrote some example code) and Carl-Daniel ++ * Halifinger who pointed out this would be a good method. ++ */ ++ ++#include <linux/errno.h> ++#include <linux/kernel.h> ++#include <linux/slab.h> ++#include "ts_filter_median.h" ++ ++struct ts_filter_median { ++ /* Private configuration. */ ++ struct ts_filter_median_configuration *config; ++ /* Generic Filter API. */ ++ struct ts_filter tsf; ++ ++ /* Count raw samples we get. */ ++ int samples_count; ++ /* ++ * Remember the last coordinates we got in order to know if ++ * we are moving slow or fast. ++ */ ++ int last_issued[MAX_TS_FILTER_COORDS]; ++ /* How many samples in the sort buffer are valid. */ ++ int valid; ++ /* Samples taken for median in sorted form. */ ++ int *sort[MAX_TS_FILTER_COORDS]; ++ /* Samples taken for median. */ ++ int *fifo[MAX_TS_FILTER_COORDS]; ++ /* Where we are in the fifo sample memory. */ ++ int pos; ++ /* Do we have a sample to deliver? */ ++ int ready; ++}; ++ ++#define ts_filter_to_filter_median(f) \ ++ container_of(f, struct ts_filter_median, tsf) ++ ++ ++static void ts_filter_median_insert(int *p, int sample, int count) ++{ ++ int n; ++ ++ /* Search through what we got so far to find where to put sample. */ ++ for (n = 0; n < count; n++) ++ if (sample < p[n]) { /* We met somebody bigger than us? */ ++ /* Starting from the end, push bigger guys down one. */ ++ for (count--; count >= n; count--) ++ p[count + 1] = p[count]; ++ p[n] = sample; /* Put us in place of first bigger. */ ++ return; ++ } ++ ++ p[count] = sample; /* Nobody was bigger than us, add us on the end. */ ++} ++ ++static void ts_filter_median_del(int *p, int value, int count) ++{ ++ int index; ++ ++ for (index = 0; index < count; index++) ++ if (p[index] == value) { ++ for (; index < count; index++) ++ p[index] = p[index + 1]; ++ return; ++ } ++} ++ ++ ++static void ts_filter_median_clear(struct ts_filter *tsf) ++{ ++ struct ts_filter_median *tsfm = ts_filter_to_filter_median(tsf); ++ ++ tsfm->pos = 0; ++ tsfm->valid = 0; ++ tsfm->ready = 0; ++ memset(&tsfm->last_issued[0], 1, tsf->count_coords * sizeof(int)); ++} ++ ++static struct ts_filter *ts_filter_median_create( ++ struct platform_device *pdev, ++ const struct ts_filter_configuration *conf, ++ int count_coords) ++{ ++ int *p; ++ int n; ++ struct ts_filter_median *tsfm = kzalloc(sizeof(struct ts_filter_median), ++ GFP_KERNEL); ++ ++ if (!tsfm) ++ return NULL; ++ ++ tsfm->config = container_of(conf, ++ struct ts_filter_median_configuration, ++ config); ++ ++ tsfm->tsf.count_coords = count_coords; ++ ++ tsfm->config->midpoint = (tsfm->config->extent >> 1) + 1; ++ ++ p = kmalloc(2 * count_coords * sizeof(int) * (tsfm->config->extent + 1), ++ GFP_KERNEL); ++ if (!p) { ++ kfree(tsfm); ++ return NULL; ++ } ++ ++ for (n = 0; n < count_coords; n++) { ++ tsfm->sort[n] = p; ++ p += tsfm->config->extent + 1; ++ tsfm->fifo[n] = p; ++ p += tsfm->config->extent + 1; ++ } ++ ++ ts_filter_median_clear(&tsfm->tsf); ++ ++ dev_info(&pdev->dev, ++ "Created Median filter len:%d coords:%d dec_threshold:%d\n", ++ tsfm->config->extent, count_coords, ++ tsfm->config->decimation_threshold); ++ ++ return &tsfm->tsf; ++} ++ ++static void ts_filter_median_destroy(struct ts_filter *tsf) ++{ ++ struct ts_filter_median *tsfm = ts_filter_to_filter_median(tsf); ++ ++ kfree(tsfm->sort[0]); /* First guy has pointer from kmalloc. */ ++ kfree(tsf); ++} ++ ++static void ts_filter_median_scale(struct ts_filter *tsf, int *coords) ++{ ++ int n; ++ ++ for (n = 0; n < tsf->count_coords; n++) ++ coords[n] = (coords[n] + 2) / 3; ++} ++ ++/* ++ * Give us the raw sample data coords, and if we return 1 then you can ++ * get a filtered coordinate from coords. If we return 0 you didn't ++ * fill all the filters with samples yet. ++ */ ++ ++static int ts_filter_median_process(struct ts_filter *tsf, int *coords) ++{ ++ struct ts_filter_median *tsfm = ts_filter_to_filter_median(tsf); ++ int n; ++ int movement = 1; ++ ++ for (n = 0; n < tsf->count_coords; n++) { ++ /* Grab copy in insertion order to remove when oldest. */ ++ tsfm->fifo[n][tsfm->pos] = coords[n]; ++ /* Insert these samples in sorted order in the median arrays. */ ++ ts_filter_median_insert(tsfm->sort[n], coords[n], tsfm->valid); ++ } ++ /* Move us on in the fifo. */ ++ if (++tsfm->pos == (tsfm->config->extent + 1)) ++ tsfm->pos = 0; ++ ++ /* Have we finished a median sampling? */ ++ if (++tsfm->valid < tsfm->config->extent) ++ goto process_exit; /* No valid sample to use. */ ++ ++ BUG_ON(tsfm->valid != tsfm->config->extent); ++ ++ tsfm->valid--; ++ ++ /* ++ * Sum the middle 3 in the median sorted arrays. We don't divide back ++ * down which increases the sum resolution by a factor of 3 until the ++ * scale API function is called. ++ */ ++ for (n = 0; n < tsf->count_coords; n++) ++ /* Perform the deletion of the oldest sample. */ ++ ts_filter_median_del(tsfm->sort[n], tsfm->fifo[n][tsfm->pos], ++ tsfm->valid); ++ ++ tsfm->samples_count--; ++ if (tsfm->samples_count >= 0) ++ goto process_exit; ++ ++ for (n = 0; n < tsf->count_coords; n++) { ++ /* Give the coordinate result from summing median 3. */ ++ coords[n] = tsfm->sort[n][tsfm->config->midpoint - 1] + ++ tsfm->sort[n][tsfm->config->midpoint] + ++ tsfm->sort[n][tsfm->config->midpoint + 1]; ++ ++ movement += abs(tsfm->last_issued[n] - coords[n]); ++ } ++ ++ if (movement > tsfm->config->decimation_threshold) /* Moving fast. */ ++ tsfm->samples_count = tsfm->config->decimation_above; ++ else ++ tsfm->samples_count = tsfm->config->decimation_below; ++ ++ memcpy(&tsfm->last_issued[0], coords, tsf->count_coords * sizeof(int)); ++ ++ tsfm->ready = 1; ++ ++process_exit: ++ return 0; ++} ++ ++static int ts_filter_median_haspoint(struct ts_filter *tsf) ++{ ++ struct ts_filter_median *priv = ts_filter_to_filter_median(tsf); ++ ++ return priv->ready; ++} ++ ++static void ts_filter_median_getpoint(struct ts_filter *tsf, int *point) ++{ ++ struct ts_filter_median *priv = ts_filter_to_filter_median(tsf); ++ ++ BUG_ON(!priv->ready); ++ ++ memcpy(point, &priv->last_issued[0], tsf->count_coords * sizeof(int)); ++ ++ priv->ready = 0; ++} ++ ++const struct ts_filter_api ts_filter_median_api = { ++ .create = ts_filter_median_create, ++ .destroy = ts_filter_median_destroy, ++ .clear = ts_filter_median_clear, ++ .process = ts_filter_median_process, ++ .scale = ts_filter_median_scale, ++ .haspoint = ts_filter_median_haspoint, ++ .getpoint = ts_filter_median_getpoint, ++}; ++EXPORT_SYMBOL_GPL(ts_filter_median_api); ++ +diff -ruN --exclude='*.orig' --exclude='*.rej' linux-2.6.29-rc3.owrt/drivers/input/touchscreen/ts_filter_median.h linux-2.6.29-rc3.owrt.om/drivers/input/touchscreen/ts_filter_median.h +--- linux-2.6.29-rc3.owrt/drivers/input/touchscreen/ts_filter_median.h 1970-01-01 01:00:00.000000000 +0100 ++++ linux-2.6.29-rc3.owrt.om/drivers/input/touchscreen/ts_filter_median.h 2009-05-10 22:27:59.000000000 +0200 +@@ -0,0 +1,32 @@ ++#ifndef __TS_FILTER_MEDIAN_H__ ++#define __TS_FILTER_MEDIAN_H__ ++ ++#include "ts_filter.h" ++ ++/* ++ * Touchscreen filter. ++ * ++ * median ++ * ++ * (c) 2008 Andy Green <andy@openmoko.com> ++ */ ++ ++struct ts_filter_median_configuration { ++ /* Size of the filter. */ ++ int extent; ++ /* Precomputed midpoint. */ ++ int midpoint; ++ /* A reference value for us to check if we are going fast or slow. */ ++ int decimation_threshold; ++ /* How many points to replace if we're going fast. */ ++ int decimation_above; ++ /* How many points to replace if we're going slow. */ ++ int decimation_below; ++ ++ /* Generic configuration. */ ++ struct ts_filter_configuration config; ++}; ++ ++extern const struct ts_filter_api ts_filter_median_api; ++ ++#endif +diff -ruN --exclude='*.orig' --exclude='*.rej' linux-2.6.29-rc3.owrt/drivers/Kconfig linux-2.6.29-rc3.owrt.om/drivers/Kconfig +--- linux-2.6.29-rc3.owrt/drivers/Kconfig 2009-05-10 22:04:48.000000000 +0200 ++++ linux-2.6.29-rc3.owrt.om/drivers/Kconfig 2009-05-10 22:27:59.000000000 +0200 +@@ -109,4 +109,5 @@ + source "drivers/staging/Kconfig" + + source "drivers/platform/Kconfig" ++ + endmenu +diff -ruN --exclude='*.orig' --exclude='*.rej' linux-2.6.29-rc3.owrt/drivers/leds/Kconfig linux-2.6.29-rc3.owrt.om/drivers/leds/Kconfig +--- linux-2.6.29-rc3.owrt/drivers/leds/Kconfig 2009-05-10 22:04:48.000000000 +0200 ++++ linux-2.6.29-rc3.owrt.om/drivers/leds/Kconfig 2009-05-10 22:27:59.000000000 +0200 +@@ -33,7 +33,7 @@ + + config LEDS_S3C24XX + tristate "LED Support for Samsung S3C24XX GPIO LEDs" +- depends on LEDS_CLASS && ARCH_S3C2410 ++ depends on LEDS_CLASS && ARCH_S3C2410 && S3C2410_PWM + help + This option enables support for LEDs connected to GPIO lines + on Samsung S3C24XX series CPUs, such as the S3C2410 and S3C2440. +@@ -171,6 +171,25 @@ + This option enables support for on-chip LED drivers found + on Dialog Semiconductor DA9030/DA9034 PMICs. + ++config LEDS_NEO1973_VIBRATOR ++ tristate "Vibrator Support for the FIC Neo1973 GSM phone" ++ depends on LEDS_CLASS && MACH_NEO1973 ++ help ++ This option enables support for the vibrator on the FIC Neo1973. ++ ++config LEDS_NEO1973_GTA02 ++ tristate "LED Support for the FIC Neo1973 (GTA02)" ++ depends on LEDS_CLASS && MACH_NEO1973_GTA02 ++ help ++ This option enables support for the LEDs on the FIC Neo1973. ++ ++config LEDS_LP5521 ++ tristate "LED Support for LP5521 LED I2C chip" ++ depends on LEDS_CLASS && I2C ++ help ++ If you say yes here you get support for the National Semiconductor ++ LP5521 LED driver. ++ + comment "LED Triggers" + + config LEDS_TRIGGERS +@@ -234,4 +253,11 @@ + This allows LEDs to be controlled by network device activity. + If unsure, say Y. + ++config LEDS_TRIGGER_NETDEV ++ tristate "LED Network Device Trigger" ++ depends on LEDS_TRIGGERS ++ help ++ This allows LEDs to be controlled by Network Device activity. ++ If unsure, say Y. ++ + endif # NEW_LEDS +diff -ruN --exclude='*.orig' --exclude='*.rej' linux-2.6.29-rc3.owrt/drivers/leds/led-class.c linux-2.6.29-rc3.owrt.om/drivers/leds/led-class.c +--- linux-2.6.29-rc3.owrt/drivers/leds/led-class.c 2009-05-10 22:04:48.000000000 +0200 ++++ linux-2.6.29-rc3.owrt.om/drivers/leds/led-class.c 2009-05-10 22:27:59.000000000 +0200 +@@ -56,8 +56,10 @@ + if (count == size) { + ret = count; + ++#if 0 /* This is really bad. Don't do it!!!! */ + if (state == LED_OFF) + led_trigger_remove(led_cdev); ++#endif + led_set_brightness(led_cdev, state); + } + +diff -ruN --exclude='*.orig' --exclude='*.rej' linux-2.6.29-rc3.owrt/drivers/leds/leds-lp5521.c linux-2.6.29-rc3.owrt.om/drivers/leds/leds-lp5521.c +--- linux-2.6.29-rc3.owrt/drivers/leds/leds-lp5521.c 1970-01-01 01:00:00.000000000 +0100 ++++ linux-2.6.29-rc3.owrt.om/drivers/leds/leds-lp5521.c 2009-05-10 22:27:59.000000000 +0200 +@@ -0,0 +1,386 @@ ++/* NS LP5521 Programmable LED driver. ++ * ++ * (C) 2009 by Openmoko, Inc. ++ * Author: Matt Hsu <matt_hsu@openmoko.org> ++ * ++ * 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, MA 02111-1307 USA ++ */ ++#include <linux/module.h> ++#include <linux/init.h> ++#include <linux/i2c.h> ++#include <linux/mutex.h> ++#include <linux/device.h> ++#include <linux/sysfs.h> ++#include <linux/interrupt.h> ++#include <linux/irq.h> ++ ++#include <linux/lp5521.h> ++ ++#define LP5521_DRIVER_NAME "lp5521" ++ ++static int __lp5521_reg_write(struct lp5521 *lp, u8 reg, u8 value) ++{ ++ return i2c_smbus_write_byte_data(lp->client, reg, value); ++} ++ ++static int reg_write(struct lp5521 *lp, u_int8_t reg, u_int8_t val) ++{ ++ int ret; ++ ++ mutex_lock(&lp->lock); ++ ret = __lp5521_reg_write(lp, reg, val); ++ mutex_unlock(&lp->lock); ++ ++ return ret; ++} ++ ++static int __lp5521_reg_read(struct lp5521 *lp, u8 reg) ++{ ++ int32_t ret; ++ ++ ret = i2c_smbus_read_byte_data(lp->client, reg); ++ ++ return ret; ++} ++ ++static u_int8_t reg_read(struct lp5521 *lp, u_int8_t reg) ++{ ++ int32_t ret; ++ ++ mutex_lock(&lp->lock); ++ ret = __lp5521_reg_read(lp, reg); ++ mutex_unlock(&lp->lock); ++ ++ return ret & 0xff; ++} ++ ++static int reg_set_bit_mask(struct lp5521 *lp, ++ u_int8_t reg, u_int8_t mask, u_int8_t val) ++{ ++ int ret; ++ u_int8_t tmp; ++ ++ val &= mask; ++ ++ mutex_lock(&lp->lock); ++ ++ tmp = __lp5521_reg_read(lp, reg); ++ tmp &= ~mask; ++ tmp |= val; ++ ret = __lp5521_reg_write(lp, reg, tmp); ++ ++ mutex_unlock(&lp->lock); ++ ++ return ret; ++} ++ ++static const char *lp5521_ch_name[] = { ++ "blue", "green", "red", ++}; ++ ++static inline int channel_id_by_name(const char *name) ++{ ++ int channel_id = -1; ++ ++ if (!strncmp(name, lp5521_ch_name[LP5521_BLUE], ++ strlen(lp5521_ch_name[LP5521_BLUE]))) ++ channel_id = LP5521_BLUE; ++ else if (!strncmp(name, lp5521_ch_name[LP5521_GREEN], ++ strlen(lp5521_ch_name[LP5521_GREEN]))) ++ channel_id = LP5521_GREEN; ++ else if (!strncmp(name, lp5521_ch_name[LP5521_RED], ++ strlen(lp5521_ch_name[LP5521_RED]))) ++ channel_id = LP5521_RED; ++ ++ return channel_id; ++} ++ ++static const char *lp5521_ch_mode[] = { ++ "disable", "load", "run", ++ "direct", ++}; ++ ++/* ++ * Individual mode control ++ */ ++static ssize_t show_mode(struct device *dev, struct device_attribute ++ *attr, char *buf) ++{ ++ struct i2c_client *client = to_i2c_client(dev); ++ struct lp5521 *lp = i2c_get_clientdata(client); ++ int id; ++ uint8_t val; ++ ++ id = channel_id_by_name(attr->attr.name); ++ val = reg_read(lp, LP5521_REG_OP_MODE); ++ ++ val = val >> (id * 2); ++ val &= 0x3; ++ ++ return sprintf(buf, "%s\n", lp5521_ch_mode[val]); ++} ++ ++static ssize_t set_mode(struct device *dev, struct device_attribute *attr, ++ const char *buf, size_t count) ++{ ++ struct i2c_client *client = to_i2c_client(dev); ++ struct lp5521 *lp = i2c_get_clientdata(client); ++ int id; ++ uint8_t mask, i; ++ ++ id = channel_id_by_name(attr->attr.name); ++ ++ mask = (0x3 << (id * 2)); ++ ++ for (i = LP5521_MODE_DISABLE; i <= LP5521_MODE_DIRECT; i++) { ++ if (!strncmp(buf, lp5521_ch_mode[i], strlen(lp5521_ch_mode[i]))) { ++ reg_set_bit_mask(lp, ++ LP5521_REG_OP_MODE, mask, (i << (id * 2))); ++ } ++ } ++ ++ return count; ++} ++ ++static DEVICE_ATTR(red_mode, S_IRUGO | S_IWUSR, show_mode, set_mode); ++static DEVICE_ATTR(green_mode, S_IRUGO | S_IWUSR, show_mode, set_mode); ++static DEVICE_ATTR(blue_mode, S_IRUGO | S_IWUSR, show_mode, set_mode); ++ ++/* ++ * Individual pwm control ++ */ ++static ssize_t show_pwm(struct device *dev, struct device_attribute ++ *attr, char *buf) ++{ ++ struct i2c_client *client = to_i2c_client(dev); ++ struct lp5521 *lp = i2c_get_clientdata(client); ++ int id; ++ uint8_t val; ++ ++ id = channel_id_by_name(attr->attr.name); ++ val = reg_read(lp, LP5521_REG_B_PWM-id); ++ ++ return sprintf(buf, "%d\n", val); ++} ++ ++static ssize_t set_pwm(struct device *dev, struct device_attribute *attr, ++ const char *buf, size_t count) ++{ ++ int id; ++ struct i2c_client *client = to_i2c_client(dev); ++ struct lp5521 *lp = i2c_get_clientdata(client); ++ unsigned int pwm = simple_strtoul(buf, NULL, 10); ++ ++ id = channel_id_by_name(attr->attr.name); ++ reg_write(lp, LP5521_REG_B_PWM-id, pwm); ++ ++ return count; ++} ++ ++static DEVICE_ATTR(red_pwm, S_IRUGO | S_IWUSR, show_pwm, set_pwm); ++static DEVICE_ATTR(green_pwm, S_IRUGO | S_IWUSR, show_pwm, set_pwm); ++static DEVICE_ATTR(blue_pwm, S_IRUGO | S_IWUSR, show_pwm, set_pwm); ++ ++/* ++ * Individual current control ++ */ ++static ssize_t show_cur(struct device *dev, struct device_attribute ++ *attr, char *buf) ++{ ++ struct i2c_client *client = to_i2c_client(dev); ++ struct lp5521 *lp = i2c_get_clientdata(client); ++ int id; ++ uint8_t val; ++ ++ id = channel_id_by_name(attr->attr.name); ++ val = reg_read(lp, LP5521_REG_B_CUR-id); ++ ++ return sprintf(buf, "%d (100uA)\n", val); ++} ++ ++static ssize_t set_cur(struct device *dev, struct device_attribute *attr, ++ const char *buf, size_t count) ++{ ++ int id; ++ struct i2c_client *client = to_i2c_client(dev); ++ struct lp5521 *lp = i2c_get_clientdata(client); ++ unsigned int cur = simple_strtoul(buf, NULL, 10); ++ ++ id = channel_id_by_name(attr->attr.name); ++ reg_write(lp, LP5521_REG_B_CUR-id, cur); ++ ++ return count; ++} ++ ++static DEVICE_ATTR(red_cur, S_IRUGO | S_IWUSR, show_cur, set_cur); ++static DEVICE_ATTR(green_cur, S_IRUGO | S_IWUSR, show_cur, set_cur); ++static DEVICE_ATTR(blue_cur, S_IRUGO | S_IWUSR, show_cur, set_cur); ++ ++static struct attribute *lp_sysfs_entries[16]; ++ ++static struct attribute_group lp_attr_group = { ++ .name = NULL, ++ .attrs = lp_sysfs_entries, ++}; ++ ++static void populate_sysfs_group(struct lp5521 *lp) ++{ ++ int i = 0; ++ ++ if (lp->pdata->channels[LP5521_RED] & LP5521_CONNECTED) { ++ lp_sysfs_entries[i++] = &dev_attr_red_mode.attr; ++ lp_sysfs_entries[i++] = &dev_attr_red_pwm.attr; ++ lp_sysfs_entries[i++] = &dev_attr_red_cur.attr; ++ } ++ ++ if (lp->pdata->channels[LP5521_GREEN] & LP5521_CONNECTED) { ++ lp_sysfs_entries[i++] = &dev_attr_green_mode.attr; ++ lp_sysfs_entries[i++] = &dev_attr_green_pwm.attr; ++ lp_sysfs_entries[i++] = &dev_attr_green_cur.attr; ++ } ++ ++ if (lp->pdata->channels[LP5521_BLUE] & LP5521_CONNECTED) { ++ lp_sysfs_entries[i++] = &dev_attr_blue_mode.attr; ++ lp_sysfs_entries[i++] = &dev_attr_blue_pwm.attr; ++ lp_sysfs_entries[i++] = &dev_attr_blue_cur.attr; ++ } ++} ++ ++static struct i2c_driver lp5521_driver; ++ ++#ifdef CONFIG_PM ++static int lp5521_suspend(struct device *dev, pm_message_t state) ++{ ++ /* FIXME: Not implemented ++ * Here we could upload firmware to perform ++ * any scenarios we want and save registers. ++ */ ++ return 0; ++} ++ ++static int lp5521_resume(struct device *dev) ++{ ++ /* FIXME: Not implemented */ ++ return 0; ++} ++#else ++#define lp5521_suspend NULL ++#define lp5521_resume NULL ++#endif ++ ++static irqreturn_t lp5521_irq(int irq, void *_lp) ++{ ++ struct lp5521 *lp = _lp; ++ dev_info(lp->dev, "lp5521 interrupt\n"); ++ ++ return IRQ_HANDLED; ++} ++ ++static int __devinit ++lp5521_probe(struct i2c_client *client, const struct i2c_device_id *id) ++{ ++ struct lp5521 *lp; ++ int ret = 0; ++ struct lp5521_platform_data *pdata = client->dev.platform_data; ++ ++ lp = kzalloc(sizeof(*lp), GFP_KERNEL); ++ if (!lp) ++ return -ENOMEM; ++ ++ lp->client = client; ++ lp->irq = client->irq; ++ lp->dev = &client->dev; ++ i2c_set_clientdata(client, lp); ++ ++ lp->pdata = pdata; ++ mutex_init(&lp->lock); ++ ++ /* enter start-up mode */ ++ if (pdata->ext_enable) ++ (pdata->ext_enable)(1); ++ ++ reg_write(lp, LP5521_REG_ENABLE, 0x40); ++ ++ /* charge pump mode and clk src selection */ ++ reg_write(lp, LP5521_REG_CONFIG, 0x11); ++ ++ /* allocate IRQ resource */ ++ if (lp->irq) { ++ ret = request_irq(client->irq, lp5521_irq, ++ IRQF_TRIGGER_LOW, LP5521_DRIVER_NAME, lp); ++ if (ret) { ++ dev_err(lp->dev, "request IRQ failed\n"); ++ goto fail; ++ } ++ } else { ++ dev_err(lp->dev, "No IRQ allocated \n"); ++ } ++ ++ populate_sysfs_group(lp); ++ ++ ret = sysfs_create_group(&client->dev.kobj, &lp_attr_group); ++ ++ if (ret) { ++ dev_err(lp->dev, "error creating sysfs group\n"); ++ goto fail; ++ } ++ ++ return ret; ++ ++fail: ++ kfree(lp); ++ return ret; ++} ++ ++static int __devexit lp5521_remove(struct i2c_client *client) ++{ ++ struct lp5521 *lp = i2c_get_clientdata(client); ++ ++ kfree(lp); ++ ++ return 0; ++} ++ ++static struct i2c_device_id lp5521_id[] = { ++ {LP5521_DRIVER_NAME, }, ++}; ++ ++static struct i2c_driver lp5521_driver = { ++ .driver = { ++ .name = LP5521_DRIVER_NAME, ++ .suspend = lp5521_suspend, ++ .resume = lp5521_resume, ++ }, ++ .id_table = lp5521_id, ++ .probe = lp5521_probe, ++ .remove = __exit_p(lp5521_remove), ++}; ++ ++static int __init lp5521_init(void) ++{ ++ return i2c_add_driver(&lp5521_driver); ++} ++ ++static void __exit lp5521_exit(void) ++{ ++ i2c_del_driver(&lp5521_driver); ++} ++ ++MODULE_AUTHOR("Matt Hsu <matt_hsu@openmoko.org>"); ++MODULE_DESCRIPTION("NS lp5521 LED driver"); ++MODULE_LICENSE("GPLv2"); ++ ++module_init(lp5521_init); ++module_exit(lp5521_exit); +diff -ruN --exclude='*.orig' --exclude='*.rej' linux-2.6.29-rc3.owrt/drivers/leds/leds-neo1973-gta02.c linux-2.6.29-rc3.owrt.om/drivers/leds/leds-neo1973-gta02.c +--- linux-2.6.29-rc3.owrt/drivers/leds/leds-neo1973-gta02.c 1970-01-01 01:00:00.000000000 +0100 ++++ linux-2.6.29-rc3.owrt.om/drivers/leds/leds-neo1973-gta02.c 2009-05-10 22:27:59.000000000 +0200 +@@ -0,0 +1,179 @@ ++/* ++ * LED driver for the Openmoko GTA02 GSM phone ++ * ++ * (C) 2006-2008 by Openmoko, Inc. ++ * Author: Harald Welte <laforge@openmoko.org> ++ * All rights reserved. ++ * ++ * 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 <mach/hardware.h> ++#include <asm/mach-types.h> ++#include <mach/gta02.h> ++#include <plat/regs-timer.h> ++#include <asm/plat-s3c24xx/neo1973.h> ++ ++#define MAX_LEDS 3 ++#define COUNTER 256 ++ ++struct gta02_led_priv ++{ ++ spinlock_t lock; ++ struct led_classdev cdev; ++ unsigned int gpio; ++}; ++ ++struct gta02_led_bundle ++{ ++ int num_leds; ++ struct gta02_led_priv led[MAX_LEDS]; ++}; ++ ++static inline struct gta02_led_priv *to_priv(struct led_classdev *led_cdev) ++{ ++ return container_of(led_cdev, struct gta02_led_priv, cdev); ++} ++ ++static inline struct gta02_led_bundle *to_bundle(struct led_classdev *led_cdev) ++{ ++ return dev_get_drvdata(led_cdev->dev->parent); ++} ++ ++static void gta02led_set(struct led_classdev *led_cdev, ++ enum led_brightness value) ++{ ++ unsigned long flags; ++ struct gta02_led_priv *lp = to_priv(led_cdev); ++ ++ spin_lock_irqsave(&lp->lock, flags); ++ neo1973_gpb_setpin(lp->gpio, value ? 1 : 0); ++ spin_unlock_irqrestore(&lp->lock, flags); ++} ++ ++#ifdef CONFIG_PM ++static int gta02led_suspend(struct platform_device *pdev, pm_message_t state) ++{ ++ struct gta02_led_bundle *bundle = platform_get_drvdata(pdev); ++ int i; ++ ++ for (i = 0; i < bundle->num_leds; i++) ++ led_classdev_suspend(&bundle->led[i].cdev); ++ ++ return 0; ++} ++ ++static int gta02led_resume(struct platform_device *pdev) ++{ ++ struct gta02_led_bundle *bundle = platform_get_drvdata(pdev); ++ int i; ++ ++ for (i = 0; i < bundle->num_leds; i++) ++ led_classdev_resume(&bundle->led[i].cdev); ++ ++ return 0; ++} ++#endif ++ ++static int __init gta02led_probe(struct platform_device *pdev) ++{ ++ int i, rc; ++ struct gta02_led_bundle *bundle; ++ ++ if (!machine_is_neo1973_gta02()) ++ return -EIO; ++ ++ bundle = kzalloc(sizeof(struct gta02_led_bundle), GFP_KERNEL); ++ if (!bundle) ++ return -ENOMEM; ++ platform_set_drvdata(pdev, bundle); ++ ++ for (i = 0; i < pdev->num_resources; i++) { ++ struct gta02_led_priv *lp; ++ struct resource *r; ++ ++ if (i >= MAX_LEDS) ++ break; ++ ++ r = platform_get_resource(pdev, 0, i); ++ if (!r || !r->start || !r->name) ++ continue; ++ ++ lp = &bundle->led[i]; ++ ++ lp->gpio = r->start; ++ lp->cdev.name = r->name; ++ lp->cdev.brightness_set = gta02led_set; ++ ++ switch (lp->gpio) { ++ case S3C2410_GPB0: ++ case S3C2410_GPB1: ++ case S3C2410_GPB2: ++ s3c2410_gpio_cfgpin(lp->gpio, S3C2410_GPIO_OUTPUT); ++ neo1973_gpb_add_shadow_gpio(lp->gpio); ++ break; ++ default: ++ break; ++ } ++ ++ spin_lock_init(&lp->lock); ++ rc = led_classdev_register(&pdev->dev, &lp->cdev); ++ } ++ ++ bundle->num_leds = i; ++ ++ return 0; ++} ++ ++static int gta02led_remove(struct platform_device *pdev) ++{ ++ struct gta02_led_bundle *bundle = platform_get_drvdata(pdev); ++ int i; ++ ++ for (i = 0; i < bundle->num_leds; i++) { ++ struct gta02_led_priv *lp = &bundle->led[i]; ++ gta02led_set(&lp->cdev, 0); ++ led_classdev_unregister(&lp->cdev); ++ } ++ ++ platform_set_drvdata(pdev, NULL); ++ kfree(bundle); ++ ++ return 0; ++} ++ ++static struct platform_driver gta02led_driver = { ++ .probe = gta02led_probe, ++ .remove = gta02led_remove, ++#ifdef CONFIG_PM ++ .suspend = gta02led_suspend, ++ .resume = gta02led_resume, ++#endif ++ .driver = { ++ .name = "gta02-led", ++ }, ++}; ++ ++static int __init gta02led_init(void) ++{ ++ return platform_driver_register(>a02led_driver); ++} ++ ++static void __exit gta02led_exit(void) ++{ ++ platform_driver_unregister(>a02led_driver); ++} ++ ++module_init(gta02led_init); ++module_exit(gta02led_exit); ++ ++MODULE_AUTHOR("Harald Welte <laforge@openmoko.org>"); ++MODULE_DESCRIPTION("Openmoko GTA02 LED driver"); ++MODULE_LICENSE("GPL"); +diff -ruN --exclude='*.orig' --exclude='*.rej' linux-2.6.29-rc3.owrt/drivers/leds/leds-neo1973-vibrator.c linux-2.6.29-rc3.owrt.om/drivers/leds/leds-neo1973-vibrator.c +--- linux-2.6.29-rc3.owrt/drivers/leds/leds-neo1973-vibrator.c 1970-01-01 01:00:00.000000000 +0100 ++++ linux-2.6.29-rc3.owrt.om/drivers/leds/leds-neo1973-vibrator.c 2009-05-10 22:27:59.000000000 +0200 +@@ -0,0 +1,241 @@ ++/* ++ * LED driver for the vibrator of the Openmoko GTA01/GTA02 GSM Phones ++ * ++ * (C) 2006-2008 by Openmoko, Inc. ++ * Author: Harald Welte <laforge@openmoko.org> ++ * All rights reserved. ++ * ++ * 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. ++ * ++ * Javi Roman <javiroman@kernel-labs.org>: ++ * Implement PWM support for GTA01Bv4 and later ++ */ ++ ++#include <linux/kernel.h> ++#include <linux/init.h> ++#include <linux/platform_device.h> ++#include <linux/leds.h> ++#include <mach/hardware.h> ++#include <asm/mach-types.h> ++#include <plat/pwm.h> ++#include <mach/gta01.h> ++#include <plat/regs-timer.h> ++#include <linux/neo1973_vibrator.h> ++ ++#include <asm/plat-s3c24xx/neo1973.h> ++ ++#define COUNTER 64 ++ ++static struct neo1973_vib_priv { ++ struct led_classdev cdev; ++ unsigned int gpio; ++ spinlock_t lock; ++ unsigned int has_pwm; ++ struct s3c2410_pwm pwm; ++ ++ unsigned long vib_gpio_pin; /* which pin to meddle with */ ++ u8 vib_pwm; /* 0 = OFF -- will ensure GPIO deasserted and stop FIQ */ ++ u8 vib_pwm_latched; ++ u32 fiq_count; ++ ++ struct neo1973_vib_platform_data *pdata; ++} neo1973_vib_priv; ++ ++int neo1973_vibrator_fiq_handler(void) ++{ ++ neo1973_vib_priv.fiq_count++; ++ ++ if (!neo1973_vib_priv.vib_pwm_latched && !neo1973_vib_priv.vib_pwm) ++ /* idle */ ++ return 0; ++ ++ if ((u8)neo1973_vib_priv.fiq_count == neo1973_vib_priv.vib_pwm_latched) ++ neo1973_gpb_setpin(neo1973_vib_priv.vib_gpio_pin, 0); ++ ++ if ((u8)neo1973_vib_priv.fiq_count) ++ return 1; ++ ++ neo1973_vib_priv.vib_pwm_latched = neo1973_vib_priv.vib_pwm; ++ if (neo1973_vib_priv.vib_pwm_latched) ++ neo1973_gpb_setpin(neo1973_vib_priv.vib_gpio_pin, 1); ++ ++ return 1; ++} ++ ++static void neo1973_vib_vib_set(struct led_classdev *led_cdev, ++ enum led_brightness value) ++{ ++ unsigned long flags; ++ struct neo1973_vib_priv *vp = container_of(led_cdev, ++ struct neo1973_vib_priv, ++ cdev); ++ ++#ifdef CONFIG_MACH_NEO1973_GTA02 ++ if (machine_is_neo1973_gta02()) { /* use FIQ to control GPIO */ ++ neo1973_vib_priv.vib_pwm = value; /* set it for FIQ */ ++ neo1973_vib_priv.pdata->kick_fiq(); /* start up FIQs if not already going */ ++ return; ++ } ++#endif ++ /* ++ * value == 255 -> 99% duty cycle (full power) ++ * value == 128 -> 50% duty cycle (medium power) ++ * value == 0 -> 0% duty cycle (zero power) ++ */ ++ spin_lock_irqsave(&vp->lock, flags); ++ ++ if (vp->has_pwm) ++ s3c2410_pwm_duty_cycle(value / 4, &vp->pwm); ++ else ++ neo1973_gpb_setpin(vp->gpio, value ? 1 : 0); ++ ++ spin_unlock_irqrestore(&vp->lock, flags); ++} ++ ++static struct neo1973_vib_priv neo1973_vib_led = { ++ .cdev = { ++ .name = "neo1973:vibrator", ++ .brightness_set = neo1973_vib_vib_set, ++ }, ++}; ++ ++static int neo1973_vib_init_hw(struct neo1973_vib_priv *vp) ++{ ++ int rc; ++ ++ rc = s3c2410_pwm_init(&vp->pwm); ++ if (rc) ++ return rc; ++ ++ vp->pwm.timerid = PWM3; ++ /* use same prescaler as arch/arm/plat-s3c24xx/time.c */ ++ vp->pwm.prescaler = (6 - 1) / 2; ++ vp->pwm.divider = S3C2410_TCFG1_MUX3_DIV2; ++ vp->pwm.counter = COUNTER; ++ vp->pwm.comparer = COUNTER; ++ ++ rc = s3c2410_pwm_enable(&vp->pwm); ++ if (rc) ++ return rc; ++ ++ s3c2410_pwm_start(&vp->pwm); ++ ++ return 0; ++} ++ ++#ifdef CONFIG_PM ++static int neo1973_vib_suspend(struct platform_device *dev, pm_message_t state) ++{ ++ led_classdev_suspend(&neo1973_vib_led.cdev); ++ if (neo1973_vib_priv.pdata) ++ neo1973_vib_priv.pdata->disable_fiq(); ++ return 0; ++} ++ ++static int neo1973_vib_resume(struct platform_device *dev) ++{ ++ struct neo1973_vib_priv *vp = platform_get_drvdata(dev); ++ ++ if (vp->has_pwm) ++ neo1973_vib_init_hw(vp); ++ ++ led_classdev_resume(&neo1973_vib_led.cdev); ++ if (neo1973_vib_priv.pdata) ++ neo1973_vib_priv.pdata->enable_fiq(); ++ ++ return 0; ++} ++#endif /* CONFIG_PM */ ++ ++static int __init neo1973_vib_probe(struct platform_device *pdev) ++{ ++ struct resource *r; ++ int rc; ++ ++ if (!machine_is_neo1973_gta01() && !machine_is_neo1973_gta02()) ++ return -EIO; ++ ++ r = platform_get_resource(pdev, 0, 0); ++ if (!r || !r->start) ++ return -EIO; ++ ++ neo1973_vib_led.gpio = r->start; ++ ++ neo1973_vib_priv.pdata = pdev->dev.platform_data; ++ platform_set_drvdata(pdev, &neo1973_vib_led); ++ ++#ifdef CONFIG_MACH_NEO1973_GTA02 ++ if (machine_is_neo1973_gta02()) { /* use FIQ to control GPIO */ ++ neo1973_gpb_setpin(neo1973_vib_led.gpio, 0); /* off */ ++ s3c2410_gpio_cfgpin(neo1973_vib_led.gpio, S3C2410_GPIO_OUTPUT); ++ /* safe, kmalloc'd copy needed for FIQ ISR */ ++ neo1973_vib_priv.vib_gpio_pin = neo1973_vib_led.gpio; ++ neo1973_vib_priv.vib_pwm = 0; /* off */ ++ goto configured; ++ } ++#endif ++ ++ /* TOUT3 */ ++ if (neo1973_vib_led.gpio == S3C2410_GPB3) { ++ rc = neo1973_vib_init_hw(&neo1973_vib_led); ++ if (rc) ++ return rc; ++ ++ s3c2410_pwm_duty_cycle(0, &neo1973_vib_led.pwm); ++ s3c2410_gpio_cfgpin(neo1973_vib_led.gpio, S3C2410_GPB3_TOUT3); ++ neo1973_vib_led.has_pwm = 1; ++ } ++#ifdef CONFIG_MACH_NEO1973_GTA02 ++configured: ++#endif ++ spin_lock_init(&neo1973_vib_led.lock); ++ ++ return led_classdev_register(&pdev->dev, &neo1973_vib_led.cdev); ++} ++ ++static int neo1973_vib_remove(struct platform_device *pdev) ++{ ++#ifdef CONFIG_MACH_NEO1973_GTA02 ++ if (machine_is_neo1973_gta02()) /* use FIQ to control GPIO */ ++ neo1973_vib_priv.vib_pwm = 0; /* off */ ++ /* would only need kick if already off so no kick needed */ ++#endif ++ ++ if (neo1973_vib_led.has_pwm) ++ s3c2410_pwm_disable(&neo1973_vib_led.pwm); ++ ++ led_classdev_unregister(&neo1973_vib_led.cdev); ++ ++ return 0; ++} ++ ++static struct platform_driver neo1973_vib_driver = { ++ .probe = neo1973_vib_probe, ++ .remove = neo1973_vib_remove, ++#ifdef CONFIG_PM ++ .suspend = neo1973_vib_suspend, ++ .resume = neo1973_vib_resume, ++#endif ++ .driver = { ++ .name = "neo1973-vibrator", ++ }, ++}; ++ ++static int __init neo1973_vib_init(void) ++{ ++ return platform_driver_register(&neo1973_vib_driver); ++} ++ ++static void __exit neo1973_vib_exit(void) ++{ ++ platform_driver_unregister(&neo1973_vib_driver); ++} ++ ++module_init(neo1973_vib_init); ++module_exit(neo1973_vib_exit); ++ ++MODULE_AUTHOR("Harald Welte <laforge@openmoko.org>"); ++MODULE_DESCRIPTION("Openmoko GTA01/GTA02 vibrator driver"); ++MODULE_LICENSE("GPL"); +diff -ruN --exclude='*.orig' --exclude='*.rej' linux-2.6.29-rc3.owrt/drivers/leds/Makefile linux-2.6.29-rc3.owrt.om/drivers/leds/Makefile +--- linux-2.6.29-rc3.owrt/drivers/leds/Makefile 2009-05-10 22:04:48.000000000 +0200 ++++ linux-2.6.29-rc3.owrt.om/drivers/leds/Makefile 2009-05-10 22:27:59.000000000 +0200 +@@ -24,11 +24,15 @@ + obj-$(CONFIG_LEDS_PCA955X) += leds-pca955x.o + obj-$(CONFIG_LEDS_DA903X) += leds-da903x.o + obj-$(CONFIG_LEDS_WM8350) += leds-wm8350.o ++obj-$(CONFIG_LEDS_NEO1973_VIBRATOR) += leds-neo1973-vibrator.o ++obj-$(CONFIG_LEDS_NEO1973_GTA02) += leds-neo1973-gta02.o ++obj-$(CONFIG_LEDS_LP5521) += leds-lp5521.o + + # LED Triggers + obj-$(CONFIG_LEDS_TRIGGER_TIMER) += ledtrig-timer.o + obj-$(CONFIG_LEDS_TRIGGER_IDE_DISK) += ledtrig-ide-disk.o + obj-$(CONFIG_LEDS_TRIGGER_HEARTBEAT) += ledtrig-heartbeat.o ++obj-$(CONFIG_LEDS_TRIGGER_NETDEV) += ledtrig-netdev.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 +diff -ruN --exclude='*.orig' --exclude='*.rej' linux-2.6.29-rc3.owrt/drivers/Makefile linux-2.6.29-rc3.owrt.om/drivers/Makefile +--- linux-2.6.29-rc3.owrt/drivers/Makefile 2009-05-10 22:04:49.000000000 +0200 ++++ linux-2.6.29-rc3.owrt.om/drivers/Makefile 2009-05-10 22:27:59.000000000 +0200 +@@ -90,6 +90,7 @@ + obj-y += idle/ + obj-$(CONFIG_MMC) += mmc/ + obj-$(CONFIG_MEMSTICK) += memstick/ ++obj-$(CONFIG_AR6000_WLAN) += ar6000/ + obj-$(CONFIG_NEW_LEDS) += leds/ + obj-$(CONFIG_INFINIBAND) += infiniband/ + obj-$(CONFIG_SGI_SN) += sn/ +diff -ruN --exclude='*.orig' --exclude='*.rej' linux-2.6.29-rc3.owrt/drivers/media/video/Kconfig linux-2.6.29-rc3.owrt.om/drivers/media/video/Kconfig +--- linux-2.6.29-rc3.owrt/drivers/media/video/Kconfig 2009-05-10 22:04:49.000000000 +0200 ++++ linux-2.6.29-rc3.owrt.om/drivers/media/video/Kconfig 2009-05-10 22:27:59.000000000 +0200 +@@ -711,6 +711,25 @@ + CMOS camera controller. This is the controller found on first- + generation OLPC systems. + ++config VIDEO_SAMSUNG ++ bool "S3C SMDK CAMERA support" ++ depends on VIDEO_V4L2 ++ ++ default n ++ ---help--- ++ TBA ++ ++choice ++depends on VIDEO_SAMSUNG ++prompt "Select CIS module type" ++default VIDEO_SAMSUNG_S5K3BA ++ ++config VIDEO_SAMSUNG_S5K4BA ++ bool "S5K4BA (2.0M CIS module, 1600x1200)" ++ ---help--- ++ TBA ++endchoice ++ + config SOC_CAMERA + tristate "SoC camera support" + depends on VIDEO_V4L2 && HAS_DMA +diff -ruN --exclude='*.orig' --exclude='*.rej' linux-2.6.29-rc3.owrt/drivers/media/video/Makefile linux-2.6.29-rc3.owrt.om/drivers/media/video/Makefile +--- linux-2.6.29-rc3.owrt/drivers/media/video/Makefile 2009-05-10 22:04:49.000000000 +0200 ++++ linux-2.6.29-rc3.owrt.om/drivers/media/video/Makefile 2009-05-10 22:27:59.000000000 +0200 +@@ -134,6 +134,8 @@ + obj-$(CONFIG_VIDEO_VIVI) += vivi.o + obj-$(CONFIG_VIDEO_CX23885) += cx23885/ + ++obj-$(CONFIG_VIDEO_SAMSUNG) += s3c_camera_driver.o s3c_camif.o samsung/ ++ + obj-$(CONFIG_VIDEO_PXA27x) += pxa_camera.o + obj-$(CONFIG_VIDEO_SH_MOBILE_CEU) += sh_mobile_ceu_camera.o + obj-$(CONFIG_VIDEO_OMAP2) += omap2cam.o +diff -ruN --exclude='*.orig' --exclude='*.rej' linux-2.6.29-rc3.owrt/drivers/media/video/s3c_camera_driver.c linux-2.6.29-rc3.owrt.om/drivers/media/video/s3c_camera_driver.c +--- linux-2.6.29-rc3.owrt/drivers/media/video/s3c_camera_driver.c 1970-01-01 01:00:00.000000000 +0100 ++++ linux-2.6.29-rc3.owrt.om/drivers/media/video/s3c_camera_driver.c 2009-05-10 22:27:59.000000000 +0200 +@@ -0,0 +1,1943 @@ ++/* drivers/media/video/s3c_camera_driver.c ++ * ++ * Copyright (c) 2008 Samsung Electronics ++ * ++ * Samsung S3C Camera driver ++ * ++ * 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, MA 02111-1307 USA ++ */ ++ ++#include <linux/version.h> ++#include <linux/module.h> ++#include <linux/delay.h> ++#include <linux/errno.h> ++#include <linux/fs.h> ++#include <linux/kernel.h> ++#include <linux/major.h> ++#include <linux/slab.h> ++#include <linux/poll.h> ++#include <linux/signal.h> ++#include <linux/ioport.h> ++#include <linux/sched.h> ++#include <linux/types.h> ++#include <linux/interrupt.h> ++#include <linux/kmod.h> ++#include <linux/vmalloc.h> ++#include <linux/init.h> ++#include <linux/irq.h> ++#include <linux/mm.h> ++#include <linux/videodev2.h> ++#include <linux/platform_device.h> ++#include <linux/clk.h> ++#include <linux/semaphore.h> ++#include <asm/io.h> ++#include <asm/page.h> ++#include <plat/regs-gpio.h> ++#include <plat/regs-camif.h> ++#include <media/v4l2-dev.h> ++#include <media/v4l2-ioctl.h> ++#include "s3c_camif.h" ++#include "videodev2_s3c.h" ++ ++#include <linux/mfd/pcf50633/core.h> /* @@@ hack - WA */ ++#include <plat/gpio-bank-f.h> ++#include <plat/gpio-cfg.h> ++#include <mach/gpio.h> ++#include <mach/map.h> ++#include <plat/regs-sys.h> ++#include <plat/regs-syscon-power.h> ++ ++ ++static struct clk *cam_clock; ++camif_cfg_t s3c_fimc[CAMIF_DEV_NUM]; ++extern camif_cis_t msdma_input; ++extern int s3c_camif_do_postprocess(camif_cfg_t *cfg); ++ ++/************************************************************************* ++ * Utility part ++ ************************************************************************/ ++camif_cfg_t *s3c_camif_get_fimc_object(int nr) ++{ ++ camif_cfg_t *ret = NULL; ++ ++ switch (nr) { ++ case CODEC_MINOR: ++ ret = &s3c_fimc[FIMC_CODEC_INDEX]; ++ break; ++ ++ case PREVIEW_MINOR: ++ ret = &s3c_fimc[FIMC_PREVIEW_INDEX]; ++ break; ++ ++ default: ++ printk(KERN_ERR "Unknown minor number\n"); ++ ret = &s3c_fimc[FIMC_PREVIEW_INDEX]; ++ } ++ ++ return ret; ++} ++ ++#if defined(FSM_ON_PREVIEW) ++static int s3c_camif_check_global_status(camif_cfg_t *cfg) ++{ ++ int ret = 0; ++ ++ if (down_interruptible(&cfg->cis->lock)) ++ return -ERESTARTSYS; ++ ++ if (cfg->cis->status & CWANT2START) { ++ cfg->cis->status &= ~CWANT2START; ++ cfg->auto_restart = 1; ++ ret = 1; ++ } else { ++ ret = 0; /* There is no codec */ ++ cfg->auto_restart = 0; /* Duplicated ..Dummy */ ++ } ++ ++ up(&cfg->cis->lock); ++ ++ return ret; ++} ++#endif ++ ++static int s3c_camif_convert_format(int pixfmt, int *fmtptr) ++{ ++ int fmt = CAMIF_YCBCR420; ++ int depth = 12; ++ ++ switch (pixfmt) { ++ case V4L2_PIX_FMT_RGB565: ++ case V4L2_PIX_FMT_RGB565X: ++ fmt = CAMIF_RGB16; ++ depth = 16; ++ break; ++ ++ case V4L2_PIX_FMT_BGR24: /* Not tested */ ++ case V4L2_PIX_FMT_RGB24: ++ fmt = CAMIF_RGB24; ++ depth = 24; ++ break; ++ ++ case V4L2_PIX_FMT_BGR32: ++ case V4L2_PIX_FMT_RGB32: ++ fmt = CAMIF_RGB24; ++ depth = 32; ++ break; ++ ++ case V4L2_PIX_FMT_GREY: /* Not tested */ ++ fmt = CAMIF_YCBCR420; ++ depth = 8; ++ break; ++ ++ case V4L2_PIX_FMT_YUYV: ++ case V4L2_PIX_FMT_UYVY: ++ fmt = CAMIF_YCBCR422I; ++ depth = 16; ++ break; ++ ++ case V4L2_PIX_FMT_YUV422P: ++ fmt = CAMIF_YCBCR422; ++ depth = 16; ++ break; ++ ++ case V4L2_PIX_FMT_YUV420: ++ fmt = CAMIF_YCBCR420; ++ depth = 12; ++ break; ++ } ++ ++ if (fmtptr) ++ *fmtptr = fmt; ++ ++ return depth; ++} ++ ++static int s3c_camif_set_fb_info(camif_cfg_t *cfg, int depth, int fourcc) ++{ ++ /* To define v4l2_format used currently */ ++ cfg->v2.frmbuf.fmt.width = cfg->target_x; ++ cfg->v2.frmbuf.fmt.height = cfg->target_y; ++ cfg->v2.frmbuf.fmt.field = V4L2_FIELD_NONE; ++ cfg->v2.frmbuf.fmt.pixelformat = fourcc; ++ cfg->v2.frmbuf.fmt.bytesperline = cfg->v2.frmbuf.fmt.width * depth >> 3; ++ cfg->v2.frmbuf.fmt.sizeimage = ++ cfg->v2.frmbuf.fmt.height * cfg->v2.frmbuf.fmt.bytesperline; ++ ++ return 0; ++} ++ ++static int s3c_camif_convert_type(camif_cfg_t *cfg, int f) ++{ ++ int pixfmt; ++ ++ cfg->target_x = cfg->v2.frmbuf.fmt.width; ++ cfg->target_y = cfg->v2.frmbuf.fmt.height; ++ ++ s3c_camif_convert_format(cfg->v2.frmbuf.fmt.pixelformat, &pixfmt); ++ ++ cfg->dst_fmt = pixfmt; ++ ++ return 0; ++} ++ ++/************************************************************************* ++ * Control part ++ ************************************************************************/ ++static int s3c_camif_start_capture(camif_cfg_t * cfg) ++{ ++ int ret = 0; ++ ++ cfg->capture_enable = CAMIF_DMA_ON; ++ ++ s3c_camif_start_dma(cfg); ++ ++ cfg->status = CAMIF_STARTED; ++ ++ if (!(cfg->fsm == CAMIF_SET_LAST_INT || ++ cfg->fsm == CAMIF_CONTINUOUS_INT)) { ++ cfg->fsm = CAMIF_DUMMY_INT; ++ cfg->perf.frames = 0; ++ } ++ ++#if defined(CONFIG_CPU_S3C6400) || defined(CONFIG_CPU_S3C6410) ++ if (cfg->input_channel == MSDMA_FROM_CODEC) ++ s3c_camif_start_codec_msdma(cfg); ++#endif ++ return ret; ++} ++ ++ssize_t s3c_camif_start_preview(camif_cfg_t *cfg) ++{ ++ cfg->capture_enable = CAMIF_DMA_ON; ++ ++ s3c_camif_start_dma(cfg); ++ ++ cfg->status = CAMIF_STARTED; ++ cfg->fsm = CAMIF_1st_INT; ++ cfg->perf.frames = 0; ++ ++ return 0; ++} ++ ++ssize_t s3c_camif_stop_preview(camif_cfg_t *cfg) ++{ ++ cfg->capture_enable = CAMIF_DMA_OFF; ++ cfg->status = CAMIF_STOPPED; ++ ++ s3c_camif_stop_dma(cfg); ++ ++ cfg->perf.frames = 0; ++ ++ return 0; ++} ++ ++ssize_t s3c_camif_stop_capture(camif_cfg_t *cfg) ++{ ++ cfg->capture_enable = CAMIF_DMA_OFF; ++ cfg->status = CAMIF_STOPPED; ++ ++ s3c_camif_stop_dma(cfg); ++ ++ cfg->perf.frames = 0; ++ ++ return 0; ++} ++ ++ssize_t s3c_camif_stop_fimc(camif_cfg_t *cfg) ++{ ++ cfg->capture_enable = CAMIF_BOTH_DMA_OFF; ++ cfg->fsm = CAMIF_DUMMY_INT; ++ cfg->perf.frames = 0; ++ ++ s3c_camif_stop_dma(cfg); ++ ++ return 0; ++} ++ ++#if defined(FSM_ON_PREVIEW) ++static void s3c_camif_start_preview_with_codec(camif_cfg_t *cfg) ++{ ++ camif_cfg_t *other = cfg->other; ++ ++ /* Preview Stop */ ++ cfg->capture_enable = CAMIF_DMA_OFF; ++ s3c_camif_stop_dma(cfg); ++ ++ /* Start Preview and CODEC */ ++ cfg->capture_enable =CAMIF_BOTH_DMA_ON; ++ ++ s3c_camif_start_dma(cfg); ++ cfg->fsm = CAMIF_1st_INT; /* For Preview */ ++ ++ if (!other) ++ panic("Unexpected error: other is null\n"); ++ ++ switch (other->pp_num) { ++ case 4: ++ other->fsm = CAMIF_1st_INT; /* For CODEC */ ++ break; ++ ++ case 1: ++ other->fsm = CAMIF_Yth_INT; ++ break; ++ ++ default: ++ panic("Invalid pingpong number"); ++ break; ++ } ++} ++ ++static void s3c_camif_auto_restart(camif_cfg_t *cfg) ++{ ++ if (cfg->auto_restart) ++ s3c_camif_start_preview_with_codec(cfg); ++} ++#endif ++ ++static void s3c_camif_change_mode(camif_cfg_t *cfg, int mode) ++{ ++ camif_cis_t *cis = cfg->cis; ++ int res; ++ ++ if (mode == SENSOR_MAX) { ++#if defined(CONFIG_VIDEO_SAMSUNG_S5K3AA) ++ res = SENSOR_SXGA; ++#elif defined(CONFIG_VIDEO_SAMSUNG_S5K3BA) ++ res = SENSOR_UXGA; ++ ++/* 4BA max is UXGA, but we don't have UXGA control values */ ++#elif defined(CONFIG_VIDEO_SAMSUNG_S5K4BA) ++ res = SENSOR_SVGA; ++#endif ++ } else if (mode == SENSOR_DEFAULT) { ++#if defined(CONFIG_VIDEO_SAMSUNG_S5K4BA) ++ res = SENSOR_SVGA; ++#else ++ res = SENSOR_VGA; ++#endif ++ } else ++ res = mode; ++ ++ s3c_camif_stop_fimc(cfg); ++ ++ switch (res) { ++ case SENSOR_SXGA: ++ printk(KERN_INFO ++ "Resolution changed into SXGA (1280x1024) mode -> 1.3M\n"); ++ cis->sensor->driver->command(cis->sensor, SENSOR_SXGA, NULL); ++ cis->source_x = 1280; ++ cis->source_y = 1024; ++ break; ++ ++ case SENSOR_UXGA: ++ printk(KERN_INFO ++ "Resolution changed into UXGA (1600x1200) mode -> 2.0M\n"); ++ cis->sensor->driver->command(cis->sensor, SENSOR_UXGA, NULL); ++ cis->source_x = 1600; ++ cis->source_y = 1200; ++ break; ++ ++ case SENSOR_SVGA: ++ printk(KERN_INFO ++ "Resolution changed back to SVGA (800x600) mode\n"); ++ cis->sensor->driver->command(cis->sensor, SENSOR_SVGA, NULL); ++ cis->source_x = 800; ++ cis->source_y = 600; ++ break; ++ ++ case SENSOR_VGA: ++ printk(KERN_INFO "Resolution changed back to VGA (640x480) " ++ "mode (default)\n"); ++ cis->sensor->driver->command(cis->sensor, SENSOR_VGA, NULL); ++ cis->source_x = 640; ++ cis->source_y = 480; ++ break; ++ } ++ ++ cis->win_hor_ofst = cis->win_hor_ofst2 = 0; ++ cis->win_ver_ofst = cis->win_ver_ofst2 = 0; ++ ++ s3c_camif_set_source_format(cis); ++} ++ ++static int s3c_camif_check_zoom_range(camif_cfg_t *cfg, int type) ++{ ++ switch (type) { ++ case V4L2_CID_ZOOMIN: ++ if (((cfg->sc.modified_src_x - (cfg->cis->win_hor_ofst + ++ ZOOM_AT_A_TIME_IN_PIXELS + cfg->cis->win_hor_ofst2 + ++ ZOOM_AT_A_TIME_IN_PIXELS)) / cfg->sc.prehratio) > ++ ZOOM_IN_MAX) { ++ printk(KERN_INFO "Invalid Zoom-in: this zoom-in on " ++ "preview scaler already comes to the maximum\n"); ++ return 0; ++ } ++ ++ cfg->sc.zoom_in_cnt++; ++ break; ++ ++ case V4L2_CID_ZOOMOUT: ++ if (cfg->sc.zoom_in_cnt > 0) { ++ cfg->sc.zoom_in_cnt--; ++ } else { ++ printk(KERN_INFO "Invalid Zoom-out: this zoom-out on " ++ "preview scaler already comes to the minimum\n"); ++ return 0; ++ } ++ ++ break; ++ ++ default: ++ break; ++ } ++ ++ return 1; ++} ++ ++static int s3c_camif_restart_preview(camif_cfg_t *cfg) ++{ ++ int ret = 0; ++ ++ s3c_camif_stop_preview(cfg); ++ ++ if (s3c_camif_control_fimc(cfg)) { ++ printk(KERN_ERR "S3C fimc control failed\n"); ++ ret = -1; ++ } ++ ++ s3c_camif_start_preview(cfg); ++ ++ return ret; ++} ++ ++static int s3c_camif_send_sensor_command(camif_cfg_t *cfg, unsigned int cmd, ++ int arg) ++{ ++ cfg->cis->sensor->driver->command(cfg->cis->sensor, cmd, (void *) arg); ++ ++ return 0; ++} ++ ++/************************************************************************* ++ * V4L2 part ++ ************************************************************************/ ++static int s3c_camif_v4l2_querycap(camif_cfg_t *cfg, void *arg) ++{ ++ struct v4l2_capability *cap = arg; ++ ++ strcpy(cap->driver, "S3C FIMC Camera driver"); ++ strlcpy(cap->card, cfg->v->name, sizeof(cap->card)); ++ sprintf(cap->bus_info, "FIMC AHB Bus"); ++ ++ cap->version = 0; ++ cap->capabilities = V4L2_CAP_VIDEO_OVERLAY | V4L2_CAP_VIDEO_CAPTURE | ++ V4L2_CAP_STREAMING; ++ ++ return 0; ++} ++ ++static int s3c_camif_v4l2_g_fbuf(camif_cfg_t *cfg, void *arg) ++{ ++ struct v4l2_framebuffer *fb = arg; ++ ++ *fb = cfg->v2.frmbuf; ++ ++ fb->base = cfg->v2.frmbuf.base; ++ fb->capability = V4L2_FBUF_CAP_LIST_CLIPPING; ++ ++ fb->fmt.pixelformat = cfg->v2.frmbuf.fmt.pixelformat; ++ fb->fmt.width = cfg->v2.frmbuf.fmt.width; ++ fb->fmt.height = cfg->v2.frmbuf.fmt.height; ++ fb->fmt.bytesperline = cfg->v2.frmbuf.fmt.bytesperline; ++ ++ return 0; ++} ++ ++static int s3c_camif_v4l2_s_fbuf(camif_cfg_t *cfg, void *arg) ++{ ++ struct v4l2_framebuffer *fb = arg; ++ int i, depth; ++ ++ for (i = 0; i < NUMBER_OF_PREVIEW_FORMATS; i++) ++ if (fimc_preview_formats[i].pixelformat == fb->fmt.pixelformat) ++ break; ++ ++ if (i == NUMBER_OF_PREVIEW_FORMATS) ++ return -EINVAL; ++ ++ cfg->v2.frmbuf.base = fb->base; ++ cfg->v2.frmbuf.flags = fb->flags; ++ cfg->v2.frmbuf.capability = fb->capability; ++ ++ cfg->target_x = fb->fmt.width; ++ cfg->target_y = fb->fmt.height; ++ ++ depth = s3c_camif_convert_format(fb->fmt.pixelformat, ++ (int *) &cfg->dst_fmt); ++ s3c_camif_set_fb_info(cfg, depth, fb->fmt.pixelformat); ++ ++ return s3c_camif_control_fimc(cfg); ++} ++ ++static int s3c_camif_v4l2_g_fmt(camif_cfg_t *cfg, void *arg) ++{ ++ struct v4l2_format *f = arg; ++ int size = sizeof(struct v4l2_pix_format); ++ int ret = -1; ++ ++ switch (f->type) { ++ case V4L2_BUF_TYPE_VIDEO_CAPTURE: ++ memset(&f->fmt.pix, 0, size); ++ memcpy(&f->fmt.pix, &cfg->v2.frmbuf.fmt, size); ++ ret = 0; ++ break; ++ ++ default: ++ break; ++ } ++ ++ return ret; ++} ++ ++static int s3c_camif_v4l2_s_fmt(camif_cfg_t *cfg, void *arg) ++{ ++ struct v4l2_format *f = arg; ++ int ret = -1; ++ ++ switch (f->type) { ++ case V4L2_BUF_TYPE_VIDEO_CAPTURE: ++ cfg->v2.frmbuf.fmt = f->fmt.pix; ++ cfg->v2.status |= CAMIF_v4L2_DIRTY; ++ cfg->v2.status &= ~CAMIF_v4L2_DIRTY; /* dummy ? */ ++ ++ s3c_camif_convert_type(cfg, 1); ++ s3c_camif_control_fimc(cfg); ++ ret = 0; ++ break; ++ ++ default: ++ break; ++ } ++ ++ return ret; ++} ++ ++static int s3c_camif_v4l2_enum_fmt(camif_cfg_t *cfg, void *arg) ++{ ++ struct v4l2_fmtdesc *f = arg; ++ int index = f->index; ++ ++ if (index >= NUMBER_OF_CODEC_FORMATS) ++ return -EINVAL; ++ ++ switch (f->type) { ++ case V4L2_BUF_TYPE_VIDEO_CAPTURE: ++ break; ++ ++ case V4L2_BUF_TYPE_VIDEO_OVERLAY: ++ default: ++ return -EINVAL; ++ } ++ ++ memset(f, 0, sizeof(*f)); ++ memcpy(f, cfg->v2.fmtdesc + index, sizeof(*f)); ++ ++ return 0; ++} ++ ++static int s3c_camif_v4l2_overlay(camif_cfg_t *cfg, void *arg) ++{ ++ int on = *(int *) arg; ++ ++ if (on) ++ return s3c_camif_start_preview(cfg); ++ else ++ return s3c_camif_stop_preview(cfg); ++} ++ ++static int s3c_camif_v4l2_g_ctrl(camif_cfg_t *cfg, void *arg) ++{ ++ return 0; ++} ++ ++static int s3c_camif_v4l2_s_ctrl(camif_cfg_t *cfg, void *arg) ++{ ++ struct v4l2_control *ctrl = arg; ++ ++ switch (ctrl->id) { ++ case V4L2_CID_ORIGINAL: ++ case V4L2_CID_ARBITRARY: ++ case V4L2_CID_NEGATIVE: ++ case V4L2_CID_EMBOSSING: ++ case V4L2_CID_ART_FREEZE: ++ case V4L2_CID_SILHOUETTE: ++ cfg->effect = ctrl->value; ++ s3c_camif_change_effect(cfg); ++ break; ++ ++ case V4L2_CID_HFLIP: ++ cfg->flip = CAMIF_FLIP_X; ++ s3c_camif_change_flip(cfg); ++ break; ++ ++ case V4L2_CID_VFLIP: ++ cfg->flip = CAMIF_FLIP_Y; ++ s3c_camif_change_flip(cfg); ++ break; ++ ++ case V4L2_CID_ROTATE_180: ++ cfg->flip = CAMIF_FLIP_MIRROR; ++ s3c_camif_change_flip(cfg); ++ break; ++ ++#if defined(CONFIG_CPU_S3C6400) || defined(CONFIG_CPU_S3C6410) ++ case V4L2_CID_ROTATE_90: ++ cfg->flip = CAMIF_ROTATE_90; ++ s3c_camif_change_flip(cfg); ++ break; ++ ++ case V4L2_CID_ROTATE_270: ++ cfg->flip = CAMIF_FLIP_ROTATE_270; ++ s3c_camif_change_flip(cfg); ++ break; ++#endif ++ ++ case V4L2_CID_ROTATE_BYPASS: ++ cfg->flip = CAMIF_FLIP; ++ s3c_camif_change_flip(cfg); ++ break; ++ ++ case V4L2_CID_ZOOMIN: ++ if (!s3c_camif_check_zoom_range(cfg, ctrl->id)) ++ break; ++ cfg->cis->win_hor_ofst += ZOOM_AT_A_TIME_IN_PIXELS; ++ cfg->cis->win_ver_ofst += ZOOM_AT_A_TIME_IN_PIXELS; ++ cfg->cis->win_hor_ofst2 += ZOOM_AT_A_TIME_IN_PIXELS; ++ cfg->cis->win_ver_ofst2 += ZOOM_AT_A_TIME_IN_PIXELS; ++ ++ s3c_camif_restart_preview(cfg); ++ ++ break; ++ ++ case V4L2_CID_ZOOMOUT: ++ if (!s3c_camif_check_zoom_range(cfg, ctrl->id)) ++ break; ++ cfg->cis->win_hor_ofst -= ZOOM_AT_A_TIME_IN_PIXELS; ++ cfg->cis->win_ver_ofst -= ZOOM_AT_A_TIME_IN_PIXELS; ++ cfg->cis->win_hor_ofst2 -= ZOOM_AT_A_TIME_IN_PIXELS; ++ cfg->cis->win_ver_ofst2 -= ZOOM_AT_A_TIME_IN_PIXELS; ++ ++ s3c_camif_restart_preview(cfg); ++ ++ break; ++ ++ case V4L2_CID_CONTRAST: ++ case V4L2_CID_AUTO_WHITE_BALANCE: ++ s3c_camif_send_sensor_command(cfg, SENSOR_WB, ++ ctrl->value); ++ break; ++ ++ default: ++ printk(KERN_ERR "Invalid control id: %d\n", ctrl->id); ++ return -1; ++ } ++ ++ return 0; ++} ++ ++static int s3c_camif_v4l2_streamon(camif_cfg_t *cfg, void *arg) ++{ ++ return s3c_camif_start_capture(cfg); ++} ++ ++static int s3c_camif_v4l2_streamoff(camif_cfg_t *cfg, void *arg) ++{ ++ cfg->cis->status &= ~C_WORKING; ++ ++ s3c_camif_stop_capture(cfg); ++ ++ return 0; ++} ++ ++static int s3c_camif_v4l2_g_input(camif_cfg_t *cfg, void *arg) ++{ ++ unsigned int *index = arg; ++ ++ *index = cfg->v2.input->index; ++ ++ return 0; ++} ++ ++static int s3c_camif_v4l2_s_input(camif_cfg_t *cfg, unsigned int index) ++{ ++ int ret = -1; ++ ++ if (index >= NUMBER_OF_INPUTS) ++ ret = -1; ++ else { ++ cfg->v2.input = &fimc_inputs[index]; ++ ++ if (cfg->v2.input->type == V4L2_INPUT_TYPE_MSDMA) { ++ if (cfg->dma_type & CAMIF_PREVIEW) { ++ cfg->input_channel = MSDMA_FROM_PREVIEW; ++ ret = 0; ++ } else if (cfg->dma_type & CAMIF_CODEC) { ++ cfg->input_channel = MSDMA_FROM_CODEC; ++ ret = 0; ++ } ++ } else { ++ cfg->input_channel = CAMERA_INPUT; ++ ret = 0; ++ } ++ } ++ ++ return ret; ++} ++ ++static int s3c_camif_v4l2_g_output(camif_cfg_t *cfg, void *arg) ++{ ++ unsigned int *index = arg; ++ ++ *index = cfg->v2.output->index; ++ ++ return 0; ++} ++ ++static int s3c_camif_v4l2_s_output(camif_cfg_t *cfg, unsigned int index) ++{ ++ if (index >= NUMBER_OF_OUTPUTS) ++ return -EINVAL; ++ else { ++ cfg->v2.output = (struct v4l2_output *) &fimc_outputs[index]; ++ return 0; ++ } ++} ++ ++static int s3c_camif_v4l2_enum_input(camif_cfg_t *cfg, void *arg) ++{ ++ struct v4l2_input *i = arg; ++ ++ if (i->index >= NUMBER_OF_INPUTS) ++ return -EINVAL; ++ ++ memcpy(i, &fimc_inputs[i->index], sizeof(struct v4l2_input)); ++ ++ return 0; ++} ++ ++static int s3c_camif_v4l2_enum_output(camif_cfg_t *cfg, void *arg) ++{ ++ struct v4l2_output *i = arg; ++ ++ if (i->index >= NUMBER_OF_OUTPUTS) ++ return -EINVAL; ++ ++ memcpy(i, &fimc_outputs[i->index], sizeof(struct v4l2_output)); ++ ++ return 0; ++} ++ ++static int s3c_camif_v4l2_reqbufs(camif_cfg_t *cfg, void *arg) ++{ ++ struct v4l2_requestbuffers *req = arg; ++ ++ if (req->memory != V4L2_MEMORY_MMAP) { ++ printk(KERN_ERR "Only V4L2_MEMORY_MMAP capture is supported\n"); ++ return -EINVAL; ++ } ++ ++ /* control user input */ ++ if (req->count > 2) ++ req->count = 4; ++ else if (req->count > 1) ++ req->count = 2; ++ else ++ req->count = 1; ++ ++ return 0; ++} ++ ++static int s3c_camif_v4l2_querybuf(camif_cfg_t *cfg, void *arg) ++{ ++ struct v4l2_buffer *buf = arg; ++ ++ if (buf->type != V4L2_BUF_TYPE_VIDEO_CAPTURE && ++ buf->memory != V4L2_MEMORY_MMAP) ++ return -1; ++ ++ buf->length = cfg->buffer_size; ++ buf->m.offset = buf->length * buf->index; ++ ++ return 0; ++} ++ ++static int s3c_camif_v4l2_qbuf(camif_cfg_t *cfg, void *arg) ++{ ++ return 0; ++} ++ ++static int s3c_camif_v4l2_dqbuf(camif_cfg_t *cfg, void *arg) ++{ ++ struct v4l2_buffer *buf = arg; ++ ++ buf->index = cfg->cur_frame_num % cfg->pp_num; ++ ++ return 0; ++} ++ ++/* ++ * S3C specific ++ */ ++static int s3c_camif_v4l2_s_msdma(camif_cfg_t *cfg, void *arg) ++{ ++ struct v4l2_msdma_format *f = arg; ++ int ret; ++ ++ switch(f->input_path) { ++ case V4L2_MSDMA_PREVIEW: ++ cfg->cis->user--; ++ /* CIS will be replaced with a CIS for MSDMA */ ++ ++ cfg->cis = &msdma_input; ++ cfg->cis->user++; ++ cfg->input_channel = MSDMA_FROM_PREVIEW; ++ break; ++ ++ case V4L2_MSDMA_CODEC: ++ cfg->cis->user--; ++ /* CIS will be replaced with a CIS for MSDMA */ ++ ++ cfg->cis = &msdma_input; ++ cfg->cis->user++; ++ cfg->input_channel = MSDMA_FROM_CODEC; ++ break; ++ ++ default: ++ cfg->input_channel = CAMERA_INPUT; ++ break; ++ } ++ ++ cfg->cis->source_x = f->width; ++ cfg->cis->source_y = f->height; ++ ++ s3c_camif_convert_format(f->pixelformat, (int *) &cfg->src_fmt); ++ ++ cfg->cis->win_hor_ofst = 0; ++ cfg->cis->win_ver_ofst = 0; ++ cfg->cis->win_hor_ofst2 = 0; ++ cfg->cis->win_ver_ofst2 = 0; ++ ++ ret = s3c_camif_control_fimc(cfg); ++ ++ switch(f->input_path) { ++ case V4L2_MSDMA_PREVIEW: ++ ret = s3c_camif_start_preview(cfg); ++ break; ++ ++ case V4L2_MSDMA_CODEC: ++ ret = s3c_camif_start_capture(cfg); ++ break; ++ ++ default: ++ break; ++ ++ } ++ ++ return ret; ++} ++ ++static int s3c_camif_v4l2_msdma_start(camif_cfg_t *cfg, void *arg) ++{ ++ if (cfg->input_channel == MSDMA_FROM_PREVIEW) { ++ cfg->msdma_status = 1; ++ s3c_camif_start_preview_msdma(cfg); ++ } ++ ++ return 0; ++} ++ ++static int s3c_camif_v4l2_msdma_stop(camif_cfg_t *cfg, void *arg) ++{ ++ struct v4l2_msdma_format *f = arg; ++ int ret = -1; ++ ++ cfg->cis->status &= ~C_WORKING; ++ cfg->msdma_status = 0; ++ ++ switch(f->input_path) { ++ case V4L2_MSDMA_PREVIEW: ++ ret = s3c_camif_stop_preview(cfg); ++ break; ++ ++ case V4L2_MSDMA_CODEC: ++ ret = s3c_camif_stop_capture(cfg); ++ break; ++ ++ default: ++ break; ++ } ++ ++ return ret; ++} ++ ++static int s3c_camif_v4l2_camera_start(camif_cfg_t *cfg, void *arg) ++{ ++ return 0; ++} ++ ++static int s3c_camif_v4l2_camera_stop(camif_cfg_t *cfg, void *arg) ++{ ++ return 0; ++} ++ ++static int s3c_camif_v4l2_cropcap(camif_cfg_t *cfg, void *arg) ++{ ++ struct v4l2_cropcap *cap = arg; ++ ++ if (cap->type != V4L2_BUF_TYPE_VIDEO_CAPTURE && ++ cap->type != V4L2_BUF_TYPE_VIDEO_OVERLAY) ++ return -EINVAL; ++ ++ /* crop limitations */ ++ cfg->v2.crop_bounds.left = 0; ++ cfg->v2.crop_bounds.top = 0; ++ cfg->v2.crop_bounds.width = cfg->cis->source_x; ++ cfg->v2.crop_bounds.height = cfg->cis->source_y; ++ ++ /* crop default values */ ++ cfg->v2.crop_defrect.left = ++ (cfg->cis->source_x - CROP_DEFAULT_WIDTH) / 2; ++ cfg->v2.crop_defrect.top = ++ (cfg->cis->source_y - CROP_DEFAULT_HEIGHT) / 2; ++ cfg->v2.crop_defrect.width = CROP_DEFAULT_WIDTH; ++ cfg->v2.crop_defrect.height = CROP_DEFAULT_HEIGHT; ++ ++ cap->bounds = cfg->v2.crop_bounds; ++ cap->defrect = cfg->v2.crop_defrect; ++ ++ return 0; ++} ++ ++static int s3c_camif_v4l2_g_crop(camif_cfg_t *cfg, void *arg) ++{ ++ struct v4l2_crop *crop = arg; ++ ++ if (crop->type != V4L2_BUF_TYPE_VIDEO_CAPTURE && ++ crop->type != V4L2_BUF_TYPE_VIDEO_OVERLAY) ++ return -EINVAL; ++ ++ crop->c = cfg->v2.crop_current; ++ ++ return 0; ++} ++ ++static int s3c_camif_v4l2_s_crop(camif_cfg_t *cfg, void *arg) ++{ ++ struct v4l2_crop *crop = arg; ++ ++ if (crop->type != V4L2_BUF_TYPE_VIDEO_CAPTURE && ++ crop->type != V4L2_BUF_TYPE_VIDEO_OVERLAY) ++ return -EINVAL; ++ ++ if (crop->c.height < 0) ++ return -EINVAL; ++ ++ if (crop->c.width < 0) ++ return -EINVAL; ++ ++ if ((crop->c.left + crop->c.width > cfg->cis->source_x) || ++ (crop->c.top + crop->c.height > cfg->cis->source_y)) ++ return -EINVAL; ++ ++ cfg->v2.crop_current = crop->c; ++ ++ cfg->cis->win_hor_ofst = (cfg->cis->source_x - crop->c.width) / 2; ++ cfg->cis->win_ver_ofst = (cfg->cis->source_y - crop->c.height) / 2; ++ ++ cfg->cis->win_hor_ofst2 = cfg->cis->win_hor_ofst; ++ cfg->cis->win_ver_ofst2 = cfg->cis->win_ver_ofst; ++ ++ s3c_camif_restart_preview(cfg); ++ ++ return 0; ++} ++ ++static int s3c_camif_v4l2_s_parm(camif_cfg_t *cfg, void *arg) ++{ ++ struct v4l2_streamparm *sp = arg; ++ ++ if (sp->type != V4L2_BUF_TYPE_VIDEO_CAPTURE) ++ return -EINVAL; ++ ++ if (sp->parm.capture.capturemode == V4L2_MODE_HIGHQUALITY) { ++ s3c_camif_change_mode(cfg, SENSOR_MAX); ++ s3c_camif_control_fimc(cfg); ++ } else { ++ s3c_camif_change_mode(cfg, SENSOR_DEFAULT); ++ s3c_camif_control_fimc(cfg); ++ } ++ ++ return 0; ++} ++ ++/************************************************************************* ++ * Interrupt part ++ ************************************************************************/ ++#if defined(FSM_ON_CODEC) && !defined(USE_LAST_IRQ) ++int s3c_camif_do_fsm_codec(camif_cfg_t *cfg) ++{ ++ cfg->perf.frames++; ++ ++ if (cfg->fsm == CAMIF_DUMMY_INT && ++ cfg->perf.frames > CAMIF_CAPTURE_SKIP_FRAMES) ++ cfg->fsm = CAMIF_NORMAL_INT; ++ ++ switch (cfg->fsm) { ++ case CAMIF_DUMMY_INT: ++ DPRINTK(KERN_INFO "CAMIF_DUMMY_INT: %d\n", cfg->perf.frames); ++ cfg->status = CAMIF_STARTED; ++ cfg->fsm = CAMIF_DUMMY_INT; ++ return INSTANT_SKIP; ++ ++ case CAMIF_NORMAL_INT: ++ DPRINTK(KERN_INFO "CAMIF_NORMAL_INT: %d\n", cfg->perf.frames); ++ cfg->status = CAMIF_INT_HAPPEN; ++ cfg->fsm = CAMIF_CONTINUOUS_INT; ++ return INSTANT_GO; ++ ++ case CAMIF_CONTINUOUS_INT: ++ DPRINTK(KERN_INFO "CAMIF_CONTINUOS_INT: %d\n", ++ cfg->perf.frames); ++ cfg->status = CAMIF_INT_HAPPEN; ++ cfg->fsm = CAMIF_CONTINUOUS_INT; ++ return INSTANT_GO; ++ ++ default: ++ printk(KERN_INFO "Unexpect INT: %d\n", cfg->fsm); ++ return INSTANT_SKIP; ++ } ++} ++#endif ++ ++#if defined(FSM_ON_CODEC) && defined(USE_LAST_IRQ) ++int s3c_camif_do_fsm_codec_lastirq(camif_cfg_t *cfg) ++{ ++ cfg->perf.frames++; ++ ++ if (cfg->fsm == CAMIF_DUMMY_INT && ++ cfg->perf.frames > CAMIF_CAPTURE_SKIP_FRAMES - 2) ++ cfg->fsm = CAMIF_SET_LAST_INT; ++ ++ switch (cfg->fsm) { ++ case CAMIF_DUMMY_INT: ++ DPRINTK(KERN_INFO "CAMIF_DUMMY_INT: %d\n", cfg->perf.frames); ++ cfg->status = CAMIF_STARTED; ++ cfg->fsm = CAMIF_DUMMY_INT; ++ return INSTANT_SKIP; ++ ++ case CAMIF_SET_LAST_INT: ++ DPRINTK(KERN_INFO "CAMIF_SET_LAST_INT: %d\n", cfg->perf.frames); ++ s3c_camif_enable_lastirq(cfg); ++ ++/* in 64xx, lastirq is not auto cleared. */ ++#if defined(CONFIG_CPU_S3C6400) || defined(CONFIG_CPU_S3C6410) ++ s3c_camif_disable_lastirq(cfg); ++#endif ++ cfg->status = CAMIF_INT_HAPPEN; ++ cfg->fsm = CAMIF_STOP_CAPTURE; ++ return INSTANT_SKIP; ++ ++ case CAMIF_STOP_CAPTURE: ++ DPRINTK(KERN_INFO "CAMIF_STOP_CAPTURE: %d\n", cfg->perf.frames); ++ cfg->capture_enable = CAMIF_DMA_OFF; ++ s3c_camif_stop_dma(cfg); ++ cfg->fsm = CAMIF_LAST_IRQ; ++ return INSTANT_SKIP; ++ ++ case CAMIF_LAST_IRQ: ++ DPRINTK(KERN_INFO "CAMIF_LAST_IRQ: %d\n", cfg->perf.frames); ++ cfg->fsm = CAMIF_SET_LAST_INT; ++ cfg->status = CAMIF_INT_HAPPEN; ++ return INSTANT_GO; ++ ++ default: ++ printk(KERN_INFO "Unexpect INT: %d\n", cfg->fsm); ++ return = INSTANT_SKIP; ++ } ++} ++#endif ++ ++#if defined(FSM_ON_PREVIEW) ++static int s3c_camif_do_lastirq_preview(camif_cfg_t *cfg) ++{ ++ cfg->perf.frames++; ++ ++ if (cfg->fsm == CAMIF_NORMAL_INT) ++ if (cfg->perf.frames % CHECK_FREQ == 0) ++ if (s3c_camif_check_global_status(cfg) > 0) ++ cfg->fsm = CAMIF_Xth_INT; ++ ++ switch (cfg->fsm) { ++ case CAMIF_1st_INT: ++ DPRINTK(KERN_INFO "CAMIF_1st_INT INT\n"); ++ cfg->fsm = CAMIF_NORMAL_INT; ++ return INSTANT_SKIP; ++ ++ case CAMIF_NORMAL_INT: ++ DPRINTK(KERN_INFO "CAMIF_NORMAL_INT\n"); ++ cfg->status = CAMIF_INT_HAPPEN; ++ cfg->fsm = CAMIF_NORMAL_INT; ++ return INSTANT_GO; ++ ++ case CAMIF_Xth_INT: ++ DPRINTK(KERN_INFO "CAMIF_Xth_INT\n"); ++ s3c_camif_enable_lastirq(cfg); ++ cfg->status = CAMIF_INT_HAPPEN; ++ cfg->fsm = CAMIF_Yth_INT; ++ return INSTANT_GO; ++ ++ case CAMIF_Yth_INT: ++ DPRINTK(KERN_INFO "CAMIF_Yth_INT\n"); ++ s3c_camif_disable_lastirq(cfg); ++ cfg->capture_enable = CAMIF_DMA_OFF; ++ cfg->status = CAMIF_INT_HAPPEN; ++ s3c_camif_stop_dma(cfg); ++ cfg->fsm = CAMIF_Zth_INT; ++ return INSTANT_GO; ++ ++ case CAMIF_Zth_INT: ++ DPRINTK(KERN_INFO "CAMIF_Zth_INT\n"); ++ cfg->fsm = CAMIF_DUMMY_INT; ++ cfg->status = CAMIF_INT_HAPPEN; ++ s3c_camif_auto_restart(cfg); ++ return INSTANT_GO; ++ ++ case CAMIF_DUMMY_INT: ++ DPRINTK(KERN_INFO "CAMIF_DUMMY_INT\n"); ++ cfg->status = CAMIF_STOPPED; ++ return INSTANT_SKIP; ++ ++ default: ++ printk(KERN_INFO "Unexpected INT %d\n", cfg->fsm); ++ return INSTANT_SKIP; ++ } ++} ++#endif ++ ++static irqreturn_t s3c_camif_do_irq_codec(int irq, void *dev_id) ++{ ++ camif_cfg_t *cfg = (camif_cfg_t *) dev_id; ++ ++/* @@@ SMKD ? - WA */ ++#if 0 && (defined(CONFIG_CPU_S3C6400) || defined(CONFIG_CPU_S3C6410)) ++ s3c_gpio_setpin(S3C_GPN15, 1); ++#endif ++ s3c_camif_clear_irq(irq); ++ s3c_camif_get_fifo_status(cfg); ++ s3c_camif_get_frame_num(cfg); ++ ++#if defined(FSM_ON_CODEC) && !defined(USE_LAST_IRQ) ++ if (s3c_camif_do_fsm_codec(cfg) == INSTANT_SKIP) ++ return IRQ_HANDLED; ++#endif ++ ++#if defined(FSM_ON_CODEC) && defined(USE_LAST_IRQ) ++ if (s3c_camif_do_fsm_codec_lastirq(cfg) == INSTANT_SKIP) ++ return IRQ_HANDLED; ++#endif ++ wake_up_interruptible(&cfg->waitq); ++ ++ return IRQ_HANDLED; ++} ++ ++static irqreturn_t s3c_camif_do_irq_preview(int irq, void *dev_id) ++{ ++ camif_cfg_t *cfg = (camif_cfg_t *) dev_id; ++ ++ s3c_camif_clear_irq(irq); ++ s3c_camif_get_fifo_status(cfg); ++ s3c_camif_get_frame_num(cfg); ++ wake_up_interruptible(&cfg->waitq); ++ ++#if defined(FSM_ON_PREVIEW) ++ if (s3c_camif_do_lastirq_preview(cfg) == INSTANT_SKIP) ++ return IRQ_HANDLED; ++ ++ wake_up_interruptible(&cfg->waitq); ++#endif ++ cfg->status = CAMIF_INT_HAPPEN; ++ ++ return IRQ_HANDLED; ++} ++ ++static void s3c_camif_release_irq(camif_cfg_t * cfg) ++{ ++ disable_irq(cfg->irq); ++ free_irq(cfg->irq, cfg); ++} ++ ++static int s3c_camif_request_irq(camif_cfg_t * cfg) ++{ ++ int ret; ++ ++ if (cfg->dma_type & CAMIF_CODEC) { ++ ret = request_irq(cfg->irq, s3c_camif_do_irq_codec, ++ IRQF_SHARED, cfg->shortname, cfg); ++ if (ret) ++ printk(KERN_ERR "Request irq (CAM_C) failed\n"); ++ else ++ printk(KERN_INFO "Request irq %d for codec\n", ++ cfg->irq); ++ } ++ ++ if (cfg->dma_type & CAMIF_PREVIEW) { ++ ret = request_irq(cfg->irq, s3c_camif_do_irq_preview, ++ IRQF_SHARED, cfg->shortname, cfg); ++ if (ret) ++ printk("Request_irq (CAM_P) failed\n"); ++ else ++ printk(KERN_INFO "Request irq %d for preview\n", ++ cfg->irq); ++ } ++ ++ return 0; ++} ++ ++/************************************************************************* ++ * Standard file operations part ++ ************************************************************************/ ++long s3c_camif_ioctl(struct file *file, unsigned int cmd, unsigned long _arg) ++{ ++ camif_cfg_t *cfg = file->private_data; ++ void *arg = (void *) _arg; /* @@@ - WA */ ++ ++ switch (cmd) { ++ case VIDIOC_QUERYCAP: ++ return s3c_camif_v4l2_querycap(cfg, arg); ++ ++ case VIDIOC_G_FBUF: ++ return s3c_camif_v4l2_g_fbuf(cfg, arg); ++ ++ case VIDIOC_S_FBUF: ++ return s3c_camif_v4l2_s_fbuf(cfg, arg); ++ ++ case VIDIOC_G_FMT: ++ return s3c_camif_v4l2_g_fmt(cfg, arg); ++ ++ case VIDIOC_S_FMT: ++ return s3c_camif_v4l2_s_fmt(cfg, arg); ++ ++ case VIDIOC_ENUM_FMT: ++ return s3c_camif_v4l2_enum_fmt(cfg, arg); ++ ++ case VIDIOC_OVERLAY: ++ return s3c_camif_v4l2_overlay(cfg, arg); ++ ++ case VIDIOC_S_CTRL: ++ return s3c_camif_v4l2_s_ctrl(cfg, arg); ++ ++ case VIDIOC_G_CTRL: ++ return s3c_camif_v4l2_g_ctrl(cfg, arg); ++ ++ case VIDIOC_STREAMON: ++ return s3c_camif_v4l2_streamon(cfg, arg); ++ ++ case VIDIOC_STREAMOFF: ++ return s3c_camif_v4l2_streamoff(cfg, arg); ++ ++ case VIDIOC_G_INPUT: ++ return s3c_camif_v4l2_g_input(cfg, arg); ++ ++ case VIDIOC_S_INPUT: ++ return s3c_camif_v4l2_s_input(cfg, *((int *) arg)); ++ ++ case VIDIOC_G_OUTPUT: ++ return s3c_camif_v4l2_g_output(cfg, arg); ++ ++ case VIDIOC_S_OUTPUT: ++ return s3c_camif_v4l2_s_output(cfg, *((int *) arg)); ++ ++ case VIDIOC_ENUMINPUT: ++ return s3c_camif_v4l2_enum_input(cfg, arg); ++ ++ case VIDIOC_ENUMOUTPUT: ++ return s3c_camif_v4l2_enum_output(cfg, arg); ++ ++ case VIDIOC_REQBUFS: ++ return s3c_camif_v4l2_reqbufs(cfg, arg); ++ ++ case VIDIOC_QUERYBUF: ++ return s3c_camif_v4l2_querybuf(cfg, arg); ++ ++ case VIDIOC_QBUF: ++ return s3c_camif_v4l2_qbuf(cfg, arg); ++ ++ case VIDIOC_DQBUF: ++ return s3c_camif_v4l2_dqbuf(cfg, arg); ++ ++ case VIDIOC_S_MSDMA: ++ return s3c_camif_v4l2_s_msdma(cfg, arg); ++ ++ case VIDIOC_MSDMA_START: ++ return s3c_camif_v4l2_msdma_start(cfg, arg); ++ ++ case VIDIOC_MSDMA_STOP: ++ return s3c_camif_v4l2_msdma_stop(cfg, arg); ++ ++ case VIDIOC_S_CAMERA_START: ++ return s3c_camif_v4l2_camera_start(cfg, arg); ++ ++ case VIDIOC_S_CAMERA_STOP: ++ return s3c_camif_v4l2_camera_stop(cfg, arg); ++ ++ case VIDIOC_CROPCAP: ++ return s3c_camif_v4l2_cropcap(cfg, arg); ++ ++ case VIDIOC_G_CROP: ++ return s3c_camif_v4l2_g_crop(cfg, arg); ++ ++ case VIDIOC_S_CROP: ++ return s3c_camif_v4l2_s_crop(cfg, arg); ++ ++ case VIDIOC_S_PARM: ++ return s3c_camif_v4l2_s_parm(cfg, arg); ++ ++ default: /* For v4l compatability */ ++ return ++ v4l_compat_translate_ioctl(file, cmd, arg, s3c_camif_ioctl); ++ } ++} ++ ++ ++void om_3d7k_camera_on(void) ++{ ++ extern struct pcf50633 *om_3d7k_pcf; ++ int i; ++ ++ gpio_direction_output(S3C64XX_GPF(3), 0); ++ ++ /* @@@ hack - WA */ ++ pcf50633_reg_write(om_3d7k_pcf, 0x30, 0x21); ++ for (i = 0; !(pcf50633_reg_read(om_3d7k_pcf, 0x42) & 0x02); i++) { ++ if (i == 100) { ++ printk(KERN_ERR "can't bring up LDO2\n"); ++ break; ++ } ++ msleep(10); ++ } ++ ++ pcf50633_reg_write(om_3d7k_pcf, 0x39, 0x13); ++ pcf50633_reg_write(om_3d7k_pcf, 0x3a, 0x21); ++ for (i = 0; !(pcf50633_reg_read(om_3d7k_pcf, 0x42) & 0x40); i++) { ++ if (i == 100) { ++ printk(KERN_ERR "can't bring up HCLDO\n"); ++ break; ++ } ++ msleep(10); ++ } ++ ++ msleep(100); /* > 0 ms */ ++ ++ if (cam_clock) ++ clk_enable(cam_clock); ++ ++ msleep(1); /* > 100 cycles */ ++ gpio_direction_output(S3C64XX_GPF(3), 1); ++ msleep(25); /* > 1 Mcycles */ ++ s3c_gpio_cfgpin(S3C64XX_GPF(3), S3C64XX_GPF3_CAMIF_nRST); ++ msleep(25); /* just to be sure > 1 Mcycles */ ++ ++ __raw_writel(__raw_readl(S3C64XX_NORMAL_CFG) | ++ S3C64XX_NORMALCFG_DOMAIN_I_ON, S3C64XX_NORMAL_CFG); ++} ++ ++void om_3d7k_camera_off(void) ++{ ++ extern struct pcf50633 *om_3d7k_pcf; ++ ++ gpio_direction_output(S3C64XX_GPF(3), 0); ++ ++ msleep(1); /* > 20 cycles */ ++ ++ if (cam_clock) ++ clk_disable(cam_clock); ++ msleep(1); /* > 0 ms */ ++ ++ /* @@@ hack - WA */ ++ pcf50633_reg_write(om_3d7k_pcf, 0x3a, 0x20); /* 2V8, ... */ ++ pcf50633_reg_write(om_3d7k_pcf, 0x30, 0x20); /* ... then 1V5 */ ++ ++#if 0 ++ __raw_writel(__raw_readl(S3C64XX_NORMAL_CFG) & ++ ~S3C64XX_NORMALCFG_DOMAIN_I_ON, S3C64XX_NORMAL_CFG); ++#endif ++} ++ ++ ++/* @@@ - WA */ ++#define s3c_camif_exclusive_open(inode, file) 0 ++#define s3c_camif_exclusive_release(inode, file) ++ ++int s3c_camif_open(struct file *file) ++{ ++ int err; ++ camif_cfg_t *cfg = ++ s3c_camif_get_fimc_object(MINOR(file->f_dentry->d_inode->i_rdev)); ++ ++ if (!cfg->cis) { ++ printk(KERN_ERR "An object for a CIS is missing\n"); ++ printk(KERN_ERR ++ "Using msdma_input as a default CIS data structure\n"); ++ cfg->cis = &msdma_input; ++ ++ /* global lock for both Codec and Preview */ ++ sema_init(&cfg->cis->lock, 1); ++ cfg->cis->status |= P_NOT_WORKING; ++ } ++ ++ if (cfg->dma_type & CAMIF_PREVIEW) { ++ if (cfg->dma_type & CAMIF_PREVIEW) ++ cfg->cis->status &= ~P_NOT_WORKING; ++ ++ up(&cfg->cis->lock); ++ } ++ ++ om_3d7k_camera_on(); ++ ++ err = s3c_camif_exclusive_open(inode, file); ++ cfg->cis->user++; ++ cfg->status = CAMIF_STOPPED; ++ ++ if (err < 0) ++ return err; ++ ++ if (file->f_flags & O_NONCAP) { ++ printk(KERN_ERR "Don't support non-capturing open\n"); ++ return 0; ++ } ++ ++ file->private_data = cfg; ++ ++ s3c_camif_init_sensor(cfg); ++ ++ return 0; ++} ++ ++int s3c_camif_release(struct file *file) ++{ ++ camif_cfg_t *cfg = ++ s3c_camif_get_fimc_object(MINOR(file->f_dentry->d_inode->i_rdev)); ++ ++ if (cfg->dma_type & CAMIF_PREVIEW) { ++ cfg->cis->status &= ~PWANT2START; ++ cfg->cis->status |= P_NOT_WORKING; ++ s3c_camif_stop_preview(cfg); ++ up(&cfg->cis->lock); ++ } else { ++ cfg->cis->status &= ~CWANT2START; ++ s3c_camif_stop_capture(cfg); ++ } ++ ++ s3c_camif_exclusive_release(inode, file); ++ ++ if (cfg->cis->sensor == NULL) ++ DPRINTK("A CIS sensor for MSDMA has been used\n"); ++ else ++ cfg->cis->sensor->driver->command(cfg->cis->sensor, USER_EXIT, ++ NULL); ++ ++ cfg->cis->user--; ++ cfg->status = CAMIF_STOPPED; ++ ++ om_3d7k_camera_off(); ++ cfg->cis->init_sensor = 0; ++ ++ return 0; ++} ++ ++ssize_t s3c_camif_read(struct file * file, char *buf, size_t count, ++ loff_t *pos) ++{ ++ camif_cfg_t *cfg = NULL; ++ size_t end; ++ ++ cfg = s3c_camif_get_fimc_object(MINOR(file->f_dentry->d_inode->i_rdev)); ++ ++#if defined(FSM_ON_PREVIEW) ++ if (cfg->dma_type == CAMIF_PREVIEW) { ++ if (wait_event_interruptible(cfg->waitq, ++ cfg->status == CAMIF_INT_HAPPEN)) ++ return -ERESTARTSYS; ++ ++ cfg->status = CAMIF_STOPPED; ++ } ++#endif ++ ++#if defined(FSM_ON_CODEC) ++ if (cfg->dma_type == CAMIF_CODEC) { ++ if (wait_event_interruptible(cfg->waitq, ++ cfg->status == CAMIF_INT_HAPPEN)) ++ return -ERESTARTSYS; ++ ++ cfg->status = CAMIF_STOPPED; ++ } ++#endif ++ end = min_t(size_t, cfg->pp_totalsize / cfg->pp_num, count); ++ ++ if (copy_to_user(buf, s3c_camif_get_frame(cfg), end)) ++ return -EFAULT; ++ ++ return end; ++} ++ ++ssize_t s3c_camif_write(struct file * f, const char *b, size_t c, ++ loff_t *offset) ++{ ++ camif_cfg_t *cfg; ++ int ret = 0; ++ ++ cfg = s3c_camif_get_fimc_object(MINOR(f->f_dentry->d_inode->i_rdev)); ++ ++ switch (*b) { ++ case 'O': ++ if (cfg->dma_type & CAMIF_PREVIEW) ++ s3c_camif_start_preview(cfg); ++ else { ++ ret = s3c_camif_start_capture(cfg); ++ ++ if (ret < 0) ++ ret = 1; ++ } ++ ++ break; ++ ++ case 'X': ++ if (cfg->dma_type & CAMIF_PREVIEW) { ++ s3c_camif_stop_preview(cfg); ++ cfg->cis->status |= P_NOT_WORKING; ++ } else { ++ cfg->cis->status &= ~C_WORKING; ++ s3c_camif_stop_capture(cfg); ++ } ++ ++ break; ++ ++#if defined(CONFIG_CPU_S3C2443) || defined(CONFIG_CPU_S3C2450) || defined(CONFIG_CPU_S3C2416) ++ case 'P': ++ if (cfg->dma_type & CAMIF_PREVIEW) { ++ s3c_camif_start_preview(cfg); ++ s3c_camif_do_postprocess(cfg); ++ return 0; ++ } else ++ return -EFAULT; ++#endif ++ default: ++ panic("s3c_camera_driver.c: s3c_camif_write() - " ++ "Unexpected Parameter\n"); ++ } ++ ++ return ret; ++} ++ ++int s3c_camif_mmap(struct file* filp, struct vm_area_struct *vma) ++{ ++ camif_cfg_t *cfg = filp->private_data; ++ ++ unsigned long pageFrameNo; ++ unsigned long size = vma->vm_end - vma->vm_start; ++ unsigned long total_size; ++ ++ if (cfg->dma_type == CAMIF_PREVIEW) ++ total_size = RGB_MEM; ++ else ++ total_size = YUV_MEM; ++ ++ /* ++ * page frame number of the address for a source RGB frame to be stored ++ * at. ++ */ ++ pageFrameNo = __phys_to_pfn(cfg->pp_phys_buf); ++ ++ if (size > total_size) { ++ printk(KERN_ERR "The size of RGB_MEM mapping is too big\n"); ++ return -EINVAL; ++ } ++ ++ if ((vma->vm_flags & VM_WRITE) && !(vma->vm_flags & VM_SHARED)) { ++ printk(KERN_ERR "Writable RGB_MEM mapping must be shared\n"); ++ return -EINVAL; ++ } ++ ++ if (remap_pfn_range(vma, vma->vm_start, pageFrameNo + vma->vm_pgoff, ++ size, vma->vm_page_prot)) ++ return -EINVAL; ++ ++ return 0; ++} ++ ++static unsigned int s3c_camif_poll(struct file *file, poll_table *wait) ++{ ++ unsigned int mask = 0; ++ camif_cfg_t *cfg = file->private_data; ++ ++ poll_wait(file, &cfg->waitq, wait); ++ ++ if (cfg->status == CAMIF_INT_HAPPEN) ++ mask = POLLIN | POLLRDNORM; ++ ++ cfg->status = CAMIF_STOPPED; ++ ++ return mask; ++} ++ ++struct v4l2_file_operations camif_c_fops = { ++ .owner = THIS_MODULE, ++ .open = s3c_camif_open, ++ .release = s3c_camif_release, ++ .ioctl = s3c_camif_ioctl, ++ .read = s3c_camif_read, ++ .write = s3c_camif_write, ++ .mmap = s3c_camif_mmap, ++ .poll = s3c_camif_poll, ++}; ++ ++struct v4l2_file_operations camif_p_fops = { ++ .owner = THIS_MODULE, ++ .open = s3c_camif_open, ++ .release = s3c_camif_release, ++ .ioctl = s3c_camif_ioctl, ++ .read = s3c_camif_read, ++ .write = s3c_camif_write, ++ .mmap = s3c_camif_mmap, ++ .poll = s3c_camif_poll, ++}; ++ ++/************************************************************************* ++ * Templates for V4L2 ++ ************************************************************************/ ++void camif_vdev_release (struct video_device *vdev) { ++ kfree(vdev); ++} ++ ++struct video_device codec_template = { ++ .name = CODEC_DEV_NAME, ++#if 0 ++ .type = VID_TYPE_OVERLAY | VID_TYPE_CAPTURE | VID_TYPE_CLIPPING | VID_TYPE_SCALES, ++ .type2 = V4L2_CAP_VIDEO_OVERLAY | V4L2_CAP_VIDEO_CAPTURE | V4L2_CAP_STREAMING, ++ .hardware = VID_HARDWARE_SAMSUNG_FIMC3X, ++#endif ++ .fops = &camif_c_fops, ++ .release = camif_vdev_release, ++ .minor = CODEC_MINOR, ++}; ++ ++struct video_device preview_template = { ++ .name = PREVIEW_DEV_NAME, ++#if 0 ++ .type = VID_TYPE_OVERLAY | VID_TYPE_CAPTURE | VID_TYPE_CLIPPING | VID_TYPE_SCALES, ++ .type2 = V4L2_CAP_VIDEO_OVERLAY | V4L2_CAP_VIDEO_CAPTURE | V4L2_CAP_STREAMING, ++ .hardware = VID_HARDWARE_SAMSUNG_FIMC3X, ++#endif ++ .fops = &camif_p_fops, ++ .release = camif_vdev_release, ++ .minor = PREVIEW_MINOR, ++}; ++ ++/************************************************************************* ++ * Initialize part ++ ************************************************************************/ ++void s3c_camif_init_sensor(camif_cfg_t *cfg) ++{ ++ camif_cis_t *cis = cfg->cis; ++ camif_cis_t *initialized_cis; ++ ++ if (!cis->sensor) { ++ initialized_cis = (camif_cis_t *) get_initialized_cis(); ++ ++ if (initialized_cis == NULL) { ++ printk(KERN_ERR "An I2C client for CIS sensor isn't registered\n"); ++ return; ++ } ++ ++ cis = cfg->cis = initialized_cis; ++ cfg->input_channel = 0; ++ cfg->cis->user++; ++ } ++ ++ if (!cis->init_sensor) { ++ cis->sensor->driver->command(cis->sensor, SENSOR_INIT, NULL); ++ cis->init_sensor = 1; ++ ++#if defined(CONFIG_VIDEO_SAMSUNG_S5K3BA) ++ cis->sensor->driver->command(cis->sensor, SENSOR_VGA, NULL); ++ cis->source_x = 640; ++ cis->source_y = 480; ++#elif defined(CONFIG_VIDEO_SAMSUNG_S5K4BA) ++ cis->sensor->driver->command(cis->sensor, SENSOR_SVGA, NULL); ++ cis->source_x = 800; ++ cis->source_y = 600; ++#endif ++ } ++ ++ cis->sensor->driver->command(cis->sensor, USER_ADD, NULL); ++} ++ ++static int s3c_camif_init_preview(camif_cfg_t * cfg) ++{ ++ cfg->target_x = PREVIEW_DEFAULT_WIDTH; ++ cfg->target_y = PREVIEW_DEFAULT_WIDTH; ++ cfg->pp_num = PREVIEW_DEFAULT_PPNUM; ++ cfg->dma_type = CAMIF_PREVIEW; ++ cfg->input_channel = CAMERA_INPUT; ++ cfg->src_fmt = CAMIF_YCBCR422; ++ cfg->output_channel = CAMIF_OUT_PP; ++ cfg->dst_fmt = CAMIF_RGB16; ++ cfg->flip = CAMIF_FLIP_Y; ++ cfg->v = &preview_template; ++ ++ /* @@@ - WA */ ++ //init_MUTEX((struct semaphore *) &cfg->v->lock); ++ init_waitqueue_head(&cfg->waitq); ++ ++ cfg->status = CAMIF_STOPPED; ++ ++ /* To get the handle of CODEC */ ++ cfg->other = s3c_camif_get_fimc_object(CODEC_MINOR); ++ ++ return cfg->status; ++} ++ ++static int s3c_camif_init_codec(camif_cfg_t * cfg) ++{ ++ cfg->target_x = CODEC_DEFAULT_WIDTH; ++ cfg->target_y = CODEC_DEFAULT_HEIGHT; ++ cfg->pp_num = CODEC_DEFAULT_PPNUM; ++ cfg->dma_type = CAMIF_CODEC; ++ cfg->src_fmt = CAMIF_YCBCR422; ++ cfg->input_channel = CAMERA_INPUT; ++ cfg->dst_fmt = CAMIF_YCBCR420; ++ cfg->output_channel = CAMIF_OUT_PP; ++ cfg->flip = CAMIF_FLIP_X; ++ cfg->v = &codec_template; ++ ++ /* @@@ - WA */ ++ //init_MUTEX((struct semaphore *) &cfg->v->lock); ++ ++ init_waitqueue_head(&cfg->waitq); ++ ++ cfg->status = CAMIF_STOPPED; ++ ++ /* To get the handle of PREVIEW */ ++ cfg->other = s3c_camif_get_fimc_object(PREVIEW_MINOR); ++ ++ return cfg->status; ++} ++ ++static int s3c_camif_probe(struct platform_device *pdev) ++{ ++ struct resource *res; ++ camif_cfg_t *codec, *preview; ++ struct clk *camif_clock; ++ ++ /* Initialize fimc objects */ ++ codec = s3c_camif_get_fimc_object(CODEC_MINOR); ++ preview = s3c_camif_get_fimc_object(PREVIEW_MINOR); ++ ++ memset(codec, 0, sizeof(camif_cfg_t)); ++ memset(preview, 0, sizeof(camif_cfg_t)); ++ ++ /* Set the fimc name */ ++ strcpy(codec->shortname, CODEC_DEV_NAME); ++ strcpy(preview->shortname, PREVIEW_DEV_NAME); ++ ++ /* get resource for io memory */ ++ res = platform_get_resource(pdev, IORESOURCE_MEM, 0); ++ ++ if (!res) { ++ printk("Failed to get io memory region resouce.\n"); ++ return -1; ++ } ++ ++ /* request mem region */ ++ res = request_mem_region(res->start, res->end - res->start + 1, ++ pdev->name); ++ ++ if (!res) { ++ printk("Failed to request io memory region.\n"); ++ return -1; ++ } ++ ++ /* ioremap for register block */ ++ codec->regs = preview->regs = ++ ioremap(res->start, res->end - res->start + 1); ++ ++ if (codec->regs == NULL) { ++ printk(KERN_ERR "Failed to remap register block\n"); ++ return -1; ++ } ++ ++ /* ioremap for reserved memory */ ++ codec->pp_phys_buf = PHYS_OFFSET + (MEM_SIZE - RESERVED_MEM); ++ codec->pp_virt_buf = ioremap_nocache(codec->pp_phys_buf, YUV_MEM); ++ ++ preview->pp_phys_buf = ++ PHYS_OFFSET + (MEM_SIZE - RESERVED_MEM) + YUV_MEM; ++ preview->pp_virt_buf = ioremap_nocache(preview->pp_phys_buf, RGB_MEM); ++ ++ camif_clock = clk_get(&pdev->dev, "camif"); ++ if (IS_ERR(camif_clock)) { ++ dev_err(&pdev->dev, ++ "Failed to find camera interface clock source\n"); ++ return PTR_ERR(cam_clock); ++ } ++ clk_enable(camif_clock); ++ ++ /* Device init */ ++ s3c_camif_init(); ++ s3c_camif_init_codec(codec); ++ s3c_camif_init_preview(preview); ++ ++ /* Set irq */ ++ codec->irq = platform_get_irq(pdev, FIMC_CODEC_INDEX); ++ preview->irq = platform_get_irq(pdev, FIMC_PREVIEW_INDEX); ++ ++ s3c_camif_request_irq(codec); ++ s3c_camif_request_irq(preview); ++ ++ /* Register to video device */ ++ if (video_register_device(codec->v, VFL_TYPE_GRABBER, CODEC_MINOR) != ++ 0) { ++ printk(KERN_ERR "Couldn't register this codec driver\n"); ++ return -1; ++ } ++ ++ if (video_register_device(preview->v, VFL_TYPE_GRABBER, PREVIEW_MINOR) ++ != 0) { ++ printk(KERN_ERR "Couldn't register this preview driver\n"); ++ return -1; ++ } ++ ++#if defined(CONFIG_CPU_S3C6400) || defined(CONFIG_CPU_S3C6410) ++ cam_clock = clk_get(&pdev->dev, "camera"); ++#elif defined(CONFIG_CPU_S3C2443) || defined(CONFIG_CPU_S3C2416) || defined(CONFIG_CPU_S3C2450) ++ cam_clock = clk_get(&pdev->dev, "camif-upll"); ++#else ++#error cam_clock should be defined ++#endif ++ ++ if (IS_ERR(cam_clock)) { ++ printk("Failed to find camera clock source\n"); ++ return PTR_ERR(cam_clock); ++ } ++ ++ /* Print banner */ ++ printk(KERN_INFO "S3C FIMC v%s\n", FIMC_VER); ++ ++ return 0; ++} ++ ++static int s3c_camif_remove(struct platform_device *pdev) ++{ ++ camif_cfg_t *codec, *preview; ++ ++ codec = s3c_camif_get_fimc_object(CODEC_MINOR); ++ preview = s3c_camif_get_fimc_object(PREVIEW_MINOR); ++ ++ s3c_camif_release_irq(codec); ++ s3c_camif_release_irq(preview); ++ ++ iounmap(codec->pp_virt_buf); ++ codec->pp_virt_buf = 0; ++ ++ iounmap(preview->pp_virt_buf); ++ preview->pp_virt_buf = 0; ++ ++ video_unregister_device(codec->v); ++ video_unregister_device(preview->v); ++ ++ s3c_camif_set_priority(0); ++ clk_disable(cam_clock); ++ ++ memset(codec, 0, sizeof(camif_cfg_t)); ++ memset(preview, 0, sizeof(camif_cfg_t)); ++ ++ return 0; ++} ++ ++static struct platform_driver s3c_camif_driver = ++{ ++ .probe = s3c_camif_probe, ++ .remove = s3c_camif_remove, ++ .driver = { ++ .name = "s3c-camif", ++ .owner = THIS_MODULE, ++ }, ++}; ++ ++static int s3c_camif_register(void) ++{ ++ platform_driver_register(&s3c_camif_driver); ++ ++ return 0; ++} ++ ++static void s3c_camif_unregister(void) ++{ ++ platform_driver_unregister(&s3c_camif_driver); ++} ++ ++void s3c_camif_open_sensor(camif_cis_t *cis) ++{ ++ clk_set_rate(cam_clock, cis->camclk); ++ s3c_camif_reset(cis->reset_type, cis->reset_udelay); ++} ++ ++void s3c_camif_register_sensor(struct i2c_client *ptr) ++{ ++ camif_cfg_t *codec, *preview; ++ camif_cis_t *cis = i2c_get_clientdata(ptr); ++ ++ codec = s3c_camif_get_fimc_object(CODEC_MINOR); ++ preview = s3c_camif_get_fimc_object(PREVIEW_MINOR); ++ ++ codec->cis = preview->cis = cis; ++ ++ sema_init(&codec->cis->lock, 1); ++ sema_init(&preview->cis->lock, 1); ++ ++ preview->cis->status |= P_NOT_WORKING; /* Default Value */ ++ ++ s3c_camif_set_polarity(preview); ++ s3c_camif_set_source_format(cis); ++ s3c_camif_set_priority(1); ++} ++ ++void s3c_camif_unregister_sensor(struct i2c_client *ptr) ++{ ++ camif_cis_t *cis; ++ ++ cis = i2c_get_clientdata(ptr); ++ cis->init_sensor = 0; ++} ++ ++module_init(s3c_camif_register); ++module_exit(s3c_camif_unregister); ++ ++EXPORT_SYMBOL(s3c_camif_register_sensor); ++EXPORT_SYMBOL(s3c_camif_unregister_sensor); ++ ++MODULE_AUTHOR("Jinsung Yang <jsgood.yang@samsung.com>"); ++MODULE_DESCRIPTION("S3C Camera Driver for FIMC Interface"); ++MODULE_LICENSE("GPL"); +diff -ruN --exclude='*.orig' --exclude='*.rej' linux-2.6.29-rc3.owrt/drivers/media/video/s3c_camif.c linux-2.6.29-rc3.owrt.om/drivers/media/video/s3c_camif.c +--- linux-2.6.29-rc3.owrt/drivers/media/video/s3c_camif.c 1970-01-01 01:00:00.000000000 +0100 ++++ linux-2.6.29-rc3.owrt.om/drivers/media/video/s3c_camif.c 2009-05-10 22:27:59.000000000 +0200 +@@ -0,0 +1,1916 @@ ++/* drivers/media/video/s3c_camif.c ++ * ++ * Copyright (c) 2008 Samsung Electronics ++ * ++ * Samsung S3C Camera driver ++ * ++ * 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, MA 02111-1307 USA ++ */ ++ ++#include <linux/module.h> ++#include <linux/kernel.h> ++#include <linux/init.h> ++#include <linux/sched.h> ++#include <linux/completion.h> ++#include <linux/delay.h> ++#include <linux/slab.h> ++#include <linux/vmalloc.h> ++#include <linux/wait.h> ++#include <linux/videodev.h> ++#include <asm/io.h> ++#include <mach/hardware.h> ++#include <asm/uaccess.h> ++#include <mach/map.h> ++#include <mach/gpio.h> ++#include <mach/irqs.h> ++#include <plat/gpio-cfg.h> ++#include <plat/regs-camif.h> ++#include <plat/regs-gpio.h> ++#include <plat/gpio-bank-f.h> ++ ++#if defined(CONFIG_CPU_S3C2443) || defined(CONFIG_CPU_S3C2450) || defined(CONFIG_CPU_S3C2416) ++#include <asm/arch/regs-irq.h> ++#endif ++ ++#include "s3c_camif.h" ++ ++#define S3C_VIDW00ADD0B0 (S3C24XX_VA_LCD+0xa0) ++#define S3C_VIDW01ADD0B0 (S3C24XX_VA_LCD+0xa8) ++ ++static unsigned int irq_old_priority; ++ ++/************************************************************************* ++ * Utility part ++ ************************************************************************/ ++int s3c_camif_get_frame_num(camif_cfg_t *cfg) ++{ ++ int index = 0; ++ ++ if (cfg->dma_type & CAMIF_CODEC) ++ index = (readl(cfg->regs + S3C_CICOSTATUS) >> 26) & 0x3; ++ else { ++ assert(cfg->dma_type & CAMIF_PREVIEW); ++ index = (readl(cfg->regs + S3C_CIPRSTATUS) >> 26) & 0x3; ++ } ++ ++ cfg->cur_frame_num = (index + 2) % 4; /* When 4 PingPong */ ++ ++ return 0; ++} ++ ++unsigned char* s3c_camif_get_frame(camif_cfg_t *cfg) ++{ ++ unsigned char *ret = NULL; ++ int cnt = cfg->cur_frame_num; ++ ++ if (cfg->dma_type & CAMIF_PREVIEW) ++ ret = cfg->img_buf[cnt].virt_rgb; ++ ++ if (cfg->dma_type & CAMIF_CODEC) { ++ if ((cfg->dst_fmt & CAMIF_RGB16) || ++ (cfg->dst_fmt & CAMIF_RGB24)) ++ ret = cfg->img_buf[cnt].virt_rgb; ++ else ++ ret = cfg->img_buf[cnt].virt_y; ++ } ++ ++ return ret; ++} ++ ++int s3c_camif_get_fifo_status(camif_cfg_t *cfg) ++{ ++ unsigned int reg, val, flag; ++ ++ if (cfg->dma_type & CAMIF_CODEC) { ++ flag = S3C_CICOSTATUS_OVFIY_CO | S3C_CICOSTATUS_OVFICB_CO | ++ S3C_CICOSTATUS_OVFICR_CO; ++ reg = readl(cfg->regs + S3C_CICOSTATUS); ++ ++ if (reg & flag) { ++ /* FIFO Error Count ++ */ ++ val = readl(cfg->regs + S3C_CIWDOFST); ++ val |= S3C_CIWDOFST_CLROVCOFIY | ++ S3C_CIWDOFST_CLROVCOFICB | S3C_CIWDOFST_CLROVCOFICR; ++ writel(val, cfg->regs + S3C_CIWDOFST); ++ ++ val = readl(cfg->regs + S3C_CIWDOFST); ++ val &= ~(S3C_CIWDOFST_CLROVCOFIY | ++ S3C_CIWDOFST_CLROVCOFICB | ++ S3C_CIWDOFST_CLROVCOFICR); ++ writel(val, cfg->regs + S3C_CIWDOFST); ++ ++ return 1; /* Error */ ++ } ++ } else if (cfg->dma_type & CAMIF_PREVIEW) { ++ flag = S3C_CIPRSTATUS_OVFICB_PR | S3C_CIPRSTATUS_OVFICR_PR; ++ reg = readl(cfg->regs + S3C_CIPRSTATUS); ++ ++ if (reg & flag) { ++ /* FIFO Error Count ++ */ ++ val = readl(cfg->regs + S3C_CIWDOFST); ++ val |= S3C_CIWDOFST_CLROVPRFICB | ++ S3C_CIWDOFST_CLROVPRFICR; ++ writel(val, cfg->regs + S3C_CIWDOFST); ++ ++ val = readl(cfg->regs + S3C_CIWDOFST); ++ val &= ~(S3C_CIWDOFST_CLROVPRFIY | ++ S3C_CIWDOFST_CLROVPRFICB | ++ S3C_CIWDOFST_CLROVPRFICR); ++ writel(val, cfg->regs + S3C_CIWDOFST); ++ ++ return 1; /* Error */ ++ } ++ } ++ ++ return 0; ++} ++ ++void s3c_camif_set_polarity(camif_cfg_t *cfg) ++{ ++ camif_cis_t *cis = cfg->cis; ++ unsigned int val; ++ unsigned int cmd; ++ ++ cmd = readl(cfg->regs + S3C_CIGCTRL); ++ cmd &= ~(0x7 << 24); ++ ++ if (cis->polarity_pclk) ++ cmd |= S3C_CIGCTRL_INVPOLPCLK; ++ ++ if (cis->polarity_vsync) ++ cmd |= S3C_CIGCTRL_INVPOLVSYNC; ++ ++ if (cis->polarity_href) ++ cmd |= S3C_CIGCTRL_INVPOLHREF; ++ ++ val = readl(cfg->regs + S3C_CIGCTRL); ++ val |= cmd; ++ writel(val, cfg->regs + S3C_CIGCTRL); ++} ++ ++/************************************************************************* ++ * Memory part ++ ************************************************************************/ ++static int s3c_camif_request_memory(camif_cfg_t *cfg) ++{ ++ unsigned int t_size = 0, i = 0; ++ unsigned int area = 0; ++ ++ area = cfg->target_x * cfg->target_y; ++ ++ if (cfg->dma_type & CAMIF_CODEC) { ++ if (cfg->dst_fmt & CAMIF_YCBCR420) ++ t_size = area * 3 / 2; /* CAMIF_YCBCR420 */ ++ else if (cfg->dst_fmt & CAMIF_YCBCR422 || ++ cfg->dst_fmt & CAMIF_YCBCR422I) ++ t_size = area * 2; /* CAMIF_YCBCR422 */ ++ else if (cfg->dst_fmt & CAMIF_RGB16) ++ t_size = area * 2; /* 2 bytes per pixel */ ++ else if (cfg->dst_fmt & CAMIF_RGB24) ++ t_size = area * 4; /* 4 bytes per pixel */ ++ else ++ printk(KERN_INFO "Invalid target format\n"); ++ } else if (cfg->dma_type & CAMIF_PREVIEW) { ++ ++ if (cfg->dst_fmt & CAMIF_RGB16) ++ t_size = area * 2; /* 2 bytes per pixel */ ++ else if (cfg->dst_fmt & CAMIF_RGB24) ++ t_size = area * 4; /* 4 bytes per pixel */ ++ else ++ printk(KERN_ERR "Invalid target format\n"); ++ ++ } else { ++ return 0; ++ } ++ ++ if (t_size % PAGE_SIZE != 0) { ++ i = t_size / PAGE_SIZE; ++ t_size = (i + 1) * PAGE_SIZE; ++ } ++ ++ t_size = t_size * cfg->pp_num; ++ cfg->pp_totalsize = t_size; ++ ++ printk(KERN_INFO "%s memory required: 0x%08X bytes\n", ++ cfg->dma_type & CAMIF_CODEC ? "Codec" : "Preview", t_size); ++ ++ return 0; ++} ++ ++static void s3c_camif_calc_burst_length_yuv422i(unsigned int hsize, ++ unsigned int *mburst, unsigned int *rburst) ++{ ++ unsigned int tmp, wanted; ++ ++ tmp = (hsize / 2) & 0xf; ++ ++ switch (tmp) { ++ case 0: ++ wanted = 16; ++ break; ++ ++ case 4: ++ wanted = 4; ++ break; ++ ++ case 8: ++ wanted = 8; ++ break; ++ ++ default: ++ wanted = 4; ++ break; ++ } ++ ++ *mburst = wanted / 2; ++ *rburst = wanted / 2; ++} ++ ++static void s3c_camif_calc_burst_length(unsigned int hsize, ++ unsigned int *mburst, unsigned int *rburst) ++{ ++ unsigned int tmp; ++ ++ tmp = (hsize / 4) & 0xf; ++ ++ switch (tmp) { ++ case 0: ++ *mburst = 16; ++ *rburst = 16; ++ break; ++ ++ case 4: ++ *mburst = 16; ++ *rburst = 4; ++ break; ++ ++ case 8: ++ *mburst = 16; ++ *rburst = 8; ++ break; ++ ++ default: ++ tmp = (hsize / 4) % 8; ++ ++ if (tmp == 0) { ++ *mburst = 8; ++ *rburst = 8; ++ } else if (tmp == 4) { ++ *mburst = 8; ++ *rburst = 4; ++ } else { ++ tmp = (hsize / 4) % 4; ++ *mburst = 4; ++ *rburst = tmp ? tmp : 4; ++ } ++ ++ break; ++ } ++} ++ ++int s3c_camif_setup_dma(camif_cfg_t *cfg) ++{ ++ int width = cfg->target_x; ++ unsigned int val, yburst_m, yburst_r, cburst_m, cburst_r; ++ ++ if (cfg->dma_type & CAMIF_CODEC) { ++ if (cfg->dst_fmt == CAMIF_RGB16 || ++ cfg->dst_fmt == CAMIF_RGB24) { ++ if (cfg->dst_fmt == CAMIF_RGB24) { ++ if (width % 2 != 0) ++ return BURST_ERR; ++ ++ s3c_camif_calc_burst_length(width * 4, ++ &yburst_m, &yburst_r); ++ } else { ++ if ((width / 2) % 2 != 0) ++ return BURST_ERR; ++ ++ s3c_camif_calc_burst_length(width * 2, ++ &yburst_m, &yburst_r); ++ } ++ ++ val = readl(cfg->regs + S3C_CICOCTRL); ++ val &= ~(0xfffff << 4); ++ ++ if (cfg->dst_fmt == CAMIF_RGB24) { ++ val = S3C_CICOCTRL_YBURST1_CO(yburst_m / 2) | ++ S3C_CICOCTRL_YBURST2_CO(yburst_r / 4) | ++ (4 << 9) | (2 << 4); ++ } else { ++ val = S3C_CICOCTRL_YBURST1_CO(yburst_m / 2) | ++ S3C_CICOCTRL_YBURST2_CO(yburst_r / 2) | ++ (4 << 9) | (2 << 4); ++ } ++ ++ writel(val, cfg->regs + S3C_CICOCTRL); ++ } else { ++ /* CODEC DMA WIDHT is multiple of 16 */ ++ if (width % 16 != 0) ++ return BURST_ERR; ++ ++ if (cfg->dst_fmt == CAMIF_YCBCR422I) { ++ s3c_camif_calc_burst_length_yuv422i(width, ++ &yburst_m, &yburst_r); ++ cburst_m = yburst_m / 2; ++ cburst_r = yburst_r / 2; ++ } else { ++ s3c_camif_calc_burst_length(width, &yburst_m, ++ &yburst_r); ++ s3c_camif_calc_burst_length(width / 2, ++ &cburst_m, &cburst_r); ++ } ++ ++ val = readl(cfg->regs + S3C_CICOCTRL); ++ val &= ~(0xfffff << 4); ++ val |= S3C_CICOCTRL_YBURST1_CO(yburst_m) | ++ S3C_CICOCTRL_CBURST1_CO(cburst_m) | ++ S3C_CICOCTRL_YBURST2_CO(yburst_r) | ++ S3C_CICOCTRL_CBURST2_CO(cburst_r); ++ writel(val, cfg->regs + S3C_CICOCTRL); ++ } ++ } else if (cfg->dma_type & CAMIF_PREVIEW) { ++ if (cfg->dst_fmt == CAMIF_RGB24) { ++ if (width % 2 != 0) ++ return BURST_ERR; ++ ++ s3c_camif_calc_burst_length(width * 4, &yburst_m, ++ &yburst_r); ++ } else { ++ if ((width / 2) % 2 != 0) ++ return BURST_ERR; ++ ++ s3c_camif_calc_burst_length(width * 2, &yburst_m, ++ &yburst_r); ++ } ++ ++ val = readl(cfg->regs + S3C_CIPRCTRL); ++ val &= ~(0x3ff << 14); ++ val |= S3C_CICOCTRL_YBURST1_CO(yburst_m) | ++ S3C_CICOCTRL_YBURST2_CO(yburst_r); ++ writel(val, cfg->regs + S3C_CIPRCTRL); ++ } ++ ++ return 0; ++} ++ ++/************************************************************************* ++ * Input path part ++ ************************************************************************/ ++/* ++ * 2443 MSDMA (Preview Only) ++ */ ++#if defined(CONFIG_CPU_S3C2443) || defined(CONFIG_CPU_S3C2450) || defined(CONFIG_CPU_S3C2416) ++int s3c_camif_input_msdma_preview(camif_cfg_t * cfg) ++{ ++ unsigned int addr_start_Y, addr_start_CB, addr_start_CR; ++ unsigned int addr_end_Y, addr_end_CB, addr_end_CR; ++ unsigned int val, val_width; ++ unsigned area, div; ++ ++ val = readl(cfg->regs + S3C_CIMSCTRL); ++ val &= ~(1 << 2); ++ writel(val, cfg->regs + S3C_CIMSCTRL); ++ ++ val = readl(cfg->regs + S3C_CIMSCTRL); ++ val |= 1 << 2; ++ writel(val, cfg->regs + S3C_CIMSCTRL); ++ ++ switch(cfg->src_fmt) { ++ case CAMIF_YCBCR420: ++ default: ++ val = readl(cfg->regs + S3C_CIMSCTRL); ++ val |= 0x1 << 1; ++ writel(val, cfg->regs + S3C_CIMSCTRL); ++ ++ div = 4; ++ break; ++ ++ case CAMIF_YCBCR422: ++ case CAMIF_YCBCR422I: ++ val = readl(cfg->regs + S3C_CIMSCTRL); ++ val = (val & ~(0x1 << 5)) | (0x1 << 5); /* Interleave_MS */ ++ val &= ~(0x1 << 1); ++ val &= ~(0x3 << 3); /* YCbYCr */ ++ writel(val, cfg->regs + S3C_CIMSCTRL); ++ ++ div = 2; ++ break; ++ } ++ ++ area = cfg->cis->source_x * cfg->cis->source_y; ++ ++ addr_start_Y = readl(cfg->regs + S3C_CIMSYSA); ++ addr_start_CB = addr_start_Y + area; ++ addr_start_CR = addr_start_CB + area / div; ++ ++ addr_end_Y = addr_start_Y + area; ++ addr_end_CB = addr_start_CB + area / div; ++ addr_end_CR = addr_start_CR + area / div; ++ ++ /* MSDMA memory */ ++ writel(addr_start_Y, cfg->regs + S3C_CIMSYSA); ++ writel(addr_start_CB, cfg->regs + S3C_CIMSCBSA); ++ writel(addr_start_CR, cfg->regs + S3C_CIMSCRSA); ++ ++ writel(addr_end_Y, cfg->regs + S3C_CIMSYEND); ++ writel(addr_end_CB, cfg->regs + S3C_CIMSCBEND); ++ writel(addr_end_CR, cfg->regs + S3C_CIMSCREND); ++ ++ /* MSDMA memory offset - default : 0 */ ++ writel(0, cfg->regs + S3C_CIMSYOFF); ++ writel(0, cfg->regs + S3C_CIMSCBOFF); ++ writel(0, cfg->regs + S3C_CIMSCROFF); ++ ++ /* MSDMA for codec source image width */ ++ val_width = cfg->cis->source_x; /* MSCOWIDTH */ ++ writel(val_width, cfg->regs + S3C_CIMSWIDTH); ++ ++ return 0; ++} ++ ++static int s3c_camif_input_msdma(camif_cfg_t *cfg) ++{ ++ if (cfg->input_channel == MSDMA_FROM_PREVIEW) ++ s3c_camif_input_msdma_preview(cfg); ++ ++ return 0; ++} ++ ++/* ++ * 6400 MSDMA (Preview & Codec) ++ */ ++#elif defined(CONFIG_CPU_S3C6400) || defined(CONFIG_CPU_S3C6410) ++int s3c_camif_input_msdma_codec(camif_cfg_t * cfg) ++{ ++ u32 addr_start_Y, addr_start_CB, addr_start_CR; ++ u32 addr_end_Y, addr_end_CB, addr_end_CR; ++ u32 val, val_width; ++ unsigned area, div; ++ ++ /* Codec path input data selection */ ++ val = readl(cfg->regs + S3C_MSCOCTRL); ++ val &= ~(1 << 3); ++ writel(val, cfg->regs + S3C_MSCOCTRL); ++ ++ val = readl(cfg->regs + S3C_MSCOCTRL); ++ val |= 1 << 3; ++ writel(val, cfg->regs + S3C_MSCOCTRL); ++ ++ switch(cfg->src_fmt) { ++ case CAMIF_YCBCR420: ++ default: ++ val = readl(cfg->regs + S3C_MSCOCTRL); ++ val &= ~(0x3 << 1); ++ writel(val, cfg->regs + S3C_MSCOCTRL); ++ ++ div = 4; ++ break; ++ ++ case CAMIF_YCBCR422: ++ case CAMIF_YCBCR422I: ++ val = readl(cfg->regs + S3C_MSCOCTRL); ++ val = (val & ~(0x3 << 1)) | (0x2 << 1); ++ writel(val, cfg->regs + S3C_MSCOCTRL); ++ ++ div = 2; ++ break; ++ } ++ ++ area = cfg->cis->source_x * cfg->cis->source_y; ++ ++ addr_start_Y = cfg->pp_phys_buf; ++ addr_start_CB = addr_start_Y + area; ++ addr_start_CR = addr_start_CB + area / div; ++ ++ addr_end_Y = addr_start_Y + area; ++ addr_end_CB = addr_start_CB + area / div; ++ addr_end_CR = addr_start_CR + area / div; ++ ++ /* MSDMA memory */ ++ writel(addr_start_Y, cfg->regs + S3C_MSCOY0SA); ++ writel(addr_start_CB, cfg->regs + S3C_MSCOCB0SA); ++ writel(addr_start_CR, cfg->regs + S3C_MSCOCR0SA); ++ ++ writel(addr_end_Y, cfg->regs + S3C_MSCOY0END); ++ writel(addr_end_CB, cfg->regs + S3C_MSCOCB0END); ++ writel(addr_end_CR, cfg->regs + S3C_MSCOCR0END); ++ ++ /* MSDMA memory offset */ ++ writel(0, cfg->regs + S3C_MSCOYOFF); ++ writel(0, cfg->regs + S3C_MSCOCBOFF); ++ writel(0, cfg->regs + S3C_MSCOCROFF); ++ ++ /* MSDMA for codec source image width */ ++ val_width = readl(cfg->regs + S3C_MSCOWIDTH); ++ val_width &= ~0x0fffffff; ++ val_width |= 0x1 << 31; /* AutoLoadEnable */ ++ val_width |= cfg->cis->source_y << 16; /* MSCOHEIGHT */ ++ val_width |= cfg->cis->source_x; /* MSCOWIDTH */ ++ writel(val_width, cfg->regs + S3C_MSCOWIDTH); ++ ++ return 0; ++} ++ ++int s3c_camif_input_msdma_preview(camif_cfg_t * cfg) ++{ ++ int ret = 0; ++ unsigned int addr_start_Y, addr_start_CB, addr_start_CR; ++ unsigned int addr_end_Y, addr_end_CB, addr_end_CR; ++ unsigned int val, val_width; ++ unsigned area, div; ++ ++ val = readl(cfg->regs + S3C_CIMSCTRL); ++ val &= ~(0x1 << 3); ++ writel(val, cfg->regs + S3C_CIMSCTRL); ++ ++ val = readl(cfg->regs + S3C_CIMSCTRL); ++ val |= 0x1 << 3; ++ writel(val, cfg->regs + S3C_CIMSCTRL); ++ ++ switch(cfg->src_fmt) { ++ case CAMIF_YCBCR420: ++ default: ++ val = readl(cfg->regs + S3C_CIMSCTRL); ++ val &= ~(0x3 << 1); ++ writel(val, cfg->regs + S3C_CIMSCTRL); ++ ++ div = 4; ++ break; ++ ++ case CAMIF_YCBCR422: ++ case CAMIF_YCBCR422I: ++ val = readl(cfg->regs + S3C_CIMSCTRL); ++ val = (val & ~(0x3 << 1)) | (0x2 << 1); /* YCbCr 422 Interleave */ ++ val = (val & ~(0x3 << 4)) | (0x3 << 4); /* YCbYCr */ ++ writel(val, cfg->regs + S3C_CIMSCTRL); ++ ++ div = 2; ++ break; ++ } ++ ++ area = cfg->cis->source_x * cfg->cis->source_y; ++ ++ addr_start_Y = readl(cfg->regs + S3C_MSPRY0SA); ++ addr_start_CB = addr_start_Y + area; ++ addr_start_CR = addr_start_CB + area / div; ++ ++ addr_end_Y = addr_start_Y + area; ++ addr_end_CB = addr_start_CB + area / div; ++ addr_end_CR = addr_start_CR + area / div; ++ ++ /* MSDMA memory */ ++ writel(addr_start_Y, cfg->regs + S3C_MSPRY0SA); ++ writel(addr_start_CB, cfg->regs + S3C_MSPRCB0SA); ++ writel(addr_start_CR, cfg->regs + S3C_MSPRCR0SA); ++ ++ writel(addr_end_Y, cfg->regs + S3C_MSPRY0END); ++ writel(addr_end_CB, cfg->regs + S3C_MSPRCB0END); ++ writel(addr_end_CR, cfg->regs + S3C_MSPRCR0END); ++ ++ /* MSDMA memory offset */ ++ writel(0, cfg->regs + S3C_MSPRYOFF); ++ writel(0, cfg->regs + S3C_MSPRCBOFF); ++ writel(0, cfg->regs + S3C_MSPRCROFF); ++ ++ /* MSDMA for codec source image width */ ++ val_width = readl(cfg->regs + S3C_MSPRWIDTH); ++ val_width &= ~(0x1 << 31); /* AutoLoadEnable */ ++ val_width &= ~0x0fffffff; ++ val_width |= cfg->cis->source_y << 16; /* MSCOHEIGHT */ ++ val_width |= cfg->cis->source_x; /* MSCOWIDTH */ ++ writel(val_width, cfg->regs + S3C_MSPRWIDTH); ++ ++ return ret; ++} ++ ++static int s3c_camif_input_msdma(camif_cfg_t *cfg) ++{ ++ if (cfg->input_channel == MSDMA_FROM_PREVIEW) ++ s3c_camif_input_msdma_preview(cfg); ++ else if (cfg->input_channel == MSDMA_FROM_CODEC) ++ s3c_camif_input_msdma_codec(cfg); ++ ++ return 0; ++} ++#endif ++ ++static int s3c_camif_input_camera(camif_cfg_t *cfg) ++{ ++ unsigned int val; ++ ++ s3c_camif_set_offset(cfg->cis); ++ ++ if (cfg->dma_type & CAMIF_CODEC) { ++#if defined(CONFIG_CPU_S3C6400) || defined(CONFIG_CPU_S3C6410) ++ val = readl(cfg->regs + S3C_MSCOCTRL); ++ val &= ~(1 << 3); ++ writel(val, cfg->regs + S3C_MSCOCTRL); ++#endif ++ } else if (cfg->dma_type & CAMIF_PREVIEW) { ++#if defined(CONFIG_CPU_S3C2443) || defined(CONFIG_CPU_S3C2450) ++ val = readl(cfg->regs + S3C_CIMSCTRL); ++ val &= ~(1 << 2); ++ writel(val, cfg->regs + S3C_CIMSCTRL); ++#elif defined(CONFIG_CPU_S3C6400) ++ val = readl(cfg->regs + S3C_CIMSCTRL); ++ val &= ~(1 << 3); ++ writel(val, cfg->regs + S3C_CIMSCTRL); ++#endif ++ } else ++ printk(KERN_ERR "Invalid DMA type\n"); ++ ++ return 0; ++} ++ ++static int s3c_camif_setup_input_path(camif_cfg_t *cfg) ++{ ++ if (cfg->input_channel == CAMERA_INPUT) ++ s3c_camif_input_camera(cfg); ++ else ++ s3c_camif_input_msdma(cfg); ++ ++ return 0; ++} ++ ++/************************************************************************* ++ * Output path part ++ ************************************************************************/ ++static int s3c_camif_output_pp_codec_rgb(camif_cfg_t *cfg) ++{ ++ int i; ++ unsigned int val; ++ unsigned int area = cfg->target_x * cfg->target_y; ++ ++ if (cfg->dst_fmt & CAMIF_RGB24) ++ area = area * 4; ++ else { ++ assert (cfg->dst_fmt & CAMIF_RGB16); ++ area = area * 2; ++ } ++ ++ if ((area % PAGE_SIZE) != 0) { ++ i = area / PAGE_SIZE; ++ area = (i + 1) * PAGE_SIZE; ++ } ++ ++ cfg->buffer_size = area; ++ ++ if (cfg->input_channel == MSDMA_FROM_CODEC) { ++{ ++void __iomem *S3C24XX_VA_LCD = ioremap(S3C64XX_PA_FB, 1024*1024); ++ val = readl(S3C_VIDW00ADD0B0); ++} ++ ++ for (i = 0; i < 4; i++) ++ writel(val, cfg->regs + S3C_CICOYSA(i)); ++ } else { ++ switch ( cfg->pp_num ) { ++ case 1: ++ for (i = 0; i < 4; i++) { ++ cfg->img_buf[i].virt_rgb = cfg->pp_virt_buf; ++ cfg->img_buf[i].phys_rgb = cfg->pp_phys_buf; ++ writel(cfg->img_buf[i].phys_rgb, ++ cfg->regs + S3C_CICOYSA(i)); ++ } ++ ++ break; ++ ++ case 2: ++ for (i = 0; i < 4; i++) { ++ cfg->img_buf[i].virt_rgb = cfg->pp_virt_buf; ++ cfg->img_buf[i].phys_rgb = cfg->pp_phys_buf; ++ if (i & 1) { ++ cfg->img_buf[i].virt_rgb += area; ++ cfg->img_buf[i].phys_rgb += area; ++ } ++ writel(cfg->img_buf[i].phys_rgb, ++ cfg->regs + S3C_CICOYSA(i)); ++ } ++ ++ break; ++ ++ case 4: ++ for (i = 0; i < 4; i++) { ++ cfg->img_buf[i].virt_rgb = ++ cfg->pp_virt_buf + i * area; ++ cfg->img_buf[i].phys_rgb = ++ cfg->pp_phys_buf + i * area; ++ writel(cfg->img_buf[i].phys_rgb, ++ cfg->regs + S3C_CICOYSA(i)); ++ } ++ ++ break; ++ ++ default: ++ printk(KERN_ERR "Invalid pingpong number %d\n", ++ cfg->pp_num); ++ panic("s3c camif halt\n"); ++ } ++ } ++ ++ return 0; ++} ++ ++static int s3c_camif_output_pp_codec(camif_cfg_t *cfg) ++{ ++ unsigned int i, cbcr_size = 0; ++ unsigned int area = cfg->target_x * cfg->target_y; ++ unsigned int one_p_size; ++ ++ area = cfg->target_x * cfg->target_y; ++ ++ if (cfg->dst_fmt & CAMIF_YCBCR420) ++ cbcr_size = area / 4; ++ else if (cfg->dst_fmt & CAMIF_YCBCR422 || ++ cfg->dst_fmt & CAMIF_YCBCR422I) ++ cbcr_size = area / 2; ++ else if ((cfg->dst_fmt & CAMIF_RGB16) || (cfg->dst_fmt & CAMIF_RGB24)) { ++ s3c_camif_output_pp_codec_rgb(cfg); ++ return 0; ++ } else ++ printk(KERN_ERR "Invalid target format %d\n", cfg->dst_fmt); ++ ++ one_p_size = area + 2 * cbcr_size; ++ ++ if ((one_p_size % PAGE_SIZE) != 0) { ++ i = one_p_size / PAGE_SIZE; ++ one_p_size = (i + 1) * PAGE_SIZE; ++ } ++ ++ cfg->buffer_size = one_p_size; ++ ++ switch (cfg->pp_num) { ++ case 1 : ++ for (i = 0; i < 4; i++) { ++ cfg->img_buf[i].virt_y = cfg->pp_virt_buf; ++ cfg->img_buf[i].phys_y = cfg->pp_phys_buf; ++ cfg->img_buf[i].virt_cb = cfg->pp_virt_buf + area; ++ cfg->img_buf[i].phys_cb = cfg->pp_phys_buf + area; ++ cfg->img_buf[i].virt_cr = cfg->pp_virt_buf + area + cbcr_size; ++ cfg->img_buf[i].phys_cr = cfg->pp_phys_buf + area + cbcr_size; ++ writel(cfg->img_buf[i].phys_y, cfg->regs + S3C_CICOYSA(i)); ++ writel(cfg->img_buf[i].phys_cb, cfg->regs + S3C_CICOCBSA(i)); ++ writel(cfg->img_buf[i].phys_cr, cfg->regs + S3C_CICOCRSA(i)); ++ } ++ ++ break; ++ ++ case 2: ++ for (i = 0; i < 4; i++) { ++ cfg->img_buf[i].virt_y = cfg->pp_virt_buf; ++ cfg->img_buf[i].phys_y = cfg->pp_phys_buf; ++ cfg->img_buf[i].virt_cb = cfg->pp_virt_buf + area; ++ cfg->img_buf[i].phys_cb = cfg->pp_phys_buf + area; ++ cfg->img_buf[i].virt_cr = ++ cfg->pp_virt_buf + area + cbcr_size; ++ cfg->img_buf[i].phys_cr = ++ cfg->pp_phys_buf + area + cbcr_size; ++ ++ if (i & 1) { ++ cfg->img_buf[i].virt_y += one_p_size; ++ cfg->img_buf[i].phys_y += one_p_size; ++ cfg->img_buf[i].virt_cb += one_p_size; ++ cfg->img_buf[i].phys_cb += one_p_size; ++ cfg->img_buf[i].virt_cr += one_p_size; ++ cfg->img_buf[i].phys_cr += one_p_size; ++ } ++ ++ writel(cfg->img_buf[i].phys_y, ++ cfg->regs + S3C_CICOYSA(i)); ++ writel(cfg->img_buf[i].phys_cb, ++ cfg->regs + S3C_CICOCBSA(i)); ++ writel(cfg->img_buf[i].phys_cr, ++ cfg->regs + S3C_CICOCRSA(i)); ++ } ++ ++ break; ++ ++ case 4: ++ for (i = 0; i < 4; i++) { ++ cfg->img_buf[i].virt_y = ++ cfg->pp_virt_buf + i * one_p_size; ++ cfg->img_buf[i].phys_y = ++ cfg->pp_phys_buf + i * one_p_size; ++ cfg->img_buf[i].virt_cb = ++ cfg->pp_virt_buf + area + i * one_p_size; ++ cfg->img_buf[i].phys_cb = ++ cfg->pp_phys_buf + area + i * one_p_size; ++ cfg->img_buf[i].virt_cr = cfg->pp_virt_buf + ++ area + cbcr_size + i * one_p_size; ++ cfg->img_buf[i].phys_cr = cfg->pp_phys_buf + ++ area + cbcr_size + i * one_p_size; ++ writel(cfg->img_buf[i].phys_y, ++ cfg->regs + S3C_CICOYSA(i)); ++ writel(cfg->img_buf[i].phys_cb, ++ cfg->regs + S3C_CICOCBSA(i)); ++ writel(cfg->img_buf[i].phys_cr, ++ cfg->regs + S3C_CICOCRSA(i)); ++ } ++ ++ break; ++ ++ default: ++ printk(KERN_ERR "Invalid pingpong number %d\n", cfg->pp_num); ++ } ++ ++ return 0; ++} ++ ++#if defined(CONFIG_CPU_S3C2443) || defined(CONFIG_CPU_S3C2450) || defined(CONFIG_CPU_S3C2416) ++static int s3c_camif_io_duplex_preview(camif_cfg_t *cfg) ++{ ++ unsigned int cbcr_size = 0; ++ unsigned int area = cfg->cis->source_x * cfg->cis->source_y; ++ unsigned int val; ++ int i; ++ ++ val = readl(S3C_VIDW01ADD0); ++ ++ if (!((cfg->dst_fmt & CAMIF_RGB16) || (cfg->dst_fmt & CAMIF_RGB24))) ++ printk(KERN_ERR "Invalid target format\n"); ++ ++ for (i = 0; i < 4; i++) ++ writel(val, cfg->regs + S3C_CIPRYSA(i)); ++ ++ if (cfg->src_fmt & CAMIF_YCBCR420) { ++ cbcr_size = area / 4; ++ cfg->img_buf[0].virt_cb = cfg->pp_virt_buf + area; ++ cfg->img_buf[0].phys_cb = cfg->pp_phys_buf + area; ++ cfg->img_buf[0].virt_cr = cfg->pp_virt_buf + area + cbcr_size; ++ cfg->img_buf[0].phys_cr = cfg->pp_phys_buf + area + cbcr_size; ++ } else if (cfg->src_fmt & CAMIF_YCBCR422 || cfg->dst_fmt & CAMIF_YCBCR422I) { ++ area = area * 2; ++ cfg->img_buf[0].virt_cb = 0; ++ cfg->img_buf[0].phys_cb = 0; ++ cfg->img_buf[0].virt_cr = 0; ++ cfg->img_buf[0].phys_cr = 0; ++ } ++ ++ cfg->img_buf[0].virt_y = cfg->pp_virt_buf; ++ cfg->img_buf[0].phys_y = cfg->pp_phys_buf; ++ ++ writel(cfg->img_buf[0].phys_y, cfg->regs + S3C_CIMSYSA); ++ writel(cfg->img_buf[0].phys_y + area, cfg->regs + S3C_CIMSYEND); ++ ++ writel(cfg->img_buf[0].phys_cb, cfg->regs + S3C_CIMSCBSA); ++ writel(cfg->img_buf[0].phys_cb + cbcr_size, cfg->regs + S3C_CIMSCBEND); ++ ++ writel(cfg->img_buf[0].phys_cr, cfg->regs + S3C_CIMSCRSA); ++ writel(cfg->img_buf[0].phys_cr + cbcr_size, cfg->regs + S3C_CIMSCREND); ++ ++ writel(cfg->cis->source_x, cfg->regs + S3C_CIMSWIDTH); ++ ++ return 0; ++} ++#elif defined(CONFIG_CPU_S3C6400) || defined(CONFIG_CPU_S3C6410) ++static int s3c_camif_io_duplex_preview(camif_cfg_t *cfg) ++{ ++ unsigned int cbcr_size = 0; ++ unsigned int area = cfg->cis->source_x * cfg->cis->source_y; ++ unsigned int val; ++ int i; ++ ++{ ++void __iomem *S3C24XX_VA_LCD = ioremap(S3C64XX_PA_FB, 1024*1024); ++ val = readl(S3C_VIDW01ADD0B0); ++} ++ ++ if (!((cfg->dst_fmt & CAMIF_RGB16) || (cfg->dst_fmt & CAMIF_RGB24))) ++ printk(KERN_ERR "Invalid target format\n"); ++ ++ for (i = 0; i < 4; i++) ++ writel(val, cfg->regs + S3C_CIPRYSA(i)); ++ ++ if (cfg->src_fmt & CAMIF_YCBCR420) { ++ cbcr_size = area / 4; ++ cfg->img_buf[0].virt_cb = cfg->pp_virt_buf + area; ++ cfg->img_buf[0].phys_cb = cfg->pp_phys_buf + area; ++ cfg->img_buf[0].virt_cr = cfg->pp_virt_buf + area + cbcr_size; ++ cfg->img_buf[0].phys_cr = cfg->pp_phys_buf + area + cbcr_size; ++ } else if (cfg->src_fmt & CAMIF_YCBCR422 || ++ cfg->dst_fmt & CAMIF_YCBCR422I) { ++ area = area * 2; ++ cfg->img_buf[0].virt_cb = 0; ++ cfg->img_buf[0].phys_cb = 0; ++ cfg->img_buf[0].virt_cr = 0; ++ cfg->img_buf[0].phys_cr = 0; ++ } ++ ++ cfg->img_buf[0].virt_y = cfg->pp_virt_buf; ++ cfg->img_buf[0].phys_y = cfg->pp_phys_buf; ++ ++ writel(cfg->img_buf[0].phys_y, cfg->regs + S3C_MSPRY0SA); ++ writel(cfg->img_buf[0].phys_y + area, cfg->regs + S3C_MSPRY0END); ++ ++ writel(cfg->img_buf[0].phys_cb, cfg->regs + S3C_MSPRCB0SA); ++ writel(cfg->img_buf[0].phys_cb + cbcr_size, cfg->regs + S3C_MSPRCB0END); ++ ++ writel(cfg->img_buf[0].phys_cr, cfg->regs + S3C_MSPRCR0SA); ++ writel(cfg->img_buf[0].phys_cr + cbcr_size, cfg->regs + S3C_MSPRCR0END); ++ ++ val = readl(cfg->regs + S3C_MSCOWIDTH); ++ val |= 0x1 << 31; ++ val |= cfg->cis->source_y << 16; ++ val |= cfg->cis->source_x; ++ writel(val, cfg->regs + S3C_MSPRWIDTH); ++ ++ return 0; ++} ++#endif ++ ++static int s3c_camif_output_pp_preview(camif_cfg_t *cfg) ++{ ++ int i; ++ unsigned int cbcr_size = 0; ++ unsigned int area = cfg->target_x * cfg->target_y; ++ ++ if (cfg->input_channel) { ++ s3c_camif_io_duplex_preview(cfg); ++ return 0; ++ } ++ ++ if (cfg->dst_fmt & CAMIF_YCBCR420) ++ cbcr_size = area / 4; ++ else if (cfg->dst_fmt & CAMIF_YCBCR422 || ++ cfg->dst_fmt & CAMIF_YCBCR422I) ++ cbcr_size = area / 2; ++ else if (cfg->dst_fmt & CAMIF_RGB24) ++ area = area * 4; ++ else if (cfg->dst_fmt & CAMIF_RGB16) ++ area = area * 2; ++ else ++ printk(KERN_ERR "Invalid target format %d\n", cfg->dst_fmt); ++ ++ if ((area % PAGE_SIZE) != 0) { ++ i = area / PAGE_SIZE; ++ area = (i + 1) * PAGE_SIZE; ++ } ++ ++ cfg->buffer_size = area; ++ ++ switch (cfg->pp_num) { ++ case 1: ++ for (i = 0; i < 4; i++) { ++ cfg->img_buf[i].virt_rgb = cfg->pp_virt_buf; ++ cfg->img_buf[i].phys_rgb = cfg->pp_phys_buf; ++ writel(cfg->img_buf[i].phys_rgb, ++ cfg->regs + S3C_CIPRYSA(i)); ++ } ++ ++ break; ++ ++ case 2: ++ for (i = 0; i < 4; i++) { ++ cfg->img_buf[i].virt_rgb = cfg->pp_virt_buf; ++ cfg->img_buf[i].phys_rgb = cfg->pp_phys_buf; ++ if (i & 1) { ++ cfg->img_buf[i].virt_rgb += area; ++ cfg->img_buf[i].phys_rgb += area; ++ } ++ ++ writel(cfg->img_buf[i].phys_rgb, ++ cfg->regs + S3C_CIPRYSA(i)); ++ } ++ ++ break; ++ ++ case 4: ++ for (i = 0; i < 4; i++) { ++ cfg->img_buf[i].virt_rgb = cfg->pp_virt_buf + i * area; ++ cfg->img_buf[i].phys_rgb = cfg->pp_phys_buf + i * area; ++ writel(cfg->img_buf[i].phys_rgb, ++ cfg->regs + S3C_CIPRYSA(i)); ++ } ++ ++ break; ++ ++ default: ++ printk(KERN_ERR "Invalid pingpong number %d\n", cfg->pp_num); ++ } ++ ++ return 0; ++} ++ ++static int s3c_camif_output_pp(camif_cfg_t *cfg) ++{ ++ if (cfg->dma_type & CAMIF_CODEC) ++ s3c_camif_output_pp_codec(cfg); ++ else if (cfg->dma_type & CAMIF_PREVIEW) ++ s3c_camif_output_pp_preview(cfg); ++ ++ return 0; ++} ++ ++static int s3c_camif_output_lcd(camif_cfg_t *cfg) ++{ ++ /* To Be Implemented */ ++ return 0; ++} ++ ++static int s3c_camif_setup_output_path(camif_cfg_t *cfg) ++{ ++ if (cfg->output_channel == CAMIF_OUT_FIFO) ++ s3c_camif_output_lcd(cfg); ++ else ++ s3c_camif_output_pp(cfg); ++ ++ return 0; ++} ++ ++/************************************************************************* ++ * Scaler part ++ ************************************************************************/ ++static int s3c_camif_set_target_area(camif_cfg_t *cfg) ++{ ++ unsigned int rect = cfg->target_x * cfg->target_y; ++ ++ if (cfg->dma_type & CAMIF_CODEC) ++ writel(rect, cfg->regs + S3C_CICOTAREA); ++ else if (cfg->dma_type & CAMIF_PREVIEW) ++ writel(rect, cfg->regs + S3C_CIPRTAREA); ++ ++ return 0; ++} ++ ++#if defined(CONFIG_CPU_S3C6400) || defined(CONFIG_CPU_S3C6410) ++static inline int s3c_camif_set_ratio(camif_cfg_t *cfg) ++{ ++ unsigned int cmd = ++ S3C_CICOSCCTRL_CSCR2Y_WIDE | S3C_CICOSCCTRL_CSCY2R_WIDE; ++ ++ if (cfg->dma_type & CAMIF_CODEC) { ++ ++ writel(S3C_CICOSCPRERATIO_SHFACTOR_CO(cfg->sc.shfactor) | ++ S3C_CICOSCPRERATIO_PREHORRATIO_CO(cfg->sc.prehratio) | ++ S3C_CICOSCPRERATIO_PREVERRATIO_CO(cfg->sc.prevratio), ++ cfg->regs + S3C_CICOSCPRERATIO); ++ ++ writel(S3C_CICOSCPREDST_PREDSTWIDTH_CO(cfg->sc.predst_x) | ++ S3C_CICOSCPREDST_PREDSTHEIGHT_CO(cfg->sc.predst_y), ++ cfg->regs + S3C_CICOSCPREDST); ++ ++ /* Differ from Preview */ ++ if (cfg->sc.scalerbypass) ++ cmd |= S3C_CICOSCCTRL_SCALERBYPASS_CO; ++ ++ /* Differ from Codec */ ++ if (cfg->dst_fmt & CAMIF_RGB24) ++ cmd |= S3C_CICOSCCTRL_OUTRGB_FMT_RGB888; ++ else ++ cmd |= S3C_CICOSCCTRL_OUTRGB_FMT_RGB565; ++ ++ if (cfg->sc.scaleup_h & cfg->sc.scaleup_v) ++ cmd |= ++ S3C_CICOSCCTRL_SCALEUP_H | S3C_CICOSCCTRL_SCALEUP_V; ++ ++ writel(cmd | ++ S3C_CICOSCCTRL_MAINHORRATIO_CO(cfg->sc.mainhratio) | ++ S3C_CICOSCCTRL_MAINVERRATIO_CO(cfg->sc.mainvratio), ++ cfg->regs + S3C_CICOSCCTRL); ++ ++ } else if (cfg->dma_type & CAMIF_PREVIEW) { ++ writel(S3C_CIPRSCPRERATIO_SHFACTOR_PR(cfg->sc.shfactor) | ++ S3C_CIPRSCPRERATIO_PREHORRATIO_PR(cfg->sc.prehratio) | ++ S3C_CIPRSCPRERATIO_PREVERRATIO_PR(cfg->sc.prevratio), ++ cfg->regs + S3C_CIPRSCPRERATIO); ++ ++ writel(S3C_CIPRSCPREDST_PREDSTWIDTH_PR(cfg->sc.predst_x) | ++ S3C_CIPRSCPREDST_PREDSTHEIGHT_PR(cfg->sc.predst_y), ++ cfg->regs + S3C_CIPRSCPREDST); ++ ++ if (cfg->dst_fmt & CAMIF_RGB24) ++ cmd |= S3C_CIPRSCCTRL_OUTRGB_FMT_PR_RGB888; ++ else ++ cmd |= S3C_CIPRSCCTRL_OUTRGB_FMT_PR_RGB565; ++ ++ if (cfg->sc.scaleup_h & cfg->sc.scaleup_v) ++ cmd |= (1 << 30) | (1 << 29); ++ ++ writel(cmd | ++ S3C_CIPRSCCTRL_MAINHORRATIO_PR(cfg->sc.mainhratio) | ++ S3C_CIPRSCCTRL_MAINVERRATIO_PR(cfg->sc.mainvratio), ++ cfg->regs + S3C_CIPRSCCTRL); ++ ++ } else ++ printk(KERN_ERR "Invalid DMA type\n"); ++ ++ return 0; ++} ++#elif defined(CONFIG_CPU_S3C2443) || defined(CONFIG_CPU_S3C2450) || defined(CONFIG_CPU_S3C2416) ++static inline int s3c_camif_set_ratio(camif_cfg_t *cfg) ++{ ++ u32 cmd = 0; ++ ++ if (cfg->dma_type & CAMIF_CODEC) { ++ ++ writel(S3C_CICOSCPRERATIO_SHFACTOR_CO(cfg->sc.shfactor) | ++ S3C_CICOSCPRERATIO_PREHORRATIO_CO(cfg->sc.prehratio) | ++ S3C_CICOSCPRERATIO_PREVERRATIO_CO(cfg->sc.prevratio), ++ cfg->regs + S3C_CICOSCPRERATIO); ++ ++ writel(S3C_CICOSCPREDST_PREDSTWIDTH_CO(cfg->sc.predst_x) | ++ S3C_CICOSCPREDST_PREDSTHEIGHT_CO(cfg->sc.predst_y), ++ cfg->regs + S3C_CICOSCPREDST); ++ ++ if (cfg->sc.scalerbypass) ++ cmd |= S3C_CICOSCCTRL_SCALERBYPASS_CO; ++ ++ if (cfg->sc.scaleup_h & cfg->sc.scaleup_v) ++ cmd |= ++ S3C_CICOSCCTRL_SCALEUP_H | S3C_CICOSCCTRL_SCALEUP_V; ++ ++ writel(cmd | ++ S3C_CICOSCCTRL_MAINHORRATIO_CO(cfg->sc.mainhratio) | ++ S3C_CICOSCCTRL_MAINVERRATIO_CO(cfg->sc.mainvratio), ++ cfg->regs + S3C_CICOSCCTRL); ++ ++ } else if (cfg->dma_type & CAMIF_PREVIEW) { ++ ++ cmd |= S3C_CIPRSCCTRL_SAMPLE_PR; ++ ++ writel(S3C_CIPRSCPRERATIO_SHFACTOR_PR(cfg->sc.shfactor) | ++ S3C_CIPRSCPRERATIO_PREHORRATIO_PR(cfg->sc.prehratio) | ++ S3C_CIPRSCPRERATIO_PREVERRATIO_PR(cfg->sc.prevratio), ++ cfg->regs + S3C_CIPRSCPRERATIO); ++ ++ writel(S3C_CIPRSCPREDST_PREDSTWIDTH_PR(cfg->sc.predst_x) | ++ S3C_CIPRSCPREDST_PREDSTHEIGHT_PR(cfg->sc.predst_y), ++ cfg->regs + S3C_CIPRSCPREDST); ++ ++ if (cfg->dst_fmt & CAMIF_RGB24) ++ cmd |= S3C_CIPRSCCTRL_RGBFORMAT_24; ++ ++ if (cfg->sc.scaleup_h & cfg->sc.scaleup_v) ++ cmd |= (1 << 29) | (1 << 28); ++ ++ writel(cmd | ++ S3C_CIPRSCCTRL_MAINHORRATIO_PR(cfg->sc.mainhratio) | ++ S3C_CIPRSCCTRL_MAINVERRATIO_PR(cfg->sc.mainvratio), ++ cfg->regs + S3C_CIPRSCCTRL); ++ ++ } else ++ printk(KERN_ERR "Invalid DMA type\n"); ++ ++ return 0; ++} ++#endif ++ ++static int s3c_camif_calc_ratio(unsigned int src_width, unsigned int dst_width, ++ unsigned int *ratio, unsigned int *shift) ++{ ++ if (src_width >= 64 * dst_width) { ++ printk(KERN_ERR "Out of pre-scaler range: " ++ "src_width / dst_width = %d (< 64)\n", ++ src_width / dst_width); ++ return 1; ++ } ++ if (src_width >= 32 * dst_width) { ++ *shift = 5; ++ } else if (src_width >= 16 * dst_width) { ++ *shift = 4; ++ } else if (src_width >= 8 * dst_width) { ++ *shift = 3; ++ } else if (src_width >= 4 * dst_width) { ++ *shift = 2; ++ } else if (src_width >= 2 * dst_width) { ++ *shift = 1; ++ } else { ++ *shift = 0; ++ } ++ ++ *ratio = 1 << *shift; ++ ++ return 0; ++} ++ ++static int s3c_camif_setup_scaler(camif_cfg_t *cfg) ++{ ++ int tx = cfg->target_x, ty = cfg->target_y; ++ int sx, sy; ++ ++ if (tx <= 0 || ty <= 0) { ++ printk(KERN_ERR "Invalid target size\n"); ++ return -1; ++ } ++ ++ sx = cfg->cis->source_x - ++ (cfg->cis->win_hor_ofst + cfg->cis->win_hor_ofst2); ++ sy = cfg->cis->source_y - ++ (cfg->cis->win_ver_ofst + cfg->cis->win_hor_ofst2); ++ ++ if (sx <= 0 || sy <= 0) { ++ printk(KERN_ERR "Invalid source size\n"); ++ return -1; ++ } ++ ++ cfg->sc.modified_src_x = sx; ++ cfg->sc.modified_src_y = sy; ++ ++ /* Pre-scaler control register 1 */ ++ s3c_camif_calc_ratio(sx, tx, &cfg->sc.prehratio, &cfg->sc.hfactor); ++ s3c_camif_calc_ratio(sy, ty, &cfg->sc.prevratio, &cfg->sc.vfactor); ++ ++ if (cfg->dma_type & CAMIF_PREVIEW) { ++ if (sx / cfg->sc.prehratio > 640) { ++ printk(KERN_INFO "Internal preview line buffer length " ++ "is 640 pixels\n"); ++ printk(KERN_INFO "Decrease the resolution or adjust " ++ "window offset values appropriately\n"); ++ } ++ } ++ ++ cfg->sc.shfactor = 10 - (cfg->sc.hfactor + cfg->sc.vfactor); ++ ++ /* Pre-scaler control register 2 */ ++ cfg->sc.predst_x = sx / cfg->sc.prehratio; ++ cfg->sc.predst_y = sy / cfg->sc.prevratio; ++ ++ /* Main-scaler control register */ ++ cfg->sc.mainhratio = (sx << 8) / (tx << cfg->sc.hfactor); ++ cfg->sc.mainvratio = (sy << 8) / (ty << cfg->sc.vfactor); ++ ++ cfg->sc.scaleup_h = sx <= tx; ++ cfg->sc.scaleup_v = sy <= ty; ++ ++ s3c_camif_set_ratio(cfg); ++ s3c_camif_set_target_area(cfg); ++ ++ return 0; ++} ++ ++/************************************************************************* ++ * Format part ++ ************************************************************************/ ++int s3c_camif_set_source_format(camif_cis_t *cis) ++{ ++ camif_cfg_t *cfg = s3c_camif_get_fimc_object(CODEC_MINOR); ++ unsigned int cmd = 0; ++ ++ /* Configure CISRCFMT --Source Format */ ++ if (cis->itu_fmt & CAMIF_ITU601) ++ cmd = CAMIF_ITU601; ++ else { ++ assert(cis->itu_fmt & CAMIF_ITU656); ++ cmd = CAMIF_ITU656; ++ } ++ ++ cmd |= S3C_CISRCFMT_SOURCEHSIZE(cis->source_x) | ++ S3C_CISRCFMT_SOURCEVSIZE(cis->source_y); ++ ++ /* Order422 */ ++ cmd |= cis->order422; ++ writel(cmd, cfg->regs + S3C_CISRCFMT); ++ ++#if defined(CONFIG_CPU_S3C6400) || defined(CONFIG_CPU_S3C6410) ++ cmd = cis->order422 >> 14; ++ writel((readl(cfg->regs + S3C_CICOCTRL) & ~(0x3 << 0)) | cmd, ++ cfg->regs + S3C_CICOCTRL); ++#endif ++ ++ return 0; ++} ++ ++#if defined(CONFIG_CPU_S3C2443) || defined(CONFIG_CPU_S3C2450) || defined(CONFIG_CPU_S3C2416) ++static int s3c_camif_set_target_format(camif_cfg_t *cfg) ++{ ++ unsigned int cmd = 0; ++ ++ if (cfg->dma_type & CAMIF_CODEC) { ++ cmd |= S3C_CICOTRGFMT_TARGETHSIZE_CO(cfg->target_x) | ++ S3C_CICOTRGFMT_TARGETVSIZE_CO(cfg->target_y); ++ ++ if (cfg->dst_fmt & CAMIF_YCBCR420) ++ cmd |= S3C_CICOTRGFMT_OUT422_420 | ++ S3C_CICOTRGFMT_IN422_422; ++ else if (cfg->dst_fmt & CAMIF_YCBCR422) ++ cmd |= (S3C_CICOTRGFMT_OUT422_422 | ++ S3C_CICOTRGFMT_IN422_422); ++ else if ((cfg->dst_fmt & CAMIF_RGB24) || ++ (cfg->dst_fmt & CAMIF_RGB16)) ++ cmd |= (S3C_CICOTRGFMT_OUT422_422 | ++ S3C_CICOTRGFMT_IN422_422) | (1 << 29); ++ else ++ printk(KERN_ERR "Invalid target format\n"); ++ writel(cmd, cfg->regs + S3C_CICOTRGFMT); ++ } else { ++ assert(cfg->dma_type & CAMIF_PREVIEW); ++ ++ cmd = readl(cfg->regs + S3C_CIPRTRGFMT); ++ cmd &= ~(S3C_CIPRTRGFMT_TARGETHSIZE_PR(0x1fff) | ++ S3C_CIPRTRGFMT_TARGETVSIZE_PR(0x1fff)); ++ cmd |= S3C_CIPRTRGFMT_TARGETHSIZE_PR(cfg->target_x) | ++ S3C_CIPRTRGFMT_TARGETVSIZE_PR(cfg->target_y); ++ ++ writel(cmd | (2 << 30), cfg->regs + S3C_CIPRTRGFMT); ++ } ++ ++ return 0; ++} ++#elif defined(CONFIG_CPU_S3C6400) || defined(CONFIG_CPU_S3C6410) ++static int s3c_camif_set_target_format(camif_cfg_t *cfg) ++{ ++ unsigned int cmd = 0; ++ ++ if (cfg->dma_type & CAMIF_CODEC) { ++ cmd |= S3C_CICOTRGFMT_TARGETHSIZE_CO(cfg->target_x) | ++ S3C_CICOTRGFMT_TARGETVSIZE_CO(cfg->target_y); ++ ++ if (cfg->dst_fmt & CAMIF_YCBCR420) ++ cmd |= S3C_CICOTRGFMT_OUTFORMAT_YCBCR420OUT; ++ else if (cfg->dst_fmt & CAMIF_YCBCR422) ++ cmd |= S3C_CICOTRGFMT_OUTFORMAT_YCBCR422OUT; ++ else if (cfg->dst_fmt & CAMIF_YCBCR422I) ++ cmd |= S3C_CICOTRGFMT_OUTFORMAT_YCBCR422OUTINTERLEAVE; ++ else if ((cfg->dst_fmt & CAMIF_RGB24) || ++ (cfg->dst_fmt & CAMIF_RGB16)) ++ cmd |= S3C_CICOTRGFMT_OUTFORMAT_RGBOUT; ++ else ++ printk(KERN_ERR "Invalid target format\n"); ++ writel(cmd, cfg->regs + S3C_CICOTRGFMT); ++ } else { ++ assert(cfg->dma_type & CAMIF_PREVIEW); ++ ++ cmd = readl(cfg->regs + S3C_CIPRTRGFMT); ++ cmd &= ~(S3C_CIPRTRGFMT_TARGETHSIZE_PR(0x1fff) | ++ S3C_CIPRTRGFMT_TARGETVSIZE_PR(0x1fff)); ++ cmd |= S3C_CIPRTRGFMT_TARGETHSIZE_PR(cfg->target_x) | ++ S3C_CIPRTRGFMT_TARGETVSIZE_PR(cfg->target_y); ++ ++ if (cfg->dst_fmt & CAMIF_YCBCR420) ++ cmd |= S3C_CICOTRGFMT_OUTFORMAT_YCBCR420OUT; ++ else if (cfg->dst_fmt & CAMIF_YCBCR422) ++ cmd |= S3C_CICOTRGFMT_OUTFORMAT_YCBCR422OUT; ++ else if (cfg->dst_fmt & CAMIF_YCBCR422I) ++ cmd |= S3C_CICOTRGFMT_OUTFORMAT_YCBCR422OUTINTERLEAVE; ++ else if ((cfg->dst_fmt & CAMIF_RGB24) || ++ (cfg->dst_fmt & CAMIF_RGB16)) ++ cmd |= S3C_CICOTRGFMT_OUTFORMAT_RGBOUT; ++ else ++ printk(KERN_ERR "Invalid target format\n"); ++ ++ writel(cmd, cfg->regs + S3C_CIPRTRGFMT); ++ } ++ ++ return 0; ++} ++#endif ++ ++/************************************************************************* ++ * Control part ++ ************************************************************************/ ++int s3c_camif_control_fimc(camif_cfg_t *cfg) ++{ ++ if (s3c_camif_request_memory(cfg)) { ++ printk(KERN_ERR "Instead of using consistent_alloc(). " ++ "Let me use dedicated mem for DMA\n"); ++ return -1; ++ } ++ ++ s3c_camif_setup_input_path(cfg); ++ ++ if (s3c_camif_setup_scaler(cfg)) { ++ printk(KERN_ERR "Preview scaler fault: " ++ "change WinHorOfset or target size\n"); ++ return 1; ++ } ++ ++ s3c_camif_set_target_format(cfg); ++ ++ if (s3c_camif_setup_dma(cfg)) { ++ printk(KERN_ERR "DMA burst length error\n"); ++ return 1; ++ } ++ ++ s3c_camif_setup_output_path(cfg); ++ ++ return 0; ++} ++ ++int s3c_camif_start_dma(camif_cfg_t *cfg) ++{ ++ unsigned int n_cmd = readl(cfg->regs + S3C_CIIMGCPT); ++ unsigned int val; ++ ++ switch(cfg->capture_enable) { ++ case CAMIF_BOTH_DMA_ON: ++ s3c_camif_reset(CAMIF_RESET, 0); /* Flush Camera Core Buffer */ ++ ++ /* For Codec */ ++ val = readl(cfg->regs + S3C_CICOSCCTRL); ++ val |= S3C_CICOSCCTRL_COSCALERSTART; ++ writel(val, cfg->regs + S3C_CICOSCCTRL); ++ ++ /* For Preview */ ++ val = readl(cfg->regs + S3C_CIPRSCCTRL); ++ val |= S3C_CIPRSCCTRL_START; ++ writel(val, cfg->regs + S3C_CIPRSCCTRL); ++ ++ n_cmd |= ++ S3C_CIIMGCPT_IMGCPTEN_COSC | S3C_CIIMGCPT_IMGCPTEN_PRSC; ++ break; ++ ++ case CAMIF_DMA_ON: ++ s3c_camif_reset(CAMIF_RESET, 0); /* Flush Camera Core Buffer */ ++ ++ if (cfg->dma_type & CAMIF_CODEC) { ++ val = readl(cfg->regs + S3C_CICOSCCTRL); ++ val |= S3C_CICOSCCTRL_COSCALERSTART; ++ writel(val, cfg->regs + S3C_CICOSCCTRL); ++ ++ n_cmd |= S3C_CIIMGCPT_IMGCPTEN_COSC; ++ ++#if defined(CONFIG_CPU_S3C2443) || defined(CONFIG_CPU_S3C2450) || defined(CONFIG_CPU_S3C2416) ++ n_cmd |= (1 << 24); ++#endif ++ } else { ++ val = readl(cfg->regs + S3C_CIPRSCCTRL); ++ val |= S3C_CIPRSCCTRL_START; ++ writel(val, cfg->regs + S3C_CIPRSCCTRL); ++ n_cmd |= S3C_CIIMGCPT_IMGCPTEN_PRSC; ++ } ++ ++ /* wait until Sync Time expires */ ++ /* First settting, to wait VSYNC fall */ ++ /* By VESA spec,in 640x480 @60Hz ++ MAX Delay Time is around 64us which "while" has.*/ ++ while (S3C_CICOSTATUS_VSYNC & ++ readl(cfg->regs + S3C_CICOSTATUS)); ++ break; ++ ++ default: ++ break; ++ } ++ ++#if defined(CONFIG_CPU_S3C2443) ++ if (cfg->dma_type & CAMIF_CODEC) { ++ if (cfg->dst_fmt & CAMIF_RGB24) ++ n_cmd |= 3 << 25; ++ else if (cfg->dst_fmt & CAMIF_RGB16) ++ n_cmd |= 1 << 25; ++ else if (cfg->dst_fmt & CAMIF_YCBCR420) ++ n_cmd |= 2 << 25; ++ } ++#endif ++ ++ val = readl(cfg->regs + S3C_CIIMGCPT); ++ val &= ~(0x7 << 29); ++ writel(val | n_cmd | S3C_CIIMGCPT_IMGCPTEN, cfg->regs + S3C_CIIMGCPT); ++ ++ return 0; ++} ++ ++int s3c_camif_stop_dma(camif_cfg_t *cfg) ++{ ++ unsigned int n_cmd = readl(cfg->regs + S3C_CIIMGCPT); ++ unsigned int val; ++ ++ switch(cfg->capture_enable) { ++ case CAMIF_BOTH_DMA_OFF: ++ val = readl(cfg->regs + S3C_CICOSCCTRL); ++ val &= ~S3C_CICOSCCTRL_COSCALERSTART; ++ writel(val, cfg->regs + S3C_CICOSCCTRL); ++ ++ val = readl(cfg->regs + S3C_CIPRSCCTRL); ++ val &= ~S3C_CIPRSCCTRL_START; ++ writel(val, cfg->regs + S3C_CIPRSCCTRL); ++ ++ n_cmd = 0; ++ break; ++ ++ case CAMIF_DMA_OFF_L_IRQ: /* fall thru */ ++ case CAMIF_DMA_OFF: ++ if (cfg->dma_type & CAMIF_CODEC) { ++ val = readl(cfg->regs + S3C_CICOSCCTRL); ++ val &= ~S3C_CICOSCCTRL_COSCALERSTART; ++ writel(val, cfg->regs + S3C_CICOSCCTRL); ++ n_cmd &= ~S3C_CIIMGCPT_IMGCPTEN_COSC; ++ ++ if (!(n_cmd & S3C_CIIMGCPT_IMGCPTEN_PRSC)) ++ n_cmd = 0; ++ } else { ++ val = readl(cfg->regs + S3C_CIPRSCCTRL); ++ val &= ~S3C_CIPRSCCTRL_START; ++ writel(val, cfg->regs + S3C_CIPRSCCTRL); ++ ++ n_cmd &= ~S3C_CIIMGCPT_IMGCPTEN_PRSC; ++ ++ if (!(n_cmd & S3C_CIIMGCPT_IMGCPTEN_COSC)) ++ n_cmd = 0; ++ } ++ ++ break; ++ ++ default: ++ printk(KERN_ERR "Unexpected DMA control\n"); ++ } ++ ++ writel(n_cmd, cfg->regs + S3C_CIIMGCPT); ++ ++ if (cfg->capture_enable == CAMIF_DMA_OFF_L_IRQ) { /* Last IRQ */ ++ if (cfg->dma_type & CAMIF_CODEC) { ++ val = readl(cfg->regs + S3C_CICOCTRL); ++ val |= S3C_CICOCTRL_LASTIRQEN; ++ writel(val, cfg->regs + S3C_CICOCTRL); ++ } else { ++ val = readl(cfg->regs + S3C_CIPRCTRL); ++ val |= S3C_CIPRCTRL_LASTIRQEN_ENABLE; ++ writel(val, cfg->regs + S3C_CIPRCTRL); ++ } ++ } ++ ++ return 0; ++} ++ ++#if defined(CONFIG_CPU_S3C6400) || defined(CONFIG_CPU_S3C6410) ++int s3c_camif_start_codec_msdma(camif_cfg_t *cfg) ++{ ++ int ret = 0; ++ u32 val; ++ ++ val = readl(cfg->regs + S3C_MSCOCTRL); ++ val &= ~(1 << 0); ++ writel(val, cfg->regs + S3C_MSCOCTRL); ++ ++ val = readl(cfg->regs + S3C_MSCOCTRL); ++ val |= (1 << 0); ++ writel(val, cfg->regs + S3C_MSCOCTRL); ++ ++ return ret; ++} ++#endif ++ ++int s3c_camif_start_preview_msdma(camif_cfg_t * cfg) ++{ ++ unsigned int val; ++ int ret = 0; ++ ++#if !defined(CONFIG_CPU_S3C6400) && !defined(CONFIG_CPU_S3C6410) ++ val = readl(cfg->regs + S3C_CIMSCTRL); ++ val &= ~(1 << 0); ++ writel(val, cfg->regs + S3C_CIMSCTRL); ++#endif ++ val = readl(cfg->regs + S3C_CIMSCTRL); ++ val |= (1 << 0); ++ writel(val, cfg->regs + S3C_CIMSCTRL); ++ ++ while(!readl(cfg->regs + S3C_CIMSCTRL) & (1 << 6)); ++ ++ return ret; ++} ++ ++void s3c_camif_change_flip(camif_cfg_t *cfg) ++{ ++ unsigned int cmd = 0; ++ ++ if (cfg->dma_type & CAMIF_CODEC) { ++ cmd = readl(cfg->regs + S3C_CICOTRGFMT); ++ cmd &= ~((1 << 14) | (1 << 15)); ++ cmd |= cfg->flip; ++ writel(cmd, cfg->regs + S3C_CICOTRGFMT); ++ } else { ++ /* if ROT90_Pr == 1, dma burst length must be 4 */ ++ if (cfg->flip == CAMIF_ROTATE_90 || ++ cfg->flip == CAMIF_FLIP_ROTATE_270) { ++ cmd = readl(cfg->regs + S3C_CIPRCTRL); ++ cmd &= ~(0x3ff << 14); ++ cmd |= (S3C_CICOCTRL_YBURST1_CO(4) | ++ S3C_CICOCTRL_YBURST2_CO(4)); ++ writel(cmd, cfg->regs + S3C_CIPRCTRL); ++ } ++ ++ cmd = readl(cfg->regs + S3C_CIPRTRGFMT); ++ cmd &= ~(0x7 << 13); ++ cmd |= cfg->flip; ++ writel(cmd, cfg->regs + S3C_CIPRTRGFMT); ++ } ++} ++ ++void s3c_camif_change_effect(camif_cfg_t *cfg) ++{ ++ unsigned int val = readl(cfg->regs + S3C_CIIMGEFF); ++ ++ val &= ~((1 << 28) | (1 << 27) | (1 << 26)); ++ ++#if defined(CONFIG_CPU_S3C6400) || defined(CONFIG_CPU_S3C6410) ++ val |= ((1 << 31) | (1 << 30)); ++#endif ++ ++ switch(cfg->effect) { ++ case CAMIF_SILHOUETTE: ++ val |= S3C_CIIMGEFF_FIN_SILHOUETTE; ++ break; ++ ++ case CAMIF_EMBOSSING: ++ val |= S3C_CIIMGEFF_FIN_EMBOSSING; ++ break; ++ ++ case CAMIF_ART_FREEZE: ++ val |= S3C_CIIMGEFF_FIN_ARTFREEZE; ++ break; ++ ++ case CAMIF_NEGATIVE: ++ val |= S3C_CIIMGEFF_FIN_NEGATIVE; ++ break; ++ ++ case CAMIF_ARBITRARY_CB_CR: ++ val |= S3C_CIIMGEFF_FIN_ARBITRARY; ++ break; ++ ++ case CAMIF_BYPASS: ++ default: ++ break; ++ } ++ ++ writel(val, cfg->regs + S3C_CIIMGEFF); ++} ++ ++int s3c_camif_do_postprocess(camif_cfg_t *cfg) ++{ ++ unsigned int val = readl(cfg->regs + S3C_CIMSCTRL); ++ ++ if (cfg->dst_fmt & CAMIF_YCBCR420) ++ val |= 1 << 1; ++ else ++ val &= ~(1 << 1); ++ ++ val &= ~(1 << 0); ++ writel(val, cfg->regs + S3C_CIMSCTRL); ++ ++ val |= 1 << 0; ++ writel(val, cfg->regs + S3C_CIMSCTRL); ++ ++ printk(KERN_INFO "Postprocessing started\n"); ++ ++ while(!readl(cfg->regs + S3C_CIMSCTRL) & (1 << 6)); ++ ++ printk(KERN_INFO "Postprocessing finished\n"); ++ ++ return 0; ++} ++ ++int s3c_camif_set_offset(camif_cis_t *cis) ++{ ++ camif_cfg_t *cfg = s3c_camif_get_fimc_object(CODEC_MINOR); ++ unsigned int h = cis->win_hor_ofst; /* Camera input offset ONLY */ ++ unsigned int v = cis->win_ver_ofst; /* Camera input offset ONLY */ ++ unsigned int h2 = cis->win_hor_ofst2; /* Camera input offset ONLY */ ++ unsigned int v2 = cis->win_ver_ofst2; /* Camera input offset ONLY */ ++ ++ /*Clear Overflow */ ++ writel(S3C_CIWDOFST_CLROVCOFIY | S3C_CIWDOFST_CLROVCOFICB | ++ S3C_CIWDOFST_CLROVCOFICR | S3C_CIWDOFST_CLROVPRFICB | ++ S3C_CIWDOFST_CLROVPRFICR, cfg->regs + S3C_CIWDOFST); ++ ++ writel(0, cfg->regs + S3C_CIWDOFST); ++ ++ if (!h && !v) { ++ writel(0, cfg->regs + S3C_CIWDOFST); ++ writel(0, cfg->regs + S3C_CIDOWSFT2); ++ return 0; ++ } ++ ++ writel(S3C_CIWDOFST_WINOFSEN | S3C_CIWDOFST_WINHOROFST(h) | ++ S3C_CIWDOFST_WINVEROFST(v), cfg->regs + S3C_CIWDOFST); ++ writel(S3C_CIDOWSFT2_WINHOROFST2(h) | S3C_CIDOWSFT2_WINVEROFST2(v), ++ cfg->regs + S3C_CIDOWSFT2); ++ writel(S3C_CIDOWSFT2_WINHOROFST2(h2) | S3C_CIDOWSFT2_WINVEROFST2(v2), ++ cfg->regs + S3C_CIDOWSFT2); ++ ++ return 0; ++} ++ ++void s3c_camif_set_priority(int flag) ++{ ++ unsigned int val; ++ ++ if (flag) { ++ irq_old_priority = readl(S3C64XX_PRIORITY); ++ val = irq_old_priority; ++ val &= ~(3 << 7); ++ writel(val, S3C64XX_PRIORITY); ++ ++ /* Arbiter 1, REQ2 first */ ++ val |= (1 << 7); ++ writel(val, S3C64XX_PRIORITY); ++ ++ /* Disable Priority Rotate */ ++ val &= ~(1 << 1); ++ writel(val, S3C64XX_PRIORITY); ++ } else ++ writel(irq_old_priority, S3C64XX_PRIORITY); ++} ++ ++/************************************************************************* ++ * Interrupt part ++ ************************************************************************/ ++void s3c_camif_enable_lastirq(camif_cfg_t *cfg) ++{ ++ unsigned int val; ++ ++ if (cfg->capture_enable == CAMIF_BOTH_DMA_ON || ++ (cfg->dma_type & CAMIF_CODEC)) { ++ val = readl(cfg->regs + S3C_CICOCTRL); ++ val |= S3C_CICOCTRL_LASTIRQEN; ++ writel(val, cfg->regs + S3C_CICOCTRL); ++ } ++ ++ if (cfg->capture_enable == CAMIF_BOTH_DMA_ON || ++ !(cfg->dma_type & CAMIF_CODEC)) { ++ val = readl(cfg->regs + S3C_CIPRCTRL); ++ val |= S3C_CIPRCTRL_LASTIRQEN_ENABLE; ++ writel(val, cfg->regs + S3C_CIPRCTRL); ++ } ++} ++ ++void s3c_camif_disable_lastirq(camif_cfg_t *cfg) ++{ ++ unsigned int val; ++ ++ if (cfg->capture_enable == CAMIF_BOTH_DMA_ON || ++ (cfg->dma_type & CAMIF_CODEC)) { ++ val = readl(cfg->regs + S3C_CICOCTRL); ++ val &= ~S3C_CICOCTRL_LASTIRQEN; ++ writel(val, cfg->regs + S3C_CICOCTRL); ++ } ++ ++ if (cfg->capture_enable == CAMIF_BOTH_DMA_ON || ++ !(cfg->dma_type & CAMIF_CODEC)) { ++ val = readl(cfg->regs + S3C_CIPRCTRL); ++ val &= ~S3C_CIPRCTRL_LASTIRQEN_ENABLE; ++ writel(val, cfg->regs + S3C_CIPRCTRL); ++ } ++} ++ ++#if defined(CONFIG_CPU_S3C6400) || defined(CONFIG_CPU_S3C6410) ++void s3c_camif_clear_irq(int irq) ++{ ++ camif_cfg_t *cfg = s3c_camif_get_fimc_object(CODEC_MINOR); ++ unsigned int val = 0; ++ ++ if (irq == IRQ_CAMIF_C) { ++ val = readl(cfg->regs + S3C_CIGCTRL); ++ val |= (1 << 19); ++ } else if (irq == IRQ_CAMIF_P) { ++ val = readl(cfg->regs + S3C_CIGCTRL); ++ val |= (1 << 18); ++ } ++ ++ writel(val, cfg->regs + S3C_CIGCTRL); ++} ++#else ++void s3c_camif_clear_irq(int irq) ++{ ++} ++#endif ++ ++/************************************************************************* ++ * Initialize part ++ ************************************************************************/ ++#if defined(CONFIG_CPU_S3C2443) || defined(CONFIG_CPU_S3C2450) || defined(CONFIG_CPU_S3C2416) ++static int s3c_camif_set_gpio(void) ++{ ++ s3c2410_gpio_cfgpin(S3C2440_GPJ0, S3C2440_GPJ0_CAMDATA0); ++ s3c2410_gpio_cfgpin(S3C2440_GPJ1, S3C2440_GPJ1_CAMDATA1); ++ s3c2410_gpio_cfgpin(S3C2440_GPJ2, S3C2440_GPJ2_CAMDATA2); ++ s3c2410_gpio_cfgpin(S3C2440_GPJ3, S3C2440_GPJ3_CAMDATA3); ++ s3c2410_gpio_cfgpin(S3C2440_GPJ4, S3C2440_GPJ4_CAMDATA4); ++ s3c2410_gpio_cfgpin(S3C2440_GPJ5, S3C2440_GPJ5_CAMDATA5); ++ s3c2410_gpio_cfgpin(S3C2440_GPJ6, S3C2440_GPJ6_CAMDATA6); ++ s3c2410_gpio_cfgpin(S3C2440_GPJ7, S3C2440_GPJ7_CAMDATA7); ++ s3c2410_gpio_cfgpin(S3C2440_GPJ8, S3C2440_GPJ8_CAMPCLK); ++ s3c2410_gpio_cfgpin(S3C2440_GPJ9, S3C2440_GPJ9_CAMVSYNC); ++ s3c2410_gpio_cfgpin(S3C2440_GPJ10, S3C2440_GPJ10_CAMHREF); ++ s3c2410_gpio_cfgpin(S3C2440_GPJ11, S3C2440_GPJ11_CAMCLKOUT); ++ s3c2410_gpio_cfgpin(S3C2440_GPJ12, S3C2440_GPJ12_CAMRESET); ++ ++ writel(0x1fff, S3C2443_GPJDN); ++ ++ return 0; ++} ++#elif defined(CONFIG_CPU_S3C6400) || defined(CONFIG_CPU_S3C6410) ++static int s3c_camif_set_gpio(void) ++{ ++ s3c_gpio_cfgpin(S3C64XX_GPF(5), S3C64XX_GPF5_CAMIF_YDATA0); ++ s3c_gpio_cfgpin(S3C64XX_GPF(6), S3C64XX_GPF6_CAMIF_YDATA1); ++ s3c_gpio_cfgpin(S3C64XX_GPF(7), S3C64XX_GPF7_CAMIF_YDATA2); ++ s3c_gpio_cfgpin(S3C64XX_GPF(8), S3C64XX_GPF8_CAMIF_YDATA3); ++ s3c_gpio_cfgpin(S3C64XX_GPF(9), S3C64XX_GPF9_CAMIF_YDATA4); ++ s3c_gpio_cfgpin(S3C64XX_GPF(10), S3C64XX_GPF10_CAMIF_YDATA5); ++ s3c_gpio_cfgpin(S3C64XX_GPF(11), S3C64XX_GPF11_CAMIF_YDATA6); ++ s3c_gpio_cfgpin(S3C64XX_GPF(12), S3C64XX_GPF12_CAMIF_YDATA7); ++ s3c_gpio_cfgpin(S3C64XX_GPF(2), S3C64XX_GPF2_CAMIF_PCLK); ++ s3c_gpio_cfgpin(S3C64XX_GPF(4), S3C64XX_GPF4_CAMIF_VSYNC); ++ s3c_gpio_cfgpin(S3C64XX_GPF(1), S3C64XX_GPF1_CAMIF_HREF); ++ s3c_gpio_cfgpin(S3C64XX_GPF(0), S3C64XX_GPF0_CAMIF_CLK); ++ s3c_gpio_cfgpin(S3C64XX_GPF(3), S3C64XX_GPF3_CAMIF_nRST); ++ ++ writel(0, S3C64XX_GPFPUD); ++ ++ return 0; ++} ++#endif ++ ++void s3c_camif_reset(int is, int delay) ++{ ++ camif_cfg_t *cfg = s3c_camif_get_fimc_object(CODEC_MINOR); ++ unsigned int val; ++ unsigned int tmp; ++ ++ switch (is) { ++ case CAMIF_RESET: ++ tmp = readl(cfg->regs + S3C_CISRCFMT); ++ ++ if (tmp &= (1 << 31)) { ++ /* ITU-R BT 601 */ ++ val = readl(cfg->regs + S3C_CIGCTRL); ++ val |= S3C_CIGCTRL_SWRST; ++ ++#if defined(CONFIG_CPU_S3C6400) || defined(CONFIG_CPU_S3C6410) ++ val |= S3C_CIGCTRL_IRQ_LEVEL; ++#endif ++ writel(val, cfg->regs + S3C_CIGCTRL); ++ mdelay(1); ++ ++ val = readl(cfg->regs + S3C_CIGCTRL); ++ val &= ~S3C_CIGCTRL_SWRST; ++ writel(val, cfg->regs + S3C_CIGCTRL); ++ } else { ++ /* ITU-R BT 656 */ ++ tmp = readl(cfg->regs + S3C_CISRCFMT); ++ tmp |= (1 << 31); ++ writel(tmp, cfg->regs + S3C_CISRCFMT); ++ ++ val = readl(cfg->regs + S3C_CIGCTRL); ++ val |= S3C_CIGCTRL_SWRST; ++ ++#if defined(CONFIG_CPU_S3C6400) || defined(CONFIG_CPU_S3C6410) ++ val |= S3C_CIGCTRL_IRQ_LEVEL; ++#endif ++ writel(val, cfg->regs + S3C_CIGCTRL); ++ mdelay(1); ++ ++ val = readl(cfg->regs + S3C_CIGCTRL); ++ val &= ~S3C_CIGCTRL_SWRST; ++ writel(val, cfg->regs + S3C_CIGCTRL); ++ ++ tmp = readl(cfg->regs + S3C_CISRCFMT); ++ tmp &= ~(1 << 31); ++ writel(tmp, cfg->regs + S3C_CISRCFMT); ++ } ++ ++ break; ++ ++ case CAMIF_EX_RESET_AH: ++ val = readl(cfg->regs + S3C_CIGCTRL); ++ val |= S3C_CIGCTRL_CAMRST; ++ writel(val, cfg->regs + S3C_CIGCTRL); ++ udelay(200); ++ ++ val = readl(cfg->regs + S3C_CIGCTRL); ++ val &= ~S3C_CIGCTRL_CAMRST; ++ writel(val, cfg->regs + S3C_CIGCTRL); ++ udelay(delay); ++ ++#if defined(CONFIG_VIDEO_SAMSUNG_S5K3AA) ++ val = readl(cfg->regs + S3C_CIGCTRL); ++ val |= S3C_CIGCTRL_CAMRST; ++ writel(val, cfg->regs + S3C_CIGCTRL); ++ udelay(200); ++#endif ++ break; ++ ++ case CAMIF_EX_RESET_AL: ++ val = readl(cfg->regs + S3C_CIGCTRL); ++ val &= ~S3C_CIGCTRL_CAMRST; ++ writel(val, cfg->regs + S3C_CIGCTRL); ++ udelay(200); ++ ++ val = readl(cfg->regs + S3C_CIGCTRL); ++ val |= S3C_CIGCTRL_CAMRST; ++ writel(val, cfg->regs + S3C_CIGCTRL); ++ udelay(delay); ++ break; ++ ++ default: ++ break; ++ } ++} ++ ++void s3c_camif_init(void) ++{ ++ s3c_camif_reset(CAMIF_RESET, 0); ++ s3c_camif_set_gpio(); ++} +diff -ruN --exclude='*.orig' --exclude='*.rej' linux-2.6.29-rc3.owrt/drivers/media/video/s3c_camif.h linux-2.6.29-rc3.owrt.om/drivers/media/video/s3c_camif.h +--- linux-2.6.29-rc3.owrt/drivers/media/video/s3c_camif.h 1970-01-01 01:00:00.000000000 +0100 ++++ linux-2.6.29-rc3.owrt.om/drivers/media/video/s3c_camif.h 2009-05-10 22:27:59.000000000 +0200 +@@ -0,0 +1,404 @@ ++/* drivers/media/video/s3c_camif.h ++ * ++ * Copyright (c) 2008 Samsung Electronics ++ * ++ * Samsung S3C Camera driver ++ * ++ * 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, MA 02111-1307 USA ++ */ ++ ++#ifndef __S3C_CAMIF_H_ ++#define __S3C_CAMIF_H_ ++ ++#ifdef __KERNEL__ ++#include <linux/videodev.h> ++#include <linux/videodev2.h> ++#include <asm/types.h> ++#include <linux/i2c.h> ++#include <linux/video_decoder.h> ++#endif /* __KERNEL__ */ ++ ++#if !defined(O_NONCAP) ++#define O_NONCAP O_TRUNC ++#endif ++ ++#if defined(CAMIF_DEBUG) ++#define DPRINTK(fmt, args...) printk(KERN_DEBUG "%s: " fmt, __FUNCTION__ , ## args) ++#else ++#define DPRINTK(fmt, args...) ++#endif ++ ++#if defined(CAMIF_DEBUG) ++#define assert(expr) \ ++ if(!(expr)) { \ ++ printk( "Assertion failed! %s,%s,%s,line=%d\n", \ ++ #expr,__FILE__,__FUNCTION__,__LINE__); \ ++ } ++#else ++#define assert(expr) ++#endif ++ ++#if defined(CONFIG_CPU_S3C6400) || defined(CONFIG_CPU_S3C6410) ++#define MEM_SIZE 0x08000000 ++#define FIMC_VER "3.0" ++#elif defined(CONFIG_CPU_S3C2443) || defined(CONFIG_CPU_S3C2450) || defined(CONFIG_CPU_S3C2416) ++#define MEM_SIZE 0x04000000 ++#define FIMC_VER "2.3" ++#else ++#define MEM_SIZE 0x04000000 ++#define FIMC_VER "2.x" ++#endif ++ ++#undef FSM_ON_PREVIEW ++#define FSM_ON_CODEC ++ ++#undef USE_LAST_IRQ /* turn on if pp count is 1 */ ++ ++#define CODEC_DEV_NAME "CAMIF_CODEC" ++#define PREVIEW_DEV_NAME "CAMIF_PREVIEW" ++ ++#define CAMIF_DEV_NUM 2 ++#define FIMC_CODEC_INDEX 0 ++#define FIMC_PREVIEW_INDEX 1 ++ ++#define BURST_ERR 1 ++#define RESERVED_MEM (15 * 1024 * 1024) ++#define YUV_MEM (10 * 1024 * 1024) ++#define RGB_MEM (RESERVED_MEM - YUV_MEM) ++ ++#define CODEC_DEFAULT_WIDTH 640 ++#define CODEC_DEFAULT_HEIGHT 480 ++#define PREVIEW_DEFAULT_WIDTH 640 ++#define PREVIEW_DEFAULT_HEIGHT 480 ++ ++#define CROP_DEFAULT_WIDTH 352 ++#define CROP_DEFAULT_HEIGHT 272 ++ ++#define CODEC_DEFAULT_PPNUM 4 ++#define PREVIEW_DEFAULT_PPNUM 4 ++ ++#define CODEC_MINOR 12 ++#define PREVIEW_MINOR 13 ++ ++#define CHECK_FREQ 5 ++#define INSTANT_SKIP 0 ++#define INSTANT_GO 1 ++ ++#define VID_HARDWARE_SAMSUNG_FIMC3X 236 ++ ++#define ZOOM_AT_A_TIME_IN_PIXELS 32 ++#define ZOOM_IN_MAX 640 ++ ++/* Codec or Preview Status */ ++#define CAMIF_STARTED (1 << 1) ++#define CAMIF_STOPPED (1 << 2) ++#define CAMIF_INT_HAPPEN (1 << 3) ++ ++/* Codec or Preview : Interrupt FSM */ ++#define CAMIF_1st_INT (1 << 7) ++#define CAMIF_Xth_INT (1 << 8) ++#define CAMIF_Yth_INT (1 << 9) ++#define CAMIF_Zth_INT (1 << 10) ++#define CAMIF_NORMAL_INT (1 << 11) ++#define CAMIF_DUMMY_INT (1 << 12) ++#define CAMIF_CONTINUOUS_INT (1 << 13) ++#define CAMIF_SET_LAST_INT (1 << 14) ++#define CAMIF_STOP_CAPTURE (1 << 15) ++#define CAMIF_LAST_IRQ (1 << 16) ++#define CAMIF_PENDING_INT 0 ++ ++#define CAMIF_CAPTURE_SKIP_FRAMES 5 ++ ++/* CAMIF RESET Definition */ ++#define CAMIF_RESET (1 << 0) ++#define CAMIF_EX_RESET_AL (1 << 1) /* Active Low */ ++#define CAMIF_EX_RESET_AH (1 << 2) /* Active High */ ++ ++#define USER_EXIT (1 << 2) ++#define USER_ADD (1 << 1) ++#define SENSOR_INIT (1 << 0) ++ ++#define SENSOR_MAX 255 ++#define SENSOR_QSVGA (1 << 12) ++#define SENSOR_UXGA (1 << 11) ++#define SENSOR_SVGA (1 << 10) ++#define SENSOR_SXGA (1 << 4) ++#define SENSOR_VGA (1 << 3) ++#define SENSOR_DEFAULT 0 ++ ++#define SENSOR_WB (1 << 9) ++#define SENSOR_AF (1 << 8) ++#define SENSOR_MIRROR (1 << 7) ++#define SENSOR_ZOOMOUT (1 << 6) ++#define SENSOR_ZOOMIN (1 << 5) ++ ++/* Global Status Definition */ ++#define PWANT2START (1 << 0) ++#define CWANT2START (1 << 1) ++#define BOTH_STARTED (PWANT2START | CWANT2START) ++#define P_NOT_WORKING (1 << 4) ++#define C_WORKING (1 << 5) ++#define P_WORKING (1 << 6) ++#define C_NOT_WORKING (1 << 7) ++ ++#define FORMAT_FLAGS_DITHER 0x01 ++#define FORMAT_FLAGS_PACKED 0x02 ++#define FORMAT_FLAGS_PLANAR 0x04 ++#define FORMAT_FLAGS_RAW 0x08 ++#define FORMAT_FLAGS_CrCb 0x10 ++ ++enum camif_itu_fmt { ++ CAMIF_ITU601 = (1 << 31), ++ CAMIF_ITU656 = 0, ++}; ++ ++/* It is possbie to use two device simultaneously */ ++enum camif_dma_type { ++ CAMIF_PREVIEW = (1 << 0), ++ CAMIF_CODEC = (1 << 1), ++}; ++ ++enum camif_order422 { ++ CAMIF_YCBYCR = 0, ++ CAMIF_YCRYCB = (1 << 14), ++ CAMIF_CBYCRY = (1 << 15), ++ CAMIF_CRYCBY = (1 << 15) | (1 << 14), ++}; ++ ++enum flip_mode { ++ CAMIF_FLIP = 0, ++ CAMIF_ROTATE_90 = (1 << 13), ++ CAMIF_FLIP_X = (1 << 14), ++ CAMIF_FLIP_Y = (1 << 15), ++ CAMIF_FLIP_MIRROR = (1 << 15) | (1 << 14), ++ CAMIF_FLIP_ROTATE_270 = (1 << 15) | (1 << 14) | (1 << 13), ++}; ++ ++enum camif_fmt { ++ CAMIF_YCBCR420 = (1 << 0), ++ CAMIF_YCBCR422 = (1 << 1), ++ CAMIF_YCBCR422I = (1 << 2), ++ CAMIF_RGB16 = (1 << 3), ++ CAMIF_RGB24 = (1 << 4), ++ CAMIF_RGB32 = (1 << 5), ++}; ++ ++enum camif_capturing { ++ CAMIF_BOTH_DMA_ON = (1 << 4), ++ CAMIF_DMA_ON = (1 << 3), ++ CAMIF_BOTH_DMA_OFF = (1 << 1), ++ CAMIF_DMA_OFF = (1 << 0), ++ CAMIF_DMA_OFF_L_IRQ = (1 << 5), ++}; ++ ++enum image_effect { ++ CAMIF_BYPASS, ++ CAMIF_ARBITRARY_CB_CR, ++ CAMIF_NEGATIVE, ++ CAMIF_ART_FREEZE, ++ CAMIF_EMBOSSING , ++ CAMIF_SILHOUETTE, ++}; ++ ++enum input_channel{ ++ CAMERA_INPUT, ++ MSDMA_FROM_CODEC, ++ MSDMA_FROM_PREVIEW, ++}; ++ ++enum output_channel{ ++ CAMIF_OUT_PP, ++ CAMIF_OUT_FIFO, ++}; ++ ++typedef struct camif_performance ++{ ++ int frames; ++ int framesdropped; ++ __u64 bytesin; ++ __u64 bytesout; ++ __u32 reserved[4]; ++} camif_perf_t; ++ ++typedef struct { ++ dma_addr_t phys_y; ++ dma_addr_t phys_cb; ++ dma_addr_t phys_cr; ++ u8 *virt_y; ++ u8 *virt_cb; ++ u8 *virt_cr; ++ dma_addr_t phys_rgb; ++ u8 *virt_rgb; ++} img_buf_t; ++ ++/* this structure convers the CIWDOFFST, prescaler, mainscaler */ ++typedef struct { ++ u32 modified_src_x; /* After windows applyed to source_x */ ++ u32 modified_src_y; ++ u32 hfactor; ++ u32 vfactor; ++ u32 shfactor; /* SHfactor = 10 - ( hfactor + vfactor ) */ ++ u32 prehratio; ++ u32 prevratio; ++ u32 predst_x; ++ u32 predst_y; ++ u32 scaleup_h; ++ u32 scaleup_v; ++ u32 mainhratio; ++ u32 mainvratio; ++ u32 scalerbypass; /* only codec */ ++ u32 zoom_in_cnt; ++} scaler_t; ++ ++enum v4l2_status { ++ CAMIF_V4L2_INIT = (1 << 0), ++ CAMIF_v4L2_DIRTY = (1 << 1), ++}; ++ ++typedef struct { ++ struct semaphore lock; ++ enum camif_itu_fmt itu_fmt; ++ enum camif_order422 order422; ++ struct i2c_client *sensor; ++ u32 win_hor_ofst; ++ u32 win_ver_ofst; ++ u32 win_hor_ofst2; ++ u32 win_ver_ofst2; ++ u32 camclk; /* External Image Sensor Camera Clock */ ++ u32 source_x; ++ u32 source_y; ++ u32 polarity_pclk; ++ u32 polarity_vsync; ++ u32 polarity_href; ++ u32 user; /* MAX 2 (codec, preview) */ ++ u32 irq_old_priority; /* BUS PRIORITY register */ ++ u32 status; ++ u32 init_sensor; /* initializing sensor */ ++ u32 reset_type; /* External Sensor Reset Type */ ++ u32 reset_udelay; ++ u32 zoom_in_cnt; ++} camif_cis_t; ++ ++/* when App want to change v4l2 parameter, ++ * we instantly store it into v4l2_t v2 ++ * and then reflect it to hardware ++ */ ++typedef struct v4l2 { ++ struct v4l2_fmtdesc *fmtdesc; ++ struct v4l2_framebuffer frmbuf; /* current frame buffer */ ++ struct v4l2_input *input; ++ struct v4l2_output *output; ++ enum v4l2_status status; ++ ++ /* crop */ ++ struct v4l2_rect crop_bounds; ++ struct v4l2_rect crop_defrect; ++ struct v4l2_rect crop_current; ++ ++} v4l2_t; ++ ++ ++typedef struct camif_c_t { ++ struct video_device *v; ++ ++ /* V4L2 param only for v4l2 driver */ ++ v4l2_t v2; ++ camif_cis_t *cis; /* Common between Codec and Preview */ ++ ++ /* logical parameter */ ++ wait_queue_head_t waitq; ++ u32 status; /* Start/Stop */ ++ u32 fsm; /* Start/Stop */ ++ u32 open_count; /* duplicated */ ++ int irq; ++ char shortname[16]; ++ u32 target_x; ++ u32 target_y; ++ scaler_t sc; ++ enum flip_mode flip; ++ enum image_effect effect; ++ enum camif_dma_type dma_type; ++ ++ /* 4 pingpong Frame memory */ ++ u8 *pp_virt_buf; ++ dma_addr_t pp_phys_buf; ++ u32 pp_totalsize; ++ u32 pp_num; /* used pingpong memory number */ ++ img_buf_t img_buf[4]; ++ enum camif_fmt src_fmt; ++ enum camif_fmt dst_fmt; ++ enum camif_capturing capture_enable; ++ camif_perf_t perf; ++ u32 cur_frame_num; ++ u32 auto_restart; /* Only For Preview */ ++ int input_channel; ++ int output_channel; ++ int buffer_size; ++ void *other; /* other camif_cfg_t */ ++ u32 msdma_status; /* 0 : stop, 1 : start */ ++ void __iomem *regs; ++} camif_cfg_t; ++ ++/* Test Application Usage */ ++typedef struct { ++ int src_x; ++ int src_y; ++ int dst_x; ++ int dst_y; ++ int src_fmt; ++ int dst_fmt; ++ int flip; ++ int awb; ++ int effect; ++ int input_channel; ++ int output_channel; ++ unsigned int h_offset; ++ unsigned int v_offset; ++ unsigned int h_offset2; ++ unsigned int v_offset2; ++} camif_param_t; ++ ++/* Externs */ ++extern camif_cfg_t* s3c_camif_get_fimc_object(int); ++extern int s3c_camif_start_dma(camif_cfg_t *); ++extern int s3c_camif_stop_dma(camif_cfg_t *); ++extern int s3c_camif_get_frame_num(camif_cfg_t *); ++extern unsigned char* s3c_camif_get_frame(camif_cfg_t *); ++extern int s3c_camif_control_fimc(camif_cfg_t *); ++extern void s3c_camif_reset(int, int); ++extern void s3c_camif_init(void); ++extern int s3c_camif_get_fifo_status(camif_cfg_t *); ++extern void s3c_camif_enable_lastirq(camif_cfg_t *); ++extern void s3c_camif_disable_lastirq(camif_cfg_t *); ++extern void s3c_camif_change_flip(camif_cfg_t *); ++extern void s3c_camif_change_effect(camif_cfg_t *); ++extern int s3c_camif_start_codec_msdma(camif_cfg_t *); ++extern int s3c_camif_set_clock(unsigned int camclk); ++extern void s3c_camif_disable_clock(void); ++extern int s3c_camif_start_preview_msdma(camif_cfg_t *); ++extern camif_cis_t* get_initialized_cis(void); ++extern void s3c_camif_clear_irq(int); ++extern int s3c_camif_set_source_format(camif_cis_t *); ++extern void s3c_camif_register_sensor(struct i2c_client *); ++extern void s3c_camif_unregister_sensor(struct i2c_client*); ++extern int s3c_camif_setup_dma(camif_cfg_t *); ++extern void s3c_camif_init_sensor(camif_cfg_t *); ++extern int s3c_camif_set_offset(camif_cis_t *); ++extern void s3c_camif_set_priority(int); ++extern void s3c_camif_open_sensor(camif_cis_t *); ++extern void s3c_camif_set_polarity(camif_cfg_t *cfg); ++ ++#endif ++ +diff -ruN --exclude='*.orig' --exclude='*.rej' linux-2.6.29-rc3.owrt/drivers/media/video/samsung/4xa_sensor.c linux-2.6.29-rc3.owrt.om/drivers/media/video/samsung/4xa_sensor.c +--- linux-2.6.29-rc3.owrt/drivers/media/video/samsung/4xa_sensor.c 1970-01-01 01:00:00.000000000 +0100 ++++ linux-2.6.29-rc3.owrt.om/drivers/media/video/samsung/4xa_sensor.c 2009-05-10 22:27:59.000000000 +0200 +@@ -0,0 +1,384 @@ ++/* ++ * Copyright (C) 2004 Samsung Electronics ++ * SW.LEE <hitchcar@samsung.com> ++ * - based on Russell King : pcf8583.c ++ * - added smdk24a0, smdk2440 ++ * - added poseidon (s3c24a0+wavecom) ++ * ++ * This program is free software; you can redistribute it and/or modify ++ * it under the terms of the GNU General Public License version 2 as ++ * published by the Free Software Foundation. ++ * ++ * Driver for FIMC2.x Camera Decoder ++ * ++ */ ++ ++//#include <linux/config.h> ++#include <linux/module.h> ++#include <linux/kernel.h> ++#include <linux/init.h> ++#include <linux/i2c.h> ++#include <linux/i2c-id.h> ++#include <linux/slab.h> ++#include <linux/string.h> ++#include <linux/init.h> ++#include <linux/delay.h> ++ ++//#define CAMIF_DEBUG ++ ++#include "../s3c_camif.h" ++#include "4xa_sensor.h" ++ ++ ++/* ++ * Samsung's original code: ++ * .camclk = 44000000, / * for 20 fps: 44MHz, for 12 fps (more ++ * stable): 26MHz * / ++ * ++ * Experimenting with the controls yielded the following: ++ * ++ * PLL_CLK gets divided according to TCMD.Div8_r (1,00h) and then by ++ * SEL_MAIN.Half_PCLK_Enable (5,8Fh) until it finally becomes PCLK. ++ * ++ * Div8_r = 0: 1/4, 1: 1/2 (default) ++ * Half_PCLK_Enable = 0: 1/1 (default), 1: 1/2 ++ * ++ * Thus our 26.6 MHz MCLK becomes an 87.78 MHz PLL_CLK and eventually a PCLK ++ * of 43.89 MHz. ++ */ ++ ++#define CAMCLK 26600000 /* 26.6 MHz */ ++ ++ ++static struct i2c_driver sensor_driver; ++ ++/* This is an abstract CIS sensor for MSDMA input. */ ++ ++camif_cis_t msdma_input = { ++ .itu_fmt = CAMIF_ITU601, ++ .order422 = CAMIF_CBYCRY, /* another case: YCRYCB */ ++ .camclk = CAMCLK, ++ .source_x = 800, ++ .source_y = 600, ++ .win_hor_ofst = 0, ++ .win_ver_ofst = 0, ++ .win_hor_ofst2 = 0, ++ .win_ver_ofst2 = 0, ++ .polarity_pclk = 0, ++ .polarity_vsync = 1, ++ .polarity_href = 0, ++ .reset_type = CAMIF_EX_RESET_AL, ++ .reset_udelay = 5000, ++}; ++ ++camif_cis_t interlace_input = { ++ .itu_fmt = CAMIF_ITU601, ++ .order422 = CAMIF_CBYCRY, /* another case: YCRYCB */ ++ .camclk = CAMCLK, ++ .source_x = 800, ++ .source_y = 600, ++ .win_hor_ofst = 0, ++ .win_ver_ofst = 0, ++ .win_hor_ofst2 = 0, ++ .win_ver_ofst2 = 0, ++ .polarity_pclk = 0, ++ .polarity_vsync = 1, ++ .polarity_href = 0, ++ .reset_type = CAMIF_EX_RESET_AL, ++ .reset_udelay = 5000, ++}; ++ ++#if defined(CONFIG_VIDEO_SAMSUNG_S5K4BA) ++static camif_cis_t data = { ++ .itu_fmt = CAMIF_ITU601, ++ .order422 = CAMIF_YCBYCR, ++ .camclk = CAMCLK, ++ .source_x = 800, ++ .source_y = 600, ++ .win_hor_ofst = 0, ++ .win_ver_ofst = 0, ++ .win_hor_ofst2 = 0, ++ .win_ver_ofst2 = 0, ++ .polarity_pclk = 0, ++ .polarity_vsync = 1, ++ .polarity_href = 0, ++ .reset_type = CAMIF_EX_RESET_AL, ++ .reset_udelay = 5000, ++}; ++ ++s5k4xa_t s5k4ba_regs_mirror[S5K4BA_REGS]; ++#else ++#error No samsung CIS moudule here ! ++#endif ++ ++camif_cis_t* get_initialized_cis(void) ++{ ++ if (data.init_sensor == 0) ++ return NULL; ++ ++ return &data; ++} ++ ++#define CAM_ID 0x5a ++ ++static unsigned short ignore[] = { I2C_CLIENT_END }; ++static unsigned short normal_addr[] = { CAM_ID >> 1, I2C_CLIENT_END }; ++static const unsigned short *forces[] = { NULL }; ++ ++static struct i2c_client_address_data addr_data = { ++ .normal_i2c = normal_addr, ++ .probe = ignore, ++ .ignore = ignore, ++ .forces = forces, ++}; ++ ++ ++static unsigned char sensor_read(struct i2c_client *client, ++ unsigned char subaddr) ++{ ++ unsigned char buf = subaddr; ++ struct i2c_msg msg = { ++ .addr = client->addr, ++ .flags = 0, ++ .len = 1, ++ .buf = &buf, ++ }; ++ ++ if (i2c_transfer(client->adapter, &msg, 1) != 1) { ++ printk(" I2C write Error\n"); ++ return -EIO; ++ } ++ ++ msg.flags = I2C_M_RD; ++ if (i2c_transfer(client->adapter, &msg, 1) != 1) { ++ printk(" I2C read Error\n"); ++ return -EIO; ++ } ++ ++ return buf; ++} ++ ++static int ++sensor_write(struct i2c_client *client, ++ unsigned char subaddr, unsigned char val) ++{ ++ unsigned char buf[2]; ++ struct i2c_msg msg = { ++ .addr = client->addr, ++ .flags = 0, ++ .len = 2, ++ .buf = buf, ++ }; ++ ++ buf[0] = subaddr; ++ buf[1] = val; ++ ++ return i2c_transfer(client->adapter, &msg, 1) == 1 ? 0 : -EIO; ++} ++ ++#if defined(CONFIG_VIDEO_SAMSUNG_S5K4BA) ++void inline sensor_init(struct i2c_client *sam_client) ++{ ++ int i; ++ ++ i = ARRAY_SIZE(s5k4ba_reg); ++ for (i = 0; i < S5K4BA_INIT_REGS; i++) ++ sensor_write(sam_client, ++ s5k4ba_reg[i].subaddr, s5k4ba_reg[i].value); ++} ++#else ++#error No samsung CIS moudule ! ++#endif ++ ++static int ++s5k4xa_attach(struct i2c_adapter *adap, int addr, int kind) ++{ ++ struct i2c_client *c; ++ ++ c = kmalloc(sizeof(*c), GFP_KERNEL); ++ if (!c) ++ return -ENOMEM; ++ ++ memset(c, 0, sizeof(struct i2c_client)); ++ ++ strcpy(c->name, "S5K4XA"); ++ c->addr = addr; ++ c->adapter = adap; ++ c->driver = &sensor_driver; ++ i2c_set_clientdata(c, &data); ++ data.sensor = c; ++ ++ s3c_camif_register_sensor(c); ++ ++ return i2c_attach_client(c); ++} ++ ++static int sensor_attach_adapter(struct i2c_adapter *adap) ++{ ++ extern void om_3d7k_camera_on(void); ++ extern void om_3d7k_camera_off(void); ++ int ret; ++ ++ s3c_camif_open_sensor(&data); ++ ++ om_3d7k_camera_on(); ++ ret = i2c_probe(adap, &addr_data, s5k4xa_attach); ++ om_3d7k_camera_off(); ++ return ret; ++} ++ ++static int sensor_detach(struct i2c_client *client) ++{ ++ i2c_detach_client(client); ++ s3c_camif_unregister_sensor(client); ++ return 0; ++} ++ ++/* ++ * Purpose: ++ * This function only for SVGA Camera : 4BA ++ */ ++ ++static int change_sensor_size(struct i2c_client *client, int size) ++{ ++ int i; ++ ++ switch (size) { ++#if defined(CONFIG_VIDEO_SAMSUNG_S5K4BA) ++ case SENSOR_QSVGA: ++ for (i = 0; i < S5K4BA_QSVGA_REGS; i++) ++ sensor_write(client, s5k4ba_reg_qsvga[i].subaddr, ++ s5k4ba_reg_qsvga[i].value); ++ break; ++ ++ case SENSOR_SVGA: ++ for (i = 0; i < S5K4BA_SVGA_REGS; i++) ++ sensor_write(client, s5k4ba_reg_svga[i].subaddr, ++ s5k4ba_reg_svga[i].value); ++ break; ++#else ++#error No samsung CIS moudule ! ++#endif ++ default: ++ panic("4xa_sensor.c: unexpect value\n"); ++ } ++ ++ return 0; ++} ++ ++static int change_sensor_wb(struct i2c_client *client, int type) ++{ ++ printk("[ *** Page 0, 4XA Sensor White Balance Mode ***]\n"); ++ ++#if defined(CONFIG_VIDEO_SAMSUNG_S5K4BA) ++ sensor_write(client, 0xFC, 0x0); ++ sensor_write(client, 0x30, type); ++#endif ++ ++ switch(type){ ++ case 0: ++ default: ++ printk(" -> AWB auto mode ]\n"); ++ break; ++ case 1: ++ printk(" -> Indoor 3100 mode ]\n"); ++ break; ++ case 2: ++ printk(" -> Outdoor 5100 mode ]\n"); ++ break; ++ case 3: ++ printk(" -> Indoor 2000 mode ]\n"); ++ break; ++ case 4: ++ printk(" -> AE/AWB halt ]\n"); ++ break; ++ case 5: ++ printk(" -> Cloudy(6000) mode ]\n"); ++ break; ++ case 6: ++ printk(" -> Sunny(8000) mode ]\n"); ++ break; ++ } ++ ++ return 0; ++} ++ ++static int ++sensor_command(struct i2c_client *client, unsigned int cmd, void *arg) ++{ ++ switch (cmd) { ++ case SENSOR_INIT: ++ sensor_init(client); ++ printk(KERN_INFO "External Camera initialized\n"); ++ break; ++ ++ case USER_ADD: ++ break; ++ ++ case USER_EXIT: ++ break; ++ ++ case SENSOR_QSVGA: ++ change_sensor_size(client, SENSOR_QSVGA); ++ break; ++ ++ case SENSOR_VGA: ++ change_sensor_size(client, SENSOR_VGA); ++ break; ++ ++ case SENSOR_SVGA: ++ change_sensor_size(client, SENSOR_SVGA); ++ break; ++ ++ case SENSOR_SXGA: ++ change_sensor_size(client, SENSOR_SXGA); ++ break; ++ ++ case SENSOR_UXGA: ++ change_sensor_size(client, SENSOR_UXGA); ++ break; ++/* Todo ++ case SENSOR_BRIGHTNESS: ++ change_sensor_setting(); ++ break; ++*/ ++ case SENSOR_WB: ++ printk("[ *** 4XA Sensor White Balance , No mode ***]\n"); ++ change_sensor_wb(client, (int) arg); ++ break; ++ ++ default: ++ panic("4xa_sensor.c: Unexpected Sensor Command\n"); ++ break; ++ } ++ ++ return 0; ++} ++ ++static struct i2c_driver sensor_driver = { ++ .driver = { ++ .name = "s5k4xa", ++ }, ++ .id = I2C_DRIVERID_S5K_4XA, ++ .attach_adapter = sensor_attach_adapter, ++ .detach_client = sensor_detach, ++ .command = sensor_command ++}; ++ ++static __init int camif_sensor_init(void) ++{ ++ return i2c_add_driver(&sensor_driver); ++} ++ ++ ++static __init void camif_sensor_exit(void) ++{ ++ i2c_del_driver(&sensor_driver); ++} ++ ++module_init(camif_sensor_init) ++module_exit(camif_sensor_exit) ++ ++MODULE_AUTHOR("Jinsung, Yang <jsgood.yang@samsung.com>"); ++MODULE_DESCRIPTION("I2C Client Driver For FIMC V4L2 Driver"); ++MODULE_LICENSE("GPL"); +diff -ruN --exclude='*.orig' --exclude='*.rej' linux-2.6.29-rc3.owrt/drivers/media/video/samsung/4xa_sensor.h linux-2.6.29-rc3.owrt.om/drivers/media/video/samsung/4xa_sensor.h +--- linux-2.6.29-rc3.owrt/drivers/media/video/samsung/4xa_sensor.h 1970-01-01 01:00:00.000000000 +0100 ++++ linux-2.6.29-rc3.owrt.om/drivers/media/video/samsung/4xa_sensor.h 2009-05-10 22:27:59.000000000 +0200 +@@ -0,0 +1,2412 @@ ++#ifndef _SAMSUNG_SXGA_H_ ++#define _SAMSUNG_SXGA_H_ ++ ++/****************************************************************************** ++ * Display resolution standards ++ * ++ * QCIF: 176 x 144 ++ * CIF: 352 x 288 ++ * QVGA: 320 x 240 ++ * VGA: 640 x 480 ++ * SVGA: 800 x 600 ++ * XGA: 1024 x 768 ++ * WXGA: 1280 x 800 ++ * QVGA: 1280 x 960 ++ * SXGA: 1280 x 1024 ++ * SXGA+: 1400 x 1050 ++ * WSXGA+: 1680 x 1050 ++ * UXGA: 1600 x 1200 ++ * WUXGA: 1920 x 1200 ++ * QXGA: 2048 x 1536 ++ *****************************************************************************/ ++ ++//#include "../bits.h" ++ ++/* ++ * Camera information ++ * FPC Label : Samsung MEGA Pixel Camera : V4220 REV06 ++ * Modified by charles -Initial function of '3AA' test routine ++ * Modified and tested by YongHwui.Kim <yonghwui.kim@samsung.com> for S5K3AAEX ++ * Camera ++ */ ++ ++#define CHIP_DELAY 0xFF ++ ++typedef struct samsung_t{ ++ unsigned char subaddr; ++ unsigned char value; ++ unsigned char page; ++} s5k4xa_t; ++ ++#ifdef CONFIG_CPU_S3C24A0A ++#define TRY_HIGH_CLOCK 1 ++#endif ++ ++/*************************************************** ++ * name: S5K3AAEX EVT2 setfile ++ * ver: v2.61 ++ * history: ++ * v0.0 start from 040908 setfile ++ * v1.0 arange register ++ * v1.01 change MCLK(25Mhz) and Frame rate(7fps) ++ * v2.0 adjust register setting for 3AA EVT2 ++ * - color correction, RGB shading off, hsync start position, ++ * Mirror, fps ++ * - Color Tuning, YGRPDLY ++ * v2.1 change Frame rate(7.5fps) and Total gain to x4 ++ * (because of reducing visual noise at low illumination) ++ * - change BPRM AGC Max and FrameAE start ++ * improve AE speed ++ * v2.2 modify AWB G gain and solve 50hz flicker detection fail in ++ * 25MHz 7.5fps ++ * v2.3 Adjust gamma, Dark Slice, white point, Hue gain, ++ * White Balance B control, Y gain On, Digital Clamp On ++ * lower AWB G gain ++ * v2.4 Adjust AE window weight, Y Gamma, WhitePoint, Shading and BPR ++ * Max Thres. ++ * v2.41 Adjust AE/AWB window and AWB internal window boundary to ++ * decrease skin color tracking ++ * v2.411 special version for PSCDS ++ * v2.412 RGB shading off ++ * v2.5 Lens change STW to Sekonix ++ * adjust White point and Y shading Coef (RGB shading off) ++ * v2.6 New Tuning because of Full YC off and YCbCr Coef change ++ * Gamma, Dark Slice, color matrix (not use), Color suppress ++ * R Gain and DBPR agc MIN/MAX ++ * v2.61 VCK inversion(data rising) ++ ****************************************************/ ++ ++#if defined(CONFIG_VIDEO_SAMSUNG_S5K4BA) ++ ++/* For SVGA (800 x 600) */ ++#if 1 /* from han */ ++s5k4xa_t s5k4ba_reg[] = ++{ ++ {0xfc,0x07}, ++ {0x66,0x01}, /* Watch Dog Time On */ ++ {0xfc,0x00}, ++ {0x00,0xAA}, /* For EDS Check */ ++ {0x21,0x03}, /* peter */ ++ {0xfc,0x01}, ++ {0x04,0x01}, /* ARM Clock Divider */ ++ ++ {0xfc,0x02}, ++ {0x30,0x90}, /* Analog offset */ ++ {0x37,0x0d}, /* Global Gain */ ++ {0x2d,0x48}, /* Double Shutter */ ++ {0x60,0x00}, /* Blank_Adrs */ ++ ++ {0x45,0x1e}, /* 0e - CDS Timing for Average Sub_Sampling */ ++ {0x47,0x2f}, ++ {0x02,0x0e}, /* ADC Resolution */ ++ {0x3d,0x06}, /* Frame ADLC */ ++ {0x4d,0x08}, /* Doubler Volatage */ ++ {0x54,0x02}, /* Double Shutter */ ++ {0x55,0x1e}, /* Line ADLC */ ++ {0x56,0x30}, ++ {0x59,0x00}, /* LineADLC offset */ ++ {0x5b,0x08}, /* R_Ref_Ctrl */ ++ {0x44,0x63}, /* CLP_EN */ ++ {0x4A,0x10}, /* Clamp Control */ ++ {0x42,0x02}, ++ {0x43,0xef}, ++ ++ /* ++ * Table Set for Sub-Sampling ++ */ ++ ++ {0xfc,0x03}, ++ {0x2c,0x00}, /* crcb_sel for Sub-Sampling Table */ ++ {0x05,0x46}, /* Output Image Size Set for Capture */ ++ {0x07,0xb6}, ++ {0x0e,0x04}, ++ {0x12,0x03}, ++ ++ {0xfc,0x04}, ++ {0x32,0x04}, ++ {0x33,0xbc}, ++ ++ {0xfc,0x04}, ++ {0xc5,0x26}, /* Output Image Size Set for Preview */ ++ {0xc7,0x5e}, ++ {0xce,0x04}, ++ {0xd2,0x04}, ++ ++ {0xec,0x06}, /* CrCb sel = YCBYCR(0x06) by jsgood */ ++ {0xc0,0x06}, ++ {0xc1,0x70}, ++ {0xc2,0x02}, ++ {0xc3,0x87}, ++ ++ {0xfc,0x07}, ++ {0x05,0x00}, ++ {0x06,0x00}, ++ {0x07,0x8b}, ++ {0x08,0xf5}, ++ {0x09,0x00}, ++ {0x0a,0xb4}, ++ {0x0b,0x00}, ++ {0x0c,0xea}, ++ {0x0d,0x00}, ++ {0x0e,0x40}, ++ ++ {0xfc,0x00}, ++ {0x70,0x02}, ++ ++ /* Jeongyun added still shot cbcr_sel */ ++ {0xfc,0x03}, ++ {0x2c,0x00}, ++ {0x5c,0x00}, ++ {0x8c,0x00}, ++ {0xbc,0x00}, ++ {0xfc,0x04}, ++ {0x5c,0x00}, ++ ++ /* ++ * COMMAND SET ++ */ ++ ++ {0xfc,0x00}, ++ {0x73,0x21}, /* Frame AE Enable peter */ ++ {0x20,0x02}, /* Change AWB Mode */ ++ ++ {0xfc,0x00}, ++ {0x6c,0xb0}, /* AE target */ ++ {0x6d,0x00}, ++ ++ {0xfc,0x20}, ++ {0x16,0x5a}, /* for Prevating AE Hunting */ ++ ++ {0xfc,0x00}, ++ {0x78,0x6a}, /* AGC Max */ ++ {0xfc,0x20}, ++ {0x16,0x60}, /* Frame AE Start */ ++ ++ {0xfc,0x20}, ++ {0x57,0x18}, /* Stable_Frame_AE */ ++ {0x2C,0x30}, /* For Forbidden Area */ ++ {0x2E,0x00}, /* For Forbidden Area */ ++ {0x14,0x70}, ++ {0x01,0x00}, /* Stepless_Off */ ++ ++ {0xfc,0x07}, ++ {0x11,0x02}, /* AWB G Gain offset */ ++ ++ {0xfc,0x07}, ++ {0x3e,0x0a}, /* AWB Cut R max */ ++ ++ {0xfc,0x01}, ++ {0xc8,0xd0}, /* AWB Y Max */ ++ {0xfc,0x00}, ++ {0x3e,0x20}, /* 30 - AWB Y_min */ ++ {0x3d,0x10}, /* AWB Y_min Low */ ++ {0xfc,0x22}, ++ {0x8c,0x04}, /* AWB Min Y Weight AWB */ ++ {0x8d,0x16}, /* AWB Max Y Weight */ ++ ++ {0xfc,0x00}, ++ {0x32,0x04}, /* AWB moving average 8 frame */ ++ {0x81,0x10}, /* AWB G gain suppress Disable */ ++ {0xbc,0xf0}, ++ ++ {0x29,0x04}, /* Y level H */ ++ {0x2a,0x00}, /* Y level L */ ++ {0x2b,0x03}, /* color level H */ ++ {0x2c,0xc8}, /* color level L */ ++ ++ {0xfc,0x07}, ++ {0x37,0x00}, /* Flicker Add for 32 MHz */ ++ {0xfc,0x00}, ++ {0x72,0xa0}, /* Flicker for 32 MHz */ ++ {0x74,0x08}, /* flicker 60 Hz Fix */ ++ ++ {0xfc,0x20}, ++ {0x02,0x02}, /* Flicker Dgain Mode */ ++ ++ {0xfc,0x00}, ++ //{0x23,0x40}, /* Mirror Option */ ++ {0x62,0x0a}, /* Mirror Option */ ++ ++ {0xfc,0x02}, ++ {0x4e,0x1b}, /* Enable SDA and SCL pull-up; drive 8 mA */ ++ {0x4f,0xf0}, /* PCLK and YC: 8 mA, AF and ZM (AZ): 2 mA */ ++ ++ {0xfc,0x01}, ++ {0x0c,0x03}, /* Full YC Enable */ ++ //{0x0c,03}, /* Full YC Enable */ ++ //{0x02,02}, /* crcb_sel */ ++ //{0x02,02}, /* crcb_sel peter */ ++ //{0x01,01}, /* pclk peter */ ++ //{0x01,01}, ++ ++ /* ++ * COLOR MATRIX ++ */ ++ ++ {0xfc,0x01}, /* color matrix */ ++ {0x51,0x0A}, ++ {0x52,0x42}, ++ {0x53,0xF9}, ++ {0x54,0x80}, ++ {0x55,0x00}, ++ {0x56,0x3D}, ++ ++ {0x57,0xFE}, ++ {0x58,0x0B}, ++ {0x59,0x06}, ++ {0x5A,0x9C}, ++ {0x5B,0xFF}, ++ {0x5C,0x59}, ++ ++ {0x5D,0xFF}, ++ {0x5E,0xD8}, ++ {0x5F,0xFC}, ++ {0x60,0x2E}, ++ {0x61,0x07}, ++ {0x62,0xFA}, ++ ++ /* ++ * EDGE ENHANCEMENT ++ */ ++ ++ {0xfc,0x00}, ++ {0x89,0x03}, /* Edge Suppress On */ ++ {0xfc,0x0b}, ++ {0x42,0x50}, /* Edge AGC MIN */ ++ {0x43,0x60}, /* Edge AGC MAX */ ++ {0x45,0x18}, /* positive gain AGC MIN */ ++ {0x49,0x0a}, /* positive gain AGC MAX */ ++ {0x4d,0x18}, /* negative gain AGC MIN */ ++ {0x51,0x0a}, /* negative gain AGC MAX */ ++ ++ {0xfc,0x05}, ++ {0x34,0x20}, /* APTCLP */ ++ {0x35,0x09}, /* APTSC */ ++ {0x36,0x0b}, /* ENHANCE */ ++ {0x3f,0x00}, /* NON-LIN */ ++ {0x42,0x10}, /* EGFALL */ ++ {0x43,0x00}, /* HLFALL */ ++ {0x45,0xa0}, /* EGREF */ ++ {0x46,0x7a}, /* HLREF */ ++ {0x47,0x40}, /* LLREF */ ++ {0x48,0x0c}, ++ {0x49,0x31}, /* CSSEL EGSEL CS_DLY */ ++ ++ {0x40,0x41}, /* Y delay */ ++ ++ /* ++ * GAMMA ++ */ ++ ++ {0xfc,0x01}, ++ ++ {0x6F,0x0A}, /* R */ ++ {0x70,0x1A}, ++ {0x71,0x7A}, ++ {0x72,0xF8}, ++ {0x73,0x00}, ++ ++ {0x74,0xA0}, ++ {0x75,0x18}, ++ {0x76,0x65}, ++ {0x77,0xAD}, ++ {0x78,0x6A}, ++ ++ {0x79,0xE2}, ++ {0x7A,0x12}, ++ {0x7B,0x3D}, ++ {0x7C,0x5A}, ++ {0x7D,0xBF}, ++ ++ {0x7E,0x72}, ++ {0x7F,0x88}, ++ {0x80,0x9D}, ++ {0x81,0xB0}, ++ {0x82,0xFF}, ++ ++ {0x83,0xC0}, ++ {0x84,0xCF}, ++ {0x85,0xDA}, ++ {0x86,0xFC}, ++ ++ {0x87,0x08}, /* G */ ++ {0x88,0x12}, ++ {0x89,0x42}, ++ {0x8A,0xBA}, ++ {0x8B,0x00}, ++ ++ {0x8C,0x75}, ++ {0x8D,0xED}, ++ {0x8E,0x42}, ++ {0x8F,0x80}, ++ {0x90,0x5A}, ++ ++ {0x91,0xB5}, ++ {0x92,0xE5}, ++ {0x93,0x10}, ++ {0x94,0x35}, ++ {0x95,0xAF}, ++ ++ {0x96,0x55}, ++ {0x97,0x70}, ++ {0x98,0x88}, ++ {0x99,0x9D}, ++ {0x9A,0xFF}, ++ ++ {0x9B,0xB1}, ++ {0x9C,0xC4}, ++ {0x9D,0xD5}, ++ {0x9E,0xFC}, ++ ++ {0x9F,0x05}, /* B */ ++ {0xA0,0x18}, ++ {0xA1,0x42}, ++ {0xA2,0xd7}, ++ {0xA3,0x00}, ++ ++ {0xA4,0xB6}, ++ {0xA5,0x3b}, ++ {0xA6,0x88}, ++ {0xA7,0xC8}, ++ {0xA8,0x6A}, ++ ++ {0xA9,0x00}, ++ {0xAA,0x30}, ++ {0xAB,0x58}, ++ {0xAC,0x78}, ++ {0xAD,0xFF}, ++ ++ {0xAE,0x90}, ++ {0xAF,0xA5}, ++ {0xB0,0xB6}, ++ {0xB1,0xC5}, ++ {0xB2,0xFF}, ++ ++ {0xB3,0xD0}, ++ {0xB4,0xD6}, ++ {0xB5,0xDA}, ++ {0xB6,0xFC}, ++ ++ /* ++ * HUE CONTROL ++ */ ++ ++ {0xfc,0x00}, ++ {0x48,0x34}, /* 2000K */ ++ {0x49,0x34}, ++ {0x4a,0xf4}, ++ {0x4b,0x00}, ++ {0x4c,0x44}, ++ {0x4d,0x3c}, ++ {0x4e,0xf0}, ++ {0x4f,0x0c}, ++ ++ {0x50,0x34}, /* 3000K */ ++ {0x51,0x34}, ++ {0x52,0xf4}, ++ {0x53,0x00}, ++ {0x54,0x44}, ++ {0x55,0x3c}, ++ {0x56,0xf0}, ++ {0x57,0x0c}, ++ ++ {0x58,0x34}, /* 5100K */ ++ {0x59,0x30}, ++ {0x5a,0x00}, ++ {0x5b,0x04}, ++ {0x5c,0x40}, ++ {0x5d,0x2c}, ++ {0x5e,0xfc}, ++ {0x5f,0x04}, ++ ++ /* ++ * UPPRE0x0x FUNCTION ++ */ ++ ++ {0xfc,0x00}, ++ {0x7e,0xf4}, ++ ++ /* ++ * BPR ++ */ ++ ++ {0xfc,0x01}, ++ {0x3d,0x10}, ++ ++ {0xfc,0x0b}, ++ {0x0b,0x00}, /* ISP BPR On start */ ++ {0x0c,0x20}, /* Th13 AGC Min */ ++ {0x0d,0x40}, /* Th13 AGC Max */ ++ {0x0e,0x00}, /* Th1 Max H for AGCMIN */ ++ {0x0f,0x20}, /* Th1 Max L for AGCMIN */ ++ {0x10,0x00}, /* Th1 Min H for AGCMAX */ ++ {0x11,0x10}, /* Th1 Min L for AGCMAX */ ++ {0x12,0x00}, /* Th3 Max H for AGCMIN */ ++ {0x13,0x00}, /* Th3 Max L for AGCMIN */ ++ {0x14,0xff}, /* Th3 Min H for AGCMAX */ ++ {0x15,0xff}, /* Th3 Min L for AGCMAX */ ++ {0x16,0x20}, /* Th57 AGC Min */ ++ {0x17,0x40}, /* Th57 AGC Max */ ++ {0x18,0x00}, /* Th5 Max H for AGCMIN */ ++ {0x19,0x00}, /* Th5 Max L for AGCMIN */ ++ {0x1a,0x00}, /* Th5 Min H for AGCMAX */ ++ {0x1b,0x20}, /* Th5 Min L for AGCMAX */ ++ {0x1c,0x00}, /* Th7 Max H for AGCMIN */ ++ {0x1d,0x00}, /* Th7 Max L for AGCMIN */ ++ {0x1e,0x00}, /* Th7 Min H for AGCMAX */ ++ {0x1f,0x20}, /* Th7 Min L for AGCMAX */ ++ ++ /* ++ * GR/GB CORRECTION ++ */ ++ ++ {0xfc,0x01}, ++ {0x45,0x0c}, ++ ++ {0xfc,0x0b}, ++ {0x21,0x00}, /* start AGC */ ++ {0x22,0x18}, /* AGCMIN */ ++ {0x23,0x58}, /* AGCMAX */ ++ {0x24,0x0d}, /* G Th AGCMIN */ ++ {0x25,0x30}, /* G Th AGCMAX */ ++ {0x26,0x0d}, /* RB Th AGCMIN */ ++ {0x27,0x30}, /* RB Th AGCMAX */ ++ ++ /* ++ * NR ++ */ ++ ++ {0xfc,0x01}, ++ {0x4C,0x01}, /* NR Enable */ ++ {0x49,0x15}, /* Sig_Th Mult */ ++ {0x4B,0x0A}, /* Pre_Th Mult */ ++ ++ {0xfc,0x0b}, ++ {0x28,0x00}, /* NR start AGC */ ++ {0x29,0x00}, /* SIG Th AGCMIN H */ ++ {0x2a,0x14}, /* SIG Th AGCMIN L */ ++ {0x2b,0x00}, /* SIG Th AGCMAX H */ ++ {0x2c,0x14}, /* SIG Th AGCMAX L */ ++ {0x2d,0x00}, /* PRE Th AGCMIN H */ ++ {0x2e,0x90}, /* PRE Th AGCMIN L */ ++ {0x2f,0x01}, /* PRE Th AGCMAX H */ ++ {0x30,0x00}, /* PRE Th AGCMAX L */ ++ {0x31,0x00}, /* POST Th AGCMIN H */ ++ {0x32,0xa0}, /* POST Th AGCMIN L */ ++ {0x33,0x01}, /* POST Th AGCMAX H */ ++ {0x34,0x10}, /* POST Th AGCMAX L */ ++ ++ /* ++ * 1D-Y/C-SIGMA-LPF ++ */ ++ ++ {0xfc,0x01}, ++ {0x05,0xc0}, ++ ++ {0xfc,0x0b}, ++ {0x35,0x00}, /* YLPF start AGC */ ++ {0x36,0x40}, /* YLPF01 AGCMIN */ ++ {0x37,0x60}, /* YLPF01 AGCMAX */ ++ {0x38,0x00}, /* YLPF SIG01 Th AGCMINH */ ++ {0x39,0x18}, /* YLPF SIG01 Th AGCMINL */ ++ {0x3a,0x00}, /* YLPF SIG01 Th AGCMAXH */ ++ {0x3b,0x40}, /* YLPF SIG01 Th AGCMAXH */ ++ {0x3c,0x50}, /* YLPF02 AGCMIN */ ++ {0x3d,0x60}, /* YLPF02 AGCMAX */ ++ {0x3e,0x00}, /* YLPF SIG02 Th AGCMINH */ ++ {0x3f,0x30}, /* YLPF SIG02 Th AGCMINL */ ++ {0x40,0x00}, /* YLPF SIG02 Th AGCMAXH */ ++ {0x41,0x40}, /* YLPF SIG02 Th AGCMAXH */ ++ {0xd4,0x40}, /* CLPF AGCMIN */ ++ {0xd5,0x60}, /* CLPF AGCMAX */ ++ {0xd6,0xb0}, /* CLPF SIG01 Th AGCMIN */ ++ {0xd7,0xf0}, /* CLPF SIG01 Th AGCMAX */ ++ {0xd8,0xb0}, /* CLPF SIG02 Th AGCMIN */ ++ {0xd9,0xf0}, /* CLPF SIG02 Th AGCMAX */ ++ ++ /* ++ * COLOR SUPPRESS ++ */ ++ ++ {0xfc,0x0b}, ++ {0x08,0x58}, /* Color suppress AGC MIN */ ++ {0x09,0x03}, /* Color suppress MIN H */ ++ {0x0a,0x80}, /* Color suppress MIN L */ ++ ++ /* ++ * SHADING ++ */ ++ ++ {0xfc,0x09}, ++ //Shading file for 3BAFX ++ //s90000// shading off ++ // DSP9_SH_WIDTH_H ++ {0x01,0x06}, ++ {0x02,0x40}, ++ // DSP9_SH_HEIGHT_H ++ {0x03,0x04}, ++ {0x04,0xB0}, ++ // DSP9_SH_XCH_R ++ {0x05,0x03}, ++ {0x06,0x1A}, ++ {0x07,0x02}, ++ {0x08,0x4E}, ++ // DSP9_SH_XCH_G ++ {0x09,0x03}, ++ {0x0A,0x27}, ++ {0x0B,0x02}, ++ {0x0C,0x11}, ++ // DSP9_SH_XCH_B ++ {0x0D,0x03}, ++ {0x0E,0x15}, ++ {0x0F,0x01}, ++ {0x10,0xE3}, ++ // DSP9_SH_Del_eH_R ++ {0x1D,0x85}, ++ {0x1E,0x55}, ++ {0x1F,0x77}, ++ {0x20,0x9E}, ++ {0x23,0x7F}, ++ {0x24,0xE6}, ++ {0x21,0x7F}, ++ {0x22,0xE6}, ++ // DSP9_SH_Del_eH_G ++ {0x25,0x82}, ++ {0x26,0x9A}, ++ {0x27,0x78}, ++ {0x28,0xC0}, ++ {0x2B,0x76}, ++ {0x2C,0x07}, ++ {0x29,0x86}, ++ {0x2A,0x09}, ++ // DSP9_SH_Del_eH_B ++ {0x2D,0x85}, ++ {0x2E,0x55}, ++ {0x2F,0x75}, ++ {0x30,0x6D}, ++ {0x33,0x74}, ++ {0x34,0xA2}, ++ {0x31,0x84}, ++ {0x32,0xA2}, ++ // DSP9_SH_VAL_R0H ++ {0x35,0x01}, ++ {0x36,0x01}, ++ {0x37,0x01}, ++ {0x38,0x14}, ++ {0x39,0x01}, ++ {0x3A,0x45}, ++ {0x3B,0x01}, ++ {0x3C,0x8A}, ++ {0x3D,0x01}, ++ {0x3E,0xA3}, ++ {0x3F,0x01}, ++ {0x40,0xB9}, ++ {0x41,0x01}, ++ {0x42,0xD9}, ++ {0x43,0x01}, ++ {0x44,0xF6}, ++ // DSP9_SH_VAL_G0H ++ {0x45,0x01}, ++ {0x46,0x00}, ++ {0x47,0x01}, ++ {0x48,0x0E}, ++ {0x49,0x01}, ++ {0x4A,0x34}, ++ {0x4B,0x01}, ++ {0x4C,0x68}, ++ {0x4D,0x01}, ++ {0x4E,0x76}, ++ {0x4F,0x01}, ++ {0x50,0x94}, ++ {0x51,0x01}, ++ {0x52,0xAB}, ++ {0x53,0x01}, ++ {0x54,0xC3}, ++ // DSP9_SH_VAL_B0H ++ {0x55,0x01}, ++ {0x56,0x00}, ++ {0x57,0x01}, ++ {0x58,0x0C}, ++ {0x59,0x01}, ++ {0x5A,0x2B}, ++ {0x5B,0x01}, ++ {0x5C,0x5D}, ++ {0x5D,0x01}, ++ {0x5E,0x70}, ++ {0x5F,0x01}, ++ {0x60,0x8A}, ++ {0x61,0x01}, ++ {0x62,0xA1}, ++ {0x63,0x01}, ++ {0x64,0xB3}, ++ // DSP9_SH_M_R2_R1H ++ {0x65,0x00}, ++ {0x66,0x98}, ++ {0x67,0x2C}, ++ {0x68,0x02}, ++ {0x69,0x60}, ++ {0x6A,0xB0}, ++ {0x6B,0x05}, ++ {0x6C,0x59}, ++ {0x6D,0x8C}, ++ {0x6E,0x07}, ++ {0x6F,0x48}, ++ {0x70,0x1B}, ++ {0x71,0x09}, ++ {0x72,0x82}, ++ {0x73,0xC0}, ++ {0x74,0x0C}, ++ {0x75,0x09}, ++ {0x76,0x7B}, ++ {0x77,0x0E}, ++ {0x78,0xDC}, ++ {0x79,0x4D}, ++ // DSP9_SH_M_R2_G1H ++ {0x7A,0x00}, ++ {0x7B,0xAD}, ++ {0x7C,0x76}, ++ {0x7D,0x02}, ++ {0x7E,0xB5}, ++ {0x7F,0xD7}, ++ {0x80,0x06}, ++ {0x81,0x19}, ++ {0x82,0x23}, ++ {0x83,0x08}, ++ {0x84,0x4C}, ++ {0x85,0xE2}, ++ {0x86,0x0A}, ++ {0x87,0xD7}, ++ {0x88,0x5C}, ++ {0x89,0x0D}, ++ {0x8A,0xB8}, ++ {0x8B,0x90}, ++ {0x8C,0x10}, ++ {0x8D,0xF0}, ++ {0x8E,0x7F}, ++ // DSP9_SH_M_R2_B1H ++ {0x8F,0x00}, ++ {0x90,0xC1}, ++ {0x91,0xD0}, ++ {0x92,0x03}, ++ {0x93,0x07}, ++ {0x94,0x3F}, ++ {0x95,0x06}, ++ {0x96,0xD0}, ++ {0x97,0x4F}, ++ {0x98,0x09}, ++ {0x99,0x46}, ++ {0x9A,0x32}, ++ {0x9B,0x0C}, ++ {0x9C,0x1C}, ++ {0x9D,0xFE}, ++ {0x9E,0x0F}, ++ {0x9F,0x54}, ++ {0xA0,0xB1}, ++ {0xA1,0x12}, ++ {0xA2,0xED}, ++ {0xA3,0x4C}, ++ // DSP9_SH_SUB_RR0H ++ {0xA4,0x6B}, ++ {0xA5,0xAA}, ++ {0xA6,0x23}, ++ {0xA7,0xE3}, ++ {0xA8,0x15}, ++ {0xA9,0x88}, ++ {0xAA,0x21}, ++ {0xAB,0x20}, ++ {0xAC,0x1C}, ++ {0xAD,0xB6}, ++ {0xAE,0x19}, ++ {0xAF,0x55}, ++ {0xB0,0x16}, ++ {0xB1,0xAA}, ++ // DSP9_SH_SUB_RG0H ++ {0xB2,0x5E}, ++ {0xB3,0x74}, ++ {0xB4,0x1F}, ++ {0xB5,0x7C}, ++ {0xB6,0x12}, ++ {0xB7,0xE4}, ++ {0xB8,0x1D}, ++ {0xB9,0x10}, ++ {0xBA,0x19}, ++ {0xBB,0x30}, ++ {0xBC,0x16}, ++ {0xBD,0x39}, ++ {0xBE,0x13}, ++ {0xBF,0xE2}, ++ // DSP9_SH_SUB_RB0H ++ {0xC0,0x54}, ++ {0xC1,0x89}, ++ {0xC2,0x1C}, ++ {0xC3,0x2D}, ++ {0xC4,0x10}, ++ {0xC5,0xE8}, ++ {0xC6,0x1A}, ++ {0xC7,0x02}, ++ {0xC8,0x16}, ++ {0xC9,0x8A}, ++ {0xCA,0x13}, ++ {0xCB,0xE4}, ++ {0xCC,0x11}, ++ {0xCD,0xCC}, ++ ++ {0x00,0x02}, // Shading on ++ ++ //========================================================== ++ // X-SHADING ++ //========================================================== ++ {0xfc,0x1B}, ++ {0x80,0x01}, ++ {0x81,0x00}, ++ {0x82,0x4C}, ++ {0x83,0x00}, ++ {0x84,0x86}, ++ {0x85,0x03}, ++ {0x86,0x5E}, ++ {0x87,0x00}, ++ {0x88,0x07}, ++ {0x89,0xA4}, ++ {0x90,0x00}, ++ {0x91,0x12}, ++ {0x92,0x00}, ++ {0x93,0x12}, ++ {0x94,0x00}, ++ {0x95,0x12}, ++ {0x96,0x00}, ++ {0x97,0x12}, ++ {0x98,0x00}, ++ {0x99,0x12}, ++ {0x9A,0x00}, ++ {0x9B,0x12}, ++ {0x9C,0x00}, ++ {0x9D,0x12}, ++ {0x9E,0x00}, ++ {0x9F,0x12}, ++ {0xA0,0x00}, ++ {0xA1,0x12}, ++ {0xA2,0x00}, ++ {0xA3,0x12}, ++ {0xA4,0x00}, ++ {0xA5,0x12}, ++ {0xA6,0x00}, ++ {0xA7,0x12}, ++ {0xA8,0x00}, ++ {0xA9,0x12}, ++ {0xAA,0x00}, ++ {0xAB,0x12}, ++ {0xAC,0x00}, ++ {0xAD,0x12}, ++ {0xAE,0x00}, ++ {0xAF,0x12}, ++ {0xB0,0x00}, ++ {0xB1,0x12}, ++ {0xB2,0x00}, ++ {0xB3,0x12}, ++ {0xB4,0x00}, ++ {0xB5,0x12}, ++ {0xB6,0x00}, ++ {0xB7,0x15}, ++ {0xB8,0x00}, ++ {0xB9,0x12}, ++ {0xBA,0x00}, ++ {0xBB,0x12}, ++ {0xBC,0x00}, ++ {0xBD,0x12}, ++ {0xBE,0x00}, ++ {0xBF,0x12}, ++ {0xC0,0x00}, ++ {0xC1,0x12}, ++ {0xC2,0x00}, ++ {0xC3,0x12}, ++ {0xC4,0x00}, ++ {0xC5,0x12}, ++ {0xC6,0x00}, ++ {0xC7,0x12}, ++ {0xC8,0x00}, ++ {0xC9,0x12}, ++ {0xCA,0x00}, ++ {0xCB,0x12}, ++ {0xCC,0x00}, ++ {0xCD,0x12}, ++ {0xCE,0x00}, ++ {0xCF,0x12}, ++ {0xD0,0x00}, ++ {0xD1,0x12}, ++ {0xD2,0x00}, ++ {0xD3,0x12}, ++ {0xD4,0x00}, ++ {0xD5,0x12}, ++ // x-shading temp. correlation factor ++ {0xfc,0x0b}, ++ {0xda,0x00}, // t0(3100K) ++ {0xdb,0xac}, ++ {0xdc,0x01}, // tc(5100K) ++ {0xdd,0x30}, // default eeh ++ ++ {0xfc,0x00}, ++ {0x81,0x10}, // xshading tem ++ ++ {0xfc,0x1b}, ++ {0x80,0x01}, // X-Shading On ++ ++ //========================================================== ++ // AE WINDOW WEIGHT ++ //========================================================== ++ {0xfc,0x00}, ++ {0x03,0x4b}, // AE Suppress On ++ ++ {0xfc,0x06}, ++ {0x01,0x35}, // UXGA AE Window ++ {0x03,0xc2}, ++ {0x05,0x48}, ++ {0x07,0xb8}, ++ {0x31,0x2a}, // Subsampling AE Window ++ {0x33,0x61}, ++ {0x35,0x28}, ++ {0x37,0x5c}, ++ {0x39,0x28}, ++ {0x3B,0x5A}, ++ {0x3D,0x10}, // 1c ++ {0x3F,0x44}, ++ ++ {0xfc,0x20}, ++ {0x60,0x11}, ++ {0x61,0x11}, ++ {0x62,0x11}, ++ {0x63,0x11}, ++ {0x64,0x11}, ++ {0x65,0x22}, ++ {0x66,0x22}, ++ {0x67,0x11}, ++ {0x68,0x11}, ++ {0x69,0x33}, ++ {0x6a,0x33}, ++ {0x6b,0x11}, ++ {0x6c,0x12}, ++ {0x6d,0x55}, ++ {0x6e,0x55}, ++ {0x6f,0x21}, ++ {0x70,0x13}, ++ {0x71,0x55}, ++ {0x72,0x55}, ++ {0x73,0x31}, ++ {0x74,0x33}, ++ {0x75,0x33}, ++ {0x76,0x33}, ++ {0x77,0x33}, ++ ++ //========================================================== ++ // SAIT AWB ++ //========================================================== ++ //================================= ++ // White Point ++ //================================= ++ {0xfc,0x22}, // White Point (For Hue Control & MWB) ++ {0x01,0xD0}, // D65 ++ {0x03,0x9B}, ++ {0x05,0xC0}, // 5000K ++ {0x07,0xB8}, ++ {0x09,0xA7}, // CWF ++ {0x0b,0xDC}, ++ {0x0d,0x98}, // 3000K ++ {0x0f,0xE0}, ++ {0x11,0x85}, // A ++ {0x12,0x00}, ++ {0x13,0xF6}, ++ {0x15,0x80}, // 2000K ++ {0x16,0x01}, ++ {0x17,0x00}, ++ ++ //================================= ++ // Basic Setting ++ //================================= ++ {0xfc,0x22}, ++ {0xA0,0x01}, ++ {0xA1,0x3F}, ++ {0xA2,0x0E}, ++ {0xA3,0x65}, ++ {0xA4,0x07}, ++ {0xA5,0xF4}, ++ {0xA6,0x11}, ++ {0xA7,0xC8}, ++ {0xA9,0x02}, ++ {0xAA,0x43}, ++ {0xAB,0x26}, ++ {0xAC,0x1F}, ++ {0xAD,0x02}, ++ {0xAE,0x2C}, ++ {0xAF,0x19}, ++ {0xB0,0x0F}, ++ ++ {0x94,0x3C}, ++ {0x95,0xCC}, ++ {0x96,0x5C}, ++ {0x97,0x4D}, ++ {0xD0,0xA8}, ++ {0xD1,0x29}, ++ {0xD2,0x39}, ++ {0xD3,0x22}, ++ {0xD4,0x30}, ++ {0xDB,0x29}, ++ {0xDC,0x7E}, ++ {0xDD,0x22}, ++ ++ {0xE7,0x00}, ++ {0xE8,0xca}, ++ {0xE9,0x00}, ++ {0xEA,0x62}, ++ {0xEB,0x00}, ++ {0xEC,0x00}, ++ {0xEE,0x97}, ++ ++ //================================= ++ // Pixel Filter Setting ++ //================================= ++ {0xFC,0x07}, ++ {0x95,0x8F}, ++ ++ {0xfc,0x01}, ++ {0xD3,0x4B}, ++ {0xD4,0x00}, ++ {0xD5,0x38}, ++ {0xD6,0x00}, ++ {0xD7,0x60}, ++ {0xD8,0x00}, ++ {0xD9,0x4E}, ++ {0xDA,0x00}, ++ {0xDB,0x27}, ++ {0xDC,0x15}, ++ {0xDD,0x23}, ++ {0xDE,0xAD}, ++ {0xDF,0x24}, ++ {0xE0,0x01}, ++ {0xE1,0x17}, ++ {0xE2,0x4A}, ++ {0xE3,0x36}, ++ {0xE4,0x40}, ++ {0xE5,0x40}, ++ {0xE6,0x40}, ++ {0xE7,0x40}, ++ {0xE8,0x30}, ++ {0xE9,0x3D}, ++ {0xEA,0x17}, ++ {0xEB,0x01}, ++ ++ //================================= ++ // Polygon AWB Region Tune ++ //================================= ++ {0xfc,0x22}, ++ {0x18,0x00}, // 1 ++ {0x19,0x5a}, ++ {0x1a,0xf8}, ++ {0x1b,0x00}, // 2 ++ {0x1c,0x59}, ++ {0x1d,0xCC}, ++ {0x1e,0x00}, // 3 ++ {0x1f,0x74}, ++ {0x20,0xB3}, ++ {0x21,0x00}, // 4 ++ {0x22,0x86}, ++ {0x23,0xA2}, ++ {0x24,0x00}, // 5 ++ {0x25,0x94}, ++ {0x26,0x89}, ++ {0x27,0x00}, // 6 ++ {0x28,0xA6}, ++ {0x29,0x76}, ++ {0x2A,0x00}, // 7 ++ {0x2B,0xd0}, ++ {0x2C,0x5e}, ++ {0x2D,0x00}, // 8 ++ {0x2E,0xfa}, ++ {0x2F,0x47}, ++ {0x30,0x00}, // 9 ++ {0x31,0xfD}, ++ {0x32,0x5D}, ++ {0x33,0x00}, // 10 ++ {0x34,0xBB}, ++ {0x35,0x7c}, ++ {0x36,0x00}, // 11 ++ {0x37,0xAD}, ++ {0x38,0x88}, ++ {0x39,0x00}, // 12 ++ {0x3A,0x9A}, ++ {0x3B,0xA3}, ++ {0x3C,0x00}, // 13 ++ {0x3D,0x7C}, ++ {0x3E,0xDD}, ++ {0x3F,0x00}, // 14 ++ {0x40,0x00}, ++ {0x41,0x00}, ++ ++ //================================= ++ // Moving Equation Weight ++ //================================= ++ {0xfc,0x22}, ++ {0x98,0x07}, ++ ++ //================================= ++ // EIT Threshold ++ //================================= ++ {0xfc,0x22}, ++ {0xb1,0x00}, // {0xunny ++ {0xb2,0x03}, ++ {0xb3,0x00}, ++ {0xb4,0xc1}, ++ ++ {0xb5,0x00}, // Cloudy ++ {0xb6,0x05}, ++ {0xb7,0xc9}, ++ {0xb9,0x81}, ++ ++ {0xd7,0x00}, // Shade ++ {0xd8,0x35}, ++ {0xd9,0x20}, ++ {0xda,0x81}, ++ ++ //================================= ++ // Gain Offset ++ //================================= ++ {0xfc,0x00}, ++ {0x79,0xF9}, ++ {0x7A,0x02}, // Global AWB gain off{0xet ++ ++ {0xfc,0x22}, ++ {0x58,0xf6}, // D65 R Off{0xet ++ {0x59,0xff}, // D65 B Off{0xet ++ {0x5A,0xfa}, // 5000K R Off{0xet ++ {0x5B,0xFe}, // 5000K B Off{0xet ++ {0x5C,0xfb}, // CWF R Off{0xet ++ {0x5D,0xFe}, // CWF B Off{0xet ++ {0x5E,0xfb}, // 3000K R Off{0xet ++ {0x5F,0xFb}, // 3000K B Off{0xet ++ {0x60,0xfb}, // A R Off0xet ++ {0x61,0xfb}, // A B Off0xet ++ {0x62,0xfb}, // 2000K R Off0xet ++ {0x63,0xfb}, // 2000K B Off0xet ++ ++ {0xde,0x00}, // LARGE OBJECT BUG FIX ++ {0xf0,0x6a}, // RB Ratio ++ //================================= ++ // Green Stablity Enhance ++ //================================= ++ {0xfc,0x22}, ++ {0xb9,0x00}, ++ {0xba,0x00}, ++ {0xbb,0x00}, ++ {0xbc,0x00}, ++ {0xe5,0x01}, ++ {0xe6,0xff}, ++ ++ {0xbd,0x90}, ++ ++ //========================================================== ++ // Special Effect ++ //========================================================== ++ {0xfc,0x07}, // Special Effect ++ {0x30,0xc0}, ++ {0x31,0x20}, ++ {0x32,0x40}, ++ {0x33,0xc0}, ++ {0x34,0x00}, ++ {0x35,0xb0}, ++ ++ {0xfc,0x00}, ++ {0x73,0x21}, // Frame AE Enable, peter ++ ++ {0xfc,0x04}, ++ {0xc0,0x06}, ++ {0xc1,0x70}, ++ {0xFF,0xFF} // REGISTER END ++}; ++#else ++s5k4xa_t s5k4ba_reg[] = ++{ ++//========================================================== ++// CAMERA INITIAL (Analog & Clock Setting) ++//========================================================== ++ {0xfc, 0x07}, ++ {0x66, 0x01},// WDT ++ {0xfc, 0x00}, ++ {0x00, 0xaa},// For EDS Check ++ {0x21, 0x03},// peter0223 added ++ ++ {0xfc, 0x01}, ++ {0x04, 0x01},// ARM Clock Divider ++ ++ {0xfc, 0x02},// Analog setting ++ {0x55, 0x1e},// LineADLC on(s551a), off(s550a) ++ {0x56, 0x10},// BPR 16code ++ {0x30, 0x82},// Analog offset (capture =?h) ++ {0x37, 0x25},// Global Gain (default:31) ++ ++ {0x57, 0x80},// // LineADLC Roffset ++ {0x58, 0x80},//89 //90 // LineADLC Goffset ++ {0x59, 0x80},//90 // LineADLC offset don't care ++ ++ {0x44, 0x64},//clamp en[6]=1 on ++ {0x4a, 0x30},//clamp level 0011h [7]~[4] ++ ++ {0x2d, 0x48},// double shutter (default:00) ++ {0x4d, 0x08},// Voltage doubler (default:04) ++ {0x4e, 0x00},// IO current 8mA set ++ {0x4f, 0x8a},// IO current 48mA set ++ ++ {0x66, 0x41},// 1st comp current 2uA ++ {0x43, 0xef},// ec_comp ++ {0x62, 0x60},// LD control , CFPN_EN off ++ ++//========================================================== ++// Table Set for Sub-Sampling ++//========================================================== ++ {0xfc, 0x03}, ++ {0x01, 0x60}, ++ //{0x2e, 0x00}, ++ {0x2e, 0x03},//DHL ++ {0x05, 0x46},// Output Image Size Set for Capture ++ {0x07, 0xb6}, ++ {0x0e, 0x04}, ++ {0x12, 0x03}, ++ ++ {0xfc, 0x04}, ++ {0xc5, 0x26},// Output Image Size Set for Preview ++ {0xc7, 0x5e}, ++ {0xce, 0x04}, ++ {0xd2, 0x04}, ++ //{0xee, 0x00},//DHL ++ {0xee, 0x01}, ++ {0xc0, 0x06}, ++ {0xc1, 0x60},//frame_H ++ {0xc2, 0x02}, ++ {0xc3, 0x8d},//frame_V ++ ++ {0xfc, 0x07}, ++ {0x05, 0x00}, ++ {0x06, 0x00}, ++ {0x07, 0x8b}, ++ {0x08, 0xf5}, ++ {0x09, 0x00}, ++ {0x0a, 0xb4}, ++ {0x0b, 0x00}, ++ {0x0c, 0xea}, ++ {0x0d, 0x00}, ++ {0x0e, 0x40}, ++ ++#if 1 ++//========================================================== ++// COMMAND SET ++//========================================================== ++ {0xfc, 0x00}, ++ {0x70, 0x02}, ++ ++ {0xfc, 0x00}, ++ {0x73, 0x11},//21 Frmae AE Enable, peter0223 ++ {0x20, 0x02},// Change AWB Mode ++ ++ {0xfc, 0x00}, ++ {0x78, 0x6a},// AGC Max ++ ++ {0xfc, 0x00}, ++ {0x6c, 0xa0},// AE target ++ {0x6d, 0x00}, ++ ++ {0xfc, 0x20}, ++ {0x16, 0x5a},// AGC frame AE start _for Prevating AE Hunting ++ {0x57, 0x18},// Stable_Frame_AE ++ ++ {0xfc, 0x00}, ++ {0x83, 0x06},//low condition shutter off // Double shutter off ++ ++ {0xfc, 0x0b}, ++ {0x5c, 0x69},//70 //AGC value to start shutter on/off suppress ++ {0x5d, 0x65},//60 //AGC value to start double shutter on/off suppress ++ ++ {0xfc, 0x20}, ++ {0x25, 0x00},// CINTR Min ++ {0x2a, 0x01},// forbidden ++ {0x2b, 0x02},// For Forbidden Area ++ {0x2c, 0x0a}, ++ {0x2d, 0x00},// For Forbidden Area ++ {0x2e, 0x00}, ++ {0x2f, 0x05},// forbidden ++ {0x14, 0x78},//70 ++ {0x01, 0x00},// Stepless_Off ++ ++ {0xfc, 0x00}, ++ {0x29, 0x04},// Y level ++ {0x2a, 0x00}, ++ {0x2b, 0x03},// C level ++ {0x2c, 0x80},//60 ++ ++ {0xfc, 0x07}, ++ {0x37, 0x00},// Flicker ++ ++ {0xfc, 0x00}, ++ {0x72, 0xa0},// Flicker for 32MHz ++ {0x74, 0x08},// flicker 60Hz fix ++ {0xfc, 0x20}, ++ {0x02, 0x12},//02 Flicker Dgain Mode ++ {0xfc, 0x00}, ++ {0x62, 0x02},// Hue Control Enable ++ ++ {0xfc, 0x01}, ++ //{0x0c, 0x02},// Full YC Enable ++ {0x0C, 0x03},//Donghoon ++ ++ ++//========================================================== ++// COLOR MATRIX ++//========================================================== ++ {0xfc, 0x01}, //DL gain 60 ++ {0x51, 0x08}, //06 //08 07 ++ {0x52, 0xe8}, //df //9B E7 ++ {0x53, 0xfc}, //fd //FC FB ++ {0x54, 0x33}, //09 //07 B9 ++ {0x55, 0xfe}, //00 //FF 00 ++ {0x56, 0xe6}, //17 //5E 5F ++ {0x57, 0xfe}, //fe //FD FD ++ {0x58, 0x3d}, //4f //0E 46 ++ {0x59, 0x08}, //06 //07 05 ++ {0x5a, 0x21}, //9b //EE E6 ++ {0x5b, 0xfd}, //ff //FF 00 ++ {0x5c, 0xa3}, //17 //05 D3 ++ {0x5d, 0xff}, //ff //FF FF ++ {0x5e, 0xbc}, //81 //7A 53 ++ {0x5f, 0xfc}, //fd //FC FB ++ {0x60, 0x96}, //5b //23 B1 ++ {0x61, 0x07}, //07 //08 08 ++ {0x62, 0xaf}, //24 //64 FD ++ ++//========================================================== ++// EDGE ENHANCEMENT ++//========================================================== ++ {0xfc, 0x05}, ++ {0x12, 0x3d}, ++ {0x13, 0x3b}, ++ {0x14, 0x38}, ++ {0x15, 0x3b}, ++ {0x16, 0x3d}, ++ ++ {0x17, 0x3b}, ++ {0x18, 0x05}, ++ {0x19, 0x09}, ++ {0x1a, 0x05}, ++ {0x1b, 0x3b}, ++ ++ {0x1c, 0x38}, ++ {0x1d, 0x09}, ++ {0x1e, 0x1c}, ++ {0x1f, 0x09}, ++ {0x20, 0x38}, ++ ++ {0x21, 0x3b}, ++ {0x22, 0x05}, ++ {0x23, 0x09}, ++ {0x24, 0x05}, ++ {0x25, 0x3b}, ++ ++ {0x26, 0x3d}, ++ {0x27, 0x3b}, ++ {0x28, 0x38}, ++ {0x29, 0x3b}, ++ {0x2a, 0x3d}, ++ ++ {0xfc, 0x00}, ++ {0x89, 0x00},// Edge Suppress On ++ {0xfc, 0x0b}, ++ {0x42, 0x50},// Edge AGC MIN ++ {0x43, 0x60},// Edge AGC MAX ++ {0x45, 0x18},// positive gain AGC MIN ++ {0x49, 0x06},// positive gain AGC MAX ++ {0x4d, 0x18},// negative gain AGC MIN ++ {0x51, 0x06},// negative gain AGC MAX ++ ++ {0xfc, 0x05}, ++ {0x34, 0x28},// APTCLP ++ {0x35, 0x03},// APTSC ++ {0x36, 0x0b},// ENHANCE ++ {0x3f, 0x00},// NON-LIN ++ {0x42, 0x10},// EGFALL ++ {0x43, 0x00},// HLFALL ++ {0x45, 0xa0},// EGREF ++ {0x46, 0x7a},// HLREF ++ {0x47, 0x40},// LLREF ++ {0x48, 0x0c}, ++ {0x49, 0x31},// CSSEL EGSEL CS_DLY ++ ++ {0x40, 0x41},// Y delay ++ ++ // New Wide Luma Edge ++ {0xfc, 0x1d}, ++ {0x86, 0x00}, ++ {0x87, 0x60}, ++ {0x88, 0x01}, ++ {0x89, 0x20}, ++ {0x8a, 0x00}, ++ {0x8b, 0x00}, ++ {0x8c, 0x00}, ++ {0x8d, 0x00}, ++ {0x8e, 0x00}, ++ {0x8f, 0x20}, ++ {0x90, 0x00}, ++ {0x91, 0x00}, ++ {0x92, 0x00}, ++ {0x93, 0x0a}, ++ {0x94, 0x00}, ++ {0x95, 0x00}, ++ {0x96, 0x00}, ++ {0x97, 0x20}, ++ {0x98, 0x00}, ++ {0x99, 0x00}, ++ {0x9a, 0xff}, ++ {0x9b, 0xea}, ++ {0x9c, 0xaa}, ++ {0x9d, 0xab}, ++ {0x9e, 0xff}, ++ {0x9f, 0xf1}, ++ {0xa0, 0x55}, ++ {0xa1, 0x56}, ++ {0xa2, 0x07}, ++ ++ {0x85, 0x01}, ++ ++/* ++ * GAMMA ++ */ ++ ++ {0xfc, 0x1d}, ++ {0x00, 0x0b}, ++ {0x01, 0x18}, ++ {0x02, 0x3d}, ++ {0x03, 0x9c}, ++ {0x04, 0x00}, ++ {0x05, 0x0c}, ++ {0x06, 0x76}, ++ {0x07, 0xc2}, ++ {0x08, 0x00}, ++ {0x09, 0x56}, ++ {0x0a, 0x34}, ++ {0x0b, 0x60}, ++ {0x0c, 0x85}, ++ {0x0d, 0xa7}, ++ {0x0e, 0xaa}, ++ {0x0f, 0xc6}, ++ {0x10, 0xe2}, ++ {0x11, 0xfc}, ++ {0x12, 0x13}, ++ {0x13, 0xab}, ++ {0x14, 0x29}, ++ {0x15, 0x3c}, ++ {0x16, 0x4b}, ++ {0x17, 0x5a}, ++ {0x18, 0xff}, ++ {0x19, 0x69}, ++ {0x1a, 0x78}, ++ {0x1b, 0x84}, ++ {0x1c, 0x91}, ++ {0x1d, 0xff}, ++ {0x1e, 0x9c}, ++ {0x1f, 0xa7}, ++ {0x20, 0xb2}, ++ {0x21, 0xbd}, ++ {0x22, 0xff}, ++ {0x23, 0xc7}, ++ {0x24, 0xd2}, ++ {0x25, 0xdb}, ++ {0x26, 0xe4}, ++ {0x27, 0xff}, ++ {0x28, 0xec}, ++ {0x29, 0xf5}, ++ {0x2a, 0xf0}, ++ {0x2b, 0x0b}, ++ {0x2c, 0x18}, ++ {0x2d, 0x3d}, ++ {0x2e, 0x9c}, ++ {0x2f, 0x00}, ++ {0x30, 0x0c}, ++ {0x31, 0x76}, ++ {0x32, 0xc2}, ++ {0x33, 0x00}, ++ {0x34, 0x56}, ++ {0x35, 0x34}, ++ {0x36, 0x60}, ++ {0x37, 0x85}, ++ {0x38, 0xa7}, ++ {0x39, 0xaa}, ++ {0x3a, 0xc6}, ++ {0x3b, 0xe2}, ++ {0x3c, 0xfc}, ++ {0x3d, 0x13}, ++ {0x3e, 0xab}, ++ {0x3f, 0x29}, ++ {0x40, 0x3c}, ++ {0x41, 0x4b}, ++ {0x42, 0x5a}, ++ {0x43, 0xff}, ++ {0x44, 0x69}, ++ {0x45, 0x78}, ++ {0x46, 0x84}, ++ {0x47, 0x91}, ++ {0x48, 0xff}, ++ {0x49, 0x9c}, ++ {0x4a, 0xa7}, ++ {0x4b, 0xb2}, ++ {0x4c, 0xbd}, ++ {0x4d, 0xff}, ++ {0x4e, 0xc7}, ++ {0x4f, 0xd2}, ++ {0x50, 0xdb}, ++ {0x51, 0xe4}, ++ {0x52, 0xff}, ++ {0x53, 0xec}, ++ {0x54, 0xf5}, ++ {0x55, 0xf0}, ++ {0x56, 0x0b}, ++ {0x57, 0x18}, ++ {0x58, 0x3d}, ++ {0x59, 0x9c}, ++ {0x5a, 0x00}, ++ {0x5b, 0x0c}, ++ {0x5c, 0x76}, ++ {0x5d, 0xc2}, ++ {0x5e, 0x00}, ++ {0x5f, 0x56}, ++ {0x60, 0x34}, ++ {0x61, 0x60}, ++ {0x62, 0x85}, ++ {0x63, 0xa7}, ++ {0x64, 0xaa}, ++ {0x65, 0xc6}, ++ {0x66, 0xe2}, ++ {0x67, 0xfc}, ++ {0x68, 0x13}, ++ {0x69, 0xab}, ++ {0x6a, 0x29}, ++ {0x6b, 0x3c}, ++ {0x6c, 0x4b}, ++ {0x6d, 0x5a}, ++ {0x6e, 0xff}, ++ {0x6f, 0x69}, ++ {0x70, 0x78}, ++ {0x71, 0x84}, ++ {0x72, 0x91}, ++ {0x73, 0xff}, ++ {0x74, 0x9c}, ++ {0x75, 0xa7}, ++ {0x76, 0xb2}, ++ {0x77, 0xbd}, ++ {0x78, 0xff}, ++ {0x79, 0xc7}, ++ {0x7a, 0xd2}, ++ {0x7b, 0xdb}, ++ {0x7c, 0xe4}, ++ {0x7d, 0xff}, ++ {0x7e, 0xec}, ++ {0x7f, 0xf5}, ++ {0x80, 0xf0}, ++ ++/* ++ * HUE CONTROL ++ */ ++ ++ {0xfc, 0x00}, ++ {0x48, 0x40}, /* 2000K */ ++ {0x49, 0x30}, ++ {0x4a, 0x00}, ++ {0x4b, 0x00}, ++ {0x4c, 0x30}, ++ {0x4d, 0x38}, ++ {0x4e, 0x00}, ++ {0x4f, 0x00}, ++ ++ {0x50, 0x40}, /* 3000K */ ++ {0x51, 0x30}, ++ {0x52, 0x00}, ++ {0x53, 0x00}, ++ {0x54, 0x30}, ++ {0x55, 0x38}, ++ {0x56, 0x00}, ++ {0x57, 0x00}, ++ ++ {0x58, 0x3c}, /* 40 - 5100K */ ++ {0x59, 0x30}, /* 4a, 40 */ ++ {0x5a, 0x00}, /* 0c, 00 */ ++ {0x5b, 0x00}, /* 00 */ ++ {0x5c, 0x30}, /* 4a */ ++ {0x5d, 0x38}, /* 40 */ ++ {0x5e, 0x00}, /* f6, 15 */ ++ {0x5f, 0xfc}, /* 00 */ ++ ++/* ++ * SUPPRESS FUNCTION ++ */ ++ ++ {0xfc, 0x00}, ++ {0x7e, 0xf4}, ++ ++/* ++ * BPR ++ */ ++ ++ {0xfc, 0x0b}, ++ {0x3d, 0x10}, ++ ++ {0xfc, 0x0b}, ++ {0x0b, 0x00}, ++ {0x0c, 0x40}, ++ {0x0d, 0x5a}, ++ {0x0e, 0x00}, ++ {0x0f, 0x20}, ++ {0x10, 0x00}, ++ {0x11, 0x10}, ++ {0x12, 0x00}, ++ {0x13, 0x7f}, ++ {0x14, 0x03}, ++ {0x15, 0xff}, ++ {0x16, 0x48}, ++ {0x17, 0x60}, ++ {0x18, 0x00}, ++ {0x19, 0x00}, ++ {0x1a, 0x00}, ++ {0x1b, 0x20}, ++ {0x1c, 0x00}, ++ {0x1d, 0x00}, ++ {0x1e, 0x00}, ++ {0x1f, 0x20}, ++ ++/* ++ * GR/GB CORRECTION ++ */ ++ ++ {0xfc, 0x01}, ++ {0x45, 0x0c}, ++ {0xfc, 0x0b}, ++ {0x21, 0x00}, ++ {0x22, 0x40}, ++ {0x23, 0x60}, ++ {0x24, 0x0d}, ++ {0x25, 0x20}, ++ {0x26, 0x0d}, ++ {0x27, 0x20}, ++ ++/* ++ * NR ++ */ ++ ++ {0xfc, 0x01}, ++ {0x4c, 0x01}, ++ {0x49, 0x15}, ++ {0x4b, 0x0a}, ++ ++ {0xfc, 0x0b}, ++ {0x28, 0x00}, ++ {0x29, 0x00}, ++ {0x2a, 0x14}, ++ {0x2b, 0x00}, ++ {0x2c, 0x14}, ++ {0x2d, 0x00}, ++ {0x2e, 0xD0}, ++ {0x2f, 0x02}, ++ {0x30, 0x00}, ++ {0x31, 0x00}, ++ {0x32, 0xa0}, ++ {0x33, 0x00}, ++ {0x34, 0xe0}, ++ ++/* ++ * 1D-Y/C-SIGMA-LPF ++ */ ++ ++ {0xfc, 0x01}, ++ {0x05, 0xC0}, ++ ++ {0xfc, 0x0b}, ++ {0x35, 0x00}, ++ {0x36, 0x40}, ++ {0x37, 0x60}, ++ {0x38, 0x00}, ++ {0x39, 0x18}, ++ {0x3a, 0x00}, ++ {0x3b, 0x40}, ++ {0x3c, 0x50}, ++ {0x3d, 0x60}, ++ {0x3e, 0x00}, ++ {0x3f, 0x30}, ++ {0x40, 0x00}, ++ {0x41, 0x40}, ++ {0xd4, 0x40}, ++ {0xd5, 0x60}, ++ {0xd6, 0xb0}, ++ {0xd7, 0xf0}, ++ {0xd8, 0xb0}, ++ {0xd9, 0xf0}, ++ ++/* ++ * COLOR SUPPRESS ++ */ ++ ++ {0xfc, 0x0b}, ++ {0x08, 0x58}, ++ {0x09, 0x03}, ++ {0x0a, 0x00}, ++ ++/* ++ * SHADING ++ */ ++ ++ {0xfc, 0x09}, ++ ++ {0x01, 0x06}, ++ {0x02, 0x40}, ++ ++ {0x03, 0x04}, ++ {0x04, 0xB0}, ++ ++ {0x05, 0x03}, ++ {0x06, 0x20}, ++ {0x07, 0x02}, ++ {0x08, 0x91}, ++ ++ {0x09, 0x03}, ++ {0x0A, 0x25}, ++ {0x0B, 0x02}, ++ {0x0C, 0x64}, ++ ++ {0x0D, 0x03}, ++ {0x0E, 0x0F}, ++ {0x0F, 0x02}, ++ {0x10, 0x4E}, ++ ++ {0x1D, 0x80}, ++ {0x1E, 0x00}, ++ {0x1F, 0x80}, ++ {0x20, 0x00}, ++ {0x23, 0x85}, ++ {0x24, 0x52}, ++ {0x21, 0x79}, ++ {0x22, 0xE6}, ++ ++ {0x25, 0x80}, ++ {0x26, 0x00}, ++ {0x27, 0x80}, ++ {0x28, 0x00}, ++ {0x2B, 0x81}, ++ {0x2C, 0x48}, ++ {0x29, 0x81}, ++ {0x2A, 0x48}, ++ ++ {0x2D, 0x80}, ++ {0x2E, 0x00}, ++ {0x2F, 0x80}, ++ {0x30, 0x00}, ++ {0x33, 0x7C}, ++ {0x34, 0x45}, ++ {0x31, 0x7D}, ++ {0x32, 0x7D}, ++ ++ {0x35, 0x01}, ++ {0x36, 0x00}, ++ {0x37, 0x01}, ++ {0x38, 0x11}, ++ {0x39, 0x01}, ++ {0x3A, 0x4E}, ++ {0x3B, 0x01}, ++ {0x3C, 0xAB}, ++ {0x3D, 0x01}, ++ {0x3E, 0xDC}, ++ {0x3F, 0x02}, ++ {0x40, 0x1A}, ++ {0x41, 0x02}, ++ {0x42, 0x6A}, ++ {0x43, 0x02}, ++ {0x44, 0xD3}, ++ ++ {0x45, 0x01}, ++ {0x46, 0x00}, ++ {0x47, 0x01}, ++ {0x48, 0x0E}, ++ {0x49, 0x01}, ++ {0x4A, 0x40}, ++ {0x4B, 0x01}, ++ {0x4C, 0x8A}, ++ {0x4D, 0x01}, ++ {0x4E, 0xB5}, ++ {0x4F, 0x01}, ++ {0x50, 0xE8}, ++ {0x51, 0x02}, ++ {0x52, 0x27}, ++ {0x53, 0x02}, ++ {0x54, 0x84}, ++ ++ {0x55, 0x01}, ++ {0x56, 0x00}, ++ {0x57, 0x01}, ++ {0x58, 0x0C}, ++ {0x59, 0x01}, ++ {0x5A, 0x37}, ++ {0x5B, 0x01}, ++ {0x5C, 0x74}, ++ {0x5D, 0x01}, ++ {0x5E, 0x96}, ++ {0x5F, 0x01}, ++ {0x60, 0xC9}, ++ {0x61, 0x02}, ++ {0x62, 0x04}, ++ {0x63, 0x02}, ++ {0x64, 0x4B}, ++ ++ {0x65, 0x00}, ++ {0x66, 0x9A}, ++ {0x67, 0x2D}, ++ {0x68, 0x02}, ++ {0x69, 0x68}, ++ {0x6A, 0xB6}, ++ {0x6B, 0x05}, ++ {0x6C, 0x6B}, ++ {0x6D, 0x99}, ++ {0x6E, 0x07}, ++ {0x6F, 0x60}, ++ {0x70, 0xAD}, ++ {0x71, 0x09}, ++ {0x72, 0xA2}, ++ {0x73, 0xD7}, ++ {0x74, 0x0C}, ++ {0x75, 0x32}, ++ {0x76, 0x19}, ++ {0x77, 0x0F}, ++ {0x78, 0x0E}, ++ {0x79, 0x70}, ++ ++ {0x7A, 0x00}, ++ {0x7B, 0x9C}, ++ {0x7C, 0x9F}, ++ {0x7D, 0x02}, ++ {0x7E, 0x72}, ++ {0x7F, 0x7A}, ++ {0x80, 0x05}, ++ {0x81, 0x81}, ++ {0x82, 0x94}, ++ {0x83, 0x07}, ++ {0x84, 0x7E}, ++ {0x85, 0x97}, ++ {0x86, 0x09}, ++ {0x87, 0xC9}, ++ {0x88, 0xEA}, ++ {0x89, 0x0C}, ++ {0x8A, 0x63}, ++ {0x8B, 0x8C}, ++ {0x8C, 0x0F}, ++ {0x8D, 0x4B}, ++ {0x8E, 0x7E}, ++ ++ {0x8F, 0x00}, ++ {0x90, 0x9E}, ++ {0x91, 0xBD}, ++ {0x92, 0x02}, ++ {0x93, 0x7A}, ++ {0x94, 0xF5}, ++ {0x95, 0x05}, ++ {0x96, 0x94}, ++ {0x97, 0xA8}, ++ {0x98, 0x07}, ++ {0x99, 0x98}, ++ {0x9A, 0x8F}, ++ {0x9B, 0x09}, ++ {0x9C, 0xEB}, ++ {0x9D, 0xD5}, ++ {0x9E, 0x0C}, ++ {0x9F, 0x8E}, ++ {0xA0, 0x7A}, ++ {0xA1, 0x0F}, ++ {0xA2, 0x80}, ++ {0xA3, 0x7D}, ++ ++ {0xA4, 0x6A}, ++ {0xA5, 0x44}, ++ {0xA6, 0x23}, ++ {0xA7, 0x6C}, ++ {0xA8, 0x15}, ++ {0xA9, 0x40}, ++ {0xAA, 0x20}, ++ {0xAB, 0xB2}, ++ {0xAC, 0x1C}, ++ {0xAD, 0x56}, ++ {0xAE, 0x19}, ++ {0xAF, 0x01}, ++ {0xB0, 0x16}, ++ {0xB1, 0x5F}, ++ ++ {0xB2, 0x68}, ++ {0xB3, 0x9C}, ++ {0xB4, 0x22}, ++ {0xB5, 0xDE}, ++ {0xB6, 0x14}, ++ {0xB7, 0xEC}, ++ {0xB8, 0x20}, ++ {0xB9, 0x30}, ++ {0xBA, 0x1B}, ++ {0xBB, 0xE5}, ++ {0xBC, 0x18}, ++ {0xBD, 0x9D}, ++ {0xBE, 0x16}, ++ {0xBF, 0x05}, ++ ++ {0xC0, 0x67}, ++ {0xC1, 0x36}, ++ {0xC2, 0x22}, ++ {0xC3, 0x67}, ++ {0xC4, 0x14}, ++ {0xC5, 0xA4}, ++ {0xC6, 0x1F}, ++ {0xC7, 0xC2}, ++ {0xC8, 0x1B}, ++ {0xC9, 0x86}, ++ {0xCA, 0x18}, ++ {0xCB, 0x49}, ++ {0xCC, 0x15}, ++ {0xCD, 0xBA}, ++ ++ {0x00, 0x02}, /* shading on */ ++ ++/* ++ * X-SHADING ++ */ ++ ++ {0xfc, 0x1B}, ++ {0x80, 0x01}, ++ {0x81, 0x00}, ++ {0x82, 0x4C}, ++ {0x83, 0x00}, ++ {0x84, 0x86}, ++ {0x85, 0x03}, ++ {0x86, 0x5E}, ++ {0x87, 0x00}, ++ {0x88, 0x07}, ++ {0x89, 0xA4}, ++ {0x90, 0x00}, ++ {0x91, 0x88}, ++ {0x92, 0x00}, ++ {0x93, 0xC1}, ++ {0x94, 0x00}, ++ {0x95, 0xF7}, ++ {0x96, 0x01}, ++ {0x97, 0x21}, ++ {0x98, 0x01}, ++ {0x99, 0x37}, ++ {0x9A, 0x01}, ++ {0x9B, 0x0C}, ++ {0x9C, 0x00}, ++ {0x9D, 0xCE}, ++ {0x9E, 0x00}, ++ {0x9F, 0x3B}, ++ {0xA0, 0x00}, ++ {0xA1, 0x5B}, ++ {0xA2, 0x00}, ++ {0xA3, 0x7A}, ++ {0xA4, 0x00}, ++ {0xA5, 0x92}, ++ {0xA6, 0x00}, ++ {0xA7, 0x91}, ++ {0xA8, 0x00}, ++ {0xA9, 0x81}, ++ {0xAA, 0x00}, ++ {0xAB, 0x60}, ++ {0xAC, 0x07}, ++ {0xAD, 0xCB}, ++ {0xAE, 0x07}, ++ {0xAF, 0xC5}, ++ {0xB0, 0x07}, ++ {0xB1, 0xBB}, ++ {0xB2, 0x07}, ++ {0xB3, 0xAA}, ++ {0xB4, 0x07}, ++ {0xB5, 0xA9}, ++ {0xB6, 0x07}, ++ {0xB7, 0xB2}, ++ {0xB8, 0x07}, ++ {0xB9, 0xBF}, ++ {0xBA, 0x07}, ++ {0xBB, 0x5E}, ++ {0xBC, 0x07}, ++ {0xBD, 0x3C}, ++ {0xBE, 0x06}, ++ {0xBF, 0xF9}, ++ {0xC0, 0x06}, ++ {0xC1, 0xBD}, ++ {0xC2, 0x06}, ++ {0xC3, 0xB8}, ++ {0xC4, 0x06}, ++ {0xC5, 0xE2}, ++ {0xC6, 0x07}, ++ {0xC7, 0x1A}, ++ {0xC8, 0x07}, ++ {0xC9, 0x15}, ++ {0xCA, 0x06}, ++ {0xCB, 0xDE}, ++ {0xCC, 0x06}, ++ {0xCD, 0x9C}, ++ {0xCE, 0x06}, ++ {0xCF, 0x6F}, ++ {0xD0, 0x06}, ++ {0xD1, 0x5E}, ++ {0xD2, 0x06}, ++ {0xD3, 0x84}, ++ {0xD4, 0x06}, ++ {0xD5, 0xCA}, ++ ++ {0xfc, 0x0b}, ++ {0xda, 0x00}, ++ {0xdb, 0x9c}, ++ {0xdc, 0x00}, ++ {0xdd, 0xd1}, ++ ++ {0xfc, 0x1b}, ++ {0x80, 0x01}, ++ ++/* ++ * AE WINDOW WEIGHT ++ */ ++ ++ {0xfc, 0x00}, ++ {0x03, 0x4b}, ++ {0xfc, 0x06}, ++ {0x01, 0x35}, ++ {0x03, 0xc2}, ++ {0x05, 0x48}, ++ {0x07, 0xb8}, ++ {0x31, 0x2a}, ++ {0x33, 0x61}, ++ {0x35, 0x28}, ++ {0x37, 0x5c}, ++ ++ {0xfc, 0x20}, ++ {0x60, 0x11}, ++ {0x61, 0x11}, ++ {0x62, 0x11}, ++ {0x63, 0x11}, ++ {0x64, 0x11}, ++ {0x65, 0x22}, ++ {0x66, 0x22}, ++ {0x67, 0x11}, ++ {0x68, 0x11}, ++ {0x69, 0x33}, ++ {0x6a, 0x33}, ++ {0x6b, 0x11}, ++ {0x6c, 0x12}, ++ {0x6d, 0x55}, ++ {0x6e, 0x55}, ++ {0x6f, 0x21}, ++ {0x70, 0x13}, ++ {0x71, 0x55}, ++ {0x72, 0x55}, ++ {0x73, 0x31}, ++ {0x74, 0x33}, ++ {0x75, 0x33}, ++ {0x76, 0x33}, ++ {0x77, 0x33}, ++ ++/* ++ * SAIT AWB ++ */ ++ ++ {0xfc, 0x00}, ++ {0x7b, 0x00}, ++ ++ {0xfc, 0x07}, ++ {0x3c, 0x10}, ++ {0x3d, 0x10}, ++ {0x3e, 0x10}, ++ {0x3f, 0x10}, ++ ++ {0xfc, 0x01}, ++ {0xc8, 0xe0}, ++ {0xfc, 0x00}, ++ {0x3e, 0x10}, ++ ++ {0xfc, 0x00}, ++ {0x3e, 0x10}, ++ {0x3d, 0x04}, ++ {0x32, 0x02}, ++ {0x81, 0x10}, ++ {0xbc, 0xf0}, ++ {0xfc, 0x22}, ++ {0x8c, 0x04}, ++ {0x8d, 0x06}, ++ ++ {0xfc, 0x07}, ++ {0x97, 0x00}, ++ ++/* ++ * White Point ++ */ ++ ++ {0xfc, 0x22}, ++ {0x01, 0xD8}, ++ {0x03, 0xA1}, ++ {0x05, 0xCA}, ++ {0x07, 0xC8}, ++ {0x09, 0xB3}, ++ {0x0b, 0xE2}, ++ {0x0d, 0xA0}, ++ {0x0f, 0xF0}, ++ {0x11, 0x94}, ++ {0x12, 0x00}, ++ {0x13, 0xFD}, ++ {0x15, 0x88}, ++ {0x16, 0x01}, ++ {0x17, 0x10}, ++ ++/* ++ * Basic Setting ++ */ ++ ++ {0xfc, 0x22}, ++ {0xA8, 0xFF}, ++ ++ {0xA0, 0x01}, ++ {0xA1, 0x38}, ++ {0xA2, 0x0E}, ++ {0xA3, 0x6D}, ++ {0xA4, 0x07}, ++ {0xA5, 0xF5}, ++ {0xA6, 0x11}, ++ {0xA7, 0xBE}, ++ {0xA9, 0x02}, ++ {0xAA, 0xD2}, ++ {0xAB, 0x00}, ++ {0xAC, 0x00}, ++ {0xAD, 0x02}, ++ {0xAE, 0x3F}, ++ {0xAF, 0x19}, ++ {0xB0, 0x91}, ++ {0x94, 0x3D}, ++ {0x95, 0x00}, ++ {0x96, 0x58}, ++ {0x97, 0x80}, ++ {0xD0, 0xA2}, ++ {0xD1, 0x2E}, ++ {0xD2, 0x4D}, ++ {0xD3, 0x28}, ++ {0xD4, 0x90}, ++ {0xDB, 0x2E}, ++ {0xDC, 0x7A}, ++ {0xDD, 0x28}, ++ {0xE7, 0x00}, ++ {0xE8, 0xc7}, ++ {0xE9, 0x00}, ++ {0xEA, 0x62}, ++ {0xEB, 0xD2}, ++ {0xEC, 0xD9}, ++ {0xEE, 0xA6}, ++ ++ {0xfc, 0x00}, ++ {0x8a, 0x02}, ++ ++/* ++ * Pixel Filter Setting ++ */ ++ ++ {0xFC, 0x07}, ++ {0x95, 0xCF}, ++ ++ {0xfc, 0x01}, ++ {0xd3, 0x4f}, ++ {0xd4, 0x00}, ++ {0xd5, 0x3c}, ++ {0xd6, 0x80}, ++ {0xd7, 0x61}, ++ {0xd8, 0x00}, ++ {0xd9, 0x49}, ++ {0xda, 0x00}, ++ {0xdb, 0x24}, ++ {0xdc, 0x4b}, ++ {0xdd, 0x23}, ++ {0xde, 0xf2}, ++ {0xdf, 0x20}, ++ {0xe0, 0x73}, ++ {0xe1, 0x18}, ++ {0xe2, 0x69}, ++ {0xe3, 0x31}, ++ {0xe4, 0x40}, ++ {0xe5, 0x34}, ++ {0xe6, 0x40}, ++ {0xe7, 0x40}, ++ {0xe8, 0x32}, ++ {0xe9, 0x40}, ++ {0xea, 0x1c}, ++ {0xeb, 0x00}, ++ ++/* ++ * Polygon AWB Region Tune ++ */ ++ ++ /* AWB3 - Polygon Region */ ++ {0xfc, 0x22}, ++ {0x18, 0x00}, ++ {0x19, 0x4b}, ++ {0x1a, 0xfd}, ++ {0x1b, 0x00}, ++ {0x1c, 0x41}, ++ {0x1d, 0xd9}, ++ {0x1e, 0x00}, ++ {0x1f, 0x66}, ++ {0x20, 0xa9}, ++ {0x21, 0x00}, ++ {0x22, 0x8b}, ++ {0x23, 0x82}, ++ {0x24, 0x00}, ++ {0x25, 0xa4}, ++ {0x26, 0x6c}, ++ {0x27, 0x00}, ++ {0x28, 0xbd}, ++ {0x29, 0x5d}, ++ {0x2a, 0x00}, ++ {0x2b, 0xdc}, ++ {0x2c, 0x4d}, ++ {0x2d, 0x00}, ++ {0x2e, 0xdc}, ++ {0x2f, 0x63}, ++ {0x30, 0x00}, ++ {0x31, 0xc1}, ++ {0x32, 0x72}, ++ {0x33, 0x00}, ++ {0x34, 0xab}, ++ {0x35, 0x84}, ++ {0x36, 0x00}, ++ {0x37, 0x99}, ++ {0x38, 0xa0}, ++ {0x39, 0x00}, ++ {0x3a, 0x81}, ++ {0x3b, 0xe9}, ++ {0x3c, 0x00}, ++ {0x3d, 0x00}, ++ {0x3e, 0x00}, ++ {0x3f, 0x00}, ++ {0x40, 0x00}, ++ {0x41, 0x00}, ++ ++/* ++ * Moving Equation Weight ++ */ ++ ++ {0xfc, 0x22}, ++ {0x98, 0x07}, ++ ++/* ++ * EIT Threshold ++ */ ++ ++ {0xfc, 0x22}, ++ {0xb1, 0x00}, ++ {0xb2, 0x02}, ++ {0xb3, 0x00}, ++ {0xb4, 0xC1}, ++ ++ {0xb5, 0x00}, ++ {0xb6, 0x02}, ++ {0xb7, 0x00}, ++ {0xb9, 0xc2}, ++ ++ {0xd7, 0x00}, ++ {0xd8, 0x35}, ++ {0xd9, 0x20}, ++ {0xda, 0x81}, ++ ++/* ++ * Gain Offset ++ */ ++ ++ {0xfc, 0x00}, ++ {0x79, 0xf8}, ++ {0x7a, 0x08}, ++ ++ {0xfc, 0x07}, ++ {0x11, 0x01}, ++ ++ {0xfc, 0x22}, ++ {0x58, 0xf8}, ++ {0x59, 0x00}, ++ {0x5A, 0xfc}, ++ {0x5B, 0x00}, ++ {0x5C, 0x00}, ++ {0x5D, 0x00}, ++ {0x5E, 0x00}, ++ {0x5F, 0x00}, ++ {0x60, 0x00}, ++ {0x61, 0xf8}, ++ {0x62, 0x00}, ++ {0x63, 0xf0}, ++ ++ {0xde, 0x00}, ++ {0xf0, 0x6a}, ++ ++/* ++ * Green Stablity Enhance ++ */ ++ ++ {0xfc, 0x22}, ++ {0xb9, 0x00}, ++ {0xba, 0x00}, ++ {0xbb, 0x00}, ++ {0xbc, 0x00}, ++ {0xe5, 0x01}, ++ {0xe6, 0xff}, ++ {0xbd, 0x8c}, ++ ++/* ++ * Special Effect ++ */ ++ ++ {0xfc, 0x07}, ++ {0x30, 0xc0}, ++ {0x31, 0x20}, ++ {0x32, 0x40}, ++ {0x33, 0xc0}, ++ {0x34, 0x00}, ++ {0x35, 0xb0}, ++#endif ++ ++/* ++ * ETC ++ */ ++ ++ {0xfc, 0x01}, ++ {0x01, 0x01}, ++ {0x00, 0x90}, ++ {0xfc, 0x02}, ++ {0x03, 0x20}, ++ ++ {0xfc, 0x20}, ++ {0x0f, 0x00}, ++ ++ {0xfc, 0x00}, ++ {0x02, 0x09}, ++ ++ {0xfc, 0x01}, ++ //{0x02, 0x00}, ++ {0x02, 0x02},//Donghoon ++}; ++#endif ++#else ++#error No samsung CIS moudule ! ++#endif ++ ++ ++/* For VGA ( 640 x 480) on 4BA module */ ++ ++s5k4xa_t s5k4ba_reg_vga[] = ++{ ++ // To do. ++}; ++ ++/* For SVGA ( 800 x 600) on 4BA module */ ++ ++s5k4xa_t s5k4ba_reg_svga[] = ++{ ++ {0xfc,0x02}, ++ {0x2d,0x48}, ++ {0x44,0x63}, ++ ++ {0xfc,0x03}, ++ {0x02,0x04}, ++ {0xfc,0x20}, ++ {0x14,0x70}, ++ ++ {0xfc,0x00}, ++ {0x03,0x4b}, /* AE/AWB On */ ++ {0x7e,0xf4}, /* Suppress On */ ++ {0x89,0x03}, /* Edge Suppress On */ ++ ++ {0xfc,0x02}, ++ {0x02,0x0e}, /* sensor BPRoff */ ++ ++ {0xfc,0x20}, ++ {0x16,0x60}, /* Frame AE Start */ ++ ++ {0xfc,0x02}, ++ {0x30,0x90}, /* Analog offset */ ++ {0x37,0x0d}, /* Global Gain */ ++ {0x60,0x00}, /* Blank_Adrs */ ++ {0x45,0x0e}, /* CDS Timing for Average Sub_Sampling */ ++ {0x47,0x2f}, ++ ++ {0xfc,0x01}, ++ {0x9F,0x05}, /* B */ ++ {0xA0,0x18}, ++ {0xA1,0x42}, ++ {0xA2,0xd7}, ++ {0xA3,0x00}, ++ ++ {0xA4,0xB6}, ++ {0xA5,0x3b}, ++ {0xA6,0x88}, ++ {0xA7,0xC8}, ++ {0xA8,0x6A}, ++ ++ {0xfc,0x05}, ++ {0x34,0x20}, /* APTCLP */ ++ {0x35,0x08}, /* 9 - APTSC */ ++ ++ {0xfc,0x00}, /* flash 0821 */ ++ {0x32,0x04}, /* AWB moving average 8 frame */ ++ ++ {0xfc,0x01}, ++ {0x01,0x01}, /* Pclk inversion */ ++ ++ {0xfc,0x00}, ++ {0x02,0x09}, /* 800 x 600 */ ++ ++ ++ {0xFF,0xFF} /* REGISTER END */ ++}; ++ ++/* For SXGA (1280 x 1024 = 1.3M) on 4BA module */ ++ ++s5k4xa_t s5k4ba_reg_sxga[] = ++{ ++ // To do. ++}; ++ ++ ++/* For UXGA (1600 x 1200 = 2M) on 4BA module */ ++ ++s5k4xa_t s5k4ba_reg_uxga[] = ++{ ++ // To do. ++}; ++ ++ ++/* For SQVGA on 4BA module */ ++ ++s5k4xa_t s5k4ba_reg_qsvga[] = ++{ ++ /* Pclk inversion */ ++ {0xfc,0x01}, ++ {0x01,0x01}, ++ ++ /* To setting CbCr selection on Table 14h */ ++ {0xfc, 0x14}, ++ {0x5c, 0x00}, ++ ++ /* To load table_11 H4V4 */ ++ {0xfc, 0x00}, ++ {0x02, 0x0B} ++}; ++ ++#define S5K4BA_INIT_REGS ARRAY_SIZE(s5k4ba_reg) ++#define S5K4BA_UXGA_REGS ARRAY_SIZE(s5k4ba_reg_uxga) ++#define S5K4BA_SVGA_REGS ARRAY_SIZE(s5k4ba_reg_svga) ++#define S5K4BA_VGA_REGS ARRAY_SIZE(s5k4ba_reg_vga) ++#define S5K4BA_QSVGA_REGS ARRAY_SIZE(s5k4ba_reg_qsvga) ++ ++ ++#define S5K4BA_RISC_REGS 0xEB ++#define S5K4BA_ISP_REGS 0xFB /* S5C7323X */ ++#define S5K4BA_CIS_REGS 0x2F /* S5K437LA03 */ ++ ++ ++#define S5K4BA_REGS (0x1000) ++ ++ ++#endif +diff -ruN --exclude='*.orig' --exclude='*.rej' linux-2.6.29-rc3.owrt/drivers/media/video/samsung/Makefile linux-2.6.29-rc3.owrt.om/drivers/media/video/samsung/Makefile +--- linux-2.6.29-rc3.owrt/drivers/media/video/samsung/Makefile 1970-01-01 01:00:00.000000000 +0100 ++++ linux-2.6.29-rc3.owrt.om/drivers/media/video/samsung/Makefile 2009-05-10 22:27:59.000000000 +0200 +@@ -0,0 +1,4 @@ ++# ++# Samsung CIS camera module ++# ++obj-$(CONFIG_VIDEO_SAMSUNG_S5K4BA) += 4xa_sensor.o +diff -ruN --exclude='*.orig' --exclude='*.rej' linux-2.6.29-rc3.owrt/drivers/media/video/videodev2_s3c.h linux-2.6.29-rc3.owrt.om/drivers/media/video/videodev2_s3c.h +--- linux-2.6.29-rc3.owrt/drivers/media/video/videodev2_s3c.h 1970-01-01 01:00:00.000000000 +0100 ++++ linux-2.6.29-rc3.owrt.om/drivers/media/video/videodev2_s3c.h 2009-05-10 22:28:00.000000000 +0200 +@@ -0,0 +1,210 @@ ++#ifndef __VIDEODEV2_S3C_H_ ++#define __VIDEODEV2_S3C_H_ ++ ++#include <linux/videodev2.h> ++ ++#define V4L2_INPUT_TYPE_MSDMA 3 ++#define V4L2_INPUT_TYPE_INTERLACE 4 ++ ++/**************************************************************** ++* struct v4l2_control ++* Control IDs defined by S3C ++*****************************************************************/ ++/* Image Effect */ ++#define V4L2_CID_ORIGINAL (V4L2_CID_PRIVATE_BASE + 0) ++#define V4L2_CID_ARBITRARY (V4L2_CID_PRIVATE_BASE + 1) ++#define V4L2_CID_NEGATIVE (V4L2_CID_PRIVATE_BASE + 2) ++#define V4L2_CID_ART_FREEZE (V4L2_CID_PRIVATE_BASE + 3) ++#define V4L2_CID_EMBOSSING (V4L2_CID_PRIVATE_BASE + 4) ++#define V4L2_CID_SILHOUETTE (V4L2_CID_PRIVATE_BASE + 5) ++ ++/* Image Rotate */ ++#define V4L2_CID_ROTATE_90 (V4L2_CID_PRIVATE_BASE + 6) ++#define V4L2_CID_ROTATE_180 (V4L2_CID_PRIVATE_BASE + 7) ++#define V4L2_CID_ROTATE_270 (V4L2_CID_PRIVATE_BASE + 8) ++#define V4L2_CID_ROTATE_BYPASS (V4L2_CID_PRIVATE_BASE + 9) ++ ++/* Zoom-in, Zoom-out */ ++#define V4L2_CID_ZOOMIN (V4L2_CID_PRIVATE_BASE + 10) ++#define V4L2_CID_ZOOMOUT (V4L2_CID_PRIVATE_BASE + 11) ++ ++/**************************************************************** ++* I O C T L C O D E S F O R V I D E O D E V I C E S ++* It's only for S3C ++*****************************************************************/ ++#define VIDIOC_S_CAMERA_START _IO ('V', BASE_VIDIOC_PRIVATE + 0) ++#define VIDIOC_S_CAMERA_STOP _IO ('V', BASE_VIDIOC_PRIVATE + 1) ++#define VIDIOC_MSDMA_START _IOW ('V', BASE_VIDIOC_PRIVATE + 2, struct v4l2_msdma_format) ++#define VIDIOC_MSDMA_STOP _IOW ('V', BASE_VIDIOC_PRIVATE + 3, struct v4l2_msdma_format) ++#define VIDIOC_S_MSDMA _IOW ('V', BASE_VIDIOC_PRIVATE + 4, struct v4l2_msdma_format) ++#define VIDIOC_S_INTERLACE_MODE _IOW ('V', BASE_VIDIOC_PRIVATE + 5, struct v4l2_interlace_format) ++ ++/* ++ * INTERLACE MODE ++ */ ++#define S3C_VIDEO_DECODER_PAL 1 /* can decode PAL signal */ ++#define S3C_VIDEO_DECODER_NTSC 2 /* can decode NTSC */ ++#define S3C_VIDEO_DECODER_SECAM 4 /* can decode SECAM */ ++#define S3C_VIDEO_DECODER_AUTO 8 /* can autosense norm */ ++#define S3C_VIDEO_DECODER_CCIR 16 /* CCIR-601 pixel rate (720 pixels per line) instead of square pixel rate */ ++ ++#define S3C_DECODER_INIT _IOW ('V', BASE_VIDIOC_PRIVATE + 14, struct s3c_video_decoder_init) /* init internal registers at once */ ++#define S3C_DECODER_GET_CAPABILITIES _IOR ('V', BASE_VIDIOC_PRIVATE + 6, struct s3c_video_decoder_capability) ++#define S3C_DECODER_GET_STATUS _IOR ('V', BASE_VIDIOC_PRIVATE + 7, int) ++#define S3C_DECODER_SET_NORM _IOW ('V', BASE_VIDIOC_PRIVATE + 8, int) ++#define S3C_DECODER_SET_INPUT _IOW ('V', BASE_VIDIOC_PRIVATE + 9, int) /* 0 <= input < #inputs */ ++#define S3C_DECODER_SET_OUTPUT _IOW ('V', BASE_VIDIOC_PRIVATE + 10, int) /* 0 <= output < #outputs */ ++#define S3C_DECODER_ENABLE_OUTPUT _IOW ('V', BASE_VIDIOC_PRIVATE + 11, int) /* boolean output enable control */ ++#define S3C_DECODER_SET_PICTURE _IOW ('V', BASE_VIDIOC_PRIVATE + 12, struct video_picture) ++#define S3C_DECODER_SET_GPIO _IOW ('V', BASE_VIDIOC_PRIVATE + 13, int) /* switch general purpose pin */ ++#define S3C_DECODER_SET_VBI_BYPASS _IOW ('V', BASE_VIDIOC_PRIVATE + 15, int) /* switch vbi bypass */ ++#define S3C_DECODER_DUMP _IO ('V', BASE_VIDIOC_PRIVATE + 16) /* debug hook */ ++ ++enum v4l2_msdma_input { ++ V4L2_MSDMA_CODEC = 1, ++ V4L2_MSDMA_PREVIEW = 2, ++}; ++ ++struct v4l2_msdma_format ++{ ++ __u32 width; /* MSDMA INPUT : Source X size */ ++ __u32 height; /* MSDMA INPUT : Source Y size */ ++ __u32 pixelformat; ++ enum v4l2_msdma_input input_path; ++}; ++ ++struct v4l2_interlace_format ++{ ++ __u32 width; /* INTERLACE INPUT : Source X size */ ++ __u32 height; /* INTERLACE INPUT : Source Y size */ ++}; ++ ++struct s3c_video_decoder_init { ++ unsigned char len; ++ const unsigned char *data; ++}; ++ ++struct s3c_video_decoder_capability { /* this name is too long */ ++ __u32 flags; ++ int inputs; /* number of inputs */ ++ int outputs; /* number of outputs */ ++}; ++ ++static struct v4l2_input fimc_inputs[] = { ++ { ++ .index = 0, ++ .name = "S3C FIMC External Camera Input", ++ .type = V4L2_INPUT_TYPE_CAMERA, ++ .audioset = 1, ++ .tuner = 0, ++ .std = V4L2_STD_PAL_BG | V4L2_STD_NTSC_M, ++ .status = 0, ++ }, ++ { ++ .index = 1, ++ .name = "Memory Input (MSDMA)", ++ .type = V4L2_INPUT_TYPE_MSDMA, ++ .audioset = 2, ++ .tuner = 0, ++ .std = V4L2_STD_PAL_BG | V4L2_STD_NTSC_M, ++ .status = 0, ++ } ++}; ++ ++static struct v4l2_output fimc_outputs[] = { ++ { ++ .index = 0, ++ .name = "Pingpong Memory Output", ++ .type = 0, ++ .audioset = 0, ++ .modulator = 0, ++ .std = 0, ++ }, ++ { ++ .index = 1, ++ .name = "LCD FIFO Output", ++ .type = 0, ++ .audioset = 0, ++ .modulator = 0, ++ .std = 0, ++ } ++}; ++ ++const struct v4l2_fmtdesc fimc_codec_formats[] = { ++ { ++ .index = 0, ++ .type = V4L2_BUF_TYPE_VIDEO_CAPTURE, ++ .flags = FORMAT_FLAGS_PACKED, ++ .description = "16 bpp RGB, le", ++ .pixelformat = V4L2_PIX_FMT_RGB565, ++ }, ++ { ++ .index = 1, ++ .type = V4L2_BUF_TYPE_VIDEO_CAPTURE, ++ .flags = FORMAT_FLAGS_PACKED, ++ .description = "32 bpp RGB, le", ++ .pixelformat = V4L2_PIX_FMT_BGR32, ++ }, ++ { ++ .index = 2, ++ .type = V4L2_BUF_TYPE_VIDEO_CAPTURE, ++ .flags = FORMAT_FLAGS_PLANAR, ++ .description = "4:2:2, planar, Y-Cb-Cr", ++ .pixelformat = V4L2_PIX_FMT_YUV422P, ++ ++ }, ++ { ++ .index = 3, ++ .type = V4L2_BUF_TYPE_VIDEO_CAPTURE, ++ .flags = FORMAT_FLAGS_PLANAR, ++ .description = "4:2:0, planar, Y-Cb-Cr", ++ .pixelformat = V4L2_PIX_FMT_YUV420, ++ } ++}; ++ ++const struct v4l2_fmtdesc fimc_preview_formats[] = { ++ { ++ .index = 0, ++ .type = V4L2_BUF_TYPE_VIDEO_OVERLAY, ++ .flags = FORMAT_FLAGS_PACKED, ++ .description = "16 bpp RGB, le", ++ .pixelformat = V4L2_PIX_FMT_RGB565, ++ }, ++ { ++ .index = 1, ++ .type = V4L2_BUF_TYPE_VIDEO_OVERLAY, ++ .flags = FORMAT_FLAGS_PACKED, ++ .description = "24 bpp RGB, le", ++ .pixelformat = V4L2_PIX_FMT_RGB24, ++ }, ++ { ++ .index = 2, ++ .type = V4L2_BUF_TYPE_VIDEO_OVERLAY, ++ .flags = FORMAT_FLAGS_PACKED, ++ .description = "32 bpp RGB, le", ++ .pixelformat = V4L2_PIX_FMT_BGR32, ++ }, ++ { ++ .index = 3, ++ .type = V4L2_BUF_TYPE_VIDEO_OVERLAY, ++ .flags = FORMAT_FLAGS_PLANAR, ++ .description = "4:2:2, planar, Y-Cb-Cr", ++ .pixelformat = V4L2_PIX_FMT_YUV422P, ++ ++ }, ++ { ++ .index = 4, ++ .type = V4L2_BUF_TYPE_VIDEO_OVERLAY, ++ .flags = FORMAT_FLAGS_PLANAR, ++ .description = "4:2:0, planar, Y-Cb-Cr", ++ .pixelformat = V4L2_PIX_FMT_YUV420, ++ } ++}; ++ ++#define NUMBER_OF_PREVIEW_FORMATS ARRAY_SIZE(fimc_preview_formats) ++#define NUMBER_OF_CODEC_FORMATS ARRAY_SIZE(fimc_codec_formats) ++#define NUMBER_OF_INPUTS ARRAY_SIZE(fimc_inputs) ++#define NUMBER_OF_OUTPUTS ARRAY_SIZE(fimc_outputs) ++ ++#endif ++ +diff -ruN --exclude='*.orig' --exclude='*.rej' linux-2.6.29-rc3.owrt/drivers/mfd/glamo/glamo-core.c linux-2.6.29-rc3.owrt.om/drivers/mfd/glamo/glamo-core.c +--- linux-2.6.29-rc3.owrt/drivers/mfd/glamo/glamo-core.c 1970-01-01 01:00:00.000000000 +0100 ++++ linux-2.6.29-rc3.owrt.om/drivers/mfd/glamo/glamo-core.c 2009-05-10 22:28:00.000000000 +0200 +@@ -0,0 +1,1457 @@ ++/* Smedia Glamo 336x/337x driver ++ * ++ * (C) 2007 by Openmoko, Inc. ++ * Author: Harald Welte <laforge@openmoko.org> ++ * All rights reserved. ++ * ++ * 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, ++ * MA 02111-1307 USA ++ */ ++ ++#include <linux/module.h> ++#include <linux/kernel.h> ++#include <linux/errno.h> ++#include <linux/string.h> ++#include <linux/mm.h> ++#include <linux/tty.h> ++#include <linux/slab.h> ++#include <linux/delay.h> ++#include <linux/fb.h> ++#include <linux/init.h> ++#include <linux/irq.h> ++#include <linux/interrupt.h> ++#include <linux/workqueue.h> ++#include <linux/wait.h> ++#include <linux/platform_device.h> ++#include <linux/kernel_stat.h> ++#include <linux/spinlock.h> ++#include <linux/glamofb.h> ++#include <linux/mmc/mmc.h> ++#include <linux/mmc/host.h> ++ ++#include <asm/io.h> ++#include <asm/uaccess.h> ++#include <asm/div64.h> ++ ++//#include <mach/regs-irq.h> ++ ++#ifdef CONFIG_PM ++#include <linux/pm.h> ++#endif ++ ++#include "glamo-regs.h" ++#include "glamo-core.h" ++ ++#define RESSIZE(ressource) (((ressource)->end - (ressource)->start)+1) ++ ++#define GLAMO_MEM_REFRESH_COUNT 0x100 ++ ++ ++/* ++ * Glamo internal settings ++ * ++ * We run the memory interface from the faster PLLB on 2.6.28 kernels and ++ * above. Couple of GTA02 users report trouble with memory bus when they ++ * upgraded from 2.6.24. So this parameter allows reversion to 2.6.24 ++ * scheme if their Glamo chip needs it. ++ * ++ * you can override the faster default on kernel commandline using ++ * ++ * glamo3362.slow_memory=1 ++ * ++ * for example ++ */ ++ ++static int slow_memory = 0; ++module_param(slow_memory, int, 0644); ++ ++struct reg_range { ++ int start; ++ int count; ++ char *name; ++ char dump; ++}; ++struct reg_range reg_range[] = { ++ { 0x0000, 0x76, "General", 1 }, ++ { 0x0200, 0x16, "Host Bus", 1 }, ++ { 0x0300, 0x38, "Memory", 1 }, ++/* { 0x0400, 0x100, "Sensor", 0 }, */ ++/* { 0x0500, 0x300, "ISP", 0 }, */ ++/* { 0x0800, 0x400, "JPEG", 0 }, */ ++/* { 0x0c00, 0xcc, "MPEG", 0 }, */ ++ { 0x1100, 0xb2, "LCD 1", 1 }, ++ { 0x1200, 0x64, "LCD 2", 1 }, ++ { 0x1400, 0x40, "MMC", 1 }, ++/* { 0x1500, 0x080, "MPU 0", 0 }, ++ { 0x1580, 0x080, "MPU 1", 0 }, ++ { 0x1600, 0x080, "Cmd Queue", 0 }, ++ { 0x1680, 0x080, "RISC CPU", 0 }, ++ { 0x1700, 0x400, "2D Unit", 0 }, ++ { 0x1b00, 0x900, "3D Unit", 0 }, */ ++}; ++ ++static struct glamo_core *glamo_handle; ++ ++static inline void __reg_write(struct glamo_core *glamo, ++ u_int16_t reg, u_int16_t val) ++{ ++ writew(val, glamo->base + reg); ++} ++ ++static inline u_int16_t __reg_read(struct glamo_core *glamo, ++ u_int16_t reg) ++{ ++ return readw(glamo->base + reg); ++} ++ ++static void __reg_set_bit_mask(struct glamo_core *glamo, ++ u_int16_t reg, u_int16_t mask, ++ u_int16_t val) ++{ ++ u_int16_t tmp; ++ ++ val &= mask; ++ ++ tmp = __reg_read(glamo, reg); ++ tmp &= ~mask; ++ tmp |= val; ++ __reg_write(glamo, reg, tmp); ++} ++ ++static void reg_set_bit_mask(struct glamo_core *glamo, ++ u_int16_t reg, u_int16_t mask, ++ u_int16_t val) ++{ ++ spin_lock(&glamo->lock); ++ __reg_set_bit_mask(glamo, reg, mask, val); ++ spin_unlock(&glamo->lock); ++} ++ ++static inline void __reg_set_bit(struct glamo_core *glamo, ++ u_int16_t reg, u_int16_t bit) ++{ ++ __reg_set_bit_mask(glamo, reg, bit, 0xffff); ++} ++ ++static inline void __reg_clear_bit(struct glamo_core *glamo, ++ u_int16_t reg, u_int16_t bit) ++{ ++ __reg_set_bit_mask(glamo, reg, bit, 0); ++} ++ ++static inline void glamo_vmem_write(struct glamo_core *glamo, u_int32_t addr, ++ u_int16_t *src, int len) ++{ ++ if (addr & 0x0001 || (unsigned long)src & 0x0001 || len & 0x0001) { ++ dev_err(&glamo->pdev->dev, "unaligned write(0x%08x, 0x%p, " ++ "0x%x)!!\n", addr, src, len); ++ } ++ ++} ++ ++static inline void glamo_vmem_read(struct glamo_core *glamo, u_int16_t *buf, ++ u_int32_t addr, int len) ++{ ++ if (addr & 0x0001 || (unsigned long) buf & 0x0001 || len & 0x0001) { ++ dev_err(&glamo->pdev->dev, "unaligned read(0x%p, 0x08%x, " ++ "0x%x)!!\n", buf, addr, len); ++ } ++ ++ ++} ++ ++/*********************************************************************** ++ * resources of sibling devices ++ ***********************************************************************/ ++ ++#if 0 ++static struct resource glamo_core_resources[] = { ++ { ++ .start = GLAMO_REGOFS_GENERIC, ++ .end = GLAMO_REGOFS_GENERIC + 0x400, ++ .flags = IORESOURCE_MEM, ++ }, { ++ .start = 0, ++ .end = 0, ++ .flags = IORESOURCE_IRQ, ++ }, ++}; ++ ++static struct platform_device glamo_core_dev = { ++ .name = "glamo-core", ++ .resource = &glamo_core_resources, ++ .num_resources = ARRAY_SIZE(glamo_core_resources), ++}; ++#endif ++ ++static struct resource glamo_jpeg_resources[] = { ++ { ++ .start = GLAMO_REGOFS_JPEG, ++ .end = GLAMO_REGOFS_MPEG - 1, ++ .flags = IORESOURCE_MEM, ++ }, { ++ .start = IRQ_GLAMO_JPEG, ++ .end = IRQ_GLAMO_JPEG, ++ .flags = IORESOURCE_IRQ, ++ }, ++}; ++ ++static struct platform_device glamo_jpeg_dev = { ++ .name = "glamo-jpeg", ++ .resource = glamo_jpeg_resources, ++ .num_resources = ARRAY_SIZE(glamo_jpeg_resources), ++}; ++ ++static struct resource glamo_mpeg_resources[] = { ++ { ++ .start = GLAMO_REGOFS_MPEG, ++ .end = GLAMO_REGOFS_LCD - 1, ++ .flags = IORESOURCE_MEM, ++ }, { ++ .start = IRQ_GLAMO_MPEG, ++ .end = IRQ_GLAMO_MPEG, ++ .flags = IORESOURCE_IRQ, ++ }, ++}; ++ ++static struct platform_device glamo_mpeg_dev = { ++ .name = "glamo-mpeg", ++ .resource = glamo_mpeg_resources, ++ .num_resources = ARRAY_SIZE(glamo_mpeg_resources), ++}; ++ ++static struct resource glamo_2d_resources[] = { ++ { ++ .start = GLAMO_REGOFS_2D, ++ .end = GLAMO_REGOFS_3D - 1, ++ .flags = IORESOURCE_MEM, ++ }, { ++ .start = IRQ_GLAMO_2D, ++ .end = IRQ_GLAMO_2D, ++ .flags = IORESOURCE_IRQ, ++ }, ++}; ++ ++static struct platform_device glamo_2d_dev = { ++ .name = "glamo-2d", ++ .resource = glamo_2d_resources, ++ .num_resources = ARRAY_SIZE(glamo_2d_resources), ++}; ++ ++static struct resource glamo_3d_resources[] = { ++ { ++ .start = GLAMO_REGOFS_3D, ++ .end = GLAMO_REGOFS_END - 1, ++ .flags = IORESOURCE_MEM, ++ }, ++}; ++ ++static struct platform_device glamo_3d_dev = { ++ .name = "glamo-3d", ++ .resource = glamo_3d_resources, ++ .num_resources = ARRAY_SIZE(glamo_3d_resources), ++}; ++ ++static struct platform_device glamo_spigpio_dev = { ++ .name = "glamo-spi-gpio", ++}; ++ ++static struct resource glamo_fb_resources[] = { ++ /* FIXME: those need to be incremented by parent base */ ++ { ++ .name = "glamo-fb-regs", ++ .start = GLAMO_REGOFS_LCD, ++ .end = GLAMO_REGOFS_MMC - 1, ++ .flags = IORESOURCE_MEM, ++ }, { ++ .name = "glamo-fb-mem", ++ .start = GLAMO_OFFSET_FB, ++ .end = GLAMO_OFFSET_FB + GLAMO_FB_SIZE - 1, ++ .flags = IORESOURCE_MEM, ++ }, ++}; ++ ++static struct platform_device glamo_fb_dev = { ++ .name = "glamo-fb", ++ .resource = glamo_fb_resources, ++ .num_resources = ARRAY_SIZE(glamo_fb_resources), ++}; ++ ++static struct resource glamo_mmc_resources[] = { ++ { ++ /* FIXME: those need to be incremented by parent base */ ++ .start = GLAMO_REGOFS_MMC, ++ .end = GLAMO_REGOFS_MPROC0 - 1, ++ .flags = IORESOURCE_MEM ++ }, { ++ .start = IRQ_GLAMO_MMC, ++ .end = IRQ_GLAMO_MMC, ++ .flags = IORESOURCE_IRQ, ++ }, { /* our data buffer for MMC transfers */ ++ .start = GLAMO_OFFSET_FB + GLAMO_FB_SIZE, ++ .end = GLAMO_OFFSET_FB + GLAMO_FB_SIZE + ++ GLAMO_MMC_BUFFER_SIZE - 1, ++ .flags = IORESOURCE_MEM ++ }, ++}; ++ ++struct glamo_mci_pdata glamo_mci_def_pdata = { ++ .gpio_detect = 0, ++ .glamo_can_set_mci_power = NULL, /* filled in from MFD platform data */ ++ .ocr_avail = MMC_VDD_20_21 | ++ MMC_VDD_21_22 | ++ MMC_VDD_22_23 | ++ MMC_VDD_23_24 | ++ MMC_VDD_24_25 | ++ MMC_VDD_25_26 | ++ MMC_VDD_26_27 | ++ MMC_VDD_27_28 | ++ MMC_VDD_28_29 | ++ MMC_VDD_29_30 | ++ MMC_VDD_30_31 | ++ MMC_VDD_32_33, ++ .glamo_irq_is_wired = NULL, /* filled in from MFD platform data */ ++ .mci_suspending = NULL, /* filled in from MFD platform data */ ++ .mci_all_dependencies_resumed = NULL, /* filled in from MFD platform data */ ++}; ++EXPORT_SYMBOL_GPL(glamo_mci_def_pdata); ++ ++ ++ ++static void mangle_mem_resources(struct resource *res, int num_res, ++ struct resource *parent) ++{ ++ int i; ++ ++ for (i = 0; i < num_res; i++) { ++ if (res[i].flags != IORESOURCE_MEM) ++ continue; ++ res[i].start += parent->start; ++ res[i].end += parent->start; ++ res[i].parent = parent; ++ } ++} ++ ++/*********************************************************************** ++ * IRQ demultiplexer ++ ***********************************************************************/ ++#define irq2glamo(x) (x - IRQ_GLAMO(0)) ++ ++static void glamo_ack_irq(unsigned int irq) ++{ ++ /* clear interrupt source */ ++ __reg_write(glamo_handle, GLAMO_REG_IRQ_CLEAR, ++ 1 << irq2glamo(irq)); ++} ++ ++static void glamo_mask_irq(unsigned int irq) ++{ ++ u_int16_t tmp; ++ ++ /* clear bit in enable register */ ++ tmp = __reg_read(glamo_handle, GLAMO_REG_IRQ_ENABLE); ++ tmp &= ~(1 << irq2glamo(irq)); ++ __reg_write(glamo_handle, GLAMO_REG_IRQ_ENABLE, tmp); ++} ++ ++static void glamo_unmask_irq(unsigned int irq) ++{ ++ u_int16_t tmp; ++ ++ /* set bit in enable register */ ++ tmp = __reg_read(glamo_handle, GLAMO_REG_IRQ_ENABLE); ++ tmp |= (1 << irq2glamo(irq)); ++ __reg_write(glamo_handle, GLAMO_REG_IRQ_ENABLE, tmp); ++} ++ ++static struct irq_chip glamo_irq_chip = { ++ .ack = glamo_ack_irq, ++ .mask = glamo_mask_irq, ++ .unmask = glamo_unmask_irq, ++}; ++ ++static void glamo_irq_demux_handler(unsigned int irq, struct irq_desc *desc) ++{ ++ const unsigned int cpu = smp_processor_id(); ++ ++ desc->status &= ~(IRQ_REPLAY | IRQ_WAITING); ++ ++ if (unlikely(desc->status & IRQ_INPROGRESS)) { ++ desc->status |= (IRQ_PENDING | IRQ_MASKED); ++ desc->chip->mask(irq); ++ desc->chip->ack(irq); ++ return; ++ } ++ ++ kstat_cpu(cpu).irqs[irq]++; ++ desc->chip->ack(irq); ++ desc->status |= IRQ_INPROGRESS; ++ ++ do { ++ u_int16_t irqstatus; ++ int i; ++ ++ if (unlikely((desc->status & ++ (IRQ_PENDING | IRQ_MASKED | IRQ_DISABLED)) == ++ (IRQ_PENDING | IRQ_MASKED))) { ++ /* dealing with pending IRQ, unmasking */ ++ desc->chip->unmask(irq); ++ desc->status &= ~IRQ_MASKED; ++ } ++ ++ desc->status &= ~IRQ_PENDING; ++ ++ /* read IRQ status register */ ++ irqstatus = __reg_read(glamo_handle, GLAMO_REG_IRQ_STATUS); ++ for (i = 0; i < 9; i++) ++ if (irqstatus & (1 << i)) ++ desc_handle_irq(IRQ_GLAMO(i), ++ irq_desc+IRQ_GLAMO(i)); ++ ++ } while ((desc->status & (IRQ_PENDING | IRQ_DISABLED)) == IRQ_PENDING); ++ ++ desc->status &= ~IRQ_INPROGRESS; ++} ++ ++ ++static ssize_t regs_write(struct device *dev, struct device_attribute *attr, ++ const char *buf, size_t count) ++{ ++ unsigned long reg = simple_strtoul(buf, NULL, 10); ++ struct glamo_core *glamo = dev_get_drvdata(dev); ++ ++ while (*buf && (*buf != ' ')) ++ buf++; ++ if (*buf != ' ') ++ return -EINVAL; ++ while (*buf && (*buf == ' ')) ++ buf++; ++ if (!*buf) ++ return -EINVAL; ++ ++ printk(KERN_INFO"reg 0x%02lX <-- 0x%04lX\n", ++ reg, simple_strtoul(buf, NULL, 10)); ++ ++ __reg_write(glamo, reg, simple_strtoul(buf, NULL, 10)); ++ ++ return count; ++} ++ ++static ssize_t regs_read(struct device *dev, struct device_attribute *attr, ++ char *buf) ++{ ++ struct glamo_core *glamo = dev_get_drvdata(dev); ++ int n, n1 = 0, r; ++ char * end = buf; ++ ++ spin_lock(&glamo->lock); ++ ++ for (r = 0; r < ARRAY_SIZE(reg_range); r++) { ++ if (!reg_range[r].dump) ++ continue; ++ n1 = 0; ++ end += sprintf(end, "\n%s\n", reg_range[r].name); ++ for (n = reg_range[r].start; ++ n < reg_range[r].start + reg_range[r].count; n += 2) { ++ if (((n1++) & 7) == 0) ++ end += sprintf(end, "\n%04X: ", n); ++ end += sprintf(end, "%04x ", __reg_read(glamo, n)); ++ } ++ end += sprintf(end, "\n"); ++ if (!attr) { ++ printk("%s", buf); ++ end = buf; ++ } ++ } ++ spin_unlock(&glamo->lock); ++ ++ return end - buf; ++} ++ ++static DEVICE_ATTR(regs, 0644, regs_read, regs_write); ++static struct attribute *glamo_sysfs_entries[] = { ++ &dev_attr_regs.attr, ++ NULL ++}; ++static struct attribute_group glamo_attr_group = { ++ .name = NULL, ++ .attrs = glamo_sysfs_entries, ++}; ++ ++ ++ ++/*********************************************************************** ++ * 'engine' support ++ ***********************************************************************/ ++ ++int __glamo_engine_enable(struct glamo_core *glamo, enum glamo_engine engine) ++{ ++ switch (engine) { ++ case GLAMO_ENGINE_LCD: ++ __reg_set_bit_mask(glamo, GLAMO_REG_HOSTBUS(2), ++ GLAMO_HOSTBUS2_MMIO_EN_LCD, ++ GLAMO_HOSTBUS2_MMIO_EN_LCD); ++ __reg_write(glamo, GLAMO_REG_CLOCK_LCD, ++ GLAMO_CLOCK_LCD_EN_M5CLK | ++ GLAMO_CLOCK_LCD_EN_DHCLK | ++ GLAMO_CLOCK_LCD_EN_DMCLK | ++ GLAMO_CLOCK_LCD_EN_DCLK | ++ GLAMO_CLOCK_LCD_DG_M5CLK | ++ GLAMO_CLOCK_LCD_DG_DMCLK); ++ __reg_set_bit_mask(glamo, GLAMO_REG_CLOCK_GEN5_1, ++ GLAMO_CLOCK_GEN51_EN_DIV_DHCLK | ++ GLAMO_CLOCK_GEN51_EN_DIV_DMCLK | ++ GLAMO_CLOCK_GEN51_EN_DIV_DCLK, 0xffff); ++ break; ++ case GLAMO_ENGINE_MMC: ++ __reg_set_bit_mask(glamo, GLAMO_REG_HOSTBUS(2), ++ GLAMO_HOSTBUS2_MMIO_EN_MMC, ++ GLAMO_HOSTBUS2_MMIO_EN_MMC); ++ __reg_set_bit_mask(glamo, GLAMO_REG_CLOCK_MMC, ++ GLAMO_CLOCK_MMC_EN_M9CLK | ++ GLAMO_CLOCK_MMC_EN_TCLK | ++ GLAMO_CLOCK_MMC_DG_M9CLK | ++ GLAMO_CLOCK_MMC_DG_TCLK, 0xffff); ++ /* enable the TCLK divider clk input */ ++ __reg_set_bit_mask(glamo, GLAMO_REG_CLOCK_GEN5_1, ++ GLAMO_CLOCK_GEN51_EN_DIV_TCLK, ++ GLAMO_CLOCK_GEN51_EN_DIV_TCLK); ++ break; ++ case GLAMO_ENGINE_2D: ++ __reg_set_bit_mask(glamo, GLAMO_REG_CLOCK_2D, ++ GLAMO_CLOCK_2D_EN_M7CLK | ++ GLAMO_CLOCK_2D_EN_GCLK | ++ GLAMO_CLOCK_2D_DG_M7CLK | ++ GLAMO_CLOCK_2D_DG_GCLK, 0xffff); ++ __reg_set_bit_mask(glamo, GLAMO_REG_HOSTBUS(2), ++ GLAMO_HOSTBUS2_MMIO_EN_2D, ++ GLAMO_HOSTBUS2_MMIO_EN_2D); ++ break; ++ case GLAMO_ENGINE_CMDQ: ++ __reg_set_bit_mask(glamo, GLAMO_REG_CLOCK_2D, ++ GLAMO_CLOCK_2D_EN_M6CLK, 0xffff); ++ __reg_set_bit_mask(glamo, GLAMO_REG_HOSTBUS(2), ++ GLAMO_HOSTBUS2_MMIO_EN_CQ, ++ GLAMO_HOSTBUS2_MMIO_EN_CQ); ++ break; ++ /* FIXME: Implementation */ ++ default: ++ break; ++ } ++ ++ glamo->engine_enabled_bitfield |= 1 << engine; ++ ++ return 0; ++} ++ ++int glamo_engine_enable(struct glamo_core *glamo, enum glamo_engine engine) ++{ ++ int ret; ++ ++ spin_lock(&glamo->lock); ++ ++ ret = __glamo_engine_enable(glamo, engine); ++ ++ spin_unlock(&glamo->lock); ++ ++ return ret; ++} ++EXPORT_SYMBOL_GPL(glamo_engine_enable); ++ ++int __glamo_engine_disable(struct glamo_core *glamo, enum glamo_engine engine) ++{ ++ switch (engine) { ++ case GLAMO_ENGINE_LCD: ++ /* remove pixel clock to LCM */ ++ __reg_set_bit_mask(glamo, GLAMO_REG_CLOCK_LCD, ++ GLAMO_CLOCK_LCD_EN_DCLK, 0); ++ __reg_set_bit_mask(glamo, GLAMO_REG_CLOCK_LCD, ++ GLAMO_CLOCK_LCD_EN_DHCLK | ++ GLAMO_CLOCK_LCD_EN_DMCLK, 0); ++ /* kill memory clock */ ++ __reg_set_bit_mask(glamo, GLAMO_REG_CLOCK_LCD, ++ GLAMO_CLOCK_LCD_EN_M5CLK, 0); ++ /* stop dividing the clocks */ ++ __reg_set_bit_mask(glamo, GLAMO_REG_CLOCK_GEN5_1, ++ GLAMO_CLOCK_GEN51_EN_DIV_DHCLK | ++ GLAMO_CLOCK_GEN51_EN_DIV_DMCLK | ++ GLAMO_CLOCK_GEN51_EN_DIV_DCLK, 0); ++ break; ++ ++ case GLAMO_ENGINE_MMC: ++// __reg_set_bit_mask(glamo, GLAMO_REG_CLOCK_MMC, ++// GLAMO_CLOCK_MMC_EN_M9CLK | ++// GLAMO_CLOCK_MMC_EN_TCLK | ++// GLAMO_CLOCK_MMC_DG_M9CLK | ++// GLAMO_CLOCK_MMC_DG_TCLK, 0); ++ /* disable the TCLK divider clk input */ ++// __reg_set_bit_mask(glamo, GLAMO_REG_CLOCK_GEN5_1, ++// GLAMO_CLOCK_GEN51_EN_DIV_TCLK, 0); ++ ++ default: ++ break; ++ } ++ ++ glamo->engine_enabled_bitfield &= ~(1 << engine); ++ ++ return 0; ++} ++int glamo_engine_disable(struct glamo_core *glamo, enum glamo_engine engine) ++{ ++ int ret; ++ ++ spin_lock(&glamo->lock); ++ ++ ret = __glamo_engine_disable(glamo, engine); ++ ++ spin_unlock(&glamo->lock); ++ ++ return ret; ++} ++EXPORT_SYMBOL_GPL(glamo_engine_disable); ++ ++static const u_int16_t engine_clock_regs[__NUM_GLAMO_ENGINES] = { ++ [GLAMO_ENGINE_LCD] = GLAMO_REG_CLOCK_LCD, ++ [GLAMO_ENGINE_MMC] = GLAMO_REG_CLOCK_MMC, ++ [GLAMO_ENGINE_ISP] = GLAMO_REG_CLOCK_ISP, ++ [GLAMO_ENGINE_JPEG] = GLAMO_REG_CLOCK_JPEG, ++ [GLAMO_ENGINE_3D] = GLAMO_REG_CLOCK_3D, ++ [GLAMO_ENGINE_2D] = GLAMO_REG_CLOCK_2D, ++ [GLAMO_ENGINE_MPEG_ENC] = GLAMO_REG_CLOCK_MPEG, ++ [GLAMO_ENGINE_MPEG_DEC] = GLAMO_REG_CLOCK_MPEG, ++}; ++ ++void glamo_engine_clkreg_set(struct glamo_core *glamo, ++ enum glamo_engine engine, ++ u_int16_t mask, u_int16_t val) ++{ ++ reg_set_bit_mask(glamo, engine_clock_regs[engine], mask, val); ++} ++EXPORT_SYMBOL_GPL(glamo_engine_clkreg_set); ++ ++u_int16_t glamo_engine_clkreg_get(struct glamo_core *glamo, ++ enum glamo_engine engine) ++{ ++ u_int16_t val; ++ ++ spin_lock(&glamo->lock); ++ val = __reg_read(glamo, engine_clock_regs[engine]); ++ spin_unlock(&glamo->lock); ++ ++ return val; ++} ++EXPORT_SYMBOL_GPL(glamo_engine_clkreg_get); ++ ++struct glamo_script reset_regs[] = { ++ [GLAMO_ENGINE_LCD] = { ++ GLAMO_REG_CLOCK_LCD, GLAMO_CLOCK_LCD_RESET ++ }, ++#if 0 ++ [GLAMO_ENGINE_HOST] = { ++ GLAMO_REG_CLOCK_HOST, GLAMO_CLOCK_HOST_RESET ++ }, ++ [GLAMO_ENGINE_MEM] = { ++ GLAMO_REG_CLOCK_MEM, GLAMO_CLOCK_MEM_RESET ++ }, ++#endif ++ [GLAMO_ENGINE_MMC] = { ++ GLAMO_REG_CLOCK_MMC, GLAMO_CLOCK_MMC_RESET ++ }, ++ [GLAMO_ENGINE_2D] = { ++ GLAMO_REG_CLOCK_2D, GLAMO_CLOCK_2D_RESET ++ }, ++ [GLAMO_ENGINE_JPEG] = { ++ GLAMO_REG_CLOCK_JPEG, GLAMO_CLOCK_JPEG_RESET ++ }, ++}; ++ ++void glamo_engine_reset(struct glamo_core *glamo, enum glamo_engine engine) ++{ ++ struct glamo_script *rst; ++ ++ if (engine >= ARRAY_SIZE(reset_regs)) { ++ dev_warn(&glamo->pdev->dev, "unknown engine %u ", engine); ++ return; ++ } ++ ++ rst = &reset_regs[engine]; ++ ++ spin_lock(&glamo->lock); ++ __reg_set_bit(glamo, rst->reg, rst->val); ++ __reg_clear_bit(glamo, rst->reg, rst->val); ++ spin_unlock(&glamo->lock); ++} ++EXPORT_SYMBOL_GPL(glamo_engine_reset); ++ ++void glamo_lcm_reset(int level) ++{ ++ if (!glamo_handle) ++ return; ++ ++ glamo_gpio_setpin(glamo_handle, GLAMO_GPIO4, level); ++ glamo_gpio_cfgpin(glamo_handle, GLAMO_GPIO4_OUTPUT); ++ ++} ++EXPORT_SYMBOL_GPL(glamo_lcm_reset); ++ ++enum glamo_pll { ++ GLAMO_PLL1, ++ GLAMO_PLL2, ++}; ++ ++static int glamo_pll_rate(struct glamo_core *glamo, ++ enum glamo_pll pll) ++{ ++ u_int16_t reg; ++ unsigned int div = 512; ++ /* FIXME: move osci into platform_data */ ++ unsigned int osci = 32768; ++ ++ if (osci == 32768) ++ div = 1; ++ ++ switch (pll) { ++ case GLAMO_PLL1: ++ reg = __reg_read(glamo, GLAMO_REG_PLL_GEN1); ++ break; ++ case GLAMO_PLL2: ++ reg = __reg_read(glamo, GLAMO_REG_PLL_GEN3); ++ break; ++ default: ++ return -EINVAL; ++ } ++ return (osci/div)*reg; ++} ++ ++int glamo_engine_reclock(struct glamo_core *glamo, ++ enum glamo_engine engine, ++ int ps) ++{ ++ int pll, khz; ++ u_int16_t reg, mask, val = 0; ++ ++ if (!ps) ++ return 0; ++ ++ switch (engine) { ++ case GLAMO_ENGINE_LCD: ++ pll = GLAMO_PLL1; ++ reg = GLAMO_REG_CLOCK_GEN7; ++ mask = 0xff; ++ break; ++ default: ++ dev_warn(&glamo->pdev->dev, ++ "reclock of engine 0x%x not supported\n", engine); ++ return -EINVAL; ++ break; ++ } ++ ++ pll = glamo_pll_rate(glamo, pll); ++ khz = 1000000000UL / ps; ++ ++ if (khz) ++ val = (pll / khz) / 1000; ++ ++ dev_dbg(&glamo->pdev->dev, ++ "PLL %d, kHZ %d, div %d\n", pll, khz, val); ++ ++ if (val) { ++ val--; ++ reg_set_bit_mask(glamo, reg, mask, val); ++ mdelay(5); /* wait some time to stabilize */ ++ ++ return 0; ++ } else { ++ return -EINVAL; ++ } ++} ++EXPORT_SYMBOL_GPL(glamo_engine_reclock); ++ ++/*********************************************************************** ++ * script support ++ ***********************************************************************/ ++ ++int glamo_run_script(struct glamo_core *glamo, struct glamo_script *script, ++ int len, int may_sleep) ++{ ++ int i; ++ ++ for (i = 0; i < len; i++) { ++ struct glamo_script *line = &script[i]; ++ ++ switch (line->reg) { ++ case 0xffff: ++ return 0; ++ case 0xfffe: ++ if (may_sleep) ++ msleep(line->val); ++ else ++ mdelay(line->val * 4); ++ break; ++ case 0xfffd: ++ /* spin until PLLs lock */ ++ while ((__reg_read(glamo, GLAMO_REG_PLL_GEN5) & 3) != 3) ++ ; ++ break; ++ ++ /* ++ * couple of people reported artefacts with 2.6.28 changes, this ++ * allows reversion to 2.6.24 settings ++ */ ++ ++ case 0x200: ++ switch (slow_memory) { ++ /* choice 1 is the most conservative */ ++ case 1: /* 3 waits on Async BB R & W, Use PLL 1 for mem bus */ ++ __reg_write(glamo, script[i].reg, 0xef0); ++ break; ++ case 2: /* 2 waits on Async BB R & W, Use PLL 1 for mem bus */ ++ __reg_write(glamo, script[i].reg, 0xea0); ++ break; ++ case 3: /* 1 waits on Async BB R & W, Use PLL 1 for mem bus */ ++ __reg_write(glamo, script[i].reg, 0xe50); ++ break; ++ case 4: /* 0 waits on Async BB R & W, Use PLL 1 for mem bus */ ++ __reg_write(glamo, script[i].reg, 0xe00); ++ break; ++ ++ /* using PLL2 for memory bus increases CPU bandwidth significantly */ ++ case 5: /* 3 waits on Async BB R & W, Use PLL 2 for mem bus */ ++ __reg_write(glamo, script[i].reg, 0xef3); ++ break; ++ case 6: /* 2 waits on Async BB R & W, Use PLL 2 for mem bus */ ++ __reg_write(glamo, script[i].reg, 0xea3); ++ break; ++ case 7: /* 1 waits on Async BB R & W, Use PLL 2 for mem bus */ ++ __reg_write(glamo, script[i].reg, 0xe53); ++ break; ++ /* default of 0 or >7 is fastest */ ++ default: /* 0 waits on Async BB R & W, Use PLL 2 for mem bus */ ++ __reg_write(glamo, script[i].reg, 0xe03); ++ break; ++ } ++ break; ++ ++ default: ++ __reg_write(glamo, script[i].reg, script[i].val); ++ break; ++ } ++ } ++ ++ return 0; ++} ++EXPORT_SYMBOL(glamo_run_script); ++ ++static struct glamo_script glamo_init_script[] = { ++ { GLAMO_REG_CLOCK_HOST, 0x1000 }, ++ { 0xfffe, 2 }, ++ { GLAMO_REG_CLOCK_MEMORY, 0x1000 }, ++ { GLAMO_REG_CLOCK_MEMORY, 0x2000 }, ++ { GLAMO_REG_CLOCK_LCD, 0x1000 }, ++ { GLAMO_REG_CLOCK_MMC, 0x1000 }, ++ { GLAMO_REG_CLOCK_ISP, 0x1000 }, ++ { GLAMO_REG_CLOCK_ISP, 0x3000 }, ++ { GLAMO_REG_CLOCK_JPEG, 0x1000 }, ++ { GLAMO_REG_CLOCK_3D, 0x1000 }, ++ { GLAMO_REG_CLOCK_3D, 0x3000 }, ++ { GLAMO_REG_CLOCK_2D, 0x1000 }, ++ { GLAMO_REG_CLOCK_2D, 0x3000 }, ++ { GLAMO_REG_CLOCK_RISC1, 0x1000 }, ++ { GLAMO_REG_CLOCK_MPEG, 0x3000 }, ++ { GLAMO_REG_CLOCK_MPEG, 0x3000 }, ++ { GLAMO_REG_CLOCK_MPROC, 0x1000 /*0x100f*/ }, ++ { 0xfffe, 2 }, ++ { GLAMO_REG_CLOCK_HOST, 0x0000 }, ++ { GLAMO_REG_CLOCK_MEMORY, 0x0000 }, ++ { GLAMO_REG_CLOCK_LCD, 0x0000 }, ++ { GLAMO_REG_CLOCK_MMC, 0x0000 }, ++#if 0 ++/* unused engines must be left in reset to stop MMC block read "blackouts" */ ++ { GLAMO_REG_CLOCK_ISP, 0x0000 }, ++ { GLAMO_REG_CLOCK_ISP, 0x0000 }, ++ { GLAMO_REG_CLOCK_JPEG, 0x0000 }, ++ { GLAMO_REG_CLOCK_3D, 0x0000 }, ++ { GLAMO_REG_CLOCK_3D, 0x0000 }, ++ { GLAMO_REG_CLOCK_2D, 0x0000 }, ++ { GLAMO_REG_CLOCK_2D, 0x0000 }, ++ { GLAMO_REG_CLOCK_RISC1, 0x0000 }, ++ { GLAMO_REG_CLOCK_MPEG, 0x0000 }, ++ { GLAMO_REG_CLOCK_MPEG, 0x0000 }, ++#endif ++ { GLAMO_REG_PLL_GEN1, 0x05db }, /* 48MHz */ ++ { GLAMO_REG_PLL_GEN3, 0x0aba }, /* 90MHz */ ++ { 0xfffd, 0 }, ++ /* ++ * b9 of this register MUST be zero to get any interrupts on INT# ++ * the other set bits enable all the engine interrupt sources ++ */ ++ { GLAMO_REG_IRQ_ENABLE, 0x01ff }, ++ { GLAMO_REG_CLOCK_GEN6, 0x2000 }, ++ { GLAMO_REG_CLOCK_GEN7, 0x0101 }, ++ { GLAMO_REG_CLOCK_GEN8, 0x0100 }, ++ { GLAMO_REG_CLOCK_HOST, 0x000d }, ++ /* ++ * b7..b4 = 0 = no wait states on read or write ++ * b0 = 1 select PLL2 for Host interface, b1 = enable it ++ */ ++ { 0x200, 0x0e03 /* this is replaced by script parser */ }, ++ { 0x202, 0x07ff }, ++ { 0x212, 0x0000 }, ++ { 0x214, 0x4000 }, ++ { 0x216, 0xf00e }, ++ ++ /* S-Media recommended "set tiling mode to 512 mode for memory access ++ * more efficiency when 640x480" */ ++ { GLAMO_REG_MEM_TYPE, 0x0c74 }, /* 8MB, 16 word pg wr+rd */ ++ { GLAMO_REG_MEM_GEN, 0xafaf }, /* 63 grants min + max */ ++ ++ { GLAMO_REGOFS_HOSTBUS + 2, 0xffff }, /* enable on MMIO*/ ++ ++ { GLAMO_REG_MEM_TIMING1, 0x0108 }, ++ { GLAMO_REG_MEM_TIMING2, 0x0010 }, /* Taa = 3 MCLK */ ++ { GLAMO_REG_MEM_TIMING3, 0x0000 }, ++ { GLAMO_REG_MEM_TIMING4, 0x0000 }, /* CE1# delay fall/rise */ ++ { GLAMO_REG_MEM_TIMING5, 0x0000 }, /* UB# LB# */ ++ { GLAMO_REG_MEM_TIMING6, 0x0000 }, /* OE# */ ++ { GLAMO_REG_MEM_TIMING7, 0x0000 }, /* WE# */ ++ { GLAMO_REG_MEM_TIMING8, 0x1002 }, /* MCLK delay, was 0x1000 */ ++ { GLAMO_REG_MEM_TIMING9, 0x6006 }, ++ { GLAMO_REG_MEM_TIMING10, 0x00ff }, ++ { GLAMO_REG_MEM_TIMING11, 0x0001 }, ++ { GLAMO_REG_MEM_POWER1, 0x0020 }, ++ { GLAMO_REG_MEM_POWER2, 0x0000 }, ++ { GLAMO_REG_MEM_DRAM1, 0x0000 }, ++ { 0xfffe, 1 }, ++ { GLAMO_REG_MEM_DRAM1, 0xc100 }, ++ { 0xfffe, 1 }, ++ { GLAMO_REG_MEM_DRAM1, 0xe100 }, ++ { GLAMO_REG_MEM_DRAM2, 0x01d6 }, ++ { GLAMO_REG_CLOCK_MEMORY, 0x000b }, ++ { GLAMO_REG_GPIO_GEN1, 0x000f }, ++ { GLAMO_REG_GPIO_GEN2, 0x111e }, ++ { GLAMO_REG_GPIO_GEN3, 0xccc3 }, ++ { GLAMO_REG_GPIO_GEN4, 0x111e }, ++ { GLAMO_REG_GPIO_GEN5, 0x000f }, ++}; ++#if 0 ++static struct glamo_script glamo_resume_script[] = { ++ ++ { GLAMO_REG_PLL_GEN1, 0x05db }, /* 48MHz */ ++ { GLAMO_REG_PLL_GEN3, 0x0aba }, /* 90MHz */ ++ { GLAMO_REG_DFT_GEN6, 1 }, ++ { 0xfffe, 100 }, ++ { 0xfffd, 0 }, ++ { 0x200, 0x0e03 }, ++ ++ /* ++ * b9 of this register MUST be zero to get any interrupts on INT# ++ * the other set bits enable all the engine interrupt sources ++ */ ++ { GLAMO_REG_IRQ_ENABLE, 0x01ff }, ++ { GLAMO_REG_CLOCK_HOST, 0x0018 }, ++ { GLAMO_REG_CLOCK_GEN5_1, 0x18b1 }, ++ ++ { GLAMO_REG_MEM_DRAM1, 0x0000 }, ++ { 0xfffe, 1 }, ++ { GLAMO_REG_MEM_DRAM1, 0xc100 }, ++ { 0xfffe, 1 }, ++ { GLAMO_REG_MEM_DRAM1, 0xe100 }, ++ { GLAMO_REG_MEM_DRAM2, 0x01d6 }, ++ { GLAMO_REG_CLOCK_MEMORY, 0x000b }, ++}; ++#endif ++ ++enum glamo_power { ++ GLAMO_POWER_ON, ++ GLAMO_POWER_SUSPEND, ++}; ++ ++static void glamo_power(struct glamo_core *glamo, ++ enum glamo_power new_state) ++{ ++ int n; ++ unsigned long flags; ++ ++ spin_lock_irqsave(&glamo->lock, flags); ++ ++ dev_info(&glamo->pdev->dev, "***** glamo_power -> %d\n", new_state); ++ ++ /* ++Power management ++static const REG_VALUE_MASK_TYPE reg_powerOn[] = ++{ ++ { REG_GEN_DFT6, REG_BIT_ALL, REG_DATA(1u << 0) }, ++ { REG_GEN_PLL3, 0u, REG_DATA(1u << 13) }, ++ { REG_GEN_MEM_CLK, REG_BIT_ALL, REG_BIT_EN_MOCACLK }, ++ { REG_MEM_DRAM2, 0u, REG_BIT_EN_DEEP_POWER_DOWN }, ++ { REG_MEM_DRAM1, 0u, REG_BIT_SELF_REFRESH } ++}; ++ ++static const REG_VALUE_MASK_TYPE reg_powerStandby[] = ++{ ++ { REG_MEM_DRAM1, REG_BIT_ALL, REG_BIT_SELF_REFRESH }, ++ { REG_GEN_MEM_CLK, 0u, REG_BIT_EN_MOCACLK }, ++ { REG_GEN_PLL3, REG_BIT_ALL, REG_DATA(1u << 13) }, ++ { REG_GEN_DFT5, REG_BIT_ALL, REG_DATA(1u << 0) } ++}; ++ ++static const REG_VALUE_MASK_TYPE reg_powerSuspend[] = ++{ ++ { REG_MEM_DRAM2, REG_BIT_ALL, REG_BIT_EN_DEEP_POWER_DOWN }, ++ { REG_GEN_MEM_CLK, 0u, REG_BIT_EN_MOCACLK }, ++ { REG_GEN_PLL3, REG_BIT_ALL, REG_DATA(1u << 13) }, ++ { REG_GEN_DFT5, REG_BIT_ALL, REG_DATA(1u << 0) } ++}; ++*/ ++ ++ switch (new_state) { ++ case GLAMO_POWER_ON: ++ ++ /* ++ * glamo state on resume is nondeterministic in some ++ * fundamental way, it has also been observed that the ++ * Glamo reset pin can get asserted by, eg, touching it with ++ * a scope probe. So the only answer is to roll with it and ++ * force an external reset on the Glamo during resume. ++ */ ++ ++ (glamo->pdata->glamo_external_reset)(0); ++ udelay(10); ++ (glamo->pdata->glamo_external_reset)(1); ++ mdelay(5); ++ ++ glamo_run_script(glamo, glamo_init_script, ++ ARRAY_SIZE(glamo_init_script), 0); ++ ++ break; ++ ++ case GLAMO_POWER_SUSPEND: ++ ++ /* nuke interrupts */ ++ __reg_write(glamo, GLAMO_REG_IRQ_ENABLE, 0x200); ++ ++ /* stash a copy of which engines were running */ ++ glamo->engine_enabled_bitfield_suspend = ++ glamo->engine_enabled_bitfield; ++ ++ /* take down each engine before we kill mem and pll */ ++ for (n = 0; n < __NUM_GLAMO_ENGINES; n++) ++ if (glamo->engine_enabled_bitfield & (1 << n)) ++ __glamo_engine_disable(glamo, n); ++ ++ /* enable self-refresh */ ++ ++ __reg_write(glamo, GLAMO_REG_MEM_DRAM1, ++ GLAMO_MEM_DRAM1_EN_DRAM_REFRESH | ++ GLAMO_MEM_DRAM1_EN_GATE_CKE | ++ GLAMO_MEM_DRAM1_SELF_REFRESH | ++ GLAMO_MEM_REFRESH_COUNT); ++ __reg_write(glamo, GLAMO_REG_MEM_DRAM1, ++ GLAMO_MEM_DRAM1_EN_MODEREG_SET | ++ GLAMO_MEM_DRAM1_EN_DRAM_REFRESH | ++ GLAMO_MEM_DRAM1_EN_GATE_CKE | ++ GLAMO_MEM_DRAM1_SELF_REFRESH | ++ GLAMO_MEM_REFRESH_COUNT); ++ ++ /* force RAM into deep powerdown */ ++ ++ __reg_write(glamo, GLAMO_REG_MEM_DRAM2, ++ GLAMO_MEM_DRAM2_DEEP_PWRDOWN | ++ (7 << 6) | /* tRC */ ++ (1 << 4) | /* tRP */ ++ (1 << 2) | /* tRCD */ ++ 2); /* CAS latency */ ++ ++ /* disable clocks to memory */ ++ __reg_write(glamo, GLAMO_REG_CLOCK_MEMORY, 0); ++ ++ /* all dividers from OSCI */ ++ __reg_set_bit_mask(glamo, GLAMO_REG_CLOCK_GEN5_1, 0x400, 0x400); ++ ++ /* PLL2 into bypass */ ++ __reg_set_bit_mask(glamo, GLAMO_REG_PLL_GEN3, 1 << 12, 1 << 12); ++ ++ __reg_write(glamo, 0x200, 0x0e00); ++ ++ ++ /* kill PLLS 1 then 2 */ ++ __reg_write(glamo, GLAMO_REG_DFT_GEN5, 0x0001); ++ __reg_set_bit_mask(glamo, GLAMO_REG_PLL_GEN3, 1 << 13, 1 << 13); ++ ++ break; ++ } ++ ++ spin_unlock_irqrestore(&glamo->lock, flags); ++} ++ ++#if 0 ++#define MEMDETECT_RETRY 6 ++static unsigned int detect_memsize(struct glamo_core *glamo) ++{ ++ int i; ++ ++ /*static const u_int16_t pattern[] = { ++ 0x1111, 0x8a8a, 0x2222, 0x7a7a, ++ 0x3333, 0x6a6a, 0x4444, 0x5a5a, ++ 0x5555, 0x4a4a, 0x6666, 0x3a3a, ++ 0x7777, 0x2a2a, 0x8888, 0x1a1a ++ }; */ ++ ++ for (i = 0; i < MEMDETECT_RETRY; i++) { ++ switch (glamo->type) { ++ case 3600: ++ __reg_write(glamo, GLAMO_REG_MEM_TYPE, 0x0072); ++ __reg_write(glamo, GLAMO_REG_MEM_DRAM1, 0xc100); ++ break; ++ case 3650: ++ switch (glamo->revision) { ++ case GLAMO_CORE_REV_A0: ++ if (i & 1) ++ __reg_write(glamo, GLAMO_REG_MEM_TYPE, ++ 0x097a); ++ else ++ __reg_write(glamo, GLAMO_REG_MEM_TYPE, ++ 0x0173); ++ ++ __reg_write(glamo, GLAMO_REG_MEM_DRAM1, 0x0000); ++ msleep(1); ++ __reg_write(glamo, GLAMO_REG_MEM_DRAM1, 0xc100); ++ break; ++ default: ++ if (i & 1) ++ __reg_write(glamo, GLAMO_REG_MEM_TYPE, ++ 0x0972); ++ else ++ __reg_write(glamo, GLAMO_REG_MEM_TYPE, ++ 0x0872); ++ ++ __reg_write(glamo, GLAMO_REG_MEM_DRAM1, 0x0000); ++ msleep(1); ++ __reg_write(glamo, GLAMO_REG_MEM_DRAM1, 0xe100); ++ break; ++ } ++ break; ++ case 3700: ++ /* FIXME */ ++ default: ++ break; ++ } ++ ++#if 0 ++ /* FIXME: finish implementation */ ++ for (j = 0; j < 8; j++) { ++ __ ++#endif ++ } ++ ++ return 0; ++} ++#endif ++ ++/* Find out if we can support this version of the Glamo chip */ ++static int glamo_supported(struct glamo_core *glamo) ++{ ++ u_int16_t dev_id, rev_id; /*, memsize; */ ++ ++ dev_id = __reg_read(glamo, GLAMO_REG_DEVICE_ID); ++ rev_id = __reg_read(glamo, GLAMO_REG_REVISION_ID); ++ ++ switch (dev_id) { ++ case 0x3650: ++ switch (rev_id) { ++ case GLAMO_CORE_REV_A2: ++ break; ++ case GLAMO_CORE_REV_A0: ++ case GLAMO_CORE_REV_A1: ++ case GLAMO_CORE_REV_A3: ++ dev_warn(&glamo->pdev->dev, "untested core revision " ++ "%04x, your mileage may vary\n", rev_id); ++ break; ++ default: ++ dev_warn(&glamo->pdev->dev, "unknown glamo revision " ++ "%04x, your mileage may vary\n", rev_id); ++ /* maybe should abort ? */ ++ } ++ break; ++ case 0x3600: ++ case 0x3700: ++ default: ++ dev_err(&glamo->pdev->dev, "unsupported Glamo device %04x\n", ++ dev_id); ++ return 0; ++ } ++ ++ dev_dbg(&glamo->pdev->dev, "Detected Glamo core %04x Revision %04x " ++ "(%uHz CPU / %uHz Memory)\n", dev_id, rev_id, ++ glamo_pll_rate(glamo, GLAMO_PLL1), ++ glamo_pll_rate(glamo, GLAMO_PLL2)); ++ ++ return 1; ++} ++ ++static int __init glamo_probe(struct platform_device *pdev) ++{ ++ int rc = 0, irq; ++ struct glamo_core *glamo; ++ struct platform_device *glamo_mmc_dev; ++ ++ if (glamo_handle) { ++ dev_err(&pdev->dev, ++ "This driver supports only one instance\n"); ++ return -EBUSY; ++ } ++ ++ glamo = kmalloc(GFP_KERNEL, sizeof(*glamo)); ++ if (!glamo) ++ return -ENOMEM; ++ ++ spin_lock_init(&glamo->lock); ++ glamo_handle = glamo; ++ glamo->pdev = pdev; ++ glamo->mem = platform_get_resource(pdev, IORESOURCE_MEM, 0); ++ glamo->irq = platform_get_irq(pdev, 0); ++ glamo->pdata = pdev->dev.platform_data; ++ if (!glamo->mem || !glamo->pdata) { ++ dev_err(&pdev->dev, "platform device with no MEM/PDATA ?\n"); ++ rc = -ENOENT; ++ goto bail_free; ++ } ++ ++ /* register a number of sibling devices whoise IOMEM resources ++ * are siblings of pdev's IOMEM resource */ ++#if 0 ++ glamo_core_dev.dev.parent = &pdev.dev; ++ mangle_mem_resources(glamo_core_dev.resources, ++ glamo_core_dev.num_resources, glamo->mem); ++ glamo_core_dev.resources[1].start = glamo->irq; ++ glamo_core_dev.resources[1].end = glamo->irq; ++ platform_device_register(&glamo_core_dev); ++#endif ++ /* only remap the generic, hostbus and memory controller registers */ ++ glamo->base = ioremap(glamo->mem->start, 0x4000 /*GLAMO_REGOFS_VIDCAP*/); ++ if (!glamo->base) { ++ dev_err(&pdev->dev, "failed to ioremap() memory region\n"); ++ goto bail_free; ++ } ++ ++ platform_set_drvdata(pdev, glamo); ++ ++ (glamo->pdata->glamo_external_reset)(0); ++ udelay(10); ++ (glamo->pdata->glamo_external_reset)(1); ++ mdelay(10); ++ ++ /* ++ * finally set the mfd interrupts up ++ * can't do them earlier or sibling probes blow up ++ */ ++ ++ for (irq = IRQ_GLAMO(0); irq <= IRQ_GLAMO(8); irq++) { ++ set_irq_chip(irq, &glamo_irq_chip); ++ set_irq_handler(irq, handle_level_irq); ++ set_irq_flags(irq, IRQF_VALID); ++ } ++ ++ if (glamo->pdata->glamo_irq_is_wired && ++ !glamo->pdata->glamo_irq_is_wired()) { ++ set_irq_chained_handler(glamo->irq, glamo_irq_demux_handler); ++ set_irq_type(glamo->irq, IRQ_TYPE_EDGE_FALLING); ++ dev_info(&pdev->dev, "Glamo interrupt registered\n"); ++ glamo->irq_works = 1; ++ } else { ++ dev_err(&pdev->dev, "Glamo interrupt not used\n"); ++ glamo->irq_works = 0; ++ } ++ ++ ++ /* confirm it isn't insane version */ ++ if (!glamo_supported(glamo)) { ++ dev_err(&pdev->dev, "This Glamo is not supported\n"); ++ goto bail_irq; ++ } ++ ++ /* sysfs */ ++ rc = sysfs_create_group(&pdev->dev.kobj, &glamo_attr_group); ++ if (rc < 0) { ++ dev_err(&pdev->dev, "cannot create sysfs group\n"); ++ goto bail_irq; ++ } ++ ++ /* init the chip with canned register set */ ++ ++ dev_dbg(&glamo->pdev->dev, "running init script\n"); ++ glamo_run_script(glamo, glamo_init_script, ++ ARRAY_SIZE(glamo_init_script), 1); ++ ++ dev_info(&glamo->pdev->dev, "Glamo core PLL1: %uHz, PLL2: %uHz\n", ++ glamo_pll_rate(glamo, GLAMO_PLL1), ++ glamo_pll_rate(glamo, GLAMO_PLL2)); ++ ++ /* bring MCI specific stuff over from our MFD platform data */ ++ glamo_mci_def_pdata.glamo_can_set_mci_power = ++ glamo->pdata->glamo_can_set_mci_power; ++ glamo_mci_def_pdata.glamo_mci_use_slow = ++ glamo->pdata->glamo_mci_use_slow; ++ glamo_mci_def_pdata.glamo_irq_is_wired = ++ glamo->pdata->glamo_irq_is_wired; ++ ++ /* start creating the siblings */ ++ ++ glamo_2d_dev.dev.parent = &pdev->dev; ++ mangle_mem_resources(glamo_2d_dev.resource, ++ glamo_2d_dev.num_resources, glamo->mem); ++ platform_device_register(&glamo_2d_dev); ++ ++ glamo_3d_dev.dev.parent = &pdev->dev; ++ mangle_mem_resources(glamo_3d_dev.resource, ++ glamo_3d_dev.num_resources, glamo->mem); ++ platform_device_register(&glamo_3d_dev); ++ ++ glamo_jpeg_dev.dev.parent = &pdev->dev; ++ mangle_mem_resources(glamo_jpeg_dev.resource, ++ glamo_jpeg_dev.num_resources, glamo->mem); ++ platform_device_register(&glamo_jpeg_dev); ++ ++ glamo_mpeg_dev.dev.parent = &pdev->dev; ++ mangle_mem_resources(glamo_mpeg_dev.resource, ++ glamo_mpeg_dev.num_resources, glamo->mem); ++ platform_device_register(&glamo_mpeg_dev); ++ ++ glamo->pdata->glamo = glamo; ++ glamo_fb_dev.dev.parent = &pdev->dev; ++ glamo_fb_dev.dev.platform_data = glamo->pdata; ++ mangle_mem_resources(glamo_fb_dev.resource, ++ glamo_fb_dev.num_resources, glamo->mem); ++ platform_device_register(&glamo_fb_dev); ++ ++ glamo->pdata->spigpio_info->glamo = glamo; ++ glamo_spigpio_dev.dev.parent = &pdev->dev; ++ glamo_spigpio_dev.dev.platform_data = glamo->pdata->spigpio_info; ++ platform_device_register(&glamo_spigpio_dev); ++ ++ glamo_mmc_dev = glamo->pdata->mmc_dev; ++ glamo_mmc_dev->name = "glamo-mci"; ++ glamo_mmc_dev->dev.parent = &pdev->dev; ++ glamo_mmc_dev->resource = glamo_mmc_resources; ++ glamo_mmc_dev->num_resources = ARRAY_SIZE(glamo_mmc_resources); ++ ++ /* we need it later to give to the engine enable and disable */ ++ glamo_mci_def_pdata.pglamo = glamo; ++ mangle_mem_resources(glamo_mmc_dev->resource, ++ glamo_mmc_dev->num_resources, glamo->mem); ++ platform_device_register(glamo_mmc_dev); ++ ++ /* only request the generic, hostbus and memory controller MMIO */ ++ glamo->mem = request_mem_region(glamo->mem->start, ++ GLAMO_REGOFS_VIDCAP, "glamo-core"); ++ if (!glamo->mem) { ++ dev_err(&pdev->dev, "failed to request memory region\n"); ++ goto bail_irq; ++ } ++ ++ return 0; ++ ++bail_irq: ++ disable_irq(glamo->irq); ++ set_irq_chained_handler(glamo->irq, NULL); ++ ++ for (irq = IRQ_GLAMO(0); irq <= IRQ_GLAMO(8); irq++) { ++ set_irq_flags(irq, 0); ++ set_irq_chip(irq, NULL); ++ } ++ ++ iounmap(glamo->base); ++bail_free: ++ platform_set_drvdata(pdev, NULL); ++ glamo_handle = NULL; ++ kfree(glamo); ++ ++ return rc; ++} ++ ++static int glamo_remove(struct platform_device *pdev) ++{ ++ struct glamo_core *glamo = platform_get_drvdata(pdev); ++ int irq; ++ ++ disable_irq(glamo->irq); ++ set_irq_chained_handler(glamo->irq, NULL); ++ ++ for (irq = IRQ_GLAMO(0); irq <= IRQ_GLAMO(8); irq++) { ++ set_irq_flags(irq, 0); ++ set_irq_chip(irq, NULL); ++ } ++ ++ platform_set_drvdata(pdev, NULL); ++ platform_device_unregister(&glamo_fb_dev); ++ platform_device_unregister(glamo->pdata->mmc_dev); ++ iounmap(glamo->base); ++ release_mem_region(glamo->mem->start, GLAMO_REGOFS_VIDCAP); ++ glamo_handle = NULL; ++ kfree(glamo); ++ ++ return 0; ++} ++ ++#ifdef CONFIG_PM ++ ++static int glamo_suspend(struct platform_device *pdev, pm_message_t state) ++{ ++ glamo_handle->suspending = 1; ++ glamo_power(glamo_handle, GLAMO_POWER_SUSPEND); ++ ++ return 0; ++} ++ ++static int glamo_resume(struct platform_device *pdev) ++{ ++ glamo_power(glamo_handle, GLAMO_POWER_ON); ++ glamo_handle->suspending = 0; ++ ++ return 0; ++} ++ ++#else ++#define glamo_suspend NULL ++#define glamo_resume NULL ++#endif ++ ++static struct platform_driver glamo_driver = { ++ .probe = glamo_probe, ++ .remove = glamo_remove, ++ .suspend = glamo_suspend, ++ .resume = glamo_resume, ++ .driver = { ++ .name = "glamo3362", ++ .owner = THIS_MODULE, ++ }, ++}; ++ ++static int __devinit glamo_init(void) ++{ ++ return platform_driver_register(&glamo_driver); ++} ++ ++static void __exit glamo_cleanup(void) ++{ ++ platform_driver_unregister(&glamo_driver); ++} ++ ++module_init(glamo_init); ++module_exit(glamo_cleanup); ++ ++MODULE_AUTHOR("Harald Welte <laforge@openmoko.org>"); ++MODULE_DESCRIPTION("Smedia Glamo 336x/337x core/resource driver"); ++MODULE_LICENSE("GPL"); +diff -ruN --exclude='*.orig' --exclude='*.rej' linux-2.6.29-rc3.owrt/drivers/mfd/glamo/glamo-core.h linux-2.6.29-rc3.owrt.om/drivers/mfd/glamo/glamo-core.h +--- linux-2.6.29-rc3.owrt/drivers/mfd/glamo/glamo-core.h 1970-01-01 01:00:00.000000000 +0100 ++++ linux-2.6.29-rc3.owrt.om/drivers/mfd/glamo/glamo-core.h 2009-05-10 22:28:00.000000000 +0200 +@@ -0,0 +1,92 @@ ++#ifndef __GLAMO_CORE_H ++#define __GLAMO_CORE_H ++ ++#include <asm/system.h> ++ ++/* for the time being, we put the on-screen framebuffer into the lowest ++ * VRAM space. This should make the code easily compatible with the various ++ * 2MB/4MB/8MB variants of the Smedia chips */ ++#define GLAMO_OFFSET_VRAM 0x800000 ++#define GLAMO_OFFSET_FB (GLAMO_OFFSET_VRAM) ++ ++/* we only allocate the minimum possible size for the framebuffer to make ++ * sure we have sufficient memory for other functions of the chip */ ++//#define GLAMO_FB_SIZE (640*480*4) /* == 0x12c000 */ ++#define GLAMO_INTERNAL_RAM_SIZE 0x800000 ++#define GLAMO_MMC_BUFFER_SIZE (64 * 1024) ++#define GLAMO_FB_SIZE (GLAMO_INTERNAL_RAM_SIZE - GLAMO_MMC_BUFFER_SIZE) ++ ++struct glamo_core { ++ int irq; ++ int irq_works; /* 0 means PCB does not support Glamo IRQ */ ++ struct resource *mem; ++ struct resource *mem_core; ++ void __iomem *base; ++ struct platform_device *pdev; ++ struct glamofb_platform_data *pdata; ++ u_int16_t type; ++ u_int16_t revision; ++ spinlock_t lock; ++ u32 engine_enabled_bitfield; ++ u32 engine_enabled_bitfield_suspend; ++ int suspending; ++}; ++ ++struct glamo_script { ++ u_int16_t reg; ++ u_int16_t val; ++}; ++ ++int glamo_run_script(struct glamo_core *glamo, ++ struct glamo_script *script, int len, int may_sleep); ++ ++enum glamo_engine { ++ GLAMO_ENGINE_CAPTURE, ++ GLAMO_ENGINE_ISP, ++ GLAMO_ENGINE_JPEG, ++ GLAMO_ENGINE_MPEG_ENC, ++ GLAMO_ENGINE_MPEG_DEC, ++ GLAMO_ENGINE_LCD, ++ GLAMO_ENGINE_CMDQ, ++ GLAMO_ENGINE_2D, ++ GLAMO_ENGINE_3D, ++ GLAMO_ENGINE_MMC, ++ GLAMO_ENGINE_MICROP0, ++ GLAMO_ENGINE_RISC, ++ GLAMO_ENGINE_MICROP1_MPEG_ENC, ++ GLAMO_ENGINE_MICROP1_MPEG_DEC, ++#if 0 ++ GLAMO_ENGINE_H264_DEC, ++ GLAMO_ENGINE_RISC1, ++ GLAMO_ENGINE_SPI, ++#endif ++ __NUM_GLAMO_ENGINES ++}; ++ ++struct glamo_mci_pdata { ++ struct glamo_core * pglamo; ++ unsigned int gpio_detect; ++ unsigned int gpio_wprotect; ++ unsigned long ocr_avail; ++ int (*glamo_can_set_mci_power)(void); ++ /* glamo-mci asking if it should use the slow clock to card */ ++ int (*glamo_mci_use_slow)(void); ++ int (*glamo_irq_is_wired)(void); ++ void (*mci_suspending)(struct platform_device *dev); ++ int (*mci_all_dependencies_resumed)(struct platform_device *dev); ++ ++}; ++ ++int glamo_engine_enable(struct glamo_core *glamo, enum glamo_engine engine); ++int glamo_engine_disable(struct glamo_core *glamo, enum glamo_engine engine); ++void glamo_engine_reset(struct glamo_core *glamo, enum glamo_engine engine); ++int glamo_engine_reclock(struct glamo_core *glamo, ++ enum glamo_engine engine, int ps); ++ ++void glamo_engine_clkreg_set(struct glamo_core *glamo, ++ enum glamo_engine engine, ++ u_int16_t mask, u_int16_t val); ++ ++u_int16_t glamo_engine_clkreg_get(struct glamo_core *glamo, ++ enum glamo_engine engine); ++#endif /* __GLAMO_CORE_H */ +diff -ruN --exclude='*.orig' --exclude='*.rej' linux-2.6.29-rc3.owrt/drivers/mfd/glamo/glamo-fb.c linux-2.6.29-rc3.owrt.om/drivers/mfd/glamo/glamo-fb.c +--- linux-2.6.29-rc3.owrt/drivers/mfd/glamo/glamo-fb.c 1970-01-01 01:00:00.000000000 +0100 ++++ linux-2.6.29-rc3.owrt.om/drivers/mfd/glamo/glamo-fb.c 2009-05-10 22:28:00.000000000 +0200 +@@ -0,0 +1,1193 @@ ++/* Smedia Glamo 336x/337x driver ++ * ++ * (C) 2007-2008 by Openmoko, Inc. ++ * Author: Harald Welte <laforge@openmoko.org> ++ * All rights reserved. ++ * ++ * 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, ++ * MA 02111-1307 USA ++ */ ++ ++#include <linux/module.h> ++#include <linux/kernel.h> ++#include <linux/errno.h> ++#include <linux/string.h> ++#include <linux/mm.h> ++#include <linux/slab.h> ++#include <linux/delay.h> ++#include <linux/fb.h> ++#include <linux/init.h> ++#include <linux/vmalloc.h> ++#include <linux/dma-mapping.h> ++#include <linux/interrupt.h> ++#include <linux/workqueue.h> ++#include <linux/wait.h> ++#include <linux/platform_device.h> ++#include <linux/clk.h> ++#include <linux/spinlock.h> ++#include <linux/io.h> ++#include <linux/uaccess.h> ++ ++#include <asm/div64.h> ++ ++#ifdef CONFIG_PM ++#include <linux/pm.h> ++#endif ++ ++#include <linux/glamofb.h> ++ ++#include "glamo-regs.h" ++#include "glamo-core.h" ++ ++#ifndef DEBUG ++#define GLAMO_LOG(...) ++#else ++#define GLAMO_LOG(...) \ ++do { \ ++ printk(KERN_DEBUG "in %s:%s:%d", __FILE__, __func__, __LINE__); \ ++ printk(KERN_DEBUG __VA_ARGS__); \ ++} while (0); ++#endif ++ ++ ++#define RESSIZE(ressource) (((ressource)->end - (ressource)->start)+1) ++ ++struct glamofb_handle { ++ struct fb_info *fb; ++ struct device *dev; ++ struct resource *reg; ++ struct resource *fb_res; ++ char __iomem *base; ++ struct glamofb_platform_data *mach_info; ++ char __iomem *cursor_addr; ++ int cursor_on; ++ u_int32_t pseudo_pal[16]; ++ spinlock_t lock_cmd; ++ int angle; /* Current rotation angle */ ++ int blank_mode; ++}; ++ ++/* 'sibling' spi device for lcm init */ ++static struct platform_device glamo_spi_dev = { ++ .name = "glamo-lcm-spi", ++}; ++ ++ ++static int reg_read(struct glamofb_handle *glamo, ++ u_int16_t reg) ++{ ++ int i = 0; ++ ++ for (i = 0; i != 2; i++) ++ nop(); ++ ++ return readw(glamo->base + reg); ++} ++ ++static void reg_write(struct glamofb_handle *glamo, ++ u_int16_t reg, u_int16_t val) ++{ ++ int i = 0; ++ ++ for (i = 0; i != 2; i++) ++ nop(); ++ ++ writew(val, glamo->base + reg); ++} ++ ++static struct glamo_script glamo_regs[] = { ++ { GLAMO_REG_LCD_MODE1, 0x0020 }, ++ /* no display rotation, no hardware cursor, no dither, no gamma, ++ * no retrace flip, vsync low-active, hsync low active, ++ * no TVCLK, no partial display, hw dest color from fb, ++ * no partial display mode, LCD1, software flip, */ ++ { GLAMO_REG_LCD_MODE2, 0x9020 }, ++ /* video flip, no ptr, no ptr, dhclk off, ++ * normal mode, no cpuif, ++ * res, serial msb first, single fb, no fr ctrl, ++ * cpu if bits all zero, no crc ++ * 0000 0000 0010 0000 */ ++ { GLAMO_REG_LCD_MODE3, 0x0b40 }, ++ /* src data rgb565, res, 18bit rgb666 ++ * 000 01 011 0100 0000 */ ++ { GLAMO_REG_LCD_POLARITY, 0x440c }, ++ /* DE high active, no cpu/lcd if, cs0 force low, a0 low active, ++ * np cpu if, 9bit serial data, sclk rising edge latch data ++ * 01 00 0 100 0 000 01 0 0 */ ++ /* The following values assume 640*480@16bpp */ ++ { GLAMO_REG_LCD_A_BASE1, 0x0000 }, /* display A base address 15:0 */ ++ { GLAMO_REG_LCD_A_BASE2, 0x0000 }, /* display A base address 22:16 */ ++ { GLAMO_REG_LCD_B_BASE1, 0x6000 }, /* display B base address 15:0 */ ++ { GLAMO_REG_LCD_B_BASE2, 0x0009 }, /* display B base address 22:16 */ ++ { GLAMO_REG_LCD_CURSOR_BASE1, 0xC000 }, /* cursor base address 15:0 */ ++ { GLAMO_REG_LCD_CURSOR_BASE2, 0x0012 }, /* cursor base address 22:16 */ ++ { GLAMO_REG_LCD_COMMAND2, 0x0000 }, /* display page A */ ++}; ++ ++static int glamofb_run_script(struct glamofb_handle *glamo, ++ struct glamo_script *script, int len) ++{ ++ int i; ++ ++ if (glamo->mach_info->glamo->suspending) { ++ dev_err(&glamo->mach_info->glamo->pdev->dev, ++ "IGNORING glamofb_run_script while " ++ "suspended\n"); ++ return -EBUSY; ++ } ++ ++ for (i = 0; i < len; i++) { ++ struct glamo_script *line = &script[i]; ++ ++ if (line->reg == 0xffff) ++ return 0; ++ else if (line->reg == 0xfffe) ++ msleep(line->val); ++ else ++ reg_write(glamo, script[i].reg, script[i].val); ++ } ++ ++ return 0; ++} ++ ++static int glamofb_check_var(struct fb_var_screeninfo *var, ++ struct fb_info *info) ++{ ++ struct glamofb_handle *glamo = info->par; ++ ++ if (glamo->mach_info->glamo->suspending) { ++ dev_err(&glamo->mach_info->glamo->pdev->dev, ++ "IGNORING glamofb_check_var while " ++ "suspended\n"); ++ return -EBUSY; ++ } ++ ++ if (var->yres > glamo->mach_info->yres.max) ++ var->yres = glamo->mach_info->yres.max; ++ else if (var->yres < glamo->mach_info->yres.min) ++ var->yres = glamo->mach_info->yres.min; ++ ++ if (var->xres > glamo->mach_info->xres.max) ++ var->xres = glamo->mach_info->xres.max; ++ else if (var->xres < glamo->mach_info->xres.min) ++ var->xres = glamo->mach_info->xres.min; ++ ++ if (var->bits_per_pixel > glamo->mach_info->bpp.max) ++ var->bits_per_pixel = glamo->mach_info->bpp.max; ++ else if (var->bits_per_pixel < glamo->mach_info->bpp.min) ++ var->bits_per_pixel = glamo->mach_info->bpp.min; ++ ++ /* FIXME: set rgb positions */ ++ switch (var->bits_per_pixel) { ++ case 16: ++ switch (reg_read(glamo, GLAMO_REG_LCD_MODE3) & 0xc000) { ++ case GLAMO_LCD_SRC_RGB565: ++ var->red.offset = 11; ++ var->green.offset = 5; ++ var->blue.offset = 0; ++ var->red.length = 5; ++ var->green.length = 6; ++ var->blue.length = 5; ++ var->transp.length = 0; ++ break; ++ case GLAMO_LCD_SRC_ARGB1555: ++ var->transp.offset = 15; ++ var->red.offset = 10; ++ var->green.offset = 5; ++ var->blue.offset = 0; ++ var->transp.length = 1; ++ var->red.length = 5; ++ var->green.length = 5; ++ var->blue.length = 5; ++ break; ++ case GLAMO_LCD_SRC_ARGB4444: ++ var->transp.offset = 12; ++ var->red.offset = 8; ++ var->green.offset = 4; ++ var->blue.offset = 0; ++ var->transp.length = 4; ++ var->red.length = 4; ++ var->green.length = 4; ++ var->blue.length = 4; ++ break; ++ } ++ break; ++ case 24: ++ case 32: ++ default: ++ /* The Smedia Glamo doesn't support anything but 16bit color */ ++ printk(KERN_ERR ++ "Smedia driver does not [yet?] support 24/32bpp\n"); ++ return -EINVAL; ++ } ++ ++ return 0; ++} ++ ++static void reg_set_bit_mask(struct glamofb_handle *glamo, ++ u_int16_t reg, u_int16_t mask, ++ u_int16_t val) ++{ ++ u_int16_t tmp; ++ ++ val &= mask; ++ ++ tmp = reg_read(glamo, reg); ++ tmp &= ~mask; ++ tmp |= val; ++ reg_write(glamo, reg, tmp); ++} ++ ++#define GLAMO_LCD_WIDTH_MASK 0x03FF ++#define GLAMO_LCD_HEIGHT_MASK 0x03FF ++#define GLAMO_LCD_PITCH_MASK 0x07FE ++#define GLAMO_LCD_HV_TOTAL_MASK 0x03FF ++#define GLAMO_LCD_HV_RETR_START_MASK 0x03FF ++#define GLAMO_LCD_HV_RETR_END_MASK 0x03FF ++#define GLAMO_LCD_HV_RETR_DISP_START_MASK 0x03FF ++#define GLAMO_LCD_HV_RETR_DISP_END_MASK 0x03FF ++ ++enum orientation {ORIENTATION_PORTRAIT, ORIENTATION_LANDSCAPE}; ++ ++/* the caller has to enxure lock_cmd is held and we are in cmd mode */ ++static void __rotate_lcd(struct glamofb_handle *glamo, __u32 rotation) ++{ ++ int glamo_rot; ++ ++ if (glamo->mach_info->glamo->suspending) { ++ dev_err(&glamo->mach_info->glamo->pdev->dev, ++ "IGNORING rotate_lcd while " ++ "suspended\n"); ++ return; ++ } ++ ++ switch (rotation) { ++ case FB_ROTATE_UR: ++ glamo_rot = GLAMO_LCD_ROT_MODE_0; ++ glamo->angle = 0; ++ break; ++ case FB_ROTATE_CW: ++ glamo_rot = GLAMO_LCD_ROT_MODE_90; ++ glamo->angle = 90; ++ break; ++ case FB_ROTATE_UD: ++ glamo_rot = GLAMO_LCD_ROT_MODE_180; ++ glamo->angle = 180; ++ break; ++ case FB_ROTATE_CCW: ++ glamo_rot = GLAMO_LCD_ROT_MODE_270; ++ glamo->angle = 270; ++ break; ++ default: ++ glamo->angle = 0; ++ glamo_rot = GLAMO_LCD_ROT_MODE_0; ++ break; ++ } ++ ++ reg_set_bit_mask(glamo, ++ GLAMO_REG_LCD_WIDTH, ++ GLAMO_LCD_ROT_MODE_MASK, ++ glamo_rot); ++ reg_set_bit_mask(glamo, ++ GLAMO_REG_LCD_MODE1, ++ GLAMO_LCD_MODE1_ROTATE_EN, ++ (glamo_rot != GLAMO_LCD_ROT_MODE_0) ? ++ GLAMO_LCD_MODE1_ROTATE_EN : 0); ++} ++ ++static enum orientation get_orientation(struct fb_var_screeninfo *var) ++{ ++ if (var->xres <= var->yres) ++ return ORIENTATION_PORTRAIT; ++ ++ return ORIENTATION_LANDSCAPE; ++} ++ ++static int will_orientation_change(struct fb_var_screeninfo *var) ++{ ++ enum orientation orient = get_orientation(var); ++ ++ switch (orient) { ++ case ORIENTATION_LANDSCAPE: ++ if (var->rotate == FB_ROTATE_UR || var->rotate == FB_ROTATE_UD) ++ return 1; ++ break; ++ case ORIENTATION_PORTRAIT: ++ if (var->rotate == FB_ROTATE_CW || var->rotate == FB_ROTATE_CCW) ++ return 1; ++ break; ++ } ++ return 0; ++} ++ ++#ifdef CONFIG_MFD_GLAMO_FB_XGLAMO_WORKAROUND ++ ++/* ++ * See https://docs.openmoko.org/trac/ticket/2255 ++ * We have a hack for some Xglamo bugs in kernel code. ++ * If someone fixes xglamo we can remove this hack. ++ * We might make xglamo_hack_enabled 0 by default in the future. ++ */ ++ ++static unsigned xglamo_hack_enabled = 1; ++ ++static ssize_t xglamo_hack_read(struct device *dev, ++ struct device_attribute *attr, char *buf) ++{ ++ return sprintf(buf, "%d\n", xglamo_hack_enabled); ++} ++ ++static ssize_t xglamo_hack_write(struct device *dev, ++ struct device_attribute *attr, const char *buf, ++ size_t count) ++{ ++ unsigned long val; ++ ++ if (!strict_strtoul(buf, 10, &val)) ++ xglamo_hack_enabled = !!val; ++ ++ return count; ++} ++ ++static DEVICE_ATTR(xglamo_hack, S_IWUSR | S_IRUGO, xglamo_hack_read, ++ xglamo_hack_write); ++ ++static struct attribute *glamo_fb_sysfs_entries[] = { ++ &dev_attr_xglamo_hack.attr, ++ NULL ++}; ++ ++static struct attribute_group glamo_fb_attr_group = { ++ .name = NULL, ++ .attrs = glamo_fb_sysfs_entries, ++}; ++ ++/* This function implements the actual Xglamo hack. */ ++ ++static void glamofb_update_lcd_controller_hack(struct glamofb_handle *glamo, ++ struct fb_var_screeninfo *var, ++ int *xres, int *yres, int *pitch) ++{ ++ int width, height; ++ ++ if (glamo->angle == 90 || glamo->angle == 270) { ++ /* ++ * But if we are going back to portrait mode from here, ++ * we get inverted values from Xglamo ++ */ ++ if (!(var->rotate == FB_ROTATE_UR || ++ var->rotate == FB_ROTATE_UD)) { ++ width = var->yres; ++ height = var->xres; ++ } else { ++ width = var->xres; ++ height = var->yres; ++ } ++ ++ } else { ++ width = var->xres; ++ height = var->yres; ++ } ++ ++ /* Portrait ? */ ++ if (var->rotate == FB_ROTATE_UR || var->rotate == FB_ROTATE_UD) { ++ /* We don't need to set xres and yres in this particular case ++ * because Xglamo does it for us */ ++ if (!(glamo->angle == 90 || glamo->angle == 270)) { ++ var->xres = width; ++ var->yres = height; ++ } ++ ++ var->xres_virtual = width; ++ var->yres_virtual = height * 2; ++ *pitch = width * var->bits_per_pixel / 8; ++ } else { ++ var->xres = height; ++ var->yres = width; ++ var->xres_virtual = height * 2; ++ var->yres_virtual = width; ++ *pitch = height * var->bits_per_pixel / 8; ++ } ++ ++ *xres = width; ++ *yres = height; ++} ++#else ++#define xglamo_hack_enabled 0 ++static void glamofb_update_lcd_controller_hack(struct glamofb_handle *glamo, ++ struct fb_var_screeninfo *var, ++ int *xres, int *yres, int *pitch) ++{ ++} ++#endif ++ ++static void glamofb_update_lcd_controller(struct glamofb_handle *glamo, ++ struct fb_var_screeninfo *var) ++{ ++ int sync, bp, disp, fp, total, xres, yres, pitch; ++ int uninitialized_var(orientation_changing); ++ unsigned long flags; ++ ++ if (!glamo || !var) ++ return; ++ ++ if (glamo->mach_info->glamo->suspending) { ++ dev_err(&glamo->mach_info->glamo->pdev->dev, ++ "IGNORING glamofb_update_lcd_controller while " ++ "suspended\n"); ++ return; ++ } ++ ++ dev_dbg(&glamo->mach_info->glamo->pdev->dev, ++ "glamofb_update_lcd_controller spin_lock_irqsave\n"); ++ spin_lock_irqsave(&glamo->lock_cmd, flags); ++ ++ if (glamofb_cmd_mode(glamo, 1)) ++ goto out_unlock; ++ ++ if (var->pixclock) ++ glamo_engine_reclock(glamo->mach_info->glamo, ++ GLAMO_ENGINE_LCD, ++ var->pixclock); ++ ++ if (xglamo_hack_enabled) { ++ glamofb_update_lcd_controller_hack(glamo, var, &xres, &yres, ++ &pitch); ++ } else { ++ xres = var->xres; ++ yres = var->yres; ++ ++ orientation_changing = will_orientation_change(var); ++ /* Adjust the pitch according to new orientation to come. */ ++ if (orientation_changing) ++ pitch = var->yres * var->bits_per_pixel / 8; ++ else ++ pitch = var->xres * var->bits_per_pixel / 8; ++ } ++ ++ reg_set_bit_mask(glamo, ++ GLAMO_REG_LCD_WIDTH, ++ GLAMO_LCD_WIDTH_MASK, ++ xres); ++ reg_set_bit_mask(glamo, ++ GLAMO_REG_LCD_HEIGHT, ++ GLAMO_LCD_HEIGHT_MASK, ++ yres); ++ reg_set_bit_mask(glamo, ++ GLAMO_REG_LCD_PITCH, ++ GLAMO_LCD_PITCH_MASK, ++ pitch); ++ ++ /* honour the rotation request */ ++ __rotate_lcd(glamo, var->rotate); ++ ++ if (!xglamo_hack_enabled) { ++ /* update the reported geometry of the framebuffer. */ ++ if (orientation_changing) { ++ var->xres_virtual = yres; ++ var->xres = yres; ++ var->xres_virtual *= 2; ++ var->yres_virtual = xres; ++ var->yres = xres; ++ } else { ++ var->xres_virtual = xres; ++ var->yres_virtual = yres; ++ var->yres_virtual *= 2; ++ } ++ } ++ ++ /* update scannout timings */ ++ sync = 0; ++ bp = sync + var->hsync_len; ++ disp = bp + var->left_margin; ++ fp = disp + xres; ++ total = fp + var->right_margin; ++ ++ reg_set_bit_mask(glamo, GLAMO_REG_LCD_HORIZ_TOTAL, ++ GLAMO_LCD_HV_TOTAL_MASK, total); ++ reg_set_bit_mask(glamo, GLAMO_REG_LCD_HORIZ_RETR_START, ++ GLAMO_LCD_HV_RETR_START_MASK, sync); ++ reg_set_bit_mask(glamo, GLAMO_REG_LCD_HORIZ_RETR_END, ++ GLAMO_LCD_HV_RETR_END_MASK, bp); ++ reg_set_bit_mask(glamo, GLAMO_REG_LCD_HORIZ_DISP_START, ++ GLAMO_LCD_HV_RETR_DISP_START_MASK, disp); ++ reg_set_bit_mask(glamo, GLAMO_REG_LCD_HORIZ_DISP_END, ++ GLAMO_LCD_HV_RETR_DISP_END_MASK, fp); ++ ++ sync = 0; ++ bp = sync + var->vsync_len; ++ disp = bp + var->upper_margin; ++ fp = disp + yres; ++ total = fp + var->lower_margin; ++ ++ reg_set_bit_mask(glamo, GLAMO_REG_LCD_VERT_TOTAL, ++ GLAMO_LCD_HV_TOTAL_MASK, total); ++ reg_set_bit_mask(glamo, GLAMO_REG_LCD_VERT_RETR_START, ++ GLAMO_LCD_HV_RETR_START_MASK, sync); ++ reg_set_bit_mask(glamo, GLAMO_REG_LCD_VERT_RETR_END, ++ GLAMO_LCD_HV_RETR_END_MASK, bp); ++ reg_set_bit_mask(glamo, GLAMO_REG_LCD_VERT_DISP_START, ++ GLAMO_LCD_HV_RETR_DISP_START_MASK, disp); ++ reg_set_bit_mask(glamo, GLAMO_REG_LCD_VERT_DISP_END, ++ GLAMO_LCD_HV_RETR_DISP_END_MASK, fp); ++ ++ glamofb_cmd_mode(glamo, 0); ++ ++out_unlock: ++ dev_dbg(&glamo->mach_info->glamo->pdev->dev, ++ "glamofb_update_lcd_controller spin_unlock_irqrestore\n"); ++ spin_unlock_irqrestore(&glamo->lock_cmd, flags); ++} ++ ++static int glamofb_pan_display(struct fb_var_screeninfo *var, ++ struct fb_info *info) ++{ ++ struct glamofb_handle *glamo = info->par; ++ u_int16_t page = var->yoffset / glamo->mach_info->yres.defval; ++ reg_write(glamo, GLAMO_REG_LCD_COMMAND2, page); ++ ++ return 0; ++} ++ ++static int glamofb_set_par(struct fb_info *info) ++{ ++ struct glamofb_handle *glamo = info->par; ++ struct fb_var_screeninfo *var = &info->var; ++ ++ if (glamo->mach_info->glamo->suspending) { ++ dev_err(&glamo->mach_info->glamo->pdev->dev, ++ "IGNORING glamofb_set_par while " ++ "suspended\n"); ++ return -EBUSY; ++ } ++ ++ switch (var->bits_per_pixel) { ++ case 16: ++ info->fix.visual = FB_VISUAL_TRUECOLOR; ++ break; ++ default: ++ printk("Smedia driver doesn't support != 16bpp\n"); ++ return -EINVAL; ++ } ++ ++ info->fix.line_length = (var->xres * var->bits_per_pixel) / 8; ++ ++ glamofb_update_lcd_controller(glamo, var); ++ ++ return 0; ++} ++ ++ ++static void notify_blank(struct fb_info *info, int blank_mode) ++{ ++ struct fb_event event; ++ ++ event.info = info; ++ event.data = &blank_mode; ++ fb_notifier_call_chain(FB_EVENT_CONBLANK, &event); ++} ++ ++ ++static int glamofb_blank(int blank_mode, struct fb_info *info) ++{ ++ struct glamofb_handle *gfb = info->par; ++ struct glamo_core *gcore = gfb->mach_info->glamo; ++ ++ dev_dbg(gfb->dev, "glamofb_blank(%u)\n", blank_mode); ++ ++ switch (blank_mode) { ++ case FB_BLANK_VSYNC_SUSPEND: ++ case FB_BLANK_HSYNC_SUSPEND: ++ /* FIXME: add pdata hook/flag to indicate whether ++ * we should already switch off pixel clock here */ ++ break; ++ case FB_BLANK_POWERDOWN: ++ /* Simulating FB_BLANK_NORMAL allow turning off backlight */ ++ if (gfb->blank_mode != FB_BLANK_NORMAL) ++ notify_blank(info, FB_BLANK_NORMAL); ++ ++ /* LCM need notification before pixel clock is stopped */ ++ notify_blank(info, blank_mode); ++ ++ /* disable the pixel clock */ ++ glamo_engine_clkreg_set(gcore, GLAMO_ENGINE_LCD, ++ GLAMO_CLOCK_LCD_EN_DCLK, 0); ++ gfb->blank_mode = blank_mode; ++ break; ++ case FB_BLANK_UNBLANK: ++ case FB_BLANK_NORMAL: ++ /* enable the pixel clock if off */ ++ if (gfb->blank_mode == FB_BLANK_POWERDOWN) ++ glamo_engine_clkreg_set(gcore, ++ GLAMO_ENGINE_LCD, ++ GLAMO_CLOCK_LCD_EN_DCLK, ++ GLAMO_CLOCK_LCD_EN_DCLK); ++ ++ notify_blank(info, blank_mode); ++ gfb->blank_mode = blank_mode; ++ break; ++ } ++ ++ /* FIXME: once we have proper clock management in glamo-core, ++ * we can determine if other units need MCLK1 or the PLL, and ++ * disable it if not used. */ ++ return 0; ++} ++ ++static inline unsigned int chan_to_field(unsigned int chan, ++ struct fb_bitfield *bf) ++{ ++ chan &= 0xffff; ++ chan >>= 16 - bf->length; ++ return chan << bf->offset; ++} ++ ++static int glamofb_setcolreg(unsigned regno, ++ unsigned red, unsigned green, unsigned blue, ++ unsigned transp, struct fb_info *info) ++{ ++ struct glamofb_handle *glamo = info->par; ++ unsigned int val; ++ ++ if (glamo->mach_info->glamo->suspending) { ++ dev_err(&glamo->mach_info->glamo->pdev->dev, ++ "IGNORING glamofb_set_par while " ++ "suspended\n"); ++ return -EBUSY; ++ } ++ ++ switch (glamo->fb->fix.visual) { ++ case FB_VISUAL_TRUECOLOR: ++ case FB_VISUAL_DIRECTCOLOR: ++ /* true-colour, use pseuo-palette */ ++ ++ if (regno < 16) { ++ u32 *pal = glamo->fb->pseudo_palette; ++ ++ val = chan_to_field(red, &glamo->fb->var.red); ++ val |= chan_to_field(green, &glamo->fb->var.green); ++ val |= chan_to_field(blue, &glamo->fb->var.blue); ++ ++ pal[regno] = val; ++ }; ++ break; ++ default: ++ return 1; /* unknown type */ ++ } ++ ++ return 0; ++} ++ ++#ifdef CONFIG_MFD_GLAMO_HWACCEL ++static inline void glamofb_vsync_wait(struct glamofb_handle *glamo, ++ int line, int size, int range) ++{ ++ int count[2]; ++ ++ do { ++ count[0] = reg_read(glamo, GLAMO_REG_LCD_STATUS2) & 0x3ff; ++ count[1] = reg_read(glamo, GLAMO_REG_LCD_STATUS2) & 0x3ff; ++ } while (count[0] != count[1] || ++ (line < count[0] + range && ++ size > count[0] - range) || ++ count[0] < range * 2); ++} ++ ++/* ++ * Enable/disable the hardware cursor mode altogether ++ * (for blinking and such, use glamofb_cursor()). ++ */ ++static void glamofb_cursor_onoff(struct glamofb_handle *glamo, int on) ++{ ++ int y, size; ++ ++ if (glamo->cursor_on) { ++ y = reg_read(glamo, GLAMO_REG_LCD_CURSOR_Y_POS); ++ size = reg_read(glamo, GLAMO_REG_LCD_CURSOR_Y_SIZE); ++ ++ glamofb_vsync_wait(glamo, y, size, 30); ++ } ++ ++ reg_set_bit_mask(glamo, GLAMO_REG_LCD_MODE1, ++ GLAMO_LCD_MODE1_CURSOR_EN, ++ on ? GLAMO_LCD_MODE1_CURSOR_EN : 0); ++ glamo->cursor_on = on; ++ ++ /* Hide the cursor by default */ ++ reg_write(glamo, GLAMO_REG_LCD_CURSOR_X_SIZE, 0); ++} ++ ++static int glamofb_cursor(struct fb_info *info, struct fb_cursor *cursor) ++{ ++ struct glamofb_handle *glamo = info->par; ++ unsigned long flags; ++ ++ spin_lock_irqsave(&glamo->lock_cmd, flags); ++ ++ reg_write(glamo, GLAMO_REG_LCD_CURSOR_X_SIZE, ++ cursor->enable ? cursor->image.width : 0); ++ ++ if (cursor->set & FB_CUR_SETPOS) { ++ reg_write(glamo, GLAMO_REG_LCD_CURSOR_X_POS, ++ cursor->image.dx); ++ reg_write(glamo, GLAMO_REG_LCD_CURSOR_Y_POS, ++ cursor->image.dy); ++ } ++ ++ if (cursor->set & FB_CUR_SETCMAP) { ++ uint16_t fg = glamo->pseudo_pal[cursor->image.fg_color]; ++ uint16_t bg = glamo->pseudo_pal[cursor->image.bg_color]; ++ ++ reg_write(glamo, GLAMO_REG_LCD_CURSOR_FG_COLOR, fg); ++ reg_write(glamo, GLAMO_REG_LCD_CURSOR_BG_COLOR, bg); ++ reg_write(glamo, GLAMO_REG_LCD_CURSOR_DST_COLOR, fg); ++ } ++ ++ if (cursor->set & FB_CUR_SETHOT) ++ reg_write(glamo, GLAMO_REG_LCD_CURSOR_PRESET, ++ (cursor->hot.x << 8) | cursor->hot.y); ++ ++ if ((cursor->set & FB_CUR_SETSIZE) || ++ (cursor->set & (FB_CUR_SETIMAGE | FB_CUR_SETSHAPE))) { ++ int x, y, pitch, op; ++ const uint8_t *pcol = cursor->image.data; ++ const uint8_t *pmsk = cursor->mask; ++ uint8_t __iomem *dst = glamo->cursor_addr; ++ uint8_t dcol = 0; ++ uint8_t dmsk = 0; ++ uint8_t byte = 0; ++ ++ if (cursor->image.depth > 1) { ++ spin_unlock_irqrestore(&glamo->lock_cmd, flags); ++ return -EINVAL; ++ } ++ ++ pitch = ((cursor->image.width + 7) >> 2) & ~1; ++ reg_write(glamo, GLAMO_REG_LCD_CURSOR_PITCH, ++ pitch); ++ reg_write(glamo, GLAMO_REG_LCD_CURSOR_Y_SIZE, ++ cursor->image.height); ++ ++ for (y = 0; y < cursor->image.height; y++) { ++ byte = 0; ++ for (x = 0; x < cursor->image.width; x++) { ++ if ((x % 8) == 0) { ++ dcol = *pcol++; ++ dmsk = *pmsk++; ++ } else { ++ dcol >>= 1; ++ dmsk >>= 1; ++ } ++ ++ if (cursor->rop == ROP_COPY) ++ op = (dmsk & 1) ? ++ (dcol & 1) ? 1 : 3 : 0; ++ else ++ op = ((dmsk & 1) << 1) | ++ ((dcol & 1) << 0); ++ byte |= op << ((x & 3) << 1); ++ ++ if (x % 4 == 3) { ++ writeb(byte, dst + x / 4); ++ byte = 0; ++ } ++ } ++ if (x % 4) { ++ writeb(byte, dst + x / 4); ++ byte = 0; ++ } ++ ++ dst += pitch; ++ } ++ } ++ ++ spin_unlock_irqrestore(&glamo->lock_cmd, flags); ++ ++ return 0; ++} ++#endif ++ ++static inline int glamofb_cmdq_empty(struct glamofb_handle *gfb) ++{ ++ /* DGCMdQempty -- 1 == command queue is empty */ ++ return reg_read(gfb, GLAMO_REG_LCD_STATUS1) & (1 << 15); ++} ++ ++/* call holding gfb->lock_cmd when locking, until you unlock */ ++int glamofb_cmd_mode(struct glamofb_handle *gfb, int on) ++{ ++ int timeout = 2000000; ++ ++ if (gfb->mach_info->glamo->suspending) { ++ dev_err(&gfb->mach_info->glamo->pdev->dev, ++ "IGNORING glamofb_cmd_mode while " ++ "suspended\n"); ++ return -EBUSY; ++ } ++ ++ dev_dbg(gfb->dev, "glamofb_cmd_mode(gfb=%p, on=%d)\n", gfb, on); ++ if (on) { ++ dev_dbg(gfb->dev, "%s: waiting for cmdq empty: ", ++ __func__); ++ while ((!glamofb_cmdq_empty(gfb)) && (timeout--)) ++ /* yield() */; ++ if (timeout < 0) { ++ printk(KERN_ERR"*************" ++ "glamofb cmd_queue never got empty" ++ "*************\n"); ++ return -EIO; ++ } ++ dev_dbg(gfb->dev, "empty!\n"); ++ ++ /* display the entire frame then switch to command */ ++ reg_write(gfb, GLAMO_REG_LCD_COMMAND1, ++ GLAMO_LCD_CMD_TYPE_DISP | ++ GLAMO_LCD_CMD_DATA_FIRE_VSYNC); ++ ++ /* wait until lcd idle */ ++ dev_dbg(gfb->dev, "waiting for lcd idle: "); ++ timeout = 2000000; ++ while ((!reg_read(gfb, GLAMO_REG_LCD_STATUS2) & (1 << 12)) && ++ (timeout--)) ++ /* yield() */; ++ if (timeout < 0) { ++ printk(KERN_ERR"*************" ++ "glamofb lcd never idle" ++ "*************\n"); ++ return -EIO; ++ } ++ ++ mdelay(100); ++ ++ dev_dbg(gfb->dev, "cmd mode entered\n"); ++ ++ } else { ++ /* RGB interface needs vsync/hsync */ ++ if (reg_read(gfb, GLAMO_REG_LCD_MODE3) & GLAMO_LCD_MODE3_RGB) ++ reg_write(gfb, GLAMO_REG_LCD_COMMAND1, ++ GLAMO_LCD_CMD_TYPE_DISP | ++ GLAMO_LCD_CMD_DATA_DISP_SYNC); ++ ++ reg_write(gfb, GLAMO_REG_LCD_COMMAND1, ++ GLAMO_LCD_CMD_TYPE_DISP | ++ GLAMO_LCD_CMD_DATA_DISP_FIRE); ++ } ++ ++ return 0; ++} ++EXPORT_SYMBOL_GPL(glamofb_cmd_mode); ++ ++ ++int glamofb_cmd_write(struct glamofb_handle *gfb, u_int16_t val) ++{ ++ int timeout = 200000; ++ ++ if (gfb->mach_info->glamo->suspending) { ++ dev_err(&gfb->mach_info->glamo->pdev->dev, ++ "IGNORING glamofb_cmd_write while " ++ "suspended\n"); ++ return -EBUSY; ++ } ++ ++ dev_dbg(gfb->dev, "%s: waiting for cmdq empty\n", __func__); ++ while ((!glamofb_cmdq_empty(gfb)) && (timeout--)) ++ yield(); ++ if (timeout < 0) { ++ printk(KERN_ERR"*************" ++ "glamofb cmd_queue never got empty" ++ "*************\n"); ++ return 1; ++ } ++ dev_dbg(gfb->dev, "idle, writing 0x%04x\n", val); ++ ++ reg_write(gfb, GLAMO_REG_LCD_COMMAND1, val); ++ ++ return 0; ++} ++EXPORT_SYMBOL_GPL(glamofb_cmd_write); ++ ++static struct fb_ops glamofb_ops = { ++ .owner = THIS_MODULE, ++ .fb_check_var = glamofb_check_var, ++ .fb_pan_display = glamofb_pan_display, ++ .fb_set_par = glamofb_set_par, ++ .fb_blank = glamofb_blank, ++ .fb_setcolreg = glamofb_setcolreg, ++#ifdef CONFIG_MFD_GLAMO_HWACCEL ++ .fb_cursor = glamofb_cursor, ++#endif ++ .fb_fillrect = cfb_fillrect, ++ .fb_copyarea = cfb_copyarea, ++ .fb_imageblit = cfb_imageblit, ++}; ++ ++static int glamofb_init_regs(struct glamofb_handle *glamo) ++{ ++ struct fb_info *info = glamo->fb; ++ ++ glamofb_check_var(&info->var, info); ++ glamofb_run_script(glamo, glamo_regs, ARRAY_SIZE(glamo_regs)); ++ glamofb_set_par(info); ++ ++ return 0; ++} ++ ++static int __init glamofb_probe(struct platform_device *pdev) ++{ ++ int rc = -EIO; ++ struct fb_info *fbinfo; ++ struct glamofb_handle *glamofb; ++ struct glamofb_platform_data *mach_info = pdev->dev.platform_data; ++ ++ printk(KERN_INFO "SMEDIA Glamo frame buffer driver (C) 2007 " ++ "Openmoko, Inc.\n"); ++ ++ fbinfo = framebuffer_alloc(sizeof(struct glamofb_handle), &pdev->dev); ++ if (!fbinfo) ++ return -ENOMEM; ++ ++ glamofb = fbinfo->par; ++ glamofb->fb = fbinfo; ++ glamofb->dev = &pdev->dev; ++ ++ glamofb->angle = 0; ++ glamofb->blank_mode = FB_BLANK_POWERDOWN; ++ ++ strcpy(fbinfo->fix.id, "SMedia Glamo"); ++ ++ glamofb->reg = platform_get_resource_byname(pdev, IORESOURCE_MEM, ++ "glamo-fb-regs"); ++ if (!glamofb->reg) { ++ dev_err(&pdev->dev, "platform device with no registers?\n"); ++ rc = -ENOENT; ++ goto out_free; ++ } ++ ++ glamofb->fb_res = platform_get_resource_byname(pdev, IORESOURCE_MEM, ++ "glamo-fb-mem"); ++ if (!glamofb->fb_res) { ++ dev_err(&pdev->dev, "platform device with no memory ?\n"); ++ rc = -ENOENT; ++ goto out_free; ++ } ++ ++ glamofb->reg = request_mem_region(glamofb->reg->start, ++ RESSIZE(glamofb->reg), pdev->name); ++ if (!glamofb->reg) { ++ dev_err(&pdev->dev, "failed to request mmio region\n"); ++ goto out_free; ++ } ++ ++ glamofb->fb_res = request_mem_region(glamofb->fb_res->start, ++ mach_info->fb_mem_size, ++ pdev->name); ++ if (!glamofb->fb_res) { ++ dev_err(&pdev->dev, "failed to request vram region\n"); ++ goto out_release_reg; ++ } ++ ++ /* we want to remap only the registers required for this core ++ * driver. */ ++ glamofb->base = ioremap(glamofb->reg->start, RESSIZE(glamofb->reg)); ++ if (!glamofb->base) { ++ dev_err(&pdev->dev, "failed to ioremap() mmio memory\n"); ++ goto out_release_fb; ++ } ++ fbinfo->fix.smem_start = (unsigned long) glamofb->fb_res->start; ++ fbinfo->fix.smem_len = mach_info->fb_mem_size; ++ ++ fbinfo->screen_base = ioremap(glamofb->fb_res->start, ++ RESSIZE(glamofb->fb_res)); ++ if (!fbinfo->screen_base) { ++ dev_err(&pdev->dev, "failed to ioremap() vram memory\n"); ++ goto out_release_fb; ++ } ++ glamofb->cursor_addr = fbinfo->screen_base + 0x12C000; ++ ++ platform_set_drvdata(pdev, glamofb); ++ ++ glamofb->mach_info = pdev->dev.platform_data; ++ ++ fbinfo->fix.visual = FB_VISUAL_TRUECOLOR; ++ fbinfo->fix.type = FB_TYPE_PACKED_PIXELS; ++ fbinfo->fix.type_aux = 0; ++ fbinfo->fix.xpanstep = 0; ++ fbinfo->fix.ypanstep = mach_info->yres.defval; ++ fbinfo->fix.ywrapstep = 0; ++ fbinfo->fix.accel = FB_ACCEL_GLAMO; ++ ++ fbinfo->var.nonstd = 0; ++ fbinfo->var.activate = FB_ACTIVATE_NOW; ++ fbinfo->var.height = mach_info->height; ++ fbinfo->var.width = mach_info->width; ++ fbinfo->var.accel_flags = 0; /* FIXME */ ++ fbinfo->var.vmode = FB_VMODE_NONINTERLACED; ++ ++ fbinfo->fbops = &glamofb_ops; ++ fbinfo->flags = FBINFO_FLAG_DEFAULT; ++ fbinfo->pseudo_palette = &glamofb->pseudo_pal; ++ ++ fbinfo->var.xres = mach_info->xres.defval; ++ fbinfo->var.xres_virtual = mach_info->xres.defval; ++ fbinfo->var.yres = mach_info->yres.defval; ++ fbinfo->var.yres_virtual = mach_info->yres.defval * 2; ++ fbinfo->var.bits_per_pixel = mach_info->bpp.defval; ++ ++ fbinfo->var.pixclock = mach_info->pixclock; ++ fbinfo->var.left_margin = mach_info->left_margin; ++ fbinfo->var.right_margin = mach_info->right_margin; ++ fbinfo->var.upper_margin = mach_info->upper_margin; ++ fbinfo->var.lower_margin = mach_info->lower_margin; ++ fbinfo->var.hsync_len = mach_info->hsync_len; ++ fbinfo->var.vsync_len = mach_info->vsync_len; ++ ++ memset(fbinfo->screen_base, 0, ++ mach_info->xres.max * ++ mach_info->yres.max * ++ mach_info->bpp.max / 8); ++ ++ glamo_engine_enable(mach_info->glamo, GLAMO_ENGINE_LCD); ++ glamo_engine_reset(mach_info->glamo, GLAMO_ENGINE_LCD); ++ ++ dev_info(&pdev->dev, "spin_lock_init\n"); ++ spin_lock_init(&glamofb->lock_cmd); ++ glamofb_init_regs(glamofb); ++#ifdef CONFIG_MFD_GLAMO_HWACCEL ++ glamofb_cursor_onoff(glamofb, 1); ++#endif ++ ++#ifdef CONFIG_MFD_GLAMO_FB_XGLAMO_WORKAROUND ++ /* sysfs */ ++ rc = sysfs_create_group(&pdev->dev.kobj, &glamo_fb_attr_group); ++ if (rc < 0) { ++ dev_err(&pdev->dev, "cannot create sysfs group\n"); ++ goto out_unmap_fb; ++ } ++#endif ++ ++ rc = register_framebuffer(fbinfo); ++ if (rc < 0) { ++ dev_err(&pdev->dev, "failed to register framebuffer\n"); ++ goto out_unmap_fb; ++ } ++ ++ if (mach_info->spi_info) { ++ /* register the sibling spi device */ ++ mach_info->spi_info->glamofb_handle = glamofb; ++ glamo_spi_dev.dev.parent = &pdev->dev; ++ glamo_spi_dev.dev.platform_data = mach_info->spi_info; ++ platform_device_register(&glamo_spi_dev); ++ } ++ ++ printk(KERN_INFO "fb%d: %s frame buffer device\n", ++ fbinfo->node, fbinfo->fix.id); ++ ++ return 0; ++ ++out_unmap_fb: ++ iounmap(fbinfo->screen_base); ++ iounmap(glamofb->base); ++out_release_fb: ++ release_mem_region(glamofb->fb_res->start, RESSIZE(glamofb->fb_res)); ++out_release_reg: ++ release_mem_region(glamofb->reg->start, RESSIZE(glamofb->reg)); ++out_free: ++ framebuffer_release(fbinfo); ++ return rc; ++} ++ ++static int glamofb_remove(struct platform_device *pdev) ++{ ++ struct glamofb_handle *glamofb = platform_get_drvdata(pdev); ++ ++ platform_set_drvdata(pdev, NULL); ++ iounmap(glamofb->base); ++ release_mem_region(glamofb->reg->start, RESSIZE(glamofb->reg)); ++ kfree(glamofb); ++ ++ return 0; ++} ++ ++#ifdef CONFIG_PM ++ ++static int glamofb_suspend(struct platform_device *pdev, pm_message_t state) ++{ ++ struct glamofb_handle *gfb = platform_get_drvdata(pdev); ++ ++ /* we need to stop anything touching our framebuffer */ ++ fb_set_suspend(gfb->fb, 1); ++ ++ /* seriously -- nobody is allowed to touch glamo memory when we ++ * are suspended or we lock on nWAIT ++ */ ++ /* iounmap(gfb->fb->screen_base); */ ++ ++ return 0; ++} ++ ++static int glamofb_resume(struct platform_device *pdev) ++{ ++ struct glamofb_handle *gfb = platform_get_drvdata(pdev); ++ struct glamofb_platform_data *mach_info = pdev->dev.platform_data; ++ ++ /* OK let's allow framebuffer ops again */ ++ /* gfb->fb->screen_base = ioremap(gfb->fb_res->start, ++ RESSIZE(gfb->fb_res)); */ ++ glamo_engine_enable(mach_info->glamo, GLAMO_ENGINE_LCD); ++ glamo_engine_reset(mach_info->glamo, GLAMO_ENGINE_LCD); ++ ++ printk(KERN_ERR"spin_lock_init\n"); ++ spin_lock_init(&gfb->lock_cmd); ++ glamofb_init_regs(gfb); ++#ifdef CONFIG_MFD_GLAMO_HWACCEL ++ glamofb_cursor_onoff(gfb, 1); ++#endif ++ ++ fb_set_suspend(gfb->fb, 0); ++ ++ return 0; ++} ++#else ++#define glamofb_suspend NULL ++#define glamofb_resume NULL ++#endif ++ ++static struct platform_driver glamofb_driver = { ++ .probe = glamofb_probe, ++ .remove = glamofb_remove, ++ .suspend = glamofb_suspend, ++ .resume = glamofb_resume, ++ .driver = { ++ .name = "glamo-fb", ++ .owner = THIS_MODULE, ++ }, ++}; ++ ++static int __devinit glamofb_init(void) ++{ ++ return platform_driver_register(&glamofb_driver); ++} ++ ++static void __exit glamofb_cleanup(void) ++{ ++ platform_driver_unregister(&glamofb_driver); ++} ++ ++module_init(glamofb_init); ++module_exit(glamofb_cleanup); ++ ++MODULE_AUTHOR("Harald Welte <laforge@openmoko.org>"); ++MODULE_DESCRIPTION("Smedia Glamo 336x/337x framebuffer driver"); ++MODULE_LICENSE("GPL"); +diff -ruN --exclude='*.orig' --exclude='*.rej' linux-2.6.29-rc3.owrt/drivers/mfd/glamo/glamo-gpio.c linux-2.6.29-rc3.owrt.om/drivers/mfd/glamo/glamo-gpio.c +--- linux-2.6.29-rc3.owrt/drivers/mfd/glamo/glamo-gpio.c 1970-01-01 01:00:00.000000000 +0100 ++++ linux-2.6.29-rc3.owrt.om/drivers/mfd/glamo/glamo-gpio.c 2009-05-10 22:28:00.000000000 +0200 +@@ -0,0 +1,62 @@ ++ ++#include <linux/kernel.h> ++#include <linux/module.h> ++#include <linux/spinlock.h> ++#include <linux/io.h> ++ ++#include <linux/glamo-gpio.h> ++ ++#include "glamo-core.h" ++#include "glamo-regs.h" ++ ++void glamo_gpio_setpin(struct glamo_core *glamo, unsigned int pin, ++ unsigned int value) ++{ ++ unsigned int reg = REG_OF_GPIO(pin); ++ u_int16_t tmp; ++ ++ spin_lock(&glamo->lock); ++ tmp = readw(glamo->base + reg); ++ if (value) ++ tmp |= OUTPUT_BIT(pin); ++ else ++ tmp &= ~OUTPUT_BIT(pin); ++ writew(tmp, glamo->base + reg); ++ spin_unlock(&glamo->lock); ++} ++EXPORT_SYMBOL(glamo_gpio_setpin); ++ ++int glamo_gpio_getpin(struct glamo_core *glamo, unsigned int pin) ++{ ++ return readw(REG_OF_GPIO(pin)) & INPUT_BIT(pin) ? 1 : 0; ++} ++EXPORT_SYMBOL(glamo_gpio_getpin); ++ ++void glamo_gpio_cfgpin(struct glamo_core *glamo, unsigned int pinfunc) ++{ ++ unsigned int reg = REG_OF_GPIO(pinfunc); ++ u_int16_t tmp; ++ ++ spin_lock(&glamo->lock); ++ tmp = readw(glamo->base + reg); ++ ++ if ((pinfunc & 0x00f0) == GLAMO_GPIO_F_FUNC) { ++ /* pin is a function pin: clear gpio bit */ ++ tmp &= ~FUNC_BIT(pinfunc); ++ } else { ++ /* pin is gpio: set gpio bit */ ++ tmp |= FUNC_BIT(pinfunc); ++ ++ if (pinfunc & GLAMO_GPIO_F_IN) { ++ /* gpio input: set bit to disable output mode */ ++ tmp |= GPIO_OUT_BIT(pinfunc); ++ } else if (pinfunc & GLAMO_GPIO_F_OUT) { ++ /* gpio output: clear bit to enable output mode */ ++ tmp &= ~GPIO_OUT_BIT(pinfunc); ++ } ++ } ++ writew(tmp, glamo->base + reg); ++ spin_unlock(&glamo->lock); ++} ++EXPORT_SYMBOL(glamo_gpio_cfgpin); ++ +diff -ruN --exclude='*.orig' --exclude='*.rej' linux-2.6.29-rc3.owrt/drivers/mfd/glamo/glamo-lcm-spi.c linux-2.6.29-rc3.owrt.om/drivers/mfd/glamo/glamo-lcm-spi.c +--- linux-2.6.29-rc3.owrt/drivers/mfd/glamo/glamo-lcm-spi.c 1970-01-01 01:00:00.000000000 +0100 ++++ linux-2.6.29-rc3.owrt.om/drivers/mfd/glamo/glamo-lcm-spi.c 2009-05-10 22:28:00.000000000 +0200 +@@ -0,0 +1,240 @@ ++/* ++ * Copyright (C) 2007 Openmoko, Inc. ++ * Author: Harald Welte <laforge@openmoko.org> ++ * ++ * Smedia Glamo GPIO based SPI driver ++ * ++ * 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. ++ * ++ * This driver currently only implements a minimum subset of the hardware ++ * features, esp. those features that are required to drive the jbt6k74 ++ * LCM controller asic in the TD028TTEC1 LCM. ++ * ++*/ ++ ++#define DEBUG ++ ++#include <linux/kernel.h> ++#include <linux/init.h> ++#include <linux/delay.h> ++#include <linux/device.h> ++#include <linux/spinlock.h> ++#include <linux/workqueue.h> ++#include <linux/platform_device.h> ++ ++#include <linux/spi/spi.h> ++#include <linux/spi/spi_bitbang.h> ++#include <linux/spi/glamo.h> ++ ++#include <linux/glamofb.h> ++ ++#include <mach/hardware.h> ++ ++#include "glamo-core.h" ++#include "glamo-regs.h" ++ ++struct glamo_spi { ++ struct spi_bitbang bitbang; ++ struct spi_master *master; ++ struct glamo_spi_info *info; ++ struct device *dev; ++}; ++ ++static inline struct glamo_spi *to_gs(struct spi_device *spi) ++{ ++ return spi->controller_data; ++} ++ ++static int glamo_spi_setupxfer(struct spi_device *spi, struct spi_transfer *t) ++{ ++ unsigned int bpw; ++ ++ bpw = t ? t->bits_per_word : spi->bits_per_word; ++ ++ if (bpw != 9 && bpw != 8) { ++ dev_err(&spi->dev, "invalid bits-per-word (%d)\n", bpw); ++ return -EINVAL; ++ } ++ ++ return 0; ++} ++ ++static void glamo_spi_chipsel(struct spi_device *spi, int value) ++{ ++#if 0 ++ struct glamo_spi *gs = to_gs(spi); ++ ++ dev_dbg(&spi->dev, "chipsel %d: spi=%p, gs=%p, info=%p, handle=%p\n", ++ value, spi, gs, gs->info, gs->info->glamofb_handle); ++ ++ glamofb_cmd_mode(gs->info->glamofb_handle, value); ++#endif ++} ++ ++static int glamo_spi_txrx(struct spi_device *spi, struct spi_transfer *t) ++{ ++ struct glamo_spi *gs = to_gs(spi); ++ const u_int16_t *ui16 = (const u_int16_t *) t->tx_buf; ++ u_int16_t nine_bits; ++ int i; ++ ++ dev_dbg(&spi->dev, "txrx: tx %p, rx %p, bpw %d, len %d\n", ++ t->tx_buf, t->rx_buf, t->bits_per_word, t->len); ++ ++ if (spi->bits_per_word == 9) ++ nine_bits = (1 << 9); ++ else ++ nine_bits = 0; ++ ++ if (t->len > 3 * sizeof(u_int16_t)) { ++ dev_err(&spi->dev, "this driver doesn't support " ++ "%u sized xfers\n", t->len); ++ return -EINVAL; ++ } ++ ++ for (i = 0; i < t->len/sizeof(u_int16_t); i++) { ++ /* actually transfer the data */ ++#if 1 ++ glamofb_cmd_write(gs->info->glamofb_handle, ++ GLAMO_LCD_CMD_TYPE_SERIAL | nine_bits | ++ (1 << 10) | (1 << 11) | (ui16[i] & 0x1ff)); ++#endif ++ /* FIXME: fire ?!? */ ++ if (i == 0 && (ui16[i] & 0x1ff) == 0x29) { ++ dev_dbg(&spi->dev, "leaving command mode\n"); ++ glamofb_cmd_mode(gs->info->glamofb_handle, 0); ++ } ++ } ++ ++ return t->len; ++} ++ ++static int glamo_spi_setup(struct spi_device *spi) ++{ ++ int ret; ++ ++ if (!spi->bits_per_word) ++ spi->bits_per_word = 9; ++ ++ /* FIXME: hardware can do this */ ++ if (spi->mode & SPI_LSB_FIRST) ++ return -EINVAL; ++ ++ ret = glamo_spi_setupxfer(spi, NULL); ++ if (ret < 0) { ++ dev_err(&spi->dev, "setupxfer returned %d\n", ret); ++ return ret; ++ } ++ ++ dev_dbg(&spi->dev, "%s: mode %d, %u bpw\n", ++ __FUNCTION__, spi->mode, spi->bits_per_word); ++ ++ return 0; ++} ++ ++static int glamo_spi_probe(struct platform_device *pdev) ++{ ++ struct spi_master *master; ++ struct glamo_spi *sp; ++ int ret; ++ int i; ++ ++ master = spi_alloc_master(&pdev->dev, sizeof(struct glamo_spi)); ++ if (master == NULL) { ++ dev_err(&pdev->dev, "failed to allocate spi master\n"); ++ ret = -ENOMEM; ++ goto err; ++ } ++ ++ sp = spi_master_get_devdata(master); ++ memset(sp, 0, sizeof(struct glamo_spi)); ++ ++ sp->master = spi_master_get(master); ++ sp->info = pdev->dev.platform_data; ++ if (!sp->info) { ++ dev_err(&pdev->dev, "can't operate without platform data\n"); ++ ret = -EIO; ++ goto err_no_pdev; ++ } ++ dev_dbg(&pdev->dev, "sp->info(pdata) = %p\n", sp->info); ++ ++ sp->dev = &pdev->dev; ++ ++ platform_set_drvdata(pdev, sp); ++ ++ sp->bitbang.master = sp->master; ++ sp->bitbang.setup_transfer = glamo_spi_setupxfer; ++ sp->bitbang.chipselect = glamo_spi_chipsel; ++ sp->bitbang.txrx_bufs = glamo_spi_txrx; ++ sp->bitbang.master->setup = glamo_spi_setup; ++ ++ ret = spi_bitbang_start(&sp->bitbang); ++ if (ret) ++ goto err_no_bitbang; ++ ++ /* register the chips to go with the board */ ++ ++ glamofb_cmd_mode(sp->info->glamofb_handle, 1); ++ ++ for (i = 0; i < sp->info->board_size; i++) { ++ dev_info(&pdev->dev, "registering %p: %s\n", ++ &sp->info->board_info[i], ++ sp->info->board_info[i].modalias); ++ ++ sp->info->board_info[i].controller_data = sp; ++ spi_new_device(master, sp->info->board_info + i); ++ } ++ ++ return 0; ++ ++err_no_bitbang: ++ platform_set_drvdata(pdev, NULL); ++err_no_pdev: ++ spi_master_put(sp->bitbang.master); ++err: ++ return ret; ++ ++} ++ ++static int glamo_spi_remove(struct platform_device *pdev) ++{ ++ struct glamo_spi *sp = platform_get_drvdata(pdev); ++ ++ spi_bitbang_stop(&sp->bitbang); ++ spi_master_put(sp->bitbang.master); ++ ++ return 0; ++} ++ ++#define glamo_spi_suspend NULL ++#define glamo_spi_resume NULL ++ ++static struct platform_driver glamo_spi_drv = { ++ .probe = glamo_spi_probe, ++ .remove = glamo_spi_remove, ++ .suspend = glamo_spi_suspend, ++ .resume = glamo_spi_resume, ++ .driver = { ++ .name = "glamo-lcm-spi", ++ .owner = THIS_MODULE, ++ }, ++}; ++ ++static int __init glamo_spi_init(void) ++{ ++ return platform_driver_register(&glamo_spi_drv); ++} ++ ++static void __exit glamo_spi_exit(void) ++{ ++ platform_driver_unregister(&glamo_spi_drv); ++} ++ ++module_init(glamo_spi_init); ++module_exit(glamo_spi_exit); ++ ++MODULE_DESCRIPTION("Smedia Glamo 336x/337x LCM serial command SPI Driver"); ++MODULE_AUTHOR("Harald Welte <laforge@openmoko.org>") ++MODULE_LICENSE("GPL"); +diff -ruN --exclude='*.orig' --exclude='*.rej' linux-2.6.29-rc3.owrt/drivers/mfd/glamo/glamo-mci.c linux-2.6.29-rc3.owrt.om/drivers/mfd/glamo/glamo-mci.c +--- linux-2.6.29-rc3.owrt/drivers/mfd/glamo/glamo-mci.c 1970-01-01 01:00:00.000000000 +0100 ++++ linux-2.6.29-rc3.owrt.om/drivers/mfd/glamo/glamo-mci.c 2009-05-10 22:28:00.000000000 +0200 +@@ -0,0 +1,1168 @@ ++/* ++ * linux/drivers/mmc/host/glamo-mmc.c - Glamo MMC driver ++ * ++ * Copyright (C) 2007 Openmoko, Inc, Andy Green <andy@openmoko.com> ++ * Based on S3C MMC driver that was: ++ * Copyright (C) 2004-2006 maintech GmbH, Thomas Kleffel <tk@maintech.de> ++ * ++ * 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/dma-mapping.h> ++#include <linux/clk.h> ++#include <linux/mmc/mmc.h> ++#include <linux/mmc/host.h> ++#include <linux/platform_device.h> ++#include <linux/irq.h> ++#include <linux/pcf50633.h> ++#include <linux/delay.h> ++#include <linux/interrupt.h> ++#include <linux/spinlock.h> ++#include <linux/workqueue.h> ++ ++#include <asm/dma.h> ++#include <asm/dma-mapping.h> ++#include <asm/io.h> ++ ++#include "glamo-mci.h" ++#include "glamo-core.h" ++#include "glamo-regs.h" ++ ++/* from glamo-core.c */ ++extern struct glamo_mci_pdata glamo_mci_def_pdata; ++ ++static spinlock_t clock_lock; ++ ++#define DRIVER_NAME "glamo-mci" ++#define RESSIZE(ressource) (((ressource)->end - (ressource)->start) + 1) ++ ++static void glamo_mci_send_request(struct mmc_host *mmc); ++ ++/* ++ * Max SD clock rate ++ * ++ * held at /(3 + 1) due to concerns of 100R recommended series resistor ++ * allows 16MHz @ 4-bit --> 8MBytes/sec raw ++ * ++ * you can override this on kernel commandline using ++ * ++ * glamo_mci.sd_max_clk=10000000 ++ * ++ * for example ++ */ ++ ++static int sd_max_clk = 50000000 / 3; ++module_param(sd_max_clk, int, 0644); ++ ++/* ++ * Slow SD clock rate ++ * ++ * you can override this on kernel commandline using ++ * ++ * glamo_mci.sd_slow_ratio=8 ++ * ++ * for example ++ * ++ * platform callback is used to decide effective clock rate, if not ++ * defined then max is used, if defined and returns nonzero, rate is ++ * divided by this factor ++ */ ++ ++static int sd_slow_ratio = 8; ++module_param(sd_slow_ratio, int, 0644); ++ ++/* ++ * Post-power SD clock rate ++ * ++ * you can override this on kernel commandline using ++ * ++ * glamo_mci.sd_post_power_clock=1000000 ++ * ++ * for example ++ * ++ * After changing power to card, clock is held at this rate until first bulk ++ * transfer completes ++ */ ++ ++static int sd_post_power_clock = 1000000; ++module_param(sd_post_power_clock, int, 0644); ++ ++ ++/* ++ * SD Signal drive strength ++ * ++ * you can override this on kernel commandline using ++ * ++ * glamo_mci.sd_drive=0 ++ * ++ * for example ++ */ ++ ++static int sd_drive; ++module_param(sd_drive, int, 0644); ++ ++/* ++ * SD allow SD clock to run while idle ++ * ++ * you can override this on kernel commandline using ++ * ++ * glamo_mci.sd_idleclk=0 ++ * ++ * for example ++ */ ++ ++static int sd_idleclk = 0; /* disallow idle clock by default */ ++module_param(sd_idleclk, int, 0644); ++ ++/* used to stash real idleclk state in suspend: we force it to run in there */ ++static int suspend_sd_idleclk; ++ ++ ++unsigned char CRC7(u8 * pu8, int cnt) ++{ ++ u8 crc = 0; ++ ++ while (cnt--) { ++ int n; ++ u8 d = *pu8++; ++ for (n = 0; n < 8; n++) { ++ crc <<= 1; ++ if ((d & 0x80) ^ (crc & 0x80)) ++ crc ^= 0x09; ++ d <<= 1; ++ } ++ } ++ return (crc << 1) | 1; ++} ++ ++static int get_data_buffer(struct glamo_mci_host *host, ++ volatile u32 *words, volatile u16 **pointer) ++{ ++ struct scatterlist *sg; ++ ++ *words = 0; ++ *pointer = NULL; ++ ++ if (host->pio_active == XFER_NONE) ++ return -EINVAL; ++ ++ if ((!host->mrq) || (!host->mrq->data)) ++ return -EINVAL; ++ ++ if (host->pio_sgptr >= host->mrq->data->sg_len) { ++ dev_dbg(&host->pdev->dev, "no more buffers (%i/%i)\n", ++ host->pio_sgptr, host->mrq->data->sg_len); ++ return -EBUSY; ++ } ++ sg = &host->mrq->data->sg[host->pio_sgptr]; ++ ++ *words = sg->length >> 1; /* we are working with a 16-bit data bus */ ++ *pointer = page_address(sg_page(sg)) + sg->offset; ++ ++ BUG_ON(((long)(*pointer)) & 1); ++ ++ host->pio_sgptr++; ++ ++ /* dev_info(&host->pdev->dev, "new buffer (%i/%i)\n", ++ host->pio_sgptr, host->mrq->data->sg_len); */ ++ return 0; ++} ++ ++static void do_pio_read(struct glamo_mci_host *host) ++{ ++ int res; ++ u16 __iomem *from_ptr = host->base_data + (RESSIZE(host->mem_data) / ++ sizeof(u16) / 2); ++#ifdef DEBUG ++ u16 * block; ++#endif ++ ++ while (1) { ++ res = get_data_buffer(host, &host->pio_words, &host->pio_ptr); ++ if (res) { ++ host->pio_active = XFER_NONE; ++ host->complete_what = COMPLETION_FINALIZE; ++ ++ dev_dbg(&host->pdev->dev, "pio_read(): " ++ "complete (no more data).\n"); ++ return; ++ } ++ ++ dev_dbg(&host->pdev->dev, "pio_read(): host->pio_words: %d\n", ++ host->pio_words); ++ ++ host->pio_count += host->pio_words << 1; ++ ++#ifdef DEBUG ++ block = (u16 *)host->pio_ptr; ++ res = host->pio_words << 1; ++#endif ++#if 0 ++ /* u16-centric memcpy */ ++ while (host->pio_words--) ++ *host->pio_ptr++ = *from_ptr++; ++#else ++ /* memcpy can be faster? */ ++ memcpy((void *)host->pio_ptr, from_ptr, host->pio_words << 1); ++ host->pio_ptr += host->pio_words; ++#endif ++ ++#ifdef DEBUG ++ print_hex_dump(KERN_DEBUG, "", DUMP_PREFIX_OFFSET, 16, 1, ++ (void *)block, res, 1); ++#endif ++ } ++} ++ ++static int do_pio_write(struct glamo_mci_host *host) ++{ ++ int res = 0; ++ volatile u16 __iomem *to_ptr = host->base_data; ++ int err = 0; ++ ++ dev_dbg(&host->pdev->dev, "pio_write():\n"); ++ while (!res) { ++ res = get_data_buffer(host, &host->pio_words, &host->pio_ptr); ++ if (res) ++ continue; ++ ++ dev_dbg(&host->pdev->dev, "pio_write():new source: [%i]@[%p]\n", ++ host->pio_words, host->pio_ptr); ++ ++ host->pio_count += host->pio_words << 1; ++ while (host->pio_words--) ++ writew(*host->pio_ptr++, to_ptr++); ++ } ++ ++ dev_dbg(&host->pdev->dev, "pio_write(): complete\n"); ++ host->pio_active = XFER_NONE; ++ return err; ++} ++ ++static void __glamo_mci_fix_card_div(struct glamo_mci_host *host, int div) ++{ ++ unsigned long flags; ++ ++ spin_lock_irqsave(&clock_lock, flags); ++ ++ if (div < 0) { ++ /* stop clock - remove clock from divider input */ ++ writew(readw(glamo_mci_def_pdata.pglamo->base + ++ GLAMO_REG_CLOCK_GEN5_1) & (~GLAMO_CLOCK_GEN51_EN_DIV_TCLK), ++ glamo_mci_def_pdata.pglamo->base + GLAMO_REG_CLOCK_GEN5_1); ++ ++ goto done; ++ } else { ++ /* set the nearest prescaler factor ++ * ++ * register shared with SCLK divisor -- no chance of race because ++ * we don't use sensor interface ++ */ ++ writew((readw(glamo_mci_def_pdata.pglamo->base + ++ GLAMO_REG_CLOCK_GEN8) & 0xff00) | div, ++ glamo_mci_def_pdata.pglamo->base + GLAMO_REG_CLOCK_GEN8); ++ /* enable clock to divider input */ ++ writew(readw(glamo_mci_def_pdata.pglamo->base + ++ GLAMO_REG_CLOCK_GEN5_1) | GLAMO_CLOCK_GEN51_EN_DIV_TCLK, ++ glamo_mci_def_pdata.pglamo->base + GLAMO_REG_CLOCK_GEN5_1); ++ } ++ ++ if (host->force_slow_during_powerup) ++ div = host->clk_rate / sd_post_power_clock; ++ else ++ if (host->pdata->glamo_mci_use_slow) ++ if ((host->pdata->glamo_mci_use_slow)()) ++ div = div * sd_slow_ratio; ++ ++ if (div > 255) ++ div = 255; ++ ++ /* ++ * set the nearest prescaler factor ++ * ++ * register shared with SCLK divisor -- no chance of race because ++ * we don't use sensor interface ++ */ ++ writew((readw(glamo_mci_def_pdata.pglamo->base + ++ GLAMO_REG_CLOCK_GEN8) & 0xff00) | div, ++ glamo_mci_def_pdata.pglamo->base + GLAMO_REG_CLOCK_GEN8); ++ /* enable clock to divider input */ ++ writew(readw(glamo_mci_def_pdata.pglamo->base + ++ GLAMO_REG_CLOCK_GEN5_1) | GLAMO_CLOCK_GEN51_EN_DIV_TCLK, ++ glamo_mci_def_pdata.pglamo->base + GLAMO_REG_CLOCK_GEN5_1); ++ ++done: ++ spin_unlock_irqrestore(&clock_lock, flags); ++} ++ ++static int __glamo_mci_set_card_clock(struct glamo_mci_host *host, int freq, ++ int *division) ++{ ++ int div = 0; ++ int real_rate = 0; ++ ++ if (freq) { ++ /* Set clock */ ++ for (div = 0; div < 256; div++) { ++ real_rate = host->clk_rate / (div + 1); ++ if (real_rate <= freq) ++ break; ++ } ++ if (div > 255) ++ div = 255; ++ ++ if (division) ++ *division = div; ++ ++ __glamo_mci_fix_card_div(host, div); ++ ++ } else { ++ /* stop clock */ ++ if (division) ++ *division = 0xff; ++ ++ if (!sd_idleclk && !host->force_slow_during_powerup) ++ /* clock off */ ++ __glamo_mci_fix_card_div(host, -1); ++ } ++ ++ return real_rate; ++} ++ ++ ++static void glamo_mci_irq_worker(struct work_struct *work) ++{ ++ struct glamo_mci_host *host = ++ container_of(work, struct glamo_mci_host, irq_work); ++ struct mmc_command *cmd = host->mrq->cmd; ++ ++ if (host->pio_active == XFER_READ) ++ do_pio_read(host); ++ ++ host->mrq->data->bytes_xfered = host->pio_count; ++ dev_dbg(&host->pdev->dev, "count=%d\n", host->pio_count); ++ ++ /* issue STOP if we have been given one to use */ ++ if (host->mrq->stop) { ++ host->cmd_is_stop = 1; ++ glamo_mci_send_request(host->mmc); ++ host->cmd_is_stop = 0; ++ } ++ ++ if (!sd_idleclk && !host->force_slow_during_powerup) ++ /* clock off */ ++ __glamo_mci_fix_card_div(host, -1); ++ ++ host->complete_what = COMPLETION_NONE; ++ host->mrq = NULL; ++ mmc_request_done(host->mmc, cmd->mrq); ++} ++ ++static void glamo_mci_irq_host(struct glamo_mci_host *host) ++{ ++ u16 status; ++ struct mmc_command *cmd; ++ unsigned long iflags; ++ ++ if (host->suspending) { /* bad news, dangerous time */ ++ dev_err(&host->pdev->dev, "****glamo_mci_irq before resumed\n"); ++ return; ++ } ++ ++ if (!host->mrq) ++ return; ++ cmd = host->mrq->cmd; ++ if (!cmd) ++ return; ++ ++ spin_lock_irqsave(&host->complete_lock, iflags); ++ ++ status = readw(host->base + GLAMO_REG_MMC_RB_STAT1); ++ dev_dbg(&host->pdev->dev, "status = 0x%04x\n", status); ++ ++ /* ack this interrupt source */ ++ writew(GLAMO_IRQ_MMC, ++ glamo_mci_def_pdata.pglamo->base + GLAMO_REG_IRQ_CLEAR); ++ ++ /* we ignore a data timeout report if we are also told the data came */ ++ if (status & GLAMO_STAT1_MMC_RB_DRDY) ++ status &= ~GLAMO_STAT1_MMC_DTOUT; ++ ++ if (status & (GLAMO_STAT1_MMC_RTOUT | ++ GLAMO_STAT1_MMC_DTOUT)) ++ cmd->error = -ETIMEDOUT; ++ if (status & (GLAMO_STAT1_MMC_BWERR | ++ GLAMO_STAT1_MMC_BRERR)) ++ cmd->error = -EILSEQ; ++ if (cmd->error) { ++ dev_info(&host->pdev->dev, "Error after cmd: 0x%x\n", status); ++ goto done; ++ } ++ ++ /* ++ * disable the initial slow start after first bulk transfer ++ */ ++ if (host->force_slow_during_powerup) ++ host->force_slow_during_powerup--; ++ ++ /* ++ * we perform the memcpy out of Glamo memory outside of IRQ context ++ * so we don't block other interrupts ++ */ ++ schedule_work(&host->irq_work); ++ ++ goto leave; ++ ++done: ++ host->complete_what = COMPLETION_NONE; ++ host->mrq = NULL; ++ mmc_request_done(host->mmc, cmd->mrq); ++leave: ++ spin_unlock_irqrestore(&host->complete_lock, iflags); ++} ++ ++static void glamo_mci_irq(unsigned int irq, struct irq_desc *desc) ++{ ++ struct glamo_mci_host *host = (struct glamo_mci_host *) ++ desc->handler_data; ++ ++ if (host) ++ glamo_mci_irq_host(host); ++ ++} ++ ++static int glamo_mci_send_command(struct glamo_mci_host *host, ++ struct mmc_command *cmd) ++{ ++ u8 u8a[6]; ++ u16 fire = 0; ++ ++ /* if we can't do it, reject as busy */ ++ if (!readw(host->base + GLAMO_REG_MMC_RB_STAT1) & ++ GLAMO_STAT1_MMC_IDLE) { ++ host->mrq = NULL; ++ cmd->error = -EBUSY; ++ mmc_request_done(host->mmc, host->mrq); ++ return -EBUSY; ++ } ++ ++ /* create an array in wire order for CRC computation */ ++ u8a[0] = 0x40 | (cmd->opcode & 0x3f); ++ u8a[1] = (u8)(cmd->arg >> 24); ++ u8a[2] = (u8)(cmd->arg >> 16); ++ u8a[3] = (u8)(cmd->arg >> 8); ++ u8a[4] = (u8)cmd->arg; ++ u8a[5] = CRC7(&u8a[0], 5); /* CRC7 on first 5 bytes of packet */ ++ ++ /* issue the wire-order array including CRC in register order */ ++ writew((u8a[4] << 8) | u8a[5], host->base + GLAMO_REG_MMC_CMD_REG1); ++ writew((u8a[2] << 8) | u8a[3], host->base + GLAMO_REG_MMC_CMD_REG2); ++ writew((u8a[0] << 8) | u8a[1], host->base + GLAMO_REG_MMC_CMD_REG3); ++ ++ /* command index toggle */ ++ fire |= (host->ccnt & 1) << 12; ++ ++ /* set type of command */ ++ switch (mmc_cmd_type(cmd)) { ++ case MMC_CMD_BC: ++ fire |= GLAMO_FIRE_MMC_CMDT_BNR; ++ break; ++ case MMC_CMD_BCR: ++ fire |= GLAMO_FIRE_MMC_CMDT_BR; ++ break; ++ case MMC_CMD_AC: ++ fire |= GLAMO_FIRE_MMC_CMDT_AND; ++ break; ++ case MMC_CMD_ADTC: ++ fire |= GLAMO_FIRE_MMC_CMDT_AD; ++ break; ++ } ++ /* ++ * if it expects a response, set the type expected ++ * ++ * R1, Length : 48bit, Normal response ++ * R1b, Length : 48bit, same R1, but added card busy status ++ * R2, Length : 136bit (really 128 bits with CRC snipped) ++ * R3, Length : 48bit (OCR register value) ++ * R4, Length : 48bit, SDIO_OP_CONDITION, Reverse SDIO Card ++ * R5, Length : 48bit, IO_RW_DIRECTION, Reverse SDIO Card ++ * R6, Length : 48bit (RCA register) ++ * R7, Length : 48bit (interface condition, VHS(voltage supplied), ++ * check pattern, CRC7) ++ */ ++ switch (mmc_resp_type(cmd)) { ++ case MMC_RSP_R6: /* same index as R7 and R1 */ ++ fire |= GLAMO_FIRE_MMC_RSPT_R1; ++ break; ++ case MMC_RSP_R1B: ++ fire |= GLAMO_FIRE_MMC_RSPT_R1b; ++ break; ++ case MMC_RSP_R2: ++ fire |= GLAMO_FIRE_MMC_RSPT_R2; ++ break; ++ case MMC_RSP_R3: ++ fire |= GLAMO_FIRE_MMC_RSPT_R3; ++ break; ++ /* R4 and R5 supported by chip not defined in linux/mmc/core.h (sdio) */ ++ } ++ /* ++ * From the command index, set up the command class in the host ctrllr ++ * ++ * missing guys present on chip but couldn't figure out how to use yet: ++ * 0x0 "stream read" ++ * 0x9 "cancel running command" ++ */ ++ switch (cmd->opcode) { ++ case MMC_READ_SINGLE_BLOCK: ++ fire |= GLAMO_FIRE_MMC_CC_SBR; /* single block read */ ++ break; ++ case MMC_SWITCH: /* 64 byte payload */ ++ case 0x33: /* observed issued by MCI */ ++ case MMC_READ_MULTIPLE_BLOCK: ++ /* we will get an interrupt off this */ ++ if (!cmd->mrq->stop) ++ /* multiblock no stop */ ++ fire |= GLAMO_FIRE_MMC_CC_MBRNS; ++ else ++ /* multiblock with stop */ ++ fire |= GLAMO_FIRE_MMC_CC_MBRS; ++ break; ++ case MMC_WRITE_BLOCK: ++ fire |= GLAMO_FIRE_MMC_CC_SBW; /* single block write */ ++ break; ++ case MMC_WRITE_MULTIPLE_BLOCK: ++ if (cmd->mrq->stop) ++ /* multiblock with stop */ ++ fire |= GLAMO_FIRE_MMC_CC_MBWS; ++ else ++// /* multiblock NO stop-- 'RESERVED'? */ ++ fire |= GLAMO_FIRE_MMC_CC_MBWNS; ++ break; ++ case MMC_STOP_TRANSMISSION: ++ fire |= GLAMO_FIRE_MMC_CC_STOP; /* STOP */ ++ break; ++ default: ++ fire |= GLAMO_FIRE_MMC_CC_BASIC; /* "basic command" */ ++ break; ++ } ++ ++ /* always largest timeout */ ++ writew(0xfff, host->base + GLAMO_REG_MMC_TIMEOUT); ++ ++ /* Generate interrupt on txfer */ ++ writew((readw(host->base + GLAMO_REG_MMC_BASIC) & 0x3e) | ++ 0x0800 | GLAMO_BASIC_MMC_NO_CLK_RD_WAIT | ++ GLAMO_BASIC_MMC_EN_COMPL_INT | (sd_drive << 6), ++ host->base + GLAMO_REG_MMC_BASIC); ++ ++ /* send the command out on the wire */ ++ /* dev_info(&host->pdev->dev, "Using FIRE %04X\n", fire); */ ++ writew(fire, host->base + GLAMO_REG_MMC_CMD_FIRE); ++ cmd->error = 0; ++ return 0; ++} ++ ++static int glamo_mci_prepare_pio(struct glamo_mci_host *host, ++ struct mmc_data *data) ++{ ++ /* ++ * the S-Media-internal RAM offset for our MMC buffer ++ * Read is halfway up the buffer and write is at the start ++ */ ++ if (data->flags & MMC_DATA_READ) { ++ writew((u16)(GLAMO_FB_SIZE + (RESSIZE(host->mem_data) / 2)), ++ host->base + GLAMO_REG_MMC_WDATADS1); ++ writew((u16)((GLAMO_FB_SIZE + ++ (RESSIZE(host->mem_data) / 2)) >> 16), ++ host->base + GLAMO_REG_MMC_WDATADS2); ++ } else { ++ writew((u16)GLAMO_FB_SIZE, host->base + ++ GLAMO_REG_MMC_RDATADS1); ++ writew((u16)(GLAMO_FB_SIZE >> 16), host->base + ++ GLAMO_REG_MMC_RDATADS2); ++ } ++ ++ /* set up the block info */ ++ writew(data->blksz, host->base + GLAMO_REG_MMC_DATBLKLEN); ++ writew(data->blocks, host->base + GLAMO_REG_MMC_DATBLKCNT); ++ dev_dbg(&host->pdev->dev, "(blksz=%d, count=%d)\n", ++ data->blksz, data->blocks); ++ host->pio_sgptr = 0; ++ host->pio_words = 0; ++ host->pio_count = 0; ++ host->pio_active = 0; ++ /* if write, prep the write into the shared RAM before the command */ ++ if (data->flags & MMC_DATA_WRITE) { ++ host->pio_active = XFER_WRITE; ++ return do_pio_write(host); ++ } ++ host->pio_active = XFER_READ; ++ return 0; ++} ++ ++static void glamo_mci_send_request(struct mmc_host *mmc) ++{ ++ struct glamo_mci_host *host = mmc_priv(mmc); ++ struct mmc_request *mrq = host->mrq; ++ struct mmc_command *cmd = host->cmd_is_stop ? mrq->stop : mrq->cmd; ++ u16 * pu16 = (u16 *)&cmd->resp[0]; ++ u16 * reg_resp = (u16 *)(host->base + GLAMO_REG_MMC_CMD_RSP1); ++ u16 status; ++ int n; ++ int timeout = 1000000; ++ int insanity_timeout = 1000000; ++ ++ if (host->suspending) { ++ dev_err(&host->pdev->dev, "IGNORING glamo_mci_send_request while " ++ "suspended\n"); ++ cmd->error = -EIO; ++ if (cmd->data) ++ cmd->data->error = -EIO; ++ mmc_request_done(mmc, mrq); ++ return; ++ } ++ ++ host->ccnt++; ++ /* ++ * somehow 2.6.24 MCI manages to issue MMC_WRITE_BLOCK *without* the ++ * MMC_DATA_WRITE flag, WTF? Work around the madness. ++ */ ++ if (cmd->opcode == MMC_WRITE_BLOCK) ++ if (mrq->data) ++ mrq->data->flags |= MMC_DATA_WRITE; ++ ++ /* this guy has data to read/write? */ ++ if ((!host->cmd_is_stop) && cmd->data) { ++ int res; ++ host->dcnt++; ++ res = glamo_mci_prepare_pio(host, cmd->data); ++ if (res) { ++ cmd->error = -EIO; ++ cmd->data->error = -EIO; ++ mmc_request_done(mmc, mrq); ++ return; ++ } ++ } ++ ++ dev_dbg(&host->pdev->dev,"cmd 0x%x, " ++ "arg 0x%x data=%p mrq->stop=%p flags 0x%x\n", ++ cmd->opcode, cmd->arg, cmd->data, cmd->mrq->stop, ++ cmd->flags); ++ ++ /* resume requested clock rate ++ * scale it down by sd_slow_ratio if platform requests it ++ */ ++ __glamo_mci_fix_card_div(host, host->clk_div); ++ ++ if (glamo_mci_send_command(host, cmd)) ++ goto bail; ++ ++ /* we are deselecting card? because it isn't going to ack then... */ ++ if ((cmd->opcode == 7) && (cmd->arg == 0)) ++ goto done; ++ ++ /* ++ * we must spin until response is ready or timed out ++ * -- we don't get interrupts unless there is a bulk rx ++ */ ++ do ++ status = readw(host->base + GLAMO_REG_MMC_RB_STAT1); ++ while (((((status >> 15) & 1) != (host->ccnt & 1)) || ++ (!(status & (GLAMO_STAT1_MMC_RB_RRDY | ++ GLAMO_STAT1_MMC_RTOUT | ++ GLAMO_STAT1_MMC_DTOUT | ++ GLAMO_STAT1_MMC_BWERR | ++ GLAMO_STAT1_MMC_BRERR)))) && (insanity_timeout--)); ++ ++ if (insanity_timeout < 0) ++ dev_info(&host->pdev->dev, "command timeout, continuing\n"); ++ ++ if (status & (GLAMO_STAT1_MMC_RTOUT | ++ GLAMO_STAT1_MMC_DTOUT)) ++ cmd->error = -ETIMEDOUT; ++ if (status & (GLAMO_STAT1_MMC_BWERR | ++ GLAMO_STAT1_MMC_BRERR)) ++ cmd->error = -EILSEQ; ++ ++ if (host->cmd_is_stop) ++ goto bail; ++ ++ if (cmd->error) { ++ dev_info(&host->pdev->dev, "Error after cmd: 0x%x\n", status); ++ goto done; ++ } ++ /* ++ * mangle the response registers in two different exciting ++ * undocumented ways discovered by trial and error ++ */ ++ if (mmc_resp_type(cmd) == MMC_RSP_R2) ++ /* grab the response */ ++ for (n = 0; n < 8; n++) /* super mangle power 1 */ ++ pu16[n ^ 6] = readw(®_resp[n]); ++ else ++ for (n = 0; n < 3; n++) /* super mangle power 2 */ ++ pu16[n] = (readw(®_resp[n]) >> 8) | ++ (readw(®_resp[n + 1]) << 8); ++ /* ++ * if we don't have bulk data to take care of, we're done ++ */ ++ if (!cmd->data) ++ goto done; ++ if (!(cmd->data->flags & (MMC_DATA_READ | MMC_DATA_WRITE))) ++ goto done; ++ ++ /* ++ * Otherwise can can use the interrupt as async completion -- ++ * if there is read data coming, or we wait for write data to complete, ++ * exit without mmc_request_done() as the payload interrupt ++ * will service it ++ */ ++ dev_dbg(&host->pdev->dev, "Waiting for payload data\n"); ++ /* ++ * if the glamo INT# line isn't wired (*cough* it can happen) ++ * I'm afraid we have to spin on the IRQ status bit and "be ++ * our own INT# line" ++ */ ++ if (!glamo_mci_def_pdata.pglamo->irq_works) { ++ /* ++ * we have faith we will get an "interrupt"... ++ * but something insane like suspend problems can mean ++ * we spin here forever, so we timeout after a LONG time ++ */ ++ while ((!(readw(glamo_mci_def_pdata.pglamo->base + ++ GLAMO_REG_IRQ_STATUS) & GLAMO_IRQ_MMC)) && ++ (timeout--)) ++ ; ++ ++ if (timeout < 0) { ++ if (cmd->data->error) ++ cmd->data->error = -ETIMEDOUT; ++ dev_err(&host->pdev->dev, "Payload timeout\n"); ++ goto bail; ++ } ++ ++ /* yay we are an interrupt controller! -- call the ISR ++ * it will stop clock to card ++ */ ++ glamo_mci_irq_host(host); ++ } ++ return; ++ ++done: ++ host->complete_what = COMPLETION_NONE; ++ host->mrq = NULL; ++ mmc_request_done(host->mmc, cmd->mrq); ++bail: ++ if (!sd_idleclk && !host->force_slow_during_powerup) ++ /* stop the clock to card */ ++ __glamo_mci_fix_card_div(host, -1); ++} ++ ++static void glamo_mci_request(struct mmc_host *mmc, struct mmc_request *mrq) ++{ ++ struct glamo_mci_host *host = mmc_priv(mmc); ++ ++ host->cmd_is_stop = 0; ++ host->mrq = mrq; ++ glamo_mci_send_request(mmc); ++} ++ ++#if 1 ++static void glamo_mci_reset(struct glamo_mci_host *host) ++{ ++ if (host->suspending) { ++ dev_err(&host->pdev->dev, "IGNORING glamo_mci_reset while " ++ "suspended\n"); ++ return; ++ } ++ dev_dbg(&host->pdev->dev, "******* glamo_mci_reset\n"); ++ /* reset MMC controller */ ++ writew(GLAMO_CLOCK_MMC_RESET | GLAMO_CLOCK_MMC_DG_TCLK | ++ GLAMO_CLOCK_MMC_EN_TCLK | GLAMO_CLOCK_MMC_DG_M9CLK | ++ GLAMO_CLOCK_MMC_EN_M9CLK, ++ glamo_mci_def_pdata.pglamo->base + GLAMO_REG_CLOCK_MMC); ++ udelay(10); ++ /* and disable reset */ ++ writew(GLAMO_CLOCK_MMC_DG_TCLK | ++ GLAMO_CLOCK_MMC_EN_TCLK | GLAMO_CLOCK_MMC_DG_M9CLK | ++ GLAMO_CLOCK_MMC_EN_M9CLK, ++ glamo_mci_def_pdata.pglamo->base + GLAMO_REG_CLOCK_MMC); ++} ++#endif ++static inline int glamo_mci_get_mv(int vdd) ++{ ++ int mv = 1650; ++ ++ if (vdd > 7) ++ mv += 350 + 100 * (vdd - 8); ++ ++ return mv; ++} ++ ++static void glamo_mci_set_ios(struct mmc_host *mmc, struct mmc_ios *ios) ++{ ++ struct glamo_mci_host *host = mmc_priv(mmc); ++ struct regulator *regulator; ++ int n = 0; ++ int div; ++ int powering = 0; ++ int mv; ++ ++ if (host->suspending) { ++ dev_err(&host->pdev->dev, "IGNORING glamo_mci_set_ios while " ++ "suspended\n"); ++ return; ++ } ++ ++ regulator = host->regulator; ++ ++ /* Set power */ ++ switch(ios->power_mode) { ++ case MMC_POWER_UP: ++ if (host->pdata->glamo_can_set_mci_power()) { ++ mv = glamo_mci_get_mv(ios->vdd); ++ regulator_set_voltage(regulator, mv * 1000, mv * 1000); ++ regulator_enable(regulator); ++ } ++ break; ++ case MMC_POWER_ON: ++ /* ++ * we should use very slow clock until first bulk ++ * transfer completes OK ++ */ ++ host->force_slow_during_powerup = 1; ++ ++ if (host->vdd_current != ios->vdd) { ++ if (host->pdata->glamo_can_set_mci_power()) { ++ mv = glamo_mci_get_mv(ios->vdd); ++ regulator_set_voltage(regulator, mv * 1000, mv * 1000); ++ printk(KERN_INFO "SD power -> %dmV\n", mv); ++ } ++ host->vdd_current = ios->vdd; ++ } ++ if (host->power_mode_current == MMC_POWER_OFF) { ++ glamo_engine_enable(glamo_mci_def_pdata.pglamo, ++ GLAMO_ENGINE_MMC); ++ powering = 1; ++ } ++ break; ++ ++ case MMC_POWER_OFF: ++ default: ++ if (host->power_mode_current == MMC_POWER_OFF) ++ break; ++ /* never want clocking with dead card */ ++ __glamo_mci_fix_card_div(host, -1); ++ ++ glamo_engine_disable(glamo_mci_def_pdata.pglamo, ++ GLAMO_ENGINE_MMC); ++ regulator_disable(regulator); ++ host->vdd_current = -1; ++ break; ++ } ++ host->power_mode_current = ios->power_mode; ++ ++ host->real_rate = __glamo_mci_set_card_clock(host, ios->clock, &div); ++ host->clk_div = div; ++ ++ /* after power-up, we are meant to give it >= 74 clocks so it can ++ * initialize itself. Doubt any modern cards need it but anyway... ++ */ ++ if (powering) ++ mdelay(1); ++ ++ if (!sd_idleclk && !host->force_slow_during_powerup) ++ /* stop the clock to card, because we are idle until transfer */ ++ __glamo_mci_fix_card_div(host, -1); ++ ++ if ((ios->power_mode == MMC_POWER_ON) || ++ (ios->power_mode == MMC_POWER_UP)) { ++ dev_info(&host->pdev->dev, ++ "powered (vdd = %d) clk: %lukHz div=%d (req: %ukHz). " ++ "Bus width=%d\n",(int)ios->vdd, ++ host->real_rate / 1000, (int)host->clk_div, ++ ios->clock / 1000, (int)ios->bus_width); ++ } else ++ dev_info(&host->pdev->dev, "glamo_mci_set_ios: power down.\n"); ++ ++ /* set bus width */ ++ host->bus_width = ios->bus_width; ++ if (host->bus_width == MMC_BUS_WIDTH_4) ++ n = GLAMO_BASIC_MMC_EN_4BIT_DATA; ++ writew((readw(host->base + GLAMO_REG_MMC_BASIC) & ++ (~(GLAMO_BASIC_MMC_EN_4BIT_DATA | ++ GLAMO_BASIC_MMC_EN_DR_STR0 | ++ GLAMO_BASIC_MMC_EN_DR_STR1))) | n | ++ sd_drive << 6, host->base + GLAMO_REG_MMC_BASIC); ++} ++ ++ ++/* ++ * no physical write protect supported by us ++ */ ++static int glamo_mci_get_ro(struct mmc_host *mmc) ++{ ++ return 0; ++} ++ ++static struct mmc_host_ops glamo_mci_ops = { ++ .request = glamo_mci_request, ++ .set_ios = glamo_mci_set_ios, ++ .get_ro = glamo_mci_get_ro, ++}; ++ ++static int glamo_mci_probe(struct platform_device *pdev) ++{ ++ struct mmc_host *mmc; ++ struct glamo_mci_host *host; ++ int ret; ++ ++ dev_info(&pdev->dev, "glamo_mci driver (C)2007 Openmoko, Inc\n"); ++ ++ mmc = mmc_alloc_host(sizeof(struct glamo_mci_host), &pdev->dev); ++ if (!mmc) { ++ ret = -ENOMEM; ++ goto probe_out; ++ } ++ ++ host = mmc_priv(mmc); ++ host->mmc = mmc; ++ host->pdev = pdev; ++ host->pdata = &glamo_mci_def_pdata; ++ host->power_mode_current = MMC_POWER_OFF; ++ ++ host->complete_what = COMPLETION_NONE; ++ host->pio_active = XFER_NONE; ++ ++ spin_lock_init(&host->complete_lock); ++ INIT_WORK(&host->irq_work, glamo_mci_irq_worker); ++ ++ host->mem = platform_get_resource(pdev, IORESOURCE_MEM, 0); ++ if (!host->mem) { ++ dev_err(&pdev->dev, ++ "failed to get io memory region resouce.\n"); ++ ++ ret = -ENOENT; ++ goto probe_free_host; ++ } ++ ++ host->mem = request_mem_region(host->mem->start, ++ RESSIZE(host->mem), pdev->name); ++ ++ if (!host->mem) { ++ dev_err(&pdev->dev, "failed to request io memory region.\n"); ++ ret = -ENOENT; ++ goto probe_free_host; ++ } ++ ++ host->base = ioremap(host->mem->start, RESSIZE(host->mem)); ++ if (!host->base) { ++ dev_err(&pdev->dev, "failed to ioremap() io memory region.\n"); ++ ret = -EINVAL; ++ goto probe_free_mem_region; ++ } ++ ++ host->regulator = regulator_get(&pdev->dev, "SD_3V3"); ++ if (!host->regulator) { ++ dev_err(&pdev->dev, "Cannot proceed without regulator.\n"); ++ return -ENODEV; ++ } ++ ++ /* set the handler for our bit of the shared chip irq register */ ++ set_irq_handler(IRQ_GLAMO(GLAMO_IRQIDX_MMC), glamo_mci_irq); ++ /* stash host as our handler's private data */ ++ set_irq_data(IRQ_GLAMO(GLAMO_IRQIDX_MMC), host); ++ ++ /* Get ahold of our data buffer we use for data in and out on MMC */ ++ host->mem_data = platform_get_resource(pdev, IORESOURCE_MEM, 1); ++ if (!host->mem_data) { ++ dev_err(&pdev->dev, ++ "failed to get io memory region resource.\n"); ++ ret = -ENOENT; ++ goto probe_iounmap; ++ } ++ ++ host->mem_data = request_mem_region(host->mem_data->start, ++ RESSIZE(host->mem_data), pdev->name); ++ ++ if (!host->mem_data) { ++ dev_err(&pdev->dev, "failed to request io memory region.\n"); ++ ret = -ENOENT; ++ goto probe_iounmap; ++ } ++ host->base_data = ioremap(host->mem_data->start, ++ RESSIZE(host->mem_data)); ++ host->data_max_size = RESSIZE(host->mem_data); ++ ++ if (host->base_data == 0) { ++ dev_err(&pdev->dev, "failed to ioremap() io memory region.\n"); ++ ret = -EINVAL; ++ goto probe_free_mem_region_data; ++ } ++ ++ host->vdd_current = 0; ++ host->clk_rate = 50000000; /* really it's 49152000 */ ++ host->clk_div = 16; ++ ++ /* explain our host controller capabilities */ ++ mmc->ops = &glamo_mci_ops; ++ mmc->ocr_avail = host->pdata->ocr_avail; ++ mmc->caps = MMC_CAP_4_BIT_DATA | ++ MMC_CAP_MMC_HIGHSPEED | ++ MMC_CAP_SD_HIGHSPEED; ++ mmc->f_min = host->clk_rate / 256; ++ mmc->f_max = sd_max_clk; ++ ++ mmc->max_blk_count = (1 << 16) - 1; /* GLAMO_REG_MMC_RB_BLKCNT */ ++ mmc->max_blk_size = (1 << 12) - 1; /* GLAMO_REG_MMC_RB_BLKLEN */ ++ mmc->max_req_size = RESSIZE(host->mem_data) / 2; ++ mmc->max_seg_size = mmc->max_req_size; ++ mmc->max_phys_segs = 1; /* hw doesn't talk about segs??? */ ++ mmc->max_hw_segs = 1; ++ ++ dev_info(&host->pdev->dev, "probe: mapped mci_base:%p irq:%u.\n", ++ host->base, host->irq); ++ ++ platform_set_drvdata(pdev, mmc); ++ ++ glamo_engine_enable(glamo_mci_def_pdata.pglamo, GLAMO_ENGINE_MMC); ++ glamo_mci_reset(host); ++ ++ if ((ret = mmc_add_host(mmc))) { ++ dev_err(&pdev->dev, "failed to add mmc host.\n"); ++ goto probe_free_mem_region_data; ++ } ++ ++ dev_info(&pdev->dev,"initialisation done.\n"); ++ return 0; ++ ++ probe_free_mem_region_data: ++ release_mem_region(host->mem_data->start, RESSIZE(host->mem_data)); ++ ++ probe_iounmap: ++ iounmap(host->base); ++ ++ probe_free_mem_region: ++ release_mem_region(host->mem->start, RESSIZE(host->mem)); ++ ++ probe_free_host: ++ mmc_free_host(mmc); ++ probe_out: ++ return ret; ++} ++ ++static int glamo_mci_remove(struct platform_device *pdev) ++{ ++ struct mmc_host *mmc = platform_get_drvdata(pdev); ++ struct glamo_mci_host *host = mmc_priv(mmc); ++ struct regulator *regulator; ++ ++ mmc_remove_host(mmc); ++ /* stop using our handler, revert it to default */ ++ set_irq_handler(IRQ_GLAMO(GLAMO_IRQIDX_MMC), handle_level_irq); ++ iounmap(host->base); ++ iounmap(host->base_data); ++ release_mem_region(host->mem->start, RESSIZE(host->mem)); ++ release_mem_region(host->mem_data->start, RESSIZE(host->mem_data)); ++ ++ regulator = host->regulator; ++ regulator_put(regulator); ++ ++ mmc_free_host(mmc); ++ ++ glamo_engine_disable(glamo_mci_def_pdata.pglamo, GLAMO_ENGINE_MMC); ++ return 0; ++} ++ ++ ++#ifdef CONFIG_PM ++ ++static int glamo_mci_suspend(struct platform_device *dev, pm_message_t state) ++{ ++ struct mmc_host *mmc = platform_get_drvdata(dev); ++ struct glamo_mci_host *host = mmc_priv(mmc); ++ int ret; ++ ++ cancel_work_sync(&host->irq_work); ++ ++ /* ++ * possible workaround for SD corruption during suspend - resume ++ * make sure the clock was running during suspend and consequently ++ * resume ++ */ ++ __glamo_mci_fix_card_div(host, host->clk_div); ++ ++ /* we are going to do more commands to override this in ++ * mmc_suspend_host(), so we need to change sd_idleclk for the ++ * duration as well ++ */ ++ suspend_sd_idleclk = sd_idleclk; ++ sd_idleclk = 1; ++ ++ ret = mmc_suspend_host(mmc, state); ++ ++ host->suspending++; ++ /* so that when we resume, we use any modified max rate */ ++ mmc->f_max = sd_max_clk; ++ ++ return ret; ++} ++ ++int glamo_mci_resume(struct platform_device *dev) ++{ ++ struct mmc_host *mmc = platform_get_drvdata(dev); ++ struct glamo_mci_host *host = mmc_priv(mmc); ++ int ret; ++ ++ sd_idleclk = 1; ++ ++ glamo_engine_enable(host->pdata->pglamo, GLAMO_ENGINE_MMC); ++ glamo_mci_reset(host); ++ ++ host->suspending--; ++ ++ ret = mmc_resume_host(mmc); ++ ++ /* put sd_idleclk back to pre-suspend state */ ++ sd_idleclk = suspend_sd_idleclk; ++ ++ return ret; ++} ++EXPORT_SYMBOL_GPL(glamo_mci_resume); ++ ++#else /* CONFIG_PM */ ++#define glamo_mci_suspend NULL ++#define glamo_mci_resume NULL ++#endif /* CONFIG_PM */ ++ ++ ++static struct platform_driver glamo_mci_driver = ++{ ++ .driver.name = "glamo-mci", ++ .probe = glamo_mci_probe, ++ .remove = glamo_mci_remove, ++ .suspend = glamo_mci_suspend, ++ .resume = glamo_mci_resume, ++}; ++ ++static int __init glamo_mci_init(void) ++{ ++ spin_lock_init(&clock_lock); ++ platform_driver_register(&glamo_mci_driver); ++ return 0; ++} ++ ++static void __exit glamo_mci_exit(void) ++{ ++ platform_driver_unregister(&glamo_mci_driver); ++} ++ ++module_init(glamo_mci_init); ++module_exit(glamo_mci_exit); ++ ++MODULE_DESCRIPTION("Glamo MMC/SD Card Interface driver"); ++MODULE_LICENSE("GPL"); ++MODULE_AUTHOR("Andy Green <andy@openmoko.com>"); +diff -ruN --exclude='*.orig' --exclude='*.rej' linux-2.6.29-rc3.owrt/drivers/mfd/glamo/glamo-mci.h linux-2.6.29-rc3.owrt.om/drivers/mfd/glamo/glamo-mci.h +--- linux-2.6.29-rc3.owrt/drivers/mfd/glamo/glamo-mci.h 1970-01-01 01:00:00.000000000 +0100 ++++ linux-2.6.29-rc3.owrt.om/drivers/mfd/glamo/glamo-mci.h 2009-05-10 22:28:00.000000000 +0200 +@@ -0,0 +1,84 @@ ++/* ++ * linux/drivers/mmc/host/glamo-mmc.h - GLAMO MCI driver ++ * ++ * Copyright (C) 2007-2008 Openmoko, Inc, Andy Green <andy@openmoko.com> ++ * based on S3C MMC driver --> ++ * Copyright (C) 2004-2006 Thomas Kleffel, All Rights Reserved. ++ * ++ * 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/regulator/consumer.h> ++ ++enum glamo_mci_waitfor { ++ COMPLETION_NONE, ++ COMPLETION_FINALIZE, ++ COMPLETION_CMDSENT, ++ COMPLETION_RSPFIN, ++ COMPLETION_XFERFINISH, ++ COMPLETION_XFERFINISH_RSPFIN, ++}; ++ ++struct glamo_mci_host { ++ struct platform_device *pdev; ++ struct glamo_mci_pdata *pdata; ++ struct mmc_host *mmc; ++ struct resource *mem; ++ struct resource *mem_data; ++ struct clk *clk; ++ void __iomem *base; ++ u16 __iomem *base_data; ++ int irq; ++ int irq_cd; ++ int dma; ++ int data_max_size; ++ ++ int suspending; ++ ++ int power_mode_current; ++ unsigned int vdd_current; ++ ++ unsigned long clk_rate; ++ unsigned long clk_div; ++ unsigned long real_rate; ++ u8 prescaler; ++ ++ int force_slow_during_powerup; ++ ++ unsigned sdiimsk; ++ int dodma; ++ ++ volatile int dmatogo; ++ ++ struct mmc_request *mrq; ++ int cmd_is_stop; ++ struct work_struct irq_work; ++ ++ spinlock_t complete_lock; ++ volatile enum glamo_mci_waitfor ++ complete_what; ++ ++ volatile int dma_complete; ++ ++ volatile u32 pio_sgptr; ++ volatile u32 pio_words; ++ volatile u32 pio_count; ++ volatile u16 *pio_ptr; ++#define XFER_NONE 0 ++#define XFER_READ 1 ++#define XFER_WRITE 2 ++ volatile u32 pio_active; ++ ++ int bus_width; ++ ++ char dbgmsg_cmd[301]; ++ char dbgmsg_dat[301]; ++ volatile char *status; ++ ++ unsigned int ccnt, dcnt; ++ struct tasklet_struct pio_tasklet; ++ ++ struct regulator *regulator; ++}; +diff -ruN --exclude='*.orig' --exclude='*.rej' linux-2.6.29-rc3.owrt/drivers/mfd/glamo/glamo-regs.h linux-2.6.29-rc3.owrt.om/drivers/mfd/glamo/glamo-regs.h +--- linux-2.6.29-rc3.owrt/drivers/mfd/glamo/glamo-regs.h 1970-01-01 01:00:00.000000000 +0100 ++++ linux-2.6.29-rc3.owrt.om/drivers/mfd/glamo/glamo-regs.h 2009-05-10 22:28:00.000000000 +0200 +@@ -0,0 +1,632 @@ ++#ifndef _GLAMO_REGS_H ++#define _GLAMO_REGS_H ++ ++/* Smedia Glamo 336x/337x driver ++ * ++ * (C) 2007 by Openmoko, Inc. ++ * Author: Harald Welte <laforge@openmoko.org> ++ * All rights reserved. ++ * ++ * 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, ++ * MA 02111-1307 USA ++ */ ++ ++enum glamo_regster_offsets { ++ GLAMO_REGOFS_GENERIC = 0x0000, ++ GLAMO_REGOFS_HOSTBUS = 0x0200, ++ GLAMO_REGOFS_MEMORY = 0x0300, ++ GLAMO_REGOFS_VIDCAP = 0x0400, ++ GLAMO_REGOFS_ISP = 0x0500, ++ GLAMO_REGOFS_JPEG = 0x0800, ++ GLAMO_REGOFS_MPEG = 0x0c00, ++ GLAMO_REGOFS_LCD = 0x1100, ++ GLAMO_REGOFS_MMC = 0x1400, ++ GLAMO_REGOFS_MPROC0 = 0x1500, ++ GLAMO_REGOFS_MPROC1 = 0x1580, ++ GLAMO_REGOFS_CMDQUEUE = 0x1600, ++ GLAMO_REGOFS_RISC = 0x1680, ++ GLAMO_REGOFS_2D = 0x1700, ++ GLAMO_REGOFS_3D = 0x1b00, ++ GLAMO_REGOFS_END = 0x2400, ++}; ++ ++ ++enum glamo_register_generic { ++ GLAMO_REG_GCONF1 = 0x0000, ++ GLAMO_REG_GCONF2 = 0x0002, ++#define GLAMO_REG_DEVICE_ID GLAMO_REG_GCONF2 ++ GLAMO_REG_GCONF3 = 0x0004, ++#define GLAMO_REG_REVISION_ID GLAMO_REG_GCONF3 ++ GLAMO_REG_IRQ_GEN1 = 0x0006, ++#define GLAMO_REG_IRQ_ENABLE GLAMO_REG_IRQ_GEN1 ++ GLAMO_REG_IRQ_GEN2 = 0x0008, ++#define GLAMO_REG_IRQ_SET GLAMO_REG_IRQ_GEN2 ++ GLAMO_REG_IRQ_GEN3 = 0x000a, ++#define GLAMO_REG_IRQ_CLEAR GLAMO_REG_IRQ_GEN3 ++ GLAMO_REG_IRQ_GEN4 = 0x000c, ++#define GLAMO_REG_IRQ_STATUS GLAMO_REG_IRQ_GEN4 ++ GLAMO_REG_CLOCK_HOST = 0x0010, ++ GLAMO_REG_CLOCK_MEMORY = 0x0012, ++ GLAMO_REG_CLOCK_LCD = 0x0014, ++ GLAMO_REG_CLOCK_MMC = 0x0016, ++ GLAMO_REG_CLOCK_ISP = 0x0018, ++ GLAMO_REG_CLOCK_JPEG = 0x001a, ++ GLAMO_REG_CLOCK_3D = 0x001c, ++ GLAMO_REG_CLOCK_2D = 0x001e, ++ GLAMO_REG_CLOCK_RISC1 = 0x0020, /* 3365 only? */ ++ GLAMO_REG_CLOCK_RISC2 = 0x0022, /* 3365 only? */ ++ GLAMO_REG_CLOCK_MPEG = 0x0024, ++ GLAMO_REG_CLOCK_MPROC = 0x0026, ++ ++ GLAMO_REG_CLOCK_GEN5_1 = 0x0030, ++ GLAMO_REG_CLOCK_GEN5_2 = 0x0032, ++ GLAMO_REG_CLOCK_GEN6 = 0x0034, ++ GLAMO_REG_CLOCK_GEN7 = 0x0036, ++ GLAMO_REG_CLOCK_GEN8 = 0x0038, ++ GLAMO_REG_CLOCK_GEN9 = 0x003a, ++ GLAMO_REG_CLOCK_GEN10 = 0x003c, ++ GLAMO_REG_CLOCK_GEN11 = 0x003e, ++ GLAMO_REG_PLL_GEN1 = 0x0040, ++ GLAMO_REG_PLL_GEN2 = 0x0042, ++ GLAMO_REG_PLL_GEN3 = 0x0044, ++ GLAMO_REG_PLL_GEN4 = 0x0046, ++ GLAMO_REG_PLL_GEN5 = 0x0048, ++ GLAMO_REG_GPIO_GEN1 = 0x0050, ++ GLAMO_REG_GPIO_GEN2 = 0x0052, ++ GLAMO_REG_GPIO_GEN3 = 0x0054, ++ GLAMO_REG_GPIO_GEN4 = 0x0056, ++ GLAMO_REG_GPIO_GEN5 = 0x0058, ++ GLAMO_REG_GPIO_GEN6 = 0x005a, ++ GLAMO_REG_GPIO_GEN7 = 0x005c, ++ GLAMO_REG_GPIO_GEN8 = 0x005e, ++ GLAMO_REG_GPIO_GEN9 = 0x0060, ++ GLAMO_REG_GPIO_GEN10 = 0x0062, ++ GLAMO_REG_DFT_GEN1 = 0x0070, ++ GLAMO_REG_DFT_GEN2 = 0x0072, ++ GLAMO_REG_DFT_GEN3 = 0x0074, ++ GLAMO_REG_DFT_GEN4 = 0x0076, ++ ++ GLAMO_REG_DFT_GEN5 = 0x01e0, ++ GLAMO_REG_DFT_GEN6 = 0x01f0, ++}; ++ ++#define GLAMO_REG_HOSTBUS(x) (GLAMO_REGOFS_HOSTBUS-2+(x*2)) ++ ++#define REG_MEM(x) (GLAMO_REGOFS_MEMORY+(x)) ++#define GLAMO_REG_MEM_TIMING(x) (GLAMO_REG_MEM_TIMING1-2+(x*2)) ++ ++enum glamo_register_mem { ++ GLAMO_REG_MEM_TYPE = REG_MEM(0x00), ++ GLAMO_REG_MEM_GEN = REG_MEM(0x02), ++ GLAMO_REG_MEM_TIMING1 = REG_MEM(0x04), ++ GLAMO_REG_MEM_TIMING2 = REG_MEM(0x06), ++ GLAMO_REG_MEM_TIMING3 = REG_MEM(0x08), ++ GLAMO_REG_MEM_TIMING4 = REG_MEM(0x0a), ++ GLAMO_REG_MEM_TIMING5 = REG_MEM(0x0c), ++ GLAMO_REG_MEM_TIMING6 = REG_MEM(0x0e), ++ GLAMO_REG_MEM_TIMING7 = REG_MEM(0x10), ++ GLAMO_REG_MEM_TIMING8 = REG_MEM(0x12), ++ GLAMO_REG_MEM_TIMING9 = REG_MEM(0x14), ++ GLAMO_REG_MEM_TIMING10 = REG_MEM(0x16), ++ GLAMO_REG_MEM_TIMING11 = REG_MEM(0x18), ++ GLAMO_REG_MEM_POWER1 = REG_MEM(0x1a), ++ GLAMO_REG_MEM_POWER2 = REG_MEM(0x1c), ++ GLAMO_REG_MEM_LCD_BUF1 = REG_MEM(0x1e), ++ GLAMO_REG_MEM_LCD_BUF2 = REG_MEM(0x20), ++ GLAMO_REG_MEM_LCD_BUF3 = REG_MEM(0x22), ++ GLAMO_REG_MEM_LCD_BUF4 = REG_MEM(0x24), ++ GLAMO_REG_MEM_BIST1 = REG_MEM(0x26), ++ GLAMO_REG_MEM_BIST2 = REG_MEM(0x28), ++ GLAMO_REG_MEM_BIST3 = REG_MEM(0x2a), ++ GLAMO_REG_MEM_BIST4 = REG_MEM(0x2c), ++ GLAMO_REG_MEM_BIST5 = REG_MEM(0x2e), ++ GLAMO_REG_MEM_MAH1 = REG_MEM(0x30), ++ GLAMO_REG_MEM_MAH2 = REG_MEM(0x32), ++ GLAMO_REG_MEM_DRAM1 = REG_MEM(0x34), ++ GLAMO_REG_MEM_DRAM2 = REG_MEM(0x36), ++ GLAMO_REG_MEM_CRC = REG_MEM(0x38), ++}; ++ ++#define GLAMO_MEM_TYPE_MASK 0x03 ++ ++enum glamo_reg_mem_dram1 { ++ /* b0 - b10 == refresh period, 1 -> 2048 clocks */ ++ GLAMO_MEM_DRAM1_EN_GATE_CLK = (1 << 11), ++ GLAMO_MEM_DRAM1_SELF_REFRESH = (1 << 12), ++ GLAMO_MEM_DRAM1_EN_GATE_CKE = (1 << 13), ++ GLAMO_MEM_DRAM1_EN_DRAM_REFRESH = (1 << 14), ++ GLAMO_MEM_DRAM1_EN_MODEREG_SET = (1 << 15), ++}; ++ ++enum glamo_reg_mem_dram2 { ++ GLAMO_MEM_DRAM2_DEEP_PWRDOWN = (1 << 12), ++}; ++ ++enum glamo_irq_index { ++ GLAMO_IRQIDX_HOSTBUS = 0, ++ GLAMO_IRQIDX_JPEG = 1, ++ GLAMO_IRQIDX_MPEG = 2, ++ GLAMO_IRQIDX_MPROC1 = 3, ++ GLAMO_IRQIDX_MPROC0 = 4, ++ GLAMO_IRQIDX_CMDQUEUE = 5, ++ GLAMO_IRQIDX_2D = 6, ++ GLAMO_IRQIDX_MMC = 7, ++ GLAMO_IRQIDX_RISC = 8, ++}; ++ ++enum glamo_irq { ++ GLAMO_IRQ_HOSTBUS = (1 << GLAMO_IRQIDX_HOSTBUS), ++ GLAMO_IRQ_JPEG = (1 << GLAMO_IRQIDX_JPEG), ++ GLAMO_IRQ_MPEG = (1 << GLAMO_IRQIDX_MPEG), ++ GLAMO_IRQ_MPROC1 = (1 << GLAMO_IRQIDX_MPROC1), ++ GLAMO_IRQ_MPROC0 = (1 << GLAMO_IRQIDX_MPROC0), ++ GLAMO_IRQ_CMDQUEUE = (1 << GLAMO_IRQIDX_CMDQUEUE), ++ GLAMO_IRQ_2D = (1 << GLAMO_IRQIDX_2D), ++ GLAMO_IRQ_MMC = (1 << GLAMO_IRQIDX_MMC), ++ GLAMO_IRQ_RISC = (1 << GLAMO_IRQIDX_RISC), ++}; ++ ++enum glamo_reg_clock_host { ++ GLAMO_CLOCK_HOST_DG_BCLK = 0x0001, ++ GLAMO_CLOCK_HOST_DG_M0CLK = 0x0004, ++ GLAMO_CLOCK_HOST_RESET = 0x1000, ++}; ++ ++enum glamo_reg_clock_mem { ++ GLAMO_CLOCK_MEM_DG_M1CLK = 0x0001, ++ GLAMO_CLOCK_MEM_EN_M1CLK = 0x0002, ++ GLAMO_CLOCK_MEM_DG_MOCACLK = 0x0004, ++ GLAMO_CLOCK_MEM_EN_MOCACLK = 0x0008, ++ GLAMO_CLOCK_MEM_RESET = 0x1000, ++ GLAMO_CLOCK_MOCA_RESET = 0x2000, ++}; ++ ++enum glamo_reg_clock_lcd { ++ GLAMO_CLOCK_LCD_DG_DCLK = 0x0001, ++ GLAMO_CLOCK_LCD_EN_DCLK = 0x0002, ++ GLAMO_CLOCK_LCD_DG_DMCLK = 0x0004, ++ GLAMO_CLOCK_LCD_EN_DMCLK = 0x0008, ++ // ++ GLAMO_CLOCK_LCD_EN_DHCLK = 0x0020, ++ GLAMO_CLOCK_LCD_DG_M5CLK = 0x0040, ++ GLAMO_CLOCK_LCD_EN_M5CLK = 0x0080, ++ GLAMO_CLOCK_LCD_RESET = 0x1000, ++}; ++ ++enum glamo_reg_clock_mmc { ++ GLAMO_CLOCK_MMC_DG_TCLK = 0x0001, ++ GLAMO_CLOCK_MMC_EN_TCLK = 0x0002, ++ GLAMO_CLOCK_MMC_DG_M9CLK = 0x0004, ++ GLAMO_CLOCK_MMC_EN_M9CLK = 0x0008, ++ GLAMO_CLOCK_MMC_RESET = 0x1000, ++}; ++ ++enum glamo_reg_basic_mmc { ++ /* set to disable CRC error rejection */ ++ GLAMO_BASIC_MMC_DISABLE_CRC = 0x0001, ++ /* enable completion interrupt */ ++ GLAMO_BASIC_MMC_EN_COMPL_INT = 0x0002, ++ /* stop MMC clock while enforced idle waiting for data from card */ ++ GLAMO_BASIC_MMC_NO_CLK_RD_WAIT = 0x0004, ++ /* 0 = 1-bit bus to card, 1 = use 4-bit bus (has to be negotiated) */ ++ GLAMO_BASIC_MMC_EN_4BIT_DATA = 0x0008, ++ /* enable 75K pullups on D3..D0 */ ++ GLAMO_BASIC_MMC_EN_DATA_PUPS = 0x0010, ++ /* enable 75K pullup on CMD */ ++ GLAMO_BASIC_MMC_EN_CMD_PUP = 0x0020, ++ /* IO drive strength 00=weak -> 11=strongest */ ++ GLAMO_BASIC_MMC_EN_DR_STR0 = 0x0040, ++ GLAMO_BASIC_MMC_EN_DR_STR1 = 0x0080, ++ /* TCLK delay stage A, 0000 = 500ps --> 1111 = 8ns */ ++ GLAMO_BASIC_MMC_EN_TCLK_DLYA0 = 0x0100, ++ GLAMO_BASIC_MMC_EN_TCLK_DLYA1 = 0x0200, ++ GLAMO_BASIC_MMC_EN_TCLK_DLYA2 = 0x0400, ++ GLAMO_BASIC_MMC_EN_TCLK_DLYA3 = 0x0800, ++ /* TCLK delay stage B (cumulative), 0000 = 500ps --> 1111 = 8ns */ ++ GLAMO_BASIC_MMC_EN_TCLK_DLYB0 = 0x1000, ++ GLAMO_BASIC_MMC_EN_TCLK_DLYB1 = 0x2000, ++ GLAMO_BASIC_MMC_EN_TCLK_DLYB2 = 0x4000, ++ GLAMO_BASIC_MMC_EN_TCLK_DLYB3 = 0x8000, ++}; ++ ++enum glamo_reg_stat1_mmc { ++ /* command "counter" (really: toggle) */ ++ GLAMO_STAT1_MMC_CMD_CTR = 0x8000, ++ /* engine is idle */ ++ GLAMO_STAT1_MMC_IDLE = 0x4000, ++ /* readback response is ready */ ++ GLAMO_STAT1_MMC_RB_RRDY = 0x0200, ++ /* readback data is ready */ ++ GLAMO_STAT1_MMC_RB_DRDY = 0x0100, ++ /* no response timeout */ ++ GLAMO_STAT1_MMC_RTOUT = 0x0020, ++ /* no data timeout */ ++ GLAMO_STAT1_MMC_DTOUT = 0x0010, ++ /* CRC error on block write */ ++ GLAMO_STAT1_MMC_BWERR = 0x0004, ++ /* CRC error on block read */ ++ GLAMO_STAT1_MMC_BRERR = 0x0002 ++}; ++ ++enum glamo_reg_fire_mmc { ++ /* command "counter" (really: toggle) ++ * the STAT1 register reflects this so you can ensure you don't look ++ * at status for previous command ++ */ ++ GLAMO_FIRE_MMC_CMD_CTR = 0x8000, ++ /* sets kind of response expected */ ++ GLAMO_FIRE_MMC_RES_MASK = 0x0700, ++ /* sets command type */ ++ GLAMO_FIRE_MMC_TYP_MASK = 0x00C0, ++ /* sets command class */ ++ GLAMO_FIRE_MMC_CLS_MASK = 0x000F, ++}; ++ ++enum glamo_fire_mmc_response_types { ++ GLAMO_FIRE_MMC_RSPT_R1 = 0x0000, ++ GLAMO_FIRE_MMC_RSPT_R1b = 0x0100, ++ GLAMO_FIRE_MMC_RSPT_R2 = 0x0200, ++ GLAMO_FIRE_MMC_RSPT_R3 = 0x0300, ++ GLAMO_FIRE_MMC_RSPT_R4 = 0x0400, ++ GLAMO_FIRE_MMC_RSPT_R5 = 0x0500, ++}; ++ ++enum glamo_fire_mmc_command_types { ++ /* broadcast, no response */ ++ GLAMO_FIRE_MMC_CMDT_BNR = 0x0000, ++ /* broadcast, with response */ ++ GLAMO_FIRE_MMC_CMDT_BR = 0x0040, ++ /* addressed, no data */ ++ GLAMO_FIRE_MMC_CMDT_AND = 0x0080, ++ /* addressed, with data */ ++ GLAMO_FIRE_MMC_CMDT_AD = 0x00C0, ++}; ++ ++enum glamo_fire_mmc_command_class { ++ /* "Stream Read" */ ++ GLAMO_FIRE_MMC_CC_STRR = 0x0000, ++ /* Single Block Read */ ++ GLAMO_FIRE_MMC_CC_SBR = 0x0001, ++ /* Multiple Block Read With Stop */ ++ GLAMO_FIRE_MMC_CC_MBRS = 0x0002, ++ /* Multiple Block Read No Stop */ ++ GLAMO_FIRE_MMC_CC_MBRNS = 0x0003, ++ /* RESERVED for "Stream Write" */ ++ GLAMO_FIRE_MMC_CC_STRW = 0x0004, ++ /* "Stream Write" */ ++ GLAMO_FIRE_MMC_CC_SBW = 0x0005, ++ /* RESERVED for Multiple Block Write With Stop */ ++ GLAMO_FIRE_MMC_CC_MBWS = 0x0006, ++ /* Multiple Block Write No Stop */ ++ GLAMO_FIRE_MMC_CC_MBWNS = 0x0007, ++ /* STOP command */ ++ GLAMO_FIRE_MMC_CC_STOP = 0x0008, ++ /* Cancel on Running Command */ ++ GLAMO_FIRE_MMC_CC_CANCL = 0x0009, ++ /* "Basic Command" */ ++ GLAMO_FIRE_MMC_CC_BASIC = 0x000a, ++}; ++ ++/* these are offsets from the start of the MMC register region */ ++enum glamo_register_mmc { ++ /* MMC command, b15..8 = cmd arg b7..0; b7..1 = CRC; b0 = end bit */ ++ GLAMO_REG_MMC_CMD_REG1 = 0x00, ++ /* MMC command, b15..0 = cmd arg b23 .. 8 */ ++ GLAMO_REG_MMC_CMD_REG2 = 0x02, ++ /* MMC command, b15=start, b14=transmission, ++ * b13..8=cmd idx, b7..0=cmd arg b31..24 ++ */ ++ GLAMO_REG_MMC_CMD_REG3 = 0x04, ++ GLAMO_REG_MMC_CMD_FIRE = 0x06, ++ GLAMO_REG_MMC_CMD_RSP1 = 0x10, ++ GLAMO_REG_MMC_CMD_RSP2 = 0x12, ++ GLAMO_REG_MMC_CMD_RSP3 = 0x14, ++ GLAMO_REG_MMC_CMD_RSP4 = 0x16, ++ GLAMO_REG_MMC_CMD_RSP5 = 0x18, ++ GLAMO_REG_MMC_CMD_RSP6 = 0x1a, ++ GLAMO_REG_MMC_CMD_RSP7 = 0x1c, ++ GLAMO_REG_MMC_CMD_RSP8 = 0x1e, ++ GLAMO_REG_MMC_RB_STAT1 = 0x20, ++ GLAMO_REG_MMC_RB_BLKCNT = 0x22, ++ GLAMO_REG_MMC_RB_BLKLEN = 0x24, ++ GLAMO_REG_MMC_BASIC = 0x30, ++ GLAMO_REG_MMC_RDATADS1 = 0x34, ++ GLAMO_REG_MMC_RDATADS2 = 0x36, ++ GLAMO_REG_MMC_WDATADS1 = 0x38, ++ GLAMO_REG_MMC_WDATADS2 = 0x3a, ++ GLAMO_REG_MMC_DATBLKCNT = 0x3c, ++ GLAMO_REG_MMC_DATBLKLEN = 0x3e, ++ GLAMO_REG_MMC_TIMEOUT = 0x40, ++ ++}; ++ ++enum glamo_reg_clock_isp { ++ GLAMO_CLOCK_ISP_DG_I1CLK = 0x0001, ++ GLAMO_CLOCK_ISP_EN_I1CLK = 0x0002, ++ GLAMO_CLOCK_ISP_DG_CCLK = 0x0004, ++ GLAMO_CLOCK_ISP_EN_CCLK = 0x0008, ++ // ++ GLAMO_CLOCK_ISP_EN_SCLK = 0x0020, ++ GLAMO_CLOCK_ISP_DG_M2CLK = 0x0040, ++ GLAMO_CLOCK_ISP_EN_M2CLK = 0x0080, ++ GLAMO_CLOCK_ISP_DG_M15CLK = 0x0100, ++ GLAMO_CLOCK_ISP_EN_M15CLK = 0x0200, ++ GLAMO_CLOCK_ISP1_RESET = 0x1000, ++ GLAMO_CLOCK_ISP2_RESET = 0x2000, ++}; ++ ++enum glamo_reg_clock_jpeg { ++ GLAMO_CLOCK_JPEG_DG_JCLK = 0x0001, ++ GLAMO_CLOCK_JPEG_EN_JCLK = 0x0002, ++ GLAMO_CLOCK_JPEG_DG_M3CLK = 0x0004, ++ GLAMO_CLOCK_JPEG_EN_M3CLK = 0x0008, ++ GLAMO_CLOCK_JPEG_RESET = 0x1000, ++}; ++ ++enum glamo_reg_clock_2d { ++ GLAMO_CLOCK_2D_DG_GCLK = 0x0001, ++ GLAMO_CLOCK_2D_EN_GCLK = 0x0002, ++ GLAMO_CLOCK_2D_DG_M7CLK = 0x0004, ++ GLAMO_CLOCK_2D_EN_M7CLK = 0x0008, ++ GLAMO_CLOCK_2D_DG_M6CLK = 0x0010, ++ GLAMO_CLOCK_2D_EN_M6CLK = 0x0020, ++ GLAMO_CLOCK_2D_RESET = 0x1000, ++ GLAMO_CLOCK_2D_CQ_RESET = 0x2000, ++}; ++ ++enum glamo_reg_clock_3d { ++ GLAMO_CLOCK_3D_DG_ECLK = 0x0001, ++ GLAMO_CLOCK_3D_EN_ECLK = 0x0002, ++ GLAMO_CLOCK_3D_DG_RCLK = 0x0004, ++ GLAMO_CLOCK_3D_EN_RCLK = 0x0008, ++ GLAMO_CLOCK_3D_DG_M8CLK = 0x0010, ++ GLAMO_CLOCK_3D_EN_M8CLK = 0x0020, ++ GLAMO_CLOCK_3D_BACK_RESET = 0x1000, ++ GLAMO_CLOCK_3D_FRONT_RESET = 0x2000, ++}; ++ ++enum glamo_reg_clock_mpeg { ++ GLAMO_CLOCK_MPEG_DG_X0CLK = 0x0001, ++ GLAMO_CLOCK_MPEG_EN_X0CLK = 0x0002, ++ GLAMO_CLOCK_MPEG_DG_X1CLK = 0x0004, ++ GLAMO_CLOCK_MPEG_EN_X1CLK = 0x0008, ++ GLAMO_CLOCK_MPEG_DG_X2CLK = 0x0010, ++ GLAMO_CLOCK_MPEG_EN_X2CLK = 0x0020, ++ GLAMO_CLOCK_MPEG_DG_X3CLK = 0x0040, ++ GLAMO_CLOCK_MPEG_EN_X3CLK = 0x0080, ++ GLAMO_CLOCK_MPEG_DG_X4CLK = 0x0100, ++ GLAMO_CLOCK_MPEG_EN_X4CLK = 0x0200, ++ GLAMO_CLOCK_MPEG_DG_X6CLK = 0x0400, ++ GLAMO_CLOCK_MPEG_EN_X6CLK = 0x0800, ++ GLAMO_CLOCK_MPEG_ENC_RESET = 0x1000, ++ GLAMO_CLOCK_MPEG_DEC_RESET = 0x2000, ++}; ++ ++enum glamo_reg_clock51 { ++ GLAMO_CLOCK_GEN51_EN_DIV_MCLK = 0x0001, ++ GLAMO_CLOCK_GEN51_EN_DIV_SCLK = 0x0002, ++ GLAMO_CLOCK_GEN51_EN_DIV_JCLK = 0x0004, ++ GLAMO_CLOCK_GEN51_EN_DIV_DCLK = 0x0008, ++ GLAMO_CLOCK_GEN51_EN_DIV_DMCLK = 0x0010, ++ GLAMO_CLOCK_GEN51_EN_DIV_DHCLK = 0x0020, ++ GLAMO_CLOCK_GEN51_EN_DIV_GCLK = 0x0040, ++ GLAMO_CLOCK_GEN51_EN_DIV_TCLK = 0x0080, ++ /* FIXME: higher bits */ ++}; ++ ++enum glamo_reg_hostbus2 { ++ GLAMO_HOSTBUS2_MMIO_EN_ISP = 0x0001, ++ GLAMO_HOSTBUS2_MMIO_EN_JPEG = 0x0002, ++ GLAMO_HOSTBUS2_MMIO_EN_MPEG = 0x0004, ++ GLAMO_HOSTBUS2_MMIO_EN_LCD = 0x0008, ++ GLAMO_HOSTBUS2_MMIO_EN_MMC = 0x0010, ++ GLAMO_HOSTBUS2_MMIO_EN_MICROP0 = 0x0020, ++ GLAMO_HOSTBUS2_MMIO_EN_MICROP1 = 0x0040, ++ GLAMO_HOSTBUS2_MMIO_EN_CQ = 0x0080, ++ GLAMO_HOSTBUS2_MMIO_EN_RISC = 0x0100, ++ GLAMO_HOSTBUS2_MMIO_EN_2D = 0x0200, ++ GLAMO_HOSTBUS2_MMIO_EN_3D = 0x0400, ++}; ++ ++/* LCD Controller */ ++ ++#define REG_LCD(x) (x) ++enum glamo_reg_lcd { ++ GLAMO_REG_LCD_MODE1 = REG_LCD(0x00), ++ GLAMO_REG_LCD_MODE2 = REG_LCD(0x02), ++ GLAMO_REG_LCD_MODE3 = REG_LCD(0x04), ++ GLAMO_REG_LCD_WIDTH = REG_LCD(0x06), ++ GLAMO_REG_LCD_HEIGHT = REG_LCD(0x08), ++ GLAMO_REG_LCD_POLARITY = REG_LCD(0x0a), ++ GLAMO_REG_LCD_A_BASE1 = REG_LCD(0x0c), ++ GLAMO_REG_LCD_A_BASE2 = REG_LCD(0x0e), ++ GLAMO_REG_LCD_B_BASE1 = REG_LCD(0x10), ++ GLAMO_REG_LCD_B_BASE2 = REG_LCD(0x12), ++ GLAMO_REG_LCD_C_BASE1 = REG_LCD(0x14), ++ GLAMO_REG_LCD_C_BASE2 = REG_LCD(0x16), ++ GLAMO_REG_LCD_PITCH = REG_LCD(0x18), ++ /* RES */ ++ GLAMO_REG_LCD_HORIZ_TOTAL = REG_LCD(0x1c), ++ /* RES */ ++ GLAMO_REG_LCD_HORIZ_RETR_START = REG_LCD(0x20), ++ /* RES */ ++ GLAMO_REG_LCD_HORIZ_RETR_END = REG_LCD(0x24), ++ /* RES */ ++ GLAMO_REG_LCD_HORIZ_DISP_START = REG_LCD(0x28), ++ /* RES */ ++ GLAMO_REG_LCD_HORIZ_DISP_END = REG_LCD(0x2c), ++ /* RES */ ++ GLAMO_REG_LCD_VERT_TOTAL = REG_LCD(0x30), ++ /* RES */ ++ GLAMO_REG_LCD_VERT_RETR_START = REG_LCD(0x34), ++ /* RES */ ++ GLAMO_REG_LCD_VERT_RETR_END = REG_LCD(0x38), ++ /* RES */ ++ GLAMO_REG_LCD_VERT_DISP_START = REG_LCD(0x3c), ++ /* RES */ ++ GLAMO_REG_LCD_VERT_DISP_END = REG_LCD(0x40), ++ /* RES */ ++ GLAMO_REG_LCD_POL = REG_LCD(0x44), ++ GLAMO_REG_LCD_DATA_START = REG_LCD(0x46), ++ GLAMO_REG_LCD_FRATE_CONTRO = REG_LCD(0x48), ++ GLAMO_REG_LCD_DATA_CMD_HDR = REG_LCD(0x4a), ++ GLAMO_REG_LCD_SP_START = REG_LCD(0x4c), ++ GLAMO_REG_LCD_SP_END = REG_LCD(0x4e), ++ GLAMO_REG_LCD_CURSOR_BASE1 = REG_LCD(0x50), ++ GLAMO_REG_LCD_CURSOR_BASE2 = REG_LCD(0x52), ++ GLAMO_REG_LCD_CURSOR_PITCH = REG_LCD(0x54), ++ GLAMO_REG_LCD_CURSOR_X_SIZE = REG_LCD(0x56), ++ GLAMO_REG_LCD_CURSOR_Y_SIZE = REG_LCD(0x58), ++ GLAMO_REG_LCD_CURSOR_X_POS = REG_LCD(0x5a), ++ GLAMO_REG_LCD_CURSOR_Y_POS = REG_LCD(0x5c), ++ GLAMO_REG_LCD_CURSOR_PRESET = REG_LCD(0x5e), ++ GLAMO_REG_LCD_CURSOR_FG_COLOR = REG_LCD(0x60), ++ /* RES */ ++ GLAMO_REG_LCD_CURSOR_BG_COLOR = REG_LCD(0x64), ++ /* RES */ ++ GLAMO_REG_LCD_CURSOR_DST_COLOR = REG_LCD(0x68), ++ /* RES */ ++ GLAMO_REG_LCD_STATUS1 = REG_LCD(0x80), ++ GLAMO_REG_LCD_STATUS2 = REG_LCD(0x82), ++ GLAMO_REG_LCD_STATUS3 = REG_LCD(0x84), ++ GLAMO_REG_LCD_STATUS4 = REG_LCD(0x86), ++ /* RES */ ++ GLAMO_REG_LCD_COMMAND1 = REG_LCD(0xa0), ++ GLAMO_REG_LCD_COMMAND2 = REG_LCD(0xa2), ++ /* RES */ ++ GLAMO_REG_LCD_WFORM_DELAY1 = REG_LCD(0xb0), ++ GLAMO_REG_LCD_WFORM_DELAY2 = REG_LCD(0xb2), ++ /* RES */ ++ GLAMO_REG_LCD_GAMMA_CORR = REG_LCD(0x100), ++ /* RES */ ++ GLAMO_REG_LCD_GAMMA_R_ENTRY01 = REG_LCD(0x110), ++ GLAMO_REG_LCD_GAMMA_R_ENTRY23 = REG_LCD(0x112), ++ GLAMO_REG_LCD_GAMMA_R_ENTRY45 = REG_LCD(0x114), ++ GLAMO_REG_LCD_GAMMA_R_ENTRY67 = REG_LCD(0x116), ++ GLAMO_REG_LCD_GAMMA_R_ENTRY8 = REG_LCD(0x118), ++ /* RES */ ++ GLAMO_REG_LCD_GAMMA_G_ENTRY01 = REG_LCD(0x130), ++ GLAMO_REG_LCD_GAMMA_G_ENTRY23 = REG_LCD(0x132), ++ GLAMO_REG_LCD_GAMMA_G_ENTRY45 = REG_LCD(0x134), ++ GLAMO_REG_LCD_GAMMA_G_ENTRY67 = REG_LCD(0x136), ++ GLAMO_REG_LCD_GAMMA_G_ENTRY8 = REG_LCD(0x138), ++ /* RES */ ++ GLAMO_REG_LCD_GAMMA_B_ENTRY01 = REG_LCD(0x150), ++ GLAMO_REG_LCD_GAMMA_B_ENTRY23 = REG_LCD(0x152), ++ GLAMO_REG_LCD_GAMMA_B_ENTRY45 = REG_LCD(0x154), ++ GLAMO_REG_LCD_GAMMA_B_ENTRY67 = REG_LCD(0x156), ++ GLAMO_REG_LCD_GAMMA_B_ENTRY8 = REG_LCD(0x158), ++ /* RES */ ++ GLAMO_REG_LCD_SRAM_DRIVING1 = REG_LCD(0x160), ++ GLAMO_REG_LCD_SRAM_DRIVING2 = REG_LCD(0x162), ++ GLAMO_REG_LCD_SRAM_DRIVING3 = REG_LCD(0x164), ++}; ++ ++enum glamo_reg_lcd_mode1 { ++ GLAMO_LCD_MODE1_PWRSAVE = 0x0001, ++ GLAMO_LCD_MODE1_PARTIAL_PRT = 0x0002, ++ GLAMO_LCD_MODE1_HWFLIP = 0x0004, ++ GLAMO_LCD_MODE1_LCD2 = 0x0008, ++ /* RES */ ++ GLAMO_LCD_MODE1_PARTIAL_MODE = 0x0020, ++ GLAMO_LCD_MODE1_CURSOR_DSTCOLOR = 0x0040, ++ GLAMO_LCD_MODE1_PARTIAL_ENABLE = 0x0080, ++ GLAMO_LCD_MODE1_TVCLK_IN_ENABLE = 0x0100, ++ GLAMO_LCD_MODE1_HSYNC_HIGH_ACT = 0x0200, ++ GLAMO_LCD_MODE1_VSYNC_HIGH_ACT = 0x0400, ++ GLAMO_LCD_MODE1_HSYNC_FLIP = 0x0800, ++ GLAMO_LCD_MODE1_GAMMA_COR_EN = 0x1000, ++ GLAMO_LCD_MODE1_DITHER_EN = 0x2000, ++ GLAMO_LCD_MODE1_CURSOR_EN = 0x4000, ++ GLAMO_LCD_MODE1_ROTATE_EN = 0x8000, ++}; ++ ++enum glamo_reg_lcd_mode2 { ++ GLAMO_LCD_MODE2_CRC_CHECK_EN = 0x0001, ++ GLAMO_LCD_MODE2_DCMD_PER_LINE = 0x0002, ++ GLAMO_LCD_MODE2_NOUSE_BDEF = 0x0004, ++ GLAMO_LCD_MODE2_OUT_POS_MODE = 0x0008, ++ GLAMO_LCD_MODE2_FRATE_CTRL_EN = 0x0010, ++ GLAMO_LCD_MODE2_SINGLE_BUFFER = 0x0020, ++ GLAMO_LCD_MODE2_SER_LSB_TO_MSB = 0x0040, ++ /* FIXME */ ++}; ++ ++enum glamo_reg_lcd_mode3 { ++ /* LCD color source data format */ ++ GLAMO_LCD_SRC_RGB565 = 0x0000, ++ GLAMO_LCD_SRC_ARGB1555 = 0x4000, ++ GLAMO_LCD_SRC_ARGB4444 = 0x8000, ++ /* interface type */ ++ GLAMO_LCD_MODE3_LCD = 0x1000, ++ GLAMO_LCD_MODE3_RGB = 0x0800, ++ GLAMO_LCD_MODE3_CPU = 0x0000, ++ /* mode */ ++ GLAMO_LCD_MODE3_RGB332 = 0x0000, ++ GLAMO_LCD_MODE3_RGB444 = 0x0100, ++ GLAMO_LCD_MODE3_RGB565 = 0x0200, ++ GLAMO_LCD_MODE3_RGB666 = 0x0300, ++ /* depth */ ++ GLAMO_LCD_MODE3_6BITS = 0x0000, ++ GLAMO_LCD_MODE3_8BITS = 0x0010, ++ GLAMO_LCD_MODE3_9BITS = 0x0020, ++ GLAMO_LCD_MODE3_16BITS = 0x0030, ++ GLAMO_LCD_MODE3_18BITS = 0x0040, ++}; ++ ++enum glamo_lcd_rot_mode { ++ GLAMO_LCD_ROT_MODE_0 = 0x0000, ++ GLAMO_LCD_ROT_MODE_180 = 0x2000, ++ GLAMO_LCD_ROT_MODE_MIRROR = 0x4000, ++ GLAMO_LCD_ROT_MODE_FLIP = 0x6000, ++ GLAMO_LCD_ROT_MODE_90 = 0x8000, ++ GLAMO_LCD_ROT_MODE_270 = 0xa000, ++}; ++#define GLAMO_LCD_ROT_MODE_MASK 0xe000 ++ ++enum glamo_lcd_cmd_type { ++ GLAMO_LCD_CMD_TYPE_DISP = 0x0000, ++ GLAMO_LCD_CMD_TYPE_PARALLEL = 0x4000, ++ GLAMO_LCD_CMD_TYPE_SERIAL = 0x8000, ++ GLAMO_LCD_CMD_TYPE_SERIAL_DIRECT= 0xc000, ++}; ++#define GLAMO_LCD_CMD_TYPE_MASK 0xc000 ++ ++enum glamo_lcd_cmds { ++ GLAMO_LCD_CMD_DATA_DISP_FIRE = 0x00, ++ GLAMO_LCD_CMD_DATA_DISP_SYNC = 0x01, /* RGB only */ ++ /* switch to command mode, no display */ ++ GLAMO_LCD_CMD_DATA_FIRE_NO_DISP = 0x02, ++ /* display until VSYNC, switch to command */ ++ GLAMO_LCD_CMD_DATA_FIRE_VSYNC = 0x11, ++ /* display until HSYNC, switch to command */ ++ GLAMO_LCD_CMD_DATA_FIRE_HSYNC = 0x12, ++ /* display until VSYNC, 1 black frame, VSYNC, switch to command */ ++ GLAMO_LCD_CMD_DATA_FIRE_VSYNC_B = 0x13, ++ /* don't care about display and switch to command */ ++ GLAMO_LCD_CMD_DATA_FIRE_FREE = 0x14, /* RGB only */ ++ /* don't care about display, keep data display but disable data, ++ * and switch to command */ ++ GLAMO_LCD_CMD_DATA_FIRE_FREE_D = 0x15, /* RGB only */ ++}; ++ ++enum glamo_core_revisions { ++ GLAMO_CORE_REV_A0 = 0x0000, ++ GLAMO_CORE_REV_A1 = 0x0001, ++ GLAMO_CORE_REV_A2 = 0x0002, ++ GLAMO_CORE_REV_A3 = 0x0003, ++}; ++ ++#endif /* _GLAMO_REGS_H */ +diff -ruN --exclude='*.orig' --exclude='*.rej' linux-2.6.29-rc3.owrt/drivers/mfd/glamo/glamo-spi-gpio.c linux-2.6.29-rc3.owrt.om/drivers/mfd/glamo/glamo-spi-gpio.c +--- linux-2.6.29-rc3.owrt/drivers/mfd/glamo/glamo-spi-gpio.c 1970-01-01 01:00:00.000000000 +0100 ++++ linux-2.6.29-rc3.owrt.om/drivers/mfd/glamo/glamo-spi-gpio.c 2009-05-10 22:28:00.000000000 +0200 +@@ -0,0 +1,278 @@ ++/* ++ * Copyright (C) 2007 Openmoko, Inc. ++ * Author: Harald Welte <laforge@openmoko.org> ++ * ++ * Smedia Glamo GPIO based SPI driver ++ * ++ * 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. ++ * ++ * This driver currently only implements a minimum subset of the hardware ++ * features, esp. those features that are required to drive the jbt6k74 ++ * LCM controller asic in the TD028TTEC1 LCM. ++ * ++*/ ++ ++#define DEBUG ++ ++#include <linux/kernel.h> ++#include <linux/init.h> ++#include <linux/delay.h> ++#include <linux/device.h> ++#include <linux/spinlock.h> ++#include <linux/workqueue.h> ++#include <linux/platform_device.h> ++ ++#include <linux/spi/spi.h> ++#include <linux/spi/spi_bitbang.h> ++#include <linux/spi/glamo.h> ++ ++#include <linux/glamofb.h> ++ ++#include <mach/hardware.h> ++ ++#include "glamo-core.h" ++#include "glamo-regs.h" ++ ++struct glamo_spigpio { ++ struct spi_bitbang bitbang; ++ struct spi_master *master; ++ struct glamo_spigpio_info *info; ++ struct glamo_core *glamo; ++}; ++ ++static inline struct glamo_spigpio *to_sg(struct spi_device *spi) ++{ ++ return dev_get_drvdata(&spi->master->dev); ++} ++ ++static inline void setsck(struct spi_device *dev, int on) ++{ ++ struct glamo_spigpio *sg = to_sg(dev); ++ glamo_gpio_setpin(sg->glamo, sg->info->pin_clk, on ? 1 : 0); ++} ++ ++static inline void setmosi(struct spi_device *dev, int on) ++{ ++ struct glamo_spigpio *sg = to_sg(dev); ++ glamo_gpio_setpin(sg->glamo, sg->info->pin_mosi, on ? 1 : 0); ++} ++ ++static inline u32 getmiso(struct spi_device *dev) ++{ ++ struct glamo_spigpio *sg = to_sg(dev); ++ if (sg->info->pin_miso) ++ return glamo_gpio_getpin(sg->glamo, sg->info->pin_miso) ? 1 : 0; ++ else ++ return 0; ++} ++ ++#define spidelay(x) ndelay(x) ++ ++#define EXPAND_BITBANG_TXRX ++#include <linux/spi/spi_bitbang.h> ++ ++static u32 glamo_spigpio_txrx_mode0(struct spi_device *spi, ++ unsigned nsecs, u32 word, u8 bits) ++{ ++ return bitbang_txrx_be_cpha0(spi, nsecs, 0, word, bits); ++} ++ ++static u32 glamo_spigpio_txrx_mode1(struct spi_device *spi, ++ unsigned nsecs, u32 word, u8 bits) ++{ ++ return bitbang_txrx_be_cpha1(spi, nsecs, 0, word, bits); ++} ++ ++static u32 glamo_spigpio_txrx_mode2(struct spi_device *spi, ++ unsigned nsecs, u32 word, u8 bits) ++{ ++ return bitbang_txrx_be_cpha0(spi, nsecs, 1, word, bits); ++} ++ ++static u32 glamo_spigpio_txrx_mode3(struct spi_device *spi, ++ unsigned nsecs, u32 word, u8 bits) ++{ ++ return bitbang_txrx_be_cpha1(spi, nsecs, 1, word, bits); ++} ++ ++ ++#if 0 ++static int glamo_spigpio_setupxfer(struct spi_device *spi, ++ struct spi_transfer *t) ++{ ++ struct glamo_spi *gs = to_sg(spi); ++ unsigned int bpw; ++ ++ bpw = t ? t->bits_per_word : spi->bits_per_word; ++ ++ if (bpw != 9 && bpw != 8) { ++ dev_err(&spi->dev, "invalid bits-per-word (%d)\n", bpw); ++ return -EINVAL; ++ } ++ ++ return 0; ++} ++#endif ++ ++static void glamo_spigpio_chipsel(struct spi_device *spi, int value) ++{ ++ struct glamo_spigpio *gs = to_sg(spi); ++#if 0 ++ dev_dbg(&spi->dev, "chipsel %d: spi=%p, gs=%p, info=%p, handle=%p\n", ++ value, spi, gs, gs->info, gs->info->glamo); ++#endif ++ glamo_gpio_setpin(gs->glamo, gs->info->pin_cs, value ? 0 : 1); ++} ++ ++ ++static int glamo_spigpio_probe(struct platform_device *pdev) ++{ ++ struct spi_master *master; ++ struct glamo_spigpio *sp; ++ int ret; ++ ++ master = spi_alloc_master(&pdev->dev, sizeof(struct glamo_spigpio)); ++ if (master == NULL) { ++ dev_err(&pdev->dev, "failed to allocate spi master\n"); ++ ret = -ENOMEM; ++ goto err; ++ } ++ ++ sp = spi_master_get_devdata(master); ++ platform_set_drvdata(pdev, sp); ++ sp->info = pdev->dev.platform_data; ++ if (!sp->info) { ++ dev_err(&pdev->dev, "can't operate without platform data\n"); ++ ret = -EIO; ++ goto err_no_pdev; ++ } ++ ++ master->num_chipselect = 1; ++ master->bus_num = 2; /* FIXME: use dynamic number */ ++ ++ sp->master = spi_master_get(master); ++ sp->glamo = sp->info->glamo; ++ ++ sp->bitbang.master = sp->master; ++ sp->bitbang.chipselect = glamo_spigpio_chipsel; ++ sp->bitbang.txrx_word[SPI_MODE_0] = glamo_spigpio_txrx_mode0; ++ sp->bitbang.txrx_word[SPI_MODE_1] = glamo_spigpio_txrx_mode1; ++ sp->bitbang.txrx_word[SPI_MODE_2] = glamo_spigpio_txrx_mode2; ++ sp->bitbang.txrx_word[SPI_MODE_3] = glamo_spigpio_txrx_mode3; ++ ++ /* set state of spi pins */ ++ glamo_gpio_setpin(sp->glamo, sp->info->pin_clk, 0); ++ glamo_gpio_setpin(sp->glamo, sp->info->pin_mosi, 0); ++ glamo_gpio_setpin(sp->glamo, sp->info->pin_cs, 1); ++ ++ glamo_gpio_cfgpin(sp->glamo, sp->info->pin_clk); ++ glamo_gpio_cfgpin(sp->glamo, sp->info->pin_mosi); ++ glamo_gpio_cfgpin(sp->glamo, sp->info->pin_cs); ++ if (sp->info->pin_miso) ++ glamo_gpio_cfgpin(sp->glamo, sp->info->pin_miso); ++ ++ /* bring the LCM panel out of reset if it isn't already */ ++ ++ glamo_gpio_setpin(sp->glamo, GLAMO_GPIO4, 1); ++ glamo_gpio_cfgpin(sp->glamo, GLAMO_GPIO4_OUTPUT); ++ msleep(90); ++ ++#if 0 ++ sp->dev = &pdev->dev; ++ ++ sp->bitbang.setup_transfer = glamo_spi_setupxfer; ++ sp->bitbang.txrx_bufs = glamo_spi_txrx; ++ sp->bitbang.master->setup = glamo_spi_setup; ++#endif ++ ++ dev_set_drvdata(&sp->master->dev, sp); ++ ++ ret = spi_bitbang_start(&sp->bitbang); ++ if (ret) ++ goto err_no_bitbang; ++ ++ return 0; ++ ++err_no_bitbang: ++ platform_set_drvdata(pdev, NULL); ++err_no_pdev: ++ spi_master_put(sp->bitbang.master); ++err: ++ return ret; ++ ++} ++ ++static int glamo_spigpio_remove(struct platform_device *pdev) ++{ ++ struct glamo_spigpio *sp = platform_get_drvdata(pdev); ++ ++ spi_bitbang_stop(&sp->bitbang); ++ spi_master_put(sp->bitbang.master); ++ ++ return 0; ++} ++ ++/*#define glamo_spigpio_suspend NULL ++#define glamo_spigpio_resume NULL ++*/ ++ ++ ++#ifdef CONFIG_PM ++static int glamo_spigpio_suspend(struct platform_device *pdev, pm_message_t state) ++{ ++ return 0; ++} ++ ++static int glamo_spigpio_resume(struct platform_device *pdev) ++{ ++ struct glamo_spigpio *sp = platform_get_drvdata(pdev); ++ ++ if (!sp) ++ return 0; ++ ++ /* set state of spi pins */ ++ glamo_gpio_setpin(sp->glamo, sp->info->pin_clk, 0); ++ glamo_gpio_setpin(sp->glamo, sp->info->pin_mosi, 0); ++ glamo_gpio_setpin(sp->glamo, sp->info->pin_cs, 1); ++ ++ glamo_gpio_cfgpin(sp->glamo, sp->info->pin_clk); ++ glamo_gpio_cfgpin(sp->glamo, sp->info->pin_mosi); ++ glamo_gpio_cfgpin(sp->glamo, sp->info->pin_cs); ++ if (sp->info->pin_miso) ++ glamo_gpio_cfgpin(sp->glamo, sp->info->pin_miso); ++ ++ return 0; ++} ++#endif ++ ++static struct platform_driver glamo_spi_drv = { ++ .probe = glamo_spigpio_probe, ++ .remove = glamo_spigpio_remove, ++#ifdef CONFIG_PM ++ .suspend_late = glamo_spigpio_suspend, ++ .resume_early = glamo_spigpio_resume, ++#endif ++ .driver = { ++ .name = "glamo-spi-gpio", ++ .owner = THIS_MODULE, ++ }, ++}; ++ ++static int __init glamo_spi_init(void) ++{ ++ return platform_driver_register(&glamo_spi_drv); ++} ++ ++static void __exit glamo_spi_exit(void) ++{ ++ platform_driver_unregister(&glamo_spi_drv); ++} ++ ++module_init(glamo_spi_init); ++module_exit(glamo_spi_exit); ++ ++MODULE_DESCRIPTION("Smedia Glamo 336x/337x LCM serial command SPI Driver"); ++MODULE_AUTHOR("Harald Welte <laforge@openmoko.org>") ++MODULE_LICENSE("GPL"); +diff -ruN --exclude='*.orig' --exclude='*.rej' linux-2.6.29-rc3.owrt/drivers/mfd/glamo/Kconfig linux-2.6.29-rc3.owrt.om/drivers/mfd/glamo/Kconfig +--- linux-2.6.29-rc3.owrt/drivers/mfd/glamo/Kconfig 1970-01-01 01:00:00.000000000 +0100 ++++ linux-2.6.29-rc3.owrt.om/drivers/mfd/glamo/Kconfig 2009-05-10 22:28:00.000000000 +0200 +@@ -0,0 +1,57 @@ ++config MFD_GLAMO ++ bool "Smedia Glamo 336x/337x support" ++ help ++ This enables the core driver for the Smedia Glamo 336x/337x ++ multi-function device. It includes irq_chip demultiplex as ++ well as clock / power management and GPIO support. ++ ++config MFD_GLAMO_FB ++ tristate "Smedia Glamo 336x/337x framebuffer support" ++ depends on FB && MFD_GLAMO ++ select FB_CFB_FILLRECT ++ select FB_CFB_COPYAREA ++ select FB_CFB_IMAGEBLIT ++ help ++ Frame buffer driver for the LCD controller in the Smedia Glamo ++ 336x/337x. ++ ++ This driver is also available as a module ( = code which can be ++ inserted and removed from the running kernel whenever you want). The ++ module will be called glamofb. If you want to compile it as a module, ++ say M here and read <file:Documentation/modules.txt>. ++ ++ If unsure, say N. ++ ++config MFD_GLAMO_FB_XGLAMO_WORKAROUND ++ bool "Smedia Glamo 336x/337x Xglamo rotation workaround" ++ depends on MFD_GLAMO_FB ++ help ++ This is a workaround for a Xglamo bug. This should be fixed ++ in Xglamo and not in kernel space. ++ ++ If unsure, say N. ++ ++ ++config MFD_GLAMO_SPI_GPIO ++ tristate "Glamo GPIO SPI bitbang support" ++ depends on MFD_GLAMO ++ help ++ Enable a bitbanging SPI adapter driver for the Smedia Glamo. ++ ++config MFD_GLAMO_SPI_FB ++ tristate "Glamo LCM control channel SPI support" ++ depends on MFD_GLAMO_FB ++ help ++ Enable a bitbanging SPI adapter driver for the Smedia Glamo LCM ++ control channel. This SPI interface is frequently used to ++ interconnect the LCM control interface. ++ ++config MFD_GLAMO_MCI ++ tristate "Glamo S3C SD/MMC Card Interface support" ++ depends on MFD_GLAMO && MMC ++ help ++ This selects a driver for the MCI interface found in ++ the S-Media GLAMO chip, as used in Openmoko ++ neo1973 GTA-02. ++ ++ If unsure, say N. +diff -ruN --exclude='*.orig' --exclude='*.rej' linux-2.6.29-rc3.owrt/drivers/mfd/glamo/Makefile linux-2.6.29-rc3.owrt.om/drivers/mfd/glamo/Makefile +--- linux-2.6.29-rc3.owrt/drivers/mfd/glamo/Makefile 1970-01-01 01:00:00.000000000 +0100 ++++ linux-2.6.29-rc3.owrt.om/drivers/mfd/glamo/Makefile 2009-05-10 22:28:00.000000000 +0200 +@@ -0,0 +1,12 @@ ++# ++# Makefile for the Smedia Glamo framebuffer driver ++# ++ ++obj-$(CONFIG_MFD_GLAMO) += glamo-core.o glamo-gpio.o ++obj-$(CONFIG_MFD_GLAMO_SPI) += glamo-spi.o ++obj-$(CONFIG_MFD_GLAMO_SPI_GPIO) += glamo-spi-gpio.o ++ ++obj-$(CONFIG_MFD_GLAMO_FB) += glamo-fb.o ++obj-$(CONFIG_MFD_GLAMO_SPI_FB) += glamo-lcm-spi.o ++obj-$(CONFIG_MFD_GLAMO_MCI) += glamo-mci.o ++ +diff -ruN --exclude='*.orig' --exclude='*.rej' linux-2.6.29-rc3.owrt/drivers/mfd/Kconfig linux-2.6.29-rc3.owrt.om/drivers/mfd/Kconfig +--- linux-2.6.29-rc3.owrt/drivers/mfd/Kconfig 2009-05-10 22:04:49.000000000 +0200 ++++ linux-2.6.29-rc3.owrt.om/drivers/mfd/Kconfig 2009-05-10 22:28:00.000000000 +0200 +@@ -240,6 +240,33 @@ + Say yes here if you want to include support GPIO for pins on + the PCF50633 chip. + ++ ++config MFD_PCF50606 ++ tristate "Support for NXP PCF50606" ++ depends on I2C ++ help ++ Say yes here if you have NXP PCF50606 chip on your board. ++ This core driver provides register access and IRQ handling ++ facilities, and registers devices for the various functions ++ so that function-specific drivers can bind to them. ++ ++config PCF50606_ADC ++ tristate "Support for NXP PCF50606 ADC" ++ depends on MFD_PCF50606 ++ help ++ Say yes here if you want to include support for ADC in the ++ NXP PCF50606 chip. ++ ++config PCF50606_GPO ++ tristate "Support for NXP PCF50606 GPO" ++ depends on MFD_PCF50606 ++ help ++ Say yes here if you want to include support GPO for pins on ++ the PCF50606 chip. ++ ++ ++source "drivers/mfd/glamo/Kconfig" ++ + endmenu + + menu "Multimedia Capabilities Port drivers" +diff -ruN --exclude='*.orig' --exclude='*.rej' linux-2.6.29-rc3.owrt/drivers/mfd/Makefile linux-2.6.29-rc3.owrt.om/drivers/mfd/Makefile +--- linux-2.6.29-rc3.owrt/drivers/mfd/Makefile 2009-05-10 22:04:49.000000000 +0200 ++++ linux-2.6.29-rc3.owrt.om/drivers/mfd/Makefile 2009-05-10 22:28:00.000000000 +0200 +@@ -4,6 +4,7 @@ + + obj-$(CONFIG_MFD_SM501) += sm501.o + obj-$(CONFIG_MFD_ASIC3) += asic3.o ++obj-$(CONFIG_MFD_GLAMO) += glamo/ + + obj-$(CONFIG_HTC_EGPIO) += htc-egpio.o + obj-$(CONFIG_HTC_PASIC3) += htc-pasic3.o +@@ -40,4 +41,8 @@ + + obj-$(CONFIG_MFD_PCF50633) += pcf50633-core.o + obj-$(CONFIG_PCF50633_ADC) += pcf50633-adc.o +-obj-$(CONFIG_PCF50633_GPIO) += pcf50633-gpio.o +\ No newline at end of file ++obj-$(CONFIG_PCF50633_GPIO) += pcf50633-gpio.o ++ ++obj-$(CONFIG_MFD_PCF50606) += pcf50606-core.o ++obj-$(CONFIG_PCF50606_ADC) += pcf50606-adc.o ++obj-$(CONFIG_PCF50606_GPO) += pcf50606-gpo.o +diff -ruN --exclude='*.orig' --exclude='*.rej' linux-2.6.29-rc3.owrt/drivers/mfd/pcf50606-adc.c linux-2.6.29-rc3.owrt.om/drivers/mfd/pcf50606-adc.c +--- linux-2.6.29-rc3.owrt/drivers/mfd/pcf50606-adc.c 1970-01-01 01:00:00.000000000 +0100 ++++ linux-2.6.29-rc3.owrt.om/drivers/mfd/pcf50606-adc.c 2009-05-10 22:28:00.000000000 +0200 +@@ -0,0 +1,279 @@ ++/* Philips PCF50606 ADC Driver ++ * ++ * (C) 2006-2008 by Openmoko, Inc. ++ * Author: Balaji Rao <balajirrao@openmoko.org> ++ * All rights reserved. ++ * ++ * Broken down from monstrous PCF50606 driver mainly by ++ * Harald Welte, Andy Green, Werner Almesberger and Matt Hsu ++ * ++ * 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. ++ * ++ * NOTE: This driver does not yet support subtractive ADC mode, which means ++ * you can do only one measurement per read request. ++ */ ++ ++#include <linux/kernel.h> ++#include <linux/module.h> ++#include <linux/init.h> ++#include <linux/device.h> ++#include <linux/platform_device.h> ++#include <linux/completion.h> ++ ++#include <linux/mfd/pcf50606/core.h> ++#include <linux/mfd/pcf50606/adc.h> ++ ++struct pcf50606_adc_request { ++ int mux; ++ int result; ++ void (*callback)(struct pcf50606 *, void *, int); ++ void *callback_param; ++ ++ /* Used in case of sync requests */ ++ struct completion completion; ++ ++}; ++ ++#define PCF50606_MAX_ADC_FIFO_DEPTH 8 ++ ++struct pcf50606_adc { ++ struct pcf50606 *pcf; ++ ++ /* Private stuff */ ++ struct pcf50606_adc_request *queue[PCF50606_MAX_ADC_FIFO_DEPTH]; ++ int queue_head; ++ int queue_tail; ++ struct mutex queue_mutex; ++}; ++ ++static inline struct pcf50606_adc *__to_adc(struct pcf50606 *pcf) ++{ ++ return platform_get_drvdata(pcf->adc_pdev); ++} ++ ++static void adc_setup(struct pcf50606 *pcf, int channel) ++{ ++ channel &= PCF50606_ADCC2_ADCMUX_MASK; ++ ++ /* start ADC conversion of selected channel */ ++ pcf50606_reg_write(pcf, PCF50606_REG_ADCC2, channel | ++ PCF50606_ADCC2_ADCSTART | PCF50606_ADCC2_RES_10BIT); ++ ++} ++ ++static void trigger_next_adc_job_if_any(struct pcf50606 *pcf) ++{ ++ struct pcf50606_adc *adc = __to_adc(pcf); ++ int head, tail; ++ ++ mutex_lock(&adc->queue_mutex); ++ ++ head = adc->queue_head; ++ tail = adc->queue_tail; ++ ++ if (!adc->queue[head]) ++ goto out; ++ ++ adc_setup(pcf, adc->queue[head]->mux); ++out: ++ mutex_unlock(&adc->queue_mutex); ++} ++ ++static int ++adc_enqueue_request(struct pcf50606 *pcf, struct pcf50606_adc_request *req) ++{ ++ struct pcf50606_adc *adc = __to_adc(pcf); ++ int head, tail; ++ ++ mutex_lock(&adc->queue_mutex); ++ head = adc->queue_head; ++ tail = adc->queue_tail; ++ ++ if (adc->queue[tail]) { ++ mutex_unlock(&adc->queue_mutex); ++ return -EBUSY; ++ } ++ ++ adc->queue[tail] = req; ++ ++ adc->queue_tail = ++ (tail + 1) & (PCF50606_MAX_ADC_FIFO_DEPTH - 1); ++ ++ mutex_unlock(&adc->queue_mutex); ++ ++ trigger_next_adc_job_if_any(pcf); ++ ++ return 0; ++} ++ ++static void ++pcf50606_adc_sync_read_callback(struct pcf50606 *pcf, void *param, int result) ++{ ++ struct pcf50606_adc_request *req; ++ ++ /*We know here that the passed param is an adc_request object */ ++ req = (struct pcf50606_adc_request *)param; ++ ++ req->result = result; ++ complete(&req->completion); ++} ++ ++int pcf50606_adc_sync_read(struct pcf50606 *pcf, int mux) ++{ ++ ++ struct pcf50606_adc_request *req; ++ int result; ++ ++ /* req is freed when the result is ready, in irq handler*/ ++ req = kzalloc(sizeof(*req), GFP_KERNEL); ++ if (!req) ++ return -ENOMEM; ++ ++ req->mux = mux; ++ req->callback = pcf50606_adc_sync_read_callback; ++ req->callback_param = req; ++ init_completion(&req->completion); ++ ++ adc_enqueue_request(pcf, req); ++ ++ if (wait_for_completion_timeout(&req->completion, 5 * HZ) == 5 * HZ) { ++ dev_err(pcf->dev, "ADC read timed out \n"); ++ } ++ ++ result = req->result; ++ ++ return result; ++} ++EXPORT_SYMBOL_GPL(pcf50606_adc_sync_read); ++ ++int pcf50606_adc_async_read(struct pcf50606 *pcf, int mux, ++ void (*callback)(struct pcf50606 *, void *, int), ++ void *callback_param) ++{ ++ struct pcf50606_adc_request *req; ++ ++ /* req is freed when the result is ready, in pcf50606_work*/ ++ req = kmalloc(sizeof(*req), GFP_KERNEL); ++ if (!req) ++ return -ENOMEM; ++ ++ req->mux = mux; ++ req->callback = callback; ++ req->callback_param = callback_param; ++ ++ adc_enqueue_request(pcf, req); ++ ++ return 0; ++} ++EXPORT_SYMBOL_GPL(pcf50606_adc_async_read); ++ ++static int adc_result(struct pcf50606 *pcf) ++{ ++ u16 ret = (pcf50606_reg_read(pcf, PCF50606_REG_ADCS1) << 2) | ++ (pcf50606_reg_read(pcf, PCF50606_REG_ADCS2) & 0x03); ++ ++ dev_dbg(pcf->dev, "adc result = %d\n", ret); ++ ++ return ret; ++} ++ ++static void pcf50606_adc_irq(int irq, void *data) ++{ ++ struct pcf50606_adc *adc = data; ++ struct pcf50606 *pcf = adc->pcf; ++ struct pcf50606_adc_request *req; ++ int head; ++ ++ mutex_lock(&adc->queue_mutex); ++ head = adc->queue_head; ++ ++ req = adc->queue[head]; ++ if (WARN_ON(!req)) { ++ dev_err(pcf->dev, "pcf50606-adc irq: ADC queue empty!\n"); ++ mutex_unlock(&adc->queue_mutex); ++ return; ++ } ++ ++ adc->queue[head] = NULL; ++ adc->queue_head = (head + 1) & ++ (PCF50606_MAX_ADC_FIFO_DEPTH - 1); ++ ++ mutex_unlock(&adc->queue_mutex); ++ ++ req->callback(pcf, req->callback_param, adc_result(pcf)); ++ kfree(req); ++ ++ trigger_next_adc_job_if_any(pcf); ++} ++ ++static int __devinit pcf50606_adc_probe(struct platform_device *pdev) ++{ ++ struct pcf50606_subdev_pdata *pdata = pdev->dev.platform_data; ++ struct pcf50606_adc *adc; ++ ++ adc = kzalloc(sizeof(*adc), GFP_KERNEL); ++ if (!adc) ++ return -ENOMEM; ++ ++ adc->pcf = pdata->pcf; ++ platform_set_drvdata(pdev, adc); ++ ++ pcf50606_register_irq(pdata->pcf, PCF50606_IRQ_ADCRDY, ++ pcf50606_adc_irq, adc); ++ ++ mutex_init(&adc->queue_mutex); ++ ++ return 0; ++} ++ ++static int __devexit pcf50606_adc_remove(struct platform_device *pdev) ++{ ++ struct pcf50606_adc *adc = platform_get_drvdata(pdev); ++ int i, head; ++ ++ pcf50606_free_irq(adc->pcf, PCF50606_IRQ_ADCRDY); ++ ++ mutex_lock(&adc->queue_mutex); ++ head = adc->queue_head; ++ ++ if (WARN_ON(adc->queue[head])) ++ dev_err(adc->pcf->dev, ++ "adc driver removed with request pending\n"); ++ ++ for (i = 0; i < PCF50606_MAX_ADC_FIFO_DEPTH; i++) ++ kfree(adc->queue[i]); ++ ++ mutex_unlock(&adc->queue_mutex); ++ kfree(adc); ++ ++ return 0; ++} ++ ++struct platform_driver pcf50606_adc_driver = { ++ .driver = { ++ .name = "pcf50606-adc", ++ }, ++ .probe = pcf50606_adc_probe, ++ .remove = __devexit_p(pcf50606_adc_remove), ++}; ++ ++static int __init pcf50606_adc_init(void) ++{ ++ return platform_driver_register(&pcf50606_adc_driver); ++} ++module_init(pcf50606_adc_init); ++ ++static void __exit pcf50606_adc_exit(void) ++{ ++ platform_driver_unregister(&pcf50606_adc_driver); ++} ++module_exit(pcf50606_adc_exit); ++ ++MODULE_AUTHOR("Balaji Rao <balajirrao@openmoko.org>"); ++MODULE_DESCRIPTION("PCF50606 adc driver"); ++MODULE_LICENSE("GPL"); ++MODULE_ALIAS("platform:pcf50606-adc"); ++ +diff -ruN --exclude='*.orig' --exclude='*.rej' linux-2.6.29-rc3.owrt/drivers/mfd/pcf50606-core.c linux-2.6.29-rc3.owrt.om/drivers/mfd/pcf50606-core.c +--- linux-2.6.29-rc3.owrt/drivers/mfd/pcf50606-core.c 1970-01-01 01:00:00.000000000 +0100 ++++ linux-2.6.29-rc3.owrt.om/drivers/mfd/pcf50606-core.c 2009-05-10 22:28:00.000000000 +0200 +@@ -0,0 +1,680 @@ ++/* Philips PCF50606 Power Management Unit (PMU) driver ++ * ++ * (C) 2006-2008 by Openmoko, Inc. ++ * Author: Harald Welte <laforge@openmoko.org> ++ * Matt Hsu <matt@openmoko.org> ++ * All rights reserved. ++ * ++ * 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. ++ * ++ */ ++#include <linux/kernel.h> ++#include <linux/device.h> ++#include <linux/sysfs.h> ++#include <linux/device.h> ++#include <linux/module.h> ++#include <linux/types.h> ++#include <linux/interrupt.h> ++#include <linux/workqueue.h> ++#include <linux/platform_device.h> ++#include <linux/i2c.h> ++#include <linux/irq.h> ++#include <linux/device.h> ++#include <linux/module.h> ++ ++#include <linux/mfd/pcf50606/core.h> ++ ++static int __pcf50606_read(struct pcf50606 *pcf, u8 reg, int num, u8 *data) ++{ ++ int ret; ++ ++ ret = i2c_smbus_read_i2c_block_data(pcf->i2c_client, reg, ++ num, data); ++ if (ret < 0) ++ dev_err(pcf->dev, "Error reading %d regs at %d\n", num, reg); ++ ++ return ret; ++} ++ ++static int __pcf50606_write(struct pcf50606 *pcf, u8 reg, int num, u8 *data) ++{ ++ int ret; ++ ++ ret = i2c_smbus_write_i2c_block_data(pcf->i2c_client, reg, ++ num, data); ++ if (ret < 0) ++ dev_err(pcf->dev, "Error writing %d regs at %d\n", num, reg); ++ ++ return ret; ++ ++} ++ ++/* Read a block of upto 32 regs */ ++int pcf50606_read_block(struct pcf50606 *pcf, u8 reg, ++ int nr_regs, u8 *data) ++{ ++ int ret; ++ ++ mutex_lock(&pcf->lock); ++ ret = __pcf50606_read(pcf, reg, nr_regs, data); ++ mutex_unlock(&pcf->lock); ++ ++ return ret; ++} ++EXPORT_SYMBOL_GPL(pcf50606_read_block); ++ ++/* Write a block of upto 32 regs */ ++int pcf50606_write_block(struct pcf50606 *pcf , u8 reg, ++ int nr_regs, u8 *data) ++{ ++ int ret; ++ ++ mutex_lock(&pcf->lock); ++ ret = __pcf50606_write(pcf, reg, nr_regs, data); ++ mutex_unlock(&pcf->lock); ++ ++ return ret; ++} ++EXPORT_SYMBOL_GPL(pcf50606_write_block); ++ ++u8 pcf50606_reg_read(struct pcf50606 *pcf, u8 reg) ++{ ++ u8 val; ++ ++ mutex_lock(&pcf->lock); ++ __pcf50606_read(pcf, reg, 1, &val); ++ mutex_unlock(&pcf->lock); ++ ++ return val; ++} ++EXPORT_SYMBOL_GPL(pcf50606_reg_read); ++ ++int pcf50606_reg_write(struct pcf50606 *pcf, u8 reg, u8 val) ++{ ++ int ret; ++ ++ mutex_lock(&pcf->lock); ++ ret = __pcf50606_write(pcf, reg, 1, &val); ++ mutex_unlock(&pcf->lock); ++ ++ return ret; ++} ++EXPORT_SYMBOL_GPL(pcf50606_reg_write); ++ ++int pcf50606_reg_set_bit_mask(struct pcf50606 *pcf, u8 reg, u8 mask, u8 val) ++{ ++ int ret; ++ u8 tmp; ++ ++ val &= mask; ++ ++ mutex_lock(&pcf->lock); ++ ret = __pcf50606_read(pcf, reg, 1, &tmp); ++ if (ret < 0) ++ goto out; ++ ++ tmp &= ~mask; ++ tmp |= val; ++ ret = __pcf50606_write(pcf, reg, 1, &tmp); ++ ++out: ++ mutex_unlock(&pcf->lock); ++ ++ return ret; ++} ++EXPORT_SYMBOL_GPL(pcf50606_reg_set_bit_mask); ++ ++int pcf50606_reg_clear_bits(struct pcf50606 *pcf, u8 reg, u8 val) ++{ ++ int ret; ++ u8 tmp; ++ ++ mutex_lock(&pcf->lock); ++ ret = __pcf50606_read(pcf, reg, 1, &tmp); ++ if (ret < 0) ++ goto out; ++ ++ tmp &= ~val; ++ ret = __pcf50606_write(pcf, reg, 1, &tmp); ++ ++out: ++ mutex_unlock(&pcf->lock); ++ ++ return ret; ++} ++EXPORT_SYMBOL_GPL(pcf50606_reg_clear_bits); ++ ++/* sysfs attributes */ ++static ssize_t show_dump_regs(struct device *dev, struct device_attribute *attr, ++ char *buf) ++{ ++ struct pcf50606 *pcf = dev_get_drvdata(dev); ++ u8 dump[16]; ++ int n, n1, idx = 0; ++ char *buf1 = buf; ++ static u8 address_no_read[] = { /* must be ascending */ ++ PCF50606_REG_INT1, ++ PCF50606_REG_INT2, ++ PCF50606_REG_INT3, ++ 0 /* terminator */ ++ }; ++ ++ for (n = 0; n < 256; n += sizeof(dump)) { ++ for (n1 = 0; n1 < sizeof(dump); n1++) ++ if (n == address_no_read[idx]) { ++ idx++; ++ dump[n1] = 0x00; ++ } else ++ dump[n1] = pcf50606_reg_read(pcf, n + n1); ++ ++ hex_dump_to_buffer(dump, sizeof(dump), 16, 1, buf1, 128, 0); ++ buf1 += strlen(buf1); ++ *buf1++ = '\n'; ++ *buf1 = '\0'; ++ } ++ ++ return buf1 - buf; ++} ++static DEVICE_ATTR(dump_regs, 0400, show_dump_regs, NULL); ++ ++static ssize_t show_resume_reason(struct device *dev, ++ struct device_attribute *attr, char *buf) ++{ ++ struct pcf50606 *pcf = dev_get_drvdata(dev); ++ int n; ++ ++ n = sprintf(buf, "%02x%02x%02x\n", ++ pcf->resume_reason[0], ++ pcf->resume_reason[1], ++ pcf->resume_reason[2]); ++ ++ return n; ++} ++static DEVICE_ATTR(resume_reason, 0400, show_resume_reason, NULL); ++ ++static struct attribute *pcf_sysfs_entries[] = { ++ &dev_attr_dump_regs.attr, ++ &dev_attr_resume_reason.attr, ++ NULL, ++}; ++ ++static struct attribute_group pcf_attr_group = { ++ .name = NULL, /* put in device directory */ ++ .attrs = pcf_sysfs_entries, ++}; ++ ++int pcf50606_register_irq(struct pcf50606 *pcf, int irq, ++ void (*handler) (int, void *), void *data) ++{ ++ if (irq < 0 || irq > PCF50606_NUM_IRQ || !handler) ++ return -EINVAL; ++ ++ if (WARN_ON(pcf->irq_handler[irq].handler)) ++ return -EBUSY; ++ ++ mutex_lock(&pcf->lock); ++ pcf->irq_handler[irq].handler = handler; ++ pcf->irq_handler[irq].data = data; ++ mutex_unlock(&pcf->lock); ++ ++ return 0; ++} ++EXPORT_SYMBOL_GPL(pcf50606_register_irq); ++ ++int pcf50606_free_irq(struct pcf50606 *pcf, int irq) ++{ ++ if (irq < 0 || irq > PCF50606_NUM_IRQ) ++ return -EINVAL; ++ ++ mutex_lock(&pcf->lock); ++ pcf->irq_handler[irq].handler = NULL; ++ mutex_unlock(&pcf->lock); ++ ++ return 0; ++} ++EXPORT_SYMBOL_GPL(pcf50606_free_irq); ++ ++static int __pcf50606_irq_mask_set(struct pcf50606 *pcf, int irq, u8 mask) ++{ ++ u8 reg, bits, tmp; ++ int ret = 0, idx; ++ ++ idx = irq >> 3; ++ reg = PCF50606_REG_INT1M + idx; ++ bits = 1 << (irq & 0x07); ++ ++ mutex_lock(&pcf->lock); ++ ++ if (mask) { ++ ret = __pcf50606_read(pcf, reg, 1, &tmp); ++ if (ret < 0) ++ goto out; ++ ++ tmp |= bits; ++ ++ ret = __pcf50606_write(pcf, reg, 1, &tmp); ++ if (ret < 0) ++ goto out; ++ ++ pcf->mask_regs[idx] &= ~bits; ++ pcf->mask_regs[idx] |= bits; ++ } else { ++ ret = __pcf50606_read(pcf, reg, 1, &tmp); ++ if (ret < 0) ++ goto out; ++ ++ tmp &= ~bits; ++ ++ ret = __pcf50606_write(pcf, reg, 1, &tmp); ++ if (ret < 0) ++ goto out; ++ ++ pcf->mask_regs[idx] &= ~bits; ++ } ++out: ++ mutex_unlock(&pcf->lock); ++ ++ return ret; ++} ++ ++int pcf50606_irq_mask(struct pcf50606 *pcf, int irq) ++{ ++ dev_info(pcf->dev, "Masking IRQ %d\n", irq); ++ ++ return __pcf50606_irq_mask_set(pcf, irq, 1); ++} ++EXPORT_SYMBOL_GPL(pcf50606_irq_mask); ++ ++int pcf50606_irq_unmask(struct pcf50606 *pcf, int irq) ++{ ++ dev_info(pcf->dev, "Unmasking IRQ %d\n", irq); ++ ++ return __pcf50606_irq_mask_set(pcf, irq, 0); ++} ++EXPORT_SYMBOL_GPL(pcf50606_irq_unmask); ++ ++int pcf50606_irq_mask_get(struct pcf50606 *pcf, int irq) ++{ ++ u8 reg, bits; ++ ++ reg = (irq / 8); ++ bits = (1 << (irq % 8)); ++ ++ return pcf->mask_regs[reg] & bits; ++} ++EXPORT_SYMBOL_GPL(pcf50606_irq_mask_get); ++ ++static void pcf50606_irq_call_handler(struct pcf50606 *pcf, ++ int irq) ++{ ++ if (pcf->irq_handler[irq].handler) ++ pcf->irq_handler[irq].handler(irq, pcf->irq_handler[irq].data); ++} ++ ++#define PCF50606_ONKEY1S_TIMEOUT 8 ++ ++#define PCF50606_REG_MBCS1 0x2c ++ ++static void pcf50606_irq_worker(struct work_struct *work) ++{ ++ struct pcf50606 *pcf; ++ int ret, i, j; ++ u8 pcf_int[3], chgstat; ++ ++ pcf = container_of(work, struct pcf50606, irq_work); ++ ++ /* Read the 3 INT regs in one transaction */ ++ ret = pcf50606_read_block(pcf, PCF50606_REG_INT1, ++ ARRAY_SIZE(pcf_int), pcf_int); ++ if (ret != ARRAY_SIZE(pcf_int)) { ++ dev_info(pcf->dev, "Error reading INT registers\n"); ++ ++ /* ++ * If this doesn't ACK the interrupt to the chip, we'll be ++ * called once again as we're level triggered. ++ */ ++ goto out; ++ } ++ ++ /* We immediately read the charger status. We thus make sure ++ * only of CHGINS/CHGRM interrupt handlers are called */ ++ if (pcf_int[1] & (PCF50606_INT2_CHGINS | PCF50606_INT2_CHGRM)) { ++ chgstat = pcf50606_reg_read(pcf, PCF50606_REG_MBCS1); ++ if (chgstat & (0x1 << 4)) ++ pcf_int[1] &= ~(1 << PCF50606_INT2_CHGRM); ++ else ++ pcf_int[1] &= ~(1 << PCF50606_INT2_CHGINS); ++ } ++ ++ dev_dbg(pcf->dev, "INT1=0x%02x INT2=0x%02x INT3=0x%02x\n", ++ pcf_int[0], pcf_int[1], pcf_int[2]); ++ ++ /* Some revisions of the chip don't have a 8s standby mode on ++ * ONKEY1S press. We try to manually do it in such cases. */ ++ if (pcf_int[0] & PCF50606_INT1_SECOND && pcf->onkey1s_held) { ++ dev_info(pcf->dev, "ONKEY1S held for %d secs\n", ++ pcf->onkey1s_held); ++ if (pcf->onkey1s_held++ == PCF50606_ONKEY1S_TIMEOUT) ++ if (pcf->pdata->force_shutdown) ++ pcf->pdata->force_shutdown(pcf); ++ } ++ ++ if (pcf_int[0] & PCF50606_INT1_ONKEY1S) { ++ dev_info(pcf->dev, "ONKEY1S held\n"); ++ pcf->onkey1s_held = 1 ; ++ ++ /* Unmask IRQ_SECOND */ ++ pcf50606_reg_clear_bits(pcf, PCF50606_REG_INT1M, ++ PCF50606_INT1_SECOND); ++ ++ /* Unmask IRQ_ONKEYF */ ++ pcf50606_reg_clear_bits(pcf, PCF50606_REG_INT1M, ++ PCF50606_INT1_ONKEYF); ++ } ++ ++ if ((pcf_int[0] & PCF50606_INT1_ONKEYR) && pcf->onkey1s_held) { ++ pcf->onkey1s_held = 0; ++ ++ /* Mask SECOND and ONKEYF interrupts */ ++ if (pcf->mask_regs[0] & PCF50606_INT1_SECOND) ++ pcf50606_reg_set_bit_mask(pcf, ++ PCF50606_REG_INT1M, ++ PCF50606_INT1_SECOND, ++ PCF50606_INT1_SECOND); ++ ++ if (pcf->mask_regs[0] & PCF50606_INT1_ONKEYF) ++ pcf50606_reg_set_bit_mask(pcf, ++ PCF50606_REG_INT1M, ++ PCF50606_INT1_ONKEYF, ++ PCF50606_INT1_ONKEYF); ++ } ++ ++ /* Have we just resumed ? */ ++ if (pcf->is_suspended) { ++ ++ pcf->is_suspended = 0; ++ ++ /* Set the resume reason filtering out non resumers */ ++ for (i = 0; i < ARRAY_SIZE(pcf_int); i++) ++ pcf->resume_reason[i] = pcf_int[i] & ++ pcf->pdata->resumers[i]; ++ ++ /* Make sure we don't pass on ONKEY events to ++ * userspace now */ ++ pcf_int[1] &= ~(PCF50606_INT1_ONKEYR | PCF50606_INT1_ONKEYF); ++ } ++ ++ for (i = 0; i < ARRAY_SIZE(pcf_int); i++) { ++ /* Unset masked interrupts */ ++ pcf_int[i] &= ~pcf->mask_regs[i]; ++ ++ for (j = 0; j < 8 ; j++) ++ if (pcf_int[i] & (1 << j)) ++ pcf50606_irq_call_handler(pcf, (i * 8) + j); ++ } ++ ++out: ++ put_device(pcf->dev); ++ enable_irq(pcf->irq); ++} ++ ++static irqreturn_t pcf50606_irq(int irq, void *data) ++{ ++ struct pcf50606 *pcf = data; ++ ++ get_device(pcf->dev); ++ disable_irq(pcf->irq); ++ schedule_work(&pcf->irq_work); ++ ++ return IRQ_HANDLED; ++} ++ ++static void ++pcf50606_client_dev_register(struct pcf50606 *pcf, const char *name, ++ struct platform_device **pdev) ++{ ++ struct pcf50606_subdev_pdata subdev_pdata; ++ int ret; ++ ++ *pdev = platform_device_alloc(name, -1); ++ if (!*pdev) { ++ dev_err(pcf->dev, "Falied to allocate %s\n", name); ++ return; ++ } ++ ++ subdev_pdata.pcf = pcf; ++ platform_device_add_data(*pdev, &subdev_pdata, sizeof(subdev_pdata)); ++ ++ (*pdev)->dev.parent = pcf->dev; ++ ++ ret = platform_device_add(*pdev); ++ if (ret) { ++ dev_err(pcf->dev, "Failed to register %s: %d\n", name, ret); ++ platform_device_put(*pdev); ++ *pdev = NULL; ++ } ++} ++ ++#ifdef CONFIG_PM ++static int pcf50606_suspend(struct device *dev, pm_message_t state) ++{ ++ struct pcf50606 *pcf; ++ int ret, i; ++ u8 res[3]; ++ ++ pcf = dev_get_drvdata(dev); ++ ++ /* Make sure our interrupt handlers are not called ++ * henceforth */ ++ disable_irq(pcf->irq); ++ ++ /* Make sure that any running IRQ worker has quit */ ++ cancel_work_sync(&pcf->irq_work); ++ ++ /* Save the masks */ ++ ret = pcf50606_read_block(pcf, PCF50606_REG_INT1M, ++ ARRAY_SIZE(pcf->suspend_irq_masks), ++ pcf->suspend_irq_masks); ++ if (ret < 0) { ++ dev_err(pcf->dev, "error saving irq masks\n"); ++ goto out; ++ } ++ ++ /* Write wakeup irq masks */ ++ for (i = 0; i < ARRAY_SIZE(res); i++) ++ res[i] = ~pcf->pdata->resumers[i]; ++ ++ ret = pcf50606_write_block(pcf, PCF50606_REG_INT1M, ++ ARRAY_SIZE(res), &res[0]); ++ if (ret < 0) { ++ dev_err(pcf->dev, "error writing wakeup irq masks\n"); ++ goto out; ++ } ++ ++ pcf->is_suspended = 1; ++ ++out: ++ return ret; ++} ++ ++static int pcf50606_resume(struct device *dev) ++{ ++ struct pcf50606 *pcf; ++ int ret; ++ ++ pcf = dev_get_drvdata(dev); ++ ++ /* Write the saved mask registers */ ++ ret = pcf50606_write_block(pcf, PCF50606_REG_INT1M, ++ ARRAY_SIZE(pcf->suspend_irq_masks), ++ pcf->suspend_irq_masks); ++ if (ret < 0) ++ dev_err(pcf->dev, "Error restoring saved suspend masks\n"); ++ ++ get_device(pcf->dev); ++ ++ /* ++ * Clear any pending interrupts and set resume reason if any. ++ * This will leave with enable_irq() ++ */ ++ pcf50606_irq_worker(&pcf->irq_work); ++ ++ return 0; ++} ++#else ++#define pcf50606_suspend NULL ++#define pcf50606_resume NULL ++#endif ++ ++static int pcf50606_probe(struct i2c_client *client, ++ const struct i2c_device_id *ids) ++{ ++ struct pcf50606 *pcf; ++ struct pcf50606_platform_data *pdata = client->dev.platform_data; ++ int i, ret = 0; ++ int version, variant; ++ ++ pcf = kzalloc(sizeof(*pcf), GFP_KERNEL); ++ if (!pcf) ++ return -ENOMEM; ++ ++ pcf->pdata = pdata; ++ ++ mutex_init(&pcf->lock); ++ ++ i2c_set_clientdata(client, pcf); ++ pcf->dev = &client->dev; ++ pcf->i2c_client = client; ++ pcf->irq = client->irq; ++ ++ INIT_WORK(&pcf->irq_work, pcf50606_irq_worker); ++ ++ version = pcf50606_reg_read(pcf, 0); ++ variant = pcf50606_reg_read(pcf, 1); ++ if (version < 0 || variant < 0) { ++ dev_err(pcf->dev, "Unable to probe pcf50606\n"); ++ ret = -ENODEV; ++ goto err; ++ } ++ ++ dev_info(pcf->dev, "Probed device version %d variant %d\n", ++ version, variant); ++ /* Enable all inteerupts except RTC SECOND */ ++ pcf->mask_regs[0] = 0x40; ++ pcf50606_reg_write(pcf, PCF50606_REG_INT1M, pcf->mask_regs[0]); ++ pcf50606_reg_write(pcf, PCF50606_REG_INT2M, 0x00); ++ pcf50606_reg_write(pcf, PCF50606_REG_INT3M, 0x00); ++ ++ pcf50606_client_dev_register(pcf, "pcf50606-input", ++ &pcf->input_pdev); ++ pcf50606_client_dev_register(pcf, "pcf50606-rtc", ++ &pcf->rtc_pdev); ++ pcf50606_client_dev_register(pcf, "pcf50606-mbc", ++ &pcf->mbc_pdev); ++ pcf50606_client_dev_register(pcf, "pcf50606-adc", ++ &pcf->adc_pdev); ++ pcf50606_client_dev_register(pcf, "pcf50606-wdt", ++ &pcf->wdt_pdev); ++ for (i = 0; i < PCF50606_NUM_REGULATORS; i++) { ++ struct platform_device *pdev; ++ ++ pdev = platform_device_alloc("pcf50606-regltr", i); ++ if (!pdev) { ++ dev_err(pcf->dev, "Cannot create regulator\n"); ++ continue; ++ } ++ ++ pdev->dev.parent = pcf->dev; ++ pdev->dev.platform_data = &pdata->reg_init_data[i]; ++ pdev->dev.driver_data = pcf; ++ pcf->regulator_pdev[i] = pdev; ++ ++ platform_device_add(pdev); ++ } ++ ++ if (client->irq) { ++ set_irq_handler(client->irq, handle_level_irq); ++ ret = request_irq(client->irq, pcf50606_irq, ++ IRQF_TRIGGER_LOW, "pcf50606", pcf); ++ ++ if (ret) { ++ dev_err(pcf->dev, "Failed to request IRQ %d\n", ret); ++ goto err; ++ } ++ } else { ++ dev_err(pcf->dev, "No IRQ configured\n"); ++ goto err; ++ } ++ ++ if (enable_irq_wake(client->irq) < 0) ++ dev_err(pcf->dev, "IRQ %u cannot be enabled as wake-up source" ++ "in this hardware revision", client->irq); ++ ++ ret = sysfs_create_group(&client->dev.kobj, &pcf_attr_group); ++ if (ret) ++ dev_err(pcf->dev, "error creating sysfs entries\n"); ++ ++ if (pdata->probe_done) ++ pdata->probe_done(pcf); ++ ++ return 0; ++ ++err: ++ kfree(pcf); ++ return ret; ++} ++ ++static int pcf50606_remove(struct i2c_client *client) ++{ ++ struct pcf50606 *pcf = i2c_get_clientdata(client); ++ int i; ++ ++ free_irq(pcf->irq, pcf); ++ ++ platform_device_unregister(pcf->input_pdev); ++ platform_device_unregister(pcf->rtc_pdev); ++ platform_device_unregister(pcf->mbc_pdev); ++ platform_device_unregister(pcf->adc_pdev); ++ ++ for (i = 0; i < PCF50606_NUM_REGULATORS; i++) ++ platform_device_unregister(pcf->regulator_pdev[i]); ++ ++ kfree(pcf); ++ ++ return 0; ++} ++ ++static struct i2c_device_id pcf50606_id_table[] = { ++ {"pcf50606", 0x08}, ++}; ++ ++static struct i2c_driver pcf50606_driver = { ++ .driver = { ++ .name = "pcf50606", ++ .suspend = pcf50606_suspend, ++ .resume = pcf50606_resume, ++ }, ++ .id_table = pcf50606_id_table, ++ .probe = pcf50606_probe, ++ .remove = pcf50606_remove, ++}; ++ ++static int __init pcf50606_init(void) ++{ ++ return i2c_add_driver(&pcf50606_driver); ++} ++ ++static void pcf50606_exit(void) ++{ ++ i2c_del_driver(&pcf50606_driver); ++} ++ ++MODULE_DESCRIPTION("I2C chip driver for NXP PCF50606 PMU"); ++MODULE_AUTHOR("Harald Welte <laforge@openmoko.org>"); ++MODULE_LICENSE("GPL"); ++ ++module_init(pcf50606_init); ++module_exit(pcf50606_exit); +diff -ruN --exclude='*.orig' --exclude='*.rej' linux-2.6.29-rc3.owrt/drivers/mfd/pcf50606-gpo.c linux-2.6.29-rc3.owrt.om/drivers/mfd/pcf50606-gpo.c +--- linux-2.6.29-rc3.owrt/drivers/mfd/pcf50606-gpo.c 1970-01-01 01:00:00.000000000 +0100 ++++ linux-2.6.29-rc3.owrt.om/drivers/mfd/pcf50606-gpo.c 2009-05-10 22:28:00.000000000 +0200 +@@ -0,0 +1,119 @@ ++/* Philips PCF50606 GPO Driver ++ * ++ * (C) 2006-2008 by Openmoko, Inc. ++ * Author: Balaji Rao <balajirrao@openmoko.org> ++ * All rights reserved. ++ * ++ * Broken down from monstrous PCF50606 driver mainly by ++ * Harald Welte, Andy Green Werner Almesberger and Matt Hsu ++ * ++ * 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. ++ */ ++ ++#include <linux/kernel.h> ++ ++#include <linux/mfd/pcf50606/core.h> ++#include <linux/mfd/pcf50606/gpo.h> ++ ++void pcf50606_gpo_set_active(struct pcf50606 *pcf, int gpo, int val) ++{ ++ u8 reg, value, mask; ++ ++ reg = gpo; ++ value = val; ++ mask = 0x07; ++ ++ if (gpo == PCF50606_GPO2) { ++ value = val << 4; ++ mask = 0x07 << 4; ++ } ++ pcf50606_reg_set_bit_mask(pcf, reg, mask, value); ++} ++EXPORT_SYMBOL_GPL(pcf50606_gpo_set_active); ++ ++int pcf50606_gpo_get_active(struct pcf50606 *pcf, int gpo) ++{ ++ u8 reg, value, shift = 0; ++ ++ reg = gpo; ++ if (gpo == PCF50606_GPO2) ++ shift = 4; ++ ++ value = pcf50606_reg_read(pcf, reg); ++ ++ return (value >> shift) & 0x07; ++} ++EXPORT_SYMBOL_GPL(pcf50606_gpo_get_active); ++ ++void pcf50606_gpo_set_standby(struct pcf50606 *pcf, int gpo, int val) ++{ ++ u8 reg; ++ ++ if (gpo == PCF50606_GPO1 || gpo == PCF50606_GPO2) { ++ dev_err(pcf->dev, "Can't set standby settings for GPO[12]n"); ++ return; ++ } ++ ++ reg = gpo; ++ ++ pcf50606_reg_set_bit_mask(pcf, gpo, 0x07 << 3, val); ++} ++EXPORT_SYMBOL_GPL(pcf50606_gpo_set_standby); ++ ++int pcf50606_gpo_get_standby(struct pcf50606 *pcf, int gpo) ++{ ++ u8 reg, value; ++ ++ if (gpo == PCF50606_GPO1 || gpo == PCF50606_GPO2) { ++ dev_err(pcf->dev, "Can't get standby settings for GPO[12]n"); ++ return -EINVAL; ++ } ++ ++ reg = gpo; ++ value = pcf50606_reg_read(pcf, reg); ++ ++ return (value >> 3) & 0x07; ++} ++EXPORT_SYMBOL_GPL(pcf50606_gpo_get_standby); ++ ++void pcf50606_gpo_invert_set(struct pcf50606 *pcf, int gpo, int invert) ++{ ++ u8 reg, value, mask; ++ ++ reg = gpo; ++ value = !!invert << 6; ++ mask = 0x01 << 6; ++ ++ if (gpo == PCF50606_GPO1) { ++ mask = 0x01 << 4; ++ value = !!invert << 4; ++ } ++ else if (gpo == PCF50606_GPO2) { ++ mask = 0x01 << 7; ++ value = !!invert << 7; ++ } ++ ++ pcf50606_reg_set_bit_mask(pcf, reg, mask, value); ++} ++EXPORT_SYMBOL_GPL(pcf50606_gpo_invert_set); ++ ++int pcf50606_gpo_invert_get(struct pcf50606 *pcf, int gpo) ++{ ++ u8 reg, value, shift; ++ ++ reg = gpo; ++ shift = 6; ++ ++ if (gpo == PCF50606_GPO1) ++ shift = 4; ++ else if (gpo == PCF50606_GPO2) ++ shift = 7; ++ ++ value = pcf50606_reg_read(pcf, reg); ++ ++ return (value >> shift) & 0x01; ++} ++EXPORT_SYMBOL_GPL(pcf50606_gpo_invert_get); +diff -ruN --exclude='*.orig' --exclude='*.rej' linux-2.6.29-rc3.owrt/drivers/mfd/pcf50633-core.c linux-2.6.29-rc3.owrt.om/drivers/mfd/pcf50633-core.c +--- linux-2.6.29-rc3.owrt/drivers/mfd/pcf50633-core.c 2009-05-10 22:08:43.000000000 +0200 ++++ linux-2.6.29-rc3.owrt.om/drivers/mfd/pcf50633-core.c 2009-05-10 22:28:00.000000000 +0200 +@@ -346,6 +346,8 @@ + goto out; + } + ++ pcf50633_reg_write(pcf, PCF50633_REG_OOCSHDWN, 0x04 ); /* defeat 8s death from lowsys on A5 */ ++ + /* We immediately read the usb and adapter status. We thus make sure + * only of USBINS/USBREM IRQ handlers are called */ + if (pcf_int[0] & (PCF50633_INT1_USBINS | PCF50633_INT1_USBREM)) { +@@ -445,6 +447,7 @@ + + get_device(pcf->dev); + disable_irq(pcf->irq); ++ + schedule_work(&pcf->irq_work); + + return IRQ_HANDLED; +diff -ruN --exclude='*.orig' --exclude='*.rej' linux-2.6.29-rc3.owrt/drivers/misc/Kconfig linux-2.6.29-rc3.owrt.om/drivers/misc/Kconfig +--- linux-2.6.29-rc3.owrt/drivers/misc/Kconfig 2009-05-10 22:08:43.000000000 +0200 ++++ linux-2.6.29-rc3.owrt.om/drivers/misc/Kconfig 2009-05-10 22:28:00.000000000 +0200 +@@ -225,4 +225,10 @@ + source "drivers/misc/c2port/Kconfig" + source "drivers/misc/eeprom/Kconfig" + ++config MACH_NEO1973 ++ bool ++ help ++ Common machine code for Openmoko GTAxx hardware ++ + endif # MISC_DEVICES ++ +diff -ruN --exclude='*.orig' --exclude='*.rej' linux-2.6.29-rc3.owrt/drivers/misc/Makefile linux-2.6.29-rc3.owrt.om/drivers/misc/Makefile +--- linux-2.6.29-rc3.owrt/drivers/misc/Makefile 2009-05-10 22:04:49.000000000 +0200 ++++ linux-2.6.29-rc3.owrt.om/drivers/misc/Makefile 2009-05-10 22:28:00.000000000 +0200 +@@ -20,3 +20,8 @@ + obj-$(CONFIG_HP_ILO) += hpilo.o + obj-$(CONFIG_C2PORT) += c2port/ + obj-y += eeprom/ ++obj-$(CONFIG_MACH_SMDK6410) += smdk6410-sleeptest.o ++obj-$(CONFIG_MACH_NEO1973) += neo1973_version.o \ ++ neo1973_pm_host.o \ ++ neo1973_pm_resume_reason.o ++ +diff -ruN --exclude='*.orig' --exclude='*.rej' linux-2.6.29-rc3.owrt/drivers/misc/neo1973_pm_charging_led.c linux-2.6.29-rc3.owrt.om/drivers/misc/neo1973_pm_charging_led.c +--- linux-2.6.29-rc3.owrt/drivers/misc/neo1973_pm_charging_led.c 1970-01-01 01:00:00.000000000 +0100 ++++ linux-2.6.29-rc3.owrt.om/drivers/misc/neo1973_pm_charging_led.c 2009-05-10 22:28:00.000000000 +0200 +@@ -0,0 +1,106 @@ ++/* ++ * Charging LED sysfs for the FIC Neo1973 GSM Phone ++ * (currently only implemented in GTA02 but ready for GTA01 implementation) ++ * ++ * (C) 2008 by Openmoko Inc. ++ * Author: Andy Green <andy@openmoko.com> ++ * All rights reserved. ++ * ++ * This program is free software; you can redistribute it and/or modify ++ * it under the terms of the GNU General Public License charging_led 2 as ++ * published by the Free Software Foundation ++ * ++ */ ++ ++#include <linux/module.h> ++#include <linux/init.h> ++#include <linux/kernel.h> ++#include <linux/platform_device.h> ++ ++#include <asm/hardware.h> ++#include <asm/mach-types.h> ++ ++#ifdef CONFIG_MACH_NEO1973_GTA02 ++#include <asm/arch/gta02.h> ++ ++static enum neo1973_charging_led_modes charging_mode; ++ ++static char *charging_led_mode_names[] = { ++ "Disabled", ++ "Aux LED", ++ "Power LED" ++}; ++ ++static ssize_t charging_led_read(struct device *dev, ++ struct device_attribute *attr, char *buf) ++{ ++ return sprintf(buf, "0x%03X\n", gta02_get_pcb_revision()); ++} ++ ++static ssize_t charging_led_read(struct device *dev, ++ struct device_attribute *attr, char *buf) ++{ ++ return sprintf(buf, "0x%03X\n", gta02_get_pcb_revision()); ++} ++ ++ ++static DEVICE_ATTR(pcb, 0644, charging_led_read, charging_led_write); ++ ++static struct attribute *neo1973_charging_led_sysfs_entries[] = { ++ &dev_attr_pcb.attr, ++ NULL ++}; ++ ++static struct attribute_group neo1973_charging_led_attr_group = { ++ .name = NULL, ++ .attrs = neo1973_charging_led_sysfs_entries, ++}; ++ ++static int __init neo1973_charging_led_probe(struct platform_device *pdev) ++{ ++ dev_info(&pdev->dev, "starting\n"); ++ ++ switch (machine_arch_type) { ++#ifdef CONFIG_MACH_NEO1973_GTA01 ++ case MACH_TYPE_NEO1973_GTA01: ++ return -EINVAL; ++#endif /* CONFIG_MACH_NEO1973_GTA01 */ ++ default: ++ break; ++ } ++ ++ return sysfs_create_group(&pdev->dev.kobj, ++ &neo1973_charging_led_attr_group); ++} ++ ++static int neo1973_charging_led_remove(struct platform_device *pdev) ++{ ++ sysfs_remove_group(&pdev->dev.kobj, &neo1973_charging_led_attr_group); ++ return 0; ++} ++ ++static struct platform_driver neo1973_charging_led_driver = { ++ .probe = neo1973_charging_led_probe, ++ .remove = neo1973_charging_led_remove, ++ .driver = { ++ .name = "neo1973-charging-led", ++ }, ++}; ++ ++static int __devinit neo1973_charging_led_init(void) ++{ ++ return platform_driver_register(&neo1973_charging_led_driver); ++} ++ ++static void neo1973_charging_led_exit(void) ++{ ++ platform_driver_unregister(&neo1973_charging_led_driver); ++} ++ ++module_init(neo1973_charging_led_init); ++module_exit(neo1973_charging_led_exit); ++ ++MODULE_LICENSE("GPL"); ++MODULE_AUTHOR("Andy Green <andy@openmoko.com>"); ++MODULE_DESCRIPTION("Neo1973 PCB charging_led"); ++#endif +diff -ruN --exclude='*.orig' --exclude='*.rej' linux-2.6.29-rc3.owrt/drivers/misc/neo1973_pm_host.c linux-2.6.29-rc3.owrt.om/drivers/misc/neo1973_pm_host.c +--- linux-2.6.29-rc3.owrt/drivers/misc/neo1973_pm_host.c 1970-01-01 01:00:00.000000000 +0100 ++++ linux-2.6.29-rc3.owrt.om/drivers/misc/neo1973_pm_host.c 2009-05-10 22:28:00.000000000 +0200 +@@ -0,0 +1,109 @@ ++/* ++ * Bluetooth PM code for the FIC Neo1973 GSM Phone ++ * ++ * (C) 2007 by Openmoko Inc. ++ * Author: Harald Welte <laforge@openmoko.org> ++ * All rights reserved. ++ * ++ * 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/init.h> ++#include <linux/kernel.h> ++#include <linux/platform_device.h> ++ ++#include <mach/hardware.h> ++#include <asm/mach-types.h> ++ ++#ifdef CONFIG_MACH_NEO1973_GTA02 ++#include <mach/gta02.h> ++#include <linux/mfd/pcf50633/gpio.h> ++ ++static ssize_t pm_host_read(struct device *dev, struct device_attribute *attr, ++ char *buf) ++{ ++ return sprintf(buf, "%d\n", ++ pcf50633_gpio_get(gta02_pcf, PCF50633_GPO) ++ == PCF50633_GPOCFG_GPOSEL_1); ++} ++ ++static ssize_t pm_host_write(struct device *dev, struct device_attribute *attr, ++ const char *buf, size_t count) ++{ ++ unsigned long on = simple_strtoul(buf, NULL, 10); ++ u8 val; ++ ++ if (on) ++ val = PCF50633_GPOCFG_GPOSEL_1; ++ else ++ val = PCF50633_GPOCFG_GPOSEL_0; ++ ++ ++ pcf50633_gpio_set(gta02_pcf, PCF50633_GPO, val); ++ ++ return count; ++} ++ ++static DEVICE_ATTR(hostmode, 0644, pm_host_read, pm_host_write); ++ ++static struct attribute *neo1973_pm_host_sysfs_entries[] = { ++ &dev_attr_hostmode.attr, ++ NULL ++}; ++ ++static struct attribute_group neo1973_pm_host_attr_group = { ++ .name = NULL, ++ .attrs = neo1973_pm_host_sysfs_entries, ++}; ++ ++static int __init neo1973_pm_host_probe(struct platform_device *pdev) ++{ ++ dev_info(&pdev->dev, "starting\n"); ++ ++ switch (machine_arch_type) { ++#ifdef CONFIG_MACH_NEO1973_GTA01 ++ case MACH_TYPE_NEO1973_GTA01: ++ return -EINVAL; ++#endif /* CONFIG_MACH_NEO1973_GTA01 */ ++ default: ++ break; ++ } ++ ++ return sysfs_create_group(&pdev->dev.kobj, &neo1973_pm_host_attr_group); ++} ++ ++static int neo1973_pm_host_remove(struct platform_device *pdev) ++{ ++ sysfs_remove_group(&pdev->dev.kobj, &neo1973_pm_host_attr_group); ++ return 0; ++} ++ ++static struct platform_driver neo1973_pm_host_driver = { ++ .probe = neo1973_pm_host_probe, ++ .remove = neo1973_pm_host_remove, ++ .driver = { ++ .name = "neo1973-pm-host", ++ }, ++}; ++ ++static int __devinit neo1973_pm_host_init(void) ++{ ++ return platform_driver_register(&neo1973_pm_host_driver); ++} ++ ++static void neo1973_pm_host_exit(void) ++{ ++ platform_driver_unregister(&neo1973_pm_host_driver); ++} ++ ++module_init(neo1973_pm_host_init); ++module_exit(neo1973_pm_host_exit); ++ ++MODULE_LICENSE("GPL"); ++MODULE_AUTHOR("Andy Green <andy@openmoko.com>"); ++MODULE_DESCRIPTION("Neo1973 USB Host Power Management"); ++#endif +diff -ruN --exclude='*.orig' --exclude='*.rej' linux-2.6.29-rc3.owrt/drivers/misc/neo1973_pm_resume_reason.c linux-2.6.29-rc3.owrt.om/drivers/misc/neo1973_pm_resume_reason.c +--- linux-2.6.29-rc3.owrt/drivers/misc/neo1973_pm_resume_reason.c 1970-01-01 01:00:00.000000000 +0100 ++++ linux-2.6.29-rc3.owrt.om/drivers/misc/neo1973_pm_resume_reason.c 2009-05-10 22:28:00.000000000 +0200 +@@ -0,0 +1,147 @@ ++/* ++ * Resume reason sysfs for the FIC Neo1973 GSM Phone ++ * ++ * (C) 2008 by Openmoko Inc. ++ * Author: Andy Green <andy@openmoko.com> ++ * All rights reserved. ++ * ++ * This program is free software; you can redistribute it and/or modify ++ * it under the terms of the GNU General Public License resume_reason 2 as ++ * published by the Free Software Foundation ++ * ++ */ ++ ++#include <linux/module.h> ++#include <linux/init.h> ++#include <linux/kernel.h> ++#include <linux/platform_device.h> ++#include <linux/io.h> ++ ++#include <mach/hardware.h> ++#include <asm/mach-types.h> ++ ++#ifdef CONFIG_MACH_NEO1973_GTA02 ++#include <mach/gta02.h> ++#include <linux/mfd/pcf50633/core.h> ++#endif ++ ++static unsigned int *gstatus4_mapped; ++static char *resume_reasons[][17] = { { /* GTA01 */ ++ "EINT00_NULL", ++ "EINT01_GSM", ++ "EINT02_NULL", ++ "EINT03_NULL", ++ "EINT04_JACK", ++ "EINT05_SDCARD", ++ "EINT06_AUXKEY", ++ "EINT07_HOLDKEY", ++ "EINT08_NULL", ++ "EINT09_NULL", ++ "EINT10_NULL", ++ "EINT11_NULL", ++ "EINT12_NULL", ++ "EINT13_NULL", ++ "EINT14_NULL", ++ "EINT15_NULL", ++ NULL ++}, { /* GTA02 */ ++ "EINT00_ACCEL1", ++ "EINT01_GSM", ++ "EINT02_BLUETOOTH", ++ "EINT03_DEBUGBRD", ++ "EINT04_JACK", ++ "EINT05_WLAN", ++ "EINT06_AUXKEY", ++ "EINT07_HOLDKEY", ++ "EINT08_ACCEL2", ++ "EINT09_PMU", ++ "EINT10_NULL", ++ "EINT11_NULL", ++ "EINT12_GLAMO", ++ "EINT13_NULL", ++ "EINT14_NULL", ++ "EINT15_NULL", ++ NULL ++} }; ++ ++static ssize_t resume_reason_read(struct device *dev, ++ struct device_attribute *attr, ++ char *buf) ++{ ++ int bit = 0; ++ char *end = buf; ++ int gta = !!machine_is_neo1973_gta02(); ++ ++ for (bit = 0; resume_reasons[gta][bit]; bit++) { ++ if ((*gstatus4_mapped) & (1 << bit)) ++ end += sprintf(end, "* %s\n", resume_reasons[gta][bit]); ++ else ++ end += sprintf(end, " %s\n", resume_reasons[gta][bit]); ++ ++#ifdef CONFIG_MACH_NEO1973_GTA02 ++ if ((gta) && (bit == 9)); /* PMU */ ++// end += pcf50633_report_resumers(gta02_pcf_pdata.pcf, end); ++#endif ++ } ++ ++ return end - buf; ++} ++ ++ ++static DEVICE_ATTR(resume_reason, 0644, resume_reason_read, NULL); ++ ++static struct attribute *neo1973_resume_reason_sysfs_entries[] = { ++ &dev_attr_resume_reason.attr, ++ NULL ++}; ++ ++static struct attribute_group neo1973_resume_reason_attr_group = { ++ .name = NULL, ++ .attrs = neo1973_resume_reason_sysfs_entries, ++}; ++ ++static int __init neo1973_resume_reason_probe(struct platform_device *pdev) ++{ ++ dev_info(&pdev->dev, "starting\n"); ++ ++ gstatus4_mapped = ioremap(0x560000BC /* GSTATUS4 */, 0x4); ++ if (!gstatus4_mapped) { ++ dev_err(&pdev->dev, "failed to ioremap() memory region\n"); ++ return -EINVAL; ++ } ++ ++ return sysfs_create_group(&pdev->dev.kobj, ++ &neo1973_resume_reason_attr_group); ++} ++ ++static int neo1973_resume_reason_remove(struct platform_device *pdev) ++{ ++ sysfs_remove_group(&pdev->dev.kobj, &neo1973_resume_reason_attr_group); ++ iounmap(gstatus4_mapped); ++ return 0; ++} ++ ++static struct platform_driver neo1973_resume_reason_driver = { ++ .probe = neo1973_resume_reason_probe, ++ .remove = neo1973_resume_reason_remove, ++ .driver = { ++ .name = "neo1973-resume", ++ }, ++}; ++ ++static int __devinit neo1973_resume_reason_init(void) ++{ ++ return platform_driver_register(&neo1973_resume_reason_driver); ++} ++ ++static void neo1973_resume_reason_exit(void) ++{ ++ platform_driver_unregister(&neo1973_resume_reason_driver); ++} ++ ++module_init(neo1973_resume_reason_init); ++module_exit(neo1973_resume_reason_exit); ++ ++MODULE_LICENSE("GPL"); ++MODULE_AUTHOR("Andy Green <andy@openmoko.com>"); ++MODULE_DESCRIPTION("Neo1973 resume_reason"); +diff -ruN --exclude='*.orig' --exclude='*.rej' linux-2.6.29-rc3.owrt/drivers/misc/neo1973_pm_usbhost.c linux-2.6.29-rc3.owrt.om/drivers/misc/neo1973_pm_usbhost.c +--- linux-2.6.29-rc3.owrt/drivers/misc/neo1973_pm_usbhost.c 1970-01-01 01:00:00.000000000 +0100 ++++ linux-2.6.29-rc3.owrt.om/drivers/misc/neo1973_pm_usbhost.c 2009-05-10 22:28:00.000000000 +0200 +@@ -0,0 +1,132 @@ ++/* ++ * Bluetooth PM code for the FIC Neo1973 GSM Phone ++ * ++ * (C) 2007 by OpenMoko Inc. ++ * Author: Harald Welte <laforge@openmoko.org> ++ * All rights reserved. ++ * ++ * 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/init.h> ++#include <linux/kernel.h> ++#include <linux/platform_device.h> ++ ++#include <asm/hardware.h> ++#include <asm/mach-types.h> ++ ++#ifdef CONFIG_MACH_NEO1973_GTA02 ++#include <asm/arch/gta02.h> ++#include <linux/pcf50633.h> ++#endif ++ ++static ssize_t pm_usbhost_read(struct device *dev, struct device_attribute *attr, ++ char *buf) ++{ ++ return sprintf(buf, "%d\n", ++ pcf50633_gpio_get(pcf50633_global, PCF50633_GPO)); ++} ++ ++static ssize_t pm_usbhost_write(struct device *dev, struct device_attribute *attr, ++ const char *buf, size_t count) ++{ ++ unsigned long on = simple_strtoul(buf, NULL, 10); ++ ++ pcf50633_gpio_set(pcf50633_global, PCF50633_GPO, on); ++ ++ return count; ++} ++ ++static DEVICE_ATTR(hostmode, 0644, pm_usbhost_read, pm_usbhost_write); ++ ++#ifdef CONFIG_PM ++static int neo1973_usbhost_suspend(struct platform_device *pdev, pm_message_t state) ++{ ++ dev_dbg(&pdev->dev, "suspending\n"); ++ /* FIXME: The PMU should save the PMU status, and the GPIO code should ++ * preserve the GPIO level, so there shouldn't be anything left to do ++ * for us, should there? */ ++ ++ return 0; ++} ++ ++static int neo1973_usbhost_resume(struct platform_device *pdev) ++{ ++ dev_dbg(&pdev->dev, "resuming\n"); ++ ++ return 0; ++} ++#else ++#define neo1973_usbhost_suspend NULL ++#define neo1973_usbhost_resume NULL ++#endif ++ ++static struct attribute *neo1973_usbhost_sysfs_entries[] = { ++ &dev_attr_hostmode.attr, ++ NULL ++}; ++ ++static struct attribute_group neo1973_usbhost_attr_group = { ++ .name = NULL, ++ .attrs = neo1973_usbhost_sysfs_entries, ++}; ++ ++static int __init neo1973_usbhost_probe(struct platform_device *pdev) ++{ ++ dev_info(&pdev->dev, "starting\n"); ++ ++ switch (machine_arch_type) { ++ ++#ifdef CONFIG_MACH_NEO1973_GTA01 ++ case MACH_TYPE_NEO1973_GTA01: ++ return -EINVAL; ++#endif /* CONFIG_MACH_NEO1973_GTA01 */ ++ ++#ifdef CONFIG_MACH_NEO1973_GTA02 ++ case MACH_TYPE_NEO1973_GTA02: ++/* race */ ++/* pcf50633_gpio_set(pcf50633_global, PCF50633_GPO, 0); */ ++ break; ++#endif /* CONFIG_MACH_NEO1973_GTA02 */ ++ } ++ ++ return sysfs_create_group(&pdev->dev.kobj, &neo1973_usbhost_attr_group); ++} ++ ++static int neo1973_usbhost_remove(struct platform_device *pdev) ++{ ++ sysfs_remove_group(&pdev->dev.kobj, &neo1973_usbhost_attr_group); ++ ++ return 0; ++} ++ ++static struct platform_driver neo1973_usbhost_driver = { ++ .probe = neo1973_usbhost_probe, ++ .remove = neo1973_usbhost_remove, ++ .suspend = neo1973_usbhost_suspend, ++ .resume = neo1973_usbhost_resume, ++ .driver = { ++ .name = "neo1973-pm-host", ++ }, ++}; ++ ++static int __devinit neo1973_usbhost_init(void) ++{ ++ return platform_driver_register(&neo1973_usbhost_driver); ++} ++ ++static void neo1973_usbhost_exit(void) ++{ ++ platform_driver_unregister(&neo1973_usbhost_driver); ++} ++ ++module_init(neo1973_usbhost_init); ++module_exit(neo1973_usbhost_exit); ++ ++MODULE_LICENSE("GPL"); ++MODULE_AUTHOR("Andy Green <andy@openmoko.com>"); ++MODULE_DESCRIPTION("Neo1973 USB Host Power Management"); +diff -ruN --exclude='*.orig' --exclude='*.rej' linux-2.6.29-rc3.owrt/drivers/misc/neo1973_version.c linux-2.6.29-rc3.owrt.om/drivers/misc/neo1973_version.c +--- linux-2.6.29-rc3.owrt/drivers/misc/neo1973_version.c 1970-01-01 01:00:00.000000000 +0100 ++++ linux-2.6.29-rc3.owrt.om/drivers/misc/neo1973_version.c 2009-05-10 22:28:00.000000000 +0200 +@@ -0,0 +1,90 @@ ++/* ++ * PCB version sysfs for the FIC Neo1973 GSM Phone ++ * ++ * (C) 2007 by Openmoko Inc. ++ * Author: Andy Green <andy@openmoko.com> ++ * All rights reserved. ++ * ++ * 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/init.h> ++#include <linux/kernel.h> ++#include <linux/platform_device.h> ++ ++#include <mach/hardware.h> ++#include <asm/mach-types.h> ++ ++#ifdef CONFIG_MACH_NEO1973_GTA02 ++#include <mach/gta02.h> ++ ++static ssize_t version_read(struct device *dev, struct device_attribute *attr, ++ char *buf) ++{ ++ return sprintf(buf, "0x%03X\n", gta02_get_pcb_revision()); ++} ++ ++ ++static DEVICE_ATTR(pcb, 0644, version_read, NULL); ++ ++static struct attribute *neo1973_version_sysfs_entries[] = { ++ &dev_attr_pcb.attr, ++ NULL ++}; ++ ++static struct attribute_group neo1973_version_attr_group = { ++ .name = NULL, ++ .attrs = neo1973_version_sysfs_entries, ++}; ++ ++static int __init neo1973_version_probe(struct platform_device *pdev) ++{ ++ dev_info(&pdev->dev, "starting\n"); ++ ++ switch (machine_arch_type) { ++#ifdef CONFIG_MACH_NEO1973_GTA01 ++ case MACH_TYPE_NEO1973_GTA01: ++ return -EINVAL; ++#endif /* CONFIG_MACH_NEO1973_GTA01 */ ++ default: ++ break; ++ } ++ ++ return sysfs_create_group(&pdev->dev.kobj, &neo1973_version_attr_group); ++} ++ ++static int neo1973_version_remove(struct platform_device *pdev) ++{ ++ sysfs_remove_group(&pdev->dev.kobj, &neo1973_version_attr_group); ++ return 0; ++} ++ ++static struct platform_driver neo1973_version_driver = { ++ .probe = neo1973_version_probe, ++ .remove = neo1973_version_remove, ++ .driver = { ++ .name = "neo1973-version", ++ }, ++}; ++ ++static int __devinit neo1973_version_init(void) ++{ ++ return platform_driver_register(&neo1973_version_driver); ++} ++ ++static void neo1973_version_exit(void) ++{ ++ platform_driver_unregister(&neo1973_version_driver); ++} ++ ++module_init(neo1973_version_init); ++module_exit(neo1973_version_exit); ++ ++MODULE_LICENSE("GPL"); ++MODULE_AUTHOR("Andy Green <andy@openmoko.com>"); ++MODULE_DESCRIPTION("Neo1973 PCB version"); ++#endif +diff -ruN --exclude='*.orig' --exclude='*.rej' linux-2.6.29-rc3.owrt/drivers/misc/smdk6410-sleeptest.c linux-2.6.29-rc3.owrt.om/drivers/misc/smdk6410-sleeptest.c +--- linux-2.6.29-rc3.owrt/drivers/misc/smdk6410-sleeptest.c 1970-01-01 01:00:00.000000000 +0100 ++++ linux-2.6.29-rc3.owrt.om/drivers/misc/smdk6410-sleeptest.c 2009-05-10 22:28:00.000000000 +0200 +@@ -0,0 +1,65 @@ ++/* linux/drivers/misc/smdk6410-sleeptest.c ++ * ++ * Copyright 2008 Simtec Electronics ++ * Ben Dooks <ben@simtec.co.uk> ++ * http://armlinux.simtec.co.uk/ ++ * ++ * This program is free software; you can redistribute it and/or modify ++ * it under the terms of the GNU General Public License version 2 as ++ * published by the Free Software Foundation. ++*/ ++ ++#include <linux/init.h> ++#include <linux/kernel.h> ++#include <linux/module.h> ++#include <linux/init.h> ++#include <linux/gpio.h> ++#include <linux/err.h> ++#include <linux/interrupt.h> ++ ++#include <plat/gpio-cfg.h> ++ ++static irqreturn_t sleep_action(int irq, void *pw) ++{ ++ printk(KERN_INFO "%s: irq %d\n", __func__, irq); ++ return IRQ_HANDLED; ++} ++ ++static void sleep_setup(unsigned int irq, unsigned int gpio) ++{ ++ int ret; ++ ++ WARN_ON(s3c_gpio_cfgpin(gpio, S3C_GPIO_SFN(2)) < 0); ++ WARN_ON(s3c_gpio_setpull(gpio, S3C_GPIO_PULL_UP) < 0); ++ ++ ret = request_irq(irq, sleep_action, IRQF_TRIGGER_FALLING, ++ "sleep", NULL); ++ if (ret < 0) ++ printk(KERN_ERR "%s: request_irq() failed\n", __func__); ++ ++ ret = set_irq_wake(irq, 1); ++ if (ret < 0) ++ printk(KERN_ERR "%s: set_irq_wake() failed\n", __func__); ++} ++ ++static void sleep_led(unsigned int gpio) ++{ ++// gpio_request(gpio, "sleep led"); ++// gpio_direction_output(gpio, 0); ++} ++ ++static __init int smdk6410_sleeptest_init(void) ++{ ++ sleep_setup(IRQ_EINT(10), S3C64XX_GPN(10)); ++// sleep_led(S3C64XX_GPN(15)); ++// sleep_led(S3C64XX_GPN(14)); ++// sleep_led(S3C64XX_GPN(13)); ++// sleep_led(S3C64XX_GPN(12)); ++ ++ return 0; ++} ++ ++module_init(smdk6410_sleeptest_init); ++ ++MODULE_AUTHOR("Ben Dooks <ben@simtec.co.uk>"); ++MODULE_LICENSE("GPL"); +diff -ruN --exclude='*.orig' --exclude='*.rej' linux-2.6.29-rc3.owrt/drivers/mmc/core/core.c linux-2.6.29-rc3.owrt.om/drivers/mmc/core/core.c +--- linux-2.6.29-rc3.owrt/drivers/mmc/core/core.c 2009-05-10 22:04:48.000000000 +0200 ++++ linux-2.6.29-rc3.owrt.om/drivers/mmc/core/core.c 2009-05-10 22:28:00.000000000 +0200 +@@ -58,10 +58,11 @@ + /* + * Internal function. Flush all scheduled work from the MMC work queue. + */ +-static void mmc_flush_scheduled_work(void) ++void mmc_flush_scheduled_work(void) + { + flush_workqueue(workqueue); + } ++EXPORT_SYMBOL_GPL(mmc_flush_scheduled_work); + + /** + * mmc_request_done - finish processing an MMC request +@@ -572,7 +573,13 @@ + */ + static void mmc_power_up(struct mmc_host *host) + { +- int bit = fls(host->ocr_avail) - 1; ++ int bit; ++ ++ /* If ocr is set, we use it */ ++ if (host->ocr) ++ bit = ffs(host->ocr) - 1; ++ else ++ bit = fls(host->ocr_avail) - 1; + + host->ios.vdd = bit; + if (mmc_host_is_spi(host)) { +diff -ruN --exclude='*.orig' --exclude='*.rej' linux-2.6.29-rc3.owrt/drivers/mmc/host/Kconfig linux-2.6.29-rc3.owrt.om/drivers/mmc/host/Kconfig +--- linux-2.6.29-rc3.owrt/drivers/mmc/host/Kconfig 2009-05-10 22:08:43.000000000 +0200 ++++ linux-2.6.29-rc3.owrt.om/drivers/mmc/host/Kconfig 2009-05-10 22:28:00.000000000 +0200 +@@ -48,6 +48,18 @@ + + If unsure, say N. + ++config MMC_SDHCI_S3C ++ tristate "SDHCI support on Samsung S3C SoC" ++ depends on MMC_SDHCI && (PLAT_S3C24XX || PLAT_S3C64XX) ++ help ++ This selects the Secure Digital Host Controller Interface (SDHCI) ++ often referrered to as the HSMMC block in some of the Samsung S3C ++ range of SoC. ++ ++ If you have a controller with this interface, say Y or M here. ++ ++ If unsure, say N. ++ + config MMC_RICOH_MMC + tristate "Ricoh MMC Controller Disabler (EXPERIMENTAL)" + depends on MMC_SDHCI_PCI +diff -ruN --exclude='*.orig' --exclude='*.rej' linux-2.6.29-rc3.owrt/drivers/mmc/host/Makefile linux-2.6.29-rc3.owrt.om/drivers/mmc/host/Makefile +--- linux-2.6.29-rc3.owrt/drivers/mmc/host/Makefile 2009-05-10 22:08:43.000000000 +0200 ++++ linux-2.6.29-rc3.owrt.om/drivers/mmc/host/Makefile 2009-05-10 22:28:00.000000000 +0200 +@@ -11,6 +11,7 @@ + obj-$(CONFIG_MMC_IMX) += imxmmc.o + obj-$(CONFIG_MMC_SDHCI) += sdhci.o + obj-$(CONFIG_MMC_SDHCI_PCI) += sdhci-pci.o ++obj-$(CONFIG_MMC_SDHCI_S3C) += sdhci-s3c.o + obj-$(CONFIG_MMC_RICOH_MMC) += ricoh_mmc.o + obj-$(CONFIG_MMC_WBSD) += wbsd.o + obj-$(CONFIG_MMC_AU1X) += au1xmmc.o +diff -ruN --exclude='*.orig' --exclude='*.rej' linux-2.6.29-rc3.owrt/drivers/mmc/host/s3cmci.c linux-2.6.29-rc3.owrt.om/drivers/mmc/host/s3cmci.c +--- linux-2.6.29-rc3.owrt/drivers/mmc/host/s3cmci.c 2009-05-10 22:08:43.000000000 +0200 ++++ linux-2.6.29-rc3.owrt.om/drivers/mmc/host/s3cmci.c 2009-05-10 22:28:00.000000000 +0200 +@@ -2,6 +2,7 @@ + * linux/drivers/mmc/s3cmci.h - Samsung S3C MCI driver + * + * Copyright (C) 2004-2006 maintech GmbH, Thomas Kleffel <tk@maintech.de> ++ * Copyright (C) 2007 Harald Welte <laforge@gnumonks.org> + * + * Current driver maintained by Ben Dooks and Simtec Electronics + * Copyright (C) 2008 Simtec Electronics <ben-linux@fluff.org> +@@ -24,9 +25,18 @@ + + #include <mach/regs-sdi.h> + #include <mach/regs-gpio.h> ++#include <mach/hardware.h> + + #include <plat/mci.h> + ++#include <asm/dma.h> ++#include <asm/dma-mapping.h> ++ ++#include <asm/io.h> ++#include <mach/regs-gpio.h> ++#include <mach/mci.h> ++#include <mach/dma.h> ++ + #include "s3cmci.h" + + #define DRIVER_NAME "s3c-mci" +@@ -47,6 +57,9 @@ + static const int dbgmap_info = dbg_info | dbg_conf; + static const int dbgmap_debug = dbg_err | dbg_debug; + ++static int f_max = -1; /* override maximum frequency limit */ ++static int persist; /* keep interface alive across suspend/resume */ ++ + #define dbg(host, channels, args...) \ + do { \ + if (dbgmap_err & channels) \ +@@ -280,8 +293,11 @@ + * an even multiple of 4. */ + if (fifo >= host->pio_bytes) + fifo = host->pio_bytes; +- else ++ else { + fifo -= fifo & 3; ++ if (!fifo) ++ break; ++ } + + host->pio_bytes -= fifo; + host->pio_count += fifo; +@@ -353,8 +369,11 @@ + * words, so round down to an even multiple of 4. */ + if (fifo >= host->pio_bytes) + fifo = host->pio_bytes; +- else ++ else { + fifo -= fifo & 3; ++ if (!fifo) ++ break; ++ } + + host->pio_bytes -= fifo; + host->pio_count += fifo; +@@ -373,7 +392,6 @@ + { + struct s3cmci_host *host = (struct s3cmci_host *) data; + +- + disable_irq(host->irq); + + if (host->pio_active == XFER_WRITE) +@@ -614,7 +632,6 @@ + + spin_unlock_irqrestore(&host->complete_lock, iflags); + return IRQ_HANDLED; +- + } + + /* +@@ -789,12 +806,11 @@ + + last_source = source; + +- s3c2410_dma_devconfig(host->dma, source, 3, ++ s3c2410_dma_devconfig(host->dma, source, + host->mem->start + host->sdidata); + + if (!setup_ok) { +- s3c2410_dma_config(host->dma, 4, +- (S3C2410_DCON_HWTRIG | S3C2410_DCON_CH0_SDI)); ++ s3c2410_dma_config(host->dma, 4); + s3c2410_dma_set_buffdone_fn(host->dma, + s3cmci_dma_done_callback); + s3c2410_dma_setflags(host->dma, S3C2410_DMAF_AUTOSTART); +@@ -1027,6 +1043,7 @@ + dbg(host, dbg_err, "data prepare error %d\n", res); + cmd->error = res; + cmd->data->error = res; ++ cmd->data->error = -EIO; + + mmc_request_done(mmc, mrq); + return; +@@ -1264,10 +1281,8 @@ + host->is2440 = is2440; + + host->pdata = pdev->dev.platform_data; +- if (!host->pdata) { +- pdev->dev.platform_data = &s3cmci_def_pdata; ++ if (!host->pdata) + host->pdata = &s3cmci_def_pdata; +- } + + spin_lock_init(&host->complete_lock); + tasklet_init(&host->pio_tasklet, pio_tasklet, (unsigned long) host); +@@ -1380,6 +1395,18 @@ + mmc->f_min = host->clk_rate / (host->clk_div * 256); + mmc->f_max = host->clk_rate / host->clk_div; + ++ if (f_max >= 0) { ++ unsigned f = f_max; ++ ++ if (f < mmc->f_min) ++ f = mmc->f_min; ++ if (mmc->f_max > f) { ++ dev_info(&pdev->dev, "f_max lowered from %u to %u Hz\n", ++ mmc->f_max, f); ++ mmc->f_max = f; ++ } ++ } ++ + if (host->pdata->ocr_avail) + mmc->ocr_avail = host->pdata->ocr_avail; + +@@ -1492,18 +1519,60 @@ + + #ifdef CONFIG_PM + ++static int save_regs(struct mmc_host *mmc) ++{ ++ struct s3cmci_host *host = mmc_priv(mmc); ++ unsigned long flags; ++ unsigned from; ++ u32 *to = host->saved; ++ ++ mmc_flush_scheduled_work(); ++ ++ local_irq_save(flags); ++ for (from = S3C2410_SDICON; from != S3C2410_SDIIMSK+4; from += 4) ++ if (from != host->sdidata) ++ *to++ = readl(host->base + from); ++ BUG_ON(to-host->saved != ARRAY_SIZE(host->saved)); ++ local_irq_restore(flags); ++ ++ return 0; ++} ++ ++static int restore_regs(struct mmc_host *mmc) ++{ ++ struct s3cmci_host *host = mmc_priv(mmc); ++ unsigned long flags; ++ unsigned to; ++ u32 *from = host->saved; ++ ++ /* ++ * Before we begin with the necromancy, make sure we don't ++ * inadvertently start something we'll regret microseconds later. ++ */ ++ from[S3C2410_SDICMDCON - S3C2410_SDICON] = 0; ++ ++ local_irq_save(flags); ++ for (to = S3C2410_SDICON; to != S3C2410_SDIIMSK+4; to += 4) ++ if (to != host->sdidata) ++ writel(*from++, host->base + to); ++ BUG_ON(from-host->saved != ARRAY_SIZE(host->saved)); ++ local_irq_restore(flags); ++ ++ return 0; ++} ++ + static int s3cmci_suspend(struct platform_device *dev, pm_message_t state) + { + struct mmc_host *mmc = platform_get_drvdata(dev); + +- return mmc_suspend_host(mmc, state); ++ return persist ? save_regs(mmc) : mmc_suspend_host(mmc, state); + } + + static int s3cmci_resume(struct platform_device *dev) + { + struct mmc_host *mmc = platform_get_drvdata(dev); + +- return mmc_resume_host(mmc); ++ return persist ? restore_regs(mmc) : mmc_resume_host(mmc); + } + + #else /* CONFIG_PM */ +@@ -1561,9 +1630,13 @@ + module_init(s3cmci_init); + module_exit(s3cmci_exit); + ++module_param(f_max, int, 0644); ++module_param(persist, int, 0644); ++ + MODULE_DESCRIPTION("Samsung S3C MMC/SD Card Interface driver"); + MODULE_LICENSE("GPL v2"); + MODULE_AUTHOR("Thomas Kleffel <tk@maintech.de>, Ben Dooks <ben-linux@fluff.org>"); + MODULE_ALIAS("platform:s3c2410-sdi"); + MODULE_ALIAS("platform:s3c2412-sdi"); + MODULE_ALIAS("platform:s3c2440-sdi"); ++ +diff -ruN --exclude='*.orig' --exclude='*.rej' linux-2.6.29-rc3.owrt/drivers/mmc/host/s3cmci.h linux-2.6.29-rc3.owrt.om/drivers/mmc/host/s3cmci.h +--- linux-2.6.29-rc3.owrt/drivers/mmc/host/s3cmci.h 2009-05-10 22:04:48.000000000 +0200 ++++ linux-2.6.29-rc3.owrt.om/drivers/mmc/host/s3cmci.h 2009-05-10 22:28:00.000000000 +0200 +@@ -8,6 +8,10 @@ + * published by the Free Software Foundation. + */ + ++ ++#include <mach/regs-sdi.h> ++#include <linux/regulator/consumer.h> ++ + /* FIXME: DMA Resource management ?! */ + #define S3CMCI_DMA 0 + +@@ -68,7 +72,16 @@ + unsigned int ccnt, dcnt; + struct tasklet_struct pio_tasklet; + ++ /* ++ * Here's where we save the registers during suspend. Note that we skip ++ * SDIDATA, which is at different positions on 2410 and 2440, so ++ * there's no "+1" in the array size. ++ */ ++ u32 saved[(S3C2410_SDIIMSK-S3C2410_SDICON)/4]; ++ + #ifdef CONFIG_CPU_FREQ + struct notifier_block freq_transition; + #endif ++ ++ struct regulator *regulator; + }; +diff -ruN --exclude='*.orig' --exclude='*.rej' linux-2.6.29-rc3.owrt/drivers/mmc/host/sdhci.c linux-2.6.29-rc3.owrt.om/drivers/mmc/host/sdhci.c +--- linux-2.6.29-rc3.owrt/drivers/mmc/host/sdhci.c 2009-05-10 22:08:43.000000000 +0200 ++++ linux-2.6.29-rc3.owrt.om/drivers/mmc/host/sdhci.c 2009-05-10 22:28:00.000000000 +0200 +@@ -78,6 +78,11 @@ + readl(host->ioaddr + SDHCI_CAPABILITIES), + readl(host->ioaddr + SDHCI_MAX_CURRENT)); + ++ if (host->flags & SDHCI_USE_ADMA) ++ printk(KERN_DEBUG DRIVER_NAME ": ADMA Err: 0x%08x | ADMA Ptr: 0x%08x\n", ++ readl(host->ioaddr + SDHCI_ADMA_ERROR), ++ readl(host->ioaddr + SDHCI_ADMA_ADDRESS)); ++ + printk(KERN_DEBUG DRIVER_NAME ": ===========================================\n"); + } + +@@ -736,6 +741,23 @@ + writew(mode, host->ioaddr + SDHCI_TRANSFER_MODE); + } + ++static void shdci_check_dma_overrun(struct sdhci_host *host, struct mmc_data *data) ++{ ++ u32 dma_pos = readl(host->ioaddr + SDHCI_DMA_ADDRESS); ++ u32 dma_start = sg_dma_address(data->sg); ++ u32 dma_end = dma_start + data->sg->length; ++ ++ /* Test whether we ended up moving more data than ++ * was originally requested. */ ++ ++ if (dma_pos <= dma_end) ++ return; ++ ++ printk(KERN_ERR "%s: dma overrun, dma %08x, req %08x..%08x\n", ++ mmc_hostname(host->mmc), dma_pos, ++ dma_start, dma_end); ++} ++ + static void sdhci_finish_data(struct sdhci_host *host) + { + struct mmc_data *data; +@@ -749,6 +771,8 @@ + if (host->flags & SDHCI_USE_ADMA) + sdhci_adma_table_post(host, data); + else { ++ shdci_check_dma_overrun(host, data); ++ + dma_unmap_sg(mmc_dev(host->mmc), data->sg, + data->sg_len, (data->flags & MMC_DATA_READ) ? + DMA_FROM_DEVICE : DMA_TO_DEVICE); +@@ -888,13 +912,18 @@ + + static void sdhci_set_clock(struct sdhci_host *host, unsigned int clock) + { ++ if (clock == host->clock) ++ return; ++ ++ host->ops->change_clock(host, clock); ++} ++ ++void sdhci_change_clock(struct sdhci_host *host, unsigned int clock) ++{ + int div; + u16 clk; + unsigned long timeout; + +- if (clock == host->clock) +- return; +- + writew(0, host->ioaddr + SDHCI_CLOCK_CONTROL); + + if (clock == 0) +@@ -931,6 +960,8 @@ + host->clock = clock; + } + ++EXPORT_SYMBOL_GPL(sdhci_set_clock); ++ + static void sdhci_set_power(struct sdhci_host *host, unsigned short power) + { + u8 pwr; +@@ -1004,12 +1035,13 @@ + #endif + + host->mrq = mrq; +- ++/* + if (!(readl(host->ioaddr + SDHCI_PRESENT_STATE) & SDHCI_CARD_PRESENT) + || (host->flags & SDHCI_DEVICE_DEAD)) { + host->mrq->cmd->error = -ENOMEDIUM; + tasklet_schedule(&host->finish_tasklet); + } else ++*/ + sdhci_send_command(host, mrq->cmd); + + mmiowb(); +@@ -1038,6 +1070,9 @@ + sdhci_init(host); + } + ++ if (host->ops->set_ios) ++ host->ops->set_ios(host, ios); ++ + sdhci_set_clock(host, ios->clock); + + if (ios->power_mode == MMC_POWER_OFF) +@@ -1141,7 +1176,7 @@ + host = (struct sdhci_host*)param; + + spin_lock_irqsave(&host->lock, flags); +- ++/* + if (!(readl(host->ioaddr + SDHCI_PRESENT_STATE) & SDHCI_CARD_PRESENT)) { + if (host->mrq) { + printk(KERN_ERR "%s: Card removed during transfer!\n", +@@ -1156,7 +1191,7 @@ + tasklet_schedule(&host->finish_tasklet); + } + } +- ++*/ + spin_unlock_irqrestore(&host->lock, flags); + + mmc_detect_change(host->mmc, msecs_to_jiffies(200)); +@@ -1288,11 +1323,24 @@ + * controllers. + */ + if (host->cmd->flags & MMC_RSP_BUSY) { ++ u32 present; ++ + if (host->cmd->data) + DBG("Cannot wait for busy signal when also " + "doing a data transfer"); +- else ++ else if (!(host->quirks & SDHCI_QUIRK_NO_TCIRQ_ON_NOT_BUSY)) + return; ++ ++ /* The Samsung SDHCI does not seem to provide an INT_DATA_END ++ * when the system goes non-busy, so check the state of the ++ * transfer by reading SDHCI_PRESENT_STATE to see if the ++ * controller is ready ++ */ ++ ++ present = readl(host->ioaddr + SDHCI_PRESENT_STATE); ++ DBG("busy? present %08x, intstat %08x\n", present, intmask); ++ ++ /* fall through and take the SDHCI_INT_RESPONSE */ + } + + if (intmask & SDHCI_INT_RESPONSE) +@@ -1609,17 +1657,23 @@ + mmc_dev(host->mmc)->dma_mask = &host->dma_mask; + } + +- host->max_clk = +- (caps & SDHCI_CLOCK_BASE_MASK) >> SDHCI_CLOCK_BASE_SHIFT; ++ if (host->ops->get_max_clock) ++ host->max_clk = host->ops->get_max_clock(host); ++ else { ++ host->max_clk = (caps & SDHCI_CLOCK_BASE_MASK) >> SDHCI_CLOCK_BASE_SHIFT; ++ host->max_clk *= 1000000; ++ } + if (host->max_clk == 0) { + printk(KERN_ERR "%s: Hardware doesn't specify base clock " + "frequency.\n", mmc_hostname(mmc)); + return -ENODEV; + } +- host->max_clk *= 1000000; + +- host->timeout_clk = +- (caps & SDHCI_TIMEOUT_CLK_MASK) >> SDHCI_TIMEOUT_CLK_SHIFT; ++ if (host->ops->get_timeout_clock) ++ host->timeout_clk = host->ops->get_timeout_clock(host); ++ else ++ host->timeout_clk = ++ (caps & SDHCI_TIMEOUT_CLK_MASK) >> SDHCI_TIMEOUT_CLK_SHIFT; + if (host->timeout_clk == 0) { + printk(KERN_ERR "%s: Hardware doesn't specify timeout clock " + "frequency.\n", mmc_hostname(mmc)); +diff -ruN --exclude='*.orig' --exclude='*.rej' linux-2.6.29-rc3.owrt/drivers/mmc/host/sdhci.h linux-2.6.29-rc3.owrt.om/drivers/mmc/host/sdhci.h +--- linux-2.6.29-rc3.owrt/drivers/mmc/host/sdhci.h 2009-05-10 22:08:43.000000000 +0200 ++++ linux-2.6.29-rc3.owrt.om/drivers/mmc/host/sdhci.h 2009-05-10 22:28:00.000000000 +0200 +@@ -57,6 +57,7 @@ + #define SDHCI_DATA_AVAILABLE 0x00000800 + #define SDHCI_CARD_PRESENT 0x00010000 + #define SDHCI_WRITE_PROTECT 0x00080000 ++#define SDHCI_DATA_BIT(x) (1 << ((x) + 20)) + + #define SDHCI_HOST_CONTROL 0x28 + #define SDHCI_CTRL_LED 0x01 +@@ -210,6 +211,8 @@ + #define SDHCI_QUIRK_BROKEN_SMALL_PIO (1<<13) + /* Controller supports high speed but doesn't have the caps bit set */ + #define SDHCI_QUIRK_FORCE_HIGHSPEED (1<<14) ++/* Controller does not provide transfer-complete interrupt when not busy */ ++#define SDHCI_QUIRK_NO_TCIRQ_ON_NOT_BUSY (1<<15) + + int irq; /* Device IRQ */ + void __iomem * ioaddr; /* Mapped address */ +@@ -267,6 +270,14 @@ + + struct sdhci_ops { + int (*enable_dma)(struct sdhci_host *host); ++ unsigned int (*get_max_clock)(struct sdhci_host *host); ++ unsigned int (*get_timeout_clock)(struct sdhci_host *host); ++ ++ void (*change_clock)(struct sdhci_host *host, ++ unsigned int clock); ++ ++ void (*set_ios)(struct sdhci_host *host, ++ struct mmc_ios *ios); + }; + + +@@ -274,6 +285,8 @@ + size_t priv_size); + extern void sdhci_free_host(struct sdhci_host *host); + ++extern void sdhci_change_clock(struct sdhci_host *host, unsigned int clock); ++ + static inline void *sdhci_priv(struct sdhci_host *host) + { + return (void *)host->private; +diff -ruN --exclude='*.orig' --exclude='*.rej' linux-2.6.29-rc3.owrt/drivers/mmc/host/sdhci-pci.c linux-2.6.29-rc3.owrt.om/drivers/mmc/host/sdhci-pci.c +--- linux-2.6.29-rc3.owrt/drivers/mmc/host/sdhci-pci.c 2009-05-10 22:08:43.000000000 +0200 ++++ linux-2.6.29-rc3.owrt.om/drivers/mmc/host/sdhci-pci.c 2009-05-10 22:28:00.000000000 +0200 +@@ -391,6 +391,7 @@ + + static struct sdhci_ops sdhci_pci_ops = { + .enable_dma = sdhci_pci_enable_dma, ++ .change_clock = sdhci_change_clock, + }; + + /*****************************************************************************\ +diff -ruN --exclude='*.orig' --exclude='*.rej' linux-2.6.29-rc3.owrt/drivers/mmc/host/sdhci-s3c.c linux-2.6.29-rc3.owrt.om/drivers/mmc/host/sdhci-s3c.c +--- linux-2.6.29-rc3.owrt/drivers/mmc/host/sdhci-s3c.c 1970-01-01 01:00:00.000000000 +0100 ++++ linux-2.6.29-rc3.owrt.om/drivers/mmc/host/sdhci-s3c.c 2009-05-10 22:28:00.000000000 +0200 +@@ -0,0 +1,419 @@ ++/* linux/drivers/mmc/host/sdhci-s3c.c ++ * ++ * Copyright 2008 Openmoko Inc. ++ * Copyright 2008 Simtec Electronics ++ * Ben Dooks <ben@simtec.co.uk> ++ * http://armlinux.simtec.co.uk/ ++ * ++ * SDHCI (HSMMC) support for Samsung SoC ++ * ++ * 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/delay.h> ++#include <linux/dma-mapping.h> ++#include <linux/platform_device.h> ++#include <linux/clk.h> ++#include <linux/io.h> ++ ++#include <linux/mmc/host.h> ++ ++#include <plat/regs-sdhci.h> ++#include <plat/sdhci.h> ++ ++#include "sdhci.h" ++ ++#define MAX_BUS_CLK (4) ++ ++struct sdhci_s3c { ++ struct sdhci_host *host; ++ struct platform_device *pdev; ++ struct resource *ioarea; ++ struct s3c_sdhci_platdata *pdata; ++ unsigned int cur_clk; ++ ++ struct clk *clk_io; /* clock for io bus */ ++ struct clk *clk_bus[MAX_BUS_CLK]; ++}; ++ ++static inline struct sdhci_s3c *to_s3c(struct sdhci_host *host) ++{ ++ return sdhci_priv(host); ++} ++ ++static u32 get_curclk(u32 ctrl2) ++{ ++ ctrl2 &= S3C_SDHCI_CTRL2_SELBASECLK_MASK; ++ ctrl2 >>= S3C_SDHCI_CTRL2_SELBASECLK_SHIFT; ++ ++ return ctrl2; ++} ++ ++static void sdhci_s3c_check_sclk(struct sdhci_host *host) ++{ ++ struct sdhci_s3c *ourhost = to_s3c(host); ++ u32 tmp = readl(host->ioaddr + S3C_SDHCI_CONTROL2); ++ ++ if (get_curclk(tmp) != ourhost->cur_clk) { ++ dev_dbg(&ourhost->pdev->dev, "restored ctrl2 clock setting\n"); ++ ++ tmp &= ~S3C_SDHCI_CTRL2_SELBASECLK_MASK; ++ tmp |= ourhost->cur_clk << S3C_SDHCI_CTRL2_SELBASECLK_SHIFT; ++ writel(tmp, host->ioaddr + 0x80); ++ } ++} ++ ++static unsigned int sdhci_s3c_get_max_clk(struct sdhci_host *host) ++{ ++ struct sdhci_s3c *ourhost = to_s3c(host); ++ struct clk *busclk; ++ unsigned int rate, max; ++ int clk; ++ ++ /* note, a reset will reset the clock source */ ++ ++ sdhci_s3c_check_sclk(host); ++ ++ for (max = 0, clk = 0; clk < MAX_BUS_CLK; clk++) { ++ busclk = ourhost->clk_bus[clk]; ++ if (!busclk) ++ continue; ++ ++ rate = clk_get_rate(busclk); ++ if (rate > max) ++ max = rate; ++ } ++ ++ return max; ++} ++ ++static unsigned int sdhci_s3c_get_timeout_clk(struct sdhci_host *host) ++{ ++ return sdhci_s3c_get_max_clk(host) / 1000000; ++} ++ ++static void sdhci_s3c_set_ios(struct sdhci_host *host, ++ struct mmc_ios *ios) ++{ ++ struct sdhci_s3c *ourhost = to_s3c(host); ++ struct s3c_sdhci_platdata *pdata = ourhost->pdata; ++ int width; ++ ++ sdhci_s3c_check_sclk(host); ++ ++ if (ios->power_mode != MMC_POWER_OFF) { ++ switch (ios->bus_width) { ++ case MMC_BUS_WIDTH_4: ++ width = 4; ++ break; ++ case MMC_BUS_WIDTH_1: ++ width = 1; ++ break; ++ default: ++ BUG(); ++ } ++ ++ if (pdata->cfg_gpio) ++ pdata->cfg_gpio(ourhost->pdev, width); ++ } ++ ++ if (pdata->cfg_card) ++ pdata->cfg_card(ourhost->pdev, host->ioaddr, ++ ios, host->mmc->card); ++} ++ ++static unsigned int sdhci_s3c_consider_clock(struct sdhci_s3c *ourhost, ++ unsigned int src, ++ unsigned int wanted) ++{ ++ unsigned long rate; ++ struct clk *clksrc = ourhost->clk_bus[src]; ++ int div; ++ ++ if (!clksrc) ++ return UINT_MAX; ++ ++ rate = clk_get_rate(clksrc); ++ ++ for (div = 1; div < 256; div *= 2) { ++ if ((rate / div) <= wanted) ++ break; ++ } ++ ++ dev_dbg(&ourhost->pdev->dev, "clk %d: rate %ld, want %d, got %ld\n", ++ src, rate, wanted, rate / div); ++ ++ return (wanted - (rate / div)); ++} ++ ++static void sdhci_s3c_change_clock(struct sdhci_host *host, unsigned int clock) ++{ ++ struct sdhci_s3c *ourhost = to_s3c(host); ++ unsigned int best = UINT_MAX; ++ unsigned int delta; ++ int best_src = 0; ++ int src; ++ u32 ctrl; ++ ++ for (src = 0; src < MAX_BUS_CLK; src++) { ++ delta = sdhci_s3c_consider_clock(ourhost, src, clock); ++ if (delta < best) { ++ best = delta; ++ best_src = src; ++ } ++ } ++ ++ dev_dbg(&ourhost->pdev->dev, ++ "selected source %d, clock %d, delta %d\n", ++ best_src, clock, best); ++ ++ /* turn clock off to card before changing clock source */ ++ writew(0, host->ioaddr + SDHCI_CLOCK_CONTROL); ++ ++ /* select the new clock source */ ++ ++ if (ourhost->cur_clk != best_src) { ++ struct clk *clk = ourhost->clk_bus[best_src]; ++ ++ ourhost->cur_clk = best_src; ++ host->max_clk = clk_get_rate(clk); ++ host->timeout_clk = host->max_clk / 1000000; ++ ++ ctrl = readl(host->ioaddr + S3C_SDHCI_CONTROL2); ++ ctrl &= ~S3C_SDHCI_CTRL2_SELBASECLK_MASK; ++ ctrl |= best_src << S3C_SDHCI_CTRL2_SELBASECLK_SHIFT; ++ writel(ctrl, host->ioaddr + S3C_SDHCI_CONTROL2); ++ } ++ ++ sdhci_change_clock(host, clock); ++} ++ ++static struct sdhci_ops sdhci_s3c_ops = { ++ .get_max_clock = sdhci_s3c_get_max_clk, ++ .get_timeout_clock = sdhci_s3c_get_timeout_clk, ++ .change_clock = sdhci_s3c_change_clock, ++ .set_ios = sdhci_s3c_set_ios, ++}; ++ ++/* ++ * call this when you need sd stack to recognize insertion or removal of card ++ * that can't be told by SDHCI regs ++ */ ++ ++void sdhci_s3c_force_presence_change(struct platform_device *pdev) ++{ ++ struct s3c_sdhci_platdata *pdata = pdev->dev.platform_data; ++ ++ dev_info(&pdev->dev, "sdhci_s3c_force_presence_change called\n"); ++ mmc_detect_change(pdata->sdhci_host->mmc, msecs_to_jiffies(200)); ++} ++EXPORT_SYMBOL_GPL(sdhci_s3c_force_presence_change); ++ ++ ++static int __devinit sdhci_s3c_probe(struct platform_device *pdev) ++{ ++ struct s3c_sdhci_platdata *pdata = pdev->dev.platform_data; ++ struct device *dev = &pdev->dev; ++ struct sdhci_host *host; ++ struct sdhci_s3c *sc; ++ struct resource *res; ++ int ret, irq, ptr, clks; ++ ++ if (!pdata) { ++ dev_err(dev, "no device data specified\n"); ++ return -ENOENT; ++ } ++ ++ irq = platform_get_irq(pdev, 0); ++ if (irq < 0) { ++ dev_err(dev, "no irq specified\n"); ++ return irq; ++ } ++ ++ res = platform_get_resource(pdev, IORESOURCE_MEM, 0); ++ if (!res) { ++ dev_err(dev, "no memory specified\n"); ++ return -ENOENT; ++ } ++ ++ host = sdhci_alloc_host(dev, sizeof(struct sdhci_s3c)); ++ if (IS_ERR(host)) { ++ dev_err(dev, "sdhci_alloc_host() failed\n"); ++ return PTR_ERR(host); ++ } ++ ++ pdata->sdhci_host = host; ++ ++ sc = sdhci_priv(host); ++ ++ sc->host = host; ++ sc->pdev = pdev; ++ sc->pdata = pdata; ++ ++ platform_set_drvdata(pdev, host); ++ ++ sc->clk_io = clk_get(dev, "hsmmc"); ++ if (IS_ERR(sc->clk_io)) { ++ dev_err(dev, "failed to get io clock\n"); ++ ret = PTR_ERR(sc->clk_io); ++ goto err_io_clk; ++ } ++ ++ /* enable the local io clock and keep it running for the moment. */ ++ clk_enable(sc->clk_io); ++ ++ for (clks = 0, ptr = 0; ptr < MAX_BUS_CLK; ptr++) { ++ struct clk *clk; ++ char *name = pdata->clocks[ptr]; ++ ++ if (name == NULL) ++ continue; ++ ++ clk = clk_get(dev, name); ++ if (IS_ERR(clk)) { ++ dev_err(dev, "failed to get clock %s\n", name); ++ continue; ++ } ++ ++ clks++; ++ sc->clk_bus[ptr] = clk; ++ clk_enable(clk); ++ ++ dev_info(dev, "clock source %d: %s (%ld Hz)\n", ++ ptr, name, clk_get_rate(clk)); ++ } ++ ++ if (clks == 0) { ++ dev_err(dev, "failed to find any bus clocks\n"); ++ ret = -ENOENT; ++ goto err_no_busclks; ++ } ++ ++ sc->ioarea = request_mem_region(res->start, resource_size(res), ++ mmc_hostname(host->mmc)); ++ if (!sc->ioarea) { ++ dev_err(dev, "failed to reserve register area\n"); ++ ret = -ENXIO; ++ goto err_req_regs; ++ } ++ ++ host->ioaddr = ioremap_nocache(res->start, resource_size(res)); ++ if (!host->ioaddr) { ++ dev_err(dev, "failed to map registers\n"); ++ ret = -ENXIO; ++ goto err_req_regs; ++ } ++ ++ /* Ensure we have minimal gpio selected CMD/CLK/Detect */ ++ if (pdata->cfg_gpio) ++ pdata->cfg_gpio(pdev, 0); ++ ++ sdhci_s3c_check_sclk(host); ++ ++ host->hw_name = "samsung-hsmmc"; ++ host->ops = &sdhci_s3c_ops; ++ host->quirks = 0; ++ host->irq = irq; ++ ++ /* Setup quirks for the controller */ ++ ++ /* Currently with ADMA enabled we are getting some length ++ * interrupts that are not being dealt with, do disable ++ * ADMA until this is sorted out. */ ++ host->quirks |= SDHCI_QUIRK_BROKEN_ADMA; ++ host->quirks |= SDHCI_QUIRK_32BIT_ADMA_SIZE; ++ ++ /* It seems we do not get an DATA transfer complete on non-busy ++ * transfers, not sure if this is a problem with this specific ++ * SDHCI block, or a missing configuration that needs to be set. */ ++ host->quirks |= SDHCI_QUIRK_NO_TCIRQ_ON_NOT_BUSY; ++ ++ host->quirks |= (SDHCI_QUIRK_32BIT_DMA_ADDR | ++ SDHCI_QUIRK_32BIT_DMA_SIZE); ++ ++ ret = sdhci_add_host(host); ++ if (ret) { ++ dev_err(dev, "sdhci_add_host() failed\n"); ++ goto err_add_host; ++ } ++ ++ return 0; ++ ++ err_add_host: ++ release_resource(sc->ioarea); ++ kfree(sc->ioarea); ++ ++ err_req_regs: ++ for (ptr = 0; ptr < MAX_BUS_CLK; ptr++) { ++ clk_disable(sc->clk_bus[ptr]); ++ clk_put(sc->clk_bus[ptr]); ++ } ++ ++ err_no_busclks: ++ clk_disable(sc->clk_io); ++ clk_put(sc->clk_io); ++ ++ err_io_clk: ++ sdhci_free_host(host); ++ ++ return ret; ++} ++ ++static int __devexit sdhci_s3c_remove(struct platform_device *pdev) ++{ ++ return 0; ++} ++ ++#ifdef CONFIG_PM ++ ++static int sdhci_s3c_suspend(struct platform_device *dev, pm_message_t pm) ++{ ++ struct sdhci_host *host = platform_get_drvdata(dev); ++ ++ sdhci_suspend_host(host, pm); ++ return 0; ++} ++ ++static int sdhci_s3c_resume(struct platform_device *dev) ++{ ++ struct sdhci_host *host = platform_get_drvdata(dev); ++ ++ sdhci_resume_host(host); ++ return 0; ++} ++ ++#else ++#define sdhci_s3c_suspend NULL ++#define sdhci_s3c_resume NULL ++#endif ++ ++static struct platform_driver sdhci_s3c_driver = { ++ .probe = sdhci_s3c_probe, ++ .remove = __devexit_p(sdhci_s3c_remove), ++ .suspend = sdhci_s3c_suspend, ++ .resume = sdhci_s3c_resume, ++ .driver = { ++ .owner = THIS_MODULE, ++ .name = "s3c-sdhci", ++ }, ++}; ++ ++static int __init sdhci_s3c_init(void) ++{ ++ return platform_driver_register(&sdhci_s3c_driver); ++} ++ ++static void __exit sdhci_s3c_exit(void) ++{ ++ platform_driver_unregister(&sdhci_s3c_driver); ++} ++ ++module_init(sdhci_s3c_init); ++module_exit(sdhci_s3c_exit); ++ ++MODULE_DESCRIPTION("Samsung SDHCI (HSMMC) glue"); ++MODULE_AUTHOR("Ben Dooks, <ben@simtec.co.uk>"); ++MODULE_LICENSE("GPL v2"); ++MODULE_ALIAS("platform:s3c-sdhci"); +diff -ruN --exclude='*.orig' --exclude='*.rej' linux-2.6.29-rc3.owrt/drivers/mtd/nand/s3c2410.c linux-2.6.29-rc3.owrt.om/drivers/mtd/nand/s3c2410.c +--- linux-2.6.29-rc3.owrt/drivers/mtd/nand/s3c2410.c 2009-05-10 22:04:49.000000000 +0200 ++++ linux-2.6.29-rc3.owrt.om/drivers/mtd/nand/s3c2410.c 2009-05-10 22:28:00.000000000 +0200 +@@ -231,8 +231,6 @@ + BUG(); + } + +- dev_dbg(info->device, "NF_CONF is 0x%lx\n", cfg); +- + local_irq_save(flags); + + cfg = readl(info->regs + S3C2410_NFCONF); +@@ -240,6 +238,8 @@ + cfg |= set; + writel(cfg, info->regs + S3C2410_NFCONF); + ++ dev_dbg(info->device, "NF_CONF is 0x%lx\n", cfg); ++ + local_irq_restore(flags); + + return 0; +@@ -438,7 +438,7 @@ + if ((diff0 & ~(1<<fls(diff0))) == 0) + return 1; + +- return -1; ++ return -EBADMSG; + } + + /* ECC functions +@@ -530,7 +530,12 @@ + static void s3c2440_nand_read_buf(struct mtd_info *mtd, u_char *buf, int len) + { + struct s3c2410_nand_info *info = s3c2410_nand_mtd_toinfo(mtd); ++ u8 *ptr = buf + (len & ~3); ++ int i; ++ + readsl(info->regs + S3C2440_NFDATA, buf, len / 4); ++ for (i = 0; i != (len & 3); i++) ++ ptr[i] = readb(info->regs + S3C2440_NFDATA); + } + + static void s3c2410_nand_write_buf(struct mtd_info *mtd, const u_char *buf, int len) +@@ -645,17 +650,31 @@ + } + + #ifdef CONFIG_MTD_PARTITIONS ++const char *part_probes[] = { "cmdlinepart", NULL }; + static int s3c2410_nand_add_partition(struct s3c2410_nand_info *info, + struct s3c2410_nand_mtd *mtd, + struct s3c2410_nand_set *set) + { ++ struct mtd_partition *part_info; ++ int nr_part = 0; ++ + if (set == NULL) + return add_mtd_device(&mtd->mtd); + +- if (set->nr_partitions > 0 && set->partitions != NULL) { +- return add_mtd_partitions(&mtd->mtd, set->partitions, set->nr_partitions); ++ if (set->nr_partitions == 0) { ++ mtd->mtd.name = set->name; ++ nr_part = parse_mtd_partitions(&mtd->mtd, part_probes, ++ &part_info, 0); ++ } else { ++ if (set->nr_partitions > 0 && set->partitions != NULL) { ++ nr_part = set->nr_partitions; ++ part_info = set->partitions; ++ } + } + ++ if (nr_part > 0 && part_info) ++ return add_mtd_partitions(&mtd->mtd, part_info, nr_part); ++ + return add_mtd_device(&mtd->mtd); + } + #else +@@ -684,9 +703,13 @@ + chip->select_chip = s3c2410_nand_select_chip; + chip->chip_delay = 50; + chip->priv = nmtd; +- chip->options = 0; + chip->controller = &info->controller; + ++ if (set->flags & S3C2410_NAND_BBT) ++ chip->options = NAND_USE_FLASH_BBT; ++ else ++ chip->options = 0; ++ + switch (info->cpu_type) { + case TYPE_S3C2410: + chip->IO_ADDR_W = regs + S3C2410_NFDATA; +@@ -726,7 +749,7 @@ + nmtd->mtd.owner = THIS_MODULE; + nmtd->set = set; + +- if (hardware_ecc) { ++ if (!info->platform->software_ecc && hardware_ecc) { + chip->ecc.calculate = s3c2410_nand_calculate_ecc; + chip->ecc.correct = s3c2410_nand_correct_data; + chip->ecc.mode = NAND_ECC_HW; +diff -ruN --exclude='*.orig' --exclude='*.rej' linux-2.6.29-rc3.owrt/drivers/net/ppp_deflate.c linux-2.6.29-rc3.owrt.om/drivers/net/ppp_deflate.c +--- linux-2.6.29-rc3.owrt/drivers/net/ppp_deflate.c 2009-05-10 22:04:48.000000000 +0200 ++++ linux-2.6.29-rc3.owrt.om/drivers/net/ppp_deflate.c 2009-05-10 22:28:00.000000000 +0200 +@@ -306,7 +306,7 @@ + + if (state) { + zlib_inflateEnd(&state->strm); +- kfree(state->strm.workspace); ++ vfree(state->strm.workspace); + kfree(state); + } + } +@@ -346,8 +346,7 @@ + + state->w_size = w_size; + state->strm.next_out = NULL; +- state->strm.workspace = kmalloc(zlib_inflate_workspacesize(), +- GFP_KERNEL|__GFP_REPEAT); ++ state->strm.workspace = vmalloc(zlib_inflate_workspacesize()); + if (state->strm.workspace == NULL) + goto out_free; + +diff -ruN --exclude='*.orig' --exclude='*.rej' linux-2.6.29-rc3.owrt/drivers/net/wireless/libertas/if_sdio.c linux-2.6.29-rc3.owrt.om/drivers/net/wireless/libertas/if_sdio.c +--- linux-2.6.29-rc3.owrt/drivers/net/wireless/libertas/if_sdio.c 2009-05-10 22:04:49.000000000 +0200 ++++ linux-2.6.29-rc3.owrt.om/drivers/net/wireless/libertas/if_sdio.c 2009-05-10 22:28:00.000000000 +0200 +@@ -49,6 +49,7 @@ + + static const struct sdio_device_id if_sdio_ids[] = { + { SDIO_DEVICE(SDIO_VENDOR_ID_MARVELL, SDIO_DEVICE_ID_MARVELL_LIBERTAS) }, ++ { SDIO_DEVICE(SDIO_VENDOR_ID_MARVELL, SDIO_DEVICE_ID_MARVELL_88W8688) }, + { /* end: all zeroes */ }, + }; + +@@ -73,7 +74,12 @@ + .helper = "sd8686_helper.bin", + .firmware = "sd8686.bin", + }, +-}; ++ { ++ /* 8688 */ ++ .model = 0x10, ++ .helper = "sd8688_helper.bin", ++ .firmware = "sd8688.bin", ++ },}; + + struct if_sdio_packet { + struct if_sdio_packet *next; +diff -ruN --exclude='*.orig' --exclude='*.rej' linux-2.6.29-rc3.owrt/drivers/pnp/Kconfig linux-2.6.29-rc3.owrt.om/drivers/pnp/Kconfig +--- linux-2.6.29-rc3.owrt/drivers/pnp/Kconfig 2009-05-10 22:04:48.000000000 +0200 ++++ linux-2.6.29-rc3.owrt.om/drivers/pnp/Kconfig 2009-05-10 22:28:00.000000000 +0200 +@@ -5,7 +5,7 @@ + menuconfig PNP + bool "Plug and Play support" + depends on HAS_IOMEM +- depends on ISA || ACPI ++ depends on ISA || ACPI || SDIO + ---help--- + Plug and Play (PnP) is a standard for peripherals which allows those + peripherals to be configured by software, e.g. assign IRQ's or other +diff -ruN --exclude='*.orig' --exclude='*.rej' linux-2.6.29-rc3.owrt/drivers/pnp/resource.c linux-2.6.29-rc3.owrt.om/drivers/pnp/resource.c +--- linux-2.6.29-rc3.owrt/drivers/pnp/resource.c 2009-05-10 22:04:48.000000000 +0200 ++++ linux-2.6.29-rc3.owrt.om/drivers/pnp/resource.c 2009-05-10 22:28:00.000000000 +0200 +@@ -436,6 +436,7 @@ + } + } + ++#if 0 + /* check if the resource is already in use, skip if the + * device is active because it itself may be in use */ + if (!dev->active) { +@@ -443,6 +444,7 @@ + return 0; + free_dma(*dma); + } ++#endif + + /* check for conflicts with other pnp devices */ + pnp_for_each_dev(tdev) { +diff -ruN --exclude='*.orig' --exclude='*.rej' linux-2.6.29-rc3.owrt/drivers/power/bq27000_battery.c linux-2.6.29-rc3.owrt.om/drivers/power/bq27000_battery.c +--- linux-2.6.29-rc3.owrt/drivers/power/bq27000_battery.c 1970-01-01 01:00:00.000000000 +0100 ++++ linux-2.6.29-rc3.owrt.om/drivers/power/bq27000_battery.c 2009-05-10 22:28:00.000000000 +0200 +@@ -0,0 +1,474 @@ ++/* ++ * Driver for batteries with bq27000 chips inside via HDQ ++ * ++ * Copyright 2008 Openmoko, Inc ++ * Andy Green <andy@openmoko.com> ++ * ++ * based on ds2760 driver, original copyright notice for that ---> ++ * ++ * Copyright © 2007 Anton Vorontsov ++ * 2004-2007 Matt Reimer ++ * 2004 Szabolcs Gyurko ++ * ++ * Use consistent with the GNU GPL is permitted, ++ * provided that this copyright notice is ++ * preserved in its entirety in all copies and derived works. ++ * ++ * Author: Anton Vorontsov <cbou@mail.ru> ++ * February 2007 ++ * ++ * Matt Reimer <mreimer@vpop.net> ++ * April 2004, 2005, 2007 ++ * ++ * Szabolcs Gyurko <szabolcs.gyurko@tlt.hu> ++ * September 2004 ++ */ ++ ++#include <linux/module.h> ++#include <linux/param.h> ++#include <linux/jiffies.h> ++#include <linux/delay.h> ++#include <linux/pm.h> ++#include <linux/workqueue.h> ++#include <linux/platform_device.h> ++#include <linux/power_supply.h> ++#include <linux/bq27000_battery.h> ++ ++enum bq27000_regs { ++ /* RAM regs */ ++ /* read-write after this */ ++ BQ27000_CTRL = 0, /* Device Control Register */ ++ BQ27000_MODE, /* Device Mode Register */ ++ BQ27000_AR_L, /* At-Rate H L */ ++ BQ27000_AR_H, ++ /* read-only after this */ ++ BQ27000_ARTTE_L, /* At-Rate Time To Empty H L */ ++ BQ27000_ARTTE_H, ++ BQ27000_TEMP_L, /* Reported Temperature H L */ ++ BQ27000_TEMP_H, ++ BQ27000_VOLT_L, /* Reported Voltage H L */ ++ BQ27000_VOLT_H, ++ BQ27000_FLAGS, /* Status Flags */ ++ BQ27000_RSOC, /* Relative State of Charge */ ++ BQ27000_NAC_L, /* Nominal Available Capacity H L */ ++ BQ27000_NAC_H, ++ BQ27000_CACD_L, /* Discharge Compensated H L */ ++ BQ27000_CACD_H, ++ BQ27000_CACT_L, /* Temperature Compensated H L */ ++ BQ27000_CACT_H, ++ BQ27000_LMD_L, /* Last measured discharge H L */ ++ BQ27000_LMD_H, ++ BQ27000_AI_L, /* Average Current H L */ ++ BQ27000_AI_H, ++ BQ27000_TTE_L, /* Time to Empty H L */ ++ BQ27000_TTE_H, ++ BQ27000_TTF_L, /* Time to Full H L */ ++ BQ27000_TTF_H, ++ BQ27000_SI_L, /* Standby Current H L */ ++ BQ27000_SI_H, ++ BQ27000_STTE_L, /* Standby Time To Empty H L */ ++ BQ27000_STTE_H, ++ BQ27000_MLI_L, /* Max Load Current H L */ ++ BQ27000_MLI_H, ++ BQ27000_MLTTE_L, /* Max Load Time To Empty H L */ ++ BQ27000_MLTTE_H, ++ BQ27000_SAE_L, /* Available Energy H L */ ++ BQ27000_SAE_H, ++ BQ27000_AP_L, /* Available Power H L */ ++ BQ27000_AP_H, ++ BQ27000_TTECP_L, /* Time to Empty at Constant Power H L */ ++ BQ27000_TTECP_H, ++ BQ27000_CYCL_L, /* Cycle count since learning cycle H L */ ++ BQ27000_CYCL_H, ++ BQ27000_CYCT_L, /* Cycle Count Total H L */ ++ BQ27000_CYCT_H, ++ BQ27000_CSOC, /* Compensated State Of Charge */ ++ /* EEPROM regs */ ++ /* read-write after this */ ++ BQ27000_EE_EE_EN = 0x6e, /* EEPROM Program Enable */ ++ BQ27000_EE_ILMD = 0x76, /* Initial Last Measured Discharge High Byte */ ++ BQ27000_EE_SEDVF, /* Scaled EDVF Threshold */ ++ BQ27000_EE_SEDV1, /* Scaled EDV1 Threshold */ ++ BQ27000_EE_ISLC, /* Initial Standby Load Current */ ++ BQ27000_EE_DMFSD, /* Digital Magnitude Filter and Self Discharge */ ++ BQ27000_EE_TAPER, /* Aging Estimate Enable, Charge Termination Taper */ ++ BQ27000_EE_PKCFG, /* Pack Configuration Values */ ++ BQ27000_EE_IMLC, /* Initial Max Load Current or ID #3 */ ++ BQ27000_EE_DCOMP, /* Discharge rate compensation constants or ID #2 */ ++ BQ27000_EE_TCOMP, /* Temperature Compensation constants or ID #1 */ ++}; ++ ++enum bq27000_status_flags { ++ BQ27000_STATUS_CHGS = 0x80, /* 1 = being charged */ ++ BQ27000_STATUS_NOACT = 0x40, /* 1 = no activity */ ++ BQ27000_STATUS_IMIN = 0x20, /* 1 = Lion taper current mode */ ++ BQ27000_STATUS_CI = 0x10, /* 1 = capacity likely innacurate */ ++ BQ27000_STATUS_CALIP = 0x08, /* 1 = calibration in progress */ ++ BQ27000_STATUS_VDQ = 0x04, /* 1 = capacity should be accurate */ ++ BQ27000_STATUS_EDV1 = 0x02, /* 1 = end of discharge.. <6% left */ ++ BQ27000_STATUS_EDVF = 0x01, /* 1 = no, it's really empty now */ ++}; ++ ++#define NANOVOLTS_UNIT 3750 ++ ++struct bq27000_bat_regs { ++ int ai; ++ int flags; ++ int lmd; ++ int rsoc; ++ int temp; ++ int tte; ++ int ttf; ++ int volt; ++}; ++ ++struct bq27000_device_info { ++ struct device *dev; ++ struct power_supply bat; ++ struct power_supply ac; ++ struct power_supply usb; ++ struct delayed_work work; ++ struct bq27000_platform_data *pdata; ++ ++ struct bq27000_bat_regs regs; ++}; ++ ++static unsigned int cache_time = 5000; ++module_param(cache_time, uint, 0644); ++MODULE_PARM_DESC(cache_time, "cache time in milliseconds"); ++ ++/* ++ * reading 16 bit values over HDQ has a special hazard where the ++ * hdq device firmware can update the 16-bit register during the time we ++ * read the two halves. TI document SLUS556D recommends the algorithm here ++ * to avoid trouble ++ */ ++ ++static int hdq_read16(struct bq27000_device_info *di, int address) ++{ ++ int acc; ++ int high; ++ int retries = 3; ++ ++ while (retries--) { ++ ++ high = (di->pdata->hdq_read)(address + 1); /* high part */ ++ ++ if (high < 0) ++ return high; ++ acc = (di->pdata->hdq_read)(address); ++ if (acc < 0) ++ return acc; ++ ++ /* confirm high didn't change between reading it and low */ ++ if (high == (di->pdata->hdq_read)(address + 1)) ++ return (high << 8) | acc; ++ } ++ ++ return -ETIME; ++} ++ ++static void bq27000_battery_external_power_changed(struct power_supply *psy) ++{ ++ struct bq27000_device_info *di = container_of(psy, struct bq27000_device_info, bat); ++ ++ dev_dbg(di->dev, "%s\n", __FUNCTION__); ++ schedule_delayed_work(&di->work, 0); ++} ++ ++static int bq27000_battery_get_property(struct power_supply *psy, ++ enum power_supply_property psp, ++ union power_supply_propval *val) ++{ ++ int n; ++ struct bq27000_device_info *di = container_of(psy, struct bq27000_device_info, bat); ++ ++ switch (psp) { ++ case POWER_SUPPLY_PROP_STATUS: ++ val->intval = POWER_SUPPLY_STATUS_UNKNOWN; ++ ++ if (!di->pdata->get_charger_online_status) ++ goto use_bat; ++ if ((di->pdata->get_charger_online_status)()) { ++ /* ++ * charger is definitively present ++ * we report our state in terms of what it says it ++ * is doing ++ */ ++ if (!di->pdata->get_charger_active_status) ++ goto use_bat; ++ ++ if ((di->pdata->get_charger_active_status)()) { ++ val->intval = POWER_SUPPLY_STATUS_CHARGING; ++ break; ++ } ++ val->intval = POWER_SUPPLY_STATUS_NOT_CHARGING; ++ break; ++ } ++ ++ /* ++ * platform provided definite indication of charger presence, ++ * and it is telling us it isn't there... but we are on so we ++ * must be running from battery ---> ++ */ ++ ++ val->intval = POWER_SUPPLY_STATUS_DISCHARGING; ++ break; ++ ++use_bat: ++ /* ++ * either the charger is not connected, or the ++ * platform doesn't give info about charger, use battery state ++ * but... battery state can be out of date by 4 seconds or ++ * so... use the platform callbacks if possible. ++ */ ++ ++ /* no real activity on the battery */ ++ if (di->regs.ai < 2) { ++ if (!di->regs.ttf) ++ val->intval = POWER_SUPPLY_STATUS_FULL; ++ else ++ val->intval = POWER_SUPPLY_STATUS_NOT_CHARGING; ++ break; ++ } ++ /* power is actually going in or out... */ ++ if (di->regs.flags < 0) ++ return di->regs.flags; ++ if (di->regs.flags & BQ27000_STATUS_CHGS) ++ val->intval = POWER_SUPPLY_STATUS_CHARGING; ++ else ++ val->intval = POWER_SUPPLY_STATUS_DISCHARGING; ++ break; ++ case POWER_SUPPLY_PROP_HEALTH: ++ val->intval = POWER_SUPPLY_HEALTH_UNKNOWN; ++ /* Do we have accurate readings... */ ++ if (di->regs.flags < 0) ++ return di->regs.flags; ++ if (di->regs.flags & BQ27000_STATUS_VDQ) ++ val->intval = POWER_SUPPLY_HEALTH_GOOD; ++ break; ++ case POWER_SUPPLY_PROP_VOLTAGE_NOW: ++ if (di->regs.volt < 0) ++ return di->regs.volt; ++ /* mV -> uV */ ++ val->intval = di->regs.volt * 1000; ++ break; ++ case POWER_SUPPLY_PROP_CURRENT_NOW: ++ if (di->regs.flags < 0) ++ return di->regs.flags; ++ if (di->regs.flags & BQ27000_STATUS_CHGS) ++ n = -NANOVOLTS_UNIT; ++ else ++ n = NANOVOLTS_UNIT; ++ if (di->regs.ai < 0) ++ return di->regs.ai; ++ val->intval = (di->regs.ai * n) / di->pdata->rsense_mohms; ++ break; ++ case POWER_SUPPLY_PROP_CHARGE_FULL: ++ if (di->regs.lmd < 0) ++ return di->regs.lmd; ++ val->intval = (di->regs.lmd * 3570) / di->pdata->rsense_mohms; ++ break; ++ case POWER_SUPPLY_PROP_TEMP: ++ if (di->regs.temp < 0) ++ return di->regs.temp; ++ /* K (in 0.25K units) is 273.15 up from C (in 0.1C)*/ ++ /* 10926 = 27315 * 4 / 10 */ ++ val->intval = (((long)di->regs.temp * 10l) - 10926) / 4; ++ break; ++ case POWER_SUPPLY_PROP_TECHNOLOGY: ++ val->intval = POWER_SUPPLY_TECHNOLOGY_LION; ++ break; ++ case POWER_SUPPLY_PROP_CAPACITY: ++ val->intval = di->regs.rsoc; ++ if (val->intval < 0) ++ return val->intval; ++ break; ++ case POWER_SUPPLY_PROP_PRESENT: ++ val->intval = !(di->regs.rsoc < 0); ++ break; ++ case POWER_SUPPLY_PROP_TIME_TO_EMPTY_NOW: ++ if (di->regs.tte < 0) ++ return di->regs.tte; ++ val->intval = 60 * di->regs.tte; ++ break; ++ case POWER_SUPPLY_PROP_TIME_TO_FULL_NOW: ++ if (di->regs.ttf < 0) ++ return di->regs.ttf; ++ val->intval = 60 * di->regs.ttf; ++ break; ++ case POWER_SUPPLY_PROP_ONLINE: ++ if (di->pdata->get_charger_online_status) ++ val->intval = (di->pdata->get_charger_online_status)(); ++ else ++ return -EINVAL; ++ break; ++ default: ++ return -EINVAL; ++ } ++ ++ return 0; ++} ++ ++static void bq27000_battery_work(struct work_struct *work) ++{ ++ struct bq27000_device_info *di = ++ container_of(work, struct bq27000_device_info, work.work); ++ ++ if ((di->pdata->hdq_initialized)()) { ++ struct bq27000_bat_regs regs; ++ ++ regs.ai = hdq_read16(di, BQ27000_AI_L); ++ regs.flags = (di->pdata->hdq_read)(BQ27000_FLAGS); ++ regs.lmd = hdq_read16(di, BQ27000_LMD_L); ++ regs.rsoc = (di->pdata->hdq_read)(BQ27000_RSOC); ++ regs.temp = hdq_read16(di, BQ27000_TEMP_L); ++ regs.tte = hdq_read16(di, BQ27000_TTE_L); ++ regs.ttf = hdq_read16(di, BQ27000_TTF_L); ++ regs.volt = hdq_read16(di, BQ27000_VOLT_L); ++ ++ if (memcmp (®s, &di->regs, sizeof(regs)) != 0) { ++ di->regs = regs; ++ power_supply_changed(&di->bat); ++ } ++ } ++ ++ if (!schedule_delayed_work(&di->work, cache_time)) ++ dev_err(di->dev, "battery service reschedule failed\n"); ++} ++ ++static enum power_supply_property bq27000_battery_props[] = { ++ POWER_SUPPLY_PROP_STATUS, ++ POWER_SUPPLY_PROP_HEALTH, ++ POWER_SUPPLY_PROP_VOLTAGE_NOW, ++ POWER_SUPPLY_PROP_CURRENT_NOW, ++ POWER_SUPPLY_PROP_CHARGE_FULL, ++ POWER_SUPPLY_PROP_TEMP, ++ POWER_SUPPLY_PROP_TECHNOLOGY, ++ POWER_SUPPLY_PROP_PRESENT, ++ POWER_SUPPLY_PROP_TIME_TO_EMPTY_NOW, ++ POWER_SUPPLY_PROP_TIME_TO_FULL_NOW, ++ POWER_SUPPLY_PROP_CAPACITY, ++ POWER_SUPPLY_PROP_ONLINE ++}; ++ ++static int bq27000_battery_probe(struct platform_device *pdev) ++{ ++ int retval = 0; ++ struct bq27000_device_info *di; ++ struct bq27000_platform_data *pdata; ++ ++ dev_info(&pdev->dev, "BQ27000 Battery Driver (C) 2008 Openmoko, Inc\n"); ++ ++ di = kzalloc(sizeof(*di), GFP_KERNEL); ++ if (!di) { ++ retval = -ENOMEM; ++ goto di_alloc_failed; ++ } ++ ++ platform_set_drvdata(pdev, di); ++ ++ pdata = pdev->dev.platform_data; ++ di->dev = &pdev->dev; ++ /* di->w1_dev = pdev->dev.parent; */ ++ di->bat.name = pdata->name; ++ di->bat.type = POWER_SUPPLY_TYPE_BATTERY; ++ di->bat.properties = bq27000_battery_props; ++ di->bat.num_properties = ARRAY_SIZE(bq27000_battery_props); ++ di->bat.get_property = bq27000_battery_get_property; ++ di->bat.external_power_changed = ++ bq27000_battery_external_power_changed; ++ di->bat.use_for_apm = 1; ++ di->pdata = pdata; ++ ++ retval = power_supply_register(&pdev->dev, &di->bat); ++ if (retval) { ++ dev_err(di->dev, "failed to register battery\n"); ++ goto batt_failed; ++ } ++ ++ INIT_DELAYED_WORK(&di->work, bq27000_battery_work); ++ ++ if (!schedule_delayed_work(&di->work, 0)) ++ dev_err(di->dev, "failed to schedule bq27000_battery_work\n"); ++ ++ return 0; ++ ++batt_failed: ++ kfree(di); ++di_alloc_failed: ++ return retval; ++} ++ ++static int bq27000_battery_remove(struct platform_device *pdev) ++{ ++ struct bq27000_device_info *di = platform_get_drvdata(pdev); ++ ++ cancel_delayed_work(&di->work); ++ ++ power_supply_unregister(&di->bat); ++ ++ return 0; ++} ++ ++void bq27000_charging_state_change(struct platform_device *pdev) ++{ ++ struct bq27000_device_info *di = platform_get_drvdata(pdev); ++ ++ if (!di) ++ return; ++} ++EXPORT_SYMBOL_GPL(bq27000_charging_state_change); ++ ++#ifdef CONFIG_PM ++ ++static int bq27000_battery_suspend(struct platform_device *pdev, ++ pm_message_t state) ++{ ++ struct bq27000_device_info *di = platform_get_drvdata(pdev); ++ ++ cancel_delayed_work(&di->work); ++ return 0; ++} ++ ++static int bq27000_battery_resume(struct platform_device *pdev) ++{ ++ struct bq27000_device_info *di = platform_get_drvdata(pdev); ++ ++ schedule_delayed_work(&di->work, 0); ++ return 0; ++} ++ ++#else ++ ++#define bq27000_battery_suspend NULL ++#define bq27000_battery_resume NULL ++ ++#endif /* CONFIG_PM */ ++ ++static struct platform_driver bq27000_battery_driver = { ++ .driver = { ++ .name = "bq27000-battery", ++ }, ++ .probe = bq27000_battery_probe, ++ .remove = bq27000_battery_remove, ++ .suspend = bq27000_battery_suspend, ++ .resume = bq27000_battery_resume, ++}; ++ ++static int __init bq27000_battery_init(void) ++{ ++ return platform_driver_register(&bq27000_battery_driver); ++} ++ ++static void __exit bq27000_battery_exit(void) ++{ ++ platform_driver_unregister(&bq27000_battery_driver); ++} ++ ++module_init(bq27000_battery_init); ++module_exit(bq27000_battery_exit); ++ ++MODULE_LICENSE("GPL"); ++MODULE_AUTHOR("Andy Green <andy@openmoko.com>"); ++MODULE_DESCRIPTION("bq27000 battery driver"); +diff -ruN --exclude='*.orig' --exclude='*.rej' linux-2.6.29-rc3.owrt/drivers/power/gta01_battery.c linux-2.6.29-rc3.owrt.om/drivers/power/gta01_battery.c +--- linux-2.6.29-rc3.owrt/drivers/power/gta01_battery.c 1970-01-01 01:00:00.000000000 +0100 ++++ linux-2.6.29-rc3.owrt.om/drivers/power/gta01_battery.c 2009-05-10 22:28:00.000000000 +0200 +@@ -0,0 +1,117 @@ ++/* ++ * Dumb driver for gta01 battery ++ * ++ * Copyright 2009 Openmoko, Inc ++ * Balaji Rao <balajirrao@openmoko.org> ++ */ ++ ++#include <linux/module.h> ++#include <linux/param.h> ++#include <linux/delay.h> ++#include <linux/workqueue.h> ++#include <linux/platform_device.h> ++#include <linux/power_supply.h> ++#include <linux/gta01_battery.h> ++ ++struct gta01_battery { ++ struct power_supply psy; ++ struct gta01_bat_platform_data *pdata; ++}; ++ ++static enum power_supply_property gta01_bat_props[] = { ++ POWER_SUPPLY_PROP_PRESENT, ++ POWER_SUPPLY_PROP_STATUS, ++ POWER_SUPPLY_PROP_VOLTAGE_NOW, ++ POWER_SUPPLY_PROP_CURRENT_NOW, ++}; ++ ++static int gta01_bat_get_property(struct power_supply *psy, ++ enum power_supply_property psp, ++ union power_supply_propval *val) ++{ ++ struct gta01_battery *bat = container_of(psy, struct gta01_battery, psy); ++ ++ switch(psp) { ++ case POWER_SUPPLY_PROP_STATUS: ++ if (bat->pdata->get_charging_status()) ++ val->intval = POWER_SUPPLY_STATUS_CHARGING; ++ else ++ val->intval = POWER_SUPPLY_STATUS_DISCHARGING; ++ break; ++ case POWER_SUPPLY_PROP_VOLTAGE_NOW: ++ val->intval = bat->pdata->get_voltage(); ++ break; ++ case POWER_SUPPLY_PROP_CURRENT_NOW: ++ val->intval = bat->pdata->get_current(); ++ break; ++ case POWER_SUPPLY_PROP_PRESENT: ++ val->intval = 1; /* You must never run GTA01 without battery. */ ++ break; ++ default: ++ return -EINVAL; ++ } ++ ++ return 0; ++} ++ ++static void gta01_bat_ext_changed(struct power_supply *psy) ++{ ++ struct gta01_battery *bat = container_of(psy, struct gta01_battery, psy); ++ power_supply_changed(&bat->psy); ++} ++ ++static int gta01_battery_probe(struct platform_device *pdev) ++{ ++ struct gta01_battery *gta01_bat; ++ ++ gta01_bat = kzalloc(sizeof(*gta01_bat), GFP_KERNEL); ++ if (!gta01_bat) ++ return -ENOMEM; ++ ++ gta01_bat->psy.name = "battery"; ++ gta01_bat->psy.type = POWER_SUPPLY_TYPE_BATTERY; ++ gta01_bat->psy.properties = gta01_bat_props; ++ gta01_bat->psy.num_properties = ARRAY_SIZE(gta01_bat_props); ++ gta01_bat->psy.get_property = gta01_bat_get_property; ++ gta01_bat->psy.external_power_changed = gta01_bat_ext_changed; ++ ++ gta01_bat->pdata = pdev->dev.platform_data; ++ power_supply_register(&pdev->dev, >a01_bat->psy); ++ ++ return 0; ++} ++ ++static int gta01_battery_remove(struct platform_device *pdev) ++{ ++ struct gta01_battery *bat = platform_get_drvdata(pdev); ++ ++ power_supply_unregister(&bat->psy); ++ kfree(bat); ++ ++ return 0; ++} ++ ++static struct platform_driver gta01_battery_driver = { ++ .driver = { ++ .name = "gta01_battery", ++ }, ++ .probe = gta01_battery_probe, ++ .remove = gta01_battery_remove, ++}; ++ ++static int __init gta01_battery_init(void) ++{ ++ return platform_driver_register(>a01_battery_driver); ++} ++ ++static void __exit gta01_battery_exit(void) ++{ ++ platform_driver_unregister(>a01_battery_driver); ++} ++ ++module_init(gta01_battery_init); ++module_exit(gta01_battery_exit); ++ ++MODULE_LICENSE("GPL"); ++MODULE_AUTHOR("Balaji Rao <balajirrao@openmoko.org>"); ++MODULE_DESCRIPTION("gta01 battery driver"); +diff -ruN --exclude='*.orig' --exclude='*.rej' linux-2.6.29-rc3.owrt/drivers/power/hdq.c linux-2.6.29-rc3.owrt.om/drivers/power/hdq.c +--- linux-2.6.29-rc3.owrt/drivers/power/hdq.c 1970-01-01 01:00:00.000000000 +0100 ++++ linux-2.6.29-rc3.owrt.om/drivers/power/hdq.c 2009-05-10 22:28:00.000000000 +0200 +@@ -0,0 +1,515 @@ ++/* ++ * HDQ generic GPIO bitbang driver using FIQ ++ * ++ * (C) 2006-2007 by Openmoko, Inc. ++ * Author: Andy Green <andy@openmoko.com> ++ * All rights reserved. ++ * ++ * 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/delay.h> ++#include <linux/platform_device.h> ++#include <linux/hdq.h> ++ ++#define HDQ_READ 0 ++#define HDQ_WRITE 0x80 ++ ++enum hdq_bitbang_states { ++ HDQB_IDLE = 0, ++ HDQB_TX_BREAK, ++ HDQB_TX_BREAK_RECOVERY, ++ HDQB_ADS_CALC, ++ HDQB_ADS_LOW, ++ HDQB_ADS_HIGH, ++ HDQB_WAIT_RX, ++ HDQB_DATA_RX_LOW, ++ HDQB_DATA_RX_HIGH, ++ HDQB_WAIT_TX, ++}; ++ ++static struct hdq_priv { ++ u8 hdq_probed; /* nonzero after HDQ driver probed */ ++ struct mutex hdq_lock; /* if you want to use hdq, you have to take lock */ ++ unsigned long hdq_gpio_pin; /* GTA02 = GPD14 which pin to meddle with */ ++ u8 hdq_ads; /* b7..b6 = register address, b0 = r/w */ ++ u8 hdq_tx_data; /* data to tx for write action */ ++ u8 hdq_rx_data; /* data received in read action */ ++ u8 hdq_request_ctr; /* incremented by "user" to request a transfer */ ++ u8 hdq_transaction_ctr; /* incremented after each transfer */ ++ u8 hdq_error; /* 0 = no error */ ++ u8 hdq_ctr; ++ u8 hdq_ctr2; ++ u8 hdq_bit; ++ u8 hdq_shifter; ++ u8 hdq_tx_data_done; ++ enum hdq_bitbang_states hdq_state; ++ int reported_error; ++ ++ struct hdq_platform_data *pdata; ++} hdq_priv; ++ ++ ++static void hdq_bad(void) ++{ ++ if (!hdq_priv.reported_error) ++ printk(KERN_ERR "HDQ error: %d\n", hdq_priv.hdq_error); ++ hdq_priv.reported_error = 1; ++} ++ ++static void hdq_good(void) ++{ ++ if (hdq_priv.reported_error) ++ printk(KERN_INFO "HDQ responds again\n"); ++ hdq_priv.reported_error = 0; ++} ++ ++int hdq_fiq_handler(void) ++{ ++ if (!hdq_priv.hdq_probed) ++ return 0; ++ ++ switch (hdq_priv.hdq_state) { ++ case HDQB_IDLE: ++ if (hdq_priv.hdq_request_ctr == hdq_priv.hdq_transaction_ctr) ++ break; ++ hdq_priv.hdq_ctr = 250 / HDQ_SAMPLE_PERIOD_US; ++ hdq_priv.pdata->gpio_set(0); ++ hdq_priv.pdata->gpio_dir_out(); ++ hdq_priv.hdq_tx_data_done = 0; ++ hdq_priv.hdq_state = HDQB_TX_BREAK; ++ break; ++ ++ case HDQB_TX_BREAK: /* issue low for > 190us */ ++ if (--hdq_priv.hdq_ctr == 0) { ++ hdq_priv.hdq_ctr = 60 / HDQ_SAMPLE_PERIOD_US; ++ hdq_priv.hdq_state = HDQB_TX_BREAK_RECOVERY; ++ hdq_priv.pdata->gpio_set(1); ++ } ++ break; ++ ++ case HDQB_TX_BREAK_RECOVERY: /* issue low for > 40us */ ++ if (--hdq_priv.hdq_ctr) ++ break; ++ hdq_priv.hdq_shifter = hdq_priv.hdq_ads; ++ hdq_priv.hdq_bit = 8; /* 8 bits of ads / rw */ ++ hdq_priv.hdq_tx_data_done = 0; /* doing ads */ ++ /* fallthru on last one */ ++ case HDQB_ADS_CALC: ++ if (hdq_priv.hdq_shifter & 1) ++ hdq_priv.hdq_ctr = 50 / HDQ_SAMPLE_PERIOD_US; ++ else ++ hdq_priv.hdq_ctr = 120 / HDQ_SAMPLE_PERIOD_US; ++ /* carefully precompute the other phase length */ ++ hdq_priv.hdq_ctr2 = (210 - (hdq_priv.hdq_ctr * HDQ_SAMPLE_PERIOD_US)) / ++ HDQ_SAMPLE_PERIOD_US; ++ hdq_priv.hdq_state = HDQB_ADS_LOW; ++ hdq_priv.hdq_shifter >>= 1; ++ hdq_priv.hdq_bit--; ++ hdq_priv.pdata->gpio_set(0); ++ break; ++ ++ case HDQB_ADS_LOW: ++ if (--hdq_priv.hdq_ctr) ++ break; ++ hdq_priv.pdata->gpio_set(1); ++ hdq_priv.hdq_state = HDQB_ADS_HIGH; ++ break; ++ ++ case HDQB_ADS_HIGH: ++ if (--hdq_priv.hdq_ctr2 > 1) /* account for HDQB_ADS_CALC */ ++ break; ++ if (hdq_priv.hdq_bit) { /* more bits to do */ ++ hdq_priv.hdq_state = HDQB_ADS_CALC; ++ break; ++ } ++ /* no more bits, wait it out until hdq_priv.hdq_ctr2 exhausted */ ++ if (hdq_priv.hdq_ctr2) ++ break; ++ /* ok no more bits and very last state */ ++ hdq_priv.hdq_ctr = 60 / HDQ_SAMPLE_PERIOD_US; ++ /* FIXME 0 = read */ ++ if (hdq_priv.hdq_ads & 0x80) { /* write the byte out */ ++ /* set delay before payload */ ++ hdq_priv.hdq_ctr = 300 / HDQ_SAMPLE_PERIOD_US; ++ /* already high, no need to write */ ++ hdq_priv.hdq_state = HDQB_WAIT_TX; ++ break; ++ } ++ /* read the next byte */ ++ hdq_priv.hdq_bit = 8; /* 8 bits of data */ ++ hdq_priv.hdq_ctr = 2500 / HDQ_SAMPLE_PERIOD_US; ++ hdq_priv.hdq_state = HDQB_WAIT_RX; ++ hdq_priv.pdata->gpio_dir_in(); ++ break; ++ ++ case HDQB_WAIT_TX: /* issue low for > 40us */ ++ if (--hdq_priv.hdq_ctr) ++ break; ++ if (!hdq_priv.hdq_tx_data_done) { /* was that the data sent? */ ++ hdq_priv.hdq_tx_data_done++; ++ hdq_priv.hdq_shifter = hdq_priv.hdq_tx_data; ++ hdq_priv.hdq_bit = 8; /* 8 bits of data */ ++ hdq_priv.hdq_state = HDQB_ADS_CALC; /* start sending */ ++ break; ++ } ++ hdq_priv.hdq_error = 0; ++ hdq_priv.hdq_transaction_ctr = hdq_priv.hdq_request_ctr; ++ hdq_priv.hdq_state = HDQB_IDLE; /* all tx is done */ ++ /* idle in input mode, it's pulled up by 10K */ ++ hdq_priv.pdata->gpio_dir_in(); ++ break; ++ ++ case HDQB_WAIT_RX: /* wait for battery to talk to us */ ++ if (hdq_priv.pdata->gpio_get() == 0) { ++ /* it talks to us! */ ++ hdq_priv.hdq_ctr2 = 1; ++ hdq_priv.hdq_bit = 8; /* 8 bits of data */ ++ /* timeout */ ++ hdq_priv.hdq_ctr = 500 / HDQ_SAMPLE_PERIOD_US; ++ hdq_priv.hdq_state = HDQB_DATA_RX_LOW; ++ break; ++ } ++ if (--hdq_priv.hdq_ctr == 0) { /* timed out, error */ ++ hdq_priv.hdq_error = 1; ++ hdq_priv.hdq_transaction_ctr = hdq_priv.hdq_request_ctr; ++ hdq_priv.hdq_state = HDQB_IDLE; /* abort */ ++ } ++ break; ++ ++ /* ++ * HDQ basically works by measuring the low time of the bit cell ++ * 32-50us --> '1', 80 - 145us --> '0' ++ */ ++ ++ case HDQB_DATA_RX_LOW: ++ if (hdq_priv.pdata->gpio_get()) { ++ hdq_priv.hdq_rx_data >>= 1; ++ if (hdq_priv.hdq_ctr2 <= (65 / HDQ_SAMPLE_PERIOD_US)) ++ hdq_priv.hdq_rx_data |= 0x80; ++ ++ if (--hdq_priv.hdq_bit == 0) { ++ hdq_priv.hdq_error = 0; ++ hdq_priv.hdq_transaction_ctr = ++ hdq_priv.hdq_request_ctr; ++ ++ hdq_priv.hdq_state = HDQB_IDLE; ++ } else ++ hdq_priv.hdq_state = HDQB_DATA_RX_HIGH; ++ /* timeout */ ++ hdq_priv.hdq_ctr = 1000 / HDQ_SAMPLE_PERIOD_US; ++ hdq_priv.hdq_ctr2 = 1; ++ break; ++ } ++ hdq_priv.hdq_ctr2++; ++ if (--hdq_priv.hdq_ctr) ++ break; ++ /* timed out, error */ ++ hdq_priv.hdq_error = 2; ++ hdq_priv.hdq_transaction_ctr = hdq_priv.hdq_request_ctr; ++ hdq_priv.hdq_state = HDQB_IDLE; /* abort */ ++ break; ++ ++ case HDQB_DATA_RX_HIGH: ++ if (!hdq_priv.pdata->gpio_get()) { ++ /* it talks to us! */ ++ hdq_priv.hdq_ctr2 = 1; ++ /* timeout */ ++ hdq_priv.hdq_ctr = 400 / HDQ_SAMPLE_PERIOD_US; ++ hdq_priv.hdq_state = HDQB_DATA_RX_LOW; ++ break; ++ } ++ if (--hdq_priv.hdq_ctr) ++ break; ++ /* timed out, error */ ++ hdq_priv.hdq_error = 3; ++ hdq_priv.hdq_transaction_ctr = hdq_priv.hdq_request_ctr; ++ ++ /* we're in input mode already */ ++ hdq_priv.hdq_state = HDQB_IDLE; /* abort */ ++ break; ++ } ++ ++ /* Are we interested in keeping the FIQ source alive ? */ ++ if (hdq_priv.hdq_state != HDQB_IDLE) ++ return 1; ++ else ++ return 0; ++} ++static int fiq_busy(void) ++{ ++ int request = (volatile u8)hdq_priv.hdq_request_ctr; ++ int transact = (volatile u8)hdq_priv.hdq_transaction_ctr; ++ ++ ++ return (request != transact); ++} ++ ++int hdq_initialized(void) ++{ ++ return hdq_priv.hdq_probed; ++} ++EXPORT_SYMBOL_GPL(hdq_initialized); ++ ++int hdq_read(int address) ++{ ++ int count_sleeps = 5; ++ int ret = -ETIME; ++ ++ if (!hdq_priv.hdq_probed) ++ return -EINVAL; ++ ++ mutex_lock(&hdq_priv.hdq_lock); ++ ++ hdq_priv.hdq_error = 0; ++ hdq_priv.hdq_ads = address | HDQ_READ; ++ hdq_priv.hdq_request_ctr++; ++ hdq_priv.pdata->kick_fiq(); ++ /* ++ * FIQ takes care of it while we block our calling process ++ * But we're not spinning -- other processes run normally while ++ * we wait for the result ++ */ ++ while (count_sleeps--) { ++ msleep(10); /* valid transaction always completes in < 10ms */ ++ ++ if (fiq_busy()) ++ continue; ++ ++ if (hdq_priv.hdq_error) { ++ hdq_bad(); ++ goto done; /* didn't see a response in good time */ ++ } ++ hdq_good(); ++ ++ ret = hdq_priv.hdq_rx_data; ++ goto done; ++ } ++ ++done: ++ mutex_unlock(&hdq_priv.hdq_lock); ++ return ret; ++} ++EXPORT_SYMBOL_GPL(hdq_read); ++ ++int hdq_write(int address, u8 data) ++{ ++ int count_sleeps = 5; ++ int ret = -ETIME; ++ ++ if (!hdq_priv.hdq_probed) ++ return -EINVAL; ++ ++ mutex_lock(&hdq_priv.hdq_lock); ++ ++ hdq_priv.hdq_error = 0; ++ hdq_priv.hdq_ads = address | HDQ_WRITE; ++ hdq_priv.hdq_tx_data = data; ++ hdq_priv.hdq_request_ctr++; ++ hdq_priv.pdata->kick_fiq(); ++ /* ++ * FIQ takes care of it while we block our calling process ++ * But we're not spinning -- other processes run normally while ++ * we wait for the result ++ */ ++ while (count_sleeps--) { ++ msleep(10); /* valid transaction always completes in < 10ms */ ++ ++ if (fiq_busy()) ++ continue; /* something bad with FIQ */ ++ ++ if (hdq_priv.hdq_error) { ++ hdq_bad(); ++ goto done; /* didn't see a response in good time */ ++ } ++ hdq_good(); ++ ++ ret = 0; ++ goto done; ++ } ++ ++done: ++ mutex_unlock(&hdq_priv.hdq_lock); ++ return ret; ++} ++EXPORT_SYMBOL_GPL(hdq_write); ++ ++/* sysfs */ ++ ++static ssize_t hdq_sysfs_dump(struct device *dev, struct device_attribute *attr, ++ char *buf) ++{ ++ int n; ++ int v; ++ u8 u8a[128]; /* whole address space for HDQ */ ++ char *end = buf; ++ ++ if (!hdq_priv.hdq_probed) ++ return -EINVAL; ++ ++ /* the dump does not take care about 16 bit regs, because at this ++ * bus level we don't know about the chip details ++ */ ++ for (n = 0; n < sizeof(u8a); n++) { ++ v = hdq_read(n); ++ if (v < 0) ++ goto bail; ++ u8a[n] = v; ++ } ++ ++ for (n = 0; n < sizeof(u8a); n += 16) { ++ hex_dump_to_buffer(u8a + n, sizeof(u8a), 16, 1, end, 4096, 0); ++ end += strlen(end); ++ *end++ = '\n'; ++ *end = '\0'; ++ } ++ return (end - buf); ++ ++bail: ++ return sprintf(buf, "ERROR %d\n", v); ++} ++ ++/* you write by <address> <data>, eg, "34 128" */ ++ ++#define atoi(str) simple_strtoul(((str != NULL) ? str : ""), NULL, 0) ++ ++static ssize_t hdq_sysfs_write(struct device *dev, ++ struct device_attribute *attr, ++ const char *buf, size_t count) ++{ ++ const char *end = buf + count; ++ int address = atoi(buf); ++ ++ if (!hdq_priv.hdq_probed) ++ return -EINVAL; ++ ++ while ((buf != end) && (*buf != ' ')) ++ buf++; ++ if (buf >= end) ++ return 0; ++ while ((buf < end) && (*buf == ' ')) ++ buf++; ++ if (buf >= end) ++ return 0; ++ ++ hdq_write(address, atoi(buf)); ++ ++ return count; ++} ++ ++static DEVICE_ATTR(dump, 0400, hdq_sysfs_dump, NULL); ++static DEVICE_ATTR(write, 0600, NULL, hdq_sysfs_write); ++ ++static struct attribute *hdq_sysfs_entries[] = { ++ &dev_attr_dump.attr, ++ &dev_attr_write.attr, ++ NULL ++}; ++ ++static struct attribute_group hdq_attr_group = { ++ .name = "hdq", ++ .attrs = hdq_sysfs_entries, ++}; ++ ++ ++#ifdef CONFIG_PM ++static int hdq_suspend(struct platform_device *pdev, pm_message_t state) ++{ ++ /* after 18s of this, the battery monitor will also go to sleep */ ++ hdq_priv.pdata->gpio_dir_in(); ++ hdq_priv.pdata->disable_fiq(); ++ return 0; ++} ++ ++static int hdq_resume(struct platform_device *pdev) ++{ ++ hdq_priv.pdata->gpio_set(1); ++ hdq_priv.pdata->gpio_dir_out(); ++ hdq_priv.pdata->enable_fiq(); ++ return 0; ++} ++#endif ++ ++static int __init hdq_probe(struct platform_device *pdev) ++{ ++ struct resource *r = platform_get_resource(pdev, 0, 0); ++ int ret; ++ struct hdq_platform_data *pdata = pdev->dev.platform_data; ++ ++ if (!r || !pdata) ++ return -EINVAL; ++ ++ platform_set_drvdata(pdev, NULL); ++ ++ mutex_init(&hdq_priv.hdq_lock); ++ ++ /* set our HDQ comms pin from the platform data */ ++ hdq_priv.hdq_gpio_pin = r->start; ++ hdq_priv.pdata = pdata; ++ ++ hdq_priv.pdata->gpio_set(1); ++ hdq_priv.pdata->gpio_dir_out(); ++ ++ /* Initialize FIQ */ ++ if (hdq_priv.pdata->enable_fiq() < 0) { ++ dev_err(&pdev->dev, "Could not enable FIQ source\n"); ++ return -EINVAL; ++ } ++ ++ ret = sysfs_create_group(&pdev->dev.kobj, &hdq_attr_group); ++ if (ret) ++ return ret; ++ ++ hdq_priv.hdq_probed = 1; /* we are ready to do stuff now */ ++ ++ /* ++ * if wanted, users can defer registration of devices ++ * that depend on HDQ until after we register, and can use our ++ * device as parent so suspend-resume ordering is correct ++ */ ++ if (pdata->attach_child_devices) ++ (pdata->attach_child_devices)(&pdev->dev); ++ ++ hdq_priv.pdata = pdata; ++ ++ return 0; ++} ++ ++static int hdq_remove(struct platform_device *pdev) ++{ ++ sysfs_remove_group(&pdev->dev.kobj, &hdq_attr_group); ++ return 0; ++} ++ ++static struct platform_driver hdq_driver = { ++ .probe = hdq_probe, ++ .remove = hdq_remove, ++#ifdef CONFIG_PM ++ .suspend = hdq_suspend, ++ .resume = hdq_resume, ++#endif ++ .driver = { ++ .name = "hdq", ++ }, ++}; ++ ++static int __init hdq_init(void) ++{ ++ return platform_driver_register(&hdq_driver); ++} ++ ++static void __exit hdq_exit(void) ++{ ++ platform_driver_unregister(&hdq_driver); ++} ++ ++module_init(hdq_init); ++module_exit(hdq_exit); ++ ++MODULE_AUTHOR("Andy Green <andy@openmoko.com>"); ++MODULE_DESCRIPTION("HDQ driver"); +diff -ruN --exclude='*.orig' --exclude='*.rej' linux-2.6.29-rc3.owrt/drivers/power/Kconfig linux-2.6.29-rc3.owrt.om/drivers/power/Kconfig +--- linux-2.6.29-rc3.owrt/drivers/power/Kconfig 2009-05-10 22:04:48.000000000 +0200 ++++ linux-2.6.29-rc3.owrt.om/drivers/power/Kconfig 2009-05-10 22:28:00.000000000 +0200 +@@ -88,4 +88,27 @@ + help + Say Y to include support for NXP PCF50633 Main Battery Charger. + ++config BATTERY_BQ27000_HDQ ++ tristate "BQ27000 HDQ battery monitor driver" ++ help ++ Say Y to enable support for the battery on the Neo Freerunner ++ ++config HDQ_GPIO_BITBANG ++ bool "Generic gpio based HDQ bitbang" ++ help ++ Say Y to enable supoort for generic gpio based HDQ bitbang driver. ++ This can not be built as a module. ++ ++config CHARGER_PCF50606 ++ tristate "Support for NXP PCF50606 MBC" ++ depends on MFD_PCF50606 ++ help ++ Say Y to include support for NXP PCF50606 Battery Charger. ++ ++config BATTERY_GTA01 ++ tristate "GTA01 battery driver" ++ help ++ Say Y here to enable this dumb driver for dumb gta01 batteries ++ + endif # POWER_SUPPLY ++ +diff -ruN --exclude='*.orig' --exclude='*.rej' linux-2.6.29-rc3.owrt/drivers/power/Makefile linux-2.6.29-rc3.owrt.om/drivers/power/Makefile +--- linux-2.6.29-rc3.owrt/drivers/power/Makefile 2009-05-10 22:04:48.000000000 +0200 ++++ linux-2.6.29-rc3.owrt.om/drivers/power/Makefile 2009-05-10 22:28:00.000000000 +0200 +@@ -25,4 +25,10 @@ + obj-$(CONFIG_BATTERY_WM97XX) += wm97xx_battery.o + obj-$(CONFIG_BATTERY_BQ27x00) += bq27x00_battery.o + obj-$(CONFIG_BATTERY_DA9030) += da9030_battery.o +-obj-$(CONFIG_CHARGER_PCF50633) += pcf50633-charger.o +\ No newline at end of file ++obj-$(CONFIG_CHARGER_PCF50633) += pcf50633-charger.o ++obj-$(CONFIG_CHARGER_PCF50606) += pcf50606-charger.o ++obj-$(CONFIG_BATTERY_PALMTX) += palmtx_battery.o ++obj-$(CONFIG_BATTERY_BQ27000_HDQ) += bq27000_battery.o ++obj-$(CONFIG_BATTERY_GTA01) += gta01_battery.o ++ ++obj-$(CONFIG_HDQ_GPIO_BITBANG) += hdq.o +diff -ruN --exclude='*.orig' --exclude='*.rej' linux-2.6.29-rc3.owrt/drivers/power/pcf50606-charger.c linux-2.6.29-rc3.owrt.om/drivers/power/pcf50606-charger.c +--- linux-2.6.29-rc3.owrt/drivers/power/pcf50606-charger.c 1970-01-01 01:00:00.000000000 +0100 ++++ linux-2.6.29-rc3.owrt.om/drivers/power/pcf50606-charger.c 2009-05-10 22:28:00.000000000 +0200 +@@ -0,0 +1,244 @@ ++/* NXP PCF50606 Main Battery Charger Driver ++ * ++ * (C) 2006-2008 by Openmoko, Inc. ++ * Author: Balaji Rao <balajirrao@openmoko.org> ++ * All rights reserved. ++ * ++ * Broken down from monstrous PCF50606 driver mainly by ++ * Harald Welte, Andy Green and Werner Almesberger ++ * ++ * 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. ++ * ++ */ ++ ++#include <linux/kernel.h> ++#include <linux/module.h> ++#include <linux/init.h> ++#include <linux/types.h> ++#include <linux/device.h> ++#include <linux/sysfs.h> ++#include <linux/platform_device.h> ++#include <linux/power_supply.h> ++ ++#include <linux/mfd/pcf50606/core.h> ++#include <linux/mfd/pcf50606/mbc.h> ++ ++struct pcf50606_mbc { ++ struct pcf50606 *pcf; ++ ++ int charger_online; ++ struct power_supply charger; ++}; ++ ++void pcf50606_charge_fast(struct pcf50606 *pcf, int on) ++{ ++ struct pcf50606_mbc *mbc = platform_get_drvdata(pcf->mbc_pdev); ++ ++ /* ++ * This is a fix to work around boot-time ordering problems if ++ * the s3c2410_udc is initialized before the pcf50606 mbc is ++ * ready. ++ */ ++ if (!mbc) ++ return; ++ ++ if (on) { ++ pcf50606_reg_set_bit_mask(pcf, PCF50606_REG_MBCC1, ++ PCF50606_MBCC1_AUTOFST, ++ PCF50606_MBCC1_AUTOFST);\ ++ mbc->charger_online = 1; ++ } else { ++ /* disable automatic fast-charge */ ++ pcf50606_reg_clear_bits(pcf, PCF50606_REG_MBCC1, ++ PCF50606_MBCC1_AUTOFST); ++ /* switch to idle mode to abort existing charge process */ ++ pcf50606_reg_set_bit_mask(pcf, PCF50606_REG_MBCC1, ++ PCF50606_MBCC1_CHGMOD_MASK, ++ PCF50606_MBCC1_CHGMOD_IDLE); ++ mbc->charger_online = 0; ++ } ++} ++EXPORT_SYMBOL_GPL(pcf50606_charge_fast); ++ ++static ssize_t ++show_chgmode(struct device *dev, struct device_attribute *attr, char *buf) ++{ ++ struct pcf50606_mbc *mbc = dev_get_drvdata(dev); ++ ++ u8 mbcc1 = pcf50606_reg_read(mbc->pcf, PCF50606_REG_MBCC1); ++ u8 chgmod = (mbcc1 & PCF50606_MBCC1_CHGMOD_MASK); ++ ++ return sprintf(buf, "%d\n", chgmod); ++} ++ ++static ssize_t set_chgmode(struct device *dev, struct device_attribute *attr, ++ const char *buf, size_t count) ++{ ++ struct pcf50606_mbc *mbc = dev_get_drvdata(dev); ++ u_int8_t mbcc1 = pcf50606_reg_read(mbc->pcf, PCF50606_REG_MBCC1); ++ ++ mbcc1 &= ~PCF50606_MBCC1_CHGMOD_MASK; ++ ++ if (!strcmp(buf, "qualification")) ++ mbcc1 |= PCF50606_MBCC1_CHGMOD_QUAL; ++ else if (!strcmp(buf, "pre")) ++ mbcc1 |= PCF50606_MBCC1_CHGMOD_PRE; ++ else if (!strcmp(buf, "trickle")) ++ mbcc1 |= PCF50606_MBCC1_CHGMOD_TRICKLE; ++ else if (!strcmp(buf, "fast_cccv")) ++ mbcc1 |= PCF50606_MBCC1_CHGMOD_FAST_CCCV; ++ /* We don't allow the other fast modes for security reasons */ ++ else if (!strcmp(buf, "idle")) ++ mbcc1 |= PCF50606_MBCC1_CHGMOD_IDLE; ++ else ++ return -EINVAL; ++ ++ pcf50606_reg_write(mbc->pcf, PCF50606_REG_MBCC1, mbcc1); ++ ++ return count; ++} ++ ++static DEVICE_ATTR(chgmode, S_IRUGO, show_chgmode, set_chgmode); ++ ++ ++static struct attribute *pcf50606_mbc_sysfs_entries[] = { ++ &dev_attr_chgmode.attr, ++ NULL, ++}; ++ ++static struct attribute_group mbc_attr_group = { ++ .name = NULL, /* put in device directory */ ++ .attrs = pcf50606_mbc_sysfs_entries, ++}; ++ ++static void ++pcf50606_mbc_irq_handler(int irq, void *data) ++{ ++ struct pcf50606_mbc *mbc = data; ++ ++ power_supply_changed(&mbc->charger); ++ ++ if (mbc->pcf->pdata->mbc_event_callback) ++ mbc->pcf->pdata->mbc_event_callback(mbc->pcf, irq); ++} ++ ++static int charger_get_property(struct power_supply *psy, ++ enum power_supply_property psp, ++ union power_supply_propval *val) ++{ ++ struct pcf50606_mbc *mbc = container_of(psy, struct pcf50606_mbc, charger); ++ int ret = 0; ++ ++ switch (psp) { ++ case POWER_SUPPLY_PROP_ONLINE: ++ val->intval = mbc->charger_online; ++ break; ++ default: ++ ret = -EINVAL; ++ break; ++ } ++ return ret; ++} ++ ++static enum power_supply_property power_props[] = { ++ POWER_SUPPLY_PROP_ONLINE, ++}; ++ ++static const u8 mbc_irq_handlers[] = { ++ PCF50606_IRQ_CHGINS, ++ PCF50606_IRQ_CHGRM, ++ PCF50606_IRQ_CHGFOK, ++ PCF50606_IRQ_CHGERR, ++ PCF50606_IRQ_CHGFRDY, ++ PCF50606_IRQ_CHGPROT, ++}; ++ ++static int __devinit pcf50606_mbc_probe(struct platform_device *pdev) ++{ ++ struct pcf50606_mbc *mbc; ++ struct pcf50606_subdev_pdata *pdata = pdev->dev.platform_data; ++ int ret; ++ int i; ++ u8 oocs; ++ ++ mbc = kzalloc(sizeof(*mbc), GFP_KERNEL); ++ if (!mbc) ++ return -ENOMEM; ++ ++ platform_set_drvdata(pdev, mbc); ++ mbc->pcf = pdata->pcf; ++ ++ /* Set up IRQ handlers */ ++ for (i = 0; i < ARRAY_SIZE(mbc_irq_handlers); i++) ++ pcf50606_register_irq(mbc->pcf, mbc_irq_handlers[i], ++ pcf50606_mbc_irq_handler, mbc); ++ ++ mbc->charger.name = "charger"; ++ mbc->charger.type = POWER_SUPPLY_TYPE_MAINS; ++ mbc->charger.properties = power_props; ++ mbc->charger.num_properties = ARRAY_SIZE(power_props); ++ mbc->charger.get_property = &charger_get_property; ++ mbc->charger.supplied_to = mbc->pcf->pdata->batteries; ++ mbc->charger.num_supplicants = mbc->pcf->pdata->num_batteries; ++ ++ ret = power_supply_register(&pdev->dev, &mbc->charger); ++ if (ret) { ++ dev_err(mbc->pcf->dev, "failed to register charger\n"); ++ kfree(mbc); ++ return ret; ++ } ++ ++ ret = sysfs_create_group(&pdev->dev.kobj, &mbc_attr_group); ++ if (ret) ++ dev_err(mbc->pcf->dev, "failed to create sysfs entries\n"); ++ ++ oocs = pcf50606_reg_read(mbc->pcf, PCF50606_REG_OOCS); ++ if (oocs & PCF50606_OOCS_CHGOK) ++ pcf50606_mbc_irq_handler(PCF50606_IRQ_CHGINS, mbc); ++ ++ return 0; ++} ++ ++static int __devexit pcf50606_mbc_remove(struct platform_device *pdev) ++{ ++ struct pcf50606_mbc *mbc = platform_get_drvdata(pdev); ++ int i; ++ ++ /* Remove IRQ handlers */ ++ for (i = 0; i < ARRAY_SIZE(mbc_irq_handlers); i++) ++ pcf50606_free_irq(mbc->pcf, mbc_irq_handlers[i]); ++ ++ power_supply_unregister(&mbc->charger); ++ ++ kfree(mbc); ++ ++ return 0; ++} ++ ++static struct platform_driver pcf50606_mbc_driver = { ++ .driver = { ++ .name = "pcf50606-mbc", ++ }, ++ .probe = pcf50606_mbc_probe, ++ .remove = __devexit_p(pcf50606_mbc_remove), ++}; ++ ++static int __init pcf50606_mbc_init(void) ++{ ++ return platform_driver_register(&pcf50606_mbc_driver); ++} ++module_init(pcf50606_mbc_init); ++ ++static void __exit pcf50606_mbc_exit(void) ++{ ++ platform_driver_unregister(&pcf50606_mbc_driver); ++} ++module_exit(pcf50606_mbc_exit); ++ ++MODULE_AUTHOR("Balaji Rao <balajirrao@openmoko.org>"); ++MODULE_DESCRIPTION("PCF50606 mbc driver"); ++MODULE_LICENSE("GPL"); ++MODULE_ALIAS("platform:pcf50606-mbc"); +diff -ruN --exclude='*.orig' --exclude='*.rej' linux-2.6.29-rc3.owrt/drivers/power/pcf50633-charger.c linux-2.6.29-rc3.owrt.om/drivers/power/pcf50633-charger.c +--- linux-2.6.29-rc3.owrt/drivers/power/pcf50633-charger.c 2009-05-10 22:08:44.000000000 +0200 ++++ linux-2.6.29-rc3.owrt.om/drivers/power/pcf50633-charger.c 2009-05-10 22:28:00.000000000 +0200 +@@ -36,6 +36,9 @@ + + struct power_supply usb; + struct power_supply adapter; ++ struct power_supply ac; ++ ++ struct delayed_work charging_restart_work; + }; + + int pcf50633_mbc_usb_curlim_set(struct pcf50633 *pcf, int ma) +@@ -43,15 +46,24 @@ + struct pcf50633_mbc *mbc = platform_get_drvdata(pcf->mbc_pdev); + int ret = 0; + u8 bits; ++ int charging_start = 1; ++ u8 mbcs2, chgmod; ++ unsigned int mbcc5; + +- if (ma >= 1000) ++ if (ma >= 1000) { + bits = PCF50633_MBCC7_USB_1000mA; +- else if (ma >= 500) ++ ma = 1000; ++ } else if (ma >= 500) { + bits = PCF50633_MBCC7_USB_500mA; +- else if (ma >= 100) ++ ma = 500; ++ } else if (ma >= 100) { + bits = PCF50633_MBCC7_USB_100mA; +- else ++ ma = 100; ++ } else { + bits = PCF50633_MBCC7_USB_SUSPEND; ++ charging_start = 0; ++ ma = 0; ++ } + + ret = pcf50633_reg_set_bit_mask(pcf, PCF50633_REG_MBCC7, + PCF50633_MBCC7_USB_MASK, bits); +@@ -60,6 +72,37 @@ + else + dev_info(pcf->dev, "usb curlim to %d mA\n", ma); + ++ /* ++ * We limit the charging current to be the USB current limit. ++ * The reason is that on pcf50633, when it enters PMU Standby mode, ++ * which it does when the device goes "off", the USB current limit ++ * reverts to the variant default. In at least one common case, that ++ * default is 500mA. By setting the charging current to be the same ++ * as the USB limit we set here before PMU standby, we enforce it only ++ * using the correct amount of current even when the USB current limit ++ * gets reset to the wrong thing ++ */ ++ ++ mbcc5 = (ma << 8) / mbc->pcf->pdata->chg_ref_current_ma; ++ if (mbcc5 > 255) ++ mbcc5 = 255; ++ pcf50633_reg_write(mbc->pcf, PCF50633_REG_MBCC5, mbcc5); ++ ++ mbcs2 = pcf50633_reg_read(pcf, PCF50633_REG_MBCS2); ++ chgmod = (mbcs2 & PCF50633_MBCS2_MBC_MASK); ++ ++ /* If chgmod == BATFULL, setting chgena has no effect. ++ * We need to set resume instead. ++ */ ++ if (chgmod != PCF50633_MBCS2_MBC_BAT_FULL) ++ pcf50633_reg_set_bit_mask(pcf, PCF50633_REG_MBCC1, ++ PCF50633_MBCC1_CHGENA, PCF50633_MBCC1_CHGENA); ++ else ++ pcf50633_reg_set_bit_mask(pcf, PCF50633_REG_MBCC1, ++ PCF50633_MBCC1_RESUME, PCF50633_MBCC1_RESUME); ++ ++ mbc->usb_active = charging_start; ++ + power_supply_changed(&mbc->usb); + + return ret; +@@ -84,21 +127,6 @@ + } + EXPORT_SYMBOL_GPL(pcf50633_mbc_get_status); + +-void pcf50633_mbc_set_status(struct pcf50633 *pcf, int what, int status) +-{ +- struct pcf50633_mbc *mbc = platform_get_drvdata(pcf->mbc_pdev); +- +- if (what & PCF50633_MBC_USB_ONLINE) +- mbc->usb_online = !!status; +- if (what & PCF50633_MBC_USB_ACTIVE) +- mbc->usb_active = !!status; +- if (what & PCF50633_MBC_ADAPTER_ONLINE) +- mbc->adapter_online = !!status; +- if (what & PCF50633_MBC_ADAPTER_ACTIVE) +- mbc->adapter_active = !!status; +-} +-EXPORT_SYMBOL_GPL(pcf50633_mbc_set_status); +- + static ssize_t + show_chgmode(struct device *dev, struct device_attribute *attr, char *buf) + { +@@ -149,9 +177,44 @@ + + static DEVICE_ATTR(usb_curlim, S_IRUGO | S_IWUSR, show_usblim, set_usblim); + ++static ssize_t ++show_chglim(struct device *dev, struct device_attribute *attr, char *buf) ++{ ++ struct pcf50633_mbc *mbc = dev_get_drvdata(dev); ++ u8 mbcc5 = pcf50633_reg_read(mbc->pcf, PCF50633_REG_MBCC5); ++ unsigned int ma; ++ ++ ma = (mbc->pcf->pdata->chg_ref_current_ma * mbcc5) >> 8; ++ ++ return sprintf(buf, "%u\n", ma); ++} ++ ++static ssize_t set_chglim(struct device *dev, ++ struct device_attribute *attr, const char *buf, size_t count) ++{ ++ struct pcf50633_mbc *mbc = dev_get_drvdata(dev); ++ unsigned long ma; ++ unsigned int mbcc5; ++ int ret; ++ ++ ret = strict_strtoul(buf, 10, &ma); ++ if (ret) ++ return -EINVAL; ++ ++ mbcc5 = (ma << 8) / mbc->pcf->pdata->chg_ref_current_ma; ++ if (mbcc5 > 255) ++ mbcc5 = 255; ++ pcf50633_reg_write(mbc->pcf, PCF50633_REG_MBCC5, mbcc5); ++ ++ return count; ++} ++ ++static DEVICE_ATTR(chg_curlim, S_IRUGO | S_IWUSR, show_chglim, set_chglim); ++ + static struct attribute *pcf50633_mbc_sysfs_entries[] = { + &dev_attr_chgmode.attr, + &dev_attr_usb_curlim.attr, ++ &dev_attr_chg_curlim.attr, + NULL, + }; + +@@ -160,10 +223,44 @@ + .attrs = pcf50633_mbc_sysfs_entries, + }; + ++/* MBC state machine switches into charging mode when the battery voltage ++ * falls below 96% of a battery float voltage. But the voltage drop in Li-ion ++ * batteries is marginal(1~2 %) till about 80% of its capacity - which means, ++ * after a BATFULL, charging won't be restarted until 80%. ++ * ++ * This work_struct function restarts charging every few seconds and makes ++ * sure we don't discharge too much ++ */ ++ ++static void pcf50633_mbc_charging_restart(struct work_struct *work) ++{ ++ struct pcf50633_mbc *mbc; ++ u8 mbcs2, chgmod; ++ ++ mbc = container_of(work, struct pcf50633_mbc, ++ charging_restart_work.work); ++ ++ mbcs2 = pcf50633_reg_read(mbc->pcf, PCF50633_REG_MBCS2); ++ chgmod = (mbcs2 & PCF50633_MBCS2_MBC_MASK); ++ ++ if (chgmod != PCF50633_MBCS2_MBC_BAT_FULL) ++ return; ++ ++ /* Restart charging */ ++ pcf50633_reg_set_bit_mask(mbc->pcf, PCF50633_REG_MBCC1, ++ PCF50633_MBCC1_RESUME, PCF50633_MBCC1_RESUME); ++ mbc->usb_active = 1; ++ power_supply_changed(&mbc->usb); ++ ++ dev_info(mbc->pcf->dev, "Charging restarted\n"); ++} ++ + static void + pcf50633_mbc_irq_handler(int irq, void *data) + { + struct pcf50633_mbc *mbc = data; ++ int chg_restart_interval = ++ mbc->pcf->pdata->charging_restart_interval; + + /* USB */ + if (irq == PCF50633_IRQ_USBINS) { +@@ -171,7 +268,8 @@ + } else if (irq == PCF50633_IRQ_USBREM) { + mbc->usb_online = 0; + mbc->usb_active = 0; +- pcf50633_mbc_usb_curlim_set(mbc->pcf, 0); ++ pcf50633_mbc_usb_curlim_set(mbc->pcf, 0); ++ cancel_delayed_work_sync(&mbc->charging_restart_work); + } + + /* Adapter */ +@@ -186,10 +284,18 @@ + if (irq == PCF50633_IRQ_BATFULL) { + mbc->usb_active = 0; + mbc->adapter_active = 0; +- } ++ ++ if (chg_restart_interval > 0) ++ schedule_delayed_work(&mbc->charging_restart_work, ++ chg_restart_interval); ++ } else if (irq == PCF50633_IRQ_USBLIMON) ++ mbc->usb_active = 0; ++ else if (irq == PCF50633_IRQ_USBLIMOFF) ++ mbc->usb_active = 1; + + power_supply_changed(&mbc->usb); + power_supply_changed(&mbc->adapter); ++ power_supply_changed(&mbc->ac); + + if (mbc->pcf->pdata->mbc_event_callback) + mbc->pcf->pdata->mbc_event_callback(mbc->pcf, irq); +@@ -199,7 +305,7 @@ + enum power_supply_property psp, + union power_supply_propval *val) + { +- struct pcf50633_mbc *mbc = container_of(psy, struct pcf50633_mbc, usb); ++ struct pcf50633_mbc *mbc = container_of(psy, struct pcf50633_mbc, adapter); + int ret = 0; + + switch (psp) { +@@ -219,10 +325,34 @@ + { + struct pcf50633_mbc *mbc = container_of(psy, struct pcf50633_mbc, usb); + int ret = 0; ++ u8 usblim = pcf50633_reg_read(mbc->pcf, PCF50633_REG_MBCC7) & ++ PCF50633_MBCC7_USB_MASK; ++ ++ switch (psp) { ++ case POWER_SUPPLY_PROP_ONLINE: ++ val->intval = mbc->usb_online && ++ (usblim <= PCF50633_MBCC7_USB_500mA); ++ break; ++ default: ++ ret = -EINVAL; ++ break; ++ } ++ return ret; ++} ++ ++static int ac_get_property(struct power_supply *psy, ++ enum power_supply_property psp, ++ union power_supply_propval *val) ++{ ++ struct pcf50633_mbc *mbc = container_of(psy, struct pcf50633_mbc, ac); ++ int ret = 0; ++ u8 usblim = pcf50633_reg_read(mbc->pcf, PCF50633_REG_MBCC7) & ++ PCF50633_MBCC7_USB_MASK; + + switch (psp) { + case POWER_SUPPLY_PROP_ONLINE: +- val->intval = mbc->usb_online; ++ val->intval = mbc->usb_online && ++ (usblim == PCF50633_MBCC7_USB_1000mA); + break; + default: + ret = -EINVAL; +@@ -287,6 +417,17 @@ + mbc->usb.supplied_to = mbc->pcf->pdata->batteries; + mbc->usb.num_supplicants = mbc->pcf->pdata->num_batteries; + ++ mbc->ac.name = "ac"; ++ mbc->ac.type = POWER_SUPPLY_TYPE_MAINS; ++ mbc->ac.properties = power_props; ++ mbc->ac.num_properties = ARRAY_SIZE(power_props); ++ mbc->ac.get_property = ac_get_property; ++ mbc->ac.supplied_to = mbc->pcf->pdata->batteries; ++ mbc->ac.num_supplicants = mbc->pcf->pdata->num_batteries; ++ ++ INIT_DELAYED_WORK(&mbc->charging_restart_work, ++ pcf50633_mbc_charging_restart); ++ + ret = power_supply_register(&pdev->dev, &mbc->adapter); + if (ret) { + dev_err(mbc->pcf->dev, "failed to register adapter\n"); +@@ -302,6 +443,15 @@ + return ret; + } + ++ ret = power_supply_register(&pdev->dev, &mbc->ac); ++ if (ret) { ++ dev_err(mbc->pcf->dev, "failed to register ac\n"); ++ power_supply_unregister(&mbc->adapter); ++ power_supply_unregister(&mbc->usb); ++ kfree(mbc); ++ return ret; ++ } ++ + ret = sysfs_create_group(&pdev->dev.kobj, &mbc_attr_group); + if (ret) + dev_err(mbc->pcf->dev, "failed to create sysfs entries\n"); +@@ -327,6 +477,8 @@ + power_supply_unregister(&mbc->usb); + power_supply_unregister(&mbc->adapter); + ++ cancel_delayed_work_sync(&mbc->charging_restart_work); ++ + kfree(mbc); + + return 0; +diff -ruN --exclude='*.orig' --exclude='*.rej' linux-2.6.29-rc3.owrt/drivers/regulator/core.c linux-2.6.29-rc3.owrt.om/drivers/regulator/core.c +--- linux-2.6.29-rc3.owrt/drivers/regulator/core.c 2009-05-10 22:04:48.000000000 +0200 ++++ linux-2.6.29-rc3.owrt.om/drivers/regulator/core.c 2009-05-10 22:28:00.000000000 +0200 +@@ -1102,18 +1102,19 @@ + struct regulator_dev *rdev = regulator->rdev; + int ret = 0; + +- mutex_lock(&rdev->mutex); +- if (regulator->enabled == 1) { +- ret = _regulator_disable(rdev); +- if (ret == 0) +- regulator->uA_load = 0; +- } else if (WARN(regulator->enabled <= 0, +- "unbalanced disables for supply %s\n", +- regulator->supply_name)) +- ret = -EIO; +- if (ret == 0) +- regulator->enabled--; +- mutex_unlock(&rdev->mutex); ++ if (!regulator->enabled) { ++ printk(KERN_ERR "%s: not in use by this consumer\n", ++ __func__); ++ WARN_ON(1); ++ return 0; ++ } ++ ++ mutex_lock(®ulator->rdev->mutex); ++ regulator->enabled = 0; ++ regulator->uA_load = 0; ++ ret = _regulator_disable(regulator->rdev); ++ mutex_unlock(®ulator->rdev->mutex); ++ + return ret; + } + EXPORT_SYMBOL_GPL(regulator_disable); +diff -ruN --exclude='*.orig' --exclude='*.rej' linux-2.6.29-rc3.owrt/drivers/regulator/Kconfig linux-2.6.29-rc3.owrt.om/drivers/regulator/Kconfig +--- linux-2.6.29-rc3.owrt/drivers/regulator/Kconfig 2009-05-10 22:04:48.000000000 +0200 ++++ linux-2.6.29-rc3.owrt.om/drivers/regulator/Kconfig 2009-05-10 22:28:00.000000000 +0200 +@@ -80,4 +80,10 @@ + Say Y here to support the voltage regulators and convertors + on PCF50633 + ++config REGULATOR_PCF50606 ++ bool "PCF50606 regulator driver" ++ depends on MFD_PCF50606 ++ help ++ Say Y here to support the voltage regulators and convertors ++ on PCF50606 + endif +diff -ruN --exclude='*.orig' --exclude='*.rej' linux-2.6.29-rc3.owrt/drivers/regulator/Makefile linux-2.6.29-rc3.owrt.om/drivers/regulator/Makefile +--- linux-2.6.29-rc3.owrt/drivers/regulator/Makefile 2009-05-10 22:04:48.000000000 +0200 ++++ linux-2.6.29-rc3.owrt.om/drivers/regulator/Makefile 2009-05-10 22:28:00.000000000 +0200 +@@ -12,5 +12,6 @@ + obj-$(CONFIG_REGULATOR_WM8400) += wm8400-regulator.o + obj-$(CONFIG_REGULATOR_DA903X) += da903x.o + obj-$(CONFIG_REGULATOR_PCF50633) += pcf50633-regulator.o ++obj-$(CONFIG_REGULATOR_PCF50606) += pcf50606-regulator.o + + ccflags-$(CONFIG_REGULATOR_DEBUG) += -DDEBUG +diff -ruN --exclude='*.orig' --exclude='*.rej' linux-2.6.29-rc3.owrt/drivers/regulator/pcf50606-regulator.c linux-2.6.29-rc3.owrt.om/drivers/regulator/pcf50606-regulator.c +--- linux-2.6.29-rc3.owrt/drivers/regulator/pcf50606-regulator.c 1970-01-01 01:00:00.000000000 +0100 ++++ linux-2.6.29-rc3.owrt.om/drivers/regulator/pcf50606-regulator.c 2009-05-10 22:28:00.000000000 +0200 +@@ -0,0 +1,380 @@ ++/* NXP PCF50606 PMIC Driver ++ * ++ * (C) 2006-2008 by Openmoko, Inc. ++ * Author: Balaji Rao <balajirrao@openmoko.org> ++ * All rights reserved. ++ * ++ * Broken down from monstrous PCF50606 driver mainly by ++ * Harald Welte and Andy Green and Werner Almesberger ++ * ++ * 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. ++ * ++ */ ++ ++#include <linux/kernel.h> ++#include <linux/module.h> ++#include <linux/init.h> ++#include <linux/device.h> ++#include <linux/err.h> ++#include <linux/platform_device.h> ++ ++#include <linux/mfd/pcf50606/core.h> ++#include <linux/mfd/pcf50606/pmic.h> ++ ++#define PCF50606_REGULATOR(_name, _id) \ ++ { \ ++ .name = _name, \ ++ .id = _id, \ ++ .ops = &pcf50606_regulator_ops, \ ++ .type = REGULATOR_VOLTAGE, \ ++ .owner = THIS_MODULE, \ ++ } ++ ++static const u8 pcf50606_regulator_registers[PCF50606_NUM_REGULATORS] = { ++ [PCF50606_REGULATOR_DCD] = PCF50606_REG_DCDC1, ++ [PCF50606_REGULATOR_DCDE] = PCF50606_REG_DCDEC1, ++ [PCF50606_REGULATOR_DCUD] = PCF50606_REG_DCUDC1, ++ [PCF50606_REGULATOR_D1REG] = PCF50606_REG_D1REGC1, ++ [PCF50606_REGULATOR_D2REG] = PCF50606_REG_D2REGC1, ++ [PCF50606_REGULATOR_D3REG] = PCF50606_REG_D3REGC1, ++ [PCF50606_REGULATOR_LPREG] = PCF50606_REG_LPREGC1, ++ [PCF50606_REGULATOR_IOREG] = PCF50606_REG_IOREGC, ++}; ++ ++static u8 dcudc_voltage(unsigned int millivolts) ++{ ++ if (millivolts < 900) ++ return 0; ++ if (millivolts > 5500) ++ return 0x1f; ++ if (millivolts <= 3300) { ++ millivolts -= 900; ++ return millivolts/300; ++ } ++ if (millivolts < 4000) ++ return 0x0f; ++ else { ++ millivolts -= 4000; ++ return millivolts/100; ++ } ++} ++ ++static unsigned int dcudc_2voltage(u8 bits) ++{ ++ bits &= 0x1f; ++ if (bits < 0x08) ++ return 900 + bits * 300; ++ else if (bits < 0x10) ++ return 3300; ++ else ++ return 4000 + bits * 100; ++} ++ ++static u8 dcdec_voltage(unsigned int millivolts) ++{ ++ if (millivolts < 900) ++ return 0; ++ else if (millivolts > 3300) ++ return 0x0f; ++ ++ millivolts -= 900; ++ return millivolts/300; ++} ++ ++static unsigned int dcdec_2voltage(u8 bits) ++{ ++ bits &= 0x0f; ++ return 900 + bits*300; ++} ++ ++static u8 dcdc_voltage(unsigned int millivolts) ++{ ++ if (millivolts < 900) ++ return 0; ++ else if (millivolts > 3600) ++ return 0x1f; ++ ++ if (millivolts < 1500) { ++ millivolts -= 900; ++ return millivolts/25; ++ } else { ++ millivolts -= 1500; ++ return 0x18 + millivolts/300; ++ } ++} ++ ++static unsigned int dcdc_2voltage(u8 bits) ++{ ++ bits &= 0x1f; ++ if ((bits & 0x18) == 0x18) ++ return 1500 + ((bits & 0x7) * 300); ++ else ++ return 900 + (bits * 25); ++} ++ ++static u8 dx_voltage(unsigned int millivolts) ++{ ++ if (millivolts < 900) ++ return 0; ++ else if (millivolts > 3300) ++ return 0x18; ++ ++ millivolts -= 900; ++ return millivolts/100; ++} ++ ++static unsigned int dx_2voltage(u8 bits) ++{ ++ bits &= 0x1f; ++ return 900 + (bits * 100); ++} ++ ++static int pcf50606_regulator_set_voltage(struct regulator_dev *rdev, ++ int min_uV, int max_uV) ++{ ++ struct pcf50606 *pcf; ++ int regulator_id, millivolts, rc; ++ u8 volt_bits, regnr; ++ ++ pcf = rdev_get_drvdata(rdev); ++ ++ regulator_id = rdev_get_id(rdev); ++ if (regulator_id >= PCF50606_NUM_REGULATORS) ++ return -EINVAL; ++ ++ millivolts = min_uV / 1000; ++ ++ switch (regulator_id) { ++ case PCF50606_REGULATOR_DCD: ++ volt_bits = dcdc_voltage(millivolts); ++ rc = pcf50606_reg_set_bit_mask(pcf, PCF50606_REG_DCDC1, 0x1f, ++ volt_bits); ++ break; ++ case PCF50606_REGULATOR_DCDE: ++ volt_bits = dcdec_voltage(millivolts); ++ rc = pcf50606_reg_set_bit_mask(pcf, PCF50606_REG_DCDEC1, 0x0f, ++ volt_bits); ++ break; ++ case PCF50606_REGULATOR_DCUD: ++ volt_bits = dcudc_voltage(millivolts); ++ rc = pcf50606_reg_set_bit_mask(pcf, PCF50606_REG_DCUDC1, 0x1f, ++ volt_bits); ++ break; ++ case PCF50606_REGULATOR_D1REG: ++ case PCF50606_REGULATOR_D2REG: ++ case PCF50606_REGULATOR_D3REG: ++ regnr = PCF50606_REG_D1REGC1 + ++ (regulator_id - PCF50606_REGULATOR_D1REG); ++ volt_bits = dx_voltage(millivolts); ++ rc = pcf50606_reg_set_bit_mask(pcf, regnr, 0x1f, volt_bits); ++ break; ++ case PCF50606_REGULATOR_LPREG: ++ volt_bits = dx_voltage(millivolts); ++ rc = pcf50606_reg_set_bit_mask(pcf, PCF50606_REG_LPREGC1, 0x1f, ++ volt_bits); ++ break; ++ case PCF50606_REGULATOR_IOREG: ++ if (millivolts < 1800) ++ return -EINVAL; ++ volt_bits = dx_voltage(millivolts); ++ rc = pcf50606_reg_set_bit_mask(pcf, PCF50606_REG_IOREGC, 0x1f, ++ volt_bits); ++ break; ++ default: ++ return -EINVAL; ++ } ++ ++ return rc; ++} ++ ++static int pcf50606_regulator_get_voltage(struct regulator_dev *rdev) ++{ ++ struct pcf50606 *pcf; ++ u8 volt_bits, regnr; ++ int rc = 0, regulator_id; ++ ++ ++ pcf = rdev_get_drvdata(rdev); ++ ++ regulator_id = rdev_get_id(rdev); ++ if (regulator_id >= PCF50606_NUM_REGULATORS) ++ return -EINVAL; ++ ++ switch (regulator_id) { ++ case PCF50606_REGULATOR_DCD: ++ volt_bits = pcf50606_reg_read(pcf, PCF50606_REG_DCDC1) & 0x1f; ++ rc = dcdc_2voltage(volt_bits); ++ break; ++ case PCF50606_REGULATOR_DCDE: ++ volt_bits = pcf50606_reg_read(pcf, PCF50606_REG_DCDEC1) & 0x0f; ++ rc = dcdec_2voltage(volt_bits); ++ break; ++ case PCF50606_REGULATOR_DCUD: ++ volt_bits = pcf50606_reg_read(pcf, PCF50606_REG_DCUDC1) & 0x1f; ++ rc = dcudc_2voltage(volt_bits); ++ break; ++ case PCF50606_REGULATOR_D1REG: ++ case PCF50606_REGULATOR_D2REG: ++ case PCF50606_REGULATOR_D3REG: ++ regnr = PCF50606_REG_D1REGC1 + (regulator_id - PCF50606_REGULATOR_D1REG); ++ volt_bits = pcf50606_reg_read(pcf, regnr) & 0x1f; ++ if (volt_bits > 0x18) ++ volt_bits = 0x18; ++ rc = dx_2voltage(volt_bits); ++ break; ++ case PCF50606_REGULATOR_LPREG: ++ volt_bits = pcf50606_reg_read(pcf, PCF50606_REG_LPREGC1) & 0x1f; ++ if (volt_bits > 0x18) ++ volt_bits = 0x18; ++ rc = dx_2voltage(volt_bits); ++ break; ++ case PCF50606_REGULATOR_IOREG: ++ volt_bits = pcf50606_reg_read(pcf, PCF50606_REG_IOREGC) & 0x1f; ++ if (volt_bits > 0x18) ++ volt_bits = 0x18; ++ rc = dx_2voltage(volt_bits); ++ break; ++ default: ++ return -EINVAL; ++ } ++ ++ return rc * 1000; ++ ++} ++ ++static int pcf50606_regulator_enable(struct regulator_dev *rdev) ++{ ++ struct pcf50606 *pcf = rdev_get_drvdata(rdev); ++ int regulator_id; ++ u8 regnr; ++ ++ regulator_id = rdev_get_id(rdev); ++ if (regulator_id >= PCF50606_NUM_REGULATORS) ++ return -EINVAL; ++ ++ regnr = pcf50606_regulator_registers[regulator_id]; ++ ++ return pcf50606_reg_set_bit_mask(pcf, regnr, 0xe0, 0xe0); ++} ++ ++static int pcf50606_regulator_disable(struct regulator_dev *rdev) ++{ ++ struct pcf50606 *pcf = rdev_get_drvdata(rdev); ++ int regulator_id; ++ u8 regnr; ++ ++ regulator_id = rdev_get_id(rdev); ++ if (regulator_id >= PCF50606_NUM_REGULATORS) ++ return -EINVAL; ++ ++ /* IOREG cannot be powered off since it powers the PMU I2C */ ++ if (regulator_id == PCF50606_REGULATOR_IOREG) ++ return -EINVAL; ++ ++ regnr = pcf50606_regulator_registers[regulator_id]; ++ ++ return pcf50606_reg_set_bit_mask(pcf, regnr, 0xe0, 0); ++} ++ ++static int pcf50606_regulator_is_enabled(struct regulator_dev *rdev) ++{ ++ struct pcf50606 *pcf = rdev_get_drvdata(rdev); ++ int regulator_id = rdev_get_id(rdev); ++ u8 regnr, val; ++ ++ regulator_id = rdev_get_id(rdev); ++ if (regulator_id >= PCF50606_NUM_REGULATORS) ++ return -EINVAL; ++ ++ /* the *ENA register is always one after the *OUT register */ ++ regnr = pcf50606_regulator_registers[regulator_id]; ++ val = (pcf50606_reg_read(pcf, regnr) & 0xe0) >> 5; ++ ++ /* PWREN1 = 1, PWREN2 = 1, see table 16 of datasheet */ ++ if (val == 0 || val == 5) ++ return 0; ++ ++ return 1; ++} ++ ++static struct regulator_ops pcf50606_regulator_ops = { ++ .set_voltage = pcf50606_regulator_set_voltage, ++ .get_voltage = pcf50606_regulator_get_voltage, ++ .enable = pcf50606_regulator_enable, ++ .disable = pcf50606_regulator_disable, ++ .is_enabled = pcf50606_regulator_is_enabled, ++}; ++ ++static struct regulator_desc regulators[] = { ++ [PCF50606_REGULATOR_DCD] = ++ PCF50606_REGULATOR("dcd", PCF50606_REGULATOR_DCD), ++ [PCF50606_REGULATOR_DCDE] = ++ PCF50606_REGULATOR("dcde", PCF50606_REGULATOR_DCDE), ++ [PCF50606_REGULATOR_DCUD] = ++ PCF50606_REGULATOR("dcud", PCF50606_REGULATOR_DCUD), ++ [PCF50606_REGULATOR_D1REG] = ++ PCF50606_REGULATOR("d1reg", PCF50606_REGULATOR_D1REG), ++ [PCF50606_REGULATOR_D2REG] = ++ PCF50606_REGULATOR("d2reg", PCF50606_REGULATOR_D2REG), ++ [PCF50606_REGULATOR_D3REG] = ++ PCF50606_REGULATOR("d3reg", PCF50606_REGULATOR_D3REG), ++ [PCF50606_REGULATOR_LPREG] = ++ PCF50606_REGULATOR("lpreg", PCF50606_REGULATOR_LPREG), ++ [PCF50606_REGULATOR_IOREG] = ++ PCF50606_REGULATOR("ioreg", PCF50606_REGULATOR_IOREG), ++}; ++ ++static int __devinit pcf50606_regulator_probe(struct platform_device *pdev) ++{ ++ struct regulator_dev *rdev; ++ struct pcf50606 *pcf; ++ ++ /* Already set by core driver */ ++ pcf = platform_get_drvdata(pdev); ++ ++ rdev = regulator_register(®ulators[pdev->id], &pdev->dev, pcf); ++ if (IS_ERR(rdev)) ++ return PTR_ERR(rdev); ++ ++ if (pcf->pdata->regulator_registered) ++ pcf->pdata->regulator_registered(pcf, pdev->id); ++ ++ return 0; ++} ++ ++static int __devexit pcf50606_regulator_remove(struct platform_device *pdev) ++{ ++ struct regulator_dev *rdev = platform_get_drvdata(pdev); ++ ++ regulator_unregister(rdev); ++ ++ return 0; ++} ++ ++static struct platform_driver pcf50606_regulator_driver = { ++ .driver = { ++ .name = "pcf50606-regltr", ++ }, ++ .probe = pcf50606_regulator_probe, ++ .remove = __devexit_p(pcf50606_regulator_remove), ++}; ++ ++static int __init pcf50606_regulator_init(void) ++{ ++ return platform_driver_register(&pcf50606_regulator_driver); ++} ++module_init(pcf50606_regulator_init); ++ ++static void __exit pcf50606_regulator_exit(void) ++{ ++ platform_driver_unregister(&pcf50606_regulator_driver); ++} ++module_exit(pcf50606_regulator_exit); ++ ++MODULE_AUTHOR("Balaji Rao <balajirrao@openmoko.org>"); ++MODULE_DESCRIPTION("PCF50606 regulator driver"); ++MODULE_LICENSE("GPL"); ++MODULE_ALIAS("platform:pcf50606-regulator"); +diff -ruN --exclude='*.orig' --exclude='*.rej' linux-2.6.29-rc3.owrt/drivers/rtc/Kconfig linux-2.6.29-rc3.owrt.om/drivers/rtc/Kconfig +--- linux-2.6.29-rc3.owrt/drivers/rtc/Kconfig 2009-05-10 22:08:44.000000000 +0200 ++++ linux-2.6.29-rc3.owrt.om/drivers/rtc/Kconfig 2009-05-10 22:28:00.000000000 +0200 +@@ -223,6 +223,13 @@ + This driver can also be built as a module. If so, the module + will be called rtc-pcf8583. + ++config RTC_DRV_PCF50606 ++ depends on MFD_PCF50606 ++ tristate "Philips PCF50606" ++ help ++ If you say yes here you get support for the Philips PCF50606 ++ PMU's RTC. ++ + config RTC_DRV_M41T80 + tristate "ST M41T65/M41T80/81/82/83/84/85/87" + help +diff -ruN --exclude='*.orig' --exclude='*.rej' linux-2.6.29-rc3.owrt/drivers/rtc/Makefile linux-2.6.29-rc3.owrt.om/drivers/rtc/Makefile +--- linux-2.6.29-rc3.owrt/drivers/rtc/Makefile 2009-05-10 22:08:44.000000000 +0200 ++++ linux-2.6.29-rc3.owrt.om/drivers/rtc/Makefile 2009-05-10 22:28:00.000000000 +0200 +@@ -76,3 +76,4 @@ + obj-$(CONFIG_RTC_DRV_WM8350) += rtc-wm8350.o + obj-$(CONFIG_RTC_DRV_X1205) += rtc-x1205.o + obj-$(CONFIG_RTC_DRV_PCF50633) += rtc-pcf50633.o ++obj-$(CONFIG_RTC_DRV_PCF50606) += rtc-pcf50606.o +diff -ruN --exclude='*.orig' --exclude='*.rej' linux-2.6.29-rc3.owrt/drivers/rtc/rtc-pcf50606.c linux-2.6.29-rc3.owrt.om/drivers/rtc/rtc-pcf50606.c +--- linux-2.6.29-rc3.owrt/drivers/rtc/rtc-pcf50606.c 1970-01-01 01:00:00.000000000 +0100 ++++ linux-2.6.29-rc3.owrt.om/drivers/rtc/rtc-pcf50606.c 2009-05-10 22:28:00.000000000 +0200 +@@ -0,0 +1,335 @@ ++/* NXP PCF50606 RTC Driver ++ * ++ * (C) 2006-2008 by Openmoko, Inc. ++ * Author: Balaji Rao <balajirrao@openmoko.org> ++ * All rights reserved. ++ * ++ * Broken down from monstrous PCF50606 driver mainly by ++ * Harald Welte, Andy Green and Werner Almesberger ++ * ++ * 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. ++ * ++ */ ++ ++#include <linux/kernel.h> ++#include <linux/module.h> ++#include <linux/init.h> ++#include <linux/device.h> ++#include <linux/platform_device.h> ++#include <linux/rtc.h> ++#include <linux/bcd.h> ++#include <linux/err.h> ++ ++#include <linux/mfd/pcf50606/core.h> ++ ++#define PCF50606_REG_RTCSC 0x0a /* Second */ ++#define PCF50606_REG_RTCMN 0x0b /* Minute */ ++#define PCF50606_REG_RTCHR 0x0c /* Hour */ ++#define PCF50606_REG_RTCWD 0x0d /* Weekday */ ++#define PCF50606_REG_RTCDT 0x0e /* Day */ ++#define PCF50606_REG_RTCMT 0x0f /* Month */ ++#define PCF50606_REG_RTCYR 0x10 /* Year */ ++#define PCF50606_REG_RTCSCA 0x11 /* Alarm Second */ ++#define PCF50606_REG_RTCMNA 0x12 /* Alarm Minute */ ++#define PCF50606_REG_RTCHRA 0x13 /* Alarm Hour */ ++#define PCF50606_REG_RTCWDA 0x14 /* Alarm Weekday */ ++#define PCF50606_REG_RTCDTA 0x15 /* Alarm Day */ ++#define PCF50606_REG_RTCMTA 0x16 /* Alarm Month */ ++#define PCF50606_REG_RTCYRA 0x17 /* Alarm Year */ ++ ++enum pcf50606_time_indexes { ++ PCF50606_TI_SEC, ++ PCF50606_TI_MIN, ++ PCF50606_TI_HOUR, ++ PCF50606_TI_WKDAY, ++ PCF50606_TI_DAY, ++ PCF50606_TI_MONTH, ++ PCF50606_TI_YEAR, ++ PCF50606_TI_EXTENT /* always last */ ++}; ++ ++struct pcf50606_time { ++ u_int8_t time[PCF50606_TI_EXTENT]; ++}; ++ ++struct pcf50606_rtc { ++ int alarm_enabled; ++ int second_enabled; ++ ++ struct pcf50606 *pcf; ++ struct rtc_device *rtc_dev; ++}; ++ ++static void pcf2rtc_time(struct rtc_time *rtc, struct pcf50606_time *pcf) ++{ ++ rtc->tm_sec = bcd2bin(pcf->time[PCF50606_TI_SEC]); ++ rtc->tm_min = bcd2bin(pcf->time[PCF50606_TI_MIN]); ++ rtc->tm_hour = bcd2bin(pcf->time[PCF50606_TI_HOUR]); ++ rtc->tm_wday = bcd2bin(pcf->time[PCF50606_TI_WKDAY]); ++ rtc->tm_mday = bcd2bin(pcf->time[PCF50606_TI_DAY]); ++ rtc->tm_mon = bcd2bin(pcf->time[PCF50606_TI_MONTH]) - 1; ++ rtc->tm_year = bcd2bin(pcf->time[PCF50606_TI_YEAR]) + 100; ++} ++ ++static void rtc2pcf_time(struct pcf50606_time *pcf, struct rtc_time *rtc) ++{ ++ pcf->time[PCF50606_TI_SEC] = bin2bcd(rtc->tm_sec); ++ pcf->time[PCF50606_TI_MIN] = bin2bcd(rtc->tm_min); ++ pcf->time[PCF50606_TI_HOUR] = bin2bcd(rtc->tm_hour); ++ pcf->time[PCF50606_TI_WKDAY] = bin2bcd(rtc->tm_wday); ++ pcf->time[PCF50606_TI_DAY] = bin2bcd(rtc->tm_mday); ++ pcf->time[PCF50606_TI_MONTH] = bin2bcd(rtc->tm_mon + 1); ++ pcf->time[PCF50606_TI_YEAR] = bin2bcd(rtc->tm_year % 100); ++} ++ ++static int ++pcf50606_rtc_ioctl(struct device *dev, unsigned int cmd, unsigned long arg) ++{ ++ struct pcf50606_rtc *rtc = dev_get_drvdata(dev); ++ ++ switch (cmd) { ++ case RTC_AIE_OFF: ++ rtc->alarm_enabled = 0; ++ pcf50606_irq_mask(rtc->pcf, PCF50606_IRQ_ALARM); ++ return 0; ++ case RTC_AIE_ON: ++ rtc->alarm_enabled = 1; ++ pcf50606_irq_unmask(rtc->pcf, PCF50606_IRQ_ALARM); ++ return 0; ++ case RTC_UIE_OFF: ++ rtc->second_enabled = 0; ++ pcf50606_irq_mask(rtc->pcf, PCF50606_IRQ_SECOND); ++ return 0; ++ case RTC_UIE_ON: ++ rtc->second_enabled = 1; ++ pcf50606_irq_unmask(rtc->pcf, PCF50606_IRQ_SECOND); ++ return 0; ++ } ++ ++ return -ENOIOCTLCMD; ++} ++ ++static int pcf50606_rtc_read_time(struct device *dev, struct rtc_time *tm) ++{ ++ struct pcf50606_rtc *rtc; ++ struct pcf50606_time pcf_tm; ++ int ret; ++ ++ rtc = dev_get_drvdata(dev); ++ ++ ret = pcf50606_read_block(rtc->pcf, PCF50606_REG_RTCSC, ++ PCF50606_TI_EXTENT, ++ &pcf_tm.time[0]); ++ if (ret != PCF50606_TI_EXTENT) { ++ dev_err(dev, "Failed to read time\n"); ++ return -EIO; ++ } ++ ++ dev_dbg(dev, "PCF_TIME: %02x.%02x.%02x %02x:%02x:%02x\n", ++ pcf_tm.time[PCF50606_TI_DAY], ++ pcf_tm.time[PCF50606_TI_MONTH], ++ pcf_tm.time[PCF50606_TI_YEAR], ++ pcf_tm.time[PCF50606_TI_HOUR], ++ pcf_tm.time[PCF50606_TI_MIN], ++ pcf_tm.time[PCF50606_TI_SEC]); ++ ++ pcf2rtc_time(tm, &pcf_tm); ++ ++ dev_dbg(dev, "RTC_TIME: %u.%u.%u %u:%u:%u\n", ++ tm->tm_mday, tm->tm_mon, tm->tm_year, ++ tm->tm_hour, tm->tm_min, tm->tm_sec); ++ ++ return rtc_valid_tm(tm); ++} ++ ++static int pcf50606_rtc_set_time(struct device *dev, struct rtc_time *tm) ++{ ++ struct pcf50606_rtc *rtc; ++ struct pcf50606_time pcf_tm; ++ int second_masked, alarm_masked, ret = 0; ++ ++ rtc = dev_get_drvdata(dev); ++ ++ dev_dbg(dev, "RTC_TIME: %u.%u.%u %u:%u:%u\n", ++ tm->tm_mday, tm->tm_mon, tm->tm_year, ++ tm->tm_hour, tm->tm_min, tm->tm_sec); ++ ++ rtc2pcf_time(&pcf_tm, tm); ++ ++ dev_dbg(dev, "PCF_TIME: %02x.%02x.%02x %02x:%02x:%02x\n", ++ pcf_tm.time[PCF50606_TI_DAY], ++ pcf_tm.time[PCF50606_TI_MONTH], ++ pcf_tm.time[PCF50606_TI_YEAR], ++ pcf_tm.time[PCF50606_TI_HOUR], ++ pcf_tm.time[PCF50606_TI_MIN], ++ pcf_tm.time[PCF50606_TI_SEC]); ++ ++ ++ second_masked = pcf50606_irq_mask_get(rtc->pcf, PCF50606_IRQ_SECOND); ++ alarm_masked = pcf50606_irq_mask_get(rtc->pcf, PCF50606_IRQ_ALARM); ++ ++ if (!second_masked) ++ pcf50606_irq_mask(rtc->pcf, PCF50606_IRQ_SECOND); ++ if (!alarm_masked) ++ pcf50606_irq_mask(rtc->pcf, PCF50606_IRQ_ALARM); ++ ++ /* Returns 0 on success */ ++ ret = pcf50606_write_block(rtc->pcf, PCF50606_REG_RTCSC, ++ PCF50606_TI_EXTENT, ++ &pcf_tm.time[0]); ++ ++ if (!second_masked) ++ pcf50606_irq_unmask(rtc->pcf, PCF50606_IRQ_SECOND); ++ if (!alarm_masked) ++ pcf50606_irq_unmask(rtc->pcf, PCF50606_IRQ_ALARM); ++ ++ return ret; ++} ++ ++static int pcf50606_rtc_read_alarm(struct device *dev, struct rtc_wkalrm *alrm) ++{ ++ struct pcf50606_rtc *rtc; ++ struct pcf50606_time pcf_tm; ++ int ret = 0; ++ ++ rtc = dev_get_drvdata(dev); ++ ++ alrm->enabled = rtc->alarm_enabled; ++ ++ ret = pcf50606_read_block(rtc->pcf, PCF50606_REG_RTCSCA, ++ PCF50606_TI_EXTENT, &pcf_tm.time[0]); ++ if (ret != PCF50606_TI_EXTENT) { ++ dev_err(dev, "Failed to read time\n"); ++ return -EIO; ++ } ++ ++ pcf2rtc_time(&alrm->time, &pcf_tm); ++ ++ return rtc_valid_tm(&alrm->time); ++} ++ ++static int pcf50606_rtc_set_alarm(struct device *dev, struct rtc_wkalrm *alrm) ++{ ++ struct pcf50606_rtc *rtc; ++ struct pcf50606_time pcf_tm; ++ int alarm_masked, ret = 0; ++ ++ rtc = dev_get_drvdata(dev); ++ ++ rtc2pcf_time(&pcf_tm, &alrm->time); ++ ++ /* do like mktime does and ignore tm_wday */ ++ pcf_tm.time[PCF50606_TI_WKDAY] = 7; ++ ++ alarm_masked = pcf50606_irq_mask_get(rtc->pcf, PCF50606_IRQ_ALARM); ++ ++ /* disable alarm interrupt */ ++ if (!alarm_masked) ++ pcf50606_irq_mask(rtc->pcf, PCF50606_IRQ_ALARM); ++ ++ /* Returns 0 on success */ ++ ret = pcf50606_write_block(rtc->pcf, PCF50606_REG_RTCSCA, ++ PCF50606_TI_EXTENT, &pcf_tm.time[0]); ++ ++ if (!alarm_masked) ++ pcf50606_irq_unmask(rtc->pcf, PCF50606_IRQ_ALARM); ++ ++ return ret; ++} ++ ++static struct rtc_class_ops pcf50606_rtc_ops = { ++ .ioctl = pcf50606_rtc_ioctl, ++ .read_time = pcf50606_rtc_read_time, ++ .set_time = pcf50606_rtc_set_time, ++ .read_alarm = pcf50606_rtc_read_alarm, ++ .set_alarm = pcf50606_rtc_set_alarm, ++}; ++ ++static void pcf50606_rtc_irq(int irq, void *data) ++{ ++ struct pcf50606_rtc *rtc = data; ++ ++ switch (irq) { ++ case PCF50606_IRQ_ALARM: ++ rtc_update_irq(rtc->rtc_dev, 1, RTC_AF | RTC_IRQF); ++ break; ++ case PCF50606_IRQ_SECOND: ++ rtc_update_irq(rtc->rtc_dev, 1, RTC_UF | RTC_IRQF); ++ break; ++ } ++} ++ ++static int __devinit pcf50606_rtc_probe(struct platform_device *pdev) ++{ ++ struct pcf50606_subdev_pdata *pdata; ++ struct pcf50606_rtc *rtc; ++ ++ ++ rtc = kzalloc(sizeof(*rtc), GFP_KERNEL); ++ if (!rtc) ++ return -ENOMEM; ++ ++ pdata = pdev->dev.platform_data; ++ rtc->pcf = pdata->pcf; ++ platform_set_drvdata(pdev, rtc); ++ rtc->rtc_dev = rtc_device_register("pcf50606-rtc", &pdev->dev, ++ &pcf50606_rtc_ops, THIS_MODULE); ++ ++ if (IS_ERR(rtc->rtc_dev)) { ++ kfree(rtc); ++ return PTR_ERR(rtc->rtc_dev); ++ } ++ ++ pcf50606_register_irq(rtc->pcf, PCF50606_IRQ_ALARM, ++ pcf50606_rtc_irq, rtc); ++ pcf50606_register_irq(rtc->pcf, PCF50606_IRQ_SECOND, ++ pcf50606_rtc_irq, rtc); ++ ++ return 0; ++} ++ ++ ++static int __devexit pcf50606_rtc_remove(struct platform_device *pdev) ++{ ++ struct pcf50606_rtc *rtc; ++ ++ rtc = platform_get_drvdata(pdev); ++ ++ pcf50606_free_irq(rtc->pcf, PCF50606_IRQ_ALARM); ++ pcf50606_free_irq(rtc->pcf, PCF50606_IRQ_SECOND); ++ ++ rtc_device_unregister(rtc->rtc_dev); ++ ++ kfree(rtc); ++ ++ return 0; ++} ++ ++ ++static struct platform_driver pcf50606_rtc_driver = { ++ .driver = { ++ .name = "pcf50606-rtc", ++ }, ++ .probe = pcf50606_rtc_probe, ++ .remove = __devexit_p(pcf50606_rtc_remove), ++}; ++ ++static int __init pcf50606_rtc_init(void) ++{ ++ return platform_driver_register(&pcf50606_rtc_driver); ++} ++module_init(pcf50606_rtc_init); ++ ++static void __exit pcf50606_rtc_exit(void) ++{ ++ platform_driver_unregister(&pcf50606_rtc_driver); ++} ++module_exit(pcf50606_rtc_exit); ++ ++MODULE_DESCRIPTION("PCF50606 RTC driver"); ++MODULE_AUTHOR("Balaji Rao <balajirrao@openmoko.org>"); ++MODULE_LICENSE("GPL"); ++ +diff -ruN --exclude='*.orig' --exclude='*.rej' linux-2.6.29-rc3.owrt/drivers/rtc/rtc-pcf50633.c linux-2.6.29-rc3.owrt.om/drivers/rtc/rtc-pcf50633.c +--- linux-2.6.29-rc3.owrt/drivers/rtc/rtc-pcf50633.c 2009-05-10 22:04:49.000000000 +0200 ++++ linux-2.6.29-rc3.owrt.om/drivers/rtc/rtc-pcf50633.c 2009-05-10 22:28:00.000000000 +0200 +@@ -58,6 +58,7 @@ + struct pcf50633_rtc { + int alarm_enabled; + int second_enabled; ++ int alarm_pending; + + struct pcf50633 *pcf; + struct rtc_device *rtc_dev; +@@ -70,7 +71,7 @@ + rtc->tm_hour = bcd2bin(pcf->time[PCF50633_TI_HOUR]); + rtc->tm_wday = bcd2bin(pcf->time[PCF50633_TI_WKDAY]); + rtc->tm_mday = bcd2bin(pcf->time[PCF50633_TI_DAY]); +- rtc->tm_mon = bcd2bin(pcf->time[PCF50633_TI_MONTH]); ++ rtc->tm_mon = bcd2bin(pcf->time[PCF50633_TI_MONTH]) - 1; + rtc->tm_year = bcd2bin(pcf->time[PCF50633_TI_YEAR]) + 100; + } + +@@ -81,7 +82,7 @@ + pcf->time[PCF50633_TI_HOUR] = bin2bcd(rtc->tm_hour); + pcf->time[PCF50633_TI_WKDAY] = bin2bcd(rtc->tm_wday); + pcf->time[PCF50633_TI_DAY] = bin2bcd(rtc->tm_mday); +- pcf->time[PCF50633_TI_MONTH] = bin2bcd(rtc->tm_mon); ++ pcf->time[PCF50633_TI_MONTH] = bin2bcd(rtc->tm_mon + 1); + pcf->time[PCF50633_TI_YEAR] = bin2bcd(rtc->tm_year % 100); + } + +@@ -209,6 +210,7 @@ + rtc = dev_get_drvdata(dev); + + alrm->enabled = rtc->alarm_enabled; ++ alrm->pending = rtc->alarm_pending; + + ret = pcf50633_read_block(rtc->pcf, PCF50633_REG_RTCSCA, + PCF50633_TI_EXTENT, &pcf_tm.time[0]); +@@ -244,9 +246,12 @@ + /* Returns 0 on success */ + ret = pcf50633_write_block(rtc->pcf, PCF50633_REG_RTCSCA, + PCF50633_TI_EXTENT, &pcf_tm.time[0]); ++ if (!alrm->enabled) ++ rtc->alarm_pending = 0; + +- if (!alarm_masked) ++ if (!alarm_masked || alrm->enabled) + pcf50633_irq_unmask(rtc->pcf, PCF50633_IRQ_ALARM); ++ rtc->alarm_enabled = alrm->enabled; + + return ret; + } +@@ -267,6 +272,7 @@ + switch (irq) { + case PCF50633_IRQ_ALARM: + rtc_update_irq(rtc->rtc_dev, 1, RTC_AF | RTC_IRQF); ++ rtc->alarm_pending = 1; + break; + case PCF50633_IRQ_SECOND: + rtc_update_irq(rtc->rtc_dev, 1, RTC_UF | RTC_IRQF); +diff -ruN --exclude='*.orig' --exclude='*.rej' linux-2.6.29-rc3.owrt/drivers/serial/s3c2410.c linux-2.6.29-rc3.owrt.om/drivers/serial/s3c2410.c +--- linux-2.6.29-rc3.owrt/drivers/serial/s3c2410.c 2009-05-10 22:04:48.000000000 +0200 ++++ linux-2.6.29-rc3.owrt.om/drivers/serial/s3c2410.c 2009-05-10 22:28:00.000000000 +0200 +@@ -19,6 +19,7 @@ + #include <linux/serial.h> + + #include <asm/irq.h> ++ + #include <mach/hardware.h> + + #include <plat/regs-serial.h> +@@ -85,6 +86,7 @@ + + static int s3c2410_serial_probe(struct platform_device *dev) + { ++ dbg("s3c2410_serial_probe: dev=%p\n", dev); + return s3c24xx_serial_probe(dev, &s3c2410_uart_inf); + } + +diff -ruN --exclude='*.orig' --exclude='*.rej' linux-2.6.29-rc3.owrt/drivers/serial/s3c6400.c linux-2.6.29-rc3.owrt.om/drivers/serial/s3c6400.c +--- linux-2.6.29-rc3.owrt/drivers/serial/s3c6400.c 2009-05-10 22:04:48.000000000 +0200 ++++ linux-2.6.29-rc3.owrt.om/drivers/serial/s3c6400.c 2009-05-10 22:28:00.000000000 +0200 +@@ -102,6 +102,7 @@ + .name = "Samsung S3C6400 UART", + .type = PORT_S3C6400, + .fifosize = 64, ++ .has_divslot = 1, + .rx_fifomask = S3C2440_UFSTAT_RXMASK, + .rx_fifoshift = S3C2440_UFSTAT_RXSHIFT, + .rx_fifofull = S3C2440_UFSTAT_RXFULL, +diff -ruN --exclude='*.orig' --exclude='*.rej' linux-2.6.29-rc3.owrt/drivers/serial/samsung.c linux-2.6.29-rc3.owrt.om/drivers/serial/samsung.c +--- linux-2.6.29-rc3.owrt/drivers/serial/samsung.c 2009-05-10 22:04:48.000000000 +0200 ++++ linux-2.6.29-rc3.owrt.om/drivers/serial/samsung.c 2009-05-10 22:28:00.000000000 +0200 +@@ -50,6 +50,10 @@ + #include <mach/map.h> + + #include <plat/regs-serial.h> ++#if defined(CONFIG_MACH_NEO1973) && !defined(CONFIG_CPU_S3C6410) ++#include <mach/regs-gpio.h> ++#include <mach/regs-clock.h> ++#endif + + #include "samsung.h" + +@@ -235,8 +239,8 @@ + port->icount.rx++; + + if (unlikely(uerstat & S3C2410_UERSTAT_ANY)) { +- dbg("rxerr: port ch=0x%02x, rxs=0x%08x\n", +- ch, uerstat); ++ printk(KERN_DEBUG "rxerr: port=%d ch=0x%02x, rxs=0x%08x\n", ++ port->line, ch, uerstat); + + /* check for break */ + if (uerstat & S3C2410_UERSTAT_BREAK) { +@@ -265,8 +269,8 @@ + if (uart_handle_sysrq_char(port, ch)) + goto ignore_char; + +- uart_insert_char(port, uerstat, S3C2410_UERSTAT_OVERRUN, +- ch, flag); ++ if ((uerstat & port->ignore_status_mask & ~S3C2410_UERSTAT_OVERRUN) == 0) ++ tty_insert_flip_char(tty, ch, flag); + + ignore_char: + continue; +@@ -508,6 +512,7 @@ + struct baud_calc { + struct s3c24xx_uart_clksrc *clksrc; + unsigned int calc; ++ unsigned int divslot; + unsigned int quot; + struct clk *src; + }; +@@ -517,6 +522,7 @@ + struct s3c24xx_uart_clksrc *clksrc, + unsigned int baud) + { ++ struct s3c24xx_uart_port *ourport = to_ourport(port); + unsigned long rate; + + calc->src = clk_get(port->dev, clksrc->name); +@@ -527,8 +533,24 @@ + rate /= clksrc->divisor; + + calc->clksrc = clksrc; +- calc->quot = (rate + (8 * baud)) / (16 * baud); +- calc->calc = (rate / (calc->quot * 16)); ++ ++ if (ourport->info->has_divslot) { ++ unsigned long div = rate / baud; ++ ++ /* The UDIVSLOT register on the newer UARTs allows us to ++ * get a divisor adjustment of 1/16th on the baud clock. ++ * ++ * We don't keep the UDIVSLOT value (the 16ths we calculated ++ * by not multiplying the baud by 16) as it is easy enough ++ * to recalculate. ++ */ ++ ++ calc->quot = div / 16; ++ calc->calc = rate / div; ++ } else { ++ calc->quot = (rate + (8 * baud)) / (16 * baud); ++ calc->calc = (rate / (calc->quot * 16)); ++ } + + calc->quot--; + return 1; +@@ -611,6 +633,30 @@ + return best->quot; + } + ++/* udivslot_table[] ++ * ++ * This table takes the fractional value of the baud divisor and gives ++ * the recommended setting for the UDIVSLOT register. ++ */ ++static u16 udivslot_table[16] = { ++ [0] = 0x0000, ++ [1] = 0x0080, ++ [2] = 0x0808, ++ [3] = 0x0888, ++ [4] = 0x2222, ++ [5] = 0x4924, ++ [6] = 0x4A52, ++ [7] = 0x54AA, ++ [8] = 0x5555, ++ [9] = 0xD555, ++ [10] = 0xD5D5, ++ [11] = 0xDDD5, ++ [12] = 0xDDDD, ++ [13] = 0xDFDD, ++ [14] = 0xDFDF, ++ [15] = 0xFFDF, ++}; ++ + static void s3c24xx_serial_set_termios(struct uart_port *port, + struct ktermios *termios, + struct ktermios *old) +@@ -623,6 +669,7 @@ + unsigned int baud, quot; + unsigned int ulcon; + unsigned int umcon; ++ unsigned int udivslot = 0; + + /* + * We don't support modem control lines. +@@ -644,6 +691,7 @@ + /* check to see if we need to change clock source */ + + if (ourport->clksrc != clksrc || ourport->baudclk != clk) { ++ dbg("selecting clock %p\n", clk); + s3c24xx_serial_setsource(port, clksrc); + + if (ourport->baudclk != NULL && !IS_ERR(ourport->baudclk)) { +@@ -658,6 +706,13 @@ + ourport->baudclk_rate = clk ? clk_get_rate(clk) : 0; + } + ++ if (ourport->info->has_divslot) { ++ unsigned int div = ourport->baudclk_rate / baud; ++ ++ udivslot = udivslot_table[div & 15]; ++ dbg("udivslot = %04x (div %d)\n", udivslot, div & 15); ++ } ++ + switch (termios->c_cflag & CSIZE) { + case CS5: + dbg("config: 5bits/char\n"); +@@ -697,12 +752,16 @@ + + spin_lock_irqsave(&port->lock, flags); + +- dbg("setting ulcon to %08x, brddiv to %d\n", ulcon, quot); ++ dbg("setting ulcon to %08x, brddiv to %d, udivslot %08x\n", ++ ulcon, quot, udivslot); + + wr_regl(port, S3C2410_ULCON, ulcon); + wr_regl(port, S3C2410_UBRDIV, quot); + wr_regl(port, S3C2410_UMCON, umcon); + ++ if (ourport->info->has_divslot) ++ wr_regl(port, S3C2443_DIVSLOT, udivslot); ++ + dbg("uart: ulcon = 0x%08x, ucon = 0x%08x, ufcon = 0x%08x\n", + rd_regl(port, S3C2410_ULCON), + rd_regl(port, S3C2410_UCON), +@@ -887,6 +946,70 @@ + #endif + }; + ++#ifdef CONFIG_MACH_NEO1973_GTA02 ++static void s3c24xx_serial_force_debug_port_up(void) ++{ ++ struct s3c24xx_uart_port *ourport = &s3c24xx_serial_ports[ ++ CONFIG_DEBUG_S3C_UART]; ++ struct s3c24xx_uart_clksrc *clksrc = NULL; ++ struct clk *clk = NULL; ++ unsigned long tmp; ++ ++ s3c24xx_serial_getclk(&ourport->port, &clksrc, &clk, 115200); ++ ++ tmp = __raw_readl(S3C2410_CLKCON); ++ ++ /* re-start uart clocks */ ++ tmp |= S3C2410_CLKCON_UART0; ++ tmp |= S3C2410_CLKCON_UART1; ++ tmp |= S3C2410_CLKCON_UART2; ++ ++ __raw_writel(tmp, S3C2410_CLKCON); ++ udelay(10); ++ ++ s3c24xx_serial_setsource(&ourport->port, clksrc); ++ ++ if (ourport->baudclk != NULL && !IS_ERR(ourport->baudclk)) { ++ clk_disable(ourport->baudclk); ++ ourport->baudclk = NULL; ++ } ++ ++ clk_enable(clk); ++ ++ ourport->clksrc = clksrc; ++ ourport->baudclk = clk; ++} ++ ++static void s3c2410_printascii(const char *sz) ++{ ++ struct s3c24xx_uart_port *ourport = &s3c24xx_serial_ports[ ++ CONFIG_DEBUG_S3C_UART]; ++ struct uart_port *port = &ourport->port; ++ ++ /* 8 N 1 */ ++ wr_regl(port, S3C2410_ULCON, (rd_regl(port, S3C2410_ULCON)) | 3); ++ /* polling mode */ ++ wr_regl(port, S3C2410_UCON, (rd_regl(port, S3C2410_UCON) & ~0xc0f) | 5); ++ /* disable FIFO */ ++ wr_regl(port, S3C2410_UFCON, (rd_regl(port, S3C2410_UFCON) & ~0x01)); ++ /* fix baud rate */ ++ wr_regl(port, S3C2410_UBRDIV, 26); ++ ++ while (*sz) { ++ int timeout = 10000000; ++ ++ /* spin on it being busy */ ++ while ((!(rd_regl(port, S3C2410_UTRSTAT) & 2)) && timeout--) ++ ; ++ ++ /* transmit register */ ++ wr_regl(port, S3C2410_UTXH, *sz); ++ ++ sz++; ++ } ++} ++#endif ++ + /* s3c24xx_serial_resetport + * + * wrapper to call the specific reset for this port (reset the fifos +@@ -937,13 +1060,17 @@ + struct ktermios *termios; + struct tty_struct *tty; + +- if (uport->info == NULL) ++ if (uport->info == NULL) { ++ printk(KERN_WARNING "%s: info NULL\n", __func__); + goto exit; ++ } + + tty = uport->info->port.tty; + +- if (tty == NULL) ++ if (tty == NULL) { ++ printk(KERN_WARNING "%s: tty is NULL\n", __func__); + goto exit; ++ } + + termios = tty->termios; + +@@ -1092,6 +1219,7 @@ + + ourport = &s3c24xx_serial_ports[probe_index]; + probe_index++; ++ init_resume_dependency_list(&ourport->resume_dependency); + + dbg("%s: initialising port %p...\n", __func__, ourport); + +@@ -1148,6 +1276,16 @@ + return 0; + } + ++void s3c24xx_serial_register_resume_dependency(struct resume_dependency * ++ resume_dependency, int uart_index) ++{ ++ struct s3c24xx_uart_port *ourport = &s3c24xx_serial_ports[uart_index]; ++ ++ register_resume_dependency(&ourport->resume_dependency, ++ resume_dependency); ++} ++EXPORT_SYMBOL(s3c24xx_serial_register_resume_dependency); ++ + static int s3c24xx_serial_resume(struct platform_device *dev) + { + struct uart_port *port = s3c24xx_dev_to_port(&dev->dev); +@@ -1159,6 +1297,9 @@ + clk_disable(ourport->clk); + + uart_resume_port(&s3c24xx_uart_drv, port); ++ ++ callback_all_resume_dependencies(&ourport->resume_dependency); ++ + } + + return 0; +@@ -1169,6 +1310,12 @@ + struct s3c24xx_uart_info *info) + { + dbg("s3c24xx_serial_init(%p,%p)\n", drv, info); ++#ifdef CONFIG_MACH_NEO1973_GTA02 ++ /* set up the emergency debug UART functions */ ++ ++ printk_emergency_debug_spew_init = s3c24xx_serial_force_debug_port_up; ++ printk_emergency_debug_spew_send_string = s3c2410_printascii; ++#endif + + #ifdef CONFIG_PM + drv->suspend = s3c24xx_serial_suspend; +@@ -1208,6 +1355,13 @@ + #ifdef CONFIG_SERIAL_SAMSUNG_CONSOLE + + static struct uart_port *cons_uart; ++static int cons_silenced; ++ ++void s3c24xx_serial_console_set_silence(int silenced) ++{ ++ cons_silenced = silenced; ++} ++EXPORT_SYMBOL(s3c24xx_serial_console_set_silence); + + static int + s3c24xx_serial_console_txrdy(struct uart_port *port, unsigned int ufcon) +@@ -1232,9 +1386,21 @@ + s3c24xx_serial_console_putchar(struct uart_port *port, int ch) + { + unsigned int ufcon = rd_regl(cons_uart, S3C2410_UFCON); ++ unsigned int umcon = rd_regl(cons_uart, S3C2410_UMCON); ++ ++ if (cons_silenced) ++ return; ++ ++ /* If auto HW flow control enabled, temporarily turn it off */ ++ if (umcon & S3C2410_UMCOM_AFC) ++ wr_regl(port, S3C2410_UMCON, (umcon & !S3C2410_UMCOM_AFC)); ++ + while (!s3c24xx_serial_console_txrdy(port, ufcon)) + barrier(); + wr_regb(cons_uart, S3C2410_UTXH, ch); ++ ++ if (umcon & S3C2410_UMCOM_AFC) ++ wr_regl(port, S3C2410_UMCON, umcon); + } + + static void +diff -ruN --exclude='*.orig' --exclude='*.rej' linux-2.6.29-rc3.owrt/drivers/serial/samsung.h linux-2.6.29-rc3.owrt.om/drivers/serial/samsung.h +--- linux-2.6.29-rc3.owrt/drivers/serial/samsung.h 2009-05-10 22:04:48.000000000 +0200 ++++ linux-2.6.29-rc3.owrt.om/drivers/serial/samsung.h 2009-05-10 22:28:00.000000000 +0200 +@@ -10,6 +10,8 @@ + * published by the Free Software Foundation. + */ + ++#include <linux/resume-dependency.h> ++ + struct s3c24xx_uart_info { + char *name; + unsigned int type; +@@ -21,6 +23,10 @@ + unsigned long tx_fifoshift; + unsigned long tx_fifofull; + ++ /* uart port features */ ++ ++ unsigned int has_divslot:1; ++ + /* clock source control */ + + int (*get_clksrc)(struct uart_port *, struct s3c24xx_uart_clksrc *clk); +@@ -48,6 +54,8 @@ + #ifdef CONFIG_CPU_FREQ + struct notifier_block freq_transition; + #endif ++ ++ struct resume_dependency resume_dependency; + }; + + /* conversion functions */ +diff -ruN --exclude='*.orig' --exclude='*.rej' linux-2.6.29-rc3.owrt/drivers/spi/Kconfig linux-2.6.29-rc3.owrt.om/drivers/spi/Kconfig +--- linux-2.6.29-rc3.owrt/drivers/spi/Kconfig 2009-05-10 22:04:49.000000000 +0200 ++++ linux-2.6.29-rc3.owrt.om/drivers/spi/Kconfig 2009-05-10 22:28:00.000000000 +0200 +@@ -257,6 +257,15 @@ + sysfs interface, with each line presented as a kind of GPIO + exposing both switch control and diagnostic feedback. + ++config SPI_S3C64XX_GPIO ++ tristate "Samsung S3C64XX series SPI by GPIO" ++ depends on ARCH_S3C64XX && EXPERIMENTAL ++ select SPI_BITBANG ++ help ++ SPI driver for Samsung S3C64XX series ARM SoCs using ++ GPIO lines to provide the SPI bus. This can be used where ++ the inbuilt hardware cannot provide the transfer mode, or ++ where the board is using non hardware connected pins. + # + # Add new SPI protocol masters in alphabetical order above this line + # +diff -ruN --exclude='*.orig' --exclude='*.rej' linux-2.6.29-rc3.owrt/drivers/spi/Makefile linux-2.6.29-rc3.owrt.om/drivers/spi/Makefile +--- linux-2.6.29-rc3.owrt/drivers/spi/Makefile 2009-05-10 22:04:49.000000000 +0200 ++++ linux-2.6.29-rc3.owrt.om/drivers/spi/Makefile 2009-05-10 22:28:00.000000000 +0200 +@@ -31,6 +31,7 @@ + obj-$(CONFIG_SPI_TXX9) += spi_txx9.o + obj-$(CONFIG_SPI_XILINX) += xilinx_spi.o + obj-$(CONFIG_SPI_SH_SCI) += spi_sh_sci.o ++obj-$(CONFIG_SPI_S3C64XX_GPIO) += spi_s3c64xx_gpio.o + # ... add above this line ... + + # SPI protocol drivers (device/link on bus) +diff -ruN --exclude='*.orig' --exclude='*.rej' linux-2.6.29-rc3.owrt/drivers/spi/spi_bitbang.c linux-2.6.29-rc3.owrt.om/drivers/spi/spi_bitbang.c +--- linux-2.6.29-rc3.owrt/drivers/spi/spi_bitbang.c 2009-05-10 22:04:49.000000000 +0200 ++++ linux-2.6.29-rc3.owrt.om/drivers/spi/spi_bitbang.c 2009-05-10 22:28:00.000000000 +0200 +@@ -264,6 +264,123 @@ + * Drivers can provide word-at-a-time i/o primitives, or provide + * transfer-at-a-time ones to leverage dma or fifo hardware. + */ ++ ++/* Synchronous non blocking transfer */ ++int ++spi_bitbang_transfer_sync(struct spi_device *spi, struct spi_message *m) ++{ ++ struct spi_bitbang *bitbang = spi_master_get_devdata(spi->master); ++ struct spi_transfer *t; ++ unsigned long flags; ++ int cs_change = 1; ++ int status; ++ int nsecs; ++ int (*setup_transfer)(struct spi_device *, struct spi_transfer *); ++ ++ /* FIXME this is made-up ... the correct value is known to ++ * word-at-a-time bitbang code, and presumably chipselect() ++ * should enforce these requirements too? ++ */ ++ nsecs = 100; ++ cs_change = 1; ++ status = 0; ++ setup_transfer = NULL; ++ ++ local_irq_save(flags); ++ list_for_each_entry (t, &m->transfers, transfer_list) { ++ /* override or restore speed and wordsize */ ++ if (t->speed_hz || t->bits_per_word) { ++ setup_transfer = bitbang->setup_transfer; ++ if (!setup_transfer) { ++ status = -ENOPROTOOPT; ++ break; ++ } ++ } ++ if (setup_transfer) { ++ status = setup_transfer(spi, t); ++ if (status < 0) ++ break; ++ } ++ ++ /* set up default clock polarity, and activate chip; ++ * this implicitly updates clock and spi modes as ++ * previously recorded for this device via setup(). ++ * (and also deselects any other chip that might be ++ * selected ...) ++ */ ++ ++ if (cs_change) { ++ bitbang->chipselect(spi, BITBANG_CS_ACTIVE); ++ ndelay(nsecs); ++ } ++ ++ cs_change = t->cs_change; ++ if (!t->tx_buf && !t->rx_buf && t->len) { ++ status = -EINVAL; ++ break; ++ } ++ ++ /* transfer data. the lower level code handles any ++ * new dma mappings it needs. our caller always gave ++ * us dma-safe buffers. ++ */ ++ if (t->len) { ++ /* REVISIT dma API still needs a designated ++ * DMA_ADDR_INVALID; ~0 might be better. ++ */ ++ if (!m->is_dma_mapped) ++ t->rx_dma = t->tx_dma = 0; ++ status = bitbang->txrx_bufs(spi, t); ++ } ++ ++ if (status > 0) ++ m->actual_length += status; ++ if (status != t->len) { ++ /* always report some kind of error */ ++ if (status >= 0) ++ status = -EREMOTEIO; ++ break; ++ } ++ status = 0; ++ /* protocol tweaks before next transfer */ ++ if (t->delay_usecs) ++ udelay(t->delay_usecs); ++ if (!cs_change) ++ continue; ++ if (t->transfer_list.next == &m->transfers) ++ break; ++ /* sometimes a short mid-message deselect of the chip ++ * may be needed to terminate a mode or command ++ */ ++ ndelay(nsecs); ++ bitbang->chipselect(spi, BITBANG_CS_INACTIVE); ++ ndelay(nsecs); ++ } ++ ++ m->status = status; ++ if (m->complete) ++ m->complete(m->context); ++ ++ /* restore speed and wordsize */ ++ if (setup_transfer) ++ setup_transfer(spi, NULL); ++ ++ /* normally deactivate chipselect ... unless no error and ++ * cs_change has hinted that the next message will probably ++ * be for this chip too. ++ */ ++ if (!(status == 0 && cs_change)) { ++ ndelay(nsecs); ++ bitbang->chipselect(spi, BITBANG_CS_INACTIVE); ++ ndelay(nsecs); ++ } ++ ++ local_irq_restore(flags); ++ ++ return status; ++} ++EXPORT_SYMBOL_GPL(spi_bitbang_transfer_sync); ++ + static void bitbang_work(struct work_struct *work) + { + struct spi_bitbang *bitbang = +@@ -274,120 +391,13 @@ + bitbang->busy = 1; + while (!list_empty(&bitbang->queue)) { + struct spi_message *m; +- struct spi_device *spi; +- unsigned nsecs; +- struct spi_transfer *t = NULL; +- unsigned tmp; +- unsigned cs_change; +- int status; +- int (*setup_transfer)(struct spi_device *, +- struct spi_transfer *); + + m = container_of(bitbang->queue.next, struct spi_message, + queue); + list_del_init(&m->queue); +- spin_unlock_irqrestore(&bitbang->lock, flags); +- +- /* FIXME this is made-up ... the correct value is known to +- * word-at-a-time bitbang code, and presumably chipselect() +- * should enforce these requirements too? +- */ +- nsecs = 100; +- +- spi = m->spi; +- tmp = 0; +- cs_change = 1; +- status = 0; +- setup_transfer = NULL; +- +- list_for_each_entry (t, &m->transfers, transfer_list) { +- +- /* override or restore speed and wordsize */ +- if (t->speed_hz || t->bits_per_word) { +- setup_transfer = bitbang->setup_transfer; +- if (!setup_transfer) { +- status = -ENOPROTOOPT; +- break; +- } +- } +- if (setup_transfer) { +- status = setup_transfer(spi, t); +- if (status < 0) +- break; +- } +- +- /* set up default clock polarity, and activate chip; +- * this implicitly updates clock and spi modes as +- * previously recorded for this device via setup(). +- * (and also deselects any other chip that might be +- * selected ...) +- */ +- if (cs_change) { +- bitbang->chipselect(spi, BITBANG_CS_ACTIVE); +- ndelay(nsecs); +- } +- cs_change = t->cs_change; +- if (!t->tx_buf && !t->rx_buf && t->len) { +- status = -EINVAL; +- break; +- } +- +- /* transfer data. the lower level code handles any +- * new dma mappings it needs. our caller always gave +- * us dma-safe buffers. +- */ +- if (t->len) { +- /* REVISIT dma API still needs a designated +- * DMA_ADDR_INVALID; ~0 might be better. +- */ +- if (!m->is_dma_mapped) +- t->rx_dma = t->tx_dma = 0; +- status = bitbang->txrx_bufs(spi, t); +- } +- if (status > 0) +- m->actual_length += status; +- if (status != t->len) { +- /* always report some kind of error */ +- if (status >= 0) +- status = -EREMOTEIO; +- break; +- } +- status = 0; +- +- /* protocol tweaks before next transfer */ +- if (t->delay_usecs) +- udelay(t->delay_usecs); +- +- if (!cs_change) +- continue; +- if (t->transfer_list.next == &m->transfers) +- break; +- +- /* sometimes a short mid-message deselect of the chip +- * may be needed to terminate a mode or command +- */ +- ndelay(nsecs); +- bitbang->chipselect(spi, BITBANG_CS_INACTIVE); +- ndelay(nsecs); +- } +- +- m->status = status; +- m->complete(m->context); +- +- /* restore speed and wordsize */ +- if (setup_transfer) +- setup_transfer(spi, NULL); +- +- /* normally deactivate chipselect ... unless no error and +- * cs_change has hinted that the next message will probably +- * be for this chip too. +- */ +- if (!(status == 0 && cs_change)) { +- ndelay(nsecs); +- bitbang->chipselect(spi, BITBANG_CS_INACTIVE); +- ndelay(nsecs); +- } + ++ spin_unlock_irqrestore(&bitbang->lock, flags); ++ spi_bitbang_transfer_sync(m->spi, m); + spin_lock_irqsave(&bitbang->lock, flags); + } + bitbang->busy = 0; +@@ -459,6 +469,9 @@ + + if (!bitbang->master->transfer) + bitbang->master->transfer = spi_bitbang_transfer; ++ if (!bitbang->master->transfer_sync && bitbang->non_blocking_transfer) ++ bitbang->master->transfer_sync = spi_bitbang_transfer_sync; ++ + if (!bitbang->txrx_bufs) { + bitbang->use_dma = 0; + bitbang->txrx_bufs = spi_bitbang_bufs; +diff -ruN --exclude='*.orig' --exclude='*.rej' linux-2.6.29-rc3.owrt/drivers/spi/spi_s3c24xx_gpio.c linux-2.6.29-rc3.owrt.om/drivers/spi/spi_s3c24xx_gpio.c +--- linux-2.6.29-rc3.owrt/drivers/spi/spi_s3c24xx_gpio.c 2009-05-10 22:04:49.000000000 +0200 ++++ linux-2.6.29-rc3.owrt.om/drivers/spi/spi_s3c24xx_gpio.c 2009-05-10 22:28:00.000000000 +0200 +@@ -91,7 +91,7 @@ + struct s3c2410_spigpio *sg = spidev_to_sg(dev); + + if (sg->info && sg->info->chip_select) +- (sg->info->chip_select)(sg->info, value); ++ (sg->info->chip_select)(sg->info, dev->chip_select, value); + } + + static int s3c2410_spigpio_probe(struct platform_device *dev) +@@ -112,14 +112,17 @@ + + platform_set_drvdata(dev, sp); + +- /* copy in the plkatform data */ ++ /* copy in the platform data */ + info = sp->info = dev->dev.platform_data; + ++ master->num_chipselect = info->num_chipselect; ++ + /* setup spi bitbang adaptor */ + sp->bitbang.master = spi_master_get(master); + sp->bitbang.master->bus_num = info->bus_num; + sp->bitbang.master->num_chipselect = info->num_chipselect; + sp->bitbang.chipselect = s3c2410_spigpio_chipselect; ++ sp->bitbang.non_blocking_transfer = info->non_blocking_transfer; + + sp->bitbang.txrx_word[SPI_MODE_0] = s3c2410_spigpio_txrx_mode0; + sp->bitbang.txrx_word[SPI_MODE_1] = s3c2410_spigpio_txrx_mode1; +diff -ruN --exclude='*.orig' --exclude='*.rej' linux-2.6.29-rc3.owrt/drivers/spi/spi_s3c64xx_gpio.c linux-2.6.29-rc3.owrt.om/drivers/spi/spi_s3c64xx_gpio.c +--- linux-2.6.29-rc3.owrt/drivers/spi/spi_s3c64xx_gpio.c 1970-01-01 01:00:00.000000000 +0100 ++++ linux-2.6.29-rc3.owrt.om/drivers/spi/spi_s3c64xx_gpio.c 2009-05-10 22:28:00.000000000 +0200 +@@ -0,0 +1,187 @@ ++/* linux/drivers/spi/spi_s3c64xx_gpio.c ++ * ++ * Copyright (c) 2009 Openmoko Inc. ++ * Author: Matt Hsu <matt_hsu@openmoko.org> ++ * ++ * S3C64XX GPIO-SPI driver. ++ * This driver is based on spi_s3c24xx_gpio.c ++ * ++ * Copyright (c) 2006 Ben Dooks ++ * Copyright (c) 2006 Simtec Electronics ++ * ++ * 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/delay.h> ++#include <linux/spinlock.h> ++#include <linux/workqueue.h> ++#include <linux/platform_device.h> ++#include <linux/gpio.h> ++ ++#include <linux/spi/spi.h> ++#include <linux/spi/spi_bitbang.h> ++ ++#include <plat/gpio-cfg.h> ++#include <mach/spi-gpio.h> ++ ++struct s3c64xx_spigpio { ++ struct spi_bitbang bitbang; ++ struct s3c64xx_spigpio_info *info; ++ struct platform_device *dev; ++}; ++ ++static inline struct s3c64xx_spigpio *spidev_to_sg(struct spi_device *spi) ++{ ++ return dev_get_drvdata(&spi->master->dev); ++} ++ ++static inline void setsck(struct spi_device *dev, int on) ++{ ++ struct s3c64xx_spigpio *sg = spidev_to_sg(dev); ++ gpio_direction_output(sg->info->pin_clk, on ? 1 : 0); ++} ++ ++static inline void setmosi(struct spi_device *dev, int on) ++{ ++ struct s3c64xx_spigpio *sg = spidev_to_sg(dev); ++ gpio_direction_output(sg->info->pin_mosi, on ? 1 : 0); ++} ++ ++static inline u32 getmiso(struct spi_device *dev) ++{ ++ struct s3c64xx_spigpio *sg = spidev_to_sg(dev); ++ return gpio_direction_input(sg->info->pin_miso) ? 1 : 0; ++} ++ ++#define spidelay(x) ndelay(x) ++ ++#define EXPAND_BITBANG_TXRX ++#include <linux/spi/spi_bitbang.h> ++ ++static u32 s3c64xx_spigpio_txrx_mode0(struct spi_device *spi, ++ unsigned nsecs, u32 word, u8 bits) ++{ ++ return bitbang_txrx_be_cpha0(spi, nsecs, 0, word, bits); ++} ++ ++static u32 s3c64xx_spigpio_txrx_mode1(struct spi_device *spi, ++ unsigned nsecs, u32 word, u8 bits) ++{ ++ return bitbang_txrx_be_cpha1(spi, nsecs, 0, word, bits); ++} ++ ++static u32 s3c64xx_spigpio_txrx_mode2(struct spi_device *spi, ++ unsigned nsecs, u32 word, u8 bits) ++{ ++ return bitbang_txrx_be_cpha0(spi, nsecs, 1, word, bits); ++} ++ ++static u32 s3c64xx_spigpio_txrx_mode3(struct spi_device *spi, ++ unsigned nsecs, u32 word, u8 bits) ++{ ++ return bitbang_txrx_be_cpha1(spi, nsecs, 1, word, bits); ++} ++static void s3c64xx_spigpio_chipselect(struct spi_device *dev, int value) ++{ ++ struct s3c64xx_spigpio *sg = spidev_to_sg(dev); ++ ++ if (sg && sg->info && sg->info->chip_select) ++ (sg->info->chip_select)(sg->info, dev->chip_select, value); ++} ++ ++static int s3c64xx_spigpio_probe(struct platform_device *dev) ++{ ++ struct s3c64xx_spigpio_info *info; ++ struct spi_master *master; ++ struct s3c64xx_spigpio *spi; ++ ++ int ret; ++ ++ master = spi_alloc_master(&dev->dev, sizeof(struct s3c64xx_spigpio)); ++ if (master == NULL) { ++ dev_err(&dev->dev, "failed to allocate spi master\n"); ++ ret = -ENOMEM; ++ goto err; ++ } ++ ++ spi = spi_master_get_devdata(master); ++ ++ /* copy in the platform data */ ++ info = spi->info = dev->dev.platform_data; ++ ++ master->num_chipselect = info->num_chipselect; ++ ++ /* setup spi bitbang adaptor */ ++ spi->bitbang.master = spi_master_get(master); ++ spi->bitbang.master->bus_num = info->bus_num; ++ ++ spi->bitbang.chipselect = s3c64xx_spigpio_chipselect; ++ ++ spi->bitbang.txrx_word[SPI_MODE_0] = s3c64xx_spigpio_txrx_mode0; ++ spi->bitbang.txrx_word[SPI_MODE_1] = s3c64xx_spigpio_txrx_mode1; ++ spi->bitbang.txrx_word[SPI_MODE_2] = s3c64xx_spigpio_txrx_mode2; ++ spi->bitbang.txrx_word[SPI_MODE_3] = s3c64xx_spigpio_txrx_mode3; ++ ++ /* set state of spi pins. */ ++ gpio_direction_output(info->pin_clk, 0); ++ s3c_gpio_cfgpin(info->pin_clk, S3C_GPIO_OUTPUT); ++ ++ dev_set_drvdata(&master->dev, spi); ++ ++ ret = spi_bitbang_start(&spi->bitbang); ++ if (ret) ++ goto err_no_bitbang; ++ ++ return 0; ++ ++ err_no_bitbang: ++ spi_master_put(spi->bitbang.master); ++ err: ++ return ret; ++} ++ ++static int s3c64xx_spigpio_remove(struct platform_device *dev) ++{ ++ struct s3c64xx_spigpio *sp = platform_get_drvdata(dev); ++ ++ spi_bitbang_stop(&sp->bitbang); ++ spi_master_put(sp->bitbang.master); ++ ++ return 0; ++} ++ ++#define s3c64xx_spigpio_suspend NULL ++#define s3c64xx_spigpio_resume NULL ++ ++static struct platform_driver s3c64xx_spigpio_drv = { ++ .probe = s3c64xx_spigpio_probe, ++ .remove = s3c64xx_spigpio_remove, ++ .suspend = s3c64xx_spigpio_suspend, ++ .resume = s3c64xx_spigpio_resume, ++ .driver = { ++ .name = "spi_s3c64xx_gpio", ++ .owner = THIS_MODULE, ++ }, ++}; ++ ++static int __init s3c64xx_spigpio_init(void) ++{ ++ return platform_driver_register(&s3c64xx_spigpio_drv); ++} ++ ++static void __exit s3c64xx_spigpio_exit(void) ++{ ++ platform_driver_unregister(&s3c64xx_spigpio_drv); ++} ++ ++module_init(s3c64xx_spigpio_init); ++module_exit(s3c64xx_spigpio_exit); ++ ++MODULE_DESCRIPTION("S3C64XX GPIO-SPI Driver"); ++MODULE_AUTHOR("Matt Hsu, <matt_hsu@openmoko.org>"); ++MODULE_LICENSE("GPLv2"); +diff -ruN --exclude='*.orig' --exclude='*.rej' linux-2.6.29-rc3.owrt/drivers/staging/android/alarm.c linux-2.6.29-rc3.owrt.om/drivers/staging/android/alarm.c +--- linux-2.6.29-rc3.owrt/drivers/staging/android/alarm.c 1970-01-01 01:00:00.000000000 +0100 ++++ linux-2.6.29-rc3.owrt.om/drivers/staging/android/alarm.c 2009-05-10 22:28:00.000000000 +0200 +@@ -0,0 +1,567 @@ ++/* drivers/rtc/alarm.c ++ * ++ * Copyright (C) 2007 Google, Inc. ++ * ++ * This software is licensed under the terms of the GNU General Public ++ * License version 2, as published by the Free Software Foundation, and ++ * may be copied, distributed, and modified under those terms. ++ * ++ * 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. ++ * ++ */ ++ ++#include <asm/mach/time.h> ++#include <linux/android_alarm.h> ++#include <linux/device.h> ++#include <linux/miscdevice.h> ++#include <linux/platform_device.h> ++#include <linux/rtc.h> ++#include <linux/spinlock.h> ++#include <linux/sysdev.h> ++#include <linux/wakelock.h> ++ ++#define ANDROID_ALARM_PRINT_ERRORS (1U << 0) ++#define ANDROID_ALARM_PRINT_INIT_STATUS (1U << 1) ++#define ANDROID_ALARM_PRINT_INFO (1U << 2) ++#define ANDROID_ALARM_PRINT_IO (1U << 3) ++#define ANDROID_ALARM_PRINT_INT (1U << 4) ++#define ANDROID_ALARM_PRINT_FLOW (1U << 5) ++ ++#if 0 ++#define ANDROID_ALARM_DPRINTF_MASK (~0) ++#define ANDROID_ALARM_DPRINTF(debug_level_mask, args...) \ ++ do { \ ++ if (ANDROID_ALARM_DPRINTF_MASK & debug_level_mask) { \ ++ printk(args); \ ++ } \ ++ } while (0) ++#else ++#define ANDROID_ALARM_DPRINTF(args...) ++#endif ++ ++#define ANDROID_ALARM_WAKEUP_MASK ( \ ++ ANDROID_ALARM_RTC_WAKEUP_MASK | \ ++ ANDROID_ALARM_ELAPSED_REALTIME_WAKEUP_MASK) ++ ++/* support old usespace code */ ++#define ANDROID_ALARM_SET_OLD _IOW('a', 2, time_t) /* set alarm */ ++#define ANDROID_ALARM_SET_AND_WAIT_OLD _IOW('a', 3, time_t) ++ ++static struct rtc_device *alarm_rtc_dev; ++static int alarm_opened; ++static DEFINE_SPINLOCK(alarm_slock); ++static DEFINE_MUTEX(alarm_setrtc_mutex); ++static struct wake_lock alarm_wake_lock; ++static struct wake_lock alarm_rtc_wake_lock; ++static DECLARE_WAIT_QUEUE_HEAD(alarm_wait_queue); ++static uint32_t alarm_pending; ++static uint32_t alarm_enabled; ++static uint32_t wait_pending; ++static struct platform_device *alarm_platform_dev; ++static struct hrtimer alarm_timer[ANDROID_ALARM_TYPE_COUNT]; ++static struct timespec alarm_time[ANDROID_ALARM_TYPE_COUNT]; ++static struct timespec elapsed_rtc_delta; ++ ++static void alarm_start_hrtimer(enum android_alarm_type alarm_type) ++{ ++ struct timespec hr_alarm_time; ++ if (!(alarm_enabled & (1U << alarm_type))) ++ return; ++ hr_alarm_time = alarm_time[alarm_type]; ++ if (alarm_type == ANDROID_ALARM_ELAPSED_REALTIME_WAKEUP || ++ alarm_type == ANDROID_ALARM_ELAPSED_REALTIME) ++ set_normalized_timespec(&hr_alarm_time, ++ hr_alarm_time.tv_sec + elapsed_rtc_delta.tv_sec, ++ hr_alarm_time.tv_nsec + elapsed_rtc_delta.tv_nsec); ++ ANDROID_ALARM_DPRINTF(ANDROID_ALARM_PRINT_FLOW, ++ "alarm start hrtimer %d at %ld.%09ld\n", ++ alarm_type, hr_alarm_time.tv_sec, hr_alarm_time.tv_nsec); ++ hrtimer_start(&alarm_timer[alarm_type], ++ timespec_to_ktime(hr_alarm_time), HRTIMER_MODE_ABS); ++} ++ ++static long alarm_ioctl(struct file *file, unsigned int cmd, unsigned long arg) ++{ ++ int rv = 0; ++ unsigned long flags; ++ int i; ++ struct timespec new_alarm_time; ++ struct timespec new_rtc_time; ++ struct timespec tmp_time; ++ struct rtc_time rtc_new_rtc_time; ++ enum android_alarm_type alarm_type = ANDROID_ALARM_IOCTL_TO_TYPE(cmd); ++ uint32_t alarm_type_mask = 1U << alarm_type; ++ ++ if (alarm_type >= ANDROID_ALARM_TYPE_COUNT) ++ return -EINVAL; ++ ++ if (ANDROID_ALARM_BASE_CMD(cmd) != ANDROID_ALARM_GET_TIME(0)) { ++ if ((file->f_flags & O_ACCMODE) == O_RDONLY) ++ return -EPERM; ++ if (file->private_data == NULL && ++ cmd != ANDROID_ALARM_SET_RTC) { ++ spin_lock_irqsave(&alarm_slock, flags); ++ if (alarm_opened) { ++ spin_unlock_irqrestore(&alarm_slock, flags); ++ return -EBUSY; ++ } ++ alarm_opened = 1; ++ file->private_data = (void *)1; ++ spin_unlock_irqrestore(&alarm_slock, flags); ++ } ++ } ++ ++ switch (ANDROID_ALARM_BASE_CMD(cmd)) { ++ case ANDROID_ALARM_CLEAR(0): ++ spin_lock_irqsave(&alarm_slock, flags); ++ ANDROID_ALARM_DPRINTF(ANDROID_ALARM_PRINT_IO, ++ "alarm %d clear\n", alarm_type); ++ hrtimer_try_to_cancel(&alarm_timer[alarm_type]); ++ if (alarm_pending) { ++ alarm_pending &= ~alarm_type_mask; ++ if (!alarm_pending && !wait_pending) ++ wake_unlock(&alarm_wake_lock); ++ } ++ alarm_enabled &= ~alarm_type_mask; ++ spin_unlock_irqrestore(&alarm_slock, flags); ++ break; ++ ++ case ANDROID_ALARM_SET_OLD: ++ case ANDROID_ALARM_SET_AND_WAIT_OLD: ++ if (get_user(new_alarm_time.tv_sec, (int __user *)arg)) { ++ rv = -EFAULT; ++ goto err1; ++ } ++ new_alarm_time.tv_nsec = 0; ++ goto from_old_alarm_set; ++ ++ case ANDROID_ALARM_SET_AND_WAIT(0): ++ case ANDROID_ALARM_SET(0): ++ if (copy_from_user(&new_alarm_time, (void __user *)arg, ++ sizeof(new_alarm_time))) { ++ rv = -EFAULT; ++ goto err1; ++ } ++from_old_alarm_set: ++ spin_lock_irqsave(&alarm_slock, flags); ++ ANDROID_ALARM_DPRINTF(ANDROID_ALARM_PRINT_IO, ++ "alarm %d set %ld.%09ld\n", alarm_type, ++ new_alarm_time.tv_sec, new_alarm_time.tv_nsec); ++ alarm_time[alarm_type] = new_alarm_time; ++ alarm_enabled |= alarm_type_mask; ++ alarm_start_hrtimer(alarm_type); ++ spin_unlock_irqrestore(&alarm_slock, flags); ++ if (ANDROID_ALARM_BASE_CMD(cmd) != ANDROID_ALARM_SET_AND_WAIT(0) ++ && cmd != ANDROID_ALARM_SET_AND_WAIT_OLD) ++ break; ++ /* fall though */ ++ case ANDROID_ALARM_WAIT: ++ spin_lock_irqsave(&alarm_slock, flags); ++ ANDROID_ALARM_DPRINTF(ANDROID_ALARM_PRINT_IO, "alarm wait\n"); ++ if (!alarm_pending && wait_pending) { ++ wake_unlock(&alarm_wake_lock); ++ wait_pending = 0; ++ } ++ spin_unlock_irqrestore(&alarm_slock, flags); ++ rv = wait_event_interruptible(alarm_wait_queue, alarm_pending); ++ if (rv) ++ goto err1; ++ spin_lock_irqsave(&alarm_slock, flags); ++ rv = alarm_pending; ++ wait_pending = 1; ++ alarm_pending = 0; ++ if (rv & ANDROID_ALARM_WAKEUP_MASK) ++ wake_unlock(&alarm_rtc_wake_lock); ++ spin_unlock_irqrestore(&alarm_slock, flags); ++ break; ++ case ANDROID_ALARM_SET_RTC: ++ if (copy_from_user(&new_rtc_time, (void __user *)arg, ++ sizeof(new_rtc_time))) { ++ rv = -EFAULT; ++ goto err1; ++ } ++ rtc_time_to_tm(new_rtc_time.tv_sec, &rtc_new_rtc_time); ++ ++ ANDROID_ALARM_DPRINTF(ANDROID_ALARM_PRINT_IO, ++ "set rtc %ld %ld - rtc %02d:%02d:%02d %02d/%02d/%04d\n", ++ new_rtc_time.tv_sec, new_rtc_time.tv_nsec, ++ rtc_new_rtc_time.tm_hour, rtc_new_rtc_time.tm_min, ++ rtc_new_rtc_time.tm_sec, rtc_new_rtc_time.tm_mon + 1, ++ rtc_new_rtc_time.tm_mday, ++ rtc_new_rtc_time.tm_year + 1900); ++ ++ mutex_lock(&alarm_setrtc_mutex); ++ spin_lock_irqsave(&alarm_slock, flags); ++ for (i = 0; i < ANDROID_ALARM_SYSTEMTIME; i++) ++ hrtimer_try_to_cancel(&alarm_timer[i]); ++ getnstimeofday(&tmp_time); ++ elapsed_rtc_delta = timespec_sub(elapsed_rtc_delta, ++ timespec_sub(tmp_time, new_rtc_time)); ++ spin_unlock_irqrestore(&alarm_slock, flags); ++ rv = do_settimeofday(&new_rtc_time); ++ spin_lock_irqsave(&alarm_slock, flags); ++ for (i = 0; i < ANDROID_ALARM_SYSTEMTIME; i++) ++ alarm_start_hrtimer(i); ++ spin_unlock_irqrestore(&alarm_slock, flags); ++ if (rv < 0) { ++ ANDROID_ALARM_DPRINTF(ANDROID_ALARM_PRINT_ERRORS, ++ "Failed to set time\n"); ++ mutex_unlock(&alarm_setrtc_mutex); ++ goto err1; ++ } ++ rv = rtc_set_time(alarm_rtc_dev, &rtc_new_rtc_time); ++ spin_lock_irqsave(&alarm_slock, flags); ++ alarm_pending |= ANDROID_ALARM_TIME_CHANGE_MASK; ++ wake_up(&alarm_wait_queue); ++ spin_unlock_irqrestore(&alarm_slock, flags); ++ mutex_unlock(&alarm_setrtc_mutex); ++ if (rv < 0) { ++ ANDROID_ALARM_DPRINTF(ANDROID_ALARM_PRINT_ERRORS, ++ "Failed to set RTC, time will be lost on reboot\n"); ++ goto err1; ++ } ++ break; ++ case ANDROID_ALARM_GET_TIME(0): ++ mutex_lock(&alarm_setrtc_mutex); ++ spin_lock_irqsave(&alarm_slock, flags); ++ if (alarm_type != ANDROID_ALARM_SYSTEMTIME) { ++ getnstimeofday(&tmp_time); ++ if (alarm_type >= ANDROID_ALARM_ELAPSED_REALTIME_WAKEUP) ++ tmp_time = timespec_sub(tmp_time, ++ elapsed_rtc_delta); ++ } else ++ ktime_get_ts(&tmp_time); ++ spin_unlock_irqrestore(&alarm_slock, flags); ++ mutex_unlock(&alarm_setrtc_mutex); ++ if (copy_to_user((void __user *)arg, &tmp_time, ++ sizeof(tmp_time))) { ++ rv = -EFAULT; ++ goto err1; ++ } ++ break; ++ ++ default: ++ rv = -EINVAL; ++ goto err1; ++ } ++err1: ++ return rv; ++} ++ ++static int alarm_open(struct inode *inode, struct file *file) ++{ ++ file->private_data = NULL; ++ return 0; ++} ++ ++static int alarm_release(struct inode *inode, struct file *file) ++{ ++ int i; ++ unsigned long flags; ++ ++ spin_lock_irqsave(&alarm_slock, flags); ++ if (file->private_data != 0) { ++ for (i = 0; i < ANDROID_ALARM_TYPE_COUNT; i++) { ++ uint32_t alarm_type_mask = 1U << i; ++ if (alarm_enabled & alarm_type_mask) { ++ ANDROID_ALARM_DPRINTF(ANDROID_ALARM_PRINT_INFO, ++ "alarm_release: clear alarm, " ++ "pending %d\n", ++ !!(alarm_pending & alarm_type_mask)); ++ alarm_enabled &= ~alarm_type_mask; ++ } ++ spin_unlock_irqrestore(&alarm_slock, flags); ++ hrtimer_cancel(&alarm_timer[i]); ++ spin_lock_irqsave(&alarm_slock, flags); ++ } ++ if (alarm_pending | wait_pending) { ++ if (alarm_pending) ++ ANDROID_ALARM_DPRINTF(ANDROID_ALARM_PRINT_INFO, ++ "alarm_release: clear pending alarms " ++ "%x\n", alarm_pending); ++ wake_unlock(&alarm_wake_lock); ++ wait_pending = 0; ++ alarm_pending = 0; ++ } ++ alarm_opened = 0; ++ } ++ spin_unlock_irqrestore(&alarm_slock, flags); ++ return 0; ++} ++ ++static enum hrtimer_restart alarm_timer_triggered(struct hrtimer *timer) ++{ ++ unsigned long flags; ++ enum android_alarm_type alarm_type = (timer - alarm_timer); ++ uint32_t alarm_type_mask = 1U << alarm_type; ++ ++ ++ ANDROID_ALARM_DPRINTF(ANDROID_ALARM_PRINT_INT, ++ "alarm_timer_triggered type %d\n", alarm_type); ++ spin_lock_irqsave(&alarm_slock, flags); ++ if (alarm_enabled & alarm_type_mask) { ++ wake_lock_timeout(&alarm_wake_lock, 5 * HZ); ++ alarm_enabled &= ~alarm_type_mask; ++ alarm_pending |= alarm_type_mask; ++ wake_up(&alarm_wait_queue); ++ } ++ spin_unlock_irqrestore(&alarm_slock, flags); ++ return HRTIMER_NORESTART; ++} ++ ++static void alarm_triggered_func(void *p) ++{ ++ struct rtc_device *rtc = alarm_rtc_dev; ++ if (!(rtc->irq_data & RTC_AF)) ++ return; ++ ANDROID_ALARM_DPRINTF(ANDROID_ALARM_PRINT_INT, "rtc alarm triggered\n"); ++ wake_lock_timeout(&alarm_rtc_wake_lock, 1 * HZ); ++} ++ ++int alarm_suspend(struct platform_device *pdev, pm_message_t state) ++{ ++ int err = 0; ++ unsigned long flags; ++ struct rtc_wkalrm rtc_alarm; ++ struct rtc_time rtc_current_rtc_time; ++ unsigned long rtc_current_time; ++ unsigned long rtc_alarm_time; ++ struct timespec rtc_current_timespec; ++ struct timespec rtc_delta; ++ struct timespec elapsed_realtime_alarm_time; ++ ++ ANDROID_ALARM_DPRINTF(ANDROID_ALARM_PRINT_FLOW, ++ "alarm_suspend(%p, %d)\n", pdev, state.event); ++ spin_lock_irqsave(&alarm_slock, flags); ++ if (alarm_pending && !wake_lock_active(&alarm_wake_lock)) { ++ ANDROID_ALARM_DPRINTF(ANDROID_ALARM_PRINT_INFO, ++ "alarm pending\n"); ++ err = -EBUSY; ++ goto err1; ++ } ++ if (alarm_enabled & ANDROID_ALARM_WAKEUP_MASK) { ++ spin_unlock_irqrestore(&alarm_slock, flags); ++ if (alarm_enabled & ANDROID_ALARM_RTC_WAKEUP_MASK) ++ hrtimer_cancel(&alarm_timer[ANDROID_ALARM_RTC_WAKEUP]); ++ if (alarm_enabled & ANDROID_ALARM_ELAPSED_REALTIME_WAKEUP_MASK) ++ hrtimer_cancel(&alarm_timer[ ++ ANDROID_ALARM_ELAPSED_REALTIME_WAKEUP]); ++ ++ rtc_read_time(alarm_rtc_dev, &rtc_current_rtc_time); ++ rtc_current_timespec.tv_nsec = 0; ++ rtc_tm_to_time(&rtc_current_rtc_time, ++ &rtc_current_timespec.tv_sec); ++ save_time_delta(&rtc_delta, &rtc_current_timespec); ++ set_normalized_timespec(&elapsed_realtime_alarm_time, ++ alarm_time[ANDROID_ALARM_ELAPSED_REALTIME_WAKEUP] ++ .tv_sec + elapsed_rtc_delta.tv_sec, ++ alarm_time[ANDROID_ALARM_ELAPSED_REALTIME_WAKEUP] ++ .tv_nsec + elapsed_rtc_delta.tv_nsec); ++ if ((alarm_enabled & ANDROID_ALARM_RTC_WAKEUP_MASK) && ++ (!(alarm_enabled & ++ ANDROID_ALARM_ELAPSED_REALTIME_WAKEUP_MASK) || ++ timespec_compare(&alarm_time[ANDROID_ALARM_RTC_WAKEUP], ++ &elapsed_realtime_alarm_time) < 0)) ++ rtc_alarm_time = timespec_sub( ++ alarm_time[ANDROID_ALARM_RTC_WAKEUP], ++ rtc_delta).tv_sec; ++ else ++ rtc_alarm_time = timespec_sub( ++ elapsed_realtime_alarm_time, rtc_delta).tv_sec; ++ rtc_time_to_tm(rtc_alarm_time, &rtc_alarm.time); ++ rtc_alarm.enabled = 1; ++ rtc_set_alarm(alarm_rtc_dev, &rtc_alarm); ++ rtc_read_time(alarm_rtc_dev, &rtc_current_rtc_time); ++ rtc_tm_to_time(&rtc_current_rtc_time, &rtc_current_time); ++ ANDROID_ALARM_DPRINTF(ANDROID_ALARM_PRINT_INFO, ++ "rtc alarm set at %ld, now %ld, rtc delta %ld.%09ld\n", ++ rtc_alarm_time, rtc_current_time, ++ rtc_delta.tv_sec, rtc_delta.tv_nsec); ++ if (rtc_current_time + 1 >= rtc_alarm_time) { ++ ANDROID_ALARM_DPRINTF(ANDROID_ALARM_PRINT_INFO, ++ "alarm about to go off\n"); ++ memset(&rtc_alarm, 0, sizeof(rtc_alarm)); ++ rtc_alarm.enabled = 0; ++ rtc_set_alarm(alarm_rtc_dev, &rtc_alarm); ++ ++ spin_lock_irqsave(&alarm_slock, flags); ++ wake_lock_timeout(&alarm_rtc_wake_lock, 2 * HZ); ++ alarm_start_hrtimer(ANDROID_ALARM_RTC_WAKEUP); ++ alarm_start_hrtimer( ++ ANDROID_ALARM_ELAPSED_REALTIME_WAKEUP); ++ err = -EBUSY; ++ spin_unlock_irqrestore(&alarm_slock, flags); ++ } ++ } else { ++err1: ++ spin_unlock_irqrestore(&alarm_slock, flags); ++ } ++ return err; ++} ++ ++int alarm_resume(struct platform_device *pdev) ++{ ++ struct rtc_wkalrm alarm; ++ ANDROID_ALARM_DPRINTF(ANDROID_ALARM_PRINT_FLOW, ++ "alarm_resume(%p)\n", pdev); ++ if (alarm_enabled & ANDROID_ALARM_WAKEUP_MASK) { ++ memset(&alarm, 0, sizeof(alarm)); ++ alarm.enabled = 0; ++ rtc_set_alarm(alarm_rtc_dev, &alarm); ++ alarm_start_hrtimer(ANDROID_ALARM_RTC_WAKEUP); ++ alarm_start_hrtimer(ANDROID_ALARM_ELAPSED_REALTIME_WAKEUP); ++ } ++ return 0; ++} ++ ++static struct rtc_task alarm_rtc_task = { ++ .func = alarm_triggered_func ++}; ++ ++static struct file_operations alarm_fops = { ++ .owner = THIS_MODULE, ++ .unlocked_ioctl = alarm_ioctl, ++ .open = alarm_open, ++ .release = alarm_release, ++}; ++ ++static struct miscdevice alarm_device = { ++ .minor = MISC_DYNAMIC_MINOR, ++ .name = "alarm", ++ .fops = &alarm_fops, ++}; ++ ++static int rtc_alarm_add_device(struct device *dev, ++ struct class_interface *class_intf) ++{ ++ int err; ++ struct rtc_device *rtc = to_rtc_device(dev); ++ ++ mutex_lock(&alarm_setrtc_mutex); ++ ++ if (alarm_rtc_dev) { ++ err = -EBUSY; ++ goto err1; ++ } ++ ++ err = misc_register(&alarm_device); ++ if (err) ++ goto err1; ++ alarm_platform_dev = ++ platform_device_register_simple("alarm", -1, NULL, 0); ++ if (IS_ERR(alarm_platform_dev)) { ++ err = PTR_ERR(alarm_platform_dev); ++ goto err2; ++ } ++ err = rtc_irq_register(rtc, &alarm_rtc_task); ++ if (err) ++ goto err3; ++ alarm_rtc_dev = rtc; ++ mutex_unlock(&alarm_setrtc_mutex); ++ ++ ANDROID_ALARM_DPRINTF(ANDROID_ALARM_PRINT_INFO, "alarm: parent %p\n", ++ alarm_platform_dev->dev.power.pm_parent); ++ return 0; ++ ++err3: ++ platform_device_unregister(alarm_platform_dev); ++err2: ++ misc_deregister(&alarm_device); ++err1: ++ mutex_unlock(&alarm_setrtc_mutex); ++ return err; ++} ++ ++static void rtc_alarm_remove_device(struct device *dev, ++ struct class_interface *class_intf) ++{ ++ if (dev == &alarm_rtc_dev->dev) { ++ rtc_irq_unregister(alarm_rtc_dev, &alarm_rtc_task); ++ platform_device_unregister(alarm_platform_dev); ++ misc_deregister(&alarm_device); ++ alarm_rtc_dev = NULL; ++ } ++} ++ ++static struct class_interface rtc_alarm_interface = { ++ .add_dev = &rtc_alarm_add_device, ++ .remove_dev = &rtc_alarm_remove_device, ++}; ++ ++static struct platform_driver alarm_driver = { ++ .suspend = alarm_suspend, ++ .resume = alarm_resume, ++ .driver = { ++ .name = "alarm" ++ } ++}; ++ ++static int __init alarm_late_init(void) ++{ ++ unsigned long flags; ++ struct timespec system_time; ++ ++ /* this needs to run after the rtc is read at boot */ ++ spin_lock_irqsave(&alarm_slock, flags); ++ /* We read the current rtc and system time so we can later calulate ++ * elasped realtime to be (boot_systemtime + rtc - boot_rtc) == ++ * (rtc - (boot_rtc - boot_systemtime)) ++ */ ++ getnstimeofday(&elapsed_rtc_delta); ++ ktime_get_ts(&system_time); ++ elapsed_rtc_delta = timespec_sub(elapsed_rtc_delta, system_time); ++ spin_unlock_irqrestore(&alarm_slock, flags); ++ ++ ANDROID_ALARM_DPRINTF(ANDROID_ALARM_PRINT_INFO, ++ "alarm_late_init: rtc to elapsed realtime delta %ld.%09ld\n", ++ elapsed_rtc_delta.tv_sec, elapsed_rtc_delta.tv_nsec); ++ return 0; ++} ++ ++static int __init alarm_init(void) ++{ ++ int err; ++ int i; ++ ++ for (i = 0; i < ANDROID_ALARM_SYSTEMTIME; i++) { ++ hrtimer_init(&alarm_timer[i], CLOCK_REALTIME, HRTIMER_MODE_ABS); ++ alarm_timer[i].function = alarm_timer_triggered; ++ } ++ hrtimer_init(&alarm_timer[ANDROID_ALARM_SYSTEMTIME], ++ CLOCK_MONOTONIC, HRTIMER_MODE_ABS); ++ alarm_timer[ANDROID_ALARM_SYSTEMTIME].function = alarm_timer_triggered; ++ err = platform_driver_register(&alarm_driver); ++ if (err < 0) ++ goto err1; ++ wake_lock_init(&alarm_wake_lock, WAKE_LOCK_SUSPEND, "alarm"); ++ wake_lock_init(&alarm_rtc_wake_lock, WAKE_LOCK_SUSPEND, "alarm_rtc"); ++ rtc_alarm_interface.class = rtc_class; ++ err = class_interface_register(&rtc_alarm_interface); ++ if (err < 0) ++ goto err2; ++ ++ return 0; ++ ++err2: ++ wake_lock_destroy(&alarm_rtc_wake_lock); ++ wake_lock_destroy(&alarm_wake_lock); ++ platform_driver_unregister(&alarm_driver); ++err1: ++ return err; ++} ++ ++static void __exit alarm_exit(void) ++{ ++ class_interface_unregister(&rtc_alarm_interface); ++ wake_lock_destroy(&alarm_rtc_wake_lock); ++ wake_lock_destroy(&alarm_wake_lock); ++ platform_driver_unregister(&alarm_driver); ++} ++ ++late_initcall(alarm_late_init); ++module_init(alarm_init); ++module_exit(alarm_exit); ++ +diff -ruN --exclude='*.orig' --exclude='*.rej' linux-2.6.29-rc3.owrt/drivers/staging/android/binder.c linux-2.6.29-rc3.owrt.om/drivers/staging/android/binder.c +--- linux-2.6.29-rc3.owrt/drivers/staging/android/binder.c 2009-05-10 22:08:44.000000000 +0200 ++++ linux-2.6.29-rc3.owrt.om/drivers/staging/android/binder.c 2009-05-10 22:28:00.000000000 +0200 +@@ -54,7 +54,7 @@ + #define SZ_4M 0x400000 + #endif + +-#ifndef __i386__ ++#if !defined(__i386__) && !defined(__arm__) + #define FORBIDDEN_MMAP_FLAGS (VM_WRITE | VM_EXEC) + #else + #define FORBIDDEN_MMAP_FLAGS (VM_WRITE) +@@ -2649,14 +2649,14 @@ + { + struct binder_proc *proc = vma->vm_private_data; + if (binder_debug_mask & BINDER_DEBUG_OPEN_CLOSE) +- printk(KERN_INFO "binder: %d open vm area %lx-%lx (%ld K) vma %lx pagep %lx\n", proc->pid, vma->vm_start, vma->vm_end, (vma->vm_end - vma->vm_start) / SZ_1K, vma->vm_flags, vma->vm_page_prot.pgprot); ++ printk(KERN_INFO "binder: %d open vm area %lx-%lx (%ld K) vma %lx pagep %lx\n", proc->pid, vma->vm_start, vma->vm_end, (vma->vm_end - vma->vm_start) / SZ_1K, vma->vm_flags, vma->vm_page_prot); + dump_stack(); + } + static void binder_vma_close(struct vm_area_struct *vma) + { + struct binder_proc *proc = vma->vm_private_data; + if (binder_debug_mask & BINDER_DEBUG_OPEN_CLOSE) +- printk(KERN_INFO "binder: %d close vm area %lx-%lx (%ld K) vma %lx pagep %lx\n", proc->pid, vma->vm_start, vma->vm_end, (vma->vm_end - vma->vm_start) / SZ_1K, vma->vm_flags, vma->vm_page_prot.pgprot); ++ printk(KERN_INFO "binder: %d close vm area %lx-%lx (%ld K) vma %lx pagep %lx\n", proc->pid, vma->vm_start, vma->vm_end, (vma->vm_end - vma->vm_start) / SZ_1K, vma->vm_flags, vma->vm_page_prot); + proc->vma = NULL; + } + +@@ -2677,7 +2677,7 @@ + vma->vm_end = vma->vm_start + SZ_4M; + + if (binder_debug_mask & BINDER_DEBUG_OPEN_CLOSE) +- printk(KERN_INFO "binder_mmap: %d %lx-%lx (%ld K) vma %lx pagep %lx\n", proc->pid, vma->vm_start, vma->vm_end, (vma->vm_end - vma->vm_start) / SZ_1K, vma->vm_flags, vma->vm_page_prot.pgprot); ++ printk(KERN_INFO "binder_mmap: %d %lx-%lx (%ld K) vma %lx pagep %lx\n", proc->pid, vma->vm_start, vma->vm_end, (vma->vm_end - vma->vm_start) / SZ_1K, vma->vm_flags, vma->vm_page_prot); + + if (vma->vm_flags & FORBIDDEN_MMAP_FLAGS) { + ret = -EPERM; +diff -ruN --exclude='*.orig' --exclude='*.rej' linux-2.6.29-rc3.owrt/drivers/staging/android/consoleearlysuspend.c linux-2.6.29-rc3.owrt.om/drivers/staging/android/consoleearlysuspend.c +--- linux-2.6.29-rc3.owrt/drivers/staging/android/consoleearlysuspend.c 1970-01-01 01:00:00.000000000 +0100 ++++ linux-2.6.29-rc3.owrt.om/drivers/staging/android/consoleearlysuspend.c 2009-05-10 22:28:00.000000000 +0200 +@@ -0,0 +1,78 @@ ++/* kernel/power/consoleearlysuspend.c ++ * ++ * Copyright (C) 2005-2008 Google, Inc. ++ * ++ * This software is licensed under the terms of the GNU General Public ++ * License version 2, as published by the Free Software Foundation, and ++ * may be copied, distributed, and modified under those terms. ++ * ++ * 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. ++ * ++ */ ++ ++#include <linux/console.h> ++#include <linux/earlysuspend.h> ++#include <linux/kbd_kern.h> ++#include <linux/module.h> ++#include <linux/vt_kern.h> ++#include <linux/wait.h> ++ ++#define EARLY_SUSPEND_CONSOLE (MAX_NR_CONSOLES-1) ++ ++static int orig_fgconsole; ++static void console_early_suspend(struct early_suspend *h) ++{ ++ acquire_console_sem(); ++ orig_fgconsole = fg_console; ++ if (vc_allocate(EARLY_SUSPEND_CONSOLE)) ++ goto err; ++ if (set_console(EARLY_SUSPEND_CONSOLE)) ++ goto err; ++ release_console_sem(); ++ ++ if (vt_waitactive(EARLY_SUSPEND_CONSOLE)) ++ pr_warning("console_early_suspend: Can't switch VCs.\n"); ++ return; ++err: ++ pr_warning("console_early_suspend: Can't set console\n"); ++ release_console_sem(); ++} ++ ++static void console_late_resume(struct early_suspend *h) ++{ ++ int ret; ++ acquire_console_sem(); ++ ret = set_console(orig_fgconsole); ++ release_console_sem(); ++ if (ret) { ++ pr_warning("console_late_resume: Can't set console.\n"); ++ return; ++ } ++ ++ if (vt_waitactive(orig_fgconsole)) ++ pr_warning("console_late_resume: Can't switch VCs.\n"); ++} ++ ++static struct early_suspend console_early_suspend_desc = { ++ .level = EARLY_SUSPEND_LEVEL_STOP_DRAWING, ++ .suspend = console_early_suspend, ++ .resume = console_late_resume, ++}; ++ ++static int __init console_early_suspend_init(void) ++{ ++ register_early_suspend(&console_early_suspend_desc); ++ return 0; ++} ++ ++static void __exit console_early_suspend_exit(void) ++{ ++ unregister_early_suspend(&console_early_suspend_desc); ++} ++ ++module_init(console_early_suspend_init); ++module_exit(console_early_suspend_exit); ++ +diff -ruN --exclude='*.orig' --exclude='*.rej' linux-2.6.29-rc3.owrt/drivers/staging/android/earlysuspend.c linux-2.6.29-rc3.owrt.om/drivers/staging/android/earlysuspend.c +--- linux-2.6.29-rc3.owrt/drivers/staging/android/earlysuspend.c 1970-01-01 01:00:00.000000000 +0100 ++++ linux-2.6.29-rc3.owrt.om/drivers/staging/android/earlysuspend.c 2009-05-10 22:28:00.000000000 +0200 +@@ -0,0 +1,178 @@ ++/* kernel/power/earlysuspend.c ++ * ++ * Copyright (C) 2005-2008 Google, Inc. ++ * ++ * This software is licensed under the terms of the GNU General Public ++ * License version 2, as published by the Free Software Foundation, and ++ * may be copied, distributed, and modified under those terms. ++ * ++ * 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. ++ * ++ */ ++ ++#include <linux/earlysuspend.h> ++#include <linux/module.h> ++#include <linux/mutex.h> ++#include <linux/rtc.h> ++#include <linux/syscalls.h> /* sys_sync */ ++#include <linux/wakelock.h> ++#include <linux/workqueue.h> ++ ++#include "power.h" ++ ++enum { ++ DEBUG_USER_STATE = 1U << 0, ++ DEBUG_SUSPEND = 1U << 2, ++}; ++static int debug_mask = DEBUG_USER_STATE; ++module_param_named(debug_mask, debug_mask, int, S_IRUGO | S_IWUSR | S_IWGRP); ++ ++static DEFINE_MUTEX(early_suspend_lock); ++static LIST_HEAD(early_suspend_handlers); ++static void early_suspend(struct work_struct *work); ++static void late_resume(struct work_struct *work); ++static DECLARE_WORK(early_suspend_work, early_suspend); ++static DECLARE_WORK(late_resume_work, late_resume); ++static DEFINE_SPINLOCK(state_lock); ++enum { ++ SUSPEND_REQUESTED = 0x1, ++ SUSPENDED = 0x2, ++ SUSPEND_REQUESTED_AND_SUSPENDED = SUSPEND_REQUESTED | SUSPENDED, ++}; ++static int state; ++ ++void register_early_suspend(struct early_suspend *handler) ++{ ++ struct list_head *pos; ++ ++ mutex_lock(&early_suspend_lock); ++ list_for_each(pos, &early_suspend_handlers) { ++ struct early_suspend *e; ++ e = list_entry(pos, struct early_suspend, link); ++ if (e->level > handler->level) ++ break; ++ } ++ list_add_tail(&handler->link, pos); ++ if ((state & SUSPENDED) && handler->suspend) ++ handler->suspend(handler); ++ mutex_unlock(&early_suspend_lock); ++} ++EXPORT_SYMBOL(register_early_suspend); ++ ++void unregister_early_suspend(struct early_suspend *handler) ++{ ++ mutex_lock(&early_suspend_lock); ++ list_del(&handler->link); ++ mutex_unlock(&early_suspend_lock); ++} ++EXPORT_SYMBOL(unregister_early_suspend); ++ ++static void early_suspend(struct work_struct *work) ++{ ++ struct early_suspend *pos; ++ unsigned long irqflags; ++ int abort = 0; ++ ++ mutex_lock(&early_suspend_lock); ++ spin_lock_irqsave(&state_lock, irqflags); ++ if (state == SUSPEND_REQUESTED) ++ state |= SUSPENDED; ++ else ++ abort = 1; ++ spin_unlock_irqrestore(&state_lock, irqflags); ++ ++ if (abort) { ++ if (debug_mask & DEBUG_SUSPEND) ++ pr_info("early_suspend: abort, state %d\n", state); ++ mutex_unlock(&early_suspend_lock); ++ goto abort; ++ } ++ ++ if (debug_mask & DEBUG_SUSPEND) ++ pr_info("early_suspend: call handlers\n"); ++ list_for_each_entry(pos, &early_suspend_handlers, link) { ++ if (pos->suspend != NULL) ++ pos->suspend(pos); ++ } ++ mutex_unlock(&early_suspend_lock); ++ ++ if (debug_mask & DEBUG_SUSPEND) ++ pr_info("early_suspend: sync\n"); ++ ++ sys_sync(); ++abort: ++ spin_lock_irqsave(&state_lock, irqflags); ++ if (state == SUSPEND_REQUESTED_AND_SUSPENDED) ++ wake_unlock(&main_wake_lock); ++ spin_unlock_irqrestore(&state_lock, irqflags); ++} ++ ++static void late_resume(struct work_struct *work) ++{ ++ struct early_suspend *pos; ++ unsigned long irqflags; ++ int abort = 0; ++ ++ mutex_lock(&early_suspend_lock); ++ spin_lock_irqsave(&state_lock, irqflags); ++ if (state == SUSPENDED) ++ state &= ~SUSPENDED; ++ else ++ abort = 1; ++ spin_unlock_irqrestore(&state_lock, irqflags); ++ ++ if (abort) { ++ if (debug_mask & DEBUG_SUSPEND) ++ pr_info("late_resume: abort, state %d\n", state); ++ goto abort; ++ } ++ if (debug_mask & DEBUG_SUSPEND) ++ pr_info("late_resume: call handlers\n"); ++ list_for_each_entry_reverse(pos, &early_suspend_handlers, link) ++ if (pos->resume != NULL) ++ pos->resume(pos); ++ if (debug_mask & DEBUG_SUSPEND) ++ pr_info("late_resume: done\n"); ++abort: ++ mutex_unlock(&early_suspend_lock); ++} ++ ++void request_suspend_state(suspend_state_t new_state) ++{ ++ unsigned long irqflags; ++ int old_sleep; ++ ++ spin_lock_irqsave(&state_lock, irqflags); ++ old_sleep = state & SUSPEND_REQUESTED; ++ if (debug_mask & DEBUG_USER_STATE) { ++ struct timespec ts; ++ struct rtc_time tm; ++ getnstimeofday(&ts); ++ rtc_time_to_tm(ts.tv_sec, &tm); ++ pr_info("request_suspend_state: %s (%d->%d) at %lld " ++ "(%d-%02d-%02d %02d:%02d:%02d.%09lu UTC)\n", ++ new_state != PM_SUSPEND_ON ? "sleep" : "wakeup", ++ requested_suspend_state, new_state, ++ ktime_to_ns(ktime_get()), ++ tm.tm_year + 1900, tm.tm_mon + 1, tm.tm_mday, ++ tm.tm_hour, tm.tm_min, tm.tm_sec, ts.tv_nsec); ++ } ++ if (!old_sleep && new_state != PM_SUSPEND_ON) { ++ state |= SUSPEND_REQUESTED; ++ queue_work(suspend_work_queue, &early_suspend_work); ++ } else if (old_sleep && new_state == PM_SUSPEND_ON) { ++ state &= ~SUSPEND_REQUESTED; ++ wake_lock(&main_wake_lock); ++ queue_work(suspend_work_queue, &late_resume_work); ++ } ++ requested_suspend_state = new_state; ++ spin_unlock_irqrestore(&state_lock, irqflags); ++} ++ ++suspend_state_t get_suspend_state(void) ++{ ++ return requested_suspend_state; ++} +diff -ruN --exclude='*.orig' --exclude='*.rej' linux-2.6.29-rc3.owrt/drivers/staging/android/fbearlysuspend.c linux-2.6.29-rc3.owrt.om/drivers/staging/android/fbearlysuspend.c +--- linux-2.6.29-rc3.owrt/drivers/staging/android/fbearlysuspend.c 1970-01-01 01:00:00.000000000 +0100 ++++ linux-2.6.29-rc3.owrt.om/drivers/staging/android/fbearlysuspend.c 2009-05-10 22:28:00.000000000 +0200 +@@ -0,0 +1,153 @@ ++/* kernel/power/fbearlysuspend.c ++ * ++ * Copyright (C) 2005-2008 Google, Inc. ++ * ++ * This software is licensed under the terms of the GNU General Public ++ * License version 2, as published by the Free Software Foundation, and ++ * may be copied, distributed, and modified under those terms. ++ * ++ * 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. ++ * ++ */ ++ ++#include <linux/earlysuspend.h> ++#include <linux/module.h> ++#include <linux/wait.h> ++ ++#include "power.h" ++ ++static wait_queue_head_t fb_state_wq; ++static DEFINE_SPINLOCK(fb_state_lock); ++static enum { ++ FB_STATE_STOPPED_DRAWING, ++ FB_STATE_REQUEST_STOP_DRAWING, ++ FB_STATE_DRAWING_OK, ++} fb_state; ++ ++/* tell userspace to stop drawing, wait for it to stop */ ++static void stop_drawing_early_suspend(struct early_suspend *h) ++{ ++ int ret; ++ unsigned long irq_flags; ++ ++ spin_lock_irqsave(&fb_state_lock, irq_flags); ++ fb_state = FB_STATE_REQUEST_STOP_DRAWING; ++ spin_unlock_irqrestore(&fb_state_lock, irq_flags); ++ ++ wake_up_all(&fb_state_wq); ++ ret = wait_event_timeout(fb_state_wq, ++ fb_state == FB_STATE_STOPPED_DRAWING, ++ HZ); ++ if (unlikely(fb_state != FB_STATE_STOPPED_DRAWING)) ++ pr_warning("stop_drawing_early_suspend: timeout waiting for " ++ "userspace to stop drawing\n"); ++} ++ ++/* tell userspace to start drawing */ ++static void start_drawing_late_resume(struct early_suspend *h) ++{ ++ unsigned long irq_flags; ++ ++ spin_lock_irqsave(&fb_state_lock, irq_flags); ++ fb_state = FB_STATE_DRAWING_OK; ++ spin_unlock_irqrestore(&fb_state_lock, irq_flags); ++ wake_up(&fb_state_wq); ++} ++ ++static struct early_suspend stop_drawing_early_suspend_desc = { ++ .level = EARLY_SUSPEND_LEVEL_STOP_DRAWING, ++ .suspend = stop_drawing_early_suspend, ++ .resume = start_drawing_late_resume, ++}; ++ ++static ssize_t wait_for_fb_sleep_show(struct kobject *kobj, ++ struct kobj_attribute *attr, char *buf) ++{ ++ char *s = buf; ++ int ret; ++ ++ ret = wait_event_interruptible(fb_state_wq, ++ fb_state != FB_STATE_DRAWING_OK); ++ if (ret && fb_state == FB_STATE_DRAWING_OK) ++ return ret; ++ else ++ s += sprintf(buf, "sleeping"); ++ return s - buf; ++} ++ ++static ssize_t wait_for_fb_wake_show(struct kobject *kobj, ++ struct kobj_attribute *attr, char *buf) ++{ ++ char *s = buf; ++ int ret; ++ unsigned long irq_flags; ++ ++ spin_lock_irqsave(&fb_state_lock, irq_flags); ++ if (fb_state == FB_STATE_REQUEST_STOP_DRAWING) { ++ fb_state = FB_STATE_STOPPED_DRAWING; ++ wake_up(&fb_state_wq); ++ } ++ spin_unlock_irqrestore(&fb_state_lock, irq_flags); ++ ++ ret = wait_event_interruptible(fb_state_wq, ++ fb_state == FB_STATE_DRAWING_OK); ++ if (ret && fb_state != FB_STATE_DRAWING_OK) ++ return ret; ++ else ++ s += sprintf(buf, "awake"); ++ ++ return s - buf; ++} ++ ++#define power_ro_attr(_name) \ ++static struct kobj_attribute _name##_attr = { \ ++ .attr = { \ ++ .name = __stringify(_name), \ ++ .mode = 0444, \ ++ }, \ ++ .show = _name##_show, \ ++ .store = NULL, \ ++} ++ ++power_ro_attr(wait_for_fb_sleep); ++power_ro_attr(wait_for_fb_wake); ++ ++static struct attribute *g[] = { ++ &wait_for_fb_sleep_attr.attr, ++ &wait_for_fb_wake_attr.attr, ++ NULL, ++}; ++ ++static struct attribute_group attr_group = { ++ .attrs = g, ++}; ++ ++static int __init android_power_init(void) ++{ ++ int ret; ++ ++ init_waitqueue_head(&fb_state_wq); ++ fb_state = FB_STATE_DRAWING_OK; ++ ++ ret = sysfs_create_group(power_kobj, &attr_group); ++ if (ret) { ++ pr_err("android_power_init: sysfs_create_group failed\n"); ++ return ret; ++ } ++ ++ register_early_suspend(&stop_drawing_early_suspend_desc); ++ return 0; ++} ++ ++static void __exit android_power_exit(void) ++{ ++ unregister_early_suspend(&stop_drawing_early_suspend_desc); ++ sysfs_remove_group(power_kobj, &attr_group); ++} ++ ++module_init(android_power_init); ++module_exit(android_power_exit); ++ +diff -ruN --exclude='*.orig' --exclude='*.rej' linux-2.6.29-rc3.owrt/drivers/staging/android/Kconfig linux-2.6.29-rc3.owrt.om/drivers/staging/android/Kconfig +--- linux-2.6.29-rc3.owrt/drivers/staging/android/Kconfig 2009-05-10 22:08:44.000000000 +0200 ++++ linux-2.6.29-rc3.owrt.om/drivers/staging/android/Kconfig 2009-05-10 22:28:00.000000000 +0200 +@@ -83,4 +83,80 @@ + ---help--- + Register processes to be killed when memory is low + ++config ANDROID_HAS_WAKELOCK ++ bool ++ ++config ANDROID_HAS_EARLYSUSPEND ++ bool ++ ++config ANDROID_WAKELOCK ++ bool "Wake lock" ++ depends on PM && RTC_CLASS ++ default n ++ select ANDROID_HAS_WAKELOCK ++ ---help--- ++ Enable wakelocks. When user space request a sleep state the ++ sleep request will be delayed until no wake locks are held. ++ ++config ANDROID_WAKELOCK_STAT ++ bool "Wake lock stats" ++ depends on WAKELOCK ++ default y ++ ---help--- ++ Report wake lock stats in /proc/wakelocks ++ ++config ANDROID_USER_WAKELOCK ++ bool "Userspace wake locks" ++ depends on ANDROID_WAKELOCK ++ default y ++ ---help--- ++ User-space wake lock api. Write "lockname" or "lockname timeout" ++ to /sys/power/wake_lock lock and if needed create a wake lock. ++ Write "lockname" to /sys/power/wake_unlock to unlock a user wake ++ lock. ++ ++config ANDROID_EARLYSUSPEND ++ bool "Early suspend" ++ depends on ANDROID_WAKELOCK ++ default y ++ select ANDROID_HAS_EARLYSUSPEND ++ ---help--- ++ Call early suspend handlers when the user requested sleep state ++ changes. ++ ++choice ++ prompt "User-space screen access" ++ default ANDROID_FB_EARLYSUSPEND if !FRAMEBUFFER_CONSOLE ++ default ANDROID_CONSOLE_EARLYSUSPEND ++ depends on ANDROID_HAS_EARLYSUSPEND ++ ++ config NO_USER_SPACE_SCREEN_ACCESS_CONTROL ++ bool "None" ++ ++ config ANDROID_CONSOLE_EARLYSUSPEND ++ bool "Console switch on early-suspend" ++ depends on ANDROID_HAS_EARLYSUSPEND && VT ++ ---help--- ++ Register early suspend handler to perform a console switch to ++ when user-space should stop drawing to the screen and a switch ++ back when it should resume. ++ ++ config ANDROID_FB_EARLYSUSPEND ++ bool "Sysfs interface" ++ depends on ANDROID_HAS_EARLYSUSPEND ++ ---help--- ++ Register early suspend handler that notifies and waits for ++ user-space through sysfs when user-space should stop drawing ++ to the screen and notifies user-space when it should resume. ++endchoice ++ ++config ANDROID_POWER_ALARM ++ bool "Android alarm driver" ++ depends on ANDROID_WAKELOCK ++ default y ++ ++config ANDROID_PARANOID_NETWORK ++ bool "Only allow certain groups to create sockets" ++ default y ++ + endmenu +diff -ruN --exclude='*.orig' --exclude='*.rej' linux-2.6.29-rc3.owrt/drivers/staging/android/Makefile linux-2.6.29-rc3.owrt.om/drivers/staging/android/Makefile +--- linux-2.6.29-rc3.owrt/drivers/staging/android/Makefile 2009-05-10 22:04:48.000000000 +0200 ++++ linux-2.6.29-rc3.owrt.om/drivers/staging/android/Makefile 2009-05-10 22:28:00.000000000 +0200 +@@ -3,3 +3,9 @@ + obj-$(CONFIG_ANDROID_RAM_CONSOLE) += ram_console.o + obj-$(CONFIG_ANDROID_TIMED_GPIO) += timed_gpio.o + obj-$(CONFIG_ANDROID_LOW_MEMORY_KILLER) += lowmemorykiller.o ++obj-$(CONFIG_ANDROID_POWER_ALARM) += alarm.o ++obj-$(CONFIG_ANDROID_WAKELOCK) += wakelock.o ++obj-$(CONFIG_ANDROID_USER_WAKELOCK) += userwakelock.o ++obj-$(CONFIG_ANDROID_EARLYSUSPEND) += earlysuspend.o ++obj-$(CONFIG_ANDROID_CONSOLE_EARLYSUSPEND) += consoleearlysuspend.o ++obj-$(CONFIG_ANDROID_FB_EARLYSUSPEND) += fbearlysuspend.o +diff -ruN --exclude='*.orig' --exclude='*.rej' linux-2.6.29-rc3.owrt/drivers/staging/android/power.h linux-2.6.29-rc3.owrt.om/drivers/staging/android/power.h +--- linux-2.6.29-rc3.owrt/drivers/staging/android/power.h 1970-01-01 01:00:00.000000000 +0100 ++++ linux-2.6.29-rc3.owrt.om/drivers/staging/android/power.h 2009-05-10 22:28:00.000000000 +0200 +@@ -0,0 +1 @@ ++#include "../../../kernel/power/power.h" +diff -ruN --exclude='*.orig' --exclude='*.rej' linux-2.6.29-rc3.owrt/drivers/staging/android/timed_gpio.c linux-2.6.29-rc3.owrt.om/drivers/staging/android/timed_gpio.c +--- linux-2.6.29-rc3.owrt/drivers/staging/android/timed_gpio.c 2009-05-10 22:08:44.000000000 +0200 ++++ linux-2.6.29-rc3.owrt.om/drivers/staging/android/timed_gpio.c 2009-05-10 22:28:00.000000000 +0200 +@@ -18,7 +18,7 @@ + #include <linux/platform_device.h> + #include <linux/hrtimer.h> + #include <linux/err.h> +-#include <asm/arch/gpio.h> ++#include <linux/gpio.h> + + #include "timed_gpio.h" + +diff -ruN --exclude='*.orig' --exclude='*.rej' linux-2.6.29-rc3.owrt/drivers/staging/android/userwakelock.c linux-2.6.29-rc3.owrt.om/drivers/staging/android/userwakelock.c +--- linux-2.6.29-rc3.owrt/drivers/staging/android/userwakelock.c 1970-01-01 01:00:00.000000000 +0100 ++++ linux-2.6.29-rc3.owrt.om/drivers/staging/android/userwakelock.c 2009-05-10 22:28:00.000000000 +0200 +@@ -0,0 +1,245 @@ ++/* kernel/power/userwakelock.c ++ * ++ * Copyright (C) 2005-2008 Google, Inc. ++ * ++ * This software is licensed under the terms of the GNU General Public ++ * License version 2, as published by the Free Software Foundation, and ++ * may be copied, distributed, and modified under those terms. ++ * ++ * 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. ++ * ++ */ ++ ++#include <linux/ctype.h> ++#include <linux/module.h> ++#include <linux/wakelock.h> ++ ++#include "power.h" ++ ++enum { ++ DEBUG_FAILURE = BIT(0), ++ DEBUG_ERROR = BIT(1), ++ DEBUG_NEW = BIT(2), ++ DEBUG_ACCESS = BIT(3), ++ DEBUG_LOOKUP = BIT(4), ++}; ++static int debug_mask = DEBUG_FAILURE; ++module_param_named(debug_mask, debug_mask, int, S_IRUGO | S_IWUSR | S_IWGRP); ++ ++static DEFINE_MUTEX(tree_lock); ++ ++struct user_wake_lock { ++ struct rb_node node; ++ struct wake_lock wake_lock; ++ char name[0]; ++}; ++struct rb_root user_wake_locks; ++ ++static struct user_wake_lock *lookup_wake_lock_name( ++ const char *buf, int allocate, long *timeoutptr) ++{ ++ struct rb_node **p = &user_wake_locks.rb_node; ++ struct rb_node *parent = NULL; ++ struct user_wake_lock *l; ++ int diff; ++ u64 timeout; ++ int name_len; ++ const char *arg; ++ ++ /* Find length of lock name and start of optional timeout string */ ++ arg = buf; ++ while (*arg && !isspace(*arg)) ++ arg++; ++ name_len = arg - buf; ++ if (!name_len) ++ goto bad_arg; ++ while (isspace(*arg)) ++ arg++; ++ ++ /* Process timeout string */ ++ if (timeoutptr && *arg) { ++ timeout = simple_strtoull(arg, (char **)&arg, 0); ++ while (isspace(*arg)) ++ arg++; ++ if (*arg) ++ goto bad_arg; ++ /* convert timeout from nanoseconds to jiffies > 0 */ ++ timeout += (NSEC_PER_SEC / HZ) - 1; ++ do_div(timeout, (NSEC_PER_SEC / HZ)); ++ if (timeout <= 0) ++ timeout = 1; ++ *timeoutptr = timeout; ++ } else if (*arg) ++ goto bad_arg; ++ else if (timeoutptr) ++ *timeoutptr = 0; ++ ++ /* Lookup wake lock in rbtree */ ++ while (*p) { ++ parent = *p; ++ l = rb_entry(parent, struct user_wake_lock, node); ++ diff = strncmp(buf, l->name, name_len); ++ if (!diff && l->name[name_len]) ++ diff = -1; ++ if (debug_mask & DEBUG_ERROR) ++ pr_info("lookup_wake_lock_name: compare %.*s %s %d\n", ++ name_len, buf, l->name, diff); ++ ++ if (diff < 0) ++ p = &(*p)->rb_left; ++ else if (diff > 0) ++ p = &(*p)->rb_right; ++ else ++ return l; ++ } ++ ++ /* Allocate and add new wakelock to rbtree */ ++ if (!allocate) { ++ if (debug_mask & DEBUG_ERROR) ++ pr_info("lookup_wake_lock_name: %.*s not found\n", ++ name_len, buf); ++ return ERR_PTR(-EINVAL); ++ } ++ l = kzalloc(sizeof(*l) + name_len + 1, GFP_KERNEL); ++ if (l == NULL) { ++ if (debug_mask & DEBUG_FAILURE) ++ pr_err("lookup_wake_lock_name: failed to allocate " ++ "memory for %.*s\n", name_len, buf); ++ return ERR_PTR(-ENOMEM); ++ } ++ memcpy(l->name, buf, name_len); ++ if (debug_mask & DEBUG_NEW) ++ pr_info("lookup_wake_lock_name: new wake lock %s\n", l->name); ++ wake_lock_init(&l->wake_lock, WAKE_LOCK_SUSPEND, l->name); ++ rb_link_node(&l->node, parent, p); ++ rb_insert_color(&l->node, &user_wake_locks); ++ return l; ++ ++bad_arg: ++ if (debug_mask & DEBUG_ERROR) ++ pr_info("lookup_wake_lock_name: wake lock, %.*s, bad arg, %s\n", ++ name_len, buf, arg); ++ return ERR_PTR(-EINVAL); ++} ++ ++ssize_t wake_lock_show( ++ struct kobject *kobj, struct kobj_attribute *attr, char *buf) ++{ ++ char *s = buf; ++ char *end = buf + PAGE_SIZE; ++ struct rb_node *n; ++ struct user_wake_lock *l; ++ ++ mutex_lock(&tree_lock); ++ ++ for (n = rb_first(&user_wake_locks); n != NULL; n = rb_next(n)) { ++ l = rb_entry(n, struct user_wake_lock, node); ++ if (wake_lock_active(&l->wake_lock)) ++ s += scnprintf(s, end - s, "%s ", l->name); ++ } ++ s += scnprintf(s, end - s, "\n"); ++ ++ mutex_unlock(&tree_lock); ++ return (s - buf); ++} ++ ++ssize_t wake_full_lock_store( ++ struct kobject *kobj, struct kobj_attribute *attr, ++ const char *buf, size_t n) ++{ ++ long timeout; ++ struct user_wake_lock *l; ++ ++ mutex_lock(&tree_lock); ++ l = lookup_wake_lock_name(buf, 1, &timeout); ++ if (IS_ERR(l)) { ++ n = PTR_ERR(l); ++ goto bad_name; ++ } ++ ++ if (debug_mask & DEBUG_ACCESS) ++ pr_info("wake_full_lock_store: %s, timeout %ld\n", l->name, timeout); ++ ++ if (timeout == 0) ++ timeout = INT_MAX; ++ ++ if (timeout) ++ wake_lock_timeout(&l->wake_lock, timeout); ++bad_name: ++ mutex_unlock(&tree_lock); ++ return n; ++} ++ ++ssize_t wake_lock_store( ++ struct kobject *kobj, struct kobj_attribute *attr, ++ const char *buf, size_t n) ++{ ++ long timeout; ++ struct user_wake_lock *l; ++ ++ mutex_lock(&tree_lock); ++ l = lookup_wake_lock_name(buf, 1, &timeout); ++ if (IS_ERR(l)) { ++ n = PTR_ERR(l); ++ goto bad_name; ++ } ++ ++ if (debug_mask & DEBUG_ACCESS) ++ pr_info("wake_lock_store: %s, timeout %ld\n", l->name, timeout); ++ ++ if (timeout) ++ wake_lock_timeout(&l->wake_lock, timeout); ++ else ++ wake_lock(&l->wake_lock); ++bad_name: ++ mutex_unlock(&tree_lock); ++ return n; ++} ++ ++ ++ssize_t wake_unlock_show( ++ struct kobject *kobj, struct kobj_attribute *attr, char *buf) ++{ ++ char *s = buf; ++ char *end = buf + PAGE_SIZE; ++ struct rb_node *n; ++ struct user_wake_lock *l; ++ ++ mutex_lock(&tree_lock); ++ ++ for (n = rb_first(&user_wake_locks); n != NULL; n = rb_next(n)) { ++ l = rb_entry(n, struct user_wake_lock, node); ++ if (!wake_lock_active(&l->wake_lock)) ++ s += scnprintf(s, end - s, "%s ", l->name); ++ } ++ s += scnprintf(s, end - s, "\n"); ++ ++ mutex_unlock(&tree_lock); ++ return (s - buf); ++} ++ ++ssize_t wake_unlock_store( ++ struct kobject *kobj, struct kobj_attribute *attr, ++ const char *buf, size_t n) ++{ ++ struct user_wake_lock *l; ++ ++ mutex_lock(&tree_lock); ++ l = lookup_wake_lock_name(buf, 0, NULL); ++ if (IS_ERR(l)) { ++ n = PTR_ERR(l); ++ goto not_found; ++ } ++ ++ if (debug_mask & DEBUG_ACCESS) ++ pr_info("wake_unlock_store: %s\n", l->name); ++ ++ wake_unlock(&l->wake_lock); ++not_found: ++ mutex_unlock(&tree_lock); ++ return n; ++} ++ +diff -ruN --exclude='*.orig' --exclude='*.rej' linux-2.6.29-rc3.owrt/drivers/staging/android/wakelock.c linux-2.6.29-rc3.owrt.om/drivers/staging/android/wakelock.c +--- linux-2.6.29-rc3.owrt/drivers/staging/android/wakelock.c 1970-01-01 01:00:00.000000000 +0100 ++++ linux-2.6.29-rc3.owrt.om/drivers/staging/android/wakelock.c 2009-05-10 22:28:00.000000000 +0200 +@@ -0,0 +1,605 @@ ++/* kernel/power/wakelock.c ++ * ++ * Copyright (C) 2005-2008 Google, Inc. ++ * ++ * This software is licensed under the terms of the GNU General Public ++ * License version 2, as published by the Free Software Foundation, and ++ * may be copied, distributed, and modified under those terms. ++ * ++ * 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. ++ * ++ */ ++ ++#include <linux/module.h> ++#include <linux/platform_device.h> ++#include <linux/rtc.h> ++#include <linux/suspend.h> ++#include <linux/syscalls.h> /* sys_sync */ ++#include <linux/wakelock.h> ++#ifdef CONFIG_ANDROID_WAKELOCK_STAT ++#include <linux/proc_fs.h> ++#endif ++#include "power.h" ++ ++enum { ++ DEBUG_EXIT_SUSPEND = 1U << 0, ++ DEBUG_WAKEUP = 1U << 1, ++ DEBUG_SUSPEND = 1U << 2, ++ DEBUG_EXPIRE = 1U << 3, ++ DEBUG_WAKE_LOCK = 1U << 4, ++}; ++static int debug_mask = DEBUG_EXIT_SUSPEND | DEBUG_WAKEUP; ++ ++module_param_named(debug_mask, debug_mask, int, S_IRUGO | S_IWUSR | S_IWGRP); ++ ++#define WAKE_LOCK_TYPE_MASK (0x0f) ++#define WAKE_LOCK_INITIALIZED (1U << 8) ++#define WAKE_LOCK_ACTIVE (1U << 9) ++#define WAKE_LOCK_AUTO_EXPIRE (1U << 10) ++#define WAKE_LOCK_PREVENTING_SUSPEND (1U << 11) ++ ++static DEFINE_SPINLOCK(list_lock); ++static LIST_HEAD(inactive_locks); ++static struct list_head active_wake_locks[WAKE_LOCK_TYPE_COUNT]; ++static int current_event_num; ++struct workqueue_struct *suspend_work_queue; ++struct wake_lock main_wake_lock; ++suspend_state_t requested_suspend_state = PM_SUSPEND_MEM; ++static struct wake_lock unknown_wakeup; ++ ++#ifdef CONFIG_ANDROID_WAKELOCK_STAT ++static struct wake_lock deleted_wake_locks; ++static ktime_t last_sleep_time_update; ++static int wait_for_wakeup; ++ ++int get_expired_time(struct wake_lock *lock, ktime_t *expire_time) ++{ ++ struct timespec ts; ++ struct timespec kt; ++ struct timespec tomono; ++ struct timespec delta; ++ unsigned long seq; ++ long timeout; ++ ++ if (!(lock->flags & WAKE_LOCK_AUTO_EXPIRE)) ++ return 0; ++ do { ++ seq = read_seqbegin(&xtime_lock); ++ timeout = lock->expires - jiffies; ++ if (timeout > 0) ++ return 0; ++ kt = current_kernel_time(); ++ tomono = wall_to_monotonic; ++ } while (read_seqretry(&xtime_lock, seq)); ++ jiffies_to_timespec(-timeout, &delta); ++ set_normalized_timespec(&ts, kt.tv_sec + tomono.tv_sec - delta.tv_sec, ++ kt.tv_nsec + tomono.tv_nsec - delta.tv_nsec); ++ *expire_time = timespec_to_ktime(ts); ++ return 1; ++} ++ ++ ++static int print_lock_stat(char *buf, struct wake_lock *lock) ++{ ++ int lock_count = lock->stat.count; ++ int expire_count = lock->stat.expire_count; ++ ktime_t active_time = ktime_set(0, 0); ++ ktime_t total_time = lock->stat.total_time; ++ ktime_t max_time = lock->stat.max_time; ++ ktime_t prevent_suspend_time = lock->stat.prevent_suspend_time; ++ if (lock->flags & WAKE_LOCK_ACTIVE) { ++ ktime_t now, add_time; ++ int expired = get_expired_time(lock, &now); ++ if (!expired) ++ now = ktime_get(); ++ add_time = ktime_sub(now, lock->stat.last_time); ++ lock_count++; ++ if (!expired) ++ active_time = add_time; ++ else ++ expire_count++; ++ total_time = ktime_add(total_time, add_time); ++ if (lock->flags & WAKE_LOCK_PREVENTING_SUSPEND) ++ prevent_suspend_time = ktime_add(prevent_suspend_time, ++ ktime_sub(now, last_sleep_time_update)); ++ if (add_time.tv64 > max_time.tv64) ++ max_time = add_time; ++ } ++ ++ return sprintf(buf, "\"%s\"\t%d\t%d\t%d\t%lld\t%lld\t%lld\t%lld\t" ++ "%lld\n", lock->name, lock_count, expire_count, ++ lock->stat.wakeup_count, ktime_to_ns(active_time), ++ ktime_to_ns(total_time), ++ ktime_to_ns(prevent_suspend_time), ktime_to_ns(max_time), ++ ktime_to_ns(lock->stat.last_time)); ++} ++ ++ ++static int wakelocks_read_proc(char *page, char **start, off_t off, ++ int count, int *eof, void *data) ++{ ++ unsigned long irqflags; ++ struct wake_lock *lock; ++ int len = 0; ++ char *p = page; ++ int type; ++ ++ spin_lock_irqsave(&list_lock, irqflags); ++ ++ p += sprintf(p, "name\tcount\texpire_count\twake_count\tactive_since" ++ "\ttotal_time\tsleep_time\tmax_time\tlast_change\n"); ++ list_for_each_entry(lock, &inactive_locks, link) { ++ p += print_lock_stat(p, lock); ++ } ++ for (type = 0; type < WAKE_LOCK_TYPE_COUNT; type++) { ++ list_for_each_entry(lock, &active_wake_locks[type], link) ++ p += print_lock_stat(p, lock); ++ } ++ spin_unlock_irqrestore(&list_lock, irqflags); ++ ++ *start = page + off; ++ ++ len = p - page; ++ if (len > off) ++ len -= off; ++ else ++ len = 0; ++ ++ return len < count ? len : count; ++} ++ ++static void wake_unlock_stat_locked(struct wake_lock *lock, int expired) ++{ ++ ktime_t duration; ++ ktime_t now; ++ if (!(lock->flags & WAKE_LOCK_ACTIVE)) ++ return; ++ if (get_expired_time(lock, &now)) ++ expired = 1; ++ else ++ now = ktime_get(); ++ lock->stat.count++; ++ if (expired) ++ lock->stat.expire_count++; ++ duration = ktime_sub(now, lock->stat.last_time); ++ lock->stat.total_time = ktime_add(lock->stat.total_time, duration); ++ if (ktime_to_ns(duration) > ktime_to_ns(lock->stat.max_time)) ++ lock->stat.max_time = duration; ++ lock->stat.last_time = ktime_get(); ++ if (lock->flags & WAKE_LOCK_PREVENTING_SUSPEND) { ++ duration = ktime_sub(now, last_sleep_time_update); ++ lock->stat.prevent_suspend_time = ktime_add( ++ lock->stat.prevent_suspend_time, duration); ++ lock->flags &= ~WAKE_LOCK_PREVENTING_SUSPEND; ++ } ++} ++ ++static void update_sleep_wait_stats_locked(int done) ++{ ++ struct wake_lock *lock; ++ ktime_t now, etime, elapsed, add; ++ int expired; ++ ++ now = ktime_get(); ++ elapsed = ktime_sub(now, last_sleep_time_update); ++ list_for_each_entry(lock, &active_wake_locks[WAKE_LOCK_SUSPEND], link) { ++ expired = get_expired_time(lock, &etime); ++ if (lock->flags & WAKE_LOCK_PREVENTING_SUSPEND) { ++ if (expired) ++ add = ktime_sub(etime, last_sleep_time_update); ++ else ++ add = elapsed; ++ lock->stat.prevent_suspend_time = ktime_add( ++ lock->stat.prevent_suspend_time, add); ++ } ++ if (done || expired) ++ lock->flags &= ~WAKE_LOCK_PREVENTING_SUSPEND; ++ else ++ lock->flags |= WAKE_LOCK_PREVENTING_SUSPEND; ++ } ++ last_sleep_time_update = now; ++} ++#endif ++ ++ ++static void expire_wake_lock(struct wake_lock *lock) ++{ ++#ifdef CONFIG_ANDROID_WAKELOCK_STAT ++ wake_unlock_stat_locked(lock, 1); ++#endif ++ lock->flags &= ~(WAKE_LOCK_ACTIVE | WAKE_LOCK_AUTO_EXPIRE); ++ list_del(&lock->link); ++ list_add(&lock->link, &inactive_locks); ++ if (debug_mask & (DEBUG_WAKE_LOCK | DEBUG_EXPIRE)) ++ pr_info("expired wake lock %s\n", lock->name); ++} ++ ++static void print_active_locks(int type) ++{ ++ unsigned long irqflags; ++ struct wake_lock *lock; ++ ++ BUG_ON(type >= WAKE_LOCK_TYPE_COUNT); ++ spin_lock_irqsave(&list_lock, irqflags); ++ list_for_each_entry(lock, &active_wake_locks[type], link) { ++ if (lock->flags & WAKE_LOCK_AUTO_EXPIRE) { ++ long timeout = lock->expires - jiffies; ++ if (timeout <= 0) ++ pr_info("wake lock %s, expired\n", lock->name); ++ else ++ pr_info("active wake lock %s, time left %ld\n", ++ lock->name, timeout); ++ } else ++ pr_info("active wake lock %s\n", lock->name); ++ } ++ spin_unlock_irqrestore(&list_lock, irqflags); ++} ++ ++static long has_wake_lock_locked(int type) ++{ ++ struct wake_lock *lock, *n; ++ long max_timeout = 0; ++ ++ BUG_ON(type >= WAKE_LOCK_TYPE_COUNT); ++ list_for_each_entry_safe(lock, n, &active_wake_locks[type], link) { ++ if (lock->flags & WAKE_LOCK_AUTO_EXPIRE) { ++ long timeout = lock->expires - jiffies; ++ if (timeout <= 0) ++ expire_wake_lock(lock); ++ else if (timeout > max_timeout) ++ max_timeout = timeout; ++ } else ++ return -1; ++ } ++ return max_timeout; ++} ++ ++long has_wake_lock(int type) ++{ ++ long ret; ++ unsigned long irqflags; ++ spin_lock_irqsave(&list_lock, irqflags); ++ ret = has_wake_lock_locked(type); ++ spin_unlock_irqrestore(&list_lock, irqflags); ++ return ret; ++} ++ ++static void suspend(struct work_struct *work) ++{ ++ int ret; ++ int entry_event_num; ++ ++ if (has_wake_lock(WAKE_LOCK_SUSPEND)) { ++ if (debug_mask & DEBUG_SUSPEND) ++ pr_info("suspend: abort suspend\n"); ++ return; ++ } ++ ++ entry_event_num = current_event_num; ++ sys_sync(); ++ if (debug_mask & DEBUG_SUSPEND) ++ pr_info("suspend: enter suspend\n"); ++ ret = pm_suspend(requested_suspend_state); ++ if (debug_mask & DEBUG_EXIT_SUSPEND) { ++ struct timespec ts; ++ struct rtc_time tm; ++ getnstimeofday(&ts); ++ rtc_time_to_tm(ts.tv_sec, &tm); ++ pr_info("suspend: exit suspend, ret = %d " ++ "(%d-%02d-%02d %02d:%02d:%02d.%09lu UTC)\n", ret, ++ tm.tm_year + 1900, tm.tm_mon + 1, tm.tm_mday, ++ tm.tm_hour, tm.tm_min, tm.tm_sec, ts.tv_nsec); ++ } ++ /* Openmoko needs more times to resume and a timeout is necessary ++ * in any case */ ++ if (current_event_num == entry_event_num) { ++ if (debug_mask & DEBUG_SUSPEND) ++ pr_info("suspend: pm_suspend returned with no event\n"); ++ wake_lock_timeout(&unknown_wakeup, HZ / 2); ++ } else { ++ /* create a temp lock to avoid autosuspend */ ++ wake_lock_timeout(&unknown_wakeup, 5 * HZ); ++ } ++} ++ ++static DECLARE_WORK(suspend_work, suspend); ++ ++static void expire_wake_locks(unsigned long data) ++{ ++ long has_lock; ++ unsigned long irqflags; ++ if (debug_mask & DEBUG_EXPIRE) ++ pr_info("expire_wake_locks: start\n"); ++ if (debug_mask & DEBUG_SUSPEND) ++ print_active_locks(WAKE_LOCK_SUSPEND); ++ spin_lock_irqsave(&list_lock, irqflags); ++ has_lock = has_wake_lock_locked(WAKE_LOCK_SUSPEND); ++ if (debug_mask & DEBUG_EXPIRE) ++ pr_info("expire_wake_locks: done, has_lock %ld\n", has_lock); ++ if (has_lock == 0) ++ queue_work(suspend_work_queue, &suspend_work); ++ spin_unlock_irqrestore(&list_lock, irqflags); ++} ++static DEFINE_TIMER(expire_timer, expire_wake_locks, 0, 0); ++ ++static int power_suspend_late(struct platform_device *pdev, pm_message_t state) ++{ ++ int ret = has_wake_lock(WAKE_LOCK_SUSPEND) ? -EAGAIN : 0; ++#ifdef CONFIG_ANDROID_WAKELOCK_STAT ++ wait_for_wakeup = 1; ++#endif ++ if (debug_mask & DEBUG_SUSPEND) ++ pr_info("power_suspend_late return %d\n", ret); ++ return ret; ++} ++ ++static struct platform_driver power_driver = { ++ .driver.name = "power", ++ .suspend_late = power_suspend_late, ++}; ++static struct platform_device power_device = { ++ .name = "power", ++}; ++ ++void wake_lock_init(struct wake_lock *lock, int type, const char *name) ++{ ++ unsigned long irqflags = 0; ++ ++ if (name) ++ lock->name = name; ++ BUG_ON(!lock->name); ++ ++ if (debug_mask & DEBUG_WAKE_LOCK) ++ pr_info("wake_lock_init name=%s\n", lock->name); ++#ifdef CONFIG_ANDROID_WAKELOCK_STAT ++ lock->stat.count = 0; ++ lock->stat.expire_count = 0; ++ lock->stat.wakeup_count = 0; ++ lock->stat.total_time = ktime_set(0, 0); ++ lock->stat.prevent_suspend_time = ktime_set(0, 0); ++ lock->stat.max_time = ktime_set(0, 0); ++ lock->stat.last_time = ktime_set(0, 0); ++#endif ++ lock->flags = (type & WAKE_LOCK_TYPE_MASK) | WAKE_LOCK_INITIALIZED; ++ ++ INIT_LIST_HEAD(&lock->link); ++ spin_lock_irqsave(&list_lock, irqflags); ++ list_add(&lock->link, &inactive_locks); ++ spin_unlock_irqrestore(&list_lock, irqflags); ++} ++EXPORT_SYMBOL(wake_lock_init); ++ ++void wake_lock_destroy(struct wake_lock *lock) ++{ ++ unsigned long irqflags; ++ if (debug_mask & DEBUG_WAKE_LOCK) ++ pr_info("wake_lock_destroy name=%s\n", lock->name); ++ spin_lock_irqsave(&list_lock, irqflags); ++ lock->flags &= ~WAKE_LOCK_INITIALIZED; ++#ifdef CONFIG_ANDROID_WAKELOCK_STAT ++ if (lock->stat.count) { ++ deleted_wake_locks.stat.count += lock->stat.count; ++ deleted_wake_locks.stat.expire_count += lock->stat.expire_count; ++ deleted_wake_locks.stat.total_time = ++ ktime_add(deleted_wake_locks.stat.total_time, ++ lock->stat.total_time); ++ deleted_wake_locks.stat.prevent_suspend_time = ++ ktime_add(deleted_wake_locks.stat.prevent_suspend_time, ++ lock->stat.prevent_suspend_time); ++ deleted_wake_locks.stat.max_time = ++ ktime_add(deleted_wake_locks.stat.max_time, ++ lock->stat.max_time); ++ } ++#endif ++ list_del(&lock->link); ++ spin_unlock_irqrestore(&list_lock, irqflags); ++} ++EXPORT_SYMBOL(wake_lock_destroy); ++ ++static void wake_lock_internal( ++ struct wake_lock *lock, long timeout, int has_timeout) ++{ ++ int type; ++ unsigned long irqflags; ++ long expire_in; ++ ++ spin_lock_irqsave(&list_lock, irqflags); ++ type = lock->flags & WAKE_LOCK_TYPE_MASK; ++ BUG_ON(type >= WAKE_LOCK_TYPE_COUNT); ++ BUG_ON(!(lock->flags & WAKE_LOCK_INITIALIZED)); ++#ifdef CONFIG_ANDROID_WAKELOCK_STAT ++ if (type == WAKE_LOCK_SUSPEND && wait_for_wakeup) { ++ if (debug_mask & DEBUG_WAKEUP) ++ pr_info("wakeup wake lock: %s\n", lock->name); ++ wait_for_wakeup = 0; ++ lock->stat.wakeup_count++; ++ } ++ if ((lock->flags & WAKE_LOCK_AUTO_EXPIRE) && ++ (long)(lock->expires - jiffies) <= 0) { ++ wake_unlock_stat_locked(lock, 0); ++ lock->stat.last_time = ktime_get(); ++ } ++#endif ++ if (!(lock->flags & WAKE_LOCK_ACTIVE)) { ++ lock->flags |= WAKE_LOCK_ACTIVE; ++#ifdef CONFIG_ANDROID_WAKELOCK_STAT ++ lock->stat.last_time = ktime_get(); ++#endif ++ } ++ list_del(&lock->link); ++ if (has_timeout) { ++ if (debug_mask & DEBUG_WAKE_LOCK) ++ pr_info("wake_lock: %s, type %d, timeout %ld.%03lu\n", ++ lock->name, type, timeout / HZ, ++ (timeout % HZ) * MSEC_PER_SEC / HZ); ++ lock->expires = jiffies + timeout; ++ lock->flags |= WAKE_LOCK_AUTO_EXPIRE; ++ list_add_tail(&lock->link, &active_wake_locks[type]); ++ } else { ++ if (debug_mask & DEBUG_WAKE_LOCK) ++ pr_info("wake_lock: %s, type %d\n", lock->name, type); ++ lock->expires = LONG_MAX; ++ lock->flags &= ~WAKE_LOCK_AUTO_EXPIRE; ++ list_add(&lock->link, &active_wake_locks[type]); ++ } ++ if (type == WAKE_LOCK_SUSPEND) { ++ current_event_num++; ++#ifdef CONFIG_ANDROID_WAKELOCK_STAT ++ if (lock == &main_wake_lock) ++ update_sleep_wait_stats_locked(1); ++ else if (!wake_lock_active(&main_wake_lock)) ++ update_sleep_wait_stats_locked(0); ++#endif ++ if (has_timeout) ++ expire_in = has_wake_lock_locked(type); ++ else ++ expire_in = -1; ++ if (expire_in > 0) { ++ if (debug_mask & DEBUG_EXPIRE) ++ pr_info("wake_lock: %s, start expire timer, " ++ "%ld\n", lock->name, expire_in); ++ mod_timer(&expire_timer, jiffies + expire_in); ++ } else { ++ if (del_timer(&expire_timer)) ++ if (debug_mask & DEBUG_EXPIRE) ++ pr_info("wake_lock: %s, stop expire timer\n", ++ lock->name); ++ if (expire_in == 0) ++ queue_work(suspend_work_queue, &suspend_work); ++ } ++ } ++ spin_unlock_irqrestore(&list_lock, irqflags); ++} ++ ++void wake_lock(struct wake_lock *lock) ++{ ++ wake_lock_internal(lock, 0, 0); ++} ++EXPORT_SYMBOL(wake_lock); ++ ++void wake_lock_timeout(struct wake_lock *lock, long timeout) ++{ ++ wake_lock_internal(lock, timeout, 1); ++} ++EXPORT_SYMBOL(wake_lock_timeout); ++ ++void wake_unlock(struct wake_lock *lock) ++{ ++ int type; ++ unsigned long irqflags; ++ spin_lock_irqsave(&list_lock, irqflags); ++ type = lock->flags & WAKE_LOCK_TYPE_MASK; ++#ifdef CONFIG_ANDROID_WAKELOCK_STAT ++ wake_unlock_stat_locked(lock, 0); ++#endif ++ if (debug_mask & DEBUG_WAKE_LOCK) ++ pr_info("wake_unlock: %s\n", lock->name); ++ lock->flags &= ~(WAKE_LOCK_ACTIVE | WAKE_LOCK_AUTO_EXPIRE); ++ list_del(&lock->link); ++ list_add(&lock->link, &inactive_locks); ++ if (type == WAKE_LOCK_SUSPEND) { ++ long has_lock = has_wake_lock_locked(type); ++ if (has_lock > 0) { ++ if (debug_mask & DEBUG_EXPIRE) ++ pr_info("wake_unlock: %s, start expire timer, " ++ "%ld\n", lock->name, has_lock); ++ mod_timer(&expire_timer, jiffies + has_lock); ++ } else { ++ if (del_timer(&expire_timer)) ++ if (debug_mask & DEBUG_EXPIRE) ++ pr_info("wake_unlock: %s, stop expire " ++ "timer\n", lock->name); ++ if (has_lock == 0) ++ queue_work(suspend_work_queue, &suspend_work); ++ } ++ if (lock == &main_wake_lock) { ++ if (debug_mask & DEBUG_SUSPEND) ++ print_active_locks(WAKE_LOCK_SUSPEND); ++#ifdef CONFIG_ANDROID_WAKELOCK_STAT ++ update_sleep_wait_stats_locked(0); ++#endif ++ } ++ } ++ spin_unlock_irqrestore(&list_lock, irqflags); ++} ++EXPORT_SYMBOL(wake_unlock); ++ ++int wake_lock_active(struct wake_lock *lock) ++{ ++ return !!(lock->flags & WAKE_LOCK_ACTIVE); ++} ++EXPORT_SYMBOL(wake_lock_active); ++ ++static int __init wakelocks_init(void) ++{ ++ int ret; ++ int i; ++ ++ for (i = 0; i < ARRAY_SIZE(active_wake_locks); i++) ++ INIT_LIST_HEAD(&active_wake_locks[i]); ++ ++#ifdef CONFIG_ANDROID_WAKELOCK_STAT ++ wake_lock_init(&deleted_wake_locks, WAKE_LOCK_SUSPEND, ++ "deleted_wake_locks"); ++#endif ++ wake_lock_init(&main_wake_lock, WAKE_LOCK_SUSPEND, "main"); ++ wake_lock(&main_wake_lock); ++ wake_lock_init(&unknown_wakeup, WAKE_LOCK_SUSPEND, "unknown_wakeups"); ++ ++ ret = platform_device_register(&power_device); ++ if (ret) { ++ pr_err("wakelocks_init: platform_device_register failed\n"); ++ goto err_platform_device_register; ++ } ++ ret = platform_driver_register(&power_driver); ++ if (ret) { ++ pr_err("wakelocks_init: platform_driver_register failed\n"); ++ goto err_platform_driver_register; ++ } ++ ++ suspend_work_queue = create_singlethread_workqueue("suspend"); ++ if (suspend_work_queue == NULL) { ++ ret = -ENOMEM; ++ goto err_suspend_work_queue; ++ } ++ ++#ifdef CONFIG_ANDROID_WAKELOCK_STAT ++ create_proc_read_entry("wakelocks", S_IRUGO, NULL, ++ wakelocks_read_proc, NULL); ++#endif ++ ++ return 0; ++ ++err_suspend_work_queue: ++ platform_driver_unregister(&power_driver); ++err_platform_driver_register: ++ platform_device_unregister(&power_device); ++err_platform_device_register: ++ wake_lock_destroy(&unknown_wakeup); ++ wake_lock_destroy(&main_wake_lock); ++#ifdef CONFIG_ANDROID_WAKELOCK_STAT ++ wake_lock_destroy(&deleted_wake_locks); ++#endif ++ return ret; ++} ++ ++static void __exit wakelocks_exit(void) ++{ ++#ifdef CONFIG_ANDROID_WAKELOCK_STAT ++ remove_proc_entry("wakelocks", NULL); ++#endif ++ destroy_workqueue(suspend_work_queue); ++ platform_driver_unregister(&power_driver); ++ platform_device_unregister(&power_device); ++ wake_lock_destroy(&unknown_wakeup); ++ wake_lock_destroy(&main_wake_lock); ++#ifdef CONFIG_ANDROID_WAKELOCK_STAT ++ wake_lock_destroy(&deleted_wake_locks); ++#endif ++} ++ ++core_initcall(wakelocks_init); ++module_exit(wakelocks_exit); +diff -ruN --exclude='*.orig' --exclude='*.rej' linux-2.6.29-rc3.owrt/drivers/usb/gadget/composite.c linux-2.6.29-rc3.owrt.om/drivers/usb/gadget/composite.c +--- linux-2.6.29-rc3.owrt/drivers/usb/gadget/composite.c 2009-05-10 22:04:48.000000000 +0200 ++++ linux-2.6.29-rc3.owrt.om/drivers/usb/gadget/composite.c 2009-05-10 22:28:00.000000000 +0200 +@@ -1046,7 +1046,11 @@ + /*-------------------------------------------------------------------------*/ + + static struct usb_gadget_driver composite_driver = { ++#ifdef CONFIG_USB_GADGET_DUALSPEED + .speed = USB_SPEED_HIGH, ++#else ++ .speed = USB_SPEED_FULL, ++#endif + + .bind = composite_bind, + .unbind = __exit_p(composite_unbind), +diff -ruN --exclude='*.orig' --exclude='*.rej' linux-2.6.29-rc3.owrt/drivers/usb/gadget/epautoconf.c linux-2.6.29-rc3.owrt.om/drivers/usb/gadget/epautoconf.c +--- linux-2.6.29-rc3.owrt/drivers/usb/gadget/epautoconf.c 2009-05-10 22:04:48.000000000 +0200 ++++ linux-2.6.29-rc3.owrt.om/drivers/usb/gadget/epautoconf.c 2009-05-10 22:28:00.000000000 +0200 +@@ -275,6 +275,18 @@ + ep = find_ep (gadget, "ep1-bulk"); + if (ep && ep_matches (gadget, ep, desc)) + return ep; ++ } else if (gadget_is_s3c64xx(gadget)) { ++ if (USB_ENDPOINT_XFER_INT == type) { ++ /* single buffering is enough */ ++ ep = find_ep(gadget, "ep3-int"); ++ if (ep && ep_matches(gadget, ep, desc)) ++ return ep; ++ } else if (USB_ENDPOINT_XFER_BULK == type ++ && (USB_DIR_IN & desc->bEndpointAddress)) { ++ ep = find_ep(gadget, "ep2-bulk"); ++ if (ep && ep_matches(gadget, ep, desc)) ++ return ep; ++ } + } + + /* Second, look at endpoints until an unclaimed one looks usable */ +diff -ruN --exclude='*.orig' --exclude='*.rej' linux-2.6.29-rc3.owrt/drivers/usb/gadget/ether.c linux-2.6.29-rc3.owrt.om/drivers/usb/gadget/ether.c +--- linux-2.6.29-rc3.owrt/drivers/usb/gadget/ether.c 2009-05-10 22:04:48.000000000 +0200 ++++ linux-2.6.29-rc3.owrt.om/drivers/usb/gadget/ether.c 2009-05-10 22:28:00.000000000 +0200 +@@ -122,11 +122,16 @@ + * Instead: allocate your own, using normal USB-IF procedures. + */ + ++#if 0 + /* Thanks to NetChip Technologies for donating this product ID. + * It's for devices with only CDC Ethernet configurations. + */ + #define CDC_VENDOR_NUM 0x0525 /* NetChip */ + #define CDC_PRODUCT_NUM 0xa4a1 /* Linux-USB Ethernet Gadget */ ++#else ++#define CDC_VENDOR_NUM 0x1457 /* First International Computer */ ++#define CDC_PRODUCT_NUM 0x5117 /* Linux-USB Ethernet Gadget */ ++#endif + + /* For hardware that can't talk CDC, we use the same vendor ID that + * ARM Linux has used for ethernet-over-usb, both with sa1100 and +@@ -147,8 +152,8 @@ + * used with CDC Ethernet, Linux 2.4 hosts will need updates to choose + * the non-RNDIS configuration. + */ +-#define RNDIS_VENDOR_NUM 0x0525 /* NetChip */ +-#define RNDIS_PRODUCT_NUM 0xa4a2 /* Ethernet/RNDIS Gadget */ ++#define RNDIS_VENDOR_NUM 0x1457 /* NetChip */ ++#define RNDIS_PRODUCT_NUM 0x5122 /* Ethernet/RNDIS Gadget */ + + /*-------------------------------------------------------------------------*/ + +diff -ruN --exclude='*.orig' --exclude='*.rej' linux-2.6.29-rc3.owrt/drivers/usb/gadget/f_rndis.c linux-2.6.29-rc3.owrt.om/drivers/usb/gadget/f_rndis.c +--- linux-2.6.29-rc3.owrt/drivers/usb/gadget/f_rndis.c 2009-05-10 22:04:48.000000000 +0200 ++++ linux-2.6.29-rc3.owrt.om/drivers/usb/gadget/f_rndis.c 2009-05-10 22:28:00.000000000 +0200 +@@ -437,7 +437,8 @@ + DBG(cdev, "rndis req%02x.%02x v%04x i%04x l%d\n", + ctrl->bRequestType, ctrl->bRequest, + w_value, w_index, w_length); +- req->zero = 0; ++ req->zero = value < w_length ++ && (value % cdev->gadget->ep0->maxpacket) == 0; + req->length = value; + value = usb_ep_queue(cdev->gadget->ep0, req, GFP_ATOMIC); + if (value < 0) +diff -ruN --exclude='*.orig' --exclude='*.rej' linux-2.6.29-rc3.owrt/drivers/usb/gadget/gadget_chips.h linux-2.6.29-rc3.owrt.om/drivers/usb/gadget/gadget_chips.h +--- linux-2.6.29-rc3.owrt/drivers/usb/gadget/gadget_chips.h 2009-05-10 22:04:48.000000000 +0200 ++++ linux-2.6.29-rc3.owrt.om/drivers/usb/gadget/gadget_chips.h 2009-05-10 22:28:00.000000000 +0200 +@@ -104,6 +104,12 @@ + #define gadget_is_s3c2410(g) 0 + #endif + ++#ifdef CONFIG_USB_GADGET_S3C_OTGD_HS ++#define gadget_is_s3c64xx(g) !strcmp("s3c-otg-device", (g)->name) ++#else ++#define gadget_is_s3c64xx(g) 0 ++#endif ++ + #ifdef CONFIG_USB_GADGET_AT91 + #define gadget_is_at91(g) !strcmp("at91_udc", (g)->name) + #else +@@ -231,6 +237,8 @@ + return 0x22; + else if (gadget_is_ci13xxx(gadget)) + return 0x23; ++ else if (gadget_is_s3c64xx(gadget)) ++ return 0x24; + return -ENOENT; + } + +diff -ruN --exclude='*.orig' --exclude='*.rej' linux-2.6.29-rc3.owrt/drivers/usb/gadget/Kconfig linux-2.6.29-rc3.owrt.om/drivers/usb/gadget/Kconfig +--- linux-2.6.29-rc3.owrt/drivers/usb/gadget/Kconfig 2009-05-10 22:08:45.000000000 +0200 ++++ linux-2.6.29-rc3.owrt.om/drivers/usb/gadget/Kconfig 2009-05-10 22:28:00.000000000 +0200 +@@ -291,6 +291,22 @@ + boolean "S3C2410 udc debug messages" + depends on USB_GADGET_S3C2410 + ++config USB_GADGET_S3C_OTGD_HS ++ boolean "S3C high speed(2.0, dual-speed) USB OTG device" ++ depends on (CPU_S3C6400 || CPU_S3C6410) ++ select USB_GADGET_SELECTED ++ select USB_GADGET_DUALSPEED ++ help ++ Say "y" to link the driver statically, or "m" to build a ++ dynamically linked module called "s3c_udc_hs" and force all ++ gadget drivers to also be dynamically linked. ++ ++config USB_S3C ++ tristate ++ depends on USB_GADGET_S3C_FS && USB_GADGET_S3C_HS && USB_GADGET_S3C_OTGD_HS ++ default USB_GADGET ++ select USB_GADGET_SELECTED ++ + # + # Controllers available in both integrated and discrete versions + # +diff -ruN --exclude='*.orig' --exclude='*.rej' linux-2.6.29-rc3.owrt/drivers/usb/gadget/Makefile linux-2.6.29-rc3.owrt.om/drivers/usb/gadget/Makefile +--- linux-2.6.29-rc3.owrt/drivers/usb/gadget/Makefile 2009-05-10 22:04:48.000000000 +0200 ++++ linux-2.6.29-rc3.owrt.om/drivers/usb/gadget/Makefile 2009-05-10 22:28:00.000000000 +0200 +@@ -19,6 +19,7 @@ + obj-$(CONFIG_USB_ATMEL_USBA) += atmel_usba_udc.o + obj-$(CONFIG_USB_FSL_USB2) += fsl_usb2_udc.o + obj-$(CONFIG_USB_M66592) += m66592-udc.o ++obj-$(CONFIG_USB_GADGET_S3C_OTGD_HS) += s3c_hs_otg.o + obj-$(CONFIG_USB_FSL_QE) += fsl_qe_udc.o + obj-$(CONFIG_USB_CI13XXX) += ci13xxx_udc.o + +diff -ruN --exclude='*.orig' --exclude='*.rej' linux-2.6.29-rc3.owrt/drivers/usb/gadget/s3c2410_udc.c linux-2.6.29-rc3.owrt.om/drivers/usb/gadget/s3c2410_udc.c +--- linux-2.6.29-rc3.owrt/drivers/usb/gadget/s3c2410_udc.c 2009-05-10 22:04:48.000000000 +0200 ++++ linux-2.6.29-rc3.owrt.om/drivers/usb/gadget/s3c2410_udc.c 2009-05-10 22:28:00.000000000 +0200 +@@ -134,6 +134,8 @@ + return 0; + } + #endif ++ ++#ifdef CONFIG_USB_GADGET_DEBUG_FS + static int s3c2410_udc_debugfs_seq_show(struct seq_file *m, void *p) + { + u32 addr_reg,pwr_reg,ep_int_reg,usb_int_reg; +@@ -197,6 +199,7 @@ + .release = single_release, + .owner = THIS_MODULE, + }; ++#endif + + /* io macros */ + +@@ -843,6 +846,7 @@ + u32 ep_csr1; + u32 idx; + ++handle_ep_again: + if (likely (!list_empty(&ep->queue))) + req = list_entry(ep->queue.next, + struct s3c2410_request, queue); +@@ -882,6 +886,8 @@ + + if ((ep_csr1 & S3C2410_UDC_OCSR1_PKTRDY) && req) { + s3c2410_udc_read_fifo(ep,req); ++ if (s3c2410_udc_fifo_count_out()) ++ goto handle_ep_again; + } + } + } +@@ -1707,6 +1713,7 @@ + if (driver->disconnect) + driver->disconnect(&udc->gadget); + ++ driver->unbind(&udc->gadget); + device_del(&udc->gadget.dev); + udc->driver = NULL; + +@@ -1897,6 +1904,7 @@ + udc->vbus = 1; + } + ++#ifdef CONFIG_USB_GADGET_DEBUG_FS + if (s3c2410_udc_debugfs_root) { + udc->regs_info = debugfs_create_file("registers", S_IRUGO, + s3c2410_udc_debugfs_root, +@@ -1904,6 +1912,7 @@ + if (!udc->regs_info) + dev_warn(dev, "debugfs file creation failed\n"); + } ++#endif + + dev_dbg(dev, "probe ok\n"); + +@@ -2013,12 +2022,14 @@ + + dprintk(DEBUG_NORMAL, "%s: version %s\n", gadget_name, DRIVER_VERSION); + ++#ifdef CONFIG_USB_GADGET_DEBUG_FS + s3c2410_udc_debugfs_root = debugfs_create_dir(gadget_name, NULL); + if (IS_ERR(s3c2410_udc_debugfs_root)) { + printk(KERN_ERR "%s: debugfs dir creation failed %ld\n", + gadget_name, PTR_ERR(s3c2410_udc_debugfs_root)); + s3c2410_udc_debugfs_root = NULL; + } ++#endif + + retval = platform_driver_register(&udc_driver_2410); + if (retval) +diff -ruN --exclude='*.orig' --exclude='*.rej' linux-2.6.29-rc3.owrt/drivers/usb/gadget/s3c_hs_otg.c linux-2.6.29-rc3.owrt.om/drivers/usb/gadget/s3c_hs_otg.c +--- linux-2.6.29-rc3.owrt/drivers/usb/gadget/s3c_hs_otg.c 1970-01-01 01:00:00.000000000 +0100 ++++ linux-2.6.29-rc3.owrt.om/drivers/usb/gadget/s3c_hs_otg.c 2009-05-10 22:28:00.000000000 +0200 +@@ -0,0 +1,1874 @@ ++/* ++ * drivers/usb/gadget/s3c_hs_otg.c ++ * Samsung S3C on-chip full/high speed USB OTG 2.0 device controllers ++ * ++ * Copyright (C) 2008 Samsung Electronics ++ * Minkyu Kang <mk7.kang@samsung.com> ++ * ++ * 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, MA 02111-1307 USA ++ * ++ */ ++ ++#include "s3c-udc.h" ++#include <linux/platform_device.h> ++#include <linux/clk.h> ++#include <mach/map.h> ++#include <plat/regs-clock.h> ++#include <plat/regs-usb-hs-otg.h> ++#include <plat/regs-sys.h> ++#include <plat/devs.h> ++ ++static char *state_names[] = { ++ "WAIT_FOR_SETUP", ++ "DATA_STATE_XMIT", ++ "DATA_STATE_NEED_ZLP", ++ "WAIT_FOR_OUT_STATUS", ++ "DATA_STATE_RECV" ++}; ++ ++#define S3C_USB_DBG_LEVEL 0 ++ ++#define DBG(level, fmt, args...) do { \ ++ if (level >= S3C_USB_DBG_LEVEL) { \ ++ printk(KERN_INFO "[%s] " fmt, \ ++ __func__, ##args); \ ++ } } while (0) ++ ++ ++#define DRIVER_DESC "Samsung Dual-speed USB 2.0 OTG Device Controller" ++#define DRIVER_AUTHOR "Samsung Electronics" ++#define DRIVER_VERSION "04 Dec 2008" ++ ++ ++struct s3c_udc *the_controller; ++ ++static const char driver_name[] = "s3c-otg-device"; ++static const char driver_desc[] = DRIVER_DESC; ++static const char ep0name[] = "ep0-control"; ++ ++static u32 tx_ep_num = 2; ++ ++static u32 ep0_fifo_size = EP0_FIFO_SIZE; ++static u32 ep_fifo_size = EP_FIFO_SIZE; ++static u32 ep_fifo_size2 = EP_FIFO_SIZE2; ++ ++struct usb_ctrlrequest ctrl; ++static int reset_available = 1; ++ ++#ifdef CONFIG_USB_GADGET_DEBUG_FILES ++ ++static const char proc_node_name[] = "driver/otg"; ++ ++static int ++udc_proc_read(char *page, char **start, off_t off, int count, ++ int *eof, void *_dev) ++{ ++ char *buf = page; ++ struct s3c_udc *dev = _dev; ++ char *next = buf; ++ unsigned size = count; ++ unsigned long flags; ++ int t; ++ ++ if (off != 0) ++ return 0; ++ ++ local_irq_save(flags); ++ ++ /* basic device status */ ++ t = scnprintf(next, size, ++ DRIVER_DESC "\n" ++ "%s version: %s\n" ++ "Gadget driver: %s\n" ++ "\n", ++ driver_name, DRIVER_VERSION, ++ dev->driver ? dev->driver->driver.name : "(none)"); ++ size -= t; ++ next += t; ++ ++ local_irq_restore(flags); ++ *eof = 1; ++ return count - size; ++} ++ ++#define create_proc_files() \ ++ create_proc_read_entry(proc_node_name, 0, NULL, udc_proc_read, dev) ++#define remove_proc_files() \ ++ remove_proc_entry(proc_node_name, NULL) ++ ++#else /* !CONFIG_USB_GADGET_DEBUG_FILES */ ++ ++#define create_proc_files() do {} while (0) ++#define remove_proc_files() do {} while (0) ++ ++#endif /* CONFIG_USB_GADGET_DEBUG_FILES */ ++ ++ ++static u32 s3c_otg_readl(struct s3c_udc *dev, u32 reg) ++{ ++ return __raw_readl((u32)dev->reg_base + reg); ++} ++ ++static void s3c_otg_writel(struct s3c_udc *dev, u32 val, u32 reg) ++{ ++ __raw_writel(val, ((u32)dev->reg_base) + reg); ++} ++ ++static void s3c_otg_orl(struct s3c_udc *dev, u32 val, u32 reg) ++{ ++ u32 temp = __raw_readl(((u32)dev->reg_base) + reg); ++ ++ __raw_writel(val|temp, ((u32)dev->reg_base) + reg); ++} ++ ++/* ++ * retire a request ++ */ ++static void s3c_otg_done(struct s3c_ep *ep, struct s3c_request *req, int status) ++{ ++ unsigned int stopped = ep->stopped; ++ ++ DBG(1, "%s %p, stopped = %d\n", ep->ep.name, ep, stopped); ++ list_del_init(&req->queue); ++ ++ if (req->req.status == -EINPROGRESS) ++ req->req.status = status; ++ else ++ status = req->req.status; ++ ++ if (status && (status != -ESHUTDOWN)) ++ DBG(2, "complete %s stat %d len %u/%u\n", ++ ep->ep.name, status, req->req.actual, req->req.length); ++ ++ /* don't modify queue heads during completion callback */ ++ ep->stopped = 1; ++ ++ spin_unlock(&ep->dev->lock); ++ req->req.complete(&ep->ep, &req->req); ++ spin_lock(&ep->dev->lock); ++ ++ ep->stopped = stopped; ++} ++ ++/* ++ * dequeue ALL requests ++ */ ++void s3c_otg_nuke(struct s3c_ep *ep, int status) ++{ ++ struct s3c_request *req; ++ ++ DBG(1, "%s %p\n", ep->ep.name, ep); ++ ++ /* called with irqs blocked */ ++ while (!list_empty(&ep->queue)) { ++ req = list_entry(ep->queue.next, struct s3c_request, queue); ++ s3c_otg_done(ep, req, status); ++ } ++} ++ ++static void s3c_otg_ep_control(int ep, int dir, u32 val, int update) ++{ ++ u32 epctrl; ++ ++ switch (ep) { ++ case 0: ++ if (dir) ++ epctrl = (u32)S3C_UDC_OTG_DIEPCTL0; ++ else ++ epctrl = (u32)S3C_UDC_OTG_DOEPCTL0; ++ break; ++ case 1: ++ if (dir) ++ epctrl = -EOPNOTSUPP; ++ else ++ epctrl = (u32)S3C_UDC_OTG_DOEPCTL1; ++ break; ++ case 2: ++ if (dir) ++ epctrl = (u32)S3C_UDC_OTG_DIEPCTL2; ++ else ++ epctrl = -EOPNOTSUPP; ++ break; ++ case 3: ++ if (dir) ++ epctrl = (u32)S3C_UDC_OTG_DIEPCTL3; ++ else ++ epctrl = -EOPNOTSUPP; ++ break; ++ default: ++ DBG(3, "ep%d is unused Endpoint", ep); ++ return; ++ } ++ ++ if (epctrl < 0) { ++ DBG(3, "ep%d - %s is invalid direction\n", ++ ep, dir ? "IN" : "OUT"); ++ return; ++ } ++ ++ if (update) ++ s3c_otg_orl(the_controller, val, epctrl); ++ else ++ s3c_otg_writel(the_controller, val, epctrl); ++} ++ ++static int s3c_otg_write_packet(struct s3c_ep *ep, ++ struct s3c_request *req, int max) ++{ ++ u32 *buf; ++ int length; ++ int count; ++ u32 fifo = ep->fifo; ++ u32 epsize; ++ ++ buf = req->req.buf + req->req.actual; ++ prefetch(buf); ++ ++ length = req->req.length - req->req.actual; ++ length = min(length, max); ++ req->req.actual += length; ++ ++ DBG(1, "%s: %d/%d, fifo=0x%x\n", ep->ep.name, length, max, fifo); ++ ++ switch (ep_index(ep)) { ++ case 0: ++ epsize = (u32)S3C_UDC_OTG_DIEPTSIZ0; ++ break; ++ case 2: ++ epsize = (u32)S3C_UDC_OTG_DIEPTSIZ2; ++ break; ++ case 3: ++ epsize = (u32)S3C_UDC_OTG_DIEPTSIZ3; ++ break; ++ default: ++ DBG(3, "ep%d is unused Endpoint", ep_index(ep)); ++ return 0; ++ } ++ ++ s3c_otg_writel(ep->dev, PKT_CNT(0x1)|XFERSIZE(length), epsize); ++ s3c_otg_ep_control(ep_index(ep), USB_DIR_IN, ++ DEPCTL_EPENA|DEPCTL_CNAK, 1); ++ ++ for (count = 0; count < length; count += 4) ++ s3c_otg_writel(ep->dev, *buf++, fifo); ++ ++ return length; ++} ++ ++static int s3c_otg_write_fifo_ep0(struct s3c_ep *ep, struct s3c_request *req) ++{ ++ u32 max; ++ unsigned count; ++ int is_last; ++ ++ max = ep_maxpacket(ep); ++ count = s3c_otg_write_packet(ep, req, max); ++ ++ /* last packet is usually short (or a zlp) */ ++ if (count != max) { ++ is_last = 1; ++ } else { ++ if ((req->req.length != req->req.actual) || req->req.zero) ++ is_last = 0; ++ else ++ is_last = 1; ++ } ++ ++ DBG(2, "wrote %s %d bytes%s %d left %p\n", ++ ep->ep.name, count, is_last ? "/L" : "", ++ req->req.length - req->req.actual, req); ++ ++ /* requests complete when all IN data is in the FIFO */ ++ return is_last; ++} ++ ++static int s3c_otg_read_fifo_ep0(struct s3c_ep *ep, struct s3c_request *req) ++{ ++ u32 csr; ++ u32 *buf; ++ unsigned bufferspace; ++ unsigned count; ++ unsigned is_short; ++ unsigned bytes; ++ u32 fifo = ep->fifo; ++ ++ csr = s3c_otg_readl(ep->dev, S3C_UDC_OTG_GRXSTSP); ++ bytes = BYTE_COUNT(csr); ++ ++ buf = req->req.buf + req->req.actual; ++ prefetchw(buf); ++ bufferspace = req->req.length - req->req.actual; ++ ++ /* read all bytes from this packet */ ++ if (EP_NUM(csr) == 0) { ++ count = bytes / 4 + (bytes % 4 ? 1 : 0); ++ req->req.actual += min(bytes, bufferspace); ++ } else { ++ count = 0; ++ bytes = 0; ++ } ++ ++ is_short = (bytes < ep->ep.maxpacket); ++ ++ DBG(2, "read %s %d bytes%s %d/%d\n", ++ ep->ep.name, bytes, is_short ? "/S" : "", ++ req->req.actual, req->req.length); ++ ++ while (count--) { ++ u32 byte = s3c_otg_readl(ep->dev, fifo); ++ ++ if (unlikely(bufferspace == 0)) { ++ /* this happens when the driver's buffer ++ * is smaller than what the host sent. ++ * discard the extra data. ++ */ ++ if (req->req.status != -EOVERFLOW) ++ DBG(3, "%s overflow %d\n", ep->ep.name, count); ++ req->req.status = -EOVERFLOW; ++ } else { ++ *buf++ = byte; ++ bufferspace -= 4; ++ } ++ } ++ ++ /* completion */ ++ if (is_short || req->req.actual == req->req.length) ++ return 1; ++ ++ return 0; ++} ++ ++static int s3c_otg_write_ep0(struct s3c_udc *dev) ++{ ++ struct s3c_request *req; ++ struct s3c_ep *ep = &dev->ep[0]; ++ int ret; ++ int need_zlp = 0; ++ ++ if (list_empty(&ep->queue)) ++ req = NULL; ++ else ++ req = list_entry(ep->queue.next, struct s3c_request, queue); ++ ++ if (!req) { ++ DBG(2, "NULL REQ\n"); ++ return 0; ++ } ++ ++ DBG(2, "length = 0x%x, actual = 0x%x\n", ++ req->req.length, req->req.actual); ++ ++ if (req->req.length == 0) { ++ dev->ep0state = WAIT_FOR_SETUP; ++ s3c_otg_done(ep, req, 0); ++ return 1; ++ } ++ ++ /* Next write will end with the packet size, */ ++ /* so we need Zero-length-packet */ ++ if (req->req.length - req->req.actual == ep0_fifo_size) ++ need_zlp = 1; ++ ++ ret = s3c_otg_write_fifo_ep0(ep, req); ++ ++ if ((ret == 1) && !need_zlp) { ++ /* Last packet */ ++ DBG(1, "finished, waiting for status\n"); ++ dev->ep0state = WAIT_FOR_SETUP; ++ } ++ ++ if (need_zlp) { ++ DBG(1, "Need ZLP!\n"); ++ dev->ep0state = DATA_STATE_NEED_ZLP; ++ } ++ ++ if (ret) ++ s3c_otg_done(ep, req, 0); ++ ++ return ret; ++} ++ ++static int first_time = 1; ++ ++static int s3c_otg_read_ep0(struct s3c_udc *dev) ++{ ++ struct s3c_request *req; ++ struct s3c_ep *ep = &dev->ep[0]; ++ int ret; ++ ++ if (!list_empty(&ep->queue)) ++ req = list_entry(ep->queue.next, struct s3c_request, queue); ++ else { ++ DBG(3, "---> BUG\n"); ++ BUG(); ++ return 0; ++ } ++ ++ DBG(2, "length = 0x%x, actual = 0x%x\n", ++ req->req.length, req->req.actual); ++ ++ if (req->req.length == 0) { ++ dev->ep0state = WAIT_FOR_SETUP; ++ first_time = 1; ++ s3c_otg_done(ep, req, 0); ++ return 1; ++ } ++ ++ if (!req->req.actual && first_time) { ++ first_time = 0; ++ return 1; ++ } ++ ++ ret = s3c_otg_read_fifo_ep0(ep, req); ++ ++ if (ret) ++ s3c_otg_done(ep, req, 0); ++ ++ dev->ep0state = WAIT_FOR_SETUP; ++ first_time = 1; ++ ++ return ret; ++} ++ ++static void s3c_otg_kick_ep0(struct s3c_udc *dev, struct s3c_ep *ep) ++{ ++ int res = 0; ++ ++ DBG(1, "ep_is_in = %d\n", ep_is_in(ep)); ++ ++ if (ep_is_in(ep)) { ++ dev->ep0state = DATA_STATE_XMIT; ++ while (!res) ++ res = s3c_otg_write_ep0(dev); ++ } else { ++ dev->ep0state = DATA_STATE_RECV; ++ s3c_otg_read_ep0(dev); ++ } ++} ++ ++/* ++ * Write request to FIFO ++ */ ++static int s3c_otg_write_fifo(struct s3c_ep *ep, struct s3c_request *req) ++{ ++ u32 max; ++ u32 gintmsk; ++ unsigned count; ++ int is_last = 0; ++ int is_short = 0; ++ ++ gintmsk = s3c_otg_readl(ep->dev, S3C_UDC_OTG_GINTMSK); ++ ++ max = le16_to_cpu(ep->desc->wMaxPacketSize); ++ count = s3c_otg_write_packet(ep, req, max); ++ ++ /* last packet is usually short (or a zlp) */ ++ if (count != max) { ++ is_last = 1; ++ is_short = 1; ++ } else { ++ if ((req->req.length != req->req.actual) || req->req.zero) ++ is_last = 0; ++ else ++ is_last = 1; ++ ++ /* interrupt/iso maxpacket may not fill the fifo */ ++ is_short = (max < ep_maxpacket(ep)); ++ } ++ ++ DBG(2, "wrote %s %d bytes%s%s %d/%d\n", ++ ep->ep.name, count, ++ is_last ? "/L" : "", is_short ? "/S" : "", ++ req->req.actual, req->req.length); ++ ++ /* requests complete when all IN data is in the FIFO */ ++ if (is_last) { ++ if (ep_index(ep) == 0) { ++ DBG(3, "--> EP0 must not come here!\n"); ++ BUG(); ++ } ++ ++ s3c_otg_writel(ep->dev, gintmsk & (~INT_TX_FIFO_EMPTY), ++ (u32)S3C_UDC_OTG_GINTMSK); ++ s3c_otg_done(ep, req, 0); ++ ++ return 1; ++ } ++ ++ s3c_otg_writel(ep->dev, gintmsk|INT_TX_FIFO_EMPTY, ++ (u32)S3C_UDC_OTG_GINTMSK); ++ ++ return 0; ++} ++ ++/* ++ * Read to request from FIFO (max read == bytes in fifo) ++ */ ++static int s3c_otg_read_fifo(struct s3c_ep *ep, struct s3c_request *req) ++{ ++ u32 csr; ++ u32 gintmsk; ++ u32 *buf; ++ unsigned bufferspace; ++ unsigned count; ++ unsigned is_short = 0; ++ unsigned bytes; ++ u32 fifo = ep->fifo; ++ ++ csr = s3c_otg_readl(ep->dev, S3C_UDC_OTG_GRXSTSP); ++ bytes = BYTE_COUNT(csr); ++ gintmsk = readl(S3C_UDC_OTG_GINTMSK); ++ ++ if (!bytes) { ++ DBG(2, "%d bytes\n", bytes); ++ s3c_otg_orl(ep->dev, INT_RX_FIFO_NOT_EMPTY, ++ (u32)S3C_UDC_OTG_GINTMSK); ++ return 0; ++ } ++ ++ buf = req->req.buf + req->req.actual; ++ prefetchw(buf); ++ bufferspace = req->req.length - req->req.actual; ++ ++ count = bytes / 4 + (bytes % 4 ? 1 : 0); ++ req->req.actual += min(bytes, bufferspace); ++ ++ is_short = (bytes < ep->ep.maxpacket); ++ ++ DBG(2, "read %s %d bytes%s %d/%d\n", ++ ep->ep.name, bytes, is_short ? "/S" : "", ++ req->req.actual, req->req.length); ++ ++ while (count--) { ++ u32 byte = s3c_otg_readl(ep->dev, fifo); ++ ++ if (unlikely(bufferspace == 0)) { ++ /* this happens when the driver's buffer ++ * is smaller than what the host sent. ++ * discard the extra data. ++ */ ++ if (req->req.status != -EOVERFLOW) ++ DBG(3, "%s overflow %d\n", ep->ep.name, count); ++ req->req.status = -EOVERFLOW; ++ } else { ++ *buf++ = byte; ++ bufferspace -= 4; ++ } ++ } ++ ++ s3c_otg_writel(ep->dev, gintmsk|INT_RX_FIFO_NOT_EMPTY, ++ (u32)S3C_UDC_OTG_GINTMSK); ++ ++ /* completion */ ++ if (is_short || req->req.actual == req->req.length) { ++ s3c_otg_done(ep, req, 0); ++ return 1; ++ } ++ ++ /* finished that packet. the next one may be waiting... */ ++ return 0; ++} ++ ++static struct usb_request *s3c_otg_alloc_request( ++ struct usb_ep *ep, gfp_t gfp_flags) ++{ ++ struct s3c_request *req; ++ ++ if (!ep) ++ return NULL; ++ ++ DBG(1, "%s %p\n", ep->name, ep); ++ ++ req = kzalloc(sizeof *req, gfp_flags); ++ if (!req) ++ return NULL; ++ ++ INIT_LIST_HEAD(&req->queue); ++ ++ return &req->req; ++} ++ ++static void s3c_otg_free_request(struct usb_ep *ep, struct usb_request *_req) ++{ ++ struct s3c_request *req; ++ ++ if (!ep) ++ return; ++ ++ DBG(1, "%s %p\n", ep->name, ep); ++ ++ if (!_req) ++ return; ++ ++ req = container_of(_req, struct s3c_request, req); ++ ++ WARN_ON(!list_empty(&req->queue)); ++ kfree(req); ++} ++ ++/* ++ * Queue one request ++ * Kickstart transfer if needed ++ */ ++static int s3c_otg_queue(struct usb_ep *_ep, ++ struct usb_request *_req, gfp_t gfp_flags) ++{ ++ struct s3c_request *req; ++ struct s3c_ep *ep; ++ struct s3c_udc *dev; ++ unsigned long flags; ++ u32 csr; ++ ++ req = container_of(_req, struct s3c_request, req); ++ if (!_req || !_req->complete || !_req->buf ++ || !list_empty(&req->queue)) { ++ DBG(3, "bad params\n"); ++ return -EINVAL; ++ } ++ ++ ep = container_of(_ep, struct s3c_ep, ep); ++ if (!_ep || (!ep->desc && ep->ep.name != ep0name)) { ++ DBG(3, "bad ep\n"); ++ return -EINVAL; ++ } ++ ++ dev = ep->dev; ++ if (!dev->driver || dev->gadget.speed == USB_SPEED_UNKNOWN) { ++ DBG(3, "bogus device state %p\n", dev->driver); ++ return -ESHUTDOWN; ++ } ++ ++ DBG(2, "%s queue req %p, len %d buf %p\n", ++ _ep->name, _req, _req->length, _req->buf); ++ ++ spin_lock_irqsave(&dev->lock, flags); ++ ++ _req->status = -EINPROGRESS; ++ _req->actual = 0; ++ ++ DBG(2, "ep=%d, Q empty=%d, stopped=%d\n", ++ ep_index(ep), list_empty(&ep->queue), ep->stopped); ++ ++ /* kickstart this i/o queue? */ ++ if (list_empty(&ep->queue) && !ep->stopped) { ++ if (ep_index(ep) == 0) { ++ list_add_tail(&req->queue, &ep->queue); ++ s3c_otg_kick_ep0(dev, ep); ++ req = NULL; ++ } else if (ep_is_in(ep)) { ++ csr = s3c_otg_readl(ep->dev, S3C_UDC_OTG_GINTSTS); ++ ++ if ((csr & INT_TX_FIFO_EMPTY) && ++ (s3c_otg_write_fifo(ep, req) == 1)) ++ req = NULL; ++ else ++ tx_ep_num = ep_index(ep); ++ } else { ++ csr = s3c_otg_readl(ep->dev, S3C_UDC_OTG_GINTSTS); ++ ++ if ((csr & INT_RX_FIFO_NOT_EMPTY) && ++ (s3c_otg_read_fifo(ep, req) == 1)) ++ req = NULL; ++ } ++ } ++ ++ /* pio or dma irq handler advances the queue. */ ++ if (req) ++ list_add_tail(&req->queue, &ep->queue); ++ ++ spin_unlock_irqrestore(&dev->lock, flags); ++ ++ return 0; ++} ++ ++/* ++ * dequeue JUST ONE request ++ */ ++static int s3c_otg_dequeue(struct usb_ep *_ep, struct usb_request *_req) ++{ ++ struct s3c_ep *ep; ++ struct s3c_request *req; ++ unsigned long flags; ++ ++ ep = container_of(_ep, struct s3c_ep, ep); ++ if (!_ep || ep->ep.name == ep0name) ++ return -EINVAL; ++ ++ spin_lock_irqsave(&ep->dev->lock, flags); ++ ++ /* make sure it's actually queued on this endpoint */ ++ list_for_each_entry(req, &ep->queue, queue) { ++ if (&req->req == _req) ++ break; ++ } ++ ++ if (&req->req != _req) { ++ spin_unlock_irqrestore(&ep->dev->lock, flags); ++ return -EINVAL; ++ } ++ ++ s3c_otg_done(ep, req, -ECONNRESET); ++ ++ spin_unlock_irqrestore(&ep->dev->lock, flags); ++ ++ return 0; ++} ++ ++static int s3c_otg_set_halt(struct usb_ep *_ep, int value) ++{ ++ return 0; ++} ++ ++static int s3c_otg_fifo_status(struct usb_ep *_ep) ++{ ++ int count = 0; ++ struct s3c_ep *ep; ++ ++ ep = container_of(_ep, struct s3c_ep, ep); ++ if (!_ep) { ++ DBG(3, "bad ep\n"); ++ return -ENODEV; ++ } ++ ++ /* LPD can't report unclaimed bytes from IN fifos */ ++ if (ep_is_in(ep)) ++ return -EOPNOTSUPP; ++ ++ return count; ++} ++ ++static void s3c_otg_fifo_flush(struct usb_ep *_ep) ++{ ++ struct s3c_ep *ep; ++ ++ ep = container_of(_ep, struct s3c_ep, ep); ++ if (unlikely(!_ep || (!ep->desc && ep->ep.name != ep0name))) { ++ DBG(3, "bad ep\n"); ++ return; ++ } ++} ++ ++static int s3c_otg_ep_enable(struct usb_ep *_ep, ++ const struct usb_endpoint_descriptor *desc) ++{ ++ struct s3c_ep *ep; ++ struct s3c_udc *dev; ++ unsigned long flags; ++ ++ ep = container_of(_ep, struct s3c_ep, ep); ++ if (!_ep || !desc || ep->desc || _ep->name == ep0name ++ || desc->bDescriptorType != USB_DT_ENDPOINT ++ || ep->bEndpointAddress != desc->bEndpointAddress ++ || ep_maxpacket(ep) < le16_to_cpu(desc->wMaxPacketSize)) { ++ DBG(3, "bad ep or descriptor\n"); ++ return -EINVAL; ++ } ++ ++ /* xfer types must match, except that interrupt ~= bulk */ ++ if (ep->bmAttributes != desc->bmAttributes ++ && ep->bmAttributes != USB_ENDPOINT_XFER_BULK ++ && desc->bmAttributes != USB_ENDPOINT_XFER_INT) { ++ DBG(3, "%s type mismatch\n", _ep->name); ++ return -EINVAL; ++ } ++ ++ /* hardware _could_ do smaller, but driver doesn't */ ++ if ((desc->bmAttributes == USB_ENDPOINT_XFER_BULK ++ && le16_to_cpu(desc->wMaxPacketSize) ++ != ep_maxpacket(ep)) ++ || !desc->wMaxPacketSize) { ++ DBG(3, "bad %s maxpacket\n", _ep->name); ++ return -ERANGE; ++ } ++ ++ dev = ep->dev; ++ if (!dev->driver || dev->gadget.speed == USB_SPEED_UNKNOWN) { ++ DBG(3, "bogus device state\n"); ++ return -ESHUTDOWN; ++ } ++ ++ spin_lock_irqsave(&ep->dev->lock, flags); ++ ++ ep->stopped = 0; ++ ep->desc = desc; ++ ep->pio_irqs = 0; ++ ep->ep.maxpacket = le16_to_cpu(desc->wMaxPacketSize); ++ ++ /* Reset halt state */ ++ s3c_otg_set_halt(_ep, 0); ++ ++ spin_unlock_irqrestore(&ep->dev->lock, flags); ++ ++ DBG(2, "enabled %s, stopped = %d, maxpacket = %d\n", ++ _ep->name, ep->stopped, ep->ep.maxpacket); ++ return 0; ++} ++ ++static int s3c_otg_ep_disable(struct usb_ep *_ep) ++{ ++ struct s3c_ep *ep; ++ unsigned long flags; ++ ++ ep = container_of(_ep, struct s3c_ep, ep); ++ if (!_ep || !ep->desc) { ++ DBG(3, "%s not enabled\n", _ep ? ep->ep.name : NULL); ++ return -EINVAL; ++ } ++ ++ spin_lock_irqsave(&ep->dev->lock, flags); ++ ++ /* Nuke all pending requests */ ++ s3c_otg_nuke(ep, -ESHUTDOWN); ++ ++ ep->desc = 0; ++ ep->stopped = 1; ++ ++ spin_unlock_irqrestore(&ep->dev->lock, flags); ++ ++ DBG(2, "disabled %s\n", _ep->name); ++ return 0; ++} ++ ++static struct usb_ep_ops s3c_ep_ops = { ++ .enable = s3c_otg_ep_enable, ++ .disable = s3c_otg_ep_disable, ++ ++ .alloc_request = s3c_otg_alloc_request, ++ .free_request = s3c_otg_free_request, ++ ++ .queue = s3c_otg_queue, ++ .dequeue = s3c_otg_dequeue, ++ ++ .set_halt = s3c_otg_set_halt, ++ .fifo_status = s3c_otg_fifo_status, ++ .fifo_flush = s3c_otg_fifo_flush, ++}; ++ ++void s3c_otg_set_ep(struct s3c_udc *dev, enum usb_device_speed speed) ++{ ++ u32 ep0_mps = DEPCTL0_MPS_64; ++ ++ if (speed == USB_SPEED_FULL) { ++ ep0_fifo_size = 8; ++ ep_fifo_size = 64; ++ ep_fifo_size2 = 64; ++ ++ ep0_mps = DEPCTL0_MPS_8; ++ } ++ ++ dev->gadget.speed = speed; ++ ++ dev->ep[0].ep.maxpacket = ep0_fifo_size; ++ dev->ep[1].ep.maxpacket = ep_fifo_size; ++ dev->ep[2].ep.maxpacket = ep_fifo_size; ++ dev->ep[3].ep.maxpacket = ep_fifo_size; ++ dev->ep[4].ep.maxpacket = ep_fifo_size; ++ dev->ep[5].ep.maxpacket = ep_fifo_size2; ++ dev->ep[6].ep.maxpacket = ep_fifo_size2; ++ dev->ep[7].ep.maxpacket = ep_fifo_size2; ++ dev->ep[8].ep.maxpacket = ep_fifo_size2; ++ ++ /* EP0 - Control */ ++ s3c_otg_ep_control(0, USB_DIR_OUT, ep0_mps, 1); ++ s3c_otg_ep_control(0, USB_DIR_IN, ep0_mps, 1); ++ ++ /* EP1 - Bulk Data OUT */ ++ s3c_otg_ep_control(1, USB_DIR_OUT, ep_fifo_size, 1); ++ ++ /* EP2 - Bulk Data IN */ ++ s3c_otg_ep_control(2, USB_DIR_IN, ep_fifo_size, 1); ++ ++ /* EP3 - INTR Data IN */ ++ s3c_otg_ep_control(3, USB_DIR_IN, ep_fifo_size, 1); ++ ++ DBG(2, "%s Speed Detection\n", ++ speed == USB_SPEED_HIGH ? "High" : "Full"); ++} ++ ++/* ++ * set the USB address for this device ++ * ++ * Called from control endpoint function ++ * after it decodes a set address setup packet. ++ */ ++static void s3c_otg_set_address(struct s3c_udc *dev, unsigned char addr) ++{ ++ s3c_otg_orl(dev, DEVICE_ADDR(addr), S3C_UDC_OTG_DCFG); ++ s3c_otg_ep_control(0, USB_DIR_IN, DEPCTL_EPENA|DEPCTL_CNAK, 1); ++ ++ DBG(2, "USB OTG 2.0 Device Address=%d\n", addr); ++ ++ dev->usb_address = addr; ++} ++ ++static inline int s3c_otg_read_setup(struct s3c_ep *ep, u32 *ctrl, int max) ++{ ++ int bytes; ++ int count; ++ u32 csr = s3c_otg_readl(ep->dev, S3C_UDC_OTG_GRXSTSP); ++ ++ bytes = BYTE_COUNT(csr); ++ ++ /* 32 bits interface */ ++ count = bytes / 4; ++ ++ while (count--) ++ *ctrl++ = s3c_otg_readl(ep->dev, S3C_UDC_OTG_EP0_FIFO); ++ ++ return bytes; ++} ++ ++static void s3c_otg_setup(struct s3c_udc *dev) ++{ ++ struct s3c_ep *ep = &dev->ep[0]; ++ int bytes; ++ int is_in; ++ int ret; ++ ++ /* Nuke all previous transfers */ ++ s3c_otg_nuke(ep, -EPROTO); ++ ++ /* read control req from fifo (8 bytes) */ ++ bytes = s3c_otg_read_setup(ep, (u32 *)&ctrl, 8); ++ ++ DBG(2, "SETUP REQ %02x %02x %04x %04x %d\n", ++ ctrl.bRequestType, ctrl.bRequest, ++ ctrl.wValue, ctrl.wIndex, ctrl.wLength); ++ ++ /* Set direction of EP0 */ ++ if (ctrl.bRequestType & USB_DIR_IN) { ++ ep->bEndpointAddress |= USB_DIR_IN; ++ is_in = 1; ++ } else { ++ ep->bEndpointAddress &= ~USB_DIR_IN; ++ is_in = 0; ++ } ++ ++ dev->req_pending = 1; ++ ++ /* Handle some SETUP packets ourselves */ ++ switch (ctrl.bRequest) { ++ case USB_REQ_SET_ADDRESS: ++ if (ctrl.bRequestType != (USB_TYPE_STANDARD|USB_RECIP_DEVICE)) ++ break; ++ ++ s3c_otg_set_address(dev, ctrl.wValue); ++ return; ++ ++ case USB_REQ_SET_INTERFACE: ++ DBG(2, "USB_REQ_SET_INTERFACE (%d)\n", ctrl.wValue); ++ /* FALLTHROUGH */ ++ ++ case USB_REQ_SET_CONFIGURATION: ++ DBG(2, "USB_REQ_SET_CONFIGURATION (%d)\n", ctrl.wValue); ++ ++ s3c_otg_ep_control(0, USB_DIR_IN, ++ DEPCTL_EPENA|DEPCTL_CNAK, 1); ++ s3c_otg_ep_control(1, USB_DIR_OUT, ++ DEPCTL_EPDIS|DEPCTL_CNAK| ++ DEPCTL_BULK_TYPE|DEPCTL_USBACTEP, 1); ++ s3c_otg_ep_control(2, USB_DIR_IN, ++ DEPCTL_BULK_TYPE|DEPCTL_USBACTEP, 1); ++ s3c_otg_ep_control(3, USB_DIR_IN, ++ DEPCTL_BULK_TYPE|DEPCTL_USBACTEP, 1); ++ ++ reset_available = 1; ++ dev->req_config = 1; ++ break; ++ ++ case USB_REQ_GET_DESCRIPTOR: ++ DBG(2, "USB_REQ_GET_DESCRIPTOR\n"); ++ break; ++ ++ case USB_REQ_GET_CONFIGURATION: ++ DBG(2, "USB_REQ_GET_CONFIGURATION\n"); ++ break; ++ ++ case USB_REQ_GET_STATUS: ++ DBG(2, "USB_REQ_GET_STATUS\n"); ++ s3c_otg_ep_control(0, USB_DIR_IN, DEPCTL_EPENA|DEPCTL_CNAK, 1); ++ break; ++ ++ case USB_REQ_CLEAR_FEATURE: ++ DBG(2, "USB_REQ_CLEAR_FEATURE\n"); ++ break; ++ ++ case USB_REQ_SET_FEATURE: ++ DBG(2, "USB_REQ_SET_FEATURE\n"); ++ break; ++ ++ default: ++ DBG(3, "Default of ctrl.bRequest=0x%x\n", ctrl.bRequest); ++ break; ++ } ++ ++ if (dev->driver) { ++ /* device-2-host (IN) or no data setup command, ++ * process immediately */ ++ spin_unlock(&dev->lock); ++ ++ DBG(1, "usb_ctrlrequest will be passed to fsg_setup()\n"); ++ ++ ret = dev->driver->setup(&dev->gadget, &ctrl); ++ spin_lock(&dev->lock); ++ ++ if (ret < 0) { ++ /* setup processing failed, force stall */ ++ DBG(3, "gadget setup FAILED (stalling) - %d\n", ret); ++ dev->ep0state = WAIT_FOR_SETUP; ++ } ++ } ++} ++ ++/* ++ * handle ep0 interrupt ++ */ ++static void s3c_otg_handle_ep0(struct s3c_udc *dev) ++{ ++ if (dev->ep0state == WAIT_FOR_SETUP) ++ s3c_otg_setup(dev); ++ else ++ DBG(3, "strange state!! - %s\n", state_names[dev->ep0state]); ++} ++ ++static void s3c_otg_handle_ep_out(struct s3c_udc *dev, u32 ep_num) ++{ ++ struct s3c_ep *ep = &dev->ep[ep_num]; ++ struct s3c_request *req; ++ ++ if (unlikely(!(ep->desc))) { ++ /* Throw packet away.. */ ++ DBG(3, "No descriptor?!?\n"); ++ return; ++ } ++ ++ if (list_empty(&ep->queue)) ++ req = 0; ++ else ++ req = list_entry(ep->queue.next, struct s3c_request, queue); ++ ++ if (unlikely(!req)) ++ DBG(2, "NULL REQ on OUT EP-%d\n", ep_num); ++ else ++ s3c_otg_read_fifo(ep, req); ++} ++ ++static void s3c_otg_handle_ep_in(struct s3c_udc *dev, u32 ep_num) ++{ ++ struct s3c_ep *ep = &dev->ep[ep_num]; ++ struct s3c_request *req; ++ ++ if (list_empty(&ep->queue)) ++ req = 0; ++ else ++ req = list_entry(ep->queue.next, struct s3c_request, queue); ++ ++ if (unlikely(!req)) { ++ DBG(2, "NULL REQ on IN EP-%d\n", ep_num); ++ return; ++ } else ++ s3c_otg_write_fifo(ep, req); ++} ++ ++static void s3c_otg_handle_ep(struct s3c_udc *dev, u32 gintmsk) ++{ ++ u32 csr; ++ u32 packet_status; ++ u32 ep_num; ++ u32 bytes = 0; ++ ++ gintmsk &= ~INT_RX_FIFO_NOT_EMPTY; ++ s3c_otg_writel(dev, gintmsk, S3C_UDC_OTG_GINTMSK); ++ ++ csr = s3c_otg_readl(dev, S3C_UDC_OTG_GRXSTSR); ++ ++ packet_status = PKT_STS(csr); ++ bytes = BYTE_COUNT(csr); ++ ep_num = EP_NUM(csr); ++ ++ switch (packet_status) { ++ case SETUP_PKT_RECEIVED: ++ DBG(2, "SETUP received : %d bytes\n", bytes); ++ if (!bytes) ++ break; ++ ++ s3c_otg_handle_ep0(dev); ++ gintmsk |= INT_RX_FIFO_NOT_EMPTY; ++ break; ++ ++ case OUT_PKT_RECEIVED: ++ if (!bytes) ++ break; ++ ++ if (ep_num == 0) { ++ DBG(2, "CONTROL OUT received : %d bytes\n", bytes); ++ ++ dev->ep0state = DATA_STATE_RECV; ++ s3c_otg_read_ep0(dev); ++ ++ gintmsk |= INT_RX_FIFO_NOT_EMPTY; ++ } else if (ep_num == 1) { ++ DBG(2, " Bulk OUT received : %d bytes\n", bytes); ++ ++ s3c_otg_handle_ep_out(dev, 1); ++ gintmsk = s3c_otg_readl(dev,S3C_UDC_OTG_GINTMSK); ++ ++ s3c_otg_ep_control(1, USB_DIR_OUT, DEPCTL_CNAK, 1); ++ } else ++ DBG(2, "Unused EP%d: %d bytes\n", ep_num, bytes); ++ break; ++ ++ case SETUP_COMPLETED: ++ DBG(2, "SETUP_COMPLETED\n"); ++ s3c_otg_ep_control(0, USB_DIR_OUT, DEPCTL_CNAK, 1); ++ break; ++ ++ case OUT_COMPLELTED: ++ DBG(2, "OUT_COMPLELTED - ep%d\n", ep_num); ++ s3c_otg_ep_control(ep_num, USB_DIR_OUT, DEPCTL_CNAK, 1); ++ break; ++ ++ default: ++ gintmsk |= INT_RX_FIFO_NOT_EMPTY; ++ s3c_otg_ep_control(0, USB_DIR_OUT, DEPCTL_CNAK, 1); ++ DBG(1, "reserved packet received : scr=0x%08X bytes\n", csr); ++ break; ++ } ++ ++ if (!bytes) { ++ csr = s3c_otg_readl(dev, S3C_UDC_OTG_GRXSTSP); ++ gintmsk |= INT_RX_FIFO_NOT_EMPTY; ++ } ++ ++ s3c_otg_writel(dev, gintmsk, S3C_UDC_OTG_GINTMSK); ++} ++ ++/* ++ * disable USB device controller ++ */ ++static void s3c_otg_disable(struct s3c_udc *dev) ++{ ++ s3c_otg_set_address(dev, 0); ++ ++ dev->ep0state = WAIT_FOR_SETUP; ++ dev->gadget.speed = USB_SPEED_UNKNOWN; ++ dev->usb_address = 0; ++ ++ s3c_otg_orl(dev, ANALOG_PWR_DOWN, S3C_USBOTG_PHYPWR); ++} ++ ++/* ++ * initialize software state ++ */ ++static void s3c_otg_reinit(struct s3c_udc *dev) ++{ ++ u32 i; ++ ++ /* device/ep0 records init */ ++ INIT_LIST_HEAD(&dev->gadget.ep_list); ++ INIT_LIST_HEAD(&dev->gadget.ep0->ep_list); ++ dev->ep0state = WAIT_FOR_SETUP; ++ ++ /* basic endpoint records init */ ++ for (i = 0; i < S3C_MAX_ENDPOINTS; i++) { ++ struct s3c_ep *ep = &dev->ep[i]; ++ ++ if (i != 0) ++ list_add_tail(&ep->ep.ep_list, &dev->gadget.ep_list); ++ ++ ep->desc = 0; ++ ep->stopped = 0; ++ INIT_LIST_HEAD(&ep->queue); ++ ep->pio_irqs = 0; ++ } ++} ++ ++#define GUSBCFG_INIT (PHY_CLK_480M|TXFIFO_RE_EN| \ ++ TURN_AROUND|HNP_DISABLE|SRP_DISABLE|ULPI_DDR| \ ++ HS_UTMI|INTERF_UTMI|PHY_INTERF_16|TIME_OUT_CAL) ++ ++#define GINTMSK_INIT (INT_RESUME|INT_ENUMDONE| \ ++ INT_RESET|INT_SUSPEND|INT_RX_FIFO_NOT_EMPTY) ++ ++#define DOEPMSK_INIT (AHB_ERROR) ++ ++#define DIEPMSK_INIT (IN_EP_TIMEOUT|AHB_ERROR) ++ ++#define GAHBCFG_INIT (PTXFE_HALF|NPTXFE_HALF| \ ++ MODE_SLAVE|BURST_INCR16|GBL_INT_UNMASK) ++ ++static void s3c_otg_config(struct s3c_udc *dev) ++{ ++ u32 reg; ++ ++ /* OTG USB configuration */ ++ s3c_otg_writel(dev, GUSBCFG_INIT, S3C_UDC_OTG_GUSBCFG); ++ ++ /* Soft-reset OTG Core and then unreset again */ ++ s3c_otg_writel(dev, CORE_SOFT_RESET, S3C_UDC_OTG_GRSTCTL); ++ ++ /* Put the OTG device core in the disconnected state */ ++ s3c_otg_orl(dev, SOFT_DISCONNECT, S3C_UDC_OTG_DCTL); ++ ++ udelay(20); ++ ++ /* Make the OTG device core exit from the disconnected state */ ++ reg = s3c_otg_readl(dev, S3C_UDC_OTG_DCTL); ++ s3c_otg_writel(dev, reg & ~SOFT_DISCONNECT, S3C_UDC_OTG_DCTL); ++ ++ /* Configure OTG Core to initial settings of device mode */ ++ s3c_otg_orl(dev, EP_MIS_CNT(0x1)|SPEED_2_HIGH, S3C_UDC_OTG_DCFG); ++ ++ udelay(1000); ++ ++ /* Unmask the core interrupts */ ++ s3c_otg_writel(dev, GINTMSK_INIT, S3C_UDC_OTG_GINTMSK); ++ ++ /* Set NAK bit of EP0, EP1, EP2 */ ++ s3c_otg_ep_control(0, USB_DIR_OUT, ++ DEPCTL_EPDIS|DEPCTL_SNAK|DEPCTL0_MPS_64, 0); ++ s3c_otg_ep_control(0, USB_DIR_IN, ++ DEPCTL_EPDIS|DEPCTL_SNAK|DEPCTL0_MPS_64, 0); ++ s3c_otg_ep_control(1, USB_DIR_OUT, ++ DEPCTL_EPDIS|DEPCTL_SNAK|DEPCTL_BULK_TYPE, 0); ++ s3c_otg_ep_control(2, USB_DIR_IN, ++ DEPCTL_EPDIS|DEPCTL_SNAK|DEPCTL_BULK_TYPE, 0); ++ s3c_otg_ep_control(3, USB_DIR_IN, ++ DEPCTL_EPDIS|DEPCTL_SNAK|DEPCTL_BULK_TYPE, 0); ++ ++ /* Unmask EP interrupts */ ++ s3c_otg_writel(dev, S3C_UDC_INT_IN_EP0 ++ |S3C_UDC_INT_IN_EP2 ++ |S3C_UDC_INT_IN_EP3 ++ |S3C_UDC_INT_OUT_EP0 ++ |S3C_UDC_INT_OUT_EP1, ++ S3C_UDC_OTG_DAINTMSK); ++ ++ /* Unmask device OUT EP common interrupts */ ++ s3c_otg_writel(dev, DOEPMSK_INIT, S3C_UDC_OTG_DOEPMSK); ++ ++ /* Unmask device IN EP common interrupts */ ++ s3c_otg_writel(dev, DIEPMSK_INIT, S3C_UDC_OTG_DIEPMSK); ++ ++ /* Set Rx FIFO Size */ ++ s3c_otg_writel(dev, RX_FIFO_SIZE, S3C_UDC_OTG_GRXFSIZ); ++ ++ /* Set Non Periodic Tx FIFO Size */ ++ s3c_otg_writel(dev, NPTX_FIFO_SIZE|NPTX_FIFO_START_ADDR, ++ (u32)S3C_UDC_OTG_GNPTXFSIZ); ++ ++ /* Clear NAK bit of EP0 For Slave mode */ ++ s3c_otg_ep_control(0, USB_DIR_OUT, DEPCTL_EPDIS|DEPCTL_CNAK, 0); ++ ++ /* Initialize OTG Link Core */ ++ s3c_otg_writel(dev, GAHBCFG_INIT, S3C_UDC_OTG_GAHBCFG); ++} ++ ++static int s3c_otg_enable(struct s3c_udc *dev) ++{ ++ /* USB_SIG_MASK */ ++ __raw_writel(S3C64XX_OTHERS_USBMASK | __raw_readl(S3C64XX_OTHERS), ++ S3C64XX_OTHERS); ++ ++ /* Initializes OTG Phy. */ ++ s3c_otg_writel(dev, SUSPEND_DISABLE, S3C_USBOTG_PHYPWR); ++ ++ s3c_otg_writel(dev, dev->phyclk, S3C_USBOTG_PHYCLK); ++ ++ s3c_otg_writel(dev, SW_RST_ON, S3C_USBOTG_RSTCON); ++ udelay(50); ++ ++ s3c_otg_writel(dev, SW_RST_OFF, S3C_USBOTG_RSTCON); ++ udelay(50); ++ ++ s3c_otg_config(dev); ++ ++ DBG(2, "S3C USB 2.0 OTG Controller Core Initialized\n"); ++ ++ dev->gadget.speed = USB_SPEED_UNKNOWN; ++ ++ return 0; ++} ++ ++/* ++ * usb client interrupt handler. ++ */ ++static irqreturn_t s3c_otg_irq(int irq, void *_dev) ++{ ++ struct s3c_udc *dev = _dev; ++ u32 intr_status; ++ u32 usb_status; ++ u32 gintmsk; ++ ++ spin_lock(&dev->lock); ++ ++ intr_status = s3c_otg_readl(dev, S3C_UDC_OTG_GINTSTS); ++ gintmsk = s3c_otg_readl(dev, S3C_UDC_OTG_GINTMSK); ++ ++ DBG(1, "GINTSTS=0x%x(on state %s), GINTMSK : 0x%x\n", ++ intr_status, state_names[dev->ep0state], gintmsk); ++ ++ if (!intr_status) { ++ spin_unlock(&dev->lock); ++ return IRQ_HANDLED; ++ } ++ ++ if (intr_status & INT_ENUMDONE) { ++ DBG(2, "Speed Detection interrupt\n"); ++ s3c_otg_writel(dev, INT_ENUMDONE, S3C_UDC_OTG_GINTSTS); ++ ++ usb_status = ENUM_SPEED(s3c_otg_readl(dev, S3C_UDC_OTG_DSTS)); ++ ++ if (usb_status & (USB_FULL_30_60MHZ | USB_FULL_48MHZ)) ++ s3c_otg_set_ep(dev, USB_SPEED_FULL); ++ else ++ s3c_otg_set_ep(dev, USB_SPEED_HIGH); ++ } ++ ++ if (intr_status & INT_EARLY_SUSPEND) { ++ DBG(2, "Early suspend interrupt\n"); ++ s3c_otg_writel(dev, INT_EARLY_SUSPEND, S3C_UDC_OTG_GINTSTS); ++ } ++ ++ if (intr_status & INT_SUSPEND) { ++ DBG(2, "Suspend interrupt\n"); ++ s3c_otg_writel(dev, INT_SUSPEND, S3C_UDC_OTG_GINTSTS); ++ ++ if (dev->gadget.speed != USB_SPEED_UNKNOWN ++ && dev->driver ++ && dev->driver->suspend) { ++ dev->driver->suspend(&dev->gadget); ++ } ++ } ++ ++ if (intr_status & INT_RESUME) { ++ DBG(2, "Resume interrupt\n"); ++ s3c_otg_writel(dev, INT_RESUME, S3C_UDC_OTG_GINTSTS); ++ ++ if (dev->gadget.speed != USB_SPEED_UNKNOWN ++ && dev->driver ++ && dev->driver->resume) { ++ dev->driver->resume(&dev->gadget); ++ } ++ } ++ ++ if (intr_status & INT_RESET) { ++ DBG(2, "Reset interrupt\n"); ++ s3c_otg_writel(dev, INT_RESET, S3C_UDC_OTG_GINTSTS); ++ ++ usb_status = s3c_otg_readl(dev, S3C_UDC_OTG_GOTGCTL); ++ ++ if (usb_status | (A_SESSION_VALID|B_SESSION_VALID)) { ++ if (reset_available) { ++ s3c_otg_config(dev); ++ dev->ep0state = WAIT_FOR_SETUP; ++ reset_available = 0; ++ } ++ } else { ++ reset_available = 1; ++ DBG(2, "RESET handling skipped\n"); ++ } ++ } ++ ++ if (intr_status & INT_RX_FIFO_NOT_EMPTY) { ++ s3c_otg_handle_ep(dev, gintmsk); ++ spin_unlock(&dev->lock); ++ ++ return IRQ_HANDLED; ++ } ++ ++ ++ if (intr_status & INT_TX_FIFO_EMPTY) { ++ DBG(2, "INT_TX_FIFO_EMPTY ep_num=%d\n", tx_ep_num); ++ s3c_otg_handle_ep_in(dev, tx_ep_num); ++ } ++ ++ spin_unlock(&dev->lock); ++ ++ return IRQ_HANDLED; ++} ++ ++static void s3c_otg_stop_activity(struct s3c_udc *dev, ++ struct usb_gadget_driver *driver) ++{ ++ int i; ++ ++ /* don't disconnect drivers more than once */ ++ if (dev->gadget.speed == USB_SPEED_UNKNOWN) ++ driver = 0; ++ dev->gadget.speed = USB_SPEED_UNKNOWN; ++ ++ /* prevent new request submissions, kill any outstanding requests */ ++ for (i = 0; i < S3C_MAX_ENDPOINTS; i++) { ++ struct s3c_ep *ep = &dev->ep[i]; ++ ep->stopped = 1; ++ s3c_otg_nuke(ep, -ESHUTDOWN); ++ } ++ ++ /* report disconnect; the driver is already quiesced */ ++ if (driver) { ++ spin_unlock(&dev->lock); ++ driver->disconnect(&dev->gadget); ++ spin_lock(&dev->lock); ++ } ++ ++ /* re-init driver-visible data structures */ ++ s3c_otg_reinit(dev); ++} ++ ++/* ++ * Register the gadget driver. Used by gadget drivers when ++ * registering themselves with the controller. ++ */ ++int usb_gadget_register_driver(struct usb_gadget_driver *driver) ++{ ++ struct s3c_udc *dev = the_controller; ++ int retval; ++ ++ if (!driver ++ || driver->speed != USB_SPEED_HIGH ++ || !driver->bind ++ || !driver->setup) ++ return -EINVAL; ++ ++ if (!dev) { ++ DBG(3, "No device\n"); ++ return -ENODEV; ++ } ++ ++ if (dev->driver) { ++ DBG(3, "Already bound to %s\n", driver->driver.name); ++ return -EBUSY; ++ } ++ ++ /* first hook up the driver ... */ ++ dev->driver = driver; ++ dev->gadget.dev.driver = &driver->driver; ++ retval = device_add(&dev->gadget.dev); ++ ++ if (retval) { /* TODO */ ++ DBG(3, "target device_add failed, error %d\n", retval); ++ return retval; ++ } ++ ++ retval = driver->bind(&dev->gadget); ++ if (retval) { ++ DBG(3, "%s: bind to driver %s --> error %d\n", ++ dev->gadget.name, driver->driver.name, retval); ++ device_del(&dev->gadget.dev); ++ ++ dev->driver = 0; ++ dev->gadget.dev.driver = 0; ++ return retval; ++ } ++ ++ dev_info(&dev->gadget.dev, "Registered gadget driver '%s'\n", ++ driver->driver.name); ++ s3c_otg_enable(dev); ++ ++ enable_irq(IRQ_OTG); ++ ++ return 0; ++} ++EXPORT_SYMBOL(usb_gadget_register_driver); ++ ++/* ++ Unregister entry point for the peripheral controller driver. ++*/ ++int usb_gadget_unregister_driver(struct usb_gadget_driver *driver) ++{ ++ struct s3c_udc *dev = the_controller; ++ unsigned long flags; ++ ++ if (!dev) ++ return -ENODEV; ++ ++ if (!driver || driver != dev->driver) ++ return -EINVAL; ++ ++ spin_lock_irqsave(&dev->lock, flags); ++ ++ dev->driver = 0; ++ s3c_otg_stop_activity(dev, driver); ++ ++ spin_unlock_irqrestore(&dev->lock, flags); ++ ++ if (driver->unbind) ++ driver->unbind(&dev->gadget); ++ ++ device_del(&dev->gadget.dev); ++ ++ disable_irq(IRQ_OTG); ++ ++ dev_info(&dev->gadget.dev, "Unregistered gadget driver '%s'\n", ++ driver->driver.name); ++ ++ s3c_otg_disable(dev); ++ ++ return 0; ++} ++EXPORT_SYMBOL(usb_gadget_unregister_driver); ++ ++/* ++ * device-scoped parts of the api to the usb controller hardware ++ */ ++static int s3c_otg_get_frame(struct usb_gadget *gadget) ++{ ++ u32 frame = s3c_otg_readl(the_controller, S3C_UDC_OTG_DSTS); ++ return FRAME_CNT(frame); ++} ++ ++static int s3c_otg_wakeup(struct usb_gadget *gadget) ++{ ++ return -EOPNOTSUPP; ++} ++ ++static int s3c_otg_set_selfpowered( ++ struct usb_gadget *gadget, int is_selfpowered) ++{ ++ return -EOPNOTSUPP; ++} ++ ++static int s3c_otg_pullup(struct usb_gadget *gadget, int is_on) ++{ ++ return -EOPNOTSUPP; ++} ++ ++static int s3c_otg_vbus_session(struct usb_gadget *gadget, int is_active) ++{ ++ return -EOPNOTSUPP; ++} ++ ++static int s3c_otg_vbus_draw(struct usb_gadget *gadget, unsigned mA) ++{ ++ return -EOPNOTSUPP; ++} ++ ++static const struct usb_gadget_ops s3c_udc_ops = { ++ .get_frame = s3c_otg_get_frame, ++ .wakeup = s3c_otg_wakeup, ++ .set_selfpowered = s3c_otg_set_selfpowered, ++ .vbus_session = s3c_otg_vbus_session, ++ .vbus_draw = s3c_otg_vbus_draw, ++ .pullup = s3c_otg_pullup, ++}; ++ ++static void nop_release(struct device *dev) ++{ ++ DBG(2, "%s\n", dev->bus_id); ++} ++ ++static struct s3c_udc memory = { ++ .usb_address = 0, ++ .gadget = { ++ .ops = &s3c_udc_ops, ++ .ep0 = &memory.ep[0].ep, ++ .name = driver_name, ++ .dev = { ++ .bus_id = "gadget", ++ .release = nop_release, ++ }, ++ }, ++ .ep[0] = { ++ .ep = { ++ .name = ep0name, ++ .ops = &s3c_ep_ops, ++ .maxpacket = EP0_FIFO_SIZE, ++ }, ++ .dev = &memory, ++ ++ .bEndpointAddress = 0, ++ .bmAttributes = 0, ++ ++ .ep_type = ep_control, ++ .fifo = (u32) S3C_UDC_OTG_EP0_FIFO, ++ }, ++ .ep[1] = { ++ .ep = { ++ .name = "ep1-bulk", ++ .ops = &s3c_ep_ops, ++ .maxpacket = EP_FIFO_SIZE, ++ }, ++ .dev = &memory, ++ ++ .bEndpointAddress = 1, ++ .bmAttributes = USB_ENDPOINT_XFER_BULK, ++ ++ .ep_type = ep_bulk_out, ++ .fifo = (u32) S3C_UDC_OTG_EP1_FIFO, ++ }, ++ .ep[2] = { ++ .ep = { ++ .name = "ep2-bulk", ++ .ops = &s3c_ep_ops, ++ .maxpacket = EP_FIFO_SIZE, ++ }, ++ .dev = &memory, ++ ++ .bEndpointAddress = USB_DIR_IN | 2, ++ .bmAttributes = USB_ENDPOINT_XFER_BULK, ++ ++ .ep_type = ep_bulk_in, ++ .fifo = (u32) S3C_UDC_OTG_EP2_FIFO, ++ }, ++ ++ .ep[3] = { ++ .ep = { ++ .name = "ep3-int", ++ .ops = &s3c_ep_ops, ++ .maxpacket = EP_FIFO_SIZE, ++ }, ++ .dev = &memory, ++ ++ .bEndpointAddress = USB_DIR_IN | 3, ++ .bmAttributes = USB_ENDPOINT_XFER_INT, ++ ++ .ep_type = ep_interrupt, ++ .fifo = (u32) S3C_UDC_OTG_EP3_FIFO, ++ }, ++ .ep[4] = { ++ .ep = { ++ .name = "ep4-int", ++ .ops = &s3c_ep_ops, ++ .maxpacket = EP_FIFO_SIZE, ++ }, ++ .dev = &memory, ++ ++ .bEndpointAddress = USB_DIR_IN | 4, ++ .bmAttributes = USB_ENDPOINT_XFER_INT, ++ ++ .ep_type = ep_interrupt, ++ .fifo = (u32) S3C_UDC_OTG_EP4_FIFO, ++ }, ++ .ep[5] = { ++ .ep = { ++ .name = "ep5-int", ++ .ops = &s3c_ep_ops, ++ .maxpacket = EP_FIFO_SIZE2, ++ }, ++ .dev = &memory, ++ ++ .bEndpointAddress = USB_DIR_IN | 5, ++ .bmAttributes = USB_ENDPOINT_XFER_INT, ++ ++ .ep_type = ep_interrupt, ++ .fifo = (u32) S3C_UDC_OTG_EP5_FIFO, ++ }, ++ .ep[6] = { ++ .ep = { ++ .name = "ep6-int", ++ .ops = &s3c_ep_ops, ++ .maxpacket = EP_FIFO_SIZE2, ++ }, ++ .dev = &memory, ++ ++ .bEndpointAddress = USB_DIR_IN | 6, ++ .bmAttributes = USB_ENDPOINT_XFER_INT, ++ ++ .ep_type = ep_interrupt, ++ .fifo = (u32) S3C_UDC_OTG_EP6_FIFO, ++ }, ++ .ep[7] = { ++ .ep = { ++ .name = "ep7-int", ++ .ops = &s3c_ep_ops, ++ .maxpacket = EP_FIFO_SIZE2, ++ }, ++ .dev = &memory, ++ ++ .bEndpointAddress = USB_DIR_IN | 7, ++ .bmAttributes = USB_ENDPOINT_XFER_INT, ++ ++ .ep_type = ep_interrupt, ++ .fifo = (u32) S3C_UDC_OTG_EP7_FIFO, ++ }, ++ .ep[8] = { ++ .ep = { ++ .name = "ep8-int", ++ .ops = &s3c_ep_ops, ++ .maxpacket = EP_FIFO_SIZE2, ++ }, ++ .dev = &memory, ++ ++ .bEndpointAddress = USB_DIR_IN | 8, ++ .bmAttributes = USB_ENDPOINT_XFER_INT, ++ ++ .ep_type = ep_interrupt, ++ .fifo = (u32) S3C_UDC_OTG_EP8_FIFO, ++ }, ++}; ++ ++static struct clk *otg_clock; ++ ++/* ++ * binds to the platform device ++ */ ++static int s3c_otg_probe(struct platform_device *pdev) ++{ ++ struct s3c_udc *dev = &memory; ++ struct s3c_plat_otg_data *pdata = pdev->dev.platform_data; ++ int retval; ++ ++ dev->reg_base = ioremap(pdev->resource[0].start, ++ pdev->resource[0].end - pdev->resource[0].start); ++ if (dev->reg_base == NULL) { ++ dev_err(&pdev->dev, "Unable to map USB OTG physical regs\n"); ++ return -ENOMEM; ++ } ++ ++ ++ DBG(2, "%p\n", pdev); ++ ++ spin_lock_init(&dev->lock); ++ dev->dev = pdev; ++ ++ device_initialize(&dev->gadget.dev); ++ dev->gadget.dev.parent = &pdev->dev; ++ ++ dev->gadget.is_dualspeed = 1; ++ dev->gadget.is_otg = 0; ++ dev->gadget.is_a_peripheral = 0; ++ dev->gadget.b_hnp_enable = 0; ++ dev->gadget.a_hnp_support = 0; ++ dev->gadget.a_alt_hnp_support = 0; ++ ++ dev->phyclk = pdata->phyclk; ++ ++ the_controller = dev; ++ platform_set_drvdata(pdev, dev); ++ ++ otg_clock = clk_get(&pdev->dev, "otg"); ++ if (otg_clock == NULL) { ++ DBG(3, "failed to find otg clock source\n"); ++ return -ENOENT; ++ } ++ clk_enable(otg_clock); ++ ++ s3c_otg_reinit(dev); ++ ++ local_irq_disable(); ++ ++ /* irq setup after old hardware state is cleaned up */ ++ retval = request_irq(pdev->resource[1].start, s3c_otg_irq, ++ IRQF_DISABLED, driver_name, dev); ++ ++ if (retval != 0) { ++ DBG(3, "%s: can't get irq %i - %d\n", ++ driver_name, IRQ_OTG, retval); ++ return -EBUSY; ++ } ++ ++ disable_irq(IRQ_OTG); ++ local_irq_enable(); ++ create_proc_files(); ++ ++ return retval; ++} ++ ++static int s3c_otg_remove(struct platform_device *pdev) ++{ ++ struct s3c_udc *dev = platform_get_drvdata(pdev); ++ ++ if (otg_clock != NULL) { ++ clk_disable(otg_clock); ++ clk_put(otg_clock); ++ otg_clock = NULL; ++ } ++ ++ remove_proc_files(); ++ usb_gadget_unregister_driver(dev->driver); ++ ++ free_irq(IRQ_OTG, dev); ++ ++ platform_set_drvdata(pdev, 0); ++ ++ the_controller = 0; ++ ++ if (dev->reg_base) ++ iounmap(dev->reg_base); ++ ++ return 0; ++} ++ ++#ifdef CONFIG_PM ++static int s3c_otg_suspend(struct platform_device *pdev, pm_message_t state) ++{ ++ struct s3c_udc *dev = the_controller; ++ ++ if (dev->driver) { ++ disable_irq(IRQ_OTG); ++ s3c_otg_disable(dev); ++ clk_disable(otg_clock); ++ } ++ ++ return 0; ++} ++ ++static int s3c_otg_resume(struct platform_device *pdev) ++{ ++ struct s3c_udc *dev = the_controller; ++ ++ if (dev->driver) { ++ clk_enable(otg_clock); ++ s3c_otg_enable(dev); ++ s3c_otg_reinit(dev); ++ enable_irq(IRQ_OTG); ++ } ++ ++ return 0; ++} ++#else ++#define s3c_otg_suspend NULL ++#define s3c_otg_resume NULL ++#endif ++ ++/*-------------------------------------------------------------------------*/ ++static struct platform_driver s3c_otg_driver = { ++ .probe = s3c_otg_probe, ++ .remove = s3c_otg_remove, ++ .suspend = s3c_otg_suspend, ++ .resume = s3c_otg_resume, ++ .driver = { ++ .owner = THIS_MODULE, ++ .name = "s3c-otg-usbgadget", ++ }, ++}; ++ ++static int __init otg_init(void) ++{ ++ int ret; ++ ++ ret = platform_driver_register(&s3c_otg_driver); ++ if (!ret) ++ printk(KERN_INFO "Loaded %s version %s %s\n", ++ driver_name, DRIVER_VERSION, "(Slave Mode)"); ++ ++ return ret; ++} ++ ++static void __exit otg_exit(void) ++{ ++ platform_driver_unregister(&s3c_otg_driver); ++ printk(KERN_INFO "Unloaded %s version %s\n", ++ driver_name, DRIVER_VERSION); ++} ++ ++module_init(otg_init); ++module_exit(otg_exit); ++ ++MODULE_AUTHOR(DRIVER_AUTHOR); ++MODULE_DESCRIPTION(DRIVER_DESC); ++MODULE_VERSION(DRIVER_VERSION); ++MODULE_LICENSE("GPL"); +diff -ruN --exclude='*.orig' --exclude='*.rej' linux-2.6.29-rc3.owrt/drivers/usb/gadget/s3c-udc.h linux-2.6.29-rc3.owrt.om/drivers/usb/gadget/s3c-udc.h +--- linux-2.6.29-rc3.owrt/drivers/usb/gadget/s3c-udc.h 1970-01-01 01:00:00.000000000 +0100 ++++ linux-2.6.29-rc3.owrt.om/drivers/usb/gadget/s3c-udc.h 2009-05-10 22:28:00.000000000 +0200 +@@ -0,0 +1,132 @@ ++/* ++ * drivers/usb/gadget/s3c-udc.h ++ * Samsung S3C on-chip full/high speed USB device controllers ++ * ++ * Copyright (C) 2008 Samsung Electronics ++ * Minkyu Kang <mk7.kang@samsung.com> ++ * ++ * 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, MA 02111-1307 USA ++ * ++ */ ++ ++#ifndef __S3C_UDC_H ++#define __S3C_UDC_H ++ ++#include <linux/module.h> ++#include <linux/kernel.h> ++#include <linux/ioport.h> ++#include <linux/types.h> ++#include <linux/version.h> ++#include <linux/errno.h> ++#include <linux/delay.h> ++#include <linux/sched.h> ++#include <linux/slab.h> ++#include <linux/init.h> ++#include <linux/timer.h> ++#include <linux/list.h> ++#include <linux/interrupt.h> ++#include <linux/proc_fs.h> ++#include <linux/mm.h> ++#include <linux/device.h> ++#include <linux/dma-mapping.h> ++#include <asm/byteorder.h> ++#include <linux/io.h> ++#include <asm/dma.h> ++#include <asm/irq.h> ++#include <asm/system.h> ++#include <asm/unaligned.h> ++#include <mach/hardware.h> ++ ++#include <linux/usb/ch9.h> ++#include <linux/usb/gadget.h> ++ ++/* Max packet size */ ++#if defined(CONFIG_USB_GADGET_S3C_FS) ++#define EP0_FIFO_SIZE 8 ++#define EP_FIFO_SIZE 64 ++#define S3C_MAX_ENDPOINTS 5 ++#elif defined(CONFIG_USB_GADGET_S3C_HS) ++#define EP0_FIFO_SIZE 64 ++#define EP_FIFO_SIZE 512 ++#define EP_FIFO_SIZE2 1024 ++#define S3C_MAX_ENDPOINTS 9 ++#else ++#define EP0_FIFO_SIZE 64 ++#define EP_FIFO_SIZE 512 ++#define EP_FIFO_SIZE2 1024 ++#define S3C_MAX_ENDPOINTS 16 ++#endif ++ ++#define WAIT_FOR_SETUP 0 ++#define DATA_STATE_XMIT 1 ++#define DATA_STATE_NEED_ZLP 2 ++#define WAIT_FOR_OUT_STATUS 3 ++#define DATA_STATE_RECV 4 ++ ++enum ep_type { ++ ep_control, ep_bulk_in, ep_bulk_out, ep_interrupt ++}; ++ ++struct s3c_ep { ++ struct usb_ep ep; ++ struct s3c_udc *dev; ++ ++ const struct usb_endpoint_descriptor *desc; ++ struct list_head queue; ++ unsigned long pio_irqs; ++ ++ u8 stopped; ++ u8 bEndpointAddress; ++ u8 bmAttributes; ++ ++ u32 ep_type; ++ u32 fifo; ++#ifdef CONFIG_USB_GADGET_S3C_FS ++ u32 csr1; ++ u32 csr2; ++#endif ++}; ++ ++struct s3c_request { ++ struct usb_request req; ++ struct list_head queue; ++}; ++ ++struct s3c_udc { ++ struct usb_gadget gadget; ++ struct usb_gadget_driver *driver; ++ struct platform_device *dev; ++ spinlock_t lock; ++ u32 * reg_base; ++ ++ int phyclk; ++ int ep0state; ++ struct s3c_ep ep[S3C_MAX_ENDPOINTS]; ++ ++ unsigned char usb_address; ++ ++ unsigned req_pending:1; ++ unsigned req_std:1; ++ unsigned req_config:1; ++}; ++ ++extern struct s3c_udc *the_controller; ++ ++#define ep_is_in(EP) (((EP)->bEndpointAddress & USB_DIR_IN) \ ++ == USB_DIR_IN) ++#define ep_index(EP) ((EP)->bEndpointAddress & 0xF) ++#define ep_maxpacket(EP) ((EP)->ep.maxpacket) ++ ++#endif +diff -ruN --exclude='*.orig' --exclude='*.rej' linux-2.6.29-rc3.owrt/drivers/usb/host/ohci-hcd.c linux-2.6.29-rc3.owrt.om/drivers/usb/host/ohci-hcd.c +--- linux-2.6.29-rc3.owrt/drivers/usb/host/ohci-hcd.c 2009-05-10 22:04:48.000000000 +0200 ++++ linux-2.6.29-rc3.owrt.om/drivers/usb/host/ohci-hcd.c 2009-05-10 22:28:00.000000000 +0200 +@@ -997,7 +997,7 @@ + #define SA1111_DRIVER ohci_hcd_sa1111_driver + #endif + +-#ifdef CONFIG_ARCH_S3C2410 ++#ifdef CONFIG_PLAT_S3C + #include "ohci-s3c2410.c" + #define PLATFORM_DRIVER ohci_hcd_s3c2410_driver + #endif +diff -ruN --exclude='*.orig' --exclude='*.rej' linux-2.6.29-rc3.owrt/drivers/usb/host/ohci-s3c2410.c linux-2.6.29-rc3.owrt.om/drivers/usb/host/ohci-s3c2410.c +--- linux-2.6.29-rc3.owrt/drivers/usb/host/ohci-s3c2410.c 2009-05-10 22:04:48.000000000 +0200 ++++ linux-2.6.29-rc3.owrt.om/drivers/usb/host/ohci-s3c2410.c 2009-05-10 22:28:00.000000000 +0200 +@@ -21,9 +21,9 @@ + + #include <linux/platform_device.h> + #include <linux/clk.h> +- + #include <mach/hardware.h> +-#include <mach/usb-control.h> ++#include <mach/regs-gpio.h> ++#include <plat/usb-control.h> + + #define valid_port(idx) ((idx) == 1 || (idx) == 2) + +@@ -58,9 +58,8 @@ + info->hcd = hcd; + info->report_oc = s3c2410_hcd_oc; + +- if (info->enable_oc != NULL) { ++ if (info->enable_oc != NULL) + (info->enable_oc)(info, 1); +- } + } + } + +@@ -74,9 +73,8 @@ + info->report_oc = NULL; + info->hcd = NULL; + +- if (info->enable_oc != NULL) { ++ if (info->enable_oc != NULL) + (info->enable_oc)(info, 0); +- } + } + + clk_disable(clk); +@@ -90,14 +88,14 @@ + */ + + static int +-ohci_s3c2410_hub_status_data (struct usb_hcd *hcd, char *buf) ++ohci_s3c2410_hub_status_data(struct usb_hcd *hcd, char *buf) + { + struct s3c2410_hcd_info *info = to_s3c2410_info(hcd); + struct s3c2410_hcd_port *port; + int orig; + int portno; + +- orig = ohci_hub_status_data (hcd, buf); ++ orig = ohci_hub_status_data(hcd, buf); + + if (info == NULL) + return orig; +@@ -147,7 +145,7 @@ + * request. + */ + +-static int ohci_s3c2410_hub_control ( ++static int ohci_s3c2410_hub_control( + struct usb_hcd *hcd, + u16 typeReq, + u16 wValue, +@@ -201,9 +199,8 @@ + dev_dbg(hcd->self.controller, + "ClearPortFeature: OVER_CURRENT\n"); + +- if (valid_port(wIndex)) { ++ if (valid_port(wIndex)) + info->port[wIndex-1].oc_status = 0; +- } + + goto out; + +@@ -244,28 +241,28 @@ + desc->wHubCharacteristics |= cpu_to_le16(0x0001); + + if (info->enable_oc) { +- desc->wHubCharacteristics &= ~cpu_to_le16(HUB_CHAR_OCPM); +- desc->wHubCharacteristics |= cpu_to_le16(0x0008|0x0001); ++ desc->wHubCharacteristics &= ++ ~cpu_to_le16(HUB_CHAR_OCPM); ++ desc->wHubCharacteristics |= ++ cpu_to_le16(0x0008|0x0001); + } + +- dev_dbg(hcd->self.controller, "wHubCharacteristics after 0x%04x\n", ++ dev_dbg(hcd->self.controller, ++ "wHubCharacteristics after 0x%04x\n", + desc->wHubCharacteristics); + + return ret; + + case GetPortStatus: + /* check port status */ +- + dev_dbg(hcd->self.controller, "GetPortStatus(%d)\n", wIndex); + + if (valid_port(wIndex)) { +- if (info->port[wIndex-1].oc_changed) { ++ if (info->port[wIndex-1].oc_changed) + *data |= cpu_to_le32(RH_PS_OCIC); +- } + +- if (info->port[wIndex-1].oc_status) { ++ if (info->port[wIndex-1].oc_status) + *data |= cpu_to_le32(RH_PS_POCI); +- } + } + } + +@@ -308,6 +305,42 @@ + local_irq_restore(flags); + } + ++/* switching of USB pads */ ++static ssize_t show_usb_mode(struct device *dev, struct device_attribute *attr, ++ char *buf) ++{ ++ if (__raw_readl(S3C24XX_MISCCR) & S3C2410_MISCCR_USBHOST) ++ return sprintf(buf, "host\n"); ++ ++ return sprintf(buf, "device\n"); ++} ++ ++static ssize_t set_usb_mode(struct device *dev, struct device_attribute *attr, ++ const char *buf, size_t count) ++{ ++ if (!strncmp(buf, "host", 4)) { ++ printk(KERN_WARNING "s3c2410: changing usb to host\n"); ++ s3c2410_modify_misccr(S3C2410_MISCCR_USBHOST, ++ S3C2410_MISCCR_USBHOST); ++ /* FIXME: ++ * - call machine-specific disable-pullup function i ++ * - enable +Vbus (if hardware supports it) ++ */ ++ s3c2410_gpio_setpin(S3C2410_GPB9, 0); ++ } else if (!strncmp(buf, "device", 6)) { ++ printk(KERN_WARNING "s3c2410: changing usb to device\n"); ++ s3c2410_modify_misccr(S3C2410_MISCCR_USBHOST, 0); ++ s3c2410_gpio_setpin(S3C2410_GPB9, 1); ++ } else { ++ printk(KERN_WARNING "s3c2410: unknown mode\n"); ++ return -EINVAL; ++ } ++ ++ return count; ++} ++ ++static DEVICE_ATTR(usb_mode, S_IRUGO | S_IWUSR, show_usb_mode, set_usb_mode); ++ + /* may be called without controller electrically present */ + /* may be called with controller, bus, and devices active */ + +@@ -323,8 +356,9 @@ + */ + + static void +-usb_hcd_s3c2410_remove (struct usb_hcd *hcd, struct platform_device *dev) ++usb_hcd_s3c2410_remove(struct usb_hcd *hcd, struct platform_device *dev) + { ++ device_remove_file(&dev->dev, &dev_attr_usb_mode); + usb_remove_hcd(hcd); + s3c2410_stop_hc(dev); + iounmap(hcd->regs); +@@ -341,8 +375,8 @@ + * through the hotplug entry's driver_data. + * + */ +-static int usb_hcd_s3c2410_probe (const struct hc_driver *driver, +- struct platform_device *dev) ++static int usb_hcd_s3c2410_probe(const struct hc_driver *driver, ++ struct platform_device *dev) + { + struct usb_hcd *hcd = NULL; + int retval; +@@ -392,9 +426,16 @@ + if (retval != 0) + goto err_ioremap; + ++ retval = device_create_file(&dev->dev, &dev_attr_usb_mode); ++ if (retval != 0) ++ goto err_hcd; ++ + return 0; + +- err_ioremap: ++err_hcd: ++ usb_remove_hcd(hcd); ++ ++err_ioremap: + s3c2410_stop_hc(dev); + iounmap(hcd->regs); + clk_put(usb_clk); +@@ -413,17 +454,19 @@ + /*-------------------------------------------------------------------------*/ + + static int +-ohci_s3c2410_start (struct usb_hcd *hcd) ++ohci_s3c2410_start(struct usb_hcd *hcd) + { +- struct ohci_hcd *ohci = hcd_to_ohci (hcd); ++ struct ohci_hcd *ohci = hcd_to_ohci(hcd); + int ret; + +- if ((ret = ohci_init(ohci)) < 0) ++ ret = ohci_init(ohci); ++ if (ret < 0) + return ret; + +- if ((ret = ohci_run (ohci)) < 0) { +- err ("can't start %s", hcd->self.bus_name); +- ohci_stop (hcd); ++ ret = ohci_run(ohci); ++ if (ret < 0) { ++ err("can't start %s", hcd->self.bus_name); ++ ohci_stop(hcd); + return ret; + } + +@@ -488,15 +531,23 @@ + return 0; + } + ++static int ohci_hcd_s3c2410_drv_resume(struct platform_device *pdev) ++{ ++ struct usb_hcd *hcd = platform_get_drvdata(pdev); ++ ++ ohci_finish_controller_resume(hcd); ++ return 0; ++} ++ + static struct platform_driver ohci_hcd_s3c2410_driver = { + .probe = ohci_hcd_s3c2410_drv_probe, + .remove = ohci_hcd_s3c2410_drv_remove, + .shutdown = usb_hcd_platform_shutdown, + /*.suspend = ohci_hcd_s3c2410_drv_suspend, */ +- /*.resume = ohci_hcd_s3c2410_drv_resume, */ ++ .resume = ohci_hcd_s3c2410_drv_resume, + .driver = { + .owner = THIS_MODULE, +- .name = "s3c2410-ohci", ++ .name = "s3c-ohci", + }, + }; + +diff -ruN --exclude='*.orig' --exclude='*.rej' linux-2.6.29-rc3.owrt/drivers/usb/Kconfig linux-2.6.29-rc3.owrt.om/drivers/usb/Kconfig +--- linux-2.6.29-rc3.owrt/drivers/usb/Kconfig 2009-05-10 22:04:48.000000000 +0200 ++++ linux-2.6.29-rc3.owrt.om/drivers/usb/Kconfig 2009-05-10 22:28:00.000000000 +0200 +@@ -31,7 +31,7 @@ + default y if SA1111 + default y if ARCH_OMAP + default y if ARCH_LH7A404 +- default y if ARCH_S3C2410 ++ default y if PLAT_S3C + default y if PXA27x + default y if PXA3xx + default y if ARCH_EP93XX +diff -ruN --exclude='*.orig' --exclude='*.rej' linux-2.6.29-rc3.owrt/drivers/video/backlight/gta01_bl.c linux-2.6.29-rc3.owrt.om/drivers/video/backlight/gta01_bl.c +--- linux-2.6.29-rc3.owrt/drivers/video/backlight/gta01_bl.c 1970-01-01 01:00:00.000000000 +0100 ++++ linux-2.6.29-rc3.owrt.om/drivers/video/backlight/gta01_bl.c 2009-05-10 22:28:00.000000000 +0200 +@@ -0,0 +1,269 @@ ++/* ++ * Backlight Driver for FIC GTA01 (Neo1973) GSM Phone ++ * ++ * Copyright (C) 2006-2007 by Openmoko, Inc. ++ * Author: Harald Welte <laforge@openmoko.org> ++ * All rights reserved. ++ * ++ * based on corgi_cl.c, Copyright (c) 2004-2006 Richard Purdie ++ * ++ * 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, version 2. ++ * ++ * 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, ++ * MA 02111-1307 USA ++ * ++ * Javi Roman <javiroman@kernel-labs.org>: ++ * implement PWM, instead of simple on/off switching ++ * ++ */ ++ ++#include <linux/module.h> ++#include <linux/kernel.h> ++#include <linux/init.h> ++#include <linux/platform_device.h> ++#include <linux/mutex.h> ++#include <linux/fb.h> ++#include <linux/backlight.h> ++#include <linux/clk.h> ++ ++#include <mach/hardware.h> ++#include <mach/gta01.h> ++#include <plat/pwm.h> ++ ++#include <plat/regs-timer.h> ++#include <asm/plat-s3c24xx/neo1973.h> ++ ++static struct backlight_properties gta01bl_prop; ++static struct backlight_device *gta01_backlight_device; ++static struct gta01bl_machinfo *bl_machinfo; ++ ++static unsigned long gta01bl_flags; ++ ++struct gta01bl_data { ++ int intensity; ++ struct mutex mutex; ++ struct clk *clk; ++ struct s3c2410_pwm pwm; ++}; ++ ++static struct gta01bl_data gta01bl; ++ ++static int gta01bl_defer_resume_backlight; ++ ++#define GTA01BL_SUSPENDED 0x01 ++#define GTA01BL_BATTLOW 0x02 ++ ++/* On the GTA01 / Neo1973, we use a 50 or 66MHz PCLK, which gives ++ * us a 6.25..8.25MHz DIV8 clock, which is further divided by a ++ * prescaler of 4, resulting in a 1.56..2.06MHz tick. This results in a ++ * minimum frequency of 24..31Hz. At 400Hz, we need to set the count ++ * to something like 3906..5156, providing us a way sufficient resolution ++ * for display brightness adjustment. */ ++#define GTA01BL_COUNTER 5156 ++ ++static int gta01bl_send_intensity(struct backlight_device *bd) ++{ ++ int intensity = bd->props.brightness; ++ ++ if (bd->props.power != FB_BLANK_UNBLANK) ++ intensity = 0; ++ if (bd->props.fb_blank != FB_BLANK_UNBLANK) ++ intensity = 0; ++ if (gta01bl_flags & GTA01BL_SUSPENDED) ++ intensity = 0; ++ if (gta01bl_flags & GTA01BL_BATTLOW) ++ intensity &= bl_machinfo->limit_mask; ++ ++ mutex_lock(>a01bl.mutex); ++#ifdef GTA01_BACKLIGHT_ONOFF_ONLY ++ if (intensity) ++ neo1973_gpb_setpin(GTA01_GPIO_BACKLIGHT, 1); ++ else ++ neo1973_gpb_setpin(GTA01_GPIO_BACKLIGHT, 0); ++#else ++ if (intensity == bd->props.max_brightness) { ++ neo1973_gpb_setpin(GTA01_GPIO_BACKLIGHT, 1); ++ s3c2410_gpio_cfgpin(GTA01_GPIO_BACKLIGHT, S3C2410_GPIO_OUTPUT); ++ } else { ++ s3c2410_pwm_duty_cycle(intensity & 0xffff, >a01bl.pwm); ++ s3c2410_gpio_cfgpin(GTA01_GPIO_BACKLIGHT, S3C2410_GPB0_TOUT0); ++ } ++#endif ++ mutex_unlock(>a01bl.mutex); ++ ++ gta01bl.intensity = intensity; ++ return 0; ++} ++ ++static int gta01bl_init_hw(void) ++{ ++ int rc; ++ ++ rc = s3c2410_pwm_init(>a01bl.pwm); ++ if (rc) ++ return rc; ++ ++ gta01bl.pwm.timerid = PWM0; ++ gta01bl.pwm.prescaler = (4 - 1); ++ gta01bl.pwm.divider = S3C2410_TCFG1_MUX0_DIV8; ++ gta01bl.pwm.counter = GTA01BL_COUNTER; ++ gta01bl.pwm.comparer = gta01bl.pwm.counter; ++ ++ rc = s3c2410_pwm_enable(>a01bl.pwm); ++ if (rc) ++ return rc; ++ ++ s3c2410_pwm_start(>a01bl.pwm); ++ ++ gta01bl_prop.max_brightness = gta01bl.pwm.counter; ++ ++ return 0; ++} ++ ++#ifdef CONFIG_PM ++static int gta01bl_suspend(struct platform_device *dev, pm_message_t state) ++{ ++ gta01bl_flags |= GTA01BL_SUSPENDED; ++ gta01bl_send_intensity(gta01_backlight_device); ++ neo1973_gpb_setpin(GTA01_GPIO_BACKLIGHT, 0); ++ s3c2410_gpio_cfgpin(GTA01_GPIO_BACKLIGHT, S3C2410_GPIO_OUTPUT); ++ return 0; ++} ++ ++void gta01bl_deferred_resume(void) ++{ ++ mutex_lock(>a01bl.mutex); ++ gta01bl_init_hw(); ++ mutex_unlock(>a01bl.mutex); ++ ++ gta01bl_flags &= ~GTA01BL_SUSPENDED; ++ gta01bl_send_intensity(gta01_backlight_device); ++} ++EXPORT_SYMBOL_GPL(gta01bl_deferred_resume); ++ ++static int gta01bl_resume(struct platform_device *dev) ++{ ++ if (!gta01bl_defer_resume_backlight) ++ gta01bl_deferred_resume(); ++ return 0; ++} ++#else ++#define gta01bl_suspend NULL ++#define gta01bl_resume NULL ++#endif ++ ++static int gta01bl_get_intensity(struct backlight_device *bd) ++{ ++ return gta01bl.intensity; ++} ++ ++static int gta01bl_set_intensity(struct backlight_device *bd) ++{ ++ gta01bl_send_intensity(gta01_backlight_device); ++ return 0; ++} ++ ++/* ++ * Called when the battery is low to limit the backlight intensity. ++ * If limit==0 clear any limit, otherwise limit the intensity ++ */ ++void gta01bl_limit_intensity(int limit) ++{ ++ if (limit) ++ gta01bl_flags |= GTA01BL_BATTLOW; ++ else ++ gta01bl_flags &= ~GTA01BL_BATTLOW; ++ gta01bl_send_intensity(gta01_backlight_device); ++} ++EXPORT_SYMBOL_GPL(gta01bl_limit_intensity); ++ ++ ++static struct backlight_ops gta01bl_ops = { ++ .get_brightness = gta01bl_get_intensity, ++ .update_status = gta01bl_set_intensity, ++}; ++ ++static int __init gta01bl_probe(struct platform_device *pdev) ++{ ++ struct gta01bl_machinfo *machinfo = pdev->dev.platform_data; ++ int rc; ++ ++#ifdef GTA01_BACKLIGHT_ONOFF_ONLY ++ s3c2410_gpio_cfgpin(GTA01_GPIO_BACKLIGHT, S3C2410_GPIO_OUTPUT); ++ gta01bl_prop.max_brightness = 1; ++#else ++ rc = gta01bl_init_hw(); ++ if (rc < 0) ++ return rc; ++#endif ++ mutex_init(>a01bl.mutex); ++ ++ if (!machinfo->limit_mask) ++ machinfo->limit_mask = -1; ++ ++ gta01bl_defer_resume_backlight = machinfo->defer_resume_backlight; ++ ++ gta01_backlight_device = backlight_device_register("gta01-bl", ++ &pdev->dev, NULL, ++ >a01bl_ops); ++ if (IS_ERR(gta01_backlight_device)) ++ return PTR_ERR(gta01_backlight_device); ++ ++ gta01bl_prop.power = FB_BLANK_UNBLANK; ++ gta01bl_prop.brightness = gta01bl_prop.max_brightness; ++ memcpy(>a01_backlight_device->props, ++ >a01bl_prop, sizeof(gta01bl_prop)); ++ gta01bl_send_intensity(gta01_backlight_device); ++ ++ return 0; ++} ++ ++static int gta01bl_remove(struct platform_device *dev) ++{ ++#ifndef GTA01_BACKLIGHT_ONOFF_ONLY ++ s3c2410_pwm_disable(>a01bl.pwm); ++#endif ++ backlight_device_unregister(gta01_backlight_device); ++ mutex_destroy(>a01bl.mutex); ++ ++ s3c2410_gpio_cfgpin(GTA01_GPIO_BACKLIGHT, S3C2410_GPIO_OUTPUT); ++ neo1973_gpb_setpin(GTA01_GPIO_BACKLIGHT, 1); ++ ++ return 0; ++} ++ ++static struct platform_driver gta01bl_driver = { ++ .probe = gta01bl_probe, ++ .remove = gta01bl_remove, ++ .suspend = gta01bl_suspend, ++ .resume = gta01bl_resume, ++ .driver = { ++ .name = "gta01-bl", ++ }, ++}; ++ ++static int __init gta01bl_init(void) ++{ ++ return platform_driver_register(>a01bl_driver); ++} ++ ++static void __exit gta01bl_exit(void) ++{ ++ platform_driver_unregister(>a01bl_driver); ++} ++ ++module_init(gta01bl_init); ++module_exit(gta01bl_exit); ++ ++MODULE_DESCRIPTION("FIC GTA01 (Neo1973) Backlight Driver"); ++MODULE_AUTHOR("Harald Welte <laforge@openmoko.org>"); ++MODULE_LICENSE("GPL"); +diff -ruN --exclude='*.orig' --exclude='*.rej' linux-2.6.29-rc3.owrt/drivers/video/backlight/Kconfig linux-2.6.29-rc3.owrt.om/drivers/video/backlight/Kconfig +--- linux-2.6.29-rc3.owrt/drivers/video/backlight/Kconfig 2009-05-10 22:04:48.000000000 +0200 ++++ linux-2.6.29-rc3.owrt.om/drivers/video/backlight/Kconfig 2009-05-10 22:28:00.000000000 +0200 +@@ -149,6 +149,13 @@ + the PWL module of OMAP1 processors. Say Y if your board + uses this hardware. + ++config BACKLIGHT_GTA01 ++ tristate "FIC Neo1973 GTA01 Backlight Driver" ++ depends on BACKLIGHT_CLASS_DEVICE && MACH_NEO1973_GTA01 ++ default y ++ help ++ If you have a FIC Neo1973 GTA01, say y to enable the backlight driver. ++ + config BACKLIGHT_HP680 + tristate "HP Jornada 680 Backlight Driver" + depends on BACKLIGHT_CLASS_DEVICE && SH_HP6XX +diff -ruN --exclude='*.orig' --exclude='*.rej' linux-2.6.29-rc3.owrt/drivers/video/backlight/Makefile linux-2.6.29-rc3.owrt.om/drivers/video/backlight/Makefile +--- linux-2.6.29-rc3.owrt/drivers/video/backlight/Makefile 2009-05-10 22:08:45.000000000 +0200 ++++ linux-2.6.29-rc3.owrt.om/drivers/video/backlight/Makefile 2009-05-10 22:28:00.000000000 +0200 +@@ -12,6 +12,8 @@ + obj-$(CONFIG_BACKLIGHT_CLASS_DEVICE) += backlight.o + obj-$(CONFIG_BACKLIGHT_ATMEL_PWM) += atmel-pwm-bl.o + obj-$(CONFIG_BACKLIGHT_GENERIC) += generic_bl.o ++obj-$(CONFIG_BACKLIGHT_CORGI) += corgi_bl.o ++obj-$(CONFIG_BACKLIGHT_GTA01) += gta01_bl.o + obj-$(CONFIG_BACKLIGHT_HP680) += hp680_bl.o + obj-$(CONFIG_BACKLIGHT_LOCOMO) += locomolcd.o + obj-$(CONFIG_BACKLIGHT_OMAP1) += omap1_bl.o +diff -ruN --exclude='*.orig' --exclude='*.rej' linux-2.6.29-rc3.owrt/drivers/video/console/fbcon.c linux-2.6.29-rc3.owrt.om/drivers/video/console/fbcon.c +--- linux-2.6.29-rc3.owrt/drivers/video/console/fbcon.c 2009-05-10 22:04:48.000000000 +0200 ++++ linux-2.6.29-rc3.owrt.om/drivers/video/console/fbcon.c 2009-05-10 22:28:00.000000000 +0200 +@@ -373,6 +373,9 @@ + int c; + int mode; + ++ if (info->state != FBINFO_STATE_RUNNING) ++ return; ++ + acquire_console_sem(); + if (ops && ops->currcon != -1) + vc = vc_cons[ops->currcon].d; +diff -ruN --exclude='*.orig' --exclude='*.rej' linux-2.6.29-rc3.owrt/drivers/video/display/jbt6k74.c linux-2.6.29-rc3.owrt.om/drivers/video/display/jbt6k74.c +--- linux-2.6.29-rc3.owrt/drivers/video/display/jbt6k74.c 1970-01-01 01:00:00.000000000 +0100 ++++ linux-2.6.29-rc3.owrt.om/drivers/video/display/jbt6k74.c 2009-05-10 22:28:00.000000000 +0200 +@@ -0,0 +1,768 @@ ++/* Linux kernel driver for the tpo JBT6K74-AS LCM ASIC ++ * ++ * Copyright (C) 2006-2007 by Openmoko, Inc. ++ * Author: Harald Welte <laforge@openmoko.org>, ++ * Stefan Schmidt <stefan@openmoko.org> ++ * Copyright (C) 2008 by Harald Welte <laforge@openmoko.org> ++ * All rights reserved. ++ * ++ * 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, ++ * MA 02111-1307 USA ++ * ++ */ ++ ++#include <linux/kernel.h> ++#include <linux/types.h> ++#include <linux/module.h> ++#include <linux/device.h> ++#include <linux/platform_device.h> ++#include <linux/delay.h> ++#include <linux/jbt6k74.h> ++#include <linux/fb.h> ++#include <linux/time.h> ++ ++enum jbt_register { ++ JBT_REG_SLEEP_IN = 0x10, ++ JBT_REG_SLEEP_OUT = 0x11, ++ ++ JBT_REG_DISPLAY_OFF = 0x28, ++ JBT_REG_DISPLAY_ON = 0x29, ++ ++ JBT_REG_RGB_FORMAT = 0x3a, ++ JBT_REG_QUAD_RATE = 0x3b, ++ ++ JBT_REG_POWER_ON_OFF = 0xb0, ++ JBT_REG_BOOSTER_OP = 0xb1, ++ JBT_REG_BOOSTER_MODE = 0xb2, ++ JBT_REG_BOOSTER_FREQ = 0xb3, ++ JBT_REG_OPAMP_SYSCLK = 0xb4, ++ JBT_REG_VSC_VOLTAGE = 0xb5, ++ JBT_REG_VCOM_VOLTAGE = 0xb6, ++ JBT_REG_EXT_DISPL = 0xb7, ++ JBT_REG_OUTPUT_CONTROL = 0xb8, ++ JBT_REG_DCCLK_DCEV = 0xb9, ++ JBT_REG_DISPLAY_MODE1 = 0xba, ++ JBT_REG_DISPLAY_MODE2 = 0xbb, ++ JBT_REG_DISPLAY_MODE = 0xbc, ++ JBT_REG_ASW_SLEW = 0xbd, ++ JBT_REG_DUMMY_DISPLAY = 0xbe, ++ JBT_REG_DRIVE_SYSTEM = 0xbf, ++ ++ JBT_REG_SLEEP_OUT_FR_A = 0xc0, ++ JBT_REG_SLEEP_OUT_FR_B = 0xc1, ++ JBT_REG_SLEEP_OUT_FR_C = 0xc2, ++ JBT_REG_SLEEP_IN_LCCNT_D = 0xc3, ++ JBT_REG_SLEEP_IN_LCCNT_E = 0xc4, ++ JBT_REG_SLEEP_IN_LCCNT_F = 0xc5, ++ JBT_REG_SLEEP_IN_LCCNT_G = 0xc6, ++ ++ JBT_REG_GAMMA1_FINE_1 = 0xc7, ++ JBT_REG_GAMMA1_FINE_2 = 0xc8, ++ JBT_REG_GAMMA1_INCLINATION = 0xc9, ++ JBT_REG_GAMMA1_BLUE_OFFSET = 0xca, ++ ++ /* VGA */ ++ JBT_REG_BLANK_CONTROL = 0xcf, ++ JBT_REG_BLANK_TH_TV = 0xd0, ++ JBT_REG_CKV_ON_OFF = 0xd1, ++ JBT_REG_CKV_1_2 = 0xd2, ++ JBT_REG_OEV_TIMING = 0xd3, ++ JBT_REG_ASW_TIMING_1 = 0xd4, ++ JBT_REG_ASW_TIMING_2 = 0xd5, ++ ++ /* QVGA */ ++ JBT_REG_BLANK_CONTROL_QVGA = 0xd6, ++ JBT_REG_BLANK_TH_TV_QVGA = 0xd7, ++ JBT_REG_CKV_ON_OFF_QVGA = 0xd8, ++ JBT_REG_CKV_1_2_QVGA = 0xd9, ++ JBT_REG_OEV_TIMING_QVGA = 0xde, ++ JBT_REG_ASW_TIMING_1_QVGA = 0xdf, ++ JBT_REG_ASW_TIMING_2_QVGA = 0xe0, ++ ++ ++ JBT_REG_HCLOCK_VGA = 0xec, ++ JBT_REG_HCLOCK_QVGA = 0xed, ++ ++}; ++ ++enum jbt_state { ++ JBT_STATE_DEEP_STANDBY, ++ JBT_STATE_SLEEP, ++ JBT_STATE_NORMAL, ++ JBT_STATE_QVGA_NORMAL, ++}; ++ ++static const char *jbt_state_names[] = { ++ [JBT_STATE_DEEP_STANDBY] = "deep-standby", ++ [JBT_STATE_SLEEP] = "sleep", ++ [JBT_STATE_NORMAL] = "normal", ++ [JBT_STATE_QVGA_NORMAL] = "qvga-normal", ++}; ++ ++struct jbt_info { ++ enum jbt_state state, normal_state; ++ struct spi_device *spi_dev; ++ struct mutex lock; /* protects tx_buf and reg_cache */ ++ struct notifier_block fb_notif; ++ u16 tx_buf[8]; ++ u16 reg_cache[0xEE]; ++ struct timespec last_sleep; ++}; ++ ++#define JBT_COMMAND 0x000 ++#define JBT_DATA 0x100 ++ ++static inline unsigned int timespec_sub_ms(struct timespec lhs, ++ struct timespec rhs) ++{ ++ struct timespec ts = timespec_sub(lhs, rhs); ++ return (ts.tv_sec * MSEC_PER_SEC) + (ts.tv_nsec / NSEC_PER_MSEC); ++} ++ ++static int jbt_reg_write_nodata(struct jbt_info *jbt, u8 reg) ++{ ++ int rc; ++ ++ jbt->tx_buf[0] = JBT_COMMAND | reg; ++ rc = spi_write(jbt->spi_dev, (u8 *)jbt->tx_buf, ++ 1*sizeof(u16)); ++ if (rc == 0) ++ jbt->reg_cache[reg] = 0; ++ else ++ printk(KERN_ERR"jbt_reg_write_nodata spi_write ret %d\n", ++ rc); ++ ++ return rc; ++} ++ ++ ++static int jbt_reg_write(struct jbt_info *jbt, u8 reg, u8 data) ++{ ++ int rc; ++ ++ jbt->tx_buf[0] = JBT_COMMAND | reg; ++ jbt->tx_buf[1] = JBT_DATA | data; ++ rc = spi_write(jbt->spi_dev, (u8 *)jbt->tx_buf, ++ 2*sizeof(u16)); ++ if (rc == 0) ++ jbt->reg_cache[reg] = data; ++ else ++ printk(KERN_ERR"jbt_reg_write spi_write ret %d\n", rc); ++ ++ return rc; ++} ++ ++static int jbt_reg_write16(struct jbt_info *jbt, u8 reg, u16 data) ++{ ++ int rc; ++ ++ jbt->tx_buf[0] = JBT_COMMAND | reg; ++ jbt->tx_buf[1] = JBT_DATA | (data >> 8); ++ jbt->tx_buf[2] = JBT_DATA | (data & 0xff); ++ ++ rc = spi_write(jbt->spi_dev, (u8 *)jbt->tx_buf, ++ 3*sizeof(u16)); ++ if (rc == 0) ++ jbt->reg_cache[reg] = data; ++ else ++ printk(KERN_ERR"jbt_reg_write16 spi_write ret %d\n", rc); ++ ++ return rc; ++} ++ ++static int jbt_init_regs(struct jbt_info *jbt) ++{ ++ int rc; ++ ++ dev_dbg(&jbt->spi_dev->dev, "entering %cVGA mode\n", ++ jbt->normal_state == JBT_STATE_QVGA_NORMAL ? 'Q' : ' '); ++ ++ rc = jbt_reg_write(jbt, JBT_REG_DISPLAY_MODE1, 0x01); ++ rc |= jbt_reg_write(jbt, JBT_REG_DISPLAY_MODE2, 0x00); ++ rc |= jbt_reg_write(jbt, JBT_REG_RGB_FORMAT, 0x60); ++ rc |= jbt_reg_write(jbt, JBT_REG_DRIVE_SYSTEM, 0x10); ++ rc |= jbt_reg_write(jbt, JBT_REG_BOOSTER_OP, 0x56); ++ rc |= jbt_reg_write(jbt, JBT_REG_BOOSTER_MODE, 0x33); ++ rc |= jbt_reg_write(jbt, JBT_REG_BOOSTER_FREQ, 0x11); ++ rc |= jbt_reg_write(jbt, JBT_REG_OPAMP_SYSCLK, 0x02); ++ rc |= jbt_reg_write(jbt, JBT_REG_VSC_VOLTAGE, 0x2b); ++ rc |= jbt_reg_write(jbt, JBT_REG_VCOM_VOLTAGE, 0x40); ++ rc |= jbt_reg_write(jbt, JBT_REG_EXT_DISPL, 0x03); ++ rc |= jbt_reg_write(jbt, JBT_REG_DCCLK_DCEV, 0x04); ++ /* ++ * default of 0x02 in JBT_REG_ASW_SLEW responsible for 72Hz requirement ++ * to avoid red / blue flicker ++ */ ++ rc |= jbt_reg_write(jbt, JBT_REG_ASW_SLEW, 0x04); ++ rc |= jbt_reg_write(jbt, JBT_REG_DUMMY_DISPLAY, 0x00); ++ ++ rc |= jbt_reg_write(jbt, JBT_REG_SLEEP_OUT_FR_A, 0x11); ++ rc |= jbt_reg_write(jbt, JBT_REG_SLEEP_OUT_FR_B, 0x11); ++ rc |= jbt_reg_write(jbt, JBT_REG_SLEEP_OUT_FR_C, 0x11); ++ rc |= jbt_reg_write16(jbt, JBT_REG_SLEEP_IN_LCCNT_D, 0x2040); ++ rc |= jbt_reg_write16(jbt, JBT_REG_SLEEP_IN_LCCNT_E, 0x60c0); ++ rc |= jbt_reg_write16(jbt, JBT_REG_SLEEP_IN_LCCNT_F, 0x1020); ++ rc |= jbt_reg_write16(jbt, JBT_REG_SLEEP_IN_LCCNT_G, 0x60c0); ++ ++ rc |= jbt_reg_write16(jbt, JBT_REG_GAMMA1_FINE_1, 0x5533); ++ rc |= jbt_reg_write(jbt, JBT_REG_GAMMA1_FINE_2, 0x00); ++ rc |= jbt_reg_write(jbt, JBT_REG_GAMMA1_INCLINATION, 0x00); ++ rc |= jbt_reg_write(jbt, JBT_REG_GAMMA1_BLUE_OFFSET, 0x00); ++ ++ if (jbt->normal_state != JBT_STATE_QVGA_NORMAL) { ++ rc |= jbt_reg_write16(jbt, JBT_REG_HCLOCK_VGA, 0x1f0); ++ rc |= jbt_reg_write(jbt, JBT_REG_BLANK_CONTROL, 0x02); ++ rc |= jbt_reg_write16(jbt, JBT_REG_BLANK_TH_TV, 0x0804); ++ ++ rc |= jbt_reg_write(jbt, JBT_REG_CKV_ON_OFF, 0x01); ++ rc |= jbt_reg_write16(jbt, JBT_REG_CKV_1_2, 0x0000); ++ ++ rc |= jbt_reg_write16(jbt, JBT_REG_OEV_TIMING, 0x0d0e); ++ rc |= jbt_reg_write16(jbt, JBT_REG_ASW_TIMING_1, 0x11a4); ++ rc |= jbt_reg_write(jbt, JBT_REG_ASW_TIMING_2, 0x0e); ++ } else { ++ rc |= jbt_reg_write16(jbt, JBT_REG_HCLOCK_QVGA, 0x00ff); ++ rc |= jbt_reg_write(jbt, JBT_REG_BLANK_CONTROL_QVGA, 0x02); ++ rc |= jbt_reg_write16(jbt, JBT_REG_BLANK_TH_TV_QVGA, 0x0804); ++ ++ rc |= jbt_reg_write(jbt, JBT_REG_CKV_ON_OFF_QVGA, 0x01); ++ rc |= jbt_reg_write16(jbt, JBT_REG_CKV_1_2_QVGA, 0x0008); ++ ++ rc |= jbt_reg_write16(jbt, JBT_REG_OEV_TIMING_QVGA, 0x050a); ++ rc |= jbt_reg_write16(jbt, JBT_REG_ASW_TIMING_1_QVGA, 0x0a19); ++ rc |= jbt_reg_write(jbt, JBT_REG_ASW_TIMING_2_QVGA, 0x0a); ++ } ++ ++ return rc ? -EIO : 0; ++} ++ ++static int standby_to_sleep(struct jbt_info *jbt) ++{ ++ int rc; ++ ++ /* three times command zero */ ++ rc = jbt_reg_write_nodata(jbt, 0x00); ++ mdelay(1); ++ rc |= jbt_reg_write_nodata(jbt, 0x00); ++ mdelay(1); ++ rc |= jbt_reg_write_nodata(jbt, 0x00); ++ mdelay(1); ++ ++ /* deep standby out */ ++ rc |= jbt_reg_write(jbt, JBT_REG_POWER_ON_OFF, 0x11); ++ mdelay(1); ++ rc = jbt_reg_write(jbt, JBT_REG_DISPLAY_MODE, 0x28); ++ ++ /* (re)initialize register set */ ++ rc |= jbt_init_regs(jbt); ++ ++ return rc ? -EIO : 0; ++} ++ ++static int sleep_to_normal(struct jbt_info *jbt) ++{ ++ int rc; ++ ++ /* Make sure we are 120 ms after SLEEP_OUT */ ++ unsigned int sleep_time = timespec_sub_ms(current_kernel_time(), ++ jbt->last_sleep); ++ if (sleep_time < 120) ++ mdelay(120 - sleep_time); ++ ++ if (jbt->normal_state == JBT_STATE_NORMAL) { ++ /* RGB I/F on, RAM wirte off, QVGA through, SIGCON enable */ ++ rc = jbt_reg_write(jbt, JBT_REG_DISPLAY_MODE, 0x80); ++ ++ /* Quad mode off */ ++ rc |= jbt_reg_write(jbt, JBT_REG_QUAD_RATE, 0x00); ++ } else { ++ /* RGB I/F on, RAM wirte off, QVGA through, SIGCON enable */ ++ rc = jbt_reg_write(jbt, JBT_REG_DISPLAY_MODE, 0x81); ++ ++ /* Quad mode on */ ++ rc |= jbt_reg_write(jbt, JBT_REG_QUAD_RATE, 0x22); ++ } ++ ++ /* AVDD on, XVDD on */ ++ rc |= jbt_reg_write(jbt, JBT_REG_POWER_ON_OFF, 0x16); ++ ++ /* Output control */ ++ rc |= jbt_reg_write16(jbt, JBT_REG_OUTPUT_CONTROL, 0xfff9); ++ ++ /* Turn on display */ ++ rc |= jbt_reg_write_nodata(jbt, JBT_REG_DISPLAY_ON); ++ ++ /* Sleep mode off */ ++ rc |= jbt_reg_write_nodata(jbt, JBT_REG_SLEEP_OUT); ++ jbt->last_sleep = current_kernel_time(); ++ ++ /* Allow the booster and display controller to restart stably */ ++ mdelay(5); ++ ++ return rc ? -EIO : 0; ++} ++ ++static int normal_to_sleep(struct jbt_info *jbt) ++{ ++ int rc; ++ ++ /* Make sure we are 120 ms after SLEEP_OUT */ ++ unsigned int sleep_time = timespec_sub_ms(current_kernel_time(), ++ jbt->last_sleep); ++ if (sleep_time < 120) ++ mdelay(120 - sleep_time); ++ ++ rc = jbt_reg_write_nodata(jbt, JBT_REG_DISPLAY_OFF); ++ rc |= jbt_reg_write16(jbt, JBT_REG_OUTPUT_CONTROL, 0x8002); ++ rc |= jbt_reg_write_nodata(jbt, JBT_REG_SLEEP_IN); ++ jbt->last_sleep = current_kernel_time(); ++ ++ /* Allow the internal circuits to stop automatically */ ++ mdelay(5); ++ ++ return rc ? -EIO : 0; ++} ++ ++static int sleep_to_standby(struct jbt_info *jbt) ++{ ++ return jbt_reg_write(jbt, JBT_REG_POWER_ON_OFF, 0x00); ++} ++ ++/* frontend function */ ++int jbt6k74_enter_state(struct jbt_info *jbt, enum jbt_state new_state) ++{ ++ int rc = -EINVAL; ++ ++ dev_dbg(&jbt->spi_dev->dev, "entering (old_state=%s, new_state=%s)\n", ++ jbt_state_names[jbt->state], ++ jbt_state_names[new_state]); ++ ++ mutex_lock(&jbt->lock); ++ ++ if (new_state == JBT_STATE_NORMAL || ++ new_state == JBT_STATE_QVGA_NORMAL) ++ jbt->normal_state = new_state; ++ ++ switch (jbt->state) { ++ case JBT_STATE_DEEP_STANDBY: ++ switch (new_state) { ++ case JBT_STATE_DEEP_STANDBY: ++ rc = 0; ++ break; ++ case JBT_STATE_SLEEP: ++ rc = standby_to_sleep(jbt); ++ break; ++ case JBT_STATE_NORMAL: ++ /* first transition into sleep */ ++ rc = standby_to_sleep(jbt); ++ /* then transition into normal */ ++ rc |= sleep_to_normal(jbt); ++ break; ++ case JBT_STATE_QVGA_NORMAL: ++ /* first transition into sleep */ ++ rc = standby_to_sleep(jbt); ++ /* then transition into normal */ ++ rc |= sleep_to_normal(jbt); ++ break; ++ } ++ break; ++ case JBT_STATE_SLEEP: ++ switch (new_state) { ++ case JBT_STATE_SLEEP: ++ rc = 0; ++ break; ++ case JBT_STATE_DEEP_STANDBY: ++ rc = sleep_to_standby(jbt); ++ break; ++ case JBT_STATE_NORMAL: ++ case JBT_STATE_QVGA_NORMAL: ++ rc = sleep_to_normal(jbt); ++ break; ++ } ++ break; ++ case JBT_STATE_NORMAL: ++ switch (new_state) { ++ case JBT_STATE_NORMAL: ++ rc = 0; ++ break; ++ case JBT_STATE_DEEP_STANDBY: ++ /* first transition into sleep */ ++ rc = normal_to_sleep(jbt); ++ /* then transition into deep standby */ ++ rc |= sleep_to_standby(jbt); ++ break; ++ case JBT_STATE_SLEEP: ++ rc = normal_to_sleep(jbt); ++ break; ++ case JBT_STATE_QVGA_NORMAL: ++ /* first transition into sleep */ ++ rc = normal_to_sleep(jbt); ++ /* second transition into deep standby */ ++ rc |= sleep_to_standby(jbt); ++ /* third transition into sleep */ ++ rc |= standby_to_sleep(jbt); ++ /* fourth transition into normal */ ++ rc |= sleep_to_normal(jbt); ++ break; ++ } ++ break; ++ case JBT_STATE_QVGA_NORMAL: ++ switch (new_state) { ++ case JBT_STATE_QVGA_NORMAL: ++ rc = 0; ++ break; ++ case JBT_STATE_DEEP_STANDBY: ++ /* first transition into sleep */ ++ rc = normal_to_sleep(jbt); ++ /* then transition into deep standby */ ++ rc |= sleep_to_standby(jbt); ++ break; ++ case JBT_STATE_SLEEP: ++ rc = normal_to_sleep(jbt); ++ break; ++ case JBT_STATE_NORMAL: ++ /* first transition into sleep */ ++ rc = normal_to_sleep(jbt); ++ /* second transition into deep standby */ ++ rc |= sleep_to_standby(jbt); ++ /* third transition into sleep */ ++ rc |= standby_to_sleep(jbt); ++ /* fourth transition into normal */ ++ rc |= sleep_to_normal(jbt); ++ break; ++ } ++ break; ++ } ++ ++ if (rc == 0) ++ jbt->state = new_state; ++ else ++ dev_err(&jbt->spi_dev->dev, "Failed enter state '%s')\n", ++ jbt_state_names[new_state]); ++ ++ mutex_unlock(&jbt->lock); ++ ++ return rc; ++} ++EXPORT_SYMBOL_GPL(jbt6k74_enter_state); ++ ++static ssize_t state_read(struct device *dev, struct device_attribute *attr, ++ char *buf) ++{ ++ struct jbt_info *jbt = dev_get_drvdata(dev); ++ ++ if (jbt->state >= ARRAY_SIZE(jbt_state_names)) ++ return -EIO; ++ ++ return sprintf(buf, "%s\n", jbt_state_names[jbt->state]); ++} ++ ++static ssize_t state_write(struct device *dev, struct device_attribute *attr, ++ const char *buf, size_t count) ++{ ++ struct jbt_info *jbt = dev_get_drvdata(dev); ++ int i, rc; ++ ++ for (i = 0; i < ARRAY_SIZE(jbt_state_names); i++) { ++ if (!strncmp(buf, jbt_state_names[i], ++ strlen(jbt_state_names[i]))) { ++ rc = jbt6k74_enter_state(jbt, i); ++ if (rc) ++ return rc; ++ return count; ++ } ++ } ++ ++ return -EINVAL; ++} ++ ++static DEVICE_ATTR(state, 0644, state_read, state_write); ++ ++static int reg_by_string(const char *name) ++{ ++ if (!strcmp(name, "gamma_fine1")) ++ return JBT_REG_GAMMA1_FINE_1; ++ else if (!strcmp(name, "gamma_fine2")) ++ return JBT_REG_GAMMA1_FINE_2; ++ else if (!strcmp(name, "gamma_inclination")) ++ return JBT_REG_GAMMA1_INCLINATION; ++ else ++ return JBT_REG_GAMMA1_BLUE_OFFSET; ++} ++ ++static ssize_t gamma_read(struct device *dev, struct device_attribute *attr, ++ char *buf) ++{ ++ struct jbt_info *jbt = dev_get_drvdata(dev); ++ int reg = reg_by_string(attr->attr.name); ++ u16 val; ++ ++ mutex_lock(&jbt->lock); ++ val = jbt->reg_cache[reg]; ++ mutex_unlock(&jbt->lock); ++ ++ return sprintf(buf, "0x%04x\n", val); ++} ++ ++static ssize_t gamma_write(struct device *dev, struct device_attribute *attr, ++ const char *buf, size_t count) ++{ ++ struct jbt_info *jbt = dev_get_drvdata(dev); ++ int reg = reg_by_string(attr->attr.name); ++ unsigned long val = simple_strtoul(buf, NULL, 10); ++ ++ dev_info(dev, "writing gama %lu\n", val & 0xff); ++ ++ mutex_lock(&jbt->lock); ++ jbt_reg_write(jbt, reg, val & 0xff); ++ mutex_unlock(&jbt->lock); ++ ++ return count; ++} ++ ++static ssize_t reset_write(struct device *dev, struct device_attribute *attr, ++ const char *buf, size_t count) ++{ ++ int rc; ++ struct jbt_info *jbt = dev_get_drvdata(dev); ++ struct jbt6k74_platform_data *pdata = jbt->spi_dev->dev.platform_data; ++ ++ dev_info(dev, "reset\n"); ++ ++ mutex_lock(&jbt->lock); ++ ++ jbt->state = JBT_STATE_DEEP_STANDBY; ++ ++ /* hard reset the jbt6k74 */ ++ (pdata->reset)(0, 0); ++ mdelay(1); ++ (pdata->reset)(0, 1); ++ mdelay(120); ++ ++ rc = jbt_reg_write_nodata(jbt, 0x01); ++ if (rc < 0) ++ dev_err(&jbt->spi_dev->dev, "cannot soft reset\n"); ++ mdelay(120); ++ ++ mutex_unlock(&jbt->lock); ++ ++ jbt6k74_enter_state(jbt, jbt->normal_state); ++ ++ return count; ++} ++ ++static DEVICE_ATTR(gamma_fine1, 0644, gamma_read, gamma_write); ++static DEVICE_ATTR(gamma_fine2, 0644, gamma_read, gamma_write); ++static DEVICE_ATTR(gamma_inclination, 0644, gamma_read, gamma_write); ++static DEVICE_ATTR(gamma_blue_offset, 0644, gamma_read, gamma_write); ++static DEVICE_ATTR(reset, 0600, NULL, reset_write); ++ ++static struct attribute *jbt_sysfs_entries[] = { ++ &dev_attr_state.attr, ++ &dev_attr_gamma_fine1.attr, ++ &dev_attr_gamma_fine2.attr, ++ &dev_attr_gamma_inclination.attr, ++ &dev_attr_gamma_blue_offset.attr, ++ &dev_attr_reset.attr, ++ NULL, ++}; ++ ++static struct attribute_group jbt_attr_group = { ++ .name = NULL, ++ .attrs = jbt_sysfs_entries, ++}; ++ ++static int fb_notifier_callback(struct notifier_block *self, ++ unsigned long event, void *data) ++{ ++ struct jbt_info *jbt; ++ struct fb_event *evdata = data; ++ int fb_blank; ++ ++ jbt = container_of(self, struct jbt_info, fb_notif); ++ ++ dev_dbg(&jbt->spi_dev->dev, "event=%lu\n", event); ++ ++ if (event != FB_EVENT_BLANK && event != FB_EVENT_CONBLANK) ++ return 0; ++ ++ fb_blank = *(int *)evdata->data; ++ switch (fb_blank) { ++ case FB_BLANK_UNBLANK: ++ dev_dbg(&jbt->spi_dev->dev, "unblank\n"); ++ jbt6k74_enter_state(jbt, jbt->normal_state); ++ break; ++ case FB_BLANK_NORMAL: ++ dev_dbg(&jbt->spi_dev->dev, "blank\n"); ++ break; ++ case FB_BLANK_VSYNC_SUSPEND: ++ dev_dbg(&jbt->spi_dev->dev, "vsync suspend\n"); ++ break; ++ case FB_BLANK_HSYNC_SUSPEND: ++ dev_dbg(&jbt->spi_dev->dev, "hsync suspend\n"); ++ break; ++ case FB_BLANK_POWERDOWN: ++ dev_dbg(&jbt->spi_dev->dev, "powerdown\n"); ++ jbt6k74_enter_state(jbt, JBT_STATE_SLEEP); ++ break; ++ } ++ ++ return 0; ++} ++ ++/* linux device model infrastructure */ ++ ++static int __devinit jbt_probe(struct spi_device *spi) ++{ ++ int rc; ++ struct jbt_info *jbt; ++ struct jbt6k74_platform_data *pdata = spi->dev.platform_data; ++ ++ /* the controller doesn't have a MISO pin; we can't do detection */ ++ ++ spi->mode = SPI_CPOL | SPI_CPHA; ++ spi->bits_per_word = 9; ++ ++ rc = spi_setup(spi); ++ if (rc < 0) { ++ dev_err(&spi->dev, ++ "error during spi_setup of jbt6k74 driver\n"); ++ return rc; ++ } ++ ++ jbt = kzalloc(sizeof(*jbt), GFP_KERNEL); ++ if (!jbt) ++ return -ENOMEM; ++ ++ jbt->spi_dev = spi; ++ jbt->normal_state = JBT_STATE_NORMAL; ++ jbt->state = JBT_STATE_DEEP_STANDBY; ++ jbt->last_sleep = current_kernel_time(); ++ mutex_init(&jbt->lock); ++ ++ dev_set_drvdata(&spi->dev, jbt); ++ ++ rc = jbt6k74_enter_state(jbt, JBT_STATE_NORMAL); ++ if (rc < 0) { ++ dev_err(&spi->dev, "cannot enter NORMAL state\n"); ++ goto err_free_drvdata; ++ } ++ ++ rc = sysfs_create_group(&spi->dev.kobj, &jbt_attr_group); ++ if (rc < 0) { ++ dev_err(&spi->dev, "cannot create sysfs group\n"); ++ goto err_standby; ++ } ++ ++ jbt->fb_notif.notifier_call = fb_notifier_callback; ++ rc = fb_register_client(&jbt->fb_notif); ++ if (rc < 0) { ++ dev_err(&spi->dev, "cannot register notifier\n"); ++ goto err_sysfs; ++ } ++ ++ if (pdata->probe_completed) ++ (pdata->probe_completed)(&spi->dev); ++ ++ return 0; ++ ++err_sysfs: ++ sysfs_remove_group(&spi->dev.kobj, &jbt_attr_group); ++err_standby: ++ jbt6k74_enter_state(jbt, JBT_STATE_DEEP_STANDBY); ++err_free_drvdata: ++ dev_set_drvdata(&spi->dev, NULL); ++ kfree(jbt); ++ ++ return rc; ++} ++ ++static int __devexit jbt_remove(struct spi_device *spi) ++{ ++ struct jbt_info *jbt = dev_get_drvdata(&spi->dev); ++ ++ /* We don't want to switch off the display in case the user ++ * accidentially onloads the module (whose use count normally is 0) */ ++ jbt6k74_enter_state(jbt, jbt->normal_state); ++ ++ fb_unregister_client(&jbt->fb_notif); ++ sysfs_remove_group(&spi->dev.kobj, &jbt_attr_group); ++ dev_set_drvdata(&spi->dev, NULL); ++ kfree(jbt); ++ ++ return 0; ++} ++ ++#ifdef CONFIG_PM ++static int jbt_suspend(struct spi_device *spi, pm_message_t state) ++{ ++ struct jbt_info *jbt = dev_get_drvdata(&spi->dev); ++ ++ jbt6k74_enter_state(jbt, JBT_STATE_DEEP_STANDBY); ++ ++ dev_info(&spi->dev, "suspended\n"); ++ ++ return 0; ++} ++ ++int jbt6k74_resume(struct spi_device *spi) ++{ ++ struct jbt_info *jbt = dev_get_drvdata(&spi->dev); ++ struct jbt6k74_platform_data *pdata = spi->dev.platform_data; ++ ++ jbt6k74_enter_state(jbt, jbt->normal_state); ++ ++ if (pdata->resuming) ++ (pdata->resuming)(0); ++ ++ dev_info(&spi->dev, "resumed\n"); ++ ++ return 0; ++} ++EXPORT_SYMBOL_GPL(jbt6k74_resume); ++ ++#else ++#define jbt_suspend NULL ++#define jbt6k74_resume NULL ++#endif ++ ++static struct spi_driver jbt6k74_driver = { ++ .driver = { ++ .name = "jbt6k74", ++ .owner = THIS_MODULE, ++ }, ++ ++ .probe = jbt_probe, ++ .remove = __devexit_p(jbt_remove), ++ .suspend = jbt_suspend, ++ .resume = jbt6k74_resume, ++}; ++ ++static int __init jbt_init(void) ++{ ++ return spi_register_driver(&jbt6k74_driver); ++} ++ ++static void __exit jbt_exit(void) ++{ ++ spi_unregister_driver(&jbt6k74_driver); ++} ++ ++MODULE_DESCRIPTION("SPI driver for tpo JBT6K74-AS LCM control interface"); ++MODULE_AUTHOR("Harald Welte <laforge@openmoko.org>"); ++MODULE_LICENSE("GPL"); ++ ++module_init(jbt_init); ++module_exit(jbt_exit); +diff -ruN --exclude='*.orig' --exclude='*.rej' linux-2.6.29-rc3.owrt/drivers/video/display/Kconfig linux-2.6.29-rc3.owrt.om/drivers/video/display/Kconfig +--- linux-2.6.29-rc3.owrt/drivers/video/display/Kconfig 2009-05-10 22:04:48.000000000 +0200 ++++ linux-2.6.29-rc3.owrt.om/drivers/video/display/Kconfig 2009-05-10 22:28:00.000000000 +0200 +@@ -21,4 +21,23 @@ + comment "Display hardware drivers" + depends on DISPLAY_SUPPORT + ++config DISPLAY_JBT6K74 ++ tristate "TPO JBT6K74-AS TFT display ASIC control interface" ++ depends on SPI_MASTER && SYSFS ++ help ++ SPI driver for the control interface of TFT panels containing ++ the TPO JBT6K74-AS controller ASIC, such as the TPO TD028TTEC1 ++ TFT diplay module used in the FIC/Openmoko Neo1973 GSM phones. ++ ++ The control interface is required for display operation, as it ++ controls power management, display timing and gamma calibration. ++ ++config DISPLAY_L1K002 ++ tristate "TP0 L1K0-02 TFT ASIC control interface" ++ depends on SPI_MASTER && SYSFS ++ help ++ The control interface of this LTPS TFT panel is based on SPI bitbang driver. ++ It controls display timing and gamma calibration. TP0 LPJ028T007A LCM uses this IC ++ as its controller in the Openmoko GTA03 GSM phone. ++ + endmenu +diff -ruN --exclude='*.orig' --exclude='*.rej' linux-2.6.29-rc3.owrt/drivers/video/display/l1k002.c linux-2.6.29-rc3.owrt.om/drivers/video/display/l1k002.c +--- linux-2.6.29-rc3.owrt/drivers/video/display/l1k002.c 1970-01-01 01:00:00.000000000 +0100 ++++ linux-2.6.29-rc3.owrt.om/drivers/video/display/l1k002.c 2009-05-10 22:28:00.000000000 +0200 +@@ -0,0 +1,278 @@ ++/* ++ * Copyright (C) 2009 Openmoko, Inc. ++ * ++ * Author: Matt Hsu <matt_hsu@openmoko.org> ++ * ++ * 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, MA 02111-1307 USA. ++ * ++*/ ++ ++#include <linux/kernel.h> ++#include <linux/device.h> ++#include <linux/module.h> ++#include <linux/platform_device.h> ++#include <linux/spi/spi.h> ++ ++#include <linux/l1k002.h> ++ ++struct l1k002_data { ++ struct spi_device *spi; ++ struct mutex lock; ++ u8 mosi_buf[2]; ++ u8 reg_cache[0x40]; ++}; ++ ++enum l1k002_regs_table { ++ ++ L1K002_REG_SYNCP_SEL = 0x02, ++ L1K002_REG_VSTS = 0x03, ++ L1K002_REG_HSTS = 0x04, ++ L1K002_REG_MISC = 0x07, ++ L1K002_REG_CMDR = 0x08, ++ L1K002_REG_IN_DATA_TIMING = 0x09, ++ L1K002_REG_ENGR_OTP = 0x0b, ++ L1K002_REG_VGLS = 0x0c, ++ L1K002_REG_DISP_8_9 = 0x0d, ++ L1K002_REG_DISP_0_7 = 0x0e, ++ L1K002_REG_HTOTAL_8_10 = 0x0f, ++ L1K002_REG_HTOTAL_0_7 = 0x10, ++ L1K002_REG_WCKH = 0x20, ++ L1K002_REG_GCKH = 0x21, ++ L1K002_REG_DCKH = 0x22, ++ L1K002_REG_WENBV = 0x23, ++ L1K002_REG_DCKV = 0x25, ++ L1K002_REG_WCKV = 0x27, ++ L1K002_REG_DA_VCOM = 0x2a, ++ L1K002_REG_PVH = 0x2b, ++ L1K002_REG_NVH_NVL = 0x2c, ++ L1K002_REG_GC1 = 0x2d, ++ L1K002_REG_GC2 = 0x2e, ++ L1K002_REG_GC3 = 0x2f, ++ L1K002_REG_GC4 = 0x30, ++ L1K002_REG_GC5 = 0x31, ++ L1K002_REG_GC6 = 0x32, ++ L1K002_REG_GC7 = 0x33, ++ L1K002_REG_GC8 = 0x34, ++ L1K002_REG_GC9 = 0x35, ++ L1K002_REG_GC10 = 0x36, ++ L1K002_REG_GC11 = 0x37, ++ L1K002_REG_GC12 = 0x38, ++ L1K002_REG_GC13 = 0x39, ++ L1K002_REG_GC14 = 0x3a, ++ L1K002_REG_GC15 = 0x3b, ++}; ++ ++static int l1k002_reg_write(struct l1k002_data *l1k002, u8 reg, u8 data) ++{ ++ int ret; ++ ++ mutex_lock(&l1k002->lock); ++ ++ l1k002->mosi_buf[0] = reg; ++ l1k002->mosi_buf[1] = data; ++ ++ ret = spi_write(l1k002->spi, (u8 *)l1k002->mosi_buf, 2*sizeof(u8)); ++ if (ret == 0) ++ l1k002->reg_cache[reg] = data; ++ else ++ dev_err(&l1k002->spi->dev, "reg spi_write ret: %d\n", ret); ++ ++ mutex_unlock(&l1k002->lock); ++ return ret; ++} ++ ++static int l1k002_init_reg(struct l1k002_data *l1k002) ++{ ++ int ret; ++ ++ /* software reset */ ++ ret = l1k002_reg_write(l1k002, L1K002_REG_CMDR, 0x01); ++ ret |= l1k002_reg_write(l1k002, L1K002_REG_CMDR, 0x00); ++ ++ /* setup color mode and direction */ ++ ret |= l1k002_reg_write(l1k002, L1K002_REG_MISC, 0xd9); ++ ++ /* dclk initial */ ++ ret |= l1k002_reg_write(l1k002, L1K002_REG_SYNCP_SEL, 0x00); ++ ++ /* start vertical data */ ++ ret |= l1k002_reg_write(l1k002, L1K002_REG_VSTS, 0x04); ++ ++ /* start horizonal data */ ++ ret |= l1k002_reg_write(l1k002, L1K002_REG_HSTS, 0x14); ++ ++ /* setup hsnc, vsnc, data_enable */ ++ ret |= l1k002_reg_write(l1k002, L1K002_REG_IN_DATA_TIMING, 0x03); ++ /* enable engineering mode and OTP */ ++ ret |= l1k002_reg_write(l1k002, L1K002_REG_ENGR_OTP, 0x18); ++ ++ /* display area */ ++ ret |= l1k002_reg_write(l1k002, L1K002_REG_VGLS, 0x41); ++ ret |= l1k002_reg_write(l1k002, L1K002_REG_DISP_8_9, 0x02); ++ ret |= l1k002_reg_write(l1k002, L1K002_REG_DISP_0_7, 0x80); ++ ret |= l1k002_reg_write(l1k002, L1K002_REG_HTOTAL_8_10, 0x02); ++ ret |= l1k002_reg_write(l1k002, L1K002_REG_HTOTAL_0_7, 0x08); ++ ++ /* CKH pulse config */ ++ ret |= l1k002_reg_write(l1k002, L1K002_REG_WCKH, 0x3c); ++ ret |= l1k002_reg_write(l1k002, L1K002_REG_GCKH, 0x0c); ++ ret |= l1k002_reg_write(l1k002, L1K002_REG_DCKH, 0x10); ++ ++ /* ENBV config */ ++ ret |= l1k002_reg_write(l1k002, L1K002_REG_WENBV, 0x38); ++ ret |= l1k002_reg_write(l1k002, L1K002_REG_DCKV, 0x3c); ++ ret |= l1k002_reg_write(l1k002, L1K002_REG_WCKV, 0xdb); ++ ++ /* driving voltage */ ++ ret |= l1k002_reg_write(l1k002, L1K002_REG_DA_VCOM, 0x66); ++ ++ /* gamma output voltage level */ ++ ret |= l1k002_reg_write(l1k002, L1K002_REG_PVH, 0x70); ++ ret |= l1k002_reg_write(l1k002, L1K002_REG_NVH_NVL, 0x70); ++ ++ /* gamma correction */ ++ ret |= l1k002_reg_write(l1k002, L1K002_REG_GC1, 0x15); ++ ret |= l1k002_reg_write(l1k002, L1K002_REG_GC2, 0xaa); ++ ret |= l1k002_reg_write(l1k002, L1K002_REG_GC3, 0xbf); ++ ret |= l1k002_reg_write(l1k002, L1K002_REG_GC4, 0x86); ++ ret |= l1k002_reg_write(l1k002, L1K002_REG_GC5, 0x11); ++ ret |= l1k002_reg_write(l1k002, L1K002_REG_GC6, 0x5e); ++ ret |= l1k002_reg_write(l1k002, L1K002_REG_GC7, 0xb6); ++ ret |= l1k002_reg_write(l1k002, L1K002_REG_GC8, 0x16); ++ ret |= l1k002_reg_write(l1k002, L1K002_REG_GC9, 0x4e); ++ ret |= l1k002_reg_write(l1k002, L1K002_REG_GC10, 0x78); ++ ret |= l1k002_reg_write(l1k002, L1K002_REG_GC11, 0xbf); ++ ret |= l1k002_reg_write(l1k002, L1K002_REG_GC12, 0xec); ++ ret |= l1k002_reg_write(l1k002, L1K002_REG_GC13, 0x10); ++ ret |= l1k002_reg_write(l1k002, L1K002_REG_GC14, 0x30); ++ ret |= l1k002_reg_write(l1k002, L1K002_REG_GC15, 0xff); ++ ++ ret |= l1k002_reg_write(l1k002, 0x07, 0xc9); ++ ++ if (ret == 0) ++ dev_info(&l1k002->spi->dev, "initialize OK \n"); ++ else ++ dev_err(&l1k002->spi->dev, "initialize failed ret: %d\n", ret); ++ return ret; ++} ++ ++static int l1k002_probe(struct spi_device *spi) ++{ ++ int ret; ++ struct l1k002_data *l1k002; ++ struct l1k002_platform_data *l1k002_pdata = spi->dev.platform_data; ++ ++ if (l1k002_pdata == NULL) { ++ dev_err(&spi->dev, ++ "no platform data available \n"); ++ return -EINVAL; ++ } ++ ++ spi->mode = SPI_CPOL | SPI_CPHA; ++ spi->bits_per_word = 8; ++ ++ ret = spi_setup(spi); ++ if (ret < 0) { ++ dev_err(&spi->dev, ++ "error during spi_setup of l1k002 driver\n"); ++ return ret; ++ } ++ ++ l1k002 = kzalloc(sizeof(*l1k002), GFP_KERNEL); ++ if (!l1k002) ++ return -ENOMEM; ++ ++ l1k002->spi = spi; ++ dev_set_drvdata(&spi->dev, l1k002); ++ ++ mutex_init(&l1k002->lock); ++ ++ /* hard reset l1k002 */ ++ (l1k002_pdata->pwr_onoff)(1); ++ ++ ret = l1k002_init_reg(l1k002); ++ if (ret) ++ goto err_free; ++ ++ /* FIXME: sysfs should be added here */ ++ ++ return 0; ++ ++err_free: ++ kfree(l1k002); ++ return ret; ++} ++ ++static int __devexit l1k002_remove(struct spi_device *spi) ++{ ++ struct l1k002 *l1k002 = dev_get_drvdata(&spi->dev); ++ ++ dev_set_drvdata(&spi->dev, NULL); ++ kfree(l1k002); ++ return 0; ++} ++ ++#ifdef CONFIG_PM ++static int l1k002_suspend(struct spi_device *spi, pm_message_t state) ++{ ++ struct l1k002_platform_data *l1k002_pdata = spi->dev.platform_data; ++ ++ /* l1k002 doesn't have sleep mode ++ * it should be powered down as entering suspend state ++ */ ++ (l1k002_pdata->pwr_onoff)(0); ++ return 0; ++} ++ ++static int l1k002_resume(struct spi_device *spi) ++{ ++ struct l1k002_platform_data *l1k002_pdata = spi->dev.platform_data; ++ struct l1k002_data *l1k002 = dev_get_drvdata(&spi->dev); ++ ++ (l1k002_pdata->pwr_onoff)(1); ++ return l1k002_init_reg(l1k002); ++} ++#else ++#define l1k002_suspend NULL ++#define l1k002_resume NULL ++#endif ++ ++static struct spi_driver l1k002_driver = { ++ .driver = { ++ .name = "l1k002", ++ .owner = THIS_MODULE, ++ }, ++ ++ .probe = l1k002_probe, ++ .remove = __devexit_p(l1k002_remove), ++ .suspend = l1k002_suspend, ++ .resume = l1k002_resume, ++}; ++ ++static int __init l1k002_init(void) ++{ ++ return spi_register_driver(&l1k002_driver); ++} ++ ++static void __exit l1k002_exit(void) ++{ ++ spi_unregister_driver(&l1k002_driver); ++} ++ ++MODULE_AUTHOR("Matt Hsu <matt_hsu@openmoko.org>"); ++MODULE_LICENSE("GPL v2"); ++ ++module_init(l1k002_init); ++module_exit(l1k002_exit); +diff -ruN --exclude='*.orig' --exclude='*.rej' linux-2.6.29-rc3.owrt/drivers/video/display/Makefile linux-2.6.29-rc3.owrt.om/drivers/video/display/Makefile +--- linux-2.6.29-rc3.owrt/drivers/video/display/Makefile 2009-05-10 22:04:48.000000000 +0200 ++++ linux-2.6.29-rc3.owrt.om/drivers/video/display/Makefile 2009-05-10 22:28:00.000000000 +0200 +@@ -3,4 +3,6 @@ + display-objs := display-sysfs.o + + obj-$(CONFIG_DISPLAY_SUPPORT) += display.o ++obj-$(CONFIG_DISPLAY_JBT6K74) += jbt6k74.o ++obj-$(CONFIG_DISPLAY_L1K002) += l1k002.o + +diff -ruN --exclude='*.orig' --exclude='*.rej' linux-2.6.29-rc3.owrt/drivers/video/Kconfig linux-2.6.29-rc3.owrt.om/drivers/video/Kconfig +--- linux-2.6.29-rc3.owrt/drivers/video/Kconfig 2009-05-10 22:08:45.000000000 +0200 ++++ linux-2.6.29-rc3.owrt.om/drivers/video/Kconfig 2009-05-10 22:28:00.000000000 +0200 +@@ -1924,6 +1924,30 @@ + depends on FB_TMIO + default y + ++config FB_S3C ++ tristate "Samsung S3C framebuffer support" ++ depends on FB && ARCH_S3C64XX ++ select FB_CFB_FILLRECT ++ select FB_CFB_COPYAREA ++ select FB_CFB_IMAGEBLIT ++ ---help--- ++ Frame buffer driver for the built-in FB controller in the Samsung ++ SoC line from the S3C2443 onwards, including the S3C2416, S3C2450, ++ and the S3C64XX series such as the S3C6400 and S3C6410. ++ ++ These chips all have the same basic framebuffer design with the ++ actual capabilities depending on the chip. For instance the S3C6400 ++ and S3C6410 support 4 hardware windows whereas the S3C24XX series ++ currently only have two. ++ ++ Currently the support is only for the S3C6400 and S3C6410 SoCs. ++ ++config FB_S3C_DEBUG_REGWRITE ++ bool "Debug register writes" ++ depends on FB_S3C ++ ---help--- ++ Show all register writes via printk(KERN_DEBUG) ++ + config FB_S3C2410 + tristate "S3C2410 LCD framebuffer support" + depends on FB && ARCH_S3C2410 +diff -ruN --exclude='*.orig' --exclude='*.rej' linux-2.6.29-rc3.owrt/drivers/video/logo/Kconfig linux-2.6.29-rc3.owrt.om/drivers/video/logo/Kconfig +--- linux-2.6.29-rc3.owrt/drivers/video/logo/Kconfig 2009-05-10 22:04:48.000000000 +0200 ++++ linux-2.6.29-rc3.owrt.om/drivers/video/logo/Kconfig 2009-05-10 22:28:00.000000000 +0200 +@@ -77,6 +77,11 @@ + depends on SUPERH + default y + ++config LOGO_OPENMOKO_CLUT224 ++ bool "224-color Openmoko Linux logo" ++ depends on MACH_NEO1973_GTA01 || MACH_NEO1973_GTA02 ++ default y ++ + config LOGO_M32R_CLUT224 + bool "224-color M32R Linux logo" + depends on M32R +diff -ruN --exclude='*.orig' --exclude='*.rej' linux-2.6.29-rc3.owrt/drivers/video/logo/logo.c linux-2.6.29-rc3.owrt.om/drivers/video/logo/logo.c +--- linux-2.6.29-rc3.owrt/drivers/video/logo/logo.c 2009-05-10 22:04:48.000000000 +0200 ++++ linux-2.6.29-rc3.owrt.om/drivers/video/logo/logo.c 2009-05-10 22:28:00.000000000 +0200 +@@ -35,6 +35,7 @@ + extern const struct linux_logo logo_superh_vga16; + extern const struct linux_logo logo_superh_clut224; + extern const struct linux_logo logo_m32r_clut224; ++extern const struct linux_logo logo_openmoko_clut224; + + static int nologo; + module_param(nologo, bool, 0); +@@ -115,6 +116,10 @@ + /* M32R Linux logo */ + logo = &logo_m32r_clut224; + #endif ++#ifdef CONFIG_LOGO_OPENMOKO_CLUT224 ++ /* Openmoko Linux logo */ ++ logo = &logo_openmoko_clut224; ++#endif + } + return logo; + } +diff -ruN --exclude='*.orig' --exclude='*.rej' linux-2.6.29-rc3.owrt/drivers/video/logo/Makefile linux-2.6.29-rc3.owrt.om/drivers/video/logo/Makefile +--- linux-2.6.29-rc3.owrt/drivers/video/logo/Makefile 2009-05-10 22:04:48.000000000 +0200 ++++ linux-2.6.29-rc3.owrt.om/drivers/video/logo/Makefile 2009-05-10 22:28:00.000000000 +0200 +@@ -15,6 +15,7 @@ + obj-$(CONFIG_LOGO_SUPERH_VGA16) += logo_superh_vga16.o + obj-$(CONFIG_LOGO_SUPERH_CLUT224) += logo_superh_clut224.o + obj-$(CONFIG_LOGO_M32R_CLUT224) += logo_m32r_clut224.o ++obj-$(CONFIG_LOGO_OPENMOKO_CLUT224) += logo_openmoko_clut224.o + + obj-$(CONFIG_SPU_BASE) += logo_spe_clut224.o + +diff -ruN --exclude='*.orig' --exclude='*.rej' linux-2.6.29-rc3.owrt/drivers/video/Makefile linux-2.6.29-rc3.owrt.om/drivers/video/Makefile +--- linux-2.6.29-rc3.owrt/drivers/video/Makefile 2009-05-10 22:04:48.000000000 +0200 ++++ linux-2.6.29-rc3.owrt.om/drivers/video/Makefile 2009-05-10 22:28:00.000000000 +0200 +@@ -109,6 +109,7 @@ + obj-$(CONFIG_FB_S1D13XXX) += s1d13xxxfb.o + obj-$(CONFIG_FB_SH7760) += sh7760fb.o + obj-$(CONFIG_FB_IMX) += imxfb.o ++obj-$(CONFIG_FB_S3C) += s3c-fb.o + obj-$(CONFIG_FB_S3C2410) += s3c2410fb.o + obj-$(CONFIG_FB_FSL_DIU) += fsl-diu-fb.o + obj-$(CONFIG_FB_COBALT) += cobalt_lcdfb.o +diff -ruN --exclude='*.orig' --exclude='*.rej' linux-2.6.29-rc3.owrt/drivers/video/s3c2410fb.c linux-2.6.29-rc3.owrt.om/drivers/video/s3c2410fb.c +--- linux-2.6.29-rc3.owrt/drivers/video/s3c2410fb.c 2009-05-10 22:04:48.000000000 +0200 ++++ linux-2.6.29-rc3.owrt.om/drivers/video/s3c2410fb.c 2009-05-10 22:28:00.000000000 +0200 +@@ -1017,6 +1017,8 @@ + + s3c2410fb_init_registers(fbinfo); + ++ s3c2410fb_set_par(fbinfo); ++ + return 0; + } + +diff -ruN --exclude='*.orig' --exclude='*.rej' linux-2.6.29-rc3.owrt/drivers/video/s3c-fb.c linux-2.6.29-rc3.owrt.om/drivers/video/s3c-fb.c +--- linux-2.6.29-rc3.owrt/drivers/video/s3c-fb.c 1970-01-01 01:00:00.000000000 +0100 ++++ linux-2.6.29-rc3.owrt.om/drivers/video/s3c-fb.c 2009-05-10 22:28:00.000000000 +0200 +@@ -0,0 +1,1036 @@ ++/* linux/drivers/video/s3c-fb.c ++ * ++ * Copyright 2008 Openmoko Inc. ++ * Copyright 2008 Simtec Electronics ++ * Ben Dooks <ben@simtec.co.uk> ++ * http://armlinux.simtec.co.uk/ ++ * ++ * Samsung SoC Framebuffer driver ++ * ++ * 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/platform_device.h> ++#include <linux/dma-mapping.h> ++#include <linux/init.h> ++#include <linux/gfp.h> ++#include <linux/clk.h> ++#include <linux/fb.h> ++#include <linux/io.h> ++ ++#include <mach/map.h> ++#include <mach/regs-fb.h> ++#include <plat/fb.h> ++ ++/* This driver will export a number of framebuffer interfaces depending ++ * on the configuration passed in via the platform data. Each fb instance ++ * maps to a hardware window. Currently there is no support for runtime ++ * setting of the alpha-blending functions that each window has, so only ++ * window 0 is actually useful. ++ * ++ * Window 0 is treated specially, it is used for the basis of the LCD ++ * output timings and as the control for the output power-down state. ++*/ ++ ++/* note, some of the functions that get called are derived from including ++ * <mach/regs-fb.h> as they are specific to the architecture that the code ++ * is being built for. ++*/ ++ ++#ifdef CONFIG_FB_S3C_DEBUG_REGWRITE ++#undef writel ++#define writel(v, r) do { \ ++ printk(KERN_DEBUG "%s: %08x => %p\n", __func__, (unsigned int)v, r); \ ++ __raw_writel(v, r); } while(0) ++#endif /* FB_S3C_DEBUG_REGWRITE */ ++ ++struct s3c_fb; ++ ++/** ++ * struct s3c_fb_win - per window private data for each framebuffer. ++ * @windata: The platform data supplied for the window configuration. ++ * @parent: The hardware that this window is part of. ++ * @fbinfo: Pointer pack to the framebuffer info for this window. ++ * @palette_buffer: Buffer/cache to hold palette entries. ++ * @pseudo_palette: For use in TRUECOLOUR modes for entries 0..15/ ++ * @index: The window number of this window. ++ * @palette: The bitfields for changing r/g/b into a hardware palette entry. ++ */ ++struct s3c_fb_win { ++ struct s3c_fb_pd_win *windata; ++ struct s3c_fb *parent; ++ struct fb_info *fbinfo; ++ struct s3c_fb_palette palette; ++ ++ u32 *palette_buffer; ++ u32 pseudo_palette[16]; ++ unsigned int index; ++}; ++ ++/** ++ * struct s3c_fb - overall hardware state of the hardware ++ * @dev: The device that we bound to, for printing, etc. ++ * @regs_res: The resource we claimed for the IO registers. ++ * @bus_clk: The clk (hclk) feeding our interface and possibly pixclk. ++ * @regs: The mapped hardware registers. ++ * @enabled: A bitmask of enabled hardware windows. ++ * @pdata: The platform configuration data passed with the device. ++ * @windows: The hardware windows that have been claimed. ++ */ ++struct s3c_fb { ++ struct device *dev; ++ struct resource *regs_res; ++ struct clk *bus_clk; ++ void __iomem *regs; ++ ++ unsigned char enabled; ++ ++ struct s3c_fb_platdata *pdata; ++ struct s3c_fb_win *windows[S3C_FB_MAX_WIN]; ++}; ++ ++/** ++ * s3c_fb_win_has_palette() - determine if a mode has a palette ++ * @win: The window number being queried. ++ * @bpp: The number of bits per pixel to test. ++ * ++ * Work out if the given window supports palletised data at the specified bpp. ++ */ ++static int s3c_fb_win_has_palette(unsigned int win, unsigned int bpp) ++{ ++ return s3c_fb_win_pal_size(win) <= (1 << bpp); ++} ++ ++/** ++ * s3c_fb_check_var() - framebuffer layer request to verify a given mode. ++ * @var: The screen information to verify. ++ * @info: The framebuffer device. ++ * ++ * Framebuffer layer call to verify the given information and allow us to ++ * update various information depending on the hardware capabilities. ++ */ ++static int s3c_fb_check_var(struct fb_var_screeninfo *var, ++ struct fb_info *info) ++{ ++ struct s3c_fb_win *win = info->par; ++ struct s3c_fb_pd_win *windata = win->windata; ++ struct s3c_fb *sfb = win->parent; ++ ++ dev_dbg(sfb->dev, "checking parameters\n"); ++ ++ var->xres_virtual = max((unsigned int)windata->virtual_x, var->xres); ++ var->yres_virtual = max((unsigned int)windata->virtual_y, var->yres); ++ ++ if (!s3c_fb_validate_win_bpp(win->index, var->bits_per_pixel)) { ++ dev_dbg(sfb->dev, "win %d: unsupported bpp %d\n", ++ win->index, var->bits_per_pixel); ++ return -EINVAL; ++ } ++ ++ /* always ensure these are zero, for drop through cases below */ ++ var->transp.offset = 0; ++ var->transp.length = 0; ++ ++ switch (var->bits_per_pixel) { ++ case 1: ++ case 2: ++ case 4: ++ case 8: ++ if (!s3c_fb_win_has_palette(win->index, var->bits_per_pixel)) { ++ /* non palletised, A:1,R:2,G:3,B:2 mode */ ++ var->red.offset = 4; ++ var->green.offset = 2; ++ var->blue.offset = 0; ++ var->red.length = 5; ++ var->green.length = 3; ++ var->blue.length = 2; ++ var->transp.offset = 7; ++ var->transp.length = 1; ++ } else { ++ var->red.offset = 0; ++ var->red.length = var->bits_per_pixel; ++ var->green = var->red; ++ var->blue = var->red; ++ } ++ break; ++ ++ case 19: ++ /* 666 with one bit alpha/transparency */ ++ var->transp.offset = 18; ++ var->transp.length = 1; ++ case 18: ++ var->bits_per_pixel = 32; ++ ++ /* 666 format */ ++ var->red.offset = 12; ++ var->green.offset = 6; ++ var->blue.offset = 0; ++ var->red.length = 6; ++ var->green.length = 6; ++ var->blue.length = 6; ++ break; ++ ++ case 16: ++ /* 16 bpp, 565 format */ ++ var->red.offset = 11; ++ var->green.offset = 5; ++ var->blue.offset = 0; ++ var->red.length = 5; ++ var->green.length = 6; ++ var->blue.length = 5; ++ break; ++ ++ case 28: ++ case 25: ++ var->transp.length = var->bits_per_pixel - 24; ++ var->transp.offset = 24; ++ /* drop through */ ++ case 24: ++ /* our 24bpp is unpacked, so 32bpp */ ++ var->bits_per_pixel = 32; ++ case 32: ++ var->red.offset = 16; ++ var->red.length = 8; ++ var->green.offset = 8; ++ var->green.length = 8; ++ var->blue.offset = 0; ++ var->blue.length = 8; ++ break; ++ ++ default: ++ dev_err(sfb->dev, "invalid bpp\n"); ++ } ++ ++ dev_dbg(sfb->dev, "%s: verified parameters\n", __func__); ++ return 0; ++} ++ ++/** ++ * s3c_fb_calc_pixclk() - calculate the divider to create the pixel clock. ++ * @sfb: The hardware state. ++ * @pixclock: The pixel clock wanted, in picoseconds. ++ * ++ * Given the specified pixel clock, work out the necessary divider to get ++ * close to the output frequency. ++ */ ++static int s3c_fb_calc_pixclk(struct s3c_fb *sfb, unsigned int pixclk) ++{ ++ unsigned long clk = clk_get_rate(sfb->bus_clk); ++ unsigned long long tmp; ++ unsigned int result; ++ ++ tmp = (unsigned long long)clk; ++ tmp *= pixclk; ++ ++ do_div(tmp, 1000000000UL); ++ result = (unsigned int)tmp / 1000; ++ ++ dev_dbg(sfb->dev, "pixclk=%u, clk=%lu, div=%d (%lu)\n", ++ pixclk, clk, result, clk / result); ++ ++ return result; ++} ++ ++/** ++ * s3c_fb_align_word() - align pixel count to word boundary ++ * @bpp: The number of bits per pixel ++ * @pix: The value to be aligned. ++ * ++ * Align the given pixel count so that it will start on an 32bit word ++ * boundary. ++ */ ++static int s3c_fb_align_word(unsigned int bpp, unsigned int pix) ++{ ++ int pix_per_word; ++ ++ if (bpp > 16) ++ return pix; ++ ++ pix_per_word = (8 * 32) / bpp; ++ return ALIGN(pix, pix_per_word); ++} ++ ++/** ++ * s3c_fb_set_par() - framebuffer request to set new framebuffer state. ++ * @info: The framebuffer to change. ++ * ++ * Framebuffer layer request to set a new mode for the specified framebuffer ++ */ ++static int s3c_fb_set_par(struct fb_info *info) ++{ ++ struct fb_var_screeninfo *var = &info->var; ++ struct s3c_fb_win *win = info->par; ++ struct s3c_fb *sfb = win->parent; ++ void __iomem *regs = sfb->regs; ++ int win_no = win->index; ++ u32 data; ++ u32 pagewidth; ++ int clkdiv; ++ ++ dev_dbg(sfb->dev, "setting framebuffer parameters\n"); ++ ++ switch (var->bits_per_pixel) { ++ case 32: ++ case 24: ++ case 16: ++ case 12: ++ info->fix.visual = FB_VISUAL_TRUECOLOR; ++ break; ++ case 8: ++ if (s3c_fb_win_has_palette(win_no, 8)) ++ info->fix.visual = FB_VISUAL_PSEUDOCOLOR; ++ else ++ info->fix.visual = FB_VISUAL_TRUECOLOR; ++ break; ++ case 1: ++ info->fix.visual = FB_VISUAL_MONO01; ++ break; ++ default: ++ info->fix.visual = FB_VISUAL_PSEUDOCOLOR; ++ break; ++ } ++ ++ info->fix.line_length = (var->xres_virtual * var->bits_per_pixel) / 8; ++ ++ /* disable the window whilst we update it */ ++ writel(0, regs + WINCON(win_no)); ++ ++ /* use window 0 as the basis for the lcd output timings */ ++ ++ if (win_no == 0) { ++ clkdiv = s3c_fb_calc_pixclk(sfb, var->pixclock); ++ ++ data = sfb->pdata->vidcon0; ++ data &= ~(VIDCON0_CLKVAL_F_MASK | VIDCON0_CLKDIR); ++ ++ if (clkdiv > 1) ++ data |= VIDCON0_CLKVAL_F(clkdiv-1) | VIDCON0_CLKDIR; ++ else ++ data &= ~VIDCON0_CLKDIR; /* 1:1 clock */ ++ ++ /* write the timing data to the panel */ ++ ++ data |= VIDCON0_ENVID | VIDCON0_ENVID_F; ++ writel(data, regs + VIDCON0); ++ ++ data = VIDTCON0_VBPD(var->upper_margin - 1) | ++ VIDTCON0_VFPD(var->lower_margin - 1) | ++ VIDTCON0_VSPW(var->vsync_len - 1); ++ ++ writel(data, regs + VIDTCON0); ++ ++ data = VIDTCON1_HBPD(var->left_margin - 1) | ++ VIDTCON1_HFPD(var->right_margin - 1) | ++ VIDTCON1_HSPW(var->hsync_len - 1); ++ ++ writel(data, regs + VIDTCON1); ++ ++ data = VIDTCON2_LINEVAL(var->yres - 1) | ++ VIDTCON2_HOZVAL(var->xres - 1); ++ writel(data, regs + VIDTCON2); ++ } ++ ++ /* write the buffer address */ ++ ++ writel(info->fix.smem_start, regs + VIDW_BUF_START(win_no)); ++ ++ data = info->fix.smem_start + info->fix.line_length * var->yres; ++ writel(data, regs + VIDW_BUF_END(win_no)); ++ ++ pagewidth = (var->xres * var->bits_per_pixel) >> 3; ++ data = VIDW_BUF_SIZE_OFFSET(info->fix.line_length - pagewidth) | ++ VIDW_BUF_SIZE_PAGEWIDTH(pagewidth); ++ writel(data, regs + VIDW_BUF_SIZE(win_no)); ++ ++ /* write 'OSD' registers to control position of framebuffer */ ++ ++ data = VIDOSDxA_TOPLEFT_X(0) | VIDOSDxA_TOPLEFT_Y(0); ++ writel(data, regs + VIDOSD_A(win_no)); ++ ++ data = VIDOSDxB_BOTRIGHT_X(s3c_fb_align_word(var->bits_per_pixel, ++ var->xres - 1)) | ++ VIDOSDxB_BOTRIGHT_Y(var->yres - 1); ++ ++ writel(data, regs + VIDOSD_B(win_no)); ++ ++ data = var->xres * var->yres; ++ if (s3c_fb_has_osd_d(win_no)) { ++ writel(data, regs + VIDOSD_D(win_no)); ++ writel(0, regs + VIDOSD_C(win_no)); ++ } else ++ writel(data, regs + VIDOSD_C(win_no)); ++ ++ data = WINCONx_ENWIN; ++ ++ /* note, since we have to round up the bits-per-pixel, we end up ++ * relying on the bitfield information for r/g/b/a to work out ++ * exactly which mode of operation is intended. */ ++ ++ switch (var->bits_per_pixel) { ++ case 1: ++ data |= WINCON0_BPPMODE_1BPP; ++ data |= WINCONx_BITSWP; ++ data |= WINCONx_BURSTLEN_4WORD; ++ break; ++ case 2: ++ data |= WINCON0_BPPMODE_2BPP; ++ data |= WINCONx_BITSWP; ++ data |= WINCONx_BURSTLEN_8WORD; ++ break; ++ case 4: ++ data |= WINCON0_BPPMODE_4BPP; ++ data |= WINCONx_BITSWP; ++ data |= WINCONx_BURSTLEN_8WORD; ++ break; ++ case 8: ++ if (var->transp.length != 0) ++ data |= WINCON1_BPPMODE_8BPP_1232; ++ else ++ data |= WINCON0_BPPMODE_8BPP_PALETTE; ++ data |= WINCONx_BURSTLEN_8WORD; ++ data |= WINCONx_BYTSWP; ++ break; ++ case 16: ++ if (var->transp.length != 0) ++ data |= WINCON1_BPPMODE_16BPP_A1555; ++ else ++ data |= WINCON0_BPPMODE_16BPP_565; ++ data |= WINCONx_HAWSWP; ++ data |= WINCONx_BURSTLEN_16WORD; ++ break; ++ case 24: ++ case 32: ++ if (var->red.length == 6) { ++ if (var->transp.length != 0) ++ data |= WINCON1_BPPMODE_19BPP_A1666; ++ else ++ data |= WINCON1_BPPMODE_18BPP_666; ++ } else if (var->transp.length != 0) ++ data |= WINCON1_BPPMODE_25BPP_A1888; ++ else ++ data |= WINCON0_BPPMODE_24BPP_888; ++ ++ data |= WINCONx_BURSTLEN_16WORD; ++ break; ++ } ++ ++ writel(data, regs + WINCON(win_no)); ++ writel(0x0, regs + WINxMAP(win_no)); ++ ++ return 0; ++} ++ ++/** ++ * s3c_fb_update_palette() - set or schedule a palette update. ++ * @sfb: The hardware information. ++ * @win: The window being updated. ++ * @reg: The palette index being changed. ++ * @value: The computed palette value. ++ * ++ * Change the value of a palette register, either by directly writing to ++ * the palette (this requires the palette RAM to be disconnected from the ++ * hardware whilst this is in progress) or schedule the update for later. ++ * ++ * At the moment, since we have no VSYNC interrupt support, we simply set ++ * the palette entry directly. ++ */ ++static void s3c_fb_update_palette(struct s3c_fb *sfb, ++ struct s3c_fb_win *win, ++ unsigned int reg, ++ u32 value) ++{ ++ void __iomem *palreg; ++ u32 palcon; ++ ++ palreg = sfb->regs + s3c_fb_pal_reg(win->index, reg); ++ ++ dev_dbg(sfb->dev, "%s: win %d, reg %d (%p): %08x\n", ++ __func__, win->index, reg, palreg, value); ++ ++ win->palette_buffer[reg] = value; ++ ++ palcon = readl(sfb->regs + WPALCON); ++ writel(palcon | WPALCON_PAL_UPDATE, sfb->regs + WPALCON); ++ ++ if (s3c_fb_pal_is16(win->index)) ++ writew(value, palreg); ++ else ++ writel(value, palreg); ++ ++ writel(palcon, sfb->regs + WPALCON); ++} ++ ++static inline unsigned int chan_to_field(unsigned int chan, ++ struct fb_bitfield *bf) ++{ ++ chan &= 0xffff; ++ chan >>= 16 - bf->length; ++ return chan << bf->offset; ++} ++ ++/** ++ * s3c_fb_setcolreg() - framebuffer layer request to change palette. ++ * @regno: The palette index to change. ++ * @red: The red field for the palette data. ++ * @green: The green field for the palette data. ++ * @blue: The blue field for the palette data. ++ * @trans: The transparency (alpha) field for the palette data. ++ * @info: The framebuffer being changed. ++ */ ++static int s3c_fb_setcolreg(unsigned regno, ++ unsigned red, unsigned green, unsigned blue, ++ unsigned transp, struct fb_info *info) ++{ ++ struct s3c_fb_win *win = info->par; ++ struct s3c_fb *sfb = win->parent; ++ unsigned int val; ++ ++ dev_dbg(sfb->dev, "%s: win %d: %d => rgb=%d/%d/%d\n", ++ __func__, win->index, regno, red, green, blue); ++ ++ switch (info->fix.visual) { ++ case FB_VISUAL_TRUECOLOR: ++ /* true-colour, use pseudo-palette */ ++ ++ if (regno < 16) { ++ u32 *pal = info->pseudo_palette; ++ ++ val = chan_to_field(red, &info->var.red); ++ val |= chan_to_field(green, &info->var.green); ++ val |= chan_to_field(blue, &info->var.blue); ++ ++ pal[regno] = val; ++ } ++ break; ++ ++ case FB_VISUAL_PSEUDOCOLOR: ++ if (regno < s3c_fb_win_pal_size(win->index)) { ++ val = chan_to_field(red, &win->palette.r); ++ val |= chan_to_field(green, &win->palette.g); ++ val |= chan_to_field(blue, &win->palette.b); ++ ++ s3c_fb_update_palette(sfb, win, regno, val); ++ } ++ ++ break; ++ ++ default: ++ return 1; /* unknown type */ ++ } ++ ++ return 0; ++} ++ ++/** ++ * s3c_fb_enable() - Set the state of the main LCD output ++ * @sfb: The main framebuffer state. ++ * @enable: The state to set. ++ */ ++static void s3c_fb_enable(struct s3c_fb *sfb, int enable) ++{ ++ u32 vidcon0 = readl(sfb->regs + VIDCON0); ++ ++ if (enable) ++ vidcon0 |= VIDCON0_ENVID | VIDCON0_ENVID_F; ++ else { ++ /* see the note in the framebuffer datasheet about ++ * why you cannot take both of these bits down at the ++ * same time. */ ++ ++ if (!(vidcon0 & VIDCON0_ENVID)) ++ return; ++ ++ vidcon0 |= VIDCON0_ENVID; ++ vidcon0 &= ~VIDCON0_ENVID_F; ++ } ++ ++ writel(vidcon0, sfb->regs + VIDCON0); ++} ++ ++/** ++ * s3c_fb_blank() - blank or unblank the given window ++ * @blank_mode: The blank state from FB_BLANK_* ++ * @info: The framebuffer to blank. ++ * ++ * Framebuffer layer request to change the power state. ++ */ ++static int s3c_fb_blank(int blank_mode, struct fb_info *info) ++{ ++ struct s3c_fb_win *win = info->par; ++ struct s3c_fb *sfb = win->parent; ++ unsigned int index = win->index; ++ u32 wincon; ++ ++ dev_dbg(sfb->dev, "blank mode %d\n", blank_mode); ++ ++ wincon = readl(sfb->regs + WINCON(index)); ++ ++ switch (blank_mode) { ++ case FB_BLANK_POWERDOWN: ++ wincon &= ~WINCONx_ENWIN; ++ sfb->enabled &= ~(1 << index); ++ /* fall through to FB_BLANK_NORMAL */ ++ ++ case FB_BLANK_NORMAL: ++ /* disable the DMA and display 0x0 (black) */ ++ writel(WINxMAP_MAP | WINxMAP_MAP_COLOUR(0x0), ++ sfb->regs + WINxMAP(index)); ++ break; ++ ++ case FB_BLANK_UNBLANK: ++ writel(0x0, sfb->regs + WINxMAP(index)); ++ wincon |= WINCONx_ENWIN; ++ sfb->enabled |= (1 << index); ++ break; ++ ++ case FB_BLANK_VSYNC_SUSPEND: ++ case FB_BLANK_HSYNC_SUSPEND: ++ default: ++ return 1; ++ } ++ ++ writel(wincon, sfb->regs + WINCON(index)); ++ ++ /* Check the enabled state to see if we need to be running the ++ * main LCD interface, as if there are no active windows then ++ * it is highly likely that we also do not need to output ++ * anything. ++ */ ++ ++ /* We could do something like the following code, but the current ++ * system of using framebuffer events means that we cannot make ++ * the distinction between just window 0 being inactive and all ++ * the windows being down. ++ * ++ * s3c_fb_enable(sfb, sfb->enabled ? 1 : 0); ++ */ ++ ++ /* we're stuck with this until we can do something about overriding ++ * the power control using the blanking event for a single fb. ++ */ ++ if (index == 0) ++ s3c_fb_enable(sfb, blank_mode != FB_BLANK_POWERDOWN ? 1 : 0); ++ ++ return 0; ++} ++ ++static struct fb_ops s3c_fb_ops = { ++ .owner = THIS_MODULE, ++ .fb_check_var = s3c_fb_check_var, ++ .fb_set_par = s3c_fb_set_par, ++ .fb_blank = s3c_fb_blank, ++ .fb_setcolreg = s3c_fb_setcolreg, ++ .fb_fillrect = cfb_fillrect, ++ .fb_copyarea = cfb_copyarea, ++ .fb_imageblit = cfb_imageblit, ++}; ++ ++/** ++ * s3c_fb_alloc_memory() - allocate display memory for framebuffer window ++ * @sfb: The base resources for the hardware. ++ * @win: The window to initialise memory for. ++ * ++ * Allocate memory for the given framebuffer. ++ */ ++static int __devinit s3c_fb_alloc_memory(struct s3c_fb *sfb, ++ struct s3c_fb_win *win) ++{ ++ struct s3c_fb_pd_win *windata = win->windata; ++ unsigned int real_size, virt_size, size; ++ struct fb_info *fbi = win->fbinfo; ++ dma_addr_t map_dma; ++ ++ dev_dbg(sfb->dev, "allocating memory for display\n"); ++ ++ real_size = windata->win_mode.xres * windata->win_mode.yres; ++ virt_size = windata->virtual_x * windata->virtual_y; ++ ++ dev_dbg(sfb->dev, "real_size=%u (%u.%u), virt_size=%u (%u.%u)\n", ++ real_size, windata->win_mode.xres, windata->win_mode.yres, ++ virt_size, windata->virtual_x, windata->virtual_y); ++ ++ size = (real_size > virt_size) ? real_size : virt_size; ++ size *= (windata->max_bpp > 16) ? 32 : windata->max_bpp; ++ size /= 8; ++ ++ fbi->fix.smem_len = size; ++ size = PAGE_ALIGN(size); ++ ++ dev_dbg(sfb->dev, "want %u bytes for window\n", size); ++ ++ fbi->screen_base = dma_alloc_writecombine(sfb->dev, size, ++ &map_dma, GFP_KERNEL); ++ if (!fbi->screen_base) ++ return -ENOMEM; ++ ++ dev_dbg(sfb->dev, "mapped %x to %p\n", ++ (unsigned int)map_dma, fbi->screen_base); ++ ++ memset(fbi->screen_base, 0x0, size); ++ fbi->fix.smem_start = map_dma; ++ ++ return 0; ++} ++ ++/** ++ * s3c_fb_free_memory() - free the display memory for the given window ++ * @sfb: The base resources for the hardware. ++ * @win: The window to free the display memory for. ++ * ++ * Free the display memory allocated by s3c_fb_alloc_memory(). ++ */ ++static void s3c_fb_free_memory(struct s3c_fb *sfb, struct s3c_fb_win *win) ++{ ++ struct fb_info *fbi = win->fbinfo; ++ ++ dma_free_writecombine(sfb->dev, PAGE_ALIGN(fbi->fix.smem_len), ++ fbi->screen_base, fbi->fix.smem_start); ++} ++ ++/** ++ * s3c_fb_release_win() - release resources for a framebuffer window. ++ * @win: The window to cleanup the resources for. ++ * ++ * Release the resources that where claimed for the hardware window, ++ * such as the framebuffer instance and any memory claimed for it. ++ */ ++static void s3c_fb_release_win(struct s3c_fb *sfb, struct s3c_fb_win *win) ++{ ++ fb_dealloc_cmap(&win->fbinfo->cmap); ++ unregister_framebuffer(win->fbinfo); ++ s3c_fb_free_memory(sfb, win); ++} ++ ++/** ++ * s3c_fb_probe_win() - register an hardware window ++ * @sfb: The base resources for the hardware ++ * @res: Pointer to where to place the resultant window. ++ * ++ * Allocate and do the basic initialisation for one of the hardware's graphics ++ * windows. ++ */ ++static int __devinit s3c_fb_probe_win(struct s3c_fb *sfb, unsigned int win_no, ++ struct s3c_fb_win **res) ++{ ++ struct fb_var_screeninfo *var; ++ struct fb_videomode *initmode; ++ struct s3c_fb_pd_win *windata; ++ struct s3c_fb_win *win; ++ struct fb_info *fbinfo; ++ int palette_size; ++ int ret; ++ ++ dev_dbg(sfb->dev, "probing window %d\n", win_no); ++ ++ palette_size = s3c_fb_win_pal_size(win_no); ++ ++ fbinfo = framebuffer_alloc(sizeof(struct s3c_fb_win) + ++ palette_size * sizeof(u32), sfb->dev); ++ if (!fbinfo) { ++ dev_err(sfb->dev, "failed to allocate framebuffer\n"); ++ return -ENOENT; ++ } ++ ++ windata = sfb->pdata->win[win_no]; ++ initmode = &windata->win_mode; ++ ++ WARN_ON(windata->max_bpp == 0); ++ WARN_ON(windata->win_mode.xres == 0); ++ WARN_ON(windata->win_mode.yres == 0); ++ ++ win = fbinfo->par; ++ var = &fbinfo->var; ++ win->fbinfo = fbinfo; ++ win->parent = sfb; ++ win->windata = windata; ++ win->index = win_no; ++ win->palette_buffer = (u32 *)(win + 1); ++ ++ ret = s3c_fb_alloc_memory(sfb, win); ++ if (ret) { ++ dev_err(sfb->dev, "failed to allocate display memory\n"); ++ goto err_framebuffer; ++ } ++ ++ /* setup the r/b/g positions for the window's palette */ ++ s3c_fb_init_palette(win_no, &win->palette); ++ ++ /* setup the initial video mode from the window */ ++ fb_videomode_to_var(&fbinfo->var, initmode); ++ ++ fbinfo->fix.type = FB_TYPE_PACKED_PIXELS; ++ fbinfo->fix.accel = FB_ACCEL_NONE; ++ fbinfo->var.activate = FB_ACTIVATE_NOW; ++ fbinfo->var.vmode = FB_VMODE_NONINTERLACED; ++ fbinfo->var.bits_per_pixel = windata->default_bpp; ++ fbinfo->fbops = &s3c_fb_ops; ++ fbinfo->flags = FBINFO_FLAG_DEFAULT; ++ fbinfo->pseudo_palette = &win->pseudo_palette; ++ ++ /* prepare to actually start the framebuffer */ ++ ++ ret = s3c_fb_check_var(&fbinfo->var, fbinfo); ++ if (ret < 0) { ++ dev_err(sfb->dev, "check_var failed on initial video params\n"); ++ goto err_alloc_mem; ++ } ++ ++ /* create initial colour map */ ++ ++ ret = fb_alloc_cmap(&fbinfo->cmap, s3c_fb_win_pal_size(win_no), 1); ++ if (ret == 0) ++ fb_set_cmap(&fbinfo->cmap, fbinfo); ++ else ++ dev_err(sfb->dev, "failed to allocate fb cmap\n"); ++ ++ s3c_fb_set_par(fbinfo); ++ ++ dev_dbg(sfb->dev, "about to register framebuffer\n"); ++ ++ /* run the check_var and set_par on our configuration. */ ++ ++ ret = register_framebuffer(fbinfo); ++ if (ret < 0) { ++ dev_err(sfb->dev, "failed to register framebuffer\n"); ++ goto err_alloc_mem; ++ } ++ ++ *res = win; ++ dev_info(sfb->dev, "window %d: fb %s\n", win_no, fbinfo->fix.id); ++ ++ return 0; ++ ++err_alloc_mem: ++ s3c_fb_free_memory(sfb, win); ++ ++err_framebuffer: ++ unregister_framebuffer(fbinfo); ++ return ret; ++} ++ ++/** ++ * s3c_fb_clear_win() - clear hardware window registers. ++ * @sfb: The base resources for the hardware. ++ * @win: The window to process. ++ * ++ * Reset the specific window registers to a known state. ++ */ ++static void s3c_fb_clear_win(struct s3c_fb *sfb, int win) ++{ ++ void __iomem *regs = sfb->regs; ++ ++ writel(0, regs + WINCON(win)); ++ writel(0xffffff, regs + WxKEYCONy(win, 0)); ++ writel(0xffffff, regs + WxKEYCONy(win, 1)); ++ ++ writel(0, regs + VIDOSD_A(win)); ++ writel(0, regs + VIDOSD_B(win)); ++ writel(0, regs + VIDOSD_C(win)); ++} ++ ++static int __devinit s3c_fb_probe(struct platform_device *pdev) ++{ ++ struct device *dev = &pdev->dev; ++ struct s3c_fb_platdata *pd; ++ struct s3c_fb *sfb; ++ struct resource *res; ++ int win; ++ int ret = 0; ++ ++ pd = pdev->dev.platform_data; ++ if (!pd) { ++ dev_err(dev, "no platform data specified\n"); ++ return -EINVAL; ++ } ++ ++ sfb = kzalloc(sizeof(struct s3c_fb), GFP_KERNEL); ++ if (!sfb) { ++ dev_err(dev, "no memory for framebuffers\n"); ++ return -ENOMEM; ++ } ++ ++ sfb->dev = dev; ++ sfb->pdata = pd; ++ ++ sfb->bus_clk = clk_get(dev, "lcd"); ++ if (IS_ERR(sfb->bus_clk)) { ++ dev_err(dev, "failed to get bus clock\n"); ++ goto err_sfb; ++ } ++ ++ clk_enable(sfb->bus_clk); ++ ++ res = platform_get_resource(pdev, IORESOURCE_MEM, 0); ++ if (!res) { ++ dev_err(dev, "failed to find registers\n"); ++ ret = -ENOENT; ++ goto err_clk; ++ } ++ ++ sfb->regs_res = request_mem_region(res->start, resource_size(res), ++ dev_name(dev)); ++ if (!sfb->regs_res) { ++ dev_err(dev, "failed to claim register region\n"); ++ ret = -ENOENT; ++ goto err_clk; ++ } ++ ++ sfb->regs = ioremap(res->start, resource_size(res)); ++ if (!sfb->regs) { ++ dev_err(dev, "failed to map registers\n"); ++ ret = -ENXIO; ++ goto err_req_region; ++ } ++ ++ dev_dbg(dev, "got resources (regs %p), probing windows\n", sfb->regs); ++ ++ /* setup gpio and output polarity controls */ ++ ++ pd->setup_gpio(); ++ ++ writel(pd->vidcon1, sfb->regs + VIDCON1); ++ ++ /* zero all windows before we do anything */ ++ ++ for (win = 0; win < S3C_FB_MAX_WIN; win++) ++ s3c_fb_clear_win(sfb, win); ++ ++ /* we have the register setup, start allocating framebuffers */ ++ ++ for (win = 0; win < S3C_FB_MAX_WIN; win++) { ++ if (!pd->win[win]) ++ continue; ++ ++ ret = s3c_fb_probe_win(sfb, win, &sfb->windows[win]); ++ if (ret < 0) { ++ dev_err(dev, "failed to create window %d\n", win); ++ for (; win >= 0; win--) ++ s3c_fb_release_win(sfb, sfb->windows[win]); ++ goto err_ioremap; ++ } ++ } ++ ++ platform_set_drvdata(pdev, sfb); ++ ++ return 0; ++ ++err_ioremap: ++ iounmap(sfb->regs); ++ ++err_req_region: ++ release_resource(sfb->regs_res); ++ kfree(sfb->regs_res); ++ ++err_clk: ++ clk_disable(sfb->bus_clk); ++ clk_put(sfb->bus_clk); ++ ++err_sfb: ++ kfree(sfb); ++ return ret; ++} ++ ++/** ++ * s3c_fb_remove() - Cleanup on module finalisation ++ * @pdev: The platform device we are bound to. ++ * ++ * Shutdown and then release all the resources that the driver allocated ++ * on initialisation. ++ */ ++static int __devexit s3c_fb_remove(struct platform_device *pdev) ++{ ++ struct s3c_fb *sfb = platform_get_drvdata(pdev); ++ int win; ++ ++ for (win = 0; win <= S3C_FB_MAX_WIN; win++) ++ s3c_fb_release_win(sfb, sfb->windows[win]); ++ ++ iounmap(sfb->regs); ++ ++ clk_disable(sfb->bus_clk); ++ clk_put(sfb->bus_clk); ++ ++ release_resource(sfb->regs_res); ++ kfree(sfb->regs_res); ++ ++ kfree(sfb); ++ ++ return 0; ++} ++ ++#ifdef CONFIG_PM ++static int s3c_fb_suspend(struct platform_device *pdev, pm_message_t state) ++{ ++ struct s3c_fb *sfb = platform_get_drvdata(pdev); ++ struct s3c_fb_win *win; ++ int win_no; ++ ++ for (win_no = S3C_FB_MAX_WIN; win_no >= 0; win_no--) { ++ win = sfb->windows[win_no]; ++ if (!win) ++ continue; ++ ++ /* use the blank function to push into power-down */ ++ s3c_fb_blank(FB_BLANK_POWERDOWN, win->fbinfo); ++ } ++ ++ clk_disable(sfb->bus_clk); ++ return 0; ++} ++ ++static int s3c_fb_resume(struct platform_device *pdev) ++{ ++ struct s3c_fb *sfb = platform_get_drvdata(pdev); ++ struct s3c_fb_win *win; ++ int win_no; ++ ++ clk_enable(sfb->bus_clk); ++ ++ for (win_no = 0; win_no < S3C_FB_MAX_WIN; win_no++) { ++ win = sfb->windows[win_no]; ++ if (!win) ++ continue; ++ ++ dev_dbg(&pdev->dev, "resuming window %d\n", win_no); ++ s3c_fb_set_par(win->fbinfo); ++ } ++ ++ return 0; ++} ++#else ++#define s3c_fb_suspend NULL ++#define s3c_fb_resume NULL ++#endif ++ ++static struct platform_driver s3c_fb_driver = { ++ .probe = s3c_fb_probe, ++ .remove = s3c_fb_remove, ++ .suspend = s3c_fb_suspend, ++ .resume = s3c_fb_resume, ++ .driver = { ++ .name = "s3c-fb", ++ .owner = THIS_MODULE, ++ }, ++}; ++ ++static int __init s3c_fb_init(void) ++{ ++ return platform_driver_register(&s3c_fb_driver); ++} ++ ++static void __exit s3c_fb_cleanup(void) ++{ ++ platform_driver_unregister(&s3c_fb_driver); ++} ++ ++module_init(s3c_fb_init); ++module_exit(s3c_fb_cleanup); ++ ++MODULE_AUTHOR("Ben Dooks <ben@simtec.co.uk>"); ++MODULE_DESCRIPTION("Samsung S3C SoC Framebuffer driver"); ++MODULE_LICENSE("GPL"); ++MODULE_ALIAS("platform:s3c-fb"); +diff -ruN --exclude='*.orig' --exclude='*.rej' linux-2.6.29-rc3.owrt/drivers/watchdog/Kconfig linux-2.6.29-rc3.owrt.om/drivers/watchdog/Kconfig +--- linux-2.6.29-rc3.owrt/drivers/watchdog/Kconfig 2009-05-10 22:08:45.000000000 +0200 ++++ linux-2.6.29-rc3.owrt.om/drivers/watchdog/Kconfig 2009-05-10 22:28:00.000000000 +0200 +@@ -154,6 +154,13 @@ + The driver can be built as a module by choosing M, and will + be called s3c2410_wdt + ++config PCF50606_WATCHDOG ++ depends on MFD_PCF50606 ++ tristate "Philips PCF50606 watchdog" ++ help ++ If you say yes here you get support for the Philips PCF50606 ++ PMU's watchdog. ++ + config SA1100_WATCHDOG + tristate "SA1100/PXA2xx watchdog" + depends on ARCH_SA1100 || ARCH_PXA +diff -ruN --exclude='*.orig' --exclude='*.rej' linux-2.6.29-rc3.owrt/drivers/watchdog/Makefile linux-2.6.29-rc3.owrt.om/drivers/watchdog/Makefile +--- linux-2.6.29-rc3.owrt/drivers/watchdog/Makefile 2009-05-10 22:04:48.000000000 +0200 ++++ linux-2.6.29-rc3.owrt.om/drivers/watchdog/Makefile 2009-05-10 22:28:00.000000000 +0200 +@@ -34,6 +34,7 @@ + obj-$(CONFIG_IXP4XX_WATCHDOG) += ixp4xx_wdt.o + obj-$(CONFIG_KS8695_WATCHDOG) += ks8695_wdt.o + obj-$(CONFIG_S3C2410_WATCHDOG) += s3c2410_wdt.o ++obj-$(CONFIG_PCF50606_WATCHDOG) += pcf50606_wdt.o + obj-$(CONFIG_SA1100_WATCHDOG) += sa1100_wdt.o + obj-$(CONFIG_MPCORE_WATCHDOG) += mpcore_wdt.o + obj-$(CONFIG_EP93XX_WATCHDOG) += ep93xx_wdt.o +diff -ruN --exclude='*.orig' --exclude='*.rej' linux-2.6.29-rc3.owrt/drivers/watchdog/pcf50606_wdt.c linux-2.6.29-rc3.owrt.om/drivers/watchdog/pcf50606_wdt.c +--- linux-2.6.29-rc3.owrt/drivers/watchdog/pcf50606_wdt.c 1970-01-01 01:00:00.000000000 +0100 ++++ linux-2.6.29-rc3.owrt.om/drivers/watchdog/pcf50606_wdt.c 2009-05-10 22:28:00.000000000 +0200 +@@ -0,0 +1,223 @@ ++/* Philips PCF50606 Watchdog Timer Driver ++ * ++ * (C) 2006-2008 by Openmoko, Inc. ++ * Author: Balaji Rao <balajirrao@openmoko.org> ++ * All rights reserved. ++ * ++ * Broken down from monstrous PCF50606 driver mainly by ++ * Harald Welte, Matt Hsu, Andy Green and Werner Almesberger ++ * ++ * 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. ++ */ ++ ++#include <linux/kernel.h> ++#include <linux/module.h> ++#include <linux/init.h> ++#include <linux/device.h> ++#include <linux/rtc.h> ++#include <linux/bcd.h> ++#include <linux/err.h> ++#include <linux/miscdevice.h> ++#include <linux/watchdog.h> ++#include <linux/platform_device.h> ++ ++#include <linux/mfd/pcf50606/core.h> ++ ++static struct pcf50606 *pcf = NULL; ++static unsigned long wdt_status; ++ ++#define WDT_IN_USE 0 ++#define WDT_OK_TO_CLOSE 1 ++#define WDT_REGION_INITED 2 ++#define WDT_DEVICE_INITED 3 ++ ++static int allow_close; ++#define CLOSE_STATE_NOT 0x0000 ++#define CLOSE_STATE_ALLOW 0x2342 ++ ++#define PCF50606_REG_OOCC1 0x08 ++#define PCF50606_REG_OOCS 0x01 ++ ++#define PCF50606_OOCS_WDTEXP 0x80 ++#define PCF50606_OOCC1_WDTRST 0x08 ++ ++static void pcf50606_wdt_start(void) ++{ ++ pcf50606_reg_set_bit_mask(pcf, PCF50606_REG_OOCC1, PCF50606_OOCC1_WDTRST, ++ PCF50606_OOCC1_WDTRST); ++} ++ ++static void pcf50606_wdt_stop(void) ++{ ++ pcf50606_reg_clear_bits(pcf, PCF50606_REG_OOCS, PCF50606_OOCS_WDTEXP); ++} ++ ++static void pcf50606_wdt_keepalive(void) ++{ ++ pcf50606_wdt_start(); ++} ++ ++static int pcf50606_wdt_open(struct inode *inode, struct file *file) ++{ ++ if (test_and_set_bit(WDT_IN_USE, &wdt_status)) ++ return -EBUSY; ++ ++ pcf50606_wdt_start(); ++ ++ return nonseekable_open(inode, file); ++} ++ ++static int pcf50606_wdt_release(struct inode *inode, struct file *file) ++{ ++ if (allow_close == CLOSE_STATE_ALLOW) ++ pcf50606_wdt_stop(); ++ else { ++ printk(KERN_CRIT "Unexpected close, not stopping watchdog!\n"); ++ pcf50606_wdt_keepalive(); ++ } ++ ++ allow_close = CLOSE_STATE_NOT; ++ clear_bit(WDT_IN_USE, &wdt_status); ++ ++ return 0; ++} ++ ++static ssize_t pcf50606_wdt_write(struct file *file, const char __user *data, ++ size_t len, loff_t *ppos) ++{ ++ if (len) { ++ size_t i; ++ ++ for (i = 0; i != len; i++) { ++ char c; ++ if (get_user(c, data + i)) ++ return -EFAULT; ++ if (c == 'V') ++ allow_close = CLOSE_STATE_ALLOW; ++ } ++ pcf50606_wdt_keepalive(); ++ } ++ ++ return len; ++} ++ ++static struct watchdog_info pcf50606_wdt_ident = { ++ .options = WDIOF_MAGICCLOSE, ++ .firmware_version = 0, ++ .identity = "PCF50606 Watchdog", ++}; ++ ++static int pcf50606_wdt_ioctl(struct inode *inode, struct file *file, ++ unsigned int cmd, unsigned long arg) ++{ ++ void __user *argp = (void __user *)arg; ++ int __user *p = argp; ++ ++ switch (cmd) { ++ case WDIOC_GETSUPPORT: ++ return copy_to_user(argp, &pcf50606_wdt_ident, ++ sizeof(pcf50606_wdt_ident)) ? -EFAULT : 0; ++ break; ++ case WDIOC_GETSTATUS: ++ case WDIOC_GETBOOTSTATUS: ++ return put_user(0, p); ++ case WDIOC_KEEPALIVE: ++ pcf50606_wdt_keepalive(); ++ return 0; ++ case WDIOC_GETTIMEOUT: ++ return put_user(8, p); ++ default: ++ return -ENOIOCTLCMD; ++ } ++} ++ ++static struct file_operations pcf50606_wdt_fops = { ++ .owner = THIS_MODULE, ++ .llseek = no_llseek, ++ .write = &pcf50606_wdt_write, ++ .ioctl = &pcf50606_wdt_ioctl, ++ .open = &pcf50606_wdt_open, ++ .release = &pcf50606_wdt_release, ++}; ++ ++static struct miscdevice pcf50606_wdt_miscdev = { ++ .minor = WATCHDOG_MINOR, ++ .name = "watchdog", ++ .fops = &pcf50606_wdt_fops, ++}; ++ ++static void pcf50606_wdt_irq(int irq, void *unused) ++{ ++ pcf50606_reg_set_bit_mask(pcf, PCF50606_REG_OOCC1, ++ PCF50606_OOCC1_WDTRST, ++ PCF50606_OOCC1_WDTRST); ++} ++ ++int __init pcf50606_wdt_probe(struct platform_device *pdev) ++{ ++ struct pcf50606_subdev_pdata *pdata; ++ int err; ++ ++ if (pcf) { ++ dev_err(pcf->dev, "Only one instance of WDT supported\n"); ++ return -ENODEV; ++ } ++ ++ pdata = pdev->dev.platform_data; ++ if (!pdata) { ++ dev_err(&pdev->dev, "No platform data available\n"); ++ return -EINVAL; ++ } ++ ++ pcf = pdata->pcf; ++ ++ err = misc_register(&pcf50606_wdt_miscdev); ++ if (err) { ++ dev_err(&pdev->dev, "cannot register miscdev on " ++ "minor=%d (%d)\n", WATCHDOG_MINOR, err); ++ return err; ++ } ++ set_bit(WDT_DEVICE_INITED, &wdt_status); ++ ++ pcf50606_register_irq(pcf, PCF50606_IRQ_CHGWD10S, pcf50606_wdt_irq, NULL); ++ ++ return 0; ++} ++ ++static int __devexit pcf50606_wdt_remove(struct platform_device *pdev) ++{ ++ pcf50606_free_irq(pcf, PCF50606_IRQ_CHGWD10S); ++ misc_deregister(&pcf50606_wdt_miscdev); ++ pcf = NULL; ++ ++ return 0; ++} ++ ++struct platform_driver pcf50606_wdt_driver = { ++ .driver = { ++ .name = "pcf50606-wdt", ++ }, ++ .probe = pcf50606_wdt_probe, ++ .remove = __devexit_p(pcf50606_wdt_remove), ++}; ++ ++static int __init pcf50606_wdt_init(void) ++{ ++ return platform_driver_register(&pcf50606_wdt_driver); ++} ++module_init(pcf50606_wdt_init); ++ ++static void __exit pcf50606_wdt_exit(void) ++{ ++ platform_driver_unregister(&pcf50606_wdt_driver); ++} ++module_exit(pcf50606_wdt_exit); ++ ++MODULE_AUTHOR("Balaji Rao <balajirrao@openmoko.org>"); ++MODULE_DESCRIPTION("PCF50606 wdt driver"); ++MODULE_LICENSE("GPL"); ++MODULE_ALIAS("platform:pcf50606-wdt"); ++ +diff -ruN --exclude='*.orig' --exclude='*.rej' linux-2.6.29-rc3.owrt/fs/jffs2/background.c linux-2.6.29-rc3.owrt.om/fs/jffs2/background.c +--- linux-2.6.29-rc3.owrt/fs/jffs2/background.c 2009-05-10 22:08:58.000000000 +0200 ++++ linux-2.6.29-rc3.owrt.om/fs/jffs2/background.c 2009-05-10 22:28:00.000000000 +0200 +@@ -95,13 +95,17 @@ + spin_unlock(&c->erase_completion_lock); + + +- /* This thread is purely an optimisation. But if it runs when +- other things could be running, it actually makes things a +- lot worse. Use yield() and put it at the back of the runqueue +- every time. Especially during boot, pulling an inode in +- with read_inode() is much preferable to having the GC thread +- get there first. */ +- yield(); ++ /* Problem - immediately after bootup, the GCD spends a lot ++ * of time in places like jffs2_kill_fragtree(); so much so ++ * that userspace processes (like gdm and X) are starved ++ * despite plenty of cond_resched()s and renicing. Yield() ++ * doesn't help, either (presumably because userspace and GCD ++ * are generally competing for a higher latency resource - ++ * disk). ++ * This forces the GCD to slow the hell down. Pulling an ++ * inode in with read_inode() is much preferable to having ++ * the GC thread get there first. */ ++ schedule_timeout_interruptible(msecs_to_jiffies(50)); + + /* Put_super will send a SIGKILL and then wait on the sem. + */ +diff -ruN --exclude='*.orig' --exclude='*.rej' linux-2.6.29-rc3.owrt/include/asm-arm/plat-s3c24xx/neo1973.h linux-2.6.29-rc3.owrt.om/include/asm-arm/plat-s3c24xx/neo1973.h +--- linux-2.6.29-rc3.owrt/include/asm-arm/plat-s3c24xx/neo1973.h 1970-01-01 01:00:00.000000000 +0100 ++++ linux-2.6.29-rc3.owrt.om/include/asm-arm/plat-s3c24xx/neo1973.h 2009-05-10 22:28:00.000000000 +0200 +@@ -0,0 +1,33 @@ ++/* ++ * include/asm-arm/plat-s3c24xx/neo1973.h ++ * ++ * Common utility code for GTA01 and GTA02 ++ * ++ * Copyright (C) 2008 by Openmoko, Inc. ++ * Author: Holger Hans Peter Freyther <freyther@openmoko.org> ++ * All rights reserved. ++ * ++ * 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, ++ * MA 02111-1307 USA ++ * ++ */ ++ ++#ifndef NEO1973_H ++#define NEO1973_H ++ ++void neo1973_gpb_add_shadow_gpio(unsigned int gpio); ++void neo1973_gpb_setpin(unsigned int pin, unsigned to); ++ ++#endif +diff -ruN --exclude='*.orig' --exclude='*.rej' linux-2.6.29-rc3.owrt/include/asm-arm/plat-s3c24xx/regs-iis.h linux-2.6.29-rc3.owrt.om/include/asm-arm/plat-s3c24xx/regs-iis.h +--- linux-2.6.29-rc3.owrt/include/asm-arm/plat-s3c24xx/regs-iis.h 2009-05-10 22:04:48.000000000 +0200 ++++ linux-2.6.29-rc3.owrt.om/include/asm-arm/plat-s3c24xx/regs-iis.h 1970-01-01 01:00:00.000000000 +0100 +@@ -1,77 +0,0 @@ +-/* arch/arm/mach-s3c2410/include/mach/regs-iis.h +- * +- * Copyright (c) 2003 Simtec Electronics <linux@simtec.co.uk> +- * http://www.simtec.co.uk/products/SWLINUX/ +- * +- * 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. +- * +- * S3C2410 IIS register definition +-*/ +- +-#ifndef __ASM_ARCH_REGS_IIS_H +-#define __ASM_ARCH_REGS_IIS_H +- +-#define S3C2410_IISCON (0x00) +- +-#define S3C2410_IISCON_LRINDEX (1<<8) +-#define S3C2410_IISCON_TXFIFORDY (1<<7) +-#define S3C2410_IISCON_RXFIFORDY (1<<6) +-#define S3C2410_IISCON_TXDMAEN (1<<5) +-#define S3C2410_IISCON_RXDMAEN (1<<4) +-#define S3C2410_IISCON_TXIDLE (1<<3) +-#define S3C2410_IISCON_RXIDLE (1<<2) +-#define S3C2410_IISCON_PSCEN (1<<1) +-#define S3C2410_IISCON_IISEN (1<<0) +- +-#define S3C2410_IISMOD (0x04) +- +-#define S3C2440_IISMOD_MPLL (1<<9) +-#define S3C2410_IISMOD_SLAVE (1<<8) +-#define S3C2410_IISMOD_NOXFER (0<<6) +-#define S3C2410_IISMOD_RXMODE (1<<6) +-#define S3C2410_IISMOD_TXMODE (2<<6) +-#define S3C2410_IISMOD_TXRXMODE (3<<6) +-#define S3C2410_IISMOD_LR_LLOW (0<<5) +-#define S3C2410_IISMOD_LR_RLOW (1<<5) +-#define S3C2410_IISMOD_IIS (0<<4) +-#define S3C2410_IISMOD_MSB (1<<4) +-#define S3C2410_IISMOD_8BIT (0<<3) +-#define S3C2410_IISMOD_16BIT (1<<3) +-#define S3C2410_IISMOD_BITMASK (1<<3) +-#define S3C2410_IISMOD_256FS (0<<2) +-#define S3C2410_IISMOD_384FS (1<<2) +-#define S3C2410_IISMOD_16FS (0<<0) +-#define S3C2410_IISMOD_32FS (1<<0) +-#define S3C2410_IISMOD_48FS (2<<0) +-#define S3C2410_IISMOD_FS_MASK (3<<0) +- +-#define S3C2410_IISPSR (0x08) +-#define S3C2410_IISPSR_INTMASK (31<<5) +-#define S3C2410_IISPSR_INTSHIFT (5) +-#define S3C2410_IISPSR_EXTMASK (31<<0) +-#define S3C2410_IISPSR_EXTSHFIT (0) +- +-#define S3C2410_IISFCON (0x0c) +- +-#define S3C2410_IISFCON_TXDMA (1<<15) +-#define S3C2410_IISFCON_RXDMA (1<<14) +-#define S3C2410_IISFCON_TXENABLE (1<<13) +-#define S3C2410_IISFCON_RXENABLE (1<<12) +-#define S3C2410_IISFCON_TXMASK (0x3f << 6) +-#define S3C2410_IISFCON_TXSHIFT (6) +-#define S3C2410_IISFCON_RXMASK (0x3f) +-#define S3C2410_IISFCON_RXSHIFT (0) +- +-#define S3C2400_IISFCON_TXDMA (1<<11) +-#define S3C2400_IISFCON_RXDMA (1<<10) +-#define S3C2400_IISFCON_TXENABLE (1<<9) +-#define S3C2400_IISFCON_RXENABLE (1<<8) +-#define S3C2400_IISFCON_TXMASK (0x07 << 4) +-#define S3C2400_IISFCON_TXSHIFT (4) +-#define S3C2400_IISFCON_RXMASK (0x07) +-#define S3C2400_IISFCON_RXSHIFT (0) +- +-#define S3C2410_IISFIFO (0x10) +-#endif /* __ASM_ARCH_REGS_IIS_H */ +diff -ruN --exclude='*.orig' --exclude='*.rej' linux-2.6.29-rc3.owrt/include/asm-arm/plat-s3c24xx/regs-s3c2412-iis.h linux-2.6.29-rc3.owrt.om/include/asm-arm/plat-s3c24xx/regs-s3c2412-iis.h +--- linux-2.6.29-rc3.owrt/include/asm-arm/plat-s3c24xx/regs-s3c2412-iis.h 2009-05-10 22:04:48.000000000 +0200 ++++ linux-2.6.29-rc3.owrt.om/include/asm-arm/plat-s3c24xx/regs-s3c2412-iis.h 1970-01-01 01:00:00.000000000 +0100 +@@ -1,72 +0,0 @@ +-/* linux/include/asm-arm/plat-s3c24xx/regs-s3c2412-iis.h +- * +- * Copyright 2007 Simtec Electronics <linux@simtec.co.uk> +- * http://armlinux.simtec.co.uk/ +- * +- * 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. +- * +- * S3C2412 IIS register definition +-*/ +- +-#ifndef __ASM_ARCH_REGS_S3C2412_IIS_H +-#define __ASM_ARCH_REGS_S3C2412_IIS_H +- +-#define S3C2412_IISCON (0x00) +-#define S3C2412_IISMOD (0x04) +-#define S3C2412_IISFIC (0x08) +-#define S3C2412_IISPSR (0x0C) +-#define S3C2412_IISTXD (0x10) +-#define S3C2412_IISRXD (0x14) +- +-#define S3C2412_IISCON_LRINDEX (1 << 11) +-#define S3C2412_IISCON_TXFIFO_EMPTY (1 << 10) +-#define S3C2412_IISCON_RXFIFO_EMPTY (1 << 9) +-#define S3C2412_IISCON_TXFIFO_FULL (1 << 8) +-#define S3C2412_IISCON_RXFIFO_FULL (1 << 7) +-#define S3C2412_IISCON_TXDMA_PAUSE (1 << 6) +-#define S3C2412_IISCON_RXDMA_PAUSE (1 << 5) +-#define S3C2412_IISCON_TXCH_PAUSE (1 << 4) +-#define S3C2412_IISCON_RXCH_PAUSE (1 << 3) +-#define S3C2412_IISCON_TXDMA_ACTIVE (1 << 2) +-#define S3C2412_IISCON_RXDMA_ACTIVE (1 << 1) +-#define S3C2412_IISCON_IIS_ACTIVE (1 << 0) +- +-#define S3C2412_IISMOD_MASTER_INTERNAL (0 << 10) +-#define S3C2412_IISMOD_MASTER_EXTERNAL (1 << 10) +-#define S3C2412_IISMOD_SLAVE (2 << 10) +-#define S3C2412_IISMOD_MASTER_MASK (3 << 10) +-#define S3C2412_IISMOD_MODE_TXONLY (0 << 8) +-#define S3C2412_IISMOD_MODE_RXONLY (1 << 8) +-#define S3C2412_IISMOD_MODE_TXRX (2 << 8) +-#define S3C2412_IISMOD_MODE_MASK (3 << 8) +-#define S3C2412_IISMOD_LR_LLOW (0 << 7) +-#define S3C2412_IISMOD_LR_RLOW (1 << 7) +-#define S3C2412_IISMOD_SDF_IIS (0 << 5) +-#define S3C2412_IISMOD_SDF_MSB (0 << 5) +-#define S3C2412_IISMOD_SDF_LSB (0 << 5) +-#define S3C2412_IISMOD_SDF_MASK (3 << 5) +-#define S3C2412_IISMOD_RCLK_256FS (0 << 3) +-#define S3C2412_IISMOD_RCLK_512FS (1 << 3) +-#define S3C2412_IISMOD_RCLK_384FS (2 << 3) +-#define S3C2412_IISMOD_RCLK_768FS (3 << 3) +-#define S3C2412_IISMOD_RCLK_MASK (3 << 3) +-#define S3C2412_IISMOD_BCLK_32FS (0 << 1) +-#define S3C2412_IISMOD_BCLK_48FS (1 << 1) +-#define S3C2412_IISMOD_BCLK_16FS (2 << 1) +-#define S3C2412_IISMOD_BCLK_24FS (3 << 1) +-#define S3C2412_IISMOD_BCLK_MASK (3 << 1) +-#define S3C2412_IISMOD_8BIT (1 << 0) +- +-#define S3C2412_IISPSR_PSREN (1 << 15) +- +-#define S3C2412_IISFIC_TXFLUSH (1 << 15) +-#define S3C2412_IISFIC_RXFLUSH (1 << 7) +-#define S3C2412_IISFIC_TXCOUNT(x) (((x) >> 8) & 0xf) +-#define S3C2412_IISFIC_RXCOUNT(x) (((x) >> 0) & 0xf) +- +- +- +-#endif /* __ASM_ARCH_REGS_S3C2412_IIS_H */ +- +diff -ruN --exclude='*.orig' --exclude='*.rej' linux-2.6.29-rc3.owrt/include/linux/android_aid.h linux-2.6.29-rc3.owrt.om/include/linux/android_aid.h +--- linux-2.6.29-rc3.owrt/include/linux/android_aid.h 1970-01-01 01:00:00.000000000 +0100 ++++ linux-2.6.29-rc3.owrt.om/include/linux/android_aid.h 2009-05-10 22:28:00.000000000 +0200 +@@ -0,0 +1,25 @@ ++/* include/linux/android_aid.h ++ * ++ * Copyright (C) 2008 Google, Inc. ++ * ++ * This software is licensed under the terms of the GNU General Public ++ * License version 2, as published by the Free Software Foundation, and ++ * may be copied, distributed, and modified under those terms. ++ * ++ * 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. ++ * ++ */ ++ ++#ifndef _LINUX_ANDROID_AID_H ++#define _LINUX_ANDROID_AID_H ++ ++/* AIDs that the kernel treats differently */ ++#define AID_NET_BT_ADMIN 3001 ++#define AID_NET_BT 3002 ++#define AID_INET 3003 ++#define AID_NET_RAW 3004 ++ ++#endif +diff -ruN --exclude='*.orig' --exclude='*.rej' linux-2.6.29-rc3.owrt/include/linux/android_alarm.h linux-2.6.29-rc3.owrt.om/include/linux/android_alarm.h +--- linux-2.6.29-rc3.owrt/include/linux/android_alarm.h 1970-01-01 01:00:00.000000000 +0100 ++++ linux-2.6.29-rc3.owrt.om/include/linux/android_alarm.h 2009-05-10 22:28:00.000000000 +0200 +@@ -0,0 +1,62 @@ ++/* include/linux/android_alarm.h ++ * ++ * Copyright (C) 2006-2007 Google, Inc. ++ * ++ * This software is licensed under the terms of the GNU General Public ++ * License version 2, as published by the Free Software Foundation, and ++ * may be copied, distributed, and modified under those terms. ++ * ++ * 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. ++ * ++ */ ++ ++#ifndef _LINUX_ANDROID_ALARM_H ++#define _LINUX_ANDROID_ALARM_H ++ ++#include <linux/ioctl.h> ++#include <linux/time.h> ++ ++enum android_alarm_type { ++ /* return code bit numbers or set alarm arg */ ++ ANDROID_ALARM_RTC_WAKEUP, ++ ANDROID_ALARM_RTC, ++ ANDROID_ALARM_ELAPSED_REALTIME_WAKEUP, ++ ANDROID_ALARM_ELAPSED_REALTIME, ++ ANDROID_ALARM_SYSTEMTIME, ++ ++ ANDROID_ALARM_TYPE_COUNT, ++ ++ /* return code bit numbers */ ++ /* ANDROID_ALARM_TIME_CHANGE = 16 */ ++}; ++ ++enum android_alarm_return_flags { ++ ANDROID_ALARM_RTC_WAKEUP_MASK = 1U << ANDROID_ALARM_RTC_WAKEUP, ++ ANDROID_ALARM_RTC_MASK = 1U << ANDROID_ALARM_RTC, ++ ANDROID_ALARM_ELAPSED_REALTIME_WAKEUP_MASK = ++ 1U << ANDROID_ALARM_ELAPSED_REALTIME_WAKEUP, ++ ANDROID_ALARM_ELAPSED_REALTIME_MASK = ++ 1U << ANDROID_ALARM_ELAPSED_REALTIME, ++ ANDROID_ALARM_SYSTEMTIME_MASK = 1U << ANDROID_ALARM_SYSTEMTIME, ++ ANDROID_ALARM_TIME_CHANGE_MASK = 1U << 16 ++}; ++ ++/* Disable alarm */ ++#define ANDROID_ALARM_CLEAR(type) _IO('a', 0 | ((type) << 4)) ++ ++/* Ack last alarm and wait for next */ ++#define ANDROID_ALARM_WAIT _IO('a', 1) ++ ++#define ALARM_IOW(c, type, size) _IOW('a', (c) | ((type) << 4), size) ++/* Set alarm */ ++#define ANDROID_ALARM_SET(type) ALARM_IOW(2, type, struct timespec) ++#define ANDROID_ALARM_SET_AND_WAIT(type) ALARM_IOW(3, type, struct timespec) ++#define ANDROID_ALARM_GET_TIME(type) ALARM_IOW(4, type, struct timespec) ++#define ANDROID_ALARM_SET_RTC _IOW('a', 5, struct timespec) ++#define ANDROID_ALARM_BASE_CMD(cmd) (cmd & ~(_IOC(0, 0, 0xf0, 0))) ++#define ANDROID_ALARM_IOCTL_TO_TYPE(cmd) (_IOC_NR(cmd) >> 4) ++ ++#endif +diff -ruN --exclude='*.orig' --exclude='*.rej' linux-2.6.29-rc3.owrt/include/linux/ashmem.h linux-2.6.29-rc3.owrt.om/include/linux/ashmem.h +--- linux-2.6.29-rc3.owrt/include/linux/ashmem.h 1970-01-01 01:00:00.000000000 +0100 ++++ linux-2.6.29-rc3.owrt.om/include/linux/ashmem.h 2009-05-10 22:28:00.000000000 +0200 +@@ -0,0 +1,48 @@ ++/* ++ * include/linux/ashmem.h ++ * ++ * Copyright 2008 Google Inc. ++ * Author: Robert Love ++ * ++ * This file is dual licensed. It may be redistributed and/or modified ++ * under the terms of the Apache 2.0 License OR version 2 of the GNU ++ * General Public License. ++ */ ++ ++#ifndef _LINUX_ASHMEM_H ++#define _LINUX_ASHMEM_H ++ ++#include <linux/limits.h> ++#include <linux/ioctl.h> ++ ++#define ASHMEM_NAME_LEN 256 ++ ++#define ASHMEM_NAME_DEF "dev/ashmem" ++ ++/* Return values from ASHMEM_PIN: Was the mapping purged while unpinned? */ ++#define ASHMEM_NOT_PURGED 0 ++#define ASHMEM_WAS_PURGED 1 ++ ++/* Return values from ASHMEM_GET_PIN_STATUS: Is the mapping pinned? */ ++#define ASHMEM_IS_UNPINNED 0 ++#define ASHMEM_IS_PINNED 1 ++ ++struct ashmem_pin { ++ __u32 offset; /* offset into region, in bytes, page-aligned */ ++ __u32 len; /* length forward from offset, in bytes, page-aligned */ ++}; ++ ++#define __ASHMEMIOC 0x77 ++ ++#define ASHMEM_SET_NAME _IOW(__ASHMEMIOC, 1, char[ASHMEM_NAME_LEN]) ++#define ASHMEM_GET_NAME _IOR(__ASHMEMIOC, 2, char[ASHMEM_NAME_LEN]) ++#define ASHMEM_SET_SIZE _IOW(__ASHMEMIOC, 3, size_t) ++#define ASHMEM_GET_SIZE _IO(__ASHMEMIOC, 4) ++#define ASHMEM_SET_PROT_MASK _IOW(__ASHMEMIOC, 5, unsigned long) ++#define ASHMEM_GET_PROT_MASK _IO(__ASHMEMIOC, 6) ++#define ASHMEM_PIN _IOW(__ASHMEMIOC, 7, struct ashmem_pin) ++#define ASHMEM_UNPIN _IOW(__ASHMEMIOC, 8, struct ashmem_pin) ++#define ASHMEM_GET_PIN_STATUS _IO(__ASHMEMIOC, 9) ++#define ASHMEM_PURGE_ALL_CACHES _IO(__ASHMEMIOC, 10) ++ ++#endif /* _LINUX_ASHMEM_H */ +diff -ruN --exclude='*.orig' --exclude='*.rej' linux-2.6.29-rc3.owrt/include/linux/bq27000_battery.h linux-2.6.29-rc3.owrt.om/include/linux/bq27000_battery.h +--- linux-2.6.29-rc3.owrt/include/linux/bq27000_battery.h 1970-01-01 01:00:00.000000000 +0100 ++++ linux-2.6.29-rc3.owrt.om/include/linux/bq27000_battery.h 2009-05-10 22:28:00.000000000 +0200 +@@ -0,0 +1,16 @@ ++#ifndef __BQ27000_BATTERY_H__ ++#define __BQ27000_BATTERY_H__ ++ ++void bq27000_charging_state_change(struct platform_device *pdev); ++ ++struct bq27000_platform_data { ++ const char *name; ++ int rsense_mohms; ++ int (*hdq_read)(int); ++ int (*hdq_write)(int, u8); ++ int (*hdq_initialized)(void); ++ int (*get_charger_online_status)(void); ++ int (*get_charger_active_status)(void); ++}; ++ ++#endif +diff -ruN --exclude='*.orig' --exclude='*.rej' linux-2.6.29-rc3.owrt/include/linux/device.h linux-2.6.29-rc3.owrt.om/include/linux/device.h +--- linux-2.6.29-rc3.owrt/include/linux/device.h 2009-05-10 22:09:07.000000000 +0200 ++++ linux-2.6.29-rc3.owrt.om/include/linux/device.h 2009-05-10 22:28:00.000000000 +0200 +@@ -48,6 +48,11 @@ + struct bus_attribute *); + extern void bus_remove_file(struct bus_type *, struct bus_attribute *); + ++extern int __must_check bus_create_device_link(struct bus_type *bus, ++ struct kobject *target, ++ const char *name); ++extern void bus_remove_device_link(struct bus_type *bus, const char *name); ++ + struct bus_type { + const char *name; + struct bus_attribute *bus_attrs; +diff -ruN --exclude='*.orig' --exclude='*.rej' linux-2.6.29-rc3.owrt/include/linux/earlysuspend.h linux-2.6.29-rc3.owrt.om/include/linux/earlysuspend.h +--- linux-2.6.29-rc3.owrt/include/linux/earlysuspend.h 1970-01-01 01:00:00.000000000 +0100 ++++ linux-2.6.29-rc3.owrt.om/include/linux/earlysuspend.h 2009-05-10 22:28:00.000000000 +0200 +@@ -0,0 +1,56 @@ ++/* include/linux/earlysuspend.h ++ * ++ * Copyright (C) 2007-2008 Google, Inc. ++ * ++ * This software is licensed under the terms of the GNU General Public ++ * License version 2, as published by the Free Software Foundation, and ++ * may be copied, distributed, and modified under those terms. ++ * ++ * 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. ++ * ++ */ ++ ++#ifndef _LINUX_EARLYSUSPEND_H ++#define _LINUX_EARLYSUSPEND_H ++ ++#ifdef CONFIG_ANDROID_HAS_EARLYSUSPEND ++#include <linux/list.h> ++#endif ++ ++/* The early_suspend structure defines suspend and resume hooks to be called ++ * when the user visible sleep state of the system changes, and a level to ++ * control the order. They can be used to turn off the screen and input ++ * devices that are not used for wakeup. ++ * Suspend handlers are called in low to high level order, resume handlers are ++ * called in the opposite order. If, when calling register_early_suspend, ++ * the suspend handlers have already been called without a matching call to the ++ * resume handlers, the suspend handler will be called directly from ++ * register_early_suspend. This direct call can violate the normal level order. ++ */ ++enum { ++ EARLY_SUSPEND_LEVEL_BLANK_SCREEN = 50, ++ EARLY_SUSPEND_LEVEL_STOP_DRAWING = 100, ++ EARLY_SUSPEND_LEVEL_DISABLE_FB = 150, ++}; ++struct early_suspend { ++#ifdef CONFIG_ANDROID_HAS_EARLYSUSPEND ++ struct list_head link; ++ int level; ++ void (*suspend)(struct early_suspend *h); ++ void (*resume)(struct early_suspend *h); ++#endif ++}; ++ ++#ifdef CONFIG_ANDROID_HAS_EARLYSUSPEND ++void register_early_suspend(struct early_suspend *handler); ++void unregister_early_suspend(struct early_suspend *handler); ++#else ++#define register_early_suspend(handler) do { } while (0) ++#define unregister_early_suspend(handler) do { } while (0) ++#endif ++ ++#endif ++ +diff -ruN --exclude='*.orig' --exclude='*.rej' linux-2.6.29-rc3.owrt/include/linux/fb.h linux-2.6.29-rc3.owrt.om/include/linux/fb.h +--- linux-2.6.29-rc3.owrt/include/linux/fb.h 2009-05-10 22:09:07.000000000 +0200 ++++ linux-2.6.29-rc3.owrt.om/include/linux/fb.h 2009-05-10 22:28:00.000000000 +0200 +@@ -123,6 +123,7 @@ + #define FB_ACCEL_TRIDENT_3DIMAGE 51 /* Trident 3DImage */ + #define FB_ACCEL_TRIDENT_BLADE3D 52 /* Trident Blade3D */ + #define FB_ACCEL_TRIDENT_BLADEXP 53 /* Trident BladeXP */ ++#define FB_ACCEL_GLAMO 50 /* SMedia Glamo */ + #define FB_ACCEL_NEOMAGIC_NM2070 90 /* NeoMagic NM2070 */ + #define FB_ACCEL_NEOMAGIC_NM2090 91 /* NeoMagic NM2090 */ + #define FB_ACCEL_NEOMAGIC_NM2093 92 /* NeoMagic NM2093 */ +diff -ruN --exclude='*.orig' --exclude='*.rej' linux-2.6.29-rc3.owrt/include/linux/glamofb.h linux-2.6.29-rc3.owrt.om/include/linux/glamofb.h +--- linux-2.6.29-rc3.owrt/include/linux/glamofb.h 1970-01-01 01:00:00.000000000 +0100 ++++ linux-2.6.29-rc3.owrt.om/include/linux/glamofb.h 2009-05-10 22:28:00.000000000 +0200 +@@ -0,0 +1,50 @@ ++#ifndef _LINUX_GLAMOFB_H ++#define _LINUX_GLAMOFB_H ++ ++#include <linux/spi/glamo.h> ++ ++struct glamofb_val { ++ unsigned int defval; ++ unsigned int min; ++ unsigned int max; ++}; ++ ++struct glamo_core; ++ ++struct glamofb_platform_data { ++ int width, height; ++ int pixclock; ++ int left_margin, right_margin; ++ int upper_margin, lower_margin; ++ int hsync_len, vsync_len; ++ int fb_mem_size; ++ ++ struct glamofb_val xres; ++ struct glamofb_val yres; ++ struct glamofb_val bpp; ++ ++ struct glamo_spi_info *spi_info; ++ struct glamo_spigpio_info *spigpio_info; ++ struct glamo_core *glamo; ++ ++ struct platform_device *mmc_dev; ++ ++ /* glamo mmc platform specific info */ ++ int (*glamo_can_set_mci_power)(void); ++ ++ /* glamo-mci asking if it should use the slow clock to card */ ++ int (*glamo_mci_use_slow)(void); ++ int (*glamo_irq_is_wired)(void); ++ void (*glamo_external_reset)(int); ++}; ++ ++int glamofb_cmd_mode(struct glamofb_handle *gfb, int on); ++int glamofb_cmd_write(struct glamofb_handle *gfb, u_int16_t val); ++ ++#ifdef CONFIG_MFD_GLAMO ++void glamo_lcm_reset(int level); ++#else ++#define glamo_lcm_reset(...) do {} while (0) ++#endif ++ ++#endif +diff -ruN --exclude='*.orig' --exclude='*.rej' linux-2.6.29-rc3.owrt/include/linux/glamo-gpio.h linux-2.6.29-rc3.owrt.om/include/linux/glamo-gpio.h +--- linux-2.6.29-rc3.owrt/include/linux/glamo-gpio.h 1970-01-01 01:00:00.000000000 +0100 ++++ linux-2.6.29-rc3.owrt.om/include/linux/glamo-gpio.h 2009-05-10 22:28:00.000000000 +0200 +@@ -0,0 +1,99 @@ ++#ifndef __GLAMO_GPIO_H ++#define __GLAMO_GPIO_H ++ ++struct glamo_core; ++ ++#define GLAMO_GPIO_BANKA 0x0000 ++#define GLAMO_GPIO_BANKB 0x1000 ++#define GLAMO_GPIO_BANKC 0x2000 ++#define GLAMO_GPIO_BANKD 0x3000 ++ ++#define GLAMO_GPIONO(bank, pin) ((bank & 0xf000) | ((pin & 0xf) << 8)) ++ ++#define GLAMO_GPIO_F_IN 0x0010 ++#define GLAMO_GPIO_F_OUT 0x0020 ++#define GLAMO_GPIO_F_FUNC 0x0030 ++ ++#define GLAMO_GPIO0 GLAMO_GPIONO(GLAMO_GPIO_BANKA, 0) ++#define GLAMO_GPIO0_INPUT (GLAMO_GPIO0 | GLAMO_GPIO_F_IN) ++#define GLAMO_GPIO0_OUTPUT (GLAMO_GPIO0 | GLAMO_GPIO_F_OUT) ++#define GLAMO_GPIO0_HA20 (GLAMO_GPIO0 | GLAMO_GPIO_F_FUNC) ++ ++#define GLAMO_GPIO1 GLAMO_GPIONO(GLAMO_GPIO_BANKA, 1) ++#define GLAMO_GPIO1_INPUT (GLAMO_GPIO1 | GLAMO_GPIO_F_IN) ++#define GLAMO_GPIO1_OUTPUT (GLAMO_GPIO1 | GLAMO_GPIO_F_OUT) ++#define GLAMO_GPIO1_HA21 (GLAMO_GPIO1 | GLAMO_GPIO_F_FUNC) ++ ++#define GLAMO_GPIO2 GLAMO_GPIONO(GLAMO_GPIO_BANKA, 2) ++#define GLAMO_GPIO2_INPUT (GLAMO_GPIO2 | GLAMO_GPIO_F_IN) ++#define GLAMO_GPIO2_OUTPUT (GLAMO_GPIO2 | GLAMO_GPIO_F_OUT) ++#define GLAMO_GPIO2_HA22 (GLAMO_GPIO2 | GLAMO_GPIO_F_FUNC) ++ ++#define GLAMO_GPIO3 GLAMO_GPIONO(GLAMO_GPIO_BANKA, 3) ++#define GLAMO_GPIO3_INPUT (GLAMO_GPIO3 | GLAMO_GPIO_F_IN) ++#define GLAMO_GPIO3_OUTPUT (GLAMO_GPIO3 | GLAMO_GPIO_F_OUT) ++#define GLAMO_GPIO3_HA23 (GLAMO_GPIO3 | GLAMO_GPIO_F_FUNC) ++ ++#define GLAMO_GPIO4 GLAMO_GPIONO(GLAMO_GPIO_BANKB, 0) ++#define GLAMO_GPIO4_INPUT (GLAMO_GPIO4 | GLAMO_GPIO_F_IN) ++#define GLAMO_GPIO4_OUTPUT (GLAMO_GPIO4 | GLAMO_GPIO_F_OUT) ++#define GLAMO_GPIO4_nLCS0 (GLAMO_GPIO4 | GLAMO_GPIO_F_FUNC) ++ ++#define GLAMO_GPIO5 GLAMO_GPIONO(GLAMO_GPIO_BANKB, 1) ++#define GLAMO_GPIO5_INPUT (GLAMO_GPIO5 | GLAMO_GPIO_F_IN) ++#define GLAMO_GPIO5_OUTPUT (GLAMO_GPIO5 | GLAMO_GPIO_F_OUT) ++#define GLAMO_GPIO5_nLCS1 (GLAMO_GPIO5 | GLAMO_GPIO_F_FUNC) ++ ++#define GLAMO_GPIO6 GLAMO_GPIONO(GLAMO_GPIO_BANKB, 2) ++#define GLAMO_GPIO6_INPUT (GLAMO_GPIO6 | GLAMO_GPIO_F_IN) ++#define GLAMO_GPIO6_OUTPUT (GLAMO_GPIO6 | GLAMO_GPIO_F_OUT) ++#define GLAMO_GPIO6_LDCLK (GLAMO_GPIO6 | GLAMO_GPIO_F_FUNC) ++ ++#define GLAMO_GPIO7 GLAMO_GPIONO(GLAMO_GPIO_BANKB, 3) ++#define GLAMO_GPIO7_INPUT (GLAMO_GPIO7 | GLAMO_GPIO_F_IN) ++#define GLAMO_GPIO7_OUTPUT (GLAMO_GPIO7 | GLAMO_GPIO_F_OUT) ++#define GLAMO_GPIO7_nLDE (GLAMO_GPIO7 | GLAMO_GPIO_F_FUNC) ++ ++#define GLAMO_GPIO8 GLAMO_GPIONO(GLAMO_GPIO_BANKC, 0) ++#define GLAMO_GPIO8_INPUT (GLAMO_GPIO8 | GLAMO_GPIO_F_IN) ++#define GLAMO_GPIO8_OUTPUT (GLAMO_GPIO8 | GLAMO_GPIO_F_OUT) ++#define GLAMO_GPIO8_LD16 (GLAMO_GPIO8 | GLAMO_GPIO_F_FUNC) ++ ++#define GLAMO_GPIO9 GLAMO_GPIONO(GLAMO_GPIO_BANKC, 1) ++#define GLAMO_GPIO9_INPUT (GLAMO_GPIO9 | GLAMO_GPIO_F_IN) ++#define GLAMO_GPIO9_OUTPUT (GLAMO_GPIO9 | GLAMO_GPIO_F_OUT) ++#define GLAMO_GPIO9_LD17 (GLAMO_GPIO9 | GLAMO_GPIO_F_FUNC) ++ ++#define GLAMO_GPIO10 GLAMO_GPIONO(GLAMO_GPIO_BANKC, 2) ++#define GLAMO_GPIO10_INPUT (GLAMO_GPIO10 | GLAMO_GPIO_F_IN) ++#define GLAMO_GPIO10_OUTPUT (GLAMO_GPIO10 | GLAMO_GPIO_F_OUT) ++#define GLAMO_GPIO10_LSCK (GLAMO_GPIO10 | GLAMO_GPIO_F_FUNC) ++ ++#define GLAMO_GPIO11 GLAMO_GPIONO(GLAMO_GPIO_BANKC, 3) ++#define GLAMO_GPIO11_INPUT (GLAMO_GPIO11 | GLAMO_GPIO_F_IN) ++#define GLAMO_GPIO11_OUTPUT (GLAMO_GPIO11 | GLAMO_GPIO_F_OUT) ++#define GLAMO_GPIO11_LSDA (GLAMO_GPIO11 | GLAMO_GPIO_F_FUNC) ++ ++#define GLAMO_GPIO12 GLAMO_GPIONO(GLAMO_GPIO_BANKD, 0) ++#define GLAMO_GPIO12_INPUT (GLAMO_GPIO12 | GLAMO_GPIO_F_IN) ++#define GLAMO_GPIO12_OUTPUT (GLAMO_GPIO12 | GLAMO_GPIO_F_OUT) ++#define GLAMO_GPIO12_LSA0 (GLAMO_GPIO12 | GLAMO_GPIO_F_FUNC) ++ ++ ++#define REG_OF_GPIO(gpio) (((gpio & 0xf000) >> 12)*2 \ ++ + GLAMO_REG_GPIO_GEN1) ++#define NUM_OF_GPIO(gpio) ((gpio & 0x0f00) >> 8) ++#define GPIO_OUT_BIT(gpio) (1 << (NUM_OF_GPIO(gpio) + 0)) ++#define OUTPUT_BIT(gpio) (1 << (NUM_OF_GPIO(gpio) + 4)) ++#define INPUT_BIT(gpio) (1 << (NUM_OF_GPIO(gpio) + 8)) ++#define FUNC_BIT(gpio) (1 << (NUM_OF_GPIO(gpio) + 12)) ++ ++void glamo_gpio_setpin(struct glamo_core *glamo, unsigned int pin, ++ unsigned int value); ++ ++int glamo_gpio_getpin(struct glamo_core *glamo, unsigned int pin); ++ ++void glamo_gpio_cfgpin(struct glamo_core *glamo, unsigned int pinfunc); ++ ++ ++#endif /* _GLAMO_GPIO */ +diff -ruN --exclude='*.orig' --exclude='*.rej' linux-2.6.29-rc3.owrt/include/linux/gta01_battery.h linux-2.6.29-rc3.owrt.om/include/linux/gta01_battery.h +--- linux-2.6.29-rc3.owrt/include/linux/gta01_battery.h 1970-01-01 01:00:00.000000000 +0100 ++++ linux-2.6.29-rc3.owrt.om/include/linux/gta01_battery.h 2009-05-10 22:28:00.000000000 +0200 +@@ -0,0 +1,10 @@ ++#ifndef __GTA01_BATTERY_H__ ++#define __GTA01_BATTERY_H__ ++ ++struct gta01_bat_platform_data { ++ int (*get_charging_status)(void); ++ int (*get_voltage)(void); ++ int (*get_current)(void); ++}; ++ ++#endif +diff -ruN --exclude='*.orig' --exclude='*.rej' linux-2.6.29-rc3.owrt/include/linux/gta02_hdq.h linux-2.6.29-rc3.owrt.om/include/linux/gta02_hdq.h +--- linux-2.6.29-rc3.owrt/include/linux/gta02_hdq.h 1970-01-01 01:00:00.000000000 +0100 ++++ linux-2.6.29-rc3.owrt.om/include/linux/gta02_hdq.h 2009-05-10 22:28:00.000000000 +0200 +@@ -0,0 +1,18 @@ ++#ifndef __GTA02HDQ_H__ ++#define __GTA02HDQ_H__ ++ ++/* platform data */ ++ ++struct gta02_hdq_platform_data { ++ /* ++ * give an opportunity to use us as parent for ++ * devices that depend on us ++ */ ++ void (*attach_child_devices)(struct device *parent_device); ++}; ++ ++int gta02hdq_read(int address); ++int gta02hdq_write(int address, u8 data); ++int gta02hdq_initialized(void); ++ ++#endif +diff -ruN --exclude='*.orig' --exclude='*.rej' linux-2.6.29-rc3.owrt/include/linux/hdq.h linux-2.6.29-rc3.owrt.om/include/linux/hdq.h +--- linux-2.6.29-rc3.owrt/include/linux/hdq.h 1970-01-01 01:00:00.000000000 +0100 ++++ linux-2.6.29-rc3.owrt.om/include/linux/hdq.h 2009-05-10 22:28:00.000000000 +0200 +@@ -0,0 +1,32 @@ ++#ifndef __LINUX_HDQ_H__ ++#define __LINUX_HDQ_H__ ++ ++#include <linux/device.h> ++ ++#define HDQ_SAMPLE_PERIOD_US 10 ++ ++/* platform data */ ++ ++struct hdq_platform_data { ++ /* ++ * give an opportunity to use us as parent for ++ * devices that depend on us ++ */ ++ void (*attach_child_devices)(struct device *parent_device); ++ ++ void (*gpio_dir_out)(void); ++ void (*gpio_dir_in)(void); ++ void (*gpio_set)(int); ++ int (*gpio_get)(void); ++ ++ int (*enable_fiq)(void); ++ void (*disable_fiq)(void); ++ void (*kick_fiq)(void); ++ ++}; ++ ++int hdq_read(int address); ++int hdq_write(int address, u8 data); ++int hdq_initialized(void); ++ ++#endif +diff -ruN --exclude='*.orig' --exclude='*.rej' linux-2.6.29-rc3.owrt/include/linux/i2c-id.h linux-2.6.29-rc3.owrt.om/include/linux/i2c-id.h +--- linux-2.6.29-rc3.owrt/include/linux/i2c-id.h 2009-05-10 22:04:47.000000000 +0200 ++++ linux-2.6.29-rc3.owrt.om/include/linux/i2c-id.h 2009-05-10 22:28:00.000000000 +0200 +@@ -73,6 +73,15 @@ + #define I2C_DRIVERID_CS5345 96 /* cs5345 audio processor */ + + #define I2C_DRIVERID_OV7670 1048 /* Omnivision 7670 camera */ ++#define I2C_DRIVERID_PCF50606 1049 ++#define I2C_DRIVERID_PCF50633 1051 ++#define I2C_DRIVERID_PCA9632 1052 ++ ++#define I2C_DRIVERID_S5K_3XA 1500 /* Samsung MobileAP I2C adapter */ ++#define I2C_DRIVERID_S5K_53BEA 1501 /* Samsung MobileAP I2C adapter */ ++#define I2C_DRIVERID_S5K_532 1502 /* Samsung MobileAP I2C adapter */ ++#define I2C_DRIVERID_S5K_3BA 1503 /* Samsung MobileAP I2C adapter */ ++#define I2C_DRIVERID_S5K_4XA 1504 /* Samsung MobileAP I2C adapter */ + + /* + * ---- Adapter types ---------------------------------------------------- +diff -ruN --exclude='*.orig' --exclude='*.rej' linux-2.6.29-rc3.owrt/include/linux/jbt6k74.h linux-2.6.29-rc3.owrt.om/include/linux/jbt6k74.h +--- linux-2.6.29-rc3.owrt/include/linux/jbt6k74.h 1970-01-01 01:00:00.000000000 +0100 ++++ linux-2.6.29-rc3.owrt.om/include/linux/jbt6k74.h 2009-05-10 22:28:00.000000000 +0200 +@@ -0,0 +1,12 @@ ++#ifndef __JBT6K74_H__ ++#define __JBT6K74_H__ ++ ++#include <linux/spi/spi.h> ++ ++struct jbt6k74_platform_data { ++ void (*reset)(int devindex, int level); ++ void (*resuming)(int devindex); /* called when LCM is resumed */ ++ void (*probe_completed)(struct device *dev); ++}; ++ ++#endif +diff -ruN --exclude='*.orig' --exclude='*.rej' linux-2.6.29-rc3.owrt/include/linux/kernel.h linux-2.6.29-rc3.owrt.om/include/linux/kernel.h +--- linux-2.6.29-rc3.owrt/include/linux/kernel.h 2009-05-10 22:09:07.000000000 +0200 ++++ linux-2.6.29-rc3.owrt.om/include/linux/kernel.h 2009-05-10 22:28:00.000000000 +0200 +@@ -242,6 +242,8 @@ + extern int printk_ratelimit(void); + extern bool printk_timed_ratelimit(unsigned long *caller_jiffies, + unsigned int interval_msec); ++extern void (*printk_emergency_debug_spew_init)(void); ++extern void (*printk_emergency_debug_spew_send_string)(const char *); + #else + static inline int vprintk(const char *s, va_list args) + __attribute__ ((format (printf, 1, 0))); +diff -ruN --exclude='*.orig' --exclude='*.rej' linux-2.6.29-rc3.owrt/include/linux/kexec.h linux-2.6.29-rc3.owrt.om/include/linux/kexec.h +--- linux-2.6.29-rc3.owrt/include/linux/kexec.h 2009-05-10 22:04:47.000000000 +0200 ++++ linux-2.6.29-rc3.owrt.om/include/linux/kexec.h 2009-05-10 22:28:00.000000000 +0200 +@@ -1,7 +1,6 @@ + #ifndef LINUX_KEXEC_H + #define LINUX_KEXEC_H + +-#ifdef CONFIG_KEXEC + #include <linux/types.h> + #include <linux/list.h> + #include <linux/linkage.h> +@@ -11,6 +10,8 @@ + #include <linux/elf.h> + #include <asm/kexec.h> + ++#ifdef CONFIG_KEXEC ++ + /* Verify architecture specific macros are defined */ + + #ifndef KEXEC_SOURCE_MEMORY_LIMIT +diff -ruN --exclude='*.orig' --exclude='*.rej' linux-2.6.29-rc3.owrt/include/linux/l1k002.h linux-2.6.29-rc3.owrt.om/include/linux/l1k002.h +--- linux-2.6.29-rc3.owrt/include/linux/l1k002.h 1970-01-01 01:00:00.000000000 +0100 ++++ linux-2.6.29-rc3.owrt.om/include/linux/l1k002.h 2009-05-10 22:28:00.000000000 +0200 +@@ -0,0 +1,8 @@ ++#ifndef __LINUX_L1K002_H_ ++#define __LINUX_L1K002_H_ ++ ++struct l1k002_platform_data { ++ void (*pwr_onoff)(int level); ++}; ++ ++#endif /* __LINUX_L1K002_H_ */ +diff -ruN --exclude='*.orig' --exclude='*.rej' linux-2.6.29-rc3.owrt/include/linux/lis302dl.h linux-2.6.29-rc3.owrt.om/include/linux/lis302dl.h +--- linux-2.6.29-rc3.owrt/include/linux/lis302dl.h 1970-01-01 01:00:00.000000000 +0100 ++++ linux-2.6.29-rc3.owrt.om/include/linux/lis302dl.h 2009-05-10 22:28:00.000000000 +0200 +@@ -0,0 +1,152 @@ ++#ifndef _LINUX_LIS302DL_H ++#define _LINUX_LIS302DL_H ++ ++#include <linux/types.h> ++#include <linux/spi/spi.h> ++#include <linux/input.h> ++#include <linux/workqueue.h> ++ ++struct lis302dl_info; ++ ++struct lis302dl_platform_data { ++ char *name; ++ unsigned long pin_chip_select; ++ unsigned long pin_clk; ++ unsigned long pin_mosi; ++ unsigned long pin_miso; ++ int open_drain; ++ int interrupt; ++ void (*lis302dl_suspend_io)(struct lis302dl_info *, int resuming); ++}; ++ ++struct lis302dl_info { ++ struct lis302dl_platform_data *pdata; ++ struct device *dev; ++ struct input_dev *input_dev; ++ unsigned int flags; ++ unsigned int threshold; ++ unsigned int duration; ++ u32 overruns; ++ struct { ++ unsigned int threshold; /* mg */ ++ unsigned int duration; /* ms */ ++ } wakeup; ++ ++ struct spi_device *spi; ++ u_int8_t regs[0x40]; ++}; ++ ++enum lis302dl_reg { ++ LIS302DL_REG_WHO_AM_I = 0x0f, ++ LIS302DL_REG_CTRL1 = 0x20, ++ LIS302DL_REG_CTRL2 = 0x21, ++ LIS302DL_REG_CTRL3 = 0x22, ++ LIS302DL_REG_HP_FILTER_RESET = 0x23, ++ LIS302DL_REG_STATUS = 0x27, ++ LIS302DL_REG_OUT_X = 0x29, ++ LIS302DL_REG_OUT_Y = 0x2b, ++ LIS302DL_REG_OUT_Z = 0x2d, ++ LIS302DL_REG_FF_WU_CFG_1 = 0x30, ++ LIS302DL_REG_FF_WU_SRC_1 = 0x31, ++ LIS302DL_REG_FF_WU_THS_1 = 0x32, ++ LIS302DL_REG_FF_WU_DURATION_1 = 0x33, ++ LIS302DL_REG_FF_WU_CFG_2 = 0x34, ++ LIS302DL_REG_FF_WU_SRC_2 = 0x35, ++ LIS302DL_REG_FF_WU_THS_2 = 0x36, ++ LIS302DL_REG_FF_WU_DURATION_2 = 0x37, ++ LIS302DL_REG_CLICK_CFG = 0x38, ++ LIS302DL_REG_CLICK_SRC = 0x39, ++ LIS302DL_REG_CLICK_THSY_X = 0x3b, ++ LIS302DL_REG_CLICK_THSZ = 0x3c, ++ LIS302DL_REG_CLICK_TIME_LIMIT = 0x3d, ++ LIS302DL_REG_CLICK_LATENCY = 0x3e, ++ LIS302DL_REG_CLICK_WINDOW = 0x3f, ++}; ++ ++enum lis302dl_reg_ctrl1 { ++ LIS302DL_CTRL1_Xen = 0x01, ++ LIS302DL_CTRL1_Yen = 0x02, ++ LIS302DL_CTRL1_Zen = 0x04, ++ LIS302DL_CTRL1_STM = 0x08, ++ LIS302DL_CTRL1_STP = 0x10, ++ LIS302DL_CTRL1_FS = 0x20, ++ LIS302DL_CTRL1_PD = 0x40, ++ LIS302DL_CTRL1_DR = 0x80, ++}; ++ ++enum lis302dl_reg_ctrl2 { ++ LIS302DL_CTRL2_HPC1 = 0x01, ++ LIS302DL_CTRL2_HPC2 = 0x02, ++ LIS302DL_CTRL2_HPFF1 = 0x04, ++ LIS302DL_CTRL2_HPFF2 = 0x08, ++ LIS302DL_CTRL2_FDS = 0x10, ++ LIS302DL_CTRL2_BOOT = 0x40, ++ LIS302DL_CTRL2_SIM = 0x80, ++}; ++enum lis302dl_reg_ctrl3 { ++ LIS302DL_CTRL3_PP_OD = 0x40, ++ LIS302DL_CTRL3_IHL = 0x80, ++}; ++ ++enum lis302dl_reg_status { ++ LIS302DL_STATUS_XDA = 0x01, ++ LIS302DL_STATUS_YDA = 0x02, ++ LIS302DL_STATUS_ZDA = 0x04, ++ LIS302DL_STATUS_XYZDA = 0x08, ++ LIS302DL_STATUS_XOR = 0x10, ++ LIS302DL_STATUS_YOR = 0x20, ++ LIS302DL_STATUS_ZOR = 0x40, ++ LIS302DL_STATUS_XYZOR = 0x80, ++}; ++ ++/* Wakeup/freefall interrupt defs */ ++enum lis302dl_reg_ffwucfg { ++ LIS302DL_FFWUCFG_XLIE = 0x01, ++ LIS302DL_FFWUCFG_XHIE = 0x02, ++ LIS302DL_FFWUCFG_YLIE = 0x04, ++ LIS302DL_FFWUCFG_YHIE = 0x08, ++ LIS302DL_FFWUCFG_ZLIE = 0x10, ++ LIS302DL_FFWUCFG_ZHIE = 0x20, ++ LIS302DL_FFWUCFG_LIR = 0x40, ++ LIS302DL_FFWUCFG_AOI = 0x80, ++}; ++ ++enum lis302dl_reg_ffwuths { ++ LIS302DL_FFWUTHS_DCRM = 0x80, ++}; ++ ++enum lis302dl_reg_ffwusrc { ++ LIS302DL_FFWUSRC_XL = 0x01, ++ LIS302DL_FFWUSRC_XH = 0x02, ++ LIS302DL_FFWUSRC_YL = 0x04, ++ LIS302DL_FFWUSRC_YH = 0x08, ++ LIS302DL_FFWUSRC_ZL = 0x10, ++ LIS302DL_FFWUSRC_ZH = 0x20, ++ LIS302DL_FFWUSRC_IA = 0x40, ++}; ++ ++enum lis302dl_reg_cloik_src { ++ LIS302DL_CLICKSRC_SINGLE_X = 0x01, ++ LIS302DL_CLICKSRC_DOUBLE_X = 0x02, ++ LIS302DL_CLICKSRC_SINGLE_Y = 0x04, ++ LIS302DL_CLICKSRC_DOUBLE_Y = 0x08, ++ LIS302DL_CLICKSRC_SINGLE_Z = 0x10, ++ LIS302DL_CLICKSRC_DOUBLE_Z = 0x20, ++ LIS302DL_CLICKSRC_IA = 0x40, ++}; ++ ++#define LIS302DL_WHO_AM_I_MAGIC 0x3b ++ ++#define LIS302DL_F_WUP_FF_1 0x0001 /* wake up from free fall */ ++#define LIS302DL_F_WUP_FF_2 0x0002 ++#define LIS302DL_F_WUP_FF 0x0003 ++#define LIS302DL_F_WUP_CLICK 0x0004 ++#define LIS302DL_F_POWER 0x0010 ++#define LIS302DL_F_FS 0x0020 /* ADC full scale */ ++#define LIS302DL_F_INPUT_OPEN 0x0040 /* Set if input device is opened */ ++#define LIS302DL_F_IRQ_WAKE 0x0080 /* IRQ is setup in wake mode */ ++#define LIS302DL_F_DR 0x0100 /* Data rate, 400Hz/100Hz */ ++ ++ ++#endif /* _LINUX_LIS302DL_H */ ++ +diff -ruN --exclude='*.orig' --exclude='*.rej' linux-2.6.29-rc3.owrt/include/linux/lp5521.h linux-2.6.29-rc3.owrt.om/include/linux/lp5521.h +--- linux-2.6.29-rc3.owrt/include/linux/lp5521.h 1970-01-01 01:00:00.000000000 +0100 ++++ linux-2.6.29-rc3.owrt.om/include/linux/lp5521.h 2009-05-10 22:28:00.000000000 +0200 +@@ -0,0 +1,75 @@ ++#ifndef _LINUX_LP5521_H_ ++#define _LINUX_LP5521_H_ ++ ++#define LP5521_REG_ENABLE 0x00 ++#define LP5521_REG_OP_MODE 0x01 ++ ++#define LP5521_REG_R_PWM 0x02 ++#define LP5521_REG_G_PWM 0x03 ++#define LP5521_REG_B_PWM 0x04 ++ ++#define LP5521_REG_R_CUR 0x05 ++#define LP5521_REG_G_CUR 0x06 ++#define LP5521_REG_B_CUR 0x07 ++ ++#define LP5521_REG_CONFIG 0x08 ++ ++#define LP5521_REG_R_PC 0x09 ++#define LP5521_REG_G_PC 0x0a ++#define LP5521_REG_B_PC 0x0b ++ ++#define LP5521_REG_STATUS 0x0c ++#define LP5521_REG_RESET 0x0d ++#define LP5521_REG_GPO 0x0e ++ ++enum { ++ LP5521_NC, ++ LP5521_CONNECTED, ++}; ++ ++enum { ++ LP5521_BLUE, ++ LP5521_GREEN, ++ LP5521_RED, ++ LP5521_NUM_CH, ++}; ++ ++enum { ++ LP5521_MODE_DISABLE, ++ LP5521_MODE_LOAD, ++ LP5521_MODE_RUN, ++ LP5521_MODE_DIRECT, ++}; ++ ++enum CP_MODE { ++ LP5521_CPM_OFF, ++ LP5521_CPM_BY_PASS, ++ LP5521_CPM_1_5X, ++ LP5521_CPM_AUTO, ++}; ++ ++enum CLK_SRC { ++ LP5521_EXT_CLK, ++ LP5521_INT_CLK, ++ LP5521_AUTO_CLK, ++}; ++ ++#define LP5521_FEAT_TRIG 0x00000001 ++#define LP5521_FEAT_GPO 0x00000002 ++ ++ ++struct lp5521_platform_data { ++ int channels[LP5521_NUM_CH]; ++ /* chip enable */ ++ void (*ext_enable)(int level); ++}; ++ ++struct lp5521 { ++ struct device *dev; ++ struct i2c_client *client; ++ struct mutex lock; ++ int irq; ++ ++ struct lp5521_platform_data *pdata; ++}; ++#endif /* LINUX_LP5521_H */ +diff -ruN --exclude='*.orig' --exclude='*.rej' linux-2.6.29-rc3.owrt/include/linux/mfd/pcf50606/adc.h linux-2.6.29-rc3.owrt.om/include/linux/mfd/pcf50606/adc.h +--- linux-2.6.29-rc3.owrt/include/linux/mfd/pcf50606/adc.h 1970-01-01 01:00:00.000000000 +0100 ++++ linux-2.6.29-rc3.owrt.om/include/linux/mfd/pcf50606/adc.h 2009-05-10 22:28:00.000000000 +0200 +@@ -0,0 +1,72 @@ ++/* ++ * adc.h -- Driver for NXP PCF50606 ADC ++ * ++ * (C) 2006-2008 by Openmoko, Inc. ++ * All rights reserved. ++ * ++ * 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. ++ */ ++ ++#ifndef __LINUX_MFD_PCF50606_ADC_H ++#define __LINUX_MFD_PCF50606_ADC_H ++ ++#include <linux/mfd/pcf50633/core.h> ++#include <linux/platform_device.h> ++ ++/* ADC Registers */ ++#define PCF50606_REG_ADCC1 0x2e ++#define PCF50606_REG_ADCC2 0x2f ++#define PCF50606_REG_ADCS1 0x30 ++#define PCF50606_REG_ADCS2 0x31 ++#define PCF50606_REG_ADCS3 0x32 ++ ++#define PCF50606_ADCC1_TSCMODACT 0x01 ++#define PCF50606_ADCC1_TSCMODSTB 0x02 ++#define PCF50606_ADCC1_TRATSET 0x04 ++#define PCF50606_ADCC1_NTCSWAPE 0x08 ++#define PCF50606_ADCC1_NTCSWAOFF 0x10 ++#define PCF50606_ADCC1_EXTSYNCBREAK 0x20 ++ /* reserved */ ++#define PCF50606_ADCC1_TSCINT 0x80 ++ ++#define PCF50606_ADCC2_ADCSTART 0x01 ++ /* see enum pcf50606_adcc2_adcmux */ ++#define PCF50606_ADCC2_SYNC_NONE 0x00 ++#define PCF50606_ADCC2_SYNC_TXON 0x20 ++#define PCF50606_ADCC2_SYNC_PWREN1 0x40 ++#define PCF50606_ADCC2_SYNC_PWREN2 0x60 ++#define PCF50606_ADCC2_RES_10BIT 0x00 ++#define PCF50606_ADCC2_RES_8BIT 0x80 ++ ++#define PCF50606_ADCC2_ADCMUX_MASK (0xf << 1) ++ ++#define ADCMUX_SHIFT 1 ++#define PCF50606_ADCMUX_BATVOLT_RES (0x0 << ADCMUX_SHIFT) ++#define PCF50606_ADCMUX_BATVOLT_SUBTR (0x1 << ADCMUX_SHIFT) ++#define PCF50606_ADCMUX_ADCIN1_RES (0x2 << ADCMUX_SHIFT) ++#define PCF50606_ADCMUX_ADCIN1_SUBTR (0x3 << ADCMUX_SHIFT) ++#define PCF50606_ADCMUX_BATTEMP (0x4 << ADCMUX_SHIFT) ++#define PCF50606_ADCMUX_ADCIN2 (0x5 << ADCMUX_SHIFT) ++#define PCF50606_ADCMUX_ADCIN3 (0x6 << ADCMUX_SHIFT) ++#define PCF50606_ADCMUX_ADCIN3_RATIO (0x7 << ADCMUX_SHIFT) ++#define PCF50606_ADCMUX_XPOS (0x8 << ADCMUX_SHIFT) ++#define PCF50606_ADCMUX_YPOS (0x9 << ADCMUX_SHIFT) ++#define PCF50606_ADCMUX_P1 (0xa << ADCMUX_SHIFT) ++#define PCF50606_ADCMUX_P2 (0xb << ADCMUX_SHIFT) ++#define PCF50606_ADCMUX_BATVOLT_ADCIN1 (0xc << ADCMUX_SHIFT) ++#define PCF50606_ADCMUX_XY_SEQUENCE (0xe << ADCMUX_SHIFT) ++#define PCF50606_P1_P2_RESISTANCE (0xf << ADCMUX_SHIFT) ++ ++#define PCF50606_ADCS2_ADCRDY 0x80 ++ ++extern int ++pcf50606_adc_async_read(struct pcf50606 *pcf, int mux, ++ void (*callback)(struct pcf50606 *, void *, int), ++ void *callback_param); ++extern int ++pcf50606_adc_sync_read(struct pcf50606 *pcf, int mux); ++ ++#endif /* __LINUX_PCF50606_ADC_H */ +diff -ruN --exclude='*.orig' --exclude='*.rej' linux-2.6.29-rc3.owrt/include/linux/mfd/pcf50606/core.h linux-2.6.29-rc3.owrt.om/include/linux/mfd/pcf50606/core.h +--- linux-2.6.29-rc3.owrt/include/linux/mfd/pcf50606/core.h 1970-01-01 01:00:00.000000000 +0100 ++++ linux-2.6.29-rc3.owrt.om/include/linux/mfd/pcf50606/core.h 2009-05-10 22:28:00.000000000 +0200 +@@ -0,0 +1,170 @@ ++/* ++ * core.h -- Core driver for NXP PCF50606 ++ * ++ * (C) 2006-2008 by Openmoko, Inc. ++ * All rights reserved. ++ * ++ * 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. ++ */ ++ ++#ifndef __LINUX_MFD_PCF50606_CORE_H ++#define __LINUX_MFD_PCF50606_CORE_H ++ ++#include <linux/i2c.h> ++#include <linux/workqueue.h> ++#include <linux/regulator/driver.h> ++#include <linux/regulator/machine.h> ++#include <linux/power_supply.h> ++ ++struct pcf50606; ++ ++#define PCF50606_NUM_REGULATORS 8 ++ ++struct pcf50606_platform_data { ++ struct regulator_init_data reg_init_data[PCF50606_NUM_REGULATORS]; ++ ++ char **batteries; ++ int num_batteries; ++ ++ /* Callbacks */ ++ void (*probe_done)(struct pcf50606 *); ++ void (*mbc_event_callback)(struct pcf50606 *, int); ++ void (*regulator_registered)(struct pcf50606 *, int); ++ void (*force_shutdown)(struct pcf50606 *); ++ ++ u8 resumers[3]; ++}; ++ ++struct pcf50606_subdev_pdata { ++ struct pcf50606 *pcf; ++}; ++ ++struct pcf50606_irq { ++ void (*handler)(int, void *); ++ void *data; ++}; ++ ++int pcf50606_register_irq(struct pcf50606 *pcf, int irq, ++ void (*handler) (int, void *), void *data); ++int pcf50606_free_irq(struct pcf50606 *pcf, int irq); ++ ++int pcf50606_irq_mask(struct pcf50606 *pcf, int irq); ++int pcf50606_irq_unmask(struct pcf50606 *pcf, int irq); ++int pcf50606_irq_mask_get(struct pcf50606 *pcf, int irq); ++ ++int pcf50606_read_block(struct pcf50606 *, u8 reg, ++ int nr_regs, u8 *data); ++int pcf50606_write_block(struct pcf50606 *pcf, u8 reg, ++ int nr_regs, u8 *data); ++u8 pcf50606_reg_read(struct pcf50606 *, u8 reg); ++int pcf50606_reg_write(struct pcf50606 *pcf, u8 reg, u8 val); ++ ++int pcf50606_reg_set_bit_mask(struct pcf50606 *pcf, u8 reg, u8 mask, u8 val); ++int pcf50606_reg_clear_bits(struct pcf50606 *pcf, u8 reg, u8 bits); ++ ++/* Interrupt registers */ ++ ++#define PCF50606_REG_INT1 0x02 ++#define PCF50606_REG_INT2 0x03 ++#define PCF50606_REG_INT3 0x04 ++ ++#define PCF50606_REG_INT1M 0x05 ++#define PCF50606_REG_INT2M 0x06 ++#define PCF50606_REG_INT3M 0x07 ++ ++enum { ++ /* Chip IRQs */ ++ PCF50606_IRQ_ONKEYR, ++ PCF50606_IRQ_ONKEYF, ++ PCF50606_IRQ_ONKEY1S, ++ PCF50606_IRQ_EXTONR, ++ PCF50606_IRQ_EXTONF, ++ PCF50606_IRQ_RESERVED_1, ++ PCF50606_IRQ_SECOND, ++ PCF50606_IRQ_ALARM, ++ PCF50606_IRQ_CHGINS, ++ PCF50606_IRQ_CHGRM, ++ PCF50606_IRQ_CHGFOK, ++ PCF50606_IRQ_CHGERR, ++ PCF50606_IRQ_CHGFRDY, ++ PCF50606_IRQ_CHGPROT, ++ PCF50606_IRQ_CHGWD10S, ++ PCF50606_IRQ_CHGWDEXP, ++ PCF50606_IRQ_ADCRDY, ++ PCF50606_IRQ_ACDINS, ++ PCF50606_IRQ_ACDREM, ++ PCF50606_IRQ_TSCPRES, ++ PCF50606_IRQ_RESERVED_2, ++ PCF50606_IRQ_RESERVED_3, ++ PCF50606_IRQ_LOWBAT, ++ PCF50606_IRQ_HIGHTMP, ++ ++ /* Always last */ ++ PCF50606_NUM_IRQ, ++}; ++ ++struct pcf50606 { ++ struct device *dev; ++ struct i2c_client *i2c_client; ++ ++ struct pcf50606_platform_data *pdata; ++ int irq; ++ struct pcf50606_irq irq_handler[PCF50606_NUM_IRQ]; ++ struct work_struct irq_work; ++ struct mutex lock; ++ ++ u8 mask_regs[3]; ++ ++ u8 suspend_irq_masks[3]; ++ u8 resume_reason[3]; ++ int is_suspended; ++ ++ int onkey1s_held; ++ ++ struct platform_device *rtc_pdev; ++ struct platform_device *mbc_pdev; ++ struct platform_device *adc_pdev; ++ struct platform_device *input_pdev; ++ struct platform_device *wdt_pdev; ++ struct platform_device *regulator_pdev[PCF50606_NUM_REGULATORS]; ++}; ++ ++enum pcf50606_reg_int1 { ++ PCF50606_INT1_ONKEYR = 0x01, /* ONKEY rising edge */ ++ PCF50606_INT1_ONKEYF = 0x02, /* ONKEY falling edge */ ++ PCF50606_INT1_ONKEY1S = 0x04, /* OMKEY at least 1sec low */ ++ PCF50606_INT1_EXTONR = 0x08, /* EXTON rising edge */ ++ PCF50606_INT1_EXTONF = 0x10, /* EXTON falling edge */ ++ PCF50606_INT1_SECOND = 0x40, /* RTC periodic second interrupt */ ++ PCF50606_INT1_ALARM = 0x80, /* RTC alarm time is reached */ ++}; ++ ++enum pcf50606_reg_int2 { ++ PCF50606_INT2_CHGINS = 0x01, /* Charger inserted */ ++ PCF50606_INT2_CHGRM = 0x02, /* Charger removed */ ++ PCF50606_INT2_CHGFOK = 0x04, /* Fast charging OK */ ++ PCF50606_INT2_CHGERR = 0x08, /* Error in charging mode */ ++ PCF50606_INT2_CHGFRDY = 0x10, /* Fast charge completed */ ++ PCF50606_INT2_CHGPROT = 0x20, /* Charging protection interrupt */ ++ PCF50606_INT2_CHGWD10S = 0x40, /* Charger watchdig expires in 10s */ ++ PCF50606_INT2_CHGWDEXP = 0x80, /* Charger watchdog expires */ ++}; ++ ++enum pcf50606_reg_int3 { ++ PCF50606_INT3_ADCRDY = 0x01, /* ADC conversion finished */ ++ PCF50606_INT3_ACDINS = 0x02, /* Accessory inserted */ ++ PCF50606_INT3_ACDREM = 0x04, /* Accessory removed */ ++ PCF50606_INT3_TSCPRES = 0x08, /* Touch screen pressed */ ++ PCF50606_INT3_LOWBAT = 0x40, /* Low battery voltage */ ++ PCF50606_INT3_HIGHTMP = 0x80, /* High temperature */ ++}; ++ ++/* Misc regs */ ++ ++#define PCF50606_REG_OOCC1 0x08 ++#define PCF50606_OOCC1_GOSTDBY 0x01 ++#endif ++ +diff -ruN --exclude='*.orig' --exclude='*.rej' linux-2.6.29-rc3.owrt/include/linux/mfd/pcf50606/gpo.h linux-2.6.29-rc3.owrt.om/include/linux/mfd/pcf50606/gpo.h +--- linux-2.6.29-rc3.owrt/include/linux/mfd/pcf50606/gpo.h 1970-01-01 01:00:00.000000000 +0100 ++++ linux-2.6.29-rc3.owrt.om/include/linux/mfd/pcf50606/gpo.h 2009-05-10 22:28:00.000000000 +0200 +@@ -0,0 +1,42 @@ ++/* ++ * gpo.h -- GPO driver for NXP PCF50606 ++ * ++ * (C) 2006-2008 by Openmoko, Inc. ++ * All rights reserved. ++ * ++ * 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. ++ */ ++ ++#ifndef __LINUX_MFD_PCF50606_GPO_H ++#define __LINUX_MFD_PCF50606_GPO_H ++ ++#include <linux/mfd/pcf50633/core.h> ++ ++#define PCF50606_REG_GPOC1 0x38 ++#define PCF50606_REG_GPOC2 0x39 ++#define PCF50606_REG_GPOC3 0x3a ++#define PCF50606_REG_GPOC4 0x3b ++#define PCF50606_REG_GPOC5 0x3c ++ ++#define PCF50606_GPO1 PCF50606_REG_GPOC1 ++#define PCF50606_GPO2 PCF50606_REG_GPOC1 ++#define PCF50606_GPOOD1 PCF50606_REG_GPOC2 ++#define PCF50606_GPOOD2 PCF50606_REG_GPOC3 ++#define PCF50606_GPOOD3 PCF50606_REG_GPOC4 ++#define PCF50606_GPOOD4 PCF50606_REG_GPOC5 ++ ++#define PCF50606_GPOCFG_GPOSEL_MASK 0x07 ++ ++void pcf50606_gpo_set_active(struct pcf50606 *pcf, int gpo, int value); ++int pcf50606_gpo_get_active(struct pcf50606 *pcf, int gpo); ++void pcf50606_gpo_set_standby(struct pcf50606 *pcf, int gpo, int value); ++int pcf50606_gpo_get_standby(struct pcf50606 *pcf, int gpo); ++ ++void pcf50606_gpo_invert_set(struct pcf50606 *, int gpo, int invert); ++int pcf50606_gpo_invert_get(struct pcf50606 *pcf, int gpo); ++ ++#endif /* __LINUX_MFD_PCF50606_GPIO_H */ ++ +diff -ruN --exclude='*.orig' --exclude='*.rej' linux-2.6.29-rc3.owrt/include/linux/mfd/pcf50606/mbc.h linux-2.6.29-rc3.owrt.om/include/linux/mfd/pcf50606/mbc.h +--- linux-2.6.29-rc3.owrt/include/linux/mfd/pcf50606/mbc.h 1970-01-01 01:00:00.000000000 +0100 ++++ linux-2.6.29-rc3.owrt.om/include/linux/mfd/pcf50606/mbc.h 2009-05-10 22:28:00.000000000 +0200 +@@ -0,0 +1,52 @@ ++/* ++ * mbc.h -- Driver for NXP PCF50606 Main Battery Charger ++ * ++ * (C) 2006-2008 by Openmoko, Inc. ++ * All rights reserved. ++ * ++ * 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. ++ */ ++ ++#ifndef __LINUX_MFD_PCF50606_MBC_H ++#define __LINUX_MFD_PCF50606_MBC_H ++ ++#include <linux/mfd/pcf50606/core.h> ++#include <linux/platform_device.h> ++ ++#define PCF50606_REG_OOCS 0x01 ++ ++/* Charger OK */ ++#define PCF50606_OOCS_CHGOK 0x20 ++ ++#define PCF50606_REG_MBCC1 0x29 ++#define PCF50606_REG_MBCC2 0x2a ++#define PCF50606_REG_MBCC3 0x2b ++#define PCF50606_REG_MBCS1 0x2c ++ ++#define PCF50606_MBCC1_CHGAPE 0x01 ++#define PCF50606_MBCC1_AUTOFST 0x02 ++#define PCF50606_MBCC1_CHGMOD_MASK 0x1c ++#define PCF50606_MBCC1_CHGMOD_QUAL 0x00 ++#define PCF50606_MBCC1_CHGMOD_PRE 0x04 ++#define PCF50606_MBCC1_CHGMOD_TRICKLE 0x08 ++#define PCF50606_MBCC1_CHGMOD_FAST_CCCV 0x0c ++#define PCF50606_MBCC1_CHGMOD_FAST_NOCC 0x10 ++#define PCF50606_MBCC1_CHGMOD_FAST_NOCV 0x14 ++#define PCF50606_MBCC1_CHGMOD_FAST_SW 0x18 ++#define PCF50606_MBCC1_CHGMOD_IDLE 0x1c ++#define PCF50606_MBCC1_DETMOD_LOWCHG 0x20 ++#define PCF50606_MBCC1_DETMOD_WDRST 0x40 ++ ++#define PCF50606_MBCC1_CHGMOD_SHIFT 2 ++ ++/* Charger status */ ++#define PCF50606_MBC_CHARGER_ONLINE 0x01 ++#define PCF50606_MBC_CHARGER_ACTIVE 0x02 ++ ++void pcf50606_charge_fast(struct pcf50606 *pcf, int on); ++ ++#endif ++ +diff -ruN --exclude='*.orig' --exclude='*.rej' linux-2.6.29-rc3.owrt/include/linux/mfd/pcf50606/pmic.h linux-2.6.29-rc3.owrt.om/include/linux/mfd/pcf50606/pmic.h +--- linux-2.6.29-rc3.owrt/include/linux/mfd/pcf50606/pmic.h 1970-01-01 01:00:00.000000000 +0100 ++++ linux-2.6.29-rc3.owrt.om/include/linux/mfd/pcf50606/pmic.h 2009-05-10 22:28:00.000000000 +0200 +@@ -0,0 +1,73 @@ ++#ifndef __LINUX_MFD_PCF50606_PMIC_H ++#define __LINUX_MFD_PCF50606_PMIC_H ++ ++#define PCF50606_REG_DCDC1 0x1b ++#define PCF50606_REG_DCDC2 0x1c ++#define PCF50606_REG_DCDC3 0x1d ++#define PCF50606_REG_DCDC4 0x1e ++#define PCF50606_REG_DCDEC1 0x1f ++#define PCF50606_REG_DCDEC2 0x20 ++#define PCF50606_REG_DCUDC1 0x21 ++#define PCF50606_REG_DCUDC2 0x22 ++#define PCF50606_REG_IOREGC 0x23 ++#define PCF50606_REG_D1REGC1 0x24 ++#define PCF50606_REG_D2REGC1 0x25 ++#define PCF50606_REG_D3REGC1 0x26 ++#define PCF50606_REG_LPREGC1 0x27 ++#define PCF50606_REG_LPREGC2 0x28 ++ ++/* used by PSSC, PWROKM, PWROKS, */ ++enum pcf50606_regu { ++ PCF50606_REGU_DCD = 0x01, /* DCD in phase 2 */ ++ PCF50606_REGU_DCDE = 0x02, /* DCDE in phase 2 */ ++ PCF50606_REGU_DCUD = 0x04, /* DCDU in phase 2 */ ++ PCF50606_REGU_IO = 0x08, /* IO in phase 2 */ ++ PCF50606_REGU_D1 = 0x10, /* D1 in phase 2 */ ++ PCF50606_REGU_D2 = 0x20, /* D2 in phase 2 */ ++ PCF50606_REGU_D3 = 0x40, /* D3 in phase 2 */ ++ PCF50606_REGU_LP = 0x80, /* LP in phase 2 */ ++}; ++ ++enum pcf50606_reg_dcdc4 { ++ PCF50606_DCDC4_MODE_AUTO = 0x00, ++ PCF50606_DCDC4_MODE_PWM = 0x01, ++ PCF50606_DCDC4_MODE_PCF = 0x02, ++ PCF50606_DCDC4_OFF_FLOAT = 0x00, ++ PCF50606_DCDC4_OFF_BYPASS = 0x04, ++ PCF50606_DCDC4_OFF_PULLDOWN = 0x08, ++ PCF50606_DCDC4_CURLIM_500mA = 0x00, ++ PCF50606_DCDC4_CURLIM_750mA = 0x10, ++ PCF50606_DCDC4_CURLIM_1000mA = 0x20, ++ PCF50606_DCDC4_CURLIM_1250mA = 0x30, ++ PCF50606_DCDC4_TOGGLE = 0x40, ++ PCF50606_DCDC4_REGSEL_DCDC2 = 0x80, ++}; ++ ++enum pcf50606_reg_dcdec2 { ++ PCF50606_DCDEC2_MODE_AUTO = 0x00, ++ PCF50606_DCDEC2_MODE_PWM = 0x01, ++ PCF50606_DCDEC2_MODE_PCF = 0x02, ++ PCF50606_DCDEC2_OFF_FLOAT = 0x00, ++ PCF50606_DCDEC2_OFF_BYPASS = 0x04, ++}; ++ ++enum pcf50606_reg_dcudc2 { ++ PCF50606_DCUDC2_MODE_AUTO = 0x00, ++ PCF50606_DCUDC2_MODE_PWM = 0x01, ++ PCF50606_DCUDC2_MODE_PCF = 0x02, ++ PCF50606_DCUDC2_OFF_FLOAT = 0x00, ++ PCF50606_DCUDC2_OFF_BYPASS = 0x04, ++}; ++ ++enum pcf50606_regulator_id { ++ PCF50606_REGULATOR_DCD, ++ PCF50606_REGULATOR_DCDE, ++ PCF50606_REGULATOR_DCUD, ++ PCF50606_REGULATOR_D1REG, ++ PCF50606_REGULATOR_D2REG, ++ PCF50606_REGULATOR_D3REG, ++ PCF50606_REGULATOR_LPREG, ++ PCF50606_REGULATOR_IOREG, ++}; ++ ++#endif +diff -ruN --exclude='*.orig' --exclude='*.rej' linux-2.6.29-rc3.owrt/include/linux/mfd/pcf50633/core.h linux-2.6.29-rc3.owrt.om/include/linux/mfd/pcf50633/core.h +--- linux-2.6.29-rc3.owrt/include/linux/mfd/pcf50633/core.h 2009-05-10 22:04:47.000000000 +0200 ++++ linux-2.6.29-rc3.owrt.om/include/linux/mfd/pcf50633/core.h 2009-05-10 22:28:00.000000000 +0200 +@@ -29,6 +29,10 @@ + char **batteries; + int num_batteries; + ++ int charging_restart_interval; ++ ++ int chg_ref_current_ma; ++ + /* Callbacks */ + void (*probe_done)(struct pcf50633 *); + void (*mbc_event_callback)(struct pcf50633 *, int); +@@ -206,7 +210,8 @@ + }; + + /* misc. registers */ +-#define PCF50633_REG_OOCSHDWN 0x0c ++#define PCF50633_REG_OOCSHDWN 0x0c ++#define PCF50633_OOCSHDWN_GOSTDBY 0x01 + + /* LED registers */ + #define PCF50633_REG_LEDOUT 0x28 +diff -ruN --exclude='*.orig' --exclude='*.rej' linux-2.6.29-rc3.owrt/include/linux/mfd/pcf50633/mbc.h linux-2.6.29-rc3.owrt.om/include/linux/mfd/pcf50633/mbc.h +--- linux-2.6.29-rc3.owrt/include/linux/mfd/pcf50633/mbc.h 2009-05-10 22:04:47.000000000 +0200 ++++ linux-2.6.29-rc3.owrt.om/include/linux/mfd/pcf50633/mbc.h 2009-05-10 22:28:00.000000000 +0200 +@@ -128,7 +128,5 @@ + int pcf50633_mbc_usb_curlim_set(struct pcf50633 *pcf, int ma); + + int pcf50633_mbc_get_status(struct pcf50633 *); +-void pcf50633_mbc_set_status(struct pcf50633 *, int what, int status); +- + #endif + +diff -ruN --exclude='*.orig' --exclude='*.rej' linux-2.6.29-rc3.owrt/include/linux/mmc/core.h linux-2.6.29-rc3.owrt.om/include/linux/mmc/core.h +--- linux-2.6.29-rc3.owrt/include/linux/mmc/core.h 2009-05-10 22:04:47.000000000 +0200 ++++ linux-2.6.29-rc3.owrt.om/include/linux/mmc/core.h 2009-05-10 22:28:00.000000000 +0200 +@@ -129,6 +129,8 @@ + struct mmc_host; + struct mmc_card; + ++extern void mmc_flush_scheduled_work(void); ++ + extern void mmc_wait_for_req(struct mmc_host *, struct mmc_request *); + extern int mmc_wait_for_cmd(struct mmc_host *, struct mmc_command *, int); + extern int mmc_wait_for_app_cmd(struct mmc_host *, struct mmc_card *, +diff -ruN --exclude='*.orig' --exclude='*.rej' linux-2.6.29-rc3.owrt/include/linux/mmc/sdio_ids.h linux-2.6.29-rc3.owrt.om/include/linux/mmc/sdio_ids.h +--- linux-2.6.29-rc3.owrt/include/linux/mmc/sdio_ids.h 2009-05-10 22:04:47.000000000 +0200 ++++ linux-2.6.29-rc3.owrt.om/include/linux/mmc/sdio_ids.h 2009-05-10 22:28:00.000000000 +0200 +@@ -25,5 +25,9 @@ + + #define SDIO_VENDOR_ID_MARVELL 0x02df + #define SDIO_DEVICE_ID_MARVELL_LIBERTAS 0x9103 ++#define SDIO_DEVICE_ID_MARVELL_88W8688 0x9104 ++#define SDIO_VENDOR_ID_ATHEROS 0x0271 ++#define SDIO_DEVICE_ID_ATHEROS_AR6001 0x0100 ++#define SDIO_DEVICE_ID_ATHEROS_AR6002 0x0200 + + #endif +diff -ruN --exclude='*.orig' --exclude='*.rej' linux-2.6.29-rc3.owrt/include/linux/mm.h linux-2.6.29-rc3.owrt.om/include/linux/mm.h +--- linux-2.6.29-rc3.owrt/include/linux/mm.h 2009-05-10 22:09:07.000000000 +0200 ++++ linux-2.6.29-rc3.owrt.om/include/linux/mm.h 2009-05-10 22:28:00.000000000 +0200 +@@ -725,7 +725,7 @@ + } + #endif + struct file *shmem_file_setup(char *name, loff_t size, unsigned long flags); +- ++void shmem_set_file(struct vm_area_struct *, struct file *); + int shmem_zero_setup(struct vm_area_struct *); + + #ifndef CONFIG_MMU +diff -ruN --exclude='*.orig' --exclude='*.rej' linux-2.6.29-rc3.owrt/include/linux/neo1973_vibrator.h linux-2.6.29-rc3.owrt.om/include/linux/neo1973_vibrator.h +--- linux-2.6.29-rc3.owrt/include/linux/neo1973_vibrator.h 1970-01-01 01:00:00.000000000 +0100 ++++ linux-2.6.29-rc3.owrt.om/include/linux/neo1973_vibrator.h 2009-05-10 22:28:00.000000000 +0200 +@@ -0,0 +1,5 @@ ++struct neo1973_vib_platform_data { ++ int (* enable_fiq)(void); ++ void (*disable_fiq)(void); ++ void (*kick_fiq)(void); ++}; +diff -ruN --exclude='*.orig' --exclude='*.rej' linux-2.6.29-rc3.owrt/include/linux/pcap7200.h linux-2.6.29-rc3.owrt.om/include/linux/pcap7200.h +--- linux-2.6.29-rc3.owrt/include/linux/pcap7200.h 1970-01-01 01:00:00.000000000 +0100 ++++ linux-2.6.29-rc3.owrt.om/include/linux/pcap7200.h 2009-05-10 22:28:00.000000000 +0200 +@@ -0,0 +1,25 @@ ++#ifndef _LINUX_PCPA7200_H ++#define _LINUX_PCPA7200_H ++ ++enum op_mode { ++ SLEEP, ++ WAKEUP, ++ SINGLE_TOUCH, ++ MULTI_TOUCH, ++}; ++ ++enum gesture { ++ ZOOM, ++ FST_ZOOM, ++ SND_ZOOM, ++ ROTATE, ++ FST_SLIDE, ++ SND_SLIDE, ++}; ++ ++struct pcap7200_platform_data { ++ enum op_mode mode; ++ void (*reset)(void); ++}; ++ ++#endif /* _LINUX_PCPA7200_H */ +diff -ruN --exclude='*.orig' --exclude='*.rej' linux-2.6.29-rc3.owrt/include/linux/pcf50606.h linux-2.6.29-rc3.owrt.om/include/linux/pcf50606.h +--- linux-2.6.29-rc3.owrt/include/linux/pcf50606.h 1970-01-01 01:00:00.000000000 +0100 ++++ linux-2.6.29-rc3.owrt.om/include/linux/pcf50606.h 2009-05-10 22:28:00.000000000 +0200 +@@ -0,0 +1,91 @@ ++#ifndef _LINUX_PCF50606_H ++#define _LINUX_PCF50606_H ++ ++#include <linux/pcf506xx.h> ++ ++ ++/* public in-kernel pcf50606 api */ ++enum pcf50606_regulator_id { ++ PCF50606_REGULATOR_DCD, ++ PCF50606_REGULATOR_DCDE, ++ PCF50606_REGULATOR_DCUD, ++ PCF50606_REGULATOR_D1REG, ++ PCF50606_REGULATOR_D2REG, ++ PCF50606_REGULATOR_D3REG, ++ PCF50606_REGULATOR_LPREG, ++ PCF50606_REGULATOR_IOREG, ++ __NUM_PCF50606_REGULATORS ++}; ++ ++struct pcf50606_data; ++ ++/* This is an ugly construct on how to access the (currently single/global) ++ * pcf50606 handle from other code in the kernel. I didn't really come up with ++ * a more decent method of dynamically resolving this */ ++extern struct pcf50606_data *pcf50606_global; ++ ++extern void ++pcf50606_go_standby(void); ++ ++extern void ++pcf50606_gpo0_set(struct pcf50606_data *pcf, int on); ++ ++extern int ++pcf50606_gpo0_get(struct pcf50606_data *pcf); ++ ++extern int ++pcf50606_voltage_set(struct pcf50606_data *pcf, ++ enum pcf50606_regulator_id reg, ++ unsigned int millivolts); ++extern unsigned int ++pcf50606_voltage_get(struct pcf50606_data *pcf, ++ enum pcf50606_regulator_id reg); ++extern int ++pcf50606_onoff_get(struct pcf50606_data *pcf, ++ enum pcf50606_regulator_id reg); ++ ++extern int ++pcf50606_onoff_set(struct pcf50606_data *pcf, ++ enum pcf50606_regulator_id reg, int on); ++ ++extern void ++pcf50606_charge_fast(struct pcf50606_data *pcf, int on); ++ ++ ++#define PCF50606_FEAT_EXTON 0x00000001 /* not yet supported */ ++#define PCF50606_FEAT_MBC 0x00000002 ++#define PCF50606_FEAT_BBC 0x00000004 /* not yet supported */ ++#define PCF50606_FEAT_TSC 0x00000008 /* not yet supported */ ++#define PCF50606_FEAT_WDT 0x00000010 ++#define PCF50606_FEAT_ACD 0x00000020 ++#define PCF50606_FEAT_RTC 0x00000040 ++#define PCF50606_FEAT_PWM 0x00000080 ++#define PCF50606_FEAT_CHGCUR 0x00000100 ++#define PCF50606_FEAT_BATVOLT 0x00000200 ++#define PCF50606_FEAT_BATTEMP 0x00000400 ++#define PCF50606_FEAT_PWM_BL 0x00000800 ++ ++struct pcf50606_platform_data { ++ /* general */ ++ unsigned int used_features; ++ unsigned int onkey_seconds_required; ++ ++ /* voltage regulator related */ ++ struct pmu_voltage_rail rails[__NUM_PCF50606_REGULATORS]; ++ unsigned int used_regulators; ++ ++ /* charger related */ ++ unsigned int r_fix_batt; ++ unsigned int r_fix_batt_par; ++ unsigned int r_sense_milli; ++ ++ /* backlight related */ ++ unsigned int init_brightness; ++ ++ struct { ++ u_int8_t mbcc3; /* charger voltage / current */ ++ } charger; ++ pmu_cb cb; ++}; ++ ++#endif +diff -ruN --exclude='*.orig' --exclude='*.rej' linux-2.6.29-rc3.owrt/include/linux/pcf50633.h linux-2.6.29-rc3.owrt.om/include/linux/pcf50633.h +--- linux-2.6.29-rc3.owrt/include/linux/pcf50633.h 1970-01-01 01:00:00.000000000 +0100 ++++ linux-2.6.29-rc3.owrt.om/include/linux/pcf50633.h 2009-05-10 22:28:00.000000000 +0200 +@@ -0,0 +1,176 @@ ++#ifndef _LINUX_PCF50633_H ++#define _LINUX_PCF50633_H ++ ++#include <linux/pcf506xx.h> ++#include <linux/regulator/machine.h> ++ ++ ++/* public in-kernel pcf50633 api */ ++enum pcf50633_regulator_id { ++ PCF50633_REGULATOR_AUTO, ++ PCF50633_REGULATOR_DOWN1, ++ PCF50633_REGULATOR_DOWN2, ++ PCF50633_REGULATOR_MEMLDO, ++ PCF50633_REGULATOR_LDO1, ++ PCF50633_REGULATOR_LDO2, ++ PCF50633_REGULATOR_LDO3, ++ PCF50633_REGULATOR_LDO4, ++ PCF50633_REGULATOR_LDO5, ++ PCF50633_REGULATOR_LDO6, ++ PCF50633_REGULATOR_HCLDO, ++ __NUM_PCF50633_REGULATORS ++}; ++ ++enum pcf50633_reg_int1 { ++ PCF50633_INT1_ADPINS = 0x01, /* Adapter inserted */ ++ PCF50633_INT1_ADPREM = 0x02, /* Adapter removed */ ++ PCF50633_INT1_USBINS = 0x04, /* USB inserted */ ++ PCF50633_INT1_USBREM = 0x08, /* USB removed */ ++ /* reserved */ ++ PCF50633_INT1_ALARM = 0x40, /* RTC alarm time is reached */ ++ PCF50633_INT1_SECOND = 0x80, /* RTC periodic second interrupt */ ++}; ++ ++enum pcf50633_reg_int2 { ++ PCF50633_INT2_ONKEYR = 0x01, /* ONKEY rising edge */ ++ PCF50633_INT2_ONKEYF = 0x02, /* ONKEY falling edge */ ++ PCF50633_INT2_EXTON1R = 0x04, /* EXTON1 rising edge */ ++ PCF50633_INT2_EXTON1F = 0x08, /* EXTON1 falling edge */ ++ PCF50633_INT2_EXTON2R = 0x10, /* EXTON2 rising edge */ ++ PCF50633_INT2_EXTON2F = 0x20, /* EXTON2 falling edge */ ++ PCF50633_INT2_EXTON3R = 0x40, /* EXTON3 rising edge */ ++ PCF50633_INT2_EXTON3F = 0x80, /* EXTON3 falling edge */ ++}; ++ ++enum pcf50633_reg_int3 { ++ PCF50633_INT3_BATFULL = 0x01, /* Battery full */ ++ PCF50633_INT3_CHGHALT = 0x02, /* Charger halt */ ++ PCF50633_INT3_THLIMON = 0x04, ++ PCF50633_INT3_THLIMOFF = 0x08, ++ PCF50633_INT3_USBLIMON = 0x10, ++ PCF50633_INT3_USBLIMOFF = 0x20, ++ PCF50633_INT3_ADCRDY = 0x40, /* ADC conversion finished */ ++ PCF50633_INT3_ONKEY1S = 0x80, /* ONKEY pressed 1 second */ ++}; ++ ++enum pcf50633_reg_int4 { ++ PCF50633_INT4_LOWSYS = 0x01, ++ PCF50633_INT4_LOWBAT = 0x02, ++ PCF50633_INT4_HIGHTMP = 0x04, ++ PCF50633_INT4_AUTOPWRFAIL = 0x08, ++ PCF50633_INT4_DWN1PWRFAIL = 0x10, ++ PCF50633_INT4_DWN2PWRFAIL = 0x20, ++ PCF50633_INT4_LEDPWRFAIL = 0x40, ++ PCF50633_INT4_LEDOVP = 0x80, ++}; ++ ++enum pcf50633_reg_int5 { ++ PCF50633_INT5_LDO1PWRFAIL = 0x01, ++ PCF50633_INT5_LDO2PWRFAIL = 0x02, ++ PCF50633_INT5_LDO3PWRFAIL = 0x04, ++ PCF50633_INT5_LDO4PWRFAIL = 0x08, ++ PCF50633_INT5_LDO5PWRFAIL = 0x10, ++ PCF50633_INT5_LDO6PWRFAIL = 0x20, ++ PCF50633_INT5_HCLDOPWRFAIL = 0x40, ++ PCF50633_INT5_HCLDOOVL = 0x80, ++}; ++ ++struct pcf50633_data; ++extern struct pcf50633_data *pcf50633_global; ++ ++extern void ++pcf50633_go_standby(void); ++ ++enum pcf50633_gpio { ++ PCF50633_GPIO1 = 1, ++ PCF50633_GPIO2 = 2, ++ PCF50633_GPIO3 = 3, ++ PCF50633_GPO = 4, ++}; ++ ++extern void ++pcf50633_gpio_set(struct pcf50633_data *pcf, enum pcf50633_gpio gpio, int on); ++ ++extern int ++pcf50633_gpio_get(struct pcf50633_data *pcf, enum pcf50633_gpio gpio); ++ ++extern int ++pcf50633_voltage_set(struct pcf50633_data *pcf, ++ enum pcf50633_regulator_id reg, ++ unsigned int millivolts); ++extern unsigned int ++pcf50633_voltage_get(struct pcf50633_data *pcf, ++ enum pcf50633_regulator_id reg); ++ ++extern int ++pcf50633_onoff_get(struct pcf50633_data *pcf, ++ enum pcf50633_regulator_id reg); ++ ++extern int ++pcf50633_onoff_set(struct pcf50633_data *pcf, ++ enum pcf50633_regulator_id reg, int on); ++ ++extern void ++pcf50633_backlight_resume(struct pcf50633_data *pcf); ++ ++extern u_int16_t ++pcf50633_battvolt(struct pcf50633_data *pcf); ++ ++extern int ++pcf50633_report_resumers(struct pcf50633_data *pcf, char *buf); ++ ++extern int ++pcf50633_notify_usb_current_limit_change(struct pcf50633_data *pcf, ++ unsigned int ma); ++extern int ++pcf50633_wait_for_ready(struct pcf50633_data *pcf, int timeout_ms, ++ char *name); ++ ++/* 0 = initialized and resumed and ready to roll, !=0 = either not ++ * initialized or not resumed yet ++ */ ++extern int ++pcf50633_ready(struct pcf50633_data *pcf); ++ ++#define PCF50633_FEAT_EXTON 0x00000001 /* not yet supported */ ++#define PCF50633_FEAT_MBC 0x00000002 ++#define PCF50633_FEAT_BBC 0x00000004 /* not yet supported */ ++#define PCF50633_FEAT_RTC 0x00000040 ++#define PCF50633_FEAT_CHGCUR 0x00000100 ++#define PCF50633_FEAT_BATVOLT 0x00000200 ++#define PCF50633_FEAT_BATTEMP 0x00000400 ++#define PCF50633_FEAT_PWM_BL 0x00000800 ++ ++struct pcf50633_platform_data { ++ /* general */ ++ unsigned int used_features; ++ unsigned int onkey_seconds_sig_init; ++ unsigned int onkey_seconds_shutdown; ++ ++ /* callback to attach platform children (to enforce suspend / resume ++ * ordering */ ++ void (*attach_child_devices)(struct device *parent_device); ++ ++ /* voltage regulator related */ ++ struct pmu_voltage_rail rails[__NUM_PCF50633_REGULATORS]; ++ unsigned int used_regulators; ++ ++ /* charger related */ ++ unsigned int r_fix_batt; ++ unsigned int r_fix_batt_par; ++ unsigned int r_sense_milli; ++ int flag_use_apm_emulation; ++ ++ unsigned char resumers[5]; ++ ++ struct { ++ u_int8_t mbcc3; /* charger voltage / current */ ++ } charger; ++ pmu_cb cb; ++ ++ /* post-resume backlight bringup */ ++ int defer_resume_backlight; ++ u8 resume_backlight_ramp_speed; ++}; ++ ++#endif /* _PCF50633_H */ +diff -ruN --exclude='*.orig' --exclude='*.rej' linux-2.6.29-rc3.owrt/include/linux/pcf506xx.h linux-2.6.29-rc3.owrt.om/include/linux/pcf506xx.h +--- linux-2.6.29-rc3.owrt/include/linux/pcf506xx.h 1970-01-01 01:00:00.000000000 +0100 ++++ linux-2.6.29-rc3.owrt.om/include/linux/pcf506xx.h 2009-05-10 22:28:00.000000000 +0200 +@@ -0,0 +1,34 @@ ++#ifndef _LINUX_PCF506XX_H ++#define _LINUX_PCF506XX_H ++ ++ ++#define PMU_VRAIL_F_SUSPEND_ON 0x00000001 /* Remains on during suspend */ ++#define PMU_VRAIL_F_UNUSED 0x00000002 /* This rail is not used */ ++struct pmu_voltage_rail { ++ char *name; ++ unsigned int flags; ++ struct { ++ unsigned int init; ++ unsigned int max; ++ } voltage; ++}; ++ ++enum pmu_event { ++ PMU_EVT_NONE, ++ PMU_EVT_INSERT, ++ PMU_EVT_REMOVE, ++#ifdef CONFIG_SENSORS_PCF50633 ++ PMU_EVT_USB_INSERT, ++ PMU_EVT_USB_REMOVE, ++#endif ++ PMU_EVT_CHARGER_ACTIVE, ++ PMU_EVT_CHARGER_IDLE, ++ PMU_EVT_CHARGER_CHANGE, ++ __NUM_PMU_EVTS ++}; ++ ++typedef int (*pmu_cb)(struct device *dev, unsigned int feature, ++ enum pmu_event event); ++ ++ ++#endif /* !_LINUX_PCF506XX_H */ +diff -ruN --exclude='*.orig' --exclude='*.rej' linux-2.6.29-rc3.owrt/include/linux/resume-dependency.h linux-2.6.29-rc3.owrt.om/include/linux/resume-dependency.h +--- linux-2.6.29-rc3.owrt/include/linux/resume-dependency.h 1970-01-01 01:00:00.000000000 +0100 ++++ linux-2.6.29-rc3.owrt.om/include/linux/resume-dependency.h 2009-05-10 22:28:00.000000000 +0200 +@@ -0,0 +1,114 @@ ++#ifndef __RESUME_DEPENDENCY_H__ ++#define __RESUME_DEPENDENCY_H__ ++ ++/* Resume dependency framework ++ * ++ * (C) 2008 Openmoko, Inc. ++ * Author: Andy Green <andy@openmoko.com> ++ * ++ * 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; version 2.1. ++ * ++ * 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, ++ * MA 02111-1307 USA ++ * ++ */ ++ ++#include <linux/list.h> ++ ++struct resume_dependency { ++ struct list_head list; ++ ++ void (*callback)(void *); /* called with context as arg */ ++ void * context; ++ int called_flag; /* set to 1 after called, use for multi dep */ ++}; ++ ++/* if you are a driver accept to have other drivers as dependencies, you need to ++ * instantiate a struct resume_dependency above, then initialize it by invoking ++ * init_resume_dependency_list() on it ++ */ ++ ++#define init_resume_dependency_list(_head) \ ++ printk(KERN_INFO "##### init_resume_dependency_list(head=%p)\n", (_head)); \ ++ INIT_LIST_HEAD(&(_head)->list); ++ ++ ++/* if your resume function depends on something else being resumed first, you ++ * can register the dependency by calling this in your suspend function with ++ * head being the list held by the thing you are dependent on, and dep being ++ * your struct resume_dependency ++ */ ++ ++#define register_resume_dependency(_head, _dep) { \ ++ struct list_head *_pos, *_q; \ ++ struct resume_dependency *_d; \ ++\ ++ printk(KERN_ERR "##### register_resume_dependency(head=%p, dep=%p)\n", (_head), (_dep)); \ ++ (_dep)->called_flag = 1; \ ++ list_for_each_safe(_pos, _q, &((_head)->list)) { \ ++ _d = list_entry(_pos, struct resume_dependency, list); \ ++ if (_d == (_dep)) { \ ++ list_del(_pos); \ ++ printk(KERN_ERR "##### duplicate dependency removed first\n"); \ ++ } \ ++ } \ ++ list_add(&(_dep)->list, &(_head)->list); \ ++} ++ ++/* In the resume function that things can be dependent on, at the end you ++ * invoke this macro. This calls back the dependent resumes now it is safe to ++ * use the resumed thing they were dependent on. ++ */ ++ ++#define callback_all_resume_dependencies(_head) { \ ++ struct list_head *_pos, *_q; \ ++ struct resume_dependency *_dep; \ ++\ ++ printk(KERN_ERR "##### callback_all_resume_dependencies(head=%p)\n", (_head)); \ ++ list_for_each_safe(_pos, _q, &((_head)->list)) { \ ++ _dep = list_entry(_pos, struct resume_dependency, list); \ ++ printk(KERN_ERR "##### callback list entry (head=%p, dep=%p)\n", (_head), (_dep)); \ ++ _dep->called_flag = 1; \ ++ printk(KERN_ERR "##### callback=%p(context=%p))\n", (_dep->callback),(_dep->context)); \ ++ (_dep->callback)(_dep->context); \ ++ list_del(_pos); \ ++ } \ ++} ++ ++/* When a dependency is added, it is not actually active; the dependent resume ++ * handler will function as normal. The dependency is activated by the suspend ++ * handler for the driver that will be doing the callbacks. This ensures that ++ * if the suspend is aborted for any reason (error, driver busy, etc), that all ++ * suspended drivers will resume, even if the driver upon which they are dependent ++ * did not suspend, and hence will not resume, and thus would be unable to perform ++ * the callbacks. ++ */ ++ ++#define activate_all_resume_dependencies(_head) { \ ++ struct list_head *_pos, *_q; \ ++ struct resume_dependency *_dep; \ ++\ ++ printk(KERN_ERR "##### activate_all_resume_dependencies(head=%p)\n", (_head)); \ ++ list_for_each_safe(_pos, _q, &((_head)->list)) { \ ++ _dep = list_entry(_pos, struct resume_dependency, list); \ ++ printk(KERN_ERR "##### activating callback list entry (head=%p, dep=%p)\n", (_head), (_dep)); \ ++ _dep->called_flag = 0; \ ++ } \ ++} ++ ++/* if your resume action is dependent on multiple drivers being resumed already, ++ * register the same callback with each driver you are dependent on, and check ++ * .called_flag for all of the struct resume_dependency. When they are all 1 ++ * you know it is the last callback and you can resume, otherwise just return ++ */ ++ ++#endif +diff -ruN --exclude='*.orig' --exclude='*.rej' linux-2.6.29-rc3.owrt/include/linux/rtc/pcf50633.h linux-2.6.29-rc3.owrt.om/include/linux/rtc/pcf50633.h +--- linux-2.6.29-rc3.owrt/include/linux/rtc/pcf50633.h 1970-01-01 01:00:00.000000000 +0100 ++++ linux-2.6.29-rc3.owrt.om/include/linux/rtc/pcf50633.h 2009-05-10 22:28:00.000000000 +0200 +@@ -0,0 +1,9 @@ ++enum pcf50633_rtc_event { ++ PCF50633_RTC_EVENT_ALARM, ++ PCF50633_RTC_EVENT_SECOND, ++}; ++ ++extern void pcf50633_rtc_handle_event(struct pcf50633_data *pcf, ++ enum pcf50633_rtc_event evt); ++ ++ +diff -ruN --exclude='*.orig' --exclude='*.rej' linux-2.6.29-rc3.owrt/include/linux/spi/glamo.h linux-2.6.29-rc3.owrt.om/include/linux/spi/glamo.h +--- linux-2.6.29-rc3.owrt/include/linux/spi/glamo.h 1970-01-01 01:00:00.000000000 +0100 ++++ linux-2.6.29-rc3.owrt.om/include/linux/spi/glamo.h 2009-05-10 22:28:00.000000000 +0200 +@@ -0,0 +1,27 @@ ++#ifndef __GLAMO_SPI_H ++#define __GLAMO_SPI_H ++ ++#include <linux/glamo-gpio.h> ++ ++struct spi_board_info; ++struct glamofb_handle; ++struct glamo_core; ++ ++struct glamo_spi_info { ++ unsigned long board_size; ++ struct spi_board_info *board_info; ++ struct glamofb_handle *glamofb_handle; ++}; ++ ++struct glamo_spigpio_info { ++ unsigned int pin_clk; ++ unsigned int pin_mosi; ++ unsigned int pin_miso; ++ unsigned int pin_cs; ++ int bus_num; ++ ++ struct glamo_core *glamo; ++}; ++ ++ ++#endif +diff -ruN --exclude='*.orig' --exclude='*.rej' linux-2.6.29-rc3.owrt/include/linux/spi/spi_bitbang.h linux-2.6.29-rc3.owrt.om/include/linux/spi/spi_bitbang.h +--- linux-2.6.29-rc3.owrt/include/linux/spi/spi_bitbang.h 2009-05-10 22:09:08.000000000 +0200 ++++ linux-2.6.29-rc3.owrt.om/include/linux/spi/spi_bitbang.h 2009-05-10 22:28:00.000000000 +0200 +@@ -31,6 +31,9 @@ + u8 use_dma; + u8 flags; /* extra spi->mode support */ + ++ /* Support for synchronous non blocking transfers */ ++ int non_blocking_transfer; ++ + struct spi_master *master; + + /* setup_transfer() changes clock and/or wordsize to match settings +@@ -62,6 +65,8 @@ + extern int spi_bitbang_transfer(struct spi_device *spi, struct spi_message *m); + extern int spi_bitbang_setup_transfer(struct spi_device *spi, + struct spi_transfer *t); ++extern int spi_bitbang_transfer_sync(struct spi_device *spi, ++ struct spi_message *m); + + /* start or stop queue processing */ + extern int spi_bitbang_start(struct spi_bitbang *spi); +diff -ruN --exclude='*.orig' --exclude='*.rej' linux-2.6.29-rc3.owrt/include/linux/spi/spi.h linux-2.6.29-rc3.owrt.om/include/linux/spi/spi.h +--- linux-2.6.29-rc3.owrt/include/linux/spi/spi.h 2009-05-10 22:04:47.000000000 +0200 ++++ linux-2.6.29-rc3.owrt.om/include/linux/spi/spi.h 2009-05-10 22:28:00.000000000 +0200 +@@ -264,6 +264,13 @@ + int (*transfer)(struct spi_device *spi, + struct spi_message *mesg); + ++ /* ++ * Synchronous non blocking transfer function. Should guarantee ++ * data availability when it returns ++ */ ++ int (*transfer_sync)(struct spi_device *spi, ++ struct spi_message *mesg); ++ + /* called on release() to free memory provided by spi_master */ + void (*cleanup)(struct spi_device *spi); + }; +@@ -573,6 +580,29 @@ + return spi->master->transfer(spi, message); + } + ++/** ++ * spi_non_blocking_transfer - Synchronous, non blocking transfer ++ * @spi: device with which data will be exchanged ++ * @message: describes the data transfers with optional completion handlers ++ * Context: any (irqs may be blocked, etc) ++ * ++ * Data is guaranteed to be written or read when this function returns. ++ * ++ * Note : This may not be supported by all spi masters. ++ */ ++ ++static inline int ++spi_non_blocking_transfer(struct spi_device *spi, struct spi_message *message) ++{ ++ if (unlikely(!spi->master->transfer_sync)) { ++ dev_err(&spi->master->dev, ++ "non-blocking transfers not supported\n"); ++ return -EIO; ++ } ++ ++ return spi->master->transfer_sync(spi, message); ++} ++ + /*---------------------------------------------------------------------------*/ + + /* All these synchronous SPI transfer routines are utilities layered +diff -ruN --exclude='*.orig' --exclude='*.rej' linux-2.6.29-rc3.owrt/include/linux/suspend.h linux-2.6.29-rc3.owrt.om/include/linux/suspend.h +--- linux-2.6.29-rc3.owrt/include/linux/suspend.h 2009-05-10 22:04:48.000000000 +0200 ++++ linux-2.6.29-rc3.owrt.om/include/linux/suspend.h 2009-05-10 22:28:00.000000000 +0200 +@@ -146,6 +146,12 @@ + struct pbe *next; + }; + ++/** ++ * global indication we are somewhere between start of suspend and end of ++ * resume, nonzero is true ++ */ ++extern int global_inside_suspend; ++ + /* mm/page_alloc.c */ + extern void mark_free_pages(struct zone *zone); + +diff -ruN --exclude='*.orig' --exclude='*.rej' linux-2.6.29-rc3.owrt/include/linux/vt.h linux-2.6.29-rc3.owrt.om/include/linux/vt.h +--- linux-2.6.29-rc3.owrt/include/linux/vt.h 2009-05-10 22:04:47.000000000 +0200 ++++ linux-2.6.29-rc3.owrt.om/include/linux/vt.h 2009-05-10 22:28:00.000000000 +0200 +@@ -18,8 +18,19 @@ + * resizing). + */ + #define MIN_NR_CONSOLES 1 /* must be at least 1 */ ++#if (CONFIG_NR_TTY_DEVICES < 4) ++/* Lower Limit */ ++#define MAX_NR_CONSOLES 4 /* serial lines start at 64 */ ++#define MAX_NR_USER_CONSOLES 4 /* must be root to allocate above this */ ++#elif (CONFIG_NR_TTY_DEVICES > 63) ++/* Upper Limit */ + #define MAX_NR_CONSOLES 63 /* serial lines start at 64 */ + #define MAX_NR_USER_CONSOLES 63 /* must be root to allocate above this */ ++#else ++/* They chose a sensible number */ ++#define MAX_NR_CONSOLES CONFIG_NR_TTY_DEVICES ++#define MAX_NR_USER_CONSOLES CONFIG_NR_TTY_DEVICES ++#endif + /* Note: the ioctl VT_GETSTATE does not work for + consoles 16 and higher (since it returns a short) */ + +diff -ruN --exclude='*.orig' --exclude='*.rej' linux-2.6.29-rc3.owrt/include/linux/wakelock.h linux-2.6.29-rc3.owrt.om/include/linux/wakelock.h +--- linux-2.6.29-rc3.owrt/include/linux/wakelock.h 1970-01-01 01:00:00.000000000 +0100 ++++ linux-2.6.29-rc3.owrt.om/include/linux/wakelock.h 2009-05-10 22:28:00.000000000 +0200 +@@ -0,0 +1,91 @@ ++/* include/linux/wakelock.h ++ * ++ * Copyright (C) 2007-2008 Google, Inc. ++ * ++ * This software is licensed under the terms of the GNU General Public ++ * License version 2, as published by the Free Software Foundation, and ++ * may be copied, distributed, and modified under those terms. ++ * ++ * 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. ++ * ++ */ ++ ++#ifndef _LINUX_WAKELOCK_H ++#define _LINUX_WAKELOCK_H ++ ++#include <linux/list.h> ++#include <linux/ktime.h> ++ ++/* A wake_lock prevents the system from entering suspend or other low power ++ * states when active. If the type is set to WAKE_LOCK_SUSPEND, the wake_lock ++ * prevents a full system suspend. If the type is WAKE_LOCK_IDLE, low power ++ * states that cause large interrupt latencies or that disable a set of ++ * interrupts will not entered from idle until the wake_locks are released. ++ */ ++ ++enum { ++ WAKE_LOCK_SUSPEND, /* Prevent suspend */ ++ WAKE_LOCK_IDLE, /* Prevent low power idle */ ++ WAKE_LOCK_TYPE_COUNT ++}; ++ ++struct wake_lock { ++#ifdef CONFIG_ANDROID_HAS_WAKELOCK ++ struct list_head link; ++ int flags; ++ const char *name; ++ unsigned long expires; ++#ifdef CONFIG_ANDROID_WAKELOCK_STAT ++ struct { ++ int count; ++ int expire_count; ++ int wakeup_count; ++ ktime_t total_time; ++ ktime_t prevent_suspend_time; ++ ktime_t max_time; ++ ktime_t last_time; ++ } stat; ++#endif ++#endif ++}; ++ ++#ifdef CONFIG_ANDROID_HAS_WAKELOCK ++ ++void wake_lock_init(struct wake_lock *lock, int type, const char *name); ++void wake_lock_destroy(struct wake_lock *lock); ++void wake_lock(struct wake_lock *lock); ++void wake_lock_timeout(struct wake_lock *lock, long timeout); ++void wake_unlock(struct wake_lock *lock); ++ ++/* wake_lock_active returns a non-zero value if the wake_lock is currently ++ * locked. If the wake_lock has a timeout, it does not check the timeout ++ * but if the timeout had aready been checked it will return 0. ++ */ ++int wake_lock_active(struct wake_lock *lock); ++ ++/* has_wake_lock returns 0 if no wake locks of the specified type are active, ++ * and non-zero if one or more wake locks are held. Specifically it returns ++ * -1 if one or more wake locks with no timeout are active or the ++ * number of jiffies until all active wake locks time out. ++ */ ++long has_wake_lock(int type); ++ ++#else ++ ++static inline void wake_lock_init(struct wake_lock *lock, int type, ++ const char *name) {} ++static inline void wake_lock_destroy(struct wake_lock *lock) {} ++static inline void wake_lock(struct wake_lock *lock) {} ++static inline void wake_lock_timeout(struct wake_lock *lock, long timeout) {} ++static inline void wake_unlock(struct wake_lock *lock) {} ++ ++static inline int wake_lock_active(struct wake_lock *lock) { return 0; } ++static inline long has_wake_lock(int type) { return 0; } ++ ++#endif ++ ++#endif ++ +diff -ruN --exclude='*.orig' --exclude='*.rej' linux-2.6.29-rc3.owrt/include/sound/soc-dapm.h linux-2.6.29-rc3.owrt.om/include/sound/soc-dapm.h +--- linux-2.6.29-rc3.owrt/include/sound/soc-dapm.h 2009-05-10 22:04:48.000000000 +0200 ++++ linux-2.6.29-rc3.owrt.om/include/sound/soc-dapm.h 2009-05-10 22:28:00.000000000 +0200 +@@ -182,6 +182,15 @@ + .get = snd_soc_dapm_get_value_enum_double, \ + .put = snd_soc_dapm_put_value_enum_double, \ + .private_value = (unsigned long)&xenum } ++/* NOTE: Openmoko-specific "DAPM " prefix added to controls for ++ * backwards compatibility. ++ */ ++#define SOC_DAPM_PIN_SWITCH(xname) \ ++{ .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = "DAPM " xname " Switch", \ ++ .info = snd_soc_dapm_info_pin_switch, \ ++ .get = snd_soc_dapm_get_pin_switch, \ ++ .put = snd_soc_dapm_put_pin_switch, \ ++ .private_value = (unsigned long)xname } + + /* dapm stream operations */ + #define SND_SOC_DAPM_STREAM_NOP 0x0 +@@ -228,6 +237,12 @@ + struct snd_ctl_elem_value *ucontrol); + int snd_soc_dapm_put_value_enum_double(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol); ++int snd_soc_dapm_info_pin_switch(struct snd_kcontrol *kcontrol, ++ struct snd_ctl_elem_info *uinfo); ++int snd_soc_dapm_get_pin_switch(struct snd_kcontrol *kcontrol, ++ struct snd_ctl_elem_value *uncontrol); ++int snd_soc_dapm_put_pin_switch(struct snd_kcontrol *kcontrol, ++ struct snd_ctl_elem_value *uncontrol); + int snd_soc_dapm_new_control(struct snd_soc_codec *codec, + const struct snd_soc_dapm_widget *widget); + int snd_soc_dapm_new_controls(struct snd_soc_codec *codec, +@@ -250,12 +265,19 @@ + int snd_soc_dapm_sys_add(struct device *dev); + + /* dapm audio pin control and status */ +-int snd_soc_dapm_enable_pin(struct snd_soc_codec *codec, char *pin); +-int snd_soc_dapm_disable_pin(struct snd_soc_codec *codec, char *pin); +-int snd_soc_dapm_nc_pin(struct snd_soc_codec *codec, char *pin); +-int snd_soc_dapm_get_pin_status(struct snd_soc_codec *codec, char *pin); ++int snd_soc_dapm_enable_pin(struct snd_soc_codec *codec, const char *pin); ++int snd_soc_dapm_disable_pin(struct snd_soc_codec *codec, const char *pin); ++int snd_soc_dapm_nc_pin(struct snd_soc_codec *codec, const char *pin); ++int snd_soc_dapm_get_pin_status(struct snd_soc_codec *codec, const char *pin); + int snd_soc_dapm_sync(struct snd_soc_codec *codec); + ++/* dapm audio endpoint control */ ++int snd_soc_dapm_set_endpoint(struct snd_soc_codec *codec, ++ char *pin, int status); ++int snd_soc_dapm_get_endpoint(struct snd_soc_codec *codec, ++ char *pin); ++int snd_soc_dapm_sync_endpoints(struct snd_soc_codec *codec); ++ + /* dapm widget types */ + enum snd_soc_dapm_type { + snd_soc_dapm_input = 0, /* input pin */ +diff -ruN --exclude='*.orig' --exclude='*.rej' linux-2.6.29-rc3.owrt/init/Kconfig linux-2.6.29-rc3.owrt.om/init/Kconfig +--- linux-2.6.29-rc3.owrt/init/Kconfig 2009-05-10 22:09:09.000000000 +0200 ++++ linux-2.6.29-rc3.owrt.om/init/Kconfig 2009-05-10 22:28:00.000000000 +0200 +@@ -869,6 +869,15 @@ + by some high performance threaded applications. Disabling + this option saves about 7k. + ++config ASHMEM ++ bool "Enable Android's Shared Memory Subsystem" ++ default n ++ depends on SHMEM || TINY_SHMEM ++ help ++ The ashmem subsystem is a new shared memory allocator, similar to ++ POSIX SHM but with different behavior and sporting a simpler ++ file-based API. ++ + config VM_EVENT_COUNTERS + default y + bool "Enable VM event counters for /proc/vmstat" if EMBEDDED +diff -ruN --exclude='*.orig' --exclude='*.rej' linux-2.6.29-rc3.owrt/kernel/irq/chip.c linux-2.6.29-rc3.owrt.om/kernel/irq/chip.c +--- linux-2.6.29-rc3.owrt/kernel/irq/chip.c 2009-05-10 22:09:09.000000000 +0200 ++++ linux-2.6.29-rc3.owrt.om/kernel/irq/chip.c 2009-05-10 22:28:00.000000000 +0200 +@@ -383,6 +383,7 @@ + out_unlock: + spin_unlock(&desc->lock); + } ++EXPORT_SYMBOL(handle_level_irq); + + /** + * handle_fasteoi_irq - irq handler for transparent controllers +@@ -593,6 +594,7 @@ + } + spin_unlock_irqrestore(&desc->lock, flags); + } ++EXPORT_SYMBOL(__set_irq_handler); + + void + set_irq_chip_and_handler(unsigned int irq, struct irq_chip *chip, +diff -ruN --exclude='*.orig' --exclude='*.rej' linux-2.6.29-rc3.owrt/kernel/power/main.c linux-2.6.29-rc3.owrt.om/kernel/power/main.c +--- linux-2.6.29-rc3.owrt/kernel/power/main.c 2009-05-10 22:09:09.000000000 +0200 ++++ linux-2.6.29-rc3.owrt.om/kernel/power/main.c 2009-05-10 22:28:00.000000000 +0200 +@@ -131,6 +131,9 @@ + + #endif /* CONFIG_PM_SLEEP */ + ++int global_inside_suspend; ++EXPORT_SYMBOL(global_inside_suspend); ++ + #ifdef CONFIG_SUSPEND + + #ifdef CONFIG_PM_TEST_SUSPEND +@@ -321,6 +324,8 @@ + if (!suspend_ops) + return -ENOSYS; + ++ global_inside_suspend = 1; ++ + if (suspend_ops->begin) { + error = suspend_ops->begin(state); + if (error) +@@ -362,6 +367,8 @@ + Close: + if (suspend_ops->end) + suspend_ops->end(); ++ global_inside_suspend = 0; ++ + return error; + + Recover_platform: +@@ -388,6 +395,9 @@ + + + static const char * const pm_states[PM_SUSPEND_MAX] = { ++#ifdef CONFIG_ANDROID_EARLYSUSPEND ++ [PM_SUSPEND_ON] = "on", ++#endif + [PM_SUSPEND_STANDBY] = "standby", + [PM_SUSPEND_MEM] = "mem", + }; +@@ -424,6 +434,8 @@ + return -EBUSY; + + printk(KERN_INFO "PM: Syncing filesystems ... "); ++ global_inside_suspend = 1; ++ + sys_sync(); + printk("done.\n"); + +@@ -505,7 +517,11 @@ + const char *buf, size_t n) + { + #ifdef CONFIG_SUSPEND ++#ifdef CONFIG_ANDROID_EARLYSUSPEND ++ suspend_state_t state = PM_SUSPEND_ON; ++#else + suspend_state_t state = PM_SUSPEND_STANDBY; ++#endif + const char * const *s; + #endif + char *p; +@@ -527,8 +543,15 @@ + break; + } + if (state < PM_SUSPEND_MAX && *s) ++#ifdef CONFIG_ANDROID_EARLYSUSPEND ++ if (state == PM_SUSPEND_ON || valid_state(state)) { ++ error = 0; ++ request_suspend_state(state); ++ } ++#else + error = enter_state(state); + #endif ++#endif + + Exit: + return error ? error : n; +@@ -561,6 +584,12 @@ + power_attr(pm_trace); + #endif /* CONFIG_PM_TRACE */ + ++#ifdef CONFIG_ANDROID_USER_WAKELOCK ++power_attr(wake_lock); ++power_attr(wake_full_lock); ++power_attr(wake_unlock); ++#endif ++ + static struct attribute * g[] = { + &state_attr.attr, + #ifdef CONFIG_PM_TRACE +@@ -569,6 +598,11 @@ + #if defined(CONFIG_PM_SLEEP) && defined(CONFIG_PM_DEBUG) + &pm_test_attr.attr, + #endif ++#ifdef CONFIG_ANDROID_USER_WAKELOCK ++ &wake_lock_attr.attr, ++ &wake_unlock_attr.attr, ++ &wake_full_lock_attr.attr, ++#endif + NULL, + }; + +diff -ruN --exclude='*.orig' --exclude='*.rej' linux-2.6.29-rc3.owrt/kernel/power/power.h linux-2.6.29-rc3.owrt.om/kernel/power/power.h +--- linux-2.6.29-rc3.owrt/kernel/power/power.h 2009-05-10 22:05:04.000000000 +0200 ++++ linux-2.6.29-rc3.owrt.om/kernel/power/power.h 2009-05-10 22:28:00.000000000 +0200 +@@ -223,3 +223,32 @@ + { + } + #endif ++ ++#ifdef CONFIG_ANDROID_WAKELOCK ++/* kernel/power/wakelock.c */ ++extern struct workqueue_struct *suspend_work_queue; ++extern struct wake_lock main_wake_lock; ++extern suspend_state_t requested_suspend_state; ++#endif ++ ++#ifdef CONFIG_ANDROID_USER_WAKELOCK ++ssize_t wake_lock_show(struct kobject *kobj, struct kobj_attribute *attr, ++ char *buf); ++ssize_t wake_lock_store(struct kobject *kobj, struct kobj_attribute *attr, ++ const char *buf, size_t n); ++ssize_t wake_full_lock_store(struct kobject *kobj, struct kobj_attribute *attr, ++ const char *buf, size_t n); ++ ++#define wake_full_lock_show wake_lock_show ++ ++ssize_t wake_unlock_show(struct kobject *kobj, struct kobj_attribute *attr, ++ char *buf); ++ssize_t wake_unlock_store(struct kobject *kobj, struct kobj_attribute *attr, ++ const char *buf, size_t n); ++#endif ++ ++#ifdef CONFIG_ANDROID_EARLYSUSPEND ++/* kernel/power/earlysuspend.c */ ++void request_suspend_state(suspend_state_t state); ++suspend_state_t get_suspend_state(void); ++#endif +diff -ruN --exclude='*.orig' --exclude='*.rej' linux-2.6.29-rc3.owrt/kernel/power/process.c linux-2.6.29-rc3.owrt.om/kernel/power/process.c +--- linux-2.6.29-rc3.owrt/kernel/power/process.c 2009-05-10 22:05:04.000000000 +0200 ++++ linux-2.6.29-rc3.owrt.om/kernel/power/process.c 2009-05-10 22:28:00.000000000 +0200 +@@ -13,6 +13,7 @@ + #include <linux/module.h> + #include <linux/syscalls.h> + #include <linux/freezer.h> ++#include <linux/wakelock.h> + + /* + * Timeout for stopping processes +@@ -36,6 +37,7 @@ + struct timeval start, end; + u64 elapsed_csecs64; + unsigned int elapsed_csecs; ++ unsigned int wakeup = 0; + + do_gettimeofday(&start); + +@@ -62,6 +64,10 @@ + } while_each_thread(g, p); + read_unlock(&tasklist_lock); + yield(); /* Yield is okay here */ ++ if (todo && has_wake_lock(WAKE_LOCK_SUSPEND)) { ++ wakeup = 1; ++ break; ++ } + if (time_after(jiffies, end_time)) + break; + } while (todo); +@@ -77,11 +83,17 @@ + * and caller must call thaw_processes() if something fails), + * but it cleans up leftover PF_FREEZE requests. + */ +- printk("\n"); +- printk(KERN_ERR "Freezing of tasks failed after %d.%02d seconds " ++ if (wakeup) { ++ printk("\n"); ++ printk(KERN_ERR "Freezing of %s aborted\n", ++ sig_only ? "user space " : "tasks "); ++ } else { ++ printk("\n"); ++ printk(KERN_ERR "Freezing of tasks failed after %d.%02d seconds " + "(%d tasks refusing to freeze):\n", + elapsed_csecs / 100, elapsed_csecs % 100, todo); +- show_state(); ++ show_state(); ++ } + read_lock(&tasklist_lock); + do_each_thread(g, p) { + task_lock(p); +diff -ruN --exclude='*.orig' --exclude='*.rej' linux-2.6.29-rc3.owrt/kernel/printk.c linux-2.6.29-rc3.owrt.om/kernel/printk.c +--- linux-2.6.29-rc3.owrt/kernel/printk.c 2009-05-10 22:09:09.000000000 +0200 ++++ linux-2.6.29-rc3.owrt.om/kernel/printk.c 2009-05-10 22:28:00.000000000 +0200 +@@ -32,8 +32,11 @@ + #include <linux/security.h> + #include <linux/bootmem.h> + #include <linux/syscalls.h> ++#include <linux/jiffies.h> ++#include <linux/suspend.h> + + #include <asm/uaccess.h> ++#include <asm/plat-s3c24xx/neo1973.h> + + /* + * Architectures can override it: +@@ -67,13 +70,21 @@ + int oops_in_progress; + EXPORT_SYMBOL(oops_in_progress); + ++void (*printk_emergency_debug_spew_init)(void) = NULL; ++EXPORT_SYMBOL(printk_emergency_debug_spew_init); ++ ++void (*printk_emergency_debug_spew_send_string)(const char *) = NULL; ++EXPORT_SYMBOL(printk_emergency_debug_spew_send_string); ++ + /* + * console_sem protects the console_drivers list, and also + * provides serialisation for access to the entire console + * driver system. + */ + static DECLARE_MUTEX(console_sem); ++#ifndef CONFIG_ANDROID_CONSOLE_EARLYSUSPEND + static DECLARE_MUTEX(secondary_console_sem); ++#endif + struct console *console_drivers; + EXPORT_SYMBOL_GPL(console_drivers); + +@@ -667,8 +678,39 @@ + /* Emit the output into the temporary buffer */ + printed_len += vscnprintf(printk_buf + printed_len, + sizeof(printk_buf) - printed_len, fmt, args); +- +- ++#if defined(CONFIG_MACH_NEO1973_GTA02) && defined(CONFIG_PM) ++ /* if you're debugging resume, the normal methods can change resume ++ * ordering behaviours because their debugging output is synchronous ++ * (ie, CONFIG_DEBUG_LL). If your problem is an OOPS, this code ++ * will not affect the speed and duration and ordering of resume ++ * actions, but will give you a chance to read the full undumped ++ * syslog AND the OOPS data when it happens ++ * ++ * if you support it, your debug device init can override the exported ++ * emergency_debug_spew_init and emergency_debug_spew_send_string to ++ * usually force polling or bitbanging on your debug console device ++ */ ++ if (oops_in_progress && global_inside_suspend && ++ printk_emergency_debug_spew_init && ++ printk_emergency_debug_spew_send_string) { ++ unsigned long cur_index; ++ char ch[2]; ++ ++ if (global_inside_suspend == 1) { ++ (printk_emergency_debug_spew_init)(); ++ ++ ch[1] = '\0'; ++ cur_index = con_start; ++ while (cur_index != log_end) { ++ ch[0] = LOG_BUF(cur_index); ++ (printk_emergency_debug_spew_send_string)(ch); ++ cur_index++; ++ } ++ global_inside_suspend++; /* only once */ ++ } ++ (printk_emergency_debug_spew_send_string)(printk_buf); ++ } ++#endif + /* + * Copy the output into log_buf. If the caller didn't provide + * appropriate log level tags, we insert them here +@@ -891,12 +933,18 @@ + printk("Suspending console(s) (use no_console_suspend to debug)\n"); + acquire_console_sem(); + console_suspended = 1; ++#ifdef CONFIG_ANDROID_CONSOLE_EARLYSUSPEND ++ up(&console_sem); ++#endif + } + + void resume_console(void) + { + if (!console_suspend_enabled) + return; ++#ifdef CONFIG_ANDROID_CONSOLE_EARLYSUSPEND ++ down(&console_sem); ++#endif + console_suspended = 0; + release_console_sem(); + } +@@ -912,11 +960,17 @@ + void acquire_console_sem(void) + { + BUG_ON(in_interrupt()); ++#ifndef CONFIG_ANDROID_CONSOLE_EARLYSUSPEND + if (console_suspended) { + down(&secondary_console_sem); + return; + } ++#endif + down(&console_sem); ++#ifdef CONFIG_ANDROID_CONSOLE_EARLYSUSPEND ++ if (console_suspended) ++ return; ++#endif + console_locked = 1; + console_may_schedule = 1; + } +@@ -926,6 +980,12 @@ + { + if (down_trylock(&console_sem)) + return -1; ++#ifdef CONFIG_ANDROID_CONSOLE_EARLYSUSPEND ++ if (console_suspended) { ++ up(&console_sem); ++ return -1; ++ } ++#endif + console_locked = 1; + console_may_schedule = 0; + return 0; +@@ -979,7 +1039,11 @@ + unsigned wake_klogd = 0; + + if (console_suspended) { ++#ifdef CONFIG_ANDROID_CONSOLE_EARLYSUSPEND ++ up(&console_sem); ++#else + up(&secondary_console_sem); ++#endif + return; + } + +diff -ruN --exclude='*.orig' --exclude='*.rej' linux-2.6.29-rc3.owrt/kernel/timer.c linux-2.6.29-rc3.owrt.om/kernel/timer.c +--- linux-2.6.29-rc3.owrt/kernel/timer.c 2009-05-10 22:05:04.000000000 +0200 ++++ linux-2.6.29-rc3.owrt.om/kernel/timer.c 2009-05-10 22:28:00.000000000 +0200 +@@ -813,7 +813,6 @@ + * don't have to detach them individually. + */ + list_for_each_entry_safe(timer, tmp, &tv_list, entry) { +- BUG_ON(tbase_get_base(timer->base) != base); + internal_add_timer(base, timer); + } + +diff -ruN --exclude='*.orig' --exclude='*.rej' linux-2.6.29-rc3.owrt/lib/Kconfig.debug linux-2.6.29-rc3.owrt.om/lib/Kconfig.debug +--- linux-2.6.29-rc3.owrt/lib/Kconfig.debug 2009-05-10 22:09:09.000000000 +0200 ++++ linux-2.6.29-rc3.owrt.om/lib/Kconfig.debug 2009-05-10 22:28:00.000000000 +0200 +@@ -847,6 +847,13 @@ + + Say N if you are unsure. + ++config FIND_IRQ_BLOCKERS ++ bool "IRQ Blocker statistics" ++ depends on ARM ++ ---help--- ++ Enables tracking of IRQ dead-time because something has ++ disabled interrupts ++ + config DYNAMIC_PRINTK_DEBUG + bool "Enable dynamic printk() call support" + default n +diff -ruN --exclude='*.orig' --exclude='*.rej' linux-2.6.29-rc3.owrt/MAINTAINERS linux-2.6.29-rc3.owrt.om/MAINTAINERS +--- linux-2.6.29-rc3.owrt/MAINTAINERS 2009-05-10 22:09:09.000000000 +0200 ++++ linux-2.6.29-rc3.owrt.om/MAINTAINERS 2009-05-10 22:28:00.000000000 +0200 +@@ -1711,6 +1711,20 @@ + P: Matthew Wilcox + M: matthew@wil.cx + L: linux-fsdevel@vger.kernel.org ++ ++FIC/OPENMOKO NEO1973 GSM PHONE ++P: Harald Welte ++M: laforge@openmoko.org ++L: openmoko-kernel@lists.openmoko.org ++W: http://wiki.openmoko.org/wiki/Kernel ++W: http://wiki.openmoko.org/wiki/Neo1973 ++S: Maintained ++ ++FRAMEBUFFER LAYER ++P: Antonino Daplas ++M: adaplas@gmail.com ++L: linux-fbdev-devel@lists.sourceforge.net (moderated for non-subscribers) ++W: http://linux-fbdev.sourceforge.net/ + S: Maintained + + FILESYSTEMS (VFS and infrastructure) +diff -ruN --exclude='*.orig' --exclude='*.rej' linux-2.6.29-rc3.owrt/makerecovery linux-2.6.29-rc3.owrt.om/makerecovery +--- linux-2.6.29-rc3.owrt/makerecovery 1970-01-01 01:00:00.000000000 +0100 ++++ linux-2.6.29-rc3.owrt.om/makerecovery 2009-05-10 22:28:00.000000000 +0200 +@@ -0,0 +1,17 @@ ++#!/bin/sh ++# ++# make 6MB recovery image from two moredrivers type kernels ++# placed at start and at +4MBytes ++ ++if [ -z "$1" ] ; then ++ echo "Usage: $0 uImage-moredrivers-..." ++ exit 1 ++fi ++cat $1 > recovery-$1 ++SIZE=`ls -l $1 | tr -s ' ' ' ' | cut -d' ' -f5` ++SPACE=$(( 4 * 1024 * 1024 - $SIZE )) ++dd if=/dev/zero of=_spacer bs=1 count=$SPACE ++cat _spacer >> recovery-$1 ++rm -f _spacer ++cat $1 >> recovery-$1 ++ +diff -ruN --exclude='*.orig' --exclude='*.rej' linux-2.6.29-rc3.owrt/mm/ashmem.c linux-2.6.29-rc3.owrt.om/mm/ashmem.c +--- linux-2.6.29-rc3.owrt/mm/ashmem.c 1970-01-01 01:00:00.000000000 +0100 ++++ linux-2.6.29-rc3.owrt.om/mm/ashmem.c 2009-05-10 22:28:00.000000000 +0200 +@@ -0,0 +1,657 @@ ++/* drivers/android/ashmem.c ++** ++** Android / Anonymous Shared Memory Subsystem, ashmem ++** ++** Copyright (C) 2008 Google, Inc. ++** ++** Robert Love <rlove@google.com> ++** ++** This software is licensed under the terms of the GNU General Public ++** License version 2, as published by the Free Software Foundation, and ++** may be copied, distributed, and modified under those terms. ++** ++** 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. ++*/ ++ ++#include <linux/module.h> ++#include <linux/file.h> ++#include <linux/fs.h> ++#include <linux/miscdevice.h> ++#include <linux/security.h> ++#include <linux/mm.h> ++#include <linux/mman.h> ++#include <linux/uaccess.h> ++#include <linux/personality.h> ++#include <linux/bitops.h> ++#include <linux/mutex.h> ++#include <linux/shmem_fs.h> ++#include <linux/ashmem.h> ++ ++/* ++ * ashmem_area - android shared memory area ++ * Lifecycle: From our parent file's open() until its release() ++ * Locking: Protected by `ashmem_mutex' ++ * Big Note: Mappings do NOT pin this structure; it dies on close() ++ */ ++struct ashmem_area { ++ char name[ASHMEM_NAME_LEN]; /* optional name for /proc/pid/maps */ ++ struct list_head unpinned_list; /* list of all ashmem areas */ ++ struct file *file; /* the shmem-based backing file */ ++ size_t size; /* size of the mapping, in bytes */ ++ unsigned long prot_mask; /* allowed prot bits, as vm_flags */ ++}; ++ ++/* ++ * ashmem_range - represents an interval of unpinned (evictable) pages ++ * Lifecycle: From unpin to pin ++ * Locking: Protected by `ashmem_mutex' ++ */ ++struct ashmem_range { ++ struct list_head lru; /* entry in LRU list */ ++ struct list_head unpinned; /* entry in its area's unpinned list */ ++ struct ashmem_area *asma; /* associated area */ ++ size_t pgstart; /* starting page, inclusive */ ++ size_t pgend; /* ending page, inclusive */ ++ unsigned int purged; /* ASHMEM_NOT or ASHMEM_WAS_PURGED */ ++}; ++ ++/* LRU list of unpinned pages, protected by ashmem_mutex */ ++static LIST_HEAD(ashmem_lru_list); ++ ++/* Count of pages on our LRU list, protected by ashmem_mutex */ ++static unsigned long lru_count; ++ ++/* ++ * ashmem_mutex - protects the list of and each individual ashmem_area ++ * ++ * Lock Ordering: ashmex_mutex -> i_mutex -> i_alloc_sem ++ */ ++static DEFINE_MUTEX(ashmem_mutex); ++ ++static struct kmem_cache *ashmem_area_cachep __read_mostly; ++static struct kmem_cache *ashmem_range_cachep __read_mostly; ++ ++#define range_size(range) \ ++ ((range)->pgend - (range)->pgstart + 1) ++ ++#define range_on_lru(range) \ ++ ((range)->purged == ASHMEM_NOT_PURGED) ++ ++#define page_range_subsumes_range(range, start, end) \ ++ (((range)->pgstart >= (start)) && ((range)->pgend <= (end))) ++ ++#define page_range_subsumed_by_range(range, start, end) \ ++ (((range)->pgstart <= (start)) && ((range)->pgend >= (end))) ++ ++#define page_in_range(range, page) \ ++ (((range)->pgstart <= (page)) && ((range)->pgend >= (page))) ++ ++#define page_range_in_range(range, start, end) \ ++ (page_in_range(range, start) || page_in_range(range, end) || \ ++ page_range_subsumes_range(range, start, end)) ++ ++#define range_before_page(range, page) \ ++ ((range)->pgend < (page)) ++ ++#define PROT_MASK (PROT_EXEC | PROT_READ | PROT_WRITE) ++ ++static inline void lru_add(struct ashmem_range *range) ++{ ++ list_add_tail(&range->lru, &ashmem_lru_list); ++ lru_count += range_size(range); ++} ++ ++static inline void lru_del(struct ashmem_range *range) ++{ ++ list_del(&range->lru); ++ lru_count -= range_size(range); ++} ++ ++/* ++ * range_alloc - allocate and initialize a new ashmem_range structure ++ * ++ * 'asma' - associated ashmem_area ++ * 'prev_range' - the previous ashmem_range in the sorted asma->unpinned list ++ * 'purged' - initial purge value (ASMEM_NOT_PURGED or ASHMEM_WAS_PURGED) ++ * 'start' - starting page, inclusive ++ * 'end' - ending page, inclusive ++ * ++ * Caller must hold ashmem_mutex. ++ */ ++static int range_alloc(struct ashmem_area *asma, ++ struct ashmem_range *prev_range, unsigned int purged, ++ size_t start, size_t end) ++{ ++ struct ashmem_range *range; ++ ++ range = kmem_cache_zalloc(ashmem_range_cachep, GFP_KERNEL); ++ if (unlikely(!range)) ++ return -ENOMEM; ++ ++ range->asma = asma; ++ range->pgstart = start; ++ range->pgend = end; ++ range->purged = purged; ++ ++ list_add_tail(&range->unpinned, &prev_range->unpinned); ++ ++ if (range_on_lru(range)) ++ lru_add(range); ++ ++ return 0; ++} ++ ++static void range_del(struct ashmem_range *range) ++{ ++ list_del(&range->unpinned); ++ if (range_on_lru(range)) ++ lru_del(range); ++ kmem_cache_free(ashmem_range_cachep, range); ++} ++ ++/* ++ * range_shrink - shrinks a range ++ * ++ * Caller must hold ashmem_mutex. ++ */ ++static inline void range_shrink(struct ashmem_range *range, ++ size_t start, size_t end) ++{ ++ size_t pre = range_size(range); ++ ++ range->pgstart = start; ++ range->pgend = end; ++ ++ if (range_on_lru(range)) ++ lru_count -= pre - range_size(range); ++} ++ ++static int ashmem_open(struct inode *inode, struct file *file) ++{ ++ struct ashmem_area *asma; ++ int ret; ++ ++ ret = nonseekable_open(inode, file); ++ if (unlikely(ret)) ++ return ret; ++ ++ asma = kmem_cache_zalloc(ashmem_area_cachep, GFP_KERNEL); ++ if (unlikely(!asma)) ++ return -ENOMEM; ++ ++ INIT_LIST_HEAD(&asma->unpinned_list); ++ asma->prot_mask = PROT_MASK; ++ file->private_data = asma; ++ ++ return 0; ++} ++ ++static int ashmem_release(struct inode *ignored, struct file *file) ++{ ++ struct ashmem_area *asma = file->private_data; ++ struct ashmem_range *range, *next; ++ ++ mutex_lock(&ashmem_mutex); ++ list_for_each_entry_safe(range, next, &asma->unpinned_list, unpinned) ++ range_del(range); ++ mutex_unlock(&ashmem_mutex); ++ ++ if (asma->file) ++ fput(asma->file); ++ kmem_cache_free(ashmem_area_cachep, asma); ++ ++ return 0; ++} ++ ++static int ashmem_mmap(struct file *file, struct vm_area_struct *vma) ++{ ++ struct ashmem_area *asma = file->private_data; ++ int ret = 0; ++ ++ mutex_lock(&ashmem_mutex); ++ ++ /* user needs to SET_SIZE before mapping */ ++ if (unlikely(!asma->size)) { ++ ret = -EINVAL; ++ goto out; ++ } ++ ++ /* requested protection bits must match our allowed protection mask */ ++ if (unlikely((vma->vm_flags & ~asma->prot_mask) & PROT_MASK)) { ++ ret = -EPERM; ++ goto out; ++ } ++ ++ if (!asma->file) { ++ char *name = ASHMEM_NAME_DEF; ++ struct file *vmfile; ++ ++ if (asma->name[0] != '\0') ++ name = asma->name; ++ ++ /* ... and allocate the backing shmem file */ ++ vmfile = shmem_file_setup(name, asma->size, vma->vm_flags); ++ if (unlikely(IS_ERR(vmfile))) { ++ ret = PTR_ERR(vmfile); ++ goto out; ++ } ++ asma->file = vmfile; ++ } ++ get_file(asma->file); ++ ++ shmem_set_file(vma, asma->file); ++ vma->vm_flags |= VM_CAN_NONLINEAR; ++ ++out: ++ mutex_unlock(&ashmem_mutex); ++ return ret; ++} ++ ++/* ++ * ashmem_shrink - our cache shrinker, called from mm/vmscan.c :: shrink_slab ++ * ++ * 'nr_to_scan' is the number of objects (pages) to prune, or 0 to query how ++ * many objects (pages) we have in total. ++ * ++ * 'gfp_mask' is the mask of the allocation that got us into this mess. ++ * ++ * Return value is the number of objects (pages) remaining, or -1 if we cannot ++ * proceed without risk of deadlock (due to gfp_mask). ++ * ++ * We approximate LRU via least-recently-unpinned, jettisoning unpinned partial ++ * chunks of ashmem regions LRU-wise one-at-a-time until we hit 'nr_to_scan' ++ * pages freed. ++ */ ++static int ashmem_shrink(int nr_to_scan, gfp_t gfp_mask) ++{ ++ struct ashmem_range *range, *next; ++ ++ /* We might recurse into filesystem code, so bail out if necessary */ ++ if (nr_to_scan && !(gfp_mask & __GFP_FS)) ++ return -1; ++ if (!nr_to_scan) ++ return lru_count; ++ ++ mutex_lock(&ashmem_mutex); ++ list_for_each_entry_safe(range, next, &ashmem_lru_list, lru) { ++ struct inode *inode = range->asma->file->f_dentry->d_inode; ++ loff_t start = range->pgstart * PAGE_SIZE; ++ loff_t end = (range->pgend + 1) * PAGE_SIZE - 1; ++ ++ vmtruncate_range(inode, start, end); ++ range->purged = ASHMEM_WAS_PURGED; ++ lru_del(range); ++ ++ nr_to_scan -= range_size(range); ++ if (nr_to_scan <= 0) ++ break; ++ } ++ mutex_unlock(&ashmem_mutex); ++ ++ return lru_count; ++} ++ ++static struct shrinker ashmem_shrinker = { ++ .shrink = ashmem_shrink, ++ .seeks = DEFAULT_SEEKS * 4, ++}; ++ ++static int set_prot_mask(struct ashmem_area *asma, unsigned long prot) ++{ ++ int ret = 0; ++ ++ mutex_lock(&ashmem_mutex); ++ ++ /* the user can only remove, not add, protection bits */ ++ if (unlikely((asma->prot_mask & prot) != prot)) { ++ ret = -EINVAL; ++ goto out; ++ } ++ ++ /* does the application expect PROT_READ to imply PROT_EXEC? */ ++ if ((prot & PROT_READ) && (current->personality & READ_IMPLIES_EXEC)) ++ prot |= PROT_EXEC; ++ ++ asma->prot_mask = prot; ++ ++out: ++ mutex_unlock(&ashmem_mutex); ++ return ret; ++} ++ ++static int set_name(struct ashmem_area *asma, void __user *name) ++{ ++ int ret = 0; ++ ++ mutex_lock(&ashmem_mutex); ++ ++ /* cannot change an existing mapping's name */ ++ if (unlikely(asma->file)) { ++ ret = -EINVAL; ++ goto out; ++ } ++ ++ if (unlikely(copy_from_user(asma->name, name, ASHMEM_NAME_LEN))) ++ ret = -EFAULT; ++ asma->name[ASHMEM_NAME_LEN-1] = '\0'; ++ ++out: ++ mutex_unlock(&ashmem_mutex); ++ ++ return ret; ++} ++ ++static int get_name(struct ashmem_area *asma, void __user *name) ++{ ++ int ret = 0; ++ ++ mutex_lock(&ashmem_mutex); ++ if (asma->name[0] != '\0') { ++ size_t len; ++ ++ /* ++ * Copying only `len', instead of ASHMEM_NAME_LEN, bytes ++ * prevents us from revealing one user's stack to another. ++ */ ++ len = strlen(asma->name) + 1; ++ if (unlikely(copy_to_user(name, asma->name, len))) ++ ret = -EFAULT; ++ } else { ++ if (unlikely(copy_to_user(name, ASHMEM_NAME_DEF, ++ sizeof(ASHMEM_NAME_DEF)))) ++ ret = -EFAULT; ++ } ++ mutex_unlock(&ashmem_mutex); ++ ++ return ret; ++} ++ ++/* ++ * ashmem_pin - pin the given ashmem region, returning whether it was ++ * previously purged (ASHMEM_WAS_PURGED) or not (ASHMEM_NOT_PURGED). ++ * ++ * Caller must hold ashmem_mutex. ++ */ ++static int ashmem_pin(struct ashmem_area *asma, size_t pgstart, size_t pgend) ++{ ++ struct ashmem_range *range, *next; ++ int ret = ASHMEM_NOT_PURGED; ++ ++ list_for_each_entry_safe(range, next, &asma->unpinned_list, unpinned) { ++ /* moved past last applicable page; we can short circuit */ ++ if (range_before_page(range, pgstart)) ++ break; ++ ++ /* ++ * The user can ask us to pin pages that span multiple ranges, ++ * or to pin pages that aren't even unpinned, so this is messy. ++ * ++ * Four cases: ++ * 1. The requested range subsumes an existing range, so we ++ * just remove the entire matching range. ++ * 2. The requested range overlaps the start of an existing ++ * range, so we just update that range. ++ * 3. The requested range overlaps the end of an existing ++ * range, so we just update that range. ++ * 4. The requested range punches a hole in an existing range, ++ * so we have to update one side of the range and then ++ * create a new range for the other side. ++ */ ++ if (page_range_in_range(range, pgstart, pgend)) { ++ ret |= range->purged; ++ ++ /* Case #1: Easy. Just nuke the whole thing. */ ++ if (page_range_subsumes_range(range, pgstart, pgend)) { ++ range_del(range); ++ continue; ++ } ++ ++ /* Case #2: We overlap from the start, so adjust it */ ++ if (range->pgstart >= pgstart) { ++ range_shrink(range, pgend + 1, range->pgend); ++ continue; ++ } ++ ++ /* Case #3: We overlap from the rear, so adjust it */ ++ if (range->pgend <= pgend) { ++ range_shrink(range, range->pgstart, pgstart-1); ++ continue; ++ } ++ ++ /* ++ * Case #4: We eat a chunk out of the middle. A bit ++ * more complicated, we allocate a new range for the ++ * second half and adjust the first chunk's endpoint. ++ */ ++ range_alloc(asma, range, range->purged, ++ pgend + 1, range->pgend); ++ range_shrink(range, range->pgstart, pgstart - 1); ++ break; ++ } ++ } ++ ++ return ret; ++} ++ ++/* ++ * ashmem_unpin - unpin the given range of pages. Returns zero on success. ++ * ++ * Caller must hold ashmem_mutex. ++ */ ++static int ashmem_unpin(struct ashmem_area *asma, size_t pgstart, size_t pgend) ++{ ++ struct ashmem_range *range, *next; ++ unsigned int purged = ASHMEM_NOT_PURGED; ++ ++restart: ++ list_for_each_entry_safe(range, next, &asma->unpinned_list, unpinned) { ++ /* short circuit: this is our insertion point */ ++ if (range_before_page(range, pgstart)) ++ break; ++ ++ /* ++ * The user can ask us to unpin pages that are already entirely ++ * or partially pinned. We handle those two cases here. ++ */ ++ if (page_range_subsumed_by_range(range, pgstart, pgend)) ++ return 0; ++ if (page_range_in_range(range, pgstart, pgend)) { ++ pgstart = min_t(size_t, range->pgstart, pgstart), ++ pgend = max_t(size_t, range->pgend, pgend); ++ purged |= range->purged; ++ range_del(range); ++ goto restart; ++ } ++ } ++ ++ return range_alloc(asma, range, purged, pgstart, pgend); ++} ++ ++/* ++ * ashmem_get_pin_status - Returns ASHMEM_IS_UNPINNED if _any_ pages in the ++ * given interval are unpinned and ASHMEM_IS_PINNED otherwise. ++ * ++ * Caller must hold ashmem_mutex. ++ */ ++static int ashmem_get_pin_status(struct ashmem_area *asma, size_t pgstart, ++ size_t pgend) ++{ ++ struct ashmem_range *range; ++ int ret = ASHMEM_IS_PINNED; ++ ++ list_for_each_entry(range, &asma->unpinned_list, unpinned) { ++ if (range_before_page(range, pgstart)) ++ break; ++ if (page_range_in_range(range, pgstart, pgend)) { ++ ret = ASHMEM_IS_UNPINNED; ++ break; ++ } ++ } ++ ++ return ret; ++} ++ ++static int ashmem_pin_unpin(struct ashmem_area *asma, unsigned long cmd, ++ void __user *p) ++{ ++ struct ashmem_pin pin; ++ size_t pgstart, pgend; ++ int ret = -EINVAL; ++ ++ if (unlikely(!asma->file)) ++ return -EINVAL; ++ ++ if (unlikely(copy_from_user(&pin, p, sizeof(pin)))) ++ return -EFAULT; ++ ++ /* per custom, you can pass zero for len to mean "everything onward" */ ++ if (!pin.len) ++ pin.len = asma->size - pin.offset; ++ ++ if (unlikely((pin.offset | pin.len) & ~PAGE_MASK)) ++ return -EINVAL; ++ ++ if (unlikely(((__u32) -1) - pin.offset < pin.len)) ++ return -EINVAL; ++ ++ if (unlikely(asma->size < pin.offset + pin.len)) ++ return -EINVAL; ++ ++ pgstart = pin.offset / PAGE_SIZE; ++ pgend = pgstart + (pin.len / PAGE_SIZE) - 1; ++ ++ mutex_lock(&ashmem_mutex); ++ ++ switch (cmd) { ++ case ASHMEM_PIN: ++ ret = ashmem_pin(asma, pgstart, pgend); ++ break; ++ case ASHMEM_UNPIN: ++ ret = ashmem_unpin(asma, pgstart, pgend); ++ break; ++ case ASHMEM_GET_PIN_STATUS: ++ ret = ashmem_get_pin_status(asma, pgstart, pgend); ++ break; ++ } ++ ++ mutex_unlock(&ashmem_mutex); ++ ++ return ret; ++} ++ ++static long ashmem_ioctl(struct file *file, unsigned int cmd, unsigned long arg) ++{ ++ struct ashmem_area *asma = file->private_data; ++ long ret = -ENOTTY; ++ ++ switch (cmd) { ++ case ASHMEM_SET_NAME: ++ ret = set_name(asma, (void __user *) arg); ++ break; ++ case ASHMEM_GET_NAME: ++ ret = get_name(asma, (void __user *) arg); ++ break; ++ case ASHMEM_SET_SIZE: ++ ret = -EINVAL; ++ if (!asma->file && !(arg & ~PAGE_MASK)) { ++ ret = 0; ++ asma->size = (size_t) arg; ++ } ++ break; ++ case ASHMEM_GET_SIZE: ++ ret = asma->size; ++ break; ++ case ASHMEM_SET_PROT_MASK: ++ ret = set_prot_mask(asma, arg); ++ break; ++ case ASHMEM_GET_PROT_MASK: ++ ret = asma->prot_mask; ++ break; ++ case ASHMEM_PIN: ++ case ASHMEM_UNPIN: ++ case ASHMEM_GET_PIN_STATUS: ++ ret = ashmem_pin_unpin(asma, cmd, (void __user *) arg); ++ break; ++ case ASHMEM_PURGE_ALL_CACHES: ++ ret = -EPERM; ++ if (capable(CAP_SYS_ADMIN)) { ++ ret = ashmem_shrink(0, GFP_KERNEL); ++ ashmem_shrink(ret, GFP_KERNEL); ++ } ++ break; ++ } ++ ++ return ret; ++} ++ ++static struct file_operations ashmem_fops = { ++ .owner = THIS_MODULE, ++ .open = ashmem_open, ++ .release = ashmem_release, ++ .mmap = ashmem_mmap, ++ .unlocked_ioctl = ashmem_ioctl, ++ .compat_ioctl = ashmem_ioctl, ++}; ++ ++static struct miscdevice ashmem_misc = { ++ .minor = MISC_DYNAMIC_MINOR, ++ .name = "ashmem", ++ .fops = &ashmem_fops, ++}; ++ ++static int __init ashmem_init(void) ++{ ++ int ret; ++ ++ ashmem_area_cachep = kmem_cache_create("ashmem_area_cache", ++ sizeof(struct ashmem_area), ++ 0, 0, NULL); ++ if (unlikely(!ashmem_area_cachep)) { ++ printk(KERN_ERR "ashmem: failed to create slab cache\n"); ++ return -ENOMEM; ++ } ++ ++ ashmem_range_cachep = kmem_cache_create("ashmem_range_cache", ++ sizeof(struct ashmem_range), ++ 0, 0, NULL); ++ if (unlikely(!ashmem_range_cachep)) { ++ printk(KERN_ERR "ashmem: failed to create slab cache\n"); ++ return -ENOMEM; ++ } ++ ++ ret = misc_register(&ashmem_misc); ++ if (unlikely(ret)) { ++ printk(KERN_ERR "ashmem: failed to register misc device!\n"); ++ return ret; ++ } ++ ++ register_shrinker(&ashmem_shrinker); ++ ++ printk(KERN_INFO "ashmem: initialized\n"); ++ ++ return 0; ++} ++ ++static void __exit ashmem_exit(void) ++{ ++ int ret; ++ ++ unregister_shrinker(&ashmem_shrinker); ++ ++ ret = misc_deregister(&ashmem_misc); ++ if (unlikely(ret)) ++ printk(KERN_ERR "ashmem: failed to unregister misc device!\n"); ++ ++ kmem_cache_destroy(ashmem_range_cachep); ++ kmem_cache_destroy(ashmem_area_cachep); ++ ++ printk(KERN_INFO "ashmem: unloaded\n"); ++} ++ ++module_init(ashmem_init); ++module_exit(ashmem_exit); ++ ++MODULE_LICENSE("GPL"); +diff -ruN --exclude='*.orig' --exclude='*.rej' linux-2.6.29-rc3.owrt/mm/Makefile linux-2.6.29-rc3.owrt.om/mm/Makefile +--- linux-2.6.29-rc3.owrt/mm/Makefile 2009-05-10 22:04:53.000000000 +0200 ++++ linux-2.6.29-rc3.owrt.om/mm/Makefile 2009-05-10 22:28:00.000000000 +0200 +@@ -21,6 +21,8 @@ + obj-$(CONFIG_NUMA) += mempolicy.o + obj-$(CONFIG_SPARSEMEM) += sparse.o + obj-$(CONFIG_SPARSEMEM_VMEMMAP) += sparse-vmemmap.o ++obj-$(CONFIG_SHMEM) += shmem.o ++obj-$(CONFIG_ASHMEM) += ashmem.o + obj-$(CONFIG_TMPFS_POSIX_ACL) += shmem_acl.o + obj-$(CONFIG_SLOB) += slob.o + obj-$(CONFIG_MMU_NOTIFIER) += mmu_notifier.o +diff -ruN --exclude='*.orig' --exclude='*.rej' linux-2.6.29-rc3.owrt/mm/tiny-shmem.c linux-2.6.29-rc3.owrt.om/mm/tiny-shmem.c +--- linux-2.6.29-rc3.owrt/mm/tiny-shmem.c 1970-01-01 01:00:00.000000000 +0100 ++++ linux-2.6.29-rc3.owrt.om/mm/tiny-shmem.c 2009-05-10 22:28:00.000000000 +0200 +@@ -0,0 +1,148 @@ ++/* ++ * tiny-shmem.c: simple shmemfs and tmpfs using ramfs code ++ * ++ * Matt Mackall <mpm@selenic.com> January, 2004 ++ * derived from mm/shmem.c and fs/ramfs/inode.c ++ * ++ * This is intended for small system where the benefits of the full ++ * shmem code (swap-backed and resource-limited) are outweighed by ++ * their complexity. On systems without swap this code should be ++ * effectively equivalent, but much lighter weight. ++ */ ++ ++#include <linux/fs.h> ++#include <linux/init.h> ++#include <linux/vfs.h> ++#include <linux/mount.h> ++#include <linux/file.h> ++#include <linux/mm.h> ++#include <linux/module.h> ++#include <linux/swap.h> ++#include <linux/ramfs.h> ++ ++static struct file_system_type tmpfs_fs_type = { ++ .name = "tmpfs", ++ .get_sb = ramfs_get_sb, ++ .kill_sb = kill_litter_super, ++}; ++ ++static struct vfsmount *shm_mnt; ++ ++static int __init init_tmpfs(void) ++{ ++ BUG_ON(register_filesystem(&tmpfs_fs_type) != 0); ++ ++ shm_mnt = kern_mount(&tmpfs_fs_type); ++ BUG_ON(IS_ERR(shm_mnt)); ++ ++ return 0; ++} ++module_init(init_tmpfs) ++ ++/** ++ * shmem_file_setup - get an unlinked file living in tmpfs ++ * @name: name for dentry (to be seen in /proc/<pid>/maps ++ * @size: size to be set for the file ++ * @flags: vm_flags ++ */ ++struct file *shmem_file_setup(char *name, loff_t size, unsigned long flags) ++{ ++ int error; ++ struct file *file; ++ struct inode *inode; ++ struct dentry *dentry, *root; ++ struct qstr this; ++ ++ if (IS_ERR(shm_mnt)) ++ return (void *)shm_mnt; ++ ++ error = -ENOMEM; ++ this.name = name; ++ this.len = strlen(name); ++ this.hash = 0; /* will go */ ++ root = shm_mnt->mnt_root; ++ dentry = d_alloc(root, &this); ++ if (!dentry) ++ goto put_memory; ++ ++ error = -ENFILE; ++ file = get_empty_filp(); ++ if (!file) ++ goto put_dentry; ++ ++ error = -ENOSPC; ++ inode = ramfs_get_inode(root->d_sb, S_IFREG | S_IRWXUGO, 0); ++ if (!inode) ++ goto close_file; ++ ++ d_instantiate(dentry, inode); ++ inode->i_size = size; ++ inode->i_nlink = 0; /* It is unlinked */ ++ init_file(file, shm_mnt, dentry, FMODE_WRITE | FMODE_READ, ++ &ramfs_file_operations); ++ ++#ifndef CONFIG_MMU ++ error = ramfs_nommu_expand_for_mapping(inode, size); ++ if (error) ++ goto close_file; ++#endif ++ return file; ++ ++close_file: ++ put_filp(file); ++put_dentry: ++ dput(dentry); ++put_memory: ++ return ERR_PTR(error); ++} ++EXPORT_SYMBOL_GPL(shmem_file_setup); ++ ++void shmem_set_file(struct vm_area_struct *vma, struct file *file) ++{ ++ if (vma->vm_file) ++ fput(vma->vm_file); ++ vma->vm_file = file; ++ vma->vm_ops = &generic_file_vm_ops; ++} ++ ++void shmem_set_file(struct vm_area_struct *vma, struct file *file) ++{ ++ if (vma->vm_file) ++ fput(vma->vm_file); ++ vma->vm_file = file; ++ vma->vm_ops = &generic_file_vm_ops; ++} ++ ++/** ++ * shmem_zero_setup - setup a shared anonymous mapping ++ * @vma: the vma to be mmapped is prepared by do_mmap_pgoff ++ */ ++int shmem_zero_setup(struct vm_area_struct *vma) ++{ ++ struct file *file; ++ loff_t size = vma->vm_end - vma->vm_start; ++ ++ file = shmem_file_setup("dev/zero", size, vma->vm_flags); ++ if (IS_ERR(file)) ++ return PTR_ERR(file); ++ ++ shmem_set_file(vma, file); ++ ++ return 0; ++} ++ ++int shmem_unuse(swp_entry_t entry, struct page *page) ++{ ++ return 0; ++} ++ ++#ifndef CONFIG_MMU ++unsigned long shmem_get_unmapped_area(struct file *file, ++ unsigned long addr, ++ unsigned long len, ++ unsigned long pgoff, ++ unsigned long flags) ++{ ++ return ramfs_nommu_get_unmapped_area(file, addr, len, pgoff, flags); ++} ++#endif +diff -ruN --exclude='*.orig' --exclude='*.rej' linux-2.6.29-rc3.owrt/remote_install_sdcard linux-2.6.29-rc3.owrt.om/remote_install_sdcard +--- linux-2.6.29-rc3.owrt/remote_install_sdcard 1970-01-01 01:00:00.000000000 +0100 ++++ linux-2.6.29-rc3.owrt.om/remote_install_sdcard 2009-05-10 22:28:00.000000000 +0200 +@@ -0,0 +1,18 @@ ++#!/bin/sh ++ ++# automatic kernel updater and reboot - Andy Green <andy@openmoko.com> ++ ++GTA_DEVICE_IP=192.168.0.202 ++ ++# you should set up key-based auth on dropbear if you want ++# to play this game. ++# ++# 1) mkdir /home/root/.ssh ++# 2) chown root:root / /home /home/root ++# 3) chmod 700 /home/root /home/root/.ssh ++# 4) copy your id_*.pub into /home/root/.ssh/authorized_keys ++# 5) chmod 600 /home/root/.ssh/* ++ ++scp uImage.bin root@$GTA_DEVICE_IP:/boot ++ssh root@$GTA_DEVICE_IP "mount /dev/mmcblk0p1 / -oremount,ro ; reboot -if &" ++ +diff -ruN --exclude='*.orig' --exclude='*.rej' linux-2.6.29-rc3.owrt/scripts/mkuboot.sh linux-2.6.29-rc3.owrt.om/scripts/mkuboot.sh +--- linux-2.6.29-rc3.owrt/scripts/mkuboot.sh 2009-05-10 22:04:48.000000000 +0200 ++++ linux-2.6.29-rc3.owrt.om/scripts/mkuboot.sh 2009-05-10 22:28:00.000000000 +0200 +@@ -11,7 +11,7 @@ + if [ -z "${MKIMAGE}" ]; then + # Doesn't exist + echo '"mkimage" command not found - U-Boot images will not be built' >&2 +- exit 0; ++ exit 1; + fi + fi + +diff -ruN --exclude='*.orig' --exclude='*.rej' linux-2.6.29-rc3.owrt/sound/soc/codecs/wm8731.c linux-2.6.29-rc3.owrt.om/sound/soc/codecs/wm8731.c +--- linux-2.6.29-rc3.owrt/sound/soc/codecs/wm8731.c 2009-05-10 22:05:01.000000000 +0200 ++++ linux-2.6.29-rc3.owrt.om/sound/soc/codecs/wm8731.c 2009-05-10 22:28:00.000000000 +0200 +@@ -73,6 +73,8 @@ + u16 *cache = codec->reg_cache; + if (reg >= WM8731_CACHEREGNUM) + return; ++ ++ printk(KERN_INFO "%s: reg %d, val %04x\n", __func__, reg, value); + cache[reg] = value; + } + +@@ -84,6 +86,8 @@ + { + u8 data[2]; + ++ printk(KERN_INFO "%s: reg %d val %04x\n", __func__, reg, value); ++ + /* data is + * D15..D9 WM8731 register offset + * D8...D0 register data +@@ -521,7 +525,11 @@ + if (codec->reg_cache == NULL) + return -ENOMEM; + +- wm8731_reset(codec); ++ ret = wm8731_reset(codec); ++ if (ret < 0) { ++ printk(KERN_ERR "wm8731: failed to send reset\n"); ++ return -EIO; ++ } + + /* register pcms */ + ret = snd_soc_new_pcms(socdev, SNDRV_DEFAULT_IDX1, SNDRV_DEFAULT_STR1); +diff -ruN --exclude='*.orig' --exclude='*.rej' linux-2.6.29-rc3.owrt/sound/soc/codecs/wm8753.c linux-2.6.29-rc3.owrt.om/sound/soc/codecs/wm8753.c +--- linux-2.6.29-rc3.owrt/sound/soc/codecs/wm8753.c 2009-05-10 22:09:10.000000000 +0200 ++++ linux-2.6.29-rc3.owrt.om/sound/soc/codecs/wm8753.c 2009-05-10 22:28:00.000000000 +0200 +@@ -51,8 +51,6 @@ + + #include "wm8753.h" + +-#define WM8753_VERSION "0.16" +- + static int caps_charge = 2000; + module_param(caps_charge, int, 0); + MODULE_PARM_DESC(caps_charge, "WM8753 cap charge time (msecs)"); +@@ -60,12 +58,6 @@ + static void wm8753_set_dai_mode(struct snd_soc_codec *codec, + unsigned int mode); + +-/* codec private data */ +-struct wm8753_priv { +- unsigned int sysclk; +- unsigned int pcmclk; +-}; +- + /* + * wm8753 register cache + * We can't read the WM8753 register space when we +@@ -90,6 +82,14 @@ + 0x0000, 0x0000 + }; + ++/* codec private data */ ++struct wm8753_priv { ++ unsigned int sysclk; ++ unsigned int pcmclk; ++ struct snd_soc_codec codec; ++ u16 reg_cache[ARRAY_SIZE(wm8753_reg)]; ++}; ++ + /* + * read wm8753 register cache + */ +@@ -1451,7 +1451,15 @@ + }, + }; + +-struct snd_soc_dai wm8753_dai[2]; ++struct snd_soc_dai wm8753_dai[2] = { ++ { ++ .name = "dummy1" ++ }, ++ { ++ .name = "dummy2" ++ }, ++}; ++ + EXPORT_SYMBOL_GPL(wm8753_dai); + + static void wm8753_set_dai_mode(struct snd_soc_codec *codec, unsigned int mode) +@@ -1459,30 +1467,35 @@ + if (mode < 4) { + int playback_active, capture_active, codec_active, pop_wait; + void *private_data; ++ struct list_head list; + + playback_active = wm8753_dai[0].playback.active; + capture_active = wm8753_dai[0].capture.active; + codec_active = wm8753_dai[0].active; + private_data = wm8753_dai[0].private_data; + pop_wait = wm8753_dai[0].pop_wait; ++ list = wm8753_dai[0].list; + wm8753_dai[0] = wm8753_all_dai[mode << 1]; + wm8753_dai[0].playback.active = playback_active; + wm8753_dai[0].capture.active = capture_active; + wm8753_dai[0].active = codec_active; + wm8753_dai[0].private_data = private_data; + wm8753_dai[0].pop_wait = pop_wait; ++ wm8753_dai[0].list = list; + + playback_active = wm8753_dai[1].playback.active; + capture_active = wm8753_dai[1].capture.active; + codec_active = wm8753_dai[1].active; + private_data = wm8753_dai[1].private_data; + pop_wait = wm8753_dai[1].pop_wait; ++ list = wm8753_dai[1].list; + wm8753_dai[1] = wm8753_all_dai[(mode << 1) + 1]; + wm8753_dai[1].playback.active = playback_active; + wm8753_dai[1].capture.active = capture_active; + wm8753_dai[1].active = codec_active; + wm8753_dai[1].private_data = private_data; + wm8753_dai[1].pop_wait = pop_wait; ++ wm8753_dai[1].list = list; + } + wm8753_dai[0].codec = codec; + wm8753_dai[1].codec = codec; +@@ -1524,6 +1537,11 @@ + for (i = 0; i < ARRAY_SIZE(wm8753_reg); i++) { + if (i + 1 == WM8753_RESET) + continue; ++ ++ /* No point in writing hardware default values back */ ++ if (cache[i] == wm8753_reg[i]) ++ continue; ++ + data[0] = ((i + 1) << 1) | ((cache[i] >> 8) & 0x0001); + data[1] = cache[i] & 0x00ff; + codec->hw_write(codec->control_data, data, 2); +@@ -1542,44 +1560,133 @@ + return 0; + } + ++static struct snd_soc_codec *wm8753_codec; ++ ++static int wm8753_probe(struct platform_device *pdev) ++{ ++ struct snd_soc_device *socdev = platform_get_drvdata(pdev); ++ struct snd_soc_codec *codec; ++ int ret = 0; ++ ++ if (!wm8753_codec) { ++ dev_err(&pdev->dev, "WM8753 codec not yet registered\n"); ++ return -EINVAL; ++ } ++ ++ socdev->codec = wm8753_codec; ++ codec = wm8753_codec; ++ ++ wm8753_set_dai_mode(codec, 0); ++ ++ /* register pcms */ ++ ret = snd_soc_new_pcms(socdev, SNDRV_DEFAULT_IDX1, SNDRV_DEFAULT_STR1); ++ if (ret < 0) { ++ printk(KERN_ERR "wm8753: failed to create pcms\n"); ++ goto pcm_err; ++ } ++ ++ wm8753_add_controls(codec); ++ wm8753_add_widgets(codec); ++ ret = snd_soc_init_card(socdev); ++ if (ret < 0) { ++ printk(KERN_ERR "wm8753: failed to register card\n"); ++ goto card_err; ++ } ++ ++ return 0; ++ ++card_err: ++ snd_soc_free_pcms(socdev); ++ snd_soc_dapm_free(socdev); ++ ++pcm_err: ++ return ret; ++} ++ + /* +- * initialise the WM8753 driver +- * register the mixer and dsp interfaces with the kernel ++ * This function forces any delayed work to be queued and run. + */ +-static int wm8753_init(struct snd_soc_device *socdev) ++static int run_delayed_work(struct delayed_work *dwork) + { +- struct snd_soc_codec *codec = socdev->codec; +- int reg, ret = 0; ++ int ret; ++ ++ /* cancel any work waiting to be queued. */ ++ ret = cancel_delayed_work(dwork); ++ ++ /* if there was any work waiting then we run it now and ++ * wait for it's completion */ ++ if (ret) { ++ schedule_delayed_work(dwork, 0); ++ flush_scheduled_work(); ++ } ++ return ret; ++} ++ ++/* power down chip */ ++static int wm8753_remove(struct platform_device *pdev) ++{ ++ struct snd_soc_device *socdev = platform_get_drvdata(pdev); ++ ++ snd_soc_free_pcms(socdev); ++ snd_soc_dapm_free(socdev); ++ ++ return 0; ++} ++ ++struct snd_soc_codec_device soc_codec_dev_wm8753 = { ++ .probe = wm8753_probe, ++ .remove = wm8753_remove, ++ .suspend = wm8753_suspend, ++ .resume = wm8753_resume, ++}; ++EXPORT_SYMBOL_GPL(soc_codec_dev_wm8753); ++ ++static int wm8753_register(struct wm8753_priv *wm8753) ++{ ++ int ret, i; ++ struct snd_soc_codec *codec = &wm8753->codec; ++ u16 reg; ++ ++ if (wm8753_codec) { ++ dev_err(codec->dev, "Multiple WM8753 devices not supported\n"); ++ ret = -EINVAL; ++ goto err; ++ } ++ ++ mutex_init(&codec->mutex); ++ INIT_LIST_HEAD(&codec->dapm_widgets); ++ INIT_LIST_HEAD(&codec->dapm_paths); + + codec->name = "WM8753"; + codec->owner = THIS_MODULE; + codec->read = wm8753_read_reg_cache; + codec->write = wm8753_write; ++ codec->bias_level = SND_SOC_BIAS_STANDBY; + codec->set_bias_level = wm8753_set_bias_level; + codec->dai = wm8753_dai; + codec->num_dai = 2; +- codec->reg_cache_size = ARRAY_SIZE(wm8753_reg); +- codec->reg_cache = kmemdup(wm8753_reg, sizeof(wm8753_reg), GFP_KERNEL); +- +- if (codec->reg_cache == NULL) +- return -ENOMEM; +- +- wm8753_set_dai_mode(codec, 0); ++ codec->reg_cache_size = ARRAY_SIZE(wm8753->reg_cache); ++ codec->reg_cache = &wm8753->reg_cache; ++ codec->private_data = wm8753; + +- wm8753_reset(codec); ++ memcpy(codec->reg_cache, wm8753_reg, sizeof(codec->reg_cache)); ++ INIT_DELAYED_WORK(&codec->delayed_work, wm8753_work); + +- /* register pcms */ +- ret = snd_soc_new_pcms(socdev, SNDRV_DEFAULT_IDX1, SNDRV_DEFAULT_STR1); ++ ret = wm8753_reset(codec); + if (ret < 0) { +- printk(KERN_ERR "wm8753: failed to create pcms\n"); +- goto pcm_err; ++ dev_err(codec->dev, "Failed to issue reset\n"); ++ goto err; + } + + /* charge output caps */ + wm8753_set_bias_level(codec, SND_SOC_BIAS_PREPARE); +- codec->bias_level = SND_SOC_BIAS_STANDBY; + schedule_delayed_work(&codec->delayed_work, +- msecs_to_jiffies(caps_charge)); ++ msecs_to_jiffies(caps_charge)); ++ ++ /* OpenMoko specific bodge for ++ * http://bugzilla.openmoko.org/cgi-bin/bugzilla/show_bug.cgi?id=1172 ++ */ ++ wm8753_write(codec, WM8753_ADCTL2, 0x0000); + + /* set the update bits */ + reg = wm8753_read_reg_cache(codec, WM8753_LDAC); +@@ -1603,58 +1710,69 @@ + reg = wm8753_read_reg_cache(codec, WM8753_RINVOL); + wm8753_write(codec, WM8753_RINVOL, reg | 0x0100); + +- wm8753_add_controls(codec); +- wm8753_add_widgets(codec); +- ret = snd_soc_init_card(socdev); +- if (ret < 0) { +- printk(KERN_ERR "wm8753: failed to register card\n"); +- goto card_err; ++ wm8753_codec = codec; ++ ++ for (i = 0; i < ARRAY_SIZE(wm8753_dai); i++) ++ wm8753_dai[i].dev = codec->dev; ++ ++ ret = snd_soc_register_codec(codec); ++ if (ret != 0) { ++ dev_err(codec->dev, "Failed to register codec: %d\n", ret); ++ goto err; + } + +- return ret; ++ ret = snd_soc_register_dais(&wm8753_dai[0], ARRAY_SIZE(wm8753_dai)); ++ if (ret != 0) { ++ dev_err(codec->dev, "Failed to register DAIs: %d\n", ret); ++ goto err_codec; ++ } + +-card_err: +- snd_soc_free_pcms(socdev); +- snd_soc_dapm_free(socdev); +-pcm_err: +- kfree(codec->reg_cache); ++ return 0; ++ ++err_codec: ++ run_delayed_work(&codec->delayed_work); ++ snd_soc_unregister_codec(codec); ++err: ++ kfree(wm8753); + return ret; + } + +-/* If the i2c layer weren't so broken, we could pass this kind of data +- around */ +-static struct snd_soc_device *wm8753_socdev; ++static void wm8753_unregister(struct wm8753_priv *wm8753) ++{ ++ wm8753_set_bias_level(&wm8753->codec, SND_SOC_BIAS_OFF); ++ run_delayed_work(&wm8753->codec.delayed_work); ++ snd_soc_unregister_dais(&wm8753_dai[0], ARRAY_SIZE(wm8753_dai)); ++ snd_soc_unregister_codec(&wm8753->codec); ++ kfree(wm8753); ++ wm8753_codec = NULL; ++} + + #if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE) + +-/* +- * WM8753 2 wire address is determined by GPIO5 +- * state during powerup. +- * low = 0x1a +- * high = 0x1b +- */ +- + static int wm8753_i2c_probe(struct i2c_client *i2c, + const struct i2c_device_id *id) + { +- struct snd_soc_device *socdev = wm8753_socdev; +- struct snd_soc_codec *codec = socdev->codec; +- int ret; ++ struct snd_soc_codec *codec; ++ struct wm8753_priv *wm8753; + +- i2c_set_clientdata(i2c, codec); ++ wm8753 = kzalloc(sizeof(struct wm8753_priv), GFP_KERNEL); ++ if (wm8753 == NULL) ++ return -ENOMEM; ++ ++ codec = &wm8753->codec; ++ codec->hw_write = (hw_write_t)i2c_master_send; + codec->control_data = i2c; ++ i2c_set_clientdata(i2c, wm8753); + +- ret = wm8753_init(socdev); +- if (ret < 0) +- pr_err("failed to initialise WM8753\n"); ++ codec->dev = &i2c->dev; + +- return ret; ++ return wm8753_register(wm8753); + } + + static int wm8753_i2c_remove(struct i2c_client *client) + { +- struct snd_soc_codec *codec = i2c_get_clientdata(client); +- kfree(codec->reg_cache); ++ struct wm8753_priv *wm8753 = i2c_get_clientdata(client); ++ wm8753_unregister(wm8753); + return 0; + } + +@@ -1666,86 +1784,16 @@ + + static struct i2c_driver wm8753_i2c_driver = { + .driver = { +- .name = "WM8753 I2C Codec", ++ .name = "wm8753", + .owner = THIS_MODULE, + }, + .probe = wm8753_i2c_probe, + .remove = wm8753_i2c_remove, + .id_table = wm8753_i2c_id, + }; +- +-static int wm8753_add_i2c_device(struct platform_device *pdev, +- const struct wm8753_setup_data *setup) +-{ +- struct i2c_board_info info; +- struct i2c_adapter *adapter; +- struct i2c_client *client; +- int ret; +- +- ret = i2c_add_driver(&wm8753_i2c_driver); +- if (ret != 0) { +- dev_err(&pdev->dev, "can't add i2c driver\n"); +- return ret; +- } +- +- memset(&info, 0, sizeof(struct i2c_board_info)); +- info.addr = setup->i2c_address; +- strlcpy(info.type, "wm8753", I2C_NAME_SIZE); +- +- adapter = i2c_get_adapter(setup->i2c_bus); +- if (!adapter) { +- dev_err(&pdev->dev, "can't get i2c adapter %d\n", +- setup->i2c_bus); +- goto err_driver; +- } +- +- client = i2c_new_device(adapter, &info); +- i2c_put_adapter(adapter); +- if (!client) { +- dev_err(&pdev->dev, "can't add i2c device at 0x%x\n", +- (unsigned int)info.addr); +- goto err_driver; +- } +- +- return 0; +- +-err_driver: +- i2c_del_driver(&wm8753_i2c_driver); +- return -ENODEV; +-} + #endif + + #if defined(CONFIG_SPI_MASTER) +-static int __devinit wm8753_spi_probe(struct spi_device *spi) +-{ +- struct snd_soc_device *socdev = wm8753_socdev; +- struct snd_soc_codec *codec = socdev->codec; +- int ret; +- +- codec->control_data = spi; +- +- ret = wm8753_init(socdev); +- if (ret < 0) +- dev_err(&spi->dev, "failed to initialise WM8753\n"); +- +- return ret; +-} +- +-static int __devexit wm8753_spi_remove(struct spi_device *spi) +-{ +- return 0; +-} +- +-static struct spi_driver wm8753_spi_driver = { +- .driver = { +- .name = "wm8753", +- .bus = &spi_bus_type, +- .owner = THIS_MODULE, +- }, +- .probe = wm8753_spi_probe, +- .remove = __devexit_p(wm8753_spi_remove), +-}; +- + static int wm8753_spi_write(struct spi_device *spi, const char *data, int len) + { + struct spi_transfer t; +@@ -1769,120 +1817,69 @@ + + return len; + } +-#endif +- + +-static int wm8753_probe(struct platform_device *pdev) ++static int __devinit wm8753_spi_probe(struct spi_device *spi) + { +- struct snd_soc_device *socdev = platform_get_drvdata(pdev); +- struct wm8753_setup_data *setup; + struct snd_soc_codec *codec; + struct wm8753_priv *wm8753; +- int ret = 0; +- +- pr_info("WM8753 Audio Codec %s", WM8753_VERSION); +- +- setup = socdev->codec_data; +- codec = kzalloc(sizeof(struct snd_soc_codec), GFP_KERNEL); +- if (codec == NULL) +- return -ENOMEM; + + wm8753 = kzalloc(sizeof(struct wm8753_priv), GFP_KERNEL); +- if (wm8753 == NULL) { +- kfree(codec); ++ if (wm8753 == NULL) + return -ENOMEM; +- } + +- codec->private_data = wm8753; +- socdev->codec = codec; +- mutex_init(&codec->mutex); +- INIT_LIST_HEAD(&codec->dapm_widgets); +- INIT_LIST_HEAD(&codec->dapm_paths); +- wm8753_socdev = socdev; +- INIT_DELAYED_WORK(&codec->delayed_work, wm8753_work); ++ codec = &wm8753->codec; ++ codec->control_data = spi; ++ codec->hw_write = (hw_write_t)wm8753_spi_write; ++ codec->dev = &spi->dev; + +-#if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE) +- if (setup->i2c_address) { +- codec->hw_write = (hw_write_t)i2c_master_send; +- ret = wm8753_add_i2c_device(pdev, setup); +- } +-#endif +-#if defined(CONFIG_SPI_MASTER) +- if (setup->spi) { +- codec->hw_write = (hw_write_t)wm8753_spi_write; +- ret = spi_register_driver(&wm8753_spi_driver); +- if (ret != 0) +- printk(KERN_ERR "can't add spi driver"); +- } +-#endif ++ spi->dev.driver_data = wm8753; + +- if (ret != 0) { +- kfree(codec->private_data); +- kfree(codec); +- } +- return ret; ++ return wm8753_register(wm8753); + } + +-/* +- * This function forces any delayed work to be queued and run. +- */ +-static int run_delayed_work(struct delayed_work *dwork) ++static int __devexit wm8753_spi_remove(struct spi_device *spi) + { +- int ret; +- +- /* cancel any work waiting to be queued. */ +- ret = cancel_delayed_work(dwork); +- +- /* if there was any work waiting then we run it now and +- * wait for it's completion */ +- if (ret) { +- schedule_delayed_work(dwork, 0); +- flush_scheduled_work(); +- } +- return ret; ++ struct wm8753_priv *wm8753 = spi->dev.driver_data; ++ wm8753_unregister(wm8753); ++ return 0; + } + +-/* power down chip */ +-static int wm8753_remove(struct platform_device *pdev) +-{ +- struct snd_soc_device *socdev = platform_get_drvdata(pdev); +- struct snd_soc_codec *codec = socdev->codec; ++static struct spi_driver wm8753_spi_driver = { ++ .driver = { ++ .name = "wm8753", ++ .bus = &spi_bus_type, ++ .owner = THIS_MODULE, ++ }, ++ .probe = wm8753_spi_probe, ++ .remove = __devexit_p(wm8753_spi_remove), ++}; ++#endif + +- if (codec->control_data) +- wm8753_set_bias_level(codec, SND_SOC_BIAS_OFF); +- run_delayed_work(&codec->delayed_work); +- snd_soc_free_pcms(socdev); +- snd_soc_dapm_free(socdev); ++static int __init wm8753_modinit(void) ++{ ++ int ret; + #if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE) +- i2c_unregister_device(codec->control_data); +- i2c_del_driver(&wm8753_i2c_driver); ++ ret = i2c_add_driver(&wm8753_i2c_driver); ++ if (ret != 0) ++ pr_err("Failed to register WM8753 I2C driver: %d\n", ret); + #endif + #if defined(CONFIG_SPI_MASTER) +- spi_unregister_driver(&wm8753_spi_driver); ++ ret = spi_register_driver(&wm8753_spi_driver); ++ if (ret != 0) ++ pr_err("Failed to register WM8753 SPI driver: %d\n", ret); + #endif +- kfree(codec->private_data); +- kfree(codec); +- + return 0; + } +- +-struct snd_soc_codec_device soc_codec_dev_wm8753 = { +- .probe = wm8753_probe, +- .remove = wm8753_remove, +- .suspend = wm8753_suspend, +- .resume = wm8753_resume, +-}; +-EXPORT_SYMBOL_GPL(soc_codec_dev_wm8753); +- +-static int __init wm8753_modinit(void) +-{ +- return snd_soc_register_dais(wm8753_dai, ARRAY_SIZE(wm8753_dai)); +-} + module_init(wm8753_modinit); + + static void __exit wm8753_exit(void) + { +- snd_soc_unregister_dais(wm8753_dai, ARRAY_SIZE(wm8753_dai)); ++#if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE) ++ i2c_del_driver(&wm8753_i2c_driver); ++#endif ++#if defined(CONFIG_SPI_MASTER) ++ spi_unregister_driver(&wm8753_spi_driver); ++#endif + } + module_exit(wm8753_exit); + +diff -ruN --exclude='*.orig' --exclude='*.rej' linux-2.6.29-rc3.owrt/sound/soc/codecs/wm8753.h linux-2.6.29-rc3.owrt.om/sound/soc/codecs/wm8753.h +--- linux-2.6.29-rc3.owrt/sound/soc/codecs/wm8753.h 2009-05-10 22:05:01.000000000 +0200 ++++ linux-2.6.29-rc3.owrt.om/sound/soc/codecs/wm8753.h 2009-05-10 22:28:00.000000000 +0200 +@@ -77,12 +77,6 @@ + #define WM8753_BIASCTL 0x3d + #define WM8753_ADCTL2 0x3f + +-struct wm8753_setup_data { +- int spi; +- int i2c_bus; +- unsigned short i2c_address; +-}; +- + #define WM8753_PLL1 0 + #define WM8753_PLL2 1 + +diff -ruN --exclude='*.orig' --exclude='*.rej' linux-2.6.29-rc3.owrt/sound/soc/s3c24xx/jive_wm8750.c linux-2.6.29-rc3.owrt.om/sound/soc/s3c24xx/jive_wm8750.c +--- linux-2.6.29-rc3.owrt/sound/soc/s3c24xx/jive_wm8750.c 1970-01-01 01:00:00.000000000 +0100 ++++ linux-2.6.29-rc3.owrt.om/sound/soc/s3c24xx/jive_wm8750.c 2009-05-10 22:28:00.000000000 +0200 +@@ -0,0 +1,216 @@ ++/* sound/soc/s3c24xx/jive_wm8750.c ++ * ++ * Copyright 2007,2008 Simtec Electronics ++ * ++ * Based on sound/soc/pxa/spitz.c ++ * Copyright 2005 Wolfson Microelectronics PLC. ++ * Copyright 2005 Openedhand Ltd. ++ * ++ * 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/moduleparam.h> ++#include <linux/timer.h> ++#include <linux/interrupt.h> ++#include <linux/platform_device.h> ++#include <linux/clk.h> ++ ++#include <sound/core.h> ++#include <sound/pcm.h> ++#include <sound/soc.h> ++#include <sound/soc-dapm.h> ++ ++#include <asm/mach-types.h> ++ ++#include "s3c24xx-pcm.h" ++#include "s3c2412-i2s.h" ++ ++#include "../codecs/wm8750.h" ++ ++static const struct snd_soc_dapm_route audio_map[] = { ++ { "Headphone Jack", NULL, "LOUT1" }, ++ { "Headphone Jack", NULL, "ROUT1" }, ++ { "Internal Speaker", NULL, "LOUT2" }, ++ { "Internal Speaker", NULL, "ROUT2" }, ++ { "LINPUT1", NULL, "Line Input" }, ++ { "RINPUT1", NULL, "Line Input" }, ++}; ++ ++static const struct snd_soc_dapm_widget wm8750_dapm_widgets[] = { ++ SND_SOC_DAPM_HP("Headphone Jack", NULL), ++ SND_SOC_DAPM_SPK("Internal Speaker", NULL), ++ SND_SOC_DAPM_LINE("Line In", NULL), ++}; ++ ++static int jive_startup(struct snd_pcm_substream *substream) ++{ ++ struct snd_soc_pcm_runtime *rtd = substream->private_data; ++ struct snd_soc_codec *codec = rtd->socdev->codec; ++ ++ snd_soc_dapm_enable_pin(codec, "Headphone Jack"); ++ snd_soc_dapm_enable_pin(codec, "Internal Speaker"); ++ snd_soc_dapm_enable_pin(codec, "Line In"); ++ ++ snd_soc_dapm_sync(codec); ++ ++ return 0; ++} ++ ++static int jive_hw_params(struct snd_pcm_substream *substream, ++ struct snd_pcm_hw_params *params) ++{ ++ struct snd_soc_pcm_runtime *rtd = substream->private_data; ++ struct snd_soc_dai *codec_dai = rtd->dai->codec_dai; ++ struct snd_soc_dai *cpu_dai = rtd->dai->cpu_dai; ++ struct s3c_i2sv2_rate_calc div; ++ unsigned int clk = 0; ++ int ret = 0; ++ ++ switch (params_rate(params)) { ++ case 8000: ++ case 16000: ++ case 48000: ++ case 96000: ++ clk = 12288000; ++ break; ++ case 11025: ++ case 22050: ++ case 44100: ++ clk = 11289600; ++ break; ++ } ++ ++ s3c_i2sv2_calc_rate(&div, NULL, params_rate(params), ++ s3c2412_get_iisclk()); ++ ++ /* set codec DAI configuration */ ++ ret = snd_soc_dai_set_fmt(codec_dai, SND_SOC_DAIFMT_I2S | ++ SND_SOC_DAIFMT_NB_NF | ++ SND_SOC_DAIFMT_CBS_CFS); ++ if (ret < 0) ++ return ret; ++ ++ /* set cpu DAI configuration */ ++ ret = snd_soc_dai_set_fmt(cpu_dai, SND_SOC_DAIFMT_I2S | ++ SND_SOC_DAIFMT_NB_NF | ++ SND_SOC_DAIFMT_CBS_CFS); ++ if (ret < 0) ++ return ret; ++ ++ /* set the codec system clock for DAC and ADC */ ++ ret = snd_soc_dai_set_sysclk(codec_dai, WM8750_SYSCLK, clk, ++ SND_SOC_CLOCK_IN); ++ if (ret < 0) ++ return ret; ++ ++ ret = snd_soc_dai_set_clkdiv(cpu_dai, S3C2412_DIV_RCLK, div.fs_div); ++ if (ret < 0) ++ return ret; ++ ++ ret = snd_soc_dai_set_clkdiv(cpu_dai, S3C2412_DIV_PRESCALER, ++ div.clk_div - 1); ++ if (ret < 0) ++ return ret; ++ ++ return 0; ++} ++ ++static struct snd_soc_ops jive_ops = { ++ .startup = jive_startup, ++ .hw_params = jive_hw_params, ++}; ++ ++static int jive_wm8750_init(struct snd_soc_codec *codec) ++{ ++ int err; ++ ++ /* These endpoints are not being used. */ ++ snd_soc_dapm_disable_pin(codec, "LINPUT2"); ++ snd_soc_dapm_disable_pin(codec, "RINPUT2"); ++ snd_soc_dapm_disable_pin(codec, "LINPUT3"); ++ snd_soc_dapm_disable_pin(codec, "RINPUT3"); ++ snd_soc_dapm_disable_pin(codec, "OUT3"); ++ snd_soc_dapm_disable_pin(codec, "MONO"); ++ ++ /* Add jive specific widgets */ ++ err = snd_soc_dapm_new_controls(codec, wm8750_dapm_widgets, ++ ARRAY_SIZE(wm8750_dapm_widgets)); ++ if (err) { ++ printk(KERN_ERR "%s: failed to add widgets (%d)\n", ++ __func__, err); ++ return err; ++ } ++ ++ snd_soc_dapm_add_routes(codec, audio_map, ARRAY_SIZE(audio_map)); ++ snd_soc_dapm_sync(codec); ++ ++ return 0; ++} ++ ++static struct snd_soc_dai_link jive_dai = { ++ .name = "wm8750", ++ .stream_name = "WM8750", ++ .cpu_dai = &s3c2412_i2s_dai, ++ .codec_dai = &wm8750_dai, ++ .init = jive_wm8750_init, ++ .ops = &jive_ops, ++}; ++ ++/* jive audio machine driver */ ++static struct snd_soc_machine snd_soc_machine_jive = { ++ .name = "Jive", ++ .dai_link = &jive_dai, ++ .num_links = 1, ++}; ++ ++/* jive audio private data */ ++static struct wm8750_setup_data jive_wm8750_setup = { ++}; ++ ++/* jive audio subsystem */ ++static struct snd_soc_device jive_snd_devdata = { ++ .machine = &snd_soc_machine_jive, ++ .platform = &s3c24xx_soc_platform, ++ .codec_dev = &soc_codec_dev_wm8750_spi, ++ .codec_data = &jive_wm8750_setup, ++}; ++ ++static struct platform_device *jive_snd_device; ++ ++static int __init jive_init(void) ++{ ++ int ret; ++ ++ if (!machine_is_jive()) ++ return 0; ++ ++ printk("JIVE WM8750 Audio support\n"); ++ ++ jive_snd_device = platform_device_alloc("soc-audio", -1); ++ if (!jive_snd_device) ++ return -ENOMEM; ++ ++ platform_set_drvdata(jive_snd_device, &jive_snd_devdata); ++ jive_snd_devdata.dev = &jive_snd_device->dev; ++ ret = platform_device_add(jive_snd_device); ++ ++ if (ret) ++ platform_device_put(jive_snd_device); ++ ++ return ret; ++} ++ ++static void __exit jive_exit(void) ++{ ++ platform_device_unregister(jive_snd_device); ++} ++ ++module_init(jive_init); ++module_exit(jive_exit); ++ ++MODULE_AUTHOR("Ben Dooks <ben@simtec.co.uk>"); ++MODULE_DESCRIPTION("ALSA SoC Jive Audio support"); ++MODULE_LICENSE("GPL"); +diff -ruN --exclude='*.orig' --exclude='*.rej' linux-2.6.29-rc3.owrt/sound/soc/s3c24xx/Kconfig linux-2.6.29-rc3.owrt.om/sound/soc/s3c24xx/Kconfig +--- linux-2.6.29-rc3.owrt/sound/soc/s3c24xx/Kconfig 2009-05-10 22:05:01.000000000 +0200 ++++ linux-2.6.29-rc3.owrt.om/sound/soc/s3c24xx/Kconfig 2009-05-10 22:28:00.000000000 +0200 +@@ -1,6 +1,6 @@ + config SND_S3C24XX_SOC + tristate "SoC Audio for the Samsung S3C24XX chips" +- depends on ARCH_S3C2410 ++ depends on ARCH_S3C2410 || ARCH_S3C64XX + help + Say Y or M if you want to add support for codecs attached to + the S3C24XX AC97, I2S or SSP interface. You will also need +@@ -9,8 +9,16 @@ + config SND_S3C24XX_SOC_I2S + tristate + ++config SND_S3C_I2SV2_SOC ++ tristate ++ + config SND_S3C2412_SOC_I2S + tristate ++ select SND_S3C_I2SV2_SOC ++ ++config SND_S3C64XX_SOC_I2S ++ tristate ++ select SND_S3C_I2SV2_SOC + + config SND_S3C2443_SOC_AC97 + tristate +@@ -26,6 +34,33 @@ + Say Y if you want to add support for SoC audio on smdk2440 + with the WM8753. + ++config SND_S3C24XX_SOC_JIVE_WM8750 ++ tristate "SoC I2S Audio support for Jive" ++ depends on SND_S3C24XX_SOC && MACH_JIVE ++ select SND_SOC_WM8750 ++ select SND_SOC_WM8750_SPI ++ select SND_S3C2412_SOC_I2S ++ help ++ Sat Y if you want to add support for SoC audio on the Jive. ++ ++config SND_S3C24XX_SOC_NEO1973_GTA02_WM8753 ++ tristate "SoC I2S Audio support for NEO1973 GTA02 - WM8753" ++ depends on SND_S3C24XX_SOC && MACH_NEO1973_GTA02 ++ select SND_S3C24XX_SOC_I2S ++ select SND_SOC_WM8753 ++ help ++ Say Y if you want to add support for SoC audio on neo1973 gta02 ++ with the WM8753 codec ++ ++config SND_S3C24XX_SOC_OM_3D7K_WM8753 ++ tristate "SoC I2S Audio support for OM 3D7K - WM8753" ++ depends on SND_S3C24XX_SOC && MACH_OM_3D7K ++ select SND_S3C64XX_SOC_I2S ++ select SND_SOC_WM8753 ++ help ++ Say Y if you want support for SoC audio on Openmoko 3D7K ++ with the WM8753 codec. ++ + config SND_S3C24XX_SOC_SMDK2443_WM9710 + tristate "SoC AC97 Audio support for SMDK2443 - WM9710" + depends on SND_S3C24XX_SOC && MACH_SMDK2443 +@@ -49,3 +84,11 @@ + depends on SND_S3C24XX_SOC + select SND_S3C24XX_SOC_I2S + select SND_SOC_UDA134X ++ ++config SND_S3C64XX_SOC_SMDK6410_WM8731 ++ tristate "SoC I2S Audio support for WM8731 added to an SMDK6410" ++ depends on SND_S3C24XX_SOC ++ select SND_S3C64XX_SOC_I2S ++ select SND_SOC_WM8731 ++ help ++ Support for an WM8731 add-on board on I2S channel 0 on an SMDK6410 +diff -ruN --exclude='*.orig' --exclude='*.rej' linux-2.6.29-rc3.owrt/sound/soc/s3c24xx/Makefile linux-2.6.29-rc3.owrt.om/sound/soc/s3c24xx/Makefile +--- linux-2.6.29-rc3.owrt/sound/soc/s3c24xx/Makefile 2009-05-10 22:05:01.000000000 +0200 ++++ linux-2.6.29-rc3.owrt.om/sound/soc/s3c24xx/Makefile 2009-05-10 22:28:00.000000000 +0200 +@@ -2,20 +2,32 @@ + snd-soc-s3c24xx-objs := s3c24xx-pcm.o + snd-soc-s3c24xx-i2s-objs := s3c24xx-i2s.o + snd-soc-s3c2412-i2s-objs := s3c2412-i2s.o ++snd-soc-s3c64xx-i2s-objs := s3c64xx-i2s.o + snd-soc-s3c2443-ac97-objs := s3c2443-ac97.o ++snd-soc-s3c-i2s-v2-objs := s3c-i2s-v2.o + + obj-$(CONFIG_SND_S3C24XX_SOC) += snd-soc-s3c24xx.o + obj-$(CONFIG_SND_S3C24XX_SOC_I2S) += snd-soc-s3c24xx-i2s.o + obj-$(CONFIG_SND_S3C2443_SOC_AC97) += snd-soc-s3c2443-ac97.o + obj-$(CONFIG_SND_S3C2412_SOC_I2S) += snd-soc-s3c2412-i2s.o ++obj-$(CONFIG_SND_S3C64XX_SOC_I2S) += snd-soc-s3c64xx-i2s.o ++obj-$(CONFIG_SND_S3C_I2SV2_SOC) += snd-soc-s3c-i2s-v2.o + + # S3C24XX Machine Support ++snd-soc-jive-wm8750-objs := jive_wm8750.o + snd-soc-neo1973-wm8753-objs := neo1973_wm8753.o + snd-soc-smdk2443-wm9710-objs := smdk2443_wm9710.o + snd-soc-ln2440sbc-alc650-objs := ln2440sbc_alc650.o + snd-soc-s3c24xx-uda134x-objs := s3c24xx_uda134x.o ++snd-soc-neo1973-gta02-wm8753-objs := neo1973_gta02_wm8753.o ++snd-soc-om-3d7k-wm8753-objs := om_3d7k_wm8753.o ++snd-soc-smdk6410-wm8731-objs := smdk6410-wm8731.o + ++obj-$(CONFIG_SND_S3C24XX_SOC_JIVE_WM8750) += snd-soc-jive-wm8750.o + obj-$(CONFIG_SND_S3C24XX_SOC_NEO1973_WM8753) += snd-soc-neo1973-wm8753.o + obj-$(CONFIG_SND_S3C24XX_SOC_SMDK2443_WM9710) += snd-soc-smdk2443-wm9710.o + obj-$(CONFIG_SND_S3C24XX_SOC_LN2440SBC_ALC650) += snd-soc-ln2440sbc-alc650.o + obj-$(CONFIG_SND_S3C24XX_SOC_S3C24XX_UDA134X) += snd-soc-s3c24xx-uda134x.o ++obj-$(CONFIG_SND_S3C24XX_SOC_NEO1973_GTA02_WM8753) += snd-soc-neo1973-gta02-wm8753.o ++obj-$(CONFIG_SND_S3C24XX_SOC_OM_3D7K_WM8753) += snd-soc-om-3d7k-wm8753.o ++obj-$(CONFIG_SND_S3C64XX_SOC_SMDK6410_WM8731) += snd-soc-smdk6410-wm8731.o +diff -ruN --exclude='*.orig' --exclude='*.rej' linux-2.6.29-rc3.owrt/sound/soc/s3c24xx/neo1973_gta02_wm8753.c linux-2.6.29-rc3.owrt.om/sound/soc/s3c24xx/neo1973_gta02_wm8753.c +--- linux-2.6.29-rc3.owrt/sound/soc/s3c24xx/neo1973_gta02_wm8753.c 1970-01-01 01:00:00.000000000 +0100 ++++ linux-2.6.29-rc3.owrt.om/sound/soc/s3c24xx/neo1973_gta02_wm8753.c 2009-05-10 22:28:00.000000000 +0200 +@@ -0,0 +1,481 @@ ++/* ++ * neo1973_gta02_wm8753.c -- SoC audio for Neo1973 ++ * ++ * Copyright 2007 Openmoko Inc ++ * Author: Graeme Gregory <graeme@openmoko.org> ++ * Copyright 2007 Wolfson Microelectronics PLC. ++ * Author: Graeme Gregory <linux@wolfsonmicro.com> ++ * Copyright 2009 Wolfson Microelectronics ++ * ++ * 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. ++ */ ++ ++#include <linux/module.h> ++#include <linux/moduleparam.h> ++#include <linux/timer.h> ++#include <linux/interrupt.h> ++#include <linux/platform_device.h> ++#include <sound/core.h> ++#include <sound/pcm.h> ++#include <sound/soc.h> ++#include <sound/soc-dapm.h> ++ ++#include <asm/mach-types.h> ++ ++#include <plat/regs-iis.h> ++ ++#include <mach/regs-clock.h> ++#include <mach/regs-gpio.h> ++#include <mach/hardware.h> ++#include <asm/io.h> ++#include <mach/regs-gpioj.h> ++#include <mach/gta02.h> ++#include "../codecs/wm8753.h" ++#include "s3c24xx-pcm.h" ++#include "s3c24xx-i2s.h" ++ ++static struct snd_soc_card neo1973_gta02; ++ ++static int neo1973_gta02_hifi_hw_params(struct snd_pcm_substream *substream, ++ struct snd_pcm_hw_params *params) ++{ ++ struct snd_soc_pcm_runtime *rtd = substream->private_data; ++ struct snd_soc_dai *codec_dai = rtd->dai->codec_dai; ++ struct snd_soc_dai *cpu_dai = rtd->dai->cpu_dai; ++ unsigned int pll_out = 0, bclk = 0; ++ int ret = 0; ++ unsigned long iis_clkrate; ++ ++ iis_clkrate = s3c24xx_i2s_get_clockrate(); ++ ++ switch (params_rate(params)) { ++ case 8000: ++ case 16000: ++ pll_out = 12288000; ++ break; ++ case 48000: ++ bclk = WM8753_BCLK_DIV_4; ++ pll_out = 12288000; ++ break; ++ case 96000: ++ bclk = WM8753_BCLK_DIV_2; ++ pll_out = 12288000; ++ break; ++ case 11025: ++ bclk = WM8753_BCLK_DIV_16; ++ pll_out = 11289600; ++ break; ++ case 22050: ++ bclk = WM8753_BCLK_DIV_8; ++ pll_out = 11289600; ++ break; ++ case 44100: ++ bclk = WM8753_BCLK_DIV_4; ++ pll_out = 11289600; ++ break; ++ case 88200: ++ bclk = WM8753_BCLK_DIV_2; ++ pll_out = 11289600; ++ break; ++ } ++ ++ /* set codec DAI configuration */ ++ ret = snd_soc_dai_set_fmt(codec_dai, ++ SND_SOC_DAIFMT_I2S | SND_SOC_DAIFMT_NB_NF | ++ SND_SOC_DAIFMT_CBM_CFM); ++ if (ret < 0) ++ return ret; ++ ++ /* set cpu DAI configuration */ ++ ret = snd_soc_dai_set_fmt(cpu_dai, ++ SND_SOC_DAIFMT_I2S | SND_SOC_DAIFMT_NB_NF | ++ SND_SOC_DAIFMT_CBM_CFM); ++ if (ret < 0) ++ return ret; ++ ++ /* set the codec system clock for DAC and ADC */ ++ ret = snd_soc_dai_set_sysclk(codec_dai, WM8753_MCLK, pll_out, ++ SND_SOC_CLOCK_IN); ++ if (ret < 0) ++ return ret; ++ ++ /* set MCLK division for sample rate */ ++ ret = snd_soc_dai_set_clkdiv(cpu_dai, S3C24XX_DIV_MCLK, ++ S3C2410_IISMOD_32FS); ++ if (ret < 0) ++ return ret; ++ ++ /* set codec BCLK division for sample rate */ ++ ret = snd_soc_dai_set_clkdiv(codec_dai, ++ WM8753_BCLKDIV, bclk); ++ if (ret < 0) ++ return ret; ++ ++ /* set prescaler division for sample rate */ ++ ret = snd_soc_dai_set_clkdiv(cpu_dai, S3C24XX_DIV_PRESCALER, ++ S3C24XX_PRESCALE(4, 4)); ++ if (ret < 0) ++ return ret; ++ ++ /* codec PLL input is PCLK/4 */ ++ ret = snd_soc_dai_set_pll(codec_dai, WM8753_PLL1, ++ iis_clkrate / 4, pll_out); ++ if (ret < 0) ++ return ret; ++ ++ return 0; ++} ++ ++static int neo1973_gta02_hifi_hw_free(struct snd_pcm_substream *substream) ++{ ++ struct snd_soc_pcm_runtime *rtd = substream->private_data; ++ struct snd_soc_dai *codec_dai = rtd->dai->codec_dai; ++ ++ /* disable the PLL */ ++ return snd_soc_dai_set_pll(codec_dai, WM8753_PLL1, 0, 0); ++} ++ ++/* ++ * Neo1973 WM8753 HiFi DAI opserations. ++ */ ++static struct snd_soc_ops neo1973_gta02_hifi_ops = { ++ .hw_params = neo1973_gta02_hifi_hw_params, ++ .hw_free = neo1973_gta02_hifi_hw_free, ++}; ++ ++static int neo1973_gta02_voice_hw_params( ++ struct snd_pcm_substream *substream, ++ struct snd_pcm_hw_params *params) ++{ ++ struct snd_soc_pcm_runtime *rtd = substream->private_data; ++ struct snd_soc_dai *codec_dai = rtd->dai->codec_dai; ++ unsigned int pcmdiv = 0; ++ int ret = 0; ++ unsigned long iis_clkrate; ++ ++ iis_clkrate = s3c24xx_i2s_get_clockrate(); ++ ++ if (params_rate(params) != 8000) ++ return -EINVAL; ++ if (params_channels(params) != 1) ++ return -EINVAL; ++ ++ pcmdiv = WM8753_PCM_DIV_6; /* 2.048 MHz */ ++ ++ /* todo: gg check mode (DSP_B) against CSR datasheet */ ++ /* set codec DAI configuration */ ++ ret = snd_soc_dai_set_fmt(codec_dai, SND_SOC_DAIFMT_DSP_B | ++ SND_SOC_DAIFMT_NB_NF | SND_SOC_DAIFMT_CBS_CFS); ++ if (ret < 0) ++ return ret; ++ ++ /* set the codec system clock for DAC and ADC */ ++ ret = snd_soc_dai_set_sysclk(codec_dai, WM8753_PCMCLK, ++ 12288000, SND_SOC_CLOCK_IN); ++ if (ret < 0) ++ return ret; ++ ++ /* set codec PCM division for sample rate */ ++ ret = snd_soc_dai_set_clkdiv(codec_dai, WM8753_PCMDIV, ++ pcmdiv); ++ if (ret < 0) ++ return ret; ++ ++ /* configue and enable PLL for 12.288MHz output */ ++ ret = snd_soc_dai_set_pll(codec_dai, WM8753_PLL2, ++ iis_clkrate / 4, 12288000); ++ if (ret < 0) ++ return ret; ++ ++ return 0; ++} ++ ++static int neo1973_gta02_voice_hw_free(struct snd_pcm_substream *substream) ++{ ++ struct snd_soc_pcm_runtime *rtd = substream->private_data; ++ struct snd_soc_dai *codec_dai = rtd->dai->codec_dai; ++ ++ /* disable the PLL */ ++ return snd_soc_dai_set_pll(codec_dai, WM8753_PLL2, 0, 0); ++} ++ ++static struct snd_soc_ops neo1973_gta02_voice_ops = { ++ .hw_params = neo1973_gta02_voice_hw_params, ++ .hw_free = neo1973_gta02_voice_hw_free, ++}; ++ ++#define LM4853_AMP 1 ++#define LM4853_SPK 2 ++ ++static u8 lm4853_state; ++ ++/* This has no effect, it exists only to maintain compatibility with ++ * existing ALSA state files. ++ */ ++static int lm4853_set_state(struct snd_kcontrol *kcontrol, ++ struct snd_ctl_elem_value *ucontrol) ++{ ++ int val = ucontrol->value.integer.value[0]; ++ ++ if (val) ++ lm4853_state |= LM4853_AMP; ++ else ++ lm4853_state &= ~LM4853_AMP; ++ ++ return 0; ++} ++ ++static int lm4853_get_state(struct snd_kcontrol *kcontrol, ++ struct snd_ctl_elem_value *ucontrol) ++{ ++ ucontrol->value.integer.value[0] = lm4853_state & LM4853_AMP; ++ ++ return 0; ++} ++ ++static int lm4853_set_spk(struct snd_kcontrol *kcontrol, ++ struct snd_ctl_elem_value *ucontrol) ++{ ++ int val = ucontrol->value.integer.value[0]; ++ ++ if (val) { ++ lm4853_state |= LM4853_SPK; ++ s3c2410_gpio_setpin(GTA02_GPIO_HP_IN, 0); ++ } else { ++ lm4853_state &= ~LM4853_SPK; ++ s3c2410_gpio_setpin(GTA02_GPIO_HP_IN, 1); ++ } ++ ++ return 0; ++} ++ ++static int lm4853_get_spk(struct snd_kcontrol *kcontrol, ++ struct snd_ctl_elem_value *ucontrol) ++{ ++ ucontrol->value.integer.value[0] = (lm4853_state & LM4853_SPK) >> 1; ++ ++ return 0; ++} ++ ++static int lm4853_event(struct snd_soc_dapm_widget *w, ++ struct snd_kcontrol *k, ++ int event) ++{ ++ if (SND_SOC_DAPM_EVENT_ON(event)) ++ s3c2410_gpio_setpin(GTA02_GPIO_AMP_SHUT, 0); ++ ++ if (SND_SOC_DAPM_EVENT_OFF(event)) ++ s3c2410_gpio_setpin(GTA02_GPIO_AMP_SHUT, 1); ++ ++ return 0; ++} ++ ++static const struct snd_soc_dapm_widget wm8753_dapm_widgets[] = { ++ SND_SOC_DAPM_SPK("Stereo Out", lm4853_event), ++ SND_SOC_DAPM_LINE("GSM Line Out", NULL), ++ SND_SOC_DAPM_LINE("GSM Line In", NULL), ++ SND_SOC_DAPM_MIC("Headset Mic", NULL), ++ SND_SOC_DAPM_MIC("Handset Mic", NULL), ++ SND_SOC_DAPM_SPK("Handset Spk", NULL), ++}; ++ ++ ++/* example machine audio_mapnections */ ++static const struct snd_soc_dapm_route audio_map[] = { ++ ++ /* Connections to the lm4853 amp */ ++ {"Stereo Out", NULL, "LOUT1"}, ++ {"Stereo Out", NULL, "ROUT1"}, ++ ++ /* Connections to the GSM Module */ ++ {"GSM Line Out", NULL, "MONO1"}, ++ {"GSM Line Out", NULL, "MONO2"}, ++ {"RXP", NULL, "GSM Line In"}, ++ {"RXN", NULL, "GSM Line In"}, ++ ++ /* Connections to Headset */ ++ {"MIC1", NULL, "Mic Bias"}, ++ {"Mic Bias", NULL, "Headset Mic"}, ++ ++ /* Call Mic */ ++ {"MIC2", NULL, "Mic Bias"}, ++ {"MIC2N", NULL, "Mic Bias"}, ++ {"Mic Bias", NULL, "Handset Mic"}, ++ ++ /* Call Speaker */ ++ {"Handset Spk", NULL, "LOUT2"}, ++ {"Handset Spk", NULL, "ROUT2"}, ++ ++ /* Connect the ALC pins */ ++ {"ACIN", NULL, "ACOP"}, ++}; ++ ++static const struct snd_kcontrol_new wm8753_neo1973_gta02_controls[] = { ++ SOC_DAPM_PIN_SWITCH("Stereo Out"), ++ SOC_DAPM_PIN_SWITCH("GSM Line Out"), ++ SOC_DAPM_PIN_SWITCH("GSM Line In"), ++ SOC_DAPM_PIN_SWITCH("Headset Mic"), ++ SOC_DAPM_PIN_SWITCH("Handset Mic"), ++ SOC_DAPM_PIN_SWITCH("Handset Spk"), ++ ++ /* This has no effect, it exists only to maintain compatibility with ++ * existing ALSA state files. ++ */ ++ SOC_SINGLE_EXT("Amp State Switch", 6, 0, 1, 0, ++ lm4853_get_state, ++ lm4853_set_state), ++ SOC_SINGLE_EXT("Amp Spk Switch", 7, 0, 1, 0, ++ lm4853_get_spk, ++ lm4853_set_spk), ++}; ++ ++/* ++ * This is an example machine initialisation for a wm8753 connected to a ++ * neo1973 GTA02. ++ */ ++static int neo1973_gta02_wm8753_init(struct snd_soc_codec *codec) ++{ ++ int i, err; ++ ++ /* set up NC codec pins */ ++ snd_soc_dapm_nc_pin(codec, "OUT3"); ++ snd_soc_dapm_nc_pin(codec, "OUT4"); ++ snd_soc_dapm_nc_pin(codec, "LINE1"); ++ snd_soc_dapm_nc_pin(codec, "LINE2"); ++ ++ /* Add neo1973 gta02 specific widgets */ ++ snd_soc_dapm_new_controls(codec, wm8753_dapm_widgets, ++ ARRAY_SIZE(wm8753_dapm_widgets)); ++ ++ /* add neo1973 gta02 specific controls */ ++ for (i = 0; i < ARRAY_SIZE(wm8753_neo1973_gta02_controls); i++) { ++ err = snd_ctl_add(codec->card, ++ snd_soc_cnew(&wm8753_neo1973_gta02_controls[i], ++ codec, NULL)); ++ if (err < 0) ++ return err; ++ } ++ ++ /* set up neo1973 gta02 specific audio path audio_map */ ++ snd_soc_dapm_add_routes(codec, audio_map, ARRAY_SIZE(audio_map)); ++ ++ /* set endpoints to default off mode */ ++ snd_soc_dapm_disable_pin(codec, "Stereo Out"); ++ snd_soc_dapm_disable_pin(codec, "GSM Line Out"); ++ snd_soc_dapm_disable_pin(codec, "GSM Line In"); ++ snd_soc_dapm_disable_pin(codec, "Headset Mic"); ++ snd_soc_dapm_disable_pin(codec, "Handset Mic"); ++ snd_soc_dapm_disable_pin(codec, "Handset Spk"); ++ ++ snd_soc_dapm_sync(codec); ++ ++ return 0; ++} ++ ++/* ++ * BT Codec DAI ++ */ ++static struct snd_soc_dai bt_dai = { ++ .name = "Bluetooth", ++ .id = 0, ++ .playback = { ++ .channels_min = 1, ++ .channels_max = 1, ++ .rates = SNDRV_PCM_RATE_8000, ++ .formats = SNDRV_PCM_FMTBIT_S16_LE,}, ++ .capture = { ++ .channels_min = 1, ++ .channels_max = 1, ++ .rates = SNDRV_PCM_RATE_8000, ++ .formats = SNDRV_PCM_FMTBIT_S16_LE,}, ++}; ++ ++static struct snd_soc_dai_link neo1973_gta02_dai[] = { ++{ /* Hifi Playback - for similatious use with voice below */ ++ .name = "WM8753", ++ .stream_name = "WM8753 HiFi", ++ .cpu_dai = &s3c24xx_i2s_dai, ++ .codec_dai = &wm8753_dai[WM8753_DAI_HIFI], ++ .init = neo1973_gta02_wm8753_init, ++ .ops = &neo1973_gta02_hifi_ops, ++}, ++{ /* Voice via BT */ ++ .name = "Bluetooth", ++ .stream_name = "Voice", ++ .cpu_dai = &bt_dai, ++ .codec_dai = &wm8753_dai[WM8753_DAI_VOICE], ++ .ops = &neo1973_gta02_voice_ops, ++}, ++}; ++ ++static struct snd_soc_card neo1973_gta02 = { ++ .name = "neo1973-gta02", ++ .platform = &s3c24xx_soc_platform, ++ .dai_link = neo1973_gta02_dai, ++ .num_links = ARRAY_SIZE(neo1973_gta02_dai), ++}; ++ ++static struct snd_soc_device neo1973_gta02_snd_devdata = { ++ .card = &neo1973_gta02, ++ .codec_dev = &soc_codec_dev_wm8753, ++}; ++ ++static struct platform_device *neo1973_gta02_snd_device; ++ ++static int __init neo1973_gta02_init(void) ++{ ++ int ret; ++ ++ if (!machine_is_neo1973_gta02()) { ++ printk(KERN_INFO ++ "Only GTA02 is supported by this ASoC driver\n"); ++ return -ENODEV; ++ } ++ ++ /* register bluetooth DAI here */ ++ ret = snd_soc_register_dai(&bt_dai); ++ if (ret) ++ return ret; ++ ++ neo1973_gta02_snd_device = platform_device_alloc("soc-audio", -1); ++ if (!neo1973_gta02_snd_device) ++ return -ENOMEM; ++ ++ platform_set_drvdata(neo1973_gta02_snd_device, ++ &neo1973_gta02_snd_devdata); ++ neo1973_gta02_snd_devdata.dev = &neo1973_gta02_snd_device->dev; ++ ret = platform_device_add(neo1973_gta02_snd_device); ++ ++ if (ret) { ++ platform_device_put(neo1973_gta02_snd_device); ++ return ret; ++ } ++ ++ /* Initialise GPIOs used by amp */ ++ s3c2410_gpio_cfgpin(GTA02_GPIO_HP_IN, S3C2410_GPIO_OUTPUT); ++ s3c2410_gpio_cfgpin(GTA02_GPIO_AMP_SHUT, S3C2410_GPIO_OUTPUT); ++ ++ /* Amp off by default */ ++ s3c2410_gpio_setpin(GTA02_GPIO_AMP_SHUT, 1); ++ ++ /* Speaker off by default */ ++ s3c2410_gpio_setpin(GTA02_GPIO_HP_IN, 1); ++ ++ return ret; ++} ++module_init(neo1973_gta02_init); ++ ++static void __exit neo1973_gta02_exit(void) ++{ ++ snd_soc_unregister_dai(&bt_dai); ++ platform_device_unregister(neo1973_gta02_snd_device); ++} ++module_exit(neo1973_gta02_exit); ++ ++/* Module information */ ++MODULE_AUTHOR("Graeme Gregory, graeme@openmoko.org"); ++MODULE_DESCRIPTION("ALSA SoC WM8753 Neo1973 GTA02"); ++MODULE_LICENSE("GPL"); +diff -ruN --exclude='*.orig' --exclude='*.rej' linux-2.6.29-rc3.owrt/sound/soc/s3c24xx/neo1973_wm8753.c linux-2.6.29-rc3.owrt.om/sound/soc/s3c24xx/neo1973_wm8753.c +--- linux-2.6.29-rc3.owrt/sound/soc/s3c24xx/neo1973_wm8753.c 2009-05-10 22:05:01.000000000 +0200 ++++ linux-2.6.29-rc3.owrt.om/sound/soc/s3c24xx/neo1973_wm8753.c 2009-05-10 22:28:00.000000000 +0200 +@@ -29,11 +29,11 @@ + #include <mach/regs-clock.h> + #include <mach/regs-gpio.h> + #include <mach/hardware.h> +-#include <mach/audio.h> ++#include <plat/audio.h> + #include <linux/io.h> + #include <mach/spi-gpio.h> + +-#include <asm/plat-s3c24xx/regs-iis.h> ++#include <plat/regs-iis.h> + + #include "../codecs/wm8753.h" + #include "lm4857.h" +@@ -585,15 +585,9 @@ + .num_links = ARRAY_SIZE(neo1973_dai), + }; + +-static struct wm8753_setup_data neo1973_wm8753_setup = { +- .i2c_bus = 0, +- .i2c_address = 0x1a, +-}; +- + static struct snd_soc_device neo1973_snd_devdata = { + .card = &neo1973, + .codec_dev = &soc_codec_dev_wm8753, +- .codec_data = &neo1973_wm8753_setup, + }; + + static int lm4857_i2c_probe(struct i2c_client *client, +@@ -652,13 +646,13 @@ + } + + static const struct i2c_device_id lm4857_i2c_id[] = { +- { "neo1973_lm4857", 0 }, ++ { "lm4857", 0 }, + { } + }; + + static struct i2c_driver lm4857_i2c_driver = { + .driver = { +- .name = "LM4857 I2C Amp", ++ .name = "lm4857", + .owner = THIS_MODULE, + }, + .suspend = lm4857_suspend, +@@ -675,7 +669,7 @@ + { + int ret; + +- DBG("Entered %s\n", __func__); ++ printk(KERN_DEBUG "Entered %s\n", __func__); + + if (!machine_is_neo1973_gta01()) { + printk(KERN_INFO +@@ -683,6 +677,11 @@ + return -ENODEV; + } + ++ /* register bluetooth DAI here */ ++ ret = snd_soc_register_dai(&bt_dai); ++ if (ret) ++ return ret; ++ + neo1973_snd_device = platform_device_alloc("soc-audio", -1); + if (!neo1973_snd_device) + return -ENOMEM; +@@ -708,6 +707,7 @@ + { + DBG("Entered %s\n", __func__); + ++ snd_soc_unregister_dai(&bt_dai); + i2c_del_driver(&lm4857_i2c_driver); + platform_device_unregister(neo1973_snd_device); + } +diff -ruN --exclude='*.orig' --exclude='*.rej' linux-2.6.29-rc3.owrt/sound/soc/s3c24xx/om_3d7k_wm8753.c linux-2.6.29-rc3.owrt.om/sound/soc/s3c24xx/om_3d7k_wm8753.c +--- linux-2.6.29-rc3.owrt/sound/soc/s3c24xx/om_3d7k_wm8753.c 1970-01-01 01:00:00.000000000 +0100 ++++ linux-2.6.29-rc3.owrt.om/sound/soc/s3c24xx/om_3d7k_wm8753.c 2009-05-10 22:28:00.000000000 +0200 +@@ -0,0 +1,600 @@ ++/* ++ * om_3d7k_wm8753.c -- SoC audio for 3D7K ++ * ++ * Based on neo1973_gta02_wm8753 ++ * ++ * Copyright 2009 Openmoko Inc ++ * Author: Ben Dooks <ben@simtec.co.uk> ++ * Copyright 2007 Openmoko Inc ++ * Author: Graeme Gregory <graeme@openmoko.org> ++ * Copyright 2007 Wolfson Microelectronics PLC. ++ * Author: Graeme Gregory <linux@wolfsonmicro.com> ++ * ++ * 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. ++ */ ++ ++#include <linux/module.h> ++#include <linux/moduleparam.h> ++#include <linux/timer.h> ++#include <linux/interrupt.h> ++#include <linux/platform_device.h> ++#include <linux/i2c.h> ++#include <sound/core.h> ++#include <sound/pcm.h> ++#include <sound/soc.h> ++#include <sound/soc-dapm.h> ++ ++#include <asm/mach-types.h> ++#include <asm/hardware/scoop.h> ++ ++#include <plat/regs-s3c2412-iis.h> ++ ++#include "../codecs/wm8753.h" ++#include "s3c24xx-pcm.h" ++#include "s3c64xx-i2s.h" ++ ++/* define the scenarios */ ++#define NEO_AUDIO_OFF 0 ++#define NEO_GSM_CALL_AUDIO_HANDSET 1 ++#define NEO_GSM_CALL_AUDIO_HEADSET 2 ++#define NEO_GSM_CALL_AUDIO_BLUETOOTH 3 ++#define NEO_STEREO_TO_SPEAKERS 4 ++#define NEO_STEREO_TO_HEADPHONES 5 ++#define NEO_CAPTURE_HANDSET 6 ++#define NEO_CAPTURE_HEADSET 7 ++#define NEO_CAPTURE_BLUETOOTH 8 ++#define NEO_STEREO_TO_HANDSET_SPK 9 ++ ++static struct snd_soc_card om_3d7k; ++ ++static int om_3d7k_hifi_hw_params(struct snd_pcm_substream *substream, ++ struct snd_pcm_hw_params *params) ++{ ++ struct snd_soc_pcm_runtime *rtd = substream->private_data; ++ struct snd_soc_dai *codec_dai = rtd->dai->codec_dai; ++ struct snd_soc_dai *cpu_dai = rtd->dai->cpu_dai; ++ unsigned int pll_out = 0, bclk = 0; ++ int ret = 0; ++ unsigned long iis_clkrate; ++ ++ iis_clkrate = s3c64xx_i2s_get_clockrate(cpu_dai); ++ ++ switch (params_rate(params)) { ++ case 8000: ++ case 16000: ++ pll_out = 12288000; ++ break; ++ case 48000: ++ bclk = WM8753_BCLK_DIV_4; ++ pll_out = 12288000; ++ break; ++ case 96000: ++ bclk = WM8753_BCLK_DIV_2; ++ pll_out = 12288000; ++ break; ++ case 11025: ++ bclk = WM8753_BCLK_DIV_16; ++ pll_out = 11289600; ++ break; ++ case 22050: ++ bclk = WM8753_BCLK_DIV_8; ++ pll_out = 11289600; ++ break; ++ case 44100: ++ bclk = WM8753_BCLK_DIV_4; ++ pll_out = 11289600; ++ break; ++ case 88200: ++ bclk = WM8753_BCLK_DIV_2; ++ pll_out = 11289600; ++ break; ++ } ++ ++ ret = snd_soc_dai_set_sysclk(cpu_dai, S3C64XX_CLKSRC_MUX, 0, ++ SND_SOC_CLOCK_OUT); ++ if (ret < 0) ++ goto err; ++ ++ /* set codec DAI configuration */ ++ ret = snd_soc_dai_set_fmt(codec_dai, ++ SND_SOC_DAIFMT_LEFT_J | SND_SOC_DAIFMT_NB_NF | ++ SND_SOC_DAIFMT_CBM_CFM); ++ if (ret < 0) ++ goto err; ++ ++ /* set cpu DAI configuration */ ++ ret = snd_soc_dai_set_fmt(cpu_dai, ++ SND_SOC_DAIFMT_I2S | SND_SOC_DAIFMT_NB_NF | ++ SND_SOC_DAIFMT_CBM_CFM); ++ if (ret < 0) ++ goto err; ++ ++ /* set the codec system clock for DAC and ADC */ ++ ret = snd_soc_dai_set_sysclk(codec_dai, WM8753_MCLK, pll_out, ++ SND_SOC_CLOCK_IN); ++ if (ret < 0) ++ goto err; ++ ++#if 0 ++ /* do not think we need to set this if the cpu is not the bitclk ++ * master */ ++ /* set MCLK division for sample rate */ ++ ret = snd_soc_dai_set_clkdiv(cpu_dai, S3C24XX_DIV_MCLK, ++ S3C2410_IISMOD_32FS); ++ if (ret < 0) ++ return ret; ++#endif ++ ++ /* set codec BCLK division for sample rate */ ++ ret = snd_soc_dai_set_clkdiv(codec_dai, WM8753_BCLKDIV, bclk); ++ if (ret < 0) ++ goto err; ++ ++ /* set prescaler division for sample rate */ ++ ret = snd_soc_dai_set_clkdiv(cpu_dai, S3C64XX_DIV_PRESCALER, 2-1); ++ if (ret < 0) ++ goto err; ++ ++ /* codec PLL input is ACLK/2 */ ++ ret = snd_soc_dai_set_pll(codec_dai, WM8753_PLL1, ++ iis_clkrate / 2, pll_out); ++ if (ret < 0) ++ goto err; ++ ++ return 0; ++ ++err: ++ printk(KERN_ERR "%s: failed %d\n", __func__, ret); ++ return ret; ++} ++ ++static int om_3d7k_hifi_hw_free(struct snd_pcm_substream *substream) ++{ ++ struct snd_soc_pcm_runtime *rtd = substream->private_data; ++ struct snd_soc_dai *codec_dai = rtd->dai->codec_dai; ++ ++ /* disable the PLL */ ++ return snd_soc_dai_set_pll(codec_dai, WM8753_PLL1, 0, 0); ++} ++ ++/* ++ * 3D7K WM8753 HiFi DAI opserations. ++ */ ++static struct snd_soc_ops om_3d7k_hifi_ops = { ++ .hw_params = om_3d7k_hifi_hw_params, ++ .hw_free = om_3d7k_hifi_hw_free, ++}; ++ ++static int om_3d7k_voice_hw_params(struct snd_pcm_substream *substream, ++ struct snd_pcm_hw_params *params) ++{ ++ struct snd_soc_pcm_runtime *rtd = substream->private_data; ++ struct snd_soc_dai *codec_dai = rtd->dai->codec_dai; ++ unsigned int pcmdiv = 0; ++ int ret = 0; ++ unsigned long iis_clkrate; ++ ++ iis_clkrate = s3c64xx_i2s_get_clockrate(rtd->dai->cpu_dai); ++ ++ if (params_rate(params) != 8000) ++ return -EINVAL; ++ if (params_channels(params) != 1) ++ return -EINVAL; ++ ++ pcmdiv = WM8753_PCM_DIV_6; /* 2.048 MHz */ ++ ++ /* todo: gg check mode (DSP_B) against CSR datasheet */ ++ /* set codec DAI configuration */ ++ ret = snd_soc_dai_set_fmt(codec_dai, (SND_SOC_DAIFMT_DSP_B | ++ SND_SOC_DAIFMT_NB_NF | ++ SND_SOC_DAIFMT_CBS_CFS)); ++ if (ret < 0) ++ return ret; ++ ++ /* set the codec system clock for DAC and ADC */ ++ ret = snd_soc_dai_set_sysclk(codec_dai, WM8753_PCMCLK, ++ 12288000, SND_SOC_CLOCK_IN); ++ if (ret < 0) ++ return ret; ++ ++ /* set codec PCM division for sample rate */ ++ ret = snd_soc_dai_set_clkdiv(codec_dai, WM8753_PCMDIV, pcmdiv); ++ if (ret < 0) ++ return ret; ++ ++ /* configue and enable PLL for 12.288MHz output */ ++ ret = snd_soc_dai_set_pll(codec_dai, WM8753_PLL2, ++ iis_clkrate / 2, 12288000); ++ if (ret < 0) ++ return ret; ++ ++ return 0; ++} ++ ++static int om_3d7k_voice_hw_free(struct snd_pcm_substream *substream) ++{ ++ struct snd_soc_pcm_runtime *rtd = substream->private_data; ++ struct snd_soc_dai *codec_dai = rtd->dai->codec_dai; ++ ++ /* disable the PLL */ ++ return snd_soc_dai_set_pll(codec_dai, WM8753_PLL2, 0, 0); ++} ++ ++static struct snd_soc_ops om_3d7k_voice_ops = { ++ .hw_params = om_3d7k_voice_hw_params, ++ .hw_free = om_3d7k_voice_hw_free, ++}; ++ ++static int om_3d7k_set_stereo_out(struct snd_kcontrol *kcontrol, ++ struct snd_ctl_elem_value *ucontrol) ++{ ++ struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol); ++ int val = ucontrol->value.integer.value[0]; ++ ++ snd_soc_dapm_set_endpoint(codec, "Stereo Out", val); ++ snd_soc_dapm_sync(codec); ++ ++ return 0; ++} ++ ++static int om_3d7k_get_stereo_out(struct snd_kcontrol *kcontrol, ++ struct snd_ctl_elem_value *ucontrol) ++{ ++ struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol); ++ ++ ucontrol->value.integer.value[0] = ++ snd_soc_dapm_get_endpoint(codec, "Stereo Out"); ++ ++ return 0; ++} ++ ++ ++static int om_3d7k_set_gsm_out(struct snd_kcontrol *kcontrol, ++ struct snd_ctl_elem_value *ucontrol) ++{ ++ struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol); ++ int val = ucontrol->value.integer.value[0]; ++ ++ snd_soc_dapm_set_endpoint(codec, "GSM Line Out", val); ++ snd_soc_dapm_sync(codec); ++ ++ return 0; ++} ++ ++static int om_3d7k_get_gsm_out(struct snd_kcontrol *kcontrol, ++ struct snd_ctl_elem_value *ucontrol) ++{ ++ struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol); ++ ++ ucontrol->value.integer.value[0] = ++ snd_soc_dapm_get_endpoint(codec, "GSM Line Out"); ++ ++ return 0; ++} ++ ++static int om_3d7k_set_gsm_in(struct snd_kcontrol *kcontrol, ++ struct snd_ctl_elem_value *ucontrol) ++{ ++ struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol); ++ int val = ucontrol->value.integer.value[0]; ++ ++ snd_soc_dapm_set_endpoint(codec, "GSM Line In", val); ++ snd_soc_dapm_sync(codec); ++ ++ return 0; ++} ++ ++static int om_3d7k_get_gsm_in(struct snd_kcontrol *kcontrol, ++ struct snd_ctl_elem_value *ucontrol) ++{ ++ struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol); ++ ++ ucontrol->value.integer.value[0] = ++ snd_soc_dapm_get_endpoint(codec, "GSM Line In"); ++ ++ return 0; ++} ++ ++static int om_3d7k_set_headset_mic(struct snd_kcontrol *kcontrol, ++ struct snd_ctl_elem_value *ucontrol) ++{ ++ struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol); ++ int val = ucontrol->value.integer.value[0]; ++ ++ snd_soc_dapm_set_endpoint(codec, "Headset Mic", val); ++ snd_soc_dapm_sync(codec); ++ ++ return 0; ++} ++ ++static int om_3d7k_get_headset_mic(struct snd_kcontrol *kcontrol, ++ struct snd_ctl_elem_value *ucontrol) ++{ ++ struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol); ++ ++ ucontrol->value.integer.value[0] = ++ snd_soc_dapm_get_endpoint(codec, "Headset Mic"); ++ ++ return 0; ++} ++ ++static int om_3d7k_set_handset_mic(struct snd_kcontrol *kcontrol, ++ struct snd_ctl_elem_value *ucontrol) ++{ ++ struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol); ++ int val = ucontrol->value.integer.value[0]; ++ ++ snd_soc_dapm_set_endpoint(codec, "Handset Mic", val); ++ ++ snd_soc_dapm_sync(codec); ++ ++ return 0; ++} ++ ++static int om_3d7k_get_handset_mic(struct snd_kcontrol *kcontrol, ++ struct snd_ctl_elem_value *ucontrol) ++{ ++ struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol); ++ ++ ucontrol->value.integer.value[0] = ++ snd_soc_dapm_get_endpoint(codec, "Handset Mic"); ++ ++ return 0; ++} ++ ++static int om_3d7k_set_handset_spk(struct snd_kcontrol *kcontrol, ++ struct snd_ctl_elem_value *ucontrol) ++{ ++ struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol); ++ int val = ucontrol->value.integer.value[0]; ++ ++ snd_soc_dapm_set_endpoint(codec, "Handset Spk", val); ++ ++ snd_soc_dapm_sync(codec); ++ ++ return 0; ++} ++ ++static int om_3d7k_get_handset_spk(struct snd_kcontrol *kcontrol, ++ struct snd_ctl_elem_value *ucontrol) ++{ ++ struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol); ++ ++ ucontrol->value.integer.value[0] = ++ snd_soc_dapm_get_endpoint(codec, "Handset Spk"); ++ ++ return 0; ++} ++ ++static int om_3d7k_set_headset_spk(struct snd_kcontrol *kcontrol, ++ struct snd_ctl_elem_value *ucontrol) ++{ ++ struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol); ++ int val = ucontrol->value.integer.value[0]; ++ ++ snd_soc_dapm_set_endpoint(codec, "Headset Spk", val); ++ ++ snd_soc_dapm_sync(codec); ++ ++ return 0; ++} ++ ++static int om_3d7k_get_headset_spk(struct snd_kcontrol *kcontrol, ++ struct snd_ctl_elem_value *ucontrol) ++{ ++ struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol); ++ ++ ucontrol->value.integer.value[0] = ++ snd_soc_dapm_get_endpoint(codec, "Headset Spk"); ++ ++ return 0; ++} ++ ++static const struct snd_soc_dapm_widget wm8753_dapm_widgets[] = { ++ SND_SOC_DAPM_LINE("Stereo Out", NULL), ++ SND_SOC_DAPM_LINE("GSM Line Out", NULL), ++ SND_SOC_DAPM_LINE("GSM Line In", NULL), ++ SND_SOC_DAPM_MIC("Headset Mic", NULL), ++ SND_SOC_DAPM_MIC("Handset Mic", NULL), ++ SND_SOC_DAPM_SPK("Handset Spk", NULL), ++ SND_SOC_DAPM_SPK("Headset Spk", NULL), ++}; ++ ++ ++/* example machine audio_mapnections */ ++static const struct snd_soc_dapm_route audio_map[] = { ++ ++ {"Stereo Out", NULL, "LOUT2"}, ++ {"Stereo Out", NULL, "ROUT2"}, ++ ++ /* Connections to the GSM Module */ ++ {"GSM Line Out", NULL, "MONO1"}, ++ {"GSM Line Out", NULL, "MONO2"}, ++ {"RXP", NULL, "GSM Line In"}, ++ {"RXN", NULL, "GSM Line In"}, ++ ++ /* Connections to Headset */ ++ {"MIC1", NULL, "Mic Bias"}, ++ {"Mic Bias", NULL, "Headset Mic"}, ++ ++ /* Call Mic */ ++ {"MIC2", NULL, "Mic Bias"}, ++ {"MIC2N", NULL, "Mic Bias"}, ++ {"Mic Bias", NULL, "Handset Mic"}, ++ ++ /* Call Speaker */ ++ {"Handset Spk", NULL, "OUT3"}, ++ {"Handset Spk", NULL, "LOUT1"}, ++ ++ {"Headset Spk", NULL, "ROUT1"}, ++ {"Headset Spk", NULL, "LOUT1"}, ++ ++ /* Connect the ALC pins */ ++ {"ACIN", NULL, "ACOP"}, ++}; ++ ++static const struct snd_kcontrol_new wm8753_om_3d7k_controls[] = { ++ SOC_SINGLE_EXT("DAPM Stereo Out Switch", 0, 0, 1, 0, ++ om_3d7k_get_stereo_out, ++ om_3d7k_set_stereo_out), ++ SOC_SINGLE_EXT("DAPM GSM Line Out Switch", 1, 0, 1, 0, ++ om_3d7k_get_gsm_out, ++ om_3d7k_set_gsm_out), ++ SOC_SINGLE_EXT("DAPM GSM Line In Switch", 2, 0, 1, 0, ++ om_3d7k_get_gsm_in, ++ om_3d7k_set_gsm_in), ++ SOC_SINGLE_EXT("DAPM Headset Mic Switch", 3, 0, 1, 0, ++ om_3d7k_get_headset_mic, ++ om_3d7k_set_headset_mic), ++ SOC_SINGLE_EXT("DAPM Handset Mic Switch", 4, 0, 1, 0, ++ om_3d7k_get_handset_mic, ++ om_3d7k_set_handset_mic), ++ SOC_SINGLE_EXT("DAPM Handset Spk Switch", 5, 0, 1, 0, ++ om_3d7k_get_handset_spk, ++ om_3d7k_set_handset_spk), ++ SOC_SINGLE_EXT("DAPM Headset Spk Switch", 6, 0, 1, 0, ++ om_3d7k_get_headset_spk, ++ om_3d7k_set_headset_spk), ++}; ++ ++/* ++ * This is an example machine initialisation for a wm8753 connected to a ++ * neo1973 GTA02. ++ */ ++static int om_3d7k_wm8753_init(struct snd_soc_codec *codec) ++{ ++ int i, err; ++ ++ /* set up NC codec pins */ ++ snd_soc_dapm_set_endpoint(codec, "OUT4", 0); ++ snd_soc_dapm_set_endpoint(codec, "LINE1", 0); ++ snd_soc_dapm_set_endpoint(codec, "LINE2", 0); ++ ++ ++ /* Add neo1973 gta02 specific widgets */ ++ snd_soc_dapm_new_controls(codec, wm8753_dapm_widgets, ++ ARRAY_SIZE(wm8753_dapm_widgets)); ++ ++ /* add neo1973 gta02 specific controls */ ++ for (i = 0; i < ARRAY_SIZE(wm8753_om_3d7k_controls); i++) { ++ err = snd_ctl_add(codec->card, ++ snd_soc_cnew(&wm8753_om_3d7k_controls[i], ++ codec, NULL)); ++ if (err < 0) ++ return err; ++ } ++ ++ /* set up neo1973 gta02 specific audio path audio_mapnects */ ++ snd_soc_dapm_add_routes(codec, audio_map, ARRAY_SIZE(audio_map)); ++ ++ /* set endpoints to default off mode */ ++ snd_soc_dapm_set_endpoint(codec, "Stereo Out", 0); ++ snd_soc_dapm_set_endpoint(codec, "GSM Line Out",0); ++ snd_soc_dapm_set_endpoint(codec, "GSM Line In", 0); ++ snd_soc_dapm_set_endpoint(codec, "Headset Mic", 0); ++ snd_soc_dapm_set_endpoint(codec, "Handset Mic", 0); ++ snd_soc_dapm_set_endpoint(codec, "Handset Spk", 0); ++ snd_soc_dapm_set_endpoint(codec, "Headset Spk", 0); ++ ++ snd_soc_dapm_sync(codec); ++ ++ return 0; ++} ++ ++/* ++ * BT Codec DAI ++ */ ++static struct snd_soc_dai bt_dai = ++{ .name = "Bluetooth", ++ .id = 0, ++ .playback = { ++ .channels_min = 1, ++ .channels_max = 1, ++ .rates = SNDRV_PCM_RATE_8000, ++ .formats = SNDRV_PCM_FMTBIT_S16_LE, ++ }, ++ .capture = { ++ .channels_min = 1, ++ .channels_max = 1, ++ .rates = SNDRV_PCM_RATE_8000, ++ .formats = SNDRV_PCM_FMTBIT_S16_LE, ++ }, ++}; ++ ++static struct snd_soc_dai_link om_3d7k_dai[] = { ++ { /* Hifi Playback - for similatious use with voice below */ ++ .name = "WM8753", ++ .stream_name = "WM8753 HiFi", ++ .cpu_dai = &s3c64xx_i2s_dai, ++ .codec_dai = &wm8753_dai[WM8753_DAI_HIFI], ++ .init = om_3d7k_wm8753_init, ++ .ops = &om_3d7k_hifi_ops, ++ }, ++ { /* Voice via BT */ ++ .name = "Bluetooth", ++ .stream_name = "Voice", ++ .cpu_dai = &bt_dai, ++ .codec_dai = &wm8753_dai[WM8753_DAI_VOICE], ++ .ops = &om_3d7k_voice_ops, ++ }, ++}; ++ ++static struct snd_soc_card om_3d7k = { ++ .name = "om-3d7k", ++ .platform = &s3c24xx_soc_platform, ++ .dai_link = om_3d7k_dai, ++ .num_links = ARRAY_SIZE(om_3d7k_dai), ++}; ++ ++static struct snd_soc_device om_3d7k_snd_devdata = { ++ .card = &om_3d7k, ++ .codec_dev = &soc_codec_dev_wm8753, ++}; ++ ++static struct platform_device *om_3d7k_snd_device; ++ ++static int __init om_3d7k_init(void) ++{ ++ int ret; ++ ++ if (!machine_is_om_3d7k()) { ++ printk(KERN_INFO "Only 3D7K supported by ASoC driver\n"); ++ return -ENODEV; ++ } ++ ++ /* register bluetooth DAI here */ ++ ret = snd_soc_register_dai(&bt_dai); ++ if (ret) ++ return ret; ++ ++ om_3d7k_snd_device = platform_device_alloc("soc-audio", 1); ++ if (!om_3d7k_snd_device) ++ return -ENOMEM; ++ ++ platform_set_drvdata(om_3d7k_snd_device, &om_3d7k_snd_devdata); ++ om_3d7k_snd_devdata.dev = &om_3d7k_snd_device->dev; ++ ret = platform_device_add(om_3d7k_snd_device); ++ ++ if (ret) { ++ platform_device_put(om_3d7k_snd_device); ++ return ret; ++ } ++ ++ return ret; ++} ++ ++static void __exit om_3d7k_exit(void) ++{ ++ platform_device_unregister(om_3d7k_snd_device); ++} ++ ++module_init(om_3d7k_init); ++module_exit(om_3d7k_exit); ++ ++/* Module information */ ++MODULE_AUTHOR("Graeme Gregory, graeme@openmoko.org; Ben Dooks <ben@simtec.co.uk>"); ++MODULE_DESCRIPTION("ALSA SoC WM8753 OM 3D7K"); ++MODULE_LICENSE("GPL"); +diff -ruN --exclude='*.orig' --exclude='*.rej' linux-2.6.29-rc3.owrt/sound/soc/s3c24xx/s3c2412-i2s.c linux-2.6.29-rc3.owrt.om/sound/soc/s3c24xx/s3c2412-i2s.c +--- linux-2.6.29-rc3.owrt/sound/soc/s3c24xx/s3c2412-i2s.c 2009-05-10 22:05:01.000000000 +0200 ++++ linux-2.6.29-rc3.owrt.om/sound/soc/s3c24xx/s3c2412-i2s.c 2009-05-10 22:28:00.000000000 +0200 +@@ -22,6 +22,7 @@ + #include <linux/delay.h> + #include <linux/clk.h> + #include <linux/kernel.h> ++#include <linux/io.h> + + #include <sound/core.h> + #include <sound/pcm.h> +@@ -30,20 +31,16 @@ + #include <sound/soc.h> + #include <mach/hardware.h> + +-#include <linux/io.h> +-#include <asm/dma.h> +- +-#include <asm/plat-s3c24xx/regs-s3c2412-iis.h> ++#include <plat/regs-s3c2412-iis.h> + +-#include <mach/regs-gpio.h> +-#include <mach/audio.h> ++#include <plat/regs-gpio.h> ++#include <plat/audio.h> + #include <mach/dma.h> + + #include "s3c24xx-pcm.h" + #include "s3c2412-i2s.h" + + #define S3C2412_I2S_DEBUG 0 +-#define S3C2412_I2S_DEBUG_CON 0 + + #if S3C2412_I2S_DEBUG + #define DBG(x...) printk(KERN_INFO x) +@@ -73,431 +70,7 @@ + .dma_size = 4, + }; + +-struct s3c2412_i2s_info { +- struct device *dev; +- void __iomem *regs; +- struct clk *iis_clk; +- struct clk *iis_pclk; +- struct clk *iis_cclk; +- +- u32 suspend_iismod; +- u32 suspend_iiscon; +- u32 suspend_iispsr; +-}; +- +-static struct s3c2412_i2s_info s3c2412_i2s; +- +-#define bit_set(v, b) (((v) & (b)) ? 1 : 0) +- +-#if S3C2412_I2S_DEBUG_CON +-static void dbg_showcon(const char *fn, u32 con) +-{ +- printk(KERN_DEBUG "%s: LRI=%d, TXFEMPT=%d, RXFEMPT=%d, TXFFULL=%d, RXFFULL=%d\n", fn, +- bit_set(con, S3C2412_IISCON_LRINDEX), +- bit_set(con, S3C2412_IISCON_TXFIFO_EMPTY), +- bit_set(con, S3C2412_IISCON_RXFIFO_EMPTY), +- bit_set(con, S3C2412_IISCON_TXFIFO_FULL), +- bit_set(con, S3C2412_IISCON_RXFIFO_FULL)); +- +- printk(KERN_DEBUG "%s: PAUSE: TXDMA=%d, RXDMA=%d, TXCH=%d, RXCH=%d\n", +- fn, +- bit_set(con, S3C2412_IISCON_TXDMA_PAUSE), +- bit_set(con, S3C2412_IISCON_RXDMA_PAUSE), +- bit_set(con, S3C2412_IISCON_TXCH_PAUSE), +- bit_set(con, S3C2412_IISCON_RXCH_PAUSE)); +- printk(KERN_DEBUG "%s: ACTIVE: TXDMA=%d, RXDMA=%d, IIS=%d\n", fn, +- bit_set(con, S3C2412_IISCON_TXDMA_ACTIVE), +- bit_set(con, S3C2412_IISCON_RXDMA_ACTIVE), +- bit_set(con, S3C2412_IISCON_IIS_ACTIVE)); +-} +-#else +-static inline void dbg_showcon(const char *fn, u32 con) +-{ +-} +-#endif +- +-/* Turn on or off the transmission path. */ +-static void s3c2412_snd_txctrl(int on) +-{ +- struct s3c2412_i2s_info *i2s = &s3c2412_i2s; +- void __iomem *regs = i2s->regs; +- u32 fic, con, mod; +- +- DBG("%s(%d)\n", __func__, on); +- +- fic = readl(regs + S3C2412_IISFIC); +- con = readl(regs + S3C2412_IISCON); +- mod = readl(regs + S3C2412_IISMOD); +- +- DBG("%s: IIS: CON=%x MOD=%x FIC=%x\n", __func__, con, mod, fic); +- +- if (on) { +- con |= S3C2412_IISCON_TXDMA_ACTIVE | S3C2412_IISCON_IIS_ACTIVE; +- con &= ~S3C2412_IISCON_TXDMA_PAUSE; +- con &= ~S3C2412_IISCON_TXCH_PAUSE; +- +- switch (mod & S3C2412_IISMOD_MODE_MASK) { +- case S3C2412_IISMOD_MODE_TXONLY: +- case S3C2412_IISMOD_MODE_TXRX: +- /* do nothing, we are in the right mode */ +- break; +- +- case S3C2412_IISMOD_MODE_RXONLY: +- mod &= ~S3C2412_IISMOD_MODE_MASK; +- mod |= S3C2412_IISMOD_MODE_TXRX; +- break; +- +- default: +- dev_err(i2s->dev, "TXEN: Invalid MODE in IISMOD\n"); +- } +- +- writel(con, regs + S3C2412_IISCON); +- writel(mod, regs + S3C2412_IISMOD); +- } else { +- /* Note, we do not have any indication that the FIFO problems +- * tha the S3C2410/2440 had apply here, so we should be able +- * to disable the DMA and TX without resetting the FIFOS. +- */ +- +- con |= S3C2412_IISCON_TXDMA_PAUSE; +- con |= S3C2412_IISCON_TXCH_PAUSE; +- con &= ~S3C2412_IISCON_TXDMA_ACTIVE; +- +- switch (mod & S3C2412_IISMOD_MODE_MASK) { +- case S3C2412_IISMOD_MODE_TXRX: +- mod &= ~S3C2412_IISMOD_MODE_MASK; +- mod |= S3C2412_IISMOD_MODE_RXONLY; +- break; +- +- case S3C2412_IISMOD_MODE_TXONLY: +- mod &= ~S3C2412_IISMOD_MODE_MASK; +- con &= ~S3C2412_IISCON_IIS_ACTIVE; +- break; +- +- default: +- dev_err(i2s->dev, "TXDIS: Invalid MODE in IISMOD\n"); +- } +- +- writel(mod, regs + S3C2412_IISMOD); +- writel(con, regs + S3C2412_IISCON); +- } +- +- fic = readl(regs + S3C2412_IISFIC); +- dbg_showcon(__func__, con); +- DBG("%s: IIS: CON=%x MOD=%x FIC=%x\n", __func__, con, mod, fic); +-} +- +-static void s3c2412_snd_rxctrl(int on) +-{ +- struct s3c2412_i2s_info *i2s = &s3c2412_i2s; +- void __iomem *regs = i2s->regs; +- u32 fic, con, mod; +- +- DBG("%s(%d)\n", __func__, on); +- +- fic = readl(regs + S3C2412_IISFIC); +- con = readl(regs + S3C2412_IISCON); +- mod = readl(regs + S3C2412_IISMOD); +- +- DBG("%s: IIS: CON=%x MOD=%x FIC=%x\n", __func__, con, mod, fic); +- +- if (on) { +- con |= S3C2412_IISCON_RXDMA_ACTIVE | S3C2412_IISCON_IIS_ACTIVE; +- con &= ~S3C2412_IISCON_RXDMA_PAUSE; +- con &= ~S3C2412_IISCON_RXCH_PAUSE; +- +- switch (mod & S3C2412_IISMOD_MODE_MASK) { +- case S3C2412_IISMOD_MODE_TXRX: +- case S3C2412_IISMOD_MODE_RXONLY: +- /* do nothing, we are in the right mode */ +- break; +- +- case S3C2412_IISMOD_MODE_TXONLY: +- mod &= ~S3C2412_IISMOD_MODE_MASK; +- mod |= S3C2412_IISMOD_MODE_TXRX; +- break; +- +- default: +- dev_err(i2s->dev, "RXEN: Invalid MODE in IISMOD\n"); +- } +- +- writel(mod, regs + S3C2412_IISMOD); +- writel(con, regs + S3C2412_IISCON); +- } else { +- /* See txctrl notes on FIFOs. */ +- +- con &= ~S3C2412_IISCON_RXDMA_ACTIVE; +- con |= S3C2412_IISCON_RXDMA_PAUSE; +- con |= S3C2412_IISCON_RXCH_PAUSE; +- +- switch (mod & S3C2412_IISMOD_MODE_MASK) { +- case S3C2412_IISMOD_MODE_RXONLY: +- con &= ~S3C2412_IISCON_IIS_ACTIVE; +- mod &= ~S3C2412_IISMOD_MODE_MASK; +- break; +- +- case S3C2412_IISMOD_MODE_TXRX: +- mod &= ~S3C2412_IISMOD_MODE_MASK; +- mod |= S3C2412_IISMOD_MODE_TXONLY; +- break; +- +- default: +- dev_err(i2s->dev, "RXEN: Invalid MODE in IISMOD\n"); +- } +- +- writel(con, regs + S3C2412_IISCON); +- writel(mod, regs + S3C2412_IISMOD); +- } +- +- fic = readl(regs + S3C2412_IISFIC); +- DBG("%s: IIS: CON=%x MOD=%x FIC=%x\n", __func__, con, mod, fic); +-} +- +- +-/* +- * Wait for the LR signal to allow synchronisation to the L/R clock +- * from the codec. May only be needed for slave mode. +- */ +-static int s3c2412_snd_lrsync(void) +-{ +- u32 iiscon; +- unsigned long timeout = jiffies + msecs_to_jiffies(5); +- +- DBG("Entered %s\n", __func__); +- +- while (1) { +- iiscon = readl(s3c2412_i2s.regs + S3C2412_IISCON); +- if (iiscon & S3C2412_IISCON_LRINDEX) +- break; +- +- if (timeout < jiffies) { +- printk(KERN_ERR "%s: timeout\n", __func__); +- return -ETIMEDOUT; +- } +- } +- +- return 0; +-} +- +-/* +- * Check whether CPU is the master or slave +- */ +-static inline int s3c2412_snd_is_clkmaster(void) +-{ +- u32 iismod = readl(s3c2412_i2s.regs + S3C2412_IISMOD); +- +- DBG("Entered %s\n", __func__); +- +- iismod &= S3C2412_IISMOD_MASTER_MASK; +- return !(iismod == S3C2412_IISMOD_SLAVE); +-} +- +-/* +- * Set S3C2412 I2S DAI format +- */ +-static int s3c2412_i2s_set_fmt(struct snd_soc_dai *cpu_dai, +- unsigned int fmt) +-{ +- u32 iismod; +- +- +- DBG("Entered %s\n", __func__); +- +- iismod = readl(s3c2412_i2s.regs + S3C2412_IISMOD); +- DBG("hw_params r: IISMOD: %x \n", iismod); +- +- switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) { +- case SND_SOC_DAIFMT_CBM_CFM: +- iismod &= ~S3C2412_IISMOD_MASTER_MASK; +- iismod |= S3C2412_IISMOD_SLAVE; +- break; +- case SND_SOC_DAIFMT_CBS_CFS: +- iismod &= ~S3C2412_IISMOD_MASTER_MASK; +- iismod |= S3C2412_IISMOD_MASTER_INTERNAL; +- break; +- default: +- DBG("unknwon master/slave format\n"); +- return -EINVAL; +- } +- +- iismod &= ~S3C2412_IISMOD_SDF_MASK; +- +- switch (fmt & SND_SOC_DAIFMT_FORMAT_MASK) { +- case SND_SOC_DAIFMT_RIGHT_J: +- iismod |= S3C2412_IISMOD_SDF_MSB; +- break; +- case SND_SOC_DAIFMT_LEFT_J: +- iismod |= S3C2412_IISMOD_SDF_LSB; +- break; +- case SND_SOC_DAIFMT_I2S: +- iismod |= S3C2412_IISMOD_SDF_IIS; +- break; +- default: +- DBG("Unknown data format\n"); +- return -EINVAL; +- } +- +- writel(iismod, s3c2412_i2s.regs + S3C2412_IISMOD); +- DBG("hw_params w: IISMOD: %x \n", iismod); +- return 0; +-} +- +-static int s3c2412_i2s_hw_params(struct snd_pcm_substream *substream, +- struct snd_pcm_hw_params *params, +- struct snd_soc_dai *dai) +-{ +- struct snd_soc_pcm_runtime *rtd = substream->private_data; +- u32 iismod; +- +- DBG("Entered %s\n", __func__); +- +- if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) +- rtd->dai->cpu_dai->dma_data = &s3c2412_i2s_pcm_stereo_out; +- else +- rtd->dai->cpu_dai->dma_data = &s3c2412_i2s_pcm_stereo_in; +- +- /* Working copies of register */ +- iismod = readl(s3c2412_i2s.regs + S3C2412_IISMOD); +- DBG("%s: r: IISMOD: %x\n", __func__, iismod); +- +- switch (params_format(params)) { +- case SNDRV_PCM_FORMAT_S8: +- iismod |= S3C2412_IISMOD_8BIT; +- break; +- case SNDRV_PCM_FORMAT_S16_LE: +- iismod &= ~S3C2412_IISMOD_8BIT; +- break; +- } +- +- writel(iismod, s3c2412_i2s.regs + S3C2412_IISMOD); +- DBG("%s: w: IISMOD: %x\n", __func__, iismod); +- return 0; +-} +- +-static int s3c2412_i2s_trigger(struct snd_pcm_substream *substream, int cmd, +- struct snd_soc_dai *dai) +-{ +- int capture = (substream->stream == SNDRV_PCM_STREAM_CAPTURE); +- unsigned long irqs; +- int ret = 0; +- +- DBG("Entered %s\n", __func__); +- +- switch (cmd) { +- case SNDRV_PCM_TRIGGER_START: +- /* On start, ensure that the FIFOs are cleared and reset. */ +- +- writel(capture ? S3C2412_IISFIC_RXFLUSH : S3C2412_IISFIC_TXFLUSH, +- s3c2412_i2s.regs + S3C2412_IISFIC); +- +- /* clear again, just in case */ +- writel(0x0, s3c2412_i2s.regs + S3C2412_IISFIC); +- +- case SNDRV_PCM_TRIGGER_RESUME: +- case SNDRV_PCM_TRIGGER_PAUSE_RELEASE: +- if (!s3c2412_snd_is_clkmaster()) { +- ret = s3c2412_snd_lrsync(); +- if (ret) +- goto exit_err; +- } +- +- local_irq_save(irqs); +- +- if (capture) +- s3c2412_snd_rxctrl(1); +- else +- s3c2412_snd_txctrl(1); +- +- local_irq_restore(irqs); +- break; +- +- case SNDRV_PCM_TRIGGER_STOP: +- case SNDRV_PCM_TRIGGER_SUSPEND: +- case SNDRV_PCM_TRIGGER_PAUSE_PUSH: +- local_irq_save(irqs); +- +- if (capture) +- s3c2412_snd_rxctrl(0); +- else +- s3c2412_snd_txctrl(0); +- +- local_irq_restore(irqs); +- break; +- default: +- ret = -EINVAL; +- break; +- } +- +-exit_err: +- return ret; +-} +- +-/* default table of all avaialable root fs divisors */ +-static unsigned int s3c2412_iis_fs[] = { 256, 512, 384, 768, 0 }; +- +-int s3c2412_iis_calc_rate(struct s3c2412_rate_calc *info, +- unsigned int *fstab, +- unsigned int rate, struct clk *clk) +-{ +- unsigned long clkrate = clk_get_rate(clk); +- unsigned int div; +- unsigned int fsclk; +- unsigned int actual; +- unsigned int fs; +- unsigned int fsdiv; +- signed int deviation = 0; +- unsigned int best_fs = 0; +- unsigned int best_div = 0; +- unsigned int best_rate = 0; +- unsigned int best_deviation = INT_MAX; +- +- +- if (fstab == NULL) +- fstab = s3c2412_iis_fs; +- +- for (fs = 0;; fs++) { +- fsdiv = s3c2412_iis_fs[fs]; +- +- if (fsdiv == 0) +- break; +- +- fsclk = clkrate / fsdiv; +- div = fsclk / rate; +- +- if ((fsclk % rate) > (rate / 2)) +- div++; +- +- if (div <= 1) +- continue; +- +- actual = clkrate / (fsdiv * div); +- deviation = actual - rate; +- +- printk(KERN_DEBUG "%dfs: div %d => result %d, deviation %d\n", +- fsdiv, div, actual, deviation); +- +- deviation = abs(deviation); +- +- if (deviation < best_deviation) { +- best_fs = fsdiv; +- best_div = div; +- best_rate = actual; +- best_deviation = deviation; +- } +- +- if (deviation == 0) +- break; +- } +- +- printk(KERN_DEBUG "best: fs=%d, div=%d, rate=%d\n", +- best_fs, best_div, best_rate); +- +- info->fs_div = best_fs; +- info->clk_div = best_div; +- +- return 0; +-} +-EXPORT_SYMBOL_GPL(s3c2412_iis_calc_rate); ++static struct s3c_i2sv2_info s3c2412_i2s; + + /* + * Set S3C2412 Clock source +@@ -512,10 +85,12 @@ + + switch (clk_id) { + case S3C2412_CLKSRC_PCLK: ++ s3c2412_i2s.master = 1; + iismod &= ~S3C2412_IISMOD_MASTER_MASK; + iismod |= S3C2412_IISMOD_MASTER_INTERNAL; + break; + case S3C2412_CLKSRC_I2SCLK: ++ s3c2412_i2s.master = 0; + iismod &= ~S3C2412_IISMOD_MASTER_MASK; + iismod |= S3C2412_IISMOD_MASTER_EXTERNAL; + break; +@@ -527,74 +102,6 @@ + return 0; + } + +-/* +- * Set S3C2412 Clock dividers +- */ +-static int s3c2412_i2s_set_clkdiv(struct snd_soc_dai *cpu_dai, +- int div_id, int div) +-{ +- struct s3c2412_i2s_info *i2s = &s3c2412_i2s; +- u32 reg; +- +- DBG("%s(%p, %d, %d)\n", __func__, cpu_dai, div_id, div); +- +- switch (div_id) { +- case S3C2412_DIV_BCLK: +- reg = readl(i2s->regs + S3C2412_IISMOD); +- reg &= ~S3C2412_IISMOD_BCLK_MASK; +- writel(reg | div, i2s->regs + S3C2412_IISMOD); +- +- DBG("%s: MOD=%08x\n", __func__, readl(i2s->regs + S3C2412_IISMOD)); +- break; +- +- case S3C2412_DIV_RCLK: +- if (div > 3) { +- /* convert value to bit field */ +- +- switch (div) { +- case 256: +- div = S3C2412_IISMOD_RCLK_256FS; +- break; +- +- case 384: +- div = S3C2412_IISMOD_RCLK_384FS; +- break; +- +- case 512: +- div = S3C2412_IISMOD_RCLK_512FS; +- break; +- +- case 768: +- div = S3C2412_IISMOD_RCLK_768FS; +- break; +- +- default: +- return -EINVAL; +- } +- } +- +- reg = readl(s3c2412_i2s.regs + S3C2412_IISMOD); +- reg &= ~S3C2412_IISMOD_RCLK_MASK; +- writel(reg | div, i2s->regs + S3C2412_IISMOD); +- DBG("%s: MOD=%08x\n", __func__, readl(i2s->regs + S3C2412_IISMOD)); +- break; +- +- case S3C2412_DIV_PRESCALER: +- if (div >= 0) { +- writel((div << 8) | S3C2412_IISPSR_PSREN, +- i2s->regs + S3C2412_IISPSR); +- } else { +- writel(0x0, i2s->regs + S3C2412_IISPSR); +- } +- DBG("%s: PSR=%08x\n", __func__, readl(i2s->regs + S3C2412_IISPSR)); +- break; +- +- default: +- return -EINVAL; +- } +- +- return 0; +-} + + struct clk *s3c2412_get_iisclk(void) + { +@@ -606,20 +113,16 @@ + static int s3c2412_i2s_probe(struct platform_device *pdev, + struct snd_soc_dai *dai) + { ++ int ret; ++ + DBG("Entered %s\n", __func__); + +- s3c2412_i2s.dev = &pdev->dev; ++ ret = s3c_i2sv2_probe(pdev, dai, &s3c2412_i2s, S3C2410_PA_IIS); ++ if (ret) ++ return ret; + +- s3c2412_i2s.regs = ioremap(S3C2410_PA_IIS, 0x100); +- if (s3c2412_i2s.regs == NULL) +- return -ENXIO; +- +- s3c2412_i2s.iis_pclk = clk_get(&pdev->dev, "iis"); +- if (s3c2412_i2s.iis_pclk == NULL) { +- DBG("failed to get iis_clock\n"); +- iounmap(s3c2412_i2s.regs); +- return -ENODEV; +- } ++ s3c2412_i2s.dma_capture = &s3c2412_i2s_pcm_stereo_in; ++ s3c2412_i2s.dma_playback = &s3c2412_i2s_pcm_stereo_out; + + s3c2412_i2s.iis_cclk = clk_get(&pdev->dev, "i2sclk"); + if (s3c2412_i2s.iis_cclk == NULL) { +@@ -628,12 +131,12 @@ + return -ENODEV; + } + +- clk_set_parent(s3c2412_i2s.iis_cclk, clk_get(NULL, "mpll")); ++ /* Set MPLL as the source for IIS CLK */ + +- clk_enable(s3c2412_i2s.iis_pclk); ++ clk_set_parent(s3c2412_i2s.iis_cclk, clk_get(NULL, "mpll")); + clk_enable(s3c2412_i2s.iis_cclk); + +- s3c2412_i2s.iis_clk = s3c2412_i2s.iis_pclk; ++ s3c2412_i2s.iis_cclk = s3c2412_i2s.iis_pclk; + + /* Configure the I2S pins in correct mode */ + s3c2410_gpio_cfgpin(S3C2410_GPE0, S3C2410_GPE0_I2SLRCK); +@@ -642,66 +145,8 @@ + s3c2410_gpio_cfgpin(S3C2410_GPE3, S3C2410_GPE3_I2SSDI); + s3c2410_gpio_cfgpin(S3C2410_GPE4, S3C2410_GPE4_I2SSDO); + +- s3c2412_snd_txctrl(0); +- s3c2412_snd_rxctrl(0); +- +- return 0; +-} +- +-#ifdef CONFIG_PM +-static int s3c2412_i2s_suspend(struct snd_soc_dai *dai) +-{ +- struct s3c2412_i2s_info *i2s = &s3c2412_i2s; +- u32 iismod; +- +- if (dai->active) { +- i2s->suspend_iismod = readl(i2s->regs + S3C2412_IISMOD); +- i2s->suspend_iiscon = readl(i2s->regs + S3C2412_IISCON); +- i2s->suspend_iispsr = readl(i2s->regs + S3C2412_IISPSR); +- +- /* some basic suspend checks */ +- +- iismod = readl(i2s->regs + S3C2412_IISMOD); +- +- if (iismod & S3C2412_IISCON_RXDMA_ACTIVE) +- pr_warning("%s: RXDMA active?\n", __func__); +- +- if (iismod & S3C2412_IISCON_TXDMA_ACTIVE) +- pr_warning("%s: TXDMA active?\n", __func__); +- +- if (iismod & S3C2412_IISCON_IIS_ACTIVE) +- pr_warning("%s: IIS active\n", __func__); +- } +- +- return 0; +-} +- +-static int s3c2412_i2s_resume(struct snd_soc_dai *dai) +-{ +- struct s3c2412_i2s_info *i2s = &s3c2412_i2s; +- +- pr_info("dai_active %d, IISMOD %08x, IISCON %08x\n", +- dai->active, i2s->suspend_iismod, i2s->suspend_iiscon); +- +- if (dai->active) { +- writel(i2s->suspend_iiscon, i2s->regs + S3C2412_IISCON); +- writel(i2s->suspend_iismod, i2s->regs + S3C2412_IISMOD); +- writel(i2s->suspend_iispsr, i2s->regs + S3C2412_IISPSR); +- +- writel(S3C2412_IISFIC_RXFLUSH | S3C2412_IISFIC_TXFLUSH, +- i2s->regs + S3C2412_IISFIC); +- +- ndelay(250); +- writel(0x0, i2s->regs + S3C2412_IISFIC); +- +- } +- + return 0; + } +-#else +-#define s3c2412_i2s_suspend NULL +-#define s3c2412_i2s_resume NULL +-#endif /* CONFIG_PM */ + + #define S3C2412_I2S_RATES \ + (SNDRV_PCM_RATE_8000 | SNDRV_PCM_RATE_11025 | SNDRV_PCM_RATE_16000 | \ +@@ -709,11 +154,9 @@ + SNDRV_PCM_RATE_48000 | SNDRV_PCM_RATE_88200 | SNDRV_PCM_RATE_96000) + + struct snd_soc_dai s3c2412_i2s_dai = { +- .name = "s3c2412-i2s", +- .id = 0, +- .probe = s3c2412_i2s_probe, +- .suspend = s3c2412_i2s_suspend, +- .resume = s3c2412_i2s_resume, ++ .name = "s3c2412-i2s", ++ .id = 0, ++ .probe = s3c2412_i2s_probe, + .playback = { + .channels_min = 2, + .channels_max = 2, +@@ -727,10 +170,6 @@ + .formats = SNDRV_PCM_FMTBIT_S8 | SNDRV_PCM_FMTBIT_S16_LE, + }, + .ops = { +- .trigger = s3c2412_i2s_trigger, +- .hw_params = s3c2412_i2s_hw_params, +- .set_fmt = s3c2412_i2s_set_fmt, +- .set_clkdiv = s3c2412_i2s_set_clkdiv, + .set_sysclk = s3c2412_i2s_set_sysclk, + }, + }; +@@ -738,7 +177,7 @@ + + static int __init s3c2412_i2s_init(void) + { +- return snd_soc_register_dai(&s3c2412_i2s_dai); ++ return s3c_i2sv2_register_dai(&s3c2412_i2s_dai); + } + module_init(s3c2412_i2s_init); + +@@ -748,7 +187,6 @@ + } + module_exit(s3c2412_i2s_exit); + +- + /* Module information */ + MODULE_AUTHOR("Ben Dooks, <ben@simtec.co.uk>"); + MODULE_DESCRIPTION("S3C2412 I2S SoC Interface"); +diff -ruN --exclude='*.orig' --exclude='*.rej' linux-2.6.29-rc3.owrt/sound/soc/s3c24xx/s3c2412-i2s.h linux-2.6.29-rc3.owrt.om/sound/soc/s3c24xx/s3c2412-i2s.h +--- linux-2.6.29-rc3.owrt/sound/soc/s3c24xx/s3c2412-i2s.h 2009-05-10 22:05:01.000000000 +0200 ++++ linux-2.6.29-rc3.owrt.om/sound/soc/s3c24xx/s3c2412-i2s.h 2009-05-10 22:28:00.000000000 +0200 +@@ -15,9 +15,11 @@ + #ifndef __SND_SOC_S3C24XX_S3C2412_I2S_H + #define __SND_SOC_S3C24XX_S3C2412_I2S_H __FILE__ + +-#define S3C2412_DIV_BCLK (1) +-#define S3C2412_DIV_RCLK (2) +-#define S3C2412_DIV_PRESCALER (3) ++#include "s3c-i2s-v2.h" ++ ++#define S3C2412_DIV_BCLK S3C_I2SV2_DIV_BCLK ++#define S3C2412_DIV_RCLK S3C_I2SV2_DIV_RCLK ++#define S3C2412_DIV_PRESCALER S3C_I2SV2_DIV_PRESCALER + + #define S3C2412_CLKSRC_PCLK (0) + #define S3C2412_CLKSRC_I2SCLK (1) +@@ -26,13 +28,4 @@ + + extern struct snd_soc_dai s3c2412_i2s_dai; + +-struct s3c2412_rate_calc { +- unsigned int clk_div; /* for prescaler */ +- unsigned int fs_div; /* for root frame clock */ +-}; +- +-extern int s3c2412_iis_calc_rate(struct s3c2412_rate_calc *info, +- unsigned int *fstab, +- unsigned int rate, struct clk *clk); +- + #endif /* __SND_SOC_S3C24XX_S3C2412_I2S_H */ +diff -ruN --exclude='*.orig' --exclude='*.rej' linux-2.6.29-rc3.owrt/sound/soc/s3c24xx/s3c2443-ac97.c linux-2.6.29-rc3.owrt.om/sound/soc/s3c24xx/s3c2443-ac97.c +--- linux-2.6.29-rc3.owrt/sound/soc/s3c24xx/s3c2443-ac97.c 2009-05-10 22:05:01.000000000 +0200 ++++ linux-2.6.29-rc3.owrt.om/sound/soc/s3c24xx/s3c2443-ac97.c 2009-05-10 22:28:00.000000000 +0200 +@@ -31,7 +31,7 @@ + #include <plat/regs-ac97.h> + #include <mach/regs-gpio.h> + #include <mach/regs-clock.h> +-#include <mach/audio.h> ++#include <plat/audio.h> + #include <asm/dma.h> + #include <mach/dma.h> + +diff -ruN --exclude='*.orig' --exclude='*.rej' linux-2.6.29-rc3.owrt/sound/soc/s3c24xx/s3c24xx-i2s.c linux-2.6.29-rc3.owrt.om/sound/soc/s3c24xx/s3c24xx-i2s.c +--- linux-2.6.29-rc3.owrt/sound/soc/s3c24xx/s3c24xx-i2s.c 2009-05-10 22:05:01.000000000 +0200 ++++ linux-2.6.29-rc3.owrt.om/sound/soc/s3c24xx/s3c24xx-i2s.c 2009-05-10 22:28:00.000000000 +0200 +@@ -4,7 +4,7 @@ + * (c) 2006 Wolfson Microelectronics PLC. + * Graeme Gregory graeme.gregory@wolfsonmicro.com or linux@wolfsonmicro.com + * +- * (c) 2004-2005 Simtec Electronics ++ * Copyright 2004-2005 Simtec Electronics + * http://armlinux.simtec.co.uk/ + * Ben Dooks <ben@simtec.co.uk> + * +@@ -30,11 +30,11 @@ + #include <mach/hardware.h> + #include <mach/regs-gpio.h> + #include <mach/regs-clock.h> +-#include <mach/audio.h> ++#include <plat/audio.h> + #include <asm/dma.h> + #include <mach/dma.h> + +-#include <asm/plat-s3c24xx/regs-iis.h> ++#include <plat/regs-iis.h> + + #include "s3c24xx-pcm.h" + #include "s3c24xx-i2s.h" +@@ -175,7 +175,7 @@ + static int s3c24xx_snd_lrsync(void) + { + u32 iiscon; +- int timeout = 50; /* 5ms */ ++ int timeout = 5; /* 500us, 125 should be enough at 8kHz */ + + DBG("Entered %s\n", __func__); + +@@ -291,11 +291,14 @@ + case SNDRV_PCM_TRIGGER_START: + case SNDRV_PCM_TRIGGER_RESUME: + case SNDRV_PCM_TRIGGER_PAUSE_RELEASE: +- if (!s3c24xx_snd_is_clkmaster()) { +- ret = s3c24xx_snd_lrsync(); +- if (ret) +- goto exit_err; +- } ++ if (!s3c24xx_snd_is_clkmaster()) ++ /* we ignore the return code, if it sync'd then fine, ++ * if it didn't sync, which happens after resume the ++ * first time when there was a live stream at suspend, ++ * just let it timeout, the stream picks up OK after ++ * that and LRCK is evidently working again. ++ */ ++ s3c24xx_snd_lrsync(); + + if (substream->stream == SNDRV_PCM_STREAM_CAPTURE) + s3c24xx_snd_rxctrl(1); +@@ -315,7 +318,6 @@ + break; + } + +-exit_err: + return ret; + } + +diff -ruN --exclude='*.orig' --exclude='*.rej' linux-2.6.29-rc3.owrt/sound/soc/s3c24xx/s3c24xx-pcm.c linux-2.6.29-rc3.owrt.om/sound/soc/s3c24xx/s3c24xx-pcm.c +--- linux-2.6.29-rc3.owrt/sound/soc/s3c24xx/s3c24xx-pcm.c 2009-05-10 22:05:01.000000000 +0200 ++++ linux-2.6.29-rc3.owrt.om/sound/soc/s3c24xx/s3c24xx-pcm.c 2009-05-10 22:28:00.000000000 +0200 +@@ -4,7 +4,7 @@ + * (c) 2006 Wolfson Microelectronics PLC. + * Graeme Gregory graeme.gregory@wolfsonmicro.com or linux@wolfsonmicro.com + * +- * (c) 2004-2005 Simtec Electronics ++ * Copyright 2004-2005 Simtec Electronics + * http://armlinux.simtec.co.uk/ + * Ben Dooks <ben@simtec.co.uk> + * +@@ -29,7 +29,7 @@ + #include <asm/dma.h> + #include <mach/hardware.h> + #include <mach/dma.h> +-#include <mach/audio.h> ++#include <plat/audio.h> + + #include "s3c24xx-pcm.h" + +@@ -82,11 +82,19 @@ + { + struct s3c24xx_runtime_data *prtd = substream->runtime->private_data; + dma_addr_t pos = prtd->dma_pos; ++ unsigned int limit; + int ret; + + DBG("Entered %s\n", __func__); + +- while (prtd->dma_loaded < prtd->dma_limit) { ++ if (s3c_dma_has_circular()) { ++ limit = (prtd->dma_end - prtd->dma_start) / prtd->dma_period; ++ } else ++ limit = prtd->dma_limit; ++ ++ DBG("%s: loaded %d, limit %d\n", __func__, prtd->dma_loaded, limit); ++ ++ while (prtd->dma_loaded < limit) { + unsigned long len = prtd->dma_period; + + DBG("dma_loaded: %d\n", prtd->dma_loaded); +@@ -130,7 +138,7 @@ + snd_pcm_period_elapsed(substream); + + spin_lock(&prtd->lock); +- if (prtd->state & ST_RUNNING) { ++ if (prtd->state & ST_RUNNING && !s3c_dma_has_circular()) { + prtd->dma_loaded--; + s3c24xx_pcm_enqueue(substream); + } +@@ -168,9 +176,14 @@ + prtd->params->client, NULL); + + if (ret < 0) { +- DBG(KERN_ERR "failed to get dma channel\n"); ++ DBG(KERN_ERR "failed to get dma channel: %d\n", ret); + return ret; + } ++ ++ /* use the circular buffering if we have it available. */ ++ if (s3c_dma_has_circular()) ++ s3c2410_dma_setflags(prtd->params->channel, ++ S3C2410_DMAF_CIRCULAR); + } + + s3c2410_dma_set_buffdone_fn(prtd->params->channel, +@@ -225,23 +238,16 @@ + * sync to pclk, half-word transfers to the IIS-FIFO. */ + if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) { + s3c2410_dma_devconfig(prtd->params->channel, +- S3C2410_DMASRC_MEM, S3C2410_DISRCC_INC | +- S3C2410_DISRCC_APB, prtd->params->dma_addr); +- +- s3c2410_dma_config(prtd->params->channel, +- prtd->params->dma_size, +- S3C2410_DCON_SYNC_PCLK | +- S3C2410_DCON_HANDSHAKE); ++ S3C2410_DMASRC_MEM, ++ prtd->params->dma_addr); + } else { +- s3c2410_dma_config(prtd->params->channel, +- prtd->params->dma_size, +- S3C2410_DCON_HANDSHAKE | +- S3C2410_DCON_SYNC_PCLK); +- + s3c2410_dma_devconfig(prtd->params->channel, +- S3C2410_DMASRC_HW, 0x3, +- prtd->params->dma_addr); ++ S3C2410_DMASRC_HW, ++ prtd->params->dma_addr); + } ++ ++ s3c2410_dma_config(prtd->params->channel, ++ prtd->params->dma_size); + + /* flush the DMA channel */ + s3c2410_dma_ctrl(prtd->params->channel, S3C2410_DMAOP_FLUSH); +diff -ruN --exclude='*.orig' --exclude='*.rej' linux-2.6.29-rc3.owrt/sound/soc/s3c24xx/s3c24xx_uda134x.c linux-2.6.29-rc3.owrt.om/sound/soc/s3c24xx/s3c24xx_uda134x.c +--- linux-2.6.29-rc3.owrt/sound/soc/s3c24xx/s3c24xx_uda134x.c 2009-05-10 22:05:01.000000000 +0200 ++++ linux-2.6.29-rc3.owrt.om/sound/soc/s3c24xx/s3c24xx_uda134x.c 2009-05-10 22:28:00.000000000 +0200 +@@ -22,7 +22,7 @@ + #include <sound/s3c24xx_uda134x.h> + #include <sound/uda134x.h> + +-#include <asm/plat-s3c24xx/regs-iis.h> ++#include <plat/regs-iis.h> + + #include "s3c24xx-pcm.h" + #include "s3c24xx-i2s.h" +diff -ruN --exclude='*.orig' --exclude='*.rej' linux-2.6.29-rc3.owrt/sound/soc/s3c24xx/s3c64xx-i2s.c linux-2.6.29-rc3.owrt.om/sound/soc/s3c24xx/s3c64xx-i2s.c +--- linux-2.6.29-rc3.owrt/sound/soc/s3c24xx/s3c64xx-i2s.c 1970-01-01 01:00:00.000000000 +0100 ++++ linux-2.6.29-rc3.owrt.om/sound/soc/s3c24xx/s3c64xx-i2s.c 2009-05-10 22:28:00.000000000 +0200 +@@ -0,0 +1,219 @@ ++/* sound/soc/s3c24xx/s3c64xx-i2s.c ++ * ++ * ALSA SoC Audio Layer - S3C64XX I2S driver ++ * ++ * Copyright 2008 Openmoko, Inc. ++ * Copyright 2008 Simtec Electronics ++ * Ben Dooks <ben@simtec.co.uk> ++ * http://armlinux.simtec.co.uk/ ++ * ++ * This program is free software; you can redistribute it and/or modify ++ * it under the terms of the GNU General Public License version 2 as ++ * published by the Free Software Foundation. ++ */ ++ ++#include <linux/init.h> ++#include <linux/module.h> ++#include <linux/device.h> ++#include <linux/delay.h> ++#include <linux/clk.h> ++#include <linux/kernel.h> ++#include <linux/gpio.h> ++#include <linux/io.h> ++ ++#include <sound/core.h> ++#include <sound/pcm.h> ++#include <sound/pcm_params.h> ++#include <sound/initval.h> ++#include <sound/soc.h> ++ ++#include <plat/regs-s3c2412-iis.h> ++#include <plat/gpio-bank-d.h> ++#include <plat/gpio-bank-e.h> ++#include <plat/gpio-cfg.h> ++#include <plat/audio.h> ++ ++#include <mach/map.h> ++#include <mach/dma.h> ++ ++#include "s3c24xx-pcm.h" ++#include "s3c64xx-i2s.h" ++ ++static struct s3c2410_dma_client s3c64xx_dma_client_out = { ++ .name = "I2S PCM Stereo out" ++}; ++ ++static struct s3c2410_dma_client s3c64xx_dma_client_in = { ++ .name = "I2S PCM Stereo in" ++}; ++ ++static struct s3c24xx_pcm_dma_params s3c64xx_i2s_pcm_stereo_out[2] = { ++ [0] = { ++ .channel = DMACH_I2S0_OUT, ++ .client = &s3c64xx_dma_client_out, ++ .dma_addr = S3C64XX_PA_IIS0 + S3C2412_IISTXD, ++ .dma_size = 4, ++ }, ++ [1] = { ++ .channel = DMACH_I2S1_OUT, ++ .client = &s3c64xx_dma_client_out, ++ .dma_addr = S3C64XX_PA_IIS1 + S3C2412_IISTXD, ++ .dma_size = 4, ++ }, ++}; ++ ++static struct s3c24xx_pcm_dma_params s3c64xx_i2s_pcm_stereo_in[2] = { ++ [0] = { ++ .channel = DMACH_I2S0_IN, ++ .client = &s3c64xx_dma_client_in, ++ .dma_addr = S3C64XX_PA_IIS0 + S3C2412_IISRXD, ++ .dma_size = 4, ++ }, ++ [1] = { ++ .channel = DMACH_I2S1_IN, ++ .client = &s3c64xx_dma_client_in, ++ .dma_addr = S3C64XX_PA_IIS1 + S3C2412_IISRXD, ++ .dma_size = 4, ++ }, ++}; ++ ++static struct s3c_i2sv2_info s3c64xx_i2s[2]; ++ ++static inline struct s3c_i2sv2_info *to_info(struct snd_soc_dai *cpu_dai) ++{ ++ return cpu_dai->private_data; ++} ++ ++static int s3c64xx_i2s_set_sysclk(struct snd_soc_dai *cpu_dai, ++ int clk_id, unsigned int freq, int dir) ++{ ++ struct s3c_i2sv2_info *i2s = to_info(cpu_dai); ++ u32 iismod = readl(i2s->regs + S3C2412_IISMOD); ++ ++ switch (clk_id) { ++ case S3C64XX_CLKSRC_PCLK: ++ iismod &= ~S3C64XX_IISMOD_IMS_SYSMUX; ++ break; ++ ++ case S3C64XX_CLKSRC_MUX: ++ iismod |= S3C64XX_IISMOD_IMS_SYSMUX; ++ break; ++ ++ default: ++ return -EINVAL; ++ } ++ ++ writel(iismod, i2s->regs + S3C2412_IISMOD); ++ ++ return 0; ++} ++ ++unsigned long s3c64xx_i2s_get_clockrate(struct snd_soc_dai *dai) ++{ ++ struct s3c_i2sv2_info *i2s = to_info(dai); ++ ++ return clk_get_rate(i2s->iis_cclk); ++} ++EXPORT_SYMBOL_GPL(s3c64xx_i2s_get_clockrate); ++ ++static int s3c64xx_i2s_probe(struct platform_device *pdev, ++ struct snd_soc_dai *dai) ++{ ++ struct device *dev = &pdev->dev; ++ struct s3c_i2sv2_info *i2s; ++ int ret; ++ ++ dev_dbg(dev, "%s: probing dai %d\n", __func__, pdev->id); ++ ++ if (pdev->id < 0 || pdev->id > ARRAY_SIZE(s3c64xx_i2s)) { ++ dev_err(dev, "id %d out of range\n", pdev->id); ++ return -EINVAL; ++ } ++ ++ i2s = &s3c64xx_i2s[pdev->id]; ++ ++ ret = s3c_i2sv2_probe(pdev, dai, i2s, ++ pdev->id ? S3C64XX_PA_IIS1 : S3C64XX_PA_IIS0); ++ if (ret) ++ return ret; ++ ++ i2s->dma_capture = &s3c64xx_i2s_pcm_stereo_in[pdev->id]; ++ i2s->dma_playback = &s3c64xx_i2s_pcm_stereo_out[pdev->id]; ++ ++ i2s->iis_cclk = clk_get(dev, "audio-bus"); ++ if (IS_ERR(i2s->iis_cclk)) { ++ dev_err(dev, "failed to get audio-bus"); ++ iounmap(i2s->regs); ++ return -ENODEV; ++ } ++ ++ /* configure GPIO for i2s port */ ++ switch (pdev->id) { ++ case 0: ++ s3c_gpio_cfgpin(S3C64XX_GPD(0), S3C64XX_GPD0_I2S0_CLK); ++ s3c_gpio_cfgpin(S3C64XX_GPD(1), S3C64XX_GPD1_I2S0_CDCLK); ++ s3c_gpio_cfgpin(S3C64XX_GPD(2), S3C64XX_GPD2_I2S0_LRCLK); ++ s3c_gpio_cfgpin(S3C64XX_GPD(3), S3C64XX_GPD3_I2S0_DI); ++ s3c_gpio_cfgpin(S3C64XX_GPD(4), S3C64XX_GPD4_I2S0_D0); ++ break; ++ case 1: ++ s3c_gpio_cfgpin(S3C64XX_GPE(0), S3C64XX_GPE0_I2S1_CLK); ++ s3c_gpio_cfgpin(S3C64XX_GPE(1), S3C64XX_GPE1_I2S1_CDCLK); ++ s3c_gpio_cfgpin(S3C64XX_GPE(2), S3C64XX_GPE2_I2S1_LRCLK); ++ s3c_gpio_cfgpin(S3C64XX_GPE(3), S3C64XX_GPE3_I2S1_DI); ++ s3c_gpio_cfgpin(S3C64XX_GPE(4), S3C64XX_GPE4_I2S1_D0); ++ } ++ ++ return 0; ++} ++ ++ ++#define S3C64XX_I2S_RATES \ ++ (SNDRV_PCM_RATE_8000 | SNDRV_PCM_RATE_11025 | SNDRV_PCM_RATE_16000 | \ ++ SNDRV_PCM_RATE_22050 | SNDRV_PCM_RATE_32000 | SNDRV_PCM_RATE_44100 | \ ++ SNDRV_PCM_RATE_48000 | SNDRV_PCM_RATE_88200 | SNDRV_PCM_RATE_96000) ++ ++#define S3C64XX_I2S_FMTS \ ++ (SNDRV_PCM_FMTBIT_S8 | SNDRV_PCM_FMTBIT_S16_LE) ++ ++struct snd_soc_dai s3c64xx_i2s_dai = { ++ .name = "s3c64xx-i2s", ++ .id = 0, ++ .probe = s3c64xx_i2s_probe, ++ .playback = { ++ .channels_min = 2, ++ .channels_max = 2, ++ .rates = S3C64XX_I2S_RATES, ++ .formats = S3C64XX_I2S_FMTS, ++ }, ++ .capture = { ++ .channels_min = 2, ++ .channels_max = 2, ++ .rates = S3C64XX_I2S_RATES, ++ .formats = S3C64XX_I2S_FMTS, ++ }, ++ .ops = { ++ .set_sysclk = s3c64xx_i2s_set_sysclk, ++ }, ++}; ++EXPORT_SYMBOL_GPL(s3c64xx_i2s_dai); ++ ++static int __init s3c64xx_i2s_init(void) ++{ ++ return s3c_i2sv2_register_dai(&s3c64xx_i2s_dai); ++} ++module_init(s3c64xx_i2s_init); ++ ++static void __exit s3c64xx_i2s_exit(void) ++{ ++ snd_soc_unregister_dai(&s3c64xx_i2s_dai); ++} ++module_exit(s3c64xx_i2s_exit); ++ ++/* Module information */ ++MODULE_AUTHOR("Ben Dooks, <ben@simtec.co.uk>"); ++MODULE_DESCRIPTION("S3C64XX I2S SoC Interface"); ++MODULE_LICENSE("GPL"); ++ ++ ++ +diff -ruN --exclude='*.orig' --exclude='*.rej' linux-2.6.29-rc3.owrt/sound/soc/s3c24xx/s3c64xx-i2s.h linux-2.6.29-rc3.owrt.om/sound/soc/s3c24xx/s3c64xx-i2s.h +--- linux-2.6.29-rc3.owrt/sound/soc/s3c24xx/s3c64xx-i2s.h 1970-01-01 01:00:00.000000000 +0100 ++++ linux-2.6.29-rc3.owrt.om/sound/soc/s3c24xx/s3c64xx-i2s.h 2009-05-10 22:28:00.000000000 +0200 +@@ -0,0 +1,31 @@ ++/* sound/soc/s3c24xx/s3c64xx-i2s.h ++ * ++ * ALSA SoC Audio Layer - S3C64XX I2S driver ++ * ++ * Copyright 2008 Openmoko, Inc. ++ * Copyright 2008 Simtec Electronics ++ * Ben Dooks <ben@simtec.co.uk> ++ * http://armlinux.simtec.co.uk/ ++ * ++ * 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 __SND_SOC_S3C24XX_S3C64XX_I2S_H ++#define __SND_SOC_S3C24XX_S3C64XX_I2S_H __FILE__ ++ ++#include "s3c-i2s-v2.h" ++ ++#define S3C64XX_DIV_BCLK S3C_I2SV2_DIV_BCLK ++#define S3C64XX_DIV_RCLK S3C_I2SV2_DIV_RCLK ++#define S3C64XX_DIV_PRESCALER S3C_I2SV2_DIV_PRESCALER ++ ++#define S3C64XX_CLKSRC_PCLK (0) ++#define S3C64XX_CLKSRC_MUX (1) ++ ++extern struct snd_soc_dai s3c64xx_i2s_dai; ++ ++extern unsigned long s3c64xx_i2s_get_clockrate(struct snd_soc_dai *cpu_dai); ++ ++#endif /* __SND_SOC_S3C24XX_S3C64XX_I2S_H */ +diff -ruN --exclude='*.orig' --exclude='*.rej' linux-2.6.29-rc3.owrt/sound/soc/s3c24xx/s3c-i2s-v2.c linux-2.6.29-rc3.owrt.om/sound/soc/s3c24xx/s3c-i2s-v2.c +--- linux-2.6.29-rc3.owrt/sound/soc/s3c24xx/s3c-i2s-v2.c 1970-01-01 01:00:00.000000000 +0100 ++++ linux-2.6.29-rc3.owrt.om/sound/soc/s3c24xx/s3c-i2s-v2.c 2009-05-10 22:28:00.000000000 +0200 +@@ -0,0 +1,645 @@ ++/* sound/soc/s3c24xx/s3c-i2c-v2.c ++ * ++ * ALSA Soc Audio Layer - I2S core for newer Samsung SoCs. ++ * ++ * Copyright (c) 2006 Wolfson Microelectronics PLC. ++ * Graeme Gregory graeme.gregory@wolfsonmicro.com ++ * linux@wolfsonmicro.com ++ * ++ * Copyright (c) 2008, 2007, 2004-2005 Simtec Electronics ++ * http://armlinux.simtec.co.uk/ ++ * Ben Dooks <ben@simtec.co.uk> ++ * ++ * 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. ++ */ ++ ++#include <linux/init.h> ++#include <linux/module.h> ++#include <linux/device.h> ++#include <linux/delay.h> ++#include <linux/clk.h> ++#include <linux/kernel.h> ++#include <linux/io.h> ++ ++#include <sound/core.h> ++#include <sound/pcm.h> ++#include <sound/pcm_params.h> ++#include <sound/initval.h> ++#include <sound/soc.h> ++ ++#include <plat/regs-s3c2412-iis.h> ++ ++#include <plat/audio.h> ++#include <mach/dma.h> ++ ++#include "s3c-i2s-v2.h" ++ ++#define S3C2412_I2S_DEBUG_CON 0 ++#define S3C2412_I2S_DEBUG 0 ++ ++#if S3C2412_I2S_DEBUG ++#define DBG(x...) printk(KERN_INFO x) ++#else ++#define DBG(x...) do { } while (0) ++#endif ++ ++static inline struct s3c_i2sv2_info *to_info(struct snd_soc_dai *cpu_dai) ++{ ++ return cpu_dai->private_data; ++} ++ ++#define bit_set(v, b) (((v) & (b)) ? 1 : 0) ++ ++#if S3C2412_I2S_DEBUG_CON ++static void dbg_showcon(const char *fn, u32 con) ++{ ++ printk(KERN_DEBUG "%s: LRI=%d, TXFEMPT=%d, RXFEMPT=%d, TXFFULL=%d, RXFFULL=%d\n", fn, ++ bit_set(con, S3C2412_IISCON_LRINDEX), ++ bit_set(con, S3C2412_IISCON_TXFIFO_EMPTY), ++ bit_set(con, S3C2412_IISCON_RXFIFO_EMPTY), ++ bit_set(con, S3C2412_IISCON_TXFIFO_FULL), ++ bit_set(con, S3C2412_IISCON_RXFIFO_FULL)); ++ ++ printk(KERN_DEBUG "%s: PAUSE: TXDMA=%d, RXDMA=%d, TXCH=%d, RXCH=%d\n", ++ fn, ++ bit_set(con, S3C2412_IISCON_TXDMA_PAUSE), ++ bit_set(con, S3C2412_IISCON_RXDMA_PAUSE), ++ bit_set(con, S3C2412_IISCON_TXCH_PAUSE), ++ bit_set(con, S3C2412_IISCON_RXCH_PAUSE)); ++ printk(KERN_DEBUG "%s: ACTIVE: TXDMA=%d, RXDMA=%d, IIS=%d\n", fn, ++ bit_set(con, S3C2412_IISCON_TXDMA_ACTIVE), ++ bit_set(con, S3C2412_IISCON_RXDMA_ACTIVE), ++ bit_set(con, S3C2412_IISCON_IIS_ACTIVE)); ++} ++#else ++static inline void dbg_showcon(const char *fn, u32 con) ++{ ++} ++#endif ++ ++ ++/* Turn on or off the transmission path. */ ++void s3c2412_snd_txctrl(struct s3c_i2sv2_info *i2s, int on) ++{ ++ void __iomem *regs = i2s->regs; ++ u32 fic, con, mod; ++ ++ DBG("%s(%d)\n", __func__, on); ++ ++ fic = readl(regs + S3C2412_IISFIC); ++ con = readl(regs + S3C2412_IISCON); ++ mod = readl(regs + S3C2412_IISMOD); ++ ++ DBG("%s: IIS: CON=%x MOD=%x FIC=%x\n", __func__, con, mod, fic); ++ ++ if (on) { ++ con |= S3C2412_IISCON_TXDMA_ACTIVE | S3C2412_IISCON_IIS_ACTIVE; ++ con &= ~S3C2412_IISCON_TXDMA_PAUSE; ++ con &= ~S3C2412_IISCON_TXCH_PAUSE; ++ ++ switch (mod & S3C2412_IISMOD_MODE_MASK) { ++ case S3C2412_IISMOD_MODE_TXONLY: ++ case S3C2412_IISMOD_MODE_TXRX: ++ /* do nothing, we are in the right mode */ ++ break; ++ ++ case S3C2412_IISMOD_MODE_RXONLY: ++ mod &= ~S3C2412_IISMOD_MODE_MASK; ++ mod |= S3C2412_IISMOD_MODE_TXRX; ++ break; ++ ++ default: ++ dev_err(i2s->dev, "TXEN: Invalid MODE in IISMOD\n"); ++ } ++ ++ writel(con, regs + S3C2412_IISCON); ++ writel(mod, regs + S3C2412_IISMOD); ++ } else { ++ /* Note, we do not have any indication that the FIFO problems ++ * tha the S3C2410/2440 had apply here, so we should be able ++ * to disable the DMA and TX without resetting the FIFOS. ++ */ ++ ++ con |= S3C2412_IISCON_TXDMA_PAUSE; ++ con |= S3C2412_IISCON_TXCH_PAUSE; ++ con &= ~S3C2412_IISCON_TXDMA_ACTIVE; ++ ++ switch (mod & S3C2412_IISMOD_MODE_MASK) { ++ case S3C2412_IISMOD_MODE_TXRX: ++ mod &= ~S3C2412_IISMOD_MODE_MASK; ++ mod |= S3C2412_IISMOD_MODE_RXONLY; ++ break; ++ ++ case S3C2412_IISMOD_MODE_TXONLY: ++ mod &= ~S3C2412_IISMOD_MODE_MASK; ++ con &= ~S3C2412_IISCON_IIS_ACTIVE; ++ break; ++ ++ default: ++ dev_err(i2s->dev, "TXDIS: Invalid MODE in IISMOD\n"); ++ } ++ ++ writel(mod, regs + S3C2412_IISMOD); ++ writel(con, regs + S3C2412_IISCON); ++ } ++ ++ fic = readl(regs + S3C2412_IISFIC); ++ dbg_showcon(__func__, con); ++ DBG("%s: IIS: CON=%x MOD=%x FIC=%x\n", __func__, con, mod, fic); ++} ++EXPORT_SYMBOL_GPL(s3c2412_snd_txctrl); ++ ++void s3c2412_snd_rxctrl(struct s3c_i2sv2_info *i2s, int on) ++{ ++ void __iomem *regs = i2s->regs; ++ u32 fic, con, mod; ++ ++ DBG("%s(%d)\n", __func__, on); ++ ++ fic = readl(regs + S3C2412_IISFIC); ++ con = readl(regs + S3C2412_IISCON); ++ mod = readl(regs + S3C2412_IISMOD); ++ ++ DBG("%s: IIS: CON=%x MOD=%x FIC=%x\n", __func__, con, mod, fic); ++ ++ if (on) { ++ con |= S3C2412_IISCON_RXDMA_ACTIVE | S3C2412_IISCON_IIS_ACTIVE; ++ con &= ~S3C2412_IISCON_RXDMA_PAUSE; ++ con &= ~S3C2412_IISCON_RXCH_PAUSE; ++ ++ switch (mod & S3C2412_IISMOD_MODE_MASK) { ++ case S3C2412_IISMOD_MODE_TXRX: ++ case S3C2412_IISMOD_MODE_RXONLY: ++ /* do nothing, we are in the right mode */ ++ break; ++ ++ case S3C2412_IISMOD_MODE_TXONLY: ++ mod &= ~S3C2412_IISMOD_MODE_MASK; ++ mod |= S3C2412_IISMOD_MODE_TXRX; ++ break; ++ ++ default: ++ dev_err(i2s->dev, "RXEN: Invalid MODE in IISMOD\n"); ++ } ++ ++ writel(mod, regs + S3C2412_IISMOD); ++ writel(con, regs + S3C2412_IISCON); ++ } else { ++ /* See txctrl notes on FIFOs. */ ++ ++ con &= ~S3C2412_IISCON_RXDMA_ACTIVE; ++ con |= S3C2412_IISCON_RXDMA_PAUSE; ++ con |= S3C2412_IISCON_RXCH_PAUSE; ++ ++ switch (mod & S3C2412_IISMOD_MODE_MASK) { ++ case S3C2412_IISMOD_MODE_RXONLY: ++ con &= ~S3C2412_IISCON_IIS_ACTIVE; ++ mod &= ~S3C2412_IISMOD_MODE_MASK; ++ break; ++ ++ case S3C2412_IISMOD_MODE_TXRX: ++ mod &= ~S3C2412_IISMOD_MODE_MASK; ++ mod |= S3C2412_IISMOD_MODE_TXONLY; ++ break; ++ ++ default: ++ dev_err(i2s->dev, "RXEN: Invalid MODE in IISMOD\n"); ++ } ++ ++ writel(con, regs + S3C2412_IISCON); ++ writel(mod, regs + S3C2412_IISMOD); ++ } ++ ++ fic = readl(regs + S3C2412_IISFIC); ++ DBG("%s: IIS: CON=%x MOD=%x FIC=%x\n", __func__, con, mod, fic); ++} ++EXPORT_SYMBOL_GPL(s3c2412_snd_rxctrl); ++ ++/* ++ * Wait for the LR signal to allow synchronisation to the L/R clock ++ * from the codec. May only be needed for slave mode. ++ */ ++static int s3c2412_snd_lrsync(struct s3c_i2sv2_info *i2s) ++{ ++ u32 iiscon; ++ unsigned long timeout = jiffies + msecs_to_jiffies(5); ++ ++ DBG("Entered %s\n", __func__); ++ ++ while (1) { ++ iiscon = readl(i2s->regs + S3C2412_IISCON); ++ if (iiscon & S3C2412_IISCON_LRINDEX) ++ break; ++ ++ if (timeout < jiffies) { ++ printk(KERN_ERR "%s: timeout\n", __func__); ++ return -ETIMEDOUT; ++ } ++ } ++ ++ return 0; ++} ++ ++/* ++ * Set S3C2412 I2S DAI format ++ */ ++static int s3c2412_i2s_set_fmt(struct snd_soc_dai *cpu_dai, ++ unsigned int fmt) ++{ ++ struct s3c_i2sv2_info *i2s = to_info(cpu_dai); ++ u32 iismod; ++ ++ DBG("Entered %s\n", __func__); ++ ++ iismod = readl(i2s->regs + S3C2412_IISMOD); ++ DBG("hw_params r: IISMOD: %x \n", iismod); ++ ++#if defined(CONFIG_CPU_S3C2412) || defined(CONFIG_CPU_S3C2413) ++#define IISMOD_MASTER_MASK S3C2412_IISMOD_MASTER_MASK ++#define IISMOD_SLAVE S3C2412_IISMOD_SLAVE ++#define IISMOD_MASTER S3C2412_IISMOD_MASTER_INTERNAL ++#endif ++ ++#if defined(CONFIG_PLAT_S3C64XX) ++/* From Rev1.1 datasheet, we have two master and two slave modes: ++ * IMS[11:10]: ++ * 00 = master mode, fed from PCLK ++ * 01 = master mode, fed from CLKAUDIO ++ * 10 = slave mode, using PCLK ++ * 11 = slave mode, using I2SCLK ++ */ ++#define IISMOD_MASTER_MASK (1 << 11) ++#define IISMOD_SLAVE (1 << 11) ++#define IISMOD_MASTER (0x0) ++#endif ++ ++ switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) { ++ case SND_SOC_DAIFMT_CBM_CFM: ++ i2s->master = 0; ++ iismod &= ~IISMOD_MASTER_MASK; ++ iismod |= IISMOD_SLAVE; ++ break; ++ case SND_SOC_DAIFMT_CBS_CFS: ++ i2s->master = 1; ++ iismod &= ~IISMOD_MASTER_MASK; ++ iismod |= IISMOD_MASTER; ++ break; ++ default: ++ DBG("unknwon master/slave format\n"); ++ return -EINVAL; ++ } ++ ++ iismod &= ~S3C2412_IISMOD_SDF_MASK; ++ ++ switch (fmt & SND_SOC_DAIFMT_FORMAT_MASK) { ++ case SND_SOC_DAIFMT_RIGHT_J: ++ iismod |= S3C2412_IISMOD_SDF_MSB; ++ break; ++ case SND_SOC_DAIFMT_LEFT_J: ++ iismod |= S3C2412_IISMOD_SDF_LSB; ++ break; ++ case SND_SOC_DAIFMT_I2S: ++ iismod |= S3C2412_IISMOD_SDF_IIS; ++ break; ++ default: ++ DBG("Unknown data format\n"); ++ return -EINVAL; ++ } ++ ++ writel(iismod, i2s->regs + S3C2412_IISMOD); ++ DBG("hw_params w: IISMOD: %x \n", iismod); ++ return 0; ++} ++ ++static int s3c2412_i2s_hw_params(struct snd_pcm_substream *substream, ++ struct snd_pcm_hw_params *params, ++ struct snd_soc_dai *socdai) ++{ ++ struct snd_soc_pcm_runtime *rtd = substream->private_data; ++ struct snd_soc_dai_link *dai = rtd->dai; ++ struct s3c_i2sv2_info *i2s = to_info(dai->cpu_dai); ++ u32 iismod; ++ ++ DBG("Entered %s\n", __func__); ++ ++ if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) ++ dai->cpu_dai->dma_data = i2s->dma_playback; ++ else ++ dai->cpu_dai->dma_data = i2s->dma_capture; ++ ++ /* Working copies of register */ ++ iismod = readl(i2s->regs + S3C2412_IISMOD); ++ DBG("%s: r: IISMOD: %x\n", __func__, iismod); ++ ++ switch (params_format(params)) { ++ case SNDRV_PCM_FORMAT_S8: ++ iismod |= S3C2412_IISMOD_8BIT; ++ break; ++ case SNDRV_PCM_FORMAT_S16_LE: ++ iismod &= ~S3C2412_IISMOD_8BIT; ++ break; ++ } ++ ++ writel(iismod, i2s->regs + S3C2412_IISMOD); ++ DBG("%s: w: IISMOD: %x\n", __func__, iismod); ++ return 0; ++} ++ ++static int s3c2412_i2s_trigger(struct snd_pcm_substream *substream, int cmd, ++ struct snd_soc_dai *dai) ++{ ++ struct snd_soc_pcm_runtime *rtd = substream->private_data; ++ struct s3c_i2sv2_info *i2s = to_info(rtd->dai->cpu_dai); ++ int capture = (substream->stream == SNDRV_PCM_STREAM_CAPTURE); ++ unsigned long irqs; ++ int ret = 0; ++ ++ DBG("Entered %s\n", __func__); ++ ++ switch (cmd) { ++ case SNDRV_PCM_TRIGGER_START: ++ /* On start, ensure that the FIFOs are cleared and reset. */ ++ ++ writel(capture ? S3C2412_IISFIC_RXFLUSH : S3C2412_IISFIC_TXFLUSH, ++ i2s->regs + S3C2412_IISFIC); ++ ++ /* clear again, just in case */ ++ writel(0x0, i2s->regs + S3C2412_IISFIC); ++ ++ case SNDRV_PCM_TRIGGER_RESUME: ++ case SNDRV_PCM_TRIGGER_PAUSE_RELEASE: ++ if (!i2s->master) { ++ ret = s3c2412_snd_lrsync(i2s); ++ if (ret) ++ goto exit_err; ++ } ++ ++ local_irq_save(irqs); ++ ++ if (capture) ++ s3c2412_snd_rxctrl(i2s, 1); ++ else ++ s3c2412_snd_txctrl(i2s, 1); ++ ++ local_irq_restore(irqs); ++ break; ++ ++ case SNDRV_PCM_TRIGGER_STOP: ++ case SNDRV_PCM_TRIGGER_SUSPEND: ++ case SNDRV_PCM_TRIGGER_PAUSE_PUSH: ++ local_irq_save(irqs); ++ ++ if (capture) ++ s3c2412_snd_rxctrl(i2s, 0); ++ else ++ s3c2412_snd_txctrl(i2s, 0); ++ ++ local_irq_restore(irqs); ++ break; ++ default: ++ ret = -EINVAL; ++ break; ++ } ++ ++exit_err: ++ return ret; ++} ++ ++/* ++ * Set S3C2412 Clock dividers ++ */ ++static int s3c2412_i2s_set_clkdiv(struct snd_soc_dai *cpu_dai, ++ int div_id, int div) ++{ ++ struct s3c_i2sv2_info *i2s = to_info(cpu_dai); ++ u32 reg; ++ ++ DBG("%s(%p, %d, %d)\n", __func__, cpu_dai, div_id, div); ++ ++ switch (div_id) { ++ case S3C_I2SV2_DIV_BCLK: ++ reg = readl(i2s->regs + S3C2412_IISMOD); ++ reg &= ~S3C2412_IISMOD_BCLK_MASK; ++ writel(reg | div, i2s->regs + S3C2412_IISMOD); ++ ++ DBG("%s: MOD=%08x\n", __func__, readl(i2s->regs + S3C2412_IISMOD)); ++ break; ++ ++ case S3C_I2SV2_DIV_RCLK: ++ if (div > 3) { ++ /* convert value to bit field */ ++ ++ switch (div) { ++ case 256: ++ div = S3C2412_IISMOD_RCLK_256FS; ++ break; ++ ++ case 384: ++ div = S3C2412_IISMOD_RCLK_384FS; ++ break; ++ ++ case 512: ++ div = S3C2412_IISMOD_RCLK_512FS; ++ break; ++ ++ case 768: ++ div = S3C2412_IISMOD_RCLK_768FS; ++ break; ++ ++ default: ++ return -EINVAL; ++ } ++ } ++ ++ reg = readl(i2s->regs + S3C2412_IISMOD); ++ reg &= ~S3C2412_IISMOD_RCLK_MASK; ++ writel(reg | div, i2s->regs + S3C2412_IISMOD); ++ DBG("%s: MOD=%08x\n", __func__, readl(i2s->regs + S3C2412_IISMOD)); ++ break; ++ ++ case S3C_I2SV2_DIV_PRESCALER: ++ if (div >= 0) { ++ writel((div << 8) | S3C2412_IISPSR_PSREN, ++ i2s->regs + S3C2412_IISPSR); ++ } else { ++ writel(0x0, i2s->regs + S3C2412_IISPSR); ++ } ++ DBG("%s: PSR=%08x\n", __func__, readl(i2s->regs + S3C2412_IISPSR)); ++ break; ++ ++ default: ++ return -EINVAL; ++ } ++ ++ return 0; ++} ++ ++/* default table of all avaialable root fs divisors */ ++static unsigned int iis_fs_tab[] = { 256, 512, 384, 768 }; ++ ++int s3c2412_iis_calc_rate(struct s3c_i2sv2_rate_calc *info, ++ unsigned int *fstab, ++ unsigned int rate, struct clk *clk) ++{ ++ unsigned long clkrate = clk_get_rate(clk); ++ unsigned int div; ++ unsigned int fsclk; ++ unsigned int actual; ++ unsigned int fs; ++ unsigned int fsdiv; ++ signed int deviation = 0; ++ unsigned int best_fs = 0; ++ unsigned int best_div = 0; ++ unsigned int best_rate = 0; ++ unsigned int best_deviation = INT_MAX; ++ ++ if (fstab == NULL) ++ fstab = iis_fs_tab; ++ ++ for (fs = 0; fs < ARRAY_SIZE(iis_fs_tab); fs++) { ++ fsdiv = iis_fs_tab[fs]; ++ ++ fsclk = clkrate / fsdiv; ++ div = fsclk / rate; ++ ++ if ((fsclk % rate) > (rate / 2)) ++ div++; ++ ++ if (div <= 1) ++ continue; ++ ++ actual = clkrate / (fsdiv * div); ++ deviation = actual - rate; ++ ++ printk(KERN_DEBUG "%dfs: div %d => result %d, deviation %d\n", ++ fsdiv, div, actual, deviation); ++ ++ deviation = abs(deviation); ++ ++ if (deviation < best_deviation) { ++ best_fs = fsdiv; ++ best_div = div; ++ best_rate = actual; ++ best_deviation = deviation; ++ } ++ ++ if (deviation == 0) ++ break; ++ } ++ ++ printk(KERN_DEBUG "best: fs=%d, div=%d, rate=%d\n", ++ best_fs, best_div, best_rate); ++ ++ info->fs_div = best_fs; ++ info->clk_div = best_div; ++ ++ return 0; ++} ++EXPORT_SYMBOL_GPL(s3c2412_iis_calc_rate); ++ ++int s3c_i2sv2_probe(struct platform_device *pdev, ++ struct snd_soc_dai *dai, ++ struct s3c_i2sv2_info *i2s, ++ unsigned long base) ++{ ++ struct device *dev = &pdev->dev; ++ ++ i2s->dev = dev; ++ ++ /* record our i2s structure for later use in the callbacks */ ++ dai->private_data = i2s; ++ ++ i2s->regs = ioremap(base, 0x100); ++ if (i2s->regs == NULL) { ++ dev_err(dev, "cannot ioremap registers\n"); ++ return -ENXIO; ++ } ++ ++ i2s->iis_pclk = clk_get(dev, "iis"); ++ if (i2s->iis_pclk == NULL) { ++ DBG("failed to get iis_clock\n"); ++ iounmap(i2s->regs); ++ return -ENOENT; ++ } ++ ++ clk_enable(i2s->iis_pclk); ++ ++ s3c2412_snd_txctrl(i2s, 0); ++ s3c2412_snd_rxctrl(i2s, 0); ++ ++ return 0; ++} ++ ++EXPORT_SYMBOL_GPL(s3c_i2sv2_probe); ++ ++#ifdef CONFIG_PM ++static int s3c2412_i2s_suspend(struct snd_soc_dai *dai) ++{ ++ struct s3c_i2sv2_info *i2s = to_info(dai); ++ u32 iismod; ++ ++ if (dai->active) { ++ i2s->suspend_iismod = readl(i2s->regs + S3C2412_IISMOD); ++ i2s->suspend_iiscon = readl(i2s->regs + S3C2412_IISCON); ++ i2s->suspend_iispsr = readl(i2s->regs + S3C2412_IISPSR); ++ ++ /* some basic suspend checks */ ++ ++ iismod = readl(i2s->regs + S3C2412_IISMOD); ++ ++ if (iismod & S3C2412_IISCON_RXDMA_ACTIVE) ++ pr_warning("%s: RXDMA active?\n", __func__); ++ ++ if (iismod & S3C2412_IISCON_TXDMA_ACTIVE) ++ pr_warning("%s: TXDMA active?\n", __func__); ++ ++ if (iismod & S3C2412_IISCON_IIS_ACTIVE) ++ pr_warning("%s: IIS active\n", __func__); ++ } ++ ++ return 0; ++} ++ ++static int s3c2412_i2s_resume(struct snd_soc_dai *dai) ++{ ++ struct s3c_i2sv2_info *i2s = to_info(dai); ++ ++ pr_info("dai_active %d, IISMOD %08x, IISCON %08x\n", ++ dai->active, i2s->suspend_iismod, i2s->suspend_iiscon); ++ ++ if (dai->active) { ++ writel(i2s->suspend_iiscon, i2s->regs + S3C2412_IISCON); ++ writel(i2s->suspend_iismod, i2s->regs + S3C2412_IISMOD); ++ writel(i2s->suspend_iispsr, i2s->regs + S3C2412_IISPSR); ++ ++ writel(S3C2412_IISFIC_RXFLUSH | S3C2412_IISFIC_TXFLUSH, ++ i2s->regs + S3C2412_IISFIC); ++ ++ ndelay(250); ++ writel(0x0, i2s->regs + S3C2412_IISFIC); ++ } ++ ++ return 0; ++} ++#else ++#define s3c2412_i2s_suspend NULL ++#define s3c2412_i2s_resume NULL ++#endif ++ ++int s3c_i2sv2_register_dai(struct snd_soc_dai *dai) ++{ ++ dai->ops.trigger = s3c2412_i2s_trigger; ++ dai->ops.hw_params = s3c2412_i2s_hw_params; ++ dai->ops.set_fmt = s3c2412_i2s_set_fmt; ++ dai->ops.set_clkdiv = s3c2412_i2s_set_clkdiv; ++ ++ dai->suspend = s3c2412_i2s_suspend; ++ dai->resume = s3c2412_i2s_resume; ++ ++ return snd_soc_register_dai(dai); ++} ++ ++EXPORT_SYMBOL_GPL(s3c_i2sv2_register_dai); +diff -ruN --exclude='*.orig' --exclude='*.rej' linux-2.6.29-rc3.owrt/sound/soc/s3c24xx/s3c-i2s-v2.h linux-2.6.29-rc3.owrt.om/sound/soc/s3c24xx/s3c-i2s-v2.h +--- linux-2.6.29-rc3.owrt/sound/soc/s3c24xx/s3c-i2s-v2.h 1970-01-01 01:00:00.000000000 +0100 ++++ linux-2.6.29-rc3.owrt.om/sound/soc/s3c24xx/s3c-i2s-v2.h 2009-05-10 22:28:00.000000000 +0200 +@@ -0,0 +1,90 @@ ++/* sound/soc/s3c24xx/s3c-i2s-v2.h ++ * ++ * ALSA Soc Audio Layer - S3C_I2SV2 I2S driver ++ * ++ * Copyright (c) 2007 Simtec Electronics ++ * http://armlinux.simtec.co.uk/ ++ * Ben Dooks <ben@simtec.co.uk> ++ * ++ * 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 code is the core support for the I2S block found in a number of ++ * Samsung SoC devices which is unofficially named I2S-V2. Currently the ++ * S3C2412 and the S3C64XX series use this block to provide 1 or 2 I2S ++ * channels via configurable GPIO. ++ */ ++ ++#ifndef __SND_SOC_S3C24XX_S3C_I2SV2_I2S_H ++#define __SND_SOC_S3C24XX_S3C_I2SV2_I2S_H __FILE__ ++ ++#define S3C_I2SV2_DIV_BCLK (1) ++#define S3C_I2SV2_DIV_RCLK (2) ++#define S3C_I2SV2_DIV_PRESCALER (3) ++ ++/** ++ * struct s3c_i2sv2_info - S3C I2S-V2 information ++ * @dev: The parent device passed to use from the probe. ++ * @regs: The pointer to the device registe block. ++ * @master: True if the I2S core is the I2S bit clock master. ++ * @dma_playback: DMA information for playback channel. ++ * @dma_capture: DMA information for capture channel. ++ * @suspend_iismod: PM save for the IISMOD register. ++ * @suspend_iiscon: PM save for the IISCON register. ++ * @suspend_iispsr: PM save for the IISPSR register. ++ * ++ * This is the private codec state for the hardware associated with an ++ * I2S channel such as the register mappings and clock sources. ++ */ ++struct s3c_i2sv2_info { ++ struct device *dev; ++ void __iomem *regs; ++ ++ struct clk *iis_pclk; ++ struct clk *iis_cclk; ++ struct clk *iis_clk; ++ ++ unsigned char master; ++ ++ struct s3c24xx_pcm_dma_params *dma_playback; ++ struct s3c24xx_pcm_dma_params *dma_capture; ++ ++ u32 suspend_iismod; ++ u32 suspend_iiscon; ++ u32 suspend_iispsr; ++}; ++ ++struct s3c_i2sv2_rate_calc { ++ unsigned int clk_div; /* for prescaler */ ++ unsigned int fs_div; /* for root frame clock */ ++}; ++ ++extern int s3c_i2sv2_iis_calc_rate(struct s3c_i2sv2_rate_calc *info, ++ unsigned int *fstab, ++ unsigned int rate, struct clk *clk); ++ ++/** ++ * s3c_i2sv2_probe - probe for i2s device helper ++ * @pdev: The platform device supplied to the original probe. ++ * @dai: The ASoC DAI structure supplied to the original probe. ++ * @i2s: Our local i2s structure to fill in. ++ * @base: The base address for the registers. ++ */ ++extern int s3c_i2sv2_probe(struct platform_device *pdev, ++ struct snd_soc_dai *dai, ++ struct s3c_i2sv2_info *i2s, ++ unsigned long base); ++ ++/** ++ * s3c_i2sv2_register_dai - register dai with soc core ++ * @dai: The snd_soc_dai structure to register ++ * ++ * Fill in any missing fields and then register the given dai with the ++ * soc core. ++ */ ++extern int s3c_i2sv2_register_dai(struct snd_soc_dai *dai); ++ ++#endif /* __SND_SOC_S3C24XX_S3C_I2SV2_I2S_H */ +diff -ruN --exclude='*.orig' --exclude='*.rej' linux-2.6.29-rc3.owrt/sound/soc/s3c24xx/smdk6410-wm8731.c linux-2.6.29-rc3.owrt.om/sound/soc/s3c24xx/smdk6410-wm8731.c +--- linux-2.6.29-rc3.owrt/sound/soc/s3c24xx/smdk6410-wm8731.c 1970-01-01 01:00:00.000000000 +0100 ++++ linux-2.6.29-rc3.owrt.om/sound/soc/s3c24xx/smdk6410-wm8731.c 2009-05-10 22:28:00.000000000 +0200 +@@ -0,0 +1,227 @@ ++ ++ ++#include <linux/module.h> ++#include <linux/moduleparam.h> ++#include <linux/kernel.h> ++#include <linux/clk.h> ++#include <linux/timer.h> ++#include <linux/interrupt.h> ++#include <linux/platform_device.h> ++ ++#include <sound/core.h> ++#include <sound/pcm.h> ++#include <sound/pcm_params.h> ++#include <sound/soc.h> ++#include <sound/soc-dapm.h> ++ ++#include <asm/mach-types.h> ++ ++#include "../codecs/wm8731.h" ++#include "s3c64xx-i2s.h" ++ ++static struct platform_device *socdev; ++ ++ ++ ++static void wm_shutdown(struct snd_pcm_substream *substream) ++{ ++ printk(KERN_INFO "%s: substream %p\n", __func__, substream); ++} ++ ++static int wm_hw_params(struct snd_pcm_substream *substream, ++ struct snd_pcm_hw_params *params) ++{ ++ struct snd_soc_pcm_runtime *rtd = substream->private_data; ++ struct snd_soc_dai *codec_dai = rtd->dai->codec_dai; ++ struct snd_soc_dai *cpu_dai = rtd->dai->cpu_dai; ++ unsigned int fmt; ++ int ret; ++ ++ printk(KERN_INFO "%s: (%p,%p)\n", __func__, substream, params); ++ printk(KERN_INFO "%s: dai: cpu %p, codec %p\n", __func__, cpu_dai, codec_dai); ++ ++ //fmt = SND_SOC_DAIFMT_NB_NF | SND_SOC_DAIFMT_CBS_CFS; ++ fmt = SND_SOC_DAIFMT_NB_NF | SND_SOC_DAIFMT_CBM_CFM; ++ fmt |= SND_SOC_DAIFMT_I2S; ++ ++ ret = snd_soc_dai_set_fmt(codec_dai, fmt); ++ if (ret < 0) ++ return ret; ++ ++ /* set cpu DAI configuration */ ++ ret = snd_soc_dai_set_fmt(cpu_dai, fmt); ++ if (ret < 0) ++ return ret; ++ ++ if (fmt == (SND_SOC_DAIFMT_I2S | SND_SOC_DAIFMT_NB_NF | SND_SOC_DAIFMT_CBM_CFM)) { ++ unsigned long iis_clkrate; ++ ++ ret = snd_soc_dai_set_sysclk(cpu_dai, S3C64XX_CLKSRC_MUX, 0, ++ SND_SOC_CLOCK_OUT); ++ if (ret < 0) { ++ printk(KERN_ERR "%s: cpu set_sysclk err\n", __func__); ++ return ret; ++ } ++ ++ /* set prescaler division for sample rate */ ++ ret = snd_soc_dai_set_clkdiv(cpu_dai, S3C64XX_DIV_PRESCALER, 1); ++ if (ret < 0) { ++ printk(KERN_ERR "%s: codec clkdiv err\n", __func__); ++ return ret; ++ } ++ ++ iis_clkrate = s3c64xx_i2s_get_clockrate(cpu_dai) / 2; ++ printk(KERN_INFO "%s: clockrate %ld\n", __func__, iis_clkrate); ++ ++ iis_clkrate = 12000000; //tmphack// ++ ++ /* set the codec system clock for DAC and ADC */ ++ ret = snd_soc_dai_set_sysclk(codec_dai, WM8731_SYSCLK, ++ iis_clkrate, ++ SND_SOC_CLOCK_IN); ++ if (ret < 0) { ++ printk(KERN_ERR "%s: codec sysclk err\n", __func__); ++ return ret; ++ } ++ ++ } else { ++ /* TODO */ ++ BUG(); ++ } ++ ++ return 0; ++} ++ ++static int wm_startup(struct snd_pcm_substream *substream) ++{ ++ struct snd_soc_pcm_runtime *rtd = snd_pcm_substream_chip(substream); ++ struct snd_soc_dai *codec_dai = rtd->dai->codec_dai; ++ struct snd_soc_dai *cpu_dai = rtd->dai->cpu_dai; ++ int ret; ++ ++ ret = snd_soc_dai_set_sysclk(cpu_dai, S3C64XX_CLKSRC_MUX, 0, ++ SND_SOC_CLOCK_OUT); ++ if (ret < 0) { ++ printk(KERN_ERR "%s: cpu set_sysclk err\n", __func__); ++ return ret; ++ } ++ ++ ret = snd_soc_dai_set_clkdiv(cpu_dai, S3C64XX_DIV_PRESCALER, 1); ++ if (ret < 0) { ++ printk(KERN_ERR "%s: cpu set_clkdiv err\n", __func__); ++ return ret; ++ } ++ ++ ret = snd_soc_dai_set_sysclk(codec_dai, WM8731_SYSCLK, ++ 12000000, SND_SOC_CLOCK_IN); ++ if (ret < 0) { ++ printk(KERN_ERR "%s: codec sysclk err\n", __func__); ++ return ret; ++ } ++ ++ return 0; ++} ++ ++static struct snd_soc_ops wm_ops = { ++ .startup = wm_startup, ++ .hw_params = wm_hw_params, ++ .shutdown = wm_shutdown, ++}; ++ ++static const struct snd_soc_dapm_widget widgets[] = { ++ SND_SOC_DAPM_LINE("Line Out", NULL), ++ SND_SOC_DAPM_HP("Headphone Jack", NULL), ++ SND_SOC_DAPM_INPUT("Line In"), ++}; ++ ++static const struct snd_soc_dapm_route intercon[] = { ++ /* headphone connected to LHPOUT1, RHPOUT1 */ ++ {"Headphone Jack", NULL, "LHPOUT"}, ++ {"Headphone Jack", NULL, "RHPOUT"}, ++ ++ {"Line Out", NULL, "LOUT" }, ++ {"Line Out", NULL, "ROUT" }, ++ ++ {"LLINEIN", NULL, "Line In" }, ++ {"RLINEIN", NULL, "Line In" }, ++}; ++ ++static int wm_init(struct snd_soc_codec *codec) ++{ ++ printk(KERN_DEBUG "%s: codec %p\n", __func__, codec); ++ ++ snd_soc_dapm_new_controls(codec, widgets, ARRAY_SIZE(widgets)); ++ snd_soc_dapm_add_routes(codec, intercon, ARRAY_SIZE(intercon)); ++ ++ snd_soc_dapm_sync(codec); ++ ++ return 0; ++} ++ ++#include "s3c24xx-pcm.h" ++ ++static struct snd_soc_dai_link wm_dai_link = { ++ .name = "WM8731", ++ .stream_name = "WM8731", ++ .cpu_dai = &s3c64xx_i2s_dai, ++ .codec_dai = &wm8731_dai, ++ .init = wm_init, ++ .ops = &wm_ops, ++}; ++ ++static struct snd_soc_card wm_card = { ++ .name = "SMDK6410-WM8731", ++ .dai_link = &wm_dai_link, ++ .platform = &s3c24xx_soc_platform, ++ .num_links = 1, ++}; ++ ++struct wm8731_setup_data wm_setup = { ++ .i2c_bus = 0, ++ .i2c_address = 0x1a, ++}; ++ ++static struct snd_soc_device wm_snd_devdata = { ++ .card = &wm_card, ++ .codec_dev = &soc_codec_dev_wm8731, ++ .codec_data = &wm_setup, ++}; ++ ++static int __init smdk6410_wm8731_init(void) ++{ ++ int ret; ++ ++ printk(KERN_INFO "%s: welcome\n", __func__); ++ ++ if (!machine_is_smdk6410()) { ++ printk(KERN_INFO "%s: for SMDK6410s\n", __func__); ++ return -ENOENT; ++ } ++ ++ socdev = platform_device_alloc("soc-audio", 0); ++ if (!socdev) { ++ printk(KERN_ERR "%s: no device\n", __func__); ++ return -ENOMEM; ++ } ++ ++ platform_set_drvdata(socdev, &wm_snd_devdata); ++ ++ wm_snd_devdata.dev = &socdev->dev; ++ ++ ret = platform_device_add(socdev); ++ if (ret) { ++ printk(KERN_ERR "%s: failed to add\n", __func__); ++ goto err_dev; ++ } ++ ++ printk(KERN_INFO "%s: succesfull\n", __func__); ++ return 0; ++ ++err_dev: ++ platform_device_put(socdev); ++ return ret; ++} ++ ++module_init(smdk6410_wm8731_init); ++MODULE_AUTHOR("Ben Dooks <ben@simtec.co.uk>"); ++MODULE_LICENSE("GPL"); +diff -ruN --exclude='*.orig' --exclude='*.rej' linux-2.6.29-rc3.owrt/sound/soc/soc-core.c linux-2.6.29-rc3.owrt.om/sound/soc/soc-core.c +--- linux-2.6.29-rc3.owrt/sound/soc/soc-core.c 2009-05-10 22:09:10.000000000 +0200 ++++ linux-2.6.29-rc3.owrt.om/sound/soc/soc-core.c 2009-05-10 22:28:00.000000000 +0200 +@@ -1190,6 +1190,7 @@ + } + #endif + ++ + /** + * snd_soc_new_ac97_codec - initailise AC97 device + * @codec: audio codec +diff -ruN --exclude='*.orig' --exclude='*.rej' linux-2.6.29-rc3.owrt/sound/soc/soc-dapm.c linux-2.6.29-rc3.owrt.om/sound/soc/soc-dapm.c +--- linux-2.6.29-rc3.owrt/sound/soc/soc-dapm.c 2009-05-10 22:05:01.000000000 +0200 ++++ linux-2.6.29-rc3.owrt.om/sound/soc/soc-dapm.c 2009-05-10 22:28:00.000000000 +0200 +@@ -332,6 +332,24 @@ + + snprintf(path->long_name, name_len, "%s %s", + w->name, w->kcontrols[i].name); ++ ++ /* ++ * This is an ugly Openmoko revert for name ++ * changes in alsa configuration. This is mergeable ++ * with the future Linux version. ++ * We force the truncation again for now because we ++ * can't cope with mass breakage on alsa state files ++ * that are spread all over the different distros. ++ * FIXME: Remember to revert this change. ++ */ ++ ++ if (name_len > 32) { ++ printk(KERN_WARNING __FILE__ ":%d mixer name " ++ "'%s' truncated to 31 characters.\n", ++ __LINE__, path->long_name); ++ name_len = 32; ++ } ++ + path->long_name[name_len - 1] = '\0'; + + path->kcontrol = snd_soc_cnew(&w->kcontrols[i], w, +@@ -876,7 +894,7 @@ + } + + static int snd_soc_dapm_set_pin(struct snd_soc_codec *codec, +- char *pin, int status) ++ const char *pin, int status) + { + struct snd_soc_dapm_widget *w; + +@@ -1396,6 +1414,76 @@ + EXPORT_SYMBOL_GPL(snd_soc_dapm_put_value_enum_double); + + /** ++ * snd_soc_dapm_info_pin_switch - Info for a pin switch ++ * ++ * @kcontrol: mixer control ++ * @uinfo: control element information ++ * ++ * Callback to provide information about a pin switch control. ++ */ ++int snd_soc_dapm_info_pin_switch(struct snd_kcontrol *kcontrol, ++ struct snd_ctl_elem_info *uinfo) ++{ ++ uinfo->type = SNDRV_CTL_ELEM_TYPE_BOOLEAN; ++ uinfo->count = 1; ++ uinfo->value.integer.min = 0; ++ uinfo->value.integer.max = 1; ++ ++ return 0; ++} ++EXPORT_SYMBOL_GPL(snd_soc_dapm_info_pin_switch); ++ ++/** ++ * snd_soc_dapm_get_pin_switch - Get information for a pin switch ++ * ++ * @kcontrol: mixer control ++ * @ucontrol: Value ++ */ ++int snd_soc_dapm_get_pin_switch(struct snd_kcontrol *kcontrol, ++ struct snd_ctl_elem_value *ucontrol) ++{ ++ struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol); ++ const char *pin = (const char *)kcontrol->private_value; ++ ++ mutex_lock(&codec->mutex); ++ ++ ucontrol->value.integer.value[0] = ++ snd_soc_dapm_get_pin_status(codec, pin); ++ ++ mutex_unlock(&codec->mutex); ++ ++ return 0; ++} ++EXPORT_SYMBOL_GPL(snd_soc_dapm_get_pin_switch); ++ ++/** ++ * snd_soc_dapm_put_pin_switch - Set information for a pin switch ++ * ++ * @kcontrol: mixer control ++ * @ucontrol: Value ++ */ ++int snd_soc_dapm_put_pin_switch(struct snd_kcontrol *kcontrol, ++ struct snd_ctl_elem_value *ucontrol) ++{ ++ struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol); ++ const char *pin = (const char *)kcontrol->private_value; ++ ++ mutex_lock(&codec->mutex); ++ ++ if (ucontrol->value.integer.value[0]) ++ snd_soc_dapm_enable_pin(codec, pin); ++ else ++ snd_soc_dapm_disable_pin(codec, pin); ++ ++ snd_soc_dapm_sync(codec); ++ ++ mutex_unlock(&codec->mutex); ++ ++ return 0; ++} ++EXPORT_SYMBOL_GPL(snd_soc_dapm_put_pin_switch); ++ ++/** + * snd_soc_dapm_new_control - create new dapm control + * @codec: audio codec + * @widget: widget template +@@ -1549,7 +1637,7 @@ + * NOTE: snd_soc_dapm_sync() needs to be called after this for DAPM to + * do any widget power switching. + */ +-int snd_soc_dapm_enable_pin(struct snd_soc_codec *codec, char *pin) ++int snd_soc_dapm_enable_pin(struct snd_soc_codec *codec, const char *pin) + { + return snd_soc_dapm_set_pin(codec, pin, 1); + } +@@ -1564,7 +1652,7 @@ + * NOTE: snd_soc_dapm_sync() needs to be called after this for DAPM to + * do any widget power switching. + */ +-int snd_soc_dapm_disable_pin(struct snd_soc_codec *codec, char *pin) ++int snd_soc_dapm_disable_pin(struct snd_soc_codec *codec, const char *pin) + { + return snd_soc_dapm_set_pin(codec, pin, 0); + } +@@ -1584,7 +1672,7 @@ + * NOTE: snd_soc_dapm_sync() needs to be called after this for DAPM to + * do any widget power switching. + */ +-int snd_soc_dapm_nc_pin(struct snd_soc_codec *codec, char *pin) ++int snd_soc_dapm_nc_pin(struct snd_soc_codec *codec, const char *pin) + { + return snd_soc_dapm_set_pin(codec, pin, 0); + } +@@ -1599,7 +1687,7 @@ + * + * Returns 1 for connected otherwise 0. + */ +-int snd_soc_dapm_get_pin_status(struct snd_soc_codec *codec, char *pin) ++int snd_soc_dapm_get_pin_status(struct snd_soc_codec *codec, const char *pin) + { + struct snd_soc_dapm_widget *w; + +@@ -1613,6 +1701,56 @@ + EXPORT_SYMBOL_GPL(snd_soc_dapm_get_pin_status); + + /** ++ * snd_soc_dapm_get_endpoint - get audio endpoint status ++ * @codec: audio codec ++ * @endpoint: audio signal endpoint (or start point) ++ * ++ * Get audio endpoint status - connected or disconnected. ++ * ++ * Returns status ++ */ ++int snd_soc_dapm_get_endpoint(struct snd_soc_codec *codec, ++ char *endpoint) ++{ ++ struct snd_soc_dapm_widget *w; ++ ++ list_for_each_entry(w, &codec->dapm_widgets, list) { ++ if (!strcmp(w->name, endpoint)) { ++ return w->connected; ++ } ++ } ++ ++ return 0; ++} ++EXPORT_SYMBOL_GPL(snd_soc_dapm_get_endpoint); ++ ++/** ++ * snd_soc_dapm_set_endpoint - set audio endpoint status ++ * @codec: audio codec ++ * @endpoint: audio signal endpoint (or start point) ++ * @status: point status ++ * ++ * Set audio endpoint status - connected or disconnected. ++ * ++ * Returns 0 for success else error. ++ */ ++int snd_soc_dapm_set_endpoint(struct snd_soc_codec *codec, ++ char *endpoint, int status) ++{ ++ struct snd_soc_dapm_widget *w; ++ ++ list_for_each_entry(w, &codec->dapm_widgets, list) { ++ if (!strcmp(w->name, endpoint)) { ++ w->connected = status; ++ return 0; ++ } ++ } ++ ++ return -ENODEV; ++} ++EXPORT_SYMBOL_GPL(snd_soc_dapm_set_endpoint); ++ ++/** + * snd_soc_dapm_free - free dapm resources + * @socdev: SoC device + * diff --git a/target/linux/s3c24xx/patches-2.6.29/002-call-preinit-instead-of-init.patch b/target/linux/s3c24xx/patches-2.6.29/002-call-preinit-instead-of-init.patch new file mode 100644 index 0000000000..8ab3a5ce32 --- /dev/null +++ b/target/linux/s3c24xx/patches-2.6.29/002-call-preinit-instead-of-init.patch @@ -0,0 +1,10 @@ +--- a/init/main.c ++++ b/init/main.c +@@ -825,6 +825,7 @@ static int noinline init_post(void) + printk(KERN_WARNING "Failed to execute %s. Attempting " + "defaults...\n", execute_command); + } ++ run_init_process("/etc/preinit"); + run_init_process("/sbin/init"); + run_init_process("/etc/init"); + run_init_process("/bin/init"); |